diff -Nru diffimg-1.5.0/3rdparty/3rdparty.pro diffimg-2.0.0/3rdparty/3rdparty.pro --- diffimg-1.5.0/3rdparty/3rdparty.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/3rdparty.pro 2013-07-15 21:17:30.000000000 +0000 @@ -0,0 +1,12 @@ +TEMPLATE = subdirs + +CONFIG += warn_on debug_and_release + +SUBDIRS += qtpropertybrowser perceptualdiff + +win32|os2-g++ { + +SUBDIRS += qwt opencv + +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/3rdparty.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/3rdparty.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/3rdparty.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/3rdparty.pro 2013-05-05 17:32:40.000000000 +0000 @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +CONFIG += warn_on debug_and_release +SUBDIRS += zlib libjpeg libpng libjasper libtiff openexr + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/CMakeLists.txt 2013-05-05 19:11:56.000000000 +0000 @@ -0,0 +1,5 @@ +#add_subdirectory(libjasper) +#add_subdirectory(libjpeg) +#add_subdirectory(libpng) +#add_subdirectory(libtiff) +#add_subdirectory(openexr) diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/ffmpeg_version.cmake diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/ffmpeg_version.cmake --- diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/ffmpeg_version.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/ffmpeg_version.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,11 @@ +set(NEW_FFMPEG 1) +set(HAVE_FFMPEG_CODEC 1) +set(HAVE_FFMPEG_FORMAT 1) +set(HAVE_FFMPEG_UTIL 1) +set(HAVE_FFMPEG_SWSCALE 1) +set(HAVE_GENTOO_FFMPEG 1) + +set(ALIASOF_libavcodec_VERSION 53.61.100) +set(ALIASOF_libavformat_VERSION 53.32.100) +set(ALIASOF_libavutil_VERSION 51.35.100) +set(ALIASOF_libswscale_VERSION 2.1.100) \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/ffopencv.c diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/ffopencv.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/ffopencv.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/ffopencv.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1 @@ +#include "cap_ffmpeg_impl.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/make.bat diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/make.bat --- diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/make.bat 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/make.bat 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2 @@ +set path=c:\dev\msys32\bin;%path% & gcc -Wall -shared -o opencv_ffmpeg.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat -lavcodec -lavdevice -lswscale -lavutil -lwsock32 +set path=c:\dev\msys64\bin;%path% & gcc -m64 -Wall -shared -o opencv_ffmpeg_64.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat64 -lavcodec64 -lavdevice64 -lswscale64 -lavutil64 -lavcore64 -lwsock32 -lws2_32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/readme.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/readme.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/ffmpeg/readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/ffmpeg/readme.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,44 @@ +The build script is to be fixed. +Right now it assumes that 32-bit MinGW is in the system path and +64-bit mingw is installed to c:\Apps\MinGW64. + +It is important that gcc is used, not g++! +Otherwise the produced DLL will likely be dependent on libgcc_s_dw2-1.dll or similar DLL. +While we want to make the DLLs with minimum dependencies: Win32 libraries + msvcrt.dll. + +ffopencv.c is really a C++ source, hence -x c++ is used. + +How to update opencv_ffmpeg.dll and opencv_ffmpeg_64.dll when a new version of FFMPEG is release? + +1. Install 32-bit MinGW + MSYS from + http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/ + Let's assume, it's installed in C:\MSYS32. +2. Install 64-bit MinGW. http://mingw-w64.sourceforge.net/ + Let's assume, it's installed in C:\MSYS64 +3. Copy C:\MSYS32\msys to C:\MSYS64\msys. Edit C:\MSYS64\msys\etc\fstab, change C:\MSYS32 to C:\MSYS64. + +4. Now you have working MSYS32 and MSYS64 environments. + Launch, one by one, C:\MSYS32\msys\msys.bat and C:\MSYS64\msys\msys.bat to create your home directories. + +4. Download ffmpeg-x.y.z.tar.gz (where x.y.z denotes the actual ffmpeg version). + Copy it to C:\MSYS{32|64}\msys\home\ directory. + +5. To build 32-bit ffmpeg libraries, run C:\MSYS32\msys\msys.bat and type the following commands: + + 5.1. tar -xzf ffmpeg-x.y.z.tar.gz + 5.2. mkdir build + 5.3. cd build + 5.4. ../ffmpeg-x.y.z/configure --enable-w32threads + 5.5. make + 5.6. make install + 5.7. cd /local/lib + 5.8. strip -g *.a + +6. Then repeat the same for 64-bit case. The output libs: libavcodec.a etc. need to be renamed to libavcodec64.a etc. + +7. Then, copy all those libs to \3rdparty\lib\, copy the headers to \3rdparty\include\ffmpeg_. + +8. Then, go to \3rdparty\ffmpeg, edit make.bat + (change paths to the actual paths to your msys32 and msys64 distributions) and then run make.bat + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/include/MultiMon.h diffimg-2.0.0/3rdparty/opencv/3rdparty/include/MultiMon.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/include/MultiMon.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/include/MultiMon.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,502 @@ +//============================================================================= +// +// multimon.h -- Stub module that fakes multiple monitor apis on Win32 OSes +// without them. +// +// By using this header your code will get back default values from +// GetSystemMetrics() for new metrics, and the new multimonitor APIs +// will act like only one display is present on a Win32 OS without +// multimonitor APIs. +// +// Exactly one source must include this with COMPILE_MULTIMON_STUBS defined. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//============================================================================= + +#ifdef __cplusplus +extern "C" { // Assume C declarations for C++ +#endif // __cplusplus + +// +// If we are building with Win95/NT4 headers, we need to declare +// the multimonitor-related metrics and APIs ourselves. +// +#ifndef SM_CMONITORS + +#define SM_XVIRTUALSCREEN 76 +#define SM_YVIRTUALSCREEN 77 +#define SM_CXVIRTUALSCREEN 78 +#define SM_CYVIRTUALSCREEN 79 +#define SM_CMONITORS 80 +#define SM_SAMEDISPLAYFORMAT 81 + +// HMONITOR is already declared if WINVER >= 0x0500 in windef.h +// This is for components built with an older version number. +// +#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) +DECLARE_HANDLE(HMONITOR); +#define HMONITOR_DECLARED +#endif + +#define MONITOR_DEFAULTTONULL 0x00000000 +#define MONITOR_DEFAULTTOPRIMARY 0x00000001 +#define MONITOR_DEFAULTTONEAREST 0x00000002 + +#define MONITORINFOF_PRIMARY 0x00000001 + +typedef struct tagMONITORINFO +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; + +#ifndef CCHDEVICENAME +#define CCHDEVICENAME 32 +#endif + +#ifdef __cplusplus +typedef struct tagMONITORINFOEXA : public tagMONITORINFO +{ + CHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEXA, *LPMONITORINFOEXA; +typedef struct tagMONITORINFOEXW : public tagMONITORINFO +{ + WCHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEXW, *LPMONITORINFOEXW; +#ifdef UNICODE +typedef MONITORINFOEXW MONITORINFOEX; +typedef LPMONITORINFOEXW LPMONITORINFOEX; +#else +typedef MONITORINFOEXA MONITORINFOEX; +typedef LPMONITORINFOEXA LPMONITORINFOEX; +#endif // UNICODE +#else // ndef __cplusplus +typedef struct tagMONITORINFOEXA +{ + MONITORINFO; + CHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEXA, *LPMONITORINFOEXA; +typedef struct tagMONITORINFOEXW +{ + MONITORINFO; + WCHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEXW, *LPMONITORINFOEXW; +#ifdef UNICODE +typedef MONITORINFOEXW MONITORINFOEX; +typedef LPMONITORINFOEXW LPMONITORINFOEX; +#else +typedef MONITORINFOEXA MONITORINFOEX; +typedef LPMONITORINFOEXA LPMONITORINFOEX; +#endif // UNICODE +#endif + +typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM); + +#ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP +typedef struct _DISPLAY_DEVICEA { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD StateFlags; + CHAR DeviceID[128]; + CHAR DeviceKey[128]; +} DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA; +typedef struct _DISPLAY_DEVICEW { + DWORD cb; + WCHAR DeviceName[32]; + WCHAR DeviceString[128]; + DWORD StateFlags; + WCHAR DeviceID[128]; + WCHAR DeviceKey[128]; +} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW; +#ifdef UNICODE +typedef DISPLAY_DEVICEW DISPLAY_DEVICE; +typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE; +typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE; +#else +typedef DISPLAY_DEVICEA DISPLAY_DEVICE; +typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE; +typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE; +#endif // UNICODE + +#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 +#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 +#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 +#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 +#define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010 +#endif + +#endif // SM_CMONITORS + +#undef GetMonitorInfo +#undef GetSystemMetrics +#undef MonitorFromWindow +#undef MonitorFromRect +#undef MonitorFromPoint +#undef EnumDisplayMonitors +#undef EnumDisplayDevices + +// +// Define COMPILE_MULTIMON_STUBS to compile the stubs; +// otherwise, you get the declarations. +// +#ifdef COMPILE_MULTIMON_STUBS + +//----------------------------------------------------------------------------- +// +// Implement the API stubs. +// +//----------------------------------------------------------------------------- + +#ifndef _MULTIMON_USE_SECURE_CRT +#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L +#define _MULTIMON_USE_SECURE_CRT 1 +#else +#define _MULTIMON_USE_SECURE_CRT 0 +#endif +#endif + +#ifndef MULTIMON_FNS_DEFINED + +int (WINAPI* g_pfnGetSystemMetrics)(int) = NULL; +HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL; +HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL; +HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL; +BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL; +BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL; +BOOL (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL; +BOOL g_fMultiMonInitDone = FALSE; +BOOL g_fMultimonPlatformNT = FALSE; + +#endif + +BOOL IsPlatformNT() +{ + OSVERSIONINFOA osvi = {0}; + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionExA((OSVERSIONINFOA*)&osvi); + return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId); +} + +BOOL InitMultipleMonitorStubs(void) +{ + HMODULE hUser32; + if (g_fMultiMonInitDone) + { + return g_pfnGetMonitorInfo != NULL; + } + + g_fMultimonPlatformNT = IsPlatformNT(); + hUser32 = GetModuleHandle(TEXT("USER32")); + if (hUser32 && + (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL && + (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL && + (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) != NULL && + (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL && + (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL && +#ifdef UNICODE + (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL && + (*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") : + GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL +#else + (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL && + (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL +#endif + ) { + g_fMultiMonInitDone = TRUE; + return TRUE; + } + else + { + g_pfnGetSystemMetrics = NULL; + g_pfnMonitorFromWindow = NULL; + g_pfnMonitorFromRect = NULL; + g_pfnMonitorFromPoint = NULL; + g_pfnGetMonitorInfo = NULL; + g_pfnEnumDisplayMonitors = NULL; + g_pfnEnumDisplayDevices = NULL; + + g_fMultiMonInitDone = TRUE; + return FALSE; + } +} + +//----------------------------------------------------------------------------- +// +// fake implementations of Monitor APIs that work with the primary display +// no special parameter validation is made since these run in client code +// +//----------------------------------------------------------------------------- + +int WINAPI +xGetSystemMetrics(int nIndex) +{ + if (InitMultipleMonitorStubs()) + return g_pfnGetSystemMetrics(nIndex); + + switch (nIndex) + { + case SM_CMONITORS: + case SM_SAMEDISPLAYFORMAT: + return 1; + + case SM_XVIRTUALSCREEN: + case SM_YVIRTUALSCREEN: + return 0; + + case SM_CXVIRTUALSCREEN: + nIndex = SM_CXSCREEN; + break; + + case SM_CYVIRTUALSCREEN: + nIndex = SM_CYSCREEN; + break; + } + + return GetSystemMetrics(nIndex); +} + +#define xPRIMARY_MONITOR ((HMONITOR)0x12340042) + +HMONITOR WINAPI +xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags) +{ + if (InitMultipleMonitorStubs()) + return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags); + + if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || + ((ptScreenCoords.x >= 0) && + (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) && + (ptScreenCoords.y >= 0) && + (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN)))) + { + return xPRIMARY_MONITOR; + } + + return NULL; +} + +HMONITOR WINAPI +xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags) +{ + if (InitMultipleMonitorStubs()) + return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags); + + if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || + ((lprcScreenCoords->right > 0) && + (lprcScreenCoords->bottom > 0) && + (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) && + (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN)))) + { + return xPRIMARY_MONITOR; + } + + return NULL; +} + +HMONITOR WINAPI +xMonitorFromWindow(HWND hWnd, DWORD dwFlags) +{ + WINDOWPLACEMENT wp; + + if (InitMultipleMonitorStubs()) + return g_pfnMonitorFromWindow(hWnd, dwFlags); + + if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) + return xPRIMARY_MONITOR; + + if (IsIconic(hWnd) ? + GetWindowPlacement(hWnd, &wp) : + GetWindowRect(hWnd, &wp.rcNormalPosition)) { + + return xMonitorFromRect(&wp.rcNormalPosition, dwFlags); + } + + return NULL; +} + +BOOL WINAPI +xGetMonitorInfo(HMONITOR hMonitor, __inout LPMONITORINFO lpMonitorInfo) +{ + RECT rcWork; + + if (InitMultipleMonitorStubs()) + { + BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo); +#ifdef UNICODE + if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))) + { + MultiByteToWideChar(CP_ACP, 0, + (LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1, + ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); + } +#endif + return f; + } + + if ((hMonitor == xPRIMARY_MONITOR) && + lpMonitorInfo && + (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) && + SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0)) + { + lpMonitorInfo->rcMonitor.left = 0; + lpMonitorInfo->rcMonitor.top = 0; + lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN); + lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN); + lpMonitorInfo->rcWork = rcWork; + lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; + + if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)) + { +#ifdef UNICODE + MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); +#else // UNICODE +#if _MULTIMON_USE_SECURE_CRT + strncpy_s(((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)) - 1); +#else + lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); +#endif // _MULTIMON_USE_SECURE_CRT +#endif // UNICODE + } + + return TRUE; + } + + return FALSE; +} + +BOOL WINAPI +xEnumDisplayMonitors( + HDC hdcOptionalForPainting, + LPCRECT lprcEnumMonitorsThatIntersect, + MONITORENUMPROC lpfnEnumProc, + LPARAM dwData) +{ + RECT rcLimit; + + if (InitMultipleMonitorStubs()) { + return g_pfnEnumDisplayMonitors( + hdcOptionalForPainting, + lprcEnumMonitorsThatIntersect, + lpfnEnumProc, + dwData); + } + + if (!lpfnEnumProc) + return FALSE; + + rcLimit.left = 0; + rcLimit.top = 0; + rcLimit.right = GetSystemMetrics(SM_CXSCREEN); + rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN); + + if (hdcOptionalForPainting) + { + RECT rcClip; + POINT ptOrg; + + switch (GetClipBox(hdcOptionalForPainting, &rcClip)) + { + default: + if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg)) + return FALSE; + + OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y); + if (IntersectRect(&rcLimit, &rcLimit, &rcClip) && + (!lprcEnumMonitorsThatIntersect || + IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) { + + break; + } + //fall thru + case NULLREGION: + return TRUE; + case ERROR: + return FALSE; + } + } else { + if ( lprcEnumMonitorsThatIntersect && + !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) { + + return TRUE; + } + } + + return lpfnEnumProc( + xPRIMARY_MONITOR, + hdcOptionalForPainting, + &rcLimit, + dwData); +} + +BOOL WINAPI +xEnumDisplayDevices( + PVOID Unused, + DWORD iDevNum, + __inout PDISPLAY_DEVICE lpDisplayDevice, + DWORD dwFlags) +{ + if (InitMultipleMonitorStubs()) + return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags); + + if (Unused != NULL) + return FALSE; + + if (iDevNum != 0) + return FALSE; + + if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE)) + return FALSE; + +#ifdef UNICODE + MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR))); + MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR))); +#else // UNICODE +#if _MULTIMON_USE_SECURE_CRT + strncpy_s((LPTSTR)lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1); + strncpy_s((LPTSTR)lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1); +#else + lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR))); + lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR))); +#endif // _MULTIMON_USE_SECURE_CRT +#endif // UNICODE + + lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE; + + return TRUE; +} + +#undef xPRIMARY_MONITOR +#undef COMPILE_MULTIMON_STUBS + +#else // COMPILE_MULTIMON_STUBS + +extern int WINAPI xGetSystemMetrics(int); +extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD); +extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD); +extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD); +extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO); +extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM); +extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD); + +#endif // COMPILE_MULTIMON_STUBS + +// +// build defines that replace the regular APIs with our versions +// +#define GetSystemMetrics xGetSystemMetrics +#define MonitorFromWindow xMonitorFromWindow +#define MonitorFromRect xMonitorFromRect +#define MonitorFromPoint xMonitorFromPoint +#define GetMonitorInfo xGetMonitorInfo +#define EnumDisplayMonitors xEnumDisplayMonitors +#define EnumDisplayDevices xEnumDisplayDevices + +#ifdef __cplusplus +} +#endif // __cplusplus + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/include/msc_inttypes.h diffimg-2.0.0/3rdparty/opencv/3rdparty/include/msc_inttypes.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/include/msc_inttypes.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/include/msc_inttypes.h 2013-05-05 19:48:08.000000000 +0000 @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef WIN32 // XBEE + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] + +#endif // WIN32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/include/msc_stdint.h diffimg-2.0.0/3rdparty/opencv/3rdparty/include/msc_stdint.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/include/msc_stdint.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/include/msc_stdint.h 2013-05-05 19:47:40.000000000 +0000 @@ -0,0 +1,223 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef WIN32 // XBEE + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#include + +// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if (_MSC_VER < 1300) && defined(__cplusplus) + extern "C++" { +#endif +# include +#if (_MSC_VER < 1300) && defined(__cplusplus) + } +#endif + +#if defined __GNUC__ || _MSC_VER >= 1600 +#include "stdint.h" +#else + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef int intptr_t; + typedef unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN _I8_MIN +#define INT8_MAX _I8_MAX +#define INT16_MIN _I16_MIN +#define INT16_MAX _I16_MAX +#define INT32_MIN _I32_MIN +#define INT32_MAX _I32_MAX +#define INT64_MIN _I64_MIN +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val +#define INT16_C(val) val +#define INT32_C(val) val##L +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val +#define UINT16_C(val) val +#define UINT32_C(val) val##UL +#define UINT64_C(val) val##Ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + +#endif + +#endif // _MSC_STDINT_H_ ] + +#endif // WIN32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,50 @@ +# ---------------------------------------------------------------------------- +# CMake file for libjasper. See root CMakeLists.txt +# +# ---------------------------------------------------------------------------- +project(${JASPER_LIBRARY}) + + +add_definitions(-DEXCLUDE_MIF_SUPPORT -DEXCLUDE_PNM_SUPPORT -DEXCLUDE_BMP_SUPPORT -DEXCLUDE_RAS_SUPPORT -DEXCLUDE_JPG_SUPPORT -DEXCLUDE_PGX_SUPPORT) + +ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +file(GLOB lib_srcs *.c) +file(GLOB lib_hdrs *.h) +file(GLOB lib_ext_hdrs jasper/*.h) + +# ---------------------------------------------------------------------------------- +# Define the library target: +# ---------------------------------------------------------------------------------- + +add_library(${JASPER_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs} ${lib_ext_hdrs}) + +if(WIN32 AND NOT MINGW) + add_definitions(-DJAS_WIN_MSVC_BUILD) +endif(WIN32 AND NOT MINGW) + +ocv_warnings_disable(CMAKE_C_FLAGS -Wno-implicit-function-declaration -Wno-uninitialized -Wmissing-prototypes -Wmissing-declarations -Wunused -Wshadow -Wsign-compare) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang +ocv_warnings_disable(CMAKE_C_FLAGS /wd4013 /wd4018 /wd4101 /wd4244 /wd4267 /wd4715) # vs2005 + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() +endif() + +set_target_properties(${JASPER_LIBRARY} + PROPERTIES + OUTPUT_NAME ${JASPER_LIBRARY} + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${JASPER_LIBRARY} PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS ${JASPER_LIBRARY} ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/LICENSE diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/LICENSE --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/LICENSE 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,51 @@ +JasPer License Version 2.0 + +Copyright (c) 2001-2006 Michael David Adams +Copyright (c) 1999-2000 Image Power, Inc. +Copyright (c) 1999-2000 The University of British Columbia + +All rights reserved. + +Permission is hereby granted, free of charge, to any person (the +"User") obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +1. The above copyright notices and this permission notice (which +includes the disclaimer below) shall be included in all copies or +substantial portions of the Software. + +2. The name of a copyright holder shall not be used to endorse or +promote products derived from the Software without specific prior +written permission. + +THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS +LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER +THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE +PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE +THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. +EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS +BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL +PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS +GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE +ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE +IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL +SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, +AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL +SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH +THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, +PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH +RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY +EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/README diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/README --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/README 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/README 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,22 @@ +JasPer Readme +************* + +This is the source code distribution for JasPer. JasPer is a collection +of software (i.e., a library and application programs) for the coding +and manipulation of images. This software can handle image data in a +variety of formats. One such format supported by JasPer is the JPEG-2000 +format defined in ISO/IEC 15444-1. + +The complete licensing terms for the JasPer software can be found in +the file named "LICENSE" in the top level directory of this software +distribution. Any use of this software contrary to the terms of the +license is strictly prohibited. The changes made to the software +since the last release are described in the file "NEWS". Detailed +documentation on the JasPer software can be found in the JasPer Software +Reference Manual. This manual is located in the "doc" directory, and +includes useful information such as: 1) how to build, install, and use +the software, 2) how to submit report bugs, and 3) where to find +additional information about the software. + +Enjoy! :) + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/changelog diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/changelog --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/changelog 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/changelog 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,162 @@ +jasper (1.900.1-13) unstable; urgency=high + + * Fix CVE-2011-4516 and CVE-2011-4517: Two buffer overflow issues possibly + exploitable via specially crafted input files (Closes: #652649) + Thanks to Red Hat and Michael Gilbert + + -- Roland Stigge Wed, 04 Jan 2012 19:14:40 +0100 + +jasper (1.900.1-12) unstable; urgency=low + + * Added patch to fix filename buffer overflow, thanks to Jonas Smedegard + and Alex Cherepanov from ghostscript (Closes: #649833) + + -- Roland Stigge Sun, 27 Nov 2011 19:56:01 +0100 + +jasper (1.900.1-11) unstable; urgency=low + + * Added Multiarch support, thanks to Colin Watson (Closes: #645118) + + -- Roland Stigge Wed, 02 Nov 2011 17:16:10 +0100 + +jasper (1.900.1-10) unstable; urgency=low + + * Added debian/watch + * debian/patches/01-misc-fixes.patch: + - Separated out config.{guess,sub} + + -- Roland Stigge Mon, 15 Aug 2011 19:09:29 +0200 + +jasper (1.900.1-9) unstable; urgency=low + + * Switch to dpkg-source 3.0 (quilt) format + * Using new dh 7 build system + + -- Roland Stigge Tue, 12 Jul 2011 20:21:21 +0200 + +jasper (1.900.1-8) unstable; urgency=low + + * Removed unneeded .la file (Closes: #633162) + * debian/control: + - Standards-Version: 3.9.2 + - use libjpeg8-dev instead of libjpeg62-dev + + -- Roland Stigge Mon, 11 Jul 2011 21:27:24 +0200 + +jasper (1.900.1-7) unstable; urgency=low + + * Acknowledge NMU + * Added patch to fix Debian patch for CVE-2008-3521 (Closes: #506739) + * debian/control: Standards-Version: 3.8.4 + + -- Roland Stigge Sun, 21 Feb 2010 16:09:45 +0100 + +jasper (1.900.1-6.1) unstable; urgency=low + + * Non-maintainer upload. + * This is a fix for the GeoJP2 patch introduced in 1.900.1-5 which caused + GDAL faulting. Thanks Even Rouault. (Closes: #553429) + + -- Francesco Paolo Lovergine Wed, 28 Oct 2009 09:39:28 +0100 + +jasper (1.900.1-6) unstable; urgency=low + + * Reverted to jasper 1.900.1-6 because 1.900.1-5.1 messed up (see #528543) + but 1.900.1-5 wasn't available anymore. (Closes: #514296, #528543) + * Re-applied patch from #275619 as in 1.900.1-5 + * debian/control: Standards-Version: 3.8.2 + * Applied patch by Nico Golde (Closes: #501021) + - CVE-2008-3522[0]: Buffer overflow. + - CVE-2008-3521[1]: unsecure temporary files handling. + - CVE-2008-3520[2]: Multiple integer overflows. + + -- Roland Stigge Sat, 20 Jun 2009 15:21:16 +0200 + +jasper (1.900.1-5.1) unstable; urgency=low + + * Non-maintainer upload. + * add patches/02_security.dpatch to fix various CVEs (Closes: #501021): + + CVE-2008-3522[0]: Buffer overflow. + + CVE-2008-3521[1]: unsecure temporary files handling. + + CVE-2008-3520[2]: Multiple integer overflows. + + -- Pierre Habouzit Sun, 12 Oct 2008 21:40:59 +0200 + +jasper (1.900.1-5) unstable; urgency=low + + * Added GeoJP2 patch by Sven Geggus + (Closes: #275619) + * debian/control: Standards-Version: 3.8.0 + + -- Roland Stigge Sun, 08 Jun 2008 13:14:24 +0200 + +jasper (1.900.1-4) unstable; urgency=low + + * src/libjasper/jpc/jpc_dec.c: Extended assert() to accept 4 color + components (Closes: #469786) + * debian/rules: improve "make distclean", thanks to lintian + * debian/control: + - Standards-Version: 3.7.3 + - ${Source-Version} -> ${binary:Version} + - Removed self-dependencies of libjasper-dev + + -- Roland Stigge Sun, 09 Mar 2008 11:53:44 +0100 + +jasper (1.900.1-3) unstable; urgency=low + + * Fixed segfaults on broken images (Closes: #413041) + + -- Roland Stigge Tue, 10 Apr 2007 10:05:10 +0200 + +jasper (1.900.1-2) experimental; urgency=low + + * Added jas_tmr.h to -dev package (Closes: #414705) + + -- Roland Stigge Tue, 13 Mar 2007 14:23:58 +0100 + +jasper (1.900.1-1) experimental; urgency=low + + * New upstream release + * debian/control: + - Standards-Version: 3.7.2 + - Build-Depends: freeglut3-dev instead of libglut3-dev (Closes: #394496) + * Renamed packages to libjasper1, libjasper-dev, libjasper-runtime according + to upstream shared library naming change + + -- Roland Stigge Fri, 26 Jan 2007 14:22:18 +0100 + +jasper (1.701.0-2) unstable; urgency=low + + * Prevent compression of pdf documents in binary packages + * Added man pages for the executables (Closes: #250077) + * Again renamed binary packages to reflect Policy: + - libjasper-1.701-1 + - libjasper-1.701-dev (Provides, Replaces and Conflicts: libjasper-dev) + - libjasper-runtime + + -- Roland Stigge Sun, 20 Jun 2004 13:54:10 +0200 + +jasper (1.701.0-1) unstable; urgency=low + + * New maintainer (Closes: #217099) + * New upstream release (Closes: #217570) + - new DFSG-compliant license (Closes: #218999, #245075) + - includes newer libtool related files (Closes: #210383) + * debian/control: + - Standards-Version: 3.6.1 + - Changed binary package names, fixed interdependencies (Closes: #211592) + libjasper-1.700-2 => libjasper1 + libjasper-1.700-2-dev => libjasper-dev + libjasper-progs => libjasper-runtime + (new packages conflicting and replacing the old ones) + - Added libxi-dev, libxmu-dev, libxt-dev to Build-Depends + (Closes: #250481) + + -- Roland Stigge Sat, 19 Jun 2004 23:19:32 +0200 + +jasper (1.700.2-1) unstable; urgency=low + + * Initial Release. + + -- Christopher L Cheney Fri, 22 Aug 2003 01:30:00 -0500 + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/copyright diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/copyright --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/copyright 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/copyright 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,62 @@ +This package was debianized by Christopher L Cheney on +Fri, 22 Aug 2003 01:33:34 -0500. + +The current maintainer is Roland Stigge + +It was downloaded from http://www.ece.uvic.ca/~mdadams/jasper/ + +Upstream Author: Michael Adams + +License: + +JasPer License Version 2.0 + +Copyright (c) 1999-2000 Image Power, Inc. +Copyright (c) 1999-2000 The University of British Columbia +Copyright (c) 2001-2003 Michael David Adams + +All rights reserved. + +Permission is hereby granted, free of charge, to any person (the +"User") obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +1. The above copyright notices and this permission notice (which +includes the disclaimer below) shall be included in all copies or +substantial portions of the Software. + +2. The name of a copyright holder shall not be used to endorse or +promote products derived from the Software without specific prior +written permission. + +THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS +LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER +THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE +PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE +THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. +EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS +BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL +PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS +GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE +ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE +IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL +SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, +AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL +SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH +THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, +PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH +RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY +EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_cm.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_cm.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_cm.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_cm.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1281 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Color Management + * + * $Id: jas_cm.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static jas_cmprof_t *jas_cmprof_create(void); +static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *); +static jas_cmreal_t jas_cmshapmatlut_lookup(jas_cmshapmatlut_t *lut, jas_cmreal_t x); + +static void jas_cmpxform_destroy(jas_cmpxform_t *pxform); +static jas_cmpxform_t *jas_cmpxform_copy(jas_cmpxform_t *pxform); + +static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform); +static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in, + jas_cmreal_t *out, int cnt); + +static int jas_cmputint(long **bufptr, int sgnd, int prec, long val); +static int jas_cmgetint(long **bufptr, int sgnd, int prec, long *val); +static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq, + jas_cmpxformseq_t *othpxformseq); +static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq, + int, int); +static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, int n); + +static int mono(jas_iccprof_t *prof, int op, jas_cmpxformseq_t **pxformseq); +static int triclr(jas_iccprof_t *prof, int op, jas_cmpxformseq_t **retpxformseq); + +static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq); +static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, int i); +static jas_cmpxformseq_t *jas_cmpxformseq_create(void); +static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq); +static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]); +static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, + int i, jas_cmpxform_t *pxform); + +#define SEQFWD(intent) (intent) +#define SEQREV(intent) (4 + (intent)) +#define SEQSIM(intent) (8 + (intent)) +#define SEQGAM 12 + +#define fwdpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQFWD(intent)]) ? \ + ((prof)->pxformseqs[SEQFWD(intent)]) : \ + ((prof)->pxformseqs[SEQFWD(0)])) + +#define revpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQREV(intent)]) ? \ + ((prof)->pxformseqs[SEQREV(intent)]) : \ + ((prof)->pxformseqs[SEQREV(0)])) + +#define simpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQSIM(intent)]) ? \ + ((prof)->pxformseqs[SEQSIM(intent)]) : \ + ((prof)->pxformseqs[SEQSIM(0)])) + +#define gampxformseq(prof) ((prof)->pxformseqs[SEQGAM]) + +static int icctoclrspc(int iccclrspc, int refflag); +static jas_cmpxform_t *jas_cmpxform_create0(void); +static jas_cmpxform_t *jas_cmpxform_createshapmat(void); +static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut); +static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, jas_icccurv_t *curv); + +static jas_cmpxformops_t shapmat_ops = {jas_cmshapmat_destroy, jas_cmshapmat_apply, 0}; +static jas_cmprof_t *jas_cmprof_createsycc(void); + +/******************************************************************************\ +* Color profile class. +\******************************************************************************/ + +jas_cmprof_t *jas_cmprof_createfromclrspc(int clrspc) +{ + jas_iccprof_t *iccprof; + jas_cmprof_t *prof; + + iccprof = 0; + prof = 0; + switch (clrspc) { + case JAS_CLRSPC_SYCBCR: + if (!(prof = jas_cmprof_createsycc())) + goto error; + break; + default: + if (!(iccprof = jas_iccprof_createfromclrspc(clrspc))) + goto error; + if (!(prof = jas_cmprof_createfromiccprof(iccprof))) + goto error; + jas_iccprof_destroy(iccprof); + iccprof = 0; + if (!jas_clrspc_isgeneric(clrspc)) + prof->clrspc = clrspc; + break; + } + return prof; +error: + if (iccprof) + jas_iccprof_destroy(iccprof); + return 0; +} + +static jas_cmprof_t *jas_cmprof_createsycc() +{ + jas_cmprof_t *prof; + jas_cmpxform_t *fwdpxform; + jas_cmpxform_t *revpxform; + jas_cmshapmat_t *fwdshapmat; + jas_cmshapmat_t *revshapmat; + int i; + int j; + + if (!(prof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) + goto error; + prof->clrspc = JAS_CLRSPC_SYCBCR; + assert(prof->numchans == 3 && prof->numrefchans == 3); + assert(prof->refclrspc == JAS_CLRSPC_CIEXYZ); + if (!(fwdpxform = jas_cmpxform_createshapmat())) + goto error; + fwdpxform->numinchans = 3; + fwdpxform->numoutchans = 3; + fwdshapmat = &fwdpxform->data.shapmat; + fwdshapmat->mono = 0; + fwdshapmat->order = 0; + fwdshapmat->useluts = 0; + fwdshapmat->usemat = 1; + fwdshapmat->mat[0][0] = 1.0; + fwdshapmat->mat[0][1] = 0.0; + fwdshapmat->mat[0][2] = 1.402; + fwdshapmat->mat[1][0] = 1.0; + fwdshapmat->mat[1][1] = -0.34413; + fwdshapmat->mat[1][2] = -0.71414; + fwdshapmat->mat[2][0] = 1.0; + fwdshapmat->mat[2][1] = 1.772; + fwdshapmat->mat[2][2] = 0.0; + fwdshapmat->mat[0][3] = -0.5 * (1.402); + fwdshapmat->mat[1][3] = -0.5 * (-0.34413 - 0.71414); + fwdshapmat->mat[2][3] = -0.5 * (1.772); + if (!(revpxform = jas_cmpxform_createshapmat())) + goto error; + revpxform->numinchans = 3; + revpxform->numoutchans = 3; + revshapmat = &revpxform->data.shapmat; + revshapmat->mono = 0; + revshapmat->order = 1; + revshapmat->useluts = 0; + revshapmat->usemat = 1; + jas_cmshapmat_invmat(revshapmat->mat, fwdshapmat->mat); + + for (i = 0; i < JAS_CMXFORM_NUMINTENTS; ++i) { + j = SEQFWD(i); + if (prof->pxformseqs[j]) { + if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], 0, + fwdpxform)) + goto error; + } + j = SEQREV(i); + if (prof->pxformseqs[j]) { + if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], + -1, revpxform)) + goto error; + } + } + + jas_cmpxform_destroy(fwdpxform); + jas_cmpxform_destroy(revpxform); + return prof; +error: + return 0; +} + +jas_cmprof_t *jas_cmprof_createfromiccprof(jas_iccprof_t *iccprof) +{ + jas_cmprof_t *prof; + jas_icchdr_t icchdr; + jas_cmpxformseq_t *fwdpxformseq; + jas_cmpxformseq_t *revpxformseq; + + prof = 0; + fwdpxformseq = 0; + revpxformseq = 0; + + if (!(prof = jas_cmprof_create())) + goto error; + jas_iccprof_gethdr(iccprof, &icchdr); + if (!(prof->iccprof = jas_iccprof_copy(iccprof))) + goto error; + prof->clrspc = icctoclrspc(icchdr.colorspc, 0); + prof->refclrspc = icctoclrspc(icchdr.refcolorspc, 1); + prof->numchans = jas_clrspc_numchans(prof->clrspc); + prof->numrefchans = jas_clrspc_numchans(prof->refclrspc); + + if (prof->numchans == 1) { + if (mono(prof->iccprof, 0, &fwdpxformseq)) + goto error; + if (mono(prof->iccprof, 1, &revpxformseq)) + goto error; + } else if (prof->numchans == 3) { + if (triclr(prof->iccprof, 0, &fwdpxformseq)) + goto error; + if (triclr(prof->iccprof, 1, &revpxformseq)) + goto error; + } + prof->pxformseqs[SEQFWD(0)] = fwdpxformseq; + prof->pxformseqs[SEQREV(0)] = revpxformseq; + +#if 0 + if (prof->numchans > 1) { + lut(prof->iccprof, 0, PER, &pxformseq); + pxformseqs_set(prof, SEQFWD(PER), pxformseq); + lut(prof->iccprof, 1, PER, &pxformseq); + pxformseqs_set(prof, SEQREV(PER), pxformseq); + lut(prof->iccprof, 0, CLR, &pxformseq); + pxformseqs_set(prof, SEQREV(CLR), pxformseq); + lut(prof->iccprof, 1, CLR, &pxformseq); + pxformseqs_set(prof, SEQREV(CLR), pxformseq); + lut(prof->iccprof, 0, SAT, &pxformseq); + pxformseqs_set(prof, SEQREV(SAT), pxformseq); + lut(prof->iccprof, 1, SAT, &pxformseq); + pxformseqs_set(prof, SEQREV(SAT), pxformseq); + } +#endif + + return prof; + +error: + if (fwdpxformseq) { + jas_cmpxformseq_destroy(fwdpxformseq); + } + if (revpxformseq) { + jas_cmpxformseq_destroy(revpxformseq); + } + if (prof) { + jas_cmprof_destroy(prof); + } + + return 0; +} + +static jas_cmprof_t *jas_cmprof_create() +{ + int i; + jas_cmprof_t *prof; + if (!(prof = jas_malloc(sizeof(jas_cmprof_t)))) + return 0; + memset(prof, 0, sizeof(jas_cmprof_t)); + prof->iccprof = 0; + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) + prof->pxformseqs[i] = 0; + return prof; +} + +void jas_cmprof_destroy(jas_cmprof_t *prof) +{ + int i; + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) { + if (prof->pxformseqs[i]) { + jas_cmpxformseq_destroy(prof->pxformseqs[i]); + prof->pxformseqs[i] = 0; + } + } + if (prof->iccprof) + jas_iccprof_destroy(prof->iccprof); + jas_free(prof); +} + +jas_cmprof_t *jas_cmprof_copy(jas_cmprof_t *prof) +{ + jas_cmprof_t *newprof; + int i; + + if (!(newprof = jas_cmprof_create())) + goto error; + newprof->clrspc = prof->clrspc; + newprof->numchans = prof->numchans; + newprof->refclrspc = prof->refclrspc; + newprof->numrefchans = prof->numrefchans; + newprof->iccprof = jas_iccprof_copy(prof->iccprof); + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) { + if (prof->pxformseqs[i]) { + if (!(newprof->pxformseqs[i] = jas_cmpxformseq_copy(prof->pxformseqs[i]))) + goto error; + } + } + return newprof; +error: + return 0; +} + +/******************************************************************************\ +* Transform class. +\******************************************************************************/ + +jas_cmxform_t *jas_cmxform_create(jas_cmprof_t *inprof, jas_cmprof_t *outprof, + jas_cmprof_t *prfprof, int op, int intent, int optimize) +{ + jas_cmxform_t *xform; + jas_cmpxformseq_t *inpxformseq; + jas_cmpxformseq_t *outpxformseq; + jas_cmpxformseq_t *altoutpxformseq; + jas_cmpxformseq_t *prfpxformseq; + int prfintent; + + /* Avoid compiler warnings about unused parameters. */ + optimize = 0; + + prfintent = intent; + + if (!(xform = jas_malloc(sizeof(jas_cmxform_t)))) + goto error; + if (!(xform->pxformseq = jas_cmpxformseq_create())) + goto error; + + switch (op) { + case JAS_CMXFORM_OP_FWD: + inpxformseq = fwdpxformseq(inprof, intent); + outpxformseq = revpxformseq(outprof, intent); + if (!inpxformseq || !outpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(outprof->clrspc); + break; + case JAS_CMXFORM_OP_REV: + outpxformseq = fwdpxformseq(outprof, intent); + inpxformseq = revpxformseq(inprof, intent); + if (!outpxformseq || !inpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + outprof->refclrspc, inprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, inpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(outprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(inprof->clrspc); + break; + case JAS_CMXFORM_OP_PROOF: + assert(prfprof); + inpxformseq = fwdpxformseq(inprof, intent); + prfpxformseq = fwdpxformseq(prfprof, prfintent); + if (!inpxformseq || !prfpxformseq) + goto error; + outpxformseq = simpxformseq(outprof, intent); + altoutpxformseq = 0; + if (!outpxformseq) { + outpxformseq = revpxformseq(outprof, intent); + altoutpxformseq = fwdpxformseq(outprof, intent); + if (!outpxformseq || !altoutpxformseq) + goto error; + } + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc)) + goto error; + if (altoutpxformseq) { + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) || + jas_cmpxformseq_append(xform->pxformseq, altoutpxformseq)) + goto error; + } else { + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + } + if (jas_cmpxformseq_appendcnvt(xform->pxformseq, + outprof->refclrspc, inprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, prfpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(prfprof->clrspc); + break; + case JAS_CMXFORM_OP_GAMUT: + inpxformseq = fwdpxformseq(inprof, intent); + outpxformseq = gampxformseq(outprof); + if (!inpxformseq || !outpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = 1; + break; + } + return xform; +error: + return 0; +} + +#define APPLYBUFSIZ 2048 +int jas_cmxform_apply(jas_cmxform_t *xform, jas_cmpixmap_t *in, jas_cmpixmap_t *out) +{ + jas_cmcmptfmt_t *fmt; + jas_cmreal_t buf[2][APPLYBUFSIZ]; + jas_cmpxformseq_t *pxformseq; + int i; + int j; + int width; + int height; + int total; + int n; + jas_cmreal_t *inbuf; + jas_cmreal_t *outbuf; + jas_cmpxform_t *pxform; + long *dataptr; + int maxchans; + int bufmax; + int m; + int bias; + jas_cmreal_t scale; + long v; + jas_cmreal_t *bufptr; + + if (xform->numinchans > in->numcmpts || xform->numoutchans > out->numcmpts) + goto error; + + fmt = &in->cmptfmts[0]; + width = fmt->width; + height = fmt->height; + for (i = 1; i < xform->numinchans; ++i) { + fmt = &in->cmptfmts[i]; + if (fmt->width != width || fmt->height != height) { + goto error; + } + } + for (i = 0; i < xform->numoutchans; ++i) { + fmt = &out->cmptfmts[i]; + if (fmt->width != width || fmt->height != height) { + goto error; + } + } + + maxchans = 0; + pxformseq = xform->pxformseq; + for (i = 0; i < pxformseq->numpxforms; ++i) { + pxform = pxformseq->pxforms[i]; + if (pxform->numinchans > maxchans) { + maxchans = pxform->numinchans; + } + if (pxform->numoutchans > maxchans) { + maxchans = pxform->numoutchans; + } + } + bufmax = APPLYBUFSIZ / maxchans; + assert(bufmax > 0); + + total = width * height; + n = 0; + while (n < total) { + + inbuf = &buf[0][0]; + m = JAS_MIN(total - n, bufmax); + + for (i = 0; i < xform->numinchans; ++i) { + fmt = &in->cmptfmts[i]; + scale = (double)((1 << fmt->prec) - 1); + bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0; + dataptr = &fmt->buf[n]; + bufptr = &inbuf[i]; + for (j = 0; j < m; ++j) { + if (jas_cmgetint(&dataptr, fmt->sgnd, fmt->prec, &v)) + goto error; + *bufptr = (v - bias) / scale; + bufptr += xform->numinchans; + } + } + + inbuf = &buf[0][0]; + outbuf = inbuf; + for (i = 0; i < pxformseq->numpxforms; ++i) { + pxform = pxformseq->pxforms[i]; + if (pxform->numoutchans > pxform->numinchans) { + outbuf = (inbuf == &buf[0][0]) ? &buf[1][0] : &buf[0][0]; + } else { + outbuf = inbuf; + } + if ((*pxform->ops->apply)(pxform, inbuf, outbuf, m)) + goto error; + inbuf = outbuf; + } + + for (i = 0; i < xform->numoutchans; ++i) { + fmt = &out->cmptfmts[i]; + scale = (double)((1 << fmt->prec) - 1); + bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0; + bufptr = &outbuf[i]; + dataptr = &fmt->buf[n]; + for (j = 0; j < m; ++j) { + v = (*bufptr) * scale + bias; + bufptr += xform->numoutchans; + if (jas_cmputint(&dataptr, fmt->sgnd, fmt->prec, v)) + goto error; + } + } + + n += m; + } + + return 0; +error: + return -1; +} + +void jas_cmxform_destroy(jas_cmxform_t *xform) +{ + if (xform->pxformseq) + jas_cmpxformseq_destroy(xform->pxformseq); + jas_free(xform); +} + +/******************************************************************************\ +* Primitive transform sequence class. +\******************************************************************************/ + +static jas_cmpxformseq_t *jas_cmpxformseq_create() +{ + jas_cmpxformseq_t *pxformseq; + pxformseq = 0; + if (!(pxformseq = jas_malloc(sizeof(jas_cmpxformseq_t)))) + goto error; + pxformseq->pxforms = 0; + pxformseq->numpxforms = 0; + pxformseq->maxpxforms = 0; + if (jas_cmpxformseq_resize(pxformseq, 16)) + goto error; + return pxformseq; +error: + if (pxformseq) + jas_cmpxformseq_destroy(pxformseq); + return 0; +} + +static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq) +{ + jas_cmpxformseq_t *newpxformseq; + + if (!(newpxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_append(newpxformseq, pxformseq)) + goto error; + return newpxformseq; +error: + return 0; +} + +static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq) +{ + while (pxformseq->numpxforms > 0) + jas_cmpxformseq_delete(pxformseq, pxformseq->numpxforms - 1); + if (pxformseq->pxforms) + jas_free(pxformseq->pxforms); + jas_free(pxformseq); +} + +static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, int i) +{ + assert(i >= 0 && i < pxformseq->numpxforms); + if (i != pxformseq->numpxforms - 1) + abort(); + jas_cmpxform_destroy(pxformseq->pxforms[i]); + pxformseq->pxforms[i] = 0; + --pxformseq->numpxforms; + return 0; +} + +static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq, + int dstclrspc, int srcclrspc) +{ + if (dstclrspc == srcclrspc) + return 0; + abort(); + /* Avoid compiler warnings about unused parameters. */ + pxformseq = 0; + return -1; +} + +static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, + int i, jas_cmpxform_t *pxform) +{ + jas_cmpxform_t *tmppxform; + int n; + if (i < 0) + i = pxformseq->numpxforms; + assert(i >= 0 && i <= pxformseq->numpxforms); + if (pxformseq->numpxforms >= pxformseq->maxpxforms) { + if (jas_cmpxformseq_resize(pxformseq, pxformseq->numpxforms + + 16)) + goto error; + } + assert(pxformseq->numpxforms < pxformseq->maxpxforms); + if (!(tmppxform = jas_cmpxform_copy(pxform))) + goto error; + n = pxformseq->numpxforms - i; + if (n > 0) { + memmove(&pxformseq->pxforms[i + 1], &pxformseq->pxforms[i], + n * sizeof(jas_cmpxform_t *)); + } + pxformseq->pxforms[i] = tmppxform; + ++pxformseq->numpxforms; + return 0; +error: + return -1; +} + +static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq, + jas_cmpxformseq_t *othpxformseq) +{ + int n; + int i; + jas_cmpxform_t *pxform; + jas_cmpxform_t *othpxform; + n = pxformseq->numpxforms + othpxformseq->numpxforms; + if (n > pxformseq->maxpxforms) { + if (jas_cmpxformseq_resize(pxformseq, n)) + goto error; + } + for (i = 0; i < othpxformseq->numpxforms; ++i) { + othpxform = othpxformseq->pxforms[i]; + if (!(pxform = jas_cmpxform_copy(othpxform))) + goto error; + pxformseq->pxforms[pxformseq->numpxforms] = pxform; + ++pxformseq->numpxforms; + } + return 0; +error: + return -1; +} + +static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, int n) +{ + jas_cmpxform_t **p; + assert(n >= pxformseq->numpxforms); + p = jas_realloc2(pxformseq->pxforms, n, sizeof(jas_cmpxform_t *)); + if (!p) { + return -1; + } + pxformseq->pxforms = p; + pxformseq->maxpxforms = n; + return 0; +} + +/******************************************************************************\ +* Primitive transform class. +\******************************************************************************/ + +static jas_cmpxform_t *jas_cmpxform_create0() +{ + jas_cmpxform_t *pxform; + if (!(pxform = jas_malloc(sizeof(jas_cmpxform_t)))) + return 0; + memset(pxform, 0, sizeof(jas_cmpxform_t)); + pxform->refcnt = 0; + pxform->ops = 0; + return pxform; +} + +static void jas_cmpxform_destroy(jas_cmpxform_t *pxform) +{ + if (--pxform->refcnt <= 0) { + (*pxform->ops->destroy)(pxform); + jas_free(pxform); + } +} + +static jas_cmpxform_t *jas_cmpxform_copy(jas_cmpxform_t *pxform) +{ + ++pxform->refcnt; + return pxform; +} + +/******************************************************************************\ +* Shaper matrix class. +\******************************************************************************/ + +static jas_cmpxform_t *jas_cmpxform_createshapmat() +{ + int i; + int j; + jas_cmpxform_t *pxform; + jas_cmshapmat_t *shapmat; + if (!(pxform = jas_cmpxform_create0())) + return 0; + pxform->ops = &shapmat_ops; + shapmat = &pxform->data.shapmat; + shapmat->mono = 0; + shapmat->order = 0; + shapmat->useluts = 0; + shapmat->usemat = 0; + for (i = 0; i < 3; ++i) + jas_cmshapmatlut_init(&shapmat->luts[i]); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 4; ++j) + shapmat->mat[i][j] = 0.0; + } + ++pxform->refcnt; + return pxform; +} + +static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform) +{ + jas_cmshapmat_t *shapmat = &pxform->data.shapmat; + int i; + for (i = 0; i < 3; ++i) + jas_cmshapmatlut_cleanup(&shapmat->luts[i]); +} + +static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in, + jas_cmreal_t *out, int cnt) +{ + jas_cmshapmat_t *shapmat = &pxform->data.shapmat; + jas_cmreal_t *src; + jas_cmreal_t *dst; + jas_cmreal_t a0; + jas_cmreal_t a1; + jas_cmreal_t a2; + jas_cmreal_t b0; + jas_cmreal_t b1; + jas_cmreal_t b2; + src = in; + dst = out; + if (!shapmat->mono) { + while (--cnt >= 0) { + a0 = *src++; + a1 = *src++; + a2 = *src++; + if (!shapmat->order && shapmat->useluts) { + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1); + a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2); + } + if (shapmat->usemat) { + b0 = shapmat->mat[0][0] * a0 + + shapmat->mat[0][1] * a1 + + shapmat->mat[0][2] * a2 + + shapmat->mat[0][3]; + b1 = shapmat->mat[1][0] * a0 + + shapmat->mat[1][1] * a1 + + shapmat->mat[1][2] * a2 + + shapmat->mat[1][3]; + b2 = shapmat->mat[2][0] * a0 + + shapmat->mat[2][1] * a1 + + shapmat->mat[2][2] * a2 + + shapmat->mat[2][3]; + a0 = b0; + a1 = b1; + a2 = b2; + } + if (shapmat->order && shapmat->useluts) { + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1); + a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2); + } + *dst++ = a0; + *dst++ = a1; + *dst++ = a2; + } + } else { + if (!shapmat->order) { + while (--cnt >= 0) { + a0 = *src++; + if (shapmat->useluts) + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a2 = a0 * shapmat->mat[2][0]; + a1 = a0 * shapmat->mat[1][0]; + a0 = a0 * shapmat->mat[0][0]; + *dst++ = a0; + *dst++ = a1; + *dst++ = a2; + } + } else { +assert(0); + while (--cnt >= 0) { + a0 = *src++; + src++; + src++; + a0 = a0 * shapmat->mat[0][0]; + if (shapmat->useluts) + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + *dst++ = a0; + } + } + } + + return 0; +} + +static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut) +{ + lut->data = 0; + lut->size = 0; +} + +static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *lut) +{ + if (lut->data) { + jas_free(lut->data); + lut->data = 0; + } + lut->size = 0; +} + +static double gammafn(double x, double gamma) +{ + if (x == 0.0) + return 0.0; + return pow(x, gamma); +} + +static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, jas_icccurv_t *curv) +{ + jas_cmreal_t gamma; + int i; + gamma = 0; + jas_cmshapmatlut_cleanup(lut); + if (curv->numents == 0) { + lut->size = 2; + if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) + goto error; + lut->data[0] = 0.0; + lut->data[1] = 1.0; + } else if (curv->numents == 1) { + lut->size = 256; + if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) + goto error; + gamma = curv->ents[0] / 256.0; + for (i = 0; i < lut->size; ++i) { + lut->data[i] = gammafn(i / (double) (lut->size - 1), gamma); + } + } else { + lut->size = curv->numents; + if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) + goto error; + for (i = 0; i < lut->size; ++i) { + lut->data[i] = curv->ents[i] / 65535.0; + } + } + return 0; +error: + return -1; +} + +static jas_cmreal_t jas_cmshapmatlut_lookup(jas_cmshapmatlut_t *lut, jas_cmreal_t x) +{ + jas_cmreal_t t; + int lo; + int hi; + t = x * (lut->size - 1); + lo = floor(t); + if (lo < 0) + return lut->data[0]; + hi = ceil(t); + if (hi >= lut->size) + return lut->data[lut->size - 1]; + return lut->data[lo] + (t - lo) * (lut->data[hi] - lut->data[lo]); +} + +static int jas_cmshapmatlut_invert(jas_cmshapmatlut_t *invlut, + jas_cmshapmatlut_t *lut, int n) +{ + int i; + int j; + int k; + jas_cmreal_t ax; + jas_cmreal_t ay; + jas_cmreal_t bx; + jas_cmreal_t by; + jas_cmreal_t sx; + jas_cmreal_t sy; + assert(n >= 2); + if (invlut->data) { + jas_free(invlut->data); + invlut->data = 0; + } + /* The sample values should be nondecreasing. */ + for (i = 1; i < lut->size; ++i) { + if (lut->data[i - 1] > lut->data[i]) { + assert(0); + return -1; + } + } + if (!(invlut->data = jas_alloc2(n, sizeof(jas_cmreal_t)))) + return -1; + invlut->size = n; + for (i = 0; i < invlut->size; ++i) { + sy = ((double) i) / (invlut->size - 1); + sx = 1.0; + for (j = 0; j < lut->size; ++j) { + ay = lut->data[j]; + if (sy == ay) { + for (k = j + 1; k < lut->size; ++k) { + by = lut->data[k]; + if (by != sy) + break; +#if 0 +assert(0); +#endif + } + if (k < lut->size) { + --k; + ax = ((double) j) / (lut->size - 1); + bx = ((double) k) / (lut->size - 1); + sx = (ax + bx) / 2.0; + } + break; + } + if (j < lut->size - 1) { + by = lut->data[j + 1]; + if (sy > ay && sy < by) { + ax = ((double) j) / (lut->size - 1); + bx = ((double) j + 1) / (lut->size - 1); + sx = ax + + (sy - ay) / (by - ay) * (bx - ax); + break; + } + } + } + invlut->data[i] = sx; + } +#if 0 +for (i=0;isize;++i) + jas_eprintf("lut[%d]=%f ", i, lut->data[i]); +for (i=0;isize;++i) + jas_eprintf("invlut[%d]=%f ", i, invlut->data[i]); +#endif + return 0; +} + +static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]) +{ + jas_cmreal_t d; + d = in[0][0] * (in[1][1] * in[2][2] - in[1][2] * in[2][1]) + - in[0][1] * (in[1][0] * in[2][2] - in[1][2] * in[2][0]) + + in[0][2] * (in[1][0] * in[2][1] - in[1][1] * in[2][0]); +#if 0 +jas_eprintf("delta=%f\n", d); +#endif + if (JAS_ABS(d) < 1e-6) + return -1; + out[0][0] = (in[1][1] * in[2][2] - in[1][2] * in[2][1]) / d; + out[1][0] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) / d; + out[2][0] = (in[1][0] * in[2][1] - in[1][1] * in[2][0]) / d; + out[0][1] = -(in[0][1] * in[2][2] - in[0][2] * in[2][1]) / d; + out[1][1] = (in[0][0] * in[2][2] - in[0][2] * in[2][0]) / d; + out[2][1] = -(in[0][0] * in[2][1] - in[0][1] * in[2][0]) / d; + out[0][2] = (in[0][1] * in[1][2] - in[0][2] * in[1][1]) / d; + out[1][2] = -(in[0][0] * in[1][2] - in[1][0] * in[0][2]) / d; + out[2][2] = (in[0][0] * in[1][1] - in[0][1] * in[1][0]) / d; + out[0][3] = -in[0][3]; + out[1][3] = -in[1][3]; + out[2][3] = -in[2][3]; +#if 0 +jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n", +in[0][0], in[0][1], in[0][2], in[0][3], +in[1][0], in[1][1], in[1][2], in[1][3], +in[2][0], in[2][1], in[2][2], in[2][3]); +jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n", +out[0][0], out[0][1], out[0][2], out[0][3], +out[1][0], out[1][1], out[1][2], out[1][3], +out[2][0], out[2][1], out[2][2], out[2][3]); +#endif + return 0; +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int icctoclrspc(int iccclrspc, int refflag) +{ + if (refflag) { + switch (iccclrspc) { + case JAS_ICC_COLORSPC_XYZ: + return JAS_CLRSPC_CIEXYZ; + case JAS_ICC_COLORSPC_LAB: + return JAS_CLRSPC_CIELAB; + default: + abort(); + break; + } + } else { + switch (iccclrspc) { + case JAS_ICC_COLORSPC_YCBCR: + return JAS_CLRSPC_GENYCBCR; + case JAS_ICC_COLORSPC_RGB: + return JAS_CLRSPC_GENRGB; + case JAS_ICC_COLORSPC_GRAY: + return JAS_CLRSPC_GENGRAY; + default: + abort(); + break; + } + } +} + +static int mono(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq) +{ + jas_iccattrval_t *graytrc; + jas_cmshapmat_t *shapmat; + jas_cmpxform_t *pxform; + jas_cmpxformseq_t *pxformseq; + jas_cmshapmatlut_t lut; + + jas_cmshapmatlut_init(&lut); + if (!(graytrc = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRYTRC)) || + graytrc->type != JAS_ICC_TYPE_CURV) + goto error; + if (!(pxform = jas_cmpxform_createshapmat())) + goto error; + shapmat = &pxform->data.shapmat; + if (!(pxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) + goto error; + + pxform->numinchans = 1; + pxform->numoutchans = 3; + + shapmat->mono = 1; + shapmat->useluts = 1; + shapmat->usemat = 1; + if (!op) { + shapmat->order = 0; + shapmat->mat[0][0] = 0.9642; + shapmat->mat[1][0] = 1.0; + shapmat->mat[2][0] = 0.8249; + if (jas_cmshapmatlut_set(&shapmat->luts[0], &graytrc->data.curv)) + goto error; + } else { + shapmat->order = 1; + shapmat->mat[0][0] = 1.0 / 0.9642; + shapmat->mat[1][0] = 1.0; + shapmat->mat[2][0] = 1.0 / 0.8249; + jas_cmshapmatlut_init(&lut); + if (jas_cmshapmatlut_set(&lut, &graytrc->data.curv)) + goto error; + if (jas_cmshapmatlut_invert(&shapmat->luts[0], &lut, lut.size)) + goto error; + jas_cmshapmatlut_cleanup(&lut); + } + jas_iccattrval_destroy(graytrc); + jas_cmpxform_destroy(pxform); + *retpxformseq = pxformseq; + return 0; +error: + return -1; +} + +static int triclr(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq) +{ + int i; + jas_iccattrval_t *trcs[3]; + jas_iccattrval_t *cols[3]; + jas_cmshapmat_t *shapmat; + jas_cmpxform_t *pxform; + jas_cmpxformseq_t *pxformseq; + jas_cmreal_t mat[3][4]; + jas_cmshapmatlut_t lut; + + pxform = 0; + pxformseq = 0; + for (i = 0; i < 3; ++i) { + trcs[i] = 0; + cols[i] = 0; + } + jas_cmshapmatlut_init(&lut); + + if (!(trcs[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDTRC)) || + !(trcs[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNTRC)) || + !(trcs[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUTRC)) || + !(cols[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDMATCOL)) || + !(cols[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNMATCOL)) || + !(cols[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUMATCOL))) + goto error; + for (i = 0; i < 3; ++i) { + if (trcs[i]->type != JAS_ICC_TYPE_CURV || + cols[i]->type != JAS_ICC_TYPE_XYZ) + goto error; + } + if (!(pxform = jas_cmpxform_createshapmat())) + goto error; + pxform->numinchans = 3; + pxform->numoutchans = 3; + shapmat = &pxform->data.shapmat; + if (!(pxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) + goto error; + shapmat->mono = 0; + shapmat->useluts = 1; + shapmat->usemat = 1; + if (!op) { + shapmat->order = 0; + for (i = 0; i < 3; ++i) { + shapmat->mat[0][i] = cols[i]->data.xyz.x / 65536.0; + shapmat->mat[1][i] = cols[i]->data.xyz.y / 65536.0; + shapmat->mat[2][i] = cols[i]->data.xyz.z / 65536.0; + } + for (i = 0; i < 3; ++i) + shapmat->mat[i][3] = 0.0; + for (i = 0; i < 3; ++i) { + if (jas_cmshapmatlut_set(&shapmat->luts[i], &trcs[i]->data.curv)) + goto error; + } + } else { + shapmat->order = 1; + for (i = 0; i < 3; ++i) { + mat[0][i] = cols[i]->data.xyz.x / 65536.0; + mat[1][i] = cols[i]->data.xyz.y / 65536.0; + mat[2][i] = cols[i]->data.xyz.z / 65536.0; + } + for (i = 0; i < 3; ++i) + mat[i][3] = 0.0; + if (jas_cmshapmat_invmat(shapmat->mat, mat)) + goto error; + for (i = 0; i < 3; ++i) { + jas_cmshapmatlut_init(&lut); + if (jas_cmshapmatlut_set(&lut, &trcs[i]->data.curv)) + goto error; + if (jas_cmshapmatlut_invert(&shapmat->luts[i], &lut, lut.size)) + goto error; + jas_cmshapmatlut_cleanup(&lut); + } + } + for (i = 0; i < 3; ++i) { + jas_iccattrval_destroy(trcs[i]); + jas_iccattrval_destroy(cols[i]); + } + jas_cmpxform_destroy(pxform); + *retpxformseq = pxformseq; + return 0; + +error: + + for (i = 0; i < 3; ++i) { + if (trcs[i]) { + jas_iccattrval_destroy(trcs[i]); + } + if (cols[i]) { + jas_iccattrval_destroy(cols[i]); + } + } + if (pxformseq) { + jas_cmpxformseq_destroy(pxformseq); + } + if (pxform) { + jas_cmpxform_destroy(pxform); + } + + return -1; +} + +static int jas_cmgetint(long **bufptr, int sgnd, int prec, long *val) +{ + long v; + int m; + v = **bufptr; + if (sgnd) { + m = (1 << (prec - 1)); + if (v < -m || v >= m) + return -1; + } else { + if (v < 0 || v >= (1 << prec)) + return -1; + } + ++(*bufptr); + *val = v; + return 0; +} + +static int jas_cmputint(long **bufptr, int sgnd, int prec, long val) +{ + int m; + if (sgnd) { + m = (1 << (prec - 1)); + if (val < -m || val >= m) + return -1; + } else { + if (val < 0 || val >= (1 << prec)) + return -1; + } + **bufptr = val; + ++(*bufptr); + return 0; +} + +int jas_clrspc_numchans(int clrspc) +{ + switch (jas_clrspc_fam(clrspc)) { + case JAS_CLRSPC_FAM_XYZ: + case JAS_CLRSPC_FAM_LAB: + case JAS_CLRSPC_FAM_RGB: + case JAS_CLRSPC_FAM_YCBCR: + return 3; + break; + case JAS_CLRSPC_FAM_GRAY: + return 1; + break; + default: + abort(); + break; + } +} + +jas_iccprof_t *jas_iccprof_createfromcmprof(jas_cmprof_t *prof) +{ + return jas_iccprof_copy(prof->iccprof); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_debug.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_debug.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_debug.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_debug.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_debug.h" + +/******************************************************************************\ +* Local data. +\******************************************************************************/ + +static int jas_dbglevel = 0; +/* The debug level. */ + +/******************************************************************************\ +* Code for getting/setting the debug level. +\******************************************************************************/ + +/* Set the library debug level. */ +int jas_setdbglevel(int dbglevel) +{ + int olddbglevel; + + /* Save the old debug level. */ + olddbglevel = jas_dbglevel; + + /* Change the debug level. */ + jas_dbglevel = dbglevel; + + /* Return the old debug level. */ + return olddbglevel; +} + +/* Get the library debug level. */ +int jas_getdbglevel() +{ + return jas_dbglevel; +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Perform formatted output to standard error. */ +int jas_eprintf(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(stderr, fmt, ap); + va_end(ap); + return ret; +} + +/* Dump memory to a stream. */ +int jas_memdump(FILE *out, void *data, size_t len) +{ + size_t i; + size_t j; + uchar *dp; + dp = data; + for (i = 0; i < len; i += 16) { + fprintf(out, "%04x:", (int)i); + for (j = 0; j < 16; ++j) { + if (i + j < len) { + fprintf(out, " %02x", dp[i + j]); + } + } + fprintf(out, "\n"); + } + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_getopt.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_getopt.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_getopt.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_getopt.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999-2000, Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Command Line Option Parsing Library + * + * $Id: jas_getopt.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +#include "jasper/jas_getopt.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +int jas_optind = 0; +int jas_opterr = 1; +char *jas_optarg = 0; + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +static jas_opt_t *jas_optlookup(jas_opt_t *opts, char *name) +{ + jas_opt_t *opt; + + for (opt = opts; opt->id >= 0 && opt->name; ++opt) { + if (!strcmp(opt->name, name)) { + return opt; + } + } + return 0; +} + +int jas_getopt(int argc, char **argv, jas_opt_t *opts) +{ + char *cp; + int id; + int hasarg; + jas_opt_t *opt; + char *s; + + if (!jas_optind) { + jas_optind = JAS_MIN(1, argc); + } + while (jas_optind < argc) { + s = cp = argv[jas_optind]; + if (*cp == '-') { + /* We are processing an option. */ + ++jas_optind; + if (*++cp == '-') { + /* We are processing a long option. */ + ++cp; + if (*cp == '\0') { + /* This is the end of the options. */ + return JAS_GETOPT_EOF; + } + if (!(opt = jas_optlookup(opts, cp))) { + if (jas_opterr) { + jas_eprintf("unknown long option %s\n", s); + } + return JAS_GETOPT_ERR; + } + hasarg = (opt->flags & JAS_OPT_HASARG) != 0; + id = opt->id; + } else { + /* We are processing a short option. */ + if (strlen(cp) != 1 || + !(opt = jas_optlookup(opts, cp))) { + if (jas_opterr) { + jas_eprintf("unknown short option %s\n", s); + } + return JAS_GETOPT_ERR; + } + hasarg = (opt->flags & JAS_OPT_HASARG) != 0; + id = opt->id; + } + if (hasarg) { + /* The option has an argument. */ + if (jas_optind >= argc) { + if (jas_opterr) { + jas_eprintf("missing argument for option %s\n", s); + } + return JAS_GETOPT_ERR; + } + jas_optarg = argv[jas_optind]; + ++jas_optind; + } else { + /* The option does not have an argument. */ + jas_optarg = 0; + } + return id; + } else { + /* We are not processing an option. */ + return JAS_GETOPT_EOF; + } + } + return JAS_GETOPT_EOF; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_icc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_icc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_icc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_icc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1721 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define jas_iccputuint8(out, val) jas_iccputuint(out, 1, val) +#define jas_iccputuint16(out, val) jas_iccputuint(out, 2, val) +#define jas_iccputsint32(out, val) jas_iccputsint(out, 4, val) +#define jas_iccputuint32(out, val) jas_iccputuint(out, 4, val) +#define jas_iccputuint64(out, val) jas_iccputuint(out, 8, val) + +static jas_iccattrval_t *jas_iccattrval_create0(void); + +static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val); +static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val); +static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val); +static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val); +static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val); +static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val); +static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val); +static int jas_iccputsint(jas_stream_t *out, int n, longlong val); +static jas_iccprof_t *jas_iccprof_create(void); +static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr); +static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr); +static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab); +static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab); +static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab, jas_iccuint32_t name); +static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab); +static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t name); +static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time); +static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz); +static int jas_icctagtabent_cmp(const void *src, const void *dst); + +static void jas_icccurv_destroy(jas_iccattrval_t *attrval); +static int jas_icccurv_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icccurv_getsize(jas_iccattrval_t *attrval); +static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval); +static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval); +static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icctxt_destroy(jas_iccattrval_t *attrval); +static int jas_icctxt_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icctxt_getsize(jas_iccattrval_t *attrval); +static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out); + +static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_iccxyz_getsize(jas_iccattrval_t *attrval); +static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out); + +static jas_iccattrtab_t *jas_iccattrtab_create(void); +static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab); +static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents); +static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val); +static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val); +static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i); +static long jas_iccpadtomult(long x, long y); +static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i, + jas_iccattrname_t *name, jas_iccattrval_t **val); +static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab); + +static void jas_icclut16_destroy(jas_iccattrval_t *attrval); +static int jas_icclut16_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icclut16_getsize(jas_iccattrval_t *attrval); +static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icclut8_destroy(jas_iccattrval_t *attrval); +static int jas_icclut8_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icclut8_getsize(jas_iccattrval_t *attrval); +static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out); + +static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *ctime); +static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz); + +static long jas_iccpowi(int x, int n); + +static char *jas_iccsigtostr(int sig, char *buf); + + +jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { + {JAS_ICC_TYPE_CURV, {jas_icccurv_destroy, jas_icccurv_copy, + jas_icccurv_input, jas_icccurv_output, jas_icccurv_getsize, + jas_icccurv_dump}}, + {JAS_ICC_TYPE_XYZ, {0, 0, jas_iccxyz_input, jas_iccxyz_output, + jas_iccxyz_getsize, jas_iccxyz_dump}}, + {JAS_ICC_TYPE_TXTDESC, {jas_icctxtdesc_destroy, + jas_icctxtdesc_copy, jas_icctxtdesc_input, jas_icctxtdesc_output, + jas_icctxtdesc_getsize, jas_icctxtdesc_dump}}, + {JAS_ICC_TYPE_TXT, {jas_icctxt_destroy, jas_icctxt_copy, + jas_icctxt_input, jas_icctxt_output, jas_icctxt_getsize, + jas_icctxt_dump}}, + {JAS_ICC_TYPE_LUT8, {jas_icclut8_destroy, jas_icclut8_copy, + jas_icclut8_input, jas_icclut8_output, jas_icclut8_getsize, + jas_icclut8_dump}}, + {JAS_ICC_TYPE_LUT16, {jas_icclut16_destroy, jas_icclut16_copy, + jas_icclut16_input, jas_icclut16_output, jas_icclut16_getsize, + jas_icclut16_dump}}, + {0, {0, 0, 0, 0, 0, 0}} +}; + +typedef struct { + jas_iccuint32_t tag; + char *name; +} jas_icctaginfo_t; + +/******************************************************************************\ +* profile class +\******************************************************************************/ + +static jas_iccprof_t *jas_iccprof_create() +{ + jas_iccprof_t *prof; + prof = 0; + if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) { + goto error; + } + if (!(prof->attrtab = jas_iccattrtab_create())) + goto error; + memset(&prof->hdr, 0, sizeof(jas_icchdr_t)); + prof->tagtab.numents = 0; + prof->tagtab.ents = 0; + return prof; +error: + if (prof) + jas_iccprof_destroy(prof); + return 0; +} + +jas_iccprof_t *jas_iccprof_copy(jas_iccprof_t *prof) +{ + jas_iccprof_t *newprof; + newprof = 0; + if (!(newprof = jas_iccprof_create())) + goto error; + newprof->hdr = prof->hdr; + newprof->tagtab.numents = 0; + newprof->tagtab.ents = 0; + assert(newprof->attrtab); + jas_iccattrtab_destroy(newprof->attrtab); + if (!(newprof->attrtab = jas_iccattrtab_copy(prof->attrtab))) + goto error; + return newprof; +error: + if (newprof) + jas_iccprof_destroy(newprof); + return 0; +} + +void jas_iccprof_destroy(jas_iccprof_t *prof) +{ + if (prof->attrtab) + jas_iccattrtab_destroy(prof->attrtab); + if (prof->tagtab.ents) + jas_free(prof->tagtab.ents); + jas_free(prof); +} + +void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out) +{ + jas_iccattrtab_dump(prof->attrtab, out); +} + +jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) +{ + jas_iccprof_t *prof; + int numtags; + long curoff; + long reloff; + long prevoff; + jas_iccsig_t type; + jas_iccattrval_t *attrval; + jas_iccattrval_t *prevattrval; + jas_icctagtabent_t *tagtabent; + jas_iccattrvalinfo_t *attrvalinfo; + int i; + int len; + + prof = 0; + attrval = 0; + + if (!(prof = jas_iccprof_create())) { + goto error; + } + + if (jas_iccprof_readhdr(in, &prof->hdr)) { + jas_eprintf("cannot get header\n"); + goto error; + } + if (jas_iccprof_gettagtab(in, &prof->tagtab)) { + jas_eprintf("cannot get tab table\n"); + goto error; + } + jas_iccprof_sorttagtab(&prof->tagtab); + + numtags = prof->tagtab.numents; + curoff = JAS_ICC_HDRLEN + 4 + 12 * numtags; + prevoff = 0; + prevattrval = 0; + for (i = 0; i < numtags; ++i) { + tagtabent = &prof->tagtab.ents[i]; + if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) { + if (prevattrval) { + if (!(attrval = jas_iccattrval_clone(prevattrval))) + goto error; + if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) + goto error; + jas_iccattrval_destroy(attrval); + } else { +#if 0 + jas_eprintf("warning: skipping unknown tag type\n"); +#endif + } + continue; + } + reloff = tagtabent->off - curoff; + if (reloff > 0) { + if (jas_stream_gobble(in, reloff) != reloff) + goto error; + curoff += reloff; + } else if (reloff < 0) { + /* This should never happen since we read the tagged + element data in a single pass. */ + abort(); + } + prevoff = curoff; + if (jas_iccgetuint32(in, &type)) { + goto error; + } + if (jas_stream_gobble(in, 4) != 4) { + goto error; + } + curoff += 8; + if (!(attrvalinfo = jas_iccattrvalinfo_lookup(type))) { +#if 0 + jas_eprintf("warning: skipping unknown tag type\n"); +#endif + prevattrval = 0; + continue; + } + if (!(attrval = jas_iccattrval_create(type))) { + goto error; + } + len = tagtabent->len - 8; + if ((*attrval->ops->input)(attrval, in, len)) { + goto error; + } + curoff += len; + if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) { + goto error; + } + prevattrval = attrval; /* This is correct, but slimey. */ + jas_iccattrval_destroy(attrval); + attrval = 0; + } + + return prof; + +error: + if (prof) + jas_iccprof_destroy(prof); + if (attrval) + jas_iccattrval_destroy(attrval); + return 0; +} + +int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out) +{ + long curoff; + long reloff; + long newoff; + int i; + int j; + jas_icctagtabent_t *tagtabent; + jas_icctagtabent_t *sharedtagtabent; + jas_icctagtabent_t *tmptagtabent; + jas_iccuint32_t attrname; + jas_iccattrval_t *attrval; + jas_icctagtab_t *tagtab; + + tagtab = &prof->tagtab; + if (!(tagtab->ents = jas_alloc2(prof->attrtab->numattrs, + sizeof(jas_icctagtabent_t)))) + goto error; + tagtab->numents = prof->attrtab->numattrs; + curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents; + for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) { + tagtabent = &tagtab->ents[i]; + if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) + goto error; + assert(attrval->ops->output); + tagtabent->tag = attrname; + tagtabent->data = &attrval->data; + sharedtagtabent = 0; + for (j = 0; j < i; ++j) { + tmptagtabent = &tagtab->ents[j]; + if (tagtabent->data == tmptagtabent->data) { + sharedtagtabent = tmptagtabent; + break; + } + } + if (sharedtagtabent) { + tagtabent->off = sharedtagtabent->off; + tagtabent->len = sharedtagtabent->len; + tagtabent->first = sharedtagtabent; + } else { + tagtabent->off = curoff; + tagtabent->len = (*attrval->ops->getsize)(attrval) + 8; + tagtabent->first = 0; + if (i < JAS_CAST(int, tagtab->numents - 1)) { + curoff = jas_iccpadtomult(curoff + tagtabent->len, 4); + } else { + curoff += tagtabent->len; + } + } + jas_iccattrval_destroy(attrval); + } + prof->hdr.size = curoff; + if (jas_iccprof_writehdr(out, &prof->hdr)) + goto error; + if (jas_iccprof_puttagtab(out, &prof->tagtab)) + goto error; + curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents; + for (i = 0; i < JAS_CAST(int, tagtab->numents);) { + tagtabent = &tagtab->ents[i]; + assert(curoff == JAS_CAST(long, tagtabent->off)); + if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) + goto error; + if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out, + 4, 0) != 4) + goto error; + if ((*attrval->ops->output)(attrval, out)) + goto error; + jas_iccattrval_destroy(attrval); + curoff += tagtabent->len; + ++i; + while (i < JAS_CAST(int, tagtab->numents) && + tagtab->ents[i].first) + ++i; + newoff = (i < JAS_CAST(int, tagtab->numents)) ? + tagtab->ents[i].off : prof->hdr.size; + reloff = newoff - curoff; + assert(reloff >= 0); + if (reloff > 0) { + if (jas_stream_pad(out, reloff, 0) != reloff) + goto error; + curoff += reloff; + } + } + return 0; +error: + /* XXX - need to free some resources here */ + return -1; +} + +static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr) +{ + if (jas_iccputuint32(out, hdr->size) || + jas_iccputuint32(out, hdr->cmmtype) || + jas_iccputuint32(out, hdr->version) || + jas_iccputuint32(out, hdr->clas) || + jas_iccputuint32(out, hdr->colorspc) || + jas_iccputuint32(out, hdr->refcolorspc) || + jas_iccputtime(out, &hdr->ctime) || + jas_iccputuint32(out, hdr->magic) || + jas_iccputuint32(out, hdr->platform) || + jas_iccputuint32(out, hdr->flags) || + jas_iccputuint32(out, hdr->maker) || + jas_iccputuint32(out, hdr->model) || + jas_iccputuint64(out, hdr->attr) || + jas_iccputuint32(out, hdr->intent) || + jas_iccputxyz(out, &hdr->illum) || + jas_iccputuint32(out, hdr->creator) || + jas_stream_pad(out, 44, 0) != 44) + return -1; + return 0; +} + +static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab) +{ + int i; + jas_icctagtabent_t *tagtabent; + if (jas_iccputuint32(out, tagtab->numents)) + goto error; + for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) { + tagtabent = &tagtab->ents[i]; + if (jas_iccputuint32(out, tagtabent->tag) || + jas_iccputuint32(out, tagtabent->off) || + jas_iccputuint32(out, tagtabent->len)) + goto error; + } + return 0; +error: + return -1; +} + +static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr) +{ + if (jas_iccgetuint32(in, &hdr->size) || + jas_iccgetuint32(in, &hdr->cmmtype) || + jas_iccgetuint32(in, &hdr->version) || + jas_iccgetuint32(in, &hdr->clas) || + jas_iccgetuint32(in, &hdr->colorspc) || + jas_iccgetuint32(in, &hdr->refcolorspc) || + jas_iccgettime(in, &hdr->ctime) || + jas_iccgetuint32(in, &hdr->magic) || + jas_iccgetuint32(in, &hdr->platform) || + jas_iccgetuint32(in, &hdr->flags) || + jas_iccgetuint32(in, &hdr->maker) || + jas_iccgetuint32(in, &hdr->model) || + jas_iccgetuint64(in, &hdr->attr) || + jas_iccgetuint32(in, &hdr->intent) || + jas_iccgetxyz(in, &hdr->illum) || + jas_iccgetuint32(in, &hdr->creator) || + jas_stream_gobble(in, 44) != 44) + return -1; + return 0; +} + +static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab) +{ + int i; + jas_icctagtabent_t *tagtabent; + + if (tagtab->ents) { + jas_free(tagtab->ents); + tagtab->ents = 0; + } + if (jas_iccgetuint32(in, &tagtab->numents)) + goto error; + if (!(tagtab->ents = jas_alloc2(tagtab->numents, + sizeof(jas_icctagtabent_t)))) + goto error; + tagtabent = tagtab->ents; + for (i = 0; i < JAS_CAST(long, tagtab->numents); ++i) { + if (jas_iccgetuint32(in, &tagtabent->tag) || + jas_iccgetuint32(in, &tagtabent->off) || + jas_iccgetuint32(in, &tagtabent->len)) + goto error; + ++tagtabent; + } + return 0; +error: + if (tagtab->ents) { + jas_free(tagtab->ents); + tagtab->ents = 0; + } + return -1; +} + +jas_iccattrval_t *jas_iccprof_getattr(jas_iccprof_t *prof, + jas_iccattrname_t name) +{ + int i; + jas_iccattrval_t *attrval; + if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0) + goto error; + if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val))) + goto error; + return attrval; +error: + return 0; +} + +int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name, + jas_iccattrval_t *val) +{ + int i; + if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) { + if (val) { + if (jas_iccattrtab_replace(prof->attrtab, i, name, val)) + goto error; + } else { + jas_iccattrtab_delete(prof->attrtab, i); + } + } else { + if (val) { + if (jas_iccattrtab_add(prof->attrtab, -1, name, val)) + goto error; + } else { + /* NOP */ + } + } + return 0; +error: + return -1; +} + +int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr) +{ + *hdr = prof->hdr; + return 0; +} + +int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr) +{ + prof->hdr = *hdr; + return 0; +} + +static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab) +{ + qsort(tagtab->ents, tagtab->numents, sizeof(jas_icctagtabent_t), + jas_icctagtabent_cmp); +} + +static int jas_icctagtabent_cmp(const void *src, const void *dst) +{ + jas_icctagtabent_t *srctagtabent = JAS_CAST(jas_icctagtabent_t *, src); + jas_icctagtabent_t *dsttagtabent = JAS_CAST(jas_icctagtabent_t *, dst); + if (srctagtabent->off > dsttagtabent->off) { + return 1; + } else if (srctagtabent->off < dsttagtabent->off) { + return -1; + } + return 0; +} + +static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t type) +{ + jas_iccattrvalinfo_t *info; + info = jas_iccattrvalinfos; + for (info = jas_iccattrvalinfos; info->type; ++info) { + if (info->type == type) { + return info; + } + } + return 0; +} + +static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time) +{ + if (jas_iccgetuint16(in, &time->year) || + jas_iccgetuint16(in, &time->month) || + jas_iccgetuint16(in, &time->day) || + jas_iccgetuint16(in, &time->hour) || + jas_iccgetuint16(in, &time->min) || + jas_iccgetuint16(in, &time->sec)) { + return -1; + } + return 0; +} + +static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz) +{ + if (jas_iccgetsint32(in, &xyz->x) || + jas_iccgetsint32(in, &xyz->y) || + jas_iccgetsint32(in, &xyz->z)) { + return -1; + } + return 0; +} + +static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *time) +{ + jas_iccputuint16(out, time->year); + jas_iccputuint16(out, time->month); + jas_iccputuint16(out, time->day); + jas_iccputuint16(out, time->hour); + jas_iccputuint16(out, time->min); + jas_iccputuint16(out, time->sec); + return 0; +} + +static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz) +{ + jas_iccputuint32(out, xyz->x); + jas_iccputuint32(out, xyz->y); + jas_iccputuint32(out, xyz->z); + return 0; +} + +/******************************************************************************\ +* attribute table class +\******************************************************************************/ + +static jas_iccattrtab_t *jas_iccattrtab_create() +{ + jas_iccattrtab_t *tab; + tab = 0; + if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t)))) + goto error; + tab->maxattrs = 0; + tab->numattrs = 0; + tab->attrs = 0; + if (jas_iccattrtab_resize(tab, 32)) + goto error; + return tab; +error: + if (tab) + jas_iccattrtab_destroy(tab); + return 0; +} + +static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab) +{ + jas_iccattrtab_t *newattrtab; + int i; + if (!(newattrtab = jas_iccattrtab_create())) + goto error; + for (i = 0; i < attrtab->numattrs; ++i) { + if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name, + attrtab->attrs[i].val)) + goto error; + } + return newattrtab; +error: + return 0; +} + +static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab) +{ + if (tab->attrs) { + while (tab->numattrs > 0) { + jas_iccattrtab_delete(tab, 0); + } + jas_free(tab->attrs); + } + jas_free(tab); +} + +void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out) +{ + int i; + jas_iccattr_t *attr; + jas_iccattrval_t *attrval; + jas_iccattrvalinfo_t *info; + char buf[16]; + fprintf(out, "numattrs=%d\n", attrtab->numattrs); + fprintf(out, "---\n"); + for (i = 0; i < attrtab->numattrs; ++i) { + attr = &attrtab->attrs[i]; + attrval = attr->val; + info = jas_iccattrvalinfo_lookup(attrval->type); + if (!info) abort(); + fprintf(out, "attrno=%d; attrname=\"%s\"(0x%08x); attrtype=\"%s\"(0x%08x)\n", + i, + jas_iccsigtostr(attr->name, &buf[0]), + (unsigned)attr->name, + jas_iccsigtostr(attrval->type, &buf[8]), + (unsigned)attrval->type + ); + jas_iccattrval_dump(attrval, out); + fprintf(out, "---\n"); + } +} + +static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents) +{ + jas_iccattr_t *newattrs; + assert(maxents >= tab->numattrs); + newattrs = jas_realloc2(tab->attrs, maxents, sizeof(jas_iccattr_t)); + if (!newattrs) + return -1; + tab->attrs = newattrs; + tab->maxattrs = maxents; + return 0; +} + +static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val) +{ + int n; + jas_iccattr_t *attr; + jas_iccattrval_t *tmpattrval; + tmpattrval = 0; + if (i < 0) { + i = attrtab->numattrs; + } + assert(i >= 0 && i <= attrtab->numattrs); + if (attrtab->numattrs >= attrtab->maxattrs) { + if (jas_iccattrtab_resize(attrtab, attrtab->numattrs + 32)) { + goto error; + } + } + if (!(tmpattrval = jas_iccattrval_clone(val))) + goto error; + n = attrtab->numattrs - i; + if (n > 0) + memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i], + n * sizeof(jas_iccattr_t)); + attr = &attrtab->attrs[i]; + attr->name = name; + attr->val = tmpattrval; + ++attrtab->numattrs; + return 0; +error: + if (tmpattrval) + jas_iccattrval_destroy(tmpattrval); + return -1; +} + +static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val) +{ + jas_iccattrval_t *newval; + jas_iccattr_t *attr; + if (!(newval = jas_iccattrval_clone(val))) + goto error; + attr = &attrtab->attrs[i]; + jas_iccattrval_destroy(attr->val); + attr->name = name; + attr->val = newval; + return 0; +error: + return -1; +} + +static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i) +{ + int n; + jas_iccattrval_destroy(attrtab->attrs[i].val); + if ((n = attrtab->numattrs - i - 1) > 0) + memmove(&attrtab->attrs[i], &attrtab->attrs[i + 1], + n * sizeof(jas_iccattr_t)); + --attrtab->numattrs; +} + +static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i, + jas_iccattrname_t *name, jas_iccattrval_t **val) +{ + jas_iccattr_t *attr; + if (i < 0 || i >= attrtab->numattrs) + goto error; + attr = &attrtab->attrs[i]; + *name = attr->name; + if (!(*val = jas_iccattrval_clone(attr->val))) + goto error; + return 0; +error: + return -1; +} + +static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab, + jas_iccuint32_t name) +{ + int i; + jas_iccattr_t *attr; + for (i = 0; i < attrtab->numattrs; ++i) { + attr = &attrtab->attrs[i]; + if (attr->name == name) + return i; + } + return -1; +} + +/******************************************************************************\ +* attribute value class +\******************************************************************************/ + +jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type) +{ + jas_iccattrval_t *attrval; + jas_iccattrvalinfo_t *info; + + if (!(info = jas_iccattrvalinfo_lookup(type))) + goto error; + if (!(attrval = jas_iccattrval_create0())) + goto error; + attrval->ops = &info->ops; + attrval->type = type; + ++attrval->refcnt; + memset(&attrval->data, 0, sizeof(attrval->data)); + return attrval; +error: + return 0; +} + +jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval) +{ + ++attrval->refcnt; + return attrval; +} + +void jas_iccattrval_destroy(jas_iccattrval_t *attrval) +{ +#if 0 +jas_eprintf("refcnt=%d\n", attrval->refcnt); +#endif + if (--attrval->refcnt <= 0) { + if (attrval->ops->destroy) + (*attrval->ops->destroy)(attrval); + jas_free(attrval); + } +} + +void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out) +{ + char buf[8]; + jas_iccsigtostr(attrval->type, buf); + fprintf(out, "refcnt = %d; type = 0x%08x %s\n", attrval->refcnt, + (unsigned)attrval->type, jas_iccsigtostr(attrval->type, &buf[0])); + if (attrval->ops->dump) { + (*attrval->ops->dump)(attrval, out); + } +} + +int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx) +{ + jas_iccattrval_t *newattrval; + jas_iccattrval_t *attrval = *attrvalx; + newattrval = 0; + if (attrval->refcnt > 1) { + if (!(newattrval = jas_iccattrval_create0())) + goto error; + newattrval->ops = attrval->ops; + newattrval->type = attrval->type; + ++newattrval->refcnt; + if (newattrval->ops->copy) { + if ((*newattrval->ops->copy)(newattrval, attrval)) + goto error; + } else { + memcpy(&newattrval->data, &attrval->data, + sizeof(newattrval->data)); + } + *attrvalx = newattrval; + } + return 0; +error: + if (newattrval) { + jas_free(newattrval); + } + return -1; +} + +static jas_iccattrval_t *jas_iccattrval_create0() +{ + jas_iccattrval_t *attrval; + if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t)))) + return 0; + memset(attrval, 0, sizeof(jas_iccattrval_t)); + attrval->refcnt = 0; + attrval->ops = 0; + attrval->type = 0; + return attrval; +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int len) +{ + if (len != 4 * 3) abort(); + return jas_iccgetxyz(in, &attrval->data.xyz); +} + +static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_iccxyz_t *xyz = &attrval->data.xyz; + if (jas_iccputuint32(out, xyz->x) || + jas_iccputuint32(out, xyz->y) || + jas_iccputuint32(out, xyz->z)) + return -1; + return 0; +} + +static int jas_iccxyz_getsize(jas_iccattrval_t *attrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + + return 12; +} + +static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_iccxyz_t *xyz = &attrval->data.xyz; + fprintf(out, "(%f, %f, %f)\n", xyz->x / 65536.0, xyz->y / 65536.0, xyz->z / 65536.0); +} + +/******************************************************************************\ +* attribute table class +\******************************************************************************/ + +static void jas_icccurv_destroy(jas_iccattrval_t *attrval) +{ + jas_icccurv_t *curv = &attrval->data.curv; + if (curv->ents) + jas_free(curv->ents); +} + +static int jas_icccurv_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + jas_icccurv_t *curv = &attrval->data.curv; + unsigned int i; + + curv->numents = 0; + curv->ents = 0; + + if (jas_iccgetuint32(in, &curv->numents)) + goto error; + if (!(curv->ents = jas_alloc2(curv->numents, sizeof(jas_iccuint16_t)))) + goto error; + for (i = 0; i < curv->numents; ++i) { + if (jas_iccgetuint16(in, &curv->ents[i])) + goto error; + } + + if (JAS_CAST(int, 4 + 2 * curv->numents) != cnt) + goto error; + return 0; + +error: + jas_icccurv_destroy(attrval); + return -1; +} + +static int jas_icccurv_getsize(jas_iccattrval_t *attrval) +{ + jas_icccurv_t *curv = &attrval->data.curv; + return 4 + 2 * curv->numents; +} + +static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icccurv_t *curv = &attrval->data.curv; + unsigned int i; + + if (jas_iccputuint32(out, curv->numents)) + goto error; + for (i = 0; i < curv->numents; ++i) { + if (jas_iccputuint16(out, curv->ents[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out) +{ + int i; + jas_icccurv_t *curv = &attrval->data.curv; + fprintf(out, "number of entires = %d\n", (int)curv->numents); + if (curv->numents == 1) { + fprintf(out, "gamma = %f\n", curv->ents[0] / 256.0); + } else { + for (i = 0; i < JAS_CAST(int, curv->numents); ++i) { + if (i < 3 || i >= JAS_CAST(int, curv->numents) - 3) { + fprintf(out, "entry[%d] = %f\n", i, curv->ents[i] / 65535.0); + } + } + } +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + if (txtdesc->ascdata) + jas_free(txtdesc->ascdata); + if (txtdesc->ucdata) + jas_free(txtdesc->ucdata); +} + +static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + txtdesc = 0; + + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int n; + int c; + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + txtdesc->ascdata = 0; + txtdesc->ucdata = 0; + if (jas_iccgetuint32(in, &txtdesc->asclen)) + goto error; + if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen))) + goto error; + if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) != + JAS_CAST(int, txtdesc->asclen)) + goto error; + txtdesc->ascdata[txtdesc->asclen - 1] = '\0'; + if (jas_iccgetuint32(in, &txtdesc->uclangcode) || + jas_iccgetuint32(in, &txtdesc->uclen)) + goto error; + if (!(txtdesc->ucdata = jas_alloc2(txtdesc->uclen, 2))) + goto error; + if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) != + JAS_CAST(int, txtdesc->uclen * 2)) + goto error; + if (jas_iccgetuint16(in, &txtdesc->sccode)) + goto error; + if ((c = jas_stream_getc(in)) == EOF) + goto error; + txtdesc->maclen = c; + if (jas_stream_read(in, txtdesc->macdata, 67) != 67) + goto error; + txtdesc->asclen = strlen(txtdesc->ascdata) + 1; +#define WORKAROUND_BAD_PROFILES +#ifdef WORKAROUND_BAD_PROFILES + n = txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67; + if (n > cnt) { + return -1; + } + if (n < cnt) { + if (jas_stream_gobble(in, cnt - n) != cnt - n) + goto error; + } +#else + if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt) + return -1; +#endif + return 0; +error: + jas_icctxtdesc_destroy(attrval); + return -1; +} + +static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67; +} + +static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + if (jas_iccputuint32(out, txtdesc->asclen) || + jas_stream_puts(out, txtdesc->ascdata) || + jas_stream_putc(out, 0) == EOF || + jas_iccputuint32(out, txtdesc->uclangcode) || + jas_iccputuint32(out, txtdesc->uclen) || + jas_stream_write(out, txtdesc->ucdata, txtdesc->uclen * 2) != JAS_CAST(int, txtdesc->uclen * 2) || + jas_iccputuint16(out, txtdesc->sccode) || + jas_stream_putc(out, txtdesc->maclen) == EOF) + goto error; + if (txtdesc->maclen > 0) { + if (jas_stream_write(out, txtdesc->macdata, 67) != 67) + goto error; + } else { + if (jas_stream_pad(out, 67, 0) != 67) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + fprintf(out, "ascii = \"%s\"\n", txtdesc->ascdata); + fprintf(out, "uclangcode = %d; uclen = %d\n", (int)txtdesc->uclangcode, + (int)txtdesc->uclen); + fprintf(out, "sccode = %d\n", (int)txtdesc->sccode); + fprintf(out, "maclen = %d\n", txtdesc->maclen); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icctxt_destroy(jas_iccattrval_t *attrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + if (txt->string) + jas_free(txt->string); +} + +static int jas_icctxt_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + jas_icctxt_t *othtxt = &othattrval->data.txt; + if (!(txt->string = jas_strdup(othtxt->string))) + return -1; + return 0; +} + +static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + jas_icctxt_t *txt = &attrval->data.txt; + txt->string = 0; + if (!(txt->string = jas_malloc(cnt))) + goto error; + if (jas_stream_read(in, txt->string, cnt) != cnt) + goto error; + txt->string[cnt - 1] = '\0'; + if (JAS_CAST(int, strlen(txt->string)) + 1 != cnt) + goto error; + return 0; +error: + if (txt->string) + jas_free(txt->string); + return -1; +} + +static int jas_icctxt_getsize(jas_iccattrval_t *attrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + return strlen(txt->string) + 1; +} + +static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icctxt_t *txt = &attrval->data.txt; + if (jas_stream_puts(out, txt->string) || + jas_stream_putc(out, 0) == EOF) + return -1; + return 0; +} + +static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icctxt_t *txt = &attrval->data.txt; + fprintf(out, "string = \"%s\"\n", txt->string); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icclut8_destroy(jas_iccattrval_t *attrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + if (lut8->clut) + jas_free(lut8->clut); + if (lut8->intabs) + jas_free(lut8->intabs); + if (lut8->intabsbuf) + jas_free(lut8->intabsbuf); + if (lut8->outtabs) + jas_free(lut8->outtabs); + if (lut8->outtabsbuf) + jas_free(lut8->outtabsbuf); +} + +static int jas_icclut8_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + lut8 = 0; + abort(); + return -1; +} + +static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int i; + int j; + int clutsize; + jas_icclut8_t *lut8 = &attrval->data.lut8; + lut8->clut = 0; + lut8->intabs = 0; + lut8->intabsbuf = 0; + lut8->outtabs = 0; + lut8->outtabsbuf = 0; + if (jas_iccgetuint8(in, &lut8->numinchans) || + jas_iccgetuint8(in, &lut8->numoutchans) || + jas_iccgetuint8(in, &lut8->clutlen) || + jas_stream_getc(in) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccgetsint32(in, &lut8->e[i][j])) + goto error; + } + } + if (jas_iccgetuint16(in, &lut8->numintabents) || + jas_iccgetuint16(in, &lut8->numouttabents)) + goto error; + clutsize = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; + if (!(lut8->clut = jas_alloc2(clutsize, sizeof(jas_iccuint8_t))) || + !(lut8->intabsbuf = jas_alloc3(lut8->numinchans, + lut8->numintabents, sizeof(jas_iccuint8_t))) || + !(lut8->intabs = jas_alloc2(lut8->numinchans, + sizeof(jas_iccuint8_t *)))) + goto error; + for (i = 0; i < lut8->numinchans; ++i) + lut8->intabs[i] = &lut8->intabsbuf[i * lut8->numintabents]; + if (!(lut8->outtabsbuf = jas_alloc3(lut8->numoutchans, + lut8->numouttabents, sizeof(jas_iccuint8_t))) || + !(lut8->outtabs = jas_alloc2(lut8->numoutchans, + sizeof(jas_iccuint8_t *)))) + goto error; + for (i = 0; i < lut8->numoutchans; ++i) + lut8->outtabs[i] = &lut8->outtabsbuf[i * lut8->numouttabents]; + for (i = 0; i < lut8->numinchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut8->numintabents); ++j) { + if (jas_iccgetuint8(in, &lut8->intabs[i][j])) + goto error; + } + } + for (i = 0; i < lut8->numoutchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut8->numouttabents); ++j) { + if (jas_iccgetuint8(in, &lut8->outtabs[i][j])) + goto error; + } + } + for (i = 0; i < clutsize; ++i) { + if (jas_iccgetuint8(in, &lut8->clut[i])) + goto error; + } + if (JAS_CAST(int, 44 + lut8->numinchans * lut8->numintabents + + lut8->numoutchans * lut8->numouttabents + + jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans) != + cnt) + goto error; + return 0; +error: + jas_icclut8_destroy(attrval); + return -1; +} + +static int jas_icclut8_getsize(jas_iccattrval_t *attrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + return 44 + lut8->numinchans * lut8->numintabents + + lut8->numoutchans * lut8->numouttabents + + jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; +} + +static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + int i; + int j; + int n; + lut8->clut = 0; + lut8->intabs = 0; + lut8->intabsbuf = 0; + lut8->outtabs = 0; + lut8->outtabsbuf = 0; + if (jas_stream_putc(out, lut8->numinchans) == EOF || + jas_stream_putc(out, lut8->numoutchans) == EOF || + jas_stream_putc(out, lut8->clutlen) == EOF || + jas_stream_putc(out, 0) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccputsint32(out, lut8->e[i][j])) + goto error; + } + } + if (jas_iccputuint16(out, lut8->numintabents) || + jas_iccputuint16(out, lut8->numouttabents)) + goto error; + n = lut8->numinchans * lut8->numintabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->intabsbuf[i])) + goto error; + } + n = lut8->numoutchans * lut8->numouttabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->outtabsbuf[i])) + goto error; + } + n = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->clut[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + int i; + int j; + fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n", + lut8->numinchans, lut8->numoutchans, lut8->clutlen); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + fprintf(out, "e[%d][%d]=%f ", i, j, lut8->e[i][j] / 65536.0); + } + fprintf(out, "\n"); + } + fprintf(out, "numintabents=%d, numouttabents=%d\n", + (int)lut8->numintabents, (int)lut8->numouttabents); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icclut16_destroy(jas_iccattrval_t *attrval) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + if (lut16->clut) + jas_free(lut16->clut); + if (lut16->intabs) + jas_free(lut16->intabs); + if (lut16->intabsbuf) + jas_free(lut16->intabsbuf); + if (lut16->outtabs) + jas_free(lut16->outtabs); + if (lut16->outtabsbuf) + jas_free(lut16->outtabsbuf); +} + +static int jas_icclut16_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int i; + int j; + int clutsize; + jas_icclut16_t *lut16 = &attrval->data.lut16; + lut16->clut = 0; + lut16->intabs = 0; + lut16->intabsbuf = 0; + lut16->outtabs = 0; + lut16->outtabsbuf = 0; + if (jas_iccgetuint8(in, &lut16->numinchans) || + jas_iccgetuint8(in, &lut16->numoutchans) || + jas_iccgetuint8(in, &lut16->clutlen) || + jas_stream_getc(in) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccgetsint32(in, &lut16->e[i][j])) + goto error; + } + } + if (jas_iccgetuint16(in, &lut16->numintabents) || + jas_iccgetuint16(in, &lut16->numouttabents)) + goto error; + clutsize = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans; + if (!(lut16->clut = jas_alloc2(clutsize, sizeof(jas_iccuint16_t))) || + !(lut16->intabsbuf = jas_alloc3(lut16->numinchans, + lut16->numintabents, sizeof(jas_iccuint16_t))) || + !(lut16->intabs = jas_alloc2(lut16->numinchans, + sizeof(jas_iccuint16_t *)))) + goto error; + for (i = 0; i < lut16->numinchans; ++i) + lut16->intabs[i] = &lut16->intabsbuf[i * lut16->numintabents]; + if (!(lut16->outtabsbuf = jas_alloc3(lut16->numoutchans, + lut16->numouttabents, sizeof(jas_iccuint16_t))) || + !(lut16->outtabs = jas_alloc2(lut16->numoutchans, + sizeof(jas_iccuint16_t *)))) + goto error; + for (i = 0; i < lut16->numoutchans; ++i) + lut16->outtabs[i] = &lut16->outtabsbuf[i * lut16->numouttabents]; + for (i = 0; i < lut16->numinchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut16->numintabents); ++j) { + if (jas_iccgetuint16(in, &lut16->intabs[i][j])) + goto error; + } + } + for (i = 0; i < lut16->numoutchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut16->numouttabents); ++j) { + if (jas_iccgetuint16(in, &lut16->outtabs[i][j])) + goto error; + } + } + for (i = 0; i < clutsize; ++i) { + if (jas_iccgetuint16(in, &lut16->clut[i])) + goto error; + } + if (JAS_CAST(int, 44 + 2 * (lut16->numinchans * lut16->numintabents + + lut16->numoutchans * lut16->numouttabents + + jas_iccpowi(lut16->clutlen, lut16->numinchans) * + lut16->numoutchans)) != cnt) + goto error; + return 0; +error: + jas_icclut16_destroy(attrval); + return -1; +} + +static int jas_icclut16_getsize(jas_iccattrval_t *attrval) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + return 44 + 2 * (lut16->numinchans * lut16->numintabents + + lut16->numoutchans * lut16->numouttabents + + jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans); +} + +static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + int i; + int j; + int n; + if (jas_stream_putc(out, lut16->numinchans) == EOF || + jas_stream_putc(out, lut16->numoutchans) == EOF || + jas_stream_putc(out, lut16->clutlen) == EOF || + jas_stream_putc(out, 0) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccputsint32(out, lut16->e[i][j])) + goto error; + } + } + if (jas_iccputuint16(out, lut16->numintabents) || + jas_iccputuint16(out, lut16->numouttabents)) + goto error; + n = lut16->numinchans * lut16->numintabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->intabsbuf[i])) + goto error; + } + n = lut16->numoutchans * lut16->numouttabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->outtabsbuf[i])) + goto error; + } + n = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->clut[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + int i; + int j; + fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n", + lut16->numinchans, lut16->numoutchans, lut16->clutlen); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + fprintf(out, "e[%d][%d]=%f ", i, j, lut16->e[i][j] / 65536.0); + } + fprintf(out, "\n"); + } + fprintf(out, "numintabents=%d, numouttabents=%d\n", + (int)lut16->numintabents, (int)lut16->numouttabents); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val) +{ + int i; + int c; + ulonglong v; + v = 0; + for (i = n; i > 0; --i) { + if ((c = jas_stream_getc(in)) == EOF) + return -1; + v = (v << 8) | c; + } + *val = v; + return 0; +} + +static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val) +{ + int c; + if ((c = jas_stream_getc(in)) == EOF) + return -1; + *val = c; + return 0; +} + +static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 2, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 4, &tmp)) + return -1; + *val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) & + 0x7fffffff) + 1))) : JAS_CAST(longlong, tmp); + return 0; +} + +static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 4, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 8, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val) +{ + int i; + int c; + for (i = n; i > 0; --i) { + c = (val >> (8 * (i - 1))) & 0xff; + if (jas_stream_putc(out, c) == EOF) + return -1; + } + return 0; +} + +static int jas_iccputsint(jas_stream_t *out, int n, longlong val) +{ + ulonglong tmp; + tmp = (val < 0) ? (abort(), 0) : val; + return jas_iccputuint(out, n, tmp); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static char *jas_iccsigtostr(int sig, char *buf) +{ + int n; + int c; + char *bufptr; + bufptr = buf; + for (n = 4; n > 0; --n) { + c = (sig >> 24) & 0xff; + if (isalpha(c) || isdigit(c)) { + *bufptr++ = c; + } + sig <<= 8; + } + *bufptr = '\0'; + return buf; +} + +static long jas_iccpadtomult(long x, long y) +{ + return ((x + y - 1) / y) * y; +} + +static long jas_iccpowi(int x, int n) +{ + long y; + y = 1; + while (--n >= 0) + y *= x; + return y; +} + + +jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len) +{ + jas_stream_t *in; + jas_iccprof_t *prof; + if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len))) + goto error; + if (!(prof = jas_iccprof_load(in))) + goto error; + jas_stream_close(in); + return prof; +error: + return 0; +} + +jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc) +{ + jas_iccprof_t *prof; + switch (clrspc) { + case JAS_CLRSPC_SRGB: + prof = jas_iccprof_createfrombuf(jas_iccprofdata_srgb, + jas_iccprofdata_srgblen); + break; + case JAS_CLRSPC_SGRAY: + prof = jas_iccprof_createfrombuf(jas_iccprofdata_sgray, + jas_iccprofdata_sgraylen); + break; + default: + prof = 0; + break; + } + return prof; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_iccdata.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_iccdata.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_iccdata.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_iccdata.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include +#include + +uchar jas_iccprofdata_srgb[] = +{ + 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, + 0x02, 0x10, 0x00, 0x00, 0x6d, 0x6e, 0x74, 0x72, + 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, + 0x00, 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, + 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, + 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x63, 0x70, 0x72, 0x74, + 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x33, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, + 0x00, 0x00, 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, + 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04, + 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, + 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x2c, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, + 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, + 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64, 0x64, + 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, + 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, + 0x00, 0x00, 0x00, 0x86, 0x76, 0x69, 0x65, 0x77, + 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24, + 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, + 0x00, 0x00, 0x00, 0x14, 0x6d, 0x65, 0x61, 0x73, + 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x24, + 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, + 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, + 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, + 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, + 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, + 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, + 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, + 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, + 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00, 0x38, 0xf5, + 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, + 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, + 0x00, 0x00, 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, + 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x69, 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, + 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, + 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2d, + 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, + 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, + 0x47, 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, + 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, + 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, + 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, + 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, + 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, + 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0xfe, + 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, + 0x00, 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, + 0x00, 0x03, 0x5c, 0x9e, 0x00, 0x00, 0x00, 0x01, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x57, 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, + 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, + 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, + 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, + 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, + 0x00, 0x4f, 0x00, 0x54, 0x00, 0x59, 0x00, 0x5e, + 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72, + 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, + 0x00, 0x8b, 0x00, 0x90, 0x00, 0x95, 0x00, 0x9a, + 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae, + 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, + 0x00, 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, + 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb, + 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, + 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, + 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, + 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, + 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67, + 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, + 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, + 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9, 0x01, 0xc1, + 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, + 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, + 0x02, 0x0c, 0x02, 0x14, 0x02, 0x1d, 0x02, 0x26, + 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b, + 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, + 0x02, 0x7a, 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, + 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1, + 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, + 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, + 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43, + 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, + 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, + 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, + 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, + 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04, 0x3b, + 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, + 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, + 0x04, 0xb6, 0x04, 0xc4, 0x04, 0xd3, 0x04, 0xe1, + 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c, + 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, + 0x05, 0x67, 0x05, 0x77, 0x05, 0x86, 0x05, 0x96, + 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5, + 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, + 0x06, 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, + 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d, + 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, + 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, + 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, + 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, + 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b, + 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, + 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, + 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7, 0x08, 0xfb, + 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, + 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, + 0x09, 0xba, 0x09, 0xcf, 0x09, 0xe5, 0x09, 0xfb, + 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54, + 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, + 0x0a, 0xc5, 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, + 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69, + 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, + 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, + 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e, + 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, + 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, + 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, + 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, + 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e, 0x9b, + 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, + 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, + 0x0f, 0x96, 0x0f, 0xb3, 0x0f, 0xcf, 0x0f, 0xec, + 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61, + 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, + 0x10, 0xf5, 0x11, 0x13, 0x11, 0x31, 0x11, 0x4f, + 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9, + 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, + 0x12, 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, + 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43, + 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, + 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, + 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, + 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, + 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0, + 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, + 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, + 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65, 0x17, 0x89, + 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, + 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, + 0x18, 0xd5, 0x18, 0xfa, 0x19, 0x20, 0x19, 0x45, + 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd, + 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, + 0x1a, 0x9e, 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, + 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2, + 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, + 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, + 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99, + 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, + 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, + 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, + 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, + 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20, 0xf0, + 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, + 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, + 0x22, 0x82, 0x22, 0xaf, 0x22, 0xdd, 0x23, 0x0a, + 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2, + 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, + 0x24, 0xab, 0x24, 0xda, 0x25, 0x09, 0x25, 0x38, + 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7, + 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, + 0x26, 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, + 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f, + 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, + 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, + 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, + 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, + 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39, + 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, + 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, + 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82, 0x2e, 0xb7, + 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, + 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, + 0x30, 0xa4, 0x30, 0xdb, 0x31, 0x12, 0x31, 0x4a, + 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a, + 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, + 0x33, 0x46, 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, + 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8, + 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, + 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, + 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c, + 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, + 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, + 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, + 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, + 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c, 0x65, + 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, + 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, + 0x3e, 0xa0, 0x3e, 0xe0, 0x3f, 0x21, 0x3f, 0x61, + 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64, + 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, + 0x41, 0xac, 0x41, 0xee, 0x42, 0x30, 0x42, 0x72, + 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d, + 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, + 0x44, 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, + 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab, + 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, + 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, + 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, + 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, + 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a, + 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, + 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, + 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49, 0x4f, 0x93, + 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, + 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, + 0x52, 0x31, 0x52, 0x7c, 0x52, 0xc7, 0x53, 0x13, + 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42, + 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, + 0x55, 0xc2, 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, + 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0, + 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, + 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, + 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95, + 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, + 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, + 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, + 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, + 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61, 0xf5, + 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, + 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, + 0x64, 0xe9, 0x65, 0x3d, 0x65, 0x92, 0x65, 0xe7, + 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d, + 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, + 0x68, 0xec, 0x69, 0x43, 0x69, 0x9a, 0x69, 0xf1, + 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f, + 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, + 0x6d, 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, + 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78, + 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, + 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, + 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, + 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, + 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b, + 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, + 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, + 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5, 0x7b, 0x04, + 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, + 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, + 0x7e, 0x62, 0x7e, 0xc2, 0x7f, 0x23, 0x7f, 0x84, + 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a, + 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, + 0x82, 0xf4, 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, + 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab, + 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, + 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, + 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64, + 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, + 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, + 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, + 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, + 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92, 0x7a, + 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, + 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, + 0x96, 0x34, 0x96, 0x9f, 0x97, 0x0a, 0x97, 0x75, + 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24, + 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, + 0x9b, 0x42, 0x9b, 0xaf, 0x9c, 0x1c, 0x9c, 0x89, + 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40, + 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, + 0xa0, 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, + 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76, + 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, + 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, + 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, + 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, + 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c, + 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, + 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, + 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60, 0xb1, 0xd6, + 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, + 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, + 0xb6, 0x01, 0xb6, 0x79, 0xb6, 0xf0, 0xb7, 0x68, + 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a, + 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, + 0xbb, 0xa7, 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, + 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff, + 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, + 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, + 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce, + 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, + 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, + 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, + 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, + 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce, 0xb6, + 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, + 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, + 0xd3, 0x44, 0xd3, 0xc6, 0xd4, 0x49, 0xd4, 0xcb, + 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8, + 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, + 0xd9, 0x6c, 0xd9, 0xf1, 0xda, 0x76, 0xda, 0xfb, + 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10, + 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, + 0xdf, 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, + 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63, + 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, + 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, + 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, + 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, + 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28, + 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, + 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, + 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34, 0xf4, 0xc2, + 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, + 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, + 0xf9, 0xc7, 0xfa, 0x57, 0xfa, 0xe7, 0xfb, 0x77, + 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba, + 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff +}; + +int jas_iccprofdata_srgblen = sizeof(jas_iccprofdata_srgb); + +uchar jas_iccprofdata_sgray[] = { + 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x20, 0x00, 0x00, 0x73, 0x63, 0x6e, 0x72, + 0x47, 0x52, 0x41, 0x59, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xd3, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d, + 0x00, 0x35, 0x00, 0x21, 0x61, 0x63, 0x73, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x4b, 0x4f, 0x44, 0x41, 0x73, 0x47, 0x72, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, + 0x4a, 0x50, 0x45, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x86, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x3c, + 0x00, 0x00, 0x00, 0x2b, 0x77, 0x74, 0x70, 0x74, + 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x14, + 0x6b, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x7c, + 0x00, 0x00, 0x00, 0x0e, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x49, 0x43, 0x43, 0x20, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x6e, + 0x67, 0x20, 0x73, 0x52, 0x47, 0x42, 0x2d, 0x67, + 0x72, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, + 0x30, 0x33, 0x20, 0x73, 0x52, 0x47, 0x42, 0x2d, + 0x67, 0x72, 0x65, 0x79, 0x20, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x54, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x16, 0xcf, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0xcd +}; + +int jas_iccprofdata_sgraylen = sizeof(jas_iccprofdata_sgray); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_image.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_image.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_image.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_image.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1444 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Image Library + * + * $Id: jas_image.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "jasper/jas_math.h" +#include "jasper/jas_image.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +#define FLOORDIV(x, y) ((x) / (y)) + +/******************************************************************************\ +* Local prototypes. +\******************************************************************************/ + +static jas_image_cmpt_t *jas_image_cmpt_create0(void); +static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt); +static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, + uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t + height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem); +static void jas_image_setbbox(jas_image_t *image); +static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt); +static int jas_image_growcmpts(jas_image_t *image, int maxcmpts); +static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd); +static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd); +static int putint(jas_stream_t *out, int sgnd, int prec, long val); +static int getint(jas_stream_t *in, int sgnd, int prec, long *val); +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry); +static long uptomult(long x, long y); +static long downtomult(long x, long y); +static long convert(long val, int oldsgnd, int oldprec, int newsgnd, + int newprec); +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry); + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +static int jas_image_numfmts = 0; +static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS]; + +/******************************************************************************\ +* Create and destroy operations. +\******************************************************************************/ + +jas_image_t *jas_image_create(int numcmpts, jas_image_cmptparm_t *cmptparms, + int clrspc) +{ + jas_image_t *image; + uint_fast32_t rawsize; + uint_fast32_t inmem; + int cmptno; + jas_image_cmptparm_t *cmptparm; + + if (!(image = jas_image_create0())) { + return 0; + } + + image->clrspc_ = clrspc; + image->maxcmpts_ = numcmpts; + image->inmem_ = true; + + /* Allocate memory for the per-component information. */ + if (!(image->cmpts_ = jas_alloc2(image->maxcmpts_, + sizeof(jas_image_cmpt_t *)))) { + jas_image_destroy(image); + return 0; + } + /* Initialize in case of failure. */ + for (cmptno = 0; cmptno < image->maxcmpts_; ++cmptno) { + image->cmpts_[cmptno] = 0; + } + + /* Compute the approximate raw size of the image. */ + rawsize = 0; + for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, + ++cmptparm) { + rawsize += cmptparm->width * cmptparm->height * + (cmptparm->prec + 7) / 8; + } + /* Decide whether to buffer the image data in memory, based on the + raw size of the image. */ + inmem = (rawsize < JAS_IMAGE_INMEMTHRESH); + + /* Create the individual image components. */ + for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, + ++cmptparm) { + if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx, + cmptparm->tly, cmptparm->hstep, cmptparm->vstep, + cmptparm->width, cmptparm->height, cmptparm->prec, + cmptparm->sgnd, inmem))) { + jas_image_destroy(image); + return 0; + } + ++image->numcmpts_; + } + + /* Determine the bounding box for all of the components on the + reference grid (i.e., the image area) */ + jas_image_setbbox(image); + + return image; +} + +jas_image_t *jas_image_create0() +{ + jas_image_t *image; + + if (!(image = jas_malloc(sizeof(jas_image_t)))) { + return 0; + } + + image->tlx_ = 0; + image->tly_ = 0; + image->brx_ = 0; + image->bry_ = 0; + image->clrspc_ = JAS_CLRSPC_UNKNOWN; + image->numcmpts_ = 0; + image->maxcmpts_ = 0; + image->cmpts_ = 0; + image->inmem_ = true; + image->cmprof_ = 0; + + return image; +} + +jas_image_t *jas_image_copy(jas_image_t *image) +{ + jas_image_t *newimage; + int cmptno; + + newimage = jas_image_create0(); + if (jas_image_growcmpts(newimage, image->numcmpts_)) { + goto error; + } + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(image->cmpts_[cmptno]))) { + goto error; + } + ++newimage->numcmpts_; + } + + jas_image_setbbox(newimage); + + if (image->cmprof_) { + if (!(newimage->cmprof_ = jas_cmprof_copy(image->cmprof_))) + goto error; + } + + return newimage; +error: + if (newimage) { + jas_image_destroy(newimage); + } + return 0; +} + +static jas_image_cmpt_t *jas_image_cmpt_create0() +{ + jas_image_cmpt_t *cmpt; + if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { + return 0; + } + memset(cmpt, 0, sizeof(jas_image_cmpt_t)); + cmpt->type_ = JAS_IMAGE_CT_UNKNOWN; + return cmpt; +} + +static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt) +{ + jas_image_cmpt_t *newcmpt; + + if (!(newcmpt = jas_image_cmpt_create0())) { + return 0; + } + newcmpt->tlx_ = cmpt->tlx_; + newcmpt->tly_ = cmpt->tly_; + newcmpt->hstep_ = cmpt->hstep_; + newcmpt->vstep_ = cmpt->vstep_; + newcmpt->width_ = cmpt->width_; + newcmpt->height_ = cmpt->height_; + newcmpt->prec_ = cmpt->prec_; + newcmpt->sgnd_ = cmpt->sgnd_; + newcmpt->cps_ = cmpt->cps_; + newcmpt->type_ = cmpt->type_; + if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) { + return 0; + } + if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) { + return 0; + } + if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) { + return 0; + } + if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) { + return 0; + } + return newcmpt; +} + +void jas_image_destroy(jas_image_t *image) +{ + int i; + + if (image->cmpts_) { + for (i = 0; i < image->numcmpts_; ++i) { + jas_image_cmpt_destroy(image->cmpts_[i]); + image->cmpts_[i] = 0; + } + jas_free(image->cmpts_); + } + if (image->cmprof_) + jas_cmprof_destroy(image->cmprof_); + jas_free(image); +} + +static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, + uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t + height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem) +{ + jas_image_cmpt_t *cmpt; + long size; + + if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { + return 0; + } + + cmpt->type_ = JAS_IMAGE_CT_UNKNOWN; + cmpt->tlx_ = tlx; + cmpt->tly_ = tly; + cmpt->hstep_ = hstep; + cmpt->vstep_ = vstep; + cmpt->width_ = width; + cmpt->height_ = height; + cmpt->prec_ = depth; + cmpt->sgnd_ = sgnd; + cmpt->stream_ = 0; + cmpt->cps_ = (depth + 7) / 8; + + size = cmpt->width_ * cmpt->height_ * cmpt->cps_; + cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile(); + if (!cmpt->stream_) { + jas_image_cmpt_destroy(cmpt); + return 0; + } + + /* Zero the component data. This isn't necessary, but it is + convenient for debugging purposes. */ + if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 || + jas_stream_putc(cmpt->stream_, 0) == EOF || + jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) { + jas_image_cmpt_destroy(cmpt); + return 0; + } + + return cmpt; +} + +static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt) +{ + if (cmpt->stream_) { + jas_stream_close(cmpt->stream_); + } + jas_free(cmpt); +} + +/******************************************************************************\ +* Load and save operations. +\******************************************************************************/ + +jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr) +{ + jas_image_fmtinfo_t *fmtinfo; + jas_image_t *image; + + image = 0; + + /* If possible, try to determine the format of the input data. */ + if (fmt < 0) { + if ((fmt = jas_image_getfmt(in)) < 0) + goto error; + } + + /* Is it possible to decode an image represented in this format? */ + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) + goto error; + if (!fmtinfo->ops.decode) + goto error; + + /* Decode the image. */ + if (!(image = (*fmtinfo->ops.decode)(in, optstr))) + goto error; + + /* Create a color profile if needed. */ + if (!jas_clrspc_isunknown(image->clrspc_) && + !jas_clrspc_isgeneric(image->clrspc_) && !image->cmprof_) { + if (!(image->cmprof_ = + jas_cmprof_createfromclrspc(jas_image_clrspc(image)))) + goto error; + } + + return image; +error: + if (image) + jas_image_destroy(image); + return 0; +} + +int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, char *optstr) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { + return -1; + } + return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out, + optstr) : (-1); +} + +/******************************************************************************\ +* Component read and write operations. +\******************************************************************************/ + +int jas_image_readcmpt(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + jas_matrix_t *data) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + int k; + jas_seqent_t v; + int c; + jas_seqent_t *dr; + jas_seqent_t *d; + int drs; + + if (cmptno < 0 || cmptno >= image->numcmpts_) { + return -1; + } + + cmpt = image->cmpts_[cmptno]; + if (x >= cmpt->width_ || y >= cmpt->height_ || + x + width > cmpt->width_ || + y + height > cmpt->height_) { + return -1; + } + + if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) { + if (jas_matrix_resize(data, height, width)) { + return -1; + } + } + + dr = jas_matrix_getref(data, 0, 0); + drs = jas_matrix_rowstep(data); + for (i = 0; i < height; ++i, dr += drs) { + d = dr; + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) { + return -1; + } + for (j = width; j > 0; --j, ++d) { + v = 0; + for (k = cmpt->cps_; k > 0; --k) { + if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { + return -1; + } + v = (v << 8) | (c & 0xff); + } + *d = bitstoint(v, cmpt->prec_, cmpt->sgnd_); + } + } + + return 0; +} + +int jas_image_writecmpt(jas_image_t *image, int cmptno, jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, + jas_image_coord_t height, jas_matrix_t *data) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + jas_seqent_t *d; + jas_seqent_t *dr; + int drs; + jas_seqent_t v; + int k; + int c; + + if (cmptno < 0 || cmptno >= image->numcmpts_) { + return -1; + } + + cmpt = image->cmpts_[cmptno]; + if (x >= cmpt->width_ || y >= cmpt->height_ || + x + width > cmpt->width_ || + y + height > cmpt->height_) { + return -1; + } + + if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) { + return -1; + } + + dr = jas_matrix_getref(data, 0, 0); + drs = jas_matrix_rowstep(data); + for (i = 0; i < height; ++i, dr += drs) { + d = dr; + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) { + return -1; + } + for (j = width; j > 0; --j, ++d) { + v = inttobits(*d, cmpt->prec_, cmpt->sgnd_); + for (k = cmpt->cps_; k > 0; --k) { + c = (v >> (8 * (cmpt->cps_ - 1))) & 0xff; + if (jas_stream_putc(cmpt->stream_, + (unsigned char) c) == EOF) { + return -1; + } + v <<= 8; + } + } + } + + return 0; +} + +/******************************************************************************\ +* File format operations. +\******************************************************************************/ + +void jas_image_clearfmts() +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + for (i = 0; i < jas_image_numfmts; ++i) { + fmtinfo = &jas_image_fmtinfos[i]; + if (fmtinfo->name) { + jas_free(fmtinfo->name); + fmtinfo->name = 0; + } + if (fmtinfo->ext) { + jas_free(fmtinfo->ext); + fmtinfo->ext = 0; + } + if (fmtinfo->desc) { + jas_free(fmtinfo->desc); + fmtinfo->desc = 0; + } + } + jas_image_numfmts = 0; +} + +int jas_image_addfmt(int id, char *name, char *ext, char *desc, + jas_image_fmtops_t *ops) +{ + jas_image_fmtinfo_t *fmtinfo; + assert(id >= 0 && name && ext && ops); + if (jas_image_numfmts >= JAS_IMAGE_MAXFMTS) { + return -1; + } + fmtinfo = &jas_image_fmtinfos[jas_image_numfmts]; + fmtinfo->id = id; + if (!(fmtinfo->name = jas_strdup(name))) { + return -1; + } + if (!(fmtinfo->ext = jas_strdup(ext))) { + jas_free(fmtinfo->name); + return -1; + } + if (!(fmtinfo->desc = jas_strdup(desc))) { + jas_free(fmtinfo->name); + jas_free(fmtinfo->ext); + return -1; + } + fmtinfo->ops = *ops; + ++jas_image_numfmts; + return 0; +} + +int jas_image_strtofmt(char *name) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyname(name))) { + return -1; + } + return fmtinfo->id; +} + +char *jas_image_fmttostr(int fmt) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { + return 0; + } + return fmtinfo->name; +} + +int jas_image_getfmt(jas_stream_t *in) +{ + jas_image_fmtinfo_t *fmtinfo; + int found; + int i; + + /* Check for data in each of the supported formats. */ + found = 0; + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, + ++fmtinfo) { + if (fmtinfo->ops.validate) { + /* Is the input data valid for this format? */ + if (!(*fmtinfo->ops.validate)(in)) { + found = 1; + break; + } + } + } + return found ? fmtinfo->id : (-1); +} + +int jas_image_fmtfromname(char *name) +{ + int i; + char *ext; + jas_image_fmtinfo_t *fmtinfo; + /* Get the file name extension. */ + if (!(ext = strrchr(name, '.'))) { + return -1; + } + ++ext; + /* Try to find a format that uses this extension. */ + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, + ++fmtinfo) { + /* Do we have a match? */ + if (!strcmp(ext, fmtinfo->ext)) { + return fmtinfo->id; + } + } + return -1; +} + +/******************************************************************************\ +* Miscellaneous operations. +\******************************************************************************/ + +uint_fast32_t jas_image_rawsize(jas_image_t *image) +{ + uint_fast32_t rawsize; + int cmptno; + jas_image_cmpt_t *cmpt; + + rawsize = 0; + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + rawsize += (cmpt->width_ * cmpt->height_ * cmpt->prec_ + + 7) / 8; + } + return rawsize; +} + +void jas_image_delcmpt(jas_image_t *image, int cmptno) +{ + if (cmptno >= image->numcmpts_) { + return; + } + jas_image_cmpt_destroy(image->cmpts_[cmptno]); + if (cmptno < image->numcmpts_) { + memmove(&image->cmpts_[cmptno], &image->cmpts_[cmptno + 1], + (image->numcmpts_ - 1 - cmptno) * sizeof(jas_image_cmpt_t *)); + } + --image->numcmpts_; + + jas_image_setbbox(image); +} + +int jas_image_addcmpt(jas_image_t *image, int cmptno, + jas_image_cmptparm_t *cmptparm) +{ + jas_image_cmpt_t *newcmpt; + if (cmptno < 0) + cmptno = image->numcmpts_; + assert(cmptno >= 0 && cmptno <= image->numcmpts_); + if (image->numcmpts_ >= image->maxcmpts_) { + if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) { + return -1; + } + } + if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx, + cmptparm->tly, cmptparm->hstep, cmptparm->vstep, + cmptparm->width, cmptparm->height, cmptparm->prec, + cmptparm->sgnd, 1))) { + return -1; + } + if (cmptno < image->numcmpts_) { + memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno], + (image->numcmpts_ - cmptno) * sizeof(jas_image_cmpt_t *)); + } + image->cmpts_[cmptno] = newcmpt; + ++image->numcmpts_; + + jas_image_setbbox(image); + + return 0; +} + +jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id) +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { + if (fmtinfo->id == id) { + return fmtinfo; + } + } + return 0; +} + +jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name) +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { + if (!strcmp(fmtinfo->name, name)) { + return fmtinfo; + } + } + return 0; +} + + + + + +static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd) +{ + uint_fast32_t ret; + ret = ((sgnd && v < 0) ? ((1 << prec) + v) : v) & JAS_ONES(prec); + return ret; +} + +static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd) +{ + jas_seqent_t ret; + v &= JAS_ONES(prec); + ret = (sgnd && (v & (1 << (prec - 1)))) ? (v - (1 << prec)) : v; + return ret; +} + +static void jas_image_setbbox(jas_image_t *image) +{ + jas_image_cmpt_t *cmpt; + int cmptno; + int_fast32_t x; + int_fast32_t y; + + if (image->numcmpts_ > 0) { + /* Determine the bounding box for all of the components on the + reference grid (i.e., the image area) */ + cmpt = image->cmpts_[0]; + image->tlx_ = cmpt->tlx_; + image->tly_ = cmpt->tly_; + image->brx_ = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; + image->bry_ = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; + for (cmptno = 1; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + if (image->tlx_ > cmpt->tlx_) { + image->tlx_ = cmpt->tlx_; + } + if (image->tly_ > cmpt->tly_) { + image->tly_ = cmpt->tly_; + } + x = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; + if (image->brx_ < x) { + image->brx_ = x; + } + y = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; + if (image->bry_ < y) { + image->bry_ = y; + } + } + } else { + image->tlx_ = 0; + image->tly_ = 0; + image->brx_ = 0; + image->bry_ = 0; + } +} + +static int jas_image_growcmpts(jas_image_t *image, int maxcmpts) +{ + jas_image_cmpt_t **newcmpts; + int cmptno; + + newcmpts = jas_realloc2(image->cmpts_, maxcmpts, sizeof(jas_image_cmpt_t *)); + if (!newcmpts) { + return -1; + } + image->cmpts_ = newcmpts; + image->maxcmpts_ = maxcmpts; + for (cmptno = image->numcmpts_; cmptno < image->maxcmpts_; ++cmptno) { + image->cmpts_[cmptno] = 0; + } + return 0; +} + +int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, jas_image_t *srcimage, + int srccmptno) +{ + jas_image_cmpt_t *newcmpt; + if (dstimage->numcmpts_ >= dstimage->maxcmpts_) { + if (jas_image_growcmpts(dstimage, dstimage->maxcmpts_ + 128)) { + return -1; + } + } + if (!(newcmpt = jas_image_cmpt_copy(srcimage->cmpts_[srccmptno]))) { + return -1; + } + if (dstcmptno < dstimage->numcmpts_) { + memmove(&dstimage->cmpts_[dstcmptno + 1], &dstimage->cmpts_[dstcmptno], + (dstimage->numcmpts_ - dstcmptno) * sizeof(jas_image_cmpt_t *)); + } + dstimage->cmpts_[dstcmptno] = newcmpt; + ++dstimage->numcmpts_; + + jas_image_setbbox(dstimage); + return 0; +} + +void jas_image_dump(jas_image_t *image, FILE *out) +{ + long buf[1024]; + int cmptno; + int n; + int i; + int width; + int height; + jas_image_cmpt_t *cmpt; + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + fprintf(out, "prec=%d, sgnd=%d, cmpttype=%d\n", cmpt->prec_, + cmpt->sgnd_, (int)cmpt->type_); + width = jas_image_cmptwidth(image, cmptno); + height = jas_image_cmptheight(image, cmptno); + n = JAS_MIN(16, width); + if (jas_image_readcmpt2(image, cmptno, 0, 0, n, 1, buf)) { + abort(); + } + for (i = 0; i < n; ++i) { + fprintf(out, " f(%d,%d)=%ld", i, 0, buf[i]); + } + fprintf(out, "\n"); + if (jas_image_readcmpt2(image, cmptno, width - n, height - 1, n, 1, buf)) { + abort(); + } + for (i = 0; i < n; ++i) { + fprintf(out, " f(%d,%d)=%ld", width - n + i, height - 1, buf[i]); + } + fprintf(out, "\n"); + } +} + +int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents, + int_fast32_t *lutents, int dtype, int newcmptno) +{ + jas_image_cmptparm_t cmptparms; + int_fast32_t v; + int i; + int j; + jas_image_cmpt_t *cmpt; + + cmpt = image->cmpts_[cmptno]; + cmptparms.tlx = cmpt->tlx_; + cmptparms.tly = cmpt->tly_; + cmptparms.hstep = cmpt->hstep_; + cmptparms.vstep = cmpt->vstep_; + cmptparms.width = cmpt->width_; + cmptparms.height = cmpt->height_; + cmptparms.prec = JAS_IMAGE_CDT_GETPREC(dtype); + cmptparms.sgnd = JAS_IMAGE_CDT_GETSGND(dtype); + + if (jas_image_addcmpt(image, newcmptno, &cmptparms)) { + return -1; + } + if (newcmptno <= cmptno) { + ++cmptno; + cmpt = image->cmpts_[cmptno]; + } + + for (j = 0; j < cmpt->height_; ++j) { + for (i = 0; i < cmpt->width_; ++i) { + v = jas_image_readcmptsample(image, cmptno, i, j); + if (v < 0) { + v = 0; + } else if (v >= numlutents) { + v = numlutents - 1; + } + jas_image_writecmptsample(image, newcmptno, i, j, + lutents[v]); + } + } + return 0; +} + +int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y) +{ + jas_image_cmpt_t *cmpt; + uint_fast32_t v; + int k; + int c; + + cmpt = image->cmpts_[cmptno]; + + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, + SEEK_SET) < 0) { + return -1; + } + v = 0; + for (k = cmpt->cps_; k > 0; --k) { + if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { + return -1; + } + v = (v << 8) | (c & 0xff); + } + return bitstoint(v, cmpt->prec_, cmpt->sgnd_); +} + +void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y, + int_fast32_t v) +{ + jas_image_cmpt_t *cmpt; + uint_fast32_t t; + int k; + int c; + + cmpt = image->cmpts_[cmptno]; + + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, + SEEK_SET) < 0) { + return; + } + t = inttobits(v, cmpt->prec_, cmpt->sgnd_); + for (k = cmpt->cps_; k > 0; --k) { + c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff; + if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) { + return; + } + t <<= 8; + } +} + +int jas_image_getcmptbytype(jas_image_t *image, int ctype) +{ + int cmptno; + + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + if (image->cmpts_[cmptno]->type_ == ctype) { + return cmptno; + } + } + return -1; +} + + + + + + + + + + + + + + + + +/***********************************************/ +/***********************************************/ +/***********************************************/ +/***********************************************/ + +int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + long v; + long *bufptr; + + if (cmptno < 0 || cmptno >= image->numcmpts_) + goto error; + cmpt = image->cmpts_[cmptno]; + if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ || + width < 0 || height < 0 || x + width > cmpt->width_ || + y + height > cmpt->height_) + goto error; + + bufptr = buf; + for (i = 0; i < height; ++i) { + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) + goto error; + for (j = 0; j < width; ++j) { + if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v)) + goto error; + *bufptr++ = v; + } + } + + return 0; +error: + return -1; +} + +int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + long v; + long *bufptr; + + if (cmptno < 0 || cmptno >= image->numcmpts_) + goto error; + cmpt = image->cmpts_[cmptno]; + if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ || + width < 0 || height < 0 || x + width > cmpt->width_ || + y + height > cmpt->height_) + goto error; + + bufptr = buf; + for (i = 0; i < height; ++i) { + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) + goto error; + for (j = 0; j < width; ++j) { + v = *bufptr++; + if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v)) + goto error; + } + } + + return 0; +error: + return -1; +} + +int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno, + jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs, + jas_image_coord_t vs, int sgnd, int prec) +{ + jas_image_cmpt_t *oldcmpt; + jas_image_cmpt_t *newcmpt; + int width; + int height; + jas_image_coord_t tlx; + jas_image_coord_t tly; + jas_image_coord_t brx; + jas_image_coord_t bry; + int i; + int j; + jas_image_cmptparm_t cmptparm; + jas_image_coord_t ax; + jas_image_coord_t ay; + jas_image_coord_t bx; + jas_image_coord_t by; + jas_image_coord_t d0; + jas_image_coord_t d1; + jas_image_coord_t d2; + jas_image_coord_t d3; + jas_image_coord_t oldx; + jas_image_coord_t oldy; + jas_image_coord_t x; + jas_image_coord_t y; + long v; + jas_image_coord_t cmptbrx; + jas_image_coord_t cmptbry; + + assert(cmptno >= 0 && cmptno < image->numcmpts_); + oldcmpt = image->cmpts_[cmptno]; + assert(oldcmpt->tlx_ == 0 && oldcmpt->tly_ == 0); + jas_image_calcbbox2(image, &tlx, &tly, &brx, &bry); + width = FLOORDIV(brx - ho + hs, hs); + height = FLOORDIV(bry - vo + vs, vs); + cmptparm.tlx = ho; + cmptparm.tly = vo; + cmptparm.hstep = hs; + cmptparm.vstep = vs; + cmptparm.width = width; + cmptparm.height = height; + cmptparm.prec = prec; + cmptparm.sgnd = sgnd; + if (jas_image_addcmpt(image, newcmptno, &cmptparm)) + goto error; +cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_; +cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_; + newcmpt = image->cmpts_[newcmptno]; + jas_stream_rewind(newcmpt->stream_); + for (i = 0; i < height; ++i) { + y = newcmpt->tly_ + newcmpt->vstep_ * i; + for (j = 0; j < width; ++j) { + x = newcmpt->tlx_ + newcmpt->hstep_ * j; + ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_; + ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_; + bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_; + if (bx > cmptbrx) + bx = cmptbrx; + by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_; + if (by > cmptbry) + by = cmptbry; + d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y); + d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y); + d2 = (bx - x) * (bx - x) + (by - y) * (by - y); + d3 = (ax - x) * (ax - x) + (by - y) * (by - y); + if (d0 <= d1 && d0 <= d2 && d0 <= d3) { + oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_; + } else if (d1 <= d0 && d1 <= d2 && d1 <= d3) { + oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_; + } else if (d2 <= d0 && d2 <= d1 && d1 <= d3) { + oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_; + } else { + oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_; + } + assert(oldx >= 0 && oldx < oldcmpt->width_ && + oldy >= 0 && oldy < oldcmpt->height_); + if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ * + (oldy * oldcmpt->width_ + oldx), SEEK_SET) < 0) + goto error; + if (getint(oldcmpt->stream_, oldcmpt->sgnd_, + oldcmpt->prec_, &v)) + goto error; + if (newcmpt->prec_ != oldcmpt->prec_ || + newcmpt->sgnd_ != oldcmpt->sgnd_) { + v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_, + newcmpt->sgnd_, newcmpt->prec_); + } + if (putint(newcmpt->stream_, newcmpt->sgnd_, + newcmpt->prec_, v)) + goto error; + } + } + return 0; +error: + return -1; +} + +int jas_image_ishomosamp(jas_image_t *image) +{ + jas_image_coord_t hstep; + jas_image_coord_t vstep; + int result; + int i; + hstep = jas_image_cmpthstep(image, 0); + vstep = jas_image_cmptvstep(image, 0); + result = 1; + for (i = 0; i < image->numcmpts_; ++i) { + if (jas_image_cmpthstep(image, i) != hstep || + jas_image_cmptvstep(image, i) != vstep) { + result = 0; + break; + } + } + return result; +} + +/* Note: This function defines a bounding box differently. */ +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t tmptlx; + jas_image_coord_t tmptly; + jas_image_coord_t tmpbrx; + jas_image_coord_t tmpbry; + jas_image_coord_t t; + int i; + if (image->numcmpts_ > 0) { + cmpt = image->cmpts_[0]; + tmptlx = cmpt->tlx_; + tmptly = cmpt->tly_; + tmpbrx = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1); + tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1); + for (i = 0; i < image->numcmpts_; ++i) { + cmpt = image->cmpts_[i]; + if (cmpt->tlx_ < tmptlx) + tmptlx = cmpt->tlx_; + if (cmpt->tly_ < tmptly) + tmptly = cmpt->tly_; + t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1); + if (t > tmpbrx) + tmpbrx = t; + t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1); + if (t > tmpbry) + tmpbry = t; + } + } else { + tmptlx = 0; + tmptly = 0; + tmpbrx = -1; + tmpbry = -1; + } + *tlx = tmptlx; + *tly = tmptly; + *brx = tmpbrx; + *bry = tmpbry; +} + + + +static int getint(jas_stream_t *in, int sgnd, int prec, long *val) +{ + long v; + int n; + int c; + n = (prec + 7) / 8; + v = 0; + while (--n >= 0) { + if ((c = jas_stream_getc(in)) == EOF) + return -1; + v = (v << 8) | c; + } + v &= ((1 << prec) - 1); + if (sgnd) { + /* XXX - Do something here. */ + abort(); + } else { + *val = v; + } + return 0; +} + +static int putint(jas_stream_t *out, int sgnd, int prec, long val) +{ + int n; + int c; + if (sgnd) { + /* XXX - Do something here. */ + abort(); + } + val &= (1 << prec) - 1; + n = (prec + 7) / 8; + while (--n >= 0) { + c = (val >> (n * 8)) & 0xff; + if (jas_stream_putc(out, c) != c) + return -1; + } + return 0; +} + +static long convert(long val, int oldsgnd, int oldprec, int newsgnd, + int newprec) +{ + if (newsgnd != oldsgnd) { + } + if (newprec != oldprec) { + if (newprec > oldprec) { + val <<= newprec - oldprec; + } else if (oldprec > newprec) { + val >>= oldprec - newprec; + } + } + return val; +} + +static long downtomult(long x, long y) +{ + assert(x >= 0); + return (x / y) * y; +} + +static long uptomult(long x, long y) +{ + assert(x >= 0); + return ((x + y - 1) / y) * y; +} + +jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof, + int intent) +{ + jas_image_t *inimage; + int minhstep; + int minvstep; + int i; + int j; + int k; + int n; + int hstep; + int vstep; + int numinauxchans; + int numoutauxchans; + int numinclrchans; + int numoutclrchans; + int prec; + jas_image_t *outimage; + int cmpttype; + int numoutchans; + jas_cmprof_t *inprof; + jas_cmprof_t *tmpprof; + jas_image_cmptparm_t cmptparm; + int width; + int height; + jas_cmxform_t *xform; + jas_cmpixmap_t inpixmap; + jas_cmpixmap_t outpixmap; + jas_cmcmptfmt_t *incmptfmts; + jas_cmcmptfmt_t *outcmptfmts; + +#if 0 +jas_eprintf("IMAGE\n"); +jas_image_dump(image, stderr); +#endif + + if (!(inimage = jas_image_copy(image))) + goto error; + image = 0; + + if (!jas_image_ishomosamp(inimage)) { + minhstep = jas_image_cmpthstep(inimage, 0); + minvstep = jas_image_cmptvstep(inimage, 0); + for (i = 1; i < jas_image_numcmpts(inimage); ++i) { + hstep = jas_image_cmpthstep(inimage, i); + vstep = jas_image_cmptvstep(inimage, i); + if (hstep < minhstep) + minhstep = hstep; + if (vstep < minvstep) + minvstep = vstep; + } + n = jas_image_numcmpts(inimage); + for (i = 0; i < n; ++i) { + cmpttype = jas_image_cmpttype(inimage, i); + if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep, jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage, i))) + goto error; + jas_image_setcmpttype(inimage, i + 1, cmpttype); + jas_image_delcmpt(inimage, i); + } + } + + width = jas_image_cmptwidth(inimage, 0); + height = jas_image_cmptheight(inimage, 0); + hstep = jas_image_cmpthstep(inimage, 0); + vstep = jas_image_cmptvstep(inimage, 0); + + inprof = jas_image_cmprof(inimage); + assert(inprof); + numinclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(inprof)); + numinauxchans = jas_image_numcmpts(inimage) - numinclrchans; + numoutclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(outprof)); + numoutauxchans = 0; + numoutchans = numoutclrchans + numoutauxchans; + prec = 8; + + if (!(outimage = jas_image_create0())) + goto error; + + /* Create a component for each of the colorants. */ + for (i = 0; i < numoutclrchans; ++i) { + cmptparm.tlx = 0; + cmptparm.tly = 0; + cmptparm.hstep = hstep; + cmptparm.vstep = vstep; + cmptparm.width = width; + cmptparm.height = height; + cmptparm.prec = prec; + cmptparm.sgnd = 0; + if (jas_image_addcmpt(outimage, -1, &cmptparm)) + goto error; + jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i)); + } +#if 0 + /* Copy the auxiliary components without modification. */ + for (i = 0; i < jas_image_numcmpts(inimage); ++i) { + if (!ISCOLOR(jas_image_cmpttype(inimage, i))) { + jas_image_copycmpt(outimage, -1, inimage, i); +/* XXX - need to specify laydown of component on ref. grid */ + } + } +#endif + + if (!(tmpprof = jas_cmprof_copy(outprof))) + goto error; + assert(!jas_image_cmprof(outimage)); + jas_image_setcmprof(outimage, tmpprof); + tmpprof = 0; + jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof)); + + if (!(xform = jas_cmxform_create(inprof, outprof, 0, JAS_CMXFORM_OP_FWD, intent, 0))) + goto error; + + inpixmap.numcmpts = numinclrchans; + incmptfmts = malloc(numinclrchans * sizeof(jas_cmcmptfmt_t)); + assert(incmptfmts); + inpixmap.cmptfmts = incmptfmts; + for (i = 0; i < numinclrchans; ++i) { + j = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(i)); + assert(j >= 0); + if (!(incmptfmts[i].buf = malloc(width * sizeof(long)))) + goto error; + incmptfmts[i].prec = jas_image_cmptprec(inimage, j); + incmptfmts[i].sgnd = jas_image_cmptsgnd(inimage, j); + incmptfmts[i].width = width; + incmptfmts[i].height = 1; + } + + outpixmap.numcmpts = numoutclrchans; + outcmptfmts = malloc(numoutclrchans * sizeof(jas_cmcmptfmt_t)); + assert(outcmptfmts); + outpixmap.cmptfmts = outcmptfmts; + + for (i = 0; i < numoutclrchans; ++i) { + j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i)); + assert(j >= 0); + if (!(outcmptfmts[i].buf = malloc(width * sizeof(long)))) + goto error; + outcmptfmts[i].prec = jas_image_cmptprec(outimage, j); + outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j); + outcmptfmts[i].width = width; + outcmptfmts[i].height = 1; + } + + for (i = 0; i < height; ++i) { + for (j = 0; j < numinclrchans; ++j) { + k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j)); + if (jas_image_readcmpt2(inimage, k, 0, i, width, 1, incmptfmts[j].buf)) + goto error; + } + jas_cmxform_apply(xform, &inpixmap, &outpixmap); + for (j = 0; j < numoutclrchans; ++j) { + k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j)); + if (jas_image_writecmpt2(outimage, k, 0, i, width, 1, outcmptfmts[j].buf)) + goto error; + } + } + + for (i = 0; i < numoutclrchans; ++i) + jas_free(outcmptfmts[i].buf); + jas_free(outcmptfmts); + for (i = 0; i < numinclrchans; ++i) + jas_free(incmptfmts[i].buf); + jas_free(incmptfmts); + jas_cmxform_destroy(xform); + jas_image_destroy(inimage); + +#if 0 +jas_eprintf("INIMAGE\n"); +jas_image_dump(inimage, stderr); +jas_eprintf("OUTIMAGE\n"); +jas_image_dump(outimage, stderr); +#endif + return outimage; +error: + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_init.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_init.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_init.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_init.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" +#include "jasper/jas_image.h" +#include "jasper/jas_init.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Initialize the image format table. */ +int jas_init() +{ + jas_image_fmtops_t fmtops; + int fmtid; + + fmtid = 0; + +#if !defined(EXCLUDE_MIF_SUPPORT) + fmtops.decode = mif_decode; + fmtops.encode = mif_encode; + fmtops.validate = mif_validate; + jas_image_addfmt(fmtid, "mif", "mif", "My Image Format (MIF)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_PNM_SUPPORT) + fmtops.decode = pnm_decode; + fmtops.encode = pnm_encode; + fmtops.validate = pnm_validate; + jas_image_addfmt(fmtid, "pnm", "pnm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + jas_image_addfmt(fmtid, "pnm", "pgm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + jas_image_addfmt(fmtid, "pnm", "ppm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_BMP_SUPPORT) + fmtops.decode = bmp_decode; + fmtops.encode = bmp_encode; + fmtops.validate = bmp_validate; + jas_image_addfmt(fmtid, "bmp", "bmp", "Microsoft Bitmap (BMP)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_RAS_SUPPORT) + fmtops.decode = ras_decode; + fmtops.encode = ras_encode; + fmtops.validate = ras_validate; + jas_image_addfmt(fmtid, "ras", "ras", "Sun Rasterfile (RAS)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_JP2_SUPPORT) + fmtops.decode = jp2_decode; + fmtops.encode = jp2_encode; + fmtops.validate = jp2_validate; + jas_image_addfmt(fmtid, "jp2", "jp2", + "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops); + ++fmtid; + fmtops.decode = jpc_decode; + fmtops.encode = jpc_encode; + fmtops.validate = jpc_validate; + jas_image_addfmt(fmtid, "jpc", "jpc", + "JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_JPG_SUPPORT) + fmtops.decode = jpg_decode; + fmtops.encode = jpg_encode; + fmtops.validate = jpg_validate; + jas_image_addfmt(fmtid, "jpg", "jpg", "JPEG (ISO/IEC 10918-1)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_PGX_SUPPORT) + fmtops.decode = pgx_decode; + fmtops.encode = pgx_encode; + fmtops.validate = pgx_validate; + jas_image_addfmt(fmtid, "pgx", "pgx", "JPEG-2000 VM Format (PGX)", &fmtops); + ++fmtid; +#endif + + /* We must not register the JasPer library exit handler until after + at least one memory allocation is performed. This is desirable + as it ensures that the JasPer exit handler is called before the + debug memory allocator exit handler. */ + atexit(jas_cleanup); + + return 0; +} + +void jas_cleanup() +{ + jas_image_clearfmts(); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_malloc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_malloc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_malloc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_malloc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Memory Allocator + * + * $Id: jas_malloc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +/* We need the prototype for memset. */ +#include +#include +#include +#if !defined _WIN32 || defined __MINGW__ || defined __MINGW32__ +#include +#endif + +#include "jasper/jas_malloc.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +#if defined(DEBUG_MEMALLOC) +#include "../../../local/src/memalloc.c" +#endif + +#if !defined(DEBUG_MEMALLOC) + +#define MEMALLOC_ALIGNMENT 32 +#define MEMALLOC_ALIGN2 +#undef MEMALLOC_ALIGN2 + +void *jas_malloc(size_t size) +{ +#if defined(MEMALLOC_ALIGN2) + void *ptr; +abort(); + if (posix_memalign(&ptr, MEMALLOC_ALIGNMENT, size)) { + return 0; + } + return ptr; +#endif + return malloc(size); +} + +void jas_free(void *ptr) +{ + free(ptr); +} + +void *jas_realloc(void *ptr, size_t size) +{ + return ptr ? realloc(ptr, size) : malloc(size); +} + +void *jas_realloc2(void *ptr, size_t nmemb, size_t size) +{ + if (!ptr) + return jas_alloc2(nmemb, size); + if (nmemb && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return jas_realloc(ptr, nmemb * size); + +} + +void *jas_alloc2(size_t nmemb, size_t size) +{ + if (nmemb && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + + return jas_malloc(nmemb * size); +} + +void *jas_alloc3(size_t a, size_t b, size_t c) +{ + size_t n; + + if (a && SIZE_MAX / a < b) { + errno = ENOMEM; + return NULL; + } + + return jas_alloc2(a*b, c); +} + +void *jas_calloc(size_t nmemb, size_t size) +{ + void *ptr; + + ptr = jas_alloc2(nmemb, size); + if (ptr) + memset(ptr, 0, nmemb*size); + return ptr; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_seq.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_seq.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_seq.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_seq.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,454 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Sequence/Matrix Library + * + * $Id: jas_seq.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_seq.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Constructors and destructors. +\******************************************************************************/ + +jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend) +{ + jas_matrix_t *matrix; + assert(xstart <= xend && ystart <= yend); + if (!(matrix = jas_matrix_create(yend - ystart, xend - xstart))) { + return 0; + } + matrix->xstart_ = xstart; + matrix->ystart_ = ystart; + matrix->xend_ = xend; + matrix->yend_ = yend; + return matrix; +} + +jas_matrix_t *jas_matrix_create(int numrows, int numcols) +{ + jas_matrix_t *matrix; + int i; + + if (!(matrix = jas_malloc(sizeof(jas_matrix_t)))) { + return 0; + } + matrix->flags_ = 0; + matrix->numrows_ = numrows; + matrix->numcols_ = numcols; + matrix->rows_ = 0; + matrix->maxrows_ = numrows; + matrix->data_ = 0; + matrix->datasize_ = numrows * numcols; + + if (matrix->maxrows_ > 0) { + if (!(matrix->rows_ = jas_alloc2(matrix->maxrows_, + sizeof(jas_seqent_t *)))) { + jas_matrix_destroy(matrix); + return 0; + } + } + + if (matrix->datasize_ > 0) { + if (!(matrix->data_ = jas_alloc2(matrix->datasize_, + sizeof(jas_seqent_t)))) { + jas_matrix_destroy(matrix); + return 0; + } + } + + for (i = 0; i < numrows; ++i) { + matrix->rows_[i] = &matrix->data_[i * matrix->numcols_]; + } + + for (i = 0; i < matrix->datasize_; ++i) { + matrix->data_[i] = 0; + } + + matrix->xstart_ = 0; + matrix->ystart_ = 0; + matrix->xend_ = matrix->numcols_; + matrix->yend_ = matrix->numrows_; + + return matrix; +} + +void jas_matrix_destroy(jas_matrix_t *matrix) +{ + if (matrix->data_) { + assert(!(matrix->flags_ & JAS_MATRIX_REF)); + jas_free(matrix->data_); + matrix->data_ = 0; + } + if (matrix->rows_) { + jas_free(matrix->rows_); + matrix->rows_ = 0; + } + jas_free(matrix); +} + +jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x) +{ + jas_matrix_t *y; + int i; + int j; + y = jas_seq2d_create(jas_seq2d_xstart(x), jas_seq2d_ystart(x), jas_seq2d_xend(x), + jas_seq2d_yend(x)); + assert(y); + for (i = 0; i < x->numrows_; ++i) { + for (j = 0; j < x->numcols_; ++j) { + *jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j); + } + } + return y; +} + +jas_matrix_t *jas_matrix_copy(jas_matrix_t *x) +{ + jas_matrix_t *y; + int i; + int j; + y = jas_matrix_create(x->numrows_, x->numcols_); + for (i = 0; i < x->numrows_; ++i) { + for (j = 0; j < x->numcols_; ++j) { + *jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j); + } + } + return y; +} + +/******************************************************************************\ +* Bind operations. +\******************************************************************************/ + +void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart, int ystart, + int xend, int yend) +{ + jas_matrix_bindsub(s, s1, ystart - s1->ystart_, xstart - s1->xstart_, + yend - s1->ystart_ - 1, xend - s1->xstart_ - 1); +} + +void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0, int c0, + int r1, int c1) +{ + int i; + + if (mat0->data_) { + if (!(mat0->flags_ & JAS_MATRIX_REF)) { + jas_free(mat0->data_); + } + mat0->data_ = 0; + mat0->datasize_ = 0; + } + if (mat0->rows_) { + jas_free(mat0->rows_); + mat0->rows_ = 0; + } + mat0->flags_ |= JAS_MATRIX_REF; + mat0->numrows_ = r1 - r0 + 1; + mat0->numcols_ = c1 - c0 + 1; + mat0->maxrows_ = mat0->numrows_; + mat0->rows_ = jas_alloc2(mat0->maxrows_, sizeof(jas_seqent_t *)); + for (i = 0; i < mat0->numrows_; ++i) { + mat0->rows_[i] = mat1->rows_[r0 + i] + c0; + } + + mat0->xstart_ = mat1->xstart_ + c0; + mat0->ystart_ = mat1->ystart_ + r0; + mat0->xend_ = mat0->xstart_ + mat0->numcols_; + mat0->yend_ = mat0->ystart_ + mat0->numrows_; +} + +/******************************************************************************\ +* Arithmetic operations. +\******************************************************************************/ + +int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1) +{ + int i; + int j; + + if (mat0->numrows_ != mat1->numrows_ || mat0->numcols_ != + mat1->numcols_) { + return 1; + } + for (i = 0; i < mat0->numrows_; i++) { + for (j = 0; j < mat0->numcols_; j++) { + if (jas_matrix_get(mat0, i, j) != jas_matrix_get(mat1, i, j)) { + return 1; + } + } + } + return 0; +} + +void jas_matrix_divpow2(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data = (*data >= 0) ? ((*data) >> n) : + (-((-(*data)) >> n)); + } + } +} + +void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval, jas_seqent_t maxval) +{ + int i; + int j; + jas_seqent_t v; + jas_seqent_t *rowstart; + jas_seqent_t *data; + int rowstep; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + data = rowstart; + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + v = *data; + if (v < minval) { + *data = minval; + } else if (v > maxval) { + *data = maxval; + } + } + } +} + +void jas_matrix_asr(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + assert(n >= 0); + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data >>= n; + } + } +} + +void jas_matrix_asl(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data <<= n; + } + } +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols) +{ + int size; + int i; + + size = numrows * numcols; + if (size > matrix->datasize_ || numrows > matrix->maxrows_) { + return -1; + } + + matrix->numrows_ = numrows; + matrix->numcols_ = numcols; + + for (i = 0; i < numrows; ++i) { + matrix->rows_[i] = &matrix->data_[numcols * i]; + } + + return 0; +} + +void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data = val; + } + } +} + +jas_matrix_t *jas_seq2d_input(FILE *in) +{ + jas_matrix_t *matrix; + int i; + int j; + long x; + int numrows; + int numcols; + int xoff; + int yoff; + + if (fscanf(in, "%d %d", &xoff, &yoff) != 2) + return 0; + if (fscanf(in, "%d %d", &numcols, &numrows) != 2) + return 0; + if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols, yoff + numrows))) + return 0; + + if (jas_matrix_numrows(matrix) != numrows || jas_matrix_numcols(matrix) != numcols) { + abort(); + } + + /* Get matrix data. */ + for (i = 0; i < jas_matrix_numrows(matrix); i++) { + for (j = 0; j < jas_matrix_numcols(matrix); j++) { + if (fscanf(in, "%ld", &x) != 1) { + jas_matrix_destroy(matrix); + return 0; + } + jas_matrix_set(matrix, i, j, JAS_CAST(jas_seqent_t, x)); + } + } + + return matrix; +} + +int jas_seq2d_output(jas_matrix_t *matrix, FILE *out) +{ +#define MAXLINELEN 80 + int i; + int j; + jas_seqent_t x; + char buf[MAXLINELEN + 1]; + char sbuf[MAXLINELEN + 1]; + int n; + + fprintf(out, "%d %d\n", (int)jas_seq2d_xstart(matrix), + (int)jas_seq2d_ystart(matrix)); + fprintf(out, "%d %d\n", (int)jas_matrix_numcols(matrix), + (int)jas_matrix_numrows(matrix)); + + buf[0] = '\0'; + for (i = 0; i < jas_matrix_numrows(matrix); ++i) { + for (j = 0; j < jas_matrix_numcols(matrix); ++j) { + x = jas_matrix_get(matrix, i, j); + sprintf(sbuf, "%s%4ld", (strlen(buf) > 0) ? " " : "", + JAS_CAST(long, x)); + n = strlen(buf); + if (n + strlen(sbuf) > MAXLINELEN) { + fputs(buf, out); + fputs("\n", out); + buf[0] = '\0'; + } + strcat(buf, sbuf); + if (j == jas_matrix_numcols(matrix) - 1) { + fputs(buf, out); + fputs("\n", out); + buf[0] = '\0'; + } + } + } + fputs(buf, out); + + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_stream.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_stream.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_stream.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_stream.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1156 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * I/O Stream Library + * + * $Id: jas_stream.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#if defined(HAVE_FCNTL_H) +#include +#endif +#include +#include +#include +#include +#if defined(HAVE_UNISTD_H) +#include +#endif +#if defined(WIN32) || defined(HAVE_IO_H) +#include +#endif + +#include "jasper/jas_types.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Local function prototypes. +\******************************************************************************/ + +static int jas_strtoopenmode(const char *s); +static void jas_stream_destroy(jas_stream_t *stream); +static jas_stream_t *jas_stream_create(void); +static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, + int bufsize); + +static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long mem_seek(jas_stream_obj_t *obj, long offset, int origin); +static int mem_close(jas_stream_obj_t *obj); + +static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin); +static int sfile_close(jas_stream_obj_t *obj); + +static int file_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int file_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long file_seek(jas_stream_obj_t *obj, long offset, int origin); +static int file_close(jas_stream_obj_t *obj); + +/******************************************************************************\ +* Local data. +\******************************************************************************/ + +static jas_stream_ops_t jas_stream_fileops = { + file_read, + file_write, + file_seek, + file_close +}; + +static jas_stream_ops_t jas_stream_sfileops = { + sfile_read, + sfile_write, + sfile_seek, + sfile_close +}; + +static jas_stream_ops_t jas_stream_memops = { + mem_read, + mem_write, + mem_seek, + mem_close +}; + +/******************************************************************************\ +* Code for opening and closing streams. +\******************************************************************************/ + +static jas_stream_t *jas_stream_create() +{ + jas_stream_t *stream; + + if (!(stream = jas_malloc(sizeof(jas_stream_t)))) { + return 0; + } + stream->openmode_ = 0; + stream->bufmode_ = 0; + stream->flags_ = 0; + stream->bufbase_ = 0; + stream->bufstart_ = 0; + stream->bufsize_ = 0; + stream->ptr_ = 0; + stream->cnt_ = 0; + stream->ops_ = 0; + stream->obj_ = 0; + stream->rwcnt_ = 0; + stream->rwlimit_ = -1; + + return stream; +} + +jas_stream_t *jas_stream_memopen(char *buf, int bufsize) +{ + jas_stream_t *stream; + jas_stream_memobj_t *obj; + + if (!(stream = jas_stream_create())) { + return 0; + } + + /* A stream associated with a memory buffer is always opened + for both reading and writing in binary mode. */ + stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; + + /* Since the stream data is already resident in memory, buffering + is not necessary. */ + /* But... It still may be faster to use buffering anyways. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + /* Select the operations for a memory stream. */ + stream->ops_ = &jas_stream_memops; + + /* Allocate memory for the underlying memory stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_memobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + stream->obj_ = (void *) obj; + + /* Initialize a few important members of the memory stream object. */ + obj->myalloc_ = 0; + obj->buf_ = 0; + + /* If the buffer size specified is nonpositive, then the buffer + is allocated internally and automatically grown as needed. */ + if (bufsize <= 0) { + obj->bufsize_ = 1024; + obj->growable_ = 1; + } else { + obj->bufsize_ = bufsize; + obj->growable_ = 0; + } + if (buf) { + obj->buf_ = (unsigned char *) buf; + } else { + obj->buf_ = jas_malloc(obj->bufsize_); + obj->myalloc_ = 1; + } + if (!obj->buf_) { + jas_stream_close(stream); + return 0; + } + + if (bufsize > 0 && buf) { + /* If a buffer was supplied by the caller and its length is positive, + make the associated buffer data appear in the stream initially. */ + obj->len_ = bufsize; + } else { + /* The stream is initially empty. */ + obj->len_ = 0; + } + obj->pos_ = 0; + + return stream; +} + +jas_stream_t *jas_stream_fopen(const char *filename, const char *mode) +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + int openflags; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + + /* Determine the correct flags to use for opening the file. */ + if ((stream->openmode_ & JAS_STREAM_READ) && + (stream->openmode_ & JAS_STREAM_WRITE)) { + openflags = O_RDWR; + } else if (stream->openmode_ & JAS_STREAM_READ) { + openflags = O_RDONLY; + } else if (stream->openmode_ & JAS_STREAM_WRITE) { + openflags = O_WRONLY; + } else { + openflags = 0; + } + if (stream->openmode_ & JAS_STREAM_APPEND) { + openflags |= O_APPEND; + } + if (stream->openmode_ & JAS_STREAM_BINARY) { + openflags |= O_BINARY; + } + if (stream->openmode_ & JAS_STREAM_CREATE) { + openflags |= O_CREAT | O_TRUNC; + } + + /* Allocate space for the underlying file stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = -1; + obj->flags = 0; + obj->pathname[0] = '\0'; + stream->obj_ = (void *) obj; + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_fileops; + + /* Open the underlying file. */ + if ((obj->fd = open(filename, openflags, JAS_STREAM_PERMS)) < 0) { + jas_stream_destroy(stream); + return 0; + } + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + return stream; +} + +jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp) +{ + jas_stream_t *stream; + int openflags; + + /* Eliminate compiler warning about unused variable. */ + path = 0; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + + /* Determine the correct flags to use for opening the file. */ + if ((stream->openmode_ & JAS_STREAM_READ) && + (stream->openmode_ & JAS_STREAM_WRITE)) { + openflags = O_RDWR; + } else if (stream->openmode_ & JAS_STREAM_READ) { + openflags = O_RDONLY; + } else if (stream->openmode_ & JAS_STREAM_WRITE) { + openflags = O_WRONLY; + } else { + openflags = 0; + } + if (stream->openmode_ & JAS_STREAM_APPEND) { + openflags |= O_APPEND; + } + if (stream->openmode_ & JAS_STREAM_BINARY) { + openflags |= O_BINARY; + } + if (stream->openmode_ & JAS_STREAM_CREATE) { + openflags |= O_CREAT | O_TRUNC; + } + + stream->obj_ = JAS_CAST(void *, fp); + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_sfileops; + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + return stream; +} + +jas_stream_t *jas_stream_tmpfile() +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + + if (!(stream = jas_stream_create())) { + return 0; + } + + /* A temporary file stream is always opened for both reading and + writing in binary mode. */ + stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; + + /* Allocate memory for the underlying temporary file object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = -1; + obj->flags = 0; + stream->obj_ = obj; + +#ifdef _WIN32 + /* Choose a file name. */ + tmpnam(obj->pathname); + + /* Open the underlying file. */ + if ((obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY, + JAS_STREAM_PERMS)) < 0) { + jas_stream_destroy(stream); + return 0; + } +#else + /* Choose a file name. */ + snprintf(obj->pathname, L_tmpnam, "%s/tmp.XXXXXXXXXX", P_tmpdir); + + /* Open the underlying file. */ + if ((obj->fd = mkstemp(obj->pathname)) < 0) { + jas_stream_destroy(stream); + return 0; + } +#endif + + /* Unlink the file so that it will disappear if the program + terminates abnormally. */ + if (unlink(obj->pathname)) { + jas_stream_destroy(stream); + return 0; + } + + /* Use full buffering. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + stream->ops_ = &jas_stream_fileops; + + return stream; +} + +jas_stream_t *jas_stream_fdopen(int fd, const char *mode) +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + +#if defined(WIN32) + /* Argh!!! Someone ought to banish text mode (i.e., O_TEXT) to the + greatest depths of purgatory! */ + /* Ensure that the file descriptor is in binary mode, if the caller + has specified the binary mode flag. Arguably, the caller ought to + take care of this, but text mode is a ugly wart anyways, so we save + the caller some grief by handling this within the stream library. */ + /* This ugliness is mainly for the benefit of those who run the + JasPer software under Windows from shells that insist on opening + files in text mode. For example, in the Cygwin environment, + shells often open files in text mode when I/O redirection is + used. Grr... */ + if (stream->openmode_ & JAS_STREAM_BINARY) { + setmode(fd, O_BINARY); + } +#endif + + /* Allocate space for the underlying file stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = fd; + obj->flags = 0; + obj->pathname[0] = '\0'; + stream->obj_ = (void *) obj; + + /* Do not close the underlying file descriptor when the stream is + closed. */ + obj->flags |= JAS_STREAM_FILEOBJ_NOCLOSE; + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_fileops; + + return stream; +} + +static void jas_stream_destroy(jas_stream_t *stream) +{ + /* If the memory for the buffer was allocated with malloc, free + this memory. */ + if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) { + jas_free(stream->bufbase_); + stream->bufbase_ = 0; + } + jas_free(stream); +} + +int jas_stream_close(jas_stream_t *stream) +{ + /* Flush buffer if necessary. */ + jas_stream_flush(stream); + + /* Close the underlying stream object. */ + (*stream->ops_->close_)(stream->obj_); + + jas_stream_destroy(stream); + + return 0; +} + +/******************************************************************************\ +* Code for reading and writing streams. +\******************************************************************************/ + +int jas_stream_getc_func(jas_stream_t *stream) +{ + assert(stream->ptr_ - stream->bufbase_ <= stream->bufsize_ + + JAS_STREAM_MAXPUTBACK); + return jas_stream_getc_macro(stream); +} + +int jas_stream_putc_func(jas_stream_t *stream, int c) +{ + assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_); + return jas_stream_putc_macro(stream, c); +} + +int jas_stream_ungetc(jas_stream_t *stream, int c) +{ + if (!stream->ptr_ || stream->ptr_ == stream->bufbase_) { + return -1; + } + + /* Reset the EOF indicator (since we now have at least one character + to read). */ + stream->flags_ &= ~JAS_STREAM_EOF; + + --stream->rwcnt_; + --stream->ptr_; + ++stream->cnt_; + *stream->ptr_ = c; + return 0; +} + +int jas_stream_read(jas_stream_t *stream, void *buf, int cnt) +{ + int n; + int c; + char *bufptr; + + bufptr = buf; + + n = 0; + while (n < cnt) { + if ((c = jas_stream_getc(stream)) == EOF) { + return n; + } + *bufptr++ = c; + ++n; + } + + return n; +} + +int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt) +{ + int n; + const char *bufptr; + + bufptr = buf; + + n = 0; + while (n < cnt) { + if (jas_stream_putc(stream, *bufptr) == EOF) { + return n; + } + ++bufptr; + ++n; + } + + return n; +} + +/* Note: This function uses a fixed size buffer. Therefore, it cannot + handle invocations that will produce more output than can be held + by the buffer. */ +int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...) +{ + va_list ap; + char buf[4096]; + int ret; + + va_start(ap, fmt); + ret = vsnprintf(buf, sizeof buf, fmt, ap); + jas_stream_puts(stream, buf); + va_end(ap); + return ret; +} + +int jas_stream_puts(jas_stream_t *stream, const char *s) +{ + while (*s != '\0') { + if (jas_stream_putc_macro(stream, *s) == EOF) { + return -1; + } + ++s; + } + return 0; +} + +char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize) +{ + int c; + char *bufptr; + assert(bufsize > 0); + + bufptr = buf; + while (bufsize > 1) { + if ((c = jas_stream_getc(stream)) == EOF) { + break; + } + *bufptr++ = c; + --bufsize; + if (c == '\n') { + break; + } + } + *bufptr = '\0'; + return buf; +} + +int jas_stream_gobble(jas_stream_t *stream, int n) +{ + int m; + m = n; + for (m = n; m > 0; --m) { + if (jas_stream_getc(stream) == EOF) { + return n - m; + } + } + return n; +} + +int jas_stream_pad(jas_stream_t *stream, int n, int c) +{ + int m; + m = n; + for (m = n; m > 0; --m) { + if (jas_stream_putc(stream, c) == EOF) + return n - m; + } + return n; +} + +/******************************************************************************\ +* Code for getting and setting the stream position. +\******************************************************************************/ + +int jas_stream_isseekable(jas_stream_t *stream) +{ + if (stream->ops_ == &jas_stream_memops) { + return 1; + } else if (stream->ops_ == &jas_stream_fileops) { + if ((*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR) < 0) { + return 0; + } + return 1; + } else { + return 0; + } +} + +int jas_stream_rewind(jas_stream_t *stream) +{ + return jas_stream_seek(stream, 0, SEEK_SET); +} + +long jas_stream_seek(jas_stream_t *stream, long offset, int origin) +{ + long newpos; + + /* The buffer cannot be in use for both reading and writing. */ + assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ & + JAS_STREAM_WRBUF))); + + /* Reset the EOF indicator (since we may not be at the EOF anymore). */ + stream->flags_ &= ~JAS_STREAM_EOF; + + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + if (origin == SEEK_CUR) { + offset -= stream->cnt_; + } + } else if (stream->bufmode_ & JAS_STREAM_WRBUF) { + if (jas_stream_flush(stream)) { + return -1; + } + } + stream->cnt_ = 0; + stream->ptr_ = stream->bufstart_; + stream->bufmode_ &= ~(JAS_STREAM_RDBUF | JAS_STREAM_WRBUF); + + if ((newpos = (*stream->ops_->seek_)(stream->obj_, offset, origin)) + < 0) { + return -1; + } + + return newpos; +} + +long jas_stream_tell(jas_stream_t *stream) +{ + int adjust; + int offset; + + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + adjust = -stream->cnt_; + } else if (stream->bufmode_ & JAS_STREAM_WRBUF) { + adjust = stream->ptr_ - stream->bufstart_; + } else { + adjust = 0; + } + + if ((offset = (*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR)) < 0) { + return -1; + } + + return offset + adjust; +} + +/******************************************************************************\ +* Buffer initialization code. +\******************************************************************************/ + +static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, + int bufsize) +{ + /* If this function is being called, the buffer should not have been + initialized yet. */ + assert(!stream->bufbase_); + + if (bufmode != JAS_STREAM_UNBUF) { + /* The full- or line-buffered mode is being employed. */ + if (!buf) { + /* The caller has not specified a buffer to employ, so allocate + one. */ + if ((stream->bufbase_ = jas_malloc(JAS_STREAM_BUFSIZE + + JAS_STREAM_MAXPUTBACK))) { + stream->bufmode_ |= JAS_STREAM_FREEBUF; + stream->bufsize_ = JAS_STREAM_BUFSIZE; + } else { + /* The buffer allocation has failed. Resort to unbuffered + operation. */ + stream->bufbase_ = stream->tinybuf_; + stream->bufsize_ = 1; + } + } else { + /* The caller has specified a buffer to employ. */ + /* The buffer must be large enough to accommodate maximum + putback. */ + assert(bufsize > JAS_STREAM_MAXPUTBACK); + stream->bufbase_ = JAS_CAST(uchar *, buf); + stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK; + } + } else { + /* The unbuffered mode is being employed. */ + /* A buffer should not have been supplied by the caller. */ + assert(!buf); + /* Use a trivial one-character buffer. */ + stream->bufbase_ = stream->tinybuf_; + stream->bufsize_ = 1; + } + stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK]; + stream->ptr_ = stream->bufstart_; + stream->cnt_ = 0; + stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK; +} + +/******************************************************************************\ +* Buffer filling and flushing code. +\******************************************************************************/ + +int jas_stream_flush(jas_stream_t *stream) +{ + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + return 0; + } + return jas_stream_flushbuf(stream, EOF); +} + +int jas_stream_fillbuf(jas_stream_t *stream, int getflag) +{ + int c; + + /* The stream must not be in an error or EOF state. */ + if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) { + return EOF; + } + + /* The stream must be open for reading. */ + if ((stream->openmode_ & JAS_STREAM_READ) == 0) { + return EOF; + } + + /* Make a half-hearted attempt to confirm that the buffer is not + currently being used for writing. This check is not intended + to be foolproof! */ + assert((stream->bufmode_ & JAS_STREAM_WRBUF) == 0); + + assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_); + + /* Mark the buffer as being used for reading. */ + stream->bufmode_ |= JAS_STREAM_RDBUF; + + /* Read new data into the buffer. */ + stream->ptr_ = stream->bufstart_; + if ((stream->cnt_ = (*stream->ops_->read_)(stream->obj_, + (char *) stream->bufstart_, stream->bufsize_)) <= 0) { + if (stream->cnt_ < 0) { + stream->flags_ |= JAS_STREAM_ERR; + } else { + stream->flags_ |= JAS_STREAM_EOF; + } + stream->cnt_ = 0; + return EOF; + } + + assert(stream->cnt_ > 0); + /* Get or peek at the first character in the buffer. */ + c = (getflag) ? jas_stream_getc2(stream) : (*stream->ptr_); + + return c; +} + +int jas_stream_flushbuf(jas_stream_t *stream, int c) +{ + int len; + int n; + + /* The stream should not be in an error or EOF state. */ + if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) { + return EOF; + } + + /* The stream must be open for writing. */ + if ((stream->openmode_ & (JAS_STREAM_WRITE | JAS_STREAM_APPEND)) == 0) { + return EOF; + } + + /* The buffer should not currently be in use for reading. */ + assert(!(stream->bufmode_ & JAS_STREAM_RDBUF)); + + /* Note: Do not use the quantity stream->cnt to determine the number + of characters in the buffer! Depending on how this function was + called, the stream->cnt value may be "off-by-one". */ + len = stream->ptr_ - stream->bufstart_; + if (len > 0) { + n = (*stream->ops_->write_)(stream->obj_, (char *) + stream->bufstart_, len); + if (n != len) { + stream->flags_ |= JAS_STREAM_ERR; + return EOF; + } + } + stream->cnt_ = stream->bufsize_; + stream->ptr_ = stream->bufstart_; + + stream->bufmode_ |= JAS_STREAM_WRBUF; + + if (c != EOF) { + assert(stream->cnt_ > 0); + return jas_stream_putc2(stream, c); + } + + return 0; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +static int jas_strtoopenmode(const char *s) +{ + int openmode = 0; + while (*s != '\0') { + switch (*s) { + case 'r': + openmode |= JAS_STREAM_READ; + break; + case 'w': + openmode |= JAS_STREAM_WRITE | JAS_STREAM_CREATE; + break; + case 'b': + openmode |= JAS_STREAM_BINARY; + break; + case 'a': + openmode |= JAS_STREAM_APPEND; + break; + case '+': + openmode |= JAS_STREAM_READ | JAS_STREAM_WRITE; + break; + default: + break; + } + ++s; + } + return openmode; +} + +int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n) +{ + int all; + int c; + int m; + + all = (n < 0) ? 1 : 0; + + m = n; + while (all || m > 0) { + if ((c = jas_stream_getc_macro(in)) == EOF) { + /* The next character of input could not be read. */ + /* Return with an error if an I/O error occured + (not including EOF) or if an explicit copy count + was specified. */ + return (!all || jas_stream_error(in)) ? (-1) : 0; + } + if (jas_stream_putc_macro(out, c) == EOF) { + return -1; + } + --m; + } + return 0; +} + +long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt) +{ + int old; + + old = stream->rwcnt_; + stream->rwcnt_ = rwcnt; + return old; +} + +int jas_stream_display(jas_stream_t *stream, FILE *fp, int n) +{ + unsigned char buf[16]; + int i; + int j; + int m; + int c; + int display; + int cnt; + + cnt = n - (n % 16); + display = 1; + + for (i = 0; i < n; i += 16) { + if (n > 16 && i > 0) { + display = (i >= cnt) ? 1 : 0; + } + if (display) { + fprintf(fp, "%08x:", i); + } + m = JAS_MIN(n - i, 16); + for (j = 0; j < m; ++j) { + if ((c = jas_stream_getc(stream)) == EOF) { + abort(); + return -1; + } + buf[j] = c; + } + if (display) { + for (j = 0; j < m; ++j) { + fprintf(fp, " %02x", buf[j]); + } + fputc(' ', fp); + for (; j < 16; ++j) { + fprintf(fp, " "); + } + for (j = 0; j < m; ++j) { + if (isprint(buf[j])) { + fputc(buf[j], fp); + } else { + fputc(' ', fp); + } + } + fprintf(fp, "\n"); + } + + + } + return 0; +} + +long jas_stream_length(jas_stream_t *stream) +{ + long oldpos; + long pos; + if ((oldpos = jas_stream_tell(stream)) < 0) { + return -1; + } + if (jas_stream_seek(stream, 0, SEEK_END) < 0) { + return -1; + } + if ((pos = jas_stream_tell(stream)) < 0) { + return -1; + } + if (jas_stream_seek(stream, oldpos, SEEK_SET) < 0) { + return -1; + } + return pos; +} + +/******************************************************************************\ +* Memory stream object. +\******************************************************************************/ + +static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + int n; + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + n = m->len_ - m->pos_; + cnt = JAS_MIN(n, cnt); + memcpy(buf, &m->buf_[m->pos_], cnt); + m->pos_ += cnt; + return cnt; +} + +static int mem_resize(jas_stream_memobj_t *m, int bufsize) +{ + unsigned char *buf; + + assert(m->buf_); + if (!(buf = jas_realloc(m->buf_, bufsize))) { + return -1; + } + m->buf_ = buf; + m->bufsize_ = bufsize; + return 0; +} + +static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + int n; + int ret; + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + long newbufsize; + long newpos; + + newpos = m->pos_ + cnt; + if (newpos > m->bufsize_ && m->growable_) { + newbufsize = m->bufsize_; + while (newbufsize < newpos) { + newbufsize <<= 1; + assert(newbufsize >= 0); + } + if (mem_resize(m, newbufsize)) { + return -1; + } + } + if (m->pos_ > m->len_) { + /* The current position is beyond the end of the file, so + pad the file to the current position with zeros. */ + n = JAS_MIN(m->pos_, m->bufsize_) - m->len_; + if (n > 0) { + memset(&m->buf_[m->len_], 0, n); + m->len_ += n; + } + if (m->pos_ != m->len_) { + /* The buffer is not big enough. */ + return 0; + } + } + n = m->bufsize_ - m->pos_; + ret = JAS_MIN(n, cnt); + if (ret > 0) { + memcpy(&m->buf_[m->pos_], buf, ret); + m->pos_ += ret; + } + if (m->pos_ > m->len_) { + m->len_ = m->pos_; + } +assert(ret == cnt); + return ret; +} + +static long mem_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + long newpos; + + switch (origin) { + case SEEK_SET: + newpos = offset; + break; + case SEEK_END: + newpos = m->len_ - offset; + break; + case SEEK_CUR: + newpos = m->pos_ + offset; + break; + default: + abort(); + break; + } + if (newpos < 0) { + return -1; + } + m->pos_ = newpos; + + return m->pos_; +} + +static int mem_close(jas_stream_obj_t *obj) +{ + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + if (m->myalloc_ && m->buf_) { + jas_free(m->buf_); + m->buf_ = 0; + } + jas_free(obj); + return 0; +} + +/******************************************************************************\ +* File stream object. +\******************************************************************************/ + +static int file_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return read(fileobj->fd, buf, cnt); +} + +static int file_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return write(fileobj->fd, buf, cnt); +} + +static long file_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return lseek(fileobj->fd, offset, origin); +} + +static int file_close(jas_stream_obj_t *obj) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + int ret; + ret = close(fileobj->fd); + if (fileobj->flags & JAS_STREAM_FILEOBJ_DELONCLOSE) { + unlink(fileobj->pathname); + } + jas_free(fileobj); + return ret; +} + +/******************************************************************************\ +* Stdio file stream object. +\******************************************************************************/ + +static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fread(buf, 1, cnt, fp); +} + +static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fwrite(buf, 1, cnt, fp); +} + +static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fseek(fp, offset, origin); +} + +static int sfile_close(jas_stream_obj_t *obj) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fclose(fp); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_string.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_string.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_string.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_string.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * String Library + * + * $Id: jas_string.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include + +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" + +/******************************************************************************\ +* Miscellaneous Functions +\******************************************************************************/ + +/* This function is equivalent to the popular but non-standard (and + not-always-available) strdup function. */ + +char *jas_strdup(const char *s) +{ + int n; + char *p; + n = strlen(s) + 1; + if (!(p = jas_malloc(n * sizeof(char)))) { + return 0; + } + strcpy(p, s); + return p; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_tmr.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_tmr.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_tmr.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_tmr.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Timing Routines + * + * $Id: jas_tmr.c,v 1.1 2008-05-26 09:40:51 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_tmr.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +#if defined(HAVE_GETTIMEOFDAY) + +void jas_tmr_start(jas_tmr_t *tmr) +{ + if (gettimeofday(&tmr->start, 0)) { + abort(); + } +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ + if (gettimeofday(&tmr->stop, 0)) { + abort(); + } +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + double t0; + double t1; + t0 = ((double) tmr->start.tv_sec) + ((double) tmr->start.tv_usec) / 1e6; + t1 = ((double) tmr->stop.tv_sec) + ((double) tmr->stop.tv_usec) / 1e6; + return t1 - t0; +} + +#elif defined(HAVE_GETRUSAGE) + +void jas_tmr_start(jas_tmr_t *tmr) +{ + if (getrusage(RUSAGE_SELF, &tmr->start) < 0) { + abort(); + } +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ + if (getrusage(RUSAGE_SELF, &tmr->stop) < 0) { + abort(); + } +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + double t; + t = ((tmr->stop.ru_utime.tv_sec * 1e6 + tmr->stop.ru_utime.tv_usec) - + (tmr->start.ru_utime.tv_sec * 1e6 + tmr->start.ru_utime.tv_usec)) / 1e6; + t += ((tmr->stop.ru_stime.tv_sec * 1e6 + tmr->stop.ru_stime.tv_usec) - + (tmr->start.ru_stime.tv_sec * 1e6 + tmr->start.ru_stime.tv_usec)) / 1e6; + return t; +} + +#else + +void jas_tmr_start(jas_tmr_t *tmr) +{ +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + return 0.0; +} + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_tvp.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_tvp.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_tvp.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_tvp.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tag-Value Parser Library + * + * $Id: jas_tvp.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include + +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" +#include "jasper/jas_tvp.h" + +/******************************************************************************\ +* Macros. +\******************************************************************************/ + +/* Is the specified character valid for a tag name? */ +#define JAS_TVP_ISTAG(x) \ + (isalpha(x) || (x) == '_' || isdigit(x)) + +/******************************************************************************\ +* Code for creating and destroying a tag-value parser. +\******************************************************************************/ + +jas_tvparser_t *jas_tvparser_create(const char *s) +{ + jas_tvparser_t *tvp; + if (!(tvp = jas_malloc(sizeof(jas_tvparser_t)))) { + return 0; + } + if (!(tvp->buf = jas_strdup(s))) { + jas_tvparser_destroy(tvp); + return 0; + } + tvp->pos = tvp->buf; + tvp->tag = 0; + tvp->val = 0; + return tvp; +} + +void jas_tvparser_destroy(jas_tvparser_t *tvp) +{ + if (tvp->buf) { + jas_free(tvp->buf); + } + jas_free(tvp); +} + +/******************************************************************************\ +* Main parsing code. +\******************************************************************************/ + +/* Get the next tag-value pair. */ +int jas_tvparser_next(jas_tvparser_t *tvp) +{ + char *p; + char *tag; + char *val; + + /* Skip any leading whitespace. */ + p = tvp->pos; + while (*p != '\0' && isspace(*p)) { + ++p; + } + + /* Has the end of the input data been reached? */ + if (*p == '\0') { + /* No more tags are present. */ + tvp->pos = p; + return 1; + } + + /* Does the tag name begin with a valid character? */ + if (!JAS_TVP_ISTAG(*p)) { + return -1; + } + + /* Remember where the tag name begins. */ + tag = p; + + /* Find the end of the tag name. */ + while (*p != '\0' && JAS_TVP_ISTAG(*p)) { + ++p; + } + + /* Has the end of the input data been reached? */ + if (*p == '\0') { + /* The value field is empty. */ + tvp->tag = tag; + tvp->val = ""; + tvp->pos = p; + return 0; + } + + /* Is a value field not present? */ + if (*p != '=') { + if (*p != '\0' && !isspace(*p)) { + return -1; + } + *p++ = '\0'; + tvp->tag = tag; + tvp->val = ""; + tvp->pos = p; + return 0; + } + + *p++ = '\0'; + + val = p; + while (*p != '\0' && !isspace(*p)) { + ++p; + } + + if (*p != '\0') { + *p++ = '\0'; + } + + tvp->pos = p; + tvp->tag = tag; + tvp->val = val; + + return 0; +} + +/******************************************************************************\ +* Code for querying the current tag/value. +\******************************************************************************/ + +/* Get the current tag. */ +char *jas_tvparser_gettag(jas_tvparser_t *tvp) +{ + return tvp->tag; +} + +/* Get the current value. */ +char *jas_tvparser_getval(jas_tvparser_t *tvp) +{ + return tvp->val; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +/* Lookup a tag by name. */ +jas_taginfo_t *jas_taginfos_lookup(jas_taginfo_t *taginfos, const char *name) +{ + jas_taginfo_t *taginfo; + taginfo = taginfos; + while (taginfo->id >= 0) { + if (!strcmp(taginfo->name, name)) { + return taginfo; + } + ++taginfo; + } + return 0; +} + +/* This function is simply for convenience. */ +/* One can avoid testing for the special case of a null pointer, by + using this function. This function never returns a null pointer. */ +jas_taginfo_t *jas_taginfo_nonull(jas_taginfo_t *taginfo) +{ + static jas_taginfo_t invalidtaginfo = { + -1, 0 + }; + + return taginfo ? taginfo : &invalidtaginfo; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_version.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_version.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jas_version.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jas_version.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include "jasper/jas_version.h" + +const char *jas_getversion() +{ + return JAS_VERSION; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_cm.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_cm.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_cm.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_cm.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Color Management + * + * $Id: jas_cm.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_CM_H +#define JAS_CM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int jas_clrspc_t; + +/* transform operations */ +#define JAS_CMXFORM_OP_FWD 0 +#define JAS_CMXFORM_OP_REV 1 +#define JAS_CMXFORM_OP_PROOF 2 +#define JAS_CMXFORM_OP_GAMUT 3 + +/* rendering intents */ +#define JAS_CMXFORM_INTENT_PER 0 +#define JAS_CMXFORM_INTENT_RELCLR 1 +#define JAS_CMXFORM_INTENT_ABSCLR 2 +#define JAS_CMXFORM_INTENT_SAT 3 +#define JAS_CMXFORM_NUMINTENTS 4 + +#define JAS_CMXFORM_OPTM_SPEED 0 +#define JAS_CMXFORM_OPTM_SIZE 1 +#define JAS_CMXFORM_OPTM_ACC 2 + + +#define jas_clrspc_create(fam, mbr) (((fam) << 8) | (mbr)) +#define jas_clrspc_fam(clrspc) ((clrspc) >> 8) +#define jas_clrspc_mbr(clrspc) ((clrspc) & 0xff) +#define jas_clrspc_isgeneric(clrspc) (!jas_clrspc_mbr(clrspc)) +#define jas_clrspc_isunknown(clrspc) ((clrspc) & JAS_CLRSPC_UNKNOWNMASK) + +#define JAS_CLRSPC_UNKNOWNMASK 0x4000 + +/* color space families */ +#define JAS_CLRSPC_FAM_UNKNOWN 0 +#define JAS_CLRSPC_FAM_XYZ 1 +#define JAS_CLRSPC_FAM_LAB 2 +#define JAS_CLRSPC_FAM_GRAY 3 +#define JAS_CLRSPC_FAM_RGB 4 +#define JAS_CLRSPC_FAM_YCBCR 5 + +/* specific color spaces */ +#define JAS_CLRSPC_UNKNOWN JAS_CLRSPC_UNKNOWNMASK +#define JAS_CLRSPC_CIEXYZ jas_clrspc_create(JAS_CLRSPC_FAM_XYZ, 1) +#define JAS_CLRSPC_CIELAB jas_clrspc_create(JAS_CLRSPC_FAM_LAB, 1) +#define JAS_CLRSPC_SGRAY jas_clrspc_create(JAS_CLRSPC_FAM_GRAY, 1) +#define JAS_CLRSPC_SRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 1) +#define JAS_CLRSPC_SYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 1) + +/* generic color spaces */ +#define JAS_CLRSPC_GENRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 0) +#define JAS_CLRSPC_GENGRAY jas_clrspc_create(JAS_CLRSPC_FAM_GRAY, 0) +#define JAS_CLRSPC_GENYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 0) + +#define JAS_CLRSPC_CHANIND_YCBCR_Y 0 +#define JAS_CLRSPC_CHANIND_YCBCR_CB 1 +#define JAS_CLRSPC_CHANIND_YCBCR_CR 2 + +#define JAS_CLRSPC_CHANIND_RGB_R 0 +#define JAS_CLRSPC_CHANIND_RGB_G 1 +#define JAS_CLRSPC_CHANIND_RGB_B 2 + +#define JAS_CLRSPC_CHANIND_GRAY_Y 0 + +typedef double jas_cmreal_t; + +struct jas_cmpxform_s; + +typedef struct { + long *buf; + int prec; + int sgnd; + int width; + int height; +} jas_cmcmptfmt_t; + +typedef struct { + int numcmpts; + jas_cmcmptfmt_t *cmptfmts; +} jas_cmpixmap_t; + +typedef struct { + void (*destroy)(struct jas_cmpxform_s *pxform); + int (*apply)(struct jas_cmpxform_s *pxform, jas_cmreal_t *in, jas_cmreal_t *out, int cnt); + void (*dump)(struct jas_cmpxform_s *pxform); +} jas_cmpxformops_t; + +typedef struct { + jas_cmreal_t *data; + int size; +} jas_cmshapmatlut_t; + +typedef struct { + int mono; + int order; + int useluts; + int usemat; + jas_cmshapmatlut_t luts[3]; + jas_cmreal_t mat[3][4]; +} jas_cmshapmat_t; + +typedef struct { + int order; +} jas_cmshaplut_t; + +typedef struct { + int inclrspc; + int outclrspc; +} jas_cmclrspcconv_t; + +#define jas_align_t double + +typedef struct jas_cmpxform_s { + int refcnt; + jas_cmpxformops_t *ops; + int numinchans; + int numoutchans; + union { + jas_align_t dummy; + jas_cmshapmat_t shapmat; + jas_cmshaplut_t shaplut; + jas_cmclrspcconv_t clrspcconv; + } data; +} jas_cmpxform_t; + +typedef struct { + int numpxforms; + int maxpxforms; + jas_cmpxform_t **pxforms; +} jas_cmpxformseq_t; + +typedef struct { + int numinchans; + int numoutchans; + jas_cmpxformseq_t *pxformseq; +} jas_cmxform_t; + +#define JAS_CMPROF_TYPE_DEV 1 +#define JAS_CMPROF_TYPE_CLRSPC 2 + +#define JAS_CMPROF_NUMPXFORMSEQS 13 + +typedef struct { + int clrspc; + int numchans; + int refclrspc; + int numrefchans; + jas_iccprof_t *iccprof; + jas_cmpxformseq_t *pxformseqs[JAS_CMPROF_NUMPXFORMSEQS]; +} jas_cmprof_t; + +/* Create a profile. */ + +/* Destroy a profile. */ +void jas_cmprof_destroy(jas_cmprof_t *prof); + +#if 0 +typedef int_fast32_t jas_cmattrname_t; +typedef int_fast32_t jas_cmattrval_t; +typedef int_fast32_t jas_cmattrtype_t; +/* Load a profile. */ +int jas_cmprof_load(jas_cmprof_t *prof, jas_stream_t *in, int fmt); +/* Save a profile. */ +int jas_cmprof_save(jas_cmprof_t *prof, jas_stream_t *out, int fmt); +/* Set an attribute of a profile. */ +int jas_cm_prof_setattr(jas_cm_prof_t *prof, jas_cm_attrname_t name, void *val); +/* Get an attribute of a profile. */ +void *jas_cm_prof_getattr(jas_cm_prof_t *prof, jas_cm_attrname_t name); +#endif + +jas_cmxform_t *jas_cmxform_create(jas_cmprof_t *inprof, jas_cmprof_t *outprof, + jas_cmprof_t *proofprof, int op, int intent, int optimize); + +void jas_cmxform_destroy(jas_cmxform_t *xform); + +/* Apply a transform to data. */ +int jas_cmxform_apply(jas_cmxform_t *xform, jas_cmpixmap_t *in, + jas_cmpixmap_t *out); + +int jas_cxform_optimize(jas_cmxform_t *xform, int optimize); + +int jas_clrspc_numchans(int clrspc); +jas_cmprof_t *jas_cmprof_createfromiccprof(jas_iccprof_t *iccprof); +jas_cmprof_t *jas_cmprof_createfromclrspc(int clrspc); +jas_iccprof_t *jas_iccprof_createfromcmprof(jas_cmprof_t *prof); + +#define jas_cmprof_clrspc(prof) ((prof)->clrspc) +jas_cmprof_t *jas_cmprof_copy(jas_cmprof_t *prof); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h 2013-05-05 19:46:52.000000000 +0000 @@ -0,0 +1,175 @@ +/* src/libjasper/include/jasper/jas_config.h. Generated by configure. */ +/* src/libjasper/include/jasper/jas_config.h.in. Generated from configure.ac by autoheader. */ + + +/* Avoid problems due to multiple inclusion. */ +#ifndef JAS_CONFIG_H +#define JAS_CONFIG_H + +/* This preprocessor symbol identifies the version of JasPer. */ +#define JAS_VERSION "1.900.1" +/* If configure is being used, this symbol will be defined automatically + at this point in the configuration header file. */ + +/* The preprocessor symbol JAS_WIN_MSVC_BUILD should not be defined + unless the JasPer software is being built under Microsoft Windows + using Microsoft Visual C. */ +#if !defined(JAS_WIN_MSVC_BUILD) +/* A configure-based build is being used. */ + + + +/* Extra debugging support */ +/* #undef DEBUG */ + +/* Debugging memory allocator */ +/* #undef DEBUG_MEMALLOC */ + +/* Debugging overflow detection */ +/* #undef DEBUG_OVERFLOW */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getrusage' function. */ +//#define HAVE_GETRUSAGE 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +//#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +//#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#ifndef WIN32 // XBEE +#define HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +//#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +//#define HAVE_UNISTD_H 1 + +/* Have variable length arrays */ +//#define HAVE_VLA 1 + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* JasPer configure */ +#define JAS_CONFIGURE 1 + +/* JasPer version */ +#define JAS_VERSION "1.900.1" + +/* Name of package */ +#define PACKAGE "jasper" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "jasper" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "jasper 1.900.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "jasper" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.900.1" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "1.900.1" + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `long long' if does not define. */ +#define longlong long long + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef ssize_t */ + +/* Define to `unsigned char' if does not define. */ +#define uchar unsigned char + +/* Define to `unsigned int' if does not define. */ +/* #undef uint */ + +/* Define to `unsigned long' if does not define. */ +/* #undef ulong */ + +/* Define to `unsigned long long' if does not define. */ +#define ulonglong unsigned long long + +/* Define to `unsigned short' if does not define. */ +/* #undef ushort */ + + +#else +/* A configure-based build is not being used. */ +#include +#endif + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h.in diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h.in --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config.h.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,172 @@ +/* src/libjasper/include/jasper/jas_config.h.in. Generated from configure.ac by autoheader. */ + + +/* Avoid problems due to multiple inclusion. */ +#ifndef JAS_CONFIG_H +#define JAS_CONFIG_H + +/* This preprocessor symbol identifies the version of JasPer. */ +#undef JAS_VERSION +/* If configure is being used, this symbol will be defined automatically + at this point in the configuration header file. */ + +/* The preprocessor symbol JAS_WIN_MSVC_BUILD should not be defined + unless the JasPer software is being built under Microsoft Windows + using Microsoft Visual C. */ +#if !defined(JAS_WIN_MSVC_BUILD) +/* A configure-based build is being used. */ + + + +/* Extra debugging support */ +#undef DEBUG + +/* Debugging memory allocator */ +#undef DEBUG_MEMALLOC + +/* Debugging overflow detection */ +#undef DEBUG_OVERFLOW + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IO_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Have variable length arrays */ +#undef HAVE_VLA + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* JasPer configure */ +#undef JAS_CONFIGURE + +/* JasPer version */ +#undef JAS_VERSION + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `long long' if does not define. */ +#undef longlong + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define to `unsigned char' if does not define. */ +#undef uchar + +/* Define to `unsigned int' if does not define. */ +#undef uint + +/* Define to `unsigned long' if does not define. */ +#undef ulong + +/* Define to `unsigned long long' if does not define. */ +#undef ulonglong + +/* Define to `unsigned short' if does not define. */ +#undef ushort + + +#else +/* A configure-based build is not being used. */ +#include +#endif + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config2.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config2.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config2.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_config2.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JAS_CONFIG2_H +#define JAS_CONFIG2_H + +/* + * Configuration for Microsoft Windows and Microsoft Visual C. + * + * We are not using a configure-based build. + * Try to compensate for this here, by specifying the preprocessor symbols + * normally defined by configure. + */ + +#define uchar unsigned char +#define ushort unsigned short +#define uint unsigned int +#define ulong unsigned long +#define longlong long long +#define ulonglong unsigned long long +/*#define ssize_t int*/ + +#define HAVE_FCNTL_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_IO_H 1 +#define HAVE_WINDOWS_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDDEF_H 1 + +#define EXCLUDE_JPG_SUPPORT 1 +#define EXCLUDE_MIF_SUPPORT 1 +#define EXCLUDE_PNM_SUPPORT 1 +#define EXCLUDE_PNM_SUPPORT 1 +#define EXCLUDE_RAS_SUPPORT 1 +#define EXCLUDE_BMP_SUPPORT 1 +#define EXCLUDE_PGX_SUPPORT 1 + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_debug.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_debug.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_debug.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Debugging-Related Code + * + * $Id: jas_debug.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_DEBUG_H +#define JAS_DEBUG_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include +#include "jasper/jas_types.h" +#include "jasper/jas_debug.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Macros and functions. +\******************************************************************************/ + +/* Output debugging information to standard error provided that the debug + level is set sufficiently high. */ +#if defined(DEBUG) +#define JAS_DBGLOG(n, x) \ + ((jas_getdbglevel() >= (n)) ? (jas_eprintf x) : 0) +#else +#define JAS_DBGLOG(n, x) +#endif + +/* Get the library debug level. */ +int jas_getdbglevel(void); + +/* Set the library debug level. */ +int jas_setdbglevel(int dbglevel); + +/* Perform formatted output to standard error. */ +int jas_eprintf(const char *fmt, ...); + +/* Dump memory to a stream. */ +int jas_memdump(FILE *out, void *data, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_fix.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_fix.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_fix.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_fix.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,358 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Fixed-Point Number Class + * + * $Id: jas_fix.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_FIX_H +#define JAS_FIX_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* The representation of the value zero. */ +#define JAS_FIX_ZERO(fix_t, fracbits) \ + JAS_CAST(fix_t, 0) + +/* The representation of the value one. */ +#define JAS_FIX_ONE(fix_t, fracbits) \ + (JAS_CAST(fix_t, 1) << (fracbits)) + +/* The representation of the value one half. */ +#define JAS_FIX_HALF(fix_t, fracbits) \ + (JAS_CAST(fix_t, 1) << ((fracbits) - 1)) + +/******************************************************************************\ +* Conversion operations. +\******************************************************************************/ + +/* Convert an int to a fixed-point number. */ +#define JAS_INTTOFIX(fix_t, fracbits, x) \ + JAS_CAST(fix_t, (x) << (fracbits)) + +/* Convert a fixed-point number to an int. */ +#define JAS_FIXTOINT(fix_t, fracbits, x) \ + JAS_CAST(int, (x) >> (fracbits)) + +/* Convert a fixed-point number to a double. */ +#define JAS_FIXTODBL(fix_t, fracbits, x) \ + (JAS_CAST(double, x) / (JAS_CAST(fix_t, 1) << (fracbits))) + +/* Convert a double to a fixed-point number. */ +#define JAS_DBLTOFIX(fix_t, fracbits, x) \ + JAS_CAST(fix_t, ((x) * JAS_CAST(double, JAS_CAST(fix_t, 1) << (fracbits)))) + +/******************************************************************************\ +* Basic arithmetic operations. +* All other arithmetic operations are synthesized from these basic operations. +* There are three macros for each type of arithmetic operation. +* One macro always performs overflow/underflow checking, one never performs +* overflow/underflow checking, and one is generic with its behavior +* depending on compile-time flags. +* Only the generic macros should be invoked directly by application code. +\******************************************************************************/ + +/* Calculate the sum of two fixed-point numbers. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_ADD JAS_FIX_ADD_FAST +#else +#define JAS_FIX_ADD JAS_FIX_ADD_OFLOW +#endif + +/* Calculate the sum of two fixed-point numbers without overflow checking. */ +#define JAS_FIX_ADD_FAST(fix_t, fracbits, x, y) ((x) + (y)) + +/* Calculate the sum of two fixed-point numbers with overflow checking. */ +#define JAS_FIX_ADD_OFLOW(fix_t, fracbits, x, y) \ + ((x) >= 0) ? \ + (((y) >= 0) ? ((x) + (y) >= 0 || JAS_FIX_OFLOW(), (x) + (y)) : \ + ((x) + (y))) : \ + (((y) >= 0) ? ((x) + (y)) : ((x) + (y) < 0 || JAS_FIX_OFLOW(), \ + (x) + (y))) + +/* Calculate the product of two fixed-point numbers. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_MUL JAS_FIX_MUL_FAST +#else +#define JAS_FIX_MUL JAS_FIX_MUL_OFLOW +#endif + +/* Calculate the product of two fixed-point numbers without overflow + checking. */ +#define JAS_FIX_MUL_FAST(fix_t, fracbits, bigfix_t, x, y) \ + JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y)) >> \ + (fracbits)) + +/* Calculate the product of two fixed-point numbers with overflow + checking. */ +#define JAS_FIX_MUL_OFLOW(fix_t, fracbits, bigfix_t, x, y) \ + ((JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> (fracbits)) == \ + JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> \ + (fracbits))) ? \ + JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> \ + (fracbits))) : JAS_FIX_OFLOW()) + +/* Calculate the product of a fixed-point number and an int. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_FAST +#else +#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_OFLOW +#endif + +/* Calculate the product of a fixed-point number and an int without overflow + checking. */ +#define JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y) \ + JAS_CAST(fix_t, ((x) * (y))) + +/* Calculate the product of a fixed-point number and an int with overflow + checking. */ +#define JAS_FIX_MULBYINT_OFLOW(fix_t, fracbits, x, y) \ + JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y) + +/* Calculate the quotient of two fixed-point numbers. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_DIV JAS_FIX_DIV_FAST +#else +#define JAS_FIX_DIV JAS_FIX_DIV_UFLOW +#endif + +/* Calculate the quotient of two fixed-point numbers without underflow + checking. */ +#define JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y) \ + JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) << (fracbits)) / (y)) + +/* Calculate the quotient of two fixed-point numbers with underflow + checking. */ +#define JAS_FIX_DIV_UFLOW(fix_t, fracbits, bigfix_t, x, y) \ + JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y) + +/* Negate a fixed-point number. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_NEG JAS_FIX_NEG_FAST +#else +#define JAS_FIX_NEG JAS_FIX_NEG_OFLOW +#endif + +/* Negate a fixed-point number without overflow checking. */ +#define JAS_FIX_NEG_FAST(fix_t, fracbits, x) \ + (-(x)) + +/* Negate a fixed-point number with overflow checking. */ +/* Yes, overflow is actually possible for two's complement representations, + although highly unlikely to occur. */ +#define JAS_FIX_NEG_OFLOW(fix_t, fracbits, x) \ + (((x) < 0) ? (-(x) > 0 || JAS_FIX_OFLOW(), -(x)) : (-(x))) + +/* Perform an arithmetic shift left of a fixed-point number. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_ASL JAS_FIX_ASL_FAST +#else +#define JAS_FIX_ASL JAS_FIX_ASL_OFLOW +#endif + +/* Perform an arithmetic shift left of a fixed-point number without overflow + checking. */ +#define JAS_FIX_ASL_FAST(fix_t, fracbits, x, n) \ + ((x) << (n)) + +/* Perform an arithmetic shift left of a fixed-point number with overflow + checking. */ +#define JAS_FIX_ASL_OFLOW(fix_t, fracbits, x, n) \ + ((((x) << (n)) >> (n)) == (x) || JAS_FIX_OFLOW(), (x) << (n)) + +/* Perform an arithmetic shift right of a fixed-point number. */ +#if !defined(DEBUG_OVERFLOW) +#define JAS_FIX_ASR JAS_FIX_ASR_FAST +#else +#define JAS_FIX_ASR JAS_FIX_ASR_UFLOW +#endif + +/* Perform an arithmetic shift right of a fixed-point number without underflow + checking. */ +#define JAS_FIX_ASR_FAST(fix_t, fracbits, x, n) \ + ((x) >> (n)) + +/* Perform an arithmetic shift right of a fixed-point number with underflow + checking. */ +#define JAS_FIX_ASR_UFLOW(fix_t, fracbits, x, n) \ + JAS_FIX_ASR_FAST(fix_t, fracbits, x, n) + +/******************************************************************************\ +* Other basic arithmetic operations. +\******************************************************************************/ + +/* Calculate the difference between two fixed-point numbers. */ +#define JAS_FIX_SUB(fix_t, fracbits, x, y) \ + JAS_FIX_ADD(fix_t, fracbits, x, JAS_FIX_NEG(fix_t, fracbits, y)) + +/* Add one fixed-point number to another. */ +#define JAS_FIX_PLUSEQ(fix_t, fracbits, x, y) \ + ((x) = JAS_FIX_ADD(fix_t, fracbits, x, y)) + +/* Subtract one fixed-point number from another. */ +#define JAS_FIX_MINUSEQ(fix_t, fracbits, x, y) \ + ((x) = JAS_FIX_SUB(fix_t, fracbits, x, y)) + +/* Multiply one fixed-point number by another. */ +#define JAS_FIX_MULEQ(fix_t, fracbits, bigfix_t, x, y) \ + ((x) = JAS_FIX_MUL(fix_t, fracbits, bigfix_t, x, y)) + +/******************************************************************************\ +* Miscellaneous operations. +\******************************************************************************/ + +/* Calculate the absolute value of a fixed-point number. */ +#define JAS_FIX_ABS(fix_t, fracbits, x) \ + (((x) >= 0) ? (x) : (JAS_FIX_NEG(fix_t, fracbits, x))) + +/* Is a fixed-point number an integer? */ +#define JAS_FIX_ISINT(fix_t, fracbits, x) \ + (JAS_FIX_FLOOR(fix_t, fracbits, x) == (x)) + +/* Get the sign of a fixed-point number. */ +#define JAS_FIX_SGN(fix_t, fracbits, x) \ + ((x) >= 0 ? 1 : (-1)) + +/******************************************************************************\ +* Relational operations. +\******************************************************************************/ + +/* Compare two fixed-point numbers. */ +#define JAS_FIX_CMP(fix_t, fracbits, x, y) \ + ((x) > (y) ? 1 : (((x) == (y)) ? 0 : (-1))) + +/* Less than. */ +#define JAS_FIX_LT(fix_t, fracbits, x, y) \ + ((x) < (y)) + +/* Less than or equal. */ +#define JAS_FIX_LTE(fix_t, fracbits, x, y) \ + ((x) <= (y)) + +/* Greater than. */ +#define JAS_FIX_GT(fix_t, fracbits, x, y) \ + ((x) > (y)) + +/* Greater than or equal. */ +#define JAS_FIX_GTE(fix_t, fracbits, x, y) \ + ((x) >= (y)) + +/******************************************************************************\ +* Rounding functions. +\******************************************************************************/ + +/* Round a fixed-point number to the nearest integer. */ +#define JAS_FIX_ROUND(fix_t, fracbits, x) \ + (((x) < 0) ? JAS_FIX_FLOOR(fix_t, fracbits, JAS_FIX_ADD(fix_t, fracbits, \ + (x), JAS_FIX_HALF(fix_t, fracbits))) : \ + JAS_FIX_NEG(fix_t, fracbits, JAS_FIX_FLOOR(fix_t, fracbits, \ + JAS_FIX_ADD(fix_t, fracbits, (-(x)), JAS_FIX_HALF(fix_t, fracbits))))) + +/* Round a fixed-point number to the nearest integer in the direction of + negative infinity (i.e., the floor function). */ +#define JAS_FIX_FLOOR(fix_t, fracbits, x) \ + ((x) & (~((JAS_CAST(fix_t, 1) << (fracbits)) - 1))) + +/* Round a fixed-point number to the nearest integer in the direction + of zero. */ +#define JAS_FIX_TRUNC(fix_t, fracbits, x) \ + (((x) >= 0) ? JAS_FIX_FLOOR(fix_t, fracbits, x) : \ + JAS_FIX_CEIL(fix_t, fracbits, x)) + +/******************************************************************************\ +* The below macros are for internal library use only. Do not invoke them +* directly in application code. +\******************************************************************************/ + +/* Handle overflow. */ +#define JAS_FIX_OFLOW() \ + jas_eprintf("overflow error: file %s, line %d\n", __FILE__, __LINE__) + +/* Handle underflow. */ +#define JAS_FIX_UFLOW() \ + jas_eprintf("underflow error: file %s, line %d\n", __FILE__, __LINE__) + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_getopt.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_getopt.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_getopt.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_getopt.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Command Line Option Parsing Code + * + * $Id: jas_getopt.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_GETOPT_H +#define JAS_GETOPT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +#define JAS_GETOPT_EOF (-1) +#define JAS_GETOPT_ERR '?' + +/* option flags. */ +#define JAS_OPT_HASARG 0x01 /* option has argument */ + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* Command line option type. */ +typedef struct { + + int id; + /* The unique identifier for this option. */ + + char *name; + /* The name of this option. */ + + int flags; + /* option flags. */ + +} jas_opt_t; + +/******************************************************************************\ +* External data. +\******************************************************************************/ + +/* The current option index. */ +extern int jas_optind; + +/* The current option argument. */ +extern char *jas_optarg; + +/* The debug level. */ +extern int jas_opterr; + +/******************************************************************************\ +* Prototypes. +\******************************************************************************/ + +/* Get the next option. */ +int jas_getopt(int argc, char **argv, jas_opt_t *opts); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_icc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_icc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_icc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_icc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JAS_ICC_H +#define JAS_ICC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Profile file signature. */ +#define JAS_ICC_MAGIC 0x61637370 + +#define JAS_ICC_HDRLEN 128 + +/* Profile/device class signatures. */ +#define JAS_ICC_CLAS_IN 0x73636e72 /* input device */ +#define JAS_ICC_CLAS_DPY 0x6d6e7472 /* display device */ +#define JAS_ICC_CLAS_OUT 0x70727472 /* output device */ +#define JAS_ICC_CLAS_LNK 0x6c696e6b /* device link */ +#define JAS_ICC_CLAS_CNV 0x73706163 /* color space conversion */ +#define JAS_ICC_CLAS_ABS 0x61627374 /* abstract */ +#define JAS_ICC_CLAS_NAM 0x6e6d636c /* named color */ + +/* Color space signatures. */ +#define JAS_ICC_COLORSPC_XYZ 0x58595a20 /* XYZ */ +#define JAS_ICC_COLORSPC_LAB 0x4c616220 /* LAB */ +#define JAS_ICC_COLORSPC_LUV 0x4c757620 /* LUV */ +#define JAS_ICC_COLORSPC_YCBCR 0x59436272 /* YCbCr */ +#define JAS_ICC_COLORSPC_YXY 0x59787920 /* Yxy */ +#define JAS_ICC_COLORSPC_RGB 0x52474220 /* RGB */ +#define JAS_ICC_COLORSPC_GRAY 0x47524159 /* Gray */ +#define JAS_ICC_COLORSPC_HSV 0x48535620 /* HSV */ +#define JAS_ICC_COLORSPC_HLS 0x484c5320 /* HLS */ +#define JAS_ICC_COLORSPC_CMYK 0x434d594b /* CMYK */ +#define JAS_ICC_COLORSPC_CMY 0x434d5920 /* CMY */ +#define JAS_ICC_COLORSPC_2 0x32434c52 /* 2 channel color */ +#define JAS_ICC_COLORSPC_3 0x33434c52 /* 3 channel color */ +#define JAS_ICC_COLORSPC_4 0x34434c52 /* 4 channel color */ +#define JAS_ICC_COLORSPC_5 0x35434c52 /* 5 channel color */ +#define JAS_ICC_COLORSPC_6 0x36434c52 /* 6 channel color */ +#define JAS_ICC_COLORSPC_7 0x37434c52 /* 7 channel color */ +#define JAS_ICC_COLORSPC_8 0x38434c52 /* 8 channel color */ +#define JAS_ICC_COLORSPC_9 0x39434c52 /* 9 channel color */ +#define JAS_ICC_COLORSPC_10 0x41434c52 /* 10 channel color */ +#define JAS_ICC_COLORSPC_11 0x42434c52 /* 11 channel color */ +#define JAS_ICC_COLORSPC_12 0x43434c52 /* 12 channel color */ +#define JAS_ICC_COLORSPC_13 0x44434c52 /* 13 channel color */ +#define JAS_ICC_COLORSPC_14 0x45434c52 /* 14 channel color */ +#define JAS_ICC_COLORSPC_15 0x46434c52 /* 15 channel color */ + +/* Profile connection color space (PCS) signatures. */ +#define JAS_ICC_REFCOLORSPC_XYZ 0x58595a20 /* CIE XYZ */ +#define JAS_ICC_REFCOLORSPC_LAB 0x4c616220 /* CIE Lab */ + +/* Primary platform signatures. */ +#define JAS_ICC_PLATFORM_APPL 0x4150504c /* Apple Computer */ +#define JAS_ICC_PLATFORM_MSFT 0x4d534654 /* Microsoft */ +#define JAS_ICC_PLATFORM_SGI 0x53474920 /* Silicon Graphics */ +#define JAS_ICC_PLATFORM_SUNW 0x53554e57 /* Sun Microsystems */ +#define JAS_ICC_PLATFORM_TGNT 0x54474e54 /* Taligent */ + +/* Profile flags. */ +#define JAS_ICC_FLAGS_EMBED 0x01 /* embedded */ +#define JAS_ICC_FLAGS_NOSEP 0x02 /* no separate use */ + +/* Attributes. */ +#define JAS_ICC_ATTR_TRANS 0x01 /* transparent */ +#define JAS_ICC_ATTR_MATTE 0x02 /* matte */ + +/* Rendering intents. */ +#define JAS_ICC_INTENT_PER 0 /* perceptual */ +#define JAS_ICC_INTENT_REL 1 /* relative colorimetric */ +#define JAS_ICC_INTENT_SAT 2 /* saturation */ +#define JAS_ICC_INTENT_ABS 3 /* absolute colorimetric */ + +/* Tag signatures. */ +#define JAS_ICC_TAG_ATOB0 0x41324230 /* */ +#define JAS_ICC_TAG_ATOB1 0x41324231 /* */ +#define JAS_ICC_TAG_ATOB2 0x41324232 /* */ +#define JAS_ICC_TAG_BLUMATCOL 0x6258595a /* */ +#define JAS_ICC_TAG_BLUTRC 0x62545243 /* */ +#define JAS_ICC_TAG_BTOA0 0x42324130 /* */ +#define JAS_ICC_TAG_BTOA1 0x42324131 /* */ +#define JAS_ICC_TAG_BTOA2 0x42324132 /* */ +#define JAS_ICC_TAG_CALTIME 0x63616c74 /* */ +#define JAS_ICC_TAG_CHARTARGET 0x74617267 /* */ +#define JAS_ICC_TAG_CPYRT 0x63707274 /* */ +#define JAS_ICC_TAG_CRDINFO 0x63726469 /* */ +#define JAS_ICC_TAG_DEVMAKERDESC 0x646d6e64 /* */ +#define JAS_ICC_TAG_DEVMODELDESC 0x646d6464 /* */ +#define JAS_ICC_TAG_DEVSET 0x64657673 /* */ +#define JAS_ICC_TAG_GAMUT 0x67616d74 /* */ +#define JAS_ICC_TAG_GRYTRC 0x6b545243 /* */ +#define JAS_ICC_TAG_GRNMATCOL 0x6758595a /* */ +#define JAS_ICC_TAG_GRNTRC 0x67545243 /* */ +#define JAS_ICC_TAG_LUM 0x6c756d69 /* */ +#define JAS_ICC_TAG_MEASURE 0x6d656173 /* */ +#define JAS_ICC_TAG_MEDIABLKPT 0x626b7074 /* */ +#define JAS_ICC_TAG_MEDIAWHIPT 0x77747074 /* */ +#define JAS_ICC_TAG_NAMCOLR 0x6e636f6c /* */ +#define JAS_ICC_TAG_NAMCOLR2 0x6e636c32 /* */ +#define JAS_ICC_TAG_OUTRESP 0x72657370 /* */ +#define JAS_ICC_TAG_PREVIEW0 0x70726530 /* */ +#define JAS_ICC_TAG_PREVIEW1 0x70726531 /* */ +#define JAS_ICC_TAG_PREVIEW2 0x70726532 /* */ +#define JAS_ICC_TAG_PROFDESC 0x64657363 /* */ +#define JAS_ICC_TAG_PROFSEQDESC 0x70736571 /* */ +#define JAS_ICC_TAG_PSDCRD0 0x70736430 /* */ +#define JAS_ICC_TAG_PSCRDD1 0x70736431 /* */ +#define JAS_ICC_TAG_PSCRDD2 0x70736432 /* */ +#define JAS_ICC_TAG_PSCRDD3 0x70736433 /* */ +#define JAS_ICC_TAG_PS2CSA 0x70733273 /* */ +#define JAS_ICC_TAG_PS2RENINTENT 0x70733269 /* */ +#define JAS_ICC_TAG_REDMATCOL 0x7258595a /* */ +#define JAS_ICC_TAG_REDTRC 0x72545243 /* */ +#define JAS_ICC_TAG_SCRNGDES 0x73637264 /* */ +#define JAS_ICC_TAG_SCRNG 0x7363726e /* */ +#define JAS_ICC_TAG_TECH 0x74656368 /* */ +#define JAS_ICC_TAG_UCRBG 0x62666420 /* */ +#define JAS_ICC_TAG_VIEWCONDDESC 0x76756564 /* */ +#define JAS_ICC_TAG_VIEWCOND 0x76696577 /* */ + +/* Type signatures. */ +#define JAS_ICC_TYPE_CRDINFO 0x63726469 /* CRD information */ +#define JAS_ICC_TYPE_CURV 0x63757276 /* curve */ +#define JAS_ICC_TYPE_DATA 0x64617461 /* data */ +#define JAS_ICC_TYPE_TIME 0x6474696d /* date/time */ +#define JAS_ICC_TYPE_DEVSET 0x64657673 /* device settings */ +#define JAS_ICC_TYPE_LUT16 0x6d667432 /* */ +#define JAS_ICC_TYPE_LUT8 0x6d667431 /* */ +#define JAS_ICC_TYPE_MEASURE 0x6d656173 /* */ +#define JAS_ICC_TYPE_NAMCOLR 0x6e636f6c /* */ +#define JAS_ICC_TYPE_NAMCOLR2 0x6e636c32 /* */ +#define JAS_ICC_TYPE_PROFSEQDESC 0x70736571 /* profile sequence description */ +#define JAS_ICC_TYPE_RESPCURVSET16 0x72637332 /* response curve set 16 */ +#define JAS_ICC_TYPE_SF32 0x73663332 /* signed 32-bit fixed-point */ +#define JAS_ICC_TYPE_SCRNG 0x7363726e /* screening */ +#define JAS_ICC_TYPE_SIG 0x73696720 /* signature */ +#define JAS_ICC_TYPE_TXTDESC 0x64657363 /* text description */ +#define JAS_ICC_TYPE_TXT 0x74657874 /* text */ +#define JAS_ICC_TYPE_UF32 0x75663332 /* unsigned 32-bit fixed-point */ +#define JAS_ICC_TYPE_UCRBG 0x62666420 /* */ +#define JAS_ICC_TYPE_UI16 0x75693136 /* */ +#define JAS_ICC_TYPE_UI32 0x75693332 /* */ +#define JAS_ICC_TYPE_UI8 0x75693038 /* */ +#define JAS_ICC_TYPE_UI64 0x75693634 /* */ +#define JAS_ICC_TYPE_VIEWCOND 0x76696577 /* */ +#define JAS_ICC_TYPE_XYZ 0x58595a20 /* XYZ */ + +typedef uint_fast8_t jas_iccuint8_t; +typedef uint_fast16_t jas_iccuint16_t; +typedef uint_fast32_t jas_iccuint32_t; +typedef int_fast32_t jas_iccsint32_t; +typedef int_fast32_t jas_iccs15fixed16_t; +typedef uint_fast32_t jas_iccu16fixed16_t; +typedef uint_fast64_t jas_iccuint64_t; +typedef uint_fast32_t jas_iccsig_t; + +typedef jas_iccsig_t jas_icctagsig_t; +typedef jas_iccsig_t jas_icctagtype_t; +typedef jas_iccsig_t jas_iccattrname_t; + +/* Date/time type. */ +typedef struct { + jas_iccuint16_t year; + jas_iccuint16_t month; + jas_iccuint16_t day; + jas_iccuint16_t hour; + jas_iccuint16_t min; + jas_iccuint16_t sec; +} jas_icctime_t; + +/* XYZ type. */ +typedef struct { + jas_iccs15fixed16_t x; + jas_iccs15fixed16_t y; + jas_iccs15fixed16_t z; +} jas_iccxyz_t; + +/* Curve type. */ +typedef struct { + jas_iccuint32_t numents; + jas_iccuint16_t *ents; +} jas_icccurv_t; + +/* Text description type. */ +typedef struct { + jas_iccuint32_t asclen; + char *ascdata; /* ASCII invariant description */ + jas_iccuint32_t uclangcode; /* Unicode language code */ + jas_iccuint32_t uclen; /* Unicode localizable description count */ + uchar *ucdata; /* Unicode localizable description */ + jas_iccuint16_t sccode; /* ScriptCode code */ + jas_iccuint8_t maclen; /* Localizable Macintosh description count */ + uchar macdata[69]; /* Localizable Macintosh description */ +} jas_icctxtdesc_t; + +/* Text type. */ +typedef struct { + char *string; /* ASCII character string */ +} jas_icctxt_t; + +typedef struct { + jas_iccuint8_t numinchans; + jas_iccuint8_t numoutchans; + jas_iccsint32_t e[3][3]; + jas_iccuint8_t clutlen; + jas_iccuint8_t *clut; + jas_iccuint16_t numintabents; + jas_iccuint8_t **intabs; + jas_iccuint8_t *intabsbuf; + jas_iccuint16_t numouttabents; + jas_iccuint8_t **outtabs; + jas_iccuint8_t *outtabsbuf; +} jas_icclut8_t; + +typedef struct { + jas_iccuint8_t numinchans; + jas_iccuint8_t numoutchans; + jas_iccsint32_t e[3][3]; + jas_iccuint8_t clutlen; + jas_iccuint16_t *clut; + jas_iccuint16_t numintabents; + jas_iccuint16_t **intabs; + jas_iccuint16_t *intabsbuf; + jas_iccuint16_t numouttabents; + jas_iccuint16_t **outtabs; + jas_iccuint16_t *outtabsbuf; +} jas_icclut16_t; + +struct jas_iccattrval_s; + +typedef struct { + void (*destroy)(struct jas_iccattrval_s *); + int (*copy)(struct jas_iccattrval_s *, struct jas_iccattrval_s *); + int (*input)(struct jas_iccattrval_s *, jas_stream_t *, int); + int (*output)(struct jas_iccattrval_s *, jas_stream_t *); + int (*getsize)(struct jas_iccattrval_s *); + void (*dump)(struct jas_iccattrval_s *, FILE *); +} jas_iccattrvalops_t; + +/* Attribute value type (type and value information). */ +typedef struct jas_iccattrval_s { + int refcnt; /* reference count */ + jas_iccsig_t type; /* type */ + jas_iccattrvalops_t *ops; /* type-dependent operations */ + union { + jas_iccxyz_t xyz; + jas_icccurv_t curv; + jas_icctxtdesc_t txtdesc; + jas_icctxt_t txt; + jas_icclut8_t lut8; + jas_icclut16_t lut16; + } data; /* value */ +} jas_iccattrval_t; + +/* Header type. */ +typedef struct { + jas_iccuint32_t size; /* profile size */ + jas_iccsig_t cmmtype; /* CMM type signature */ + jas_iccuint32_t version; /* profile version */ + jas_iccsig_t clas; /* profile/device class signature */ + jas_iccsig_t colorspc; /* color space of data */ + jas_iccsig_t refcolorspc; /* profile connection space */ + jas_icctime_t ctime; /* creation time */ + jas_iccsig_t magic; /* profile file signature */ + jas_iccsig_t platform; /* primary platform */ + jas_iccuint32_t flags; /* profile flags */ + jas_iccsig_t maker; /* device manufacturer signature */ + jas_iccsig_t model; /* device model signature */ + jas_iccuint64_t attr; /* device setup attributes */ + jas_iccsig_t intent; /* rendering intent */ + jas_iccxyz_t illum; /* illuminant */ + jas_iccsig_t creator; /* profile creator signature */ +} jas_icchdr_t; + +typedef struct { + jas_iccsig_t name; + jas_iccattrval_t *val; +} jas_iccattr_t; + +typedef struct { + int numattrs; + int maxattrs; + jas_iccattr_t *attrs; +} jas_iccattrtab_t; + +typedef struct jas_icctagtabent_s { + jas_iccuint32_t tag; + jas_iccuint32_t off; + jas_iccuint32_t len; + void *data; + struct jas_icctagtabent_s *first; +} jas_icctagtabent_t; + +typedef struct { + jas_iccuint32_t numents; + jas_icctagtabent_t *ents; +} jas_icctagtab_t; + +/* ICC profile type. */ +typedef struct { + jas_icchdr_t hdr; + jas_icctagtab_t tagtab; + jas_iccattrtab_t *attrtab; +} jas_iccprof_t; + +typedef struct { + jas_iccuint32_t type; + jas_iccattrvalops_t ops; +} jas_iccattrvalinfo_t; + +jas_iccprof_t *jas_iccprof_load(jas_stream_t *in); +int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out); +void jas_iccprof_destroy(jas_iccprof_t *prof); +jas_iccattrval_t *jas_iccprof_getattr(jas_iccprof_t *prof, + jas_iccattrname_t name); +int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name, + jas_iccattrval_t *val); +void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out); +jas_iccprof_t *jas_iccprof_copy(jas_iccprof_t *prof); +int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr); +int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr); + +void jas_iccattrval_destroy(jas_iccattrval_t *attrval); +void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out); +int jas_iccattrval_allowmodify(jas_iccattrval_t **attrval); +jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval); +jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type); + +void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out); + +extern uchar jas_iccprofdata_srgb[]; +extern int jas_iccprofdata_srgblen; +extern uchar jas_iccprofdata_sgray[]; +extern int jas_iccprofdata_sgraylen; +jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len); +jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_image.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_image.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_image.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_image.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,564 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Image Class + * + * $Id: jas_image.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_IMAGE_H +#define JAS_IMAGE_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* + * Miscellaneous constants. + */ + +/* The threshold at which image data is no longer stored in memory. */ +#define JAS_IMAGE_INMEMTHRESH (16 * 1024 * 1024) + +/* + * Component types + */ + +#define JAS_IMAGE_CT_UNKNOWN 0x10000 +#define JAS_IMAGE_CT_COLOR(n) ((n) & 0x7fff) +#define JAS_IMAGE_CT_OPACITY 0x08000 + +#define JAS_IMAGE_CT_RGB_R 0 +#define JAS_IMAGE_CT_RGB_G 1 +#define JAS_IMAGE_CT_RGB_B 2 + +#define JAS_IMAGE_CT_YCBCR_Y 0 +#define JAS_IMAGE_CT_YCBCR_CB 1 +#define JAS_IMAGE_CT_YCBCR_CR 2 + +#define JAS_IMAGE_CT_GRAY_Y 0 + +/******************************************************************************\ +* Simple types. +\******************************************************************************/ + +/* Image coordinate. */ +typedef int_fast32_t jas_image_coord_t; + +/* Color space (e.g., RGB, YCbCr). */ +typedef int_fast16_t jas_image_colorspc_t; + +/* Component type (e.g., color, opacity). */ +typedef int_fast32_t jas_image_cmpttype_t; + +/* Component sample data format (e.g., real/integer, signedness, precision). */ +typedef int_fast16_t jas_image_smpltype_t; + +/******************************************************************************\ +* Image class and supporting classes. +\******************************************************************************/ + +/* Image component class. */ + +typedef struct { + + jas_image_coord_t tlx_; + /* The x-coordinate of the top-left corner of the component. */ + + jas_image_coord_t tly_; + /* The y-coordinate of the top-left corner of the component. */ + + jas_image_coord_t hstep_; + /* The horizontal sampling period in units of the reference grid. */ + + jas_image_coord_t vstep_; + /* The vertical sampling period in units of the reference grid. */ + + jas_image_coord_t width_; + /* The component width in samples. */ + + jas_image_coord_t height_; + /* The component height in samples. */ + +#ifdef FIX_ME + int smpltype_; +#else + int prec_; + /* The precision of the sample data (i.e., the number of bits per + sample). If the samples are signed values, this quantity + includes the sign bit. */ + + int sgnd_; + /* The signedness of the sample data. */ +#endif + + jas_stream_t *stream_; + /* The stream containing the component data. */ + + int cps_; + /* The number of characters per sample in the stream. */ + + jas_image_cmpttype_t type_; + /* The type of component (e.g., opacity, red, green, blue, luma). */ + +} jas_image_cmpt_t; + +/* Image class. */ + +typedef struct { + + jas_image_coord_t tlx_; + /* The x-coordinate of the top-left corner of the image bounding box. */ + + jas_image_coord_t tly_; + /* The y-coordinate of the top-left corner of the image bounding box. */ + + jas_image_coord_t brx_; + /* The x-coordinate of the bottom-right corner of the image bounding + box (plus one). */ + + jas_image_coord_t bry_; + /* The y-coordinate of the bottom-right corner of the image bounding + box (plus one). */ + + int numcmpts_; + /* The number of components. */ + + int maxcmpts_; + /* The maximum number of components that this image can have (i.e., the + allocated size of the components array). */ + + jas_image_cmpt_t **cmpts_; + /* Per-component information. */ + + jas_clrspc_t clrspc_; + + jas_cmprof_t *cmprof_; + + bool inmem_; + +} jas_image_t; + +/* Component parameters class. */ +/* This data type exists solely/mainly for the purposes of the + jas_image_create function. */ + +typedef struct { + + jas_image_coord_t tlx; + /* The x-coordinate of the top-left corner of the component. */ + + jas_image_coord_t tly; + /* The y-coordinate of the top-left corner of the component. */ + + jas_image_coord_t hstep; + /* The horizontal sampling period in units of the reference grid. */ + + jas_image_coord_t vstep; + /* The vertical sampling period in units of the reference grid. */ + + jas_image_coord_t width; + /* The width of the component in samples. */ + + jas_image_coord_t height; + /* The height of the component in samples. */ + +#ifdef FIX_ME + int smpltype; +#else + int prec; + /* The precision of the component sample data. */ + + int sgnd; + /* The signedness of the component sample data. */ +#endif + +} jas_image_cmptparm_t; + +/******************************************************************************\ +* File format related classes. +\******************************************************************************/ + +#define JAS_IMAGE_MAXFMTS 32 +/* The maximum number of image data formats supported. */ + +/* Image format-dependent operations. */ + +typedef struct { + + jas_image_t *(*decode)(jas_stream_t *in, char *opts); + /* Decode image data from a stream. */ + + int (*encode)(jas_image_t *image, jas_stream_t *out, char *opts); + /* Encode image data to a stream. */ + + int (*validate)(jas_stream_t *in); + /* Determine if stream data is in a particular format. */ + +} jas_image_fmtops_t; + +/* Image format information. */ + +typedef struct { + + int id; + /* The ID for this format. */ + + char *name; + /* The name by which this format is identified. */ + + char *ext; + /* The file name extension associated with this format. */ + + char *desc; + /* A brief description of the format. */ + + jas_image_fmtops_t ops; + /* The operations for this format. */ + +} jas_image_fmtinfo_t; + +/******************************************************************************\ +* Image operations. +\******************************************************************************/ + +/* Create an image. */ +jas_image_t *jas_image_create(int numcmpts, + jas_image_cmptparm_t *cmptparms, jas_clrspc_t clrspc); + +/* Create an "empty" image. */ +jas_image_t *jas_image_create0(void); + +/* Clone an image. */ +jas_image_t *jas_image_copy(jas_image_t *image); + +/* Deallocate any resources associated with an image. */ +void jas_image_destroy(jas_image_t *image); + +/* Get the width of the image in units of the image reference grid. */ +#define jas_image_width(image) \ + ((image)->brx_ - (image)->tlx_) + +/* Get the height of the image in units of the image reference grid. */ +#define jas_image_height(image) \ + ((image)->bry_ - (image)->tly_) + +/* Get the x-coordinate of the top-left corner of the image bounding box + on the reference grid. */ +#define jas_image_tlx(image) \ + ((image)->tlx_) + +/* Get the y-coordinate of the top-left corner of the image bounding box + on the reference grid. */ +#define jas_image_tly(image) \ + ((image)->tly_) + +/* Get the x-coordinate of the bottom-right corner of the image bounding box + on the reference grid (plus one). */ +#define jas_image_brx(image) \ + ((image)->brx_) + +/* Get the y-coordinate of the bottom-right corner of the image bounding box + on the reference grid (plus one). */ +#define jas_image_bry(image) \ + ((image)->bry_) + +/* Get the number of image components. */ +#define jas_image_numcmpts(image) \ + ((image)->numcmpts_) + +/* Get the color model used by the image. */ +#define jas_image_clrspc(image) \ + ((image)->clrspc_) + +/* Set the color model for an image. */ +#define jas_image_setclrspc(image, clrspc) \ + ((image)->clrspc_ = (clrspc)) + +#define jas_image_cmpttype(image, cmptno) \ + ((image)->cmpts_[(cmptno)]->type_) +#define jas_image_setcmpttype(image, cmptno, type) \ + ((image)->cmpts_[(cmptno)]->type_ = (type)) + +/* Get the width of a component. */ +#define jas_image_cmptwidth(image, cmptno) \ + ((image)->cmpts_[cmptno]->width_) + +/* Get the height of a component. */ +#define jas_image_cmptheight(image, cmptno) \ + ((image)->cmpts_[cmptno]->height_) + +/* Get the signedness of the sample data for a component. */ +#define jas_image_cmptsgnd(image, cmptno) \ + ((image)->cmpts_[cmptno]->sgnd_) + +/* Get the precision of the sample data for a component. */ +#define jas_image_cmptprec(image, cmptno) \ + ((image)->cmpts_[cmptno]->prec_) + +/* Get the horizontal subsampling factor for a component. */ +#define jas_image_cmpthstep(image, cmptno) \ + ((image)->cmpts_[cmptno]->hstep_) + +/* Get the vertical subsampling factor for a component. */ +#define jas_image_cmptvstep(image, cmptno) \ + ((image)->cmpts_[cmptno]->vstep_) + +/* Get the x-coordinate of the top-left corner of a component. */ +#define jas_image_cmpttlx(image, cmptno) \ + ((image)->cmpts_[cmptno]->tlx_) + +/* Get the y-coordinate of the top-left corner of a component. */ +#define jas_image_cmpttly(image, cmptno) \ + ((image)->cmpts_[cmptno]->tly_) + +/* Get the x-coordinate of the bottom-right corner of a component + (plus "one"). */ +#define jas_image_cmptbrx(image, cmptno) \ + ((image)->cmpts_[cmptno]->tlx_ + (image)->cmpts_[cmptno]->width_ * \ + (image)->cmpts_[cmptno]->hstep_) + +/* Get the y-coordinate of the bottom-right corner of a component + (plus "one"). */ +#define jas_image_cmptbry(image, cmptno) \ + ((image)->cmpts_[cmptno]->tly_ + (image)->cmpts_[cmptno]->height_ * \ + (image)->cmpts_[cmptno]->vstep_) + +/* Get the raw size of an image (i.e., the nominal size of the image without + any compression. */ +uint_fast32_t jas_image_rawsize(jas_image_t *image); + +/* Create an image from a stream in some specified format. */ +jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr); + +/* Write an image to a stream in a specified format. */ +int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, + char *optstr); + +/* Read a rectangular region of an image component. */ +/* The position and size of the rectangular region to be read is specified +relative to the component's coordinate system. */ +int jas_image_readcmpt(jas_image_t *image, int cmptno, + jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + jas_matrix_t *data); + +/* Write a rectangular region of an image component. */ +int jas_image_writecmpt(jas_image_t *image, int cmptno, + jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + jas_matrix_t *data); + +/* Delete a component from an image. */ +void jas_image_delcmpt(jas_image_t *image, int cmptno); + +/* Add a component to an image. */ +int jas_image_addcmpt(jas_image_t *image, int cmptno, + jas_image_cmptparm_t *cmptparm); + +/* Copy a component from one image to another. */ +int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, + jas_image_t *srcimage, int srccmptno); + +#define JAS_IMAGE_CDT_GETSGND(dtype) (((dtype) >> 7) & 1) +#define JAS_IMAGE_CDT_SETSGND(dtype) (((dtype) & 1) << 7) +#define JAS_IMAGE_CDT_GETPREC(dtype) ((dtype) & 0x7f) +#define JAS_IMAGE_CDT_SETPREC(dtype) ((dtype) & 0x7f) + +#define jas_image_cmptdtype(image, cmptno) \ + (JAS_IMAGE_CDT_SETSGND((image)->cmpts_[cmptno]->sgnd_) | JAS_IMAGE_CDT_SETPREC((image)->cmpts_[cmptno]->prec_)) + +int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents, + int_fast32_t *lutents, int dtype, int newcmptno); + +int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y); +void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y, + int_fast32_t v); + +int jas_image_getcmptbytype(jas_image_t *image, int ctype); + +/******************************************************************************\ +* Image format-related operations. +\******************************************************************************/ + +/* Clear the table of image formats. */ +void jas_image_clearfmts(void); + +/* Add entry to table of image formats. */ +int jas_image_addfmt(int id, char *name, char *ext, char *desc, + jas_image_fmtops_t *ops); + +/* Get the ID for the image format with the specified name. */ +int jas_image_strtofmt(char *s); + +/* Get the name of the image format with the specified ID. */ +char *jas_image_fmttostr(int fmt); + +/* Lookup image format information by the format ID. */ +jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id); + +/* Lookup image format information by the format name. */ +jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name); + +/* Guess the format of an image file based on its name. */ +int jas_image_fmtfromname(char *filename); + +/* Get the format of image data in a stream. */ +int jas_image_getfmt(jas_stream_t *in); + + +#define jas_image_cmprof(image) ((image)->cmprof_) +int jas_image_ishomosamp(jas_image_t *image); +int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno, + jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs, + jas_image_coord_t vs, int sgnd, int prec); +int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf); +int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf); + +#define jas_image_setcmprof(image, cmprof) ((image)->cmprof_ = cmprof) +jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof, + int intent); +void jas_image_dump(jas_image_t *image, FILE *out); + +/******************************************************************************\ +* Image format-dependent operations. +\******************************************************************************/ + +#if !defined(EXCLUDE_JPG_SUPPORT) +/* Format-dependent operations for JPG support. */ +jas_image_t *jpg_decode(jas_stream_t *in, char *optstr); +int jpg_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int jpg_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_MIF_SUPPORT) +/* Format-dependent operations for MIF support. */ +jas_image_t *mif_decode(jas_stream_t *in, char *optstr); +int mif_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int mif_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_PNM_SUPPORT) +/* Format-dependent operations for PNM support. */ +jas_image_t *pnm_decode(jas_stream_t *in, char *optstr); +int pnm_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int pnm_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_RAS_SUPPORT) +/* Format-dependent operations for Sun Rasterfile support. */ +jas_image_t *ras_decode(jas_stream_t *in, char *optstr); +int ras_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int ras_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_BMP_SUPPORT) +/* Format-dependent operations for BMP support. */ +jas_image_t *bmp_decode(jas_stream_t *in, char *optstr); +int bmp_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int bmp_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_JP2_SUPPORT) +/* Format-dependent operations for JP2 support. */ +jas_image_t *jp2_decode(jas_stream_t *in, char *optstr); +int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int jp2_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_JPC_SUPPORT) +/* Format-dependent operations for JPEG-2000 code stream support. */ +jas_image_t *jpc_decode(jas_stream_t *in, char *optstr); +int jpc_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int jpc_validate(jas_stream_t *in); +#endif + +#if !defined(EXCLUDE_PGX_SUPPORT) +/* Format-dependent operations for PGX support. */ +jas_image_t *pgx_decode(jas_stream_t *in, char *optstr); +int pgx_encode(jas_image_t *image, jas_stream_t *out, char *optstr); +int pgx_validate(jas_stream_t *in); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_init.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_init.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_init.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_init.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JAS_INIT_H +#define JAS_INIT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +int jas_init(void); + +void jas_cleanup(void); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_malloc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_malloc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_malloc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_malloc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Memory Allocator + * + * $Id: jas_malloc.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_MALLOC_H +#define JAS_MALLOC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Hack follows... +\******************************************************************************/ + +#if defined(DEBUG_MEMALLOC) +/* This is somewhat of a hack, but it's a useful hack. :-) */ +/* Use my own custom memory allocator for debugging. */ +#include "../../../../local/src/memalloc.h" +#define jas_malloc MEMALLOC +#define jas_free MEMFREE +#define jas_realloc MEMREALLOC +#define jas_calloc MEMCALLOC +#define jas_alloc2(a, b) MEMALLOC((a)*(b)) +#define jas_alloc3(a, b, c) MEMALLOC((a)*(b)*(c)) +#define jas_realloc2(p, a, b) MEMREALLOC((p), (a)*(b)) +#endif + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +#if !defined(DEBUG_MEMALLOC) + +/* Allocate memory. */ +void *jas_malloc(size_t size); + +/* Free memory. */ +void jas_free(void *ptr); + +/* Resize a block of allocated memory. */ +void *jas_realloc(void *ptr, size_t size); + +/* Allocate a block of memory and initialize the contents to zero. */ +void *jas_calloc(size_t nmemb, size_t size); + +/* size-checked double allocation .*/ +void *jas_alloc2(size_t, size_t); + +void *jas_alloc3(size_t, size_t, size_t); + +void *jas_realloc2(void *, size_t, size_t); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_math.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_math.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_math.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_math.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Math-Related Code + * + * $Id: jas_math.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_MATH_H +#define JAS_MATH_H + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Macros +\******************************************************************************/ + +/* Compute the absolute value. */ +#define JAS_ABS(x) \ + (((x) >= 0) ? (x) : (-(x))) + +/* Compute the minimum of two values. */ +#define JAS_MIN(x, y) \ + (((x) < (y)) ? (x) : (y)) + +/* Compute the maximum of two values. */ +#define JAS_MAX(x, y) \ + (((x) > (y)) ? (x) : (y)) + +/* Compute the remainder from division (where division is defined such + that the remainder is always nonnegative). */ +#define JAS_MOD(x, y) \ + (((x) < 0) ? (((-x) % (y)) ? ((y) - ((-(x)) % (y))) : (0)) : ((x) % (y))) + +/* Compute the integer with the specified number of least significant bits + set to one. */ +#define JAS_ONES(n) \ + ((1 << (n)) - 1) + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_seq.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_seq.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_seq.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_seq.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,301 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Sequence/Matrix Library + * + * $Id: jas_seq.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_SEQ_H +#define JAS_SEQ_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* This matrix is a reference to another matrix. */ +#define JAS_MATRIX_REF 0x0001 + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* An element in a sequence. */ +typedef int_fast32_t jas_seqent_t; + +/* An element in a matrix. */ +typedef int_fast32_t jas_matent_t; + +/* Matrix. */ + +typedef struct { + + /* Additional state information. */ + int flags_; + + /* The starting horizontal index. */ + int_fast32_t xstart_; + + /* The starting vertical index. */ + int_fast32_t ystart_; + + /* The ending horizontal index. */ + int_fast32_t xend_; + + /* The ending vertical index. */ + int_fast32_t yend_; + + /* The number of rows in the matrix. */ + int_fast32_t numrows_; + + /* The number of columns in the matrix. */ + int_fast32_t numcols_; + + /* Pointers to the start of each row. */ + jas_seqent_t **rows_; + + /* The allocated size of the rows array. */ + int_fast32_t maxrows_; + + /* The matrix data buffer. */ + jas_seqent_t *data_; + + /* The allocated size of the data array. */ + int_fast32_t datasize_; + +} jas_matrix_t; + +typedef jas_matrix_t jas_seq2d_t; +typedef jas_matrix_t jas_seq_t; + +/******************************************************************************\ +* Functions/macros for matrix class. +\******************************************************************************/ + +/* Get the number of rows. */ +#define jas_matrix_numrows(matrix) \ + ((matrix)->numrows_) + +/* Get the number of columns. */ +#define jas_matrix_numcols(matrix) \ + ((matrix)->numcols_) + +/* Get a matrix element. */ +#define jas_matrix_get(matrix, i, j) \ + ((matrix)->rows_[i][j]) + +/* Set a matrix element. */ +#define jas_matrix_set(matrix, i, j, v) \ + ((matrix)->rows_[i][j] = (v)) + +/* Get an element from a matrix that is known to be a row or column vector. */ +#define jas_matrix_getv(matrix, i) \ + (((matrix)->numrows_ == 1) ? ((matrix)->rows_[0][i]) : \ + ((matrix)->rows_[i][0])) + +/* Set an element in a matrix that is known to be a row or column vector. */ +#define jas_matrix_setv(matrix, i, v) \ + (((matrix)->numrows_ == 1) ? ((matrix)->rows_[0][i] = (v)) : \ + ((matrix)->rows_[i][0] = (v))) + +/* Get the address of an element in a matrix. */ +#define jas_matrix_getref(matrix, i, j) \ + (&(matrix)->rows_[i][j]) + +#define jas_matrix_getvref(matrix, i) \ + (((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : jas_matrix_getref(matrix, 0, i)) + +#define jas_matrix_length(matrix) \ + (max((matrix)->numrows_, (matrix)->numcols_)) + +/* Create a matrix with the specified dimensions. */ +jas_matrix_t *jas_matrix_create(int numrows, int numcols); + +/* Destroy a matrix. */ +void jas_matrix_destroy(jas_matrix_t *matrix); + +/* Resize a matrix. The previous contents of the matrix are lost. */ +int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols); + +int jas_matrix_output(jas_matrix_t *matrix, FILE *out); + +/* Create a matrix that references part of another matrix. */ +void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0, int c0, + int r1, int c1); + +/* Create a matrix that is a reference to a row of another matrix. */ +#define jas_matrix_bindrow(mat0, mat1, r) \ + (jas_matrix_bindsub((mat0), (mat1), (r), 0, (r), (mat1)->numcols_ - 1)) + +/* Create a matrix that is a reference to a column of another matrix. */ +#define jas_matrix_bindcol(mat0, mat1, c) \ + (jas_matrix_bindsub((mat0), (mat1), 0, (c), (mat1)->numrows_ - 1, (c))) + +/* Clip the values of matrix elements to the specified range. */ +void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval, + jas_seqent_t maxval); + +/* Arithmetic shift left of all elements in a matrix. */ +void jas_matrix_asl(jas_matrix_t *matrix, int n); + +/* Arithmetic shift right of all elements in a matrix. */ +void jas_matrix_asr(jas_matrix_t *matrix, int n); + +/* Almost-but-not-quite arithmetic shift right of all elements in a matrix. */ +void jas_matrix_divpow2(jas_matrix_t *matrix, int n); + +/* Set all elements of a matrix to the specified value. */ +void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val); + +/* The spacing between rows of a matrix. */ +#define jas_matrix_rowstep(matrix) \ + (((matrix)->numrows_ > 1) ? ((matrix)->rows_[1] - (matrix)->rows_[0]) : (0)) + +/* The spacing between columns of a matrix. */ +#define jas_matrix_step(matrix) \ + (((matrix)->numrows_ > 1) ? (jas_matrix_rowstep(matrix)) : (1)) + +/* Compare two matrices for equality. */ +int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1); + +jas_matrix_t *jas_matrix_copy(jas_matrix_t *x); + +jas_matrix_t *jas_matrix_input(FILE *); + +/******************************************************************************\ +* Functions/macros for 2-D sequence class. +\******************************************************************************/ + +jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x); + +jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend); + +#define jas_seq2d_destroy(s) \ + jas_matrix_destroy(s) + +#define jas_seq2d_xstart(s) \ + ((s)->xstart_) +#define jas_seq2d_ystart(s) \ + ((s)->ystart_) +#define jas_seq2d_xend(s) \ + ((s)->xend_) +#define jas_seq2d_yend(s) \ + ((s)->yend_) +#define jas_seq2d_getref(s, x, y) \ + (jas_matrix_getref(s, (y) - (s)->ystart_, (x) - (s)->xstart_)) +#define jas_seq2d_get(s, x, y) \ + (jas_matrix_get(s, (y) - (s)->ystart_, (x) - (s)->xstart_)) +#define jas_seq2d_rowstep(s) \ + jas_matrix_rowstep(s) +#define jas_seq2d_width(s) \ + ((s)->xend_ - (s)->xstart_) +#define jas_seq2d_height(s) \ + ((s)->yend_ - (s)->ystart_) +#define jas_seq2d_setshift(s, x, y) \ + ((s)->xstart_ = (x), (s)->ystart_ = (y), \ + (s)->xend_ = (s)->xstart_ + (s)->numcols_, \ + (s)->yend_ = (s)->ystart_ + (s)->numrows_) + +void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart, + int ystart, int xend, int yend); + +/******************************************************************************\ +* Functions/macros for 1-D sequence class. +\******************************************************************************/ + +#define jas_seq_create(start, end) \ + (jas_seq2d_create(start, 0, end, 1)) + +#define jas_seq_destroy(seq) \ + (jas_seq2d_destroy(seq)) + +#define jas_seq_set(seq, i, v) \ + ((seq)->rows_[0][(i) - (seq)->xstart_] = (v)) +#define jas_seq_getref(seq, i) \ + (&(seq)->rows_[0][(i) - (seq)->xstart_]) +#define jas_seq_get(seq, i) \ + ((seq)->rows_[0][(i) - (seq)->xstart_]) +#define jas_seq_start(seq) \ + ((seq)->xstart_) +#define jas_seq_end(seq) \ + ((seq)->xend_) + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_stream.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_stream.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_stream.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_stream.h 2013-05-05 17:22:52.000000000 +0000 @@ -0,0 +1,469 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * I/O Stream Class + * + * $Id: jas_stream.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_STREAM_H +#define JAS_STREAM_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include +#include +#if defined(HAVE_FCNTL_H) +#include +#endif +#include +#if defined(HAVE_UNISTD_H) +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* On most UNIX systems, we probably need to define O_BINARY ourselves. */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* + * Stream open flags. + */ + +/* The stream was opened for reading. */ +#define JAS_STREAM_READ 0x0001 +/* The stream was opened for writing. */ +#define JAS_STREAM_WRITE 0x0002 +/* The stream was opened for appending. */ +#define JAS_STREAM_APPEND 0x0004 +/* The stream was opened in binary mode. */ +#define JAS_STREAM_BINARY 0x0008 +/* The stream should be created/truncated. */ +#define JAS_STREAM_CREATE 0x0010 + + +/* + * Stream buffering flags. + */ + +/* The stream is unbuffered. */ +#define JAS_STREAM_UNBUF 0x0000 +/* The stream is line buffered. */ +#define JAS_STREAM_LINEBUF 0x0001 +/* The stream is fully buffered. */ +#define JAS_STREAM_FULLBUF 0x0002 +/* The buffering mode mask. */ +#define JAS_STREAM_BUFMODEMASK 0x000f + +/* The memory associated with the buffer needs to be deallocated when the + stream is destroyed. */ +#define JAS_STREAM_FREEBUF 0x0008 +/* The buffer is currently being used for reading. */ +#define JAS_STREAM_RDBUF 0x0010 +/* The buffer is currently being used for writing. */ +#define JAS_STREAM_WRBUF 0x0020 + +/* + * Stream error flags. + */ + +/* The end-of-file has been encountered (on reading). */ +#define JAS_STREAM_EOF 0x0001 +/* An I/O error has been encountered on the stream. */ +#define JAS_STREAM_ERR 0x0002 +/* The read/write limit has been exceeded. */ +#define JAS_STREAM_RWLIMIT 0x0004 +/* The error mask. */ +#define JAS_STREAM_ERRMASK \ + (JAS_STREAM_EOF | JAS_STREAM_ERR | JAS_STREAM_RWLIMIT) + +/* + * Other miscellaneous constants. + */ + +/* The default buffer size (for fully-buffered operation). */ +#define JAS_STREAM_BUFSIZE 8192 +/* The default permission mask for file creation. */ +#define JAS_STREAM_PERMS 0666 + +/* The maximum number of characters that can always be put back on a stream. */ +#define JAS_STREAM_MAXPUTBACK 16 + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* + * Generic file object. + */ + +typedef void jas_stream_obj_t; + +/* + * Generic file object operations. + */ + +typedef struct { + + /* Read characters from a file object. */ + int (*read_)(jas_stream_obj_t *obj, char *buf, int cnt); + + /* Write characters to a file object. */ + int (*write_)(jas_stream_obj_t *obj, char *buf, int cnt); + + /* Set the position for a file object. */ + long (*seek_)(jas_stream_obj_t *obj, long offset, int origin); + + /* Close a file object. */ + int (*close_)(jas_stream_obj_t *obj); + +} jas_stream_ops_t; + +/* + * Stream object. + */ + +typedef struct { + + /* The mode in which the stream was opened. */ + int openmode_; + + /* The buffering mode. */ + int bufmode_; + + /* The stream status. */ + int flags_; + + /* The start of the buffer area to use for reading/writing. */ + uchar *bufbase_; + + /* The start of the buffer area excluding the extra initial space for + character putback. */ + uchar *bufstart_; + + /* The buffer size. */ + int bufsize_; + + /* The current position in the buffer. */ + uchar *ptr_; + + /* The number of characters that must be read/written before + the buffer needs to be filled/flushed. */ + int cnt_; + + /* A trivial buffer to be used for unbuffered operation. */ + uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1]; + + /* The operations for the underlying stream file object. */ + jas_stream_ops_t *ops_; + + /* The underlying stream file object. */ + jas_stream_obj_t *obj_; + + /* The number of characters read/written. */ + long rwcnt_; + + /* The maximum number of characters that may be read/written. */ + long rwlimit_; + +} jas_stream_t; + +/* + * Regular file object. + */ + +/* + * File descriptor file object. + */ +typedef struct { + int fd; + int flags; +#if defined _WIN32 && !defined __MINGW__ && !defined __MINGW32__ + char pathname[256 + 1]; +#else + char pathname[PATH_MAX + 1]; +#endif +} jas_stream_fileobj_t; + +#define JAS_STREAM_FILEOBJ_DELONCLOSE 0x01 +#define JAS_STREAM_FILEOBJ_NOCLOSE 0x02 + +/* + * Memory file object. + */ + +typedef struct { + + /* The data associated with this file. */ + uchar *buf_; + + /* The allocated size of the buffer for holding file data. */ + int bufsize_; + + /* The length of the file. */ + int_fast32_t len_; + + /* The seek position. */ + int_fast32_t pos_; + + /* Is the buffer growable? */ + int growable_; + + /* Was the buffer allocated internally? */ + int myalloc_; + +} jas_stream_memobj_t; + +/******************************************************************************\ +* Macros/functions for opening and closing streams. +\******************************************************************************/ + +/* Open a file as a stream. */ +jas_stream_t *jas_stream_fopen(const char *filename, const char *mode); + +/* Open a memory buffer as a stream. */ +jas_stream_t *jas_stream_memopen(char *buf, int bufsize); + +/* Open a file descriptor as a stream. */ +jas_stream_t *jas_stream_fdopen(int fd, const char *mode); + +/* Open a stdio stream as a stream. */ +jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp); + +/* Open a temporary file as a stream. */ +jas_stream_t *jas_stream_tmpfile(void); + +/* Close a stream. */ +int jas_stream_close(jas_stream_t *stream); + +/******************************************************************************\ +* Macros/functions for getting/setting the stream state. +\******************************************************************************/ + +/* Get the EOF indicator for a stream. */ +#define jas_stream_eof(stream) \ + (((stream)->flags_ & JAS_STREAM_EOF) != 0) + +/* Get the error indicator for a stream. */ +#define jas_stream_error(stream) \ + (((stream)->flags_ & JAS_STREAM_ERR) != 0) + +/* Clear the error indicator for a stream. */ +#define jas_stream_clearerr(stream) \ + ((stream)->flags_ &= ~(JAS_STREAM_ERR | JAS_STREAM_EOF)) + +/* Get the read/write limit for a stream. */ +#define jas_stream_getrwlimit(stream) \ + (((const jas_stream_t *)(stream))->rwlimit_) + +/* Set the read/write limit for a stream. */ +int jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit); + +/* Get the read/write count for a stream. */ +#define jas_stream_getrwcount(stream) \ + (((const jas_stream_t *)(stream))->rwcnt_) + +/* Set the read/write count for a stream. */ +long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt); + +/******************************************************************************\ +* Macros/functions for I/O. +\******************************************************************************/ + +/* Read a character from a stream. */ +#if defined(DEBUG) +#define jas_stream_getc(stream) jas_stream_getc_func(stream) +#else +#define jas_stream_getc(stream) jas_stream_getc_macro(stream) +#endif + +/* Write a character to a stream. */ +#if defined(DEBUG) +#define jas_stream_putc(stream, c) jas_stream_putc_func(stream, c) +#else +#define jas_stream_putc(stream, c) jas_stream_putc_macro(stream, c) +#endif + +/* Read characters from a stream into a buffer. */ +int jas_stream_read(jas_stream_t *stream, void *buf, int cnt); + +/* Write characters from a buffer to a stream. */ +int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt); + +/* Write formatted output to a stream. */ +int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...); + +/* Write a string to a stream. */ +int jas_stream_puts(jas_stream_t *stream, const char *s); + +/* Read a line of input from a stream. */ +char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize); + +/* Look at the next character to be read from a stream without actually + removing it from the stream. */ +#define jas_stream_peekc(stream) \ + (((stream)->cnt_ <= 0) ? jas_stream_fillbuf(stream, 0) : \ + ((int)(*(stream)->ptr_))) + +/* Put a character back on a stream. */ +int jas_stream_ungetc(jas_stream_t *stream, int c); + +/******************************************************************************\ +* Macros/functions for getting/setting the stream position. +\******************************************************************************/ + +/* Is it possible to seek on this stream? */ +int jas_stream_isseekable(jas_stream_t *stream); + +/* Set the current position within the stream. */ +long jas_stream_seek(jas_stream_t *stream, long offset, int origin); + +/* Get the current position within the stream. */ +long jas_stream_tell(jas_stream_t *stream); + +/* Seek to the beginning of a stream. */ +int jas_stream_rewind(jas_stream_t *stream); + +/******************************************************************************\ +* Macros/functions for flushing. +\******************************************************************************/ + +/* Flush any pending output to a stream. */ +int jas_stream_flush(jas_stream_t *stream); + +/******************************************************************************\ +* Miscellaneous macros/functions. +\******************************************************************************/ + +/* Copy data from one stream to another. */ +int jas_stream_copy(jas_stream_t *dst, jas_stream_t *src, int n); + +/* Display stream contents (for debugging purposes). */ +int jas_stream_display(jas_stream_t *stream, FILE *fp, int n); + +/* Consume (i.e., discard) characters from stream. */ +int jas_stream_gobble(jas_stream_t *stream, int n); + +/* Write a character multiple times to a stream. */ +int jas_stream_pad(jas_stream_t *stream, int n, int c); + +/* Get the size of the file associated with the specified stream. + The specified stream must be seekable. */ +long jas_stream_length(jas_stream_t *stream); + +/******************************************************************************\ +* Internal functions. +\******************************************************************************/ + +/* The following functions are for internal use only! If you call them +directly, you will die a horrible, miserable, and painful death! */ + +/* Read a character from a stream. */ +#define jas_stream_getc_macro(stream) \ + ((!((stream)->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | \ + JAS_STREAM_RWLIMIT))) ? \ + (((stream)->rwlimit_ >= 0 && (stream)->rwcnt_ >= (stream)->rwlimit_) ? \ + (stream->flags_ |= JAS_STREAM_RWLIMIT, EOF) : \ + jas_stream_getc2(stream)) : EOF) +#define jas_stream_getc2(stream) \ + ((--(stream)->cnt_ < 0) ? jas_stream_fillbuf(stream, 1) : \ + (++(stream)->rwcnt_, (int)(*(stream)->ptr_++))) + +/* Write a character to a stream. */ +#define jas_stream_putc_macro(stream, c) \ + ((!((stream)->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | \ + JAS_STREAM_RWLIMIT))) ? \ + (((stream)->rwlimit_ >= 0 && (stream)->rwcnt_ >= (stream)->rwlimit_) ? \ + (stream->flags_ |= JAS_STREAM_RWLIMIT, EOF) : \ + jas_stream_putc2(stream, c)) : EOF) +#define jas_stream_putc2(stream, c) \ + (((stream)->bufmode_ |= JAS_STREAM_WRBUF, --(stream)->cnt_ < 0) ? \ + jas_stream_flushbuf((stream), (uchar)(c)) : \ + (++(stream)->rwcnt_, (int)(*(stream)->ptr_++ = (c)))) + +/* These prototypes need to be here for the sake of the stream_getc and +stream_putc macros. */ +int jas_stream_fillbuf(jas_stream_t *stream, int getflag); +int jas_stream_flushbuf(jas_stream_t *stream, int c); +int jas_stream_getc_func(jas_stream_t *stream); +int jas_stream_putc_func(jas_stream_t *stream, int c); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_string.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_string.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_string.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_string.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * String Library + * + * $Id: jas_string.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_STRING_H +#define JAS_STRING_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Copy a string (a la strdup). */ +char *jas_strdup(const char *); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tmr.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tmr.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tmr.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tmr.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JAS_TMR_H +#define JAS_TMR_H + +#include +#include +#if defined(HAVE_SYS_TIME_H) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(HAVE_GETTIMEOFDAY) + +typedef struct { + struct timeval start; + struct timeval stop; +} jas_tmr_t; + +#elif defined(HAVE_GETRUSAGE) + +typedef struct { + struct rusage start; + struct rusage stop; +} jas_tmr_t; + +#else + +typedef int jas_tmr_t; + +#endif + +void jas_tmr_start(jas_tmr_t *tmr); +void jas_tmr_stop(jas_tmr_t *tmr); +double jas_tmr_get(jas_tmr_t *tmr); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tvp.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tvp.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tvp.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_tvp.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tag/Value Parser + * + * $Id: jas_tvp.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_TVP_H +#define JAS_TVP_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* Tag information type. */ + +typedef struct { + + int id; + /* The ID for the tag. */ + + char *name; + /* The name of the tag. */ + +} jas_taginfo_t; + +/* Tag-value parser type. */ + +typedef struct { + + char *buf; + /* The parsing buffer. */ + + char *tag; + /* The current tag name. */ + + char *val; + /* The current value. */ + + char *pos; + /* The current position in the parsing buffer. */ + +} jas_tvparser_t; + +/******************************************************************************\ +* Tag information functions. +\******************************************************************************/ + +/* Lookup a tag by name. */ +jas_taginfo_t *jas_taginfos_lookup(jas_taginfo_t *taginfos, const char *name); + +/* This function returns a pointer to the specified taginfo object if it + exists (i.e., the pointer is nonnull); otherwise, a pointer to a dummy + object is returned. This is useful in some situations to avoid checking + for a null pointer. */ +jas_taginfo_t *jas_taginfo_nonull(jas_taginfo_t *taginfo); + +/******************************************************************************\ +* Tag-value parser functions. +\******************************************************************************/ + +/* Create a tag-value parser for the specified string. */ +jas_tvparser_t *jas_tvparser_create(const char *s); + +/* Destroy a tag-value parser. */ +void jas_tvparser_destroy(jas_tvparser_t *tvparser); + +/* Get the next tag-value pair. */ +int jas_tvparser_next(jas_tvparser_t *tvparser); + +/* Get the tag name for the current tag-value pair. */ +char *jas_tvparser_gettag(jas_tvparser_t *tvparser); + +/* Get the value for the current tag-value pair. */ +char *jas_tvparser_getval(jas_tvparser_t *tvparser); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_types.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_types.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_types.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_types.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,228 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Primitive Types + * + * $Id: jas_types.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_TYPES_H +#define JAS_TYPES_H + +#include + +#if !defined(JAS_CONFIGURE) + +#if defined(WIN32) || defined(HAVE_WINDOWS_H) +/* + We are dealing with Microsoft Windows and most likely Microsoft + Visual C (MSVC). (Heaven help us.) Sadly, MSVC does not correctly + define some of the standard types specified in ISO/IEC 9899:1999. + In particular, it does not define the "long long" and "unsigned long + long" types. So, we work around this problem by using the "INT64" + and "UINT64" types that are defined in the header file "windows.h". + */ +#include +#undef longlong +#define longlong INT64 +#undef ulonglong +#define ulonglong UINT64 +#endif + +#endif + +#if defined(HAVE_STDLIB_H) +#undef false +#undef true +#include +#endif +#if defined(HAVE_STDDEF_H) +#include +#endif +#if defined(HAVE_SYS_TYPES_H) +#include +#endif + +#ifndef __cplusplus +#if defined(HAVE_STDBOOL_H) +/* + * The C language implementation does correctly provide the standard header + * file "stdbool.h". + */ +#include +#else + +/* + * The C language implementation does not provide the standard header file + * "stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this + * braindamage below. + */ +#if !defined(bool) +#define bool int +#endif +#if !defined(true) +#define true 1 +#endif +#if !defined(false) +#define false 0 +#endif +#endif + +#endif + +#if defined(HAVE_STDINT_H) +/* + * The C language implementation does correctly provide the standard header + * file "stdint.h". + */ +#include +#else +/* + * The C language implementation does not provide the standard header file + * "stdint.h" as required by ISO/IEC 9899:1999. Try to compensate for this + * braindamage below. + */ +#include +/**********/ +#if !defined(INT_FAST8_MIN) +typedef signed char int_fast8_t; +#define INT_FAST8_MIN (-127) +#define INT_FAST8_MAX 128 +#endif +/**********/ +#if !defined(UINT_FAST8_MAX) +typedef unsigned char uint_fast8_t; +#define UINT_FAST8_MAX 255 +#endif +/**********/ +#if !defined(INT_FAST16_MIN) +typedef short int_fast16_t; +#define INT_FAST16_MIN SHRT_MIN +#define INT_FAST16_MAX SHRT_MAX +#endif +/**********/ +#if !defined(UINT_FAST16_MAX) +typedef unsigned short uint_fast16_t; +#define UINT_FAST16_MAX USHRT_MAX +#endif +/**********/ +#if !defined(INT_FAST32_MIN) +typedef int int_fast32_t; +#define INT_FAST32_MIN INT_MIN +#define INT_FAST32_MAX INT_MAX +#endif +/**********/ +#if !defined(UINT_FAST32_MAX) +typedef unsigned int uint_fast32_t; +#define UINT_FAST32_MAX UINT_MAX +#endif +/**********/ +#if !defined(INT_FAST64_MIN) +typedef longlong int_fast64_t; +#define INT_FAST64_MIN LLONG_MIN +#define INT_FAST64_MAX LLONG_MAX +#endif +/**********/ +#if !defined(UINT_FAST64_MAX) +typedef ulonglong uint_fast64_t; +#define UINT_FAST64_MAX ULLONG_MAX +#endif +/**********/ +#endif + +/* Hopefully, these macro definitions will fix more problems than they cause. */ +#if !defined(uchar) +#define uchar unsigned char +#endif +#if !defined(ushort) +#define ushort unsigned short +#endif +#if !defined(uint) +#define uint unsigned int +#endif +#if !defined(ulong) +#define ulong unsigned long +#endif +#if !defined(longlong) +#define longlong long long +#endif +#if !defined(ulonglong) +#define ulonglong unsigned long long +#endif + +/* The below macro is intended to be used for type casts. By using this + macro, type casts can be easily located in the source code with + tools like "grep". */ +#define JAS_CAST(t, e) \ + ((t) (e)) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_version.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_version.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_version.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jas_version.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jas_version.h,v 1.2 2008-05-26 09:41:51 vp153 Exp $ + */ + +#ifndef JAS_VERSION_H +#define JAS_VERSION_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************\ +* Constants and types. +\******************************************************************************/ + +#if !defined(JAS_VERSION) +/* The version information below should match that specified in + the "configure.in" file! */ +#define JAS_VERSION "unknown" +#endif + +#define JAS_COPYRIGHT \ + "Copyright (c) 2001-2006 Michael David Adams.\n" \ + "Copyright (c) 1999-2000 Image Power, Inc. and the University of\n" \ + " British Columbia.\n" \ + "All rights reserved.\n" + +#define JAS_NOTES \ + "For more information about this software, please visit the following\n" \ + "web sites/pages:\n" \ + " http://www.ece.uvic.ca/~mdadams/jasper\n" \ + " http://www.jpeg.org/software\n" \ + "To be added to the (moderated) JasPer software announcements\n" \ + "mailing list, send an email to:\n" \ + " jasper-announce-subscribe@yahoogroups.com\n" \ + "To be added to the (unmoderated) JasPer software discussion\n" \ + "mailing list, send an email to:\n" \ + " jasper-discussion-subscribe@yahoogroups.com\n" \ + "Please send any bug reports to:\n" \ + " mdadams@ieee.org\n" + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +const char *jas_getversion(void); +/* Get the version information for the JasPer library. */ +/* Note: Since libjasper can be built as a shared library, the version + returned by this function may not necessarily correspond to JAS_VERSION. */ + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jasper.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jasper.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jasper/jasper.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jasper/jasper.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JAS_JASPER_H +#define JAS_JASPER_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,979 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* + * Modified by Andrey Kiselev to handle UUID + * box properly. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JP2 Library + * + * $Id: jp2_cod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +#include "jasper/jas_stream.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_debug.h" + +#include "jp2_cod.h" + +/******************************************************************************\ +* Function prototypes. +\******************************************************************************/ + +#define ONES(n) ((1 << (n)) - 1) + +jp2_boxinfo_t *jp2_boxinfolookup(int type); + +static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val); +static int jp2_getuint16(jas_stream_t *in, uint_fast16_t *val); +static int jp2_getuint32(jas_stream_t *in, uint_fast32_t *val); +static int jp2_getuint64(jas_stream_t *in, uint_fast64_t *val); +static int jp2_putuint8(jas_stream_t *out, uint_fast8_t val); +static int jp2_putuint16(jas_stream_t *out, uint_fast16_t val); +static int jp2_putuint32(jas_stream_t *out, uint_fast32_t val); +static int jp2_putuint64(jas_stream_t *out, uint_fast64_t val); + +static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val); + +jp2_box_t *jp2_box_get(jas_stream_t *in); +void jp2_box_dump(jp2_box_t *box, FILE *out); + +static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_jp_putdata(jp2_box_t *box, jas_stream_t *out); +static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_ftyp_putdata(jp2_box_t *box, jas_stream_t *out); +static int jp2_ihdr_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_ihdr_putdata(jp2_box_t *box, jas_stream_t *out); +static void jp2_bpcc_destroy(jp2_box_t *box); +static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_bpcc_putdata(jp2_box_t *box, jas_stream_t *out); +static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_colr_putdata(jp2_box_t *box, jas_stream_t *out); +static void jp2_colr_dumpdata(jp2_box_t *box, FILE *out); +static void jp2_colr_destroy(jp2_box_t *box); +static void jp2_cdef_destroy(jp2_box_t *box); +static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_cdef_putdata(jp2_box_t *box, jas_stream_t *out); +static void jp2_cdef_dumpdata(jp2_box_t *box, FILE *out); +static void jp2_cmap_destroy(jp2_box_t *box); +static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_cmap_putdata(jp2_box_t *box, jas_stream_t *out); +static void jp2_cmap_dumpdata(jp2_box_t *box, FILE *out); +static void jp2_pclr_destroy(jp2_box_t *box); +static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_pclr_putdata(jp2_box_t *box, jas_stream_t *out); +static void jp2_pclr_dumpdata(jp2_box_t *box, FILE *out); +static void jp2_uuid_destroy(jp2_box_t *box); +static int jp2_uuid_getdata(jp2_box_t *box, jas_stream_t *in); +static int jp2_uuid_putdata(jp2_box_t *box, jas_stream_t *out); + +/******************************************************************************\ +* Local data. +\******************************************************************************/ + +jp2_boxinfo_t jp2_boxinfos[] = { + {JP2_BOX_JP, "JP", 0, + {0, 0, jp2_jp_getdata, jp2_jp_putdata, 0}}, + {JP2_BOX_FTYP, "FTYP", 0, + {0, 0, jp2_ftyp_getdata, jp2_ftyp_putdata, 0}}, + {JP2_BOX_JP2H, "JP2H", JP2_BOX_SUPER, + {0, 0, 0, 0, 0}}, + {JP2_BOX_IHDR, "IHDR", 0, + {0, 0, jp2_ihdr_getdata, jp2_ihdr_putdata, 0}}, + {JP2_BOX_BPCC, "BPCC", 0, + {0, jp2_bpcc_destroy, jp2_bpcc_getdata, jp2_bpcc_putdata, 0}}, + {JP2_BOX_COLR, "COLR", 0, + {0, jp2_colr_destroy, jp2_colr_getdata, jp2_colr_putdata, jp2_colr_dumpdata}}, + {JP2_BOX_PCLR, "PCLR", 0, + {0, jp2_pclr_destroy, jp2_pclr_getdata, jp2_pclr_putdata, jp2_pclr_dumpdata}}, + {JP2_BOX_CMAP, "CMAP", 0, + {0, jp2_cmap_destroy, jp2_cmap_getdata, jp2_cmap_putdata, jp2_cmap_dumpdata}}, + {JP2_BOX_CDEF, "CDEF", 0, + {0, jp2_cdef_destroy, jp2_cdef_getdata, jp2_cdef_putdata, jp2_cdef_dumpdata}}, + {JP2_BOX_RES, "RES", JP2_BOX_SUPER, + {0, 0, 0, 0, 0}}, + {JP2_BOX_RESC, "RESC", 0, + {0, 0, 0, 0, 0}}, + {JP2_BOX_RESD, "RESD", 0, + {0, 0, 0, 0, 0}}, + {JP2_BOX_JP2C, "JP2C", JP2_BOX_NODATA, + {0, 0, 0, 0, 0}}, + {JP2_BOX_JP2I, "JP2I", 0, + {0, 0, 0, 0, 0}}, + {JP2_BOX_XML, "XML", 0, + {0, 0, 0, 0, 0}}, + {JP2_BOX_UUID, "UUID", 0, + {0, jp2_uuid_destroy, jp2_uuid_getdata, jp2_uuid_putdata, 0}}, + {JP2_BOX_UINF, "UINF", JP2_BOX_SUPER, + {0, 0, 0, 0, 0}}, + {JP2_BOX_ULST, "ULST", 0, + {0, 0, 0, 0, 0}}, + {JP2_BOX_URL, "URL", 0, + {0, 0, 0, 0, 0}}, + {0, 0, 0, {0, 0, 0, 0, 0}}, +}; + +jp2_boxinfo_t jp2_boxinfo_unk = { + 0, "Unknown", 0, {0, 0, 0, 0, 0} +}; + +/******************************************************************************\ +* Box constructor. +\******************************************************************************/ + +jp2_box_t *jp2_box_create(int type) +{ + jp2_box_t *box; + jp2_boxinfo_t *boxinfo; + + if (!(box = jas_malloc(sizeof(jp2_box_t)))) { + return 0; + } + memset(box, 0, sizeof(jp2_box_t)); + box->type = type; + box->len = 0; + if (!(boxinfo = jp2_boxinfolookup(type))) { + return 0; + } + box->info = boxinfo; + box->ops = &boxinfo->ops; + return box; +} + +/******************************************************************************\ +* Box destructor. +\******************************************************************************/ + +void jp2_box_destroy(jp2_box_t *box) +{ + if (box->ops->destroy) { + (*box->ops->destroy)(box); + } + jas_free(box); +} + +static void jp2_bpcc_destroy(jp2_box_t *box) +{ + jp2_bpcc_t *bpcc = &box->data.bpcc; + if (bpcc->bpcs) { + jas_free(bpcc->bpcs); + bpcc->bpcs = 0; + } +} + +static void jp2_cdef_destroy(jp2_box_t *box) +{ + jp2_cdef_t *cdef = &box->data.cdef; + if (cdef->ents) { + jas_free(cdef->ents); + cdef->ents = 0; + } +} + +/******************************************************************************\ +* Box input. +\******************************************************************************/ + +jp2_box_t *jp2_box_get(jas_stream_t *in) +{ + jp2_box_t *box; + jp2_boxinfo_t *boxinfo; + jas_stream_t *tmpstream; + uint_fast32_t len; + uint_fast64_t extlen; + bool dataflag; + + box = 0; + tmpstream = 0; + + if (!(box = jas_malloc(sizeof(jp2_box_t)))) { + goto error; + } + box->ops = &jp2_boxinfo_unk.ops; + if (jp2_getuint32(in, &len) || jp2_getuint32(in, &box->type)) { + goto error; + } + boxinfo = jp2_boxinfolookup(box->type); + box->info = boxinfo; + box->ops = &boxinfo->ops; + box->len = len; + if (box->len == 1) { + if (jp2_getuint64(in, &extlen)) { + goto error; + } + if (extlen > 0xffffffffUL) { + jas_eprintf("warning: cannot handle large 64-bit box length\n"); + extlen = 0xffffffffUL; + } + box->len = extlen; + box->datalen = extlen - JP2_BOX_HDRLEN(true); + } else { + box->datalen = box->len - JP2_BOX_HDRLEN(false); + } + if (box->len != 0 && box->len < 8) { + goto error; + } + + dataflag = !(box->info->flags & (JP2_BOX_SUPER | JP2_BOX_NODATA)); + + if (dataflag) { + if (!(tmpstream = jas_stream_memopen(0, 0))) { + goto error; + } + if (jas_stream_copy(tmpstream, in, box->datalen)) { + jas_eprintf("cannot copy box data\n"); + goto error; + } + jas_stream_rewind(tmpstream); + + if (box->ops->getdata) { + if ((*box->ops->getdata)(box, tmpstream)) { + jas_eprintf("cannot parse box data\n"); + goto error; + } + } + jas_stream_close(tmpstream); + } + + if (jas_getdbglevel() >= 1) { + jp2_box_dump(box, stderr); + } + + return box; + abort(); + +error: + if (box) { + jp2_box_destroy(box); + } + if (tmpstream) { + jas_stream_close(tmpstream); + } + return 0; +} + +void jp2_box_dump(jp2_box_t *box, FILE *out) +{ + jp2_boxinfo_t *boxinfo; + boxinfo = jp2_boxinfolookup(box->type); + assert(boxinfo); + + fprintf(out, "JP2 box: "); + fprintf(out, "type=%c%s%c (0x%08x); length=%d\n", '"', boxinfo->name, + '"', (unsigned)box->type, (int)box->len); + if (box->ops->dumpdata) { + (*box->ops->dumpdata)(box, out); + } +} + +static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_jp_t *jp = &box->data.jp; + if (jp2_getuint32(in, &jp->magic)) { + return -1; + } + return 0; +} + +static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_ftyp_t *ftyp = &box->data.ftyp; + unsigned int i; + if (jp2_getuint32(in, &ftyp->majver) || jp2_getuint32(in, &ftyp->minver)) { + return -1; + } + ftyp->numcompatcodes = (box->datalen - 8) / 4; + if (ftyp->numcompatcodes > JP2_FTYP_MAXCOMPATCODES) { + return -1; + } + for (i = 0; i < ftyp->numcompatcodes; ++i) { + if (jp2_getuint32(in, &ftyp->compatcodes[i])) { + return -1; + } + } + return 0; +} + +static int jp2_ihdr_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_ihdr_t *ihdr = &box->data.ihdr; + if (jp2_getuint32(in, &ihdr->height) || jp2_getuint32(in, &ihdr->width) || + jp2_getuint16(in, &ihdr->numcmpts) || jp2_getuint8(in, &ihdr->bpc) || + jp2_getuint8(in, &ihdr->comptype) || jp2_getuint8(in, &ihdr->csunk) || + jp2_getuint8(in, &ihdr->ipr)) { + return -1; + } + return 0; +} + +static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_bpcc_t *bpcc = &box->data.bpcc; + unsigned int i; + bpcc->numcmpts = box->datalen; + if (!(bpcc->bpcs = jas_alloc2(bpcc->numcmpts, sizeof(uint_fast8_t)))) { + return -1; + } + for (i = 0; i < bpcc->numcmpts; ++i) { + if (jp2_getuint8(in, &bpcc->bpcs[i])) { + return -1; + } + } + return 0; +} + +static void jp2_colr_dumpdata(jp2_box_t *box, FILE *out) +{ + jp2_colr_t *colr = &box->data.colr; + fprintf(out, "method=%d; pri=%d; approx=%d\n", (int)colr->method, (int)colr->pri, (int)colr->approx); + switch (colr->method) { + case JP2_COLR_ENUM: + fprintf(out, "csid=%d\n", (int)colr->csid); + break; + case JP2_COLR_ICC: + jas_memdump(out, colr->iccp, colr->iccplen); + break; + } +} + +static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_colr_t *colr = &box->data.colr; + colr->csid = 0; + colr->iccp = 0; + colr->iccplen = 0; + + if (jp2_getuint8(in, &colr->method) || jp2_getuint8(in, &colr->pri) || + jp2_getuint8(in, &colr->approx)) { + return -1; + } + switch (colr->method) { + case JP2_COLR_ENUM: + if (jp2_getuint32(in, &colr->csid)) { + return -1; + } + break; + case JP2_COLR_ICC: + colr->iccplen = box->datalen - 3; + if (!(colr->iccp = jas_alloc2(colr->iccplen, sizeof(uint_fast8_t)))) { + return -1; + } + if (jas_stream_read(in, colr->iccp, colr->iccplen) != colr->iccplen) { + return -1; + } + break; + } + return 0; +} + +static void jp2_cdef_dumpdata(jp2_box_t *box, FILE *out) +{ + jp2_cdef_t *cdef = &box->data.cdef; + unsigned int i; + for (i = 0; i < cdef->numchans; ++i) { + fprintf(out, "channo=%d; type=%d; assoc=%d\n", + (int)cdef->ents[i].channo, (int)cdef->ents[i].type, (int)cdef->ents[i].assoc); + } +} + +static void jp2_colr_destroy(jp2_box_t *box) +{ + jp2_colr_t *colr = &box->data.colr; + if (colr->iccp) { + jas_free(colr->iccp); + } +} + +static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_cdef_t *cdef = &box->data.cdef; + jp2_cdefchan_t *chan; + unsigned int channo; + if (jp2_getuint16(in, &cdef->numchans)) { + return -1; + } + if (!(cdef->ents = jas_alloc2(cdef->numchans, sizeof(jp2_cdefchan_t)))) { + return -1; + } + for (channo = 0; channo < cdef->numchans; ++channo) { + chan = &cdef->ents[channo]; + if (jp2_getuint16(in, &chan->channo) || jp2_getuint16(in, &chan->type) || + jp2_getuint16(in, &chan->assoc)) { + return -1; + } + } + return 0; +} + +/******************************************************************************\ +* Box output. +\******************************************************************************/ + +int jp2_box_put(jp2_box_t *box, jas_stream_t *out) +{ + jas_stream_t *tmpstream; + bool extlen; + bool dataflag; + + tmpstream = 0; + + dataflag = !(box->info->flags & (JP2_BOX_SUPER | JP2_BOX_NODATA)); + + if (dataflag) { + tmpstream = jas_stream_memopen(0, 0); + if (box->ops->putdata) { + if ((*box->ops->putdata)(box, tmpstream)) { + goto error; + } + } + box->len = jas_stream_tell(tmpstream) + JP2_BOX_HDRLEN(false); + jas_stream_rewind(tmpstream); + } + //extlen = (box->len >= (((uint_fast64_t)1) << 32)) != 0; + if (jp2_putuint32(out, /*extlen ? 1 :*/ box->len)) { + goto error; + } + if (jp2_putuint32(out, box->type)) { + goto error; + } + /*if (extlen) { + if (jp2_putuint64(out, box->len)) { + goto error; + } + }*/ + + if (dataflag) { + if (jas_stream_copy(out, tmpstream, box->len - JP2_BOX_HDRLEN(false))) { + goto error; + } + jas_stream_close(tmpstream); + } + + return 0; + abort(); + +error: + + if (tmpstream) { + jas_stream_close(tmpstream); + } + return -1; +} + +static int jp2_jp_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_jp_t *jp = &box->data.jp; + if (jp2_putuint32(out, jp->magic)) { + return -1; + } + return 0; +} + +static int jp2_ftyp_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_ftyp_t *ftyp = &box->data.ftyp; + unsigned int i; + if (jp2_putuint32(out, ftyp->majver) || jp2_putuint32(out, ftyp->minver)) { + return -1; + } + for (i = 0; i < ftyp->numcompatcodes; ++i) { + if (jp2_putuint32(out, ftyp->compatcodes[i])) { + return -1; + } + } + return 0; +} + +static int jp2_ihdr_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_ihdr_t *ihdr = &box->data.ihdr; + if (jp2_putuint32(out, ihdr->height) || jp2_putuint32(out, ihdr->width) || + jp2_putuint16(out, ihdr->numcmpts) || jp2_putuint8(out, ihdr->bpc) || + jp2_putuint8(out, ihdr->comptype) || jp2_putuint8(out, ihdr->csunk) || + jp2_putuint8(out, ihdr->ipr)) { + return -1; + } + return 0; +} + +static int jp2_bpcc_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_bpcc_t *bpcc = &box->data.bpcc; + unsigned int i; + for (i = 0; i < bpcc->numcmpts; ++i) { + if (jp2_putuint8(out, bpcc->bpcs[i])) { + return -1; + } + } + return 0; +} + +static int jp2_colr_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_colr_t *colr = &box->data.colr; + if (jp2_putuint8(out, colr->method) || jp2_putuint8(out, colr->pri) || + jp2_putuint8(out, colr->approx)) { + return -1; + } + switch (colr->method) { + case JP2_COLR_ENUM: + if (jp2_putuint32(out, colr->csid)) { + return -1; + } + break; + case JP2_COLR_ICC: + if (jas_stream_write(out, colr->iccp, + JAS_CAST(int, colr->iccplen)) != JAS_CAST(int, colr->iccplen)) + return -1; + break; + } + return 0; +} + +static int jp2_cdef_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_cdef_t *cdef = &box->data.cdef; + unsigned int i; + jp2_cdefchan_t *ent; + + if (jp2_putuint16(out, cdef->numchans)) { + return -1; + } + + for (i = 0; i < cdef->numchans; ++i) { + ent = &cdef->ents[i]; + if (jp2_putuint16(out, ent->channo) || + jp2_putuint16(out, ent->type) || + jp2_putuint16(out, ent->assoc)) { + return -1; + } + } + return 0; +} + +/******************************************************************************\ +* Input operations for primitive types. +\******************************************************************************/ + +static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val) +{ + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + if (val) { + *val = c; + } + return 0; +} + +static int jp2_getuint16(jas_stream_t *in, uint_fast16_t *val) +{ + uint_fast16_t v; + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if (val) { + *val = v; + } + return 0; +} + +static int jp2_getuint32(jas_stream_t *in, uint_fast32_t *val) +{ + uint_fast32_t v; + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if (val) { + *val = v; + } + return 0; +} + +static int jp2_getuint64(jas_stream_t *in, uint_fast64_t *val) +{ + uint_fast64_t tmpval; + int i; + int c; + + tmpval = 0; + for (i = 0; i < 8; ++i) { + tmpval <<= 8; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + tmpval |= (c & 0xff); + } + *val = tmpval; + + return 0; +} + +/******************************************************************************\ +* Output operations for primitive types. +\******************************************************************************/ + +static int jp2_putuint8(jas_stream_t *out, uint_fast8_t val) +{ + if (jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +static int jp2_putuint16(jas_stream_t *out, uint_fast16_t val) +{ + if (jas_stream_putc(out, (val >> 8) & 0xff) == EOF || + jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +static int jp2_putuint32(jas_stream_t *out, uint_fast32_t val) +{ + if (jas_stream_putc(out, (val >> 24) & 0xff) == EOF || + jas_stream_putc(out, (val >> 16) & 0xff) == EOF || + jas_stream_putc(out, (val >> 8) & 0xff) == EOF || + jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +static int jp2_putuint64(jas_stream_t *out, uint_fast64_t val) +{ + if (jp2_putuint32(out, (val >> 32) & 0xffffffffUL) || + jp2_putuint32(out, val & 0xffffffffUL)) { + return -1; + } + return 0; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +jp2_boxinfo_t *jp2_boxinfolookup(int type) +{ + jp2_boxinfo_t *boxinfo; + for (boxinfo = jp2_boxinfos; boxinfo->name; ++boxinfo) { + if (boxinfo->type == type) { + return boxinfo; + } + } + return &jp2_boxinfo_unk; +} + + + + + +static void jp2_cmap_destroy(jp2_box_t *box) +{ + jp2_cmap_t *cmap = &box->data.cmap; + if (cmap->ents) { + jas_free(cmap->ents); + } +} + +static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_cmap_t *cmap = &box->data.cmap; + jp2_cmapent_t *ent; + unsigned int i; + + cmap->numchans = (box->datalen) / 4; + if (!(cmap->ents = jas_alloc2(cmap->numchans, sizeof(jp2_cmapent_t)))) { + return -1; + } + for (i = 0; i < cmap->numchans; ++i) { + ent = &cmap->ents[i]; + if (jp2_getuint16(in, &ent->cmptno) || + jp2_getuint8(in, &ent->map) || + jp2_getuint8(in, &ent->pcol)) { + return -1; + } + } + + return 0; +} + +static int jp2_cmap_putdata(jp2_box_t *box, jas_stream_t *out) +{ + /* Eliminate compiler warning about unused variables. */ + box = 0; + out = 0; + + return -1; +} + +static void jp2_cmap_dumpdata(jp2_box_t *box, FILE *out) +{ + jp2_cmap_t *cmap = &box->data.cmap; + unsigned int i; + jp2_cmapent_t *ent; + fprintf(out, "numchans = %d\n", (int) cmap->numchans); + for (i = 0; i < cmap->numchans; ++i) { + ent = &cmap->ents[i]; + fprintf(out, "cmptno=%d; map=%d; pcol=%d\n", + (int) ent->cmptno, (int) ent->map, (int) ent->pcol); + } +} + +static void jp2_pclr_destroy(jp2_box_t *box) +{ + jp2_pclr_t *pclr = &box->data.pclr; + if (pclr->lutdata) { + jas_free(pclr->lutdata); + } + if (pclr->bpc) + jas_free(pclr->bpc); +} + +static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_pclr_t *pclr = &box->data.pclr; + int lutsize; + unsigned int i; + unsigned int j; + int_fast32_t x; + + pclr->lutdata = 0; + + if (jp2_getuint16(in, &pclr->numlutents) || + jp2_getuint8(in, &pclr->numchans)) { + return -1; + } + lutsize = pclr->numlutents * pclr->numchans; + if (!(pclr->lutdata = jas_alloc2(lutsize, sizeof(int_fast32_t)))) { + return -1; + } + if (!(pclr->bpc = jas_alloc2(pclr->numchans, sizeof(uint_fast8_t)))) { + return -1; + } + for (i = 0; i < pclr->numchans; ++i) { + if (jp2_getuint8(in, &pclr->bpc[i])) { + return -1; + } + } + for (i = 0; i < pclr->numlutents; ++i) { + for (j = 0; j < pclr->numchans; ++j) { + if (jp2_getint(in, (pclr->bpc[j] & 0x80) != 0, + (pclr->bpc[j] & 0x7f) + 1, &x)) { + return -1; + } + pclr->lutdata[i * pclr->numchans + j] = x; + } + } + return 0; +} + +static int jp2_pclr_putdata(jp2_box_t *box, jas_stream_t *out) +{ +#if 0 + jp2_pclr_t *pclr = &box->data.pclr; +#endif +/* Eliminate warning about unused variable. */ +box = 0; +out = 0; + return -1; +} + +static void jp2_pclr_dumpdata(jp2_box_t *box, FILE *out) +{ + jp2_pclr_t *pclr = &box->data.pclr; + unsigned int i; + int j; + fprintf(out, "numents=%d; numchans=%d\n", (int) pclr->numlutents, + (int) pclr->numchans); + for (i = 0; i < pclr->numlutents; ++i) { + for (j = 0; j < pclr->numchans; ++j) { + fprintf(out, "LUT[%d][%d]=%d\n", i, j, (int)pclr->lutdata[i * pclr->numchans + j]); + } + } +} + +static void jp2_uuid_destroy(jp2_box_t *box) +{ + jp2_uuid_t *uuid = &box->data.uuid; + if (uuid->data) + { + jas_free(uuid->data); + uuid->data = NULL; + } +} + +static int jp2_uuid_getdata(jp2_box_t *box, jas_stream_t *in) +{ + jp2_uuid_t *uuid = &box->data.uuid; + int i; + + for (i = 0; i < 16; i++) + { + if (jp2_getuint8(in, &uuid->uuid[i])) + return -1; + } + + uuid->datalen = box->datalen - 16; + uuid->data = jas_malloc(uuid->datalen * sizeof(uint_fast8_t)); + for (i = 0; i < uuid->datalen; i++) + { + if (jp2_getuint8(in, &uuid->data[i])) + return -1; + } + return 0; +} + +static int jp2_uuid_putdata(jp2_box_t *box, jas_stream_t *out) +{ + jp2_uuid_t *uuid = &box->data.uuid; + int i; + + for (i = 0; i < 16; i++) + { + if (jp2_putuint8(out, uuid->uuid[i])) + return -1; + } + + for (i = 0; i < uuid->datalen; i++) + { + if (jp2_putuint8(out, uuid->data[i])) + return -1; + } + return 0; +} + +static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val) +{ + int c; + int i; + uint_fast32_t v; + int m; + + m = (n + 7) / 8; + + v = 0; + for (i = 0; i < m; ++i) { + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + } + v &= ONES(n); + if (s) { + int sb; + sb = v & (1 << (8 * m - 1)); + *val = ((~v) + 1) & ONES(8 * m); + if (sb) { + *val = -*val; + } + } else { + *val = v; + } + + return 0; +} + +jp2_cdefchan_t *jp2_cdef_lookup(jp2_cdef_t *cdef, int channo) +{ + unsigned int i; + jp2_cdefchan_t *cdefent; + for (i = 0; i < cdef->numchans; ++i) { + cdefent = &cdef->ents[i]; + if (cdefent->channo == JAS_CAST(unsigned int, channo)) { + return cdefent; + } + } + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_cod.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,316 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* + * Modified by Andrey Kiselev to handle UUID + * box properly. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JP2 Library + * + * $Id: jp2_cod.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JP2_COD_H +#define JP2_COD_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" + +/******************************************************************************\ +* Macros. +\******************************************************************************/ + +#define JP2_SPTOBPC(s, p) \ + ((((p) - 1) & 0x7f) | (((s) & 1) << 7)) + +/******************************************************************************\ +* Box class. +\******************************************************************************/ + +#define JP2_BOX_HDRLEN(ext) ((ext) ? 16 : 8) + +/* Box types. */ +#define JP2_BOX_JP 0x6a502020 /* Signature */ +#define JP2_BOX_FTYP 0x66747970 /* File Type */ +#define JP2_BOX_JP2H 0x6a703268 /* JP2 Header */ +#define JP2_BOX_IHDR 0x69686472 /* Image Header */ +#define JP2_BOX_BPCC 0x62706363 /* Bits Per Component */ +#define JP2_BOX_COLR 0x636f6c72 /* Color Specification */ +#define JP2_BOX_PCLR 0x70636c72 /* Palette */ +#define JP2_BOX_CMAP 0x636d6170 /* Component Mapping */ +#define JP2_BOX_CDEF 0x63646566 /* Channel Definition */ +#define JP2_BOX_RES 0x72657320 /* Resolution */ +#define JP2_BOX_RESC 0x72657363 /* Capture Resolution */ +#define JP2_BOX_RESD 0x72657364 /* Default Display Resolution */ +#define JP2_BOX_JP2C 0x6a703263 /* Contiguous Code Stream */ +#define JP2_BOX_JP2I 0x6a703269 /* Intellectual Property */ +#define JP2_BOX_XML 0x786d6c20 /* XML */ +#define JP2_BOX_UUID 0x75756964 /* UUID */ +#define JP2_BOX_UINF 0x75696e66 /* UUID Info */ +#define JP2_BOX_ULST 0x75637374 /* UUID List */ +#define JP2_BOX_URL 0x75726c20 /* URL */ + +#define JP2_BOX_SUPER 0x01 +#define JP2_BOX_NODATA 0x02 + +/* JP box data. */ + +#define JP2_JP_MAGIC 0x0d0a870a +#define JP2_JP_LEN 12 + +typedef struct { + uint_fast32_t magic; +} jp2_jp_t; + +/* FTYP box data. */ + +#define JP2_FTYP_MAXCOMPATCODES 32 +#define JP2_FTYP_MAJVER 0x6a703220 +#define JP2_FTYP_MINVER 0 +#define JP2_FTYP_COMPATCODE JP2_FTYP_MAJVER + +typedef struct { + uint_fast32_t majver; + uint_fast32_t minver; + uint_fast32_t numcompatcodes; + uint_fast32_t compatcodes[JP2_FTYP_MAXCOMPATCODES]; +} jp2_ftyp_t; + +/* IHDR box data. */ + +#define JP2_IHDR_COMPTYPE 7 +#define JP2_IHDR_BPCNULL 255 + +typedef struct { + uint_fast32_t width; + uint_fast32_t height; + uint_fast16_t numcmpts; + uint_fast8_t bpc; + uint_fast8_t comptype; + uint_fast8_t csunk; + uint_fast8_t ipr; +} jp2_ihdr_t; + +/* BPCC box data. */ + +typedef struct { + uint_fast16_t numcmpts; + uint_fast8_t *bpcs; +} jp2_bpcc_t; + +/* COLR box data. */ + +#define JP2_COLR_ENUM 1 +#define JP2_COLR_ICC 2 +#define JP2_COLR_PRI 0 + +#define JP2_COLR_SRGB 16 +#define JP2_COLR_SGRAY 17 +#define JP2_COLR_SYCC 18 + +typedef struct { + uint_fast8_t method; + uint_fast8_t pri; + uint_fast8_t approx; + uint_fast32_t csid; + uint_fast8_t *iccp; + int iccplen; + /* XXX - Someday we ought to add ICC profile data here. */ +} jp2_colr_t; + +/* PCLR box data. */ + +typedef struct { + uint_fast16_t numlutents; + uint_fast8_t numchans; + int_fast32_t *lutdata; + uint_fast8_t *bpc; +} jp2_pclr_t; + +/* CDEF box per-channel data. */ + +#define JP2_CDEF_RGB_R 1 +#define JP2_CDEF_RGB_G 2 +#define JP2_CDEF_RGB_B 3 + +#define JP2_CDEF_YCBCR_Y 1 +#define JP2_CDEF_YCBCR_CB 2 +#define JP2_CDEF_YCBCR_CR 3 + +#define JP2_CDEF_GRAY_Y 1 + +#define JP2_CDEF_TYPE_COLOR 0 +#define JP2_CDEF_TYPE_OPACITY 1 +#define JP2_CDEF_TYPE_UNSPEC 65535 +#define JP2_CDEF_ASOC_ALL 0 +#define JP2_CDEF_ASOC_NONE 65535 + +typedef struct { + uint_fast16_t channo; + uint_fast16_t type; + uint_fast16_t assoc; +} jp2_cdefchan_t; + +/* CDEF box data. */ + +typedef struct { + uint_fast16_t numchans; + jp2_cdefchan_t *ents; +} jp2_cdef_t; + +typedef struct { + uint_fast16_t cmptno; + uint_fast8_t map; + uint_fast8_t pcol; +} jp2_cmapent_t; + +typedef struct { + uint_fast16_t numchans; + jp2_cmapent_t *ents; +} jp2_cmap_t; + +typedef struct { + uint_fast32_t datalen; + uint_fast8_t uuid[16]; + uint_fast8_t *data; +} jp2_uuid_t; + +#define JP2_CMAP_DIRECT 0 +#define JP2_CMAP_PALETTE 1 + +/* Generic box. */ + +struct jp2_boxops_s; +typedef struct { + + struct jp2_boxops_s *ops; + struct jp2_boxinfo_s *info; + + uint_fast32_t type; + + /* The length of the box including the (variable-length) header. */ + uint_fast32_t len; + + /* The length of the box data. */ + uint_fast32_t datalen; + + union { + jp2_jp_t jp; + jp2_ftyp_t ftyp; + jp2_ihdr_t ihdr; + jp2_bpcc_t bpcc; + jp2_colr_t colr; + jp2_pclr_t pclr; + jp2_cdef_t cdef; + jp2_cmap_t cmap; + jp2_uuid_t uuid; + } data; + +} jp2_box_t; + +typedef struct jp2_boxops_s { + void (*init)(jp2_box_t *box); + void (*destroy)(jp2_box_t *box); + int (*getdata)(jp2_box_t *box, jas_stream_t *in); + int (*putdata)(jp2_box_t *box, jas_stream_t *out); + void (*dumpdata)(jp2_box_t *box, FILE *out); +} jp2_boxops_t; + +/******************************************************************************\ +* +\******************************************************************************/ + +typedef struct jp2_boxinfo_s { + int type; + char *name; + int flags; + jp2_boxops_t ops; +} jp2_boxinfo_t; + +/******************************************************************************\ +* Box class. +\******************************************************************************/ + +jp2_box_t *jp2_box_create(int type); +void jp2_box_destroy(jp2_box_t *box); +jp2_box_t *jp2_box_get(jas_stream_t *in); +int jp2_box_put(jp2_box_t *box, jas_stream_t *out); + +#define JP2_DTYPETOBPC(dtype) \ + ((JAS_IMAGE_CDT_GETSGND(dtype) << 7) | (JAS_IMAGE_CDT_GETPREC(dtype) - 1)) +#define JP2_BPCTODTYPE(bpc) \ + (JAS_IMAGE_CDT_SETSGND(bpc >> 7) | JAS_IMAGE_CDT_SETPREC((bpc & 0x7f) + 1)) + +#define ICC_CS_RGB 0x52474220 +#define ICC_CS_YCBCR 0x59436272 +#define ICC_CS_GRAY 0x47524159 + +jp2_cdefchan_t *jp2_cdef_lookup(jp2_cdef_t *cdef, int channo); + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,603 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JP2 Library + * + * $Id: jp2_dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_image.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_version.h" + +#include "jp2_cod.h" +#include "jp2_dec.h" + +#define JP2_VALIDATELEN (JAS_MIN(JP2_JP_LEN + 16, JAS_STREAM_MAXPUTBACK)) + +static jp2_dec_t *jp2_dec_create(void); +static void jp2_dec_destroy(jp2_dec_t *dec); +static int jp2_getcs(jp2_colr_t *colr); +static int fromiccpcs(int cs); +static int jp2_getct(int colorspace, int type, int assoc); + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +jas_image_t *jp2_decode(jas_stream_t *in, char *optstr) +{ + jp2_box_t *box; + int found; + jas_image_t *image; + jp2_dec_t *dec; + bool samedtype; + int dtype; + unsigned int i; + jp2_cmap_t *cmapd; + jp2_pclr_t *pclrd; + jp2_cdef_t *cdefd; + unsigned int channo; + int newcmptno; + int_fast32_t *lutents; +#if 0 + jp2_cdefchan_t *cdefent; + int cmptno; +#endif + jp2_cmapent_t *cmapent; + jas_icchdr_t icchdr; + jas_iccprof_t *iccprof; + + dec = 0; + box = 0; + image = 0; + + if (!(dec = jp2_dec_create())) { + goto error; + } + + /* Get the first box. This should be a JP box. */ + if (!(box = jp2_box_get(in))) { + jas_eprintf("error: cannot get box\n"); + goto error; + } + if (box->type != JP2_BOX_JP) { + jas_eprintf("error: expecting signature box\n"); + goto error; + } + if (box->data.jp.magic != JP2_JP_MAGIC) { + jas_eprintf("incorrect magic number\n"); + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* Get the second box. This should be a FTYP box. */ + if (!(box = jp2_box_get(in))) { + goto error; + } + if (box->type != JP2_BOX_FTYP) { + jas_eprintf("expecting file type box\n"); + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* Get more boxes... */ + found = 0; + while ((box = jp2_box_get(in))) { + if (jas_getdbglevel() >= 1) { + jas_eprintf("box type %s\n", box->info->name); + } + switch (box->type) { + case JP2_BOX_JP2C: + found = 1; + break; + case JP2_BOX_IHDR: + if (!dec->ihdr) { + dec->ihdr = box; + box = 0; + } + break; + case JP2_BOX_BPCC: + if (!dec->bpcc) { + dec->bpcc = box; + box = 0; + } + break; + case JP2_BOX_CDEF: + if (!dec->cdef) { + dec->cdef = box; + box = 0; + } + break; + case JP2_BOX_PCLR: + if (!dec->pclr) { + dec->pclr = box; + box = 0; + } + break; + case JP2_BOX_CMAP: + if (!dec->cmap) { + dec->cmap = box; + box = 0; + } + break; + case JP2_BOX_COLR: + if (!dec->colr) { + dec->colr = box; + box = 0; + } + break; + } + if (box) { + jp2_box_destroy(box); + box = 0; + } + if (found) { + break; + } + } + + if (!found) { + jas_eprintf("error: no code stream found\n"); + goto error; + } + + if (!(dec->image = jpc_decode(in, optstr))) { + jas_eprintf("error: cannot decode code stream\n"); + goto error; + } + + /* An IHDR box must be present. */ + if (!dec->ihdr) { + jas_eprintf("error: missing IHDR box\n"); + goto error; + } + + /* Does the number of components indicated in the IHDR box match + the value specified in the code stream? */ + if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint, jas_image_numcmpts(dec->image))) { + jas_eprintf("warning: number of components mismatch\n"); + } + + /* At least one component must be present. */ + if (!jas_image_numcmpts(dec->image)) { + jas_eprintf("error: no components\n"); + goto error; + } + + /* Determine if all components have the same data type. */ + samedtype = true; + dtype = jas_image_cmptdtype(dec->image, 0); + for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { + if (jas_image_cmptdtype(dec->image, i) != dtype) { + samedtype = false; + break; + } + } + + /* Is the component data type indicated in the IHDR box consistent + with the data in the code stream? */ + if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) || + (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) { + jas_eprintf("warning: component data type mismatch\n"); + } + + /* Is the compression type supported? */ + if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) { + jas_eprintf("error: unsupported compression type\n"); + goto error; + } + + if (dec->bpcc) { + /* Is the number of components indicated in the BPCC box + consistent with the code stream data? */ + if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts( + dec->image))) { + jas_eprintf("warning: number of components mismatch\n"); + } + /* Is the component data type information indicated in the BPCC + box consistent with the code stream data? */ + if (!samedtype) { + for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { + if (jas_image_cmptdtype(dec->image, i) != JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) { + jas_eprintf("warning: component data type mismatch\n"); + } + } + } else { + jas_eprintf("warning: superfluous BPCC box\n"); + } + } + + /* A COLR box must be present. */ + if (!dec->colr) { + jas_eprintf("error: no COLR box\n"); + goto error; + } + + switch (dec->colr->data.colr.method) { + case JP2_COLR_ENUM: + jas_image_setclrspc(dec->image, jp2_getcs(&dec->colr->data.colr)); + break; + case JP2_COLR_ICC: + iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp, + dec->colr->data.colr.iccplen); + assert(iccprof); + jas_iccprof_gethdr(iccprof, &icchdr); + jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc); + jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc)); + dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof); + assert(dec->image->cmprof_); + jas_iccprof_destroy(iccprof); + break; + } + + /* If a CMAP box is present, a PCLR box must also be present. */ + if (dec->cmap && !dec->pclr) { + jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n"); + jp2_box_destroy(dec->cmap); + dec->cmap = 0; + } + + /* If a CMAP box is not present, a PCLR box must not be present. */ + if (!dec->cmap && dec->pclr) { + jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n"); + jp2_box_destroy(dec->pclr); + dec->pclr = 0; + } + + /* Determine the number of channels (which is essentially the number + of components after any palette mappings have been applied). */ + dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans : JAS_CAST(uint, jas_image_numcmpts(dec->image)); + + /* Perform a basic sanity check on the CMAP box if present. */ + if (dec->cmap) { + for (i = 0; i < dec->numchans; ++i) { + /* Is the component number reasonable? */ + if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint, jas_image_numcmpts(dec->image))) { + jas_eprintf("error: invalid component number in CMAP box\n"); + goto error; + } + /* Is the LUT index reasonable? */ + if (dec->cmap->data.cmap.ents[i].pcol >= dec->pclr->data.pclr.numchans) { + jas_eprintf("error: invalid CMAP LUT index\n"); + goto error; + } + } + } + + /* Allocate space for the channel-number to component-number LUT. */ + if (!(dec->chantocmptlut = jas_alloc2(dec->numchans, sizeof(uint_fast16_t)))) { + jas_eprintf("error: no memory\n"); + goto error; + } + + if (!dec->cmap) { + for (i = 0; i < dec->numchans; ++i) { + dec->chantocmptlut[i] = i; + } + } else { + cmapd = &dec->cmap->data.cmap; + pclrd = &dec->pclr->data.pclr; + cdefd = &dec->cdef->data.cdef; + for (channo = 0; channo < cmapd->numchans; ++channo) { + cmapent = &cmapd->ents[channo]; + if (cmapent->map == JP2_CMAP_DIRECT) { + dec->chantocmptlut[channo] = channo; + } else if (cmapent->map == JP2_CMAP_PALETTE) { + lutents = jas_alloc2(pclrd->numlutents, sizeof(int_fast32_t)); + for (i = 0; i < pclrd->numlutents; ++i) { + lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans]; + } + newcmptno = jas_image_numcmpts(dec->image); + jas_image_depalettize(dec->image, cmapent->cmptno, pclrd->numlutents, lutents, JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno); + dec->chantocmptlut[channo] = newcmptno; + jas_free(lutents); +#if 0 + if (dec->cdef) { + cdefent = jp2_cdef_lookup(cdefd, channo); + if (!cdefent) { + abort(); + } + jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc)); + } else { + jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1)); + } +#endif + } + } + } + + /* Mark all components as being of unknown type. */ + + for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { + jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN); + } + + /* Determine the type of each component. */ + if (dec->cdef) { + for (i = 0; i < dec->numchans; ++i) { + jas_image_setcmpttype(dec->image, + dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo], + jp2_getct(jas_image_clrspc(dec->image), + dec->cdef->data.cdef.ents[i].type, dec->cdef->data.cdef.ents[i].assoc)); + } + } else { + for (i = 0; i < dec->numchans; ++i) { + jas_image_setcmpttype(dec->image, dec->chantocmptlut[i], + jp2_getct(jas_image_clrspc(dec->image), 0, i + 1)); + } + } + + /* Delete any components that are not of interest. */ + for (i = jas_image_numcmpts(dec->image); i > 0; --i) { + if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) { + jas_image_delcmpt(dec->image, i - 1); + } + } + + /* Ensure that some components survived. */ + if (!jas_image_numcmpts(dec->image)) { + jas_eprintf("error: no components\n"); + goto error; + } +#if 0 +jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image)); +#endif + + /* Prevent the image from being destroyed later. */ + image = dec->image; + dec->image = 0; + + jp2_dec_destroy(dec); + + return image; + +error: + if (box) { + jp2_box_destroy(box); + } + if (dec) { + jp2_dec_destroy(dec); + } + return 0; +} + +int jp2_validate(jas_stream_t *in) +{ + char buf[JP2_VALIDATELEN]; + int i; + int n; +#if 0 + jas_stream_t *tmpstream; + jp2_box_t *box; +#endif + + assert(JAS_STREAM_MAXPUTBACK >= JP2_VALIDATELEN); + + /* Read the validation data (i.e., the data used for detecting + the format). */ + if ((n = jas_stream_read(in, buf, JP2_VALIDATELEN)) < 0) { + return -1; + } + + /* Put the validation data back onto the stream, so that the + stream position will not be changed. */ + for (i = n - 1; i >= 0; --i) { + if (jas_stream_ungetc(in, buf[i]) == EOF) { + return -1; + } + } + + /* Did we read enough data? */ + if (n < JP2_VALIDATELEN) { + return -1; + } + + /* Is the box type correct? */ + if (((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]) != + JP2_BOX_JP) + { + return -1; + } + + return 0; +} + +static jp2_dec_t *jp2_dec_create(void) +{ + jp2_dec_t *dec; + + if (!(dec = jas_malloc(sizeof(jp2_dec_t)))) { + return 0; + } + dec->ihdr = 0; + dec->bpcc = 0; + dec->cdef = 0; + dec->pclr = 0; + dec->image = 0; + dec->chantocmptlut = 0; + dec->cmap = 0; + dec->colr = 0; + return dec; +} + +static void jp2_dec_destroy(jp2_dec_t *dec) +{ + if (dec->ihdr) { + jp2_box_destroy(dec->ihdr); + } + if (dec->bpcc) { + jp2_box_destroy(dec->bpcc); + } + if (dec->cdef) { + jp2_box_destroy(dec->cdef); + } + if (dec->pclr) { + jp2_box_destroy(dec->pclr); + } + if (dec->image) { + jas_image_destroy(dec->image); + } + if (dec->cmap) { + jp2_box_destroy(dec->cmap); + } + if (dec->colr) { + jp2_box_destroy(dec->colr); + } + if (dec->chantocmptlut) { + jas_free(dec->chantocmptlut); + } + jas_free(dec); +} + +static int jp2_getct(int colorspace, int type, int assoc) +{ + if (type == 1 && assoc == 0) { + return JAS_IMAGE_CT_OPACITY; + } + if (type == 0 && assoc >= 1 && assoc <= 65534) { + switch (colorspace) { + case JAS_CLRSPC_FAM_RGB: + switch (assoc) { + case JP2_CDEF_RGB_R: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R); + break; + case JP2_CDEF_RGB_G: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G); + break; + case JP2_CDEF_RGB_B: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B); + break; + } + break; + case JAS_CLRSPC_FAM_YCBCR: + switch (assoc) { + case JP2_CDEF_YCBCR_Y: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y); + break; + case JP2_CDEF_YCBCR_CB: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB); + break; + case JP2_CDEF_YCBCR_CR: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR); + break; + } + break; + case JAS_CLRSPC_FAM_GRAY: + switch (assoc) { + case JP2_CDEF_GRAY_Y: + return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); + break; + } + break; + default: + return JAS_IMAGE_CT_COLOR(assoc - 1); + break; + } + } + return JAS_IMAGE_CT_UNKNOWN; +} + +static int jp2_getcs(jp2_colr_t *colr) +{ + if (colr->method == JP2_COLR_ENUM) { + switch (colr->csid) { + case JP2_COLR_SRGB: + return JAS_CLRSPC_SRGB; + break; + case JP2_COLR_SYCC: + return JAS_CLRSPC_SYCBCR; + break; + case JP2_COLR_SGRAY: + return JAS_CLRSPC_SGRAY; + break; + } + } + return JAS_CLRSPC_UNKNOWN; +} + +static int fromiccpcs(int cs) +{ + switch (cs) { + case ICC_CS_RGB: + return JAS_CLRSPC_GENRGB; + break; + case ICC_CS_YCBCR: + return JAS_CLRSPC_GENYCBCR; + break; + case ICC_CS_GRAY: + return JAS_CLRSPC_GENGRAY; + break; + } + return JAS_CLRSPC_UNKNOWN; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_dec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JP2_DEC_H +#define JP2_DEC_H + +#include "jasper/jas_image.h" +#include "jasper/jas_stream.h" +#include "jp2_cod.h" + +typedef struct { + + jp2_box_t *pclr; + jp2_box_t *cdef; + jp2_box_t *ihdr; + jp2_box_t *bpcc; + jp2_box_t *cmap; + jp2_box_t *colr; + jas_image_t *image; + uint_fast16_t numchans; + uint_fast16_t *chantocmptlut; + +} jp2_dec_t; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_enc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_enc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jp2_enc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jp2_enc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,481 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* + * Modified by Andrey Kiselev to handle UUID + * box properly. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JP2 Library + * + * $Id: jp2_enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include "jasper/jas_malloc.h" +#include "jasper/jas_image.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_cm.h" +#include "jasper/jas_icc.h" +#include "jp2_cod.h" + +static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype); +static int clrspctojp2(jas_clrspc_t clrspc); + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +int jp2_write_header(jas_image_t *image, jas_stream_t *out) +{ + jp2_box_t *box; + jp2_ftyp_t *ftyp; + jp2_ihdr_t *ihdr; + jas_stream_t *tmpstream; + int allcmptssame; + jp2_bpcc_t *bpcc; + long len; + uint_fast16_t cmptno; + jp2_colr_t *colr; + jp2_cdefchan_t *cdefchanent; + jp2_cdef_t *cdef; + int i; + uint_fast32_t typeasoc; +jas_iccprof_t *iccprof; +jas_stream_t *iccstream; +int pos; +int needcdef; +int prec; +int sgnd; + + box = 0; + tmpstream = 0; + + allcmptssame = 1; + sgnd = jas_image_cmptsgnd(image, 0); + prec = jas_image_cmptprec(image, 0); + for (i = 1; i < jas_image_numcmpts(image); ++i) { + if (jas_image_cmptsgnd(image, i) != sgnd || + jas_image_cmptprec(image, i) != prec) { + allcmptssame = 0; + break; + } + } + + /* Output the signature box. */ + + if (!(box = jp2_box_create(JP2_BOX_JP))) { + goto error; + } + box->data.jp.magic = JP2_JP_MAGIC; + if (jp2_box_put(box, out)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* Output the file type box. */ + + if (!(box = jp2_box_create(JP2_BOX_FTYP))) { + goto error; + } + ftyp = &box->data.ftyp; + ftyp->majver = JP2_FTYP_MAJVER; + ftyp->minver = JP2_FTYP_MINVER; + ftyp->numcompatcodes = 1; + ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; + if (jp2_box_put(box, out)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* + * Generate the data portion of the JP2 header box. + * We cannot simply output the header for this box + * since we do not yet know the correct value for the length + * field. + */ + + if (!(tmpstream = jas_stream_memopen(0, 0))) { + goto error; + } + + /* Generate image header box. */ + + if (!(box = jp2_box_create(JP2_BOX_IHDR))) { + goto error; + } + ihdr = &box->data.ihdr; + ihdr->width = jas_image_width(image); + ihdr->height = jas_image_height(image); + ihdr->numcmpts = jas_image_numcmpts(image); + ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), + jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; + ihdr->comptype = JP2_IHDR_COMPTYPE; + ihdr->csunk = 0; + ihdr->ipr = 0; + if (jp2_box_put(box, tmpstream)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* Generate bits per component box. */ + + if (!allcmptssame) { + if (!(box = jp2_box_create(JP2_BOX_BPCC))) { + goto error; + } + bpcc = &box->data.bpcc; + bpcc->numcmpts = jas_image_numcmpts(image); + if (!(bpcc->bpcs = jas_alloc2(bpcc->numcmpts, + sizeof(uint_fast8_t)))) { + goto error; + } + for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { + bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, + cmptno), jas_image_cmptprec(image, cmptno)); + } + if (jp2_box_put(box, tmpstream)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + } + + /* Generate color specification box. */ + + if (!(box = jp2_box_create(JP2_BOX_COLR))) { + goto error; + } + colr = &box->data.colr; + switch (jas_image_clrspc(image)) { + case JAS_CLRSPC_SRGB: + case JAS_CLRSPC_SYCBCR: + case JAS_CLRSPC_SGRAY: + colr->method = JP2_COLR_ENUM; + colr->csid = clrspctojp2(jas_image_clrspc(image)); + colr->pri = JP2_COLR_PRI; + colr->approx = 0; + break; + default: + colr->method = JP2_COLR_ICC; + colr->pri = JP2_COLR_PRI; + colr->approx = 0; + iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); + assert(iccprof); + iccstream = jas_stream_memopen(0, 0); + assert(iccstream); + if (jas_iccprof_save(iccprof, iccstream)) + abort(); + if ((pos = jas_stream_tell(iccstream)) < 0) + abort(); + colr->iccplen = pos; + colr->iccp = jas_malloc(pos); + assert(colr->iccp); + jas_stream_rewind(iccstream); + if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen) + abort(); + jas_stream_close(iccstream); + jas_iccprof_destroy(iccprof); + break; + } + if (jp2_box_put(box, tmpstream)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + needcdef = 1; + switch (jas_clrspc_fam(jas_image_clrspc(image))) { + case JAS_CLRSPC_FAM_RGB: + if (jas_image_cmpttype(image, 0) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) && + jas_image_cmpttype(image, 1) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) && + jas_image_cmpttype(image, 2) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)) + needcdef = 0; + break; + case JAS_CLRSPC_FAM_YCBCR: + if (jas_image_cmpttype(image, 0) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) && + jas_image_cmpttype(image, 1) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) && + jas_image_cmpttype(image, 2) == + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR)) + needcdef = 0; + break; + case JAS_CLRSPC_FAM_GRAY: + if (jas_image_cmpttype(image, 0) == + JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y)) + needcdef = 0; + break; + default: + abort(); + break; + } + + if (needcdef) { + if (!(box = jp2_box_create(JP2_BOX_CDEF))) { + goto error; + } + cdef = &box->data.cdef; + cdef->numchans = jas_image_numcmpts(image); + cdef->ents = jas_alloc2(cdef->numchans, sizeof(jp2_cdefchan_t)); + for (i = 0; i < jas_image_numcmpts(image); ++i) { + cdefchanent = &cdef->ents[i]; + cdefchanent->channo = i; + typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i)); + cdefchanent->type = typeasoc >> 16; + cdefchanent->assoc = typeasoc & 0x7fff; + } + if (jp2_box_put(box, tmpstream)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + } + + /* Determine the total length of the JP2 header box. */ + + len = jas_stream_tell(tmpstream); + jas_stream_rewind(tmpstream); + + /* + * Output the JP2 header box and all of the boxes which it contains. + */ + + if (!(box = jp2_box_create(JP2_BOX_JP2H))) { + goto error; + } + box->len = len + JP2_BOX_HDRLEN(false); + if (jp2_box_put(box, out)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + if (jas_stream_copy(out, tmpstream, len)) { + goto error; + } + + jas_stream_close(tmpstream); + tmpstream = 0; + + return 0; + abort(); + +error: + + if (box) { + jp2_box_destroy(box); + } + if (tmpstream) { + jas_stream_close(tmpstream); + } + return -1; +} + +int jp2_write_codestream(jas_image_t *image, jas_stream_t *out, char *optstr) +{ + jp2_box_t *box; + char buf[4096]; + uint_fast32_t overhead; + + /* + * Output the contiguous code stream box. + */ + + if (!(box = jp2_box_create(JP2_BOX_JP2C))) { + goto error; + } + box->len = 0; + if (jp2_box_put(box, out)) { + goto error; + } + jp2_box_destroy(box); + box = 0; + + /* Output the JPEG-2000 code stream. */ + + overhead = jas_stream_getrwcount(out); + sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""), + (unsigned long) overhead); + + if (jpc_encode(image, out, buf)) { + goto error; + } + + return 0; + abort(); + +error: + + if (box) { + jp2_box_destroy(box); + } + return -1; +} + +int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr) +{ + if (jp2_write_header(image, out) < 0) + return -1; + if (jp2_write_codestream(image, out, optstr) < 0) + return -1; + + return 0; +} + +int jp2_encode_uuid(jas_image_t *image, jas_stream_t *out, + char *optstr, jp2_box_t *uuid) +{ + if (jp2_write_header(image, out) < 0) + return -1; + if (uuid) { + if (jp2_box_put(uuid, out)) + return -1; + } + if (jp2_write_codestream(image, out, optstr) < 0) + return -1; + + return 0; +} + +static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype) +{ + int type; + int asoc; + + if (ctype & JAS_IMAGE_CT_OPACITY) { + type = JP2_CDEF_TYPE_OPACITY; + asoc = JP2_CDEF_ASOC_ALL; + goto done; + } + + type = JP2_CDEF_TYPE_UNSPEC; + asoc = JP2_CDEF_ASOC_NONE; + switch (jas_clrspc_fam(colorspace)) { + case JAS_CLRSPC_FAM_RGB: + switch (JAS_IMAGE_CT_COLOR(ctype)) { + case JAS_IMAGE_CT_RGB_R: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_RGB_R; + break; + case JAS_IMAGE_CT_RGB_G: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_RGB_G; + break; + case JAS_IMAGE_CT_RGB_B: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_RGB_B; + break; + } + break; + case JAS_CLRSPC_FAM_YCBCR: + switch (JAS_IMAGE_CT_COLOR(ctype)) { + case JAS_IMAGE_CT_YCBCR_Y: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_YCBCR_Y; + break; + case JAS_IMAGE_CT_YCBCR_CB: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_YCBCR_CB; + break; + case JAS_IMAGE_CT_YCBCR_CR: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_YCBCR_CR; + break; + } + break; + case JAS_CLRSPC_FAM_GRAY: + type = JP2_CDEF_TYPE_COLOR; + asoc = JP2_CDEF_GRAY_Y; + break; + } + +done: + return (type << 16) | asoc; +} + +static int clrspctojp2(jas_clrspc_t clrspc) +{ + switch (clrspc) { + case JAS_CLRSPC_SRGB: + return JP2_COLR_SRGB; + case JAS_CLRSPC_SYCBCR: + return JP2_COLR_SYCC; + case JAS_CLRSPC_SGRAY: + return JP2_COLR_SGRAY; + default: + abort(); + break; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,440 @@ +/* + * Copyright (c) 1999-2000, Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Bit Stream Class + * + * $Id: jpc_bs.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" + +#include "jpc_bs.h" + +/******************************************************************************\ +* Local function prototypes. +\******************************************************************************/ + +static jpc_bitstream_t *jpc_bitstream_alloc(void); + +/******************************************************************************\ +* Code for opening and closing bit streams. +\******************************************************************************/ + +/* Open a bit stream from a stream. */ +jpc_bitstream_t *jpc_bitstream_sopen(jas_stream_t *stream, char *mode) +{ + jpc_bitstream_t *bitstream; + + /* Ensure that the open mode is valid. */ +#if 1 +/* This causes a string literal too long error (with c99 pedantic mode). */ + assert(!strcmp(mode, "r") || !strcmp(mode, "w") || !strcmp(mode, "r+") + || !strcmp(mode, "w+")); +#endif + + if (!(bitstream = jpc_bitstream_alloc())) { + return 0; + } + + /* By default, do not close the underlying (character) stream, upon + the close of the bit stream. */ + bitstream->flags_ = JPC_BITSTREAM_NOCLOSE; + + bitstream->stream_ = stream; + bitstream->openmode_ = (mode[0] == 'w') ? JPC_BITSTREAM_WRITE : + JPC_BITSTREAM_READ; + + /* Mark the data buffer as empty. */ + bitstream->cnt_ = (bitstream->openmode_ == JPC_BITSTREAM_READ) ? 0 : 8; + bitstream->buf_ = 0; + + return bitstream; +} + +/* Close a bit stream. */ +int jpc_bitstream_close(jpc_bitstream_t *bitstream) +{ + int ret = 0; + + /* Align to the next byte boundary while considering the effects of + bit stuffing. */ + if (jpc_bitstream_align(bitstream)) { + ret = -1; + } + + /* If necessary, close the underlying (character) stream. */ + if (!(bitstream->flags_ & JPC_BITSTREAM_NOCLOSE) && bitstream->stream_) { + if (jas_stream_close(bitstream->stream_)) { + ret = -1; + } + bitstream->stream_ = 0; + } + + jas_free(bitstream); + return ret; +} + +/* Allocate a new bit stream. */ +static jpc_bitstream_t *jpc_bitstream_alloc() +{ + jpc_bitstream_t *bitstream; + + /* Allocate memory for the new bit stream object. */ + if (!(bitstream = jas_malloc(sizeof(jpc_bitstream_t)))) { + return 0; + } + /* Initialize all of the data members. */ + bitstream->stream_ = 0; + bitstream->cnt_ = 0; + bitstream->flags_ = 0; + bitstream->openmode_ = 0; + + return bitstream; +} + +/******************************************************************************\ +* Code for reading/writing from/to bit streams. +\******************************************************************************/ + +/* Get a bit from a bit stream. */ +int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream) +{ + int ret; + JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func(%p)\n", bitstream)); + ret = jpc_bitstream_getbit_macro(bitstream); + JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func -> %d\n", ret)); + return ret; +} + +/* Put a bit to a bit stream. */ +int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int b) +{ + int ret; + JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func(%p, %d)\n", bitstream, b)); + ret = jpc_bitstream_putbit_macro(bitstream, b); + JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func() -> %d\n", ret)); + return ret; +} + +/* Get one or more bits from a bit stream. */ +long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n) +{ + long v; + int u; + + /* We can reliably get at most 31 bits since ISO/IEC 9899 only + guarantees that a long can represent values up to 2^31-1. */ + assert(n >= 0 && n < 32); + + /* Get the number of bits requested from the specified bit stream. */ + v = 0; + while (--n >= 0) { + if ((u = jpc_bitstream_getbit(bitstream)) < 0) { + return -1; + } + v = (v << 1) | u; + } + return v; +} + +/* Put one or more bits to a bit stream. */ +int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v) +{ + int m; + + /* We can reliably put at most 31 bits since ISO/IEC 9899 only + guarantees that a long can represent values up to 2^31-1. */ + assert(n >= 0 && n < 32); + /* Ensure that only the bits to be output are nonzero. */ + assert(!(v & (~JAS_ONES(n)))); + + /* Put the desired number of bits to the specified bit stream. */ + m = n - 1; + while (--n >= 0) { + if (jpc_bitstream_putbit(bitstream, (v >> m) & 1) == EOF) { + return EOF; + } + v <<= 1; + } + return 0; +} + +/******************************************************************************\ +* Code for buffer filling and flushing. +\******************************************************************************/ + +/* Fill the buffer for a bit stream. */ +int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream) +{ + int c; + /* Note: The count has already been decremented by the caller. */ + assert(bitstream->openmode_ & JPC_BITSTREAM_READ); + assert(bitstream->cnt_ <= 0); + + if (bitstream->flags_ & JPC_BITSTREAM_ERR) { + bitstream->cnt_ = 0; + return -1; + } + + if (bitstream->flags_ & JPC_BITSTREAM_EOF) { + bitstream->buf_ = 0x7f; + bitstream->cnt_ = 7; + return 1; + } + + bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff; + if ((c = jas_stream_getc((bitstream)->stream_)) == EOF) { + bitstream->flags_ |= JPC_BITSTREAM_EOF; + return 1; + } + bitstream->cnt_ = (bitstream->buf_ == 0xff00) ? 6 : 7; + bitstream->buf_ |= c & ((1 << (bitstream->cnt_ + 1)) - 1); + return (bitstream->buf_ >> bitstream->cnt_) & 1; +} + + +/******************************************************************************\ +* Code related to flushing. +\******************************************************************************/ + +/* Does the bit stream need to be aligned to a byte boundary (considering + the effects of bit stuffing)? */ +int jpc_bitstream_needalign(jpc_bitstream_t *bitstream) +{ + if (bitstream->openmode_ & JPC_BITSTREAM_READ) { + /* The bit stream is open for reading. */ + /* If there are any bits buffered for reading, or the + previous byte forced a stuffed bit, alignment is + required. */ + if ((bitstream->cnt_ < 8 && bitstream->cnt_ > 0) || + ((bitstream->buf_ >> 8) & 0xff) == 0xff) { + return 1; + } + } else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { + /* The bit stream is open for writing. */ + /* If there are any bits buffered for writing, or the + previous byte forced a stuffed bit, alignment is + required. */ + if ((bitstream->cnt_ < 8 && bitstream->cnt_ >= 0) || + ((bitstream->buf_ >> 8) & 0xff) == 0xff) { + return 1; + } + } else { + /* This should not happen. Famous last words, eh? :-) */ + assert(0); + return -1; + } + return 0; +} + +/* How many additional bytes would be output if we align the bit stream? */ +int jpc_bitstream_pending(jpc_bitstream_t *bitstream) +{ + if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { + /* The bit stream is being used for writing. */ +#if 1 + /* XXX - Is this really correct? Check someday... */ + if (bitstream->cnt_ < 8) { + return 1; + } +#else + if (bitstream->cnt_ < 8) { + if (((bitstream->buf_ >> 8) & 0xff) == 0xff) { + return 2; + } + return 1; + } +#endif + return 0; + } else { + /* This operation should not be invoked on a bit stream that + is being used for reading. */ + return -1; + } +} + +/* Align the bit stream to a byte boundary. */ +int jpc_bitstream_align(jpc_bitstream_t *bitstream) +{ + int ret; + if (bitstream->openmode_ & JPC_BITSTREAM_READ) { + ret = jpc_bitstream_inalign(bitstream, 0, 0); + } else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { + ret = jpc_bitstream_outalign(bitstream, 0); + } else { + abort(); + } + return ret; +} + +/* Align a bit stream in the input case. */ +int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, + int filldata) +{ + int n; + int v; + int u; + int numfill; + int m; + + numfill = 7; + m = 0; + v = 0; + if (bitstream->cnt_ > 0) { + n = bitstream->cnt_; + } else if (!bitstream->cnt_) { + n = ((bitstream->buf_ & 0xff) == 0xff) ? 7 : 0; + } else { + n = 0; + } + if (n > 0) { + if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) { + return -1; + } + m += n; + v = (v << n) | u; + } + if ((bitstream->buf_ & 0xff) == 0xff) { + if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) { + return -1; + } + v = (v << 7) | u; + m += 7; + } + if (m > numfill) { + v >>= m - numfill; + } else { + filldata >>= numfill - m; + fillmask >>= numfill - m; + } + if (((~(v ^ filldata)) & fillmask) != fillmask) { + /* The actual fill pattern does not match the expected one. */ + return 1; + } + + return 0; +} + +/* Align a bit stream in the output case. */ +int jpc_bitstream_outalign(jpc_bitstream_t *bitstream, int filldata) +{ + int n; + int v; + + /* Ensure that this bit stream is open for writing. */ + assert(bitstream->openmode_ & JPC_BITSTREAM_WRITE); + + /* Ensure that the first bit of fill data is zero. */ + /* Note: The first bit of fill data must be zero. If this were not + the case, the fill data itself could cause further bit stuffing to + be required (which would cause numerous complications). */ + assert(!(filldata & (~0x3f))); + + if (!bitstream->cnt_) { + if ((bitstream->buf_ & 0xff) == 0xff) { + n = 7; + v = filldata; + } else { + n = 0; + v = 0; + } + } else if (bitstream->cnt_ > 0 && bitstream->cnt_ < 8) { + n = bitstream->cnt_; + v = filldata >> (7 - n); + } else { + n = 0; + v = 0; + return 0; + } + + /* Write the appropriate fill data to the bit stream. */ + if (n > 0) { + if (jpc_bitstream_putbits(bitstream, n, v)) { + return -1; + } + } + if (bitstream->cnt_ < 8) { + assert(bitstream->cnt_ >= 0 && bitstream->cnt_ < 8); + assert((bitstream->buf_ & 0xff) != 0xff); + /* Force the pending byte of output to be written to the + underlying (character) stream. */ + if (jas_stream_putc(bitstream->stream_, bitstream->buf_ & 0xff) == EOF) { + return -1; + } + bitstream->cnt_ = 8; + bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff; + } + + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_bs.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Bit Stream Class + * + * $Id: jpc_bs.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_BS_H +#define JPC_BS_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_stream.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* + * Bit stream open mode flags. + */ + +/* Bit stream open for reading. */ +#define JPC_BITSTREAM_READ 0x01 +/* Bit stream open for writing. */ +#define JPC_BITSTREAM_WRITE 0x02 + +/* + * Bit stream flags. + */ + +/* Do not close underlying character stream. */ +#define JPC_BITSTREAM_NOCLOSE 0x01 +/* End of file has been reached while reading. */ +#define JPC_BITSTREAM_EOF 0x02 +/* An I/O error has occured. */ +#define JPC_BITSTREAM_ERR 0x04 + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* Bit stream class. */ + +typedef struct { + + /* Some miscellaneous flags. */ + int flags_; + + /* The input/output buffer. */ + uint_fast16_t buf_; + + /* The number of bits remaining in the byte being read/written. */ + int cnt_; + + /* The underlying stream associated with this bit stream. */ + jas_stream_t *stream_; + + /* The mode in which this bit stream was opened. */ + int openmode_; + +} jpc_bitstream_t; + +/******************************************************************************\ +* Functions/macros for opening and closing bit streams.. +\******************************************************************************/ + +/* Open a stream as a bit stream. */ +jpc_bitstream_t *jpc_bitstream_sopen(jas_stream_t *stream, char *mode); + +/* Close a bit stream. */ +int jpc_bitstream_close(jpc_bitstream_t *bitstream); + +/******************************************************************************\ +* Functions/macros for reading from and writing to bit streams.. +\******************************************************************************/ + +/* Read a bit from a bit stream. */ +#if defined(DEBUG) +#define jpc_bitstream_getbit(bitstream) \ + jpc_bitstream_getbit_func(bitstream) +#else +#define jpc_bitstream_getbit(bitstream) \ + jpc_bitstream_getbit_macro(bitstream) +#endif + +/* Write a bit to a bit stream. */ +#if defined(DEBUG) +#define jpc_bitstream_putbit(bitstream, v) \ + jpc_bitstream_putbit_func(bitstream, v) +#else +#define jpc_bitstream_putbit(bitstream, v) \ + jpc_bitstream_putbit_macro(bitstream, v) +#endif + +/* Read one or more bits from a bit stream. */ +long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n); + +/* Write one or more bits to a bit stream. */ +int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v); + +/******************************************************************************\ +* Functions/macros for flushing and aligning bit streams. +\******************************************************************************/ + +/* Align the current position within the bit stream to the next byte + boundary. */ +int jpc_bitstream_align(jpc_bitstream_t *bitstream); + +/* Align the current position in the bit stream with the next byte boundary, + ensuring that certain bits consumed in the process match a particular + pattern. */ +int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, + int filldata); + +/* Align the current position in the bit stream with the next byte boundary, + writing bits from the specified pattern (if necessary) in the process. */ +int jpc_bitstream_outalign(jpc_bitstream_t *bitstream, int filldata); + +/* Check if a bit stream needs alignment. */ +int jpc_bitstream_needalign(jpc_bitstream_t *bitstream); + +/* How many additional bytes would be output if the bit stream was aligned? */ +int jpc_bitstream_pending(jpc_bitstream_t *bitstream); + +/******************************************************************************\ +* Functions/macros for querying state information for bit streams. +\******************************************************************************/ + +/* Has EOF been encountered on a bit stream? */ +#define jpc_bitstream_eof(bitstream) \ + ((bitstream)->flags_ & JPC_BITSTREAM_EOF) + +/******************************************************************************\ +* Internals. +\******************************************************************************/ + +/* DO NOT DIRECTLY INVOKE ANY OF THE MACROS OR FUNCTIONS BELOW. THEY ARE + FOR INTERNAL USE ONLY. */ + +int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream); + +int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int v); + +int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream); + +#define jpc_bitstream_getbit_macro(bitstream) \ + (assert((bitstream)->openmode_ & JPC_BITSTREAM_READ), \ + (--(bitstream)->cnt_ >= 0) ? \ + ((int)(((bitstream)->buf_ >> (bitstream)->cnt_) & 1)) : \ + jpc_bitstream_fillbuf(bitstream)) + +#define jpc_bitstream_putbit_macro(bitstream, bit) \ + (assert((bitstream)->openmode_ & JPC_BITSTREAM_WRITE), \ + (--(bitstream)->cnt_ < 0) ? \ + ((bitstream)->buf_ = ((bitstream)->buf_ << 8) & 0xffff, \ + (bitstream)->cnt_ = ((bitstream)->buf_ == 0xff00) ? 6 : 7, \ + (bitstream)->buf_ |= ((bit) & 1) << (bitstream)->cnt_, \ + (jas_stream_putc((bitstream)->stream_, (bitstream)->buf_ >> 8) == EOF) \ + ? (EOF) : ((bit) & 1)) : \ + ((bitstream)->buf_ |= ((bit) & 1) << (bitstream)->cnt_, \ + (bit) & 1)) + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cod.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cod.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cod.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cod.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_cod.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_COD_H +#define JPC_COD_H + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* The nominal word size used by this implementation. */ +#define JPC_PREC 32 + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1650 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JPEG-2000 Code Stream Library + * + * $Id: jpc_cs.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_malloc.h" +#include "jasper/jas_debug.h" + +#include "jpc_cs.h" + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* Marker segment table entry. */ +typedef struct { + int id; + char *name; + jpc_msops_t ops; +} jpc_mstabent_t; + +/******************************************************************************\ +* Local prototypes. +\******************************************************************************/ + +static jpc_mstabent_t *jpc_mstab_lookup(int id); + +static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static void jpc_poc_destroyparms(jpc_ms_t *ms); + +static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_coc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_qcd_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_qcc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_rgn_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); +static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); + +static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); +static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); + +static int jpc_sot_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_cod_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_unk_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_ppm_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_crg_dumpparms(jpc_ms_t *ms, FILE *out); +static int jpc_com_dumpparms(jpc_ms_t *ms, FILE *out); + +static void jpc_siz_destroyparms(jpc_ms_t *ms); +static void jpc_qcd_destroyparms(jpc_ms_t *ms); +static void jpc_qcc_destroyparms(jpc_ms_t *ms); +static void jpc_cod_destroyparms(jpc_ms_t *ms); +static void jpc_coc_destroyparms(jpc_ms_t *ms); +static void jpc_unk_destroyparms(jpc_ms_t *ms); +static void jpc_ppm_destroyparms(jpc_ms_t *ms); +static void jpc_ppt_destroyparms(jpc_ms_t *ms); +static void jpc_crg_destroyparms(jpc_ms_t *ms); +static void jpc_com_destroyparms(jpc_ms_t *ms); + +static void jpc_qcx_destroycompparms(jpc_qcxcp_t *compparms); +static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, + jas_stream_t *in, uint_fast16_t len); +static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, + jas_stream_t *out); +static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms); +static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, + jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms); +static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, + jas_stream_t *out, int prtflag, jpc_coxcp_t *compparms); + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +static jpc_mstabent_t jpc_mstab[] = { + {JPC_MS_SOC, "SOC", {0, 0, 0, 0}}, + {JPC_MS_SOT, "SOT", {0, jpc_sot_getparms, jpc_sot_putparms, + jpc_sot_dumpparms}}, + {JPC_MS_SOD, "SOD", {0, 0, 0, 0}}, + {JPC_MS_EOC, "EOC", {0, 0, 0, 0}}, + {JPC_MS_SIZ, "SIZ", {jpc_siz_destroyparms, jpc_siz_getparms, + jpc_siz_putparms, jpc_siz_dumpparms}}, + {JPC_MS_COD, "COD", {jpc_cod_destroyparms, jpc_cod_getparms, + jpc_cod_putparms, jpc_cod_dumpparms}}, + {JPC_MS_COC, "COC", {jpc_coc_destroyparms, jpc_coc_getparms, + jpc_coc_putparms, jpc_coc_dumpparms}}, + {JPC_MS_RGN, "RGN", {0, jpc_rgn_getparms, jpc_rgn_putparms, + jpc_rgn_dumpparms}}, + {JPC_MS_QCD, "QCD", {jpc_qcd_destroyparms, jpc_qcd_getparms, + jpc_qcd_putparms, jpc_qcd_dumpparms}}, + {JPC_MS_QCC, "QCC", {jpc_qcc_destroyparms, jpc_qcc_getparms, + jpc_qcc_putparms, jpc_qcc_dumpparms}}, + {JPC_MS_POC, "POC", {jpc_poc_destroyparms, jpc_poc_getparms, + jpc_poc_putparms, jpc_poc_dumpparms}}, + {JPC_MS_TLM, "TLM", {0, jpc_unk_getparms, jpc_unk_putparms, 0}}, + {JPC_MS_PLM, "PLM", {0, jpc_unk_getparms, jpc_unk_putparms, 0}}, + {JPC_MS_PPM, "PPM", {jpc_ppm_destroyparms, jpc_ppm_getparms, + jpc_ppm_putparms, jpc_ppm_dumpparms}}, + {JPC_MS_PPT, "PPT", {jpc_ppt_destroyparms, jpc_ppt_getparms, + jpc_ppt_putparms, jpc_ppt_dumpparms}}, + {JPC_MS_SOP, "SOP", {0, jpc_sop_getparms, jpc_sop_putparms, + jpc_sop_dumpparms}}, + {JPC_MS_EPH, "EPH", {0, 0, 0, 0}}, + {JPC_MS_CRG, "CRG", {0, jpc_crg_getparms, jpc_crg_putparms, + jpc_crg_dumpparms}}, + {JPC_MS_COM, "COM", {jpc_com_destroyparms, jpc_com_getparms, + jpc_com_putparms, jpc_com_dumpparms}}, + {-1, "UNKNOWN", {jpc_unk_destroyparms, jpc_unk_getparms, + jpc_unk_putparms, jpc_unk_dumpparms}} +}; + +/******************************************************************************\ +* Code stream manipulation functions. +\******************************************************************************/ + +/* Create a code stream state object. */ +jpc_cstate_t *jpc_cstate_create() +{ + jpc_cstate_t *cstate; + if (!(cstate = jas_malloc(sizeof(jpc_cstate_t)))) { + return 0; + } + cstate->numcomps = 0; + return cstate; +} + +/* Destroy a code stream state object. */ +void jpc_cstate_destroy(jpc_cstate_t *cstate) +{ + jas_free(cstate); +} + +/* Read a marker segment from a stream. */ +jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) +{ + jpc_ms_t *ms; + jpc_mstabent_t *mstabent; + jas_stream_t *tmpstream; + + if (!(ms = jpc_ms_create(0))) { + return 0; + } + + /* Get the marker type. */ + if (jpc_getuint16(in, &ms->id) || ms->id < JPC_MS_MIN /*|| ms->id > JPC_MS_MAX*/) { + jpc_ms_destroy(ms); + return 0; + } + + mstabent = jpc_mstab_lookup(ms->id); + ms->ops = &mstabent->ops; + + /* Get the marker segment length and parameters if present. */ + /* Note: It is tacitly assumed that a marker segment cannot have + parameters unless it has a length field. That is, there cannot + be a parameters field without a length field and vice versa. */ + if (JPC_MS_HASPARMS(ms->id)) { + /* Get the length of the marker segment. */ + if (jpc_getuint16(in, &ms->len) || ms->len < 3) { + jpc_ms_destroy(ms); + return 0; + } + /* Calculate the length of the marker segment parameters. */ + ms->len -= 2; + /* Create and prepare a temporary memory stream from which to + read the marker segment parameters. */ + /* Note: This approach provides a simple way of ensuring that + we never read beyond the end of the marker segment (even if + the marker segment length is errantly set too small). */ + if (!(tmpstream = jas_stream_memopen(0, 0))) { + jpc_ms_destroy(ms); + return 0; + } + if (jas_stream_copy(tmpstream, in, ms->len) || + jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) { + jas_stream_close(tmpstream); + jpc_ms_destroy(ms); + return 0; + } + /* Get the marker segment parameters. */ + if ((*ms->ops->getparms)(ms, cstate, tmpstream)) { + ms->ops = 0; + jpc_ms_destroy(ms); + jas_stream_close(tmpstream); + return 0; + } + + if (jas_getdbglevel() > 0) { + jpc_ms_dump(ms, stderr); + } + + if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) { + jas_eprintf("warning: trailing garbage in marker segment (%ld bytes)\n", + ms->len - jas_stream_tell(tmpstream)); + } + + /* Close the temporary stream. */ + jas_stream_close(tmpstream); + + } else { + /* There are no marker segment parameters. */ + ms->len = 0; + + if (jas_getdbglevel() > 0) { + jpc_ms_dump(ms, stderr); + } + } + + /* Update the code stream state information based on the type of + marker segment read. */ + /* Note: This is a bit of a hack, but I'm not going to define another + type of virtual function for this one special case. */ + if (ms->id == JPC_MS_SIZ) { + cstate->numcomps = ms->parms.siz.numcomps; + } + + return ms; +} + +/* Write a marker segment to a stream. */ +int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms) +{ + jas_stream_t *tmpstream; + int len; + + /* Output the marker segment type. */ + if (jpc_putuint16(out, ms->id)) { + return -1; + } + + /* Output the marker segment length and parameters if necessary. */ + if (ms->ops->putparms) { + /* Create a temporary stream in which to buffer the + parameter data. */ + if (!(tmpstream = jas_stream_memopen(0, 0))) { + return -1; + } + if ((*ms->ops->putparms)(ms, cstate, tmpstream)) { + jas_stream_close(tmpstream); + return -1; + } + /* Get the number of bytes of parameter data written. */ + if ((len = jas_stream_tell(tmpstream)) < 0) { + jas_stream_close(tmpstream); + return -1; + } + ms->len = len; + /* Write the marker segment length and parameter data to + the output stream. */ + if (jas_stream_seek(tmpstream, 0, SEEK_SET) < 0 || + jpc_putuint16(out, ms->len + 2) || + jas_stream_copy(out, tmpstream, ms->len) < 0) { + jas_stream_close(tmpstream); + return -1; + } + /* Close the temporary stream. */ + jas_stream_close(tmpstream); + } + + /* This is a bit of a hack, but I'm not going to define another + type of virtual function for this one special case. */ + if (ms->id == JPC_MS_SIZ) { + cstate->numcomps = ms->parms.siz.numcomps; + } + + if (jas_getdbglevel() > 0) { + jpc_ms_dump(ms, stderr); + } + + return 0; +} + +/******************************************************************************\ +* Marker segment operations. +\******************************************************************************/ + +/* Create a marker segment of the specified type. */ +jpc_ms_t *jpc_ms_create(int type) +{ + jpc_ms_t *ms; + jpc_mstabent_t *mstabent; + + if (!(ms = jas_malloc(sizeof(jpc_ms_t)))) { + return 0; + } + ms->id = type; + ms->len = 0; + mstabent = jpc_mstab_lookup(ms->id); + ms->ops = &mstabent->ops; + memset(&ms->parms, 0, sizeof(jpc_msparms_t)); + return ms; +} + +/* Destroy a marker segment. */ +void jpc_ms_destroy(jpc_ms_t *ms) +{ + if (ms->ops && ms->ops->destroyparms) { + (*ms->ops->destroyparms)(ms); + } + jas_free(ms); +} + +/* Dump a marker segment to a stream for debugging. */ +void jpc_ms_dump(jpc_ms_t *ms, FILE *out) +{ + jpc_mstabent_t *mstabent; + mstabent = jpc_mstab_lookup(ms->id); + fprintf(out, "type = 0x%04x (%s);", (unsigned)ms->id, mstabent->name); + if (JPC_MS_HASPARMS(ms->id)) { + fprintf(out, " len = %d;", (int)(ms->len + 2)); + if (ms->ops->dumpparms) { + (*ms->ops->dumpparms)(ms, out); + } else { + fprintf(out, "\n"); + } + } else { + fprintf(out, "\n"); + } +} + +/******************************************************************************\ +* SOT marker segment operations. +\******************************************************************************/ + +static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_sot_t *sot = &ms->parms.sot; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (jpc_getuint16(in, &sot->tileno) || + jpc_getuint32(in, &sot->len) || + jpc_getuint8(in, &sot->partno) || + jpc_getuint8(in, &sot->numparts)) { + return -1; + } + if (jas_stream_eof(in)) { + return -1; + } + return 0; +} + +static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_sot_t *sot = &ms->parms.sot; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (jpc_putuint16(out, sot->tileno) || + jpc_putuint32(out, sot->len) || + jpc_putuint8(out, sot->partno) || + jpc_putuint8(out, sot->numparts)) { + return -1; + } + return 0; +} + +static int jpc_sot_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_sot_t *sot = &ms->parms.sot; + fprintf(out, "tileno = %d; len = %d; partno = %d; numparts = %d\n", + (int)sot->tileno, (int)sot->len, sot->partno, sot->numparts); + return 0; +} + +/******************************************************************************\ +* SIZ marker segment operations. +\******************************************************************************/ + +static void jpc_siz_destroyparms(jpc_ms_t *ms) +{ + jpc_siz_t *siz = &ms->parms.siz; + if (siz->comps) { + jas_free(siz->comps); + } +} + +static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, + jas_stream_t *in) +{ + jpc_siz_t *siz = &ms->parms.siz; + unsigned int i; + uint_fast8_t tmp; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (jpc_getuint16(in, &siz->caps) || + jpc_getuint32(in, &siz->width) || + jpc_getuint32(in, &siz->height) || + jpc_getuint32(in, &siz->xoff) || + jpc_getuint32(in, &siz->yoff) || + jpc_getuint32(in, &siz->tilewidth) || + jpc_getuint32(in, &siz->tileheight) || + jpc_getuint32(in, &siz->tilexoff) || + jpc_getuint32(in, &siz->tileyoff) || + jpc_getuint16(in, &siz->numcomps)) { + return -1; + } + if (!siz->width || !siz->height || !siz->tilewidth || + !siz->tileheight || !siz->numcomps) { + return -1; + } + if (!(siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)))) { + return -1; + } + for (i = 0; i < siz->numcomps; ++i) { + if (jpc_getuint8(in, &tmp) || + jpc_getuint8(in, &siz->comps[i].hsamp) || + jpc_getuint8(in, &siz->comps[i].vsamp)) { + jas_free(siz->comps); + return -1; + } + siz->comps[i].sgnd = (tmp >> 7) & 1; + siz->comps[i].prec = (tmp & 0x7f) + 1; + } + if (jas_stream_eof(in)) { + jas_free(siz->comps); + return -1; + } + return 0; +} + +static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_siz_t *siz = &ms->parms.siz; + unsigned int i; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + assert(siz->width && siz->height && siz->tilewidth && + siz->tileheight && siz->numcomps); + if (jpc_putuint16(out, siz->caps) || + jpc_putuint32(out, siz->width) || + jpc_putuint32(out, siz->height) || + jpc_putuint32(out, siz->xoff) || + jpc_putuint32(out, siz->yoff) || + jpc_putuint32(out, siz->tilewidth) || + jpc_putuint32(out, siz->tileheight) || + jpc_putuint32(out, siz->tilexoff) || + jpc_putuint32(out, siz->tileyoff) || + jpc_putuint16(out, siz->numcomps)) { + return -1; + } + for (i = 0; i < siz->numcomps; ++i) { + if (jpc_putuint8(out, ((siz->comps[i].sgnd & 1) << 7) | + ((siz->comps[i].prec - 1) & 0x7f)) || + jpc_putuint8(out, siz->comps[i].hsamp) || + jpc_putuint8(out, siz->comps[i].vsamp)) { + return -1; + } + } + return 0; +} + +static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_siz_t *siz = &ms->parms.siz; + unsigned int i; + fprintf(out, "caps = 0x%02x;\n", (unsigned)siz->caps); + fprintf(out, "width = %d; height = %d; xoff = %d; yoff = %d;\n", + (int)siz->width, (int)siz->height, (int)siz->xoff, (int)siz->yoff); + fprintf(out, "tilewidth = %d; tileheight = %d; tilexoff = %d; " + "tileyoff = %d;\n", (int)siz->tilewidth, (int)siz->tileheight, (int)siz->tilexoff, + (int)siz->tileyoff); + for (i = 0; i < siz->numcomps; ++i) { + fprintf(out, "prec[%d] = %d; sgnd[%d] = %d; hsamp[%d] = %d; " + "vsamp[%d] = %d\n", i, siz->comps[i].prec, i, + siz->comps[i].sgnd, i, siz->comps[i].hsamp, i, + siz->comps[i].vsamp); + } + return 0; +} + +/******************************************************************************\ +* COD marker segment operations. +\******************************************************************************/ + +static void jpc_cod_destroyparms(jpc_ms_t *ms) +{ + jpc_cod_t *cod = &ms->parms.cod; + jpc_cox_destroycompparms(&cod->compparms); +} + +static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_cod_t *cod = &ms->parms.cod; + if (jpc_getuint8(in, &cod->csty)) { + return -1; + } + if (jpc_getuint8(in, &cod->prg) || + jpc_getuint16(in, &cod->numlyrs) || + jpc_getuint8(in, &cod->mctrans)) { + return -1; + } + if (jpc_cox_getcompparms(ms, cstate, in, + (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) { + return -1; + } + if (jas_stream_eof(in)) { + jpc_cod_destroyparms(ms); + return -1; + } + return 0; +} + +static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_cod_t *cod = &ms->parms.cod; + assert(cod->numlyrs > 0 && cod->compparms.numdlvls <= 32); + assert(cod->compparms.numdlvls == cod->compparms.numrlvls - 1); + if (jpc_putuint8(out, cod->compparms.csty) || + jpc_putuint8(out, cod->prg) || + jpc_putuint16(out, cod->numlyrs) || + jpc_putuint8(out, cod->mctrans)) { + return -1; + } + if (jpc_cox_putcompparms(ms, cstate, out, + (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) { + return -1; + } + return 0; +} + +static int jpc_cod_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_cod_t *cod = &ms->parms.cod; + int i; + fprintf(out, "csty = 0x%02x;\n", cod->compparms.csty); + fprintf(out, "numdlvls = %d; qmfbid = %d; mctrans = %d\n", + cod->compparms.numdlvls, cod->compparms.qmfbid, cod->mctrans); + fprintf(out, "prg = %d; numlyrs = %d;\n", + cod->prg, (int)cod->numlyrs); + fprintf(out, "cblkwidthval = %d; cblkheightval = %d; " + "cblksty = 0x%02x;\n", cod->compparms.cblkwidthval, cod->compparms.cblkheightval, + cod->compparms.cblksty); + if (cod->csty & JPC_COX_PRT) { + for (i = 0; i < cod->compparms.numrlvls; ++i) { + jas_eprintf("prcwidth[%d] = %d, prcheight[%d] = %d\n", + i, cod->compparms.rlvls[i].parwidthval, + i, cod->compparms.rlvls[i].parheightval); + } + } + return 0; +} + +/******************************************************************************\ +* COC marker segment operations. +\******************************************************************************/ + +static void jpc_coc_destroyparms(jpc_ms_t *ms) +{ + jpc_coc_t *coc = &ms->parms.coc; + jpc_cox_destroycompparms(&coc->compparms); +} + +static int jpc_coc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_coc_t *coc = &ms->parms.coc; + uint_fast8_t tmp; + if (cstate->numcomps <= 256) { + if (jpc_getuint8(in, &tmp)) { + return -1; + } + coc->compno = tmp; + } else { + if (jpc_getuint16(in, &coc->compno)) { + return -1; + } + } + if (jpc_getuint8(in, &coc->compparms.csty)) { + return -1; + } + if (jpc_cox_getcompparms(ms, cstate, in, + (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) { + return -1; + } + if (jas_stream_eof(in)) { + return -1; + } + return 0; +} + +static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_coc_t *coc = &ms->parms.coc; + assert(coc->compparms.numdlvls <= 32); + if (cstate->numcomps <= 256) { + if (jpc_putuint8(out, coc->compno)) { + return -1; + } + } else { + if (jpc_putuint16(out, coc->compno)) { + return -1; + } + } + if (jpc_putuint8(out, coc->compparms.csty)) { + return -1; + } + if (jpc_cox_putcompparms(ms, cstate, out, + (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) { + return -1; + } + return 0; +} + +static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_coc_t *coc = &ms->parms.coc; + fprintf(out, "compno = %d; csty = 0x%02x; numdlvls = %d;\n", + (int)coc->compno, coc->compparms.csty, coc->compparms.numdlvls); + fprintf(out, "cblkwidthval = %d; cblkheightval = %d; " + "cblksty = 0x%02x; qmfbid = %d;\n", coc->compparms.cblkwidthval, + coc->compparms.cblkheightval, coc->compparms.cblksty, coc->compparms.qmfbid); + return 0; +} +/******************************************************************************\ +* COD/COC marker segment operation helper functions. +\******************************************************************************/ + +static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms) +{ + /* Eliminate compiler warning about unused variables. */ + compparms = 0; +} + +static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, + jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms) +{ + uint_fast8_t tmp; + int i; + + /* Eliminate compiler warning about unused variables. */ + ms = 0; + cstate = 0; + + if (jpc_getuint8(in, &compparms->numdlvls) || + jpc_getuint8(in, &compparms->cblkwidthval) || + jpc_getuint8(in, &compparms->cblkheightval) || + jpc_getuint8(in, &compparms->cblksty) || + jpc_getuint8(in, &compparms->qmfbid)) { + return -1; + } + compparms->numrlvls = compparms->numdlvls + 1; + if (compparms->numrlvls > JPC_MAXRLVLS) { + jpc_cox_destroycompparms(compparms); + return -1; + } + if (prtflag) { + for (i = 0; i < compparms->numrlvls; ++i) { + if (jpc_getuint8(in, &tmp)) { + jpc_cox_destroycompparms(compparms); + return -1; + } + compparms->rlvls[i].parwidthval = tmp & 0xf; + compparms->rlvls[i].parheightval = (tmp >> 4) & 0xf; + } +/* Sigh. This bit should be in the same field in both COC and COD mrk segs. */ +compparms->csty |= JPC_COX_PRT; + } else { + } + if (jas_stream_eof(in)) { + jpc_cox_destroycompparms(compparms); + return -1; + } + return 0; +} + +static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, + jas_stream_t *out, int prtflag, jpc_coxcp_t *compparms) +{ + int i; + assert(compparms->numdlvls <= 32); + + /* Eliminate compiler warning about unused variables. */ + ms = 0; + cstate = 0; + + if (jpc_putuint8(out, compparms->numdlvls) || + jpc_putuint8(out, compparms->cblkwidthval) || + jpc_putuint8(out, compparms->cblkheightval) || + jpc_putuint8(out, compparms->cblksty) || + jpc_putuint8(out, compparms->qmfbid)) { + return -1; + } + if (prtflag) { + for (i = 0; i < compparms->numrlvls; ++i) { + if (jpc_putuint8(out, + ((compparms->rlvls[i].parheightval & 0xf) << 4) | + (compparms->rlvls[i].parwidthval & 0xf))) { + return -1; + } + } + } + return 0; +} + +/******************************************************************************\ +* RGN marker segment operations. +\******************************************************************************/ + +static int jpc_rgn_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_rgn_t *rgn = &ms->parms.rgn; + uint_fast8_t tmp; + if (cstate->numcomps <= 256) { + if (jpc_getuint8(in, &tmp)) { + return -1; + } + rgn->compno = tmp; + } else { + if (jpc_getuint16(in, &rgn->compno)) { + return -1; + } + } + if (jpc_getuint8(in, &rgn->roisty) || + jpc_getuint8(in, &rgn->roishift)) { + return -1; + } + return 0; +} + +static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_rgn_t *rgn = &ms->parms.rgn; + if (cstate->numcomps <= 256) { + if (jpc_putuint8(out, rgn->compno)) { + return -1; + } + } else { + if (jpc_putuint16(out, rgn->compno)) { + return -1; + } + } + if (jpc_putuint8(out, rgn->roisty) || + jpc_putuint8(out, rgn->roishift)) { + return -1; + } + return 0; +} + +static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_rgn_t *rgn = &ms->parms.rgn; + fprintf(out, "compno = %d; roisty = %d; roishift = %d\n", + (int)rgn->compno, rgn->roisty, rgn->roishift); + return 0; +} + +/******************************************************************************\ +* QCD marker segment operations. +\******************************************************************************/ + +static void jpc_qcd_destroyparms(jpc_ms_t *ms) +{ + jpc_qcd_t *qcd = &ms->parms.qcd; + jpc_qcx_destroycompparms(&qcd->compparms); +} + +static int jpc_qcd_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms; + return jpc_qcx_getcompparms(compparms, cstate, in, ms->len); +} + +static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms; + return jpc_qcx_putcompparms(compparms, cstate, out); +} + +static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_qcd_t *qcd = &ms->parms.qcd; + int i; + fprintf(out, "qntsty = %d; numguard = %d; numstepsizes = %d\n", + (int) qcd->compparms.qntsty, qcd->compparms.numguard, qcd->compparms.numstepsizes); + for (i = 0; i < qcd->compparms.numstepsizes; ++i) { + fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n", + i, (unsigned) JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i]), + i, (unsigned) JPC_QCX_GETMANT(qcd->compparms.stepsizes[i])); + } + return 0; +} + +/******************************************************************************\ +* QCC marker segment operations. +\******************************************************************************/ + +static void jpc_qcc_destroyparms(jpc_ms_t *ms) +{ + jpc_qcc_t *qcc = &ms->parms.qcc; + jpc_qcx_destroycompparms(&qcc->compparms); +} + +static int jpc_qcc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_qcc_t *qcc = &ms->parms.qcc; + uint_fast8_t tmp; + int len; + len = ms->len; + if (cstate->numcomps <= 256) { + jpc_getuint8(in, &tmp); + qcc->compno = tmp; + --len; + } else { + jpc_getuint16(in, &qcc->compno); + len -= 2; + } + if (jpc_qcx_getcompparms(&qcc->compparms, cstate, in, len)) { + return -1; + } + if (jas_stream_eof(in)) { + jpc_qcc_destroyparms(ms); + return -1; + } + return 0; +} + +static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_qcc_t *qcc = &ms->parms.qcc; + if (cstate->numcomps <= 256) { + jpc_putuint8(out, qcc->compno); + } else { + jpc_putuint16(out, qcc->compno); + } + if (jpc_qcx_putcompparms(&qcc->compparms, cstate, out)) { + return -1; + } + return 0; +} + +static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_qcc_t *qcc = &ms->parms.qcc; + int i; + fprintf(out, "compno = %d; qntsty = %d; numguard = %d; " + "numstepsizes = %d\n", (int)qcc->compno, qcc->compparms.qntsty, qcc->compparms.numguard, + qcc->compparms.numstepsizes); + for (i = 0; i < qcc->compparms.numstepsizes; ++i) { + fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n", + i, (unsigned) JPC_QCX_GETEXPN(qcc->compparms.stepsizes[i]), + i, (unsigned) JPC_QCX_GETMANT(qcc->compparms.stepsizes[i])); + } + return 0; +} + +/******************************************************************************\ +* QCD/QCC marker segment helper functions. +\******************************************************************************/ + +static void jpc_qcx_destroycompparms(jpc_qcxcp_t *compparms) +{ + if (compparms->stepsizes) { + jas_free(compparms->stepsizes); + } +} + +static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, + jas_stream_t *in, uint_fast16_t len) +{ + uint_fast8_t tmp; + int n; + int i; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + n = 0; + jpc_getuint8(in, &tmp); + ++n; + compparms->qntsty = tmp & 0x1f; + compparms->numguard = (tmp >> 5) & 7; + switch (compparms->qntsty) { + case JPC_QCX_SIQNT: + compparms->numstepsizes = 1; + break; + case JPC_QCX_NOQNT: + compparms->numstepsizes = (len - n); + break; + case JPC_QCX_SEQNT: + /* XXX - this is a hack */ + compparms->numstepsizes = (len - n) / 2; + break; + } + if (compparms->numstepsizes > 3 * JPC_MAXRLVLS + 1) { + jpc_qcx_destroycompparms(compparms); + return -1; + } else if (compparms->numstepsizes > 0) { + compparms->stepsizes = jas_malloc(compparms->numstepsizes * + sizeof(uint_fast16_t)); + assert(compparms->stepsizes); + for (i = 0; i < compparms->numstepsizes; ++i) { + if (compparms->qntsty == JPC_QCX_NOQNT) { + jpc_getuint8(in, &tmp); + compparms->stepsizes[i] = JPC_QCX_EXPN(tmp >> 3); + } else { + jpc_getuint16(in, &compparms->stepsizes[i]); + } + } + } else { + compparms->stepsizes = 0; + } + if (jas_stream_error(in) || jas_stream_eof(in)) { + jpc_qcx_destroycompparms(compparms); + return -1; + } + return 0; +} + +static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, + jas_stream_t *out) +{ + int i; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + jpc_putuint8(out, ((compparms->numguard & 7) << 5) | compparms->qntsty); + for (i = 0; i < compparms->numstepsizes; ++i) { + if (compparms->qntsty == JPC_QCX_NOQNT) { + jpc_putuint8(out, JPC_QCX_GETEXPN( + compparms->stepsizes[i]) << 3); + } else { + jpc_putuint16(out, compparms->stepsizes[i]); + } + } + return 0; +} + +/******************************************************************************\ +* SOP marker segment operations. +\******************************************************************************/ + +static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_sop_t *sop = &ms->parms.sop; + + /* Eliminate compiler warning about unused variable. */ + cstate = 0; + + if (jpc_getuint16(in, &sop->seqno)) { + return -1; + } + return 0; +} + +static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_sop_t *sop = &ms->parms.sop; + + /* Eliminate compiler warning about unused variable. */ + cstate = 0; + + if (jpc_putuint16(out, sop->seqno)) { + return -1; + } + return 0; +} + +static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_sop_t *sop = &ms->parms.sop; + fprintf(out, "seqno = %d;\n", (int)sop->seqno); + return 0; +} + +/******************************************************************************\ +* PPM marker segment operations. +\******************************************************************************/ + +static void jpc_ppm_destroyparms(jpc_ms_t *ms) +{ + jpc_ppm_t *ppm = &ms->parms.ppm; + if (ppm->data) { + jas_free(ppm->data); + } +} + +static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_ppm_t *ppm = &ms->parms.ppm; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + ppm->data = 0; + + if (ms->len < 1) { + goto error; + } + if (jpc_getuint8(in, &ppm->ind)) { + goto error; + } + + ppm->len = ms->len - 1; + if (ppm->len > 0) { + if (!(ppm->data = jas_malloc(ppm->len))) { + goto error; + } + if (JAS_CAST(uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) { + goto error; + } + } else { + ppm->data = 0; + } + return 0; + +error: + jpc_ppm_destroyparms(ms); + return -1; +} + +static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_ppm_t *ppm = &ms->parms.ppm; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (JAS_CAST(uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) { + return -1; + } + return 0; +} + +static int jpc_ppm_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_ppm_t *ppm = &ms->parms.ppm; + fprintf(out, "ind=%d; len = %d;\n", ppm->ind, (int)ppm->len); + if (ppm->len > 0) { + fprintf(out, "data =\n"); + jas_memdump(out, ppm->data, ppm->len); + } + return 0; +} + +/******************************************************************************\ +* PPT marker segment operations. +\******************************************************************************/ + +static void jpc_ppt_destroyparms(jpc_ms_t *ms) +{ + jpc_ppt_t *ppt = &ms->parms.ppt; + if (ppt->data) { + jas_free(ppt->data); + } +} + +static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_ppt_t *ppt = &ms->parms.ppt; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + ppt->data = 0; + + if (ms->len < 1) { + goto error; + } + if (jpc_getuint8(in, &ppt->ind)) { + goto error; + } + ppt->len = ms->len - 1; + if (ppt->len > 0) { + if (!(ppt->data = jas_malloc(ppt->len))) { + goto error; + } + if (jas_stream_read(in, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) { + goto error; + } + } else { + ppt->data = 0; + } + return 0; + +error: + jpc_ppt_destroyparms(ms); + return -1; +} + +static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_ppt_t *ppt = &ms->parms.ppt; + + /* Eliminate compiler warning about unused variable. */ + cstate = 0; + + if (jpc_putuint8(out, ppt->ind)) { + return -1; + } + if (jas_stream_write(out, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) { + return -1; + } + return 0; +} + +static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_ppt_t *ppt = &ms->parms.ppt; + fprintf(out, "ind=%d; len = %d;\n", ppt->ind, (int)ppt->len); + if (ppt->len > 0) { + fprintf(out, "data =\n"); + jas_memdump(out, ppt->data, ppt->len); + } + return 0; +} + +/******************************************************************************\ +* POC marker segment operations. +\******************************************************************************/ + +static void jpc_poc_destroyparms(jpc_ms_t *ms) +{ + jpc_poc_t *poc = &ms->parms.poc; + if (poc->pchgs) { + jas_free(poc->pchgs); + } +} + +static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_poc_t *poc = &ms->parms.poc; + jpc_pocpchg_t *pchg; + int pchgno; + uint_fast8_t tmp; + poc->numpchgs = (cstate->numcomps > 256) ? (ms->len / 9) : + (ms->len / 7); + if (!(poc->pchgs = jas_alloc2(poc->numpchgs, sizeof(jpc_pocpchg_t)))) { + goto error; + } + for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno, + ++pchg) { + if (jpc_getuint8(in, &pchg->rlvlnostart)) { + goto error; + } + if (cstate->numcomps > 256) { + if (jpc_getuint16(in, &pchg->compnostart)) { + goto error; + } + } else { + if (jpc_getuint8(in, &tmp)) { + goto error; + }; + pchg->compnostart = tmp; + } + if (jpc_getuint16(in, &pchg->lyrnoend) || + jpc_getuint8(in, &pchg->rlvlnoend)) { + goto error; + } + if (cstate->numcomps > 256) { + if (jpc_getuint16(in, &pchg->compnoend)) { + goto error; + } + } else { + if (jpc_getuint8(in, &tmp)) { + goto error; + } + pchg->compnoend = tmp; + } + if (jpc_getuint8(in, &pchg->prgord)) { + goto error; + } + if (pchg->rlvlnostart > pchg->rlvlnoend || + pchg->compnostart > pchg->compnoend) { + goto error; + } + } + return 0; + +error: + jpc_poc_destroyparms(ms); + return -1; +} + +static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_poc_t *poc = &ms->parms.poc; + jpc_pocpchg_t *pchg; + int pchgno; + for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno, + ++pchg) { + if (jpc_putuint8(out, pchg->rlvlnostart) || + ((cstate->numcomps > 256) ? + jpc_putuint16(out, pchg->compnostart) : + jpc_putuint8(out, pchg->compnostart)) || + jpc_putuint16(out, pchg->lyrnoend) || + jpc_putuint8(out, pchg->rlvlnoend) || + ((cstate->numcomps > 256) ? + jpc_putuint16(out, pchg->compnoend) : + jpc_putuint8(out, pchg->compnoend)) || + jpc_putuint8(out, pchg->prgord)) { + return -1; + } + } + return 0; +} + +static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_poc_t *poc = &ms->parms.poc; + jpc_pocpchg_t *pchg; + int pchgno; + for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; + ++pchgno, ++pchg) { + fprintf(out, "po[%d] = %d; ", pchgno, pchg->prgord); + fprintf(out, "cs[%d] = %d; ce[%d] = %d; ", + pchgno, (int)pchg->compnostart, pchgno, (int)pchg->compnoend); + fprintf(out, "rs[%d] = %d; re[%d] = %d; ", + pchgno, pchg->rlvlnostart, pchgno, pchg->rlvlnoend); + fprintf(out, "le[%d] = %d\n", pchgno, (int)pchg->lyrnoend); + } + return 0; +} + +/******************************************************************************\ +* CRG marker segment operations. +\******************************************************************************/ + +static void jpc_crg_destroyparms(jpc_ms_t *ms) +{ + jpc_crg_t *crg = &ms->parms.crg; + if (crg->comps) { + jas_free(crg->comps); + } +} + +static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_crg_t *crg = &ms->parms.crg; + jpc_crgcomp_t *comp; + uint_fast16_t compno; + crg->numcomps = cstate->numcomps; + if (!(crg->comps = jas_alloc2(cstate->numcomps, sizeof(jpc_crgcomp_t)))) { + return -1; + } + for (compno = 0, comp = crg->comps; compno < cstate->numcomps; + ++compno, ++comp) { + if (jpc_getuint16(in, &comp->hoff) || + jpc_getuint16(in, &comp->voff)) { + jpc_crg_destroyparms(ms); + return -1; + } + } + return 0; +} + +static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_crg_t *crg = &ms->parms.crg; + int compno; + jpc_crgcomp_t *comp; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno, + ++comp) { + if (jpc_putuint16(out, comp->hoff) || + jpc_putuint16(out, comp->voff)) { + return -1; + } + } + return 0; +} + +static int jpc_crg_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_crg_t *crg = &ms->parms.crg; + int compno; + jpc_crgcomp_t *comp; + for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno, + ++comp) { + fprintf(out, "hoff[%d] = %d; voff[%d] = %d\n", compno, + (int)comp->hoff, compno, (int)comp->voff); + } + return 0; +} + +/******************************************************************************\ +* Operations for COM marker segment. +\******************************************************************************/ + +static void jpc_com_destroyparms(jpc_ms_t *ms) +{ + jpc_com_t *com = &ms->parms.com; + if (com->data) { + jas_free(com->data); + } +} + +static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_com_t *com = &ms->parms.com; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (jpc_getuint16(in, &com->regid)) { + return -1; + } + com->len = ms->len - 2; + if (com->len > 0) { + if (!(com->data = jas_malloc(com->len))) { + return -1; + } + if (jas_stream_read(in, com->data, com->len) != JAS_CAST(int, com->len)) { + return -1; + } + } else { + com->data = 0; + } + return 0; +} + +static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + jpc_com_t *com = &ms->parms.com; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (jpc_putuint16(out, com->regid)) { + return -1; + } + if (jas_stream_write(out, com->data, com->len) != JAS_CAST(int, com->len)) { + return -1; + } + return 0; +} + +static int jpc_com_dumpparms(jpc_ms_t *ms, FILE *out) +{ + jpc_com_t *com = &ms->parms.com; + unsigned int i; + int printable; + fprintf(out, "regid = %d;\n", (int)com->regid); + printable = 1; + for (i = 0; i < com->len; ++i) { + if (!isprint(com->data[i])) { + printable = 0; + break; + } + } + if (printable) { + fprintf(out, "data = "); + fwrite(com->data, sizeof(char), com->len, out); + fprintf(out, "\n"); + } + return 0; +} + +/******************************************************************************\ +* Operations for unknown types of marker segments. +\******************************************************************************/ + +static void jpc_unk_destroyparms(jpc_ms_t *ms) +{ + jpc_unk_t *unk = &ms->parms.unk; + if (unk->data) { + jas_free(unk->data); + } +} + +static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) +{ + jpc_unk_t *unk = &ms->parms.unk; + + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + + if (ms->len > 0) { + if (!(unk->data = jas_malloc(ms->len))) { + return -1; + } + if (jas_stream_read(in, (char *) unk->data, ms->len) != JAS_CAST(int, ms->len)) { + jas_free(unk->data); + return -1; + } + unk->len = ms->len; + } else { + unk->data = 0; + unk->len = 0; + } + return 0; +} + +static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out) +{ + /* Eliminate compiler warning about unused variables. */ + cstate = 0; + ms = 0; + out = 0; + + /* If this function is called, we are trying to write an unsupported + type of marker segment. Return with an error indication. */ + return -1; +} + +static int jpc_unk_dumpparms(jpc_ms_t *ms, FILE *out) +{ + unsigned int i; + jpc_unk_t *unk = &ms->parms.unk; + for (i = 0; i < unk->len; ++i) { + fprintf(out, "%02x ", unk->data[i]); + } + return 0; +} + +/******************************************************************************\ +* Primitive I/O operations. +\******************************************************************************/ + +int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val) +{ + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + if (val) { + *val = c; + } + return 0; +} + +int jpc_putuint8(jas_stream_t *out, uint_fast8_t val) +{ + if (jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +int jpc_getuint16(jas_stream_t *in, uint_fast16_t *val) +{ + uint_fast16_t v; + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if (val) { + *val = v; + } + return 0; +} + +int jpc_putuint16(jas_stream_t *out, uint_fast16_t val) +{ + if (jas_stream_putc(out, (val >> 8) & 0xff) == EOF || + jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +int jpc_getuint32(jas_stream_t *in, uint_fast32_t *val) +{ + uint_fast32_t v; + int c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if ((c = jas_stream_getc(in)) == EOF) { + return -1; + } + v = (v << 8) | c; + if (val) { + *val = v; + } + return 0; +} + +int jpc_putuint32(jas_stream_t *out, uint_fast32_t val) +{ + if (jas_stream_putc(out, (val >> 24) & 0xff) == EOF || + jas_stream_putc(out, (val >> 16) & 0xff) == EOF || + jas_stream_putc(out, (val >> 8) & 0xff) == EOF || + jas_stream_putc(out, val & 0xff) == EOF) { + return -1; + } + return 0; +} + +/******************************************************************************\ +* Miscellany +\******************************************************************************/ + +static jpc_mstabent_t *jpc_mstab_lookup(int id) +{ + jpc_mstabent_t *mstabent; + for (mstabent = jpc_mstab;; ++mstabent) { + if (mstabent->id == id || mstabent->id < 0) { + return mstabent; + } + } + assert(0); + return 0; +} + +int jpc_validate(jas_stream_t *in) +{ + int n; + int i; + unsigned char buf[2]; + + assert(JAS_STREAM_MAXPUTBACK >= 2); + + if ((n = jas_stream_read(in, (char *) buf, 2)) < 0) { + return -1; + } + for (i = n - 1; i >= 0; --i) { + if (jas_stream_ungetc(in, buf[i]) == EOF) { + return -1; + } + } + if (n < 2) { + return -1; + } + if (buf[0] == (JPC_MS_SOC >> 8) && buf[1] == (JPC_MS_SOC & 0xff)) { + return 0; + } + return -1; +} + +int jpc_getdata(jas_stream_t *in, jas_stream_t *out, long len) +{ + return jas_stream_copy(out, in, len); +} + +int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long len) +{ + return jas_stream_copy(out, in, len); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_cs.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,763 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JPEG-2000 Code Stream Library + * + * $Id: jpc_cs.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_CS_H +#define JPC_CS_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_image.h" +#include "jasper/jas_stream.h" + +#include "jpc_cod.h" + +/******************************************************************************\ +* Constants and Types. +\******************************************************************************/ + +/* The maximum number of resolution levels. */ +#define JPC_MAXRLVLS 33 + +/* The maximum number of bands. */ +#define JPC_MAXBANDS (3 * JPC_MAXRLVLS + 1) + +/* The maximum number of layers. */ +#define JPC_MAXLYRS 16384 + +/**************************************\ +* Code stream. +\**************************************/ + +/* + * Code stream states. + */ + +/* Initial. */ +#define JPC_CS_INIT 0 +/* Main header. */ +#define JPC_CS_MHDR 1 +/* Tile-part header. */ +#define JPC_CS_THDR 2 +/* Main trailer. */ +#define JPC_CS_MTLR 3 +/* Tile-part data. */ +#define JPC_CS_TDATA 4 + +/* + * Unfortunately, the code stream syntax was not designed in such a way that + * any given marker segment can be correctly decoded without additional state + * derived from previously decoded marker segments. + * For example, a RGN/COC/QCC marker segment cannot be decoded unless the + * number of components is known. + */ + +/* + * Code stream state information. + */ + +typedef struct { + + /* The number of components. */ + uint_fast16_t numcomps; + +} jpc_cstate_t; + +/**************************************\ +* SOT marker segment parameters. +\**************************************/ + +typedef struct { + + /* The tile number. */ + uint_fast16_t tileno; + + /* The combined length of the marker segment and its auxilary data + (i.e., packet data). */ + uint_fast32_t len; + + /* The tile-part instance. */ + uint_fast8_t partno; + + /* The number of tile-parts. */ + uint_fast8_t numparts; + +} jpc_sot_t; + +/**************************************\ +* SIZ marker segment parameters. +\**************************************/ + +/* Per component information. */ + +typedef struct { + + /* The precision of the samples. */ + uint_fast8_t prec; + + /* The signedness of the samples. */ + uint_fast8_t sgnd; + + /* The horizontal separation of samples with respect to the reference + grid. */ + uint_fast8_t hsamp; + + /* The vertical separation of samples with respect to the reference + grid. */ + uint_fast8_t vsamp; + +} jpc_sizcomp_t; + +/* SIZ marker segment parameters. */ + +typedef struct { + + /* The code stream capabilities. */ + uint_fast16_t caps; + + /* The width of the image in units of the reference grid. */ + uint_fast32_t width; + + /* The height of the image in units of the reference grid. */ + uint_fast32_t height; + + /* The horizontal offset from the origin of the reference grid to the + left side of the image area. */ + uint_fast32_t xoff; + + /* The vertical offset from the origin of the reference grid to the + top side of the image area. */ + uint_fast32_t yoff; + + /* The nominal width of a tile in units of the reference grid. */ + uint_fast32_t tilewidth; + + /* The nominal height of a tile in units of the reference grid. */ + uint_fast32_t tileheight; + + /* The horizontal offset from the origin of the reference grid to the + left side of the first tile. */ + uint_fast32_t tilexoff; + + /* The vertical offset from the origin of the reference grid to the + top side of the first tile. */ + uint_fast32_t tileyoff; + + /* The number of components. */ + uint_fast16_t numcomps; + + /* The per-component information. */ + jpc_sizcomp_t *comps; + +} jpc_siz_t; + +/**************************************\ +* COD marker segment parameters. +\**************************************/ + +/* + * Coding style constants. + */ + +/* Precincts may be used. */ +#define JPC_COX_PRT 0x01 +/* SOP marker segments may be used. */ +#define JPC_COD_SOP 0x02 +/* EPH marker segments may be used. */ +#define JPC_COD_EPH 0x04 + +/* + * Progression order constants. + */ + +/* Layer-resolution-component-precinct progressive + (i.e., progressive by fidelity). */ +#define JPC_COD_LRCPPRG 0 +/* Resolution-layer-component-precinct progressive + (i.e., progressive by resolution). */ +#define JPC_COD_RLCPPRG 1 +/* Resolution-precinct-component-layer progressive. */ +#define JPC_COD_RPCLPRG 2 +/* Precinct-component-resolution-layer progressive. */ +#define JPC_COD_PCRLPRG 3 +/* Component-position-resolution-layer progressive. */ +#define JPC_COD_CPRLPRG 4 + +/* + * Code block style constants. + */ + +#define JPC_COX_LAZY 0x01 /* Selective arithmetic coding bypass. */ +#define JPC_COX_RESET 0x02 /* Reset context probabilities. */ +#define JPC_COX_TERMALL 0x04 /* Terminate all coding passes. */ +#define JPC_COX_VSC 0x08 /* Vertical stripe causal context formation. */ +#define JPC_COX_PTERM 0x10 /* Predictable termination. */ +#define JPC_COX_SEGSYM 0x20 /* Use segmentation symbols. */ + +/* Transform constants. */ +#define JPC_COX_INS 0x00 /* Irreversible 9/7. */ +#define JPC_COX_RFT 0x01 /* Reversible 5/3. */ + +/* Multicomponent transform constants. */ +#define JPC_COD_NOMCT 0x00 /* No multicomponent transform. */ +#define JPC_COD_MCT 0x01 /* Multicomponent transform. */ + +/* Get the code block size value from the code block size exponent. */ +#define JPC_COX_CBLKSIZEEXPN(x) ((x) - 2) +/* Get the code block size exponent from the code block size value. */ +#define JPC_COX_GETCBLKSIZEEXPN(x) ((x) + 2) + +/* Per resolution-level information. */ + +typedef struct { + + /* The packet partition width. */ + uint_fast8_t parwidthval; + + /* The packet partition height. */ + uint_fast8_t parheightval; + +} jpc_coxrlvl_t; + +/* Per component information. */ + +typedef struct { + + /* The coding style. */ + uint_fast8_t csty; + + /* The number of decomposition levels. */ + uint_fast8_t numdlvls; + + /* The nominal code block width specifier. */ + uint_fast8_t cblkwidthval; + + /* The nominal code block height specifier. */ + uint_fast8_t cblkheightval; + + /* The style of coding passes. */ + uint_fast8_t cblksty; + + /* The QMFB employed. */ + uint_fast8_t qmfbid; + + /* The number of resolution levels. */ + int numrlvls; + + /* The per-resolution-level information. */ + jpc_coxrlvl_t rlvls[JPC_MAXRLVLS]; + +} jpc_coxcp_t; + +/* COD marker segment parameters. */ + +typedef struct { + + /* The general coding style. */ + uint_fast8_t csty; + + /* The progression order. */ + uint_fast8_t prg; + + /* The number of layers. */ + uint_fast16_t numlyrs; + + /* The multicomponent transform. */ + uint_fast8_t mctrans; + + /* Component-related parameters. */ + jpc_coxcp_t compparms; + +} jpc_cod_t; + +/* COC marker segment parameters. */ + +typedef struct { + + /* The component number. */ + uint_fast16_t compno; + + /* Component-related parameters. */ + jpc_coxcp_t compparms; + +} jpc_coc_t; + +/**************************************\ +* RGN marker segment parameters. +\**************************************/ + +/* The maxshift ROI style. */ +#define JPC_RGN_MAXSHIFT 0x00 + +typedef struct { + + /* The component to which the marker applies. */ + uint_fast16_t compno; + + /* The ROI style. */ + uint_fast8_t roisty; + + /* The ROI shift value. */ + uint_fast8_t roishift; + +} jpc_rgn_t; + +/**************************************\ +* QCD/QCC marker segment parameters. +\**************************************/ + +/* + * Quantization style constants. + */ + +#define JPC_QCX_NOQNT 0 /* No quantization. */ +#define JPC_QCX_SIQNT 1 /* Scalar quantization, implicit. */ +#define JPC_QCX_SEQNT 2 /* Scalar quantization, explicit. */ + +/* + * Stepsize manipulation macros. + */ + +#define JPC_QCX_GETEXPN(x) ((x) >> 11) +#define JPC_QCX_GETMANT(x) ((x) & 0x07ff) +#define JPC_QCX_EXPN(x) (assert(!((x) & (~0x1f))), (((x) & 0x1f) << 11)) +#define JPC_QCX_MANT(x) (assert(!((x) & (~0x7ff))), ((x) & 0x7ff)) + +/* Per component information. */ + +typedef struct { + + /* The quantization style. */ + uint_fast8_t qntsty; + + /* The number of step sizes. */ + int numstepsizes; + + /* The step sizes. */ + uint_fast16_t *stepsizes; + + /* The number of guard bits. */ + uint_fast8_t numguard; + +} jpc_qcxcp_t; + +/* QCC marker segment parameters. */ + +typedef struct { + + /* The component associated with this marker segment. */ + uint_fast16_t compno; + + /* The parameters. */ + jpc_qcxcp_t compparms; + +} jpc_qcc_t; + +/* QCD marker segment parameters. */ + +typedef struct { + + /* The parameters. */ + jpc_qcxcp_t compparms; + +} jpc_qcd_t; + +/**************************************\ +* POD marker segment parameters. +\**************************************/ + +typedef struct { + + /* The progression order. */ + uint_fast8_t prgord; + + /* The lower bound (inclusive) on the resolution level for the + progression order volume. */ + uint_fast8_t rlvlnostart; + + /* The upper bound (exclusive) on the resolution level for the + progression order volume. */ + uint_fast8_t rlvlnoend; + + /* The lower bound (inclusive) on the component for the progression + order volume. */ + uint_fast16_t compnostart; + + /* The upper bound (exclusive) on the component for the progression + order volume. */ + uint_fast16_t compnoend; + + /* The upper bound (exclusive) on the layer for the progression + order volume. */ + uint_fast16_t lyrnoend; + +} jpc_pocpchg_t; + +/* An alias for the above type. */ +typedef jpc_pocpchg_t jpc_pchg_t; + +/* POC marker segment parameters. */ + +typedef struct { + + /* The number of progression order changes. */ + int numpchgs; + + /* The per-progression-order-change information. */ + jpc_pocpchg_t *pchgs; + +} jpc_poc_t; + +/**************************************\ +* PPM/PPT marker segment parameters. +\**************************************/ + +/* PPM marker segment parameters. */ + +typedef struct { + + /* The index. */ + uint_fast8_t ind; + + /* The length. */ + uint_fast16_t len; + + /* The data. */ + uchar *data; + +} jpc_ppm_t; + +/* PPT marker segment parameters. */ + +typedef struct { + + /* The index. */ + uint_fast8_t ind; + + /* The length. */ + uint_fast32_t len; + + /* The data. */ + unsigned char *data; + +} jpc_ppt_t; + +/**************************************\ +* COM marker segment parameters. +\**************************************/ + +/* + * Registration IDs. + */ + +#define JPC_COM_BIN 0x00 +#define JPC_COM_LATIN 0x01 + +typedef struct { + + /* The registration ID. */ + uint_fast16_t regid; + + /* The length of the data in bytes. */ + uint_fast16_t len; + + /* The data. */ + uchar *data; + +} jpc_com_t; + +/**************************************\ +* SOP marker segment parameters. +\**************************************/ + +typedef struct { + + /* The sequence number. */ + uint_fast16_t seqno; + +} jpc_sop_t; + +/**************************************\ +* CRG marker segment parameters. +\**************************************/ + +/* Per component information. */ + +typedef struct { + + /* The horizontal offset. */ + uint_fast16_t hoff; + + /* The vertical offset. */ + uint_fast16_t voff; + +} jpc_crgcomp_t; + +typedef struct { + + /* The number of components. */ + int numcomps; + + /* Per component information. */ + jpc_crgcomp_t *comps; + +} jpc_crg_t; + +/**************************************\ +* Marker segment parameters for unknown marker type. +\**************************************/ + +typedef struct { + + /* The data. */ + uchar *data; + + /* The length. */ + uint_fast16_t len; + +} jpc_unk_t; + +/**************************************\ +* Generic marker segment parameters. +\**************************************/ + +typedef union { + int soc; /* unused */ + jpc_sot_t sot; + int sod; /* unused */ + int eoc; /* unused */ + jpc_siz_t siz; + jpc_cod_t cod; + jpc_coc_t coc; + jpc_rgn_t rgn; + jpc_qcd_t qcd; + jpc_qcc_t qcc; + jpc_poc_t poc; + /* jpc_plm_t plm; */ + /* jpc_plt_t plt; */ + jpc_ppm_t ppm; + jpc_ppt_t ppt; + jpc_sop_t sop; + int eph; /* unused */ + jpc_com_t com; + jpc_crg_t crg; + jpc_unk_t unk; +} jpc_msparms_t; + +/**************************************\ +* Marker segment. +\**************************************/ + +/* Marker segment IDs. */ + +/* The smallest valid marker value. */ +#define JPC_MS_MIN 0xff00 + +/* The largest valid marker value. */ +#define JPC_MS_MAX 0xffff + +/* The minimum marker value that cannot occur within packet data. */ +#define JPC_MS_INMIN 0xff80 +/* The maximum marker value that cannot occur within packet data. */ +#define JPC_MS_INMAX 0xffff + +/* Delimiting marker segments. */ +#define JPC_MS_SOC 0xff4f /* Start of code stream (SOC). */ +#define JPC_MS_SOT 0xff90 /* Start of tile-part (SOT). */ +#define JPC_MS_SOD 0xff93 /* Start of data (SOD). */ +#define JPC_MS_EOC 0xffd9 /* End of code stream (EOC). */ + +/* Fixed information marker segments. */ +#define JPC_MS_SIZ 0xff51 /* Image and tile size (SIZ). */ + +/* Functional marker segments. */ +#define JPC_MS_COD 0xff52 /* Coding style default (COD). */ +#define JPC_MS_COC 0xff53 /* Coding style component (COC). */ +#define JPC_MS_RGN 0xff5e /* Region of interest (RGN). */ +#define JPC_MS_QCD 0xff5c /* Quantization default (QCD). */ +#define JPC_MS_QCC 0xff5d /* Quantization component (QCC). */ +#define JPC_MS_POC 0xff5f /* Progression order default (POC). */ + +/* Pointer marker segments. */ +#define JPC_MS_TLM 0xff55 /* Tile-part lengths, main header (TLM). */ +#define JPC_MS_PLM 0xff57 /* Packet length, main header (PLM). */ +#define JPC_MS_PLT 0xff58 /* Packet length, tile-part header (PLT). */ +#define JPC_MS_PPM 0xff60 /* Packed packet headers, main header (PPM). */ +#define JPC_MS_PPT 0xff61 /* Packet packet headers, tile-part header (PPT). */ + +/* In bit stream marker segments. */ +#define JPC_MS_SOP 0xff91 /* Start of packet (SOP). */ +#define JPC_MS_EPH 0xff92 /* End of packet header (EPH). */ + +/* Informational marker segments. */ +#define JPC_MS_CRG 0xff63 /* Component registration (CRG). */ +#define JPC_MS_COM 0xff64 /* Comment (COM). */ + +/* Forward declaration. */ +struct jpc_msops_s; + +/* Generic marker segment class. */ + +typedef struct { + + /* The type of marker segment. */ + uint_fast16_t id; + + /* The length of the marker segment. */ + uint_fast16_t len; + + /* The starting offset within the stream. */ + uint_fast32_t off; + + /* The parameters of the marker segment. */ + jpc_msparms_t parms; + + /* The marker segment operations. */ + struct jpc_msops_s *ops; + +} jpc_ms_t; + +/* Marker segment operations (which depend on the marker segment type). */ + +typedef struct jpc_msops_s { + + /* Destroy the marker segment parameters. */ + void (*destroyparms)(jpc_ms_t *ms); + + /* Get the marker segment parameters from a stream. */ + int (*getparms)(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in); + + /* Put the marker segment parameters to a stream. */ + int (*putparms)(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out); + + /* Dump the marker segment parameters (for debugging). */ + int (*dumpparms)(jpc_ms_t *ms, FILE *out); + +} jpc_msops_t; + +/******************************************************************************\ +* Macros/Functions. +\******************************************************************************/ + +/* Create a code-stream state object. */ +jpc_cstate_t *jpc_cstate_create(void); + +/* Destroy a code-stream state object. */ +void jpc_cstate_destroy(jpc_cstate_t *cstate); + +/* Create a marker segment. */ +jpc_ms_t *jpc_ms_create(int type); + +/* Destroy a marker segment. */ +void jpc_ms_destroy(jpc_ms_t *ms); + +/* Does a marker segment have parameters? */ +#define JPC_MS_HASPARMS(x) \ + (!((x) == JPC_MS_SOC || (x) == JPC_MS_SOD || (x) == JPC_MS_EOC || \ + (x) == JPC_MS_EPH || ((x) >= 0xff30 && (x) <= 0xff3f))) + +/* Get the marker segment type. */ +#define jpc_ms_gettype(ms) \ + ((ms)->id) + +/* Read a marker segment from a stream. */ +jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate); + +/* Write a marker segment to a stream. */ +int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms); + +/* Copy code stream data from one stream to another. */ +int jpc_getdata(jas_stream_t *in, jas_stream_t *out, long n); + +/* Copy code stream data from one stream to another. */ +int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long n); + +/* Dump a marker segment (for debugging). */ +void jpc_ms_dump(jpc_ms_t *ms, FILE *out); + +/* Read a 8-bit unsigned integer from a stream. */ +int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val); + +/* Read a 16-bit unsigned integer from a stream. */ +int jpc_getuint16(jas_stream_t *in, uint_fast16_t *val); + +/* Read a 32-bit unsigned integer from a stream. */ +int jpc_getuint32(jas_stream_t *in, uint_fast32_t *val); + +/* Write a 8-bit unsigned integer to a stream. */ +int jpc_putuint8(jas_stream_t *out, uint_fast8_t val); + +/* Write a 16-bit unsigned integer to a stream. */ +int jpc_putuint16(jas_stream_t *out, uint_fast16_t val); + +/* Write a 32-bit unsigned integer to a stream. */ +int jpc_putuint32(jas_stream_t *out, uint_fast32_t val); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2304 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_math.h" +#include "jasper/jas_tvp.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_debug.h" + +#include "jpc_fix.h" +#include "jpc_dec.h" +#include "jpc_cs.h" +#include "jpc_mct.h" +#include "jpc_t2dec.h" +#include "jpc_t1dec.h" +#include "jpc_math.h" + +/******************************************************************************\ +* +\******************************************************************************/ + +#define JPC_MHSOC 0x0001 + /* In the main header, expecting a SOC marker segment. */ +#define JPC_MHSIZ 0x0002 + /* In the main header, expecting a SIZ marker segment. */ +#define JPC_MH 0x0004 + /* In the main header, expecting "other" marker segments. */ +#define JPC_TPHSOT 0x0008 + /* In a tile-part header, expecting a SOT marker segment. */ +#define JPC_TPH 0x0010 + /* In a tile-part header, expecting "other" marker segments. */ +#define JPC_MT 0x0020 + /* In the main trailer. */ + +typedef struct { + + uint_fast16_t id; + /* The marker segment type. */ + + int validstates; + /* The states in which this type of marker segment can be + validly encountered. */ + + int (*action)(jpc_dec_t *dec, jpc_ms_t *ms); + /* The action to take upon encountering this type of marker segment. */ + +} jpc_dec_mstabent_t; + +/******************************************************************************\ +* +\******************************************************************************/ + +/* COD/COC parameters have been specified. */ +#define JPC_CSET 0x0001 +/* QCD/QCC parameters have been specified. */ +#define JPC_QSET 0x0002 +/* COD/COC parameters set from a COC marker segment. */ +#define JPC_COC 0x0004 +/* QCD/QCC parameters set from a QCC marker segment. */ +#define JPC_QCC 0x0008 + +/******************************************************************************\ +* Local function prototypes. +\******************************************************************************/ + +static int jpc_dec_dump(jpc_dec_t *dec, FILE *out); + +jpc_ppxstab_t *jpc_ppxstab_create(void); +void jpc_ppxstab_destroy(jpc_ppxstab_t *tab); +int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents); +int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent); +jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab); +int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab); +jpc_ppxstabent_t *jpc_ppxstabent_create(void); +void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent); + +int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist); +jpc_streamlist_t *jpc_streamlist_create(void); +int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno, + jas_stream_t *stream); +jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno); +void jpc_streamlist_destroy(jpc_streamlist_t *streamlist); +jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno); + +static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp); +static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps); +static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp); +static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp); +static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod); +static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc); +static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, + jpc_coxcp_t *compparms, int flags); +static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd); +static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc); +static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, + jpc_qcxcp_t *compparms, int flags); +static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn); +static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp); +static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp); +static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset); +static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc); + +static int jpc_dec_decode(jpc_dec_t *dec); +static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in); +static void jpc_dec_destroy(jpc_dec_t *dec); +static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize); +static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps); +static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits); +static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile); +static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile); +static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile); +static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms); +static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts); + +static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id); + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +jpc_dec_mstabent_t jpc_dec_mstab[] = { + {JPC_MS_SOC, JPC_MHSOC, jpc_dec_process_soc}, + {JPC_MS_SOT, JPC_MH | JPC_TPHSOT, jpc_dec_process_sot}, + {JPC_MS_SOD, JPC_TPH, jpc_dec_process_sod}, + {JPC_MS_EOC, JPC_TPHSOT, jpc_dec_process_eoc}, + {JPC_MS_SIZ, JPC_MHSIZ, jpc_dec_process_siz}, + {JPC_MS_COD, JPC_MH | JPC_TPH, jpc_dec_process_cod}, + {JPC_MS_COC, JPC_MH | JPC_TPH, jpc_dec_process_coc}, + {JPC_MS_RGN, JPC_MH | JPC_TPH, jpc_dec_process_rgn}, + {JPC_MS_QCD, JPC_MH | JPC_TPH, jpc_dec_process_qcd}, + {JPC_MS_QCC, JPC_MH | JPC_TPH, jpc_dec_process_qcc}, + {JPC_MS_POC, JPC_MH | JPC_TPH, jpc_dec_process_poc}, + {JPC_MS_TLM, JPC_MH, 0}, + {JPC_MS_PLM, JPC_MH, 0}, + {JPC_MS_PLT, JPC_TPH, 0}, + {JPC_MS_PPM, JPC_MH, jpc_dec_process_ppm}, + {JPC_MS_PPT, JPC_TPH, jpc_dec_process_ppt}, + {JPC_MS_SOP, 0, 0}, + {JPC_MS_CRG, JPC_MH, jpc_dec_process_crg}, + {JPC_MS_COM, JPC_MH | JPC_TPH, jpc_dec_process_com}, + {0, JPC_MH | JPC_TPH, jpc_dec_process_unk} +}; + +/******************************************************************************\ +* The main entry point for the JPEG-2000 decoder. +\******************************************************************************/ + +jas_image_t *jpc_decode(jas_stream_t *in, char *optstr) +{ + jpc_dec_importopts_t opts; + jpc_dec_t *dec; + jas_image_t *image; + + dec = 0; + + if (jpc_dec_parseopts(optstr, &opts)) { + goto error; + } + + jpc_initluts(); + + if (!(dec = jpc_dec_create(&opts, in))) { + goto error; + } + + /* Do most of the work. */ + if (jpc_dec_decode(dec)) { + goto error; + } + + if (jas_image_numcmpts(dec->image) >= 3) { + jas_image_setclrspc(dec->image, JAS_CLRSPC_SRGB); + jas_image_setcmpttype(dec->image, 0, + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); + jas_image_setcmpttype(dec->image, 1, + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); + jas_image_setcmpttype(dec->image, 2, + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); + } else { + jas_image_setclrspc(dec->image, JAS_CLRSPC_SGRAY); + jas_image_setcmpttype(dec->image, 0, + JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); + } + + /* Save the return value. */ + image = dec->image; + + /* Stop the image from being discarded. */ + dec->image = 0; + + /* Destroy decoder. */ + jpc_dec_destroy(dec); + + return image; + +error: + if (dec) { + jpc_dec_destroy(dec); + } + return 0; +} + +typedef enum { + OPT_MAXLYRS, + OPT_MAXPKTS, + OPT_DEBUG +} optid_t; + +jas_taginfo_t decopts[] = { + {OPT_MAXLYRS, "maxlyrs"}, + {OPT_MAXPKTS, "maxpkts"}, + {OPT_DEBUG, "debug"}, + {-1, 0} +}; + +static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts) +{ + jas_tvparser_t *tvp; + + opts->debug = 0; + opts->maxlyrs = JPC_MAXLYRS; + opts->maxpkts = -1; + + if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) { + return -1; + } + + while (!jas_tvparser_next(tvp)) { + switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts, + jas_tvparser_gettag(tvp)))->id) { + case OPT_MAXLYRS: + opts->maxlyrs = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_DEBUG: + opts->debug = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_MAXPKTS: + opts->maxpkts = atoi(jas_tvparser_getval(tvp)); + break; + default: + jas_eprintf("warning: ignoring invalid option %s\n", + jas_tvparser_gettag(tvp)); + break; + } + } + + jas_tvparser_destroy(tvp); + + return 0; +} + +/******************************************************************************\ +* Code for table-driven code stream decoder. +\******************************************************************************/ + +static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id) +{ + jpc_dec_mstabent_t *mstabent; + for (mstabent = jpc_dec_mstab; mstabent->id != 0; ++mstabent) { + if (mstabent->id == id) { + break; + } + } + return mstabent; +} + +static int jpc_dec_decode(jpc_dec_t *dec) +{ + jpc_ms_t *ms; + jpc_dec_mstabent_t *mstabent; + int ret; + jpc_cstate_t *cstate; + + if (!(cstate = jpc_cstate_create())) { + return -1; + } + dec->cstate = cstate; + + /* Initially, we should expect to encounter a SOC marker segment. */ + dec->state = JPC_MHSOC; + + for (;;) { + + /* Get the next marker segment in the code stream. */ + if (!(ms = jpc_getms(dec->in, cstate))) { + jas_eprintf("cannot get marker segment\n"); + return -1; + } + + mstabent = jpc_dec_mstab_lookup(ms->id); + assert(mstabent); + + /* Ensure that this type of marker segment is permitted + at this point in the code stream. */ + if (!(dec->state & mstabent->validstates)) { + jas_eprintf("unexpected marker segment type\n"); + jpc_ms_destroy(ms); + return -1; + } + + /* Process the marker segment. */ + if (mstabent->action) { + ret = (*mstabent->action)(dec, ms); + } else { + /* No explicit action is required. */ + ret = 0; + } + + /* Destroy the marker segment. */ + jpc_ms_destroy(ms); + + if (ret < 0) { + return -1; + } else if (ret > 0) { + break; + } + + } + + return 0; +} + +static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms) +{ + int cmptno; + jpc_dec_cmpt_t *cmpt; + jpc_crg_t *crg; + + crg = &ms->parms.crg; + for (cmptno = 0, cmpt = dec->cmpts; cmptno < dec->numcomps; ++cmptno, + ++cmpt) { + /* Ignore the information in the CRG marker segment for now. + This information serves no useful purpose for decoding anyhow. + Some other parts of the code need to be changed if these lines + are uncommented. + cmpt->hsubstep = crg->comps[cmptno].hoff; + cmpt->vsubstep = crg->comps[cmptno].voff; + */ + } + return 0; +} + +static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms) +{ + /* Eliminate warnings about unused variables. */ + ms = 0; + + /* We should expect to encounter a SIZ marker segment next. */ + dec->state = JPC_MHSIZ; + + return 0; +} + +static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_dec_tile_t *tile; + jpc_sot_t *sot = &ms->parms.sot; + jas_image_cmptparm_t *compinfos; + jas_image_cmptparm_t *compinfo; + jpc_dec_cmpt_t *cmpt; + int cmptno; + + if (dec->state == JPC_MH) { + + compinfos = jas_alloc2(dec->numcomps, sizeof(jas_image_cmptparm_t)); + assert(compinfos); + for (cmptno = 0, cmpt = dec->cmpts, compinfo = compinfos; + cmptno < dec->numcomps; ++cmptno, ++cmpt, ++compinfo) { + compinfo->tlx = 0; + compinfo->tly = 0; + compinfo->prec = cmpt->prec; + compinfo->sgnd = cmpt->sgnd; + compinfo->width = cmpt->width; + compinfo->height = cmpt->height; + compinfo->hstep = cmpt->hstep; + compinfo->vstep = cmpt->vstep; + } + + if (!(dec->image = jas_image_create(dec->numcomps, compinfos, + JAS_CLRSPC_UNKNOWN))) { + return -1; + } + jas_free(compinfos); + + /* Is the packet header information stored in PPM marker segments in + the main header? */ + if (dec->ppmstab) { + /* Convert the PPM marker segment data into a collection of streams + (one stream per tile-part). */ + if (!(dec->pkthdrstreams = jpc_ppmstabtostreams(dec->ppmstab))) { + abort(); + } + jpc_ppxstab_destroy(dec->ppmstab); + dec->ppmstab = 0; + } + } + + if (sot->len > 0) { + dec->curtileendoff = jas_stream_getrwcount(dec->in) - ms->len - + 4 + sot->len; + } else { + dec->curtileendoff = 0; + } + + if (JAS_CAST(int, sot->tileno) > dec->numtiles) { + jas_eprintf("invalid tile number in SOT marker segment\n"); + return -1; + } + /* Set the current tile. */ + dec->curtile = &dec->tiles[sot->tileno]; + tile = dec->curtile; + /* Ensure that this is the expected part number. */ + if (sot->partno != tile->partno) { + return -1; + } + if (tile->numparts > 0 && sot->partno >= tile->numparts) { + return -1; + } + if (!tile->numparts && sot->numparts > 0) { + tile->numparts = sot->numparts; + } + + tile->pptstab = 0; + + switch (tile->state) { + case JPC_TILE_INIT: + /* This is the first tile-part for this tile. */ + tile->state = JPC_TILE_ACTIVE; + assert(!tile->cp); + if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) { + return -1; + } + jpc_dec_cp_resetflags(dec->cp); + break; + default: + if (sot->numparts == sot->partno - 1) { + tile->state = JPC_TILE_ACTIVELAST; + } + break; + } + + /* Note: We do not increment the expected tile-part number until + all processing for this tile-part is complete. */ + + /* We should expect to encounter other tile-part header marker + segments next. */ + dec->state = JPC_TPH; + + return 0; +} + +static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_dec_tile_t *tile; + int pos; + + /* Eliminate compiler warnings about unused variables. */ + ms = 0; + + if (!(tile = dec->curtile)) { + return -1; + } + + if (!tile->partno) { + if (!jpc_dec_cp_isvalid(tile->cp)) { + return -1; + } + jpc_dec_cp_prepare(tile->cp); + if (jpc_dec_tileinit(dec, tile)) { + return -1; + } + } + + /* Are packet headers stored in the main header or tile-part header? */ + if (dec->pkthdrstreams) { + /* Get the stream containing the packet header data for this + tile-part. */ + if (!(tile->pkthdrstream = jpc_streamlist_remove(dec->pkthdrstreams, 0))) { + return -1; + } + } + + if (tile->pptstab) { + if (!tile->pkthdrstream) { + if (!(tile->pkthdrstream = jas_stream_memopen(0, 0))) { + return -1; + } + } + pos = jas_stream_tell(tile->pkthdrstream); + jas_stream_seek(tile->pkthdrstream, 0, SEEK_END); + if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) { + return -1; + } + jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET); + jpc_ppxstab_destroy(tile->pptstab); + tile->pptstab = 0; + } + + if (jas_getdbglevel() >= 10) { + jpc_dec_dump(dec, stderr); + } + + if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream : + dec->in, dec->in)) { + jas_eprintf("jpc_dec_decodepkts failed\n"); + return -1; + } + + /* Gobble any unconsumed tile data. */ + if (dec->curtileendoff > 0) { + long curoff; + uint_fast32_t n; + curoff = jas_stream_getrwcount(dec->in); + if (curoff < dec->curtileendoff) { + n = dec->curtileendoff - curoff; + jas_eprintf("warning: ignoring trailing garbage (%lu bytes)\n", + (unsigned long) n); + + while (n-- > 0) { + if (jas_stream_getc(dec->in) == EOF) { + jas_eprintf("read error\n"); + return -1; + } + } + } else if (curoff > dec->curtileendoff) { + jas_eprintf("warning: not enough tile data (%lu bytes)\n", + (unsigned long) curoff - dec->curtileendoff); + } + + } + + if (tile->numparts > 0 && tile->partno == tile->numparts - 1) { + if (jpc_dec_tiledecode(dec, tile)) { + return -1; + } + jpc_dec_tilefini(dec, tile); + } + + dec->curtile = 0; + + /* Increment the expected tile-part number. */ + ++tile->partno; + + /* We should expect to encounter a SOT marker segment next. */ + dec->state = JPC_TPHSOT; + + return 0; +} + +static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) +{ + jpc_dec_tcomp_t *tcomp; + int compno; + int rlvlno; + jpc_dec_rlvl_t *rlvl; + jpc_dec_band_t *band; + jpc_dec_prc_t *prc; + int bndno; + jpc_tsfb_band_t *bnd; + int bandno; + jpc_dec_ccp_t *ccp; + int prccnt; + jpc_dec_cblk_t *cblk; + int cblkcnt; + uint_fast32_t tlprcxstart; + uint_fast32_t tlprcystart; + uint_fast32_t brprcxend; + uint_fast32_t brprcyend; + uint_fast32_t tlcbgxstart; + uint_fast32_t tlcbgystart; + uint_fast32_t brcbgxend; + uint_fast32_t brcbgyend; + uint_fast32_t cbgxstart; + uint_fast32_t cbgystart; + uint_fast32_t cbgxend; + uint_fast32_t cbgyend; + uint_fast32_t tlcblkxstart; + uint_fast32_t tlcblkystart; + uint_fast32_t brcblkxend; + uint_fast32_t brcblkyend; + uint_fast32_t cblkxstart; + uint_fast32_t cblkystart; + uint_fast32_t cblkxend; + uint_fast32_t cblkyend; + uint_fast32_t tmpxstart; + uint_fast32_t tmpystart; + uint_fast32_t tmpxend; + uint_fast32_t tmpyend; + jpc_dec_cp_t *cp; + jpc_tsfb_band_t bnds[64]; + jpc_pchg_t *pchg; + int pchgno; + jpc_dec_cmpt_t *cmpt; + + cp = tile->cp; + tile->realmode = 0; + if (cp->mctid == JPC_MCT_ICT) { + tile->realmode = 1; + } + + for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno < + dec->numcomps; ++compno, ++tcomp, ++cmpt) { + ccp = &tile->cp->ccps[compno]; + if (ccp->qmfbid == JPC_COX_INS) { + tile->realmode = 1; + } + tcomp->numrlvls = ccp->numrlvls; + if (!(tcomp->rlvls = jas_alloc2(tcomp->numrlvls, + sizeof(jpc_dec_rlvl_t)))) { + return -1; + } + if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart, + cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep), + JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend, + cmpt->vstep)))) { + return -1; + } + if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid, + tcomp->numrlvls - 1))) { + return -1; + } +{ + jpc_tsfb_getbands(tcomp->tsfb, jas_seq2d_xstart(tcomp->data), jas_seq2d_ystart(tcomp->data), jas_seq2d_xend(tcomp->data), jas_seq2d_yend(tcomp->data), bnds); +} + for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls; + ++rlvlno, ++rlvl) { +rlvl->bands = 0; + rlvl->xstart = JPC_CEILDIVPOW2(tcomp->xstart, + tcomp->numrlvls - 1 - rlvlno); + rlvl->ystart = JPC_CEILDIVPOW2(tcomp->ystart, + tcomp->numrlvls - 1 - rlvlno); + rlvl->xend = JPC_CEILDIVPOW2(tcomp->xend, + tcomp->numrlvls - 1 - rlvlno); + rlvl->yend = JPC_CEILDIVPOW2(tcomp->yend, + tcomp->numrlvls - 1 - rlvlno); + rlvl->prcwidthexpn = ccp->prcwidthexpns[rlvlno]; + rlvl->prcheightexpn = ccp->prcheightexpns[rlvlno]; + tlprcxstart = JPC_FLOORDIVPOW2(rlvl->xstart, + rlvl->prcwidthexpn) << rlvl->prcwidthexpn; + tlprcystart = JPC_FLOORDIVPOW2(rlvl->ystart, + rlvl->prcheightexpn) << rlvl->prcheightexpn; + brprcxend = JPC_CEILDIVPOW2(rlvl->xend, + rlvl->prcwidthexpn) << rlvl->prcwidthexpn; + brprcyend = JPC_CEILDIVPOW2(rlvl->yend, + rlvl->prcheightexpn) << rlvl->prcheightexpn; + rlvl->numhprcs = (brprcxend - tlprcxstart) >> + rlvl->prcwidthexpn; + rlvl->numvprcs = (brprcyend - tlprcystart) >> + rlvl->prcheightexpn; + rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs; + + if (rlvl->xstart >= rlvl->xend || rlvl->ystart >= rlvl->yend) { + rlvl->bands = 0; + rlvl->numprcs = 0; + rlvl->numhprcs = 0; + rlvl->numvprcs = 0; + continue; + } + if (!rlvlno) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + rlvl->cbgwidthexpn = rlvl->prcwidthexpn; + rlvl->cbgheightexpn = rlvl->prcheightexpn; + } else { + tlcbgxstart = JPC_CEILDIVPOW2(tlprcxstart, 1); + tlcbgystart = JPC_CEILDIVPOW2(tlprcystart, 1); + brcbgxend = JPC_CEILDIVPOW2(brprcxend, 1); + brcbgyend = JPC_CEILDIVPOW2(brprcyend, 1); + rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1; + rlvl->cbgheightexpn = rlvl->prcheightexpn - 1; + } + rlvl->cblkwidthexpn = JAS_MIN(ccp->cblkwidthexpn, + rlvl->cbgwidthexpn); + rlvl->cblkheightexpn = JAS_MIN(ccp->cblkheightexpn, + rlvl->cbgheightexpn); + + rlvl->numbands = (!rlvlno) ? 1 : 3; + if (!(rlvl->bands = jas_alloc2(rlvl->numbands, + sizeof(jpc_dec_band_t)))) { + return -1; + } + for (bandno = 0, band = rlvl->bands; + bandno < rlvl->numbands; ++bandno, ++band) { + bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + + bandno + 1); + bnd = &bnds[bndno]; + + band->orient = bnd->orient; + band->stepsize = ccp->stepsizes[bndno]; + band->analgain = JPC_NOMINALGAIN(ccp->qmfbid, + tcomp->numrlvls - 1, rlvlno, band->orient); + band->absstepsize = jpc_calcabsstepsize(band->stepsize, + cmpt->prec + band->analgain); + band->numbps = ccp->numguardbits + + JPC_QCX_GETEXPN(band->stepsize) - 1; + band->roishift = (ccp->roishift + band->numbps >= JPC_PREC) ? + (JPC_PREC - 1 - band->numbps) : ccp->roishift; + band->data = 0; + band->prcs = 0; + if (bnd->xstart == bnd->xend || bnd->ystart == bnd->yend) { + continue; + } + if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) { + return -1; + } + jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart, bnd->locystart, bnd->locxend, bnd->locyend); + jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart); + + assert(rlvl->numprcs); + + if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_dec_prc_t)))) { + return -1; + } + +/************************************************/ + cbgxstart = tlcbgxstart; + cbgystart = tlcbgystart; + for (prccnt = rlvl->numprcs, prc = band->prcs; + prccnt > 0; --prccnt, ++prc) { + cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn); + cbgyend = cbgystart + (1 << rlvl->cbgheightexpn); + prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t, jas_seq2d_xstart(band->data))); + prc->ystart = JAS_MAX(cbgystart, JAS_CAST(uint_fast32_t, jas_seq2d_ystart(band->data))); + prc->xend = JAS_MIN(cbgxend, JAS_CAST(uint_fast32_t, jas_seq2d_xend(band->data))); + prc->yend = JAS_MIN(cbgyend, JAS_CAST(uint_fast32_t, jas_seq2d_yend(band->data))); + if (prc->xend > prc->xstart && prc->yend > prc->ystart) { + tlcblkxstart = JPC_FLOORDIVPOW2(prc->xstart, + rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn; + tlcblkystart = JPC_FLOORDIVPOW2(prc->ystart, + rlvl->cblkheightexpn) << rlvl->cblkheightexpn; + brcblkxend = JPC_CEILDIVPOW2(prc->xend, + rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn; + brcblkyend = JPC_CEILDIVPOW2(prc->yend, + rlvl->cblkheightexpn) << rlvl->cblkheightexpn; + prc->numhcblks = (brcblkxend - tlcblkxstart) >> + rlvl->cblkwidthexpn; + prc->numvcblks = (brcblkyend - tlcblkystart) >> + rlvl->cblkheightexpn; + prc->numcblks = prc->numhcblks * prc->numvcblks; + assert(prc->numcblks > 0); + + if (!(prc->incltagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) { + return -1; + } + if (!(prc->numimsbstagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) { + return -1; + } + if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_dec_cblk_t)))) { + return -1; + } + + cblkxstart = cbgxstart; + cblkystart = cbgystart; + for (cblkcnt = prc->numcblks, cblk = prc->cblks; cblkcnt > 0;) { + cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn); + cblkyend = cblkystart + (1 << rlvl->cblkheightexpn); + tmpxstart = JAS_MAX(cblkxstart, prc->xstart); + tmpystart = JAS_MAX(cblkystart, prc->ystart); + tmpxend = JAS_MIN(cblkxend, prc->xend); + tmpyend = JAS_MIN(cblkyend, prc->yend); + if (tmpxend > tmpxstart && tmpyend > tmpystart) { + cblk->firstpassno = -1; + cblk->mqdec = 0; + cblk->nulldec = 0; + cblk->flags = 0; + cblk->numpasses = 0; + cblk->segs.head = 0; + cblk->segs.tail = 0; + cblk->curseg = 0; + cblk->numimsbs = 0; + cblk->numlenbits = 3; + cblk->flags = 0; + if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) { + return -1; + } + jas_seq2d_bindsub(cblk->data, band->data, tmpxstart, tmpystart, tmpxend, tmpyend); + ++cblk; + --cblkcnt; + } + cblkxstart += 1 << rlvl->cblkwidthexpn; + if (cblkxstart >= cbgxend) { + cblkxstart = cbgxstart; + cblkystart += 1 << rlvl->cblkheightexpn; + } + } + + } else { + prc->cblks = 0; + prc->incltagtree = 0; + prc->numimsbstagtree = 0; + } + cbgxstart += 1 << rlvl->cbgwidthexpn; + if (cbgxstart >= brcbgxend) { + cbgxstart = tlcbgxstart; + cbgystart += 1 << rlvl->cbgheightexpn; + } + + } +/********************************************/ + } + } + } + +if (!(tile->pi = jpc_dec_pi_create(dec, tile))) +{ + return -1; +} + + for (pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist); + ++pchgno) { + pchg = jpc_pchg_copy(jpc_pchglist_get(tile->cp->pchglist, pchgno)); + assert(pchg); + jpc_pi_addpchg(tile->pi, pchg); + } + jpc_pi_init(tile->pi); + + return 0; +} + +static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile) +{ + jpc_dec_tcomp_t *tcomp; + int compno; + int bandno; + int rlvlno; + jpc_dec_band_t *band; + jpc_dec_rlvl_t *rlvl; + int prcno; + jpc_dec_prc_t *prc; + jpc_dec_seg_t *seg; + jpc_dec_cblk_t *cblk; + int cblkno; + +if (tile->tcomps) { + + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + ++compno, ++tcomp) { + for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls; + ++rlvlno, ++rlvl) { +if (!rlvl->bands) { + continue; +} + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; ++bandno, ++band) { +if (band->prcs) { + for (prcno = 0, prc = band->prcs; prcno < + rlvl->numprcs; ++prcno, ++prc) { +if (!prc->cblks) { + continue; +} + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; ++cblkno, ++cblk) { + + while (cblk->segs.head) { + seg = cblk->segs.head; + jpc_seglist_remove(&cblk->segs, seg); + jpc_seg_destroy(seg); + } + jas_matrix_destroy(cblk->data); + if (cblk->mqdec) { + jpc_mqdec_destroy(cblk->mqdec); + } + if (cblk->nulldec) { + jpc_bitstream_close(cblk->nulldec); + } + if (cblk->flags) { + jas_matrix_destroy(cblk->flags); + } + } + if (prc->incltagtree) { + jpc_tagtree_destroy(prc->incltagtree); + } + if (prc->numimsbstagtree) { + jpc_tagtree_destroy(prc->numimsbstagtree); + } + if (prc->cblks) { + jas_free(prc->cblks); + } + } +} + if (band->data) { + jas_matrix_destroy(band->data); + } + if (band->prcs) { + jas_free(band->prcs); + } + } + if (rlvl->bands) { + jas_free(rlvl->bands); + } + } + if (tcomp->rlvls) { + jas_free(tcomp->rlvls); + } + if (tcomp->data) { + jas_matrix_destroy(tcomp->data); + } + if (tcomp->tsfb) { + jpc_tsfb_destroy(tcomp->tsfb); + } + } +} + if (tile->cp) { + jpc_dec_cp_destroy(tile->cp); + tile->cp = 0; + } + if (tile->tcomps) { + jas_free(tile->tcomps); + tile->tcomps = 0; + } + if (tile->pi) { + jpc_pi_destroy(tile->pi); + tile->pi = 0; + } + if (tile->pkthdrstream) { + jas_stream_close(tile->pkthdrstream); + tile->pkthdrstream = 0; + } + if (tile->pptstab) { + jpc_ppxstab_destroy(tile->pptstab); + tile->pptstab = 0; + } + + tile->state = JPC_TILE_DONE; + + return 0; +} + +static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) +{ + int i; + int j; + jpc_dec_tcomp_t *tcomp; + jpc_dec_rlvl_t *rlvl; + jpc_dec_band_t *band; + int compno; + int rlvlno; + int bandno; + int adjust; + int v; + jpc_dec_ccp_t *ccp; + jpc_dec_cmpt_t *cmpt; + + if (jpc_dec_decodecblks(dec, tile)) { + jas_eprintf("jpc_dec_decodecblks failed\n"); + return -1; + } + + /* Perform dequantization. */ + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + ++compno, ++tcomp) { + ccp = &tile->cp->ccps[compno]; + for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls; + ++rlvlno, ++rlvl) { + if (!rlvl->bands) { + continue; + } + for (bandno = 0, band = rlvl->bands; + bandno < rlvl->numbands; ++bandno, ++band) { + if (!band->data) { + continue; + } + jpc_undo_roi(band->data, band->roishift, ccp->roishift - + band->roishift, band->numbps); + if (tile->realmode) { + jas_matrix_asl(band->data, JPC_FIX_FRACBITS); + jpc_dequantize(band->data, band->absstepsize); + } + + } + } + } + + /* Apply an inverse wavelet transform if necessary. */ + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + ++compno, ++tcomp) { + ccp = &tile->cp->ccps[compno]; + jpc_tsfb_synthesize(tcomp->tsfb, tcomp->data); + } + + + /* Apply an inverse intercomponent transform if necessary. */ + switch (tile->cp->mctid) { + case JPC_MCT_RCT: + assert(dec->numcomps == 3 || dec->numcomps == 4); + jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data, + tile->tcomps[2].data); + break; + case JPC_MCT_ICT: + assert(dec->numcomps == 3 || dec->numcomps == 4); + jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data, + tile->tcomps[2].data); + break; + } + + /* Perform rounding and convert to integer values. */ + if (tile->realmode) { + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + ++compno, ++tcomp) { + for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) { + for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) { + v = jas_matrix_get(tcomp->data, i, j); + v = jpc_fix_round(v); + jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v)); + } + } + } + } + + /* Perform level shift. */ + for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno < + dec->numcomps; ++compno, ++tcomp, ++cmpt) { + adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1)); + for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) { + for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) { + *jas_matrix_getref(tcomp->data, i, j) += adjust; + } + } + } + + /* Perform clipping. */ + for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno < + dec->numcomps; ++compno, ++tcomp, ++cmpt) { + jpc_fix_t mn; + jpc_fix_t mx; + mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0); + mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 << + cmpt->prec) - 1); + jas_matrix_clip(tcomp->data, mn, mx); + } + + /* XXX need to free tsfb struct */ + + /* Write the data for each component of the image. */ + for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno < + dec->numcomps; ++compno, ++tcomp, ++cmpt) { + if (jas_image_writecmpt(dec->image, compno, tcomp->xstart - + JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart - + JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols( + tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) { + jas_eprintf("write component failed\n"); + return -4; + } + } + + return 0; +} + +static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms) +{ + int tileno; + jpc_dec_tile_t *tile; + + /* Eliminate compiler warnings about unused variables. */ + ms = 0; + + for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno, + ++tile) { + if (tile->state == JPC_TILE_ACTIVE) { + if (jpc_dec_tiledecode(dec, tile)) { + return -1; + } + } + jpc_dec_tilefini(dec, tile); + } + + /* We are done processing the code stream. */ + dec->state = JPC_MT; + + return 1; +} + +static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_siz_t *siz = &ms->parms.siz; + int compno; + int tileno; + jpc_dec_tile_t *tile; + jpc_dec_tcomp_t *tcomp; + int htileno; + int vtileno; + jpc_dec_cmpt_t *cmpt; + + dec->xstart = siz->xoff; + dec->ystart = siz->yoff; + dec->xend = siz->width; + dec->yend = siz->height; + dec->tilewidth = siz->tilewidth; + dec->tileheight = siz->tileheight; + dec->tilexoff = siz->tilexoff; + dec->tileyoff = siz->tileyoff; + dec->numcomps = siz->numcomps; + if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) { + return -1; + } + + if (!(dec->cmpts = jas_alloc2(dec->numcomps, sizeof(jpc_dec_cmpt_t)))) { + return -1; + } + + for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno, + ++cmpt) { + cmpt->prec = siz->comps[compno].prec; + cmpt->sgnd = siz->comps[compno].sgnd; + cmpt->hstep = siz->comps[compno].hsamp; + cmpt->vstep = siz->comps[compno].vsamp; + cmpt->width = JPC_CEILDIV(dec->xend, cmpt->hstep) - + JPC_CEILDIV(dec->xstart, cmpt->hstep); + cmpt->height = JPC_CEILDIV(dec->yend, cmpt->vstep) - + JPC_CEILDIV(dec->ystart, cmpt->vstep); + cmpt->hsubstep = 0; + cmpt->vsubstep = 0; + } + + dec->image = 0; + + dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth); + dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight); + dec->numtiles = dec->numhtiles * dec->numvtiles; + if (!(dec->tiles = jas_alloc2(dec->numtiles, sizeof(jpc_dec_tile_t)))) { + return -1; + } + + for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno, + ++tile) { + htileno = tileno % dec->numhtiles; + vtileno = tileno / dec->numhtiles; + tile->realmode = 0; + tile->state = JPC_TILE_INIT; + tile->xstart = JAS_MAX(dec->tilexoff + htileno * dec->tilewidth, + dec->xstart); + tile->ystart = JAS_MAX(dec->tileyoff + vtileno * dec->tileheight, + dec->ystart); + tile->xend = JAS_MIN(dec->tilexoff + (htileno + 1) * + dec->tilewidth, dec->xend); + tile->yend = JAS_MIN(dec->tileyoff + (vtileno + 1) * + dec->tileheight, dec->yend); + tile->numparts = 0; + tile->partno = 0; + tile->pkthdrstream = 0; + tile->pkthdrstreampos = 0; + tile->pptstab = 0; + tile->cp = 0; + if (!(tile->tcomps = jas_alloc2(dec->numcomps, + sizeof(jpc_dec_tcomp_t)))) { + return -1; + } + for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps; + compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) { + tcomp->rlvls = 0; + tcomp->data = 0; + tcomp->xstart = JPC_CEILDIV(tile->xstart, cmpt->hstep); + tcomp->ystart = JPC_CEILDIV(tile->ystart, cmpt->vstep); + tcomp->xend = JPC_CEILDIV(tile->xend, cmpt->hstep); + tcomp->yend = JPC_CEILDIV(tile->yend, cmpt->vstep); + tcomp->tsfb = 0; + } + } + + dec->pkthdrstreams = 0; + + /* We should expect to encounter other main header marker segments + or an SOT marker segment next. */ + dec->state = JPC_MH; + + return 0; +} + +static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_cod_t *cod = &ms->parms.cod; + jpc_dec_tile_t *tile; + + switch (dec->state) { + case JPC_MH: + jpc_dec_cp_setfromcod(dec->cp, cod); + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (tile->partno != 0) { + return -1; + } + jpc_dec_cp_setfromcod(tile->cp, cod); + break; + } + return 0; +} + +static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_coc_t *coc = &ms->parms.coc; + jpc_dec_tile_t *tile; + + if (JAS_CAST(int, coc->compno) > dec->numcomps) { + jas_eprintf("invalid component number in COC marker segment\n"); + return -1; + } + switch (dec->state) { + case JPC_MH: + jpc_dec_cp_setfromcoc(dec->cp, coc); + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (tile->partno > 0) { + return -1; + } + jpc_dec_cp_setfromcoc(tile->cp, coc); + break; + } + return 0; +} + +static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_rgn_t *rgn = &ms->parms.rgn; + jpc_dec_tile_t *tile; + + if (JAS_CAST(int, rgn->compno) > dec->numcomps) { + jas_eprintf("invalid component number in RGN marker segment\n"); + return -1; + } + switch (dec->state) { + case JPC_MH: + jpc_dec_cp_setfromrgn(dec->cp, rgn); + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (tile->partno > 0) { + return -1; + } + jpc_dec_cp_setfromrgn(tile->cp, rgn); + break; + } + + return 0; +} + +static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_qcd_t *qcd = &ms->parms.qcd; + jpc_dec_tile_t *tile; + + switch (dec->state) { + case JPC_MH: + jpc_dec_cp_setfromqcd(dec->cp, qcd); + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (tile->partno > 0) { + return -1; + } + jpc_dec_cp_setfromqcd(tile->cp, qcd); + break; + } + return 0; +} + +static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_qcc_t *qcc = &ms->parms.qcc; + jpc_dec_tile_t *tile; + + if (JAS_CAST(int, qcc->compno) > dec->numcomps) { + jas_eprintf("invalid component number in QCC marker segment\n"); + return -1; + } + switch (dec->state) { + case JPC_MH: + jpc_dec_cp_setfromqcc(dec->cp, qcc); + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (tile->partno > 0) { + return -1; + } + jpc_dec_cp_setfromqcc(tile->cp, qcc); + break; + } + return 0; +} + +static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_poc_t *poc = &ms->parms.poc; + jpc_dec_tile_t *tile; + switch (dec->state) { + case JPC_MH: + if (jpc_dec_cp_setfrompoc(dec->cp, poc, 1)) { + return -1; + } + break; + case JPC_TPH: + if (!(tile = dec->curtile)) { + return -1; + } + if (!tile->partno) { + if (jpc_dec_cp_setfrompoc(tile->cp, poc, (!tile->partno))) { + return -1; + } + } else { + jpc_pi_addpchgfrompoc(tile->pi, poc); + } + break; + } + return 0; +} + +static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_ppm_t *ppm = &ms->parms.ppm; + jpc_ppxstabent_t *ppmstabent; + + if (!dec->ppmstab) { + if (!(dec->ppmstab = jpc_ppxstab_create())) { + return -1; + } + } + + if (!(ppmstabent = jpc_ppxstabent_create())) { + return -1; + } + ppmstabent->ind = ppm->ind; + ppmstabent->data = ppm->data; + ppm->data = 0; + ppmstabent->len = ppm->len; + if (jpc_ppxstab_insert(dec->ppmstab, ppmstabent)) { + return -1; + } + return 0; +} + +static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms) +{ + jpc_ppt_t *ppt = &ms->parms.ppt; + jpc_dec_tile_t *tile; + jpc_ppxstabent_t *pptstabent; + + tile = dec->curtile; + if (!tile->pptstab) { + if (!(tile->pptstab = jpc_ppxstab_create())) { + return -1; + } + } + if (!(pptstabent = jpc_ppxstabent_create())) { + return -1; + } + pptstabent->ind = ppt->ind; + pptstabent->data = ppt->data; + ppt->data = 0; + pptstabent->len = ppt->len; + if (jpc_ppxstab_insert(tile->pptstab, pptstabent)) { + return -1; + } + return 0; +} + +static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms) +{ + /* Eliminate compiler warnings about unused variables. */ + dec = 0; + ms = 0; + + return 0; +} + +static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms) +{ + /* Eliminate compiler warnings about unused variables. */ + dec = 0; + + jas_eprintf("warning: ignoring unknown marker segment\n"); + jpc_ms_dump(ms, stderr); + return 0; +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps) +{ + jpc_dec_cp_t *cp; + jpc_dec_ccp_t *ccp; + int compno; + + if (!(cp = jas_malloc(sizeof(jpc_dec_cp_t)))) { + return 0; + } + cp->flags = 0; + cp->numcomps = numcomps; + cp->prgord = 0; + cp->numlyrs = 0; + cp->mctid = 0; + cp->csty = 0; + if (!(cp->ccps = jas_alloc2(cp->numcomps, sizeof(jpc_dec_ccp_t)))) { + return 0; + } + if (!(cp->pchglist = jpc_pchglist_create())) { + jas_free(cp->ccps); + return 0; + } + for (compno = 0, ccp = cp->ccps; compno < cp->numcomps; + ++compno, ++ccp) { + ccp->flags = 0; + ccp->numrlvls = 0; + ccp->cblkwidthexpn = 0; + ccp->cblkheightexpn = 0; + ccp->qmfbid = 0; + ccp->numstepsizes = 0; + ccp->numguardbits = 0; + ccp->roishift = 0; + ccp->cblkctx = 0; + } + return cp; +} + +static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp) +{ + jpc_dec_cp_t *newcp; + jpc_dec_ccp_t *newccp; + jpc_dec_ccp_t *ccp; + int compno; + + if (!(newcp = jpc_dec_cp_create(cp->numcomps))) { + return 0; + } + newcp->flags = cp->flags; + newcp->prgord = cp->prgord; + newcp->numlyrs = cp->numlyrs; + newcp->mctid = cp->mctid; + newcp->csty = cp->csty; + jpc_pchglist_destroy(newcp->pchglist); + newcp->pchglist = 0; + if (!(newcp->pchglist = jpc_pchglist_copy(cp->pchglist))) { + jas_free(newcp); + return 0; + } + for (compno = 0, newccp = newcp->ccps, ccp = cp->ccps; + compno < cp->numcomps; + ++compno, ++newccp, ++ccp) { + *newccp = *ccp; + } + return newcp; +} + +static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp) +{ + int compno; + jpc_dec_ccp_t *ccp; + cp->flags &= (JPC_CSET | JPC_QSET); + for (compno = 0, ccp = cp->ccps; compno < cp->numcomps; + ++compno, ++ccp) { + ccp->flags = 0; + } +} + +static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp) +{ + if (cp->ccps) { + jas_free(cp->ccps); + } + if (cp->pchglist) { + jpc_pchglist_destroy(cp->pchglist); + } + jas_free(cp); +} + +static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp) +{ + uint_fast16_t compcnt; + jpc_dec_ccp_t *ccp; + + if (!(cp->flags & JPC_CSET) || !(cp->flags & JPC_QSET)) { + return 0; + } + for (compcnt = cp->numcomps, ccp = cp->ccps; compcnt > 0; --compcnt, + ++ccp) { + /* Is there enough step sizes for the number of bands? */ + if ((ccp->qsty != JPC_QCX_SIQNT && JAS_CAST(int, ccp->numstepsizes) < 3 * + ccp->numrlvls - 2) || (ccp->qsty == JPC_QCX_SIQNT && + ccp->numstepsizes != 1)) { + return 0; + } + } + return 1; +} + +static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls, + uint_fast16_t *stepsizes) +{ + int bandno; + int numbands; + uint_fast16_t expn; + uint_fast16_t mant; + expn = JPC_QCX_GETEXPN(refstepsize); + mant = JPC_QCX_GETMANT(refstepsize); + numbands = 3 * numrlvls - 2; + for (bandno = 0; bandno < numbands; ++bandno) { + stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(expn + + (numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0)))); + } +} + +static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp) +{ + jpc_dec_ccp_t *ccp; + int compno; + int i; + for (compno = 0, ccp = cp->ccps; compno < cp->numcomps; + ++compno, ++ccp) { + if (!(ccp->csty & JPC_COX_PRT)) { + for (i = 0; i < JPC_MAXRLVLS; ++i) { + ccp->prcwidthexpns[i] = 15; + ccp->prcheightexpns[i] = 15; + } + } + if (ccp->qsty == JPC_QCX_SIQNT) { + calcstepsizes(ccp->stepsizes[0], ccp->numrlvls, ccp->stepsizes); + } + } + return 0; +} + +static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod) +{ + jpc_dec_ccp_t *ccp; + int compno; + cp->flags |= JPC_CSET; + cp->prgord = cod->prg; + if (cod->mctrans) { + cp->mctid = (cod->compparms.qmfbid == JPC_COX_INS) ? (JPC_MCT_ICT) : (JPC_MCT_RCT); + } else { + cp->mctid = JPC_MCT_NONE; + } + cp->numlyrs = cod->numlyrs; + cp->csty = cod->csty & (JPC_COD_SOP | JPC_COD_EPH); + for (compno = 0, ccp = cp->ccps; compno < cp->numcomps; + ++compno, ++ccp) { + jpc_dec_cp_setfromcox(cp, ccp, &cod->compparms, 0); + } + cp->flags |= JPC_CSET; + return 0; +} + +static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc) +{ + jpc_dec_cp_setfromcox(cp, &cp->ccps[coc->compno], &coc->compparms, JPC_COC); + return 0; +} + +static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, + jpc_coxcp_t *compparms, int flags) +{ + int rlvlno; + + /* Eliminate compiler warnings about unused variables. */ + cp = 0; + + if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) { + ccp->numrlvls = compparms->numdlvls + 1; + ccp->cblkwidthexpn = JPC_COX_GETCBLKSIZEEXPN( + compparms->cblkwidthval); + ccp->cblkheightexpn = JPC_COX_GETCBLKSIZEEXPN( + compparms->cblkheightval); + ccp->qmfbid = compparms->qmfbid; + ccp->cblkctx = compparms->cblksty; + ccp->csty = compparms->csty & JPC_COX_PRT; + for (rlvlno = 0; rlvlno < compparms->numrlvls; ++rlvlno) { + ccp->prcwidthexpns[rlvlno] = + compparms->rlvls[rlvlno].parwidthval; + ccp->prcheightexpns[rlvlno] = + compparms->rlvls[rlvlno].parheightval; + } + ccp->flags |= flags | JPC_CSET; + } + return 0; +} + +static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd) +{ + int compno; + jpc_dec_ccp_t *ccp; + for (compno = 0, ccp = cp->ccps; compno < cp->numcomps; + ++compno, ++ccp) { + jpc_dec_cp_setfromqcx(cp, ccp, &qcd->compparms, 0); + } + cp->flags |= JPC_QSET; + return 0; +} + +static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc) +{ + return jpc_dec_cp_setfromqcx(cp, &cp->ccps[qcc->compno], &qcc->compparms, JPC_QCC); +} + +static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, + jpc_qcxcp_t *compparms, int flags) +{ + int bandno; + + /* Eliminate compiler warnings about unused variables. */ + cp = 0; + + if ((flags & JPC_QCC) || !(ccp->flags & JPC_QCC)) { + ccp->flags |= flags | JPC_QSET; + for (bandno = 0; bandno < compparms->numstepsizes; ++bandno) { + ccp->stepsizes[bandno] = compparms->stepsizes[bandno]; + } + ccp->numstepsizes = compparms->numstepsizes; + ccp->numguardbits = compparms->numguard; + ccp->qsty = compparms->qntsty; + } + return 0; +} + +static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn) +{ + jpc_dec_ccp_t *ccp; + ccp = &cp->ccps[rgn->compno]; + ccp->roishift = rgn->roishift; + return 0; +} + +static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc) +{ + int pchgno; + jpc_pchg_t *pchg; + for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) { + if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) { + return -1; + } + if (jpc_pchglist_insert(pi->pchglist, -1, pchg)) { + return -1; + } + } + return 0; +} + +static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset) +{ + int pchgno; + jpc_pchg_t *pchg; + if (reset) { + while (jpc_pchglist_numpchgs(cp->pchglist) > 0) { + pchg = jpc_pchglist_remove(cp->pchglist, 0); + jpc_pchg_destroy(pchg); + } + } + for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) { + if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) { + return -1; + } + if (jpc_pchglist_insert(cp->pchglist, -1, pchg)) { + return -1; + } + } + return 0; +} + +static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits) +{ + jpc_fix_t absstepsize; + int n; + + absstepsize = jpc_inttofix(1); + n = JPC_FIX_FRACBITS - 11; + absstepsize |= (n >= 0) ? (JPC_QCX_GETMANT(stepsize) << n) : + (JPC_QCX_GETMANT(stepsize) >> (-n)); + n = numbits - JPC_QCX_GETEXPN(stepsize); + absstepsize = (n >= 0) ? (absstepsize << n) : (absstepsize >> (-n)); + return absstepsize; +} + +static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize) +{ + int i; + int j; + int t; + + assert(absstepsize >= 0); + if (absstepsize == jpc_inttofix(1)) { + return; + } + + for (i = 0; i < jas_matrix_numrows(x); ++i) { + for (j = 0; j < jas_matrix_numcols(x); ++j) { + t = jas_matrix_get(x, i, j); + if (t) { + t = jpc_fix_mul(t, absstepsize); + } else { + t = 0; + } + jas_matrix_set(x, i, j, t); + } + } + +} + +static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps) +{ + int i; + int j; + int thresh; + jpc_fix_t val; + jpc_fix_t mag; + bool warn; + uint_fast32_t mask; + + if (roishift == 0 && bgshift == 0) { + return; + } + thresh = 1 << roishift; + + warn = false; + for (i = 0; i < jas_matrix_numrows(x); ++i) { + for (j = 0; j < jas_matrix_numcols(x); ++j) { + val = jas_matrix_get(x, i, j); + mag = JAS_ABS(val); + if (mag >= thresh) { + /* We are dealing with ROI data. */ + mag >>= roishift; + val = (val < 0) ? (-mag) : mag; + jas_matrix_set(x, i, j, val); + } else { + /* We are dealing with non-ROI (i.e., background) data. */ + mag <<= bgshift; + mask = (1 << numbps) - 1; + /* Perform a basic sanity check on the sample value. */ + /* Some implementations write garbage in the unused + most-significant bit planes introduced by ROI shifting. + Here we ensure that any such bits are masked off. */ + if (mag & (~mask)) { + if (!warn) { + jas_eprintf("warning: possibly corrupt code stream\n"); + warn = true; + } + mag &= mask; + } + val = (val < 0) ? (-mag) : mag; + jas_matrix_set(x, i, j, val); + } + } + } +} + +static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in) +{ + jpc_dec_t *dec; + + if (!(dec = jas_malloc(sizeof(jpc_dec_t)))) { + return 0; + } + + dec->image = 0; + dec->xstart = 0; + dec->ystart = 0; + dec->xend = 0; + dec->yend = 0; + dec->tilewidth = 0; + dec->tileheight = 0; + dec->tilexoff = 0; + dec->tileyoff = 0; + dec->numhtiles = 0; + dec->numvtiles = 0; + dec->numtiles = 0; + dec->tiles = 0; + dec->curtile = 0; + dec->numcomps = 0; + dec->in = in; + dec->cp = 0; + dec->maxlyrs = impopts->maxlyrs; + dec->maxpkts = impopts->maxpkts; +dec->numpkts = 0; + dec->ppmseqno = 0; + dec->state = 0; + dec->cmpts = 0; + dec->pkthdrstreams = 0; + dec->ppmstab = 0; + dec->curtileendoff = 0; + + return dec; +} + +static void jpc_dec_destroy(jpc_dec_t *dec) +{ + if (dec->cstate) { + jpc_cstate_destroy(dec->cstate); + } + if (dec->pkthdrstreams) { + jpc_streamlist_destroy(dec->pkthdrstreams); + } + if (dec->image) { + jas_image_destroy(dec->image); + } + + if (dec->cp) { + jpc_dec_cp_destroy(dec->cp); + } + + if (dec->cmpts) { + jas_free(dec->cmpts); + } + + if (dec->tiles) { + jas_free(dec->tiles); + } + + jas_free(dec); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +void jpc_seglist_insert(jpc_dec_seglist_t *list, jpc_dec_seg_t *ins, jpc_dec_seg_t *node) +{ + jpc_dec_seg_t *prev; + jpc_dec_seg_t *next; + + prev = ins; + node->prev = prev; + next = prev ? (prev->next) : 0; + node->prev = prev; + node->next = next; + if (prev) { + prev->next = node; + } else { + list->head = node; + } + if (next) { + next->prev = node; + } else { + list->tail = node; + } +} + +void jpc_seglist_remove(jpc_dec_seglist_t *list, jpc_dec_seg_t *seg) +{ + jpc_dec_seg_t *prev; + jpc_dec_seg_t *next; + + prev = seg->prev; + next = seg->next; + if (prev) { + prev->next = next; + } else { + list->head = next; + } + if (next) { + next->prev = prev; + } else { + list->tail = prev; + } + seg->prev = 0; + seg->next = 0; +} + +jpc_dec_seg_t *jpc_seg_alloc() +{ + jpc_dec_seg_t *seg; + + if (!(seg = jas_malloc(sizeof(jpc_dec_seg_t)))) { + return 0; + } + seg->prev = 0; + seg->next = 0; + seg->passno = -1; + seg->numpasses = 0; + seg->maxpasses = 0; + seg->type = JPC_SEG_INVALID; + seg->stream = 0; + seg->cnt = 0; + seg->complete = 0; + seg->lyrno = -1; + return seg; +} + +void jpc_seg_destroy(jpc_dec_seg_t *seg) +{ + if (seg->stream) { + jas_stream_close(seg->stream); + } + jas_free(seg); +} + +static int jpc_dec_dump(jpc_dec_t *dec, FILE *out) +{ + jpc_dec_tile_t *tile; + int tileno; + jpc_dec_tcomp_t *tcomp; + int compno; + jpc_dec_rlvl_t *rlvl; + int rlvlno; + jpc_dec_band_t *band; + int bandno; + jpc_dec_prc_t *prc; + int prcno; + jpc_dec_cblk_t *cblk; + int cblkno; + + for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; + ++tileno, ++tile) { + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + ++compno, ++tcomp) { + for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < + tcomp->numrlvls; ++rlvlno, ++rlvl) { +fprintf(out, "RESOLUTION LEVEL %d\n", rlvlno); +fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n", + (int)rlvl->xstart, (int)rlvl->ystart, (int)rlvl->xend, (int)rlvl->yend, (int)(rlvl->xend - + rlvl->xstart), (int)(rlvl->yend - rlvl->ystart)); + for (bandno = 0, band = rlvl->bands; + bandno < rlvl->numbands; ++bandno, ++band) { +fprintf(out, "BAND %d\n", bandno); +fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n", + (int)jas_seq2d_xstart(band->data), (int)jas_seq2d_ystart(band->data), (int)jas_seq2d_xend(band->data), + (int)jas_seq2d_yend(band->data), (int)(jas_seq2d_xend(band->data) - jas_seq2d_xstart(band->data)), + (int)(jas_seq2d_yend(band->data) - jas_seq2d_ystart(band->data))); + for (prcno = 0, prc = band->prcs; + prcno < rlvl->numprcs; ++prcno, + ++prc) { +fprintf(out, "CODE BLOCK GROUP %d\n", prcno); +fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n", + (int)prc->xstart, (int)prc->ystart, (int)prc->xend, (int)prc->yend, (int)(prc->xend - + prc->xstart), (int)(prc->yend - prc->ystart)); + for (cblkno = 0, cblk = + prc->cblks; cblkno < + prc->numcblks; ++cblkno, + ++cblk) { +fprintf(out, "CODE BLOCK %d\n", cblkno); +fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n", + (int)jas_seq2d_xstart(cblk->data), (int)jas_seq2d_ystart(cblk->data), (int)jas_seq2d_xend(cblk->data), + (int)jas_seq2d_yend(cblk->data), (int)(jas_seq2d_xend(cblk->data) - jas_seq2d_xstart(cblk->data)), + (int)(jas_seq2d_yend(cblk->data) - jas_seq2d_ystart(cblk->data))); + } + } + } + } + } + } + + return 0; +} + +jpc_streamlist_t *jpc_streamlist_create() +{ + jpc_streamlist_t *streamlist; + int i; + + if (!(streamlist = jas_malloc(sizeof(jpc_streamlist_t)))) { + return 0; + } + streamlist->numstreams = 0; + streamlist->maxstreams = 100; + if (!(streamlist->streams = jas_alloc2(streamlist->maxstreams, + sizeof(jas_stream_t *)))) { + jas_free(streamlist); + return 0; + } + for (i = 0; i < streamlist->maxstreams; ++i) { + streamlist->streams[i] = 0; + } + return streamlist; +} + +int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno, + jas_stream_t *stream) +{ + jas_stream_t **newstreams; + int newmaxstreams; + int i; + /* Grow the array of streams if necessary. */ + if (streamlist->numstreams >= streamlist->maxstreams) { + newmaxstreams = streamlist->maxstreams + 1024; + if (!(newstreams = jas_realloc2(streamlist->streams, + (newmaxstreams + 1024), sizeof(jas_stream_t *)))) { + return -1; + } + for (i = streamlist->numstreams; i < streamlist->maxstreams; ++i) { + streamlist->streams[i] = 0; + } + streamlist->maxstreams = newmaxstreams; + streamlist->streams = newstreams; + } + if (streamno != streamlist->numstreams) { + /* Can only handle insertion at start of list. */ + return -1; + } + streamlist->streams[streamno] = stream; + ++streamlist->numstreams; + return 0; +} + +jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno) +{ + jas_stream_t *stream; + int i; + if (streamno >= streamlist->numstreams) { + abort(); + } + stream = streamlist->streams[streamno]; + for (i = streamno + 1; i < streamlist->numstreams; ++i) { + streamlist->streams[i - 1] = streamlist->streams[i]; + } + --streamlist->numstreams; + return stream; +} + +void jpc_streamlist_destroy(jpc_streamlist_t *streamlist) +{ + int streamno; + if (streamlist->streams) { + for (streamno = 0; streamno < streamlist->numstreams; + ++streamno) { + jas_stream_close(streamlist->streams[streamno]); + } + jas_free(streamlist->streams); + } + jas_free(streamlist); +} + +jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno) +{ + assert(streamno < streamlist->numstreams); + return streamlist->streams[streamno]; +} + +int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist) +{ + return streamlist->numstreams; +} + +jpc_ppxstab_t *jpc_ppxstab_create() +{ + jpc_ppxstab_t *tab; + + if (!(tab = jas_malloc(sizeof(jpc_ppxstab_t)))) { + return 0; + } + tab->numents = 0; + tab->maxents = 0; + tab->ents = 0; + return tab; +} + +void jpc_ppxstab_destroy(jpc_ppxstab_t *tab) +{ + int i; + for (i = 0; i < tab->numents; ++i) { + jpc_ppxstabent_destroy(tab->ents[i]); + } + if (tab->ents) { + jas_free(tab->ents); + } + jas_free(tab); +} + +int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents) +{ + jpc_ppxstabent_t **newents; + if (tab->maxents < maxents) { + newents = jas_realloc2(tab->ents, maxents, sizeof(jpc_ppxstabent_t *)); + if (!newents) { + return -1; + } + tab->ents = newents; + tab->maxents = maxents; + } + return 0; +} + +int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent) +{ + int inspt; + int i; + + for (i = 0; i < tab->numents; ++i) { + if (tab->ents[i]->ind > ent->ind) { + break; + } + } + inspt = i; + + if (tab->numents >= tab->maxents) { + if (jpc_ppxstab_grow(tab, tab->maxents + 128)) { + return -1; + } + } + + for (i = tab->numents; i > inspt; --i) { + tab->ents[i] = tab->ents[i - 1]; + } + tab->ents[i] = ent; + ++tab->numents; + + return 0; +} + +jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab) +{ + jpc_streamlist_t *streams; + uchar *dataptr; + uint_fast32_t datacnt; + uint_fast32_t tpcnt; + jpc_ppxstabent_t *ent; + int entno; + jas_stream_t *stream; + int n; + + if (!(streams = jpc_streamlist_create())) { + goto error; + } + + if (!tab->numents) { + return streams; + } + + entno = 0; + ent = tab->ents[entno]; + dataptr = ent->data; + datacnt = ent->len; + for (;;) { + + /* Get the length of the packet header data for the current + tile-part. */ + if (datacnt < 4) { + goto error; + } + if (!(stream = jas_stream_memopen(0, 0))) { + goto error; + } + if (jpc_streamlist_insert(streams, jpc_streamlist_numstreams(streams), + stream)) { + goto error; + } + tpcnt = (dataptr[0] << 24) | (dataptr[1] << 16) | (dataptr[2] << 8) + | dataptr[3]; + datacnt -= 4; + dataptr += 4; + + /* Get the packet header data for the current tile-part. */ + while (tpcnt) { + if (!datacnt) { + if (++entno >= tab->numents) { + goto error; + } + ent = tab->ents[entno]; + dataptr = ent->data; + datacnt = ent->len; + } + n = JAS_MIN(tpcnt, datacnt); + if (jas_stream_write(stream, dataptr, n) != n) { + goto error; + } + tpcnt -= n; + dataptr += n; + datacnt -= n; + } + jas_stream_rewind(stream); + if (!datacnt) { + if (++entno >= tab->numents) { + break; + } + ent = tab->ents[entno]; + dataptr = ent->data; + datacnt = ent->len; + } + } + + return streams; + +error: + jpc_streamlist_destroy(streams); + return 0; +} + +int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab) +{ + int i; + jpc_ppxstabent_t *ent; + for (i = 0; i < tab->numents; ++i) { + ent = tab->ents[i]; + if (jas_stream_write(out, ent->data, ent->len) != JAS_CAST(int, ent->len)) { + return -1; + } + } + return 0; +} + +jpc_ppxstabent_t *jpc_ppxstabent_create() +{ + jpc_ppxstabent_t *ent; + if (!(ent = jas_malloc(sizeof(jpc_ppxstabent_t)))) { + return 0; + } + ent->data = 0; + ent->len = 0; + ent->ind = 0; + return ent; +} + +void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent) +{ + if (ent->data) { + jas_free(ent->data); + } + jas_free(ent); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_dec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,696 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * JPEG-2000 Decoder + * + * $Id: jpc_dec.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_DEC_H +#define JPC_DEC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_stream.h" + +#include "jpc_tsfb.h" +#include "jpc_bs.h" +#include "jpc_tagtree.h" +#include "jpc_cs.h" +#include "jpc_cod.h" +#include "jpc_mqdec.h" +#include "jpc_t2cod.h" + +/******************************************************************************\ +* Below are some ugly warts necessary to support packed packet headers. +\******************************************************************************/ + +/* PPM/PPT marker segment table entry. */ + +typedef struct { + + /* The index for this entry. */ + uint_fast16_t ind; + + /* The data length. */ + uint_fast32_t len; + + /* The data. */ + uchar *data; + +} jpc_ppxstabent_t; + +/* PPM/PPT marker segment table. */ + +typedef struct { + + /* The number of entries. */ + int numents; + + /* The maximum number of entries (i.e., the allocated size of the array + below). */ + int maxents; + + /* The table entries. */ + jpc_ppxstabent_t **ents; + +} jpc_ppxstab_t; + +/* Stream list class. */ + +typedef struct { + + /* The number of streams in this list. */ + int numstreams; + + /* The maximum number of streams that can be accomodated without + growing the streams array. */ + int maxstreams; + + /* The streams. */ + jas_stream_t **streams; + +} jpc_streamlist_t; + +/******************************************************************************\ +* Coding parameters class. +\******************************************************************************/ + +/* Per-component coding parameters. */ + +typedef struct { + + /* How were various coding parameters set? */ + int flags; + + /* Per-component coding style parameters (e.g., explicit precinct sizes) */ + uint_fast8_t csty; + + /* The number of resolution levels. */ + uint_fast8_t numrlvls; + + /* The code block width exponent. */ + uint_fast8_t cblkwidthexpn; + + /* The code block height exponent. */ + uint_fast8_t cblkheightexpn; + + /* The QMFB ID. */ + uint_fast8_t qmfbid; + + /* The quantization style. */ + uint_fast8_t qsty; + + /* The number of quantizer step sizes. */ + uint_fast16_t numstepsizes; + + /* The step sizes. */ + uint_fast16_t stepsizes[3 * JPC_MAXRLVLS + 1]; + + /* The number of guard bits. */ + uint_fast8_t numguardbits; + + /* The ROI shift value. */ + uint_fast8_t roishift; + + /* The code block parameters. */ + uint_fast8_t cblkctx; + + /* The precinct width exponents. */ + uint_fast8_t prcwidthexpns[JPC_MAXRLVLS]; + + /* The precinct height exponents. */ + uint_fast8_t prcheightexpns[JPC_MAXRLVLS]; + +} jpc_dec_ccp_t; + +/* Coding paramters. */ + +typedef struct { + + /* How were these coding parameters set? */ + int flags; + + /* Progression change list. */ + jpc_pchglist_t *pchglist; + + /* Progression order. */ + uint_fast8_t prgord; + + /* The number of layers. */ + uint_fast16_t numlyrs; + + /* The MCT ID. */ + uint_fast8_t mctid; + + /* The coding style parameters (e.g., SOP, EPH). */ + uint_fast8_t csty; + + /* The number of components. */ + int numcomps; + + /* The per-component coding parameters. */ + jpc_dec_ccp_t *ccps; + +} jpc_dec_cp_t; + +/******************************************************************************\ +* Decoder class. +\******************************************************************************/ + +/* Decoder per-segment state information. */ + +typedef struct jpc_dec_seg_s { + + /* The next segment in the list. */ + struct jpc_dec_seg_s *next; + + /* The previous segment in the list. */ + struct jpc_dec_seg_s *prev; + + /* The starting pass number for this segment. */ + int passno; + + /* The number of passes in this segment. */ + int numpasses; + + /* The maximum number of passes in this segment. */ + int maxpasses; + + /* The type of data in this segment (i.e., MQ or raw). */ + int type; + + /* A stream containing the data for this segment. */ + jas_stream_t *stream; + + /* The number of bytes destined for this segment from the packet + currently being decoded. */ + int cnt; + + /* A flag indicating if this segment has been terminated. */ + int complete; + + /* The layer number to which this segment belongs. */ + /* If the segment spans multiple layers, then the largest layer number + spanned by the segment is used. */ + int lyrno; + +} jpc_dec_seg_t; + +/* Decoder segment list. */ + +typedef struct { + + /* The first entry in the list. */ + jpc_dec_seg_t *head; + + /* The last entry in the list. */ + jpc_dec_seg_t *tail; + +} jpc_dec_seglist_t; + +/* Decoder per-code-block state information. */ + +typedef struct { + + /* The number of passes. */ + int numpasses; + + /* A list of segments that still need to be decoded. */ + jpc_dec_seglist_t segs; + + /* The first incomplete/partial segment. */ + jpc_dec_seg_t *curseg; + + /* The number of leading insignificant bit planes for this code block. */ + int numimsbs; + + /* The number of bits used to encode pass data lengths. */ + int numlenbits; + + /* The first pass number containing data for this code block. */ + int firstpassno; + + /* The MQ decoder. */ + jpc_mqdec_t *mqdec; + + /* The raw bit stream decoder. */ + jpc_bitstream_t *nulldec; + + /* The per-sample state information for this code block. */ + jas_matrix_t *flags; + + /* The sample data associated with this code block. */ + jas_matrix_t *data; + +} jpc_dec_cblk_t; + +/* Decoder per-code-block-group state information. */ + +typedef struct { + + /* The x-coordinate of the top-left corner of the precinct. */ + uint_fast32_t xstart; + + /* The y-coordinate of the top-left corner of the precinct. */ + uint_fast32_t ystart; + + /* The x-coordinate of the bottom-right corner of the precinct + (plus one). */ + uint_fast32_t xend; + + /* The y-coordinate of the bottom-right corner of the precinct + (plus one). */ + uint_fast32_t yend; + + /* The number of code blocks spanning this precinct in the horizontal + direction. */ + int numhcblks; + + /* The number of code blocks spanning this precinct in the vertical + direction. */ + int numvcblks; + + /* The total number of code blocks in this precinct. */ + int numcblks; + + /* The per code block information. */ + jpc_dec_cblk_t *cblks; + + /* The inclusion tag tree. */ + jpc_tagtree_t *incltagtree; + + /* The insignificant MSBs tag tree. */ + jpc_tagtree_t *numimsbstagtree; + +} jpc_dec_prc_t; + +/* Decoder per-band state information. */ + +typedef struct { + + /* The per-code-block-group state information. */ + jpc_dec_prc_t *prcs; + + /* The sample data associated with this band. */ + jas_matrix_t *data; + + /* The orientation of this band (i.e., LL, LH, HL, or HH). */ + int orient; + + /* The encoded quantizer step size. */ + int stepsize; + + /* The absolute quantizer step size. */ + jpc_fix_t absstepsize; + + /* The number of bit planes for this band. */ + int numbps; + + /* The analysis gain associated with this band. */ + int analgain; + + /* The ROI shift value for this band. */ + int roishift; + +} jpc_dec_band_t; + +/* Decoder per-resolution-level state information. */ + +typedef struct { + + /* The number of bands associated with this resolution level. */ + int numbands; + + /* The per-band information. */ + jpc_dec_band_t *bands; + + /* The x-coordinate of the top-left corner of the tile-component + at this resolution. */ + uint_fast32_t xstart; + + /* The y-coordinate of the top-left corner of the tile-component + at this resolution. */ + uint_fast32_t ystart; + + /* The x-coordinate of the bottom-right corner of the tile-component + at this resolution (plus one). */ + uint_fast32_t xend; + + /* The y-coordinate of the bottom-right corner of the tile-component + at this resolution (plus one). */ + uint_fast32_t yend; + + /* The exponent value for the nominal precinct width measured + relative to the associated LL band. */ + int prcwidthexpn; + + /* The exponent value for the nominal precinct height measured + relative to the associated LL band. */ + int prcheightexpn; + + /* The number of precincts in the horizontal direction. */ + int numhprcs; + + /* The number of precincts in the vertical direction. */ + int numvprcs; + + /* The total number of precincts. */ + int numprcs; + + /* The exponent value for the nominal code block group width. + This quantity is associated with the next lower resolution level + (assuming that there is one). */ + int cbgwidthexpn; + + /* The exponent value for the nominal code block group height + This quantity is associated with the next lower resolution level + (assuming that there is one). */ + int cbgheightexpn; + + /* The exponent value for the code block width. */ + uint_fast16_t cblkwidthexpn; + + /* The exponent value for the code block height. */ + uint_fast16_t cblkheightexpn; + +} jpc_dec_rlvl_t; + +/* Decoder per-tile-component state information. */ + +typedef struct { + + /* The x-coordinate of the top-left corner of the tile-component + in the coordinate system of the tile-component. */ + uint_fast32_t xstart; + + /* The y-coordinate of the top-left corner of the tile-component + in the coordinate system of the tile-component. */ + uint_fast32_t ystart; + + /* The x-coordinate of the bottom-right corner of the tile-component + in the coordinate system of the tile-component (plus one). */ + uint_fast32_t xend; + + /* The y-coordinate of the bottom-right corner of the tile-component + in the coordinate system of the tile-component (plus one). */ + uint_fast32_t yend; + + /* The component data for the current tile. */ + jas_matrix_t *data; + + /* The number of resolution levels. */ + int numrlvls; + + /* The per resolution level information. */ + jpc_dec_rlvl_t *rlvls; + + /* The TSFB. */ + jpc_tsfb_t *tsfb; + +} jpc_dec_tcomp_t; + +/* + * Tile states. + */ + +#define JPC_TILE_INIT 0 +#define JPC_TILE_ACTIVE 1 +#define JPC_TILE_ACTIVELAST 2 +#define JPC_TILE_DONE 3 + +/* Decoder per-tile state information. */ + +typedef struct { + + /* The processing state for this tile. */ + int state; + + /* The x-coordinate of the top-left corner of the tile on the reference + grid. */ + uint_fast32_t xstart; + + /* The y-coordinate of the top-left corner of the tile on the reference + grid. */ + uint_fast32_t ystart; + + /* The x-coordinate of the bottom-right corner of the tile on the + reference grid (plus one). */ + uint_fast32_t xend; + + /* The y-coordinate of the bottom-right corner of the tile on the + reference grid (plus one). */ + uint_fast32_t yend; + + /* The packed packet header data for this tile. */ + jpc_ppxstab_t *pptstab; + + /* A stream containing the packed packet header data for this tile. */ + jas_stream_t *pkthdrstream; + + /* The current position within the packed packet header stream. */ + long pkthdrstreampos; + + /* The coding parameters for this tile. */ + jpc_dec_cp_t *cp; + + /* The per tile-component information. */ + jpc_dec_tcomp_t *tcomps; + + /* The next expected tile-part number. */ + int partno; + + /* The number of tile-parts. */ + int numparts; + + /* The coding mode. */ + int realmode; + + /* The packet iterator for this tile. */ + jpc_pi_t *pi; + +} jpc_dec_tile_t; + +/* Decoder per-component state information. */ + +typedef struct { + + /* The horizontal sampling period. */ + uint_fast32_t hstep; + + /* The vertical sampling period. */ + uint_fast32_t vstep; + + /* The number of samples in the horizontal direction. */ + uint_fast32_t width; + + /* The number of samples in the vertical direction. */ + uint_fast32_t height; + + /* The precision of the sample data. */ + uint_fast16_t prec; + + /* The signedness of the sample data. */ + bool sgnd; + + /* The sample alignment horizontal offset. */ + uint_fast32_t hsubstep; + + /* The sample alignment vertical offset. */ + uint_fast32_t vsubstep; + +} jpc_dec_cmpt_t; + +/* Decoder state information. */ + +typedef struct { + + /* The decoded image. */ + jas_image_t *image; + + /* The x-coordinate of the top-left corner of the image area on + the reference grid. */ + uint_fast32_t xstart; + + /* The y-coordinate of the top-left corner of the image area on + the reference grid. */ + uint_fast32_t ystart; + + /* The x-coordinate of the bottom-right corner of the image area on + the reference grid (plus one). */ + uint_fast32_t xend; + + /* The y-coordinate of the bottom-right corner of the image area on + the reference grid (plus one). */ + uint_fast32_t yend; + + /* The nominal tile width in units of the image reference grid. */ + uint_fast32_t tilewidth; + + /* The nominal tile height in units of the image reference grid. */ + uint_fast32_t tileheight; + + /* The horizontal offset from the origin of the reference grid to the + left side of the first tile. */ + uint_fast32_t tilexoff; + + /* The vertical offset from the origin of the reference grid to the + top side of the first tile. */ + uint_fast32_t tileyoff; + + /* The number of tiles spanning the image area in the vertical + direction. */ + int numhtiles; + + /* The number of tiles spanning the image area in the horizontal + direction. */ + int numvtiles; + + /* The total number of tiles. */ + int numtiles; + + /* The per-tile information. */ + jpc_dec_tile_t *tiles; + + /* The tile currently being processed. */ + jpc_dec_tile_t *curtile; + + /* The number of components. */ + int numcomps; + + /* The stream containing the input JPEG-2000 code stream data. */ + jas_stream_t *in; + + /* The default coding parameters for all tiles. */ + jpc_dec_cp_t *cp; + + /* The maximum number of layers that may be decoded. */ + int maxlyrs; + + /* The maximum number of packets that may be decoded. */ + int maxpkts; + + /* The number of packets decoded so far in the processing of the entire + code stream. */ + int numpkts; + + /* The next expected PPM marker segment sequence number. */ + int ppmseqno; + + /* The current state for code stream processing. */ + int state; + + /* The per-component information. */ + jpc_dec_cmpt_t *cmpts; + + /* The information from PPM marker segments. */ + jpc_ppxstab_t *ppmstab; + + /* A list of streams containing packet header data from PPM marker + segments. */ + jpc_streamlist_t *pkthdrstreams; + + /* The expected ending offset for a tile-part. */ + long curtileendoff; + + /* This is required by the tier-2 decoder. */ + jpc_cstate_t *cstate; + +} jpc_dec_t; + +/* Decoder options. */ + +typedef struct { + + /* The debug level for the decoder. */ + int debug; + + /* The maximum number of layers to decode. */ + int maxlyrs; + + /* The maximum number of packets to decode. */ + int maxpkts; + +} jpc_dec_importopts_t; + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Create a decoder segment object. */ +jpc_dec_seg_t *jpc_seg_alloc(void); + +/* Destroy a decoder segment object. */ +void jpc_seg_destroy(jpc_dec_seg_t *seg); + +/* Remove a segment from a segment list. */ +void jpc_seglist_remove(jpc_dec_seglist_t *list, jpc_dec_seg_t *node); + +/* Insert a segment into a segment list. */ +void jpc_seglist_insert(jpc_dec_seglist_t *list, jpc_dec_seg_t *ins, + jpc_dec_seg_t *node); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2620 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_string.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_image.h" +#include "jasper/jas_fix.h" +#include "jasper/jas_tvp.h" +#include "jasper/jas_version.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" + +#include "jpc_flt.h" +#include "jpc_fix.h" +#include "jpc_tagtree.h" +#include "jpc_enc.h" +#include "jpc_cs.h" +#include "jpc_mct.h" +#include "jpc_tsfb.h" +#include "jpc_qmfb.h" +#include "jpc_t1enc.h" +#include "jpc_t2enc.h" +#include "jpc_cod.h" +#include "jpc_math.h" +#include "jpc_util.h" + +/******************************************************************************\ +* +\******************************************************************************/ + +#define JPC_POW2(n) \ + (1 << (n)) + +#define JPC_FLOORTOMULTPOW2(x, n) \ + (((n) > 0) ? ((x) & (~((1 << n) - 1))) : (x)) +/* Round to the nearest multiple of the specified power of two in the + direction of negative infinity. */ + +#define JPC_CEILTOMULTPOW2(x, n) \ + (((n) > 0) ? JPC_FLOORTOMULTPOW2(((x) + (1 << (n)) - 1), n) : (x)) +/* Round to the nearest multiple of the specified power of two in the + direction of positive infinity. */ + +#define JPC_POW2(n) \ + (1 << (n)) + +jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno); +void jpc_enc_tile_destroy(jpc_enc_tile_t *tile); + +static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp, + jas_image_t *image, jpc_enc_tile_t *tile); +static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt); +static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp, + jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos); +static void rlvl_destroy(jpc_enc_rlvl_t *rlvl); +static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp, + jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos); +static void band_destroy(jpc_enc_band_t *bands); +static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_cp_t *cp, + jpc_enc_band_t *band); +static void prc_destroy(jpc_enc_prc_t *prcs); +static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk, jpc_enc_cp_t *cp, + jpc_enc_prc_t *prc); +static void cblk_destroy(jpc_enc_cblk_t *cblks); +int ratestrtosize(char *s, uint_fast32_t rawsize, uint_fast32_t *size); +static void pass_destroy(jpc_enc_pass_t *pass); +void jpc_enc_dump(jpc_enc_t *enc); + +/******************************************************************************\ +* Local prototypes. +\******************************************************************************/ + +int dump_passes(jpc_enc_pass_t *passes, int numpasses, jpc_enc_cblk_t *cblk); +void calcrdslopes(jpc_enc_cblk_t *cblk); +void dump_layeringinfo(jpc_enc_t *enc); +static int jpc_calcssexp(jpc_fix_t stepsize); +static int jpc_calcssmant(jpc_fix_t stepsize); +void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize); +static int jpc_enc_encodemainhdr(jpc_enc_t *enc); +static int jpc_enc_encodemainbody(jpc_enc_t *enc); +int jpc_enc_encodetiledata(jpc_enc_t *enc); +jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image); +void jpc_enc_destroy(jpc_enc_t *enc); +static int jpc_enc_encodemainhdr(jpc_enc_t *enc); +static int jpc_enc_encodemainbody(jpc_enc_t *enc); +int jpc_enc_encodetiledata(jpc_enc_t *enc); +int rateallocate(jpc_enc_t *enc, int numlyrs, uint_fast32_t *cumlens); +int setins(int numvalues, jpc_flt_t *values, jpc_flt_t value); +static jpc_enc_cp_t *cp_create(char *optstr, jas_image_t *image); +void jpc_enc_cp_destroy(jpc_enc_cp_t *cp); +static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn); + +static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn) +{ + int p; + uint_fast32_t mant; + uint_fast32_t expn; + int n; + + if (absdelta < 0) { + abort(); + } + + p = jpc_firstone(absdelta) - JPC_FIX_FRACBITS; + n = 11 - jpc_firstone(absdelta); + mant = ((n < 0) ? (absdelta >> (-n)) : (absdelta << n)) & 0x7ff; + expn = scaleexpn - p; + if (scaleexpn < p) { + abort(); + } + return JPC_QCX_EXPN(expn) | JPC_QCX_MANT(mant); +} + +typedef enum { + OPT_DEBUG, + OPT_IMGAREAOFFX, + OPT_IMGAREAOFFY, + OPT_TILEGRDOFFX, + OPT_TILEGRDOFFY, + OPT_TILEWIDTH, + OPT_TILEHEIGHT, + OPT_PRCWIDTH, + OPT_PRCHEIGHT, + OPT_CBLKWIDTH, + OPT_CBLKHEIGHT, + OPT_MODE, + OPT_PRG, + OPT_NOMCT, + OPT_MAXRLVLS, + OPT_SOP, + OPT_EPH, + OPT_LAZY, + OPT_TERMALL, + OPT_SEGSYM, + OPT_VCAUSAL, + OPT_RESET, + OPT_PTERM, + OPT_NUMGBITS, + OPT_RATE, + OPT_ILYRRATES, + OPT_JP2OVERHEAD +} optid_t; + +jas_taginfo_t encopts[] = { + {OPT_DEBUG, "debug"}, + {OPT_IMGAREAOFFX, "imgareatlx"}, + {OPT_IMGAREAOFFY, "imgareatly"}, + {OPT_TILEGRDOFFX, "tilegrdtlx"}, + {OPT_TILEGRDOFFY, "tilegrdtly"}, + {OPT_TILEWIDTH, "tilewidth"}, + {OPT_TILEHEIGHT, "tileheight"}, + {OPT_PRCWIDTH, "prcwidth"}, + {OPT_PRCHEIGHT, "prcheight"}, + {OPT_CBLKWIDTH, "cblkwidth"}, + {OPT_CBLKHEIGHT, "cblkheight"}, + {OPT_MODE, "mode"}, + {OPT_PRG, "prg"}, + {OPT_NOMCT, "nomct"}, + {OPT_MAXRLVLS, "numrlvls"}, + {OPT_SOP, "sop"}, + {OPT_EPH, "eph"}, + {OPT_LAZY, "lazy"}, + {OPT_TERMALL, "termall"}, + {OPT_SEGSYM, "segsym"}, + {OPT_VCAUSAL, "vcausal"}, + {OPT_PTERM, "pterm"}, + {OPT_RESET, "resetprob"}, + {OPT_NUMGBITS, "numgbits"}, + {OPT_RATE, "rate"}, + {OPT_ILYRRATES, "ilyrrates"}, + {OPT_JP2OVERHEAD, "_jp2overhead"}, + {-1, 0} +}; + +typedef enum { + PO_L = 0, + PO_R +} poid_t; + + +jas_taginfo_t prgordtab[] = { + {JPC_COD_LRCPPRG, "lrcp"}, + {JPC_COD_RLCPPRG, "rlcp"}, + {JPC_COD_RPCLPRG, "rpcl"}, + {JPC_COD_PCRLPRG, "pcrl"}, + {JPC_COD_CPRLPRG, "cprl"}, + {-1, 0} +}; + +typedef enum { + MODE_INT, + MODE_REAL +} modeid_t; + +jas_taginfo_t modetab[] = { + {MODE_INT, "int"}, + {MODE_REAL, "real"}, + {-1, 0} +}; + +/******************************************************************************\ +* The main encoder entry point. +\******************************************************************************/ + +int jpc_encode(jas_image_t *image, jas_stream_t *out, char *optstr) +{ + jpc_enc_t *enc; + jpc_enc_cp_t *cp; + + enc = 0; + cp = 0; + + jpc_initluts(); + + if (!(cp = cp_create(optstr, image))) { + jas_eprintf("invalid JP encoder options\n"); + goto error; + } + + if (!(enc = jpc_enc_create(cp, out, image))) { + goto error; + } + cp = 0; + + /* Encode the main header. */ + if (jpc_enc_encodemainhdr(enc)) { + goto error; + } + + /* Encode the main body. This constitutes most of the encoding work. */ + if (jpc_enc_encodemainbody(enc)) { + goto error; + } + + /* Write EOC marker segment. */ + if (!(enc->mrk = jpc_ms_create(JPC_MS_EOC))) { + goto error; + } + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write EOI marker\n"); + goto error; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + + if (jas_stream_flush(enc->out)) { + goto error; + } + + jpc_enc_destroy(enc); + + return 0; + +error: + if (cp) { + jpc_enc_cp_destroy(cp); + } + if (enc) { + jpc_enc_destroy(enc); + } + return -1; +} + +/******************************************************************************\ +* Option parsing code. +\******************************************************************************/ + +static jpc_enc_cp_t *cp_create(char *optstr, jas_image_t *image) +{ + jpc_enc_cp_t *cp; + jas_tvparser_t *tvp; + int ret; + int numilyrrates; + double *ilyrrates; + int i; + int tagid; + jpc_enc_tcp_t *tcp; + jpc_enc_tccp_t *tccp; + jpc_enc_ccp_t *ccp; + int cmptno; + uint_fast16_t rlvlno; + uint_fast16_t prcwidthexpn; + uint_fast16_t prcheightexpn; + bool enablemct; + uint_fast32_t jp2overhead; + uint_fast16_t lyrno; + uint_fast32_t hsteplcm; + uint_fast32_t vsteplcm; + bool mctvalid; + + tvp = 0; + cp = 0; + ilyrrates = 0; + numilyrrates = 0; + + if (!(cp = jas_malloc(sizeof(jpc_enc_cp_t)))) { + goto error; + } + + prcwidthexpn = 15; + prcheightexpn = 15; + enablemct = true; + jp2overhead = 0; + + cp->ccps = 0; + cp->debug = 0; + cp->imgareatlx = UINT_FAST32_MAX; + cp->imgareatly = UINT_FAST32_MAX; + cp->refgrdwidth = 0; + cp->refgrdheight = 0; + cp->tilegrdoffx = UINT_FAST32_MAX; + cp->tilegrdoffy = UINT_FAST32_MAX; + cp->tilewidth = 0; + cp->tileheight = 0; + cp->numcmpts = jas_image_numcmpts(image); + + hsteplcm = 1; + vsteplcm = 1; + for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) { + if (jas_image_cmptbrx(image, cmptno) + jas_image_cmpthstep(image, cmptno) <= + jas_image_brx(image) || jas_image_cmptbry(image, cmptno) + + jas_image_cmptvstep(image, cmptno) <= jas_image_bry(image)) { + jas_eprintf("unsupported image type\n"); + goto error; + } + /* Note: We ought to be calculating the LCMs here. Fix some day. */ + hsteplcm *= jas_image_cmpthstep(image, cmptno); + vsteplcm *= jas_image_cmptvstep(image, cmptno); + } + + if (!(cp->ccps = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_ccp_t)))) { + goto error; + } + for (cmptno = 0, ccp = cp->ccps; cmptno < JAS_CAST(int, cp->numcmpts); ++cmptno, + ++ccp) { + ccp->sampgrdstepx = jas_image_cmpthstep(image, cmptno); + ccp->sampgrdstepy = jas_image_cmptvstep(image, cmptno); + /* XXX - this isn't quite correct for more general image */ + ccp->sampgrdsubstepx = 0; + ccp->sampgrdsubstepx = 0; + ccp->prec = jas_image_cmptprec(image, cmptno); + ccp->sgnd = jas_image_cmptsgnd(image, cmptno); + ccp->numstepsizes = 0; + memset(ccp->stepsizes, 0, sizeof(ccp->stepsizes)); + } + + cp->rawsize = jas_image_rawsize(image); + cp->totalsize = UINT_FAST32_MAX; + + tcp = &cp->tcp; + tcp->csty = 0; + tcp->intmode = true; + tcp->prg = JPC_COD_LRCPPRG; + tcp->numlyrs = 1; + tcp->ilyrrates = 0; + + tccp = &cp->tccp; + tccp->csty = 0; + tccp->maxrlvls = 6; + tccp->cblkwidthexpn = 6; + tccp->cblkheightexpn = 6; + tccp->cblksty = 0; + tccp->numgbits = 2; + + if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) { + goto error; + } + + while (!(ret = jas_tvparser_next(tvp))) { + switch (jas_taginfo_nonull(jas_taginfos_lookup(encopts, + jas_tvparser_gettag(tvp)))->id) { + case OPT_DEBUG: + cp->debug = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_IMGAREAOFFX: + cp->imgareatlx = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_IMGAREAOFFY: + cp->imgareatly = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_TILEGRDOFFX: + cp->tilegrdoffx = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_TILEGRDOFFY: + cp->tilegrdoffy = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_TILEWIDTH: + cp->tilewidth = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_TILEHEIGHT: + cp->tileheight = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_PRCWIDTH: + prcwidthexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); + break; + case OPT_PRCHEIGHT: + prcheightexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); + break; + case OPT_CBLKWIDTH: + tccp->cblkwidthexpn = + jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); + break; + case OPT_CBLKHEIGHT: + tccp->cblkheightexpn = + jpc_floorlog2(atoi(jas_tvparser_getval(tvp))); + break; + case OPT_MODE: + if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(modetab, + jas_tvparser_getval(tvp)))->id) < 0) { + jas_eprintf("ignoring invalid mode %s\n", + jas_tvparser_getval(tvp)); + } else { + tcp->intmode = (tagid == MODE_INT); + } + break; + case OPT_PRG: + if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(prgordtab, + jas_tvparser_getval(tvp)))->id) < 0) { + jas_eprintf("ignoring invalid progression order %s\n", + jas_tvparser_getval(tvp)); + } else { + tcp->prg = tagid; + } + break; + case OPT_NOMCT: + enablemct = false; + break; + case OPT_MAXRLVLS: + tccp->maxrlvls = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_SOP: + cp->tcp.csty |= JPC_COD_SOP; + break; + case OPT_EPH: + cp->tcp.csty |= JPC_COD_EPH; + break; + case OPT_LAZY: + tccp->cblksty |= JPC_COX_LAZY; + break; + case OPT_TERMALL: + tccp->cblksty |= JPC_COX_TERMALL; + break; + case OPT_SEGSYM: + tccp->cblksty |= JPC_COX_SEGSYM; + break; + case OPT_VCAUSAL: + tccp->cblksty |= JPC_COX_VSC; + break; + case OPT_RESET: + tccp->cblksty |= JPC_COX_RESET; + break; + case OPT_PTERM: + tccp->cblksty |= JPC_COX_PTERM; + break; + case OPT_NUMGBITS: + cp->tccp.numgbits = atoi(jas_tvparser_getval(tvp)); + break; + case OPT_RATE: + if (ratestrtosize(jas_tvparser_getval(tvp), cp->rawsize, + &cp->totalsize)) { + jas_eprintf("ignoring bad rate specifier %s\n", + jas_tvparser_getval(tvp)); + } + break; + case OPT_ILYRRATES: + if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates, + &ilyrrates)) { + jas_eprintf("warning: invalid intermediate layer rates specifier ignored (%s)\n", + jas_tvparser_getval(tvp)); + } + break; + + case OPT_JP2OVERHEAD: + jp2overhead = atoi(jas_tvparser_getval(tvp)); + break; + default: + jas_eprintf("warning: ignoring invalid option %s\n", + jas_tvparser_gettag(tvp)); + break; + } + } + + jas_tvparser_destroy(tvp); + tvp = 0; + + if (cp->totalsize != UINT_FAST32_MAX) { + cp->totalsize = (cp->totalsize > jp2overhead) ? + (cp->totalsize - jp2overhead) : 0; + } + + if (cp->imgareatlx == UINT_FAST32_MAX) { + cp->imgareatlx = 0; + } else { + if (hsteplcm != 1) { + jas_eprintf("warning: overriding imgareatlx value\n"); + } + cp->imgareatlx *= hsteplcm; + } + if (cp->imgareatly == UINT_FAST32_MAX) { + cp->imgareatly = 0; + } else { + if (vsteplcm != 1) { + jas_eprintf("warning: overriding imgareatly value\n"); + } + cp->imgareatly *= vsteplcm; + } + cp->refgrdwidth = cp->imgareatlx + jas_image_width(image); + cp->refgrdheight = cp->imgareatly + jas_image_height(image); + if (cp->tilegrdoffx == UINT_FAST32_MAX) { + cp->tilegrdoffx = cp->imgareatlx; + } + if (cp->tilegrdoffy == UINT_FAST32_MAX) { + cp->tilegrdoffy = cp->imgareatly; + } + if (!cp->tilewidth) { + cp->tilewidth = cp->refgrdwidth - cp->tilegrdoffx; + } + if (!cp->tileheight) { + cp->tileheight = cp->refgrdheight - cp->tilegrdoffy; + } + + if (cp->numcmpts == 3) { + mctvalid = true; + for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) { + if (jas_image_cmptprec(image, cmptno) != jas_image_cmptprec(image, 0) || + jas_image_cmptsgnd(image, cmptno) != jas_image_cmptsgnd(image, 0) || + jas_image_cmptwidth(image, cmptno) != jas_image_cmptwidth(image, 0) || + jas_image_cmptheight(image, cmptno) != jas_image_cmptheight(image, 0)) { + mctvalid = false; + } + } + } else { + mctvalid = false; + } + if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_RGB) { + jas_eprintf("warning: color space apparently not RGB\n"); + } + if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) == JAS_CLRSPC_FAM_RGB) { + tcp->mctid = (tcp->intmode) ? (JPC_MCT_RCT) : (JPC_MCT_ICT); + } else { + tcp->mctid = JPC_MCT_NONE; + } + tccp->qmfbid = (tcp->intmode) ? (JPC_COX_RFT) : (JPC_COX_INS); + + for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) { + tccp->prcwidthexpns[rlvlno] = prcwidthexpn; + tccp->prcheightexpns[rlvlno] = prcheightexpn; + } + if (prcwidthexpn != 15 || prcheightexpn != 15) { + tccp->csty |= JPC_COX_PRT; + } + + /* Ensure that the tile width and height is valid. */ + if (!cp->tilewidth) { + jas_eprintf("invalid tile width %lu\n", (unsigned long) + cp->tilewidth); + goto error; + } + if (!cp->tileheight) { + jas_eprintf("invalid tile height %lu\n", (unsigned long) + cp->tileheight); + goto error; + } + + /* Ensure that the tile grid offset is valid. */ + if (cp->tilegrdoffx > cp->imgareatlx || + cp->tilegrdoffy > cp->imgareatly || + cp->tilegrdoffx + cp->tilewidth < cp->imgareatlx || + cp->tilegrdoffy + cp->tileheight < cp->imgareatly) { + jas_eprintf("invalid tile grid offset (%lu, %lu)\n", + (unsigned long) cp->tilegrdoffx, (unsigned long) + cp->tilegrdoffy); + goto error; + } + + cp->numhtiles = JPC_CEILDIV(cp->refgrdwidth - cp->tilegrdoffx, + cp->tilewidth); + cp->numvtiles = JPC_CEILDIV(cp->refgrdheight - cp->tilegrdoffy, + cp->tileheight); + cp->numtiles = cp->numhtiles * cp->numvtiles; + + if (ilyrrates && numilyrrates > 0) { + tcp->numlyrs = numilyrrates + 1; + if (!(tcp->ilyrrates = jas_alloc2((tcp->numlyrs - 1), + sizeof(jpc_fix_t)))) { + goto error; + } + for (i = 0; i < JAS_CAST(int, tcp->numlyrs - 1); ++i) { + tcp->ilyrrates[i] = jpc_dbltofix(ilyrrates[i]); + } + } + + /* Ensure that the integer mode is used in the case of lossless + coding. */ + if (cp->totalsize == UINT_FAST32_MAX && (!cp->tcp.intmode)) { + jas_eprintf("cannot use real mode for lossless coding\n"); + goto error; + } + + /* Ensure that the precinct width is valid. */ + if (prcwidthexpn > 15) { + jas_eprintf("invalid precinct width\n"); + goto error; + } + + /* Ensure that the precinct height is valid. */ + if (prcheightexpn > 15) { + jas_eprintf("invalid precinct height\n"); + goto error; + } + + /* Ensure that the code block width is valid. */ + if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) { + jas_eprintf("invalid code block width %d\n", + JPC_POW2(cp->tccp.cblkwidthexpn)); + goto error; + } + + /* Ensure that the code block height is valid. */ + if (cp->tccp.cblkheightexpn < 2 || cp->tccp.cblkheightexpn > 12) { + jas_eprintf("invalid code block height %d\n", + JPC_POW2(cp->tccp.cblkheightexpn)); + goto error; + } + + /* Ensure that the code block size is not too large. */ + if (cp->tccp.cblkwidthexpn + cp->tccp.cblkheightexpn > 12) { + jas_eprintf("code block size too large\n"); + goto error; + } + + /* Ensure that the number of layers is valid. */ + if (cp->tcp.numlyrs > 16384) { + jas_eprintf("too many layers\n"); + goto error; + } + + /* There must be at least one resolution level. */ + if (cp->tccp.maxrlvls < 1) { + jas_eprintf("must be at least one resolution level\n"); + goto error; + } + + /* Ensure that the number of guard bits is valid. */ + if (cp->tccp.numgbits > 8) { + jas_eprintf("invalid number of guard bits\n"); + goto error; + } + + /* Ensure that the rate is within the legal range. */ + if (cp->totalsize != UINT_FAST32_MAX && cp->totalsize > cp->rawsize) { + jas_eprintf("warning: specified rate is unreasonably large (%lu > %lu)\n", (unsigned long) cp->totalsize, (unsigned long) cp->rawsize); + } + + /* Ensure that the intermediate layer rates are valid. */ + if (tcp->numlyrs > 1) { + /* The intermediate layers rates must increase monotonically. */ + for (lyrno = 0; lyrno + 2 < tcp->numlyrs; ++lyrno) { + if (tcp->ilyrrates[lyrno] >= tcp->ilyrrates[lyrno + 1]) { + jas_eprintf("intermediate layer rates must increase monotonically\n"); + goto error; + } + } + /* The intermediate layer rates must be less than the overall rate. */ + if (cp->totalsize != UINT_FAST32_MAX) { + for (lyrno = 0; lyrno < tcp->numlyrs - 1; ++lyrno) { + if (jpc_fixtodbl(tcp->ilyrrates[lyrno]) > ((double) cp->totalsize) + / cp->rawsize) { + jas_eprintf("warning: intermediate layer rates must be less than overall rate\n"); + goto error; + } + } + } + } + + if (ilyrrates) { + jas_free(ilyrrates); + } + + return cp; + +error: + + if (ilyrrates) { + jas_free(ilyrrates); + } + if (tvp) { + jas_tvparser_destroy(tvp); + } + if (cp) { + jpc_enc_cp_destroy(cp); + } + return 0; +} + +void jpc_enc_cp_destroy(jpc_enc_cp_t *cp) +{ + if (cp->ccps) { + if (cp->tcp.ilyrrates) { + jas_free(cp->tcp.ilyrrates); + } + jas_free(cp->ccps); + } + jas_free(cp); +} + +int ratestrtosize(char *s, uint_fast32_t rawsize, uint_fast32_t *size) +{ + char *cp; + jpc_flt_t f; + + /* Note: This function must not modify output size on failure. */ + if ((cp = strchr(s, 'B'))) { + *size = atoi(s); + } else { + f = atof(s); + if (f < 0) { + *size = 0; + } else if (f > 1.0) { + *size = rawsize + 1; + } else { + *size = f * rawsize; + } + } + return 0; +} + +/******************************************************************************\ +* Encoder constructor and destructor. +\******************************************************************************/ + +jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image) +{ + jpc_enc_t *enc; + + enc = 0; + + if (!(enc = jas_malloc(sizeof(jpc_enc_t)))) { + goto error; + } + + enc->image = image; + enc->out = out; + enc->cp = cp; + enc->cstate = 0; + enc->tmpstream = 0; + enc->mrk = 0; + enc->curtile = 0; + + if (!(enc->cstate = jpc_cstate_create())) { + goto error; + } + enc->len = 0; + enc->mainbodysize = 0; + + return enc; + +error: + + if (enc) { + jpc_enc_destroy(enc); + } + return 0; +} + +void jpc_enc_destroy(jpc_enc_t *enc) +{ + /* The image object (i.e., enc->image) and output stream object + (i.e., enc->out) are created outside of the encoder. + Therefore, they must not be destroyed here. */ + + if (enc->curtile) { + jpc_enc_tile_destroy(enc->curtile); + } + if (enc->cp) { + jpc_enc_cp_destroy(enc->cp); + } + if (enc->cstate) { + jpc_cstate_destroy(enc->cstate); + } + if (enc->tmpstream) { + jas_stream_close(enc->tmpstream); + } + + jas_free(enc); +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +static int jpc_calcssmant(jpc_fix_t stepsize) +{ + int n; + int e; + int m; + + n = jpc_firstone(stepsize); + e = n - JPC_FIX_FRACBITS; + if (n >= 11) { + m = (stepsize >> (n - 11)) & 0x7ff; + } else { + m = (stepsize & ((1 << n) - 1)) << (11 - n); + } + return m; +} + +static int jpc_calcssexp(jpc_fix_t stepsize) +{ + return jpc_firstone(stepsize) - JPC_FIX_FRACBITS; +} + +static int jpc_enc_encodemainhdr(jpc_enc_t *enc) +{ + jpc_siz_t *siz; + jpc_cod_t *cod; + jpc_qcd_t *qcd; + int i; +long startoff; +long mainhdrlen; + jpc_enc_cp_t *cp; + jpc_qcc_t *qcc; + jpc_enc_tccp_t *tccp; + uint_fast16_t cmptno; + jpc_tsfb_band_t bandinfos[JPC_MAXBANDS]; + jpc_fix_t mctsynweight; + jpc_enc_tcp_t *tcp; + jpc_tsfb_t *tsfb; + jpc_tsfb_band_t *bandinfo; + uint_fast16_t numbands; + uint_fast16_t bandno; + uint_fast16_t rlvlno; + uint_fast16_t analgain; + jpc_fix_t absstepsize; + char buf[1024]; + jpc_com_t *com; + + cp = enc->cp; + +startoff = jas_stream_getrwcount(enc->out); + + /* Write SOC marker segment. */ + if (!(enc->mrk = jpc_ms_create(JPC_MS_SOC))) { + return -1; + } + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write SOC marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + + /* Write SIZ marker segment. */ + if (!(enc->mrk = jpc_ms_create(JPC_MS_SIZ))) { + return -1; + } + siz = &enc->mrk->parms.siz; + siz->caps = 0; + siz->xoff = cp->imgareatlx; + siz->yoff = cp->imgareatly; + siz->width = cp->refgrdwidth; + siz->height = cp->refgrdheight; + siz->tilexoff = cp->tilegrdoffx; + siz->tileyoff = cp->tilegrdoffy; + siz->tilewidth = cp->tilewidth; + siz->tileheight = cp->tileheight; + siz->numcomps = cp->numcmpts; + siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)); + assert(siz->comps); + for (i = 0; i < JAS_CAST(int, cp->numcmpts); ++i) { + siz->comps[i].prec = cp->ccps[i].prec; + siz->comps[i].sgnd = cp->ccps[i].sgnd; + siz->comps[i].hsamp = cp->ccps[i].sampgrdstepx; + siz->comps[i].vsamp = cp->ccps[i].sampgrdstepy; + } + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write SIZ marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + + if (!(enc->mrk = jpc_ms_create(JPC_MS_COM))) { + return -1; + } + sprintf(buf, "Creator: JasPer Version %s", jas_getversion()); + com = &enc->mrk->parms.com; + com->len = strlen(buf); + com->regid = JPC_COM_LATIN; + if (!(com->data = JAS_CAST(uchar *, jas_strdup(buf)))) { + abort(); + } + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write COM marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + +#if 0 + if (!(enc->mrk = jpc_ms_create(JPC_MS_CRG))) { + return -1; + } + crg = &enc->mrk->parms.crg; + crg->comps = jas_alloc2(crg->numcomps, sizeof(jpc_crgcomp_t)); + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write CRG marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; +#endif + + tcp = &cp->tcp; + tccp = &cp->tccp; + for (cmptno = 0; cmptno < cp->numcmpts; ++cmptno) { + tsfb = jpc_cod_gettsfb(tccp->qmfbid, tccp->maxrlvls - 1); + jpc_tsfb_getbands(tsfb, 0, 0, 1 << tccp->maxrlvls, 1 << tccp->maxrlvls, + bandinfos); + jpc_tsfb_destroy(tsfb); + mctsynweight = jpc_mct_getsynweight(tcp->mctid, cmptno); + numbands = 3 * tccp->maxrlvls - 2; + for (bandno = 0, bandinfo = bandinfos; bandno < numbands; + ++bandno, ++bandinfo) { + rlvlno = (bandno) ? ((bandno - 1) / 3 + 1) : 0; + analgain = JPC_NOMINALGAIN(tccp->qmfbid, tccp->maxrlvls, + rlvlno, bandinfo->orient); + if (!tcp->intmode) { + absstepsize = jpc_fix_div(jpc_inttofix(1 << + (analgain + 1)), bandinfo->synenergywt); + } else { + absstepsize = jpc_inttofix(1); + } + cp->ccps[cmptno].stepsizes[bandno] = + jpc_abstorelstepsize(absstepsize, + cp->ccps[cmptno].prec + analgain); + } + cp->ccps[cmptno].numstepsizes = numbands; + } + + if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) { + return -1; + } + cod = &enc->mrk->parms.cod; + cod->csty = cp->tccp.csty | cp->tcp.csty; + cod->compparms.csty = cp->tccp.csty | cp->tcp.csty; + cod->compparms.numdlvls = cp->tccp.maxrlvls - 1; + cod->compparms.numrlvls = cp->tccp.maxrlvls; + cod->prg = cp->tcp.prg; + cod->numlyrs = cp->tcp.numlyrs; + cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkwidthexpn); + cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkheightexpn); + cod->compparms.cblksty = cp->tccp.cblksty; + cod->compparms.qmfbid = cp->tccp.qmfbid; + cod->mctrans = (cp->tcp.mctid != JPC_MCT_NONE); + if (tccp->csty & JPC_COX_PRT) { + for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) { + cod->compparms.rlvls[rlvlno].parwidthval = tccp->prcwidthexpns[rlvlno]; + cod->compparms.rlvls[rlvlno].parheightval = tccp->prcheightexpns[rlvlno]; + } + } + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write COD marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + + if (!(enc->mrk = jpc_ms_create(JPC_MS_QCD))) { + return -1; + } + qcd = &enc->mrk->parms.qcd; + qcd->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ? + JPC_QCX_SEQNT : JPC_QCX_NOQNT; + qcd->compparms.numstepsizes = cp->ccps[0].numstepsizes; + qcd->compparms.numguard = cp->tccp.numgbits; + qcd->compparms.stepsizes = cp->ccps[0].stepsizes; + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + return -1; + } + /* We do not want the step size array to be freed! */ + qcd->compparms.stepsizes = 0; + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + + tccp = &cp->tccp; + for (cmptno = 1; cmptno < cp->numcmpts; ++cmptno) { + if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) { + return -1; + } + qcc = &enc->mrk->parms.qcc; + qcc->compno = cmptno; + qcc->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ? + JPC_QCX_SEQNT : JPC_QCX_NOQNT; + qcc->compparms.numstepsizes = cp->ccps[cmptno].numstepsizes; + qcc->compparms.numguard = cp->tccp.numgbits; + qcc->compparms.stepsizes = cp->ccps[cmptno].stepsizes; + if (jpc_putms(enc->out, enc->cstate, enc->mrk)) { + return -1; + } + /* We do not want the step size array to be freed! */ + qcc->compparms.stepsizes = 0; + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + } + +#define MAINTLRLEN 2 + mainhdrlen = jas_stream_getrwcount(enc->out) - startoff; + enc->len += mainhdrlen; + if (enc->cp->totalsize != UINT_FAST32_MAX) { + uint_fast32_t overhead; + overhead = mainhdrlen + MAINTLRLEN; + enc->mainbodysize = (enc->cp->totalsize >= overhead) ? + (enc->cp->totalsize - overhead) : 0; + } else { + enc->mainbodysize = UINT_FAST32_MAX; + } + + return 0; +} + +static int jpc_enc_encodemainbody(jpc_enc_t *enc) +{ + int tileno; + int tilex; + int tiley; + int i; + jpc_sot_t *sot; + jpc_enc_tcmpt_t *comp; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_rlvl_t *lvl; + int rlvlno; + jpc_qcc_t *qcc; + jpc_cod_t *cod; + int adjust; + int j; + int absbandno; + long numbytes; + long tilehdrlen; + long tilelen; + jpc_enc_tile_t *tile; + jpc_enc_cp_t *cp; + double rho; + int lyrno; + int cmptno; + int samestepsizes; + jpc_enc_ccp_t *ccps; + jpc_enc_tccp_t *tccp; +int bandno; +uint_fast32_t x; +uint_fast32_t y; +int mingbits; +int actualnumbps; +jpc_fix_t mxmag; +jpc_fix_t mag; +int numgbits; + + cp = enc->cp; + + /* Avoid compile warnings. */ + numbytes = 0; + + for (tileno = 0; tileno < JAS_CAST(int, cp->numtiles); ++tileno) { + tilex = tileno % cp->numhtiles; + tiley = tileno / cp->numhtiles; + + if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image, tileno))) { + abort(); + } + + tile = enc->curtile; + + if (jas_getdbglevel() >= 10) { + jpc_enc_dump(enc); + } + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (cmptno = 0, comp = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno, ++comp) { + if (!cp->ccps[cmptno].sgnd) { + adjust = 1 << (cp->ccps[cmptno].prec - 1); + for (i = 0; i < jas_matrix_numrows(comp->data); ++i) { + for (j = 0; j < jas_matrix_numcols(comp->data); ++j) { + *jas_matrix_getref(comp->data, i, j) -= adjust; + } + } + } + } + + if (!tile->intmode) { + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + jas_matrix_asl(comp->data, JPC_FIX_FRACBITS); + } + } + + switch (tile->mctid) { + case JPC_MCT_RCT: +assert(jas_image_numcmpts(enc->image) == 3); + jpc_rct(tile->tcmpts[0].data, tile->tcmpts[1].data, + tile->tcmpts[2].data); + break; + case JPC_MCT_ICT: +assert(jas_image_numcmpts(enc->image) == 3); + jpc_ict(tile->tcmpts[0].data, tile->tcmpts[1].data, + tile->tcmpts[2].data); + break; + default: + break; + } + + for (i = 0; i < jas_image_numcmpts(enc->image); ++i) { + comp = &tile->tcmpts[i]; + jpc_tsfb_analyze(comp->tsfb, comp->data); + + } + + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (cmptno = 0, comp = tile->tcmpts; comp != endcomps; ++cmptno, ++comp) { + mingbits = 0; + absbandno = 0; + /* All bands must have a corresponding quantizer step size, + even if they contain no samples and are never coded. */ + /* Some bands may not be hit by the loop below, so we must + initialize all of the step sizes to a sane value. */ + memset(comp->stepsizes, 0, sizeof(comp->stepsizes)); + for (rlvlno = 0, lvl = comp->rlvls; rlvlno < comp->numrlvls; ++rlvlno, ++lvl) { + if (!lvl->bands) { + absbandno += rlvlno ? 3 : 1; + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + ++absbandno; + continue; + } + actualnumbps = 0; + mxmag = 0; + for (y = 0; y < JAS_CAST(uint_fast32_t, jas_matrix_numrows(band->data)); ++y) { + for (x = 0; x < JAS_CAST(uint_fast32_t, jas_matrix_numcols(band->data)); ++x) { + mag = abs(jas_matrix_get(band->data, y, x)); + if (mag > mxmag) { + mxmag = mag; + } + } + } + if (tile->intmode) { + actualnumbps = jpc_firstone(mxmag) + 1; + } else { + actualnumbps = jpc_firstone(mxmag) + 1 - JPC_FIX_FRACBITS; + } + numgbits = actualnumbps - (cp->ccps[cmptno].prec - 1 + + band->analgain); +#if 0 +jas_eprintf("%d %d mag=%d actual=%d numgbits=%d\n", cp->ccps[cmptno].prec, band->analgain, mxmag, actualnumbps, numgbits); +#endif + if (numgbits > mingbits) { + mingbits = numgbits; + } + if (!tile->intmode) { + band->absstepsize = jpc_fix_div(jpc_inttofix(1 + << (band->analgain + 1)), + band->synweight); + } else { + band->absstepsize = jpc_inttofix(1); + } + band->stepsize = jpc_abstorelstepsize( + band->absstepsize, cp->ccps[cmptno].prec + + band->analgain); + band->numbps = cp->tccp.numgbits + + JPC_QCX_GETEXPN(band->stepsize) - 1; + + if ((!tile->intmode) && band->data) { + jpc_quantize(band->data, band->absstepsize); + } + + comp->stepsizes[absbandno] = band->stepsize; + ++absbandno; + } + } + + assert(JPC_FIX_FRACBITS >= JPC_NUMEXTRABITS); + if (!tile->intmode) { + jas_matrix_divpow2(comp->data, JPC_FIX_FRACBITS - JPC_NUMEXTRABITS); + } else { + jas_matrix_asl(comp->data, JPC_NUMEXTRABITS); + } + +#if 0 +jas_eprintf("mingbits %d\n", mingbits); +#endif + if (mingbits > cp->tccp.numgbits) { + jas_eprintf("error: too few guard bits (need at least %d)\n", + mingbits); + return -1; + } + } + + if (!(enc->tmpstream = jas_stream_memopen(0, 0))) { + jas_eprintf("cannot open tmp file\n"); + return -1; + } + + /* Write the tile header. */ + if (!(enc->mrk = jpc_ms_create(JPC_MS_SOT))) { + return -1; + } + sot = &enc->mrk->parms.sot; + sot->len = 0; + sot->tileno = tileno; + sot->partno = 0; + sot->numparts = 1; + if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write SOT marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + + tccp = &cp->tccp; + for (cmptno = 0; cmptno < JAS_CAST(int, cp->numcmpts); ++cmptno) { + comp = &tile->tcmpts[cmptno]; + if (comp->numrlvls != tccp->maxrlvls) { + if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) { + return -1; + } +/* XXX = this is not really correct. we are using comp #0's precint sizes +and other characteristics */ + comp = &tile->tcmpts[0]; + cod = &enc->mrk->parms.cod; + cod->compparms.csty = 0; + cod->compparms.numdlvls = comp->numrlvls - 1; + cod->prg = tile->prg; + cod->numlyrs = tile->numlyrs; + cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(comp->cblkwidthexpn); + cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(comp->cblkheightexpn); + cod->compparms.cblksty = comp->cblksty; + cod->compparms.qmfbid = comp->qmfbid; + cod->mctrans = (tile->mctid != JPC_MCT_NONE); + for (i = 0; i < comp->numrlvls; ++i) { + cod->compparms.rlvls[i].parwidthval = comp->rlvls[i].prcwidthexpn; + cod->compparms.rlvls[i].parheightval = comp->rlvls[i].prcheightexpn; + } + if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) { + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + } + } + + for (cmptno = 0, comp = tile->tcmpts; cmptno < JAS_CAST(int, cp->numcmpts); ++cmptno, ++comp) { + ccps = &cp->ccps[cmptno]; + if (JAS_CAST(int, ccps->numstepsizes) == comp->numstepsizes) { + samestepsizes = 1; + for (bandno = 0; bandno < JAS_CAST(int, ccps->numstepsizes); ++bandno) { + if (ccps->stepsizes[bandno] != comp->stepsizes[bandno]) { + samestepsizes = 0; + break; + } + } + } else { + samestepsizes = 0; + } + if (!samestepsizes) { + if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) { + return -1; + } + qcc = &enc->mrk->parms.qcc; + qcc->compno = cmptno; + qcc->compparms.numguard = cp->tccp.numgbits; + qcc->compparms.qntsty = (comp->qmfbid == JPC_COX_INS) ? + JPC_QCX_SEQNT : JPC_QCX_NOQNT; + qcc->compparms.numstepsizes = comp->numstepsizes; + qcc->compparms.stepsizes = comp->stepsizes; + if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) { + return -1; + } + qcc->compparms.stepsizes = 0; + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; + } + } + + /* Write a SOD marker to indicate the end of the tile header. */ + if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) { + return -1; + } + if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) { + jas_eprintf("cannot write SOD marker\n"); + return -1; + } + jpc_ms_destroy(enc->mrk); + enc->mrk = 0; +tilehdrlen = jas_stream_getrwcount(enc->tmpstream); + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +if (jpc_enc_enccblks(enc)) { + abort(); + return -1; +} + + cp = enc->cp; + rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) / + ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight - + cp->imgareatly)); + tile->rawsize = cp->rawsize * rho; + + for (lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) { + tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl( + cp->tcp.ilyrrates[lyrno]); + } + tile->lyrsizes[tile->numlyrs - 1] = (cp->totalsize != UINT_FAST32_MAX) ? + (rho * enc->mainbodysize) : UINT_FAST32_MAX; + for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) { + if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) { + if (tilehdrlen <= JAS_CAST(long, tile->lyrsizes[lyrno])) { + tile->lyrsizes[lyrno] -= tilehdrlen; + } else { + tile->lyrsizes[lyrno] = 0; + } + } + } + + if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) { + return -1; + } + +#if 0 +jas_eprintf("ENCODE TILE DATA\n"); +#endif + if (jpc_enc_encodetiledata(enc)) { + jas_eprintf("dotile failed\n"); + return -1; + } + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + + tilelen = jas_stream_tell(enc->tmpstream); + + if (jas_stream_seek(enc->tmpstream, 6, SEEK_SET) < 0) { + return -1; + } + jpc_putuint32(enc->tmpstream, tilelen); + + if (jas_stream_seek(enc->tmpstream, 0, SEEK_SET) < 0) { + return -1; + } + if (jpc_putdata(enc->out, enc->tmpstream, -1)) { + return -1; + } + enc->len += tilelen; + + jas_stream_close(enc->tmpstream); + enc->tmpstream = 0; + + jpc_enc_tile_destroy(enc->curtile); + enc->curtile = 0; + + } + + return 0; +} + +int jpc_enc_encodetiledata(jpc_enc_t *enc) +{ +assert(enc->tmpstream); + if (jpc_enc_encpkts(enc, enc->tmpstream)) { + return -1; + } + return 0; +} + +int dump_passes(jpc_enc_pass_t *passes, int numpasses, jpc_enc_cblk_t *cblk) +{ + jpc_enc_pass_t *pass; + int i; + jas_stream_memobj_t *smo; + + smo = cblk->stream->obj_; + + pass = passes; + for (i = 0; i < numpasses; ++i) { + jas_eprintf("start=%d end=%d type=%d term=%d lyrno=%d firstchar=%02x size=%ld pos=%ld\n", + (int)pass->start, (int)pass->end, (int)pass->type, (int)pass->term, (int)pass->lyrno, + smo->buf_[pass->start], (long)smo->len_, (long)smo->pos_); +#if 0 + jas_memdump(stderr, &smo->buf_[pass->start], pass->end - pass->start); +#endif + ++pass; + } + return 0; +} + +void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize) +{ + int i; + int j; + jpc_fix_t t; + + if (stepsize == jpc_inttofix(1)) { + return; + } + + for (i = 0; i < jas_matrix_numrows(data); ++i) { + for (j = 0; j < jas_matrix_numcols(data); ++j) { + t = jas_matrix_get(data, i, j); + +{ + if (t < 0) { + t = jpc_fix_neg(jpc_fix_div(jpc_fix_neg(t), stepsize)); + } else { + t = jpc_fix_div(t, stepsize); + } +} + + jas_matrix_set(data, i, j, t); + } + } +} + +void calcrdslopes(jpc_enc_cblk_t *cblk) +{ + jpc_enc_pass_t *endpasses; + jpc_enc_pass_t *pass0; + jpc_enc_pass_t *pass1; + jpc_enc_pass_t *pass2; + jpc_flt_t slope0; + jpc_flt_t slope; + jpc_flt_t dd; + long dr; + + endpasses = &cblk->passes[cblk->numpasses]; + pass2 = cblk->passes; + slope0 = 0; + while (pass2 != endpasses) { + pass0 = 0; + for (pass1 = cblk->passes; pass1 != endpasses; ++pass1) { + dd = pass1->cumwmsedec; + dr = pass1->end; + if (pass0) { + dd -= pass0->cumwmsedec; + dr -= pass0->end; + } + if (dd <= 0) { + pass1->rdslope = JPC_BADRDSLOPE; + if (pass1 >= pass2) { + pass2 = &pass1[1]; + } + continue; + } + if (pass1 < pass2 && pass1->rdslope <= 0) { + continue; + } + if (!dr) { + assert(pass0); + pass0->rdslope = 0; + break; + } + slope = dd / dr; + if (pass0 && slope >= slope0) { + pass0->rdslope = 0; + break; + } + pass1->rdslope = slope; + if (pass1 >= pass2) { + pass2 = &pass1[1]; + } + pass0 = pass1; + slope0 = slope; + } + } + +#if 0 + for (pass0 = cblk->passes; pass0 != endpasses; ++pass0) { +if (pass0->rdslope > 0.0) { + jas_eprintf("pass %02d nmsedec=%lf dec=%lf end=%d %lf\n", pass0 - cblk->passes, + fixtodbl(pass0->nmsedec), pass0->wmsedec, pass0->end, pass0->rdslope); +} + } +#endif +} + +void dump_layeringinfo(jpc_enc_t *enc) +{ + + jpc_enc_tcmpt_t *tcmpt; + int tcmptno; + jpc_enc_rlvl_t *rlvl; + int rlvlno; + jpc_enc_band_t *band; + int bandno; + jpc_enc_prc_t *prc; + int prcno; + jpc_enc_cblk_t *cblk; + int cblkno; + jpc_enc_pass_t *pass; + int passno; + int lyrno; + jpc_enc_tile_t *tile; + + tile = enc->curtile; + + for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) { + jas_eprintf("lyrno = %02d\n", lyrno); + for (tcmptno = 0, tcmpt = tile->tcmpts; tcmptno < tile->numtcmpts; + ++tcmptno, ++tcmpt) { + for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; + ++rlvlno, ++rlvl) { + if (!rlvl->bands) { + continue; + } + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; + ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + for (cblkno = 0, cblk = prc->cblks; cblkno < + prc->numcblks; ++cblkno, ++cblk) { + for (passno = 0, pass = cblk->passes; passno < + cblk->numpasses && pass->lyrno == lyrno; + ++passno, ++pass) { + jas_eprintf("lyrno=%02d cmptno=%02d rlvlno=%02d bandno=%02d prcno=%02d cblkno=%03d passno=%03d\n", lyrno, tcmptno, rlvlno, bandno, prcno, cblkno, passno); + } + } + } + } + } + } + } +} + +int rateallocate(jpc_enc_t *enc, int numlyrs, uint_fast32_t *cumlens) +{ + jpc_flt_t lo; + jpc_flt_t hi; + jas_stream_t *out; + long cumlen; + int lyrno; + jpc_flt_t thresh; + jpc_flt_t goodthresh; + int success; + long pos; + long oldpos; + int numiters; + + jpc_enc_tcmpt_t *comp; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_rlvl_t *lvl; + jpc_enc_rlvl_t *endlvls; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + jpc_enc_pass_t *pass; + jpc_enc_pass_t *endpasses; + jpc_enc_pass_t *pass1; + jpc_flt_t mxrdslope; + jpc_flt_t mnrdslope; + jpc_enc_tile_t *tile; + jpc_enc_prc_t *prc; + int prcno; + + tile = enc->curtile; + + for (lyrno = 1; lyrno < numlyrs - 1; ++lyrno) { + if (cumlens[lyrno - 1] > cumlens[lyrno]) { + abort(); + } + } + + if (!(out = jas_stream_memopen(0, 0))) { + return -1; + } + + + /* Find minimum and maximum R-D slope values. */ + mnrdslope = DBL_MAX; + mxrdslope = 0; + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + calcrdslopes(cblk); + endpasses = &cblk->passes[cblk->numpasses]; + for (pass = cblk->passes; pass != endpasses; ++pass) { + if (pass->rdslope > 0) { + if (pass->rdslope < mnrdslope) { + mnrdslope = pass->rdslope; + } + if (pass->rdslope > mxrdslope) { + mxrdslope = pass->rdslope; + } + } + } + } + } + } + } + } +if (jas_getdbglevel()) { + jas_eprintf("min rdslope = %f max rdslope = %f\n", mnrdslope, mxrdslope); +} + + jpc_init_t2state(enc, 1); + + for (lyrno = 0; lyrno < numlyrs; ++lyrno) { + + lo = mnrdslope; + hi = mxrdslope; + + success = 0; + goodthresh = 0; + numiters = 0; + + do { + + cumlen = cumlens[lyrno]; + if (cumlen == UINT_FAST32_MAX) { + /* Only the last layer can be free of a rate + constraint (e.g., for lossless coding). */ + assert(lyrno == numlyrs - 1); + goodthresh = -1; + success = 1; + break; + } + + thresh = (lo + hi) / 2; + + /* Save the tier 2 coding state. */ + jpc_save_t2state(enc); + oldpos = jas_stream_tell(out); + assert(oldpos >= 0); + + /* Assign all passes with R-D slopes greater than or + equal to the current threshold to this layer. */ + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + if (cblk->curpass) { + endpasses = &cblk->passes[cblk->numpasses]; + pass1 = cblk->curpass; + for (pass = cblk->curpass; pass != endpasses; ++pass) { + if (pass->rdslope >= thresh) { + pass1 = &pass[1]; + } + } + for (pass = cblk->curpass; pass != pass1; ++pass) { + pass->lyrno = lyrno; + } + for (; pass != endpasses; ++pass) { + pass->lyrno = -1; + } + } + } + } + } + } + } + + /* Perform tier 2 coding. */ + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + for (prcno = 0; prcno < lvl->numprcs; ++prcno) { + if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts, lvl - comp->rlvls, prcno, lyrno)) { + return -1; + } + } + } + } + + pos = jas_stream_tell(out); + + /* Check the rate constraint. */ + assert(pos >= 0); + if (pos > cumlen) { + /* The rate is too high. */ + lo = thresh; + } else if (pos <= cumlen) { + /* The rate is low enough, so try higher. */ + hi = thresh; + if (!success || thresh < goodthresh) { + goodthresh = thresh; + success = 1; + } + } + + /* Save the tier 2 coding state. */ + jpc_restore_t2state(enc); + if (jas_stream_seek(out, oldpos, SEEK_SET) < 0) { + abort(); + } + +if (jas_getdbglevel()) { +jas_eprintf("maxlen=%08ld actuallen=%08ld thresh=%f\n", cumlen, pos, thresh); +} + + ++numiters; + } while (lo < hi - 1e-3 && numiters < 32); + + if (!success) { + jas_eprintf("warning: empty layer generated\n"); + } + +if (jas_getdbglevel()) { +jas_eprintf("success %d goodthresh %f\n", success, goodthresh); +} + + /* Assign all passes with R-D slopes greater than or + equal to the selected threshold to this layer. */ + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { +if (!lvl->bands) { + continue; +} + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + if (cblk->curpass) { + endpasses = &cblk->passes[cblk->numpasses]; + pass1 = cblk->curpass; + if (success) { + for (pass = cblk->curpass; pass != endpasses; ++pass) { + if (pass->rdslope >= goodthresh) { + pass1 = &pass[1]; + } + } + } + for (pass = cblk->curpass; pass != pass1; ++pass) { + pass->lyrno = lyrno; + } + for (; pass != endpasses; ++pass) { + pass->lyrno = -1; + } + } + } + } + } + } + } + + /* Perform tier 2 coding. */ + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + for (prcno = 0; prcno < lvl->numprcs; ++prcno) { + if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts, lvl - comp->rlvls, prcno, lyrno)) { + return -1; + } + } + } + } + } + + if (jas_getdbglevel() >= 5) { + dump_layeringinfo(enc); + } + + jas_stream_close(out); + + JAS_DBGLOG(10, ("done doing rateallocation\n")); +#if 0 +jas_eprintf("DONE RATE ALLOCATE\n"); +#endif + + return 0; +} + +/******************************************************************************\ +* Tile constructors and destructors. +\******************************************************************************/ + +jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno) +{ + jpc_enc_tile_t *tile; + uint_fast32_t htileno; + uint_fast32_t vtileno; + uint_fast16_t lyrno; + uint_fast16_t cmptno; + jpc_enc_tcmpt_t *tcmpt; + + if (!(tile = jas_malloc(sizeof(jpc_enc_tile_t)))) { + goto error; + } + + /* Initialize a few members used in error recovery. */ + tile->tcmpts = 0; + tile->lyrsizes = 0; + tile->numtcmpts = cp->numcmpts; + tile->pi = 0; + + tile->tileno = tileno; + htileno = tileno % cp->numhtiles; + vtileno = tileno / cp->numhtiles; + + /* Calculate the coordinates of the top-left and bottom-right + corners of the tile. */ + tile->tlx = JAS_MAX(cp->tilegrdoffx + htileno * cp->tilewidth, + cp->imgareatlx); + tile->tly = JAS_MAX(cp->tilegrdoffy + vtileno * cp->tileheight, + cp->imgareatly); + tile->brx = JAS_MIN(cp->tilegrdoffx + (htileno + 1) * cp->tilewidth, + cp->refgrdwidth); + tile->bry = JAS_MIN(cp->tilegrdoffy + (vtileno + 1) * cp->tileheight, + cp->refgrdheight); + + /* Initialize some tile coding parameters. */ + tile->intmode = cp->tcp.intmode; + tile->csty = cp->tcp.csty; + tile->prg = cp->tcp.prg; + tile->mctid = cp->tcp.mctid; + + tile->numlyrs = cp->tcp.numlyrs; + if (!(tile->lyrsizes = jas_alloc2(tile->numlyrs, + sizeof(uint_fast32_t)))) { + goto error; + } + for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) { + tile->lyrsizes[lyrno] = 0; + } + + /* Allocate an array for the per-tile-component information. */ + if (!(tile->tcmpts = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_tcmpt_t)))) { + goto error; + } + /* Initialize a few members critical for error recovery. */ + for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts; + ++cmptno, ++tcmpt) { + tcmpt->rlvls = 0; + tcmpt->tsfb = 0; + tcmpt->data = 0; + } + /* Initialize the per-tile-component information. */ + for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts; + ++cmptno, ++tcmpt) { + if (!tcmpt_create(tcmpt, cp, image, tile)) { + goto error; + } + } + + /* Initialize the synthesis weights for the MCT. */ + switch (tile->mctid) { + case JPC_MCT_RCT: + tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0)); + tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(0.6875)); + tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(0.6875)); + break; + case JPC_MCT_ICT: + tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0000)); + tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(3.2584)); + tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(2.4755)); + break; + default: + case JPC_MCT_NONE: + for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts; + ++cmptno, ++tcmpt) { + tcmpt->synweight = JPC_FIX_ONE; + } + break; + } + + if (!(tile->pi = jpc_enc_pi_create(cp, tile))) { + goto error; + } + + return tile; + +error: + + if (tile) { + jpc_enc_tile_destroy(tile); + } + return 0; +} + +void jpc_enc_tile_destroy(jpc_enc_tile_t *tile) +{ + jpc_enc_tcmpt_t *tcmpt; + uint_fast16_t cmptno; + + if (tile->tcmpts) { + for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < + tile->numtcmpts; ++cmptno, ++tcmpt) { + tcmpt_destroy(tcmpt); + } + jas_free(tile->tcmpts); + } + if (tile->lyrsizes) { + jas_free(tile->lyrsizes); + } + if (tile->pi) { + jpc_pi_destroy(tile->pi); + } + jas_free(tile); +} + +static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp, + jas_image_t *image, jpc_enc_tile_t *tile) +{ + uint_fast16_t cmptno; + uint_fast16_t rlvlno; + jpc_enc_rlvl_t *rlvl; + uint_fast32_t tlx; + uint_fast32_t tly; + uint_fast32_t brx; + uint_fast32_t bry; + uint_fast32_t cmpttlx; + uint_fast32_t cmpttly; + jpc_enc_ccp_t *ccp; + jpc_tsfb_band_t bandinfos[JPC_MAXBANDS]; + + tcmpt->tile = tile; + tcmpt->tsfb = 0; + tcmpt->data = 0; + tcmpt->rlvls = 0; + + /* Deduce the component number. */ + cmptno = tcmpt - tile->tcmpts; + + ccp = &cp->ccps[cmptno]; + + /* Compute the coordinates of the top-left and bottom-right + corners of this tile-component. */ + tlx = JPC_CEILDIV(tile->tlx, ccp->sampgrdstepx); + tly = JPC_CEILDIV(tile->tly, ccp->sampgrdstepy); + brx = JPC_CEILDIV(tile->brx, ccp->sampgrdstepx); + bry = JPC_CEILDIV(tile->bry, ccp->sampgrdstepy); + + /* Create a sequence to hold the tile-component sample data. */ + if (!(tcmpt->data = jas_seq2d_create(tlx, tly, brx, bry))) { + goto error; + } + + /* Get the image data associated with this tile-component. */ + cmpttlx = JPC_CEILDIV(cp->imgareatlx, ccp->sampgrdstepx); + cmpttly = JPC_CEILDIV(cp->imgareatly, ccp->sampgrdstepy); + if (jas_image_readcmpt(image, cmptno, tlx - cmpttlx, tly - cmpttly, + brx - tlx, bry - tly, tcmpt->data)) { + goto error; + } + + tcmpt->synweight = 0; + tcmpt->qmfbid = cp->tccp.qmfbid; + tcmpt->numrlvls = cp->tccp.maxrlvls; + tcmpt->numbands = 3 * tcmpt->numrlvls - 2; + if (!(tcmpt->tsfb = jpc_cod_gettsfb(tcmpt->qmfbid, tcmpt->numrlvls - 1))) { + goto error; + } + + for (rlvlno = 0; rlvlno < tcmpt->numrlvls; ++rlvlno) { + tcmpt->prcwidthexpns[rlvlno] = cp->tccp.prcwidthexpns[rlvlno]; + tcmpt->prcheightexpns[rlvlno] = cp->tccp.prcheightexpns[rlvlno]; + } + tcmpt->cblkwidthexpn = cp->tccp.cblkwidthexpn; + tcmpt->cblkheightexpn = cp->tccp.cblkheightexpn; + tcmpt->cblksty = cp->tccp.cblksty; + tcmpt->csty = cp->tccp.csty; + + tcmpt->numstepsizes = tcmpt->numbands; + assert(tcmpt->numstepsizes <= JPC_MAXBANDS); + memset(tcmpt->stepsizes, 0, tcmpt->numstepsizes * + sizeof(uint_fast16_t)); + + /* Retrieve information about the various bands. */ + jpc_tsfb_getbands(tcmpt->tsfb, jas_seq2d_xstart(tcmpt->data), + jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data), + jas_seq2d_yend(tcmpt->data), bandinfos); + + if (!(tcmpt->rlvls = jas_alloc2(tcmpt->numrlvls, sizeof(jpc_enc_rlvl_t)))) { + goto error; + } + for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; + ++rlvlno, ++rlvl) { + rlvl->bands = 0; + rlvl->tcmpt = tcmpt; + } + for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; + ++rlvlno, ++rlvl) { + if (!rlvl_create(rlvl, cp, tcmpt, bandinfos)) { + goto error; + } + } + + return tcmpt; + +error: + + tcmpt_destroy(tcmpt); + return 0; + +} + +static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt) +{ + jpc_enc_rlvl_t *rlvl; + uint_fast16_t rlvlno; + + if (tcmpt->rlvls) { + for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; + ++rlvlno, ++rlvl) { + rlvl_destroy(rlvl); + } + jas_free(tcmpt->rlvls); + } + + if (tcmpt->data) { + jas_seq2d_destroy(tcmpt->data); + } + if (tcmpt->tsfb) { + jpc_tsfb_destroy(tcmpt->tsfb); + } +} + +static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp, + jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos) +{ + uint_fast16_t rlvlno; + uint_fast32_t tlprctlx; + uint_fast32_t tlprctly; + uint_fast32_t brprcbrx; + uint_fast32_t brprcbry; + uint_fast16_t bandno; + jpc_enc_band_t *band; + + /* Deduce the resolution level. */ + rlvlno = rlvl - tcmpt->rlvls; + + /* Initialize members required for error recovery. */ + rlvl->bands = 0; + rlvl->tcmpt = tcmpt; + + /* Compute the coordinates of the top-left and bottom-right + corners of the tile-component at this resolution. */ + rlvl->tlx = JPC_CEILDIVPOW2(jas_seq2d_xstart(tcmpt->data), tcmpt->numrlvls - + 1 - rlvlno); + rlvl->tly = JPC_CEILDIVPOW2(jas_seq2d_ystart(tcmpt->data), tcmpt->numrlvls - + 1 - rlvlno); + rlvl->brx = JPC_CEILDIVPOW2(jas_seq2d_xend(tcmpt->data), tcmpt->numrlvls - + 1 - rlvlno); + rlvl->bry = JPC_CEILDIVPOW2(jas_seq2d_yend(tcmpt->data), tcmpt->numrlvls - + 1 - rlvlno); + + if (rlvl->tlx >= rlvl->brx || rlvl->tly >= rlvl->bry) { + rlvl->numhprcs = 0; + rlvl->numvprcs = 0; + rlvl->numprcs = 0; + return rlvl; + } + + rlvl->numbands = (!rlvlno) ? 1 : 3; + rlvl->prcwidthexpn = cp->tccp.prcwidthexpns[rlvlno]; + rlvl->prcheightexpn = cp->tccp.prcheightexpns[rlvlno]; + if (!rlvlno) { + rlvl->cbgwidthexpn = rlvl->prcwidthexpn; + rlvl->cbgheightexpn = rlvl->prcheightexpn; + } else { + rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1; + rlvl->cbgheightexpn = rlvl->prcheightexpn - 1; + } + rlvl->cblkwidthexpn = JAS_MIN(cp->tccp.cblkwidthexpn, rlvl->cbgwidthexpn); + rlvl->cblkheightexpn = JAS_MIN(cp->tccp.cblkheightexpn, rlvl->cbgheightexpn); + + /* Compute the number of precincts. */ + tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn); + tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn); + brprcbrx = JPC_CEILTOMULTPOW2(rlvl->brx, rlvl->prcwidthexpn); + brprcbry = JPC_CEILTOMULTPOW2(rlvl->bry, rlvl->prcheightexpn); + rlvl->numhprcs = JPC_FLOORDIVPOW2(brprcbrx - tlprctlx, rlvl->prcwidthexpn); + rlvl->numvprcs = JPC_FLOORDIVPOW2(brprcbry - tlprctly, rlvl->prcheightexpn); + rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs; + + if (!(rlvl->bands = jas_alloc2(rlvl->numbands, sizeof(jpc_enc_band_t)))) { + goto error; + } + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + band->prcs = 0; + band->data = 0; + band->rlvl = rlvl; + } + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + if (!band_create(band, cp, rlvl, bandinfos)) { + goto error; + } + } + + return rlvl; +error: + + rlvl_destroy(rlvl); + return 0; +} + +static void rlvl_destroy(jpc_enc_rlvl_t *rlvl) +{ + jpc_enc_band_t *band; + uint_fast16_t bandno; + + if (rlvl->bands) { + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + band_destroy(band); + } + jas_free(rlvl->bands); + } +} + +static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp, + jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos) +{ + uint_fast16_t bandno; + uint_fast16_t gblbandno; + uint_fast16_t rlvlno; + jpc_tsfb_band_t *bandinfo; + jpc_enc_tcmpt_t *tcmpt; + uint_fast32_t prcno; + jpc_enc_prc_t *prc; + + tcmpt = rlvl->tcmpt; + band->data = 0; + band->prcs = 0; + band->rlvl = rlvl; + + /* Deduce the resolution level and band number. */ + rlvlno = rlvl - rlvl->tcmpt->rlvls; + bandno = band - rlvl->bands; + gblbandno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + bandno + 1); + + bandinfo = &bandinfos[gblbandno]; + +if (bandinfo->xstart != bandinfo->xend && bandinfo->ystart != bandinfo->yend) { + if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) { + goto error; + } + jas_seq2d_bindsub(band->data, tcmpt->data, bandinfo->locxstart, + bandinfo->locystart, bandinfo->locxend, bandinfo->locyend); + jas_seq2d_setshift(band->data, bandinfo->xstart, bandinfo->ystart); +} + band->orient = bandinfo->orient; + band->analgain = JPC_NOMINALGAIN(cp->tccp.qmfbid, tcmpt->numrlvls, rlvlno, + band->orient); + band->numbps = 0; + band->absstepsize = 0; + band->stepsize = 0; + band->synweight = bandinfo->synenergywt; + +if (band->data) { + if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_enc_prc_t)))) { + goto error; + } + for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno, + ++prc) { + prc->cblks = 0; + prc->incltree = 0; + prc->nlibtree = 0; + prc->savincltree = 0; + prc->savnlibtree = 0; + prc->band = band; + } + for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno, + ++prc) { + if (!prc_create(prc, cp, band)) { + goto error; + } + } +} + + return band; + +error: + band_destroy(band); + return 0; +} + +static void band_destroy(jpc_enc_band_t *band) +{ + jpc_enc_prc_t *prc; + jpc_enc_rlvl_t *rlvl; + uint_fast32_t prcno; + + if (band->prcs) { + rlvl = band->rlvl; + for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; + ++prcno, ++prc) { + prc_destroy(prc); + } + jas_free(band->prcs); + } + if (band->data) { + jas_seq2d_destroy(band->data); + } +} + +static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_cp_t *cp, jpc_enc_band_t *band) +{ + uint_fast32_t prcno; + uint_fast32_t prcxind; + uint_fast32_t prcyind; + uint_fast32_t cbgtlx; + uint_fast32_t cbgtly; + uint_fast32_t tlprctlx; + uint_fast32_t tlprctly; + uint_fast32_t tlcbgtlx; + uint_fast32_t tlcbgtly; + uint_fast16_t rlvlno; + jpc_enc_rlvl_t *rlvl; + uint_fast32_t tlcblktlx; + uint_fast32_t tlcblktly; + uint_fast32_t brcblkbrx; + uint_fast32_t brcblkbry; + uint_fast32_t cblkno; + jpc_enc_cblk_t *cblk; + jpc_enc_tcmpt_t *tcmpt; + + prc->cblks = 0; + prc->incltree = 0; + prc->savincltree = 0; + prc->nlibtree = 0; + prc->savnlibtree = 0; + + rlvl = band->rlvl; + tcmpt = rlvl->tcmpt; +rlvlno = rlvl - tcmpt->rlvls; + prcno = prc - band->prcs; + prcxind = prcno % rlvl->numhprcs; + prcyind = prcno / rlvl->numhprcs; + prc->band = band; + +tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn); +tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn); +if (!rlvlno) { + tlcbgtlx = tlprctlx; + tlcbgtly = tlprctly; +} else { + tlcbgtlx = JPC_CEILDIVPOW2(tlprctlx, 1); + tlcbgtly = JPC_CEILDIVPOW2(tlprctly, 1); +} + + /* Compute the coordinates of the top-left and bottom-right + corners of the precinct. */ + cbgtlx = tlcbgtlx + (prcxind << rlvl->cbgwidthexpn); + cbgtly = tlcbgtly + (prcyind << rlvl->cbgheightexpn); + prc->tlx = JAS_MAX(jas_seq2d_xstart(band->data), cbgtlx); + prc->tly = JAS_MAX(jas_seq2d_ystart(band->data), cbgtly); + prc->brx = JAS_MIN(jas_seq2d_xend(band->data), cbgtlx + + (1 << rlvl->cbgwidthexpn)); + prc->bry = JAS_MIN(jas_seq2d_yend(band->data), cbgtly + + (1 << rlvl->cbgheightexpn)); + + if (prc->tlx < prc->brx && prc->tly < prc->bry) { + /* The precinct contains at least one code block. */ + + tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn); + tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn); + brcblkbrx = JPC_CEILTOMULTPOW2(prc->brx, rlvl->cblkwidthexpn); + brcblkbry = JPC_CEILTOMULTPOW2(prc->bry, rlvl->cblkheightexpn); + prc->numhcblks = JPC_FLOORDIVPOW2(brcblkbrx - tlcblktlx, + rlvl->cblkwidthexpn); + prc->numvcblks = JPC_FLOORDIVPOW2(brcblkbry - tlcblktly, + rlvl->cblkheightexpn); + prc->numcblks = prc->numhcblks * prc->numvcblks; + + if (!(prc->incltree = jpc_tagtree_create(prc->numhcblks, + prc->numvcblks))) { + goto error; + } + if (!(prc->nlibtree = jpc_tagtree_create(prc->numhcblks, + prc->numvcblks))) { + goto error; + } + if (!(prc->savincltree = jpc_tagtree_create(prc->numhcblks, + prc->numvcblks))) { + goto error; + } + if (!(prc->savnlibtree = jpc_tagtree_create(prc->numhcblks, + prc->numvcblks))) { + goto error; + } + + if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_enc_cblk_t)))) { + goto error; + } + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + cblk->passes = 0; + cblk->stream = 0; + cblk->mqenc = 0; + cblk->data = 0; + cblk->flags = 0; + cblk->prc = prc; + } + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + if (!cblk_create(cblk, cp, prc)) { + goto error; + } + } + } else { + /* The precinct does not contain any code blocks. */ + prc->tlx = prc->brx; + prc->tly = prc->bry; + prc->numcblks = 0; + prc->numhcblks = 0; + prc->numvcblks = 0; + prc->cblks = 0; + prc->incltree = 0; + prc->nlibtree = 0; + prc->savincltree = 0; + prc->savnlibtree = 0; + } + + return prc; + +error: + prc_destroy(prc); + return 0; +} + +static void prc_destroy(jpc_enc_prc_t *prc) +{ + jpc_enc_cblk_t *cblk; + uint_fast32_t cblkno; + + if (prc->cblks) { + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + cblk_destroy(cblk); + } + jas_free(prc->cblks); + } + if (prc->incltree) { + jpc_tagtree_destroy(prc->incltree); + } + if (prc->nlibtree) { + jpc_tagtree_destroy(prc->nlibtree); + } + if (prc->savincltree) { + jpc_tagtree_destroy(prc->savincltree); + } + if (prc->savnlibtree) { + jpc_tagtree_destroy(prc->savnlibtree); + } +} + +static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk, jpc_enc_cp_t *cp, jpc_enc_prc_t *prc) +{ + jpc_enc_band_t *band; + uint_fast32_t cblktlx; + uint_fast32_t cblktly; + uint_fast32_t cblkbrx; + uint_fast32_t cblkbry; + jpc_enc_rlvl_t *rlvl; + uint_fast32_t cblkxind; + uint_fast32_t cblkyind; + uint_fast32_t cblkno; + uint_fast32_t tlcblktlx; + uint_fast32_t tlcblktly; + + cblkno = cblk - prc->cblks; + cblkxind = cblkno % prc->numhcblks; + cblkyind = cblkno / prc->numhcblks; + rlvl = prc->band->rlvl; + cblk->prc = prc; + + cblk->numpasses = 0; + cblk->passes = 0; + cblk->numencpasses = 0; + cblk->numimsbs = 0; + cblk->numlenbits = 0; + cblk->stream = 0; + cblk->mqenc = 0; + cblk->flags = 0; + cblk->numbps = 0; + cblk->curpass = 0; + cblk->data = 0; + cblk->savedcurpass = 0; + cblk->savednumlenbits = 0; + cblk->savednumencpasses = 0; + + band = prc->band; + tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn); + tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn); + cblktlx = JAS_MAX(tlcblktlx + (cblkxind << rlvl->cblkwidthexpn), prc->tlx); + cblktly = JAS_MAX(tlcblktly + (cblkyind << rlvl->cblkheightexpn), prc->tly); + cblkbrx = JAS_MIN(tlcblktlx + ((cblkxind + 1) << rlvl->cblkwidthexpn), + prc->brx); + cblkbry = JAS_MIN(tlcblktly + ((cblkyind + 1) << rlvl->cblkheightexpn), + prc->bry); + + assert(cblktlx < cblkbrx && cblktly < cblkbry); + if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) { + goto error; + } + jas_seq2d_bindsub(cblk->data, band->data, cblktlx, cblktly, cblkbrx, cblkbry); + + return cblk; + +error: + cblk_destroy(cblk); + return 0; +} + +static void cblk_destroy(jpc_enc_cblk_t *cblk) +{ + uint_fast16_t passno; + jpc_enc_pass_t *pass; + if (cblk->passes) { + for (passno = 0, pass = cblk->passes; passno < cblk->numpasses; + ++passno, ++pass) { + pass_destroy(pass); + } + jas_free(cblk->passes); + } + if (cblk->stream) { + jas_stream_close(cblk->stream); + } + if (cblk->mqenc) { + jpc_mqenc_destroy(cblk->mqenc); + } + if (cblk->data) { + jas_seq2d_destroy(cblk->data); + } + if (cblk->flags) { + jas_seq2d_destroy(cblk->flags); + } +} + +static void pass_destroy(jpc_enc_pass_t *pass) +{ + /* XXX - need to free resources here */ +} + +void jpc_enc_dump(jpc_enc_t *enc) +{ + jpc_enc_tile_t *tile; + jpc_enc_tcmpt_t *tcmpt; + jpc_enc_rlvl_t *rlvl; + jpc_enc_band_t *band; + jpc_enc_prc_t *prc; + jpc_enc_cblk_t *cblk; + uint_fast16_t cmptno; + uint_fast16_t rlvlno; + uint_fast16_t bandno; + uint_fast32_t prcno; + uint_fast32_t cblkno; + + tile = enc->curtile; + + for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno, + ++tcmpt) { + jas_eprintf(" tcmpt %5d %5d %5d %5d\n", jas_seq2d_xstart(tcmpt->data), jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data), jas_seq2d_yend(tcmpt->data)); + for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls; + ++rlvlno, ++rlvl) { + jas_eprintf(" rlvl %5d %5d %5d %5d\n", rlvl->tlx, rlvl->tly, rlvl->brx, rlvl->bry); + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + if (!band->data) { + continue; + } + jas_eprintf(" band %5d %5d %5d %5d\n", jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data), jas_seq2d_yend(band->data)); + for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; + ++prcno, ++prc) { + jas_eprintf(" prc %5d %5d %5d %5d (%5d %5d)\n", prc->tlx, prc->tly, prc->brx, prc->bry, prc->brx - prc->tlx, prc->bry - prc->tly); + if (!prc->cblks) { + continue; + } + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + jas_eprintf(" cblk %5d %5d %5d %5d\n", jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data), jas_seq2d_yend(cblk->data)); + } + } + } + } + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_enc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,646 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_enc.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_ENC_H +#define JPC_ENC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_seq.h" + +#include "jpc_t2cod.h" +#include "jpc_mqenc.h" +#include "jpc_cod.h" +#include "jpc_tagtree.h" +#include "jpc_cs.h" +#include "jpc_flt.h" +#include "jpc_tsfb.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* The number of bits used in various lookup tables. */ +#define JPC_NUMEXTRABITS JPC_NMSEDEC_FRACBITS + +/* An invalid R-D slope value. */ +#define JPC_BADRDSLOPE (-1) + +/******************************************************************************\ +* Coding parameters types. +\******************************************************************************/ + +/* Per-component coding paramters. */ + +typedef struct { + + /* The horizontal sampling period. */ + uint_fast8_t sampgrdstepx; + + /* The vertical sampling period. */ + uint_fast8_t sampgrdstepy; + + /* The sample alignment horizontal offset. */ + uint_fast8_t sampgrdsubstepx; + + /* The sample alignment vertical offset. */ + uint_fast8_t sampgrdsubstepy; + + /* The precision of the samples. */ + uint_fast8_t prec; + + /* The signedness of the samples. */ + bool sgnd; + + /* The number of step sizes. */ + uint_fast16_t numstepsizes; + + /* The quantizer step sizes. */ + uint_fast16_t stepsizes[JPC_MAXBANDS]; + +} jpc_enc_ccp_t; + +/* Per-tile coding parameters. */ + +typedef struct { + + /* The coding mode. */ + bool intmode; + + /* The coding style (i.e., SOP, EPH). */ + uint_fast8_t csty; + + /* The progression order. */ + uint_fast8_t prg; + + /* The multicomponent transform. */ + uint_fast8_t mctid; + + /* The number of layers. */ + uint_fast16_t numlyrs; + + /* The normalized bit rates associated with the various + intermediate layers. */ + jpc_fix_t *ilyrrates; + +} jpc_enc_tcp_t; + +/* Per tile-component coding parameters. */ + +typedef struct { + + /* The coding style (i.e., explicit precinct sizes). */ + uint_fast8_t csty; + + /* The maximum number of resolution levels allowed. */ + uint_fast8_t maxrlvls; + + /* The exponent for the nominal code block width. */ + uint_fast16_t cblkwidthexpn; + + /* The exponent for the nominal code block height. */ + uint_fast16_t cblkheightexpn; + + /* The code block style parameters (e.g., lazy, terminate all, + segmentation symbols, causal, reset probability models). */ + uint_fast8_t cblksty; + + /* The QMFB. */ + uint_fast8_t qmfbid; + + /* The precinct width values. */ + uint_fast16_t prcwidthexpns[JPC_MAXRLVLS]; + + /* The precinct height values. */ + uint_fast16_t prcheightexpns[JPC_MAXRLVLS]; + + /* The number of guard bits. */ + uint_fast8_t numgbits; + +} jpc_enc_tccp_t; + +/* Coding parameters. */ + +typedef struct { + + /* The debug level. */ + int debug; + + /* The horizontal offset from the origin of the reference grid to the + left edge of the image area. */ + uint_fast32_t imgareatlx; + + /* The vertical offset from the origin of the reference grid to the + top edge of the image area. */ + uint_fast32_t imgareatly; + + /* The horizontal offset from the origin of the reference grid to the + right edge of the image area (plus one). */ + uint_fast32_t refgrdwidth; + + /* The vertical offset from the origin of the reference grid to the + bottom edge of the image area (plus one). */ + uint_fast32_t refgrdheight; + + /* The horizontal offset from the origin of the tile grid to the + origin of the reference grid. */ + uint_fast32_t tilegrdoffx; + + /* The vertical offset from the origin of the tile grid to the + origin of the reference grid. */ + uint_fast32_t tilegrdoffy; + + /* The nominal tile width in units of the image reference grid. */ + uint_fast32_t tilewidth; + + /* The nominal tile height in units of the image reference grid. */ + uint_fast32_t tileheight; + + /* The number of tiles spanning the image area in the horizontal + direction. */ + uint_fast32_t numhtiles; + + /* The number of tiles spanning the image area in the vertical + direction. */ + uint_fast32_t numvtiles; + + /* The number of tiles. */ + uint_fast32_t numtiles; + + /* The number of components. */ + uint_fast16_t numcmpts; + + /* The per-component coding parameters. */ + jpc_enc_ccp_t *ccps; + + /* The per-tile coding parameters. */ + jpc_enc_tcp_t tcp; + + /* The per-tile-component coding parameters. */ + jpc_enc_tccp_t tccp; + + /* The target code stream length in bytes. */ + uint_fast32_t totalsize; + + /* The raw (i.e., uncompressed) size of the image in bytes. */ + uint_fast32_t rawsize; + +} jpc_enc_cp_t; + +/******************************************************************************\ +* Encoder class. +\******************************************************************************/ + +/* Encoder per-coding-pass state information. */ + +typedef struct { + + /* The starting offset for this pass. */ + int start; + + /* The ending offset for this pass. */ + int end; + + /* The type of data in this pass (i.e., MQ or raw). */ + int type; + + /* Flag indicating that this pass is terminated. */ + int term; + + /* The entropy coder state after coding this pass. */ + jpc_mqencstate_t mqencstate; + + /* The layer to which this pass has been assigned. */ + int lyrno; + + /* The R-D slope for this pass. */ + jpc_flt_t rdslope; + + /* The weighted MSE reduction associated with this pass. */ + jpc_flt_t wmsedec; + + /* The cumulative weighted MSE reduction. */ + jpc_flt_t cumwmsedec; + + /* The normalized MSE reduction. */ + long nmsedec; + +} jpc_enc_pass_t; + +/* Encoder per-code-block state information. */ + +typedef struct { + + /* The number of passes. */ + int numpasses; + + /* The per-pass information. */ + jpc_enc_pass_t *passes; + + /* The number of passes encoded so far. */ + int numencpasses; + + /* The number of insignificant MSBs. */ + int numimsbs; + + /* The number of bits used to encode pass data lengths. */ + int numlenbits; + + /* The byte stream for this code block. */ + jas_stream_t *stream; + + /* The entropy encoder. */ + jpc_mqenc_t *mqenc; + + /* The data for this code block. */ + jas_matrix_t *data; + + /* The state for this code block. */ + jas_matrix_t *flags; + + /* The number of bit planes required for this code block. */ + int numbps; + + /* The next pass to be encoded. */ + jpc_enc_pass_t *curpass; + + /* The per-code-block-group state information. */ + struct jpc_enc_prc_s *prc; + + /* The saved current pass. */ + /* This is used by the rate control code. */ + jpc_enc_pass_t *savedcurpass; + + /* The saved length indicator size. */ + /* This is used by the rate control code. */ + int savednumlenbits; + + /* The saved number of encoded passes. */ + /* This is used by the rate control code. */ + int savednumencpasses; + +} jpc_enc_cblk_t; + +/* Encoder per-code-block-group state information. */ + +typedef struct jpc_enc_prc_s { + + /* The x-coordinate of the top-left corner of the precinct. */ + uint_fast32_t tlx; + + /* The y-coordinate of the top-left corner of the precinct. */ + uint_fast32_t tly; + + /* The x-coordinate of the bottom-right corner of the precinct + (plus one). */ + uint_fast32_t brx; + + /* The y-coordinate of the bottom-right corner of the precinct + (plus one). */ + uint_fast32_t bry; + + /* The number of code blocks spanning the precinct in the horizontal + direction. */ + int numhcblks; + + /* The number of code blocks spanning the precinct in the vertical + direction. */ + int numvcblks; + + /* The total number of code blocks. */ + int numcblks; + + /* The per-code-block information. */ + jpc_enc_cblk_t *cblks; + + /* The inclusion tag tree. */ + jpc_tagtree_t *incltree; + + /* The insignifcant MSBs tag tree. */ + jpc_tagtree_t *nlibtree; + + /* The per-band information. */ + struct jpc_enc_band_s *band; + + /* The saved inclusion tag tree. */ + /* This is used by rate control. */ + jpc_tagtree_t *savincltree; + + /* The saved leading-insignificant-bit-planes tag tree. */ + /* This is used by rate control. */ + jpc_tagtree_t *savnlibtree; + +} jpc_enc_prc_t; + +/* Encoder per-band state information. */ + +typedef struct jpc_enc_band_s { + + /* The per precinct information. */ + jpc_enc_prc_t *prcs; + + /* The coefficient data for this band. */ + jas_matrix_t *data; + + /* The orientation of this band (i.e., LL, LH, HL, or HH). */ + int orient; + + /* The number of bit planes associated with this band. */ + int numbps; + + /* The quantizer step size. */ + jpc_fix_t absstepsize; + + /* The encoded quantizer step size. */ + int stepsize; + + /* The L2 norm of the synthesis basis functions associated with + this band. (The MCT is not considered in this value.) */ + jpc_fix_t synweight; + + /* The analysis gain for this band. */ + int analgain; + + /* The per-resolution-level information. */ + struct jpc_enc_rlvl_s *rlvl; + +} jpc_enc_band_t; + +/* Encoder per-resolution-level state information. */ + +typedef struct jpc_enc_rlvl_s { + + /* The x-coordinate of the top-left corner of the tile-component + at this resolution. */ + uint_fast32_t tlx; + + /* The y-coordinate of the top-left corner of the tile-component + at this resolution. */ + uint_fast32_t tly; + + /* The x-coordinate of the bottom-right corner of the tile-component + at this resolution (plus one). */ + uint_fast32_t brx; + + /* The y-coordinate of the bottom-right corner of the tile-component + at this resolution (plus one). */ + uint_fast32_t bry; + + /* The exponent value for the nominal precinct width measured + relative to the associated LL band. */ + int prcwidthexpn; + + /* The exponent value for the nominal precinct height measured + relative to the associated LL band. */ + int prcheightexpn; + + /* The number of precincts spanning the resolution level in the + horizontal direction. */ + int numhprcs; + + /* The number of precincts spanning the resolution level in the + vertical direction. */ + int numvprcs; + + /* The total number of precincts. */ + int numprcs; + + /* The exponent value for the nominal code block group width. + This quantity is associated with the next lower resolution level + (assuming that there is one). */ + int cbgwidthexpn; + + /* The exponent value for the nominal code block group height. + This quantity is associated with the next lower resolution level + (assuming that there is one). */ + int cbgheightexpn; + + /* The exponent value for the code block width. */ + uint_fast16_t cblkwidthexpn; + + /* The exponent value for the code block height. */ + uint_fast16_t cblkheightexpn; + + /* The number of bands associated with this resolution level. */ + int numbands; + + /* The per-band information. */ + jpc_enc_band_t *bands; + + /* The parent tile-component. */ + struct jpc_enc_tcmpt_s *tcmpt; + +} jpc_enc_rlvl_t; + +/* Encoder per-tile-component state information. */ + +typedef struct jpc_enc_tcmpt_s { + + /* The number of resolution levels. */ + int numrlvls; + + /* The per-resolution-level information. */ + jpc_enc_rlvl_t *rlvls; + + /* The tile-component data. */ + jas_matrix_t *data; + + /* The QMFB. */ + int qmfbid; + + /* The number of bands. */ + int numbands; + + /* The TSFB. */ + jpc_tsfb_t *tsfb; + + /* The synthesis energy weight (for the MCT). */ + jpc_fix_t synweight; + + /* The precinct width exponents. */ + int prcwidthexpns[JPC_MAXRLVLS]; + + /* The precinct height exponents. */ + int prcheightexpns[JPC_MAXRLVLS]; + + /* The code block width exponent. */ + int cblkwidthexpn; + + /* The code block height exponent. */ + int cblkheightexpn; + + /* Coding style (i.e., explicit precinct sizes). */ + int csty; + + /* Code block style. */ + int cblksty; + + /* The number of quantizer step sizes. */ + int numstepsizes; + + /* The encoded quantizer step sizes. */ + uint_fast16_t stepsizes[JPC_MAXBANDS]; + + /* The parent tile. */ + struct jpc_enc_tile_s *tile; + +} jpc_enc_tcmpt_t; + +/* Encoder per-tile state information. */ + +typedef struct jpc_enc_tile_s { + + /* The tile number. */ + uint_fast32_t tileno; + + /* The x-coordinate of the top-left corner of the tile measured with + respect to the reference grid. */ + uint_fast32_t tlx; + + /* The y-coordinate of the top-left corner of the tile measured with + respect to the reference grid. */ + uint_fast32_t tly; + + /* The x-coordinate of the bottom-right corner of the tile measured + with respect to the reference grid (plus one). */ + uint_fast32_t brx; + + /* The y-coordinate of the bottom-right corner of the tile measured + with respect to the reference grid (plus one). */ + uint_fast32_t bry; + + /* The coding style. */ + uint_fast8_t csty; + + /* The progression order. */ + uint_fast8_t prg; + + /* The number of layers. */ + int numlyrs; + + /* The MCT to employ (if any). */ + uint_fast8_t mctid; + + /* The packet iterator (used to determine the order of packet + generation). */ + jpc_pi_t *pi; + + /* The coding mode (i.e., integer or real). */ + bool intmode; + + /* The number of bytes to allocate to the various layers. */ + uint_fast32_t *lyrsizes; + + /* The number of tile-components. */ + int numtcmpts; + + /* The per tile-component information. */ + jpc_enc_tcmpt_t *tcmpts; + + /* The raw (i.e., uncompressed) size of this tile. */ + uint_fast32_t rawsize; + +} jpc_enc_tile_t; + +/* Encoder class. */ + +typedef struct jpc_enc_s { + + /* The image being encoded. */ + jas_image_t *image; + + /* The output stream. */ + jas_stream_t *out; + + /* The coding parameters. */ + jpc_enc_cp_t *cp; + + /* The tile currently being processed. */ + jpc_enc_tile_t *curtile; + + /* The code stream state. */ + jpc_cstate_t *cstate; + + /* The number of bytes output so far. */ + uint_fast32_t len; + + /* The number of bytes available for the main body of the code stream. */ + /* This is used for rate allocation purposes. */ + uint_fast32_t mainbodysize; + + /* The marker segment currently being processed. */ + /* This member is a convenience for making cleanup easier. */ + jpc_ms_t *mrk; + + /* The stream used to temporarily hold tile-part data. */ + jas_stream_t *tmpstream; + +} jpc_enc_t; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_fix.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_fix.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_fix.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_fix.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Fixed-Point Number Class + * + * $Id: jpc_fix.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_FIX_H +#define JPC_FIX_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" +#include "jasper/jas_fix.h" + +/******************************************************************************\ +* Basic parameters of the fixed-point type. +\******************************************************************************/ + +/* The integral type used to represent a fixed-point number. This + type must be capable of representing values from -(2^31) to 2^31-1 + (inclusive). */ +typedef int_fast32_t jpc_fix_t; + +/* The integral type used to respresent higher-precision intermediate results. + This type should be capable of representing values from -(2^63) to 2^63-1 + (inclusive). */ +typedef int_fast64_t jpc_fix_big_t; + +/* The number of bits used for the fractional part of a fixed-point number. */ +#define JPC_FIX_FRACBITS 13 + +/******************************************************************************\ +* Instantiations of the generic fixed-point number macros for the +* parameters given above. (Too bad C does not support templates, eh?) +* The purpose of these macros is self-evident if one examines the +* corresponding macros in the jasper/jas_fix.h header file. +\******************************************************************************/ + +#define JPC_FIX_ZERO JAS_FIX_ZERO(jpc_fix_t, JPC_FIX_FRACBITS) +#define JPC_FIX_ONE JAS_FIX_ONE(jpc_fix_t, JPC_FIX_FRACBITS) +#define JPC_FIX_HALF JAS_FIX_HALF(jpc_fix_t, JPC_FIX_FRACBITS) + +#define jpc_inttofix(x) JAS_INTTOFIX(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fixtoint(x) JAS_FIXTOINT(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fixtodbl(x) JAS_FIXTODBL(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_dbltofix(x) JAS_DBLTOFIX(jpc_fix_t, JPC_FIX_FRACBITS, x) + +#define jpc_fix_add(x, y) JAS_FIX_ADD(jpc_fix_t, JPC_FIX_FRACBITS, x, y) +#define jpc_fix_sub(x, y) JAS_FIX_SUB(jpc_fix_t, JPC_FIX_FRACBITS, x, y) +#define jpc_fix_mul(x, y) \ + JAS_FIX_MUL(jpc_fix_t, JPC_FIX_FRACBITS, jpc_fix_big_t, x, y) +#define jpc_fix_mulbyint(x, y) \ + JAS_FIX_MULBYINT(jpc_fix_t, JPC_FIX_FRACBITS, x, y) +#define jpc_fix_div(x, y) \ + JAS_FIX_DIV(jpc_fix_t, JPC_FIX_FRACBITS, jpc_fix_big_t, x, y) +#define jpc_fix_neg(x) JAS_FIX_NEG(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_asl(x, n) JAS_FIX_ASL(jpc_fix_t, JPC_FIX_FRACBITS, x, n) +#define jpc_fix_asr(x, n) JAS_FIX_ASR(jpc_fix_t, JPC_FIX_FRACBITS, x, n) + +#define jpc_fix_pluseq(x, y) JAS_FIX_PLUSEQ(jpc_fix_t, JPC_FIX_FRACBITS, x, y) +#define jpc_fix_minuseq(x, y) JAS_FIX_MINUSEQ(jpc_fix_t, JPC_FIX_FRACBITS, x, y) +#define jpc_fix_muleq(x, y) \ + JAS_FIX_MULEQ(jpc_fix_t, JPC_FIX_FRACBITS, jpc_fix_big_t, x, y) + +#define jpc_fix_abs(x) JAS_FIX_ABS(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_isint(x) JAS_FIX_ISINT(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_sgn(x) JAS_FIX_SGN(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_round(x) JAS_FIX_ROUND(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_floor(x) JAS_FIX_FLOOR(jpc_fix_t, JPC_FIX_FRACBITS, x) +#define jpc_fix_trunc(x) JAS_FIX_TRUNC(jpc_fix_t, JPC_FIX_FRACBITS, x) + +/******************************************************************************\ +* Extra macros for convenience. +\******************************************************************************/ + +/* Compute the sum of three fixed-point numbers. */ +#define jpc_fix_add3(x, y, z) jpc_fix_add(jpc_fix_add(x, y), z) + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_flt.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_flt.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_flt.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_flt.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Floating-Point Class + * + * $Id: jpc_flt.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_FLT_H +#define JPC_FLT_H + +#include + +/* The code ought to be modified so this type is not used at all. */ +/* Very few places in the code rely on floating-point arithmetic, aside + from conversions in printf's. */ +typedef double jpc_flt_t; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Math Library + * + * $Id: jpc_math.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "jpc_math.h" + +/******************************************************************************\ +* Miscellaneous Functions +\******************************************************************************/ + +/* Calculate the integer quantity floor(log2(x)), where x is a positive + integer. */ +int jpc_floorlog2(int x) +{ + int y; + + /* The argument must be positive. */ + assert(x > 0); + + y = 0; + while (x > 1) { + x >>= 1; + ++y; + } + return y; +} + +/* Calculate the bit position of the first leading one in a nonnegative + integer. */ +/* This function is the basically the same as ceillog2(x), except that the + allowable range for x is slightly different. */ +int jpc_firstone(int x) +{ + int n; + + /* The argument must be nonnegative. */ + assert(x >= 0); + + n = -1; + while (x > 0) { + x >>= 1; + ++n; + } + return n; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_math.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JPC_MATH_H +#define JPC_MATH_H + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include + +/******************************************************************************\ +* Macros +\******************************************************************************/ + +/* Compute the floor of the quotient of two integers. */ +#define JPC_FLOORDIV(x, y) ((x) / (y)) + +/* Compute the ceiling of the quotient of two integers. */ +#define JPC_CEILDIV(x, y) (((x) + (y) - 1) / (y)) + +/* Compute the floor of (x / 2^y). */ +#define JPC_FLOORDIVPOW2(x, y) ((x) >> (y)) + +/* Compute the ceiling of (x / 2^y). */ +#define JPC_CEILDIVPOW2(x, y) (((x) + (1 << (y)) - 1) >> (y)) + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Calculate the bit position of the first leading one in a nonnegative + integer. */ +int jpc_firstone(int x); + +/* Calculate the integer quantity floor(log2(x)), where x is a positive + integer. */ +int jpc_floorlog2(int x); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,291 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Multicomponent Transform Code + * + * $Id: jpc_mct.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include "jasper/jas_seq.h" + +#include "jpc_fix.h" +#include "jpc_mct.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Compute the forward RCT. */ + +void jpc_rct(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2) +{ + int numrows; + int numcols; + int i; + int j; + jpc_fix_t *c0p; + jpc_fix_t *c1p; + jpc_fix_t *c2p; + + numrows = jas_matrix_numrows(c0); + numcols = jas_matrix_numcols(c0); + + /* All three matrices must have the same dimensions. */ + assert(jas_matrix_numrows(c1) == numrows && jas_matrix_numcols(c1) == numcols + && jas_matrix_numrows(c2) == numrows && jas_matrix_numcols(c2) == numcols); + + for (i = 0; i < numrows; i++) { + c0p = jas_matrix_getref(c0, i, 0); + c1p = jas_matrix_getref(c1, i, 0); + c2p = jas_matrix_getref(c2, i, 0); + for (j = numcols; j > 0; --j) { + int r; + int g; + int b; + int y; + int u; + int v; + r = *c0p; + g = *c1p; + b = *c2p; + y = (r + (g << 1) + b) >> 2; + u = b - g; + v = r - g; + *c0p++ = y; + *c1p++ = u; + *c2p++ = v; + } + } +} + +/* Compute the inverse RCT. */ + +void jpc_irct(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2) +{ + int numrows; + int numcols; + int i; + int j; + jpc_fix_t *c0p; + jpc_fix_t *c1p; + jpc_fix_t *c2p; + + numrows = jas_matrix_numrows(c0); + numcols = jas_matrix_numcols(c0); + + /* All three matrices must have the same dimensions. */ + assert(jas_matrix_numrows(c1) == numrows && jas_matrix_numcols(c1) == numcols + && jas_matrix_numrows(c2) == numrows && jas_matrix_numcols(c2) == numcols); + + for (i = 0; i < numrows; i++) { + c0p = jas_matrix_getref(c0, i, 0); + c1p = jas_matrix_getref(c1, i, 0); + c2p = jas_matrix_getref(c2, i, 0); + for (j = numcols; j > 0; --j) { + int r; + int g; + int b; + int y; + int u; + int v; + y = *c0p; + u = *c1p; + v = *c2p; + g = y - ((u + v) >> 2); + r = v + g; + b = u + g; + *c0p++ = r; + *c1p++ = g; + *c2p++ = b; + } + } +} + +void jpc_ict(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2) +{ + int numrows; + int numcols; + int i; + int j; + jpc_fix_t r; + jpc_fix_t g; + jpc_fix_t b; + jpc_fix_t y; + jpc_fix_t u; + jpc_fix_t v; + jpc_fix_t *c0p; + jpc_fix_t *c1p; + jpc_fix_t *c2p; + + numrows = jas_matrix_numrows(c0); + assert(jas_matrix_numrows(c1) == numrows && jas_matrix_numrows(c2) == numrows); + numcols = jas_matrix_numcols(c0); + assert(jas_matrix_numcols(c1) == numcols && jas_matrix_numcols(c2) == numcols); + for (i = 0; i < numrows; ++i) { + c0p = jas_matrix_getref(c0, i, 0); + c1p = jas_matrix_getref(c1, i, 0); + c2p = jas_matrix_getref(c2, i, 0); + for (j = numcols; j > 0; --j) { + r = *c0p; + g = *c1p; + b = *c2p; + y = jpc_fix_add3(jpc_fix_mul(jpc_dbltofix(0.299), r), jpc_fix_mul(jpc_dbltofix(0.587), g), + jpc_fix_mul(jpc_dbltofix(0.114), b)); + u = jpc_fix_add3(jpc_fix_mul(jpc_dbltofix(-0.16875), r), jpc_fix_mul(jpc_dbltofix(-0.33126), g), + jpc_fix_mul(jpc_dbltofix(0.5), b)); + v = jpc_fix_add3(jpc_fix_mul(jpc_dbltofix(0.5), r), jpc_fix_mul(jpc_dbltofix(-0.41869), g), + jpc_fix_mul(jpc_dbltofix(-0.08131), b)); + *c0p++ = y; + *c1p++ = u; + *c2p++ = v; + } + } +} + +void jpc_iict(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2) +{ + int numrows; + int numcols; + int i; + int j; + jpc_fix_t r; + jpc_fix_t g; + jpc_fix_t b; + jpc_fix_t y; + jpc_fix_t u; + jpc_fix_t v; + jpc_fix_t *c0p; + jpc_fix_t *c1p; + jpc_fix_t *c2p; + + numrows = jas_matrix_numrows(c0); + assert(jas_matrix_numrows(c1) == numrows && jas_matrix_numrows(c2) == numrows); + numcols = jas_matrix_numcols(c0); + assert(jas_matrix_numcols(c1) == numcols && jas_matrix_numcols(c2) == numcols); + for (i = 0; i < numrows; ++i) { + c0p = jas_matrix_getref(c0, i, 0); + c1p = jas_matrix_getref(c1, i, 0); + c2p = jas_matrix_getref(c2, i, 0); + for (j = numcols; j > 0; --j) { + y = *c0p; + u = *c1p; + v = *c2p; + r = jpc_fix_add(y, jpc_fix_mul(jpc_dbltofix(1.402), v)); + g = jpc_fix_add3(y, jpc_fix_mul(jpc_dbltofix(-0.34413), u), + jpc_fix_mul(jpc_dbltofix(-0.71414), v)); + b = jpc_fix_add(y, jpc_fix_mul(jpc_dbltofix(1.772), u)); + *c0p++ = r; + *c1p++ = g; + *c2p++ = b; + } + } +} + +jpc_fix_t jpc_mct_getsynweight(int mctid, int cmptno) +{ + jpc_fix_t synweight; + + synweight = JPC_FIX_ONE; + switch (mctid) { + case JPC_MCT_RCT: + switch (cmptno) { + case 0: + synweight = jpc_dbltofix(sqrt(3.0)); + break; + case 1: + synweight = jpc_dbltofix(sqrt(0.6875)); + break; + case 2: + synweight = jpc_dbltofix(sqrt(0.6875)); + break; + } + break; + case JPC_MCT_ICT: + switch (cmptno) { + case 0: + synweight = jpc_dbltofix(sqrt(3.0000)); + break; + case 1: + synweight = jpc_dbltofix(sqrt(3.2584)); + break; + case 2: + synweight = jpc_dbltofix(sqrt(2.4755)); + break; + } + break; +#if 0 + default: + synweight = JPC_FIX_ONE; + break; +#endif + } + + return synweight; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mct.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Multicomponent Transform Code + * + * $Id: jpc_mct.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_MCT_H +#define JPC_MCT_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_seq.h" +#include "jasper/jas_fix.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* + * Multicomponent transform IDs. + */ + +#define JPC_MCT_NONE 0 +#define JPC_MCT_ICT 1 +#define JPC_MCT_RCT 2 + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Calculate the forward RCT. */ +void jpc_rct(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2); + +/* Calculate the inverse RCT. */ +void jpc_irct(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2); + +/* Calculate the forward ICT. */ +void jpc_ict(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2); + +/* Calculate the inverse ICT. */ +void jpc_iict(jas_matrix_t *c0, jas_matrix_t *c1, jas_matrix_t *c2); + +/* Get the synthesis weight associated with a particular component. */ +jpc_fix_t jpc_mct_getsynweight(int mctid, int cmptno); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Coder + * + * $Id: jpc_mqcod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_malloc.h" + +#include "jpc_mqcod.h" + +/******************************************************************************\ +* Data. +\******************************************************************************/ + +/* MQ coder per-state information. */ + +jpc_mqstate_t jpc_mqstates[47 * 2] = { + {0x5601, 0, &jpc_mqstates[ 2], &jpc_mqstates[ 3]}, + {0x5601, 1, &jpc_mqstates[ 3], &jpc_mqstates[ 2]}, + {0x3401, 0, &jpc_mqstates[ 4], &jpc_mqstates[12]}, + {0x3401, 1, &jpc_mqstates[ 5], &jpc_mqstates[13]}, + {0x1801, 0, &jpc_mqstates[ 6], &jpc_mqstates[18]}, + {0x1801, 1, &jpc_mqstates[ 7], &jpc_mqstates[19]}, + {0x0ac1, 0, &jpc_mqstates[ 8], &jpc_mqstates[24]}, + {0x0ac1, 1, &jpc_mqstates[ 9], &jpc_mqstates[25]}, + {0x0521, 0, &jpc_mqstates[10], &jpc_mqstates[58]}, + {0x0521, 1, &jpc_mqstates[11], &jpc_mqstates[59]}, + {0x0221, 0, &jpc_mqstates[76], &jpc_mqstates[66]}, + {0x0221, 1, &jpc_mqstates[77], &jpc_mqstates[67]}, + {0x5601, 0, &jpc_mqstates[14], &jpc_mqstates[13]}, + {0x5601, 1, &jpc_mqstates[15], &jpc_mqstates[12]}, + {0x5401, 0, &jpc_mqstates[16], &jpc_mqstates[28]}, + {0x5401, 1, &jpc_mqstates[17], &jpc_mqstates[29]}, + {0x4801, 0, &jpc_mqstates[18], &jpc_mqstates[28]}, + {0x4801, 1, &jpc_mqstates[19], &jpc_mqstates[29]}, + {0x3801, 0, &jpc_mqstates[20], &jpc_mqstates[28]}, + {0x3801, 1, &jpc_mqstates[21], &jpc_mqstates[29]}, + {0x3001, 0, &jpc_mqstates[22], &jpc_mqstates[34]}, + {0x3001, 1, &jpc_mqstates[23], &jpc_mqstates[35]}, + {0x2401, 0, &jpc_mqstates[24], &jpc_mqstates[36]}, + {0x2401, 1, &jpc_mqstates[25], &jpc_mqstates[37]}, + {0x1c01, 0, &jpc_mqstates[26], &jpc_mqstates[40]}, + {0x1c01, 1, &jpc_mqstates[27], &jpc_mqstates[41]}, + {0x1601, 0, &jpc_mqstates[58], &jpc_mqstates[42]}, + {0x1601, 1, &jpc_mqstates[59], &jpc_mqstates[43]}, + {0x5601, 0, &jpc_mqstates[30], &jpc_mqstates[29]}, + {0x5601, 1, &jpc_mqstates[31], &jpc_mqstates[28]}, + {0x5401, 0, &jpc_mqstates[32], &jpc_mqstates[28]}, + {0x5401, 1, &jpc_mqstates[33], &jpc_mqstates[29]}, + {0x5101, 0, &jpc_mqstates[34], &jpc_mqstates[30]}, + {0x5101, 1, &jpc_mqstates[35], &jpc_mqstates[31]}, + {0x4801, 0, &jpc_mqstates[36], &jpc_mqstates[32]}, + {0x4801, 1, &jpc_mqstates[37], &jpc_mqstates[33]}, + {0x3801, 0, &jpc_mqstates[38], &jpc_mqstates[34]}, + {0x3801, 1, &jpc_mqstates[39], &jpc_mqstates[35]}, + {0x3401, 0, &jpc_mqstates[40], &jpc_mqstates[36]}, + {0x3401, 1, &jpc_mqstates[41], &jpc_mqstates[37]}, + {0x3001, 0, &jpc_mqstates[42], &jpc_mqstates[38]}, + {0x3001, 1, &jpc_mqstates[43], &jpc_mqstates[39]}, + {0x2801, 0, &jpc_mqstates[44], &jpc_mqstates[38]}, + {0x2801, 1, &jpc_mqstates[45], &jpc_mqstates[39]}, + {0x2401, 0, &jpc_mqstates[46], &jpc_mqstates[40]}, + {0x2401, 1, &jpc_mqstates[47], &jpc_mqstates[41]}, + {0x2201, 0, &jpc_mqstates[48], &jpc_mqstates[42]}, + {0x2201, 1, &jpc_mqstates[49], &jpc_mqstates[43]}, + {0x1c01, 0, &jpc_mqstates[50], &jpc_mqstates[44]}, + {0x1c01, 1, &jpc_mqstates[51], &jpc_mqstates[45]}, + {0x1801, 0, &jpc_mqstates[52], &jpc_mqstates[46]}, + {0x1801, 1, &jpc_mqstates[53], &jpc_mqstates[47]}, + {0x1601, 0, &jpc_mqstates[54], &jpc_mqstates[48]}, + {0x1601, 1, &jpc_mqstates[55], &jpc_mqstates[49]}, + {0x1401, 0, &jpc_mqstates[56], &jpc_mqstates[50]}, + {0x1401, 1, &jpc_mqstates[57], &jpc_mqstates[51]}, + {0x1201, 0, &jpc_mqstates[58], &jpc_mqstates[52]}, + {0x1201, 1, &jpc_mqstates[59], &jpc_mqstates[53]}, + {0x1101, 0, &jpc_mqstates[60], &jpc_mqstates[54]}, + {0x1101, 1, &jpc_mqstates[61], &jpc_mqstates[55]}, + {0x0ac1, 0, &jpc_mqstates[62], &jpc_mqstates[56]}, + {0x0ac1, 1, &jpc_mqstates[63], &jpc_mqstates[57]}, + {0x09c1, 0, &jpc_mqstates[64], &jpc_mqstates[58]}, + {0x09c1, 1, &jpc_mqstates[65], &jpc_mqstates[59]}, + {0x08a1, 0, &jpc_mqstates[66], &jpc_mqstates[60]}, + {0x08a1, 1, &jpc_mqstates[67], &jpc_mqstates[61]}, + {0x0521, 0, &jpc_mqstates[68], &jpc_mqstates[62]}, + {0x0521, 1, &jpc_mqstates[69], &jpc_mqstates[63]}, + {0x0441, 0, &jpc_mqstates[70], &jpc_mqstates[64]}, + {0x0441, 1, &jpc_mqstates[71], &jpc_mqstates[65]}, + {0x02a1, 0, &jpc_mqstates[72], &jpc_mqstates[66]}, + {0x02a1, 1, &jpc_mqstates[73], &jpc_mqstates[67]}, + {0x0221, 0, &jpc_mqstates[74], &jpc_mqstates[68]}, + {0x0221, 1, &jpc_mqstates[75], &jpc_mqstates[69]}, + {0x0141, 0, &jpc_mqstates[76], &jpc_mqstates[70]}, + {0x0141, 1, &jpc_mqstates[77], &jpc_mqstates[71]}, + {0x0111, 0, &jpc_mqstates[78], &jpc_mqstates[72]}, + {0x0111, 1, &jpc_mqstates[79], &jpc_mqstates[73]}, + {0x0085, 0, &jpc_mqstates[80], &jpc_mqstates[74]}, + {0x0085, 1, &jpc_mqstates[81], &jpc_mqstates[75]}, + {0x0049, 0, &jpc_mqstates[82], &jpc_mqstates[76]}, + {0x0049, 1, &jpc_mqstates[83], &jpc_mqstates[77]}, + {0x0025, 0, &jpc_mqstates[84], &jpc_mqstates[78]}, + {0x0025, 1, &jpc_mqstates[85], &jpc_mqstates[79]}, + {0x0015, 0, &jpc_mqstates[86], &jpc_mqstates[80]}, + {0x0015, 1, &jpc_mqstates[87], &jpc_mqstates[81]}, + {0x0009, 0, &jpc_mqstates[88], &jpc_mqstates[82]}, + {0x0009, 1, &jpc_mqstates[89], &jpc_mqstates[83]}, + {0x0005, 0, &jpc_mqstates[90], &jpc_mqstates[84]}, + {0x0005, 1, &jpc_mqstates[91], &jpc_mqstates[85]}, + {0x0001, 0, &jpc_mqstates[90], &jpc_mqstates[86]}, + {0x0001, 1, &jpc_mqstates[91], &jpc_mqstates[87]}, + {0x5601, 0, &jpc_mqstates[92], &jpc_mqstates[92]}, + {0x5601, 1, &jpc_mqstates[93], &jpc_mqstates[93]}, +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqcod.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Coder + * + * $Id: jpc_mqcod.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_MQCOD_H +#define JPC_MQCOD_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* + * MQ coder context information. + */ + +typedef struct { + + /* The most probable symbol (MPS). */ + int mps; + + /* The state index. */ + int_fast16_t ind; + +} jpc_mqctx_t; + +/* + * MQ coder state table entry. + */ + +typedef struct jpc_mqstate_s { + + /* The Qe value. */ + uint_fast16_t qeval; + + /* The MPS. */ + int mps; + + /* The NMPS state. */ + struct jpc_mqstate_s *nmps; + + /* The NLPS state. */ + struct jpc_mqstate_s *nlps; + +} jpc_mqstate_t; + +/******************************************************************************\ +* Data. +\******************************************************************************/ + +/* The state table for the MQ coder. */ +extern jpc_mqstate_t jpc_mqstates[]; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,306 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Decoder + * + * $Id: jpc_mqdec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" + +#include "jpc_mqdec.h" + +/******************************************************************************\ +* Local macros. +\******************************************************************************/ + +#if defined(DEBUG) +#define MQDEC_CALL(n, x) \ + ((jas_getdbglevel() >= (n)) ? ((void)(x)) : ((void)0)) +#else +#define MQDEC_CALL(n, x) +#endif + +/******************************************************************************\ +* Local function prototypes. +\******************************************************************************/ + +static void jpc_mqdec_bytein(jpc_mqdec_t *mqdec); + +/******************************************************************************\ +* Code for creation and destruction of a MQ decoder. +\******************************************************************************/ + +/* Create a MQ decoder. */ +jpc_mqdec_t *jpc_mqdec_create(int maxctxs, jas_stream_t *in) +{ + jpc_mqdec_t *mqdec; + + /* There must be at least one context. */ + assert(maxctxs > 0); + + /* Allocate memory for the MQ decoder. */ + if (!(mqdec = jas_malloc(sizeof(jpc_mqdec_t)))) { + goto error; + } + mqdec->in = in; + mqdec->maxctxs = maxctxs; + /* Allocate memory for the per-context state information. */ + if (!(mqdec->ctxs = jas_alloc2(mqdec->maxctxs, sizeof(jpc_mqstate_t *)))) { + goto error; + } + /* Set the current context to the first context. */ + mqdec->curctx = mqdec->ctxs; + + /* If an input stream has been associated with the MQ decoder, + initialize the decoder state from the stream. */ + if (mqdec->in) { + jpc_mqdec_init(mqdec); + } + /* Initialize the per-context state information. */ + jpc_mqdec_setctxs(mqdec, 0, 0); + + return mqdec; + +error: + /* Oops... Something has gone wrong. */ + if (mqdec) { + jpc_mqdec_destroy(mqdec); + } + return 0; +} + +/* Destroy a MQ decoder. */ +void jpc_mqdec_destroy(jpc_mqdec_t *mqdec) +{ + if (mqdec->ctxs) { + jas_free(mqdec->ctxs); + } + jas_free(mqdec); +} + +/******************************************************************************\ +* Code for initialization of a MQ decoder. +\******************************************************************************/ + +/* Initialize the state of a MQ decoder. */ + +void jpc_mqdec_init(jpc_mqdec_t *mqdec) +{ + int c; + + mqdec->eof = 0; + mqdec->creg = 0; + /* Get the next byte from the input stream. */ + if ((c = jas_stream_getc(mqdec->in)) == EOF) { + /* We have encountered an I/O error or EOF. */ + c = 0xff; + mqdec->eof = 1; + } + mqdec->inbuffer = c; + mqdec->creg += mqdec->inbuffer << 16; + jpc_mqdec_bytein(mqdec); + mqdec->creg <<= 7; + mqdec->ctreg -= 7; + mqdec->areg = 0x8000; +} + +/* Set the input stream for a MQ decoder. */ + +void jpc_mqdec_setinput(jpc_mqdec_t *mqdec, jas_stream_t *in) +{ + mqdec->in = in; +} + +/* Initialize one or more contexts. */ + +void jpc_mqdec_setctxs(jpc_mqdec_t *mqdec, int numctxs, jpc_mqctx_t *ctxs) +{ + jpc_mqstate_t **ctx; + int n; + + ctx = mqdec->ctxs; + n = JAS_MIN(mqdec->maxctxs, numctxs); + while (--n >= 0) { + *ctx = &jpc_mqstates[2 * ctxs->ind + ctxs->mps]; + ++ctx; + ++ctxs; + } + n = mqdec->maxctxs - numctxs; + while (--n >= 0) { + *ctx = &jpc_mqstates[0]; + ++ctx; + } +} + +/* Initialize a context. */ + +void jpc_mqdec_setctx(jpc_mqdec_t *mqdec, int ctxno, jpc_mqctx_t *ctx) +{ + jpc_mqstate_t **ctxi; + ctxi = &mqdec->ctxs[ctxno]; + *ctxi = &jpc_mqstates[2 * ctx->ind + ctx->mps]; +} + +/******************************************************************************\ +* Code for decoding a bit. +\******************************************************************************/ + +/* Decode a bit. */ + +int jpc_mqdec_getbit_func(register jpc_mqdec_t *mqdec) +{ + int bit; + JAS_DBGLOG(100, ("jpc_mqdec_getbit_func(%p)\n", mqdec)); + MQDEC_CALL(100, jpc_mqdec_dump(mqdec, stderr)); + bit = jpc_mqdec_getbit_macro(mqdec); + MQDEC_CALL(100, jpc_mqdec_dump(mqdec, stderr)); + JAS_DBGLOG(100, ("ctx = %d, decoded %d\n", mqdec->curctx - + mqdec->ctxs, bit)); + return bit; +} + +/* Apply MPS_EXCHANGE algorithm (with RENORMD). */ +int jpc_mqdec_mpsexchrenormd(register jpc_mqdec_t *mqdec) +{ + int ret; + register jpc_mqstate_t *state = *mqdec->curctx; + jpc_mqdec_mpsexchange(mqdec->areg, state->qeval, mqdec->curctx, ret); + jpc_mqdec_renormd(mqdec->areg, mqdec->creg, mqdec->ctreg, mqdec->in, + mqdec->eof, mqdec->inbuffer); + return ret; +} + +/* Apply LPS_EXCHANGE algorithm (with RENORMD). */ +int jpc_mqdec_lpsexchrenormd(register jpc_mqdec_t *mqdec) +{ + int ret; + register jpc_mqstate_t *state = *mqdec->curctx; + jpc_mqdec_lpsexchange(mqdec->areg, state->qeval, mqdec->curctx, ret); + jpc_mqdec_renormd(mqdec->areg, mqdec->creg, mqdec->ctreg, mqdec->in, + mqdec->eof, mqdec->inbuffer); + return ret; +} + +/******************************************************************************\ +* Support code. +\******************************************************************************/ + +/* Apply the BYTEIN algorithm. */ +static void jpc_mqdec_bytein(jpc_mqdec_t *mqdec) +{ + int c; + unsigned char prevbuf; + + if (!mqdec->eof) { + if ((c = jas_stream_getc(mqdec->in)) == EOF) { + mqdec->eof = 1; + c = 0xff; + } + prevbuf = mqdec->inbuffer; + mqdec->inbuffer = c; + if (prevbuf == 0xff) { + if (c > 0x8f) { + mqdec->creg += 0xff00; + mqdec->ctreg = 8; + } else { + mqdec->creg += c << 9; + mqdec->ctreg = 7; + } + } else { + mqdec->creg += c << 8; + mqdec->ctreg = 8; + } + } else { + mqdec->creg += 0xff00; + mqdec->ctreg = 8; + } +} + +/******************************************************************************\ +* Code for debugging. +\******************************************************************************/ + +/* Dump a MQ decoder to a stream for debugging. */ + +void jpc_mqdec_dump(jpc_mqdec_t *mqdec, FILE *out) +{ + fprintf(out, "MQDEC A = %08lx, C = %08lx, CT=%08lx, ", + (unsigned long) mqdec->areg, (unsigned long) mqdec->creg, + (unsigned long) mqdec->ctreg); + fprintf(out, "CTX = %d, ", (int)(mqdec->curctx - mqdec->ctxs)); + fprintf(out, "IND %d, MPS %d, QEVAL %x\n", (int)(*mqdec->curctx - + jpc_mqstates), (int)(*mqdec->curctx)->mps, (int)(*mqdec->curctx)->qeval); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqdec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Decoder + * + * $Id: jpc_mqdec.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_MQDEC_H +#define JPC_MQDEC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" +#include "jasper/jas_stream.h" + +#include "jpc_mqcod.h" + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* MQ arithmetic decoder. */ + +typedef struct { + + /* The C register. */ + uint_fast32_t creg; + + /* The A register. */ + uint_fast32_t areg; + + /* The CT register. */ + uint_fast32_t ctreg; + + /* The current context. */ + jpc_mqstate_t **curctx; + + /* The per-context information. */ + jpc_mqstate_t **ctxs; + + /* The maximum number of contexts. */ + int maxctxs; + + /* The stream from which to read data. */ + jas_stream_t *in; + + /* The last character read. */ + uchar inbuffer; + + /* The EOF indicator. */ + int eof; + +} jpc_mqdec_t; + +/******************************************************************************\ +* Functions/macros for construction and destruction. +\******************************************************************************/ + +/* Create a MQ decoder. */ +jpc_mqdec_t *jpc_mqdec_create(int maxctxs, jas_stream_t *in); + +/* Destroy a MQ decoder. */ +void jpc_mqdec_destroy(jpc_mqdec_t *dec); + +/******************************************************************************\ +* Functions/macros for initialization. +\******************************************************************************/ + +/* Set the input stream associated with a MQ decoder. */ +void jpc_mqdec_setinput(jpc_mqdec_t *dec, jas_stream_t *in); + +/* Initialize a MQ decoder. */ +void jpc_mqdec_init(jpc_mqdec_t *dec); + +/******************************************************************************\ +* Functions/macros for manipulating contexts. +\******************************************************************************/ + +/* Set the current context for a MQ decoder. */ +#define jpc_mqdec_setcurctx(dec, ctxno) \ + ((mqdec)->curctx = &(mqdec)->ctxs[ctxno]); + +/* Set the state information for a particular context of a MQ decoder. */ +void jpc_mqdec_setctx(jpc_mqdec_t *dec, int ctxno, jpc_mqctx_t *ctx); + +/* Set the state information for all contexts of a MQ decoder. */ +void jpc_mqdec_setctxs(jpc_mqdec_t *dec, int numctxs, jpc_mqctx_t *ctxs); + +/******************************************************************************\ +* Functions/macros for decoding bits. +\******************************************************************************/ + +/* Decode a symbol. */ +#if !defined(DEBUG) +#define jpc_mqdec_getbit(dec) \ + jpc_mqdec_getbit_macro(dec) +#else +#define jpc_mqdec_getbit(dec) \ + jpc_mqdec_getbit_func(dec) +#endif + +/* Decode a symbol (assuming an unskewed probability distribution). */ +#if !defined(DEBUG) +#define jpc_mqdec_getbitnoskew(dec) \ + jpc_mqdec_getbit_macro(dec) +#else +#define jpc_mqdec_getbitnoskew(dec) \ + jpc_mqdec_getbit_func(dec) +#endif + +/******************************************************************************\ +* Functions/macros for debugging. +\******************************************************************************/ + +/* Dump the MQ decoder state for debugging. */ +void jpc_mqdec_dump(jpc_mqdec_t *dec, FILE *out); + +/******************************************************************************\ +* EVERYTHING BELOW THIS POINT IS IMPLEMENTATION SPECIFIC AND NOT PART OF THE +* APPLICATION INTERFACE. DO NOT RELY ON ANY OF THE INTERNAL FUNCTIONS/MACROS +* GIVEN BELOW. +\******************************************************************************/ + +#define jpc_mqdec_getbit_macro(dec) \ + ((((dec)->areg -= (*(dec)->curctx)->qeval), \ + (dec)->creg >> 16 >= (*(dec)->curctx)->qeval) ? \ + ((((dec)->creg -= (*(dec)->curctx)->qeval << 16), \ + (dec)->areg & 0x8000) ? (*(dec)->curctx)->mps : \ + jpc_mqdec_mpsexchrenormd(dec)) : \ + jpc_mqdec_lpsexchrenormd(dec)) + +#define jpc_mqdec_mpsexchange(areg, delta, curctx, bit) \ +{ \ + if ((areg) < (delta)) { \ + register jpc_mqstate_t *state = *(curctx); \ + /* LPS decoded. */ \ + (bit) = state->mps ^ 1; \ + *(curctx) = state->nlps; \ + } else { \ + register jpc_mqstate_t *state = *(curctx); \ + /* MPS decoded. */ \ + (bit) = state->mps; \ + *(curctx) = state->nmps; \ + } \ +} + +#define jpc_mqdec_lpsexchange(areg, delta, curctx, bit) \ +{ \ + if ((areg) >= (delta)) { \ + register jpc_mqstate_t *state = *(curctx); \ + (areg) = (delta); \ + (bit) = state->mps ^ 1; \ + *(curctx) = state->nlps; \ + } else { \ + register jpc_mqstate_t *state = *(curctx); \ + (areg) = (delta); \ + (bit) = state->mps; \ + *(curctx) = state->nmps; \ + } \ +} + +#define jpc_mqdec_renormd(areg, creg, ctreg, in, eof, inbuf) \ +{ \ + do { \ + if (!(ctreg)) { \ + jpc_mqdec_bytein2(creg, ctreg, in, eof, inbuf); \ + } \ + (areg) <<= 1; \ + (creg) <<= 1; \ + --(ctreg); \ + } while (!((areg) & 0x8000)); \ +} + +#define jpc_mqdec_bytein2(creg, ctreg, in, eof, inbuf) \ +{ \ + int c; \ + unsigned char prevbuf; \ + if (!(eof)) { \ + if ((c = jas_stream_getc(in)) == EOF) { \ + (eof) = 1; \ + c = 0xff; \ + } \ + prevbuf = (inbuf); \ + (inbuf) = c; \ + if (prevbuf == 0xff) { \ + if (c > 0x8f) { \ + (creg) += 0xff00; \ + (ctreg) = 8; \ + } else { \ + (creg) += c << 9; \ + (ctreg) = 7; \ + } \ + } else { \ + (creg) += c << 8; \ + (ctreg) = 8; \ + } \ + } else { \ + (creg) += 0xff00; \ + (ctreg) = 8; \ + } \ +} + +int jpc_mqdec_getbit_func(jpc_mqdec_t *dec); +int jpc_mqdec_mpsexchrenormd(jpc_mqdec_t *dec); +int jpc_mqdec_lpsexchrenormd(jpc_mqdec_t *dec); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,392 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Encoder + * + * $Id: jpc_mqenc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include + +#include "jasper/jas_stream.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" + +#include "jpc_mqenc.h" + +/******************************************************************************\ +* Macros +\******************************************************************************/ + +#if defined(DEBUG) +#define JPC_MQENC_CALL(n, x) \ + ((jas_getdbglevel() >= (n)) ? ((void)(x)) : ((void)0)) +#else +#define JPC_MQENC_CALL(n, x) +#endif + +#define jpc_mqenc_codemps9(areg, creg, ctreg, curctx, enc) \ +{ \ + jpc_mqstate_t *state = *(curctx); \ + (areg) -= state->qeval; \ + if (!((areg) & 0x8000)) { \ + if ((areg) < state->qeval) { \ + (areg) = state->qeval; \ + } else { \ + (creg) += state->qeval; \ + } \ + *(curctx) = state->nmps; \ + jpc_mqenc_renorme((areg), (creg), (ctreg), (enc)); \ + } else { \ + (creg) += state->qeval; \ + } \ +} + +#define jpc_mqenc_codelps2(areg, creg, ctreg, curctx, enc) \ +{ \ + jpc_mqstate_t *state = *(curctx); \ + (areg) -= state->qeval; \ + if ((areg) < state->qeval) { \ + (creg) += state->qeval; \ + } else { \ + (areg) = state->qeval; \ + } \ + *(curctx) = state->nlps; \ + jpc_mqenc_renorme((areg), (creg), (ctreg), (enc)); \ +} + +#define jpc_mqenc_renorme(areg, creg, ctreg, enc) \ +{ \ + do { \ + (areg) <<= 1; \ + (creg) <<= 1; \ + if (!--(ctreg)) { \ + jpc_mqenc_byteout((areg), (creg), (ctreg), (enc)); \ + } \ + } while (!((areg) & 0x8000)); \ +} + +#define jpc_mqenc_byteout(areg, creg, ctreg, enc) \ +{ \ + if ((enc)->outbuf != 0xff) { \ + if ((creg) & 0x8000000) { \ + if (++((enc)->outbuf) == 0xff) { \ + (creg) &= 0x7ffffff; \ + jpc_mqenc_byteout2(enc); \ + enc->outbuf = ((creg) >> 20) & 0xff; \ + (creg) &= 0xfffff; \ + (ctreg) = 7; \ + } else { \ + jpc_mqenc_byteout2(enc); \ + enc->outbuf = ((creg) >> 19) & 0xff; \ + (creg) &= 0x7ffff; \ + (ctreg) = 8; \ + } \ + } else { \ + jpc_mqenc_byteout2(enc); \ + (enc)->outbuf = ((creg) >> 19) & 0xff; \ + (creg) &= 0x7ffff; \ + (ctreg) = 8; \ + } \ + } else { \ + jpc_mqenc_byteout2(enc); \ + (enc)->outbuf = ((creg) >> 20) & 0xff; \ + (creg) &= 0xfffff; \ + (ctreg) = 7; \ + } \ +} + +#define jpc_mqenc_byteout2(enc) \ +{ \ + if (enc->outbuf >= 0) { \ + if (jas_stream_putc(enc->out, (unsigned char)enc->outbuf) == EOF) { \ + enc->err |= 1; \ + } \ + } \ + enc->lastbyte = enc->outbuf; \ +} + +/******************************************************************************\ +* Local function protoypes. +\******************************************************************************/ + +static void jpc_mqenc_setbits(jpc_mqenc_t *mqenc); + +/******************************************************************************\ +* Code for creation and destruction of encoder. +\******************************************************************************/ + +/* Create a MQ encoder. */ + +jpc_mqenc_t *jpc_mqenc_create(int maxctxs, jas_stream_t *out) +{ + jpc_mqenc_t *mqenc; + + /* Allocate memory for the MQ encoder. */ + if (!(mqenc = jas_malloc(sizeof(jpc_mqenc_t)))) { + goto error; + } + mqenc->out = out; + mqenc->maxctxs = maxctxs; + + /* Allocate memory for the per-context state information. */ + if (!(mqenc->ctxs = jas_alloc2(mqenc->maxctxs, sizeof(jpc_mqstate_t *)))) { + goto error; + } + + /* Set the current context to the first one. */ + mqenc->curctx = mqenc->ctxs; + + jpc_mqenc_init(mqenc); + + /* Initialize the per-context state information to something sane. */ + jpc_mqenc_setctxs(mqenc, 0, 0); + + return mqenc; + +error: + if (mqenc) { + jpc_mqenc_destroy(mqenc); + } + return 0; +} + +/* Destroy a MQ encoder. */ + +void jpc_mqenc_destroy(jpc_mqenc_t *mqenc) +{ + if (mqenc->ctxs) { + jas_free(mqenc->ctxs); + } + jas_free(mqenc); +} + +/******************************************************************************\ +* State initialization code. +\******************************************************************************/ + +/* Initialize the coding state of a MQ encoder. */ + +void jpc_mqenc_init(jpc_mqenc_t *mqenc) +{ + mqenc->areg = 0x8000; + mqenc->outbuf = -1; + mqenc->creg = 0; + mqenc->ctreg = 12; + mqenc->lastbyte = -1; + mqenc->err = 0; +} + +/* Initialize one or more contexts. */ + +void jpc_mqenc_setctxs(jpc_mqenc_t *mqenc, int numctxs, jpc_mqctx_t *ctxs) +{ + jpc_mqstate_t **ctx; + int n; + + ctx = mqenc->ctxs; + n = JAS_MIN(mqenc->maxctxs, numctxs); + while (--n >= 0) { + *ctx = &jpc_mqstates[2 * ctxs->ind + ctxs->mps]; + ++ctx; + ++ctxs; + } + n = mqenc->maxctxs - numctxs; + while (--n >= 0) { + *ctx = &jpc_mqstates[0]; + ++ctx; + } + +} + +/* Get the coding state for a MQ encoder. */ + +void jpc_mqenc_getstate(jpc_mqenc_t *mqenc, jpc_mqencstate_t *state) +{ + state->areg = mqenc->areg; + state->creg = mqenc->creg; + state->ctreg = mqenc->ctreg; + state->lastbyte = mqenc->lastbyte; +} + +/******************************************************************************\ +* Code for coding symbols. +\******************************************************************************/ + +/* Encode a bit. */ + +int jpc_mqenc_putbit_func(jpc_mqenc_t *mqenc, int bit) +{ + const jpc_mqstate_t *state; + JAS_DBGLOG(100, ("jpc_mqenc_putbit(%p, %d)\n", mqenc, bit)); + JPC_MQENC_CALL(100, jpc_mqenc_dump(mqenc, stderr)); + + state = *(mqenc->curctx); + + if (state->mps == bit) { + /* Apply the CODEMPS algorithm as defined in the standard. */ + mqenc->areg -= state->qeval; + if (!(mqenc->areg & 0x8000)) { + jpc_mqenc_codemps2(mqenc); + } else { + mqenc->creg += state->qeval; + } + } else { + /* Apply the CODELPS algorithm as defined in the standard. */ + jpc_mqenc_codelps2(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc->curctx, mqenc); + } + + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} + +int jpc_mqenc_codemps2(jpc_mqenc_t *mqenc) +{ + /* Note: This function only performs part of the work associated with + the CODEMPS algorithm from the standard. Some of the work is also + performed by the caller. */ + + jpc_mqstate_t *state = *(mqenc->curctx); + if (mqenc->areg < state->qeval) { + mqenc->areg = state->qeval; + } else { + mqenc->creg += state->qeval; + } + *mqenc->curctx = state->nmps; + jpc_mqenc_renorme(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc); + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} + +int jpc_mqenc_codelps(jpc_mqenc_t *mqenc) +{ + jpc_mqenc_codelps2(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc->curctx, mqenc); + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +/* Terminate the code word. */ + +int jpc_mqenc_flush(jpc_mqenc_t *mqenc, int termmode) +{ + int_fast16_t k; + + switch (termmode) { + case JPC_MQENC_PTERM: + k = 11 - mqenc->ctreg + 1; + while (k > 0) { + mqenc->creg <<= mqenc->ctreg; + mqenc->ctreg = 0; + jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, + mqenc); + k -= mqenc->ctreg; + } + if (mqenc->outbuf != 0xff) { + jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc); + } + break; + case JPC_MQENC_DEFTERM: + jpc_mqenc_setbits(mqenc); + mqenc->creg <<= mqenc->ctreg; + jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc); + mqenc->creg <<= mqenc->ctreg; + jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc); + if (mqenc->outbuf != 0xff) { + jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc); + } + break; + default: + abort(); + break; + } + return 0; +} + +static void jpc_mqenc_setbits(jpc_mqenc_t *mqenc) +{ + uint_fast32_t tmp = mqenc->creg + mqenc->areg; + mqenc->creg |= 0xffff; + if (mqenc->creg >= tmp) { + mqenc->creg -= 0x8000; + } +} + +/* Dump a MQ encoder to a stream for debugging. */ + +int jpc_mqenc_dump(jpc_mqenc_t *mqenc, FILE *out) +{ + fprintf(out, "AREG = %08x, CREG = %08x, CTREG = %d\n", + (unsigned)mqenc->areg, (unsigned)mqenc->creg, (int)mqenc->ctreg); + fprintf(out, "IND = %02d, MPS = %d, QEVAL = %04x\n", + (int)(*mqenc->curctx - jpc_mqstates), (int)(*mqenc->curctx)->mps, + (int)(*mqenc->curctx)->qeval); + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_mqenc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,236 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * MQ Arithmetic Encoder + * + * $Id: jpc_mqenc.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_MQENC_H +#define JPC_MQENC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" +#include "jasper/jas_stream.h" + +#include "jpc_mqcod.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* + * Termination modes. + */ + +#define JPC_MQENC_DEFTERM 0 /* default termination */ +#define JPC_MQENC_PTERM 1 /* predictable termination */ + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* MQ arithmetic encoder class. */ + +typedef struct { + + /* The C register. */ + uint_fast32_t creg; + + /* The A register. */ + uint_fast32_t areg; + + /* The CT register. */ + uint_fast32_t ctreg; + + /* The maximum number of contexts. */ + int maxctxs; + + /* The per-context information. */ + jpc_mqstate_t **ctxs; + + /* The current context. */ + jpc_mqstate_t **curctx; + + /* The stream for encoder output. */ + jas_stream_t *out; + + /* The byte buffer (i.e., the B variable in the standard). */ + int_fast16_t outbuf; + + /* The last byte output. */ + int_fast16_t lastbyte; + + /* The error indicator. */ + int err; + +} jpc_mqenc_t; + +/* MQ arithmetic encoder state information. */ + +typedef struct { + + /* The A register. */ + unsigned areg; + + /* The C register. */ + unsigned creg; + + /* The CT register. */ + unsigned ctreg; + + /* The last byte output by the encoder. */ + int lastbyte; + +} jpc_mqencstate_t; + +/******************************************************************************\ +* Functions/macros for construction and destruction. +\******************************************************************************/ + +/* Create a MQ encoder. */ +jpc_mqenc_t *jpc_mqenc_create(int maxctxs, jas_stream_t *out); + +/* Destroy a MQ encoder. */ +void jpc_mqenc_destroy(jpc_mqenc_t *enc); + +/******************************************************************************\ +* Functions/macros for initialization. +\******************************************************************************/ + +/* Initialize a MQ encoder. */ +void jpc_mqenc_init(jpc_mqenc_t *enc); + +/******************************************************************************\ +* Functions/macros for context manipulation. +\******************************************************************************/ + +/* Set the current context. */ +#define jpc_mqenc_setcurctx(enc, ctxno) \ + ((enc)->curctx = &(enc)->ctxs[ctxno]); + +/* Set the state information for a particular context. */ +void jpc_mqenc_setctx(jpc_mqenc_t *enc, int ctxno, jpc_mqctx_t *ctx); + +/* Set the state information for multiple contexts. */ +void jpc_mqenc_setctxs(jpc_mqenc_t *enc, int numctxs, jpc_mqctx_t *ctxs); + +/******************************************************************************\ +* Miscellaneous functions/macros. +\******************************************************************************/ + +/* Get the error state of a MQ encoder. */ +#define jpc_mqenc_error(enc) \ + ((enc)->err) + +/* Get the current encoder state. */ +void jpc_mqenc_getstate(jpc_mqenc_t *enc, jpc_mqencstate_t *state); + +/* Terminate the code. */ +int jpc_mqenc_flush(jpc_mqenc_t *enc, int termmode); + +/******************************************************************************\ +* Functions/macros for encoding bits. +\******************************************************************************/ + +/* Encode a bit. */ +#if !defined(DEBUG) +#define jpc_mqenc_putbit(enc, bit) jpc_mqenc_putbit_macro(enc, bit) +#else +#define jpc_mqenc_putbit(enc, bit) jpc_mqenc_putbit_func(enc, bit) +#endif + +/******************************************************************************\ +* Functions/macros for debugging. +\******************************************************************************/ + +int jpc_mqenc_dump(jpc_mqenc_t *mqenc, FILE *out); + +/******************************************************************************\ +* Implementation-specific details. +\******************************************************************************/ + +/* Note: This macro is included only to satisfy the needs of + the mqenc_putbit macro. */ +#define jpc_mqenc_putbit_macro(enc, bit) \ + (((*((enc)->curctx))->mps == (bit)) ? \ + (((enc)->areg -= (*(enc)->curctx)->qeval), \ + ((!((enc)->areg & 0x8000)) ? (jpc_mqenc_codemps2(enc)) : \ + ((enc)->creg += (*(enc)->curctx)->qeval))) : \ + jpc_mqenc_codelps(enc)) + +/* Note: These function prototypes are included only to satisfy the + needs of the mqenc_putbit_macro macro. Do not call any of these + functions directly. */ +int jpc_mqenc_codemps2(jpc_mqenc_t *enc); +int jpc_mqenc_codelps(jpc_mqenc_t *enc); + +/* Note: This function prototype is included only to satisfy the needs of + the mqenc_putbit macro. */ +int jpc_mqenc_putbit_func(jpc_mqenc_t *enc, int bit); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3144 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Quadrature Mirror-Image Filter Bank (QMFB) Library + * + * $Id: jpc_qmfb.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* +\******************************************************************************/ + +#undef WT_LENONE /* This is not needed due to normalization. */ +#define WT_DOSCALE + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include "jasper/jas_fix.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +#include "jpc_qmfb.h" +#include "jpc_tsfb.h" +#include "jpc_math.h" + +/******************************************************************************\ +* +\******************************************************************************/ + +#define QMFB_SPLITBUFSIZE 4096 +#define QMFB_JOINBUFSIZE 4096 + +int jpc_ft_analyze(int *a, int xstart, int ystart, int width, int height, + int stride); +int jpc_ft_synthesize(int *a, int xstart, int ystart, int width, int height, + int stride); + +int jpc_ns_analyze(int *a, int xstart, int ystart, int width, int height, + int stride); +int jpc_ns_synthesize(int *a, int xstart, int ystart, int width, + int height, int stride); + +void jpc_ft_fwdlift_row(jpc_fix_t *a, int numcols, int parity); +void jpc_ft_fwdlift_col(jpc_fix_t *a, int numrows, int stride, + int parity); +void jpc_ft_fwdlift_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity); +void jpc_ft_fwdlift_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity); + +void jpc_ft_invlift_row(jpc_fix_t *a, int numcols, int parity); +void jpc_ft_invlift_col(jpc_fix_t *a, int numrows, int stride, + int parity); +void jpc_ft_invlift_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity); +void jpc_ft_invlift_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity); + +void jpc_ns_fwdlift_row(jpc_fix_t *a, int numcols, int parity); +void jpc_ns_fwdlift_colgrp(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_ns_fwdlift_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity); +void jpc_ns_invlift_row(jpc_fix_t *a, int numcols, int parity); +void jpc_ns_invlift_colgrp(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_ns_invlift_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity); + +void jpc_qmfb_split_row(jpc_fix_t *a, int numcols, int parity); +void jpc_qmfb_split_col(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_qmfb_split_colgrp(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_qmfb_split_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity); + +void jpc_qmfb_join_row(jpc_fix_t *a, int numcols, int parity); +void jpc_qmfb_join_col(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_qmfb_join_colgrp(jpc_fix_t *a, int numrows, int stride, int parity); +void jpc_qmfb_join_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity); + +double jpc_ft_lpenergywts[32] = { + 1.2247448713915889, + 1.6583123951776999, + 2.3184046238739260, + 3.2691742076555053, + 4.6199296531440819, + 6.5323713152269596, + 9.2377452606141937, + 13.0639951297449581, + 18.4752262333915667, + 26.1278968190610392, + 36.9504194305524791, + 52.2557819580462777, + 73.9008347315741645, + 104.5115624560829133, + 147.8016689469569656, + 209.0231247296646018, + 295.6033378293900000, + 418.0462494347059419, + 591.2066756503630813, + 836.0924988714708661, + /* approximations */ + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661, + 836.0924988714708661 +}; + +double jpc_ft_hpenergywts[32] = { + 0.8477912478906585, + 0.9601432184835760, + 1.2593401049756179, + 1.7444107171191079, + 2.4538713036750726, + 3.4656517695088755, + 4.8995276398597856, + 6.9283970402160842, + 9.7980274940131444, + 13.8564306871112652, + 19.5959265076535587, + 27.7128159494245487, + 39.1918369552045860, + 55.4256262207444053, + 78.3836719028959124, + 110.8512517317256822, + 156.7673435548526868, + 221.7025033739244293, + 313.5346870787551552, + 443.4050067351659550, + /* approximations */ + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550, + 443.4050067351659550 +}; + +double jpc_ns_lpenergywts[32] = { + 1.4021081679297411, + 2.0303718560817923, + 2.9011625562785555, + 4.1152851751758002, + 5.8245108637728071, + 8.2387599345725171, + 11.6519546479210838, + 16.4785606470644375, + 23.3042776444606794, + 32.9572515613740435, + 46.6086013487782793, + 65.9145194076860861, + 93.2172084551803977, + 131.8290408510004283, + 186.4344176300625691, + 263.6580819564562148, + 372.8688353500955373, + 527.3161639447193920, + 745.7376707114038936, + 1054.6323278917823245, + /* approximations follow */ + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245, + 1054.6323278917823245 +}; + +double jpc_ns_hpenergywts[32] = { + 1.4425227650161456, + 1.9669426082455688, + 2.8839248082788891, + 4.1475208393432981, + 5.8946497530677817, + 8.3471789178590949, + 11.8086046551047463, + 16.7012780415647804, + 23.6196657032246620, + 33.4034255108592362, + 47.2396388881632632, + 66.8069597416714061, + 94.4793162154500692, + 133.6139330736999113, + 188.9586372358249378, + 267.2278678461869390, + 377.9172750722391356, + 534.4557359047058753, + 755.8345502191498326, + 1068.9114718353569060, + /* approximations follow */ + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060, + 1068.9114718353569060 +}; + +jpc_qmfb2d_t jpc_ft_qmfb2d = { + jpc_ft_analyze, + jpc_ft_synthesize, + jpc_ft_lpenergywts, + jpc_ft_hpenergywts +}; + +jpc_qmfb2d_t jpc_ns_qmfb2d = { + jpc_ns_analyze, + jpc_ns_synthesize, + jpc_ns_lpenergywts, + jpc_ns_hpenergywts +}; + +/******************************************************************************\ +* generic +\******************************************************************************/ + +void jpc_qmfb_split_row(jpc_fix_t *a, int numcols, int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numcols, 1); +#if !defined(HAVE_VLA) + jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE]; +#else + jpc_fix_t splitbuf[bufsize]; +#endif + jpc_fix_t *buf = splitbuf; + register jpc_fix_t *srcptr; + register jpc_fix_t *dstptr; + register int n; + register int m; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Get a buffer. */ + if (bufsize > QMFB_SPLITBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide in this case. */ + abort(); + } + } +#endif + + if (numcols >= 2) { + hstartcol = (numcols + 1 - parity) >> 1; + m = (parity) ? hstartcol : (numcols - hstartcol); + /* Save the samples destined for the highpass channel. */ + n = m; + dstptr = buf; + srcptr = &a[1 - parity]; + while (n-- > 0) { + *dstptr = *srcptr; + ++dstptr; + srcptr += 2; + } + /* Copy the appropriate samples into the lowpass channel. */ + dstptr = &a[1 - parity]; + srcptr = &a[2 - parity]; + n = numcols - m - (!parity); + while (n-- > 0) { + *dstptr = *srcptr; + ++dstptr; + srcptr += 2; + } + /* Copy the saved samples into the highpass channel. */ + dstptr = &a[hstartcol]; + srcptr = buf; + n = m; + while (n-- > 0) { + *dstptr = *srcptr; + ++dstptr; + ++srcptr; + } + } + +#if !defined(HAVE_VLA) + /* If the split buffer was allocated on the heap, free this memory. */ + if (buf != splitbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_split_col(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE]; +#else + jpc_fix_t splitbuf[bufsize]; +#endif + jpc_fix_t *buf = splitbuf; + register jpc_fix_t *srcptr; + register jpc_fix_t *dstptr; + register int n; + register int m; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Get a buffer. */ + if (bufsize > QMFB_SPLITBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide in this case. */ + abort(); + } + } +#endif + + if (numrows >= 2) { + hstartcol = (numrows + 1 - parity) >> 1; + m = (parity) ? hstartcol : (numrows - hstartcol); + /* Save the samples destined for the highpass channel. */ + n = m; + dstptr = buf; + srcptr = &a[(1 - parity) * stride]; + while (n-- > 0) { + *dstptr = *srcptr; + ++dstptr; + srcptr += stride << 1; + } + /* Copy the appropriate samples into the lowpass channel. */ + dstptr = &a[(1 - parity) * stride]; + srcptr = &a[(2 - parity) * stride]; + n = numrows - m - (!parity); + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += stride; + srcptr += stride << 1; + } + /* Copy the saved samples into the highpass channel. */ + dstptr = &a[hstartcol * stride]; + srcptr = buf; + n = m; + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += stride; + ++srcptr; + } + } + +#if !defined(HAVE_VLA) + /* If the split buffer was allocated on the heap, free this memory. */ + if (buf != splitbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_split_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE * JPC_QMFB_COLGRPSIZE]; +#else + jpc_fix_t splitbuf[bufsize * JPC_QMFB_COLGRPSIZE]; +#endif + jpc_fix_t *buf = splitbuf; + jpc_fix_t *srcptr; + jpc_fix_t *dstptr; + register jpc_fix_t *srcptr2; + register jpc_fix_t *dstptr2; + register int n; + register int i; + int m; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Get a buffer. */ + if (bufsize > QMFB_SPLITBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide in this case. */ + abort(); + } + } +#endif + + if (numrows >= 2) { + hstartcol = (numrows + 1 - parity) >> 1; + m = (parity) ? hstartcol : (numrows - hstartcol); + /* Save the samples destined for the highpass channel. */ + n = m; + dstptr = buf; + srcptr = &a[(1 - parity) * stride]; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += JPC_QMFB_COLGRPSIZE; + srcptr += stride << 1; + } + /* Copy the appropriate samples into the lowpass channel. */ + dstptr = &a[(1 - parity) * stride]; + srcptr = &a[(2 - parity) * stride]; + n = numrows - m - (!parity); + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += stride; + srcptr += stride << 1; + } + /* Copy the saved samples into the highpass channel. */ + dstptr = &a[hstartcol * stride]; + srcptr = buf; + n = m; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += stride; + srcptr += JPC_QMFB_COLGRPSIZE; + } + } + +#if !defined(HAVE_VLA) + /* If the split buffer was allocated on the heap, free this memory. */ + if (buf != splitbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_split_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE * JPC_QMFB_COLGRPSIZE]; +#else + jpc_fix_t splitbuf[bufsize * numcols]; +#endif + jpc_fix_t *buf = splitbuf; + jpc_fix_t *srcptr; + jpc_fix_t *dstptr; + register jpc_fix_t *srcptr2; + register jpc_fix_t *dstptr2; + register int n; + register int i; + int m; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Get a buffer. */ + if (bufsize > QMFB_SPLITBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide in this case. */ + abort(); + } + } +#endif + + if (numrows >= 2) { + hstartcol = (numrows + 1 - parity) >> 1; + m = (parity) ? hstartcol : (numrows - hstartcol); + /* Save the samples destined for the highpass channel. */ + n = m; + dstptr = buf; + srcptr = &a[(1 - parity) * stride]; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += numcols; + srcptr += stride << 1; + } + /* Copy the appropriate samples into the lowpass channel. */ + dstptr = &a[(1 - parity) * stride]; + srcptr = &a[(2 - parity) * stride]; + n = numrows - m - (!parity); + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += stride; + srcptr += stride << 1; + } + /* Copy the saved samples into the highpass channel. */ + dstptr = &a[hstartcol * stride]; + srcptr = buf; + n = m; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += stride; + srcptr += numcols; + } + } + +#if !defined(HAVE_VLA) + /* If the split buffer was allocated on the heap, free this memory. */ + if (buf != splitbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_join_row(jpc_fix_t *a, int numcols, int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numcols, 1); +#if !defined(HAVE_VLA) + jpc_fix_t joinbuf[QMFB_JOINBUFSIZE]; +#else + jpc_fix_t joinbuf[bufsize]; +#endif + jpc_fix_t *buf = joinbuf; + register jpc_fix_t *srcptr; + register jpc_fix_t *dstptr; + register int n; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Allocate memory for the join buffer from the heap. */ + if (bufsize > QMFB_JOINBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide. */ + abort(); + } + } +#endif + + hstartcol = (numcols + 1 - parity) >> 1; + + /* Save the samples from the lowpass channel. */ + n = hstartcol; + srcptr = &a[0]; + dstptr = buf; + while (n-- > 0) { + *dstptr = *srcptr; + ++srcptr; + ++dstptr; + } + /* Copy the samples from the highpass channel into place. */ + srcptr = &a[hstartcol]; + dstptr = &a[1 - parity]; + n = numcols - hstartcol; + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += 2; + ++srcptr; + } + /* Copy the samples from the lowpass channel into place. */ + srcptr = buf; + dstptr = &a[parity]; + n = hstartcol; + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += 2; + ++srcptr; + } + +#if !defined(HAVE_VLA) + /* If the join buffer was allocated on the heap, free this memory. */ + if (buf != joinbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_join_col(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t joinbuf[QMFB_JOINBUFSIZE]; +#else + jpc_fix_t joinbuf[bufsize]; +#endif + jpc_fix_t *buf = joinbuf; + register jpc_fix_t *srcptr; + register jpc_fix_t *dstptr; + register int n; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Allocate memory for the join buffer from the heap. */ + if (bufsize > QMFB_JOINBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide. */ + abort(); + } + } +#endif + + hstartcol = (numrows + 1 - parity) >> 1; + + /* Save the samples from the lowpass channel. */ + n = hstartcol; + srcptr = &a[0]; + dstptr = buf; + while (n-- > 0) { + *dstptr = *srcptr; + srcptr += stride; + ++dstptr; + } + /* Copy the samples from the highpass channel into place. */ + srcptr = &a[hstartcol * stride]; + dstptr = &a[(1 - parity) * stride]; + n = numrows - hstartcol; + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += 2 * stride; + srcptr += stride; + } + /* Copy the samples from the lowpass channel into place. */ + srcptr = buf; + dstptr = &a[parity * stride]; + n = hstartcol; + while (n-- > 0) { + *dstptr = *srcptr; + dstptr += 2 * stride; + ++srcptr; + } + +#if !defined(HAVE_VLA) + /* If the join buffer was allocated on the heap, free this memory. */ + if (buf != joinbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_join_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t joinbuf[QMFB_JOINBUFSIZE * JPC_QMFB_COLGRPSIZE]; +#else + jpc_fix_t joinbuf[bufsize * JPC_QMFB_COLGRPSIZE]; +#endif + jpc_fix_t *buf = joinbuf; + jpc_fix_t *srcptr; + jpc_fix_t *dstptr; + register jpc_fix_t *srcptr2; + register jpc_fix_t *dstptr2; + register int n; + register int i; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Allocate memory for the join buffer from the heap. */ + if (bufsize > QMFB_JOINBUFSIZE) { + if (!(buf = jas_alloc2(bufsize, JPC_QMFB_COLGRPSIZE * sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide. */ + abort(); + } + } +#endif + + hstartcol = (numrows + 1 - parity) >> 1; + + /* Save the samples from the lowpass channel. */ + n = hstartcol; + srcptr = &a[0]; + dstptr = buf; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + srcptr += stride; + dstptr += JPC_QMFB_COLGRPSIZE; + } + /* Copy the samples from the highpass channel into place. */ + srcptr = &a[hstartcol * stride]; + dstptr = &a[(1 - parity) * stride]; + n = numrows - hstartcol; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += 2 * stride; + srcptr += stride; + } + /* Copy the samples from the lowpass channel into place. */ + srcptr = buf; + dstptr = &a[parity * stride]; + n = hstartcol; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += 2 * stride; + srcptr += JPC_QMFB_COLGRPSIZE; + } + +#if !defined(HAVE_VLA) + /* If the join buffer was allocated on the heap, free this memory. */ + if (buf != joinbuf) { + jas_free(buf); + } +#endif + +} + +void jpc_qmfb_join_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity) +{ + + int bufsize = JPC_CEILDIVPOW2(numrows, 1); +#if !defined(HAVE_VLA) + jpc_fix_t joinbuf[QMFB_JOINBUFSIZE * JPC_QMFB_COLGRPSIZE]; +#else + jpc_fix_t joinbuf[bufsize * numcols]; +#endif + jpc_fix_t *buf = joinbuf; + jpc_fix_t *srcptr; + jpc_fix_t *dstptr; + register jpc_fix_t *srcptr2; + register jpc_fix_t *dstptr2; + register int n; + register int i; + int hstartcol; + +#if !defined(HAVE_VLA) + /* Allocate memory for the join buffer from the heap. */ + if (bufsize > QMFB_JOINBUFSIZE) { + if (!(buf = jas_alloc3(bufsize, numcols, sizeof(jpc_fix_t)))) { + /* We have no choice but to commit suicide. */ + abort(); + } + } +#endif + + hstartcol = (numrows + 1 - parity) >> 1; + + /* Save the samples from the lowpass channel. */ + n = hstartcol; + srcptr = &a[0]; + dstptr = buf; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + srcptr += stride; + dstptr += numcols; + } + /* Copy the samples from the highpass channel into place. */ + srcptr = &a[hstartcol * stride]; + dstptr = &a[(1 - parity) * stride]; + n = numrows - hstartcol; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += 2 * stride; + srcptr += stride; + } + /* Copy the samples from the lowpass channel into place. */ + srcptr = buf; + dstptr = &a[parity * stride]; + n = hstartcol; + while (n-- > 0) { + dstptr2 = dstptr; + srcptr2 = srcptr; + for (i = 0; i < numcols; ++i) { + *dstptr2 = *srcptr2; + ++dstptr2; + ++srcptr2; + } + dstptr += 2 * stride; + srcptr += numcols; + } + +#if !defined(HAVE_VLA) + /* If the join buffer was allocated on the heap, free this memory. */ + if (buf != joinbuf) { + jas_free(buf); + } +#endif + +} + +/******************************************************************************\ +* 5/3 transform +\******************************************************************************/ + +void jpc_ft_fwdlift_row(jpc_fix_t *a, int numcols, int parity) +{ + + register jpc_fix_t *lptr; + register jpc_fix_t *hptr; + register int n; + int llen; + + llen = (numcols + 1 - parity) >> 1; + + if (numcols > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + hptr[0] -= lptr[0]; + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + hptr[0] -= (lptr[0] + lptr[1]) >> 1; + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + hptr[0] -= lptr[0]; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + lptr[0] += (hptr[0] + 1) >> 1; + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + lptr[0] += (hptr[0] + hptr[1] + 2) >> 2; + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + lptr[0] += (hptr[0] + 1) >> 1; + } + + } else { + + if (parity) { + lptr = &a[0]; + lptr[0] <<= 1; + } + + } + +} + +void jpc_ft_fwdlift_col(jpc_fix_t *a, int numrows, int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; +#if 0 + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int i; +#endif + register int n; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + hptr[0] -= lptr[0]; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + hptr[0] -= (lptr[0] + lptr[stride]) >> 1; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + hptr[0] -= lptr[0]; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr[0] += (hptr[0] + 1) >> 1; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr[0] += (hptr[0] + hptr[stride] + 2) >> 2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr[0] += (hptr[0] + 1) >> 1; + } + + } else { + + if (parity) { + lptr = &a[0]; + lptr[0] <<= 1; + } + + } + +} + +void jpc_ft_fwdlift_colgrp(jpc_fix_t *a, int numrows, int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] -= lptr2[0]; + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] -= (lptr2[0] + lptr2[stride]) >> 1; + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] -= lptr2[0]; + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] += (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] += (hptr2[0] + hptr2[stride] + 2) >> 2; + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] += (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + } + + } else { + + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] <<= 1; + ++lptr2; + } + } + + } + +} + +void jpc_ft_fwdlift_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] -= lptr2[0]; + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] -= (lptr2[0] + lptr2[stride]) >> 1; + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] -= lptr2[0]; + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] += (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] += (hptr2[0] + hptr2[stride] + 2) >> 2; + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] += (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + } + + } else { + + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < numcols; ++i) { + lptr2[0] <<= 1; + ++lptr2; + } + } + + } + +} + +void jpc_ft_invlift_row(jpc_fix_t *a, int numcols, int parity) +{ + + register jpc_fix_t *lptr; + register jpc_fix_t *hptr; + register int n; + int llen; + + llen = (numcols + 1 - parity) >> 1; + + if (numcols > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + lptr[0] -= (hptr[0] + 1) >> 1; + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + lptr[0] -= (hptr[0] + hptr[1] + 2) >> 2; + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + lptr[0] -= (hptr[0] + 1) >> 1; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + hptr[0] += lptr[0]; + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + hptr[0] += (lptr[0] + lptr[1]) >> 1; + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + hptr[0] += lptr[0]; + } + + } else { + + if (parity) { + lptr = &a[0]; + lptr[0] >>= 1; + } + + } + +} + +void jpc_ft_invlift_col(jpc_fix_t *a, int numrows, int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; +#if 0 + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int i; +#endif + register int n; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr[0] -= (hptr[0] + 1) >> 1; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr[0] -= (hptr[0] + hptr[stride] + 2) >> 2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr[0] -= (hptr[0] + 1) >> 1; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + hptr[0] += lptr[0]; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + hptr[0] += (lptr[0] + lptr[stride]) >> 1; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + hptr[0] += lptr[0]; + } + + } else { + + if (parity) { + lptr = &a[0]; + lptr[0] >>= 1; + } + + } + +} + +void jpc_ft_invlift_colgrp(jpc_fix_t *a, int numrows, int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] -= (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] -= (hptr2[0] + hptr2[stride] + 2) >> 2; + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] -= (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] += lptr2[0]; + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] += (lptr2[0] + lptr2[stride]) >> 1; + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] += lptr2[0]; + ++lptr2; + ++hptr2; + } + } + + } else { + + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] >>= 1; + ++lptr2; + } + } + + } + +} + +void jpc_ft_invlift_colres(jpc_fix_t *a, int numrows, int numcols, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] -= (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] -= (hptr2[0] + hptr2[stride] + 2) >> 2; + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] -= (hptr2[0] + 1) >> 1; + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] += lptr2[0]; + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] += (lptr2[0] + lptr2[stride]) >> 1; + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] += lptr2[0]; + ++lptr2; + ++hptr2; + } + } + + } else { + + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < numcols; ++i) { + lptr2[0] >>= 1; + ++lptr2; + } + } + + } + +} + +int jpc_ft_analyze(int *a, int xstart, int ystart, int width, int height, + int stride) +{ + int numrows = height; + int numcols = width; + int rowparity = ystart & 1; + int colparity = xstart & 1; + int i; + jpc_fix_t *startptr; + int maxcols; + + maxcols = (numcols / JPC_QMFB_COLGRPSIZE) * JPC_QMFB_COLGRPSIZE; + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < maxcols; i += JPC_QMFB_COLGRPSIZE) { + jpc_qmfb_split_colgrp(startptr, numrows, stride, rowparity); + jpc_ft_fwdlift_colgrp(startptr, numrows, stride, rowparity); + startptr += JPC_QMFB_COLGRPSIZE; + } + if (maxcols < numcols) { + jpc_qmfb_split_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + jpc_ft_fwdlift_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + } + + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < numrows; ++i) { + jpc_qmfb_split_row(startptr, numcols, colparity); + jpc_ft_fwdlift_row(startptr, numcols, colparity); + startptr += stride; + } + + return 0; + +} + +int jpc_ft_synthesize(int *a, int xstart, int ystart, int width, int height, + int stride) +{ + int numrows = height; + int numcols = width; + int rowparity = ystart & 1; + int colparity = xstart & 1; + + int maxcols; + jpc_fix_t *startptr; + int i; + + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < numrows; ++i) { + jpc_ft_invlift_row(startptr, numcols, colparity); + jpc_qmfb_join_row(startptr, numcols, colparity); + startptr += stride; + } + + maxcols = (numcols / JPC_QMFB_COLGRPSIZE) * JPC_QMFB_COLGRPSIZE; + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < maxcols; i += JPC_QMFB_COLGRPSIZE) { + jpc_ft_invlift_colgrp(startptr, numrows, stride, rowparity); + jpc_qmfb_join_colgrp(startptr, numrows, stride, rowparity); + startptr += JPC_QMFB_COLGRPSIZE; + } + if (maxcols < numcols) { + jpc_ft_invlift_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + jpc_qmfb_join_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + } + + return 0; + +} + +/******************************************************************************\ +* 9/7 transform +\******************************************************************************/ + +#define ALPHA (-1.586134342059924) +#define BETA (-0.052980118572961) +#define GAMMA (0.882911075530934) +#define DELTA (0.443506852043971) +#define LGAIN (1.0 / 1.23017410558578) +#define HGAIN (1.0 / 1.62578613134411) + +void jpc_ns_fwdlift_row(jpc_fix_t *a, int numcols, int parity) +{ + + register jpc_fix_t *lptr; + register jpc_fix_t *hptr; + register int n; + int llen; + + llen = (numcols + 1 - parity) >> 1; + + if (numcols > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr[0])); + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr[0], lptr[1]))); + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr[0])); + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr[0])); + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr[0], hptr[1]))); + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr[0])); + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr[0])); + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr[0], lptr[1]))); + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + jpc_fix_pluseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr[0])); + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr[0])); + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr[0], hptr[1]))); + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + jpc_fix_pluseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr[0])); + } + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr[0] = jpc_fix_mul(lptr[0], jpc_dbltofix(LGAIN)); + ++lptr; + } + hptr = &a[llen]; + n = numcols - llen; + while (n-- > 0) { + hptr[0] = jpc_fix_mul(hptr[0], jpc_dbltofix(HGAIN)); + ++hptr; + } +#endif + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr = &a[0]; + lptr[0] <<= 1; + } +#endif + + } + +} + +void jpc_ns_fwdlift_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(LGAIN)); + ++lptr2; + } + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(HGAIN)); + ++hptr2; + } + hptr += stride; + } +#endif + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] <<= 1; + ++lptr2; + } + } +#endif + + } + +} + +void jpc_ns_fwdlift_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(LGAIN)); + ++lptr2; + } + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(HGAIN)); + ++hptr2; + } + hptr += stride; + } +#endif + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < numcols; ++i) { + lptr2[0] <<= 1; + ++lptr2; + } + } +#endif + + } + +} + +void jpc_ns_fwdlift_col(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++hptr2; + ++lptr2; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++hptr2; + ++lptr2; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_pluseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(LGAIN)); + ++lptr2; + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(HGAIN)); + ++hptr2; + hptr += stride; + } +#endif + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + lptr2[0] <<= 1; + ++lptr2; + } +#endif + + } + +} + +void jpc_ns_invlift_row(jpc_fix_t *a, int numcols, int parity) +{ + + register jpc_fix_t *lptr; + register jpc_fix_t *hptr; + register int n; + int llen; + + llen = (numcols + 1 - parity) >> 1; + + if (numcols > 1) { + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr[0] = jpc_fix_mul(lptr[0], jpc_dbltofix(1.0 / LGAIN)); + ++lptr; + } + hptr = &a[llen]; + n = numcols - llen; + while (n-- > 0) { + hptr[0] = jpc_fix_mul(hptr[0], jpc_dbltofix(1.0 / HGAIN)); + ++hptr; + } +#endif + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr[0])); + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr[0], hptr[1]))); + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * DELTA), + hptr[0])); + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr[0])); + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr[0], lptr[1]))); + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * GAMMA), + lptr[0])); + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (!parity) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr[0])); + ++lptr; + } + n = llen - (!parity) - (parity != (numcols & 1)); + while (n-- > 0) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr[0], hptr[1]))); + ++lptr; + ++hptr; + } + if (parity != (numcols & 1)) { + jpc_fix_minuseq(lptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr[0])); + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen]; + if (parity) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr[0])); + ++hptr; + } + n = numcols - llen - parity - (parity == (numcols & 1)); + while (n-- > 0) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr[0], lptr[1]))); + ++hptr; + ++lptr; + } + if (parity == (numcols & 1)) { + jpc_fix_minuseq(hptr[0], jpc_fix_mul(jpc_dbltofix(2.0 * ALPHA), + lptr[0])); + } + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr = &a[0]; + lptr[0] >>= 1; + } +#endif + + } + +} + +void jpc_ns_invlift_colgrp(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(1.0 / LGAIN)); + ++lptr2; + } + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(1.0 / HGAIN)); + ++hptr2; + } + hptr += stride; + } +#endif + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < JPC_QMFB_COLGRPSIZE; ++i) { + lptr2[0] >>= 1; + ++lptr2; + } + } +#endif + + } + +} + +void jpc_ns_invlift_colres(jpc_fix_t *a, int numrows, int numcols, + int stride, int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + register int i; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + for (i = 0; i < numcols; ++i) { + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(1.0 / LGAIN)); + ++lptr2; + } + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(1.0 / HGAIN)); + ++hptr2; + } + hptr += stride; + } +#endif + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + } + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++hptr2; + ++lptr2; + } + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + } + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + for (i = 0; i < numcols; ++i) { + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++lptr2; + ++hptr2; + } + } + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + for (i = 0; i < numcols; ++i) { + lptr2[0] >>= 1; + ++lptr2; + } + } +#endif + + } + +} + +void jpc_ns_invlift_col(jpc_fix_t *a, int numrows, int stride, + int parity) +{ + + jpc_fix_t *lptr; + jpc_fix_t *hptr; + register jpc_fix_t *lptr2; + register jpc_fix_t *hptr2; + register int n; + int llen; + + llen = (numrows + 1 - parity) >> 1; + + if (numrows > 1) { + + /* Apply the scaling step. */ +#if defined(WT_DOSCALE) + lptr = &a[0]; + n = llen; + while (n-- > 0) { + lptr2 = lptr; + lptr2[0] = jpc_fix_mul(lptr2[0], jpc_dbltofix(1.0 / LGAIN)); + ++lptr2; + lptr += stride; + } + hptr = &a[llen * stride]; + n = numrows - llen; + while (n-- > 0) { + hptr2 = hptr; + hptr2[0] = jpc_fix_mul(hptr2[0], jpc_dbltofix(1.0 / HGAIN)); + ++hptr2; + hptr += stride; + } +#endif + + /* Apply the first lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(DELTA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + DELTA), hptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the second lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++hptr2; + ++lptr2; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(GAMMA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + GAMMA), lptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the third lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (!parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + lptr += stride; + } + n = llen - (!parity) - (parity != (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(BETA), + jpc_fix_add(hptr2[0], hptr2[stride]))); + ++lptr2; + ++hptr2; + lptr += stride; + hptr += stride; + } + if (parity != (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(lptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * BETA), + hptr2[0])); + ++lptr2; + ++hptr2; + } + + /* Apply the fourth lifting step. */ + lptr = &a[0]; + hptr = &a[llen * stride]; + if (parity) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++hptr2; + ++lptr2; + hptr += stride; + } + n = numrows - llen - parity - (parity == (numrows & 1)); + while (n-- > 0) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(ALPHA), + jpc_fix_add(lptr2[0], lptr2[stride]))); + ++lptr2; + ++hptr2; + hptr += stride; + lptr += stride; + } + if (parity == (numrows & 1)) { + lptr2 = lptr; + hptr2 = hptr; + jpc_fix_minuseq(hptr2[0], jpc_fix_mul(jpc_dbltofix(2.0 * + ALPHA), lptr2[0])); + ++lptr2; + ++hptr2; + } + + } else { + +#if defined(WT_LENONE) + if (parity) { + lptr2 = &a[0]; + lptr2[0] >>= 1; + ++lptr2; + } +#endif + + } + +} + +int jpc_ns_analyze(int *a, int xstart, int ystart, int width, int height, + int stride) +{ + + int numrows = height; + int numcols = width; + int rowparity = ystart & 1; + int colparity = xstart & 1; + int i; + jpc_fix_t *startptr; + int maxcols; + + maxcols = (numcols / JPC_QMFB_COLGRPSIZE) * JPC_QMFB_COLGRPSIZE; + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < maxcols; i += JPC_QMFB_COLGRPSIZE) { + jpc_qmfb_split_colgrp(startptr, numrows, stride, rowparity); + jpc_ns_fwdlift_colgrp(startptr, numrows, stride, rowparity); + startptr += JPC_QMFB_COLGRPSIZE; + } + if (maxcols < numcols) { + jpc_qmfb_split_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + jpc_ns_fwdlift_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + } + + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < numrows; ++i) { + jpc_qmfb_split_row(startptr, numcols, colparity); + jpc_ns_fwdlift_row(startptr, numcols, colparity); + startptr += stride; + } + + return 0; + +} + +int jpc_ns_synthesize(int *a, int xstart, int ystart, int width, + int height, int stride) +{ + + int numrows = height; + int numcols = width; + int rowparity = ystart & 1; + int colparity = xstart & 1; + int maxcols; + jpc_fix_t *startptr; + int i; + + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < numrows; ++i) { + jpc_ns_invlift_row(startptr, numcols, colparity); + jpc_qmfb_join_row(startptr, numcols, colparity); + startptr += stride; + } + + maxcols = (numcols / JPC_QMFB_COLGRPSIZE) * JPC_QMFB_COLGRPSIZE; + startptr = (jpc_fix_t*)&a[0]; + for (i = 0; i < maxcols; i += JPC_QMFB_COLGRPSIZE) { + jpc_ns_invlift_colgrp(startptr, numrows, stride, rowparity); + jpc_qmfb_join_colgrp(startptr, numrows, stride, rowparity); + startptr += JPC_QMFB_COLGRPSIZE; + } + if (maxcols < numcols) { + jpc_ns_invlift_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + jpc_qmfb_join_colres(startptr, numrows, numcols - maxcols, stride, + rowparity); + } + + return 0; + +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_qmfb.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Quadrature Mirror-Image Filter Bank (QMFB) Routines + * + * $Id: jpc_qmfb.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_QMFB_H +#define JPC_QMFB_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_seq.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* QMFB IDs. */ +#define JPC_QMFB1D_FT 1 /* 5/3 */ +#define JPC_QMFB1D_NS 2 /* 9/7 */ + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +#if !defined(JPC_QMFB_COLGRPSIZE) +/* The number of columns to group together during the vertical processing +stage of the wavelet transform. */ +/* The default value for this parameter is probably not optimal for +any particular platform. Hopefully, it is not too unreasonable, however. */ +#define JPC_QMFB_COLGRPSIZE 16 +#endif + +typedef struct { + int (*analyze)(int *, int, int, int, int, int); + int (*synthesize)(int *, int, int, int, int, int); + double *lpenergywts; + double *hpenergywts; +} jpc_qmfb2d_t; + +extern jpc_qmfb2d_t jpc_ft_qmfb2d; +extern jpc_qmfb2d_t jpc_ns_qmfb2d; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,497 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_t1cod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_math.h" + +#include "jpc_bs.h" +#include "jpc_dec.h" +#include "jpc_cs.h" +#include "jpc_mqcod.h" +#include "jpc_t1cod.h" +#include "jpc_tsfb.h" + +double jpc_pow2i(int n); + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +int jpc_zcctxnolut[4 * 256]; +int jpc_spblut[256]; +int jpc_scctxnolut[256]; +int jpc_magctxnolut[4096]; + +jpc_fix_t jpc_signmsedec[1 << JPC_NMSEDEC_BITS]; +jpc_fix_t jpc_refnmsedec[1 << JPC_NMSEDEC_BITS]; +jpc_fix_t jpc_signmsedec0[1 << JPC_NMSEDEC_BITS]; +jpc_fix_t jpc_refnmsedec0[1 << JPC_NMSEDEC_BITS]; + +jpc_mqctx_t jpc_mqctxs[JPC_NUMCTXS]; + +/******************************************************************************\ +* +\******************************************************************************/ + +void jpc_initmqctxs(void); + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +int JPC_PASSTYPE(int passno) +{ + int passtype; + switch (passno % 3) { + case 0: + passtype = JPC_CLNPASS; + break; + case 1: + passtype = JPC_SIGPASS; + break; + case 2: + passtype = JPC_REFPASS; + break; + default: + passtype = -1; + assert(0); + break; + } + return passtype; +} + +int JPC_NOMINALGAIN(int qmfbid, int numlvls, int lvlno, int orient) +{ + /* Avoid compiler warnings about unused parameters. */ + numlvls = 0; + +if (qmfbid == JPC_COX_INS) { + return 0; +} + assert(qmfbid == JPC_COX_RFT); + if (lvlno == 0) { + assert(orient == JPC_TSFB_LL); + return 0; + } else { + switch (orient) { + case JPC_TSFB_LH: + case JPC_TSFB_HL: + return 1; + break; + case JPC_TSFB_HH: + return 2; + break; + } + } + abort(); +} + +/******************************************************************************\ +* Coding pass related functions. +\******************************************************************************/ + +int JPC_SEGTYPE(int passno, int firstpassno, int bypass) +{ + int passtype; + if (bypass) { + passtype = JPC_PASSTYPE(passno); + if (passtype == JPC_CLNPASS) { + return JPC_SEG_MQ; + } + return ((passno < firstpassno + 10) ? JPC_SEG_MQ : JPC_SEG_RAW); + } else { + return JPC_SEG_MQ; + } +} + +int JPC_SEGPASSCNT(int passno, int firstpassno, int numpasses, int bypass, int termall) +{ + int ret; + int passtype; + + if (termall) { + ret = 1; + } else if (bypass) { + if (passno < firstpassno + 10) { + ret = 10 - (passno - firstpassno); + } else { + passtype = JPC_PASSTYPE(passno); + switch (passtype) { + case JPC_SIGPASS: + ret = 2; + break; + case JPC_REFPASS: + ret = 1; + break; + case JPC_CLNPASS: + ret = 1; + break; + default: + ret = -1; + assert(0); + break; + } + } + } else { + ret = JPC_PREC * 3 - 2; + } + ret = JAS_MIN(ret, numpasses - passno); + return ret; +} + +int JPC_ISTERMINATED(int passno, int firstpassno, int numpasses, int termall, + int lazy) +{ + int ret; + int n; + if (passno - firstpassno == numpasses - 1) { + ret = 1; + } else { + n = JPC_SEGPASSCNT(passno, firstpassno, numpasses, lazy, termall); + ret = (n <= 1) ? 1 : 0; + } + + return ret; +} + +/******************************************************************************\ +* Lookup table code. +\******************************************************************************/ + +void jpc_initluts() +{ + int i; + int orient; + int refine; + float u; + float v; + float t; + +/* XXX - hack */ +jpc_initmqctxs(); + + for (orient = 0; orient < 4; ++orient) { + for (i = 0; i < 256; ++i) { + jpc_zcctxnolut[(orient << 8) | i] = jpc_getzcctxno(i, orient); + } + } + + for (i = 0; i < 256; ++i) { + jpc_spblut[i] = jpc_getspb(i << 4); + } + + for (i = 0; i < 256; ++i) { + jpc_scctxnolut[i] = jpc_getscctxno(i << 4); + } + + for (refine = 0; refine < 2; ++refine) { + for (i = 0; i < 2048; ++i) { + jpc_magctxnolut[(refine << 11) + i] = jpc_getmagctxno((refine ? JPC_REFINE : 0) | i); + } + } + + for (i = 0; i < (1 << JPC_NMSEDEC_BITS); ++i) { + t = i * jpc_pow2i(-JPC_NMSEDEC_FRACBITS); + u = t; + v = t - 1.5; + jpc_signmsedec[i] = jpc_dbltofix(floor((u * u - v * v) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS)); +/* XXX - this calc is not correct */ + jpc_signmsedec0[i] = jpc_dbltofix(floor((u * u) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS)); + u = t - 1.0; + if (i & (1 << (JPC_NMSEDEC_BITS - 1))) { + v = t - 1.5; + } else { + v = t - 0.5; + } + jpc_refnmsedec[i] = jpc_dbltofix(floor((u * u - v * v) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS)); +/* XXX - this calc is not correct */ + jpc_refnmsedec0[i] = jpc_dbltofix(floor((u * u) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS)); + } +} + +jpc_fix_t jpc_getsignmsedec_func(jpc_fix_t x, int bitpos) +{ + jpc_fix_t y; + assert(!(x & (~JAS_ONES(bitpos + 1)))); + y = jpc_getsignmsedec_macro(x, bitpos); + return y; +} + +int jpc_getzcctxno(int f, int orient) +{ + int h; + int v; + int d; + int n; + int t; + int hv; + + /* Avoid compiler warning. */ + n = 0; + + h = ((f & JPC_WSIG) != 0) + ((f & JPC_ESIG) != 0); + v = ((f & JPC_NSIG) != 0) + ((f & JPC_SSIG) != 0); + d = ((f & JPC_NWSIG) != 0) + ((f & JPC_NESIG) != 0) + ((f & JPC_SESIG) != 0) + ((f & JPC_SWSIG) != 0); + switch (orient) { + case JPC_TSFB_HL: + t = h; + h = v; + v = t; + case JPC_TSFB_LL: + case JPC_TSFB_LH: + if (!h) { + if (!v) { + if (!d) { + n = 0; + } else if (d == 1) { + n = 1; + } else { + n = 2; + } + } else if (v == 1) { + n = 3; + } else { + n = 4; + } + } else if (h == 1) { + if (!v) { + if (!d) { + n = 5; + } else { + n = 6; + } + } else { + n = 7; + } + } else { + n = 8; + } + break; + case JPC_TSFB_HH: + hv = h + v; + if (!d) { + if (!hv) { + n = 0; + } else if (hv == 1) { + n = 1; + } else { + n = 2; + } + } else if (d == 1) { + if (!hv) { + n = 3; + } else if (hv == 1) { + n = 4; + } else { + n = 5; + } + } else if (d == 2) { + if (!hv) { + n = 6; + } else { + n = 7; + } + } else { + n = 8; + } + break; + } + assert(n < JPC_NUMZCCTXS); + return JPC_ZCCTXNO + n; +} + +int jpc_getspb(int f) +{ + int hc; + int vc; + int n; + + hc = JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == JPC_ESIG) + ((f & (JPC_WSIG | JPC_WSGN)) == JPC_WSIG), 1) - + JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == (JPC_ESIG | JPC_ESGN)) + ((f & (JPC_WSIG | JPC_WSGN)) == (JPC_WSIG | JPC_WSGN)), 1); + vc = JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == JPC_NSIG) + ((f & (JPC_SSIG | JPC_SSGN)) == JPC_SSIG), 1) - + JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == (JPC_NSIG | JPC_NSGN)) + ((f & (JPC_SSIG | JPC_SSGN)) == (JPC_SSIG | JPC_SSGN)), 1); + if (!hc && !vc) { + n = 0; + } else { + n = (!(hc > 0 || (!hc && vc > 0))); + } + return n; +} + +int jpc_getscctxno(int f) +{ + int hc; + int vc; + int n; + + /* Avoid compiler warning. */ + n = 0; + + hc = JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == JPC_ESIG) + ((f & (JPC_WSIG | JPC_WSGN)) == JPC_WSIG), + 1) - JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == (JPC_ESIG | JPC_ESGN)) + + ((f & (JPC_WSIG | JPC_WSGN)) == (JPC_WSIG | JPC_WSGN)), 1); + vc = JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == JPC_NSIG) + ((f & (JPC_SSIG | JPC_SSGN)) == JPC_SSIG), + 1) - JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == (JPC_NSIG | JPC_NSGN)) + + ((f & (JPC_SSIG | JPC_SSGN)) == (JPC_SSIG | JPC_SSGN)), 1); + assert(hc >= -1 && hc <= 1 && vc >= -1 && vc <= 1); + if (hc < 0) { + hc = -hc; + vc = -vc; + } + if (!hc) { + if (vc == -1) { + n = 1; + } else if (!vc) { + n = 0; + } else { + n = 1; + } + } else if (hc == 1) { + if (vc == -1) { + n = 2; + } else if (!vc) { + n = 3; + } else { + n = 4; + } + } + assert(n < JPC_NUMSCCTXS); + return JPC_SCCTXNO + n; +} + +int jpc_getmagctxno(int f) +{ + int n; + + if (!(f & JPC_REFINE)) { + n = (f & (JPC_OTHSIGMSK)) ? 1 : 0; + } else { + n = 2; + } + + assert(n < JPC_NUMMAGCTXS); + return JPC_MAGCTXNO + n; +} + +void jpc_initctxs(jpc_mqctx_t *ctxs) +{ + jpc_mqctx_t *ctx; + int i; + + ctx = ctxs; + for (i = 0; i < JPC_NUMCTXS; ++i) { + ctx->mps = 0; + switch (i) { + case JPC_UCTXNO: + ctx->ind = 46; + break; + case JPC_ZCCTXNO: + ctx->ind = 4; + break; + case JPC_AGGCTXNO: + ctx->ind = 3; + break; + default: + ctx->ind = 0; + break; + } + ++ctx; + } +} + +void jpc_initmqctxs() +{ + jpc_initctxs(jpc_mqctxs); +} + +/* Calculate the real quantity exp2(n), where x is an integer. */ +double jpc_pow2i(int n) +{ + double x; + double a; + + x = 1.0; + if (n < 0) { + a = 0.5; + n = -n; + } else { + a = 2.0; + } + while (--n >= 0) { + x *= a; + } + return x; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1cod.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_t1cod.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T1COD_H +#define JPC_T1COD_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_fix.h" +#include "jasper/jas_math.h" + +#include "jpc_mqcod.h" +#include "jpc_tsfb.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +/* The number of bits used to index into various lookup tables. */ +#define JPC_NMSEDEC_BITS 7 +#define JPC_NMSEDEC_FRACBITS (JPC_NMSEDEC_BITS - 1) + +/* + * Segment types. + */ + +/* Invalid. */ +#define JPC_SEG_INVALID 0 +/* MQ. */ +#define JPC_SEG_MQ 1 +/* Raw. */ +#define JPC_SEG_RAW 2 + +/* The nominal word size. */ +#define JPC_PREC 32 + +/* Tier-1 coding pass types. */ +#define JPC_SIGPASS 0 /* significance */ +#define JPC_REFPASS 1 /* refinement */ +#define JPC_CLNPASS 2 /* cleanup */ + +/* + * Per-sample state information for tier-1 coding. + */ + +/* The northeast neighbour has been found to be significant. */ +#define JPC_NESIG 0x0001 +/* The southeast neighbour has been found to be significant. */ +#define JPC_SESIG 0x0002 +/* The southwest neighbour has been found to be significant. */ +#define JPC_SWSIG 0x0004 +/* The northwest neighbour has been found to be significant. */ +#define JPC_NWSIG 0x0008 +/* The north neighbour has been found to be significant. */ +#define JPC_NSIG 0x0010 +/* The east neighbour has been found to be significant. */ +#define JPC_ESIG 0x0020 +/* The south neighbour has been found to be significant. */ +#define JPC_SSIG 0x0040 +/* The west neighbour has been found to be significant. */ +#define JPC_WSIG 0x0080 +/* The significance mask for 8-connected neighbours. */ +#define JPC_OTHSIGMSK \ + (JPC_NSIG | JPC_NESIG | JPC_ESIG | JPC_SESIG | JPC_SSIG | JPC_SWSIG | JPC_WSIG | JPC_NWSIG) +/* The significance mask for 4-connected neighbours. */ +#define JPC_PRIMSIGMSK (JPC_NSIG | JPC_ESIG | JPC_SSIG | JPC_WSIG) + +/* The north neighbour is negative in value. */ +#define JPC_NSGN 0x0100 +/* The east neighbour is negative in value. */ +#define JPC_ESGN 0x0200 +/* The south neighbour is negative in value. */ +#define JPC_SSGN 0x0400 +/* The west neighbour is negative in value. */ +#define JPC_WSGN 0x0800 +/* The sign mask for 4-connected neighbours. */ +#define JPC_SGNMSK (JPC_NSGN | JPC_ESGN | JPC_SSGN | JPC_WSGN) + +/* This sample has been found to be significant. */ +#define JPC_SIG 0x1000 +/* The sample has been refined. */ +#define JPC_REFINE 0x2000 +/* This sample has been processed during the significance pass. */ +#define JPC_VISIT 0x4000 + +/* The number of aggregation contexts. */ +#define JPC_NUMAGGCTXS 1 +/* The number of zero coding contexts. */ +#define JPC_NUMZCCTXS 9 +/* The number of magnitude contexts. */ +#define JPC_NUMMAGCTXS 3 +/* The number of sign coding contexts. */ +#define JPC_NUMSCCTXS 5 +/* The number of uniform contexts. */ +#define JPC_NUMUCTXS 1 + +/* The context ID for the first aggregation context. */ +#define JPC_AGGCTXNO 0 +/* The context ID for the first zero coding context. */ +#define JPC_ZCCTXNO (JPC_AGGCTXNO + JPC_NUMAGGCTXS) +/* The context ID for the first magnitude context. */ +#define JPC_MAGCTXNO (JPC_ZCCTXNO + JPC_NUMZCCTXS) +/* The context ID for the first sign coding context. */ +#define JPC_SCCTXNO (JPC_MAGCTXNO + JPC_NUMMAGCTXS) +/* The context ID for the first uniform context. */ +#define JPC_UCTXNO (JPC_SCCTXNO + JPC_NUMSCCTXS) +/* The total number of contexts. */ +#define JPC_NUMCTXS (JPC_UCTXNO + JPC_NUMUCTXS) + +/******************************************************************************\ +* External data. +\******************************************************************************/ + +/* These lookup tables are used by various macros/functions. */ +/* Do not access these lookup tables directly. */ +extern int jpc_zcctxnolut[]; +extern int jpc_spblut[]; +extern int jpc_scctxnolut[]; +extern int jpc_magctxnolut[]; +extern jpc_fix_t jpc_refnmsedec[]; +extern jpc_fix_t jpc_signmsedec[]; +extern jpc_fix_t jpc_refnmsedec0[]; +extern jpc_fix_t jpc_signmsedec0[]; + +/* The initial settings for the MQ contexts. */ +extern jpc_mqctx_t jpc_mqctxs[]; + +/******************************************************************************\ +* Functions and macros. +\******************************************************************************/ + +/* Initialize the MQ contexts. */ +void jpc_initctxs(jpc_mqctx_t *ctxs); + +/* Get the zero coding context. */ +int jpc_getzcctxno(int f, int orient); +#define JPC_GETZCCTXNO(f, orient) \ + (jpc_zcctxnolut[((orient) << 8) | ((f) & JPC_OTHSIGMSK)]) + +/* Get the sign prediction bit. */ +int jpc_getspb(int f); +#define JPC_GETSPB(f) \ + (jpc_spblut[((f) & (JPC_PRIMSIGMSK | JPC_SGNMSK)) >> 4]) + +/* Get the sign coding context. */ +int jpc_getscctxno(int f); +#define JPC_GETSCCTXNO(f) \ + (jpc_scctxnolut[((f) & (JPC_PRIMSIGMSK | JPC_SGNMSK)) >> 4]) + +/* Get the magnitude context. */ +int jpc_getmagctxno(int f); +#define JPC_GETMAGCTXNO(f) \ + (jpc_magctxnolut[((f) & JPC_OTHSIGMSK) | ((((f) & JPC_REFINE) != 0) << 11)]) + +/* Get the normalized MSE reduction for significance passes. */ +#define JPC_GETSIGNMSEDEC(x, bitpos) jpc_getsignmsedec_macro(x, bitpos) +jpc_fix_t jpc_getsignmsedec_func(jpc_fix_t x, int bitpos); +#define jpc_getsignmsedec_macro(x, bitpos) \ + ((bitpos > JPC_NMSEDEC_FRACBITS) ? jpc_signmsedec[JPC_ASR(x, bitpos - JPC_NMSEDEC_FRACBITS) & JAS_ONES(JPC_NMSEDEC_BITS)] : \ + (jpc_signmsedec0[JPC_ASR(x, bitpos - JPC_NMSEDEC_FRACBITS) & JAS_ONES(JPC_NMSEDEC_BITS)])) + +/* Get the normalized MSE reduction for refinement passes. */ +#define JPC_GETREFNMSEDEC(x, bitpos) jpc_getrefnmsedec_macro(x, bitpos) +jpc_fix_t jpc_refsignmsedec_func(jpc_fix_t x, int bitpos); +#define jpc_getrefnmsedec_macro(x, bitpos) \ + ((bitpos > JPC_NMSEDEC_FRACBITS) ? jpc_refnmsedec[JPC_ASR(x, bitpos - JPC_NMSEDEC_FRACBITS) & JAS_ONES(JPC_NMSEDEC_BITS)] : \ + (jpc_refnmsedec0[JPC_ASR(x, bitpos - JPC_NMSEDEC_FRACBITS) & JAS_ONES(JPC_NMSEDEC_BITS)])) + +/* Arithmetic shift right (with ability to shift left also). */ +#define JPC_ASR(x, n) \ + (((n) >= 0) ? ((x) >> (n)) : ((x) << (-(n)))) + +/* Update the per-sample state information. */ +#define JPC_UPDATEFLAGS4(fp, rowstep, s, vcausalflag) \ +{ \ + register jpc_fix_t *np = (fp) - (rowstep); \ + register jpc_fix_t *sp = (fp) + (rowstep); \ + if ((vcausalflag)) { \ + sp[-1] |= JPC_NESIG; \ + sp[1] |= JPC_NWSIG; \ + if (s) { \ + *sp |= JPC_NSIG | JPC_NSGN; \ + (fp)[-1] |= JPC_ESIG | JPC_ESGN; \ + (fp)[1] |= JPC_WSIG | JPC_WSGN; \ + } else { \ + *sp |= JPC_NSIG; \ + (fp)[-1] |= JPC_ESIG; \ + (fp)[1] |= JPC_WSIG; \ + } \ + } else { \ + np[-1] |= JPC_SESIG; \ + np[1] |= JPC_SWSIG; \ + sp[-1] |= JPC_NESIG; \ + sp[1] |= JPC_NWSIG; \ + if (s) { \ + *np |= JPC_SSIG | JPC_SSGN; \ + *sp |= JPC_NSIG | JPC_NSGN; \ + (fp)[-1] |= JPC_ESIG | JPC_ESGN; \ + (fp)[1] |= JPC_WSIG | JPC_WSGN; \ + } else { \ + *np |= JPC_SSIG; \ + *sp |= JPC_NSIG; \ + (fp)[-1] |= JPC_ESIG; \ + (fp)[1] |= JPC_WSIG; \ + } \ + } \ +} + +/* Initialize the lookup tables used by the codec. */ +void jpc_initluts(void); + +/* Get the nominal gain associated with a particular band. */ +int JPC_NOMINALGAIN(int qmfbid, int numlvls, int lvlno, int orient); + +/* Get the coding pass type. */ +int JPC_PASSTYPE(int passno); + +/* Get the segment type. */ +int JPC_SEGTYPE(int passno, int firstpassno, int bypass); + +/* Get the number of coding passess in the segment. */ +int JPC_SEGPASSCNT(int passno, int firstpassno, int numpasses, int bypass, + int termall); + +/* Is the coding pass terminated? */ +int JPC_ISTERMINATED(int passno, int firstpassno, int numpasses, int termall, + int lazy); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,922 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 1 Decoder + * + * $Id: jpc_t1dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_fix.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_math.h" + +#include "jpc_bs.h" +#include "jpc_mqdec.h" +#include "jpc_t1dec.h" +#include "jpc_t1cod.h" +#include "jpc_dec.h" + +/******************************************************************************\ +* +\******************************************************************************/ + +static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band, + jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs); +static int dec_sigpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient, + int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data); +static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, + int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data); +static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag, + jas_matrix_t *flags, jas_matrix_t *data); +static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, + int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data); +static int dec_clnpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient, + int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data); + +#if defined(DEBUG) +static long t1dec_cnt = 0; +#endif + +#if !defined(DEBUG) +#define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \ + ((v) = jpc_mqdec_getbit(mqdec)) +#else +#define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \ +{ \ + (v) = jpc_mqdec_getbit(mqdec); \ + if (jas_getdbglevel() >= 100) { \ + jas_eprintf("index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \ + ++t1dec_cnt; \ + } \ +} +#endif +#define JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \ + JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) + +#if !defined(DEBUG) +#define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \ + ((v) = jpc_bitstream_getbit(bitstream)) +#else +#define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \ +{ \ + (v) = jpc_bitstream_getbit(bitstream); \ + if (jas_getdbglevel() >= 100) { \ + jas_eprintf("index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \ + ++t1dec_cnt; \ + } \ +} +#endif + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile) +{ + jpc_dec_tcomp_t *tcomp; + int compcnt; + jpc_dec_rlvl_t *rlvl; + int rlvlcnt; + jpc_dec_band_t *band; + int bandcnt; + jpc_dec_prc_t *prc; + int prccnt; + jpc_dec_cblk_t *cblk; + int cblkcnt; + + for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0; + --compcnt, ++tcomp) { + for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls; + rlvlcnt > 0; --rlvlcnt, ++rlvl) { + if (!rlvl->bands) { + continue; + } + for (bandcnt = rlvl->numbands, band = rlvl->bands; + bandcnt > 0; --bandcnt, ++band) { + if (!band->data) { + continue; + } + for (prccnt = rlvl->numprcs, prc = band->prcs; + prccnt > 0; --prccnt, ++prc) { + if (!prc->cblks) { + continue; + } + for (cblkcnt = prc->numcblks, + cblk = prc->cblks; cblkcnt > 0; + --cblkcnt, ++cblk) { + if (jpc_dec_decodecblk(dec, tile, tcomp, + band, cblk, 1, JPC_MAXLYRS)) { + return -1; + } + } + } + + } + } + } + + return 0; +} + +static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band, + jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs) +{ + jpc_dec_seg_t *seg; + int i; + int bpno; + int passtype; + int ret; + int compno; + int filldata; + int fillmask; + jpc_dec_ccp_t *ccp; + + compno = tcomp - tile->tcomps; + + if (!cblk->flags) { + /* Note: matrix is assumed to be zeroed */ + if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + + 2, jas_matrix_numcols(cblk->data) + 2))) { + return -1; + } + } + + seg = cblk->segs.head; + while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 || + seg->lyrno < maxlyrs)) { + assert(seg->numpasses >= seg->maxpasses || dopartial); + assert(seg->stream); + jas_stream_rewind(seg->stream); + jas_stream_setrwcount(seg->stream, 0); + if (seg->type == JPC_SEG_MQ) { + if (!cblk->mqdec) { + if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) { + return -1; + } + jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs); + } + jpc_mqdec_setinput(cblk->mqdec, seg->stream); + jpc_mqdec_init(cblk->mqdec); + } else { + assert(seg->type == JPC_SEG_RAW); + if (!cblk->nulldec) { + if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) { + assert(0); + } + } + } + + + for (i = 0; i < seg->numpasses; ++i) { + if (cblk->numimsbs > band->numbps) { + ccp = &tile->cp->ccps[compno]; + if (ccp->roishift <= 0) { + jas_eprintf("warning: corrupt code stream\n"); + } else { + if (cblk->numimsbs < ccp->roishift - band->numbps) { + jas_eprintf("warning: corrupt code stream\n"); + } + } + } + bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs + + (seg->passno + i - cblk->firstpassno + 2) / 3); +if (bpno < 0) { + goto premature_exit; +} +#if 1 + passtype = (seg->passno + i + 2) % 3; +#else + passtype = JPC_PASSTYPE(seg->passno + i + 2); +#endif + assert(bpno >= 0 && bpno < 31); + switch (passtype) { + case JPC_SIGPASS: + ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec, + cblk->mqdec, bpno, band->orient, + (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0, + cblk->flags, cblk->data) : + dec_rawsigpass(dec, cblk->nulldec, bpno, + (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0, + cblk->flags, cblk->data); + break; + case JPC_REFPASS: + ret = (seg->type == JPC_SEG_MQ) ? + dec_refpass(dec, cblk->mqdec, bpno, + (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0, + cblk->flags, cblk->data) : + dec_rawrefpass(dec, cblk->nulldec, bpno, + (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0, + cblk->flags, cblk->data); + break; + case JPC_CLNPASS: + assert(seg->type == JPC_SEG_MQ); + ret = dec_clnpass(dec, cblk->mqdec, bpno, + band->orient, (tile->cp->ccps[compno].cblkctx & + JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx & + JPC_COX_SEGSYM) != 0, cblk->flags, + cblk->data); + break; + default: + ret = -1; + break; + } + /* Do we need to reset after each coding pass? */ + if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) { + jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs); + } + + if (ret) { + jas_eprintf("coding pass failed passtype=%d segtype=%d\n", passtype, seg->type); + return -1; + } + + } + + if (seg->type == JPC_SEG_MQ) { +/* Note: dont destroy mq decoder because context info will be lost */ + } else { + assert(seg->type == JPC_SEG_RAW); + if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) { + fillmask = 0x7f; + filldata = 0x2a; + } else { + fillmask = 0; + filldata = 0; + } + if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask, + filldata)) < 0) { + return -1; + } else if (ret > 0) { + jas_eprintf("warning: bad termination pattern detected\n"); + } + jpc_bitstream_close(cblk->nulldec); + cblk->nulldec = 0; + } + + cblk->curseg = seg->next; + jpc_seglist_remove(&cblk->segs, seg); + jpc_seg_destroy(seg); + seg = cblk->curseg; + } + + assert(dopartial ? (!cblk->curseg) : 1); + +premature_exit: + return 0; +} + +/******************************************************************************\ +* Code for significance pass. +\******************************************************************************/ + +#define jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \ +{ \ + int f; \ + int v; \ + f = *(fp); \ + if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ + jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \ + JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \ + if (v) { \ + jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \ + JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \ + v ^= JPC_GETSPB(f); \ + JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \ + *(fp) |= JPC_SIG; \ + *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \ + } \ + *(fp) |= JPC_VISIT; \ + } \ +} + +static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient, + int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data) +{ + int i; + int j; + int one; + int half; + int oneplushalf; + int vscanlen; + int width; + int height; + jpc_fix_t *fp; + int frowstep; + int fstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dp; + int drowstep; + int dstripestep; + jpc_fix_t *dstripestart; + jpc_fix_t *dvscanstart; + int k; + + /* Avoid compiler warning about unused parameters. */ + dec = 0; + + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << bitpos; + half = one >> 1; + oneplushalf = one | half; + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + /* Process first sample in vertical scan. */ + jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, + orient, mqdec, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process second sample in vertical scan. */ + jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, + orient, mqdec, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process third sample in vertical scan. */ + jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, + orient, mqdec, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process fourth sample in vertical scan. */ + jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, + orient, mqdec, 0); + } + } + return 0; +} + +#define jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \ +{ \ + jpc_fix_t f = *(fp); \ + jpc_fix_t v; \ + if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ + JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \ + if (v < 0) { \ + return -1; \ + } \ + if (v) { \ + JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \ + if (v < 0) { \ + return -1; \ + } \ + JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \ + *(fp) |= JPC_SIG; \ + *(dp) = v ? (-oneplushalf) : (oneplushalf); \ + } \ + *(fp) |= JPC_VISIT; \ + } \ +} + +static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag, + jas_matrix_t *flags, jas_matrix_t *data) +{ + int i; + int j; + int k; + int one; + int half; + int oneplushalf; + int vscanlen; + int width; + int height; + jpc_fix_t *fp; + int frowstep; + int fstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dp; + int drowstep; + int dstripestep; + jpc_fix_t *dstripestart; + jpc_fix_t *dvscanstart; + + /* Avoid compiler warning about unused parameters. */ + dec = 0; + + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << bitpos; + half = one >> 1; + oneplushalf = one | half; + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + /* Process first sample in vertical scan. */ + jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, + in, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process second sample in vertical scan. */ + jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, + in, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process third sample in vertical scan. */ + jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, + in, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process fourth sample in vertical scan. */ + jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, + in, 0); + + } + } + return 0; +} + +/******************************************************************************\ +* Code for refinement pass. +\******************************************************************************/ + +#define jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \ +{ \ + int v; \ + int t; \ + if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ + jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \ + JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \ + t = (v ? (poshalf) : (neghalf)); \ + *(dp) += (*(dp) < 0) ? (-t) : t; \ + *(fp) |= JPC_REFINE; \ + } \ +} + +static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, + int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data) +{ + int i; + int j; + int vscanlen; + int width; + int height; + int one; + int poshalf; + int neghalf; + jpc_fix_t *fp; + int frowstep; + int fstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dp; + int drowstep; + int dstripestep; + jpc_fix_t *dstripestart; + jpc_fix_t *dvscanstart; + int k; + + /* Avoid compiler warning about unused parameters. */ + dec = 0; + vcausalflag = 0; + + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << bitpos; + poshalf = one >> 1; + neghalf = (bitpos > 0) ? (-poshalf) : (-1); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + /* Process first sample in vertical scan. */ + jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, + vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process second sample in vertical scan. */ + jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process third sample in vertical scan. */ + jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process fourth sample in vertical scan. */ + jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0); + } + } + + return 0; +} + +#define jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \ +{ \ + jpc_fix_t v; \ + jpc_fix_t t; \ + if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ + JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \ + if (v < 0) { \ + return -1; \ + } \ + t = (v ? poshalf : neghalf); \ + *(dp) += (*(dp) < 0) ? (-t) : t; \ + *(fp) |= JPC_REFINE; \ + } \ +} + +static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag, + jas_matrix_t *flags, jas_matrix_t *data) +{ + int i; + int j; + int k; + int vscanlen; + int width; + int height; + int one; + int poshalf; + int neghalf; + jpc_fix_t *fp; + int frowstep; + int fstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dp; + int drowstep; + int dstripestep; + jpc_fix_t *dstripestart; + jpc_fix_t *dvscanstart; + + /* Avoid compiler warning about unused parameters. */ + dec = 0; + vcausalflag = 0; + + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << bitpos; + poshalf = one >> 1; + neghalf = (bitpos > 0) ? (-poshalf) : (-1); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + /* Process first sample in vertical scan. */ + jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, + vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process second sample in vertical scan. */ + jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process third sample in vertical scan. */ + jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process fourth sample in vertical scan. */ + jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0); + } + } + return 0; +} + +/******************************************************************************\ +* Code for cleanup pass. +\******************************************************************************/ + +#define jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \ +{ \ + int v; \ +flabel \ + if (!((f) & (JPC_SIG | JPC_VISIT))) { \ + jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \ + JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \ + if (v) { \ +plabel \ + /* Coefficient is significant. */ \ + jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \ + JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \ + v ^= JPC_GETSPB(f); \ + *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \ + JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \ + *(fp) |= JPC_SIG; \ + } \ + } \ + /* XXX - Is this correct? Can aggregation cause some VISIT bits not to be reset? Check. */ \ + *(fp) &= ~JPC_VISIT; \ +} + +static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient, + int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data) +{ + int i; + int j; + int k; + int vscanlen; + int v; + int half; + int runlen; + int f; + int width; + int height; + int one; + int oneplushalf; + + jpc_fix_t *fp; + int frowstep; + int fstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *fvscanstart; + + jpc_fix_t *dp; + int drowstep; + int dstripestep; + jpc_fix_t *dstripestart; + jpc_fix_t *dvscanstart; + + /* Avoid compiler warning about unused parameters. */ + dec = 0; + + one = 1 << bitpos; + half = one >> 1; + oneplushalf = one | half; + + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = 0; i < height; i += 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(4, height - i); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT | + JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG | + JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & + (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, + !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) { + + jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO); + JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG"); + if (!v) { + continue; + } + jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO); + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL"); + runlen = v; + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL"); + runlen = (runlen << 1) | v; + f = *(fp = fvscanstart + frowstep * runlen); + dp = dvscanstart + drowstep * runlen; + k = vscanlen - runlen; + switch (runlen) { + case 0: + goto clnpass_partial0; + break; + case 1: + goto clnpass_partial1; + break; + case 2: + goto clnpass_partial2; + break; + case 3: + goto clnpass_partial3; + break; + } + } else { + f = *(fp = fvscanstart); + dp = dvscanstart; + k = vscanlen; + goto clnpass_full0; + } + + /* Process first sample in vertical scan. */ + jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, + mqdec, clnpass_full0:, clnpass_partial0:, + vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process second sample in vertical scan. */ + f = *fp; + jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, + mqdec, ;, clnpass_partial1:, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process third sample in vertical scan. */ + f = *fp; + jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, + mqdec, ;, clnpass_partial2:, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + /* Process fourth sample in vertical scan. */ + f = *fp; + jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, + mqdec, ;, clnpass_partial3:, 0); + } + } + + if (segsymflag) { + int segsymval; + segsymval = 0; + jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO); + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM"); + segsymval = (segsymval << 1) | (v & 1); + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM"); + segsymval = (segsymval << 1) | (v & 1); + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM"); + segsymval = (segsymval << 1) | (v & 1); + JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM"); + segsymval = (segsymval << 1) | (v & 1); + if (segsymval != 0xa) { + jas_eprintf("warning: bad segmentation symbol\n"); + } + } + + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1dec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 1 Decoder + * + * $Id: jpc_t1dec.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T1DEC_H +#define JPC_T1DEC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jpc_dec.h" +#include "jpc_mqdec.h" +#include "jpc_t1cod.h" + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Decode all of the code blocks for a particular tile. */ +int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,959 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 1 Encoder + * + * $Id: jpc_t1enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_fix.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +#include "jpc_t1enc.h" +#include "jpc_t1cod.h" +#include "jpc_enc.h" +#include "jpc_cod.h" +#include "jpc_math.h" + +static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int, + jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); + +static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int, jas_matrix_t *flags, + jas_matrix_t *data, int term, long *nmsedec); + +static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int, + int, jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); + +static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int, + jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); + +static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int, + jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); + +/******************************************************************************\ +* Code for encoding code blocks. +\******************************************************************************/ + +/* Encode all of the code blocks associated with the current tile. */ +int jpc_enc_enccblks(jpc_enc_t *enc) +{ + jpc_enc_tcmpt_t *tcmpt; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_rlvl_t *lvl; + jpc_enc_rlvl_t *endlvls; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + int i; + int j; + int mx; + int bmx; + int v; + jpc_enc_tile_t *tile; + uint_fast32_t prcno; + jpc_enc_prc_t *prc; + + tile = enc->curtile; + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (tcmpt = tile->tcmpts; tcmpt != endcomps; ++tcmpt) { + endlvls = &tcmpt->rlvls[tcmpt->numrlvls]; + for (lvl = tcmpt->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + bmx = 0; + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + mx = 0; + for (i = 0; i < jas_matrix_numrows(cblk->data); ++i) { + for (j = 0; j < jas_matrix_numcols(cblk->data); ++j) { + v = abs(jas_matrix_get(cblk->data, i, j)); + if (v > mx) { + mx = v; + } + } + } + if (mx > bmx) { + bmx = mx; + } + cblk->numbps = JAS_MAX(jpc_firstone(mx) + 1 - JPC_NUMEXTRABITS, 0); + } + + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + cblk->numimsbs = band->numbps - cblk->numbps; + assert(cblk->numimsbs >= 0); + } + + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + if (jpc_enc_enccblk(enc, cblk->stream, tcmpt, band, cblk)) { + return -1; + } + } + } + } + } + } + return 0; +} + +int getthebyte(jas_stream_t *in, long off) +{ + int c; + long oldpos; + oldpos = jas_stream_tell(in); + assert(oldpos >= 0); + jas_stream_seek(in, off, SEEK_SET); + c = jas_stream_peekc(in); + jas_stream_seek(in, oldpos, SEEK_SET); + return c; +} + +/* Encode a single code block. */ +int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk) +{ + jpc_enc_pass_t *pass; + jpc_enc_pass_t *endpasses; + int bitpos; + int n; + int adjust; + int ret; + int passtype; + int t; + jpc_bitstream_t *bout; + jpc_enc_pass_t *termpass; + jpc_enc_rlvl_t *rlvl; + int vcausal; + int segsym; + int termmode; + int c; + + bout = 0; + rlvl = band->rlvl; + + cblk->stream = jas_stream_memopen(0, 0); + assert(cblk->stream); + cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream); + assert(cblk->mqenc); + jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); + + cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0; + if (cblk->numpasses > 0) { + cblk->passes = jas_alloc2(cblk->numpasses, sizeof(jpc_enc_pass_t)); + assert(cblk->passes); + } else { + cblk->passes = 0; + } + endpasses = &cblk->passes[cblk->numpasses]; + for (pass = cblk->passes; pass != endpasses; ++pass) { + pass->start = 0; + pass->end = 0; + pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); + pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); + pass->lyrno = -1; +if (pass == endpasses - 1) { +assert(pass->term == 1); + pass->term = 1; +} + } + + cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2, + jas_matrix_numcols(cblk->data) + 2); + assert(cblk->flags); + + + bitpos = cblk->numbps - 1; + pass = cblk->passes; + n = cblk->numpasses; + while (--n >= 0) { + + if (pass->type == JPC_SEG_MQ) { + /* NOP */ + } else { + assert(pass->type == JPC_SEG_RAW); + if (!bout) { + bout = jpc_bitstream_sopen(cblk->stream, "w"); + assert(bout); + } + } + +#if 1 + passtype = (pass - cblk->passes + 2) % 3; +#else + passtype = JPC_PASSTYPE(pass - cblk->passes + 2); +#endif + pass->start = jas_stream_tell(cblk->stream); +#if 0 +assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); +#endif + assert(bitpos >= 0); + vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0; + segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0; + if (pass->term) { + termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ? + JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1; + } else { + termmode = 0; + } + switch (passtype) { + case JPC_SIGPASS: + ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc, + bitpos, band->orient, vcausal, cblk->flags, + cblk->data, termmode, &pass->nmsedec) : + jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags, + cblk->data, termmode, &pass->nmsedec); + break; + case JPC_REFPASS: + ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc, + bitpos, vcausal, cblk->flags, cblk->data, termmode, + &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos, + vcausal, cblk->flags, cblk->data, termmode, + &pass->nmsedec); + break; + case JPC_CLNPASS: + assert(pass->type == JPC_SEG_MQ); + ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient, + vcausal, segsym, cblk->flags, cblk->data, termmode, + &pass->nmsedec); + break; + default: + assert(0); + break; + } + + if (pass->type == JPC_SEG_MQ) { + if (pass->term) { + jpc_mqenc_init(cblk->mqenc); + } + jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate); + pass->end = jas_stream_tell(cblk->stream); + if (tcmpt->cblksty & JPC_COX_RESET) { + jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); + } + } else { + if (pass->term) { + if (jpc_bitstream_pending(bout)) { + jpc_bitstream_outalign(bout, 0x2a); + } + jpc_bitstream_close(bout); + bout = 0; + pass->end = jas_stream_tell(cblk->stream); + } else { + pass->end = jas_stream_tell(cblk->stream) + + jpc_bitstream_pending(bout); +/* NOTE - This will not work. need to adjust by # of pending output bytes */ + } + } +#if 0 +/* XXX - This assertion fails sometimes when various coding modes are used. +This seems to be harmless, but why does it happen at all? */ +assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); +#endif + + pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) * + jpc_fixtodbl(band->rlvl->tcmpt->synweight) * + jpc_fixtodbl(band->synweight) * + jpc_fixtodbl(band->synweight) * + jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) * + ((double) (1 << bitpos)) * ((double)(1 << bitpos)) * + jpc_fixtodbl(pass->nmsedec); + pass->cumwmsedec = pass->wmsedec; + if (pass != cblk->passes) { + pass->cumwmsedec += pass[-1].cumwmsedec; + } + if (passtype == JPC_CLNPASS) { + --bitpos; + } + ++pass; + } + +#if 0 +dump_passes(cblk->passes, cblk->numpasses, cblk); +#endif + + n = 0; + endpasses = &cblk->passes[cblk->numpasses]; + for (pass = cblk->passes; pass != endpasses; ++pass) { + if (pass->start < n) { + pass->start = n; + } + if (pass->end < n) { + pass->end = n; + } + if (!pass->term) { + termpass = pass; + while (termpass - pass < cblk->numpasses && + !termpass->term) { + ++termpass; + } + if (pass->type == JPC_SEG_MQ) { + t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0; + if (pass->mqencstate.ctreg >= 5) { + adjust = 4 + t; + } else { + adjust = 5 + t; + } + pass->end += adjust; + } + if (pass->end > termpass->end) { + pass->end = termpass->end; + } + if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) { + abort(); + } + if (c == 0xff) { + ++pass->end; + } + n = JAS_MAX(n, pass->end); + } else { + n = JAS_MAX(n, pass->end); + } + } + +#if 0 +dump_passes(cblk->passes, cblk->numpasses, cblk); +#endif + + if (bout) { + jpc_bitstream_close(bout); + } + + return 0; +} + +/******************************************************************************\ +* Code for significance pass. +\******************************************************************************/ + +#define sigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, orient, mqenc, vcausalflag) \ +{ \ + int f; \ + int v; \ + f = *(fp); \ + if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ + v = (abs(*(dp)) & (one)) ? 1 : 0; \ + jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \ + jpc_mqenc_putbit(mqenc, v); \ + if (v) { \ + *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ + v = ((*(dp) < 0) ? 1 : 0); \ + jpc_mqenc_setcurctx(mqenc, JPC_GETSCCTXNO(f)); \ + jpc_mqenc_putbit(mqenc, v ^ JPC_GETSPB(f)); \ + JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \ + *(fp) |= JPC_SIG; \ + } \ + *(fp) |= JPC_VISIT; \ + } \ +} + +static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, + jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec) +{ + int i; + int j; + int one; + int vscanlen; + int width; + int height; + int frowstep; + int drowstep; + int fstripestep; + int dstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *dstripestart; + jpc_fix_t *fp; + jpc_fix_t *dp; + jpc_fix_t *fvscanstart; + jpc_fix_t *dvscanstart; + int k; + + *nmsedec = 0; + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << (bitpos + JPC_NUMEXTRABITS); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + sigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, orient, mqenc, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + sigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, orient, mqenc, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + sigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, orient, mqenc, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + sigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, orient, mqenc, 0); + + } + } + + if (term) { + jpc_mqenc_flush(mqenc, term - 1); + } + + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} + +#define rawsigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, out, vcausalflag) \ +{ \ + jpc_fix_t f = *(fp); \ + jpc_fix_t v; \ + if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ + v = (abs(*(dp)) & (one)) ? 1 : 0; \ + if ((jpc_bitstream_putbit((out), v)) == EOF) { \ + return -1; \ + } \ + if (v) { \ + *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ + v = ((*(dp) < 0) ? 1 : 0); \ + if (jpc_bitstream_putbit(out, v) == EOF) { \ + return -1; \ + } \ + JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \ + *(fp) |= JPC_SIG; \ + } \ + *(fp) |= JPC_VISIT; \ + } \ +} + +static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags, + jas_matrix_t *data, int term, long *nmsedec) +{ + int i; + int j; + int k; + int one; + int vscanlen; + int width; + int height; + int frowstep; + int drowstep; + int fstripestep; + int dstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *dstripestart; + jpc_fix_t *fp; + jpc_fix_t *dp; + jpc_fix_t *fvscanstart; + jpc_fix_t *dvscanstart; + + *nmsedec = 0; + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << (bitpos + JPC_NUMEXTRABITS); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + rawsigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, out, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + rawsigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, out, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + rawsigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, out, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + rawsigpass_step(fp, frowstep, dp, bitpos, one, + nmsedec, out, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + + } + } + + if (term) { + jpc_bitstream_outalign(out, 0x2a); + } + + return 0; +} + +/******************************************************************************\ +* Code for refinement pass. +\******************************************************************************/ + +#define refpass_step(fp, dp, bitpos, one, nmsedec, mqenc, vcausalflag) \ +{ \ + int v; \ + if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ + (d) = *(dp); \ + *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \ + jpc_mqenc_setcurctx((mqenc), JPC_GETMAGCTXNO(*(fp))); \ + v = (abs(d) & (one)) ? 1 : 0; \ + jpc_mqenc_putbit((mqenc), v); \ + *(fp) |= JPC_REFINE; \ + } \ +} + +static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data, + int term, long *nmsedec) +{ + int i; + int j; + int one; + int vscanlen; + int d; + int width; + int height; + int frowstep; + int drowstep; + int fstripestep; + int dstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *dstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dvscanstart; + jpc_fix_t *dp; + jpc_fix_t *fp; +int k; + + *nmsedec = 0; + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << (bitpos + JPC_NUMEXTRABITS); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + refpass_step(fp, dp, bitpos, one, nmsedec, + mqenc, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + refpass_step(fp, dp, bitpos, one, nmsedec, + mqenc, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + refpass_step(fp, dp, bitpos, one, nmsedec, + mqenc, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + refpass_step(fp, dp, bitpos, one, nmsedec, + mqenc, 0); + + } + } + + if (term) { + jpc_mqenc_flush(mqenc, term - 1); + } + + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} + +#define rawrefpass_step(fp, dp, bitpos, one, nmsedec, out, vcausalflag) \ +{ \ + jpc_fix_t d; \ + jpc_fix_t v; \ + if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ + d = *(dp); \ + *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \ + v = (abs(d) & (one)) ? 1 : 0; \ + if (jpc_bitstream_putbit((out), v) == EOF) { \ + return -1; \ + } \ + *(fp) |= JPC_REFINE; \ + } \ +} + +static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags, + jas_matrix_t *data, int term, long *nmsedec) +{ + int i; + int j; + int k; + int one; + int vscanlen; + int width; + int height; + int frowstep; + int drowstep; + int fstripestep; + int dstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *dstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dvscanstart; + jpc_fix_t *dp; + jpc_fix_t *fp; + + *nmsedec = 0; + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << (bitpos + JPC_NUMEXTRABITS); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + + rawrefpass_step(fp, dp, bitpos, one, nmsedec, + out, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + rawrefpass_step(fp, dp, bitpos, one, nmsedec, + out, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + rawrefpass_step(fp, dp, bitpos, one, nmsedec, + out, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + rawrefpass_step(fp, dp, bitpos, one, nmsedec, + out, vcausalflag); + + } + } + + if (term) { + jpc_bitstream_outalign(out, 0x2a); + } + + return 0; +} + +/******************************************************************************\ +* Code for cleanup pass. +\******************************************************************************/ + +#define clnpass_step(fp, frowstep, dp, bitpos, one, orient, nmsedec, mqenc, label1, label2, vcausalflag) \ +{ \ + int f; \ + int v; \ +label1 \ + f = *(fp); \ + if (!(f & (JPC_SIG | JPC_VISIT))) { \ + jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \ + v = (abs(*(dp)) & (one)) ? 1 : 0; \ + jpc_mqenc_putbit((mqenc), v); \ + if (v) { \ +label2 \ + f = *(fp); \ + /* Coefficient is significant. */ \ + *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ + jpc_mqenc_setcurctx((mqenc), JPC_GETSCCTXNO(f)); \ + v = ((*(dp) < 0) ? 1 : 0); \ + jpc_mqenc_putbit((mqenc), v ^ JPC_GETSPB(f)); \ + JPC_UPDATEFLAGS4((fp), (frowstep), v, vcausalflag); \ + *(fp) |= JPC_SIG; \ + } \ + } \ + *(fp) &= ~JPC_VISIT; \ +} + +static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags, + jas_matrix_t *data, int term, long *nmsedec) +{ + int i; + int j; + int k; + int vscanlen; + int v; + int runlen; + jpc_fix_t *fp; + int width; + int height; + jpc_fix_t *dp; + int one; + int frowstep; + int drowstep; + int fstripestep; + int dstripestep; + jpc_fix_t *fstripestart; + jpc_fix_t *dstripestart; + jpc_fix_t *fvscanstart; + jpc_fix_t *dvscanstart; + + *nmsedec = 0; + width = jas_matrix_numcols(data); + height = jas_matrix_numrows(data); + frowstep = jas_matrix_rowstep(flags); + drowstep = jas_matrix_rowstep(data); + fstripestep = frowstep << 2; + dstripestep = drowstep << 2; + + one = 1 << (bitpos + JPC_NUMEXTRABITS); + + fstripestart = jas_matrix_getref(flags, 1, 1); + dstripestart = jas_matrix_getref(data, 0, 0); + for (i = height; i > 0; i -= 4, fstripestart += fstripestep, + dstripestart += dstripestep) { + fvscanstart = fstripestart; + dvscanstart = dstripestart; + vscanlen = JAS_MIN(i, 4); + for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { + + fp = fvscanstart; + if (vscanlen >= 4 && !((*fp) & (JPC_SIG | JPC_VISIT | + JPC_OTHSIGMSK)) && (fp += frowstep, !((*fp) & (JPC_SIG | + JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & + (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, + !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) { + dp = dvscanstart; + for (k = 0; k < vscanlen; ++k) { + v = (abs(*dp) & one) ? 1 : 0; + if (v) { + break; + } + dp += drowstep; + } + runlen = k; + if (runlen >= 4) { + jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO); + jpc_mqenc_putbit(mqenc, 0); + continue; + } + jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO); + jpc_mqenc_putbit(mqenc, 1); + jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO); + jpc_mqenc_putbit(mqenc, runlen >> 1); + jpc_mqenc_putbit(mqenc, runlen & 1); + fp = fvscanstart + frowstep * runlen; + dp = dvscanstart + drowstep * runlen; + k = vscanlen - runlen; + switch (runlen) { + case 0: + goto clnpass_partial0; + break; + case 1: + goto clnpass_partial1; + break; + case 2: + goto clnpass_partial2; + break; + case 3: + goto clnpass_partial3; + break; + } + } else { + runlen = 0; + fp = fvscanstart; + dp = dvscanstart; + k = vscanlen; + goto clnpass_full0; + } + clnpass_step(fp, frowstep, dp, bitpos, one, + orient, nmsedec, mqenc, clnpass_full0:, clnpass_partial0:, vcausalflag); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + clnpass_step(fp, frowstep, dp, bitpos, one, + orient, nmsedec, mqenc, ;, clnpass_partial1:, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + clnpass_step(fp, frowstep, dp, bitpos, one, + orient, nmsedec, mqenc, ;, clnpass_partial2:, 0); + if (--k <= 0) { + continue; + } + fp += frowstep; + dp += drowstep; + clnpass_step(fp, frowstep, dp, bitpos, one, + orient, nmsedec, mqenc, ;, clnpass_partial3:, 0); + } + } + + if (segsymflag) { + jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO); + jpc_mqenc_putbit(mqenc, 1); + jpc_mqenc_putbit(mqenc, 0); + jpc_mqenc_putbit(mqenc, 1); + jpc_mqenc_putbit(mqenc, 0); + } + + if (term) { + jpc_mqenc_flush(mqenc, term - 1); + } + + return jpc_mqenc_error(mqenc) ? (-1) : 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t1enc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 1 Encoder + * + * $Id: jpc_t1enc.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T1ENC_H +#define JPC_T1ENC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_seq.h" + +#include "jpc_enc.h" +#include "jpc_t1cod.h" + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Encode all of the code blocks. */ +int jpc_enc_enccblks(jpc_enc_t *enc); + +/* Encode a single code block. */ +int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *comp, + jpc_enc_band_t *band, jpc_enc_cblk_t *cblk); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,684 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier-2 Coding Library + * + * $Id: jpc_t2cod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#include "jasper/jas_math.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +#include "jpc_cs.h" +#include "jpc_t2cod.h" +#include "jpc_math.h" + +static int jpc_pi_nextlrcp(jpc_pi_t *pi); +static int jpc_pi_nextrlcp(jpc_pi_t *pi); +static int jpc_pi_nextrpcl(jpc_pi_t *pi); +static int jpc_pi_nextpcrl(jpc_pi_t *pi); +static int jpc_pi_nextcprl(jpc_pi_t *pi); + +int jpc_pi_next(jpc_pi_t *pi) +{ + jpc_pchg_t *pchg; + int ret; + + + for (;;) { + + pi->valid = false; + + if (!pi->pchg) { + ++pi->pchgno; + pi->compno = 0; + pi->rlvlno = 0; + pi->prcno = 0; + pi->lyrno = 0; + pi->prgvolfirst = true; + if (pi->pchgno < jpc_pchglist_numpchgs(pi->pchglist)) { + pi->pchg = jpc_pchglist_get(pi->pchglist, pi->pchgno); + } else if (pi->pchgno == jpc_pchglist_numpchgs(pi->pchglist)) { + pi->pchg = &pi->defaultpchg; + } else { + return 1; + } + } + + pchg = pi->pchg; + switch (pchg->prgord) { + case JPC_COD_LRCPPRG: + ret = jpc_pi_nextlrcp(pi); + break; + case JPC_COD_RLCPPRG: + ret = jpc_pi_nextrlcp(pi); + break; + case JPC_COD_RPCLPRG: + ret = jpc_pi_nextrpcl(pi); + break; + case JPC_COD_PCRLPRG: + ret = jpc_pi_nextpcrl(pi); + break; + case JPC_COD_CPRLPRG: + ret = jpc_pi_nextcprl(pi); + break; + default: + ret = -1; + break; + } + if (!ret) { + pi->valid = true; + ++pi->pktno; + return 0; + } + pi->pchg = 0; + } +} + +static int jpc_pi_nextlrcp(register jpc_pi_t *pi) +{ + jpc_pchg_t *pchg; + int *prclyrno; + + pchg = pi->pchg; + if (!pi->prgvolfirst) { + prclyrno = &pi->pirlvl->prclyrnos[pi->prcno]; + goto skip; + } else { + pi->prgvolfirst = false; + } + + for (pi->lyrno = 0; pi->lyrno < pi->numlyrs && pi->lyrno < + JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) { + for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pi->maxrlvls && + pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno) { + for (pi->compno = pchg->compnostart, pi->picomp = + &pi->picomps[pi->compno]; pi->compno < pi->numcomps + && pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, + ++pi->picomp) { + if (pi->rlvlno >= pi->picomp->numrlvls) { + continue; + } + pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno]; + for (pi->prcno = 0, prclyrno = + pi->pirlvl->prclyrnos; pi->prcno < + pi->pirlvl->numprcs; ++pi->prcno, + ++prclyrno) { + if (pi->lyrno >= *prclyrno) { + *prclyrno = pi->lyrno; + ++(*prclyrno); + return 0; + } +skip: + ; + } + } + } + } + return 1; +} + +static int jpc_pi_nextrlcp(register jpc_pi_t *pi) +{ + jpc_pchg_t *pchg; + int *prclyrno; + + pchg = pi->pchg; + if (!pi->prgvolfirst) { + assert(pi->prcno < pi->pirlvl->numprcs); + prclyrno = &pi->pirlvl->prclyrnos[pi->prcno]; + goto skip; + } else { + pi->prgvolfirst = 0; + } + + for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pi->maxrlvls && + pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno) { + for (pi->lyrno = 0; pi->lyrno < pi->numlyrs && pi->lyrno < + JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) { + for (pi->compno = pchg->compnostart, pi->picomp = + &pi->picomps[pi->compno]; pi->compno < pi->numcomps && + pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, ++pi->picomp) { + if (pi->rlvlno >= pi->picomp->numrlvls) { + continue; + } + pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno]; + for (pi->prcno = 0, prclyrno = pi->pirlvl->prclyrnos; + pi->prcno < pi->pirlvl->numprcs; ++pi->prcno, ++prclyrno) { + if (pi->lyrno >= *prclyrno) { + *prclyrno = pi->lyrno; + ++(*prclyrno); + return 0; + } +skip: + ; + } + } + } + } + return 1; +} + +static int jpc_pi_nextrpcl(register jpc_pi_t *pi) +{ + int rlvlno; + jpc_pirlvl_t *pirlvl; + jpc_pchg_t *pchg; + int prchind; + int prcvind; + int *prclyrno; + int compno; + jpc_picomp_t *picomp; + int xstep; + int ystep; + uint_fast32_t r; + uint_fast32_t rpx; + uint_fast32_t rpy; + uint_fast32_t trx0; + uint_fast32_t try0; + + pchg = pi->pchg; + if (!pi->prgvolfirst) { + goto skip; + } else { + pi->xstep = 0; + pi->ystep = 0; + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; + ++compno, ++picomp) { + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + xstep = picomp->hsamp * (1 << (pirlvl->prcwidthexpn + + picomp->numrlvls - rlvlno - 1)); + ystep = picomp->vsamp * (1 << (pirlvl->prcheightexpn + + picomp->numrlvls - rlvlno - 1)); + pi->xstep = (!pi->xstep) ? xstep : JAS_MIN(pi->xstep, xstep); + pi->ystep = (!pi->ystep) ? ystep : JAS_MIN(pi->ystep, ystep); + } + } + pi->prgvolfirst = 0; + } + + for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pchg->rlvlnoend && + pi->rlvlno < pi->maxrlvls; ++pi->rlvlno) { + for (pi->y = pi->ystart; pi->y < pi->yend; pi->y += + pi->ystep - (pi->y % pi->ystep)) { + for (pi->x = pi->xstart; pi->x < pi->xend; pi->x += + pi->xstep - (pi->x % pi->xstep)) { + for (pi->compno = pchg->compnostart, + pi->picomp = &pi->picomps[pi->compno]; + pi->compno < JAS_CAST(int, pchg->compnoend) && pi->compno < + pi->numcomps; ++pi->compno, ++pi->picomp) { + if (pi->rlvlno >= pi->picomp->numrlvls) { + continue; + } + pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno]; + if (pi->pirlvl->numprcs == 0) { + continue; + } + r = pi->picomp->numrlvls - 1 - pi->rlvlno; + rpx = r + pi->pirlvl->prcwidthexpn; + rpy = r + pi->pirlvl->prcheightexpn; + trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r); + try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r); + if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) + || !(pi->x % (1 << rpx))) && + ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) + || !(pi->y % (1 << rpy)))) { + prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp + << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0, + pi->pirlvl->prcwidthexpn); + prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp + << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0, + pi->pirlvl->prcheightexpn); + pi->prcno = prcvind * pi->pirlvl->numhprcs + prchind; + + assert(pi->prcno < pi->pirlvl->numprcs); + for (pi->lyrno = 0; pi->lyrno < + pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) { + prclyrno = &pi->pirlvl->prclyrnos[pi->prcno]; + if (pi->lyrno >= *prclyrno) { + ++(*prclyrno); + return 0; + } +skip: + ; + } + } + } + } + } + } + return 1; +} + +static int jpc_pi_nextpcrl(register jpc_pi_t *pi) +{ + int rlvlno; + jpc_pirlvl_t *pirlvl; + jpc_pchg_t *pchg; + int prchind; + int prcvind; + int *prclyrno; + int compno; + jpc_picomp_t *picomp; + int xstep; + int ystep; + uint_fast32_t trx0; + uint_fast32_t try0; + uint_fast32_t r; + uint_fast32_t rpx; + uint_fast32_t rpy; + + pchg = pi->pchg; + if (!pi->prgvolfirst) { + goto skip; + } else { + pi->xstep = 0; + pi->ystep = 0; + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; + ++compno, ++picomp) { + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + xstep = picomp->hsamp * (1 << + (pirlvl->prcwidthexpn + picomp->numrlvls - + rlvlno - 1)); + ystep = picomp->vsamp * (1 << + (pirlvl->prcheightexpn + picomp->numrlvls - + rlvlno - 1)); + pi->xstep = (!pi->xstep) ? xstep : + JAS_MIN(pi->xstep, xstep); + pi->ystep = (!pi->ystep) ? ystep : + JAS_MIN(pi->ystep, ystep); + } + } + pi->prgvolfirst = 0; + } + + for (pi->y = pi->ystart; pi->y < pi->yend; pi->y += pi->ystep - + (pi->y % pi->ystep)) { + for (pi->x = pi->xstart; pi->x < pi->xend; pi->x += pi->xstep - + (pi->x % pi->xstep)) { + for (pi->compno = pchg->compnostart, pi->picomp = + &pi->picomps[pi->compno]; pi->compno < pi->numcomps + && pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, + ++pi->picomp) { + for (pi->rlvlno = pchg->rlvlnostart, + pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno]; + pi->rlvlno < pi->picomp->numrlvls && + pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno, + ++pi->pirlvl) { + if (pi->pirlvl->numprcs == 0) { + continue; + } + r = pi->picomp->numrlvls - 1 - pi->rlvlno; + trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r); + try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r); + rpx = r + pi->pirlvl->prcwidthexpn; + rpy = r + pi->pirlvl->prcheightexpn; + if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) || + !(pi->x % (pi->picomp->hsamp << rpx))) && + ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) || + !(pi->y % (pi->picomp->vsamp << rpy)))) { + prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp + << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0, + pi->pirlvl->prcwidthexpn); + prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp + << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0, + pi->pirlvl->prcheightexpn); + pi->prcno = prcvind * pi->pirlvl->numhprcs + prchind; + assert(pi->prcno < pi->pirlvl->numprcs); + for (pi->lyrno = 0; pi->lyrno < pi->numlyrs && + pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) { + prclyrno = &pi->pirlvl->prclyrnos[pi->prcno]; + if (pi->lyrno >= *prclyrno) { + ++(*prclyrno); + return 0; + } +skip: + ; + } + } + } + } + } + } + return 1; +} + +static int jpc_pi_nextcprl(register jpc_pi_t *pi) +{ + int rlvlno; + jpc_pirlvl_t *pirlvl; + jpc_pchg_t *pchg; + int prchind; + int prcvind; + int *prclyrno; + uint_fast32_t trx0; + uint_fast32_t try0; + uint_fast32_t r; + uint_fast32_t rpx; + uint_fast32_t rpy; + + pchg = pi->pchg; + if (!pi->prgvolfirst) { + goto skip; + } else { + pi->prgvolfirst = 0; + } + + for (pi->compno = pchg->compnostart, pi->picomp = + &pi->picomps[pi->compno]; pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, + ++pi->picomp) { + pirlvl = pi->picomp->pirlvls; + pi->xstep = pi->picomp->hsamp * (1 << (pirlvl->prcwidthexpn + + pi->picomp->numrlvls - 1)); + pi->ystep = pi->picomp->vsamp * (1 << (pirlvl->prcheightexpn + + pi->picomp->numrlvls - 1)); + for (rlvlno = 1, pirlvl = &pi->picomp->pirlvls[1]; + rlvlno < pi->picomp->numrlvls; ++rlvlno, ++pirlvl) { + pi->xstep = JAS_MIN(pi->xstep, pi->picomp->hsamp * (1 << + (pirlvl->prcwidthexpn + pi->picomp->numrlvls - + rlvlno - 1))); + pi->ystep = JAS_MIN(pi->ystep, pi->picomp->vsamp * (1 << + (pirlvl->prcheightexpn + pi->picomp->numrlvls - + rlvlno - 1))); + } + for (pi->y = pi->ystart; pi->y < pi->yend; + pi->y += pi->ystep - (pi->y % pi->ystep)) { + for (pi->x = pi->xstart; pi->x < pi->xend; + pi->x += pi->xstep - (pi->x % pi->xstep)) { + for (pi->rlvlno = pchg->rlvlnostart, + pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno]; + pi->rlvlno < pi->picomp->numrlvls && pi->rlvlno < + pchg->rlvlnoend; ++pi->rlvlno, ++pi->pirlvl) { + if (pi->pirlvl->numprcs == 0) { + continue; + } + r = pi->picomp->numrlvls - 1 - pi->rlvlno; + trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r); + try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r); + rpx = r + pi->pirlvl->prcwidthexpn; + rpy = r + pi->pirlvl->prcheightexpn; + if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) || + !(pi->x % (pi->picomp->hsamp << rpx))) && + ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) || + !(pi->y % (pi->picomp->vsamp << rpy)))) { + prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp + << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0, + pi->pirlvl->prcwidthexpn); + prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp + << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0, + pi->pirlvl->prcheightexpn); + pi->prcno = prcvind * + pi->pirlvl->numhprcs + + prchind; + assert(pi->prcno < + pi->pirlvl->numprcs); + for (pi->lyrno = 0; pi->lyrno < + pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) { + prclyrno = &pi->pirlvl->prclyrnos[pi->prcno]; + if (pi->lyrno >= *prclyrno) { + ++(*prclyrno); + return 0; + } +skip: + ; + } + } + } + } + } + } + return 1; +} + +static void pirlvl_destroy(jpc_pirlvl_t *rlvl) +{ + if (rlvl->prclyrnos) { + jas_free(rlvl->prclyrnos); + } +} + +static void jpc_picomp_destroy(jpc_picomp_t *picomp) +{ + int rlvlno; + jpc_pirlvl_t *pirlvl; + if (picomp->pirlvls) { + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + pirlvl_destroy(pirlvl); + } + jas_free(picomp->pirlvls); + } +} + +void jpc_pi_destroy(jpc_pi_t *pi) +{ + jpc_picomp_t *picomp; + int compno; + if (pi->picomps) { + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; + ++compno, ++picomp) { + jpc_picomp_destroy(picomp); + } + jas_free(pi->picomps); + } + if (pi->pchglist) { + jpc_pchglist_destroy(pi->pchglist); + } + jas_free(pi); +} + +jpc_pi_t *jpc_pi_create0() +{ + jpc_pi_t *pi; + if (!(pi = jas_malloc(sizeof(jpc_pi_t)))) { + return 0; + } + pi->picomps = 0; + pi->pchgno = 0; + if (!(pi->pchglist = jpc_pchglist_create())) { + jas_free(pi); + return 0; + } + return pi; +} + +int jpc_pi_addpchg(jpc_pi_t *pi, jpc_pocpchg_t *pchg) +{ + return jpc_pchglist_insert(pi->pchglist, -1, pchg); +} + +jpc_pchglist_t *jpc_pchglist_create() +{ + jpc_pchglist_t *pchglist; + if (!(pchglist = jas_malloc(sizeof(jpc_pchglist_t)))) { + return 0; + } + pchglist->numpchgs = 0; + pchglist->maxpchgs = 0; + pchglist->pchgs = 0; + return pchglist; +} + +int jpc_pchglist_insert(jpc_pchglist_t *pchglist, int pchgno, jpc_pchg_t *pchg) +{ + int i; + int newmaxpchgs; + jpc_pchg_t **newpchgs; + if (pchgno < 0) { + pchgno = pchglist->numpchgs; + } + if (pchglist->numpchgs >= pchglist->maxpchgs) { + newmaxpchgs = pchglist->maxpchgs + 128; + if (!(newpchgs = jas_realloc2(pchglist->pchgs, newmaxpchgs, sizeof(jpc_pchg_t *)))) { + return -1; + } + pchglist->maxpchgs = newmaxpchgs; + pchglist->pchgs = newpchgs; + } + for (i = pchglist->numpchgs; i > pchgno; --i) { + pchglist->pchgs[i] = pchglist->pchgs[i - 1]; + } + pchglist->pchgs[pchgno] = pchg; + ++pchglist->numpchgs; + return 0; +} + +jpc_pchg_t *jpc_pchglist_remove(jpc_pchglist_t *pchglist, int pchgno) +{ + int i; + jpc_pchg_t *pchg; + assert(pchgno < pchglist->numpchgs); + pchg = pchglist->pchgs[pchgno]; + for (i = pchgno + 1; i < pchglist->numpchgs; ++i) { + pchglist->pchgs[i - 1] = pchglist->pchgs[i]; + } + --pchglist->numpchgs; + return pchg; +} + +jpc_pchg_t *jpc_pchg_copy(jpc_pchg_t *pchg) +{ + jpc_pchg_t *newpchg; + if (!(newpchg = jas_malloc(sizeof(jpc_pchg_t)))) { + return 0; + } + *newpchg = *pchg; + return newpchg; +} + +jpc_pchglist_t *jpc_pchglist_copy(jpc_pchglist_t *pchglist) +{ + jpc_pchglist_t *newpchglist; + jpc_pchg_t *newpchg; + int pchgno; + if (!(newpchglist = jpc_pchglist_create())) { + return 0; + } + for (pchgno = 0; pchgno < pchglist->numpchgs; ++pchgno) { + if (!(newpchg = jpc_pchg_copy(pchglist->pchgs[pchgno])) || + jpc_pchglist_insert(newpchglist, -1, newpchg)) { + jpc_pchglist_destroy(newpchglist); + return 0; + } + } + return newpchglist; +} + +void jpc_pchglist_destroy(jpc_pchglist_t *pchglist) +{ + int pchgno; + if (pchglist->pchgs) { + for (pchgno = 0; pchgno < pchglist->numpchgs; ++pchgno) { + jpc_pchg_destroy(pchglist->pchgs[pchgno]); + } + jas_free(pchglist->pchgs); + } + jas_free(pchglist); +} + +void jpc_pchg_destroy(jpc_pchg_t *pchg) +{ + jas_free(pchg); +} + +jpc_pchg_t *jpc_pchglist_get(jpc_pchglist_t *pchglist, int pchgno) +{ + return pchglist->pchgs[pchgno]; +} + +int jpc_pchglist_numpchgs(jpc_pchglist_t *pchglist) +{ + return pchglist->numpchgs; +} + +int jpc_pi_init(jpc_pi_t *pi) +{ + int compno; + int rlvlno; + int prcno; + jpc_picomp_t *picomp; + jpc_pirlvl_t *pirlvl; + int *prclyrno; + + pi->prgvolfirst = 0; + pi->valid = 0; + pi->pktno = -1; + pi->pchgno = -1; + pi->pchg = 0; + + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; + ++compno, ++picomp) { + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + for (prcno = 0, prclyrno = pirlvl->prclyrnos; + prcno < pirlvl->numprcs; ++prcno, ++prclyrno) { + *prclyrno = 0; + } + } + } + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2cod.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,299 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier-2 Coding Library + * + * $Id: jpc_t2cod.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T2COD_H +#define JPC_T2COD_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jpc_cs.h" + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +/* Progression change list. */ + +typedef struct { + + /* The number of progression changes. */ + int numpchgs; + + /* The maximum number of progression changes that can be accomodated + without growing the progression change array. */ + int maxpchgs; + + /* The progression changes. */ + jpc_pchg_t **pchgs; + +} jpc_pchglist_t; + +/* Packet iterator per-resolution-level information. */ + +typedef struct { + + /* The number of precincts. */ + int numprcs; + + /* The last layer processed for each precinct. */ + int *prclyrnos; + + /* The precinct width exponent. */ + int prcwidthexpn; + + /* The precinct height exponent. */ + int prcheightexpn; + + /* The number of precincts spanning the resolution level in the horizontal + direction. */ + int numhprcs; + +} jpc_pirlvl_t; + +/* Packet iterator per-component information. */ + +typedef struct { + + /* The number of resolution levels. */ + int numrlvls; + + /* The per-resolution-level information. */ + jpc_pirlvl_t *pirlvls; + + /* The horizontal sampling period. */ + int hsamp; + + /* The vertical sampling period. */ + int vsamp; + +} jpc_picomp_t; + +/* Packet iterator class. */ + +typedef struct { + + /* The number of layers. */ + int numlyrs; + + /* The number of resolution levels. */ + int maxrlvls; + + /* The number of components. */ + int numcomps; + + /* The per-component information. */ + jpc_picomp_t *picomps; + + /* The current component. */ + jpc_picomp_t *picomp; + + /* The current resolution level. */ + jpc_pirlvl_t *pirlvl; + + /* The number of the current component. */ + int compno; + + /* The number of the current resolution level. */ + int rlvlno; + + /* The number of the current precinct. */ + int prcno; + + /* The number of the current layer. */ + int lyrno; + + /* The x-coordinate of the current position. */ + int x; + + /* The y-coordinate of the current position. */ + int y; + + /* The horizontal step size. */ + int xstep; + + /* The vertical step size. */ + int ystep; + + /* The x-coordinate of the top-left corner of the tile on the reference + grid. */ + int xstart; + + /* The y-coordinate of the top-left corner of the tile on the reference + grid. */ + int ystart; + + /* The x-coordinate of the bottom-right corner of the tile on the + reference grid (plus one). */ + int xend; + + /* The y-coordinate of the bottom-right corner of the tile on the + reference grid (plus one). */ + int yend; + + /* The current progression change. */ + jpc_pchg_t *pchg; + + /* The progression change list. */ + jpc_pchglist_t *pchglist; + + /* The progression to use in the absense of explicit specification. */ + jpc_pchg_t defaultpchg; + + /* The current progression change number. */ + int pchgno; + + /* Is this the first time in the current progression volume? */ + bool prgvolfirst; + + /* Is the current iterator value valid? */ + bool valid; + + /* The current packet number. */ + int pktno; + +} jpc_pi_t; + +/******************************************************************************\ +* Functions/macros for packet iterators. +\******************************************************************************/ + +/* Create a packet iterator. */ +jpc_pi_t *jpc_pi_create0(void); + +/* Destroy a packet iterator. */ +void jpc_pi_destroy(jpc_pi_t *pi); + +/* Add a progression change to a packet iterator. */ +int jpc_pi_addpchg(jpc_pi_t *pi, jpc_pocpchg_t *pchg); + +/* Prepare a packet iterator for iteration. */ +int jpc_pi_init(jpc_pi_t *pi); + +/* Set the iterator to the first packet. */ +int jpc_pi_begin(jpc_pi_t *pi); + +/* Proceed to the next packet in sequence. */ +int jpc_pi_next(jpc_pi_t *pi); + +/* Get the index of the current packet. */ +#define jpc_pi_getind(pi) ((pi)->pktno) + +/* Get the component number of the current packet. */ +#define jpc_pi_cmptno(pi) (assert(pi->valid), (pi)->compno) + +/* Get the resolution level of the current packet. */ +#define jpc_pi_rlvlno(pi) (assert(pi->valid), (pi)->rlvlno) + +/* Get the layer number of the current packet. */ +#define jpc_pi_lyrno(pi) (assert(pi->valid), (pi)->lyrno) + +/* Get the precinct number of the current packet. */ +#define jpc_pi_prcno(pi) (assert(pi->valid), (pi)->prcno) + +/* Get the progression order for the current packet. */ +#define jpc_pi_prg(pi) (assert(pi->valid), (pi)->pchg->prgord) + +/******************************************************************************\ +* Functions/macros for progression change lists. +\******************************************************************************/ + +/* Create a progression change list. */ +jpc_pchglist_t *jpc_pchglist_create(void); + +/* Destroy a progression change list. */ +void jpc_pchglist_destroy(jpc_pchglist_t *pchglist); + +/* Insert a new element into a progression change list. */ +int jpc_pchglist_insert(jpc_pchglist_t *pchglist, int pchgno, jpc_pchg_t *pchg); + +/* Remove an element from a progression change list. */ +jpc_pchg_t *jpc_pchglist_remove(jpc_pchglist_t *pchglist, int pchgno); + +/* Get an element from a progression change list. */ +jpc_pchg_t *jpc_pchglist_get(jpc_pchglist_t *pchglist, int pchgno); + +/* Copy a progression change list. */ +jpc_pchglist_t *jpc_pchglist_copy(jpc_pchglist_t *pchglist); + +/* Get the number of elements in a progression change list. */ +int jpc_pchglist_numpchgs(jpc_pchglist_t *pchglist); + +/******************************************************************************\ +* Functions/macros for progression changes. +\******************************************************************************/ + +/* Destroy a progression change. */ +void jpc_pchg_destroy(jpc_pchg_t *pchg); + +/* Copy a progression change. */ +jpc_pchg_t *jpc_pchg_copy(jpc_pchg_t *pchg); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,581 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 2 Decoder + * + * $Id: jpc_t2dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_types.h" +#include "jasper/jas_fix.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_debug.h" + +#include "jpc_bs.h" +#include "jpc_dec.h" +#include "jpc_cs.h" +#include "jpc_mqdec.h" +#include "jpc_t2dec.h" +#include "jpc_t1cod.h" +#include "jpc_math.h" + +/******************************************************************************\ +* +\******************************************************************************/ + +long jpc_dec_lookahead(jas_stream_t *in); +static int jpc_getcommacode(jpc_bitstream_t *in); +static int jpc_getnumnewpasses(jpc_bitstream_t *in); +static int jpc_dec_decodepkt(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in, int compno, int lvlno, + int prcno, int lyrno); + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +static int jpc_getcommacode(jpc_bitstream_t *in) +{ + int n; + int v; + + n = 0; + for (;;) { + if ((v = jpc_bitstream_getbit(in)) < 0) { + return -1; + } + if (jpc_bitstream_eof(in)) { + return -1; + } + if (!v) { + break; + } + ++n; + } + + return n; +} + +static int jpc_getnumnewpasses(jpc_bitstream_t *in) +{ + int n; + + if ((n = jpc_bitstream_getbit(in)) > 0) { + if ((n = jpc_bitstream_getbit(in)) > 0) { + if ((n = jpc_bitstream_getbits(in, 2)) == 3) { + if ((n = jpc_bitstream_getbits(in, 5)) == 31) { + if ((n = jpc_bitstream_getbits(in, 7)) >= 0) { + n += 36 + 1; + } + } else if (n >= 0) { + n += 5 + 1; + } + } else if (n >= 0) { + n += 2 + 1; + } + } else if (!n) { + n += 2; + } + } else if (!n) { + ++n; + } + + return n; +} + +static int jpc_dec_decodepkt(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in, int compno, int rlvlno, + int prcno, int lyrno) +{ + jpc_bitstream_t *inb; + jpc_dec_tcomp_t *tcomp; + jpc_dec_rlvl_t *rlvl; + jpc_dec_band_t *band; + jpc_dec_cblk_t *cblk; + int n; + int m; + int i; + jpc_tagtreenode_t *leaf; + int included; + int ret; + int numnewpasses; + jpc_dec_seg_t *seg; + int len; + int present; + int savenumnewpasses; + int mycounter; + jpc_ms_t *ms; + jpc_dec_tile_t *tile; + jpc_dec_ccp_t *ccp; + jpc_dec_cp_t *cp; + int bandno; + jpc_dec_prc_t *prc; + int usedcblkcnt; + int cblkno; + uint_fast32_t bodylen; + bool discard; + int passno; + int maxpasses; + int hdrlen; + int hdroffstart; + int hdroffend; + + /* Avoid compiler warning about possible use of uninitialized + variable. */ + bodylen = 0; + + discard = (lyrno >= dec->maxlyrs); + + tile = dec->curtile; + cp = tile->cp; + ccp = &cp->ccps[compno]; + + /* + * Decode the packet header. + */ + + /* Decode the SOP marker segment if present. */ + if (cp->csty & JPC_COD_SOP) { + if (jpc_dec_lookahead(in) == JPC_MS_SOP) { + if (!(ms = jpc_getms(in, dec->cstate))) { + return -1; + } + if (jpc_ms_gettype(ms) != JPC_MS_SOP) { + jpc_ms_destroy(ms); + jas_eprintf("missing SOP marker segment\n"); + return -1; + } + jpc_ms_destroy(ms); + } + } + +hdroffstart = jas_stream_getrwcount(pkthdrstream); + + if (!(inb = jpc_bitstream_sopen(pkthdrstream, "r"))) { + return -1; + } + + if ((present = jpc_bitstream_getbit(inb)) < 0) { + return 1; + } + JAS_DBGLOG(10, ("\n", present)); + JAS_DBGLOG(10, ("present=%d ", present)); + + /* Is the packet non-empty? */ + if (present) { + /* The packet is non-empty. */ + tcomp = &tile->tcomps[compno]; + rlvl = &tcomp->rlvls[rlvlno]; + bodylen = 0; + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + if (!band->data) { + continue; + } + prc = &band->prcs[prcno]; + if (!prc->cblks) { + continue; + } + usedcblkcnt = 0; + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + ++usedcblkcnt; + if (!cblk->numpasses) { + leaf = jpc_tagtree_getleaf(prc->incltagtree, usedcblkcnt - 1); + if ((included = jpc_tagtree_decode(prc->incltagtree, leaf, lyrno + 1, inb)) < 0) { + return -1; + } + } else { + if ((included = jpc_bitstream_getbit(inb)) < 0) { + return -1; + } + } + JAS_DBGLOG(10, ("\n")); + JAS_DBGLOG(10, ("included=%d ", included)); + if (!included) { + continue; + } + if (!cblk->numpasses) { + i = 1; + leaf = jpc_tagtree_getleaf(prc->numimsbstagtree, usedcblkcnt - 1); + for (;;) { + if ((ret = jpc_tagtree_decode(prc->numimsbstagtree, leaf, i, inb)) < 0) { + return -1; + } + if (ret) { + break; + } + ++i; + } + cblk->numimsbs = i - 1; + cblk->firstpassno = cblk->numimsbs * 3; + } + if ((numnewpasses = jpc_getnumnewpasses(inb)) < 0) { + return -1; + } + JAS_DBGLOG(10, ("numnewpasses=%d ", numnewpasses)); + seg = cblk->curseg; + savenumnewpasses = numnewpasses; + mycounter = 0; + if (numnewpasses > 0) { + if ((m = jpc_getcommacode(inb)) < 0) { + return -1; + } + cblk->numlenbits += m; + JAS_DBGLOG(10, ("increment=%d ", m)); + while (numnewpasses > 0) { + passno = cblk->firstpassno + cblk->numpasses + mycounter; + /* XXX - the maxpasses is not set precisely but this doesn't matter... */ + maxpasses = JPC_SEGPASSCNT(passno, cblk->firstpassno, 10000, (ccp->cblkctx & JPC_COX_LAZY) != 0, (ccp->cblkctx & JPC_COX_TERMALL) != 0); + if (!discard && !seg) { + if (!(seg = jpc_seg_alloc())) { + return -1; + } + jpc_seglist_insert(&cblk->segs, cblk->segs.tail, seg); + if (!cblk->curseg) { + cblk->curseg = seg; + } + seg->passno = passno; + seg->type = JPC_SEGTYPE(seg->passno, cblk->firstpassno, (ccp->cblkctx & JPC_COX_LAZY) != 0); + seg->maxpasses = maxpasses; + } + n = JAS_MIN(numnewpasses, maxpasses); + mycounter += n; + numnewpasses -= n; + if ((len = jpc_bitstream_getbits(inb, cblk->numlenbits + jpc_floorlog2(n))) < 0) { + return -1; + } + JAS_DBGLOG(10, ("len=%d ", len)); + if (!discard) { + seg->lyrno = lyrno; + seg->numpasses += n; + seg->cnt = len; + seg = seg->next; + } + bodylen += len; + } + } + cblk->numpasses += savenumnewpasses; + } + } + + jpc_bitstream_inalign(inb, 0, 0); + + } else { + if (jpc_bitstream_inalign(inb, 0x7f, 0)) { + jas_eprintf("alignment failed\n"); + return -1; + } + } + jpc_bitstream_close(inb); + + hdroffend = jas_stream_getrwcount(pkthdrstream); + hdrlen = hdroffend - hdroffstart; + if (jas_getdbglevel() >= 5) { + jas_eprintf("hdrlen=%lu bodylen=%lu \n", (unsigned long) hdrlen, + (unsigned long) bodylen); + } + + if (cp->csty & JPC_COD_EPH) { + if (jpc_dec_lookahead(pkthdrstream) == JPC_MS_EPH) { + if (!(ms = jpc_getms(pkthdrstream, dec->cstate))) { + jas_eprintf("cannot get (EPH) marker segment\n"); + return -1; + } + if (jpc_ms_gettype(ms) != JPC_MS_EPH) { + jpc_ms_destroy(ms); + jas_eprintf("missing EPH marker segment\n"); + return -1; + } + jpc_ms_destroy(ms); + } + } + + /* decode the packet body. */ + + if (jas_getdbglevel() >= 1) { + jas_eprintf("packet body offset=%06ld\n", (long) jas_stream_getrwcount(in)); + } + + if (!discard) { + tcomp = &tile->tcomps[compno]; + rlvl = &tcomp->rlvls[rlvlno]; + for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; + ++bandno, ++band) { + if (!band->data) { + continue; + } + prc = &band->prcs[prcno]; + if (!prc->cblks) { + continue; + } + for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; + ++cblkno, ++cblk) { + seg = cblk->curseg; + while (seg) { + if (!seg->stream) { + if (!(seg->stream = jas_stream_memopen(0, 0))) { + return -1; + } + } +#if 0 +jas_eprintf("lyrno=%02d, compno=%02d, lvlno=%02d, prcno=%02d, bandno=%02d, cblkno=%02d, passno=%02d numpasses=%02d cnt=%d numbps=%d, numimsbs=%d\n", lyrno, compno, rlvlno, prcno, band - rlvl->bands, cblk - prc->cblks, seg->passno, seg->numpasses, seg->cnt, band->numbps, cblk->numimsbs); +#endif + if (seg->cnt > 0) { + if (jpc_getdata(in, seg->stream, seg->cnt) < 0) { + return -1; + } + seg->cnt = 0; + } + if (seg->numpasses >= seg->maxpasses) { + cblk->curseg = seg->next; + } + seg = seg->next; + } + } + } + } else { + if (jas_stream_gobble(in, bodylen) != JAS_CAST(int, bodylen)) { + return -1; + } + } + return 0; +} + +/********************************************************************************************/ +/********************************************************************************************/ + +int jpc_dec_decodepkts(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in) +{ + jpc_dec_tile_t *tile; + jpc_pi_t *pi; + int ret; + + tile = dec->curtile; + pi = tile->pi; + for (;;) { +if (!tile->pkthdrstream || jas_stream_peekc(tile->pkthdrstream) == EOF) { + switch (jpc_dec_lookahead(in)) { + case JPC_MS_EOC: + case JPC_MS_SOT: + return 0; + break; + case JPC_MS_SOP: + case JPC_MS_EPH: + case 0: + break; + default: + return -1; + break; + } +} + if ((ret = jpc_pi_next(pi))) { + return ret; + } +if (dec->maxpkts >= 0 && dec->numpkts >= dec->maxpkts) { + jas_eprintf("warning: stopping decode prematurely as requested\n"); + return 0; +} + if (jas_getdbglevel() >= 1) { + jas_eprintf("packet offset=%08ld prg=%d cmptno=%02d " + "rlvlno=%02d prcno=%03d lyrno=%02d\n", (long) + jas_stream_getrwcount(in), jpc_pi_prg(pi), jpc_pi_cmptno(pi), + jpc_pi_rlvlno(pi), jpc_pi_prcno(pi), jpc_pi_lyrno(pi)); + } + if (jpc_dec_decodepkt(dec, pkthdrstream, in, jpc_pi_cmptno(pi), jpc_pi_rlvlno(pi), + jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) { + return -1; + } +++dec->numpkts; + } + + return 0; +} + +jpc_pi_t *jpc_dec_pi_create(jpc_dec_t *dec, jpc_dec_tile_t *tile) +{ + jpc_pi_t *pi; + int compno; + jpc_picomp_t *picomp; + jpc_pirlvl_t *pirlvl; + jpc_dec_tcomp_t *tcomp; + int rlvlno; + jpc_dec_rlvl_t *rlvl; + int prcno; + int *prclyrno; + jpc_dec_cmpt_t *cmpt; + + if (!(pi = jpc_pi_create0())) { + return 0; + } + pi->numcomps = dec->numcomps; + if (!(pi->picomps = jas_alloc2(pi->numcomps, sizeof(jpc_picomp_t)))) { + jpc_pi_destroy(pi); + return 0; + } + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno, + ++picomp) { + picomp->pirlvls = 0; + } + + for (compno = 0, tcomp = tile->tcomps, picomp = pi->picomps; + compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { + picomp->numrlvls = tcomp->numrlvls; + if (!(picomp->pirlvls = jas_alloc2(picomp->numrlvls, + sizeof(jpc_pirlvl_t)))) { + jpc_pi_destroy(pi); + return 0; + } + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + pirlvl->prclyrnos = 0; + } + for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; + rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { +/* XXX sizeof(long) should be sizeof different type */ + pirlvl->numprcs = rlvl->numprcs; + if (!(pirlvl->prclyrnos = jas_alloc2(pirlvl->numprcs, + sizeof(long)))) { + jpc_pi_destroy(pi); + return 0; + } + } + } + + pi->maxrlvls = 0; + for (compno = 0, tcomp = tile->tcomps, picomp = pi->picomps, cmpt = + dec->cmpts; compno < pi->numcomps; ++compno, ++tcomp, ++picomp, + ++cmpt) { + picomp->hsamp = cmpt->hstep; + picomp->vsamp = cmpt->vstep; + for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; + rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { + pirlvl->prcwidthexpn = rlvl->prcwidthexpn; + pirlvl->prcheightexpn = rlvl->prcheightexpn; + for (prcno = 0, prclyrno = pirlvl->prclyrnos; + prcno < pirlvl->numprcs; ++prcno, ++prclyrno) { + *prclyrno = 0; + } + pirlvl->numhprcs = rlvl->numhprcs; + } + if (pi->maxrlvls < tcomp->numrlvls) { + pi->maxrlvls = tcomp->numrlvls; + } + } + + pi->numlyrs = tile->cp->numlyrs; + pi->xstart = tile->xstart; + pi->ystart = tile->ystart; + pi->xend = tile->xend; + pi->yend = tile->yend; + + pi->picomp = 0; + pi->pirlvl = 0; + pi->x = 0; + pi->y = 0; + pi->compno = 0; + pi->rlvlno = 0; + pi->prcno = 0; + pi->lyrno = 0; + pi->xstep = 0; + pi->ystep = 0; + + pi->pchgno = -1; + + pi->defaultpchg.prgord = tile->cp->prgord; + pi->defaultpchg.compnostart = 0; + pi->defaultpchg.compnoend = pi->numcomps; + pi->defaultpchg.rlvlnostart = 0; + pi->defaultpchg.rlvlnoend = pi->maxrlvls; + pi->defaultpchg.lyrnoend = pi->numlyrs; + pi->pchg = 0; + + pi->valid = 0; + + return pi; +} + +long jpc_dec_lookahead(jas_stream_t *in) +{ + uint_fast16_t x; + if (jpc_getuint16(in, &x)) { + return -1; + } + if (jas_stream_ungetc(in, x & 0xff) == EOF || + jas_stream_ungetc(in, x >> 8) == EOF) { + return -1; + } + if (x >= JPC_MS_INMIN /*&& x <= JPC_MS_INMAX*/) { + return x; + } + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2dec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 2 Decoder + * + * $Id: jpc_t2dec.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T2DEC_H +#define JPC_T2DEC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_fix.h" +#include "jasper/jas_stream.h" + +#include "jpc_bs.h" +#include "jpc_dec.h" +#include "jpc_mqdec.h" + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Decode the packets for a tile-part. */ +int jpc_dec_decodepkts(jpc_dec_t *dec, jas_stream_t *pkthdrstream, + jas_stream_t *in); + +/* Create a packet iterator for the decoder. */ +jpc_pi_t *jpc_dec_pi_create(jpc_dec_t *dec, jpc_dec_tile_t *tile); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,655 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 2 Encoder + * + * $Id: jpc_t2enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jasper/jas_fix.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" +#include "jasper/jas_debug.h" + +#include "jpc_flt.h" +#include "jpc_t2enc.h" +#include "jpc_t2cod.h" +#include "jpc_tagtree.h" +#include "jpc_enc.h" +#include "jpc_math.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +static int jpc_putcommacode(jpc_bitstream_t *out, int n) +{ + assert(n >= 0); + + while (--n >= 0) { + if (jpc_bitstream_putbit(out, 1) == EOF) { + return -1; + } + } + if (jpc_bitstream_putbit(out, 0) == EOF) { + return -1; + } + return 0; +} + +static int jpc_putnumnewpasses(jpc_bitstream_t *out, int n) +{ + int ret; + + if (n <= 0) { + return -1; + } else if (n == 1) { + ret = jpc_bitstream_putbit(out, 0); + } else if (n == 2) { + ret = jpc_bitstream_putbits(out, 2, 2); + } else if (n <= 5) { + ret = jpc_bitstream_putbits(out, 4, 0xc | (n - 3)); + } else if (n <= 36) { + ret = jpc_bitstream_putbits(out, 9, 0x1e0 | (n - 6)); + } else if (n <= 164) { + ret = jpc_bitstream_putbits(out, 16, 0xff80 | (n - 37)); + } else { + /* The standard has no provision for encoding a larger value. + In practice, however, it is highly unlikely that this + limitation will ever be encountered. */ + return -1; + } + + return (ret != EOF) ? 0 : (-1); +} + +int jpc_enc_encpkts(jpc_enc_t *enc, jas_stream_t *out) +{ + jpc_enc_tile_t *tile; + jpc_pi_t *pi; + + tile = enc->curtile; + + jpc_init_t2state(enc, 0); + pi = tile->pi; + jpc_pi_init(pi); + + if (!jpc_pi_next(pi)) { + for (;;) { + if (jpc_enc_encpkt(enc, out, jpc_pi_cmptno(pi), jpc_pi_rlvlno(pi), + jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) { + return -1; + } + if (jpc_pi_next(pi)) { + break; + } + } + } + + return 0; +} + +int jpc_enc_encpkt(jpc_enc_t *enc, jas_stream_t *out, int compno, int lvlno, int prcno, int lyrno) +{ + jpc_enc_tcmpt_t *comp; + jpc_enc_rlvl_t *lvl; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + jpc_bitstream_t *outb; + jpc_enc_pass_t *pass; + jpc_enc_pass_t *startpass; + jpc_enc_pass_t *lastpass; + jpc_enc_pass_t *endpass; + jpc_enc_pass_t *endpasses; + int i; + int included; + int ret; + jpc_tagtreenode_t *leaf; + int n; + int t1; + int t2; + int adjust; + int maxadjust; + int datalen; + int numnewpasses; + int passcount; + jpc_enc_tile_t *tile; + jpc_enc_prc_t *prc; + jpc_enc_cp_t *cp; + jpc_ms_t *ms; + + tile = enc->curtile; + cp = enc->cp; + + if (cp->tcp.csty & JPC_COD_SOP) { + if (!(ms = jpc_ms_create(JPC_MS_SOP))) { + return -1; + } + ms->parms.sop.seqno = jpc_pi_getind(tile->pi); + if (jpc_putms(out, enc->cstate, ms)) { + return -1; + } + jpc_ms_destroy(ms); + } + + outb = jpc_bitstream_sopen(out, "w+"); + assert(outb); + + if (jpc_bitstream_putbit(outb, 1) == EOF) { + return -1; + } + JAS_DBGLOG(10, ("\n")); + JAS_DBGLOG(10, ("present. ")); + + comp = &tile->tcmpts[compno]; + lvl = &comp->rlvls[lvlno]; + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + prc = &band->prcs[prcno]; + if (!prc->cblks) { + continue; + } + + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + if (!lyrno) { + leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks); + jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs); + } + pass = cblk->curpass; + included = (pass && pass->lyrno == lyrno); + if (included && (!cblk->numencpasses)) { + assert(pass->lyrno == lyrno); + leaf = jpc_tagtree_getleaf(prc->incltree, + cblk - prc->cblks); + jpc_tagtree_setvalue(prc->incltree, leaf, pass->lyrno); + } + } + + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + pass = cblk->curpass; + included = (pass && pass->lyrno == lyrno); + if (!cblk->numencpasses) { + leaf = jpc_tagtree_getleaf(prc->incltree, + cblk - prc->cblks); + if (jpc_tagtree_encode(prc->incltree, leaf, lyrno + + 1, outb) < 0) { + return -1; + } + } else { + if (jpc_bitstream_putbit(outb, included) == EOF) { + return -1; + } + } + JAS_DBGLOG(10, ("included=%d ", included)); + if (!included) { + continue; + } + if (!cblk->numencpasses) { + i = 1; + leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks); + for (;;) { + if ((ret = jpc_tagtree_encode(prc->nlibtree, leaf, i, outb)) < 0) { + return -1; + } + if (ret) { + break; + } + ++i; + } + assert(leaf->known_ && i == leaf->value_ + 1); + } + + endpasses = &cblk->passes[cblk->numpasses]; + startpass = pass; + endpass = startpass; + while (endpass != endpasses && endpass->lyrno == lyrno){ + ++endpass; + } + numnewpasses = endpass - startpass; + if (jpc_putnumnewpasses(outb, numnewpasses)) { + return -1; + } + JAS_DBGLOG(10, ("numnewpasses=%d ", numnewpasses)); + + lastpass = endpass - 1; + n = startpass->start; + passcount = 1; + maxadjust = 0; + for (pass = startpass; pass != endpass; ++pass) { + if (pass->term || pass == lastpass) { + datalen = pass->end - n; + t1 = jpc_firstone(datalen) + 1; + t2 = cblk->numlenbits + jpc_floorlog2(passcount); + adjust = JAS_MAX(t1 - t2, 0); + maxadjust = JAS_MAX(adjust, maxadjust); + n += datalen; + passcount = 1; + } else { + ++passcount; + } + } + if (jpc_putcommacode(outb, maxadjust)) { + return -1; + } + cblk->numlenbits += maxadjust; + + lastpass = endpass - 1; + n = startpass->start; + passcount = 1; + for (pass = startpass; pass != endpass; ++pass) { + if (pass->term || pass == lastpass) { + datalen = pass->end - n; +assert(jpc_firstone(datalen) < cblk->numlenbits + jpc_floorlog2(passcount)); + if (jpc_bitstream_putbits(outb, cblk->numlenbits + jpc_floorlog2(passcount), datalen) == EOF) { + return -1; + } + n += datalen; + passcount = 1; + } else { + ++passcount; + } + } + } + } + + jpc_bitstream_outalign(outb, 0); + jpc_bitstream_close(outb); + + if (cp->tcp.csty & JPC_COD_EPH) { + if (!(ms = jpc_ms_create(JPC_MS_EPH))) { + return -1; + } + jpc_putms(out, enc->cstate, ms); + jpc_ms_destroy(ms); + } + + comp = &tile->tcmpts[compno]; + lvl = &comp->rlvls[lvlno]; + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + prc = &band->prcs[prcno]; + if (!prc->cblks) { + continue; + } + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + pass = cblk->curpass; + + if (!pass) { + continue; + } + if (pass->lyrno != lyrno) { + assert(pass->lyrno < 0 || pass->lyrno > lyrno); + continue; + } + + endpasses = &cblk->passes[cblk->numpasses]; + startpass = pass; + endpass = startpass; + while (endpass != endpasses && endpass->lyrno == lyrno){ + ++endpass; + } + lastpass = endpass - 1; + numnewpasses = endpass - startpass; + + jas_stream_seek(cblk->stream, startpass->start, SEEK_SET); + assert(jas_stream_tell(cblk->stream) == startpass->start); + if (jas_stream_copy(out, cblk->stream, lastpass->end - startpass->start)) { + return -1; + } + cblk->curpass = (endpass != endpasses) ? endpass : 0; + cblk->numencpasses += numnewpasses; + + } + } + + return 0; +} + +void jpc_save_t2state(jpc_enc_t *enc) +{ +/* stream pos in embedded T1 stream may be wrong since not saved/restored! */ + + jpc_enc_tcmpt_t *comp; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_rlvl_t *lvl; + jpc_enc_rlvl_t *endlvls; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + jpc_enc_tile_t *tile; + int prcno; + jpc_enc_prc_t *prc; + + tile = enc->curtile; + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + jpc_tagtree_copy(prc->savincltree, prc->incltree); + jpc_tagtree_copy(prc->savnlibtree, prc->nlibtree); + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + cblk->savedcurpass = cblk->curpass; + cblk->savednumencpasses = cblk->numencpasses; + cblk->savednumlenbits = cblk->numlenbits; + } + } + } + } + } + +} + +void jpc_restore_t2state(jpc_enc_t *enc) +{ + + jpc_enc_tcmpt_t *comp; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_rlvl_t *lvl; + jpc_enc_rlvl_t *endlvls; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + jpc_enc_tile_t *tile; + int prcno; + jpc_enc_prc_t *prc; + + tile = enc->curtile; + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + jpc_tagtree_copy(prc->incltree, prc->savincltree); + jpc_tagtree_copy(prc->nlibtree, prc->savnlibtree); + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + cblk->curpass = cblk->savedcurpass; + cblk->numencpasses = cblk->savednumencpasses; + cblk->numlenbits = cblk->savednumlenbits; + } + } + } + } + } +} + +void jpc_init_t2state(jpc_enc_t *enc, int raflag) +{ +/* It is assumed that band->numbps and cblk->numbps precomputed */ + + jpc_enc_tcmpt_t *comp; + jpc_enc_tcmpt_t *endcomps; + jpc_enc_rlvl_t *lvl; + jpc_enc_rlvl_t *endlvls; + jpc_enc_band_t *band; + jpc_enc_band_t *endbands; + jpc_enc_cblk_t *cblk; + jpc_enc_cblk_t *endcblks; + jpc_enc_pass_t *pass; + jpc_enc_pass_t *endpasses; + jpc_tagtreenode_t *leaf; + jpc_enc_tile_t *tile; + int prcno; + jpc_enc_prc_t *prc; + + tile = enc->curtile; + + endcomps = &tile->tcmpts[tile->numtcmpts]; + for (comp = tile->tcmpts; comp != endcomps; ++comp) { + endlvls = &comp->rlvls[comp->numrlvls]; + for (lvl = comp->rlvls; lvl != endlvls; ++lvl) { + if (!lvl->bands) { + continue; + } + endbands = &lvl->bands[lvl->numbands]; + for (band = lvl->bands; band != endbands; ++band) { + if (!band->data) { + continue; + } + for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { + if (!prc->cblks) { + continue; + } + jpc_tagtree_reset(prc->incltree); + jpc_tagtree_reset(prc->nlibtree); + endcblks = &prc->cblks[prc->numcblks]; + for (cblk = prc->cblks; cblk != endcblks; ++cblk) { + if (jas_stream_rewind(cblk->stream)) { + assert(0); + } + cblk->curpass = (cblk->numpasses > 0) ? cblk->passes : 0; + cblk->numencpasses = 0; + cblk->numlenbits = 3; + cblk->numimsbs = band->numbps - cblk->numbps; + assert(cblk->numimsbs >= 0); + leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks); + jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs); + + if (raflag) { + endpasses = &cblk->passes[cblk->numpasses]; + for (pass = cblk->passes; pass != endpasses; ++pass) { + pass->lyrno = -1; + pass->lyrno = 0; + } + } + } + } + } + } + } + +} + +jpc_pi_t *jpc_enc_pi_create(jpc_enc_cp_t *cp, jpc_enc_tile_t *tile) +{ + jpc_pi_t *pi; + int compno; + jpc_picomp_t *picomp; + jpc_pirlvl_t *pirlvl; + jpc_enc_tcmpt_t *tcomp; + int rlvlno; + jpc_enc_rlvl_t *rlvl; + int prcno; + int *prclyrno; + + if (!(pi = jpc_pi_create0())) { + return 0; + } + pi->pktno = -1; + pi->numcomps = cp->numcmpts; + if (!(pi->picomps = jas_alloc2(pi->numcomps, sizeof(jpc_picomp_t)))) { + jpc_pi_destroy(pi); + return 0; + } + for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno, + ++picomp) { + picomp->pirlvls = 0; + } + + for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps; + compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { + picomp->numrlvls = tcomp->numrlvls; + if (!(picomp->pirlvls = jas_alloc2(picomp->numrlvls, + sizeof(jpc_pirlvl_t)))) { + jpc_pi_destroy(pi); + return 0; + } + for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < + picomp->numrlvls; ++rlvlno, ++pirlvl) { + pirlvl->prclyrnos = 0; + } + for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; + rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { +/* XXX sizeof(long) should be sizeof different type */ + pirlvl->numprcs = rlvl->numprcs; + if (rlvl->numprcs) { + if (!(pirlvl->prclyrnos = jas_alloc2(pirlvl->numprcs, + sizeof(long)))) { + jpc_pi_destroy(pi); + return 0; + } + } else { + pirlvl->prclyrnos = 0; + } + } + } + + pi->maxrlvls = 0; + for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps; + compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { + picomp->hsamp = cp->ccps[compno].sampgrdstepx; + picomp->vsamp = cp->ccps[compno].sampgrdstepy; + for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; + rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { + pirlvl->prcwidthexpn = rlvl->prcwidthexpn; + pirlvl->prcheightexpn = rlvl->prcheightexpn; + for (prcno = 0, prclyrno = pirlvl->prclyrnos; + prcno < pirlvl->numprcs; ++prcno, ++prclyrno) { + *prclyrno = 0; + } + pirlvl->numhprcs = rlvl->numhprcs; + } + if (pi->maxrlvls < tcomp->numrlvls) { + pi->maxrlvls = tcomp->numrlvls; + } + } + + pi->numlyrs = tile->numlyrs; + pi->xstart = tile->tlx; + pi->ystart = tile->tly; + pi->xend = tile->brx; + pi->yend = tile->bry; + + pi->picomp = 0; + pi->pirlvl = 0; + pi->x = 0; + pi->y = 0; + pi->compno = 0; + pi->rlvlno = 0; + pi->prcno = 0; + pi->lyrno = 0; + pi->xstep = 0; + pi->ystep = 0; + + pi->pchgno = -1; + + pi->defaultpchg.prgord = tile->prg; + pi->defaultpchg.compnostart = 0; + pi->defaultpchg.compnoend = pi->numcomps; + pi->defaultpchg.rlvlnostart = 0; + pi->defaultpchg.rlvlnoend = pi->maxrlvls; + pi->defaultpchg.lyrnoend = pi->numlyrs; + pi->pchg = 0; + + pi->valid = 0; + + return pi; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_t2enc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tier 2 Encoder + * + * $Id: jpc_t2enc.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_T2ENC_H +#define JPC_T2ENC_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include + +#include "jpc_enc.h" + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Encode the packets for a tile. */ +int jpc_enc_encpkts(jpc_enc_t *enc, jas_stream_t *out); + +/* Encode the specified packet. */ +int jpc_enc_encpkt(jpc_enc_t *enc, jas_stream_t *out, int compno, int lvlno, + int prcno, int lyrno); + +/* Save the tier-2 coding state. */ +void jpc_save_t2state(jpc_enc_t *enc); + +/* Restore the tier-2 coding state. */ +void jpc_restore_t2state(jpc_enc_t *enc); + +/* Initialize the tier-2 coding state. */ +void jpc_init_t2state(jpc_enc_t *enc, int raflag); + +/* Create a packet iterator for the encoder. */ +jpc_pi_t *jpc_enc_pi_create(jpc_enc_cp_t *cp, jpc_enc_tile_t *tile); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,393 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tag Tree Library + * + * $Id: jpc_tagtree.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include +#include +#include +#include + +#include "jasper/jas_malloc.h" + +#include "jpc_tagtree.h" + +/******************************************************************************\ +* Prototypes. +\******************************************************************************/ + +static jpc_tagtree_t *jpc_tagtree_alloc(void); + +/******************************************************************************\ +* Code for creating and destroying tag trees. +\******************************************************************************/ + +/* Create a tag tree. */ + +jpc_tagtree_t *jpc_tagtree_create(int numleafsh, int numleafsv) +{ + int nplh[JPC_TAGTREE_MAXDEPTH]; + int nplv[JPC_TAGTREE_MAXDEPTH]; + jpc_tagtreenode_t *node; + jpc_tagtreenode_t *parentnode; + jpc_tagtreenode_t *parentnode0; + jpc_tagtree_t *tree; + int i; + int j; + int k; + int numlvls; + int n; + + assert(numleafsh > 0 && numleafsv > 0); + + if (!(tree = jpc_tagtree_alloc())) { + return 0; + } + tree->numleafsh_ = numleafsh; + tree->numleafsv_ = numleafsv; + + numlvls = 0; + nplh[0] = numleafsh; + nplv[0] = numleafsv; + do { + n = nplh[numlvls] * nplv[numlvls]; + nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; + nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; + tree->numnodes_ += n; + ++numlvls; + } while (n > 1); + + if (!(tree->nodes_ = jas_alloc2(tree->numnodes_, sizeof(jpc_tagtreenode_t)))) { + return 0; + } + + /* Initialize the parent links for all nodes in the tree. */ + + node = tree->nodes_; + parentnode = &tree->nodes_[tree->numleafsh_ * tree->numleafsv_]; + parentnode0 = parentnode; + + for (i = 0; i < numlvls - 1; ++i) { + for (j = 0; j < nplv[i]; ++j) { + k = nplh[i]; + while (--k >= 0) { + node->parent_ = parentnode; + ++node; + if (--k >= 0) { + node->parent_ = parentnode; + ++node; + } + ++parentnode; + } + if ((j & 1) || j == nplv[i] - 1) { + parentnode0 = parentnode; + } else { + parentnode = parentnode0; + parentnode0 += nplh[i]; + } + } + } + node->parent_ = 0; + + /* Initialize the data values to something sane. */ + + jpc_tagtree_reset(tree); + + return tree; +} + +/* Destroy a tag tree. */ + +void jpc_tagtree_destroy(jpc_tagtree_t *tree) +{ + if (tree->nodes_) { + jas_free(tree->nodes_); + } + jas_free(tree); +} + +static jpc_tagtree_t *jpc_tagtree_alloc() +{ + jpc_tagtree_t *tree; + + if (!(tree = jas_malloc(sizeof(jpc_tagtree_t)))) { + return 0; + } + tree->numleafsh_ = 0; + tree->numleafsv_ = 0; + tree->numnodes_ = 0; + tree->nodes_ = 0; + + return tree; +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Copy state information from one tag tree to another. */ + +void jpc_tagtree_copy(jpc_tagtree_t *dsttree, jpc_tagtree_t *srctree) +{ + int n; + jpc_tagtreenode_t *srcnode; + jpc_tagtreenode_t *dstnode; + + /* The two tag trees must have similar sizes. */ + assert(srctree->numleafsh_ == dsttree->numleafsh_ && + srctree->numleafsv_ == dsttree->numleafsv_); + + n = srctree->numnodes_; + srcnode = srctree->nodes_; + dstnode = dsttree->nodes_; + while (--n >= 0) { + dstnode->value_ = srcnode->value_; + dstnode->low_ = srcnode->low_; + dstnode->known_ = srcnode->known_; + ++dstnode; + ++srcnode; + } +} + +/* Reset all of the state information associated with a tag tree. */ + +void jpc_tagtree_reset(jpc_tagtree_t *tree) +{ + int n; + jpc_tagtreenode_t *node; + + n = tree->numnodes_; + node = tree->nodes_; + + while (--n >= 0) { + node->value_ = INT_MAX; + node->low_ = 0; + node->known_ = 0; + ++node; + } +} + +/* Set the value associated with the specified leaf node, updating +the other nodes as necessary. */ + +void jpc_tagtree_setvalue(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int value) +{ + jpc_tagtreenode_t *node; + + /* Avoid compiler warnings about unused parameters. */ + tree = 0; + + assert(value >= 0); + + node = leaf; + while (node && node->value_ > value) { + node->value_ = value; + node = node->parent_; + } +} + +/* Get a particular leaf node. */ + +jpc_tagtreenode_t *jpc_tagtree_getleaf(jpc_tagtree_t *tree, int n) +{ + return &tree->nodes_[n]; +} + +/* Invoke the tag tree encoding procedure. */ + +int jpc_tagtree_encode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int threshold, jpc_bitstream_t *out) +{ + jpc_tagtreenode_t *stk[JPC_TAGTREE_MAXDEPTH - 1]; + jpc_tagtreenode_t **stkptr; + jpc_tagtreenode_t *node; + int low; + + /* Avoid compiler warnings about unused parameters. */ + tree = 0; + + assert(leaf); + assert(threshold >= 0); + + /* Traverse to the root of the tree, recording the path taken. */ + stkptr = stk; + node = leaf; + while (node->parent_) { + *stkptr++ = node; + node = node->parent_; + } + + low = 0; + for (;;) { + if (low > node->low_) { + /* Deferred propagation of the lower bound downward in + the tree. */ + node->low_ = low; + } else { + low = node->low_; + } + + while (low < threshold) { + if (low >= node->value_) { + if (!node->known_) { + if (jpc_bitstream_putbit(out, 1) == EOF) { + return -1; + } + node->known_ = 1; + } + break; + } + if (jpc_bitstream_putbit(out, 0) == EOF) { + return -1; + } + ++low; + } + node->low_ = low; + if (stkptr == stk) { + break; + } + node = *--stkptr; + + } + return (leaf->low_ < threshold) ? 1 : 0; + +} + +/* Invoke the tag tree decoding procedure. */ + +int jpc_tagtree_decode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int threshold, jpc_bitstream_t *in) +{ + jpc_tagtreenode_t *stk[JPC_TAGTREE_MAXDEPTH - 1]; + jpc_tagtreenode_t **stkptr; + jpc_tagtreenode_t *node; + int low; + int ret; + + /* Avoid compiler warnings about unused parameters. */ + tree = 0; + + assert(threshold >= 0); + + /* Traverse to the root of the tree, recording the path taken. */ + stkptr = stk; + node = leaf; + while (node->parent_) { + *stkptr++ = node; + node = node->parent_; + } + + low = 0; + for (;;) { + if (low > node->low_) { + node->low_ = low; + } else { + low = node->low_; + } + while (low < threshold && low < node->value_) { + if ((ret = jpc_bitstream_getbit(in)) < 0) { + return -1; + } + if (ret) { + node->value_ = low; + } else { + ++low; + } + } + node->low_ = low; + if (stkptr == stk) { + break; + } + node = *--stkptr; + } + + return (node->value_ < threshold) ? 1 : 0; +} + +/******************************************************************************\ +* Code for debugging. +\******************************************************************************/ + +void jpc_tagtree_dump(jpc_tagtree_t *tree, FILE *out) +{ + jpc_tagtreenode_t *node; + int n; + + node = tree->nodes_; + n = tree->numnodes_; + while (--n >= 0) { + fprintf(out, "node %p, parent %p, value %d, lower %d, known %d\n", + (void *) node, (void *) node->parent_, node->value_, node->low_, + node->known_); + ++node; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tagtree.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tag Tree Library + * + * $Id: jpc_tagtree.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_TAGTREE_H +#define JPC_TAGTREE_H + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include +#include + +#include "jpc_bs.h" + +/******************************************************************************\ +* Constants +\******************************************************************************/ + +/* The maximum allowable depth for a tag tree. */ +#define JPC_TAGTREE_MAXDEPTH 32 + +/******************************************************************************\ +* Types +\******************************************************************************/ + +/* + * Tag tree node. + */ + +typedef struct jpc_tagtreenode_ { + + /* The parent of this node. */ + struct jpc_tagtreenode_ *parent_; + + /* The value associated with this node. */ + int value_; + + /* The lower bound on the value associated with this node. */ + int low_; + + /* A flag indicating if the value is known exactly. */ + int known_; + +} jpc_tagtreenode_t; + +/* + * Tag tree. + */ + +typedef struct { + + /* The number of leaves in the horizontal direction. */ + int numleafsh_; + + /* The number of leaves in the vertical direction. */ + int numleafsv_; + + /* The total number of nodes in the tree. */ + int numnodes_; + + /* The nodes. */ + jpc_tagtreenode_t *nodes_; + +} jpc_tagtree_t; + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Create a tag tree. */ +jpc_tagtree_t *jpc_tagtree_create(int numleafsh, int numleafsv); + +/* Destroy a tag tree. */ +void jpc_tagtree_destroy(jpc_tagtree_t *tree); + +/* Copy data from one tag tree to another. */ +void jpc_tagtree_copy(jpc_tagtree_t *dsttree, jpc_tagtree_t *srctree); + +/* Reset the tag tree state. */ +void jpc_tagtree_reset(jpc_tagtree_t *tree); + +/* Set the value associated with a particular leaf node of a tag tree. */ +void jpc_tagtree_setvalue(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int value); + +/* Get a pointer to a particular leaf node. */ +jpc_tagtreenode_t *jpc_tagtree_getleaf(jpc_tagtree_t *tree, int n); + +/* Invoke the tag tree decoding procedure. */ +int jpc_tagtree_decode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int threshold, jpc_bitstream_t *in); + +/* Invoke the tag tree encoding procedure. */ +int jpc_tagtree_encode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf, + int threshold, jpc_bitstream_t *out); + +/* Dump a tag tree (for debugging purposes). */ +void jpc_tagtree_dump(jpc_tagtree_t *tree, FILE *out); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,288 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tree-Structured Filter Bank (TSFB) Library + * + * $Id: jpc_tsfb.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include + +#include "jasper/jas_malloc.h" +#include "jasper/jas_seq.h" + +#include "jpc_tsfb.h" +#include "jpc_cod.h" +#include "jpc_cs.h" +#include "jpc_util.h" +#include "jpc_math.h" + +void jpc_tsfb_getbands2(jpc_tsfb_t *tsfb, int locxstart, int locystart, + int xstart, int ystart, int xend, int yend, jpc_tsfb_band_t **bands, + int numlvls); + +/******************************************************************************\ +* +\******************************************************************************/ + +jpc_tsfb_t *jpc_cod_gettsfb(int qmfbid, int numlvls) +{ + jpc_tsfb_t *tsfb; + + if (!(tsfb = malloc(sizeof(jpc_tsfb_t)))) + return 0; + + if (numlvls > 0) { + switch (qmfbid) { + case JPC_COX_INS: + tsfb->qmfb = &jpc_ns_qmfb2d; + break; + default: + case JPC_COX_RFT: + tsfb->qmfb = &jpc_ft_qmfb2d; + break; + } + } else { + tsfb->qmfb = 0; + } + tsfb->numlvls = numlvls; + return tsfb; +} + +void jpc_tsfb_destroy(jpc_tsfb_t *tsfb) +{ + free(tsfb); +} + +int jpc_tsfb_analyze(jpc_tsfb_t *tsfb, jas_seq2d_t *a) +{ + return (tsfb->numlvls > 0) ? jpc_tsfb_analyze2(tsfb, jas_seq2d_getref(a, + jas_seq2d_xstart(a), jas_seq2d_ystart(a)), jas_seq2d_xstart(a), + jas_seq2d_ystart(a), jas_seq2d_width(a), + jas_seq2d_height(a), jas_seq2d_rowstep(a), tsfb->numlvls - 1) : 0; +} + +int jpc_tsfb_analyze2(jpc_tsfb_t *tsfb, int *a, int xstart, int ystart, + int width, int height, int stride, int numlvls) +{ + if (width > 0 && height > 0) { + if ((*tsfb->qmfb->analyze)(a, xstart, ystart, width, height, stride)) + return -1; + if (numlvls > 0) { + if (jpc_tsfb_analyze2(tsfb, a, JPC_CEILDIVPOW2(xstart, + 1), JPC_CEILDIVPOW2(ystart, 1), JPC_CEILDIVPOW2( + xstart + width, 1) - JPC_CEILDIVPOW2(xstart, 1), + JPC_CEILDIVPOW2(ystart + height, 1) - + JPC_CEILDIVPOW2(ystart, 1), stride, numlvls - 1)) { + return -1; + } + } + } + return 0; +} + +int jpc_tsfb_synthesize(jpc_tsfb_t *tsfb, jas_seq2d_t *a) +{ + return (tsfb->numlvls > 0) ? jpc_tsfb_synthesize2(tsfb, + jas_seq2d_getref(a, jas_seq2d_xstart(a), jas_seq2d_ystart(a)), + jas_seq2d_xstart(a), jas_seq2d_ystart(a), jas_seq2d_width(a), + jas_seq2d_height(a), jas_seq2d_rowstep(a), tsfb->numlvls - 1) : 0; +} + +int jpc_tsfb_synthesize2(jpc_tsfb_t *tsfb, int *a, int xstart, int ystart, + int width, int height, int stride, int numlvls) +{ + if (numlvls > 0) { + if (jpc_tsfb_synthesize2(tsfb, a, JPC_CEILDIVPOW2(xstart, 1), + JPC_CEILDIVPOW2(ystart, 1), JPC_CEILDIVPOW2(xstart + width, + 1) - JPC_CEILDIVPOW2(xstart, 1), JPC_CEILDIVPOW2(ystart + + height, 1) - JPC_CEILDIVPOW2(ystart, 1), stride, numlvls - + 1)) { + return -1; + } + } + if (width > 0 && height > 0) { + if ((*tsfb->qmfb->synthesize)(a, xstart, ystart, width, height, stride)) { + return -1; + } + } + return 0; +} + +int jpc_tsfb_getbands(jpc_tsfb_t *tsfb, uint_fast32_t xstart, + uint_fast32_t ystart, uint_fast32_t xend, uint_fast32_t yend, + jpc_tsfb_band_t *bands) +{ + jpc_tsfb_band_t *band; + + band = bands; + if (tsfb->numlvls > 0) { + jpc_tsfb_getbands2(tsfb, xstart, ystart, xstart, ystart, xend, yend, + &band, tsfb->numlvls); + } else { + + band->xstart = xstart; + band->ystart = ystart; + band->xend = xend; + band->yend = yend; + band->locxstart = xstart; + band->locystart = ystart; + band->locxend = band->locxstart + band->xend - band->xstart; + band->locyend = band->locystart + band->yend - band->ystart; + band->orient = JPC_TSFB_LL; + band->synenergywt = JPC_FIX_ONE; + ++band; + } + return band - bands; +} + +void jpc_tsfb_getbands2(jpc_tsfb_t *tsfb, int locxstart, int locystart, + int xstart, int ystart, int xend, int yend, jpc_tsfb_band_t **bands, + int numlvls) +{ + int newxstart; + int newystart; + int newxend; + int newyend; + jpc_tsfb_band_t *band; + + newxstart = JPC_CEILDIVPOW2(xstart, 1); + newystart = JPC_CEILDIVPOW2(ystart, 1); + newxend = JPC_CEILDIVPOW2(xend, 1); + newyend = JPC_CEILDIVPOW2(yend, 1); + + if (numlvls > 0) { + + jpc_tsfb_getbands2(tsfb, locxstart, locystart, newxstart, newystart, + newxend, newyend, bands, numlvls - 1); + + band = *bands; + band->xstart = JPC_FLOORDIVPOW2(xstart, 1); + band->ystart = newystart; + band->xend = JPC_FLOORDIVPOW2(xend, 1); + band->yend = newyend; + band->locxstart = locxstart + newxend - newxstart; + band->locystart = locystart; + band->locxend = band->locxstart + band->xend - band->xstart; + band->locyend = band->locystart + band->yend - band->ystart; + band->orient = JPC_TSFB_HL; + band->synenergywt = jpc_dbltofix(tsfb->qmfb->hpenergywts[ + tsfb->numlvls - numlvls] * tsfb->qmfb->lpenergywts[ + tsfb->numlvls - numlvls]); + ++(*bands); + + band = *bands; + band->xstart = newxstart; + band->ystart = JPC_FLOORDIVPOW2(ystart, 1); + band->xend = newxend; + band->yend = JPC_FLOORDIVPOW2(yend, 1); + band->locxstart = locxstart; + band->locystart = locystart + newyend - newystart; + band->locxend = band->locxstart + band->xend - band->xstart; + band->locyend = band->locystart + band->yend - band->ystart; + band->orient = JPC_TSFB_LH; + band->synenergywt = jpc_dbltofix(tsfb->qmfb->lpenergywts[ + tsfb->numlvls - numlvls] * tsfb->qmfb->hpenergywts[ + tsfb->numlvls - numlvls]); + ++(*bands); + + band = *bands; + band->xstart = JPC_FLOORDIVPOW2(xstart, 1); + band->ystart = JPC_FLOORDIVPOW2(ystart, 1); + band->xend = JPC_FLOORDIVPOW2(xend, 1); + band->yend = JPC_FLOORDIVPOW2(yend, 1); + band->locxstart = locxstart + newxend - newxstart; + band->locystart = locystart + newyend - newystart; + band->locxend = band->locxstart + band->xend - band->xstart; + band->locyend = band->locystart + band->yend - band->ystart; + band->orient = JPC_TSFB_HH; + band->synenergywt = jpc_dbltofix(tsfb->qmfb->hpenergywts[ + tsfb->numlvls - numlvls] * tsfb->qmfb->hpenergywts[ + tsfb->numlvls - numlvls]); + ++(*bands); + + } else { + + band = *bands; + band->xstart = xstart; + band->ystart = ystart; + band->xend = xend; + band->yend = yend; + band->locxstart = locxstart; + band->locystart = locystart; + band->locxend = band->locxstart + band->xend - band->xstart; + band->locyend = band->locystart + band->yend - band->ystart; + band->orient = JPC_TSFB_LL; + band->synenergywt = jpc_dbltofix(tsfb->qmfb->lpenergywts[ + tsfb->numlvls - numlvls - 1] * tsfb->qmfb->lpenergywts[ + tsfb->numlvls - numlvls - 1]); + ++(*bands); + + } + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_tsfb.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tree-Structured Filter Bank (TSFB) Library + * + * $Id: jpc_tsfb.h,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +#ifndef JPC_TSFB_H +#define JPC_TSFB_H + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_seq.h" + +#include "jpc_fix.h" +#include "jpc_qmfb.h" + +/******************************************************************************\ +* Constants. +\******************************************************************************/ + +#define JPC_TSFB_MAXBANDS (JPC_TSFB_MAXDEPTH * 3 + 1) +#define JPC_TSFB_MAXDEPTH 32 +#define JPC_TSFB_RITIMODE JPC_QMFB1D_RITIMODE + +#define JPC_TSFB_LL 0 +#define JPC_TSFB_LH 1 +#define JPC_TSFB_HL 2 +#define JPC_TSFB_HH 3 + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +typedef struct { + int xstart; + int ystart; + int xend; + int yend; + int orient; + int locxstart; + int locystart; + int locxend; + int locyend; + jpc_fix_t synenergywt; +} jpc_tsfb_band_t; + +typedef struct { + int numlvls; + jpc_qmfb2d_t *qmfb; +} jpc_tsfb_t; + +/******************************************************************************\ +* Functions. +\******************************************************************************/ + +/* Create a TSFB. */ +jpc_tsfb_t *jpc_cod_gettsfb(int qmfbid, int numlevels); + +/* Destroy a TSFB. */ +void jpc_tsfb_destroy(jpc_tsfb_t *tsfb); + +/* Perform analysis. */ +int jpc_tsfb_analyze(jpc_tsfb_t *tsfb, jas_seq2d_t *x); + +/* Perform synthesis. */ +int jpc_tsfb_synthesize(jpc_tsfb_t *tsfb, jas_seq2d_t *x); + +/* Get band information for a TSFB. */ +int jpc_tsfb_getbands(jpc_tsfb_t *tsfb, uint_fast32_t xstart, + uint_fast32_t ystart, uint_fast32_t xend, uint_fast32_t yend, + jpc_tsfb_band_t *bands); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * $Id: jpc_util.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $ + */ + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "jasper/jas_math.h" +#include "jasper/jas_malloc.h" + +#include "jpc_fix.h" +#include "jpc_cs.h" +#include "jpc_flt.h" +#include "jpc_util.h" + +/******************************************************************************\ +* Miscellaneous Functions +\******************************************************************************/ + +int jpc_atoaf(char *s, int *numvalues, double **values) +{ + static char delim[] = ", \t\n"; + char buf[4096]; + int n; + double *vs; + char *cp; + + strncpy(buf, s, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + n = 0; + if ((cp = strtok(buf, delim))) { + ++n; + while ((cp = strtok(0, delim))) { + if (cp != '\0') { + ++n; + } + } + } + + if (n) { + if (!(vs = jas_alloc2(n, sizeof(double)))) { + return -1; + } + + strncpy(buf, s, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + n = 0; + if ((cp = strtok(buf, delim))) { + vs[n] = atof(cp); + ++n; + while ((cp = strtok(0, delim))) { + if (cp != '\0') { + vs[n] = atof(cp); + ++n; + } + } + } + } else { + vs = 0; + } + + *numvalues = n; + *values = vs; + + return 0; +} + +jas_seq_t *jpc_seq_upsample(jas_seq_t *x, int m) +{ + jas_seq_t *z; + int i; + + if (!(z = jas_seq_create(jas_seq_start(x) * m, (jas_seq_end(x) - 1) * m + 1))) + return 0; + for (i = jas_seq_start(z); i < jas_seq_end(z); i++) { + *jas_seq_getref(z, i) = (!JAS_MOD(i, m)) ? jas_seq_get(x, i / m) : + jpc_inttofix(0); + } + + return z; +} + +jpc_fix_t jpc_seq_norm(jas_seq_t *x) +{ + jpc_fix_t s; + int i; + + s = jpc_inttofix(0); + for (i = jas_seq_start(x); i < jas_seq_end(x); i++) { + s = jpc_fix_add(s, jpc_fix_mul(jas_seq_get(x, i), jas_seq_get(x, i))); + } + + return jpc_dbltofix(sqrt(jpc_fixtodbl(s))); +} + +jas_seq_t *jpc_seq_conv(jas_seq_t *x, jas_seq_t *y) +{ + int i; + int j; + int k; + jas_seq_t *z; + jpc_fix_t s; + jpc_fix_t v; + + z = jas_seq_create(jas_seq_start(x) + jas_seq_start(y), + jas_seq_end(x) + jas_seq_end(y) - 1); + assert(z); + for (i = jas_seq_start(z); i < jas_seq_end(z); i++) { + s = jpc_inttofix(0); + for (j = jas_seq_start(y); j < jas_seq_end(y); j++) { + k = i - j; + if (k < jas_seq_start(x) || k >= jas_seq_end(x)) { + v = JPC_FIX_ZERO; + } else { + v = jas_seq_get(x, k); + } + s = jpc_fix_add(s, jpc_fix_mul(jas_seq_get(y, j), v)); + } + *jas_seq_getref(z, i) = s; + } + + return z; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/jpc_util.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#ifndef JPC_UTIL_H +#define JPC_UTIL_H + +/* Parse a comma separated list of real numbers into an array of doubles. */ +int jpc_atoaf(char *s, int *numvalues, double **values); + +/* Upsample a sequence. */ +jas_seq_t *jpc_seq_upsample(jas_seq_t *seq, int n); + +/* Convolve two sequences. */ +jas_seq_t *jpc_seq_conv(jas_seq_t *seq0, jas_seq_t *seq1); + +/* Compute the norm of a sequence. */ +jpc_fix_t jpc_seq_norm(jas_seq_t *x); + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/libjasper.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/libjasper.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjasper/libjasper.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjasper/libjasper.pro 2013-05-08 15:40:18.000000000 +0000 @@ -0,0 +1,19 @@ + + +TEMPLATE = lib +TARGET = jasper + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.c + + +INCLUDEPATH += ./ ../zlib + +DEFINES += EXCLUDE_MIF_SUPPORT EXCLUDE_PNM_SUPPORT EXCLUDE_BMP_SUPPORT EXCLUDE_RAS_SUPPORT EXCLUDE_JPG_SUPPORT EXCLUDE_PGX_SUPPORT + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,43 @@ +# ---------------------------------------------------------------------------- +# CMake file for libjpeg. See root CMakeLists.txt +# +# ---------------------------------------------------------------------------- +project(${JPEG_LIBRARY}) + +ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +file(GLOB lib_srcs *.c) +file(GLOB lib_hdrs *.h) + +# ---------------------------------------------------------------------------------- +# Define the library target: +# ---------------------------------------------------------------------------------- + +add_library(${JPEG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs}) + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + set_source_files_properties(jcdctmgr.c PROPERTIES COMPILE_FLAGS "-O1") +endif() + +ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align -Wshadow -Wunused) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang + +set_target_properties(${JPEG_LIBRARY} + PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY} + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${JPEG_LIBRARY} PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS ${JPEG_LIBRARY} ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/README diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/README --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/README 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/README 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,385 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6b of 27-Mar-1998 +==================================== + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, +Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, +Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG +Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1998, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The Unix configuration script "configure" was produced with GNU Autoconf. +It is copyright by the Free Software Foundation but is freely distributable. +The same holds for its supporting scripts (config.guess, config.sub, +ltconfig, ltmain.sh). Another support script, install-sh, is copyright +by M.I.T. but is also freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +The IJG distribution formerly included code to read and write GIF files. +To avoid entanglement with the Unisys LZW patent, GIF reading support has +been removed altogether, and the GIF writer has been simplified to produce +"uncompressed GIFs". This technique does not use the LZW algorithm; the +resulting GIF files are larger than usual, but are readable by all standard +GIF decoders. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article is +available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and IEEE, +and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides +good explanations and example C code for a multitude of compression methods +including JPEG. It is an excellent source if you are comfortable reading C +code but don't know much about data compression in general. The book's JPEG +sample code is far from industrial-strength, but when you are ready to look +at a full implementation, you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Some extensions to the original JPEG standard are defined in JPEG Part 3, +a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG +currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available by FTP at +ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text +version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing +the figures. + +The TIFF 6.0 file format specification can be obtained by FTP from +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or +from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision +of the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from ftp://ftp.sgi.com/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have +direct Internet access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or +on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 +"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net +release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ +and other news.answers archive sites, including the official news.answers +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS software, which provides many useful operations on PPM-format image +files. In particular, it can convert PPM images to and from a wide range of +other formats, thus making cjpeg/djpeg considerably more useful. The latest +version is distributed by the NetPBM group, and is available from numerous +sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; +you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from ftp://havefun.stanford.edu/pub/jpeg/. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. (On the other hand, it doesn't do progressive JPEG.) + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +The major thrust for v7 will probably be improvement of visual quality. +The current method for scaling the quantization tables is known not to be +very good at low Q values. We also intend to investigate block boundary +smoothing, "poor man's variable quantization", and other means of improving +quality-vs-file-size performance without sacrificing compatibility. + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +As always, speeding things up is of great interest. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcapimin.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcapimin.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcapimin.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcapimin.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,280 @@ +/* + * jcapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-compression case or the transcoding-only + * case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jcapistd.c. But also see jcparam.c for + * parameter-setup helper routines, jcomapi.c for routines shared by + * compression and decompression, and jctrans.c for the transcoding case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.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(). + */ +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcapistd.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcapistd.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcapistd.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcapistd.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * jcapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-compression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_compress, it will end up linking in the entire compressor. + * We thus must separate this file from jcapimin.c to avoid linking the + * whole compression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jccoefct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jccoefct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jccoefct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jccoefct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,449 @@ +/* + * jccoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for compression. + * This controller is the top level of the JPEG compressor proper. + * The coefficient buffer lies between forward-DCT and entropy encoding steps. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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 */ + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jccolor.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jccolor.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jccolor.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jccolor.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,459 @@ +/* + * jccolor.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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< 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; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcdctmgr.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcdctmgr.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcdctmgr.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcdctmgr.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,387 @@ +/* + * jcdctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the forward-DCT management logic. + * This code selects a particular DCT implementation to be used, + * and it performs related housekeeping chores including coefficient + * quantization. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "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 + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,909 @@ +/* + * jchuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "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)<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 + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jchuff.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* 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. + */ + +#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[])); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcinit.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcinit.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcinit.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcinit.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * jcinit.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains initialization logic for the JPEG compressor. + * This routine is in charge of selecting the modules to be executed and + * making an initialization call to each one. + * + * Logically, this code belongs in jcmaster.c. It's split out because + * linking this routine implies linking the entire compression library. + * For a transcoding-only application, we want to be able to use jcmaster.c + * without linking in the whole library. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmainct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmainct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmainct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmainct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,293 @@ +/* + * jcmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main_ptr buffer controller for compression. + * The main_ptr buffer lies between the pre-processor and the JPEG + * compressor proper; it holds downsampled data in the JPEG colorspace. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_ptr = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + main_ptr->cur_iMCU_row = 0; /* initialize counters */ + main_ptr->rowgroup_ctr = 0; + main_ptr->suspended = FALSE; + main_ptr->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_ptr->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + main_ptr->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_ptr->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + main_ptr->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_ptr = (my_main_ptr) cinfo->main; + + while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Read input data if we haven't filled the main_ptr buffer yet */ + if (main_ptr->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main_ptr->buffer, &main_ptr->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_ptr->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ + if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->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_ptr->suspended) { + (*in_row_ctr)--; + main_ptr->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main_ptr buffer empty. + */ + if (main_ptr->suspended) { + (*in_row_ctr)++; + main_ptr->suspended = FALSE; + } + main_ptr->rowgroup_ctr = 0; + main_ptr->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_ptr = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; + boolean writing = (main_ptr->pass_mode != JBUF_CRANK_DEST); + + while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ + if (main_ptr->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main_ptr->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main_ptr->whole_image[ci], + main_ptr->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_ptr->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_ptr->buffer, &main_ptr->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ + if (main_ptr->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ + if (main_ptr->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->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_ptr->suspended) { + (*in_row_ctr)--; + main_ptr->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main_ptr buffer empty. + */ + if (main_ptr->suspended) { + (*in_row_ctr)++; + main_ptr->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ + main_ptr->rowgroup_ctr = 0; + main_ptr->cur_iMCU_row++; + } +} + +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ + + +/* + * Initialize main_ptr buffer controller. + */ + +GLOBAL(void) +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main_ptr; + int ci; + jpeg_component_info *compptr; + + main_ptr = (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_ptr; + main_ptr->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_ptr->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_ptr->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_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmarker.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmarker.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmarker.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmarker.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,664 @@ +/* + * jcmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write JPEG datastream markers. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +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; + + +/* 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmaster.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmaster.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcmaster.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcmaster.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,590 @@ +/* + * jcmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG compressor. + * These routines are concerned with parameter validation, initial setup, + * and inter-pass control (determining the number of passes and the work + * to be done in each pass). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcomapi.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcomapi.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcomapi.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcomapi.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * jcomapi.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jconfig.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jconfig.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jconfig.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jconfig.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,67 @@ +/* jconfig.h. Generated automatically by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/*#undef void*/ +/*#undef const*/ +#undef CHAR_IS_UNSIGNED + +#if defined __MINGW__ || defined __MINGW32__ || (!defined WIN32 && !defined _WIN32) +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#endif + +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#if defined WIN32 || defined _WIN32 +/* 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 */ +#endif + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +/* These are for configuring the JPEG memory manager. */ +#define DEFAULT_MAX_MEM 1073741824 + +#if !defined WIN32 && !defined _WIN32 +#define INLINE __inline__ +#undef NO_MKTEMP +#endif + +#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 */ + +#if defined WIN32 || defined _WIN32 +#define TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Microsoft has setmode() */ +#else +#undef TWO_FILE_COMMANDLINE +#endif + +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcparam.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcparam.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcparam.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcparam.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,610 @@ +/* + * jcparam.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains optional default-setting code for the JPEG compressor. + * Applications do not have to use this file, but those that don't use it + * must know a lot more about the innards of the JPEG code. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcphuff.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcphuff.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcphuff.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcphuff.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,833 @@ +/* + * jcphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for progressive JPEG. + * + * We do not support output suspension in this module, since the library + * currently does not allow multiple-scan files to be written with output + * suspension. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jchuff.c */ + +#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(entropy); } + + +LOCAL(void) +dump_buffer (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 (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)<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 (phuff_entropy_ptr entropy) +{ + emit_bits(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(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(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(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 (phuff_entropy_ptr entropy, int restart_num) +{ + int ci; + + emit_eobrun(entropy); + + if (! entropy->gather_statistics) { + flush_bits(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(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(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(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(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(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(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(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(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(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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcprepct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcprepct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcprepct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcprepct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,354 @@ +/* + * jcprepct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the compression preprocessing controller. + * This controller manages the color conversion, downsampling, + * and edge expansion steps. + * + * Most of the complexity here is associated with buffering input rows + * as required by the downsampler. See the comments at the head of + * jcsample.c for the downsampler's needs. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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); + } + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcsample.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcsample.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jcsample.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jcsample.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,519 @@ +/* + * jcsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains downsampling routines. + * + * Downsampling input data is counted in "row groups". A row group + * is defined to be max_v_samp_factor pixel rows of each component, + * from which the downsampler produces v_samp_factor sample rows. + * A single row group is processed in each call to the downsampler module. + * + * The downsampler is responsible for edge-expansion of its output data + * to fill an integral number of DCT blocks horizontally. The source buffer + * may be modified if it is helpful for this purpose (the source buffer is + * allocated wide enough to correspond to the desired output width). + * The caller (the prep controller) is responsible for vertical padding. + * + * The downsampler may request "context rows" by setting need_context_rows + * during startup. In this case, the input arrays will contain at least + * one row group's worth of pixels above and below the passed-in data; + * the caller will create dummy rows at image top and bottom by replicating + * the first or last real pixel row. + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + * + * The downsampling algorithm used here is a simple average of the source + * pixels covered by the output pixel. The hi-falutin sampling literature + * refers to this as a "box filter". In general the characteristics of a box + * filter are not very good, but for the specific cases we normally use (1:1 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + * nearly so bad. If you intend to use other sampling ratios, you'd be well + * advised to improve this code. + * + * A simple input-smoothing capability is provided. This is mainly intended + * for cleaning up color-dithered GIF input files (if you find it inadequate, + * we suggest using an external filtering program such as pnmconvol). When + * enabled, each input pixel P is replaced by a weighted sum of itself and its + * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + * where SF = (smoothing_factor / 1024). + * Currently, smoothing is only supported for 2h2v sampling factors. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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 +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jctrans.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jctrans.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jctrans.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jctrans.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,388 @@ +/* + * jctrans.c + * + * Copyright (C) 1995-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding compression, + * that is, writing raw DCT coefficient arrays to an output JPEG file. + * The routines in jcapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_controller; + +typedef my_coef_controller * my_coef_ptr; + + +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; + + if (pass_mode != JBUF_CRANK_DEST) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + coef->iMCU_row_num = 0; + start_iMCU_row(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_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 */ + 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_row(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_ptr coef; + JBLOCKROW buffer; + int i; + + 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; + coef->pub.compress_data = compress_output; + + /* 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; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdapimin.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdapimin.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdapimin.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdapimin.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,395 @@ +/* + * jdapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c. But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdapistd.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdapistd.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdapistd.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdapistd.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,275 @@ +/* + * jdapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-decompression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdatadst.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdatadst.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdatadst.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdatadst.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * jdatadst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains compression data destination routines for the case of + * emitting JPEG data to a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * destination manager. + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of + * JOCTETs into 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +METHODDEF(void) +init_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != + (size_t) OUTPUT_BUF_SIZE) + ERREXIT(cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * 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_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + fflush(dest->outfile); + /* Make sure we wrote the output file OK */ + if (ferror(dest->outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +GLOBAL(void) +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) +{ + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdatasrc.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdatasrc.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdatasrc.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdatasrc.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,212 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "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 */ +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdcoefct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdcoefct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdcoefct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdcoefct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,736 @@ +/* + * jdcoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* 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_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* 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_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + 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 (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_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED + my_coef_ptr coef = (my_coef_ptr) 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_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, 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_row(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_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. */ + 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_row(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_ptr coef = (my_coef_ptr) 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_ptr coef = (my_coef_ptr) 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_ptr coef = (my_coef_ptr) 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< 0 && pred >= (1<= 0) { + pred = (int) (((Q10<<7) + num) / (Q10<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q20<<7) + num) / (Q20<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q11<<7) + num) / (Q11<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q02<<7) + num) / (Q02<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<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_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + 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 */ + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdcolor.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdcolor.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdcolor.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdcolor.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,396 @@ +/* + * jdcolor.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** 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<RGB colorspace conversion. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) 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_ptr cconvert = (my_cconvert_ptr) 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_convert (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_convert (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_ptr cconvert = (my_cconvert_ptr) 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_ptr cconvert; + int ci; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_deconverter)); + 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_convert; + /* 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_convert; + } 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_convert; + } 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_convert; + } 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdct.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdct.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdct.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdct.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * 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. + */ + +#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 diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jddctmgr.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jddctmgr.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jddctmgr.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jddctmgr.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,269 @@ +/* + * jddctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores. No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper. This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* + * 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; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,651 @@ +/* + * jdhuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "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_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).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_state 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_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) 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]) ]; +} + + +/* + * 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 */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) 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_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn; + BITREAD_STATE_VARS; + savable_state 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_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)); + 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; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdhuff.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,201 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#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< 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)); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdinput.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdinput.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdinput.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdinput.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,381 @@ +/* + * jdinput.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding). The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_setup (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_setup (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_pass (j_decompress_ptr cinfo) +{ + per_scan_setup(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_setup(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_pass(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_pass; + 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmainct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmainct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmainct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmainct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,512 @@ +/* + * jdmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main_ptr buffer controller for decompression. + * The main_ptr buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main_ptr buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main_ptr buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers. Nonetheless, the main_ptr 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_controller; + +typedef my_main_controller * my_main_ptr; + +/* 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_main + 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_ptr main_ptr = (my_main_ptr) 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_ptr->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + main_ptr->xbuffer[1] = main_ptr->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_ptr->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); + main_ptr->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_ptr->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_ptr main_ptr = (my_main_ptr) 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_ptr->xbuffer[0][ci]; + xbuf1 = main_ptr->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ + buf = main_ptr->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_ptr main_ptr = (my_main_ptr) 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_ptr->xbuffer[0][ci]; + xbuf1 = main_ptr->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_ptr main_ptr = (my_main_ptr) 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_ptr->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_ptr->xbuffer[main_ptr->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_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main_ptr = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { + main_ptr->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ + main_ptr->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main_ptr->context_state = CTX_PREPARE_FOR_IMCU; + main_ptr->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ + main_ptr->pub.process_data = process_data_simple_main; + } + main_ptr->buffer_full = FALSE; /* Mark buffer empty */ + main_ptr->rowgroup_ctr = 0; + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ + main_ptr->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_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main_ptr = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + + /* Read input data if we haven't filled the main_ptr buffer yet */ + if (! main_ptr->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, main_ptr->buffer)) + return; /* suspension forced, can do nothing more */ + main_ptr->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_ptr->buffer, + &main_ptr->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_ptr->rowgroup_ctr >= rowgroups_avail) { + main_ptr->buffer_full = FALSE; + main_ptr->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_ptr main_ptr = (my_main_ptr) cinfo->main; + + /* Read input data if we haven't filled the main_ptr buffer yet */ + if (! main_ptr->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, + main_ptr->xbuffer[main_ptr->whichptr])) + return; /* suspension forced, can do nothing more */ + main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main_ptr->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_ptr->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ + (*cinfo->post->post_process_data) (cinfo, main_ptr->xbuffer[main_ptr->whichptr], + &main_ptr->rowgroup_ctr, main_ptr->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail) + return; /* Need to suspend */ + main_ptr->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_ptr->rowgroup_ctr = 0; + main_ptr->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_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); + main_ptr->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ + (*cinfo->post->post_process_data) (cinfo, main_ptr->xbuffer[main_ptr->whichptr], + &main_ptr->rowgroup_ctr, main_ptr->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ + if (main_ptr->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ + main_ptr->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main_ptr->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_ptr->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); + main_ptr->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); + main_ptr->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_ptr buffer controller. + */ + +GLOBAL(void) +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main_ptr; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + + main_ptr = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_d_main_controller *) main_ptr; + main_ptr->pub.start_pass = start_pass_main; + + 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_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmarker.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmarker.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmarker.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmarker.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1360 @@ +/* + * jdmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application. On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +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; + + +/* 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_ptr; + + +/* + * 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_ptr marker = (my_marker_ptr) 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_ptr) cinfo->marker)->process_APPn[ + cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_COM: + if (! (*((my_marker_ptr) 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_ptr marker = (my_marker_ptr) 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_ptr marker; + int i; + + /* Create subobject in permanent pool */ + marker = (my_marker_ptr) + (*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_ptr marker = (my_marker_ptr) 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_ptr marker = (my_marker_ptr) 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); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmaster.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmaster.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmaster.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmaster.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,557 @@ +/* + * jdmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_ptr; + + +/* + * 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_ptr master = (my_master_ptr) 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_ptr master = (my_master_ptr) 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_ptr master = (my_master_ptr) 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_ptr master = (my_master_ptr) 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_ptr master; + + master = (my_master_ptr) + (*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); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmerge.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmerge.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdmerge.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdmerge.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,400 @@ +/* + * jdmerge.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains code for merged upsampling/color conversion. + * + * This file combines functions from jdsample.c and jdcolor.c; + * read those files first to understand what's going on. + * + * When the chroma components are to be upsampled by simple replication + * (ie, box filtering), we can save some work in color conversion by + * calculating all the output pixels corresponding to a pair of chroma + * samples at one time. In the conversion equations + * R = Y + K1 * Cr + * G = Y + K2 * Cb + K3 * Cr + * B = Y + K4 * Cb + * only the Y term varies among the group of pixels corresponding to a pair + * of chroma samples, so the rest of the terms can be calculated just once. + * At typical sampling ratios, this eliminates half or three-quarters of the + * multiplications needed for color conversion. + * + * This file currently provides implementations for the following cases: + * YCbCr => RGB color conversion only. + * Sampling ratios of 2h1v or 2h2v. + * No scaling needed at upsample time. + * Corner-aligned (non-CCIR601) sampling alignment. + * Other special cases could be added, but in most applications these are + * the only common cases. (For uncommon cases we fall back on the more + * general code in jdsample.c and jdcolor.c.) + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#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<RGB colorspace conversion. + * This is taken directly from jdcolor.c; see that file for more info. + */ + +LOCAL(void) +build_ycc_rgb_table (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_table(cinfo); +} + +#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdphuff.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdphuff.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdphuff.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdphuff.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,668 @@ +/* + * jdphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for progressive JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdhuff.c */ + + +#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_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).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_state 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_ptr; + +/* 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_ptr entropy = (phuff_entropy_ptr) 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; +} + + +/* + * 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 */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) 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_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Al = cinfo->Al; + register int s, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state 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_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++) { + 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_ptr entropy = (phuff_entropy_ptr) 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_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. + * 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_ptr entropy = (phuff_entropy_ptr) 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_restart(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_ptr entropy = (phuff_entropy_ptr) 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_restart(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_ptr entropy; + int *coef_bit_ptr; + int ci, i; + + entropy = (phuff_entropy_ptr) + (*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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdpostct.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdpostct.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdpostct.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdpostct.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,290 @@ +/* + * jdpostct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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); + } + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdsample.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdsample.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdsample.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdsample.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,478 @@ +/* + * jdsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains upsampling routines. + * + * Upsampling 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. Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) 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_ptr upsample = (my_upsample_ptr) 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_ptr upsample = (my_upsample_ptr) 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_ptr 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_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_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); + } + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdtrans.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdtrans.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jdtrans.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jdtrans.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * jdtrans.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* 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; + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jerror.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jerror.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jerror.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jerror.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,253 @@ +/* + * jerror.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do. Many applications will want to replace + * some or all of these routines. + * + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, + * you get a Windows-specific hack to display error messages in a dialog box. + * It ain't much, but it beats dropping error messages into the bit bucket, + * which is what happens to output to stderr under most Windows C compilers. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" +#include + +#ifdef USE_WINDOWS_MESSAGEBOX +#include +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" + NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error. Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object. Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF(void) +error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + exit(EXIT_FAILURE); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; + * + * cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL(struct jpeg_error_mgr *) +jpeg_std_error (struct jpeg_error_mgr * err) +{ + err->error_exit = error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jerror.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jerror.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jerror.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jerror.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,292 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctflt.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctflt.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctflt.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctflt.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,168 @@ +/* + * jfdctflt.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctfst.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctfst.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctfst.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctfst.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,224 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctint.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctint.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jfdctint.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jfdctint.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,283 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctflt.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctflt.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctflt.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctflt.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,242 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctfst.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctfst.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctfst.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctfst.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,368 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctint.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctint.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctint.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctint.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,389 @@ +/* + * jidctint.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctred.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctred.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jidctred.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jidctred.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,398 @@ +/* + * jidctred.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains inverse-DCT routines that produce reduced-size output: + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + * + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + * with an 8-to-4 step that produces the four averages of two adjacent outputs + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + * These steps were derived by computing the corresponding values at the end + * of the normal LL&M code, then simplifying as much as possible. + * + * 1x1 is trivial: just take the DC coefficient divided by 8. + * + * See jidctint.c for additional comments. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jinclude.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jinclude.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jinclude.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jinclude.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "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 . + * Otherwise, we get them from or ; we may have to + * pull in as well. + * Note that the core JPEG library does not require ; + * 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 . + */ + +#ifdef HAVE_STDDEF_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef NEED_SYS_TYPES_H +#include +#endif + +#include + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in . + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in . + * + * 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 +#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 +#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))) diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemansi.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemansi.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemansi.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemansi.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,167 @@ +/* + * jmemansi.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a simple generic implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that you have the ANSI-standard library routine tmpfile(). + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#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. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); + /* Since this implementation uses tmpfile() to create the file, + * no explicit file deletion is needed. + */ +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses tmpfile(), which constructs a suitable file name + * behind the scenes. We don't have to use info->temp_name[] at all; + * indeed, we can't even find out the actual name of the temp file. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + if ((info->temp_file = tmpfile()) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemmgr.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemmgr.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemmgr.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemmgr.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1121 @@ +/* + * jmemmgr.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the JPEG system-independent memory management + * routines. This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + * * pool-based allocation and freeing of memory; + * * policy decisions about how to divide available memory among the + * virtual arrays; + * * control logic for swapping virtual arrays between main memory and + * backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems. For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed. (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H /* should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + +#if defined _MSC_VER && _MSC_VER >= 1400 +#pragma warning(disable: 4267) +#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 + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemsys.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemsys.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmemsys.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmemsys.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,198 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. + */ + + +/* 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 +#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, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr 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, + backing_store_ptr 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)); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmorecfg.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmorecfg.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jmorecfg.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jmorecfg.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jpegint.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jpegint.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jpegint.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jpegint.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,392 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jpeglib.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jpeglib.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jpeglib.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jpeglib.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1116 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* HJH modification: protect compiler options for structure alignment and enum + * size if the compiler is Borland C++ */ +#ifdef __BORLANDC__ +#pragma option push -b +#pragma option push -a4 +#endif + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#ifdef __BORLANDC__ +#pragma option pop /* pop -a switch */ +#pragma option pop /* pop -b */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* JPEGLIB_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jquant1.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jquant1.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jquant1.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jquant1.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,856 @@ +/* + * jquant1.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 1-pass color quantization (color mapping) routines. + * These routines provide mapping to a fixed color map using equally spaced + * color values. Optional Floyd-Steinberg or ordered dithering is available. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jquant2.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jquant2.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jquant2.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jquant2.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1310 @@ +/* + * jquant2.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 2-pass color quantization (color mapping) routines. + * These routines provide selection of a custom color map for an image, + * followed by mapping of the image to that color map, with optional + * Floyd-Steinberg dithering. + * It is also possible to use just the second pass to map to an arbitrary + * externally-given color map. + * + * Note: ordered dithering is not supported, since there isn't any fast + * way to compute intercolor distances; it's unclear that ordered dither's + * fundamental assumptions even hold with an irregularly spaced color map. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#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<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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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<>1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1<>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<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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize = (my_cquantize_ptr) 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_ptr cquantize; + int i; + + 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_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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jutils.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jutils.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jutils.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jutils.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * jutils.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * 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 +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jversion.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jversion.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/jversion.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/jversion.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6b 27-Mar-1998" + +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/libjpeg.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/libjpeg.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/libjpeg.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/libjpeg.pro 2013-05-05 17:07:20.000000000 +0000 @@ -0,0 +1,17 @@ + + +TEMPLATE = lib +TARGET = jpeg + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.c + + +INCLUDEPATH += ./ + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/transupp.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/transupp.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/transupp.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/transupp.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1533 @@ +/* + * transupp.c + * + * Copyright (C) 1997-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains image transformation routines and other utility code + * used by the jpegtran sample application. These are NOT part of the core + * JPEG library. But we keep these routines separate from jpegtran.c to + * ease the task of maintaining jpegtran-like programs that have other user + * interfaces. + */ + +/* 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 + +#include "jinclude.h" +#include "jpeglib.h" +#include "transupp.h" /* My own external interface */ +#include /* to declare isdigit() */ + + +#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, + * and to Ben Jackson for introducing the cropping 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. + * + * If cropping or trimming is involved, the destination arrays may be smaller + * than the source arrays. Note it is not possible to do horizontal flip + * in-place when a nonzero Y crop offset is specified, since we'd have to move + * data from one block row to another but the virtual array manager doesn't + * guarantee we can touch more than one row at a time. So in that case, + * we have to use a separate destination array. + * + * 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. When "crop" is in effect, the destination's dimensions will be the + * cropped values but the source's will be uncropped. Each transform + * routine is responsible for picking up source data starting at the + * correct X and Y offset for the crop region. (The X and Y offsets + * passed to the transform routines are measured in iMCU blocks of the + * destination.) + * 6. 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. + */ + + +LOCAL(void) +do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Crop. This is only used when no rotate/flip is requested with the crop. */ +{ + JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks; + int ci, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + jpeg_component_info *compptr; + + /* We simply have to copy the right amount of data (the destination's + * image size) starting at the given X and Y offsets in the source. + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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); + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, + dst_buffer[offset_y], + compptr->width_in_blocks); + } + } + } +} + + +LOCAL(void) +do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, + jvirt_barray_ptr *src_coef_arrays) +/* Horizontal flip; done in-place, so no separate dest array is required. + * NB: this only works when y_crop_offset is zero. + */ +{ + JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks; + 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 = srcinfo->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; + x_crop_blocks = x_crop_offset * 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++) { + /* Do the mirroring */ + 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; + } + } + if (x_crop_blocks > 0) { + /* Now left-justify the portion of the data to be kept. + * We can't use a single jcopy_block_row() call because that routine + * depends on memcpy(), whose behavior is unspecified for overlapping + * source and destination areas. Sigh. + */ + for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { + jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks, + buffer[offset_y] + blk_x, + (JDIMENSION) 1); + } + } + } + } + } +} + + +LOCAL(void) +do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Horizontal flip in general cropping case */ +{ + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, k, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Here we must output into a separate array because we can't touch + * different rows of a single virtual array simultaneously. Otherwise, + * this is essentially the same as the routine above. + */ + MCU_cols = srcinfo->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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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); + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[offset_y]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Do the mirrorable blocks */ + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; + /* this unrolled loop doesn't need to know which row it's on... */ + for (k = 0; k < DCTSIZE2; k += 2) { + *dst_ptr++ = *src_ptr++; /* copy even column */ + *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */ + } + } else { + /* Copy last partial block(s) verbatim */ + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, + dst_row_ptr + dst_blk_x, + (JDIMENSION) 1); + } + } + } + } + } +} + + +LOCAL(void) +do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + 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; + JDIMENSION x_crop_blocks, y_crop_blocks; + 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 = srcinfo->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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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 (y_crop_blocks + 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 - y_crop_blocks - 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 + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (y_crop_blocks + 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]; + src_row_ptr += x_crop_blocks; + 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] + x_crop_blocks, + dst_buffer[offset_y], + compptr->width_in_blocks); + } + } + } + } +} + + +LOCAL(void) +do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Transpose source into destination */ +{ + JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks; + 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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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 + x_crop_blocks, + (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]; + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks]; + 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, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + 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; + JDIMENSION x_crop_blocks, y_crop_blocks; + 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 = srcinfo->image_height / (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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_width - x_crop_blocks - dst_blk_x - + (JDIMENSION) compptr->h_samp_factor, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } else { + /* Edge blocks are transposed but not mirrored. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (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 (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [dst_blk_y + offset_y + y_crop_blocks]; + 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. */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y + y_crop_blocks]; + 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, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + 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; + JDIMENSION x_crop_blocks, y_crop_blocks; + 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 = srcinfo->image_width / (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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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 + x_crop_blocks, + (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 (y_crop_blocks + dst_blk_y < comp_height) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[offset_x] + [comp_height - y_crop_blocks - 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 + y_crop_blocks]; + 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, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + 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; + JDIMENSION x_crop_blocks, y_crop_blocks; + 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 = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = srcinfo->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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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 (y_crop_blocks + 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 - y_crop_blocks - 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 + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + dst_row_ptr = dst_buffer[offset_y]; + if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + 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]; + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Process the blocks that can be mirrored both ways. */ + src_ptr = src_row_ptr[comp_width - x_crop_blocks - 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++; + } + } + } else { + /* Any remaining right-edge blocks are only mirrored vertically. */ + src_ptr = src_row_ptr[x_crop_blocks + 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. */ + src_row_ptr = src_buffer[offset_y]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Process the blocks that can be mirrored. */ + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE2; i += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + } else { + /* Any remaining right-edge blocks are only copied. */ + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, + dst_row_ptr + dst_blk_x, + (JDIMENSION) 1); + } + } + } + } + } + } +} + + +LOCAL(void) +do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + 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; + JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = srcinfo->image_width / (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; + x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + y_crop_blocks = y_crop_offset * 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) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_width - x_crop_blocks - dst_blk_x - + (JDIMENSION) compptr->h_samp_factor, + (JDIMENSION) compptr->h_samp_factor, FALSE); + } else { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + dst_blk_x + x_crop_blocks, + (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 (y_crop_blocks + dst_blk_y < comp_height) { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [comp_height - y_crop_blocks - 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]; + } + 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 */ + src_ptr = src_buffer[offset_x] + [comp_height - y_crop_blocks - 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 { + if (x_crop_blocks + dst_blk_x < comp_width) { + /* Bottom-edge blocks are mirrored in x only */ + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] + [dst_blk_y + offset_y + y_crop_blocks]; + 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 */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } + } +} + + +/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec. + * Returns TRUE if valid integer found, FALSE if not. + * *strptr is advanced over the digit string, and *result is set to its value. + */ + +LOCAL(boolean) +jt_read_integer (const char ** strptr, JDIMENSION * result) +{ + const char * ptr = *strptr; + JDIMENSION val = 0; + + for (; isdigit(*ptr); ptr++) { + val = val * 10 + (JDIMENSION) (*ptr - '0'); + } + *result = val; + if (ptr == *strptr) + return FALSE; /* oops, no digits */ + *strptr = ptr; + return TRUE; +} + + +/* Parse a crop specification (written in X11 geometry style). + * The routine returns TRUE if the spec string is valid, FALSE if not. + * + * The crop spec string should have the format + * x{+-}{+-} + * where width, height, xoffset, and yoffset are unsigned integers. + * Each of the elements can be omitted to indicate a default value. + * (A weakness of this style is that it is not possible to omit xoffset + * while specifying yoffset, since they look alike.) + * + * This code is loosely based on XParseGeometry from the X11 distribution. + */ + +GLOBAL(boolean) +jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec) +{ + info->crop = FALSE; + info->crop_width_set = JCROP_UNSET; + info->crop_height_set = JCROP_UNSET; + info->crop_xoffset_set = JCROP_UNSET; + info->crop_yoffset_set = JCROP_UNSET; + + if (isdigit(*spec)) { + /* fetch width */ + if (! jt_read_integer(&spec, &info->crop_width)) + return FALSE; + info->crop_width_set = JCROP_POS; + } + if (*spec == 'x' || *spec == 'X') { + /* fetch height */ + spec++; + if (! jt_read_integer(&spec, &info->crop_height)) + return FALSE; + info->crop_height_set = JCROP_POS; + } + if (*spec == '+' || *spec == '-') { + /* fetch xoffset */ + info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; + spec++; + if (! jt_read_integer(&spec, &info->crop_xoffset)) + return FALSE; + } + if (*spec == '+' || *spec == '-') { + /* fetch yoffset */ + info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; + spec++; + if (! jt_read_integer(&spec, &info->crop_yoffset)) + return FALSE; + } + /* We had better have gotten to the end of the string. */ + if (*spec != '\0') + return FALSE; + info->crop = TRUE; + return TRUE; +} + + +/* Trim off any partial iMCUs on the indicated destination edge */ + +LOCAL(void) +trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width) +{ + JDIMENSION MCU_cols; + + MCU_cols = info->output_width / (info->max_h_samp_factor * DCTSIZE); + if (MCU_cols > 0 && info->x_crop_offset + MCU_cols == + full_width / (info->max_h_samp_factor * DCTSIZE)) + info->output_width = MCU_cols * (info->max_h_samp_factor * DCTSIZE); +} + +LOCAL(void) +trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height) +{ + JDIMENSION MCU_rows; + + MCU_rows = info->output_height / (info->max_v_samp_factor * DCTSIZE); + if (MCU_rows > 0 && info->y_crop_offset + MCU_rows == + full_height / (info->max_v_samp_factor * DCTSIZE)) + info->output_height = MCU_rows * (info->max_v_samp_factor * DCTSIZE); +} + + +/* Request any required workspace. + * + * This routine figures out the size that the output image will be + * (which implies that all the transform parameters must be set before + * it is called). + * + * 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; + boolean need_workspace, transpose_it; + jpeg_component_info *compptr; + JDIMENSION xoffset, yoffset, width_in_iMCUs, height_in_iMCUs; + JDIMENSION width_in_blocks, height_in_blocks; + int ci, h_samp_factor, v_samp_factor; + + /* Determine number of components in output image */ + 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; + } + /* If there is only one output component, force the iMCU size to be 1; + * else use the source iMCU size. (This allows us to do the right thing + * when reducing color to grayscale, and also provides a handy way of + * cleaning up "funny" grayscale images whose sampling factors are not 1x1.) + */ + + switch (info->transform) { + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + info->output_width = srcinfo->image_height; + info->output_height = srcinfo->image_width; + if (info->num_components == 1) { + info->max_h_samp_factor = 1; + info->max_v_samp_factor = 1; + } else { + info->max_h_samp_factor = srcinfo->max_v_samp_factor; + info->max_v_samp_factor = srcinfo->max_h_samp_factor; + } + break; + default: + info->output_width = srcinfo->image_width; + info->output_height = srcinfo->image_height; + if (info->num_components == 1) { + info->max_h_samp_factor = 1; + info->max_v_samp_factor = 1; + } else { + info->max_h_samp_factor = srcinfo->max_h_samp_factor; + info->max_v_samp_factor = srcinfo->max_v_samp_factor; + } + break; + } + + /* If cropping has been requested, compute the crop area's position and + * dimensions, ensuring that its upper left corner falls at an iMCU boundary. + */ + if (info->crop) { + /* Insert default values for unset crop parameters */ + if (info->crop_xoffset_set == JCROP_UNSET) + info->crop_xoffset = 0; /* default to +0 */ + if (info->crop_yoffset_set == JCROP_UNSET) + info->crop_yoffset = 0; /* default to +0 */ + if (info->crop_xoffset >= info->output_width || + info->crop_yoffset >= info->output_height) + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); + if (info->crop_width_set == JCROP_UNSET) + info->crop_width = info->output_width - info->crop_xoffset; + if (info->crop_height_set == JCROP_UNSET) + info->crop_height = info->output_height - info->crop_yoffset; + /* Ensure parameters are valid */ + if (info->crop_width <= 0 || info->crop_width > info->output_width || + info->crop_height <= 0 || info->crop_height > info->output_height || + info->crop_xoffset > info->output_width - info->crop_width || + info->crop_yoffset > info->output_height - info->crop_height) + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); + /* Convert negative crop offsets into regular offsets */ + if (info->crop_xoffset_set == JCROP_NEG) + xoffset = info->output_width - info->crop_width - info->crop_xoffset; + else + xoffset = info->crop_xoffset; + if (info->crop_yoffset_set == JCROP_NEG) + yoffset = info->output_height - info->crop_height - info->crop_yoffset; + else + yoffset = info->crop_yoffset; + /* Now adjust so that upper left corner falls at an iMCU boundary */ + info->output_width = + info->crop_width + (xoffset % (info->max_h_samp_factor * DCTSIZE)); + info->output_height = + info->crop_height + (yoffset % (info->max_v_samp_factor * DCTSIZE)); + /* Save x/y offsets measured in iMCUs */ + info->x_crop_offset = xoffset / (info->max_h_samp_factor * DCTSIZE); + info->y_crop_offset = yoffset / (info->max_v_samp_factor * DCTSIZE); + } else { + info->x_crop_offset = 0; + info->y_crop_offset = 0; + } + + /* Figure out whether we need workspace arrays, + * and if so whether they are transposed relative to the source. + */ + need_workspace = FALSE; + transpose_it = FALSE; + switch (info->transform) { + case JXFORM_NONE: + if (info->x_crop_offset != 0 || info->y_crop_offset != 0) + need_workspace = TRUE; + /* No workspace needed if neither cropping nor transforming */ + break; + case JXFORM_FLIP_H: + if (info->trim) + trim_right_edge(info, srcinfo->image_width); + if (info->y_crop_offset != 0) + need_workspace = TRUE; + /* do_flip_h_no_crop doesn't need a workspace array */ + break; + case JXFORM_FLIP_V: + if (info->trim) + trim_bottom_edge(info, srcinfo->image_height); + /* Need workspace arrays having same dimensions as source image. */ + need_workspace = TRUE; + break; + case JXFORM_TRANSPOSE: + /* transpose does NOT have to trim anything */ + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_TRANSVERSE: + if (info->trim) { + trim_right_edge(info, srcinfo->image_height); + trim_bottom_edge(info, srcinfo->image_width); + } + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_ROT_90: + if (info->trim) + trim_right_edge(info, srcinfo->image_height); + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + case JXFORM_ROT_180: + if (info->trim) { + trim_right_edge(info, srcinfo->image_width); + trim_bottom_edge(info, srcinfo->image_height); + } + /* Need workspace arrays having same dimensions as source image. */ + need_workspace = TRUE; + break; + case JXFORM_ROT_270: + if (info->trim) + trim_bottom_edge(info, srcinfo->image_width); + /* Need workspace arrays having transposed dimensions. */ + need_workspace = TRUE; + transpose_it = TRUE; + break; + } + + /* Allocate workspace if needed. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + if (need_workspace) { + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, + SIZEOF(jvirt_barray_ptr) * info->num_components); + width_in_iMCUs = (JDIMENSION) + jdiv_round_up((long) info->output_width, + (long) (info->max_h_samp_factor * DCTSIZE)); + height_in_iMCUs = (JDIMENSION) + jdiv_round_up((long) info->output_height, + (long) (info->max_v_samp_factor * DCTSIZE)); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + if (info->num_components == 1) { + /* we're going to force samp factors to 1x1 in this case */ + h_samp_factor = v_samp_factor = 1; + } else if (transpose_it) { + h_samp_factor = compptr->v_samp_factor; + v_samp_factor = compptr->h_samp_factor; + } else { + h_samp_factor = compptr->h_samp_factor; + v_samp_factor = compptr->v_samp_factor; + } + width_in_blocks = width_in_iMCUs * h_samp_factor; + height_in_blocks = height_in_iMCUs * v_samp_factor; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, + width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor); + } + } + + 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; + UINT16 qtemp; + + /* 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; + } + } + } + } +} + + +/* Adjust Exif image parameters. + * + * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. + */ + +LOCAL(void) +adjust_exif_parameters (JOCTET FAR * data, unsigned int length, + JDIMENSION new_width, JDIMENSION new_height) +{ + boolean is_motorola; /* Flag for byte order */ + unsigned int number_of_tags, tagnum; + unsigned int firstoffset, offset; + JDIMENSION new_value; + + if (length < 12) return; /* Length of an IFD entry */ + + /* Discover byte order */ + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) + is_motorola = FALSE; + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) + is_motorola = TRUE; + else + return; + + /* Check Tag Mark */ + if (is_motorola) { + if (GETJOCTET(data[2]) != 0) return; + if (GETJOCTET(data[3]) != 0x2A) return; + } else { + if (GETJOCTET(data[3]) != 0) return; + if (GETJOCTET(data[2]) != 0x2A) return; + } + + /* Get first IFD offset (offset to IFD0) */ + if (is_motorola) { + if (GETJOCTET(data[4]) != 0) return; + if (GETJOCTET(data[5]) != 0) return; + firstoffset = GETJOCTET(data[6]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[7]); + } else { + if (GETJOCTET(data[7]) != 0) return; + if (GETJOCTET(data[6]) != 0) return; + firstoffset = GETJOCTET(data[5]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[4]); + } + if (firstoffset > length - 2) return; /* check end of data segment */ + + /* Get the number of directory entries contained in this IFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[firstoffset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset+1]); + } else { + number_of_tags = GETJOCTET(data[firstoffset+1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset]); + } + if (number_of_tags == 0) return; + firstoffset += 2; + + /* Search for ExifSubIFD offset Tag in IFD0 */ + for (;;) { + if (firstoffset > length - 12) return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[firstoffset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset+1]); + } else { + tagnum = GETJOCTET(data[firstoffset+1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset]); + } + if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */ + if (--number_of_tags == 0) return; + firstoffset += 12; + } + + /* Get the ExifSubIFD offset */ + if (is_motorola) { + if (GETJOCTET(data[firstoffset+8]) != 0) return; + if (GETJOCTET(data[firstoffset+9]) != 0) return; + offset = GETJOCTET(data[firstoffset+10]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset+11]); + } else { + if (GETJOCTET(data[firstoffset+11]) != 0) return; + if (GETJOCTET(data[firstoffset+10]) != 0) return; + offset = GETJOCTET(data[firstoffset+9]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset+8]); + } + if (offset > length - 2) return; /* check end of data segment */ + + /* Get the number of directory entries contained in this SubIFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[offset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset+1]); + } else { + number_of_tags = GETJOCTET(data[offset+1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset]); + } + if (number_of_tags < 2) return; + offset += 2; + + /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ + do { + if (offset > length - 12) return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[offset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset+1]); + } else { + tagnum = GETJOCTET(data[offset+1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset]); + } + if (tagnum == 0xA002 || tagnum == 0xA003) { + if (tagnum == 0xA002) + new_value = new_width; /* ExifImageWidth Tag */ + else + new_value = new_height; /* ExifImageHeight Tag */ + if (is_motorola) { + data[offset+2] = 0; /* Format = unsigned long (4 octets) */ + data[offset+3] = 4; + data[offset+4] = 0; /* Number Of Components = 1 */ + data[offset+5] = 0; + data[offset+6] = 0; + data[offset+7] = 1; + data[offset+8] = 0; + data[offset+9] = 0; + data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); + data[offset+11] = (JOCTET)(new_value & 0xFF); + } else { + data[offset+2] = 4; /* Format = unsigned long (4 octets) */ + data[offset+3] = 0; + data[offset+4] = 1; /* Number Of Components = 1 */ + data[offset+5] = 0; + data[offset+6] = 0; + data[offset+7] = 0; + data[offset+8] = (JOCTET)(new_value & 0xFF); + data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); + data[offset+10] = 0; + data[offset+11] = 0; + } + } + offset += 12; + } while (--number_of_tags); +} + + +/* 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) { + /* First, ensure we have YCbCr or grayscale data, and that the source's + * Y channel is full resolution. (No reasonable person would make Y + * be less than full resolution, so actually coping with that case + * isn't worth extra code space. But we check it to avoid crashing.) + */ + if (((dstinfo->jpeg_color_space == JCS_YCbCr && + dstinfo->num_components == 3) || + (dstinfo->jpeg_color_space == JCS_GRAYSCALE && + dstinfo->num_components == 1)) && + srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor && + srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) { + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed + * properly. Among other things, it sets the target h_samp_factor & + * v_samp_factor to 1, which typically won't match the source. + * We have to preserve the source's quantization table number, however. + */ + 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); + } + } else if (info->num_components == 1) { + /* For a single-component source, we force the destination sampling factors + * to 1x1, with or without force_grayscale. This is useful because some + * decoders choke on grayscale images with other sampling factors. + */ + dstinfo->comp_info[0].h_samp_factor = 1; + dstinfo->comp_info[0].v_samp_factor = 1; + } + + /* Correct the destination's image dimensions as necessary + * for crop and rotate/flip operations. + */ + dstinfo->image_width = info->output_width; + dstinfo->image_height = info->output_height; + + /* Transpose destination image parameters */ + switch (info->transform) { + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + transpose_critical_parameters(dstinfo); + break; + default: + break; + } + + /* Adjust Exif properties */ + if (srcinfo->marker_list != NULL && + srcinfo->marker_list->marker == JPEG_APP0+1 && + srcinfo->marker_list->data_length >= 6 && + GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 && + GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 && + GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 && + GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 && + GETJOCTET(srcinfo->marker_list->data[4]) == 0 && + GETJOCTET(srcinfo->marker_list->data[5]) == 0) { + /* Suppress output of JFIF marker */ + dstinfo->write_JFIF_header = FALSE; + /* Adjust Exif image parameters */ + if (dstinfo->image_width != srcinfo->image_width || + dstinfo->image_height != srcinfo->image_height) + /* Align data segment to start of TIFF structure for parsing */ + adjust_exif_parameters(srcinfo->marker_list->data + 6, + srcinfo->marker_list->data_length - 6, + dstinfo->image_width, dstinfo->image_height); + } + + /* 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_transform (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; + + /* Note: conditions tested here should match those in switch statement + * in jtransform_request_workspace() + */ + switch (info->transform) { + case JXFORM_NONE: + if (info->x_crop_offset != 0 || info->y_crop_offset != 0) + do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_FLIP_H: + if (info->y_crop_offset != 0) + do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + else + do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset, + src_coef_arrays); + break; + case JXFORM_FLIP_V: + do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSPOSE: + do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSVERSE: + do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_90: + do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_180: + do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_270: + do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, + src_coef_arrays, dst_coef_arrays); + break; + } +} + +/* jtransform_perfect_transform + * + * Determine whether lossless transformation is perfectly + * possible for a specified image and transformation. + * + * Inputs: + * image_width, image_height: source image dimensions. + * MCU_width, MCU_height: pixel dimensions of MCU. + * transform: transformation identifier. + * Parameter sources from initialized jpeg_struct + * (after reading source header): + * image_width = cinfo.image_width + * image_height = cinfo.image_height + * MCU_width = cinfo.max_h_samp_factor * DCTSIZE + * MCU_height = cinfo.max_v_samp_factor * DCTSIZE + * Result: + * TRUE = perfect transformation possible + * FALSE = perfect transformation not possible + * (may use custom action then) + */ + +GLOBAL(boolean) +jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height, + int MCU_width, int MCU_height, + JXFORM_CODE transform) +{ + boolean result = TRUE; /* initialize TRUE */ + + switch (transform) { + case JXFORM_FLIP_H: + case JXFORM_ROT_270: + if (image_width % (JDIMENSION) MCU_width) + result = FALSE; + break; + case JXFORM_FLIP_V: + case JXFORM_ROT_90: + if (image_height % (JDIMENSION) MCU_height) + result = FALSE; + break; + case JXFORM_TRANSVERSE: + case JXFORM_ROT_180: + if (image_width % (JDIMENSION) MCU_width) + result = FALSE; + if (image_height % (JDIMENSION) MCU_height) + result = FALSE; + break; + default: + break; + } + + return result; +} + +#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 + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/transupp.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/transupp.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libjpeg/transupp.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libjpeg/transupp.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,205 @@ +/* + * transupp.h + * + * Copyright (C) 1997-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for image transformation routines and + * other utility code used by the jpegtran sample application. These are + * NOT part of the core JPEG library. But we keep these routines separate + * from jpegtran.c to ease the task of maintaining jpegtran-like programs + * that have other user interfaces. + * + * NOTE: all the routines declared here have very specific requirements + * about when they are to be executed during the reading and writing of the + * source and destination files. See the comments in transupp.c, or see + * jpegtran.c for an example of correct usage. + */ + +/* 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 + +/* + * 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 lossless-crop option, which discards data outside a given + * image region but losslessly preserves what is inside. Like the rotate and + * flip transforms, lossless crop is restricted by the JPEG format: the upper + * left corner of the selected region must fall on an iMCU boundary. If this + * does not hold for the given crop parameters, we silently move the upper left + * corner up and/or left to make it so, simultaneously increasing the region + * dimensions to keep the lower right crop corner unchanged. (Thus, the + * output image covers at least the requested region, but may cover more.) + * + * If both crop and a rotate/flip transform are requested, the crop is applied + * last --- that is, the crop region is specified in terms of the destination + * image. + * + * 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. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jtransform_parse_crop_spec jTrParCrop +#define jtransform_request_workspace jTrRequest +#define jtransform_adjust_parameters jTrAdjust +#define jtransform_execute_transform jTrExec +#define jtransform_perfect_transform jTrPerfect +#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; + +/* + * Codes for crop parameters, which can individually be unspecified, + * positive, or negative. (Negative width or height makes no sense, though.) + */ + +typedef enum { + JCROP_UNSET, + JCROP_POS, + JCROP_NEG +} JCROP_CODE; + +/* + * Transform parameters struct. + * NB: application must not change any elements of this struct after + * calling jtransform_request_workspace. + */ + +typedef struct { + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + boolean perfect; /* if TRUE, fail if partial MCUs are requested */ + boolean trim; /* if TRUE, trim partial MCUs as needed */ + boolean force_grayscale; /* if TRUE, convert color image to grayscale */ + boolean crop; /* if TRUE, crop source image */ + + /* Crop parameters: application need not set these unless crop is TRUE. + * These can be filled in by jtransform_parse_crop_spec(). + */ + JDIMENSION crop_width; /* Width of selected region */ + JCROP_CODE crop_width_set; + JDIMENSION crop_height; /* Height of selected region */ + JCROP_CODE crop_height_set; + JDIMENSION crop_xoffset; /* X offset of selected region */ + JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */ + JDIMENSION crop_yoffset; /* Y offset of selected region */ + JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ + JDIMENSION output_width; /* cropped destination dimensions */ + JDIMENSION output_height; + JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */ + JDIMENSION y_crop_offset; + int max_h_samp_factor; /* destination iMCU size */ + int max_v_samp_factor; +} jpeg_transform_info; + + +#if TRANSFORMS_SUPPORTED + +/* Parse a crop specification (written in X11 geometry style) */ +EXTERN(boolean) jtransform_parse_crop_spec + JPP((jpeg_transform_info *info, const char *spec)); +/* 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_transform + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Determine whether lossless transformation is perfectly + * possible for a specified image and transformation. + */ +EXTERN(boolean) jtransform_perfect_transform + JPP((JDIMENSION image_width, JDIMENSION image_height, + int MCU_width, int MCU_height, + JXFORM_CODE transform)); + +/* jtransform_execute_transform used to be called + * jtransform_execute_transformation, but some compilers complain about + * routine names that long. This macro is here to avoid breaking any + * old source code that uses the original name... + */ +#define jtransform_execute_transformation jtransform_execute_transform + +#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)); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/CHANGES diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/CHANGES --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/CHANGES 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/CHANGES 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3906 @@ +#if 0 +CHANGES - changes for libpng + +Version 0.2 + added reader into png.h + fixed small problems in stub file + +Version 0.3 + added pull reader + split up pngwrite.c to several files + added pnglib.txt + added example.c + cleaned up writer, adding a few new transformations + fixed some bugs in writer + interfaced with zlib 0.5 + added K&R support + added check for 64 KB blocks for 16-bit machines + +Version 0.4 + cleaned up code and commented code + simplified time handling into png_time + created png_color_16 and png_color_8 to handle color needs + cleaned up color type defines + fixed various bugs + made various names more consistent + interfaced with zlib 0.71 + cleaned up zTXt reader and writer (using zlib's Reset functions) + split transformations into pngrtran.c and pngwtran.c + +Version 0.5 + interfaced with zlib 0.8 + fixed many reading and writing bugs + saved using 3 spaces instead of tabs + +Version 0.6 + added png_large_malloc() and png_large_free() + added png_size_t + cleaned up some compiler warnings + added png_start_read_image() + +Version 0.7 + cleaned up lots of bugs + finished dithering and other stuff + added test program + changed name from pnglib to libpng + +Version 0.71 [June, 1995] + changed pngtest.png for zlib 0.93 + fixed error in libpng.txt and example.c + +Version 0.8 + cleaned up some bugs + added png_set_filler() + split up pngstub.c into pngmem.c, pngio.c, and pngerror.c + added #define's to remove unwanted code + moved png_info_init() to png.c + added old_size into png_realloc() + added functions to manually set filtering and compression info + changed compression parameters based on image type + optimized filter selection code + added version info + changed external functions passing floats to doubles (k&r problems?) + put all the configurable stuff in pngconf.h + enabled png_set_shift to work with paletted images on read + added png_read_update_info() - updates info structure with transformations + +Version 0.81 [August, 1995] + incorporated Tim Wegner's medium model code (thanks, Tim) + +Version 0.82 [September, 1995] + [unspecified changes] + +Version 0.85 [December, 1995] + added more medium model code (almost everything's a far) + added i/o, error, and memory callback functions + fixed some bugs (16-bit, 4-bit interlaced, etc.) + added first run progressive reader (barely tested) + +Version 0.86 [January, 1996] + fixed bugs + improved documentation + +Version 0.87 [January, 1996] + fixed medium model bugs + fixed other bugs introduced in 0.85 and 0.86 + added some minor documentation + +Version 0.88 [January, 1996] + fixed progressive bugs + replaced tabs with spaces + cleaned up documentation + added callbacks for read/write and warning/error functions + +Version 0.89 [July, 1996] + Added new initialization API to make libpng work better with shared libs + we now have png_create_read_struct(), png_create_write_struct(), + png_create_info_struct(), png_destroy_read_struct(), and + png_destroy_write_struct() instead of the separate calls to + malloc and png_read_init(), png_info_init(), and png_write_init() + Changed warning/error callback functions to fix bug - this means you + should use the new initialization API if you were using the old + png_set_message_fn() calls, and that the old API no longer exists + so that people are aware that they need to change their code + Changed filter selection API to allow selection of multiple filters + since it didn't work in previous versions of libpng anyways + Optimized filter selection code + Fixed png_set_background() to allow using an arbitrary RGB color for + paletted images + Fixed gamma and background correction for paletted images, so + png_correct_palette is not needed unless you are correcting an + external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED + in pngconf.h) - if nobody uses this, it may disappear in the future. + Fixed bug with Borland 64K memory allocation (Alexander Lehmann) + Fixed bug in interlace handling (Smarasderagd, I think) + Added more error checking for writing and image to reduce invalid files + Separated read and write functions so that they won't both be linked + into a binary when only reading or writing functionality is used + New pngtest image also has interlacing and zTXt + Updated documentation to reflect new API + +Version 0.90 [January, 1997] + Made CRC errors/warnings on critical and ancillary chunks configurable + libpng will use the zlib CRC routines by (compile-time) default + Changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) + Added external C++ wrapper statements to png.h (Gilles Dauphin) + Allow PNG file to be read when some or all of file signature has already + been read from the beginning of the stream. ****This affects the size + of info_struct and invalidates all programs that use a shared libpng**** + Fixed png_filler() declarations + Fixed? background color conversions + Fixed order of error function pointers to match documentation + Current chunk name is now available in png_struct to reduce the number + of nearly identical error messages (will simplify multi-lingual + support when available) + Try to get ready for unknown-chunk callback functions: + - previously read critical chunks are flagged, so the chunk handling + routines can determine if the chunk is in the right place + - all chunk handling routines have the same prototypes, so we will + be able to handle all chunks via a callback mechanism + Try to fix Linux "setjmp" buffer size problems + Removed png_large_malloc, png_large_free, and png_realloc functions. + +Version 0.95 [March, 1997] + Fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never + Fixed bug in PNG file signature compares when start != 0 + Changed parameter type of png_set_filler(...filler...) from png_byte + to png_uint_32 + Added test for MACOS to ensure that both math.h and fp.h are not #included + Added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) + Added "packswap" transformation, which changes the endianness of + packed-pixel bytes (Kevin Bracey) + Added "strip_alpha" transformation, which removes the alpha channel of + input images without using it (not necessarily a good idea) + Added "swap_alpha" transformation, which puts the alpha channel in front + of the color bytes instead of after + Removed all implicit variable tests which assume NULL == 0 (I think) + Changed several variables to "png_size_t" to show 16/32-bit limitations + Added new pCAL chunk read/write support + Added experimental filter selection weighting (Greg Roelofs) + Removed old png_set_rgbx() and png_set_xrgb() functions that have been + obsolete for about 2 years now (use png_set_filler() instead) + Added macros to read 16- and 32-bit ints directly from buffer, to be + used only on those systems that support it (namely PowerPC and 680x0) + With some testing, this may become the default for MACOS/PPC systems. + Only calculate CRC on data if we are going to use it + Added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? + Added macros for simple libpng debugging output selectable at compile time + Removed PNG_READ_END_MODE in progressive reader (Smarasderagd) + More description of info_struct in libpng.txt and png.h + More instructions in example.c + More chunk types tested in pngtest.c + Renamed pngrcb.c to pngset.c, and all png_read_ functions to be + png_set_. We now have corresponding png_get_ + functions in pngget.c to get information in info_ptr. This isolates + the application from the internal organization of png_info_struct + (good for shared library implementations). + +Version 0.96 [May, 1997] + Fixed serious bug with < 8bpp images introduced in 0.95 + Fixed 256-color transparency bug (Greg Roelofs) + Fixed up documentation (Greg Roelofs, Laszlo Nyul) + Fixed "error" in pngconf.h for Linux setjmp() behavior + Fixed DOS medium model support (Tim Wegner) + Fixed png_check_keyword() for case with error in static string text + Added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) + Added typecasts to quiet compiler errors + Added more debugging info + +Version 0.97 [January, 1998] + Removed PNG_USE_OWN_CRC capability + Relocated png_set_crc_action from pngrutil.c to pngrtran.c + Fixed typecasts of "new_key", etc. (Andreas Dilger) + Added RFC 1152 [sic] date support + Fixed bug in gamma handling of 4-bit grayscale + Added 2-bit grayscale gamma handling (Glenn R-P) + Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) + Minor corrections in libpng.txt + Added simple sRGB support (Glenn R-P) + Easier conditional compiling, e.g., + define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; + all configurable options can be selected from command-line instead + of having to edit pngconf.h (Glenn R-P) + Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) + Added more conditions for png_do_background, to avoid changing + black pixels to background when a background is supplied and + no pixels are transparent + Repaired PNG_NO_STDIO behavior + Tested NODIV support and made it default behavior (Greg Roelofs) + Added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) + Regularized version numbering scheme and bumped shared-library major + version number to 2 to avoid problems with libpng 0.89 apps + (Greg Roelofs) + +Version 0.98 [January, 1998] + Cleaned up some typos in libpng.txt and in code documentation + Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) + Cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c + Changed recommendation about file_gamma for PC images to .51 from .45, + in example.c and libpng.txt, added comments to distinguish between + screen_gamma, viewing_gamma, and display_gamma. + Changed all references to RFC1152 to read RFC1123 and changed the + PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED + Added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) + Changed srgb_intent from png_byte to int to avoid compiler bugs + +Version 0.99 [January 30, 1998] + Free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) + Fixed a longstanding "packswap" bug in pngtrans.c + Fixed some inconsistencies in pngconf.h that prevented compiling with + PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined + Fixed some typos and made other minor rearrangement of libpng.txt (Andreas) + Changed recommendation about file_gamma for PC images to .50 from .51 in + example.c and libpng.txt, and changed file_gamma for sRGB images to .45 + Added a number of functions to access information from the png structure + png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) + Added TARGET_MACOS similar to zlib-1.0.8 + Define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined + Added type casting to all png_malloc() function calls + +Version 0.99a [January 31, 1998] + Added type casts and parentheses to all returns that return a value.(Tim W.) + +Version 0.99b [February 4, 1998] + Added type cast png_uint_32 on malloc function calls where needed. + Changed type of num_hist from png_uint_32 to int (same as num_palette). + Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. + Renamed makefile.elf to makefile.lnx. + +Version 0.99c [February 7, 1998] + More type casting. Removed erroneous overflow test in pngmem.c. + Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. + Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. + +Version 0.99d [February 11, 1998] + Renamed "far_to_near()" "png_far_to_near()" + Revised libpng.3 + Version 99c "buffered" operations didn't work as intended. Replaced them + with png_memcpy_check() and png_memset_check(). + Added many "if (png_ptr == NULL) return" to quell compiler warnings about + unused png_ptr, mostly in pngget.c and pngset.c. + Check for overlength tRNS chunk present when indexed-color PLTE is read. + Cleaned up spelling errors in libpng.3/libpng.txt + Corrected a problem with png_get_tRNS() which returned undefined trans array + +Version 0.99e [February 28, 1998] + Corrected png_get_tRNS() again. + Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". + Touched up example.c to make more of it compileable, although the entire + file still can't be compiled (Willem van Schaik) + Fixed a bug in png_do_shift() (Bryan Tsai) + Added a space in png.h prototype for png_write_chunk_start() + Replaced pngtest.png with one created with zlib 1.1.1 + Changed pngtest to report PASS even when file size is different (Jean-loup G.) + Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) + +Version 0.99f [March 5, 1998] + Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) + Moved makefiles into a "scripts" directory, and added INSTALL instruction file + Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) + Added pointers to "note on libpng versions" in makefile.lnx and README + Added row callback feature when reading and writing nonprogressive rows + and added a test of this feature in pngtest.c + Added user transform callbacks, with test of the feature in pngtest.c + +Version 0.99g [March 6, 1998, morning] + Minor changes to pngtest.c to suppress compiler warnings. + Removed "beta" language from documentation. + +Version 0.99h [March 6, 1998, evening] + Minor changes to previous minor changes to pngtest.c + Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED + and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro + Added user transform capability + +Version 1.00 [March 7, 1998] + Changed several typedefs in pngrutil.c + Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) + Replaced "while(1)" with "for(;;)" + Added PNGARG() to prototypes in pngtest.c and removed some prototypes + Updated some of the makefiles (Tom Lane) + Changed some typedefs (s_start, etc.) in pngrutil.c + Fixed dimensions of "short_months" array in pngwrite.c + Replaced ansi2knr.c with the one from jpeg-v6 + +Version 1.0.0 [March 8, 1998] + Changed name from 1.00 to 1.0.0 (Adam Costello) + Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) + +Version 1.0.0a [March 9, 1998] + Fixed three bugs in pngrtran.c to make gamma+background handling consistent + (Greg Roelofs) + Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz + for major, minor, and bugfix releases. This is 10001. (Adam Costello, + Tom Lane) + Make months range from 1-12 in png_convert_to_rfc1123 + +Version 1.0.0b [March 13, 1998] + Quieted compiler complaints about two empty "for" loops in pngrutil.c + Minor changes to makefile.s2x + Removed #ifdef/#endif around a png_free() in pngread.c + +Version 1.0.1 [March 14, 1998] + Changed makefile.s2x to reduce security risk of using a relative pathname + Fixed some typos in the documentation (Greg). + Fixed a problem with value of "channels" returned by png_read_update_info() + +Version 1.0.1a [April 21, 1998] + Optimized Paeth calculations by replacing abs() function calls with intrinsics + plus other loop optimizations. Improves avg decoding speed by about 20%. + Commented out i386istic "align" compiler flags in makefile.lnx. + Reduced the default warning level in some makefiles, to make them consistent. + Removed references to IJG and JPEG in the ansi2knr.c copyright statement. + Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. + Added grayscale and 16-bit capability to png_do_read_filler(). + Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes + too large when writing an image with bit_depth < 8 (Bob Dellaca). + Corrected some bugs in the experimental weighted filtering heuristics. + Moved a misplaced pngrutil code block that truncates tRNS if it has more + than num_palette entries -- test was done before num_palette was defined. + Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). + Changed compiler flags in makefile.wat for better optimization + (Pawel Mrochen). + +Version 1.0.1b [May 2, 1998] + Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). + Relocated the png_composite macros from pngrtran.c to png.h (Greg). + Added makefile.sco (contributed by Mike Hopkirk). + Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. + Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. + More work on the Paeth-filtering, achieving imperceptible speedup + (A Kleinert). + More work on loop optimization which may help when compiled with C++ + compilers. + Added warnings when people try to use transforms they've defined out. + Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. + Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) + +Version 1.0.1c [May 11, 1998] + Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for + filler bytes should have been 0xff instead of 0xf. + Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. + Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED + out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h + Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, + for consistency, in pngconf.h + Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier + to remove unwanted capabilities via the compile line + Made some corrections to grammar (which, it's) in documentation (Greg). + Corrected example.c, use of row_pointers in png_write_image(). + +Version 1.0.1d [May 24, 1998] + Corrected several statements that used side effects illegally in pngrutil.c + and pngtrans.c, that were introduced in version 1.0.1b + Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) + More corrections to example.c, use of row_pointers in png_write_image() + and png_read_rows(). + Added pngdll.mak and pngdef.pas to scripts directory, contributed by + Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 + Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) + Changed several loops from count-down to count-up, for consistency. + +Version 1.0.1e [June 6, 1998] + Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and + added warnings when people try to set png_read_fn and png_write_fn in + the same structure. + Added a test such that png_do_gamma will be done when num_trans==0 + for truecolor images that have defined a background. This corrects an + error that was introduced in libpng-0.90 that can cause gamma processing + to be skipped. + Added tests in png.h to include "trans" and "trans_values" in structures + when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. + Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() + Moved png_convert_to_rfc_1123() from pngwrite.c to png.c + Added capability for user-provided malloc_fn() and free_fn() functions, + and revised pngtest.c to demonstrate their use, replacing the + PNGTEST_DEBUG_MEM feature. + Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). + +Version 1.0.2 [June 14, 1998] + Fixed two bugs in makefile.bor . + +Version 1.0.2a [December 30, 1998] + Replaced and extended code that was removed from png_set_filler() in 1.0.1a. + Fixed a bug in png_do_filler() that made it fail to write filler bytes in + the left-most pixel of each row (Kevin Bracey). + Changed "static pngcharp tIME_string" to "static char tIME_string[30]" + in pngtest.c (Duncan Simpson). + Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk + even when no tIME chunk was present in the source file. + Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. + Fixed a problem in png_read_push_finish_row(), which would not skip some + passes that it should skip, for images that are less than 3 pixels high. + Interchanged the order of calls to png_do_swap() and png_do_shift() + in pngwtran.c (John Cromer). + Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . + Changed "bad adaptive filter type" from error to warning in pngrutil.c . + Fixed a documentation error about default filtering with 8-bit indexed-color. + Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO + (L. Peter Deutsch). + Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. + Added png_get_copyright() and png_get_header_version() functions. + Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c + Added information about debugging in libpng.txt and libpng.3 . + Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and + makefile.sco. + Removed lines after Dynamic Dependencies" in makefile.aco . + Revised makefile.dec to make a shared library (Jeremie Petit). + Removed trailing blanks from all files. + +Version 1.0.2a [January 6, 1999] + Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h + Added "if" tests to silence complaints about unused png_ptr in png.h and png.c + Changed "check_if_png" function in example.c to return true (nonzero) if PNG. + Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() + which is obsolete. + +Version 1.0.3 [January 14, 1999] + Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) + Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. + +Version 1.0.3a [August 12, 1999] + Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning + if an attempt is made to read an interlaced image when it's not supported. + Added check if png_ptr->trans is defined before freeing it in pngread.c + Modified the Y2K statement to include versions back to version 0.71 + Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c + Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) + Replaced leading blanks with tab characters in makefile.hux + Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. + Changed (float)red and (float)green to (double)red, (double)green + in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. + Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). + Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). + Updated documentation to refer to the PNG-1.2 specification. + Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c + in makefile.knr, INSTALL, and README (L. Peter Deutsch) + Fixed bugs in calculation of the length of rowbytes when adding alpha + channels to 16-bit images, in pngrtran.c (Chris Nokleberg) + Added function png_set_user_transform_info() to store user_transform_ptr, + user_depth, and user_channels into the png_struct, and a function + png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) + Added function png_set_empty_plte_permitted() to make libpng useable + in MNG applications. + Corrected the typedef for png_free_ptr in png.h (Jesse Jones). + Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be + consistent with PNG-1.2, and allow variance of 500 before complaining. + Added assembler code contributed by Intel in file pngvcrd.c and modified + makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, + Gilles Vollant) + Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. + Added some aliases for png_set_expand() in pngrtran.c, namely + png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() + (Greg Roelofs, in "PNG: The Definitive Guide"). + Added makefile.beo for BEOS on X86, contributed by Sander Stok. + +Version 1.0.3b [August 26, 1999] + Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h + Changed leading blanks to tabs in all makefiles. + Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. + Made alternate versions of png_set_expand() in pngrtran.c, namely + png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha + (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. + Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h + Revised calculation of num_blocks in pngmem.c to avoid a potentially + negative shift distance, whose results are undefined in the C language. + Added a check in pngset.c to prevent writing multiple tIME chunks. + Added a check in pngwrite.c to detect invalid small window_bits sizes. + +Version 1.0.3d [September 4, 1999] + Fixed type casting of igamma in pngrutil.c + Added new png_expand functions to scripts/pngdef.pas and pngos2.def + Added a demo read_user_transform_fn that examines the row filters in pngtest.c + +Version 1.0.4 [September 24, 1999] + Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined + Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h + Made several minor corrections to pngtest.c + Renamed the makefiles with longer but more user friendly extensions. + Copied the PNG copyright and license to a separate LICENSE file. + Revised documentation, png.h, and example.c to remove reference to + "viewing_gamma" which no longer appears in the PNG specification. + Revised pngvcrd.c to use MMX code for interlacing only on the final pass. + Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a + Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX + assembler code) and makefile.vcwin32 (doesn't). + Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) + Added a copy of pngnow.png to the distribution. + +Version 1.0.4a [September 25, 1999] + Increase max_pixel_depth in pngrutil.c if a user transform needs it. + Changed several division operations to right-shifts in pngvcrd.c + +Version 1.0.4b [September 30, 1999] + Added parentheses in line 3732 of pngvcrd.c + Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 + +Version 1.0.4c [October 1, 1999] + Added a "png_check_version" function in png.c and pngtest.c that will generate + a helpful compiler error if an old png.h is found in the search path. + Changed type of png_user_transform_depth|channels from int to png_byte. + +Version 1.0.4d [October 6, 1999] + Changed 0.45 to 0.45455 in png_set_sRGB() + Removed unused PLTE entries from pngnow.png + Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. + +Version 1.0.4e [October 10, 1999] + Fixed sign error in pngvcrd.c (Greg Roelofs) + Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) + +Version 1.0.4f [October 15, 1999] + Surrounded example.c code with #if 0 .. #endif to prevent people from + inadvertently trying to compile it. + Changed png_get_header_version() from a function to a macro in png.h + Added type casting mostly in pngrtran.c and pngwtran.c + Removed some pointless "ptr = NULL" in pngmem.c + Added a "contrib" directory containing the source code from Greg's book. + +Version 1.0.5 [October 15, 1999] + Minor editing of the INSTALL and README files. + +Version 1.0.5a [October 23, 1999] + Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) + Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) + Further optimization and bugfix of pngvcrd.c + Revised pngset.c so that it does not allocate or free memory in the user's + text_ptr structure. Instead, it makes its own copy. + Created separate write_end_info_struct in pngtest.c for a more severe test. + Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. + +Version 1.0.5b [November 23, 1999] + Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and + PNG_FLAG_WROTE_tIME from flags to mode. + Added png_write_info_before_PLTE() function. + Fixed some typecasting in contrib/gregbook/*.c + Updated scripts/makevms.com and added makevms.com to contrib/gregbook + and contrib/pngminus (Martin Zinser) + +Version 1.0.5c [November 26, 1999] + Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr. + Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to + accommodate making DLL's: Moved usr_png_ver from global variable to function + png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and + eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays + into pngtypes.h. Eliminated use of global png_pass arrays. Declared the + png_CHNK and png_pass arrays to be "const". Made the global arrays + available to applications (although none are used in libpng itself) when + PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. + Removed some extraneous "-I" from contrib/pngminus/makefile.std + Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. + Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 + +Version 1.0.5d [November 29, 1999] + Add type cast (png_const_charp) two places in png.c + Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. + Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available + to applications a macro "PNG_USE_LOCAL_ARRAYS". + comment out (with #ifdef) all the new declarations when + PNG_USE_GLOBAL_ARRAYS is defined. + Added PNG_EXPORT_VAR macro to accommodate making DLL's. + +Version 1.0.5e [November 30, 1999] + Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text + structure; refactored the inflate/deflate support to make adding new chunks + with trailing compressed parts easier in the future, and added new functions + png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, + png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). + NOTE: Applications that write text chunks MUST define png_text->lang + before calling png_set_text(). It must be set to NULL if you want to + write tEXt or zTXt chunks. If you want your application to be able to + run with older versions of libpng, use + + #ifdef PNG_iTXt_SUPPORTED + png_text[i].lang = NULL; + #endif + + Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned + offsets (Eric S. Raymond). + Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into + PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED + macros, leaving the separate macros also available. + Removed comments on #endifs at the end of many short, non-nested #if-blocks. + +Version 1.0.5f [December 6, 1999] + Changed makefile.solaris to issue a warning about potential problems when + the ucb "ld" is in the path ahead of the ccs "ld". + Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. + Added sCAL chunk support (Eric S. Raymond). + +Version 1.0.5g [December 7, 1999] + Fixed "png_free_spallettes" typo in png.h + Added code to handle new chunks in pngpread.c + Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block + Added "translated_key" to png_text structure and png_write_iTXt(). + Added code in pngwrite.c to work around a newly discovered zlib bug. + +Version 1.0.5h [December 10, 1999] + NOTE: regarding the note for version 1.0.5e, the following must also + be included in your code: + png_text[i].translated_key = NULL; + Unknown chunk handling is now supported. + Option to eliminate all floating point support was added. Some new + fixed-point functions such as png_set_gAMA_fixed() were added. + Expanded tabs and removed trailing blanks in source files. + +Version 1.0.5i [December 13, 1999] + Added some type casts to silence compiler warnings. + Renamed "png_free_spalette" to "png_free_spalettes" for consistency. + Removed leading blanks from a #define in pngvcrd.c + Added some parameters to the new png_set_keep_unknown_chunks() function. + Added a test for up->location != 0 in the first instance of writing + unknown chunks in pngwrite.c + Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to + prevent recursion. + Added png_free_hIST() function. + Various patches to fix bugs in the sCAL and integer cHRM processing, + and to add some convenience macros for use with sCAL. + +Version 1.0.5j [December 21, 1999] + Changed "unit" parameter of png_write_sCAL from png_byte to int, to work + around buggy compilers. + Added new type "png_fixed_point" for integers that hold float*100000 values + Restored backward compatibility of tEXt/zTXt chunk processing: + Restored the first four members of png_text to the same order as v.1.0.5d. + Added members "lang_key" and "itxt_length" to png_text struct. Set + text_length=0 when "text" contains iTXt data. Use the "compression" + member to distinguish among tEXt/zTXt/iTXt types. Added + PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. + The "Note" above, about backward incompatibility of libpng-1.0.5e, no + longer applies. + Fixed png_read|write_iTXt() to read|write parameters in the right order, + and to write the iTXt chunk after IDAT if it appears in the end_ptr. + Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) + Reversed the order of trying to write floating-point and fixed-point gAMA. + +Version 1.0.5k [December 27, 1999] + Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" + Added png_handle_as_unknown() function (Glenn) + Added png_free_chunk_list() function and chunk_list and num_chunk_list members + of png_ptr. + Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. + Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings + about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) + Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). + Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. + Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). + +Version 1.0.5l [January 1, 2000] + Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() + for setting a callback function to handle unknown chunks and for + retrieving the associated user pointer (Glenn). + +Version 1.0.5m [January 7, 2000] + Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). + +Version 1.0.5n [January 9, 2000] + Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its + own memory for info_ptr->palette. This makes it safe for the calling + application to free its copy of the palette any time after it calls + png_set_PLTE(). + +Version 1.0.5o [January 20, 2000] + Cosmetic changes only (removed some trailing blanks and TABs) + +Version 1.0.5p [January 31, 2000] + Renamed pngdll.mak to makefile.bd32 + Cosmetic changes in pngtest.c + +Version 1.0.5q [February 5, 2000] + Relocated the makefile.solaris warning about PATH problems. + Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) + Revised makefile.gcmmx + Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros + +Version 1.0.5r [February 7, 2000] + Removed superfluous prototype for png_get_itxt from png.h + Fixed a bug in pngrtran.c that improperly expanded the background color. + Return *num_text=0 from png_get_text() when appropriate, and fix documentation + of png_get_text() in libpng.txt/libpng.3. + +Version 1.0.5s [February 18, 2000] + Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the + new error handler that's planned for the next libpng release, and changed + example.c, pngtest.c, and contrib programs to use this macro. + Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) + Fixed a bug in png_read_png() that caused it to fail to expand some images + that it should have expanded. + Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions + in pngget.c + Changed the allocation of palette, history, and trans arrays back to + the version 1.0.5 method (linking instead of copying) which restores + backward compatibility with version 1.0.5. Added some remarks about + that in example.c. Added "free_me" member to info_ptr and png_ptr + and added png_free_data() function. + Updated makefile.linux and makefile.gccmmx to make directories conditionally. + Made cosmetic changes to pngasmrd.h + Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). + Modified png_read_png() to allocate info_ptr->row_pointers only if it + hasn't already been allocated. + +Version 1.0.5t [March 4, 2000] + Changed png_jmp_env() migration aiding macro to png_jmpbuf(). + Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c + Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when + PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b + Files in contrib/gregbook were revised to use png_jmpbuf() and to select + a 24-bit visual if one is available, and to allow abbreviated options. + Files in contrib/pngminus were revised to use the png_jmpbuf() macro. + Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s + +Version 1.0.5u [March 5, 2000] + Simplified the code that detects old png.h in png.c and pngtest.c + Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) + Increased precision of rgb_to_gray calculations from 8 to 15 bits and + added png_set_rgb_to_gray_fixed() function. + Added makefile.bc32 (32-bit Borland C++, C mode) + +Version 1.0.5v [March 11, 2000] + Added some parentheses to the png_jmpbuf macro definition. + Updated references to the zlib home page, which has moved to freesoftware.com. + Corrected bugs in documentation regarding png_read_row() and png_write_row(). + Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. + Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, + revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) + +Version 1.0.6 [March 20, 2000] + Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c + Added makefile.sggcc (SGI IRIX with gcc) + +Version 1.0.6d [April 7, 2000] + Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO + Added data_length parameter to png_decompress_chunk() function + Revised documentation to remove reference to abandoned png_free_chnk functions + Fixed an error in png_rgb_to_gray_fixed() + Revised example.c, usage of png_destroy_write_struct(). + Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file + Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c + Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). + +Version 1.0.6e [April 9, 2000] + Added png_data_freer() function. + In the code that checks for over-length tRNS chunks, added check of + info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) + Minor revisions of libpng.txt/libpng.3. + Check for existing data and free it if the free_me flag is set, in png_set_*() + and png_handle_*(). + Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED + is defined. + Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c + and mentioned the purposes of the two macros in libpng.txt/libpng.3. + +Version 1.0.6f [April 14, 2000] + Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. + Add checks in png_set_text() for NULL members of the input text structure. + Revised libpng.txt/libpng.3. + Removed superfluous prototype for png_set_iTXt from png.h + Removed "else" from pngread.c, after png_error(), and changed "0" to "length". + Changed several png_errors about malformed ancillary chunks to png_warnings. + +Version 1.0.6g [April 24, 2000] + Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. + Relocated paragraph about png_set_background() in libpng.3/libpng.txt + and other revisions (Matthias Benckmann) + Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and + png_ptr members to restore binary compatibility with libpng-1.0.5 + (breaks compatibility with libpng-1.0.6). + +Version 1.0.6h [April 24, 2000] + Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds + libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) + This is a temporary change for test purposes. + +Version 1.0.6i [May 2, 2000] + Rearranged some members at the end of png_info and png_struct, to put + unknown_chunks_num and free_me within the original size of the png_structs + and free_me, png_read_user_fn, and png_free_fn within the original png_info, + because some old applications allocate the structs directly instead of + using png_create_*(). + Added documentation of user memory functions in libpng.txt/libpng.3 + Modified png_read_png so that it will use user_allocated row_pointers + if present, unless free_me directs that it be freed, and added description + of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. + Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version + 1.00) members of png_struct and png_info, to regain binary compatibility + when you define this macro. Capabilities lost in this event + are user transforms (new in version 1.0.0),the user transform pointer + (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, + the high-level interface, and unknown chunks support (all new in 1.0.6). + This was necessary because of old applications that allocate the structs + directly as authors were instructed to do in libpng-0.88 and earlier, + instead of using png_create_*(). + Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which + can be used to detect codes that directly allocate the structs, and + code to check these modes in png_read_init() and png_write_init() and + generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED + was not defined. + Added makefile.intel and updated makefile.watcom (Pawel Mrochen) + +Version 1.0.6j [May 3, 2000] + Overloaded png_read_init() and png_write_init() with macros that convert + calls to png_read_init_2() or png_write_init_2() that check the version + and structure sizes. + +Version 1.0.7beta11 [May 7, 2000] + Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes + which are no longer used. + Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is + defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED + is defined. + Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory + overrun when old applications fill the info_ptr->text structure directly. + Added PNGAPI macro, and added it to the definitions of all exported functions. + Relocated version macro definitions ahead of the includes of zlib.h and + pngconf.h in png.h. + +Version 1.0.7beta12 [May 12, 2000] + Revised pngset.c to avoid a problem with expanding the png_debug macro. + Deleted some extraneous defines from pngconf.h + Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. + Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. + Added png_access_version_number() function. + Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). + Expanded libpng.3/libpng.txt information about png_data_freer(). + +Version 1.0.7beta14 [May 17, 2000] (beta13 was not published) + Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as + warnings instead of errors, as pngrutil.c does. + Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() + will actually write IDATs. + Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. + Make png_free_data() ignore its final parameter except when freeing data + that can have multiple instances (text, sPLT, unknowns). + Fixed a new bug in png_set_rows(). + Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. + Added png_set_invalid() function. + Fixed incorrect illustrations of png_destroy_write_struct() in example.c. + +Version 1.0.7beta15 [May 30, 2000] + Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce + fewer error messages. + Rearranged checks for Z_OK to check the most likely path first in pngpread.c + and pngwutil.c. + Added checks in pngtest.c for png_create_*() returning NULL, and mentioned + in libpng.txt/libpng.3 the need for applications to check this. + Changed names of png_default_*() functions in pngtest to pngtest_*(). + Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. + Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c + Set each pointer to NULL after freeing it in png_free_data(). + Worked around a problem in pngconf.h; AIX's strings.h defines an "index" + macro that conflicts with libpng's png_color_16.index. (Dimitri + Papadapoulos) + Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). + +Version 1.0.7beta16 [June 4, 2000] + Revised the workaround of AIX string.h "index" bug. + Added a check for overlength PLTE chunk in pngrutil.c. + Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer + indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. + Added a warning in png_decompress_chunk() when it runs out of data, e.g. + when it tries to read an erroneous PhotoShop iCCP chunk. + Added PNG_USE_DLL macro. + Revised the copyright/disclaimer/license notice. + Added contrib/msvctest directory + +Version 1.0.7rc1 [June 9, 2000] + Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) + Added contrib/visupng directory (Willem van Schaik) + +Version 1.0.7beta18 [June 23, 2000] + Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ + and do not redefine PNGAPI if it is passed in via a compiler directive. + Revised visupng/PngFile.c to remove returns from within the Try block. + Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. + Updated contrib/visupng/cexcept.h to version 1.0.0. + Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. + +Version 1.0.7rc2 [June 28, 2000] + Updated license to include disclaimers required by UCITA. + Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. + +Version 1.0.7 [July 1, 2000] + Revised the definition of "trans_values" in libpng.3/libpng.txt + +Version 1.0.8beta1 [July 8, 2000] + Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. + Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and + pngwutil.c. + Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. + Removed unused "#include " from png.c + Added WindowsCE support. + Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. + +Version 1.0.8beta2 [July 10, 2000] + Added project files to the wince directory and made further revisions + of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. + +Version 1.0.8beta3 [July 11, 2000] + Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() + for indexed-color input files to avoid potential double-freeing trans array + under some unusual conditions; problem was introduced in version 1.0.6f. + Further revisions to pngtest.c and files in the wince subdirectory. + +Version 1.0.8beta4 [July 14, 2000] + Added the files pngbar.png and pngbar.jpg to the distribution. + Added makefile.cygwin, and cygwin support in pngconf.h + Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) + +Version 1.0.8rc1 [July 16, 2000] + Revised png_debug() macros and statements to eliminate compiler warnings. + +Version 1.0.8 [July 24, 2000] + Added png_flush() in pngwrite.c, after png_write_IEND(). + Updated makefile.hpux to build a shared library. + +Version 1.0.9beta1 [November 10, 2000] + Fixed typo in scripts/makefile.hpux + Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) + Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser) + Changed "cdrom.com" in documentation to "libpng.org" + Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). + Changed type of "params" from voidp to png_voidp in png_read|write_png(). + Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. + Revised the 3 instances of WRITEFILE in pngtest.c. + Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. + Updated png.rc in dll/msvc project + Revised makefile.dec to define and use LIBPATH and INCPATH + Increased size of global png_libpng_ver[] array from 12 to 18 chars. + Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. + Removed duplicate png_crc_finish() from png_handle_bKGD() function. + Added a warning when application calls png_read_update_info() multiple times. + Revised makefile.cygwin + Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. + Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). + +Version 1.0.9beta2 [November 19, 2000] + Renamed the "dll" subdirectory "projects". + Added borland project files to "projects" subdirectory. + Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. + Add error message in png_set_compression_buffer_size() when malloc fails. + +Version 1.0.9beta3 [November 23, 2000] + Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. + Removed the png_flush() in pngwrite.c that crashes some applications + that don't set png_output_flush_fn. + Added makefile.macosx and makefile.aix to scripts directory. + +Version 1.0.9beta4 [December 1, 2000] + Change png_chunk_warning to png_warning in png_check_keyword(). + Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). + +Version 1.0.9beta5 [December 15, 2000] + Added support for filter method 64 (for PNG datastreams embedded in MNG). + +Version 1.0.9beta6 [December 18, 2000] + Revised png_set_filter() to accept filter method 64 when appropriate. + Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to + help prevent applications from using MNG features in PNG datastreams. + Added png_permit_mng_features() function. + Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". + +Version 1.0.9rc1 [December 23, 2000] + Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c + Fixed error handling of unknown compression type in png_decompress_chunk(). + In pngconf.h, define __cdecl when _MSC_VER is defined. + +Version 1.0.9beta7 [December 28, 2000] + Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. + Revised memory management in png_set_hIST and png_handle_hIST in a backward + compatible manner. PLTE and tRNS were revised similarly. + Revised the iCCP chunk reader to ignore trailing garbage. + +Version 1.0.9beta8 [January 12, 2001] + Moved pngasmrd.h into pngconf.h. + Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. + +Version 1.0.9beta9 [January 15, 2001] + Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to + wince and msvc project module definition files. + Minor revision of makefile.cygwin. + Fixed bug with progressive reading of narrow interlaced images in pngpread.c + +Version 1.0.9beta10 [January 16, 2001] + Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. + Fixed "png_mmx_supported" typo in project definition files. + +Version 1.0.9beta11 [January 19, 2001] + Updated makefile.sgi to make shared library. + Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED + by default, for the benefit of DLL forward compatibility. These will + be re-enabled in version 1.2.0. + +Version 1.0.9rc2 [January 22, 2001] + Revised cygwin support. + +Version 1.0.9 [January 31, 2001] + Added check of cygwin's ALL_STATIC in pngconf.h + Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. + +Version 1.0.10beta1 [March 14, 2001] + Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. + Reformatted libpng.3 to eliminate bad line breaks. + Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c + Added prototype for png_mmx_support() near the top of pnggccrd.c + Moved some error checking from png_handle_IHDR to png_set_IHDR. + Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. + Revised png_mmx_support() function in pnggccrd.c + Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c + Fixed memory leak in contrib/visupng/PngFile.c + Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) + Added warnings when retrieving or setting gamma=0. + Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). + +Version 1.0.10rc1 [March 23, 2001] + Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, + and png_strlen. + Revised png_mmx_supported() function in pnggccrd.c to return proper value. + Fixed bug in progressive reading (pngpread.c) with small images (height < 8). + +Version 1.0.10 [March 30, 2001] + Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin + Added beos project files (Chris Herborth) + +Version 1.0.11beta1 [April 3, 2001] + Added type casts on several png_malloc() calls (Dimitri Papadapoulos). + Removed a no-longer needed AIX work-around from pngconf.h + Changed several "//" single-line comments to C-style in pnggccrd.c + +Version 1.0.11beta2 [April 11, 2001] + Removed PNGAPI from several functions whose prototypes did not have PNGAPI. + Updated scripts/pngos2.def + +Version 1.0.11beta3 [April 14, 2001] + Added checking the results of many instances of png_malloc() for NULL + +Version 1.0.11beta4 [April 20, 2001] + Undid the changes from version 1.0.11beta3. Added a check for NULL return + from user's malloc_fn(). + Removed some useless type casts of the NULL pointer. + Added makefile.netbsd + +Version 1.0.11 [April 27, 2001] + Revised makefile.netbsd + +Version 1.0.12beta1 [May 14, 2001] + Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) + Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h + Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. + Eliminated the png_error about apps using png_read|write_init(). Instead, + libpng will reallocate the png_struct and info_struct if they are too small. + This retains future binary compatibility for old applications written for + libpng-0.88 and earlier. + +Version 1.2.0beta1 [May 6, 2001] + Bumped DLLNUM to 2. + Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED + by default. + Added runtime selection of MMX features. + Added png_set_strip_error_numbers function and related macros. + +Version 1.2.0beta2 [May 7, 2001] + Finished merging 1.2.0beta1 with version 1.0.11 + Added a check for attempts to read or write PLTE in grayscale PNG datastreams. + +Version 1.2.0beta3 [May 17, 2001] + Enabled user memory function by default. + Modified png_create_struct so it passes user mem_ptr to user memory allocator. + Increased png_mng_features flag from png_byte to png_uint_32. + Bumped shared-library (so-number) and dll-number to 3. + +Version 1.2.0beta4 [June 23, 2001] + Check for missing profile length field in iCCP chunk and free chunk_data + in case of truncated iCCP chunk. + Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc + Bumped dll-number from 2 to 3 in makefile.cygwin + Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly + if user attempts to run it on an 8-bit display. + Updated contrib/gregbook + Use png_malloc instead of png_zalloc to allocate palette in pngset.c + Updated makefile.ibmc + Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes + of png_write_oFFS width and height from png_uint_32 to png_int_32. + Updated example.c + Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c + +Version 1.2.0beta5 [August 8, 2001] + Revised contrib/gregbook + Revised makefile.gcmmx + Revised pnggccrd.c to conditionally compile some thread-unsafe code only + when PNG_THREAD_UNSAFE_OK is defined. + Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with + value exceeding 2^bit_depth-1 + Revised makefile.sgi and makefile.sggcc + Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c + Removed restriction that do_invert_mono only operate on 1-bit opaque files + +Version 1.2.0 [September 1, 2001] + Changed a png_warning() to png_debug() in pnggccrd.c + Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). + +Version 1.2.1beta1 [October 19, 2001] + Revised makefile.std in contrib/pngminus + Include background_1 in png_struct regardless of gamma support. + Revised makefile.netbsd and makefile.macosx, added makefile.darwin. + Revised example.c to provide more details about using row_callback(). + +Version 1.2.1beta2 [October 25, 2001] + Added type cast to each NULL appearing in a function call, except for + WINCE functions. + Added makefile.so9. + +Version 1.2.1beta3 [October 27, 2001] + Removed type casts from all NULLs. + Simplified png_create_struct_2(). + +Version 1.2.1beta4 [November 7, 2001] + Revised png_create_info_struct() and png_creat_struct_2(). + Added error message if png_write_info() was omitted. + Type cast NULLs appearing in function calls when _NO_PROTO or + PNG_TYPECAST_NULL is defined. + +Version 1.2.1rc1 [November 24, 2001] + Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL + is defined. + Changed typecast of "size" argument to png_size_t in pngmem.c calls to + the user malloc_fn, to agree with the prototype in png.h + Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) + Updated makefile.sgi to recognize LIBPATH and INCPATH. + Updated various makefiles so "make clean" does not remove previous major + version of the shared library. + +Version 1.2.1rc2 [December 4, 2001] + Always allocate 256-entry internal palette, hist, and trans arrays, to + avoid out-of-bounds memory reference caused by invalid PNG datastreams. + Added a check for prefix_length > data_length in iCCP chunk handler. + +Version 1.2.1 [December 7, 2001] + None. + +Version 1.2.2beta1 [February 22, 2002] + Fixed a bug with reading the length of iCCP profiles (Larry Reeves). + Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate + libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h + Revised makefile.darwin to remove "-undefined suppress" option. + Added checks for gamma and chromaticity values over 21474.83, which exceed + the limit for PNG unsigned 32-bit integers when encoded. + Revised calls to png_create_read_struct() and png_create_write_struct() + for simpler debugging. + Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) + +Version 1.2.2beta2 [February 23, 2002] + Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. + Check for invalid image dimensions in png_get_IHDR. + Added missing "fi;" in the install target of the SGI makefiles. + Added install-static to all makefiles that make shared libraries. + Always do gamma compensation when image is partially transparent. + +Version 1.2.2beta3 [March 7, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later. + Modified shared-library makefiles to install pkgconfig/libpngNN.pc. + Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown + Removed unused png_write_destroy_info prototype from png.h + Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case + Added install-shared target to all makefiles that make shared libraries. + Stopped a double free of palette, hist, and trans when not using free_me. + Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. + +Version 1.2.2beta4 [March 8, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later (Jason Summers). + Relocated a misplaced /bin/rm in the "install-shared" makefile targets + Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. + +Version 1.2.2beta5 [March 26, 2002] + Added missing PNGAPI to several function definitions. + Check for invalid bit_depth or color_type in png_get_IHDR(), and + check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). + Revised iTXt support to accept NULL for lang and lang_key. + Compute gamma for color components of background even when color_type is gray. + Changed "()" to "{}" in scripts/libpng.pc.in. + Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN + Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so + +Version 1.2.2beta6 [March 31, 2002] + +Version 1.0.13beta1 [March 31, 2002] + Prevent png_zalloc() from trying to memset memory that it failed to acquire. + Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). + Ensure that the right function (user or default) is used to free the + png_struct after an error in png_create_read_struct_2(). + +Version 1.2.2rc1 [April 7, 2002] + +Version 1.0.13rc1 [April 7, 2002] + Save the ebx register in pnggccrd.c (Sami Farin) + Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). + Updated makefiles to put headers in include/libpng and remove old include/*.h. + +Version 1.2.2 [April 15, 2002] + +Version 1.0.13 [April 15, 2002] + Revised description of png_set_filter() in libpng.3/libpng.txt. + Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd + +Version 1.0.13patch01 [April 17, 2002] + +Version 1.2.2patch01 [April 17, 2002] + Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and + makefile.sggcc + Fixed VER -> PNGVER typo in makefile.macosx and added install-static to + install + Added install: target to makefile.32sunu and makefile.64sunu + +Version 1.0.13patch03 [April 18, 2002] + +Version 1.2.2patch03 [April 18, 2002] + Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng + subdirectory to libpngNN subdirectory without the full pathname. + Moved generation of libpng.pc from "install" to "all" in 15 makefiles. + +Version 1.2.3rc1 [April 28, 2002] + Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). + Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) + Fixed bug with $prefix, should be $(prefix) in makefile.hpux. + Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin + Added a link from libpngNN.pc to libpng.pc in 15 makefiles. + Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. + Revised makefile.darwin to make relative links without full pathname. + Added setjmp() at the end of png_create_*_struct_2() in case user forgets + to put one in their application. + Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and + removed them from module definition files. + +Version 1.2.3rc2 [May 1, 2002] + Fixed bug in reporting number of channels in pngget.c and pngset.c, + that was introduced in version 1.2.2beta5. + Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), + png_default_flush(), and png_push_fill_buffer() and included them in + module definition files. + Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. + +Version 1.2.3rc3 [May 1, 2002] + Revised prototype for png_default_flush() + Remove old libpng.pc and libpngNN.pc before installing new ones. + +Version 1.2.3rc4 [May 2, 2002] + Typos in *.def files (png_default_read|write -> png_default_read|write_data) + In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc + Added libpng-config and libpngNN-config and modified makefiles to install + them. + Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles + Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp + +Version 1.2.3rc5 [May 11, 2002] + Changed "error" and "message" in prototypes to "error_message" and + "warning_message" to avoid namespace conflict. + Revised 15 makefiles to build libpng-config from libpng-config-*.in + Once more restored png_zalloc and png_zfree to regular nonexported form. + Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer + to nonexported form, but with PNGAPI, and removed them from module def + files. + +Version 1.2.3rc6 [May 14, 2002] + Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c + Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. + Removed leftover libpng-config "sed" script from four makefiles. + Revised libpng-config creating script in 16 makefiles. + +Version 1.2.3 [May 22, 2002] + Revised libpng-config target in makefile.cygwin. + Removed description of png_set_mem_fn() from documentation. + Revised makefile.freebsd. + Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). + Revised projects/msvc/README.txt + Changed -lpng to -lpngNN in LDFLAGS in several makefiles. + +Version 1.2.4beta1 [May 24, 2002] + Added libpng.pc and libpng-config to "all:" target in 16 makefiles. + Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) + Added missing "\" before closing double quote in makefile.gcmmx. + Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() + functions. + +Version 1.2.4beta2 [June 25, 2002] + Plugged memory leak of png_ptr->current_text (Matt Holgate). + Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) + Added -soname to the loader flags in makefile.dec, makefile.sgi, and + makefile.sggcc. + Added "test-installed" target to makefile.linux, makefile.gcmmx, + makefile.sgi, and makefile.sggcc. + +Version 1.2.4beta3 [June 28, 2002] + Plugged memory leak of row_buf in pngtest.c when there is a png_error(). + Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. + Added "test-installed" target to makefile.32sunu, makefile.64sunu, + makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, + makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. + +Version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] + Added "test-installed" target to makefile.cygwin and makefile.sco. + Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. + +Version 1.2.4 and 1.0.14 [July 8, 2002] + Changed png_warning() to png_error() when width is too large to process. + +Version 1.2.4patch01 [July 20, 2002] + Revised makefile.cygwin to use DLL number 12 instead of 13. + +Version 1.2.5beta1 [August 6, 2002] + Added code to contrib/gregbook/readpng2.c to ignore unused chunks. + Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) + Removed some stray *.o files from contrib/gregbook. + Changed png_error() to png_warning() about "Too much data" in pngpread.c + and about "Extra compressed data" in pngrutil.c. + Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). + Updated makefile.hpgcc + Updated png.c and pnggccrd.c handling of return from png_mmx_support() + +Version 1.2.5beta2 [August 15, 2002] + Only issue png_warning() about "Too much data" in pngpread.c when avail_in + is nonzero. + Updated makefiles to install a separate libpng.so.3 with its own rpath. + +Version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] + Revised makefiles to not remove previous minor versions of shared libraries. + +Version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] + Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared + library loader directive. + Added missing "$OBJSDLL" line to makefile.gcmmx. + Added missing "; fi" to makefile.32sunu. + +Version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] + Revised libpng-config script. + +Version 1.2.5 and 1.0.15 [October 3, 2002] + Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, + and makefile.aix. + Relocated two misplaced PNGAPI lines in pngtest.c + +Version 1.2.6beta1 [October 22, 2002] + Commented out warning about uninitialized mmx_support in pnggccrd.c. + Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. + Relocated two more misplaced PNGAPI lines in pngtest.c + Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, + introduced in version 1.0.2. + Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. + +Version 1.2.6beta2 [November 1, 2002] + Added libpng-config "--ldopts" output. + Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" + in makefiles. + +Version 1.2.6beta3 [July 18, 2004] + Reverted makefile changes from version 1.2.6beta2 and some of the changes + from version 1.2.6beta1; these will be postponed until version 1.2.7. + Version 1.2.6 is going to be a simple bugfix release. + Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. + Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. + Added "#!/bin/sh" at the top of configure, for recognition of the + 'x' flag under Cygwin (Cosmin). + Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). + Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). + Fixed the special memory handler for Borland C under DOS, in pngmem.c + (Cosmin). + Removed some spurious assignments in pngrutil.c (Cosmin). + Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings + on 16-bit platforms (Cosmin). + Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). + Used proper type png_fixed_point, to avoid problems on 16-bit platforms, + in png_handle_sRGB() (Cosmin). + Added compression_type to png_struct, and optimized the window size + inside the deflate stream (Cosmin). + Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). + Fixed handling of unknown chunks that come after IDAT (Cosmin). + Allowed png_error() and png_warning() to work even if png_ptr == NULL + (Cosmin). + Replaced row_info->rowbytes with row_bytes in png_write_find_filter() + (Cosmin). + Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). + Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded + values in png.c (Simon-Pierre, Cosmin). + Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). + Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc + (Simon-Pierre). + Moved the definition of PNG_HEADER_VERSION_STRING near the definitions + of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). + Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). + Updated scripts/makefile.vc(a)win32 (Cosmin). + Updated the MSVC project (Simon-Pierre, Cosmin). + Updated the Borland C++ Builder project (Cosmin). + Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). + Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). + Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). + Added extra guard around inclusion of Turbo C memory headers, in pngconf.h + (Cosmin). + Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to + projects/cbuilder5/ (Cosmin). + Moved projects/visualc6/png32ms.def to scripts/pngw32.def, + and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). + Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). + Changed line endings to DOS style in cbuilder5 and visualc6 files, even + in the tar.* distributions (Cosmin). + Updated contrib/visupng/VisualPng.dsp (Cosmin). + Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). + Added a separate distribution with "configure" and supporting files (Junichi). + +Version 1.2.6beta4 [July 28, 2004] + Added user ability to change png_size_t via a PNG_SIZE_T macro. + Added png_sizeof() and png_convert_size() functions. + Added PNG_SIZE_MAX (maximum value of a png_size_t variable. + Added check in png_malloc_default() for (size_t)size != (png_uint_32)size + which would indicate an overflow. + Changed sPLT failure action from png_error to png_warning and abandon chunk. + Changed sCAL and iCCP failures from png_error to png_warning and abandon. + Added png_get_uint_31(png_ptr, buf) function. + Added PNG_UINT_32_MAX macro. + Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. + Made png_zalloc() issue a png_warning and return NULL on potential + overflow. + Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x + Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. + Revised Borland portion of png_malloc() to return NULL or issue + png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. + Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove + sequential read support. + Added some "#if PNG_WRITE_SUPPORTED" blocks. + Added #ifdef to remove some redundancy in png_malloc_default(). + Use png_malloc instead of png_zalloc to allocate the pallete. + +Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] + Fixed buffer overflow vulnerability in png_handle_tRNS() + Fixed integer arithmetic overflow vulnerability in png_read_png(). + Fixed some harmless bugs in png_handle_sBIT, etc, that would cause + duplicate chunk types to go undetected. + Fixed some timestamps in the -config version + Rearranged order of processing of color types in png_handle_tRNS(). + Added ROWBYTES macro to calculate rowbytes without integer overflow. + Updated makefile.darwin and removed makefile.macosx from scripts directory. + Imposed default one million column, one-million row limits on the image + dimensions, and added png_set_user_limits() function to override them. + Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. + Fixed wrong cast of returns from png_get_user_width|height_max(). + Changed some "keep the compiler happy" from empty statements to returns, + Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution + +Version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] + Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. + Revised pngtest's png_debug_malloc() to use png_malloc() instead of + png_malloc_default() which is not supposed to be exported. + Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in + pngpread.c. Bug was introduced in 1.2.6rc1. + Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. + Fixed old bug in RGB to Gray transformation. + Fixed problem with 64-bit compilers by casting arguments to abs() + to png_int_32. + Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). + Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) + Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. + Added code to update the row_info->colortype in png_do_read_filler() (MSB). + +Version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] + Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid + trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. + Revised documentation of png_set_keep_unknown_chunks(). + Check handle_as_unknown status in pngpread.c, as in pngread.c previously. + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h + Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c + +Version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] + Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of + "pinfo" was out of place). + +Version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED + section of png.h where they were inadvertently placed in version rc3. + +Version 1.2.6 and 1.0.16 [August 15, 2004] + Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. + +Version 1.2.7beta1 [August 26, 2004] + Removed unused pngasmrd.h file. + Removed references to uu.net for archived files. Added references to + PNG Spec (second edition) and the PNG ISO/IEC Standard. + Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. + Fixed bug with "optimized window size" in the IDAT datastream, that + causes libpng to write PNG files with incorrect zlib header bytes. + +Version 1.2.7beta2 [August 28, 2004] + Fixed bug with sCAL chunk and big-endian machines (David Munro). + Undid new code added in 1.2.6rc2 to update the color_type in + png_set_filler(). + Added png_set_add_alpha() that updates color type. + +Version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] + Revised png_set_strip_filler() to not remove alpha if color_type has alpha. + +Version 1.2.7 and 1.0.17 [September 12, 2004] + Added makefile.hp64 + Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin + +Version 1.2.8beta1 [November 1, 2004] + Fixed bug in png_text_compress() that would fail to complete a large block. + Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during + strip alpha operation in png_do_strip_filler(). + Added PNG_1_2_X definition in pngconf.h + Use #ifdef to comment out png_info_init in png.c and png_read_init in + pngread.c (as of 1.3.0) + +Version 1.2.8beta2 [November 2, 2004] + Reduce color_type to a nonalpha type after strip alpha operation in + png_do_strip_filler(). + +Version 1.2.8beta3 [November 3, 2004] + Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM + +Version 1.2.8beta4 [November 12, 2004] + Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). + Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). + Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection + of data type in deflate (Cosmin). + Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. + +Version 1.2.8beta5 [November 20, 2004] + Use png_ptr->flags instead of png_ptr->transformations to pass + PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI + compatibility. + Revised handling of SPECIALBUILD, PRIVATEBUILD, + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. + +Version 1.2.8rc1 [November 24, 2004] + Moved handling of BUILD macros from pngconf.h to png.h + Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently + omitted from beta5. + Revised scripts/pngw32.rc + Despammed mailing addresses by masking "@" with "at". + Inadvertently installed a supposedly faster test version of pngrutil.c + +Version 1.2.8rc2 [November 26, 2004] + Added two missing "\" in png.h + Change tests in pngread.c and pngpread.c to + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); + +Version 1.2.8rc3 [November 28, 2004] + Reverted pngrutil.c to version libpng-1.2.8beta5. + Added scripts/makefile.elf with supporting code in pngconf.h for symbol + versioning (John Bowler). + +Version 1.2.8rc4 [November 29, 2004] + Added projects/visualc7 (Simon-pierre). + +Version 1.2.8rc5 [November 29, 2004] + Fixed new typo in scripts/pngw32.rc + +Version 1.2.8 [December 3, 2004] + Removed projects/visualc7, added projects/visualc71. + +Version 1.2.9beta1 [February 21, 2006] + Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints + Revised man page and libpng.txt to make it clear that one should not call + png_read_end or png_write_end after png_read_png or png_write_png. + Updated references to png-mng-implement mailing list. + Fixed an incorrect typecast in pngrutil.c + Added PNG_NO_READ_SUPPORTED conditional for making a write-only library. + Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional. + Optimized alpha-inversion loops in pngwtran.c + Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c + Make sure num_trans is <= 256 before copying data in png_set_tRNS(). + Make sure num_palette is <= 256 before copying data in png_set_PLTE(). + Interchanged order of write_swap_alpha and write_invert_alpha transforms. + Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin). + Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin). + Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin). + Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16, + png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin). + Added type cast (png_byte) in png_write_sCAL() (Cosmin). + Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin). + Default iTXt support was inadvertently enabled. + +Version 1.2.9beta2 [February 21, 2006] + Check for png_rgb_to_gray and png_gray_to_rgb read transformations before + checking for png_read_dither in pngrtran.c + Revised checking of chromaticity limits to accommodate extended RGB + colorspace (John Denker). + Changed line endings in some of the project files to CRLF, even in the + "Unix" tar distributions (Cosmin). + Made png_get_int_32 and png_save_int_32 always available (Cosmin). + Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def + with the newly exported functions. + Eliminated distributions without the "configure" script. + Updated INSTALL instructions. + +Version 1.2.9beta3 [February 24, 2006] + Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp + Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler) + Removed reference to pngasmrd.h from Makefile.am + Renamed CHANGES to ChangeLog. + Renamed LICENSE to COPYING. + Renamed ANNOUNCE to NEWS. + Created AUTHORS file. + +Version 1.2.9beta4 [March 3, 2006] + Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac + Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING. + Removed newline from the end of some error and warning messages. + Removed test for sqrt() from configure.ac and configure. + Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix). + Disabled default iTXt support that was inadvertently enabled in + libpng-1.2.9beta1. + Added "OS2" to list of systems that don't need underscores, in pnggccrd.c + Removed libpng version and date from *.c files. + +Version 1.2.9beta5 [March 4, 2006] + Removed trailing blanks from source files. + Put version and date of latest change in each source file, and changed + copyright year accordingly. + More cleanup of configure.ac, Makefile.am, and associated scripts. + Restored scripts/makefile.elf which was inadvertently deleted. + +Version 1.2.9beta6 [March 6, 2006] + Fixed typo (RELEASE) in configuration files. + +Version 1.2.9beta7 [March 7, 2006] + Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am + Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s() + in png.h. + Updated makefile.elf as suggested by debian. + Made cosmetic changes to some makefiles, adding LN_SF and other macros. + Made some makefiles accept "exec_prefix". + +Version 1.2.9beta8 [March 9, 2006] + Fixed some "#if defined (..." which should be "#if defined(..." + Bug introduced in libpng-1.2.8. + Fixed inconsistency in definition of png_default_read_data() + Restored blank that was lost from makefile.sggcc "clean" target in beta7. + Revised calculation of "current" and "major" for irix in ltmain.sh + Changed "mkdir" to "MKDIR_P" in some makefiles. + Separated PNG_EXPAND and PNG_EXPAND_tRNS. + Added png_set_expand_gray_1_2_4_to_8() and deprecated + png_set_gray_1_2_4_to_8() which also expands tRNS to alpha. + +Version 1.2.9beta9 [March 10, 2006] + Include "config.h" in pngconf.h when available. + Added some checks for NULL png_ptr or NULL info_ptr (timeless) + +Version 1.2.9beta10 [March 20, 2006] + Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin) + Made pnggccrd.c PIC-compliant (Christian Aichinger). + Added makefile.mingw (Wolfgang Glas). + Revised pngconf.h MMX checking. + +Version 1.2.9beta11 [March 22, 2006] + Fixed out-of-order declaration in pngwrite.c that was introduced in beta9 + Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros. + +Version 1.2.9rc1 [March 31, 2006] + Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin). + Removed nonsensical assertion check from pngtest.c (Cosmin). + +Version 1.2.9 [April 14, 2006] + Revised makefile.beos and added "none" selector in ltmain.sh + +Version 1.2.10beta1 [April 15, 2006] + Renamed "config.h" to "png_conf.h" and revised Makefile.am to add + -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h + to include png_conf.h only when PNG_BUILDING_LIBPNG is defined. + +Version 1.2.10beta2 [April 15, 2006] + Manually updated Makefile.in and configure. Changed png_conf.h.in + back to config.h. + +Version 1.2.10beta3 [April 15, 2006] + Change png_conf.h back to config.h in pngconf.h. + +Version 1.2.10beta4 [April 16, 2006] + Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*. + +Version 1.2.10beta5 [April 16, 2006] + Added a configure check for compiling assembler code in pnggccrd.c + +Version 1.2.10beta6 [April 17, 2006] + Revised the configure check for pnggccrd.c + Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@ + Added @LIBPNG_DEFINES@ to arguments when building libpng.sym + +Version 1.2.10beta7 [April 18, 2006] + Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles. + +Version 1.2.10rc1 [April 19, 2006] + Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD + Fixed "LN_FS" typo in makefile.sco and makefile.solaris. + +Version 1.2.10rc2 [April 20, 2006] + Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE + in configure.ac and configure + Made the configure warning about versioned symbols less arrogant. + +Version 1.2.10rc3 [April 21, 2006] + Added a note in libpng.txt that png_set_sig_bytes(8) can be used when + writing an embedded PNG without the 8-byte signature. + Revised makefiles and configure to avoid making links to libpng.so.* + +Version 1.2.10 [April 23, 2006] + Reverted configure to "rc2" state. + +Version 1.2.11beta1 [May 31, 2006] + scripts/libpng.pc.in contained "configure" style version info and would + not work with makefiles. + The shared-library makefiles were linking to libpng.so.0 instead of + libpng.so.3 compatibility as the library. + +Version 1.2.11beta2 [June 2, 2006] + Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb) + +Version 1.2.11beta3 [June 5, 2006] + Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin). + Removed the accidental leftover Makefile.in~ (Cosmin). + Avoided potential buffer overflow and optimized buffer in + png_write_sCAL(), png_write_sCAL_s() (Cosmin). + Removed the include directories and libraries from CFLAGS and LDFLAGS + in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin). + +Version 1.2.11beta4 [June 6, 2006] + Allow zero-length IDAT chunks after the entire zlib datastream, but not + after another intervening chunk type. + +Version 1.0.19rc1, 1.2.11rc1 [June 13, 2006] + Deleted extraneous square brackets from [config.h] in configure.ac + +Version 1.0.19rc2, 1.2.11rc2 [June 14, 2006] + Added prototypes for PNG_INCH_CONVERSIONS functions to png.h + Revised INSTALL and autogen.sh + Fixed typo in several makefiles (-W1 should be -Wl) + Added typedef for png_int_32 and png_uint_32 on 64-bit systems. + +Version 1.0.19rc3, 1.2.11rc3 [June 15, 2006] + Removed the new typedefs for 64-bit systems (delay until version 1.4.0) + Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid + reading out of bounds. + +Version 1.0.19rc4, 1.2.11rc4 [June 15, 2006] + Really removed the new typedefs for 64-bit systems. + +Version 1.0.19rc5, 1.2.11rc5 [June 22, 2006] + Removed png_sig_bytes entry from scripts/pngw32.def + +Version 1.0.19, 1.2.11 [June 26, 2006] + None. + +Version 1.0.20, 1.2.12 [June 27, 2006] + Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + +Version 1.2.13beta1 [October 2, 2006] + Removed AC_FUNC_MALLOC from configure.ac + Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h + Change "logical" to "bitwise" throughout documentation. + Detect and fix attempt to write wrong iCCP profile length (CVE-2006-7244) + +Version 1.0.21, 1.2.13 [November 14, 2006] + Fix potential buffer overflow in sPLT chunk handler. + Fix Makefile.am to not try to link to noexistent files. + Check all exported functions for NULL png_ptr. + +Version 1.2.14beta1 [November 17, 2006] + Relocated three misplaced tests for NULL png_ptr. + Built Makefile.in with automake-1.9.6 instead of 1.9.2. + Build configure with autoconf-2.60 instead of 2.59 + +Version 1.2.14beta2 [November 17, 2006] + Added some typecasts in png_zalloc(). + +Version 1.2.14rc1 [November 20, 2006] + Changed "strtod" to "png_strtod" in pngrutil.c + +Version 1.0.22, 1.2.14 [November 27, 2006] + Added missing "$(srcdir)" in Makefile.am and Makefile.in + +Version 1.2.15beta1 [December 3, 2006] + Generated configure with autoconf-2.61 instead of 2.60 + Revised configure.ac to update libpng.pc and libpng-config. + +Version 1.2.15beta2 [December 3, 2006] + Always export MMX asm functions, just stubs if not building pnggccrd.c + +Version 1.2.15beta3 [December 4, 2006] + Add "png_bytep" typecast to profile while calculating length in pngwutil.c + +Version 1.2.15beta4 [December 7, 2006] + Added scripts/CMakeLists.txt + Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta + +Version 1.2.15beta5 [December 7, 2006] + Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c + Revised scripts/CMakeLists.txt + +Version 1.2.15beta6 [December 13, 2006] + Revised scripts/CMakeLists.txt and configure.ac + +Version 1.2.15rc1 [December 18, 2006] + Revised scripts/CMakeLists.txt + +Version 1.2.15rc2 [December 21, 2006] + Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. + Added scripts/makefile.nommx + +Version 1.2.15rc3 [December 25, 2006] + Fixed shared library numbering error that was introduced in 1.2.15beta6. + +Version 1.2.15rc4 [December 27, 2006] + Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set. + +Version 1.2.15rc5 [December 31, 2006] + Revised handling of rgb_to_gray. + +Version 1.2.15 [January 5, 2007] + Added some (unsigned long) typecasts in pngtest.c to avoid printing errors. + +Version 1.2.16beta1 [January 6, 2007] + Fix bugs in makefile.nommx + +Version 1.2.16beta2 [January 16, 2007] + Revised scripts/CMakeLists.txt + +Version 1.2.16 [January 31, 2007] + No changes. + +Version 1.2.17beta1 [March 6, 2007] + Revised scripts/CMakeLists.txt to install both shared and static libraries. + Deleted a redundant line from pngset.c. + +Version 1.2.17beta2 [April 26, 2007] + Relocated misplaced test for png_ptr == NULL in pngpread.c + Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN + flags. + Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_* + Added pngerror() when write_IHDR fails in deflateInit2(). + Added "const" to some array declarations. + Mention examples of libpng usage in the libpng*.txt and libpng.3 documents. + +Version 1.2.17rc1 [May 4, 2007] + No changes. + +Version 1.2.17rc2 [May 8, 2007] + Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications + calling set_unknown_chunk_location() need them. + Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in + png_set_expand_gray_1_2_4_to_8(). + Added png_ptr->unknown_chunk to hold working unknown chunk data, so it + can be free'ed in case of error. Revised unknown chunk handling in + pngrutil.c and pngpread.c to use this structure. + +Version 1.2.17rc3 [May 8, 2007] + Revised symbol-handling in configure script. + +Version 1.2.17rc4 [May 10, 2007] + Revised unknown chunk handling to avoid storing unknown critical chunks. + +Version 1.0.25 [May 15, 2007] +Version 1.2.17 [May 15, 2007] + Added "png_ptr->num_trans=0" before error return in png_handle_tRNS, + to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664) + +Version 1.0.26 [May 15, 2007] +Version 1.2.18 [May 15, 2007] + Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script + +Version 1.2.19beta1 [May 18, 2007] + Changed "const static" to "static PNG_CONST" everywhere, mostly undoing + change of libpng-1.2.17beta2. Changed other "const" to "PNG_CONST" + Changed some handling of unused parameters, to avoid compiler warnings. + "if (unused == NULL) return;" becomes "unused = unused". + +Version 1.2.19beta2 [May 18, 2007] + Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier) + +Version 1.2.19beta3 [May 19, 2007] + Add some "png_byte" typecasts in png_check_keyword() and write new_key + instead of key in zTXt chunk (Kevin Ryde). + +Version 1.2.19beta4 [May 21, 2007] + Add png_snprintf() function and use it in place of sprint() for improved + defense against buffer overflows. + +Version 1.2.19beta5 [May 21, 2007] + Fixed png_handle_tRNS() to only use the valid bits of tRNS value. + Changed handling of more unused parameters, to avoid compiler warnings. + Removed some PNG_CONST in pngwutil.c to avoid compiler warnings. + +Version 1.2.19beta6 [May 22, 2007] + Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c + Added a special "_MSC_VER" case that defines png_snprintf to _snprintf + +Version 1.2.19beta7 [May 22, 2007] + Squelched png_squelch_warnings() in pnggccrd.c and added + an #ifdef PNG_MMX_CODE_SUPPORTED block around the declarations that caused + the warnings that png_squelch_warnings was squelching. + +Version 1.2.19beta8 [May 22, 2007] + Removed __MMX__ from test in pngconf.h. + +Version 1.2.19beta9 [May 23, 2007] + Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro. + Revised png_squelch_warnings() so it might work. + Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86. + +Version 1.2.19beta10 [May 24, 2007] + Resquelched png_squelch_warnings(), use "__attribute__((used))" instead. + +Version 1.4.0beta1 [April 20, 2006] + Enabled iTXt support (changes png_struct, thus requires so-number change). + Cleaned up PNG_ASSEMBLER_CODE_SUPPORTED vs PNG_MMX_CODE_SUPPORTED + Eliminated PNG_1_0_X and PNG_1_2_X macros. + Removed deprecated functions png_read_init, png_write_init, png_info_init, + png_permit_empty_plte, png_set_gray_1_2_4_to_8, png_check_sig, and + removed the deprecated macro PNG_MAX_UINT. + Moved "PNG_INTERNAL" parts of png.h and pngconf.h into pngintrn.h + Removed many WIN32_WCE #ifdefs (Cosmin). + Reduced dependency on C-runtime library when on Windows (Simon-Pierre) + Replaced sprintf() with png_sprintf() (Simon-Pierre) + +Version 1.4.0beta2 [April 20, 2006] + Revised makefiles and configure to avoid making links to libpng.so.* + Moved some leftover MMX-related defines from pngconf.h to pngintrn.h + Updated scripts/pngos2.def, pngw32.def, and projects/wince/png32ce.def + +Version 1.4.0beta3 [May 10, 2006] + Updated scripts/pngw32.def to comment out MMX functions. + Added PNG_NO_GET_INT_32 and PNG_NO_SAVE_INT_32 macros. + Scripts/libpng.pc.in contained "configure" style version info and would + not work with makefiles. + Revised pngconf.h and added pngconf.h.in, so makefiles and configure can + pass defines to libpng and applications. + +Version 1.4.0beta4 [May 11, 2006] + Revised configure.ac, Makefile.am, and many of the makefiles to write + their defines in pngconf.h. + +Version 1.4.0beta5 [May 15, 2006] + Added a missing semicolon in Makefile.am and Makefile.in + Deleted extraneous square brackets from configure.ac + +Version 1.4.0beta6 [June 2, 2006] + Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + Changed sonum from 0 to 1. + Removed unused prototype for png_check_sig() from png.h + +Version 1.4.0beta7 [June 16, 2006] + Exported png_write_sig (Cosmin). + Optimized buffer in png_handle_cHRM() (Cosmin). + Set pHYs = 2835 x 2835 pixels per meter, and added + sCAL = 0.352778e-3 x 0.352778e-3 meters, in pngtest.png (Cosmin). + Added png_set_benign_errors(), png_benign_error(), png_chunk_benign_error(). + Added typedef for png_int_32 and png_uint_32 on 64-bit systems. + Added "(unsigned long)" typecast on png_uint_32 variables in printf lists. + +Version 1.4.0beta8 [June 22, 2006] + Added demonstration of user chunk support in pngtest.c, to support the + public sTER chunk and a private vpAg chunk. + +Version 1.4.0beta9 [July 3, 2006] + Removed ordinals from scripts/pngw32.def and removed png_info_int and + png_set_gray_1_2_4_to_8 entries. + Inline call of png_get_uint_32() in png_get_uint_31(). + Use png_get_uint_31() to get vpAg width and height in pngtest.c + Removed WINCE and Netware projects. + Removed standalone Y2KINFO file. + +Version 1.4.0beta10 [July 12, 2006] + Eliminated automatic copy of pngconf.h to pngconf.h.in from configure and + some makefiles, because it was not working reliably. Instead, distribute + pngconf.h.in along with pngconf.h and cause configure and some of the + makefiles to update pngconf.h from pngconf.h.in. + Added pngconf.h to DEPENDENCIES in Makefile.am + +Version 1.4.0beta11 [August 19, 2006] + Removed AC_FUNC_MALLOC from configure.ac. + Added a warning when writing iCCP profile with mismatched profile length. + Patched pnggccrd.c to assemble on x86_64 platforms. + Moved chunk header reading into a separate function png_read_chunk_header() + in pngrutil.c. The chunk header (len+sig) is now serialized in a single + operation (Cosmin). + Implemented support for I/O states. Added png_ptr member io_state, and + functions png_get_io_chunk_name() and png_get_io_state() in pngget.c + (Cosmin). + Added png_get_io_chunk_name and png_get_io_state to scripts/*.def (Cosmin). + Renamed scripts/pngw32.* to scripts/pngwin.* (Cosmin). + Removed the include directories and libraries from CFLAGS and LDFLAGS + in scripts/makefile.gcc (Cosmin). + Used png_save_uint_32() to set vpAg width and height in pngtest.c (Cosmin). + Cast to proper type when getting/setting vpAg units in pngtest.c (Cosmin). + Added pngintrn.h to the Visual C++ projects (Cosmin). + Removed scripts/list (Cosmin). + Updated copyright year in scripts/pngwin.def (Cosmin). + Removed PNG_TYPECAST_NULL and used standard NULL consistently (Cosmin). + Disallowed the user to redefine png_size_t, and enforced a consistent use + of png_size_t across libpng (Cosmin). + Changed the type of png_ptr->rowbytes, PNG_ROWBYTES() and friends + to png_size_t (Cosmin). + Removed png_convert_size() and replaced png_sizeof with sizeof (Cosmin). + Removed some unnecessary type casts (Cosmin). + Changed prototype of png_get_compression_buffer_size() and + png_set_compression_buffer_size() to work with png_size_t instead of + png_uint_32 (Cosmin). + Removed png_memcpy_check() and png_memset_check() (Cosmin). + Fixed a typo (png_byte --> png_bytep) in libpng.3 and libpng.txt (Cosmin). + Clarified that png_zalloc() does not clear the allocated memory, + and png_zalloc() and png_zfree() cannot be PNGAPI (Cosmin). + Renamed png_mem_size_t to png_alloc_size_t, fixed its definition in + pngconf.h, and used it in all memory allocation functions (Cosmin). + Renamed pngintrn.h to pngpriv.h, added a comment at the top of the file + mentioning that the symbols declared in that file are private, and + updated the scripts and the Visual C++ projects accordingly (Cosmin). + Removed circular references between pngconf.h and pngconf.h.in in + scripts/makefile.vc*win32 (Cosmin). + Removing trailing '.' from the warning and error messages (Cosmin). + Added pngdefs.h that is built by makefile or configure, instead of + pngconf.h.in (Glenn). + Detect and fix attempt to write wrong iCCP profile length. + +Version 1.4.0beta12 [October 19, 2006] + Changed "logical" to "bitwise" in the documentation. + Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h + Add a typecast to stifle compiler warning in pngrutil.c + +Version 1.4.0beta13 [November 10, 2006] + Fix potential buffer overflow in sPLT chunk handler. + Fix Makefile.am to not try to link to noexistent files. + +Version 1.4.0beta14 [November 15, 2006] + Check all exported functions for NULL png_ptr. + +Version 1.4.0beta15 [November 17, 2006] + Relocated two misplaced tests for NULL png_ptr. + Built Makefile.in with automake-1.9.6 instead of 1.9.2. + Build configure with autoconf-2.60 instead of 2.59 + Add "install: all" in Makefile.am so "configure; make install" will work. + +Version 1.4.0beta16 [November 17, 2006] + Added a typecast in png_zalloc(). + +Version 1.4.0beta17 [December 4, 2006] + Changed "new_key[79] = '\0';" to "(*new_key)[79] = '\0';" in pngwutil.c + Add "png_bytep" typecast to profile while calculating length in pngwutil.c + +Version 1.4.0beta18 [December 7, 2006] + Added scripts/CMakeLists.txt + +Version 1.4.0beta19 [May 16, 2007] + Revised scripts/CMakeLists.txt + Rebuilt configure and Makefile.in with newer tools. + Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. + Added scripts/makefile.nommx + +Version 1.4.0beta20 [July 9, 2008] + Moved several PNG_HAVE_* macros from pngpriv.h to png.h because applications + calling set_unknown_chunk_location() need them. + Moved several macro definitions from pngpriv.h to pngconf.h + Merge with changes to the 1.2.X branch, as of 1.2.30beta04. + Deleted all use of the MMX assembler code and Intel-licensed optimizations. + Revised makefile.mingw + +Version 1.4.0beta21 [July 21, 2008] + Moved local array "chunkdata" from pngrutil.c to the png_struct, so + it will be freed by png_read_destroy() in case of a read error (Kurt + Christensen). + +Version 1.4.0beta22 [July 21, 2008] + Change "purpose" and "buffer" to png_ptr->chunkdata to avoid memory leaking. + +Version 1.4.0beta23 [July 22, 2008] + Change "chunkdata = NULL" to "png_ptr->chunkdata = NULL" several places in + png_decompress_chunk(). + +Version 1.4.0beta24 [July 25, 2008] + Change all remaining "chunkdata" to "png_ptr->chunkdata" in + png_decompress_chunk(), and remove "chunkdata" from parameter list. + Put a call to png_check_chunk_name() in png_read_chunk_header(). + Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte. + Removed two calls to png_check_chunk_name() occuring later in the process. + Define PNG_NO_ERROR_NUMBERS by default in pngconf.h + +Version 1.4.0beta25 [July 30, 2008] + Added a call to png_check_chunk_name() in pngpread.c + Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte. + Added png_push_have_buffer() function to pngpread.c + Eliminated PNG_BIG_ENDIAN_SUPPORTED and associated png_get_* macros. + Made inline expansion of png_get_*() optional with PNG_USE_READ_MACROS. + Eliminated all PNG_USELESS_TESTS and PNG_CORRECT_PALETTE_SUPPORTED code. + Synced contrib directory and configure files with libpng-1.2.30beta06. + Eliminated no-longer-used pngdefs.h (but it's still built in the makefiles) + Relocated a misplaced "#endif /* PNG_NO_WRITE_FILTER */" in pngwutil.c + +Version 1.4.0beta26 [August 4, 2008] + Removed png_push_have_buffer() function in pngpread.c. It increased the + compiled library size slightly. + Changed "-Wall" to "-W -Wall" in the CFLAGS in all makefiles (Cosmin Truta) + Declared png_ptr "volatile" in pngread.c and pngwrite.c to avoid warnings. + Updated contrib/visupng/cexcept.h to version 2.0.1 + Added PNG_LITERAL_CHARACTER macros for #, [, and ]. + +Version 1.4.0beta27 [August 5, 2008] + Revised usage of PNG_LITERAL_SHARP in pngerror.c. + Moved newline character from individual png_debug messages into the + png_debug macros. + Allow user to #define their own png_debug, png_debug1, and png_debug2. + +Version 1.4.0beta28 [August 5, 2008] + Revised usage of PNG_LITERAL_SHARP in pngerror.c. + Added PNG_STRING_NEWLINE macro + +Version 1.4.0beta29 [August 9, 2008] + Revised usage of PNG_STRING_NEWLINE to work on non-ISO compilers. + Added PNG_STRING_COPYRIGHT macro. + Added non-ISO versions of png_debug macros. + +Version 1.4.0beta30 [August 14, 2008] + Added premultiplied alpha feature (Volker Wiendl). + +Version 1.4.0beta31 [August 18, 2008] + Moved png_set_premultiply_alpha from pngtrans.c to pngrtran.c + Removed extra crc check at the end of png_handle_cHRM(). Bug introduced + in libpng-1.4.0beta20. + +Version 1.4.0beta32 [August 19, 2008] + Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call. + Revised PNG_NO_STDIO version of png_write_flush() + +Version 1.4.0beta33 [August 20, 2008] + Added png_get|set_chunk_cache_max() to limit the total number of sPLT, + text, and unknown chunks that can be stored. + +Version 1.4.0beta34 [September 6, 2008] + Shortened tIME_string to 29 bytes in pngtest.c + Fixed off-by-one error introduced in png_push_read_zTXt() function in + libpng-1.2.30beta04/pngpread.c (Harald van Dijk) + +Version 1.4.0beta35 [October 6, 2008] + Changed "trans_values" to "trans_color". + Changed so-number from 0 to 14. Some OS do not like 0. + Revised makefile.darwin to fix shared library numbering. + Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8() + in example.c (debian bug report) + +Version 1.4.0beta36 [October 25, 2008] + Sync with tEXt vulnerability fix in libpng-1.2.33rc02. + +Version 1.4.0beta37 [November 13, 2008] + Added png_check_cHRM in png.c and moved checking from pngget.c, pngrutil.c, + and pngwrite.c + +Version 1.4.0beta38 [November 22, 2008] + Added check for zero-area RGB cHRM triangle in png_check_cHRM() and + png_check_cHRM_fixed(). + +Version 1.4.0beta39 [November 23, 2008] + Revised png_warning() to write its message on standard output by default + when warning_fn is NULL. + +Version 1.4.0beta40 [November 24, 2008] + Eliminated png_check_cHRM(). Instead, always use png_check_cHRM_fixed(). + In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant + check for all-zero coordinates that is detected by the triangle check. + +Version 1.4.0beta41 [November 26, 2008] + Fixed string vs pointer-to-string error in png_check_keyword(). + Rearranged test expressions in png_check_cHRM_fixed() to avoid internal + overflows. + Added PNG_NO_CHECK_cHRM conditional. + +Version 1.4.0beta42, 43 [December 1, 2008] + Merge png_debug with version 1.2.34beta04. + +Version 1.4.0beta44 [December 6, 2008] + Removed redundant check for key==NULL before calling png_check_keyword() + to ensure that new_key gets initialized and removed extra warning + (Merge with version 1.2.34beta05 -- Arvan Pritchard). + +Version 1.4.0beta45 [December 9, 2008] + In png_write_png(), respect the placement of the filler bytes in an earlier + call to png_set_filler() (Jim Barry). + +Version 1.4.0beta46 [December 10, 2008] + Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and + PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated + PNG_TRANSFORM_STRIP_FILLER (Jim Barry). + +Version 1.4.0beta47 [December 15, 2008] + Support for dithering was disabled by default, because it has never + been well tested and doesn't work very well. The code has not + been removed, however, and can be enabled by building libpng with + PNG_READ_DITHER_SUPPORTED defined. + +Version 1.4.0beta48 [February 14, 2009] + Added new exported function png_calloc(). + Combined several instances of png_malloc(); png_memset() into png_calloc(). + Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 + but was never defined. + +Version 1.4.0beta49 [February 28, 2009] + Added png_fileno() macro to pngconf.h, used in pngwio.c + Corrected order of #ifdef's in png_debug definition in png.h + Fixed bug introduced in libpng-1.4.0beta48 with the memset arguments + for pcal_params. + Fixed order of #ifdef directives in the png_debug defines in png.h + (bug introduced in libpng-1.2.34/1.4.0beta29). + Revised comments in png_set_read_fn() and png_set_write_fn(). + +Version 1.4.0beta50 [March 18, 2009] + Use png_calloc() instead of png_malloc() to allocate big_row_buf when + reading an interlaced file, to avoid a possible UMR. + Undid revision of PNG_NO_STDIO version of png_write_flush(). Users + having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined + or supply their own flush_fn() replacement. + Revised libpng*.txt and png.h documentation about use of png_write_flush() + and png_set_write_fn(). + Removed fflush() from pngtest.c. + Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h + +Version 1.4.0beta51 [March 21, 2009] + Removed new png_fileno() macro from pngconf.h . + +Version 1.4.0beta52 [March 27, 2009] + Relocated png_do_chop() ahead of building gamma tables in pngrtran.c + This avoids building 16-bit gamma tables unnecessarily. + Removed fflush() from pngtest.c. + Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h + Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt + +Version 1.4.0beta53 [April 1, 2009] + Removed some remaining MMX macros from pngpriv.h + Fixed potential memory leak of "new_name" in png_write_iCCP() (Ralph Giles) + +Version 1.4.0beta54 [April 13, 2009] + Added "ifndef PNG_SKIP_SETJMP_CHECK" block in pngconf.h to allow + application code writers to bypass the check for multiple inclusion + of setjmp.h when they know that it is safe to ignore the situation. + Eliminated internal use of setjmp() in pngread.c and pngwrite.c + Reordered ancillary chunks in pngtest.png to be the same as what + pngtest now produces, and made some cosmetic changes to pngtest output. + Eliminated deprecated png_read_init_3() and png_write_init_3() functions. + +Version 1.4.0beta55 [April 15, 2009] + Simplified error handling in pngread.c and pngwrite.c by putting + the new png_read_cleanup() and png_write_cleanup() functions inline. + +Version 1.4.0beta56 [April 25, 2009] + Renamed "user_chunk_data" to "my_user_chunk_data" in pngtest.c to suppress + "shadowed declaration" warning from gcc-4.3.3. + Renamed "gamma" to "png_gamma" in pngset.c to avoid "shadowed declaration" + warning about a global "gamma" variable in math.h on some platforms. + +Version 1.4.0beta57 [May 2, 2009] + Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 + but was never defined (again). + Rebuilt configure scripts with autoconf-2.63 instead of 2.62 + Removed pngprefs.h and MMX from makefiles + +Version 1.4.0beta58 [May 14, 2009] + Changed pngw32.def to pngwin.def in makefile.mingw (typo was introduced + in beta57). + Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri) + +Version 1.4.0beta59 [May 15, 2009] + Reformated sources in libpng style (3-space intentation, comment format) + Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG) + Added sections about the git repository and our coding style to the + documentation + Relocated misplaced #endif in pngwrite.c, sCAL chunk handler. + +Version 1.4.0beta60 [May 19, 2009] + Conditionally compile png_read_finish_row() which is not used by + progressive readers. + Added contrib/pngminim/preader to demonstrate building minimal progressive + decoder, based on contrib/gregbook with embedded libpng and zlib. + +Version 1.4.0beta61 [May 20, 2009] + In contrib/pngminim/*, renamed "makefile.std" to "makefile", since there + is only one makefile in those directories, and revised the README files + accordingly. + More reformatting of comments, mostly to capitalize sentences. + +Version 1.4.0beta62 [June 2, 2009] + Added "#define PNG_NO_WRITE_SWAP" to contrib/pngminim/encoder/pngusr.h + and "define PNG_NO_READ_SWAP" to decoder/pngusr.h and preader/pngusr.h + Reformatted several remaining "else statement" into two lines. + Added a section to the libpng documentation about using png_get_io_ptr() + in configure scripts to detect the presence of libpng. + +Version 1.4.0beta63 [June 15, 2009] + Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR() + multiple times and to specify the sample order in the tRNS chunk, + because the ISO PNG specification has a typo in the tRNS table. + Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to + PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism + available for ignoring known chunks even when not saving unknown chunks. + Adopted preference for consistent use of "#ifdef" and "#ifndef" versus + "#if defined()" and "if !defined()" where possible. + +Version 1.4.0beta64 [June 24, 2009] + Eliminated PNG_LEGACY_SUPPORTED code. + Moved the various unknown chunk macro definitions outside of the + PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks. + +Version 1.4.0beta65 [June 26, 2009] + Added a reference to the libpng license in each file. + +Version 1.4.0beta66 [June 27, 2009] + Refer to the libpng license instead of the libpng license in each file. + +Version 1.4.0beta67 [July 6, 2009] + Relocated INVERT_ALPHA within png_read_png() and png_write_png(). + Added high-level API transform PNG_TRANSFORM_GRAY_TO_RGB. + Added an "xcode" project to the projects directory (Alam Arias). + +Version 1.4.0beta68 [July 19, 2009] + Avoid some tests in filter selection in pngwutil.c + +Version 1.4.0beta69 [July 25, 2009] + Simplified the new filter-selection test. This runs faster in the + common "PNG_ALL_FILTERS" and PNG_FILTER_NONE cases. + Removed extraneous declaration from the new call to png_read_gray_to_rgb() + (bug introduced in libpng-1.4.0beta67). + Fixed up xcode project (Alam Arias) + Added a prototype for png_64bit_product() in png.c + +Version 1.4.0beta70 [July 27, 2009] + Avoid a possible NULL dereference in debug build, in png_set_text_2(). + (bug introduced in libpng-0.95, discovered by Evan Rouault) + +Version 1.4.0beta71 [July 29, 2009] + Rebuilt configure scripts with autoconf-2.64. + +Version 1.4.0beta72 [August 1, 2009] + Replaced *.tar.lzma with *.tar.xz in distribution. Get the xz codec + from . + +Version 1.4.0beta73 [August 1, 2009] + Reject attempt to write iCCP chunk with negative embedded profile length + (JD Chen) (CVE-2009-5063). + +Version 1.4.0beta74 [August 8, 2009] + Changed png_ptr and info_ptr member "trans" to "trans_alpha". + +Version 1.4.0beta75 [August 21, 2009] + Removed an extra png_debug() recently added to png_write_find_filter(). + Fixed incorrect #ifdef in pngset.c regarding unknown chunk support. + +Version 1.4.0beta76 [August 22, 2009] + Moved an incorrectly located test in png_read_row() in pngread.c + +Version 1.4.0beta77 [August 27, 2009] + Removed lpXYZ.tar.bz2 (with CRLF), KNOWNBUG, libpng-x.y.z-KNOWNBUG.txt, + and the "noconfig" files from the distribution. + Moved CMakeLists.txt from scripts into the main libpng directory. + Various bugfixes and improvements to CMakeLists.txt (Philip Lowman) + +Version 1.4.0beta78 [August 31, 2009] + Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h + Eliminated PNG_NO_FREE_ME and PNG_FREE_ME_SUPPORTED macros. + Use png_malloc plus a loop instead of png_calloc() to initialize + row_pointers in png_read_png(). + +Version 1.4.0beta79 [September 1, 2009] + Eliminated PNG_GLOBAL_ARRAYS and PNG_LOCAL_ARRAYS; always use local arrays. + Eliminated PNG_CALLOC_SUPPORTED macro and always provide png_calloc(). + +Version 1.4.0beta80 [September 17, 2009] + Removed scripts/libpng.icc + Changed typecast of filler from png_byte to png_uint_16 in png_set_filler(). + (Dennis Gustafsson) + Fixed typo introduced in beta78 in pngtest.c ("#if def " should be "#ifdef ") + +Version 1.4.0beta81 [September 23, 2009] + Eliminated unused PNG_FLAG_FREE_* defines from pngpriv.h + Expanded TAB characters in pngrtran.c + Removed PNG_CONST from all "PNG_CONST PNG_CHNK" declarations to avoid + compiler complaints about doubly declaring things "const". + Changed all "#if [!]defined(X)" to "if[n]def X" where possible. + Eliminated unused png_ptr->row_buf_size + +Version 1.4.0beta82 [September 25, 2009] + Moved redundant IHDR checking into new png_check_IHDR() in png.c + and report all errors found in the IHDR data. + Eliminated useless call to png_check_cHRM() from pngset.c + +Version 1.4.0beta83 [September 25, 2009] + Revised png_check_IHDR() to eliminate bogus complaint about filter_type. + +Version 1.4.0beta84 [September 30, 2009] + Fixed some inconsistent indentation in pngconf.h + Revised png_check_IHDR() to add a test for width variable less than 32-bit. + +Version 1.4.0beta85 [October 1, 2009] + Revised png_check_IHDR() again, to check info_ptr members instead of + the contents of the returned parameters. + +Version 1.4.0beta86 [October 9, 2009] + Updated the "xcode" project (Alam Arias). + Eliminated a shadowed declaration of "pp" in png_handle_sPLT(). + +Version 1.4.0rc01 [October 19, 2009] + Trivial cosmetic changes. + +Version 1.4.0beta87 [October 30, 2009] + Moved version 1.4.0 back into beta. + +Version 1.4.0beta88 [October 30, 2009] + Revised libpng*.txt section about differences between 1.2.x and 1.4.0 + because most of the new features have now been ported back to 1.2.41 + +Version 1.4.0beta89 [November 1, 2009] + More bugfixes and improvements to CMakeLists.txt (Philip Lowman) + Removed a harmless extra png_set_invert_alpha() from pngwrite.c + Apply png_user_chunk_cache_max within png_decompress_chunk(). + Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate. + +Version 1.4.0beta90 [November 2, 2009] + Removed all remaining WIN32_WCE #ifdefs except those involving the + time.h "tm" structure + +Version 1.4.0beta91 [November 3, 2009] + Updated scripts/pngw32.def and projects/wince/png32ce.def + Copied projects/wince/png32ce.def to the scripts directory. + Added scripts/makefile.wce + Patched ltmain.sh for wince support. + Added PNG_CONVERT_tIME_SUPPORTED macro. + +Version 1.4.0beta92 [November 4, 2009] + Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED + Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED + Revised libpng*.txt to describe differences from 1.2.40 to 1.4.0 (instead + of differences from 1.2.41 to 1.4.0) + +Version 1.4.0beta93 [November 7, 2009] + Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and + PNG_ALLOCATED macros to detect deprecated direct access to the + png_struct or info_struct members and other deprecated usage in + applications (John Bowler). + Updated scripts/makefile* to add "-DPNG_CONFIGURE_LIBPNG" to CFLAGS, + to prevent warnings about direct access to png structs by libpng + functions while building libpng. They need to be tested, especially + those using compilers other than gcc. + Updated projects/visualc6 and visualc71 with "/d PNG_CONFIGURE_LIBPNG". + They should work but still need to be updated to remove + references to pnggccrd.c or pngvcrd.c and ASM building. + Added README.txt to the beos, cbuilder5, netware, and xcode projects warning + that they need to be updated, to remove references to pnggccrd.c and + pngvcrd.c and to depend on pngpriv.h + Removed three direct references to read_info_ptr members in pngtest.c + that were detected by the new PNG_DEPSTRUCT macro. + Moved the png_debug macro definitions and the png_read_destroy(), + png_write_destroy() and png_far_to_near() prototypes from png.h + to pngpriv.h (John Bowler) + Moved the synopsis lines for png_read_destroy(), png_write_destroy() + png_debug(), png_debug1(), and png_debug2() from libpng.3 to libpngpf.3. + +Version 1.4.0beta94 [November 9, 2009] + Removed the obsolete, unused pnggccrd.c and pngvcrd.c files. + Updated CMakeLists.txt to add "-DPNG_CONFIGURE_LIBPNG" to the definitions. + Removed dependency of pngtest.o on pngpriv.h in the makefiles. + Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined. + +Version 1.4.0beta95 [November 10, 2009] + Changed png_check_sig() to !png_sig_cmp() in contrib programs. + Added -DPNG_CONFIGURE_LIBPNG to contrib/pngminm/*/makefile + Changed png_check_sig() to !png_sig_cmp() in contrib programs. + Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c + Changed pngminim/*/gather.sh to stop trying to remove pnggccrd.c and pngvcrd.c + Added dependency on pngpriv.h in contrib/pngminim/*/makefile + +Version 1.4.0beta96 [November 12, 2009] + Renamed scripts/makefile.wce to scripts/makefile.cegcc + Revised Makefile.am to use libpng.sys while building libpng.so + so that only PNG_EXPORT functions are exported. + Removed the deprecated png_check_sig() function/macro. + Removed recently removed function names from scripts/*.def + Revised pngtest.png to put chunks in the same order written by pngtest + (evidently the same change made in libpng-1.0beta54 was lost). + Added PNG_PRIVATE macro definition in pngconf.h for possible future use. + +Version 1.4.0beta97 [November 13, 2009] + Restored pngtest.png to the libpng-1.4.0beta7 version. + Removed projects/beos and netware.txt; no one seems to be supporting them. + Revised Makefile.in + +Version 1.4.0beta98 [November 13, 2009] + Added the "xcode" project to zip distributions, + Fixed a typo in scripts/pngwin.def introduced in beta97. + +Version 1.4.0beta99 [November 14, 2009] + Moved libpng-config.in and libpng.pc-configure.in out of the scripts + directory, to libpng-config.in and libpng-pc.in, respectively, and + modified Makefile.am and configure.ac accordingly. Now "configure" + needs nothing from the "scripts" directory. + Avoid redefining PNG_CONST in pngconf.h + +Version 1.4.0beta100 [November 14, 2009] + Removed ASM builds from projects/visualc6 and projects/visualc71 + Removed scripts/makefile.nommx and makefile.vcawin32 + Revised CMakeLists.txt to account for new location of libpng-config.in + and libpng-pc.in + Updated INSTALL to reflect removal and relocation of files. + +Version 1.4.0beta101 [November 14, 2009] + Restored the binary files (*.jpg, *.png, some project files) that were + accidentally deleted from the zip and 7z distributions when the xcode + project was added. + +Version 1.4.0beta102 [November 18, 2009] + Added libpng-config.in and libpng-pc.in to the zip and 7z distributions. + Fixed a typo in projects/visualc6/pngtest.dsp, introduced in beta100. + Moved descriptions of makefiles and other scripts out of INSTALL into + scripts/README.txt + Updated the copyright year in scripts/pngwin.rc from 2006 to 2009. + +Version 1.4.0beta103 [November 21, 2009] + Removed obsolete comments about ASM from projects/visualc71/README_zlib.txt + Align row_buf on 16-byte boundary in memory. + Restored the PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED guard around the call + to png_flush() after png_write_IEND(). See 1.4.0beta32, 1.4.0beta50 + changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES. Someone + needs this feature. + Make the 'png_jmpbuf' macro expand to a call that records the correct + longjmp function as well as returning a pointer to the setjmp + jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'. + (John Bowler) + +Version 1.4.0beta104 [November 22, 2009] + Removed png_longjmp_ptr from scripts/*.def and libpng.3 + Rebuilt configure scripts with autoconf-2.65 + +Version 1.4.0beta105 [November 25, 2009] + Use fast integer PNG_DIVIDE_BY_255() or PNG_DIVIDE_BY_65535() + to accomplish alpha premultiplication when + PNG_READ_COMPOSITE_NODIV_SUPPORTED is defined. + Changed "/255" to "/255.0" in background calculations to make it clear + that the 255 is used as a double. + +Version 1.4.0beta106 [November 27, 2009] + Removed premultiplied alpha feature. + +Version 1.4.0beta107 [December 4, 2009] + Updated README + Added "#define PNG_NO_PEDANTIC_WARNINGS" in the libpng source files. + Removed "-DPNG_CONFIGURE_LIBPNG" from the makefiles and projects. + Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco + to put png.h and pngconf.h in $prefix/include, like the other scripts, + instead of in $prefix/include/libpng. Also revised makefile.sco + to put them in $prefix/include/libpng15 instead of in + $prefix/include/libpng/libpng15. + +Version 1.4.0beta108 [December 11, 2009] + Removed leftover "-DPNG_CONFIGURE_LIBPNG" from contrib/pngminim/*/makefile + Relocated png_do_chop() to its original position in pngrtran.c; the + change in version 1.2.41beta08 caused transparency to be handled wrong + in some 16-bit datastreams (Yusaku Sugai). + +Version 1.4.0beta109 [December 13, 2009] + Added "bit_depth" parameter to the private png_build_gamma_table() function. + Pass bit_depth=8 to png_build_gamma_table() when bit_depth is 16 but the + PNG_16_TO_8 transform has been set, to avoid unnecessary build of 16-bit + tables. + +Version 1.4.0rc02 [December 20, 2009] + Declared png_cleanup_needed "volatile" in pngread.c and pngwrite.c + +Version 1.4.0rc03 [December 22, 2009] + Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt + (revising the change in 1.4.0beta99) + +Version 1.4.0rc04 [December 25, 2009] + Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED + in pngset.c to be consistent with other changes in version 1.2.38. + +Version 1.4.0rc05 [December 25, 2009] + Changed "libpng-pc.in" to "libpng.pc.in" in configure.ac, configure, and + Makefile.in to be consistent with changes in libpng-1.4.0rc03 + +Version 1.4.0rc06 [December 29, 2009] + Reverted the gamma_table changes from libpng-1.4.0beta109. + Fixed some indentation errors. + +Version 1.4.0rc07 [January 1, 2010] + Revised libpng*.txt and libpng.3 about 1.2.x->1.4.x differences. + Use png_calloc() instead of png_malloc(); png_memset() in pngrutil.c + Update copyright year to 2010. + +Version 1.4.0rc08 [January 2, 2010] + Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr + in pngtest.c + +Version 1.4.0 [January 3, 2010] + No changes. + +Version 1.4.1beta01 [January 8, 2010] + Updated CMakeLists.txt for consistent indentation and to avoid an + unclosed if-statement warning (Philip Lowman). + Revised Makefile.am and Makefile.in to remove references to Y2KINFO, + KNOWNBUG, and libpng.la (Robert Schwebel). + Revised the makefiles to install the same files and symbolic + links as configure, except for libpng.la and libpng14.la. + Make png_set|get_compression_buffer_size() available even when + PNG_WRITE_SUPPORTED is not enabled. + Revised Makefile.am and Makefile.in to simplify their maintenance. + Revised scripts/makefile.linux to install a link to libpng14.so.14.1 + +Version 1.4.1beta02 [January 9, 2010] + Revised the rest of the makefiles to install a link to libpng14.so.14.1 + +Version 1.4.1beta03 [January 10, 2010] + Removed png_set_premultiply_alpha() from scripts/*.def + +Version 1.4.1rc01 [January 16, 2010] + No changes. + +Version 1.4.1beta04 [January 23, 2010] + Revised png_decompress_chunk() to improve speed and memory usage when + decoding large chunks. + Added png_set|get_chunk_malloc_max() functions. + +Version 1.4.1beta05 [January 26, 2010] + Relocated "int k" declaration in pngtest.c to minimize its scope. + +Version 1.4.1beta06 [January 28, 2010] + Revised png_decompress_chunk() to use a two-pass method suggested by + John Bowler. + +Version 1.4.1beta07 [February 6, 2010] + Folded some long lines in the source files. + Added defineable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX, + and a PNG_USER_LIMITS_SUPPORTED flag. + Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as + png_ptr->png_user_chunk_malloc_max. + Revised png_push_save_buffer() to do fewer but larger png_malloc() calls. + +Version 1.4.1beta08 [February 6, 2010] + Minor cleanup and updating of dates and copyright year. + +Version 1.5.0beta01 [February 7, 2010] + Moved declaration of png_struct into private pngstruct.h and png_info + into pnginfo.h + +Version 1.4.1beta09 and 1.5.0beta02 [February 7, 2010] + Reverted to original png_push_save_buffer() code. + +Version 1.4.1beta10 and 1.5.0beta03 [February 8, 2010] + Return allocated "old_buffer" in png_push_save_buffer() before + calling png_error(), to avoid a potential memory leak. + Updated configure script to use SO number 15. + +Version 1.5.0beta04 [February 9, 2010] + Removed malformed "incomplete struct declaration" of png_info from png.h + +Version 1.5.0beta05 [February 12, 2010] + Removed PNG_DEPSTRUCT markup in pngstruct.h and pnginfo.h, and undid the + linewrapping that it entailed. + Revised comments in pngstruct.h and pnginfo.h and added pointers to + the libpng license. + Changed PNG_INTERNAL to PNG_EXPOSE_INTERNAL_STRUCTURES + Removed the cbuilder5 project, which has not been updated to 1.4.0. + +Version 1.4.1beta12 and 1.5.0beta06 [February 14, 2010] + Fixed type declaration of png_get_chunk_malloc_max() in pngget.c (Daisuke + Nishikawa) + +Version 1.5.0beta07 [omitted] + +Version 1.5.0beta08 [February 19, 2010] + Changed #ifdef PNG_NO_STDIO_SUPPORTED to #ifdef PNG_NO_CONSOLE_IO_SUPPORTED + wherever png_snprintf() is used to construct error and warning messages. + Noted in scripts/makefile.mingw that it expects to be run under MSYS. + Removed obsolete unused MMX-querying support from contrib/gregbook + Added exported png_longjmp() function. + Removed the AIX redefinition of jmpbuf in png.h + Added -D_ALLSOURCE in configure.ac, makefile.aix, and CMakeLists.txt + when building on AIX. + +Version 1.5.0beta09 [February 19, 2010] + Removed -D_ALLSOURCE from configure.ac, makefile.aix, and CMakeLists.txt. + Changed the name of png_ptr->jmpbuf to png_ptr->png_jmpbuf in pngstruct.h + +Version 1.5.0beta10 [February 25, 2010] + Removed unused gzio.c from contrib/pngminim gather and makefile scripts + Removed replacement error handlers from contrib/gregbook. Because of + the new png_longjmp() function they are no longer needed. + +Version 1.5.0beta11 [March 6, 2010] + Removed checking for already-included setjmp.h from pngconf.h + Fixed inconsistent indentations and made numerous cosmetic changes. + Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5 + +Version 1.5.0beta12 [March 9, 2010] + Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from + the source files, along with "#define PNG_EXPOSE_INTERNAL_STRUCTURES" + and "#define PNG_NO_PEDANTIC_WARNINGS" (John Bowler). + Created new pngdebug.h and moved debug definitions there. + +Version 1.5.0beta13 [March 10, 2010] + Protect pngstruct.h, pnginfo.h, and pngdebug.h from being included twice. + Revise the "#ifdef" blocks in png_inflate() so it will compile when neither + PNG_USER_CHUNK_MALLOC_MAX nor PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED + is defined. + Removed unused png_measure_compressed_chunk() from pngpriv.h and libpngpf.3 + Moved the 'config.h' support from pngconf.h to pngpriv.h + Removed PNGAPI from the png_longjmp_ptr typedef. + Eliminated dependence of pngtest.c on the private pngdebug.h file. + Make all png_debug macros into *unterminated* statements or + expressions (i.e. a trailing ';' must always be added) and correct + the format statements in various png_debug messages. + +Version 1.5.0beta14 [March 14, 2010] + Removed direct access to png_ptr->io_ptr from the Windows code in pngtest.c + Revised Makefile.am to account for recent additions and replacements. + Corrected CE and OS/2 DEF files (scripts/png*def) for symbols removed and + added ordinal numbers to the Windows DEF file and corrected the duplicated + ordinal numbers on CE symbols that are commented out. + Added back in export symbols that can be present in the Windows build but + are disabled by default. + PNG_EXPORT changed to include an 'ordinal' field for DEF file generation. + PNG_CALLBACK added to make callback definitions uniform. PNGAPI split + into PNGCAPI (base C form), PNGAPI (exports) and PNGCBAPI (callbacks), + and appropriate changes made to all files. Cygwin builds re-hinged to + allow procedure call standard changes and to remove the need for the DEF + file (fixes build on Cygwin). + Enabled 'attribute' warnings that are relevant to library APIs and callbacks. + Changed rules for generation of the various symbol files and added a new + rule for a DEF file (which is also added to the distribution). + Updated the symbol file generation to stop it adding spurious spaces + to EOL (coming from preprocessor macro expansion). Added a facility + to join tokens in the output and rewrite *.dfn to use this. + Eliminated scripts/*.def in favor of libpng.def; updated projects/visualc71 + and removed scripts/makefile.cygwin. + Made PNG_BUILD_DLL safe: it can be set whenever a DLL is being built. + Removed the include of sys/types.h - apparently unnecessary now on the + platforms on which it happened (all but Mac OS and RISC OS). + Moved the Mac OS test into pngpriv.h (the only place it is used.) + +Version 1.5.0beta15 [March 17, 2010] + Added symbols.chk target to Makefile.am to validate the symbols in png.h + against the new DEF file scripts/symbols.def. + Changed the default DEF file back to pngwin.def. + Removed makefile.mingw. + Eliminated PNG_NO_EXTERN and PNG_ALL_EXTERN + +Version 1.5.0beta16 [April 1, 2010] + Make png_text_struct independent of PNG_iTXt_SUPPORTED, so that + fields are initialized in all configurations. The READ/WRITE + macros (PNG_(READ|WRITE)_iTXt_SUPPORTED) still function as + before to disable code to actually read or write iTXt chunks + and iTXt_SUPPORTED can be used to detect presence of either + read or write support (but it is probably better to check for + the one actually required - read or write.) + Combined multiple png_warning() calls for a single error. + Restored the macro definition of png_check_sig(). + +Version 1.5.0beta17 [April 17, 2010] + Added some "(long)" typecasts to printf calls in png_handle_cHRM(). + Documented the fact that png_set_dither() was disabled since libpng-1.4.0. + Reenabled png_set_dither() but renamed it to png_set_quantize() to reflect + more accurately what it actually does. At the same time, renamed + the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros to + PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS. + Added some "(long)" typecasts to printf calls in png_handle_cHRM(). + Freeze build-time only configuration in the build. + In all prior versions of libpng most configuration options + controlled by compiler #defines had to be repeated by the + application code that used libpng. This patch changes this + so that compilation options that can only be changed at build + time are frozen in the build. Options that are compiler + dependent (and those that are system dependent) are evaluated + each time - pngconf.h holds these. Options that can be changed + per-file in the application are in png.h. Frozen options are + in the new installed header file pnglibconf.h (John Bowler) + Removed the xcode project because it has not been updated to work + with libpng-1.5.0. + Removed the ability to include optional pngusr.h + +Version 1.5.0beta18 [April 17, 2010] + Restored the ability to include optional pngusr.h + Moved replacements for png_error() and png_warning() from the + contrib/pngminim project to pngerror.c, for use when warnings or + errors are disabled via PNG_NO_WARN or PNG_NO_ERROR_TEXT, to avoid + storing unneeded error/warning text. + Updated contrib/pngminim project to work with the new pnglibconf.h + Added some PNG_NO_* defines to contrib/pngminim/*/pngusr.h to save space. + +Version 1.5.0beta19 [April 24, 2010] + Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED. This allows the functions + to read and write ints to be disabled independently of PNG_USE_READ_MACROS, + which allows libpng to be built with the functions even though the default + is to use the macros - this allows applications to choose at app build + time whether or not to use macros (previously impossible because the + functions weren't in the default build.) + Changed Windows calling convention back to __cdecl for API functions. + For Windows/x86 platforms only: + __stdcall is no longer needed for Visual Basic, so libpng-1.5.0 uses + __cdecl throughout (both API functions and callbacks) on Windows/x86 + platforms. + Replaced visualc6 and visualc71 projects with new vstudio project + Relaxed the overly-restrictive permissions of some files. + +Version 1.5.0beta20 [April 24, 2010] + Relaxed more overly-restrictive permissions of some files. + +Version 1.5.0beta21 [April 27, 2010] + Removed some unwanted binary bytes and changed CRLF to NEWLINE in the new + vstudio project files, and some trivial editing of some files in the + scripts directory. + Set PNG_NO_READ_BGR, PNG_NO_IO_STATE, and PNG_NO_TIME_RFC1123 in + contrib/pngminim/decoder/pngusr.h to make a smaller decoder application. + +Version 1.5.0beta22 [April 28, 2010] + Fixed dependencies of GET_INT_32 - it does not require READ_INT_FUNCTIONS + because it has a macro equivalent. + Improved the options.awk script; added an "everything off" option. + Revised contrib/pngminim to use the "everything off" option in pngusr.dfa. + +Version 1.5.0beta23 [April 29, 2010] + Corrected PNG_REMOVED macro to take five arguments. + The macro was documented with two arguments (name,ordinal), however + the symbol checking .dfn files assumed five arguments. The five + argument form seems more useful so it is changed to that. + Corrected PNG_UNKNOWN_CHUNKS_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED + in gregbook/readpng2.c + Corrected protection of png_get_user_transform_ptr. The API declaration in + png.h is removed if both READ and WRITE USER_TRANSFORM are turned off + but was left defined in pngtrans.c + Added logunsupported=1 to cause pnglibconf.h to document disabled options. + This makes the installed pnglibconf.h more readable but causes no + other change. The intention is that users of libpng will find it + easier to understand if an API they need is missing. + Include png_reset_zstream() in png.c only when PNG_READ_SUPPORTED is defined. + Removed dummy_inflate.c from contrib/pngminim/encoder + Removed contrib/pngminim/*/gather.sh; gathering is now done in the makefile. + +Version 1.5.0beta24 [May 7, 2010] + Use bitwise "&" instead of arithmetic mod in pngrutil.c calculation of the + offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. + Added more blank lines for readability. + +Version 1.5.0beta25 [June 18, 2010] + In pngpread.c: png_push_have_row() add check for new_row > height + Removed the now-redundant check for out-of-bounds new_row from example.c + +Version 1.5.0beta26 [June 18, 2010] + In pngpread.c: png_push_process_row() add check for too many rows. + +Version 1.5.0beta27 [June 18, 2010] + Removed the check added in beta25 as it is now redundant. + +Version 1.5.0beta28 [June 20, 2010] + Rewrote png_process_IDAT_data to consistently treat extra data as warnings + and handle end conditions more cleanly. + Removed the new (beta26) check in png_push_process_row(). + +Version 1.5.0beta29 [June 21, 2010] + Revised scripts/options.awk to work on Sunos (but still doesn't work) + Added comment to options.awk and contrib/pngminim/*/makefile to try nawk. + +Version 1.5.0beta30 [June 22, 2010] + Stop memory leak when reading a malformed sCAL chunk. + +Version 1.5.0beta31 [June 26, 2010] + Revised pngpread.c patch of beta28 to avoid an endless loop. + Removed some trailing blanks. + +Version 1.5.0beta32 [June 26, 2010] + Removed leftover scripts/options.patch and scripts/options.rej + +Version 1.5.0beta33 [July 6, 3010] + Made FIXED and FLOATING options consistent in the APIs they enable and + disable. Corrected scripts/options.awk to handle both command line + options and options specified in the .dfa files. + Changed char *msg to PNG_CONST char *msg in pngrutil.c + Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or + floating point APIs, but not both. + Reversed patch to remove error handler when the jmp_buf is stored in the + main program structure, not the png_struct. + The error handler is needed because the default handler in libpng will + always use the jmp_buf in the library control structure; this is never + set. The gregbook code is a useful example because, even though it + uses setjmp/longjmp, it shows how error handling can be implemented + using control mechanisms not directly supported by libpng. The + technique will work correctly with mechanisms such as Microsoft + Structure Exceptions or C++ exceptions (compiler willing - note that gcc + does not by default support interworking of C and C++ error handling.) + Reverted changes to call png_longjmp in contrib/gregbook where it is not + appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp + cannot be used. + Changed "extern PNG_EXPORT" to "PNG_EXPORT" in png.h (Jan Nijtmans) + Changed "extern" to "PNG_EXTERN" in pngpriv.h (except for the 'extern "C" {') + +Version 1.5.0beta34 [July 12, 2010] + Put #ifndef PNG_EXTERN, #endif around the define PNG_EXTERN in pngpriv.h + +Version 1.5.0beta35 [July 24, 2010] + Removed some newly-added TAB characters. + Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2 + Moved the definition of png_snprintf() outside of the enclosing + #ifdef blocks in pngconf.h + +Version 1.5.0beta36 [July 29, 2010] + Patches by John Bowler: + Fixed point APIs are now supported throughout (no missing APIs). + Internal fixed point arithmetic support exists for all internal floating + point operations. + sCAL validates the floating point strings it is passed. + Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2 + Two new APIs exist to get the number of passes without turning on the + PNG_INTERLACE transform and to get the number of rows in the current + pass. + A new test program, pngvalid.c, validates the gamma code. + Errors in the 16-bit gamma correction (overflows) have been corrected. + cHRM chunk testing is done consistently (previously the floating point + API bypassed it, because the test really didn't work on FP, now the test + is performed on the actual values to be stored in the PNG file so it + works in the FP case too.) + Most floating point APIs now simply call the fixed point APIs after + converting the values to the fixed point form used in the PNG file. + The standard headers no longer include zlib.h, which is currently only + required for pngstruct.h and can therefore be internal. + Revised png_get_int_32 to undo the PNG two's complement representation of + negative numbers. + +Version 1.5.0beta37 [July 30, 2010] + Added a typecast in png_get_int_32() in png.h and pngrutil.h to avoid + a compiler warning. + Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png + +Version 1.5.0beta38 [July 31, 2010] + Implemented remaining "_fixed" functions. + Corrected a number of recently introduced warnings mostly resulting from + safe but uncast assignments to shorter integers. Also added a zlib + VStudio release library project because the latest zlib Official Windows + build does not include such a thing. + Revised png_get_int_16() to be similar to png_get_int_32(). + Restored projects/visualc71. + +Version 1.5.0beta39 [August 2, 2010] + VisualC/GCC warning fixes, VisualC build fixes + The changes include support for function attributes in VC in addition to + those already present in GCC - necessary because without these some + warnings are unavoidable. Fixes include signed/unsigned fixes in + pngvalid and checks with gcc -Wall -Wextra -Wunused. + VC requires function attributes on function definitions as well as + declarations, PNG_FUNCTION has been added to enable this and the + relevant function definitions changed. + +Version 1.5.0beta40 [August 6, 2010] + Correct use of _WINDOWS_ in pngconf.h + Removed png_mem_ #defines; they are no longer used. + Added the sRGB chunk to pngtest.png + +Version 1.5.0beta41 [August 11, 2010] + Added the cHRM chunk to pngtest.png + Don't try to use version-script with cygwin/mingw. + Revised contrib/gregbook to work under cygwin/mingw. + +Version 1.5.0beta42 [August 18, 2010] + Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov) + Made all API functions that have const arguments and constant string + literal pointers declare them (John Bowler). + +Version 1.5.0beta43 [August 20, 2010] + Removed spurious tabs, shorten long lines (no source change) + Also added scripts/chkfmt to validate the format of all the files that can + reasonably be validated (it is suggested to run "make distclean" before + checking, because some machine generated files have long lines.) + Reformatted the CHANGES file to be more consistent throughout. + Made changes to address various issues identified by GCC, mostly + signed/unsigned and shortening problems on assignment but also a few + difficult to optimize (for GCC) loops. + Fixed non-GCC fixed point builds. In png.c a declaration was misplaced + in an earlier update. Fixed to declare the auto variables at the head. + Use cexcept.h in pngvalid.c. + +Version 1.5.0beta44 [August 24, 2010] + Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for + installing libpng in /usr/lib64 (Funda Wang). + Revised CMakeLists.txt to put the man pages in share/man/man* not man/man* + Revised CMakeLists.txt to make symlinks instead of copies when installing. + Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman) + Implemented memory checks within pngvalid + Reformatted/rearranged pngvalid.c to assist use of progressive reader. + Check interlaced images in pngvalid + Clarified pngusr.h comments in pnglibconf.dfa + Simplified the pngvalid error-handling code now that cexcept.h is in place. + Implemented progressive reader in pngvalid.c for standard tests + Implemented progressive read in pngvalid.c gamma tests + Turn on progressive reader in pngvalid.c by default and tidy code. + +Version 1.5.0beta45 [August 26, 2010] + Added an explicit make step to projects/vstudio for pnglibconf.h + Also corrected zlib.vcxproj into which Visual Studio had introduced + what it calls an "authoring error". The change to make pnglibconf.h + simply copies the file; in the future it may actually generate the + file from scripts/pnglibconf.dfa as the other build systems do. + Changed pngvalid to work when floating point APIs are disabled + Renamed the prebuilt scripts/pnglibconf.h to scripts/pnglibconf.h.prebuilt + Supply default values for PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX + in pngpriv.h in case the user neglected to define them in their pngusr.h + +Version 1.5.0beta46 [August 28, 2010] + Added new private header files to libpng_sources in CMakeLists.txt + Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options. + Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project. + +Version 1.5.0beta47 [September 11, 2010] + Fixed a number of problems with 64-bit compilation reported by Visual + Studio 2010 (John Bowler). + +Version 1.5.0beta48 [October 4, 2010] + Updated CMakeLists.txt (Philip Lowman). + Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER, + $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE + Fixed problem with symbols creation in Makefile.am which was assuming that + all versions of ccp write to standard output by default (Martin Banky). The + bug was introduced in libpng-1.2.9beta5. + Removed unused mkinstalldirs. + +Version 1.5.0beta49 [October 8, 2010] + Undid Makefile.am revision of 1.5.0beta48. + +Version 1.5.0beta50 [October 14, 2010] + Revised Makefile.in to account for mkinstalldirs being removed. + Added some "(unsigned long)" typecasts in printf statements in pngvalid.c. + Suppressed a compiler warning in png_handle_sPLT(). + Check for out-of-range text compression mode in png_set_text(). + +Version 1.5.0beta51 [October 15, 2010] + Changed embedded dates to "(PENDING RELEASE) in beta releases (and future + rc releases) to minimize the difference between releases. + +Version 1.5.0beta52 [October 16, 2010] + Restored some of the embedded dates (in png.h, png.c, documentation, etc.) + +Version 1.5.0beta53 [October 18, 2010] + Updated INSTALL to mention using "make maintainer-clean" and to remove + obsolete statement about a custom ltmain.sh + Disabled "color-tests" by default in Makefile.am so it will work with + automake versions earlier than 1.11.1 + Use document name "libpng-manual.txt" instead of "libpng-.txt" + to simplify version differences. + Removed obsolete remarks about setjmp handling from INSTALL. + Revised and renamed the typedef in png.h and png.c that was designed + to catch library and header mismatch. + +Version 1.5.0beta54 [November 10, 2010] + Require 48 bytes, not 64 bytes, for big_row_buf in overflow checks. + Used a consistent structure for the pngget.c functions. + +Version 1.5.0beta55 [November 21, 2010] + Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin) + Moved reading of file signature into png_read_sig (Cosmin) + Fixed atomicity of chunk header serialization (Cosmin) + Added test for io_state in pngtest.c (Cosmin) + Added "#!/bin/sh" at the top of contrib/pngminim/*/gather.sh scripts. + Changes to remove gcc warnings (John Bowler) + Certain optional gcc warning flags resulted in warnings in libpng code. + With these changes only -Wconversion and -Wcast-qual cannot be turned on. + Changes are trivial rearrangements of code. -Wconversion is not possible + for pngrutil.c (because of the widespread use of += et al on variables + smaller than (int) or (unsigned int)) and -Wcast-qual is not possible + with pngwio.c and pngwutil.c because the 'write' callback and zlib + compression both fail to declare their input buffers with 'const'. + +Version 1.5.0beta56 [December 7, 2010] + Added the private PNG_UNUSED() macro definition in pngpriv.h. + Added some commentary about PNG_EXPORT in png.h and pngconf.h + Revised PNG_EXPORT() macro and added PNG_EXPORTA() macro, with the + objective of simplifying and improving the cosmetic appearance of png.h. + Fixed some incorrect "=" macro names in pnglibconf.dfa + Included documentation of changes in 1.5.0 from 1.4.x in libpng-manual.txt + +Version 1.5.0beta57 [December 9, 2010] + Documented the pngvalid gamma error summary with additional comments and + print statements. + Improved missing symbol handling in checksym.awk; symbols missing in both + the old and new files can now be optionally ignored, treated as errors + or warnings. + Removed references to pngvcrd.c and pnggccrd.c from the vstudio project. + Updated "libpng14" to "libpng15" in the visualc71 project. + Enabled the strip16 tests in pngvalid.` + Don't display test results (except PASS/FAIL) when running "make test". + Instead put them in pngtest-log.txt + Added "--with-zprefix=" to configure.ac + Updated the prebuilt configuration files to autoconf version 2.68 + +Version 1.5.0beta58 [December 19, 2010] + Fixed interlace image handling and add test cases (John Bowler) + Fixed the clean rule in Makefile.am to remove pngtest-log.txt + Made minor changes to work around warnings in gcc 3.4 + +Version 1.5.0rc01 [December 27, 2010] + No changes. + +Version 1.5.0rc02 [December 27, 2010] + Eliminated references to the scripts/*.def files in project/visualc71. + +Version 1.5.0rc03 [December 28, 2010] + Eliminated scripts/*.def and revised Makefile.am accordingly + +Version 1.5.0rc04 [December 29, 2010] + Fixed bug in background transformation handling in pngrtran.c (it was + looking for the flag in png_ptr->transformations instead of in + png_ptr->flags) (David Raymond). + +Version 1.5.0rc05 [December 31, 2010] + Fixed typo in a comment in CMakeLists.txt (libpng14 => libpng15) (Cosmin) + +Version 1.5.0rc06 [January 4, 2011] + Changed the new configure option "zprefix=string" to "zlib-prefix=string" + +Version 1.5.0rc07 [January 4, 2011] + Updated copyright year. + +Version 1.5.0 [January 6, 2011] + No changes. + +version 1.5.1beta01 [January 8, 2011] + Added description of png_set_crc_action() to the manual. + Added a note in the manual that the type of the iCCP profile was changed + from png_charpp to png_bytepp in png_get_iCCP(). This change happened + in version 1.5.0beta36 but is not noted in the CHANGES. Similarly, + it was changed from png_charpp to png_const_bytepp in png_set_iCCP(). + Ensure that png_rgb_to_gray ignores palette mapped images, if libpng + internally happens to call it with one, and fixed a failure to handle + palette mapped images correctly. This fixes CVE-2690. + +Version 1.5.1beta02 [January 14, 2011] + Fixed a bug in handling of interlaced images (bero at arklinux.org). + Updated CMakeLists.txt (Clifford Yapp) + +Version 1.5.1beta03 [January 14, 2011] + Fixed typecasting of some png_debug() statements (Cosmin) + +Version 1.5.1beta04 [January 16, 2011] + Updated documentation of png_set|get_tRNS() (Thomas Klausner). + Mentioned in the documentation that applications must #include "zlib.h" + if they need access to anything in zlib.h, and that a number of + macros such as png_memset() are no longer accessible by applications. + Corrected pngvalid gamma test "sample" function to access all of the color + samples of each pixel, instead of sampling the red channel three times. + Prefixed variable names index, div, exp, gamma with "png_" to avoid "shadow" + warnings, and (mistakenly) changed png_exp() to exp(). + +Version 1.5.1beta05 [January 16, 2011] + Changed variable names png_index, png_div, png_exp, and png_gamma to + char_index, divisor, exp_b10, and gamma_val, respectively, and + changed exp() back to png_exp(). + +Version 1.5.1beta06 [January 20, 2011] + Prevent png_push_crc_skip() from hanging while reading an unknown chunk + or an over-large compressed zTXt chunk with the progressive reader. + Eliminated more GCC "shadow" warnings. + Revised png_fixed() in png.c to avoid compiler warning about reaching the + end without returning anything. + +Version 1.5.1beta07 [January 22, 2011] + In the manual, describe the png_get_IHDR() arguments in the correct order. + Added const_png_structp and const_png_infop types, and used them in + prototypes for most png_get_*() functions. + +Version 1.5.1beta08 [January 23, 2011] + Added png_get_io_chunk_type() and deprecated png_get_io_chunk_name() + Added synopses for the IO_STATE functions and other missing synopses + to the manual. Removed the synopses from libpngpf.3 because they + were out of date and no longer useful. Better information can be + obtained by reading the prototypes and comments in pngpriv.h + Attempted to fix cpp on Solaris with S. Studio 12 cc, fix build + Added a make macro DFNCPP that is a CPP that will accept the tokens in + a .dfn file and adds configure stuff to test for such a CPP. ./configure + should fail if one is not available. + Corrected const_png_ in png.h to png_const_ to avoid polluting the namespace. + Added png_get_current_row_number and png_get_current_pass_number for the + benefit of the user transform callback. + Added png_process_data_pause and png_process_data_skip for the benefit of + progressive readers that need to stop data processing or want to optimize + skipping of unread data (e.g., if the reader marks a chunk to be skipped.) + +Version 1.5.1beta09 [January 24, 2011] + Enhanced pngvalid, corrected an error in gray_to_rgb, corrected doc error. + pngvalid contains tests of transforms, which tests are currently disabled + because they are incompletely tested. gray_to_rgb was failing to expand + the bit depth for smaller bit depth images; this seems to be a long + standing error and resulted, apparently, in invalid output + (CVE-2011-0408, CERT VU#643140). The documentation did not accurately + describe what libpng really does when converting RGB to gray. + +Version 1.5.1beta10 [January 27, 2010] + Fixed incorrect examples of callback prototypes in the manual, that were + introduced in libpng-1.0.0. + In addition the order of the png_get_uint macros with respect to the + relevant function definitions has been reversed. This helps the + preprocessing of the symbol files be more robust. Furthermore, the + symbol file preprocessing now uses -DPNG_NO_USE_READ_MACROS even when + the library may actually be built with PNG_USE_READ_MACROS; this stops + the read macros interfering with the symbol file format. + Made the manual, synopses, and function prototypes use the function + argument names file_gamma, int_file_gamma, and srgb_intent consistently. + +Version 1.5.1beta11 [January 28, 2011] + Changed PNG_UNUSED from "param=param;" to "{if(param){}}". + Corrected local variable type in new API png_process_data_skip() + The type was self-evidently incorrect but only causes problems on 64-bit + architectures. + Added transform tests to pngvalid and simplified the arguments. + +Version 1.5.1rc01 [January 29, 2011] + No changes. + +Version 1.5.1rc02 [January 31, 2011] + Added a request in the manual that applications do not use "png_" or + "PNG_" to begin any of their own symbols. + Changed PNG_UNUSED to "(void)param;" and updated the commentary in pngpriv.h + +Version 1.5.1 [February 3, 2011] + No changes. + +Version 1.5.2beta01 [February 13, 2011] + More -Wshadow fixes for older gcc compilers. Older gcc versions apparently + check formal parameters names in function declarations (as well as + definitions) to see if they match a name in the global namespace. + Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the + old VisualC++ preprocessor. + Turned on interlace handling in png_read_png(). + Fixed gcc pendantic warnings. + Handle longjmp in Cygwin. + Fixed png_get_current_row_number() in the interlaced case. + Cleaned up ALPHA flags and transformations. + Implemented expansion to 16 bits. + +Version 1.5.2beta02 [February 19, 2011] + Fixed mistake in the descriptions of user read_transform and write_transform + function prototypes in the manual. The row_info struct is png_row_infop. + Reverted png_get_current_row_number() to previous (1.5.2beta01) behavior. + Corrected png_get_current_row_number documentation + Fixed the read/write row callback documentation. + This documents the current behavior, where the callback is called after + every row with information pertaining to the next row. + +Version 1.5.2beta03 [March 3, 2011] + Fixed scripts/makefile.vcwin32 + Updated contrib/pngsuite/README to add the word "modify". + Define PNG_ALLOCATED to blank when _MSC_VER<1300. + +Version 1.5.2rc01 [March 19, 2011] + Define remaining attributes to blank when MSC_VER<1300. + ifdef out mask arrays in pngread.c when interlacing is not supported. + +Version 1.5.2rc02 [March 22, 2011] + Added a hint to try CPP=/bin/cpp if "cpp -E" fails in scripts/pnglibconf.mak + and in contrib/pngminim/*/makefile, eg., on SunOS 5.10, and removed "strip" + from the makefiles. + Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail + to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill) + +Version 1.5.2rc03 [March 24, 2011] + Don't include standard header files in png.h while building the symbol table, + to avoid cpp failure on SunOS (introduced PNG_BUILDING_SYMBOL_TABLE macro). + +Version 1.5.2 [March 31, 2011] + No changes. + +Version 1.5.3beta01 [April 1, 2011] + Re-initialize the zlib compressor before compressing non-IDAT chunks. + Added API functions (png_set_text_compression_level() and four others) to + set parameters for zlib compression of non-IDAT chunks. + +Version 1.5.3beta02 [April 3, 2011] + Updated scripts/symbols.def with new API functions. + Only compile the new zlib re-initializing code when text or iCCP is + supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro. + Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03). + Optimize the zlib CMF byte in non-IDAT compressed chunks + +Version 1.5.3beta03 [April 16, 2011] + Fixed gcc -ansi -pedantic compile. A strict ANSI system does not have + snprintf, and the "__STRICT_ANSI__" detects that condition more reliably + than __STDC__ (John Bowler). + Removed the PNG_PTR_NORETURN attribute because it too dangerous. It tells + the compiler that a user supplied callback (the error handler) does not + return, yet there is no guarantee in practice that the application code + will correctly implement the error handler because the compiler only + issues a warning if there is a mistake (John Bowler). + Removed the no-longer-used PNG_DEPSTRUCT macro. + Updated the zlib version to 1.2.5 in the VStudio project. + Fixed 64-bit builds where png_uint_32 is smaller than png_size_t in + pngwutil.c (John Bowler). + Fixed bug with stripping the filler or alpha channel when writing, that + was introduced in libpng-1.5.2beta01 (bug report by Andrew Church). + +Version 1.5.3beta04 [April 27, 2011] + Updated pngtest.png with the new zlib CMF optimization. + Cleaned up conditional compilation code and of background/gamma handling + Internal changes only except a new option to avoid compiling the + png_build_grayscale_palette API (which is not used at all internally.) + The main change is to move the transform tests (READ_TRANSFORMS, + WRITE_TRANSFORMS) up one level to the caller of the APIs. This avoids + calls to spurious functions if all transforms are disabled and slightly + simplifies those functions. Pngvalid modified to handle this. + A minor change is to stop the strip_16 and expand_16 interfaces from + disabling each other; this allows the future alpha premultiplication + code to use 16-bit intermediate values while still producing 8-bit output. + png_do_background and png_do_gamma have been simplified to take a single + pointer to the png_struct rather than pointers to every item required + from the png_struct. This makes no practical difference to the internal + code. + A serious bug in the pngvalid internal routine 'standard_display_init' has + been fixed - this failed to initialize the red channel and accidentally + initialized the alpha channel twice. + Changed png_struct jmp_buf member name from png_jmpbuf to tmp_jmpbuf to + avoid a possible clash with the png_jmpbuf macro on some platforms. + +Version 1.5.3beta05 [May 6, 2011] + Added the "_POSIX_SOURCE" feature test macro to ensure libpng sees the + correct API. _POSIX_SOURCE is defined in pngpriv.h, pngtest.c and + pngvalid.c to ensure that POSIX conformant systems disable non-POSIX APIs. + Removed png_snprintf and added formatted warning messages. This change adds + internal APIs to allow png_warning messages to have parameters without + requiring the host OS to implement snprintf. As a side effect the + dependency of the tIME-supporting RFC1132 code on stdio is removed and + PNG_NO_WARNINGS does actually work now. + Pass "" instead of '\0' to png_default_error() in png_err(). This mistake + was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. + Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte + optimization configureable. + IDAT compression failed if preceded by a compressed text chunk (bug + introduced in libpng-1.5.3beta01-02). This was because the attempt to + reset the zlib stream in png_write_IDAT happened after the first IDAT + chunk had been deflated - much too late. In this change internal + functions were added to claim/release the z_stream and, hopefully, make + the code more robust. Also deflateEnd checking is added - previously + libpng would ignore an error at the end of the stream. + +Version 1.5.3beta06 [May 8, 2011] + Removed the -D_ALL_SOURCE from definitions for AIX in CMakeLists.txt + Implemented premultiplied alpha support: png_set_alpha_mode API + +Version 1.5.3beta07 [May 11, 2011] + Added expand_16 support to the high level interface. + Added named value and 'flag' gamma support to png_set_gamma. Made a minor + change from the previous (unreleased) ABI/API to hide the exact value used + for Macs - it's not a good idea to embed this in the ABI! + Moved macro definitions for PNG_HAVE_IHDR, PNG_HAVE_PLTE, and PNG_AFTER_IDAT + from pngpriv.h to png.h because they must be visible to applications + that call png_set_unknown_chunks(). + Check for up->location !PNG_AFTER_IDAT when writing unknown chunks + before IDAT. + +Version 1.5.3beta08 [May 16, 2011] + Improved "pngvalid --speed" to exclude more of pngvalid from the time. + Documented png_set_alpha_mode(), other changes in libpng.3/libpng-manual.txt + The cHRM chunk now sets the defaults for png_set_rgb_to_gray() (when negative + parameters are supplied by the caller), while in the absence of cHRM + sRGB/Rec 709 values are still used. This introduced a divide-by-zero + bug in png_handle_cHRM(). + The bKGD chunk no longer overwrites the background value set by + png_set_background(), allowing the latter to be used before the file + header is read. It never performed any useful function to override + the default anyway. + Added memory overwrite and palette image checks to pngvalid.c + Previously palette image code was poorly checked. Since the transformation + code has a special palette path in most cases this was a severe weakness. + Minor cleanup and some extra checking in pngrutil.c and pngrtran.c. When + expanding an indexed image, always expand to RGBA if transparency is + present. + +Version 1.5.3beta09 [May 17, 2011] + Reversed earlier 1.5.3 change of transformation order; move png_expand_16 + back where it was. The change doesn't work because it requires 16-bit + gamma tables when the code only generates 8-bit ones. This fails + silently; the libpng code just doesn't do any gamma correction. Moving + the tests back leaves the old, inaccurate, 8-bit gamma calculations, but + these are clearly better than none! + +Version 1.5.3beta10 [May 20, 2011] + + png_set_background() and png_expand_16() did not work together correctly. + This problem is present in 1.5.2; if png_set_background is called with + need_expand false and the matching 16 bit color libpng erroneously just + treats it as an 8-bit color because of where png_do_expand_16 is in the + transform list. This simple fix reduces the supplied colour to 8-bits, + so it gets smashed, but this is better than the current behavior. + Added tests for expand16, more fixes for palette image tests to pngvalid. + Corrects the code for palette image tests and disables attempts to + validate palette colors. + +Version 1.5.3rc01 [June 3, 2011] + No changes. + +Version 1.5.3rc02 [June 8, 2011] + Fixed uninitialized memory read in png_format_buffer() (Bug report by + Frank Busse, CVE-2011-2501, related to CVE-2004-0421). + +Version 1.5.3beta11 [June 11, 2011] + Fixed png_handle_sCAL which is broken in 1.5. This fixes CVE 2011-2692. + Added sCAL to pngtest.png + Revised documentation about png_set_user_limits() to say that it also affects + png writing. + Revised handling of png_set_user_limits() so that it can increase the + limit beyond the PNG_USER_WIDTH|HEIGHT_MAX; previously it could only + reduce it. + Make the 16-to-8 scaling accurate. Dividing by 256 with no rounding is + wrong (high by one) 25% of the time. Dividing by 257 with rounding is + wrong in 128 out of 65536 cases. Getting the right answer all the time + without division is easy. + Added "_SUPPORTED" to the PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION macro. + Added projects/owatcom, an IDE project for OpenWatcom to replace + scripts/makefile.watcom. This project works with OpenWatcom 1.9. The + IDE autogenerates appropriate makefiles (libpng.mk) for batch processing. + The project is configurable, unlike the Visual Studio project, so long + as the developer has an awk. + Changed png_set_gAMA to limit the gamma value range so that the inverse + of the stored value cannot overflow the fixed point representation, + and changed other things OpenWatcom warns about. + Revised pngvalid.c to test PNG_ALPHA_MODE_SUPPORTED correctly. This allows + pngvalid to build when ALPHA_MODE is not supported, which is required if + it is to build on libpng 1.4. + Removed string/memory macros that are no longer used and are not + necessarily fully supportable, particularly png_strncpy and png_snprintf. + Added log option to pngvalid.c and attempted to improve gamma messages. + +Version 1.5.3 [omitted] + People found the presence of a beta release following an rc release + to be confusing; therefore we bump the version to libpng-1.5.4beta01 + and there will be no libpng-1.5.3 release. + +Version 1.5.4beta01 [June 14, 2011] + Made it possible to undefine PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED + to get the same (inaccurate) output as libpng-1.5.2 and earlier. + Moved definitions of PNG_HAVE_IHDR, PNG_AFTER_IDAT, and PNG_HAVE_PLTE + outside of an unknown-chunk block in png.h because they are also + needed for other uses. + +Version 1.5.4beta02 [June 14, 2011] + Fixed and clarified LEGACY 16-to-8 scaling code. + Added png_set_chop_16() API, to match inaccurate results from previous + libpng versions. + Removed the ACCURATE and LEGACY options (they are no longer useable) + Use the old scaling method for background if png_set_chop_16() was + called. + Made png_set_chop_16() API removeable by disabling PNG_CHOP_16_TO_8_SUPPORTED + +Version 1.5.4beta03 [June 15, 2011] + Fixed a problem in png_do_expand_palette() exposed by optimization in + 1.5.3beta06 + Also removed a spurious and confusing "trans" member ("trans") from png_info. + The palette expand optimization prevented expansion to an intermediate RGBA + form if tRNS was present but alpha was marked to be stripped; this exposed + a check for tRNS in png_do_expand_palette() which is inconsistent with the + code elsewhere in libpng. + Correction to the expand_16 code; removed extra instance of + png_set_scale_16_to_8 from pngpriv.h + +Version 1.5.4beta04 [June 16, 2011] + Added a missing "#ifdef PNG_READ_BACKGROUND_SUPPORTED/#endif" in pngrtran.c + Added PNG_TRANSFORM_CHOP_16 to the high-level read transforms. + Made PNG_READ_16_TO_8_ACCURATE_SCALE configurable again. If this is + not enabled, png_set_strip_16() and png_do_scale_16_to_8() aren't built. + Revised contrib/visupng, gregbook, and pngminim to demonstrate chop_16_to_8 + +Version 1.5.4beta05 [June 16, 2011] + Renamed png_set_strip_16() to png_set_scale_16() and renamed + png_set_chop_16() to png_set_strip(16) in an attempt to minimize the + behavior changes between libpng14 and libpng15. + +Version 1.5.4beta06 [June 18, 2011] + Fixed new bug that was causing both strip_16 and scale_16 to be applied. + +Version 1.5.4beta07 [June 19, 2011] + Fixed pngvalid, simplified macros, added checking for 0 in sCAL. + The ACCURATE scale macro is no longer defined in 1.5 - call the + png_scale_16_to_8 API. Made sure that PNG_READ_16_TO_8 is still defined + if the png_strip_16_to_8 API is present. png_check_fp_number now + maintains some state so that positive, negative and zero values are + identified. sCAL uses these to be strictly spec conformant. + +Version 1.5.4beta08 [June 23, 2011] + Fixed pngvalid if ACCURATE_SCALE is defined. + Updated scripts/pnglibconf.h.prebuilt. + +Version 1.5.4rc01 [June 30, 2011] + Define PNG_ALLOCATED to "restrict" only if MSC_VER >= 1400. + +Version 1.5.4 [July 7, 2011] + No changes. + +Version 1.5.5beta01 [July 13, 2011] + Fixed some typos and made other minor changes in the manual. + Updated contrib/pngminus/makefile.std (Samuli Souminen) + +Version 1.5.5beta02 [July 14, 2011] + Revised Makefile.am and Makefile.in to look in the right directory for + pnglibconf.h.prebuilt + +Version 1.5.5beta03 [July 27, 2011] + Enabled compilation with g++ compiler. This compiler does not recognize + the file extension, so it always compiles with C++ rules. Made minor + changes to pngrutil.c to cast results where C++ expects it but C does not. + Minor editing of libpng.3 and libpng-manual.txt. + +Version 1.5.5beta04 [July 29, 2011] + Revised CMakeLists.txt (Clifford Yapp) + Updated commentary about the png_rgb_to_gray() default coefficients + in the manual and in pngrtran.c + +Version 1.5.5beta05 [August 17, 2011] + Prevent unexpected API exports from non-libpng DLLs on Windows. The "_DLL" + is removed from the test of whether a DLL is being built (this erroneously + caused the libpng APIs to be marked as DLL exports in static builds under + Microsoft Visual Studio). Almost all of the libpng building configuration + is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in + pngconf.h, though, so that it is colocated with the import definition (it + is no longer used anywhere in the installed headers). The VStudio project + definitions have been cleaned up: "_USRDLL" has been removed from the + static library builds (this was incorrect), and PNG_USE_DLL has been added + to pngvalid to test the functionality (pngtest does not supply it, + deliberately). The spurious "_EXPORTS" has been removed from the + libpng build (all these errors were a result of copy/paste between project + configurations.) + Added new types and internal functions for CIE RGB end point handling to + pngpriv.h (functions yet to be implemented). + +Version 1.5.5beta06 [August 26, 2011] + Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt + (Clifford Yap) + Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler): + The rgb_to_gray code had errors when combined with gamma correction. + Some pixels were treated as true grey when they weren't and such pixels + and true grey ones were not gamma corrected (the original value of the + red component was used instead). APIs to get and set cHRM using color + space end points have been added and the rgb_to_gray code that defaults + based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT + VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected. + A considerable number of tests has been added to pngvalid for the + rgb_to_gray transform. + Arithmetic errors in rgb_to_gray whereby the calculated gray value was + truncated to the bit depth rather than rounded have been fixed except in + the 8-bit non-gamma-corrected case (where consistency seems more important + than correctness.) The code still has considerable inaccuracies in the + 8-bit case because 8-bit linear arithmetic is used. + +Version 1.5.5beta07 [September 7, 2011] + Added "$(ARCH)" option to makefile.darwin + Added SunOS support to configure.ac and Makefile.am + Changed png_chunk_benign_error() to png_warning() in png.c, in + png_XYZ_from_xy_checked(). + +Version 1.5.5beta08 [September 10, 2011] + Fixed 64-bit compilation errors (gcc). The errors fixed relate + to conditions where types that are 32 bits in the GCC 32-bit + world (uLong and png_size_t) become 64 bits in the 64-bit + world. This produces potential truncation errors which the + compiler correctly flags. + Relocated new HAVE_SOLARIS_LD definition in configure.ac + Constant changes for 64-bit compatibility (removal of L suffixes). The + 16-bit cases still use "L" as we don't have a 16-bit test system. + +Version 1.5.5rc01 [September 15, 2011] + Removed "L" suffixes in pngpriv.h + +Version 1.5.5 [September 22, 2011] + No changes. + +Version 1.5.6beta01 [September 22, 2011] + Fixed some 64-bit type conversion warnings in pngrtran.c + Moved row_info from png_struct to a local variable. + The various interlace mask arrays have been made into arrays of + bytes and made PNG_CONST and static (previously some arrays were + marked PNG_CONST and some weren't). + Additional checks have been added to the transform code to validate the + pixel depths after the transforms on both read and write. + Removed some redundant code from pngwrite.c, in png_destroy_write_struct(). + Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. + This removes the need to allocate temporary strings for chunk names on + the stack in the read/write code. Unknown chunk handling still uses the + string form because this is exposed in the API. + +Version 1.5.6beta02 [September 26, 2011] + Added a note in the manual the png_read_update_info() must be called only + once with a particular info_ptr. + Fixed a typo in the definition of the new PNG_STRING_FROM_CHUNK(s,c) macro. + +Version 1.5.6beta03 [September 28, 2011] + Revised test-pngtest.sh to report FAIL when pngtest fails. + Added "--strict" option to pngtest, to report FAIL when the failure is + only because the resulting valid files are different. + Revised CMakeLists.txt to work with mingw and removed some material from + CMakeLists.txt that is no longer useful in libpng-1.5. + +Version 1.5.6beta04 [October 5, 2011] + Fixed typo in Makefile.in and Makefile.am ("-M Wl" should be "-M -Wl")." + +Version 1.5.6beta05 [October 12, 2011] + Speed up png_combine_row() for interlaced images. This reduces the generality + of the code, allowing it to be optimized for Adam7 interlace. The masks + passed to png_combine_row() are now generated internally, avoiding + some code duplication and localizing the interlace handling somewhat. + Align png_struct::row_buf - previously it was always unaligned, caused by + a bug in the code that attempted to align it; the code needs to subtract + one from the pointer to take account of the filter byte prepended to + each row. + Optimized png_combine_row() when rows are aligned. This gains a small + percentage for 16-bit and 32-bit pixels in the typical case where the + output row buffers are appropriately aligned. The optimization was not + previously possible because the png_struct buffer was always misaligned. + Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. + +Version 1.5.6beta06 [October 17, 2011] + Removed two redundant tests for unitialized row. + Fixed a relatively harmless memory overwrite in compressed text writing + with a 1 byte zlib buffer. + Add ability to call png_read_update_info multiple times to pngvalid.c. + Fixes for multiple calls to png_read_update_info. These fixes attend to + most of the errors revealed in pngvalid, however doing the gamma work + twice results in inaccuracies that can't be easily fixed. There is now + a warning in the code if this is going to happen. + Turned on multiple png_read_update_info in pngvalid transform tests. + Prevent libpng from overwriting unused bits at the end of the image when + it is not byte aligned, while reading. Prior to libpng-1.5.6 libpng would + overwrite the partial byte at the end of each row if the row width was not + an exact multiple of 8 bits and the image is not interlaced. + +Version 1.5.6beta07 [October 21, 2011] + Made png_ptr->prev_row an aligned pointer into png_ptr->big_prev_row + (Mans Rullgard). + +Version 1.5.6rc01 [October 26, 2011] + Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM" + +Version 1.5.6rc02 [October 27, 2011] + Added LSR() macro to defend against buggy compilers that evaluate non-taken + code branches and complain about out-of-range shifts. + +Version 1.5.6rc03 [October 28, 2011] + Renamed the LSR() macro to PNG_LSR() and added PNG_LSL() macro. + Fixed compiler warnings with Intel and MSYS compilers. The logical shift + fix for Microsoft Visual C is required by other compilers, so this + enables that fix for all compilers when using compile-time constants. + Under MSYS 'byte' is a name declared in a system header file, so we + changed the name of a local variable to avoid the warnings that result. + Added #define PNG_ALIGN_TYPE PNG_ALIGN_NONE to contrib/pngminim/*/pngusr.h + +Version 1.5.6 [November 3, 2011] + No changes. + +Version 1.5.7beta01 [November 4, 2011] + Added support for ARM processor (Mans Rullgard) + Fixed bug in pngvalid on early allocation failure; fixed type cast in + pngmem.c; pngvalid would attempt to call png_error() if the allocation + of a png_struct or png_info failed. This would probably have led to a + crash. The pngmem.c implementation of png_malloc() included a cast + to png_size_t which would fail on large allocations on 16-bit systems. + Fix for the preprocessor of the Intel C compiler. The preprocessor + splits adjacent @ signs with a space; this changes the concatentation + token from @-@-@ to PNG_JOIN; that should work with all compiler + preprocessors. + Paeth filter speed improvements from work by Siarhei Siamashka. This + changes the 'Paeth' reconstruction function to improve the GCC code + generation on x86. The changes are only part of the suggested ones; + just the changes that definitely improve speed and remain simple. + The changes also slightly increase the clarity of the code. + +Version 1.5.7beta02 [November 11, 2011] + Check compression_type parameter in png_get_iCCP and remove spurious + casts. The compression_type parameter is always assigned to, so must + be non-NULL. The cast of the profile length potentially truncated the + value unnecessarily on a 16-bit int system, so the cast of the (byte) + compression type to (int) is specified by ANSI-C anyway. + Fixed FP division by zero in pngvalid.c; the 'test_pixel' code left + the sBIT fields in the test pixel as 0, which resulted in a floating + point division by zero which was irrelevant but causes systems where + FP exceptions cause a crash. Added code to pngvalid to turn on FP + exceptions if the appropriate glibc support is there to ensure this is + tested in the future. + Updated scripts/pnglibconf.mak and scripts/makefile.std to handle the + new PNG_JOIN macro. + Added versioning to pnglibconf.h comments. + Simplified read/write API initial version; basic read/write tested on + a variety of images, limited documentation (in the header file.) + Installed more accurate linear to sRGB conversion tables. The slightly + modified tables reduce the number of 16-bit values that + convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used + to generate the tables is now in a contrib/sRGBtables sub-directory. + +Version 1.5.7beta03 [November 17, 2011] + Removed PNG_CONST from the sRGB table declarations in pngpriv.h and png.c + Added run-time detection of NEON support. + Added contrib/libtests; includes simplified API test and timing test and + a color conversion utility for rapid checking of failed 'pngstest' results. + Multiple transform bug fixes plus a work-round for double gamma correction. + libpng does not support more than one transform that requires linear data + at once - if this is tried typically the results is double gamma + correction. Since the simplified APIs can need rgb to gray combined with + a compose operation it is necessary to do one of these outside the main + libpng transform code. This check-in also contains fixes to various bugs + in the simplified APIs themselves and to some bugs in compose and rgb to + gray (on palette) itself. + Fixes for C++ compilation using g++ When libpng source is compiled + using g++. The compiler imposes C++ rules on the C source; thus it + is desireable to make the source work with either C or C++ rules + without throwing away useful error information. This change adds + png_voidcast to allow C semantic (void*) cases or the corresponding + C++ static_cast operation, as appropriate. + Added --noexecstack to assembler file compilation. GCC does not set + this on assembler compilation, even though it does on C compilation. + This creates security issues if assembler code is enabled; the + work-around is to set it by default in the flags for $(CCAS) + Work around compilers that don't support declaration of const data. Some + compilers fault 'extern const' data declarations (because the data is + not initialized); this turns on const-ness only for compilers where + this is known to work. + +Version 1.5.7beta04 [November 17, 2011] + Since the gcc driver does not recognize the --noexecstack flag, we must + use the -Wa prefix to have it passed through to the assembler. + Also removed a duplicate setting of this flag. + Added files that were omitted from the libpng-1.5.7beta03 zip distribution. + +Version 1.5.7beta05 [November 25, 2011] + Removed "zTXt" from warning in generic chunk decompression function. + Validate time settings passed to pngset() and png_convert_to_rfc1123() + (Frank Busse). + Added MINGW support to CMakeLists.txt + Reject invalid compression flag or method when reading the iTXt chunk. + Backed out 'simplified' API changes. The API seems too complex and there + is a lack of consensus or enthusiasm for the proposals. The API also + reveals significant bugs inside libpng (double gamma correction and the + known bug of being unable to retrieve a corrected palette). It seems + better to wait until the bugs, at least, are corrected. + Moved pngvalid.c into contrib/libtests + Rebuilt Makefile.in, configure, etc., with autoconf-2.68 + +Version 1.5.7rc01 [December 1, 2011] + Replaced an "#if" with "#ifdef" in pngrtran.c + Revised #if PNG_DO_BC block in png.c (use #ifdef and add #else) + +Version 1.5.7rc02 [December 5, 2011] + Revised project files and contrib/pngvalid/pngvalid.c to account for + the relocation of pngvalid into contrib/libtests. + Revised pngconf.h to use " __declspec(restrict)" only when MSC_VER >= 1400, + as in libpng-1.5.4. + Put CRLF line endings in the owatcom project files. + +Version 1.5.7rc03 [December 7, 2011] + Updated CMakeLists.txt to account for the relocation of pngvalid.c + +Version 1.5.7 [December 15, 2011] + Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings + reported by earlier versions. + +Version 1.5.8beta01 [January 15, 2011] + Removed '#include config.h"' from contrib/libtests/pngvalid.c. It's not + needed and causes trouble for VPATH building. + Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper + location in configure.ac (Gilles Espinasse). + Fix bug in pngerror.c: some long warnings were being improperly truncated + (CVE-2011-3464, bug introduced in libpng-1.5.3beta05). + +Version 1.5.8rc01 [January 21, 2012] + No changes. + +Version 1.5.8rc02 [January 25, 2012] + Fixed Min/GW uninstall to remove libpng.dll.a + Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt + +Version 1.5.8 [February 1, 2012] + No changes. + +Version 1.5.9beta01 [February 3, 2012] + Rebuilt configure scripts in the tar distributions. + +Version 1.5.9beta02 [February 16, 2012] + Removed two unused definitions from scripts/pnglibconf.h.prebuilt + Removed some unused arrays (with #ifdef) from png_read_push_finish_row(). + Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h + +Version 1.5.9rc01 [February 17, 2012] + Fixed CVE-2011-3026 buffer overrun bug. This bug was introduced when + iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the + test on iCCP chunk length. Also removed spurious casts that may hide + problems on 16-bit systems. + +Version 1.5.9 [February 18, 2012] + No changes. + +Version 1.5.10beta01 [February 24, 2012] + Removed two useless #ifdef directives from pngread.c and one from pngrutil.c + Always put the CMAKE_LIBRARY in "lib" (removed special WIN32 case). + Removed empty vstudio/pngstest directory (Clifford Yapp). + Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from + pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c; + now that png_ptr->buffer is inaccessible to applications, the special + handling is no longer useful. + Fixed bug with png_handle_hIST with odd chunk length (Frank Busse). + Added PNG_SAFE_LIMITS feature to pnglibconf.dfa and code in pngconf.h + to reset the user limits to safe ones if PNG_SAFE_LIMITS is defined. + To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED" on the configure + command or put "#define PNG_SAFE_LIMITS_SUPPORTED" in pnglibconf.h. + Revised the SAFE_LIMITS feature to be the same as the feature in libpng16. + Added information about the new limits in the manual. + +Version 1.5.10beta02 [February 27, 2012] + Updated Makefile.in + +Version 1.5.10beta03 [March 6, 2012] + Removed unused "current_text" members of png_struct and the png_free() + of png_ptr->current_text from pngread.c + Added palette-index checking. Issue a png_warning() if an invalid index is + found. + +Version 1.5.10beta04 [March 10, 2012] + Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. + Fixed CMF optimization of non-IDAT compressed chunks, which was added at + libpng-1.5.4. It sometimes produced too small of a window. + +Version 1.5.10beta05 [March 10, 2012] + Reject all iCCP chunks after the first, even if the first one is invalid. + Issue a png_benign_error() instead of png_warning() about bad palette index. + Fixed an off-by-one error in the palette index checking function. + Revised example.c to put text strings in a temporary character array + instead of directly assigning string constants to png_textp members. + This avoids compiler warnings when -Wwrite-strings is enabled. + +Version 1.5.10 [March 29, 2012] + Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice. + Revised png_set_text_2() to avoid potential memory corruption (fixes + CVE-2011-3048). + +Version 1.5.11beta01 [April 28, 2012] + Revised scripts/makefile.darwin: use system zlib; remove quotes around + architecture list; add missing ppc architecture; add architecture options + to shared library link; don't try to create a shared lib based on missing + RELEASE variable. + Enable png_set_check_for_invalid_index() for both read and write. + Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED/#endif in pngpriv.h around + declaration of png_handle_unknown(). + Added -lssp_nonshared in a comment in scripts/makefile.freebsd + and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE. + +Version 1.5.11rc01 [May 23, 2012] + No changes. + +Version 1.5.11rc02 [May 29, 2012] + Fixed some typos in comments. + Revised CMakeLists.txt to not attempt to make a symlink under mingw. + Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale), + and renamed three whose names were inconsistent with those in + pngsuite/README.txt. + +Version 1.5.11rc03 [June 4, 2012] + Do not depend upon a GCC feature macro being available for use in generating + the linker mapfile symbol prefix. + Made fixes for new optimization warnings from gcc 4.7.0. The compiler + performed an optimization which is safe but then warned about it. + Changing the type of 'palette_number' in pngvalid.c removes the warning. + +Version 1.5.11rc04 [June 6, 2012] + Improved performance of new do_check_palette_indexes() function. + +Version 1.5.11rc05 [June 7, 2012] + Don't check palette indexes if num_palette is 0 (as it can be in MNG files). + +Version 1.5.11 [June 14, 2012] + Include zlib.h in contrib/gregbook and contrib/visupng examples. + +Version 1.5.12 [July 11, 2012] + Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it + depends on configure, which is not included in those archives. + Changed "a+w" to "u+w" in Makefile.in to fix CVE-2012-3386. + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) +or to glennrp at users.sourceforge.net + +Glenn R-P +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,55 @@ +# ---------------------------------------------------------------------------- +# CMake file for libpng. See root CMakeLists.txt +# +# ---------------------------------------------------------------------------- + +if(NEON) + project(${PNG_LIBRARY} ASM) +else() + project(${PNG_LIBRARY}) +endif() + +ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" ${ZLIB_INCLUDE_DIR}) + +file(GLOB lib_srcs *.c) +file(GLOB lib_hdrs *.h) + +if(NEON) + list(APPEND lib_srcs arm/filter_neon.S) + add_definitions(-DPNG_ARM_NEON) +endif() + +# ---------------------------------------------------------------------------------- +# Define the library target: +# ---------------------------------------------------------------------------------- + +add_definitions(-DPNG_CONFIGURE_LIBPNG) + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) +endif(MSVC) + +add_library(${PNG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs}) +target_link_libraries(${PNG_LIBRARY} ${ZLIB_LIBRARY}) + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() +endif() + +ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align) + +set_target_properties(${PNG_LIBRARY} + PROPERTIES OUTPUT_NAME ${PNG_LIBRARY} + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${PNG_LIBRARY} PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS ${PNG_LIBRARY} ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/LICENSE diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/LICENSE --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/LICENSE 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,111 @@ + +This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +If you modify libpng you may insert additional notices immediately following +this sentence. + +This code is released under the libpng license. + +libpng versions 1.2.6, August 15, 2004, through 1.5.12, July 11, 2012, are +Copyright (c) 2004, 2006-2012 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 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 Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +July 11, 2012 diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/README diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/README --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/README 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/README 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,202 @@ +README for libpng version 1.5.12 - July 11, 2012 (shared library 15.0) +See the note about version numbers near the top of png.h + +See INSTALL for instructions on how to install libpng. + +Libpng comes in several distribution formats. Get libpng-*.tar.gz, +libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings +in the text files, or lpng*.zip if you want DOS-style line endings. + +Version 0.89 was the first official release of libpng. Don't let the +fact that it's the first release fool you. The libpng library has been in +extensive use and testing since mid-1995. By late 1997 it had +finally gotten to the stage where there hadn't been significant +changes to the API in some time, and people have a bad feeling about +libraries with versions < 1.0. Version 1.0.0 was released in +March 1998. + +**** +Note that some of the changes to the png_info structure render this +version of the library binary incompatible with libpng-0.89 or +earlier versions if you are using a shared library. The type of the +"filler" parameter for png_set_filler() has changed from png_byte to +png_uint_32, which will affect shared-library applications that use +this function. + +To avoid problems with changes to the internals of png_info_struct, +new APIs have been made available in 0.95 to avoid direct application +access to info_ptr. These functions are the png_set_ and +png_get_ functions. These functions should be used when +accessing/storing the info_struct data, rather than manipulating it +directly, to avoid such problems in the future. + +It is important to note that the APIs do not make current programs +that access the info struct directly incompatible with the new +library. However, it is strongly suggested that new programs use +the new APIs (as shown in example.c and pngtest.c), and older programs +be converted to the new format, to facilitate upgrades in the future. +**** + +Additions since 0.90 include the ability to compile libpng as a +Windows DLL, and new APIs for accessing data in the info struct. +Experimental functions include the ability to set weighting and cost +factors for row filter selection, direct reads of integers from buffers +on big-endian processors that support misaligned data access, faster +methods of doing alpha composition, and more accurate 16->8 bit color +conversion. + +The additions since 0.89 include the ability to read from a PNG stream +which has had some (or all) of the signature bytes read by the calling +application. This also allows the reading of embedded PNG streams that +do not have the PNG file signature. As well, it is now possible to set +the library action on the detection of chunk CRC errors. It is possible +to set different actions based on whether the CRC error occurred in a +critical or an ancillary chunk. + +The changes made to the library, and bugs fixed are based on discussions +on the PNG-implement mailing list and not on material submitted +privately to Guy, Andreas, or Glenn. They will forward any good +suggestions to the list. + +For a detailed description on using libpng, read libpng-manual.txt. For +examples of libpng in a program, see example.c and pngtest.c. For usage +information and restrictions (what little they are) on libpng, see +png.h. For a description on using zlib (the compression library used by +libpng) and zlib's restrictions, see zlib.h + +I have included a general makefile, as well as several machine and +compiler specific ones, but you may have to modify one for your own needs. + +You should use zlib 1.0.4 or later to run this, but it MAY work with +versions as old as zlib 0.95. Even so, there are bugs in older zlib +versions which can cause the output of invalid compression streams for +some images. You will definitely need zlib 1.0.4 or later if you are +taking advantage of the MS-DOS "far" structure allocation for the small +and medium memory models. You should also note that zlib is a +compression library that is useful for more things than just PNG files. +You can use zlib as a drop-in replacement for fread() and fwrite() if +you are so inclined. + +zlib should be available at the same place that libpng is, or at. +ftp://ftp.info-zip.org/pub/infozip/zlib + +You may also want a copy of the PNG specification. It is available +as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find +these at http://www.libpng.org/pub/png/documents/ + +This code is currently being archived at libpng.sf.net in the +[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) +at GO GRAPHSUP. If you can't find it in any of those places, +e-mail me, and I'll help you find it. + +If you have any code changes, requests, problems, etc., please e-mail +them to me. Also, I'd appreciate any make files or project files, +and any modifications you needed to make to get libpng to compile, +along with a #define variable to tell what compiler/system you are on. +If you needed to add transformations to libpng, or wish libpng would +provide the image in a different way, drop me a note (and code, if +possible), so I can consider supporting the transformation. +Finally, if you get any warning messages when compiling libpng +(note: not zlib), and they are easy to fix, I'd appreciate the +fix. Please mention "libpng" somewhere in the subject line. Thanks. + +This release was created and will be supported by myself (of course +based in a large way on Guy's and Andreas' earlier work), and the PNG +development group. + +Send comments/corrections/commendations to png-mng-implement at +lists.sourceforge.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +You can't reach Guy, the original libpng author, at the addresses +given in previous versions of this document. He and Andreas will +read mail addressed to the png-implement list, however. + +Please do not send general questions about PNG. Send them to +png-mng-misc at lists.sf.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-misc to +subscribe). If you have a question about something +in the PNG specification that is related to using libpng, send it +to me. Send me any questions that start with "I was using libpng, +and ...". If in doubt, send questions to me. I'll bounce them +to others, if necessary. + +Please do not send suggestions on how to change PNG. We have +been discussing PNG for sixteen years now, and it is official and +finished. If you have suggestions for libpng, however, I'll +gladly listen. Even if your suggestion is not used immediately, +it may be used later. + +Files in this distribution: + + ANNOUNCE => Announcement of this version, with recent changes + CHANGES => Description of changes between libpng versions + KNOWNBUG => List of known bugs and deficiencies + LICENSE => License to use and redistribute libpng + README => This file + TODO => Things not implemented in the current library + Y2KINFO => Statement of Y2K compliance + example.c => Example code for using libpng functions + libpng.3 => manual page for libpng (includes libpng-manual.txt) + libpng-manual.txt => Description of libpng and its functions + libpngpf.3 => manual page for libpng's private functions + png.5 => manual page for the PNG format + png.c => Basic interface functions common to library + png.h => Library function and interface declarations (public) + pngpriv.h => Library function and interface declarations (private) + pngconf.h => System specific library configuration (public) + pngstruct.h => png_struct declaration (private) + pnginfo.h => png_info struct declaration (private) + pngdebug.h => debugging macros (private) + pngerror.c => Error/warning message I/O functions + pngget.c => Functions for retrieving info from struct + pngmem.c => Memory handling functions + pngbar.png => PNG logo, 88x31 + pngnow.png => PNG logo, 98x31 + pngpread.c => Progressive reading functions + pngread.c => Read data/helper high-level functions + pngrio.c => Lowest-level data read I/O functions + pngrtran.c => Read data transformation functions + pngrutil.c => Read data utility functions + pngset.c => Functions for storing data into the info_struct + pngtest.c => Library test program + pngtest.png => Library test sample image + pngtrans.c => Common data transformation functions + pngwio.c => Lowest-level write I/O functions + pngwrite.c => High-level write functions + pngwtran.c => Write data transformations + pngwutil.c => Write utility functions + contrib => Contributions + gregbook => source code for PNG reading and writing, from + Greg Roelofs' "PNG: The Definitive Guide", + O'Reilly, 1999 + msvctest => Builds and runs pngtest using a MSVC workspace + pngminus => Simple pnm2png and png2pnm programs + pngsuite => Test images + visupng => Contains a MSVC workspace for VisualPng + projects => Contains project files and workspaces for + building a DLL + cbuilder5 => Contains a Borland workspace for building + libpng and zlib + visualc6 => Contains a Microsoft Visual C++ (MSVC) + workspace for building libpng and zlib + visualc71 => Contains a Microsoft Visual C++ (MSVC) + workspace for building libpng and zlib + xcode => Contains an Apple xcode + workspace for building libpng and zlib + scripts => Directory containing scripts for building libpng: + (see scripts/README.txt for the list of scripts) + +Good luck, and happy coding. + +-Glenn Randers-Pehrson (current maintainer, since 1998) + Internet: glennrp at users.sourceforge.net + +-Andreas Eric Dilger (former maintainer, 1996-1997) + Internet: adilger at enel.ucalgary.ca + Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ + +-Guy Eric Schalnat (original author and former maintainer, 1995-1996) + (formerly of Group 42, Inc) + Internet: gschal at infinet.com diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/arm/filter_neon.S diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/arm/filter_neon.S --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/arm/filter_neon.S 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/arm/filter_neon.S 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,225 @@ + +/* filter_neon.S - NEON optimised filter functions + * + * Copyright (c) 2011 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ +#endif + +#ifdef __ELF__ +# define ELF +#else +# define ELF @ +#endif + + .arch armv7-a + .fpu neon + +.macro func name, export=0 + .macro endfunc +ELF .size \name, . - \name + .endfunc + .purgem endfunc + .endm + .text + .if \export + .global \name + .endif +ELF .type \name, STT_FUNC + .func \name +\name: +.endm + +func png_read_filter_row_sub4_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1] + vadd.u8 d0, d3, d4 + vadd.u8 d1, d0, d5 + vadd.u8 d2, d1, d6 + vadd.u8 d3, d2, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_sub3_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r2, #3 + mov r12, #12 + vld1.8 {q11}, [r0], r12 +1: + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d3, d22 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d0, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], r12 + vst1.32 {d0[0]}, [r1], r2 + vadd.u8 d2, d1, d6 + vst1.32 {d1[0]}, [r1], r2 + vadd.u8 d3, d2, d7 + vst1.32 {d2[0]}, [r1], r2 + vst1.32 {d3[0]}, [r1], r2 + subs r3, r3, #12 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_up_neon, export=1 + ldr r3, [r0, #4] @ rowbytes +1: + vld1.8 {q0}, [r1] + vld1.8 {q1}, [r2]! + vadd.u8 q0, q0, q1 + vst1.8 {q0}, [r1]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1] + vld4.32 {d16[],d17[],d18[],d19[]},[r2]! + vhadd.u8 d0, d3, d16 + vadd.u8 d0, d0, d4 + vhadd.u8 d1, d0, d17 + vadd.u8 d1, d1, d5 + vhadd.u8 d2, d1, d18 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + vext.8 d5, d22, d23, #3 + vhadd.u8 d0, d3, d20 + vext.8 d17, d20, d21, #3 + vadd.u8 d0, d0, d22 + vext.8 d6, d22, d23, #6 + vhadd.u8 d1, d0, d17 + vext.8 d18, d20, d21, #6 + vadd.u8 d1, d1, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d0[0]}, [r1], r4 + vhadd.u8 d2, d1, d18 + vst1.32 {d1[0]}, [r1], r4 + vext.8 d19, d21, d21, #1 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vst1.32 {d2[0]}, [r1], r4 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc + +.macro paeth rx, ra, rb, rc + vaddl.u8 q12, \ra, \rb @ a + b + vaddl.u8 q15, \rc, \rc @ 2*c + vabdl.u8 q13, \rb, \rc @ pa + vabdl.u8 q14, \ra, \rc @ pb + vabd.u16 q15, q12, q15 @ pc + vcle.u16 q12, q13, q14 @ pa <= pb + vcle.u16 q13, q13, q15 @ pa <= pc + vcle.u16 q14, q14, q15 @ pb <= pc + vand q12, q12, q13 @ pa <= pb && pa <= pc + vmovn.u16 d28, q14 + vmovn.u16 \rx, q12 + vbsl d28, \rb, \rc + vbsl \rx, \ra, d28 +.endm + +func png_read_filter_row_paeth4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d20, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1] + vld4.32 {d16[],d17[],d18[],d19[]},[r2]! + paeth d0, d3, d16, d20 + vadd.u8 d0, d0, d4 + paeth d1, d0, d17, d16 + vadd.u8 d1, d1, d5 + paeth d2, d1, d18, d17 + vadd.u8 d2, d2, d6 + paeth d3, d2, d19, d18 + vmov d20, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_paeth3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d4, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + paeth d0, d3, d20, d4 + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d0, d22 + vext.8 d17, d20, d21, #3 + paeth d1, d0, d17, d20 + vst1.32 {d0[0]}, [r1], r4 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d1, d5 + vext.8 d18, d20, d21, #6 + paeth d2, d1, d18, d17 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d1[0]}, [r1], r4 + vadd.u8 d2, d2, d6 + vext.8 d19, d21, d21, #1 + paeth d3, d2, d19, d18 + vst1.32 {d2[0]}, [r1], r4 + vmov d4, d19 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/libpng.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/libpng.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/libpng.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/libpng.pro 2013-05-05 17:10:28.000000000 +0000 @@ -0,0 +1,17 @@ + + +TEMPLATE = lib +TARGET = png + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.c + + +INCLUDEPATH += ../zlib + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/png.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/png.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/png.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/png.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2874 @@ + +/* png.c - location for general purpose libpng functions + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef png_libpng_version_1_5_12 Your_png_h_is_not_version_1_5_12; + +/* 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) +{ + png_debug(1, "in png_set_sig_bytes"); + + if (png_ptr == NULL) + return; + + 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 behavior as strcmp, memcmp, etc). + */ +int PNGAPI +png_sig_cmp(png_const_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))); +} + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Function to allocate memory for zlib */ +PNG_FUNCTION(voidpf /* PRIVATE */, +png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) +{ + png_voidp ptr; + png_structp p=(png_structp)png_ptr; + png_uint_32 save_flags=p->flags; + png_alloc_size_t 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_alloc_size_t)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; + + return ((voidpf)ptr); +} + +/* Function to free memory for zlib */ +void /* PRIVATE */ +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) +{ + /* The cast is safe because the crc is a 32 bit value. */ + png_ptr->crc = (png_uint_32)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_const_bytep ptr, png_size_t length) +{ + int need_crc = 1; + + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) + { + 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; + } + + /* 'uLong' is defined as unsigned long, this means that on some systems it is + * a 64 bit value. crc32, however, returns 32 bits so the following cast is + * safe. 'uInt' may be no more than 16 bits, so it is necessary to perform a + * loop here. + */ + if (need_crc && length > 0) + { + uLong crc = png_ptr->crc; /* Should never issue a warning */ + + do + { + uInt safeLength = (uInt)length; + if (safeLength == 0) + safeLength = (uInt)-1; /* evil, but safe */ + + crc = crc32(crc, ptr, safeLength); + + /* The following should never issue compiler warnings, if they do the + * target system has characteristics that will probably violate other + * assumptions within the libpng code. + */ + ptr += safeLength; + length -= safeLength; + } + while (length > 0); + + /* And the following is always safe because the crc is only 32 bits. */ + png_ptr->crc = (png_uint_32)crc; + } +} + +/* Check a user supplied version number, called from both read and write + * functions that create a png_struct + */ +int +png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver) +{ + if (user_png_ver) + { + int i = 0; + + do + { + if (user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + } + + else + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + + 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')) + { +#ifdef PNG_WARNINGS_SUPPORTED + size_t pos = 0; + char m[128]; + + pos = png_safecat(m, sizeof m, pos, "Application built with libpng-"); + pos = png_safecat(m, sizeof m, pos, user_png_ver); + pos = png_safecat(m, sizeof m, pos, " but running with "); + pos = png_safecat(m, sizeof m, pos, png_libpng_ver); + + png_warning(png_ptr, m); +#endif + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags = 0; +#endif + + return 0; + } + } + + /* Success return. */ + return 1; +} + +/* 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_FUNCTION(png_infop,PNGAPI +png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) +{ + png_infop info_ptr; + + png_debug(1, "in png_create_info_struct"); + + 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; + + png_debug(1, "in png_destroy_info_struct"); + + if (png_ptr == NULL) + return; + + 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. + */ + +void PNGAPI +png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) +{ + png_infop info_ptr = *ptr_ptr; + + png_debug(1, "in png_info_init_3"); + + if (info_ptr == NULL) + return; + + 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)); +} + +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"); + + 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"); +} + +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"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +#ifdef PNG_TEXT_SUPPORTED + /* Free text item num or (if num == -1) all text items */ + if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) + { + 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 + +#ifdef PNG_tRNS_SUPPORTED + /* Free any tRNS entry */ + if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->trans_alpha); + info_ptr->trans_alpha = NULL; + info_ptr->valid &= ~PNG_INFO_tRNS; + } +#endif + +#ifdef PNG_sCAL_SUPPORTED + /* Free any sCAL entry */ + if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) + { + 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; + info_ptr->valid &= ~PNG_INFO_sCAL; + } +#endif + +#ifdef PNG_pCAL_SUPPORTED + /* Free any pCAL entry */ + if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) + { + 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 + +#ifdef PNG_iCCP_SUPPORTED + /* Free any iCCP entry */ + if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) + { + 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 + +#ifdef PNG_sPLT_SUPPORTED + /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ + if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) + { + 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 + +#ifdef 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; + } + + if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) + { + 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 < 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 + +#ifdef PNG_hIST_SUPPORTED + /* Free any hIST entry */ + if ((mask & PNG_FREE_HIST) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; + } +#endif + + /* Free any PLTE entry that was internally allocated */ + if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) + { + png_zfree(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; + info_ptr->num_palette = 0; + } + +#ifdef PNG_INFO_IMAGE_SUPPORTED + /* Free any image bits attached to the info structure */ + if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) + { + 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 + + if (num != -1) + mask &= ~PNG_FREE_MUL; + + info_ptr->free_me &= ~mask; +} + +/* 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"); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#ifdef PNG_HANDLE_AS_UNKNOWN_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) +# ifdef PNG_STDIO_SUPPORTED +/* 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 or otherwise disabled PNG_STDIO_SUPPORTED, 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"); + + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = (png_voidp)fp; +} +# endif + +# ifdef 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_const_charp PNGAPI +png_convert_to_rfc1123(png_structp png_ptr, png_const_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 (ptime->year > 9999 /* RFC1123 limitation */ || + ptime->month == 0 || ptime->month > 12 || + ptime->day == 0 || ptime->day > 31 || + ptime->hour > 23 || ptime->minute > 59 || + ptime->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + return (NULL); + } + + { + size_t pos = 0; + char number_buf[5]; /* enough for a four-digit year */ + +# define APPEND_STRING(string)\ + pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\ + pos, (string)) +# define APPEND_NUMBER(format, value)\ + APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) +# define APPEND(ch)\ + if (pos < (sizeof png_ptr->time_buffer)-1)\ + png_ptr->time_buffer[pos++] = (ch) + + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); + APPEND(' '); + APPEND_STRING(short_months[(ptime->month - 1)]); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); + APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ + +# undef APPEND +# undef APPEND_NUMBER +# undef APPEND_STRING + } + + return png_ptr->time_buffer; +} +# endif /* PNG_TIME_RFC1123_SUPPORTED */ + +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +png_const_charp PNGAPI +png_get_copyright(png_const_structp png_ptr) +{ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef PNG_STRING_COPYRIGHT + return PNG_STRING_COPYRIGHT +#else +# ifdef __STDC__ + return PNG_STRING_NEWLINE \ + "libpng version 1.5.12 - July 11, 2012" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2012 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ + "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ + "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ + PNG_STRING_NEWLINE; +# else + return "libpng version 1.5.12 - July 11, 2012\ + Copyright (c) 1998-2012 Glenn Randers-Pehrson\ + Copyright (c) 1996-1997 Andreas Dilger\ + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; +# endif +#endif +} + +/* 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_const_charp PNGAPI +png_get_libpng_ver(png_const_structp png_ptr) +{ + /* Version of *.c files used when building libpng */ + return png_get_header_ver(png_ptr); +} + +png_const_charp PNGAPI +png_get_header_ver(png_const_structp png_ptr) +{ + /* Version of *.h files used when building libpng */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ + return PNG_LIBPNG_VER_STRING; +} + +png_const_charp PNGAPI +png_get_header_version(png_const_structp png_ptr) +{ + /* Returns longer string containing both version and date */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef __STDC__ + return PNG_HEADER_VERSION_STRING +# ifndef PNG_READ_SUPPORTED + " (NO READ SUPPORT)" +# endif + PNG_STRING_NEWLINE; +#else + return PNG_HEADER_VERSION_STRING; +#endif +} + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) +{ + /* Check chunk_name and return "keep" value if it's on the list, else 0 */ + png_const_bytep p, p_end; + + if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0) + return PNG_HANDLE_CHUNK_AS_DEFAULT; + + p_end = png_ptr->chunk_list; + p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ + + /* The code is the fifth byte after each four byte string. Historically this + * code was always searched from the end of the list, so it should continue + * to do so in case there are duplicated entries. + */ + do /* num_chunk_list > 0, so at least one */ + { + p -= 5; + if (!png_memcmp(chunk_name, p, 4)) + return p[4]; + } + while (p > p_end); + + return PNG_HANDLE_CHUNK_AS_DEFAULT; +} + +int /* PRIVATE */ +png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name) +{ + png_byte chunk_string[5]; + + PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); + return png_handle_as_unknown(png_ptr, chunk_string); +} +#endif + +#ifdef PNG_READ_SUPPORTED +/* 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 /* PNG_READ_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_WRITE_SUPPORTED) +/* png_convert_size: a PNGAPI but no longer in png.h, so deleted + * at libpng 1.5.5! + */ + +/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ +# ifdef PNG_CHECK_cHRM_SUPPORTED + +int /* PRIVATE */ +png_check_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) +{ + int ret = 1; + unsigned long xy_hi,xy_lo,yx_hi,yx_lo; + + png_debug(1, "in function png_check_cHRM_fixed"); + + if (png_ptr == NULL) + return 0; + + /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white + * y must also be greater than 0. To test for the upper limit calculate + * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression + * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is + * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it + * pointless (and it produces compiler warnings!) + */ + 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"); + ret = 0; + } + /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ + if (white_x > PNG_FP_1 - white_y) + { + png_warning(png_ptr, "Invalid cHRM white point"); + ret = 0; + } + + if (red_x > PNG_FP_1 - red_y) + { + png_warning(png_ptr, "Invalid cHRM red point"); + ret = 0; + } + + if (green_x > PNG_FP_1 - green_y) + { + png_warning(png_ptr, "Invalid cHRM green point"); + ret = 0; + } + + if (blue_x > PNG_FP_1 - blue_y) + { + png_warning(png_ptr, "Invalid cHRM blue point"); + ret = 0; + } + + png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); + png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); + + if (xy_hi == yx_hi && xy_lo == yx_lo) + { + png_warning(png_ptr, + "Ignoring attempt to set cHRM RGB triangle with zero area"); + ret = 0; + } + + return ret; +} +# endif /* PNG_CHECK_cHRM_SUPPORTED */ + +#ifdef PNG_cHRM_SUPPORTED +/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for + * cHRM, as opposed to using chromaticities. These internal APIs return + * non-zero on a parameter error. The X, Y and Z values are required to be + * positive and less than 1.0. + */ +int png_xy_from_XYZ(png_xy *xy, png_XYZ XYZ) +{ + png_int_32 d, dwhite, whiteX, whiteY; + + d = XYZ.redX + XYZ.redY + XYZ.redZ; + if (!png_muldiv(&xy->redx, XYZ.redX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->redy, XYZ.redY, PNG_FP_1, d)) return 1; + dwhite = d; + whiteX = XYZ.redX; + whiteY = XYZ.redY; + + d = XYZ.greenX + XYZ.greenY + XYZ.greenZ; + if (!png_muldiv(&xy->greenx, XYZ.greenX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->greeny, XYZ.greenY, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ.greenX; + whiteY += XYZ.greenY; + + d = XYZ.blueX + XYZ.blueY + XYZ.blueZ; + if (!png_muldiv(&xy->bluex, XYZ.blueX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->bluey, XYZ.blueY, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ.blueX; + whiteY += XYZ.blueY; + + /* The reference white is simply the same of the end-point (X,Y,Z) vectors, + * thus: + */ + if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1; + if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1; + + return 0; +} + +int png_XYZ_from_xy(png_XYZ *XYZ, png_xy xy) +{ + png_fixed_point red_inverse, green_inverse, blue_scale; + png_fixed_point left, right, denominator; + + /* Check xy and, implicitly, z. Note that wide gamut color spaces typically + * have end points with 0 tristimulus values (these are impossible end + * points, but they are used to cover the possible colors.) + */ + if (xy.redx < 0 || xy.redx > PNG_FP_1) return 1; + if (xy.redy < 0 || xy.redy > PNG_FP_1-xy.redx) return 1; + if (xy.greenx < 0 || xy.greenx > PNG_FP_1) return 1; + if (xy.greeny < 0 || xy.greeny > PNG_FP_1-xy.greenx) return 1; + if (xy.bluex < 0 || xy.bluex > PNG_FP_1) return 1; + if (xy.bluey < 0 || xy.bluey > PNG_FP_1-xy.bluex) return 1; + if (xy.whitex < 0 || xy.whitex > PNG_FP_1) return 1; + if (xy.whitey < 0 || xy.whitey > PNG_FP_1-xy.whitex) return 1; + + /* The reverse calculation is more difficult because the original tristimulus + * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 + * derived values were recorded in the cHRM chunk; + * (red,green,blue,white)x(x,y). This loses one degree of freedom and + * therefore an arbitrary ninth value has to be introduced to undo the + * original transformations. + * + * Think of the original end-points as points in (X,Y,Z) space. The + * chromaticity values (c) have the property: + * + * C + * c = --------- + * X + Y + Z + * + * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the + * three chromaticity values (x,y,z) for each end-point obey the + * relationship: + * + * x + y + z = 1 + * + * This describes the plane in (X,Y,Z) space that intersects each axis at the + * value 1.0; call this the chromaticity plane. Thus the chromaticity + * calculation has scaled each end-point so that it is on the x+y+z=1 plane + * and chromaticity is the intersection of the vector from the origin to the + * (X,Y,Z) value with the chromaticity plane. + * + * To fully invert the chromaticity calculation we would need the three + * end-point scale factors, (red-scale, green-scale, blue-scale), but these + * were not recorded. Instead we calculated the reference white (X,Y,Z) and + * recorded the chromaticity of this. The reference white (X,Y,Z) would have + * given all three of the scale factors since: + * + * color-C = color-c * color-scale + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * But cHRM records only white-x and white-y, so we have lost the white scale + * factor: + * + * white-C = white-c*white-scale + * + * To handle this the inverse transformation makes an arbitrary assumption + * about white-scale: + * + * Assume: white-Y = 1.0 + * Hence: white-scale = 1/white-y + * Or: red-Y + green-Y + blue-Y = 1.0 + * + * Notice the last statement of the assumption gives an equation in three of + * the nine values we want to calculate. 8 more equations come from the + * above routine as summarised at the top above (the chromaticity + * calculation): + * + * Given: color-x = color-X / (color-X + color-Y + color-Z) + * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 + * + * This is 9 simultaneous equations in the 9 variables "color-C" and can be + * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix + * determinants, however this is not as bad as it seems because only 28 of + * the total of 90 terms in the various matrices are non-zero. Nevertheless + * Cramer's rule is notoriously numerically unstable because the determinant + * calculation involves the difference of large, but similar, numbers. It is + * difficult to be sure that the calculation is stable for real world values + * and it is certain that it becomes unstable where the end points are close + * together. + * + * So this code uses the perhaps slightly less optimal but more + * understandable and totally obvious approach of calculating color-scale. + * + * This algorithm depends on the precision in white-scale and that is + * (1/white-y), so we can immediately see that as white-y approaches 0 the + * accuracy inherent in the cHRM chunk drops off substantially. + * + * libpng arithmetic: a simple invertion of the above equations + * ------------------------------------------------------------ + * + * white_scale = 1/white-y + * white-X = white-x * white-scale + * white-Y = 1.0 + * white-Z = (1 - white-x - white-y) * white_scale + * + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * This gives us three equations in (red-scale,green-scale,blue-scale) where + * all the coefficients are now known: + * + * red-x*red-scale + green-x*green-scale + blue-x*blue-scale + * = white-x/white-y + * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 + * red-z*red-scale + green-z*green-scale + blue-z*blue-scale + * = (1 - white-x - white-y)/white-y + * + * In the last equation color-z is (1 - color-x - color-y) so we can add all + * three equations together to get an alternative third: + * + * red-scale + green-scale + blue-scale = 1/white-y = white-scale + * + * So now we have a Cramer's rule solution where the determinants are just + * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve + * multiplication of three coefficients so we can't guarantee to avoid + * overflow in the libpng fixed point representation. Using Cramer's rule in + * floating point is probably a good choice here, but it's not an option for + * fixed point. Instead proceed to simplify the first two equations by + * eliminating what is likely to be the largest value, blue-scale: + * + * blue-scale = white-scale - red-scale - green-scale + * + * Hence: + * + * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = + * (white-x - blue-x)*white-scale + * + * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = + * 1 - blue-y*white-scale + * + * And now we can trivially solve for (red-scale,green-scale): + * + * green-scale = + * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale + * ----------------------------------------------------------- + * green-x - blue-x + * + * red-scale = + * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale + * --------------------------------------------------------- + * red-y - blue-y + * + * Hence: + * + * red-scale = + * ( (green-x - blue-x) * (white-y - blue-y) - + * (green-y - blue-y) * (white-x - blue-x) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * green-scale = + * ( (red-y - blue-y) * (white-x - blue-x) - + * (red-x - blue-x) * (white-y - blue-y) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * Accuracy: + * The input values have 5 decimal digits of accuracy. The values are all in + * the range 0 < value < 1, so simple products are in the same range but may + * need up to 10 decimal digits to preserve the original precision and avoid + * underflow. Because we are using a 32-bit signed representation we cannot + * match this; the best is a little over 9 decimal digits, less than 10. + * + * The approach used here is to preserve the maximum precision within the + * signed representation. Because the red-scale calculation above uses the + * difference between two products of values that must be in the range -1..+1 + * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The + * factor is irrelevant in the calculation because it is applied to both + * numerator and denominator. + * + * Note that the values of the differences of the products of the + * chromaticities in the above equations tend to be small, for example for + * the sRGB chromaticities they are: + * + * red numerator: -0.04751 + * green numerator: -0.08788 + * denominator: -0.2241 (without white-y multiplication) + * + * The resultant Y coefficients from the chromaticities of some widely used + * color space definitions are (to 15 decimal places): + * + * sRGB + * 0.212639005871510 0.715168678767756 0.072192315360734 + * Kodak ProPhoto + * 0.288071128229293 0.711843217810102 0.000085653960605 + * Adobe RGB + * 0.297344975250536 0.627363566255466 0.075291458493998 + * Adobe Wide Gamut RGB + * 0.258728243040113 0.724682314948566 0.016589442011321 + */ + /* By the argument, above overflow should be impossible here. The return + * value of 2 indicates an internal error to the caller. + */ + if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.redy - xy.bluey, 7)) return 2; + if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.redx - xy.bluex, 7)) return 2; + denominator = left - right; + + /* Now find the red numerator. */ + if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; + if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; + + /* Overflow is possible here and it indicates an extreme set of PNG cHRM + * chunk values. This calculation actually returns the reciprocal of the + * scale value because this allows us to delay the multiplication of white-y + * into the denominator, which tends to produce a small number. + */ + if (!png_muldiv(&red_inverse, xy.whitey, denominator, left-right) || + red_inverse <= xy.whitey /* r+g+b scales = white scale */) + return 1; + + /* Similarly for green_inverse: */ + if (!png_muldiv(&left, xy.redy-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; + if (!png_muldiv(&right, xy.redx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; + if (!png_muldiv(&green_inverse, xy.whitey, denominator, left-right) || + green_inverse <= xy.whitey) + return 1; + + /* And the blue scale, the checks above guarantee this can't overflow but it + * can still produce 0 for extreme cHRM values. + */ + blue_scale = png_reciprocal(xy.whitey) - png_reciprocal(red_inverse) - + png_reciprocal(green_inverse); + if (blue_scale <= 0) return 1; + + + /* And fill in the png_XYZ: */ + if (!png_muldiv(&XYZ->redX, xy.redx, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->redY, xy.redy, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->redZ, PNG_FP_1 - xy.redx - xy.redy, PNG_FP_1, + red_inverse)) + return 1; + + if (!png_muldiv(&XYZ->greenX, xy.greenx, PNG_FP_1, green_inverse)) return 1; + if (!png_muldiv(&XYZ->greenY, xy.greeny, PNG_FP_1, green_inverse)) return 1; + if (!png_muldiv(&XYZ->greenZ, PNG_FP_1 - xy.greenx - xy.greeny, PNG_FP_1, + green_inverse)) + return 1; + + if (!png_muldiv(&XYZ->blueX, xy.bluex, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blueY, xy.bluey, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blueZ, PNG_FP_1 - xy.bluex - xy.bluey, blue_scale, + PNG_FP_1)) + return 1; + + return 0; /*success*/ +} + +int png_XYZ_from_xy_checked(png_structp png_ptr, png_XYZ *XYZ, png_xy xy) +{ + switch (png_XYZ_from_xy(XYZ, xy)) + { + case 0: /* success */ + return 1; + + case 1: + /* The chunk may be technically valid, but we got png_fixed_point + * overflow while trying to get XYZ values out of it. This is + * entirely benign - the cHRM chunk is pretty extreme. + */ + png_warning(png_ptr, + "extreme cHRM chunk cannot be converted to tristimulus values"); + break; + + default: + /* libpng is broken; this should be a warning but if it happens we + * want error reports so for the moment it is an error. + */ + png_error(png_ptr, "internal error in png_XYZ_from_xy"); + break; + } + + /* ERROR RETURN */ + return 0; +} +#endif + +void /* PRIVATE */ +png_check_IHDR(png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + int error = 0; + + /* Check for width and height valid values */ + if (width == 0) + { + png_warning(png_ptr, "Image width is zero in IHDR"); + error = 1; + } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max) + +# else + if (width > PNG_USER_WIDTH_MAX) +# endif + { + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); + error = 1; + } + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (height > png_ptr->user_height_max) +# else + if (height > PNG_USER_HEIGHT_MAX) +# endif + { + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); + error = 1; + } + + if (width > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + + if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + + if (width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 48 /* 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_warning(png_ptr, "Invalid bit depth in IHDR"); + error = 1; + } + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + { + png_warning(png_ptr, "Invalid color type in IHDR"); + error = 1; + } + + 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_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); + error = 1; + } + + if (interlace_type >= PNG_INTERLACE_LAST) + { + png_warning(png_ptr, "Unknown interlace method in IHDR"); + error = 1; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Unknown compression method in IHDR"); + error = 1; + } + +# ifdef 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_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } + + if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) + { + png_warning(png_ptr, "Invalid filter method in IHDR"); + error = 1; + } + } + +# else + if (filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } +# endif + + if (error == 1) + png_error(png_ptr, "Invalid IHDR data"); +} + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* ASCII to fp functions */ +/* Check an ASCII formated floating point value, see the more detailed + * comments in pngpriv.h + */ +/* The following is used internally to preserve the sticky flags */ +#define png_fp_add(state, flags) ((state) |= (flags)) +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) + +int /* PRIVATE */ +png_check_fp_number(png_const_charp string, png_size_t size, int *statep, + png_size_tp whereami) +{ + int state = *statep; + png_size_t i = *whereami; + + while (i < size) + { + int type; + /* First find the type of the next character */ + switch (string[i]) + { + case 43: type = PNG_FP_SAW_SIGN; break; + case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; + case 46: type = PNG_FP_SAW_DOT; break; + case 48: type = PNG_FP_SAW_DIGIT; break; + case 49: case 50: case 51: case 52: + case 53: case 54: case 55: case 56: + case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; + case 69: + case 101: type = PNG_FP_SAW_E; break; + default: goto PNG_FP_End; + } + + /* Now deal with this type according to the current + * state, the type is arranged to not overlap the + * bits of the PNG_FP_STATE. + */ + switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) + { + case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, type); + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DOT: + /* Ok as trailer, ok as lead of fraction. */ + if (state & PNG_FP_SAW_DOT) /* two dots */ + goto PNG_FP_End; + + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ + png_fp_add(state, type); + + else + png_fp_set(state, PNG_FP_FRACTION | type); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + png_fp_add(state, type | PNG_FP_WAS_VALID); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_E: + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: + goto PNG_FP_End; ** no sign in fraction */ + + /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: + goto PNG_FP_End; ** Because SAW_DOT is always set */ + + case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: + png_fp_add(state, type | PNG_FP_WAS_VALID); + break; + + case PNG_FP_FRACTION + PNG_FP_SAW_E: + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); + + break; + + /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: + goto PNG_FP_End; */ + + case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); + + break; + + /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: + goto PNG_FP_End; */ + + default: goto PNG_FP_End; /* I.e. break 2 */ + } + + /* The character seems ok, continue. */ + ++i; + } + +PNG_FP_End: + /* Here at the end, update the state and return the correct + * return code. + */ + *statep = state; + *whereami = i; + + return (state & PNG_FP_SAW_DIGIT) != 0; +} + + +/* The same but for a complete string. */ +int +png_check_fp_string(png_const_charp string, png_size_t size) +{ + int state=0; + png_size_t char_index=0; + + if (png_check_fp_number(string, size, &state, &char_index) && + (char_index == size || string[char_index] == 0)) + return state /* must be non-zero - see above */; + + return 0; /* i.e. fail */ +} +#endif /* pCAL or sCAL */ + +#ifdef PNG_READ_sCAL_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +/* Utility used below - a simple accurate power of ten from an integral + * exponent. + */ +static double +png_pow10(int power) +{ + int recip = 0; + double d = 1.0; + + /* Handle negative exponent with a reciprocal at the end because + * 10 is exact whereas .1 is inexact in base 2 + */ + if (power < 0) + { + if (power < DBL_MIN_10_EXP) return 0; + recip = 1, power = -power; + } + + if (power > 0) + { + /* Decompose power bitwise. */ + double mult = 10.0; + do + { + if (power & 1) d *= mult; + mult *= mult; + power >>= 1; + } + while (power > 0); + + if (recip) d = 1/d; + } + /* else power is 0 and d is 1 */ + + return d; +} + +/* Function to format a floating point value in ASCII with a given + * precision. + */ +void /* PRIVATE */ +png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, + double fp, unsigned int precision) +{ + /* We use standard functions from math.h, but not printf because + * that would require stdio. The caller must supply a buffer of + * sufficient size or we will png_error. The tests on size and + * the space in ascii[] consumed are indicated below. + */ + if (precision < 1) + precision = DBL_DIG; + + /* Enforce the limit of the implementation precision too. */ + if (precision > DBL_DIG+1) + precision = DBL_DIG+1; + + /* Basic sanity checks */ + if (size >= precision+5) /* See the requirements below. */ + { + if (fp < 0) + { + fp = -fp; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ + --size; + } + + if (fp >= DBL_MIN && fp <= DBL_MAX) + { + int exp_b10; /* A base 10 exponent */ + double base; /* 10^exp_b10 */ + + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp_b10); /* exponent to base 2 */ + + exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ + + /* Avoid underflow here. */ + base = png_pow10(exp_b10); /* May underflow */ + + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp_b10+1); + + if (test <= DBL_MAX) + ++exp_b10, base = test; + + else + break; + } + + /* Normalize fp and correct exp_b10, after this fp is in the + * range [.1,1) and exp_b10 is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp_b10 is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) fp /= 10, ++exp_b10; + + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ + + { + int czero, clead, cdigits; + char exponent[10]; + + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ + { + czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ + exp_b10 = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ + + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + + do + { + double d; + + fp *= 10.0; + + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero-clead+1 < (int)precision) + fp = modf(fp, &d); + + else + { + d = floor(fp + .5); + + if (d > 9.0) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero, d = 1; + if (cdigits == 0) --clead; + } + + else + { + while (cdigits > 0 && d > 9.0) + { + int ch = *--ascii; + + if (exp_b10 != (-1)) + ++exp_b10; + + else if (ch == 46) + { + ch = *--ascii, ++size; + /* Advance exp_b10 to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp_b10 = 1; + } + + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } + + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9.0) /* cdigits == 0 */ + { + if (exp_b10 == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + + if (ch == 46) + ++size, exp_b10 = 1; + + /* Else lost a leading zero, so 'exp_b10' is + * still ok at (-1) + */ + } + else + ++exp_b10; + + /* In all cases we output a '1' */ + d = 1.0; + } + } + } + fp = 0; /* Guarantees termination below. */ + } + + if (d == 0.0) + { + ++czero; + if (cdigits == 0) ++clead; + } + + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; + + while (czero > 0) + { + /* exp_b10 == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp_b10' any + * more! + */ + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) *ascii++ = 46, --size; + /* PLUS 1: TOTAL 4 */ + --exp_b10; + } + *ascii++ = 48, --czero; + } + + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) *ascii++ = 46, --size; /* counted + above */ + --exp_b10; + } + + *ascii++ = (char)(48 + (int)d), ++cdigits; + } + } + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + + /* The total output count (max) is now 4+precision */ + + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At + * this point exp_b10==(-1) is effectively if flag - it got + * to '-1' because of the decrement after outputing + * the decimal point above (the exponent required is + * *not* -1!) + */ + if (exp_b10 >= (-1) && exp_b10 <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doest add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (--exp_b10 >= 0) *ascii++ = 48; + + *ascii = 0; + + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } + + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; + + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ + + /* The following use of an unsigned temporary avoids ambiguities in + * the signed arithmetic on exp_b10 and permits GCC at least to do + * better optimization. + */ + { + unsigned int uexp_b10; + + if (exp_b10 < 0) + { + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ + uexp_b10 = -exp_b10; + } + + else + uexp_b10 = exp_b10; + + cdigits = 0; + + while (uexp_b10 > 0) + { + exponent[cdigits++] = (char)(48 + uexp_b10 % 10); + uexp_b10 /= 10; + } + } + + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if ((int)size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + + *ascii = 0; + + return; + } + } + } + else if (!(fp >= DBL_MIN)) + { + *ascii++ = 48; /* '0' */ + *ascii = 0; + return; + } + else + { + *ascii++ = 105; /* 'i' */ + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} + +# endif /* FLOATING_POINT */ + +# ifdef PNG_FIXED_POINT_SUPPORTED +/* Function to format a fixed point value in ASCII. + */ +void /* PRIVATE */ +png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, + png_fixed_point fp) +{ + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: + */ + if (size > 12) + { + png_uint_32 num; + + /* Avoid overflow here on the minimum integer. */ + if (fp < 0) + *ascii++ = 45, --size, num = -fp; + else + num = fp; + + if (num <= 0x80000000) /* else overflowed */ + { + unsigned int ndigits = 0, first = 16 /* flag value */; + char digits[10]; + + while (num) + { + /* Split the low digit off num: */ + unsigned int tmp = num/10; + num -= tmp*10; + digits[ndigits++] = (char)(48 + num); + /* Record the first non-zero digit, note that this is a number + * starting at 1, it's not actually the array index. + */ + if (first == 16 && num > 0) + first = ndigits; + num = tmp; + } + + if (ndigits > 0) + { + while (ndigits > 5) *ascii++ = digits[--ndigits]; + /* The remaining digits are fractional digits, ndigits is '5' or + * smaller at this point. It is certainly not zero. Check for a + * non-zero fractional digit: + */ + if (first <= 5) + { + unsigned int i; + *ascii++ = 46; /* decimal point */ + /* ndigits may be <5 for small numbers, output leading zeros + * then ndigits digits to first: + */ + i = 5; + while (ndigits < i) *ascii++ = 48, --i; + while (ndigits >= first) *ascii++ = digits[--ndigits]; + /* Don't output the trailing zeros! */ + } + } + else + *ascii++ = 48; + + /* And null terminate the string: */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FIXED_POINT */ +#endif /* READ_SCAL */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) +png_fixed_point +png_fixed(png_structp png_ptr, double fp, png_const_charp text) +{ + double r = floor(100000 * fp + .5); + + if (r > 2147483647. || r < -2147483648.) + png_fixed_error(png_ptr, text); + + return (png_fixed_point)r; +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || \ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) +/* muldiv functions */ +/* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to + * the nearest .00001). Overflow and divide by zero are signalled in + * the result, a boolean - true on success, false on overflow. + */ +int +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, + png_int_32 divisor) +{ + /* Return a * times / divisor, rounded. */ + if (divisor != 0) + { + if (a == 0 || times == 0) + { + *res = 0; + return 1; + } + else + { +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a; + r *= times; + r /= divisor; + r = floor(r+.5); + + /* A png_fixed_point is a 32-bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } +#else + int negative = 0; + png_uint_32 A, T, D; + png_uint_32 s16, s32, s00; + + if (a < 0) + negative = 1, A = -a; + else + A = a; + + if (times < 0) + negative = !negative, T = -times; + else + T = times; + + if (divisor < 0) + negative = !negative, D = -divisor; + else + D = divisor; + + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + s00 = (A & 0xffff) * (T & 0xffff); + + s16 = (s16 & 0xffff) << 16; + s00 += s16; + + if (s00 < s16) + ++s32; /* carry */ + + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64-bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ + + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + + else + d32 = 0, d00 = D; + + if (s32 > d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) + ++result; + + if (negative) + result = -result; + + /* Check for overflow. */ + if ((negative && result <= 0) || (!negative && result >= 0)) + { + *res = result; + return 1; + } + } +#endif + } + } + + return 0; +} +#endif /* READ_GAMMA || INCH_CONVERSIONS */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* The following is for when the caller doesn't much care about the + * result. + */ +png_fixed_point +png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, + png_int_32 divisor) +{ + png_fixed_point result; + + if (png_muldiv(&result, a, times, divisor)) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; +} +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gamma */ +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ +png_fixed_point +png_reciprocal(png_fixed_point a) +{ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(1E10/a+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, 100000, 100000, a)) + return res; +#endif + + return 0; /* error/overflow */ +} + +/* A local convenience routine. */ +static png_fixed_point +png_product2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, a, b, 100000)) + return res; +#endif + + return 0; /* overflow */ +} + +/* The inverse of the above. */ +png_fixed_point +png_reciprocal2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = 1E15/a; + r /= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + /* This may overflow because the range of png_fixed_point isn't symmetric, + * but this API is only used for the product of file and screen gamma so it + * doesn't matter that the smallest number it can produce is 1/21474, not + * 1/100000 + */ + png_fixed_point res = png_product2(a, b); + + if (res != 0) + return png_reciprocal(res); +#endif + + return 0; /* overflow */ +} +#endif /* READ_GAMMA */ + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, + * 2010: moved from pngset.c) */ +/* + * Multiply two 32-bit numbers, V1 and V2, using 32-bit + * arithmetic, to produce a 64-bit result in the HI/LO words. + * + * A B + * x C D + * ------ + * AD || BD + * AC || CB || 0 + * + * where A and B are the high and low 16-bit words of V1, + * C and D are the 16-bit words of V2, AD is the product of + * A and D, and X || Y is (X << 16) + Y. +*/ + +void /* PRIVATE */ +png_64bit_product (long v1, long v2, unsigned long *hi_product, + unsigned long *lo_product) +{ + int a, b, c, d; + long lo, hi, x, y; + + a = (v1 >> 16) & 0xffff; + b = v1 & 0xffff; + c = (v2 >> 16) & 0xffff; + d = v2 & 0xffff; + + lo = b * d; /* BD */ + x = a * d + c * b; /* AD + CB */ + y = ((lo >> 16) & 0xffff) + x; + + lo = (lo & 0xffff) | ((y & 0xffff) << 16); + hi = (y >> 16) & 0xffff; + + hi += a * c; /* AC */ + + *hi_product = (unsigned long)hi; + *lo_product = (unsigned long)lo; +} +#endif /* CHECK_cHRM */ + +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8-bit + * or 16-bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double + * precision floating point arithmetic would work fine. The programs are given + * at the head of each table. + * + * 8-bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8-bit floating point + * mantissa. The numbers are 32-bit fractions. + */ +static png_uint_32 +png_8bit_l2[128] = +{ +# ifdef PNG_DO_BC + for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } +# else + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U +# endif + +#if 0 + /* The following are the values for 16-bit tables - these work fine for the + * 8-bit conversions but produce very slightly larger errors in the 16-bit + * log (about 1.2 as opposed to 0.7 absolute error in the final value). To + * use these all the shifts below must be adjusted appropriately. + */ + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, + 1119, 744, 372 +#endif +}; + +PNG_STATIC png_int_32 +png_log8bit(unsigned int x) +{ + unsigned int lg2 = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 + * input), return 7.99998 for the overflow (log 0) case - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) + return 0xffffffff; + + if ((x & 0xf0) == 0) + lg2 = 4, x <<= 4; + + if ((x & 0xc0) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x80) == 0) + lg2 += 1, x <<= 1; + + /* result is at most 19 bits, so this cast is safe: */ + return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); +} + +/* The above gives exact (to 16 binary places) log2 values for 8-bit images, + * for 16-bit images we use the most significant 8 bits of the 16-bit value to + * get an approximation then multiply the approximation by a correction factor + * determined by the remaining up to 8 bits. This requires an additional step + * in the 16-bit case. + * + * We want log2(value/65535), we have log2(v'/255), where: + * + * value = v' * 256 + v'' + * = v' * f + * + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less + * than 258. The final factor also needs to correct for the fact that our 8-bit + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. + * + * This gives a final formula using a calculated value 'x' which is value/v' and + * scaling by 65536 to match the above table: + * + * log2(x/257) * 65536 + * + * Since these numbers are so close to '1' we can use simple linear + * interpolation between the two end values 256/257 (result -368.61) and 258/257 + * (result 367.179). The values used below are scaled by a further 64 to give + * 16-bit precision in the interpolation: + * + * Start (256): -23591 + * Zero (257): 0 + * End (258): 23499 + */ +PNG_STATIC png_int_32 +png_log16bit(png_uint_32 x) +{ + unsigned int lg2 = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) + return 0xffffffff; + + if ((x & 0xff00) == 0) + lg2 = 8, x <<= 8; + + if ((x & 0xf000) == 0) + lg2 += 4, x <<= 4; + + if ((x & 0xc000) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x8000) == 0) + lg2 += 1, x <<= 1; + + /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional + * value. + */ + lg2 <<= 28; + lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; + + /* Now we need to interpolate the factor, this requires a division by the top + * 8 bits. Do this with maximum precision. + */ + x = ((x << 16) + (x >> 9)) / (x >> 8); + + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly + * 16 bits to interpolate to get the low bits of the result. Round the + * answer. Note that the end point values are scaled by 64 to retain overall + * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust + * the overall scaling by 6-12. Round at every step. + */ + x -= 1U << 24; + + if (x <= 65536U) /* <= '257' */ + lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); + + else + lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); + + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((lg2 + 2048) >> 12); +} + +/* The 'exp()' case must invert the above, taking a 20-bit fixed point + * logarithmic value and returning a 16 or 8-bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * + * The worst case is the 16-bit distinction between 65535 and 65534, this + * requires perhaps spurious accuracy in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * + * To deal with this the following exp() function works out the exponent of the + * frational part of the logarithm by using an accurate 32-bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +static png_uint_32 +png_32bit_exp[16] = +{ +# ifdef PNG_DO_BC + for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } +# else + /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, + 2553802834U, 2445529972U, 2341847524U, 2242560872U +# endif +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#ifdef PNG_DO_BC +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 + 9 45303.31936980687359311872 + 8 45364.65110595323018870784 + 7 45395.35850361789624614912 + 6 45410.72259715102037508096 + 5 45418.40724413220722311168 + 4 45422.25021786898173001728 + 3 45424.17186732298419044352 + 2 45425.13273269940811464704 + 1 45425.61317555035558641664 + 0 45425.85339951654943850496 +#endif + +PNG_STATIC png_uint_32 +png_exp(png_fixed_point x) +{ + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ + { + /* Obtain a 4-bit approximation */ + png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; + + /* Incorporate the low 12 bits - these decrease the returned value by + * multiplying by a number less than 1 if the bit is set. The multiplier + * is determined by the above table and the shift. Notice that the values + * converge on 45426 and this is used to allow linear interpolation of the + * low bits. + */ + if (x & 0x800) + e -= (((e >> 16) * 44938U) + 16U) >> 5; + + if (x & 0x400) + e -= (((e >> 16) * 45181U) + 32U) >> 6; + + if (x & 0x200) + e -= (((e >> 16) * 45303U) + 64U) >> 7; + + if (x & 0x100) + e -= (((e >> 16) * 45365U) + 128U) >> 8; + + if (x & 0x080) + e -= (((e >> 16) * 45395U) + 256U) >> 9; + + if (x & 0x040) + e -= (((e >> 16) * 45410U) + 512U) >> 10; + + /* And handle the low 6 bits in a single block. */ + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; + + /* Handle the upper bits of x. */ + e >>= x >> 16; + return e; + } + + /* Check for overflow */ + if (x <= 0) + return png_32bit_exp[0]; + + /* Else underflow */ + return 0; +} + +PNG_STATIC png_byte +png_exp8bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ + x -= x >> 8; + return (png_byte)((x + 0x7fffffU) >> 24); +} + +PNG_STATIC png_uint_16 +png_exp16bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ + x -= x >> 16; + return (png_uint_16)((x + 32767U) >> 16); +} +#endif /* FLOATING_ARITHMETIC */ + +png_byte +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 255) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); + return (png_byte)r; +# else + png_int_32 lg2 = png_log8bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) + return png_exp8bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_byte)value; +} + +png_uint_16 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 65535) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); + return (png_uint_16)r; +# else + png_int_32 lg2 = png_log16bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) + return png_exp16bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_uint_16)value; +} + +/* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8-bit or 16-bit. While the result + * is nominally a 16-bit value if bit depth is 8 then the result is + * 8-bit (as are the arguments.) + */ +png_uint_16 /* PRIVATE */ +png_gamma_correct(png_structp png_ptr, unsigned int value, + png_fixed_point gamma_val) +{ + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma_val); + + else + return png_gamma_16bit_correct(value, gamma_val); +} + +/* This is the shared test on whether a gamma value is 'significant' - whether + * it is worth doing gamma correction. + */ +int /* PRIVATE */ +png_gamma_significant(png_fixed_point gamma_val) +{ + return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || + gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; +} + +/* Internal function to build a single 16-bit table - the table consists of + * 'num' 256-entry subtables, where 'num' is determined by 'shift' - the amount + * to shift the input values right (or 16-number_of_signifiant_bits). + * + * The caller is responsible for ensuring that the table gets cleaned up on + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument + * should be somewhere that will be cleaned. + */ +static void +png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) +{ + /* Various values derived from 'shift': */ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int i; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = + (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); + + /* The 'threshold' test is repeated here because it can arise for one of + * the 16-bit tables even if the others don't hit it. + */ + if (png_gamma_significant(gamma_val)) + { + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an + * arithmetic error. This code follows the spec exactly; ig is + * the recovered input sample, it always has 8-16 bits. + * + * We want input * 65535/max, rounded, the arithmetic fits in 32 + * bits (unsigned) so long as max <= 32767. + */ + unsigned int j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ + double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); + sub_table[j] = (png_uint_16)d; +# else + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); +# endif + } + } + else + { + /* We must still build a table, but do it the fast way. */ + unsigned int j; + + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = (png_uint_16)ig; + } + } + } +} + +/* NOTE: this function expects the *inverse* of the overall gamma transformation + * required. + */ +static void +png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) +{ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + unsigned int i; + png_uint_32 last; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + /* 'num' is the number of tables and also the number of low bits of the + * input 16-bit value used to select a table. Each table is itself indexed + * by the high 8 bits of the value. + */ + for (i = 0; i < num; i++) + table[i] = (png_uint_16p)png_malloc(png_ptr, + 256 * png_sizeof(png_uint_16)); + + /* 'gamma_val' is set to the reciprocal of the value calculated above, so + * pow(out,g) is an *input* value. 'last' is the last input value set. + * + * In the loop 'i' is used to find output values. Since the output is + * 8-bit there are only 256 possible values. The tables are set up to + * select the closest possible output value for each input by finding + * the input value at the boundary between each pair of output values + * and filling the table up to that boundary with the lower output + * value. + * + * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit + * values the code below uses a 16-bit value in i; the values start at + * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last + * entries are filled with 255). Start i at 128 and fill all 'last' + * table entries <= 'max' + */ + last = 0; + for (i = 0; i < 255; ++i) /* 8-bit output value */ + { + /* Find the corresponding maximum input value */ + png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ + + /* Find the boundary value in 16 bits: */ + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); + + /* Adjust (round) to (16-shift) bits: */ + bound = (bound * max + 32768U)/65535U + 1U; + + while (last < bound) + { + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; + } + } + + /* And fill in the final entries. */ + while (last < (num << 8)) + { + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; + last++; + } +} + +/* Build a single 8-bit table: same as the 16-bit case but much simpler (and + * typically much faster). Note that libpng currently does no sBIT processing + * (apparently contrary to the spec) so a 256-entry table is always generated. + */ +static void +png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, + PNG_CONST png_fixed_point gamma_val) +{ + unsigned int i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + + if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) + table[i] = png_gamma_8bit_correct(i, gamma_val); + + else for (i=0; i<256; ++i) + table[i] = (png_byte)i; +} + +/* Used from png_read_destroy and below to release the memory used by the gamma + * tables. + */ +void /* PRIVATE */ +png_destroy_gamma_table(png_structp png_ptr) +{ + png_free(png_ptr, png_ptr->gamma_table); + png_ptr->gamma_table = NULL; + + 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); + png_ptr->gamma_16_table = NULL; + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_from_1); + png_ptr->gamma_from_1 = NULL; + png_free(png_ptr, png_ptr->gamma_to_1); + png_ptr->gamma_to_1 = NULL; + + 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); + png_ptr->gamma_16_from_1 = NULL; + } + 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); + png_ptr->gamma_16_to_1 = NULL; + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +} + +/* 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, int bit_depth) +{ + png_debug(1, "in png_build_gamma_table"); + + /* Remove any existing table; this copes with multiple calls to + * png_read_update_info. The warning is because building the gamma tables + * multiple times is a performance hit - it's harmless but the ability to call + * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible + * to warn if the app introduces such a hit. + */ + if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) + { + png_warning(png_ptr, "gamma table being rebuilt"); + png_destroy_gamma_table(png_ptr); + } + + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, + png_reciprocal(png_ptr->gamma)); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } + else + { + png_byte shift, sig_bit; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = png_ptr->sig_bit.red; + + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + sig_bit = png_ptr->sig_bit.gray; + + /* 16-bit gamma code uses this equation: + * + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] + * + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * + * Thus the gamma table consists of up to 256 256-entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits of + * the color value then indexed by the upper 8 bits: + * + * table[low bits][high 8 bits] + * + * So the table 'n' corresponds to all those 'iv' of: + * + * ..<(n+1 << gamma_shift)-1> + * + */ + if (sig_bit > 0 && sig_bit < 16U) + shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ + + else + shift = 0; /* keep all 16 bits */ + + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } + + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ + + png_ptr->gamma_shift = shift; + +#ifdef PNG_16BIT_SUPPORTED + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now + * PNG_COMPOSE). This effectively smashed the background calculation for + * 16-bit output because the 8-bit table assumes the result will be reduced + * to 8 bits. + */ + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) +#endif + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#ifdef PNG_16BIT_SUPPORTED + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->gamma)); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. + * TODO: fix this. + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } +} +#endif /* READ_GAMMA */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/png.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/png.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/png.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/png.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2671 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.5.12 - July 11, 2012 + * Copyright (c) 1998-2012 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 code is released under the libpng license (See LICENSE, below) + * + * 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.5.12 - July 11, 2012: 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 12.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 12.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 12.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 12.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-7 13 10210 12.so.0.10[.0] + * 1.2.10rc1-2 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.4.0beta1-5 14 10400 14.so.0.0[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.4.0beta7-8 14 10400 14.so.0.0[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.4.0beta9-14 14 10400 14.so.0.0[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.4.0beta15-36 14 10400 14.so.0.0[.0] + * 1.4.0beta37-87 14 10400 14.so.14.0[.0] + * 1.4.0rc01 14 10400 14.so.14.0[.0] + * 1.4.0beta88-109 14 10400 14.so.14.0[.0] + * 1.4.0rc02-08 14 10400 14.so.14.0[.0] + * 1.4.0 14 10400 14.so.14.0[.0] + * 1.4.1beta01-03 14 10401 14.so.14.1[.0] + * 1.4.1rc01 14 10401 14.so.14.1[.0] + * 1.4.1beta04-12 14 10401 14.so.14.1[.0] + * 1.4.1 14 10401 14.so.14.1[.0] + * 1.4.2 14 10402 14.so.14.2[.0] + * 1.4.3 14 10403 14.so.14.3[.0] + * 1.4.4 14 10404 14.so.14.4[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] + * 1.5.1beta01-11 15 10501 15.so.15.1[.0] + * 1.5.1rc01-02 15 10501 15.so.15.1[.0] + * 1.5.1 15 10501 15.so.15.1[.0] + * 1.5.2beta01-03 15 10502 15.so.15.2[.0] + * 1.5.2rc01-03 15 10502 15.so.15.2[.0] + * 1.5.2 15 10502 15.so.15.2[.0] + * 1.5.3beta01-10 15 10503 15.so.15.3[.0] + * 1.5.3rc01-02 15 10503 15.so.15.3[.0] + * 1.5.3beta11 15 10503 15.so.15.3[.0] + * 1.5.3 [omitted] + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] + * 1.5.5beta01-08 15 10505 15.so.15.5[.0] + * 1.5.5rc01 15 10505 15.so.15.5[.0] + * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-07 15 10506 15.so.15.6[.0] + * 1.5.6rc01-03 15 10506 15.so.15.6[.0] + * 1.5.6 15 10506 15.so.15.6[.0] + * 1.5.7beta01-05 15 10507 15.so.15.7[.0] + * 1.5.7rc01-03 15 10507 15.so.15.7[.0] + * 1.5.7 15 10507 15.so.15.7[.0] + * 1.5.8beta01 15 10508 15.so.15.8[.0] + * 1.5.8rc01 15 10508 15.so.15.8[.0] + * 1.5.8 15 10508 15.so.15.8[.0] + * 1.5.9beta01-02 15 10509 15.so.15.9[.0] + * 1.5.9rc01 15 10509 15.so.15.9[.0] + * 1.5.9 15 10509 15.so.15.9[.0] + * 1.5.10beta01-05 15 10510 15.so.15.10[.0] + * 1.5.10 15 10510 15.so.15.10[.0] + * 1.5.11beta01 15 10511 15.so.15.11[.0] + * 1.5.11rc01-05 15 10511 15.so.15.11[.0] + * 1.5.11 15 10511 15.so.15.11[.0] + * 1.5.12 15 10512 15.so.15.12[.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 "rcNN". + * + * 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-manual.txt or libpng.3 for more information. The PNG + * specification is available as a W3C Recommendation and as an ISO + * Specification, +# endif + + /* Need the time information for converting tIME chunks, it + * defines struct tm: + */ +# ifdef PNG_CONVERT_tIME_SUPPORTED + /* "time.h" functions are not supported on all operating systems */ +# include +# endif +# endif + +/* Machine specific configuration. */ +# include "pngconf.h" +#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. + */ + +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# ifdef 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 */ + +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#define png_libpng_ver png_get_header_ver(NULL) + +/* This file is arranged in several sections: + * + * 1. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ +/* Section 1: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 2: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char* png_libpng_version_1_5_12; + +/* 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_CONST png_color FAR * png_const_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_CONST png_color_16 FAR * png_const_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_CONST png_color_8 FAR * png_const_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_CONST png_sPLT_entry FAR * png_const_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_CONST png_sPLT_t FAR * png_const_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" fields can be a + * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain + * the "text" field as a regular zero-terminated C string (possibly + * empty), never a NULL pointer, so it can be safely used in printf() and + * other string-handling functions. Note that the "itxt_length", "lang", and + * "lang_key" members of the structure only exist when the library is built + * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by + * default without iTXt support. Also note that when iTXt *is* supported, + * the "lang" and "lang_key" fields contain NULL pointers when the + * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or + * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the + * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" + * which is always 0 or 1, or its "compression method" which is always 0. + */ +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 */ + 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 */ +} png_text; +typedef png_text FAR * png_textp; +typedef PNG_CONST png_text FAR * png_const_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_CONST png_time FAR * png_const_timep; +typedef png_time FAR * FAR * png_timepp; + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ + defined(PNG_HANDLE_AS_UNKNOWN_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_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; +#endif + +/* Values for the unknown chunk location byte */ + +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* The complete definition of png_info has, as of libpng-1.5.0, + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_info_def png_info; +typedef png_info FAR * png_infop; +typedef PNG_CONST png_info FAR * png_const_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)) + +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 +#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) +#define PNG_FP_MIN (-PNG_FP_MAX) + +/* 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_ 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 0x8000 /* 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_size_t 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; + +/* The complete definition of png_struct has, as of libpng-1.5.0, + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_struct_def png_struct; +typedef PNG_CONST png_struct FAR * png_const_structp; +typedef png_struct FAR * png_structp; + +/* 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. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, + png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in , and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); +#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 */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read 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 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +typedef png_struct FAR * FAR * png_structpp; + +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.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. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, (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). + */ +PNG_EXPORT(3, int, png_sig_cmp, (png_const_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). + */ +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_const_structp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, + png_size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, 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), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, 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), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), + PNG_ALLOCATED); + +PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structp png_ptr, png_infop info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structp png_ptr, png_infop info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED +PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, + (png_structp png_ptr, + png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + PNG_CONST struct tm FAR * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, + (png_timep ptime, time_t ttime)); +#endif /* PNG_CONVERT_tIME_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, + int error_action, double red, double green)); +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)); + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp + png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels of + * a PNG file are returned when an alpha channel, or tRNS chunk in a palette + * file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel. The gamma encoded color channels must be + * scaled according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. The + * advantage is that the color channels can be resampled (the image can be + * scaled) in this form. The disadvantage is that normal practice is to store + * linear, not (gamma) encoded, values and this requires 16-bit channels for + * still images rather than the 8-bit channels that are just about sufficient if + * gamma encoding is used. In addition all non-transparent pixel values, + * including completely opaque ones, must be gamma encoded to produce the final + * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the + * latter being the two common names for associated alpha color channels.) + * + * Since it is not necessary to perform arithmetic on opaque color values so + * long as they are not to be resampled and are in the final color space it is + * possible to optimize the handling of alpha by storing the opaque pixels in + * the PNG format (adjusted for the output color space) while storing partially + * opaque pixels in the standard, linear, format. The accuracy required for + * standard alpha composition is relatively low, because the pixels are + * isolated, therefore typically the accuracy loss in storing 8-bit linear + * values is acceptable. (This is not true if the alpha channel is used to + * simulate transparency over large areas - use 16 bits or the PNG mode in + * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is + * treated as opaque only if the alpha value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode, + double output_gamma)); +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr, + int mode, png_fixed_point output_gamma)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. The values used + * correspond to the normal numbers used to describe the overall gamma of a + * computer display system; for example 2.2 for an sRGB conformant system. The + * values are scaled by 100000 in the _fixed version of the API (so 220000 for + * sRGB.) + * + * The inverse of the value is always used to provide a default for the PNG file + * encoding if it has no gAMA chunk and if png_set_gamma() has not been called + * to override the PNG gamma information. + * + * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode + * opaque pixels however pixels with lower alpha values are not encoded, + * regardless of the output gamma setting. + * + * When the standard Porter Duff handling is requested with mode 1 the output + * encoding is set to be linear and the output_gamma value is only relevant + * as a default for input data that has no gamma information. The linear output + * encoding will be overridden if png_set_gamma() is called - the results may be + * highly unexpected! + * + * The following numbers are derived from the sRGB standard and the research + * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of + * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing + * correction required to take account of any differences in the color + * environment of the original scene and the intended display environment; the + * value expresses how to *decode* the image for display, not how the original + * data was *encoded*. + * + * sRGB provides a peg for the PNG standard by defining a viewing environment. + * sRGB itself, and earlier TV standards, actually use a more complex transform + * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is + * limited to simple power laws.) By saying that an image for direct display on + * an sRGB conformant system should be stored with a gAMA chunk value of 45455 + * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification + * makes it possible to derive values for other display systems and + * environments. + * + * The Mac value is deduced from the sRGB based on an assumption that the actual + * extra viewing correction used in early Mac display systems was implemented as + * a power 1.45 lookup table. + * + * Any system where a programmable lookup table is used or where the behavior of + * the final display device characteristics can be changed requires system + * specific code to obtain the current characteristic. However this can be + * difficult and most PNG gamma correction only requires an approximate value. + * + * By default, if png_set_alpha_mode() is not called, libpng assumes that all + * values are unencoded, linear, values and that the output device also has a + * linear characteristic. This is only very rarely correct - it is invariably + * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the + * default if you don't know what the right answer is! + * + * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS + * 10.6) which used a correction table to implement a somewhat lower gamma on an + * otherwise sRGB system. + * + * Both these values are reserved (not simple gamma values) in order to allow + * more precise correction internally in the future. + * + * NOTE: the following values can be passed to either the fixed or floating + * point APIs, but the floating point API will also accept floating point + * values. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceeded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, (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. */ +PNG_EXPORT(39, void, png_set_filler, (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. */ +PNG_EXPORT(40, void, png_set_add_alpha, + (png_structp png_ptr, png_uint_32 filler, + int flags)); +#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. */ +PNG_EXPORT(41, void, png_set_swap, (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. */ +PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_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. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)); +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# 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 + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, + (png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, + (png_structp png_ptr, double screen_gamma, + double override_file_gamma)); +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)); +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, + png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, + (png_structp png_ptr, png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, + (png_structp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, + (png_structp png_ptr, int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() 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. + */ +PNG_EXPORT(67, void, png_set_filter, + (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 + +#ifdef 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. + */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)); +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_fixed_point_p + filter_weights, png_const_fixed_point_p filter_costs)); +#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 */ + +#ifdef PNG_WRITE_SUPPORTED +/* 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. + */ +PNG_EXPORT(69, void, png_set_compression_level, + (png_structp png_ptr, int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, + int method)); +#endif + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, + (png_structp png_ptr, int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp + png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr, + int method)); +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ + +/* 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-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, (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. + */ + +PNG_EXPORT(75, void, png_set_error_fn, + (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 */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_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). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, (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. */ +PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (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). */ +PNG_EXPORT(82, void, png_set_mem_fn, (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 */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, (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 */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_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. + */ +PNG_EXPORT(90, void, 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)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, + (png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PNG_READ_INTERLACING_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +PNG_EXPORTA(94, png_voidp, png_malloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, + (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +PNG_EXPORT(99, void, png_data_freer, + (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); + +/* 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 +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, + (png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, + png_const_charp warning_message)); +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +# undef png_benign_error +PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); + +/* Same, chunk name is prepended to message. */ +# undef png_chunk_benign_error +PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ 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_ 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. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, + (png_const_structp png_ptr, png_const_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, + (png_const_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, + (png_const_structp png_ptr, png_infop info_ptr, + png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr, + png_const_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_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_structp png_ptr, + png_const_infop info_ptr, double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, double *blue_X, + double *blue_Y, double *blue_Z)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structp png_ptr, + png_const_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 +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, 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_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_structp png_ptr, + png_infop info_ptr, double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, double blue_X, + double blue_Y, double blue_Z)); +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (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)); +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, + (png_const_structp png_ptr, png_const_infop info_ptr, + double *file_gamma)); +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_file_gamma)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, + png_infop info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, 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_method, int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, 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_method, int compression_method, int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, + (png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, + (png_const_structp png_ptr, png_const_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 + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, + png_infop info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, + (png_structp png_ptr, png_infop info_ptr, + png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, + (png_const_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, + (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr, + png_const_infop info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, + (png_structp png_ptr, png_infop info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, + png_infop info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_charpp name, int *compression_type, png_bytepp profile, + png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, + (png_structp png_ptr, png_infop info_ptr, + png_const_charp name, int compression_type, png_const_bytep profile, + png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, png_uint_32, png_get_sPLT, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, + (png_structp png_ptr, png_infop info_ptr, + png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, png_uint_32, png_get_text, + (png_const_structp png_ptr, png_const_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. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, + (png_structp png_ptr, png_infop info_ptr, + png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, + (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, + (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, + (png_const_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, + (png_structp png_ptr, png_infop info_ptr, + png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, + (png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, double *width, double *height)); +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_structp png_ptr, png_const_infop info_ptr, int *unit, + png_fixed_point *width, + png_fixed_point *height)); +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, + (png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height)); +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, + png_infop info_ptr, int unit, png_fixed_point width, + png_fixed_point height)); +PNG_EXPORT(171, void, png_set_sCAL_s, + (png_structp png_ptr, png_infop info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight)); +#endif /* PNG_sCAL_SUPPORTED */ + +#ifdef PNG_HANDLE_AS_UNKNOWN_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. Because this turns off the default handling for chunks + that would otherwise be recognized the behavior of libpng transformations may + well become incorrect! + keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior + = 1: PNG_HANDLE_CHUNK_NEVER: do not keep + = 2: PNG_HANDLE_CHUNK_IF_SAFE: keep only if safe-to-copy + = 3: PNG_HANDLE_CHUNK_ALWAYS: keep even if unsafe-to-copy +*/ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, + (png_structp png_ptr, int keep, + png_const_bytep chunk_list, int num_chunks)); + +/* The handling code is returned; the result is therefore true (non-zero) if + * special handling is required, false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, + png_const_bytep chunk_name)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, + png_infop info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr, + png_const_infop info_ptr, png_unknown_chunkpp entries)); +#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); + */ +PNG_EXPORT(177, void, png_set_invalid, + (png_structp png_ptr, png_infop info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); +PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (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 + +/* 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 +PNG_EXPORT(185, void, png_set_strip_error_numbers, + (png_structp png_ptr, + png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structp png_ptr, png_const_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_structp png_ptr, png_const_infop info_ptr)); +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr, + png_const_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_structp png_ptr, png_const_infop info_ptr)); +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr, + png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); + +PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name, + (png_structp png_ptr), PNG_DEPRECATED); +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ + (((yIn)<>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#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)) + 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)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (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)) + \ + 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)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535) +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, + png_const_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). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif + +/* 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. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define png_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define png_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define png_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) +#endif + +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +PNG_EXPORT(234, void, png_set_check_for_invalid_index, (png_structp png_ptr, + int allowed)); +#endif + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) Maintainer, remember to add an entry to + * scripts/symbols.def as well. + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(234); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngconf.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngconf.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngconf.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngconf.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,596 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.5.12 - July 11, 2012 + * + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +/* 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 + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C + * definition file for machine specific limits, this may impact the + * correctness of the definitions below (see uses of INT_MAX). + */ +# ifndef PNG_NO_LIMITS_H +# include +# endif + +/* For the memory copy APIs (i.e. the standard definitions of these), + * because this file defines png_memcpy and so on the base APIs must + * be defined here. + */ +# ifdef BSD +# include +# else +# include +# endif + +/* For png_FILE_p - this provides the standard definition of a + * FILE + */ +# ifdef PNG_STDIO_SUPPORTED +# include +# endif +#endif + +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used when the function is called. + * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG 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) () +# else +# define PNGARG(arglist) arglist +# endif /* _NO_PROTO */ + +# endif /* OF */ + +#endif /* PNGARG */ + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows/x86 systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ + ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ + defined(_M_X64) || defined(_M_IA64) ) + /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes + * builds under Cygwin or MinGW. Also includes Watcom builds but these need + * special treatment because they are not compatible with GCC or Visual C + * because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) + ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows/x86 */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA + +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ + extern attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. + */ +# if defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# endif /* __GNUC__ */ + +# if defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# endif /* _MSC_VER */ +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +/* 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. + * + * This should not change how the APIs are called, so it can be done + * on a per-file basis in the application. + */ +#ifndef PNG_CONST +# ifndef PNG_NO_CONST +# define PNG_CONST const +# else +# define PNG_CONST +# 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. + */ + +#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL) +typedef unsigned int png_uint_32; +typedef int png_int_32; +#else +typedef unsigned long png_uint_32; +typedef long png_int_32; +#endif +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +#ifdef PNG_NO_SIZE_T +typedef unsigned int png_size_t; +#else +typedef size_t png_size_t; +#endif +#define png_sizeof(x) (sizeof (x)) + +/* The following is needed for medium model support. It cannot be in the + * pngpriv.h header. 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 /* only used in build */ +# 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 */ +#ifdef FAR +# ifdef M_I86MM +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# 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., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef PNG_CONST void FAR * png_const_voidp; +typedef png_byte FAR * png_bytep; +typedef PNG_CONST png_byte FAR * png_const_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef PNG_CONST png_int_32 FAR * png_const_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST png_int_16 FAR * png_const_int_16p; +typedef char FAR * png_charp; +typedef PNG_CONST char FAR * png_const_charp; +typedef png_fixed_point FAR * png_fixed_point_p; +typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; +typedef png_size_t FAR * png_size_tp; +typedef PNG_CONST png_size_t FAR * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +typedef PNG_CONST double FAR * png_const_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; + +/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, + * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 + * to png_alloc_size_t are not necessary; in fact, it is recommended + * not to use them at all so that the compiler can complain when something + * turns out to be problematic. + * Casts in the other direction (from png_alloc_size_t to png_size_t or + * png_uint_32) should be explicitly applied; however, we do not expect + * to encounter practical situations that require such conversions. + */ +#if defined(__TURBOC__) && !defined(__FLAT__) + typedef unsigned long png_alloc_size_t; +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + typedef unsigned long png_alloc_size_t; +# else + /* This is an attempt to detect an old Windows system where (int) is + * actually 16 bits, in that case png_malloc must have an argument with a + * bigger size to accomodate the requirements of the library. + */ +# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \ + (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL) + typedef DWORD png_alloc_size_t; +# else + typedef png_size_t png_alloc_size_t; +# endif +# endif +#endif + +#endif /* PNGCONF_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngdebug.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngdebug.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngdebug.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngdebug.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,157 @@ + +/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c + * + * Copyright (c) 1998-2011 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.) + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* 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. + * + * png_debug[1-2]?(level, message ,arg{0-2}) + * Expands to a statement (either a simple expression or a compound + * do..while(0) statement) that outputs a message with parameter + * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG + * is undefined, 0 or 1 every png_debug expands to a simple expression + * (actually ((void)0)). + * + * level: level of detail of message, starting at 0. A level 'n' + * message is preceded by 'n' tab characters (not implemented + * on Microsoft compilers unless PNG_DEBUG_FILE is also + * defined, to allow debug DLL compilation with no standard IO). + * message: a printf(3) style text string. A trailing '\n' is added + * to the message. + * arg: 0 to 2 arguments for printf(3) style substitution in message. + */ +#ifndef PNGDEBUG_H +#define PNGDEBUG_H +/* These settings control the formatting of messages in png.c and pngerror.c */ +/* Moved to pngdebug.h at 1.5.0 */ +# ifndef PNG_LITERAL_SHARP +# define PNG_LITERAL_SHARP 0x23 +# endif +# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET +# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b +# endif +# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET +# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d +# endif +# ifndef PNG_STRING_NEWLINE +# define PNG_STRING_NEWLINE "\n" +# endif + +#ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +# include +# if (PNG_DEBUG > 1) +# ifndef _DEBUG +# define _DEBUG +# endif +# ifndef png_debug +# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) +# endif +# endif +# else /* PNG_DEBUG_FILE || !_MSC_VER */ +# ifndef PNG_STDIO_SUPPORTED +# include /* not included yet */ +# endif +# ifndef PNG_DEBUG_FILE +# define PNG_DEBUG_FILE stderr +# endif /* PNG_DEBUG_FILE */ + +# if (PNG_DEBUG > 1) +/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on + * non-ISO compilers + */ +# ifdef __STDC__ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ + } while (0) +# endif +# else /* __STDC __ */ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1,p2); \ + } while (0) +# endif +# endif /* __STDC __ */ +# endif /* (PNG_DEBUG > 1) */ + +# endif /* _MSC_VER */ +# endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +# define png_debug(l, m) ((void)0) +#endif +#ifndef png_debug1 +# define png_debug1(l, m, p1) ((void)0) +#endif +#ifndef png_debug2 +# define png_debug2(l, m, p1, p2) ((void)0) +#endif +#endif /* PNGDEBUG_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngerror.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngerror.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngerror.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngerror.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,685 @@ + +/* pngerror.c - stub functions for i/o and memory allocation + * + * Last changed in libpng 1.5.8 [February 1, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, + png_const_charp error_message)),PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +static void /* PRIVATE */ +png_default_warning PNGARG((png_structp png_ptr, + png_const_charp warning_message)); +#endif /* PNG_WARNINGS_SUPPORTED */ + +/* 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. + */ +#ifdef PNG_ERROR_TEXT_SUPPORTED +PNG_FUNCTION(void,PNGAPI +png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) +{ +#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 == PNG_LITERAL_SHARP) + { + /* Strip "#nnnn " from beginning of 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 - 1] = '\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 +PNG_FUNCTION(void,PNGAPI +png_err,(png_structp png_ptr),PNG_NORETURN) +{ + /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed + * erroneously as '\0', instead of the empty string "". This was + * apparently an error, introduced in libpng-1.2.20, and png_default_error + * will crash in this case. + */ + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_ptr, ""); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, ""); +} +#endif /* PNG_ERROR_TEXT_SUPPORTED */ + +/* Utility to safely appends strings to a buffer. This never errors out so + * error checking is not required in the caller. + */ +size_t +png_safecat(png_charp buffer, size_t bufsize, size_t pos, + png_const_charp string) +{ + if (buffer != NULL && pos < bufsize) + { + if (string != NULL) + while (*string != '\0' && pos < bufsize-1) + buffer[pos++] = *string++; + + buffer[pos] = '\0'; + } + + return pos; +} + +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. + */ +png_charp +png_format_number(png_const_charp start, png_charp end, int format, + png_alloc_size_t number) +{ + int count = 0; /* number of digits output */ + int mincount = 1; /* minimum number required */ + int output = 0; /* digit output (for the fixed point format) */ + + *--end = '\0'; + + /* This is written so that the loop always runs at least once, even with + * number zero. + */ + while (end > start && (number != 0 || count < mincount)) + { + + static const char digits[] = "0123456789ABCDEF"; + + switch (format) + { + case PNG_NUMBER_FORMAT_fixed: + /* Needs five digits (the fraction) */ + mincount = 5; + if (output || number % 10 != 0) + { + *--end = digits[number % 10]; + output = 1; + } + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02u: + /* Expects at least 2 digits. */ + mincount = 2; + /* fall through */ + + case PNG_NUMBER_FORMAT_u: + *--end = digits[number % 10]; + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02x: + /* This format expects at least two digits */ + mincount = 2; + /* fall through */ + + case PNG_NUMBER_FORMAT_x: + *--end = digits[number & 0xf]; + number >>= 4; + break; + + default: /* an error */ + number = 0; + break; + } + + /* Keep track of the number of digits added */ + ++count; + + /* Float a fixed number here: */ + if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start) + { + /* End of the fraction, but maybe nothing was output? In that case + * drop the decimal point. If the number is a true zero handle that + * here. + */ + if (output) + *--end = '.'; + else if (number == 0) /* and !output */ + *--end = '0'; + } + } + + return end; +} +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* 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 == PNG_LITERAL_SHARP) + { + 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); +} + +/* These functions support 'formatted' warning messages with up to + * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter + * is introduced by @, where 'number' starts at 1. This follows the + * standard established by X/Open for internationalizable error messages. + */ +void +png_warning_parameter(png_warning_parameters p, int number, + png_const_charp string) +{ + if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) + (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); +} + +void +png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, + png_alloc_size_t value) +{ + char buffer[PNG_NUMBER_BUFFER_SIZE]; + png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); +} + +void +png_warning_parameter_signed(png_warning_parameters p, int number, int format, + png_int_32 value) +{ + png_alloc_size_t u; + png_charp str; + char buffer[PNG_NUMBER_BUFFER_SIZE]; + + /* Avoid overflow by doing the negate in a png_alloc_size_t: */ + u = (png_alloc_size_t)value; + if (value < 0) + u = ~u + 1; + + str = PNG_FORMAT_NUMBER(buffer, format, u); + + if (value < 0 && str > buffer) + *--str = '-'; + + png_warning_parameter(p, number, str); +} + +void +png_formatted_warning(png_structp png_ptr, png_warning_parameters p, + png_const_charp message) +{ + /* The internal buffer is just 192 bytes - enough for all our messages, + * overflow doesn't happen because this code checks! If someone figures + * out how to send us a message longer than 192 bytes, all that will + * happen is that the message will be truncated appropriately. + */ + size_t i = 0; /* Index in the msg[] buffer: */ + char msg[192]; + + /* Each iteration through the following loop writes at most one character + * to msg[i++] then returns here to validate that there is still space for + * the trailing '\0'. It may (in the case of a parameter) read more than + * one character from message[]; it must check for '\0' and continue to the + * test if it finds the end of string. + */ + while (i<(sizeof msg)-1 && *message != '\0') + { + /* '@' at end of string is now just printed (previously it was skipped); + * it is an error in the calling code to terminate the string with @. + */ + if (p != NULL && *message == '@' && message[1] != '\0') + { + int parameter_char = *++message; /* Consume the '@' */ + static const char valid_parameters[] = "123456789"; + int parameter = 0; + + /* Search for the parameter digit, the index in the string is the + * parameter to use. + */ + while (valid_parameters[parameter] != parameter_char && + valid_parameters[parameter] != '\0') + ++parameter; + + /* If the parameter digit is out of range it will just get printed. */ + if (parameter < PNG_WARNING_PARAMETER_COUNT) + { + /* Append this parameter */ + png_const_charp parm = p[parameter]; + png_const_charp pend = p[parameter] + (sizeof p[parameter]); + + /* No need to copy the trailing '\0' here, but there is no guarantee + * that parm[] has been initialized, so there is no guarantee of a + * trailing '\0': + */ + while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) + msg[i++] = *parm++; + + /* Consume the parameter digit too: */ + ++message; + continue; + } + + /* else not a parameter and there is a character after the @ sign; just + * copy that. This is known not to be '\0' because of the test above. + */ + } + + /* At this point *message can't be '\0', even in the bad parameter case + * above where there is a lone '@' at the end of the message string. + */ + msg[i++] = *message++; + } + + /* i is always less than (sizeof msg), so: */ + msg[i] = '\0'; + + /* And this is the formatted message, it may be larger than + * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are + * not (currently) formatted. + */ + png_warning(png_ptr, msg); +} +#endif /* PNG_WARNINGS_SUPPORTED */ + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_benign_error(png_structp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); +} +#endif + +/* 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' +}; + +#define PNG_MAX_ERROR_TEXT 64 +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) +static void /* PRIVATE */ +png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp + error_message) +{ + png_uint_32 chunk_name = png_ptr->chunk_name; + int iout = 0, ishift = 24; + + while (ishift >= 0) + { + int c = (int)(chunk_name >> ishift) & 0xff; + + ishift -= 8; + if (isnonalpha(c)) + { + buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; + buffer[iout++] = png_digit[(c & 0xf0) >> 4]; + buffer[iout++] = png_digit[c & 0x0f]; + buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; + } + + else + { + buffer[iout++] = (char)c; + } + } + + if (error_message == NULL) + buffer[iout] = '\0'; + + else + { + int iin = 0; + + buffer[iout++] = ':'; + buffer[iout++] = ' '; + + while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') + buffer[iout++] = error_message[iin++]; + + /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ + buffer[iout] = '\0'; + } +} +#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_FUNCTION(void,PNGAPI +png_chunk_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + 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 && PNG_ERROR_TEXT_SUPPORTED */ + +#ifdef PNG_WARNINGS_SUPPORTED +void PNGAPI +png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + 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_WARNINGS_SUPPORTED */ + +#ifdef PNG_READ_SUPPORTED +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + png_chunk_warning(png_ptr, error_message); + + else + png_chunk_error(png_ptr, error_message); +} +#endif +#endif /* PNG_READ_SUPPORTED */ + +#ifdef PNG_ERROR_TEXT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_FUNCTION(void, +png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) +{ +# define fixed_message "fixed point overflow in " +# define fixed_message_ln ((sizeof fixed_message)-1) + int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; + png_memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; + if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) + { + msg[fixed_message_ln + iin] = name[iin]; + ++iin; + } + msg[fixed_message_ln + iin] = 0; + png_error(png_ptr, msg); +} +#endif +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This API only exists if ANSI-C style error handling is used, + * otherwise it is necessary for png_default_error to be overridden. + */ +jmp_buf* PNGAPI +png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, + size_t jmp_buf_size) +{ + if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf)) + return NULL; + + png_ptr->longjmp_fn = longjmp_fn; + return &png_ptr->longjmp_buffer; +} +#endif + +/* 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 PNG_FUNCTION(void /* PRIVATE */, +png_default_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + /* Check on NULL only added in 1.5.4 */ + if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) + { + /* Strip "#nnnn " from beginning of 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", + error_number, error_message + offset + 1); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng error: %s, offset=%d", + error_message, offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } + } + else +#endif + { + fprintf(stderr, "libpng error: %s", error_message ? error_message : + "undefined"); + fprintf(stderr, PNG_STRING_NEWLINE); + } +#else + PNG_UNUSED(error_message) /* Make compiler happy */ +#endif + png_longjmp(png_ptr, 1); +} + +PNG_FUNCTION(void,PNGAPI +png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) +{ +#ifdef PNG_SETJMP_SUPPORTED + if (png_ptr && png_ptr->longjmp_fn) + { +# ifdef USE_FAR_KEYWORD + { + jmp_buf tmp_jmpbuf; + png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); + png_ptr->longjmp_fn(tmp_jmpbuf, val); + } + +# else + png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val); +# endif + } +#endif + /* Here if not setjmp support or if png_ptr is null. */ + PNG_ABORT(); +} + +#ifdef PNG_WARNINGS_SUPPORTED +/* 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) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED +# ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (*warning_message == PNG_LITERAL_SHARP) + { + 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", + warning_number, warning_message + offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng warning: %s", + warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } + } + else +# endif + + { + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } +#else + PNG_UNUSED(warning_message) /* Make compiler happy */ +#endif + PNG_UNUSED(png_ptr) /* Make compiler happy */ +} +#endif /* PNG_WARNINGS_SUPPORTED */ + +/* 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->longjmp_buffer, 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; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#else + PNG_UNUSED(warning_fn) +#endif +} + + +/* 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_const_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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngget.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngget.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngget.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngget.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1124 @@ + +/* pngget.c - retrieval of values from info struct + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +png_uint_32 PNGAPI +png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 flag) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->valid & flag); + + return(0); +} + +png_size_t PNGAPI +png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->rowbytes); + + return(0); +} + +#ifdef PNG_INFO_IMAGE_SUPPORTED +png_bytepp PNGAPI +png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->row_pointers); + + 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_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->height; + + return (0); +} + +png_byte PNGAPI +png_get_bit_depth(png_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_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_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", + "png_get_x_pixels_per_meter"); + + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->x_pixels_per_unit); + } +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", + "png_get_y_pixels_per_meter"); + + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->y_pixels_per_unit); + } +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", "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 (info_ptr->x_pixels_per_unit); + } +#endif + + return (0); +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); + + if (info_ptr->x_pixels_per_unit != 0) + return ((float)((float)info_ptr->y_pixels_per_unit + /(float)info_ptr->x_pixels_per_unit)); + } +#endif + + return ((float)0.0); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr, + png_const_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) + && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 + && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX + && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) + { + png_fixed_point res; + + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); + + /* The following casts work because a PNG 4 byte integer only has a valid + * range of 0..2^31-1; otherwise the cast might overflow. + */ + if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, + (png_int_32)info_ptr->x_pixels_per_unit)) + return res; + } +#endif + + return 0; +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->x_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->y_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->x_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->y_offset); + } +#endif + + return (0); +} + +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED +static png_uint_32 +ppi_from_ppm(png_uint_32 ppm) +{ +#if 0 + /* The conversion is *(2.54/100), in binary (32 digits): + * .00000110100000001001110101001001 + */ + png_uint_32 t1001, t1101; + ppm >>= 1; /* .1 */ + t1001 = ppm + (ppm >> 3); /* .1001 */ + t1101 = t1001 + (ppm >> 1); /* .1101 */ + ppm >>= 20; /* .000000000000000000001 */ + t1101 += t1101 >> 15; /* .1101000000000001101 */ + t1001 >>= 11; /* .000000000001001 */ + t1001 += t1001 >> 12; /* .000000000001001000000001001 */ + ppm += t1001; /* .000000000001001000001001001 */ + ppm += t1101; /* .110100000001001110101001001 */ + return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ +#else + /* The argument is a PNG unsigned integer, so it is not permitted + * to be bigger than 2^31. + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, + 5000)) + return result; + + /* Overflow. */ + return 0; +#endif +} + +png_uint_32 PNGAPI +png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); +} + +#ifdef PNG_FIXED_POINT_SUPPORTED +static png_fixed_point +png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) +{ + /* Convert from metres * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. + * Notice that this can overflow - a warning is output and 0 is + * returned. + */ + return png_muldiv_warn(png_ptr, microns, 500, 127); +} + +png_fixed_point PNGAPI +png_get_x_offset_inches_fixed(png_structp png_ptr, + png_const_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_y_offset_inches_fixed(png_structp png_ptr, + png_const_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs_dpi(png_const_structp png_ptr, png_const_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", "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_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_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); + + return (0); +} + +png_const_bytep PNGAPI +png_get_signature(png_const_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + + return (NULL); +} + +#ifdef PNG_bKGD_SUPPORTED +png_uint_32 PNGAPI +png_get_bKGD(png_const_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", "bKGD"); + + *background = &(info_ptr->background); + return (PNG_INFO_bKGD); + } + + return (0); +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the + * same time to correct the rgb grayscale coefficient defaults obtained from the + * cHRM chunk in 1.5.4 + */ +png_uint_32 PNGFAPI +png_get_cHRM_XYZ_fixed(png_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_xy xy; + png_XYZ XYZ; + + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + + xy.whitex = info_ptr->x_white; + xy.whitey = info_ptr->y_white; + xy.redx = info_ptr->x_red; + xy.redy = info_ptr->y_red; + xy.greenx = info_ptr->x_green; + xy.greeny = info_ptr->y_green; + xy.bluex = info_ptr->x_blue; + xy.bluey = info_ptr->y_blue; + + /* The *_checked function handles error reporting, so just return 0 if + * there is a failure here. + */ + if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) + { + if (int_red_X != NULL) + *int_red_X = XYZ.redX; + if (int_red_Y != NULL) + *int_red_Y = XYZ.redY; + if (int_red_Z != NULL) + *int_red_Z = XYZ.redZ; + if (int_green_X != NULL) + *int_green_X = XYZ.greenX; + if (int_green_Y != NULL) + *int_green_Y = XYZ.greenY; + if (int_green_Z != NULL) + *int_green_Z = XYZ.greenZ; + if (int_blue_X != NULL) + *int_blue_X = XYZ.blueX; + if (int_blue_Y != NULL) + *int_blue_Y = XYZ.blueY; + if (int_blue_Z != NULL) + *int_blue_Z = XYZ.blueZ; + + return (PNG_INFO_cHRM); + } + } + + return (0); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_const_structp png_ptr, png_const_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", "cHRM"); + + if (white_x != NULL) + *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); + if (white_y != NULL) + *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); + if (red_x != NULL) + *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); + if (red_y != NULL) + *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); + if (green_x != NULL) + *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); + if (green_y != NULL) + *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); + if (blue_x != NULL) + *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); + if (blue_y != NULL) + *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); + return (PNG_INFO_cHRM); + } + + return (0); +} + +png_uint_32 PNGAPI +png_get_cHRM_XYZ(png_structp png_ptr, png_const_infop info_ptr, + double *red_X, double *red_Y, double *red_Z, double *green_X, + double *green_Y, double *green_Z, double *blue_X, double *blue_Y, + double *blue_Z) +{ + png_XYZ XYZ; + + if (png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, + &XYZ.redX, &XYZ.redY, &XYZ.redZ, &XYZ.greenX, &XYZ.greenY, &XYZ.greenZ, + &XYZ.blueX, &XYZ.blueY, &XYZ.blueZ) & PNG_INFO_cHRM) + { + if (red_X != NULL) + *red_X = png_float(png_ptr, XYZ.redX, "cHRM red X"); + if (red_Y != NULL) + *red_Y = png_float(png_ptr, XYZ.redY, "cHRM red Y"); + if (red_Z != NULL) + *red_Z = png_float(png_ptr, XYZ.redZ, "cHRM red Z"); + if (green_X != NULL) + *green_X = png_float(png_ptr, XYZ.greenX, "cHRM green X"); + if (green_Y != NULL) + *green_Y = png_float(png_ptr, XYZ.greenY, "cHRM green Y"); + if (green_Z != NULL) + *green_Z = png_float(png_ptr, XYZ.greenZ, "cHRM green Z"); + if (blue_X != NULL) + *blue_X = png_float(png_ptr, XYZ.blueX, "cHRM blue X"); + if (blue_Y != NULL) + *blue_Y = png_float(png_ptr, XYZ.blueY, "cHRM blue Y"); + if (blue_Z != NULL) + *blue_Z = png_float(png_ptr, XYZ.blueZ, "cHRM blue Z"); + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_const_structp png_ptr, png_const_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 retrieval function", "cHRM"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + if (white_x != NULL) + *white_x = info_ptr->x_white; + if (white_y != NULL) + *white_y = info_ptr->y_white; + if (red_x != NULL) + *red_x = info_ptr->x_red; + if (red_y != NULL) + *red_y = info_ptr->y_red; + if (green_x != NULL) + *green_x = info_ptr->x_green; + if (green_y != NULL) + *green_y = info_ptr->y_green; + if (blue_x != NULL) + *blue_x = info_ptr->x_blue; + if (blue_y != NULL) + *blue_y = info_ptr->y_blue; + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif +#endif + +#ifdef PNG_gAMA_SUPPORTED +png_uint_32 PNGFAPI +png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && file_gamma != NULL) + { + *file_gamma = info_ptr->gamma; + return (PNG_INFO_gAMA); + } + + return (0); +} +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, + double *file_gamma) +{ + png_fixed_point igamma; + png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); + + if (ok) + *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); + + return ok; +} + +# endif +#endif + +#ifdef PNG_sRGB_SUPPORTED +png_uint_32 PNGAPI +png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, + int *file_srgb_intent) +{ + png_debug1(1, "in %s retrieval function", "sRGB"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) + && file_srgb_intent != NULL) + { + *file_srgb_intent = (int)info_ptr->srgb_intent; + return (PNG_INFO_sRGB); + } + + return (0); +} +#endif + +#ifdef PNG_iCCP_SUPPORTED +png_uint_32 PNGAPI +png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr, + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen) +{ + png_debug1(1, "in %s retrieval function", "iCCP"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) + && name != NULL && compression_type != NULL && profile != NULL && + proflen != NULL) + { + *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 = info_ptr->iccp_proflen; + *compression_type = info_ptr->iccp_compression; + return (PNG_INFO_iCCP); + } + + return (0); +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +png_uint_32 PNGAPI +png_get_sPLT(png_const_structp png_ptr, png_const_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 + +#ifdef PNG_hIST_SUPPORTED +png_uint_32 PNGAPI +png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_16p *hist) +{ + png_debug1(1, "in %s retrieval function", "hIST"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) + && hist != NULL) + { + *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) + +{ + png_debug1(1, "in %s retrieval function", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL || width == NULL || + height == NULL || bit_depth == NULL || color_type == NULL) + return (0); + + *width = info_ptr->width; + *height = info_ptr->height; + *bit_depth = info_ptr->bit_depth; + *color_type = info_ptr->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; + + /* This is redundant if we can be sure that the info_ptr values were all + * assigned in png_set_IHDR(). We do the check anyhow in case an + * application has ignored our advice not to mess with the members + * of info_ptr directly. + */ + png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + + return (1); +} + +#ifdef PNG_oFFs_SUPPORTED +png_uint_32 PNGAPI +png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) +{ + png_debug1(1, "in %s retrieval function", "oFFs"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) + && offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + *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 + +#ifdef PNG_pCAL_SUPPORTED +png_uint_32 PNGAPI +png_get_pCAL(png_const_structp png_ptr, png_const_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_debug1(1, "in %s retrieval function", "pCAL"); + + 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) + { + *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 + +#ifdef PNG_sCAL_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + /*TODO: make this work without FP support */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); + return (PNG_INFO_sCAL); + } + + return(0); +} +# endif /* FLOATING_ARITHMETIC */ +# endif /* FIXED_POINT */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_const_structp png_ptr, png_const_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 = atof(info_ptr->scal_s_width); + *height = atof(info_ptr->scal_s_height); + return (PNG_INFO_sCAL); + } + + return(0); +} +# endif /* FLOATING POINT */ +png_uint_32 PNGAPI +png_get_sCAL_s(png_const_structp png_ptr, png_const_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 /* sCAL */ + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_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 /* pHYs */ + +png_uint_32 PNGAPI +png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, + png_colorp *palette, int *num_palette) +{ + png_debug1(1, "in %s retrieval function", "PLTE"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) + && palette != NULL) + { + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; + png_debug1(3, "num_palette = %d", *num_palette); + return (PNG_INFO_PLTE); + } + + return (0); +} + +#ifdef PNG_sBIT_SUPPORTED +png_uint_32 PNGAPI +png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit) +{ + png_debug1(1, "in %s retrieval function", "sBIT"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) + && sig_bit != NULL) + { + *sig_bit = &(info_ptr->sig_bit); + return (PNG_INFO_sBIT); + } + + return (0); +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +png_uint_32 PNGAPI +png_get_text(png_const_structp png_ptr, png_const_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 0x%lx retrieval function", + (unsigned long)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 + +#ifdef PNG_tIME_SUPPORTED +png_uint_32 PNGAPI +png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time) +{ + png_debug1(1, "in %s retrieval function", "tIME"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) + && mod_time != NULL) + { + *mod_time = &(info_ptr->mod_time); + return (PNG_INFO_tIME); + } + + return (0); +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +png_uint_32 PNGAPI +png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) +{ + 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", "tRNS"); + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (trans_alpha != NULL) + { + *trans_alpha = info_ptr->trans_alpha; + retval |= PNG_INFO_tRNS; + } + + if (trans_color != NULL) + *trans_color = &(info_ptr->trans_color); + } + + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ + { + if (trans_color != NULL) + { + *trans_color = &(info_ptr->trans_color); + retval |= PNG_INFO_tRNS; + } + + if (trans_alpha != NULL) + *trans_alpha = NULL; + } + + if (num_trans != NULL) + { + *num_trans = info_ptr->num_trans; + retval |= PNG_INFO_tRNS; + } + } + + return (retval); +} +#endif + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr, + png_unknown_chunkpp unknowns) +{ + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) + { + *unknowns = info_ptr->unknown_chunks; + return info_ptr->unknown_chunks_num; + } + + return (0); +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +png_byte PNGAPI +png_get_rgb_to_gray_status (png_const_structp png_ptr) +{ + return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); +} +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +png_voidp PNGAPI +png_get_user_chunk_ptr(png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); +} +#endif + +png_size_t PNGAPI +png_get_compression_buffer_size(png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->zbuf_size : 0); +} + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* These functions were added to libpng 1.2.6 and were enabled + * by default in libpng-1.4.0 */ +png_uint_32 PNGAPI +png_get_user_width_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_width_max : 0); +} + +png_uint_32 PNGAPI +png_get_user_height_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_height_max : 0); +} + +/* This function was added to libpng 1.4.0 */ +png_uint_32 PNGAPI +png_get_chunk_cache_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_cache_max : 0); +} + +/* This function was added to libpng 1.4.1 */ +png_alloc_size_t PNGAPI +png_get_chunk_malloc_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +/* These functions were added to libpng 1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +png_uint_32 PNGAPI +png_get_io_state (png_structp png_ptr) +{ + return png_ptr->io_state; +} + +png_uint_32 PNGAPI +png_get_io_chunk_type (png_const_structp png_ptr) +{ + return png_ptr->chunk_name; +} + +png_const_bytep PNGAPI +png_get_io_chunk_name (png_structp png_ptr) +{ + PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name); + return png_ptr->io_chunk_string; +} +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pnginfo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pnginfo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pnginfo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pnginfo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,269 @@ + +/* pnginfo.h - header file for PNG reference library + * + * Copyright (c) 1998-2011 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.) + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + + /* 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, using png_set_*() functions, 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 libpng-1.5.0 this was moved into a separate private + * file that is not visible to applications. + * + * 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. + */ +#ifndef PNGINFO_H +#define PNGINFO_H + +struct png_info_def +{ + /* 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_size_t 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) + /* 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. + */ + png_fixed_point gamma; +#endif + +#ifdef 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 + +#ifdef 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 or comments to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read or comments to write */ +#endif /* PNG_TEXT_SUPPORTED */ + +#ifdef 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 + +#ifdef 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_alpha; /* alpha values for paletted image */ + png_color_16 trans_color; /* 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 + +#ifdef 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 + +#ifdef 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 + +#ifdef 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. + */ + png_fixed_point x_white; + png_fixed_point y_white; + png_fixed_point x_red; + png_fixed_point y_red; + png_fixed_point x_green; + png_fixed_point y_green; + png_fixed_point x_blue; + png_fixed_point y_blue; +#endif + +#ifdef 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 */ + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + /* Storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + int unknown_chunks_num; +#endif + +#ifdef PNG_iCCP_SUPPORTED + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_bytep iccp_profile; /* International Color Consortium profile data */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#ifdef 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 + +#ifdef 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. Data values are valid if (valid & PNG_INFO_sCAL) is + * non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif + +#ifdef 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 + +}; +#endif /* PNGINFO_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pnglibconf.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pnglibconf.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pnglibconf.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pnglibconf.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,186 @@ + +/* libpng STANDARD API DEFINITION */ + +/* pnglibconf.h - library build configuration */ + +/* Libpng 1.5.12 - July 11, 2012 */ + +/* Copyright (c) 1998-2012 Glenn Randers-Pehrson */ + +/* This code is released under the libpng license. */ +/* For conditions of distribution and use, see the disclaimer */ +/* and license in png.h */ + +/* pnglibconf.h */ +/* Derived from: scripts/pnglibconf.dfa */ +/* If you edit this file by hand you must obey the rules expressed in */ +/* pnglibconf.dfa with respect to the dependencies between the following */ +/* symbols. It is much better to generate a new file using */ +/* scripts/libpngconf.mak */ + +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* settings */ +#define PNG_API_RULE 0 +#define PNG_CALLOC_SUPPORTED +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_sCAL_PRECISION 5 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +/* end of settings */ +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGN_MEMORY_SUPPORTED +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_cHRM_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONVERT_tIME_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ +#define PNG_ERROR_TEXT_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_MNG_FEATURES_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_MEM_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +#endif /* PNGLCONF_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngmem.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngmem.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngmem.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngmem.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,667 @@ + +/* pngmem.c - stub functions for memory allocation + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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. + */ + +#include "pngpriv.h" + +#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_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) +{ +# ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, NULL, NULL)); +} + +/* Alternate version of png_create_struct, for use with user-defined malloc. */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) +{ +# 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; + memset(&dummy_struct, 0, sizeof dummy_struct); + dummy_struct.mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(&dummy_struct, (png_alloc_size_t)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, NULL, 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; + memset(&dummy_struct, 0, sizeof dummy_struct); + dummy_struct.mem_ptr=mem_ptr; + (*(free_fn))(&dummy_struct, 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_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + ret = (png_malloc(png_ptr, size)); + + if (ret != NULL) + png_memset(ret,0,(png_size_t)size); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + 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, 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_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + 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, mem_level, window_bits; + png_byte huge * hptr; + int window_bits + + if (ret != NULL) + { + farfree(ret); + ret = NULL; + } + + window_bits = + png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ? + png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits; + + if (window_bits > 14) + num_blocks = (int)(1 << (window_bits - 14)); + + else + num_blocks = 1; + + mem_level = + png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ? + png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level; + + if (mem_level >= 7) + num_blocks += (int)(1 << (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", "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", "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 || 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_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) +{ +# ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, NULL, 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_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) +{ +# 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, NULL, 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_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + ret = (png_malloc(png_ptr, size)); + + if (ret != NULL) + png_memset(ret,0,(png_size_t)size); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + 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_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + 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 */ + +/* 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_FUNCTION(png_voidp,PNGAPI +png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + 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); +} + + +#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_const_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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngpread.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngpread.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngpread.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngpread.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1315 @@ + +/* pngpread.c - read a png file in push mode + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#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 || info_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); + } +} + +png_size_t PNGAPI +png_process_data_pause(png_structp png_ptr, int save) +{ + if (png_ptr != NULL) + { + /* It's easiest for the caller if we do the save, then the caller doesn't + * have to supply the same data again: + */ + if (save) + png_push_save_buffer(png_ptr); + else + { + /* This includes any pending saved bytes: */ + png_size_t remaining = png_ptr->buffer_size; + png_ptr->buffer_size = 0; + + /* So subtract the saved buffer size, unless all the data + * is actually 'saved', in which case we just return 0 + */ + if (png_ptr->save_buffer_size < remaining) + return remaining - png_ptr->save_buffer_size; + } + } + + return 0; +} + +png_uint_32 PNGAPI +png_process_data_skip(png_structp png_ptr) +{ + png_uint_32 remaining = 0; + + if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && + png_ptr->skip_length > 0) + { + /* At the end of png_process_data the buffer size must be 0 (see the loop + * above) so we can detect a broken call here: + */ + if (png_ptr->buffer_size != 0) + png_error(png_ptr, + "png_process_data_skip called inside png_process_data"); + + /* If is impossible for there to be a saved buffer at this point - + * otherwise we could not be in SKIP mode. This will also happen if + * png_process_skip is called inside png_process_data (but only very + * rarely.) + */ + if (png_ptr->save_buffer_size != 0) + png_error(png_ptr, "png_process_data_skip called with saved data"); + + remaining = png_ptr->skip_length; + png_ptr->skip_length = 0; + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + + return remaining; +} + +/* 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; + } + + 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) +{ + png_uint_32 chunk_name; + + /* 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]; + png_byte chunk_tag[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, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + + chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IDAT) + { + /* This is here above the if/else case statement below because if the + * unknown handling marks 'IDAT' as unknown then the IDAT handling case is + * completely skipped. + * + * TODO: there must be a better way of doing this. + */ + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + } + + if (chunk_name == png_IHDR) + { + if (png_ptr->push_length != 13) + png_error(png_ptr, "Invalid IHDR length"); + + 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 (chunk_name == png_IEND) + { + 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_chunk_unknown_handling(png_ptr, chunk_name)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (chunk_name == png_IDAT) + png_ptr->mode |= PNG_HAVE_IDAT; + + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + 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 (chunk_name == png_PLTE) + { + 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 (chunk_name == png_IDAT) + { + /* 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_benign_error(png_ptr, "Too many IDATs 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_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + png_ptr->zstream.next_out = png_ptr->row_buf; + return; + } + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (png_ptr->chunk_name == png_gAMA) + { + 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 +#ifdef PNG_READ_sBIT_SUPPORTED + else if (png_ptr->chunk_name == png_sBIT) + { + 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 +#ifdef PNG_READ_cHRM_SUPPORTED + else if (png_ptr->chunk_name == png_cHRM) + { + 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 +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + { + 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 +#ifdef PNG_READ_iCCP_SUPPORTED + else if (png_ptr->chunk_name == png_iCCP) + { + 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 +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + { + 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 +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + { + 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 +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + { + 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 +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + { + 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 +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + { + 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 +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + { + 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 + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + { + 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 +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + { + 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 +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + { + 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 +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_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_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 = png_ptr->save_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'save_buffer_size', but + * they are of different types and we don't know which variable has the + * fewest bits. Carefully select the smaller and cast it to the type of + * the larger - this cannot overflow. Do not cast in the following test + * - it will break on either 16 or 64 bit platforms. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; + + else + skip_length = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->skip_length -= skip_length; + 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 = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'current_buffer_size', here, + * the same problem exists as above and the same solution. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; + + else + skip_length = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->skip_length -= skip_length; + 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 PNGCBAPI +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_warn(png_ptr, new_max); + + if (png_ptr->save_buffer == NULL) + { + png_free(png_ptr, old_buffer); + png_error(png_ptr, "Insufficient memory for save_buffer"); + } + + 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) +{ + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + png_byte chunk_tag[4]; + + /* TODO: this code can be commoned up with the same code in push_read */ + 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, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + + if (png_ptr->chunk_name != png_IDAT) + { + 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 = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. Do not cast in the following test - it + * will break on either 16 or 64 bit platforms. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_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 = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_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) +{ + /* The caller checks for a non-zero buffer length. */ + if (!(buffer_length > 0) || buffer == NULL) + png_error(png_ptr, "No IDAT data (internal error)"); + + /* This routine must process all the data it has been given + * before returning, calling the row callback as required to + * handle the uncompressed results. + */ + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = (uInt)buffer_length; + + /* Keep going until the decompressed data is all processed + * or the stream marked as finished. + */ + while (png_ptr->zstream.avail_in > 0 && + !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { + int ret; + + /* We have data for zlib, but we must check that zlib + * has someplace to put the results. It doesn't matter + * if we don't expect any results -- it may be the input + * data is just the LZ end code. + */ + if (!(png_ptr->zstream.avail_out > 0)) + { + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + png_ptr->zstream.next_out = png_ptr->row_buf; + } + + /* Using Z_SYNC_FLUSH here means that an unterminated + * LZ stream (a stream with a missing end code) can still + * be handled, otherwise (Z_NO_FLUSH) a future zlib + * implementation might defer output and therefore + * change the current behavior (see comments in inflate.c + * for why this doesn't happen at present with zlib 1.2.5). + */ + ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); + + /* Check for any failure before proceeding. */ + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* Terminate the decompression. */ + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* This may be a truncated stream (missing or + * damaged end code). Treat that as a warning. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + png_warning(png_ptr, "Truncated compressed data in IDAT"); + + else + png_error(png_ptr, "Decompression error in IDAT"); + + /* Skip the check on unprocessed input */ + return; + } + + /* Did inflate output any data? */ + if (png_ptr->zstream.next_out != png_ptr->row_buf) + { + /* Is this unexpected data after the last row? + * If it is, artificially terminate the LZ output + * here. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + { + /* Extra data. */ + png_warning(png_ptr, "Extra compressed data in IDAT"); + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* Do no more processing; skip the unprocessed + * input check below. + */ + return; + } + + /* Do we have a complete row? */ + if (png_ptr->zstream.avail_out == 0) + png_push_process_row(png_ptr); + } + + /* And check for the end of the stream. */ + if (ret == Z_STREAM_END) + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + } + + /* All the data should have been processed, if anything + * is left at this point we have bytes of IDAT data + * after the zlib end code. + */ + if (png_ptr->zstream.avail_in > 0) + png_warning(png_ptr, "Extra compression data in IDAT"); +} + +void /* PRIVATE */ +png_push_process_row(png_structp png_ptr) +{ + /* 1.5.6: row_info moved out of png_struct to a local here. */ + png_row_info row_info; + + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced row count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "progressive row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal progressive row size calculation error"); + + +#ifdef 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) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + 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, 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, NULL); + png_read_push_finish_row(png_ptr); + } + } + + if (png_ptr->pass == 6 && png_ptr->height <= 4) + { + png_push_have_row(png_ptr, 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, 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, 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, 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, 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, NULL); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 6) /* Pass 5 might be empty */ + { + png_push_have_row(png_ptr, 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, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + default: + 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, 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_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte 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 + static PNG_CONST png_byte 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; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset(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]; + + 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); + } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ +} + +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); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void PNGAPI +png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, + png_const_bytep new_row) +{ + if (png_ptr == NULL) + return; + + /* new_row is a flag here - if it is NULL then the app callback was called + * from an empty row (see the calls to png_struct::row_fn below), otherwise + * it must be png_ptr->row_buf+1 + */ + if (new_row != NULL) + png_combine_row(png_ptr, old_row, 1/*display*/); +} +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +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_const_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return png_ptr->io_ptr; +} +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngpriv.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngpriv.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngpriv.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngpriv.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1675 @@ + +/* pngpriv.h - private declarations for use inside libpng + * + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2012 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.) + * + * Last changed in libpng 1.5.10 [March 29, 2012] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* The symbols declared in this file (including the functions declared + * as PNG_EXTERN) are PRIVATE. They are not part of the libpng public + * interface, and are not recommended for use by regular applications. + * Some of them may become public in the future; others may stay private, + * change in an incompatible way, or even disappear. + * Although the libpng users are not forbidden to include this header, + * they should be well aware of the issues that may arise from doing so. + */ + +#ifndef PNGPRIV_H +#define PNGPRIV_H + +/* Feature Test Macros. The following are defined here to ensure that correctly + * implemented libraries reveal the APIs libpng needs to build and hide those + * that are not needed and potentially damaging to the compilation. + * + * Feature Test Macros must be defined before any system header is included (see + * POSIX 1003.1 2.8.2 "POSIX Symbols." + * + * These macros only have an effect if the operating system supports either + * POSIX 1003.1 or C99, or both. On other operating systems (particularly + * Windows/Visual Studio) there is no effect; the OS specific tests below are + * still required (as of 2011-05-02.) + */ +#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ + +/* This is required for the definition of abort(), used as a last ditch + * error handler when all else fails. + */ +#include + +/* This is used to find 'offsetof', used below for alignment tests. */ +#include + +#define PNGLIB_BUILD /*libpng is being built, not used*/ + +#ifdef PNG_USER_CONFIG +# include "pngusr.h" + /* These should have been defined in pngusr.h */ +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD "Custom libpng build" +# endif +# ifndef PNG_USER_DLLFNAME_POSTFIX +# define PNG_USER_DLLFNAME_POSTFIX "Cb" +# endif +#endif + +/* Is this a build of a DLL where compilation of the object modules requires + * different preprocessor settings to those required for a simple library? If + * so PNG_BUILD_DLL must be set. + * + * If libpng is used inside a DLL but that DLL does not export the libpng APIs + * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a + * static library of libpng then link the DLL against that. + */ +#ifndef PNG_BUILD_DLL +# ifdef DLL_EXPORT + /* This is set by libtool when files are compiled for a DLL; libtool + * always compiles twice, even on systems where it isn't necessary. Set + * PNG_BUILD_DLL in case it is necessary: + */ +# define PNG_BUILD_DLL +# else +# ifdef _WINDLL + /* This is set by the Microsoft Visual Studio IDE in projects that + * build a DLL. It can't easily be removed from those projects (it + * isn't visible in the Visual Studio UI) so it is a fairly reliable + * indication that PNG_IMPEXP needs to be set to the DLL export + * attributes. + */ +# define PNG_BUILD_DLL +# else +# ifdef __DLL__ + /* This is set by the Borland C system when compiling for a DLL + * (as above.) + */ +# define PNG_BUILD_DLL +# else + /* Add additional compiler cases here. */ +# endif +# endif +# endif +#endif /* Setting PNG_BUILD_DLL if required */ + +/* See pngconf.h for more details: the builder of the library may set this on + * the command line to the right thing for the specific compilation system or it + * may be automagically set above (at present we know of no system where it does + * need to be set on the command line.) + * + * PNG_IMPEXP must be set here when building the library to prevent pngconf.h + * setting it to the "import" setting for a DLL build. + */ +#ifndef PNG_IMPEXP +# ifdef PNG_BUILD_DLL +# define PNG_IMPEXP PNG_DLL_EXPORT +# else + /* Not building a DLL, or the DLL doesn't require specific export + * definitions. + */ +# define PNG_IMPEXP +# endif +#endif + +/* No warnings for private or deprecated functions in the build: */ +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE +#endif + +#include "png.h" +#include "pnginfo.h" +#include "pngstruct.h" + +/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ +#ifndef PNG_DLL_EXPORT +# define PNG_DLL_EXPORT +#endif + +/* SECURITY and SAFETY: + * + * By default libpng is built without any internal limits on image size, + * individual heap (png_malloc) allocations or the total amount of memory used. + * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used + * (unless individually overridden). These limits are believed to be fairly + * safe, but builders of secure systems should verify the values against the + * real system capabilities. + */ + +#ifdef PNG_SAFE_LIMITS_SUPPORTED + /* 'safe' limits */ +# ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000 +# endif +# ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000 +# endif +# ifndef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 128 +# endif +# ifndef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 8000000 +# endif +#else + /* values for no limits */ +# ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 0x7fffffff +# endif +# ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 0x7fffffff +# endif +# ifndef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 0 +# endif +# ifndef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 0 +# endif +#endif + +/* This is used for 16 bit gamma tables - only the top level pointers are const, + * this could be changed: + */ +typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; + +/* Added at libpng-1.2.9 */ +/* Moved to pngpriv.h at libpng-1.5.0 */ + +/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" + * script. We may need it here to get the correct configuration on things + * like limits. + */ +#ifdef PNG_CONFIGURE_LIBPNG +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +#endif + +/* Moved to pngpriv.h at libpng-1.5.0 */ +/* NOTE: some of these may have been used in external applications as + * these definitions were exposed in pngconf.h prior to 1.5. + */ + +/* 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. + * + * zlib provides 'MAXSEG_64K' which, if defined, indicates the + * same limit and pngconf.h (already included) sets the limit + * if certain operating systems are detected. + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +#ifndef PNG_UNUSED +/* Unused formal parameter warnings are silenced using the following macro + * which is expected to have no bad effects on performance (optimizing + * compilers will probably remove it entirely). Note that if you replace + * it with something other than whitespace, you must include the terminating + * semicolon. + */ +# define PNG_UNUSED(param) (void)param; +#endif + +/* 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 + +/* PNG_STATIC is used to mark internal file scope functions if they need to be + * accessed for implementation tests (see the code in tests/?*). + */ +#ifndef PNG_STATIC +# define PNG_STATIC static +#endif + +/* C99 restrict is used where possible, to do this 'restrict' is defined as + * empty if we can't be sure it is supported. configure builds have already + * done this work. + */ +#ifdef PNG_CONFIGURE_LIBPNG +# define PNG_RESTRICT restrict +#else + /* Modern compilers support restrict, but assume not for anything not + * recognized here: + */ +# if defined __GNUC__ || defined _MSC_VER || defined __WATCOMC__ +# define PNG_RESTRICT restrict +# else +# define PNG_RESTRICT +# endif +#endif + +/* If warnings or errors are turned off the code is disabled or redirected here. + * From 1.5.4 functions have been added to allow very limited formatting of + * error and warning messages - this code will also be disabled here. + */ +#ifdef PNG_WARNINGS_SUPPORTED +# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +# define png_warning_parameter(p,number,string) ((void)0) +# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) +# define png_warning_parameter_signed(p,number,format,value) ((void)0) +# define png_formatted_warning(pp,p,message) ((void)(pp)) +# define PNG_WARNING_PARAMETERS(p) +#endif +#ifndef PNG_ERROR_TEXT_SUPPORTED +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +# define png_fixed_error(s1,s2) png_err(s1) +#endif + +/* C allows up-casts from (void*) to any pointer and (const void*) to any + * pointer to a const object. C++ regards this as a type error and requires an + * explicit, static, cast and provides the static_cast<> rune to ensure that + * const is not cast away. + */ +#ifdef __cplusplus +# define png_voidcast(type, value) static_cast(value) +#else +# define png_voidcast(type, value) (value) +#endif /* __cplusplus */ + +#ifndef PNG_EXTERN +/* The functions exported by PNG_EXTERN are 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 might be made available again. + * + * 1.5.7: turned the use of 'extern' back on, since it is localized to pngpriv.h + * it should be safe now (it is unclear why it was turned off.) + */ +# define PNG_EXTERN extern +#endif + +/* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic + * deals with this: + */ +#ifdef PNG_FIXED_POINT_SUPPORTED +# define PNGFAPI PNGAPI +#else +# define PNGFAPI /* PRIVATE */ +#endif + +/* 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) ||\ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + /* png.c requires the following ANSI-C constants if the conversion of + * floating point to ASCII is implemented therein: + * + * DBL_DIG Maximum number of decimal digits (can be set to any constant) + * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) + * DBL_MAX Maximum floating point number (can be set to an arbitrary value) + */ +# include + +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ + defined(_WIN32) || defined(__WIN32__) +# include /* defines _WINDOWS_ macro */ +#endif + +/* Moved here around 1.5.0beta36 from pngconf.h */ +/* Users may want to use these so they are not private. Any library + * functions that are passed far data must be model-independent. + */ + +/* Memory model/platform independent fns */ +#ifndef PNG_ABORT +# ifdef _WINDOWS_ +# define PNG_ABORT() ExitProcess(0) +# else +# define PNG_ABORT() abort() +# endif +#endif + +#ifdef USE_FAR_KEYWORD +/* 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_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else +# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strlen lstrlenA +# define png_memcmp memcmp +# define png_memcpy CopyMemory +# define png_memset memset +# else +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +# endif +#endif + +/* These macros may need to be architecture dependent. */ +#define PNG_ALIGN_NONE 0 /* do not use data alignment */ +#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ +#ifdef offsetof +# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ +#else +# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ +#endif +#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ + +#ifndef PNG_ALIGN_TYPE + /* Default to using aligned access optimizations and requiring alignment to a + * multiple of the data type size. Override in a compiler specific fashion + * if necessary by inserting tests here: + */ +# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE +#endif + +#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE + /* This is used because in some compiler implementations non-aligned + * structure members are supported, so the offsetof approach below fails. + * Set PNG_ALIGN_TO_SIZE=0 for compiler combinations where unaligned access + * is good for performance. Do not do this unless you have tested the result + * and understand it. + */ +# define png_alignof(type) (sizeof (type)) +#else +# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET +# define png_alignof(type) offsetof(struct{char c; type t;}, t) +# else +# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS +# define png_alignof(type) (1) +# endif + /* Else leave png_alignof undefined to prevent use thereof */ +# endif +#endif + +/* This implicitly assumes alignment is always to a power of 2. */ +#ifdef png_alignof +# define png_isaligned(ptr, type)\ + ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) +#else +# define png_isaligned(ptr, type) 0 +#endif + +/* End of memory model/platform independent support */ +/* End of 1.5.0beta36 move from pngconf.h */ + +/* CONSTANTS and UTILITY MACROS + * These are used internally by libpng and not exposed in the API + */ + +/* Various modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. Three of these + * are defined in png.h because they need to be visible to applications + * that call png_set_unknown_chunk(). + */ +/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */ +/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */ +#define PNG_HAVE_IDAT 0x04 +/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ +#define PNG_HAVE_IEND 0x10 +#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 */ +#define PNG_HAVE_iCCP 0x4000 + +/* 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_QUANTIZE 0x0040 +#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ +#define PNG_BACKGROUND_EXPAND 0x0100 +#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ +#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000 +#define PNG_PACKSWAP 0x10000 +#define PNG_SWAP_ALPHA 0x20000 +#define PNG_STRIP_ALPHA 0x40000 +#define PNG_INVERT_ALPHA 0x80000 +#define PNG_USER_TRANSFORM 0x100000 +#define PNG_RGB_TO_GRAY_ERR 0x200000 +#define PNG_RGB_TO_GRAY_WARN 0x400000 +#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ +#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ +#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ +#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ + /* 0x8000000 unused */ + /* 0x10000000 unused */ + /* 0x20000000 unused */ + /* 0x40000000 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_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#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_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000 + /* 0x200000 unused */ + /* 0x400000 unused */ +#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000 /* Added to libpng-1.4.0 */ +#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000 /* 5 lines added */ +#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000 /* to libpng-1.5.4 */ +#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000 +#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000 +#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000 + /* 0x20000000 unused */ + /* 0x40000000 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) + +/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib + * can handle at once. This type need be no larger than 16 bits (so maximum of + * 65535), this define allows us to discover how big it is, but limited by the + * maximuum for png_size_t. The value can be overriden in a library build + * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably + * lower value (e.g. 255 works). A lower value may help memory usage (slightly) + * and may even improve performance on some systems (and degrade it on others.) + */ +#ifndef ZLIB_IO_MAX +# define ZLIB_IO_MAX ((uInt)-1) +#endif + +/* 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 ? \ + ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ + (( ((png_size_t)(width) * ((png_size_t)(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) ) + +/* Conversions between fixed and floating point, only defined if + * required (to make sure the code doesn't accidentally use float + * when it is supposedly disabled.) + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* The floating point conversion can't overflow, though it can and + * does lose accuracy relative to the original fixed point value. + * In practice this doesn't matter because png_fixed_point only + * stores numbers with very low precision. The png_ptr and s + * arguments are unused by default but are there in case error + * checking becomes a requirement. + */ +#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) + +/* The fixed point conversion performs range checking and evaluates + * its argument multiple times, so must be used with care. The + * range checking uses the PNG specification values for a signed + * 32 bit fixed point value except that the values are deliberately + * rounded-to-zero to an integral value - 21474 (21474.83 is roughly + * (2^31-1) * 100000). 's' is a string that describes the value being + * converted. + * + * NOTE: this macro will raise a png_error if the range check fails, + * therefore it is normally only appropriate to use this on values + * that come from API calls or other sources where an out of range + * error indicates a programming error, not a data error! + * + * NOTE: by default this is off - the macro is not used - because the + * function call saves a lot of code. + */ +#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED +#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +#else +PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, + png_const_charp text)); +#endif +#endif + +/* Constants for known chunk types. If you need to add a chunk, define the name + * here. For historical reasons these constants have the form png_; i.e. + * the prefix is lower case. Please use decimal values as the parameters to + * match the ISO PNG specification and to avoid relying on the C locale + * interpretation of character values. + * + * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values + * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string + * to be generated if required. + * + * PNG_32b correctly produces a value shifted by up to 24 bits, even on + * architectures where (int) is only 16 bits. + */ +#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) +#define PNG_CHUNK(b1,b2,b3,b4) \ + (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) + +#define png_IHDR PNG_CHUNK( 73, 72, 68, 82) +#define png_IDAT PNG_CHUNK( 73, 68, 65, 84) +#define png_IEND PNG_CHUNK( 73, 69, 78, 68) +#define png_PLTE PNG_CHUNK( 80, 76, 84, 69) +#define png_bKGD PNG_CHUNK( 98, 75, 71, 68) +#define png_cHRM PNG_CHUNK( 99, 72, 82, 77) +#define png_gAMA PNG_CHUNK(103, 65, 77, 65) +#define png_hIST PNG_CHUNK(104, 73, 83, 84) +#define png_iCCP PNG_CHUNK(105, 67, 67, 80) +#define png_iTXt PNG_CHUNK(105, 84, 88, 116) +#define png_oFFs PNG_CHUNK(111, 70, 70, 115) +#define png_pCAL PNG_CHUNK(112, 67, 65, 76) +#define png_sCAL PNG_CHUNK(115, 67, 65, 76) +#define png_pHYs PNG_CHUNK(112, 72, 89, 115) +#define png_sBIT PNG_CHUNK(115, 66, 73, 84) +#define png_sPLT PNG_CHUNK(115, 80, 76, 84) +#define png_sRGB PNG_CHUNK(115, 82, 71, 66) +#define png_sTER PNG_CHUNK(115, 84, 69, 82) +#define png_tEXt PNG_CHUNK(116, 69, 88, 116) +#define png_tIME PNG_CHUNK(116, 73, 77, 69) +#define png_tRNS PNG_CHUNK(116, 82, 78, 83) +#define png_zTXt PNG_CHUNK(122, 84, 88, 116) + +/* The following will work on (signed char*) strings, whereas the get_uint_32 + * macro will fail on top-bit-set values because of the sign extension. + */ +#define PNG_CHUNK_FROM_STRING(s)\ + PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) + +/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is + * signed and the argument is a (char[]) This macro will fail miserably on + * systems where (char) is more than 8 bits. + */ +#define PNG_STRING_FROM_CHUNK(s,c)\ + (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ + ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) + +/* Do the same but terminate with a null character. */ +#define PNG_CSTRING_FROM_CHUNK(s,c)\ + (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) + +/* Test on flag values as defined in the spec (section 5.4): */ +#define PNG_CHUNK_ANCILLIARY(c) (1 & ((c) >> 29)) +#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLIARY(c)) +#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) +#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) +#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) + +/* Gamma values (new at libpng-1.5.4): */ +#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ +#define PNG_GAMMA_MAC_INVERSE 65909 +#define PNG_GAMMA_sRGB_INVERSE 45455 + + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* These 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. + */ + +/* Check the user version string for compatibility, returns false if the version + * numbers aren't compatible. + */ +PNG_EXTERN int png_user_version_check(png_structp png_ptr, + png_const_charp user_png_ver); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), + PNG_ALLOCATED); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, + PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), + PNG_ALLOCATED); +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)); + +/* Function to allocate memory for zlib. PNGAPI is disallowed. */ +PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, + uInt size)),PNG_ALLOCATED); + +/* Function to free memory for zlib. PNGAPI is disallowed. */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +/* Next four functions are used internally as callbacks. PNGCBAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 + */ + +PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED +PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); +# endif +#endif + +/* 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_const_bytep data, png_size_t length)); + +/* Read and check the PNG file signature */ +PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); + +/* Read the chunk header (length + type name) */ +PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); + +/* 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_READ_COMPRESSED_TEXT_SUPPORTED) +PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, 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_const_bytep ptr, png_size_t length)); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* 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_const_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)); + +#ifdef 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 + +#ifdef PNG_WRITE_sBIT_SUPPORTED +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, + png_const_color_8p sbit, int color_type)); +#endif + +#ifdef 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 +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 + +#ifdef PNG_WRITE_sRGB_SUPPORTED +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_const_charp name, int compression_type, + png_const_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_const_sPLT_tp palette)); +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, + int color_type)); +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_const_color_16p values, int color_type)); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, + png_const_uint_16p hist, int num_hist)); +#endif + +/* Chunks that have keywords */ +#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_const_charp key, png_charpp new_key)); +#endif + +#ifdef PNG_WRITE_tEXt_SUPPORTED +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len)); +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len, int compression)); +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_const_charp key, png_const_charp lang, + png_const_charp lang_key, png_const_charp text)); +#endif + +#ifdef 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_const_textp text_ptr, int num_text)); +#endif + +#ifdef 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 + +#ifdef 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_const_charp units, png_charpp params)); +#endif + +#ifdef 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 + +#ifdef PNG_WRITE_tIME_SUPPORTED +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_const_timep mod_time)); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_const_charp width, png_const_charp height)); +#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)); + +/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an + * array of png_ptr->width pixels. If the image is not interlaced or this + * is the final pass this just does a png_memcpy, otherwise the "display" flag + * is used to determine whether to copy pixels that are not in the current pass. + * + * Because 'png_do_read_interlace' (below) replicates pixels this allows this + * function to achieve the documented 'blocky' appearance during interlaced read + * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' + * are not changed if they are not in the current pass, when display is 0. + * + * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. + * + * The API always reads from the png_struct row buffer and always assumes that + * it is full width (png_do_read_interlace has already been called.) + * + * This function is only ever used to write to row buffers provided by the + * caller of the relevant libpng API and the row must have already been + * transformed by the read transformations. + * + * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed + * bitmasks for use within the code, otherwise runtime generated masks are used. + * The default is compile time masks. + */ +#ifndef PNG_USE_COMPILE_TIME_MASKS +# define PNG_USE_COMPILE_TIME_MASKS 1 +#endif +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int display)); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Expand an interlaced row: the 'row_info' describes the pass data that has + * been read in and must correspond to the pixels in 'row', the pixels are + * expanded (moved apart) in 'row' to match the final layout, when doing this + * the pixels are *replicated* to the intervening space. This is essential for + * the correct operation of png_combine_row, above. + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#ifdef 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: check the filter value before calling this, there is no point + * calling it for PNG_FILTER_VALUE_NONE. + */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp pp, png_row_infop row_info, + png_bytep row, png_const_bytep prev_row, int filter)); + +PNG_EXTERN void png_read_filter_row_up_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_sub3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_sub4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_avg3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_avg4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_paeth3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_paeth4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); + +/* 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)); + +/* 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)); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* These are the functions that do the transformations */ +#ifdef 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 + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef 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_channel PNGARG((png_row_infop row_info, + png_bytep row, int at_start)); +#endif + +#ifdef PNG_16BIT_SUPPORTED +#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 +#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 + +#ifdef 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 + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, + png_bytep row, png_const_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 + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep palette_lookup, + png_const_bytep quantize_lookup)); + +# ifdef 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 + +#ifdef 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 + +#ifdef PNG_WRITE_SHIFT_SUPPORTED +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) +PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_const_colorp palette, png_const_bytep trans, + int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_16p trans_color)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info, + png_bytep row)); +#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)); + +#ifdef PNG_READ_bKGD_SUPPORTED +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED +PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_iTXt_SUPPORTED +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED +PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_sRGB_SUPPORTED +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef 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_uint_32 chunk_name)); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk + * name, not a string. + */ +PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr, + png_uint_32 chunk_name)); +#endif + +/* Handle the transformations for reading and writing */ +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); +#endif +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); +#endif + +#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)); +# ifdef 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 +# ifdef 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 +# ifdef 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 + +/* Added at libpng version 1.4.0 */ +#ifdef PNG_CHECK_cHRM_SUPPORTED +PNG_EXTERN int png_check_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 + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 and 1.4.0 */ +/* Currently only used by png_check_cHRM_fixed */ +PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, + unsigned long *hi_product, unsigned long *lo_product)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +/* Added at libpng version 1.5.5 */ +typedef struct png_xy +{ + png_fixed_point redx, redy; + png_fixed_point greenx, greeny; + png_fixed_point bluex, bluey; + png_fixed_point whitex, whitey; +} png_xy; + +typedef struct png_XYZ +{ + png_fixed_point redX, redY, redZ; + png_fixed_point greenX, greenY, greenZ; + png_fixed_point blueX, blueY, blueZ; +} png_XYZ; + +/* The conversion APIs return 0 on success, non-zero on a parameter error. They + * allow conversion between the above representations of a color encoding. When + * converting from XYZ end points to chromaticities the absolute magnitude of + * the end points is lost, when converting back the sum of the Y values of the + * three end points will be 1.0 + */ +PNG_EXTERN int png_xy_from_XYZ PNGARG((png_xy *xy, png_XYZ XYZ)); +PNG_EXTERN int png_XYZ_from_xy PNGARG((png_XYZ *XYZ, png_xy xy)); +PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr, + png_XYZ *XYZ, png_xy xy)); +#endif + +/* Added at libpng version 1.4.0 */ +PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type)); + +/* Added at libpng version 1.5.10 */ +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +PNG_EXTERN void png_do_check_palette_indexes PNGARG((png_structp png_ptr, + png_row_infop row_info)); +#endif + +/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ +PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr, png_infop end_info_ptr)); + +/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); + +#ifdef USE_FAR_KEYWORD /* memory model conversion function */ +PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, + png_const_charp name),PNG_NORETURN); +#endif + +/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite + * the end. Always leaves the buffer nul terminated. Never errors out (and + * there is no error code.) + */ +PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, + png_const_charp string); + +/* Various internal functions to handle formatted warning messages, currently + * only implemented for warnings. + */ +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. This utility only + * does unsigned values. + */ +PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end, + int format, png_alloc_size_t number); + +/* Convenience macro that takes an array: */ +#define PNG_FORMAT_NUMBER(buffer,format,number) \ + png_format_number(buffer, buffer + (sizeof buffer), format, number) + +/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ +#define PNG_NUMBER_BUFFER_SIZE 24 + +/* These are the integer formats currently supported, the name is formed from + * the standard printf(3) format string. + */ +#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ +#define PNG_NUMBER_FORMAT_02u 2 +#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ +#define PNG_NUMBER_FORMAT_02d 2 +#define PNG_NUMBER_FORMAT_x 3 +#define PNG_NUMBER_FORMAT_02x 4 +#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* New defines and members adding in libpng-1.5.4 */ +# define PNG_WARNING_PARAMETER_SIZE 32 +# define PNG_WARNING_PARAMETER_COUNT 8 + +/* An l-value of this type has to be passed to the APIs below to cache the + * values of the parameters to a formatted warning message. + */ +typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ + PNG_WARNING_PARAMETER_SIZE]; + +PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number, + png_const_charp string); + /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, + * including the trailing '\0'. + */ +PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p, + int number, int format, png_alloc_size_t value); + /* Use png_alloc_size_t because it is an unsigned type as big as any we + * need to output. Use the following for a signed value. + */ +PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p, + int number, int format, png_int_32 value); + +PNG_EXTERN void png_formatted_warning(png_structp png_ptr, + png_warning_parameters p, png_const_charp message); + /* 'message' follows the X/Open approach of using @1, @2 to insert + * parameters previously supplied using the above functions. Errors in + * specifying the paramters will simple result in garbage substitutions. + */ +#endif + +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +#if defined(PNG_READ_sCAL_SUPPORTED) +/* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant + * digits - a build time settable option) and assumpitions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) + +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, + png_size_t size, double fp, unsigned int precision)); +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, + png_charp ascii, png_size_t size, png_fixed_point fp)); +#endif /* FIXED_POINT */ +#endif /* READ_sCAL */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* An internal API to validate the format of a floating point number. + * The result is the index of the next character. If the number is + * not valid it will be the index of a character in the supposed number. + * + * The format of a number is defined in the PNG extensions specification + * and this API is strictly conformant to that spec, not anyone elses! + * + * The format as a regular expression is: + * + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? + * + * or: + * + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? + * + * The complexity is that either integer or fraction must be present and the + * fraction is permitted to have no digits only if the integer is present. + * + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * + * PNG floating point numb1.ers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this + * doesn't matter for PNG sCAL chunk values, but it requires more care + * if the value were ever to be embedded in something more complex. Use + * ANSI-C strtod if you need the lookahead. + */ +/* State table for the parser. */ +#define PNG_FP_INTEGER 0 /* before or in integer */ +#define PNG_FP_FRACTION 1 /* before or in fraction */ +#define PNG_FP_EXPONENT 2 /* before or in exponent */ +#define PNG_FP_STATE 3 /* mask for the above */ +#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ +#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ +#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ +#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ +#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ + +/* These three values don't affect the parser. They are set but not used. + */ +#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ +#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ +#define PNG_FP_NONZERO 256 /* A non-zero value */ +#define PNG_FP_STICKY 448 /* The above three flags */ + +/* This is available for the caller to store in 'state' if required. Do not + * call the parser after setting it (the parser sometimes clears it.) + */ +#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ + +/* Result codes for the parser (boolean - true meants ok, false means + * not ok yet.) + */ +#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ +#define PNG_FP_OK 1 /* The number is valid */ + +/* Tests on the sticky non-zero and negative flags. To pass these checks + * the state must also indicate that the whole number is valid - this is + * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this + * is equivalent to PNG_FP_OK above.) + */ +#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) + /* NZ_MASK: the string is valid and a non-zero negative value */ +#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) + /* Z MASK: the string is valid and a non-zero value. */ + /* PNG_FP_SAW_DIGIT: the string is valid. */ +#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) +#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) +#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) + +/* The actual parser. This can be called repeatedly, it updates + * the index into the string and the state variable (which must + * be initialzed to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * + * Note that the pointer will consume an E or even an E+ then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling + * the parser again (from the start, with state 0) but with a string + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, + png_size_t size, int *statep, png_size_tp whereami)); + +/* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. As of 1.5.4 this + * function also returns the state at the end of parsing the number if + * it was valid (otherwise it returns 0.) This can be used for testing + * for negative or zero values using the sticky flag. + */ +PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, + png_size_t size)); +#endif /* pCAL || sCAL */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) +/* Added at libpng version 1.5.0 */ +/* This is a utility to provide a*times/div (rounded) and indicate + * if there is an overflow. The result is a boolean - false (0) + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, + png_int_32 multiplied_by, png_int_32 divided_by)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Same deal, but issue a warning on overflow and return 0. */ +PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, + png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Calculate a reciprocal - used for gamma values. This returns + * 0 if the argument is 0 in order to maintain an undefined value, + * there are no warnings. + */ +PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); + +/* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is + * not exact - use png_muldiv for that. + */ +PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, + png_fixed_point b)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Internal fixed point gamma correction. These APIs are called as + * required to convert single values - they don't need to be fast, + * they are not used when processing image pixel values. + * + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, + unsigned int value, png_fixed_point gamma_value)); +PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value)); +PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, + png_fixed_point gamma_value)); +PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, + png_fixed_point gamma_value)); +PNG_EXTERN void png_destroy_gamma_table(png_structp png_ptr); +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, + int bit_depth)); +#endif + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#include "pngdebug.h" + +#ifdef __cplusplus +} +#endif + +#endif /* PNGPRIV_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngread.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngread.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngread.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngread.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1305 @@ + +/* pngread.c - read a PNG file + * + * Last changed in libpng 1.5.10 [March 8, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that an application calls directly to + * read a PNG file or stream. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* Create a PNG structure for reading, and allocate any memory needed. */ +PNG_FUNCTION(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),PNG_ALLOCATED) +{ + +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL)); +} + +/* Alternate create PNG structure for reading, and allocate any memory + * needed. + */ +PNG_FUNCTION(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),PNG_ALLOCATED) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif + png_structp png_ptr; + volatile int png_cleanup_needed = 0; + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf tmp_jmpbuf; +#endif +#endif + + png_debug(1, "in png_create_read_struct"); + +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + malloc_fn, 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_USER_LIMITS_SUPPORTED + png_ptr->user_width_max = PNG_USER_WIDTH_MAX; + png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; + + /* Added at libpng-1.2.43 and 1.4.0 */ + png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; + + /* Added at libpng-1.2.43 and 1.4.1 */ + png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; +#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(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ +#endif + PNG_ABORT(); +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif +#endif /* PNG_SETJMP_SUPPORTED */ + +#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); + + /* Call the general version checker (shared with read and write code): */ + if (!png_user_version_check(png_ptr, user_png_ver)) + png_cleanup_needed = 1; + + if (!png_cleanup_needed) + { + /* Initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); + + if (png_ptr->zbuf == NULL) + png_cleanup_needed = 1; + } + + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + if (!png_cleanup_needed) + { + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: + break; /* Do nothing */ + + case Z_MEM_ERROR: + png_warning(png_ptr, "zlib memory error"); + png_cleanup_needed = 1; + break; + + case Z_STREAM_ERROR: + png_warning(png_ptr, "zlib stream error"); + png_cleanup_needed = 1; + break; + + case Z_VERSION_ERROR: + png_warning(png_ptr, "zlib version error"); + png_cleanup_needed = 1; + break; + + default: png_warning(png_ptr, "Unknown zlib error"); + png_cleanup_needed = 1; + } + } + + if (png_cleanup_needed) + { + /* Clean up PNG structure and deallocate any memory. */ + 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); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, NULL, NULL); + + + return (png_ptr); +} + + +#ifdef PNG_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) +{ + png_debug(1, "in png_read_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Read and check the PNG file signature. */ + png_read_sig(png_ptr, info_ptr); + + for (;;) + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ + if (chunk_name == png_IDAT) + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + + else if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) + { + if (chunk_name == png_IDAT) + png_ptr->mode |= PNG_HAVE_IDAT; + + png_handle_unknown(png_ptr, info_ptr, length); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + 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 (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + + else if (chunk_name == png_IDAT) + { + 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; + } + +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED + else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED + else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED + else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + + else + png_handle_unknown(png_ptr, info_ptr, length); + } +} +#endif /* PNG_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"); + + if (png_ptr == NULL) + return; + + png_read_start_row(png_ptr); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_read_transform_info(png_ptr, info_ptr); +#else + PNG_UNUSED(info_ptr) +#endif +} + +#ifdef PNG_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"); + + if (png_ptr != NULL) + png_read_start_row(png_ptr); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void PNGAPI +png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) +{ + int ret; + + png_row_info row_info; + + if (png_ptr == NULL) + return; + + png_debug2(1, "in png_read_row (row %lu, pass %d)", + (unsigned long)png_ptr->row_number, png_ptr->pass); + + /* png_read_start_row sets the information (in particular iwidth) for this + * interlace pass. + */ + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + + /* 1.5.6: row_info moved out of png_struct to a local here. */ + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + 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 + } + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* If interlaced and we do not need a new row, combine row and return. + * Notice that the pixels we have from previous rows have been transformed + * already; we can only combine like with like (transformed or + * untransformed) and, because of the libpng API for interlaced images, this + * means we must transform before de-interlacing. + */ + 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, 1/*display*/); + 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, 1/*display*/); + + 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, 1/*display*/); + + 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, 1/*display*/); + + 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, 1/*display*/); + + 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, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + default: + 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_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1); + + do + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_crc_finish(png_ptr, 0); + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + if (png_ptr->chunk_name != png_IDAT) + 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_benign_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); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef 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(&row_info, png_ptr->row_buf + 1); + } +#endif + + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "sequential row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal sequential row size calculation error"); + +#ifdef 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) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + if (row != NULL) + png_combine_row(png_ptr, row, 0/*row*/); + } + + else +#endif + { + if (row != NULL) + png_combine_row(png_ptr, row, -1/*ignored*/); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, -1/*ignored*/); + } + 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_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_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"); + + 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, NULL); + rp++; + } + + else if (dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep dptr = *dp; + png_read_row(png_ptr, NULL, dptr); + dp++; + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_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"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ + png_start_read_image(png_ptr); + } + else + { + if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; + } + + /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in + * the above error case. + */ + 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; + + for (j = 0; j < pass; j++) + { + rp = image; + for (i = 0; i < image_height; i++) + { + png_read_row(png_ptr, *rp, NULL); + rp++; + } + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_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_debug(1, "in png_read_end"); + + if (png_ptr == NULL) + return; + + png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Report invalid palette index; added at libng-1.5.10 */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Read palette index exceeding num_palette"); +#endif + + do + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + + else if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) + { + if (chunk_name == png_IDAT) + { + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_benign_error(png_ptr, "Too many IDATs found"); + } + png_handle_unknown(png_ptr, info_ptr, length); + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + + else if (chunk_name == png_IDAT) + { + /* 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_benign_error(png_ptr, "Too many IDATs found"); + + png_crc_finish(png_ptr, length); + } + else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED + else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED + else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED + else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + 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_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 = NULL; + png_voidp mem_ptr = NULL; +#endif + + png_debug(1, "in png_destroy_read_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + if (png_ptr == NULL) + return; + +#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 (end_info_ptr_ptr != NULL) + end_info_ptr = *end_info_ptr_ptr; + + png_read_destroy(png_ptr, info_ptr, end_info_ptr); + + if (info_ptr != NULL) + { +#ifdef 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) + { +#ifdef 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; +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; +#endif + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_read_destroy"); + + if (info_ptr != NULL) + png_info_destroy(png_ptr, info_ptr); + + if (end_info_ptr != NULL) + png_info_destroy(png_ptr, end_info_ptr); + +#ifdef PNG_READ_GAMMA_SUPPORTED + png_destroy_gamma_table(png_ptr); +#endif + + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + png_free(png_ptr, png_ptr->chunkdata); + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_free(png_ptr, png_ptr->palette_lookup); + png_free(png_ptr, png_ptr->quantize_index); +#endif + + if (png_ptr->free_me & PNG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->free_me &= ~PNG_FREE_PLTE; + +#if defined(PNG_tRNS_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->free_me & PNG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->free_me &= ~PNG_FREE_TRNS; +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + if (png_ptr->free_me & PNG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->free_me &= ~PNG_FREE_HIST; +#endif + + inflateEnd(&png_ptr->zstream); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + + /* 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->longjmp_buffer, png_sizeof(jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + warning_fn = png_ptr->warning_fn; +#endif + 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; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#endif + 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->longjmp_buffer, 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; +} + + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +#ifdef 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 || info_ptr == NULL) + return; + + /* 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 ------------------- */ + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + /* Tell libpng to strip 16-bit/color files down to 8 bits per color. + */ + if (transforms & PNG_TRANSFORM_SCALE_16) + { + /* Added at libpng-1.5.4. "strip_16" produces the same result that it + * did in earlier versions, while "scale_16" is now more accurate. + */ + png_set_scale_16(png_ptr); + } +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* If both SCALE and STRIP are required pngrtran will effectively cancel the + * latter by doing SCALE first. This is ok and allows apps not to check for + * which is supported to get the right answer. + */ + if (transforms & PNG_TRANSFORM_STRIP_16) + png_set_strip_16(png_ptr); +#endif + +#ifdef 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 + +#ifdef 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 + +#ifdef 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 quantizing. + */ + +#ifdef 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 + +#ifdef 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 + +#ifdef 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 + +#ifdef 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 + +#ifdef 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 + +/* Added at libpng-1.2.41 */ +#ifdef 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 + +/* Added at libpng-1.2.41 */ +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* Expand grayscale image to RGB */ + if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) + png_set_gray_to_rgb(png_ptr); +#endif + +/* Added at libpng-1.5.4 */ +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (transforms & PNG_TRANSFORM_EXPAND_16) + png_set_expand_16(png_ptr); +#endif + + /* We don't handle adding filler bytes */ + + /* We use png_read_image and rely on that for interlace handling, but we also + * call png_read_update_info therefore must turn on interlace handling now: + */ + (void)png_set_interlace_handling(png_ptr); + + /* 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 ------------------- */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + if (info_ptr->row_pointers == NULL) + { + png_uint_32 iptr; + + info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, + info_ptr->height * png_sizeof(png_bytep)); + for (iptr=0; iptrheight; iptr++) + info_ptr->row_pointers[iptr] = NULL; + + info_ptr->free_me |= PNG_FREE_ROWS; + + 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); + + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) + +} +#endif /* PNG_INFO_IMAGE_SUPPORTED */ +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrio.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrio.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrio.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrio.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,176 @@ + +/* pngrio.c - functions for data input + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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(...). + */ + +#include "pngpriv.h" + +#ifdef 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", (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"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* 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 PNGCBAPI +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. + */ + check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr); + + 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 PNGCBAPI +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t 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) + { + check = fread(n_data, 1, length, io_ptr); + } + + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + + do + { + read = MIN(NEAR_BUF_SIZE, remaining); + err = fread(buf, 1, read, io_ptr); + 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"). + * May be NULL, in which case libpng's default function will + * be used. + */ +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; + +#ifdef PNG_STDIO_SUPPORTED + 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, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; +#endif +} +#endif /* PNG_READ_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrtran.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrtran.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrtran.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrtran.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,5033 @@ + +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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. + */ + +#include "pngpriv.h" + +#ifdef 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"); + + if (png_ptr == NULL) + return; + + /* Tell libpng how we react to CRC errors in critical chunks */ + 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; + } + + /* Tell libpng how we react to CRC errors in ancillary chunks */ + 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; + } +} + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS via a background color */ +void PNGFAPI +png_set_background_fixed(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma) +{ + png_debug(1, "in png_set_background_fixed"); + + 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_COMPOSE | PNG_STRIP_ALPHA; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + png_memcpy(&(png_ptr->background), background_color, + png_sizeof(png_color_16)); + png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + if (need_expand) + png_ptr->transformations |= PNG_BACKGROUND_EXPAND; + else + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_set_background_fixed(png_ptr, background_color, background_gamma_code, + need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); +} +# endif /* FLOATING_POINT */ +#endif /* READ_BACKGROUND */ + +/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the + * one that pngrtran does first (scale) happens. This is necessary to allow the + * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +void PNGAPI +png_set_scale_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_scale_16"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_SCALE_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +/* Chop 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +void PNGAPI +png_set_strip_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_STRIP_ALPHA; +} +#endif + +#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) +static png_fixed_point +translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, + int is_screen) +{ + /* Check for flag values. The main reason for having the old Mac value as a + * flag is that it is pretty near impossible to work out what the correct + * value is from Apple documentation - a working Mac system is needed to + * discover the value! + */ + if (output_gamma == PNG_DEFAULT_sRGB || + output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) + { + /* If there is no sRGB support this just sets the gamma to the standard + * sRGB value. (This is a side effect of using this function!) + */ +# ifdef PNG_READ_sRGB_SUPPORTED + png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; +# endif + if (is_screen) + output_gamma = PNG_GAMMA_sRGB; + else + output_gamma = PNG_GAMMA_sRGB_INVERSE; + } + + else if (output_gamma == PNG_GAMMA_MAC_18 || + output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) + { + if (is_screen) + output_gamma = PNG_GAMMA_MAC_OLD; + else + output_gamma = PNG_GAMMA_MAC_INVERSE; + } + + return output_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +static png_fixed_point +convert_gamma_value(png_structp png_ptr, double output_gamma) +{ + /* The following silently ignores cases where fixed point (times 100,000) + * gamma values are passed to the floating point API. This is safe and it + * means the fixed point constants work just fine with the floating point + * API. The alternative would just lead to undetected errors and spurious + * bug reports. Negative values fail inside the _fixed API unless they + * correspond to the flag values. + */ + if (output_gamma > 0 && output_gamma < 128) + output_gamma *= PNG_FP_1; + + /* This preserves -1 and -2 exactly: */ + output_gamma = floor(output_gamma + .5); + + if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) + png_fixed_error(png_ptr, "gamma value"); + + return (png_fixed_point)output_gamma; +} +# endif +#endif /* READ_ALPHA_MODE || READ_GAMMA */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +void PNGFAPI +png_set_alpha_mode_fixed(png_structp png_ptr, int mode, + png_fixed_point output_gamma) +{ + int compose = 0; + png_fixed_point file_gamma; + + png_debug(1, "in png_set_alpha_mode"); + + if (png_ptr == NULL) + return; + + output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); + + /* Validate the value to ensure it is in a reasonable range. The value + * is expected to be 1 or greater, but this range test allows for some + * viewing correction values. The intent is to weed out users of this API + * who use the inverse of the gamma value accidentally! Since some of these + * values are reasonable this may have to be changed. + */ + if (output_gamma < 70000 || output_gamma > 300000) + png_error(png_ptr, "output gamma out of expected range"); + + /* The default file gamma is the inverse of the output gamma; the output + * gamma may be changed below so get the file value first: + */ + file_gamma = png_reciprocal(output_gamma); + + /* There are really 8 possibilities here, composed of any combination + * of: + * + * premultiply the color channels + * do not encode non-opaque pixels + * encode the alpha as well as the color channels + * + * The differences disappear if the input/output ('screen') gamma is 1.0, + * because then the encoding is a no-op and there is only the choice of + * premultiplying the color channels or not. + * + * png_set_alpha_mode and png_set_background interact because both use + * png_compose to do the work. Calling both is only useful when + * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along + * with a default gamma value. Otherwise PNG_COMPOSE must not be set. + */ + switch (mode) + { + case PNG_ALPHA_PNG: /* default: png standard */ + /* No compose, but it may be set by png_set_background! */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + /* The output is linear: */ + output_gamma = PNG_FP_1; + break; + + case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; + /* output_gamma records the encoding of opaque pixels! */ + break; + + case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ + compose = 1; + png_ptr->transformations |= PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + default: + png_error(png_ptr, "invalid alpha mode"); + } + + /* Only set the default gamma if the file gamma has not been set (this has + * the side effect that the gamma in a second call to png_set_alpha_mode will + * be ignored.) + */ + if (png_ptr->gamma == 0) + png_ptr->gamma = file_gamma; + + /* But always set the output gamma: */ + png_ptr->screen_gamma = output_gamma; + + /* Finally, if pre-multiplying, set the background fields to achieve the + * desired result. + */ + if (compose) + { + /* And obtain alpha pre-multiplication by composing on black: */ + png_memset(&png_ptr->background, 0, sizeof png_ptr->background); + png_ptr->background_gamma = png_ptr->gamma; /* just in case */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + + if (png_ptr->transformations & PNG_COMPOSE) + png_error(png_ptr, + "conflicting calls to set alpha mode and background"); + + png_ptr->transformations |= PNG_COMPOSE; + } + + /* New API, make sure apps call the correct initializers: */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) +{ + png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, + output_gamma)); +} +# endif +#endif + +#ifdef PNG_READ_QUANTIZE_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_quantize" indicates + * whether we need a quantizing 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_quantize(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize) +{ + png_debug(1, "in png_set_quantize"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_QUANTIZE; + + if (!full_quantize) + { + int i; + + png_ptr->quantize_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->quantize_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->quantize_sort = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof(png_byte))); + + /* Initialize the quantize_sort array */ + for (i = 0; i < num_palette; i++) + png_ptr->quantize_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->quantize_sort[j]] + < histogram[png_ptr->quantize_sort[j + 1]]) + { + png_byte t; + + t = png_ptr->quantize_sort[j]; + png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; + png_ptr->quantize_sort[j + 1] = t; + done = 0; + } + } + + if (done) + break; + } + + /* Swap the palette around, and set up a table, if necessary */ + if (full_quantize) + { + 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->quantize_sort[i] >= maximum_colors) + { + do + j--; + while ((int)png_ptr->quantize_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->quantize_sort[i] >= maximum_colors) + { + png_color tmp_color; + + do + j--; + while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + + tmp_color = palette[j]; + palette[j] = palette[i]; + palette[i] = tmp_color; + /* Indicate where the color went */ + png_ptr->quantize_index[j] = (png_byte)i; + png_ptr->quantize_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->quantize_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->quantize_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->quantize_index[i] = (png_byte)min_k; + } + } + } + png_free(png_ptr, png_ptr->quantize_sort); + png_ptr->quantize_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_calloc(png_ptr, (png_uint_32)(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_quantize) + { + int k; + + for (k = 0; k < num_palette; k++) + { + if (png_ptr->quantize_index[k] == + png_ptr->index_to_palette[j]) + png_ptr->quantize_index[k] = + png_ptr->index_to_palette[next_j]; + + if ((int)png_ptr->quantize_index[k] == + num_new_palette) + png_ptr->quantize_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_quantize) + { + int i; + png_bytep distance; + int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + + PNG_QUANTIZE_BLUE_BITS; + int num_red = (1 << PNG_QUANTIZE_RED_BITS); + int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); + int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); + png_size_t num_entries = ((png_size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, + (png_uint_32)(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_QUANTIZE_RED_BITS)); + int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); + int b = (palette[i].blue >> (8 - PNG_QUANTIZE_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_QUANTIZE_BLUE_BITS + + PNG_QUANTIZE_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_QUANTIZE_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 /* PNG_READ_QUANTIZE_SUPPORTED */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +void PNGFAPI +png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); + + if (png_ptr == NULL) + return; + + /* New in libpng-1.5.4 - reserve particular negative values as flags. */ + scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); + file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); + +#if PNG_LIBPNG_VER >= 10600 + /* Checking the gamma values for being >0 was added in 1.5.4 along with the + * premultiplied alpha support; this actually hides an undocumented feature + * of the previous implementation which allowed gamma processing to be + * disabled in background handling. There is no evidence (so far) that this + * was being used; however, png_set_background itself accepted and must still + * accept '0' for the gamma value it takes, because it isn't always used. + * + * Since this is an API change (albeit a very minor one that removes an + * undocumented API feature) it will not be made until libpng-1.6.0. + */ + if (file_gamma <= 0) + png_error(png_ptr, "invalid file gamma in png_set_gamma"); + + if (scrn_gamma <= 0) + png_error(png_ptr, "invalid screen gamma in png_set_gamma"); +#endif + + /* Set the gamma values unconditionally - this overrides the value in the PNG + * file if a gAMA chunk was present. png_set_alpha_mode provides a + * different, easier, way to default the file gamma. + */ + png_ptr->gamma = file_gamma; + png_ptr->screen_gamma = scrn_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), + convert_gamma_value(png_ptr, file_gamma)); +} +# endif /* FLOATING_POINT_SUPPORTED */ +#endif /* READ_GAMMA */ + +#ifdef 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + +/* 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.2.9, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha + * and its name was changed to png_set_expand_gray_1_2_4_to_8(). + */ + +/* 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + +/* 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_EXPAND; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + + + +/* 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"); + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} +#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise + * it may not work correctly.) + */ +void PNGAPI +png_set_expand_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_16"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + + /* New API, make sure apps call the correct initializers: */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; +} +#endif + +#ifdef 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"); + + if (png_ptr != NULL) + { + /* Because rgb must be 8 bits or more: */ + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_ptr->transformations |= PNG_GRAY_TO_RGB; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +void PNGFAPI +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"); + + if (png_ptr == NULL) + return; + + switch(error_action) + { + case PNG_ERROR_ACTION_NONE: + png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + + case PNG_ERROR_ACTION_WARN: + png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + + case PNG_ERROR_ACTION_ERROR: + png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + break; + + default: + png_error(png_ptr, "invalid error action to rgb_to_gray"); + break; + } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#ifdef 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 + { + if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) + { + png_uint_16 red_int, green_int; + + /* NOTE: this calculation does not round, but this behavior is retained + * for consistency, the inaccuracy is very small. The code here always + * overwrites the coefficients, regardless of whether they have been + * defaulted or set already. + */ + red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); + green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); + + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; + png_ptr->rgb_to_gray_coefficients_set = 1; + } + + else + { + if (red >= 0 && green >= 0) + png_warning(png_ptr, + "ignoring out of range rgb_to_gray coefficients"); + + /* Use the defaults, from the cHRM chunk if set, else the historical + * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See + * png_do_rgb_to_gray for more discussion of the values. In this case + * the coefficients are not marked as 'set' and are not overwritten if + * something has already provided a default. + */ + if (png_ptr->rgb_to_gray_red_coeff == 0 && + png_ptr->rgb_to_gray_green_coeff == 0) + { + png_ptr->rgb_to_gray_red_coeff = 6968; + png_ptr->rgb_to_gray_green_coeff = 23434; + /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ + } + } + } +} + +#ifdef 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) +{ + if (png_ptr == NULL) + return; + + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); +} +#endif /* FLOATING POINT */ + +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_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"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +#endif +} +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +#ifdef PNG_READ_GAMMA_SUPPORTED +/* In the case of gamma transformations 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. + */ +static int /* PRIVATE */ +png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) +{ + /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma + * correction as a difference of the overall transform from 1.0 + * + * We want to compare the threshold with s*f - 1, if we get + * overflow here it is because of wacky gamma values so we + * turn on processing anyway. + */ + png_fixed_point gtest; + return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || + png_gamma_significant(gtest); +} +#endif + +/* Initialize everything needed for the read. This includes modifying + * the palette. + */ + +/*For the moment 'png_init_palette_transformations' and + * 'png_init_rgb_transformations' only do some flag canceling optimizations. + * The intent is that these two routines should have palette or rgb operations + * extracted from 'png_init_read_transformations'. + */ +static void /* PRIVATE */ +png_init_palette_transformations(png_structp png_ptr) +{ + /* Called to handle the (input) palette case. In png_do_read_transformations + * the first step is to expand the palette if requested, so this code must + * take care to only make changes that are invariant with respect to the + * palette expansion, or only do them if there is no expansion. + * + * STRIP_ALPHA has already been handled in the caller (by setting num_trans + * to 0.) + */ + int input_has_alpha = 0; + int input_has_transparency = 0; + + if (png_ptr->num_trans > 0) + { + int i; + + /* Ignore if all the entries are opaque (unlikely!) */ + for (i=0; inum_trans; ++i) + if (png_ptr->trans_alpha[i] == 255) + continue; + else if (png_ptr->trans_alpha[i] == 0) + input_has_transparency = 1; + else + input_has_alpha = 1; + } + + /* If no alpha we can optimize. */ + if (!input_has_alpha) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + if (!input_has_transparency) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND)) + { + { + 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; + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + { + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later + */ + int i, istop = png_ptr->num_trans; + + for (i=0; itrans_alpha[i] = (png_byte)(255 - + png_ptr->trans_alpha[i]); + } + } +#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ + } + } /* background expand and (therefore) no alpha association. */ +#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +} + +static void /* PRIVATE */ +png_init_rgb_transformations(png_structp png_ptr) +{ + /* Added to libpng-1.5.4: check the color type to determine whether there + * is any alpha or transparency in the image and simply cancel the + * background and alpha mode stuff if there isn't. + */ + int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; + int input_has_transparency = png_ptr->num_trans > 0; + + /* If no alpha we can optimize. */ + if (!input_has_alpha) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ +# ifdef PNG_READ_ALPHA_MODE_SUPPORTED + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; +# endif + + if (!input_has_transparency) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND) && + !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + /* i.e., GRAY or GRAY_ALPHA */ + { + { + /* Expand background and tRNS chunks */ + int gray = png_ptr->background.gray; + int trans_gray = png_ptr->trans_color.gray; + + switch (png_ptr->bit_depth) + { + case 1: + gray *= 0xff; + trans_gray *= 0xff; + break; + + case 2: + gray *= 0x55; + trans_gray *= 0x55; + break; + + case 4: + gray *= 0x11; + trans_gray *= 0x11; + break; + + default: + + case 8: + /* Already 8 bits, fall through */ + + case 16: + /* Already a full 16 bits */ + break; + } + + png_ptr->background.red = png_ptr->background.green = + png_ptr->background.blue = (png_uint_16)gray; + + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_color.red = png_ptr->trans_color.green = + png_ptr->trans_color.blue = (png_uint_16)trans_gray; + } + } + } /* background expand and (therefore) no alpha association. */ +#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +} + +void /* PRIVATE */ +png_init_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_init_read_transformations"); + + /* This internal function is called from png_read_start_row in pngrutil.c + * and it is called before the 'rowbytes' calculation is done, so the code + * in here can change or update the transformations flags. + * + * First do updates that do not depend on the details of the PNG image data + * being processed. + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds + * png_set_alpha_mode and this is another source for a default file gamma so + * the test needs to be performed later - here. In addition prior to 1.5.4 + * the tests were repeated for the PALETTE color type here - this is no + * longer necessary (and doesn't seem to have been necessary before.) + */ + { + /* The following temporary indicates if overall gamma correction is + * required. + */ + int gamma_correction = 0; + + if (png_ptr->gamma != 0) /* has been set */ + { + if (png_ptr->screen_gamma != 0) /* screen set too */ + gamma_correction = png_gamma_threshold(png_ptr->gamma, + png_ptr->screen_gamma); + + else + /* Assume the output matches the input; a long time default behavior + * of libpng, although the standard has nothing to say about this. + */ + png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); + } + + else if (png_ptr->screen_gamma != 0) + /* The converse - assume the file matches the screen, note that this + * perhaps undesireable default can (from 1.5.4) be changed by calling + * png_set_alpha_mode (even if the alpha handling mode isn't required + * or isn't changed from the default.) + */ + png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); + + else /* neither are set */ + /* Just in case the following prevents any processing - file and screen + * are both assumed to be linear and there is no way to introduce a + * third gamma value other than png_set_background with 'UNIQUE', and, + * prior to 1.5.4 + */ + png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; + + /* Now turn the gamma transformation on or off as appropriate. Notice + * that PNG_GAMMA just refers to the file->screen correction. Alpha + * composition may independently cause gamma correction because it needs + * linear data (e.g. if the file has a gAMA chunk but the screen gamma + * hasn't been specified.) In any case this flag may get turned off in + * the code immediately below if the transform can be handled outside the + * row loop. + */ + if (gamma_correction) + png_ptr->transformations |= PNG_GAMMA; + + else + png_ptr->transformations &= ~PNG_GAMMA; + } +#endif + + /* Certain transformations have the effect of preventing other + * transformations that happen afterward in png_do_read_transformations, + * resolve the interdependencies here. From the code of + * png_do_read_transformations the order is: + * + * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) + * 2) PNG_STRIP_ALPHA (if no compose) + * 3) PNG_RGB_TO_GRAY + * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY + * 5) PNG_COMPOSE + * 6) PNG_GAMMA + * 7) PNG_STRIP_ALPHA (if compose) + * 8) PNG_ENCODE_ALPHA + * 9) PNG_SCALE_16_TO_8 + * 10) PNG_16_TO_8 + * 11) PNG_QUANTIZE (converts to palette) + * 12) PNG_EXPAND_16 + * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY + * 14) PNG_INVERT_MONO + * 15) PNG_SHIFT + * 16) PNG_PACK + * 17) PNG_BGR + * 18) PNG_PACKSWAP + * 19) PNG_FILLER (includes PNG_ADD_ALPHA) + * 20) PNG_INVERT_ALPHA + * 21) PNG_SWAP_ALPHA + * 22) PNG_SWAP_BYTES + * 23) PNG_USER_TRANSFORM [must be last] + */ +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + !(png_ptr->transformations & PNG_COMPOSE)) + { + /* Stripping the alpha channel happens immediately after the 'expand' + * transformations, before all other transformation, so it cancels out + * the alpha handling. It has the side effect negating the effect of + * PNG_EXPAND_tRNS too: + */ + png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | + PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen + * so transparency information would remain just so long as it wasn't + * expanded. This produces unexpected API changes if the set of things + * that do PNG_EXPAND_tRNS changes (perfectly possible given the + * documentation - which says ask for what you want, accept what you + * get.) This makes the behavior consistent from 1.5.4: + */ + png_ptr->num_trans = 0; + } +#endif /* STRIP_ALPHA supported, no COMPOSE */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA + * settings will have no effect. + */ + if (!png_gamma_significant(png_ptr->screen_gamma)) + { + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + } +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + 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. + * + * TODO: this code needs to be revised to avoid the complexity and + * interdependencies. The color type of the background should be recorded in + * png_set_background, along with the bit depth, then the code has a record + * of exactly what color space the background is currently in. + */ + if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) + { + /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if + * the file was grayscale the background value is gray. + */ + if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } + + else if (png_ptr->transformations & PNG_COMPOSE) + { + /* PNG_COMPOSE: png_set_background was called with need_expand false, + * so the color is in the color space of the output or png_set_alpha_mode + * was called and the color is black. Ignore RGB_TO_GRAY because that + * happens before GRAY_TO_RGB. + */ + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if (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 /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ + + /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations + * can be performed directly on the palette, and some (such as rgb to gray) + * can be optimized inside the palette. This is particularly true of the + * composite (background and alpha) stuff, which can be pretty much all done + * in the palette even if the result is expanded to RGB or gray afterward. + * + * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and + * earlier and the palette stuff is actually handled on the first row. This + * leads to the reported bug that the palette returned by png_get_PLTE is not + * updated. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_init_palette_transformations(png_ptr); + + else + png_init_rgb_transformations(png_ptr); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_EXPAND_16_SUPPORTED) + if ((png_ptr->transformations & PNG_EXPAND_16) && + (png_ptr->transformations & PNG_COMPOSE) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + png_ptr->bit_depth != 16) + { + /* TODO: fix this. Because the expand_16 operation is after the compose + * handling the background color must be 8, not 16, bits deep, but the + * application will supply a 16-bit value so reduce it here. + * + * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at + * present, so that case is ok (until do_expand_16 is moved.) + * + * NOTE: this discards the low 16 bits of the user supplied background + * color, but until expand_16 works properly there is no choice! + */ +# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) + CHOP(png_ptr->background.red); + CHOP(png_ptr->background.green); + CHOP(png_ptr->background.blue); + CHOP(png_ptr->background.gray); +# undef CHOP + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ + defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) + if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && + (png_ptr->transformations & PNG_COMPOSE) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + png_ptr->bit_depth == 16) + { + /* On the other hand, if a 16-bit file is to be reduced to 8-bits per + * component this will also happen after PNG_COMPOSE and so the background + * color must be pre-expanded here. + * + * TODO: fix this too. + */ + png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); + png_ptr->background.green = + (png_uint_16)(png_ptr->background.green * 257); + png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); + png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); + } +#endif + + /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the + * background support (see the comments in scripts/pnglibconf.dfa), this + * allows pre-multiplication of the alpha channel to be implemented as + * compositing on black. This is probably sub-optimal and has been done in + * 1.5.4 betas simply to enable external critique and testing (i.e. to + * implement the new API quickly, without lots of internal changes.) + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +# ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Includes ALPHA_MODE */ + png_ptr->background_1 = png_ptr->background; +# endif + + /* This needs to change - in the palette image case a whole set of tables are + * built when it would be quicker to just calculate the correct value for + * each palette entry directly. Also, the test is too tricky - why check + * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that + * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the + * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction + * the gamma tables will not be built even if composition is required on a + * gamma encoded value. + * + * In 1.5.4 this is addressed below by an additional check on the individual + * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the + * tables. + */ + if ((png_ptr->transformations & PNG_GAMMA) + || ((png_ptr->transformations & PNG_RGB_TO_GRAY) + && (png_gamma_significant(png_ptr->gamma) || + png_gamma_significant(png_ptr->screen_gamma))) + || ((png_ptr->transformations & PNG_COMPOSE) + && (png_gamma_significant(png_ptr->gamma) + || png_gamma_significant(png_ptr->screen_gamma) +# ifdef PNG_READ_BACKGROUND_SUPPORTED + || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE + && png_gamma_significant(png_ptr->background_gamma)) +# endif + )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) + && png_gamma_significant(png_ptr->screen_gamma)) + ) + { + png_build_gamma_table(png_ptr, png_ptr->bit_depth); + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + if (png_ptr->transformations & PNG_COMPOSE) + { + /* Issue a warning about this combination: because RGB_TO_GRAY is + * optimized to do the gamma transform if present yet do_background has + * to do the same thing if both options are set a + * double-gamma-correction happens. This is true in all versions of + * libpng to date. + */ + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + png_warning(png_ptr, + "libpng does not support gamma+background+rgb_to_gray"); + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + /* We don't get to here unless there is a tRNS chunk with non-opaque + * entries - see the checking code at the start of this function. + */ + 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 + { + png_fixed_point g, gs; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = PNG_FP_1; + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + default: + g = PNG_FP_1; /* back_1 */ + gs = PNG_FP_1; /* back */ + break; + } + + if (png_gamma_significant(gs)) + { + back.red = png_gamma_8bit_correct(png_ptr->background.red, + gs); + back.green = png_gamma_8bit_correct(png_ptr->background.green, + gs); + back.blue = png_gamma_8bit_correct(png_ptr->background.blue, + gs); + } + + else + { + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + } + + if (png_gamma_significant(g)) + { + back_1.red = png_gamma_8bit_correct(png_ptr->background.red, + g); + back_1.green = png_gamma_8bit_correct( + png_ptr->background.green, g); + back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, + g); + } + + else + { + back_1.red = (png_byte)png_ptr->background.red; + back_1.green = (png_byte)png_ptr->background.green; + back_1.blue = (png_byte)png_ptr->background.blue; + } + } + + for (i = 0; i < num_palette; i++) + { + if (i < (int)png_ptr->num_trans && + png_ptr->trans_alpha[i] != 0xff) + { + if (png_ptr->trans_alpha[i] == 0) + { + palette[i] = back; + } + else /* if (png_ptr->trans_alpha[i] != 0xff) */ + { + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, png_ptr->trans_alpha[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_alpha[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_alpha[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]; + } + } + + /* Prevent the transformations being done again. + * + * NOTE: this is highly dubious; it removes the transformations in + * place. This seems inconsistent with the general treatment of the + * transformations elsewhere. + */ + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); + } /* color_type == PNG_COLOR_TYPE_PALETTE */ + + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else /* color_type != PNG_COLOR_TYPE_PALETTE */ + { + int gs_sig, g_sig; + png_fixed_point g = PNG_FP_1; /* Correction to linear */ + png_fixed_point gs = PNG_FP_1; /* Correction to screen */ + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = png_ptr->screen_gamma; + /* gs = PNG_FP_1; */ + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + + default: + png_error(png_ptr, "invalid background gamma type"); + } + + g_sig = png_gamma_significant(g); + gs_sig = png_gamma_significant(gs); + + if (g_sig) + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); + + if (gs_sig) + png_ptr->background.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, gs); + + 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 */ + if (g_sig) + { + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); + + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); + + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); + } + + if (gs_sig) + { + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); + + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); + + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); + } + } + + 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; + } + + /* The background is now in screen gamma: */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; + } /* color_type != PNG_COLOR_TYPE_PALETTE */ + }/* png_ptr->transformations & PNG_BACKGROUND */ + + else + /* Transformation does not include PNG_BACKGROUND */ +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ + && ((png_ptr->transformations & PNG_EXPAND) == 0 || + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) +#endif + ) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + + /* NOTE: there are other transformations that should probably be in + * here too. + */ + 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]; + } + + /* Done the gamma correction. */ + png_ptr->transformations &= ~PNG_GAMMA; + } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ + } +#ifdef PNG_READ_BACKGROUND_SUPPORTED + else +#endif +#endif /* PNG_READ_GAMMA_SUPPORTED */ + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + /* No GAMMA transformation (see the hanging else 4 lines above) */ + if ((png_ptr->transformations & PNG_COMPOSE) && + (png_ptr->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_alpha[i] == 0) + { + palette[i] = back; + } + + else if (png_ptr->trans_alpha[i] != 0xff) + { + /* The png_composite() macro is defined in png.h */ + png_composite(palette[i].red, palette[i].red, + png_ptr->trans_alpha[i], back.red); + + png_composite(palette[i].green, palette[i].green, + png_ptr->trans_alpha[i], back.green); + + png_composite(palette[i].blue, palette[i].blue, + png_ptr->trans_alpha[i], back.blue); + } + } + + png_ptr->transformations &= ~PNG_COMPOSE; + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) && + !(png_ptr->transformations & PNG_EXPAND) && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; + + png_ptr->transformations &= ~PNG_SHIFT; + + /* significant bits can be in the range 1 to 7 for a meaninful result, if + * the number of significant bits is 0 then no shift is done (this is an + * error condition which is silently ignored.) + */ + if (shift > 0 && shift < 8) for (i=0; ipalette[i].red; + + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.green; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].green; + + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.blue; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue; + + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; + } + } +#endif /* PNG_READ_SHIFT_SUPPORTED */ +} + +/* 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"); + +#ifdef PNG_READ_EXPAND_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + /* This check must match what actually happens in + * png_do_expand_palette; if it ever checks the tRNS chunk to see if + * it is all opaque we must do the same (at present it does not.) + */ + if (png_ptr->num_trans > 0) + 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; + } + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + + info_ptr->num_trans = 0; + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* The following is almost certainly wrong unless the background value is in + * the screen space! + */ + if (png_ptr->transformations & PNG_COMPOSE) + info_ptr->background = png_ptr->background; +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), + * however it seems that the code in png_init_read_transformations, which has + * been called before this from png_read_update_info->png_read_start_row + * sometimes does the gamma transform and cancels the flag. + */ + info_ptr->gamma = png_ptr->gamma; +#endif + + if (info_ptr->bit_depth == 16) + { +# ifdef PNG_READ_16BIT_SUPPORTED +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_SCALE_16_TO_8) + info_ptr->bit_depth = 8; +# endif + +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_16_TO_8) + info_ptr->bit_depth = 8; +# endif + +# else + /* No 16 bit support: force chopping 16-bit input down to 8, in this case + * the app program can chose if both APIs are available by setting the + * correct scaling to use. + */ +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* For compatibility with previous versions use the strip method by + * default. This code works because if PNG_SCALE_16_TO_8 is already + * set the code below will do that in preference to the chop. + */ + png_ptr->transformations |= PNG_16_TO_8; + info_ptr->bit_depth = 8; +# else + +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_ptr->transformations |= PNG_SCALE_16_TO_8; + info_ptr->bit_depth = 8; +# else + + CONFIGURATION ERROR: you must enable at least one 16 to 8 method +# endif +# endif +#endif /* !READ_16BIT_SUPPORTED */ + } + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + info_ptr->color_type = (png_byte)(info_ptr->color_type | + PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if (png_ptr->transformations & PNG_QUANTIZE) + { + 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 + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && + info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + info_ptr->bit_depth = 16; + } +#endif + +#ifdef 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; + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_STRIP_ALPHA) + { + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); + info_ptr->num_trans = 0; + } +#endif + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + +#ifdef 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 (png_ptr->transformations & PNG_ADD_ALPHA) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } +#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); + + /* Adding in 1.5.4: cache the above value in png_struct so that we can later + * check in png_rowbytes that the user buffer won't get overwritten. Note + * that the field is not always set - if png_read_update_info isn't called + * the application has to either not do any transforms or get the calculation + * right itself. + */ + png_ptr->info_rowbytes = info_ptr->rowbytes; + +#ifndef 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_row_infop row_info) +{ + png_debug(1, "in png_do_read_transformations"); + + if (png_ptr->row_buf == NULL) + { + /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this + * error is incredibly rare and incredibly easy to debug without this + * information. + */ + png_error(png_ptr, "NULL row buffer"); + } + + /* The following is debugging; prior to 1.5.4 the code was never compiled in; + * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro + * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for + * selected new APIs to ensure that there is no API change. + */ + if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && + !(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 (but not enabled until 1.5.4). + */ + png_error(png_ptr, "Uninitialized row"); + } + +#ifdef PNG_READ_EXPAND_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND) + { + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_do_expand_palette(row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + } + + else + { + if (png_ptr->num_trans && + (png_ptr->transformations & PNG_EXPAND_tRNS)) + png_do_expand(row_info, png_ptr->row_buf + 1, + &(png_ptr->trans_color)); + + else + png_do_expand(row_info, png_ptr->row_buf + 1, + NULL); + } + } +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + !(png_ptr->transformations & PNG_COMPOSE) && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + { + int rgb_error = + png_do_rgb_to_gray(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. + */ + +#ifdef 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(row_info, png_ptr->row_buf + 1); +#endif + +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_SUPPORTED) + if (png_ptr->transformations & PNG_COMPOSE) + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + if ((png_ptr->transformations & PNG_GAMMA) && +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Because RGB_TO_GRAY does the gamma transform. */ + !(png_ptr->transformations & PNG_RGB_TO_GRAY) && +#endif +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_SUPPORTED) + /* Because PNG_COMPOSE does the gamma transform if there is something to + * do (if there is an alpha channel or transparency.) + */ + !((png_ptr->transformations & PNG_COMPOSE) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && +#endif + /* Because png_init_read_transformations transforms the palette, unless + * RGB_TO_GRAY will do the transform. + */ + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + (png_ptr->transformations & PNG_COMPOSE) && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && + (row_info->color_type & PNG_COLOR_MASK_ALPHA)) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_SCALE_16_TO_8) + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* There is no harm in doing both of these because only one has any effect, + * by putting the 'scale' option first if the app asks for scale (either by + * calling the API or in a TRANSFORM flag) this is what happens. + */ + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if (png_ptr->transformations & PNG_QUANTIZE) + { + png_do_quantize(row_info, png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); + + if (row_info->rowbytes == 0) + png_error(png_ptr, "png_do_quantize returned rowbytes=0"); + } +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Do the expansion now, after all the arithmetic has been done. Notice + * that previous transformations can handle the PNG_EXPAND_16 flag if this + * is efficient (particularly true in the case of gamma correction, where + * better accuracy results faster!) + */ + if (png_ptr->transformations & PNG_EXPAND_16) + png_do_expand_16(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* NOTE: moved here in 1.5.4 (from much later in this list.) */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + if (png_ptr->transformations & PNG_SHIFT) + png_do_unshift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if (png_ptr->transformations & PNG_PACK) + png_do_unpack(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, row_info); +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if (png_ptr->transformations & PNG_FILLER) + png_do_read_filler(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_16BIT_SUPPORTED +#ifdef PNG_READ_SWAP_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif +#endif + +#ifdef 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 */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t 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 */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + if (png_ptr->user_transform_depth) + row_info->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels) + row_info->channels = png_ptr->user_transform_channels; +#endif + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); + } +#endif +} + +#ifdef 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"); + + if (row_info->bit_depth < 8) + { + 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; + } + + default: + 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 + +#ifdef 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_const_color_8p sig_bits) +{ + int color_type; + + png_debug(1, "in png_do_unshift"); + + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; + int bit_depth = row_info->bit_depth; + + if (color_type & PNG_COLOR_MASK_COLOR) + { + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; + } + + else + { + shift[channels++] = bit_depth - sig_bits->gray; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + { + shift[channels++] = bit_depth - sig_bits->alpha; + } + + { + int c, have_shift; + + for (c = have_shift = 0; c < channels; ++c) + { + /* A shift of more than the bit depth is an error condition but it + * gets ignored here. + */ + if (shift[c] <= 0 || shift[c] >= bit_depth) + shift[c] = 0; + + else + have_shift = 1; + } + + if (!have_shift) + return; + } + + switch (bit_depth) + { + default: + /* Must be 1bpp gray: should not be here! */ + /* NOTREACHED */ + break; + + case 2: + /* Must be 2bpp gray */ + /* assert(channels == 1 && shift[0] == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + + while (bp < bp_end) + { + int b = (*bp >> 1) & 0x55; + *bp++ = (png_byte)b; + } + break; + } + + case 4: + /* Must be 4bpp gray */ + /* assert(channels == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int gray_shift = shift[0]; + int mask = 0xf >> gray_shift; + + mask |= mask << 4; + + while (bp < bp_end) + { + int b = (*bp >> gray_shift) & mask; + *bp++ = (png_byte)b; + } + break; + } + + case 8: + /* Single byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int b = *bp >> shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)b; + } + break; + } + +#ifdef PNG_READ_16BIT_SUPPORTED + case 16: + /* Double byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int value = (bp[0] << 8) + bp[1]; + + value >>= shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + break; + } +#endif + } + } +} +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale rows of bit depth 16 down to 8 accurately */ +void /* PRIVATE */ +png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_scale_16_to_8"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + /* The input is an array of 16 bit components, these must be scaled to + * 8 bits each. For a 16 bit value V the required value (from the PNG + * specification) is: + * + * (V * 255) / 65535 + * + * This reduces to round(V / 257), or floor((V + 128.5)/257) + * + * Represent V as the two byte value vhi.vlo. Make a guess that the + * result is the top byte of V, vhi, then the correction to this value + * is: + * + * error = floor(((V-vhi.vhi) + 128.5) / 257) + * = floor(((vlo-vhi) + 128.5) / 257) + * + * This can be approximated using integer arithmetic (and a signed + * shift): + * + * error = (vlo-vhi+128) >> 8; + * + * The approximate differs from the exact answer only when (vlo-vhi) is + * 128; it then gives a correction of +1 when the exact correction is + * 0. This gives 128 errors. The exact answer (correct for all 16 bit + * input values) is: + * + * error = (vlo-vhi+128)*65535 >> 24; + * + * An alternative arithmetic calculation which also gives no errors is: + * + * (V * 255 + 32895) >> 16 + */ + + png_int_32 tmp = *sp++; /* must be signed! */ + tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; + *dp++ = (png_byte)tmp; + } + + 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 + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +void /* PRIVATE */ +/* Simply discard the low byte. This was the default behavior prior + * to libpng-1.5.4. + */ +png_do_chop(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_chop"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + *dp++ = *sp; + sp += 2; /* skip low byte */ + } + + 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 + +#ifdef 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"); + + { + 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; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* 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]; + } + } +#endif + } + + 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; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* 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 + } + } +} +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_uint_32 row_width; + png_debug(1, "in png_do_read_invert_alpha"); + + row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + 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; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* 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; + } + } +#endif + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + 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); + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + 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 + } +} +#endif + +#ifdef 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; + +#ifdef PNG_READ_16BIT_SUPPORTED + png_byte hi_filler = (png_byte)((filler>>8) & 0xff); +#endif + png_byte lo_filler = (png_byte)(filler & 0xff); + + png_debug(1, "in png_do_read_filler"); + + if ( + row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from G to GX */ + 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; + } + + else + { + /* This changes the data from G to XG */ + 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; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from GG to GGXX */ + 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; + } + + else + { + /* This changes the data from GG to XXGG */ + 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; + } + } +#endif + } /* COLOR_TYPE == GRAY */ + else if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if (row_info->bit_depth == 8) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from RGB to RGBX */ + 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; + } + + else + { + /* This changes the data from RGB to XRGB */ + 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; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + 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; + } + + else + { + /* This changes the data from RRGGBB to XXRRGGBB */ + 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; + } + } +#endif + } /* COLOR_TYPE == RGB */ +} +#endif + +#ifdef 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"); + + if (row_info->bit_depth >= 8 && + !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + /* This changes G to RGB */ + 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 + { + /* This changes GG to RRGGBB */ + 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) + { + /* This changes GA to RGBA */ + 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 + { + /* This changes GGAA to RRGGBBAA */ + 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)(row_info->channels + 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 + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB files to grayscale, with or without alpha + * using the equation given in Poynton's ColorFAQ of 1998-01-04 at + * (THIS LINK IS DEAD June 2008 but + * versions dated 1998 through November 2002 have been archived at + * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ + * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) + * Charles Poynton poynton at poynton.com + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * + * Poynton's current link (as of January 2003 through July 2011): + * + * has changed the numbers slightly: + * + * Y = 0.2126*R + 0.7152*G + 0.0722*B + * + * which can be expressed with integers as + * + * Y = (6966 * R + 23436 * G + 2366 * B)/32768 + * + * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 + * end point chromaticities and the D65 white point. Depending on the + * precision used for the D65 white point this produces a variety of different + * numbers, however if the four decimal place value used in ITU-R Rec 709 is + * used (0.3127,0.3290) the Y calculation would be: + * + * Y = (6968 * R + 23435 * G + 2366 * B)/32768 + * + * While this is correct the rounding results in an overflow for white, because + * the sum of the rounded coefficients is 32769, not 32768. Consequently + * libpng uses, instead, the closest non-overflowing approximation: + * + * Y = (6968 * R + 23434 * G + 2366 * B)/32768 + * + * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk + * (including an sRGB chunk) then the chromaticities are used to calculate the + * coefficients. See the chunk handling in pngrutil.c for more information. + * + * In all cases the calculation is to be done in a linear colorspace. If no + * gamma information is available to correct the encoding of the original RGB + * values this results in an implicit assumption that the original PNG RGB + * values were linear. + * + * Other integer coefficents can be used via png_set_rgb_to_gray(). Because + * the API takes just red and green coefficients the blue coefficient is + * calculated to make the sum 32768. This will result in different rounding + * to that used above. + */ +int /* PRIVATE */ +png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) + +{ + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray"); + + if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + PNG_CONST png_uint_32 bc = 32768 - rc - gc; + PNG_CONST png_uint_32 row_width = row_info->width; + PNG_CONST int have_alpha = + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; + + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* Notice that gamma to/from 1 are not necessarily inverses (if + * there is an overall gamma correction). Prior to 1.5.5 this code + * checked the linearized values for equality; this doesn't match + * the documentation, the original values must be checked. + */ + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) + { + red = png_ptr->gamma_to_1[red]; + green = png_ptr->gamma_to_1[green]; + blue = png_ptr->gamma_to_1[blue]; + + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red + gc*green + bc*blue + 16384)>>15]; + } + + else + { + /* If there is no overall correction the table will not be + * set. + */ + if (png_ptr->gamma_table != NULL) + red = png_ptr->gamma_table[red]; + + *(dp++) = red; + } + + if (have_alpha) + *(dp++) = *(sp++); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + 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; + /* NOTE: this is the historical approach which simply + * truncates the results. + */ + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + } + + else + *(dp++) = red; + + if (have_alpha) + *(dp++) = *(sp++); + } + } + } + + 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; + png_uint_32 i; + + 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) + { + if (png_ptr->gamma_16_table != NULL) + w = png_ptr->gamma_16_table[(red&0xff) + >> png_ptr->gamma_shift][red>>8]; + + else + 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 + 16384)>>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); + + if (have_alpha) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + 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; + + /* From 1.5.5 in the 16 bit case do the accurate conversion even + * in the 'fast' case - this is because this is where the code + * ends up when handling linear 16 bit data. + */ + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> + 15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + + if (have_alpha) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + } + + row_info->channels = (png_byte)(row_info->channels - 2); + row_info->color_type = (png_byte)(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 +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +/* 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. This API is not used internally. + */ +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"); + + 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; + } +} +#endif + + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_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_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) +{ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; + png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; + png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; + png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; + int gamma_shift = png_ptr->gamma_shift; +#endif + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + int shift; + + png_debug(1, "in png_do_compose"); + + { + 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) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 7; + sp++; + } + + else + shift--; + } + break; + } + + case 2: + { +#ifdef 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) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->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) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + break; + } + + case 4: + { +#ifdef 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) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->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) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + break; + } + + case 8: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + + else + *sp = gamma_table[*sp]; + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + } + } + break; + } + + case 16: + { +#ifdef 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 == png_ptr->trans_color.gray) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->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 == png_ptr->trans_color.gray) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + } + } + break; + } + + default: + break; + } + break; + } + + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->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 == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef 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 == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->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 == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + *sp = gamma_table[*sp]; + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.gray; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.gray); + if (!optimize) + w = gamma_from_1[w]; + *sp = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_byte a = *(sp + 1); + + if (a == 0) + *sp = (png_byte)png_ptr->background.gray; + + else if (a < 0xff) + png_composite(*sp, *sp, a, png_ptr->background_1.gray); + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + 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]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, png_ptr->background_1.gray); + if (optimize) + w = v; + else + w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, png_ptr->background_1.gray); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.red); + if (!optimize) w = gamma_from_1[w]; + *sp = w; + + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, png_ptr->background_1.green); + if (!optimize) w = gamma_from_1[w]; + *(sp + 1) = w; + + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, png_ptr->background_1.blue); + if (!optimize) w = gamma_from_1[w]; + *(sp + 2) = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else if (a < 0xff) + { + png_composite(*sp, *sp, a, png_ptr->background.red); + + png_composite(*(sp + 1), *(sp + 1), a, + png_ptr->background.green); + + png_composite(*(sp + 2), *(sp + 2), a, + png_ptr->background.blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + 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]; + *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 if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v, w; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, png_ptr->background_1.red); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, png_ptr->background_1.green); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, png_ptr->background_1.blue); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else if (a < 0xffff) + { + 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, png_ptr->background.red); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + png_composite_16(v, g, a, png_ptr->background.green); + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + png_composite_16(v, b, a, png_ptr->background.blue); + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + default: + break; + } + } +} +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ + +#ifdef 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_structp png_ptr) +{ + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; + int gamma_shift = png_ptr->gamma_shift; + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma"); + + if (((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; + } + + default: + break; + } + } +} +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* Encode the alpha channel to the output gamma (the input channel is always + * linear.) Called only with color types that have an alpha channel. Needs the + * from_1 tables. + */ +void /* PRIVATE */ +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) +{ + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_encode_alpha"); + + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + if (row_info->bit_depth == 8) + { + PNG_CONST png_bytep table = png_ptr->gamma_from_1; + + if (table != NULL) + { + PNG_CONST int step = + (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; + + /* The alpha channel is the last component: */ + row += step - 1; + + for (; row_width > 0; --row_width, row += step) + *row = table[*row]; + + return; + } + } + + else if (row_info->bit_depth == 16) + { + PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; + PNG_CONST int gamma_shift = png_ptr->gamma_shift; + + if (table != NULL) + { + PNG_CONST int step = + (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; + + /* The alpha channel is the last component: */ + row += step - 2; + + for (; row_width > 0; --row_width, row += step) + { + png_uint_16 v; + + v = table[*(row + 1) >> gamma_shift][*row]; + *row = (png_byte)((v >> 8) & 0xff); + *(row + 1) = (png_byte)(v & 0xff); + } + + return; + } + } + } + + /* Only get to here if called with a weird row_info; no harm has been done, + * so just issue a warning. + */ + png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); +} +#endif + +#ifdef 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_const_colorp palette, png_const_bytep trans_alpha, 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"); + + if (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; + } + + default: + break; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (row_info->bit_depth == 8) + { + { + if (num_trans > 0) + { + 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_alpha[*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; + } + } + } + } +} + +/* 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_const_color_16p trans_color) +{ + 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"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->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; + } + + default: + break; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (trans_color != 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 = (png_byte)((gray >> 8) & 0xff); + png_byte gray_low = (png_byte)(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_color) + { + if (row_info->bit_depth == 8) + { + png_byte red = (png_byte)(trans_color->red & 0xff); + png_byte green = (png_byte)(trans_color->green & 0xff); + png_byte blue = (png_byte)(trans_color->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 = (png_byte)((trans_color->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_color->red & 0xff); + png_byte green_low = (png_byte)(trans_color->green & 0xff); + png_byte blue_low = (png_byte)(trans_color->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 + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* If the bit depth is 8 and the color type is not a palette type expand the + * whole row to 16 bits. Has no effect otherwise. + */ +void /* PRIVATE */ +png_do_expand_16(png_row_infop row_info, png_bytep row) +{ + if (row_info->bit_depth == 8 && + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + /* The row have a sequence of bytes containing [0..255] and we need + * to turn it into another row containing [0..65535], to do this we + * calculate: + * + * (input / 255) * 65535 + * + * Which happens to be exactly input * 257 and this can be achieved + * simply by byte replication in place (copying backwards). + */ + png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ + png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ + while (dp > sp) + dp[-2] = dp[-1] = *--sp, dp -= 2; + + row_info->rowbytes *= 2; + row_info->bit_depth = 16; + row_info->pixel_depth = (png_byte)(row_info->channels * 16); + } +} +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +void /* PRIVATE */ +png_do_quantize(png_row_infop row_info, png_bytep row, + png_const_bytep palette_lookup, png_const_bytep quantize_lookup) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_quantize"); + + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) + { + 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_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_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) + { + 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_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_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 && + quantize_lookup) + { + sp = row; + + for (i = 0; i < row_width; i++, sp++) + { + *sp = quantize_lookup[*sp]; + } + } + } +} +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#ifdef 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"); + + if ( + (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 = (s0 + s1 + 65536) & 0xffff; + png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; + *(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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrutil.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrutil.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngrutil.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngrutil.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,4159 @@ + +/* pngrutil.c - utilities to read a PNG file + * + * Last changed in libpng 1.5.10 [March 8, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that are only called from within + * libpng itself during the course of reading an image. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#define png_strtod(p,a,b) strtod(a,b) + +png_uint_32 PNGAPI +png_get_uint_31(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range"); + + return (uval); +} + +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) +/* The following is a variation on the above for use with the fixed + * point values used for gAMA and cHRM. Instead of png_error it + * issues a warning and returns (-1) - an invalid value because both + * gAMA and cHRM use *unsigned* integers for fixed point values. + */ +#define PNG_FIXED_ERROR (-1) + +static png_fixed_point /* PRIVATE */ +png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval <= PNG_UINT_31_MAX) + return (png_fixed_point)uval; /* known to be in range */ + + /* The caller can turn off the warning by passing NULL. */ + if (png_ptr != NULL) + png_warning(png_ptr, "PNG fixed point integer out of range"); + + return PNG_FIXED_ERROR; +} +#endif + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +/* NOTE: the read macros will obscure these definitions, so that if + * PNG_USE_READ_MACROS is set the library will not use them internally, + * but the APIs will still be available externally. + * + * The parentheses around "PNGAPI function_name" in the following three + * functions are necessary because they allow the macros to co-exist with + * these (unused but exported) functions. + */ + +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ +png_uint_32 (PNGAPI +png_get_uint_32)(png_const_bytep buf) +{ + png_uint_32 uval = + ((png_uint_32)(*(buf )) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + ((png_uint_32)(*(buf + 3)) ) ; + + return uval; +} + +/* 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 there + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore + * the following code does a two's complement to native conversion. + */ +png_int_32 (PNGAPI +png_get_int_32)(png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + if ((uval & 0x80000000) == 0) /* non-negative */ + return uval; + + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + return -(png_int_32)uval; +} + +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ +png_uint_16 (PNGAPI +png_get_uint_16)(png_const_bytep buf) +{ + /* ANSI-C requires an int value to accomodate at least 16 bits so this + * works and allows the compiler not to worry about possible narrowing + * on 32 bit systems. (Pre-ANSI systems did not make integers smaller + * than 16 bits either.) + */ + unsigned int val = + ((unsigned int)(*buf) << 8) + + ((unsigned int)(*(buf + 1))); + + return (png_uint_16)val; +} + +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ + +/* Read and check the PNG file signature */ +void /* PRIVATE */ +png_read_sig(png_structp png_ptr, png_infop info_ptr) +{ + png_size_t num_checked, num_to_check; + + /* Exit if the user application does not expect a signature. */ + if (png_ptr->sig_bytes >= 8) + return; + + num_checked = png_ptr->sig_bytes; + num_to_check = 8 - num_checked; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; +#endif + + /* The signature must be serialized in a single I/O call. */ + 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; +} + +/* Read the chunk header (length + type name). + * Put the type name into png_ptr->chunk_name, and return the length. + */ +png_uint_32 /* PRIVATE */ +png_read_chunk_header(png_structp png_ptr) +{ + png_byte buf[8]; + png_uint_32 length; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; +#endif + + /* Read the length and the chunk name. + * This must be performed in a single I/O call. + */ + png_read_data(png_ptr, buf, 8); + length = png_get_uint_31(png_ptr, buf); + + /* Put the chunk name into png_ptr->chunk_name. */ + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); + + png_debug2(0, "Reading %lx chunk, length = %lu", + (unsigned long)png_ptr->chunk_name, (unsigned long)length); + + /* Reset the crc and run it over the chunk name. */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, buf + 4, 4); + + /* Check to see if chunk name is valid. */ + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; +#endif + + return length; +} + +/* 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_CHUNK_ANCILLIARY(png_ptr->chunk_name) ? + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) + { + png_chunk_warning(png_ptr, "CRC error"); + } + + else + { + png_chunk_benign_error(png_ptr, "CRC error"); + return (0); + } + + 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_CHUNK_ANCILLIARY(png_ptr->chunk_name)) + { + 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; + } + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; +#endif + + /* The chunk CRC must be serialized in a single I/O call. */ + 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); +} + +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +static png_size_t +png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, + png_bytep output, png_size_t output_size) +{ + png_size_t count = 0; + + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't + * even necessarily handle 65536 bytes) because the type uInt is "16 bits or + * more". Consequently it is necessary to chunk the input to zlib. This + * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value + * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a + * lower value in pngpriv.h and this may sometimes have a performance + * advantage, because it forces access of the input data to be separated from + * at least some of the use by some period of time. + */ + png_ptr->zstream.next_in = data; + /* avail_in is set below from 'size' */ + png_ptr->zstream.avail_in = 0; + + while (1) + { + int ret, avail; + + /* The setting of 'avail_in' used to be outside the loop; by setting it + * inside it is possible to chunk the input to zlib and simply rely on + * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o + * data to be passed through zlib at the unavoidable cost of requiring a + * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX + * input bytes. + */ + if (png_ptr->zstream.avail_in == 0 && size > 0) + { + if (size <= ZLIB_IO_MAX) + { + /* The value is less than ZLIB_IO_MAX so the cast is safe: */ + png_ptr->zstream.avail_in = (uInt)size; + size = 0; + } + + else + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + size -= ZLIB_IO_MAX; + } + } + + /* Reset the output buffer each time round - we empty it + * after every inflate call. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = png_ptr->zbuf_size; + + ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; + + /* First copy/count any new output - but only if we didn't + * get an error code. + */ + if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) + { + png_size_t space = avail; /* > 0, see above */ + + if (output != 0 && output_size > count) + { + png_size_t copy = output_size - count; + + if (space < copy) + copy = space; + + png_memcpy(output + count, png_ptr->zbuf, copy); + } + count += space; + } + + if (ret == Z_OK) + continue; + + /* Termination conditions - always reset the zstream, it + * must be left in inflateInit state. + */ + png_ptr->zstream.avail_in = 0; + inflateReset(&png_ptr->zstream); + + if (ret == Z_STREAM_END) + return count; /* NOTE: may be zero. */ + + /* Now handle the error codes - the API always returns 0 + * and the error message is dumped into the uncompressed + * buffer if available. + */ +# ifdef PNG_WARNINGS_SUPPORTED + { + png_const_charp msg; + + if (png_ptr->zstream.msg != 0) + msg = png_ptr->zstream.msg; + + else switch (ret) + { + case Z_BUF_ERROR: + msg = "Buffer error in compressed datastream"; + break; + + case Z_DATA_ERROR: + msg = "Data error in compressed datastream"; + break; + + default: + msg = "Incomplete compressed datastream"; + break; + } + + png_chunk_warning(png_ptr, msg); + } +# endif + + /* 0 means an error - notice that this code simply ignores + * zero length compressed chunks as a result. + */ + return 0; + } +} + +/* + * 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). + */ +void /* PRIVATE */ +png_decompress_chunk(png_structp png_ptr, int comp_type, + png_size_t chunklength, + png_size_t prefix_size, png_size_t *newlength) +{ + /* The caller should guarantee this */ + if (prefix_size > chunklength) + { + /* The recovery is to delete the chunk. */ + png_warning(png_ptr, "invalid chunklength"); + prefix_size = 0; /* To delete everything */ + } + + else if (comp_type == PNG_COMPRESSION_TYPE_BASE) + { + png_size_t expanded_size = png_inflate(png_ptr, + (png_bytep)(png_ptr->chunkdata + prefix_size), + chunklength - prefix_size, + 0, /* output */ + 0); /* output size */ + + /* Now check the limits on this chunk - if the limit fails the + * compressed data will be removed, the prefix will remain. + */ + if (prefix_size >= (~(png_size_t)0) - 1 || + expanded_size >= (~(png_size_t)0) - 1 - prefix_size +#ifdef PNG_USER_LIMITS_SUPPORTED + || (png_ptr->user_chunk_malloc_max && + (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) +#else + || ((PNG_USER_CHUNK_MALLOC_MAX > 0) && + prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) +#endif + ) + png_warning(png_ptr, "Exceeded size limit while expanding chunk"); + + /* If the size is zero either there was an error and a message + * has already been output (warning) or the size really is zero + * and we have nothing to do - the code will exit through the + * error case below. + */ + else if (expanded_size > 0) + { + /* Success (maybe) - really uncompress the chunk. */ + png_size_t new_size = 0; + png_charp text = (png_charp)png_malloc_warn(png_ptr, + prefix_size + expanded_size + 1); + + if (text != NULL) + { + png_memcpy(text, png_ptr->chunkdata, prefix_size); + new_size = png_inflate(png_ptr, + (png_bytep)(png_ptr->chunkdata + prefix_size), + chunklength - prefix_size, + (png_bytep)(text + prefix_size), expanded_size); + text[prefix_size + expanded_size] = 0; /* just in case */ + + if (new_size == expanded_size) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = text; + *newlength = prefix_size + expanded_size; + return; /* The success return! */ + } + + png_warning(png_ptr, "png_inflate logic error"); + png_free(png_ptr, text); + } + + else + png_warning(png_ptr, "Not enough memory to decompress chunk"); + } + } + + else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ + { + PNG_WARNING_PARAMETERS(p) + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); + png_formatted_warning(png_ptr, p, "Unknown compression type @1"); + + /* The recovery is to simply drop the data. */ + } + + /* Generic error return - leave the prefix, delete the compressed + * data, reallocate the chunkdata to remove the potentially large + * amount of compressed data. + */ + { + png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1); + + if (text != NULL) + { + if (prefix_size > 0) + png_memcpy(text, png_ptr->chunkdata, prefix_size); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = text; + + /* This is an extra zero in the 'uncompressed' part. */ + *(png_ptr->chunkdata + prefix_size) = 0x00; + } + /* Ignore a malloc error here - it is safe. */ + } + + *newlength = prefix_size; +} +#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ + +/* 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"); + + 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; +#ifdef 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) + { + default: /* invalid, png_set_IHDR calls png_error */ + 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", png_ptr->bit_depth); + png_debug1(3, "channels = %d", png_ptr->channels); + png_debug1(3, "rowbytes = %lu", (unsigned long)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; +#ifdef PNG_POINTER_INDEXING_SUPPORTED + png_colorp pal_ptr; +#endif + + png_debug(1, "in png_handle_PLTE"); + + 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; + } + +#ifndef 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; + +#ifdef PNG_POINTER_INDEXING_SUPPORTED + 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. + */ +#ifndef PNG_READ_OPT_PLTE_SUPPORTED + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#endif + { + png_crc_finish(png_ptr, 0); + } + +#ifndef 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_benign_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); + +#ifdef 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"); + + 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); + + PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ +} + +#ifdef 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; + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA"); + + 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) +#ifdef 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_get_fixed_point(NULL, buf); + + /* Check for zero gamma or an error. */ + if (igamma <= 0) + { + png_warning(png_ptr, + "Ignoring gAMA chunk with out of range gamma"); + + return; + } + +# ifdef PNG_READ_sRGB_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(igamma, 45500, 500)) + { + PNG_WARNING_PARAMETERS(p) + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); + png_formatted_warning(png_ptr, p, + "Ignoring incorrect gAMA value @1 when sRGB is also present"); + return; + } + } +# endif /* PNG_READ_sRGB_SUPPORTED */ + +# ifdef PNG_READ_GAMMA_SUPPORTED + /* Gamma correction on read is supported. */ + png_ptr->gamma = igamma; +# endif + /* And set the 'info' structure members. */ + png_set_gAMA_fixed(png_ptr, info_ptr, igamma); +} +#endif + +#ifdef 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"); + + 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 + +#ifdef PNG_READ_cHRM_SUPPORTED +void /* PRIVATE */ +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[32]; + png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, + y_blue; + + png_debug(1, "in png_handle_cHRM"); + + 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, "Out of place cHRM chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) +# ifdef 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, 32); + + if (png_crc_finish(png_ptr, 0)) + return; + + x_white = png_get_fixed_point(NULL, buf); + y_white = png_get_fixed_point(NULL, buf + 4); + x_red = png_get_fixed_point(NULL, buf + 8); + y_red = png_get_fixed_point(NULL, buf + 12); + x_green = png_get_fixed_point(NULL, buf + 16); + y_green = png_get_fixed_point(NULL, buf + 20); + x_blue = png_get_fixed_point(NULL, buf + 24); + y_blue = png_get_fixed_point(NULL, buf + 28); + + if (x_white == PNG_FIXED_ERROR || + y_white == PNG_FIXED_ERROR || + x_red == PNG_FIXED_ERROR || + y_red == PNG_FIXED_ERROR || + x_green == PNG_FIXED_ERROR || + y_green == PNG_FIXED_ERROR || + x_blue == PNG_FIXED_ERROR || + y_blue == PNG_FIXED_ERROR) + { + png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); + return; + } + +#ifdef PNG_READ_sRGB_SUPPORTED + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(x_red, 64000, 1000) || + PNG_OUT_OF_RANGE(y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(y_green, 60000, 1000) || + PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); + png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); + png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); + png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); + png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); + png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); + png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); + + png_formatted_warning(png_ptr, p, + "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " + "when sRGB is also present"); + } + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Store the _white values as default coefficients for the rgb to gray + * operation if it is supported. Check if the transform is already set to + * avoid destroying the transform values. + */ + if (!png_ptr->rgb_to_gray_coefficients_set) + { + /* png_set_background has not been called and we haven't seen an sRGB + * chunk yet. Find the XYZ of the three end points. + */ + png_XYZ XYZ; + png_xy xy; + + xy.redx = x_red; + xy.redy = y_red; + xy.greenx = x_green; + xy.greeny = y_green; + xy.bluex = x_blue; + xy.bluey = y_blue; + xy.whitex = x_white; + xy.whitey = y_white; + + if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) + { + /* The success case, because XYZ_from_xy normalises to a reference + * white Y of 1.0 we just need to scale the numbers. This should + * always work just fine. It is an internal error if this overflows. + */ + { + png_fixed_point r, g, b; + if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) && + r >= 0 && r <= 32768 && + png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) && + g >= 0 && g <= 32768 && + png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) && + b >= 0 && b <= 32768 && + r+g+b <= 32769) + { + /* We allow 0 coefficients here. r+g+b may be 32769 if two or + * all of the coefficients were rounded up. Handle this by + * reducing the *largest* coefficient by 1; this matches the + * approach used for the default coefficients in pngrtran.c + */ + int add = 0; + + if (r+g+b > 32768) + add = -1; + else if (r+g+b < 32768) + add = 1; + + if (add != 0) + { + if (g >= r && g >= b) + g += add; + else if (r >= g && r >= b) + r += add; + else + b += add; + } + + /* Check for an internal error. */ + if (r+g+b != 32768) + png_error(png_ptr, + "internal error handling cHRM coefficients"); + + png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; + png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; + } + + /* This is a png_error at present even though it could be ignored - + * it should never happen, but it is important that if it does, the + * bug is fixed. + */ + else + png_error(png_ptr, "internal error handling cHRM->XYZ"); + } + } + } +#endif + + png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, + x_green, y_green, x_blue, y_blue); +} +#endif + +#ifdef 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"); + + 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)) + { + if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, + info_ptr->gamma); + + png_formatted_warning(png_ptr, p, + "Ignoring incorrect gAMA value @1 when sRGB is also present"); + } + } +#endif /* PNG_READ_gAMA_SUPPORTED */ + +#ifdef PNG_READ_cHRM_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + } +#endif /* PNG_READ_cHRM_SUPPORTED */ + + /* This is recorded for use when handling the cHRM chunk above. An sRGB + * chunk unconditionally overwrites the coefficients for grayscale conversion + * too. + */ + png_ptr->is_sRGB = 1; + +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Don't overwrite user supplied values: */ + if (!png_ptr->rgb_to_gray_coefficients_set) + { + /* These numbers come from the sRGB specification (or, since one has to + * pay much money to get a copy, the wikipedia sRGB page) the + * chromaticity values quoted have been inverted to get the reverse + * transformation from RGB to XYZ and the 'Y' coefficients scaled by + * 32768 (then rounded). + * + * sRGB and ITU Rec-709 both truncate the values for the D65 white + * point to four digits and, even though it actually stores five + * digits, the PNG spec gives the truncated value. + * + * This means that when the chromaticities are converted back to XYZ + * end points we end up with (6968,23435,2366), which, as described in + * pngrtran.c, would overflow. If the five digit precision and up is + * used we get, instead: + * + * 6968*R + 23435*G + 2365*B + * + * (Notice that this rounds the blue coefficient down, rather than the + * choice used in pngrtran.c which is to round the green one down.) + */ + png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */ + png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */ + /* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */ + + /* The following keeps the cHRM chunk from destroying the + * coefficients again in the event that it follows the sRGB chunk. + */ + png_ptr->rgb_to_gray_coefficients_set = 1; + } +# endif + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef 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_byte compression_type; + png_bytep pC; + png_charp profile; + png_uint_32 skip = 0; + png_uint_32 profile_size; + png_alloc_size_t profile_length; + png_size_t slength, prefix_length, data_length; + + png_debug(1, "in png_handle_iCCP"); + + 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 ((png_ptr->mode & PNG_HAVE_iCCP) || (info_ptr != NULL && + (info_ptr->valid & (PNG_INFO_iCCP|PNG_INFO_sRGB)))) + { + png_warning(png_ptr, "Duplicate iCCP chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_ptr->mode |= PNG_HAVE_iCCP; + +#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 + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (profile = png_ptr->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 >= png_ptr->chunkdata + slength - 1) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + 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 - png_ptr->chunkdata; + png_decompress_chunk(png_ptr, compression_type, + slength, prefix_length, &data_length); + + profile_length = data_length - prefix_length; + + if (prefix_length > data_length || profile_length < 4) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + 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)(png_ptr->chunkdata + prefix_length); + profile_size = ((*(pC )) << 24) | + ((*(pC + 1)) << 16) | + ((*(pC + 2)) << 8) | + ((*(pC + 3)) ); + + /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, + * because profile_size is a 32 bit value. + */ + if (profile_size < profile_length) + profile_length = profile_size; + + /* And the following guarantees that profile_size == profile_length. */ + if (profile_size > profile_length) + { + PNG_WARNING_PARAMETERS(p) + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); + png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); + png_formatted_warning(png_ptr, p, + "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); + return; + } + + png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, + compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, + profile_size); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef 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 entry_start; + png_sPLT_t new_palette; + png_sPLT_entryp pp; + png_uint_32 data_length; + int entry_size, i; + png_uint_32 skip = 0; + png_size_t slength; + png_uint_32 dl; + png_size_t max_dl; + + png_debug(1, "in png_handle_sPLT"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for sPLT"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + 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 + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + + /* WARNING: this may break if size_t is less than 32 bits; it is assumed + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a + * potential breakage point if the types in pngconf.h aren't exactly right. + */ + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (entry_start = (png_bytep)png_ptr->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 > (png_bytep)png_ptr->chunkdata + slength - 2) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "malformed sPLT chunk"); + return; + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + /* This must fit in a png_uint_32 because it is derived from the original + * chunk data length (and use 'length', not 'slength' here for clarity - + * they are guaranteed to be the same, see the tests above.) + */ + data_length = length - (png_uint_32)(entry_start - + (png_bytep)png_ptr->chunkdata); + + /* Integrity-check the data length */ + if (data_length % entry_size) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + dl = (png_int_32)(data_length / entry_size); + max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); + + if (dl > max_dl) + { + png_warning(png_ptr, "sPLT chunk too long"); + return; + } + + new_palette.nentries = (png_int_32)(data_length / entry_size); + + 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; + } + +#ifdef PNG_POINTER_INDEXING_SUPPORTED + for (i = 0; i < new_palette.nentries; i++) + { + 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[i].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_ptr->chunkdata; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef 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]; + + png_debug(1, "in png_handle_tRNS"); + + 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_color.gray = png_get_uint_16(buf); + } + + 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_color.red = png_get_uint_16(buf); + png_ptr->trans_color.green = png_get_uint_16(buf + 2); + png_ptr->trans_color.blue = png_get_uint_16(buf + 4); + } + + 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_color)); +} +#endif + +#ifdef 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_color_16 background; + + png_debug(1, "in png_handle_bKGD"); + + 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) + { + background.index = buf[0]; + + if (info_ptr && info_ptr->num_palette) + { + if (buf[0] >= info_ptr->num_palette) + { + png_warning(png_ptr, "Incorrect bKGD chunk index value"); + return; + } + + background.red = (png_uint_16)png_ptr->palette[buf[0]].red; + background.green = (png_uint_16)png_ptr->palette[buf[0]].green; + background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; + } + + else + background.red = background.green = background.blue = 0; + + background.gray = 0; + } + + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ + { + background.index = 0; + background.red = + background.green = + background.blue = + background.gray = png_get_uint_16(buf); + } + + else + { + background.index = 0; + background.red = png_get_uint_16(buf); + background.green = png_get_uint_16(buf + 2); + background.blue = png_get_uint_16(buf + 4); + background.gray = 0; + } + + png_set_bKGD(png_ptr, info_ptr, &background); +} +#endif + +#ifdef 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"); + + 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; + } + + if (length > 2*PNG_MAX_PALETTE_LENGTH || + length != (unsigned int) (2*png_ptr->num_palette)) + { + png_warning(png_ptr, "Incorrect hIST chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + num = length / 2 ; + + 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 + +#ifdef 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"); + + 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 + +#ifdef 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"); + + 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 + +#ifdef 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_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"); + + 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 (%u bytes)", + length + 1); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory for pCAL purpose"); + return; + } + + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string"); + for (buf = png_ptr->chunkdata; *buf; buf++) + /* Empty loop */ ; + + endptr = png_ptr->chunkdata + 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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); + 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"); + /* 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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + 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"); + + params = (png_charpp)png_malloc_warn(png_ptr, + (png_size_t)(nparams * png_sizeof(png_charp))); + + if (params == NULL) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + 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", 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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, params); + return; + } + } + + png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, + units, params); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, params); +} +#endif + +#ifdef 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_size_t slength, i; + int state; + + png_debug(1, "in png_handle_sCAL"); + + 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; + } + + /* Need unit type, width, \0, height: minimum 4 bytes */ + else if (length < 4) + { + png_warning(png_ptr, "sCAL chunk too short"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", + length + 1); + + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + /* Validate the unit. */ + if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) + { + png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + /* Validate the ASCII numbers, need two ASCII numbers separated by + * a '\0' and they need to fit exactly in the chunk data. + */ + i = 1; + state = 0; + + if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || + i >= slength || png_ptr->chunkdata[i++] != 0) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); + + else + { + png_size_t heighti = i; + + state = 0; + if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || + i != slength) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_warning(png_ptr, + "Invalid sCAL chunk ignored: non-positive height"); + + else + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], + png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); + } + + /* Clean up - just free the temporarily allocated buffer. */ + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; +} +#endif + +#ifdef 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"); + + 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 + +#ifdef 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"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for tEXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + 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 + + png_free(png_ptr, png_ptr->chunkdata); + + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process text chunk"); + return; + } + + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + key = png_ptr->chunkdata; + + 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_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process text chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; + 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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to process text chunk"); +} +#endif + +#ifdef 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 text; + int comp_type; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_zTXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for zTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + 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 + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "Out of memory processing zTXt chunk"); + return; + } + + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (text = png_ptr->chunkdata; *text; text++) + /* Empty loop */ ; + + /* zTXt must have some text after the chunkdataword */ + if (text >= png_ptr->chunkdata + slength - 2) + { + png_warning(png_ptr, "Truncated zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + 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 - png_ptr->chunkdata; + + png_decompress_chunk(png_ptr, comp_type, + (png_size_t)length, prefix_len, &data_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + png_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = comp_type; + text_ptr->key = png_ptr->chunkdata; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; + text_ptr->text = png_ptr->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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + if (ret) + png_error(png_ptr, "Insufficient memory to store zTXt chunk"); +} +#endif + +#ifdef 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 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"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for iTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + 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 + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process iTXt chunk"); + return; + } + + slength = length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (lang = png_ptr->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 >= png_ptr->chunkdata + slength - 3) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + else + { + comp_flag = *lang++; + comp_type = *lang++; + } + + if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt)) + { + png_warning(png_ptr, "Unknown iTXt compression type or method"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + for (lang_key = lang; *lang_key; lang_key++) + /* Empty loop */ ; + + lang_key++; /* Skip NUL separator */ + + if (lang_key >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + for (text = lang_key; *text; text++) + /* Empty loop */ ; + + text++; /* Skip NUL separator */ + + if (text >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Malformed iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + prefix_len = text - png_ptr->chunkdata; + + key=png_ptr->chunkdata; + + if (comp_flag) + png_decompress_chunk(png_ptr, comp_type, + (size_t)length, prefix_len, &data_len); + + else + data_len = png_strlen(png_ptr->chunkdata + prefix_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + png_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = (int)comp_flag + 1; + text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); + text_ptr->lang = png_ptr->chunkdata + (lang - key); + text_ptr->itxt_length = data_len; + text_ptr->text_length = 0; + text_ptr->key = png_ptr->chunkdata; + text_ptr->text = png_ptr->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, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + 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"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for unknown chunk"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (png_ptr->mode & PNG_HAVE_IDAT) + { + if (png_ptr->chunk_name != png_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + } + + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + { +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + || (png_ptr->read_user_chunk_fn != NULL) +#endif + ) + { +#ifdef PNG_MAX_MALLOC_64K + if (length > 65535) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - 65535; + length = 65535; + } +#endif + + /* TODO: this code is very close to the unknown handling in pngpread.c, + * maybe it can be put into a common utility routine? + * png_struct::unknown_chunk is just used as a temporary variable, along + * with the data into which the chunk is read. These can be eliminated. + */ + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + png_ptr->unknown_chunk.size = (png_size_t)length; + + if (length == 0) + png_ptr->unknown_chunk.data = NULL; + + else + { + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); + } + +#ifdef 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_CHUNK_CRITICAL(png_ptr->chunk_name)) + { +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } + + else +#endif + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + + 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); + +#ifndef PNG_READ_USER_CHUNKS_SUPPORTED + PNG_UNUSED(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. + */ + +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: + * + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + */ + +void /* PRIVATE */ +png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) +{ + int i; + + png_debug(1, "in png_check_chunk_name"); + + for (i=1; i<=4; ++i) + { + int c = chunk_name & 0xff; + + if (c < 65 || c > 122 || (c > 90 && c < 97)) + png_chunk_error(png_ptr, "invalid chunk type"); + + chunk_name >>= 8; + } +} + +/* 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 'display' value; if 'display' is true then the whole row + * (dp) is filled from the start by replicating the available pixels. If + * 'display' is false only those pixels present in the pass are filled in. + */ +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep dp, int display) +{ + unsigned int pixel_depth = png_ptr->transformed_pixel_depth; + png_const_bytep sp = png_ptr->row_buf + 1; + png_uint_32 row_width = png_ptr->width; + unsigned int pass = png_ptr->pass; + png_bytep end_ptr = 0; + png_byte end_byte = 0; + unsigned int end_mask; + + png_debug(1, "in png_combine_row"); + + /* Added in 1.5.6: it should not be possible to enter this routine until at + * least one row has been read from the PNG data and transformed. + */ + if (pixel_depth == 0) + png_error(png_ptr, "internal row logic error"); + + /* Added in 1.5.4: the pixel depth should match the information returned by + * any call to png_read_update_info at this point. Do not continue if we got + * this wrong. + */ + if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != + PNG_ROWBYTES(pixel_depth, row_width)) + png_error(png_ptr, "internal row size calculation error"); + + /* Don't expect this to ever happen: */ + if (row_width == 0) + png_error(png_ptr, "internal row width error"); + + /* Preserve the last byte in cases where only part of it will be overwritten, + * the multiply below may overflow, we don't care because ANSI-C guarantees + * we get the low bits. + */ + end_mask = (pixel_depth * row_width) & 7; + if (end_mask != 0) + { + /* end_ptr == NULL is a flag to say do nothing */ + end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; + end_byte = *end_ptr; +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */ + end_mask = 0xff << end_mask; + + else /* big-endian byte */ +# endif + end_mask = 0xff >> end_mask; + /* end_mask is now the bits to *keep* from the destination row */ + } + + /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy() + * will also happen if interlacing isn't supported or if the application + * does not call png_set_interlace_handling(). In the latter cases the + * caller just gets a sequence of the unexpanded rows from each interlace + * pass. + */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) && + pass < 6 && (display == 0 || + /* The following copies everything for 'display' on passes 0, 2 and 4. */ + (display == 1 && (pass & 1) != 0))) + { + /* Narrow images may have no bits in a pass; the caller should handle + * this, but this test is cheap: + */ + if (row_width <= PNG_PASS_START_COL(pass)) + return; + + if (pixel_depth < 8) + { + /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit + * into 32 bits, then a single loop over the bytes using the four byte + * values in the 32-bit mask can be used. For the 'display' option the + * expanded mask may also not require any masking within a byte. To + * make this work the PACKSWAP option must be taken into account - it + * simply requires the pixels to be reversed in each byte. + * + * The 'regular' case requires a mask for each of the first 6 passes, + * the 'display' case does a copy for the even passes in the range + * 0..6. This has already been handled in the test above. + * + * The masks are arranged as four bytes with the first byte to use in + * the lowest bits (little-endian) regardless of the order (PACKSWAP or + * not) of the pixels in each byte. + * + * NOTE: the whole of this logic depends on the caller of this function + * only calling it on rows appropriate to the pass. This function only + * understands the 'x' logic; the 'y' logic is handled by the caller. + * + * The following defines allow generation of compile time constant bit + * masks for each pixel depth and each possibility of swapped or not + * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, + * is in the range 0..7; and the result is 1 if the pixel is to be + * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' + * for the block method. + * + * With some compilers a compile time expression of the general form: + * + * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) + * + * Produces warnings with values of 'shift' in the range 33 to 63 + * because the right hand side of the ?: expression is evaluated by + * the compiler even though it isn't used. Microsoft Visual C (various + * versions) and the Intel C compiler are known to do this. To avoid + * this the following macros are used in 1.5.6. This is a temporary + * solution to avoid destabilizing the code during the release process. + */ +# if PNG_USE_COMPILE_TIME_MASKS +# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) +# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) +# else +# define PNG_LSR(x,s) ((x)>>(s)) +# define PNG_LSL(x,s) ((x)<<(s)) +# endif +# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) +# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) + + /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is + * little endian - the first pixel is at bit 0 - however the extra + * parameter 's' can be set to cause the mask position to be swapped + * within each byte, to match the PNG format. This is done by XOR of + * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. + */ +# define PIXEL_MASK(p,x,d,s) \ + (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) + + /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. + */ +# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) +# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) + + /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp + * cases the result needs replicating, for the 4-bpp case the above + * generates a full 32 bits. + */ +# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) + +# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ + S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ + S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) + +# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ + B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ + B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) + +#if PNG_USE_COMPILE_TIME_MASKS + /* Utility macros to construct all the masks for a depth/swap + * combination. The 's' parameter says whether the format is PNG + * (big endian bytes) or not. Only the three odd-numbered passes are + * required for the display/block algorithm. + */ +# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ + S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } + +# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) } + +# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) + + /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and + * then pass: + */ + static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + { + /* Little-endian byte masks for PACKSWAP */ + { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } + }; + + /* display_mask has only three entries for the odd passes, so index by + * pass>>1. + */ + static PNG_CONST png_uint_32 display_mask[2][3][3] = + { + /* Little-endian byte masks for PACKSWAP */ + { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } + }; + +# define MASK(pass,depth,display,png)\ + ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ + row_mask[png][DEPTH_INDEX(depth)][pass]) + +#else /* !PNG_USE_COMPILE_TIME_MASKS */ + /* This is the runtime alternative: it seems unlikely that this will + * ever be either smaller or faster than the compile time approach. + */ +# define MASK(pass,depth,display,png)\ + ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) +#endif /* !PNG_USE_COMPILE_TIME_MASKS */ + + /* Use the appropriate mask to copy the required bits. In some cases + * the byte mask will be 0 or 0xff, optimize these cases. row_width is + * the number of pixels, but the code copies bytes, so it is necessary + * to special case the end. + */ + png_uint_32 pixels_per_byte = 8 / pixel_depth; + png_uint_32 mask; + +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + mask = MASK(pass, pixel_depth, display, 0); + + else +# endif + mask = MASK(pass, pixel_depth, display, 1); + + for (;;) + { + png_uint_32 m; + + /* It doesn't matter in the following if png_uint_32 has more than + * 32 bits because the high bits always match those in m<<24; it is, + * however, essential to use OR here, not +, because of this. + */ + m = mask; + mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ + m &= 0xff; + + if (m != 0) /* something to copy */ + { + if (m != 0xff) + *dp = (png_byte)((*dp & ~m) | (*sp & m)); + else + *dp = *sp; + } + + /* NOTE: this may overwrite the last byte with garbage if the image + * is not an exact number of bytes wide; libpng has always done + * this. + */ + if (row_width <= pixels_per_byte) + break; /* May need to restore part of the last byte */ + + row_width -= pixels_per_byte; + ++dp; + ++sp; + } + } + + else /* pixel_depth >= 8 */ + { + unsigned int bytes_to_copy, bytes_to_jump; + + /* Validate the depth - it must be a multiple of 8 */ + if (pixel_depth & 7) + png_error(png_ptr, "invalid user transform pixel depth"); + + pixel_depth >>= 3; /* now in bytes */ + row_width *= pixel_depth; + + /* Regardless of pass number the Adam 7 interlace always results in a + * fixed number of pixels to copy then to skip. There may be a + * different number of pixels to skip at the start though. + */ + { + unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; + + row_width -= offset; + dp += offset; + sp += offset; + } + + /* Work out the bytes to copy. */ + if (display) + { + /* When doing the 'block' algorithm the pixel in the pass gets + * replicated to adjacent pixels. This is why the even (0,2,4,6) + * passes are skipped above - the entire expanded row is copied. + */ + bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; + + /* But don't allow this number to exceed the actual row width. */ + if (bytes_to_copy > row_width) + bytes_to_copy = row_width; + } + + else /* normal row; Adam7 only ever gives us one pixel to copy. */ + bytes_to_copy = pixel_depth; + + /* In Adam7 there is a constant offset between where the pixels go. */ + bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; + + /* And simply copy these bytes. Some optimization is possible here, + * depending on the value of 'bytes_to_copy'. Special case the low + * byte counts, which we know to be frequent. + * + * Notice that these cases all 'return' rather than 'break' - this + * avoids an unnecessary test on whether to restore the last byte + * below. + */ + switch (bytes_to_copy) + { + case 1: + for (;;) + { + *dp = *sp; + + if (row_width <= bytes_to_jump) + return; + + dp += bytes_to_jump; + sp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + case 2: + /* There is a possibility of a partial copy at the end here; this + * slows the code down somewhat. + */ + do + { + dp[0] = sp[0], dp[1] = sp[1]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + while (row_width > 1); + + /* And there can only be one byte left at this point: */ + *dp = *sp; + return; + + case 3: + /* This can only be the RGB case, so each copy is exactly one + * pixel and it is not necessary to check for a partial copy. + */ + for(;;) + { + dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + default: +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE + /* Check for double byte alignment and, if possible, use a + * 16-bit copy. Don't attempt this for narrow images - ones that + * are less than an interlace panel wide. Don't attempt it for + * wide bytes_to_copy either - use the png_memcpy there. + */ + if (bytes_to_copy < 16 /*else use png_memcpy*/ && + png_isaligned(dp, png_uint_16) && + png_isaligned(sp, png_uint_16) && + bytes_to_copy % sizeof (png_uint_16) == 0 && + bytes_to_jump % sizeof (png_uint_16) == 0) + { + /* Everything is aligned for png_uint_16 copies, but try for + * png_uint_32 first. + */ + if (png_isaligned(dp, png_uint_32) && + png_isaligned(sp, png_uint_32) && + bytes_to_copy % sizeof (png_uint_32) == 0 && + bytes_to_jump % sizeof (png_uint_32) == 0) + { + png_uint_32p dp32 = (png_uint_32p)dp; + png_const_uint_32p sp32 = (png_const_uint_32p)sp; + unsigned int skip = (bytes_to_jump-bytes_to_copy) / + sizeof (png_uint_32); + + do + { + size_t c = bytes_to_copy; + do + { + *dp32++ = *sp32++; + c -= sizeof (png_uint_32); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp32 += skip; + sp32 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* Get to here when the row_width truncates the final copy. + * There will be 1-3 bytes left to copy, so don't try the + * 16-bit loop below. + */ + dp = (png_bytep)dp32; + sp = (png_const_bytep)sp32; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + + /* Else do it in 16-bit quantities, but only if the size is + * not too large. + */ + else + { + png_uint_16p dp16 = (png_uint_16p)dp; + png_const_uint_16p sp16 = (png_const_uint_16p)sp; + unsigned int skip = (bytes_to_jump-bytes_to_copy) / + sizeof (png_uint_16); + + do + { + size_t c = bytes_to_copy; + do + { + *dp16++ = *sp16++; + c -= sizeof (png_uint_16); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp16 += skip; + sp16 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* End of row - 1 byte left, bytes_to_copy > row_width: */ + dp = (png_bytep)dp16; + sp = (png_const_bytep)sp16; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + } +#endif /* PNG_ALIGN_ code */ + + /* The true default - use a png_memcpy: */ + for (;;) + { + png_memcpy(dp, sp, bytes_to_copy); + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + if (bytes_to_copy > row_width) + bytes_to_copy = row_width; + } + } + + /* NOT REACHED*/ + } /* pixel_depth >= 8 */ + + /* Here if pixel_depth < 8 to check 'end_ptr' below. */ + } + else +#endif + + /* If here then the switch above wasn't used so just png_memcpy the whole row + * from the temporary row buffer (notice that this overwrites the end of the + * destination row if it is a partial byte.) + */ + png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); + + /* Restore the overwritten bits from the last byte if necessary. */ + if (end_ptr != NULL) + *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void /* PRIVATE */ +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations /* Because these may affect the byte layout */) +{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Offset to next interlace block */ + static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_read_interlace"); + 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; + +#ifdef 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; + +#ifdef 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]; + +#ifdef 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) & 0x0f); + 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); + } +#ifndef PNG_READ_PACKSWAP_SUPPORTED + PNG_UNUSED(transformations) /* Silence compiler warning */ +#endif +} +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +static void +png_read_filter_row_sub(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + + PNG_UNUSED(prev_row) + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_up(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + png_bytep rp = row; + png_const_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_avg(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_bytep rp = row; + png_const_bytep pp = prev_row; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t 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++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +static void +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp_end = row + row_info->rowbytes; + int a, c; + + /* First pixel/byte */ + c = *prev_row++; + a = *row + c; + *row++ = (png_byte)a; + + /* Remainder */ + while (row < rp_end) + { + int b, pa, pb, pc, p; + + a &= 0xff; /* From previous iteration or start */ + b = *prev_row++; + + 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 + + /* Find the best predictor, the least of pa, pb, pc favoring the earlier + * ones in the case of a tie. + */ + if (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + /* Calculate the current pixel in a, and move the previous row pixel to c + * for the next time round the loop + */ + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp_end = row + bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + while (row < rp_end) + { + int a = *row + *prev_row++; + *row++ = (png_byte)a; + } + + /* Remainder */ + rp_end += row_info->rowbytes - bpp; + + while (row < rp_end) + { + int a, b, c, pa, pb, pc, p; + + c = *(prev_row - bpp); + a = *(row - bpp); + b = *prev_row++; + + 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 (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +#ifdef PNG_ARM_NEON + +#if defined __linux__ && !defined __ANDROID__ +#include +#include +#include + +static int png_have_hwcap(unsigned cap) +{ + FILE *f = fopen("/proc/self/auxv", "r"); + Elf32_auxv_t aux; + int have_cap = 0; + + if (!f) + return 0; + + while (fread(&aux, sizeof(aux), 1, f) > 0) + { + if (aux.a_type == AT_HWCAP && + aux.a_un.a_val & cap) + { + have_cap = 1; + break; + } + } + + fclose(f); + + return have_cap; +} +#endif /* __linux__ */ + +static void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ +#if defined __linux__ && !defined __ANDROID__ + if (!png_have_hwcap(HWCAP_NEON)) + return; +#endif + + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_neon; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; + } +} +#endif /* PNG_ARM_NEON */ + +static void +png_init_filter_functions(png_structp pp) +{ + unsigned int bpp = (pp->pixel_depth + 7) >> 3; + + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; + if (bpp == 1) + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_1byte_pixel; + else + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_multibyte_pixel; + +#ifdef PNG_ARM_NEON + png_init_filter_functions_neon(pp, bpp); +#endif +} + +void /* PRIVATE */ +png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) +{ + if (pp->read_filter[0] == NULL) + png_init_filter_functions(pp); + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) + pp->read_filter[filter-1](row_info, row, prev_row); +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void /* PRIVATE */ +png_read_finish_row(png_structp png_ptr) +{ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + png_debug(1, "in png_read_finish_row"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + + /* TO DO: don't do this if prev_row isn't needed (requires + * read-ahead of the next row's filter byte. + */ + png_memset(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]; + + 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]; + } + + else /* if (png_ptr->transformations & PNG_INTERLACE) */ + break; /* libpng deinterlacing sees every row */ + + } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); + + if (png_ptr->pass < 7) + return; + } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { + 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_crc_finish(png_ptr, 0); + png_ptr->idat_size = png_read_chunk_header(png_ptr); + if (png_ptr->chunk_name != png_IDAT) + 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; +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +void /* PRIVATE */ +png_read_start_row(png_structp png_ptr) +{ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int max_pixel_depth; + png_size_t row_bytes; + + png_debug(1, "in png_read_start_row"); + png_ptr->zstream.avail_in = 0; +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_init_read_transformations(png_ptr); +#endif +#ifdef PNG_READ_INTERLACING_SUPPORTED + 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]; + } + + else +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; + } + + max_pixel_depth = png_ptr->pixel_depth; + + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of + * calculations to calculate the final pixel depth, then + * png_do_read_transforms actually does the transforms. This means that the + * code which effectively calculates this value is actually repeated in three + * separate places. They must all match. Innocent changes to the order of + * transformations can and will break libpng in a way that causes memory + * overwrites. + * + * TODO: fix this. + */ +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) + max_pixel_depth = 8; +#endif + +#ifdef 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 + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND_16) + { +# ifdef PNG_READ_EXPAND_SUPPORTED + /* In fact it is an error if it isn't supported, but checking is + * the safe way. + */ + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->bit_depth < 16) + max_pixel_depth *= 2; + } + else +# endif + png_ptr->transformations &= ~PNG_EXPAND_16; + } +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if (png_ptr->transformations & (PNG_FILLER)) + { + 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 || + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; + + else + max_pixel_depth = 64; + } + } +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if ( +#ifdef PNG_READ_EXPAND_SUPPORTED + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || +#endif +#ifdef 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 + + /* This value is stored in png_struct and double checked in the row read + * code. + */ + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ + + /* 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 + + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) + { + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + + if (png_ptr->interlaced) + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); + + else + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED + /* Use 16-byte aligned memory for row_buf with at least 16 bytes + * of padding before and after row_buf; treat prev_row similarly. + * NOTE: the alignment is to the start of the pixels, one beyond the start + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this + * was incorrect; the filter byte was aligned, which had the exact + * opposite effect of that intended. + */ + { + png_bytep temp = png_ptr->big_row_buf + 32; + int extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->row_buf = temp - extra - 1/*filter byte*/; + + temp = png_ptr->big_prev_row + 32; + extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->prev_row = temp - extra - 1/*filter byte*/; + } + +#else + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ + png_ptr->row_buf = png_ptr->big_row_buf + 31; + png_ptr->prev_row = png_ptr->big_prev_row + 31; +#endif + png_ptr->old_big_row_buf_size = row_bytes + 48; + } + +#ifdef PNG_MAX_MALLOC_64K + if (png_ptr->rowbytes > 65535) + png_error(png_ptr, "This image requires a row greater than 64KB"); + +#endif + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory"); + + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %u,", png_ptr->width); + png_debug1(3, "height = %u,", png_ptr->height); + png_debug1(3, "iwidth = %u,", png_ptr->iwidth); + png_debug1(3, "num_rows = %u,", png_ptr->num_rows); + png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); + png_debug1(3, "irowbytes = %lu", + (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* PNG_READ_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngset.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngset.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngset.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngset.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1311 @@ + +/* pngset.c - storage of image information into info struct + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#ifdef PNG_bKGD_SUPPORTED +void PNGAPI +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background) +{ + png_debug1(1, "in %s storage function", "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 + +#ifdef PNG_cHRM_SUPPORTED +void PNGFAPI +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", "cHRM fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +# ifdef PNG_CHECK_cHRM_SUPPORTED + if (png_check_cHRM_fixed(png_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) +# endif + { + info_ptr->x_white = white_x; + info_ptr->y_white = white_y; + info_ptr->x_red = red_x; + info_ptr->y_red = red_y; + info_ptr->x_green = green_x; + info_ptr->y_green = green_y; + info_ptr->x_blue = blue_x; + info_ptr->y_blue = blue_y; + info_ptr->valid |= PNG_INFO_cHRM; + } +} + +void PNGFAPI +png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z) +{ + png_XYZ XYZ; + png_xy xy; + + png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + XYZ.redX = int_red_X; + XYZ.redY = int_red_Y; + XYZ.redZ = int_red_Z; + XYZ.greenX = int_green_X; + XYZ.greenY = int_green_Y; + XYZ.greenZ = int_green_Z; + XYZ.blueX = int_blue_X; + XYZ.blueY = int_blue_Y; + XYZ.blueZ = int_blue_Z; + + if (png_xy_from_XYZ(&xy, XYZ)) + png_error(png_ptr, "XYZ values out of representable range"); + + png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy, + xy.greenx, xy.greeny, xy.bluex, xy.bluey); +} + +# 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_set_cHRM_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); +} + +void PNGAPI +png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X, + double red_Y, double red_Z, double green_X, double green_Y, double green_Z, + double blue_X, double blue_Y, double blue_Z) +{ + png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Red X"), + png_fixed(png_ptr, green_Y, "cHRM Red Y"), + png_fixed(png_ptr, green_Z, "cHRM Red Z"), + png_fixed(png_ptr, blue_X, "cHRM Red X"), + png_fixed(png_ptr, blue_Y, "cHRM Red Y"), + png_fixed(png_ptr, blue_Z, "cHRM Red Z")); +} +# endif /* PNG_FLOATING_POINT_SUPPORTED */ + +#endif /* PNG_cHRM_SUPPORTED */ + +#ifdef PNG_gAMA_SUPPORTED +void PNGFAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + file_gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't + * occur. Since the fixed point representation is assymetrical it is + * possible for 1/gamma to overflow the limit of 21474 and this means the + * gamma value must be at least 5/100000 and hence at most 20000.0. For + * safety the limits here are a little narrower. The values are 0.00016 to + * 6250.0, which are truly ridiculous gamma values (and will produce + * displays that are all black or all white.) + */ + if (file_gamma < 16 || file_gamma > 625000000) + png_warning(png_ptr, "Out of range gamma value ignored"); + + else + { + info_ptr->gamma = file_gamma; + info_ptr->valid |= PNG_INFO_gAMA; + } +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) +{ + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); +} +# endif +#endif + +#ifdef PNG_hIST_SUPPORTED +void PNGAPI +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) +{ + int i; + + png_debug1(1, "in %s storage function", "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; + } + + png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); + + /* 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_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; + info_ptr->free_me |= PNG_FREE_HIST; +} +#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", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + 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; + + png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_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 RRGGBBAA pixels */ + - 48 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + info_ptr->rowbytes = 0; + else + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); +} + +#ifdef 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", "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 + +#ifdef PNG_pCAL_SUPPORTED +void PNGAPI +png_set_pCAL(png_structp png_ptr, png_infop info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params) +{ + png_size_t length; + int i; + + png_debug1(1, "in %s storage function", "pCAL"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + length = png_strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)", + (unsigned long)length); + + /* TODO: validate format of calibration name and unit name */ + + /* Check that the type matches the specification. */ + if (type < 0 || type > 3) + png_error(png_ptr, "Invalid pCAL equation type"); + + /* Validate params[nparams] */ + for (i=0; ipcal_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, length); + + png_debug(3, "storing X0, X1, type, and nparams in info"); + 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)", + (unsigned long)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, length); + + info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, + (png_size_t)((nparams + 1) * png_sizeof(png_charp))); + + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params"); + return; + } + + png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); + + for (i = 0; i < nparams; i++) + { + length = png_strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, + (unsigned long)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], length); + } + + info_ptr->valid |= PNG_INFO_pCAL; + info_ptr->free_me |= PNG_FREE_PCAL; +} +#endif + +#ifdef PNG_sCAL_SUPPORTED +void PNGAPI +png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight) +{ + png_size_t lengthw = 0, lengthh = 0; + + png_debug1(1, "in %s storage function", "sCAL"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Double check the unit (should never get here with an invalid + * unit unless this is an API call.) + */ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + + if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || + swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || + sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + + info_ptr->scal_unit = (png_byte)unit; + + ++lengthw; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); + + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); + + if (info_ptr->scal_s_width == NULL) + { + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + return; + } + + png_memcpy(info_ptr->scal_s_width, swidth, lengthw); + + ++lengthh; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); + + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); + + if (info_ptr->scal_s_height == NULL) + { + png_free (png_ptr, info_ptr->scal_s_width); + info_ptr->scal_s_width = NULL; + + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + return; + } + + png_memcpy(info_ptr->scal_s_height, sheight, lengthh); + + info_ptr->valid |= PNG_INFO_sCAL; + info_ptr->free_me |= PNG_FREE_SCAL; +} + +# 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", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, + PNG_sCAL_PRECISION); + png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, + png_fixed_point width, png_fixed_point height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); + png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif +#endif + +#ifdef 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", "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_const_colorp palette, int num_palette) +{ + + png_debug1(1, "in %s storage function", "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. + */ + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); + + /* 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_calloc(png_ptr, + 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; + + info_ptr->free_me |= PNG_FREE_PLTE; + + info_ptr->valid |= PNG_INFO_PLTE; +} + +#ifdef PNG_sBIT_SUPPORTED +void PNGAPI +png_set_sBIT(png_structp png_ptr, png_infop info_ptr, + png_const_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function", "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 + +#ifdef PNG_sRGB_SUPPORTED +void PNGAPI +png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->srgb_intent = (png_byte)srgb_intent; + info_ptr->valid |= PNG_INFO_sRGB; +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, + int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + +# ifdef PNG_gAMA_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); +# endif + +# ifdef PNG_cHRM_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); +# endif /* cHRM */ +} +#endif /* sRGB */ + + +#ifdef PNG_iCCP_SUPPORTED +void PNGAPI +png_set_iCCP(png_structp png_ptr, png_infop info_ptr, + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen) +{ + png_charp new_iccp_name; + png_bytep new_iccp_profile; + png_size_t length; + + png_debug1(1, "in %s storage function", "iCCP"); + + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + length = png_strlen(name)+1; + new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); + + if (new_iccp_name == NULL) + { + png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); + return; + } + + png_memcpy(new_iccp_name, name, length); + new_iccp_profile = (png_bytep)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; + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +void PNGAPI +png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_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_const_textp text_ptr, int num_text) +{ + int i; + + png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : + (unsigned long)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) + { + int old_max_text = info_ptr->max_text; + int old_num_text = info_ptr->num_text; + + if (info_ptr->text != NULL) + { + png_textp old_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_size_t)(info_ptr->max_text * png_sizeof(png_text))); + + if (info_ptr->text == NULL) + { + /* Restore to previous condition */ + info_ptr->max_text = old_max_text; + info_ptr->text = old_text; + return(1); + } + + png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max_text * + 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_size_t)(info_ptr->max_text * png_sizeof(png_text))); + if (info_ptr->text == NULL) + { + /* Restore to previous condition */ + info_ptr->num_text = old_num_text; + info_ptr->max_text = old_max_text; + return(1); + } + info_ptr->free_me |= PNG_FREE_TEXT; + } + + png_debug1(3, "allocated %d entries for info_ptr->text", + 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; + + if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || + text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) + { + png_warning(png_ptr, "text compression mode is out of range"); + 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_iTXt_SUPPORTED */ + { + 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_size_t) + (key_len + text_length + lang_len + lang_key_len + 4)); + + if (textp->key == NULL) + return(1); + + png_debug2(2, "Allocated %lu bytes at %p in png_set_text", + (unsigned long)(png_uint_32) + (key_len + lang_len + lang_key_len + text_length + 4), + textp->key); + + png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); + *(textp->key + key_len) = '\0'; + + 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 + { + textp->lang=NULL; + textp->lang_key=NULL; + 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; + textp->itxt_length = 0; + } + + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d", info_ptr->num_text); + } + return(0); +} +#endif + +#ifdef PNG_tIME_SUPPORTED +void PNGAPI +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) +{ + png_debug1(1, "in %s storage function", "tIME"); + + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_tIME)) + return; + + if (mod_time->month == 0 || mod_time->month > 12 || + mod_time->day == 0 || mod_time->day > 31 || + mod_time->hour > 23 || mod_time->minute > 59 || + mod_time->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + return; + } + + png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +void PNGAPI +png_set_tRNS(png_structp png_ptr, png_infop info_ptr, + png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) +{ + png_debug1(1, "in %s storage function", "tRNS"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (trans_alpha != NULL) + { + /* It may not actually be necessary to set png_ptr->trans_alpha here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); + + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + png_ptr->trans_alpha = info_ptr->trans_alpha = + (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); + + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + } + + if (trans_color != NULL) + { + int sample_max = (1 << info_ptr->bit_depth); + + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + (int)trans_color->gray > sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + ((int)trans_color->red > sample_max || + (int)trans_color->green > sample_max || + (int)trans_color->blue > sample_max))) + png_warning(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth"); + + png_memcpy(&(info_ptr->trans_color), trans_color, + png_sizeof(png_color_16)); + + if (num_trans == 0) + num_trans = 1; + } + + info_ptr->num_trans = (png_uint_16)num_trans; + + if (num_trans != 0) + { + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->free_me |= PNG_FREE_TRNS; + } +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +void PNGAPI +png_set_sPLT(png_structp png_ptr, + png_infop info_ptr, png_const_sPLT_tp entries, int nentries) +/* + * entries - array of png_sPLT_t structures + * to be added to the list of palettes + * in the info structure. + * + * nentries - number of palette structures to be + * added. + */ +{ + 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_size_t)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_const_sPLT_tp from = entries + i; + png_size_t length; + + length = png_strlen(from->name) + 1; + to->name = (png_charp)png_malloc_warn(png_ptr, length); + + if (to->name == NULL) + { + png_warning(png_ptr, + "Out of memory while processing sPLT chunk"); + continue; + } + + png_memcpy(to->name, from->name, length); + to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, + 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; + continue; + } + + png_memcpy(to->entries, from->entries, + from->nentries * png_sizeof(png_sPLT_entry)); + + 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; + info_ptr->free_me |= PNG_FREE_SPLT; +} +#endif /* PNG_sPLT_SUPPORTED */ + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +void PNGAPI +png_set_unknown_chunks(png_structp png_ptr, + png_infop info_ptr, png_const_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, + (png_size_t)(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, + (png_size_t)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_const_unknown_chunkp from = unknowns + i; + + png_memcpy(to->name, from->name, png_sizeof(from->name)); + to->name[png_sizeof(to->name)-1] = '\0'; + to->size = from->size; + + /* Note our location in the read or write sequence */ + to->location = (png_byte)(png_ptr->mode & 0xff); + + if (from->size == 0) + to->data=NULL; + + else + { + to->data = (png_bytep)png_malloc_warn(png_ptr, + (png_size_t)from->size); + + if (to->data == NULL) + { + png_warning(png_ptr, + "Out of memory while processing unknown chunk"); + to->size = 0; + } + + else + png_memcpy(to->data, from->data, from->size); + } + } + + info_ptr->unknown_chunks = np; + info_ptr->unknown_chunks_num += num_unknowns; + info_ptr->free_me |= PNG_FREE_UNKN; +} + +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 < + info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks[chunk].location = (png_byte)location; +} +#endif + + +#ifdef 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"); + + 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 + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +void PNGAPI +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_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_size_t)(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; inum_chunk_list = old_num_chunks + num_chunks; + png_ptr->chunk_list = new_list; + png_ptr->free_me |= PNG_FREE_LIST; +} +#endif + +#ifdef 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"); + + if (png_ptr == NULL) + return; + + png_ptr->read_user_chunk_fn = read_user_chunk_fn; + png_ptr->user_chunk_ptr = user_chunk_ptr; +} +#endif + +#ifdef 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", "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 + +void PNGAPI +png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) +{ + if (png_ptr == NULL) + return; + + png_free(png_ptr, png_ptr->zbuf); + + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); + png_ptr->zbuf_size = ZLIB_IO_MAX; + size = ZLIB_IO_MAX; /* must fit */ + } + + else + png_ptr->zbuf_size = (uInt)size; + + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + + /* The following ensures a relatively safe failure if this gets called while + * the buffer is actually in use. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.avail_in = 0; +} + +void PNGAPI +png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) +{ + if (png_ptr && info_ptr) + info_ptr->valid &= ~mask; +} + + + +#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; +} + +/* This function was added to libpng 1.4.0 */ +void PNGAPI +png_set_chunk_cache_max (png_structp png_ptr, + png_uint_32 user_chunk_cache_max) +{ + if (png_ptr) + png_ptr->user_chunk_cache_max = user_chunk_cache_max; +} + +/* This function was added to libpng 1.4.1 */ +void PNGAPI +png_set_chunk_malloc_max (png_structp png_ptr, + png_alloc_size_t user_chunk_malloc_max) +{ + if (png_ptr) + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_set_benign_errors(png_structp png_ptr, int allowed) +{ + png_debug(1, "in png_set_benign_errors"); + + if (allowed) + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + + else + png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; +} +#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +/* Whether to report invalid palette index; added at libng-1.5.10 + * allowed - one of 0: disable; 1: enable + */ +void PNGAPI +png_set_check_for_invalid_index(png_structp png_ptr, int allowed) +{ + png_debug(1, "in png_set_check_for_invalid_index"); + + if (allowed) + png_ptr->num_palette_max = 0; + + else + png_ptr->num_palette_max = -1; +} +#endif + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngstruct.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngstruct.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngstruct.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngstruct.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,358 @@ + +/* pngstruct.h - header file for PNG reference library + * + * Copyright (c) 1998-2012 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.) + * + * Last changed in libpng 1.5.9 [February 18, 2012] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* 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. + */ + +#ifndef PNGSTRUCT_H +#define PNGSTRUCT_H +/* zlib.h defines the structure z_stream, an instance of which is included + * in this structure and is required for decompressing the LZ compressed + * data in PNG files. + */ +#include "zlib.h" + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf longjmp_buffer; /* used in png_error */ + png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; /* function for printing warnings */ +#endif + 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 */ + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#ifdef 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 */ +#ifdef 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 */ + uInt zbuf_size; /* size of zbuf (typically 65536) */ +#ifdef PNG_WRITE_SUPPORTED + +/* Added in 1.5.4: state to keep track of whether the zstream has been + * initialized and if so whether it is for IDAT or some other chunk. + */ +#define PNG_ZLIB_UNINITIALIZED 0 +#define PNG_ZLIB_FOR_IDAT 1 +#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ +#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ +#define PNG_ZLIB_IN_USE 4 /* a flag value */ + + png_uint_32 zlib_state; /* State of zlib initialization */ +/* End of material added at libpng 1.5.4 */ + + 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 */ +#endif +/* Added at libpng 1.5.4 */ +#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ + defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) + int zlib_text_level; /* holds zlib compression level */ + int zlib_text_method; /* holds zlib compression method */ + int zlib_text_window_bits; /* holds zlib compression window bits */ + int zlib_text_mem_level; /* holds zlib compression memory level */ + int zlib_text_strategy; /* holds zlib compression strategy */ +#endif +/* End of material added at libpng 1.5.4 */ + + 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_size_t rowbytes; /* size of 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_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row. + * This is a pointer into big_prev_row + */ + png_bytep row_buf; /* buffer to save current (unfiltered) row. + * This is a pointer into big_row_buf + */ + 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_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ + + 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 */ + +/* Added at libpng-1.5.10 */ +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + int num_palette_max; /* maximum palette index found in IDAT */ +#endif + + png_uint_16 num_trans; /* number of transparency values */ + 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: write only */ + 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: write only */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + png_byte maximum_pixel_depth; + /* pixel depth used for the row buffers */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ + png_byte io_chunk_string[5]; + /* string name of chunk */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_byte background_gamma_type; + png_fixed_point background_gamma; + png_color_16 background; /* background color in screen gamma space */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#ifdef 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 + +#ifdef PNG_READ_GAMMA_SUPPORTED + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ + png_fixed_point gamma; /* file gamma value */ + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + 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_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#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_alpha; /* alpha values for paletted files */ + png_color_16 trans_color; /* transparent color 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 a 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 */ + +#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 + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_bytep palette_lookup; /* lookup table for quantizing */ + png_bytep quantize_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#ifdef 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 + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* This is going to be unused in libpng16 and removed from libpng17 */ + char time_buffer[29]; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int num_chunk_list; + png_bytep chunk_list; +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + /* Added in 1.5.5 to record an sRGB chunk in the png. */ + png_byte is_sRGB; +#endif + +/* New members added in libpng-1.0.3 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; + /* Added in libpng 1.5.5 to record setting of coefficients: */ + png_byte rgb_to_gray_coefficients_set; + /* 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; + /* deleted in 1.5.5: 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) +/* Changed from png_byte to png_uint_32 at version 1.2.0 */ + png_uint_32 mng_features_permitted; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_byte filter_type; +#endif + +/* New members added in libpng-1.2.0 */ + +/* 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 */ + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep quantize_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_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; + + /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown + * chunks that can be stored (0 means unlimited). + */ + png_uint_32 user_chunk_cache_max; + + /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk + * can occupy when decompressed. 0 means unlimited. + */ + png_alloc_size_t user_chunk_malloc_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif + +/* New member added in libpng-1.2.26 */ + png_size_t old_big_row_buf_size; + +/* New member added in libpng-1.2.30 */ + png_charp chunkdata; /* buffer for reading chunk data */ + +#ifdef PNG_IO_STATE_SUPPORTED +/* New member added in libpng-1.4.0 */ + png_uint_32 io_state; +#endif + +/* New member added in libpng-1.5.6 */ + png_bytep big_prev_row; + + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); +}; +#endif /* PNGSTRUCT_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngtrans.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngtrans.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngtrans.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngtrans.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,781 @@ + +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#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"); + + 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"); + + 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"); + + 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"); + + 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_const_color_8p true_bits) +{ + png_debug(1, "in png_set_shift"); + + 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"); + + 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_FILLER; + png_ptr->filler = (png_uint_16)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; + } +} + +/* 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"); + + if (png_ptr == NULL) + return; + + png_set_filler(png_ptr, filler, filler_loc); + png_ptr->transformations |= PNG_ADD_ALPHA; +} + +#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"); + + 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"); + + 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"); + + 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"); + + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_bytep rp = row; + png_size_t i; + png_size_t 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_size_t i; + png_size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 2) + { + *rp = (png_byte)(~(*rp)); + rp += 2; + } + } + +#ifdef PNG_16BIT_SUPPORTED + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_size_t i; + png_size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 4) + { + *rp = (png_byte)(~(*rp)); + *(rp + 1) = (png_byte)(~(*(rp + 1))); + rp += 4; + } + } +#endif +} +#endif + +#ifdef PNG_16BIT_SUPPORTED +#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"); + + if (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 +#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"); + + if (row_info->bit_depth < 8) + { + png_bytep rp; + png_const_bytep end, table; + + end = row + row_info->rowbytes; + + if (row_info->bit_depth == 1) + table = onebppswaptable; + + else if (row_info->bit_depth == 2) + table = twobppswaptable; + + else if (row_info->bit_depth == 4) + table = 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 a channel - this used to be 'png_do_strip_filler' but it used a + * somewhat weird combination of flags to determine what to do. All the calls + * to png_do_strip_filler are changed in 1.5.2 to call this instead with the + * correct arguments. + * + * The routine isn't general - the channel must be the channel at the start or + * end (not in the middle) of each pixel. + */ +void /* PRIVATE */ +png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) +{ + png_bytep sp = row; /* source pointer */ + png_bytep dp = row; /* destination pointer */ + png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + + /* At the start sp will point to the first byte to copy and dp to where + * it is copied to. ep always points just beyond the end of the row, so + * the loop simply copies (channels-1) channels until sp reaches ep. + * + * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. + * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. + */ + + /* GA, GX, XG cases */ + if (row_info->channels == 2) + { + if (row_info->bit_depth == 8) + { + if (at_start) /* Skip initial filler */ + ++sp; + else /* Skip initial channel and, for sp, the filler */ + sp += 2, ++dp; + + /* For a 1 pixel wide image there is nothing to do */ + while (sp < ep) + *dp++ = *sp, sp += 2; + + row_info->pixel_depth = 8; + } + + else if (row_info->bit_depth == 16) + { + if (at_start) /* Skip initial filler */ + sp += 2; + else /* Skip initial channel and, for sp, the filler */ + sp += 4, dp += 2; + + while (sp < ep) + *dp++ = *sp++, *dp++ = *sp, sp += 3; + + row_info->pixel_depth = 16; + } + + else + return; /* bad bit depth */ + + row_info->channels = 1; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_GRAY; + } + + /* RGBA, RGBX, XRGB cases */ + else if (row_info->channels == 4) + { + if (row_info->bit_depth == 8) + { + if (at_start) /* Skip initial filler */ + ++sp; + else /* Skip initial channels and, for sp, the filler */ + sp += 4, dp += 3; + + /* Note that the loop adds 3 to dp and 4 to sp each time. */ + while (sp < ep) + *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; + + row_info->pixel_depth = 24; + } + + else if (row_info->bit_depth == 16) + { + if (at_start) /* Skip initial filler */ + sp += 2; + else /* Skip initial channels and, for sp, the filler */ + sp += 8, dp += 6; + + while (sp < ep) + { + /* Copy 6 bytes, skip 2 */ + *dp++ = *sp++, *dp++ = *sp++; + *dp++ = *sp++, *dp++ = *sp++; + *dp++ = *sp++, *dp++ = *sp, sp += 3; + } + + row_info->pixel_depth = 48; + } + + else + return; /* bad bit depth */ + + row_info->channels = 3; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_RGB; + } + + else + return; /* The filler channel has gone already */ + + /* Fix the rowbytes value. */ + row_info->rowbytes = dp-row; +} +#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"); + + if ((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; + } + } + } + +#ifdef PNG_16BIT_SUPPORTED + 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 + } +} +#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ + +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +/* Added at libpng-1.5.10 */ +void /* PRIVATE */ +png_do_check_palette_indexes(png_structp png_ptr, png_row_infop row_info) +{ + if (png_ptr->num_palette < (1 << row_info->bit_depth) && + png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ + { + /* Calculations moved outside switch in an attempt to stop different + * compiler warnings. 'padding' is in *bits* within the last byte, it is + * an 'int' because pixel_depth becomes an 'int' in the expression below, + * and this calculation is used because it avoids warnings that other + * forms produced on either GCC or MSVC. + */ + int padding = (-row_info->pixel_depth * row_info->width) & 7; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + + switch (row_info->bit_depth) + { + case 1: + { + /* in this case, all bytes must be 0 so we don't need + * to unpack the pixels except for the rightmost one. + */ + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp >> padding != 0) + png_ptr->num_palette_max = 1; + padding = 0; + } + + break; + } + + case 2: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 2) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 6) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 4: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 8: + { + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp > png_ptr->num_palette_max) + png_ptr->num_palette_max = (int) *rp; + } + + break; + } + + default: + break; + } + } +} +#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +#ifdef PNG_USER_TRANSFORM_PTR_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"); + + if (png_ptr == NULL) + return; + 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; +} +#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. + */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +png_voidp PNGAPI +png_get_user_transform_ptr(png_const_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return ((png_voidp)png_ptr->user_transform_ptr); +} +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +png_uint_32 PNGAPI +png_get_current_row_number(png_const_structp png_ptr) +{ + /* See the comments in png.h - this is the sub-image row when reading and + * interlaced image. + */ + if (png_ptr != NULL) + return png_ptr->row_number; + + return PNG_UINT_32_MAX; /* help the app not to fail silently */ +} + +png_byte PNGAPI +png_get_current_pass_number(png_const_structp png_ptr) +{ + if (png_ptr != NULL) + return png_ptr->pass; + return 8; /* invalid */ +} +#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ +#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || + PNG_WRITE_USER_TRANSFORM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwio.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwio.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwio.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwio.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,254 @@ + +/* pngwio.c - functions for data output + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * 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(...). + */ + +#include "pngpriv.h" + +#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_const_bytep data, png_size_t length) +{ + /* NOTE: write_data_fn must not change the buffer! */ + if (png_ptr->write_data_fn != NULL ) + (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); + + else + png_error(png_ptr, "Call to NULL write function"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* 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 PNGCBAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + if (png_ptr == NULL) + return; + + check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); + + 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 PNGCBAPI +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) + { + check = fwrite(near_data, 1, length, io_ptr); + } + + 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 */ + err = fwrite(buf, 1, written, io_ptr); + + 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. + */ +#ifdef 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); +} + +# ifdef PNG_STDIO_SUPPORTED +void PNGCBAPI +png_default_flush(png_structp png_ptr) +{ + png_FILE_p io_ptr; + + if (png_ptr == NULL) + return; + + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + fflush(io_ptr); +} +# 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. May be + * NULL, in which case libpng's default function will + * be used. + * 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 output, 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. May be NULL, in which case + * libpng's default function will be used, if + * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not + * a good idea if io_ptr does not point to a standard + * *FILE structure. + */ +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; + +#ifdef PNG_STDIO_SUPPORTED + 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 + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED + + 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, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +} + +#ifdef USE_FAR_KEYWORD +# ifdef _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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwrite.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwrite.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwrite.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwrite.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1668 @@ + +/* pngwrite.c - general routines to write a PNG file + * + * Last changed in libpng 1.5.11 [June 14, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#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"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + { + /* Write PNG signature */ + png_write_sig(png_ptr); + +#ifdef 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, +#ifdef 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. + */ +#ifdef PNG_WRITE_gAMA_SUPPORTED + if (info_ptr->valid & PNG_INFO_gAMA) + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); +#endif +#ifdef PNG_WRITE_sRGB_SUPPORTED + if (info_ptr->valid & PNG_INFO_sRGB) + png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED + if (info_ptr->valid & PNG_INFO_iCCP) + png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, + (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +#endif +#ifdef 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 +#ifdef PNG_WRITE_cHRM_SUPPORTED + if (info_ptr->valid & PNG_INFO_cHRM) + png_write_cHRM_fixed(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); +#endif + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + 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->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + if (up->size == 0) + png_warning(png_ptr, "Writing zero-length unknown chunk"); + + 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"); + + 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"); + +#ifdef PNG_WRITE_tRNS_SUPPORTED + if (info_ptr->valid & PNG_INFO_tRNS) + { +#ifdef 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_alpha[j] = + (png_byte)(255 - info_ptr->trans_alpha[j]); + } +#endif + png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), + info_ptr->num_trans, info_ptr->color_type); + } +#endif +#ifdef PNG_WRITE_bKGD_SUPPORTED + if (info_ptr->valid & PNG_INFO_bKGD) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED + if (info_ptr->valid & PNG_INFO_hIST) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); +#endif + +#ifdef 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 + +#ifdef 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 + +#ifdef PNG_WRITE_sCAL_SUPPORTED + if (info_ptr->valid & PNG_INFO_sCAL) + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); +#endif /* sCAL */ + +#ifdef 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 /* pHYs */ + +#ifdef 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 /* tIME */ + +#ifdef 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 /* sPLT */ + +#ifdef 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", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef 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) + { +#ifdef 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) + { +#ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, + 0); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; +#else + /* Can't get here */ + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + } + } +#endif /* tEXt */ + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + 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->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 +} + +/* 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"); + + if (png_ptr == NULL) + return; + + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "No IDATs written into file"); + +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + if (png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); +#endif + + /* See if user wants us to write information chunks */ + if (info_ptr != NULL) + { +#ifdef PNG_WRITE_TEXT_SUPPORTED + int i; /* local index variable */ +#endif +#ifdef 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 +#ifdef 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", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef 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) + { +#ifdef 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) + { +#ifdef 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 +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + 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); + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, + * and restored again in libpng-1.2.30, may cause some applications that + * do not set png_ptr->output_flush_fn to crash. If your application + * experiences a problem, please try building libpng with + * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to + * png-mng-implement at lists.sf.net . + */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED + png_flush(png_ptr); +# endif +#endif +} + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* "tm" structure is not supported on WindowsCE */ +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) +{ + png_debug(1, "in png_convert_from_struct_tm"); + + 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"); + + tbuf = gmtime(&ttime); + png_convert_from_struct_tm(ptime, tbuf); +} +#endif + +/* Initialize png_ptr structure, and allocate any memory needed */ +PNG_FUNCTION(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),PNG_ALLOCATED) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL)); +} + +/* Alternate initialize png_ptr structure, and allocate any memory needed */ +static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ + +PNG_FUNCTION(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),PNG_ALLOCATED) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + volatile int png_cleanup_needed = 0; +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif + png_structp png_ptr; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf tmp_jmpbuf; +#endif +#endif + + png_debug(1, "in png_create_write_struct"); + +#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 +/* 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(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ +#endif +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif + PNG_ABORT(); +#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); + + if (!png_user_version_check(png_ptr, user_png_ver)) + png_cleanup_needed = 1; + + /* Initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + + if (!png_cleanup_needed) + { + png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, + png_ptr->zbuf_size); + if (png_ptr->zbuf == NULL) + png_cleanup_needed = 1; + } + + if (png_cleanup_needed) + { + /* Clean up PNG structure and deallocate any memory. */ + 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); + } + + png_set_write_fn(png_ptr, NULL, NULL, NULL); + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + png_reset_filter_heuristics(png_ptr); +#endif + + return (png_ptr); +} + + +/* 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"); + + 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"); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Initialize 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_const_bytep row) +{ + /* 1.5.6: moved from png_struct to be a local structure: */ + png_row_info row_info; + + if (png_ptr == NULL) + return; + + png_debug2(1, "in png_write_row (row %u, pass %d)", + 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); + } + +#ifdef 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; + + default: /* error: ignore it */ + break; + } + } +#endif + + /* Set up row info for transformations */ + row_info.color_type = png_ptr->color_type; + row_info.width = png_ptr->usr_width; + row_info.channels = png_ptr->usr_channels; + row_info.bit_depth = png_ptr->usr_bit_depth; + row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + png_debug1(3, "row_info->color_type = %d", row_info.color_type); + png_debug1(3, "row_info->width = %u", row_info.width); + png_debug1(3, "row_info->channels = %d", row_info.channels); + png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ + png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && + (png_ptr->transformations & PNG_INTERLACE)) + { + png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); + /* This should always get caught above, but still ... */ + if (!(row_info.width)) + { + png_write_finish_row(png_ptr); + return; + } + } +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED + /* Handle other transformations */ + if (png_ptr->transformations) + png_do_write_transformations(png_ptr, &row_info); +#endif + + /* At this point the row_info pixel depth must match the 'transformed' depth, + * which is also the output depth. + */ + if (row_info.pixel_depth != png_ptr->pixel_depth || + row_info.pixel_depth != png_ptr->transformed_pixel_depth) + png_error(png_ptr, "internal write transform logic error"); + +#ifdef 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(&row_info, png_ptr->row_buf + 1); + } +#endif + +/* Added at libpng-1.5.10 */ +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Check for out-of-range palette index */ + if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, &row_info); +#endif + + /* Find a filter if necessary, filter the row and write it out. */ + png_write_find_filter(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); +} + +#ifdef 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"); + + 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"); + + 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); + 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->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"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr != NULL) + { + 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) + { + if (png_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + 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; +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; +#endif + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_write_destroy"); + + /* Free any memory zlib uses */ + if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) + 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); +#ifdef PNG_WRITE_FILTER_SUPPORTED + 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); +#endif + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + /* Use this to save a little code space, it doesn't free the filter_costs */ + png_reset_filter_heuristics(png_ptr); + 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->longjmp_buffer, png_sizeof(jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + warning_fn = png_ptr->warning_fn; +#endif + 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; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#endif + 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->longjmp_buffer, 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"); + + if (png_ptr == NULL) + return; + +#ifdef 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)) + { +#ifdef PNG_WRITE_FILTER_SUPPORTED + case 5: + case 6: + case 7: png_warning(png_ptr, "Unknown row filter for method 0"); +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + case PNG_FILTER_VALUE_NONE: + png_ptr->do_filter = PNG_FILTER_NONE; break; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + 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_WRITE_FILTER_SUPPORTED */ + } + + /* 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) + { +#ifdef PNG_WRITE_FILTER_SUPPORTED + 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_byte)(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_byte)(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_WRITE_FILTER_SUPPORTED */ + 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. + */ +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ +/* Convenience reset API. */ +static void +png_reset_filter_heuristics(png_structp png_ptr) +{ + /* Clear out any old values in the 'weights' - this must be done because if + * the app calls set_filter_heuristics multiple times with different + * 'num_weights' values we would otherwise potentially have wrong sized + * arrays. + */ + png_ptr->num_prev_filters = 0; + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + if (png_ptr->prev_filters != NULL) + { + png_bytep old = png_ptr->prev_filters; + png_ptr->prev_filters = NULL; + png_free(png_ptr, old); + } + if (png_ptr->filter_weights != NULL) + { + png_uint_16p old = png_ptr->filter_weights; + png_ptr->filter_weights = NULL; + png_free(png_ptr, old); + } + + if (png_ptr->inv_filter_weights != NULL) + { + png_uint_16p old = png_ptr->inv_filter_weights; + png_ptr->inv_filter_weights = NULL; + png_free(png_ptr, old); + } + + /* Leave the filter_costs - this array is fixed size. */ +} + +static int +png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights) +{ + if (png_ptr == NULL) + return 0; + + /* Clear out the arrays */ + png_reset_filter_heuristics(png_ptr); + + /* Check arguments; the 'reset' function makes the correct settings for the + * unweighted case, but we must handle the weight case by initializing the + * arrays for the caller. + */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + + if (num_weights > 0) + { + 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; + } + + 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; + } + + /* Safe to set this now */ + png_ptr->num_prev_filters = (png_byte)num_weights; + } + + /* 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; + } + + /* All the arrays are inited, safe to set this: */ + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; + + /* Return the 'ok' code. */ + return 1; + } + else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) + { + return 1; + } + else + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return 0; + } +} + +/* Provide floating and fixed point APIs */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + 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)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); + + png_ptr->filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); + } + } + + /* 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[i] >= 1.0) + { + png_ptr->inv_filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); + + png_ptr->filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); + } + } +} +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics_fixed"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] <= 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) + ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); + + png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* + PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); + } + } + + /* 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[i] >= PNG_FP_1) + { + png_uint_32 tmp; + + /* Use a 32 bit unsigned temporary here because otherwise the + * intermediate value will be a 32 bit *signed* integer (ANSI rules) + * and this will get the wrong answer on division. + */ + tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); + tmp /= filter_costs[i]; + + png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; + + tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; + tmp /= PNG_FP_1; + + png_ptr->filter_costs[i] = (png_uint_16)tmp; + } + } +} +#endif /* FIXED_POINT */ +#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"); + + 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"); + + 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"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +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"); + + 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; +} + +/* The following were added to libpng-1.5.4 */ +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +void PNGAPI +png_set_text_compression_level(png_structp png_ptr, int level) +{ + png_debug(1, "in png_set_text_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; + png_ptr->zlib_text_level = level; +} + +void PNGAPI +png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_text_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; + png_ptr->zlib_text_mem_level = mem_level; +} + +void PNGAPI +png_set_text_compression_strategy(png_structp png_ptr, int strategy) +{ + png_debug(1, "in png_set_text_compression_strategy"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; + png_ptr->zlib_text_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +void PNGAPI +png_set_text_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, "Text compression window is being reset to 512"); + window_bits = 9; + } + +#endif + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; + png_ptr->zlib_text_window_bits = window_bits; +} + +void PNGAPI +png_set_text_compression_method(png_structp png_ptr, int method) +{ + png_debug(1, "in png_set_text_compression_method"); + + 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_ZTXT_CUSTOM_METHOD; + png_ptr->zlib_text_method = method; +} +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +/* end of API added to libpng-1.5.4 */ + +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; +} + +#ifdef 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"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->write_user_transform_fn = write_user_transform_fn; +} +#endif + + +#ifdef 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; + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + +#ifdef PNG_WRITE_INVERT_SUPPORTED + /* Invert monochrome pixels */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#ifdef 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 + +#ifdef PNG_WRITE_PACK_SUPPORTED + /* Pack pixels into bytes */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#ifdef 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 + +#ifdef PNG_WRITE_FILLER_SUPPORTED + /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ + if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + + else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#endif + +#ifdef PNG_WRITE_BGR_SUPPORTED + /* Flip BGR pixels to RGB */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#ifdef 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 + +#ifdef 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 + +#ifdef 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 + + /* ----------------------- 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); + + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) +} +#endif +#endif /* PNG_WRITE_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwtran.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwtran.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwtran.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwtran.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,633 @@ + +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Last changed in libpng 1.5.6 [November 3, 2011] + * Copyright (c) 1998-2011 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_TRANSFORMS_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_row_infop row_info) +{ + png_debug(1, "in png_do_write_transformations"); + + if (png_ptr == NULL) + return; + +#ifdef 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 */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t 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 + +#ifdef PNG_WRITE_FILLER_SUPPORTED + if (png_ptr->transformations & PNG_FILLER) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); +#endif + +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED + if (png_ptr->transformations & PNG_PACK) + png_do_pack(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif + +#ifdef PNG_WRITE_SWAP_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if (png_ptr->transformations & PNG_SHIFT) + png_do_shift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_BGR_SUPPORTED + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif +} + +#ifdef 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"); + + if (row_info->bit_depth == 8 && + 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; + } + + default: + 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 + +#ifdef 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_const_color_8p bit_depth) +{ + png_debug(1, "in png_do_shift"); + + if (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_size_t i; + png_byte mask; + png_size_t 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 + +#ifdef 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"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from ARGB to RGBA */ + 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; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AARRGGBB to RRGGBBAA */ + 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]; + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from AG to GA */ + 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; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AAGG to GGAA */ + 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 /* PNG_WRITE_16BIT_SUPPORTED */ + } + } +} +#endif + +#ifdef 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"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + 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++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in RRGGBBAA */ + 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++)); + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + 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++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + 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 /* PNG_WRITE_16BIT_SUPPORTED */ + } + } +} +#endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#ifdef 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"); + + if ((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); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + 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_WRITE_16BIT_SUPPORTED */ + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_WRITE_SUPPORTED */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwutil.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwutil.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libpng/pngwutil.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libpng/pngwutil.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3179 @@ + +/* pngwutil.c - utilities to write a PNG file + * + * Last changed in libpng 1.5.10 [March 8, 2012] + * Copyright (c) 1998-2012 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 code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_INT_FUNCTIONS_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); +} + +#ifdef PNG_SAVE_INT_32_SUPPORTED +/* 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. Note that, + * the following works correctly even if png_int_32 has more than 32 bits + * (compare the more complex code required on read for sign extention.) + */ +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); +} +#endif + +/* 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); +} +#endif + +/* 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 PNGAPI +png_write_sig(png_structp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the signature is being written */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; +#endif + + /* 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; +} + +/* 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(). + */ +static void +png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, + png_uint_32 length) +{ + png_byte buf[8]; + +#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) + PNG_CSTRING_FROM_CHUNK(buf, chunk_name); + png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); +#endif + + if (png_ptr == NULL) + return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk header is being written. + * PNG_IO_CHUNK_HDR requires a single I/O call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; +#endif + + /* Write the length and the chunk name */ + png_save_uint_32(buf, length); + png_save_uint_32(buf + 4, chunk_name); + png_write_data(png_ptr, buf, 8); + + /* Put the chunk name into png_ptr->chunk_name */ + png_ptr->chunk_name = chunk_name; + + /* Reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + + png_calculate_crc(png_ptr, buf + 4, 4); + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that chunk data will (possibly) be written. + * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; +#endif +} + +void PNGAPI +png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, + png_uint_32 length) +{ + png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); +} + +/* Write the data of a PNG chunk started with png_write_chunk_header(). + * 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_header(). + */ +void PNGAPI +png_write_chunk_data(png_structp png_ptr, png_const_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_write_data(png_ptr, data, length); + + /* Update the CRC after writing the data, + * in case that the user I/O routine alters it. + */ + png_calculate_crc(png_ptr, data, length); + } +} + +/* Finish a chunk started with png_write_chunk_header(). */ +void PNGAPI +png_write_chunk_end(png_structp png_ptr) +{ + png_byte buf[4]; + + if (png_ptr == NULL) return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk CRC is being written. + * PNG_IO_CHUNK_CRC requires a single I/O function call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; +#endif + + /* Write the crc in a single operation */ + png_save_uint_32(buf, png_ptr->crc); + + png_write_data(png_ptr, buf, (png_size_t)4); +} + +/* 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. + */ +static void +png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, png_size_t length) +{ + if (png_ptr == NULL) + return; + + /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ + if (length > PNG_UINT_32_MAX) + png_error(png_ptr, "length exceeds PNG maxima"); + + png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* This is the API that calls the internal function above. */ +void PNGAPI +png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, + png_const_bytep data, png_size_t length) +{ + png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, + length); +} + +/* Initialize the compressor for the appropriate type of compression. */ +static void +png_zlib_claim(png_structp png_ptr, png_uint_32 state) +{ + if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) + { + /* If already initialized for 'state' do not re-init. */ + if (png_ptr->zlib_state != state) + { + int ret = Z_OK; + png_const_charp who = "-"; + + /* If actually initialized for another state do a deflateEnd. */ + if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) + { + ret = deflateEnd(&png_ptr->zstream); + who = "end"; + png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; + } + + /* zlib itself detects an incomplete state on deflateEnd */ + if (ret == Z_OK) switch (state) + { +# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + case PNG_ZLIB_FOR_TEXT: + ret = deflateInit2(&png_ptr->zstream, + png_ptr->zlib_text_level, png_ptr->zlib_text_method, + png_ptr->zlib_text_window_bits, + png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); + who = "text"; + break; +# endif + + case PNG_ZLIB_FOR_IDAT: + ret = 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); + who = "IDAT"; + break; + + default: + png_error(png_ptr, "invalid zlib state"); + } + + if (ret == Z_OK) + png_ptr->zlib_state = state; + + else /* an error in deflateEnd or deflateInit2 */ + { + size_t pos = 0; + char msg[64]; + + pos = png_safecat(msg, sizeof msg, pos, + "zlib failed to initialize compressor ("); + pos = png_safecat(msg, sizeof msg, pos, who); + + switch (ret) + { + case Z_VERSION_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") version error"); + break; + + case Z_STREAM_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") stream error"); + break; + + case Z_MEM_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") memory error"); + break; + + default: + pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); + break; + } + + png_error(png_ptr, msg); + } + } + + /* Here on success, claim the zstream: */ + png_ptr->zlib_state |= PNG_ZLIB_IN_USE; + } + + else + png_error(png_ptr, "zstream already in use (internal error)"); +} + +/* The opposite: release the stream. It is also reset, this API will warn on + * error but will not fail. + */ +static void +png_zlib_release(png_structp png_ptr) +{ + if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) + { + int ret = deflateReset(&png_ptr->zstream); + + png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; + + if (ret != Z_OK) + { + png_const_charp err; + PNG_WARNING_PARAMETERS(p) + + switch (ret) + { + case Z_VERSION_ERROR: + err = "version"; + break; + + case Z_STREAM_ERROR: + err = "stream"; + break; + + case Z_MEM_ERROR: + err = "memory"; + break; + + default: + err = "unknown"; + break; + } + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); + png_warning_parameter(p, 2, err); + + if (png_ptr->zstream.msg) + err = png_ptr->zstream.msg; + else + err = "[no zlib message]"; + + png_warning_parameter(p, 3, err); + + png_formatted_warning(png_ptr, p, + "zlib failed to reset compressor: @1(@2): @3"); + } + } + + else + png_warning(png_ptr, "zstream not in use (internal error)"); +} + +#ifdef PNG_WRITE_COMPRESSED_TEXT_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 +{ + png_const_bytep input; /* The uncompressed input data */ + png_size_t input_len; /* Its length */ + int num_output_ptr; /* Number of output pointers used */ + int max_output_ptr; /* Size of output_ptr */ + png_bytep *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_const_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 = text_len; + + /* We may just want to pass the text right through */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + comp->input = (png_const_bytep)text; + return((int)text_len); + } + + if (compression >= PNG_TEXT_COMPRESSION_LAST) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, + compression); + png_formatted_warning(png_ptr, p, "Unknown compression type @1"); + } + + /* 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). + */ + png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); + + /* Set up the compression buffers */ + /* TODO: the following cast hides a potential overflow problem. */ + png_ptr->zstream.avail_in = (uInt)text_len; + + /* NOTE: assume zlib doesn't overwrite the input */ + png_ptr->zstream.next_in = (Bytef *)text; + png_ptr->zstream.avail_out = png_ptr->zbuf_size; + png_ptr->zstream.next_out = 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_bytepp old_ptr; + + old_ptr = comp->output_ptr; + + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (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_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (comp->max_output_ptr * png_sizeof(png_charp))); + } + + /* Save the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)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_bytepp old_ptr; + + old_ptr = comp->output_ptr; + + /* This could be optimized to realloc() */ + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); + + png_memcpy(comp->output_ptr, old_ptr, + old_max * png_sizeof(png_charp)); + + png_free(png_ptr, old_ptr); + } + + else + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); + } + + /* Save the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)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, + png_size_t data_len) +{ + int i; + + /* Handle the no-compression case */ + if (comp->input) + { + png_write_chunk_data(png_ptr, comp->input, data_len); + + return; + } + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* The zbuf_size test is because the code below doesn't work if zbuf_size is + * '1'; simply skip it to avoid memory overwrite. + */ + if (data_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1) + { + unsigned int z_cmf; /* zlib compression method and flags */ + + /* Optimize the CMF field in the zlib stream. This hack of the zlib + * stream is compliant to the stream specification. + */ + + if (comp->num_output_ptr) + z_cmf = comp->output_ptr[0][0]; + else + z_cmf = png_ptr->zbuf[0]; + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + unsigned int z_cinfo; + unsigned int half_z_window_size; + png_size_t uncompressed_text_size = comp->input_len; + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1 << (z_cinfo + 7); + + while (uncompressed_text_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 (comp->num_output_ptr) + { + + if (comp->output_ptr[0][0] != z_cmf) + { + int tmp; + + comp->output_ptr[0][0] = (png_byte)z_cmf; + tmp = comp->output_ptr[0][1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + comp->output_ptr[0][1] = (png_byte)tmp; + } + } + else + { + int tmp; + + png_ptr->zbuf[0] = (png_byte)z_cmf; + tmp = png_ptr->zbuf[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + png_ptr->zbuf[1] = (png_byte)tmp; + } + } + + else + png_error(png_ptr, + "Invalid zlib compression method or flags in non-IDAT chunk"); + } +#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ + + /* Write saved output buffers, if any */ + for (i = 0; i < comp->num_output_ptr; i++) + { + png_write_chunk_data(png_ptr, comp->output_ptr[i], + (png_size_t)png_ptr->zbuf_size); + + png_free(png_ptr, comp->output_ptr[i]); + } + + if (comp->max_output_ptr != 0) + png_free(png_ptr, comp->output_ptr); + + /* 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_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + + /* Reset zlib for another zTXt/iTXt or image data */ + png_zlib_release(png_ptr); +} +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + +/* 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) +{ + png_byte buf[13]; /* Buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR"); + + /* 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: +#ifdef PNG_WRITE_16BIT_SUPPORTED + case 16: +#endif + png_ptr->channels = 1; break; + + default: + png_error(png_ptr, + "Invalid bit depth for grayscale image"); + } + break; + + case PNG_COLOR_TYPE_RGB: +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif + 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: +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif + 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 ( +#ifdef 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 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; +#ifdef 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_complete_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; + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) + png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) + png_ptr->zlib_text_level = png_ptr->zlib_level; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) + png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) + png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) + png_ptr->zlib_text_method = png_ptr->zlib_method; +#else + png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = png_ptr->zlib_level; + png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; + png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; + png_ptr->zlib_text_method = png_ptr->zlib_method; +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + + /* Record that the compressor has not yet been initialized. */ + png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; + + png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ +} + +/* 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_const_colorp palette, + png_uint_32 num_pal) +{ + png_uint_32 i; + png_const_colorp pal_ptr; + png_byte buf[3]; + + png_debug(1, "in png_write_PLTE"); + + if (( +#ifdef 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", png_ptr->num_palette); + + png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); +#ifdef PNG_POINTER_INDEXING_SUPPORTED + + 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) +{ + png_debug(1, "in png_write_IDAT"); + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + { + /* Optimize the CMF field in the zlib stream. This hack of the zlib + * stream is compliant to the stream specification. + */ + 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) + { + /* Compute the maximum possible length of the datastream */ + + /* Number of pixels, plus for each row a filter byte + * and possibly a padding byte, so increase the maximum + * size to account for these. + */ + unsigned int z_cinfo; + unsigned int half_z_window_size; + png_uint_32 uncompressed_idat_size = png_ptr->height * + ((png_ptr->width * + png_ptr->channels * png_ptr->bit_depth + 15) >> 3); + + /* If it's interlaced, each block of 8 rows is sent as up to + * 14 rows, i.e., 6 additional rows, each with a filter byte + * and possibly a padding byte + */ + if (png_ptr->interlaced) + uncompressed_idat_size += ((png_ptr->height + 7)/8) * + (png_ptr->bit_depth < 8 ? 12 : 6); + + z_cinfo = z_cmf >> 4; + 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] != z_cmf) + { + int tmp; + data[0] = (png_byte)z_cmf; + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; + } + } + } + + else + png_error(png_ptr, + "Invalid zlib compression method or flags in IDAT"); + } +#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ + + png_write_complete_chunk(png_ptr, png_IDAT, data, length); + png_ptr->mode |= PNG_HAVE_IDAT; + + /* Prior to 1.5.4 this code was replicated in every caller (except at the + * end, where it isn't technically necessary). Since this function has + * flushed the data we can safely reset the zlib output buffer here. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +} + +/* Write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structp png_ptr) +{ + png_debug(1, "in png_write_IEND"); + + png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_ptr->mode |= PNG_HAVE_IEND; +} + +#ifdef PNG_WRITE_gAMA_SUPPORTED +/* Write a gAMA chunk */ +void /* PRIVATE */ +png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) +{ + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA"); + + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); + png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); +} +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +/* Write a sRGB chunk */ +void /* PRIVATE */ +png_write_sRGB(png_structp png_ptr, int srgb_intent) +{ + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB"); + + if (srgb_intent >= PNG_sRGB_INTENT_LAST) + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + + buf[0]=(png_byte)srgb_intent; + png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); +} +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +/* Write an iCCP chunk */ +void /* PRIVATE */ +png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, + png_const_charp profile, int profile_len) +{ + png_size_t name_len; + png_charp new_name; + compression_state comp; + int embedded_profile_len = 0; + + png_debug(1, "in png_write_iCCP"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) + 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_const_bytep)profile ))<<24) | + ((*( (png_const_bytep)profile + 1))<<16) | + ((*( (png_const_bytep)profile + 2))<< 8) | + ((*( (png_const_bytep)profile + 3)) ); + + if (embedded_profile_len < 0) + { + png_warning(png_ptr, + "Embedded profile length in iCCP chunk is negative"); + + png_free(png_ptr, new_name); + return; + } + + if (profile_len < embedded_profile_len) + { + png_warning(png_ptr, + "Embedded profile length too large in iCCP chunk"); + + png_free(png_ptr, new_name); + 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_header(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, + (png_size_t)(name_len + 2)); + + if (profile_len) + { + png_write_compressed_data_out(png_ptr, &comp, profile_len); + } + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +/* Write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) +{ + png_size_t name_len; + png_charp new_name; + png_byte entrybuf[10]; + png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); + png_size_t palette_size = entry_size * spalette->nentries; + png_sPLT_entryp ep; +#ifndef PNG_POINTER_INDEXING_SUPPORTED + int i; +#endif + + png_debug(1, "in png_write_sPLT"); + + if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) + return; + + /* Make sure we include the NULL after the name */ + png_write_chunk_header(png_ptr, png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + + png_write_chunk_data(png_ptr, (png_bytep)new_name, + (png_size_t)(name_len + 1)); + + png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); + + /* Loop through each palette entry, writing appropriately */ +#ifdef PNG_POINTER_INDEXING_SUPPORTED + for (ep = spalette->entries; epentries + 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, (png_size_t)entry_size); + } +#endif + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +/* Write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) +{ + png_byte buf[4]; + png_size_t size; + + png_debug(1, "in png_write_sBIT"); + + /* 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_complete_chunk(png_ptr, png_sBIT, buf, size); +} +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +/* Write the cHRM chunk */ +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) +{ + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM"); + + /* Each value is saved in 1/100,000ths */ +#ifdef PNG_CHECK_cHRM_SUPPORTED + if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, + green_x, green_y, blue_x, blue_y)) +#endif + { + png_save_uint_32(buf, (png_uint_32)white_x); + png_save_uint_32(buf + 4, (png_uint_32)white_y); + + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_y); + + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_y); + + png_save_uint_32(buf + 24, (png_uint_32)blue_x); + png_save_uint_32(buf + 28, (png_uint_32)blue_y); + + png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); + } +} +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +/* Write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, + png_const_color_16p tran, int num_trans, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS"); + + 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_complete_chunk(png_ptr, png_tRNS, trans_alpha, (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_complete_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); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + } + + else + { + png_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } +} +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +/* Write the background chunk */ +void /* PRIVATE */ +png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD"); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if ( +#ifdef 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_complete_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); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + + return; + } + + png_write_complete_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_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + } +} +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +/* Write the histogram */ +void /* PRIVATE */ +png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) +{ + int i; + png_byte buf[3]; + + png_debug(1, "in png_write_hIST"); + + if (num_hist > (int)png_ptr->num_palette) + { + png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, + png_ptr->num_palette); + + png_warning(png_ptr, "Invalid number of histogram entries specified"); + return; + } + + png_write_chunk_header(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_const_charp key, png_charpp new_key) +{ + png_size_t key_len; + png_const_charp ikp; + png_charp kp, dp; + int kflag; + int kwarn=0; + + png_debug(1, "in png_check_keyword"); + + *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'", 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 (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) + { + if ((png_byte)*ikp < 0x20 || + ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, + (png_byte)*ikp); + png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); + *dp = ' '; + } + + else + { + *dp = *ikp; + } + } + *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'", 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); + 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 + +#ifdef PNG_WRITE_tEXt_SUPPORTED +/* Write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len) +{ + png_size_t key_len; + png_charp new_key; + + png_debug(1, "in png_write_tEXt"); + + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) + 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_header(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, + (png_size_t)(key_len + 1)); + + if (text_len) + png_write_chunk_data(png_ptr, (png_const_bytep)text, + (png_size_t)text_len); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); +} +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +/* Write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len, int compression) +{ + png_size_t key_len; + png_byte buf; + png_charp new_key; + compression_state comp; + + png_debug(1, "in png_write_zTXt"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) + { + png_free(png_ptr, new_key); + 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_header(png_ptr, png_zTXt, + (png_uint_32)(key_len+text_len + 2)); + + /* Write key */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); + + png_free(png_ptr, new_key); + + buf = (png_byte)compression; + + /* Write compression */ + png_write_chunk_data(png_ptr, &buf, (png_size_t)1); + + /* Write the compressed data */ + png_write_compressed_data_out(png_ptr, &comp, text_len); + + /* Close the chunk */ + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +/* Write an iTXt chunk */ +void /* PRIVATE */ +png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) +{ + png_size_t lang_len, key_len, lang_key_len, text_len; + png_charp new_lang; + png_charp new_key = NULL; + png_byte cbuf[2]; + compression_state comp; + + png_debug(1, "in png_write_iTXt"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) + return; + + if ((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_header(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, (png_size_t)(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, (png_size_t)2); + + cbuf[0] = 0; + png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), + (png_size_t)(lang_len + 1)); + + png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), + (png_size_t)(lang_key_len + 1)); + + png_write_compressed_data_out(png_ptr, &comp, text_len); + + png_write_chunk_end(png_ptr); + + png_free(png_ptr, new_key); + png_free(png_ptr, new_lang); +} +#endif + +#ifdef 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) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs"); + + 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_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); +} +#endif +#ifdef 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_const_charp units, + png_charpp params) +{ + png_size_t purpose_len, units_len, total_len; + png_size_tp params_len; + png_byte buf[10]; + png_charp new_purpose; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)", 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", (int)purpose_len); + units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d", (int)units_len); + total_len = purpose_len + units_len + 10; + + params_len = (png_size_tp)png_malloc(png_ptr, + (png_alloc_size_t)(nparams * png_sizeof(png_size_t))); + + /* 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", i, + (unsigned long)params_len[i]); + total_len += params_len[i]; + } + + png_debug1(3, "pCAL total length = %d", (int)total_len); + png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_const_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_const_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_const_bytep)params[i], params_len[i]); + } + + png_free(png_ptr, params_len); + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +/* Write the sCAL chunk */ +void /* PRIVATE */ +png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, + png_const_charp height) +{ + png_byte buf[64]; + png_size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s"); + + 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", (unsigned int)total_len); + png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); +} +#endif + +#ifdef 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) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs"); + + 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_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); +} +#endif + +#ifdef 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_const_timep mod_time) +{ + png_byte buf[7]; + + png_debug(1, "in png_write_tIME"); + + 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_complete_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 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_alloc_size_t buf_size; + int usr_pixel_depth; + + png_debug(1, "in png_write_start_row"); + + usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; + buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; + + /* 1.5.6: added to allow checking in the row write code. */ + png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; + png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; + + /* Set up row buffer */ + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); + + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + /* 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_calloc(png_ptr, 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_WRITE_FILTER_SUPPORTED */ + +#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_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); + 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 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int ret; + + png_debug(1, "in png_write_finish_row"); + + /* 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); + } + + png_zlib_release(png_ptr); + png_ptr->zstream.data_type = Z_BINARY; +} + +#ifdef 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) +{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_write_interlace"); + + /* We don't have to do anything on the last pass (6) */ + if (pass < 6) + { + /* 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. + */ +static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t row_bytes); + +#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; +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_bytep prev_row, row_buf; + png_uint_32 mins, bpp; + png_byte filter_to_do = png_ptr->do_filter; + png_size_t row_bytes = row_info->rowbytes; +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + int num_p_filters = png_ptr->num_prev_filters; +#endif + + png_debug(1, "in png_write_find_filter"); + +#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) + { + /* These will never be selected so we need not test them. */ + filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); + } +#endif + + /* 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; +#ifdef PNG_WRITE_FILTER_SUPPORTED + 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_size_t i; + int v; + + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) + { + v = *rp; + sum += (v < 128) ? v : 256 - v; + } + +#ifdef 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_size_t 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_size_t i; + int v; + +#ifdef 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; + } + +#ifdef 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_size_t 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_size_t i; + int v; + + +#ifdef 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; + } + +#ifdef 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_size_t i; + int v; + +#ifdef 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; + } + +#ifdef 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_size_t 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_size_t i; + int v; + +#ifdef 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; + } + +#ifdef 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_WRITE_FILTER_SUPPORTED */ + + /* Do the actual writing of the filtered row data from the chosen filter. */ + png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); + +#ifdef PNG_WRITE_FILTER_SUPPORTED +#ifdef 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_WRITE_FILTER_SUPPORTED */ +} + + +/* Do the actual writing of a previously filtered row. */ +static void +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t avail/*includes filter byte*/) +{ + png_debug(1, "in png_write_filtered_row"); + + png_debug1(2, "filter = %d", filtered_row[0]); + /* Set up the zlib input buffer */ + + png_ptr->zstream.next_in = filtered_row; + png_ptr->zstream.avail_in = 0; + /* Repeat until we have compressed all the data */ + do + { + int ret; /* Return of zlib */ + + /* Record the number of bytes available - zlib supports at least 65535 + * bytes at one step, depending on the size of the zlib type 'uInt', the + * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). + * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. + * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a + * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called + * with smaller chunks of data. + */ + if (png_ptr->zstream.avail_in == 0) + { + if (avail > ZLIB_IO_MAX) + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + avail -= ZLIB_IO_MAX; + } + + else + { + /* So this will fit in the available uInt space: */ + png_ptr->zstream.avail_in = (uInt)avail; + avail = 0; + } + } + + /* 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); + } + /* Repeat until all data has been compressed */ + } while (avail > 0 || png_ptr->zstream.avail_in > 0); + + /* 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); + +#ifdef 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,121 @@ +# ---------------------------------------------------------------------------- +# CMake file for libtiff. See root CMakeLists.txt +# +# ---------------------------------------------------------------------------- +project(${TIFF_LIBRARY}) + +include(CheckFunctionExists) +include(CheckIncludeFile) + +check_include_file(assert.h HAVE_ASSERT_H) +check_include_file(fcntl.h HAVE_FCNTL_H) +check_include_file(io.h HAVE_IO_H) +check_function_exists(jbg_newlen HAVE_JBG_NEWLEN) +check_function_exists(mmap HAVE_MMAP) +check_include_file(search.h HAVE_SEARCH_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(unistd.h HAVE_UNISTD_H) + +if(WIN32) + set(USE_WIN32_FILEIO 1) +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmakein" + "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" @ONLY) + +ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIR}) + +set(lib_srcs + tif_aux.c + tif_close.c + tif_codec.c + tif_color.c + tif_compress.c + tif_dir.c + tif_dirinfo.c + tif_dirread.c + tif_dirwrite.c + tif_dumpmode.c + tif_error.c + tif_extension.c + tif_fax3.c + tif_fax3sm.c + tif_flush.c + tif_getimage.c + tif_jbig.c + tif_jpeg_12.c + tif_jpeg.c + tif_luv.c + tif_lzma.c + tif_lzw.c + tif_next.c + tif_ojpeg.c + tif_open.c + tif_packbits.c + tif_pixarlog.c + tif_predict.c + tif_print.c + tif_read.c + tif_strip.c + tif_swab.c + tif_thunder.c + tif_tile.c + tif_version.c + tif_warning.c + tif_write.c + tif_zip.c + tif_stream.cxx + t4.h + tif_dir.h + tif_fax3.h + tiff.h + tiffio.h + tiffiop.h + tiffvers.h + tif_predict.h + uvcode.h + tiffio.hxx + "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" + ) + +if(UNIX) + list(APPEND lib_srcs tif_unix.c) +endif() + +if(WIN32) + list(APPEND lib_srcs tif_win32.c) +endif(WIN32) + +ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-prototypes -Wmissing-declarations -Wundef -Wunused -Wsign-compare + -Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter) +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4100 /wd4127 /wd4311 /wd4701 /wd4706) # vs2005 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4267 /wd4305 /wd4306) # vs2008 Win64 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4703) # vs2012 + +ocv_warnings_disable(CMAKE_C_FLAGS /wd4267 /wd4244 /wd4018) + +if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") +endif() + +add_library(${TIFF_LIBRARY} STATIC ${lib_srcs}) +target_link_libraries(${TIFF_LIBRARY} ${ZLIB_LIBRARIES}) + +set_target_properties(${TIFF_LIBRARY} + PROPERTIES + OUTPUT_NAME "${TIFF_LIBRARY}" + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${TIFF_LIBRARY} PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS ${TIFF_LIBRARY} ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/COPYRIGHT diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/COPYRIGHT --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/COPYRIGHT 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/COPYRIGHT 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,21 @@ +Copyright (c) 1988-1997 Sam Leffler +Copyright (c) 1991-1997 Silicon Graphics, Inc. + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/ChangeLog diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/ChangeLog --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/ChangeLog 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,5753 @@ +2012-06-15 Frank Warmerdam + + * libtiff 4.0.2 released. + + * tools/tif2pdf.c, tools/tifdump.c: avoid unitialized variable + warnings with clang. + +2012-06-15 Tom Lane + + * tools/tiff2pdf.c: Defend against integer overflows while + calculating required buffer sizes (CVE-2012-2113). + +2012-06-12 Frank Warmerdam + + * libtiff/tif_print.c: Be careful about printing corrupt inknames. + + * libtiff/tif_fax3.c: Ensure runs array is initialized to zeros. + +2012-06-07 Frank Warmerdam + + * libtiff/tif_print.c: avoid pretty printing other fields when + we don't have the proper amount and type of data or if the field + is actually autodefined. + +2012-06-05 Frank Warmerdam + + * libtiff/tif_tile.c, libtiff/tif_strip.c: Ensure that illegal + ycbcrsubsampling values result in a runtime error, not just an + assertion. + + * tests/custom_dir.c: Add testing of EXIF and custom directory + reading and writing. + + * libtiff/tif_dir.c, libtiff/tiffio.h: Add TIFFCreateCustomDirectory() + and TIFFCreateEXIFDirectory() functions. + + * libtiff/tif_dir.c, tif_print.c : Remove FIELD_CUSTOM handling for + PAGENUMBER, HALFTONEHINTS, and YCBCRSUBSAMPLING. Implement DOTRANGE + differently. This is to avoid using special TIFFGetField/TIFFSetField + rules for these fields in non-image directories (like EXIF). + +2012-06-04 Frank Warmerdam + + * libtiff/tif_jpeg.c: Remove code for fixing up h_sampling and v_sampling + in JPEGPreDecode(). If a fixup will be done it needs to be done sooner + in JPEGFixupTagsSubsampling() or else buffer sized may be wrong. + +2012-06-01 Frank Warmerdam + + * tools/tiffinfo.c: Do not try to read image data in EXIF directories. + + * libtiff/tif_getimage.c: added support for _SEPARATED CMYK images. + http://bugzilla.maptools.org/show_bug.cgi?id=2379 + + * libtiff/tif_unix.c: use strerror() to return a more specific error message + on failed open. + http://bugzilla.maptools.org/show_bug.cgi?id=2341 + + * libtiff/tif_jpeg.c: Fix JPEGDecodeRaw() bugs. + http://bugzilla.maptools.org/show_bug.cgi?id=2386 + + * tests/decode_raw.c, tests/images/quad-tile.jpg.tiff: add limited support + for testing jpeg in tiff image decoding including the "raw" decode interface. + +2012-05-31 Frank Warmerdam + + * libtiff/tif_jpeg.c: avoid overrunning the end of the output buffer in + JPEGDecodeRaw() - mostly likely to occur when there is confusion about + sampling values. + + * libtiff/tif_read.c: Make sure tif_rawdatasize is cleared when tif_rawdata is freed. + + * libtiff/tif_getimage.c: Add support for greyscale+alpha c/o Jérémie Laval. + http://bugzilla.maptools.org/show_bug.cgi?id=2398 + +2012-05-29 Frank Warmerdam + + * libtiff/tif_dir.c: avoid using specific set/get logic to process fields in custom directories, + like EXIF directories. This fixes problems like a tag "320" existing in a custom directory getting + processed as if it were a colormap when it isn't really. Damn the wide variety of argument formulations + to get/set functions for different tags! + + * libtiff/tif_dir.c: Ensure that we keep track of when tif_rawdata + is a pointer into an mmap()ed file via TIFF_BUFFERMMAP flag. + +2012-05-24 Frank Warmerdam + + * libtiff/tif_pixarlog.c: Allocate working buffer one word larger since we "forward + accumulate" and overwrite the end by one word in at least some cases. + +2012-05-23 Frank Warmerdam + + * libtiff/tif_pixarlog.c: avoid accessing out of the lookup arrays for out of range inputs. + + * tools/tiffinfo.c: initialize h=0 to avoid undefined variable for degenerate files. + + * libtiff/tif_ojpeg.c: if OJPEGWriteHeader() fails once do not bother trying again on + the same image. + + * libtiff/tif_ojpeg.c: make things more resilient in the face of files without + stripbytecounts or stripoffsets or where loading these fails. + + * libtiff/tif_print.c: be careful about whether min/max values are singular + or one per sample. + + * libtiff/tif_print.c: Avoid confusion about count size when printing custom fields. + May affect things like ISOSpeedRatings. + + * libtiff/tif_dir.c: avoid one byte past end of ink names reading + in some cases. + +2012-05-19 Bob Friesenhahn + + * man/TIFFGetField.3tiff: Correct the 'count' field type in the + example for how to retreive the value of unsupported tags. + +2012-03-30 Frank Warmerdam + + * tif_getimage.c: Fix size overflow (zdi-can-1221,CVE-2012-1173) + care of Tom Lane @ Red Hat. + +2012-02-18 Bob Friesenhahn + + * libtiff 4.0.1 released. + + * Update automake used to 1.11.3. + + * libtiff/tiffio.h: Use double-underbar syntax in GCC printf + attribute specification to lessen the risk of accidental macro + substitution. Patch from Vincent Torri. + +2012-01-31 Frank Warmerdam + + * libtiff/tif_dir.c, libtiff/tif_dirread.c: Extra caution around + assumption tag fetching is always successful. + + * libtiff/tif_jpeg.c: Extra caution for case where sp is NULL. + +2012-01-22 Bob Friesenhahn + + * configure.ac: Add support for using library symbol versioning on + ELF systems with the GNU linker. Support is enabled via + --enable-ld-version-script. Disabled by default for now until + there is a decision for how to deploy a libtiff with versioned + symbols after libtiff 4.0.0 was already released. + +2011-12-22 Bob Friesenhahn + + * libtiff/tif_win32.c: Eliminate some minor 64-bit warnings in + + tif_win32.c. Patch by Edward Lam. + + * configure.ac: Add libtiff private dependency on -llzma for + pkg-config. Patch by Mark Brand. + Updated Automake to 1.11.2. + +2011-12-21 Bob Friesenhahn + + * libtiff 4.0.0 released. + +2011-12-08 Frank Warmerdam + + * libtiff/tif_dirread.c, libtiff/tif_read.c: more cautious checking + of _TIFFFillStriles() results (#gdal 4372) + +2011-12-07 Frank Warmerdam + + * libtiff/tif_dirread.c: fixes to deal with invalid files where + _TIFFFillStriles() fails, and we try to chop up strips (gdal #4372) + + * libtiff/tif_dirread.c: fix error reporting when there is no + tag information struct and name (gdal #4373) + +2011-10-22 Bob Friesenhahn + + * Update GNU libtool to 2.4.2. + + * tools/tiffsplit.c (tiffcp): TIFFGetField count field should be + uint32 type for TIFFTAG_JPEGTABLES. Patch by Christophe + Deroulers. + +2011-06-21 Frank Warmerdam + + * libtiff/libtiff.def: Restore TIFFMergeFieldInfo. + +2011-05-31 Jim Meyering + + * libtiff/tif_dirread.c (TIFFFetchStripThing): Free "data" also + upon failure to allocate "resizeddata". + * tools/tiff2ps.c (PSDataBW): Zero buffer *after* checking for + allocation failure, not before. + * libtiff/tif_ojpeg.c: plug leaks on OJPEG read failure path + * tools/rgb2ycbcr.c (cvtRaster): unchecked malloc + * libtiff/tif_jpeg.c, tools/tiff2pdf.c, tools/tiff2ps.c: mark + NULL-deref and possible overflow + * tools/tiff2pdf.c: remove decl+set of set-but-not-used local, "written" + * libtiff/tif_jpeg.c (JPEGInitializeLibJPEG): Remove declaration + and set of otherwise unused local, data_is_empty. + * libtiff/tif_jpeg.c (JPEGDecodeRaw) [JPEG_LIB_MK1_OR_12BIT]: + Diagnose out-of-memory failure and return 0 rather than + dereferencing NULL. + +2011-05-24 Frank Warmerdam + + * libtiff/tif_dirread.c: produce special error message for zero tag + directories instead of error out on the malloc(0) failure. + +2011-05-16 Frank Warmerdam + + * libtiff/tif_dirinfo.c: Restore TIFFMergeFieldInfo() and + related declarations as they are in active use by libraries + such as libgeotiff, and work just fine. (#2315) + +2011-04-20 Frank Warmerdam + + * libtiff/tif_dirinfo.c,tiffio.h: Remove the obsolete + TIFFMergeFieldInfo/TIFFFindFieldInfo/TIFFFindFieldInfoByName API. + http://bugzilla.maptools.org/show_bug.cgi?id=2315 + + * libtiff/libtiff.def: add some missing (64bit) APIs. + http://bugzilla.maptools.org/show_bug.cgi?id=2316 + +2011-04-09 Bob Friesenhahn + + * libtiff 4.0.0beta7 released. + +2011-04-09 Bob Friesenhahn + + * configure.ac: Should use AC_CANONICAL_HOST since host specifies + the run-time target whereas target is used to specify the final + output target if the package is a build tool (like a compiler), + which libtiff is not. Resolves libtiff bug 2307 "Use + AC_CANONICAL_HOST macro". + +2011-04-02 Bob Friesenhahn + + * configure.ac: Support configuring TIFF_INT64_FORMAT and + TIFF_UINT64_FORMAT appropriately for MinGW32. + + * tools/tiffdump.c (ReadDirectory): MinGW32 needs to use WIN32 + printf conventions for 64-bit types because it uses the WIN32 CRT. + + * libtiff/{tif_dumpmode.c,tif_luv.c,tif_lzw.c,tif_print.c, + tif_read.c,tif_strip.c,tif_thunder.c}: MinGW32 needs to use WIN32 + printf conventions for 64-bit types because it uses the WIN32 CRT. + + * tools/tiff2pdf.c (t2p_write_pdf_string): Fix printf syntax not + understood by WIN32 CRT. + + * libtiff/tif_ojpeg.c: Fixes to compile with MinGW32 GCC. + + * tools/fax2ps.c (main): Use tmpfile() rather than mkstemp() since + it is much more portable. Tmpfile is included in ISO/IEC + 9899:1990 and the WIN32 CRT. + +2011-03-26 Frank Warmerdam + + * tools/tiffset.c: add -d and -sd switches to allow operation on + a particular directory, not just the first (jef). + +2011-03-21 Frank Warmerdam + + * libtiff/tif_thunder.c: Correct potential buffer overflow with + thunder encoded files with wrong bitspersample set. The libtiff + development team would like to thank Marin Barbella and TippingPoint's + Zero Day Initiative for reporting this vulnerability (ZDI-CAN-1004, + CVE-2011-1167). + http://bugzilla.maptools.org/show_bug.cgi?id=2300 + +2011-03-10 Frank Warmerdam + + * libtiff/tif_fax3.h: Fix to last change allowing zero length + runs at the start of a scanline - needed for legal cases. + +2011-03-02 Frank Warmerdam + + * libtiff/tif_fax3.h: Protect against a fax VL(n) codeword commanding + a move left. Without this, a malicious input file can generate an + indefinitely large series of runs without a0 ever reaching the right + margin, thus overrunning our buffer of run lengths. Per CVE-2011-0192. + This is a modified version of a patch proposed by Drew Yao of Apple + Product Security. It adds an unexpected() report, and disallows the + equality case, since emitting a run without increasing a0 still allows + buffer overrun. + +2011-02-23 Frank Warmerdam + + * libtiff/tif_jpeg.c: avoid divide by zero in degenerate case (#2296) + + * tools/tiff2rgba.c: close source file on error to make leak + detection easier. + + * libtiff/tif_getimage.c: avoid leaks if TIFFRGBAImageBegin() fails. + + http://bugzilla.maptools.org/show_bug.cgi?id=2295 + +2011-02-22 Frank Warmerdam + + * libtiff/tif_lzma.c: Maintain tif_rawcc/tif_rawcp (CHUNKY_STRING_READ + _SUPPORT) + +2011-02-18 Frank Warmerdam + + * configure.ac, configure: Added support for --enable-chunky-strip-read + configure option to enable the experimental feature from a couple + months ago for reading big strips in chunks. + + * configure.ac, tif_read.c, tif_readdir.c, tif_dir.h, tiffiop.h, + tif_write.c, tif_print.c, tif_jpeg.c, tif_dirwrite.c, tif_write.c: + Implement optional support for deferring the load of strip/tile + offset and size tags for optimized scanning of directories. Enabled + with the --enable-defer-strile-load configure option (DEFER_STRILE_LOAD + #define in tif_config.h). + +2011-02-11 Frank Warmerdam + + * libtiff/tif_print.c: remove unused variable. + +2011-02-09 Frank Warmerdam + + * libtiff/tif_win32.c: avoid error/warning buffer overrun problem + with non-console (popup message) builds on win32. + + http://bugzilla.maptools.org/show_bug.cgi?id=2293 + +2011-01-24 Olivier Paquet + + * libtiff/{tif_dir.{h,c}, tif_dirinfo.c, tif_dirread.c, tif_dirwrite.c, + tif_print.c, tiff.h, tiffiop.h} : Added support for + TIFFTAG_SMINSAMPLEVALUE and TIFFTAG_SMAXSAMPLEVALUE to have different + values for each sample. Presents the min/max of all samples by default for + compatibility. TIFFSetField/TIFFGetField can be made to handle those tags + as arrays by changing the new TIFFTAG_PERSAMPLE pseudo tag. + http://www.asmail.be/msg0055458208.html + +2011-01-06 Frank Warmerdam + + * libtiff/tif_pixarlog.c: Note that tif_rawcc/tif_rawcp are not + maintained. + + * libtiff/tif_zip.c: Maintain tif_rawcc/tif_rawcp when decoding + for CHUNKY_STRIP_READ_SUPPORT. + + * libtiff/tif_jpeg.c: ensure that rawcc and rawcp are maintained + during JPEGPreDecode and JPEGDecode calls. + * libtiff/tif_read.c: larger read ahead for CHUNKY_STRIP_READ_SUPPORT, + as compression formats like JPEG keep 16 lines interleaved in a sense + and might need to touch quite a bit of data. + + http://trac.osgeo.org/gdal/ticket/3894 + +2011-01-03 Lee Howard + + * libtiff/tif_jpeg.c: Fix regressions with 2 and 3 band images + caused by commit on 2010-12-14. Submitted by e-mail from + Even Rouault + +2010-12-31 Olivier Paquet + + * libtiff/tif_dirwrite.c: Fixed writing of TIFFTAG_REFERENCEBLACKWHITE. + http://bugzilla.maptools.org/show_bug.cgi?id=2266 + +2010-12-23 Andrey Kiselev + + * tools/tiffcp.c, man/tiffcp.1: Added support for specifying the + compression level parameter (preset) for Deflate and LZMA encoders, + e.g "-c lzma:p1" or "-c zip:p9". + + * libtiff/tif_lzma.c: Properly set the LZMA2 compression level + (preset) in LZMAVSetField(). + +2010-12-18 Bob Friesenhahn + + * libtiff/Makefile.am (libtiff_la_SOURCES): Added tif_lzma.c to + Makefile. + +2010-12-14 Andrey Kiselev + + * configure.ac, libtiff/{tif_codec.c, tif_config.h.in, tiff.h, + tiffiop.h, tif_lzma.c}, tools/tiffcp.c, man/tiffcp.1: Implement a new + TIFF compression scheme LZMA reserving a new value 34925 for + Compression tag. As per + bug http://bugzilla.maptools.org/show_bug.cgi?id=2221 + +2010-12-14 Lee Howard + + * libtiff/tif_dirread.c: tolerate some cases where + FIELD_COLORMAP is missing + http://bugzilla.maptools.org/show_bug.cgi?id=2189 + +2010-12-14 Lee Howard + + * libtiff/tif_read.c: change read_ahead to tmsize_t + http://bugzilla.maptools.org/show_bug.cgi?id=2222 + +2010-12-14 Lee Howard + + * configure.ac, libtiff/Makefile.am: Build tif_win32.c on + Windows except on Cygwin + http://bugzilla.maptools.org/show_bug.cgi?id=2224 + +2010-12-14 Lee Howard + + * tools/gif2tiff.c: fix buffer overrun + http://bugzilla.maptools.org/show_bug.cgi?id=2270 + +2010-12-14 Lee Howard + + * libtiff/tif_jpeg.c: reduce usage of JCS_UNKNOWN in order + to improve compatibility with various viewers + submitted by e-mail from Dwight Kelly + +2010-12-13 Lee Howard + + * tools/fax2ps.c: be consistent with page-numbering + http://bugzilla.maptools.org/show_bug.cgi?id=2225 + +2010-12-13 Lee Howard + + * libtiff/tif_color.c: prevent crash in handling bad TIFFs + resolves CVE-2010-2595 + http://bugzilla.maptools.org/show_bug.cgi?id=2208 + +2010-12-13 Lee Howard + + * tools/tiffcrop.c: new release by Richard Nolde + http://bugzilla.maptools.org/show_bug.cgi?id=2004 + +2010-12-12 Lee Howard + + * tools/tiff2pdf.c: fix colors for images with RGBA + interleaved data + http://bugzilla.maptools.org/show_bug.cgi?id=2250 + +2010-12-12 Lee Howard + + * libtiff/tif_dirread.c: fix for Zeiss LSM and Canon CR2 files + http://bugzilla.maptools.org/show_bug.cgi?id=2164 + +2010-12-11 Lee Howard + + * tools/tiff2pdf.c: remove invalid duplication for Lab + http://bugzilla.maptools.org/show_bug.cgi?id=2162 + +2010-12-11 Lee Howard + + * libtiff/tif_jpeg.c: fix use of clumplines calculation + http://bugzilla.maptools.org/show_bug.cgi?id=2149 + +2010-12-11 Lee Howard + + * tools/fax2ps.c: replace unsafe tmpfile() with mkstemp() + http://bugzilla.maptools.org/show_bug.cgi?id=2118 + +2010-12-11 Lee Howard + + * libtiff/tif_ojpeg.c, libtiff/tif_pixarlog.c, + libtiff/tif_zip.c: fix build errors for VC6 + http://bugzilla.maptools.org/show_bug.cgi?id=2105 + +2010-12-11 Lee Howard + + * libtiff/tif_stream.cxx: warnings cleanup + http://bugzilla.maptools.org/show_bug.cgi?id=2091 + * libtiff/tif_dirread.c: warnings cleanup + http://bugzilla.maptools.org/show_bug.cgi?id=2092 + +2010-12-11 Lee Howard + + * tools/tiff2pdf.c: add fill-page option + http://bugzilla.maptools.org/show_bug.cgi?id=2051 + +2010-12-11 Lee Howard + + * libtiff/tif_dirread.c: modify warnings + http://bugzilla.maptools.org/show_bug.cgi?id=2016 + +2010-12-11 Lee Howard + + * libtiff/tif_ojpeg.c: fix buffer overflow on problem data + http://bugzilla.maptools.org/show_bug.cgi?id=1999 + +2010-12-11 Lee Howard + + * tools/tiffinfoce.c: strip byte counts are uint64* now + +2010-12-11 Lee Howard + + * libtiff/tif_ojpeg.c: fix crash when reading a TIFF with a zero + or missing byte-count tag + * tools/tiffsplit.c: abort when reading a TIFF without a byte-count + per http://bugzilla.maptools.org/show_bug.cgi?id=1996 + +2010-12-08 Lee Howard + + * libtiff/tif_dirread.c: fix crash when reading a badly-constructed + TIFF per http://bugzilla.maptools.org/show_bug.cgi?id=1994 + +2010-12-06 Lee Howard + + * libtiff/tif_open.c: Fix mode check before opening a file. + http://bugzilla.maptools.org/show_bug.cgi?id=1906 + +2010-11-27 Bob Friesenhahn + + * libtiff-4.pc.in: Added libtiff pkg-config .pc file support. + Patch by Vincent Torri. + +2010-10-21 Frank Warmerdam + + * tools/tiffinfo.c: avoid direct reference to _TIFFerrorHandler. + + * libtiff/tif_config.vc.h: define snprintf to _snprintf for tiff2pdf. + + * libtiff/libtiff.def: export _TIFFCheckMalloc for tools. + +2010-09-25 Lee Howard + + * tools/tiff2ps.c: improvements and enhancements from Richard Nolde + with additional command line options for Document Title, + Document Creator, and Page Orientation + +2010-07-13 Bob Friesenhahn + + * tools/tiffcrop.c: Patch from Richard Nolde to avoid a + potentially unterminated buffer due to using an exceptionally long + file name. + +2010-07-08 Andrey Kiselev + + * tools/tiff2pdf.c: Fixed ID buffer filling in + t2p_write_pdf_trailer(), thanks to Dmitry V. Levin. + +2010-07-07 Andrey Kiselev + + * libtiff/tif_dirread.c: Really reset the tag count in CheckDirCount() + to expected value as the warning message suggests. As per bug + http://bugzilla.maptools.org/show_bug.cgi?id=1963 + +2010-07-06 Andrey Kiselev + + * tools/tiffset.c: Properly handle TIFFTAG_PAGENUMBER, + TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING, TIFFTAG_DOTRANGE + which should be set by value. + + * libtiff/tif_dirinfo.c: Don't use assertions in _TIFFFieldWithTag() + and _TIFFFieldWithName() if the tag is not found in the tag table. + This should be normal situation and returned NULL value should be + properly handled by the caller. + +2010-07-02 Andrey Kiselev + + * libtiff/tif_getimage.c: Avoid wrong math du to the signed/unsigned + integer type conversions. As per bug + http://bugzilla.maptools.org/show_bug.cgi?id=2207 + + * tools/{tiff2bw.c, thumbnail.c, pal2rgb.c}: Fix the count for + WhitePoint tag as per bug + http://bugzilla.maptools.org/show_bug.cgi?id=2042 + + * libtiff/tif_getimage.c: Check the number of samples per pixel when + working with YCbCr image in PickContigCase(). As per bug + http://bugzilla.maptools.org/show_bug.cgi?id=2216 + + * libtiff/tif_dir.c: Set the bogus post-decoding hook when processing + TIFFTAG_BITSPERSAMPLE in _TIFFVSetField() for the case of 8 bit when + we don't need any post-processing. That helps to reset the hook if we + previously set this field to some other value and the hook was + initialized accordingly. As per bug + http://bugzilla.maptools.org/show_bug.cgi?id=2035 + +2010-07-01 Andrey Kiselev + + * tools/tiffgt.c: Properly check the raster buffer allocations for + integer overflows. As per bug + http://bugzilla.maptools.org/show_bug.cgi?id=2108 + + * m4/acinclude.m4: Update GL/GLU/GLUt/Pthread macros from the + upstream. + + * libtiff/{tif_aux.c, tif_strip.c, tif_tile.c, tiffiop.h}: Move + multiply_32() and multiply_64() functions into tif_aux.c file and + rename them into _TIFFMultiply32() and _TIFFMultiply64() respectively. + +2010-06-30 Andrey Kiselev + + * tools/tiff2pdf.c: Better generation of ID field in + t2p_write_pdf_trailer(). Get rid of GCC aliasing warnings. + + * tools/tiff2pdf.c: Fixed computation of the tile buffer size when + converting JPEG encoded tiles. + + * tools/tiff2pdf.c: Better handling of string fields, use static + string buffers instead of dynamically allocated, use strncpy() instead + of strcpy(), control the string lengths. + +2010-06-25 Andrey Kiselev + + * tools/tiffcp.c: Initialize buffer arrays with zero to avoid + referencing to uninitialized memory in some cases (e.g. when tile size + set bigger than the image size). + +2010-06-15 Bob Friesenhahn + + * tools/tiffcrop.c: Patch from Richard Nolde. Reject YCbCr + subsampled data since tiffcrop currently doesn't support it. Fix + JPEG support. + +2010-06-13 Frank Warmerdam + + * libtiff/tif_dirinfo.c: Fix invocation of tag compare function (#2201) + + * tools/tiff2pdf.c: Fix assorted bugs in tiff2pdf: missing "return" + in t2p_read_tiff_size() causes t2p->tiff_datasize to be set entirely + wrong for COMPRESSION_JPEG case, resulting in memory stomp if actual + size is larger. Also, there are a bunch of places that try to + memset() a malloc'd buffer before checking for malloc failure, which + would result in core dump if there actually were a failure. (#2211) + +2010-06-11 Bob Friesenhahn + + * libtiff/tiffiop.h (TIFFSafeMultiply): Need more castings to + avoid compiler warnings if parameter types are not sign + consistent. + + * libtiff 4.0.0alpha6 released. + + * tools/tiffcrop.c: Applied patch from Richard Nolde: Corrected + European page size dimensions. Added an option to allow the user + to specify a custom page size on the command line. Fix the case + where a page size specified with a fractional part was being + coerced to an integer by retyping the variables that define the + paper size. + + * html/index.html: Update for the 3.9.3 release. + + * tools/tiffcp.c (tiffcp): Applied Tom Lane's patch to reject + YCbCr subsampled data since tiffcp currently doesn't support it. + http://bugzilla.maptools.org/show_bug.cgi?id=2097 + + * Update libtool to version 2.2.10. + +2010-06-10 Bob Friesenhahn + + * libtiff/tiffiop.h (TIFFSafeMultiply): Work properly if + multiplier is zero. + +2010-06-09 Bob Friesenhahn + + * libtiff/tif_fax3.c (Fax3SetupState): Yesterday's fix for + CVE-2010-1411 was not complete. + + * libtiff/tiffiop.h (TIFFSafeMultiply): New macro to safely + multiply two integers. Returns zero if there is an integer + overflow. + + * tools/tiffcp.c (main): tiffcp should not leak memory if an error + is reported when reading the input file. + +2010-06-08 Bob Friesenhahn + + * Update libtool to version 2.2.8. + + * libtiff/tif_fax3.c (Fax3SetupState): Avoid under-allocation of + buffer due to integer overflow in TIFFroundup() and several other + potential overflows. In conjunction with the fix to TIFFhowmany(), + fixes CVE-2010-1411. + + * libtiff/tiffiop.h (TIFFhowmany): Return zero if parameters would + result in an integer overflow. This causes TIFFroundup() to also + return zero if there would be an integer overflow. + + * contrib: Add an emacs formatting mode footer to all source files + so that emacs can be effectively used. + +2010-06-03 Oliver Chen Feng + + * libtiff/tools/tiffcp.c: add a new option -x to force merged tiff + file PAGENUMBER value in sequence for users who care the page + sequence, this will also prevent tiff2pdf from creating pdf file from + the merged tiff file with wrong page sequence. + +2010-05-08 Olivier Paquet + + * libtiff/tif_dirread.c: Restored TIFFReadDirEntryFloat function in order + to add missing TIFF_SETGET_FLOAT case to TIFFFetchNormalTag. + * libtiff/tif_dirinfo.c: Use correct set_field_type for + TIFFTAG_PIXAR_FOVCOT so it is readable again (regression from 3.9.2). + http://bugzilla.maptools.org/show_bug.cgi?id=2192 + +2010-05-07 Frank Warmerdam + + * libtiff/tif_jpeg.c: Ensure that quality is always set in + JPEGPreEncode(), not just when we want to output local tables. + Otherwise the quality used during compression may not be right and + might not match the tables in the tables tag. This bug only occurs + when seeking between directories in the midst of writing blocks. + http://trac.osgeo.org/gdal/ticket/3539 + +2010-05-06 Andrey Kiselev + + * html/man/TIFFGetField.3tiff.html, html/man/TIFFSetField.3tiff.html: + Regenerated from the source. + +2010-05-05 Olivier Paquet + + * libtiff/tif_print.c: Fixed printing of TIFFTAG_REFERENCEBLACKWHITE which + had stopped working. Also made it always print 6 floats instead of + 2*SamplesPerPixel. + http://bugzilla.maptools.org/show_bug.cgi?id=2191 + http://bugzilla.maptools.org/show_bug.cgi?id=2186 + * man/TIFFGetField.3tiff, man/TIFFSetField.3tiff: Fixed doc to reflect the + fact that libtiff considers TIFFTAG_REFERENCEBLACKWHITE to be 6 floats. + +2010-05-05 Frank Warmerdam + + * libtiff/tif_jpeg.c: Fix to use memcmp(), not memcpy() when checking + if the jpeg table was written. This is a fix for the last fix on 04-21. + +2010-04-21 Frank Warmerdam + + * libtiff/tif_jpeg.c: avoid preparing jpeg tables everytime + JPEGSetupEncode() is called if the tables already seem to be + established. This prevents spurious updates and rewriting of + directories with jpegtables when doing updates to existing images. + http://trac.osgeo.org/gdal/ticket/3539 + +2010-04-20 Olivier Paquet + + * libtiff/tif_dirinfo.c: Use correct set_field_type for + TIFFTAG_PIXAR_IMAGEFULLWIDTH, TIFFTAG_PIXAR_IMAGEFULLLENGTH, + TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN and TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA. + They were unreadable with TIFF_SETGET_UNDEFINED, a regression from 3.9.2. + http://bugzilla.maptools.org/show_bug.cgi?id=2139 + +2010-04-10 Bob Friesenhahn + + * libtiff/tif_dir.c (_TIFFVSetField): Add a special error case for + when the tag count value is zero. Error handling is still a + regression since in 3.9.2, empty tags are skipped (with a warning) + rather than returning a hard error and refusing to read the file. + + * tools/ppm2tiff.c (main): While case for parsing comment line + requires extra parenthesis to work as expected. Reported by + Thomas Sinclair. + +2010-04-02 Frank Warmerdam + + * libtiff/tif_read.c (primarily): Add support for + CHUNKY_STRIP_READ_SUPPORT where large strips are + read in chunks for applications using TIFFReadScanline(). + This is intended to make it more practical work with very + large compressed one-strip files. Feature is off by default. + Enable by defining CHUNK_STRIP_READ_SUPPORT as a macro. + http://trac.osgeo.org/gdal/ticket/3514 + +2010-03-31 Frank Warmerdam + + * libtiff/tif_flush.c: Use TIFFRewriteDirectory() when flushing + directories so previously placed directories will be migrated to + the end of file if needed. + +2010-03-30 Frank Warmerdam + + * libtiff/tif_lzw.c: change type of dec_bitsleft field to uint64 + to support operating on strips/tiles of more than 256MB. + http://trac.osgeo.org/gdal/ticket/3512 + +2010-03-10 Bob Friesenhahn + + * libtiff/tif_aux.c (_TIFFCheckRealloc): Improve error message so + that it is clearly a memory allocation error message, and also + includes the size of the allocation request. + +2010-02-22 Lee Howard + + * libtiff/tif_jpeg.c: Do not generate a JPEGTables tag when creating + the JPEG TIFF as is is not required in order to prevent it from + being unused and filled with invalid data. (Leave it to be + generated by later activity.) + http://bugzilla.maptools.org/show_bug.cgi?id=2135 + * tools/tiff2pdf.c: Write the JPEG SOI headers into the TIFF strip + data rather than skipping them. This fixes the ability to view in + Acrobat Reader, Evince, and Ghostscript. + http://bugzilla.maptools.org/show_bug.cgi?id=2135 + * libtiff/tif_fax3.c: Don't return error on badly-terminated MMR + strips. + http://bugzilla.maptools.org/show_bug.cgi?id=2029 + +2009-12-03 Frank Warmerdam + + * libtiff/tif_jpeg.c: Made JPEGDecodeRaw() check for buffer overruns. + Made so that when working with downsampled images a stub function + reporting an error is used for tif_decoderow. We cannot meaningfully + support reading scanlines in this situation. (#1936) + + * libtiff/tif_jpeg.c: Ensure that tif_scanlinesize is computed after + resetting of the upsampling values (gdal:#3259). + http://bugzilla.maptools.org/show_bug.cgi?id=1936 + +2009-11-30 Frank Warmerdam + + * contrib/dbs/tiff-grayscale.c, contrib/tif-palette.c, + tools/ras2tiff.c: Fix resource leaks on error. + http://bugzilla.maptools.org/show_bug.cgi?id=2121 + + * libtiff/tif_{aux.c,dir.c,dir.h,dirinfo.c}: Return to handling + TIFFTAG_REFERENCEBLACKWHITE as a field in the TIFF directory instead + of as a custom(generic) field to avoid a potential reentrancy problem. + http://bugzilla.maptools.org/show_bug.cgi?id=2125 + + * libtiff/tif_color.c, libtiff/tif_getimage.c, libtiff/tiffio.h, + man/TIFFcolor.3tiff: Make TIFFDisplay argument in TIFFCIELabToRGBInit + const, and display_sRGB static and const. + http://bugzilla.maptools.org/show_bug.cgi?id=2124 + +2009-11-04 Bob Friesenhahn + + * libtiff 4.0.0alpha5 released. + +2009-11-03 Bob Friesenhahn + + * tools/tiffcrop.c: Updated tiffcrop from Richard Nolde. This + version has undergone substantial testing with arbitrary sample + bit depths. Also eliminates GCC compilation warnings. + +2009-11-02 Bob Friesenhahn + + * port/libport.h: Add extern declarations for getopt standard + globals. + +2009-10-31 Bob Friesenhahn + + * libtiff/tif_lzw.c (LZWDecode, LZWDecodeCompat): Fix warnings + noticed in 64-bit build of libtiff with Visual Studio 2005. + Resolves "Bug 2067 - Visual Studio 2005 64-bit warnings in + tif_lzw.c", http://bugzilla.maptools.org/show_bug.cgi?id=2067 + + * libtiff/tif_pixarlog.c (PixarLogEncode): Fix non-important + warning noticed in Visual Studio 2005 build. Resolves "Bug 2068 - + Visual Studio 2005 64-bit warning in tif_pixarlog.c", + http://bugzilla.maptools.org/show_bug.cgi?id=2068 + +2009-10-29 Bob Friesenhahn + + * libtiff/tif_dirread.c: Eliminate GCC "dereferencing type-punned + pointer" warnings. + +2009-10-28 Bob Friesenhahn + + * html/tools.html: Add manual page links, and a summary + description of tiffcrop. + +2009-10-07 Bob Friesenhahn + + * configure.ac: x86_64 should use the same fill order as i386. + +2009-09-24 Bob Friesenhahn + + * tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop from Richard + Nolde. Major updates to add significant functionality for reading + and writing tile based images with bit depths not a multiple of 8 + which cannot be handled by tiffcp. + +2009-09-03 Bob Friesenhahn + + * libtiff/tif_ojpeg.c (OJPEGWriteHeaderInfo): IJG JPEG 7 needs + do_fancy_upsampling=FALSE in order to read raw data. Resolves + "Bug 2090 - OJPEG crash with libjpeg v7". + http://bugzilla.maptools.org/show_bug.cgi?id=2090 + +2009-09-03 Frank Warmerdam + + * libtiff/tif_getimage.c: Fixed error recognition handling in RGBA + interface when stoponerror is set. + http://bugzilla.maptools.org/show_bug.cgi?id=2071 + +2009-08-30 Bob Friesenhahn + + * tools/{tiffcrop.c,tiffgt.c}: Applied patch from Oden Eriksson to + fix build with gcc when using the "-Wformat + -Werror=format-security" flags. + +2009-08-29 Bob Friesenhahn + + * test/{bmp2tiff_palette.sh, bmp2tiff_rgb.sh, gif2tiff.sh, + ppm2tiff_pbm.sh, ppm2tiff_pgm.sh, ppm2tiff_ppm.sh}: Additional + utilities tests. + +2009-08-28 Bob Friesenhahn + + * tools/tiffinfo.c: tiffinfo should return error status to the + caller. Register a private error callback to accomplish that. + + * test/Makefile.am (TIFFIMAGES): Add test images in BMP, GIF, and + PNM formats so that we will be able to test more of the tools. + While adding these test images I notice that bmp2tiff and gif2tiff + only support ancient versions of their respective formats. + +2009-08-27 Bob Friesenhahn + + * libtiff 4.0.0alpha4 released. + + * HOWTO-RELEASE: Improved release instructions. + +2009-08-24 Bob Friesenhahn + + * man/{TIFFClose.3tiff,raw2tiff.1,tiffcmp.1,tiffsplit.1}: Applied + fixes for "Bug 2023 - nroff errors in manual pages". + http://bugzilla.maptools.org/show_bug.cgi?id=2023 + + * tools/{rgb2ycbcr.c, tiff2rgba.c}: Applied fixes for "Bug 2079 - + CVE-2009-2347 libtiff: integer overflows in various inter-color + space conversion tools". + http://bugzilla.maptools.org/show_bug.cgi?id=2079 + + * libtiff/tif_print.c (TIFFPrintDirectory): Apply fix from Jay + Berkenbilt for "Bug 2024 - possible null pointer dereference with + one-line fix". + http://bugzilla.maptools.org/show_bug.cgi?id=2024 + + * libtiff/tif_dirread.c (TIFFReadCustomDirectory): Apply patch + from Jay Berkenbilt for "Bug 1895 - logic error in tif_dirread.c: + segfault after setting tdir_tag = IGNORE". + http://bugzilla.maptools.org/show_bug.cgi?id=1895 + +2009-08-23 Bob Friesenhahn + + * test/Makefile.am, test/tiffcrop*.sh: Split previously existing + tiffcrop.sh into a collection of many specific tests. Re-wrote + all of the existing tests to be based on some simple shell + functions. Make distcheck works again. + + Export certain variables (MAKE, MAKEFLAGS, MEMCHECK) to tests and + added 'memcheck' and 'ptrcheck' targets to make it easy to run the + tests under valgrind. + +2009-08-21 Bob Friesenhahn + + * test/tiffcp-logluv.sh: Fix test so that it works with a VPATH + build. + + * test/Makefile.am (AUTOMAKE_OPTIONS): Colorized tests was not + actually activated since it needed to be enabled in this + Makefile.am. Also activated parallel-tests mode since it offers + useful features such as per-test .log files and a summary test + report .log file. + +2009-08-20 Bob Friesenhahn + + * configure.ac: Updated autotools. Autoconf 2.64, Automake 1.11, + libtool 2.2.6. Enabled support for silent build rules + (--enable-silent-rules or 'make V=0') and colorized tests. + + * html/{index.html, v3.9.0.html}: Update for 3.9.0 release. + +2009-06-30 Frank Warmerdam + + * tests/tiffcp-logluv.sh: minimal testing of sgilog compression. + + * tools/tiffcp.c: add -c sgilog support. + + * libtiff/tif_luv.c: correct return codes from encoderow to be + 1 on success instead of zero. + http://bugzilla.maptools.org/show_bug.cgi?id=2069 + + * libtiff/tif_lzw.c: back out patch from #2065 and apply patch from + #1085 for a better underflow fix that errors properly. + http://bugzilla.maptools.org/show_bug.cgi?id=2065 + http://bugzilla.maptools.org/show_bug.cgi?id=1985 + +2009-06-26 Frank Warmerdam + + * libtiff/tif_strip.c: Remove an inappropriate assertion that often + fails on oddly sized 12bit jpeg compressed ycbcr images. + +2009-06-22 Frank Warmerdam + + * libtiff/tif_lzw.c: Fix buffer underflow bug. + http://bugzilla.maptools.org/show_bug.cgi?id=2065 + +2009-06-21 Frank Warmerdam + + * configure.ac, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c: add support + for dual mode 8/12 bit jpeg support. + +2009-06-03 Frank Warmerdam + + * libtiff/tif_write.c: do not override the planar configuration to be + contig for one sample files if planar configuration is already set. + http://bugzilla.maptools.org/show_bug.cgi?id=2057 + +2009-06-02 Frank Warmerdam + + * libtiff/libtiff.def: Add TIFFUnsetField. + +2009-05-03 Frank Warmerdam + + * libtiff/{tif_jpeg.c,tif_ojpeg.c,tif_getimage.c}: Fixed various + error reports to use "%s" as format string. + http://trac.osgeo.org/gdal/ticket/2976 + +2009-03-12 Frank Warmerdam + + * libtiff/{tif_fax3.c,tif_jpeg.c,tif_ojpeg.c}: Fix printdir chaining + for some codecs (#2020). + +2009-02-12 Frank Warmerdam + + * libtiff/tif_luv.c: Fix handling of tiled logluv images. + http://bugzilla.maptools.org/show_bug.cgi?id=2005 + +2009-02-09 Frank Warmerdam + + * libtiff/tif_dirread.c: Improve allocation safety when allocated + buffer for large tags. (#1998) Related to (#1993) + +2009-02-06 Frank Warmerdam + + * tools/tiffcrop.c: Don't default image->res_unit to INCH. Now the + test suite should pass. + +2009-02-05 Frank Warmerdam + + * libtiff/tif_dirread.c: Re-incorporated a sanity check on tag size, + but at the 2GB boundary to avoid overflow on 32bit systems. + http://bugzilla.maptools.org/show_bug.cgi?id=1993 + + * libtiff/tif_dirread.c: Remove some assertions that blow due to + corrupt files rather than in response to library internal + inconsistencies. + http://bugzilla.maptools.org/show_bug.cgi?id=1995 + http://bugzilla.maptools.org/show_bug.cgi?id=1991 + + * libtiff/tif_dirread.c: Fixed testing for failed result from + TIFFReadDirectoryFindFieldInfo(). + http://bugzilla.maptools.org/show_bug.cgi?id=1992 + +2009-01-23 Frank Warmerdam + + * libtiff/tif_predict.c: Add support for 32bit integer horz. predictors. + http://bugzilla.maptools.org/show_bug.cgi?id=1911 + + * libtiff/tif_dirwrite.c: Fix byte swapping of next directory offset. + + http://bugzilla.maptools.org/show_bug.cgi?id=1924 + + * tools/tiffcrop.c: initialize xres/yres values. + + * test/*.sh - default ${srcdir} to local directory. + + * test/common.sh - start verbose mode after common settings. + + * libtiff/tif_dirinfo.c: Replace lfind() with local equivelent to + avoid type mismatches on different platforms. + http://bugzilla.maptools.org/show_bug.cgi?id=1889 + +2009-01-22 Frank Warmerdam + + * tools/{fax2tiff.c,thumbnail.c,tiff2pdf.c,tiff2ps.c,tiffdump.c, + tiffsplit.c}: avoid warnings, mostly 32bit/64bit casting issues. + + * port,tools: Introduce libport.h, and include in tools if NEED_LIBPORT + defined, primarily to reduce prototype warnings on windows. + + * libtiff/tif_dirinfo.c,tif_dirread.c: Avoid warnings + about unused parameters, and uninitialized variables. + +2009-01-21 Bob Friesenhahn + + * test/common.sh: Execute tests like 'make VERBOSE=TRUE check' in + order to trace full execution detail while executing the test suite. + +2009-01-20 Frank Warmerdam + + * tools/tiffsplit.c: fix sampleformat to be shortv instead of longv. + +2009-01-20 Bob Friesenhahn + + * test/Makefile.am (CLEANFILES): Make sure that test output files + are removed by 'make clean' + + * Update autotools for 4.0.0 beta3 + + * 4.0.0 beta3 produced. + +2009-01-12 Bob Friesenhahn + + * test/tiffcrop.sh: New test script for tiffcrop from Richard + Nolde. + + * tools/tiff2ps.c: Remove spurious message to stderr. + +2009-01-11 Bob Friesenhahn + + * tools/tiff2ps.c: Incorporated significant functionality update + from Richard Nolde. In particular, support for rotating the image + by 90, 180, 270, and 'auto' has been added. + + * man/tiffcrop.1: Incorporated documentation updates from Richard + Nolde. + + * tools/tiffcrop.c: Incorporated significant functionality update + from Richard Nolde. + +2008-12-31 Bob Friesenhahn + + * libtiff/tiffio.h: GCC will now validate format specifications + for TIFFError(), TIFFErrorExt(), TIFFWarning(), and + TIFFWarningExt() in order to reveal bugs. + + * Many fixes throughout to work better as a 64-bit build. + +2008-12-30 Bob Friesenhahn + + * tools/{tiff2pdf.c, tiff2ps.c, tiffinfo.c}: Offset and length + tags now require 64-bit parameter rather than 32-bit. + + * libtiff/tif_dirread.c: Fixed issues with unaligned access to + 64-bit values. + + * tools/thumbnail.c: Eliminate crash noticed while running test + suite. + +2008-12-29 Bob Friesenhahn + + * libtiff/tif_ojpeg.c (OJPEGLibjpegJpegSourceMgrFillInputBuffer): + Initialize stack variables to avoid compiler warning. + + * tools/tiffinfoce.c (main): Use toff_t for offset type when + retrieving offset of EXIF IFD. + + * libtiff/tiffio.h: Undeprecate toff_t and restore its use in the + TIFFClientOpen() callback and other external function definitions. + + * tools/tiffinfo.c (main): Offset to EXIF IFD requires a 64-bit + type now. Fixes crash when dumping files containing an EXIF IFD. + + * m4/libtool.m4: Update to libtool 2.2.6. + +2008-12-21 Frank Warmerdam + + * libtiff/tif_dir.c, tiffio.h: Introduce TIFFUnsetField() function. + + * libtiff/tif_jpeg.c: Avoid errors if the application writes a full + strip for the last partial strip in a jpeg compressed file. + http://bugzilla.maptools.org/show_bug.cgi?id=1981 + +2008-10-29 Frank Warmerdam + + * libtiff/tif_flush.c: Make sure that BEENWRITING is cleared when + we take the shortcut to only update the strip/tile offsets in place. + http://trac.osgeo.org/gdal/ticket/2621 + +2008-10-21 Andrey Kiselev + + * libtiff/tif_jbig.c: Support the JBIG-KIT 2.0 (compatibility with + the older versions retained). + +2008-10-09 Frank Warmerdam + + * libtiff/tif_jpeg.c: Add #ifdefs for changes needed if using + IPP enabled version of libjpeg from Intel. + http://bugzilla.maptools.org/show_bug.cgi?id=1951 + +2008-09-05 Andrey Kiselev + + * tools/tiffsplit.c: Use byte counts of proper size (uint64). + Required for libtiff 4.0. + + * tools/tiffsplit.c: Use dynamically allocated array instead of static + when constructing output file names. + +2008-09-03 Andrey Kiselev + + * tools/tiffsplit.c: Get rid of unsafe strcpy()/strcat() calls when + doing the filename/path construction. + + * tools/tiff2pdf.c: More appropriate format string in + t2p_write_pdf_string(); avoid signed/unsigned mismatch. + + * libtiff/tif_lzw.c: Properly zero out the codetable. As per bug + + http://bugzilla.maptools.org/show_bug.cgi?id=1929 + + * libtiff/tif_lzw.c: Properly zero out the string table. Fixes + CVE-2008-2327 security issue. + +2008-09-01 Frank Warmerdam + + * libtiff/tif_dirread.c: Avoid unused TIFFReadDirEntryFloat() function. + + * libtiff/tif_dirwrite.c: modified to write IFDs as either IFD8 or IFD + depending on whether the file is bigtiff or classic tiff. + http://bugzilla.maptools.org/show_bug.cgi?id=1917 + +2008-08-12 Edward Lam + + * tools/tiffdump.c: When compiling for Microsoft Windows, apply + consistent (__int64) casting when testing if _lseeki64 has + successfully seeked as requested. This is necessary for large + file support to work since off_t is only 32-bit. + +2008-07-29 Frank Warmerdam + + * tif_strip.c: Replace assertions related to samplesperpixel != 3 or + the subsampling values not being 1, 2 or 4 (for jpeg compressed images) + with control logic to return runtime errors (c/o Even Rouault) (#1927). + +2008-06-17 Frank Warmerdam + + * tools/tiffcrop.c: Fix some portability problems. + + * libtiff/tif_ojpeg.c: Use same jpeg/win32 boolean/FAR hacks as are + used in tif_jpeg.c. + + * libtiff/tif_win32.c: Ensure TIFFOpenW() uses same FILE_SHARE flags + as TIFFOpen(). + +2008-06-01 Frank Warmerdam + + * libtiff/tif_dirwrite.c: Fix alignment problems affecting architectures + like Sparc/Solaris. + http://bugzilla.maptools.org/show_bug.cgi?id=1892 + +2008-05-27 Frank Warmerdam + + * libtiff.def: Add TIFFFindField + http://bugzilla.maptools.org/show_bug.cgi?id=1891 + +2008-05-26 Frank Warmerdam + + * tif_config.*.h, tiffconf.*.h: Remove SIZEOF_LONG definition, unused. + + * li2008-04-15 Andrey Kiselev + +btiff/tif_win32.c: Replace custom Win32 memory api with generic + POSIX one. No apparent value to use of GlobalAlloc() in the modern + age. http://bugzilla.maptools.org/show_bug.cgi?id=1885 + + * libtiff/tiffconf.vc.h: Added JBIG_SUPPORT and MDI_SUPPORT items + in windows version (care of Edward Lam). + +2008-05-24 Frank Warmerdam + + * tif_codec.c: Avoid NULL pointer dereferencing for exotic + compression codec codes. + + * tif_dirwrite.c: fix potential memory leak. + + * tif_dirread.c: Fix unchecked malloc result. + +2008-05-24 Bob Friesenhahn + + * test {tiff2pdf.sh tiff2ps-EPS1.sh tiff2ps-PS1.sh tiff2ps-PS2.sh + tiff2ps-PS3.sh tiffcp-g3-1d-fill.sh tiffcp-g3-1d.sh + tiffcp-g3-2d-fill.sh tiffcp-g3-2d.sh tiffcp-g3.sh tiffcp-g4.sh + tiffcp-split-join.sh tiffcp-split.sh tiffcp-thumbnail.sh + tiffdump.sh tiffinfo.sh}: Added more test scripts based on + suggestions from Lee Howard posted to the tiff list on 13 Sep + 2007. + +2008-05-23 Frank Warmerdam + + * libtiff/tif_fax3.c: Add an assert in an effort to detect a + possible runtime problem reported by coverity. + + * contrib/iptcutil/iptcutil.c: Fixed memory leak of str. + + * tools/tiffcrop.c, man/tiffcrop.1: Major update from Richard Nolde. + http://bugzilla.maptools.org/show_bug.cgi?id=1888 + + * tools/tiffdither.c: remove dead onestrip code. avoid memory leak. + + * tools/rgb2ycbcr.c: fix memory leak of raster buffer. + + * tools/tiffcp.c: Simplify inknames code to avoid pointless test. + Cleanup scanline allocation to avoid coverity warning. + + * tools/thumbnail.c: Check for TIFFOpen() failure. + +2008-05-18 Frank Warmerdam + + * libtiff/tif_dirinfo.c: Use TIFF_SETGET_ASCII for PIXAR_TEXTUREFORMAT + and PIXAR_WRAPMODES instead of TIFF_SETGET_UNDEFINED. Not exactly clear + why this is needed. + +2008-05-09 Bob Friesenhahn + + * Makefile.am (ACLOCAL_AMFLAGS): Libtool 2.2.4 does not like + "ACLOCAL_AMFLAGS=-I ./m4". It wants "ACLOCAL_AMFLAGS=-I m4". + +2008-04-15 Andrey Kiselev + + * test/: Test suite updated. Everything is passed now. + + * libtiff/tif_dirinfo.c: Fixed description of the + TIFFTAG_NUMBEROFINKS tag. + +2008-04-14 Andrey Kiselev + + * libtiff/{tif_dirread.c, tif_dirwrite.c, tiffiop.h}: + Get rid of some of "dereferencing type-punned" warnings by converting + tdir_offset field of TIFFDirEntry structure into union. + +2008-04-10 Andrey Kiselev + + * libtiff/{tif_flush.c, tif_dirwrite.c, tiffio.h, tiffiop.h}: + TIFFRewriteField() renamed into _TIFFRewriteField() and moved out + from the public interface. Type of its 'count' parameter changed + from uint32 to tmsize_t. + + * /libtiff/tiffiop.h: Make tif_nfields and tif_nfieldscompat fields + of the tiff structure have the size_t type instead of uint32. + +2008-04-09 Andrey Kiselev + + * tools/tiffdump.c: Added support for MSVS 6.0. + + * libtiff/tif_dirread.c: Use custom functions _TIFFUInt64ToFloat() + and _TIFFUInt64ToDouble() to convert 64-bit integers into floating + point values on MSVS 6.0 platform. + +2008-03-14 Frank Warmerdam + + * tif_dirread.c: Removed sanity checks on tags larger than 4MB in + TIFFReadDirEntryArray() since they are interfering with seemingly + legitimate files. http://trac.osgeo.org/gdal/ticket/2005 + +2008-02-09 Joris Van Damme + + * tif_dirread.c: Added handling for the case of number of values for + PageNumber tag different from 2 (previously resulted in an assert + indicating lack of handling and was forgotten about) + +2008-02-01 Frank Warmerdam + + * libtiff/tif_jpeg.c: Do not try to fixup subsampling tags based on + the actual jpeg data stream if the first strip/tile has zero size. + This is the case when GDAL creates a new file with zero sizes, closes + and reopens it. + +2008-01-07 Frank Warmerdam + + * tools/tiff2ps.c: fix up 64bit issues (from Edward Lam). + +2008-01-01 Frank Warmerdam + + * libtiff/tif_dirwrite.c: #ifdef out lots of unused functions. + + * Makefile.vc, libtiff/Makefile.vc, tools/Makefile.vc: Improve clean + targets. + + * tools/tiffinfo.c, tools/tiffcmp.c, tools/gif2tiff.c, tools/bmp2tiff.c + tools/tiff2pdf.c: Fix 64-bit warnings when compiling under MSVC 2005 + (x64). + + * tools/tiffset.c: Changes to reflect the fact that TIFFFieldWithTag() + and TIFFFieldWithName() now return TIFFField pointers instead of + TIFFFieldInfo pointers. + + * tools/tiffdump.c: Added ssize_t typedef on Windows since it doesn't + exist. This makes it compile again on Windows + + * tif_aux.c, tif_getimage.c, tif_next.c, tif_predict.c, tif_win32.c, + tiffconf.vc.h: Various 64bit fixes from Edward Lam identified on win64. + + * test/rewrite_tag.c: New test for TIFFRewriteField(). + +2007-12-31 Frank Warmerdam + + * tif_dirwrite.c: Added TIFFRewriteField(). This new function + rewrites one field "on disk" updating an existing directory + entry. Lots of limitations still... + + * tiffiop.h, tif_write.c, tif_dirread.c, tif_flush.c: Keep track of + TIFF_DIRTYSTRIP separately from TIFF_DIRTYDIRECT to indicate that + the strip offset/size values are dirty but nothing else about the + directory is dirty. In flush handle "just stripmaps dirty" as a + special case that just rewrites these values without otherwise + modifying the directory on disk using TIFFRewriteField(). + + We also modify logic so that in update mode the directory is not + marked dirty on read, but only when something is changed. This + means we need to keep track of updates to the stripmap stuff in + TIFFAppendToStrip(). + +2007-12-10 Frank Warmerdam + + * tif_jpeg.c: Improve ability to switch between encoding and decoding + in the jpeg code (gdal bug #2033). + +2007-11-23 Frank Warmerdam + + * tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_read.c, tif_write.c, + tiffiop.h: Added TIFF_BUF4WRITE flag to indicate if contents of the + rawcp/rawcc buffer are for writing and thus may require flushing. + Necessary to distinguish whether they need to be written to disk when + in mixed read/write mode and doing a mixture of writing followed by + reading. http://trac.osgeo.org/gdal/ticket/1758 + +2007-11-23 Andrey Kiselev + + * configure.com, libtiff/tif_vms.c: Better OpenVMS support. Patches + from Alexey Chupahin. + +2007-11-02 Frank Warmerdam + + * tif_write.c: Rip out the fancy logic in TIFFAppendToStrip() for + establishing if an existing tile can be rewritten to the same location + by comparing the current size to all the other blocks in the same + directory. This is dangerous in many situations and can easily + corrupt a file. (observed in esoteric GDAL situation that's hard to + document). This change involves leaving the stripbytecount[] values + unaltered till TIFFAppendToStrip(). Now we only write a block back + to the same location it used to be at if the new data is the same + size or smaller - otherwise we move it to the end of file. + + * tif_dirwrite.c: Try to avoid writing out a full readbuffer of tile + data when writing the directory just because we have BEENWRITING at + some point in the past. This was causing odd junk to be written out + in a tile of data when a single tile had an interleaving of reading + and writing with reading last. (highlighted by gdal + autotest/gcore/tif_write.py test 7. + + * tif_predict.c: use working buffer in PredictorEncodeTile to avoid + modifying callers buffer. + http://trac.osgeo.org/gdal/ticket/1965 + + * tif_predict.c/h: more fixes related to last item, keeping a + distinct pfunc for encode and decode cases as these were getting + mixed up sometimes. + http://trac.osgeo.org/gdal/ticket/1948 + +2007-11-01 Frank Warmerdam + + * tif_predict.c/h, tif_lzw.c, tif_zip.c: Improvements so that + predictor based encoding and decoding works in read-write update + mode properly. + http://trac.osgeo.org/gdal/ticket/1948 + +2007-10-24 Joris Van Damme + + * tif_dirread.c: Fixed problem with bogus file triggering + assert(td->td_planarconfig == PLANARCONFIG_CONTIG) in + ChopUpSingleUncompressedStrip + +2007-10-22 Joris Van Damme + + * tif_jpeg.c: Resolved buffer incrementation bug that lead to faulty images + at best, access violation at worst, when subsampled JPEG compressed imagery + is decoded without the JPEG_COLORMODE feature + +2007-10-11 Frank Warmerdam + + * html/index.html: Update "people responsible" section. + +2007-10-05 Frank Warmerdam + + * tools/tiff2pdf.c: Fix problem with alpha setting in some cases + as reported on the mailing list. + +2007-10-01 Joris Van Damme + + * changed some more incorrect %lud printf flags to %lu + +2007-09-29 Joris Van Damme + + * tif_dirread.c: Strip chopping interfered badly with uncompressed + subsampled images because it tried to divide subsampled rowblocks, + leading to all sorts of errors throughout the library for these + images. Fixed by making strip chopping divide in row counts that + are a multiple of vertical subsampling value. + +2007-09-28 Joris Van Damme + + * tif_dirread.c: Logical cast working around compiler warning + + * tif_read.c: Correction of some error flags and parameter lists + +2007-09-27 Joris Van Damme + + * tif_dirread.c: Made calculation of td_maxsamplevalue more robust + when dealing with large bitspersample values, shutting up purification + tools that warn about truncation, though it remains incorrect and + indicates a conceptual problem there. + + * tif_open.c: Moved early exit in case of 'h' flag (to disable reading + of first IFD) to proper place because it badly interfered with memory + mapping, resulting in mapping flag even with dummy mapping functions + that returned 0 whilst at the same time the mapping tif_size wasn't + set, thus resulting in continuous incorrect beyond-eof errors. + +2007-09-24 Joris Van Damme + + * tif_dirinfo.c: Fixed (MSVC) compiler reports about + inconsistent use of const in tiffFields and exifFields definition + +2007-09-20 Frank Warmerdam + + * tif_dirwrite.c: Always write tile/strip offsets and sizes + using LONG8 type when output format is BigTIFF. The + TIFFWriteDirectoryTagLongLong8Array() function was restructured + accordingly. + + * tif_dirread.c: Improvements to error reporting text in + TIFFFetchDirectory(). + +2007-09-19 Bob Friesenhahn + + * test/images: Added a small collection of test images for use by + test programs and scripts. + * test/tiffinfo.sh: A trivial example test script. + * test/common.sh: Added small script for setting the environment + used by script-based tests. + +2007-08-24 Frank Warmerdam + + * tif_dirwrite.c: Write the tif_nextdiroff value instead of a fixed + zero when writing directory contents to preserve the ability to + rewrite directories in place, even in the middle of a directory + chain. + + * tif_dirinfo.c: _TIFFMergeFields() now only merges in field + definitions that are missing. Existing definitions are silently + ignored. + + * tif_dirread.c: Add runtime error for fields for which no definition + is found (in addition to an assert for developers) in + TIFFFetchNormalTag(). Not sure if this is needed, but it seems + prudent. + +2007-08-10 Joris Van Damme + + * libtiff/tif_getimage.c: removed SubsamplingHor and SubsamplingVer + from _TIFFRGBAImage structure to revert unwanted ABI change. + +2007-08-10 Joris Van Damme + + * libtiff/tif_win32.c: use SetFilePointer instead of + SetFilePointerEx, as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1580 + +2007-07-19 Andrey Kiselev + + * libtiff/tif_stream.cxx: Put all callback functions declarations + inside extern "C" block. + + * libtiff/{tif_lzw.c, tif_luv.c, tif_dumpmode.c, tif_print.c, + tif_read.c, tif_strip.c, tif_thunder.c}: Use "%I64d" printf() + formatter instead of "%lld" with MSVC compiler. + + * libtiff/{tiffiop.h, tif_aux.c}: Added _TIFFUInt64ToFloat() and + _TIFFUInt64ToDouble() functions. + +2007-07-18 Andrey Kiselev + + * libtiff/tif_dirread.c: Handle the case of MSVC 6 when using 64-bit + integer constants. + + * libtiff/{Makefile.am, Makefile.v}: Do not distribute tiffconf.h, + remove tif_config.h/tiffconf.h during cleaning. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1573 + + * libtiff/tif_unix.c: Do not use O_LARGEFILE. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1577 + +2007-07-13 Andrey Kiselev + + * libtiff 4.0.0alpha released. + +2007-07-12 Andrey Kiselev + + * tools/tiff2pdf.c: Added missed extern optind as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1567 + + * libtiff/{tif_close.c, tif_dirinfo.c, tiffiop.c, tif_dirread.c, + tif_dir.h, tif_dir.c, tiffio.h}: Transition to the new-style tag + extending scheme completed. + +2007-07-11 Bob Friesenhahn + + * libtiff/tif_stream.cxx: Adapt to use toff_t again. Update to + use standard C++ library size types and attempt to detect overflow + cases. + +2007-07-08 Andrey Kiselev + + * libtiff/{tif_jpeg.c, tif_dir.h, tif_dir.c, tif_dirinfo.c, tiffio.h, + tif_ojpeg.c, tif_print.c, tif_fax3.c, tif_dirread.c}: More work on new + tag extending scheme. Use the new scheme everywhere. + + * libtiff/{tif_zip.c, tif_predict.c, tif_pixarlog.c, tif_luv.c, + tif_fax3.c, tif_dirread.c, tif_dirwrite.c, tif_close.c, tif_ojpeg.c, + tif_jpeg.c, tif_dirinfo.c, tif_dir.h, tiffio.h, tiffiop.h}: + TIFFFIeldInfo structure replaced with TIFFField structure. + TIFFFieldInfo retained for the backward compatibility. + +2007-07-05 Bob Friesenhahn + + * tools/tiff2pdf.c: Fix a compile problem when JPEG_SUPPORT is not + defined. + +2007-07-04 Andrey Kiselev + + * libtiff/{tif_dir.c, tiff.h, tiffio.h, libtiff.def}: Unused + TIFFReassignTagToIgnore() function and TIFFIgnoreSense enumeration + removed. + + * libtiff/{tif_dirinfo.c, tif_fax3.c, tif_jbig.c, tif_jpeg.c}: Move + tags TIFFTAG_FAXRECVPARAMS, TIFFTAG_FAXSUBADDRESS, + TIFFTAG_FAXRECVTIME and TIFFTAG_FAXDCS to the common tag directory. + These tags are not codec-specific and relate to image content, so + process them as other normal tags. + + * libtiff/{tiffio.h, tif_dir.h}: TIFFTagValue structure moved from the + public tiffio.h to private tif_dir.h. + + * contrib/{acorn, mac-cw, mac-mpw}: Removed as unmaintained and + outdated. + +2007-07-03 Andrey Kiselev + + * libtiff{tif_acorn.c, tif_apple.c, tif_atari.c, tif_msdos.c, + tif_win3.c}: Obsoleted portability stuff removed. + + * tools/tiff2ps.c: Added support 16-bit images as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1566 + + Patch from William Bader. + + * tools/tiff2pdf.c: Fix for TIFFTAG_JPEGTABLES tag fetching and + significant upgrade of the whole utility as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1560 + + Now we don't need tiffiop.h in tiff2pdf anymore and will open output + PDF file using TIFFClientOpen() machinery as it is implemented + by Leon Bottou. + +2007-06-26 Bob Friesenhahn + + * configure.ac: Fix typo when substituting value for unsigned 8 bit type. + Added support for a TIFF_PTRDIFF_T type to use when doing pointer arithmetic. + Added support for a TIFF_SSIZE_T in order to return memory sizes but still + allow returning -1 for errors. + * libtiff/tiffconf.vc.h: Add porting type defintions for WIN32. + +2007-06-25 Bob Friesenhahn + + * port/strtoull.c: New porting function in case strtoull() is not + available on the target system. + * configure.ac: Add configure support for determining sized types + in a portable way and performing necessary substitutions in + tif_config.h and tiffconf.h. Updated tiff.h to use the new + definitions. + +2007-04-27 Andrey Kiselev + + * tools/tiff2pdf.c: Check the tmpfile() return status as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=154 + +2007-04-07 Andrey Kiselev + + * libtiff/{tif_dir.h, tif_dirread.c, tif_dirinfo.c, tif_jpeg.c, + tif_fax3.c, tif_jbig.c, tif_luv.c, tif_ojpeg.c, tif_pixarlog.c, + tif_predict.c, tif_zip.c}: Finally fix bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1274 + + by introducing _TIFFMergeFieldInfo() returning integer error status + instead of void in case of problems with field merging (e.g., if the + field with such a tag already registered). TIFFMergeFieldInfo() in + public API remains void. Use _TIFFMergeFieldInfo() everywhere and + check returned value. + +2007-04-07 Frank Warmerdam + + * contrib/addtiffo/tif_overview.c: Fix problems with odd sized output + blocks in TIFF_DownSample_Subsampled() (bug 1542). + +2007-04-06 Frank Warmerdam + + * libtiff/tif_jpeg.c: Changed JPEGInitializeLibJPEG() so that it + will convert from decompressor to compressor or compress to decompress + if required by the force arguments. This works around a problem in + where the JPEGFixupTestSubsampling() may cause a decompressor to + be setup on a directory when later a compressor is required with the + force flag set. Occurs with the addtiffo program for instance. + +2007-04-06 Andrey Kiselev + + * tools/tiffcrop.c, man/tiffcrop.1: Significant update in + functionality from Richard Nolde. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1525 + +2007-03-28 Frank Warmerdam + + * libtiff/tif_fax3.c: "inline static" -> "static inline" for IRIC CC. + +2007-03-17 Joris Van Damme + + * start of BigTIFF upgrade - CVS HEAD unstable until further notice + +2007-03-07 Joris Van Damme + + * libtiff/tif_getimage.c: workaround for 'Fractional scanline' error reading + OJPEG images with rowsperstrip that is not a multiple of vertical subsampling + factor. This bug is mentioned in: + http://bugzilla.remotesensing.org/show_bug.cgi?id=1390 + http://www.asmail.be/msg0054766825.html + +2007-03-07 Joris Van Damme + + * libtiff/tif_win32.c: made inclusion of windows.h unconditional + + * libtiff/tif_win32.c: replaced preprocessor indication for consiously + unused arguments by standard C indication for the same + +2007-02-27 Andrey Kiselev + + * libtiff/tif_dirread.c: Use uint32 type instead of tsize_t in byte + counters in TIFFFetchData(). Should finally fix the issue + + http://bugzilla.remotesensing.org/show_bug.cgi?id=890 + +2007-02-24 Andrey Kiselev + + * tools/tiffset.c: Properly handle tags with TIFF_VARIABLE writecount. + As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1350 + + * libtiff/tif_dirread.c: Added special function to handle + SubjectDistance EXIF tag as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1362 + + * tools/tiff2pdf.c: Do not assume inches when the resolution units + do not specified. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1366 + + * tools/{tiffcp.c, tiffcrop.c}: Do not change RowsPerStrip value if + it was set as infinite. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1368 + + * tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop utility contributed + by Richard Nolde. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1383 + +2007-02-22 Andrey Kiselev + + * libtiff/tif_dir.c: Workaround for incorrect TIFFs with + ExtraSamples == 999 produced by Corel Draw. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1490 + + * libtiff/{tif_dirread.c, tif_read.c}: Type of the byte counters + changed from tsize_t to uint32 to be able to work with data arrays + larger than 2GB. Fixes bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=890 + + Idea submitted by Matt Hancher. + +2007-01-31 Andrey Kiselev + + * tools/tif2rgba.c: This utility does not work properly on big-endian + architectures. It was fixed including the bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1149 + +2007-01-15 Mateusz Loskot + + * Submitted libtiff port for Windows CE platform + * libtiff/tif_config.wince.h: Added configuration header for WinCE. + * libtiff/tiffconf.wince.h: Ported old configuration header for WinCE. + * libtiff/tif_wince.c: Added WinCE-specific implementation of some + functons from tif_win32.c. + * libtiff/tif_win32.c: Disabled some functions already reimplemented in tif_wince.c. + * libtiff/tiffiop.h, port/lfind.c: Added conditional include of some + standard header files for Windows CE build. + * tools/tiffinfoce.c: Ported tiffinfo utility for Windows CE. + +2006-11-19 Frank Warmerdam + + * libtiff/tif_write.c: TIFFAppendToStrip() - clear sorted flag if + we move a strip. + http://bugzilla.remotesensing.org/show_bug.cgi?id=1359 + +2006-10-13 Andrey Kiselev + + * libtiff/tif_dir.c: More fixes for vulnerabilities, reported + in Gentoo bug (): + + http://bugs.gentoo.org/show_bug.cgi?id=142383 + + * libtiff/contrib/dbs/xtiff/xtiff.c: Make xtiff utility compilable. + Though it is still far from the state of being working and useful. + +2006-10-12 Andrey Kiselev + + * libtiff/tif_fax3.c: Save the state of printdir codec dependent + method. + + * libtiff/tif_jpeg.c: Save the state of printdir codec dependent method + as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1273 + + * libtiff/tif_win32.c: Fixed problem with offset value manipulation + as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1322 + + * libtiff/{tif_read.c, tif_jpeg.c, tif_dir.c}: More fixes for + vulnerabilities, reported in Gentoo bug (): + + http://bugs.gentoo.org/show_bug.cgi?id=142383 + +2006-09-28 Andrey Kiselev + + * libtiff/{tif_fax3.c, tif_next.c, tif_pixarlog.c}: Fixed multiple + vulnerabilities, as per Gentoo bug (): + + http://bugs.gentoo.org/show_bug.cgi?id=142383 + +2006-09-27 Frank Warmerdam + + * libtiff/tif_lzw.c, libtiff/tif_zip.c: Fixed problems with mixing + encoding and decoding on the same read-write TIFF handle. The LZW + code can now maintain encode and decode state at the same time. The + ZIP code will switch back and forth as needed. + http://bugzilla.remotesensing.org/show_bug.cgi?id=757 + +2006-09-20 Frank Warmerdam + + * libtiff: Rename config.h.vc and tif_config.h.vc to config.vc.h and + tif_config.vc.h for easier identification by folks using an IDE. + +2006-07-25 Frank Warmerdam + + * tif_msdos.c: Avoid handle leak for failed opens. c/o Thierry Pierron + +2006-07-19 Frank Warmerdam + + * tif_dirwrite.c: take care not to flush out buffer of strip/tile + data in _TIFFWriteDirectory if TIFF_BEENWRITING not set. Relates + to bug report by Peng Gao with black strip at bottom of images. + +2006-07-12 Frank Warmerdam + + * tif_dirwrite.c: make sure to use uint32 for wordcount in + TIFFWriteNormanTag if writecount is VARIABLE2 for ASCII fields. + It already seems to have been done for other field types. Needed + for "tiffset" on files with geotiff ascii text. + +2006-07-04 Bob Friesenhahn + + * {configure.ac, libtiff/tif_config.h.vc, libtiff/tif_jbig.c} + (JBIGDecode): jbg_newlen is not available in older JBIG-KIT and + its use does not appear to be required, so use it only when it is + available. + +2006-06-24 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Added missed EXIF tag ColorSpace (40961). + + * libtiff/tif_dirread.c: Move IFD fetching code in the separate + function TIFFFetchDirectory() avoiding code duplication in + TIFFReadDirectory() and TIFFReadCustomDirectory(). + +2006-06-19 Frank Warmerdam + + * tools/tiff2pdf.c: Fix handling of -q values. + http://bugzilla.remotesensing.org/show_bug.cgi?id=587 + +2006-06-17 Frank Warmerdam + + * tif_readdir.c: Added case in EstimateStripByteCounts() for tiled + files. Modified TIFFReadDirectory() to not invoke + EstimateStripByteCounts() for case where entry 0 and 1 are unequal + but one of them is zero. + http://bugzilla.remotesensing.org/show_bug.cgi?id=1204 + +2006-06-08 Andrey Kiselev + + * libtiff/{tif_open.c, tif_dirread.c, tiffiop.h}: Move IFD looping + checking code in the separate function TIFFCheckDirOffset(). + + * libtiff/tif_aux.c: Added _TIFFCheckRealloc() function. + + * tools/tiffcmp.c: Fixed floating point comparison logic as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1191 + + * libtiff/tif_fax3.c: Fixed problems in fax decoder as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1194 + + * tools/tiff2pdf.c: Fixed buffer overflow condition in + t2p_write_pdf_string() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1196 + +2006-06-07 Andrey Kiselev + + * {configure, configure.ac, libtiff/tif_jbig.c, tools/tiffcp.c}: Added + support for JBIG compression scheme (34661 code) contributed by Lee + Howard. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=896 + + * configure, configure.ac: OJPEG support enabled by default. + + * contrib/ojpeg/: Removed. New OJPEG support does not need this patch. + +2006-06-03 Bob Friesenhahn + + * libtiff/{tif_dirinfo.c, tif_print.c} : Fix crash in + TIFFPrintDirectory(). Joris Van Damme authored the fix. + +2006-04-21 Andrey Kiselev + + * tools/tiff2pdf.c: Unified line ending characters (always use '\n') + as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1163 + + * README.vms, Makefile.am, configure.com, libtiff/{Makefile.am, + tif_config.h-vms, tif_stream.cxx, tif_vms.c, tiffconf.h-vms}: + Added support for OpenVMS by Alexey Chupahin, elvis_75@mail.ru. + +2006-04-20 Andrey Kiselev + + * tools/{fax2ps.c, fax2tiff.c, ppm2tiff.c, ras2tiff.c, tiff2pdf.c}: + Properly set the binary mode for stdin stream as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1141 + + * man/{bmp2tiff.1, fax2ps.1, fax2tiff.1, gif2tiff.1, ras2tiff.1, + raw2tiff.1, rgb2ycbcr.1, sgi2tiff.1, tiff2bw.1, tiff2pdf.1, tiff2ps.1, + tiff2rgba.1, tiffcmp.1, tiffcp.1, tiffdither.1, tiffdump.1, tiffgt.1, + tiffset.1}: Improvements in page formatting as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1140 + + * html/tools.html, html/man/Makefile.am, tools/tiff2pdf.c: Fixed + typos as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1139 + +2006-04-18 Frank Warmerdam + + * nmake.opt: use /EHsc for VS2005 compatibility. Also define + _CRT_SECURE_NO_DEPRECATE to avoid noise on VS2005. + +2006-04-12 Joris Van Damme + + * libtiff/tif_getimage.c: Added support for planarconfig separate + non-subsampled YCbCr (i.e. separate YCbCr with subsampling [1,1]) + +2006-04-11 Joris Van Damme + + * libtiff/tif_getimage.c: Revision of all RGB(A) put routines + - Conversion of unassociated alpha to associated alpha now done with + more performant LUT, and calculation more correct + - Conversion of 16bit data to 8bit data now done with + more performant LUT, and calculation more correct + - Bugfix of handling of 16bit RGB with unassociated alpha + +2006-04-11 Joris Van Damme + + * libtiff/tif_getimage.c: + - When there is no alpha, gtTileSeparate and gtStripSeparate allocated + buffer for alpha strile and filled it, only to never read it back. + Removed allocation and fill. + - Minor rename of vars in gtTileSeparate and gtStripSeparate + anticipating planned functionality extension + +2006-04-08 Joris Van Damme + + * libtiff/tif_getimage.c: renamed pickTileContigCase to PickContigCase + and pickTileSeparateCase to PickSeparateCase as both work on strips as + well + + * libtiff/tif_getimage.c: moved img->get selection from + TIFFRGBAImageBegin into PickContigCase and PickSeparateCase to create + logical hook for planned functionality extension + +2006-04-08 Joris Van Damme + + * libtiff/tif_ojpeg.c: resolved memory leak that was a consequence + of inappropriate use of jpeg_abort instead of jpeg_destroy + +2006-04-07 Joris Van Damme + + * libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in + gtStripContig with TIFFNewScanlineSize so as to fix buggy behaviour + on subsampled images - this ought to get sorted when we feel brave + enough to replace TIFFScanlineSize alltogether + + * libtiff/tif_ojpeg.c: fixed bug in OJPEGReadSkip + +2006-04-04 Joris Van Damme + + * libtiff/tiffio.h: added new type tstrile_t + + * libtiff/tif_dir.h: changed types of td_stripsperimage and td_nstrips + to new tstrile_t, types of td_stripoffset and td_stripbytecount to + toff_t* + + * libtiff/tif_ojpeg.c: totally new implementation + + * libtiff/tif_dirread.c: added several hacks to suit new support of + OJPEG + + * libtiff/tif_getimage.c: removed TIFFTAG_JPEGCOLORMODE handling + of OJPEG images in favor of tif_getimage.c native handling of + YCbCr and desubsampling + +2006-03-29 Frank Warmerdam + + * libtiff/tif_jpeg.c: JPEGVSetField() so that altering the photometric + interpretation causes the "upsampled" flag to be recomputed. Fixes + peculiar bug where photometric flag had to be set before jpegcolormode + flag. + +2006-03-25 Joris Van Damme + + * libtiff/tif_jpeg.c: strip size related bugfix in encode raw + + * libtiff/tif_strip.c: temporarilly added two new versions of + TIFFScanlineSize + - TIFFNewScanlineSize: proposed new version, after all related + issues and side-effects are sorted out + - TIFFOldScanlineSize: old version, from prior to 2006-03-21 change + This needs further sorting out. + +2006-03-25 Joris Van Damme + + * contrib/addtiffo/tif_ovrcache.c: bugfix to correctly pass size + of last truncated strip data to TIFFWriteEncodedStrip + +2006-03-25 Joris Van Damme + + * libtiff/{tif_jpeg.c, tif_strip.c}: bugfix of tif_jpeg decode raw + +2006-03-25 Joris Van Damme + + * libtiff/tif_getimage.c: bugfix/rewrite of putcontig8bitYCbCr22tile + + * libtiff/tif_getimage.c: added putcontig8bitYCbCr12tile + + * libtiff/tif_read.c: added support for new TIFF_NOREADRAW flag to + prepare the path for new tif_ojpeg.c + +2006-03-23 Andrey Kiselev + + * libtiff 3.8.2 released. + + * tools/Makefile.am: Use runtime paths linker flags when rpath + option enabled. + +2006-03-21 Andrey Kiselev + + * libtiff/libtiff.def: Added missed exports as per bug + http://bugzilla.remotesensing.org/attachment.cgi?id=337 + + * contrib/addtiffo/Makefile.vc, libtiff/Makefile.vc, port/Makefile.vc, + tools/Makefile.vc: Makefiles improvements as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1128 + + * nmake.opt libtiff/{tif_config.h.vc, tif_unix.c, tiffio.h}, + tools/{fax2ps.c, fax2tiff.c, tiff2pdf.c}: Fixed win32 I/O functions + usage as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1127 + + * libtiff/tif_strip.c: Take subsampling in account when calculating + TIFFScanlineSize(). + + * tools/tiffcp.c: Do not set RowsPerStrip bigger than image length. + +2006-03-17 Andrey Kiselev + + * tools/fax2tiff.c: Fixed wrong TIFFerror() invocations as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1125 + + * tools/fax2ps.c: Fixed reading the input stream from stdin as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1124 + +2006-03-16 Andrey Kiselev + + * libtiff/tiffiop.h: Added decalration for + _TIFFSetDefaultCompressionState(). + + * libtiff/{tif_jpeg.c, tif_fax3.c, tif_zip.c, tif_pixarlog.c, + tif_lzw.c, tif_luv.c}: Use _TIFFSetDefaultCompressionState() in all + codec cleanup methods. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1120 + +2006-03-15 Andrey Kiselev + + * libtiff/tif_jpeg.c: Do not cleanup codec state in TIFFInitJPEG(). As + per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1119 + + * tools/raw2tiff.c: Do not set RowsPerStrip larger than ImageLength. + As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1110 + + * libtiff/tiffiop.h: dblparam_t typedef removed; GLOBALDATA macro + removed; move here the STRIP_SIZE_DEFAULT macro definition. + + * libtiff/{tif_dirread.c, tif_strip.c}: Removed STRIP_SIZE_DEFAULT + macro definition. + + * libtiff/tif_dir.c: Use double type instead of dblparam_t. + +2006-03-14 Andrey Kiselev + + * libtiff/tif_dirread.c: Do not check the PlanarConfig tag presence + in TIFFReadDirectory, because it is always set at the start of + function and we allow TIFFs without that tag set. + +2005-03-13 Andrey Kiselev + + * libtiff 3.8.1 released. + +2006-03-07 Andrey Kiselev + + * libtiff/tif_dirread.c: Fixed error reporting in TIFFFetchAnyArray() + function as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1102 + + * libtiff/tif_dirread.c: More wise check for integer overflow + condition as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1102 + + * libtiff/{tif_jpeg.c, tif_pixarlog.c, tif_fax3.c, tif_zip.c}: + Properly restore setfield/getfield methods in cleanup functions. As + per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1102 + +2006-03-03 Andrey Kiselev + + * libtiff/{tif_predict.c, tif_predict.h}: Added new function + TIFFPredictorCleanup() to restore parent decode/encode/field methods. + + * libtiff/{tif_lzw.c, tif_pixarlog.c, tif_zip.c}: Use + TIFFPredictorCleanup() in codec cleanup methods. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1102 + + * libtiff/tif_dirread.c: Fixed integer overflow condition in + TIFFFetchData() function. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1102 + +2006-03-01 Andrey Kiselev + + * libtiff/tif_ojpeg.c: Set the ReferenceBlackWhite with the + TIFFSetField() method, not directly. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1043 + + * tools/ppm2tiff.c: Added support for PBM files as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1044 + +2006-02-27 Andrey Kiselev + + * libtiff/tif_write.c: Small code rearrangement in TIFFWriteScanline() + to avoid crash as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1081. + +2006-02-26 Andrey Kiselev + + * tools/tiff2pdf.c: Functions t2p_sample_rgbaa_to_rgb() and + t2p_sample_rgba_to_rgb() was used in place of each other, that was + resulted in problems with RGBA images with associated alpha. + As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1097 + +2006-02-23 Andrey Kiselev + + * libtiff/tif_dirwrite.c: Properly write TIFFTAG_DOTRANGE tag as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088. + + * libtiff/tif_print.c: Properly read TIFFTAG_PAGENUMBER, + TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE + tags as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088. + + * tools/tiff2ps.c: Properly scale all the pages when converting + multipage TIFF with /width/height/center options set. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1080 + +2006-02-15 Andrey Kiselev + + * tools/tiff2pdf.c: Do not create output file until all option checks + will be done. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1072 + + * tools/bmp2tiff.c: Added ability to create multipage TIFFs from the + list of input files as per bug: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1077 + +2006-02-09 Andrey Kiselev + + * libtiff/tif_tile.c: Fix error reporting in TIFFCheckTile() as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1063. + + * tools/tiffgt.c: Avoid crashing in case of image unsupported by + TIFFRGBAImage interface. + + * libtiff/tif_color.c: Avoid overflow in case of wrong input as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1065. + +2006-02-07 Frank Warmerdam + + * tools/tiff2pdf.c: Fixed support for non-YCbCr encoded JPEG + compressed TIFF files, per submission from Dan Cobra. + +2006-02-07 Andrey Kiselev + + * libtiff/{tif_dirread.c, tif_packbits.c, tif_win32.c}: Properly + cast values to avoid warnings. As per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1033. + + * libtiff/tif_dirinfo.c: Use TIFF_NOTYPE instead of 0 when + appropriate. As per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1033. + + * libtiff/tif_aux.c: Fixed type of temporary variable in + _TIFFCheckMalloc() as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=1033. + +2006-02-06 Andrey Kiselev + + * libtiff/tif_aux.c: Return static array when fetching default + YCbCrCoefficients (another problem, reported a the + http://bugzilla.remotesensing.org/show_bug.cgi?id=1029 entry). + +2006-02-03 Andrey Kiselev + + * libtiff/tif_dir.c: Special handling for PageNumber, HalftoneHints, + YCbCrSubsampling and DotRange tags as per bugs + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1029 + http://bugzilla.remotesensing.org/show_bug.cgi?id=1034 + + * libtiff/tif_dirread.c: Use _TIFFGetExifFieldInfo() instead of + _TIFFGetFieldInfo() in TIFFReadEXIFDirectory() call as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1026. + +2006-01-23 Andrey Kiselev + + * libtool related stuff updated from the 2.1a branch. + +2006-01-11 Frank Warmerdam + + * tools/bmp2tiff,pal2rgb,ppm2tiff,ras2tiff,raw2tiff,sgi2tiff, + tiff2bw,tiffcp: Fixed jpeg option processing so -c jpeg:r:50 works + properly as per bug: + http://bugzilla.remotesensing.org/show_bug.cgi?id=1025 + +2006-01-09 Bob Friesenhahn + + * configure.ac: Fix with_default_strip_size comparison as reported + by Norihiko Murase. + +2006-01-08 Bob Friesenhahn + + * test/Makefile.am (LIBTIFF): Due to linking against libtiff + incorrectly, tests were not actually testing the uninstalled + libtiff. Now they are. + +2006-01-04 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Change definitions for TIFFTAG_ICCPROFILE, + TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, TIFFTAG_XMLPACKET: readcount + should be uint32 value. + +2006-01-02 Bob Friesenhahn + + * html/man/Makefile.am (htmldoc): Fix htmldoc rule so that it can + be used if build directory is not the same as source directory. + * man/{TIFFGetField.3tiff, TIFFSetField.3tiff}: Documented + TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, and TIFFTAG_XMLPACKET, + and re-sorted tag names in alphabetical order. + +2005-12-29 Andrey Kiselev + + * libtiff 3.8.0 released. + +2005-12-28 Bob Friesenhahn + + * tools/bmp2tiff.c (main): Fixed warning regarding returning + inconsistent types from a condition. + * tools/tiffcmp.c (CheckLongTag): Eliminate warning due to printf + format. + * tools/bmp2tiff.c: Reduce compilation warnings on big-endian CPUs. + +2005-12-28 Joris Van Damme + + * html/{index.html, support.hml, libtiff.html}: Cleaned up HTML + +2005-12-27 Andrey Kiselev + + * libtiff/tiffio.h: Added VC_EXTRALEAN definition before including + windows.h, to reduce the compile time. + +2005-12-26 Bob Friesenhahn + + * libtiff/tif_jpeg.c: Improve compilation under MinGW. + +2005-12-26 Andrey Kiselev + + * libtiff/{tif_dir.c, tif_dir.h, tif_dirread.c, tif_dirinfo.c}: + tiffFieldInfo and exifFieldInfo arrays definitions moved back to + tif_dirinfo.c; added _TIFFGetFieldInfo() and _TIFFGetExifFieldInfo() + private functions to retrieve FieldInfo arrays. + +2005-12-24 Bob Friesenhahn + + * html/build.html: Added some additional instructions for when + building using MSVC under Windows. Also fixed two HTML syntax + errors and used HTML Tidy to tidy up the HTML syntax and + formatting. + +2005-12-24 Andrey Kiselev + + * libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_dirwrite.c, + tif_print.c, tif_getimage.c}: Make InkSet, NumberOfInks, DotRange and + StoNits tags custom. + +2005-12-23 Andrey Kiselev + + * libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_print.c}: Make + WhitePoint tag custom. + + * libtiff/{tif_dir.h, tiff.h}: More EXIF tags added. + +2005-12-23 Joris Van Damme + + * libtiff/tiffio.h: fixed typo that potentially resulted in + redefininition of USE_WIN32_FILEIO + + * libtiff/*: Added more 'dual-mode' error handling: Done TIFFWarning + calls in core LibTiff. + +2005-12-21 Andrey Kiselev + + * libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make RichTIFFIPTC, + Photoshop and ICCProfile tags custom. + +2005-12-21 Joris Van Damme + + * libtiff/*, contrib/*: Added 'dual-mode' error handling, enabling + newer code to get context indicator in error handler and still + remain compatible with older code: Done TIFFError calls everywhere + except in tools + +2005-12-20 Andrey Kiselev + + * tools/tiffcp.c: Added many error reporting messages; fixed integer + overflow as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=789 + +2005-12-16 Frank Warmerdam + + * contrib/addtiffo/*: Major upgrade by Joris to support subsampled + YCbCr images in jpeg compressed TIFF files. + +2005-12-14 Andrey Kiselev + + * tools/tiffcp.c: Return non-zero status when reading fails (again). + +2005-12-13 Andrey Kiselev + + * tools/tiffcp.c: Return non-zero status when reading fails. + +2005-12-12 Andrey Kiselev + + * libtiff/{tif_dir.h, tiff.h}: Added more EXIF tags. + +2005-12-09 Andrey Kiselev + + * libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make XMLPacket tag + custom. + + * tools/tiffinfo.c: Print EXIF directory contents if exist. + + * libtiff/tiff.h: Few EXIF tag numbers added. + + * libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c, + tiffio.h}: Preliminary support to read custom directories. New + functions: TIFFReadCustomDirectory() and TIFFReadEXIFDirectory(). + +2005-12-07 Andrey Kiselev + + * libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c}: + More work to implement custom directory read support. + + * libtiff/{tif_aux.c, tif_dirinfo.c, tif_dirread.c, tif_dir.h, + tif_dir.c, tif_print.c}: Make YCbCrCoefficients and ReferenceBlackWhite + tags custom. + +2005-12-05 Andrey Kiselev + + * libtiff/tif_dirread.c: One more workaround for broken + StripByteCounts tag. Handle the case when StripByteCounts array filled + with completely wrong values. + +2005-11-30 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Release file descriptor in case of failure + in the TIFFOpenW() function as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1003 + + * libtiff/tif_dirinfo.c: Correctly yse bsearch() and lfind() + functions as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=1008 + +2005-11-20 Frank Warmerdam + + * tif_open.c, tiff.h, tiffdump.c: Incorporate preliminary support + for MS MDI format. + http://bugzilla.remotesensing.org/show_bug.cgi?id=1002 + + * .cvsignore: many files added, and a few update according + to suggestion of Brad HArds on tiff mailing list. + +2005-11-03 Frank Warmerdam + + * libtiff/libtiff.def, tiffiop.h, tiffio.h: Made TIFFFreeDirectory + public. + +2005-10-31 Andrey Kiselev + + * tools/fax2tiff.c: Properly calculate sizes of temporary arrays + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=943 + + * tools/fax2tiff.c: Added option '-r' to set RowsPerStrip parameter + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=944 + + * tools/tiffdump.c: Fixed typeshift and typemask arrays initialization + problem as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=946 + + * tools/bmp2tiff.c: Fixed possible integer overflow error as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=965 + + * libtiff/tif_dirinfo.c: Make XResolution, YResolution and + ResolutionUnit tags modifiable during write process. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=977 + + * tools/tiffsplit.c: Copy fax related fields over splitted parts + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=983 + +2005-10-21 Frank Warmerdam + + * tif_dirread.c: Don't try and split single strips into "0" strips + in ChopUpSingleUncompressedStrip. This happens in some degenerate + cases (like 1x1 files with stripbytecounts==0 (gtsmall.jp2 embed tiff) + +2005-10-20 Joris Van Damme + + * tif_fax3.c: changed 'at scanline ...' style warning/errors + with incorrect use of tif_row, to 'at line ... of + strip/tile ...' style + +2005-10-15 Frank Warmerdam + + * tif_write.c: fixed setting of planarconfig as per bug report + on the mailing list from Joris. + +2005-10-07 Andrey Kiselev + + * configure.ac, configure, nmake.opt, libtiff/{tif_config.h, + tif_dirread.c}: Make the default strip size configurable via the + --with-default-strip-size and STRIP_SIZE_DEFAULT options. + +2005-09-30 Bob Friesenhahn + + * html/support.html: Fixed link to documentation on Greg Ward's + LogLuv TIFF format. + +2005-09-28 Andrey Kiselev + + * tools/tiffdump.c: Fixed crash when reading malformed tags. + +2005-09-20 Andrey Kiselev + + * tools/tiff2pdf.c: Added missed 'break' statement as per bug + http://bugzilla.remotesensing.org/show_bug.cgi?id=932 + +2005-09-12 Andrey Kiselev + + * libtiff 3.7.4 released. + + * {configure, configure.ac, Makefile.am, autogen.sh}: Applied patch + from Patrick Welche (all scripts moved in the 'config' and 'm4' + directories). + +2005-09-12 Frank Warmerdam + + * libtiff/tif_open.c: reintroduce seek to avoid problem on solaris. + +2005-09-05 Frank Warmerdam + + * libtiff/tif_dir.c: When prefreeing tv->value in TIFFSetFieldV + also set it to NULL to avoid double free when re-setting custom + string fields as per: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=922 + +2005-08-12 Frank Warmerdam + + * libtiff/tif_print.c: avoid signed/unsigned warning. + + * libtiff/tif_dirread.c: removed unused variable. + +2005-07-30 Frank Warmerdam + + * libtiff/tif_dir.c: Fixed up support for swapping "double complex" + values (128 bits as 2 64 bits doubles). GDAL gcore tests now + pass on bigendian (macosx) system. + +2005-07-28 Andrey Kiselev + + * libtiff/{tif_aux.c, tif_dirread.c, tif_fax3.c, tiffiop.h}: Rename + CheckMalloc() function to _TIFFCheckMalloc() and make it available + globally as an internal helper routine. + +2005-07-27 Andrey Kiselev + + * libtiff/tif_dir.c: More improvements in the "pass by value" part of + the custom tags handling code. + +2005-07-26 Andrey Kiselev + + * libtiff/{tif_dirread.c, tif_dirinfo.c}: Do not upcast BYTEs to + SHORTs in the TIFFFetchByteArray(). Remove TIFFFetchExtraSamples() + function, use TIFFFetchNormalTag() instead as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=831 + + Remove TIFFFetchExtraSamples() function, use TIFFFetchNormalTag() + instead. + + * libtiff/tiffconf.h.in: One more attempt to fix the AIX bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + +2005-07-25 Andrey Kiselev + + * libtiff/tif_print.c: Fixed printing of the BYTE and SBYTE arrays. + + * tools/tiffdump.c: Added support for TIFF_IFD datatype. + +2005-07-21 Andrey Kiselev + + * libtiff/tif_write.c: Do not check the PlanarConfiguration field in + the TIFFWriteCheck() function in case of single band images (as per + TIFF spec). + +2005-07-12 Andrey Kiselev + + * SConstruct, libtiff/SConstruct: Added the first very preliminary + support for SCons software building tool (http://www.scons.org/). + This is experimental infrastructure and it will exist along with the + autotools mechanics. + +2005-07-07 Andrey Kiselev + + * port/{getopt.c, strcasecmp.c, strtoul.c}: Update modules from + the NetBSD source tree (the old 4-clause BSD license changed to + the new 3-clause one). + + * configure.ac, port/lfind.c, libtiff/tiffiop.h: Added lfind() + replacement module. + + * port/dummy.c: Make the dummy function static. + +2005-07-06 Andrey Kiselev + + * tools/tiffcp.c: Fixed WhitePoint tag copying. + + * libtiff/{tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_print.c}: + Make FieldOfViewCotangent, MatrixWorldToScreen, MatrixWorldToCamera, + ImageFullWidth, ImageFullLength and PrimaryChromaticities tags custom. + +2005-07-04 Andrey Kiselev + + * libtiff 3.7.3 released. + + * configure, configure.ac: Do not use empty -R option when linking + with --enable-rpath. + +2005-07-01 Andrey Kiselev + + * libtiff/{tiffiop.h, tif_open.c}: Added open option 'h' to avoid + reading the first IFD when needed. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=875 + + * libtiff/tif_color.c: Better use of TIFFmin() macro to avoid side + effects. + +2005-06-23 Andrey Kiselev + + * tools/tiff2pdf.c: Print two characters per loop in the + t2p_write_pdf_trailer(). As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=594 + + * tools/tiffgt.c: Use MacOS X OpenGL framework when appropriate. As + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=844 + + * acinclude.m4: Updated to latest OpenGL test macros versions. + + * libtiff/tiff.h: Use correct int size on Sparc 64bit/Sun compiler + platform. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=855 + +2005-06-14 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Added support for ClipPath, XClipPathUnits + and YClipPathUnits tags. + +2005-06-07 Andrey Kiselev + + * contrib/addtiffo/tif_ovrcache.c: Properly extract tile/strip size; + use pixel sized shift in contigous case. + +2005-06-06 Andrey Kiselev + + * contrib/addtiffo/{tif_overview.c, tif_ovrcache.c, tif_ovrcache.h}: + Make overviews working for contiguos images. + +2005-06-03 Andrey Kiselev + + * libtiff/tif_open.c: Replace runtime endianess check with the compile + time one. + + * libtiff/tif_predict.c: Floating point predictor now works on + big-endian hosts. + +2005-06-01 Andrey Kiselev + + * libtiff/tif_dir.c: Use _TIFFsetString() function when read custom + ASCII values. + + * libtiff/{tif_dirinfo.c, tif_dir.h, tif_dir.c, tif_print.c}: Make + DocumentName, Artist, HostComputer, ImageDescription, Make, Model, + Copyright, DateTime, PageName, TextureFormat, TextureWrapModes and + TargetPrinter tags custom. + + * libtiff/tif_jpeg.c: Cleanup the codec state depending on + TIFF_CODERSETUP flag (to fix memry leaks). + + * libtiff/tif_jpeg.c: Initialize JPEGTables array with zero after + allocating. + +2005-05-26 Andrey Kiselev + + * configure.ac, libtiff/Makefile.am: Added workaround for + OpenBSD/MirOS soname problem as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=838 + + * libtiff/tif_dirwrite.c: Use tdir_count when calling + TIFFCvtNativeToIEEEDouble() in the TIFFWriteDoubleArray() function as + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=845 + +2005-05-25 Andrey Kiselev + + * tools/ppm2tiff.c: Fixed format string when read PPM file header with + the fscanf() function. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=861 + + * libtiff/{tif_dirinfo.c, tif_print.c}: TIFFFetchByteArray() returns + uint16 array when fetching the BYTE and SBYTE filds, so we should + consider result as pointer to uint16 array and not as array of chars. + As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=831 + + * libtiff/tif_dir.c: More efficient custom tags retrieval as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=830 + + * libtiff/tif_win32.c: Use FILE_SHARE_READ | FILE_SHARE_WRITE share + mode in CreateFile() call as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=829 + + * libtiff/Makefile.am: Fixed parallel compilation of the libtiff and + libtiffxx libraries as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=826 + + * contrib/addtiffo/{tif_overview.c, tif_ovrcache.h}: Sinchronized with + GDAL. + +2005-05-23 Frank Warmerdam + + * libtiff/tif_jpeg.c: Substantial fix for addtiffo problems with + JPEG encoded TIFF files. Pre-allocate lots of space for jpegtables + in directory. + +2005-05-22 Frank Warmerdam + + * libtiff/tif_dirread.c: Changed the code that computes + stripbytecount[0] if it appears bogus to ignore if stripoffset[0] is + zero. This is a common case with GDAL indicating a "null" tile/strip. + +2005-05-17 Andrey Kiselev + + * tools/tiffsplit.c: Check for JPEGTables tag presence before copying. + +2005-05-06 Frank Warmerdam + + * libtiff/tif_dirread.c: Applied similar change to + TIFFFetchPerSampleLongs and TIFFFetchPerSampleAnys. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=843 + + * libtiff/tif_jpeg.c: added LIB_JPEG_MK1 support in JPEGDecodeRaw(). + +2005-05-06 Andrey Kiselev + * tools/tiff2pdfr.c, man/tiff2pdf.1: Calculate the tile width properly; + added new option '-b' to use interpolation in output PDF files (Bruno + Ledoux). + +2005-05-05 Frank Warmerdam + + * libtiff/tif_dirread.c: Ensure that broken files with too many + values in PerSampleShorts work ok instead of crashing. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=843 + +2005-04-27 Andrey Kiselev + + * tools/tiffdither.c: Copy the PhotometricInterpretation tag from the + input file. + +2005-04-15 Andrey Kiselev + + * libtiff/tif_predict.c: Added ability to encode floating point + predictor, as per TIFF Technical Note 3. + +2005-04-14 Andrey Kiselev + + * libtiff/{tif_predict.h, tif_predict.c}: Added ability to decode + floating point predictor, as per TIFF Technical Note 3. + +2005-04-13 Andrey Kiselev + + * libtiff/{tiffio.h, tiffiop.h, tif_dir.c, tif_read.c, tif_swab.c}: + Added _TIFFSwab24BitData() and TIFFSwabArrayOfLong() functions used to + swap 24-bit floating point values. + + * libtiff/tiff.h: Added predictor constants. + +2005-04-08 Andrey Kiselev + + * libtiff/{tiffiop.h, tif_dir.c}: Use uint32 type for appropriate + values in _TIFFVSetField() function. Inspired by the bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=816 + + * man/TIFFSetField.3tiff: Fixed definition of the TIFFTAG_INKNAMES tag + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=816 + +2005-03-30 Andrey Kiselev + + * libtiff/tif_open.c: Do not read header in case the output file + should be truncated (Ron). + + * libtiff/{tif_dirinfo.c, tif_config.h.vc}: Use lfind() instead + of bsearch() in _TIFFFindFieldInfoByName() function (Ron). + + * libtiff/{tiff.h, tif_dirinfo.c}: Fixes in EXIF tag ordering (Ron). + +2005-03-22 Andrey Kiselev + + * configure.ac, libtiff/Makefile.am: Use libtool machinery to pass + rpath option. + +2005-03-21 Andrey Kiselev + + * libtiff/{tif_dir.c, tif_print.c}: Handle all data types in custom + tags. + +2005-03-18 Andrey Kiselev + + * libtiff/dirinfo.c: Added DNG tags. + + * libtiff/{tif_dir.c, tif_print.c}: More improvements in custom tag + handling code. + + * libtiff/tiff.h: More comments; added missed DNG tag (LensInfo); + added DNG 1.1.0.0 tags. + + * tools/tif2pdf.c: Fixed problem with alpha channel handling as per + bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=794 + + * man/TIFFGetField.3tiff: Add a note about autoregistered tags. + +2005-03-17 Andrey Kiselev + + * nmake.opt: Build with Win32 CRT library by default. + + * tools/tiff2ps.c: Fixed typo in page size handling code. + + * libtiff/{tif_dir.c, tif_print.c}: Support for custom tags, passed + by value. + + * libtiff/{tiff.h, tif_dirinfo.c, tiffiop.h}: Added EXIF related tags. + +2005-03-15 Andrey Kiselev + + * libtiff 3.7.2 released. + +2005-03-09 Andrey Kiselev + + * tools/tiffcmp.c: Added ability to compare the 32-bit integer and + floating point data; complain on unsupported bit depths. + +2005-03-05 Andrey Kiselev + + * tif_stream.cxx: Use ios namespace instead of ios_base to support + GCC 2.95. + + * libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied correct patch from + Lee Howard for HylaFax DCS tag + (see http://bugzilla.remotesensing.org/show_bug.cgi?id=771) + +2005-03-04 Andrey Kiselev + + * configure, configure.ac: Use -rpath option instead of -R as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=732 + + * libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied patch from Lee + Howard to support a new tag TIFFTAG_FAXDCS (34911) used in HylaFax + software. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=771 + + * nmake.opt, html/build.html: Add more comments, change the config + file organization a bit as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=764 + + * tools/tiffcmp.c: Use properly sized buffer in short arrays comparison + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=785 + +2005-03-03 Andrey Kiselev + + * libtiff/tif_dirread.c: More logic to guess missed strip size as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=705 + + * tools/fax2ps.c: Replace insecure mktemp() function with the + tmpfile() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=786 + +2005-02-04 Andrey Kiselev + + * libtiff/tiff.h: Changed the int8 definition to be always signed char + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=727 + + * libtiff/tiffio.h: Move TIFFOpenW() function into the extern "C"{} + block as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=763 + +2005-02-03 Bob Friesenhahn + + * tools/tiffgt.c: Fix problem on big-endian CPUs so that images + display more correctly. Images display brighter than they should + on a Sun workstation. + +2005-02-03 Andrey Kiselev + + * libtiff/tif_dirread.c: Estimate strip size in case of wrong or + suspicious values in the tags. As per bugs + + http://bugzilla.remotesensing.org/show_bug.cgi?id=705 + + and + + http://bugzilla.remotesensing.org/show_bug.cgi?id=320 + + * tools/tiff2ps.c: Fixed problem with page sizes as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=742 + +2005-01-31 Bob Friesenhahn + + * libtiff/tiff.h (TIFFTAG_TILEWIDTH): Corrected description. + (TIFFTAG_TILELENGTH): Corrected description. + +2005-01-30 Andrey Kiselev + + * configure.ac: Fixes for --with-docdir option as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=759 + + * libtiff/tif_open.c: Remove unnesessary TIFFSeekFile() call as per + bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=756 + + * libtiff/tif_stream.cxx: Fixes for C++ stream interface from + Michael Rinne and Edward Lam. + +2005-01-15 Andrey Kiselev + + * configure.ac: Make the documentation directory location configurable + via the --with-docdir option (as suggested by Jeremy C. Reed). + + * libtiff/tif_color.c: Use double as the second argument of pow() + function in TIFFCIELabToRGBInit(). As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=741 + + * libtiff/tif_pixarlog.c: Avoid warnings when converting float to + integer as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=740 + + * libtiff/tif_getimage.c: Always fill the error message buffer in + TIFFRGBAImageBegin() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=739 + +2005-01-12 Andrey Kiselev + + * libtiff/tif_jpeg.c: Added ability to read/write the fax specific + TIFFTAG_FAXRECVPARAMS, TIFFTAG_FAXSUBADDRESS and TIFFTAG_FAXRECVTIME + tags as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=736 + + * libtiff/tif_win32.c: Fixed message formatting in functions + Win32WarningHandler() and Win32ErrorHandler() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=735 + + * tools/tiff2ps.c: Interpret the -w and -h options independently. As + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=689 + +2005-01-11 Andrey Kiselev + + * libtiff/tiffio.h: Move the color conversion routines in the 'extern + "C"' section as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=727 + + * libtiff/tiff.h: Restore back the workaround for AIX Visual Age C + compiler to avoid double definition of BSD types as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + + * libtiff/Makefile.am: Place the C++ stream API in the separate + library called libtiffxx to avoid unneeded dependencies. Probably + there will be more C++ API in the future. As per bugs + + http://bugzilla.remotesensing.org/show_bug.cgi?id=733 + + and + + http://bugzilla.remotesensing.org/show_bug.cgi?id=730 + +2005-01-05 Andrey Kiselev + + * tools/tiffdump.c: Fixed problem when read broken TIFFs with the + wrong tag counts (Dmitry V. Levin, Martin Pitt). + + * configure.ac: Replace --disable-c++ with the --disable-cxx option as + per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=730 + +2004-12-25 Andrey Kiselev + + * libtiff/tif_getimage.c: More fixes for multiple-alpha-channelled + RGB-images as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=713 + + + * tools/tiffset.c: Convert character option to integer value as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=725 + +2004-12-20 Andrey Kiselev + + * libtiff 3.7.1 released. + + * html/tiffset.1.html: Add missed manual page as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=678 + + * libtiff/tiff.h: Revert back libtiff data type definitions as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=687 + +2004-12-19 Andrey Kiselev + + * libtiff/tif_dirread.c: Do not forget about TIFF_VARIABLE2 when + checking for tag count in TIFFReadDirectory() function. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=713 + + * libtiff/{tif_dirread.c, tif_fax3.c}: More argument checking in + CheckMallock() function. + + * libtiff/tif_getimage.c: Support for multiple-alpha-channelled + RGB-images as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=718 + +2004-12-15 Frank Warmerdam + + * libtiff/tif_getimage.c: #define A1 bracketing for clean build on + SunPro compiler. + +2004-12-11 Bob Friesenhahn + + * autogen.sh: aclocal and autoheader should be executed after + libtoolize. Also add '-I .' to aclocal invocation to check + current directory for macros. + +2004-12-10 Andrey Kiselev + + * libtiff/tif_dirwrite.c: Always write TIFFTAG_SUBIFD using LONG type + as per bugs + + http://bugzilla.remotesensing.org/show_bug.cgi?id=703 + + and + + http://bugzilla.remotesensing.org/show_bug.cgi?id=704 + +2004-12-04 Andrey Kiselev + + * nmake.opt: Link with the user32.lib in windowed mode. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=697 + + * libtiff/tif_win32.c: Use char* strings instead of TCHAR in windowed + mode as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=697 + + * libtiff/tif_config.in.vc: Removed unneded definitions for + read/open/close/lseek functions to fix the + + http://bugzilla.remotesensing.org/show_bug.cgi?id=680 + +2004-12-03 Andrey Kiselev + + * libtiff/{tif_dir.c, tif_dirread.c}: Remove TIFFReassignTagToIgnore() + call from the TIFFReadDirectory() function. TIFFReassignTagToIgnore + must be removed in the future, as it was never used properly. As per + bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=692 + +2004-11-30 Bob Friesenhahn + + * libtiff/tif_jpeg.c: Added a work-around in order to allow + compilation with the heavily modified version of libjpeg delivered + with Cygwin. + +2004-11-29 Andrey Kiselev + + * libtiff/tif_dir.c: Properly handle tags, which have the uint32 + counts. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=693 + + * tools/fax2ps.c: Be able to extract the first page (#0). As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=690 + +2004-11-28 Andrey Kiselev + + * libtiff/tif_unix.c: Make UNIX module compilable (and usable) + on Windows. + + * nmake.opt: Add missed DLLNAME variable. + +2004-11-26 Frank Warmerdam + + * libtiff/makefile.vc: make it easier to rename the libtiff DLL. + +2004-11-24 Andrey Kiselev + + * man/libtiff.3tiff: Improvements in the "LIST OF ROUTINES" table as + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=545 + + * man/tiffset.1: Added manual page for tiffset tool written by Jay + Berkenbilt. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=678 + +2004-11-23 Frank Warmerdam + + * libtiff/tif_error.c: fixed TIFFerror call to be TIFFError. + +2004-11-21 Frank Warmerdam + + * html/document.html: Updated Adobe web links as per email from Joris. + +2004-11-21 Andrey Kiselev + + * libtiff/{tiffio.hxx, tiffio.h}: C++ stream interface moved to new + file tiffio.hxx. We don't have any C++ in tiffio.h, those who want to + use C++ streams should #include . + +2004-11-13 Andrey Kiselev + + * libtiff/tiff.h: Added Adobe DNG tags. + + * libtiff/tif_win32.c: Typo fixed. + + * libtiff/{tif_stream.cxx, tiffio.h}: C++ stream interface updated to + be compliant with the latest standard. Appropriate additions in + makefiles now completed. + +2004-11-11 Andrey Kiselev + + * tools/tiffset.c, libtiff/tif_dirinfo.c: Properly handle the + different tag types. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=600 + +2004-11-10 Andrey Kiselev + + * libtiff/tif_aux.c: Set the appropriate ReferenceBlackWhite array for + YCbCr image which lacks that tag (noted by Hans Petter Selasky). + +2004-11-09 Andrey Kiselev + + * libtiff/tif_color.c: Division by zero fixed (Hans Petter Selasky). + +2004-11-07 Andrey Kiselev + + * libtiff/{tif_stream.cxx, tiffio.h}: Added C++ stream interface + contributed by Edward Lam (see + http://bugzilla.remotesensing.org/show_bug.cgi?id=654 for details). + Though no changes in any makefiles yet. + +2004-11-05 Frank Warmerdam + + * libtiff/tif_open.c: Removed close() in TIFFClientOpen() if file + is bad. This is the callers responsibility. + http://bugzilla.remotesensing.org/show_bug.cgi?id=651 + +2004-11-05 Andrey Kiselev + + * libtiff/{tiffio.h, tif_win32.c, libtiff.def}: Added TIFFOpenW() + function to work with the double byte strings (used to represent + filenames in some locales). As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=625 + + * libtiff/tif_dirread.c: Fixed problem when fetching BitsPerSample and + Compression tags of type LONG from broken TIFFS as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=662 + + * libtiff/tif_dirinfo.c: Fixed definition for TIFFTAG_RICHTIFFIPTC, + the writecount should have uint32 type. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=662 + + * libtiff/tif_write.c: Fixed wrong if() statement in + TIFFAppendToStrip() function as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=660 + +2004-11-04 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Change definition for TIFFTAG_EXTRASAMPLES + field. The caller should supply a count when setting this field. As + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=648 + + * libtiff/{tif_jpeg.c, tif_ojpeg.c}: TIFFTAG_JPEGTABLES should have + uint32 count. Use this type everywhere. + +2004-11-03 Frank Warmerdam + + * libtiff/tif_next.c: avoid use of u_long and u_char types. Bug 653. + +2004-11-02 Frank Warmerdam + + * tools/tiff2rgba.c: removed extra newlines in usage message. + +2004-10-30 Andrey Kiselev + + * libtiff/tif_dirwrite.c: Improvements in tag writing code. + + * tools/tiff2ps.c: Fixed wrong variable data type when read Position + tags (Tristan Hill). + +2004-10-30 Frank Warmerdam + + * libtiff/tiffiop.h: added fallback definition of assert() if we + don't have assert.h. + +2004-10-29 Andrey Kiselev + + * libtiff/tif_fax3.c: Fixed case with the wrong decode routines + choosing when the incorrect Group4Options tag set. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=323 + + * libtiff/tif_dirwrite.c: Fixed problem with passing count variable of + wrong type when writing the TIFF_BYTE/TIFF_SBYTE tags in + TIFFWriteNormalTag(). + +2004-10-28 Andrey Kiselev + + * tools/tiff2ps.c: Fixed wrong variable data type when read Resolution + tags (Peter Fales). + + * tools/{bmp2tiff.c, raw2tiff.c}: Get rid of stream I/O functions. + +2004-10-28 Frank Warmerdam + + * tools/tiff2pdf.c: added casts to avoid warnings. + + * libtiff/libtiff.def: Added several more entry points required + to link fax2tiff.c against the DLL on windows. + +2004-10-27 Andrey Kiselev + + * configure, configure.ac: Added --enable-rpath option to embed linker + paths into library binary. + +2004-10-26 Andrey Kiselev + + * tools/tiffset.c: Check the malloc return value (Dmitry V. Levin). + + * libtiff/{tif_strip.c, tif_tile.c}: Zero division problem fixed + (Vladimir Nadvornik, Dmitry V. Levin). + +2004-10-16 Andrey Kiselev + + * libtiff 3.7.0 released. + +2004-10-15 Bob Friesenhahn + + * libtiff/tif_jpeg.c: There seems to be no need to include stdio.h + in this file so its inclusion is removed. Including stdio.h + sometimes incurs an INT32 typedef conflict between MinGW's + basetsd.h and libjpeg's jmorecfg.h. + +2004-10-15 Andrey Kiselev + + * man/bmp2tiff.1: Added manual page for bmp2tiff utility. + +2004-10-13 Bob Friesenhahn + + * tools/tiffcmp.c (leof): Renamed from 'eof' in order to avoid + conflict noticed under MinGW. + * ltmain.sh: Fix for MinGW compilation. + +2004-10-13 Frank Warmerdam + + * man/tiffsplit.1: Fixed to indicate using aaa-zzz, not aa-zz. + http://bugzilla.remotesensing.org/show_bug.cgi?id=635 + +2004-10-12 Andrey Kiselev + + * libtiff/{tif_dirread.c, tif_jpeg.c, tif_luv.c, tif_ojpeg.c, + tif_pixarlog.c, tif_write.c}: Handle the zero strip/tile sizes + properly (Dmitry V. Levin, Marcus Meissner). + +2004-10-11 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Type of the TIFFTAG_SUBIFD field changed + to TIFF_IFD. + +2004-10-10 Andrey Kiselev + + * tools/bmp2tif.c: Check the space allocation results. + +2004-10-09 Andrey Kiselev + + * libtiff/tif_dir.c: Initialize td_tilewidth and td_tilelength fields + of the TIFFDirectory structure with the 0 instead of -1 to avoid + confusing integer overflows in TIFFTileRowSize() for striped images. + + * tools/tiff2pdf.c: Fixed TransferFunction tag handling reported + by Ross A. Finlayson. + + * libtiff/tif_dir.c: Fixed custom tags handling as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=629 + +2004-10-08 Frank Warmerdam + + * libtiff/tif_dirinfo.c: Fix bug with tif_foundfield and reallocation + of tif_fieldinfo. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=630 + +2004-10-04 Bob Friesenhahn + + * contrib/iptcutil/README: Added the missing README which goes + along with iptcutil. + +2004-10-03 Andrey Kiselev + + * libtiff/tif_compress.c: Improved error reporting in + TIFFGetConfiguredCODECs() (Dmitry V. Levin). + +2004-10-02 Andrey Kiselev + + * libtiff 3.7.0beta2 released. + + * libtiff/{tif_aux.c, tif_compress.c, tif_dirinfo.c, tif_dirwrite.c, + tif_extension.c, tif_fax3.c, tif_luv.c, tif_packbits.c, + tif_pixarlog.c, tif_write.c}: Added checks for failed memory + allocations and integer overflows (Dmitry V. Levin). + + * libtiff/tiff.h: Missed TIFF_BIGTIFF_VERSION constant added. + +2004-10-01 Frank Warmerdam + + * libtiff/tif_open.c: added a more informative message if a BigTIFF + file is opened. + +2004-09-30 Frank Warmerdam + + * libtiff/tif_dirinfo.c: changed type of XMLPacket (tag 700) to + TIFFTAG_BYTE instead of TIFFTAG_UNDEFINED to comply with the info + in the Adobe XMP Specification. + +2004-09-29 Andrey Kiselev + + * libtiff/{tif_jpeg.c, tif_pixarlog.c}: Use _TIFFmemset() instead of + memset(). + + * libtiff/{tif_dirread.c, tif_strip.c, tif_tile.c}: Applied patches + from Dmitry V. Levin to fix possible integer overflow problems. + +2004-09-28 Andrey Kiselev + + * libtiff/tif_getimage.c: Check for allocated buffers before clearing + (Dmitry V. Levin). + +2004-09-26 Andrey Kiselev + + * libtiff/{tif_dir.h, tif_dir.c, tif_dirread.c, tif_write.c}: + Optimize checking for the strip bounds. + + * libtiff/{tif_dirread.c, tif_strip.c}: TIFFScanlineSize() and + TIFFRasterScanlineSize() functions report zero in the case of integer + overflow now. Properly handle this case in TIFFReadDirectory() + (patches from Dmitry V. Levin). + +2004-09-25 Andrey Kiselev + + * libtiff/{tif_dirinfo.c, tif_strip.c, tif_tile.c}: Use TIFFhowmany8() + macro where appropriate. + + * tools/tiff2bw.c: Write ImageWidth/Height tags to output file, as + noted by Gennady Khokhorin. + + * libtiff/tif_dirread.c: Always check the return values, returned + by the _TIFFmalloc() (Dmitry V. Levin). + + * libtiff/tif_dir.c: Fixed possible integer overflow _TIFFset*Array() + functions (Dmitry V. Levin). + + * libtiff/{tif_dirread.c, tif_dir.c, tif_write.c}: + Potential memory leak fixed in TIFFReadDirectory(), _TIFFVSetField(), + TIFFGrowStrips() (found by Dmitry V. Levin). + +2004-09-24 Andrey Kiselev + + * libtiff/{tiffio.h, tif_compress.c}: Added TIFFGetConfiguredCODECs() + to get the list of configured codecs. + + * libtiff/{tiffiop.h, tif_dirread.c}: More overflow fixes from + Dmitry V. Levin. + +2004-09-23 Andrey Kiselev + + * libtiff/tif_dirread.c: Applied patch from Dmitry V. Levin to fix + possible integer overflow in CheckMalloc() function. + +2004-09-22 Andrey Kiselev + + * libtiff/{tiffiop.h, tif_strip.c}: Use TIFFhowmany8() macro instead + of plain TIFFhowmany() where appropriate. + +2004-09-21 Andrey Kiselev + + * libtiff/tif_getimage.c: Initialize arrays after space allocation. + +2004-09-19 Andrey Kiselev + + * libtiff 3.7.0beta released. + + * libtiff/{tif_luv.c, tif_next.c, tif_thunder.c}: Several buffer + overruns fixed, as noted by Chris Evans. + +2004-09-14 Bob Friesenhahn + + * commit: Added a script to make it more convenient to commit + updates. The CVS commit message is extracted from this ChangeLog + file. + +2004-09-14 Andrey Kiselev + + * configure.ac, configure, aclocal.m4, libtiff/{mkspans.c, tif_fax3.c, + tif_getimage.c, tif_luv.c, tif_lzw.c, tif_ojpeg.c, tif_packbits.c, + tif_predict.c, tif_read.c, tif_swab.c, tif_thunder.c, tif_write.c, + tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_jpeg.c, tif_dirinfo.c, + tif_vms.c, tif_print.c, tif_strip.c, tif_tile.c, tif_dir.h, + tif_config.h.in, tiffiop.h}: + Get rid of BSD data types (u_char, u_short, u_int, u_long). + +2004-09-13 Bob Friesenhahn + + * libtiff/tiff.h: Fix column tagging. Reference current Adobe XMP + specification. Reference libtiff bug tracking system to submit + private tag additions. + +2004-09-12 Bob Friesenhahn + + * tools/tiffgt.c: Include "tif_config.h". + + * configure.ac: Use AM_PROG_CC_C_O since it is now needed to build + tiffgt. This results in the 'compile' script being added to the + project. + + * tools/Makefile.am (tiffgt_CFLAGS): Add extra build options + required to find OpenGL headers necessary to build tiffgt. Also + ensure that the libtiff that we built is used rather than some other + libtiff installed on the system. + +2004-09-12 Andrey Kiselev + + * configure.ac, acinclude.m4, aclocal.m4: New macros to detect GLUT + libraries. + +2004-09-11 Bob Friesenhahn + + * configure.ac: Pass library configuration defines via + tif_config.h rather than extending CPPFLAGS. Configure a + libtiff/tiffconf.h in order to satisfy application requirements + (not used by library build). Do not define _POSIX_C_SOURCE=2 since + this causes failure to build on systems which properly respect + this request. + + * libtiff/tiffconf.h.in: New file to act as the template for the + configured tiffconf.h + + * libtiff/files.lst (HDRS): Install the configured tiffconf.h. + +2004-09-10 Frank Warmerdam + + * html/internals.html: Split off a discussion of adding new tags + into addingtags.html. + +2004-09-10 Andrey Kiselev + + * test/{ascii_tag.c, long_tag.c}: Preliminary test suite added. + + * tools/tiff2pdf.c: Fixed reading TransferFunction tag as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=590 + + * libtiff/tif_print.c: Fixes in InkNames and NumberOfInks reporting. + + * libtiff/tif_dirread.c: Don't reject to read tags of the + SamplesPerPixel size when the tag count is greater than number of + samples as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=576 + + * libtiff/tiff.h: Use _TIFF_DATA_TYPEDEFS_ guardian to switch off + defining int8/uint8/... etc. types. As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=607 + +2004-09-09 Frank Warmerdam + + * tools/tiff2ps.c, tools/tiffmedian.c: fiddle with include files + to avoid compile warnings about getopt() and a few other things. + +2004-09-02 Andrey Kiselev + + * libtiff/tif_dirread.c: Use memcpy() function instead of pointer + assigning magic in TIFFFetchFloat(). + +2004-09-01 Andrey Kiselev + + * libtiff/{tiffio.h, tif_open.c}: Applied patches from Joris Van Damme + to avoid requirement for tiffiop.h inclusion in some applications. See + here + + http://www.asmail.be/msg0054799560.html + + for details. + + * tools/fax2tiff.c: Use the new functions in the code. + +2004-08-25 Andrey Kiselev + + * tools/tiff2pdf.c: Initialize arrays properly. + + * tools/tiff2ps.c: Avoid zero division in setupPageState() function; + properly initialize array in PSDataBW(). + +2004-08-24 Andrey Kiselev + + * tools/tiff2pdf.c: More fixes for bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=590 + + from Ross Finlayson. + +2004-08-23 Andrey Kiselev + + * tools/tiff2ps.c: Fixed problem with uninitialized values. + + * libtiff/tif_dir.c: Initialize tif_foundfield data member in the + TIFFDefaultDirectory() (in addition to 2004-08-19 fix). + + * tools/tiff2pdf.c: Fixed a bunch of problems as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=590 + +2004-08-20 Andrey Kiselev + + * tools/tiff2pdf.c: Applied patch from Ross Finlayson that checks + that the input file has compression, photometric interpretation, + etcetra, tags or if not than a more descriptive error is returned. + + * libtiff/tif_dirread.c: Fixed problem in TIFFReadDirectory() in the + code, responsible for tag data type checking. + +2004-08-19 Andrey Kiselev + + * libtiff/{tiffiop.h, tif_dirinfo.c}: Fixed problem with the static + variable as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=593 + +2004-08-16 Andrey Kiselev + + * tools/ras2tiff.c: Fixed issue with missed big-endian checks as per + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=586 + +2004-08-01 Andrey Kiselev + + * libtiff/{tif_config.h.in, tif_config.h.vc}: config.h.in and + config.h.vc files renamed in the tif_config.h.in and tif_config.h.vc. + +2004-07-24 Andrey Kiselev + + * libtiff/tif_lzw.c: LZW compression code is merged back from the + separate package. All libtiff tools are updated to not advertise an + abcence of LZW support. + +2004-07-12 Andrey Kiselev + + * libtiff/tiffio.h: Revert thandle_t back to void* type. + +2004-07-11 Andrey Kiselev + + * libtiff/{tif_read.c, tif_tile.c, tif_strip.c}: Fixes in error + messages, as suggested by Bernd Herd. + +2004-07-03 Andrey Kiselev + + * libtiff/tif_dir.c: Call TIFFError() instead of producing warnings + when setting custom tags by value. Reported by Eric Fieleke. + +2004-06-14 Andrey Kiselev + + * tools/bmp2tiff.c: Add missed RawsPerStrip setting. + +2004-06-08 Andrey Kiselev + + * tools/bmp2tiff.c: Added new utility to convert Windows BMP files + into TIFFs. + +2004-06-07 Andrey Kiselev + + * libtiff 3.7.0alpha released. + +2004-06-06 Andrey Kiselev + + * libtiff/{tiff.h, tif_dirwrite.c, tif_fax3.c, tif_packbits.c,}: Get rid + of ugly 64-bit hacks, replace them with the clever (autoconf based ) + ones :-). + + * libtiff/tiffio.h: Define thandle_t as int, not void* (may cause + problems in 64-bit environment). + +2004-06-05 Andrey Kiselev + + * tools/tiffset.c: tiffset now can set any libtiff supported tags. + Tags can be supplied by the mnemonic name or number. + + * libtiff/{tiffio.h, tif_dir.h, tif_dirinfo.c,}: Added two new + functions TIFFFindFieldInfoByName() and TIFFFieldWithName(). + +2004-05-27 Andrey Kiselev + + * libtiff/tif_ojpeg.c: Fixed problem with duplicated SOI and SOF + markers as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=581 + +2004-05-24 Andrey Kiselev + + * tools/tiffsplit.c: Don't forget to copy Photometric + Interpretation tag. + +2004-05-20 Andrey Kiselev + + * libtiff/{tif_open.c, tiffio.h}: New function added: + TIFFIsBigEndian(). Function returns nonzero if given was file written + in big-endian order. + + * tools/tiffsplit.c: Fixed problem with unproperly written multibyte + files. Now output files will be written using the same byte order + flag as in the input image. See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=574 + + for details. + +2004-05-19 Frank Warmerdam + + * libtiff/tif_print.c: added (untested) support for printing + SSHORT, SLONG and SRATIONAL fields. + + * tools/tiffcp.c: close output file on normal exit. + +2004-05-17 Andrey Kiselev + + * libtiff/tif_fax3.c: Avoid reading CCITT compression options + if compression type mismatches. See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=565 + +2004-04-30 Andrey Kiselev + + * libtiff/tif_strip.c: Never return 0 from the + TIFFNumberOfStrips(). + +2004-04-29 Andrey Kiselev + + * libtiff/tif_dirread.c: Workaround for broken TIFF writers which + store single SampleFormat value for multisampled images. See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=562 + +2004-04-25 Andrey Kiselev + + * configure.ac, libtiff/{tiff.h, config.h.in}: Added tests for int8, + int16 and int32 types to avoid complains on some compilers. Details at + + http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + +2004-04-20 Andrey Kiselev + + * tools/tiff2pdf.c: Fixed problem with unaligned access as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=555 + +2004-04-14 Andrey Kiselev + + * libtiff/tif_write.c: Allow in-place updating of the compressed + images (don't work properly with all codecs). For details see GDAL bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=534 + +2004-04-06 Andrey Kiselev + + * libtiff/tif_jpeg.c: Workaround for wrong sampling factors used + in the Intergarph JPEG compressed TIFF images as per bug: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=532 + +2004-04-04 Frank Warmerdam + + * libtiff/tif_open.c: close clientdata if TIFFClientOpen() fails + via bad2. + +2004-03-26 Andrey Kiselev + + * tools/tiffcp.c: Properly set Photometric Interpretation in case of + JPEG compression of grayscale images. + + * tools/tiffcp.c: Don't emit warnings when Orientation tag does not + present in the input image. + +2004-03-19 Andrey Kiselev + + * {many}: The first attempt to switch to autotools. + +2004-03-03 Andrey Kiselev + + * libtiff/tif_open.c: Use dummy mmap/munmap functions in + TIFFClientOpen() when the appropriate client functions was not + supplied by user. + +2004-03-02 Frank Warmerdam + + * tools/ycbcr.c: fixed main() declaration as per: + http://bugzilla.remotesensing.org/show_bug.cgi?id=513 + +2004-02-26 Andrey Kiselev + + * tools/tiffsplit.c: Copy JPEGTables tag contents for JPEG compressed + images. Reported by Artem Mirolubov. + + * libtiff/tif_dirread.c: Fixed problem with handling TIFF_UNDEFINED + tag type in TIFFFetchNormalTag() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=508 + +2004-02-17 Frank Warmerdam + + * libtiff/tif_codec.c: Fixed typo in TIFFInitPackBits name as per: + http://bugzilla.remotesensing.org/show_bug.cgi?id=494 + +2004-02-05 Andrey Kiselev + + * libtiff/tif_fax3.c: Fixed problem with CCITT encoding modes as per + bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=483 + + But we need more work on fax codec to support update mode. + +2004-01-30 Frank Warmerdam + + * libtiff/libtiff.def: Added TIFFCurrentDirOffset, TIFFWriteCheck, + TIFFRGBAImageOK, and TIFFNumberOfDirectories as suggested by + Scott Reynolds. + +2004-01-29 Andrey Kiselev + + * libtiff/tiff.h: Fixed tag definitions for TIFFTAG_YCLIPPATHUNITS + and TIFFTAG_INDEXED as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=475 + + * libtiff/{tif_win32.c, tif_unix.c}: Check whether the pointer is + NULL before proceeding further as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=474 + + Check results, returned by the TIFFFdOpen() before returning and close + file if TIFFFdOpen() failed as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=468 + + * libtiff/tif_open.c: More fixes for + + http://bugzilla.remotesensing.org/show_bug.cgi?id=468 + +2004-01-28 Andrey Kiselev + + * libtiff/{libtiff.def, tif_close.c, tiffio.h, tif_open.c}: Separate + TIFFCleanup() from the TIFFClose() in order to fix the bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=468 + + * tools/tiffcp.c: Fixed problem with wrong interpretation of the + InkNames tag as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=466 + + Memory leak fixed. + +2004-01-21 Frank Warmerdam + + * libtiff/tif_dirwrite.c: Fixed handling of writable ASCII tags that + are field_passcount=TRUE properly. Arguably anonymous custom tags + should be declared as passcount=FALSE, but I don't want to change + that without a careful review. + +2004-01-20 Andrey Kiselev + + * libtiff/tif_write.c: Fixed reporting size of the buffer in case of + stripped image in TIFFWriteBufferSetup(). As per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=460 + +2004-01-11 Andrey Kiselev + + * libtiff/tif_dir.c: Incomplete cleanup in TIFFFreeDirectory(), + patch from Gerben Koopmans. + + * libtiff/tif_dirread.c: Check field_passcount value before setting + the value of undefined type, patch from Gerben Koopmans. + +2004-01-02 Andrey Kiselev + + * tools/tiffcp.c: Fixed problem with wrong Photometric setting for + non-RGB images. + +2003-12-31 Andrey Kiselev + + * libtiff/tif_win32.c: Fixed problem with _TIFFrealloc() when the NULL + pointer passed. Patch supplied by Larry Grill. + + * libtiff/{tiff.h, tif_fax3.c}:Fixes for AMD 64 platform as + suggested by Jeremy C. Reed. + +2003-12-26 Andrey Kiselev + + * libtiff 3.6.1 released. + +2003-12-24 Andrey Kiselev + + * config.guess, config.sub: Updated from the recent upstream. + +2003-12-22 Andrey Kiselev + + * libtiff/{tif_color, tif_getimage.c, tiffio.h}, man/TIFFcolor.3t: + More cleanups in color conversion interface, added appropriate manual + page. + +2003-12-19 Andrey Kiselev + + * libtiff/{tif_extension.c, tif_dirinfo.c, tiff.h}: Warnings fixed as + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=357 + + * tools/tiff2ps.c: Added support for alpha channel. Fixes + + http://bugzilla.remotesensing.org/show_bug.cgi?id=428 + + * libtiff/{libtiff.def, tif_color.c, tif_getimage.c, tiffio.h}: + Interface for Lab->RGB color conversion is finally cleaned up. + Added support for ReferenceBlackWhite tag handling when converted from + YCbCr color space. The latter closes + + http://bugzilla.remotesensing.org/show_bug.cgi?id=120 + +2003-12-07 Andrey Kiselev + + * libtiff/{tif_getimage.c, tiffio.h}: Avoid warnings. + + * libtiff/makefile.vc, tools/makefile.vc: Support for IJG JPEG + library. + +2003-12-06 Andrey Kiselev + + * libtiff/{tif_getimage.c, tif_aux.c}: Read WhitePoint tag from the + file and properly use it for CIE Lab->RGB transform. + +2003-12-04 Andrey Kiselev + + * libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: YCbCr->RGB + conversion routines now in the tif_color.c module. New function + TIFFYCbCrtoRGB() available in TIFF API. + + * libtiff/tif_dirwrite.c: Handle TIFF_IFD tag type correctly. + +2003-12-03 Andrey Kiselev + + * libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: Improvements in + CIE Lab conversion code. Start moving YCbCr stuff to the tif_color.c + module. + + * libtiff/{tif_getimage.c, tiffio.h}, man{TIFFReadRGBAImage.3t, + TIFFReadRGBAStrip.3t, TIFFReadRGBATile.3t, TIFFRGBAImage.3t}: + Finally resolved problems with orientation handling. TIFFRGBAImage + interface now properly supports all possible orientations, i.e. images + will be flipped both in horizontal and vertical directions if + required. 'Known bugs' section now removed from the appropriate manual + pages. Closed bug entry: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=322 + +2003-12-02 Andrey Kiselev + + * libtiff/tif_dir.c: Fixed order of the parameters in TIFFError() + function calls as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=440 + +2003-11-28 Ross Finlayson + + * tools/tiff2pdf.c: Some bugs fixed. + +2003-11-27 Andrey Kiselev + + * libtiff/tif_luv.c: Fixed bug in 48-bit to 24-bit conversion routine, + reported by Antonio Scuri. + + * man/tiff2pdf.1: Few improvements in page layout. + + * Makefile.in, /man/Makefile.in, /html/man/tiff2pdf.1.html: + Added support fpr tiff2pdf manual page. + +2003-11-26 Ross Finlayson + + * /man/tiff2pdf.1: File added to repository. + +2003-11-26 Andrey Kiselev + + * Makefile.in, /tools/{Makefile.in, makefile.vc}: + Added support fpr tiff2pdf utility. + +2003-11-25 Ross Finlayson + + * /tools/tiff2pdf.c: File added to repository. + +2003-11-22 Andrey Kiselev + + * /tools/raw2tiff.c: sqrtf() replaced with sqrt(). + +2003-11-21 Andrey Kiselev + + * /tools/raw2tiff.c: #include removed. + + * tools/{Makefile.in, tiffgt.c}: Unmaintained and platform dependent + sgigt utility removed and replaced with the completely rewritten + portable tiffgt tool (depend on OpenGL and GLUT). Initial revision, + there is a lot of things to improve. + + * libtiff/tif_ojpeg.c: TIFFVGetField() function now can properly + extract the fields from the OJPEG files. Patch supplied by Ross + Finlayson. + + * libtiff/{tiffio.h, tif_codec.c}, man/{libtiff.3t, TIFFcodec.3t}: + Added new function TIFFIsCODECConfigured(), suggested by Ross + Finlayson. + +2003-11-18 Andrey Kiselev + + * libtiff/tif_dirinfo.c: Implemented binary search in + _TIFFMergeFieldInfo(). Patch supplied by Ross Finlayson. + + * libtiff/tif_dir.h: _TIFFFindOrRegisterdInfo declaration replaced + with _TIFFFindOrRegisterFieldInfo as reported by Ross Finlayson. + +2003-11-17 Frank Warmerdam + + * tif_dirread.c: do not mark all anonymously defined tags to be + IGNOREd. + +2003-11-17 Andrey Kiselev + + * contrib/pds/{tif_pdsdirread.c, tif_pdsdirwrite.c}: Use + TIFFDataWidth() function insted of tiffDataWidth array. + +2003-11-16 Andrey Kiselev + + * libtiff/{tiff.h, tif_dirinfo.c}: Added support for IFD (13) + datatype, intruduced in "Adobe PageMaker TIFF Tech. Notes". + +2003-11-15 Frank Warmerdam + + * Makefile.in: fixed missing backslash for tif_color.c in list. + +2003-11-13 Andrey Kiselev + + * libtiff/{tif_color.c, tif_getimage.c, tiffio.h, Makefile.in}: + New color space conversion code: CIE L*a*b* 1976 images now supported + by the TIFFRGBAImage interface. All introduced routines go to new + module tif_color.c. Eventually all color conversion functions should + be moved there. + +2003-11-12 Andrey Kiselev + + * tools/{ras2tiff.c, rasterfile.h}: Properly determine SUN Rasterfiles + with the reverse byte order (it is reported by the magic header + field). Problem reported by Andreas Wiesmann. + + * tools/raw2tiff.c, man/raw2tiff.1: Few improvements in correlation + calculation function. Guessing mechanics now documented in manual page. + +2003-11-11 Andrey Kiselev + + * tools/raw2tiff.c: Implemented image size guessing using + correlation coefficient calculation between two neighbour lines. + +2003-11-09 Frank Warmerdam + + * libtiff/tif_tile.c: remove spurious use of "s" (sample) in the + planarconfig_contig case in TIFFComputeTile(). + + http://bugzilla.remotesensing.org/show_bug.cgi?id=387 + +2003-11-09 Andrey Kiselev + + * libtiff/tiffiop.h: New macros: TIFFmax, TIFFmin and TIFFrint. + +2003-11-07 Andrey Kiselev + + * libtiff/{tiffio.h, tif_strip.c}, man/{TIFFstrip.3t, libtiff.3t}: + Added TIFFRawStripSize() function as suggested by Chris Hanson. + +2003-11-03 Andrey Kiselev + + * libtiff/{tif_lzw.c, tif_fax3.c}: Proper support for update mode as + per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=424 + +2003-10-29 Andrey Kiselev + + * libtiff/libtiff.def: Added TIFFReadRGBAImageOriented. + + * html/build.html: Added note about GNU make requirement. + +2003-10-25 Andrey Kiselev + + * Makefile.in: Fixes in using MAKEFLAGS as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=418 + + * port/install.sh.in: Option -p added to the mkdir command to create + all directory tree structure before installing. + +2003-10-18 Andrey Kiselev + + * /tools/tiff2ps.c: #include replaced with the + #include . + +2003-10-16 Andrey Kiselev + + * Makefile.in: Add an absolute path to the test_pics.sh call. + +2003-10-12 Andrey Kiselev + + * libtiff/tiffcomp.h: #define _BSDTYPES_DEFINED when defining BSD + typedefs. + +2003-10-09 Andrey Kiselev + + * configure, libtiff/{Makefile.in, mkversion.c}: + Relative buildings fixed. + + * tools/Makefile.in: Added "-I../libtiff" to the tiffset building + rule. + +2003-10-07 Andrey Kiselev + + * Makefile.in: Added missed v3.6.0.html. + + * libtiff/tiffio.h: Typo fixed: ORIENTATION_BOTTOMLEFT replaced with + ORIENTATION_BOTLEFT. + +2003-10-04 Andrey Kiselev + + * 3.6.0 final release. + +2003-10-03 Andrey Kiselev + + * libtiff/{tif_getimage.c, tiffio.h}, man/TIFFReadRGBAImage.3t: New + function TIFFReadRGBAImageOriented() implemented to retrieve raster + array with user-specified origin position as suggested by Jason Frank. + See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=322 + + for details. + + * tools/tiff2rgba.c: Switched to use TIFFReadRGBAImageOriented() + instead of TIFFReadRGBAImage(). + + * tools/tiff2ps.c: Fixed possible endless loop as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=404 + +2003-09-30 Andrey Kiselev + + * libtiff/tif_dirread.c: Check field counter against number of fields + in order to fix + + http://bugzilla.remotesensing.org/show_bug.cgi?id=366 + + * libtiff/tif_fax3.c: Fix wrong line numbering as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=342 + +2003-09-25 Andrey Kiselev + + * libtiff/{tiffiop.h, tif_dirread.c, tif_dir.c, tif_open.c, + tif_close.c}: Store a list of opened IFD to prevent looping as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=383 + +2003-09-23 Andrey Kiselev + + * libtiff/tif_dirread.c: More fixes for EstimateStripByteCounts(). See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=358 + +2003-08-21 Andrey Kiselev + + * tools/tiffmedian.c: int declaration replaced with the uint32 to + support large images as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=382 + +2003-08-12 Andrey Kiselev + + * libtiff/Makefile.in: Fixed problem with building in different + directory. + + * tools/tiff2ps.c: Added missing #include . + + * libtiff/tif_dirwrite.c: More fixes for custom tags code + from Ashley Dreier. + +2003-08-07 Andrey Kiselev + + * tools/tiff2ps.c: Added page size setting when creating PS Level 2. + Patch submitted by Balatoni Denes (with corrections from Tom + Kacvinsky). + + * tools/tiff2ps.c: Fixed PS comment emitted when FlateDecode is + being used. Reported by Tom Kacvinsky. + + * libtiff/tif_dirwrite.c: Fixed problem with custom tags writing, + reported by Ashley Dreier. + + * libtiff/tif_print.c: Fixed problem with float tags reading, support + for printing RATIONAL and BYTE tags added. + +2003-08-05 Andrey Kiselev + + * libtiff/tif_lzw.c: Move LZW codec state block allocation back to + TIFFInitLZW(), because its initialization in LZWSetupDecode() cause + problems with predictor initialization. Remove O_RDONLY check during + state block allocation to be able open LZW compressed files in update + mode. + + Problem exist for libtiff version of the tif_lzw.c module. One from + lzw-compression-kit hasn't such troubles. + +2003-08-04 Frank Warmerdam + + * libtiff/tif_write.c: modified tif_write.c so that the various + encoded write functions use tif_postdecode() to apply byte order + swapping (swab) to the application passed data buffer if the same + would be done when reading. This allows us to write pixel data with + more than 8 bits per sample to existing files of a non-native byte + order. One side effect of this change is the applications buffer + itself is altered in this case by the act of writing. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=171 + +2003-07-25 Frank Warmerdam + + * libtiff/tif_open.c: avoid signed/unsigned casting warning + initializing typemask as per patch from J.A. Strother. + + * tools/tiffcp.c: fixed signed/unsigned casting warning. + + * libtiff/tif_print.c: dos2unix conversion. + + * tools/tiffsplit.c: increased the maximum number of pages that + can be split. Patch provided by Andrew J. Montalenti. + +2003-07-11 Andrey Kiselev + + * tools/raw2tiff.c: Added option `-p' to explicitly select color + space of input image data. Closes + + http://bugzilla.remotesensing.org/show_bug.cgi?id=364 + +2003-07-08 Frank Warmerdam + + * tif_aux.c, tif_codec.c, tif_dir.c, tif_dirread.c, tif_extension.c, + tif_fax3.c, tif_getimage.c, tif_luv.c, tif_lzw.c, tif_next.c, + tif_packbits.c, tif_predict.c, tif_print.c, tif_swab.c, tif_thunder.c: + avoid casting warning at /W4. + +2003-07-03 Andrey Kiselev + + * tools/thumbnail.c: Memory leak fixed as reported by Robert S. Kissel. + +2003-06-30 Andrey Kiselev + + * libtiff/tif_pixarlog.c: Unused variables removed. + + * libtiff/{tif_dirread.c, tif_dir.c}: Fixed problem with + EstimateStripByteCounts() as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=358 + + * libtiff/{tif_dirwrite.c, tif_packbits.c}: Fixed compilation on + 64-bit architectures as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=357 + + * libtiff/tif_dirinfo.c: TIFFDataWidth() returns 0 in case of + unknown data type. + +2003-06-19 Frank Warmerdam + + * libtiff/tif_print.c: fixed some serious bugs when printing + custom tags ... almost certain to crash. + + * libtiff/tif_dirread.c: Don't ignore custom fields that are + autodefined. Not sure how this got to be like this. + +2003-06-18 Andrey Kiselev + + * 3.6.0 Beta2 released. + + * tools/tiffcmp.c, man/tiffcmp.1: Fixed problem with unused data + comparing as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=349 + + `-z' option now can be used to set the number of reported different + bytes. + +2003-06-09 Andrey Kiselev + + * tools/tiffcp.c, man/tiffcp.1: Added possibility to specify value -1 + to -r option to get the entire image as one strip. See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=343 + + for details. + +2003-06-04 Andrey Kiselev + + * tools/tiffcp.c: Set the correct RowsPerStrip and PageNumber + values as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=343 + +2003-05-27 Frank Warmerdam + + * libtiff/tif_jpeg.c: modified segment_height calculation to always + be a full height tile for tiled images. Also changed error to just + be a warning. + +2003-05-25 Andrey Kiselev + + * tools/fax2tiff.c: Page numbering fixed, as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=341 + +2003-05-20 Andrey Kiselev + + * contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README}, + configure, Makefile.in: Switched back to the old behaviour. Likely + better solution should be found for OJPEG support. + +2003-05-11 Andrey Kiselev + + * libtiff/mkversion.c: Fixed problem with wrong string size when + reading RELEASE-DATE file. + +2003-05-07 Andrey Kiselev + + * tools/tiff2ps.c: Fixed bug in Ascii85EncodeBlock() function: array + index was out of range. + +2003-05-06 Andrey Kiselev + + * contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README}, + configure, Makefile.in: Improved libtiff compilation with OJPEG + support. Now no need for patching IJG JPEG library, hack requred by + libtiff will be compiled and used in-place. Implemented with + suggestion and help from Bill Allombert, Debian's libjpeg maintainer. + + * libtiff/tif_aux.c: Properly handle TIFFTAG_PREDICTOR in + TIFFVGetFieldDefaulted() function. + +2003-05-05 Andrey Kiselev + + * tools/ppm2tiff.c: PPM header parser improved: now able to skip + comments. + + * tools/tiffdither.c: Fixed problem with bit fill order tag setting: + was not copied from source image. + + * libtiff/getimage.c: Workaround for some images without correct + info about alpha channel as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=331 + +2003-04-29 Andrey Kiselev + + * tools/tiff2ps.c, man/tiff2ps.1: Add ability to generate PS Level 3. + It basically allows one to use the /flateDecode filter for ZIP + compressed TIFF images. Patch supplied by Tom Kacvinsky. Fixes + + http://bugzilla.remotesensing.org/show_bug.cgi?id=328 + + * tools/tiff2ps.c: Force deadzone printing when EPS output specified + as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=325 + +2003-04-17 Andrey Kiselev + + * libtiff/tif_dirread.c: Removed additional check for StripByteCounts + due to problems with multidirectory images. Quality of error messages + improved. + +2003-04-16 Andrey Kiselev + + * tools/tiffcp.c: Fixed problem with colorspace conversion for JPEG + encoded images. See bug entries + + http://bugzilla.remotesensing.org/show_bug.cgi?id=275 + + and + + http://bugzilla.remotesensing.org/show_bug.cgi?id=23 + + * libtiff/tif_dirread.c: Additional check for StripByteCounts + correctness. Fixes + + http://bugzilla.remotesensing.org/show_bug.cgi?id=320 + +2003-03-12 Andrey Kiselev + + * tools/{fax2ps.c, fax2tiff.c, gif2tiff.c, pal2rgb.c, ppm2tiff.c, + ras2tiff.c, raw2tiff.c, rgb2ycbcr.c, thumbnail.c, tiff2bw.c, + tiff2ps.c, tiff2rgba.c, tiffcp.c, tiffdither.c, tiffinfo.c, + tiffmedian.c}: Added library version reporting facility to all tools. + +2003-03-06 Frank Warmerdam + + * port/install.sh.in: Fixed problems with install producing paths + like ///usr/local/lib on cygwin. + +2003-02-27 Andrey Kiselev + + * tools/fax2tiff.c, man/fax2tiff.1: New switch (-X) to set width of + raw input page. Patch supplied by Julien Gaulmin. See + + http://bugzilla.remotesensing.org/show_bug.cgi?id=293 + + for details. + +2003-02-26 Frank Warmerdam + + * libtiff/tif_dir.c: fixed up the tif_postdecode settings + responsible for byte swapping complex image data. + + * libtiff/tif_lzw.c: fixed so that decoder state isn't allocated till + LZWSetupDecode(). Needed to read LZW files in "r+" mode. + +2003-02-07 Andrey Kiselev + + * tools/ppm2tiff.c: Fixed problem with too many arguments. + +2003-02-04 Andrey Kiselev + + * tools/raw2tiff.c: Memory leak fixed. + +2003-02-03 Andrey Kiselev + + * tools/fax2tiff.c, man/fax2tiff.1: Applied patch from Julien Gaulmin + (thanks, Julien!). More switches for fax2tiff tool for better control + of input and output. Details at + + http://bugzilla.remotesensing.org/show_bug.cgi?id=272 + +2003-02-03 Frank Warmerdam + + * libtiff/tif_jpeg.c: Modified to defer initialization of jpeg + library so that we can check if there is already any tile/strip data + before deciding between creating a compressor or a decompressor. + +2003-01-31 Frank Warmerdam + + * libtiff/tif_write.c: TIFFWriteCheck() now fails if the image is + a pre-existing compressed image. That is, image writing to + pre-existing compressed images is not allowed. + + * libtiff/tif_open.c: Removed error if opening a compressed file + in update mode. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=198 + +2003-01-31 Andrey Kiselev + + * config.guess, config.sub: Updated to recent upstream versions. + +2003-01-15 Frank Warmerdam + + * cut 3.6.0 Beta release. + +2002-12-20 Andrey Kiselev + + * tools/fax2ps.c, man/fax2ps.1: Page size was determined + in wrong way as per bug + + http://bugzilla.remotesensing.org/show_bug.cgi?id=239 + +2002-12-17 Frank Warmerdam + + * libtiff/tif_dirread.c: Allow wrong sized arrays in + TIFFFetchStripThing(). + + http://bugzilla.remotesensing.org/show_bug.cgi?id=49 + +2002-12-02 Frank Warmerdam + + * libtiff/tif_dir.c: fix problem with test on td_customValueCount. + Was using realloc even first time. Fix by Igor Venevtsev. + +2002-11-30 Frank Warmerdam + + * libtiff/tif_dir.c: fixed bug with resetting an existing custom + field value. + + * libtiff/tif_dir.c: Fixed potential problem with ascii "custom" + tags in TIFFVGetField() ... added missing break. + +2002-10-14 Frank Warmerdam + + * tools/tiff2ps.c: fixes a problem where "tiff2ps -1e" did not make + the scanline buffer long enough when writing rgb triplets. + The scanline needs to be 3 X the number of dots or else it will + contain an incomplete triplet and programs that try to separate + the eps by redefining the colorimage operator will get messed up. + Patch supplied by William Bader. + + * Makefile.in: added tif_extension.c to file list as per + http://bugzilla.remotesensing.org/show_bug.cgi?id=218. + +2002-10-11 Andrey Kiselev + + * configure, config.site, libtiff/{tif_unix.c, Makefile.in}: Fix for + large files (>2GiB) supporting. New option in the config.site: + LARGEFILE="yes". Should be enough for I/O of the large files. + +2002-10-10 Frank Warmerdam + + * libtiff/html/v3.6.0.html: new release notes. + + * libtiff/index.html: removed faq, cvs snapshot cruft. Added email + link for Andrey. Pointer to v3.6.0.html. + + * libtiff/Makefile.in: added direct rule for tiffvers.h for release. + +2002-10-07 Andrey Kiselev + * tools/tiff2ps.c, man/tiff2ps.1: Applied patch form Sebastian Eken + (thanks, Sebastian!). New switches: + -b # for a bottom margin of # inches + -c center image + -l # for a left margin of # inches + -r rotate the image by 180 degrees + New features merged with code for shrinking/overlapping. + Previously added -c and -n switches (for overriding PS units) renamed + in -x and -y respectively. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=200 + + * html/man/*.html: Updated from actual manual pages. + +2002-10-06 Frank Warmerdam + + * libtiff/tif_jpeg.c: fixed problem with boolean defined with wrong + size on windows. Use #define boolean hack. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=188 + + * libtiff/tiff.h: Don't do special type handling in tiff.h unless + USING_VISUALAGE is defined. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + +2002-10-03 Frank Warmerdam + + * libtiff/tiff.h: added COMPRESSION_JP2000. + +2002-10-02 Andrey Kiselev + + * libtiff/tif_dirread.c: Another fix for the fetching SBYTE arrays + by the TIFFFetchByteArray() function. Should finally resolve + + http://bugzilla.remotesensing.org/show_bug.cgi?id=52 + + * configure: Set -DPIXARLOG_SUPPORT option along with -DZIP_SUPPORT + + * html/Makefile.in: New targets added: html and groffhtml for + producing HTML representations of the manual pages automatically. + html target uses man2html tool, groffhtml uses groff tool. + +2002-09-29 Frank Warmerdam + + * configure, libtiff/Makefile.in: Added SCO OpenServer 5.0.6 support + from John H. DuBois III. + +2002-09-15 Andrey Kiselev + + * Makefile.in, /man/{raw2tiff.1, Makefile.in, libtiff.3}: Added + manual page for raw2tiff(1) tool. + +2002-09-12 Andrey Kiselev + + * /libtiff/{tiffio.h, tif_dir.h}: TIFFDataWidth() declaration moved to + the tiffio.h header file. + + * Makefile.in, /man/{TIFFDataWidth.3t, Makefile.in, libtiff.3}: Added + manual page for TIFFDataWidth() function + +2002-09-08 Frank Warmerdam + + * libtiff/tif_dirread.c: Expand v[2] to v[4] in TIFFFetchShortPair() + as per http://bugzilla.remotesensing.org/show_bug.cgi?id=196. + + * tools/tiff2ps.c: Don't emit BeginData/EndData DSC comments + since we are unable to properly include the amount to skip. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=80 + +2002-09-02 Andrey Kiselev + + * /libtiff/tif_dirread.c: Fixed problem with SBYTE type data fetching + in TIFFFetchByteArray(). Problem described at + http://bugzilla.remotesensing.org/show_bug.cgi?id=52 + +2002-08-22 Andrey Kiselev + + * /libtiff/tif_dirinfo.c: Further additions to free custom fields + in _TIFFSetupFieldInfo() function. + See http://bugzilla.remotesensing.org/show_bug.cgi?id=169 for details. + + * /libtiff/tif_lzw.c: Additional consistency checking added in + LZWDecode() and LZWDecodeCompat(). + Fixes http://bugzilla.remotesensing.org/show_bug.cgi?id=190 + and http://bugzilla.remotesensing.org/show_bug.cgi?id=100 + + * /libtiff/tif_lzw.c: + Added check for valid code lengths in LZWDecode() and + LZWDecodeCompat(). Fixes + http://bugzilla.remotesensing.org/show_bug.cgi?id=115 + +2002-08-16 Andrey Kiselev + + * /libtiff/{Makefile.vc, libtiff.def}: + Missed declarations added. + +2002-08-15 Frank Warmerdam + + * tif_getimage.c: Ensure that TIFFRGBAImageBegin() returns the + return code from the underlying pick function. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=177 + + * tif_dir.h: changed FIELD_CODEC to 66 from 64 to avoid overlap + with FIELD_CUSTOM as mentioned in bug 169. + + * tif_close.c: added logic to free dynamically created anonymous + field definitions to correct a small memory leak. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=169 + +2002-08-10 Andrey Kiselev + + * /tools/{raw2tiff.c, Makefile.in, Makefile.lcc, Makefile.vc}: + New tool: raw2tiff --- raw images to TIFF converter. No manual page yet. + +2002-07-31 Frank Warmerdam + + * libtiff/tif_jpeg.c: Fixed problem with setting of nrows in + JPEGDecode() as per bugzilla bug (issue 1): + + http://bugzilla.remotesensing.org/show_bug.cgi?id=129 + + * libtiff/{tif_jpeg.c,tif_strip.c,tif_print.c}: Hacked tif_jpeg.c to + fetch TIFFTAG_YCBCRSUBSAMPLING from the jpeg data stream if it isn't + present in the tiff tags. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + + * libtiff/tif_read.c, libtiff/tif_write.c: TIFFReadScanline() and + TIFFWriteScanline() now set tif_row explicitly in case the codec has + fooled with the value. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=129 + +2002-06-22 Andrey Kiselev + + * /tools/tiff2ps.c: Added workaround for some software that may crash + when last strip of image contains fewer number of scanlines than + specified by the `/Height' variable. See + http://bugzilla.remotesensing.org/show_bug.cgi?id=164 + for explanation. + +2002-06-21 Andrey Kiselev + + * tools/tiff2ps, man/tiff2ps.1: New functionality for tiff2ps utility: + splitting long images in several pages. See + http://bugzilla.remotesensing.org/show_bug.cgi?id=142 for explanation. + Patch granted by John Williams . + +2002-06-11 Frank Warmerdam + + * libtiff/contrib/win95: renamed to contrib/win_dib. Added new + Tiffile.cpp example of converting TIFF files into a DIB on Win32. + This one is described in: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=143 + + * libtiff/tif_ojpeg.c: Major upgrade from Scott. See details at: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=156 + +2002-05-10 Andrey Kiselev + + * tools/tiff2ps: New commandline switches to override resolution + units obtained from the input file. Closes + http://bugzilla.remotesensing.org/show_bug.cgi?id=131 + +2002-04-26 Andrey Kiselev + + * libtiff/libtiff.def: Added missed declaration. + +2002-04-22 Andrey Kiselev + + * tools/fax2tiff.c: Updated to reflect latest changes in libtiff. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=125 + +2002-04-20 Andrey Kiselev + + * libtiff/tif_open.c: Pointers to custom procedures + in TIFFClientOpen() are checked to be not NULL-pointers. + +2002-04-18 Andrey Kiselev + + * libtiff/libtiff.def: Added missed declarations. + + * libtiff/tif_pixarlog.c: Updated for using tif_tagmethods structure. + +2002-04-16 Andrey Kiselev + + * libtiff/tif_lzw.c: Additional checks for data integrity introduced. + Should finally close + http://bugzilla.remotesensing.org/show_bug.cgi?id=100 + +2002-04-10 Andrey Kiselev + + * tools/tiff2ps: Division by zero fixed. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=88 + +2002-04-09 Andrey Kiselev + + * libtiff/: tif_dirwrite.c, tif_write.c, tiffio.h: + TIFFCheckpointDirectory() routine added. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=124 + + * man/: TIFFWriteDirectory.3t, Makefile.in: Added description + for the new function. + +2002-04-08 Andrey Kiselev + + * libtiff/: tif_codec.c, tif_compress.c, tiffiop.h: Introduced + additional members tif->tif_decodestatus and tif->tif_encodestatus + for correct handling of unconfigured codecs (we should not try to read + data or to define data size without correct codecs). + + * libtiff/tif_getimage.c: The way of codecs checking in TIFFRGBAImageOK + changed. Now it has used tif->tif_decodestatus and + tif->tif_encodestatus. + Should fix http://bugzilla.remotesensing.org/show_bug.cgi?id=119 (in + case of __cvs_8.tif test image). + + * libtiff/: tif_dirinfo.c, tif_dirread.c: Somebody makes a bug in + tif_dirread.c when TIFFCreateAnonFieldInfo was introduced. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=119 in case + of _cvs_00000-00.tif, _cvs_00000-01.tif and _cvs_00000-02.tif. + +2002-04-04 Andrey Kiselev + + * libtiff/: tif_lzw.c: Assertions in LZWDecode and LZWDecodeCompat + replaced by warnings. Now libtiff should read corrupted LZW-compressed + files by skipping bad strips. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=100 + +2002-04-03 Frank Warmerdam + + * libtiff/tif_dirwrite.c: Removed some dead code. + + * libtiff/*: Cleanup some warnings. + + * libtiff/tif_dir.c: Fixed bug with count returned by TIFFGetField() + for variable length FIELD_CUSTOM values. Was int * but should be + u_short *. + +2002-04-01 Andrey Kiselev + + * tools/: tifcp.c: Added support for 'Orientation' tag in tiffcp + utility (at cpStripToTile routine). + +2002-03-27 Frank Warmerdam + + * tif_dirread.c: avoid div-by-zero if rowbytes is zero in chop func. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=111 + + * tif_print.c: Fixed so that ASCII FIELD_CUSTOM values with + passcount set FALSE can be printed (such as TIFFTAG_SOFTWARE). + + * libtiff/tif_dir.c,tif_dirinfo.c,tif_dir.h,tif_ojpeg.c: modified so + that TIFFTAG_SOFTWARE uses FIELD_CUSTOM as an example. + +2002-03-26 Dwight Kelly + + * libtiff/: tiff.h, tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c, + tif_dirwrite.c: Added get/put code for new tag XMLPACKET as defined + in Adobe XMP Technote. Added missing INKSET tag value from TIFF 6.0 spec + INKSET_MULTIINK (=2). Added missing tags from Adobe TIFF technotes: + CLIPPATH, XCLIPPATHUNITS, YCLIPPATHUNITS, OPIIMAGEID, OPIPROXY and + INDEXED. Added PHOTOMETRIC tag value from TIFF technote 4 ICCLAB (=9). + +2002-03-26 Andrey Kiselev + + * libtiff/: tif_getimage.c: TIFFReadRGBAStrip and TIFFReadRGBATile + now also uses TIFFRGBAImageOK before reading. This is additional fix + for http://bugzilla.remotesensing.org/show_bug.cgi?id=110 + +2002-03-25 Andrey Kiselev + + * libtiff/: tif_getimage.c: Additional check for supported + codecs added in TIFFRGBAImageOK and TIFFReadRGBAImage now uses + TIFFRGBAImageOK before reading. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=110 + +2002-03-15 Andrey Kiselev + + * libtiff/: tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c, + tif_dirwrite.c: Added routine TIFFDataWidth for detrmining + TIFFDataType sizes instead of working with tiffDataWidth array + directly. Should prevent out-of-borders bugs in case of unknown or + broken data types. EstimateStripByteCounts routine modified, so it + won't work when tags with uknown sizes founded. + Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=109 + +2002-03-13 Andrey Kiselev + + * libtiff/tif_getimage.c: Added support for correct handling + `Orientation' tag in gtTileContig. Should be added in other gt* + functions as well, but I have not images for testing yet. Partially + resolves http://bugzilla.remotesensing.org/show_bug.cgi?id=23 + +2002-03-10 Andrey Kiselev + + * libtiff/: tif_dirinfo.c, tif_dirwrite.c: Added possibility to + read broken TIFFs with LONG type used for TIFFTAG_COMPRESSION, + TIFFTAG_BITSPERSAMPLE, TIFFTAG_PHOTOMETRIC. Closes + http://bugzilla.remotesensing.org/show_bug.cgi?id=99 + +2002-03-08 Andrey Kiselev + + * libtiff/Makefile.in, tools/Makefile.in: Shared library will not + be stripped when installing, utility binaries will do. Closes + http://bugzilla.remotesensing.org/show_bug.cgi?id=93 + +2002-02-28 Frank Warmerdam + + * man/TIFFGetField: fixed type of TIFFTAG_COPYRIGHT. + + * man/libtiff.3t: added copyright tag info. + +2002-02-11 Frank Warmerdam + + * libtiff/{tiff.h,tif_fax3.c}: Add support for __arch64__. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=94 + + * man/Makefile.in: Patch DESTDIR handling + + http://bugzilla.remotesensing.org/show_bug.cgi?id=95 + + * configure: OpenBSD changes for Sparc64 and DSO version. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=96 + +2002-02-05 Frank Warmerdam + + * config.site/configure: added support for OJPEG=yes option to enable + OJPEG support from config.site. + +2002-01-27 Frank Warmerdam + + * html/document.html: fixed links for TIFf 6 docs. + +2002-01-18 Frank Warmerdam + + * config.guess, config.sub: Updated from ftp.gnu.org/pub/config. + + * libtiff/tif_read.c: Fixed TIFFReadEncodedStrip() to fail if the + decodestrip function returns anything not greater than zero as per + http://bugzilla.remotesensing.org/show_bug.cgi?id=97 + + * configure: Modify CheckForBigEndian so it can work in a cross + compiled situation. + +2002-01-16 Frank Warmerdam + + * tools/tiffdump.c: include TIFFTAG_JPEGTABLES in tag list. + + * tools/tiffset.c: fix bug in error reporting. + + * tools/tiffcp.c: fix several warnings that show up with -Wall. + +2002-01-04 Frank Warmerdam + + * libtiff/tif_jpeg.c: fixed computation of segment_width for + tiles files to avoid error about it not matching the + cinfo.d.image_width values ("JPEGPreDecode: Improper JPEG strip/tile + size.") for ITIFF files. Apparently the problem was incorporated since + 3.5.5, presumably during the OJPEG/JPEG work recently. + +2001-12-15 Frank Warmerdam + + * configure, libtiff/Makefile.in: Changes for building on MacOS 10.1. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=94 + + * libtiff/tif_getimage.c: If DEFAULT_EXTRASAMPLE_AS_ALPHA is 1 + (defined in tiffconf.h - 1 by default) then the RGBA interface + will assume that a fourth extra sample is ASSOCALPHA if the + EXTRASAMPLE value isn't set for it. This changes the behaviour of + the library, but makes it work better with RGBA files produced by + lots of applications that don't mark the alpha values properly. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=93 + http://bugzilla.remotesensing.org/show_bug.cgi?id=65 + +2001-12-12 Frank Warmerdam + + * libtiff/tif_jpeg.c: allow jpeg data stream sampling values to + override those from tiff directory. This makes this work with + ImageGear generated files. + +2001-12-07 Frank Warmerdam + + * html/Makefile.in: added missing images per bug 92. + + * port/Makefile.in: fixed clean target per bug 92. + +2001-11-28 Frank Warmerdam + + * Reissue 3.5.7 release. + + * libtiff/mkversion.c: Fix output of TIFF_VERSION to be + YYYYMMDD so that it is increasing over time. + + * Makefile.in: Ensure that tiffvers.h is regenerated in the + make release target. + + * Makefile.in: added libtiff/tiffvers.h to the release file list. + +2001-11-23 Frank Warmerdam + + * added html/v3.5.7.html, updated html/index.html. + + * Makefile.in: added contrib/addtiffo/tif_ovrcache.{c,h}. + +2001-11-15 Frank Warmerdam + + * configure: fixed test for -lm. + +2001-11-02 Frank Warmerdam + + * Added PHOTOMETRIC_ITULAB as per bug 90. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=90 + +2001-10-10 Frank Warmerdam + + * libtiff/tiff.h: I have created COMPRESSION_CCITT_T4, + COMPRESSION_CCITT_T6, TIFFTAG_T4OPTIONS and TIFFTAG_T6OPTIONS aliases + in keeping with TIFF 6.0 standard in tiff.h + + http://bugzilla.remotesensing.org/show_bug.cgi?id=83 + +2001-09-26 Frank Warmerdam + + * libtiff/tif_dirwrite.c: added TIFFRewriteDirectory() function. + Updated TIFFWriteDirectory man page to include TIFFRewriteDirectory. + +2001-09-24 Frank Warmerdam + + * libtiff/tif_lzw.c: Avoid MS VC++ 5.0 optimization bug. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=78 + + * libtiff/tif_lzw.c: added dummy LZWSetupEncode() to report an + error about LZW not being available. + + * libtiff/tif_dir.c: propagate failure to initialize compression + back from TIFFSetField() as an error status, so applications can + detect failure. + + * libtiff/tif_dir.c: removed the auto replacement of + COMPRESSION_LZW with COMPRESSION_NONE in _TIFFVSetField(). + + * Removed Makefile, tools/Makefile, port/install.sh, man/Makefile + from CVS as they are all supposed to be auto-generated by configure. + +2001-09-22 Frank Warmerdam + + * libtiff/tif_ojpeg.c: new update from Scott. + +2001-09-09 Frank Warmerdam + + * libtif/tif_fax3.c: Removed #ifdef PURIFY logic, and modified to + always use the "safe" version, even if there is a very slight + cost in performance. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=54 + + * libtiff/Makefile.in: Fixed @DSOSUB_VERSION to be @DSOSUF_VERSION@ + in two places. + + * libtiff/tif_getimage.c: Fixed problem with reading strips or + tiles that don't start on a tile boundary. Fix contributed by + Josep Vallverdu (from HP), and further described in bug 47. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=47 + + * tools/tiff2ps.c: added OJPEG YCbCr to RGB support. + + * libtiff/tif_ojpeg.c: Applied substantial patch from Scott. + +2001-09-06 Frank Warmerdam + + * libtiff/tif_packbits.c: fixed memory overrun error. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=77 + +2001-08-31 Frank Warmerdam + + * libtiff/tif_getimage.c: relax handling of contig case where + there are extra samples that are supposed to be ignored. This + should now work for 8bit greyscale or palletted images. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=75 + +2001-08-28 Frank Warmerdam + + * libtiff/tif_getimage.c: Don't complain for CMYK (separated) + images with more than four samples per pixel. See: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=73 + +2001-08-10 Frank Warmerdam + + * libtiff/tif_getimage.c: Use memmove() instead of TIFFmemcpy() + in TIFFReadRGBATile() to avoid issues in cases of overlapping + buffers. See Bug 69 in Bugzilla. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=69 + + * tools/tiff2rgba.c: fixed getopt() call so that -b works again. + +2001-08-09 Frank Warmerdam + + * libtiff/tiff.h, libtiff/tif_fax3.c: added check for __LP64__ + when checking for 64 bit architectures as per bugzilla bug 67. + +2001-07-27 Frank Warmerdam + + * man/Makefile.in: add TIFFClientOpen link as per debian submitted + bug 66. + +2001-07-20 Frank Warmerdam + + * libtiff/tif_jpeg.c: Define HAVE_BOOLEAN on windows if RPCNDR.H + has been included. + +2001-07-19 Frank Warmerdam + + * libtiff/tif_open.c: Seek back to zero after failed read, + before writing header. + +2001-07-18 Frank Warmerdam + + * libtiff/tif_ojpeg.c: updates from Scott. Handles colors + much better. Now depends on having patched libjpeg as per + patch in contrib/ojpeg/*. + +2001-07-17 Frank Warmerdam + + * */Makefile.in: added DESTDIR support. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=60 + +2001-07-16 Frank Warmerdam + + * configure, libtiff/Makefile.in: applied OpenBSD patches + as per: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=61 + +2001-06-28 Frank Warmerdam + + * libtiff/tif_getimage.c: Fixed so that failure is properly + reported by gtTileContig, gtStripContig, gtTileSeparate and + gtStripSeparate. + + See http://bugzilla.remotesensing.org/show_bug.cgi?id=51 + + * tiffcmp.c: Fixed multi samples per pixel support for ContigCompare. + Updated bug section of tiffcmp.1 to note tiled file issues. + + See http://bugzilla.remotesensing.org/show_bug.cgi?id=53 + +2001-06-22 Frank Warmerdam + + * configure: Changes for DSO generation on AIX provided by + John Marquart . + + * configure, libtiff/Makeifle.in: Modified to build DSOs properly + on Darwin thanks to Robert Krajewski (rpk@alum.mit.edu) and + Keisuke Fujii (fujiik@jlcuxf.kek.jp). + +2001-06-13 Frank Warmerdam + + * tools/tiff2rgba.c: added -n flag to avoid emitting alpha component. + + * man/tiff2rgba.1: new + +2001-05-22 Frank Warmerdam + + * Added tiffset and tif_ojpeg to the dist lists in Makefile.in. + +2001-05-13 Frank Warmerdam + + * libtiff/tools/thumbnail.c: changed default output compression + to packbits from LZW since LZW isn't generally available. + +2001-05-12 Frank Warmerdam + + * libtiff/tif_ojpeg.c: New. + libtiff/tif_jpeg.c, tiffconf.h, tif_getimage.c: changes related + to OJPEG support. + + Scott Marovich supplied OJPEG support. + +2001-05-11 Frank Warmerdam + + * tiff.h: removed, it duplicates libtiff/tiff.h. + +2001-05-08 Frank Warmerdam + + * libtiff/tif_dirinfo.c: moved pixar and copyright flags to + ensure everything is in order. + + * libtiff/libtiff.def: added TIFFCreateDirectory and + TIFFDefaultStripSize as per: + + http://bugzilla.remotesensing.org/show_bug.cgi?id=46 + +2001-05-02 Frank Warmerdam + + * libtiff/tif_dirinfo.c: Modified the TIFF_BYTE definition for + TIFFTAG_PHOTOSHOP to use a writecount of TIFF_VARIABLE2 (-3) to + force use of uint32 counts instead of short counts. + + * libtiff/tif_dirwrite.c: Added support for TIFF_VARIABLE2 in the + case of writing TIFF_BYTE/TIFF_SBYTE fields. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=43 + +2001-05-01 Frank Warmerdam + + * libtiff/tif_dirinfo.c: removed duplicate TIFFTAG_PHOTOSHOP as per + bug report http://bugzilla.remotesensing.org/show_bug.cgi?id=44 + +2001-04-05 Frank Warmerdam + + * tiffio.h: removed C++ style comment. + + * configure: fixed up SCRIPT_SH/SHELL handling. + + * Makefile.in: Fixed SCRIPT_SH/SHELL handling. + + * config.guess: documented more variables as per bug 40. + +2001-04-03 Frank Warmerdam + + * configure, *Makefile.in: Various changes to improve configuration + for HP/UX specifically, and also in general. They include: + - Try to handle /usr/bin/sh instead of /bin/sh where necessary. + - Upgrade to HP/UX 10.x+ compiler, linker and dso options. + - Fixed mmap() test to avoid MMAP_FIXED ... it isn't available on HP + - Use -${MAKEFLAGS} in sub makes from makefiles. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=40 + +2001-04-02 Frank Warmerdam + + * libtiff/tiff.h: Applied hac to try and resolve the problem + with the inttypes.h include file on AIX. + + See http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + + * VERSION: update to 3.5.7 beta in preparation for release. + + * configure/config.site: modified to check if -lm is needed for + MACHDEPLIBS if not supplied by config.site. Needed for Darwin. + + * config.guess: updated wholesale to an FSF version apparently + from 1998 (as opposed to 1994). This is mainly inspired by + providing for MacOS X support. + +2001-03-29 Frank Warmerdam + + * configure, Makefile.in, etc: added support for OPTIMIZER being + set from config.site. + +2001-03-28 Frank Warmerdam + + * fax2ps.c: Helge (libtiff at oldach.net) submitted fix: + + Here's a fix for fax2ps that corrects behaviour for non-Letter paper + sizes. It fixes two problems: + + Without scaling (-S) the fax is now centered on the page size specified + with -H and/or -W. Before, fax2ps was using an obscure and practially + useless algorithm to allocate the image relative to Letter sized paper + which sometime sled to useless whitespace on the paper, while at the + same time cutting of the faxes printable area at the opposite border. + + Second, scaling now preserves aspect ratio, which makes unusual faxes + (in particular short ones) print properly. + + See http://bugzilla.remotesensing.org/show_bug.cgi?id=35 + + * tiff2ps.c/tiff2ps.1: Substantial changes to tiff2ps by + Bruce A. Mallett. See check message for detailed information + on all the changes, including a faster encoder, fixes for level + 2 PostScript, and support for the imagemask operator. + +2001-03-27 Frank Warmerdam + + * libtiff/tiffio.h: Changed "#if LOGLUV_PUBLIC" to + "#ifdef LOGLUV_PUBLIC" so it will work with VisualAge on AIX. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=39 + +2001-03-16 Frank Warmerdam + + * tif_dirinfo.c: moved definition of copyright tag in field list. + Apparently they have to be in sorted order by tag id. + +2001-03-13 Frank Warmerdam + + * tif_getimage.c: Added support for 16bit minisblack/miniswhite + images in RGBA interface. + +2001-03-02 Frank Warmerdam + + * Added TIFFTAG_COPYRIGHT support. + +2001-02-19 Frank Warmerdam + + * Brent Roman contributed updated tiffcp utility (and tiffcp.1) + with support for extracting subimages with the ,n syntax, and also + adding the -b bias removal flag. + +2001-02-16 Frank Warmerdam + + * libtiff/libtiff.def: Brent Roman submitted new version adding + serveral missing entry points. + + * libtiff/tif_dirinfo.c: don't declare tiffFieldInfo static on VMS. + Some sort of weird VMS thing. + + http://bugzilla.remotesensing.org/show_bug.cgi?id=31 + + * tif_luv.c/tiff.h/tiffio.h: + New version of TIFF LogLuv (SGILOG) modules contributed by Greg Ward + (greg@shutterfly.com). He writes: + + 1) I improved the gamut-mapping function in tif_luv.c for imaginary + colors, because some images were being super-saturated on the input + side and this resulted in some strange color shifts in the output. + + 2) I added a psuedotag in tiff.h to control random dithering during + LogLuv encoding. This is turned off by default for 32-bit LogLuv and + on for 24-bit LogLuv output. Dithering improves the average color + accuracy over the image. + + 3) I added a #define for LOG_LUV_PUBLIC, which is enabled by default in + tiffio.h, to expose internal routines for converting between LogLuv and + XYZ coordinates. This is helpful for writing more efficient, + specialized conversion routines, especially for reading LogLuv files. + + Changes applied with minor edits. + +2001-01-23 Frank Warmerdam + + * tif_fax3.c: keep rw_mode flag internal to fax3 state to remember + whether we are encoding or decoding. This is to ensure graceful + recovery if TIFFClientOpen() discovers an attempt to open a compressed + file for "r+" access, and subsequently close it, as it resets the + tif_mode flag to O_RDONLY in this case to avoid writes, confusing the + compressor's concept of whether it is in encode or decode mode. + +2001-01-08 Mike Welles + + * Makefile.in: Now cleaning up after itself after creating the .tar.gz and .zip + +2001-01-07 Frank Warmerdam + + * html/libtiff.html: Fixed arguments in example for TIFFRGBAImageGet() + as per bug report by Patrick Connor. + +2000-12-28 Frank Warmerdam + + * Added RELEASE-DATE file to release file list. + + * Fixed libtiff/makefile.vc to make tiffvers.h not version.h. + +2000-12-22 Mike Welles + * added link to CVS mirror from index.html + + * updated html/internals.html to note that LZW compression is + not supported by default. + +2000-12-22 Frank Warmerdam + + * updated html/libtiff.html to not point at Niles' old JPL web site + for the man pages, point at www.libtiff.org. + +2000-12-21 Frank Warmerdam + + * libtiff/tif_apple.c: Applied "Carbon" support patches supplied by + Leonard Rosenthol . May interfere + with correct building on older systems. If so, please let me know. + +2000-12-19 Mike Welles + + * Took out LZW Encoding from tif_lzw.c + + * Created HOWTO-RELEASE + + * Created html/v3.5.6.html + + * updated index.html + +2000-12-01 Frank Warmerdam + + * Added patches for EOFB support in tif_fax3.c and tif_fax3.h. + Patches supplied by Frank Cringle + Example file at: ftp://ftp.remotesensing.org/pub/libtiff/eofb_396.tif + +2000-11-24 Frank Warmerdam + + * libtiff/Makefile.in: Added an installPrivateHdrs and install-private + target so that the private headers required by libgeotiff can be + installed with the others. They are not installed by default. + + * libtiff/Makefile.in: Added @MACHLIBDEPS@ to LINUXdso and GNULDdso + targets so libtiff.so will be built with an explicit dependency + on libm.so. + + * libtiff/Makefile.in: Use softlinks to link libtiff.so.3 to + libtiff.so.3.5.5. + + * libtiff/Makefile.in & configure: Remove all references to the ALPHA + file, or ALPHA version logic. Added stuff about DIST_POINT in + place of DIST_TYPE and the alpha release number stuff. + +2000-11-22 Frank Warmerdam + + * I have applied a patch from Steffen Moeller to + the configure script so that it now accepts the --prefix, and + --exec-prefix directives. + +2000-11-13 Frank Warmerdam + + * I have made a variety of modifications in an effort to ensure the + TIFFLIB_VERSION macro is automatically generated from the RELEASE-DATE + file which seems to be updated regularly. + + o mkversion.c now reads RELEASE-DATE and emits TIFFLIB_VERSION in + version include file. + o renamed version.h to tiffvers.h because we now have to install it + with the public libtiff include files. + o include tiffvers.h in tiffio.h. + o updated tif_version.c to use tiffvers.h. + o Updated Makefile.in accordingly. + + * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=25 + I have updated the win32 detection rules in tiffcomp.h. + +2000-10-20 Frank Warmerdam + + * tif_getimage.c: Fixed RGBA translation for YCbCr images for which + the strip/tile width and height aren't multiples of the sampling size. + See http://bugzilla.remotesensing.org/show_bug.cgi?id=20 + Some patches from Rick LaMont of Dot C Software. + + * Modified tif_packbits.c encoder to avoid compressing more + data than provided if rowsize doesn't factor into provided data + (such as occurs for YCbCr). + +2000-10-19 Frank Warmerdam + + * tools/rgb2ycbcr.c: fixed output strip size to account for vertical + roundup if rows_per_strip not a multiple of vertical sample size. + +2000-10-16 Frank Warmerdam + + * tif_dir.c: Clear TIFF_ISTILED flag in TIFFDefaultDirectory + as per http://bugzilla.remotesensing.org/show_bug.cgi?id=18 + from vandrove@vc.cvut.cz. + + * Modified tif_packbits.c decoding to avoid overrunning the + output buffer, and to issue a warning if data needs to be + discarded. See http://bugzilla.remotesensing.org/show_bug.cgi?id=18 + +2000-10-12 Frank Warmerdam + + * Modified tiff2bw to ensure portions add to 100%, and that + white is properly recovered. + + See bug http://bugzilla.remotesensing.org/show_bug.cgi?id=15 + Patch c/o Stanislav Brabec + +2000-09-30 Frank Warmerdam + + * Modified TIFFClientOpen() to emit an error on an attempt to + open a comperessed file for update (O_RDWR/r+) access. This is + because the compressor/decompressor code gets very confused when + the mode is O_RDWR, assuming this means writing only. See + bug http://bugzilla.remotesensing.org/show_bug.cgi?id=13 + +2000-09-27 Frank Warmerdam + + * Added GNULDdso target an`d switched linux and freebsd to use it. + +2000-09-26 Frank Warmerdam + + * Applied patch for 0x0000 sequences in tif_fax3.h's definition + of EXPAND1D() as per bug 11 (from Roman). + +2000-09-25 Frank Warmerdam + * Fixed tiffcomp.h to avoid win32 stuff if unix #defined, to improve + cygwin compatibility. + + * Applied patch from Roman Shpount to tif_fax3.c. This seems to + be a proper fix to the buffer sizing problem. See + http://bugzilla.remotesensing.org/show_bug.cgi?id=11 + + * Fixed tif_getimage.c to fix overrun bug with YCbCr images without + downsampling. http://bugzilla.remotesensing.org/show_bug.cgi?id=10 + Thanks to Nick Lamb for reporting the + bug and proving the patch. + +2000-09-18 Frank Warmerdam + + * Fixed tif_jpeg.c so avoid destroying the decompressor before + we are done access data thanks to bug report from: + Michael Eckstein . + + * Reverted tif_flush change. + +2000-09-14 Frank Warmerdam + + * tif_flush.c: Changed so that TIFFFlushData() doesn't return an + error when TIFF_BEENWRITING is not set. This ensures that the + directory contents can still be flushed by TIFFFlush(). + +2000-08-14 Frank Warmerdam + + * tif_open.c: Don't set MMAP for O_RDWR files. + + * tif_open.c: Set STRIPCHOP_DEFAULT for O_RDWR as well as O_RDONLY + so that files opened for update can be strip chopped too. + + * tif_read.c: fixed up bug with files missing rowsperstrip and + the strips per separation fix done a few weeks ago. + +2000-07-17 Frank Warmerdam + + * Tentatively added support for SAMPLEFORMAT_COMPLEXIEEEFP, and + SAMPLEFORMAT_COMPLEXINT. + +2000-07-13 Mike Welles + + * index.html, bugs.html: added bugzilla info. + +2000-07-12 Frank Warmerdam + + * tif_read.c: fix subtle bug with determining the number of + rows for strips that are the last strip in a separation but + not the last strip of all in TIFFReadEncodedStrip(). + + * Applied 16/32 bit fix to tif_fax3.c. Fix supplied by + Peter Skarpetis + +2000-06-15 Frank Warmerdam + + * Modified tiffio.h logic with regard to including windows.h. It + won't include it when building with __CYGWIN__. + +2000-05-11 Frank Warmerdam + + * README: update to mention www.libtiff.org, don't list Sam's old + email address. + + * configure: Fixed DSO test for Linux as per patch from + Jan Van Buggenhout . + +2000-04-21 Frank Warmerdam + + * libtiff/tif_dirread.c: Don't use estimate strip byte count for + one tile/strip images with an offset, and byte count of zero. These + could be "unpopulated" images. + +2000-04-18 Frank Warmerdam + + * contrib/addtiffo: Added "averaging" resampling option. + + * tools/tiffsplit.c: Copy TIFFTAG_SAMPLEFORMAT. + +Tue Apr 18 16:18:08 2000 Frank Warmerdam + + * tools/Makefile.in: Modified to install properly on SGI. + +2000-04-12 Mike Welles + * configure: Fixed stupid mistake in libc6 test on Linux + +2000-04-04 Mike Welles + * tif_win32.c: Applied patch to fix overreads and ovverwrites + caught by BoundsChecker. From Arvan Pritchard + (untested). + + * tif_getimage.c: Applied patch to silence VC6 warnings. From + Arvan Pritchard + + * tif_lzw.c: Applied patch to silence VC6 warnings. From + Arvan Pritchard + +2000-03-28 Frank Warmerdam + + * Added contrib/stream (stream io) code submitted by Avi Bleiweiss. + +2000-03-28 Frank Warmerdam *** 3.5.5 release *** + + * fax2ps: Fixed mixup of width and height in bounding box statement + as per submission by Nalin Dahyabhai . + +2000-03-27 Mike Welles + + * fax2ps: Modified printruns to take uint32 instead of uint16. + Patch courtesy of Bernt Herd + +2000-03-20 Mike Welles + + * configure: added test for libc6 for linux targets. Bug reported by + Stanislav Brabec + + * Added 3.5 docs to html/Makefile.in. + Thanks to Stanislav Brabec + + * configure: fixed bugs in sed scripts + (applied sed script s:/@:s;@:;s:/s;;:;: to configure). + fix submitted to Stanislav Brabec + + * tools/iptcutil was not in files list, and wasn't being + added to tar archive. Updated Makefile.in. + +2000-03-17 Frank Warmerdam + + * tif_fax3.c: Fixed serious bug introduced during the uint16->uint32 + conversion for the run arrays. + +2000-03-03 Frank Warmerdam + + * Set td_sampleformat default to SAMPLEFORMAT_UINT instead of + SAMPLEFORMAT_VOID in TIFFDefaultDirectory() in tif_dir.c. + +2000-03-02 Frank Warmerdam + + * Added "GetDefaulted" support for TIFFTAG_SAMPLEFORMAT in tif_aux.c. + + * Patched tif_fax3.c so that dsp->runs is allocated a bit bigger + to avoid overruns encountered with frle_bug.tif. + +Tue Feb 15 22:01:05 2000 Frank Warmerdam + + * Fixed tools/tiffcmp so that stopondiff testing works. + Patch care of Joseph Orost . + +2000-01-28 + + * Modified tif_unix.c to support 2-4GB seeks if USE_64BIT_API is + set to 1, and added default (off) setting in tiffconf.h. This + should eventually be set by the configure script somehow. + + The original work on all these 2-4GB changes was done by + Peter Smith (psmith@creo.com). + + * Modified tif_win32.c to support 2-4GB seeks. + + * tentatively changed toff_t to be unsigned instead of signed to + facilitate support for 2-4GB files. + + * Updated a variety of files to use toff_t. Fixed some mixups + between toff_t and tsize_t. + +Fri Jan 28 10:13:49 2000 Frank Warmerdam + + * Largely reimplemented contrib/addtiffo to avoid temp files, + updating the TIFF file in place. Fixed a few other bugs to. + + * Set tif_rawdatasize to zero when freeing raw data buffer in + TIFFWriteDirectory(). + + * Enabled "REWRITE_HACK" in tif_write.c by default. + + * Fix bug in tif_write.c when switching between reading one directory + and writing to another. + + * Made TIFFWriteCheck() public, and added TIFFCreateDirectory() + +Wed Jan 5 12:37:48 2000 Frank Warmerdam + + * Added TIFFmemory(3t) functions to libtiff.def. + +Tue Jan 4 13:39:00 2000 Frank Warmerdam + + * Added libtiff/libtiff.def to TIFFILES distribution list. + +Mon Dec 27 12:13:39 EST 1999 Mike Welles + + * Created lzw compression kit, as a new module (libtiff-lzw-compression-kit). + + * Altered descriptions in tools to reflect "by default" lzw not supported + + * Updated index.html to note lzw compression kit. + +Tue Dec 21 14:01:51 1999 Frank Warmerdam + + * Added fax3sm_winnt.c to distribution list in Makefile.in. + +Tue Dec 21 11:04:45 EST 1999 Mike Welles *** 3.5.4 release *** + + * Aadded Pixar tag support. Contributed by Phil Beffery + + * Made one more change to tif_dir.c for removal of LZW compression. Also added notice + when LZW compression invoked. + + * Changed default compression in tools to TIFF_PACKBITS, and changed usage descriptions + in tools to reflect removal of LZW compression + +Mon Dec 20 18:39:02 EST 1999 Mike Welles + + * Fixed bug that caused LZW (non) compression to segfault. Added + warning about LZW compression removed being removed, and why. + + * Added nostrip to install in tools/Makefile.in so that debugging + symbols are kept. + +Tue Dec 7 12:04:47 EST 1999 Mike Welles + + * Added patch from Ivo Penzar , + supporting Adobe ZIP deflate. Untested. + +Sat Dec 4 15:47:11 1999 Frank Warmerdam + + * Made Packbits the default compression in tools/tiff2rgba.c instead + of LZW. + +Tue Nov 30 14:41:43 1999 Frank Warmerdam *** 3.5.3. release *** + + * Added tif_luv to contrib/djgpp/Makefile.lib. + +Tue Nov 30 14:15:32 EST 1999 Mike Welles + + * Added zip creation to relase makefile target + + * Added html for TIFFWriteTile.3t man page. + +Tue Nov 30 09:20:16 1999 Frank Warmerdam + + * Added some changes to tif_write.c to support rewriting existing + fixed sized tiles and strips. Code mods disabled by default, only + enabled if REWRITE_HACK is defined for now. + +Mon Nov 29 11:43:42 1999 Frank Warmerdam + + * Added TIFFWriteTile.3t man page. + +Sun Nov 28 20:36:18 1999 Frank Warmerdam + + * Added notes on use of makefile.vc in build.html, and fixed + email subscription address. + +199-11-28 Mike Welles + + * Fixed apocalypse-inducing y2k bug in contrib/ras/ras2tiff.c + + * Did some casts cleaning up to reduce compiler warnings in tif_fax3.c, + from Bruce Carmeron -- modifications of + changes made by Frank (sun cc still complained on cast). + + * Added tiffconf.h to install target per request from Bill + Radcliffe : "We need a way for ImageMagick to + know features have been compiled into the TIFF library in order to + handle things properly". + +Sat Nov 27 16:49:21 1999 Frank Warmerdam + + * fixed various VC++ warnings as suggested by Gilles Vollant + . + +Wed Nov 24 12:08:16 1999 Frank Warmerdam + + * Modified TIFFquery.3t man pages info on TIFFIsByteSwapped() to + not imply applications are responsible for image data swapping. + +1999-11-22 Mike Welles + * HTML-ized the man pages, added to html/man + + * Removed LZW Compression to comply with Unisys patent extortion. + +1999-09-29 Mike Welles + * Corrected one remaining 16 -> 32 bit value in tif_fax3.c, + From Ivo Penzar + +1999-09-26 Mike Welles *** 3.5.2 release *** + * Corrected alpha versioning. + + * Removed distinction between alpha and release targets in Makefile.in. + + * added release.stamp target, which tags cvs tree, and updates + "RELEASE-DATE" + + * added releasediff target, which diffs tree with source as of + date in "RELEASE-DATE" + + * Ticked up version to 3.5.2 (alpha 01 -- but I think we'll moving + away from alpha/non-alpha distinctions). + + * updated html to reflect release + +1999-09-23 + + * Set O_BINARY for tif_unix.c open() ... used on cygwin for instance. + + * Added CYGWIN case in configure. + +Fri Sep 17 00:13:51 CEST 1999 Mike Welles + + * Applied Francois Dagand's patch to handle fax decompression bug. + (sizes >= 65536 were failing) + +Tue Sep 14 21:31:43 1999 Frank Warmerdam + + * Applied "a" mode fix to tif_win32.c/TIFFOpen() as suggested + by Christopher Lawton + +Wed Sep 8 08:19:18 1999 Frank Warmerdam + + * Added IRIX/gcc, and OSF/1 4.x support on behalf of + Albert Chin-A-Young + + * Added TIFFReassignTagToIgnore() API on behalf of + Bruce Cameron . Man page still pending. + +Wed Aug 25 11:39:07 1999 Frank Warmerdam + + * Added test target in Makefile, test_pics.sh script and pics/*.rpt + files to provide for a rudimentary testsuite. + + * Added contrib/tags back from old distribution ... fixed up a bit. + +1999-08-16 + + * Added simple makefile.vc makefiles for building with MS VC++ + on Windows NT/98/95 in console mode. Stuff in contrib/win* make give + better solutions for some users. + +Mon Aug 16 21:52:11 1999 Frank Warmerdam + + * Added addtiffo (add overviews to a TIFF file) in contrib. Didn't + put it in tools since part of it is in C++. + +1999-08-16 Michael L. Welles + + * Updated html/index.html with anon CVS instructions. + +Mon Aug 16 13:18:41 1999 Frank Warmerdam + + * pre-remove so link before softlink in LINUXdso action in + libtiff/Makefile.in to avoid failure on LINUXdso builds other than + the first. + + * Fixed problem with cvtcmap() in tif_getimage.c modifying the + colormaps owned by the TIFF handle itself when trying to fixup wrong + (eight bit) colormaps. Corrected by maintaining a private copy of + the colormap. + + * Added TIFFReadRGBATile()/TIFFReadRGBAStrip() support in + tif_getimage.c. + + * CVS Repository placed at remotesensing.org. ChangeLog added. diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/libtiff.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/libtiff.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/libtiff.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/libtiff.pro 2013-05-05 17:26:26.000000000 +0000 @@ -0,0 +1,17 @@ + + +TEMPLATE = lib +TARGET = tiff + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.c + + +INCLUDEPATH += ../zlib + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/t4.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/t4.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/t4.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/t4.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,292 @@ +/* $Id: t4.h,v 1.3 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _T4_ +#define _T4_ +/* + * CCITT T.4 1D Huffman runlength codes and + * related definitions. Given the small sizes + * of these tables it does not seem + * worthwhile to make code & length 8 bits. + */ +typedef struct tableentry { + unsigned short length; /* bit length of g3 code */ + unsigned short code; /* g3 code */ + short runlen; /* run length in bits */ +} tableentry; + +#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ + +/* status values returned instead of a run length */ +#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ +#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ +#define G3CODE_EOF -3 /* end of input data */ +#define G3CODE_INCOMP -4 /* incomplete run code */ + +/* + * Note that these tables are ordered such that the + * index into the table is known to be either the + * run length, or (run length / 64) + a fixed offset. + * + * NB: The G3CODE_INVALID entries are only used + * during state generation (see mkg3states.c). + */ +#ifdef G3CODES +const tableentry TIFFFaxWhiteCodes[] = { + { 8, 0x35, 0 }, /* 0011 0101 */ + { 6, 0x7, 1 }, /* 0001 11 */ + { 4, 0x7, 2 }, /* 0111 */ + { 4, 0x8, 3 }, /* 1000 */ + { 4, 0xB, 4 }, /* 1011 */ + { 4, 0xC, 5 }, /* 1100 */ + { 4, 0xE, 6 }, /* 1110 */ + { 4, 0xF, 7 }, /* 1111 */ + { 5, 0x13, 8 }, /* 1001 1 */ + { 5, 0x14, 9 }, /* 1010 0 */ + { 5, 0x7, 10 }, /* 0011 1 */ + { 5, 0x8, 11 }, /* 0100 0 */ + { 6, 0x8, 12 }, /* 0010 00 */ + { 6, 0x3, 13 }, /* 0000 11 */ + { 6, 0x34, 14 }, /* 1101 00 */ + { 6, 0x35, 15 }, /* 1101 01 */ + { 6, 0x2A, 16 }, /* 1010 10 */ + { 6, 0x2B, 17 }, /* 1010 11 */ + { 7, 0x27, 18 }, /* 0100 111 */ + { 7, 0xC, 19 }, /* 0001 100 */ + { 7, 0x8, 20 }, /* 0001 000 */ + { 7, 0x17, 21 }, /* 0010 111 */ + { 7, 0x3, 22 }, /* 0000 011 */ + { 7, 0x4, 23 }, /* 0000 100 */ + { 7, 0x28, 24 }, /* 0101 000 */ + { 7, 0x2B, 25 }, /* 0101 011 */ + { 7, 0x13, 26 }, /* 0010 011 */ + { 7, 0x24, 27 }, /* 0100 100 */ + { 7, 0x18, 28 }, /* 0011 000 */ + { 8, 0x2, 29 }, /* 0000 0010 */ + { 8, 0x3, 30 }, /* 0000 0011 */ + { 8, 0x1A, 31 }, /* 0001 1010 */ + { 8, 0x1B, 32 }, /* 0001 1011 */ + { 8, 0x12, 33 }, /* 0001 0010 */ + { 8, 0x13, 34 }, /* 0001 0011 */ + { 8, 0x14, 35 }, /* 0001 0100 */ + { 8, 0x15, 36 }, /* 0001 0101 */ + { 8, 0x16, 37 }, /* 0001 0110 */ + { 8, 0x17, 38 }, /* 0001 0111 */ + { 8, 0x28, 39 }, /* 0010 1000 */ + { 8, 0x29, 40 }, /* 0010 1001 */ + { 8, 0x2A, 41 }, /* 0010 1010 */ + { 8, 0x2B, 42 }, /* 0010 1011 */ + { 8, 0x2C, 43 }, /* 0010 1100 */ + { 8, 0x2D, 44 }, /* 0010 1101 */ + { 8, 0x4, 45 }, /* 0000 0100 */ + { 8, 0x5, 46 }, /* 0000 0101 */ + { 8, 0xA, 47 }, /* 0000 1010 */ + { 8, 0xB, 48 }, /* 0000 1011 */ + { 8, 0x52, 49 }, /* 0101 0010 */ + { 8, 0x53, 50 }, /* 0101 0011 */ + { 8, 0x54, 51 }, /* 0101 0100 */ + { 8, 0x55, 52 }, /* 0101 0101 */ + { 8, 0x24, 53 }, /* 0010 0100 */ + { 8, 0x25, 54 }, /* 0010 0101 */ + { 8, 0x58, 55 }, /* 0101 1000 */ + { 8, 0x59, 56 }, /* 0101 1001 */ + { 8, 0x5A, 57 }, /* 0101 1010 */ + { 8, 0x5B, 58 }, /* 0101 1011 */ + { 8, 0x4A, 59 }, /* 0100 1010 */ + { 8, 0x4B, 60 }, /* 0100 1011 */ + { 8, 0x32, 61 }, /* 0011 0010 */ + { 8, 0x33, 62 }, /* 0011 0011 */ + { 8, 0x34, 63 }, /* 0011 0100 */ + { 5, 0x1B, 64 }, /* 1101 1 */ + { 5, 0x12, 128 }, /* 1001 0 */ + { 6, 0x17, 192 }, /* 0101 11 */ + { 7, 0x37, 256 }, /* 0110 111 */ + { 8, 0x36, 320 }, /* 0011 0110 */ + { 8, 0x37, 384 }, /* 0011 0111 */ + { 8, 0x64, 448 }, /* 0110 0100 */ + { 8, 0x65, 512 }, /* 0110 0101 */ + { 8, 0x68, 576 }, /* 0110 1000 */ + { 8, 0x67, 640 }, /* 0110 0111 */ + { 9, 0xCC, 704 }, /* 0110 0110 0 */ + { 9, 0xCD, 768 }, /* 0110 0110 1 */ + { 9, 0xD2, 832 }, /* 0110 1001 0 */ + { 9, 0xD3, 896 }, /* 0110 1001 1 */ + { 9, 0xD4, 960 }, /* 0110 1010 0 */ + { 9, 0xD5, 1024 }, /* 0110 1010 1 */ + { 9, 0xD6, 1088 }, /* 0110 1011 0 */ + { 9, 0xD7, 1152 }, /* 0110 1011 1 */ + { 9, 0xD8, 1216 }, /* 0110 1100 0 */ + { 9, 0xD9, 1280 }, /* 0110 1100 1 */ + { 9, 0xDA, 1344 }, /* 0110 1101 0 */ + { 9, 0xDB, 1408 }, /* 0110 1101 1 */ + { 9, 0x98, 1472 }, /* 0100 1100 0 */ + { 9, 0x99, 1536 }, /* 0100 1100 1 */ + { 9, 0x9A, 1600 }, /* 0100 1101 0 */ + { 6, 0x18, 1664 }, /* 0110 00 */ + { 9, 0x9B, 1728 }, /* 0100 1101 1 */ + { 11, 0x8, 1792 }, /* 0000 0001 000 */ + { 11, 0xC, 1856 }, /* 0000 0001 100 */ + { 11, 0xD, 1920 }, /* 0000 0001 101 */ + { 12, 0x12, 1984 }, /* 0000 0001 0010 */ + { 12, 0x13, 2048 }, /* 0000 0001 0011 */ + { 12, 0x14, 2112 }, /* 0000 0001 0100 */ + { 12, 0x15, 2176 }, /* 0000 0001 0101 */ + { 12, 0x16, 2240 }, /* 0000 0001 0110 */ + { 12, 0x17, 2304 }, /* 0000 0001 0111 */ + { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ + { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ + { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ + { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ + { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ + { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ + { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ + { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ + { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ +}; + +const tableentry TIFFFaxBlackCodes[] = { + { 10, 0x37, 0 }, /* 0000 1101 11 */ + { 3, 0x2, 1 }, /* 010 */ + { 2, 0x3, 2 }, /* 11 */ + { 2, 0x2, 3 }, /* 10 */ + { 3, 0x3, 4 }, /* 011 */ + { 4, 0x3, 5 }, /* 0011 */ + { 4, 0x2, 6 }, /* 0010 */ + { 5, 0x3, 7 }, /* 0001 1 */ + { 6, 0x5, 8 }, /* 0001 01 */ + { 6, 0x4, 9 }, /* 0001 00 */ + { 7, 0x4, 10 }, /* 0000 100 */ + { 7, 0x5, 11 }, /* 0000 101 */ + { 7, 0x7, 12 }, /* 0000 111 */ + { 8, 0x4, 13 }, /* 0000 0100 */ + { 8, 0x7, 14 }, /* 0000 0111 */ + { 9, 0x18, 15 }, /* 0000 1100 0 */ + { 10, 0x17, 16 }, /* 0000 0101 11 */ + { 10, 0x18, 17 }, /* 0000 0110 00 */ + { 10, 0x8, 18 }, /* 0000 0010 00 */ + { 11, 0x67, 19 }, /* 0000 1100 111 */ + { 11, 0x68, 20 }, /* 0000 1101 000 */ + { 11, 0x6C, 21 }, /* 0000 1101 100 */ + { 11, 0x37, 22 }, /* 0000 0110 111 */ + { 11, 0x28, 23 }, /* 0000 0101 000 */ + { 11, 0x17, 24 }, /* 0000 0010 111 */ + { 11, 0x18, 25 }, /* 0000 0011 000 */ + { 12, 0xCA, 26 }, /* 0000 1100 1010 */ + { 12, 0xCB, 27 }, /* 0000 1100 1011 */ + { 12, 0xCC, 28 }, /* 0000 1100 1100 */ + { 12, 0xCD, 29 }, /* 0000 1100 1101 */ + { 12, 0x68, 30 }, /* 0000 0110 1000 */ + { 12, 0x69, 31 }, /* 0000 0110 1001 */ + { 12, 0x6A, 32 }, /* 0000 0110 1010 */ + { 12, 0x6B, 33 }, /* 0000 0110 1011 */ + { 12, 0xD2, 34 }, /* 0000 1101 0010 */ + { 12, 0xD3, 35 }, /* 0000 1101 0011 */ + { 12, 0xD4, 36 }, /* 0000 1101 0100 */ + { 12, 0xD5, 37 }, /* 0000 1101 0101 */ + { 12, 0xD6, 38 }, /* 0000 1101 0110 */ + { 12, 0xD7, 39 }, /* 0000 1101 0111 */ + { 12, 0x6C, 40 }, /* 0000 0110 1100 */ + { 12, 0x6D, 41 }, /* 0000 0110 1101 */ + { 12, 0xDA, 42 }, /* 0000 1101 1010 */ + { 12, 0xDB, 43 }, /* 0000 1101 1011 */ + { 12, 0x54, 44 }, /* 0000 0101 0100 */ + { 12, 0x55, 45 }, /* 0000 0101 0101 */ + { 12, 0x56, 46 }, /* 0000 0101 0110 */ + { 12, 0x57, 47 }, /* 0000 0101 0111 */ + { 12, 0x64, 48 }, /* 0000 0110 0100 */ + { 12, 0x65, 49 }, /* 0000 0110 0101 */ + { 12, 0x52, 50 }, /* 0000 0101 0010 */ + { 12, 0x53, 51 }, /* 0000 0101 0011 */ + { 12, 0x24, 52 }, /* 0000 0010 0100 */ + { 12, 0x37, 53 }, /* 0000 0011 0111 */ + { 12, 0x38, 54 }, /* 0000 0011 1000 */ + { 12, 0x27, 55 }, /* 0000 0010 0111 */ + { 12, 0x28, 56 }, /* 0000 0010 1000 */ + { 12, 0x58, 57 }, /* 0000 0101 1000 */ + { 12, 0x59, 58 }, /* 0000 0101 1001 */ + { 12, 0x2B, 59 }, /* 0000 0010 1011 */ + { 12, 0x2C, 60 }, /* 0000 0010 1100 */ + { 12, 0x5A, 61 }, /* 0000 0101 1010 */ + { 12, 0x66, 62 }, /* 0000 0110 0110 */ + { 12, 0x67, 63 }, /* 0000 0110 0111 */ + { 10, 0xF, 64 }, /* 0000 0011 11 */ + { 12, 0xC8, 128 }, /* 0000 1100 1000 */ + { 12, 0xC9, 192 }, /* 0000 1100 1001 */ + { 12, 0x5B, 256 }, /* 0000 0101 1011 */ + { 12, 0x33, 320 }, /* 0000 0011 0011 */ + { 12, 0x34, 384 }, /* 0000 0011 0100 */ + { 12, 0x35, 448 }, /* 0000 0011 0101 */ + { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */ + { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */ + { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */ + { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */ + { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */ + { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */ + { 13, 0x72, 896 }, /* 0000 0011 1001 0 */ + { 13, 0x73, 960 }, /* 0000 0011 1001 1 */ + { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */ + { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */ + { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */ + { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */ + { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */ + { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */ + { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */ + { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */ + { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */ + { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */ + { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */ + { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */ + { 11, 0x8, 1792 }, /* 0000 0001 000 */ + { 11, 0xC, 1856 }, /* 0000 0001 100 */ + { 11, 0xD, 1920 }, /* 0000 0001 101 */ + { 12, 0x12, 1984 }, /* 0000 0001 0010 */ + { 12, 0x13, 2048 }, /* 0000 0001 0011 */ + { 12, 0x14, 2112 }, /* 0000 0001 0100 */ + { 12, 0x15, 2176 }, /* 0000 0001 0101 */ + { 12, 0x16, 2240 }, /* 0000 0001 0110 */ + { 12, 0x17, 2304 }, /* 0000 0001 0111 */ + { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ + { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ + { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ + { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ + { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ + { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ + { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ + { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ + { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ +}; +#else +extern const tableentry TIFFFaxWhiteCodes[]; +extern const tableentry TIFFFaxBlackCodes[]; +#endif +#endif /* _T4_ */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_aux.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_aux.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_aux.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_aux.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,358 @@ +/* $Id: tif_aux.c,v 1.26 2010-07-01 15:33:28 dron Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Auxiliary Support Routines. + */ +#include "tiffiop.h" +#include "tif_predict.h" +#include + +uint32 +_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where) +{ + uint32 bytes = first * second; + + if (second && bytes / second != first) { + TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); + bytes = 0; + } + + return bytes; +} + +uint64 +_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where) +{ + uint64 bytes = first * second; + + if (second && bytes / second != first) { + TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); + bytes = 0; + } + + return bytes; +} + +void* +_TIFFCheckRealloc(TIFF* tif, void* buffer, + tmsize_t nmemb, tmsize_t elem_size, const char* what) +{ + void* cp = NULL; + tmsize_t bytes = nmemb * elem_size; + + /* + * XXX: Check for integer overflow. + */ + if (nmemb && elem_size && bytes / elem_size == nmemb) + cp = _TIFFrealloc(buffer, bytes); + + if (cp == NULL) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Failed to allocate memory for %s " + "(%ld elements of %ld bytes each)", + what,(long) nmemb, (long) elem_size); + } + + return cp; +} + +void* +_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what) +{ + return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); +} + +static int +TIFFDefaultTransferFunction(TIFFDirectory* td) +{ + uint16 **tf = td->td_transferfunction; + tmsize_t i, n, nbytes; + + tf[0] = tf[1] = tf[2] = 0; + if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) + return 0; + + n = ((tmsize_t)1)<td_bitspersample; + nbytes = n * sizeof (uint16); + if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes))) + return 0; + tf[0][0] = 0; + for (i = 1; i < n; i++) { + double t = (double)i/((double) n-1.); + tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5); + } + + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes))) + goto bad; + _TIFFmemcpy(tf[1], tf[0], nbytes); + if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes))) + goto bad; + _TIFFmemcpy(tf[2], tf[0], nbytes); + } + return 1; + +bad: + if (tf[0]) + _TIFFfree(tf[0]); + if (tf[1]) + _TIFFfree(tf[1]); + if (tf[2]) + _TIFFfree(tf[2]); + tf[0] = tf[1] = tf[2] = 0; + return 0; +} + +static int +TIFFDefaultRefBlackWhite(TIFFDirectory* td) +{ + int i; + + if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float)))) + return 0; + if (td->td_photometric == PHOTOMETRIC_YCBCR) { + /* + * YCbCr (Class Y) images must have the ReferenceBlackWhite + * tag set. Fix the broken images, which lacks that tag. + */ + td->td_refblackwhite[0] = 0.0F; + td->td_refblackwhite[1] = td->td_refblackwhite[3] = + td->td_refblackwhite[5] = 255.0F; + td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; + } else { + /* + * Assume RGB (Class R) + */ + for (i = 0; i < 3; i++) { + td->td_refblackwhite[2*i+0] = 0; + td->td_refblackwhite[2*i+1] = + (float)((1L<td_bitspersample)-1L); + } + } + return 1; +} + +/* + * Like TIFFGetField, but return any default + * value if the tag is not present in the directory. + * + * NB: We use the value in the directory, rather than + * explcit values so that defaults exist only one + * place in the library -- in TIFFDefaultDirectory. + */ +int +TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (TIFFVGetField(tif, tag, ap)) + return (1); + switch (tag) { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32 *) = td->td_subfiletype; + return (1); + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16 *) = td->td_bitspersample; + return (1); + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16 *) = td->td_threshholding; + return (1); + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16 *) = td->td_fillorder; + return (1); + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16 *) = td->td_orientation; + return (1); + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16 *) = td->td_samplesperpixel; + return (1); + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32 *) = td->td_rowsperstrip; + return (1); + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16 *) = td->td_minsamplevalue; + return (1); + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16 *) = td->td_maxsamplevalue; + return (1); + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16 *) = td->td_planarconfig; + return (1); + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16 *) = td->td_resolutionunit; + return (1); + case TIFFTAG_PREDICTOR: + { + TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data; + *va_arg(ap, uint16*) = (uint16) sp->predictor; + return 1; + } + case TIFFTAG_DOTRANGE: + *va_arg(ap, uint16 *) = 0; + *va_arg(ap, uint16 *) = (1<td_bitspersample)-1; + return (1); + case TIFFTAG_INKSET: + *va_arg(ap, uint16 *) = INKSET_CMYK; + return 1; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16 *) = 4; + return (1); + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16 *) = td->td_extrasamples; + *va_arg(ap, uint16 **) = td->td_sampleinfo; + return (1); + case TIFFTAG_MATTEING: + *va_arg(ap, uint16 *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + return (1); + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32 *) = td->td_tiledepth; + return (1); + case TIFFTAG_DATATYPE: + *va_arg(ap, uint16 *) = td->td_sampleformat-1; + return (1); + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16 *) = td->td_sampleformat; + return(1); + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32 *) = td->td_imagedepth; + return (1); + case TIFFTAG_YCBCRCOEFFICIENTS: + { + /* defaults are from CCIR Recommendation 601-1 */ + static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f }; + *va_arg(ap, float **) = ycbcrcoeffs; + return 1; + } + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1]; + return (1); + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16 *) = td->td_ycbcrpositioning; + return (1); + case TIFFTAG_WHITEPOINT: + { + static float whitepoint[2]; + + /* TIFF 6.0 specification tells that it is no default + value for the WhitePoint, but AdobePhotoshop TIFF + Technical Note tells that it should be CIE D50. */ + whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0); + whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0); + *va_arg(ap, float **) = whitepoint; + return 1; + } + case TIFFTAG_TRANSFERFUNCTION: + if (!td->td_transferfunction[0] && + !TIFFDefaultTransferFunction(td)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag"); + return (0); + } + *va_arg(ap, uint16 **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + *va_arg(ap, uint16 **) = td->td_transferfunction[1]; + *va_arg(ap, uint16 **) = td->td_transferfunction[2]; + } + return (1); + case TIFFTAG_REFERENCEBLACKWHITE: + if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td)) + return (0); + *va_arg(ap, float **) = td->td_refblackwhite; + return (1); + } + return 0; +} + +/* + * Like TIFFGetField, but return any default + * value if the tag is not present in the directory. + */ +int +TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...) +{ + int ok; + va_list ap; + + va_start(ap, tag); + ok = TIFFVGetFieldDefaulted(tif, tag, ap); + va_end(ap); + return (ok); +} + +struct _Int64Parts { + int32 low, high; +}; + +typedef union { + struct _Int64Parts part; + int64 value; +} _Int64; + +float +_TIFFUInt64ToFloat(uint64 ui64) +{ + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) { + return (float)i.value; + } else { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (float)df; + } +} + +double +_TIFFUInt64ToDouble(uint64 ui64) +{ + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) { + return (double)i.value; + } else { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (double)df; + } +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_close.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_close.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_close.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_close.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,140 @@ +/* $Id: tif_close.c,v 1.19 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" +#include + +/************************************************************************/ +/* TIFFCleanup() */ +/************************************************************************/ + +/** + * Auxiliary function to free the TIFF structure. Given structure will be + * completetly freed, so you should save opened file handle and pointer + * to the close procedure in external variables before calling + * _TIFFCleanup(), if you will need these ones to close the file. + * + * @param tif A TIFF pointer. + */ + +void +TIFFCleanup(TIFF* tif) +{ + /* + * Flush buffered data and directory (if dirty). + */ + if (tif->tif_mode != O_RDONLY) + TIFFFlush(tif); + (*tif->tif_cleanup)(tif); + TIFFFreeDirectory(tif); + + if (tif->tif_dirlist) + _TIFFfree(tif->tif_dirlist); + + /* + * Clean up client info links. + */ + while( tif->tif_clientinfo ) + { + TIFFClientInfoLink *link = tif->tif_clientinfo; + + tif->tif_clientinfo = link->next; + _TIFFfree( link->name ); + _TIFFfree( link ); + } + + if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER)) + _TIFFfree(tif->tif_rawdata); + if (isMapped(tif)) + TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); + + /* + * Clean up custom fields. + */ + if (tif->tif_fields && tif->tif_nfields > 0) { + uint32 i; + + for (i = 0; i < tif->tif_nfields; i++) { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_bit == FIELD_CUSTOM && + strncmp("Tag ", fld->field_name, 4) == 0) { + _TIFFfree(fld->field_name); + _TIFFfree(fld); + } + } + + _TIFFfree(tif->tif_fields); + } + + if (tif->tif_nfieldscompat > 0) { + uint32 i; + + for (i = 0; i < tif->tif_nfieldscompat; i++) { + if (tif->tif_fieldscompat[i].allocated_size) + _TIFFfree(tif->tif_fieldscompat[i].fields); + } + _TIFFfree(tif->tif_fieldscompat); + } + + _TIFFfree(tif); +} + +/************************************************************************/ +/* TIFFClose() */ +/************************************************************************/ + +/** + * Close a previously opened TIFF file. + * + * TIFFClose closes a file that was previously opened with TIFFOpen(). + * Any buffered data are flushed to the file, including the contents of + * the current directory (if modified); and all resources are reclaimed. + * + * @param tif A TIFF pointer. + */ + +void +TIFFClose(TIFF* tif) +{ + TIFFCloseProc closeproc = tif->tif_closeproc; + thandle_t fd = tif->tif_clientdata; + + TIFFCleanup(tif); + (void) (*closeproc)(fd); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_codec.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_codec.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_codec.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_codec.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,165 @@ +/* $Id: tif_codec.c,v 1.15 2010-12-14 12:53:00 dron Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Builtin Compression Scheme Configuration Support. + */ +#include "tiffiop.h" + +static int NotConfigured(TIFF*, int); + +#ifndef LZW_SUPPORT +#define TIFFInitLZW NotConfigured +#endif +#ifndef PACKBITS_SUPPORT +#define TIFFInitPackBits NotConfigured +#endif +#ifndef THUNDER_SUPPORT +#define TIFFInitThunderScan NotConfigured +#endif +#ifndef NEXT_SUPPORT +#define TIFFInitNeXT NotConfigured +#endif +#ifndef JPEG_SUPPORT +#define TIFFInitJPEG NotConfigured +#endif +#ifndef OJPEG_SUPPORT +#define TIFFInitOJPEG NotConfigured +#endif +#ifndef CCITT_SUPPORT +#define TIFFInitCCITTRLE NotConfigured +#define TIFFInitCCITTRLEW NotConfigured +#define TIFFInitCCITTFax3 NotConfigured +#define TIFFInitCCITTFax4 NotConfigured +#endif +#ifndef JBIG_SUPPORT +#define TIFFInitJBIG NotConfigured +#endif +#ifndef ZIP_SUPPORT +#define TIFFInitZIP NotConfigured +#endif +#ifndef PIXARLOG_SUPPORT +#define TIFFInitPixarLog NotConfigured +#endif +#ifndef LOGLUV_SUPPORT +#define TIFFInitSGILog NotConfigured +#endif +#ifndef LZMA_SUPPORT +#define TIFFInitLZMA NotConfigured +#endif + +/* + * Compression schemes statically built into the library. + */ +#ifdef VMS +const TIFFCodec _TIFFBuiltinCODECS[] = { +#else +TIFFCodec _TIFFBuiltinCODECS[] = { +#endif + { "None", COMPRESSION_NONE, TIFFInitDumpMode }, + { "LZW", COMPRESSION_LZW, TIFFInitLZW }, + { "PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits }, + { "ThunderScan", COMPRESSION_THUNDERSCAN,TIFFInitThunderScan }, + { "NeXT", COMPRESSION_NEXT, TIFFInitNeXT }, + { "JPEG", COMPRESSION_JPEG, TIFFInitJPEG }, + { "Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG }, + { "CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE }, + { "CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW }, + { "CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 }, + { "CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 }, + { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG }, + { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP }, + { "AdobeDeflate", COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, + { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog }, + { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, + { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, + { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA }, + { NULL, 0, NULL } +}; + +static int +_notConfigured(TIFF* tif) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + char compression_code[20]; + + sprintf( compression_code, "%d", tif->tif_dir.td_compression ); + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%s compression support is not configured", + c ? c->name : compression_code ); + return (0); +} + +static int +NotConfigured(TIFF* tif, int scheme) +{ + (void) scheme; + + tif->tif_fixuptags = _notConfigured; + tif->tif_decodestatus = FALSE; + tif->tif_setupdecode = _notConfigured; + tif->tif_encodestatus = FALSE; + tif->tif_setupencode = _notConfigured; + return (1); +} + +/************************************************************************/ +/* TIFFIsCODECConfigured() */ +/************************************************************************/ + +/** + * Check whether we have working codec for the specific coding scheme. + * + * @return returns 1 if the codec is configured and working. Otherwise + * 0 will be returned. + */ + +int +TIFFIsCODECConfigured(uint16 scheme) +{ + const TIFFCodec* codec = TIFFFindCODEC(scheme); + + if(codec == NULL) { + return 0; + } + if(codec->init == NULL) { + return 0; + } + if(codec->init != NotConfigured){ + return 1; + } + return 0; +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_color.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_color.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_color.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_color.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,287 @@ +/* $Id: tif_color.c,v 1.19 2010-12-14 02:22:42 faxguy Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken + * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with + * the permission of John Cupitt, the VIPS author. + */ + +/* + * TIFF Library. + * + * Color space conversion routines. + */ + +#include "tiffiop.h" +#include + +/* + * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. + */ +void +TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, + float *X, float *Y, float *Z) +{ + float L = (float)l * 100.0F / 255.0F; + float cby, tmp; + + if( L < 8.856F ) { + *Y = (L * cielab->Y0) / 903.292F; + cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; + } else { + cby = (L + 16.0F) / 116.0F; + *Y = cielab->Y0 * cby * cby * cby; + } + + tmp = (float)a / 500.0F + cby; + if( tmp < 0.2069F ) + *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; + else + *X = cielab->X0 * tmp * tmp * tmp; + + tmp = cby - (float)b / 200.0F; + if( tmp < 0.2069F ) + *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; + else + *Z = cielab->Z0 * tmp * tmp * tmp; +} + +#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5))) +/* + * Convert color value from the XYZ space to RGB. + */ +void +TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, + uint32 *r, uint32 *g, uint32 *b) +{ + int i; + float Yr, Yg, Yb; + float *matrix = &cielab->display.d_mat[0][0]; + + /* Multiply through the matrix to get luminosity values. */ + Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; + Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; + Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; + + /* Clip input */ + Yr = TIFFmax(Yr, cielab->display.d_Y0R); + Yg = TIFFmax(Yg, cielab->display.d_Y0G); + Yb = TIFFmax(Yb, cielab->display.d_Y0B); + + /* Avoid overflow in case of wrong input values */ + Yr = TIFFmin(Yr, cielab->display.d_YCR); + Yg = TIFFmin(Yg, cielab->display.d_YCG); + Yb = TIFFmin(Yb, cielab->display.d_YCB); + + /* Turn luminosity to colour value. */ + i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); + i = TIFFmin(cielab->range, i); + *r = RINT(cielab->Yr2r[i]); + + i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); + i = TIFFmin(cielab->range, i); + *g = RINT(cielab->Yg2g[i]); + + i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); + i = TIFFmin(cielab->range, i); + *b = RINT(cielab->Yb2b[i]); + + /* Clip output. */ + *r = TIFFmin(*r, cielab->display.d_Vrwr); + *g = TIFFmin(*g, cielab->display.d_Vrwg); + *b = TIFFmin(*b, cielab->display.d_Vrwb); +} +#undef RINT + +/* + * Allocate conversion state structures and make look_up tables for + * the Yr,Yb,Yg <=> r,g,b conversions. + */ +int +TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, + const TIFFDisplay *display, float *refWhite) +{ + int i; + double gamma; + + cielab->range = CIELABTORGB_TABLE_RANGE; + + _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); + + /* Red */ + gamma = 1.0 / cielab->display.d_gammaR ; + cielab->rstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for(i = 0; i <= cielab->range; i++) { + cielab->Yr2r[i] = cielab->display.d_Vrwr + * ((float)pow((double)i / cielab->range, gamma)); + } + + /* Green */ + gamma = 1.0 / cielab->display.d_gammaG ; + cielab->gstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for(i = 0; i <= cielab->range; i++) { + cielab->Yg2g[i] = cielab->display.d_Vrwg + * ((float)pow((double)i / cielab->range, gamma)); + } + + /* Blue */ + gamma = 1.0 / cielab->display.d_gammaB ; + cielab->bstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for(i = 0; i <= cielab->range; i++) { + cielab->Yb2b[i] = cielab->display.d_Vrwb + * ((float)pow((double)i / cielab->range, gamma)); + } + + /* Init reference white point */ + cielab->X0 = refWhite[0]; + cielab->Y0 = refWhite[1]; + cielab->Z0 = refWhite[2]; + + return 0; +} + +/* + * Convert color value from the YCbCr space to CIE XYZ. + * The colorspace conversion algorithm comes from the IJG v5a code; + * see below for more information on how it works. + */ +#define SHIFT 16 +#define FIX(x) ((int32)((x) * (1L<(max)?(max):(f)) +#define HICLAMP(f,max) ((f)>(max)?(max):(f)) + +void +TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, + uint32 *r, uint32 *g, uint32 *b) +{ + int32 i; + + /* XXX: Only 8-bit YCbCr input supported for now */ + Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255); + + i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; + *r = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); + *g = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; + *b = CLAMP(i, 0, 255); +} + +/* + * Initialize the YCbCr->RGB conversion tables. The conversion + * is done according to the 6.0 spec: + * + * R = Y + Cr*(2 - 2*LumaRed) + * B = Y + Cb*(2 - 2*LumaBlue) + * G = Y + * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen + * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen + * + * To avoid floating point arithmetic the fractional constants that + * come out of the equations are represented as fixed point values + * in the range 0...2^16. We also eliminate multiplications by + * pre-calculating possible values indexed by Cb and Cr (this code + * assumes conversion is being done for 8-bit samples). + */ +int +TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) +{ + TIFFRGBValue* clamptab; + int i; + +#define LumaRed luma[0] +#define LumaGreen luma[1] +#define LumaBlue luma[2] + + clamptab = (TIFFRGBValue*)( + (uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))); + _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ + ycbcr->clamptab = (clamptab += 256); + for (i = 0; i < 256; i++) + clamptab[i] = (TIFFRGBValue) i; + _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */ + ycbcr->Cr_r_tab = (int*) (clamptab + 3*256); + ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256; + ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256); + ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; + ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; + + { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1); + float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2); + float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3); + float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4); + int x; + +#undef LumaBlue +#undef LumaGreen +#undef LumaRed + + /* + * i is the actual input pixel value in the range 0..255 + * Cb and Cr values are in the range -128..127 (actually + * they are in a range defined by the ReferenceBlackWhite + * tag) so there is some range shifting to do here when + * constructing tables indexed by the raw pixel data. + */ + for (i = 0, x = -128; i < 256; i++, x++) { + int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F, + refBlackWhite[5] - 128.0F, 127); + int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F, + refBlackWhite[3] - 128.0F, 127); + + ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT); + ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT); + ycbcr->Cr_g_tab[i] = D2*Cr; + ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF; + ycbcr->Y_tab[i] = + (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255); + } + } + + return 0; +} +#undef HICLAMP +#undef CLAMP +#undef Code2V +#undef SHIFT +#undef ONE_HALF +#undef FIX + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_compress.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_compress.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_compress.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_compress.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,304 @@ +/* $Id: tif_compress.c,v 1.22 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Compression Scheme Configuration Support. + */ +#include "tiffiop.h" + +static int +TIFFNoEncode(TIFF* tif, const char* method) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + + if (c) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%s %s encoding is not implemented", + c->name, method); + } else { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Compression scheme %u %s encoding is not implemented", + tif->tif_dir.td_compression, method); + } + return (-1); +} + +int +_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "scanline")); +} + +int +_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "strip")); +} + +int +_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "tile")); +} + +static int +TIFFNoDecode(TIFF* tif, const char* method) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + + if (c) + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%s %s decoding is not implemented", + c->name, method); + else + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Compression scheme %u %s decoding is not implemented", + tif->tif_dir.td_compression, method); + return (-1); +} + +int +_TIFFNoFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +int +_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "scanline")); +} + +int +_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "strip")); +} + +int +_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "tile")); +} + +int +_TIFFNoSeek(TIFF* tif, uint32 off) +{ + (void) off; + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Compression algorithm does not support random access"); + return (0); +} + +int +_TIFFNoPreCode(TIFF* tif, uint16 s) +{ + (void) tif; (void) s; + return (1); +} + +static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } +static void _TIFFvoid(TIFF* tif) { (void) tif; } + +void +_TIFFSetDefaultCompressionState(TIFF* tif) +{ + tif->tif_fixuptags = _TIFFNoFixupTags; + tif->tif_decodestatus = TRUE; + tif->tif_setupdecode = _TIFFtrue; + tif->tif_predecode = _TIFFNoPreCode; + tif->tif_decoderow = _TIFFNoRowDecode; + tif->tif_decodestrip = _TIFFNoStripDecode; + tif->tif_decodetile = _TIFFNoTileDecode; + tif->tif_encodestatus = TRUE; + tif->tif_setupencode = _TIFFtrue; + tif->tif_preencode = _TIFFNoPreCode; + tif->tif_postencode = _TIFFtrue; + tif->tif_encoderow = _TIFFNoRowEncode; + tif->tif_encodestrip = _TIFFNoStripEncode; + tif->tif_encodetile = _TIFFNoTileEncode; + tif->tif_close = _TIFFvoid; + tif->tif_seek = _TIFFNoSeek; + tif->tif_cleanup = _TIFFvoid; + tif->tif_defstripsize = _TIFFDefaultStripSize; + tif->tif_deftilesize = _TIFFDefaultTileSize; + tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW); +} + +int +TIFFSetCompressionScheme(TIFF* tif, int scheme) +{ + const TIFFCodec *c = TIFFFindCODEC((uint16) scheme); + + _TIFFSetDefaultCompressionState(tif); + /* + * Don't treat an unknown compression scheme as an error. + * This permits applications to open files with data that + * the library does not have builtin support for, but which + * may still be meaningful. + */ + return (c ? (*c->init)(tif, scheme) : 1); +} + +/* + * Other compression schemes may be registered. Registered + * schemes can also override the builtin versions provided + * by this library. + */ +typedef struct _codec { + struct _codec* next; + TIFFCodec* info; +} codec_t; +static codec_t* registeredCODECS = NULL; + +const TIFFCodec* +TIFFFindCODEC(uint16 scheme) +{ + const TIFFCodec* c; + codec_t* cd; + + for (cd = registeredCODECS; cd; cd = cd->next) + if (cd->info->scheme == scheme) + return ((const TIFFCodec*) cd->info); + for (c = _TIFFBuiltinCODECS; c->name; c++) + if (c->scheme == scheme) + return (c); + return ((const TIFFCodec*) 0); +} + +TIFFCodec* +TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) +{ + codec_t* cd = (codec_t*) + _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); + + if (cd != NULL) { + cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t)); + cd->info->name = (char*) + ((uint8*) cd->info + sizeof (TIFFCodec)); + strcpy(cd->info->name, name); + cd->info->scheme = scheme; + cd->info->init = init; + cd->next = registeredCODECS; + registeredCODECS = cd; + } else { + TIFFErrorExt(0, "TIFFRegisterCODEC", + "No space to register compression scheme %s", name); + return NULL; + } + return (cd->info); +} + +void +TIFFUnRegisterCODEC(TIFFCodec* c) +{ + codec_t* cd; + codec_t** pcd; + + for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next) + if (cd->info == c) { + *pcd = cd->next; + _TIFFfree(cd); + return; + } + TIFFErrorExt(0, "TIFFUnRegisterCODEC", + "Cannot remove compression scheme %s; not registered", c->name); +} + +/************************************************************************/ +/* TIFFGetConfisuredCODECs() */ +/************************************************************************/ + +/** + * Get list of configured codecs, both built-in and registered by user. + * Caller is responsible to free this structure. + * + * @return returns array of TIFFCodec records (the last record should be NULL) + * or NULL if function failed. + */ + +TIFFCodec* +TIFFGetConfiguredCODECs() +{ + int i = 1; + codec_t *cd; + const TIFFCodec* c; + TIFFCodec* codecs = NULL; + TIFFCodec* new_codecs; + + for (cd = registeredCODECS; cd; cd = cd->next) { + new_codecs = (TIFFCodec *) + _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) { + _TIFFfree (codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec)); + i++; + } + for (c = _TIFFBuiltinCODECS; c->name; c++) { + if (TIFFIsCODECConfigured(c->scheme)) { + new_codecs = (TIFFCodec *) + _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) { + _TIFFfree (codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); + i++; + } + } + + new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) { + _TIFFfree (codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); + + return codecs; +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h 2013-05-05 20:07:12.000000000 +0000 @@ -0,0 +1,175 @@ +/* libtiff/tif_config.h. Generated from tif_config.h.in by configure. */ +/* libtiff/tif_config.h.in. Generated from configure.ac by autoheader. */ + +/* Support CCITT Group 3 & 4 algorithms */ +#define CCITT_SUPPORT 1 + +/* Pick up YCbCr subsampling info from the JPEG data stream to support files + lacking the tag (default enabled). */ +#define CHECK_JPEG_YCBCR_SUBSAMPLING 1 + +/* enable partial strip reading for large strips (experimental) */ +#undef CHUNKY_STRIP_READ_SUPPORT + +/* Treat extra sample as alpha (default enabled). The RGBA interface will + treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many + packages produce RGBA files but don't mark the alpha properly. */ +#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1 + +/* enable deferred strip/tile offset/size loading (experimental) */ +#undef DEFER_STRILE_LOAD + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#define HAVE_IEEEFP 1 + +/* Define to 1 if you have the header file. */ +#ifdef WIN32 +#define HAVE_IO_H +#endif + +/* Define to 1 if you have the `jbg_newlen' function. */ +/* #undef HAVE_JBG_NEWLEN */ + +/* Define to 1 if you have the `mmap' function. */ +/* #undef HAVE_MMAP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SEARCH_H + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_UNISTD_H +/* #undef HAVE_UNISTD_H */ +#endif + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#define HOST_BIGENDIAN 0 + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#define HOST_FILLORDER FILLORDER_LSB2MSB + +/* Support ISO JBIG compression (requires JBIG-KIT library) */ +#undef JBIG_SUPPORT + +/* 8/12 bit libjpeg dual mode enabled */ +/* #undef JPEG_DUAL_MODE_8_12 */ + +/* Support JPEG compression (requires IJG JPEG library) */ +#undef JPEG_SUPPORT + +/* 12bit libjpeg primary include file with path */ +/* #undef LIBJPEG_12_PATH */ + +/* Support LogLuv high dynamic range encoding */ +#define LOGLUV_SUPPORT 1 + +/* Support LZMA2 compression */ +/* #undef LZMA_SUPPORT */ + +/* Support LZW algorithm */ +#define LZW_SUPPORT 1 + +/* Support Microsoft Document Imaging format */ +#define MDI_SUPPORT 1 + +/* Support NeXT 2-bit RLE algorithm */ +#define NEXT_SUPPORT 1 + +/* Support Old JPEG compresson (read-only) */ +#undef OJPEG_SUPPORT + +/* Support Macintosh PackBits algorithm */ +#define PACKBITS_SUPPORT 1 + +/* Support Pixar log-format algorithm (requires Zlib) */ +#define PIXARLOG_SUPPORT 1 + +/* The size of `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 8 + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of specified size to reduce memory usage) */ +#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP + +/* Default size of the strip in bytes (when strip chopping enabled) */ +//#define STRIP_SIZE_DEFAULT 8192 + +/* Support ThunderScan 4-bit RLE algorithm */ +#define THUNDER_SUPPORT 1 + +/* Signed 8-bit type */ +#define TIFF_INT8_T signed char + +/* Signed 16-bit type */ +#define TIFF_INT16_T signed short + +/* Signed 32-bit type */ +#define TIFF_INT32_T signed int + +/* Signed size type */ +#define TIFF_SSIZE_T size_t + +/* Unsigned 8-bit type */ +#define TIFF_UINT8_T unsigned char + +/* Unsigned 16-bit type */ +#define TIFF_UINT16_T unsigned short + +/* Unsigned 32-bit type */ +#define TIFF_UINT32_T unsigned int + +#ifdef _MSC_VER +/* Signed 64-bit type */ +# define TIFF_INT64_T signed __int64 +/* Unsigned 64-bit type */ +# define TIFF_UINT64_T unsigned __int64 +#else +/* Signed 64-bit type */ +# define TIFF_INT64_T long long +/* Signed 64-bit type */ +# define TIFF_UINT64_T unsigned long long +#endif + +/* Signed 64-bit type formatter */ +/* Unsigned 64-bit type formatter */ +#if defined _MSC_VER || defined __MINGW__ || defined __MINGW32__ +# define TIFF_UINT64_FORMAT "%I64u" +# define TIFF_SSIZE_FORMAT "%Iu" +#else +# define TIFF_UINT64_FORMAT "%llu" +# define TIFF_SSIZE_FORMAT "%zd" +#endif + +/* define to use win32 IO system */ +#ifdef WIN32 +#define USE_WIN32_FILEIO +#endif + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Support Deflate compression */ +#define ZIP_SUPPORT 1 + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h.cmakein diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h.cmakein --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h.cmakein 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_config.h.cmakein 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,171 @@ +/* libtiff/tif_config.h. Generated from tif_config.h.in by configure. */ +/* libtiff/tif_config.h.in. Generated from configure.ac by autoheader. */ + +/* Support CCITT Group 3 & 4 algorithms */ +#define CCITT_SUPPORT 1 + +/* Pick up YCbCr subsampling info from the JPEG data stream to support files + lacking the tag (default enabled). */ +#define CHECK_JPEG_YCBCR_SUBSAMPLING 1 + +/* enable partial strip reading for large strips (experimental) */ +#undef CHUNKY_STRIP_READ_SUPPORT + +/* Treat extra sample as alpha (default enabled). The RGBA interface will + treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many + packages produce RGBA files but don't mark the alpha properly. */ +#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1 + +/* enable deferred strip/tile offset/size loading (experimental) */ +#undef DEFER_STRILE_LOAD + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#define HAVE_IEEEFP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IO_H + +/* Define to 1 if you have the `jbg_newlen' function. */ +#cmakedefine HAVE_JBG_NEWLEN + +/* Define to 1 if you have the `mmap' function. */ +#cmakedefine HAVE_MMAP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SEARCH_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_UNISTD_H +#cmakedefine HAVE_UNISTD_H +#endif + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#define HOST_BIGENDIAN 0 + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#define HOST_FILLORDER FILLORDER_LSB2MSB + +/* Support ISO JBIG compression (requires JBIG-KIT library) */ +#undef JBIG_SUPPORT + +/* 8/12 bit libjpeg dual mode enabled */ +/* #undef JPEG_DUAL_MODE_8_12 */ + +/* Support JPEG compression (requires IJG JPEG library) */ +#undef JPEG_SUPPORT + +/* 12bit libjpeg primary include file with path */ +/* #undef LIBJPEG_12_PATH */ + +/* Support LogLuv high dynamic range encoding */ +#define LOGLUV_SUPPORT 1 + +/* Support LZMA2 compression */ +/* #undef LZMA_SUPPORT */ + +/* Support LZW algorithm */ +#define LZW_SUPPORT 1 + +/* Support Microsoft Document Imaging format */ +#define MDI_SUPPORT 1 + +/* Support NeXT 2-bit RLE algorithm */ +#define NEXT_SUPPORT 1 + +/* Support Old JPEG compresson (read-only) */ +#undef OJPEG_SUPPORT + +/* Support Macintosh PackBits algorithm */ +#define PACKBITS_SUPPORT 1 + +/* Support Pixar log-format algorithm (requires Zlib) */ +#define PIXARLOG_SUPPORT 1 + +/* The size of `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 8 + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of specified size to reduce memory usage) */ +#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP + +/* Default size of the strip in bytes (when strip chopping enabled) */ +//#define STRIP_SIZE_DEFAULT 8192 + +/* Support ThunderScan 4-bit RLE algorithm */ +#define THUNDER_SUPPORT 1 + +/* Signed 8-bit type */ +#define TIFF_INT8_T signed char + +/* Signed 16-bit type */ +#define TIFF_INT16_T signed short + +/* Signed 32-bit type */ +#define TIFF_INT32_T signed int + +/* Signed size type */ +#define TIFF_SSIZE_T size_t + +/* Unsigned 8-bit type */ +#define TIFF_UINT8_T unsigned char + +/* Unsigned 16-bit type */ +#define TIFF_UINT16_T unsigned short + +/* Unsigned 32-bit type */ +#define TIFF_UINT32_T unsigned int + +#ifdef _MSC_VER +/* Signed 64-bit type */ +# define TIFF_INT64_T signed __int64 +/* Unsigned 64-bit type */ +# define TIFF_UINT64_T unsigned __int64 +#else +/* Signed 64-bit type */ +# define TIFF_INT64_T long long +/* Signed 64-bit type */ +# define TIFF_UINT64_T unsigned long long +#endif + +/* Signed 64-bit type formatter */ +/* Unsigned 64-bit type formatter */ +#if defined _MSC_VER || defined __MINGW__ || defined __MINGW32__ +# define TIFF_UINT64_FORMAT "%I64u" +# define TIFF_SSIZE_FORMAT "%Iu" +#else +# define TIFF_UINT64_FORMAT "%llu" +# define TIFF_SSIZE_FORMAT "%zd" +#endif + +/* define to use win32 IO system */ +#cmakedefine USE_WIN32_FILEIO + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Support Deflate compression */ +#define ZIP_SUPPORT 1 + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1659 @@ +/* $Id: tif_dir.c,v 1.113 2012-06-14 20:32:53 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Tag Get & Set Routines. + * (and also some miscellaneous stuff) + */ +#include "tiffiop.h" + +/* + * These are used in the backwards compatibility code... + */ +#define DATATYPE_VOID 0 /* !untyped data */ +#define DATATYPE_INT 1 /* !signed integer data */ +#define DATATYPE_UINT 2 /* !unsigned integer data */ +#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ + +static void +setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) +{ + if (*vpp) + _TIFFfree(*vpp), *vpp = 0; + if (vp) { + tmsize_t bytes = (tmsize_t)(nmemb * elem_size); + if (elem_size && bytes / elem_size == nmemb) + *vpp = (void*) _TIFFmalloc(bytes); + if (*vpp) + _TIFFmemcpy(*vpp, vp, bytes); + } +} +void _TIFFsetByteArray(void** vpp, void* vp, uint32 n) + { setByteArray(vpp, vp, n, 1); } +void _TIFFsetString(char** cpp, char* cp) + { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } +void _TIFFsetNString(char** cpp, char* cp, uint32 n) + { setByteArray((void**) cpp, (void*) cp, n, 1); } +void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n) + { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } +void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n) + { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } +void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n) + { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); } +void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) + { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } +void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) + { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } + +static void +setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) +{ + if (*vpp) + _TIFFfree(*vpp); + *vpp = _TIFFmalloc(nmemb*sizeof(double)); + if (*vpp) + { + while (nmemb--) + ((double*)*vpp)[nmemb] = value; + } +} + +/* + * Install extra samples information. + */ +static int +setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) +{ +/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ +#define EXTRASAMPLE_COREL_UNASSALPHA 999 + + uint16* va; + uint32 i; + + *v = (uint16) va_arg(ap, uint16_vap); + if ((uint16) *v > td->td_samplesperpixel) + return 0; + va = va_arg(ap, uint16*); + if (*v > 0 && va == NULL) /* typically missing param */ + return 0; + for (i = 0; i < *v; i++) { + if (va[i] > EXTRASAMPLE_UNASSALPHA) { + /* + * XXX: Corel Draw is known to produce incorrect + * ExtraSamples tags which must be patched here if we + * want to be able to open some of the damaged TIFF + * files: + */ + if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) + va[i] = EXTRASAMPLE_UNASSALPHA; + else + return 0; + } + } + td->td_extrasamples = (uint16) *v; + _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); + return 1; + +#undef EXTRASAMPLE_COREL_UNASSALPHA +} + +/* + * Confirm we have "samplesperpixel" ink names separated by \0. Returns + * zero if the ink names are not as expected. + */ +static uint32 +checkInkNamesString(TIFF* tif, uint32 slen, const char* s) +{ + TIFFDirectory* td = &tif->tif_dir; + uint16 i = td->td_samplesperpixel; + + if (slen > 0) { + const char* ep = s+slen; + const char* cp = s; + for (; i > 0; i--) { + for (; cp < ep && *cp != '\0'; cp++) {} + if (cp >= ep) + goto bad; + cp++; /* skip \0 */ + } + return ((uint32)(cp-s)); + } +bad: + TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", + "%s: Invalid InkNames value; expecting %d names, found %d", + tif->tif_name, + td->td_samplesperpixel, + td->td_samplesperpixel-i); + return (0); +} + +static int +_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "_TIFFVSetField"; + + TIFFDirectory* td = &tif->tif_dir; + int status = 1; + uint32 v32, i, v; + char* s; + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + uint32 standard_tag = tag; + + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (ie. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) { + standard_tag = 0; + } + + switch (standard_tag) { + case TIFFTAG_SUBFILETYPE: + td->td_subfiletype = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_IMAGEWIDTH: + td->td_imagewidth = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_IMAGELENGTH: + td->td_imagelength = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_BITSPERSAMPLE: + td->td_bitspersample = (uint16) va_arg(ap, uint16_vap); + /* + * If the data require post-decoding processing to byte-swap + * samples, set it up here. Note that since tags are required + * to be ordered, compression code can override this behaviour + * in the setup method if it wants to roll the post decoding + * work in with its normal work. + */ + if (tif->tif_flags & TIFF_SWAB) { + if (td->td_bitspersample == 8) + tif->tif_postdecode = _TIFFNoPostDecode; + else if (td->td_bitspersample == 16) + tif->tif_postdecode = _TIFFSwab16BitData; + else if (td->td_bitspersample == 24) + tif->tif_postdecode = _TIFFSwab24BitData; + else if (td->td_bitspersample == 32) + tif->tif_postdecode = _TIFFSwab32BitData; + else if (td->td_bitspersample == 64) + tif->tif_postdecode = _TIFFSwab64BitData; + else if (td->td_bitspersample == 128) /* two 64's */ + tif->tif_postdecode = _TIFFSwab64BitData; + } + break; + case TIFFTAG_COMPRESSION: + v = (uint16) va_arg(ap, uint16_vap); + /* + * If we're changing the compression scheme, the notify the + * previous module so that it can cleanup any state it's + * setup. + */ + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { + if ((uint32)td->td_compression == v) + break; + (*tif->tif_cleanup)(tif); + tif->tif_flags &= ~TIFF_CODERSETUP; + } + /* + * Setup new compression routine state. + */ + if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) + td->td_compression = (uint16) v; + else + status = 0; + break; + case TIFFTAG_PHOTOMETRIC: + td->td_photometric = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_THRESHHOLDING: + td->td_threshholding = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_FILLORDER: + v = (uint16) va_arg(ap, uint16_vap); + if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) + goto badvalue; + td->td_fillorder = (uint16) v; + break; + case TIFFTAG_ORIENTATION: + v = (uint16) va_arg(ap, uint16_vap); + if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) + goto badvalue; + else + td->td_orientation = (uint16) v; + break; + case TIFFTAG_SAMPLESPERPIXEL: + v = (uint16) va_arg(ap, uint16_vap); + if (v == 0) + goto badvalue; + td->td_samplesperpixel = (uint16) v; + break; + case TIFFTAG_ROWSPERSTRIP: + v32 = (uint32) va_arg(ap, uint32); + if (v32 == 0) + goto badvalue32; + td->td_rowsperstrip = v32; + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { + td->td_tilelength = v32; + td->td_tilewidth = td->td_imagewidth; + } + break; + case TIFFTAG_MINSAMPLEVALUE: + td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_MAXSAMPLEVALUE: + td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); + else + setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel); + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); + else + setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel); + break; + case TIFFTAG_XRESOLUTION: + td->td_xresolution = (float) va_arg(ap, double); + break; + case TIFFTAG_YRESOLUTION: + td->td_yresolution = (float) va_arg(ap, double); + break; + case TIFFTAG_PLANARCONFIG: + v = (uint16) va_arg(ap, uint16_vap); + if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) + goto badvalue; + td->td_planarconfig = (uint16) v; + break; + case TIFFTAG_XPOSITION: + td->td_xposition = (float) va_arg(ap, double); + break; + case TIFFTAG_YPOSITION: + td->td_yposition = (float) va_arg(ap, double); + break; + case TIFFTAG_RESOLUTIONUNIT: + v = (uint16) va_arg(ap, uint16_vap); + if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) + goto badvalue; + td->td_resolutionunit = (uint16) v; + break; + case TIFFTAG_PAGENUMBER: + td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap); + td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_HALFTONEHINTS: + td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap); + td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_COLORMAP: + v32 = (uint32)(1L<td_bitspersample); + _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); + _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); + _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); + break; + case TIFFTAG_EXTRASAMPLES: + if (!setExtraSamples(td, ap, &v)) + goto badvalue; + break; + case TIFFTAG_MATTEING: + td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0); + if (td->td_extrasamples) { + uint16 sv = EXTRASAMPLE_ASSOCALPHA; + _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); + } + break; + case TIFFTAG_TILEWIDTH: + v32 = (uint32) va_arg(ap, uint32); + if (v32 % 16) { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "Nonstandard tile width %d, convert file", v32); + } + td->td_tilewidth = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILELENGTH: + v32 = (uint32) va_arg(ap, uint32); + if (v32 % 16) { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "Nonstandard tile length %d, convert file", v32); + } + td->td_tilelength = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILEDEPTH: + v32 = (uint32) va_arg(ap, uint32); + if (v32 == 0) + goto badvalue32; + td->td_tiledepth = v32; + break; + case TIFFTAG_DATATYPE: + v = (uint16) va_arg(ap, uint16_vap); + switch (v) { + case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; + case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; + case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; + case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; + default: goto badvalue; + } + td->td_sampleformat = (uint16) v; + break; + case TIFFTAG_SAMPLEFORMAT: + v = (uint16) va_arg(ap, uint16_vap); + if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) + goto badvalue; + td->td_sampleformat = (uint16) v; + + /* Try to fix up the SWAB function for complex data. */ + if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT + && td->td_bitspersample == 32 + && tif->tif_postdecode == _TIFFSwab32BitData ) + tif->tif_postdecode = _TIFFSwab16BitData; + else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT + || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) + && td->td_bitspersample == 64 + && tif->tif_postdecode == _TIFFSwab64BitData ) + tif->tif_postdecode = _TIFFSwab32BitData; + break; + case TIFFTAG_IMAGEDEPTH: + td->td_imagedepth = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_SUBIFD: + if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { + td->td_nsubifd = (uint16) va_arg(ap, uint16_vap); + _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*), + (long) td->td_nsubifd); + } else { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Sorry, cannot nest SubIFDs", + tif->tif_name); + status = 0; + } + break; + case TIFFTAG_YCBCRPOSITIONING: + td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap); + td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_TRANSFERFUNCTION: + v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; + for (i = 0; i < v; i++) + _TIFFsetShortArray(&td->td_transferfunction[i], + va_arg(ap, uint16*), 1L<td_bitspersample); + break; + case TIFFTAG_REFERENCEBLACKWHITE: + /* XXX should check for null range */ + _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); + break; + case TIFFTAG_INKNAMES: + v = (uint16) va_arg(ap, uint16_vap); + s = va_arg(ap, char*); + v = checkInkNamesString(tif, v, s); + status = v > 0; + if( v > 0 ) { + _TIFFsetNString(&td->td_inknames, s, v); + td->td_inknameslen = v; + } + break; + case TIFFTAG_PERSAMPLE: + v = (uint16) va_arg(ap, uint16_vap); + if( v == PERSAMPLE_MULTI ) + tif->tif_flags |= TIFF_PERSAMPLE; + else + tif->tif_flags &= ~TIFF_PERSAMPLE; + break; + default: { + TIFFTagValue *tv; + int tv_size, iCustom; + + /* + * This can happen if multiple images are open with different + * codecs which have private tags. The global tag information + * table may then have tags that are valid for one file but not + * the other. If the client tries to set a tag that is not valid + * for the image's codec then we'll arrive here. This + * happens, for example, when tiffcp is used to convert between + * compression schemes and codec-specific tags are blindly copied. + */ + if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip ? fip->field_name : "Unknown"); + status = 0; + break; + } + + /* + * Find the existing entry for this custom value. + */ + tv = NULL; + for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { + if (td->td_customValues[iCustom].info->field_tag == tag) { + tv = td->td_customValues + iCustom; + if (tv->value != NULL) { + _TIFFfree(tv->value); + tv->value = NULL; + } + break; + } + } + + /* + * Grow the custom list if the entry was not found. + */ + if(tv == NULL) { + TIFFTagValue *new_customValues; + + td->td_customValueCount++; + new_customValues = (TIFFTagValue *) + _TIFFrealloc(td->td_customValues, + sizeof(TIFFTagValue) * td->td_customValueCount); + if (!new_customValues) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Failed to allocate space for list of custom values", + tif->tif_name); + status = 0; + goto end; + } + + td->td_customValues = new_customValues; + + tv = td->td_customValues + (td->td_customValueCount - 1); + tv->info = fip; + tv->value = NULL; + tv->count = 0; + } + + /* + * Set custom value ... save a copy of the custom tag value. + */ + tv_size = _TIFFDataSize(fip->field_type); + if (tv_size == 0) { + status = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad field type %d for \"%s\"", + tif->tif_name, fip->field_type, + fip->field_name); + goto end; + } + + if (fip->field_type == TIFF_ASCII) + { + uint32 ma; + char* mb; + if (fip->field_passcount) + { + assert(fip->field_writecount==TIFF_VARIABLE2); + ma=(uint32)va_arg(ap,uint32); + mb=(char*)va_arg(ap,char*); + } + else + { + mb=(char*)va_arg(ap,char*); + ma=(uint32)(strlen(mb)+1); + } + tv->count=ma; + setByteArray(&tv->value,mb,ma,1); + } + else + { + if (fip->field_passcount) { + if (fip->field_writecount == TIFF_VARIABLE2) + tv->count = (uint32) va_arg(ap, uint32); + else + tv->count = (int) va_arg(ap, int); + } else if (fip->field_writecount == TIFF_VARIABLE + || fip->field_writecount == TIFF_VARIABLE2) + tv->count = 1; + else if (fip->field_writecount == TIFF_SPP) + tv->count = td->td_samplesperpixel; + else + tv->count = fip->field_writecount; + + if (tv->count == 0) { + status = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Null count for \"%s\" (type " + "%d, writecount %d, passcount %d)", + tif->tif_name, + fip->field_name, + fip->field_type, + fip->field_writecount, + fip->field_passcount); + goto end; + } + + tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, + "custom tag binary object"); + if (!tv->value) { + status = 0; + goto end; + } + + if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + uint16 v[2]; + v[0] = (uint16)va_arg(ap, int); + v[1] = (uint16)va_arg(ap, int); + _TIFFmemcpy(tv->value, &v, 4); + } + + else if (fip->field_passcount + || fip->field_writecount == TIFF_VARIABLE + || fip->field_writecount == TIFF_VARIABLE2 + || fip->field_writecount == TIFF_SPP + || tv->count > 1) { + _TIFFmemcpy(tv->value, va_arg(ap, void *), + tv->count * tv_size); + } else { + char *val = (char *)tv->value; + assert( tv->count == 1 ); + + switch (fip->field_type) { + case TIFF_BYTE: + case TIFF_UNDEFINED: + { + uint8 v = (uint8)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SBYTE: + { + int8 v = (int8)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SHORT: + { + uint16 v = (uint16)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SSHORT: + { + int16 v = (int16)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_LONG: + case TIFF_IFD: + { + uint32 v = va_arg(ap, uint32); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SLONG: + { + int32 v = va_arg(ap, int32); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_LONG8: + case TIFF_IFD8: + { + uint64 v = va_arg(ap, uint64); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SLONG8: + { + int64 v = va_arg(ap, int64); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + { + float v = (float)va_arg(ap, double); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_DOUBLE: + { + double v = va_arg(ap, double); + _TIFFmemcpy(val, &v, tv_size); + } + break; + default: + _TIFFmemset(val, 0, tv_size); + status = 0; + break; + } + } + } + } + } + if (status) { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + if (fip) + TIFFSetFieldBit(tif, fip->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + } + +end: + va_end(ap); + return (status); +badvalue: + { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad value %u for \"%s\" tag", + tif->tif_name, v, + fip ? fip->field_name : "Unknown"); + va_end(ap); + } + return (0); +badvalue32: + { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad value %u for \"%s\" tag", + tif->tif_name, v32, + fip ? fip->field_name : "Unknown"); + va_end(ap); + } + return (0); +} + +/* + * Return 1/0 according to whether or not + * it is permissible to set the tag's value. + * Note that we allow ImageLength to be changed + * so that we can append and extend to images. + * Any other tag may not be altered once writing + * has commenced, unless its value has no effect + * on the format of the data that is written. + */ +static int +OkToChangeTag(TIFF* tif, uint32 tag) +{ + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) { /* unknown tag */ + TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); + return (0); + } + if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && + !fip->field_oktochange) { + /* + * Consult info table to see if tag can be changed + * after we've started writing. We only allow changes + * to those tags that don't/shouldn't affect the + * compression and/or format of the data. + */ + TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", + "%s: Cannot modify tag \"%s\" while writing", + tif->tif_name, fip->field_name); + return (0); + } + return (1); +} + +/* + * Record the value of a field in the + * internal directory structure. The + * field will be written to the file + * when/if the directory structure is + * updated. + */ +int +TIFFSetField(TIFF* tif, uint32 tag, ...) +{ + va_list ap; + int status; + + va_start(ap, tag); + status = TIFFVSetField(tif, tag, ap); + va_end(ap); + return (status); +} + +/* + * Clear the contents of the field in the internal structure. + */ +int +TIFFUnsetField(TIFF* tif, uint32 tag) +{ + const TIFFField *fip = TIFFFieldWithTag(tif, tag); + TIFFDirectory* td = &tif->tif_dir; + + if( !fip ) + return 0; + + if( fip->field_bit != FIELD_CUSTOM ) + TIFFClrFieldBit(tif, fip->field_bit); + else + { + TIFFTagValue *tv = NULL; + int i; + + for (i = 0; i < td->td_customValueCount; i++) { + + tv = td->td_customValues + i; + if( tv->info->field_tag == tag ) + break; + } + + if( i < td->td_customValueCount ) + { + _TIFFfree(tv->value); + for( ; i < td->td_customValueCount-1; i++) { + td->td_customValues[i] = td->td_customValues[i+1]; + } + td->td_customValueCount--; + } + } + + tif->tif_flags |= TIFF_DIRTYDIRECT; + + return (1); +} + +/* + * Like TIFFSetField, but taking a varargs + * parameter list. This routine is useful + * for building higher-level interfaces on + * top of the library. + */ +int +TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + return OkToChangeTag(tif, tag) ? + (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; +} + +static int +_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + TIFFDirectory* td = &tif->tif_dir; + int ret_val = 1; + uint32 standard_tag = tag; + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); + + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (ie. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) { + standard_tag = 0; + } + + switch (standard_tag) { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32*) = td->td_subfiletype; + break; + case TIFFTAG_IMAGEWIDTH: + *va_arg(ap, uint32*) = td->td_imagewidth; + break; + case TIFFTAG_IMAGELENGTH: + *va_arg(ap, uint32*) = td->td_imagelength; + break; + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16*) = td->td_bitspersample; + break; + case TIFFTAG_COMPRESSION: + *va_arg(ap, uint16*) = td->td_compression; + break; + case TIFFTAG_PHOTOMETRIC: + *va_arg(ap, uint16*) = td->td_photometric; + break; + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16*) = td->td_threshholding; + break; + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16*) = td->td_fillorder; + break; + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16*) = td->td_orientation; + break; + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16*) = td->td_samplesperpixel; + break; + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32*) = td->td_rowsperstrip; + break; + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_minsamplevalue; + break; + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_maxsamplevalue; + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double**) = td->td_sminsamplevalue; + else + { + /* libtiff historially treats this as a single value. */ + uint16 i; + double v = td->td_sminsamplevalue[0]; + for (i=1; i < td->td_samplesperpixel; ++i) + if( td->td_sminsamplevalue[i] < v ) + v = td->td_sminsamplevalue[i]; + *va_arg(ap, double*) = v; + } + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double**) = td->td_smaxsamplevalue; + else + { + /* libtiff historially treats this as a single value. */ + uint16 i; + double v = td->td_smaxsamplevalue[0]; + for (i=1; i < td->td_samplesperpixel; ++i) + if( td->td_smaxsamplevalue[i] > v ) + v = td->td_smaxsamplevalue[i]; + *va_arg(ap, double*) = v; + } + break; + case TIFFTAG_XRESOLUTION: + *va_arg(ap, float*) = td->td_xresolution; + break; + case TIFFTAG_YRESOLUTION: + *va_arg(ap, float*) = td->td_yresolution; + break; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16*) = td->td_planarconfig; + break; + case TIFFTAG_XPOSITION: + *va_arg(ap, float*) = td->td_xposition; + break; + case TIFFTAG_YPOSITION: + *va_arg(ap, float*) = td->td_yposition; + break; + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16*) = td->td_resolutionunit; + break; + case TIFFTAG_PAGENUMBER: + *va_arg(ap, uint16*) = td->td_pagenumber[0]; + *va_arg(ap, uint16*) = td->td_pagenumber[1]; + break; + case TIFFTAG_HALFTONEHINTS: + *va_arg(ap, uint16*) = td->td_halftonehints[0]; + *va_arg(ap, uint16*) = td->td_halftonehints[1]; + break; + case TIFFTAG_COLORMAP: + *va_arg(ap, uint16**) = td->td_colormap[0]; + *va_arg(ap, uint16**) = td->td_colormap[1]; + *va_arg(ap, uint16**) = td->td_colormap[2]; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + _TIFFFillStriles( tif ); + *va_arg(ap, uint64**) = td->td_stripoffset; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + _TIFFFillStriles( tif ); + *va_arg(ap, uint64**) = td->td_stripbytecount; + break; + case TIFFTAG_MATTEING: + *va_arg(ap, uint16*) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + break; + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16*) = td->td_extrasamples; + *va_arg(ap, uint16**) = td->td_sampleinfo; + break; + case TIFFTAG_TILEWIDTH: + *va_arg(ap, uint32*) = td->td_tilewidth; + break; + case TIFFTAG_TILELENGTH: + *va_arg(ap, uint32*) = td->td_tilelength; + break; + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32*) = td->td_tiledepth; + break; + case TIFFTAG_DATATYPE: + switch (td->td_sampleformat) { + case SAMPLEFORMAT_UINT: + *va_arg(ap, uint16*) = DATATYPE_UINT; + break; + case SAMPLEFORMAT_INT: + *va_arg(ap, uint16*) = DATATYPE_INT; + break; + case SAMPLEFORMAT_IEEEFP: + *va_arg(ap, uint16*) = DATATYPE_IEEEFP; + break; + case SAMPLEFORMAT_VOID: + *va_arg(ap, uint16*) = DATATYPE_VOID; + break; + } + break; + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16*) = td->td_sampleformat; + break; + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32*) = td->td_imagedepth; + break; + case TIFFTAG_SUBIFD: + *va_arg(ap, uint16*) = td->td_nsubifd; + *va_arg(ap, uint64**) = td->td_subifd; + break; + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16*) = td->td_ycbcrpositioning; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; + break; + case TIFFTAG_TRANSFERFUNCTION: + *va_arg(ap, uint16**) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + *va_arg(ap, uint16**) = td->td_transferfunction[1]; + *va_arg(ap, uint16**) = td->td_transferfunction[2]; + } + break; + case TIFFTAG_REFERENCEBLACKWHITE: + *va_arg(ap, float**) = td->td_refblackwhite; + break; + case TIFFTAG_INKNAMES: + *va_arg(ap, char**) = td->td_inknames; + break; + default: + { + int i; + + /* + * This can happen if multiple images are open + * with different codecs which have private + * tags. The global tag information table may + * then have tags that are valid for one file + * but not the other. If the client tries to + * get a tag that is not valid for the image's + * codec then we'll arrive here. + */ + if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) + { + TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", + "%s: Invalid %stag \"%s\" " + "(not supported by codec)", + tif->tif_name, + isPseudoTag(tag) ? "pseudo-" : "", + fip ? fip->field_name : "Unknown"); + ret_val = 0; + break; + } + + /* + * Do we have a custom value? + */ + ret_val = 0; + for (i = 0; i < td->td_customValueCount; i++) { + TIFFTagValue *tv = td->td_customValues + i; + + if (tv->info->field_tag != tag) + continue; + + if (fip->field_passcount) { + if (fip->field_readcount == TIFF_VARIABLE2) + *va_arg(ap, uint32*) = (uint32)tv->count; + else /* Assume TIFF_VARIABLE */ + *va_arg(ap, uint16*) = (uint16)tv->count; + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } else if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0]; + *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1]; + ret_val = 1; + } else { + if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP + || tv->count > 1) { + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } else { + char *val = (char *)tv->value; + assert( tv->count == 1 ); + switch (fip->field_type) { + case TIFF_BYTE: + case TIFF_UNDEFINED: + *va_arg(ap, uint8*) = + *(uint8 *)val; + ret_val = 1; + break; + case TIFF_SBYTE: + *va_arg(ap, int8*) = + *(int8 *)val; + ret_val = 1; + break; + case TIFF_SHORT: + *va_arg(ap, uint16*) = + *(uint16 *)val; + ret_val = 1; + break; + case TIFF_SSHORT: + *va_arg(ap, int16*) = + *(int16 *)val; + ret_val = 1; + break; + case TIFF_LONG: + case TIFF_IFD: + *va_arg(ap, uint32*) = + *(uint32 *)val; + ret_val = 1; + break; + case TIFF_SLONG: + *va_arg(ap, int32*) = + *(int32 *)val; + ret_val = 1; + break; + case TIFF_LONG8: + case TIFF_IFD8: + *va_arg(ap, uint64*) = + *(uint64 *)val; + ret_val = 1; + break; + case TIFF_SLONG8: + *va_arg(ap, int64*) = + *(int64 *)val; + ret_val = 1; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + *va_arg(ap, float*) = + *(float *)val; + ret_val = 1; + break; + case TIFF_DOUBLE: + *va_arg(ap, double*) = + *(double *)val; + ret_val = 1; + break; + default: + ret_val = 0; + break; + } + } + } + break; + } + } + } + return(ret_val); +} + +/* + * Return the value of a field in the + * internal directory structure. + */ +int +TIFFGetField(TIFF* tif, uint32 tag, ...) +{ + int status; + va_list ap; + + va_start(ap, tag); + status = TIFFVGetField(tif, tag, ap); + va_end(ap); + return (status); +} + +/* + * Like TIFFGetField, but taking a varargs + * parameter list. This routine is useful + * for building higher-level interfaces on + * top of the library. + */ +int +TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); + return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? + (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); +} + +#define CleanupField(member) { \ + if (td->member) { \ + _TIFFfree(td->member); \ + td->member = 0; \ + } \ +} + +/* + * Release storage associated with a directory. + */ +void +TIFFFreeDirectory(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + int i; + + _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); + CleanupField(td_sminsamplevalue); + CleanupField(td_smaxsamplevalue); + CleanupField(td_colormap[0]); + CleanupField(td_colormap[1]); + CleanupField(td_colormap[2]); + CleanupField(td_sampleinfo); + CleanupField(td_subifd); + CleanupField(td_inknames); + CleanupField(td_refblackwhite); + CleanupField(td_transferfunction[0]); + CleanupField(td_transferfunction[1]); + CleanupField(td_transferfunction[2]); + CleanupField(td_stripoffset); + CleanupField(td_stripbytecount); + TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); + TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); + + /* Cleanup custom tag values */ + for( i = 0; i < td->td_customValueCount; i++ ) { + if (td->td_customValues[i].value) + _TIFFfree(td->td_customValues[i].value); + } + + td->td_customValueCount = 0; + CleanupField(td_customValues); + +#if defined(DEFER_STRILE_LOAD) + _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); +#endif +} +#undef CleanupField + +/* + * Client Tag extension support (from Niles Ritter). + */ +static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; + +TIFFExtendProc +TIFFSetTagExtender(TIFFExtendProc extender) +{ + TIFFExtendProc prev = _TIFFextender; + _TIFFextender = extender; + return (prev); +} + +/* + * Setup for a new directory. Should we automatically call + * TIFFWriteDirectory() if the current one is dirty? + * + * The newly created directory will not exist on the file till + * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. + */ +int +TIFFCreateDirectory(TIFF* tif) +{ + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; + + return 0; +} + +int +TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) +{ + TIFFDefaultDirectory(tif); + + /* + * Reset the field definitions to match the application provided list. + * Hopefully TIFFDefaultDirectory() won't have done anything irreversable + * based on it's assumption this is an image directory. + */ + _TIFFSetupFields(tif, infoarray); + + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; + + return 0; +} + +int +TIFFCreateEXIFDirectory(TIFF* tif) +{ + const TIFFFieldArray* exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFCreateCustomDirectory(tif, exifFieldArray); +} + +/* + * Setup a default directory structure. + */ +int +TIFFDefaultDirectory(TIFF* tif) +{ + register TIFFDirectory* td = &tif->tif_dir; + const TIFFFieldArray* tiffFieldArray; + + tiffFieldArray = _TIFFGetFields(); + _TIFFSetupFields(tif, tiffFieldArray); + + _TIFFmemset(td, 0, sizeof (*td)); + td->td_fillorder = FILLORDER_MSB2LSB; + td->td_bitspersample = 1; + td->td_threshholding = THRESHHOLD_BILEVEL; + td->td_orientation = ORIENTATION_TOPLEFT; + td->td_samplesperpixel = 1; + td->td_rowsperstrip = (uint32) -1; + td->td_tilewidth = 0; + td->td_tilelength = 0; + td->td_tiledepth = 1; + td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ + td->td_resolutionunit = RESUNIT_INCH; + td->td_sampleformat = SAMPLEFORMAT_UINT; + td->td_imagedepth = 1; + td->td_ycbcrsubsampling[0] = 2; + td->td_ycbcrsubsampling[1] = 2; + td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; + tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_foundfield = NULL; + tif->tif_tagmethods.vsetfield = _TIFFVSetField; + tif->tif_tagmethods.vgetfield = _TIFFVGetField; + tif->tif_tagmethods.printdir = NULL; + /* + * Give client code a chance to install their own + * tag extensions & methods, prior to compression overloads. + */ + if (_TIFFextender) + (*_TIFFextender)(tif); + (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + /* + * NB: The directory is marked dirty as a result of setting + * up the default compression scheme. However, this really + * isn't correct -- we want TIFF_DIRTYDIRECT to be set only + * if the user does something. We could just do the setup + * by hand, but it seems better to use the normal mechanism + * (i.e. TIFFSetField). + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + + /* + * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 + * we clear the ISTILED flag when setting up a new directory. + * Should we also be clearing stuff like INSUBIFD? + */ + tif->tif_flags &= ~TIFF_ISTILED; + + return (1); +} + +static int +TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off) +{ + static const char module[] = "TIFFAdvanceDirectory"; + if (isMapped(tif)) + { + uint64 poff=*nextdir; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + tmsize_t poffa,poffb,poffc,poffd; + uint16 dircount; + uint32 nextdir32; + poffa=(tmsize_t)poff; + poffb=poffa+sizeof(uint16); + if (((uint64)poffa!=poff)||(poffbtif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); + return(0); + } + _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(&dircount); + poffc=poffb+dircount*12; + poffd=poffc+sizeof(uint32); + if ((poffctif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); + return(0); + } + if (off!=NULL) + *off=(uint64)poffc; + _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdir=nextdir32; + } + else + { + tmsize_t poffa,poffb,poffc,poffd; + uint64 dircount64; + uint16 dircount16; + poffa=(tmsize_t)poff; + poffb=poffa+sizeof(uint64); + if (((uint64)poffa!=poff)||(poffbtif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); + return(0); + } + _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed"); + return(0); + } + dircount16=(uint16)dircount64; + poffc=poffb+dircount16*20; + poffd=poffc+sizeof(uint64); + if ((poffctif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); + return(0); + } + if (off!=NULL) + *off=(uint64)poffc; + _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdir); + } + return(1); + } + else + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint16 dircount; + uint32 nextdir32; + if (!SeekOK(tif, *nextdir) || + !ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + if (off != NULL) + *off = TIFFSeekFile(tif, + dircount*12, SEEK_CUR); + else + (void) TIFFSeekFile(tif, + dircount*12, SEEK_CUR); + if (!ReadOK(tif, &nextdir32, sizeof (uint32))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdir=nextdir32; + } + else + { + uint64 dircount64; + uint16 dircount16; + if (!SeekOK(tif, *nextdir) || + !ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count"); + return(0); + } + dircount16 = (uint16)dircount64; + if (off != NULL) + *off = TIFFSeekFile(tif, + dircount16*20, SEEK_CUR); + else + (void) TIFFSeekFile(tif, + dircount16*20, SEEK_CUR); + if (!ReadOK(tif, nextdir, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdir); + } + return (1); + } +} + +/* + * Count the number of directories in a file. + */ +uint16 +TIFFNumberOfDirectories(TIFF* tif) +{ + uint64 nextdir; + uint16 n; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nextdir = tif->tif_header.classic.tiff_diroff; + else + nextdir = tif->tif_header.big.tiff_diroff; + n = 0; + while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) + n++; + return (n); +} + +/* + * Set the n-th directory as the current directory. + * NB: Directories are numbered starting at 0. + */ +int +TIFFSetDirectory(TIFF* tif, uint16 dirn) +{ + uint64 nextdir; + uint16 n; + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nextdir = tif->tif_header.classic.tiff_diroff; + else + nextdir = tif->tif_header.big.tiff_diroff; + for (n = dirn; n > 0 && nextdir != 0; n--) + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) + return (0); + tif->tif_nextdiroff = nextdir; + /* + * Set curdir to the actual directory index. The + * -1 is because TIFFReadDirectory will increment + * tif_curdir after successfully reading the directory. + */ + tif->tif_curdir = (dirn - n) - 1; + /* + * Reset tif_dirnumber counter and start new list of seen directories. + * We need this to prevent IFD loops. + */ + tif->tif_dirnumber = 0; + return (TIFFReadDirectory(tif)); +} + +/* + * Set the current directory to be the directory + * located at the specified file offset. This interface + * is used mainly to access directories linked with + * the SubIFD tag (e.g. thumbnail images). + */ +int +TIFFSetSubDirectory(TIFF* tif, uint64 diroff) +{ + tif->tif_nextdiroff = diroff; + /* + * Reset tif_dirnumber counter and start new list of seen directories. + * We need this to prevent IFD loops. + */ + tif->tif_dirnumber = 0; + return (TIFFReadDirectory(tif)); +} + +/* + * Return file offset of the current directory. + */ +uint64 +TIFFCurrentDirOffset(TIFF* tif) +{ + return (tif->tif_diroff); +} + +/* + * Return an indication of whether or not we are + * at the last directory in the file. + */ +int +TIFFLastDirectory(TIFF* tif) +{ + return (tif->tif_nextdiroff == 0); +} + +/* + * Unlink the specified directory from the directory chain. + */ +int +TIFFUnlinkDirectory(TIFF* tif, uint16 dirn) +{ + static const char module[] = "TIFFUnlinkDirectory"; + uint64 nextdir; + uint64 off; + uint16 n; + + if (tif->tif_mode == O_RDONLY) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not unlink directory in read-only file"); + return (0); + } + /* + * Go to the directory before the one we want + * to unlink and nab the offset of the link + * field we'll need to patch. + */ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + nextdir = tif->tif_header.classic.tiff_diroff; + off = 4; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + off = 8; + } + for (n = dirn-1; n > 0; n--) { + if (nextdir == 0) { + TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn); + return (0); + } + if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) + return (0); + } + /* + * Advance to the directory to be unlinked and fetch + * the offset of the directory that follows. + */ + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) + return (0); + /* + * Go back and patch the link field of the preceding + * directory to point to the offset of the directory + * that follows. + */ + (void) TIFFSeekFile(tif, off, SEEK_SET); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdir32; + nextdir32=(uint32)nextdir; + assert((uint64)nextdir32==nextdir); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + if (!WriteOK(tif, &nextdir32, sizeof (uint32))) { + TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); + return (0); + } + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextdir); + if (!WriteOK(tif, &nextdir, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); + return (0); + } + } + /* + * Leave directory state setup safely. We don't have + * facilities for doing inserting and removing directories, + * so it's safest to just invalidate everything. This + * means that the caller can only append to the directory + * chain. + */ + (*tif->tif_cleanup)(tif); + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE); + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; /* force link on next write */ + tif->tif_nextdiroff = 0; /* next write must be at end */ + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; + return (1); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dir.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,308 @@ +/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFDIR_ +#define _TIFFDIR_ +/* + * ``Library-private'' Directory-related Definitions. + */ + +typedef struct { + const TIFFField *info; + int count; + void *value; +} TIFFTagValue; + +/* + * TIFF Image File Directories are comprised of a table of field + * descriptors of the form shown below. The table is sorted in + * ascending order by tag. The values associated with each entry are + * disjoint and may appear anywhere in the file (so long as they are + * placed on a word boundary). + * + * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in + * BigTIFF, then it is placed in the offset field to save space. If so, + * it is left-justified in the offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint64 tdir_count; /* number of items; length in spec */ + union { + uint16 toff_short; + uint32 toff_long; + uint64 toff_long8; + } tdir_offset; /* either offset or the data itself if fits */ +} TIFFDirEntry; + +/* + * Internal format of a TIFF directory entry. + */ +typedef struct { +#define FIELD_SETLONGS 4 + /* bit vector of fields that are set */ + unsigned long td_fieldsset[FIELD_SETLONGS]; + + uint32 td_imagewidth, td_imagelength, td_imagedepth; + uint32 td_tilewidth, td_tilelength, td_tiledepth; + uint32 td_subfiletype; + uint16 td_bitspersample; + uint16 td_sampleformat; + uint16 td_compression; + uint16 td_photometric; + uint16 td_threshholding; + uint16 td_fillorder; + uint16 td_orientation; + uint16 td_samplesperpixel; + uint32 td_rowsperstrip; + uint16 td_minsamplevalue, td_maxsamplevalue; + double* td_sminsamplevalue; + double* td_smaxsamplevalue; + float td_xresolution, td_yresolution; + uint16 td_resolutionunit; + uint16 td_planarconfig; + float td_xposition, td_yposition; + uint16 td_pagenumber[2]; + uint16* td_colormap[3]; + uint16 td_halftonehints[2]; + uint16 td_extrasamples; + uint16* td_sampleinfo; + /* even though the name is misleading, td_stripsperimage is the number + * of striles (=strips or tiles) per plane, and td_nstrips the total + * number of striles */ + uint32 td_stripsperimage; + uint32 td_nstrips; /* size of offset & bytecount arrays */ + uint64* td_stripoffset; + uint64* td_stripbytecount; + int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ +#if defined(DEFER_STRILE_LOAD) + TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ + TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ +#endif + uint16 td_nsubifd; + uint64* td_subifd; + /* YCbCr parameters */ + uint16 td_ycbcrsubsampling[2]; + uint16 td_ycbcrpositioning; + /* Colorimetry parameters */ + uint16* td_transferfunction[3]; + float* td_refblackwhite; + /* CMYK parameters */ + int td_inknameslen; + char* td_inknames; + + int td_customValueCount; + TIFFTagValue *td_customValues; +} TIFFDirectory; + +/* + * Field flags used to indicate fields that have been set in a directory, and + * to reference fields when manipulating a directory. + */ + +/* + * FIELD_IGNORE is used to signify tags that are to be processed but otherwise + * ignored. This permits antiquated tags to be quietly read and discarded. + * Note that a bit *is* allocated for ignored tags; this is understood by the + * directory reading logic which uses this fact to avoid special-case handling + */ +#define FIELD_IGNORE 0 + +/* multi-item fields */ +#define FIELD_IMAGEDIMENSIONS 1 +#define FIELD_TILEDIMENSIONS 2 +#define FIELD_RESOLUTION 3 +#define FIELD_POSITION 4 + +/* single-item fields */ +#define FIELD_SUBFILETYPE 5 +#define FIELD_BITSPERSAMPLE 6 +#define FIELD_COMPRESSION 7 +#define FIELD_PHOTOMETRIC 8 +#define FIELD_THRESHHOLDING 9 +#define FIELD_FILLORDER 10 +#define FIELD_ORIENTATION 15 +#define FIELD_SAMPLESPERPIXEL 16 +#define FIELD_ROWSPERSTRIP 17 +#define FIELD_MINSAMPLEVALUE 18 +#define FIELD_MAXSAMPLEVALUE 19 +#define FIELD_PLANARCONFIG 20 +#define FIELD_RESOLUTIONUNIT 22 +#define FIELD_PAGENUMBER 23 +#define FIELD_STRIPBYTECOUNTS 24 +#define FIELD_STRIPOFFSETS 25 +#define FIELD_COLORMAP 26 +#define FIELD_EXTRASAMPLES 31 +#define FIELD_SAMPLEFORMAT 32 +#define FIELD_SMINSAMPLEVALUE 33 +#define FIELD_SMAXSAMPLEVALUE 34 +#define FIELD_IMAGEDEPTH 35 +#define FIELD_TILEDEPTH 36 +#define FIELD_HALFTONEHINTS 37 +#define FIELD_YCBCRSUBSAMPLING 39 +#define FIELD_YCBCRPOSITIONING 40 +#define FIELD_REFBLACKWHITE 41 +#define FIELD_TRANSFERFUNCTION 44 +#define FIELD_INKNAMES 46 +#define FIELD_SUBIFD 49 +/* FIELD_CUSTOM (see tiffio.h) 65 */ +/* end of support for well-known tags; codec-private tags follow */ +#define FIELD_CODEC 66 /* base of codec-private tags */ + + +/* + * Pseudo-tags don't normally need field bits since they are not written to an + * output file (by definition). The library also has express logic to always + * query a codec for a pseudo-tag so allocating a field bit for one is a + * waste. If codec wants to promote the notion of a pseudo-tag being ``set'' + * or ``unset'' then it can do using internal state flags without polluting + * the field bit space defined for real tags. + */ +#define FIELD_PSEUDO 0 + +#define FIELD_LAST (32*FIELD_SETLONGS-1) + +#define BITn(n) (((unsigned long)1L)<<((n)&0x1f)) +#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) +#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) +#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) +#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) + +#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) +#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) + +typedef enum { + TIFF_SETGET_UNDEFINED = 0, + TIFF_SETGET_ASCII = 1, + TIFF_SETGET_UINT8 = 2, + TIFF_SETGET_SINT8 = 3, + TIFF_SETGET_UINT16 = 4, + TIFF_SETGET_SINT16 = 5, + TIFF_SETGET_UINT32 = 6, + TIFF_SETGET_SINT32 = 7, + TIFF_SETGET_UINT64 = 8, + TIFF_SETGET_SINT64 = 9, + TIFF_SETGET_FLOAT = 10, + TIFF_SETGET_DOUBLE = 11, + TIFF_SETGET_IFD8 = 12, + TIFF_SETGET_INT = 13, + TIFF_SETGET_UINT16_PAIR = 14, + TIFF_SETGET_C0_ASCII = 15, + TIFF_SETGET_C0_UINT8 = 16, + TIFF_SETGET_C0_SINT8 = 17, + TIFF_SETGET_C0_UINT16 = 18, + TIFF_SETGET_C0_SINT16 = 19, + TIFF_SETGET_C0_UINT32 = 20, + TIFF_SETGET_C0_SINT32 = 21, + TIFF_SETGET_C0_UINT64 = 22, + TIFF_SETGET_C0_SINT64 = 23, + TIFF_SETGET_C0_FLOAT = 24, + TIFF_SETGET_C0_DOUBLE = 25, + TIFF_SETGET_C0_IFD8 = 26, + TIFF_SETGET_C16_ASCII = 27, + TIFF_SETGET_C16_UINT8 = 28, + TIFF_SETGET_C16_SINT8 = 29, + TIFF_SETGET_C16_UINT16 = 30, + TIFF_SETGET_C16_SINT16 = 31, + TIFF_SETGET_C16_UINT32 = 32, + TIFF_SETGET_C16_SINT32 = 33, + TIFF_SETGET_C16_UINT64 = 34, + TIFF_SETGET_C16_SINT64 = 35, + TIFF_SETGET_C16_FLOAT = 36, + TIFF_SETGET_C16_DOUBLE = 37, + TIFF_SETGET_C16_IFD8 = 38, + TIFF_SETGET_C32_ASCII = 39, + TIFF_SETGET_C32_UINT8 = 40, + TIFF_SETGET_C32_SINT8 = 41, + TIFF_SETGET_C32_UINT16 = 42, + TIFF_SETGET_C32_SINT16 = 43, + TIFF_SETGET_C32_UINT32 = 44, + TIFF_SETGET_C32_SINT32 = 45, + TIFF_SETGET_C32_UINT64 = 46, + TIFF_SETGET_C32_SINT64 = 47, + TIFF_SETGET_C32_FLOAT = 48, + TIFF_SETGET_C32_DOUBLE = 49, + TIFF_SETGET_C32_IFD8 = 50, + TIFF_SETGET_OTHER = 51 +} TIFFSetGetFieldType; + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const TIFFFieldArray* _TIFFGetFields(void); +extern const TIFFFieldArray* _TIFFGetExifFields(void); +extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray); +extern void _TIFFPrintFieldInfo(TIFF*, FILE*); + +extern int _TIFFFillStriles(TIFF*); + +typedef enum { + tfiatImage, + tfiatExif, + tfiatOther +} TIFFFieldArrayType; + +struct _TIFFFieldArray { + TIFFFieldArrayType type; /* array type, will be used to determine if IFD is image and such */ + uint32 allocated_size; /* 0 if array is constant, other if modified by future definition extension support */ + uint32 count; /* number of elements in fields array */ + TIFFField* fields; /* actual field info */ +}; + +struct _TIFFField { + uint32 field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + uint32 reserved; /* reserved for future extension */ + TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ + TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char* field_name; /* ASCII name */ + TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */ +}; + +extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32); +extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType); +extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType); + +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFDIR_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirinfo.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirinfo.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirinfo.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirinfo.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,907 @@ +/* $Id: tif_dirinfo.c,v 1.114 2011-05-17 00:21:17 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Core Directory Tag Support. + */ +#include "tiffiop.h" +#include + +/* + * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. + * + * NOTE: The second field (field_readcount) and third field (field_writecount) + * sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3) + * and TIFFTAG_SPP (-2). The macros should be used but would throw off + * the formatting of the code, so please interprete the -1, -2 and -3 + * values accordingly. + */ + +static TIFFFieldArray tiffFieldArray; +static TIFFFieldArray exifFieldArray; + +static TIFFField +tiffFields[] = { + { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL }, + { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL }, + { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL }, + { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL }, + { TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL }, + { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL }, + { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL }, + { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL }, + { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL }, + { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL }, + { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL }, + { TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL }, + { TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL }, + { TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL }, + { TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL }, + { TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL }, + { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL }, + { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL }, + { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL }, + { TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL }, + { TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL }, + { TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL }, + { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL }, + { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL }, + { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL }, + { TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL }, + { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL }, + { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL }, + { TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL }, + { TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL }, + { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL }, + { TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL }, + { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL }, + { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL }, + { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL }, + { TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL }, + { TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL }, + { TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL }, + { TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL }, + { TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL }, + { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL }, + { TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL }, + { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL }, + { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL }, + { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL }, + { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL }, + { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL }, + { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL }, + { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", &tiffFieldArray }, + { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL }, + { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL }, + { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL }, + { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL }, + { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL }, + { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL }, + { TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL }, + { TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL }, + { TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL }, + { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, + { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL }, + { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL }, + { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL }, + { TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL }, + /* begin SGI tags */ + { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL }, + { TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL }, + { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL }, + { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL }, + /* end SGI tags */ + /* begin Pixar tags */ + { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL }, + { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL }, + { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL }, + { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL }, + { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL }, + { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL }, + { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL }, + { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, + /* end Pixar tags */ + { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, + { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL }, + { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", &exifFieldArray }, + { TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL }, + { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL }, + { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL }, + { TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL }, + { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL }, + { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL }, + { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL }, + { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, + /* begin DNG tags */ + { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, + { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL }, + { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL }, + { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL }, + { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL }, + { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL }, + { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL }, + { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL }, + { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL }, + { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL }, + { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL }, + { TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL }, + { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL }, + { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL }, + { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL }, + { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL }, + { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL }, + { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL }, + { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL }, + { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL }, + { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL }, + { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL }, + { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL }, + { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL }, + { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL }, + { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL }, + { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL }, + { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL }, + { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL }, + { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL }, + { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL }, + { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL }, + { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL }, + { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL }, + { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL }, + { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL }, + { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL }, + { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL }, + { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL }, + { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL }, + { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL }, + { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL }, + { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL }, + { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL }, + { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL }, + { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL }, + { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL }, + { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL }, + /* end DNG tags */ + /* begin pseudo tags */ + { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, +}; + +static TIFFField +exifFields[] = { + { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL }, + { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL }, + { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL }, + { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL }, + { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL }, + { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL }, + { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL }, + { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL }, + { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL }, + { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL }, + { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL }, + { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL }, + { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL }, + { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL }, + { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL }, + { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL }, + { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL }, + { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL }, + { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL }, + { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL }, + { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL }, + { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL }, + { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL }, + { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL }, + { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL }, + { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL }, + { EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL }, + { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL }, + { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL }, + { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL }, + { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL }, + { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL }, + { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL }, + { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL }, + { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL }, + { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL }, + { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL }, + { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL }, + { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL }, + { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL }, + { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL }, + { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL }, + { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL }, + { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL }, + { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL }, + { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL }, + { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL }, + { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL }, + { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL }, + { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL }, + { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL }, + { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL }, + { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL }, + { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL }, + { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL }, + { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL } +}; + +static TIFFFieldArray +tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields }; +static TIFFFieldArray +exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields }; + +/* + * We have our own local lfind() equivelent to avoid subtle differences + * in types passed to lfind() on different systems. + */ + +static void * +td_lfind(const void *key, const void *base, size_t *nmemb, size_t size, + int(*compar)(const void *, const void *)) +{ + char *element, *end; + + end = (char *)base + *nmemb * size; + for (element = (char *)base; element < end; element += size) + if (!compar(key, element)) /* key found */ + return element; + + return NULL; +} + +const TIFFFieldArray* +_TIFFGetFields(void) +{ + return(&tiffFieldArray); +} + +const TIFFFieldArray* +_TIFFGetExifFields(void) +{ + return(&exifFieldArray); +} + +void +_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) +{ + if (tif->tif_fields && tif->tif_nfields > 0) { + uint32 i; + + for (i = 0; i < tif->tif_nfields; i++) { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_bit == FIELD_CUSTOM && + strncmp("Tag ", fld->field_name, 4) == 0) { + _TIFFfree(fld->field_name); + _TIFFfree(fld); + } + } + + _TIFFfree(tif->tif_fields); + tif->tif_fields = NULL; + tif->tif_nfields = 0; + } + if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) { + TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields", + "Setting up field info failed"); + } +} + +static int +tagCompare(const void* a, const void* b) +{ + const TIFFField* ta = *(const TIFFField**) a; + const TIFFField* tb = *(const TIFFField**) b; + /* NB: be careful of return values for 16-bit platforms */ + if (ta->field_tag != tb->field_tag) + return (int)ta->field_tag - (int)tb->field_tag; + else + return (ta->field_type == TIFF_ANY) ? + 0 : ((int)tb->field_type - (int)ta->field_type); +} + +static int +tagNameCompare(const void* a, const void* b) +{ + const TIFFField* ta = *(const TIFFField**) a; + const TIFFField* tb = *(const TIFFField**) b; + int ret = strcmp(ta->field_name, tb->field_name); + + if (ret) + return ret; + else + return (ta->field_type == TIFF_ANY) ? + 0 : ((int)tb->field_type - (int)ta->field_type); +} + +int +_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n) +{ + static const char module[] = "_TIFFMergeFields"; + static const char reason[] = "for fields array"; + TIFFField** tp; + uint32 i; + + tif->tif_foundfield = NULL; + + if (tif->tif_fields && tif->tif_nfields > 0) { + tif->tif_fields = (TIFFField**) + _TIFFCheckRealloc(tif, tif->tif_fields, + (tif->tif_nfields + n), + sizeof(TIFFField *), reason); + } else { + tif->tif_fields = (TIFFField **) + _TIFFCheckMalloc(tif, n, sizeof(TIFFField *), + reason); + } + if (!tif->tif_fields) { + TIFFErrorExt(tif->tif_clientdata, module, + "Failed to allocate fields array"); + return 0; + } + + tp = tif->tif_fields + tif->tif_nfields; + for (i = 0; i < n; i++) { + const TIFFField *fip = + TIFFFindField(tif, info[i].field_tag, TIFF_ANY); + + /* only add definitions that aren't already present */ + if (!fip) { + tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i); + tif->tif_nfields++; + } + } + + /* Sort the field info by tag number */ + qsort(tif->tif_fields, tif->tif_nfields, + sizeof(TIFFField *), tagCompare); + + return n; +} + +void +_TIFFPrintFieldInfo(TIFF* tif, FILE* fd) +{ + uint32 i; + + fprintf(fd, "%s: \n", tif->tif_name); + for (i = 0; i < tif->tif_nfields; i++) { + const TIFFField* fip = tif->tif_fields[i]; + fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n" + , (int)i + , (unsigned long) fip->field_tag + , fip->field_readcount, fip->field_writecount + , fip->field_type + , fip->field_bit + , fip->field_oktochange ? "TRUE" : "FALSE" + , fip->field_passcount ? "TRUE" : "FALSE" + , fip->field_name + ); + } +} + +/* + * Return size of TIFFDataType in bytes + */ +int +TIFFDataWidth(TIFFDataType type) +{ + switch(type) + { + case 0: /* nothing */ + case TIFF_BYTE: + case TIFF_ASCII: + case TIFF_SBYTE: + case TIFF_UNDEFINED: + return 1; + case TIFF_SHORT: + case TIFF_SSHORT: + return 2; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + case TIFF_IFD: + return 4; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + return 8; + default: + return 0; /* will return 0 for unknown types */ + } +} + +/* + * Return size of TIFFDataType in bytes. + * + * XXX: We need a separate function to determine the space needed + * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, + * but we use 4-byte float to represent rationals. + */ +int +_TIFFDataSize(TIFFDataType type) +{ + switch (type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_ASCII: + case TIFF_UNDEFINED: + return 1; + case TIFF_SHORT: + case TIFF_SSHORT: + return 2; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + case TIFF_IFD: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + return 4; + case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + return 8; + default: + return 0; + } +} + +const TIFFField* +TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt) +{ + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField* pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && + (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return tif->tif_foundfield; + + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; + + /* NB: use sorted search (e.g. binary search) */ + + key.field_tag = tag; + key.field_type = dt; + + ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields, + tif->tif_nfields, + sizeof(TIFFField *), tagCompare); + return tif->tif_foundfield = (ret ? *ret : NULL); +} + +const TIFFField* +_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt) +{ + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField* pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield + && streq(tif->tif_foundfield->field_name, field_name) + && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return (tif->tif_foundfield); + + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; + + /* NB: use linear search since list is sorted by key#, not name */ + + key.field_name = (char *)field_name; + key.field_type = dt; + + ret = (const TIFFField **) + td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, + sizeof(TIFFField *), tagNameCompare); + + return tif->tif_foundfield = (ret ? *ret : NULL); +} + +const TIFFField* +TIFFFieldWithTag(TIFF* tif, uint32 tag) +{ + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) { + TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag", + "Internal error, unknown tag 0x%x", + (unsigned int) tag); + } + return (fip); +} + +const TIFFField* +TIFFFieldWithName(TIFF* tif, const char *field_name) +{ + const TIFFField* fip = + _TIFFFindFieldByName(tif, field_name, TIFF_ANY); + if (!fip) { + TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName", + "Internal error, unknown tag %s", field_name); + } + return (fip); +} + +const TIFFField* +_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt) + +{ + const TIFFField *fld; + + fld = TIFFFindField(tif, tag, dt); + if (fld == NULL) { + fld = _TIFFCreateAnonField(tif, tag, dt); + if (!_TIFFMergeFields(tif, fld, 1)) + return NULL; + } + + return fld; +} + +TIFFField* +_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type) +{ + TIFFField *fld; + (void) tif; + + fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField)); + if (fld == NULL) + return NULL; + _TIFFmemset(fld, 0, sizeof(TIFFField)); + + fld->field_tag = tag; + fld->field_readcount = TIFF_VARIABLE2; + fld->field_writecount = TIFF_VARIABLE2; + fld->field_type = field_type; + fld->reserved = 0; + switch (field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + fld->set_field_type = TIFF_SETGET_C32_UINT8; + fld->get_field_type = TIFF_SETGET_C32_UINT8; + break; + case TIFF_ASCII: + fld->set_field_type = TIFF_SETGET_C32_ASCII; + fld->get_field_type = TIFF_SETGET_C32_ASCII; + break; + case TIFF_SHORT: + fld->set_field_type = TIFF_SETGET_C32_UINT16; + fld->get_field_type = TIFF_SETGET_C32_UINT16; + break; + case TIFF_LONG: + fld->set_field_type = TIFF_SETGET_C32_UINT32; + fld->get_field_type = TIFF_SETGET_C32_UINT32; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + fld->set_field_type = TIFF_SETGET_C32_FLOAT; + fld->get_field_type = TIFF_SETGET_C32_FLOAT; + break; + case TIFF_SBYTE: + fld->set_field_type = TIFF_SETGET_C32_SINT8; + fld->get_field_type = TIFF_SETGET_C32_SINT8; + break; + case TIFF_SSHORT: + fld->set_field_type = TIFF_SETGET_C32_SINT16; + fld->get_field_type = TIFF_SETGET_C32_SINT16; + break; + case TIFF_SLONG: + fld->set_field_type = TIFF_SETGET_C32_SINT32; + fld->get_field_type = TIFF_SETGET_C32_SINT32; + break; + case TIFF_DOUBLE: + fld->set_field_type = TIFF_SETGET_C32_DOUBLE; + fld->get_field_type = TIFF_SETGET_C32_DOUBLE; + break; + case TIFF_IFD: + case TIFF_IFD8: + fld->set_field_type = TIFF_SETGET_C32_IFD8; + fld->get_field_type = TIFF_SETGET_C32_IFD8; + break; + case TIFF_LONG8: + fld->set_field_type = TIFF_SETGET_C32_UINT64; + fld->get_field_type = TIFF_SETGET_C32_UINT64; + break; + case TIFF_SLONG8: + fld->set_field_type = TIFF_SETGET_C32_SINT64; + fld->get_field_type = TIFF_SETGET_C32_SINT64; + break; + default: + fld->set_field_type = TIFF_SETGET_UNDEFINED; + fld->get_field_type = TIFF_SETGET_UNDEFINED; + break; + } + fld->field_bit = FIELD_CUSTOM; + fld->field_oktochange = TRUE; + fld->field_passcount = TRUE; + fld->field_name = (char *) _TIFFmalloc(32); + if (fld->field_name == NULL) { + _TIFFfree(fld); + return NULL; + } + fld->field_subfields = NULL; + + /* + * note that this name is a special sign to TIFFClose() and + * _TIFFSetupFields() to free the field + */ + sprintf(fld->field_name, "Tag %d", (int) tag); + + return fld; +} + +/**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the future + * libtiff versions. + ****************************************************************************/ + +static TIFFSetGetFieldType +_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount) +{ + if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) + return TIFF_SETGET_ASCII; + + else if (count == 1 && passcount == 0) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_UINT16; + case TIFF_LONG: + return TIFF_SETGET_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count >= 1 && passcount == 0) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C0_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C0_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C0_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C0_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C0_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C0_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C0_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C0_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C0_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C0_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C0_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C0_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE && passcount == 1) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C16_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C16_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C16_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C16_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C16_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C16_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C16_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C16_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C16_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C16_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C16_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C16_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE2 && passcount == 1) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C32_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C32_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C32_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C32_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C32_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C32_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C32_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C32_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C32_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C32_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C32_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C32_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + return TIFF_SETGET_UNDEFINED; +} + +int +TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n) +{ + static const char module[] = "TIFFMergeFieldInfo"; + static const char reason[] = "for fields array"; + TIFFField *tp; + size_t nfields; + uint32 i; + + if (tif->tif_nfieldscompat > 0) { + tif->tif_fieldscompat = (TIFFFieldArray *) + _TIFFCheckRealloc(tif, tif->tif_fieldscompat, + tif->tif_nfieldscompat + 1, + sizeof(TIFFFieldArray), reason); + } else { + tif->tif_fieldscompat = (TIFFFieldArray *) + _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray), + reason); + } + if (!tif->tif_fieldscompat) { + TIFFErrorExt(tif->tif_clientdata, module, + "Failed to allocate fields array"); + return -1; + } + nfields = tif->tif_nfieldscompat++; + + tif->tif_fieldscompat[nfields].type = tfiatOther; + tif->tif_fieldscompat[nfields].allocated_size = n; + tif->tif_fieldscompat[nfields].count = n; + tif->tif_fieldscompat[nfields].fields = + (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), + reason); + if (!tif->tif_fieldscompat[nfields].fields) { + TIFFErrorExt(tif->tif_clientdata, module, + "Failed to allocate fields array"); + return -1; + } + + tp = tif->tif_fieldscompat[nfields].fields; + for (i = 0; i < n; i++) { + tp->field_tag = info[i].field_tag; + tp->field_readcount = info[i].field_readcount; + tp->field_writecount = info[i].field_writecount; + tp->field_type = info[i].field_type; + tp->reserved = 0; + tp->set_field_type = + _TIFFSetGetType(info[i].field_type, + info[i].field_readcount, + info[i].field_passcount); + tp->get_field_type = + _TIFFSetGetType(info[i].field_type, + info[i].field_readcount, + info[i].field_passcount); + tp->field_bit = info[i].field_bit; + tp->field_oktochange = info[i].field_oktochange; + tp->field_passcount = info[i].field_passcount; + tp->field_name = info[i].field_name; + tp->field_subfields = NULL; + tp++; + } + + if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Setting up field info failed"); + return -1; + } + + return 0; +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirread.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirread.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirread.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirread.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,5600 @@ +/* $Id: tif_dirread.c,v 1.174 2012-02-01 02:24:47 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Read Support Routines. + */ + +/* Suggested pending improvements: + * - add a field 'ignore' to the TIFFDirEntry structure, to flag status, + * eliminating current use of the IGNORE value, and therefore eliminating + * current irrational behaviour on tags with tag id code 0 + * - add a field 'field_info' to the TIFFDirEntry structure, and set that with + * the pointer to the appropriate TIFFField structure early on in + * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. + */ + +#include "tiffiop.h" + +#define IGNORE 0 /* tag placeholder used below */ +#define FAILED_FII ((uint32) -1) + +#ifdef HAVE_IEEEFP +# define TIFFCvtIEEEFloatToNative(tif, n, fp) +# define TIFFCvtIEEEDoubleToNative(tif, n, dp) +#else +extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); +extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); +#endif + +enum TIFFReadDirEntryErr { + TIFFReadDirEntryErrOk = 0, + TIFFReadDirEntryErrCount = 1, + TIFFReadDirEntryErrType = 2, + TIFFReadDirEntryErrIo = 3, + TIFFReadDirEntryErrRange = 4, + TIFFReadDirEntryErrPsdif = 5, + TIFFReadDirEntryErrSizesan = 6, + TIFFReadDirEntryErrAlloc = 7, +}; + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +#if 0 +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +#endif + +static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); +static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value); +static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value); +static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); +static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value); +static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest); +static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover); + +static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); +static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid); +static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii); + +static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); +static void MissingRequired(TIFF*, const char*); +static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff); +static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); +static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff); +static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); +static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp); +static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); +static void ChopUpSingleUncompressedStrip(TIFF*); +static uint64 TIFFReadUInt64(const uint8 *value); + +typedef union _UInt64Aligned_t +{ + double d; + uint64 l; + uint32 i[2]; + uint16 s[4]; + uint8 c[8]; +} UInt64Aligned_t; + +/* + Unaligned safe copy of a uint64 value from an octet array. +*/ +static uint64 TIFFReadUInt64(const uint8 *value) +{ + UInt64Aligned_t result; + + result.c[0]=value[0]; + result.c[1]=value[1]; + result.c[2]=value[2]; + result.c[3]=value[3]; + result.c[4]=value[4]; + result.c[5]=value[5]; + result.c[6]=value[6]; + result.c[7]=value[7]; + + return result.l; +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + TIFFReadDirEntryCheckedByte(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteShort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteLong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeByteLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeByteSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + TIFFReadDirEntryCheckedShort(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortLong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeShortLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeShortSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + TIFFReadDirEntryCheckedLong(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLongLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLongSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Sbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Sshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Slong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); + return(err); + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLong8Slong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToFloat(m); +#else + *value=(float)m; +#endif + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + { + double m; + err=TIFFReadDirEntryCheckedRational(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SRATIONAL: + { + double m; + err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_FLOAT: + TIFFReadDirEntryCheckedFloat(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_DOUBLE: + { + double m; + err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToDouble(m); +#else + *value = (double)m; +#endif + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + err=TIFFReadDirEntryCheckedRational(tif,direntry,value); + return(err); + case TIFF_SRATIONAL: + err=TIFFReadDirEntryCheckedSrational(tif,direntry,value); + return(err); + case TIFF_FLOAT: + { + float m; + TIFFReadDirEntryCheckedFloat(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_DOUBLE: + err=TIFFReadDirEntryCheckedDouble(tif,direntry,value); + return(err); + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + case TIFF_IFD8: + err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); + return(err); + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) +{ + int typesize; + uint32 datasize; + void* data; + typesize=TIFFDataWidth(direntry->tdir_type); + if ((direntry->tdir_count==0)||(typesize==0)) + { + *value=0; + return(TIFFReadDirEntryErrOk); + } + (void) desttypesize; + + /* + * As a sanity check, make sure we have no more than a 2GB tag array + * in either the current data type or the dest data type. This also + * avoids problems with overflow of tmsize_t on 32bit systems. + */ + if ((uint64)(2147483647/typesize)tdir_count) + return(TIFFReadDirEntryErrSizesan); + if ((uint64)(2147483647/desttypesize)tdir_count) + return(TIFFReadDirEntryErrSizesan); + + *count=(uint32)direntry->tdir_count; + datasize=(*count)*typesize; + assert((tmsize_t)datasize>0); + data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); + if (data==0) + return(TIFFReadDirEntryErrAlloc); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (datasize<=4) + _TIFFmemcpy(data,&direntry->tdir_offset,datasize); + else + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + } + } + else + { + if (datasize<=8) + _TIFFmemcpy(data,&direntry->tdir_offset,datasize); + else + { + enum TIFFReadDirEntryErr err; + uint64 offset = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&offset); + err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + } + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint8* data; + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + *value=(uint8*)origdata; + return(TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8* m; + uint32 n; + m=(int8*)origdata; + for (n=0; ntdir_type) + { + case TIFF_SHORT: + { + uint16* ma; + uint8* mb; + uint32 n; + ma=(uint16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + err=TIFFReadDirEntryCheckRangeByteShort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint8* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeByteSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + uint8* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeByteLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint8* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeByteSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint8* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeByteLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint8* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeByteSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int8* data; + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + { + uint8* m; + uint32 n; + m=(uint8*)origdata; + for (n=0; ntdir_type) + { + case TIFF_SHORT: + { + uint16* ma; + int8* mb; + uint32 n; + ma=(uint16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int8* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + int8* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeSbyteLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int8* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int8* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int8* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint16* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + *value=(uint16*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16* m; + uint32 n; + m=(int16*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)m); + err=TIFFReadDirEntryCheckRangeShortSshort(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint16*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint16*)_TIFFmalloc(count*2); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint16* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeShortLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint16* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeShortSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint16* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeShortLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint16* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeShortSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int16* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16* m; + uint32 n; + m=(uint16*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(m); + err=TIFFReadDirEntryCheckRangeSshortShort(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int16*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + *value=(int16*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort((uint16*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int16*)_TIFFmalloc(count*2); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int16* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeSshortLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int16* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeSshortSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int16* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSshortLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int16* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint32* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + *value=(uint32*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32* m; + uint32 n; + m=(int32*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)m); + err=TIFFReadDirEntryCheckRangeLongSlong(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint32*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint32*)_TIFFmalloc(count*4); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint32* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint32* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeLongSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint32* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeLongLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint32* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeLongSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int32* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + { + uint32* m; + uint32 n; + m=(uint32*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)m); + err=TIFFReadDirEntryCheckRangeSlongLong(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int32*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + *value=(int32*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int32*)_TIFFmalloc(count*4); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int32* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int32* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int32* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSlongLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int32* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int32)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint64* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + *value=(uint64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG8: + { + int64* m; + uint32 n; + m=(int64*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)m); + err=TIFFReadDirEntryCheckRangeLong8Slong8(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint64*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint64* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint64* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + uint64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint64* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeLong8Slong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int64* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + { + uint64* m; + uint32 n; + m=(uint64*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(m); + err=TIFFReadDirEntryCheckRangeSlong8Long8(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int64*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + *value=(int64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int64* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int64* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + int64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int64* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(int64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + float* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_FLOAT: + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata); + *value=(float*)origdata; + return(TIFFReadDirEntryErrOk); + } + data=(float*)_TIFFmalloc(count*sizeof(float)); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + float* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + float* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + float* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + float* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToFloat(*ma++); +#else + *mb++ = (float)(*ma++); +#endif + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + float* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32* ma; + uint32 maa; + uint32 mab; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(float)maa/(float)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32* ma; + int32 maa; + uint32 mab; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*(int32*)ma; + ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(float)maa/(float)mab; + } + } + break; + case TIFF_DOUBLE: + { + double* ma; + float* mb; + uint32 n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); + ma=(double*)origdata; + mb=data; + for (n=0; ntdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_DOUBLE: + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); + *value=(double*)origdata; + return(TIFFReadDirEntryErrOk); + } + data=(double*)_TIFFmalloc(count*sizeof(double)); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + double* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + double* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + double* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + double* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToDouble(*ma++); +#else + *mb++ = (double)(*ma++); +#endif + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + double* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32* ma; + uint32 maa; + uint32 mab; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(double)maa/(double)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32* ma; + int32 maa; + uint32 mab; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*(int32*)ma; + ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(double)maa/(double)mab; + } + } + break; + case TIFF_FLOAT: + { + float* ma; + double* mb; + uint32 n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)origdata,count); + TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata); + ma=(float*)origdata; + mb=data; + for (n=0; ntdir_type) + { + case TIFF_LONG: + case TIFF_LONG8: + case TIFF_IFD: + case TIFF_IFD8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + case TIFF_IFD8: + *value=(uint64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(*value,count); + return(TIFFReadDirEntryErrOk); + } + data=(uint64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32* ma; + uint64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(uint64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + enum TIFFReadDirEntryErr err; + uint16* m; + uint16* na; + uint16 nb; + if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) + return(TIFFReadDirEntryErrCount); + err=TIFFReadDirEntryShortArray(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + na=m; + nb=tif->tif_dir.td_samplesperpixel; + *value=*na++; + nb--; + while (nb>0) + { + if (*na++!=*value) + { + err=TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfree(m); + return(err); +} + +#if 0 +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + enum TIFFReadDirEntryErr err; + double* m; + double* na; + uint16 nb; + if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) + return(TIFFReadDirEntryErrCount); + err=TIFFReadDirEntryDoubleArray(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + na=m; + nb=tif->tif_dir.td_samplesperpixel; + *value=*na++; + nb--; + while (nb>0) + { + if (*na++!=*value) + { + err=TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfree(m); + return(err); +} +#endif + +static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +{ + (void) tif; + *value=*(uint8*)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value) +{ + (void) tif; + *value=*(int8*)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + *value = direntry->tdir_offset.toff_short; + /* *value=*(uint16*)(&direntry->tdir_offset); */ + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(value); +} + +static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value) +{ + *value=*(int16*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)value); +} + +static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) +{ + *value=*(uint32*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(value); +} + +static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value) +{ + *value=*(int32*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)value); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + *value = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value) +{ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + *value=*(int64*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + UInt64Aligned_t m; + + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(uint32)==4); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if (m.i[0]==0) + *value=0.0; + else + *value=(double)m.i[0]/(double)m.i[1]; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + UInt64Aligned_t m; + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(int32)==4); + assert(sizeof(uint32)==4); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + m.l=direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if ((int32)m.i[0]==0) + *value=0.0; + else + *value=(double)((int32)m.i[0])/(double)m.i[1]; + return(TIFFReadDirEntryErrOk); +} + +static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +{ + union + { + float f; + uint32 i; + } float_union; + assert(sizeof(float)==4); + assert(sizeof(uint32)==4); + assert(sizeof(float_union)==4); + float_union.i=*(uint32*)(&direntry->tdir_offset); + *value=float_union.f; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)value); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(UInt64Aligned_t)==8); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + { + UInt64Aligned_t uint64_union; + uint64_union.l=direntry->tdir_offset.toff_long8; + *value=uint64_union.d; + } + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value) +{ + if (value>0xFFFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value) +{ + if ((value<0)||(value>0xFFFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value) +{ + if (value>0xFFFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value) +{ + if ((value<0)||(value>0xFFFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value) +{ + if ((value<-0x8000)||(value>0x7FFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value) +{ + if ((value<-0x8000)||(value>0x7FFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +/* + * Largest 32-bit unsigned integer value. + */ +#if defined(__WIN32__) && defined(_MSC_VER) +# define TIFF_UINT32_MAX 0xFFFFFFFFI64 +#else +# define TIFF_UINT32_MAX 0xFFFFFFFFLL +#endif + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongLong8(uint64 value) +{ + if (value > TIFF_UINT32_MAX) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong8(int64 value) +{ + if ((value<0) || (value > TIFF_UINT32_MAX)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +#undef TIFF_UINT32_MAX + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong(uint32 value) +{ + if (value > 0x7FFFFFFFUL) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong8(uint64 value) +{ + if (value > 0x7FFFFFFFUL) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongSlong8(int64 value) +{ + if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sshort(int16 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong(int32 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong8(int64 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +/* + * Largest 64-bit signed integer value. + */ +#if defined(__WIN32__) && defined(_MSC_VER) +# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64 +#else +# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL +#endif + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value) +{ + if (value > TIFF_INT64_MAX) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +#undef TIFF_INT64_MAX + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest) +{ + assert(size>0); + if (!isMapped(tif)) { + if (!SeekOK(tif,offset)) + return(TIFFReadDirEntryErrIo); + if (!ReadOK(tif,dest,size)) + return(TIFFReadDirEntryErrIo); + } else { + tmsize_t ma,mb; + ma=(tmsize_t)offset; + mb=ma+size; + if (((uint64)ma!=offset)||(mbtif->tif_size)) + return(TIFFReadDirEntryErrIo); + _TIFFmemcpy(dest,tif->tif_base+ma,size); + } + return(TIFFReadDirEntryErrOk); +} + +static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover) +{ + if (!recover) { + switch (err) { + case TIFFReadDirEntryErrCount: + TIFFErrorExt(tif->tif_clientdata, module, + "Incorrect count for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFErrorExt(tif->tif_clientdata, module, + "Incompatible type for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFErrorExt(tif->tif_clientdata, module, + "IO error during reading of \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFErrorExt(tif->tif_clientdata, module, + "Incorrect value for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle different values per sample for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on size of \"%s\" value failed", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFErrorExt(tif->tif_clientdata, module, + "Out of memory reading of \"%s\"", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } else { + switch (err) { + case TIFFReadDirEntryErrCount: + TIFFErrorExt(tif->tif_clientdata, module, + "Incorrect count for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFWarningExt(tif->tif_clientdata, module, + "Incompatible type for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFWarningExt(tif->tif_clientdata, module, + "IO error during reading of \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFWarningExt(tif->tif_clientdata, module, + "Incorrect value for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFWarningExt(tif->tif_clientdata, module, + "Cannot handle different values per sample for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFWarningExt(tif->tif_clientdata, module, + "Sanity check on size of \"%s\" value failed; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFWarningExt(tif->tif_clientdata, module, + "Out of memory reading of \"%s\"; tag ignored", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } +} + +/* + * Read the next TIFF directory from a file and convert it to the internal + * format. We read directories sequentially. + */ +int +TIFFReadDirectory(TIFF* tif) +{ + static const char module[] = "TIFFReadDirectory"; + TIFFDirEntry* dir; + uint16 dircount; + TIFFDirEntry* dp; + uint16 di; + const TIFFField* fip; + uint32 fii=FAILED_FII; + toff_t nextdiroff; + tif->tif_diroff=tif->tif_nextdiroff; + if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) + return 0; /* last offset or bad offset (IFD looping) */ + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + tif->tif_curdir++; + nextdiroff = tif->tif_nextdiroff; + dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff); + if (!dircount) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff); + return 0; + } + TIFFReadDirectoryCheckOrder(tif,dir,dircount); + + /* + * Mark duplicates of any tag to be ignored (bugzilla 1994) + * to avoid certain pathological problems. + */ + { + TIFFDirEntry* ma; + uint16 mb; + for (ma=dir, mb=0; mbtdir_tag==na->tdir_tag) + na->tdir_tag=IGNORE; + } + } + } + + tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ + tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ + /* free any old stuff and reinit */ + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + /* + * Electronic Arts writes gray-scale TIFF files + * without a PlanarConfiguration directory entry. + * Thus we setup a default value here, even though + * the TIFF spec says there is no default value. + */ + TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); + /* + * Setup default value and then make a pass over + * the fields to check type and tag information, + * and to extract info required to size data + * structures. A second pass is made afterwards + * to read in everthing not taken in the first pass. + * But we must process the Compression tag first + * in order to merge in codec-private tag definitions (otherwise + * we may get complaints about unknown tags). However, the + * Compression tag may be dependent on the SamplesPerPixel + * tag value because older TIFF specs permited Compression + * to be written as a SamplesPerPixel-count tag entry. + * Thus if we don't first figure out the correct SamplesPerPixel + * tag value then we may end up ignoring the Compression tag + * value because it has an incorrect count value (if the + * true value of SamplesPerPixel is not 1). + */ + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL); + if (dp) + { + if (!TIFFFetchNormalTag(tif,dp,0)) + goto bad; + dp->tdir_tag=IGNORE; + } + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION); + if (dp) + { + /* + * The 5.0 spec says the Compression tag has one value, while + * earlier specs say it has one value per sample. Because of + * this, we accept the tag if one value is supplied with either + * count. + */ + uint16 value; + enum TIFFReadDirEntryErr err; + err=TIFFReadDirEntryShort(tif,dp,&value); + if (err==TIFFReadDirEntryErrCount) + err=TIFFReadDirEntryPersampleShort(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0); + goto bad; + } + if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value)) + goto bad; + dp->tdir_tag=IGNORE; + } + else + { + if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE)) + goto bad; + } + /* + * First real pass over the directory. + */ + for (di=0, dp=dir; ditdir_tag!=IGNORE) + { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + if (fii == FAILED_FII) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Unknown field with tag %d (0x%x) encountered", + dp->tdir_tag,dp->tdir_tag); + /* the following knowingly leaks the + anonymous field structure */ + if (!_TIFFMergeFields(tif, + _TIFFCreateAnonField(tif, + dp->tdir_tag, + (TIFFDataType) dp->tdir_type), + 1)) { + TIFFWarningExt(tif->tif_clientdata, + module, + "Registering anonymous field with tag %d (0x%x) failed", + dp->tdir_tag, + dp->tdir_tag); + dp->tdir_tag=IGNORE; + } else { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + assert(fii != FAILED_FII); + } + } + } + if (dp->tdir_tag!=IGNORE) + { + fip=tif->tif_fields[fii]; + if (fip->field_bit==FIELD_IGNORE) + dp->tdir_tag=IGNORE; + else + { + switch (dp->tdir_tag) + { + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + case TIFFTAG_TILEBYTECOUNTS: + TIFFSetFieldBit(tif,fip->field_bit); + break; + case TIFFTAG_IMAGEWIDTH: + case TIFFTAG_IMAGELENGTH: + case TIFFTAG_IMAGEDEPTH: + case TIFFTAG_TILELENGTH: + case TIFFTAG_TILEWIDTH: + case TIFFTAG_TILEDEPTH: + case TIFFTAG_PLANARCONFIG: + case TIFFTAG_ROWSPERSTRIP: + case TIFFTAG_EXTRASAMPLES: + if (!TIFFFetchNormalTag(tif,dp,0)) + goto bad; + dp->tdir_tag=IGNORE; + break; + } + } + } + } + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) planarconfig tag says it's separate, + * c) strip offsets/bytecounts tag are both present and + * d) both contain exactly one value, then we consistently find + * that the buggy implementation of the buggy compression scheme + * matches contig planarconfig best. So we 'fix-up' the tag here + */ + if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&& + (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE)) + { + if (!_TIFFFillStriles(tif)) + goto bad; + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS); + if ((dp!=0)&&(dp->tdir_count==1)) + { + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount, + TIFFTAG_STRIPBYTECOUNTS); + if ((dp!=0)&&(dp->tdir_count==1)) + { + tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG; + TIFFWarningExt(tif->tif_clientdata,module, + "Planarconfig tag value assumed incorrect, " + "assuming data is contig instead of chunky"); + } + } + } + /* + * Allocate directory structure and setup defaults. + */ + if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) + { + MissingRequired(tif,"ImageLength"); + goto bad; + } + /* + * Setup appropriate structures (by strip or by tile) + */ + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { + tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); + tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; + tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; + tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; + tif->tif_flags &= ~TIFF_ISTILED; + } else { + tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_flags |= TIFF_ISTILED; + } + if (!tif->tif_dir.td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle zero number of %s", + isTiled(tif) ? "tiles" : "strips"); + goto bad; + } + tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) + tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; + if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { + if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && + (isTiled(tif)==0) && + (tif->tif_dir.td_nstrips==1)) { + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) it's not a tiled TIFF, + * and c) the number of strips is 1, + * then we tolerate the absence of stripoffsets tag, + * because, presumably, all required data is in the + * JpegInterchangeFormat stream. + */ + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + } else { + MissingRequired(tif, + isTiled(tif) ? "TileOffsets" : "StripOffsets"); + goto bad; + } + } + /* + * Second pass: extract other information. + */ + for (di=0, dp=dir; ditdir_tag) + { + case IGNORE: + break; + case TIFFTAG_MINSAMPLEVALUE: + case TIFFTAG_MAXSAMPLEVALUE: + case TIFFTAG_BITSPERSAMPLE: + case TIFFTAG_DATATYPE: + case TIFFTAG_SAMPLEFORMAT: + /* + * The MinSampleValue, MaxSampleValue, BitsPerSample + * DataType and SampleFormat tags are supposed to be + * written as one value/sample, but some vendors + * incorrectly write one value only -- so we accept + * that as well (yech). Other vendors write correct + * value for NumberOfSamples, but incorrect one for + * BitsPerSample and friends, and we will read this + * too. + */ + { + uint16 value; + enum TIFFReadDirEntryErr err; + err=TIFFReadDirEntryShort(tif,dp,&value); + if (err==TIFFReadDirEntryErrCount) + err=TIFFReadDirEntryPersampleShort(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); + goto bad; + } + if (!TIFFSetField(tif,dp->tdir_tag,value)) + goto bad; + } + break; + case TIFFTAG_SMINSAMPLEVALUE: + case TIFFTAG_SMAXSAMPLEVALUE: + { + + double *data; + enum TIFFReadDirEntryErr err; + uint32 saved_flags; + int m; + if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); + goto bad; + } + saved_flags = tif->tif_flags; + tif->tif_flags |= TIFF_PERSAMPLE; + m = TIFFSetField(tif,dp->tdir_tag,data); + tif->tif_flags = saved_flags; + _TIFFfree(data); + if (!m) + goto bad; + } + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: +#if defined(DEFER_STRILE_LOAD) + _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), + dp, sizeof(TIFFDirEntry) ); +#else + if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset)) + goto bad; +#endif + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: +#if defined(DEFER_STRILE_LOAD) + _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), + dp, sizeof(TIFFDirEntry) ); +#else + if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) + goto bad; +#endif + break; + case TIFFTAG_COLORMAP: + case TIFFTAG_TRANSFERFUNCTION: + { + enum TIFFReadDirEntryErr err; + uint32 countpersample; + uint32 countrequired; + uint32 incrementpersample; + uint16* value=NULL; + countpersample=(1L<tif_dir.td_bitspersample); + if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) + { + countrequired=countpersample; + incrementpersample=0; + } + else + { + countrequired=3*countpersample; + incrementpersample=countpersample; + } + if (dp->tdir_count!=(uint64)countrequired) + err=TIFFReadDirEntryErrCount; + else + err=TIFFReadDirEntryShortArray(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1); + } + else + { + TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample); + _TIFFfree(value); + } + } + break; +/* BEGIN REV 4.0 COMPATIBILITY */ + case TIFFTAG_OSUBFILETYPE: + { + uint16 valueo; + uint32 value; + if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk) + { + switch (valueo) + { + case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break; + case OFILETYPE_PAGE: value=FILETYPE_PAGE; break; + default: value=0; break; + } + if (value!=0) + TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value); + } + } + break; +/* END REV 4.0 COMPATIBILITY */ + default: + (void) TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } + /* + * OJPEG hack: + * - If a) compression is OJPEG, and b) photometric tag is missing, + * then we consistently find that photometric should be YCbCr + * - If a) compression is OJPEG, and b) photometric tag says it's RGB, + * then we consistently find that the buggy implementation of the + * buggy compression scheme matches photometric YCbCr instead. + * - If a) compression is OJPEG, and b) bitspersample tag is missing, + * then we consistently find bitspersample should be 8. + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is RGB or YCbCr, then we consistently find + * samplesperpixel should be 3 + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is MINISWHITE or MINISBLACK, then we consistently + * find samplesperpixel should be 3 + */ + if (tif->tif_dir.td_compression==COMPRESSION_OJPEG) + { + if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Photometric tag is missing, assuming data is YCbCr"); + if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR)) + goto bad; + } + else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) + { + tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR; + TIFFWarningExt(tif->tif_clientdata, module, + "Photometric tag value assumed incorrect, " + "assuming data is YCbCr instead of RGB"); + } + if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) + { + TIFFWarningExt(tif->tif_clientdata,module, + "BitsPerSample tag is missing, assuming 8 bits per sample"); + if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8)) + goto bad; + } + if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) + { + if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) + { + TIFFWarningExt(tif->tif_clientdata,module, + "SamplesPerPixel tag is missing, " + "assuming correct SamplesPerPixel value is 3"); + if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) + goto bad; + } + if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR) + { + TIFFWarningExt(tif->tif_clientdata,module, + "SamplesPerPixel tag is missing, " + "applying correct SamplesPerPixel value of 3"); + if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) + goto bad; + } + else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE) + || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK)) + { + /* + * SamplesPerPixel tag is missing, but is not required + * by spec. Assume correct SamplesPerPixel value of 1. + */ + if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1)) + goto bad; + } + } + } + /* + * Verify Palette image has a Colormap. + */ + if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && + !TIFFFieldSet(tif, FIELD_COLORMAP)) { + if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3) + tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; + else if (tif->tif_dir.td_bitspersample>=8) + tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; + else { + MissingRequired(tif, "Colormap"); + goto bad; + } + } + /* + * OJPEG hack: + * We do no further messing with strip/tile offsets/bytecounts in OJPEG + * TIFFs + */ + if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG) + { + /* + * Attempt to deal with a missing StripByteCounts tag. + */ + if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { + /* + * Some manufacturers violate the spec by not giving + * the size of the strips. In this case, assume there + * is one uncompressed strip of data. + */ + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 1) || + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && + tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) { + MissingRequired(tif, "StripByteCounts"); + goto bad; + } + TIFFWarningExt(tif->tif_clientdata, module, + "TIFF directory is missing required " + "\"StripByteCounts\" field, calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + /* + * Assume we have wrong StripByteCount value (in case + * of single strip) in following cases: + * - it is equal to zero along with StripOffset; + * - it is larger than file itself (in case of uncompressed + * image); + * - it is smaller than the size of the bytes per row + * multiplied on the number of rows. The last case should + * not be checked in the case of writing new image, + * because we may do not know the exact strip size + * until the whole image will be written and directory + * dumped out. + */ + #define BYTECOUNTLOOKSBAD \ + ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \ + (tif->tif_dir.td_compression == COMPRESSION_NONE && \ + tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \ + (tif->tif_mode == O_RDONLY && \ + tif->tif_dir.td_compression == COMPRESSION_NONE && \ + tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) ) + + } else if (tif->tif_dir.td_nstrips == 1 + && _TIFFFillStriles(tif) + && tif->tif_dir.td_stripoffset[0] != 0 + && BYTECOUNTLOOKSBAD) { + /* + * XXX: Plexus (and others) sometimes give a value of + * zero for a tag when they don't know what the + * correct value is! Try and handle the simple case + * of estimating the size of a one strip image. + */ + TIFFWarningExt(tif->tif_clientdata, module, + "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength"); + if(EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + +#if !defined(DEFER_STRILE_LOAD) + } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG + && tif->tif_dir.td_nstrips > 2 + && tif->tif_dir.td_compression == COMPRESSION_NONE + && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1] + && tif->tif_dir.td_stripbytecount[0] != 0 + && tif->tif_dir.td_stripbytecount[1] != 0 ) { + /* + * XXX: Some vendors fill StripByteCount array with + * absolutely wrong values (it can be equal to + * StripOffset array, for example). Catch this case + * here. + * + * We avoid this check if deferring strile loading + * as it would always force us to load the strip/tile + * information. + */ + TIFFWarningExt(tif->tif_clientdata, module, + "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; +#endif /* !defined(DEFER_STRILE_LOAD) */ + } + } + if (dir) + { + _TIFFfree(dir); + dir=NULL; + } + if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + { + if (tif->tif_dir.td_bitspersample>=16) + tif->tif_dir.td_maxsamplevalue=0xFFFF; + else + tif->tif_dir.td_maxsamplevalue = (uint16)((1L<tif_dir.td_bitspersample)-1); + } + /* + * XXX: We can optimize checking for the strip bounds using the sorted + * bytecounts array. See also comments for TIFFAppendToStrip() + * function in tif_write.c. + */ +#if !defined(DEFER_STRILE_LOAD) + if (tif->tif_dir.td_nstrips > 1) { + uint32 strip; + + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { + if (tif->tif_dir.td_stripoffset[strip - 1] > + tif->tif_dir.td_stripoffset[strip]) { + tif->tif_dir.td_stripbytecountsorted = 0; + break; + } + } + } +#endif /* !defined(DEFER_STRILE_LOAD) */ + + /* + * An opportunity for compression mode dependent tag fixup + */ + (*tif->tif_fixuptags)(tif); + + /* + * Some manufacturers make life difficult by writing + * large amounts of uncompressed data as a single strip. + * This is contrary to the recommendations of the spec. + * The following makes an attempt at breaking such images + * into strips closer to the recommended 8k bytes. A + * side effect, however, is that the RowsPerStrip tag + * value may be changed. + */ + if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& + (tif->tif_dir.td_nstrips==1)&& + (tif->tif_dir.td_compression==COMPRESSION_NONE)&& + ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP)) + { + if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount ) + return 0; + ChopUpSingleUncompressedStrip(tif); + } + + /* + * Clear the dirty directory flag. + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + + /* + * Reinitialize i/o since we are starting on a new directory. + */ + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; + tif->tif_col = (uint32) -1; + tif->tif_curtile = (uint32) -1; + tif->tif_tilesize = (tmsize_t) -1; + + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (!tif->tif_scanlinesize) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle zero scanline size"); + return (0); + } + + if (isTiled(tif)) { + tif->tif_tilesize = TIFFTileSize(tif); + if (!tif->tif_tilesize) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle zero tile size"); + return (0); + } + } else { + if (!TIFFStripSize(tif)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle zero strip size"); + return (0); + } + } + return (1); +bad: + if (dir) + _TIFFfree(dir); + return (0); +} + +static void +TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +{ + static const char module[] = "TIFFReadDirectoryCheckOrder"; + uint16 m; + uint16 n; + TIFFDirEntry* o; + m=0; + for (n=0, o=dir; ntdir_tagtif_clientdata,module, + "Invalid TIFF directory; tags are not sorted in ascending order"); + break; + } + m=o->tdir_tag+1; + } +} + +static TIFFDirEntry* +TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid) +{ + TIFFDirEntry* m; + uint16 n; + (void) tif; + for (m=dir, n=0; ntdir_tag==tagid) + return(m); + } + return(0); +} + +static void +TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii) +{ + int32 ma,mb,mc; + ma=-1; + mc=(int32)tif->tif_nfields; + while (1) + { + if (ma+1==mc) + { + *fii = FAILED_FII; + return; + } + mb=(ma+mc)/2; + if (tif->tif_fields[mb]->field_tag==(uint32)tagid) + break; + if (tif->tif_fields[mb]->field_tag<(uint32)tagid) + ma=mb; + else + mc=mb; + } + while (1) + { + if (mb==0) + break; + if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid) + break; + mb--; + } + *fii=mb; +} + +/* + * Read custom directory from the arbitarry offset. + * The code is very similar to TIFFReadDirectory(). + */ +int +TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, + const TIFFFieldArray* infoarray) +{ + static const char module[] = "TIFFReadCustomDirectory"; + TIFFDirEntry* dir; + uint16 dircount; + TIFFDirEntry* dp; + uint16 di; + const TIFFField* fip; + uint32 fii; + _TIFFSetupFields(tif, infoarray); + dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL); + if (!dircount) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff); + return 0; + } + TIFFFreeDirectory(tif); + _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); + TIFFReadDirectoryCheckOrder(tif,dir,dircount); + for (di=0, dp=dir; ditdir_tag,&fii); + if (fii == FAILED_FII) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Unknown field with tag %d (0x%x) encountered", + dp->tdir_tag, dp->tdir_tag); + if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif, + dp->tdir_tag, + (TIFFDataType) dp->tdir_type), + 1)) { + TIFFWarningExt(tif->tif_clientdata, module, + "Registering anonymous field with tag %d (0x%x) failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_tag=IGNORE; + } else { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + assert( fii != FAILED_FII ); + } + } + if (dp->tdir_tag!=IGNORE) + { + fip=tif->tif_fields[fii]; + if (fip->field_bit==FIELD_IGNORE) + dp->tdir_tag=IGNORE; + else + { + /* check data type */ + while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type)) + { + fii++; + if ((fii==tif->tif_nfields)|| + (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag)) + { + fii=0xFFFF; + break; + } + fip=tif->tif_fields[fii]; + } + if (fii==0xFFFF) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Wrong data type %d for \"%s\"; tag ignored", + dp->tdir_type,fip->field_name); + dp->tdir_tag=IGNORE; + } + else + { + /* check count if known in advance */ + if ((fip->field_readcount!=TIFF_VARIABLE)&& + (fip->field_readcount!=TIFF_VARIABLE2)) + { + uint32 expected; + if (fip->field_readcount==TIFF_SPP) + expected=(uint32)tif->tif_dir.td_samplesperpixel; + else + expected=(uint32)fip->field_readcount; + if (!CheckDirCount(tif,dp,expected)) + dp->tdir_tag=IGNORE; + } + } + } + switch (dp->tdir_tag) + { + case IGNORE: + break; + case EXIFTAG_SUBJECTDISTANCE: + (void) TIFFFetchSubjectDistance(tif,dp); + break; + default: + (void) TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } + } + if (dir) + _TIFFfree(dir); + return 1; +} + +/* + * EXIF is important special case of custom IFD, so we have a special + * function to read it. + */ +int +TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff) +{ + const TIFFFieldArray* exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); +} + +static int +EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +{ + static const char module[] = "EstimateStripByteCounts"; + + TIFFDirEntry *dp; + TIFFDirectory *td = &tif->tif_dir; + uint32 strip; + + _TIFFFillStriles( tif ); + + if (td->td_stripbytecount) + _TIFFfree(td->td_stripbytecount); + td->td_stripbytecount = (uint64*) + _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), + "for \"StripByteCounts\" array"); + if( td->td_stripbytecount == NULL ) + return -1; + + if (td->td_compression != COMPRESSION_NONE) { + uint64 space; + uint64 filesize; + uint16 n; + filesize = TIFFGetFileSize(tif); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + space=sizeof(TIFFHeaderClassic)+2+dircount*12+4; + else + space=sizeof(TIFFHeaderBig)+8+dircount*20+8; + /* calculate amount of space used by indirect values */ + for (dp = dir, n = dircount; n > 0; n--, dp++) + { + uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); + uint64 datasize; + typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); + if (typewidth == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot determine size of unknown tag type %d", + dp->tdir_type); + return -1; + } + datasize=(uint64)typewidth*dp->tdir_count; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (datasize<=4) + datasize=0; + } + else + { + if (datasize<=8) + datasize=0; + } + space+=datasize; + } + space = filesize - space; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + space /= td->td_samplesperpixel; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount[strip] = space; + /* + * This gross hack handles the case were the offset to + * the last strip is past the place where we think the strip + * should begin. Since a strip of data must be contiguous, + * it's safe to assume that we've overestimated the amount + * of data in the strip and trim this number back accordingly. + */ + strip--; + if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize) + td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip]; + } else if (isTiled(tif)) { + uint64 bytespertile = TIFFTileSize64(tif); + + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount[strip] = bytespertile; + } else { + uint64 rowbytes = TIFFScanlineSize64(tif); + uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount[strip] = rowbytes * rowsperstrip; + } + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + td->td_rowsperstrip = td->td_imagelength; + return 1; +} + +static void +MissingRequired(TIFF* tif, const char* tagname) +{ + static const char module[] = "MissingRequired"; + + TIFFErrorExt(tif->tif_clientdata, module, + "TIFF directory is missing required \"%s\" field", + tagname); +} + +/* + * Check the directory offset against the list of already seen directory + * offsets. This is a trick to prevent IFD looping. The one can create TIFF + * file with looped directory pointers. We will maintain a list of already + * seen directories and check every IFD offset against that list. + */ +static int +TIFFCheckDirOffset(TIFF* tif, uint64 diroff) +{ + uint16 n; + + if (diroff == 0) /* no more directories */ + return 0; + + for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) { + if (tif->tif_dirlist[n] == diroff) + return 0; + } + + tif->tif_dirnumber++; + + if (tif->tif_dirnumber > tif->tif_dirlistsize) { + uint64* new_dirlist; + + /* + * XXX: Reduce memory allocation granularity of the dirlist + * array. + */ + new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist, + tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list"); + if (!new_dirlist) + return 0; + tif->tif_dirlistsize = 2 * tif->tif_dirnumber; + tif->tif_dirlist = new_dirlist; + } + + tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff; + + return 1; +} + +/* + * Check the count field of a directory entry against a known value. The + * caller is expected to skip/ignore the tag if there is a mismatch. + */ +static int +CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) +{ + if ((uint64)count > dir->tdir_count) { + const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + return (0); + } else if ((uint64)count < dir->tdir_count) { + const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + dir->tdir_count = count; + return (1); + } + return (1); +} + +/* + * Read IFD structure from the specified offset. If the pointer to + * nextdiroff variable has been specified, read it too. Function returns a + * number of fields in the directory or 0 if failed. + */ +static uint16 +TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, + uint64 *nextdiroff) +{ + static const char module[] = "TIFFFetchDirectory"; + + void* origdir; + uint16 dircount16; + uint32 dirsize; + TIFFDirEntry* dir; + uint8* ma; + TIFFDirEntry* mb; + uint16 n; + + assert(pdir); + + tif->tif_diroff = diroff; + if (nextdiroff) + *nextdiroff = 0; + if (!isMapped(tif)) { + if (!SeekOK(tif, tif->tif_diroff)) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount16, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } else { + uint64 dircount64; + if (!ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16)dircount64; + dirsize = 20; + } + origdir = _TIFFCheckMalloc(tif, dircount16, + dirsize, "to read TIFF directory"); + if (origdir == NULL) + return 0; + if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%.100s: Can not read TIFF directory", + tif->tif_name); + _TIFFfree(origdir); + return 0; + } + /* + * Read offset to next directory for sequential scans if + * needed. + */ + if (nextdiroff) + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdiroff32; + if (!ReadOK(tif, &nextdiroff32, sizeof(uint32))) + nextdiroff32 = 0; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff=nextdiroff32; + } else { + if (!ReadOK(tif, nextdiroff, sizeof(uint64))) + *nextdiroff = 0; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } else { + tmsize_t m; + tmsize_t off = (tmsize_t) tif->tif_diroff; + if ((uint64)off!=tif->tif_diroff) + { + TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count"); + return(0); + } + + /* + * Check for integer overflow when validating the dir_off, + * otherwise a very high offset may cause an OOB read and + * crash the client. Make two comparisons instead of + * + * off + sizeof(uint16) > tif->tif_size + * + * to avoid overflow. + */ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + m=off+sizeof(uint16); + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory count"); + return 0; + } else { + _TIFFmemcpy(&dircount16, tif->tif_base + off, + sizeof(uint16)); + } + off += sizeof (uint16); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } + else + { + tmsize_t m; + uint64 dircount64; + m=off+sizeof(uint64); + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory count"); + return 0; + } else { + _TIFFmemcpy(&dircount64, tif->tif_base + off, + sizeof(uint64)); + } + off += sizeof (uint64); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16)dircount64; + dirsize = 20; + } + if (dircount16 == 0 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, zero tag directories not supported"); + return 0; + } + origdir = _TIFFCheckMalloc(tif, dircount16, + dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + m=off+dircount16*dirsize; + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory"); + _TIFFfree(origdir); + return 0; + } else { + _TIFFmemcpy(origdir, tif->tif_base + off, + dircount16 * dirsize); + } + if (nextdiroff) { + off += dircount16 * dirsize; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdiroff32; + m=off+sizeof(uint32); + if ((mtif->tif_size)) + nextdiroff32 = 0; + else + _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, + sizeof (uint32)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + m=off+sizeof(uint64); + if ((mtif->tif_size)) + *nextdiroff = 0; + else + _TIFFmemcpy(nextdiroff, tif->tif_base + off, + sizeof (uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } + dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16, + sizeof(TIFFDirEntry), + "to read TIFF directory"); + if (dir==0) + { + _TIFFfree(origdir); + return 0; + } + ma=(uint8*)origdir; + mb=dir; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + mb->tdir_tag=*(uint16*)ma; + ma+=sizeof(uint16); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + mb->tdir_type=*(uint16*)ma; + ma+=sizeof(uint16); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + mb->tdir_count=(uint64)(*(uint32*)ma); + ma+=sizeof(uint32); + *(uint32*)(&mb->tdir_offset)=*(uint32*)ma; + ma+=sizeof(uint32); + } + else + { + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + mb->tdir_count=TIFFReadUInt64(ma); + ma+=sizeof(uint64); + mb->tdir_offset.toff_long8=TIFFReadUInt64(ma); + ma+=sizeof(uint64); + } + mb++; + } + _TIFFfree(origdir); + *pdir = dir; + return dircount16; +} + +/* + * Fetch a tag that is not handled by special case code. + */ +static int +TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) +{ + static const char module[] = "TIFFFetchNormalTag"; + enum TIFFReadDirEntryErr err; + uint32 fii; + const TIFFField* fip = NULL; + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + if( fii == FAILED_FII ) + { + TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag", + "No definition found for tag %d", + dp->tdir_tag); + return 0; + } + fip=tif->tif_fields[fii]; + assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */ + assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */ + err=TIFFReadDirEntryErrOk; + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: + break; + case TIFF_SETGET_ASCII: + { + uint8* data; + assert(fip->field_passcount==0); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + uint8* ma; + uint32 mb; + int n; + ma=data; + mb=0; + while (mb<(uint32)dp->tdir_count) + { + if (*ma==0) + break; + ma++; + mb++; + } + if (mb+1<(uint32)dp->tdir_count) + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); + else if (mb+1>(uint32)dp->tdir_count) + { + uint8* o; + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); + if ((uint32)dp->tdir_count+1!=dp->tdir_count+1) + o=NULL; + else + o=_TIFFmalloc((uint32)dp->tdir_count+1); + if (o==NULL) + { + if (data!=NULL) + _TIFFfree(data); + return(0); + } + _TIFFmemcpy(o,data,(uint32)dp->tdir_count); + o[(uint32)dp->tdir_count]=0; + if (data!=0) + _TIFFfree(data); + data=o; + } + n=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!n) + return(0); + } + } + break; + case TIFF_SETGET_UINT8: + { + uint8 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryByte(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_UINT16: + { + uint16 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryShort(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_UINT32: + { + uint32 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryLong(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_UINT64: + { + uint64 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryLong8(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_FLOAT: + { + float data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryFloat(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_DOUBLE: + { + double data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryDouble(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_IFD8: + { + uint64 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryIfd8(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_UINT16_PAIR: + { + uint16* data; + assert(fip->field_readcount==2); + assert(fip->field_passcount==0); + if (dp->tdir_count!=2) + return(0); + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C0_UINT8: + { + uint8* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_UINT16: + { + uint16* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_UINT32: + { + uint32* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_FLOAT: + { + float* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_ASCII: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT8: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT16: + { + uint16* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT32: + { + uint32* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT64: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryLong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_FLOAT: + { + float* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_DOUBLE: + { + double* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryDoubleArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_IFD8: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryIfd8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C32_ASCII: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT8: + { + int8* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySbyteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT16: + { + uint16* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT16: + { + int16* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySshortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT32: + { + uint32* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT32: + { + int32* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySlongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT64: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryLong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT64: + { + int64* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySlong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_FLOAT: + { + float* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_DOUBLE: + { + double* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryDoubleArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_IFD8: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryIfd8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + default: + assert(0); /* we should never get here */ + break; + } + if (err!=TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover); + return(0); + } + return(1); +} + +/* + * Fetch a set of offsets or lengths. + * While this routine says "strips", in fact it's also used for tiles. + */ +static int +TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp) +{ + static const char module[] = "TIFFFetchStripThing"; + enum TIFFReadDirEntryErr err; + uint64* data; + err=TIFFReadDirEntryLong8Array(tif,dir,&data); + if (err!=TIFFReadDirEntryErrOk) + { + const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); + return(0); + } + if (dir->tdir_count!=(uint64)nstrips) + { + uint64* resizeddata; + resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array"); + if (resizeddata==0) { + _TIFFfree(data); + return(0); + } + if (dir->tdir_count<(uint64)nstrips) + { + _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64)); + _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64)); + } + else + _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64)); + _TIFFfree(data); + data=resizeddata; + } + *lpp=data; + return(1); +} + +/* + * Fetch and set the SubjectDistance EXIF tag. + */ +static int +TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir) +{ + static const char module[] = "TIFFFetchSubjectDistance"; + enum TIFFReadDirEntryErr err; + UInt64Aligned_t m; + m.l=0; + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(uint32)==4); + if (dir->tdir_count!=1) + err=TIFFReadDirEntryErrCount; + else if (dir->tdir_type!=TIFF_RATIONAL) + err=TIFFReadDirEntryErrType; + else + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 offset; + offset=*(uint32*)(&dir->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + } + else + { + m.l=dir->tdir_offset.toff_long8; + err=TIFFReadDirEntryErrOk; + } + } + if (err==TIFFReadDirEntryErrOk) + { + double n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if (m.i[0]==0) + n=0.0; + else if (m.i[0]==0xFFFFFFFF) + /* + * XXX: Numerator 0xFFFFFFFF means that we have infinite + * distance. Indicate that with a negative floating point + * SubjectDistance value. + */ + n=-1.0; + else + n=(double)m.i[0]/(double)m.i[1]; + return(TIFFSetField(tif,dir->tdir_tag,n)); + } + else + { + TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE); + return(0); + } +} + +/* + * Replace a single strip (tile) of uncompressed data by multiple strips + * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for + * dealing with large images or for dealing with machines with a limited + * amount memory. + */ +static void +ChopUpSingleUncompressedStrip(TIFF* tif) +{ + register TIFFDirectory *td = &tif->tif_dir; + uint64 bytecount; + uint64 offset; + uint32 rowblock; + uint64 rowblockbytes; + uint64 stripbytes; + uint32 strip; + uint64 nstrips64; + uint32 nstrips32; + uint32 rowsperstrip; + uint64* newcounts; + uint64* newoffsets; + + bytecount = td->td_stripbytecount[0]; + offset = td->td_stripoffset[0]; + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& + (!isUpSampled(tif))) + rowblock = td->td_ycbcrsubsampling[1]; + else + rowblock = 1; + rowblockbytes = TIFFVTileSize64(tif, rowblock); + /* + * Make the rows hold at least one scanline, but fill specified amount + * of data if possible. + */ + if (rowblockbytes > STRIP_SIZE_DEFAULT) { + stripbytes = rowblockbytes; + rowsperstrip = rowblock; + } else if (rowblockbytes > 0 ) { + uint32 rowblocksperstrip; + rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes); + rowsperstrip = rowblocksperstrip * rowblock; + stripbytes = rowblocksperstrip * rowblockbytes; + } + else + return; + + /* + * never increase the number of strips in an image + */ + if (rowsperstrip >= td->td_rowsperstrip) + return; + nstrips64 = TIFFhowmany_64(bytecount, stripbytes); + if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ + return; + nstrips32 = (uint32)nstrips64; + + newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), + "for chopped \"StripByteCounts\" array"); + newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), + "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) { + /* + * Unable to allocate new strip information, give up and use + * the original one strip information. + */ + if (newcounts != NULL) + _TIFFfree(newcounts); + if (newoffsets != NULL) + _TIFFfree(newoffsets); + return; + } + /* + * Fill the strip information arrays with new bytecounts and offsets + * that reflect the broken-up format. + */ + for (strip = 0; strip < nstrips32; strip++) { + if (stripbytes > bytecount) + stripbytes = bytecount; + newcounts[strip] = stripbytes; + newoffsets[strip] = offset; + offset += stripbytes; + bytecount -= stripbytes; + } + /* + * Replace old single strip info with multi-strip info. + */ + td->td_stripsperimage = td->td_nstrips = nstrips32; + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + + _TIFFfree(td->td_stripbytecount); + _TIFFfree(td->td_stripoffset); + td->td_stripbytecount = newcounts; + td->td_stripoffset = newoffsets; + td->td_stripbytecountsorted = 1; +} + +int _TIFFFillStriles( TIFF *tif ) +{ +#if defined(DEFER_STRILE_LOAD) + register TIFFDirectory *td = &tif->tif_dir; + int return_value = 1; + + if( td->td_stripoffset != NULL ) + return 1; + + if( td->td_stripoffset_entry.tdir_count == 0 ) + return 0; + + if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry), + td->td_nstrips,&td->td_stripoffset)) + { + return_value = 0; + } + + if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry), + td->td_nstrips,&td->td_stripbytecount)) + { + return_value = 0; + } + + _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + + if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) { + uint32 strip; + + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { + if (tif->tif_dir.td_stripoffset[strip - 1] > + tif->tif_dir.td_stripoffset[strip]) { + tif->tif_dir.td_stripbytecountsorted = 0; + break; + } + } + } + + return return_value; +#else /* !defined(DEFER_STRILE_LOAD) */ + (void) tif; + return 1; +#endif +} + + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirwrite.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirwrite.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dirwrite.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dirwrite.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2910 @@ +/* $Id: tif_dirwrite.c,v 1.76 2011-02-18 20:53:04 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Write Support Routines. + */ +#include "tiffiop.h" + +#ifdef HAVE_IEEEFP +#define TIFFCvtNativeToIEEEFloat(tif, n, fp) +#define TIFFCvtNativeToIEEEDouble(tif, n, dp) +#else +extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp); +extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp); +#endif + +static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff); + +static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +#if 0 +static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif + +static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); +static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#if 0 +static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); +#if 0 +static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); +static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +#ifdef notdef +static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); +#if 0 +static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#if 0 +static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); +#if 0 +static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); +#endif +static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); +#endif +static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); +static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#if 0 +static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +#if 0 +static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#endif +static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#endif +static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); +static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); +static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); + +static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); +static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); +static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); +#endif +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); +#endif +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); +static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); + +static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data); + +static int TIFFLinkDirectory(TIFF*); + +/* + * Write the contents of the current directory + * to the specified file. This routine doesn't + * handle overwriting a directory with auxiliary + * storage that's been changed. + */ +int +TIFFWriteDirectory(TIFF* tif) +{ + return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL); +} + +/* + * Similar to TIFFWriteDirectory(), writes the directory out + * but leaves all data structures in memory so that it can be + * written again. This will make a partially written TIFF file + * readable before it is successfully completed/closed. + */ +int +TIFFCheckpointDirectory(TIFF* tif) +{ + int rc; + /* Setup the strips arrays, if they haven't already been. */ + if (tif->tif_dir.td_stripoffset == NULL) + (void) TIFFSetupStrips(tif); + rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL); + (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); + return rc; +} + +int +TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff) +{ + return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff); +} + +/* + * Similar to TIFFWriteDirectory(), but if the directory has already + * been written once, it is relocated to the end of the file, in case it + * has changed in size. Note that this will result in the loss of the + * previously used directory space. + */ +int +TIFFRewriteDirectory( TIFF *tif ) +{ + static const char module[] = "TIFFRewriteDirectory"; + + /* We don't need to do anything special if it hasn't been written. */ + if( tif->tif_diroff == 0 ) + return TIFFWriteDirectory( tif ); + + /* + * Find and zero the pointer to this directory, so that TIFFLinkDirectory + * will cause it to be added after this directories current pre-link. + */ + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.classic.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif,4,SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4)) + { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error updating TIFF header"); + return (0); + } + } + else + { + uint32 nextdir; + nextdir = tif->tif_header.classic.tiff_diroff; + while(1) { + uint16 dircount; + uint32 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, 2)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir==tif->tif_diroff) + { + uint32 m; + m=0; + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff=0; + break; + } + nextdir=nextnextdir; + } + } + } + else + { + if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.big.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif,8,SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8)) + { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error updating TIFF header"); + return (0); + } + } + else + { + uint64 nextdir; + nextdir = tif->tif_header.big.tiff_diroff; + while(1) { + uint64 dircount64; + uint16 dircount; + uint64 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount64, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount=(uint16)dircount64; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir==tif->tif_diroff) + { + uint64 m; + m=0; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff=0; + break; + } + nextdir=nextnextdir; + } + } + } + + /* + * Now use TIFFWriteDirectory() normally. + */ + + return TIFFWriteDirectory( tif ); +} + +static int +TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) +{ + static const char module[] = "TIFFWriteDirectorySec"; + uint32 ndir; + TIFFDirEntry* dir; + uint32 dirsize; + void* dirmem; + uint32 m; + if (tif->tif_mode == O_RDONLY) + return (1); + + _TIFFFillStriles( tif ); + + /* + * Clear write state so that subsequent images with + * different characteristics get the right buffers + * setup for them. + */ + if (imagedone) + { + if (tif->tif_flags & TIFF_POSTENCODE) + { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Error post-encoding before directory write"); + return (0); + } + } + (*tif->tif_close)(tif); /* shutdown encoder */ + /* + * Flush any data that might have been written + * by the compression close+cleanup routines. But + * be careful not to write stuff if we didn't add data + * in the previous steps as the "rawcc" data may well be + * a previously read tile/strip in mixed read/write mode. + */ + if (tif->tif_rawcc > 0 + && (tif->tif_flags & TIFF_BEENWRITING) != 0 ) + { + if( !TIFFFlushData1(tif) ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Error flushing data before directory write"); + return (0); + } + } + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); + } + dir=NULL; + dirmem=NULL; + dirsize=0; + while (1) + { + ndir=0; + if (isimage) + { + if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_RESOLUTION)) + { + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_POSITION)) + { + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_COMPRESSION)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_FILLORDER)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_ORIENTATION)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_COLORMAP)) + { + if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES)) + { + if (tif->tif_dir.td_extrasamples) + { + uint16 na; + uint16* nb; + TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb); + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) + { + if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) + { + if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_INKNAMES)) + { + if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SUBIFD)) + { + if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir)) + goto bad; + } + { + uint32 n; + for (n=0; ntif_nfields; n++) { + const TIFFField* o; + o = tif->tif_fields[n]; + if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit))) + { + switch (o->get_field_type) + { + case TIFF_SETGET_ASCII: + { + uint32 pa; + char* pb; + assert(o->field_type==TIFF_ASCII); + assert(o->field_readcount==TIFF_VARIABLE); + assert(o->field_passcount==0); + TIFFGetField(tif,o->field_tag,&pb); + pa=(uint32)(strlen(pb)); + if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb)) + goto bad; + } + break; + case TIFF_SETGET_UINT16: + { + uint16 p; + assert(o->field_type==TIFF_SHORT); + assert(o->field_readcount==1); + assert(o->field_passcount==0); + TIFFGetField(tif,o->field_tag,&p); + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p)) + goto bad; + } + break; + case TIFF_SETGET_UINT32: + { + uint32 p; + assert(o->field_type==TIFF_LONG); + assert(o->field_readcount==1); + assert(o->field_passcount==0); + TIFFGetField(tif,o->field_tag,&p); + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p)) + goto bad; + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint32 pa; + void* pb; + assert(o->field_type==TIFF_UNDEFINED); + assert(o->field_readcount==TIFF_VARIABLE2); + assert(o->field_passcount==1); + TIFFGetField(tif,o->field_tag,&pa,&pb); + if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb)) + goto bad; + } + break; + default: + assert(0); /* we should never get here */ + break; + } + } + } + } + } + for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++) + { + switch (tif->tif_dir.td_customValues[m].info->field_type) + { + case TIFF_ASCII: + if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_UNDEFINED: + if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_BYTE: + if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SBYTE: + if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SHORT: + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SSHORT: + if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG: + if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG: + if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG8: + if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG8: + if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_RATIONAL: + if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SRATIONAL: + if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_FLOAT: + if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_DOUBLE: + if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD: + if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD8: + if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + default: + assert(0); /* we should never get here */ + break; + } + } + if (dir!=NULL) + break; + dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry)); + if (dir==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + goto bad; + } + if (isimage) + { + if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif))) + goto bad; + } + else + tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1); + if (pdiroff!=NULL) + *pdiroff=tif->tif_diroff; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + dirsize=2+ndir*12+4; + else + dirsize=8+ndir*20+8; + tif->tif_dataoff=tif->tif_diroff+dirsize; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_dataoff=(uint32)tif->tif_dataoff; + if ((tif->tif_dataofftif_diroff)||(tif->tif_dataoff<(uint64)dirsize)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded"); + goto bad; + } + if (tif->tif_dataoff&1) + tif->tif_dataoff++; + if (isimage) + tif->tif_curdir++; + } + if (isimage) + { + if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0)) + { + uint32 na; + TIFFDirEntry* nb; + for (na=0, nb=dir; ; na++, nb++) + { + assert(natdir_tag==TIFFTAG_SUBIFD) + break; + } + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_subifdoff=tif->tif_diroff+2+na*12+8; + else + tif->tif_subifdoff=tif->tif_diroff+8+na*20+12; + } + } + dirmem=_TIFFmalloc(dirsize); + if (dirmem==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + goto bad; + } + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint8* n; + uint32 nTmp; + TIFFDirEntry* o; + n=dirmem; + *(uint16*)n=ndir; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + o=dir; + for (m=0; mtdir_tag; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + *(uint16*)n=o->tdir_type; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + nTmp = (uint32)o->tdir_count; + _TIFFmemcpy(n,&nTmp,4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)n); + n+=4; + /* This is correct. The data has been */ + /* swabbed previously in TIFFWriteDirectoryTagData */ + _TIFFmemcpy(n,&o->tdir_offset,4); + n+=4; + o++; + } + nTmp = (uint32)tif->tif_nextdiroff; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nTmp); + _TIFFmemcpy(n,&nTmp,4); + } + else + { + uint8* n; + TIFFDirEntry* o; + n=dirmem; + *(uint64*)n=ndir; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + n+=8; + o=dir; + for (m=0; mtdir_tag; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + *(uint16*)n=o->tdir_type; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + _TIFFmemcpy(n,&o->tdir_count,8); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + n+=8; + _TIFFmemcpy(n,&o->tdir_offset,8); + n+=8; + o++; + } + _TIFFmemcpy(n,&tif->tif_nextdiroff,8); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + } + _TIFFfree(dir); + dir=NULL; + if (!SeekOK(tif,tif->tif_diroff)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); + goto bad; + } + if (!WriteOK(tif,dirmem,(tmsize_t)dirsize)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); + goto bad; + } + _TIFFfree(dirmem); + if (imagedone) + { + TIFFFreeDirectory(tif); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + (*tif->tif_cleanup)(tif); + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFCreateDirectory(tif); + } + return(1); +bad: + if (dir!=NULL) + _TIFFfree(dir); + if (dirmem!=NULL) + _TIFFfree(dirmem); + return(0); +} + +static int +TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +{ + static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; + void* conv; + uint32 i; + int ok; + conv = _TIFFmalloc(count*sizeof(double)); + if (conv == NULL) + { + TIFFErrorExt(tif->tif_clientdata, module, "Out of memory"); + return (0); + } + + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample<=32) + { + for (i = 0; i < count; ++i) + ((float*)conv)[i] = (float)value[i]; + ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); + } + else + { + ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value); + } + break; + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample<=8) + { + for (i = 0; i < count; ++i) + ((int8*)conv)[i] = (int8)value[i]; + ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv); + } + else if (tif->tif_dir.td_bitspersample<=16) + { + for (i = 0; i < count; ++i) + ((int16*)conv)[i] = (int16)value[i]; + ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); + } + else + { + for (i = 0; i < count; ++i) + ((int32*)conv)[i] = (int32)value[i]; + ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); + } + break; + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample<=8) + { + for (i = 0; i < count; ++i) + ((uint8*)conv)[i] = (uint8)value[i]; + ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv); + } + else if (tif->tif_dir.td_bitspersample<=16) + { + for (i = 0; i < count; ++i) + ((uint16*)conv)[i] = (uint16)value[i]; + ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); + } + else + { + for (i = 0; i < count; ++i) + ((uint32*)conv)[i] = (uint32)value[i]; + ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); + } + break; + default: + ok = 0; + } + + _TIFFfree(conv); + return (ok); +} + +#if 0 +static int +TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample<=32) + return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value)); + else + return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value)); + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample<=8) + return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value)); + else if (tif->tif_dir.td_bitspersample<=16) + return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value)); + else + return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value)); + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample<=8) + return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value)); + else if (tif->tif_dir.td_bitspersample<=16) + return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value)); + else + return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value)); + default: + return(1); + } +} +#endif + +static int +TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + static const char module[] = "TIFFWriteDirectoryTagBytePerSample"; + uint8* m; + uint8* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSbytePerSample"; + int8* m; + int8* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; + uint16* m; + uint16* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSshortPerSample"; + int16* m; + int16* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + static const char module[] = "TIFFWriteDirectoryTagLongPerSample"; + uint32* m; + uint32* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSlongPerSample"; + int32* m; + int32* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value)); +} +#endif + +static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + static const char module[] = "TIFFWriteDirectoryTagFloatPerSample"; + float* m; + float* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value)); +} +#endif + +static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + static const char module[] = "TIFFWriteDirectoryTagDoublePerSample"; + double* m; + double* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value)); +} +#endif + +static int +TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + if (value<=0xFFFF) + return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value)); + else + return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); +} + +/************************************************************************/ +/* TIFFWriteDirectoryTagLongLong8Array() */ +/* */ +/* Write out LONG8 array as LONG8 for BigTIFF or LONG for */ +/* Classic TIFF with some checking. */ +/************************************************************************/ + +static int +TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagLongLong8Array"; + uint64* ma; + uint32 mb; + uint32* p; + uint32* q; + int o; + + /* is this just a counting pass? */ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + + /* We always write LONG8 for BigTIFF, no checking needed. */ + if( tif->tif_flags&TIFF_BIGTIFF ) + return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir, + tag,count,value); + + /* + ** For classic tiff we want to verify everything is in range for LONG + ** and convert to long format. + */ + + p = _TIFFmalloc(count*sizeof(uint32)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + + for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); + _TIFFfree(p); + return(0); + } + *q= (uint32)(*ma); + } + + o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p); + _TIFFfree(p); + + return(o); +} + +/************************************************************************/ +/* TIFFWriteDirectoryTagIfdIfd8Array() */ +/* */ +/* Write either IFD8 or IFD array depending on file type. */ +/************************************************************************/ + +static int +TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array"; + uint64* ma; + uint32 mb; + uint32* p; + uint32* q; + int o; + + /* is this just a counting pass? */ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + + /* We always write IFD8 for BigTIFF, no checking needed. */ + if( tif->tif_flags&TIFF_BIGTIFF ) + return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir, + tag,count,value); + + /* + ** For classic tiff we want to verify everything is in range for IFD + ** and convert to long format. + */ + + p = _TIFFmalloc(count*sizeof(uint32)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + + for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); + _TIFFfree(p); + return(0); + } + *q= (uint32)(*ma); + } + + o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p); + _TIFFfree(p); + + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array"; + uint64* ma; + uint32 mb; + uint8 n; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + n=0; + for (ma=value, mb=0; mb0xFFFF)) + n=1; + if ((n==1)&&(*ma>0xFFFFFFFF)) + { + n=2; + break; + } + } + if (n==0) + { + uint16* p; + uint16* q; + p=_TIFFmalloc(count*sizeof(uint16)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (ma=value, mb=0, q=p; mbtif_clientdata,module,"Out of memory"); + return(0); + } + for (ma=value, mb=0, q=p; mbtif_dir.td_bitspersample); + n=_TIFFmalloc(3*m*sizeof(uint16)); + if (n==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16)); + _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16)); + _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16)); + o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n); + _TIFFfree(n); + return(o); +} + +static int +TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) +{ + static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; + uint32 m; + uint16 n; + uint16* o; + int p; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=(1<tif_dir.td_bitspersample); + n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples; + /* + * Check if the table can be written as a single column, + * or if it must be written as 3 columns. Note that we + * write a 3-column tag if there are 2 samples/pixel and + * a single column of data won't suffice--hmm. + */ + if (n>3) + n=3; + if (n==3) + { + if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16))) + n=2; + } + if (n==2) + { + if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16))) + n=1; + } + if (n==0) + n=1; + o=_TIFFmalloc(n*m*sizeof(uint16)); + if (o==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16)); + if (n>1) + _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)); + if (n>2) + _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)); + p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o); + _TIFFfree(o); + return(p); +} + +static int +TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) +{ + static const char module[] = "TIFFWriteDirectoryTagSubifd"; + uint64 m; + int n; + if (tif->tif_dir.td_nsubifd==0) + return(1); + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=tif->tif_dataoff; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32* o; + uint64* pa; + uint32* pb; + uint16 p; + o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32)); + if (o==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + pa=tif->tif_dir.td_subifd; + pb=o; + for (p=0; p < tif->tif_dir.td_nsubifd; p++) + { + assert(pa != 0); + assert(*pa <= 0xFFFFFFFFUL); + *pb++=(uint32)(*pa++); + } + n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o); + _TIFFfree(o); + } + else + n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd); + if (!n) + return(0); + /* + * Total hack: if this directory includes a SubIFD + * tag then force the next directories to be + * written as ``sub directories'' of this one. This + * is used to write things like thumbnails and + * image masks that one wants to keep out of the + * normal directory linkage access mechanism. + */ + tif->tif_flags|=TIFF_INSUBIFD; + tif->tif_nsubifd=tif->tif_dir.td_nsubifd; + if (tif->tif_dir.td_nsubifd==1) + tif->tif_subifdoff=0; + else + tif->tif_subifdoff=m; + return(1); +} + +static int +TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) +{ + assert(sizeof(char)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value)); +} + +static int +TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + assert(sizeof(int8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) +{ + assert(sizeof(int8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value)); +} + +static int +TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + uint16 m; + assert(sizeof(uint16)==2); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m)); +} + +static int +TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +{ + assert(count<0x80000000); + assert(sizeof(uint16)==2); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + int16 m; + assert(sizeof(int16)==2); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) +{ + assert(count<0x80000000); + assert(sizeof(int16)==2); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort((uint16*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value)); +} + +static int +TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + uint32 m; + assert(sizeof(uint32)==4); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m)); +} + +static int +TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + assert(count<0x40000000); + assert(sizeof(uint32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + int32 m; + assert(sizeof(int32)==4); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) +{ + assert(count<0x40000000); + assert(sizeof(int32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) +{ + uint64 m; + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + assert(count<0x20000000); + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +{ + int64 m; + assert(sizeof(int64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) +{ + assert(count<0x20000000); + assert(sizeof(int64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + uint32 m[2]; + assert(value>=0.0); + assert(sizeof(uint32)==4); + if (value<=0.0) + { + m[0]=0; + m[1]=1; + } + else if (value==(double)(uint32)value) + { + m[0]=(uint32)value; + m[1]=1; + } + else if (value<1.0) + { + m[0]=(uint32)(value*0xFFFFFFFF); + m[1]=0xFFFFFFFF; + } + else + { + m[0]=0xFFFFFFFF; + m[1]=(uint32)(0xFFFFFFFF/value); + } + if (tif->tif_flags&TIFF_SWAB) + { + TIFFSwabLong(&m[0]); + TIFFSwabLong(&m[1]); + } + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0])); +} + +static int +TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; + uint32* m; + float* na; + uint32* nb; + uint32 nc; + int o; + assert(sizeof(uint32)==4); + m=_TIFFmalloc(count*2*sizeof(uint32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=value, nb=m, nc=0; nctif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m,count*2); + o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); + _TIFFfree(m); + return(o); +} + +static int +TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; + int32* m; + float* na; + int32* nb; + uint32 nc; + int o; + assert(sizeof(int32)==4); + m=_TIFFmalloc(count*2*sizeof(int32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=value, nb=m, nc=0; nc-1.0) + { + nb[0]=-(int32)((-*na)*0x7FFFFFFF); + nb[1]=0x7FFFFFFF; + } + else + { + nb[0]=-0x7FFFFFFF; + nb[1]=(int32)(0x7FFFFFFF/(-*na)); + } + } + else + { + if (*na==(int32)(*na)) + { + nb[0]=(int32)(*na); + nb[1]=1; + } + else if (*na<1.0) + { + nb[0]=(int32)((*na)*0x7FFFFFFF); + nb[1]=0x7FFFFFFF; + } + else + { + nb[0]=0x7FFFFFFF; + nb[1]=(int32)(0x7FFFFFFF/(*na)); + } + } + } + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)m,count*2); + o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); + _TIFFfree(m); + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + float m; + assert(sizeof(float)==4); + m=value; + TIFFCvtNativeToIEEEFloat(tif,1,&m); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabFloat(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + assert(count<0x40000000); + assert(sizeof(float)==4); + TIFFCvtNativeToIEEEFloat(tif,count,&value); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfFloat(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + double m; + assert(sizeof(double)==8); + m=value; + TIFFCvtNativeToIEEEDouble(tif,1,&m); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabDouble(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +{ + assert(count<0x20000000); + assert(sizeof(double)==8); + TIFFCvtNativeToIEEEDouble(tif,count,&value); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfDouble(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + assert(count<0x40000000); + assert(sizeof(uint32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value)); +} + +static int +TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + assert(count<0x20000000); + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data) +{ + static const char module[] = "TIFFWriteDirectoryTagData"; + uint32 m; + m=0; + while (m<(*ndir)) + { + assert(dir[m].tdir_tag!=tag); + if (dir[m].tdir_tag>tag) + break; + m++; + } + if (m<(*ndir)) + { + uint32 n; + for (n=*ndir; n>m; n--) + dir[n]=dir[n-1]; + } + dir[m].tdir_tag=tag; + dir[m].tdir_type=datatype; + dir[m].tdir_count=count; + dir[m].tdir_offset.toff_long8 = 0; + if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U)) + _TIFFmemcpy(&dir[m].tdir_offset,data,datalength); + else + { + uint64 na,nb; + na=tif->tif_dataoff; + nb=na+datalength; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nb=(uint32)nb; + if ((nbtif_clientdata,module,"Maximum TIFF file size exceeded"); + return(0); + } + if (!SeekOK(tif,na)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); + return(0); + } + assert(datalength<0x80000000UL); + if (!WriteOK(tif,data,(tmsize_t)datalength)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); + return(0); + } + tif->tif_dataoff=nb; + if (tif->tif_dataoff&1) + tif->tif_dataoff++; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 o; + o=(uint32)na; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&o); + _TIFFmemcpy(&dir[m].tdir_offset,&o,4); + } + else + { + dir[m].tdir_offset.toff_long8 = na; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); + } + } + (*ndir)++; + return(1); +} + +/* + * Link the current directory into the directory chain for the file. + */ +static int +TIFFLinkDirectory(TIFF* tif) +{ + static const char module[] = "TIFFLinkDirectory"; + + tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1; + + /* + * Handle SubIFDs + */ + if (tif->tif_flags & TIFF_INSUBIFD) + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 m; + m = (uint32)tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 4; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + else + { + uint64 m; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 8; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + } + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 m; + uint32 nextdir; + m = (uint32)(tif->tif_diroff); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + if (tif->tif_header.classic.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff; + (void) TIFFSeekFile(tif,4, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + nextdir = tif->tif_header.classic.tiff_diroff; + while(1) { + uint16 dircount; + uint32 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, 2)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir==0) + { + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + break; + } + nextdir=nextnextdir; + } + } + else + { + uint64 m; + uint64 nextdir; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + if (tif->tif_header.big.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.big.tiff_diroff = tif->tif_diroff; + (void) TIFFSeekFile(tif,8, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + nextdir = tif->tif_header.big.tiff_diroff; + while(1) { + uint64 dircount64; + uint16 dircount; + uint64 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount64, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount=(uint16)dircount64; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir==0) + { + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + break; + } + nextdir=nextnextdir; + } + } + return (1); +} + +/************************************************************************/ +/* TIFFRewriteField() */ +/* */ +/* Rewrite a field in the directory on disk without regard to */ +/* updating the TIFF directory structure in memory. Currently */ +/* only supported for field that already exist in the on-disk */ +/* directory. Mainly used for updating stripoffset / */ +/* stripbytecount values after the directory is already on */ +/* disk. */ +/* */ +/* Returns zero on failure, and one on success. */ +/************************************************************************/ + +int +_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, + tmsize_t count, void* data) +{ + static const char module[] = "TIFFResetField"; + const TIFFField* fip = NULL; + uint16 dircount; + tmsize_t dirsize; + uint8 direntry_raw[20]; + uint16 entry_tag = 0; + uint16 entry_type = 0; + uint64 entry_count = 0; + uint64 entry_offset = 0; + int value_in_entry = 0; + uint64 read_offset; + uint8 *buf_to_write = NULL; + TIFFDataType datatype; + +/* -------------------------------------------------------------------- */ +/* Find field definition. */ +/* -------------------------------------------------------------------- */ + fip = TIFFFindField(tif, tag, TIFF_ANY); + +/* -------------------------------------------------------------------- */ +/* Do some checking this is a straight forward case. */ +/* -------------------------------------------------------------------- */ + if( isMapped(tif) ) + { + TIFFErrorExt( tif->tif_clientdata, module, + "Memory mapped files not currently supported for this operation." ); + return 0; + } + + if( tif->tif_diroff == 0 ) + { + TIFFErrorExt( tif->tif_clientdata, module, + "Attempt to reset field on directory not already on disk." ); + return 0; + } + +/* -------------------------------------------------------------------- */ +/* Read the directory entry count. */ +/* -------------------------------------------------------------------- */ + if (!SeekOK(tif, tif->tif_diroff)) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + + read_offset = tif->tif_diroff; + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dirsize = 12; + read_offset += 2; + } else { + uint64 dircount64; + if (!ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + dircount = (uint16)dircount64; + dirsize = 20; + read_offset += 8; + } + +/* -------------------------------------------------------------------- */ +/* Read through directory to find target tag. */ +/* -------------------------------------------------------------------- */ + while( dircount > 0 ) + { + if (!ReadOK(tif, direntry_raw, dirsize)) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory entry.", + tif->tif_name); + return 0; + } + + memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( &entry_tag ); + + if( entry_tag == tag ) + break; + + read_offset += dirsize; + } + + if( entry_tag != tag ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Could not find tag %d.", + tif->tif_name, tag ); + return 0; + } + +/* -------------------------------------------------------------------- */ +/* Extract the type, count and offset for this entry. */ +/* -------------------------------------------------------------------- */ + memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( &entry_type ); + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 value; + + memcpy( &value, direntry_raw + 4, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( &value ); + entry_count = value; + + memcpy( &value, direntry_raw + 8, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( &value ); + entry_offset = value; + } + else + { + memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( &entry_count ); + + memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( &entry_offset ); + } + +/* -------------------------------------------------------------------- */ +/* What data type do we want to write this as? */ +/* -------------------------------------------------------------------- */ + if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) ) + { + if( in_datatype == TIFF_LONG8 ) + datatype = TIFF_LONG; + else if( in_datatype == TIFF_SLONG8 ) + datatype = TIFF_SLONG; + else if( in_datatype == TIFF_IFD8 ) + datatype = TIFF_IFD; + else + datatype = in_datatype; + } + else + datatype = in_datatype; + +/* -------------------------------------------------------------------- */ +/* Prepare buffer of actual data to write. This includes */ +/* swabbing as needed. */ +/* -------------------------------------------------------------------- */ + buf_to_write = + (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype), + "for field buffer."); + if (!buf_to_write) + return 0; + + if( datatype == in_datatype ) + memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) ); + else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 ) + { + tmsize_t i; + + for( i = 0; i < count; i++ ) + { + ((int32 *) buf_to_write)[i] = + (int32) ((int64 *) data)[i]; + if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] ) + { + _TIFFfree( buf_to_write ); + TIFFErrorExt( tif->tif_clientdata, module, + "Value exceeds 32bit range of output type." ); + return 0; + } + } + } + else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8) + || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) ) + { + tmsize_t i; + + for( i = 0; i < count; i++ ) + { + ((uint32 *) buf_to_write)[i] = + (uint32) ((uint64 *) data)[i]; + if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] ) + { + _TIFFfree( buf_to_write ); + TIFFErrorExt( tif->tif_clientdata, module, + "Value exceeds 32bit range of output type." ); + return 0; + } + } + } + + if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) ) + { + if( TIFFDataWidth(datatype) == 2 ) + TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count ); + else if( TIFFDataWidth(datatype) == 4 ) + TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count ); + else if( TIFFDataWidth(datatype) == 8 ) + TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count ); + } + +/* -------------------------------------------------------------------- */ +/* Is this a value that fits into the directory entry? */ +/* -------------------------------------------------------------------- */ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if( TIFFDataWidth(datatype) * count <= 4 ) + { + entry_offset = read_offset + 8; + value_in_entry = 1; + } + } + else + { + if( TIFFDataWidth(datatype) * count <= 8 ) + { + entry_offset = read_offset + 12; + value_in_entry = 1; + } + } + +/* -------------------------------------------------------------------- */ +/* If the tag type, and count match, then we just write it out */ +/* over the old values without altering the directory entry at */ +/* all. */ +/* -------------------------------------------------------------------- */ + if( entry_count == (uint64)count && entry_type == (uint16) datatype ) + { + if (!SeekOK(tif, entry_offset)) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + + _TIFFfree( buf_to_write ); + return 1; + } + +/* -------------------------------------------------------------------- */ +/* Otherwise, we write the new tag data at the end of the file. */ +/* -------------------------------------------------------------------- */ + if( !value_in_entry ) + { + entry_offset = TIFFSeekFile(tif,0,SEEK_END); + + if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + + _TIFFfree( buf_to_write ); + } + else + { + memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + } + +/* -------------------------------------------------------------------- */ +/* Adjust the directory entry. */ +/* -------------------------------------------------------------------- */ + entry_type = datatype; + memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( (uint16 *) (direntry_raw + 2) ); + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 value; + + value = (uint32) entry_count; + memcpy( direntry_raw + 4, &value, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( (uint32 *) (direntry_raw + 4) ); + + value = (uint32) entry_offset; + memcpy( direntry_raw + 8, &value, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( (uint32 *) (direntry_raw + 8) ); + } + else + { + memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( (uint64 *) (direntry_raw + 4) ); + + memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( (uint64 *) (direntry_raw + 12) ); + } + +/* -------------------------------------------------------------------- */ +/* Write the directory entry out to disk. */ +/* -------------------------------------------------------------------- */ + if (!SeekOK(tif, read_offset )) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + + if (!WriteOK(tif, direntry_raw,dirsize)) + { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not write TIFF directory entry.", + tif->tif_name); + return 0; + } + + return 1; +} +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dumpmode.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dumpmode.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_dumpmode.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_dumpmode.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,143 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.14 2011-04-02 20:54:09 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * "Null" Compression Algorithm Support. + */ +#include "tiffiop.h" + +static int +DumpFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +/* + * Encode a hunk of pixels. + */ +static int +DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +{ + (void) s; + while (cc > 0) { + tmsize_t n; + + n = cc; + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + n = tif->tif_rawdatasize - tif->tif_rawcc; + + assert( n > 0 ); + + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != pp) + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && + !TIFFFlushData1(tif)) + return (-1); + } + return (1); +} + +/* + * Decode a hunk of pixels. + */ +static int +DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + static const char module[] = "DumpModeDecode"; + (void) s; + if (tif->tif_rawcc < cc) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, +"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes", + (unsigned long) tif->tif_row, + (signed __int64) tif->tif_rawcc, + (signed __int64) cc); +#else + TIFFErrorExt(tif->tif_clientdata, module, +"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes", + (unsigned long) tif->tif_row, + (signed long long) tif->tif_rawcc, + (signed long long) cc); +#endif + return (0); + } + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != buf) + _TIFFmemcpy(buf, tif->tif_rawcp, cc); + tif->tif_rawcp += cc; + tif->tif_rawcc -= cc; + return (1); +} + +/* + * Seek forwards nrows in the current strip. + */ +static int +DumpModeSeek(TIFF* tif, uint32 nrows) +{ + tif->tif_rawcp += nrows * tif->tif_scanlinesize; + tif->tif_rawcc -= nrows * tif->tif_scanlinesize; + return (1); +} + +/* + * Initialize dump mode. + */ +int +TIFFInitDumpMode(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_fixuptags = DumpFixupTags; + tif->tif_decoderow = DumpModeDecode; + tif->tif_decodestrip = DumpModeDecode; + tif->tif_decodetile = DumpModeDecode; + tif->tif_encoderow = DumpModeEncode; + tif->tif_encodestrip = DumpModeEncode; + tif->tif_encodetile = DumpModeEncode; + tif->tif_seek = DumpModeSeek; + return (1); +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_error.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_error.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_error.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_error.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,80 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL; + +TIFFErrorHandler +TIFFSetErrorHandler(TIFFErrorHandler handler) +{ + TIFFErrorHandler prev = _TIFFerrorHandler; + _TIFFerrorHandler = handler; + return (prev); +} + +TIFFErrorHandlerExt +TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) +{ + TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; + _TIFFerrorHandlerExt = handler; + return (prev); +} + +void +TIFFError(const char* module, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (_TIFFerrorHandler) + (*_TIFFerrorHandler)(module, fmt, ap); + if (_TIFFerrorHandlerExt) + (*_TIFFerrorHandlerExt)(0, module, fmt, ap); + va_end(ap); +} + +void +TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (_TIFFerrorHandler) + (*_TIFFerrorHandler)(module, fmt, ap); + if (_TIFFerrorHandlerExt) + (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); + va_end(ap); +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_extension.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_extension.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_extension.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_extension.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,118 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.7 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Various routines support external extension of the tag set, and other + * application extension capabilities. + */ + +#include "tiffiop.h" + +int TIFFGetTagListCount( TIFF *tif ) + +{ + TIFFDirectory* td = &tif->tif_dir; + + return td->td_customValueCount; +} + +uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index ) + +{ + TIFFDirectory* td = &tif->tif_dir; + + if( tag_index < 0 || tag_index >= td->td_customValueCount ) + return (uint32)(-1); + else + return td->td_customValues[tag_index].info->field_tag; +} + +/* +** This provides read/write access to the TIFFTagMethods within the TIFF +** structure to application code without giving access to the private +** TIFF structure. +*/ +TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif ) + +{ + return &(tif->tif_tagmethods); +} + +void *TIFFGetClientInfo( TIFF *tif, const char *name ) + +{ + TIFFClientInfoLink *link = tif->tif_clientinfo; + + while( link != NULL && strcmp(link->name,name) != 0 ) + link = link->next; + + if( link != NULL ) + return link->data; + else + return NULL; +} + +void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) + +{ + TIFFClientInfoLink *link = tif->tif_clientinfo; + + /* + ** Do we have an existing link with this name? If so, just + ** set it. + */ + while( link != NULL && strcmp(link->name,name) != 0 ) + link = link->next; + + if( link != NULL ) + { + link->data = data; + return; + } + + /* + ** Create a new link. + */ + + link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink)); + assert (link != NULL); + link->next = tif->tif_clientinfo; + link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1)); + assert (link->name != NULL); + strcpy(link->name, name); + link->data = data; + + tif->tif_clientinfo = link; +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1595 @@ +/* $Id: tif_fax3.c,v 1.73 2012-06-13 00:27:20 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef CCITT_SUPPORT +/* + * TIFF Library. + * + * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support. + * + * This file contains support for decoding and encoding TIFF + * compression algorithms 2, 3, 4, and 32771. + * + * Decoder support is derived, with permission, from the code + * in Frank Cringle's viewfax program; + * Copyright (C) 1990, 1995 Frank D. Cringle. + */ +#include "tif_fax3.h" +#define G3CODES +#include "t4.h" +#include + +/* + * Compression+decompression state blocks are + * derived from this ``base state'' block. + */ +typedef struct { + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + tmsize_t rowbytes; /* bytes in a decoded scanline */ + uint32 rowpixels; /* pixels in a scanline */ + + uint16 cleanfaxdata; /* CleanFaxData tag */ + uint32 badfaxrun; /* BadFaxRun tag */ + uint32 badfaxlines; /* BadFaxLines tag */ + uint32 groupoptions; /* Group 3/4 options tag */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ +} Fax3BaseState; +#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) + +typedef enum { G3_1D, G3_2D } Ttag; +typedef struct { + Fax3BaseState b; + + /* Decoder state info */ + const unsigned char* bitmap; /* bit reversal table */ + uint32 data; /* current i/o byte/word */ + int bit; /* current i/o bit in byte */ + int EOLcnt; /* count of EOL codes recognized */ + TIFFFaxFillFunc fill; /* fill routine */ + uint32* runs; /* b&w runs for current/previous row */ + uint32* refruns; /* runs for reference line */ + uint32* curruns; /* runs for current line */ + + /* Encoder state info */ + Ttag tag; /* encoding state */ + unsigned char* refline; /* reference line for 2d decoding */ + int k; /* #rows left that can be 2d encoded */ + int maxk; /* max #rows that can be 2d encoded */ + + int line; +} Fax3CodecState; +#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) + +#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) +#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0) + +/* + * Group 3 and Group 4 Decoding. + */ + +/* + * These macros glue the TIFF library state to + * the state expected by Frank's decoder. + */ +#define DECLARE_STATE(tif, sp, mod) \ + static const char module[] = mod; \ + Fax3CodecState* sp = DecoderState(tif); \ + int a0; /* reference element */ \ + int lastx = sp->b.rowpixels; /* last element in row */ \ + uint32 BitAcc; /* bit accumulator */ \ + int BitsAvail; /* # valid bits in BitAcc */ \ + int RunLength; /* length of current run */ \ + unsigned char* cp; /* next byte of input data */ \ + unsigned char* ep; /* end of input data */ \ + uint32* pa; /* place to stuff next run */ \ + uint32* thisrun; /* current row's run array */ \ + int EOLcnt; /* # EOL codes recognized */ \ + const unsigned char* bitmap = sp->bitmap; /* input data bit reverser */ \ + const TIFFFaxTabEnt* TabEnt +#define DECLARE_STATE_2D(tif, sp, mod) \ + DECLARE_STATE(tif, sp, mod); \ + int b1; /* next change on prev line */ \ + uint32* pb /* next run in reference line */\ +/* + * Load any state that may be changed during decoding. + */ +#define CACHE_STATE(tif, sp) do { \ + BitAcc = sp->data; \ + BitsAvail = sp->bit; \ + EOLcnt = sp->EOLcnt; \ + cp = (unsigned char*) tif->tif_rawcp; \ + ep = cp + tif->tif_rawcc; \ +} while (0) +/* + * Save state possibly changed during decoding. + */ +#define UNCACHE_STATE(tif, sp) do { \ + sp->bit = BitsAvail; \ + sp->data = BitAcc; \ + sp->EOLcnt = EOLcnt; \ + tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp); \ + tif->tif_rawcp = (uint8*) cp; \ +} while (0) + +/* + * Setup state for decoding a strip. + */ +static int +Fax3PreDecode(TIFF* tif, uint16 s) +{ + Fax3CodecState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + sp->bit = 0; /* force initial read */ + sp->data = 0; + sp->EOLcnt = 0; /* force initial scan for EOL */ + /* + * Decoder assumes lsb-to-msb bit order. Note that we select + * this here rather than in Fax3SetupState so that viewers can + * hold the image open, fiddle with the FillOrder tag value, + * and then re-decode the image. Otherwise they'd need to close + * and open the image to get the state reset. + */ + sp->bitmap = + TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); + if (sp->refruns) { /* init reference line to white */ + sp->refruns[0] = (uint32) sp->b.rowpixels; + sp->refruns[1] = 0; + } + sp->line = 0; + return (1); +} + +/* + * Routine for handling various errors/conditions. + * Note how they are "glued into the decoder" by + * overriding the definitions used by the decoder. + */ + +static void +Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0) +{ + TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); +} +#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) + +static void +Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0) +{ + TIFFErrorExt(tif->tif_clientdata, module, + "Uncompressed data (not supported) at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); +} +#define extension(a0) Fax3Extension(module, tif, sp->line, a0) + +static void +Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx) +{ + TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)", + a0 < lastx ? "Premature EOL" : "Line length mismatch", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0, lastx); +} +#define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) + +static void +Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) +{ + TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); +} +#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) + +#define Nop + +/* + * Decode the requested amount of G3 1D-encoded data. + */ +static int +Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + DECLARE_STATE(tif, sp, "Fax3Decode1D"); + (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + SYNC_EOL(EOF1D); + EXPAND1D(EOF1Da); + (*sp->fill)(buf, thisrun, pa, lastx); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF1D: /* premature EOF */ + CLEANUP_RUNS(); + EOF1Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} + +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +/* + * Decode the requested amount of G3 2D-encoded data. + */ +static int +Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); + int is1D; /* current line is 1d/2d-encoded */ + (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d", + BitAcc, BitsAvail, EOLcnt); +#endif + SYNC_EOL(EOF2D); + NeedBits8(1, EOF2D); + is1D = GetBits(1); /* 1D/2D-encoding tag bit */ + ClrBits(1); +#ifdef FAX3_DEBUG + printf(" %s\n-------------------- %d\n", + is1D ? "1D" : "2D", tif->tif_row); + fflush(stdout); +#endif + pb = sp->refruns; + b1 = *pb++; + if (is1D) + EXPAND1D(EOF2Da); + else + EXPAND2D(EOF2Da); + (*sp->fill)(buf, thisrun, pa, lastx); + SETVALUE(0); /* imaginary change for reference */ + SWAP(uint32*, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF2D: /* premature EOF */ + CLEANUP_RUNS(); + EOF2Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} +#undef SWAP + +/* + * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes. + * For machines with 64-bit longs this is <16 bytes; otherwise + * this is <8 bytes. We optimize the code here to reflect the + * machine characteristics. + */ +#if SIZEOF_UNSIGNED_LONG == 8 +# define FILL(n, cp) \ + switch (n) { \ + case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\ + case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\ + case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\ + case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\ + case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ + case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + } +# define ZERO(n, cp) \ + switch (n) { \ + case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \ + case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \ + case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \ + case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \ + case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ + case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + } +#else +# define FILL(n, cp) \ + switch (n) { \ + case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \ + case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ + case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + } +# define ZERO(n, cp) \ + switch (n) { \ + case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \ + case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ + case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + } +#endif + +/* + * Bit-fill a row according to the white/black + * runs generated during G3/G4 decoding. + */ +void +_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) +{ + static const unsigned char _fillmasks[] = + { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; + unsigned char* cp; + uint32 x, bx, run; + int32 n, nw; + long* lp; + + if ((erun-runs)&1) + *erun++ = 0; + x = 0; + for (; runs < erun; runs += 2) { + run = runs[0]; + if (x+run > lastx || run > lastx ) + run = runs[0] = (uint32) (lastx - x); + if (run) { + cp = buf + (x>>3); + bx = x&7; + if (run > 8-bx) { + if (bx) { /* align to byte boundary */ + *cp++ &= 0xff << (8-bx); + run -= 8-bx; + } + if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */ + if ((n/sizeof (long)) > 1) { + /* + * Align to longword boundary and fill. + */ + for (; n && !isAligned(cp, long); n--) + *cp++ = 0x00; + lp = (long*) cp; + nw = (int32)(n / sizeof (long)); + n -= nw * sizeof (long); + do { + *lp++ = 0L; + } while (--nw); + cp = (unsigned char*) lp; + } + ZERO(n, cp); + run &= 7; + } + if (run) + cp[0] &= 0xff >> run; + } else + cp[0] &= ~(_fillmasks[run]>>bx); + x += runs[0]; + } + run = runs[1]; + if (x+run > lastx || run > lastx ) + run = runs[1] = lastx - x; + if (run) { + cp = buf + (x>>3); + bx = x&7; + if (run > 8-bx) { + if (bx) { /* align to byte boundary */ + *cp++ |= 0xff >> bx; + run -= 8-bx; + } + if( (n = run>>3) != 0 ) { /* multiple bytes to fill */ + if ((n/sizeof (long)) > 1) { + /* + * Align to longword boundary and fill. + */ + for (; n && !isAligned(cp, long); n--) + *cp++ = 0xff; + lp = (long*) cp; + nw = (int32)(n / sizeof (long)); + n -= nw * sizeof (long); + do { + *lp++ = -1L; + } while (--nw); + cp = (unsigned char*) lp; + } + FILL(n, cp); + run &= 7; + } + if (run) + cp[0] |= 0xff00 >> run; + } else + cp[0] |= _fillmasks[run]>>bx; + x += runs[1]; + } + } + assert(x == lastx); +} +#undef ZERO +#undef FILL + +static int +Fax3FixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +/* + * Setup G3/G4-related compression/decompression state + * before data is processed. This routine is called once + * per image -- it sets up different state based on whether + * or not decoding or encoding is being done and whether + * 1D- or 2D-encoded data is involved. + */ +static int +Fax3SetupState(TIFF* tif) +{ + static const char module[] = "Fax3SetupState"; + TIFFDirectory* td = &tif->tif_dir; + Fax3BaseState* sp = Fax3State(tif); + int needsRefLine; + Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); + tmsize_t rowbytes; + uint32 rowpixels, nruns; + + if (td->td_bitspersample != 1) { + TIFFErrorExt(tif->tif_clientdata, module, + "Bits/sample must be 1 for Group 3/4 encoding/decoding"); + return (0); + } + /* + * Calculate the scanline/tile widths. + */ + if (isTiled(tif)) { + rowbytes = TIFFTileRowSize(tif); + rowpixels = td->td_tilewidth; + } else { + rowbytes = TIFFScanlineSize(tif); + rowpixels = td->td_imagewidth; + } + sp->rowbytes = rowbytes; + sp->rowpixels = rowpixels; + /* + * Allocate any additional space required for decoding/encoding. + */ + needsRefLine = ( + (sp->groupoptions & GROUP3OPT_2DENCODING) || + td->td_compression == COMPRESSION_CCITTFAX4 + ); + + /* + Assure that allocation computations do not overflow. + + TIFFroundup and TIFFSafeMultiply return zero on integer overflow + */ + dsp->runs=(uint32*) NULL; + nruns = TIFFroundup_32(rowpixels,32); + if (needsRefLine) { + nruns = TIFFSafeMultiply(uint32,nruns,2); + } + if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Row pixels integer overflow (rowpixels %u)", + rowpixels); + return (0); + } + dsp->runs = (uint32*) _TIFFCheckMalloc(tif, + TIFFSafeMultiply(uint32,nruns,2), + sizeof (uint32), + "for Group 3/4 run arrays"); + if (dsp->runs == NULL) + return (0); + memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)); + dsp->curruns = dsp->runs; + if (needsRefLine) + dsp->refruns = dsp->runs + nruns; + else + dsp->refruns = NULL; + if (td->td_compression == COMPRESSION_CCITTFAX3 + && is2DEncoding(dsp)) { /* NB: default is 1D routine */ + tif->tif_decoderow = Fax3Decode2D; + tif->tif_decodestrip = Fax3Decode2D; + tif->tif_decodetile = Fax3Decode2D; + } + + if (needsRefLine) { /* 2d encoding */ + Fax3CodecState* esp = EncoderState(tif); + /* + * 2d encoding requires a scanline + * buffer for the ``reference line''; the + * scanline against which delta encoding + * is referenced. The reference line must + * be initialized to be ``white'' (done elsewhere). + */ + esp->refline = (unsigned char*) _TIFFmalloc(rowbytes); + if (esp->refline == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for Group 3/4 reference line"); + return (0); + } + } else /* 1d encoding */ + EncoderState(tif)->refline = NULL; + + return (1); +} + +/* + * CCITT Group 3 FAX Encoding. + */ + +#define Fax3FlushBits(tif, sp) { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + (void) TIFFFlushData1(tif); \ + *(tif)->tif_rawcp++ = (uint8) (sp)->data; \ + (tif)->tif_rawcc++; \ + (sp)->data = 0, (sp)->bit = 8; \ +} +#define _FlushBits(tif) { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + (void) TIFFFlushData1(tif); \ + *(tif)->tif_rawcp++ = (uint8) data; \ + (tif)->tif_rawcc++; \ + data = 0, bit = 8; \ +} +static const int _msbmask[9] = + { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; +#define _PutBits(tif, bits, length) { \ + while (length > bit) { \ + data |= bits >> (length - bit); \ + length -= bit; \ + _FlushBits(tif); \ + } \ + assert( length < 9 ); \ + data |= (bits & _msbmask[length]) << (bit - length); \ + bit -= length; \ + if (bit == 0) \ + _FlushBits(tif); \ +} + +/* + * Write a variable-length bit-value to + * the output stream. Values are + * assumed to be at most 16 bits. + */ +static void +Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) +{ + Fax3CodecState* sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + + _PutBits(tif, bits, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Write a code to the output stream. + */ +#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) + +#ifdef FAX3_DEBUG +#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") +#define DEBUG_PRINT(what,len) { \ + int t; \ + printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len); \ + for (t = length-1; t >= 0; t--) \ + putchar(code & (1<bit; + int data = sp->data; + unsigned int code, length; + + while (span >= 2624) { + const tableentry* te = &tab[63 + (2560>>6)]; + code = te->code, length = te->length; +#ifdef FAX3_DEBUG + DEBUG_PRINT("MakeUp", te->runlen); +#endif + _PutBits(tif, code, length); + span -= te->runlen; + } + if (span >= 64) { + const tableentry* te = &tab[63 + (span>>6)]; + assert(te->runlen == 64*(span>>6)); + code = te->code, length = te->length; +#ifdef FAX3_DEBUG + DEBUG_PRINT("MakeUp", te->runlen); +#endif + _PutBits(tif, code, length); + span -= te->runlen; + } + code = tab[span].code, length = tab[span].length; +#ifdef FAX3_DEBUG + DEBUG_PRINT(" Term", tab[span].runlen); +#endif + _PutBits(tif, code, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Write an EOL code to the output stream. The zero-fill + * logic for byte-aligning encoded scanlines is handled + * here. We also handle writing the tag bit for the next + * scanline when doing 2d encoding. + */ +static void +Fax3PutEOL(TIFF* tif) +{ + Fax3CodecState* sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + unsigned int code, length, tparm; + + if (sp->b.groupoptions & GROUP3OPT_FILLBITS) { + /* + * Force bit alignment so EOL will terminate on + * a byte boundary. That is, force the bit alignment + * to 16-12 = 4 before putting out the EOL code. + */ + int align = 8 - 4; + if (align != sp->bit) { + if (align > sp->bit) + align = sp->bit + (8 - align); + else + align = sp->bit - align; + code = 0; + tparm=align; + _PutBits(tif, 0, tparm); + } + } + code = EOL, length = 12; + if (is2DEncoding(sp)) + code = (code<<1) | (sp->tag == G3_1D), length++; + _PutBits(tif, code, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +Fax3PreEncode(TIFF* tif, uint16 s) +{ + Fax3CodecState* sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->bit = 8; + sp->data = 0; + sp->tag = G3_1D; + /* + * This is necessary for Group 4; otherwise it isn't + * needed because the first scanline of each strip ends + * up being copied into the refline. + */ + if (sp->refline) + _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); + if (is2DEncoding(sp)) { + float res = tif->tif_dir.td_yresolution; + /* + * The CCITT spec says that when doing 2d encoding, you + * should only do it on K consecutive scanlines, where K + * depends on the resolution of the image being encoded + * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory + * code initializes td_yresolution to 0, this code will + * select a K of 2 unless the YResolution tag is set + * appropriately. (Note also that we fudge a little here + * and use 150 lpi to avoid problems with units conversion.) + */ + if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) + res *= 2.54f; /* convert to inches */ + sp->maxk = (res > 150 ? 4 : 2); + sp->k = sp->maxk-1; + } else + sp->k = sp->maxk = 0; + sp->line = 0; + return (1); +} + +static const unsigned char zeroruns[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ +}; +static const unsigned char oneruns[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ +}; + +/* + * On certain systems it pays to inline + * the routines that find pixel spans. + */ +#ifdef VAXC +static int32 find0span(unsigned char*, int32, int32); +static int32 find1span(unsigned char*, int32, int32); +#pragma inline(find0span,find1span) +#endif + +/* + * Find a span of ones or zeros using the supplied + * table. The ``base'' of the bit string is supplied + * along with the start+end bit indices. + */ +static int32 +find0span(unsigned char* bp, int32 bs, int32 be) +{ + int32 bits = be - bs; + int32 n, span; + + bp += bs>>3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7))) { + span = zeroruns[(*bp << n) & 0xff]; + if (span > 8-n) /* table value too generous */ + span = 8-n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n+span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } else + span = 0; + if (bits >= (int32)(2 * 8 * sizeof(long))) { + long* lp; + /* + * Align to longword boundary and check longwords. + */ + while (!isAligned(bp, long)) { + if (*bp != 0x00) + return (span + zeroruns[*bp]); + span += 8, bits -= 8; + bp++; + } + lp = (long*) bp; + while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) { + span += 8*sizeof (long), bits -= 8*sizeof (long); + lp++; + } + bp = (unsigned char*) lp; + } + /* + * Scan full bytes for all 0's. + */ + while (bits >= 8) { + if (*bp != 0x00) /* end of run */ + return (span + zeroruns[*bp]); + span += 8, bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) { + n = zeroruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); +} + +static int32 +find1span(unsigned char* bp, int32 bs, int32 be) +{ + int32 bits = be - bs; + int32 n, span; + + bp += bs>>3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7))) { + span = oneruns[(*bp << n) & 0xff]; + if (span > 8-n) /* table value too generous */ + span = 8-n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n+span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } else + span = 0; + if (bits >= (int32)(2 * 8 * sizeof(long))) { + long* lp; + /* + * Align to longword boundary and check longwords. + */ + while (!isAligned(bp, long)) { + if (*bp != 0xff) + return (span + oneruns[*bp]); + span += 8, bits -= 8; + bp++; + } + lp = (long*) bp; + while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) { + span += 8*sizeof (long), bits -= 8*sizeof (long); + lp++; + } + bp = (unsigned char*) lp; + } + /* + * Scan full bytes for all 1's. + */ + while (bits >= 8) { + if (*bp != 0xff) /* end of run */ + return (span + oneruns[*bp]); + span += 8, bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) { + n = oneruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); +} + +/* + * Return the offset of the next bit in the range + * [bs..be] that is different from the specified + * color. The end, be, is returned if no such bit + * exists. + */ +#define finddiff(_cp, _bs, _be, _color) \ + (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be))) +/* + * Like finddiff, but also check the starting bit + * against the end in case start > end. + */ +#define finddiff2(_cp, _bs, _be, _color) \ + (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be) + +/* + * 1d-encode a row of pixels. The encoding is + * a sequence of all-white or all-black spans + * of pixels encoded with Huffman codes. + */ +static int +Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits) +{ + Fax3CodecState* sp = EncoderState(tif); + int32 span; + uint32 bs = 0; + + for (;;) { + span = find0span(bp, bs, bits); /* white span */ + putspan(tif, span, TIFFFaxWhiteCodes); + bs += span; + if (bs >= bits) + break; + span = find1span(bp, bs, bits); /* black span */ + putspan(tif, span, TIFFFaxBlackCodes); + bs += span; + if (bs >= bits) + break; + } + if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) { + if (sp->bit != 8) /* byte-align */ + Fax3FlushBits(tif, sp); + if ((sp->b.mode&FAXMODE_WORDALIGN) && + !isAligned(tif->tif_rawcp, uint16)) + Fax3FlushBits(tif, sp); + } + return (1); +} + +static const tableentry horizcode = + { 3, 0x1, 0 }; /* 001 */ +static const tableentry passcode = + { 4, 0x1, 0 }; /* 0001 */ +static const tableentry vcodes[7] = { + { 7, 0x03, 0 }, /* 0000 011 */ + { 6, 0x03, 0 }, /* 0000 11 */ + { 3, 0x03, 0 }, /* 011 */ + { 1, 0x1, 0 }, /* 1 */ + { 3, 0x2, 0 }, /* 010 */ + { 6, 0x02, 0 }, /* 0000 10 */ + { 7, 0x02, 0 } /* 0000 010 */ +}; + +/* + * 2d-encode a row of pixels. Consult the CCITT + * documentation for the algorithm. + */ +static int +Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) +{ +#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1) + uint32 a0 = 0; + uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); + uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); + uint32 a2, b2; + + for (;;) { + b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1)); + if (b2 >= a1) { + int32 d = b1 - a1; + if (!(-3 <= d && d <= 3)) { /* horizontal mode */ + a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); + putcode(tif, &horizcode); + if (a0+a1 == 0 || PIXEL(bp, a0) == 0) { + putspan(tif, a1-a0, TIFFFaxWhiteCodes); + putspan(tif, a2-a1, TIFFFaxBlackCodes); + } else { + putspan(tif, a1-a0, TIFFFaxBlackCodes); + putspan(tif, a2-a1, TIFFFaxWhiteCodes); + } + a0 = a2; + } else { /* vertical mode */ + putcode(tif, &vcodes[d+3]); + a0 = a1; + } + } else { /* pass mode */ + putcode(tif, &passcode); + a0 = b2; + } + if (a0 >= bits) + break; + a1 = finddiff(bp, a0, bits, PIXEL(bp,a0)); + b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0)); + b1 = finddiff(rp, b1, bits, PIXEL(bp,a0)); + } + return (1); +#undef PIXEL +} + +/* + * Encode a buffer of pixels. + */ +static int +Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "Fax3Encode"; + Fax3CodecState* sp = EncoderState(tif); + (void) s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { + if ((sp->b.mode & FAXMODE_NOEOL) == 0) + Fax3PutEOL(tif); + if (is2DEncoding(sp)) { + if (sp->tag == G3_1D) { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + sp->tag = G3_2D; + } else { + if (!Fax3Encode2DRow(tif, bp, sp->refline, + sp->b.rowpixels)) + return (0); + sp->k--; + } + if (sp->k == 0) { + sp->tag = G3_1D; + sp->k = sp->maxk-1; + } else + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + } else { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + } + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); +} + +static int +Fax3PostEncode(TIFF* tif) +{ + Fax3CodecState* sp = EncoderState(tif); + + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); +} + +static void +Fax3Close(TIFF* tif) +{ + if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { + Fax3CodecState* sp = EncoderState(tif); + unsigned int code = EOL; + unsigned int length = 12; + int i; + + if (is2DEncoding(sp)) + code = (code<<1) | (sp->tag == G3_1D), length++; + for (i = 0; i < 6; i++) + Fax3PutBits(tif, code, length); + Fax3FlushBits(tif, sp); + } +} + +static void +Fax3Cleanup(TIFF* tif) +{ + Fax3CodecState* sp = DecoderState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->b.vgetparent; + tif->tif_tagmethods.vsetfield = sp->b.vsetparent; + tif->tif_tagmethods.printdir = sp->b.printdir; + + if (sp->runs) + _TIFFfree(sp->runs); + if (sp->refline) + _TIFFfree(sp->refline); + + _TIFFfree(tif->tif_data); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +#define FIELD_BADFAXLINES (FIELD_CODEC+0) +#define FIELD_CLEANFAXDATA (FIELD_CODEC+1) +#define FIELD_BADFAXRUN (FIELD_CODEC+2) + +#define FIELD_OPTIONS (FIELD_CODEC+7) + +static const TIFFField faxFields[] = { + { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL }, + { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL }, + { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL }, + { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }}; +static const TIFFField fax3Fields[] = { + { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, +}; +static const TIFFField fax4Fields[] = { + { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL }, +}; + +static int +Fax3VSetField(TIFF* tif, uint32 tag, va_list ap) +{ + Fax3BaseState* sp = Fax3State(tif); + const TIFFField* fip; + + assert(sp != 0); + assert(sp->vsetparent != 0); + + switch (tag) { + case TIFFTAG_FAXMODE: + sp->mode = (int) va_arg(ap, int); + return 1; /* NB: pseudo tag */ + case TIFFTAG_FAXFILLFUNC: + DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); + return 1; /* NB: pseudo tag */ + case TIFFTAG_GROUP3OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + sp->groupoptions = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_GROUP4OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + sp->groupoptions = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_BADFAXLINES: + sp->badfaxlines = (uint32) va_arg(ap, uint32); + break; + case TIFFTAG_CLEANFAXDATA: + sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap); + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + sp->badfaxrun = (uint32) va_arg(ap, uint32); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + + if ((fip = TIFFFieldWithTag(tif, tag))) + TIFFSetFieldBit(tif, fip->field_bit); + else + return 0; + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; +} + +static int +Fax3VGetField(TIFF* tif, uint32 tag, va_list ap) +{ + Fax3BaseState* sp = Fax3State(tif); + + assert(sp != 0); + + switch (tag) { + case TIFFTAG_FAXMODE: + *va_arg(ap, int*) = sp->mode; + break; + case TIFFTAG_FAXFILLFUNC: + *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill; + break; + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + *va_arg(ap, uint32*) = sp->groupoptions; + break; + case TIFFTAG_BADFAXLINES: + *va_arg(ap, uint32*) = sp->badfaxlines; + break; + case TIFFTAG_CLEANFAXDATA: + *va_arg(ap, uint16*) = sp->cleanfaxdata; + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + *va_arg(ap, uint32*) = sp->badfaxrun; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static void +Fax3PrintDir(TIFF* tif, FILE* fd, long flags) +{ + Fax3BaseState* sp = Fax3State(tif); + + assert(sp != 0); + + (void) flags; + if (TIFFFieldSet(tif,FIELD_OPTIONS)) { + const char* sep = " "; + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) { + fprintf(fd, " Group 4 Options:"); + if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } else { + + fprintf(fd, " Group 3 Options:"); + if (sp->groupoptions & GROUP3OPT_2DENCODING) + fprintf(fd, "%s2-d encoding", sep), sep = "+"; + if (sp->groupoptions & GROUP3OPT_FILLBITS) + fprintf(fd, "%sEOL padding", sep), sep = "+"; + if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + fprintf(fd, " (%lu = 0x%lx)\n", + (unsigned long) sp->groupoptions, + (unsigned long) sp->groupoptions); + } + if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) { + fprintf(fd, " Fax Data:"); + switch (sp->cleanfaxdata) { + case CLEANFAXDATA_CLEAN: + fprintf(fd, " clean"); + break; + case CLEANFAXDATA_REGENERATED: + fprintf(fd, " receiver regenerated"); + break; + case CLEANFAXDATA_UNCLEAN: + fprintf(fd, " uncorrected errors"); + break; + } + fprintf(fd, " (%u = 0x%x)\n", + sp->cleanfaxdata, sp->cleanfaxdata); + } + if (TIFFFieldSet(tif,FIELD_BADFAXLINES)) + fprintf(fd, " Bad Fax Lines: %lu\n", + (unsigned long) sp->badfaxlines); + if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) + fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", + (unsigned long) sp->badfaxrun); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); +} + +static int +InitCCITTFax3(TIFF* tif) +{ + static const char module[] = "InitCCITTFax3"; + Fax3BaseState* sp; + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) { + TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3", + "Merging common CCITT Fax codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) + _TIFFmalloc(sizeof (Fax3CodecState)); + + if (tif->tif_data == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for state block"); + return (0); + } + + sp = Fax3State(tif); + sp->rw_mode = tif->tif_mode; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ + sp->groupoptions = 0; + + if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ + tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ + DecoderState(tif)->runs = NULL; + TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); + EncoderState(tif)->refline = NULL; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = Fax3FixupTags; + tif->tif_setupdecode = Fax3SetupState; + tif->tif_predecode = Fax3PreDecode; + tif->tif_decoderow = Fax3Decode1D; + tif->tif_decodestrip = Fax3Decode1D; + tif->tif_decodetile = Fax3Decode1D; + tif->tif_setupencode = Fax3SetupState; + tif->tif_preencode = Fax3PreEncode; + tif->tif_postencode = Fax3PostEncode; + tif->tif_encoderow = Fax3Encode; + tif->tif_encodestrip = Fax3Encode; + tif->tif_encodetile = Fax3Encode; + tif->tif_close = Fax3Close; + tif->tif_cleanup = Fax3Cleanup; + + return (1); +} + +int +TIFFInitCCITTFax3(TIFF* tif, int scheme) +{ + (void) scheme; + if (InitCCITTFax3(tif)) { + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax3Fields, + TIFFArrayCount(fax3Fields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", + "Merging CCITT Fax 3 codec-specific tags failed"); + return 0; + } + + /* + * The default format is Class/F-style w/o RTC. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); + } else + return 01; +} + +/* + * CCITT Group 4 (T.6) Facsimile-compatible + * Compression Scheme Support. + */ + +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +/* + * Decode the requested amount of G4-encoded data. + */ +static int +Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + DECLARE_STATE_2D(tif, sp, "Fax4Decode"); + (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; + pb = sp->refruns; + b1 = *pb++; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + EXPAND2D(EOFG4); + if (EOLcnt) + goto EOFG4; + (*sp->fill)(buf, thisrun, pa, lastx); + SETVALUE(0); /* imaginary change for reference */ + SWAP(uint32*, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFG4: + NeedBits16( 13, BADG4 ); + BADG4: +#ifdef FAX3_DEBUG + if( GetBits(13) != 0x1001 ) + fputs( "Bad EOFB\n", stderr ); +#endif + ClrBits( 13 ); + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */ + } + UNCACHE_STATE(tif, sp); + return (1); +} +#undef SWAP + +/* + * Encode the requested amount of data. + */ +static int +Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "Fax4Encode"; + Fax3CodecState *sp = EncoderState(tif); + (void) s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); +} + +static int +Fax4PostEncode(TIFF* tif) +{ + Fax3CodecState *sp = EncoderState(tif); + + /* terminate strip w/ EOFB */ + Fax3PutBits(tif, EOL, 12); + Fax3PutBits(tif, EOL, 12); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); +} + +int +TIFFInitCCITTFax4(TIFF* tif, int scheme) +{ + (void) scheme; + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax4Fields, + TIFFArrayCount(fax4Fields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4", + "Merging CCITT Fax 4 codec-specific tags failed"); + return 0; + } + + tif->tif_decoderow = Fax4Decode; + tif->tif_decodestrip = Fax4Decode; + tif->tif_decodetile = Fax4Decode; + tif->tif_encoderow = Fax4Encode; + tif->tif_encodestrip = Fax4Encode; + tif->tif_encodetile = Fax4Encode; + tif->tif_postencode = Fax4PostEncode; + /* + * Suppress RTC at the end of each strip. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); + } else + return (0); +} + +/* + * CCITT Group 3 1-D Modified Huffman RLE Compression Support. + * (Compression algorithms 2 and 32771) + */ + +/* + * Decode the requested amount of RLE-encoded data. + */ +static int +Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); + int mode = sp->b.mode; + (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + EXPAND1D(EOFRLE); + (*sp->fill)(buf, thisrun, pa, lastx); + /* + * Cleanup at the end of the row. + */ + if (mode & FAXMODE_BYTEALIGN) { + int n = BitsAvail - (BitsAvail &~ 7); + ClrBits(n); + } else if (mode & FAXMODE_WORDALIGN) { + int n = BitsAvail - (BitsAvail &~ 15); + ClrBits(n); + if (BitsAvail == 0 && !isAligned(cp, uint16)) + cp++; + } + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFRLE: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} + +int +TIFFInitCCITTRLE(TIFF* tif, int scheme) +{ + (void) scheme; + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and byte-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN); + } else + return (0); +} + +int +TIFFInitCCITTRLEW(TIFF* tif, int scheme) +{ + (void) scheme; + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and word-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN); + } else + return (0); +} +#endif /* CCITT_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,538 @@ +/* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _FAX3_ +#define _FAX3_ +/* + * TIFF Library. + * + * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support. + * + * Decoder support is derived, with permission, from the code + * in Frank Cringle's viewfax program; + * Copyright (C) 1990, 1995 Frank D. Cringle. + */ +#include "tiff.h" + +/* + * To override the default routine used to image decoded + * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC. + * The routine must have the type signature given below; + * for example: + * + * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) + * + * where buf is place to set the bits, runs is the array of b&w run + * lengths (white then black), erun is the last run in the array, and + * lastx is the width of the row in pixels. Fill routines can assume + * the run array has room for at least lastx runs and can overwrite + * data in the run array as needed (e.g. to append zero runs to bring + * the count up to a nice multiple). + */ +typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); + +/* + * The default run filler; made external for other decoders. + */ +#if defined(__cplusplus) +extern "C" { +#endif +extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); +#if defined(__cplusplus) +} +#endif + + +/* finite state machine codes */ +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 + +typedef struct { /* state table entry */ + unsigned char State; /* see above */ + unsigned char Width; /* width of code in bits */ + uint32 Param; /* unsigned 32-bit run length in bits */ +} TIFFFaxTabEnt; + +extern const TIFFFaxTabEnt TIFFFaxMainTable[]; +extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; +extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; + +/* + * The following macros define the majority of the G3/G4 decoder + * algorithm using the state tables defined elsewhere. To build + * a decoder you need some setup code and some glue code. Note + * that you may also need/want to change the way the NeedBits* + * macros get input data if, for example, you know the data to be + * decoded is properly aligned and oriented (doing so before running + * the decoder can be a big performance win). + * + * Consult the decoder in the TIFF library for an idea of what you + * need to define and setup to make use of these definitions. + * + * NB: to enable a debugging version of these macros define FAX3_DEBUG + * before including this file. Trace output goes to stdout. + */ + +#ifndef EndOfData +#define EndOfData() (cp >= ep) +#endif +/* + * Need <=8 or <=16 bits of input data. Unlike viewfax we + * cannot use/assume a word-aligned, properly bit swizzled + * input data set because data may come from an arbitrarily + * aligned, read-only source such as a memory-mapped file. + * Note also that the viewfax decoder does not check for + * running off the end of the input data buffer. This is + * possible for G3-encoded data because it prescans the input + * data to count EOL markers, but can cause problems for G4 + * data. In any event, we don't prescan and must watch for + * running out of data since we can't permit the library to + * scan past the end of the input data buffer. + * + * Finally, note that we must handle remaindered data at the end + * of a strip specially. The coder asks for a fixed number of + * bits when scanning for the next code. This may be more bits + * than are actually present in the data stream. If we appear + * to run out of data but still have some number of valid bits + * remaining then we makeup the requested amount with zeros and + * return successfully. If the returned data is incorrect then + * we should be called again and get a premature EOF error; + * otherwise we should get the right answer. + */ +#ifndef NeedBits8 +#define NeedBits8(n,eoflab) do { \ + if (BitsAvail < (n)) { \ + if (EndOfData()) { \ + if (BitsAvail == 0) /* no valid bits */ \ + goto eoflab; \ + BitsAvail = (n); /* pad with zeros */ \ + } else { \ + BitAcc |= ((uint32) bitmap[*cp++])<>= (n); \ +} while (0) + +#ifdef FAX3_DEBUG +static const char* StateNames[] = { + "Null ", + "Pass ", + "Horiz ", + "V0 ", + "VR ", + "VL ", + "Ext ", + "TermW ", + "TermB ", + "MakeUpW", + "MakeUpB", + "MakeUp ", + "EOL ", +}; +#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') +#define LOOKUP8(wid,tab,eoflab) do { \ + int t; \ + NeedBits8(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ +} while (0) +#define LOOKUP16(wid,tab,eoflab) do { \ + int t; \ + NeedBits16(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ +} while (0) + +#define SETVALUE(x) do { \ + *pa++ = RunLength + (x); \ + printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ + a0 += x; \ + RunLength = 0; \ +} while (0) +#else +#define LOOKUP8(wid,tab,eoflab) do { \ + NeedBits8(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ +} while (0) +#define LOOKUP16(wid,tab,eoflab) do { \ + NeedBits16(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ +} while (0) + +/* + * Append a run to the run length array for the + * current row and reset decoding state. + */ +#define SETVALUE(x) do { \ + *pa++ = RunLength + (x); \ + a0 += (x); \ + RunLength = 0; \ +} while (0) +#endif + +/* + * Synchronize input decoding at the start of each + * row by scanning for an EOL (if appropriate) and + * skipping any trash data that might be present + * after a decoding error. Note that the decoding + * done elsewhere that recognizes an EOL only consumes + * 11 consecutive zero bits. This means that if EOLcnt + * is non-zero then we still need to scan for the final flag + * bit that is part of the EOL code. + */ +#define SYNC_EOL(eoflab) do { \ + if (EOLcnt == 0) { \ + for (;;) { \ + NeedBits16(11,eoflab); \ + if (GetBits(11) == 0) \ + break; \ + ClrBits(1); \ + } \ + } \ + for (;;) { \ + NeedBits8(8,eoflab); \ + if (GetBits(8)) \ + break; \ + ClrBits(8); \ + } \ + while (GetBits(1) == 0) \ + ClrBits(1); \ + ClrBits(1); /* EOL bit */ \ + EOLcnt = 0; /* reset EOL counter/flag */ \ +} while (0) + +/* + * Cleanup the array of runs after decoding a row. + * We adjust final runs to insure the user buffer is not + * overwritten and/or undecoded area is white filled. + */ +#define CLEANUP_RUNS() do { \ + if (RunLength) \ + SETVALUE(0); \ + if (a0 != lastx) { \ + badlength(a0, lastx); \ + while (a0 > lastx && pa > thisrun) \ + a0 -= *--pa; \ + if (a0 < lastx) { \ + if (a0 < 0) \ + a0 = 0; \ + if ((pa-thisrun)&1) \ + SETVALUE(0); \ + SETVALUE(lastx - a0); \ + } else if (a0 > lastx) { \ + SETVALUE(lastx); \ + SETVALUE(0); \ + } \ + } \ +} while (0) + +/* + * Decode a line of 1D-encoded data. + * + * The line expanders are written as macros so that they can be reused + * but still have direct access to the local variables of the "calling" + * function. + * + * Note that unlike the original version we have to explicitly test for + * a0 >= lastx after each black/white run is decoded. This is because + * the original code depended on the input data being zero-padded to + * insure the decoder recognized an EOL before running out of data. + */ +#define EXPAND1D(eoflab) do { \ + for (;;) { \ + for (;;) { \ + LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite1d; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", a0); \ + goto done1d; \ + } \ + } \ + doneWhite1d: \ + if (a0 >= lastx) \ + goto done1d; \ + for (;;) { \ + LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack1d; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", a0); \ + goto done1d; \ + } \ + } \ + doneBlack1d: \ + if (a0 >= lastx) \ + goto done1d; \ + if( *(pa-1) == 0 && *(pa-2) == 0 ) \ + pa -= 2; \ + } \ +eof1d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ +done1d: \ + CLEANUP_RUNS(); \ +} while (0) + +/* + * Update the value of b1 using the array + * of runs for the reference line. + */ +#define CHECK_b1 do { \ + if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \ + b1 += pb[0] + pb[1]; \ + pb += 2; \ + } \ +} while (0) + +/* + * Expand a row of 2D-encoded data. + */ +#define EXPAND2D(eoflab) do { \ + while (a0 < lastx) { \ + LOOKUP8(7, TIFFFaxMainTable, eof2d); \ + switch (TabEnt->State) { \ + case S_Pass: \ + CHECK_b1; \ + b1 += *pb++; \ + RunLength += b1 - a0; \ + a0 = b1; \ + b1 += *pb++; \ + break; \ + case S_Horiz: \ + if ((pa-thisrun)&1) { \ + for (;;) { /* black first */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2da; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneWhite2da:; \ + for (;;) { /* then white */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2da; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneBlack2da:; \ + } else { \ + for (;;) { /* white first */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2db; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneWhite2db:; \ + for (;;) { /* then black */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2db; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneBlack2db:; \ + } \ + CHECK_b1; \ + break; \ + case S_V0: \ + CHECK_b1; \ + SETVALUE(b1 - a0); \ + b1 += *pb++; \ + break; \ + case S_VR: \ + CHECK_b1; \ + SETVALUE(b1 - a0 + TabEnt->Param); \ + b1 += *pb++; \ + break; \ + case S_VL: \ + CHECK_b1; \ + if (b1 <= (int) (a0 + TabEnt->Param)) { \ + if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \ + unexpected("VL", a0); \ + goto eol2d; \ + } \ + } \ + SETVALUE(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ + case S_Ext: \ + *pa++ = lastx - a0; \ + extension(a0); \ + goto eol2d; \ + case S_EOL: \ + *pa++ = lastx - a0; \ + NeedBits8(4,eof2d); \ + if (GetBits(4)) \ + unexpected("EOL", a0); \ + ClrBits(4); \ + EOLcnt = 1; \ + goto eol2d; \ + default: \ + badMain2d: \ + unexpected("MainTable", a0); \ + goto eol2d; \ + badBlack2d: \ + unexpected("BlackTable", a0); \ + goto eol2d; \ + badWhite2d: \ + unexpected("WhiteTable", a0); \ + goto eol2d; \ + eof2d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + } \ + } \ + if (RunLength) { \ + if (RunLength + a0 < lastx) { \ + /* expect a final V0 */ \ + NeedBits8(1,eof2d); \ + if (!GetBits(1)) \ + goto badMain2d; \ + ClrBits(1); \ + } \ + SETVALUE(0); \ + } \ +eol2d: \ + CLEANUP_RUNS(); \ +} while (0) +#endif /* _FAX3_ */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3sm.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3sm.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3sm.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_fax3sm.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1260 @@ +/* WARNING, this file was automatically generated by the + mkg3states program */ +#include "tiff.h" +#include "tif_fax3.h" + const TIFFFaxTabEnt TIFFFaxMainTable[128] = { +{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0}, +{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0}, +{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, +{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, +{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0}, +{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0}, +{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, +{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, +{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0}, +{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0}, +{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, +{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, +{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0} +}; + const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = { +{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, +{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, +{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8}, +{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, +{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, +{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5}, +{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, +{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, +{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, +{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, +{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17}, +{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, +{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, +{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6}, +{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8}, +{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, +{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, +{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, +{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, +{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, +{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, +{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6}, +{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, +{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, +{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, +{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8}, +{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, +{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, +{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5}, +{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, +{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6}, +{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, +{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, +{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17}, +{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, +{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, +{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, +{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, +{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, +{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, +{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, +{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128}, +{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, +{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, +{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6}, +{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, +{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, +{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, +{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8}, +{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, +{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, +{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5}, +{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, +{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, +{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, +{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, +{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17}, +{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, +{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, +{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6}, +{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8}, +{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, +{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, +{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, +{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, +{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, +{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, +{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6}, +{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, +{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, +{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, +{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8}, +{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, +{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, +{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5}, +{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, +{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6}, +{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, +{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, +{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17}, +{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, +{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, +{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, +{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, +{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, +{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, +{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, +{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128}, +{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, +{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, +{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6}, +{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, +{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, +{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, +{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8}, +{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, +{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, +{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5}, +{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, +{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, +{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, +{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, +{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17}, +{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, +{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, +{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6}, +{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8}, +{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, +{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, +{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, +{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, +{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, +{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, +{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6}, +{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, +{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, +{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, +{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8}, +{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, +{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, +{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5}, +{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, +{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, +{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6}, +{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, +{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, +{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17}, +{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, +{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, +{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, +{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, +{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, +{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, +{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, +{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, +{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128}, +{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, +{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, +{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, +{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, +{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, +{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6}, +{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, +{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, +{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, +{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, +{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, +{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, +{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, +{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, +{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, +{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8}, +{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, +{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, +{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, +{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3}, +{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, +{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, +{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, +{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, +{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5}, +{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, +{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, +{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, +{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, +{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, +{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, +{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, +{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7} +}; + const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = { +{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, +{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3}, +{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, +{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, +{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, +{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, +{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, +{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, +{8,3,4},{8,2,2} +}; +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_flush.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_flush.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_flush.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_flush.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,118 @@ +/* $Id: tif_flush.c,v 1.9 2010-03-31 06:40:10 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +int +TIFFFlush(TIFF* tif) +{ + if( tif->tif_mode == O_RDONLY ) + return 1; + + if (!TIFFFlushData(tif)) + return (0); + + /* In update (r+) mode we try to detect the case where + only the strip/tile map has been altered, and we try to + rewrite only that portion of the directory without + making any other changes */ + + if( (tif->tif_flags & TIFF_DIRTYSTRIP) + && !(tif->tif_flags & TIFF_DIRTYDIRECT) + && tif->tif_mode == O_RDWR ) + { + uint64 *offsets=NULL, *sizes=NULL; + + if( TIFFIsTiled(tif) ) + { + if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets ) + && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes ) + && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8, + tif->tif_dir.td_nstrips, offsets ) + && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8, + tif->tif_dir.td_nstrips, sizes ) ) + { + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + tif->tif_flags &= ~TIFF_BEENWRITING; + return 1; + } + } + else + { + if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets ) + && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes ) + && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8, + tif->tif_dir.td_nstrips, offsets ) + && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8, + tif->tif_dir.td_nstrips, sizes ) ) + { + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + tif->tif_flags &= ~TIFF_BEENWRITING; + return 1; + } + } + } + + if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) + && !TIFFRewriteDirectory(tif)) + return (0); + + return (1); +} + +/* + * Flush buffered data to the file. + * + * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING + * is not set, so that TIFFFlush() will proceed to write out the directory. + * The documentation says returning 1 is an error indicator, but not having + * been writing isn't exactly a an error. Hopefully this doesn't cause + * problems for other people. + */ +int +TIFFFlushData(TIFF* tif) +{ + if ((tif->tif_flags & TIFF_BEENWRITING) == 0) + return (1); + if (tif->tif_flags & TIFF_POSTENCODE) { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + return (0); + } + return (TIFFFlushData1(tif)); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_getimage.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_getimage.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_getimage.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_getimage.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2867 @@ +/* $Id: tif_getimage.c,v 1.82 2012-06-06 00:17:49 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Read and return a packed RGBA image. + */ +#include "tiffiop.h" +#include + +static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); +static int PickContigCase(TIFFRGBAImage*); +static int PickSeparateCase(TIFFRGBAImage*); + +static int BuildMapUaToAa(TIFFRGBAImage* img); +static int BuildMapBitdepth16To8(TIFFRGBAImage* img); + +static const char photoTag[] = "PhotometricInterpretation"; + +/* + * Helper constants used in Orientation tag handling + */ +#define FLIP_VERTICALLY 0x01 +#define FLIP_HORIZONTALLY 0x02 + +/* + * Color conversion constants. We will define display types here. + */ + +static const TIFFDisplay display_sRGB = { + { /* XYZ -> luminance matrix */ + { 3.2410F, -1.5374F, -0.4986F }, + { -0.9692F, 1.8760F, 0.0416F }, + { 0.0556F, -0.2040F, 1.0570F } + }, + 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ + 255, 255, 255, /* Pixel values for ref. white */ + 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ + 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ +}; + +/* + * Check the image to see if TIFFReadRGBAImage can deal with it. + * 1/0 is returned according to whether or not the image can + * be handled. If 0 is returned, emsg contains the reason + * why it is being rejected. + */ +int +TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) +{ + TIFFDirectory* td = &tif->tif_dir; + uint16 photometric; + int colorchannels; + + if (!tif->tif_decodestatus) { + sprintf(emsg, "Sorry, requested compression method is not configured"); + return (0); + } + switch (td->td_bitspersample) { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + sprintf(emsg, "Sorry, can not handle images with %d-bit samples", + td->td_bitspersample); + return (0); + } + colorchannels = td->td_samplesperpixel - td->td_extrasamples; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + switch (colorchannels) { + case 1: + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + photometric = PHOTOMETRIC_RGB; + break; + default: + sprintf(emsg, "Missing needed %s tag", photoTag); + return (0); + } + } + switch (photometric) { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + if (td->td_planarconfig == PLANARCONFIG_CONTIG + && td->td_samplesperpixel != 1 + && td->td_bitspersample < 8 ) { + sprintf(emsg, + "Sorry, can not handle contiguous data with %s=%d, " + "and %s=%d and Bits/Sample=%d", + photoTag, photometric, + "Samples/pixel", td->td_samplesperpixel, + td->td_bitspersample); + return (0); + } + /* + * We should likely validate that any extra samples are either + * to be ignored, or are alpha, and if alpha we should try to use + * them. But for now we won't bother with this. + */ + break; + case PHOTOMETRIC_YCBCR: + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningfull + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) { + sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + return (0); + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16 inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) { + sprintf(emsg, + "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + return 0; + } + if (td->td_samplesperpixel < 4) { + sprintf(emsg, + "Sorry, can not handle separated image with %s=%d", + "Samples/pixel", td->td_samplesperpixel); + return 0; + } + break; + } + case PHOTOMETRIC_LOGL: + if (td->td_compression != COMPRESSION_SGILOG) { + sprintf(emsg, "Sorry, LogL data must have %s=%d", + "Compression", COMPRESSION_SGILOG); + return (0); + } + break; + case PHOTOMETRIC_LOGLUV: + if (td->td_compression != COMPRESSION_SGILOG && + td->td_compression != COMPRESSION_SGILOG24) { + sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); + return (0); + } + if (td->td_planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", + "Planarconfiguration", td->td_planarconfig); + return (0); + } + break; + case PHOTOMETRIC_CIELAB: + break; + default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, photometric); + return (0); + } + return (1); +} + +void +TIFFRGBAImageEnd(TIFFRGBAImage* img) +{ + if (img->Map) + _TIFFfree(img->Map), img->Map = NULL; + if (img->BWmap) + _TIFFfree(img->BWmap), img->BWmap = NULL; + if (img->PALmap) + _TIFFfree(img->PALmap), img->PALmap = NULL; + if (img->ycbcr) + _TIFFfree(img->ycbcr), img->ycbcr = NULL; + if (img->cielab) + _TIFFfree(img->cielab), img->cielab = NULL; + if (img->UaToAa) + _TIFFfree(img->UaToAa), img->UaToAa = NULL; + if (img->Bitdepth16To8) + _TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL; + + if( img->redcmap ) { + _TIFFfree( img->redcmap ); + _TIFFfree( img->greencmap ); + _TIFFfree( img->bluecmap ); + img->redcmap = img->greencmap = img->bluecmap = NULL; + } +} + +static int +isCCITTCompression(TIFF* tif) +{ + uint16 compress; + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); + return (compress == COMPRESSION_CCITTFAX3 || + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); +} + +int +TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) +{ + uint16* sampleinfo; + uint16 extrasamples; + uint16 planarconfig; + uint16 compress; + int colorchannels; + uint16 *red_orig, *green_orig, *blue_orig; + int n_color; + + /* Initialize to normal values */ + img->row_offset = 0; + img->col_offset = 0; + img->redcmap = NULL; + img->greencmap = NULL; + img->bluecmap = NULL; + img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ + + img->tif = tif; + img->stoponerr = stop; + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); + switch (img->bitspersample) { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + sprintf(emsg, "Sorry, can not handle images with %d-bit samples", + img->bitspersample); + goto fail_return; + } + img->alpha = 0; + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, + &extrasamples, &sampleinfo); + if (extrasamples >= 1) + { + switch (sampleinfo[0]) { + case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */ + if (img->samplesperpixel > 3) /* correct info about alpha channel */ + img->alpha = EXTRASAMPLE_ASSOCALPHA; + break; + case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ + img->alpha = sampleinfo[0]; + break; + } + } + +#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA + if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) + img->photometric = PHOTOMETRIC_MINISWHITE; + + if( extrasamples == 0 + && img->samplesperpixel == 4 + && img->photometric == PHOTOMETRIC_RGB ) + { + img->alpha = EXTRASAMPLE_ASSOCALPHA; + extrasamples = 1; + } +#endif + + colorchannels = img->samplesperpixel - extrasamples; + TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { + switch (colorchannels) { + case 1: + if (isCCITTCompression(tif)) + img->photometric = PHOTOMETRIC_MINISWHITE; + else + img->photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + img->photometric = PHOTOMETRIC_RGB; + break; + default: + sprintf(emsg, "Missing needed %s tag", photoTag); + goto fail_return; + } + } + switch (img->photometric) { + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, + &red_orig, &green_orig, &blue_orig)) { + sprintf(emsg, "Missing required \"Colormap\" tag"); + goto fail_return; + } + + /* copy the colormaps so we can modify them */ + n_color = (1L << img->bitspersample); + img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); + img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); + img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); + if( !img->redcmap || !img->greencmap || !img->bluecmap ) { + sprintf(emsg, "Out of memory for colormap copy"); + goto fail_return; + } + + _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); + _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 ); + _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 ); + + /* fall thru... */ + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (planarconfig == PLANARCONFIG_CONTIG + && img->samplesperpixel != 1 + && img->bitspersample < 8 ) { + sprintf(emsg, + "Sorry, can not handle contiguous data with %s=%d, " + "and %s=%d and Bits/Sample=%d", + photoTag, img->photometric, + "Samples/pixel", img->samplesperpixel, + img->bitspersample); + goto fail_return; + } + break; + case PHOTOMETRIC_YCBCR: + /* It would probably be nice to have a reality check here. */ + if (planarconfig == PLANARCONFIG_CONTIG) + /* can rely on libjpeg to convert to RGB */ + /* XXX should restore current state on exit */ + switch (compress) { + case COMPRESSION_JPEG: + /* + * TODO: when complete tests verify complete desubsampling + * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in + * favor of tif_getimage.c native handling + */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + img->photometric = PHOTOMETRIC_RGB; + break; + default: + /* do nothing */; + break; + } + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningfull + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) { + sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + goto fail_return; + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16 inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + goto fail_return; + } + if (img->samplesperpixel < 4) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "Samples/pixel", img->samplesperpixel); + goto fail_return; + } + } + break; + case PHOTOMETRIC_LOGL: + if (compress != COMPRESSION_SGILOG) { + sprintf(emsg, "Sorry, LogL data must have %s=%d", + "Compression", COMPRESSION_SGILOG); + goto fail_return; + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_LOGLUV: + if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { + sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); + goto fail_return; + } + if (planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", + "Planarconfiguration", planarconfig); + return (0); + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_RGB; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_CIELAB: + break; + default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, img->photometric); + goto fail_return; + } + img->Map = NULL; + img->BWmap = NULL; + img->PALmap = NULL; + img->ycbcr = NULL; + img->cielab = NULL; + img->UaToAa = NULL; + img->Bitdepth16To8 = NULL; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); + img->isContig = + !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); + if (img->isContig) { + if (!PickContigCase(img)) { + sprintf(emsg, "Sorry, can not handle image"); + goto fail_return; + } + } else { + if (!PickSeparateCase(img)) { + sprintf(emsg, "Sorry, can not handle image"); + goto fail_return; + } + } + return 1; + + fail_return: + _TIFFfree( img->redcmap ); + _TIFFfree( img->greencmap ); + _TIFFfree( img->bluecmap ); + img->redcmap = img->greencmap = img->bluecmap = NULL; + return 0; +} + +int +TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + if (img->get == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup"); + return (0); + } + if (img->put.any == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), + "No \"put\" routine setupl; probably can not handle image format"); + return (0); + } + return (*img->get)(img, raster, w, h); +} + +/* + * Read the specified image into an ABGR-format rastertaking in account + * specified orientation. + */ +int +TIFFReadRGBAImageOriented(TIFF* tif, + uint32 rwidth, uint32 rheight, uint32* raster, + int orientation, int stop) +{ + char emsg[1024] = ""; + TIFFRGBAImage img; + int ok; + + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) { + img.req_orientation = orientation; + /* XXX verify rwidth and rheight against width and height */ + ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, + rwidth, img.height); + TIFFRGBAImageEnd(&img); + } else { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); + ok = 0; + } + return (ok); +} + +/* + * Read the specified image into an ABGR-format raster. Use bottom left + * origin for raster by default. + */ +int +TIFFReadRGBAImage(TIFF* tif, + uint32 rwidth, uint32 rheight, uint32* raster, int stop) +{ + return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, + ORIENTATION_BOTLEFT, stop); +} + +static int +setorientation(TIFFRGBAImage* img) +{ + switch (img->orientation) { + case ORIENTATION_TOPLEFT: + case ORIENTATION_LEFTTOP: + if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_TOPRIGHT: + case ORIENTATION_RIGHTTOP: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_BOTRIGHT: + case ORIENTATION_RIGHTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + case ORIENTATION_BOTLEFT: + case ORIENTATION_LEFTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + default: /* NOTREACHED */ + return 0; + } +} + +/* + * Get an tile-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileContigRoutine put = img->put.contig; + uint32 col, row, y, rowstoread; + tmsize_t pos; + uint32 tw, th; + unsigned char* buf; + int32 fromskew, toskew; + uint32 nrow; + int ret = 1, flip; + + buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); + return (0); + } + _TIFFmemset(buf, 0, TIFFTileSize(tif)); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) { + y = h - 1; + toskew = -(int32)(tw + w); + } + else { + y = 0; + toskew = -(int32)(tw - w); + } + + for (row = 0; row < h; row += nrow) + { + rowstoread = th - (row + img->row_offset) % th; + nrow = (row + rowstoread > h ? h - row : rowstoread); + for (col = 0; col < w; col += tw) + { + if (TIFFReadTile(tif, buf, col+img->col_offset, + row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr) + { + ret = 0; + break; + } + + pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); + + if (col + tw > w) + { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*put)(img, raster+y*w+col, col, y, + npix, nrow, fromskew, toskew + fromskew, buf + pos); + } + else + { + (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos); + } + } + + y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + } + _TIFFfree(buf); + + if (flip & FLIP_HORIZONTALLY) { + uint32 line; + + for (line = 0; line < h; line++) { + uint32 *left = raster + (line * w); + uint32 *right = left + w - 1; + + while ( left < right ) { + uint32 temp = *left; + *left = *right; + *right = temp; + left++, right--; + } + } + } + + return (ret); +} + +/* + * Get an tile-organized image that has + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileSeparateRoutine put = img->put.separate; + uint32 col, row, y, rowstoread; + tmsize_t pos; + uint32 tw, th; + unsigned char* buf; + unsigned char* p0; + unsigned char* p1; + unsigned char* p2; + unsigned char* pa; + tmsize_t tilesize; + tmsize_t bufsize; + int32 fromskew, toskew; + int alpha = img->alpha; + uint32 nrow; + int ret = 1, flip; + int colorchannels; + + tilesize = TIFFTileSize(tif); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize); + if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); + return (0); + } + buf = (unsigned char*) _TIFFmalloc(bufsize); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); + return (0); + } + _TIFFmemset(buf, 0, bufsize); + p0 = buf; + p1 = p0 + tilesize; + p2 = p1 + tilesize; + pa = (alpha?(p2+tilesize):NULL); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) { + y = h - 1; + toskew = -(int32)(tw + w); + } + else { + y = 0; + toskew = -(int32)(tw - w); + } + + switch( img->photometric ) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + colorchannels = 1; + p2 = p1 = p0; + break; + + default: + colorchannels = 3; + break; + } + + for (row = 0; row < h; row += nrow) + { + rowstoread = th - (row + img->row_offset) % th; + nrow = (row + rowstoread > h ? h - row : rowstoread); + for (col = 0; col < w; col += tw) + { + if (TIFFReadTile(tif, p0, col+img->col_offset, + row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 + && TIFFReadTile(tif, p1, col+img->col_offset, + row+img->row_offset,0,1) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 + && TIFFReadTile(tif, p2, col+img->col_offset, + row+img->row_offset,0,2) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + if (alpha + && TIFFReadTile(tif,pa,col+img->col_offset, + row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + + pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); + + if (col + tw > w) + { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*put)(img, raster+y*w+col, col, y, + npix, nrow, fromskew, toskew + fromskew, + p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); + } else { + (*put)(img, raster+y*w+col, col, y, + tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); + } + } + + y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); + } + + if (flip & FLIP_HORIZONTALLY) { + uint32 line; + + for (line = 0; line < h; line++) { + uint32 *left = raster + (line * w); + uint32 *right = left + w - 1; + + while ( left < right ) { + uint32 temp = *left; + *left = *right; + *right = temp; + left++, right--; + } + } + } + + _TIFFfree(buf); + return (ret); +} + +/* + * Get a strip-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileContigRoutine put = img->put.contig; + uint32 row, y, nrow, nrowsub, rowstoread; + tmsize_t pos; + unsigned char* buf; + uint32 rowsperstrip; + uint16 subsamplinghor,subsamplingver; + uint32 imagewidth = img->width; + tmsize_t scanline; + int32 fromskew, toskew; + int ret = 1, flip; + + buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); + return (0); + } + _TIFFmemset(buf, 0, TIFFStripSize(tif)); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) { + y = h - 1; + toskew = -(int32)(w + w); + } else { + y = 0; + toskew = -(int32)(w - w); + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + nrowsub = nrow; + if ((nrowsub%subsamplingver)!=0) + nrowsub+=subsamplingver-nrowsub%subsamplingver; + if (TIFFReadEncodedStrip(tif, + TIFFComputeStrip(tif,row+img->row_offset, 0), + buf, + ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + + pos = ((row + img->row_offset) % rowsperstrip) * scanline; + (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); + y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + } + + if (flip & FLIP_HORIZONTALLY) { + uint32 line; + + for (line = 0; line < h; line++) { + uint32 *left = raster + (line * w); + uint32 *right = left + w - 1; + + while ( left < right ) { + uint32 temp = *left; + *left = *right; + *right = temp; + left++, right--; + } + } + } + + _TIFFfree(buf); + return (ret); +} + +/* + * Get a strip-organized image with + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileSeparateRoutine put = img->put.separate; + unsigned char *buf; + unsigned char *p0, *p1, *p2, *pa; + uint32 row, y, nrow, rowstoread; + tmsize_t pos; + tmsize_t scanline; + uint32 rowsperstrip, offset_row; + uint32 imagewidth = img->width; + tmsize_t stripsize; + tmsize_t bufsize; + int32 fromskew, toskew; + int alpha = img->alpha; + int ret = 1, flip, colorchannels; + + stripsize = TIFFStripSize(tif); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize); + if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); + return (0); + } + p0 = buf = (unsigned char *)_TIFFmalloc(bufsize); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + _TIFFmemset(buf, 0, bufsize); + p1 = p0 + stripsize; + p2 = p1 + stripsize; + pa = (alpha?(p2+stripsize):NULL); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) { + y = h - 1; + toskew = -(int32)(w + w); + } + else { + y = 0; + toskew = -(int32)(w - w); + } + + switch( img->photometric ) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + colorchannels = 1; + p2 = p1 = p0; + break; + + default: + colorchannels = 3; + break; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + offset_row = row + img->row_offset; + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), + p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 + && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), + p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 + && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), + p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + if (alpha) + { + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), + pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; + } + } + + pos = ((row + img->row_offset) % rowsperstrip) * scanline; + (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, + p2 + pos, (alpha?(pa+pos):NULL)); + y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + } + + if (flip & FLIP_HORIZONTALLY) { + uint32 line; + + for (line = 0; line < h; line++) { + uint32 *left = raster + (line * w); + uint32 *right = left + w - 1; + + while ( left < right ) { + uint32 temp = *left; + *left = *right; + *right = temp; + left++, right--; + } + } + } + + _TIFFfree(buf); + return (ret); +} + +/* + * The following routines move decoded data returned + * from the TIFF library into rasters filled with packed + * ABGR pixels (i.e. suitable for passing to lrecwrite.) + * + * The routines have been created according to the most + * important cases and optimized. PickContigCase and + * PickSeparateCase analyze the parameters and select + * the appropriate "get" and "put" routine to use. + */ +#define REPEAT8(op) REPEAT4(op); REPEAT4(op) +#define REPEAT4(op) REPEAT2(op); REPEAT2(op) +#define REPEAT2(op) op; op +#define CASE8(x,op) \ + switch (x) { \ + case 7: op; case 6: op; case 5: op; \ + case 4: op; case 3: op; case 2: op; \ + case 1: op; \ + } +#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } +#define NOP + +#define UNROLL8(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 8; _x -= 8) { \ + op1; \ + REPEAT8(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE8(_x,op2); \ + } \ +} +#define UNROLL4(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 4; _x -= 4) { \ + op1; \ + REPEAT4(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE4(_x,op2); \ + } \ +} +#define UNROLL2(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 2; _x -= 2) { \ + op1; \ + REPEAT2(op2); \ + } \ + if (_x) { \ + op1; \ + op2; \ + } \ +} + +#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } +#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } + +#define A1 (((uint32)0xffL)<<24) +#define PACK(r,g,b) \ + ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) +#define PACK4(r,g,b,a) \ + ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) +#define W2B(v) (((v)>>8)&0xff) +/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ +#define PACKW(r,g,b) \ + ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) +#define PACKW4(r,g,b,a) \ + ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) + +#define DECLAREContigPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img, \ + uint32* cp, \ + uint32 x, uint32 y, \ + uint32 w, uint32 h, \ + int32 fromskew, int32 toskew, \ + unsigned char* pp \ +) + +/* + * 8-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put8bitcmaptile) +{ + uint32** PALmap = img->PALmap; + int samplesperpixel = img->samplesperpixel; + + (void) y; + while (h-- > 0) { + for (x = w; x-- > 0;) + { + *cp++ = PALmap[*pp][0]; + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 4-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put4bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 2; + while (h-- > 0) { + uint32* bw; + UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 2-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put2bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 4; + while (h-- > 0) { + uint32* bw; + UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 1-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put1bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 8; + while (h-- > 0) { + uint32* bw; + UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(putgreytile) +{ + int samplesperpixel = img->samplesperpixel; + uint32** BWmap = img->BWmap; + + (void) y; + while (h-- > 0) { + for (x = w; x-- > 0;) + { + *cp++ = BWmap[*pp][0]; + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit greyscale with associated alpha => colormap/RGBA + */ +DECLAREContigPutFunc(putagreytile) +{ + int samplesperpixel = img->samplesperpixel; + uint32** BWmap = img->BWmap; + + (void) y; + while (h-- > 0) { + for (x = w; x-- > 0;) + { + *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 16-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(put16bitbwtile) +{ + int samplesperpixel = img->samplesperpixel; + uint32** BWmap = img->BWmap; + + (void) y; + while (h-- > 0) { + uint16 *wp = (uint16 *) pp; + + for (x = w; x-- > 0;) + { + /* use high order byte of 16bit value */ + + *cp++ = BWmap[*wp >> 8][0]; + pp += 2 * samplesperpixel; + wp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 1-bit bilevel => colormap/RGB + */ +DECLAREContigPutFunc(put1bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 8; + while (h-- > 0) { + uint32* bw; + UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 2-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(put2bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 4; + while (h-- > 0) { + uint32* bw; + UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 4-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(put4bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 2; + while (h-- > 0) { + uint32* bw; + UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples, no Map => RGB + */ +DECLAREContigPutFunc(putRGBcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + *cp++ = PACK(pp[0], pp[1], pp[2]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples => RGBA w/ associated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBAAcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples => RGBA w/ unassociated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBUAcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + uint32 r, g, b, a; + uint8* m; + for (x = w; x-- > 0;) { + a = pp[3]; + m = img->UaToAa+(a<<8); + r = m[pp[0]]; + g = m[pp[1]]; + b = m[pp[2]]; + *cp++ = PACK4(r,g,b,a); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 16-bit packed samples => RGB + */ +DECLAREContigPutFunc(putRGBcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = PACK(img->Bitdepth16To8[wp[0]], + img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 16-bit packed samples => RGBA w/ associated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBAAcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = PACK4(img->Bitdepth16To8[wp[0]], + img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]], + img->Bitdepth16To8[wp[3]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 16-bit packed samples => RGBA w/ unassociated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBUAcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + uint32 r,g,b,a; + uint8* m; + for (x = w; x-- > 0;) { + a = img->Bitdepth16To8[wp[3]]; + m = img->UaToAa+(a<<8); + r = m[img->Bitdepth16To8[wp[0]]]; + g = m[img->Bitdepth16To8[wp[1]]]; + b = m[img->Bitdepth16To8[wp[2]]]; + *cp++ = PACK4(r,g,b,a); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 8-bit packed CMYK samples w/o Map => RGB + * + * NB: The conversion of CMYK->RGB is *very* crude. + */ +DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 r, g, b, k; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = PACK(r, g, b); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed CMYK samples w/Map => RGB + * + * NB: The conversion of CMYK->RGB is *very* crude. + */ +DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) +{ + int samplesperpixel = img->samplesperpixel; + TIFFRGBValue* Map = img->Map; + uint16 r, g, b, k; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = PACK(Map[r], Map[g], Map[b]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; + } +} + +#define DECLARESepPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img,\ + uint32* cp,\ + uint32 x, uint32 y, \ + uint32 w, uint32 h,\ + int32 fromskew, int32 toskew,\ + unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ +) + +/* + * 8-bit unpacked samples => RGB + */ +DECLARESepPutFunc(putRGBseparate8bittile) +{ + (void) img; (void) x; (void) y; (void) a; + while (h-- > 0) { + UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); + SKEW(r, g, b, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked samples => RGBA w/ associated alpha + */ +DECLARESepPutFunc(putRGBAAseparate8bittile) +{ + (void) img; (void) x; (void) y; + while (h-- > 0) { + UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked CMYK samples => RGBA + */ +DECLARESepPutFunc(putCMYKseparate8bittile) +{ + (void) img; (void) y; + while (h-- > 0) { + uint32 rv, gv, bv, kv; + for (x = w; x-- > 0;) { + kv = 255 - *a++; + rv = (kv*(255-*r++))/255; + gv = (kv*(255-*g++))/255; + bv = (kv*(255-*b++))/255; + *cp++ = PACK4(rv,gv,bv,255); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked samples => RGBA w/ unassociated alpha + */ +DECLARESepPutFunc(putRGBUAseparate8bittile) +{ + (void) img; (void) y; + while (h-- > 0) { + uint32 rv, gv, bv, av; + uint8* m; + for (x = w; x-- > 0;) { + av = *a++; + m = img->UaToAa+(av<<8); + rv = m[*r++]; + gv = m[*g++]; + bv = m[*b++]; + *cp++ = PACK4(rv,gv,bv,av); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGB + */ +DECLARESepPutFunc(putRGBseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + (void) img; (void) y; (void) a; + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = PACK(img->Bitdepth16To8[*wr++], + img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++]); + SKEW(wr, wg, wb, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGBA w/ associated alpha + */ +DECLARESepPutFunc(putRGBAAseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + uint16 *wa = (uint16*) a; + (void) img; (void) y; + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = PACK4(img->Bitdepth16To8[*wr++], + img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++], + img->Bitdepth16To8[*wa++]); + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGBA w/ unassociated alpha + */ +DECLARESepPutFunc(putRGBUAseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + uint16 *wa = (uint16*) a; + (void) img; (void) y; + while (h-- > 0) { + uint32 r,g,b,a; + uint8* m; + for (x = w; x-- > 0;) { + a = img->Bitdepth16To8[*wa++]; + m = img->UaToAa+(a<<8); + r = m[img->Bitdepth16To8[*wr++]]; + g = m[img->Bitdepth16To8[*wg++]]; + b = m[img->Bitdepth16To8[*wb++]]; + *cp++ = PACK4(r,g,b,a); + } + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } +} + +/* + * 8-bit packed CIE L*a*b 1976 samples => RGB + */ +DECLAREContigPutFunc(putcontig8bitCIELab) +{ + float X, Y, Z; + uint32 r, g, b; + (void) y; + fromskew *= 3; + while (h-- > 0) { + for (x = w; x-- > 0;) { + TIFFCIELabToXYZ(img->cielab, + (unsigned char)pp[0], + (signed char)pp[1], + (signed char)pp[2], + &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); + pp += 3; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * YCbCr -> RGB conversion and packing routines. + */ + +#define YCbCrtoRGB(dst, Y) { \ + uint32 r, g, b; \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + dst = PACK(r, g, b); \ +} + +/* + * 8-bit packed YCbCr samples => RGB + * This function is generic for different sampling sizes, + * and can handle blocks sizes that aren't multiples of the + * sampling size. However, it is substantially less optimized + * than the specific sampling cases. It is used as a fallback + * for difficult blocks. + */ +#ifdef notdef +static void putcontig8bitYCbCrGenericTile( + TIFFRGBAImage* img, + uint32* cp, + uint32 x, uint32 y, + uint32 w, uint32 h, + int32 fromskew, int32 toskew, + unsigned char* pp, + int h_group, + int v_group ) + +{ + uint32* cp1 = cp+w+toskew; + uint32* cp2 = cp1+w+toskew; + uint32* cp3 = cp2+w+toskew; + int32 incr = 3*w+4*toskew; + int32 Cb, Cr; + int group_size = v_group * h_group + 2; + + (void) y; + fromskew = (fromskew * group_size) / h_group; + + for( yy = 0; yy < h; yy++ ) + { + unsigned char *pp_line; + int y_line_group = yy / v_group; + int y_remainder = yy - y_line_group * v_group; + + pp_line = pp + v_line_group * + + + for( xx = 0; xx < w; xx++ ) + { + Cb = pp + } + } + for (; h >= 4; h -= 4) { + x = w>>2; + do { + Cb = pp[16]; + Cr = pp[17]; + + YCbCrtoRGB(cp [0], pp[ 0]); + YCbCrtoRGB(cp [1], pp[ 1]); + YCbCrtoRGB(cp [2], pp[ 2]); + YCbCrtoRGB(cp [3], pp[ 3]); + YCbCrtoRGB(cp1[0], pp[ 4]); + YCbCrtoRGB(cp1[1], pp[ 5]); + YCbCrtoRGB(cp1[2], pp[ 6]); + YCbCrtoRGB(cp1[3], pp[ 7]); + YCbCrtoRGB(cp2[0], pp[ 8]); + YCbCrtoRGB(cp2[1], pp[ 9]); + YCbCrtoRGB(cp2[2], pp[10]); + YCbCrtoRGB(cp2[3], pp[11]); + YCbCrtoRGB(cp3[0], pp[12]); + YCbCrtoRGB(cp3[1], pp[13]); + YCbCrtoRGB(cp3[2], pp[14]); + YCbCrtoRGB(cp3[3], pp[15]); + + cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; + pp += 18; + } while (--x); + cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; + pp += fromskew; + } +} +#endif + +/* + * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr44tile) +{ + uint32* cp1 = cp+w+toskew; + uint32* cp2 = cp1+w+toskew; + uint32* cp3 = cp2+w+toskew; + int32 incr = 3*w+4*toskew; + + (void) y; + /* adjust fromskew */ + fromskew = (fromskew * 18) / 4; + if ((h & 3) == 0 && (w & 3) == 0) { + for (; h >= 4; h -= 4) { + x = w>>2; + do { + int32 Cb = pp[16]; + int32 Cr = pp[17]; + + YCbCrtoRGB(cp [0], pp[ 0]); + YCbCrtoRGB(cp [1], pp[ 1]); + YCbCrtoRGB(cp [2], pp[ 2]); + YCbCrtoRGB(cp [3], pp[ 3]); + YCbCrtoRGB(cp1[0], pp[ 4]); + YCbCrtoRGB(cp1[1], pp[ 5]); + YCbCrtoRGB(cp1[2], pp[ 6]); + YCbCrtoRGB(cp1[3], pp[ 7]); + YCbCrtoRGB(cp2[0], pp[ 8]); + YCbCrtoRGB(cp2[1], pp[ 9]); + YCbCrtoRGB(cp2[2], pp[10]); + YCbCrtoRGB(cp2[3], pp[11]); + YCbCrtoRGB(cp3[0], pp[12]); + YCbCrtoRGB(cp3[1], pp[13]); + YCbCrtoRGB(cp3[2], pp[14]); + YCbCrtoRGB(cp3[3], pp[15]); + + cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; + pp += 18; + } while (--x); + cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; + pp += fromskew; + } + } else { + while (h > 0) { + for (x = w; x > 0;) { + int32 Cb = pp[16]; + int32 Cr = pp[17]; + switch (x) { + default: + switch (h) { + default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ + case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ + case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) { + default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ + case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ + case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) { + default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ + case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ + case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) { + default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ + case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ + case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + } + if (x < 4) { + cp += x; cp1 += x; cp2 += x; cp3 += x; + x = 0; + } + else { + cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; + x -= 4; + } + pp += 18; + } + if (h <= 4) + break; + h -= 4; + cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; + pp += fromskew; + } + } +} + +/* + * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr42tile) +{ + uint32* cp1 = cp+w+toskew; + int32 incr = 2*toskew+w; + + (void) y; + fromskew = (fromskew * 10) / 4; + if ((h & 3) == 0 && (w & 1) == 0) { + for (; h >= 2; h -= 2) { + x = w>>2; + do { + int32 Cb = pp[8]; + int32 Cr = pp[9]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp [2], pp[2]); + YCbCrtoRGB(cp [3], pp[3]); + YCbCrtoRGB(cp1[0], pp[4]); + YCbCrtoRGB(cp1[1], pp[5]); + YCbCrtoRGB(cp1[2], pp[6]); + YCbCrtoRGB(cp1[3], pp[7]); + + cp += 4, cp1 += 4; + pp += 10; + } while (--x); + cp += incr, cp1 += incr; + pp += fromskew; + } + } else { + while (h > 0) { + for (x = w; x > 0;) { + int32 Cb = pp[8]; + int32 Cr = pp[9]; + switch (x) { + default: + switch (h) { + default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) { + default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) { + default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) { + default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ + case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + } + if (x < 4) { + cp += x; cp1 += x; + x = 0; + } + else { + cp += 4; cp1 += 4; + x -= 4; + } + pp += 10; + } + if (h <= 2) + break; + h -= 2; + cp += incr, cp1 += incr; + pp += fromskew; + } + } +} + +/* + * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr41tile) +{ + (void) y; + /* XXX adjust fromskew */ + do { + x = w>>2; + do { + int32 Cb = pp[4]; + int32 Cr = pp[5]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp [2], pp[2]); + YCbCrtoRGB(cp [3], pp[3]); + + cp += 4; + pp += 6; + } while (--x); + + if( (w&3) != 0 ) + { + int32 Cb = pp[4]; + int32 Cr = pp[5]; + + switch( (w&3) ) { + case 3: YCbCrtoRGB(cp [2], pp[2]); + case 2: YCbCrtoRGB(cp [1], pp[1]); + case 1: YCbCrtoRGB(cp [0], pp[0]); + case 0: break; + } + + cp += (w&3); + pp += 6; + } + + cp += toskew; + pp += fromskew; + } while (--h); + +} + +/* + * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr22tile) +{ + uint32* cp2; + int32 incr = 2*toskew+w; + (void) y; + fromskew = (fromskew / 2) * 6; + cp2 = cp+w+toskew; + while (h>=2) { + x = w; + while (x>=2) { + uint32 Cb = pp[4]; + uint32 Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp2[0], pp[2]); + YCbCrtoRGB(cp2[1], pp[3]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x==1) { + uint32 Cb = pp[4]; + uint32 Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[2]); + cp ++ ; + cp2 ++ ; + pp += 6; + } + cp += incr; + cp2 += incr; + pp += fromskew; + h-=2; + } + if (h==1) { + x = w; + while (x>=2) { + uint32 Cb = pp[4]; + uint32 Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x==1) { + uint32 Cb = pp[4]; + uint32 Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + } + } +} + +/* + * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr21tile) +{ + (void) y; + fromskew = (fromskew * 4) / 2; + do { + x = w>>1; + do { + int32 Cb = pp[2]; + int32 Cr = pp[3]; + + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + + cp += 2; + pp += 4; + } while (--x); + + if( (w&1) != 0 ) + { + int32 Cb = pp[2]; + int32 Cr = pp[3]; + + YCbCrtoRGB(cp[0], pp[0]); + + cp += 1; + pp += 4; + } + + cp += toskew; + pp += fromskew; + } while (--h); +} + +/* + * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr12tile) +{ + uint32* cp2; + int32 incr = 2*toskew+w; + (void) y; + fromskew = (fromskew / 2) * 4; + cp2 = cp+w+toskew; + while (h>=2) { + x = w; + do { + uint32 Cb = pp[2]; + uint32 Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[1]); + cp ++; + cp2 ++; + pp += 4; + } while (--x); + cp += incr; + cp2 += incr; + pp += fromskew; + h-=2; + } + if (h==1) { + x = w; + do { + uint32 Cb = pp[2]; + uint32 Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + cp ++; + pp += 4; + } while (--x); + } +} + +/* + * 8-bit packed YCbCr samples w/ no subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr11tile) +{ + (void) y; + fromskew *= 3; + do { + x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ + do { + int32 Cb = pp[1]; + int32 Cr = pp[2]; + + YCbCrtoRGB(*cp++, pp[0]); + + pp += 3; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); +} + +/* + * 8-bit packed YCbCr samples w/ no subsampling => RGB + */ +DECLARESepPutFunc(putseparate8bitYCbCr11tile) +{ + (void) y; + (void) a; + /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ + while (h-- > 0) { + x = w; + do { + uint32 dr, dg, db; + TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); + *cp++ = PACK(dr,dg,db); + } while (--x); + SKEW(r, g, b, fromskew); + cp += toskew; + } +} +#undef YCbCrtoRGB + +static int +initYCbCrConversion(TIFFRGBAImage* img) +{ + static const char module[] = "initYCbCrConversion"; + + float *luma, *refBlackWhite; + + if (img->ycbcr == NULL) { + img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( + TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) + + 4*256*sizeof (TIFFRGBValue) + + 2*256*sizeof (int) + + 3*256*sizeof (int32) + ); + if (img->ycbcr == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, module, + "No space for YCbCr->RGB conversion state"); + return (0); + } + } + + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); + TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, + &refBlackWhite); + if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) + return(0); + return (1); +} + +static tileContigRoutine +initCIELabConversion(TIFFRGBAImage* img) +{ + static const char module[] = "initCIELabConversion"; + + float *whitePoint; + float refWhite[3]; + + if (!img->cielab) { + img->cielab = (TIFFCIELabToRGB *) + _TIFFmalloc(sizeof(TIFFCIELabToRGB)); + if (!img->cielab) { + TIFFErrorExt(img->tif->tif_clientdata, module, + "No space for CIE L*a*b*->RGB conversion state."); + return NULL; + } + } + + TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); + refWhite[1] = 100.0F; + refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; + refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) + / whitePoint[1] * refWhite[1]; + if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { + TIFFErrorExt(img->tif->tif_clientdata, module, + "Failed to initialize CIE L*a*b*->RGB conversion state."); + _TIFFfree(img->cielab); + return NULL; + } + + return putcontig8bitCIELab; +} + +/* + * Greyscale images with less than 8 bits/sample are handled + * with a table to avoid lots of shifts and masks. The table + * is setup so that put*bwtile (below) can retrieve 8/bitspersample + * pixel values simply by indexing into the table with one + * number. + */ +static int +makebwmap(TIFFRGBAImage* img) +{ + TIFFRGBValue* Map = img->Map; + int bitspersample = img->bitspersample; + int nsamples = 8 / bitspersample; + int i; + uint32* p; + + if( nsamples == 0 ) + nsamples = 1; + + img->BWmap = (uint32**) _TIFFmalloc( + 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); + if (img->BWmap == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); + return (0); + } + p = (uint32*)(img->BWmap + 256); + for (i = 0; i < 256; i++) { + TIFFRGBValue c; + img->BWmap[i] = p; + switch (bitspersample) { +#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); + case 1: + GREY(i>>7); + GREY((i>>6)&1); + GREY((i>>5)&1); + GREY((i>>4)&1); + GREY((i>>3)&1); + GREY((i>>2)&1); + GREY((i>>1)&1); + GREY(i&1); + break; + case 2: + GREY(i>>6); + GREY((i>>4)&3); + GREY((i>>2)&3); + GREY(i&3); + break; + case 4: + GREY(i>>4); + GREY(i&0xf); + break; + case 8: + case 16: + GREY(i); + break; + } +#undef GREY + } + return (1); +} + +/* + * Construct a mapping table to convert from the range + * of the data samples to [0,255] --for display. This + * process also handles inverting B&W images when needed. + */ +static int +setupMap(TIFFRGBAImage* img) +{ + int32 x, range; + + range = (int32)((1L<bitspersample)-1); + + /* treat 16 bit the same as eight bit */ + if( img->bitspersample == 16 ) + range = (int32) 255; + + img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); + if (img->Map == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), + "No space for photometric conversion table"); + return (0); + } + if (img->photometric == PHOTOMETRIC_MINISWHITE) { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); + } else { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue) ((x * 255) / range); + } + if (img->bitspersample <= 16 && + (img->photometric == PHOTOMETRIC_MINISBLACK || + img->photometric == PHOTOMETRIC_MINISWHITE)) { + /* + * Use photometric mapping table to construct + * unpacking tables for samples <= 8 bits. + */ + if (!makebwmap(img)) + return (0); + /* no longer need Map, free it */ + _TIFFfree(img->Map), img->Map = NULL; + } + return (1); +} + +static int +checkcmap(TIFFRGBAImage* img) +{ + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + long n = 1L<bitspersample; + + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + return (8); +} + +static void +cvtcmap(TIFFRGBAImage* img) +{ + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + long i; + + for (i = (1L<bitspersample)-1; i >= 0; i--) { +#define CVT(x) ((uint16)((x)>>8)) + r[i] = CVT(r[i]); + g[i] = CVT(g[i]); + b[i] = CVT(b[i]); +#undef CVT + } +} + +/* + * Palette images with <= 8 bits/sample are handled + * with a table to avoid lots of shifts and masks. The table + * is setup so that put*cmaptile (below) can retrieve 8/bitspersample + * pixel values simply by indexing into the table with one + * number. + */ +static int +makecmap(TIFFRGBAImage* img) +{ + int bitspersample = img->bitspersample; + int nsamples = 8 / bitspersample; + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + uint32 *p; + int i; + + img->PALmap = (uint32**) _TIFFmalloc( + 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); + if (img->PALmap == NULL) { + TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); + return (0); + } + p = (uint32*)(img->PALmap + 256); + for (i = 0; i < 256; i++) { + TIFFRGBValue c; + img->PALmap[i] = p; +#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); + switch (bitspersample) { + case 1: + CMAP(i>>7); + CMAP((i>>6)&1); + CMAP((i>>5)&1); + CMAP((i>>4)&1); + CMAP((i>>3)&1); + CMAP((i>>2)&1); + CMAP((i>>1)&1); + CMAP(i&1); + break; + case 2: + CMAP(i>>6); + CMAP((i>>4)&3); + CMAP((i>>2)&3); + CMAP(i&3); + break; + case 4: + CMAP(i>>4); + CMAP(i&0xf); + break; + case 8: + CMAP(i); + break; + } +#undef CMAP + } + return (1); +} + +/* + * Construct any mapping table used + * by the associated put routine. + */ +static int +buildMap(TIFFRGBAImage* img) +{ + switch (img->photometric) { + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8) + break; + /* fall thru... */ + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + if (!setupMap(img)) + return (0); + break; + case PHOTOMETRIC_PALETTE: + /* + * Convert 16-bit colormap to 8-bit (unless it looks + * like an old-style 8-bit colormap). + */ + if (checkcmap(img) == 16) + cvtcmap(img); + else + TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); + /* + * Use mapping table and colormap to construct + * unpacking tables for samples < 8 bits. + */ + if (img->bitspersample <= 8 && !makecmap(img)) + return (0); + break; + } + return (1); +} + +/* + * Select the appropriate conversion routine for packed data. + */ +static int +PickContigCase(TIFFRGBAImage* img) +{ + img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; + img->put.contig = NULL; + switch (img->photometric) { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + img->put.contig = putRGBAAcontig8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig8bittile; + } + else + img->put.contig = putRGBcontig8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBAAcontig16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapBitdepth16To8(img) && + BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig16bittile; + } + else + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBcontig16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (buildMap(img)) { + if (img->bitspersample == 8) { + if (!img->Map) + img->put.contig = putRGBcontig8bitCMYKtile; + else + img->put.contig = putRGBcontig8bitCMYKMaptile; + } + } + break; + case PHOTOMETRIC_PALETTE: + if (buildMap(img)) { + switch (img->bitspersample) { + case 8: + img->put.contig = put8bitcmaptile; + break; + case 4: + img->put.contig = put4bitcmaptile; + break; + case 2: + img->put.contig = put2bitcmaptile; + break; + case 1: + img->put.contig = put1bitcmaptile; + break; + } + } + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (buildMap(img)) { + switch (img->bitspersample) { + case 16: + img->put.contig = put16bitbwtile; + break; + case 8: + if (img->alpha && img->samplesperpixel == 2) + img->put.contig = putagreytile; + else + img->put.contig = putgreytile; + break; + case 4: + img->put.contig = put4bitbwtile; + break; + case 2: + img->put.contig = put2bitbwtile; + break; + case 1: + img->put.contig = put1bitbwtile; + break; + } + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample==8) && (img->samplesperpixel==3)) + { + if (initYCbCrConversion(img)!=0) + { + /* + * The 6.0 spec says that subsampling must be + * one of 1, 2, or 4, and that vertical subsampling + * must always be <= horizontal subsampling; so + * there are only a few possibilities and we just + * enumerate the cases. + * Joris: added support for the [1,2] case, nonetheless, to accomodate + * some OJPEG files + */ + uint16 SubsamplingHor; + uint16 SubsamplingVer; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); + switch ((SubsamplingHor<<4)|SubsamplingVer) { + case 0x44: + img->put.contig = putcontig8bitYCbCr44tile; + break; + case 0x42: + img->put.contig = putcontig8bitYCbCr42tile; + break; + case 0x41: + img->put.contig = putcontig8bitYCbCr41tile; + break; + case 0x22: + img->put.contig = putcontig8bitYCbCr22tile; + break; + case 0x21: + img->put.contig = putcontig8bitYCbCr21tile; + break; + case 0x12: + img->put.contig = putcontig8bitYCbCr12tile; + break; + case 0x11: + img->put.contig = putcontig8bitYCbCr11tile; + break; + } + } + } + break; + case PHOTOMETRIC_CIELAB: + if (buildMap(img)) { + if (img->bitspersample == 8) + img->put.contig = initCIELabConversion(img); + break; + } + } + return ((img->get!=NULL) && (img->put.contig!=NULL)); +} + +/* + * Select the appropriate conversion routine for unpacked data. + * + * NB: we assume that unpacked single channel data is directed + * to the "packed routines. + */ +static int +PickSeparateCase(TIFFRGBAImage* img) +{ + img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; + img->put.separate = NULL; + switch (img->photometric) { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + /* greyscale images processed pretty much as RGB by gtTileSeparate */ + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + img->put.separate = putRGBAAseparate8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate8bittile; + } + else + img->put.separate = putRGBseparate8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBAAseparate16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapBitdepth16To8(img) && + BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate16bittile; + } + else + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBseparate16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8 && img->samplesperpixel == 4) + { + img->alpha = 1; // Not alpha, but seems like the only way to get 4th band + img->put.separate = putCMYKseparate8bittile; + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample==8) && (img->samplesperpixel==3)) + { + if (initYCbCrConversion(img)!=0) + { + uint16 hs, vs; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); + switch ((hs<<4)|vs) { + case 0x11: + img->put.separate = putseparate8bitYCbCr11tile; + break; + /* TODO: add other cases here */ + } + } + } + break; + } + return ((img->get!=NULL) && (img->put.separate!=NULL)); +} + +static int +BuildMapUaToAa(TIFFRGBAImage* img) +{ + static const char module[]="BuildMapUaToAa"; + uint8* m; + uint16 na,nv; + assert(img->UaToAa==NULL); + img->UaToAa=_TIFFmalloc(65536); + if (img->UaToAa==NULL) + { + TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); + return(0); + } + m=img->UaToAa; + for (na=0; na<256; na++) + { + for (nv=0; nv<256; nv++) + *m++=(nv*na+127)/255; + } + return(1); +} + +static int +BuildMapBitdepth16To8(TIFFRGBAImage* img) +{ + static const char module[]="BuildMapBitdepth16To8"; + uint8* m; + uint32 n; + assert(img->Bitdepth16To8==NULL); + img->Bitdepth16To8=_TIFFmalloc(65536); + if (img->Bitdepth16To8==NULL) + { + TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); + return(0); + } + m=img->Bitdepth16To8; + for (n=0; n<65536; n++) + *m++=(n+128)/257; + return(1); +} + + +/* + * Read a whole strip off data from the file, and convert to RGBA form. + * If this is the last strip, then it will only contain the portion of + * the strip that is actually within the image space. The result is + * organized in bottom to top form. + */ + + +int +TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) + +{ + char emsg[1024] = ""; + TIFFRGBAImage img; + int ok; + uint32 rowsperstrip, rows_to_read; + + if( TIFFIsTiled( tif ) ) + { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), + "Can't use TIFFReadRGBAStrip() with tiled file."); + return (0); + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + if( (row % rowsperstrip) != 0 ) + { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), + "Row passed to TIFFReadRGBAStrip() must be first in a strip."); + return (0); + } + + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) { + + img.row_offset = row; + img.col_offset = 0; + + if( row + rowsperstrip > img.height ) + rows_to_read = img.height - row; + else + rows_to_read = rowsperstrip; + + ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); + + TIFFRGBAImageEnd(&img); + } else { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); + ok = 0; + } + + return (ok); +} + +/* + * Read a whole tile off data from the file, and convert to RGBA form. + * The returned RGBA data is organized from bottom to top of tile, + * and may include zeroed areas if the tile extends off the image. + */ + +int +TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) + +{ + char emsg[1024] = ""; + TIFFRGBAImage img; + int ok; + uint32 tile_xsize, tile_ysize; + uint32 read_xsize, read_ysize; + uint32 i_row; + + /* + * Verify that our request is legal - on a tile file, and on a + * tile boundary. + */ + + if( !TIFFIsTiled( tif ) ) + { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), + "Can't use TIFFReadRGBATile() with stripped file."); + return (0); + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); + TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); + if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) + { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), + "Row/col passed to TIFFReadRGBATile() must be top" + "left corner of a tile."); + return (0); + } + + /* + * Setup the RGBA reader. + */ + + if (!TIFFRGBAImageOK(tif, emsg) + || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); + return( 0 ); + } + + /* + * The TIFFRGBAImageGet() function doesn't allow us to get off the + * edge of the image, even to fill an otherwise valid tile. So we + * figure out how much we can read, and fix up the tile buffer to + * a full tile configuration afterwards. + */ + + if( row + tile_ysize > img.height ) + read_ysize = img.height - row; + else + read_ysize = tile_ysize; + + if( col + tile_xsize > img.width ) + read_xsize = img.width - col; + else + read_xsize = tile_xsize; + + /* + * Read the chunk of imagery. + */ + + img.row_offset = row; + img.col_offset = col; + + ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); + + TIFFRGBAImageEnd(&img); + + /* + * If our read was incomplete we will need to fix up the tile by + * shifting the data around as if a full tile of data is being returned. + * + * This is all the more complicated because the image is organized in + * bottom to top format. + */ + + if( read_xsize == tile_xsize && read_ysize == tile_ysize ) + return( ok ); + + for( i_row = 0; i_row < read_ysize; i_row++ ) { + memmove( raster + (tile_ysize - i_row - 1) * tile_xsize, + raster + (read_ysize - i_row - 1) * read_xsize, + read_xsize * sizeof(uint32) ); + _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize, + 0, sizeof(uint32) * (tile_xsize - read_xsize) ); + } + + for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { + _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize, + 0, sizeof(uint32) * tile_xsize ); + } + + return (ok); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jbig.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jbig.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jbig.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jbig.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,213 @@ +/* $Id: tif_jbig.c,v 1.15 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * JBIG Compression Algorithm Support. + * Contributed by Lee Howard + * + */ + +#include "tiffiop.h" + +#ifdef JBIG_SUPPORT +#include "jbig.h" + +static int JBIGSetupDecode(TIFF* tif) +{ + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in decoder"); + return 0; + } + + return 1; +} + +static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) +{ + struct jbg_dec_state decoder; + int decodeStatus = 0; + unsigned char* pImage = NULL; + (void) size, (void) s; + + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); + } + + jbg_dec_init(&decoder); + +#if defined(HAVE_JBG_NEWLEN) + jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize); + /* + * I do not check the return status of jbg_newlen because even if this + * function fails it does not necessarily mean that decoding the image + * will fail. It is generally only needed for received fax images + * that do not contain the actual length of the image in the BIE + * header. I do not log when an error occurs because that will cause + * problems when converting JBIG encoded TIFF's to + * PostScript. As long as the actual image length is contained in the + * BIE header jbg_dec_in should succeed. + */ +#endif /* HAVE_JBG_NEWLEN */ + + decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata, + (size_t)tif->tif_rawdatasize, NULL); + if (JBG_EOK != decodeStatus) + { + /* + * XXX: JBG_EN constant was defined in pre-2.0 releases of the + * JBIG-KIT. Since the 2.0 the error reporting functions were + * changed. We will handle both cases here. + */ + TIFFErrorExt(tif->tif_clientdata, + "JBIG", "Error (%d) decoding: %s", + decodeStatus, +#if defined(JBG_EN) + jbg_strerror(decodeStatus, JBG_EN) +#else + jbg_strerror(decodeStatus) +#endif + ); + return 0; + } + + pImage = jbg_dec_getimage(&decoder, 0); + _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); + jbg_dec_free(&decoder); + return 1; +} + +static int JBIGSetupEncode(TIFF* tif) +{ + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in encoder"); + return 0; + } + + return 1; +} + +static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16 s) +{ + (void) s; + while (cc > 0) + { + tmsize_t n = (tmsize_t)cc; + + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + { + n = tif->tif_rawdatasize - tif->tif_rawcc; + } + + assert(n > 0); + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= (size_t)n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && + !TIFFFlushData1(tif)) + { + return (-1); + } + } + + return (1); +} + +static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData) +{ + TIFF* tif = (TIFF*)userData; + + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(buffer, (tmsize_t)len); + } + + JBIGCopyEncodedData(tif, buffer, len, 0); +} + +static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) +{ + TIFFDirectory* dir = &tif->tif_dir; + struct jbg_enc_state encoder; + + (void) size, (void) s; + + jbg_enc_init(&encoder, + dir->td_imagewidth, + dir->td_imagelength, + 1, + &buffer, + JBIGOutputBie, + tif); + /* + * jbg_enc_out does the "real" encoding. As data is encoded, + * JBIGOutputBie is called, which writes the data to the directory. + */ + jbg_enc_out(&encoder); + jbg_enc_free(&encoder); + + return 1; +} + +int TIFFInitJBIG(TIFF* tif, int scheme) +{ + assert(scheme == COMPRESSION_JBIG); + + /* + * These flags are set so the JBIG Codec can control when to reverse + * bits and when not to and to allow the jbig decoder and bit reverser + * to write to memory when necessary. + */ + tif->tif_flags |= TIFF_NOBITREV; + tif->tif_flags &= ~TIFF_MAPPED; + + /* Setup the function pointers for encode, decode, and cleanup. */ + tif->tif_setupdecode = JBIGSetupDecode; + tif->tif_decodestrip = JBIGDecode; + + tif->tif_setupencode = JBIGSetupEncode; + tif->tif_encodestrip = JBIGEncode; + + return 1; +} + +#endif /* JBIG_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2301 @@ +/* $Id: tif_jpeg.c,v 1.108 2012-06-05 03:24:30 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1994-1997 Sam Leffler + * Copyright (c) 1994-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN + +#include "tiffiop.h" +#ifdef JPEG_SUPPORT + +/* + * TIFF Library + * + * JPEG Compression support per TIFF Technical Note #2 + * (*not* per the original TIFF 6.0 spec). + * + * This file is simply an interface to the libjpeg library written by + * the Independent JPEG Group. You need release 5 or later of the IJG + * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. + * + * Contributed by Tom Lane . + */ +#include + +int TIFFFillStrip(TIFF* tif, uint32 strip); +int TIFFFillTile(TIFF* tif, uint32 tile); +int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); + +/* We undefine FAR to avoid conflict with JPEG definition */ + +#ifdef FAR +#undef FAR +#endif + +/* + Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is + not defined. Unfortunately, the MinGW and Borland compilers include + a typedef for INT32, which causes a conflict. MSVC does not include + a conficting typedef given the headers which are included. +*/ +#if defined(__BORLANDC__) || defined(__MINGW32__) +# define XMD_H 1 +#endif + +/* + The windows RPCNDR.H file defines boolean, but defines it with the + unsigned char size. You should compile JPEG library using appropriate + definitions in jconfig.h header, but many users compile library in wrong + way. That causes errors of the following type: + + "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432, + caller expects 464" + + For such users we wil fix the problem here. See install.doc file from + the JPEG library distribution for details. +*/ + +/* Define "boolean" as unsigned char, not int, per Windows custom. */ +#if defined(__WIN32__) && !defined(__MINGW32__) +# 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 */ +#endif + +#include "jpeglib.h" +#include "jerror.h" + +/* + * Do we want to do special processing suitable for when JSAMPLE is a + * 16bit value? + */ + +#if defined(JPEG_LIB_MK1) +# define JPEG_LIB_MK1_OR_12BIT 1 +#elif BITS_IN_JSAMPLE == 12 +# define JPEG_LIB_MK1_OR_12BIT 1 +#endif + +/* + * We are using width_in_blocks which is supposed to be private to + * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has + * renamed this member to width_in_data_units. Since the header has + * also renamed a define, use that unique define name in order to + * detect the problem header and adjust to suit. + */ +#if defined(D_MAX_DATA_UNITS_IN_MCU) +#define width_in_blocks width_in_data_units +#endif + +/* + * On some machines it may be worthwhile to use _setjmp or sigsetjmp + * in place of plain setjmp. These macros will make it easier. + */ +#define SETJMP(jbuf) setjmp(jbuf) +#define LONGJMP(jbuf,code) longjmp(jbuf,code) +#define JMP_BUF jmp_buf + +typedef struct jpeg_destination_mgr jpeg_destination_mgr; +typedef struct jpeg_source_mgr jpeg_source_mgr; +typedef struct jpeg_error_mgr jpeg_error_mgr; + +/* + * State block for each open TIFF file using + * libjpeg to do JPEG compression/decompression. + * + * libjpeg's visible state is either a jpeg_compress_struct + * or jpeg_decompress_struct depending on which way we + * are going. comm can be used to refer to the fields + * which are common to both. + * + * NB: cinfo is required to be the first member of JPEGState, + * so we can safely cast JPEGState* -> jpeg_xxx_struct* + * and vice versa! + */ +typedef struct { + union { + struct jpeg_compress_struct c; + struct jpeg_decompress_struct d; + struct jpeg_common_struct comm; + } cinfo; /* NB: must be first */ + int cinfo_initialized; + + jpeg_error_mgr err; /* libjpeg error manager */ + JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + /* + * The following two members could be a union, but + * they're small enough that it's not worth the effort. + */ + jpeg_destination_mgr dest; /* data dest for compression */ + jpeg_source_mgr src; /* data source for decompression */ + /* private state */ + TIFF* tif; /* back link needed by some code */ + uint16 photometric; /* copy of PhotometricInterpretation */ + uint16 h_sampling; /* luminance sampling factors */ + uint16 v_sampling; + tmsize_t bytesperline; /* decompressed bytes per scanline */ + /* pointers to intermediate buffers when processing downsampled data */ + JSAMPARRAY ds_buffer[MAX_COMPONENTS]; + int scancount; /* number of "scanlines" accumulated */ + int samplesperclump; + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFStripMethod defsparent; /* super-class method */ + TIFFTileMethod deftparent; /* super-class method */ + /* pseudo-tag fields */ + void* jpegtables; /* JPEGTables tag value, or NULL */ + uint32 jpegtables_length; /* number of bytes in same */ + int jpegquality; /* Compression quality level */ + int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ + int jpegtablesmode; /* What to put in JPEGTables */ + + int ycbcrsampling_fetched; +} JPEGState; + +#define JState(tif) ((JPEGState*)(tif)->tif_data) + +static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGInitializeLibJPEG(TIFF * tif, int decode ); +static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); + +#define FIELD_JPEGTABLES (FIELD_CODEC+0) + +static const TIFFField jpegFields[] = { + { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL }, + { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, + { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }, + { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL } +}; + +/* + * libjpeg interface layer. + * + * We use setjmp/longjmp to return control to libtiff + * when a fatal error is encountered within the JPEG + * library. We also direct libjpeg error and warning + * messages through the appropriate libtiff handlers. + */ + +/* + * Error handling routines (these replace corresponding + * IJG routines from jerror.c). These are used for both + * compression and decompression. + */ +static void +TIFFjpeg_error_exit(j_common_ptr cinfo) +{ + JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer); /* display the error message */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ +} + +/* + * This routine is invoked only for warning messages, + * since error_exit does its own thing and trace_level + * is never set > 0. + */ +static void +TIFFjpeg_output_message(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer); +} + +/* + * Interface routines. This layer of routines exists + * primarily to limit side-effects from using setjmp. + * Also, normal/error returns are converted into return + * values per libtiff practice. + */ +#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) +#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1)) + +static int +TIFFjpeg_create_compress(JPEGState* sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.c.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; + + return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); +} + +static int +TIFFjpeg_create_decompress(JPEGState* sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.d.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; + + return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_set_defaults(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); +} + +static int +TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace) +{ + return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); +} + +static int +TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline) +{ + return CALLVJPEG(sp, + jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); +} + +static int +TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress) +{ + return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); +} + +static int +TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables) +{ + return CALLVJPEG(sp, + jpeg_start_compress(&sp->cinfo.c, write_all_tables)); +} + +static int +TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c, + scanlines, (JDIMENSION) num_lines)); +} + +static int +TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c, + data, (JDIMENSION) num_lines)); +} + +static int +TIFFjpeg_finish_compress(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); +} + +static int +TIFFjpeg_write_tables(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); +} + +static int +TIFFjpeg_read_header(JPEGState* sp, boolean require_image) +{ + return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); +} + +static int +TIFFjpeg_start_decompress(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d, + scanlines, (JDIMENSION) max_lines)); +} + +static int +TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d, + data, (JDIMENSION) max_lines)); +} + +static int +TIFFjpeg_finish_decompress(JPEGState* sp) +{ + return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_abort(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); +} + +static int +TIFFjpeg_destroy(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); +} + +static JSAMPARRAY +TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +{ + return CALLJPEG(sp, (JSAMPARRAY) NULL, + (*sp->cinfo.comm.mem->alloc_sarray) + (&sp->cinfo.comm, pool_id, samplesperrow, numrows)); +} + +/* + * JPEG library destination data manager. + * These routines direct compressed data from libjpeg into the + * libtiff output buffer. + */ + +static void +std_init_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; +} + +static boolean +std_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + /* the entire buffer has been filled */ + tif->tif_rawcc = tif->tif_rawdatasize; + +#ifdef IPPJ_HUFF + /* + * The Intel IPP performance library does not necessarily fill up + * the whole output buffer on each pass, so only dump out the parts + * that have been filled. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if ( sp->dest.free_in_buffer >= 0 ) { + tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; + } +#endif + + TIFFFlushData1(tif); + sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + + return (TRUE); +} + +static void +std_term_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + tif->tif_rawcp = (uint8*) sp->dest.next_output_byte; + tif->tif_rawcc = + tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer; + /* NB: libtiff does the final buffer flush */ +} + +static void +TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif) +{ + (void) tif; + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = std_init_destination; + sp->dest.empty_output_buffer = std_empty_output_buffer; + sp->dest.term_destination = std_term_destination; +} + +/* + * Alternate destination manager for outputting to JPEGTables field. + */ + +static void +tables_init_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + /* while building, jpegtables_length is allocated buffer size */ + sp->dest.next_output_byte = (JOCTET*) sp->jpegtables; + sp->dest.free_in_buffer = (size_t) sp->jpegtables_length; +} + +static boolean +tables_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + void* newbuf; + + /* the entire buffer has been filled; enlarge it by 1000 bytes */ + newbuf = _TIFFrealloc((void*) sp->jpegtables, + (tmsize_t) (sp->jpegtables_length + 1000)); + if (newbuf == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); + sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; + sp->dest.free_in_buffer = (size_t) 1000; + sp->jpegtables = newbuf; + sp->jpegtables_length += 1000; + return (TRUE); +} + +static void +tables_term_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + /* set tables length to number of bytes actually emitted */ + sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer; +} + +static int +TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) +{ + (void) tif; + /* + * Allocate a working buffer for building tables. + * Initial size is 1000 bytes, which is usually adequate. + */ + if (sp->jpegtables) + _TIFFfree(sp->jpegtables); + sp->jpegtables_length = 1000; + sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length); + if (sp->jpegtables == NULL) { + sp->jpegtables_length = 0; + TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables"); + return (0); + } + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = tables_init_destination; + sp->dest.empty_output_buffer = tables_empty_output_buffer; + sp->dest.term_destination = tables_term_destination; + return (1); +} + +/* + * JPEG library source data manager. + * These routines supply compressed data to libjpeg. + */ + +static void +std_init_source(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata; + sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; +} + +static boolean +std_fill_input_buffer(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState* ) cinfo; + static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; + +#ifdef IPPJ_HUFF + /* + * The Intel IPP performance library does not necessarily read the whole + * input buffer in one pass, so it is possible to get here with data + * yet to read. + * + * We just return without doing anything, until the entire buffer has + * been read. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if( sp->src.bytes_in_buffer > 0 ) { + return (TRUE); + } +#endif + + /* + * Normally the whole strip/tile is read and so we don't need to do + * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have + * all the data, but the rawdata is refreshed between scanlines and + * we push this into the io machinery in JPEGDecode(). + * http://trac.osgeo.org/gdal/ticket/3894 + */ + + WARNMS(cinfo, JWRN_JPEG_EOF); + /* insert a fake EOI marker */ + sp->src.next_input_byte = dummy_EOI; + sp->src.bytes_in_buffer = 2; + return (TRUE); +} + +static void +std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + JPEGState* sp = (JPEGState*) cinfo; + + if (num_bytes > 0) { + if ((size_t)num_bytes > sp->src.bytes_in_buffer) { + /* oops, buffer overrun */ + (void) std_fill_input_buffer(cinfo); + } else { + sp->src.next_input_byte += (size_t) num_bytes; + sp->src.bytes_in_buffer -= (size_t) num_bytes; + } + } +} + +static void +std_term_source(j_decompress_ptr cinfo) +{ + /* No work necessary here */ + (void) cinfo; +} + +static void +TIFFjpeg_data_src(JPEGState* sp, TIFF* tif) +{ + (void) tif; + sp->cinfo.d.src = &sp->src; + sp->src.init_source = std_init_source; + sp->src.fill_input_buffer = std_fill_input_buffer; + sp->src.skip_input_data = std_skip_input_data; + sp->src.resync_to_restart = jpeg_resync_to_restart; + sp->src.term_source = std_term_source; + sp->src.bytes_in_buffer = 0; /* for safety */ + sp->src.next_input_byte = NULL; +} + +/* + * Alternate source manager for reading from JPEGTables. + * We can share all the code except for the init routine. + */ + +static void +tables_init_source(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + sp->src.next_input_byte = (const JOCTET*) sp->jpegtables; + sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length; +} + +static void +TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif) +{ + TIFFjpeg_data_src(sp, tif); + sp->src.init_source = tables_init_source; +} + +/* + * Allocate downsampled-data buffers needed for downsampled I/O. + * We use values computed in jpeg_start_compress or jpeg_start_decompress. + * We use libjpeg's allocator so that buffers will be released automatically + * when done with strip/tile. + * This is also a handy place to compute samplesperclump, bytesperline. + */ +static int +alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, + int num_components) +{ + JPEGState* sp = JState(tif); + int ci; + jpeg_component_info* compptr; + JSAMPARRAY buf; + int samples_per_clump = 0; + + for (ci = 0, compptr = comp_info; ci < num_components; + ci++, compptr++) { + samples_per_clump += compptr->h_samp_factor * + compptr->v_samp_factor; + buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor*DCTSIZE)); + if (buf == NULL) + return (0); + sp->ds_buffer[ci] = buf; + } + sp->samplesperclump = samples_per_clump; + return (1); +} + + +/* + * JPEG Decoding. + */ + +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + +#define JPEG_MARKER_SOF0 0xC0 +#define JPEG_MARKER_SOF1 0xC1 +#define JPEG_MARKER_SOF3 0xC3 +#define JPEG_MARKER_DHT 0xC4 +#define JPEG_MARKER_SOI 0xD8 +#define JPEG_MARKER_SOS 0xDA +#define JPEG_MARKER_DQT 0xDB +#define JPEG_MARKER_DRI 0xDD +#define JPEG_MARKER_APP0 0xE0 +#define JPEG_MARKER_COM 0xFE +struct JPEGFixupTagsSubsamplingData +{ + TIFF* tif; + void* buffer; + uint32 buffersize; + uint8* buffercurrentbyte; + uint32 bufferbytesleft; + uint64 fileoffset; + uint64 filebytesleft; + uint8 filepositioned; +}; +static void JPEGFixupTagsSubsampling(TIFF* tif); +static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data); +static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result); +static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result); +static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength); + +#endif + +static int +JPEGFixupTags(TIFF* tif) +{ +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& + (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& + (tif->tif_dir.td_samplesperpixel==3)) + JPEGFixupTagsSubsampling(tif); +#endif + + return(1); +} + +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + +static void +JPEGFixupTagsSubsampling(TIFF* tif) +{ + /* + * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in + * the TIFF tags, but still use non-default (2,2) values within the jpeg + * data stream itself. In order for TIFF applications to work properly + * - for instance to get the strip buffer size right - it is imperative + * that the subsampling be available before we start reading the image + * data normally. This function will attempt to analyze the first strip in + * order to get the sampling values from the jpeg data stream. + * + * Note that JPEGPreDeocode() will produce a fairly loud warning when the + * discovered sampling does not match the default sampling (2,2) or whatever + * was actually in the tiff tags. + * + * See the bug in bugzilla for details: + * + * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + * + * Frank Warmerdam, July 2002 + * Joris Van Damme, May 2007 + */ + static const char module[] = "JPEGFixupTagsSubsampling"; + struct JPEGFixupTagsSubsamplingData m; + + _TIFFFillStriles( tif ); + + if( tif->tif_dir.td_stripbytecount == NULL + || tif->tif_dir.td_stripbytecount[0] == 0 ) + { + /* Do not even try to check if the first strip/tile does not + yet exist, as occurs when GDAL has created a new NULL file + for instance. */ + return; + } + + m.tif=tif; + m.buffersize=2048; + m.buffer=_TIFFmalloc(m.buffersize); + if (m.buffer==NULL) + { + TIFFWarningExt(tif->tif_clientdata,module, + "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped"); + return; + } + m.buffercurrentbyte=NULL; + m.bufferbytesleft=0; + m.fileoffset=tif->tif_dir.td_stripoffset[0]; + m.filepositioned=0; + m.filebytesleft=tif->tif_dir.td_stripbytecount[0]; + if (!JPEGFixupTagsSubsamplingSec(&m)) + TIFFWarningExt(tif->tif_clientdata,module, + "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped"); + _TIFFfree(m.buffer); +} + +static int +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data) +{ + static const char module[] = "JPEGFixupTagsSubsamplingSec"; + uint8 m; + while (1) + { + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) + return(0); + if (m==255) + break; + } + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) + return(0); + if (m!=255) + break; + } + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0+1: + case JPEG_MARKER_APP0+2: + case JPEG_MARKER_APP0+3: + case JPEG_MARKER_APP0+4: + case JPEG_MARKER_APP0+5: + case JPEG_MARKER_APP0+6: + case JPEG_MARKER_APP0+7: + case JPEG_MARKER_APP0+8: + case JPEG_MARKER_APP0+9: + case JPEG_MARKER_APP0+10: + case JPEG_MARKER_APP0+11: + case JPEG_MARKER_APP0+12: + case JPEG_MARKER_APP0+13: + case JPEG_MARKER_APP0+14: + case JPEG_MARKER_APP0+15: + case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DRI: + /* this type of marker has data, but it has no use to us and should be skipped */ + { + uint16 n; + if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) + return(0); + if (n<2) + return(0); + n-=2; + if (n>0) + JPEGFixupTagsSubsamplingSkip(data,n); + } + break; + case JPEG_MARKER_SOF0: + case JPEG_MARKER_SOF1: + /* this marker contains the subsampling factors we're scanning for */ + { + uint16 n; + uint16 o; + uint8 p; + uint8 ph,pv; + if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) + return(0); + if (n!=8+data->tif->tif_dir.td_samplesperpixel*3) + return(0); + JPEGFixupTagsSubsamplingSkip(data,7); + if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) + return(0); + ph=(p>>4); + pv=(p&15); + JPEGFixupTagsSubsamplingSkip(data,1); + for (o=1; otif->tif_dir.td_samplesperpixel; o++) + { + JPEGFixupTagsSubsamplingSkip(data,1); + if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) + return(0); + if (p!=0x11) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); + return(1); + } + JPEGFixupTagsSubsamplingSkip(data,1); + } + if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4))) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); + return(1); + } + if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1])) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]", + (int)data->tif->tif_dir.td_ycbcrsubsampling[0], + (int)data->tif->tif_dir.td_ycbcrsubsampling[1], + (int)ph,(int)pv); + data->tif->tif_dir.td_ycbcrsubsampling[0]=ph; + data->tif->tif_dir.td_ycbcrsubsampling[1]=pv; + } + } + return(1); + default: + return(0); + } + } +} + +static int +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result) +{ + if (data->bufferbytesleft==0) + { + uint32 m; + if (data->filebytesleft==0) + return(0); + if (!data->filepositioned) + { + TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET); + data->filepositioned=1; + } + m=data->buffersize; + if ((uint64)m>data->filebytesleft) + m=(uint32)data->filebytesleft; + assert(m<0x80000000UL); + if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m) + return(0); + data->buffercurrentbyte=data->buffer; + data->bufferbytesleft=m; + data->fileoffset+=m; + data->filebytesleft-=m; + } + *result=*data->buffercurrentbyte; + data->buffercurrentbyte++; + data->bufferbytesleft--; + return(1); +} + +static int +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result) +{ + uint8 ma; + uint8 mb; + if (!JPEGFixupTagsSubsamplingReadByte(data,&ma)) + return(0); + if (!JPEGFixupTagsSubsamplingReadByte(data,&mb)) + return(0); + *result=(ma<<8)|mb; + return(1); +} + +static void +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength) +{ + if ((uint32)skiplength<=data->bufferbytesleft) + { + data->buffercurrentbyte+=skiplength; + data->bufferbytesleft-=skiplength; + } + else + { + uint16 m; + m=skiplength-data->bufferbytesleft; + if (m<=data->filebytesleft) + { + data->bufferbytesleft=0; + data->fileoffset+=m; + data->filebytesleft-=m; + data->filepositioned=0; + } + else + { + data->bufferbytesleft=0; + data->filebytesleft=0; + } + } +} + +#endif + + +static int +JPEGSetupDecode(TIFF* tif) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 ); +#endif + + JPEGInitializeLibJPEG( tif, TRUE ); + + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); + + /* Read JPEGTables if it is present */ + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { + TIFFjpeg_tables_src(sp, tif); + if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { + TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field"); + return (0); + } + } + + /* Grab parameters that are same for all strips/tiles */ + sp->photometric = td->td_photometric; + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + break; + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Set up for reading normal data */ + TIFFjpeg_data_src(sp, tif); + tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ + return (1); +} + +/* + * Set up for decoding a strip or tile. + */ +static int +JPEGPreDecode(TIFF* tif, uint16 s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreDecode"; + uint32 segment_width, segment_height; + int downsampled_output; + int ci; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 0) + { + tif->tif_setupdecode( tif ); + } + + assert(sp->cinfo.comm.is_decompressor); + /* + * Reset decoder state from any previous strip/tile, + * in case application didn't read the whole strip. + */ + if (!TIFFjpeg_abort(sp)) + return (0); + /* + * Read the header for this strip/tile. + */ + + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) + return (0); + + tif->tif_rawcp = (uint8*) sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* + * Check image parameters and set decompression parameters. + */ + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* + * For PC 2, scale down the expected strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (sp->cinfo.d.image_width < segment_width || + sp->cinfo.d.image_height < segment_height) { + TIFFWarningExt(tif->tif_clientdata, module, + "Improper JPEG strip/tile size, " + "expected %dx%d, got %dx%d", + segment_width, segment_height, + sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) { + /* + * This case could be dangerous, if the strip or tile size has + * been reported as less than the amount of data jpeg will + * return, some potential security issues arise. Catch this + * case and error out. + */ + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG strip/tile size exceeds expected dimensions," + " expected %dx%d, got %dx%d", + segment_width, segment_height, + sp->cinfo.d.image_width, sp->cinfo.d.image_height); + return (0); + } + if (sp->cinfo.d.num_components != + (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1)) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count"); + return (0); + } +#ifdef JPEG_LIB_MK1 + if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); + } + sp->cinfo.d.data_precision = td->td_bitspersample; + sp->cinfo.d.bits_in_jsample = td->td_bitspersample; +#else + if (sp->cinfo.d.data_precision != td->td_bitspersample) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); + } +#endif + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + /* Component 0 should have expected sampling factors */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { + TIFFErrorExt(tif->tif_clientdata, module, + "Improper JPEG sampling factors %d,%d\n" + "Apparently should be %d,%d.", + sp->cinfo.d.comp_info[0].h_samp_factor, + sp->cinfo.d.comp_info[0].v_samp_factor, + sp->h_sampling, sp->v_sampling); + return (0); + } + /* Rest should have sampling factors 1,1 */ + for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { + if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || + sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); + return (0); + } + } + } else { + /* PC 2's single component should have sampling factors 1,1 */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || + sp->cinfo.d.comp_info[0].v_samp_factor != 1) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); + return (0); + } + } + downsampled_output = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + sp->photometric == PHOTOMETRIC_YCBCR && + sp->jpegcolormode == JPEGCOLORMODE_RGB) { + /* Convert YCbCr to RGB */ + sp->cinfo.d.jpeg_color_space = JCS_YCbCr; + sp->cinfo.d.out_color_space = JCS_RGB; + } else { + /* Suppress colorspace handling */ + sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; + sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + (sp->h_sampling != 1 || sp->v_sampling != 1)) + downsampled_output = TRUE; + /* XXX what about up-sampling? */ + } + if (downsampled_output) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.d.raw_data_out = TRUE; + tif->tif_decoderow = DecodeRowError; + tif->tif_decodestrip = JPEGDecodeRaw; + tif->tif_decodetile = JPEGDecodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.d.raw_data_out = FALSE; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + } + /* Start JPEG decompressor */ + if (!TIFFjpeg_start_decompress(sp)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_output) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, + sp->cinfo.d.num_components)) + return (0); + sp->scancount = DCTSIZE; /* mark buffer empty */ + } + return (1); +} + +/* + * Decode a chunk of pixels. + * "Standard" case: returned data is not downsampled. + */ +/*ARGSUSED*/ static int +JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void) s; + + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; + + if( sp->bytesperline == 0 ) + return 0; + + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read"); + + if( nrows > (tmsize_t) sp->cinfo.d.image_height ) + nrows = sp->cinfo.d.image_height; + + /* data is expected to be read in multiples of a scanline */ + if (nrows) + { + JSAMPROW line_work_buf = NULL; + + /* + * For 6B, only use temporary buffer for 12 bit imagery. + * For Mk1 always use it. + */ +#if !defined(JPEG_LIB_MK1) + if( sp->cinfo.d.data_precision == 12 ) +#endif + { + line_work_buf = (JSAMPROW) + _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width + * sp->cinfo.d.num_components ); + } + + do { + if( line_work_buf != NULL ) + { + /* + * In the MK1 case, we aways read into a 16bit buffer, and then + * pack down to 12bit or 8bit. In 6B case we only read into 16 + * bit buffer for 12bit data, which we need to repack. + */ + if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) + return (0); + + if( sp->cinfo.d.data_precision == 12 ) + { + int value_pairs = (sp->cinfo.d.output_width + * sp->cinfo.d.num_components) / 2; + int iPair; + + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *out_ptr = + ((unsigned char *) buf) + iPair * 3; + JSAMPLE *in_ptr = line_work_buf + iPair * 2; + + out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; + out_ptr[1] = ((in_ptr[0] & 0xf) << 4) + | ((in_ptr[1] & 0xf00) >> 8); + out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); + } + } + else if( sp->cinfo.d.data_precision == 8 ) + { + int value_count = (sp->cinfo.d.output_width + * sp->cinfo.d.num_components); + int iValue; + + for( iValue = 0; iValue < value_count; iValue++ ) + { + ((unsigned char *) buf)[iValue] = + line_work_buf[iValue] & 0xff; + } + } + } + else + { + /* + * In the libjpeg6b 8bit case. We read directly into the + * TIFF buffer. + */ + JSAMPROW bufptr = (JSAMPROW)buf; + + if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) + return (0); + } + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + + if( line_work_buf != NULL ) + _TIFFfree( line_work_buf ); + } + + /* Update information on consumed data */ + tif->tif_rawcp = (uint8*) sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height + || TIFFjpeg_finish_decompress(sp); +} + +/*ARGSUSED*/ static int +DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) + +{ + (void) buf; + (void) cc; + (void) s; + + TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline", + "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." ); + return 0; +} + +/* + * Decode a chunk of pixels. + * Returned data is downsampled per sampling factors. + */ +/*ARGSUSED*/ static int +JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void) s; + + /* data is expected to be read in multiples of a scanline */ + if ( (nrows = sp->cinfo.d.image_height) ) { + + /* Cb,Cr both have sampling factors 1, so this is correct */ + JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + int samples_per_clump = sp->samplesperclump; + +#if defined(JPEG_LIB_MK1_OR_12BIT) + unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * + sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + if(tmpbuf==NULL) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "Out of memory"); + return 0; + } +#endif + + do { + jpeg_component_info *compptr; + int ci, clumpoffset; + + if( cc < sp->bytesperline ) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "application buffer not large enough for all data."); + return 0; + } + + /* Reload downsampled-data buffer if needed */ + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + } + /* + * Fastest way to unseparate data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.d.comp_info; + ci < sp->cinfo.d.num_components; + ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int ypos; + + for (ypos = 0; ypos < vsamp; ypos++) { + JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; + JDIMENSION nclump; +#if defined(JPEG_LIB_MK1_OR_12BIT) + JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; +#else + JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; + if (cc < clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "application buffer not large enough for all data, possible subsampling issue"); + return 0; + } +#endif + + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + outptr[0] = *inptr++; + outptr += samples_per_clump; + } + } else { + int xpos; + + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + for (xpos = 0; xpos < hsamp; xpos++) + outptr[xpos] = *inptr++; + outptr += samples_per_clump; + } + } + clumpoffset += hsamp; + } + } + +#if defined(JPEG_LIB_MK1_OR_12BIT) + { + if (sp->cinfo.d.data_precision == 8) + { + int i=0; + int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; + for (i=0; icinfo.d.output_width + * sp->cinfo.d.num_components) / 2; + int iPair; + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; + JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2); + out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; + out_ptr[1] = ((in_ptr[0] & 0xf) << 4) + | ((in_ptr[1] & 0xf00) >> 8); + out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); + } + } + } +#endif + + sp->scancount ++; + tif->tif_row += sp->v_sampling; + + buf += sp->bytesperline; + cc -= sp->bytesperline; + + nrows -= sp->v_sampling; + } while (nrows > 0); + +#if defined(JPEG_LIB_MK1_OR_12BIT) + _TIFFfree(tmpbuf); +#endif + + } + + /* Close down the decompressor if done. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height + || TIFFjpeg_finish_decompress(sp); +} + + +/* + * JPEG Encoding. + */ + +static void +unsuppress_quant_table (JPEGState* sp, int tblno) +{ + JQUANT_TBL* qtbl; + + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = FALSE; +} + +static void +unsuppress_huff_table (JPEGState* sp, int tblno) +{ + JHUFF_TBL* htbl; + + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; +} + +static int +prepare_JPEGTables(TIFF* tif) +{ + JPEGState* sp = JState(tif); + + /* Initialize quant tables for current quality setting */ + if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) + return (0); + /* Mark only the tables we want for output */ + /* NB: chrominance tables are currently used only with YCbCr */ + if (!TIFFjpeg_suppress_tables(sp, TRUE)) + return (0); + if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { + unsuppress_quant_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_quant_table(sp, 1); + } + if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { + unsuppress_huff_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_huff_table(sp, 1); + } + /* Direct libjpeg output into jpegtables */ + if (!TIFFjpeg_tables_dest(sp, tif)) + return (0); + /* Emit tables-only datastream */ + if (!TIFFjpeg_write_tables(sp)) + return (0); + + return (1); +} + +static int +JPEGSetupEncode(TIFF* tif) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGSetupEncode"; + +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 ); +#endif + + JPEGInitializeLibJPEG( tif, FALSE ); + + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + + /* + * Initialize all JPEG parameters to default values. + * Note that jpeg_set_defaults needs legal values for + * in_color_space and input_components. + */ + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + sp->cinfo.c.input_components = 1; + if (!TIFFjpeg_set_defaults(sp)) + return (0); + /* Set per-file parameters */ + sp->photometric = td->td_photometric; + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + /* + * A ReferenceBlackWhite field *must* be present since the + * default value is inappropriate for YCbCr. Fill in the + * proper value if application didn't set it. + */ + { + float *ref; + if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, + &ref)) { + float refbw[6]; + long top = 1L << td->td_bitspersample; + refbw[0] = 0; + refbw[1] = (float)(top-1L); + refbw[2] = (float)(top>>1); + refbw[3] = refbw[1]; + refbw[4] = refbw[2]; + refbw[5] = refbw[1]; + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, + refbw); + } + } + break; + case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ + case PHOTOMETRIC_MASK: + TIFFErrorExt(tif->tif_clientdata, module, + "PhotometricInterpretation %d not allowed for JPEG", + (int) sp->photometric); + return (0); + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Verify miscellaneous parameters */ + + /* + * This would need work if libtiff ever supports different + * depths for different components, or if libjpeg ever supports + * run-time selection of depth. Neither is imminent. + */ +#ifdef JPEG_LIB_MK1 + /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ + if (td->td_bitspersample != 8 && td->td_bitspersample != 12) +#else + if (td->td_bitspersample != BITS_IN_JSAMPLE ) +#endif + { + TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG", + (int) td->td_bitspersample); + return (0); + } + sp->cinfo.c.data_precision = td->td_bitspersample; +#ifdef JPEG_LIB_MK1 + sp->cinfo.c.bits_in_jsample = td->td_bitspersample; +#endif + if (isTiled(tif)) { + if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG tile height must be multiple of %d", + sp->v_sampling * DCTSIZE); + return (0); + } + if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG tile width must be multiple of %d", + sp->h_sampling * DCTSIZE); + return (0); + } + } else { + if (td->td_rowsperstrip < td->td_imagelength && + (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "RowsPerStrip must be multiple of %d for JPEG", + sp->v_sampling * DCTSIZE); + return (0); + } + } + + /* Create a JPEGTables field if appropriate */ + if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { + if( sp->jpegtables == NULL + || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 ) + { + if (!prepare_JPEGTables(tif)) + return (0); + /* Mark the field present */ + /* Can't use TIFFSetField since BEENWRITING is already set! */ + tif->tif_flags |= TIFF_DIRTYDIRECT; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + } + } else { + /* We do not support application-supplied JPEGTables, */ + /* so mark the field not present */ + TIFFClrFieldBit(tif, FIELD_JPEGTABLES); + } + + /* Direct libjpeg output to libtiff's output buffer */ + TIFFjpeg_data_dest(sp, tif); + + return (1); +} + +/* + * Set encoding state at the start of a strip or tile. + */ +static int +JPEGPreEncode(TIFF* tif, uint16 s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreEncode"; + uint32 segment_width, segment_height; + int downsampled_input; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 1) + { + tif->tif_setupencode( tif ); + } + + assert(!sp->cinfo.comm.is_decompressor); + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* for PC 2, scale down the strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (segment_width > 65535 || segment_height > 65535) { + TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); + return (0); + } + sp->cinfo.c.image_width = segment_width; + sp->cinfo.c.image_height = segment_height; + downsampled_input = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) { + if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { + sp->cinfo.c.in_color_space = JCS_RGB; + } else { + sp->cinfo.c.in_color_space = JCS_YCbCr; + if (sp->h_sampling != 1 || sp->v_sampling != 1) + downsampled_input = TRUE; + } + if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + return (0); + /* + * Set Y sampling factors; + * we assume jpeg_set_colorspace() set the rest to 1 + */ + sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; + sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; + } else { + if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1) + sp->cinfo.c.in_color_space = JCS_GRAYSCALE; + else if (td->td_photometric == PHOTOMETRIC_RGB) + sp->cinfo.c.in_color_space = JCS_RGB; + else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4) + sp->cinfo.c.in_color_space = JCS_CMYK; + else + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) + return (0); + /* jpeg_set_colorspace set all sampling factors to 1 */ + } + } else { + sp->cinfo.c.input_components = 1; + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + sp->cinfo.c.comp_info[0].component_id = s; + /* jpeg_set_colorspace() set sampling factors to 1 */ + if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { + sp->cinfo.c.comp_info[0].quant_tbl_no = 1; + sp->cinfo.c.comp_info[0].dc_tbl_no = 1; + sp->cinfo.c.comp_info[0].ac_tbl_no = 1; + } + } + /* ensure libjpeg won't write any extraneous markers */ + sp->cinfo.c.write_JFIF_header = FALSE; + sp->cinfo.c.write_Adobe_marker = FALSE; + /* set up table handling correctly */ + if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) + return (0); + if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { + unsuppress_quant_table(sp, 0); + unsuppress_quant_table(sp, 1); + } + if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) + sp->cinfo.c.optimize_coding = FALSE; + else + sp->cinfo.c.optimize_coding = TRUE; + if (downsampled_input) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.c.raw_data_in = TRUE; + tif->tif_encoderow = JPEGEncodeRaw; + tif->tif_encodestrip = JPEGEncodeRaw; + tif->tif_encodetile = JPEGEncodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.c.raw_data_in = FALSE; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + } + /* Start JPEG compressor */ + if (!TIFFjpeg_start_compress(sp, FALSE)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_input) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, + sp->cinfo.c.num_components)) + return (0); + } + sp->scancount = 0; + + return (1); +} + +/* + * Encode a chunk of pixels. + * "Standard" case: incoming data is not downsampled. + */ +static int +JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; + + (void) s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline discarded"); + + /* The last strip will be limited to image size */ + if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength ) + nrows = tif->tif_dir.td_imagelength - tif->tif_row; + + if( sp->cinfo.c.data_precision == 12 ) + { + line16_count = (sp->bytesperline * 2) / 3; + line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count); + // FIXME: undiagnosed malloc failure + } + + while (nrows-- > 0) { + + if( sp->cinfo.c.data_precision == 12 ) + { + + int value_pairs = line16_count / 2; + int iPair; + + bufptr[0] = (JSAMPROW) line16; + + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *in_ptr = + ((unsigned char *) buf) + iPair * 3; + JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2); + + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; + } + } + else + { + bufptr[0] = (JSAMPROW) buf; + } + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + + if( sp->cinfo.c.data_precision == 12 ) + { + _TIFFfree( line16 ); + } + + return (1); +} + +/* + * Encode a chunk of pixels. + * Incoming data is expected to be downsampled per sampling factors. + */ +static int +JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + JPEGState *sp = JState(tif); + JSAMPLE* inptr; + JSAMPLE* outptr; + tmsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info* compptr; + int samples_per_clump = sp->samplesperclump; + tmsize_t bytesperclumpline; + + (void) s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a clumpline */ + /* a clumpline is equivalent to v_sampling desubsampled scanlines */ + /* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */ + bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling) + *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7) + /8; + + nrows = ( cc / bytesperclumpline ) * sp->v_sampling; + if (cc % bytesperclumpline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); + + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; + + while (nrows > 0) { + /* + * Fastest way to separate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; + ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int padding = (int) (compptr->width_in_blocks * DCTSIZE - + clumps_per_line * hsamp); + for (ypos = 0; ypos < vsamp; ypos++) { + inptr = ((JSAMPLE*) buf) + clumpoffset; + outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + *outptr++ = inptr[0]; + inptr += samples_per_clump; + } + } else { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + for (xpos = 0; xpos < hsamp; xpos++) + *outptr++ = inptr[xpos]; + inptr += samples_per_clump; + } + } + /* pad each scanline as needed */ + for (xpos = 0; xpos < padding; xpos++) { + *outptr = outptr[-1]; + outptr++; + } + clumpoffset += hsamp; + } + } + sp->scancount++; + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + } + tif->tif_row += sp->v_sampling; + buf += bytesperclumpline; + nrows -= sp->v_sampling; + } + return (1); +} + +/* + * Finish up at the end of a strip or tile. + */ +static int +JPEGPostEncode(TIFF* tif) +{ + JPEGState *sp = JState(tif); + + if (sp->scancount > 0) { + /* + * Need to emit a partial bufferload of downsampled data. + * Pad the data vertically. + */ + int ci, ypos, n; + jpeg_component_info* compptr; + + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; + ci++, compptr++) { + int vsamp = compptr->v_samp_factor; + tmsize_t row_width = compptr->width_in_blocks * DCTSIZE + * sizeof(JSAMPLE); + for (ypos = sp->scancount * vsamp; + ypos < DCTSIZE * vsamp; ypos++) { + _TIFFmemcpy((void*)sp->ds_buffer[ci][ypos], + (void*)sp->ds_buffer[ci][ypos-1], + row_width); + + } + } + n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + } + + return (TIFFjpeg_finish_compress(JState(tif))); +} + +static void +JPEGCleanup(TIFF* tif) +{ + JPEGState *sp = JState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + + if( sp != NULL ) { + if( sp->cinfo_initialized ) + TIFFjpeg_destroy(sp); /* release libjpeg resources */ + if (sp->jpegtables) /* tag value */ + _TIFFfree(sp->jpegtables); + } + _TIFFfree(tif->tif_data); /* release local state */ + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static void +JPEGResetUpsampled( TIFF* tif ) +{ + JPEGState* sp = JState(tif); + TIFFDirectory* td = &tif->tif_dir; + + /* + * Mark whether returned data is up-sampled or not so TIFFStripSize + * and TIFFTileSize return values that reflect the true amount of + * data. + */ + tif->tif_flags &= ~TIFF_UPSAMPLED; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + if (td->td_photometric == PHOTOMETRIC_YCBCR && + sp->jpegcolormode == JPEGCOLORMODE_RGB) { + tif->tif_flags |= TIFF_UPSAMPLED; + } else { +#ifdef notdef + if (td->td_ycbcrsubsampling[0] != 1 || + td->td_ycbcrsubsampling[1] != 1) + ; /* XXX what about up-sampling? */ +#endif + } + } + + /* + * Must recalculate cached tile size in case sampling state changed. + * Should we really be doing this now if image size isn't set? + */ + if( tif->tif_tilesize > 0 ) + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if( tif->tif_scanlinesize > 0 ) + tif->tif_scanlinesize = TIFFScanlineSize(tif); +} + +static int +JPEGVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + JPEGState* sp = JState(tif); + const TIFFField* fip; + uint32 v32; + + assert(sp != NULL); + + switch (tag) { + case TIFFTAG_JPEGTABLES: + v32 = (uint32) va_arg(ap, uint32); + if (v32 == 0) { + /* XXX */ + return (0); + } + _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), + (long) v32); + sp->jpegtables_length = v32; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + break; + case TIFFTAG_JPEGQUALITY: + sp->jpegquality = (int) va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGCOLORMODE: + sp->jpegcolormode = (int) va_arg(ap, int); + JPEGResetUpsampled( tif ); + return (1); /* pseudo tag */ + case TIFFTAG_PHOTOMETRIC: + { + int ret_value = (*sp->vsetparent)(tif, tag, ap); + JPEGResetUpsampled( tif ); + return ret_value; + } + case TIFFTAG_JPEGTABLESMODE: + sp->jpegtablesmode = (int) va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_YCBCRSUBSAMPLING: + /* mark the fact that we have a real ycbcrsubsampling! */ + sp->ycbcrsampling_fetched = 1; + /* should we be recomputing upsampling info here? */ + return (*sp->vsetparent)(tif, tag, ap); + default: + return (*sp->vsetparent)(tif, tag, ap); + } + + if ((fip = TIFFFieldWithTag(tif, tag))) { + TIFFSetFieldBit(tif, fip->field_bit); + } else { + return (0); + } + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int +JPEGVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + JPEGState* sp = JState(tif); + + assert(sp != NULL); + + switch (tag) { + case TIFFTAG_JPEGTABLES: + *va_arg(ap, uint32*) = sp->jpegtables_length; + *va_arg(ap, void**) = sp->jpegtables; + break; + case TIFFTAG_JPEGQUALITY: + *va_arg(ap, int*) = sp->jpegquality; + break; + case TIFFTAG_JPEGCOLORMODE: + *va_arg(ap, int*) = sp->jpegcolormode; + break; + case TIFFTAG_JPEGTABLESMODE: + *va_arg(ap, int*) = sp->jpegtablesmode; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static void +JPEGPrintDir(TIFF* tif, FILE* fd, long flags) +{ + JPEGState* sp = JState(tif); + + assert(sp != NULL); + (void) flags; + + if( sp != NULL ) { + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%lu bytes)\n", + (unsigned long) sp->jpegtables_length); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); + } +} + +static uint32 +JPEGDefaultStripSize(TIFF* tif, uint32 s) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + s = (*sp->defsparent)(tif, s); + if (s < td->td_imagelength) + s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + return (s); +} + +static void +JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + (*sp->deftparent)(tif, tw, th); + *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); +} + +/* + * The JPEG library initialized used to be done in TIFFInitJPEG(), but + * now that we allow a TIFF file to be opened in update mode it is necessary + * to have some way of deciding whether compression or decompression is + * desired other than looking at tif->tif_mode. We accomplish this by + * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry. + * If so, we assume decompression is desired. + * + * This is tricky, because TIFFInitJPEG() is called while the directory is + * being read, and generally speaking the BYTECOUNTS tag won't have been read + * at that point. So we try to defer jpeg library initialization till we + * do have that tag ... basically any access that might require the compressor + * or decompressor that occurs after the reading of the directory. + * + * In an ideal world compressors or decompressors would be setup + * at the point where a single tile or strip was accessed (for read or write) + * so that stuff like update of missing tiles, or replacement of tiles could + * be done. However, we aren't trying to crack that nut just yet ... + * + * NFW, Feb 3rd, 2003. + */ + +static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) +{ + JPEGState* sp = JState(tif); + + if(sp->cinfo_initialized) + { + if( !decompress && sp->cinfo.comm.is_decompressor ) + TIFFjpeg_destroy( sp ); + else if( decompress && !sp->cinfo.comm.is_decompressor ) + TIFFjpeg_destroy( sp ); + else + return 1; + + sp->cinfo_initialized = 0; + } + + /* + * Initialize libjpeg. + */ + if ( decompress ) { + if (!TIFFjpeg_create_decompress(sp)) + return (0); + } else { + if (!TIFFjpeg_create_compress(sp)) + return (0); + } + + sp->cinfo_initialized = TRUE; + + return 1; +} + +int +TIFFInitJPEG(TIFF* tif, int scheme) +{ + JPEGState* sp; + + assert(scheme == COMPRESSION_JPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { + TIFFErrorExt(tif->tif_clientdata, + "TIFFInitJPEG", + "Merging JPEG codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState)); + + if (tif->tif_data == NULL) { + TIFFErrorExt(tif->tif_clientdata, + "TIFFInitJPEG", "No space for JPEG state block"); + return 0; + } + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->jpegtables = NULL; + sp->jpegtables_length = 0; + sp->jpegquality = 75; /* Default IJG quality */ + sp->jpegcolormode = JPEGCOLORMODE_RAW; + sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; + sp->ycbcrsampling_fetched = 0; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + sp->defsparent = tif->tif_defstripsize; + tif->tif_defstripsize = JPEGDefaultStripSize; + sp->deftparent = tif->tif_deftilesize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + + sp->cinfo_initialized = FALSE; + + /* + ** Create a JPEGTables field if no directory has yet been created. + ** We do this just to ensure that sufficient space is reserved for + ** the JPEGTables field. It will be properly created the right + ** size later. + */ + if( tif->tif_diroff == 0 ) + { +#define SIZE_OF_JPEGTABLES 2000 +/* +The following line assumes incorrectly that all JPEG-in-TIFF files will have +a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written +when the JPEG data is placed with TIFFWriteRawStrip. The field bit should be +set, anyway, later when actual JPEGTABLES header is generated, so removing it +here hopefully is harmless. + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); +*/ + sp->jpegtables_length = SIZE_OF_JPEGTABLES; + sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length); + // FIXME: NULL-deref after malloc failure + _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES); +#undef SIZE_OF_JPEGTABLES + } + + return 1; +} +#endif /* JPEG_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg_12.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg_12.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg_12.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_jpeg_12.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,65 @@ + +#include "tiffiop.h" + +#if defined(JPEG_DUAL_MODE_8_12) + +# define TIFFInitJPEG TIFFInitJPEG_12 + +# include LIBJPEG_12_PATH + +# include "tif_jpeg.c" + +int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ) + +{ + JPEGState* sp; + + assert(scheme == COMPRESSION_JPEG); + + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* + * Override parent get/set field methods. + */ + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ + + /* + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + tif->tif_defstripsize = JPEGDefaultStripSize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + + sp->cinfo_initialized = FALSE; + + if( is_encode ) + return JPEGSetupEncode(tif); + else + return JPEGSetupDecode(tif); +} + +#endif /* defined(JPEG_DUAL_MODE_8_12) */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_luv.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_luv.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_luv.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_luv.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1683 @@ +/* $Id: tif_luv.c,v 1.35 2011-04-02 20:54:09 bfriesen Exp $ */ + +/* + * Copyright (c) 1997 Greg Ward Larson + * Copyright (c) 1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any + * advertising or publicity relating to the software without the specific, + * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE + * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LOGLUV_SUPPORT + +/* + * TIFF Library. + * LogLuv compression support for high dynamic range images. + * + * Contributed by Greg Larson. + * + * LogLuv image support uses the TIFF library to store 16 or 10-bit + * log luminance values with 8 bits each of u and v or a 14-bit index. + * + * The codec can take as input and produce as output 32-bit IEEE float values + * as well as 16-bit integer values. A 16-bit luminance is interpreted + * as a sign bit followed by a 15-bit integer that is converted + * to and from a linear magnitude using the transformation: + * + * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit + * + * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real + * + * The actual conversion to world luminance units in candelas per sq. meter + * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. + * This value is usually set such that a reasonable exposure comes from + * clamping decoded luminances above 1 to 1 in the displayed image. + * + * The 16-bit values for u and v may be converted to real values by dividing + * each by 32768. (This allows for negative values, which aren't useful as + * far as we know, but are left in case of future improvements in human + * color vision.) + * + * Conversion from (u,v), which is actually the CIE (u',v') system for + * you color scientists, is accomplished by the following transformation: + * + * u = 4*x / (-2*x + 12*y + 3) + * v = 9*y / (-2*x + 12*y + 3) + * + * x = 9*u / (6*u - 16*v + 12) + * y = 4*v / (6*u - 16*v + 12) + * + * This process is greatly simplified by passing 32-bit IEEE floats + * for each of three CIE XYZ coordinates. The codec then takes care + * of conversion to and from LogLuv, though the application is still + * responsible for interpreting the TIFFTAG_STONITS calibration factor. + * + * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white + * point of (x,y)=(1/3,1/3). However, most color systems assume some other + * white point, such as D65, and an absolute color conversion to XYZ then + * to another color space with a different white point may introduce an + * unwanted color cast to the image. It is often desirable, therefore, to + * perform a white point conversion that maps the input white to [1 1 1] + * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT + * tag value. A decoder that demands absolute color calibration may use + * this white point tag to get back the original colors, but usually it + * will be ignored and the new white point will be used instead that + * matches the output color space. + * + * Pixel information is compressed into one of two basic encodings, depending + * on the setting of the compression tag, which is one of COMPRESSION_SGILOG + * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is + * stored as: + * + * 1 15 + * |-+---------------| + * + * COMPRESSION_SGILOG color data is stored as: + * + * 1 15 8 8 + * |-+---------------|--------+--------| + * S Le ue ve + * + * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: + * + * 10 14 + * |----------|--------------| + * Le' Ce + * + * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is + * encoded as an index for optimal color resolution. The 10 log bits are + * defined by the following conversions: + * + * L = 2^((Le'+.5)/64 - 12) # real from 10-bit + * + * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real + * + * The 10 bits of the smaller format may be converted into the 15 bits of + * the larger format by multiplying by 4 and adding 13314. Obviously, + * a smaller range of magnitudes is covered (about 5 orders of magnitude + * instead of 38), and the lack of a sign bit means that negative luminances + * are not allowed. (Well, they aren't allowed in the real world, either, + * but they are useful for certain types of image processing.) + * + * The desired user format is controlled by the setting the internal + * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: + * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values + * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v + * Raw data i/o is also possible using: + * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel + * In addition, the following decoding is provided for ease of display: + * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values + * + * For grayscale images, we provide the following data formats: + * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values + * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance + * SGILOGDATAFMT_8BIT = 8-bit gray monitor values + * + * Note that the COMPRESSION_SGILOG applies a simple run-length encoding + * scheme by separating the logL, u and v bytes for each row and applying + * a PackBits type of compression. Since the 24-bit encoding is not + * adaptive, the 32-bit color format takes less space in many cases. + * + * Further control is provided over the conversion from higher-resolution + * formats to final encoded values through the pseudo tag + * TIFFTAG_SGILOGENCODE: + * SGILOGENCODE_NODITHER = do not dither encoded values + * SGILOGENCODE_RANDITHER = apply random dithering during encoding + * + * The default value of this tag is SGILOGENCODE_NODITHER for + * COMPRESSION_SGILOG to maximize run-length encoding and + * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn + * quantization errors into noise. + */ + +#include +#include +#include + +/* + * State block for each open TIFF + * file using LogLuv compression/decompression. + */ +typedef struct logLuvState LogLuvState; + +struct logLuvState { + int user_datafmt; /* user data format */ + int encode_meth; /* encoding method */ + int pixel_size; /* bytes per pixel */ + + uint8* tbuf; /* translation buffer */ + tmsize_t tbuflen; /* buffer length */ + void (*tfunc)(LogLuvState*, uint8*, tmsize_t); + + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +}; + +#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) + +#define SGILOGDATAFMT_UNKNOWN -1 + +#define MINRUN 4 /* minimum run length */ + +/* + * Decode a string of 16-bit gray pixels. + */ +static int +LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "LogL16Decode"; + LogLuvState* sp = DecoderState(tif); + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char* bp; + int16* tp; + int16 b; + tmsize_t cc; + int rc; + + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16*) op; + else { + assert(sp->tbuflen >= npixels); + tp = (int16*) sp->tbuf; + } + _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); + + bp = (unsigned char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 2*8; (shft -= 8) >= 0; ) { + for (i = 0; i < npixels && cc > 0; ) + if (*bp >= 128) { /* run */ + rc = *bp++ + (2-128); /* TODO: potential input buffer overrun when decoding corrupt or truncated data */ + b = (int16)(*bp++ << shft); + cc -= 2; + while (rc-- && i < npixels) + tp[i++] |= b; + } else { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (int16)*bp++ << shft; + } + if (i != npixels) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + return (1); +} + +/* + * Decode a string of 24-bit pixels. + */ +static int +LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "LogLuvDecode24"; + LogLuvState* sp = DecoderState(tif); + tmsize_t cc; + tmsize_t i; + tmsize_t npixels; + unsigned char* bp; + uint32* tp; + + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32 *)op; + else { + assert(sp->tbuflen >= npixels); + tp = (uint32 *) sp->tbuf; + } + /* copy to array of uint32 */ + bp = (unsigned char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + for (i = 0; i < npixels && cc > 0; i++) { + tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; + bp += 3; + cc -= 3; + } + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + if (i != npixels) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif + return (0); + } + (*sp->tfunc)(sp, op, npixels); + return (1); +} + +/* + * Decode a string of 32-bit pixels. + */ +static int +LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "LogLuvDecode32"; + LogLuvState* sp; + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char* bp; + uint32* tp; + uint32 b; + tmsize_t cc; + int rc; + + assert(s == 0); + sp = DecoderState(tif); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) op; + else { + assert(sp->tbuflen >= npixels); + tp = (uint32*) sp->tbuf; + } + _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); + + bp = (unsigned char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 4*8; (shft -= 8) >= 0; ) { + for (i = 0; i < npixels && cc > 0; ) + if (*bp >= 128) { /* run */ + rc = *bp++ + (2-128); + b = (uint32)*bp++ << shft; + cc -= 2; /* TODO: potential input buffer overrun when decoding corrupt or truncated data */ + while (rc-- && i < npixels) + tp[i++] |= b; + } else { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (uint32)*bp++ << shft; + } + if (i != npixels) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + return (1); +} + +/* + * Decode a strip of pixels. We break it into rows to + * maintain synchrony with the encode algorithm, which + * is row by row. + */ +static int +LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + tmsize_t rowlen = TIFFScanlineSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Decode a tile of pixels. We break it into rows to + * maintain synchrony with the encode algorithm, which + * is row by row. + */ +static int +LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + tmsize_t rowlen = TIFFTileRowSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode a row of 16-bit pixels. + */ +static int +LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + LogLuvState* sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8* op; + int16* tp; + int16 b; + tmsize_t occ; + int rc=0, mask; + tmsize_t beg; + + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16*) bp; + else { + tp = (int16*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 2*8; (shft -= 8) >= 0; ) + for (i = 0; i < npixels; i += rc) { + if (occ < 4) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) { + b = (int16) (tp[beg] & mask); + rc = 1; + while (rc < 127+2 && beg+rc < npixels && + (tp[beg+rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg-i > 1 && beg-i < MINRUN) { + b = (int16) (tp[i] & mask);/*check short run */ + j = i+1; + while ((tp[j++] & mask) == b) + if (j == beg) { + *op++ = (uint8)(128-2+j-i); + *op++ = (uint8)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) { /* write out non-run */ + if ((j = beg-i) > 127) j = 127; + if (occ < j+3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8) j; occ--; + while (j--) { + *op++ = (uint8) (tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) { /* write out run */ + *op++ = (uint8) (128-2+rc); + *op++ = (uint8) (tp[beg] >> shft & 0xff); + occ -= 2; + } else + rc = 0; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); +} + +/* + * Encode a row of 24-bit pixels. + */ +static int +LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + LogLuvState* sp = EncoderState(tif); + tmsize_t i; + tmsize_t npixels; + tmsize_t occ; + uint8* op; + uint32* tp; + + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) bp; + else { + tp = (uint32*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* write out encoded pixels */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (i = npixels; i--; ) { + if (occ < 3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8)(*tp >> 16); + *op++ = (uint8)(*tp >> 8 & 0xff); + *op++ = (uint8)(*tp++ & 0xff); + occ -= 3; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); +} + +/* + * Encode a row of 32-bit pixels. + */ +static int +LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + LogLuvState* sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8* op; + uint32* tp; + uint32 b; + tmsize_t occ; + int rc=0, mask; + tmsize_t beg; + + assert(s == 0); + assert(sp != NULL); + + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) bp; + else { + tp = (uint32*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 4*8; (shft -= 8) >= 0; ) + for (i = 0; i < npixels; i += rc) { + if (occ < 4) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) { + b = tp[beg] & mask; + rc = 1; + while (rc < 127+2 && beg+rc < npixels && + (tp[beg+rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg-i > 1 && beg-i < MINRUN) { + b = tp[i] & mask; /* check short run */ + j = i+1; + while ((tp[j++] & mask) == b) + if (j == beg) { + *op++ = (uint8)(128-2+j-i); + *op++ = (uint8)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) { /* write out non-run */ + if ((j = beg-i) > 127) j = 127; + if (occ < j+3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8) j; occ--; + while (j--) { + *op++ = (uint8)(tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) { /* write out run */ + *op++ = (uint8) (128-2+rc); + *op++ = (uint8)(tp[beg] >> shft & 0xff); + occ -= 2; + } else + rc = 0; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); +} + +/* + * Encode a strip of pixels. We break it into rows to + * avoid encoding runs across row boundaries. + */ +static int +LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + tmsize_t rowlen = TIFFScanlineSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode a tile of pixels. We break it into rows to + * avoid encoding runs across row boundaries. + */ +static int +LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + tmsize_t rowlen = TIFFTileRowSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode/Decode functions for converting to and from user formats. + */ + +#include "uvcode.h" + +#ifndef UVSCALE +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. +#endif + +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#define log2(x) ((1./M_LN2)*log(x)) +#define exp2(x) exp(M_LN2*(x)) + +#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \ + (int)(x) : \ + (int)((x) + rand()*(1./RAND_MAX) - .5)) + +#if !LOGLUV_PUBLIC +static +#endif +double +LogL16toY(int p16) /* compute luminance from 16-bit LogL */ +{ + int Le = p16 & 0x7fff; + double Y; + + if (!Le) + return (0.); + Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.); + return (!(p16 & 0x8000) ? Y : -Y); +} + +#if !LOGLUV_PUBLIC +static +#endif +int +LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ +{ + if (Y >= 1.8371976e19) + return (0x7fff); + if (Y <= -1.8371976e19) + return (0xffff); + if (Y > 5.4136769e-20) + return itrunc(256.*(log2(Y) + 64.), em); + if (Y < -5.4136769e-20) + return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em)); + return (0); +} + +static void +L16toY(LogLuvState* sp, uint8* op, tmsize_t n) +{ + int16* l16 = (int16*) sp->tbuf; + float* yp = (float*) op; + + while (n-- > 0) + *yp++ = (float)LogL16toY(*l16++); +} + +static void +L16toGry(LogLuvState* sp, uint8* op, tmsize_t n) +{ + int16* l16 = (int16*) sp->tbuf; + uint8* gp = (uint8*) op; + + while (n-- > 0) { + double Y = LogL16toY(*l16++); + *gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y))); + } +} + +static void +L16fromY(LogLuvState* sp, uint8* op, tmsize_t n) +{ + int16* l16 = (int16*) sp->tbuf; + float* yp = (float*) op; + + while (n-- > 0) + *l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth)); +} + +#if !LOGLUV_PUBLIC +static +#endif +void +XYZtoRGB24(float xyz[3], uint8 rgb[3]) +{ + double r, g, b; + /* assume CCIR-709 primaries */ + r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]; + g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]; + b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]; + /* assume 2.0 gamma for speed */ + /* could use integer sqrt approx., but this is probably faster */ + rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r))); + rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g))); + rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b))); +} + +#if !LOGLUV_PUBLIC +static +#endif +double +LogL10toY(int p10) /* compute luminance from 10-bit LogL */ +{ + if (p10 == 0) + return (0.); + return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.)); +} + +#if !LOGLUV_PUBLIC +static +#endif +int +LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ +{ + if (Y >= 15.742) + return (0x3ff); + else if (Y <= .00024283) + return (0); + else + return itrunc(64.*(log2(Y) + 12.), em); +} + +#define NANGLES 100 +#define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) \ + * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES ) + +static int +oog_encode(double u, double v) /* encode out-of-gamut chroma */ +{ + static int oog_table[NANGLES]; + static int initialized = 0; + register int i; + + if (!initialized) { /* set up perimeter table */ + double eps[NANGLES], ua, va, ang, epsa; + int ui, vi, ustep; + for (i = NANGLES; i--; ) + eps[i] = 2.; + for (vi = UV_NVS; vi--; ) { + va = UV_VSTART + (vi+.5)*UV_SQSIZ; + ustep = uv_row[vi].nus-1; + if (vi == UV_NVS-1 || vi == 0 || ustep <= 0) + ustep = 1; + for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) { + ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; + ang = uv2ang(ua, va); + i = (int) ang; + epsa = fabs(ang - (i+.5)); + if (epsa < eps[i]) { + oog_table[i] = uv_row[vi].ncum + ui; + eps[i] = epsa; + } + } + } + for (i = NANGLES; i--; ) /* fill any holes */ + if (eps[i] > 1.5) { + int i1, i2; + for (i1 = 1; i1 < NANGLES/2; i1++) + if (eps[(i+i1)%NANGLES] < 1.5) + break; + for (i2 = 1; i2 < NANGLES/2; i2++) + if (eps[(i+NANGLES-i2)%NANGLES] < 1.5) + break; + if (i1 < i2) + oog_table[i] = + oog_table[(i+i1)%NANGLES]; + else + oog_table[i] = + oog_table[(i+NANGLES-i2)%NANGLES]; + } + initialized = 1; + } + i = (int) uv2ang(u, v); /* look up hue angle */ + return (oog_table[i]); +} + +#undef uv2ang +#undef NANGLES + +#if !LOGLUV_PUBLIC +static +#endif +int +uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ +{ + register int vi, ui; + + if (v < UV_VSTART) + return oog_encode(u, v); + vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em); + if (vi >= UV_NVS) + return oog_encode(u, v); + if (u < uv_row[vi].ustart) + return oog_encode(u, v); + ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em); + if (ui >= uv_row[vi].nus) + return oog_encode(u, v); + + return (uv_row[vi].ncum + ui); +} + +#if !LOGLUV_PUBLIC +static +#endif +int +uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ +{ + int upper, lower; + register int ui, vi; + + if (c < 0 || c >= UV_NDIVS) + return (-1); + lower = 0; /* binary search */ + upper = UV_NVS; + while (upper - lower > 1) { + vi = (lower + upper) >> 1; + ui = c - uv_row[vi].ncum; + if (ui > 0) + lower = vi; + else if (ui < 0) + upper = vi; + else { + lower = vi; + break; + } + } + vi = lower; + ui = c - uv_row[vi].ncum; + *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; + *vp = UV_VSTART + (vi+.5)*UV_SQSIZ; + return (0); +} + +#if !LOGLUV_PUBLIC +static +#endif +void +LogLuv24toXYZ(uint32 p, float XYZ[3]) +{ + int Ce; + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL10toY(p>>14 & 0x3ff); + if (L <= 0.) { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + Ce = p & 0x3fff; + if (uv_decode(&u, &v, Ce) < 0) { + u = U_NEU; v = V_NEU; + } + s = 1./(6.*u - 16.*v + 12.); + x = 9.*u * s; + y = 4.*v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x/y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1.-x-y)/y * L); +} + +#if !LOGLUV_PUBLIC +static +#endif +uint32 +LogLuv24fromXYZ(float XYZ[3], int em) +{ + int Le, Ce; + double u, v, s; + /* encode luminance */ + Le = LogL10fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; + if (!Le || s <= 0.) { + u = U_NEU; + v = V_NEU; + } else { + u = 4.*XYZ[0] / s; + v = 9.*XYZ[1] / s; + } + Ce = uv_encode(u, v, em); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + /* combine encodings */ + return (Le << 14 | Ce); +} + +static void +Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + LogLuv24toXYZ(*luv, xyz); + xyz += 3; + luv++; + } +} + +static void +Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + double u, v; + + *luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314); + if (uv_decode(&u, &v, *luv&0x3fff) < 0) { + u = U_NEU; + v = V_NEU; + } + *luv3++ = (int16)(u * (1L<<15)); + *luv3++ = (int16)(v * (1L<<15)); + luv++; + } +} + +static void +Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + uint8* rgb = (uint8*) op; + + while (n-- > 0) { + float xyz[3]; + + LogLuv24toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void +Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } +} + +static void +Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + int Le, Ce; + + if (luv3[0] <= 0) + Le = 0; + else if (luv3[0] >= (1<<12)+3314) + Le = (1<<10) - 1; + else if (sp->encode_meth == SGILOGENCODE_NODITHER) + Le = (luv3[0]-3314) >> 2; + else + Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth); + + Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15), + sp->encode_meth); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + *luv++ = (uint32)Le << 14 | Ce; + luv3 += 3; + } +} + +#if !LOGLUV_PUBLIC +static +#endif +void +LogLuv32toXYZ(uint32 p, float XYZ[3]) +{ + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL16toY((int)p >> 16); + if (L <= 0.) { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + u = 1./UVSCALE * ((p>>8 & 0xff) + .5); + v = 1./UVSCALE * ((p & 0xff) + .5); + s = 1./(6.*u - 16.*v + 12.); + x = 9.*u * s; + y = 4.*v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x/y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1.-x-y)/y * L); +} + +#if !LOGLUV_PUBLIC +static +#endif +uint32 +LogLuv32fromXYZ(float XYZ[3], int em) +{ + unsigned int Le, ue, ve; + double u, v, s; + /* encode luminance */ + Le = (unsigned int)LogL16fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; + if (!Le || s <= 0.) { + u = U_NEU; + v = V_NEU; + } else { + u = 4.*XYZ[0] / s; + v = 9.*XYZ[1] / s; + } + if (u <= 0.) ue = 0; + else ue = itrunc(UVSCALE*u, em); + if (ue > 255) ue = 255; + if (v <= 0.) ve = 0; + else ve = itrunc(UVSCALE*v, em); + if (ve > 255) ve = 255; + /* combine encodings */ + return (Le << 16 | ue << 8 | ve); +} + +static void +Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + LogLuv32toXYZ(*luv++, xyz); + xyz += 3; + } +} + +static void +Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + double u, v; + + *luv3++ = (int16)(*luv >> 16); + u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5); + v = 1./UVSCALE * ((*luv & 0xff) + .5); + *luv3++ = (int16)(u * (1L<<15)); + *luv3++ = (int16)(v * (1L<<15)); + luv++; + } +} + +static void +Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + uint8* rgb = (uint8*) op; + + while (n-- > 0) { + float xyz[3]; + + LogLuv32toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void +Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } +} + +static void +Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + if (sp->encode_meth == SGILOGENCODE_NODITHER) { + while (n-- > 0) { + *luv++ = (uint32)luv3[0] << 16 | + (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) | + (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff); + luv3 += 3; + } + return; + } + while (n-- > 0) { + *luv++ = (uint32)luv3[0] << 16 | + (itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) | + (itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff); + luv3 += 3; + } +} + +static void +_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n) +{ + (void) sp; (void) op; (void) n; +} + +static int +LogL16GuessDataFmt(TIFFDirectory *td) +{ +#define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f)) + switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) { + case PACK(1, 32, SAMPLEFORMAT_IEEEFP): + return (SGILOGDATAFMT_FLOAT); + case PACK(1, 16, SAMPLEFORMAT_VOID): + case PACK(1, 16, SAMPLEFORMAT_INT): + case PACK(1, 16, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_16BIT); + case PACK(1, 8, SAMPLEFORMAT_VOID): + case PACK(1, 8, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_8BIT); + } +#undef PACK + return (SGILOGDATAFMT_UNKNOWN); +} + +static tmsize_t +multiply_ms(tmsize_t m1, tmsize_t m2) +{ + tmsize_t bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; +} + +static int +LogL16InitState(TIFF* tif) +{ + static const char module[] = "LogL16InitState"; + TIFFDirectory *td = &tif->tif_dir; + LogLuvState* sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGL); + + /* for some reason, we can't do this in TIFFInitLogL16 */ + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogL16GuessDataFmt(td); + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = sizeof (float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = sizeof (int16); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = sizeof (uint8); + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "No support for converting user data format to LogL"); + return (0); + } + if( isTiled(tif) ) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 || + (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); +} + +static int +LogLuvGuessDataFmt(TIFFDirectory *td) +{ + int guess; + + /* + * If the user didn't tell us their datafmt, + * take our best guess from the bitspersample. + */ +#define PACK(a,b) (((a)<<3)|(b)) + switch (PACK(td->td_bitspersample, td->td_sampleformat)) { + case PACK(32, SAMPLEFORMAT_IEEEFP): + guess = SGILOGDATAFMT_FLOAT; + break; + case PACK(32, SAMPLEFORMAT_VOID): + case PACK(32, SAMPLEFORMAT_UINT): + case PACK(32, SAMPLEFORMAT_INT): + guess = SGILOGDATAFMT_RAW; + break; + case PACK(16, SAMPLEFORMAT_VOID): + case PACK(16, SAMPLEFORMAT_INT): + case PACK(16, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_16BIT; + break; + case PACK( 8, SAMPLEFORMAT_VOID): + case PACK( 8, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_8BIT; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; +#undef PACK + } + /* + * Double-check samples per pixel. + */ + switch (td->td_samplesperpixel) { + case 1: + if (guess != SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + case 3: + if (guess == SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; + } + return (guess); +} + +static int +LogLuvInitState(TIFF* tif) +{ + static const char module[] = "LogLuvInitState"; + TIFFDirectory* td = &tif->tif_dir; + LogLuvState* sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGLUV); + + /* for some reason, we can't do this in TIFFInitLogLuv */ + if (td->td_planarconfig != PLANARCONFIG_CONTIG) { + TIFFErrorExt(tif->tif_clientdata, module, + "SGILog compression cannot handle non-contiguous data"); + return (0); + } + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogLuvGuessDataFmt(td); + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = 3*sizeof (float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = 3*sizeof (int16); + break; + case SGILOGDATAFMT_RAW: + sp->pixel_size = sizeof (uint32); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = 3*sizeof (uint8); + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "No support for converting user data format to LogLuv"); + return (0); + } + if( isTiled(tif) ) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 || + (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); +} + +static int +LogLuvFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +static int +LogLuvSetupDecode(TIFF* tif) +{ + static const char module[] = "LogLuvSetupDecode"; + LogLuvState* sp = DecoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + + tif->tif_postdecode = _TIFFNoPostDecode; + switch (td->td_photometric) { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) { + tif->tif_decoderow = LogLuvDecode24; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv24toRGB; + break; + } + } else { + tif->tif_decoderow = LogLuvDecode32; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv32toRGB; + break; + } + } + return (1); + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_decoderow = LogL16Decode; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16toY; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = L16toGry; + break; + } + return (1); + default: + TIFFErrorExt(tif->tif_clientdata, module, + "Inappropriate photometric interpretation %d for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (0); +} + +static int +LogLuvSetupEncode(TIFF* tif) +{ + static const char module[] = "LogLuvSetupEncode"; + LogLuvState* sp = EncoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + + switch (td->td_photometric) { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) { + tif->tif_encoderow = LogLuvEncode24; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } else { + tif->tif_encoderow = LogLuvEncode32; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + break; + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_encoderow = LogL16Encode; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16fromY; + break; + case SGILOGDATAFMT_16BIT: + break; + default: + goto notsupported; + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "Inappropriate photometric interpretation %d for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (1); +notsupported: + TIFFErrorExt(tif->tif_clientdata, module, + "SGILog compression supported only for %s, or raw data", + td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); + return (0); +} + +static void +LogLuvClose(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + + /* + * For consistency, we always want to write out the same + * bitspersample and sampleformat for our TIFF file, + * regardless of the data format being used by the application. + * Since this routine is called after tags have been set but + * before they have been recorded in the file, we reset them here. + */ + td->td_samplesperpixel = + (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; + td->td_bitspersample = 16; + td->td_sampleformat = SAMPLEFORMAT_INT; +} + +static void +LogLuvCleanup(TIFF* tif) +{ + LogLuvState* sp = (LogLuvState *)tif->tif_data; + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->tbuf) + _TIFFfree(sp->tbuf); + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "LogLuvVSetField"; + LogLuvState* sp = DecoderState(tif); + int bps, fmt; + + switch (tag) { + case TIFFTAG_SGILOGDATAFMT: + sp->user_datafmt = (int) va_arg(ap, int); + /* + * Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + bps = 32, fmt = SAMPLEFORMAT_IEEEFP; + break; + case SGILOGDATAFMT_16BIT: + bps = 16, fmt = SAMPLEFORMAT_INT; + break; + case SGILOGDATAFMT_RAW: + bps = 32, fmt = SAMPLEFORMAT_UINT; + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + break; + case SGILOGDATAFMT_8BIT: + bps = 8, fmt = SAMPLEFORMAT_UINT; + break; + default: + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Unknown data format %d for LogLuv compression", + sp->user_datafmt); + return (0); + } + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1; + tif->tif_scanlinesize = TIFFScanlineSize(tif); + return (1); + case TIFFTAG_SGILOGENCODE: + sp->encode_meth = (int) va_arg(ap, int); + if (sp->encode_meth != SGILOGENCODE_NODITHER && + sp->encode_meth != SGILOGENCODE_RANDITHER) { + TIFFErrorExt(tif->tif_clientdata, module, + "Unknown encoding %d for LogLuv compression", + sp->encode_meth); + return (0); + } + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } +} + +static int +LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + LogLuvState *sp = (LogLuvState *)tif->tif_data; + + switch (tag) { + case TIFFTAG_SGILOGDATAFMT: + *va_arg(ap, int*) = sp->user_datafmt; + return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } +} + +static const TIFFField LogLuvFields[] = { + { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, + { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL} +}; + +int +TIFFInitSGILog(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitSGILog"; + LogLuvState* sp; + + assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, LogLuvFields, + TIFFArrayCount(LogLuvFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging SGILog codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState)); + if (tif->tif_data == NULL) + goto bad; + sp = (LogLuvState*) tif->tif_data; + _TIFFmemset((void*)sp, 0, sizeof (*sp)); + sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; + sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? + SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; + sp->tfunc = _logLuvNop; + + /* + * Install codec methods. + * NB: tif_decoderow & tif_encoderow are filled + * in at setup time. + */ + tif->tif_fixuptags = LogLuvFixupTags; + tif->tif_setupdecode = LogLuvSetupDecode; + tif->tif_decodestrip = LogLuvDecodeStrip; + tif->tif_decodetile = LogLuvDecodeTile; + tif->tif_setupencode = LogLuvSetupEncode; + tif->tif_encodestrip = LogLuvEncodeStrip; + tif->tif_encodetile = LogLuvEncodeTile; + tif->tif_close = LogLuvClose; + tif->tif_cleanup = LogLuvCleanup; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ + + return (1); +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "%s: No space for LogLuv state block", tif->tif_name); + return (0); +} +#endif /* LOGLUV_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_lzma.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_lzma.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_lzma.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_lzma.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,495 @@ +/* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen Exp $ */ + +/* + * Copyright (c) 2010, Andrey Kiselev + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LZMA_SUPPORT +/* + * TIFF Library. + * + * LZMA2 Compression Support + * + * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details. + * + * The codec is derived from ZLIB codec (tif_zip.c). + */ + +#include "tif_predict.h" +#include "lzma.h" + +#include + +/* + * State block for each open TIFF file using LZMA2 compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + lzma_stream stream; + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_options_delta opt_delta; /* delta filter options */ + lzma_options_lzma opt_lzma; /* LZMA2 filter options */ + int preset; /* compression level */ + lzma_check check; /* type of the integrity check */ + int state; /* state flags */ +#define LSTATE_INIT_DECODE 0x01 +#define LSTATE_INIT_ENCODE 0x02 + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} LZMAState; + +#define LState(tif) ((LZMAState*) (tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) + +static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static const char * +LZMAStrerror(lzma_ret ret) +{ + switch (ret) { + case LZMA_OK: + return "operation completed successfully"; + case LZMA_STREAM_END: + return "end of stream was reached"; + case LZMA_NO_CHECK: + return "input stream has no integrity check"; + case LZMA_UNSUPPORTED_CHECK: + return "cannot calculate the integrity check"; + case LZMA_GET_CHECK: + return "integrity check type is now available"; + case LZMA_MEM_ERROR: + return "cannot allocate memory"; + case LZMA_MEMLIMIT_ERROR: + return "memory usage limit was reached"; + case LZMA_FORMAT_ERROR: + return "file format not recognized"; + case LZMA_OPTIONS_ERROR: + return "invalid or unsupported options"; + case LZMA_DATA_ERROR: + return "data is corrupt"; + case LZMA_BUF_ERROR: + return "no progress is possible (stream is truncated or corrupt)"; + case LZMA_PROG_ERROR: + return "programming error"; + default: + return "unindentified liblzma error"; + } +} + +static int +LZMAFixupTags(TIFF* tif) +{ + (void) tif; + return 1; +} + +static int +LZMASetupDecode(TIFF* tif) +{ + LZMAState* sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; +} + +/* + * Setup state for decoding a strip. + */ +static int +LZMAPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "LZMAPreDecode"; + LZMAState* sp = DecoderState(tif); + lzma_ret ret; + + (void) s; + assert(sp != NULL); + + if( (sp->state & LSTATE_INIT_DECODE) == 0 ) + tif->tif_setupdecode(tif); + + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = (size_t) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + /* + * Disable memory limit when decoding. UINT64_MAX is a flag to disable + * the limit, we are passing (uint64_t)-1 which should be the same. + */ + ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(ret)); + return 0; + } + return 1; +} + +static int +LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "LZMADecode"; + LZMAState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (size_t) tif->tif_rawcc; + + sp->stream.next_out = op; + sp->stream.avail_out = (size_t) occ; + if ((tmsize_t)sp->stream.avail_out != occ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + do { + /* + * Save the current stream state to properly recover from the + * decoding errors later. + */ + const uint8_t *next_in = sp->stream.next_in; + size_t avail_in = sp->stream.avail_in; + + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret == LZMA_STREAM_END) + break; + if (ret == LZMA_MEMLIMIT_ERROR) { + lzma_ret r = lzma_stream_decoder(&sp->stream, + lzma_memusage(&sp->stream), 0); + if (r != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(r)); + break; + } + sp->stream.next_in = next_in; + sp->stream.avail_in = avail_in; + continue; + } + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, LZMAStrerror(ret)); + break; + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %lu (short %lu bytes)", + (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out); + return 0; + } + + tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */ + tif->tif_rawcc = sp->stream.avail_in; + + return 1; +} + +static int +LZMASetupEncode(TIFF* tif) +{ + LZMAState* sp = EncoderState(tif); + + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_ENCODE; + return 1; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +LZMAPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "LZMAPreEncode"; + LZMAState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + if( sp->state != LSTATE_INIT_ENCODE ) + tif->tif_setupencode(tif); + + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK); +} + +/* + * Encode a chunk of pixels. + */ +static int +LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "LZMAEncode"; + LZMAState *sp = EncoderState(tif); + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + (void) s; + sp->stream.next_in = bp; + sp->stream.avail_in = (size_t) cc; + if ((tmsize_t)sp->stream.avail_in != cc) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + do { + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Encoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, LZMAStrerror(ret)); + return 0; + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */ + } + } while (sp->stream.avail_in > 0); + return 1; +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +LZMAPostEncode(TIFF* tif) +{ + static const char module[] = "LZMAPostEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; + + sp->stream.avail_in = 0; + do { + ret = lzma_code(&sp->stream, LZMA_FINISH); + switch (ret) { + case LZMA_STREAM_END: + case LZMA_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s", + LZMAStrerror(ret)); + return 0; + } + } while (ret != LZMA_STREAM_END); + return 1; +} + +static void +LZMACleanup(TIFF* tif) +{ + LZMAState* sp = LState(tif); + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->state) { + lzma_end(&sp->stream); + sp->state = 0; + } + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +LZMAVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "LZMAVSetField"; + LZMAState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_LZMAPRESET: + sp->preset = (int) va_arg(ap, int); + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + if (sp->state & LSTATE_INIT_ENCODE) { + lzma_ret ret = lzma_stream_encoder(&sp->stream, + sp->filters, + sp->check); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma error: %s", + LZMAStrerror(ret)); + } + } + return 1; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +LZMAVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + LZMAState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_LZMAPRESET: + *va_arg(ap, int*) = sp->preset; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +static const TIFFField lzmaFields[] = { + { TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL }, +}; + +int +TIFFInitLZMA(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitLZMA"; + LZMAState* sp; + lzma_stream tmp_stream = LZMA_STREAM_INIT; + + assert( scheme == COMPRESSION_LZMA ); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging LZMA2 codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ + sp->check = LZMA_CHECK_NONE; + sp->state = 0; + + /* Data filters. So far we are using delta and LZMA2 filters only. */ + sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; + /* + * The sample size in bytes seems to be reasonable distance for delta + * filter. + */ + sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? + 1 : tif->tif_dir.td_bitspersample / 8; + sp->filters[0].id = LZMA_FILTER_DELTA; + sp->filters[0].options = &sp->opt_delta; + + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + sp->filters[1].id = LZMA_FILTER_LZMA2; + sp->filters[1].options = &sp->opt_lzma; + + sp->filters[2].id = LZMA_VLI_UNKNOWN; + sp->filters[2].options = NULL; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZMAFixupTags; + tif->tif_setupdecode = LZMASetupDecode; + tif->tif_predecode = LZMAPreDecode; + tif->tif_decoderow = LZMADecode; + tif->tif_decodestrip = LZMADecode; + tif->tif_decodetile = LZMADecode; + tif->tif_setupencode = LZMASetupEncode; + tif->tif_preencode = LZMAPreEncode; + tif->tif_postencode = LZMAPostEncode; + tif->tif_encoderow = LZMAEncode; + tif->tif_encodestrip = LZMAEncode; + tif->tif_encodetile = LZMAEncode; + tif->tif_cleanup = LZMACleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return 1; +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZMA2 state block"); + return 0; +} +#endif /* LZMA_SUPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_lzw.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_lzw.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_lzw.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_lzw.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1167 @@ +/* $Id: tif_lzw.c,v 1.45 2011-04-02 20:54:09 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LZW_SUPPORT +/* + * TIFF Library. + * Rev 5.0 Lempel-Ziv & Welch Compression Support + * + * This code is derived from the compress program whose code is + * derived from software contributed to Berkeley by James A. Woods, + * derived from original work by Spencer Thomas and Joseph Orost. + * + * The original Berkeley copyright notice appears below in its entirety. + */ +#include "tif_predict.h" + +#include + +/* + * NB: The 5.0 spec describes a different algorithm than Aldus + * implements. Specifically, Aldus does code length transitions + * one code earlier than should be done (for real LZW). + * Earlier versions of this library implemented the correct + * LZW algorithm, but emitted codes in a bit order opposite + * to the TIFF spec. Thus, to maintain compatibility w/ Aldus + * we interpret MSB-LSB ordered codes to be images written w/ + * old versions of this library, but otherwise adhere to the + * Aldus "off by one" algorithm. + * + * Future revisions to the TIFF spec are expected to "clarify this issue". + */ +#define LZW_COMPAT /* include backwards compatibility code */ +/* + * Each strip of data is supposed to be terminated by a CODE_EOI. + * If the following #define is included, the decoder will also + * check for end-of-strip w/o seeing this code. This makes the + * library more robust, but also slower. + */ +#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ + +#define MAXCODE(n) ((1L<<(n))-1) +/* + * The TIFF spec specifies that encoded bit + * strings range from 9 to 12 bits. + */ +#define BITS_MIN 9 /* start with 9 bits */ +#define BITS_MAX 12 /* max of 12 bit strings */ +/* predefined codes */ +#define CODE_CLEAR 256 /* code to clear string table */ +#define CODE_EOI 257 /* end-of-information code */ +#define CODE_FIRST 258 /* first free code entry */ +#define CODE_MAX MAXCODE(BITS_MAX) +#define HSIZE 9001L /* 91% occupancy */ +#define HSHIFT (13-8) +#ifdef LZW_COMPAT +/* NB: +1024 is for compatibility with old files */ +#define CSIZE (MAXCODE(BITS_MAX)+1024L) +#else +#define CSIZE (MAXCODE(BITS_MAX)+1L) +#endif + +/* + * State block for each open TIFF file using LZW + * compression/decompression. Note that the predictor + * state block must be first in this data structure. + */ +typedef struct { + TIFFPredictorState predict; /* predictor super class */ + + unsigned short nbits; /* # of bits/code */ + unsigned short maxcode; /* maximum code for lzw_nbits */ + unsigned short free_ent; /* next free entry in hash table */ + long nextdata; /* next bits of i/o */ + long nextbits; /* # of valid bits in lzw_nextdata */ + + int rw_mode; /* preserve rw_mode from init */ +} LZWBaseState; + +#define lzw_nbits base.nbits +#define lzw_maxcode base.maxcode +#define lzw_free_ent base.free_ent +#define lzw_nextdata base.nextdata +#define lzw_nextbits base.nextbits + +/* + * Encoding-specific state. + */ +typedef uint16 hcode_t; /* codes fit in 16 bits */ +typedef struct { + long hash; + hcode_t code; +} hash_t; + +/* + * Decoding-specific state. + */ +typedef struct code_ent { + struct code_ent *next; + unsigned short length; /* string len, including this token */ + unsigned char value; /* data value */ + unsigned char firstchar; /* first token of string */ +} code_t; + +typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16); + +typedef struct { + LZWBaseState base; + + /* Decoding specific data */ + long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ + long dec_restart; /* restart count */ +#ifdef LZW_CHECKEOS + uint64 dec_bitsleft; /* available bits in raw data */ +#endif + decodeFunc dec_decode; /* regular or backwards compatible */ + code_t* dec_codep; /* current recognized code */ + code_t* dec_oldcodep; /* previously recognized code */ + code_t* dec_free_entp; /* next free entry */ + code_t* dec_maxcodep; /* max available entry */ + code_t* dec_codetab; /* kept separate for small machines */ + + /* Encoding specific data */ + int enc_oldcode; /* last code encountered */ + long enc_checkpoint; /* point at which to clear table */ +#define CHECK_GAP 10000 /* enc_ratio check interval */ + long enc_ratio; /* current compression ratio */ + long enc_incount; /* (input) data bytes encoded */ + long enc_outcount; /* encoded (output) bytes */ + uint8* enc_rawlimit; /* bound on tif_rawdata buffer */ + hash_t* enc_hashtab; /* kept separate for small machines */ +} LZWCodecState; + +#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) +#define DecoderState(tif) ((LZWCodecState*) LZWState(tif)) +#define EncoderState(tif) ((LZWCodecState*) LZWState(tif)) + +static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +#ifdef LZW_COMPAT +static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +#endif +static void cl_hash(LZWCodecState*); + +/* + * LZW Decoder. + */ + +#ifdef LZW_CHECKEOS +/* + * This check shouldn't be necessary because each + * strip is suppose to be terminated with CODE_EOI. + */ +#define NextCode(_tif, _sp, _bp, _code, _get) { \ + if ((_sp)->dec_bitsleft < (uint64)nbits) { \ + TIFFWarningExt(_tif->tif_clientdata, module, \ + "LZWDecode: Strip %d not terminated with EOI code", \ + _tif->tif_curstrip); \ + _code = CODE_EOI; \ + } else { \ + _get(_sp,_bp,_code); \ + (_sp)->dec_bitsleft -= nbits; \ + } \ +} +#else +#define NextCode(tif, sp, bp, code, get) get(sp, bp, code) +#endif + +static int +LZWFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +static int +LZWSetupDecode(TIFF* tif) +{ + static const char module[] = "LZWSetupDecode"; + LZWCodecState* sp = DecoderState(tif); + int code; + + if( sp == NULL ) + { + /* + * Allocate state block so tag methods have storage to record + * values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + { + TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block"); + return (0); + } + + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + + sp = DecoderState(tif); + } + + assert(sp != NULL); + + if (sp->dec_codetab == NULL) { + sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t)); + if (sp->dec_codetab == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZW code table"); + return (0); + } + /* + * Pre-load the table. + */ + code = 255; + do { + sp->dec_codetab[code].value = code; + sp->dec_codetab[code].firstchar = code; + sp->dec_codetab[code].length = 1; + sp->dec_codetab[code].next = NULL; + } while (code--); + /* + * Zero-out the unused entries + */ + _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0, + (CODE_FIRST - CODE_CLEAR) * sizeof (code_t)); + } + return (1); +} + +/* + * Setup state for decoding a strip. + */ +static int +LZWPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "LZWPreDecode"; + LZWCodecState *sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + if( sp->dec_codetab == NULL ) + { + tif->tif_setupdecode( tif ); + } + + /* + * Check for old bit-reversed codes. + */ + if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { +#ifdef LZW_COMPAT + if (!sp->dec_decode) { + TIFFWarningExt(tif->tif_clientdata, module, + "Old-style LZW codes, convert file"); + /* + * Override default decoding methods with + * ones that deal with the old coding. + * Otherwise the predictor versions set + * above will call the compatibility routines + * through the dec_decode method. + */ + tif->tif_decoderow = LZWDecodeCompat; + tif->tif_decodestrip = LZWDecodeCompat; + tif->tif_decodetile = LZWDecodeCompat; + /* + * If doing horizontal differencing, must + * re-setup the predictor logic since we + * switched the basic decoder methods... + */ + (*tif->tif_setupdecode)(tif); + sp->dec_decode = LZWDecodeCompat; + } + sp->lzw_maxcode = MAXCODE(BITS_MIN); +#else /* !LZW_COMPAT */ + if (!sp->dec_decode) { + TIFFErrorExt(tif->tif_clientdata, module, + "Old-style LZW codes not supported"); + sp->dec_decode = LZWDecode; + } + return (0); +#endif/* !LZW_COMPAT */ + } else { + sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; + sp->dec_decode = LZWDecode; + } + sp->lzw_nbits = BITS_MIN; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + + sp->dec_restart = 0; + sp->dec_nbitsmask = MAXCODE(BITS_MIN); +#ifdef LZW_CHECKEOS + sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3; +#endif + sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; + /* + * Zero entries that are not yet filled in. We do + * this to guard against bogus input data that causes + * us to index into undefined entries. If you can + * come up with a way to safely bounds-check input codes + * while decoding then you can remove this operation. + */ + _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); + sp->dec_oldcodep = &sp->dec_codetab[-1]; + sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; + return (1); +} + +/* + * Decode a "hunk of data". + */ +#define GetNextCode(sp, bp, code) { \ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + if (nextbits < nbits) { \ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + } \ + code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \ + nextbits -= nbits; \ +} + +static void +codeLoop(TIFF* tif, const char* module) +{ + TIFFErrorExt(tif->tif_clientdata, module, + "Bogus encoding, loop in the code table; scanline %d", + tif->tif_row); +} + +static int +LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +{ + static const char module[] = "LZWDecode"; + LZWCodecState *sp = DecoderState(tif); + char *op = (char*) op0; + long occ = (long) occ0; + char *tp; + unsigned char *bp; + hcode_t code; + int len; + long nbits, nextbits, nextdata, nbitsmask; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + + (void) s; + assert(sp != NULL); + assert(sp->dec_codetab != NULL); + + /* + Fail if value does not fit in long. + */ + if ((tmsize_t) occ != occ0) + return (0); + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) { + long residue; + + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do { + codep = codep->next; + } while (--residue > occ && codep); + if (codep) { + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); + } + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue, occ -= residue; + tp = op; + do { + int t; + --tp; + t = codep->value; + codep = codep->next; + *tp = t; + } while (--residue && codep); + sp->dec_restart = 0; + } + + bp = (unsigned char *)tif->tif_rawcp; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + + while (occ > 0) { + NextCode(tif, sp, bp, code, GetNextCode); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof (code_t)); + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask-1; + NextCode(tif, sp, bp, code, GetNextCode); + if (code == CODE_EOI) + break; + if (code >= CODE_CLEAR) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "LZWDecode: Corrupted LZW table at scanline %d", + tif->tif_row); + return (0); + } + *op++ = (char)code, occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; + + /* + * Add the new entry to the code table. + */ + if (free_entp < &sp->dec_codetab[0] || + free_entp >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", + tif->tif_row); + return (0); + } + + free_entp->next = oldcodep; + if (free_entp->next < &sp->dec_codetab[0] || + free_entp->next >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", + tif->tif_row); + return (0); + } + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length+1; + free_entp->value = (codep < free_entp) ? + codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask-1; + } + oldcodep = codep; + if (code >= 256) { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if(codep->length == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong length of decoded string: " + "data probably corrupted at scanline %d", + tif->tif_row); + return (0); + } + if (codep->length > occ) { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { + codep = codep->next; + } while (codep && codep->length > occ); + if (codep) { + sp->dec_restart = (long)occ; + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); + if (codep) + codeLoop(tif, module); + } + break; + } + len = codep->length; + tp = op + len; + do { + int t; + --tp; + t = codep->value; + codep = codep->next; + *tp = t; + } while (codep && tp > op); + if (codep) { + codeLoop(tif, module); + break; + } + assert(occ >= len); + op += len, occ -= len; + } else + *op++ = (char)code, occ--; + } + + tif->tif_rawcp = (uint8*) bp; + sp->lzw_nbits = (unsigned short) nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %I64d bytes)", + tif->tif_row, (unsigned __int64) occ); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %llu bytes)", + tif->tif_row, (unsigned long long) occ); +#endif + return (0); + } + return (1); +} + +#ifdef LZW_COMPAT +/* + * Decode a "hunk of data" for old images. + */ +#define GetNextCodeCompat(sp, bp, code) { \ + nextdata |= (unsigned long) *(bp)++ << nextbits; \ + nextbits += 8; \ + if (nextbits < nbits) { \ + nextdata |= (unsigned long) *(bp)++ << nextbits;\ + nextbits += 8; \ + } \ + code = (hcode_t)(nextdata & nbitsmask); \ + nextdata >>= nbits; \ + nextbits -= nbits; \ +} + +static int +LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +{ + static const char module[] = "LZWDecodeCompat"; + LZWCodecState *sp = DecoderState(tif); + char *op = (char*) op0; + long occ = (long) occ0; + char *tp; + unsigned char *bp; + int code, nbits; + long nextbits, nextdata, nbitsmask; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + + (void) s; + assert(sp != NULL); + + /* + Fail if value does not fit in long. + */ + if ((tmsize_t) occ != occ0) + return (0); + + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) { + long residue; + + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do { + codep = codep->next; + } while (--residue > occ); + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue, occ -= residue; + tp = op; + do { + *--tp = codep->value; + codep = codep->next; + } while (--residue); + sp->dec_restart = 0; + } + + bp = (unsigned char *)tif->tif_rawcp; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + + while (occ > 0) { + NextCode(tif, sp, bp, code, GetNextCodeCompat); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof (code_t)); + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask; + NextCode(tif, sp, bp, code, GetNextCodeCompat); + if (code == CODE_EOI) + break; + if (code >= CODE_CLEAR) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "LZWDecode: Corrupted LZW table at scanline %d", + tif->tif_row); + return (0); + } + *op++ = code, occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; + + /* + * Add the new entry to the code table. + */ + if (free_entp < &sp->dec_codetab[0] || + free_entp >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", tif->tif_row); + return (0); + } + + free_entp->next = oldcodep; + if (free_entp->next < &sp->dec_codetab[0] || + free_entp->next >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", tif->tif_row); + return (0); + } + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length+1; + free_entp->value = (codep < free_entp) ? + codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask; + } + oldcodep = codep; + if (code >= 256) { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if(codep->length == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong length of decoded " + "string: data probably corrupted at scanline %d", + tif->tif_row); + return (0); + } + if (codep->length > occ) { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { + codep = codep->next; + } while (codep->length > occ); + sp->dec_restart = occ; + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + break; + } + assert(occ >= codep->length); + op += codep->length, occ -= codep->length; + tp = op; + do { + *--tp = codep->value; + } while( (codep = codep->next) != NULL ); + } else + *op++ = code, occ--; + } + + tif->tif_rawcp = (uint8*) bp; + sp->lzw_nbits = nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %I64d bytes)", + tif->tif_row, (unsigned __int64) occ); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %llu bytes)", + tif->tif_row, (unsigned long long) occ); +#endif + return (0); + } + return (1); +} +#endif /* LZW_COMPAT */ + +/* + * LZW Encoding. + */ + +static int +LZWSetupEncode(TIFF* tif) +{ + static const char module[] = "LZWSetupEncode"; + LZWCodecState* sp = EncoderState(tif); + + assert(sp != NULL); + sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t)); + if (sp->enc_hashtab == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZW hash table"); + return (0); + } + return (1); +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +LZWPreEncode(TIFF* tif, uint16 s) +{ + LZWCodecState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + + if( sp->enc_hashtab == NULL ) + { + tif->tif_setupencode( tif ); + } + + sp->lzw_nbits = BITS_MIN; + sp->lzw_maxcode = MAXCODE(BITS_MIN); + sp->lzw_free_ent = CODE_FIRST; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + sp->enc_checkpoint = CHECK_GAP; + sp->enc_ratio = 0; + sp->enc_incount = 0; + sp->enc_outcount = 0; + /* + * The 4 here insures there is space for 2 max-sized + * codes in LZWEncode and LZWPostDecode. + */ + sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; + cl_hash(sp); /* clear hash table */ + sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */ + return (1); +} + +#define CALCRATIO(sp, rat) { \ + if (incount > 0x007fffff) { /* NB: shift will overflow */\ + rat = outcount >> 8; \ + rat = (rat == 0 ? 0x7fffffff : incount/rat); \ + } else \ + rat = (incount<<8) / outcount; \ +} +#define PutNextCode(op, c) { \ + nextdata = (nextdata << nbits) | c; \ + nextbits += nbits; \ + *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ + nextbits -= 8; \ + if (nextbits >= 8) { \ + *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ + nextbits -= 8; \ + } \ + outcount += nbits; \ +} + +/* + * Encode a chunk of pixels. + * + * Uses an open addressing double hashing (no chaining) on the + * prefix code/next character combination. We do a variant of + * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's + * relatively-prime secondary probe. Here, the modular division + * first probe is gives way to a faster exclusive-or manipulation. + * Also do block compression with an adaptive reset, whereby the + * code table is cleared when the compression ratio decreases, + * but after the table fills. The variable-length output codes + * are re-sized at this point, and a CODE_CLEAR is generated + * for the decoder. + */ +static int +LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + register LZWCodecState *sp = EncoderState(tif); + register long fcode; + register hash_t *hp; + register int h, c; + hcode_t ent; + long disp; + long incount, outcount, checkpoint; + long nextdata, nextbits; + int free_ent, maxcode, nbits; + uint8* op; + uint8* limit; + + (void) s; + if (sp == NULL) + return (0); + + assert(sp->enc_hashtab != NULL); + + /* + * Load local state. + */ + incount = sp->enc_incount; + outcount = sp->enc_outcount; + checkpoint = sp->enc_checkpoint; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + free_ent = sp->lzw_free_ent; + maxcode = sp->lzw_maxcode; + nbits = sp->lzw_nbits; + op = tif->tif_rawcp; + limit = sp->enc_rawlimit; + ent = sp->enc_oldcode; + + if (ent == (hcode_t) -1 && cc > 0) { + /* + * NB: This is safe because it can only happen + * at the start of a strip where we know there + * is space in the data buffer. + */ + PutNextCode(op, CODE_CLEAR); + ent = *bp++; cc--; incount++; + } + while (cc > 0) { + c = *bp++; cc--; incount++; + fcode = ((long)c << BITS_MAX) + ent; + h = (c << HSHIFT) ^ ent; /* xor hashing */ +#ifdef _WINDOWS + /* + * Check hash index for an overflow. + */ + if (h >= HSIZE) + h -= HSIZE; +#endif + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) { + ent = hp->code; + continue; + } + if (hp->hash >= 0) { + /* + * Primary hash failed, check secondary hash. + */ + disp = HSIZE - h; + if (h == 0) + disp = 1; + do { + /* + * Avoid pointer arithmetic 'cuz of + * wraparound problems with segments. + */ + if ((h -= disp) < 0) + h += HSIZE; + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) { + ent = hp->code; + goto hit; + } + } while (hp->hash >= 0); + } + /* + * New entry, emit code and add to table. + */ + /* + * Verify there is space in the buffer for the code + * and any potential Clear code that might be emitted + * below. The value of limit is setup so that there + * are at least 4 bytes free--room for 2 codes. + */ + if (op > limit) { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + TIFFFlushData1(tif); + op = tif->tif_rawdata; + } + PutNextCode(op, ent); + ent = c; + hp->code = free_ent++; + hp->hash = fcode; + if (free_ent == CODE_MAX-1) { + /* table is full, emit clear code and reset */ + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } else { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > maxcode) { + nbits++; + assert(nbits <= BITS_MAX); + maxcode = (int) MAXCODE(nbits); + } else if (incount >= checkpoint) { + long rat; + /* + * Check compression ratio and, if things seem + * to be slipping, clear the hash table and + * reset state. The compression ratio is a + * 24+8-bit fractional number. + */ + checkpoint = incount+CHECK_GAP; + CALCRATIO(sp, rat); + if (rat <= sp->enc_ratio) { + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } else + sp->enc_ratio = rat; + } + } + hit: + ; + } + + /* + * Restore global state. + */ + sp->enc_incount = incount; + sp->enc_outcount = outcount; + sp->enc_checkpoint = checkpoint; + sp->enc_oldcode = ent; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->lzw_free_ent = free_ent; + sp->lzw_maxcode = maxcode; + sp->lzw_nbits = nbits; + tif->tif_rawcp = op; + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +LZWPostEncode(TIFF* tif) +{ + register LZWCodecState *sp = EncoderState(tif); + uint8* op = tif->tif_rawcp; + long nextbits = sp->lzw_nextbits; + long nextdata = sp->lzw_nextdata; + long outcount = sp->enc_outcount; + int nbits = sp->lzw_nbits; + + if (op > sp->enc_rawlimit) { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + TIFFFlushData1(tif); + op = tif->tif_rawdata; + } + if (sp->enc_oldcode != (hcode_t) -1) { + PutNextCode(op, sp->enc_oldcode); + sp->enc_oldcode = (hcode_t) -1; + } + PutNextCode(op, CODE_EOI); + if (nextbits > 0) + *op++ = (unsigned char)(nextdata << (8-nextbits)); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + return (1); +} + +/* + * Reset encoding hash table. + */ +static void +cl_hash(LZWCodecState* sp) +{ + register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; + register long i = HSIZE-8; + + do { + i -= 8; + hp[-7].hash = -1; + hp[-6].hash = -1; + hp[-5].hash = -1; + hp[-4].hash = -1; + hp[-3].hash = -1; + hp[-2].hash = -1; + hp[-1].hash = -1; + hp[ 0].hash = -1; + hp -= 8; + } while (i >= 0); + for (i += 8; i > 0; i--, hp--) + hp->hash = -1; +} + +static void +LZWCleanup(TIFF* tif) +{ + (void)TIFFPredictorCleanup(tif); + + assert(tif->tif_data != 0); + + if (DecoderState(tif)->dec_codetab) + _TIFFfree(DecoderState(tif)->dec_codetab); + + if (EncoderState(tif)->enc_hashtab) + _TIFFfree(EncoderState(tif)->enc_hashtab); + + _TIFFfree(tif->tif_data); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +int +TIFFInitLZW(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitLZW"; + assert(scheme == COMPRESSION_LZW); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState)); + if (tif->tif_data == NULL) + goto bad; + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + EncoderState(tif)->enc_hashtab = NULL; + LZWState(tif)->rw_mode = tif->tif_mode; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZWFixupTags; + tif->tif_setupdecode = LZWSetupDecode; + tif->tif_predecode = LZWPreDecode; + tif->tif_decoderow = LZWDecode; + tif->tif_decodestrip = LZWDecode; + tif->tif_decodetile = LZWDecode; + tif->tif_setupencode = LZWSetupEncode; + tif->tif_preencode = LZWPreEncode; + tif->tif_postencode = LZWPostEncode; + tif->tif_encoderow = LZWEncode; + tif->tif_encodestrip = LZWEncode; + tif->tif_encodetile = LZWEncode; + tif->tif_cleanup = LZWCleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return (1); +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZW state block"); + return (0); +} + +/* + * Copyright (c) 1985, 1986 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James A. Woods, derived from original work by Spencer Thomas + * and Joseph Orost. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#endif /* LZW_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_next.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_next.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_next.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_next.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,160 @@ +/* $Id: tif_next.c,v 1.13 2010-03-10 18:56:48 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef NEXT_SUPPORT +/* + * TIFF Library. + * + * NeXT 2-bit Grey Scale Compression Algorithm Support + */ + +#define SETPIXEL(op, v) { \ + switch (npixels++ & 3) { \ + case 0: op[0] = (unsigned char) ((v) << 6); break; \ + case 1: op[0] |= (v) << 4; break; \ + case 2: op[0] |= (v) << 2; break; \ + case 3: *op++ |= (v); break; \ + } \ +} + +#define LITERALROW 0x00 +#define LITERALSPAN 0x40 +#define WHITE ((1<<2)-1) + +static int +NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + static const char module[] = "NeXTDecode"; + unsigned char *bp, *op; + tmsize_t cc; + uint8* row; + tmsize_t scanline, n; + + (void) s; + /* + * Each scanline is assumed to start off as all + * white (we assume a PhotometricInterpretation + * of ``min-is-black''). + */ + for (op = (unsigned char*) buf, cc = occ; cc-- > 0;) + *op++ = 0xff; + + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + scanline = tif->tif_scanlinesize; + if (occ % scanline) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (0); + } + for (row = buf; occ > 0; occ -= scanline, row += scanline) { + n = *bp++, cc--; + switch (n) { + case LITERALROW: + /* + * The entire scanline is given as literal values. + */ + if (cc < scanline) + goto bad; + _TIFFmemcpy(row, bp, scanline); + bp += scanline; + cc -= scanline; + break; + case LITERALSPAN: { + tmsize_t off; + /* + * The scanline has a literal span that begins at some + * offset. + */ + off = (bp[0] * 256) + bp[1]; + n = (bp[2] * 256) + bp[3]; + if (cc < 4+n || off+n > scanline) + goto bad; + _TIFFmemcpy(row+off, bp+4, n); + bp += 4+n; + cc -= 4+n; + break; + } + default: { + uint32 npixels = 0, grey; + uint32 imagewidth = tif->tif_dir.td_imagewidth; + + /* + * The scanline is composed of a sequence of constant + * color ``runs''. We shift into ``run mode'' and + * interpret bytes as codes of the form + * until we've filled the scanline. + */ + op = row; + for (;;) { + grey = (uint32)((n>>6) & 0x3); + n &= 0x3f; + /* + * Ensure the run does not exceed the scanline + * bounds, potentially resulting in a security + * issue. + */ + while (n-- > 0 && npixels < imagewidth) + SETPIXEL(op, grey); + if (npixels >= imagewidth) + break; + if (cc == 0) + goto bad; + n = *bp++, cc--; + } + break; + } + } + } + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + return (1); +bad: + TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld", + (long) tif->tif_row); + return (0); +} + +int +TIFFInitNeXT(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = NeXTDecode; + tif->tif_decodestrip = NeXTDecode; + tif->tif_decodetile = NeXTDecode; + return (1); +} +#endif /* NEXT_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_ojpeg.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_ojpeg.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_ojpeg.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_ojpeg.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2496 @@ +/* $Id: tif_ojpeg.c,v 1.56 2012-05-24 03:15:18 fwarmerdam Exp $ */ + +/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0 + specification is now totally obsolete and deprecated for new applications and + images. This file was was created solely in order to read unconverted images + still present on some users' computer systems. It will never be extended + to write such files. Writing new-style JPEG compressed TIFFs is implemented + in tif_jpeg.c. + + The code is carefully crafted to robustly read all gathered JPEG-in-TIFF + testfiles, and anticipate as much as possible all other... But still, it may + fail on some. If you encounter problems, please report them on the TIFF + mailing list and/or to Joris Van Damme . + + Please read the file called "TIFF Technical Note #2" if you need to be + convinced this compression scheme is bad and breaks TIFF. That document + is linked to from the LibTiff site + and from AWare Systems' TIFF section + . It is also absorbed + in Adobe's specification supplements, marked "draft" up to this day, but + supported by the TIFF community. + + This file interfaces with Release 6B of the JPEG Library written by the + Independent JPEG Group. Previous versions of this file required a hack inside + the LibJpeg library. This version no longer requires that. Remember to + remove the hack if you update from the old version. + + Copyright (c) Joris Van Damme + Copyright (c) AWare Systems + + The licence agreement for this file is the same as the rest of the LibTiff + library. + + IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR + ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. + + Joris Van Damme and/or AWare Systems may be available for custom + developement. If you like what you see, and need anything similar or related, + contact . +*/ + +/* What is what, and what is not? + + This decoder starts with an input stream, that is essentially the JpegInterchangeFormat + stream, if any, followed by the strile data, if any. This stream is read in + OJPEGReadByte and related functions. + + It analyzes the start of this stream, until it encounters non-marker data, i.e. + compressed image data. Some of the header markers it sees have no actual content, + like the SOI marker, and APP/COM markers that really shouldn't even be there. Some + other markers do have content, and the valuable bits and pieces of information + in these markers are saved, checking all to verify that the stream is more or + less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx + functions. + + Some OJPEG imagery contains no valid JPEG header markers. This situation is picked + up on if we've seen no SOF marker when we're at the start of the compressed image + data. In this case, the tables are read from JpegXxxTables tags, and the other + bits and pieces of information is initialized to its most basic value. This is + implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. + + When this is complete, a good and valid JPEG header can be assembled, and this is + passed through to LibJpeg. When that's done, the remainder of the input stream, i.e. + the compressed image data, can be passed through unchanged. This is done in + OJPEGWriteStream functions. + + LibTiff rightly expects to know the subsampling values before decompression. Just like + in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling + tag is notoriously unreliable. To correct these tag values with the ones inside + the JPEG stream, the first part of the input stream is pre-scanned in + OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings + or errors, up to the point where either these values are read, or it's clear they + aren't there. This means that some of the data is read twice, but we feel speed + in correcting these values is important enough to warrant this sacrifice. Allthough + there is currently no define or other configuration mechanism to disable this behaviour, + the actual header scanning is build to robustly respond with error report if it + should encounter an uncorrected mismatch of subsampling values. See + OJPEGReadHeaderInfoSecStreamSof. + + The restart interval and restart markers are the most tricky part... The restart + interval can be specified in a tag. It can also be set inside the input JPEG stream. + It can be used inside the input JPEG stream. If reading from strile data, we've + consistenly discovered the need to insert restart markers in between the different + striles, as is also probably the most likely interpretation of the original TIFF 6.0 + specification. With all this setting of interval, and actual use of markers that is not + predictable at the time of valid JPEG header assembly, the restart thing may turn + out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors + succeed in reading back what they write, which may be the reason why we've been able + to discover ways that seem to work. + + Some special provision is made for planarconfig separate OJPEG files. These seem + to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS, + and plane. This may or may not be a valid JPEG configuration, we don't know and don't + care. We want LibTiff to be able to access the planes individually, without huge + buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this + case, that allow us to pass a single plane such that LibJpeg sees a valid + single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent + planes, is done inside OJPEGReadSecondarySos. + + The benefit of the scheme is... that it works, basically. We know of no other that + does. It works without checking software tag, or otherwise going about things in an + OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases + with and without JpegInterchangeFormat, with and without striles, with part of + the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving + and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out + of the data. + + Another nice side-effect is that a complete JPEG single valid stream is build if + planarconfig is not separate (vast majority). We may one day use that to build + converters to JPEG, and/or to new-style JPEG compression inside TIFF. + + A dissadvantage is the lack of random access to the individual striles. This is the + reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode. + Applications would do well accessing all striles in order, as this will result in + a single sequential scan of the input stream, and no restarting of LibJpeg decoding + session. +*/ + +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN + +#include "tiffiop.h" +#ifdef OJPEG_SUPPORT + +/* Configuration defines here are: + * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments, + * like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to + * libjpeg, with longjump stuff, are encapsulated in dedicated functions. When + * JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external + * to this unit, and can be defined elsewhere to use stuff other then longjump. + * The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators + * here, internally, with normal longjump. + * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is + * conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp + * in place of plain setjmp. These macros will make it easier. It is useless + * to fiddle with these if you define JPEG_ENCAP_EXTERNAL. + * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee + * instant processing, optimal streaming and optimal use of processor cache, but also big + * enough so as to not result in significant call overhead. It should be at least a few + * bytes to accomodate some structures (this is verified in asserts), but it would not be + * sensible to make it this small anyway, and it should be at most 64K since it is indexed + * with uint16. We recommend 2K. + * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has + * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly. + */ + +/* define LIBJPEG_ENCAP_EXTERNAL */ +#define SETJMP(jbuf) setjmp(jbuf) +#define LONGJMP(jbuf,code) longjmp(jbuf,code) +#define JMP_BUF jmp_buf +#define OJPEG_BUFFER 2048 +/* define EGYPTIANWALK */ + +#define JPEG_MARKER_SOF0 0xC0 +#define JPEG_MARKER_SOF1 0xC1 +#define JPEG_MARKER_SOF3 0xC3 +#define JPEG_MARKER_DHT 0xC4 +#define JPEG_MARKER_RST0 0XD0 +#define JPEG_MARKER_SOI 0xD8 +#define JPEG_MARKER_EOI 0xD9 +#define JPEG_MARKER_SOS 0xDA +#define JPEG_MARKER_DQT 0xDB +#define JPEG_MARKER_DRI 0xDD +#define JPEG_MARKER_APP0 0xE0 +#define JPEG_MARKER_COM 0xFE + +#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0) +#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1) +#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2) +#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3) +#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4) +#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5) +#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6) + +static const TIFFField ojpegFields[] = { + {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL}, + {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL}, + {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL}, + {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL}, + {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL}, + {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL}, + {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL}, +}; + +#ifndef LIBJPEG_ENCAP_EXTERNAL +#include +#endif + +/* We undefine FAR to avoid conflict with JPEG definition */ + +#ifdef FAR +#undef FAR +#endif + +/* + Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is + not defined. Unfortunately, the MinGW and Borland compilers include + a typedef for INT32, which causes a conflict. MSVC does not include + a conficting typedef given the headers which are included. +*/ +#if defined(__BORLANDC__) || defined(__MINGW32__) +# define XMD_H 1 +#endif + +/* Define "boolean" as unsigned char, not int, per Windows custom. */ +#if defined(__WIN32__) && !defined(__MINGW32__) +# 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 */ +#endif + +#include "jpeglib.h" +#include "jerror.h" + +typedef struct jpeg_error_mgr jpeg_error_mgr; +typedef struct jpeg_common_struct jpeg_common_struct; +typedef struct jpeg_decompress_struct jpeg_decompress_struct; +typedef struct jpeg_source_mgr jpeg_source_mgr; + +typedef enum { + osibsNotSetYet, + osibsJpegInterchangeFormat, + osibsStrile, + osibsEof +} OJPEGStateInBufferSource; + +typedef enum { + ososSoi, + ososQTable0,ososQTable1,ososQTable2,ososQTable3, + ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3, + ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3, + ososDri, + ososSof, + ososSos, + ososCompressed, + ososRst, + ososEoi +} OJPEGStateOutState; + +typedef struct { + TIFF* tif; + #ifndef LIBJPEG_ENCAP_EXTERNAL + JMP_BUF exit_jmpbuf; + #endif + TIFFVGetMethod vgetparent; + TIFFVSetMethod vsetparent; + TIFFPrintMethod printdir; + uint64 file_size; + uint32 image_width; + uint32 image_length; + uint32 strile_width; + uint32 strile_length; + uint32 strile_length_total; + uint8 samples_per_pixel; + uint8 plane_sample_offset; + uint8 samples_per_pixel_per_plane; + uint64 jpeg_interchange_format; + uint64 jpeg_interchange_format_length; + uint8 jpeg_proc; + uint8 subsamplingcorrect; + uint8 subsamplingcorrect_done; + uint8 subsampling_tag; + uint8 subsampling_hor; + uint8 subsampling_ver; + uint8 subsampling_force_desubsampling_inside_decompression; + uint8 qtable_offset_count; + uint8 dctable_offset_count; + uint8 actable_offset_count; + uint64 qtable_offset[3]; + uint64 dctable_offset[3]; + uint64 actable_offset[3]; + uint8* qtable[4]; + uint8* dctable[4]; + uint8* actable[4]; + uint16 restart_interval; + uint8 restart_index; + uint8 sof_log; + uint8 sof_marker_id; + uint32 sof_x; + uint32 sof_y; + uint8 sof_c[3]; + uint8 sof_hv[3]; + uint8 sof_tq[3]; + uint8 sos_cs[3]; + uint8 sos_tda[3]; + struct { + uint8 log; + OJPEGStateInBufferSource in_buffer_source; + uint32 in_buffer_next_strile; + uint64 in_buffer_file_pos; + uint64 in_buffer_file_togo; + } sos_end[3]; + uint8 readheader_done; + uint8 writeheader_done; + uint16 write_cursample; + uint32 write_curstrile; + uint8 libjpeg_session_active; + uint8 libjpeg_jpeg_query_style; + jpeg_error_mgr libjpeg_jpeg_error_mgr; + jpeg_decompress_struct libjpeg_jpeg_decompress_struct; + jpeg_source_mgr libjpeg_jpeg_source_mgr; + uint8 subsampling_convert_log; + uint32 subsampling_convert_ylinelen; + uint32 subsampling_convert_ylines; + uint32 subsampling_convert_clinelen; + uint32 subsampling_convert_clines; + uint32 subsampling_convert_ybuflen; + uint32 subsampling_convert_cbuflen; + uint32 subsampling_convert_ycbcrbuflen; + uint8* subsampling_convert_ycbcrbuf; + uint8* subsampling_convert_ybuf; + uint8* subsampling_convert_cbbuf; + uint8* subsampling_convert_crbuf; + uint32 subsampling_convert_ycbcrimagelen; + uint8** subsampling_convert_ycbcrimage; + uint32 subsampling_convert_clinelenout; + uint32 subsampling_convert_state; + uint32 bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */ + uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */ + OJPEGStateInBufferSource in_buffer_source; + uint32 in_buffer_next_strile; + uint32 in_buffer_strile_count; + uint64 in_buffer_file_pos; + uint8 in_buffer_file_pos_log; + uint64 in_buffer_file_togo; + uint16 in_buffer_togo; + uint8* in_buffer_cur; + uint8 in_buffer[OJPEG_BUFFER]; + OJPEGStateOutState out_state; + uint8 out_buffer[OJPEG_BUFFER]; + uint8* skip_buffer; +} OJPEGState; + +static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap); +static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap); +static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags); + +static int OJPEGFixupTags(TIFF* tif); +static int OJPEGSetupDecode(TIFF* tif); +static int OJPEGPreDecode(TIFF* tif, uint16 s); +static int OJPEGPreDecodeSkipRaw(TIFF* tif); +static int OJPEGPreDecodeSkipScanlines(TIFF* tif); +static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc); +static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc); +static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); +static int OJPEGSetupEncode(TIFF* tif); +static int OJPEGPreEncode(TIFF* tif, uint16 s); +static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int OJPEGPostEncode(TIFF* tif); +static void OJPEGCleanup(TIFF* tif); + +static void OJPEGSubsamplingCorrect(TIFF* tif); +static int OJPEGReadHeaderInfo(TIFF* tif); +static int OJPEGReadSecondarySos(TIFF* tif, uint16 s); +static int OJPEGWriteHeaderInfo(TIFF* tif); +static void OJPEGLibjpegSessionAbort(TIFF* tif); + +static int OJPEGReadHeaderInfoSec(TIFF* tif); +static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif); +static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif); +static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif); +static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id); +static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif); +static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif); +static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif); +static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif); + +static int OJPEGReadBufferFill(OJPEGState* sp); +static int OJPEGReadByte(OJPEGState* sp, uint8* byte); +static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte); +static void OJPEGReadByteAdvance(OJPEGState* sp); +static int OJPEGReadWord(OJPEGState* sp, uint16* word); +static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem); +static void OJPEGReadSkip(OJPEGState* sp, uint16 len); + +static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); +static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); +static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); +static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len); +static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len); +static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len); + +#ifdef LIBJPEG_ENCAP_EXTERNAL +extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); +extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); +extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); +extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); +extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); +extern void jpeg_encap_unwind(TIFF* tif); +#else +static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j); +static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); +static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); +static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); +static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); +static void jpeg_encap_unwind(TIFF* tif); +#endif + +static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo); +static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo); +static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo); +static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo); +static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes); +static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired); +static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo); + +int +TIFFInitOJPEG(TIFF* tif, int scheme) +{ + static const char module[]="TIFFInitOJPEG"; + OJPEGState* sp; + + assert(scheme==COMPRESSION_OJPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging Old JPEG codec-specific tags failed"); + return 0; + } + + /* state block */ + sp=_TIFFmalloc(sizeof(OJPEGState)); + if (sp==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block"); + return(0); + } + _TIFFmemset(sp,0,sizeof(OJPEGState)); + sp->tif=tif; + sp->jpeg_proc=1; + sp->subsampling_hor=2; + sp->subsampling_ver=2; + TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2); + /* tif codec methods */ + tif->tif_fixuptags=OJPEGFixupTags; + tif->tif_setupdecode=OJPEGSetupDecode; + tif->tif_predecode=OJPEGPreDecode; + tif->tif_postdecode=OJPEGPostDecode; + tif->tif_decoderow=OJPEGDecode; + tif->tif_decodestrip=OJPEGDecode; + tif->tif_decodetile=OJPEGDecode; + tif->tif_setupencode=OJPEGSetupEncode; + tif->tif_preencode=OJPEGPreEncode; + tif->tif_postencode=OJPEGPostEncode; + tif->tif_encoderow=OJPEGEncode; + tif->tif_encodestrip=OJPEGEncode; + tif->tif_encodetile=OJPEGEncode; + tif->tif_cleanup=OJPEGCleanup; + tif->tif_data=(uint8*)sp; + /* tif tag methods */ + sp->vgetparent=tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield=OJPEGVGetField; + sp->vsetparent=tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield=OJPEGVSetField; + sp->printdir=tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir=OJPEGPrintDir; + /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. + Some others do, but have totally meaningless or corrupt values + in these tags. In these cases, the JpegInterchangeFormat stream is + reliable. In any case, this decoder reads the compressed data itself, + from the most reliable locations, and we need to notify encapsulating + LibTiff not to read raw strips or tiles for us. */ + tif->tif_flags|=TIFF_NOREADRAW; + return(1); +} + +static int +OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + switch(tag) + { + case TIFFTAG_JPEGIFOFFSET: + *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format; + break; + case TIFFTAG_JPEGIFBYTECOUNT: + *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + if (sp->subsamplingcorrect_done==0) + OJPEGSubsamplingCorrect(tif); + *va_arg(ap,uint16*)=(uint16)sp->subsampling_hor; + *va_arg(ap,uint16*)=(uint16)sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count; + *va_arg(ap,void**)=(void*)sp->qtable_offset; + break; + case TIFFTAG_JPEGDCTABLES: + *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count; + *va_arg(ap,void**)=(void*)sp->dctable_offset; + break; + case TIFFTAG_JPEGACTABLES: + *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count; + *va_arg(ap,void**)=(void*)sp->actable_offset; + break; + case TIFFTAG_JPEGPROC: + *va_arg(ap,uint16*)=(uint16)sp->jpeg_proc; + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + *va_arg(ap,uint16*)=sp->restart_interval; + break; + default: + return (*sp->vgetparent)(tif,tag,ap); + } + return (1); +} + +static int +OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[]="OJPEGVSetField"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint32 ma; + uint64* mb; + uint32 n; + switch(tag) + { + case TIFFTAG_JPEGIFOFFSET: + sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64); + break; + case TIFFTAG_JPEGIFBYTECOUNT: + sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + sp->subsampling_tag=1; + sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap); + sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap); + tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor; + tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + ma=(uint32)va_arg(ap,uint32); + if (ma!=0) + { + if (ma>3) + { + TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count"); + return(0); + } + sp->qtable_offset_count=(uint8)ma; + mb=(uint64*)va_arg(ap,uint64*); + for (n=0; nqtable_offset[n]=mb[n]; + } + break; + case TIFFTAG_JPEGDCTABLES: + ma=(uint32)va_arg(ap,uint32); + if (ma!=0) + { + if (ma>3) + { + TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count"); + return(0); + } + sp->dctable_offset_count=(uint8)ma; + mb=(uint64*)va_arg(ap,uint64*); + for (n=0; ndctable_offset[n]=mb[n]; + } + break; + case TIFFTAG_JPEGACTABLES: + ma=(uint32)va_arg(ap,uint32); + if (ma!=0) + { + if (ma>3) + { + TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count"); + return(0); + } + sp->actable_offset_count=(uint8)ma; + mb=(uint64*)va_arg(ap,uint64*); + for (n=0; nactable_offset[n]=mb[n]; + } + break; + case TIFFTAG_JPEGPROC: + sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap); + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + sp->restart_interval=(uint16)va_arg(ap,uint16_vap); + break; + default: + return (*sp->vsetparent)(tif,tag,ap); + } + TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit); + tif->tif_flags|=TIFF_DIRTYDIRECT; + return(1); +} + +static void +OJPEGPrintDir(TIFF* tif, FILE* fd, long flags) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + (void)flags; + assert(sp!=NULL); + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) + fprintf(fd," JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format); + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) + fprintf(fd," JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length); + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES)) + { + fprintf(fd," JpegQTables:"); + for (m=0; mqtable_offset_count; m++) + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]); + fprintf(fd,"\n"); + } + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES)) + { + fprintf(fd," JpegDcTables:"); + for (m=0; mdctable_offset_count; m++) + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]); + fprintf(fd,"\n"); + } + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES)) + { + fprintf(fd," JpegAcTables:"); + for (m=0; mactable_offset_count; m++) + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]); + fprintf(fd,"\n"); + } + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC)) + fprintf(fd," JpegProc: %u\n",(unsigned int)sp->jpeg_proc); + if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL)) + fprintf(fd," JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); +} + +static int +OJPEGFixupTags(TIFF* tif) +{ + (void) tif; + return(1); +} + +static int +OJPEGSetupDecode(TIFF* tif) +{ + static const char module[]="OJPEGSetupDecode"; + TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software"); + return(1); +} + +static int +OJPEGPreDecode(TIFF* tif, uint16 s) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint32 m; + if (sp->subsamplingcorrect_done==0) + OJPEGSubsamplingCorrect(tif); + if (sp->readheader_done==0) + { + if (OJPEGReadHeaderInfo(tif)==0) + return(0); + } + if (sp->sos_end[s].log==0) + { + if (OJPEGReadSecondarySos(tif,s)==0) + return(0); + } + if isTiled(tif) + m=tif->tif_curtile; + else + m=tif->tif_curstrip; + if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m))) + { + if (sp->libjpeg_session_active!=0) + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done=0; + } + if (sp->writeheader_done==0) + { + sp->plane_sample_offset=(uint8)s; + sp->write_cursample=s; + sp->write_curstrile=s*tif->tif_dir.td_stripsperimage; + if ((sp->in_buffer_file_pos_log==0) || + (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos)) + { + sp->in_buffer_source=sp->sos_end[s].in_buffer_source; + sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile; + sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos; + sp->in_buffer_file_pos_log=0; + sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo; + sp->in_buffer_togo=0; + sp->in_buffer_cur=0; + } + if (OJPEGWriteHeaderInfo(tif)==0) + return(0); + } + while (sp->write_curstrilelibjpeg_jpeg_query_style==0) + { + if (OJPEGPreDecodeSkipRaw(tif)==0) + return(0); + } + else + { + if (OJPEGPreDecodeSkipScanlines(tif)==0) + return(0); + } + sp->write_curstrile++; + } + return(1); +} + +static int +OJPEGPreDecodeSkipRaw(TIFF* tif) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint32 m; + m=sp->lines_per_strile; + if (sp->subsampling_convert_state!=0) + { + if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m) + { + sp->subsampling_convert_state+=m; + if (sp->subsampling_convert_state==sp->subsampling_convert_clines) + sp->subsampling_convert_state=0; + return(1); + } + m-=sp->subsampling_convert_clines-sp->subsampling_convert_state; + sp->subsampling_convert_state=0; + } + while (m>=sp->subsampling_convert_clines) + { + if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) + return(0); + m-=sp->subsampling_convert_clines; + } + if (m>0) + { + if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) + return(0); + sp->subsampling_convert_state=m; + } + return(1); +} + +static int +OJPEGPreDecodeSkipScanlines(TIFF* tif) +{ + static const char module[]="OJPEGPreDecodeSkipScanlines"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint32 m; + if (sp->skip_buffer==NULL) + { + sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line); + if (sp->skip_buffer==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + } + for (m=0; mlines_per_strile; m++) + { + if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0) + return(0); + } + return(1); +} + +static int +OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + (void)s; + if (sp->libjpeg_jpeg_query_style==0) + { + if (OJPEGDecodeRaw(tif,buf,cc)==0) + return(0); + } + else + { + if (OJPEGDecodeScanlines(tif,buf,cc)==0) + return(0); + } + return(1); +} + +static int +OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc) +{ + static const char module[]="OJPEGDecodeRaw"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8* m; + tmsize_t n; + uint8* oy; + uint8* ocb; + uint8* ocr; + uint8* p; + uint32 q; + uint8* r; + uint8 sx,sy; + if (cc%sp->bytes_per_line!=0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); + return(0); + } + assert(cc>0); + m=buf; + n=cc; + do + { + if (sp->subsampling_convert_state==0) + { + if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) + return(0); + } + oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen; + ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; + ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; + p=m; + for (q=0; qsubsampling_convert_clinelenout; q++) + { + r=oy; + for (sy=0; sysubsampling_ver; sy++) + { + for (sx=0; sxsubsampling_hor; sx++) + *p++=*r++; + r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor; + } + oy+=sp->subsampling_hor; + *p++=*ocb++; + *p++=*ocr++; + } + sp->subsampling_convert_state++; + if (sp->subsampling_convert_state==sp->subsampling_convert_clines) + sp->subsampling_convert_state=0; + m+=sp->bytes_per_line; + n-=sp->bytes_per_line; + } while(n>0); + return(1); +} + +static int +OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc) +{ + static const char module[]="OJPEGDecodeScanlines"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8* m; + tmsize_t n; + if (cc%sp->bytes_per_line!=0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); + return(0); + } + assert(cc>0); + m=buf; + n=cc; + do + { + if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0) + return(0); + m+=sp->bytes_per_line; + n-=sp->bytes_per_line; + } while(n>0); + return(1); +} + +static void +OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + (void)buf; + (void)cc; + sp->write_curstrile++; + if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) + { + assert(sp->libjpeg_session_active!=0); + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done=0; + } +} + +static int +OJPEGSetupEncode(TIFF* tif) +{ + static const char module[]="OJPEGSetupEncode"; + TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); + return(0); +} + +static int +OJPEGPreEncode(TIFF* tif, uint16 s) +{ + static const char module[]="OJPEGPreEncode"; + (void)s; + TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); + return(0); +} + +static int +OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + static const char module[]="OJPEGEncode"; + (void)buf; + (void)cc; + (void)s; + TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); + return(0); +} + +static int +OJPEGPostEncode(TIFF* tif) +{ + static const char module[]="OJPEGPostEncode"; + TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); + return(0); +} + +static void +OJPEGCleanup(TIFF* tif) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + if (sp!=0) + { + tif->tif_tagmethods.vgetfield=sp->vgetparent; + tif->tif_tagmethods.vsetfield=sp->vsetparent; + tif->tif_tagmethods.printdir=sp->printdir; + if (sp->qtable[0]!=0) + _TIFFfree(sp->qtable[0]); + if (sp->qtable[1]!=0) + _TIFFfree(sp->qtable[1]); + if (sp->qtable[2]!=0) + _TIFFfree(sp->qtable[2]); + if (sp->qtable[3]!=0) + _TIFFfree(sp->qtable[3]); + if (sp->dctable[0]!=0) + _TIFFfree(sp->dctable[0]); + if (sp->dctable[1]!=0) + _TIFFfree(sp->dctable[1]); + if (sp->dctable[2]!=0) + _TIFFfree(sp->dctable[2]); + if (sp->dctable[3]!=0) + _TIFFfree(sp->dctable[3]); + if (sp->actable[0]!=0) + _TIFFfree(sp->actable[0]); + if (sp->actable[1]!=0) + _TIFFfree(sp->actable[1]); + if (sp->actable[2]!=0) + _TIFFfree(sp->actable[2]); + if (sp->actable[3]!=0) + _TIFFfree(sp->actable[3]); + if (sp->libjpeg_session_active!=0) + OJPEGLibjpegSessionAbort(tif); + if (sp->subsampling_convert_ycbcrbuf!=0) + _TIFFfree(sp->subsampling_convert_ycbcrbuf); + if (sp->subsampling_convert_ycbcrimage!=0) + _TIFFfree(sp->subsampling_convert_ycbcrimage); + if (sp->skip_buffer!=0) + _TIFFfree(sp->skip_buffer); + _TIFFfree(sp); + tif->tif_data=NULL; + _TIFFSetDefaultCompressionState(tif); + } +} + +static void +OJPEGSubsamplingCorrect(TIFF* tif) +{ + static const char module[]="OJPEGSubsamplingCorrect"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 mh; + uint8 mv; + _TIFFFillStriles( tif ); + + assert(sp->subsamplingcorrect_done==0); + if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB))) + { + if (sp->subsampling_tag!=0) + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel"); + sp->subsampling_hor=1; + sp->subsampling_ver=1; + sp->subsampling_force_desubsampling_inside_decompression=0; + } + else + { + sp->subsamplingcorrect_done=1; + mh=sp->subsampling_hor; + mv=sp->subsampling_ver; + sp->subsamplingcorrect=1; + OJPEGReadHeaderInfoSec(tif); + if (sp->subsampling_force_desubsampling_inside_decompression!=0) + { + sp->subsampling_hor=1; + sp->subsampling_ver=1; + } + sp->subsamplingcorrect=0; + if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0)) + { + if (sp->subsampling_tag==0) + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver); + else + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression!=0) + { + if (sp->subsampling_tag==0) + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression"); + else + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression==0) + { + if (sp->subsampling_horsubsampling_ver) + TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver); + } + } + sp->subsamplingcorrect_done=1; +} + +static int +OJPEGReadHeaderInfo(TIFF* tif) +{ + static const char module[]="OJPEGReadHeaderInfo"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(sp->readheader_done==0); + sp->image_width=tif->tif_dir.td_imagewidth; + sp->image_length=tif->tif_dir.td_imagelength; + if isTiled(tif) + { + sp->strile_width=tif->tif_dir.td_tilewidth; + sp->strile_length=tif->tif_dir.td_tilelength; + sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length; + } + else + { + sp->strile_width=sp->image_width; + sp->strile_length=tif->tif_dir.td_rowsperstrip; + sp->strile_length_total=sp->image_length; + } + if (tif->tif_dir.td_samplesperpixel==1) + { + sp->samples_per_pixel=1; + sp->plane_sample_offset=0; + sp->samples_per_pixel_per_plane=sp->samples_per_pixel; + sp->subsampling_hor=1; + sp->subsampling_ver=1; + } + else + { + if (tif->tif_dir.td_samplesperpixel!=3) + { + TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel); + return(0); + } + sp->samples_per_pixel=3; + sp->plane_sample_offset=0; + if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG) + sp->samples_per_pixel_per_plane=3; + else + sp->samples_per_pixel_per_plane=1; + } + if (sp->strile_lengthimage_length) + { + if (sp->strile_length%(sp->subsampling_ver*8)!=0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length"); + return(0); + } + sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8)); + } + if (OJPEGReadHeaderInfoSec(tif)==0) + return(0); + sp->sos_end[0].log=1; + sp->sos_end[0].in_buffer_source=sp->in_buffer_source; + sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile; + sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; + sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; + sp->readheader_done=1; + return(1); +} + +static int +OJPEGReadSecondarySos(TIFF* tif, uint16 s) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + assert(s>0); + assert(s<3); + assert(sp->sos_end[0].log!=0); + assert(sp->sos_end[s].log==0); + sp->plane_sample_offset=s-1; + while(sp->sos_end[sp->plane_sample_offset].log==0) + sp->plane_sample_offset--; + sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source; + sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; + sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; + sp->in_buffer_file_pos_log=0; + sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; + sp->in_buffer_togo=0; + sp->in_buffer_cur=0; + while(sp->plane_sample_offsetplane_sample_offset++; + if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) + return(0); + sp->sos_end[sp->plane_sample_offset].log=1; + sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source; + sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; + } + return(1); +} + +static int +OJPEGWriteHeaderInfo(TIFF* tif) +{ + static const char module[]="OJPEGWriteHeaderInfo"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8** m; + uint32 n; + /* if a previous attempt failed, don't try again */ + if (sp->libjpeg_session_active != 0) + return 0; + sp->out_state=ososSoi; + sp->restart_index=0; + jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); + sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage; + sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit; + sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr); + sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif; + if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) + return(0); + sp->libjpeg_session_active=1; + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0; + sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource; + sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer; + sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData; + sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart; + sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource; + sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr); + if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0) + return(0); + if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1)) + { + sp->libjpeg_jpeg_decompress_struct.raw_data_out=1; +#if JPEG_LIB_VERSION >= 70 + sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE; +#endif + sp->libjpeg_jpeg_query_style=0; + if (sp->subsampling_convert_log==0) + { + assert(sp->subsampling_convert_ycbcrbuf==0); + assert(sp->subsampling_convert_ycbcrimage==0); + sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8); + sp->subsampling_convert_ylines=sp->subsampling_ver*8; + sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor; + sp->subsampling_convert_clines=8; + sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines; + sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen; + sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen); + if (sp->subsampling_convert_ycbcrbuf==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf; + sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen; + sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen; + sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*)); + if (sp->subsampling_convert_ycbcrimage==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + m=sp->subsampling_convert_ycbcrimage; + *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3); + *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines); + *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines); + for (n=0; nsubsampling_convert_ylines; n++) + *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen; + for (n=0; nsubsampling_convert_clines; n++) + *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen; + for (n=0; nsubsampling_convert_clines; n++) + *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen; + sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor); + sp->subsampling_convert_state=0; + sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2); + sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver); + sp->subsampling_convert_log=1; + } + } + else + { + sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN; + sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN; + sp->libjpeg_jpeg_query_style=1; + sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width; + sp->lines_per_strile=sp->strile_length; + } + if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) + return(0); + sp->writeheader_done=1; + return(1); +} + +static void +OJPEGLibjpegSessionAbort(TIFF* tif) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(sp->libjpeg_session_active!=0); + jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct))); + sp->libjpeg_session_active=0; +} + +static int +OJPEGReadHeaderInfoSec(TIFF* tif) +{ + static const char module[]="OJPEGReadHeaderInfoSec"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + uint16 n; + uint8 o; + if (sp->file_size==0) + sp->file_size=TIFFGetFileSize(tif); + if (sp->jpeg_interchange_format!=0) + { + if (sp->jpeg_interchange_format>=sp->file_size) + { + sp->jpeg_interchange_format=0; + sp->jpeg_interchange_format_length=0; + } + else + { + if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) + sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format; + } + } + sp->in_buffer_source=osibsNotSetYet; + sp->in_buffer_next_strile=0; + sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; + sp->in_buffer_file_togo=0; + sp->in_buffer_togo=0; + do + { + if (OJPEGReadBytePeek(sp,&m)==0) + return(0); + if (m!=255) + break; + OJPEGReadByteAdvance(sp); + do + { + if (OJPEGReadByte(sp,&m)==0) + return(0); + } while(m==255); + switch(m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data, and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0+1: + case JPEG_MARKER_APP0+2: + case JPEG_MARKER_APP0+3: + case JPEG_MARKER_APP0+4: + case JPEG_MARKER_APP0+5: + case JPEG_MARKER_APP0+6: + case JPEG_MARKER_APP0+7: + case JPEG_MARKER_APP0+8: + case JPEG_MARKER_APP0+9: + case JPEG_MARKER_APP0+10: + case JPEG_MARKER_APP0+11: + case JPEG_MARKER_APP0+12: + case JPEG_MARKER_APP0+13: + case JPEG_MARKER_APP0+14: + case JPEG_MARKER_APP0+15: + /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */ + if (OJPEGReadWord(sp,&n)==0) + return(0); + if (n<2) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); + return(0); + } + if (n>2) + OJPEGReadSkip(sp,n-2); + break; + case JPEG_MARKER_DRI: + if (OJPEGReadHeaderInfoSecStreamDri(tif)==0) + return(0); + break; + case JPEG_MARKER_DQT: + if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0) + return(0); + break; + case JPEG_MARKER_DHT: + if (OJPEGReadHeaderInfoSecStreamDht(tif)==0) + return(0); + break; + case JPEG_MARKER_SOF0: + case JPEG_MARKER_SOF1: + case JPEG_MARKER_SOF3: + if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0) + return(0); + if (sp->subsamplingcorrect!=0) + return(1); + break; + case JPEG_MARKER_SOS: + if (sp->subsamplingcorrect!=0) + return(1); + assert(sp->plane_sample_offset==0); + if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) + return(0); + break; + default: + TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m); + return(0); + } + } while(m!=JPEG_MARKER_SOS); + if (sp->subsamplingcorrect) + return(1); + if (sp->sof_log==0) + { + if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0) + return(0); + sp->sof_marker_id=JPEG_MARKER_SOF0; + for (o=0; osamples_per_pixel; o++) + sp->sof_c[o]=o; + sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver); + for (o=1; osamples_per_pixel; o++) + sp->sof_hv[o]=17; + sp->sof_x=sp->strile_width; + sp->sof_y=sp->strile_length_total; + sp->sof_log=1; + if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0) + return(0); + if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0) + return(0); + for (o=1; osamples_per_pixel; o++) + sp->sos_cs[o]=o; + } + return(1); +} + +static int +OJPEGReadHeaderInfoSecStreamDri(TIFF* tif) +{ + /* this could easilly cause trouble in some cases... but no such cases have occured sofar */ + static const char module[]="OJPEGReadHeaderInfoSecStreamDri"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint16 m; + if (OJPEGReadWord(sp,&m)==0) + return(0); + if (m!=4) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data"); + return(0); + } + if (OJPEGReadWord(sp,&m)==0) + return(0); + sp->restart_interval=m; + return(1); +} + +static int +OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ + static const char module[]="OJPEGReadHeaderInfoSecStreamDqt"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint16 m; + uint32 na; + uint8* nb; + uint8 o; + if (OJPEGReadWord(sp,&m)==0) + return(0); + if (m<=2) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); + return(0); + } + if (sp->subsamplingcorrect!=0) + OJPEGReadSkip(sp,m-2); + else + { + m-=2; + do + { + if (m<65) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); + return(0); + } + na=sizeof(uint32)+69; + nb=_TIFFmalloc(na); + if (nb==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + *(uint32*)nb=na; + nb[sizeof(uint32)]=255; + nb[sizeof(uint32)+1]=JPEG_MARKER_DQT; + nb[sizeof(uint32)+2]=0; + nb[sizeof(uint32)+3]=67; + if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) { + _TIFFfree(nb); + return(0); + } + o=nb[sizeof(uint32)+4]&15; + if (3tif_clientdata,module,"Corrupt DQT marker in JPEG data"); + _TIFFfree(nb); + return(0); + } + if (sp->qtable[o]!=0) + _TIFFfree(sp->qtable[o]); + sp->qtable[o]=nb; + m-=65; + } while(m>0); + } + return(1); +} + +static int +OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ + /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */ + static const char module[]="OJPEGReadHeaderInfoSecStreamDht"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint16 m; + uint32 na; + uint8* nb; + uint8 o; + if (OJPEGReadWord(sp,&m)==0) + return(0); + if (m<=2) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + return(0); + } + if (sp->subsamplingcorrect!=0) + { + OJPEGReadSkip(sp,m-2); + } + else + { + na=sizeof(uint32)+2+m; + nb=_TIFFmalloc(na); + if (nb==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + *(uint32*)nb=na; + nb[sizeof(uint32)]=255; + nb[sizeof(uint32)+1]=JPEG_MARKER_DHT; + nb[sizeof(uint32)+2]=(m>>8); + nb[sizeof(uint32)+3]=(m&255); + if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) + return(0); + o=nb[sizeof(uint32)+4]; + if ((o&240)==0) + { + if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + return(0); + } + if (sp->dctable[o]!=0) + _TIFFfree(sp->dctable[o]); + sp->dctable[o]=nb; + } + else + { + if ((o&240)!=16) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + return(0); + } + o&=15; + if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + return(0); + } + if (sp->actable[o]!=0) + _TIFFfree(sp->actable[o]); + sp->actable[o]=nb; + } + } + return(1); +} + +static int +OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id) +{ + /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ + static const char module[]="OJPEGReadHeaderInfoSecStreamSof"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint16 m; + uint16 n; + uint8 o; + uint16 p; + uint16 q; + if (sp->sof_log!=0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); + return(0); + } + if (sp->subsamplingcorrect==0) + sp->sof_marker_id=marker_id; + /* Lf: data length */ + if (OJPEGReadWord(sp,&m)==0) + return(0); + if (m<11) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); + return(0); + } + m-=8; + if (m%3!=0) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); + return(0); + } + n=m/3; + if (sp->subsamplingcorrect==0) + { + if (n!=sp->samples_per_pixel) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples"); + return(0); + } + } + /* P: Sample precision */ + if (OJPEGReadByte(sp,&o)==0) + return(0); + if (o!=8) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample"); + return(0); + } + /* Y: Number of lines, X: Number of samples per line */ + if (sp->subsamplingcorrect) + OJPEGReadSkip(sp,4); + else + { + /* Y: Number of lines */ + if (OJPEGReadWord(sp,&p)==0) + return(0); + if (((uint32)pimage_length) && ((uint32)pstrile_length_total)) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height"); + return(0); + } + sp->sof_y=p; + /* X: Number of samples per line */ + if (OJPEGReadWord(sp,&p)==0) + return(0); + if (((uint32)pimage_width) && ((uint32)pstrile_width)) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width"); + return(0); + } + if ((uint32)p>sp->strile_width) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width"); + return(0); + } + sp->sof_x=p; + } + /* Nf: Number of image components in frame */ + if (OJPEGReadByte(sp,&o)==0) + return(0); + if (o!=n) + { + if (sp->subsamplingcorrect==0) + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); + return(0); + } + /* per component stuff */ + /* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */ + for (q=0; qsubsamplingcorrect==0) + sp->sof_c[q]=o; + /* H: Horizontal sampling factor, and V: Vertical sampling factor */ + if (OJPEGReadByte(sp,&o)==0) + return(0); + if (sp->subsamplingcorrect!=0) + { + if (q==0) + { + sp->subsampling_hor=(o>>4); + sp->subsampling_ver=(o&15); + if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || + ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) + sp->subsampling_force_desubsampling_inside_decompression=1; + } + else + { + if (o!=17) + sp->subsampling_force_desubsampling_inside_decompression=1; + } + } + else + { + sp->sof_hv[q]=o; + if (sp->subsampling_force_desubsampling_inside_decompression==0) + { + if (q==0) + { + if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver)) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); + return(0); + } + } + else + { + if (o!=17) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); + return(0); + } + } + } + } + /* Tq: Quantization table destination selector */ + if (OJPEGReadByte(sp,&o)==0) + return(0); + if (sp->subsamplingcorrect==0) + sp->sof_tq[q]=o; + } + if (sp->subsamplingcorrect==0) + sp->sof_log=1; + return(1); +} + +static int +OJPEGReadHeaderInfoSecStreamSos(TIFF* tif) +{ + /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ + static const char module[]="OJPEGReadHeaderInfoSecStreamSos"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint16 m; + uint8 n; + uint8 o; + assert(sp->subsamplingcorrect==0); + if (sp->sof_log==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); + return(0); + } + /* Ls */ + if (OJPEGReadWord(sp,&m)==0) + return(0); + if (m!=6+sp->samples_per_pixel_per_plane*2) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); + return(0); + } + /* Ns */ + if (OJPEGReadByte(sp,&n)==0) + return(0); + if (n!=sp->samples_per_pixel_per_plane) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); + return(0); + } + /* Cs, Td, and Ta */ + for (o=0; osamples_per_pixel_per_plane; o++) + { + /* Cs */ + if (OJPEGReadByte(sp,&n)==0) + return(0); + sp->sos_cs[sp->plane_sample_offset+o]=n; + /* Td and Ta */ + if (OJPEGReadByte(sp,&n)==0) + return(0); + sp->sos_tda[sp->plane_sample_offset+o]=n; + } + /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */ + OJPEGReadSkip(sp,3); + return(1); +} + +static int +OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) +{ + static const char module[]="OJPEGReadHeaderInfoSecTablesQTable"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + uint8 n; + uint32 oa; + uint8* ob; + uint32 p; + if (sp->qtable_offset[0]==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); + return(0); + } + sp->in_buffer_file_pos_log=0; + for (m=0; msamples_per_pixel; m++) + { + if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1]))) + { + for (n=0; nqtable_offset[m]==sp->qtable_offset[n]) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value"); + return(0); + } + } + oa=sizeof(uint32)+69; + ob=_TIFFmalloc(oa); + if (ob==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + *(uint32*)ob=oa; + ob[sizeof(uint32)]=255; + ob[sizeof(uint32)+1]=JPEG_MARKER_DQT; + ob[sizeof(uint32)+2]=0; + ob[sizeof(uint32)+3]=67; + ob[sizeof(uint32)+4]=m; + TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); + p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); + if (p!=64) + return(0); + sp->qtable[m]=ob; + sp->sof_tq[m]=m; + } + else + sp->sof_tq[m]=sp->sof_tq[m-1]; + } + return(1); +} + +static int +OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) +{ + static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + uint8 n; + uint8 o[16]; + uint32 p; + uint32 q; + uint32 ra; + uint8* rb; + if (sp->dctable_offset[0]==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); + return(0); + } + sp->in_buffer_file_pos_log=0; + for (m=0; msamples_per_pixel; m++) + { + if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1]))) + { + for (n=0; ndctable_offset[m]==sp->dctable_offset[n]) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value"); + return(0); + } + } + TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET); + p=TIFFReadFile(tif,o,16); + if (p!=16) + return(0); + q=0; + for (n=0; n<16; n++) + q+=o[n]; + ra=sizeof(uint32)+21+q; + rb=_TIFFmalloc(ra); + if (rb==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + *(uint32*)rb=ra; + rb[sizeof(uint32)]=255; + rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; + rb[sizeof(uint32)+2]=((19+q)>>8); + rb[sizeof(uint32)+3]=((19+q)&255); + rb[sizeof(uint32)+4]=m; + for (n=0; n<16; n++) + rb[sizeof(uint32)+5+n]=o[n]; + p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); + if (p!=q) + return(0); + sp->dctable[m]=rb; + sp->sos_tda[m]=(m<<4); + } + else + sp->sos_tda[m]=sp->sos_tda[m-1]; + } + return(1); +} + +static int +OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) +{ + static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable"; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + uint8 n; + uint8 o[16]; + uint32 p; + uint32 q; + uint32 ra; + uint8* rb; + if (sp->actable_offset[0]==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); + return(0); + } + sp->in_buffer_file_pos_log=0; + for (m=0; msamples_per_pixel; m++) + { + if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1]))) + { + for (n=0; nactable_offset[m]==sp->actable_offset[n]) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value"); + return(0); + } + } + TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); + p=TIFFReadFile(tif,o,16); + if (p!=16) + return(0); + q=0; + for (n=0; n<16; n++) + q+=o[n]; + ra=sizeof(uint32)+21+q; + rb=_TIFFmalloc(ra); + if (rb==0) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + *(uint32*)rb=ra; + rb[sizeof(uint32)]=255; + rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; + rb[sizeof(uint32)+2]=((19+q)>>8); + rb[sizeof(uint32)+3]=((19+q)&255); + rb[sizeof(uint32)+4]=(16|m); + for (n=0; n<16; n++) + rb[sizeof(uint32)+5+n]=o[n]; + p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); + if (p!=q) + return(0); + sp->actable[m]=rb; + sp->sos_tda[m]=(sp->sos_tda[m]|m); + } + else + sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15)); + } + return(1); +} + +static int +OJPEGReadBufferFill(OJPEGState* sp) +{ + uint16 m; + tmsize_t n; + /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made + * in any other case, seek or read errors should be passed through */ + do + { + if (sp->in_buffer_file_togo!=0) + { + if (sp->in_buffer_file_pos_log==0) + { + TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET); + sp->in_buffer_file_pos_log=1; + } + m=OJPEG_BUFFER; + if ((uint64)m>sp->in_buffer_file_togo) + m=(uint16)sp->in_buffer_file_togo; + n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m); + if (n==0) + return(0); + assert(n>0); + assert(n<=OJPEG_BUFFER); + assert(n<65536); + assert((uint64)n<=sp->in_buffer_file_togo); + m=(uint16)n; + sp->in_buffer_togo=m; + sp->in_buffer_cur=sp->in_buffer; + sp->in_buffer_file_togo-=m; + sp->in_buffer_file_pos+=m; + break; + } + sp->in_buffer_file_pos_log=0; + switch(sp->in_buffer_source) + { + case osibsNotSetYet: + if (sp->jpeg_interchange_format!=0) + { + sp->in_buffer_file_pos=sp->jpeg_interchange_format; + sp->in_buffer_file_togo=sp->jpeg_interchange_format_length; + } + sp->in_buffer_source=osibsJpegInterchangeFormat; + break; + case osibsJpegInterchangeFormat: + sp->in_buffer_source=osibsStrile; + case osibsStrile: + if (!_TIFFFillStriles( sp->tif ) + || sp->tif->tif_dir.td_stripoffset == NULL + || sp->tif->tif_dir.td_stripbytecount == NULL) + return 0; + + if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) + sp->in_buffer_source=osibsEof; + else + { + sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile]; + if (sp->in_buffer_file_pos!=0) + { + if (sp->in_buffer_file_pos>=sp->file_size) + sp->in_buffer_file_pos=0; + else if (sp->tif->tif_dir.td_stripbytecount==NULL) + sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; + else + { + if (sp->tif->tif_dir.td_stripbytecount == 0) { + TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing"); + return(0); + } + sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; + if (sp->in_buffer_file_togo==0) + sp->in_buffer_file_pos=0; + else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) + sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; + } + } + sp->in_buffer_next_strile++; + } + break; + default: + return(0); + } + } while (1); + return(1); +} + +static int +OJPEGReadByte(OJPEGState* sp, uint8* byte) +{ + if (sp->in_buffer_togo==0) + { + if (OJPEGReadBufferFill(sp)==0) + return(0); + assert(sp->in_buffer_togo>0); + } + *byte=*(sp->in_buffer_cur); + sp->in_buffer_cur++; + sp->in_buffer_togo--; + return(1); +} + +static int +OJPEGReadBytePeek(OJPEGState* sp, uint8* byte) +{ + if (sp->in_buffer_togo==0) + { + if (OJPEGReadBufferFill(sp)==0) + return(0); + assert(sp->in_buffer_togo>0); + } + *byte=*(sp->in_buffer_cur); + return(1); +} + +static void +OJPEGReadByteAdvance(OJPEGState* sp) +{ + assert(sp->in_buffer_togo>0); + sp->in_buffer_cur++; + sp->in_buffer_togo--; +} + +static int +OJPEGReadWord(OJPEGState* sp, uint16* word) +{ + uint8 m; + if (OJPEGReadByte(sp,&m)==0) + return(0); + *word=(m<<8); + if (OJPEGReadByte(sp,&m)==0) + return(0); + *word|=m; + return(1); +} + +static int +OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem) +{ + uint16 mlen; + uint8* mmem; + uint16 n; + assert(len>0); + mlen=len; + mmem=mem; + do + { + if (sp->in_buffer_togo==0) + { + if (OJPEGReadBufferFill(sp)==0) + return(0); + assert(sp->in_buffer_togo>0); + } + n=mlen; + if (n>sp->in_buffer_togo) + n=sp->in_buffer_togo; + _TIFFmemcpy(mmem,sp->in_buffer_cur,n); + sp->in_buffer_cur+=n; + sp->in_buffer_togo-=n; + mlen-=n; + mmem+=n; + } while(mlen>0); + return(1); +} + +static void +OJPEGReadSkip(OJPEGState* sp, uint16 len) +{ + uint16 m; + uint16 n; + m=len; + n=m; + if (n>sp->in_buffer_togo) + n=sp->in_buffer_togo; + sp->in_buffer_cur+=n; + sp->in_buffer_togo-=n; + m-=n; + if (m>0) + { + assert(sp->in_buffer_togo==0); + n=m; + if ((uint64)n>sp->in_buffer_file_togo) + n=(uint16)sp->in_buffer_file_togo; + sp->in_buffer_file_pos+=n; + sp->in_buffer_file_togo-=n; + sp->in_buffer_file_pos_log=0; + /* we don't skip past jpeginterchangeformat/strile block... + * if that is asked from us, we're dealing with totally bazurk + * data anyway, and we've not seen this happening on any + * testfile, so we might as well likely cause some other + * meaningless error to be passed at some later time + */ + } +} + +static int +OJPEGWriteStream(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + *len=0; + do + { + assert(sp->out_state<=ososEoi); + switch(sp->out_state) + { + case ososSoi: + OJPEGWriteStreamSoi(tif,mem,len); + break; + case ososQTable0: + OJPEGWriteStreamQTable(tif,0,mem,len); + break; + case ososQTable1: + OJPEGWriteStreamQTable(tif,1,mem,len); + break; + case ososQTable2: + OJPEGWriteStreamQTable(tif,2,mem,len); + break; + case ososQTable3: + OJPEGWriteStreamQTable(tif,3,mem,len); + break; + case ososDcTable0: + OJPEGWriteStreamDcTable(tif,0,mem,len); + break; + case ososDcTable1: + OJPEGWriteStreamDcTable(tif,1,mem,len); + break; + case ososDcTable2: + OJPEGWriteStreamDcTable(tif,2,mem,len); + break; + case ososDcTable3: + OJPEGWriteStreamDcTable(tif,3,mem,len); + break; + case ososAcTable0: + OJPEGWriteStreamAcTable(tif,0,mem,len); + break; + case ososAcTable1: + OJPEGWriteStreamAcTable(tif,1,mem,len); + break; + case ososAcTable2: + OJPEGWriteStreamAcTable(tif,2,mem,len); + break; + case ososAcTable3: + OJPEGWriteStreamAcTable(tif,3,mem,len); + break; + case ososDri: + OJPEGWriteStreamDri(tif,mem,len); + break; + case ososSof: + OJPEGWriteStreamSof(tif,mem,len); + break; + case ososSos: + OJPEGWriteStreamSos(tif,mem,len); + break; + case ososCompressed: + if (OJPEGWriteStreamCompressed(tif,mem,len)==0) + return(0); + break; + case ososRst: + OJPEGWriteStreamRst(tif,mem,len); + break; + case ososEoi: + OJPEGWriteStreamEoi(tif,mem,len); + break; + } + } while (*len==0); + return(1); +} + +static void +OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(OJPEG_BUFFER>=2); + sp->out_buffer[0]=255; + sp->out_buffer[1]=JPEG_MARKER_SOI; + *len=2; + *mem=(void*)sp->out_buffer; + sp->out_state++; +} + +static void +OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + if (sp->qtable[table_index]!=0) + { + *mem=(void*)(sp->qtable[table_index]+sizeof(uint32)); + *len=*((uint32*)sp->qtable[table_index])-sizeof(uint32); + } + sp->out_state++; +} + +static void +OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + if (sp->dctable[table_index]!=0) + { + *mem=(void*)(sp->dctable[table_index]+sizeof(uint32)); + *len=*((uint32*)sp->dctable[table_index])-sizeof(uint32); + } + sp->out_state++; +} + +static void +OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + if (sp->actable[table_index]!=0) + { + *mem=(void*)(sp->actable[table_index]+sizeof(uint32)); + *len=*((uint32*)sp->actable[table_index])-sizeof(uint32); + } + sp->out_state++; +} + +static void +OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(OJPEG_BUFFER>=6); + if (sp->restart_interval!=0) + { + sp->out_buffer[0]=255; + sp->out_buffer[1]=JPEG_MARKER_DRI; + sp->out_buffer[2]=0; + sp->out_buffer[3]=4; + sp->out_buffer[4]=(sp->restart_interval>>8); + sp->out_buffer[5]=(sp->restart_interval&255); + *len=6; + *mem=(void*)sp->out_buffer; + } + sp->out_state++; +} + +static void +OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3); + assert(255>=8+sp->samples_per_pixel_per_plane*3); + sp->out_buffer[0]=255; + sp->out_buffer[1]=sp->sof_marker_id; + /* Lf */ + sp->out_buffer[2]=0; + sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3; + /* P */ + sp->out_buffer[4]=8; + /* Y */ + sp->out_buffer[5]=(sp->sof_y>>8); + sp->out_buffer[6]=(sp->sof_y&255); + /* X */ + sp->out_buffer[7]=(sp->sof_x>>8); + sp->out_buffer[8]=(sp->sof_x&255); + /* Nf */ + sp->out_buffer[9]=sp->samples_per_pixel_per_plane; + for (m=0; msamples_per_pixel_per_plane; m++) + { + /* C */ + sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m]; + /* H and V */ + sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m]; + /* Tq */ + sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m]; + } + *len=10+sp->samples_per_pixel_per_plane*3; + *mem=(void*)sp->out_buffer; + sp->out_state++; +} + +static void +OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + uint8 m; + assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2); + assert(255>=6+sp->samples_per_pixel_per_plane*2); + sp->out_buffer[0]=255; + sp->out_buffer[1]=JPEG_MARKER_SOS; + /* Ls */ + sp->out_buffer[2]=0; + sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2; + /* Ns */ + sp->out_buffer[4]=sp->samples_per_pixel_per_plane; + for (m=0; msamples_per_pixel_per_plane; m++) + { + /* Cs */ + sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m]; + /* Td and Ta */ + sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m]; + } + /* Ss */ + sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0; + /* Se */ + sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63; + /* Ah and Al */ + sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0; + *len=8+sp->samples_per_pixel_per_plane*2; + *mem=(void*)sp->out_buffer; + sp->out_state++; +} + +static int +OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + if (sp->in_buffer_togo==0) + { + if (OJPEGReadBufferFill(sp)==0) + return(0); + assert(sp->in_buffer_togo>0); + } + *len=sp->in_buffer_togo; + *mem=(void*)sp->in_buffer_cur; + sp->in_buffer_togo=0; + if (sp->in_buffer_file_togo==0) + { + switch(sp->in_buffer_source) + { + case osibsStrile: + if (sp->in_buffer_next_strilein_buffer_strile_count) + sp->out_state=ososRst; + else + sp->out_state=ososEoi; + break; + case osibsEof: + sp->out_state=ososEoi; + break; + default: + break; + } + } + return(1); +} + +static void +OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(OJPEG_BUFFER>=2); + sp->out_buffer[0]=255; + sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index; + sp->restart_index++; + if (sp->restart_index==8) + sp->restart_index=0; + *len=2; + *mem=(void*)sp->out_buffer; + sp->out_state=ososCompressed; +} + +static void +OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + assert(OJPEG_BUFFER>=2); + sp->out_buffer[0]=255; + sp->out_buffer[1]=JPEG_MARKER_EOI; + *len=2; + *mem=(void*)sp->out_buffer; +} + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static int +jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) +{ + return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1)); +} +#endif + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static int +jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image) +{ + return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1)); +} +#endif + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static int +jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) +{ + return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1)); +} +#endif + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static int +jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines) +{ + return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1)); +} +#endif + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static int +jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines) +{ + return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1)); +} +#endif + +#ifndef LIBJPEG_ENCAP_EXTERNAL +static void +jpeg_encap_unwind(TIFF* tif) +{ + OJPEGState* sp=(OJPEGState*)tif->tif_data; + LONGJMP(sp->exit_jmpbuf,1); +} +#endif + +static void +OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo,buffer); + TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); +} + +static void +OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo,buffer); + TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); + jpeg_encap_unwind((TIFF*)(cinfo->client_data)); +} + +static void +OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo) +{ + (void)cinfo; +} + +static boolean +OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo) +{ + TIFF* tif=(TIFF*)cinfo->client_data; + OJPEGState* sp=(OJPEGState*)tif->tif_data; + void* mem=0; + uint32 len=0U; + if (OJPEGWriteStream(tif,&mem,&len)==0) + { + TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data"); + jpeg_encap_unwind(tif); + } + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len; + sp->libjpeg_jpeg_source_mgr.next_input_byte=mem; + return(1); +} + +static void +OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes) +{ + TIFF* tif=(TIFF*)cinfo->client_data; + (void)num_bytes; + TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); + jpeg_encap_unwind(tif); +} + +static boolean +OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired) +{ + TIFF* tif=(TIFF*)cinfo->client_data; + (void)desired; + TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); + jpeg_encap_unwind(tif); + return(0); +} + +static void +OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo) +{ + (void)cinfo; +} + +#endif + + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_open.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_open.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_open.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_open.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,725 @@ +/* $Id: tif_open.c,v 1.46 2010-12-06 16:54:54 faxguy Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +/* + * Dummy functions to fill the omitted client procedures. + */ +static int +_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) +{ + (void) fd; (void) pbase; (void) psize; + return (0); +} + +static void +_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +{ + (void) fd; (void) base; (void) size; +} + +int +_TIFFgetMode(const char* mode, const char* module) +{ + int m = -1; + + switch (mode[0]) { + case 'r': + m = O_RDONLY; + if (mode[1] == '+') + m = O_RDWR; + break; + case 'w': + case 'a': + m = O_RDWR|O_CREAT; + if (mode[0] == 'w') + m |= O_TRUNC; + break; + default: + TIFFErrorExt(0, module, "\"%s\": Bad mode", mode); + break; + } + return (m); +} + +TIFF* +TIFFClientOpen( + const char* name, const char* mode, + thandle_t clientdata, + TIFFReadWriteProc readproc, + TIFFReadWriteProc writeproc, + TIFFSeekProc seekproc, + TIFFCloseProc closeproc, + TIFFSizeProc sizeproc, + TIFFMapFileProc mapproc, + TIFFUnmapFileProc unmapproc +) +{ + static const char module[] = "TIFFClientOpen"; + TIFF *tif; + int m; + const char* cp; + + /* The following are configuration checks. They should be redundant, but should not + * compile to any actual code in an optimised release build anyway. If any of them + * fail, (makefile-based or other) configuration is not correct */ + assert(sizeof(uint8)==1); + assert(sizeof(int8)==1); + assert(sizeof(uint16)==2); + assert(sizeof(int16)==2); + assert(sizeof(uint32)==4); + assert(sizeof(int32)==4); + assert(sizeof(uint64)==8); + assert(sizeof(int64)==8); + assert(sizeof(tmsize_t)==sizeof(void*)); + { + union{ + uint8 a8[2]; + uint16 a16; + } n; + n.a8[0]=1; + n.a8[1]=0; + #ifdef WORDS_BIGENDIAN + assert(n.a16==256); + #else + assert(n.a16==1); + #endif + } + + m = _TIFFgetMode(mode, module); + if (m == -1) + goto bad2; + tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); + if (tif == NULL) { + TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); + goto bad2; + } + _TIFFmemset(tif, 0, sizeof (*tif)); + tif->tif_name = (char *)tif + sizeof (TIFF); + strcpy(tif->tif_name, name); + tif->tif_mode = m &~ (O_CREAT|O_TRUNC); + tif->tif_curdir = (uint16) -1; /* non-existent directory */ + tif->tif_curoff = 0; + tif->tif_curstrip = (uint32) -1; /* invalid strip */ + tif->tif_row = (uint32) -1; /* read/write pre-increment */ + tif->tif_clientdata = clientdata; + if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { + TIFFErrorExt(clientdata, module, + "One of the client procedures is NULL pointer."); + goto bad2; + } + tif->tif_readproc = readproc; + tif->tif_writeproc = writeproc; + tif->tif_seekproc = seekproc; + tif->tif_closeproc = closeproc; + tif->tif_sizeproc = sizeproc; + if (mapproc) + tif->tif_mapproc = mapproc; + else + tif->tif_mapproc = _tiffDummyMapProc; + if (unmapproc) + tif->tif_unmapproc = unmapproc; + else + tif->tif_unmapproc = _tiffDummyUnmapProc; + _TIFFSetDefaultCompressionState(tif); /* setup default state */ + /* + * Default is to return data MSB2LSB and enable the + * use of memory-mapped files and strip chopping when + * a file is opened read-only. + */ + tif->tif_flags = FILLORDER_MSB2LSB; + if (m == O_RDONLY ) + tif->tif_flags |= TIFF_MAPPED; + + #ifdef STRIPCHOP_DEFAULT + if (m == O_RDONLY || m == O_RDWR) + tif->tif_flags |= STRIPCHOP_DEFAULT; + #endif + + /* + * Process library-specific flags in the open mode string. + * The following flags may be used to control intrinsic library + * behaviour that may or may not be desirable (usually for + * compatibility with some application that claims to support + * TIFF but only supports some braindead idea of what the + * vendor thinks TIFF is): + * + * 'l' use little-endian byte order for creating a file + * 'b' use big-endian byte order for creating a file + * 'L' read/write information using LSB2MSB bit order + * 'B' read/write information using MSB2LSB bit order + * 'H' read/write information using host bit order + * 'M' enable use of memory-mapped files when supported + * 'm' disable use of memory-mapped files + * 'C' enable strip chopping support when reading + * 'c' disable strip chopping support + * 'h' read TIFF header only, do not load the first IFD + * '4' ClassicTIFF for creating a file (default) + * '8' BigTIFF for creating a file + * + * The use of the 'l' and 'b' flags is strongly discouraged. + * These flags are provided solely because numerous vendors, + * typically on the PC, do not correctly support TIFF; they + * only support the Intel little-endian byte order. This + * support is not configured by default because it supports + * the violation of the TIFF spec that says that readers *MUST* + * support both byte orders. It is strongly recommended that + * you not use this feature except to deal with busted apps + * that write invalid TIFF. And even in those cases you should + * bang on the vendors to fix their software. + * + * The 'L', 'B', and 'H' flags are intended for applications + * that can optimize operations on data by using a particular + * bit order. By default the library returns data in MSB2LSB + * bit order for compatibiltiy with older versions of this + * library. Returning data in the bit order of the native cpu + * makes the most sense but also requires applications to check + * the value of the FillOrder tag; something they probably do + * not do right now. + * + * The 'M' and 'm' flags are provided because some virtual memory + * systems exhibit poor behaviour when large images are mapped. + * These options permit clients to control the use of memory-mapped + * files on a per-file basis. + * + * The 'C' and 'c' flags are provided because the library support + * for chopping up large strips into multiple smaller strips is not + * application-transparent and as such can cause problems. The 'c' + * option permits applications that only want to look at the tags, + * for example, to get the unadulterated TIFF tag information. + */ + for (cp = mode; *cp; cp++) + switch (*cp) { + case 'b': + #ifndef WORDS_BIGENDIAN + if (m&O_CREAT) + tif->tif_flags |= TIFF_SWAB; + #endif + break; + case 'l': + #ifdef WORDS_BIGENDIAN + if ((m&O_CREAT)) + tif->tif_flags |= TIFF_SWAB; + #endif + break; + case 'B': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_MSB2LSB; + break; + case 'L': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_LSB2MSB; + break; + case 'H': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + HOST_FILLORDER; + break; + case 'M': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + break; + case 'm': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_MAPPED; + break; + case 'C': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_STRIPCHOP; + break; + case 'c': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_STRIPCHOP; + break; + case 'h': + tif->tif_flags |= TIFF_HEADERONLY; + break; + case '8': + if (m&O_CREAT) + tif->tif_flags |= TIFF_BIGTIFF; + break; + } + /* + * Read in TIFF header. + */ + if ((m & O_TRUNC) || + !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { + if (tif->tif_mode == O_RDONLY) { + TIFFErrorExt(tif->tif_clientdata, name, + "Cannot read TIFF header"); + goto bad; + } + /* + * Setup header and write. + */ + #ifdef WORDS_BIGENDIAN + tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB + ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; + #else + tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB + ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; + #endif + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; + tif->tif_header.classic.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; + tif->tif_header.big.tiff_offsetsize = 8; + tif->tif_header.big.tiff_unused = 0; + tif->tif_header.big.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.common.tiff_version); + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + } + tif->tif_header_size = sizeof (TIFFHeaderBig); + } + /* + * The doc for "fopen" for some STD_C_LIBs says that if you + * open a file for modify ("+"), then you must fseek (or + * fflush?) between any freads and fwrites. This is not + * necessary on most systems, but has been shown to be needed + * on Solaris. + */ + TIFFSeekFile( tif, 0, SEEK_SET ); + if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { + TIFFErrorExt(tif->tif_clientdata, name, + "Error writing TIFF header"); + goto bad; + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { + #ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } else { + #ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } + /* + * Setup default directory. + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + tif->tif_diroff = 0; + tif->tif_dirlist = NULL; + tif->tif_dirlistsize = 0; + tif->tif_dirnumber = 0; + return (tif); + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && + tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN + #if MDI_SUPPORT + && + #if HOST_BIGENDIAN + tif->tif_header.common.tiff_magic != MDI_BIGENDIAN + #else + tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN + #endif + ) { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF or MDI file, bad magic number %d (0x%x)", + #else + ) { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad magic number %d (0x%x)", + #endif + tif->tif_header.common.tiff_magic, + tif->tif_header.common.tiff_magic); + goto bad; + } + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { + #ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } else { + #ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& + (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad version number %d (0x%x)", + tif->tif_header.common.tiff_version, + tif->tif_header.common.tiff_version); + goto bad; + } + if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic)))) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Cannot read TIFF header"); + goto bad; + } + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); + } + if (tif->tif_header.big.tiff_offsetsize != 8) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)", + tif->tif_header.big.tiff_offsetsize, + tif->tif_header.big.tiff_offsetsize); + goto bad; + } + if (tif->tif_header.big.tiff_unused != 0) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad BigTIFF unused %d (0x%x)", + tif->tif_header.big.tiff_unused, + tif->tif_header.big.tiff_unused); + goto bad; + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + tif->tif_flags |= TIFF_BIGTIFF; + } + tif->tif_flags |= TIFF_MYBUFFER; + tif->tif_rawcp = tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + + switch (mode[0]) { + case 'r': + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; + else + tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; + /* + * Try to use a memory-mapped file if the client + * has not explicitly suppressed usage with the + * 'm' flag in the open mode (see above). + */ + if (tif->tif_flags & TIFF_MAPPED) + { + toff_t n; + if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) + { + tif->tif_size=(tmsize_t)n; + assert((toff_t)tif->tif_size==n); + } + else + tif->tif_flags &= ~TIFF_MAPPED; + } + /* + * Sometimes we do not want to read the first directory (for example, + * it may be broken) and want to proceed to other directories. I this + * case we use the TIFF_HEADERONLY flag to open file and return + * immediately after reading TIFF header. + */ + if (tif->tif_flags & TIFF_HEADERONLY) + return (tif); + + /* + * Setup initial directory. + */ + if (TIFFReadDirectory(tif)) { + tif->tif_rawcc = (tmsize_t)-1; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (tif); + } + break; + case 'a': + /* + * New directories are automatically append + * to the end of the directory chain when they + * are written out (see TIFFWriteDirectory). + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + return (tif); + } +bad: + tif->tif_mode = O_RDONLY; /* XXX avoid flush */ + TIFFCleanup(tif); +bad2: + return ((TIFF*)0); +} + +/* + * Query functions to access private data. + */ + +/* + * Return open file's name. + */ +const char * +TIFFFileName(TIFF* tif) +{ + return (tif->tif_name); +} + +/* + * Set the file name. + */ +const char * +TIFFSetFileName(TIFF* tif, const char *name) +{ + const char* old_name = tif->tif_name; + tif->tif_name = (char *)name; + return (old_name); +} + +/* + * Return open file's I/O descriptor. + */ +int +TIFFFileno(TIFF* tif) +{ + return (tif->tif_fd); +} + +/* + * Set open file's I/O descriptor, and return previous value. + */ +int +TIFFSetFileno(TIFF* tif, int fd) +{ + int old_fd = tif->tif_fd; + tif->tif_fd = fd; + return old_fd; +} + +/* + * Return open file's clientdata. + */ +thandle_t +TIFFClientdata(TIFF* tif) +{ + return (tif->tif_clientdata); +} + +/* + * Set open file's clientdata, and return previous value. + */ +thandle_t +TIFFSetClientdata(TIFF* tif, thandle_t newvalue) +{ + thandle_t m = tif->tif_clientdata; + tif->tif_clientdata = newvalue; + return m; +} + +/* + * Return read/write mode. + */ +int +TIFFGetMode(TIFF* tif) +{ + return (tif->tif_mode); +} + +/* + * Return read/write mode. + */ +int +TIFFSetMode(TIFF* tif, int mode) +{ + int old_mode = tif->tif_mode; + tif->tif_mode = mode; + return (old_mode); +} + +/* + * Return nonzero if file is organized in + * tiles; zero if organized as strips. + */ +int +TIFFIsTiled(TIFF* tif) +{ + return (isTiled(tif)); +} + +/* + * Return current row being read/written. + */ +uint32 +TIFFCurrentRow(TIFF* tif) +{ + return (tif->tif_row); +} + +/* + * Return index of the current directory. + */ +uint16 +TIFFCurrentDirectory(TIFF* tif) +{ + return (tif->tif_curdir); +} + +/* + * Return current strip. + */ +uint32 +TIFFCurrentStrip(TIFF* tif) +{ + return (tif->tif_curstrip); +} + +/* + * Return current tile. + */ +uint32 +TIFFCurrentTile(TIFF* tif) +{ + return (tif->tif_curtile); +} + +/* + * Return nonzero if the file has byte-swapped data. + */ +int +TIFFIsByteSwapped(TIFF* tif) +{ + return ((tif->tif_flags & TIFF_SWAB) != 0); +} + +/* + * Return nonzero if the data is returned up-sampled. + */ +int +TIFFIsUpSampled(TIFF* tif) +{ + return (isUpSampled(tif)); +} + +/* + * Return nonzero if the data is returned in MSB-to-LSB bit order. + */ +int +TIFFIsMSB2LSB(TIFF* tif) +{ + return (isFillOrder(tif, FILLORDER_MSB2LSB)); +} + +/* + * Return nonzero if given file was written in big-endian order. + */ +int +TIFFIsBigEndian(TIFF* tif) +{ + return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); +} + +/* + * Return pointer to file read method. + */ +TIFFReadWriteProc +TIFFGetReadProc(TIFF* tif) +{ + return (tif->tif_readproc); +} + +/* + * Return pointer to file write method. + */ +TIFFReadWriteProc +TIFFGetWriteProc(TIFF* tif) +{ + return (tif->tif_writeproc); +} + +/* + * Return pointer to file seek method. + */ +TIFFSeekProc +TIFFGetSeekProc(TIFF* tif) +{ + return (tif->tif_seekproc); +} + +/* + * Return pointer to file close method. + */ +TIFFCloseProc +TIFFGetCloseProc(TIFF* tif) +{ + return (tif->tif_closeproc); +} + +/* + * Return pointer to file size requesting method. + */ +TIFFSizeProc +TIFFGetSizeProc(TIFF* tif) +{ + return (tif->tif_sizeproc); +} + +/* + * Return pointer to memory mapping method. + */ +TIFFMapFileProc +TIFFGetMapFileProc(TIFF* tif) +{ + return (tif->tif_mapproc); +} + +/* + * Return pointer to memory unmapping method. + */ +TIFFUnmapFileProc +TIFFGetUnmapFileProc(TIFF* tif) +{ + return (tif->tif_unmapproc); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_packbits.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_packbits.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_packbits.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_packbits.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,294 @@ +/* $Id: tif_packbits.c,v 1.20 2010-03-10 18:56:49 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef PACKBITS_SUPPORT +/* + * TIFF Library. + * + * PackBits Compression Algorithm Support + */ +#include + +static int +PackBitsPreEncode(TIFF* tif, uint16 s) +{ + (void) s; + + if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t)))) + return (0); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif); + else + *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif); + return (1); +} + +static int +PackBitsPostEncode(TIFF* tif) +{ + if (tif->tif_data) + _TIFFfree(tif->tif_data); + return (1); +} + +/* + * Encode a run of pixels. + */ +static int +PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +{ + unsigned char* bp = (unsigned char*) buf; + uint8* op; + uint8* ep; + uint8* lastliteral; + long n, slop; + int b; + enum { BASE, LITERAL, RUN, LITERAL_RUN } state; + + (void) s; + op = tif->tif_rawcp; + ep = tif->tif_rawdata + tif->tif_rawdatasize; + state = BASE; + lastliteral = 0; + while (cc > 0) { + /* + * Find the longest string of identical bytes. + */ + b = *bp++, cc--, n = 1; + for (; cc > 0 && b == *bp; cc--, bp++) + n++; + again: + if (op + 2 >= ep) { /* insure space for new data */ + /* + * Be careful about writing the last + * literal. Must write up to that point + * and then copy the remainder to the + * front of the buffer. + */ + if (state == LITERAL || state == LITERAL_RUN) { + slop = (long)(op - lastliteral); + tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + while (slop-- > 0) + *op++ = *lastliteral++; + lastliteral = tif->tif_rawcp; + } else { + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + } + } + switch (state) { + case BASE: /* initial state, set run/literal */ + if (n > 1) { + state = RUN; + if (n > 128) { + *op++ = (uint8) -127; + *op++ = (uint8) b; + n -= 128; + goto again; + } + *op++ = (uint8)(-(n-1)); + *op++ = (uint8) b; + } else { + lastliteral = op; + *op++ = 0; + *op++ = (uint8) b; + state = LITERAL; + } + break; + case LITERAL: /* last object was literal string */ + if (n > 1) { + state = LITERAL_RUN; + if (n > 128) { + *op++ = (uint8) -127; + *op++ = (uint8) b; + n -= 128; + goto again; + } + *op++ = (uint8)(-(n-1)); /* encode run */ + *op++ = (uint8) b; + } else { /* extend literal */ + if (++(*lastliteral) == 127) + state = BASE; + *op++ = (uint8) b; + } + break; + case RUN: /* last object was run */ + if (n > 1) { + if (n > 128) { + *op++ = (uint8) -127; + *op++ = (uint8) b; + n -= 128; + goto again; + } + *op++ = (uint8)(-(n-1)); + *op++ = (uint8) b; + } else { + lastliteral = op; + *op++ = 0; + *op++ = (uint8) b; + state = LITERAL; + } + break; + case LITERAL_RUN: /* literal followed by a run */ + /* + * Check to see if previous run should + * be converted to a literal, in which + * case we convert literal-run-literal + * to a single literal. + */ + if (n == 1 && op[-2] == (uint8) -1 && + *lastliteral < 126) { + state = (((*lastliteral) += 2) == 127 ? + BASE : LITERAL); + op[-2] = op[-1]; /* replicate */ + } else + state = RUN; + goto again; + } + } + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + tif->tif_rawcp = op; + return (1); +} + +/* + * Encode a rectangular chunk of pixels. We break it up + * into row-sized pieces to insure that encoded runs do + * not span rows. Otherwise, there can be problems with + * the decoder if data is read, for example, by scanlines + * when it was encoded by strips. + */ +static int +PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + tmsize_t rowsize = *(tmsize_t*)tif->tif_data; + + while (cc > 0) { + tmsize_t chunk = rowsize; + + if( cc < chunk ) + chunk = cc; + + if (PackBitsEncode(tif, bp, chunk, s) < 0) + return (-1); + bp += chunk; + cc -= chunk; + } + return (1); +} + +static int +PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "PackBitsDecode"; + char *bp; + tmsize_t cc; + long n; + int b; + + (void) s; + bp = (char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + while (cc > 0 && occ > 0) { + n = (long) *bp++, cc--; + /* + * Watch out for compilers that + * don't sign extend chars... + */ + if (n >= 128) + n -= 256; + if (n < 0) { /* replicate next byte -n+1 times */ + if (n == -128) /* nop */ + continue; + n = -n + 1; + if( occ < (tmsize_t)n ) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Discarding %lu bytes to avoid buffer overrun", + (unsigned long) ((tmsize_t)n - occ)); + n = (long)occ; + } + occ -= n; + b = *bp++, cc--; /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ + while (n-- > 0) + *op++ = (uint8) b; + } else { /* copy next n+1 bytes literally */ + if (occ < (tmsize_t)(n + 1)) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Discarding %lu bytes to avoid buffer overrun", + (unsigned long) ((tmsize_t)n - occ + 1)); + n = (long)occ - 1; + } + _TIFFmemcpy(op, bp, ++n); /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ + op += n; occ -= n; + bp += n; cc -= n; + } + } + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + if (occ > 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data for scanline %lu", + (unsigned long) tif->tif_row); + return (0); + } + return (1); +} + +int +TIFFInitPackBits(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = PackBitsDecode; + tif->tif_decodestrip = PackBitsDecode; + tif->tif_decodetile = PackBitsDecode; + tif->tif_preencode = PackBitsPreEncode; + tif->tif_postencode = PackBitsPostEncode; + tif->tif_encoderow = PackBitsEncode; + tif->tif_encodestrip = PackBitsEncodeChunk; + tif->tif_encodetile = PackBitsEncodeChunk; + return (1); +} +#endif /* PACKBITS_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_pixarlog.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_pixarlog.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_pixarlog.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_pixarlog.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1426 @@ +/* $Id: tif_pixarlog.c,v 1.37 2012-05-24 23:21:45 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1996-1997 Sam Leffler + * Copyright (c) 1996 Pixar + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Pixar, Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef PIXARLOG_SUPPORT + +/* + * TIFF Library. + * PixarLog Compression Support + * + * Contributed by Dan McCoy. + * + * PixarLog film support uses the TIFF library to store companded + * 11 bit values into a tiff file, which are compressed using the + * zip compressor. + * + * The codec can take as input and produce as output 32-bit IEEE float values + * as well as 16-bit or 8-bit unsigned integer values. + * + * On writing any of the above are converted into the internal + * 11-bit log format. In the case of 8 and 16 bit values, the + * input is assumed to be unsigned linear color values that represent + * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to + * be the normal linear color range, in addition over 1 values are + * accepted up to a value of about 25.0 to encode "hot" hightlights and such. + * The encoding is lossless for 8-bit values, slightly lossy for the + * other bit depths. The actual color precision should be better + * than the human eye can perceive with extra room to allow for + * error introduced by further image computation. As with any quantized + * color format, it is possible to perform image calculations which + * expose the quantization error. This format should certainly be less + * susceptable to such errors than standard 8-bit encodings, but more + * susceptable than straight 16-bit or 32-bit encodings. + * + * On reading the internal format is converted to the desired output format. + * The program can request which format it desires by setting the internal + * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values: + * PIXARLOGDATAFMT_FLOAT = provide IEEE float values. + * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values + * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values + * + * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer + * values with the difference that if there are exactly three or four channels + * (rgb or rgba) it swaps the channel order (bgr or abgr). + * + * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly + * packed in 16-bit values. However no tools are supplied for interpreting + * these values. + * + * "hot" (over 1.0) areas written in floating point get clamped to + * 1.0 in the integer data types. + * + * When the file is closed after writing, the bit depth and sample format + * are set always to appear as if 8-bit data has been written into it. + * That way a naive program unaware of the particulars of the encoding + * gets the format it is most likely able to handle. + * + * The codec does it's own horizontal differencing step on the coded + * values so the libraries predictor stuff should be turned off. + * The codec also handle byte swapping the encoded values as necessary + * since the library does not have the information necessary + * to know the bit depth of the raw unencoded buffer. + * + * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc. + * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT + * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11 + */ + +#include "tif_predict.h" +#include "zlib.h" + +#include +#include +#include + +/* Tables for converting to/from 11 bit coded values */ + +#define TSIZE 2048 /* decode table size (11-bit tokens) */ +#define TSIZEP1 2049 /* Plus one for slop */ +#define ONE 1250 /* token value of 1.0 exactly */ +#define RATIO 1.004 /* nominal ratio for log part */ + +#define CODE_MASK 0x7ff /* 11 bits. */ + +static float Fltsize; +static float LogK1, LogK2; + +#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } + +static void +horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, + float *ToLinearF) +{ + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + } + } else if (stride == 4) { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + t3 = ToLinearF[ca = (wp[3] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + t3 = ToLinearF[(ca += wp[3]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else { + REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, + float *ToLinearF) +{ + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; + +#define SCALE12 2048.0F +#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071) + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + } + } else if (stride == 4) { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + } + } else { + REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, + uint16 *ToLinear16) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + op[3] = ToLinear16[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + op[3] = ToLinear16[(ca += wp[3]) & mask]; + } + } else { + REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +/* + * Returns the log encoded 11-bit values with the horizontal + * differencing undone. + */ +static void +horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2]; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + op[0] = (cr += wp[0]) & mask; + op[1] = (cg += wp[1]) & mask; + op[2] = (cb += wp[2]) & mask; + } + } else if (stride == 4) { + op[0] = cr = wp[0]; op[1] = cg = wp[1]; + op[2] = cb = wp[2]; op[3] = ca = wp[3]; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + op[0] = (cr += wp[0]) & mask; + op[1] = (cg += wp[1]) & mask; + op[2] = (cb += wp[2]) & mask; + op[3] = (ca += wp[3]) & mask; + } + } else { + REPEAT(stride, *op = *wp&mask; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = *wp&mask; wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, + unsigned char *ToLinear8) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + op += 3; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + op[3] = ToLinear8[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + op += 4; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + op[3] = ToLinear8[(ca += wp[3]) & mask]; + } + } else { + REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + + +static void +horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, + unsigned char *ToLinear8) +{ + register unsigned int cr, cg, cb, ca, mask; + register unsigned char t0, t1, t2, t3; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = 0; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + op += 4; + op[0] = 0; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else if (stride == 4) { + t0 = ToLinear8[ca = (wp[3] & mask)]; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + op += 4; + t0 = ToLinear8[(ca += wp[3]) & mask]; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else { + REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +/* + * State block for each open TIFF + * file using PixarLog compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + z_stream stream; + uint16 *tbuf; + uint16 stride; + int state; + int user_datafmt; + int quality; +#define PLSTATE_INIT 1 + + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + + float *ToLinearF; + uint16 *ToLinear16; + unsigned char *ToLinear8; + uint16 *FromLT2; + uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16 *From8; + +} PixarLogState; + +static int +PixarLogMakeTables(PixarLogState *sp) +{ + +/* + * We make several tables here to convert between various external + * representations (float, 16-bit, and 8-bit) and the internal + * 11-bit companded representation. The 11-bit representation has two + * distinct regions. A linear bottom end up through .018316 in steps + * of about .000073, and a region of constant ratio up to about 25. + * These floating point numbers are stored in the main table ToLinearF. + * All other tables are derived from this one. The tables (and the + * ratios) are continuous at the internal seam. + */ + + int nlin, lt2size; + int i, j; + double b, c, linstep, v; + float *ToLinearF; + uint16 *ToLinear16; + unsigned char *ToLinear8; + uint16 *FromLT2; + uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16 *From8; + + c = log(RATIO); + nlin = (int)(1./c); /* nlin must be an integer */ + c = 1./nlin; + b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ + linstep = b*c*exp(1.); + + LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */ + LogK2 = (float)(1./b); + lt2size = (int)(2./linstep) + 1; + FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16)); + From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16)); + From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16)); + ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float)); + ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16)); + ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char)); + if (FromLT2 == NULL || From14 == NULL || From8 == NULL || + ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { + if (FromLT2) _TIFFfree(FromLT2); + if (From14) _TIFFfree(From14); + if (From8) _TIFFfree(From8); + if (ToLinearF) _TIFFfree(ToLinearF); + if (ToLinear16) _TIFFfree(ToLinear16); + if (ToLinear8) _TIFFfree(ToLinear8); + sp->FromLT2 = NULL; + sp->From14 = NULL; + sp->From8 = NULL; + sp->ToLinearF = NULL; + sp->ToLinear16 = NULL; + sp->ToLinear8 = NULL; + return 0; + } + + j = 0; + + for (i = 0; i < nlin; i++) { + v = i * linstep; + ToLinearF[j++] = (float)v; + } + + for (i = nlin; i < TSIZE; i++) + ToLinearF[j++] = (float)(b*exp(c*i)); + + ToLinearF[2048] = ToLinearF[2047]; + + for (i = 0; i < TSIZEP1; i++) { + v = ToLinearF[i]*65535.0 + 0.5; + ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v; + v = ToLinearF[i]*255.0 + 0.5; + ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; + } + + j = 0; + for (i = 0; i < lt2size; i++) { + if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) + j++; + FromLT2[i] = j; + } + + /* + * Since we lose info anyway on 16-bit data, we set up a 14-bit + * table and shift 16-bit values down two bits on input. + * saves a little table space. + */ + j = 0; + for (i = 0; i < 16384; i++) { + while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) + j++; + From14[i] = j; + } + + j = 0; + for (i = 0; i < 256; i++) { + while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) + j++; + From8[i] = j; + } + + Fltsize = (float)(lt2size/2); + + sp->ToLinearF = ToLinearF; + sp->ToLinear16 = ToLinear16; + sp->ToLinear8 = ToLinear8; + sp->FromLT2 = FromLT2; + sp->From14 = From14; + sp->From8 = From8; + + return 1; +} + +#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) + +static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +#define PIXARLOGDATAFMT_UNKNOWN -1 + +static int +PixarLogGuessDataFmt(TIFFDirectory *td) +{ + int guess = PIXARLOGDATAFMT_UNKNOWN; + int format = td->td_sampleformat; + + /* If the user didn't tell us his datafmt, + * take our best guess from the bitspersample. + */ + switch (td->td_bitspersample) { + case 32: + if (format == SAMPLEFORMAT_IEEEFP) + guess = PIXARLOGDATAFMT_FLOAT; + break; + case 16: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_16BIT; + break; + case 12: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) + guess = PIXARLOGDATAFMT_12BITPICIO; + break; + case 11: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_11BITLOG; + break; + case 8: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_8BIT; + break; + } + + return guess; +} + +static tmsize_t +multiply_ms(tmsize_t m1, tmsize_t m2) +{ + tmsize_t bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; +} + +static int +PixarLogFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +static int +PixarLogSetupDecode(TIFF* tif) +{ + static const char module[] = "PixarLogSetupDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = DecoderState(tif); + tmsize_t tbuf_size; + + assert(sp != NULL); + + /* Make sure no byte swapping happens on the data + * after decompression. */ + tif->tif_postdecode = _TIFFNoPostDecode; + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), sizeof(uint16)); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ + sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16)); + if (sp->tbuf == NULL) + return (0); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { + TIFFErrorExt(tif->tif_clientdata, module, + "PixarLog compression can't handle bits depth/data format combination (depth: %d)", + td->td_bitspersample); + return (0); + } + + if (inflateInit(&sp->stream) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); + return (0); + } else { + sp->state |= PLSTATE_INIT; + return (1); + } +} + +/* + * Setup state for decoding a strip. + */ +static int +PixarLogPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "PixarLogPreDecode"; + PixarLogState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_in = (uInt) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (inflateReset(&sp->stream) == Z_OK); +} + +static int +PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "PixarLogDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = DecoderState(tif); + tmsize_t i; + tmsize_t nsamples; + int llen; + uint16 *up; + + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + nsamples = occ / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + nsamples = occ; + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + + (void) s; + assert(sp != NULL); + sp->stream.next_out = (unsigned char *) sp->tbuf; + assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16)); + if (sp->stream.avail_out != nsamples * sizeof(uint16)) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + do { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) { + break; /* XXX */ + } + if (state == Z_DATA_ERROR) { + TIFFErrorExt(tif->tif_clientdata, module, + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, sp->stream.msg); + if (inflateSync(&sp->stream) != Z_OK) + return (0); + continue; + } + if (state != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } while (sp->stream.avail_out > 0); + + /* hopefully, we got all the bytes we needed */ + if (sp->stream.avail_out != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", + (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); + return (0); + } + + up = sp->tbuf; + /* Swap bytes in the data if from a different endian machine. */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(up, nsamples); + + /* + * if llen is not an exact multiple of nsamples, the decode operation + * may overflow the output buffer, so truncate it enough to prevent + * that but still salvage as much data as possible. + */ + if (nsamples % llen) { + TIFFWarningExt(tif->tif_clientdata, module, + "stride %lu is not a multiple of sample count, " + "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples); + nsamples -= nsamples % llen; + } + + for (i = 0; i < nsamples; i += llen, up += llen) { + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + horizontalAccumulateF(up, llen, sp->stride, + (float *)op, sp->ToLinearF); + op += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalAccumulate16(up, llen, sp->stride, + (uint16 *)op, sp->ToLinear16); + op += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_12BITPICIO: + horizontalAccumulate12(up, llen, sp->stride, + (int16 *)op, sp->ToLinearF); + op += llen * sizeof(int16); + break; + case PIXARLOGDATAFMT_11BITLOG: + horizontalAccumulate11(up, llen, sp->stride, + (uint16 *)op); + op += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalAccumulate8(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + case PIXARLOGDATAFMT_8BITABGR: + horizontalAccumulate8abgr(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "Unsupported bits/sample: %d", + td->td_bitspersample); + return (0); + } + } + + return (1); +} + +static int +PixarLogSetupEncode(TIFF* tif) +{ + static const char module[] = "PixarLogSetupEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = EncoderState(tif); + tmsize_t tbuf_size; + + assert(sp != NULL); + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), sizeof(uint16)); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ + sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); + if (sp->tbuf == NULL) + return (0); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { + TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample); + return (0); + } + + if (deflateInit(&sp->stream, sp->quality) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); + return (0); + } else { + sp->state |= PLSTATE_INIT; + return (1); + } +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +PixarLogPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "PixarLogPreEncode"; + PixarLogState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_out = tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (deflateReset(&sp->stream) == Z_OK); +} + +static void +horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) +{ + int32 r1, g1, b1, a1, r2, g2, b2, a2, mask; + float fltsize = Fltsize; + +#define CLAMP(v) ( (v<(float)0.) ? 0 \ + : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ + : (v>(float)24.2) ? 2047 \ + : LogK1*log(v*LogK2) + 0.5 ) + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = (uint16) CLAMP(ip[0]); + g2 = wp[1] = (uint16) CLAMP(ip[1]); + b2 = wp[2] = (uint16) CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + ip += 3; + r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + } + } else if (stride == 4) { + r2 = wp[0] = (uint16) CLAMP(ip[0]); + g2 = wp[1] = (uint16) CLAMP(ip[1]); + b2 = wp[2] = (uint16) CLAMP(ip[2]); + a2 = wp[3] = (uint16) CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + ip += 4; + r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { + ip += n - 1; /* point to last one */ + wp += n - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--) + } + } +} + +static void +horizontalDifference16(unsigned short *ip, int n, int stride, + unsigned short *wp, uint16 *From14) +{ + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + +/* assumption is unsigned pixel values */ +#undef CLAMP +#define CLAMP(v) From14[(v) >> 2] + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + ip += 3; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + } + } else if (stride == 4) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + ip += 4; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { + ip += n - 1; /* point to last one */ + wp += n - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) + } + } +} + + +static void +horizontalDifference8(unsigned char *ip, int n, int stride, + unsigned short *wp, uint16 *From8) +{ + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + +#undef CLAMP +#define CLAMP(v) (From8[(v)]) + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1; + wp += 3; + ip += 3; + } + } else if (stride == 4) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1; + a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1; + wp += 4; + ip += 4; + } + } else { + wp += n + stride - 1; /* point to last one */ + ip += n + stride - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) + } + } +} + +/* + * Encode a chunk of pixels. + */ +static int +PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "PixarLogEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + tmsize_t i; + tmsize_t n; + int llen; + unsigned short * up; + + (void) s; + + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + n = cc / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + n = cc; + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + + for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + horizontalDifferenceF((float *)bp, llen, + sp->stride, up, sp->FromLT2); + bp += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalDifference16((uint16 *)bp, llen, + sp->stride, up, sp->From14); + bp += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalDifference8((unsigned char *)bp, llen, + sp->stride, up, sp->From8); + bp += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + } + + sp->stream.next_in = (unsigned char *) sp->tbuf; + assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_in = (uInt) (n * sizeof(uint16)); + if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n) + { + TIFFErrorExt(tif->tif_clientdata, module, + "ZLib cannot deal with buffers this size"); + return (0); + } + + do { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", + sp->stream.msg); + return (0); + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ + } + } while (sp->stream.avail_in > 0); + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ + +static int +PixarLogPostEncode(TIFF* tif) +{ + static const char module[] = "PixarLogPostEncode"; + PixarLogState *sp = EncoderState(tif); + int state; + + sp->stream.avail_in = 0; + + do { + state = deflate(&sp->stream, Z_FINISH); + switch (state) { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } while (state != Z_STREAM_END); + return (1); +} + +static void +PixarLogClose(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + + /* In a really sneaky (and really incorrect, and untruthfull, and + * troublesome, and error-prone) maneuver that completely goes against + * the spirit of TIFF, and breaks TIFF, on close, we covertly + * modify both bitspersample and sampleformat in the directory to + * indicate 8-bit linear. This way, the decode "just works" even for + * readers that don't know about PixarLog, or how to set + * the PIXARLOGDATFMT pseudo-tag. + */ + td->td_bitspersample = 8; + td->td_sampleformat = SAMPLEFORMAT_UINT; +} + +static void +PixarLogCleanup(TIFF* tif) +{ + PixarLogState* sp = (PixarLogState*) tif->tif_data; + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->FromLT2) _TIFFfree(sp->FromLT2); + if (sp->From14) _TIFFfree(sp->From14); + if (sp->From8) _TIFFfree(sp->From8); + if (sp->ToLinearF) _TIFFfree(sp->ToLinearF); + if (sp->ToLinear16) _TIFFfree(sp->ToLinear16); + if (sp->ToLinear8) _TIFFfree(sp->ToLinear8); + if (sp->state&PLSTATE_INIT) { + if (tif->tif_mode == O_RDONLY) + inflateEnd(&sp->stream); + else + deflateEnd(&sp->stream); + } + if (sp->tbuf) + _TIFFfree(sp->tbuf); + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "PixarLogVSetField"; + PixarLogState *sp = (PixarLogState *)tif->tif_data; + int result; + + switch (tag) { + case TIFFTAG_PIXARLOGQUALITY: + sp->quality = (int) va_arg(ap, int); + if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { + if (deflateParams(&sp->stream, + sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } + return (1); + case TIFFTAG_PIXARLOGDATAFMT: + sp->user_datafmt = (int) va_arg(ap, int); + /* Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_11BITLOG: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_12BITPICIO: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); + break; + case PIXARLOGDATAFMT_16BIT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_FLOAT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); + break; + } + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + result = 1; /* NB: pseudo tag */ + break; + default: + result = (*sp->vsetparent)(tif, tag, ap); + } + return (result); +} + +static int +PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + PixarLogState *sp = (PixarLogState *)tif->tif_data; + + switch (tag) { + case TIFFTAG_PIXARLOGQUALITY: + *va_arg(ap, int*) = sp->quality; + break; + case TIFFTAG_PIXARLOGDATAFMT: + *va_arg(ap, int*) = sp->user_datafmt; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static const TIFFField pixarlogFields[] = { + {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} +}; + +int +TIFFInitPixarLog(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitPixarLog"; + + PixarLogState* sp; + + assert(scheme == COMPRESSION_PIXARLOG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, pixarlogFields, + TIFFArrayCount(pixarlogFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging PixarLog codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState)); + if (tif->tif_data == NULL) + goto bad; + sp = (PixarLogState*) tif->tif_data; + _TIFFmemset(sp, 0, sizeof (*sp)); + sp->stream.data_type = Z_BINARY; + sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = PixarLogFixupTags; + tif->tif_setupdecode = PixarLogSetupDecode; + tif->tif_predecode = PixarLogPreDecode; + tif->tif_decoderow = PixarLogDecode; + tif->tif_decodestrip = PixarLogDecode; + tif->tif_decodetile = PixarLogDecode; + tif->tif_setupencode = PixarLogSetupEncode; + tif->tif_preencode = PixarLogPreEncode; + tif->tif_postencode = PixarLogPostEncode; + tif->tif_encoderow = PixarLogEncode; + tif->tif_encodestrip = PixarLogEncode; + tif->tif_encodetile = PixarLogEncode; + tif->tif_close = PixarLogClose; + tif->tif_cleanup = PixarLogCleanup; + + /* Override SetField so we can handle our private pseudo-tag */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + /* we don't wish to use the predictor, + * the default is none, which predictor value 1 + */ + (void) TIFFPredictorInit(tif); + + /* + * build the companding tables + */ + PixarLogMakeTables(sp); + + return (1); +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for PixarLog state block"); + return (0); +} +#endif /* PIXARLOG_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,764 @@ +/* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Predictor Tag Support (used by multiple codecs). + */ +#include "tiffiop.h" +#include "tif_predict.h" + +#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) + +static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); +static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); +static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); +static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); +static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); +static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); +static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); +static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); +static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); +static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); +static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s); + +static int +PredictorSetup(TIFF* tif) +{ + static const char module[] = "PredictorSetup"; + + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + switch (sp->predictor) /* no differencing */ + { + case PREDICTOR_NONE: + return 1; + case PREDICTOR_HORIZONTAL: + if (td->td_bitspersample != 8 + && td->td_bitspersample != 16 + && td->td_bitspersample != 32) { + TIFFErrorExt(tif->tif_clientdata, module, + "Horizontal differencing \"Predictor\" not supported with %d-bit samples", + td->td_bitspersample); + return 0; + } + break; + case PREDICTOR_FLOATINGPOINT: + if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { + TIFFErrorExt(tif->tif_clientdata, module, + "Floating point \"Predictor\" not supported with %d data format", + td->td_sampleformat); + return 0; + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "\"Predictor\" value %d not supported", + sp->predictor); + return 0; + } + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + sp->rowsize = TIFFTileRowSize(tif); + else + sp->rowsize = TIFFScanlineSize(tif); + if (sp->rowsize == 0) + return 0; + + return 1; +} + +static int +PredictorSetupDecode(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) + return 0; + + if (sp->predictor == 2) { + switch (td->td_bitspersample) { + case 8: sp->decodepfunc = horAcc8; break; + case 16: sp->decodepfunc = horAcc16; break; + case 32: sp->decodepfunc = horAcc32; break; + } + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if( tif->tif_decoderow != PredictorDecodeRow ) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + } + + /* + * If the data is horizontally differenced 16-bit data that + * requires byte-swapping, then it must be byte swapped before + * the accumulation step. We do this with a special-purpose + * routine and override the normal post decoding logic that + * the library setup when the directory was read. + */ + if (tif->tif_flags & TIFF_SWAB) { + if (sp->decodepfunc == horAcc16) { + sp->decodepfunc = swabHorAcc16; + tif->tif_postdecode = _TIFFNoPostDecode; + } else if (sp->decodepfunc == horAcc32) { + sp->decodepfunc = swabHorAcc32; + tif->tif_postdecode = _TIFFNoPostDecode; + } + } + } + + else if (sp->predictor == 3) { + sp->decodepfunc = fpAcc; + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if( tif->tif_decoderow != PredictorDecodeRow ) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + } + /* + * The data should not be swapped outside of the floating + * point predictor, the accumulation routine should return + * byres in the native order. + */ + if (tif->tif_flags & TIFF_SWAB) { + tif->tif_postdecode = _TIFFNoPostDecode; + } + /* + * Allocate buffer to keep the decoded bytes before + * rearranging in the ight order + */ + } + + return 1; +} + +static int +PredictorSetupEncode(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) + return 0; + + if (sp->predictor == 2) { + switch (td->td_bitspersample) { + case 8: sp->encodepfunc = horDiff8; break; + case 16: sp->encodepfunc = horDiff16; break; + case 32: sp->encodepfunc = horDiff32; break; + } + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if( tif->tif_encoderow != PredictorEncodeRow ) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + } + + else if (sp->predictor == 3) { + sp->encodepfunc = fpDiff; + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if( tif->tif_encoderow != PredictorEncodeRow ) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + } + + return 1; +} + +#define REPEAT4(n, op) \ + switch (n) { \ + default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ + case 4: op; \ + case 3: op; \ + case 2: op; \ + case 1: op; \ + case 0: ; \ + } + +static void +horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + + char* cp = (char*) cp0; + assert((cc%stride)==0); + if (cc > stride) { + /* + * Pipeline the most common cases. + */ + if (stride == 3) { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + cc -= 3; + cp += 3; + while (cc>0) { + cp[0] = (char) (cr += cp[0]); + cp[1] = (char) (cg += cp[1]); + cp[2] = (char) (cb += cp[2]); + cc -= 3; + cp += 3; + } + } else if (stride == 4) { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + unsigned int ca = cp[3]; + cc -= 4; + cp += 4; + while (cc>0) { + cp[0] = (char) (cr += cp[0]); + cp[1] = (char) (cg += cp[1]); + cp[2] = (char) (cb += cp[2]); + cp[3] = (char) (ca += cp[3]); + cc -= 4; + cp += 4; + } + } else { + cc -= stride; + do { + REPEAT4(stride, cp[stride] = + (char) (cp[stride] + *cp); cp++) + cc -= stride; + } while (cc>0); + } + } +} + +static void +swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint16* wp = (uint16*) cp0; + tmsize_t wc = cc / 2; + + assert((cc%(2*stride))==0); + + if (wc > stride) { + TIFFSwabArrayOfShort(wp, wc); + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } +} + +static void +horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint16* wp = (uint16*) cp0; + tmsize_t wc = cc / 2; + + assert((cc%(2*stride))==0); + + if (wc > stride) { + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } +} + +static void +swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint32* wp = (uint32*) cp0; + tmsize_t wc = cc / 4; + + assert((cc%(4*stride))==0); + + if (wc > stride) { + TIFFSwabArrayOfLong(wp, wc); + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } +} + +static void +horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint32* wp = (uint32*) cp0; + tmsize_t wc = cc / 4; + + assert((cc%(4*stride))==0); + + if (wc > stride) { + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } +} + +/* + * Floating point predictor accumulation routine. + */ +static void +fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint32 bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count = cc; + uint8 *cp = (uint8 *) cp0; + uint8 *tmp = (uint8 *)_TIFFmalloc(cc); + + assert((cc%(bps*stride))==0); + + if (!tmp) + return; + + while (count > stride) { + REPEAT4(stride, cp[stride] += cp[0]; cp++) + count -= stride; + } + + _TIFFmemcpy(tmp, cp0, cc); + cp = (uint8 *) cp0; + for (count = 0; count < wc; count++) { + uint32 byte; + for (byte = 0; byte < bps; byte++) { + #if WORDS_BIGENDIAN + cp[bps * count + byte] = tmp[byte * wc + count]; + #else + cp[bps * count + byte] = + tmp[(bps - byte - 1) * wc + count]; + #endif + } + } + _TIFFfree(tmp); +} + +/* + * Decode a scanline and apply the predictor routine. + */ +static int +PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->decoderow != NULL); + assert(sp->decodepfunc != NULL); + + if ((*sp->decoderow)(tif, op0, occ0, s)) { + (*sp->decodepfunc)(tif, op0, occ0); + return 1; + } else + return 0; +} + +/* + * Decode a tile/strip and apply the predictor routine. + * Note that horizontal differencing must be done on a + * row-by-row basis. The width of a "row" has already + * been calculated at pre-decode time according to the + * strip/tile dimensions. + */ +static int +PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->decodetile != NULL); + + if ((*sp->decodetile)(tif, op0, occ0, s)) { + tmsize_t rowsize = sp->rowsize; + assert(rowsize > 0); + assert((occ0%rowsize)==0); + assert(sp->decodepfunc != NULL); + while (occ0 > 0) { + (*sp->decodepfunc)(tif, op0, rowsize); + occ0 -= rowsize; + op0 += rowsize; + } + return 1; + } else + return 0; +} + +static void +horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; + char* cp = (char*) cp0; + + assert((cc%stride)==0); + + if (cc > stride) { + cc -= stride; + /* + * Pipeline the most common cases. + */ + if (stride == 3) { + int r1, g1, b1; + int r2 = cp[0]; + int g2 = cp[1]; + int b2 = cp[2]; + do { + r1 = cp[3]; cp[3] = r1-r2; r2 = r1; + g1 = cp[4]; cp[4] = g1-g2; g2 = g1; + b1 = cp[5]; cp[5] = b1-b2; b2 = b1; + cp += 3; + } while ((cc -= 3) > 0); + } else if (stride == 4) { + int r1, g1, b1, a1; + int r2 = cp[0]; + int g2 = cp[1]; + int b2 = cp[2]; + int a2 = cp[3]; + do { + r1 = cp[4]; cp[4] = r1-r2; r2 = r1; + g1 = cp[5]; cp[5] = g1-g2; g2 = g1; + b1 = cp[6]; cp[6] = b1-b2; b2 = b1; + a1 = cp[7]; cp[7] = a1-a2; a2 = a1; + cp += 4; + } while ((cc -= 4) > 0); + } else { + cp += cc - 1; + do { + REPEAT4(stride, cp[stride] -= cp[0]; cp--) + } while ((cc -= stride) > 0); + } + } +} + +static void +horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; + int16 *wp = (int16*) cp0; + tmsize_t wc = cc/2; + + assert((cc%(2*stride))==0); + + if (wc > stride) { + wc -= stride; + wp += wc - 1; + do { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } +} + +static void +horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; + int32 *wp = (int32*) cp0; + tmsize_t wc = cc/4; + + assert((cc%(4*stride))==0); + + if (wc > stride) { + wc -= stride; + wp += wc - 1; + do { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } +} + +/* + * Floating point predictor differencing routine. + */ +static void +fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint32 bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count; + uint8 *cp = (uint8 *) cp0; + uint8 *tmp = (uint8 *)_TIFFmalloc(cc); + + assert((cc%(bps*stride))==0); + + if (!tmp) + return; + + _TIFFmemcpy(tmp, cp0, cc); + for (count = 0; count < wc; count++) { + uint32 byte; + for (byte = 0; byte < bps; byte++) { + #if WORDS_BIGENDIAN + cp[byte * wc + count] = tmp[bps * count + byte]; + #else + cp[(bps - byte - 1) * wc + count] = + tmp[bps * count + byte]; + #endif + } + } + _TIFFfree(tmp); + + cp = (uint8 *) cp0; + cp += cc - stride - 1; + for (count = cc; count > stride; count -= stride) + REPEAT4(stride, cp[stride] -= cp[0]; cp--) +} + +static int +PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encoderow != NULL); + + /* XXX horizontal differencing alters user's data XXX */ + (*sp->encodepfunc)(tif, bp, cc); + return (*sp->encoderow)(tif, bp, cc, s); +} + +static int +PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) +{ + static const char module[] = "PredictorEncodeTile"; + TIFFPredictorState *sp = PredictorState(tif); + uint8 *working_copy; + tmsize_t cc = cc0, rowsize; + unsigned char* bp; + int result_code; + + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encodetile != NULL); + + /* + * Do predictor manipulation in a working buffer to avoid altering + * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 + */ + working_copy = (uint8*) _TIFFmalloc(cc0); + if( working_copy == NULL ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.", + cc0 ); + return 0; + } + memcpy( working_copy, bp0, cc0 ); + bp = working_copy; + + rowsize = sp->rowsize; + assert(rowsize > 0); + assert((cc0%rowsize)==0); + while (cc > 0) { + (*sp->encodepfunc)(tif, bp, rowsize); + cc -= rowsize; + bp += rowsize; + } + result_code = (*sp->encodetile)(tif, working_copy, cc0, s); + + _TIFFfree( working_copy ); + + return result_code; +} + +#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ + +static const TIFFField predictFields[] = { + { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, +}; + +static int +PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->vsetparent != NULL); + + switch (tag) { + case TIFFTAG_PREDICTOR: + sp->predictor = (uint16) va_arg(ap, uint16_vap); + TIFFSetFieldBit(tif, FIELD_PREDICTOR); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; +} + +static int +PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->vgetparent != NULL); + + switch (tag) { + case TIFFTAG_PREDICTOR: + *va_arg(ap, uint16*) = sp->predictor; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +static void +PredictorPrintDir(TIFF* tif, FILE* fd, long flags) +{ + TIFFPredictorState* sp = PredictorState(tif); + + (void) flags; + if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { + fprintf(fd, " Predictor: "); + switch (sp->predictor) { + case 1: fprintf(fd, "none "); break; + case 2: fprintf(fd, "horizontal differencing "); break; + case 3: fprintf(fd, "floating point predictor "); break; + } + fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); + } + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); +} + +int +TIFFPredictorInit(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + + assert(sp != 0); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, predictFields, + TIFFArrayCount(predictFields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", + "Merging Predictor codec-specific tags failed"); + return 0; + } + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = + PredictorVGetField;/* hook for predictor tag */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = + PredictorVSetField;/* hook for predictor tag */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = + PredictorPrintDir; /* hook for predictor tag */ + + sp->setupdecode = tif->tif_setupdecode; + tif->tif_setupdecode = PredictorSetupDecode; + sp->setupencode = tif->tif_setupencode; + tif->tif_setupencode = PredictorSetupEncode; + + sp->predictor = 1; /* default value */ + sp->encodepfunc = NULL; /* no predictor routine */ + sp->decodepfunc = NULL; /* no predictor routine */ + return 1; +} + +int +TIFFPredictorCleanup(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + tif->tif_setupdecode = sp->setupdecode; + tif->tif_setupencode = sp->setupencode; + + return 1; +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_predict.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,77 @@ +/* $Id: tif_predict.h,v 1.8 2010-03-10 18:56:49 bfriesen Exp $ */ + +/* + * Copyright (c) 1995-1997 Sam Leffler + * Copyright (c) 1995-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFPREDICT_ +#define _TIFFPREDICT_ +/* + * ``Library-private'' Support for the Predictor Tag + */ + +/* + * Codecs that want to support the Predictor tag must place + * this structure first in their private state block so that + * the predictor code can cast tif_data to find its state. + */ +typedef struct { + int predictor; /* predictor tag value */ + tmsize_t stride; /* sample stride over data */ + tmsize_t rowsize; /* tile/strip row size */ + + TIFFCodeMethod encoderow; /* parent codec encode/decode row */ + TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ + TIFFPostMethod encodepfunc; /* horizontal differencer */ + + TIFFCodeMethod decoderow; /* parent codec encode/decode row */ + TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ + TIFFPostMethod decodepfunc; /* horizontal accumulator */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFBoolMethod setupdecode; /* super-class method */ + TIFFBoolMethod setupencode; /* super-class method */ +} TIFFPredictorState; + +#if defined(__cplusplus) +extern "C" { +#endif +extern int TIFFPredictorInit(TIFF*); +extern int TIFFPredictorCleanup(TIFF*); +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFPREDICT_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_print.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_print.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_print.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_print.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,714 @@ +/* $Id: tif_print.c,v 1.59 2012-06-13 01:08:51 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Printing Support + */ +#include "tiffiop.h" +#include + +#include + +static void +_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars); + +static const char *photoNames[] = { + "min-is-white", /* PHOTOMETRIC_MINISWHITE */ + "min-is-black", /* PHOTOMETRIC_MINISBLACK */ + "RGB color", /* PHOTOMETRIC_RGB */ + "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ + "transparency mask", /* PHOTOMETRIC_MASK */ + "separated", /* PHOTOMETRIC_SEPARATED */ + "YCbCr", /* PHOTOMETRIC_YCBCR */ + "7 (0x7)", + "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ +}; +#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0])) + +static const char *orientNames[] = { + "0 (0x0)", + "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ + "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ + "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ + "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ + "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ + "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ + "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ + "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ +}; +#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) + +static void +_TIFFPrintField(FILE* fd, const TIFFField *fip, + uint32 value_count, void *raw_data) +{ + uint32 j; + + fprintf(fd, " %s: ", fip->field_name); + + for(j = 0; j < value_count; j++) { + if(fip->field_type == TIFF_BYTE) + fprintf(fd, "%u", ((uint8 *) raw_data)[j]); + else if(fip->field_type == TIFF_UNDEFINED) + fprintf(fd, "0x%x", + (unsigned int) ((unsigned char *) raw_data)[j]); + else if(fip->field_type == TIFF_SBYTE) + fprintf(fd, "%d", ((int8 *) raw_data)[j]); + else if(fip->field_type == TIFF_SHORT) + fprintf(fd, "%u", ((uint16 *) raw_data)[j]); + else if(fip->field_type == TIFF_SSHORT) + fprintf(fd, "%d", ((int16 *) raw_data)[j]); + else if(fip->field_type == TIFF_LONG) + fprintf(fd, "%lu", + (unsigned long)((uint32 *) raw_data)[j]); + else if(fip->field_type == TIFF_SLONG) + fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]); + else if(fip->field_type == TIFF_IFD) + fprintf(fd, "0x%lx", + (unsigned long)((uint32 *) raw_data)[j]); + else if(fip->field_type == TIFF_RATIONAL + || fip->field_type == TIFF_SRATIONAL + || fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float *) raw_data)[j]); + else if(fip->field_type == TIFF_LONG8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "%I64u", + (unsigned __int64)((uint64 *) raw_data)[j]); +#else + fprintf(fd, "%llu", + (unsigned long long)((uint64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_SLONG8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]); +#else + fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_IFD8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "0x%I64x", + (unsigned __int64)((uint64 *) raw_data)[j]); +#else + fprintf(fd, "0x%llx", + (unsigned long long)((uint64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float *)raw_data)[j]); + else if(fip->field_type == TIFF_DOUBLE) + fprintf(fd, "%f", ((double *) raw_data)[j]); + else if(fip->field_type == TIFF_ASCII) { + fprintf(fd, "%s", (char *) raw_data); + break; + } + else { + fprintf(fd, ""); + break; + } + + if(j < value_count - 1) + fprintf(fd, ","); + } + + fprintf(fd, "\n"); +} + +static int +_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag, + uint32 value_count, void *raw_data) +{ + (void) tif; + + /* do not try to pretty print auto-defined fields */ + if (strncmp(fip->field_name,"Tag ", 4) == 0) { + return 0; + } + + switch (tag) + { + case TIFFTAG_INKSET: + if (value_count == 2 && fip->field_type == TIFF_SHORT) { + fprintf(fd, " Ink Set: "); + switch (*((uint16*)raw_data)) { + case INKSET_CMYK: + fprintf(fd, "CMYK\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + *((uint16*)raw_data), + *((uint16*)raw_data)); + break; + } + return 1; + } + return 0; + + case TIFFTAG_DOTRANGE: + if (value_count == 2 && fip->field_type == TIFF_SHORT) { + fprintf(fd, " Dot Range: %u-%u\n", + ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); + return 1; + } + return 0; + + case TIFFTAG_WHITEPOINT: + if (value_count == 2 && fip->field_type == TIFF_RATIONAL) { + fprintf(fd, " White Point: %g-%g\n", + ((float *)raw_data)[0], ((float *)raw_data)[1]); + return 1; + } + return 0; + + case TIFFTAG_XMLPACKET: + { + uint32 i; + + fprintf(fd, " XMLPacket (XMP Metadata):\n" ); + for(i = 0; i < value_count; i++) + fputc(((char *)raw_data)[i], fd); + fprintf( fd, "\n" ); + return 1; + } + case TIFFTAG_RICHTIFFIPTC: + /* + * XXX: for some weird reason RichTIFFIPTC tag + * defined as array of LONG values. + */ + fprintf(fd, + " RichTIFFIPTC Data: , %lu bytes\n", + (unsigned long) value_count * 4); + return 1; + + case TIFFTAG_PHOTOSHOP: + fprintf(fd, " Photoshop Data: , %lu bytes\n", + (unsigned long) value_count); + return 1; + + case TIFFTAG_ICCPROFILE: + fprintf(fd, " ICC Profile: , %lu bytes\n", + (unsigned long) value_count); + return 1; + + case TIFFTAG_STONITS: + if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { + fprintf(fd, + " Sample to Nits conversion factor: %.4e\n", + *((double*)raw_data)); + return 1; + } + return 0; + } + + return 0; +} + +/* + * Print the contents of the current directory + * to the specified stdio file stream. + */ +void +TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) +{ + TIFFDirectory *td = &tif->tif_dir; + char *sep; + uint16 i; + long l, n; + +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n", + (unsigned __int64) tif->tif_diroff, + (unsigned __int64) tif->tif_diroff); +#else + fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n", + (unsigned long long) tif->tif_diroff, + (unsigned long long) tif->tif_diroff); +#endif + if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { + fprintf(fd, " Subfile Type:"); + sep = " "; + if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) { + fprintf(fd, "%sreduced-resolution image", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_PAGE) { + fprintf(fd, "%smulti-page document", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_MASK) + fprintf(fd, "%stransparency mask", sep); + fprintf(fd, " (%lu = 0x%lx)\n", + (long) td->td_subfiletype, (long) td->td_subfiletype); + } + if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { + fprintf(fd, " Image Width: %lu Image Length: %lu", + (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength); + if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) + fprintf(fd, " Image Depth: %lu", + (unsigned long) td->td_imagedepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) { + fprintf(fd, " Tile Width: %lu Tile Length: %lu", + (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength); + if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) + fprintf(fd, " Tile Depth: %lu", + (unsigned long) td->td_tiledepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_RESOLUTION)) { + fprintf(fd, " Resolution: %g, %g", + td->td_xresolution, td->td_yresolution); + if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) { + switch (td->td_resolutionunit) { + case RESUNIT_NONE: + fprintf(fd, " (unitless)"); + break; + case RESUNIT_INCH: + fprintf(fd, " pixels/inch"); + break; + case RESUNIT_CENTIMETER: + fprintf(fd, " pixels/cm"); + break; + default: + fprintf(fd, " (unit %u = 0x%x)", + td->td_resolutionunit, + td->td_resolutionunit); + break; + } + } + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_POSITION)) + fprintf(fd, " Position: %g, %g\n", + td->td_xposition, td->td_yposition); + if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) + fprintf(fd, " Bits/Sample: %u\n", td->td_bitspersample); + if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) { + fprintf(fd, " Sample Format: "); + switch (td->td_sampleformat) { + case SAMPLEFORMAT_VOID: + fprintf(fd, "void\n"); + break; + case SAMPLEFORMAT_INT: + fprintf(fd, "signed integer\n"); + break; + case SAMPLEFORMAT_UINT: + fprintf(fd, "unsigned integer\n"); + break; + case SAMPLEFORMAT_IEEEFP: + fprintf(fd, "IEEE floating point\n"); + break; + case SAMPLEFORMAT_COMPLEXINT: + fprintf(fd, "complex signed integer\n"); + break; + case SAMPLEFORMAT_COMPLEXIEEEFP: + fprintf(fd, "complex IEEE floating point\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_sampleformat, td->td_sampleformat); + break; + } + } + if (TIFFFieldSet(tif,FIELD_COMPRESSION)) { + const TIFFCodec* c = TIFFFindCODEC(td->td_compression); + fprintf(fd, " Compression Scheme: "); + if (c) + fprintf(fd, "%s\n", c->name); + else + fprintf(fd, "%u (0x%x)\n", + td->td_compression, td->td_compression); + } + if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) { + fprintf(fd, " Photometric Interpretation: "); + if (td->td_photometric < NPHOTONAMES) + fprintf(fd, "%s\n", photoNames[td->td_photometric]); + else { + switch (td->td_photometric) { + case PHOTOMETRIC_LOGL: + fprintf(fd, "CIE Log2(L)\n"); + break; + case PHOTOMETRIC_LOGLUV: + fprintf(fd, "CIE Log2(L) (u',v')\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_photometric, td->td_photometric); + break; + } + } + } + if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) { + fprintf(fd, " Extra Samples: %u<", td->td_extrasamples); + sep = ""; + for (i = 0; i < td->td_extrasamples; i++) { + switch (td->td_sampleinfo[i]) { + case EXTRASAMPLE_UNSPECIFIED: + fprintf(fd, "%sunspecified", sep); + break; + case EXTRASAMPLE_ASSOCALPHA: + fprintf(fd, "%sassoc-alpha", sep); + break; + case EXTRASAMPLE_UNASSALPHA: + fprintf(fd, "%sunassoc-alpha", sep); + break; + default: + fprintf(fd, "%s%u (0x%x)", sep, + td->td_sampleinfo[i], td->td_sampleinfo[i]); + break; + } + sep = ", "; + } + fprintf(fd, ">\n"); + } + if (TIFFFieldSet(tif,FIELD_INKNAMES)) { + char* cp; + fprintf(fd, " Ink Names: "); + i = td->td_samplesperpixel; + sep = ""; + for (cp = td->td_inknames; + i > 0 && cp < td->td_inknames + td->td_inknameslen; + cp = strchr(cp,'\0')+1, i--) { + int max_chars = + td->td_inknameslen - (cp - td->td_inknames); + fputs(sep, fd); + _TIFFprintAsciiBounded(fd, cp, max_chars); + sep = ", "; + } + fputs("\n", fd); + } + if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) { + fprintf(fd, " Thresholding: "); + switch (td->td_threshholding) { + case THRESHHOLD_BILEVEL: + fprintf(fd, "bilevel art scan\n"); + break; + case THRESHHOLD_HALFTONE: + fprintf(fd, "halftone or dithered scan\n"); + break; + case THRESHHOLD_ERRORDIFFUSE: + fprintf(fd, "error diffused\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_threshholding, td->td_threshholding); + break; + } + } + if (TIFFFieldSet(tif,FIELD_FILLORDER)) { + fprintf(fd, " FillOrder: "); + switch (td->td_fillorder) { + case FILLORDER_MSB2LSB: + fprintf(fd, "msb-to-lsb\n"); + break; + case FILLORDER_LSB2MSB: + fprintf(fd, "lsb-to-msb\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_fillorder, td->td_fillorder); + break; + } + } + if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + { + fprintf(fd, " YCbCr Subsampling: %u, %u\n", + td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] ); + } + if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) { + fprintf(fd, " YCbCr Positioning: "); + switch (td->td_ycbcrpositioning) { + case YCBCRPOSITION_CENTERED: + fprintf(fd, "centered\n"); + break; + case YCBCRPOSITION_COSITED: + fprintf(fd, "cosited\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_ycbcrpositioning, td->td_ycbcrpositioning); + break; + } + } + if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) + fprintf(fd, " Halftone Hints: light %u dark %u\n", + td->td_halftonehints[0], td->td_halftonehints[1]); + if (TIFFFieldSet(tif,FIELD_ORIENTATION)) { + fprintf(fd, " Orientation: "); + if (td->td_orientation < NORIENTNAMES) + fprintf(fd, "%s\n", orientNames[td->td_orientation]); + else + fprintf(fd, "%u (0x%x)\n", + td->td_orientation, td->td_orientation); + } + if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) + fprintf(fd, " Samples/Pixel: %u\n", td->td_samplesperpixel); + if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) { + fprintf(fd, " Rows/Strip: "); + if (td->td_rowsperstrip == (uint32) -1) + fprintf(fd, "(infinite)\n"); + else + fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip); + } + if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) + fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue); + if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) + fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue); + if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) { + int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMin Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_sminsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) { + int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMax Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_smaxsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) { + fprintf(fd, " Planar Configuration: "); + switch (td->td_planarconfig) { + case PLANARCONFIG_CONTIG: + fprintf(fd, "single image plane\n"); + break; + case PLANARCONFIG_SEPARATE: + fprintf(fd, "separate image planes\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_planarconfig, td->td_planarconfig); + break; + } + } + if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) + fprintf(fd, " Page Number: %u-%u\n", + td->td_pagenumber[0], td->td_pagenumber[1]); + if (TIFFFieldSet(tif,FIELD_COLORMAP)) { + fprintf(fd, " Color Map: "); + if (flags & TIFFPRINT_COLORMAP) { + fprintf(fd, "\n"); + n = 1L<td_bitspersample; + for (l = 0; l < n; l++) + fprintf(fd, " %5lu: %5u %5u %5u\n", + l, + td->td_colormap[0][l], + td->td_colormap[1][l], + td->td_colormap[2][l]); + } else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) { + fprintf(fd, " Reference Black/White:\n"); + for (i = 0; i < 3; i++) + fprintf(fd, " %2d: %5g %5g\n", i, + td->td_refblackwhite[2*i+0], + td->td_refblackwhite[2*i+1]); + } + if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) { + fprintf(fd, " Transfer Function: "); + if (flags & TIFFPRINT_CURVES) { + fprintf(fd, "\n"); + n = 1L<td_bitspersample; + for (l = 0; l < n; l++) { + fprintf(fd, " %2lu: %5u", + l, td->td_transferfunction[0][l]); + for (i = 1; i < td->td_samplesperpixel; i++) + fprintf(fd, " %5u", + td->td_transferfunction[i][l]); + fputc('\n', fd); + } + } else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) { + fprintf(fd, " SubIFD Offsets:"); + for (i = 0; i < td->td_nsubifd; i++) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, " %5I64u", + (unsigned __int64) td->td_subifd[i]); +#else + fprintf(fd, " %5llu", + (unsigned long long) td->td_subifd[i]); +#endif + fputc('\n', fd); + } + + /* + ** Custom tag support. + */ + { + int i; + short count; + + count = (short) TIFFGetTagListCount(tif); + for(i = 0; i < count; i++) { + uint32 tag = TIFFGetTagListEntry(tif, i); + const TIFFField *fip; + uint32 value_count; + int mem_alloc = 0; + void *raw_data; + + fip = TIFFFieldWithTag(tif, tag); + if(fip == NULL) + continue; + + if(fip->field_passcount) { + if (fip->field_readcount == TIFF_VARIABLE2 ) { + if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) + continue; + } else if (fip->field_readcount == TIFF_VARIABLE2 ) { + uint16 small_value_count; + if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1) + continue; + value_count = small_value_count; + } else { + assert (fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2); + continue; + } + } else { + if (fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2) + value_count = 1; + else if (fip->field_readcount == TIFF_SPP) + value_count = td->td_samplesperpixel; + else + value_count = fip->field_readcount; + if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + static uint16 dotrange[2]; + raw_data = dotrange; + TIFFGetField(tif, tag, dotrange+0, dotrange+1); + } else if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP + || value_count > 1) { + if(TIFFGetField(tif, tag, &raw_data) != 1) + continue; + } else { + raw_data = _TIFFmalloc( + _TIFFDataSize(fip->field_type) + * value_count); + mem_alloc = 1; + if(TIFFGetField(tif, tag, raw_data) != 1) { + _TIFFfree(raw_data); + continue; + } + } + } + + /* + * Catch the tags which needs to be specially handled + * and pretty print them. If tag not handled in + * _TIFFPrettyPrintField() fall down and print it as + * any other tag. + */ + if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) + _TIFFPrintField(fd, fip, value_count, raw_data); + + if(mem_alloc) + _TIFFfree(raw_data); + } + } + + if (tif->tif_tagmethods.printdir) + (*tif->tif_tagmethods.printdir)(tif, fd, flags); + + _TIFFFillStriles( tif ); + + if ((flags & TIFFPRINT_STRIPS) && + TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) { + uint32 s; + + fprintf(fd, " %lu %s:\n", + (long) td->td_nstrips, + isTiled(tif) ? "Tiles" : "Strips"); + for (s = 0; s < td->td_nstrips; s++) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, " %3lu: [%8I64u, %8I64u]\n", + (unsigned long) s, + (unsigned __int64) td->td_stripoffset[s], + (unsigned __int64) td->td_stripbytecount[s]); +#else + fprintf(fd, " %3lu: [%8llu, %8llu]\n", + (unsigned long) s, + (unsigned long long) td->td_stripoffset[s], + (unsigned long long) td->td_stripbytecount[s]); +#endif + } +} + +void +_TIFFprintAscii(FILE* fd, const char* cp) +{ + _TIFFprintAsciiBounded( fd, cp, strlen(cp)); +} + +static void +_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars) +{ + for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) { + const char* tp; + + if (isprint((int)*cp)) { + fputc(*cp, fd); + continue; + } + for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) + if (*tp++ == *cp) + break; + if (*tp) + fprintf(fd, "\\%c", *tp); + else + fprintf(fd, "\\%03o", *cp & 0xff); + } +} + +void +_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value) +{ + fprintf(fd, " %s: \"", name); + _TIFFprintAscii(fd, value); + fprintf(fd, "\"\n"); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_read.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_read.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_read.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_read.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1083 @@ +/* $Id: tif_read.c,v 1.40 2012-06-01 00:55:09 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * Scanline-oriented Read Support + */ +#include "tiffiop.h" +#include + +int TIFFFillStrip(TIFF* tif, uint32 strip); +int TIFFFillTile(TIFF* tif, uint32 tile); +static int TIFFStartStrip(TIFF* tif, uint32 strip); +static int TIFFStartTile(TIFF* tif, uint32 tile); +static int TIFFCheckRead(TIFF*, int); +static tmsize_t +TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module); + +#define NOSTRIP ((uint32)(-1)) /* undefined state */ +#define NOTILE ((uint32)(-1)) /* undefined state */ + +static int +TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) +{ + static const char module[] = "TIFFFillStripPartial"; + register TIFFDirectory *td = &tif->tif_dir; + uint64 unused_data; + uint64 read_offset; + tmsize_t cc, to_read; + tmsize_t bytecountm; + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + + bytecountm=(tmsize_t) td->td_stripbytecount[strip]; + if (read_ahead*2 > tif->tif_rawdatasize) { + assert( restart ); + + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold part of strip %lu", + (unsigned long) strip); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, read_ahead*2)) + return (0); + } + + if( restart ) + { + tif->tif_rawdataloaded = 0; + tif->tif_rawdataoff = 0; + } + + /* + ** If we are reading more data, move any unused data to the + ** start of the buffer. + */ + if( tif->tif_rawdataloaded > 0 ) + unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); + else + unused_data = 0; + + if( unused_data > 0 ) + { + assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); + memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data ); + } + + /* + ** Seek to the point in the file where more data should be read. + */ + read_offset = td->td_stripoffset[strip] + + tif->tif_rawdataoff + tif->tif_rawdataloaded; + + if (!SeekOK(tif, read_offset)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at scanline %lu, strip %lu", + (unsigned long) tif->tif_row, (unsigned long) strip); + return 0; + } + + /* + ** How much do we want to read? + */ + to_read = tif->tif_rawdatasize - unused_data; + if( (uint64) to_read > td->td_stripbytecount[strip] + - tif->tif_rawdataoff - tif->tif_rawdataloaded ) + { + to_read = td->td_stripbytecount[strip] + - tif->tif_rawdataoff - tif->tif_rawdataloaded; + } + + assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); + cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read); + + if (cc != to_read) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned __int64) cc, + (unsigned __int64) to_read); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long long) cc, + (unsigned long long) to_read); +#endif + return 0; + } + + tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ; + tif->tif_rawdataloaded = unused_data + to_read; + + tif->tif_rawcp = tif->tif_rawdata; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) { + assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); + TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); + } + + /* + ** When starting a strip from the beginning we need to + ** restart the decoder. + */ + if( restart ) + return TIFFStartStrip(tif, strip); + else + return 1; +} + +/* + * Seek to a random row+sample in a file. + * + * Only used by TIFFReadScanline, and is only used on + * strip organized files. We do some tricky stuff to try + * and avoid reading the whole compressed raw data for big + * strips. + */ +static int +TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) +{ + register TIFFDirectory *td = &tif->tif_dir; + uint32 strip; + int whole_strip; + tmsize_t read_ahead = 0; + + /* + ** Establish what strip we are working from. + */ + if (row >= td->td_imagelength) { /* out of range */ + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Row out of range, max %lu", + (unsigned long) row, + (unsigned long) td->td_imagelength); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Sample out of range, max %lu", + (unsigned long) sample, (unsigned long) td->td_samplesperpixel); + return (0); + } + strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip; + } else + strip = row / td->td_rowsperstrip; + + /* + * Do we want to treat this strip as one whole chunk or + * read it a few lines at a time? + */ +#if defined(CHUNKY_STRIP_READ_SUPPORT) + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 + || isMapped(tif); +#else + whole_strip = 1; +#endif + + if( !whole_strip ) + { + read_ahead = tif->tif_scanlinesize * 16 + 5000; + } + + /* + * If we haven't loaded this strip, do so now, possibly + * only reading the first part. + */ + if (strip != tif->tif_curstrip) { /* different strip, refill */ + + if( whole_strip ) + { + if (!TIFFFillStrip(tif, strip)) + return (0); + } + else + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) + return 0; + } + } + + /* + ** If we already have some data loaded, do we need to read some more? + */ + else if( !whole_strip ) + { + if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead + && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] ) + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) + return 0; + } + } + + if (row < tif->tif_row) { + /* + * Moving backwards within the same strip: backup + * to the start and then decode forward (below). + * + * NB: If you're planning on lots of random access within a + * strip, it's better to just read and decode the entire + * strip, and then access the decoded data in a random fashion. + */ + + if( tif->tif_rawdataoff != 0 ) + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) + return 0; + } + else + { + if (!TIFFStartStrip(tif, strip)) + return (0); + } + } + + if (row != tif->tif_row) { + /* + * Seek forward to the desired row. + */ + + /* TODO: Will this really work with partial buffers? */ + + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (0); + tif->tif_row = row; + } + + return (1); +} + +int +TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) +{ + int e; + + if (!TIFFCheckRead(tif, 0)) + return (-1); + if( (e = TIFFSeek(tif, row, sample)) != 0) { + /* + * Decompress desired row into user buffer. + */ + e = (*tif->tif_decoderow) + (tif, (uint8*) buf, tif->tif_scanlinesize, sample); + + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; + + if (e) + (*tif->tif_postdecode)(tif, (uint8*) buf, + tif->tif_scanlinesize); + } + return (e > 0 ? 1 : -1); +} + +/* + * Read a strip of data and decompress the specified + * amount into the user-supplied buffer. + */ +tmsize_t +TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +{ + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32 rowsperstrip; + uint32 stripsperplane; + uint32 stripinplane; + uint16 plane; + uint32 rows; + tmsize_t stripsize; + if (!TIFFCheckRead(tif,0)) + return((tmsize_t)(-1)); + if (strip>=td->td_nstrips) + { + TIFFErrorExt(tif->tif_clientdata,module, + "%lu: Strip out of range, max %lu",(unsigned long)strip, + (unsigned long)td->td_nstrips); + return((tmsize_t)(-1)); + } + /* + * Calculate the strip size according to the number of + * rows in the strip (check for truncated last strip on any + * of the separations). + */ + rowsperstrip=td->td_rowsperstrip; + if (rowsperstrip>td->td_imagelength) + rowsperstrip=td->td_imagelength; + stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip); + stripinplane=(strip%stripsperplane); + plane=(strip/stripsperplane); + rows=td->td_imagelength-stripinplane*rowsperstrip; + if (rows>rowsperstrip) + rows=rowsperstrip; + stripsize=TIFFVStripSize(tif,rows); + if (stripsize==0) + return((tmsize_t)(-1)); + if ((size!=(tmsize_t)(-1))&&(sizetif_decodestrip)(tif,buf,stripsize,plane)<=0) + return((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif,buf,stripsize); + return(stripsize); +} + +static tmsize_t +TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, + const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif )) + return ((tmsize_t)(-1)); + + assert((tif->tif_flags&TIFF_NOREADRAW)==0); + if (!isMapped(tif)) { + tmsize_t cc; + + if (!SeekOK(tif, td->td_stripoffset[strip])) { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at scanline %lu, strip %lu", + (unsigned long) tif->tif_row, (unsigned long) strip); + return ((tmsize_t)(-1)); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned __int64) cc, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long long) cc, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); + } + } else { + tmsize_t ma,mb; + tmsize_t n; + ma=(tmsize_t)td->td_stripoffset[strip]; + mb=ma+size; + if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size)) + n=0; + else if ((mbtif->tif_size)) + n=tif->tif_size-ma; + else + n=size; + if (n!=size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) strip, + (unsigned __int64) n, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) strip, + (unsigned long long) n, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); + } + _TIFFmemcpy(buf, tif->tif_base + ma, + size); + } + return (size); +} + +/* + * Read a strip of data from the file. + */ +tmsize_t +TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +{ + static const char module[] = "TIFFReadRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64 bytecount; + tmsize_t bytecountm; + + if (!TIFFCheckRead(tif, 0)) + return ((tmsize_t)(-1)); + if (strip >= td->td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Strip out of range, max %lu", + (unsigned long) strip, + (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags&TIFF_NOREADRAW) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Compression scheme does not support access to raw uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount = td->td_stripbytecount[strip]; + if (bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid strip byte count, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid strip byte count, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + return ((tmsize_t)(-1)); + } + bytecountm = (tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) { + TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow"); + return ((tmsize_t)(-1)); + } + if (size != (tmsize_t)(-1) && size < bytecountm) + bytecountm = size; + return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); +} + +/* + * Read the specified strip and setup for decoding. The data buffer is + * expanded, as necessary, to hold the strip's data. + */ +int +TIFFFillStrip(TIFF* tif, uint32 strip) +{ + static const char module[] = "TIFFFillStrip"; + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + if ((tif->tif_flags&TIFF_NOREADRAW)==0) + { + uint64 bytecount = td->td_stripbytecount[strip]; + if (bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid strip byte count %I64u, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid strip byte count %llu, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + return (0); + } + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) + || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * td->td_stripoffset[strip]+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) { + /* + * This error message might seem strange, but + * it's what would happen if a read were done + * instead. + */ +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + + "Read error on strip %lu; " + "got %I64u bytes, expected %I64u", + (unsigned long) strip, + (unsigned __int64) tif->tif_size - td->td_stripoffset[strip], + (unsigned __int64) bytecount); +#else + TIFFErrorExt(tif->tif_clientdata, module, + + "Read error on strip %lu; " + "got %llu bytes, expected %llu", + (unsigned long) strip, + (unsigned long long) tif->tif_size - td->td_stripoffset[strip], + (unsigned long long) bytecount); +#endif + tif->tif_curstrip = NOSTRIP; + return (0); + } + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t) bytecount; + + /* + * When we have tif_rawdata reference directly into the memory mapped file + * we need to be pretty careful about how we use the rawdata. It is not + * a general purpose working buffer as it normally otherwise is. So we + * keep track of this fact to avoid using it improperly. + */ + tif->tif_flags |= TIFF_BUFFERMMAP; + } else { + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm=(tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return(0); + } + if (bytecountm > tif->tif_rawdatasize) { + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold strip %lu", + (unsigned long) strip); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + if (tif->tif_flags&TIFF_BUFFERMMAP) { + tif->tif_curstrip = NOSTRIP; + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, + bytecountm, module) != bytecountm) + return (0); + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, bytecountm); + } + } + return (TIFFStartStrip(tif, strip)); +} + +/* + * Tile-oriented Read Support + * Contributed by Nancy Cam (Silicon Graphics). + */ + +/* + * Read and decompress a tile of data. The + * tile is selected by the (x,y,z,s) coordinates. + */ +tmsize_t +TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) +{ + if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + return (TIFFReadEncodedTile(tif, + TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); +} + +/* + * Read a tile of data and decompress the specified + * amount into the user-supplied buffer. + */ +tmsize_t +TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) +{ + static const char module[] = "TIFFReadEncodedTile"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t tilesize = tif->tif_tilesize; + + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Tile out of range, max %lu", + (unsigned long) tile, (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (size == (tmsize_t)(-1)) + size = tilesize; + else if (size > tilesize) + size = tilesize; + if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, + (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) { + (*tif->tif_postdecode)(tif, (uint8*) buf, size); + return (size); + } else + return ((tmsize_t)(-1)); +} + +static tmsize_t +TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif )) + return ((tmsize_t)(-1)); + + assert((tif->tif_flags&TIFF_NOREADRAW)==0); + if (!isMapped(tif)) { + tmsize_t cc; + + if (!SeekOK(tif, td->td_stripoffset[tile])) { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at row %lu, col %lu, tile %lu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) tile); + return ((tmsize_t)(-1)); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned __int64) cc, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at row %lu, col %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long long) cc, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); + } + } else { + tmsize_t ma,mb; + tmsize_t n; + ma=(tmsize_t)td->td_stripoffset[tile]; + mb=ma+size; + if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size)) + n=0; + else if ((mbtif->tif_size)) + n=tif->tif_size-ma; + else + n=size; + if (n!=size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, +"Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) tile, + (unsigned __int64) n, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, +"Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) tile, + (unsigned long long) n, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); + } + _TIFFmemcpy(buf, tif->tif_base + ma, size); + } + return (size); +} + +/* + * Read a tile of data from the file. + */ +tmsize_t +TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) +{ + static const char module[] = "TIFFReadRawTile"; + TIFFDirectory *td = &tif->tif_dir; + uint64 bytecount64; + tmsize_t bytecountm; + + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Tile out of range, max %lu", + (unsigned long) tile, (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags&TIFF_NOREADRAW) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Compression scheme does not support access to raw uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount64 = td->td_stripbytecount[tile]; + if (size != (tmsize_t)(-1) && (uint64)size < bytecount64) + bytecount64 = (uint64)size; + bytecountm = (tmsize_t)bytecount64; + if ((uint64)bytecountm!=bytecount64) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return ((tmsize_t)(-1)); + } + return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); +} + +/* + * Read the specified tile and setup for decoding. The data buffer is + * expanded, as necessary, to hold the tile's data. + */ +int +TIFFFillTile(TIFF* tif, uint32 tile) +{ + static const char module[] = "TIFFFillTile"; + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + if ((tif->tif_flags&TIFF_NOREADRAW)==0) + { + uint64 bytecount = td->td_stripbytecount[tile]; + if (bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid tile byte count, tile %lu", + (unsigned __int64) bytecount, + (unsigned long) tile); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid tile byte count, tile %lu", + (unsigned long long) bytecount, + (unsigned long) tile); +#endif + return (0); + } + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) + || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * td->td_stripoffset[tile]+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { + tif->tif_curtile = NOTILE; + return (0); + } + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = + tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t) bytecount; + tif->tif_flags |= TIFF_BUFFERMMAP; + } else { + /* + * Expand raw data buffer, if needed, to hold data + * tile coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm=(tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return(0); + } + if (bytecountm > tif->tif_rawdatasize) { + tif->tif_curtile = NOTILE; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold tile %lu", + (unsigned long) tile); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + if (tif->tif_flags&TIFF_BUFFERMMAP) { + tif->tif_curtile = NOTILE; + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + + if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, + bytecountm, module) != bytecountm) + return (0); + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, + tif->tif_rawdataloaded); + } + } + return (TIFFStartTile(tif, tile)); +} + +/* + * Setup the raw data buffer in preparation for + * reading a strip of raw data. If the buffer + * is specified as zero, then a buffer of appropriate + * size is allocated by the library. Otherwise, + * the client must guarantee that the buffer is + * large enough to hold any individual strip of + * raw data. + */ +int +TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) +{ + static const char module[] = "TIFFReadBufferSetup"; + + assert((tif->tif_flags&TIFF_NOREADRAW)==0); + tif->tif_flags &= ~TIFF_BUFFERMMAP; + + if (tif->tif_rawdata) { + if (tif->tif_flags & TIFF_MYBUFFER) + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + if (bp) { + tif->tif_rawdatasize = size; + tif->tif_rawdata = (uint8*) bp; + tif->tif_flags &= ~TIFF_MYBUFFER; + } else { + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024); + if (tif->tif_rawdatasize==0) + tif->tif_rawdatasize=(tmsize_t)(-1); + tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); + tif->tif_flags |= TIFF_MYBUFFER; + } + if (tif->tif_rawdata == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for data buffer at scanline %lu", + (unsigned long) tif->tif_row); + tif->tif_rawdatasize = 0; + return (0); + } + return (1); +} + +/* + * Set state to appear as if a + * strip has just been read in. + */ +static int +TIFFStartStrip(TIFF* tif, uint32 strip) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_flags &= ~TIFF_BUF4WRITE; + + if (tif->tif_flags&TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; + } + return ((*tif->tif_predecode)(tif, + (uint16)(strip / td->td_stripsperimage))); +} + +/* + * Set state to appear as if a + * tile has just been read in. + */ +static int +TIFFStartTile(TIFF* tif, uint32 tile) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curtile = tile; + tif->tif_row = + (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) * + td->td_tilelength; + tif->tif_col = + (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) * + td->td_tilewidth; + tif->tif_flags &= ~TIFF_BUF4WRITE; + if (tif->tif_flags&TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; + } + return ((*tif->tif_predecode)(tif, + (uint16)(tile/td->td_stripsperimage))); +} + +static int +TIFFCheckRead(TIFF* tif, int tiles) +{ + if (tif->tif_mode == O_WRONLY) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading"); + return (0); + } + if (tiles ^ isTiled(tif)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? + "Can not read tiles from a stripped image" : + "Can not read scanlines from a tiled image"); + return (0); + } + return (1); +} + +void +_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) +{ + (void) tif; (void) buf; (void) cc; +} + +void +_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc) +{ + (void) tif; + assert((cc & 1) == 0); + TIFFSwabArrayOfShort((uint16*) buf, cc/2); +} + +void +_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc) +{ + (void) tif; + assert((cc % 3) == 0); + TIFFSwabArrayOfTriples((uint8*) buf, cc/3); +} + +void +_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc) +{ + (void) tif; + assert((cc & 3) == 0); + TIFFSwabArrayOfLong((uint32*) buf, cc/4); +} + +void +_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc) +{ + (void) tif; + assert((cc & 7) == 0); + TIFFSwabArrayOfDouble((double*) buf, cc/8); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_stream.cxx diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_stream.cxx --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_stream.cxx 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_stream.cxx 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,426 @@ +/* $Id: tif_stream.cxx,v 1.11 2010-12-11 23:12:29 faxguy Exp $ */ + +/* + * Copyright (c) 1988-1996 Sam Leffler + * Copyright (c) 1991-1996 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library UNIX-specific Routines. + */ +#include "tiffiop.h" +#include "tiffio.hxx" +#include + +#ifndef __VMS +using namespace std; +#endif + +/* + ISO C++ uses a 'std::streamsize' type to define counts. This makes + it similar to, (but perhaps not the same as) size_t. + + The std::ios::pos_type is used to represent stream positions as used + by tellg(), tellp(), seekg(), and seekp(). This makes it similar to + (but perhaps not the same as) 'off_t'. The std::ios::streampos type + is used for character streams, but is documented to not be an + integral type anymore, so it should *not* be assigned to an integral + type. + + The std::ios::off_type is used to specify relative offsets needed by + the variants of seekg() and seekp() which accept a relative offset + argument. + + Useful prototype knowledge: + + Obtain read position + ios::pos_type basic_istream::tellg() + + Set read position + basic_istream& basic_istream::seekg(ios::pos_type) + basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir) + + Read data + basic_istream& istream::read(char *str, streamsize count) + + Number of characters read in last unformatted read + streamsize istream::gcount(); + + Obtain write position + ios::pos_type basic_ostream::tellp() + + Set write position + basic_ostream& basic_ostream::seekp(ios::pos_type) + basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir) + + Write data + basic_ostream& ostream::write(const char *str, streamsize count) +*/ + +struct tiffis_data; +struct tiffos_data; + +extern "C" { + + static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t); + static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size); + static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size); + static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t); + static uint64 _tiffosSeekProc(thandle_t fd, uint64 off, int whence); + static uint64 _tiffisSeekProc(thandle_t fd, uint64 off, int whence); + static uint64 _tiffosSizeProc(thandle_t fd); + static uint64 _tiffisSizeProc(thandle_t fd); + static int _tiffosCloseProc(thandle_t fd); + static int _tiffisCloseProc(thandle_t fd); + static int _tiffDummyMapProc(thandle_t , void** base, toff_t* size ); + static void _tiffDummyUnmapProc(thandle_t , void* base, toff_t size ); + static TIFF* _tiffStreamOpen(const char* name, const char* mode, void *fd); + +struct tiffis_data +{ + istream *stream; + ios::pos_type start_pos; +}; + +struct tiffos_data +{ + ostream *stream; + ios::pos_type start_pos; +}; + +static tmsize_t +_tiffosReadProc(thandle_t, void*, tmsize_t) +{ + return 0; +} + +static tmsize_t +_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size) +{ + tiffis_data *data = reinterpret_cast(fd); + + // Verify that type does not overflow. + streamsize request_size = size; + if (static_cast(request_size) != size) + return static_cast(-1); + + data->stream->read((char *) buf, request_size); + + return static_cast(data->stream->gcount()); +} + +static tmsize_t +_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size) +{ + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); + + // Verify that type does not overflow. + streamsize request_size = size; + if (static_cast(request_size) != size) + return static_cast(-1); + + os->write(reinterpret_cast(buf), request_size); + + return static_cast(os->tellp() - pos); +} + +static tmsize_t +_tiffisWriteProc(thandle_t, void*, tmsize_t) +{ + return 0; +} + +static uint64 +_tiffosSeekProc(thandle_t fd, uint64 off, int whence) +{ + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + + // if the stream has already failed, don't do anything + if( os->fail() ) + return static_cast(-1); + + switch(whence) { + case SEEK_SET: + { + // Compute 64-bit offset + uint64 new_offset = static_cast(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); + + os->seekp(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + os->seekp(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + os->seekp(offset, ios::end); + break; + } + } + + // Attempt to workaround problems with seeking past the end of the + // stream. ofstream doesn't have a problem with this but + // ostrstream/ostringstream does. In that situation, add intermediate + // '\0' characters. + if( os->fail() ) { +#ifdef __VMS + int old_state; +#else + ios::iostate old_state; +#endif + ios::pos_type origin; + + old_state = os->rdstate(); + // reset the fail bit or else tellp() won't work below + os->clear(os->rdstate() & ~ios::failbit); + switch( whence ) { + case SEEK_SET: + default: + origin = data->start_pos; + break; + case SEEK_CUR: + origin = os->tellp(); + break; + case SEEK_END: + os->seekp(0, ios::end); + origin = os->tellp(); + break; + } + // restore original stream state + os->clear(old_state); + + // only do something if desired seek position is valid + if( (static_cast(origin) + off) > static_cast(data->start_pos) ) { + uint64 num_fill; + + // clear the fail bit + os->clear(os->rdstate() & ~ios::failbit); + + // extend the stream to the expected size + os->seekp(0, ios::end); + num_fill = (static_cast(origin)) + off - os->tellp(); + for( uint64 i = 0; i < num_fill; i++ ) + os->put('\0'); + + // retry the seek + os->seekp(static_cast(static_cast(origin) + off), ios::beg); + } + } + + return static_cast(os->tellp()); +} + +static uint64 +_tiffisSeekProc(thandle_t fd, uint64 off, int whence) +{ + tiffis_data *data = reinterpret_cast(fd); + + switch(whence) { + case SEEK_SET: + { + // Compute 64-bit offset + uint64 new_offset = static_cast(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); + + data->stream->seekg(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + data->stream->seekg(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + data->stream->seekg(offset, ios::end); + break; + } + } + + return (uint64) (data->stream->tellg() - data->start_pos); +} + +static uint64 +_tiffosSizeProc(thandle_t fd) +{ + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); + ios::pos_type len; + + os->seekp(0, ios::end); + len = os->tellp(); + os->seekp(pos); + + return (uint64) len; +} + +static uint64 +_tiffisSizeProc(thandle_t fd) +{ + tiffis_data *data = reinterpret_cast(fd); + ios::pos_type pos = data->stream->tellg(); + ios::pos_type len; + + data->stream->seekg(0, ios::end); + len = data->stream->tellg(); + data->stream->seekg(pos); + + return (uint64) len; +} + +static int +_tiffosCloseProc(thandle_t fd) +{ + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast(fd); + return 0; +} + +static int +_tiffisCloseProc(thandle_t fd) +{ + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast(fd); + return 0; +} + +static int +_tiffDummyMapProc(thandle_t , void** base, toff_t* size ) +{ + return (0); +} + +static void +_tiffDummyUnmapProc(thandle_t , void* base, toff_t size ) +{ +} + +/* + * Open a TIFF file descriptor for read/writing. + */ +static TIFF* +_tiffStreamOpen(const char* name, const char* mode, void *fd) +{ + TIFF* tif; + + if( strchr(mode, 'w') ) { + tiffos_data *data = new tiffos_data; + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellp(); + + // Open for writing. + tif = TIFFClientOpen(name, mode, + reinterpret_cast(data), + _tiffosReadProc, + _tiffosWriteProc, + _tiffosSeekProc, + _tiffosCloseProc, + _tiffosSizeProc, + _tiffDummyMapProc, + _tiffDummyUnmapProc); + } else { + tiffis_data *data = new tiffis_data; + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellg(); + // Open for reading. + tif = TIFFClientOpen(name, mode, + reinterpret_cast(data), + _tiffisReadProc, + _tiffisWriteProc, + _tiffisSeekProc, + _tiffisCloseProc, + _tiffisSizeProc, + _tiffDummyMapProc, + _tiffDummyUnmapProc); + } + + return (tif); +} + +} /* extern "C" */ + +TIFF* +TIFFStreamOpen(const char* name, ostream *os) +{ + // If os is either a ostrstream or ostringstream, and has no data + // written to it yet, then tellp() will return -1 which will break us. + // We workaround this by writing out a dummy character and + // then seek back to the beginning. + if( !os->fail() && static_cast(os->tellp()) < 0 ) { + *os << '\0'; + os->seekp(0); + } + + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "wm", os); +} + +TIFF* +TIFFStreamOpen(const char* name, istream *is) +{ + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "rm", is); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + Local Variables: + mode: c + indent-tabs-mode: true + c-basic-offset: 8 + End: +*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_strip.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_strip.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_strip.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_strip.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,383 @@ +/* $Id: tif_strip.c,v 1.35 2012-06-06 05:33:55 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Strip-organized Image Support Routines. + */ +#include "tiffiop.h" + +/* + * Compute which strip a (row,sample) value is in. + */ +uint32 +TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample) +{ + static const char module[] = "TIFFComputeStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32 strip; + + strip = row / td->td_rowsperstrip; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Sample out of range, max %lu", + (unsigned long) sample, (unsigned long) td->td_samplesperpixel); + return (0); + } + strip += (uint32)sample*td->td_stripsperimage; + } + return (strip); +} + +/* + * Compute how many strips are in an image. + */ +uint32 +TIFFNumberOfStrips(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 nstrips; + + nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel, + "TIFFNumberOfStrips"); + return (nstrips); +} + +/* + * Compute the # bytes in a variable height, row-aligned strip. + */ +uint64 +TIFFVStripSize64(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVStripSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (nrows==(uint32)(-1)) + nrows=td->td_imagelength; + if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& + (td->td_photometric == PHOTOMETRIC_YCBCR)&& + (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16 ycbcrsubsampling[2]; + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint32 samplingblocks_ver; + uint64 samplingrow_samples; + uint64 samplingrow_size; + if(td->td_samplesperpixel!=3) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid td_samplesperpixel value"); + return 0; + } + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, + ycbcrsubsampling+1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) + ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], + ycbcrsubsampling[1] ); + return 0; + } + samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); + samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); + samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); + return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); + } + else + return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module)); +} +tmsize_t +TIFFVStripSize(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVStripSize"; + uint64 m; + tmsize_t n; + m=TIFFVStripSize64(tif,nrows); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); +} + +/* + * Compute the # bytes in a raw strip. + */ +uint64 +TIFFRawStripSize64(TIFF* tif, uint32 strip) +{ + static const char module[] = "TIFFRawStripSize64"; + TIFFDirectory* td = &tif->tif_dir; + uint64 bytecount = td->td_stripbytecount[strip]; + + if (bytecount == 0) + { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid strip byte count, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid strip byte count, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + bytecount = (uint64) -1; + } + + return bytecount; +} +tmsize_t +TIFFRawStripSize(TIFF* tif, uint32 strip) +{ + static const char module[] = "TIFFRawStripSize"; + uint64 m; + tmsize_t n; + m=TIFFRawStripSize64(tif,strip); + if (m==(uint64)(-1)) + n=(tmsize_t)(-1); + else + { + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + } + return(n); +} + +/* + * Compute the # bytes in a (row-aligned) strip. + * + * Note that if RowsPerStrip is larger than the + * recorded ImageLength, then the strip size is + * truncated to reflect the actual space required + * to hold the strip. + */ +uint64 +TIFFStripSize64(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + uint32 rps = td->td_rowsperstrip; + if (rps > td->td_imagelength) + rps = td->td_imagelength; + return (TIFFVStripSize64(tif, rps)); +} +tmsize_t +TIFFStripSize(TIFF* tif) +{ + static const char module[] = "TIFFStripSize"; + uint64 m; + tmsize_t n; + m=TIFFStripSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); +} + +/* + * Compute a default strip size based on the image + * characteristics and a requested value. If the + * request is <1 then we choose a strip size according + * to certain heuristics. + */ +uint32 +TIFFDefaultStripSize(TIFF* tif, uint32 request) +{ + return (*tif->tif_defstripsize)(tif, request); +} + +uint32 +_TIFFDefaultStripSize(TIFF* tif, uint32 s) +{ + if ((int32) s < 1) { + /* + * If RowsPerStrip is unspecified, try to break the + * image up into strips that are approximately + * STRIP_SIZE_DEFAULT bytes long. + */ + uint64 scanlinesize; + uint64 rows; + scanlinesize=TIFFScanlineSize64(tif); + if (scanlinesize==0) + scanlinesize=1; + rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize; + if (rows==0) + rows=1; + else if (rows>0xFFFFFFFF) + rows=0xFFFFFFFF; + s=(uint32)rows; + } + return (s); +} + +/* + * Return the number of bytes to read/write in a call to + * one of the scanline-oriented i/o routines. Note that + * this number may be 1/samples-per-pixel if data is + * stored as separate planes. + * The ScanlineSize in case of YCbCrSubsampling is defined as the + * strip size divided by the strip height, i.e. the size of a pack of vertical + * subsampling lines divided by vertical subsampling. It should thus make + * sense when multiplied by a multiple of vertical subsampling. + */ +uint64 +TIFFScanlineSize64(TIFF* tif) +{ + static const char module[] = "TIFFScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64 scanline_size; + if (td->td_planarconfig==PLANARCONFIG_CONTIG) + { + if ((td->td_photometric==PHOTOMETRIC_YCBCR)&& + (td->td_samplesperpixel==3)&& + (!isUpSampled(tif))) + { + uint16 ycbcrsubsampling[2]; + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint64 samplingrow_samples; + uint64 samplingrow_size; + if(td->td_samplesperpixel!=3) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid td_samplesperpixel value"); + return 0; + } + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling+0, + ycbcrsubsampling+1); + if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || + ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling"); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); + samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8); + scanline_size = (samplingrow_size/ycbcrsubsampling[1]); + } + else + { + uint64 scanline_samples; + scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module); + scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8); + } + } + else + scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8); + return(scanline_size); +} +tmsize_t +TIFFScanlineSize(TIFF* tif) +{ + static const char module[] = "TIFFScanlineSize"; + uint64 m; + tmsize_t n; + m=TIFFScanlineSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); +} + +/* + * Return the number of bytes required to store a complete + * decoded and packed raster scanline (as opposed to the + * I/O size returned by TIFFScanlineSize which may be less + * if data is store as separate planes). + */ +uint64 +TIFFRasterScanlineSize64(TIFF* tif) +{ + static const char module[] = "TIFFRasterScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64 scanline; + + scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); + return (TIFFhowmany8_64(scanline)); + } else + return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), + td->td_samplesperpixel, module)); +} +tmsize_t +TIFFRasterScanlineSize(TIFF* tif) +{ + static const char module[] = "TIFFRasterScanlineSize"; + uint64 m; + tmsize_t n; + m=TIFFRasterScanlineSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_swab.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_swab.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_swab.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_swab.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,310 @@ +/* $Id: tif_swab.c,v 1.13 2010-03-10 18:56:49 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Bit & Byte Swapping Support. + * + * XXX We assume short = 16-bits and long = 32-bits XXX + */ +#include "tiffiop.h" + +#ifndef TIFFSwabShort +void +TIFFSwabShort(uint16* wp) +{ + register unsigned char* cp = (unsigned char*) wp; + unsigned char t; + assert(sizeof(uint16)==2); + t = cp[1]; cp[1] = cp[0]; cp[0] = t; +} +#endif + +#ifndef TIFFSwabLong +void +TIFFSwabLong(uint32* lp) +{ + register unsigned char* cp = (unsigned char*) lp; + unsigned char t; + assert(sizeof(uint32)==4); + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; +} +#endif + +#ifndef TIFFSwabLong8 +void +TIFFSwabLong8(uint64* lp) +{ + register unsigned char* cp = (unsigned char*) lp; + unsigned char t; + assert(sizeof(uint64)==8); + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; +} +#endif + +#ifndef TIFFSwabArrayOfShort +void +TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n) +{ + register unsigned char* cp; + register unsigned char t; + assert(sizeof(uint16)==2); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char*) wp; + t = cp[1]; cp[1] = cp[0]; cp[0] = t; + wp++; + } +} +#endif + +#ifndef TIFFSwabArrayOfTriples +void +TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n) +{ + unsigned char* cp; + unsigned char t; + + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char*) tp; + t = cp[2]; cp[2] = cp[0]; cp[0] = t; + tp += 3; + } +} +#endif + +#ifndef TIFFSwabArrayOfLong +void +TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint32)==4); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)lp; + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; + lp++; + } +} +#endif + +#ifndef TIFFSwabArrayOfLong8 +void +TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint64)==8); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)lp; + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; + lp++; + } +} +#endif + +#ifndef TIFFSwabFloat +void +TIFFSwabFloat(float* fp) +{ + register unsigned char* cp = (unsigned char*) fp; + unsigned char t; + assert(sizeof(float)==4); + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; +} +#endif + +#ifndef TIFFSwabArrayOfFloat +void +TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(float)==4); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)fp; + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; + fp++; + } +} +#endif + +#ifndef TIFFSwabDouble +void +TIFFSwabDouble(double *dp) +{ + register unsigned char* cp = (unsigned char*) dp; + unsigned char t; + assert(sizeof(double)==8); + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; +} +#endif + +#ifndef TIFFSwabArrayOfDouble +void +TIFFSwabArrayOfDouble(double* dp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(double)==8); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)dp; + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; + dp++; + } +} +#endif + +/* + * Bit reversal tables. TIFFBitRevTable[] gives + * the bit reversed value of . Used in various + * places in the library when the FillOrder requires + * bit reversal of byte values (e.g. CCITT Fax 3 + * encoding/decoding). TIFFNoBitRevTable is provided + * for algorithms that want an equivalent table that + * do not reverse bit values. + */ +static const unsigned char TIFFBitRevTable[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 const unsigned char TIFFNoBitRevTable[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const unsigned char* +TIFFGetBitRevTable(int reversed) +{ + return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); +} + +void +TIFFReverseBits(uint8* cp, tmsize_t n) +{ + for (; n > 8; n -= 8) { + cp[0] = TIFFBitRevTable[cp[0]]; + cp[1] = TIFFBitRevTable[cp[1]]; + cp[2] = TIFFBitRevTable[cp[2]]; + cp[3] = TIFFBitRevTable[cp[3]]; + cp[4] = TIFFBitRevTable[cp[4]]; + cp[5] = TIFFBitRevTable[cp[5]]; + cp[6] = TIFFBitRevTable[cp[6]]; + cp[7] = TIFFBitRevTable[cp[7]]; + cp += 8; + } + while (n-- > 0) + *cp = TIFFBitRevTable[*cp], cp++; +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_thunder.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_thunder.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_thunder.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_thunder.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,207 @@ +/* $Id: tif_thunder.c,v 1.12 2011-04-02 20:54:09 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#include +#ifdef THUNDER_SUPPORT +/* + * TIFF Library. + * + * ThunderScan 4-bit Compression Algorithm Support + */ + +/* + * ThunderScan uses an encoding scheme designed for + * 4-bit pixel values. Data is encoded in bytes, with + * each byte split into a 2-bit code word and a 6-bit + * data value. The encoding gives raw data, runs of + * pixels, or pixel values encoded as a delta from the + * previous pixel value. For the latter, either 2-bit + * or 3-bit delta values are used, with the deltas packed + * into a single byte. + */ +#define THUNDER_DATA 0x3f /* mask for 6-bit data */ +#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ +/* code values */ +#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ +#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ +#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ +#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ +#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ +#define THUNDER_RAW 0xc0 /* raw data encoded */ + +static const int twobitdeltas[4] = { 0, 1, 0, -1 }; +static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; + +#define SETPIXEL(op, v) { \ + lastpixel = (v) & 0xf; \ + if ( npixels < maxpixels ) \ + { \ + if (npixels++ & 1) \ + *op++ |= lastpixel; \ + else \ + op[0] = (uint8) (lastpixel << 4); \ + } \ +} + +static int +ThunderSetupDecode(TIFF* tif) +{ + static const char module[] = "ThunderSetupDecode"; + + if( tif->tif_dir.td_bitspersample != 4 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.", + (int) tif->tif_dir.td_bitspersample ); + return 0; + } + + + return (1); +} + +static int +ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels) +{ + static const char module[] = "ThunderDecode"; + register unsigned char *bp; + register tmsize_t cc; + unsigned int lastpixel; + tmsize_t npixels; + + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + lastpixel = 0; + npixels = 0; + while (cc > 0 && npixels < maxpixels) { + int n, delta; + + n = *bp++, cc--; + switch (n & THUNDER_CODE) { + case THUNDER_RUN: /* pixel run */ + /* + * Replicate the last pixel n times, + * where n is the lower-order 6 bits. + */ + if (npixels & 1) { + op[0] |= lastpixel; + lastpixel = *op++; npixels++; n--; + } else + lastpixel |= lastpixel << 4; + npixels += n; + if (npixels < maxpixels) { + for (; n > 0; n -= 2) + *op++ = (uint8) lastpixel; + } + if (n == -1) + *--op &= 0xf0; + lastpixel &= 0xf; + break; + case THUNDER_2BITDELTAS: /* 2-bit deltas */ + if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + if ((delta = (n & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + break; + case THUNDER_3BITDELTAS: /* 3-bit deltas */ + if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) + SETPIXEL(op, lastpixel + threebitdeltas[delta]); + if ((delta = (n & 7)) != DELTA3_SKIP) + SETPIXEL(op, lastpixel + threebitdeltas[delta]); + break; + case THUNDER_RAW: /* raw data */ + SETPIXEL(op, n); + break; + } + } + tif->tif_rawcp = (uint8*) bp; + tif->tif_rawcc = cc; + if (npixels != maxpixels) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%s data at scanline %lu (%I64u != %I64u)", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long) tif->tif_row, + (unsigned __int64) npixels, + (unsigned __int64) maxpixels); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%s data at scanline %lu (%llu != %llu)", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long) tif->tif_row, + (unsigned long long) npixels, + (unsigned long long) maxpixels); +#endif + return (0); + } + + return (1); +} + +static int +ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +{ + static const char module[] = "ThunderDecodeRow"; + uint8* row = buf; + + (void) s; + if (occ % tif->tif_scanlinesize) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (0); + } + while (occ > 0) { + if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) + return (0); + occ -= tif->tif_scanlinesize; + row += tif->tif_scanlinesize; + } + return (1); +} + +int +TIFFInitThunderScan(TIFF* tif, int scheme) +{ + (void) scheme; + + tif->tif_setupdecode = ThunderSetupDecode; + tif->tif_decoderow = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; + return (1); +} +#endif /* THUNDER_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_tile.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_tile.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_tile.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_tile.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,299 @@ +/* $Id: tif_tile.c,v 1.23 2012-06-06 05:33:55 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Tiled Image Support Routines. + */ +#include "tiffiop.h" + +/* + * Compute which tile an (x,y,z,s) value is in. + */ +uint32 +TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 dx = td->td_tilewidth; + uint32 dy = td->td_tilelength; + uint32 dz = td->td_tiledepth; + uint32 tile = 1; + + if (td->td_imagedepth == 1) + z = 0; + if (dx == (uint32) -1) + dx = td->td_imagewidth; + if (dy == (uint32) -1) + dy = td->td_imagelength; + if (dz == (uint32) -1) + dz = td->td_imagedepth; + if (dx != 0 && dy != 0 && dz != 0) { + uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx); + uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy); + uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz); + + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + tile = (xpt*ypt*zpt)*s + + (xpt*ypt)*(z/dz) + + xpt*(y/dy) + + x/dx; + else + tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; + } + return (tile); +} + +/* + * Check an (x,y,z,s) coordinate + * against the image bounds. + */ +int +TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (x >= td->td_imagewidth) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Col out of range, max %lu", + (unsigned long) x, + (unsigned long) (td->td_imagewidth - 1)); + return (0); + } + if (y >= td->td_imagelength) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Row out of range, max %lu", + (unsigned long) y, + (unsigned long) (td->td_imagelength - 1)); + return (0); + } + if (z >= td->td_imagedepth) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Depth out of range, max %lu", + (unsigned long) z, + (unsigned long) (td->td_imagedepth - 1)); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && + s >= td->td_samplesperpixel) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%lu: Sample out of range, max %lu", + (unsigned long) s, + (unsigned long) (td->td_samplesperpixel - 1)); + return (0); + } + return (1); +} + +/* + * Compute how many tiles are in an image. + */ +uint32 +TIFFNumberOfTiles(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 dx = td->td_tilewidth; + uint32 dy = td->td_tilelength; + uint32 dz = td->td_tiledepth; + uint32 ntiles; + + if (dx == (uint32) -1) + dx = td->td_imagewidth; + if (dy == (uint32) -1) + dy = td->td_imagelength; + if (dz == (uint32) -1) + dz = td->td_imagedepth; + ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : + _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), + TIFFhowmany_32(td->td_imagelength, dy), + "TIFFNumberOfTiles"), + TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, + "TIFFNumberOfTiles"); + return (ntiles); +} + +/* + * Compute the # bytes in each row of a tile. + */ +uint64 +TIFFTileRowSize64(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + uint64 rowsize; + + if (td->td_tilelength == 0 || td->td_tilewidth == 0) + return (0); + rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, + "TIFFTileRowSize"); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, + "TIFFTileRowSize"); + return (TIFFhowmany8_64(rowsize)); +} +tmsize_t +TIFFTileRowSize(TIFF* tif) +{ + static const char module[] = "TIFFTileRowSize"; + uint64 m; + tmsize_t n; + m=TIFFTileRowSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); +} + +/* + * Compute the # bytes in a variable length, row-aligned tile. + */ +uint64 +TIFFVTileSize64(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVTileSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (td->td_tilelength == 0 || td->td_tilewidth == 0 || + td->td_tiledepth == 0) + return (0); + if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& + (td->td_photometric==PHOTOMETRIC_YCBCR)&& + (td->td_samplesperpixel==3)&& + (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16 ycbcrsubsampling[2]; + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint32 samplingblocks_ver; + uint64 samplingrow_samples; + uint64 samplingrow_size; + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, + ycbcrsubsampling+1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) + ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], + ycbcrsubsampling[1] ); + return 0; + } + samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); + samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); + samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); + return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); + } + else + return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module)); +} +tmsize_t +TIFFVTileSize(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVTileSize"; + uint64 m; + tmsize_t n; + m=TIFFVTileSize64(tif,nrows); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); +} + +/* + * Compute the # bytes in a row-aligned tile. + */ +uint64 +TIFFTileSize64(TIFF* tif) +{ + return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); +} +tmsize_t +TIFFTileSize(TIFF* tif) +{ + static const char module[] = "TIFFTileSize"; + uint64 m; + tmsize_t n; + m=TIFFTileSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); +} + +/* + * Compute a default tile size based on the image + * characteristics and a requested value. If a + * request is <1 then we choose a size according + * to certain heuristics. + */ +void +TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + (*tif->tif_deftilesize)(tif, tw, th); +} + +void +_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + (void) tif; + if (*(int32*) tw < 1) + *tw = 256; + if (*(int32*) th < 1) + *th = 256; + /* roundup to a multiple of 16 per the spec */ + if (*tw & 0xf) + *tw = TIFFroundup_32(*tw, 16); + if (*th & 0xf) + *th = TIFFroundup_32(*th, 16); +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_unix.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_unix.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_unix.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_unix.c 2013-05-05 17:29:36.000000000 +0000 @@ -0,0 +1,326 @@ +/* $Id: tif_unix.c,v 1.23 2012-06-01 21:40:59 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library UNIX-specific Routines. These are should also work with the + * Windows Common RunTime Library. + */ + +#include "tif_config.h" + +#ifndef WIN32 + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include + +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_IO_H +# include +#endif + +#include "tiffiop.h" + +static tmsize_t +_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +{ + size_t size_io = (size_t) size; + if ((tmsize_t) size_io != size) + { + errno=EINVAL; + return (tmsize_t) -1; + } + return ((tmsize_t) read((int) fd, buf, size_io)); +} + +static tmsize_t +_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +{ + size_t size_io = (size_t) size; + if ((tmsize_t) size_io != size) + { + errno=EINVAL; + return (tmsize_t) -1; + } + return ((tmsize_t) write((int) fd, buf, size_io)); +} + +static uint64 +_tiffSeekProc(thandle_t fd, uint64 off, int whence) +{ + off_t off_io = (off_t) off; + if ((uint64) off_io != off) + { + errno=EINVAL; + return (uint64) -1; /* this is really gross */ + } + return((uint64)lseek((int)fd,off_io,whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return(close((int)fd)); +} + +static uint64 +_tiffSizeProc(thandle_t fd) +{ + struct stat sb; + if (fstat((int)fd,&sb)<0) + return(0); + else + return((uint64)sb.st_size); +} + +#ifdef HAVE_MMAP +#include + +static int +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +{ + uint64 size64 = _tiffSizeProc(fd); + tmsize_t sizem = (tmsize_t)size64; + if ((uint64)sizem==size64) { + *pbase = (void*) + mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int) fd, 0); + if (*pbase != (void*) -1) { + *psize = (tmsize_t)sizem; + return (1); + } + } + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +{ + (void) fd; + (void) munmap(base, (off_t) size); +} +#else /* !HAVE_MMAP */ +static int +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +{ + (void) fd; (void) pbase; (void) psize; + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +{ + (void) fd; (void) base; (void) size; +} +#endif /* !HAVE_MMAP */ + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + TIFF* tif; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + +/* for cygwin and mingw */ +#ifdef O_BINARY + m |= O_BINARY; +#endif + + fd = open(name, m, 0666); + if (fd < 0) { + if (errno > 0 && strerror(errno) != NULL ) { + TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); + } else { + TIFFErrorExt(0, module, "%s: Cannot open", name); + } + return ((TIFF *)0); + } + + tif = TIFFFdOpen((int)fd, name, mode); + if(!tif) + close(fd); + return tif; +} + +#ifdef __WIN32__ +#include +/* + * Open a TIFF file with a Unicode filename, for read/writing. + */ +TIFF* +TIFFOpenW(const wchar_t* name, const char* mode) +{ + static const char module[] = "TIFFOpenW"; + int m, fd; + int mbsize; + char *mbname; + TIFF* tif; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + +/* for cygwin and mingw */ +#ifdef O_BINARY + m |= O_BINARY; +#endif + + fd = _wopen(name, m, 0666); + if (fd < 0) { + TIFFErrorExt(0, module, "%s: Cannot open", name); + return ((TIFF *)0); + } + + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) { + mbname = _TIFFmalloc(mbsize); + if (!mbname) { + TIFFErrorExt(0, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF*)0); + } + + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, + NULL, NULL); + } + + tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "", + mode); + + _TIFFfree(mbname); + + if(!tif) + close(fd); + return tif; +} +#endif + +void* +_TIFFmalloc(tmsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(void* p) +{ + free(p); +} + +void* +_TIFFrealloc(void* p, tmsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(void* p, int v, tmsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(void* d, const void* s, tmsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +static void +unixWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; + +static void +unixErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; + +/* vim: set ts=8 sts=8 sw=8 noet: */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ + + #endif // WIN32 diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_version.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_version.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_version.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_version.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,40 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_version.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */ +/* + * Copyright (c) 1992-1997 Sam Leffler + * Copyright (c) 1992-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#include "tiffiop.h" + +static const char TIFFVersion[] = TIFFLIB_VERSION_STR; + +const char* +TIFFGetVersion(void) +{ + return (TIFFVersion); +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_warning.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_warning.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_warning.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_warning.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,81 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL; + +TIFFErrorHandler +TIFFSetWarningHandler(TIFFErrorHandler handler) +{ + TIFFErrorHandler prev = _TIFFwarningHandler; + _TIFFwarningHandler = handler; + return (prev); +} + +TIFFErrorHandlerExt +TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) +{ + TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; + _TIFFwarningHandlerExt = handler; + return (prev); +} + +void +TIFFWarning(const char* module, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (_TIFFwarningHandler) + (*_TIFFwarningHandler)(module, fmt, ap); + if (_TIFFwarningHandlerExt) + (*_TIFFwarningHandlerExt)(0, module, fmt, ap); + va_end(ap); +} + +void +TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (_TIFFwarningHandler) + (*_TIFFwarningHandler)(module, fmt, ap); + if (_TIFFwarningHandlerExt) + (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); + va_end(ap); +} + + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_win32.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_win32.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_win32.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_win32.c 2013-05-05 20:09:16.000000000 +0000 @@ -0,0 +1,445 @@ +/* $Id: tif_win32.c,v 1.39 2011-12-22 17:07:57 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by + * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA + */ + +#ifdef WIN32 // XBEE + +#include "tiffiop.h" + +#include + +static tmsize_t +_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +{ + /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8* ma; + uint64 mb; + DWORD n; + DWORD o; + tmsize_t p; + ma=(uint8*)buf; + mb=size; + p=0; + while (mb>0) + { + n=0x80000000UL; + if ((uint64)n>mb) + n=(DWORD)mb; + if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) + return(0); + ma+=o; + mb-=o; + p+=o; + if (o!=n) + break; + } + return(p); +} + +static tmsize_t +_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +{ + /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8* ma; + uint64 mb; + DWORD n; + DWORD o; + tmsize_t p; + ma=(uint8*)buf; + mb=size; + p=0; + while (mb>0) + { + n=0x80000000UL; + if ((uint64)n>mb) + n=(DWORD)mb; + if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) + return(0); + ma+=o; + mb-=o; + p+=o; + if (o!=n) + break; + } + return(p); +} + +static uint64 +_tiffSeekProc(thandle_t fd, uint64 off, int whence) +{ + LARGE_INTEGER offli; + DWORD dwMoveMethod; + offli.QuadPart = off; + switch(whence) + { + case SEEK_SET: + dwMoveMethod = FILE_BEGIN; + break; + case SEEK_CUR: + dwMoveMethod = FILE_CURRENT; + break; + case SEEK_END: + dwMoveMethod = FILE_END; + break; + default: + dwMoveMethod = FILE_BEGIN; + break; + } + offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); + if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) + offli.QuadPart=0; + return(offli.QuadPart); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (CloseHandle(fd) ? 0 : -1); +} + +static uint64 +_tiffSizeProc(thandle_t fd) +{ + ULARGE_INTEGER m; + m.LowPart=GetFileSize(fd,&m.HighPart); + return(m.QuadPart); +} + +static int +_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) +{ + (void) fd; + (void) pbase; + (void) psize; + return (0); +} + +/* + * From "Hermann Josef Hill" : + * + * Windows uses both a handle and a pointer for file mapping, + * but according to the SDK documentation and Richter's book + * "Advanced Windows Programming" it is safe to free the handle + * after obtaining the file mapping pointer + * + * This removes a nasty OS dependency and cures a problem + * with Visual C++ 5.0 + */ +static int +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +{ + uint64 size; + tmsize_t sizem; + HANDLE hMapFile; + + size = _tiffSizeProc(fd); + sizem = (tmsize_t)size; + if ((uint64)sizem!=size) + return (0); + + /* By passing in 0 for the maximum file size, it specifies that we + create a file mapping object for the full file size. */ + hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapFile == NULL) + return (0); + *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); + CloseHandle(hMapFile); + if (*pbase == NULL) + return (0); + *psize = size; + return(1); +} + +static void +_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +{ + (void) fd; + (void) base; + (void) size; +} + +static void +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +{ + (void) fd; + (void) size; + UnmapViewOfFile(base); +} + +/* + * Open a TIFF file descriptor for read/writing. + * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode + * string, which forces the file to be opened unmapped. + */ +TIFF* +TIFFFdOpen(int ifd, const char* name, const char* mode) +{ + TIFF* tif; + int fSuppressMap; + int m; + fSuppressMap=0; + for (m=0; mode[m]!=0; m++) + { + if (mode[m]=='u') + { + fSuppressMap=1; + break; + } + } + tif = TIFFClientOpen(name, mode, (thandle_t)ifd, + _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, + fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); + if (tif) + tif->tif_fd = ifd; + return (tif); +} + +#ifndef _WIN32_WCE + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + thandle_t fd; + int m; + DWORD dwMode; + TIFF* tif; + + m = _TIFFgetMode(mode, module); + + switch(m) { + case O_RDONLY: dwMode = OPEN_EXISTING; break; + case O_RDWR: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; + case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; + default: return ((TIFF*)0); + } + + fd = (thandle_t)CreateFileA(name, + (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) { + TIFFErrorExt(0, module, "%s: Cannot open", name); + return ((TIFF *)0); + } + + tif = TIFFFdOpen((int)fd, name, mode); + if(!tif) + CloseHandle(fd); + return tif; +} + +/* + * Open a TIFF file with a Unicode filename, for read/writing. + */ +TIFF* +TIFFOpenW(const wchar_t* name, const char* mode) +{ + static const char module[] = "TIFFOpenW"; + thandle_t fd; + int m; + DWORD dwMode; + int mbsize; + char *mbname; + TIFF *tif; + + m = _TIFFgetMode(mode, module); + + switch(m) { + case O_RDONLY: dwMode = OPEN_EXISTING; break; + case O_RDWR: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; + case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; + default: return ((TIFF*)0); + } + + fd = (thandle_t)CreateFileW(name, + (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) { + TIFFErrorExt(0, module, "%S: Cannot open", name); + return ((TIFF *)0); + } + + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) { + mbname = (char *)_TIFFmalloc(mbsize); + if (!mbname) { + TIFFErrorExt(0, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF*)0); + } + + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, + NULL, NULL); + } + + tif = TIFFFdOpen((int)fd, + (mbname != NULL) ? mbname : "", mode); + if(!tif) + CloseHandle(fd); + + _TIFFfree(mbname); + + return tif; +} + +#endif /* ndef _WIN32_WCE */ + +void* +_TIFFmalloc(tmsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(void* p) +{ + free(p); +} + +void* +_TIFFrealloc(void* p, tmsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(void* p, int v, tmsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(void* d, const void* s, tmsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +#ifndef _WIN32_WCE + +#if (_MSC_VER < 1500) +# define vsnprintf _vsnprintf +#endif + +static void +Win32WarningHandler(const char* module, const char* fmt, va_list ap) +{ +#ifndef TIF_PLATFORM_CONSOLE + LPTSTR szTitle; + LPTSTR szTmp; + LPCTSTR szTitleText = "%s Warning"; + LPCTSTR szDefaultModule = "LIBTIFF"; + LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; + SIZE_T nBufSize = (strlen(szTmpModule) + + strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); + + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) + return; + sprintf(szTitle, szTitleText, szTmpModule); + szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); + vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); + MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION); + LocalFree(szTitle); + + return; +#else + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +#endif +} +TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; + +static void +Win32ErrorHandler(const char* module, const char* fmt, va_list ap) +{ +#ifndef TIF_PLATFORM_CONSOLE + LPTSTR szTitle; + LPTSTR szTmp; + LPCTSTR szTitleText = "%s Error"; + LPCTSTR szDefaultModule = "LIBTIFF"; + LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; + SIZE_T nBufSize = (strlen(szTmpModule) + + strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); + + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) + return; + sprintf(szTitle, szTitleText, szTmpModule); + szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); + vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); + MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION); + LocalFree(szTitle); + return; +#else + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +#endif +} +TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; + +#endif /* ndef _WIN32_WCE */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ + + #endif // WIN32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_write.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_write.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_write.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_write.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,749 @@ +/* $Id: tif_write.c,v 1.36 2011-02-18 20:53:04 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Scanline-oriented Write Support + */ +#include "tiffiop.h" +#include + +#define STRIPINCR 20 /* expansion factor on strip array */ + +#define WRITECHECKSTRIPS(tif, module) \ + (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) +#define WRITECHECKTILES(tif, module) \ + (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) +#define BUFFERCHECK(tif) \ + ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ + TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) + +static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module); +static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc); + +int +TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) +{ + static const char module[] = "TIFFWriteScanline"; + register TIFFDirectory *td; + int status, imagegrew = 0; + uint32 strip; + + if (!WRITECHECKSTRIPS(tif, module)) + return (-1); + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return (-1); + tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ + + td = &tif->tif_dir; + /* + * Extend image length if needed + * (but only for PlanarConfig=1). + */ + if (row >= td->td_imagelength) { /* extend image */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not change \"ImageLength\" when using separate planes"); + return (-1); + } + td->td_imagelength = row+1; + imagegrew = 1; + } + /* + * Calculate strip and check for crossings. + */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Sample out of range, max %lu", + (unsigned long) sample, (unsigned long) td->td_samplesperpixel); + return (-1); + } + strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; + } else + strip = row / td->td_rowsperstrip; + /* + * Check strip array to make sure there's space. We don't support + * dynamically growing files that have data organized in separate + * bitplanes because it's too painful. In that case we require that + * the imagelength be set properly before the first write (so that the + * strips array will be fully allocated above). + */ + if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) + return (-1); + if (strip != tif->tif_curstrip) { + /* + * Changing strips -- flush any data present. + */ + if (!TIFFFlushData(tif)) + return (-1); + tif->tif_curstrip = strip; + /* + * Watch out for a growing image. The value of strips/image + * will initially be 1 (since it can't be deduced until the + * imagelength is known). + */ + if (strip >= td->td_stripsperimage && imagegrew) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); + tif->tif_row = + (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return (-1); + tif->tif_flags |= TIFF_CODERSETUP; + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if( td->td_stripbytecount[strip] > 0 ) + { + /* if we are writing over existing tiles, zero length */ + td->td_stripbytecount[strip] = 0; + + /* this forces TIFFAppendToStrip() to do a seek */ + tif->tif_curoff = 0; + } + + if (!(*tif->tif_preencode)(tif, sample)) + return (-1); + tif->tif_flags |= TIFF_POSTENCODE; + } + /* + * Ensure the write is either sequential or at the + * beginning of a strip (or that we can randomly + * access the data -- i.e. no encoding). + */ + if (row != tif->tif_row) { + if (row < tif->tif_row) { + /* + * Moving backwards within the same strip: + * backup to the start and then decode + * forward (below). + */ + tif->tif_row = (strip % td->td_stripsperimage) * + td->td_rowsperstrip; + tif->tif_rawcp = tif->tif_rawdata; + } + /* + * Seek forward to the desired row. + */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (-1); + tif->tif_row = row; + } + + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize ); + + status = (*tif->tif_encoderow)(tif, (uint8*) buf, + tif->tif_scanlinesize, sample); + + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; + return (status); +} + +/* + * Encode the supplied data and write it to the + * specified strip. + * + * NB: Image length must be setup before writing. + */ +tmsize_t +TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) +{ + static const char module[] = "TIFFWriteEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint16 sample; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t) -1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t) -1); + } + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t) -1); + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized according to the directory + * info. + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t) -1); + + tif->tif_flags |= TIFF_BUF4WRITE; + tif->tif_curstrip = strip; + + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return ((tmsize_t) -1); + tif->tif_flags |= TIFF_CODERSETUP; + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if( td->td_stripbytecount[strip] > 0 ) + { + /* Force TIFFAppendToStrip() to consider placing data at end + of file. */ + tif->tif_curoff = 0; + } + + tif->tif_flags &= ~TIFF_POSTENCODE; + sample = (uint16)(strip / td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tmsize_t) -1); + + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode( tif, (uint8*) data, cc ); + + if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample)) + return (0); + if (!(*tif->tif_postencode)(tif)) + return ((tmsize_t) -1); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t) -1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); +} + +/* + * Write the supplied data to the specified strip. + * + * NB: Image length must be setup before writing. + */ +tmsize_t +TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) +{ + static const char module[] = "TIFFWriteRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t) -1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t) -1); + } + /* + * Watch out for a growing image. The value of + * strips/image will initially be 1 (since it + * can't be deduced until the imagelength is known). + */ + if (strip >= td->td_stripsperimage) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t) -1); + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? + cc : (tmsize_t) -1); +} + +/* + * Write and compress a tile of data. The + * tile is selected by the (x,y,z,s) coordinates. + */ +tmsize_t +TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) +{ + if (!TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + /* + * NB: A tile size of -1 is used instead of tif_tilesize knowing + * that TIFFWriteEncodedTile will clamp this to the tile size. + * This is done because the tile size may not be defined until + * after the output buffer is setup in TIFFWriteBufferSetup. + */ + return (TIFFWriteEncodedTile(tif, + TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); +} + +/* + * Encode the supplied data and write it to the + * specified tile. There must be space for the + * data. The function clamps individual writes + * to a tile to the tile size, but does not (and + * can not) check that multiple writes to the same + * tile do not write more than tile size data. + * + * NB: Image length must be setup before writing; this + * interface does not support automatically growing + * the image on each write (as TIFFWriteScanline does). + */ +tmsize_t +TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) +{ + static const char module[] = "TIFFWriteEncodedTile"; + TIFFDirectory *td; + uint16 sample; + + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + td = &tif->tif_dir; + if (tile >= td->td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", + (unsigned long) tile, (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t)(-1)); + + tif->tif_flags |= TIFF_BUF4WRITE; + tif->tif_curtile = tile; + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if( td->td_stripbytecount[tile] > 0 ) + { + /* Force TIFFAppendToStrip() to consider placing data at end + of file. */ + tif->tif_curoff = 0; + } + + /* + * Compute tiles per row & per column to compute + * current row and column + */ + tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) + * td->td_tilelength; + tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) + * td->td_tilewidth; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return ((tmsize_t)(-1)); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_flags &= ~TIFF_POSTENCODE; + sample = (uint16)(tile/td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tmsize_t)(-1)); + /* + * Clamp write amount to the tile size. This is mostly + * done so that callers can pass in some large number + * (e.g. -1) and have the tile size used instead. + */ + if ( cc < 1 || cc > tif->tif_tilesize) + cc = tif->tif_tilesize; + + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode( tif, (uint8*) data, cc ); + + if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) + return (0); + if (!(*tif->tif_postencode)(tif)) + return ((tmsize_t)(-1)); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, + tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)(-1)); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); +} + +/* + * Write the supplied data to the specified strip. + * There must be space for the data; we don't check + * if strips overlap! + * + * NB: Image length must be setup before writing; this + * interface does not support automatically growing + * the image on each write (as TIFFWriteScanline does). + */ +tmsize_t +TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) +{ + static const char module[] = "TIFFWriteRawTile"; + + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + if (tile >= tif->tif_dir.td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", + (unsigned long) tile, + (unsigned long) tif->tif_dir.td_nstrips); + return ((tmsize_t)(-1)); + } + return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ? + cc : (tmsize_t)(-1)); +} + +#define isUnspecified(tif, f) \ + (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) + +int +TIFFSetupStrips(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + + if (isTiled(tif)) + td->td_stripsperimage = + isUnspecified(tif, FIELD_TILEDIMENSIONS) ? + td->td_samplesperpixel : TIFFNumberOfTiles(tif); + else + td->td_stripsperimage = + isUnspecified(tif, FIELD_ROWSPERSTRIP) ? + td->td_samplesperpixel : TIFFNumberOfStrips(tif); + td->td_nstrips = td->td_stripsperimage; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + td->td_stripoffset = (uint64 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint64)); + td->td_stripbytecount = (uint64 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint64)); + if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) + return (0); + /* + * Place data at the end-of-file + * (by setting offsets to zero). + */ + _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64)); + _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64)); + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + return (1); +} +#undef isUnspecified + +/* + * Verify file is writable and that the directory + * information is setup properly. In doing the latter + * we also "freeze" the state of the directory so + * that important information is not changed. + */ +int +TIFFWriteCheck(TIFF* tif, int tiles, const char* module) +{ + if (tif->tif_mode == O_RDONLY) { + TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing"); + return (0); + } + if (tiles ^ isTiled(tif)) { + TIFFErrorExt(tif->tif_clientdata, module, tiles ? + "Can not write tiles to a stripped image" : + "Can not write scanlines to a tiled image"); + return (0); + } + + _TIFFFillStriles( tif ); + + /* + * On the first write verify all the required information + * has been setup and initialize any data structures that + * had to wait until directory information was set. + * Note that a lot of our work is assumed to remain valid + * because we disallow any of the important parameters + * from changing after we start writing (i.e. once + * TIFF_BEENWRITING is set, TIFFSetField will only allow + * the image's length to be changed). + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Must set \"ImageWidth\" before writing data"); + return (0); + } + if (tif->tif_dir.td_samplesperpixel == 1) { + /* + * Planarconfiguration is irrelevant in case of single band + * images and need not be included. We will set it anyway, + * because this field is used in other parts of library even + * in the single band case. + */ + if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) + tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; + } else { + if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Must set \"PlanarConfiguration\" before writing data"); + return (0); + } + } + if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) { + tif->tif_dir.td_nstrips = 0; + TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays", + isTiled(tif) ? "tile" : "strip"); + return (0); + } + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (tif->tif_tilesize == 0) + return (0); + } + else + tif->tif_tilesize = (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (tif->tif_scanlinesize == 0) + return (0); + tif->tif_flags |= TIFF_BEENWRITING; + return (1); +} + +/* + * Setup the raw data buffer used for encoding. + */ +int +TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size) +{ + static const char module[] = "TIFFWriteBufferSetup"; + + if (tif->tif_rawdata) { + if (tif->tif_flags & TIFF_MYBUFFER) { + _TIFFfree(tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + } + tif->tif_rawdata = NULL; + } + if (size == (tmsize_t)(-1)) { + size = (isTiled(tif) ? + tif->tif_tilesize : TIFFStripSize(tif)); + /* + * Make raw data buffer at least 8K + */ + if (size < 8*1024) + size = 8*1024; + bp = NULL; /* NB: force malloc */ + } + if (bp == NULL) { + bp = _TIFFmalloc(size); + if (bp == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer"); + return (0); + } + tif->tif_flags |= TIFF_MYBUFFER; + } else + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdata = (uint8*) bp; + tif->tif_rawdatasize = size; + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (1); +} + +/* + * Grow the strip data structures by delta strips. + */ +static int +TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + uint64* new_stripoffset; + uint64* new_stripbytecount; + + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset, + (td->td_nstrips + delta) * sizeof (uint64)); + new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount, + (td->td_nstrips + delta) * sizeof (uint64)); + if (new_stripoffset == NULL || new_stripbytecount == NULL) { + if (new_stripoffset) + _TIFFfree(new_stripoffset); + if (new_stripbytecount) + _TIFFfree(new_stripbytecount); + td->td_nstrips = 0; + TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays"); + return (0); + } + td->td_stripoffset = new_stripoffset; + td->td_stripbytecount = new_stripbytecount; + _TIFFmemset(td->td_stripoffset + td->td_nstrips, + 0, delta*sizeof (uint64)); + _TIFFmemset(td->td_stripbytecount + td->td_nstrips, + 0, delta*sizeof (uint64)); + td->td_nstrips += delta; + tif->tif_flags |= TIFF_DIRTYDIRECT; + + return (1); +} + +/* + * Append the data to the specified strip. + */ +static int +TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc) +{ + static const char module[] = "TIFFAppendToStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64 m; + int64 old_byte_count = -1; + + if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) { + assert(td->td_nstrips > 0); + + if( td->td_stripbytecount[strip] != 0 + && td->td_stripoffset[strip] != 0 + && td->td_stripbytecount[strip] >= (uint64) cc ) + { + /* + * There is already tile data on disk, and the new tile + * data we have will fit in the same space. The only + * aspect of this that is risky is that there could be + * more data to append to this strip before we are done + * depending on how we are getting called. + */ + if (!SeekOK(tif, td->td_stripoffset[strip])) { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at scanline %lu", + (unsigned long)tif->tif_row); + return (0); + } + } + else + { + /* + * Seek to end of file, and set that as our location to + * write this strip. + */ + td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END); + tif->tif_flags |= TIFF_DIRTYSTRIP; + } + + tif->tif_curoff = td->td_stripoffset[strip]; + + /* + * We are starting a fresh strip/tile, so set the size to zero. + */ + old_byte_count = td->td_stripbytecount[strip]; + td->td_stripbytecount[strip] = 0; + } + + m = tif->tif_curoff+cc; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + m = (uint32)m; + if ((mtif_curoff)||(m<(uint64)cc)) + { + TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); + return (0); + } + if (!WriteOK(tif, data, cc)) { + TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", + (unsigned long) tif->tif_row); + return (0); + } + tif->tif_curoff = m; + td->td_stripbytecount[strip] += cc; + + if( (int64) td->td_stripbytecount[strip] != old_byte_count ) + tif->tif_flags |= TIFF_DIRTYSTRIP; + + return (1); +} + +/* + * Internal version of TIFFFlushData that can be + * called by ``encodestrip routines'' w/o concern + * for infinite recursion. + */ +int +TIFFFlushData1(TIFF* tif) +{ + if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) { + if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((uint8*)tif->tif_rawdata, + tif->tif_rawcc); + if (!TIFFAppendToStrip(tif, + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, + tif->tif_rawdata, tif->tif_rawcc)) + return (0); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + } + return (1); +} + +/* + * Set the current write offset. This should only be + * used to set the offset to a known previous location + * (very carefully), or to 0 so that the next write gets + * appended to the end of the file. + */ +void +TIFFSetWriteOffset(TIFF* tif, toff_t off) +{ + tif->tif_curoff = off; +} + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_zip.c diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_zip.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tif_zip.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tif_zip.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,469 @@ +/* $Id: tif_zip.c,v 1.31 2011-01-06 16:00:23 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1995-1997 Sam Leffler + * Copyright (c) 1995-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef ZIP_SUPPORT +/* + * TIFF Library. + * + * ZIP (aka Deflate) Compression Support + * + * This file is simply an interface to the zlib library written by + * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later + * of the library: this code assumes the 1.0 API and also depends on + * the ability to write the zlib header multiple times (one per strip) + * which was not possible with versions prior to 0.95. Note also that + * older versions of this codec avoided this bug by supressing the header + * entirely. This means that files written with the old library cannot + * be read; they should be converted to a different compression scheme + * and then reconverted. + * + * The data format used by the zlib library is described in the files + * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the + * directory ftp://ftp.uu.net/pub/archiving/zip/doc. The library was + * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz. + */ +#include "tif_predict.h" +#include "zlib.h" + +#include + +/* + * Sigh, ZLIB_VERSION is defined as a string so there's no + * way to do a proper check here. Instead we guess based + * on the presence of #defines that were added between the + * 0.95 and 1.0 distributions. + */ +#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED) +#error "Antiquated ZLIB software; you must use version 1.0 or later" +#endif + +/* + * State block for each open TIFF + * file using ZIP compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + z_stream stream; + int zipquality; /* compression level */ + int state; /* state flags */ +#define ZSTATE_INIT_DECODE 0x01 +#define ZSTATE_INIT_ENCODE 0x02 + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} ZIPState; + +#define ZState(tif) ((ZIPState*) (tif)->tif_data) +#define DecoderState(tif) ZState(tif) +#define EncoderState(tif) ZState(tif) + +static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static int +ZIPFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +static int +ZIPSetupDecode(TIFF* tif) +{ + static const char module[] = "ZIPSetupDecode"; + ZIPState* sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & ZSTATE_INIT_ENCODE) { + deflateEnd(&sp->stream); + sp->state = 0; + } + + if (inflateInit(&sp->stream) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); + return (0); + } else { + sp->state |= ZSTATE_INIT_DECODE; + return (1); + } +} + +/* + * Setup state for decoding a strip. + */ +static int +ZIPPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "ZIPPreDecode"; + ZIPState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + + if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) + tif->tif_setupdecode( tif ); + + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_in = (uInt) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (inflateReset(&sp->stream) == Z_OK); +} + +static int +ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "ZIPDecode"; + ZIPState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_DECODE); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (uInt) tif->tif_rawcc; + + sp->stream.next_out = op; + assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_out = (uInt) occ; + if ((tmsize_t)sp->stream.avail_out != occ) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + do { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) + break; + if (state == Z_DATA_ERROR) { + TIFFErrorExt(tif->tif_clientdata, module, + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, sp->stream.msg); + if (inflateSync(&sp->stream) != Z_OK) + return (0); + continue; + } + if (state != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", + (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); + return (0); + } + + tif->tif_rawcp = sp->stream.next_in; + tif->tif_rawcc = sp->stream.avail_in; + + return (1); +} + +static int +ZIPSetupEncode(TIFF* tif) +{ + static const char module[] = "ZIPSetupEncode"; + ZIPState* sp = EncoderState(tif); + + assert(sp != NULL); + if (sp->state & ZSTATE_INIT_DECODE) { + inflateEnd(&sp->stream); + sp->state = 0; + } + + if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); + return (0); + } else { + sp->state |= ZSTATE_INIT_ENCODE; + return (1); + } +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +ZIPPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "ZIPPreEncode"; + ZIPState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + if( sp->state != ZSTATE_INIT_ENCODE ) + tif->tif_setupencode( tif ); + + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_out = tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (deflateReset(&sp->stream) == Z_OK); +} + +/* + * Encode a chunk of pixels. + */ +static int +ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "ZIPEncode"; + ZIPState *sp = EncoderState(tif); + + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_ENCODE); + + (void) s; + sp->stream.next_in = bp; + assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + apropriately even before we simplify it */ + sp->stream.avail_in = (uInt) cc; + if ((tmsize_t)sp->stream.avail_in != cc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } + do { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", + sp->stream.msg); + return (0); + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ + } + } while (sp->stream.avail_in > 0); + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +ZIPPostEncode(TIFF* tif) +{ + static const char module[] = "ZIPPostEncode"; + ZIPState *sp = EncoderState(tif); + int state; + + sp->stream.avail_in = 0; + do { + state = deflate(&sp->stream, Z_FINISH); + switch (state) { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } while (state != Z_STREAM_END); + return (1); +} + +static void +ZIPCleanup(TIFF* tif) +{ + ZIPState* sp = ZState(tif); + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->state & ZSTATE_INIT_ENCODE) { + deflateEnd(&sp->stream); + sp->state = 0; + } else if( sp->state & ZSTATE_INIT_DECODE) { + inflateEnd(&sp->stream); + sp->state = 0; + } + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +ZIPVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "ZIPVSetField"; + ZIPState* sp = ZState(tif); + + switch (tag) { + case TIFFTAG_ZIPQUALITY: + sp->zipquality = (int) va_arg(ap, int); + if ( sp->state&ZSTATE_INIT_ENCODE ) { + if (deflateParams(&sp->stream, + sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); + return (0); + } + } + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +ZIPVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + ZIPState* sp = ZState(tif); + + switch (tag) { + case TIFFTAG_ZIPQUALITY: + *va_arg(ap, int*) = sp->zipquality; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static const TIFFField zipFields[] = { + { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, +}; + +int +TIFFInitZIP(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitZIP"; + ZIPState* sp; + + assert( (scheme == COMPRESSION_DEFLATE) + || (scheme == COMPRESSION_ADOBE_DEFLATE)); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging Deflate codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState)); + if (tif->tif_data == NULL) + goto bad; + sp = ZState(tif); + sp->stream.zalloc = NULL; + sp->stream.zfree = NULL; + sp->stream.opaque = NULL; + sp->stream.data_type = Z_BINARY; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZIPFixupTags; + tif->tif_setupdecode = ZIPSetupDecode; + tif->tif_predecode = ZIPPreDecode; + tif->tif_decoderow = ZIPDecode; + tif->tif_decodestrip = ZIPDecode; + tif->tif_decodetile = ZIPDecode; + tif->tif_setupencode = ZIPSetupEncode; + tif->tif_preencode = ZIPPreEncode; + tif->tif_postencode = ZIPPostEncode; + tif->tif_encoderow = ZIPEncode; + tif->tif_encodestrip = ZIPEncode; + tif->tif_encodetile = ZIPEncode; + tif->tif_cleanup = ZIPCleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return (1); +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for ZIP state block"); + return (0); +} +#endif /* ZIP_SUPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiff.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiff.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiff.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiff.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,650 @@ +/* $Id: tiff.h,v 1.67 2011-01-24 21:06:32 olivier Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFF_ +#define _TIFF_ + +#include "tif_config.h" + +/* + * Tag Image File Format (TIFF) + * + * Based on Rev 6.0 from: + * Developer's Desk + * Aldus Corporation + * 411 First Ave. South + * Suite 200 + * Seattle, WA 98104 + * 206-622-5500 + * + * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) + * + * For BigTIFF design notes see the following links + * http://www.remotesensing.org/libtiff/bigtiffdesign.html + * http://www.awaresystems.be/imaging/tiff/bigtiff.html + */ + +#define TIFF_VERSION_CLASSIC 42 +#define TIFF_VERSION_BIG 43 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 +#define MDI_LITTLEENDIAN 0x5045 +#define MDI_BIGENDIAN 0x4550 + +/* + * Intrinsic data types required by the file format: + * + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * 64-bit quantities int64/uint64 + * strings unsigned char* + */ + +typedef TIFF_INT8_T int8; +typedef TIFF_UINT8_T uint8; + +typedef TIFF_INT16_T int16; +typedef TIFF_UINT16_T uint16; + +typedef TIFF_INT32_T int32; +typedef TIFF_UINT32_T uint32; + +typedef TIFF_INT64_T int64; +typedef TIFF_UINT64_T uint64; + +/* + * Some types as promoted in a variable argument list + * We use uint16_vap rather then directly using int, because this way + * we document the type we actually want to pass through, conceptually, + * rather then confusing the issue by merely stating the type it gets + * promoted to + */ + +typedef int uint16_vap; + +/* + * TIFF header. + */ +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ +} TIFFHeaderCommon; +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint32 tiff_diroff; /* byte offset to first directory */ +} TIFFHeaderClassic; +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint16 tiff_offsetsize; /* size of offsets, should be 8 */ + uint16 tiff_unused; /* unused word, should be 0 */ + uint64 tiff_diroff; /* byte offset to first directory */ +} TIFFHeaderBig; + + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + * - items marked with a & are introduced by Adobe DNG specification. + */ + +/* + * Tag data type information. + * + * Note: RATIONALs are the ratio of two 32-bit integer values. + */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ + TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ + TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ + TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ + TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ +} TIFFDataType; + +/* + * TIFF Tag Definitions. + */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define COMPRESSION_LZMA 34925 /* LZMA2 */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ +#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define PREDICTOR_NONE 1 /* no prediction scheme used */ +#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ +#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ +#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ +#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ +#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_CLIPPATH 343 /* %ClipPath + [Adobe TIFF technote 2] */ +#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits + [Adobe TIFF technote 2] */ +#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits + [Adobe TIFF technote 2] */ +#define TIFFTAG_INDEXED 346 /* %Indexed + [Adobe TIFF Technote 3] */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ +/* + * Tags 512-521 are obsoleted by Technical Note #2 which specifies a + * revised JPEG-in-TIFF scheme. + */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +#define TIFFTAG_XMLPACKET 700 /* %XML packet + [Adobe XMP Specification, + January 2004 */ +#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID + [Adobe TIFF technote] */ +/* tags 32952-32956 are private tags registered to Island Graphics */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +/* tags 32995-32999 are private tags registered to SGI */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +/* tags 33300-33309 are private tags registered to Pixar */ +/* + * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH + * are set when an image has been cropped out of a larger image. + * They reflect the size of the original uncropped image. + * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used + * to determine the position of the smaller image in the larger one. + */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ + /* Tags 33302-33306 are used to identify special image modes and data + * used by Pixar's texture formats. + */ +#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ +#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ +#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ +#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 +#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 +/* tag 33405 is a private tag registered to Eastman Kodak */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* IPTC TAG from RichTIFF specifications */ +#define TIFFTAG_RICHTIFFIPTC 33723 +/* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +/* tag 34929 is a private tag registered to FedEx */ +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ +/* Adobe Digital Negative (DNG) format tags */ +#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ +#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ +#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ +#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model + name */ +#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space + mapping */ +#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ +#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ +#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for + the BlackLevel tag */ +#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ +#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level + differences (columns) */ +#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level + differences (rows) */ +#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding + level */ +#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ +#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image + area */ +#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image + area */ +#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space + transformation matrix 1 */ +#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space + transformation matrix 2 */ +#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ +#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ +#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction + matrix 1 */ +#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction + matrix 2 */ +#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw + values*/ +#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in + linear reference space */ +#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in + x-y chromaticity + coordinates */ +#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero + point */ +#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ +#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of + sharpening */ +#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of + the green pixels in the + blue/green rows track the + values of the green pixels + in the red/green rows */ +#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ +#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ +#define TIFFTAG_LENSINFO 50736 /* info about the lens */ +#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ +#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the + camera's anti-alias filter */ +#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ +#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ +#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote + tag is safe to preserve + along with the rest of the + EXIF data */ +#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ +#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ +#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ +#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for + the raw image data */ +#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original + raw file */ +#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original + raw file */ +#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels + of the sensor */ +#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates + of fully masked pixels */ +#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ +#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space + into ICC profile space */ +#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ +#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ +/* tag 65535 is an undefined tag used by Eastman Kodak */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ + +/* + * The following are ``pseudo tags'' that can be used to control + * codec-specific functionality. These tags are not written to file. + * Note that these values start at 0xffff+1 so that they'll never + * collide with Aldus-assigned tags. + * + * If you want your private pseudo tags ``registered'' (i.e. added to + * this file), please post a bug report via the tracking system at + * http://www.remotesensing.org/libtiff/bugs.html with the appropriate + * C definitions to add. + */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +/* 65550-65556 are allocated to Oceana Matrix */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +/* 65559 is allocated to Oceana Matrix */ +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ +#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ +#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ +#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ +#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ +#define PERSAMPLE_MERGED 0 /* present as a single value */ +#define PERSAMPLE_MULTI 1 /* present as multiple values */ + +/* + * EXIF tags + */ +#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ +#define EXIFTAG_FNUMBER 33437 /* F number */ +#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ +#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ +#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ +#define EXIFTAG_OECF 34856 /* Optoelectric conversion + factor */ +#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ +#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original + data generation */ +#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital + data generation */ +#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ +#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ +#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ +#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ +#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ +#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ +#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ +#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ +#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ +#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ +#define EXIFTAG_FLASH 37385 /* Flash */ +#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ +#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ +#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ +#define EXIFTAG_USERCOMMENT 37510 /* User comments */ +#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ +#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ +#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ +#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ +#define EXIFTAG_COLORSPACE 40961 /* Color space information */ +#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ +#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ +#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ +#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ +#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ +#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ +#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ +#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ +#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ +#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ +#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ +#define EXIFTAG_FILESOURCE 41728 /* File source */ +#define EXIFTAG_SCENETYPE 41729 /* Scene type */ +#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ +#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ +#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ +#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ +#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ +#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ +#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_CONTRAST 41992 /* Contrast */ +#define EXIFTAG_SATURATION 41993 /* Saturation */ +#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ +#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ +#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ + +#endif /* _TIFF_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffio.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffio.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffio.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffio.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,550 @@ +/* $Id: tiffio.h,v 1.90 2012-06-06 04:58:00 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIO_ +#define _TIFFIO_ + +/* + * TIFF I/O Library Definitions. + */ +#include "tiff.h" +#include "tiffvers.h" + +/* + * TIFF is defined as an incomplete type to hide the + * library's internal data structures from clients. + */ +typedef struct tiff TIFF; + +/* + * The following typedefs define the intrinsic size of + * data types used in the *exported* interfaces. These + * definitions depend on the proper definition of types + * in tiff.h. Note also that the varargs interface used + * to pass tag types and values uses the types defined in + * tiff.h directly. + * + * NB: ttag_t is unsigned int and not unsigned short because + * ANSI C requires that the type before the ellipsis be a + * promoted type (i.e. one of int, unsigned int, pointer, + * or double) and because we defined pseudo-tags that are + * outside the range of legal Aldus-assigned tags. + * NB: tsize_t is int32 and not uint32 because some functions + * return -1. + * NB: toff_t is not off_t for many reasons; TIFFs max out at + * 32-bit file offsets, and BigTIFF maxes out at 64-bit + * offsets being the most important, and to ensure use of + * a consistently unsigned type across architectures. + * Prior to libtiff 4.0, this was an unsigned 32 bit type. + */ +/* + * this is the machine addressing size type, only it's signed, so make it + * int32 on 32bit machines, int64 on 64bit machines + */ +typedef TIFF_SSIZE_T tmsize_t; +typedef uint64 toff_t; /* file offset */ +/* the following are deprecated and should be replaced by their defining + counterparts */ +typedef uint32 ttag_t; /* directory tag */ +typedef uint16 tdir_t; /* directory index */ +typedef uint16 tsample_t; /* sample number */ +typedef uint32 tstrile_t; /* strip or tile number */ +typedef tstrile_t tstrip_t; /* strip number */ +typedef tstrile_t ttile_t; /* tile number */ +typedef tmsize_t tsize_t; /* i/o size in bytes */ +typedef void* tdata_t; /* image data ref */ + +#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) +#define __WIN32__ +#endif + +/* + * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c + * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c). + * + * By default tif_unix.c is assumed. + */ + +#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) +# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO) +# define AVOID_WIN32_FILEIO +# endif +#endif + +#if defined(USE_WIN32_FILEIO) +# define VC_EXTRALEAN +# include +# ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +# else +typedef HFILE thandle_t; /* client data handle */ +# endif /* __WIN32__ */ +#else +typedef void* thandle_t; /* client data handle */ +#endif /* USE_WIN32_FILEIO */ + +/* + * Flags to pass to TIFFPrintDirectory to control + * printing of data structures that are potentially + * very large. Bit-or these flags to enable printing + * multiple items. + */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ + +/* + * Colour conversion stuff + */ + +/* reference white */ +#define D65_X0 (95.0470F) +#define D65_Y0 (100.0F) +#define D65_Z0 (108.8827F) + +#define D50_X0 (96.4250F) +#define D50_Y0 (100.0F) +#define D50_Z0 (82.4680F) + +/* Structure for holding information about a display device. */ + +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ + +typedef struct { + float d_mat[3][3]; /* XYZ -> luminance matrix */ + float d_YCR; /* Light o/p for reference white */ + float d_YCG; + float d_YCB; + uint32 d_Vrwr; /* Pixel values for ref. white */ + uint32 d_Vrwg; + uint32 d_Vrwb; + float d_Y0R; /* Residual light for black pixel */ + float d_Y0G; + float d_Y0B; + float d_gammaR; /* Gamma values for the three guns */ + float d_gammaG; + float d_gammaB; +} TIFFDisplay; + +typedef struct { /* YCbCr->RGB support */ + TIFFRGBValue* clamptab; /* range clamping table */ + int* Cr_r_tab; + int* Cb_b_tab; + int32* Cr_g_tab; + int32* Cb_g_tab; + int32* Y_tab; +} TIFFYCbCrToRGB; + +typedef struct { /* CIE Lab 1976->RGB support */ + int range; /* Size of conversion table */ +#define CIELABTORGB_TABLE_RANGE 1500 + float rstep, gstep, bstep; + float X0, Y0, Z0; /* Reference white point */ + TIFFDisplay display; + float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ + float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ + float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ +} TIFFCIELabToRGB; + +/* + * RGBA-style image support. + */ +typedef struct _TIFFRGBAImage TIFFRGBAImage; +/* + * The image reading and conversion routines invoke + * ``put routines'' to copy/image/whatever tiles of + * raw image data. A default set of routines are + * provided to convert/copy raw image data to 8-bit + * packed ABGR format rasters. Applications can supply + * alternate routines that unpack the data into a + * different format or, for example, unpack the data + * and draw the unpacked raster on the display. + */ +typedef void (*tileContigRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*); +typedef void (*tileSeparateRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); +/* + * RGBA-reader state. + */ +struct _TIFFRGBAImage { + TIFF* tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32 width; /* image width */ + uint32 height; /* image height */ + uint16 bitspersample; /* image bits/sample */ + uint16 samplesperpixel; /* image samples/pixel */ + uint16 orientation; /* image orientation */ + uint16 req_orientation; /* requested orientation */ + uint16 photometric; /* image photometric interp */ + uint16* redcmap; /* colormap pallete */ + uint16* greencmap; + uint16* bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32); + /* put decoded strip/tile */ + union { + void (*any)(TIFFRGBAImage*); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; + TIFFRGBValue* Map; /* sample mapping array */ + uint32** BWmap; /* black&white map */ + uint32** PALmap; /* palette image map */ + TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ + TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */ + + uint8* UaToAa; /* Unassociated alpha to associated alpha convertion LUT */ + uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ + + int row_offset; + int col_offset; +}; + +/* + * Macros for extracting components from the + * packed ABGR form returned by TIFFReadRGBAImage. + */ +#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) +#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) +#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) + +/* + * A CODEC is a software package that implements decoding, + * encoding, or decoding+encoding of a compression algorithm. + * The library provides a collection of builtin codecs. + * More codecs may be registered through calls to the library + * and/or the builtin implementations may be overridden. + */ +typedef int (*TIFFInitMethod)(TIFF*, int); +typedef struct { + char* name; + uint16 scheme; + TIFFInitMethod init; +} TIFFCodec; + +#include +#include + +/* share internal LogLuv conversion routines? */ +#ifndef LOGLUV_PUBLIC +#define LOGLUV_PUBLIC 1 +#endif + +#if !defined(__GNUC__) && !defined(__attribute__) +# define __attribute__(x) /*nothing*/ +#endif + +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif +typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); +typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); +typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t); +typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); +typedef int (*TIFFCloseProc)(thandle_t); +typedef toff_t (*TIFFSizeProc)(thandle_t); +typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size); +typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size); +typedef void (*TIFFExtendProc)(TIFF*); + +extern const char* TIFFGetVersion(void); + +extern const TIFFCodec* TIFFFindCODEC(uint16); +extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); +extern void TIFFUnRegisterCODEC(TIFFCodec*); +extern int TIFFIsCODECConfigured(uint16); +extern TIFFCodec* TIFFGetConfiguredCODECs(void); + +/* + * Auxiliary functions. + */ + +extern void* _TIFFmalloc(tmsize_t s); +extern void* _TIFFrealloc(void* p, tmsize_t s); +extern void _TIFFmemset(void* p, int v, tmsize_t c); +extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); +extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c); +extern void _TIFFfree(void* p); + +/* +** Stuff, related to tag handling and creating custom tags. +*/ +extern int TIFFGetTagListCount( TIFF * ); +extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index ); + +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ + +#define FIELD_CUSTOM 65 + +typedef struct _TIFFField TIFFField; +typedef struct _TIFFFieldArray TIFFFieldArray; + +extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType); +extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32); +extern const TIFFField* TIFFFieldWithName(TIFF*, const char *); + +typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list); +typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list); +typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); + +typedef struct { + TIFFVSetMethod vsetfield; /* tag set routine */ + TIFFVGetMethod vgetfield; /* tag get routine */ + TIFFPrintMethod printdir; /* directory print routine */ +} TIFFTagMethods; + +extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); +extern void *TIFFGetClientInfo(TIFF *, const char *); +extern void TIFFSetClientInfo(TIFF *, void *, const char *); + +extern void TIFFCleanup(TIFF* tif); +extern void TIFFClose(TIFF* tif); +extern int TIFFFlush(TIFF* tif); +extern int TIFFFlushData(TIFF* tif); +extern int TIFFGetField(TIFF* tif, uint32 tag, ...); +extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap); +extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...); +extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap); +extern int TIFFReadDirectory(TIFF* tif); +extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray); +extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff); +extern uint64 TIFFScanlineSize64(TIFF* tif); +extern tmsize_t TIFFScanlineSize(TIFF* tif); +extern uint64 TIFFRasterScanlineSize64(TIFF* tif); +extern tmsize_t TIFFRasterScanlineSize(TIFF* tif); +extern uint64 TIFFStripSize64(TIFF* tif); +extern tmsize_t TIFFStripSize(TIFF* tif); +extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip); +extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip); +extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows); +extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows); +extern uint64 TIFFTileRowSize64(TIFF* tif); +extern tmsize_t TIFFTileRowSize(TIFF* tif); +extern uint64 TIFFTileSize64(TIFF* tif); +extern tmsize_t TIFFTileSize(TIFF* tif); +extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows); +extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows); +extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request); +extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int TIFFFileno(TIFF*); +extern int TIFFSetFileno(TIFF*, int); +extern thandle_t TIFFClientdata(TIFF*); +extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); +extern int TIFFGetMode(TIFF*); +extern int TIFFSetMode(TIFF*, int); +extern int TIFFIsTiled(TIFF*); +extern int TIFFIsByteSwapped(TIFF*); +extern int TIFFIsUpSampled(TIFF*); +extern int TIFFIsMSB2LSB(TIFF*); +extern int TIFFIsBigEndian(TIFF*); +extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); +extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); +extern TIFFSeekProc TIFFGetSeekProc(TIFF*); +extern TIFFCloseProc TIFFGetCloseProc(TIFF*); +extern TIFFSizeProc TIFFGetSizeProc(TIFF*); +extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); +extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); +extern uint32 TIFFCurrentRow(TIFF*); +extern uint16 TIFFCurrentDirectory(TIFF*); +extern uint16 TIFFNumberOfDirectories(TIFF*); +extern uint64 TIFFCurrentDirOffset(TIFF*); +extern uint32 TIFFCurrentStrip(TIFF*); +extern uint32 TIFFCurrentTile(TIFF* tif); +extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size); +extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size); +extern int TIFFSetupStrips(TIFF *); +extern int TIFFWriteCheck(TIFF*, int, const char *); +extern void TIFFFreeDirectory(TIFF*); +extern int TIFFCreateDirectory(TIFF*); +extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*); +extern int TIFFCreateEXIFDirectory(TIFF*); +extern int TIFFLastDirectory(TIFF*); +extern int TIFFSetDirectory(TIFF*, uint16); +extern int TIFFSetSubDirectory(TIFF*, uint64); +extern int TIFFUnlinkDirectory(TIFF*, uint16); +extern int TIFFSetField(TIFF*, uint32, ...); +extern int TIFFVSetField(TIFF*, uint32, va_list); +extern int TIFFUnsetField(TIFF*, uint32); +extern int TIFFWriteDirectory(TIFF *); +extern int TIFFWriteCustomDirectory(TIFF *, uint64 *); +extern int TIFFCheckpointDirectory(TIFF *); +extern int TIFFRewriteDirectory(TIFF *); + +#if defined(c_plusplus) || defined(__cplusplus) +extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); +extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); +extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, + int = ORIENTATION_BOTLEFT, int = 0); +#else +extern void TIFFPrintDirectory(TIFF*, FILE*, long); +extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); +extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); +#endif + +extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * ); +extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); +extern int TIFFRGBAImageOK(TIFF*, char [1024]); +extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); +extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); +extern void TIFFRGBAImageEnd(TIFFRGBAImage*); +extern TIFF* TIFFOpen(const char*, const char*); +# ifdef __WIN32__ +extern TIFF* TIFFOpenW(const wchar_t*, const char*); +# endif /* __WIN32__ */ +extern TIFF* TIFFFdOpen(int, const char*, const char*); +extern TIFF* TIFFClientOpen(const char*, const char*, + thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +extern const char* TIFFFileName(TIFF*); +extern const char* TIFFSetFileName(TIFF*, const char *); +extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3))); +extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4))); +extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3))); +extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4))); +extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); +extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); +extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); +extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); +extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); +extern uint32 TIFFNumberOfTiles(TIFF*); +extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); +extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); +extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16); +extern uint32 TIFFNumberOfStrips(TIFF*); +extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); +extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); +extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); +extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); +extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); +extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ +extern void TIFFSetWriteOffset(TIFF* tif, toff_t off); +extern void TIFFSwabShort(uint16*); +extern void TIFFSwabLong(uint32*); +extern void TIFFSwabLong8(uint64*); +extern void TIFFSwabFloat(float*); +extern void TIFFSwabDouble(double*); +extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n); +extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n); +extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n); +extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n); +extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n); +extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n); +extern void TIFFReverseBits(uint8* cp, tmsize_t n); +extern const unsigned char* TIFFGetBitRevTable(int); + +#ifdef LOGLUV_PUBLIC +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. +extern double LogL16toY(int); +extern double LogL10toY(int); +extern void XYZtoRGB24(float*, uint8*); +extern int uv_decode(double*, double*, int); +extern void LogLuv24toXYZ(uint32, float*); +extern void LogLuv32toXYZ(uint32, float*); +#if defined(c_plusplus) || defined(__cplusplus) +extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); +extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); +extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); +#else +extern int LogL16fromY(double, int); +extern int LogL10fromY(double, int); +extern int uv_encode(double, double, int); +extern uint32 LogLuv24fromXYZ(float*, int); +extern uint32 LogLuv32fromXYZ(float*, int); +#endif +#endif /* LOGLUV_PUBLIC */ + +extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*); +extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, + float *, float *, float *); +extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, + uint32 *, uint32 *, uint32 *); + +extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); +extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, + uint32 *, uint32 *, uint32 *); + +/**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the future + * libtiff versions. + ****************************************************************************/ +typedef struct { + ttag_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ +} TIFFFieldInfo; + +extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32); + +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif + +#endif /* _TIFFIO_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffio.hxx diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffio.hxx --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffio.hxx 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffio.hxx 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,49 @@ +/* $Id: tiffio.hxx,v 1.3 2010-06-08 18:55:15 bfriesen Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIO_HXX_ +#define _TIFFIO_HXX_ + +/* + * TIFF I/O library definitions which provide C++ streams API. + */ + +#include +#include "tiff.h" + +extern TIFF* TIFFStreamOpen(const char*, std::ostream *); +extern TIFF* TIFFStreamOpen(const char*, std::istream *); + +#endif /* _TIFFIO_HXX_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c++ + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffiop.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffiop.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffiop.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffiop.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,367 @@ +/* $Id: tiffiop.h,v 1.84 2012-05-30 01:50:17 fwarmerdam Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIOP_ +#define _TIFFIOP_ +/* + * ``Library-private'' definitions. + */ + +#include "tif_config.h" + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_STRING_H +# include +#endif + +#ifdef HAVE_ASSERT_H +# include +#else +# define assert(x) +#endif + +#ifdef HAVE_SEARCH_H +# include +#else +extern void *lfind(const void *, const void *, size_t *, size_t, + int (*)(const void *, const void *)); +#endif + +#include "tiffio.h" + +#include "tif_dir.h" + +#ifndef STRIP_SIZE_DEFAULT +# define STRIP_SIZE_DEFAULT 8192 +#endif + +#define streq(a,b) (strcmp(a,b) == 0) + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +typedef struct client_info { + struct client_info *next; + void *data; + char *name; +} TIFFClientInfoLink; + +/* + * Typedefs for ``method pointers'' used internally. + * these are depriciated and provided only for backwards compatibility + */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t* tidata_t; /* reference to internal image data */ + +typedef void (*TIFFVoidMethod)(TIFF*); +typedef int (*TIFFBoolMethod)(TIFF*); +typedef int (*TIFFPreMethod)(TIFF*, uint16); +typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample); +typedef int (*TIFFSeekMethod)(TIFF*, uint32); +typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size); +typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); +typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); + +struct tiff { + char* tif_name; /* name of open file */ + int tif_fd; /* open file descriptor */ + int tif_mode; /* open mode (O_*) */ + uint32 tif_flags; + #define TIFF_FILLORDER 0x00003 /* natural bit fill order for machine */ + #define TIFF_DIRTYHEADER 0x00004 /* header must be written on close */ + #define TIFF_DIRTYDIRECT 0x00008 /* current directory must be written */ + #define TIFF_BUFFERSETUP 0x00010 /* data buffers setup */ + #define TIFF_CODERSETUP 0x00020 /* encoder/decoder setup done */ + #define TIFF_BEENWRITING 0x00040 /* written 1+ scanlines to file */ + #define TIFF_SWAB 0x00080 /* byte swap file information */ + #define TIFF_NOBITREV 0x00100 /* inhibit bit reversal logic */ + #define TIFF_MYBUFFER 0x00200 /* my raw data buffer; free on close */ + #define TIFF_ISTILED 0x00400 /* file is tile, not strip- based */ + #define TIFF_MAPPED 0x00800 /* file is mapped into memory */ + #define TIFF_POSTENCODE 0x01000 /* need call to postencode routine */ + #define TIFF_INSUBIFD 0x02000 /* currently writing a subifd */ + #define TIFF_UPSAMPLED 0x04000 /* library is doing data up-sampling */ + #define TIFF_STRIPCHOP 0x08000 /* enable strip chopping support */ + #define TIFF_HEADERONLY 0x10000 /* read header only, do not process the first directory */ + #define TIFF_NOREADRAW 0x20000 /* skip reading of raw uncompressed image data */ + #define TIFF_INCUSTOMIFD 0x40000 /* currently writing a custom IFD */ + #define TIFF_BIGTIFF 0x80000 /* read/write bigtiff */ + #define TIFF_BUF4WRITE 0x100000 /* rawcc bytes are for writing */ + #define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/ + #define TIFF_PERSAMPLE 0x400000 /* get/set per sample tags as arrays */ + #define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */ + uint64 tif_diroff; /* file offset of current directory */ + uint64 tif_nextdiroff; /* file offset of following directory */ + uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */ + uint16 tif_dirlistsize; /* number of entires in offset list */ + uint16 tif_dirnumber; /* number of already seen directories */ + TIFFDirectory tif_dir; /* internal rep of current directory */ + TIFFDirectory tif_customdir; /* custom IFDs are separated from the main ones */ + union { + TIFFHeaderCommon common; + TIFFHeaderClassic classic; + TIFFHeaderBig big; + } tif_header; + uint16 tif_header_size; /* file's header block and its length */ + uint32 tif_row; /* current scanline */ + uint16 tif_curdir; /* current directory (index) */ + uint32 tif_curstrip; /* current strip for read/write */ + uint64 tif_curoff; /* current offset for read/write */ + uint64 tif_dataoff; /* current offset for writing dir */ + /* SubIFD support */ + uint16 tif_nsubifd; /* remaining subifds to write */ + uint64 tif_subifdoff; /* offset for patching SubIFD link */ + /* tiling support */ + uint32 tif_col; /* current column (offset by row too) */ + uint32 tif_curtile; /* current tile for read/write */ + tmsize_t tif_tilesize; /* # of bytes in a tile */ + /* compression scheme hooks */ + int tif_decodestatus; + TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ + TIFFBoolMethod tif_setupdecode; /* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode; /* called once before preencode */ + int tif_encodestatus; + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ + TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ + uint8* tif_data; /* compression scheme private data */ + /* input/output buffering */ + tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ + tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ + uint8* tif_rawdata; /* raw data buffer */ + tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ + tmsize_t tif_rawdataoff; /* rawdata offset within strip */ + tmsize_t tif_rawdataloaded;/* amount of data in rawdata */ + uint8* tif_rawcp; /* current spot in raw buffer */ + tmsize_t tif_rawcc; /* bytes unread from raw buffer */ + /* memory-mapped file support */ + uint8* tif_base; /* base of mapped file */ + tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ + /* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc; /* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ + /* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ + /* tag support */ + TIFFField** tif_fields; /* sorted table of registered tags */ + size_t tif_nfields; /* # entries in registered tag table */ + const TIFFField* tif_foundfield; /* cached pointer to already found tag */ + TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ + TIFFClientInfoLink* tif_clientinfo; /* extra client information. */ + /* Backward compatibility stuff. We need these two fields for + * setting up an old tag extension scheme. */ + TIFFFieldArray* tif_fieldscompat; + size_t tif_nfieldscompat; +}; + +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ + +#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) +#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) +#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) +#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size))) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size))) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence))) +#define TIFFCloseFile(tif) \ + ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) +#define TIFFGetFileSize(tif) \ + ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize))) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size))) + +/* + * Default Read/Seek/Write definitions. + */ +#ifndef ReadOK +#define ReadOK(tif, buf, size) \ + (TIFFReadFile((tif),(buf),(size))==(size)) +#endif +#ifndef SeekOK +#define SeekOK(tif, off) \ + (TIFFSeekFile((tif),(off),SEEK_SET)==(off)) +#endif +#ifndef WriteOK +#define WriteOK(tif, buf, size) \ + (TIFFWriteFile((tif),(buf),(size))==(size)) +#endif + +/* NB: the uint32 casts are to silence certain ANSI-C compilers */ +#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ + ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \ + 0U) +#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) +#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y)) +#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y))) +#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3) +#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) + +/* Safe multiply which returns zero if there is an integer overflow */ +#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) + +#define TIFFmax(A,B) ((A)>(B)?(A):(B)) +#define TIFFmin(A,B) ((A)<(B)?(A):(B)) + +#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0])) + +#if defined(__cplusplus) +extern "C" { +#endif +extern int _TIFFgetMode(const char* mode, const char* module); +extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); +extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); +extern int _TIFFNoPreCode(TIFF* tif, uint16 s); +extern int _TIFFNoSeek(TIFF* tif, uint32 off); +extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern int TIFFFlushData1(TIFF* tif); +extern int TIFFDefaultDirectory(TIFF* tif); +extern void _TIFFSetDefaultCompressionState(TIFF* tif); +extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *); +extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); +extern int TIFFSetDefaultCompressionState(TIFF* tif); +extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s); +extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th); +extern int _TIFFDataSize(TIFFDataType type); + +extern void _TIFFsetByteArray(void**, void*, uint32); +extern void _TIFFsetString(char**, char*); +extern void _TIFFsetShortArray(uint16**, uint16*, uint32); +extern void _TIFFsetLongArray(uint32**, uint32*, uint32); +extern void _TIFFsetFloatArray(float**, float*, uint32); +extern void _TIFFsetDoubleArray(double**, double*, uint32); + +extern void _TIFFprintAscii(FILE*, const char*); +extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); + +extern TIFFErrorHandler _TIFFwarningHandler; +extern TIFFErrorHandler _TIFFerrorHandler; +extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; +extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; + +extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*); +extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*); +extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*); +extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); + +extern double _TIFFUInt64ToDouble(uint64); +extern float _TIFFUInt64ToFloat(uint64); + +extern int TIFFInitDumpMode(TIFF*, int); +#ifdef PACKBITS_SUPPORT +extern int TIFFInitPackBits(TIFF*, int); +#endif +#ifdef CCITT_SUPPORT +extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); +extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); +#endif +#ifdef THUNDER_SUPPORT +extern int TIFFInitThunderScan(TIFF*, int); +#endif +#ifdef NEXT_SUPPORT +extern int TIFFInitNeXT(TIFF*, int); +#endif +#ifdef LZW_SUPPORT +extern int TIFFInitLZW(TIFF*, int); +#endif +#ifdef OJPEG_SUPPORT +extern int TIFFInitOJPEG(TIFF*, int); +#endif +#ifdef JPEG_SUPPORT +extern int TIFFInitJPEG(TIFF*, int); +#endif +#ifdef JBIG_SUPPORT +extern int TIFFInitJBIG(TIFF*, int); +#endif +#ifdef ZIP_SUPPORT +extern int TIFFInitZIP(TIFF*, int); +#endif +#ifdef PIXARLOG_SUPPORT +extern int TIFFInitPixarLog(TIFF*, int); +#endif +#ifdef LOGLUV_SUPPORT +extern int TIFFInitSGILog(TIFF*, int); +#endif +#ifdef LZMA_SUPPORT +extern int TIFFInitLZMA(TIFF*, int); +#endif +#ifdef VMS +extern const TIFFCodec _TIFFBuiltinCODECS[]; +#else +extern TIFFCodec _TIFFBuiltinCODECS[]; +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFIOP_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffvers.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffvers.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/tiffvers.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/tiffvers.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,9 @@ +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.2\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +/* + * This define can be used in code that requires + * compilation-related definitions specific to a + * version or versions of the library. Runtime + * version checking should be done based on the + * string returned by TIFFGetVersion. + */ +#define TIFFLIB_VERSION 20120615 diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/uvcode.h diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/uvcode.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/libtiff/uvcode.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/libtiff/uvcode.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,180 @@ +/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */ +#define UV_SQSIZ (float)0.003500 +#define UV_NDIVS 16289 +#define UV_VSTART (float)0.016940 +#define UV_NVS 163 +static struct { + float ustart; + short nus, ncum; +} uv_row[UV_NVS] = { + { (float)0.247663, 4, 0 }, + { (float)0.243779, 6, 4 }, + { (float)0.241684, 7, 10 }, + { (float)0.237874, 9, 17 }, + { (float)0.235906, 10, 26 }, + { (float)0.232153, 12, 36 }, + { (float)0.228352, 14, 48 }, + { (float)0.226259, 15, 62 }, + { (float)0.222371, 17, 77 }, + { (float)0.220410, 18, 94 }, + { (float)0.214710, 21, 112 }, + { (float)0.212714, 22, 133 }, + { (float)0.210721, 23, 155 }, + { (float)0.204976, 26, 178 }, + { (float)0.202986, 27, 204 }, + { (float)0.199245, 29, 231 }, + { (float)0.195525, 31, 260 }, + { (float)0.193560, 32, 291 }, + { (float)0.189878, 34, 323 }, + { (float)0.186216, 36, 357 }, + { (float)0.186216, 36, 393 }, + { (float)0.182592, 38, 429 }, + { (float)0.179003, 40, 467 }, + { (float)0.175466, 42, 507 }, + { (float)0.172001, 44, 549 }, + { (float)0.172001, 44, 593 }, + { (float)0.168612, 46, 637 }, + { (float)0.168612, 46, 683 }, + { (float)0.163575, 49, 729 }, + { (float)0.158642, 52, 778 }, + { (float)0.158642, 52, 830 }, + { (float)0.158642, 52, 882 }, + { (float)0.153815, 55, 934 }, + { (float)0.153815, 55, 989 }, + { (float)0.149097, 58, 1044 }, + { (float)0.149097, 58, 1102 }, + { (float)0.142746, 62, 1160 }, + { (float)0.142746, 62, 1222 }, + { (float)0.142746, 62, 1284 }, + { (float)0.138270, 65, 1346 }, + { (float)0.138270, 65, 1411 }, + { (float)0.138270, 65, 1476 }, + { (float)0.132166, 69, 1541 }, + { (float)0.132166, 69, 1610 }, + { (float)0.126204, 73, 1679 }, + { (float)0.126204, 73, 1752 }, + { (float)0.126204, 73, 1825 }, + { (float)0.120381, 77, 1898 }, + { (float)0.120381, 77, 1975 }, + { (float)0.120381, 77, 2052 }, + { (float)0.120381, 77, 2129 }, + { (float)0.112962, 82, 2206 }, + { (float)0.112962, 82, 2288 }, + { (float)0.112962, 82, 2370 }, + { (float)0.107450, 86, 2452 }, + { (float)0.107450, 86, 2538 }, + { (float)0.107450, 86, 2624 }, + { (float)0.107450, 86, 2710 }, + { (float)0.100343, 91, 2796 }, + { (float)0.100343, 91, 2887 }, + { (float)0.100343, 91, 2978 }, + { (float)0.095126, 95, 3069 }, + { (float)0.095126, 95, 3164 }, + { (float)0.095126, 95, 3259 }, + { (float)0.095126, 95, 3354 }, + { (float)0.088276, 100, 3449 }, + { (float)0.088276, 100, 3549 }, + { (float)0.088276, 100, 3649 }, + { (float)0.088276, 100, 3749 }, + { (float)0.081523, 105, 3849 }, + { (float)0.081523, 105, 3954 }, + { (float)0.081523, 105, 4059 }, + { (float)0.081523, 105, 4164 }, + { (float)0.074861, 110, 4269 }, + { (float)0.074861, 110, 4379 }, + { (float)0.074861, 110, 4489 }, + { (float)0.074861, 110, 4599 }, + { (float)0.068290, 115, 4709 }, + { (float)0.068290, 115, 4824 }, + { (float)0.068290, 115, 4939 }, + { (float)0.068290, 115, 5054 }, + { (float)0.063573, 119, 5169 }, + { (float)0.063573, 119, 5288 }, + { (float)0.063573, 119, 5407 }, + { (float)0.063573, 119, 5526 }, + { (float)0.057219, 124, 5645 }, + { (float)0.057219, 124, 5769 }, + { (float)0.057219, 124, 5893 }, + { (float)0.057219, 124, 6017 }, + { (float)0.050985, 129, 6141 }, + { (float)0.050985, 129, 6270 }, + { (float)0.050985, 129, 6399 }, + { (float)0.050985, 129, 6528 }, + { (float)0.050985, 129, 6657 }, + { (float)0.044859, 134, 6786 }, + { (float)0.044859, 134, 6920 }, + { (float)0.044859, 134, 7054 }, + { (float)0.044859, 134, 7188 }, + { (float)0.040571, 138, 7322 }, + { (float)0.040571, 138, 7460 }, + { (float)0.040571, 138, 7598 }, + { (float)0.040571, 138, 7736 }, + { (float)0.036339, 142, 7874 }, + { (float)0.036339, 142, 8016 }, + { (float)0.036339, 142, 8158 }, + { (float)0.036339, 142, 8300 }, + { (float)0.032139, 146, 8442 }, + { (float)0.032139, 146, 8588 }, + { (float)0.032139, 146, 8734 }, + { (float)0.032139, 146, 8880 }, + { (float)0.027947, 150, 9026 }, + { (float)0.027947, 150, 9176 }, + { (float)0.027947, 150, 9326 }, + { (float)0.023739, 154, 9476 }, + { (float)0.023739, 154, 9630 }, + { (float)0.023739, 154, 9784 }, + { (float)0.023739, 154, 9938 }, + { (float)0.019504, 158, 10092 }, + { (float)0.019504, 158, 10250 }, + { (float)0.019504, 158, 10408 }, + { (float)0.016976, 161, 10566 }, + { (float)0.016976, 161, 10727 }, + { (float)0.016976, 161, 10888 }, + { (float)0.016976, 161, 11049 }, + { (float)0.012639, 165, 11210 }, + { (float)0.012639, 165, 11375 }, + { (float)0.012639, 165, 11540 }, + { (float)0.009991, 168, 11705 }, + { (float)0.009991, 168, 11873 }, + { (float)0.009991, 168, 12041 }, + { (float)0.009016, 170, 12209 }, + { (float)0.009016, 170, 12379 }, + { (float)0.009016, 170, 12549 }, + { (float)0.006217, 173, 12719 }, + { (float)0.006217, 173, 12892 }, + { (float)0.005097, 175, 13065 }, + { (float)0.005097, 175, 13240 }, + { (float)0.005097, 175, 13415 }, + { (float)0.003909, 177, 13590 }, + { (float)0.003909, 177, 13767 }, + { (float)0.002340, 177, 13944 }, + { (float)0.002389, 170, 14121 }, + { (float)0.001068, 164, 14291 }, + { (float)0.001653, 157, 14455 }, + { (float)0.000717, 150, 14612 }, + { (float)0.001614, 143, 14762 }, + { (float)0.000270, 136, 14905 }, + { (float)0.000484, 129, 15041 }, + { (float)0.001103, 123, 15170 }, + { (float)0.001242, 115, 15293 }, + { (float)0.001188, 109, 15408 }, + { (float)0.001011, 103, 15517 }, + { (float)0.000709, 97, 15620 }, + { (float)0.000301, 89, 15717 }, + { (float)0.002416, 82, 15806 }, + { (float)0.003251, 76, 15888 }, + { (float)0.003246, 69, 15964 }, + { (float)0.004141, 62, 16033 }, + { (float)0.005963, 55, 16095 }, + { (float)0.008839, 47, 16150 }, + { (float)0.010490, 40, 16197 }, + { (float)0.016994, 31, 16237 }, + { (float)0.023659, 21, 16268 }, +}; +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.ilmbase diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.ilmbase --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.ilmbase 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.ilmbase 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,21 @@ +Developers: +----------- + +Florian Kainz +Rod Bogart +Drew Hess +Bill Anderson +Wojciech Jarosz + +Contributors: +------------- + +Rito Trevino +Josh Pines +Christian Rouet + +Win32 build system: +------------------- + +Nick Porcino +Kimball Thurston diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.openexr diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.openexr --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.openexr 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/AUTHORS.openexr 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,41 @@ +Developers: +----------- + +Florian Kainz +Rod Bogart +Drew Hess +Paul Schneider +Bill Anderson +Wojciech Jarosz +Andrew Kunz + +Contributors: +------------- + +Simon Green +Rito Trevino +Josh Pines +Christian Rouet +Rodrigo Damazio +Greg Ward +Joseph Goldstone +Loren Carpenter, Pixar Animation Studios + +Win32 build system: +------------------- + +Nick Porcino +Kimball Thurston + +Win32 port contributors: +------------------------ + +Dustin Graves +Jukka Liimatta +Baumann Konstantin +Daniel Koch +E. Scott Larsen +stephan mantler +Andreas Kahler +Frank Jargstorff +Lutz Latta diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,69 @@ +# ---------------------------------------------------------------------------- +# CMake file for openexr +# +# ---------------------------------------------------------------------------- + +project(openexr CXX) + +if(UNIX) + set(HAVE_PTHREAD 1) + include(CheckIncludeFile) + check_include_file(semaphore.h HAVE_POSIX_SEMAPHORES) +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/IlmBaseConfig.h.cmakein" + "${CMAKE_CURRENT_BINARY_DIR}/IlmBaseConfig.h" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/OpenEXRConfig.h.cmakein" + "${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h" @ONLY) + +set(OPENEXR_INCLUDE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/Half" + "${CMAKE_CURRENT_SOURCE_DIR}/Iex" + "${CMAKE_CURRENT_SOURCE_DIR}/IlmThread" + "${CMAKE_CURRENT_SOURCE_DIR}/Imath" + "${CMAKE_CURRENT_SOURCE_DIR}/IlmImf") + +ocv_include_directories("${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIR} ${OPENEXR_INCLUDE_PATHS}) + +file(GLOB lib_srcs Half/half.cpp Iex/*.cpp IlmThread/*.cpp Imath/*.cpp IlmImf/*.cpp) +file(GLOB lib_hdrs Half/*.h Iex/Iex*.h IlmThread/IlmThread*.h Imath/Imath*.h IlmImf/*.h) +list(APPEND lib_hdrs "${CMAKE_CURRENT_BINARY_DIR}/IlmBaseConfig.h" "${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h") + +if(WIN32) + ocv_list_filterout(lib_srcs Posix.*cpp) +else() + ocv_list_filterout(lib_srcs Win32.cpp) +endif() + +source_group("Include" FILES ${lib_hdrs} ) +source_group("Src" FILES ${lib_srcs}) + +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow -Wunused -Wsign-compare -Wundef -Wmissing-declarations -Wuninitialized -Wswitch -Wparentheses -Warray-bounds -Wextra) +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4099 /wd4100 /wd4101 /wd4127 /wd4189 /wd4245 /wd4305 /wd4389 /wd4512 /wd4701 /wd4702 /wd4706 /wd4800) # vs2005 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4334) # vs2005 Win64 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008 +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4267) # vs2008 Win64 + +if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") +endif() + +add_library(IlmImf STATIC ${lib_hdrs} ${lib_srcs}) +target_link_libraries(IlmImf ${ZLIB_LIBRARIES}) + +set_target_properties(IlmImf + PROPERTIES + OUTPUT_NAME "IlmImf" + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(IlmImf PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS IlmImf ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() + +set(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATHS} PARENT_SCOPE) +set(OPENEXR_VERSION "1.7.1" PARENT_SCOPE) diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.ilmbase diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.ilmbase --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.ilmbase 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.ilmbase 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,109 @@ +Version 1.0.3 + * Added support for enabling/disabling large stack optimisations, used in + halfFunction.h. + (Piotr Stanczyk) + * Added ImathNoise.(h/cpp) files. Initializes Perlin noise to match the + Renderman implmenetation. + (Pixar Contribution) + * Fixed a number of missing includes to comply with stricter + enforcement by gnu compilers. + (Piotr Stanczyk) + * Depracated compiler flag: -Wno-long-double since it is no longer + supported under OS X. + (Piotr Stanczyk) + * A minor API change to Imath::Frustum has been made: the functions + 'near' and 'far' have been renamed to 'nearPlane' and 'farPlane' due + to conflicts with certain windows headers. The former alternate + accessor names for these values on windows ('hither' and 'yon') + remain, though should be considered deprecated. + (David Lenihan) + * Added SVD, eigenvalue solver, and procrustes fit calculations + to ImathMatrixAlgo. + (Chris Twigg, Ji Hun Yu) + * Added Imath::FrustumTest for frustum visibility testing. + (Eric Johnston) + * Fixed a stack corruption in the matrix minorOf functions. + (Nick Rasmussen) + * Visual studio 2008 project files have been added to the vc/vc9 + directory, and several minor visual studio compile fixes have + been applied. + (Nick Rasmussen) + * Updated the so verison to 7. + (Piotr Stanczyk) + * Depracated the MacCode_Warrior and Shake submodules. + (Piotr Stanczyk) + +Version 1.0.2 + * Added support for targetting builds on 64bit Windows and minimising + number of compiler warnings on Windows. Thanks to Ger Hobbelt for his + contributions to CreateDLL. + (Ji Hun Yu) + * Removed a spurious restrict qualifier in the matrix manipulation code + that was causing the 64-bit MS compiler to generate code in release + mode that caused incorrect results. + (Ji Hun Yu) + * Added patches for improving universal binaries on OS X. Thanks to + Paul Schneider for the contribution + (Piotr Stanczyk) + * Imath::Box optimization: remove loops from methods by partially + specializing the class, for boxes of two and three dimensions. + (Piotr Stanczyk) + * Added explicit copy constructors to Imath::Matrix33 and + ImathMatrix44 to make conversions between float and double + matrices more convenient. + (Florian Kainz) + * Added slerpShortestArc() and euclideanInnerProduct() functions + to Imath::Quat. + (Nick Porcino) + * Added 4D vector class template Imath::Vec4. + (Nick Porcino) + * Copy constructors and assignment operators for Matrix33 + and Matrix44 are up to 25% faster. Added matrix constructors + that do not initialize the matrix (this is faster in cases where + the initial value of the matrix is immediately overwritten anyway). + (Nick Porcino) + * Rewrote function closestPointOnBox(point,box). Shortened + the code, improved numerical accuracy, fixed a bug where + closestPointOnBox(box.center(),box) would return the center + of the +Z side of the box, even if the +/-X or +/-Y sides + were closer. + (Florian Kainz) + * Rewrote function findEntryAndExitPoints() in ImathBoxAlgo.h. + Results are now consistent with those from intersect(), also + in ImathBoxAlgo.h. + (Florian Kainz) + * Made Vec2::length() and Vec3::length() more accurate for + vectors whose length is less than sqrt(limits::smallest()); + (Florian Kainz) + * Made Quat::angle() more accurate for small angles. + (Don Hatch) + +Version 1.0.1: + * Removed Windows .suo files from distribution. + (Eric Wimmer) + +Version 1.0.0: + * Bumped DSO version number to 6.0 + (Florian Kainz) + * Rounding during float-to-half conversion now implements + "round to nearest even" mode: if the original float value + is exactly in the middle between the two closest half values + then rounding chooses the half value whose least significant + bit is zero. + (Florian Kainz) + * Installation Tuning: + - Corrected version number on dso's (libtool) - now 5.0 + - Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs + in configure scripts of packages dependent on IlmBase can link + with static libraries properly + - eliminated some warning messages during install + (Andrew Kunz) + +Version 0.9.0: + * Initial release of this code as a separate library. + Previously the libraries contained were part of + version 1.4.0 of OpenEXR + * New build scripts for Linux/Unix + (Andrew Kunz) + * New Windows project files and build scripts + (Kimball Thurston) diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.openexr diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.openexr --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.openexr 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/ChangeLog.openexr 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,666 @@ +Version 1.7.1: + * Updated the .so verison to 7. + (Piotr Stanczyk) + +Version 1.7.0: + * Added support for targetting builds on 64bit Windows and minimising + number of compiler warnings on Windows. Thanks to Ger Hobbelt for his + contributions to CreateDLL. + (Ji Hun Yu) + * Added new atttribute types: + M33dAttribute 3x3 double-precision matrix + M44dAttribute 4x4 double-precision matrix + V2d 2D double-precision vector + V3d 3D double-precision vector + (Florian Kainz) + * Bug fix: crash when reading a damaged image file (found + by Apple). An exception thrown inside the PIZ Huffman + decoder bypasses initialization of an array of pointers. + The uninitialized pointers are later passed to operator + delete. + (Florian Kainz) + * Bug fix: crash when reading a damaged image file (found by + Apple). Computing the size of input certain buffers may + overflow and wrap around to a small number, later causing + writes beyond the end of the buffer. + (Florian Kainz) + * In the "Technical Introduction" document, added + Premultiplied vs. Un-Premulitiplied Color section: + states explicitly that pixels with zero alpha and non-zero + RGB are allowed, points out that preserving such a pixel can + be a problem in application programs with un-premultiplied + internal image representations. + (Florian Kainz) + * exrenvmap improvements: + - New command line flags set the type of the input image to + latitude-longitude map or cube-face map, overriding the + envmap attribute in the input file header. + - Cube-face maps can now be assembled from or split into six + square sub-images. + - Converting a cube-face map into a new cube-face map with + the same face size copies the image instead of resampling + it. This avoids blurring when a cube-face map is assembled + from or split into sub-images. + (Florian Kainz) + * Updated standard chromaticities in ImfAcesFile.cpp to match + final ACES (Academy Color Encoding Specification) document. + (Florian Kainz) + * Added worldToCamera and worldToNDC matrices to + ImfStandardAttributes.h (Florian Kainz) + * Increased the maximum length of attribute and channel names + from 31 to 255 characters. For files that do contain names + longer than 31 characters, a new LONG_NAMES_FLAG in the fil + version number is set. This flag causes older versions of + the IlmImf library (1.6.1 and earlier) to reject files with + long names. Without the flag, older library versions would + mis-interpret files with long names as broken. + (Florian Kainz) + * Reading luminance/chroma-encoded files via the RGBA + interface is faster: buffer padding avoids cache thrashing + for certain image sizes, redundant calls to saturation() + have been eliminated. + (Mike Wall) + * Added "hemispherical blur" option to exrenvmap. + (Florian Kainz) + * Added experimental version of I/O classes for ACES file + format (restricted OpenEXR format with special primaries + and white point); added exr2aces file converter. + (Florian Kainz) + * Added new constructors to classes Imf::RgbaInputFile and + Imf::TiledRgbaInputFile. The new constructors have a + layerName parameter, which allows the caller to specify + which layer of a multi-layer or multi-view image will + be read. + (Florian Kainz) + * A number of member functions in classes Imf::Header, + Imf::ChannelList and Imf::FrameBuffer have parameters + of type "const char *". Added equivalent functions that + take "const std::string &" parameters. + (Florian Kainz) + * Added library support for Weta Digital multi-view images: + StringVector attribute type, multiView standard attribute + of type StringVector, utility functions related to grouping + channels into separate views. + (Peter Hillman, Florian Kainz) + +Version 1.6.1: + * Removed Windows .suo files from distribution. + (Eric Wimmer) + * Bug fix: crashes, memory leaks and file descriptor leaks + when reading damaged image files (some reported by Apple, + others found by running IlmImfFuzzTest). + (Florian Kainz) + * Added new IlmImfFuzzTest program to test how resilient the + IlmImf library is with respect broken input files: the program + first damages OpenEXR files by partially overwriting them with + random data; then it tries to read the damaged files. If all + goes well, the program doesn't crash. + (Florian Kainz) + +Version 1.6.0: + * Bumped DSO version number to 6.0 + (Florian Kainz) + * Added new standard attributes related to color rendering with + CTL (Color Transformation Language): renderingTransform, + lookModTransform and adoptedNeutral. + (Florian Kainz) + * Bug fix: for pixels with luminance near HALF_MIN, conversion + from RGB to luminance/chroma produces NaNs and infinities + (Florian Kainz) + * Bug fix: excessive desaturation of small details with certain + colors after repeatedly loading and saving luminance/chroma + encoded images with B44 compression. + (Florian Kainz) + * Added B44A compression, a minor variation of B44: in most cases, + the compression ratio is 2.28:1, the same as with B44, but in + uniform image areas where all pixels have the same value, the + compression ratio increases to 10.66:1. Uniform areas occur, for + example, in an image's alpha channel, which typically contains + large patches that are solid black or white, or in computer- + generated images with a black background. + (Florian Kainz) + * Added flag to configure.ac to enable or disable use of large + auto arrays in the IlmImf library. Default is "enable" for + Linux, "disable" for everything else. + (Darby Johnston, Florian Kainz) + * corrected version number on dso's (libtool) - now 5.0 + * Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs + can link with static libraries properly + * eliminated some warning messages during install + (Andrew Kunz) + +Version 1.5.0: + * reorganized packaging of OpenEXR libraries to facilitate + integration with CTL. Now this library depends on the library + IlmBase. Some functionality has been moved into OpenEXR_Viewers, + which depends on two other libraries, CTL and OpenEXR_CTL. + Note: previously there were separate releases of + OpenEXR-related plugins for Renderman, Shake and Photoshop. + OpenEXR is supported natively by Rendermand and Photoshop, so + these plugins will not be supported for this or future + versions of OpenEXR. + (Andrew Kunz) + * New build scripts for Linux/Unix + (Andrew Kunz) + * New Windows project files and build scripts + (Kimball Thurston) + * float-to-half conversion now preserves the sign of float zeroes + and of floats that are so small that they become half zeroes. + (Florian Kainz) + * Bug fix: Imath::Frustum::planes() returns incorrect planes + if the frustum is orthogonal. + (Philip Hubbard) + * added new framesPerSecond optional standard attribute + (Florian Kainz) + * Imath cleanup: + - Rewrote function Imath::Quat::setRotation() to make it + numerically more accurate, added confidence tests + - Rewrote function Imath::Quat::slerp() using Don Hatch's + method, which is numerically more accurate, added confidence + tests. + - Rewrote functions Imath::closestPoints(), Imath::intersect(), + added confidence tests. + - Removed broken function Imath::nearestPointOnTriangle(). + - Rewrote Imath::drand48(), Imath::lrand48(), etc. to make + them functionally identical with the Unix/Linux versions + of drand48(), lrand48() and friends. + - Replaced redundant definitions of Int64 in Imath and IlmImf + with a single definition in ImathInt64.h. + (Florian Kainz) + * exrdisplay: if the file's and the display's RGB chromaticities + differ, the pixels RGB values are transformed from the file's + to the display's RGB space. + (Florian Kainz) + * Added new lossy B44 compression method. HALF channels are + compressed with a fixed ratio of 2.28:1. UINT and FLOAT + channels are stored verbatim, without compression. + (Florian Kainz) + +Version 1.4.0a: + * Fixed the ReleaseDLL targets for Visual Studio 2003. + (Barnaby Robson) + +Version 1.4.0: + * Production release. + * Bug Fix: calling setFrameBuffer() for every scan line + while reading a tiled file through the scan line API + returns bad pixel data. (Paul Schneider, Florian Kainz) + +Version 1.3.1: + * Fixed the ReleaseDLL targets for Visual Studio 2005. + (Nick Porcino, Drew Hess) + * Fixes/enhancements for createDLL. + (Nick Porcino) + +Version 1.3.0: + * Removed openexr.spec file, it's out of date and broken to + boot. + (Drew Hess) + * Support for Visual Studio 2005. + (Drew Hess, Nick Porcino) + * When compiling against OpenEXR headers on Windows, you + no longer need to define any HAVE_* or PLATFORM_* + macros in your projects. If you are using any OpenEXR + DLLs, however, you must define OPENEXR_DLL in your + project's preprocessor directives. + (Drew Hess) + * Many fixes to the Windows VC7 build system. + (Drew Hess, Nick Porcino) + * Support for building universal binaries on OS X 10.4. + (Drew Hess, Paul Schneider) + * Minor configure.ac fix to accomodate OS X's automake. + (Drew Hess) + * Removed CPU-specific optimizations from configure.ac, + autoconf's guess at the CPU type isn't very useful, + anyway. Closes #13429. + (Drew Hess) + * Fixed quoting for tests in configure.ac. Closes #13428. + (Drew Hess) + * Use host specification instead of target in configure.ac. + Closes #13427. + (Drew Hess) + * Fix use of AC_ARG_ENABLE in configure.ac. Closes + #13426. + (Drew Hess) + * Removed workaround for OS X istream::read bug. + (Drew Hess) + * Added pthread support to OpenEXR pkg-config file. + (Drew Hess) + * Added -no-undefined to LDFLAGS and required libs to LIBADD + for library projects with other library dependencies, per + Rex Dieter's patch. + (Drew Hess) + * HAVE_* macros are now defined in the OpenEXRConfig.h header + file instead of via compiler flags. There are a handful of + public headers which rely on the value of these macros, + and projects including these headers have previously needed + to define the same macros and values as used by OpenEXR's + 'configure', which is bad form. Now 'configure' writes these + values to the OpenEXRConfig.h header file, which is included + by any OpenEXR source files that need these macros. This + method of specifying HAVE_* macros guarantees that projects + will get the proper settings without needing to add compile- + time flags to accomodate OpenEXR. Note that this isn't + implemented properly for Windows yet. + (Drew Hess) + * Platform cleanups: + - No more support for IRIX or OSF1. + - No more explicit support for SunOS, because we have no way to + verify that it's working. I suspect that newish versions of + SunOS will just work out of the box, but let me know if not. + - No more PLATFORM_* macros (vestiges of the ILM internal build + system). PLATFORM_DARWIN_PPC is replaced by HAVE_DARWIN. + PLATFORM_REDHAT_IA32 (which was only used in IlmImfTest) is + replaced by HAVE_LINUX_PROCFS. + - OS X 10.4, which is the minimum version we're going to support + with this version, appears to have support for nrand48 and friends, + so no need to use the Imath-supplied version of them anymore. + (Drew Hess) + * No more PLATFORM_WINDOWS or PLATFORM_WIN32, replace with + proper standard Windows macros. (Drew Hess) + * Remove support for gcc 2.95, no longer supported. (Drew Hess) + * Eliminate HAVE_IOS_BASE macro, OpenEXR now requires support for + ios_base. (Drew Hess) + * Eliminate HAVE_STL_LIMITS macro, OpenEXR now requires the ISO C++ + header. (Drew Hess) + * Use double quote-style include dirctives for OpenEXR + includes. (Drew Hess) + * Added a document that gives an overview of the on-disk + layout of OpenEXR files (Florian Kainz) + * Added sections on layers and on memory-mapped file input + to the documentation. (Florian Kainz) + * Bug fix: reading an incomplete file causes a deadlock while + waiting on a semaphore. (Florian Kainz) + * Updated documentation (ReadingAndWritingImageFiles.sxw) and + sample code (IlmImfExamples): + Added a section about multi-threading, updated section on + thread-safety, changed documentation and sample code to use + readTiles()/writeTiles() instead of readTile()/writeTile() + where possible, mentioned that environment maps contain + redundant pixels, updated section on testing if a file is + an OpenEXR file. + (Florian Kainz) + * Multi-threading bug fixes (exceptions could be thrown + multiple times, some operations were not thread safe), + updated some comments, added comments, more multithreaded + testing. + (Florian Kainz) + * Added multi-threading support: multiple threads + cooperate to read or write a single OpenEXR file. + (Wojciech Jarosz) + * Added operator== and operator!= to Imath::Frustum. + (Andre Mazzone) + * Bug fix: Reading a PIZ-compressed file with an invalid + Huffman code table caused crashes by indexing off the + end of an array. + (Florian Kainz) + +Version 1.2.2: + * Updated README to remove option for building with Visual C++ 6.0. + (Drew Hess) + * Some older versions of gcc don't support a full iomanip + implemenation; check for this during configuration. + (Drew Hess) + * Install PDF versions of documentation, remove old/out-of-date + HTML documentation. (Florian Kainz) + * Removed vc/vc6 directory; Visual C++ 6.0 is no longer + supported. (Drew Hess) + * Updated README.win32 with details of new build system. + (Florian Kainz, Drew Hess) + * New build system for Windows / Visual C++ 7 builds both + static libraries and DLLs. + (Nick Porcino) + * Removed Imath::TMatrix and related classes, which are not + used anywhere in OpenEXR. + (Florian Kainz) + * Added minimal support for "image layers" to class Imf::ChannelList + (Florian Kainz) + * Added new isComplete() method to InputFile, TiledInputFile + etc., that checks if a file is complete or if any pixels + are missing (for example, because writing the file was + aborted prematurely). + (Florian Kainz) + * Exposed staticInitialize() function in ImfHeader.h in order + to allow thread-safe library initialization in multithreaded + programs. + (Florian Kainz) + * Added a new "time code" attribute + (Florian Kainz) + * exrmaketiled: when a MIPMAP_LEVELS or RIPMAP_LEVELS image + is produced, low-pass filtering takes samples outside the + image's data window. This requires extrapolating the image. + The user can now specify how the image is extrapolated + horizontally and vertically (image is surrounded by black / + outermost row of pixels repeats / entire image repeats / + entire image repeats, every other copy is a mirror image). + exrdisplay: added option to swap the top and botton half, + and the left and right half of an image, so that the image's + four corners end up in the center. This is useful for checking + the seams of wrap-around texture map images. + IlmImf library: Added new "wrapmodes" standard attribute + to indicate the extrapolation mode for MIPMAP_LEVELS and + RIPMAP_LEVELS images. + (Florian Kainz) + * Added a new "key code" attribute to identify motion picture + film frames. + (Florian Kainz) + * Removed #include from ImfAttribute.h, ImfHeader.h + and ImfXdr.h so that including header files such as + ImfInputFile.h no longer defines ASSERT and THROW macros, + which may conflict with similar macros defined by + application programs. + (Florian Kainz) + * Converted HTML documentation to OpenOffice format to + make maintaining the documents easier: + api.html -> ReadingAndWritingImageFiles.sxw + details.html -> TechnicalIntroduction.sxw + (Florian Kainz) + +Version 1.2.1: + * exrenvmap and exrmaketiled use slightly less memory + (Florian Kainz) + * Added functions to IlmImf for quickly testing if a file + is an OpenEXR file, and whether the file is scan-line + based or tiled. (Florian Kainz) + * Added preview image examples to IlmImfExamples. Added + description of preview images and environment maps to + docs/api.html (Florian Kainz) + * Bug fix: PXR24 compression did not work properly for channels + with ySampling != 1. + (Florian Kainz) + * Made template become template for + the transform(ObjectS, ObjectT) methods. This was done to allow + for differing templated objects to be passed in e.g. say a + Box> and a Matrix44, where S=float and T=double. + (Jeff Yost, Arkell Rasiah) + * New method Matrix44::setTheMatrix(). Used for assigning a + M44f to a M44d. (Jeff Yost, Arkell Rasiah) + * Added convenience Color typedefs for half versions of Color3 + and Color4. Note the Makefile.am for both Imath and ImathTest + have been updated with -I and/or -L pathing to Half. + (Max Chen, Arkell Rasiah) + * Methods equalWithAbsError() and equalWithRelError() are now + declared as const. (Colette Mullenhoff, Arkell Rasiah) + * Fixes for gcc34. Mainly typename/template/using/this syntax + correctness changes. (Nick Ramussen, Arkell Rasiah) + * Added Custom low-level file I/O examples to IlmImfExamples + and to the docs/api.html document. (Florian Kainz) + * Eliminated most warnings messages when OpenEXR is compiled + with Visual C++. The OpenEXR code uses lots of (intentional + and unintended) implicit type conversions. By default, Visual + C++ warns about almost all of them. Most implicit conversions + have been removed from the .h files, so that including them + should not generate warnings even at warning level 3. Most + .cpp files are now compiled with warning level 1. + (Florian Kainz) + +Version 1.2.0: + * Production-ready release. + * Disable long double warnings on OS X. (Drew Hess) + * Add new source files to VC7 IlmImfDll target. (Drew Hess) + * Iex: change the way that APPEND_EXC and REPLACE_EXC modify + their what() string to work around an issue with Visual C++ + 7.1. (Florian Kainz, Nick Porcino) + * Bumped OpenEXR version to 1.2 and .so versions to 2.0.0 in + preparation for the release. (Drew Hess) + * Imath: fixed ImathTMatrix.h to work with gcc 3.4. (Drew Hess) + * Another quoting fix in openexr.m4. (Drew Hess) + * Quoting fix in acinclude.m4 for automake 1.8. (Brad Hards) + * Imath: put inline at beginning of declaration in ImathMatrix.h + to fix a warning. (Ken McGaugh) + * Imath: made Vec equalWith*Error () methods const. + * Cleaned up compile-time Win32 support. (Florian Kainz) + * Bug fix: Reading a particular broken PIZ-compressed file + caused crashes by indexing off the end of an array. + (Florian Kainz) + +Version 1.1.1: + * Half: operator= and variants now return by reference rather + than by value. This brings half into conformance with + built-in types. (Drew Hess) + * Half: remove copy constructor, let compiler supply its + own. This improves performance up to 25% on some + expressions using half. (Drew Hess) + * configure: don't try to be fancy with CXXFLAGS, just use + what the user supplies or let configure choose a sensible + default if CXXFLAGS is not defined. + * IlmImf: fixed a bug in reading scanline files on big-endian + architectures. (Drew Hess) + * exrmaketiled: Added an option to select compression type. + (Florian Kainz) + * exrenvmap: Added an option to select compression type. + (Florian Kainz) + * exrdisplay: Added some new command-line options. (Florian Kainz) + * IlmImf: Added Pixar's new "slightly lossy" image compression + method. The new method, named PXR24, preserves HALF and + UINT data without loss, but FLOAT pixels are converted to + a 24-bit representation. PXR24 appears to compress + FLOAT depth buffers very well without losing much accuracy. + (Loren Carpenter, Florian Kainz) + * Changed top-level LICENSE file to allow for other copyright + holders for individual files. + * IlmImf: TILED FILE FORMAT CHANGE. TiledOutputFile was + incorrectly interleaving channels and scanlines before + passing pixel data to a compressor. The lossless compressors + still work, but lossy compressors do not. Fix the bug by + interleaving channels and scanlines in tiled files in the + same way as ScanLineOutputFile does. Programs compiled with + the new version of IlmImf cannot read tiled images produced + with version 1.1.0. (Florian Kainz) + * IlmImf: ImfXdr.h fix for 64-bit architectures. (Florian Kainz) + * IlmImf: OpenEXR now supports YCA (luminance/chroma/alpha) + images with subsampled chroma channels. When an image + is written with the RGBA convenience interface, selecting + WRITE_YCA instead of WRITE_RGBA causes the library to + convert the pixels to YCA format. If WRITE_Y is selected, + only luminance is stored in the file (for black and white + images). When an image file is read with the RGBA convenience + interface, YCA data are automatically converted back to RGBA. + (Florian Kainz) + * IlmImf: speed up reading tiled files as scan lines. + (Florian Kainz) + * Half: Fixed subtle bug in Half where signaling float NaNs + were being converted to inf in half. (Florian Kainz) + * gcc 3.3 compiler warning cleanups. (various) + * Imath: ImathEuler.h fixes for gcc 3.4. (Garrick Meeker) + +Version 1.1.0: + * Added new targets to Visual C++ .NET 2003 project + for exrmaketiled, exrenvmap, exrmakepreview, and exrstdattr. + (Drew Hess) + * A few assorted Win32 fixes for Imath. (Drew Hess) + * GNU autoconf builds now produce versioned libraries. + This release is 1:0:0. (Drew Hess) + * Fixes for Visual C++ .NET 2003. (Paul Schneider) + * Updated Visual C++ zlib project file to zlib 1.2.1. + (Drew Hess) + * exrdisplay: Fixed fragment shader version. (Drew Hess) + * *Test: Fixed some compiler issues. (Drew Hess) + * Imath: Handle "restrict" keyword properly. (Drew Hess) + * IlmImfExamples: Updated to latest versions of example + source code, includes tiling and multi-res images. + (Florian Kainz) + * exrmakepreview: A new utility to create preview images. + (Florian Kainz) + * exrenvmap: A new utility to create OpenEXR environment + maps. (Florian Kainz) + * exrstdattr: A new utility to modify standard + attributes. (Florian Kainz) + * Updated exrheader to print level rounding mode and + preview image size. (Florian Kainz) + * Updated exrmaketiled to use level rounding mode. + (Florian Kainz) + * IlmImf: Changed the orientation of lat-long envmaps to + match typical panoramic camera setups. (Florian Kainz) + * IlmImf: Fixed a bug where partially-completed files with + DECREASING_Y could not be read. (Florian Kainz) + * IlmImf: Added support for selectable rounding mode (up/down) + when generating multiresolution files. (Florian Kainz) + * exrdisplay: Support for tiled images, mip/ripmaps, preview + images, and display windows. (Florian Kainz, Drew Hess) + * exrmaketiled: A new utility which generates tiled + versions of OpenEXR images. (Florian Kainz) + * IlmImf: Changed Imf::VERSION to Imf::EXR_VERSION to + work around problems with autoconf VERSION macro + conflict. (Drew Hess) + * exrheader: Support for tiles, mipmaps, environment + maps. (Florian Kainz) + * IlmImf: Environment map support. (Florian Kainz) + * IlmImf: Abstracted stream I/O support. (Florian Kainz) + * IlmImf: Support for tiled and mip/ripmapped files; + requires new file format. (Wojciech Jarosz, Florian Kainz) + * Imath: TMatrix*, generic 2D matricies and algorithms. + (Francesco Callari) + * Imath: major quaternions cleanup. (Cary Phillips) + * Imath: added GLBegin, GLPushAttrib, GLPushMatrix objects + for automatic cleanup on exceptions. (Cary Phillips) + * Imath: removed implicit scalar->vector promotions and vector + comparisons. (Nick Rasmussen) + +Version 1.0.7: + * Fixed a typo in one of the IlmImfTest tests. (Paul Schneider) + * Fixed a bug in exrdisplay that causes the image to display + as all black if there's a NaN or infinity in an OpenEXR + image. (Florian Kainz) + * Updated exrheader per recent changes to IlmImf library. + (Florian Kainz) + * Changed an errant float to a T in ImathFrame.h nextFrame(). + (Cary Phillips) + * Support for new "optional standard" attributes + (chromaticities, luminance, comments, etc.). + (Florian Kainz, Greg Ward, Joseph Goldstone) + * Fixed a buffer overrun in ImfOpaqueAttribute. (Paul Schneider) + * Added new function, isImfMagic (). (Florian Kainz) + +Version 1.0.6: + * Added README.win32 to disted files. + * Fixed OpenEXR.pc.in pkg-config file, OpenEXR now works + with pkg-config. + * Random fixes to readme files for new release. + * Fixed openexr.m4, now looks in /usr by default. + * Added Visual Studio .NET 2003 "solution." + * Fixes for Visual Studio .NET 2003 w/ Microsoft C++ compiler. + (Various) + * Random Imath fixes and enhancements. Note that + extractSHRT now takes an additional optional + argument, see ImathMatrixAlgo.h for details. (Various) + * Added Wojciech Jarosz to AUTHORS file. + * Added test cases for uncompressed case, preview images, + frame buffer type conversion. (Wojciech Jarosz, + Florian Kainz) + * Fix a bug in IlmImf where uncompressed data doesn't get + read/written correctly. (Wojciech Jarosz) + * Added support for preview images and preview image + attributes (thumbnail images) in IlmImf. (Florian Kainz) + * Added support for automatic frame buffer type conversion + in IlmImf. (Florian Kainz) + * Cleaned up some compile-time checks. + * Added HalfTest unit tests. + * [exrdisplay] Download half framebuffer to texture memory + instead of converting to float first. Requires latest + Nvidia drivers. + +Version 1.0.5: + * Fixed IlmImf.dll to use static runtime libs (Andreas). + * Added exrheader project to Visual Studio 6.0 workspace. + * Added some example code showing how to use the IlmImf library. + (Florian) + * Use DLL runtime libs for Win32 libraries rather than static + runtime libs. + * Add an exrdisplay_fragshader project to the Visual Studio 6.0 + workspace to enable fragment shaders in Win32. + * Add an IlmImfDll project to the Visual Studio 6.0 workspace. + * In Win32, export the ImfCRgbaFile C interface via a DLL so + that Visual C++ 6.0 users can link against an Intel-compiled + IlmImf. (Andreas Kahler) + * Use auto_ptr in ImfAutoArray on Win32, it doesn't like large + automatic stacks. + * Performance improvements in PIZ decoding, between + 20 and 60% speedup on Athlon and Pentium 4 systems. + (Florian) + * Updated the README with various information, made + some cosmetic changes for readability. + * Added fragment shader support to exrdisplay. + * Bumped the version to 1.0.5 in prep for release. + * Updated README and README.OSX to talk about CodeWarrior + project files. + * Incorporated Rodrigo Damazio's patch for an openexr.m4 + macro file and an openexr.spec file for building RPMs. + * Small change in ImfAttribute.h to make IlmImf compile with gcc 2.95. + * Updated ImfDoubleAttribute.h for Codewarrior on MacOS. + * Added exrheader utility. + * Update to AUTHORS file. + * Added a README.win32 file. + * Added project files for Visual Studio 6.0. + * Initial Win32 port. Requires Visual Studio 6.0 and Intel C++ + compiler version 7.0. + * Added new intersectT method in ImathSphere.h + * Fixed some bugs in ImathQuat.h + * Proper use of fltk-config to get platform-specific FLTK + compile- and link-time flags. + * exrdisplay uses Imath::Math::pow instead of powf now. + powf is not availble on all platforms. + * Roll OS X "hack" into the source until Apple fixes their + istream implementation. + +Version 1.0.4: + * OpenEXR is now covered by a modified BSD license. See LICENSE + for the new terms. + +Version 1.0.3: + + * OpenEXR is now in sf.net CVS. + * Imf::Xdr namespace cleanups. + * Some IlmImfTest cleanups for OS X. + * Use .cpp extension in exrdisplay sources. + * Iex cleanups. + * Make IlmImf compile with Metrowerks Codewarrior. + * Change large automatic stacks in ImfHuf.C to auto_ptrs allocated + off the heap. MacOS X default stack size isn't large enough. + * std::ios fix for MacOS X in ImfInputFile.C. + * Added new FP predecessor/successor functions to Imath, added + tests to ImathTest + * Fixed a bug in Imath::extractSHRT for 3x3 matricies when + exactly one of the original scaling factors is negative, updated + ImathTest to check this case. + * Install include files when 'make install' is run. + * exrdisplay requires fltk 1.1+ now in an effort to support + a MacOS X display program (fltk 1.1 runs on OS X), though this + is untested. + * renamed configure.in to configure.ac + * Removed some tests from IexTest that are no longer used. + * Removed ImfHalfXdr.h, it's not used anymore. + * Revamped the autoconf system, added some compile-time + optimizations, a pkgconfig target, and some maintainer-specific + stuff. + +Version 1.0.2: + + * More OS X fixes in Imath, IlmImf and IlmImfTest. + * Imath updates. + * Fixed a rotation bug in Imath + +Version 1.0.1: + + * Used autoconf 2.53 and automake 1.6 to generate build environment. + * Makefile.am cleanups. + * OS X fixes. + * removed images directory (now distributed separately). + +Version 1.0: + + * first official release. + * added some high-level documentation, removed the old OpenEXR.html + documentation. + * fixed a few nagging build problems. + * bumped IMV_VERSION_NUMBER to 2 + +Version 0.9: + + * added exrdisplay viewer application. + * cleanup _data in Imf::InputFile and Imf::OutputFile constructors. + * removed old ILM copyright notices. + +Version 0.8: + + * Initial release. diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#include +#include + +using namespace std; + +//----------------------------------------------------- +// Compute a lookup table for float-to-half conversion. +// +// When indexed with the combined sign and exponent of +// a float, the table either returns the combined sign +// and exponent of the corresponding half, or zero if +// the corresponding half may not be normalized (zero, +// denormalized, overflow). +//----------------------------------------------------- + +void +initELut (unsigned short eLut[]) +{ + for (int i = 0; i < 0x100; i++) + { + int e = (i & 0x0ff) - (127 - 15); + + if (e <= 0 || e >= 30) + { + // + // Special case + // + + eLut[i] = 0; + eLut[i | 0x100] = 0; + } + else + { + // + // Common case - normalized half, no exponent overflow possible + // + + eLut[i] = (e << 10); + eLut[i | 0x100] = ((e << 10) | 0x8000); + } + } +} + + +//------------------------------------------------------------ +// Main - prints the sign-and-exponent conversion lookup table +//------------------------------------------------------------ + +int +main () +{ + const int tableSize = 1 << 9; + unsigned short eLut[tableSize]; + initELut (eLut); + + cout << "//\n" + "// This is an automatically generated file.\n" + "// Do not edit.\n" + "//\n\n"; + + cout << "{\n "; + + for (int i = 0; i < tableSize; i++) + { + cout << setw (5) << eLut[i] << ", "; + + if (i % 8 == 7) + { + cout << "\n"; + + if (i < tableSize - 1) + cout << " "; + } + } + + cout << "};\n"; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/eLut.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,71 @@ +// +// This is an automatically generated file. +// Do not edit. +// + +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, + 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, + 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, + 24576, 25600, 26624, 27648, 28672, 29696, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 33792, 34816, 35840, 36864, 37888, 38912, 39936, + 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, + 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, + 57344, 58368, 59392, 60416, 61440, 62464, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/half.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/half.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/half.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/half.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,311 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +// Primary authors: +// Florian Kainz +// Rod Bogart + + +//--------------------------------------------------------------------------- +// +// class half -- +// implementation of non-inline members +// +//--------------------------------------------------------------------------- + +#include +#include "half.h" + +using namespace std; + +//------------------------------------------------------------- +// Lookup tables for half-to-float and float-to-half conversion +//------------------------------------------------------------- + +HALF_EXPORT_CONST half::uif half::_toFloat[1 << 16] = +#include "toFloat.h" +HALF_EXPORT_CONST unsigned short half::_eLut[1 << 9] = +#include "eLut.h" + + +//----------------------------------------------- +// Overflow handler for float-to-half conversion; +// generates a hardware floating-point overflow, +// which may be trapped by the operating system. +//----------------------------------------------- + +float +half::overflow () +{ + volatile float f = 1e10; + + for (int i = 0; i < 10; i++) + f *= f; // this will overflow before + // the for­loop terminates + return f; +} + + +//----------------------------------------------------- +// Float-to-half conversion -- general case, including +// zeroes, denormalized numbers and exponent overflows. +//----------------------------------------------------- + +short +half::convert (int i) +{ + // + // Our floating point number, f, is represented by the bit + // pattern in integer i. Disassemble that bit pattern into + // the sign, s, the exponent, e, and the significand, m. + // Shift s into the position where it will go in in the + // resulting half number. + // Adjust e, accounting for the different exponent bias + // of float and half (127 versus 15). + // + + register int s = (i >> 16) & 0x00008000; + register int e = ((i >> 23) & 0x000000ff) - (127 - 15); + register int m = i & 0x007fffff; + + // + // Now reassemble s, e and m into a half: + // + + if (e <= 0) + { + if (e < -10) + { + // + // E is less than -10. The absolute value of f is + // less than HALF_MIN (f may be a small normalized + // float, a denormalized float or a zero). + // + // We convert f to a half zero with the same sign as f. + // + + return s; + } + + // + // E is between -10 and 0. F is a normalized float + // whose magnitude is less than HALF_NRM_MIN. + // + // We convert f to a denormalized half. + // + + // + // Add an explicit leading 1 to the significand. + // + + m = m | 0x00800000; + + // + // Round to m to the nearest (10+e)-bit value (with e between + // -10 and 0); in case of a tie, round to the nearest even value. + // + // Rounding may cause the significand to overflow and make + // our number normalized. Because of the way a half's bits + // are laid out, we don't have to treat this case separately; + // the code below will handle it correctly. + // + + int t = 14 - e; + int a = (1 << (t - 1)) - 1; + int b = (m >> t) & 1; + + m = (m + a + b) >> t; + + // + // Assemble the half from s, e (zero) and m. + // + + return s | m; + } + else if (e == 0xff - (127 - 15)) + { + if (m == 0) + { + // + // F is an infinity; convert f to a half + // infinity with the same sign as f. + // + + return s | 0x7c00; + } + else + { + // + // F is a NAN; we produce a half NAN that preserves + // the sign bit and the 10 leftmost bits of the + // significand of f, with one exception: If the 10 + // leftmost bits are all zero, the NAN would turn + // into an infinity, so we have to set at least one + // bit in the significand. + // + + m >>= 13; + return s | 0x7c00 | m | (m == 0); + } + } + else + { + // + // E is greater than zero. F is a normalized float. + // We try to convert f to a normalized half. + // + + // + // Round to m to the nearest 10-bit value. In case of + // a tie, round to the nearest even value. + // + + m = m + 0x00000fff + ((m >> 13) & 1); + + if (m & 0x00800000) + { + m = 0; // overflow in significand, + e += 1; // adjust exponent + } + + // + // Handle exponent overflow + // + + if (e > 30) + { + overflow (); // Cause a hardware floating point overflow; + return s | 0x7c00; // if this returns, the half becomes an + } // infinity with the same sign as f. + + // + // Assemble the half from s, e and m. + // + + return s | (e << 10) | (m >> 13); + } +} + + +//--------------------- +// Stream I/O operators +//--------------------- + +ostream & +operator << (ostream &os, half h) +{ + os << float (h); + return os; +} + + +istream & +operator >> (istream &is, half &h) +{ + float f; + is >> f; + h = half (f); + return is; +} + + +//--------------------------------------- +// Functions to print the bit-layout of +// floats and halfs, mostly for debugging +//--------------------------------------- + +void +printBits (ostream &os, half h) +{ + unsigned short b = h.bits(); + + for (int i = 15; i >= 0; i--) + { + os << (((b >> i) & 1)? '1': '0'); + + if (i == 15 || i == 10) + os << ' '; + } +} + + +void +printBits (ostream &os, float f) +{ + half::uif x; + x.f = f; + + for (int i = 31; i >= 0; i--) + { + os << (((x.i >> i) & 1)? '1': '0'); + + if (i == 31 || i == 23) + os << ' '; + } +} + + +void +printBits (char c[19], half h) +{ + unsigned short b = h.bits(); + + for (int i = 15, j = 0; i >= 0; i--, j++) + { + c[j] = (((b >> i) & 1)? '1': '0'); + + if (i == 15 || i == 10) + c[++j] = ' '; + } + + c[18] = 0; +} + + +void +printBits (char c[35], float f) +{ + half::uif x; + x.f = f; + + for (int i = 31, j = 0; i >= 0; i--, j++) + { + c[j] = (((x.i >> i) & 1)? '1': '0'); + + if (i == 31 || i == 23) + c[++j] = ' '; + } + + c[34] = 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/half.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/half.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/half.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/half.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,766 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +// Primary authors: +// Florian Kainz +// Rod Bogart + +//--------------------------------------------------------------------------- +// +// half -- a 16-bit floating point number class: +// +// Type half can represent positive and negative numbers whose +// magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative +// error of 9.8e-4; numbers smaller than 6.1e-5 can be represented +// with an absolute error of 6.0e-8. All integers from -2048 to +// +2048 can be represented exactly. +// +// Type half behaves (almost) like the built-in C++ floating point +// types. In arithmetic expressions, half, float and double can be +// mixed freely. Here are a few examples: +// +// half a (3.5); +// float b (a + sqrt (a)); +// a += b; +// b += a; +// b = a + 7; +// +// Conversions from half to float are lossless; all half numbers +// are exactly representable as floats. +// +// Conversions from float to half may not preserve a float's value +// exactly. If a float is not representable as a half, then the +// float value is rounded to the nearest representable half. If a +// float value is exactly in the middle between the two closest +// representable half values, then the float value is rounded to +// the closest half whose least significant bit is zero. +// +// Overflows during float-to-half conversions cause arithmetic +// exceptions. An overflow occurs when the float value to be +// converted is too large to be represented as a half, or if the +// float value is an infinity or a NAN. +// +// The implementation of type half makes the following assumptions +// about the implementation of the built-in C++ types: +// +// float is an IEEE 754 single-precision number +// sizeof (float) == 4 +// sizeof (unsigned int) == sizeof (float) +// alignof (unsigned int) == alignof (float) +// sizeof (unsigned short) == 2 +// +//--------------------------------------------------------------------------- + +#ifndef _HALF_H_ +#define _HALF_H_ + +#include + +#if defined(OPENEXR_DLL) + #if defined(HALF_EXPORTS) + #define HALF_EXPORT __declspec(dllexport) + #else + #define HALF_EXPORT __declspec(dllimport) + #endif + #define HALF_EXPORT_CONST +#else + #define HALF_EXPORT + #define HALF_EXPORT_CONST const +#endif + +class HALF_EXPORT half +{ + public: + + //------------- + // Constructors + //------------- + + half (); // no initialization + half (float f); + + + //-------------------- + // Conversion to float + //-------------------- + + operator float () const; + + + //------------ + // Unary minus + //------------ + + half operator - () const; + + + //----------- + // Assignment + //----------- + + half & operator = (half h); + half & operator = (float f); + + half & operator += (half h); + half & operator += (float f); + + half & operator -= (half h); + half & operator -= (float f); + + half & operator *= (half h); + half & operator *= (float f); + + half & operator /= (half h); + half & operator /= (float f); + + + //--------------------------------------------------------- + // Round to n-bit precision (n should be between 0 and 10). + // After rounding, the significand's 10-n least significant + // bits will be zero. + //--------------------------------------------------------- + + half round (unsigned int n) const; + + + //-------------------------------------------------------------------- + // Classification: + // + // h.isFinite() returns true if h is a normalized number, + // a denormalized number or zero + // + // h.isNormalized() returns true if h is a normalized number + // + // h.isDenormalized() returns true if h is a denormalized number + // + // h.isZero() returns true if h is zero + // + // h.isNan() returns true if h is a NAN + // + // h.isInfinity() returns true if h is a positive + // or a negative infinity + // + // h.isNegative() returns true if the sign bit of h + // is set (negative) + //-------------------------------------------------------------------- + + bool isFinite () const; + bool isNormalized () const; + bool isDenormalized () const; + bool isZero () const; + bool isNan () const; + bool isInfinity () const; + bool isNegative () const; + + + //-------------------------------------------- + // Special values + // + // posInf() returns +infinity + // + // negInf() returns -infinity + // + // qNan() returns a NAN with the bit + // pattern 0111111111111111 + // + // sNan() returns a NAN with the bit + // pattern 0111110111111111 + //-------------------------------------------- + + static half posInf (); + static half negInf (); + static half qNan (); + static half sNan (); + + + //-------------------------------------- + // Access to the internal representation + //-------------------------------------- + + unsigned short bits () const; + void setBits (unsigned short bits); + + + public: + + union uif + { + unsigned int i; + float f; + }; + + private: + + static short convert (int i); + static float overflow (); + + unsigned short _h; + + static HALF_EXPORT_CONST uif _toFloat[1 << 16]; + static HALF_EXPORT_CONST unsigned short _eLut[1 << 9]; +}; + +//----------- +// Stream I/O +//----------- + +HALF_EXPORT std::ostream & operator << (std::ostream &os, half h); +HALF_EXPORT std::istream & operator >> (std::istream &is, half &h); + + +//---------- +// Debugging +//---------- + +HALF_EXPORT void printBits (std::ostream &os, half h); +HALF_EXPORT void printBits (std::ostream &os, float f); +HALF_EXPORT void printBits (char c[19], half h); +HALF_EXPORT void printBits (char c[35], float f); + + +//------------------------------------------------------------------------- +// Limits +// +// Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float +// constants, but at least one other compiler (gcc 2.96) produces incorrect +// results if they are. +//------------------------------------------------------------------------- + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER + + #define HALF_MIN 5.96046448e-08f // Smallest positive half + + #define HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half + + #define HALF_MAX 65504.0f // Largest positive half + + #define HALF_EPSILON 0.00097656f // Smallest positive e for which + // half (1.0 + e) != half (1.0) +#else + + #define HALF_MIN 5.96046448e-08 // Smallest positive half + + #define HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half + + #define HALF_MAX 65504.0 // Largest positive half + + #define HALF_EPSILON 0.00097656 // Smallest positive e for which + // half (1.0 + e) != half (1.0) +#endif + + +#define HALF_MANT_DIG 11 // Number of digits in mantissa + // (significand + hidden leading 1) + +#define HALF_DIG 2 // Number of base 10 digits that + // can be represented without change + +#define HALF_RADIX 2 // Base of the exponent + +#define HALF_MIN_EXP -13 // Minimum negative integer such that + // HALF_RADIX raised to the power of + // one less than that integer is a + // normalized half + +#define HALF_MAX_EXP 16 // Maximum positive integer such that + // HALF_RADIX raised to the power of + // one less than that integer is a + // normalized half + +#define HALF_MIN_10_EXP -4 // Minimum positive integer such + // that 10 raised to that power is + // a normalized half + +#define HALF_MAX_10_EXP 4 // Maximum positive integer such + // that 10 raised to that power is + // a normalized half + + +//--------------------------------------------------------------------------- +// +// Implementation -- +// +// Representation of a float: +// +// We assume that a float, f, is an IEEE 754 single-precision +// floating point number, whose bits are arranged as follows: +// +// 31 (msb) +// | +// | 30 23 +// | | | +// | | | 22 0 (lsb) +// | | | | | +// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX +// +// s e m +// +// S is the sign-bit, e is the exponent and m is the significand. +// +// If e is between 1 and 254, f is a normalized number: +// +// s e-127 +// f = (-1) * 2 * 1.m +// +// If e is 0, and m is not zero, f is a denormalized number: +// +// s -126 +// f = (-1) * 2 * 0.m +// +// If e and m are both zero, f is zero: +// +// f = 0.0 +// +// If e is 255, f is an "infinity" or "not a number" (NAN), +// depending on whether m is zero or not. +// +// Examples: +// +// 0 00000000 00000000000000000000000 = 0.0 +// 0 01111110 00000000000000000000000 = 0.5 +// 0 01111111 00000000000000000000000 = 1.0 +// 0 10000000 00000000000000000000000 = 2.0 +// 0 10000000 10000000000000000000000 = 3.0 +// 1 10000101 11110000010000000000000 = -124.0625 +// 0 11111111 00000000000000000000000 = +infinity +// 1 11111111 00000000000000000000000 = -infinity +// 0 11111111 10000000000000000000000 = NAN +// 1 11111111 11111111111111111111111 = NAN +// +// Representation of a half: +// +// Here is the bit-layout for a half number, h: +// +// 15 (msb) +// | +// | 14 10 +// | | | +// | | | 9 0 (lsb) +// | | | | | +// X XXXXX XXXXXXXXXX +// +// s e m +// +// S is the sign-bit, e is the exponent and m is the significand. +// +// If e is between 1 and 30, h is a normalized number: +// +// s e-15 +// h = (-1) * 2 * 1.m +// +// If e is 0, and m is not zero, h is a denormalized number: +// +// S -14 +// h = (-1) * 2 * 0.m +// +// If e and m are both zero, h is zero: +// +// h = 0.0 +// +// If e is 31, h is an "infinity" or "not a number" (NAN), +// depending on whether m is zero or not. +// +// Examples: +// +// 0 00000 0000000000 = 0.0 +// 0 01110 0000000000 = 0.5 +// 0 01111 0000000000 = 1.0 +// 0 10000 0000000000 = 2.0 +// 0 10000 1000000000 = 3.0 +// 1 10101 1111000001 = -124.0625 +// 0 11111 0000000000 = +infinity +// 1 11111 0000000000 = -infinity +// 0 11111 1000000000 = NAN +// 1 11111 1111111111 = NAN +// +// Conversion: +// +// Converting from a float to a half requires some non-trivial bit +// manipulations. In some cases, this makes conversion relatively +// slow, but the most common case is accelerated via table lookups. +// +// Converting back from a half to a float is easier because we don't +// have to do any rounding. In addition, there are only 65536 +// different half numbers; we can convert each of those numbers once +// and store the results in a table. Later, all conversions can be +// done using only simple table lookups. +// +//--------------------------------------------------------------------------- + + +//-------------------- +// Simple constructors +//-------------------- + +inline +half::half () +{ + // no initialization +} + + +//---------------------------- +// Half-from-float constructor +//---------------------------- + +inline +half::half (float f) +{ + uif x; + + x.f = f; + + if (f == 0) + { + // + // Common special case - zero. + // Preserve the zero's sign bit. + // + + _h = (x.i >> 16); + } + else + { + // + // We extract the combined sign and exponent, e, from our + // floating-point number, f. Then we convert e to the sign + // and exponent of the half number via a table lookup. + // + // For the most common case, where a normalized half is produced, + // the table lookup returns a non-zero value; in this case, all + // we have to do is round f's significand to 10 bits and combine + // the result with e. + // + // For all other cases (overflow, zeroes, denormalized numbers + // resulting from underflow, infinities and NANs), the table + // lookup returns zero, and we call a longer, non-inline function + // to do the float-to-half conversion. + // + + register int e = (x.i >> 23) & 0x000001ff; + + e = _eLut[e]; + + if (e) + { + // + // Simple case - round the significand, m, to 10 + // bits and combine it with the sign and exponent. + // + + register int m = x.i & 0x007fffff; + _h = e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13); + } + else + { + // + // Difficult case - call a function. + // + + _h = convert (x.i); + } + } +} + + +//------------------------------------------ +// Half-to-float conversion via table lookup +//------------------------------------------ + +inline +half::operator float () const +{ + return _toFloat[_h].f; +} + + +//------------------------- +// Round to n-bit precision +//------------------------- + +inline half +half::round (unsigned int n) const +{ + // + // Parameter check. + // + + if (n >= 10) + return *this; + + // + // Disassemble h into the sign, s, + // and the combined exponent and significand, e. + // + + unsigned short s = _h & 0x8000; + unsigned short e = _h & 0x7fff; + + // + // Round the exponent and significand to the nearest value + // where ones occur only in the (10-n) most significant bits. + // Note that the exponent adjusts automatically if rounding + // up causes the significand to overflow. + // + + e >>= 9 - n; + e += e & 1; + e <<= 9 - n; + + // + // Check for exponent overflow. + // + + if (e >= 0x7c00) + { + // + // Overflow occurred -- truncate instead of rounding. + // + + e = _h; + e >>= 10 - n; + e <<= 10 - n; + } + + // + // Put the original sign bit back. + // + + half h; + h._h = s | e; + + return h; +} + + +//----------------------- +// Other inline functions +//----------------------- + +inline half +half::operator - () const +{ + half h; + h._h = _h ^ 0x8000; + return h; +} + + +inline half & +half::operator = (half h) +{ + _h = h._h; + return *this; +} + + +inline half & +half::operator = (float f) +{ + *this = half (f); + return *this; +} + + +inline half & +half::operator += (half h) +{ + *this = half (float (*this) + float (h)); + return *this; +} + + +inline half & +half::operator += (float f) +{ + *this = half (float (*this) + f); + return *this; +} + + +inline half & +half::operator -= (half h) +{ + *this = half (float (*this) - float (h)); + return *this; +} + + +inline half & +half::operator -= (float f) +{ + *this = half (float (*this) - f); + return *this; +} + + +inline half & +half::operator *= (half h) +{ + *this = half (float (*this) * float (h)); + return *this; +} + + +inline half & +half::operator *= (float f) +{ + *this = half (float (*this) * f); + return *this; +} + + +inline half & +half::operator /= (half h) +{ + *this = half (float (*this) / float (h)); + return *this; +} + + +inline half & +half::operator /= (float f) +{ + *this = half (float (*this) / f); + return *this; +} + + +inline bool +half::isFinite () const +{ + unsigned short e = (_h >> 10) & 0x001f; + return e < 31; +} + + +inline bool +half::isNormalized () const +{ + unsigned short e = (_h >> 10) & 0x001f; + return e > 0 && e < 31; +} + + +inline bool +half::isDenormalized () const +{ + unsigned short e = (_h >> 10) & 0x001f; + unsigned short m = _h & 0x3ff; + return e == 0 && m != 0; +} + + +inline bool +half::isZero () const +{ + return (_h & 0x7fff) == 0; +} + + +inline bool +half::isNan () const +{ + unsigned short e = (_h >> 10) & 0x001f; + unsigned short m = _h & 0x3ff; + return e == 31 && m != 0; +} + + +inline bool +half::isInfinity () const +{ + unsigned short e = (_h >> 10) & 0x001f; + unsigned short m = _h & 0x3ff; + return e == 31 && m == 0; +} + + +inline bool +half::isNegative () const +{ + return (_h & 0x8000) != 0; +} + + +inline half +half::posInf () +{ + half h; + h._h = 0x7c00; + return h; +} + + +inline half +half::negInf () +{ + half h; + h._h = 0xfc00; + return h; +} + + +inline half +half::qNan () +{ + half h; + h._h = 0x7fff; + return h; +} + + +inline half +half::sNan () +{ + half h; + h._h = 0x7dff; + return h; +} + + +inline unsigned short +half::bits () const +{ + return _h; +} + + +inline void +half::setBits (unsigned short bits) +{ + _h = bits; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/halfFunction.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/halfFunction.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/halfFunction.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/halfFunction.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,178 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +// Primary authors: +// Florian Kainz +// Rod Bogart + + +//--------------------------------------------------------------------------- +// +// halfFunction -- a class for fast evaluation +// of half --> T functions +// +// The constructor for a halfFunction object, +// +// halfFunction (function, +// domainMin, domainMax, +// defaultValue, +// posInfValue, negInfValue, +// nanValue); +// +// evaluates the function for all finite half values in the interval +// [domainMin, domainMax], and stores the results in a lookup table. +// For finite half values that are not in [domainMin, domainMax], the +// constructor stores defaultValue in the table. For positive infinity, +// negative infinity and NANs, posInfValue, negInfValue and nanValue +// are stored in the table. +// +// The tabulated function can then be evaluated quickly for arbitrary +// half values by calling the the halfFunction object's operator() +// method. +// +// Example: +// +// #include +// #include +// +// halfFunction hsin (sin); +// +// halfFunction hsqrt (sqrt, // function +// 0, HALF_MAX, // domain +// half::qNan(), // sqrt(x) for x < 0 +// half::posInf(), // sqrt(+inf) +// half::qNan(), // sqrt(-inf) +// half::qNan()); // sqrt(nan) +// +// half x = hsin (1); +// half y = hsqrt (3.5); +// +//--------------------------------------------------------------------------- + +#ifndef _HALF_FUNCTION_H_ +#define _HALF_FUNCTION_H_ + +#include "half.h" + +#include +#ifndef ILMBASE_HAVE_LARGE_STACK +#include // need this for memset +#else +#endif + +#include + + +template +class halfFunction +{ + public: + + //------------ + // Constructor + //------------ + + template + halfFunction (Function f, + half domainMin = -HALF_MAX, + half domainMax = HALF_MAX, + T defaultValue = 0, + T posInfValue = 0, + T negInfValue = 0, + T nanValue = 0); + +#ifndef ILMBASE_HAVE_LARGE_STACK + ~halfFunction () { delete [] _lut; } +#endif + + //----------- + // Evaluation + //----------- + + T operator () (half x) const; + + private: +#ifdef ILMBASE_HAVE_LARGE_STACK + T _lut[1 << 16]; +#else + T * _lut; +#endif +}; + + +//--------------- +// Implementation +//--------------- + +template +template +halfFunction::halfFunction (Function f, + half domainMin, + half domainMax, + T defaultValue, + T posInfValue, + T negInfValue, + T nanValue) +{ +#ifndef ILMBASE_HAVE_LARGE_STACK + _lut = new T[1<<16]; + memset (_lut, 0 , (1<<16) * sizeof(T)); +#endif + + for (int i = 0; i < (1 << 16); i++) + { + half x; + x.setBits (i); + + if (x.isNan()) + _lut[i] = nanValue; + else if (x.isInfinity()) + _lut[i] = x.isNegative()? negInfValue: posInfValue; + else if (x < domainMin || x > domainMax) + _lut[i] = defaultValue; + else + _lut[i] = f (x); + } +} + + +template +inline T +halfFunction::operator () (half x) const +{ + return _lut[x.bits()]; +} + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/halfLimits.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/halfLimits.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/halfLimits.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/halfLimits.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +// Primary authors: +// Florian Kainz +// Rod Bogart + + +#ifndef INCLUDED_HALF_LIMITS_H +#define INCLUDED_HALF_LIMITS_H + + +//------------------------------------------------------------------------ +// +// C++ standard library-style numeric_limits for class half +// +//------------------------------------------------------------------------ + +#include +#include "half.h" + +namespace std { + +template <> +class numeric_limits +{ + public: + + static const bool is_specialized = true; + + static half min () throw () {return HALF_NRM_MIN;} + static half max () throw () {return HALF_MAX;} + + static const int digits = HALF_MANT_DIG; + static const int digits10 = HALF_DIG; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = HALF_RADIX; + static half epsilon () throw () {return HALF_EPSILON;} + static half round_error () throw () {return HALF_EPSILON / 2;} + + static const int min_exponent = HALF_MIN_EXP; + static const int min_exponent10 = HALF_MIN_10_EXP; + static const int max_exponent = HALF_MAX_EXP; + static const int max_exponent10 = HALF_MAX_10_EXP; + + static const bool has_infinity = true; + static const bool has_quiet_NaN = true; + static const bool has_signaling_NaN = true; + static const float_denorm_style has_denorm = denorm_present; + static const bool has_denorm_loss = false; + static half infinity () throw () {return half::posInf();} + static half quiet_NaN () throw () {return half::qNan();} + static half signaling_NaN () throw () {return half::sNan();} + static half denorm_min () throw () {return HALF_MIN;} + + static const bool is_iec559 = false; + static const bool is_bounded = false; + static const bool is_modulo = false; + + static const bool traps = true; + static const bool tinyness_before = false; + static const float_round_style round_style = round_to_nearest; +}; + + +} // namespace std + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,164 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + + +//--------------------------------------------------------------------------- +// +// toFloat +// +// A program to generate the lookup table for half-to-float +// conversion needed by class half. +// The program loops over all 65536 possible half numbers, +// converts each of them to a float, and prints the result. +// +//--------------------------------------------------------------------------- + + +#include +#include + +using namespace std; + +//--------------------------------------------------- +// Interpret an unsigned short bit pattern as a half, +// and convert that half to the corresponding float's +// bit pattern. +//--------------------------------------------------- + +unsigned int +halfToFloat (unsigned short y) +{ + + int s = (y >> 15) & 0x00000001; + int e = (y >> 10) & 0x0000001f; + int m = y & 0x000003ff; + + if (e == 0) + { + if (m == 0) + { + // + // Plus or minus zero + // + + return s << 31; + } + else + { + // + // Denormalized number -- renormalize it + // + + while (!(m & 0x00000400)) + { + m <<= 1; + e -= 1; + } + + e += 1; + m &= ~0x00000400; + } + } + else if (e == 31) + { + if (m == 0) + { + // + // Positive or negative infinity + // + + return (s << 31) | 0x7f800000; + } + else + { + // + // Nan -- preserve sign and significand bits + // + + return (s << 31) | 0x7f800000 | (m << 13); + } + } + + // + // Normalized number + // + + e = e + (127 - 15); + m = m << 13; + + // + // Assemble s, e and m. + // + + return (s << 31) | (e << 23) | m; +} + + +//--------------------------------------------- +// Main - prints the half-to-float lookup table +//--------------------------------------------- + +int +main () +{ + cout.precision (9); + cout.setf (ios_base::hex, ios_base::basefield); + + cout << "//\n" + "// This is an automatically generated file.\n" + "// Do not edit.\n" + "//\n\n"; + + cout << "{\n "; + + const int iMax = (1 << 16); + + for (int i = 0; i < iMax; i++) + { + cout << "{0x" << setfill ('0') << setw (8) << halfToFloat (i) << "}, "; + + if (i % 4 == 3) + { + cout << "\n"; + + if (i < iMax - 1) + cout << " "; + } + } + + cout << "};\n"; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Half/toFloat.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,16391 @@ +// +// This is an automatically generated file. +// Do not edit. +// + +{ + {0x00000000}, {0x33800000}, {0x34000000}, {0x34400000}, + {0x34800000}, {0x34a00000}, {0x34c00000}, {0x34e00000}, + {0x35000000}, {0x35100000}, {0x35200000}, {0x35300000}, + {0x35400000}, {0x35500000}, {0x35600000}, {0x35700000}, + {0x35800000}, {0x35880000}, {0x35900000}, {0x35980000}, + {0x35a00000}, {0x35a80000}, {0x35b00000}, {0x35b80000}, + {0x35c00000}, {0x35c80000}, {0x35d00000}, {0x35d80000}, + {0x35e00000}, {0x35e80000}, {0x35f00000}, {0x35f80000}, + {0x36000000}, {0x36040000}, {0x36080000}, {0x360c0000}, + {0x36100000}, {0x36140000}, {0x36180000}, {0x361c0000}, + {0x36200000}, {0x36240000}, {0x36280000}, {0x362c0000}, + {0x36300000}, {0x36340000}, {0x36380000}, {0x363c0000}, + {0x36400000}, {0x36440000}, {0x36480000}, {0x364c0000}, + {0x36500000}, {0x36540000}, {0x36580000}, {0x365c0000}, + {0x36600000}, {0x36640000}, {0x36680000}, {0x366c0000}, + {0x36700000}, {0x36740000}, {0x36780000}, {0x367c0000}, + {0x36800000}, {0x36820000}, {0x36840000}, {0x36860000}, + {0x36880000}, {0x368a0000}, {0x368c0000}, {0x368e0000}, + {0x36900000}, {0x36920000}, {0x36940000}, {0x36960000}, + {0x36980000}, {0x369a0000}, {0x369c0000}, {0x369e0000}, + {0x36a00000}, {0x36a20000}, {0x36a40000}, {0x36a60000}, + {0x36a80000}, {0x36aa0000}, {0x36ac0000}, {0x36ae0000}, + {0x36b00000}, {0x36b20000}, {0x36b40000}, {0x36b60000}, + {0x36b80000}, {0x36ba0000}, {0x36bc0000}, {0x36be0000}, + {0x36c00000}, {0x36c20000}, {0x36c40000}, {0x36c60000}, + {0x36c80000}, {0x36ca0000}, {0x36cc0000}, {0x36ce0000}, + {0x36d00000}, {0x36d20000}, {0x36d40000}, {0x36d60000}, + {0x36d80000}, {0x36da0000}, {0x36dc0000}, {0x36de0000}, + {0x36e00000}, {0x36e20000}, {0x36e40000}, {0x36e60000}, + {0x36e80000}, {0x36ea0000}, {0x36ec0000}, {0x36ee0000}, + {0x36f00000}, {0x36f20000}, {0x36f40000}, {0x36f60000}, + {0x36f80000}, {0x36fa0000}, {0x36fc0000}, {0x36fe0000}, + {0x37000000}, {0x37010000}, {0x37020000}, {0x37030000}, + {0x37040000}, {0x37050000}, {0x37060000}, {0x37070000}, + {0x37080000}, {0x37090000}, {0x370a0000}, {0x370b0000}, + {0x370c0000}, {0x370d0000}, {0x370e0000}, {0x370f0000}, + {0x37100000}, {0x37110000}, {0x37120000}, {0x37130000}, + {0x37140000}, {0x37150000}, {0x37160000}, {0x37170000}, + {0x37180000}, {0x37190000}, {0x371a0000}, {0x371b0000}, + {0x371c0000}, {0x371d0000}, {0x371e0000}, {0x371f0000}, + {0x37200000}, {0x37210000}, {0x37220000}, {0x37230000}, + {0x37240000}, {0x37250000}, {0x37260000}, {0x37270000}, + {0x37280000}, {0x37290000}, {0x372a0000}, {0x372b0000}, + {0x372c0000}, {0x372d0000}, {0x372e0000}, {0x372f0000}, + {0x37300000}, {0x37310000}, {0x37320000}, {0x37330000}, + {0x37340000}, {0x37350000}, {0x37360000}, {0x37370000}, + {0x37380000}, {0x37390000}, {0x373a0000}, {0x373b0000}, + {0x373c0000}, {0x373d0000}, {0x373e0000}, {0x373f0000}, + {0x37400000}, {0x37410000}, {0x37420000}, {0x37430000}, + {0x37440000}, {0x37450000}, {0x37460000}, {0x37470000}, + {0x37480000}, {0x37490000}, {0x374a0000}, {0x374b0000}, + {0x374c0000}, {0x374d0000}, {0x374e0000}, {0x374f0000}, + {0x37500000}, {0x37510000}, {0x37520000}, {0x37530000}, + {0x37540000}, {0x37550000}, {0x37560000}, {0x37570000}, + {0x37580000}, {0x37590000}, {0x375a0000}, {0x375b0000}, + {0x375c0000}, {0x375d0000}, {0x375e0000}, {0x375f0000}, + {0x37600000}, {0x37610000}, {0x37620000}, {0x37630000}, + {0x37640000}, {0x37650000}, {0x37660000}, {0x37670000}, + {0x37680000}, {0x37690000}, {0x376a0000}, {0x376b0000}, + {0x376c0000}, {0x376d0000}, {0x376e0000}, {0x376f0000}, + {0x37700000}, {0x37710000}, {0x37720000}, {0x37730000}, + {0x37740000}, {0x37750000}, {0x37760000}, {0x37770000}, + {0x37780000}, {0x37790000}, {0x377a0000}, {0x377b0000}, + {0x377c0000}, {0x377d0000}, {0x377e0000}, {0x377f0000}, + {0x37800000}, {0x37808000}, {0x37810000}, {0x37818000}, + {0x37820000}, {0x37828000}, {0x37830000}, {0x37838000}, + {0x37840000}, {0x37848000}, {0x37850000}, {0x37858000}, + {0x37860000}, {0x37868000}, {0x37870000}, {0x37878000}, + {0x37880000}, {0x37888000}, {0x37890000}, {0x37898000}, + {0x378a0000}, {0x378a8000}, {0x378b0000}, {0x378b8000}, + {0x378c0000}, {0x378c8000}, {0x378d0000}, {0x378d8000}, + {0x378e0000}, {0x378e8000}, {0x378f0000}, {0x378f8000}, + {0x37900000}, {0x37908000}, {0x37910000}, {0x37918000}, + {0x37920000}, {0x37928000}, {0x37930000}, {0x37938000}, + {0x37940000}, {0x37948000}, {0x37950000}, {0x37958000}, + {0x37960000}, {0x37968000}, {0x37970000}, {0x37978000}, + {0x37980000}, {0x37988000}, {0x37990000}, {0x37998000}, + {0x379a0000}, {0x379a8000}, {0x379b0000}, {0x379b8000}, + {0x379c0000}, {0x379c8000}, {0x379d0000}, {0x379d8000}, + {0x379e0000}, {0x379e8000}, {0x379f0000}, {0x379f8000}, + {0x37a00000}, {0x37a08000}, {0x37a10000}, {0x37a18000}, + {0x37a20000}, {0x37a28000}, {0x37a30000}, {0x37a38000}, + {0x37a40000}, {0x37a48000}, {0x37a50000}, {0x37a58000}, + {0x37a60000}, {0x37a68000}, {0x37a70000}, {0x37a78000}, + {0x37a80000}, {0x37a88000}, {0x37a90000}, {0x37a98000}, + {0x37aa0000}, {0x37aa8000}, {0x37ab0000}, {0x37ab8000}, + {0x37ac0000}, {0x37ac8000}, {0x37ad0000}, {0x37ad8000}, + {0x37ae0000}, {0x37ae8000}, {0x37af0000}, {0x37af8000}, + {0x37b00000}, {0x37b08000}, {0x37b10000}, {0x37b18000}, + {0x37b20000}, {0x37b28000}, {0x37b30000}, {0x37b38000}, + {0x37b40000}, {0x37b48000}, {0x37b50000}, {0x37b58000}, + {0x37b60000}, {0x37b68000}, {0x37b70000}, {0x37b78000}, + {0x37b80000}, {0x37b88000}, {0x37b90000}, {0x37b98000}, + {0x37ba0000}, {0x37ba8000}, {0x37bb0000}, {0x37bb8000}, + {0x37bc0000}, {0x37bc8000}, {0x37bd0000}, {0x37bd8000}, + {0x37be0000}, {0x37be8000}, {0x37bf0000}, {0x37bf8000}, + {0x37c00000}, {0x37c08000}, {0x37c10000}, {0x37c18000}, + {0x37c20000}, {0x37c28000}, {0x37c30000}, {0x37c38000}, + {0x37c40000}, {0x37c48000}, {0x37c50000}, {0x37c58000}, + {0x37c60000}, {0x37c68000}, {0x37c70000}, {0x37c78000}, + {0x37c80000}, {0x37c88000}, {0x37c90000}, {0x37c98000}, + {0x37ca0000}, {0x37ca8000}, {0x37cb0000}, {0x37cb8000}, + {0x37cc0000}, {0x37cc8000}, {0x37cd0000}, {0x37cd8000}, + {0x37ce0000}, {0x37ce8000}, {0x37cf0000}, {0x37cf8000}, + {0x37d00000}, {0x37d08000}, {0x37d10000}, {0x37d18000}, + {0x37d20000}, {0x37d28000}, {0x37d30000}, {0x37d38000}, + {0x37d40000}, {0x37d48000}, {0x37d50000}, {0x37d58000}, + {0x37d60000}, {0x37d68000}, {0x37d70000}, {0x37d78000}, + {0x37d80000}, {0x37d88000}, {0x37d90000}, {0x37d98000}, + {0x37da0000}, {0x37da8000}, {0x37db0000}, {0x37db8000}, + {0x37dc0000}, {0x37dc8000}, {0x37dd0000}, {0x37dd8000}, + {0x37de0000}, {0x37de8000}, {0x37df0000}, {0x37df8000}, + {0x37e00000}, {0x37e08000}, {0x37e10000}, {0x37e18000}, + {0x37e20000}, {0x37e28000}, {0x37e30000}, {0x37e38000}, + {0x37e40000}, {0x37e48000}, {0x37e50000}, {0x37e58000}, + {0x37e60000}, {0x37e68000}, {0x37e70000}, {0x37e78000}, + {0x37e80000}, {0x37e88000}, {0x37e90000}, {0x37e98000}, + {0x37ea0000}, {0x37ea8000}, {0x37eb0000}, {0x37eb8000}, + {0x37ec0000}, {0x37ec8000}, {0x37ed0000}, {0x37ed8000}, + {0x37ee0000}, {0x37ee8000}, {0x37ef0000}, {0x37ef8000}, + {0x37f00000}, {0x37f08000}, {0x37f10000}, {0x37f18000}, + {0x37f20000}, {0x37f28000}, {0x37f30000}, {0x37f38000}, + {0x37f40000}, {0x37f48000}, {0x37f50000}, {0x37f58000}, + {0x37f60000}, {0x37f68000}, {0x37f70000}, {0x37f78000}, + {0x37f80000}, {0x37f88000}, {0x37f90000}, {0x37f98000}, + {0x37fa0000}, {0x37fa8000}, {0x37fb0000}, {0x37fb8000}, + {0x37fc0000}, {0x37fc8000}, {0x37fd0000}, {0x37fd8000}, + {0x37fe0000}, {0x37fe8000}, {0x37ff0000}, {0x37ff8000}, + {0x38000000}, {0x38004000}, {0x38008000}, {0x3800c000}, + {0x38010000}, {0x38014000}, {0x38018000}, {0x3801c000}, + {0x38020000}, {0x38024000}, {0x38028000}, {0x3802c000}, + {0x38030000}, {0x38034000}, {0x38038000}, {0x3803c000}, + {0x38040000}, {0x38044000}, {0x38048000}, {0x3804c000}, + {0x38050000}, {0x38054000}, {0x38058000}, {0x3805c000}, + {0x38060000}, {0x38064000}, {0x38068000}, {0x3806c000}, + {0x38070000}, {0x38074000}, {0x38078000}, {0x3807c000}, + {0x38080000}, {0x38084000}, {0x38088000}, {0x3808c000}, + {0x38090000}, {0x38094000}, {0x38098000}, {0x3809c000}, + {0x380a0000}, {0x380a4000}, {0x380a8000}, {0x380ac000}, + {0x380b0000}, {0x380b4000}, {0x380b8000}, {0x380bc000}, + {0x380c0000}, {0x380c4000}, {0x380c8000}, {0x380cc000}, + {0x380d0000}, {0x380d4000}, {0x380d8000}, {0x380dc000}, + {0x380e0000}, {0x380e4000}, {0x380e8000}, {0x380ec000}, + {0x380f0000}, {0x380f4000}, {0x380f8000}, {0x380fc000}, + {0x38100000}, {0x38104000}, {0x38108000}, {0x3810c000}, + {0x38110000}, {0x38114000}, {0x38118000}, {0x3811c000}, + {0x38120000}, {0x38124000}, {0x38128000}, {0x3812c000}, + {0x38130000}, {0x38134000}, {0x38138000}, {0x3813c000}, + {0x38140000}, {0x38144000}, {0x38148000}, {0x3814c000}, + {0x38150000}, {0x38154000}, {0x38158000}, {0x3815c000}, + {0x38160000}, {0x38164000}, {0x38168000}, {0x3816c000}, + {0x38170000}, {0x38174000}, {0x38178000}, {0x3817c000}, + {0x38180000}, {0x38184000}, {0x38188000}, {0x3818c000}, + {0x38190000}, {0x38194000}, {0x38198000}, {0x3819c000}, + {0x381a0000}, {0x381a4000}, {0x381a8000}, {0x381ac000}, + {0x381b0000}, {0x381b4000}, {0x381b8000}, {0x381bc000}, + {0x381c0000}, {0x381c4000}, {0x381c8000}, {0x381cc000}, + {0x381d0000}, {0x381d4000}, {0x381d8000}, {0x381dc000}, + {0x381e0000}, {0x381e4000}, {0x381e8000}, {0x381ec000}, + {0x381f0000}, {0x381f4000}, {0x381f8000}, {0x381fc000}, + {0x38200000}, {0x38204000}, {0x38208000}, {0x3820c000}, + {0x38210000}, {0x38214000}, {0x38218000}, {0x3821c000}, + {0x38220000}, {0x38224000}, {0x38228000}, {0x3822c000}, + {0x38230000}, {0x38234000}, {0x38238000}, {0x3823c000}, + {0x38240000}, {0x38244000}, {0x38248000}, {0x3824c000}, + {0x38250000}, {0x38254000}, {0x38258000}, {0x3825c000}, + {0x38260000}, {0x38264000}, {0x38268000}, {0x3826c000}, + {0x38270000}, {0x38274000}, {0x38278000}, {0x3827c000}, + {0x38280000}, {0x38284000}, {0x38288000}, {0x3828c000}, + {0x38290000}, {0x38294000}, {0x38298000}, {0x3829c000}, + {0x382a0000}, {0x382a4000}, {0x382a8000}, {0x382ac000}, + {0x382b0000}, {0x382b4000}, {0x382b8000}, {0x382bc000}, + {0x382c0000}, {0x382c4000}, {0x382c8000}, {0x382cc000}, + {0x382d0000}, {0x382d4000}, {0x382d8000}, {0x382dc000}, + {0x382e0000}, {0x382e4000}, {0x382e8000}, {0x382ec000}, + {0x382f0000}, {0x382f4000}, {0x382f8000}, {0x382fc000}, + {0x38300000}, {0x38304000}, {0x38308000}, {0x3830c000}, + {0x38310000}, {0x38314000}, {0x38318000}, {0x3831c000}, + {0x38320000}, {0x38324000}, {0x38328000}, {0x3832c000}, + {0x38330000}, {0x38334000}, {0x38338000}, {0x3833c000}, + {0x38340000}, {0x38344000}, {0x38348000}, {0x3834c000}, + {0x38350000}, {0x38354000}, {0x38358000}, {0x3835c000}, + {0x38360000}, {0x38364000}, {0x38368000}, {0x3836c000}, + {0x38370000}, {0x38374000}, {0x38378000}, {0x3837c000}, + {0x38380000}, {0x38384000}, {0x38388000}, {0x3838c000}, + {0x38390000}, {0x38394000}, {0x38398000}, {0x3839c000}, + {0x383a0000}, {0x383a4000}, {0x383a8000}, {0x383ac000}, + {0x383b0000}, {0x383b4000}, {0x383b8000}, {0x383bc000}, + {0x383c0000}, {0x383c4000}, {0x383c8000}, {0x383cc000}, + {0x383d0000}, {0x383d4000}, {0x383d8000}, {0x383dc000}, + {0x383e0000}, {0x383e4000}, {0x383e8000}, {0x383ec000}, + {0x383f0000}, {0x383f4000}, {0x383f8000}, {0x383fc000}, + {0x38400000}, {0x38404000}, {0x38408000}, {0x3840c000}, + {0x38410000}, {0x38414000}, {0x38418000}, {0x3841c000}, + {0x38420000}, {0x38424000}, {0x38428000}, {0x3842c000}, + {0x38430000}, {0x38434000}, {0x38438000}, {0x3843c000}, + {0x38440000}, {0x38444000}, {0x38448000}, {0x3844c000}, + {0x38450000}, {0x38454000}, {0x38458000}, {0x3845c000}, + {0x38460000}, {0x38464000}, {0x38468000}, {0x3846c000}, + {0x38470000}, {0x38474000}, {0x38478000}, {0x3847c000}, + {0x38480000}, {0x38484000}, {0x38488000}, {0x3848c000}, + {0x38490000}, {0x38494000}, {0x38498000}, {0x3849c000}, + {0x384a0000}, {0x384a4000}, {0x384a8000}, {0x384ac000}, + {0x384b0000}, {0x384b4000}, {0x384b8000}, {0x384bc000}, + {0x384c0000}, {0x384c4000}, {0x384c8000}, {0x384cc000}, + {0x384d0000}, {0x384d4000}, {0x384d8000}, {0x384dc000}, + {0x384e0000}, {0x384e4000}, {0x384e8000}, {0x384ec000}, + {0x384f0000}, {0x384f4000}, {0x384f8000}, {0x384fc000}, + {0x38500000}, {0x38504000}, {0x38508000}, {0x3850c000}, + {0x38510000}, {0x38514000}, {0x38518000}, {0x3851c000}, + {0x38520000}, {0x38524000}, {0x38528000}, {0x3852c000}, + {0x38530000}, {0x38534000}, {0x38538000}, {0x3853c000}, + {0x38540000}, {0x38544000}, {0x38548000}, {0x3854c000}, + {0x38550000}, {0x38554000}, {0x38558000}, {0x3855c000}, + {0x38560000}, {0x38564000}, {0x38568000}, {0x3856c000}, + {0x38570000}, {0x38574000}, {0x38578000}, {0x3857c000}, + {0x38580000}, {0x38584000}, {0x38588000}, {0x3858c000}, + {0x38590000}, {0x38594000}, {0x38598000}, {0x3859c000}, + {0x385a0000}, {0x385a4000}, {0x385a8000}, {0x385ac000}, + {0x385b0000}, {0x385b4000}, {0x385b8000}, {0x385bc000}, + {0x385c0000}, {0x385c4000}, {0x385c8000}, {0x385cc000}, + {0x385d0000}, {0x385d4000}, {0x385d8000}, {0x385dc000}, + {0x385e0000}, {0x385e4000}, {0x385e8000}, {0x385ec000}, + {0x385f0000}, {0x385f4000}, {0x385f8000}, {0x385fc000}, + {0x38600000}, {0x38604000}, {0x38608000}, {0x3860c000}, + {0x38610000}, {0x38614000}, {0x38618000}, {0x3861c000}, + {0x38620000}, {0x38624000}, {0x38628000}, {0x3862c000}, + {0x38630000}, {0x38634000}, {0x38638000}, {0x3863c000}, + {0x38640000}, {0x38644000}, {0x38648000}, {0x3864c000}, + {0x38650000}, {0x38654000}, {0x38658000}, {0x3865c000}, + {0x38660000}, {0x38664000}, {0x38668000}, {0x3866c000}, + {0x38670000}, {0x38674000}, {0x38678000}, {0x3867c000}, + {0x38680000}, {0x38684000}, {0x38688000}, {0x3868c000}, + {0x38690000}, {0x38694000}, {0x38698000}, {0x3869c000}, + {0x386a0000}, {0x386a4000}, {0x386a8000}, {0x386ac000}, + {0x386b0000}, {0x386b4000}, {0x386b8000}, {0x386bc000}, + {0x386c0000}, {0x386c4000}, {0x386c8000}, {0x386cc000}, + {0x386d0000}, {0x386d4000}, {0x386d8000}, {0x386dc000}, + {0x386e0000}, {0x386e4000}, {0x386e8000}, {0x386ec000}, + {0x386f0000}, {0x386f4000}, {0x386f8000}, {0x386fc000}, + {0x38700000}, {0x38704000}, {0x38708000}, {0x3870c000}, + {0x38710000}, {0x38714000}, {0x38718000}, {0x3871c000}, + {0x38720000}, {0x38724000}, {0x38728000}, {0x3872c000}, + {0x38730000}, {0x38734000}, {0x38738000}, {0x3873c000}, + {0x38740000}, {0x38744000}, {0x38748000}, {0x3874c000}, + {0x38750000}, {0x38754000}, {0x38758000}, {0x3875c000}, + {0x38760000}, {0x38764000}, {0x38768000}, {0x3876c000}, + {0x38770000}, {0x38774000}, {0x38778000}, {0x3877c000}, + {0x38780000}, {0x38784000}, {0x38788000}, {0x3878c000}, + {0x38790000}, {0x38794000}, {0x38798000}, {0x3879c000}, + {0x387a0000}, {0x387a4000}, {0x387a8000}, {0x387ac000}, + {0x387b0000}, {0x387b4000}, {0x387b8000}, {0x387bc000}, + {0x387c0000}, {0x387c4000}, {0x387c8000}, {0x387cc000}, + {0x387d0000}, {0x387d4000}, {0x387d8000}, {0x387dc000}, + {0x387e0000}, {0x387e4000}, {0x387e8000}, {0x387ec000}, + {0x387f0000}, {0x387f4000}, {0x387f8000}, {0x387fc000}, + {0x38800000}, {0x38802000}, {0x38804000}, {0x38806000}, + {0x38808000}, {0x3880a000}, {0x3880c000}, {0x3880e000}, + {0x38810000}, {0x38812000}, {0x38814000}, {0x38816000}, + {0x38818000}, {0x3881a000}, {0x3881c000}, {0x3881e000}, + {0x38820000}, {0x38822000}, {0x38824000}, {0x38826000}, + {0x38828000}, {0x3882a000}, {0x3882c000}, {0x3882e000}, + {0x38830000}, {0x38832000}, {0x38834000}, {0x38836000}, + {0x38838000}, {0x3883a000}, {0x3883c000}, {0x3883e000}, + {0x38840000}, {0x38842000}, {0x38844000}, {0x38846000}, + {0x38848000}, {0x3884a000}, {0x3884c000}, {0x3884e000}, + {0x38850000}, {0x38852000}, {0x38854000}, {0x38856000}, + {0x38858000}, {0x3885a000}, {0x3885c000}, {0x3885e000}, + {0x38860000}, {0x38862000}, {0x38864000}, {0x38866000}, + {0x38868000}, {0x3886a000}, {0x3886c000}, {0x3886e000}, + {0x38870000}, {0x38872000}, {0x38874000}, {0x38876000}, + {0x38878000}, {0x3887a000}, {0x3887c000}, {0x3887e000}, + {0x38880000}, {0x38882000}, {0x38884000}, {0x38886000}, + {0x38888000}, {0x3888a000}, {0x3888c000}, {0x3888e000}, + {0x38890000}, {0x38892000}, {0x38894000}, {0x38896000}, + {0x38898000}, {0x3889a000}, {0x3889c000}, {0x3889e000}, + {0x388a0000}, {0x388a2000}, {0x388a4000}, {0x388a6000}, + {0x388a8000}, {0x388aa000}, {0x388ac000}, {0x388ae000}, + {0x388b0000}, {0x388b2000}, {0x388b4000}, {0x388b6000}, + {0x388b8000}, {0x388ba000}, {0x388bc000}, {0x388be000}, + {0x388c0000}, {0x388c2000}, {0x388c4000}, {0x388c6000}, + {0x388c8000}, {0x388ca000}, {0x388cc000}, {0x388ce000}, + {0x388d0000}, {0x388d2000}, {0x388d4000}, {0x388d6000}, + {0x388d8000}, {0x388da000}, {0x388dc000}, {0x388de000}, + {0x388e0000}, {0x388e2000}, {0x388e4000}, {0x388e6000}, + {0x388e8000}, {0x388ea000}, {0x388ec000}, {0x388ee000}, + {0x388f0000}, {0x388f2000}, {0x388f4000}, {0x388f6000}, + {0x388f8000}, {0x388fa000}, {0x388fc000}, {0x388fe000}, + {0x38900000}, {0x38902000}, {0x38904000}, {0x38906000}, + {0x38908000}, {0x3890a000}, {0x3890c000}, {0x3890e000}, + {0x38910000}, {0x38912000}, {0x38914000}, {0x38916000}, + {0x38918000}, {0x3891a000}, {0x3891c000}, {0x3891e000}, + {0x38920000}, {0x38922000}, {0x38924000}, {0x38926000}, + {0x38928000}, {0x3892a000}, {0x3892c000}, {0x3892e000}, + {0x38930000}, {0x38932000}, {0x38934000}, {0x38936000}, + {0x38938000}, {0x3893a000}, {0x3893c000}, {0x3893e000}, + {0x38940000}, {0x38942000}, {0x38944000}, {0x38946000}, + {0x38948000}, {0x3894a000}, {0x3894c000}, {0x3894e000}, + {0x38950000}, {0x38952000}, {0x38954000}, {0x38956000}, + {0x38958000}, {0x3895a000}, {0x3895c000}, {0x3895e000}, + {0x38960000}, {0x38962000}, {0x38964000}, {0x38966000}, + {0x38968000}, {0x3896a000}, {0x3896c000}, {0x3896e000}, + {0x38970000}, {0x38972000}, {0x38974000}, {0x38976000}, + {0x38978000}, {0x3897a000}, {0x3897c000}, {0x3897e000}, + {0x38980000}, {0x38982000}, {0x38984000}, {0x38986000}, + {0x38988000}, {0x3898a000}, {0x3898c000}, {0x3898e000}, + {0x38990000}, {0x38992000}, {0x38994000}, {0x38996000}, + {0x38998000}, {0x3899a000}, {0x3899c000}, {0x3899e000}, + {0x389a0000}, {0x389a2000}, {0x389a4000}, {0x389a6000}, + {0x389a8000}, {0x389aa000}, {0x389ac000}, {0x389ae000}, + {0x389b0000}, {0x389b2000}, {0x389b4000}, {0x389b6000}, + {0x389b8000}, {0x389ba000}, {0x389bc000}, {0x389be000}, + {0x389c0000}, {0x389c2000}, {0x389c4000}, {0x389c6000}, + {0x389c8000}, {0x389ca000}, {0x389cc000}, {0x389ce000}, + {0x389d0000}, {0x389d2000}, {0x389d4000}, {0x389d6000}, + {0x389d8000}, {0x389da000}, {0x389dc000}, {0x389de000}, + {0x389e0000}, {0x389e2000}, {0x389e4000}, {0x389e6000}, + {0x389e8000}, {0x389ea000}, {0x389ec000}, {0x389ee000}, + {0x389f0000}, {0x389f2000}, {0x389f4000}, {0x389f6000}, + {0x389f8000}, {0x389fa000}, {0x389fc000}, {0x389fe000}, + {0x38a00000}, {0x38a02000}, {0x38a04000}, {0x38a06000}, + {0x38a08000}, {0x38a0a000}, {0x38a0c000}, {0x38a0e000}, + {0x38a10000}, {0x38a12000}, {0x38a14000}, {0x38a16000}, + {0x38a18000}, {0x38a1a000}, {0x38a1c000}, {0x38a1e000}, + {0x38a20000}, {0x38a22000}, {0x38a24000}, {0x38a26000}, + {0x38a28000}, {0x38a2a000}, {0x38a2c000}, {0x38a2e000}, + {0x38a30000}, {0x38a32000}, {0x38a34000}, {0x38a36000}, + {0x38a38000}, {0x38a3a000}, {0x38a3c000}, {0x38a3e000}, + {0x38a40000}, {0x38a42000}, {0x38a44000}, {0x38a46000}, + {0x38a48000}, {0x38a4a000}, {0x38a4c000}, {0x38a4e000}, + {0x38a50000}, {0x38a52000}, {0x38a54000}, {0x38a56000}, + {0x38a58000}, {0x38a5a000}, {0x38a5c000}, {0x38a5e000}, + {0x38a60000}, {0x38a62000}, {0x38a64000}, {0x38a66000}, + {0x38a68000}, {0x38a6a000}, {0x38a6c000}, {0x38a6e000}, + {0x38a70000}, {0x38a72000}, {0x38a74000}, {0x38a76000}, + {0x38a78000}, {0x38a7a000}, {0x38a7c000}, {0x38a7e000}, + {0x38a80000}, {0x38a82000}, {0x38a84000}, {0x38a86000}, + {0x38a88000}, {0x38a8a000}, {0x38a8c000}, {0x38a8e000}, + {0x38a90000}, {0x38a92000}, {0x38a94000}, {0x38a96000}, + {0x38a98000}, {0x38a9a000}, {0x38a9c000}, {0x38a9e000}, + {0x38aa0000}, {0x38aa2000}, {0x38aa4000}, {0x38aa6000}, + {0x38aa8000}, {0x38aaa000}, {0x38aac000}, {0x38aae000}, + {0x38ab0000}, {0x38ab2000}, {0x38ab4000}, {0x38ab6000}, + {0x38ab8000}, {0x38aba000}, {0x38abc000}, {0x38abe000}, + {0x38ac0000}, {0x38ac2000}, {0x38ac4000}, {0x38ac6000}, + {0x38ac8000}, {0x38aca000}, {0x38acc000}, {0x38ace000}, + {0x38ad0000}, {0x38ad2000}, {0x38ad4000}, {0x38ad6000}, + {0x38ad8000}, {0x38ada000}, {0x38adc000}, {0x38ade000}, + {0x38ae0000}, {0x38ae2000}, {0x38ae4000}, {0x38ae6000}, + {0x38ae8000}, {0x38aea000}, {0x38aec000}, {0x38aee000}, + {0x38af0000}, {0x38af2000}, {0x38af4000}, {0x38af6000}, + {0x38af8000}, {0x38afa000}, {0x38afc000}, {0x38afe000}, + {0x38b00000}, {0x38b02000}, {0x38b04000}, {0x38b06000}, + {0x38b08000}, {0x38b0a000}, {0x38b0c000}, {0x38b0e000}, + {0x38b10000}, {0x38b12000}, {0x38b14000}, {0x38b16000}, + {0x38b18000}, {0x38b1a000}, {0x38b1c000}, {0x38b1e000}, + {0x38b20000}, {0x38b22000}, {0x38b24000}, {0x38b26000}, + {0x38b28000}, {0x38b2a000}, {0x38b2c000}, {0x38b2e000}, + {0x38b30000}, {0x38b32000}, {0x38b34000}, {0x38b36000}, + {0x38b38000}, {0x38b3a000}, {0x38b3c000}, {0x38b3e000}, + {0x38b40000}, {0x38b42000}, {0x38b44000}, {0x38b46000}, + {0x38b48000}, {0x38b4a000}, {0x38b4c000}, {0x38b4e000}, + {0x38b50000}, {0x38b52000}, {0x38b54000}, {0x38b56000}, + {0x38b58000}, {0x38b5a000}, {0x38b5c000}, {0x38b5e000}, + {0x38b60000}, {0x38b62000}, {0x38b64000}, {0x38b66000}, + {0x38b68000}, {0x38b6a000}, {0x38b6c000}, {0x38b6e000}, + {0x38b70000}, {0x38b72000}, {0x38b74000}, {0x38b76000}, + {0x38b78000}, {0x38b7a000}, {0x38b7c000}, {0x38b7e000}, + {0x38b80000}, {0x38b82000}, {0x38b84000}, {0x38b86000}, + {0x38b88000}, {0x38b8a000}, {0x38b8c000}, {0x38b8e000}, + {0x38b90000}, {0x38b92000}, {0x38b94000}, {0x38b96000}, + {0x38b98000}, {0x38b9a000}, {0x38b9c000}, {0x38b9e000}, + {0x38ba0000}, {0x38ba2000}, {0x38ba4000}, {0x38ba6000}, + {0x38ba8000}, {0x38baa000}, {0x38bac000}, {0x38bae000}, + {0x38bb0000}, {0x38bb2000}, {0x38bb4000}, {0x38bb6000}, + {0x38bb8000}, {0x38bba000}, {0x38bbc000}, {0x38bbe000}, + {0x38bc0000}, {0x38bc2000}, {0x38bc4000}, {0x38bc6000}, + {0x38bc8000}, {0x38bca000}, {0x38bcc000}, {0x38bce000}, + {0x38bd0000}, {0x38bd2000}, {0x38bd4000}, {0x38bd6000}, + {0x38bd8000}, {0x38bda000}, {0x38bdc000}, {0x38bde000}, + {0x38be0000}, {0x38be2000}, {0x38be4000}, {0x38be6000}, + {0x38be8000}, {0x38bea000}, {0x38bec000}, {0x38bee000}, + {0x38bf0000}, {0x38bf2000}, {0x38bf4000}, {0x38bf6000}, + {0x38bf8000}, {0x38bfa000}, {0x38bfc000}, {0x38bfe000}, + {0x38c00000}, {0x38c02000}, {0x38c04000}, {0x38c06000}, + {0x38c08000}, {0x38c0a000}, {0x38c0c000}, {0x38c0e000}, + {0x38c10000}, {0x38c12000}, {0x38c14000}, {0x38c16000}, + {0x38c18000}, {0x38c1a000}, {0x38c1c000}, {0x38c1e000}, + {0x38c20000}, {0x38c22000}, {0x38c24000}, {0x38c26000}, + {0x38c28000}, {0x38c2a000}, {0x38c2c000}, {0x38c2e000}, + {0x38c30000}, {0x38c32000}, {0x38c34000}, {0x38c36000}, + {0x38c38000}, {0x38c3a000}, {0x38c3c000}, {0x38c3e000}, + {0x38c40000}, {0x38c42000}, {0x38c44000}, {0x38c46000}, + {0x38c48000}, {0x38c4a000}, {0x38c4c000}, {0x38c4e000}, + {0x38c50000}, {0x38c52000}, {0x38c54000}, {0x38c56000}, + {0x38c58000}, {0x38c5a000}, {0x38c5c000}, {0x38c5e000}, + {0x38c60000}, {0x38c62000}, {0x38c64000}, {0x38c66000}, + {0x38c68000}, {0x38c6a000}, {0x38c6c000}, {0x38c6e000}, + {0x38c70000}, {0x38c72000}, {0x38c74000}, {0x38c76000}, + {0x38c78000}, {0x38c7a000}, {0x38c7c000}, {0x38c7e000}, + {0x38c80000}, {0x38c82000}, {0x38c84000}, {0x38c86000}, + {0x38c88000}, {0x38c8a000}, {0x38c8c000}, {0x38c8e000}, + {0x38c90000}, {0x38c92000}, {0x38c94000}, {0x38c96000}, + {0x38c98000}, {0x38c9a000}, {0x38c9c000}, {0x38c9e000}, + {0x38ca0000}, {0x38ca2000}, {0x38ca4000}, {0x38ca6000}, + {0x38ca8000}, {0x38caa000}, {0x38cac000}, {0x38cae000}, + {0x38cb0000}, {0x38cb2000}, {0x38cb4000}, {0x38cb6000}, + {0x38cb8000}, {0x38cba000}, {0x38cbc000}, {0x38cbe000}, + {0x38cc0000}, {0x38cc2000}, {0x38cc4000}, {0x38cc6000}, + {0x38cc8000}, {0x38cca000}, {0x38ccc000}, {0x38cce000}, + {0x38cd0000}, {0x38cd2000}, {0x38cd4000}, {0x38cd6000}, + {0x38cd8000}, {0x38cda000}, {0x38cdc000}, {0x38cde000}, + {0x38ce0000}, {0x38ce2000}, {0x38ce4000}, {0x38ce6000}, + {0x38ce8000}, {0x38cea000}, {0x38cec000}, {0x38cee000}, + {0x38cf0000}, {0x38cf2000}, {0x38cf4000}, {0x38cf6000}, + {0x38cf8000}, {0x38cfa000}, {0x38cfc000}, {0x38cfe000}, + {0x38d00000}, {0x38d02000}, {0x38d04000}, {0x38d06000}, + {0x38d08000}, {0x38d0a000}, {0x38d0c000}, {0x38d0e000}, + {0x38d10000}, {0x38d12000}, {0x38d14000}, {0x38d16000}, + {0x38d18000}, {0x38d1a000}, {0x38d1c000}, {0x38d1e000}, + {0x38d20000}, {0x38d22000}, {0x38d24000}, {0x38d26000}, + {0x38d28000}, {0x38d2a000}, {0x38d2c000}, {0x38d2e000}, + {0x38d30000}, {0x38d32000}, {0x38d34000}, {0x38d36000}, + {0x38d38000}, {0x38d3a000}, {0x38d3c000}, {0x38d3e000}, + {0x38d40000}, {0x38d42000}, {0x38d44000}, {0x38d46000}, + {0x38d48000}, {0x38d4a000}, {0x38d4c000}, {0x38d4e000}, + {0x38d50000}, {0x38d52000}, {0x38d54000}, {0x38d56000}, + {0x38d58000}, {0x38d5a000}, {0x38d5c000}, {0x38d5e000}, + {0x38d60000}, {0x38d62000}, {0x38d64000}, {0x38d66000}, + {0x38d68000}, {0x38d6a000}, {0x38d6c000}, {0x38d6e000}, + {0x38d70000}, {0x38d72000}, {0x38d74000}, {0x38d76000}, + {0x38d78000}, {0x38d7a000}, {0x38d7c000}, {0x38d7e000}, + {0x38d80000}, {0x38d82000}, {0x38d84000}, {0x38d86000}, + {0x38d88000}, {0x38d8a000}, {0x38d8c000}, {0x38d8e000}, + {0x38d90000}, {0x38d92000}, {0x38d94000}, {0x38d96000}, + {0x38d98000}, {0x38d9a000}, {0x38d9c000}, {0x38d9e000}, + {0x38da0000}, {0x38da2000}, {0x38da4000}, {0x38da6000}, + {0x38da8000}, {0x38daa000}, {0x38dac000}, {0x38dae000}, + {0x38db0000}, {0x38db2000}, {0x38db4000}, {0x38db6000}, + {0x38db8000}, {0x38dba000}, {0x38dbc000}, {0x38dbe000}, + {0x38dc0000}, {0x38dc2000}, {0x38dc4000}, {0x38dc6000}, + {0x38dc8000}, {0x38dca000}, {0x38dcc000}, {0x38dce000}, + {0x38dd0000}, {0x38dd2000}, {0x38dd4000}, {0x38dd6000}, + {0x38dd8000}, {0x38dda000}, {0x38ddc000}, {0x38dde000}, + {0x38de0000}, {0x38de2000}, {0x38de4000}, {0x38de6000}, + {0x38de8000}, {0x38dea000}, {0x38dec000}, {0x38dee000}, + {0x38df0000}, {0x38df2000}, {0x38df4000}, {0x38df6000}, + {0x38df8000}, {0x38dfa000}, {0x38dfc000}, {0x38dfe000}, + {0x38e00000}, {0x38e02000}, {0x38e04000}, {0x38e06000}, + {0x38e08000}, {0x38e0a000}, {0x38e0c000}, {0x38e0e000}, + {0x38e10000}, {0x38e12000}, {0x38e14000}, {0x38e16000}, + {0x38e18000}, {0x38e1a000}, {0x38e1c000}, {0x38e1e000}, + {0x38e20000}, {0x38e22000}, {0x38e24000}, {0x38e26000}, + {0x38e28000}, {0x38e2a000}, {0x38e2c000}, {0x38e2e000}, + {0x38e30000}, {0x38e32000}, {0x38e34000}, {0x38e36000}, + {0x38e38000}, {0x38e3a000}, {0x38e3c000}, {0x38e3e000}, + {0x38e40000}, {0x38e42000}, {0x38e44000}, {0x38e46000}, + {0x38e48000}, {0x38e4a000}, {0x38e4c000}, {0x38e4e000}, + {0x38e50000}, {0x38e52000}, {0x38e54000}, {0x38e56000}, + {0x38e58000}, {0x38e5a000}, {0x38e5c000}, {0x38e5e000}, + {0x38e60000}, {0x38e62000}, {0x38e64000}, {0x38e66000}, + {0x38e68000}, {0x38e6a000}, {0x38e6c000}, {0x38e6e000}, + {0x38e70000}, {0x38e72000}, {0x38e74000}, {0x38e76000}, + {0x38e78000}, {0x38e7a000}, {0x38e7c000}, {0x38e7e000}, + {0x38e80000}, {0x38e82000}, {0x38e84000}, {0x38e86000}, + {0x38e88000}, {0x38e8a000}, {0x38e8c000}, {0x38e8e000}, + {0x38e90000}, {0x38e92000}, {0x38e94000}, {0x38e96000}, + {0x38e98000}, {0x38e9a000}, {0x38e9c000}, {0x38e9e000}, + {0x38ea0000}, {0x38ea2000}, {0x38ea4000}, {0x38ea6000}, + {0x38ea8000}, {0x38eaa000}, {0x38eac000}, {0x38eae000}, + {0x38eb0000}, {0x38eb2000}, {0x38eb4000}, {0x38eb6000}, + {0x38eb8000}, {0x38eba000}, {0x38ebc000}, {0x38ebe000}, + {0x38ec0000}, {0x38ec2000}, {0x38ec4000}, {0x38ec6000}, + {0x38ec8000}, {0x38eca000}, {0x38ecc000}, {0x38ece000}, + {0x38ed0000}, {0x38ed2000}, {0x38ed4000}, {0x38ed6000}, + {0x38ed8000}, {0x38eda000}, {0x38edc000}, {0x38ede000}, + {0x38ee0000}, {0x38ee2000}, {0x38ee4000}, {0x38ee6000}, + {0x38ee8000}, {0x38eea000}, {0x38eec000}, {0x38eee000}, + {0x38ef0000}, {0x38ef2000}, {0x38ef4000}, {0x38ef6000}, + {0x38ef8000}, {0x38efa000}, {0x38efc000}, {0x38efe000}, + {0x38f00000}, {0x38f02000}, {0x38f04000}, {0x38f06000}, + {0x38f08000}, {0x38f0a000}, {0x38f0c000}, {0x38f0e000}, + {0x38f10000}, {0x38f12000}, {0x38f14000}, {0x38f16000}, + {0x38f18000}, {0x38f1a000}, {0x38f1c000}, {0x38f1e000}, + {0x38f20000}, {0x38f22000}, {0x38f24000}, {0x38f26000}, + {0x38f28000}, {0x38f2a000}, {0x38f2c000}, {0x38f2e000}, + {0x38f30000}, {0x38f32000}, {0x38f34000}, {0x38f36000}, + {0x38f38000}, {0x38f3a000}, {0x38f3c000}, {0x38f3e000}, + {0x38f40000}, {0x38f42000}, {0x38f44000}, {0x38f46000}, + {0x38f48000}, {0x38f4a000}, {0x38f4c000}, {0x38f4e000}, + {0x38f50000}, {0x38f52000}, {0x38f54000}, {0x38f56000}, + {0x38f58000}, {0x38f5a000}, {0x38f5c000}, {0x38f5e000}, + {0x38f60000}, {0x38f62000}, {0x38f64000}, {0x38f66000}, + {0x38f68000}, {0x38f6a000}, {0x38f6c000}, {0x38f6e000}, + {0x38f70000}, {0x38f72000}, {0x38f74000}, {0x38f76000}, + {0x38f78000}, {0x38f7a000}, {0x38f7c000}, {0x38f7e000}, + {0x38f80000}, {0x38f82000}, {0x38f84000}, {0x38f86000}, + {0x38f88000}, {0x38f8a000}, {0x38f8c000}, {0x38f8e000}, + {0x38f90000}, {0x38f92000}, {0x38f94000}, {0x38f96000}, + {0x38f98000}, {0x38f9a000}, {0x38f9c000}, {0x38f9e000}, + {0x38fa0000}, {0x38fa2000}, {0x38fa4000}, {0x38fa6000}, + {0x38fa8000}, {0x38faa000}, {0x38fac000}, {0x38fae000}, + {0x38fb0000}, {0x38fb2000}, {0x38fb4000}, {0x38fb6000}, + {0x38fb8000}, {0x38fba000}, {0x38fbc000}, {0x38fbe000}, + {0x38fc0000}, {0x38fc2000}, {0x38fc4000}, {0x38fc6000}, + {0x38fc8000}, {0x38fca000}, {0x38fcc000}, {0x38fce000}, + {0x38fd0000}, {0x38fd2000}, {0x38fd4000}, {0x38fd6000}, + {0x38fd8000}, {0x38fda000}, {0x38fdc000}, {0x38fde000}, + {0x38fe0000}, {0x38fe2000}, {0x38fe4000}, {0x38fe6000}, + {0x38fe8000}, {0x38fea000}, {0x38fec000}, {0x38fee000}, + {0x38ff0000}, {0x38ff2000}, {0x38ff4000}, {0x38ff6000}, + {0x38ff8000}, {0x38ffa000}, {0x38ffc000}, {0x38ffe000}, + {0x39000000}, {0x39002000}, {0x39004000}, {0x39006000}, + {0x39008000}, {0x3900a000}, {0x3900c000}, {0x3900e000}, + {0x39010000}, {0x39012000}, {0x39014000}, {0x39016000}, + {0x39018000}, {0x3901a000}, {0x3901c000}, {0x3901e000}, + {0x39020000}, {0x39022000}, {0x39024000}, {0x39026000}, + {0x39028000}, {0x3902a000}, {0x3902c000}, {0x3902e000}, + {0x39030000}, {0x39032000}, {0x39034000}, {0x39036000}, + {0x39038000}, {0x3903a000}, {0x3903c000}, {0x3903e000}, + {0x39040000}, {0x39042000}, {0x39044000}, {0x39046000}, + {0x39048000}, {0x3904a000}, {0x3904c000}, {0x3904e000}, + {0x39050000}, {0x39052000}, {0x39054000}, {0x39056000}, + {0x39058000}, {0x3905a000}, {0x3905c000}, {0x3905e000}, + {0x39060000}, {0x39062000}, {0x39064000}, {0x39066000}, + {0x39068000}, {0x3906a000}, {0x3906c000}, {0x3906e000}, + {0x39070000}, {0x39072000}, {0x39074000}, {0x39076000}, + {0x39078000}, {0x3907a000}, {0x3907c000}, {0x3907e000}, + {0x39080000}, {0x39082000}, {0x39084000}, {0x39086000}, + {0x39088000}, {0x3908a000}, {0x3908c000}, {0x3908e000}, + {0x39090000}, {0x39092000}, {0x39094000}, {0x39096000}, + {0x39098000}, {0x3909a000}, {0x3909c000}, {0x3909e000}, + {0x390a0000}, {0x390a2000}, {0x390a4000}, {0x390a6000}, + {0x390a8000}, {0x390aa000}, {0x390ac000}, {0x390ae000}, + {0x390b0000}, {0x390b2000}, {0x390b4000}, {0x390b6000}, + {0x390b8000}, {0x390ba000}, {0x390bc000}, {0x390be000}, + {0x390c0000}, {0x390c2000}, {0x390c4000}, {0x390c6000}, + {0x390c8000}, {0x390ca000}, {0x390cc000}, {0x390ce000}, + {0x390d0000}, {0x390d2000}, {0x390d4000}, {0x390d6000}, + {0x390d8000}, {0x390da000}, {0x390dc000}, {0x390de000}, + {0x390e0000}, {0x390e2000}, {0x390e4000}, {0x390e6000}, + {0x390e8000}, {0x390ea000}, {0x390ec000}, {0x390ee000}, + {0x390f0000}, {0x390f2000}, {0x390f4000}, {0x390f6000}, + {0x390f8000}, {0x390fa000}, {0x390fc000}, {0x390fe000}, + {0x39100000}, {0x39102000}, {0x39104000}, {0x39106000}, + {0x39108000}, {0x3910a000}, {0x3910c000}, {0x3910e000}, + {0x39110000}, {0x39112000}, {0x39114000}, {0x39116000}, + {0x39118000}, {0x3911a000}, {0x3911c000}, {0x3911e000}, + {0x39120000}, {0x39122000}, {0x39124000}, {0x39126000}, + {0x39128000}, {0x3912a000}, {0x3912c000}, {0x3912e000}, + {0x39130000}, {0x39132000}, {0x39134000}, {0x39136000}, + {0x39138000}, {0x3913a000}, {0x3913c000}, {0x3913e000}, + {0x39140000}, {0x39142000}, {0x39144000}, {0x39146000}, + {0x39148000}, {0x3914a000}, {0x3914c000}, {0x3914e000}, + {0x39150000}, {0x39152000}, {0x39154000}, {0x39156000}, + {0x39158000}, {0x3915a000}, {0x3915c000}, {0x3915e000}, + {0x39160000}, {0x39162000}, {0x39164000}, {0x39166000}, + {0x39168000}, {0x3916a000}, {0x3916c000}, {0x3916e000}, + {0x39170000}, {0x39172000}, {0x39174000}, {0x39176000}, + {0x39178000}, {0x3917a000}, {0x3917c000}, {0x3917e000}, + {0x39180000}, {0x39182000}, {0x39184000}, {0x39186000}, + {0x39188000}, {0x3918a000}, {0x3918c000}, {0x3918e000}, + {0x39190000}, {0x39192000}, {0x39194000}, {0x39196000}, + {0x39198000}, {0x3919a000}, {0x3919c000}, {0x3919e000}, + {0x391a0000}, {0x391a2000}, {0x391a4000}, {0x391a6000}, + {0x391a8000}, {0x391aa000}, {0x391ac000}, {0x391ae000}, + {0x391b0000}, {0x391b2000}, {0x391b4000}, {0x391b6000}, + {0x391b8000}, {0x391ba000}, {0x391bc000}, {0x391be000}, + {0x391c0000}, {0x391c2000}, {0x391c4000}, {0x391c6000}, + {0x391c8000}, {0x391ca000}, {0x391cc000}, {0x391ce000}, + {0x391d0000}, {0x391d2000}, {0x391d4000}, {0x391d6000}, + {0x391d8000}, {0x391da000}, {0x391dc000}, {0x391de000}, + {0x391e0000}, {0x391e2000}, {0x391e4000}, {0x391e6000}, + {0x391e8000}, {0x391ea000}, {0x391ec000}, {0x391ee000}, + {0x391f0000}, {0x391f2000}, {0x391f4000}, {0x391f6000}, + {0x391f8000}, {0x391fa000}, {0x391fc000}, {0x391fe000}, + {0x39200000}, {0x39202000}, {0x39204000}, {0x39206000}, + {0x39208000}, {0x3920a000}, {0x3920c000}, {0x3920e000}, + {0x39210000}, {0x39212000}, {0x39214000}, {0x39216000}, + {0x39218000}, {0x3921a000}, {0x3921c000}, {0x3921e000}, + {0x39220000}, {0x39222000}, {0x39224000}, {0x39226000}, + {0x39228000}, {0x3922a000}, {0x3922c000}, {0x3922e000}, + {0x39230000}, {0x39232000}, {0x39234000}, {0x39236000}, + {0x39238000}, {0x3923a000}, {0x3923c000}, {0x3923e000}, + {0x39240000}, {0x39242000}, {0x39244000}, {0x39246000}, + {0x39248000}, {0x3924a000}, {0x3924c000}, {0x3924e000}, + {0x39250000}, {0x39252000}, {0x39254000}, {0x39256000}, + {0x39258000}, {0x3925a000}, {0x3925c000}, {0x3925e000}, + {0x39260000}, {0x39262000}, {0x39264000}, {0x39266000}, + {0x39268000}, {0x3926a000}, {0x3926c000}, {0x3926e000}, + {0x39270000}, {0x39272000}, {0x39274000}, {0x39276000}, + {0x39278000}, {0x3927a000}, {0x3927c000}, {0x3927e000}, + {0x39280000}, {0x39282000}, {0x39284000}, {0x39286000}, + {0x39288000}, {0x3928a000}, {0x3928c000}, {0x3928e000}, + {0x39290000}, {0x39292000}, {0x39294000}, {0x39296000}, + {0x39298000}, {0x3929a000}, {0x3929c000}, {0x3929e000}, + {0x392a0000}, {0x392a2000}, {0x392a4000}, {0x392a6000}, + {0x392a8000}, {0x392aa000}, {0x392ac000}, {0x392ae000}, + {0x392b0000}, {0x392b2000}, {0x392b4000}, {0x392b6000}, + {0x392b8000}, {0x392ba000}, {0x392bc000}, {0x392be000}, + {0x392c0000}, {0x392c2000}, {0x392c4000}, {0x392c6000}, + {0x392c8000}, {0x392ca000}, {0x392cc000}, {0x392ce000}, + {0x392d0000}, {0x392d2000}, {0x392d4000}, {0x392d6000}, + {0x392d8000}, {0x392da000}, {0x392dc000}, {0x392de000}, + {0x392e0000}, {0x392e2000}, {0x392e4000}, {0x392e6000}, + {0x392e8000}, {0x392ea000}, {0x392ec000}, {0x392ee000}, + {0x392f0000}, {0x392f2000}, {0x392f4000}, {0x392f6000}, + {0x392f8000}, {0x392fa000}, {0x392fc000}, {0x392fe000}, + {0x39300000}, {0x39302000}, {0x39304000}, {0x39306000}, + {0x39308000}, {0x3930a000}, {0x3930c000}, {0x3930e000}, + {0x39310000}, {0x39312000}, {0x39314000}, {0x39316000}, + {0x39318000}, {0x3931a000}, {0x3931c000}, {0x3931e000}, + {0x39320000}, {0x39322000}, {0x39324000}, {0x39326000}, + {0x39328000}, {0x3932a000}, {0x3932c000}, {0x3932e000}, + {0x39330000}, {0x39332000}, {0x39334000}, {0x39336000}, + {0x39338000}, {0x3933a000}, {0x3933c000}, {0x3933e000}, + {0x39340000}, {0x39342000}, {0x39344000}, {0x39346000}, + {0x39348000}, {0x3934a000}, {0x3934c000}, {0x3934e000}, + {0x39350000}, {0x39352000}, {0x39354000}, {0x39356000}, + {0x39358000}, {0x3935a000}, {0x3935c000}, {0x3935e000}, + {0x39360000}, {0x39362000}, {0x39364000}, {0x39366000}, + {0x39368000}, {0x3936a000}, {0x3936c000}, {0x3936e000}, + {0x39370000}, {0x39372000}, {0x39374000}, {0x39376000}, + {0x39378000}, {0x3937a000}, {0x3937c000}, {0x3937e000}, + {0x39380000}, {0x39382000}, {0x39384000}, {0x39386000}, + {0x39388000}, {0x3938a000}, {0x3938c000}, {0x3938e000}, + {0x39390000}, {0x39392000}, {0x39394000}, {0x39396000}, + {0x39398000}, {0x3939a000}, {0x3939c000}, {0x3939e000}, + {0x393a0000}, {0x393a2000}, {0x393a4000}, {0x393a6000}, + {0x393a8000}, {0x393aa000}, {0x393ac000}, {0x393ae000}, + {0x393b0000}, {0x393b2000}, {0x393b4000}, {0x393b6000}, + {0x393b8000}, {0x393ba000}, {0x393bc000}, {0x393be000}, + {0x393c0000}, {0x393c2000}, {0x393c4000}, {0x393c6000}, + {0x393c8000}, {0x393ca000}, {0x393cc000}, {0x393ce000}, + {0x393d0000}, {0x393d2000}, {0x393d4000}, {0x393d6000}, + {0x393d8000}, {0x393da000}, {0x393dc000}, {0x393de000}, + {0x393e0000}, {0x393e2000}, {0x393e4000}, {0x393e6000}, + {0x393e8000}, {0x393ea000}, {0x393ec000}, {0x393ee000}, + {0x393f0000}, {0x393f2000}, {0x393f4000}, {0x393f6000}, + {0x393f8000}, {0x393fa000}, {0x393fc000}, {0x393fe000}, + {0x39400000}, {0x39402000}, {0x39404000}, {0x39406000}, + {0x39408000}, {0x3940a000}, {0x3940c000}, {0x3940e000}, + {0x39410000}, {0x39412000}, {0x39414000}, {0x39416000}, + {0x39418000}, {0x3941a000}, {0x3941c000}, {0x3941e000}, + {0x39420000}, {0x39422000}, {0x39424000}, {0x39426000}, + {0x39428000}, {0x3942a000}, {0x3942c000}, {0x3942e000}, + {0x39430000}, {0x39432000}, {0x39434000}, {0x39436000}, + {0x39438000}, {0x3943a000}, {0x3943c000}, {0x3943e000}, + {0x39440000}, {0x39442000}, {0x39444000}, {0x39446000}, + {0x39448000}, {0x3944a000}, {0x3944c000}, {0x3944e000}, + {0x39450000}, {0x39452000}, {0x39454000}, {0x39456000}, + {0x39458000}, {0x3945a000}, {0x3945c000}, {0x3945e000}, + {0x39460000}, {0x39462000}, {0x39464000}, {0x39466000}, + {0x39468000}, {0x3946a000}, {0x3946c000}, {0x3946e000}, + {0x39470000}, {0x39472000}, {0x39474000}, {0x39476000}, + {0x39478000}, {0x3947a000}, {0x3947c000}, {0x3947e000}, + {0x39480000}, {0x39482000}, {0x39484000}, {0x39486000}, + {0x39488000}, {0x3948a000}, {0x3948c000}, {0x3948e000}, + {0x39490000}, {0x39492000}, {0x39494000}, {0x39496000}, + {0x39498000}, {0x3949a000}, {0x3949c000}, {0x3949e000}, + {0x394a0000}, {0x394a2000}, {0x394a4000}, {0x394a6000}, + {0x394a8000}, {0x394aa000}, {0x394ac000}, {0x394ae000}, + {0x394b0000}, {0x394b2000}, {0x394b4000}, {0x394b6000}, + {0x394b8000}, {0x394ba000}, {0x394bc000}, {0x394be000}, + {0x394c0000}, {0x394c2000}, {0x394c4000}, {0x394c6000}, + {0x394c8000}, {0x394ca000}, {0x394cc000}, {0x394ce000}, + {0x394d0000}, {0x394d2000}, {0x394d4000}, {0x394d6000}, + {0x394d8000}, {0x394da000}, {0x394dc000}, {0x394de000}, + {0x394e0000}, {0x394e2000}, {0x394e4000}, {0x394e6000}, + {0x394e8000}, {0x394ea000}, {0x394ec000}, {0x394ee000}, + {0x394f0000}, {0x394f2000}, {0x394f4000}, {0x394f6000}, + {0x394f8000}, {0x394fa000}, {0x394fc000}, {0x394fe000}, + {0x39500000}, {0x39502000}, {0x39504000}, {0x39506000}, + {0x39508000}, {0x3950a000}, {0x3950c000}, {0x3950e000}, + {0x39510000}, {0x39512000}, {0x39514000}, {0x39516000}, + {0x39518000}, {0x3951a000}, {0x3951c000}, {0x3951e000}, + {0x39520000}, {0x39522000}, {0x39524000}, {0x39526000}, + {0x39528000}, {0x3952a000}, {0x3952c000}, {0x3952e000}, + {0x39530000}, {0x39532000}, {0x39534000}, {0x39536000}, + {0x39538000}, {0x3953a000}, {0x3953c000}, {0x3953e000}, + {0x39540000}, {0x39542000}, {0x39544000}, {0x39546000}, + {0x39548000}, {0x3954a000}, {0x3954c000}, {0x3954e000}, + {0x39550000}, {0x39552000}, {0x39554000}, {0x39556000}, + {0x39558000}, {0x3955a000}, {0x3955c000}, {0x3955e000}, + {0x39560000}, {0x39562000}, {0x39564000}, {0x39566000}, + {0x39568000}, {0x3956a000}, {0x3956c000}, {0x3956e000}, + {0x39570000}, {0x39572000}, {0x39574000}, {0x39576000}, + {0x39578000}, {0x3957a000}, {0x3957c000}, {0x3957e000}, + {0x39580000}, {0x39582000}, {0x39584000}, {0x39586000}, + {0x39588000}, {0x3958a000}, {0x3958c000}, {0x3958e000}, + {0x39590000}, {0x39592000}, {0x39594000}, {0x39596000}, + {0x39598000}, {0x3959a000}, {0x3959c000}, {0x3959e000}, + {0x395a0000}, {0x395a2000}, {0x395a4000}, {0x395a6000}, + {0x395a8000}, {0x395aa000}, {0x395ac000}, {0x395ae000}, + {0x395b0000}, {0x395b2000}, {0x395b4000}, {0x395b6000}, + {0x395b8000}, {0x395ba000}, {0x395bc000}, {0x395be000}, + {0x395c0000}, {0x395c2000}, {0x395c4000}, {0x395c6000}, + {0x395c8000}, {0x395ca000}, {0x395cc000}, {0x395ce000}, + {0x395d0000}, {0x395d2000}, {0x395d4000}, {0x395d6000}, + {0x395d8000}, {0x395da000}, {0x395dc000}, {0x395de000}, + {0x395e0000}, {0x395e2000}, {0x395e4000}, {0x395e6000}, + {0x395e8000}, {0x395ea000}, {0x395ec000}, {0x395ee000}, + {0x395f0000}, {0x395f2000}, {0x395f4000}, {0x395f6000}, + {0x395f8000}, {0x395fa000}, {0x395fc000}, {0x395fe000}, + {0x39600000}, {0x39602000}, {0x39604000}, {0x39606000}, + {0x39608000}, {0x3960a000}, {0x3960c000}, {0x3960e000}, + {0x39610000}, {0x39612000}, {0x39614000}, {0x39616000}, + {0x39618000}, {0x3961a000}, {0x3961c000}, {0x3961e000}, + {0x39620000}, {0x39622000}, {0x39624000}, {0x39626000}, + {0x39628000}, {0x3962a000}, {0x3962c000}, {0x3962e000}, + {0x39630000}, {0x39632000}, {0x39634000}, {0x39636000}, + {0x39638000}, {0x3963a000}, {0x3963c000}, {0x3963e000}, + {0x39640000}, {0x39642000}, {0x39644000}, {0x39646000}, + {0x39648000}, {0x3964a000}, {0x3964c000}, {0x3964e000}, + {0x39650000}, {0x39652000}, {0x39654000}, {0x39656000}, + {0x39658000}, {0x3965a000}, {0x3965c000}, {0x3965e000}, + {0x39660000}, {0x39662000}, {0x39664000}, {0x39666000}, + {0x39668000}, {0x3966a000}, {0x3966c000}, {0x3966e000}, + {0x39670000}, {0x39672000}, {0x39674000}, {0x39676000}, + {0x39678000}, {0x3967a000}, {0x3967c000}, {0x3967e000}, + {0x39680000}, {0x39682000}, {0x39684000}, {0x39686000}, + {0x39688000}, {0x3968a000}, {0x3968c000}, {0x3968e000}, + {0x39690000}, {0x39692000}, {0x39694000}, {0x39696000}, + {0x39698000}, {0x3969a000}, {0x3969c000}, {0x3969e000}, + {0x396a0000}, {0x396a2000}, {0x396a4000}, {0x396a6000}, + {0x396a8000}, {0x396aa000}, {0x396ac000}, {0x396ae000}, + {0x396b0000}, {0x396b2000}, {0x396b4000}, {0x396b6000}, + {0x396b8000}, {0x396ba000}, {0x396bc000}, {0x396be000}, + {0x396c0000}, {0x396c2000}, {0x396c4000}, {0x396c6000}, + {0x396c8000}, {0x396ca000}, {0x396cc000}, {0x396ce000}, + {0x396d0000}, {0x396d2000}, {0x396d4000}, {0x396d6000}, + {0x396d8000}, {0x396da000}, {0x396dc000}, {0x396de000}, + {0x396e0000}, {0x396e2000}, {0x396e4000}, {0x396e6000}, + {0x396e8000}, {0x396ea000}, {0x396ec000}, {0x396ee000}, + {0x396f0000}, {0x396f2000}, {0x396f4000}, {0x396f6000}, + {0x396f8000}, {0x396fa000}, {0x396fc000}, {0x396fe000}, + {0x39700000}, {0x39702000}, {0x39704000}, {0x39706000}, + {0x39708000}, {0x3970a000}, {0x3970c000}, {0x3970e000}, + {0x39710000}, {0x39712000}, {0x39714000}, {0x39716000}, + {0x39718000}, {0x3971a000}, {0x3971c000}, {0x3971e000}, + {0x39720000}, {0x39722000}, {0x39724000}, {0x39726000}, + {0x39728000}, {0x3972a000}, {0x3972c000}, {0x3972e000}, + {0x39730000}, {0x39732000}, {0x39734000}, {0x39736000}, + {0x39738000}, {0x3973a000}, {0x3973c000}, {0x3973e000}, + {0x39740000}, {0x39742000}, {0x39744000}, {0x39746000}, + {0x39748000}, {0x3974a000}, {0x3974c000}, {0x3974e000}, + {0x39750000}, {0x39752000}, {0x39754000}, {0x39756000}, + {0x39758000}, {0x3975a000}, {0x3975c000}, {0x3975e000}, + {0x39760000}, {0x39762000}, {0x39764000}, {0x39766000}, + {0x39768000}, {0x3976a000}, {0x3976c000}, {0x3976e000}, + {0x39770000}, {0x39772000}, {0x39774000}, {0x39776000}, + {0x39778000}, {0x3977a000}, {0x3977c000}, {0x3977e000}, + {0x39780000}, {0x39782000}, {0x39784000}, {0x39786000}, + {0x39788000}, {0x3978a000}, {0x3978c000}, {0x3978e000}, + {0x39790000}, {0x39792000}, {0x39794000}, {0x39796000}, + {0x39798000}, {0x3979a000}, {0x3979c000}, {0x3979e000}, + {0x397a0000}, {0x397a2000}, {0x397a4000}, {0x397a6000}, + {0x397a8000}, {0x397aa000}, {0x397ac000}, {0x397ae000}, + {0x397b0000}, {0x397b2000}, {0x397b4000}, {0x397b6000}, + {0x397b8000}, {0x397ba000}, {0x397bc000}, {0x397be000}, + {0x397c0000}, {0x397c2000}, {0x397c4000}, {0x397c6000}, + {0x397c8000}, {0x397ca000}, {0x397cc000}, {0x397ce000}, + {0x397d0000}, {0x397d2000}, {0x397d4000}, {0x397d6000}, + {0x397d8000}, {0x397da000}, {0x397dc000}, {0x397de000}, + {0x397e0000}, {0x397e2000}, {0x397e4000}, {0x397e6000}, + {0x397e8000}, {0x397ea000}, {0x397ec000}, {0x397ee000}, + {0x397f0000}, {0x397f2000}, {0x397f4000}, {0x397f6000}, + {0x397f8000}, {0x397fa000}, {0x397fc000}, {0x397fe000}, + {0x39800000}, {0x39802000}, {0x39804000}, {0x39806000}, + {0x39808000}, {0x3980a000}, {0x3980c000}, {0x3980e000}, + {0x39810000}, {0x39812000}, {0x39814000}, {0x39816000}, + {0x39818000}, {0x3981a000}, {0x3981c000}, {0x3981e000}, + {0x39820000}, {0x39822000}, {0x39824000}, {0x39826000}, + {0x39828000}, {0x3982a000}, {0x3982c000}, {0x3982e000}, + {0x39830000}, {0x39832000}, {0x39834000}, {0x39836000}, + {0x39838000}, {0x3983a000}, {0x3983c000}, {0x3983e000}, + {0x39840000}, {0x39842000}, {0x39844000}, {0x39846000}, + {0x39848000}, {0x3984a000}, {0x3984c000}, {0x3984e000}, + {0x39850000}, {0x39852000}, {0x39854000}, {0x39856000}, + {0x39858000}, {0x3985a000}, {0x3985c000}, {0x3985e000}, + {0x39860000}, {0x39862000}, {0x39864000}, {0x39866000}, + {0x39868000}, {0x3986a000}, {0x3986c000}, {0x3986e000}, + {0x39870000}, {0x39872000}, {0x39874000}, {0x39876000}, + {0x39878000}, {0x3987a000}, {0x3987c000}, {0x3987e000}, + {0x39880000}, {0x39882000}, {0x39884000}, {0x39886000}, + {0x39888000}, {0x3988a000}, {0x3988c000}, {0x3988e000}, + {0x39890000}, {0x39892000}, {0x39894000}, {0x39896000}, + {0x39898000}, {0x3989a000}, {0x3989c000}, {0x3989e000}, + {0x398a0000}, {0x398a2000}, {0x398a4000}, {0x398a6000}, + {0x398a8000}, {0x398aa000}, {0x398ac000}, {0x398ae000}, + {0x398b0000}, {0x398b2000}, {0x398b4000}, {0x398b6000}, + {0x398b8000}, {0x398ba000}, {0x398bc000}, {0x398be000}, + {0x398c0000}, {0x398c2000}, {0x398c4000}, {0x398c6000}, + {0x398c8000}, {0x398ca000}, {0x398cc000}, {0x398ce000}, + {0x398d0000}, {0x398d2000}, {0x398d4000}, {0x398d6000}, + {0x398d8000}, {0x398da000}, {0x398dc000}, {0x398de000}, + {0x398e0000}, {0x398e2000}, {0x398e4000}, {0x398e6000}, + {0x398e8000}, {0x398ea000}, {0x398ec000}, {0x398ee000}, + {0x398f0000}, {0x398f2000}, {0x398f4000}, {0x398f6000}, + {0x398f8000}, {0x398fa000}, {0x398fc000}, {0x398fe000}, + {0x39900000}, {0x39902000}, {0x39904000}, {0x39906000}, + {0x39908000}, {0x3990a000}, {0x3990c000}, {0x3990e000}, + {0x39910000}, {0x39912000}, {0x39914000}, {0x39916000}, + {0x39918000}, {0x3991a000}, {0x3991c000}, {0x3991e000}, + {0x39920000}, {0x39922000}, {0x39924000}, {0x39926000}, + {0x39928000}, {0x3992a000}, {0x3992c000}, {0x3992e000}, + {0x39930000}, {0x39932000}, {0x39934000}, {0x39936000}, + {0x39938000}, {0x3993a000}, {0x3993c000}, {0x3993e000}, + {0x39940000}, {0x39942000}, {0x39944000}, {0x39946000}, + {0x39948000}, {0x3994a000}, {0x3994c000}, {0x3994e000}, + {0x39950000}, {0x39952000}, {0x39954000}, {0x39956000}, + {0x39958000}, {0x3995a000}, {0x3995c000}, {0x3995e000}, + {0x39960000}, {0x39962000}, {0x39964000}, {0x39966000}, + {0x39968000}, {0x3996a000}, {0x3996c000}, {0x3996e000}, + {0x39970000}, {0x39972000}, {0x39974000}, {0x39976000}, + {0x39978000}, {0x3997a000}, {0x3997c000}, {0x3997e000}, + {0x39980000}, {0x39982000}, {0x39984000}, {0x39986000}, + {0x39988000}, {0x3998a000}, {0x3998c000}, {0x3998e000}, + {0x39990000}, {0x39992000}, {0x39994000}, {0x39996000}, + {0x39998000}, {0x3999a000}, {0x3999c000}, {0x3999e000}, + {0x399a0000}, {0x399a2000}, {0x399a4000}, {0x399a6000}, + {0x399a8000}, {0x399aa000}, {0x399ac000}, {0x399ae000}, + {0x399b0000}, {0x399b2000}, {0x399b4000}, {0x399b6000}, + {0x399b8000}, {0x399ba000}, {0x399bc000}, {0x399be000}, + {0x399c0000}, {0x399c2000}, {0x399c4000}, {0x399c6000}, + {0x399c8000}, {0x399ca000}, {0x399cc000}, {0x399ce000}, + {0x399d0000}, {0x399d2000}, {0x399d4000}, {0x399d6000}, + {0x399d8000}, {0x399da000}, {0x399dc000}, {0x399de000}, + {0x399e0000}, {0x399e2000}, {0x399e4000}, {0x399e6000}, + {0x399e8000}, {0x399ea000}, {0x399ec000}, {0x399ee000}, + {0x399f0000}, {0x399f2000}, {0x399f4000}, {0x399f6000}, + {0x399f8000}, {0x399fa000}, {0x399fc000}, {0x399fe000}, + {0x39a00000}, {0x39a02000}, {0x39a04000}, {0x39a06000}, + {0x39a08000}, {0x39a0a000}, {0x39a0c000}, {0x39a0e000}, + {0x39a10000}, {0x39a12000}, {0x39a14000}, {0x39a16000}, + {0x39a18000}, {0x39a1a000}, {0x39a1c000}, {0x39a1e000}, + {0x39a20000}, {0x39a22000}, {0x39a24000}, {0x39a26000}, + {0x39a28000}, {0x39a2a000}, {0x39a2c000}, {0x39a2e000}, + {0x39a30000}, {0x39a32000}, {0x39a34000}, {0x39a36000}, + {0x39a38000}, {0x39a3a000}, {0x39a3c000}, {0x39a3e000}, + {0x39a40000}, {0x39a42000}, {0x39a44000}, {0x39a46000}, + {0x39a48000}, {0x39a4a000}, {0x39a4c000}, {0x39a4e000}, + {0x39a50000}, {0x39a52000}, {0x39a54000}, {0x39a56000}, + {0x39a58000}, {0x39a5a000}, {0x39a5c000}, {0x39a5e000}, + {0x39a60000}, {0x39a62000}, {0x39a64000}, {0x39a66000}, + {0x39a68000}, {0x39a6a000}, {0x39a6c000}, {0x39a6e000}, + {0x39a70000}, {0x39a72000}, {0x39a74000}, {0x39a76000}, + {0x39a78000}, {0x39a7a000}, {0x39a7c000}, {0x39a7e000}, + {0x39a80000}, {0x39a82000}, {0x39a84000}, {0x39a86000}, + {0x39a88000}, {0x39a8a000}, {0x39a8c000}, {0x39a8e000}, + {0x39a90000}, {0x39a92000}, {0x39a94000}, {0x39a96000}, + {0x39a98000}, {0x39a9a000}, {0x39a9c000}, {0x39a9e000}, + {0x39aa0000}, {0x39aa2000}, {0x39aa4000}, {0x39aa6000}, + {0x39aa8000}, {0x39aaa000}, {0x39aac000}, {0x39aae000}, + {0x39ab0000}, {0x39ab2000}, {0x39ab4000}, {0x39ab6000}, + {0x39ab8000}, {0x39aba000}, {0x39abc000}, {0x39abe000}, + {0x39ac0000}, {0x39ac2000}, {0x39ac4000}, {0x39ac6000}, + {0x39ac8000}, {0x39aca000}, {0x39acc000}, {0x39ace000}, + {0x39ad0000}, {0x39ad2000}, {0x39ad4000}, {0x39ad6000}, + {0x39ad8000}, {0x39ada000}, {0x39adc000}, {0x39ade000}, + {0x39ae0000}, {0x39ae2000}, {0x39ae4000}, {0x39ae6000}, + {0x39ae8000}, {0x39aea000}, {0x39aec000}, {0x39aee000}, + {0x39af0000}, {0x39af2000}, {0x39af4000}, {0x39af6000}, + {0x39af8000}, {0x39afa000}, {0x39afc000}, {0x39afe000}, + {0x39b00000}, {0x39b02000}, {0x39b04000}, {0x39b06000}, + {0x39b08000}, {0x39b0a000}, {0x39b0c000}, {0x39b0e000}, + {0x39b10000}, {0x39b12000}, {0x39b14000}, {0x39b16000}, + {0x39b18000}, {0x39b1a000}, {0x39b1c000}, {0x39b1e000}, + {0x39b20000}, {0x39b22000}, {0x39b24000}, {0x39b26000}, + {0x39b28000}, {0x39b2a000}, {0x39b2c000}, {0x39b2e000}, + {0x39b30000}, {0x39b32000}, {0x39b34000}, {0x39b36000}, + {0x39b38000}, {0x39b3a000}, {0x39b3c000}, {0x39b3e000}, + {0x39b40000}, {0x39b42000}, {0x39b44000}, {0x39b46000}, + {0x39b48000}, {0x39b4a000}, {0x39b4c000}, {0x39b4e000}, + {0x39b50000}, {0x39b52000}, {0x39b54000}, {0x39b56000}, + {0x39b58000}, {0x39b5a000}, {0x39b5c000}, {0x39b5e000}, + {0x39b60000}, {0x39b62000}, {0x39b64000}, {0x39b66000}, + {0x39b68000}, {0x39b6a000}, {0x39b6c000}, {0x39b6e000}, + {0x39b70000}, {0x39b72000}, {0x39b74000}, {0x39b76000}, + {0x39b78000}, {0x39b7a000}, {0x39b7c000}, {0x39b7e000}, + {0x39b80000}, {0x39b82000}, {0x39b84000}, {0x39b86000}, + {0x39b88000}, {0x39b8a000}, {0x39b8c000}, {0x39b8e000}, + {0x39b90000}, {0x39b92000}, {0x39b94000}, {0x39b96000}, + {0x39b98000}, {0x39b9a000}, {0x39b9c000}, {0x39b9e000}, + {0x39ba0000}, {0x39ba2000}, {0x39ba4000}, {0x39ba6000}, + {0x39ba8000}, {0x39baa000}, {0x39bac000}, {0x39bae000}, + {0x39bb0000}, {0x39bb2000}, {0x39bb4000}, {0x39bb6000}, + {0x39bb8000}, {0x39bba000}, {0x39bbc000}, {0x39bbe000}, + {0x39bc0000}, {0x39bc2000}, {0x39bc4000}, {0x39bc6000}, + {0x39bc8000}, {0x39bca000}, {0x39bcc000}, {0x39bce000}, + {0x39bd0000}, {0x39bd2000}, {0x39bd4000}, {0x39bd6000}, + {0x39bd8000}, {0x39bda000}, {0x39bdc000}, {0x39bde000}, + {0x39be0000}, {0x39be2000}, {0x39be4000}, {0x39be6000}, + {0x39be8000}, {0x39bea000}, {0x39bec000}, {0x39bee000}, + {0x39bf0000}, {0x39bf2000}, {0x39bf4000}, {0x39bf6000}, + {0x39bf8000}, {0x39bfa000}, {0x39bfc000}, {0x39bfe000}, + {0x39c00000}, {0x39c02000}, {0x39c04000}, {0x39c06000}, + {0x39c08000}, {0x39c0a000}, {0x39c0c000}, {0x39c0e000}, + {0x39c10000}, {0x39c12000}, {0x39c14000}, {0x39c16000}, + {0x39c18000}, {0x39c1a000}, {0x39c1c000}, {0x39c1e000}, + {0x39c20000}, {0x39c22000}, {0x39c24000}, {0x39c26000}, + {0x39c28000}, {0x39c2a000}, {0x39c2c000}, {0x39c2e000}, + {0x39c30000}, {0x39c32000}, {0x39c34000}, {0x39c36000}, + {0x39c38000}, {0x39c3a000}, {0x39c3c000}, {0x39c3e000}, + {0x39c40000}, {0x39c42000}, {0x39c44000}, {0x39c46000}, + {0x39c48000}, {0x39c4a000}, {0x39c4c000}, {0x39c4e000}, + {0x39c50000}, {0x39c52000}, {0x39c54000}, {0x39c56000}, + {0x39c58000}, {0x39c5a000}, {0x39c5c000}, {0x39c5e000}, + {0x39c60000}, {0x39c62000}, {0x39c64000}, {0x39c66000}, + {0x39c68000}, {0x39c6a000}, {0x39c6c000}, {0x39c6e000}, + {0x39c70000}, {0x39c72000}, {0x39c74000}, {0x39c76000}, + {0x39c78000}, {0x39c7a000}, {0x39c7c000}, {0x39c7e000}, + {0x39c80000}, {0x39c82000}, {0x39c84000}, {0x39c86000}, + {0x39c88000}, {0x39c8a000}, {0x39c8c000}, {0x39c8e000}, + {0x39c90000}, {0x39c92000}, {0x39c94000}, {0x39c96000}, + {0x39c98000}, {0x39c9a000}, {0x39c9c000}, {0x39c9e000}, + {0x39ca0000}, {0x39ca2000}, {0x39ca4000}, {0x39ca6000}, + {0x39ca8000}, {0x39caa000}, {0x39cac000}, {0x39cae000}, + {0x39cb0000}, {0x39cb2000}, {0x39cb4000}, {0x39cb6000}, + {0x39cb8000}, {0x39cba000}, {0x39cbc000}, {0x39cbe000}, + {0x39cc0000}, {0x39cc2000}, {0x39cc4000}, {0x39cc6000}, + {0x39cc8000}, {0x39cca000}, {0x39ccc000}, {0x39cce000}, + {0x39cd0000}, {0x39cd2000}, {0x39cd4000}, {0x39cd6000}, + {0x39cd8000}, {0x39cda000}, {0x39cdc000}, {0x39cde000}, + {0x39ce0000}, {0x39ce2000}, {0x39ce4000}, {0x39ce6000}, + {0x39ce8000}, {0x39cea000}, {0x39cec000}, {0x39cee000}, + {0x39cf0000}, {0x39cf2000}, {0x39cf4000}, {0x39cf6000}, + {0x39cf8000}, {0x39cfa000}, {0x39cfc000}, {0x39cfe000}, + {0x39d00000}, {0x39d02000}, {0x39d04000}, {0x39d06000}, + {0x39d08000}, {0x39d0a000}, {0x39d0c000}, {0x39d0e000}, + {0x39d10000}, {0x39d12000}, {0x39d14000}, {0x39d16000}, + {0x39d18000}, {0x39d1a000}, {0x39d1c000}, {0x39d1e000}, + {0x39d20000}, {0x39d22000}, {0x39d24000}, {0x39d26000}, + {0x39d28000}, {0x39d2a000}, {0x39d2c000}, {0x39d2e000}, + {0x39d30000}, {0x39d32000}, {0x39d34000}, {0x39d36000}, + {0x39d38000}, {0x39d3a000}, {0x39d3c000}, {0x39d3e000}, + {0x39d40000}, {0x39d42000}, {0x39d44000}, {0x39d46000}, + {0x39d48000}, {0x39d4a000}, {0x39d4c000}, {0x39d4e000}, + {0x39d50000}, {0x39d52000}, {0x39d54000}, {0x39d56000}, + {0x39d58000}, {0x39d5a000}, {0x39d5c000}, {0x39d5e000}, + {0x39d60000}, {0x39d62000}, {0x39d64000}, {0x39d66000}, + {0x39d68000}, {0x39d6a000}, {0x39d6c000}, {0x39d6e000}, + {0x39d70000}, {0x39d72000}, {0x39d74000}, {0x39d76000}, + {0x39d78000}, {0x39d7a000}, {0x39d7c000}, {0x39d7e000}, + {0x39d80000}, {0x39d82000}, {0x39d84000}, {0x39d86000}, + {0x39d88000}, {0x39d8a000}, {0x39d8c000}, {0x39d8e000}, + {0x39d90000}, {0x39d92000}, {0x39d94000}, {0x39d96000}, + {0x39d98000}, {0x39d9a000}, {0x39d9c000}, {0x39d9e000}, + {0x39da0000}, {0x39da2000}, {0x39da4000}, {0x39da6000}, + {0x39da8000}, {0x39daa000}, {0x39dac000}, {0x39dae000}, + {0x39db0000}, {0x39db2000}, {0x39db4000}, {0x39db6000}, + {0x39db8000}, {0x39dba000}, {0x39dbc000}, {0x39dbe000}, + {0x39dc0000}, {0x39dc2000}, {0x39dc4000}, {0x39dc6000}, + {0x39dc8000}, {0x39dca000}, {0x39dcc000}, {0x39dce000}, + {0x39dd0000}, {0x39dd2000}, {0x39dd4000}, {0x39dd6000}, + {0x39dd8000}, {0x39dda000}, {0x39ddc000}, {0x39dde000}, + {0x39de0000}, {0x39de2000}, {0x39de4000}, {0x39de6000}, + {0x39de8000}, {0x39dea000}, {0x39dec000}, {0x39dee000}, + {0x39df0000}, {0x39df2000}, {0x39df4000}, {0x39df6000}, + {0x39df8000}, {0x39dfa000}, {0x39dfc000}, {0x39dfe000}, + {0x39e00000}, {0x39e02000}, {0x39e04000}, {0x39e06000}, + {0x39e08000}, {0x39e0a000}, {0x39e0c000}, {0x39e0e000}, + {0x39e10000}, {0x39e12000}, {0x39e14000}, {0x39e16000}, + {0x39e18000}, {0x39e1a000}, {0x39e1c000}, {0x39e1e000}, + {0x39e20000}, {0x39e22000}, {0x39e24000}, {0x39e26000}, + {0x39e28000}, {0x39e2a000}, {0x39e2c000}, {0x39e2e000}, + {0x39e30000}, {0x39e32000}, {0x39e34000}, {0x39e36000}, + {0x39e38000}, {0x39e3a000}, {0x39e3c000}, {0x39e3e000}, + {0x39e40000}, {0x39e42000}, {0x39e44000}, {0x39e46000}, + {0x39e48000}, {0x39e4a000}, {0x39e4c000}, {0x39e4e000}, + {0x39e50000}, {0x39e52000}, {0x39e54000}, {0x39e56000}, + {0x39e58000}, {0x39e5a000}, {0x39e5c000}, {0x39e5e000}, + {0x39e60000}, {0x39e62000}, {0x39e64000}, {0x39e66000}, + {0x39e68000}, {0x39e6a000}, {0x39e6c000}, {0x39e6e000}, + {0x39e70000}, {0x39e72000}, {0x39e74000}, {0x39e76000}, + {0x39e78000}, {0x39e7a000}, {0x39e7c000}, {0x39e7e000}, + {0x39e80000}, {0x39e82000}, {0x39e84000}, {0x39e86000}, + {0x39e88000}, {0x39e8a000}, {0x39e8c000}, {0x39e8e000}, + {0x39e90000}, {0x39e92000}, {0x39e94000}, {0x39e96000}, + {0x39e98000}, {0x39e9a000}, {0x39e9c000}, {0x39e9e000}, + {0x39ea0000}, {0x39ea2000}, {0x39ea4000}, {0x39ea6000}, + {0x39ea8000}, {0x39eaa000}, {0x39eac000}, {0x39eae000}, + {0x39eb0000}, {0x39eb2000}, {0x39eb4000}, {0x39eb6000}, + {0x39eb8000}, {0x39eba000}, {0x39ebc000}, {0x39ebe000}, + {0x39ec0000}, {0x39ec2000}, {0x39ec4000}, {0x39ec6000}, + {0x39ec8000}, {0x39eca000}, {0x39ecc000}, {0x39ece000}, + {0x39ed0000}, {0x39ed2000}, {0x39ed4000}, {0x39ed6000}, + {0x39ed8000}, {0x39eda000}, {0x39edc000}, {0x39ede000}, + {0x39ee0000}, {0x39ee2000}, {0x39ee4000}, {0x39ee6000}, + {0x39ee8000}, {0x39eea000}, {0x39eec000}, {0x39eee000}, + {0x39ef0000}, {0x39ef2000}, {0x39ef4000}, {0x39ef6000}, + {0x39ef8000}, {0x39efa000}, {0x39efc000}, {0x39efe000}, + {0x39f00000}, {0x39f02000}, {0x39f04000}, {0x39f06000}, + {0x39f08000}, {0x39f0a000}, {0x39f0c000}, {0x39f0e000}, + {0x39f10000}, {0x39f12000}, {0x39f14000}, {0x39f16000}, + {0x39f18000}, {0x39f1a000}, {0x39f1c000}, {0x39f1e000}, + {0x39f20000}, {0x39f22000}, {0x39f24000}, {0x39f26000}, + {0x39f28000}, {0x39f2a000}, {0x39f2c000}, {0x39f2e000}, + {0x39f30000}, {0x39f32000}, {0x39f34000}, {0x39f36000}, + {0x39f38000}, {0x39f3a000}, {0x39f3c000}, {0x39f3e000}, + {0x39f40000}, {0x39f42000}, {0x39f44000}, {0x39f46000}, + {0x39f48000}, {0x39f4a000}, {0x39f4c000}, {0x39f4e000}, + {0x39f50000}, {0x39f52000}, {0x39f54000}, {0x39f56000}, + {0x39f58000}, {0x39f5a000}, {0x39f5c000}, {0x39f5e000}, + {0x39f60000}, {0x39f62000}, {0x39f64000}, {0x39f66000}, + {0x39f68000}, {0x39f6a000}, {0x39f6c000}, {0x39f6e000}, + {0x39f70000}, {0x39f72000}, {0x39f74000}, {0x39f76000}, + {0x39f78000}, {0x39f7a000}, {0x39f7c000}, {0x39f7e000}, + {0x39f80000}, {0x39f82000}, {0x39f84000}, {0x39f86000}, + {0x39f88000}, {0x39f8a000}, {0x39f8c000}, {0x39f8e000}, + {0x39f90000}, {0x39f92000}, {0x39f94000}, {0x39f96000}, + {0x39f98000}, {0x39f9a000}, {0x39f9c000}, {0x39f9e000}, + {0x39fa0000}, {0x39fa2000}, {0x39fa4000}, {0x39fa6000}, + {0x39fa8000}, {0x39faa000}, {0x39fac000}, {0x39fae000}, + {0x39fb0000}, {0x39fb2000}, {0x39fb4000}, {0x39fb6000}, + {0x39fb8000}, {0x39fba000}, {0x39fbc000}, {0x39fbe000}, + {0x39fc0000}, {0x39fc2000}, {0x39fc4000}, {0x39fc6000}, + {0x39fc8000}, {0x39fca000}, {0x39fcc000}, {0x39fce000}, + {0x39fd0000}, {0x39fd2000}, {0x39fd4000}, {0x39fd6000}, + {0x39fd8000}, {0x39fda000}, {0x39fdc000}, {0x39fde000}, + {0x39fe0000}, {0x39fe2000}, {0x39fe4000}, {0x39fe6000}, + {0x39fe8000}, {0x39fea000}, {0x39fec000}, {0x39fee000}, + {0x39ff0000}, {0x39ff2000}, {0x39ff4000}, {0x39ff6000}, + {0x39ff8000}, {0x39ffa000}, {0x39ffc000}, {0x39ffe000}, + {0x3a000000}, {0x3a002000}, {0x3a004000}, {0x3a006000}, + {0x3a008000}, {0x3a00a000}, {0x3a00c000}, {0x3a00e000}, + {0x3a010000}, {0x3a012000}, {0x3a014000}, {0x3a016000}, + {0x3a018000}, {0x3a01a000}, {0x3a01c000}, {0x3a01e000}, + {0x3a020000}, {0x3a022000}, {0x3a024000}, {0x3a026000}, + {0x3a028000}, {0x3a02a000}, {0x3a02c000}, {0x3a02e000}, + {0x3a030000}, {0x3a032000}, {0x3a034000}, {0x3a036000}, + {0x3a038000}, {0x3a03a000}, {0x3a03c000}, {0x3a03e000}, + {0x3a040000}, {0x3a042000}, {0x3a044000}, {0x3a046000}, + {0x3a048000}, {0x3a04a000}, {0x3a04c000}, {0x3a04e000}, + {0x3a050000}, {0x3a052000}, {0x3a054000}, {0x3a056000}, + {0x3a058000}, {0x3a05a000}, {0x3a05c000}, {0x3a05e000}, + {0x3a060000}, {0x3a062000}, {0x3a064000}, {0x3a066000}, + {0x3a068000}, {0x3a06a000}, {0x3a06c000}, {0x3a06e000}, + {0x3a070000}, {0x3a072000}, {0x3a074000}, {0x3a076000}, + {0x3a078000}, {0x3a07a000}, {0x3a07c000}, {0x3a07e000}, + {0x3a080000}, {0x3a082000}, {0x3a084000}, {0x3a086000}, + {0x3a088000}, {0x3a08a000}, {0x3a08c000}, {0x3a08e000}, + {0x3a090000}, {0x3a092000}, {0x3a094000}, {0x3a096000}, + {0x3a098000}, {0x3a09a000}, {0x3a09c000}, {0x3a09e000}, + {0x3a0a0000}, {0x3a0a2000}, {0x3a0a4000}, {0x3a0a6000}, + {0x3a0a8000}, {0x3a0aa000}, {0x3a0ac000}, {0x3a0ae000}, + {0x3a0b0000}, {0x3a0b2000}, {0x3a0b4000}, {0x3a0b6000}, + {0x3a0b8000}, {0x3a0ba000}, {0x3a0bc000}, {0x3a0be000}, + {0x3a0c0000}, {0x3a0c2000}, {0x3a0c4000}, {0x3a0c6000}, + {0x3a0c8000}, {0x3a0ca000}, {0x3a0cc000}, {0x3a0ce000}, + {0x3a0d0000}, {0x3a0d2000}, {0x3a0d4000}, {0x3a0d6000}, + {0x3a0d8000}, {0x3a0da000}, {0x3a0dc000}, {0x3a0de000}, + {0x3a0e0000}, {0x3a0e2000}, {0x3a0e4000}, {0x3a0e6000}, + {0x3a0e8000}, {0x3a0ea000}, {0x3a0ec000}, {0x3a0ee000}, + {0x3a0f0000}, {0x3a0f2000}, {0x3a0f4000}, {0x3a0f6000}, + {0x3a0f8000}, {0x3a0fa000}, {0x3a0fc000}, {0x3a0fe000}, + {0x3a100000}, {0x3a102000}, {0x3a104000}, {0x3a106000}, + {0x3a108000}, {0x3a10a000}, {0x3a10c000}, {0x3a10e000}, + {0x3a110000}, {0x3a112000}, {0x3a114000}, {0x3a116000}, + {0x3a118000}, {0x3a11a000}, {0x3a11c000}, {0x3a11e000}, + {0x3a120000}, {0x3a122000}, {0x3a124000}, {0x3a126000}, + {0x3a128000}, {0x3a12a000}, {0x3a12c000}, {0x3a12e000}, + {0x3a130000}, {0x3a132000}, {0x3a134000}, {0x3a136000}, + {0x3a138000}, {0x3a13a000}, {0x3a13c000}, {0x3a13e000}, + {0x3a140000}, {0x3a142000}, {0x3a144000}, {0x3a146000}, + {0x3a148000}, {0x3a14a000}, {0x3a14c000}, {0x3a14e000}, + {0x3a150000}, {0x3a152000}, {0x3a154000}, {0x3a156000}, + {0x3a158000}, {0x3a15a000}, {0x3a15c000}, {0x3a15e000}, + {0x3a160000}, {0x3a162000}, {0x3a164000}, {0x3a166000}, + {0x3a168000}, {0x3a16a000}, {0x3a16c000}, {0x3a16e000}, + {0x3a170000}, {0x3a172000}, {0x3a174000}, {0x3a176000}, + {0x3a178000}, {0x3a17a000}, {0x3a17c000}, {0x3a17e000}, + {0x3a180000}, {0x3a182000}, {0x3a184000}, {0x3a186000}, + {0x3a188000}, {0x3a18a000}, {0x3a18c000}, {0x3a18e000}, + {0x3a190000}, {0x3a192000}, {0x3a194000}, {0x3a196000}, + {0x3a198000}, {0x3a19a000}, {0x3a19c000}, {0x3a19e000}, + {0x3a1a0000}, {0x3a1a2000}, {0x3a1a4000}, {0x3a1a6000}, + {0x3a1a8000}, {0x3a1aa000}, {0x3a1ac000}, {0x3a1ae000}, + {0x3a1b0000}, {0x3a1b2000}, {0x3a1b4000}, {0x3a1b6000}, + {0x3a1b8000}, {0x3a1ba000}, {0x3a1bc000}, {0x3a1be000}, + {0x3a1c0000}, {0x3a1c2000}, {0x3a1c4000}, {0x3a1c6000}, + {0x3a1c8000}, {0x3a1ca000}, {0x3a1cc000}, {0x3a1ce000}, + {0x3a1d0000}, {0x3a1d2000}, {0x3a1d4000}, {0x3a1d6000}, + {0x3a1d8000}, {0x3a1da000}, {0x3a1dc000}, {0x3a1de000}, + {0x3a1e0000}, {0x3a1e2000}, {0x3a1e4000}, {0x3a1e6000}, + {0x3a1e8000}, {0x3a1ea000}, {0x3a1ec000}, {0x3a1ee000}, + {0x3a1f0000}, {0x3a1f2000}, {0x3a1f4000}, {0x3a1f6000}, + {0x3a1f8000}, {0x3a1fa000}, {0x3a1fc000}, {0x3a1fe000}, + {0x3a200000}, {0x3a202000}, {0x3a204000}, {0x3a206000}, + {0x3a208000}, {0x3a20a000}, {0x3a20c000}, {0x3a20e000}, + {0x3a210000}, {0x3a212000}, {0x3a214000}, {0x3a216000}, + {0x3a218000}, {0x3a21a000}, {0x3a21c000}, {0x3a21e000}, + {0x3a220000}, {0x3a222000}, {0x3a224000}, {0x3a226000}, + {0x3a228000}, {0x3a22a000}, {0x3a22c000}, {0x3a22e000}, + {0x3a230000}, {0x3a232000}, {0x3a234000}, {0x3a236000}, + {0x3a238000}, {0x3a23a000}, {0x3a23c000}, {0x3a23e000}, + {0x3a240000}, {0x3a242000}, {0x3a244000}, {0x3a246000}, + {0x3a248000}, {0x3a24a000}, {0x3a24c000}, {0x3a24e000}, + {0x3a250000}, {0x3a252000}, {0x3a254000}, {0x3a256000}, + {0x3a258000}, {0x3a25a000}, {0x3a25c000}, {0x3a25e000}, + {0x3a260000}, {0x3a262000}, {0x3a264000}, {0x3a266000}, + {0x3a268000}, {0x3a26a000}, {0x3a26c000}, {0x3a26e000}, + {0x3a270000}, {0x3a272000}, {0x3a274000}, {0x3a276000}, + {0x3a278000}, {0x3a27a000}, {0x3a27c000}, {0x3a27e000}, + {0x3a280000}, {0x3a282000}, {0x3a284000}, {0x3a286000}, + {0x3a288000}, {0x3a28a000}, {0x3a28c000}, {0x3a28e000}, + {0x3a290000}, {0x3a292000}, {0x3a294000}, {0x3a296000}, + {0x3a298000}, {0x3a29a000}, {0x3a29c000}, {0x3a29e000}, + {0x3a2a0000}, {0x3a2a2000}, {0x3a2a4000}, {0x3a2a6000}, + {0x3a2a8000}, {0x3a2aa000}, {0x3a2ac000}, {0x3a2ae000}, + {0x3a2b0000}, {0x3a2b2000}, {0x3a2b4000}, {0x3a2b6000}, + {0x3a2b8000}, {0x3a2ba000}, {0x3a2bc000}, {0x3a2be000}, + {0x3a2c0000}, {0x3a2c2000}, {0x3a2c4000}, {0x3a2c6000}, + {0x3a2c8000}, {0x3a2ca000}, {0x3a2cc000}, {0x3a2ce000}, + {0x3a2d0000}, {0x3a2d2000}, {0x3a2d4000}, {0x3a2d6000}, + {0x3a2d8000}, {0x3a2da000}, {0x3a2dc000}, {0x3a2de000}, + {0x3a2e0000}, {0x3a2e2000}, {0x3a2e4000}, {0x3a2e6000}, + {0x3a2e8000}, {0x3a2ea000}, {0x3a2ec000}, {0x3a2ee000}, + {0x3a2f0000}, {0x3a2f2000}, {0x3a2f4000}, {0x3a2f6000}, + {0x3a2f8000}, {0x3a2fa000}, {0x3a2fc000}, {0x3a2fe000}, + {0x3a300000}, {0x3a302000}, {0x3a304000}, {0x3a306000}, + {0x3a308000}, {0x3a30a000}, {0x3a30c000}, {0x3a30e000}, + {0x3a310000}, {0x3a312000}, {0x3a314000}, {0x3a316000}, + {0x3a318000}, {0x3a31a000}, {0x3a31c000}, {0x3a31e000}, + {0x3a320000}, {0x3a322000}, {0x3a324000}, {0x3a326000}, + {0x3a328000}, {0x3a32a000}, {0x3a32c000}, {0x3a32e000}, + {0x3a330000}, {0x3a332000}, {0x3a334000}, {0x3a336000}, + {0x3a338000}, {0x3a33a000}, {0x3a33c000}, {0x3a33e000}, + {0x3a340000}, {0x3a342000}, {0x3a344000}, {0x3a346000}, + {0x3a348000}, {0x3a34a000}, {0x3a34c000}, {0x3a34e000}, + {0x3a350000}, {0x3a352000}, {0x3a354000}, {0x3a356000}, + {0x3a358000}, {0x3a35a000}, {0x3a35c000}, {0x3a35e000}, + {0x3a360000}, {0x3a362000}, {0x3a364000}, {0x3a366000}, + {0x3a368000}, {0x3a36a000}, {0x3a36c000}, {0x3a36e000}, + {0x3a370000}, {0x3a372000}, {0x3a374000}, {0x3a376000}, + {0x3a378000}, {0x3a37a000}, {0x3a37c000}, {0x3a37e000}, + {0x3a380000}, {0x3a382000}, {0x3a384000}, {0x3a386000}, + {0x3a388000}, {0x3a38a000}, {0x3a38c000}, {0x3a38e000}, + {0x3a390000}, {0x3a392000}, {0x3a394000}, {0x3a396000}, + {0x3a398000}, {0x3a39a000}, {0x3a39c000}, {0x3a39e000}, + {0x3a3a0000}, {0x3a3a2000}, {0x3a3a4000}, {0x3a3a6000}, + {0x3a3a8000}, {0x3a3aa000}, {0x3a3ac000}, {0x3a3ae000}, + {0x3a3b0000}, {0x3a3b2000}, {0x3a3b4000}, {0x3a3b6000}, + {0x3a3b8000}, {0x3a3ba000}, {0x3a3bc000}, {0x3a3be000}, + {0x3a3c0000}, {0x3a3c2000}, {0x3a3c4000}, {0x3a3c6000}, + {0x3a3c8000}, {0x3a3ca000}, {0x3a3cc000}, {0x3a3ce000}, + {0x3a3d0000}, {0x3a3d2000}, {0x3a3d4000}, {0x3a3d6000}, + {0x3a3d8000}, {0x3a3da000}, {0x3a3dc000}, {0x3a3de000}, + {0x3a3e0000}, {0x3a3e2000}, {0x3a3e4000}, {0x3a3e6000}, + {0x3a3e8000}, {0x3a3ea000}, {0x3a3ec000}, {0x3a3ee000}, + {0x3a3f0000}, {0x3a3f2000}, {0x3a3f4000}, {0x3a3f6000}, + {0x3a3f8000}, {0x3a3fa000}, {0x3a3fc000}, {0x3a3fe000}, + {0x3a400000}, {0x3a402000}, {0x3a404000}, {0x3a406000}, + {0x3a408000}, {0x3a40a000}, {0x3a40c000}, {0x3a40e000}, + {0x3a410000}, {0x3a412000}, {0x3a414000}, {0x3a416000}, + {0x3a418000}, {0x3a41a000}, {0x3a41c000}, {0x3a41e000}, + {0x3a420000}, {0x3a422000}, {0x3a424000}, {0x3a426000}, + {0x3a428000}, {0x3a42a000}, {0x3a42c000}, {0x3a42e000}, + {0x3a430000}, {0x3a432000}, {0x3a434000}, {0x3a436000}, + {0x3a438000}, {0x3a43a000}, {0x3a43c000}, {0x3a43e000}, + {0x3a440000}, {0x3a442000}, {0x3a444000}, {0x3a446000}, + {0x3a448000}, {0x3a44a000}, {0x3a44c000}, {0x3a44e000}, + {0x3a450000}, {0x3a452000}, {0x3a454000}, {0x3a456000}, + {0x3a458000}, {0x3a45a000}, {0x3a45c000}, {0x3a45e000}, + {0x3a460000}, {0x3a462000}, {0x3a464000}, {0x3a466000}, + {0x3a468000}, {0x3a46a000}, {0x3a46c000}, {0x3a46e000}, + {0x3a470000}, {0x3a472000}, {0x3a474000}, {0x3a476000}, + {0x3a478000}, {0x3a47a000}, {0x3a47c000}, {0x3a47e000}, + {0x3a480000}, {0x3a482000}, {0x3a484000}, {0x3a486000}, + {0x3a488000}, {0x3a48a000}, {0x3a48c000}, {0x3a48e000}, + {0x3a490000}, {0x3a492000}, {0x3a494000}, {0x3a496000}, + {0x3a498000}, {0x3a49a000}, {0x3a49c000}, {0x3a49e000}, + {0x3a4a0000}, {0x3a4a2000}, {0x3a4a4000}, {0x3a4a6000}, + {0x3a4a8000}, {0x3a4aa000}, {0x3a4ac000}, {0x3a4ae000}, + {0x3a4b0000}, {0x3a4b2000}, {0x3a4b4000}, {0x3a4b6000}, + {0x3a4b8000}, {0x3a4ba000}, {0x3a4bc000}, {0x3a4be000}, + {0x3a4c0000}, {0x3a4c2000}, {0x3a4c4000}, {0x3a4c6000}, + {0x3a4c8000}, {0x3a4ca000}, {0x3a4cc000}, {0x3a4ce000}, + {0x3a4d0000}, {0x3a4d2000}, {0x3a4d4000}, {0x3a4d6000}, + {0x3a4d8000}, {0x3a4da000}, {0x3a4dc000}, {0x3a4de000}, + {0x3a4e0000}, {0x3a4e2000}, {0x3a4e4000}, {0x3a4e6000}, + {0x3a4e8000}, {0x3a4ea000}, {0x3a4ec000}, {0x3a4ee000}, + {0x3a4f0000}, {0x3a4f2000}, {0x3a4f4000}, {0x3a4f6000}, + {0x3a4f8000}, {0x3a4fa000}, {0x3a4fc000}, {0x3a4fe000}, + {0x3a500000}, {0x3a502000}, {0x3a504000}, {0x3a506000}, + {0x3a508000}, {0x3a50a000}, {0x3a50c000}, {0x3a50e000}, + {0x3a510000}, {0x3a512000}, {0x3a514000}, {0x3a516000}, + {0x3a518000}, {0x3a51a000}, {0x3a51c000}, {0x3a51e000}, + {0x3a520000}, {0x3a522000}, {0x3a524000}, {0x3a526000}, + {0x3a528000}, {0x3a52a000}, {0x3a52c000}, {0x3a52e000}, + {0x3a530000}, {0x3a532000}, {0x3a534000}, {0x3a536000}, + {0x3a538000}, {0x3a53a000}, {0x3a53c000}, {0x3a53e000}, + {0x3a540000}, {0x3a542000}, {0x3a544000}, {0x3a546000}, + {0x3a548000}, {0x3a54a000}, {0x3a54c000}, {0x3a54e000}, + {0x3a550000}, {0x3a552000}, {0x3a554000}, {0x3a556000}, + {0x3a558000}, {0x3a55a000}, {0x3a55c000}, {0x3a55e000}, + {0x3a560000}, {0x3a562000}, {0x3a564000}, {0x3a566000}, + {0x3a568000}, {0x3a56a000}, {0x3a56c000}, {0x3a56e000}, + {0x3a570000}, {0x3a572000}, {0x3a574000}, {0x3a576000}, + {0x3a578000}, {0x3a57a000}, {0x3a57c000}, {0x3a57e000}, + {0x3a580000}, {0x3a582000}, {0x3a584000}, {0x3a586000}, + {0x3a588000}, {0x3a58a000}, {0x3a58c000}, {0x3a58e000}, + {0x3a590000}, {0x3a592000}, {0x3a594000}, {0x3a596000}, + {0x3a598000}, {0x3a59a000}, {0x3a59c000}, {0x3a59e000}, + {0x3a5a0000}, {0x3a5a2000}, {0x3a5a4000}, {0x3a5a6000}, + {0x3a5a8000}, {0x3a5aa000}, {0x3a5ac000}, {0x3a5ae000}, + {0x3a5b0000}, {0x3a5b2000}, {0x3a5b4000}, {0x3a5b6000}, + {0x3a5b8000}, {0x3a5ba000}, {0x3a5bc000}, {0x3a5be000}, + {0x3a5c0000}, {0x3a5c2000}, {0x3a5c4000}, {0x3a5c6000}, + {0x3a5c8000}, {0x3a5ca000}, {0x3a5cc000}, {0x3a5ce000}, + {0x3a5d0000}, {0x3a5d2000}, {0x3a5d4000}, {0x3a5d6000}, + {0x3a5d8000}, {0x3a5da000}, {0x3a5dc000}, {0x3a5de000}, + {0x3a5e0000}, {0x3a5e2000}, {0x3a5e4000}, {0x3a5e6000}, + {0x3a5e8000}, {0x3a5ea000}, {0x3a5ec000}, {0x3a5ee000}, + {0x3a5f0000}, {0x3a5f2000}, {0x3a5f4000}, {0x3a5f6000}, + {0x3a5f8000}, {0x3a5fa000}, {0x3a5fc000}, {0x3a5fe000}, + {0x3a600000}, {0x3a602000}, {0x3a604000}, {0x3a606000}, + {0x3a608000}, {0x3a60a000}, {0x3a60c000}, {0x3a60e000}, + {0x3a610000}, {0x3a612000}, {0x3a614000}, {0x3a616000}, + {0x3a618000}, {0x3a61a000}, {0x3a61c000}, {0x3a61e000}, + {0x3a620000}, {0x3a622000}, {0x3a624000}, {0x3a626000}, + {0x3a628000}, {0x3a62a000}, {0x3a62c000}, {0x3a62e000}, + {0x3a630000}, {0x3a632000}, {0x3a634000}, {0x3a636000}, + {0x3a638000}, {0x3a63a000}, {0x3a63c000}, {0x3a63e000}, + {0x3a640000}, {0x3a642000}, {0x3a644000}, {0x3a646000}, + {0x3a648000}, {0x3a64a000}, {0x3a64c000}, {0x3a64e000}, + {0x3a650000}, {0x3a652000}, {0x3a654000}, {0x3a656000}, + {0x3a658000}, {0x3a65a000}, {0x3a65c000}, {0x3a65e000}, + {0x3a660000}, {0x3a662000}, {0x3a664000}, {0x3a666000}, + {0x3a668000}, {0x3a66a000}, {0x3a66c000}, {0x3a66e000}, + {0x3a670000}, {0x3a672000}, {0x3a674000}, {0x3a676000}, + {0x3a678000}, {0x3a67a000}, {0x3a67c000}, {0x3a67e000}, + {0x3a680000}, {0x3a682000}, {0x3a684000}, {0x3a686000}, + {0x3a688000}, {0x3a68a000}, {0x3a68c000}, {0x3a68e000}, + {0x3a690000}, {0x3a692000}, {0x3a694000}, {0x3a696000}, + {0x3a698000}, {0x3a69a000}, {0x3a69c000}, {0x3a69e000}, + {0x3a6a0000}, {0x3a6a2000}, {0x3a6a4000}, {0x3a6a6000}, + {0x3a6a8000}, {0x3a6aa000}, {0x3a6ac000}, {0x3a6ae000}, + {0x3a6b0000}, {0x3a6b2000}, {0x3a6b4000}, {0x3a6b6000}, + {0x3a6b8000}, {0x3a6ba000}, {0x3a6bc000}, {0x3a6be000}, + {0x3a6c0000}, {0x3a6c2000}, {0x3a6c4000}, {0x3a6c6000}, + {0x3a6c8000}, {0x3a6ca000}, {0x3a6cc000}, {0x3a6ce000}, + {0x3a6d0000}, {0x3a6d2000}, {0x3a6d4000}, {0x3a6d6000}, + {0x3a6d8000}, {0x3a6da000}, {0x3a6dc000}, {0x3a6de000}, + {0x3a6e0000}, {0x3a6e2000}, {0x3a6e4000}, {0x3a6e6000}, + {0x3a6e8000}, {0x3a6ea000}, {0x3a6ec000}, {0x3a6ee000}, + {0x3a6f0000}, {0x3a6f2000}, {0x3a6f4000}, {0x3a6f6000}, + {0x3a6f8000}, {0x3a6fa000}, {0x3a6fc000}, {0x3a6fe000}, + {0x3a700000}, {0x3a702000}, {0x3a704000}, {0x3a706000}, + {0x3a708000}, {0x3a70a000}, {0x3a70c000}, {0x3a70e000}, + {0x3a710000}, {0x3a712000}, {0x3a714000}, {0x3a716000}, + {0x3a718000}, {0x3a71a000}, {0x3a71c000}, {0x3a71e000}, + {0x3a720000}, {0x3a722000}, {0x3a724000}, {0x3a726000}, + {0x3a728000}, {0x3a72a000}, {0x3a72c000}, {0x3a72e000}, + {0x3a730000}, {0x3a732000}, {0x3a734000}, {0x3a736000}, + {0x3a738000}, {0x3a73a000}, {0x3a73c000}, {0x3a73e000}, + {0x3a740000}, {0x3a742000}, {0x3a744000}, {0x3a746000}, + {0x3a748000}, {0x3a74a000}, {0x3a74c000}, {0x3a74e000}, + {0x3a750000}, {0x3a752000}, {0x3a754000}, {0x3a756000}, + {0x3a758000}, {0x3a75a000}, {0x3a75c000}, {0x3a75e000}, + {0x3a760000}, {0x3a762000}, {0x3a764000}, {0x3a766000}, + {0x3a768000}, {0x3a76a000}, {0x3a76c000}, {0x3a76e000}, + {0x3a770000}, {0x3a772000}, {0x3a774000}, {0x3a776000}, + {0x3a778000}, {0x3a77a000}, {0x3a77c000}, {0x3a77e000}, + {0x3a780000}, {0x3a782000}, {0x3a784000}, {0x3a786000}, + {0x3a788000}, {0x3a78a000}, {0x3a78c000}, {0x3a78e000}, + {0x3a790000}, {0x3a792000}, {0x3a794000}, {0x3a796000}, + {0x3a798000}, {0x3a79a000}, {0x3a79c000}, {0x3a79e000}, + {0x3a7a0000}, {0x3a7a2000}, {0x3a7a4000}, {0x3a7a6000}, + {0x3a7a8000}, {0x3a7aa000}, {0x3a7ac000}, {0x3a7ae000}, + {0x3a7b0000}, {0x3a7b2000}, {0x3a7b4000}, {0x3a7b6000}, + {0x3a7b8000}, {0x3a7ba000}, {0x3a7bc000}, {0x3a7be000}, + {0x3a7c0000}, {0x3a7c2000}, {0x3a7c4000}, {0x3a7c6000}, + {0x3a7c8000}, {0x3a7ca000}, {0x3a7cc000}, {0x3a7ce000}, + {0x3a7d0000}, {0x3a7d2000}, {0x3a7d4000}, {0x3a7d6000}, + {0x3a7d8000}, {0x3a7da000}, {0x3a7dc000}, {0x3a7de000}, + {0x3a7e0000}, {0x3a7e2000}, {0x3a7e4000}, {0x3a7e6000}, + {0x3a7e8000}, {0x3a7ea000}, {0x3a7ec000}, {0x3a7ee000}, + {0x3a7f0000}, {0x3a7f2000}, {0x3a7f4000}, {0x3a7f6000}, + {0x3a7f8000}, {0x3a7fa000}, {0x3a7fc000}, {0x3a7fe000}, + {0x3a800000}, {0x3a802000}, {0x3a804000}, {0x3a806000}, + {0x3a808000}, {0x3a80a000}, {0x3a80c000}, {0x3a80e000}, + {0x3a810000}, {0x3a812000}, {0x3a814000}, {0x3a816000}, + {0x3a818000}, {0x3a81a000}, {0x3a81c000}, {0x3a81e000}, + {0x3a820000}, {0x3a822000}, {0x3a824000}, {0x3a826000}, + {0x3a828000}, {0x3a82a000}, {0x3a82c000}, {0x3a82e000}, + {0x3a830000}, {0x3a832000}, {0x3a834000}, {0x3a836000}, + {0x3a838000}, {0x3a83a000}, {0x3a83c000}, {0x3a83e000}, + {0x3a840000}, {0x3a842000}, {0x3a844000}, {0x3a846000}, + {0x3a848000}, {0x3a84a000}, {0x3a84c000}, {0x3a84e000}, + {0x3a850000}, {0x3a852000}, {0x3a854000}, {0x3a856000}, + {0x3a858000}, {0x3a85a000}, {0x3a85c000}, {0x3a85e000}, + {0x3a860000}, {0x3a862000}, {0x3a864000}, {0x3a866000}, + {0x3a868000}, {0x3a86a000}, {0x3a86c000}, {0x3a86e000}, + {0x3a870000}, {0x3a872000}, {0x3a874000}, {0x3a876000}, + {0x3a878000}, {0x3a87a000}, {0x3a87c000}, {0x3a87e000}, + {0x3a880000}, {0x3a882000}, {0x3a884000}, {0x3a886000}, + {0x3a888000}, {0x3a88a000}, {0x3a88c000}, {0x3a88e000}, + {0x3a890000}, {0x3a892000}, {0x3a894000}, {0x3a896000}, + {0x3a898000}, {0x3a89a000}, {0x3a89c000}, {0x3a89e000}, + {0x3a8a0000}, {0x3a8a2000}, {0x3a8a4000}, {0x3a8a6000}, + {0x3a8a8000}, {0x3a8aa000}, {0x3a8ac000}, {0x3a8ae000}, + {0x3a8b0000}, {0x3a8b2000}, {0x3a8b4000}, {0x3a8b6000}, + {0x3a8b8000}, {0x3a8ba000}, {0x3a8bc000}, {0x3a8be000}, + {0x3a8c0000}, {0x3a8c2000}, {0x3a8c4000}, {0x3a8c6000}, + {0x3a8c8000}, {0x3a8ca000}, {0x3a8cc000}, {0x3a8ce000}, + {0x3a8d0000}, {0x3a8d2000}, {0x3a8d4000}, {0x3a8d6000}, + {0x3a8d8000}, {0x3a8da000}, {0x3a8dc000}, {0x3a8de000}, + {0x3a8e0000}, {0x3a8e2000}, {0x3a8e4000}, {0x3a8e6000}, + {0x3a8e8000}, {0x3a8ea000}, {0x3a8ec000}, {0x3a8ee000}, + {0x3a8f0000}, {0x3a8f2000}, {0x3a8f4000}, {0x3a8f6000}, + {0x3a8f8000}, {0x3a8fa000}, {0x3a8fc000}, {0x3a8fe000}, + {0x3a900000}, {0x3a902000}, {0x3a904000}, {0x3a906000}, + {0x3a908000}, {0x3a90a000}, {0x3a90c000}, {0x3a90e000}, + {0x3a910000}, {0x3a912000}, {0x3a914000}, {0x3a916000}, + {0x3a918000}, {0x3a91a000}, {0x3a91c000}, {0x3a91e000}, + {0x3a920000}, {0x3a922000}, {0x3a924000}, {0x3a926000}, + {0x3a928000}, {0x3a92a000}, {0x3a92c000}, {0x3a92e000}, + {0x3a930000}, {0x3a932000}, {0x3a934000}, {0x3a936000}, + {0x3a938000}, {0x3a93a000}, {0x3a93c000}, {0x3a93e000}, + {0x3a940000}, {0x3a942000}, {0x3a944000}, {0x3a946000}, + {0x3a948000}, {0x3a94a000}, {0x3a94c000}, {0x3a94e000}, + {0x3a950000}, {0x3a952000}, {0x3a954000}, {0x3a956000}, + {0x3a958000}, {0x3a95a000}, {0x3a95c000}, {0x3a95e000}, + {0x3a960000}, {0x3a962000}, {0x3a964000}, {0x3a966000}, + {0x3a968000}, {0x3a96a000}, {0x3a96c000}, {0x3a96e000}, + {0x3a970000}, {0x3a972000}, {0x3a974000}, {0x3a976000}, + {0x3a978000}, {0x3a97a000}, {0x3a97c000}, {0x3a97e000}, + {0x3a980000}, {0x3a982000}, {0x3a984000}, {0x3a986000}, + {0x3a988000}, {0x3a98a000}, {0x3a98c000}, {0x3a98e000}, + {0x3a990000}, {0x3a992000}, {0x3a994000}, {0x3a996000}, + {0x3a998000}, {0x3a99a000}, {0x3a99c000}, {0x3a99e000}, + {0x3a9a0000}, {0x3a9a2000}, {0x3a9a4000}, {0x3a9a6000}, + {0x3a9a8000}, {0x3a9aa000}, {0x3a9ac000}, {0x3a9ae000}, + {0x3a9b0000}, {0x3a9b2000}, {0x3a9b4000}, {0x3a9b6000}, + {0x3a9b8000}, {0x3a9ba000}, {0x3a9bc000}, {0x3a9be000}, + {0x3a9c0000}, {0x3a9c2000}, {0x3a9c4000}, {0x3a9c6000}, + {0x3a9c8000}, {0x3a9ca000}, {0x3a9cc000}, {0x3a9ce000}, + {0x3a9d0000}, {0x3a9d2000}, {0x3a9d4000}, {0x3a9d6000}, + {0x3a9d8000}, {0x3a9da000}, {0x3a9dc000}, {0x3a9de000}, + {0x3a9e0000}, {0x3a9e2000}, {0x3a9e4000}, {0x3a9e6000}, + {0x3a9e8000}, {0x3a9ea000}, {0x3a9ec000}, {0x3a9ee000}, + {0x3a9f0000}, {0x3a9f2000}, {0x3a9f4000}, {0x3a9f6000}, + {0x3a9f8000}, {0x3a9fa000}, {0x3a9fc000}, {0x3a9fe000}, + {0x3aa00000}, {0x3aa02000}, {0x3aa04000}, {0x3aa06000}, + {0x3aa08000}, {0x3aa0a000}, {0x3aa0c000}, {0x3aa0e000}, + {0x3aa10000}, {0x3aa12000}, {0x3aa14000}, {0x3aa16000}, + {0x3aa18000}, {0x3aa1a000}, {0x3aa1c000}, {0x3aa1e000}, + {0x3aa20000}, {0x3aa22000}, {0x3aa24000}, {0x3aa26000}, + {0x3aa28000}, {0x3aa2a000}, {0x3aa2c000}, {0x3aa2e000}, + {0x3aa30000}, {0x3aa32000}, {0x3aa34000}, {0x3aa36000}, + {0x3aa38000}, {0x3aa3a000}, {0x3aa3c000}, {0x3aa3e000}, + {0x3aa40000}, {0x3aa42000}, {0x3aa44000}, {0x3aa46000}, + {0x3aa48000}, {0x3aa4a000}, {0x3aa4c000}, {0x3aa4e000}, + {0x3aa50000}, {0x3aa52000}, {0x3aa54000}, {0x3aa56000}, + {0x3aa58000}, {0x3aa5a000}, {0x3aa5c000}, {0x3aa5e000}, + {0x3aa60000}, {0x3aa62000}, {0x3aa64000}, {0x3aa66000}, + {0x3aa68000}, {0x3aa6a000}, {0x3aa6c000}, {0x3aa6e000}, + {0x3aa70000}, {0x3aa72000}, {0x3aa74000}, {0x3aa76000}, + {0x3aa78000}, {0x3aa7a000}, {0x3aa7c000}, {0x3aa7e000}, + {0x3aa80000}, {0x3aa82000}, {0x3aa84000}, {0x3aa86000}, + {0x3aa88000}, {0x3aa8a000}, {0x3aa8c000}, {0x3aa8e000}, + {0x3aa90000}, {0x3aa92000}, {0x3aa94000}, {0x3aa96000}, + {0x3aa98000}, {0x3aa9a000}, {0x3aa9c000}, {0x3aa9e000}, + {0x3aaa0000}, {0x3aaa2000}, {0x3aaa4000}, {0x3aaa6000}, + {0x3aaa8000}, {0x3aaaa000}, {0x3aaac000}, {0x3aaae000}, + {0x3aab0000}, {0x3aab2000}, {0x3aab4000}, {0x3aab6000}, + {0x3aab8000}, {0x3aaba000}, {0x3aabc000}, {0x3aabe000}, + {0x3aac0000}, {0x3aac2000}, {0x3aac4000}, {0x3aac6000}, + {0x3aac8000}, {0x3aaca000}, {0x3aacc000}, {0x3aace000}, + {0x3aad0000}, {0x3aad2000}, {0x3aad4000}, {0x3aad6000}, + {0x3aad8000}, {0x3aada000}, {0x3aadc000}, {0x3aade000}, + {0x3aae0000}, {0x3aae2000}, {0x3aae4000}, {0x3aae6000}, + {0x3aae8000}, {0x3aaea000}, {0x3aaec000}, {0x3aaee000}, + {0x3aaf0000}, {0x3aaf2000}, {0x3aaf4000}, {0x3aaf6000}, + {0x3aaf8000}, {0x3aafa000}, {0x3aafc000}, {0x3aafe000}, + {0x3ab00000}, {0x3ab02000}, {0x3ab04000}, {0x3ab06000}, + {0x3ab08000}, {0x3ab0a000}, {0x3ab0c000}, {0x3ab0e000}, + {0x3ab10000}, {0x3ab12000}, {0x3ab14000}, {0x3ab16000}, + {0x3ab18000}, {0x3ab1a000}, {0x3ab1c000}, {0x3ab1e000}, + {0x3ab20000}, {0x3ab22000}, {0x3ab24000}, {0x3ab26000}, + {0x3ab28000}, {0x3ab2a000}, {0x3ab2c000}, {0x3ab2e000}, + {0x3ab30000}, {0x3ab32000}, {0x3ab34000}, {0x3ab36000}, + {0x3ab38000}, {0x3ab3a000}, {0x3ab3c000}, {0x3ab3e000}, + {0x3ab40000}, {0x3ab42000}, {0x3ab44000}, {0x3ab46000}, + {0x3ab48000}, {0x3ab4a000}, {0x3ab4c000}, {0x3ab4e000}, + {0x3ab50000}, {0x3ab52000}, {0x3ab54000}, {0x3ab56000}, + {0x3ab58000}, {0x3ab5a000}, {0x3ab5c000}, {0x3ab5e000}, + {0x3ab60000}, {0x3ab62000}, {0x3ab64000}, {0x3ab66000}, + {0x3ab68000}, {0x3ab6a000}, {0x3ab6c000}, {0x3ab6e000}, + {0x3ab70000}, {0x3ab72000}, {0x3ab74000}, {0x3ab76000}, + {0x3ab78000}, {0x3ab7a000}, {0x3ab7c000}, {0x3ab7e000}, + {0x3ab80000}, {0x3ab82000}, {0x3ab84000}, {0x3ab86000}, + {0x3ab88000}, {0x3ab8a000}, {0x3ab8c000}, {0x3ab8e000}, + {0x3ab90000}, {0x3ab92000}, {0x3ab94000}, {0x3ab96000}, + {0x3ab98000}, {0x3ab9a000}, {0x3ab9c000}, {0x3ab9e000}, + {0x3aba0000}, {0x3aba2000}, {0x3aba4000}, {0x3aba6000}, + {0x3aba8000}, {0x3abaa000}, {0x3abac000}, {0x3abae000}, + {0x3abb0000}, {0x3abb2000}, {0x3abb4000}, {0x3abb6000}, + {0x3abb8000}, {0x3abba000}, {0x3abbc000}, {0x3abbe000}, + {0x3abc0000}, {0x3abc2000}, {0x3abc4000}, {0x3abc6000}, + {0x3abc8000}, {0x3abca000}, {0x3abcc000}, {0x3abce000}, + {0x3abd0000}, {0x3abd2000}, {0x3abd4000}, {0x3abd6000}, + {0x3abd8000}, {0x3abda000}, {0x3abdc000}, {0x3abde000}, + {0x3abe0000}, {0x3abe2000}, {0x3abe4000}, {0x3abe6000}, + {0x3abe8000}, {0x3abea000}, {0x3abec000}, {0x3abee000}, + {0x3abf0000}, {0x3abf2000}, {0x3abf4000}, {0x3abf6000}, + {0x3abf8000}, {0x3abfa000}, {0x3abfc000}, {0x3abfe000}, + {0x3ac00000}, {0x3ac02000}, {0x3ac04000}, {0x3ac06000}, + {0x3ac08000}, {0x3ac0a000}, {0x3ac0c000}, {0x3ac0e000}, + {0x3ac10000}, {0x3ac12000}, {0x3ac14000}, {0x3ac16000}, + {0x3ac18000}, {0x3ac1a000}, {0x3ac1c000}, {0x3ac1e000}, + {0x3ac20000}, {0x3ac22000}, {0x3ac24000}, {0x3ac26000}, + {0x3ac28000}, {0x3ac2a000}, {0x3ac2c000}, {0x3ac2e000}, + {0x3ac30000}, {0x3ac32000}, {0x3ac34000}, {0x3ac36000}, + {0x3ac38000}, {0x3ac3a000}, {0x3ac3c000}, {0x3ac3e000}, + {0x3ac40000}, {0x3ac42000}, {0x3ac44000}, {0x3ac46000}, + {0x3ac48000}, {0x3ac4a000}, {0x3ac4c000}, {0x3ac4e000}, + {0x3ac50000}, {0x3ac52000}, {0x3ac54000}, {0x3ac56000}, + {0x3ac58000}, {0x3ac5a000}, {0x3ac5c000}, {0x3ac5e000}, + {0x3ac60000}, {0x3ac62000}, {0x3ac64000}, {0x3ac66000}, + {0x3ac68000}, {0x3ac6a000}, {0x3ac6c000}, {0x3ac6e000}, + {0x3ac70000}, {0x3ac72000}, {0x3ac74000}, {0x3ac76000}, + {0x3ac78000}, {0x3ac7a000}, {0x3ac7c000}, {0x3ac7e000}, + {0x3ac80000}, {0x3ac82000}, {0x3ac84000}, {0x3ac86000}, + {0x3ac88000}, {0x3ac8a000}, {0x3ac8c000}, {0x3ac8e000}, + {0x3ac90000}, {0x3ac92000}, {0x3ac94000}, {0x3ac96000}, + {0x3ac98000}, {0x3ac9a000}, {0x3ac9c000}, {0x3ac9e000}, + {0x3aca0000}, {0x3aca2000}, {0x3aca4000}, {0x3aca6000}, + {0x3aca8000}, {0x3acaa000}, {0x3acac000}, {0x3acae000}, + {0x3acb0000}, {0x3acb2000}, {0x3acb4000}, {0x3acb6000}, + {0x3acb8000}, {0x3acba000}, {0x3acbc000}, {0x3acbe000}, + {0x3acc0000}, {0x3acc2000}, {0x3acc4000}, {0x3acc6000}, + {0x3acc8000}, {0x3acca000}, {0x3accc000}, {0x3acce000}, + {0x3acd0000}, {0x3acd2000}, {0x3acd4000}, {0x3acd6000}, + {0x3acd8000}, {0x3acda000}, {0x3acdc000}, {0x3acde000}, + {0x3ace0000}, {0x3ace2000}, {0x3ace4000}, {0x3ace6000}, + {0x3ace8000}, {0x3acea000}, {0x3acec000}, {0x3acee000}, + {0x3acf0000}, {0x3acf2000}, {0x3acf4000}, {0x3acf6000}, + {0x3acf8000}, {0x3acfa000}, {0x3acfc000}, {0x3acfe000}, + {0x3ad00000}, {0x3ad02000}, {0x3ad04000}, {0x3ad06000}, + {0x3ad08000}, {0x3ad0a000}, {0x3ad0c000}, {0x3ad0e000}, + {0x3ad10000}, {0x3ad12000}, {0x3ad14000}, {0x3ad16000}, + {0x3ad18000}, {0x3ad1a000}, {0x3ad1c000}, {0x3ad1e000}, + {0x3ad20000}, {0x3ad22000}, {0x3ad24000}, {0x3ad26000}, + {0x3ad28000}, {0x3ad2a000}, {0x3ad2c000}, {0x3ad2e000}, + {0x3ad30000}, {0x3ad32000}, {0x3ad34000}, {0x3ad36000}, + {0x3ad38000}, {0x3ad3a000}, {0x3ad3c000}, {0x3ad3e000}, + {0x3ad40000}, {0x3ad42000}, {0x3ad44000}, {0x3ad46000}, + {0x3ad48000}, {0x3ad4a000}, {0x3ad4c000}, {0x3ad4e000}, + {0x3ad50000}, {0x3ad52000}, {0x3ad54000}, {0x3ad56000}, + {0x3ad58000}, {0x3ad5a000}, {0x3ad5c000}, {0x3ad5e000}, + {0x3ad60000}, {0x3ad62000}, {0x3ad64000}, {0x3ad66000}, + {0x3ad68000}, {0x3ad6a000}, {0x3ad6c000}, {0x3ad6e000}, + {0x3ad70000}, {0x3ad72000}, {0x3ad74000}, {0x3ad76000}, + {0x3ad78000}, {0x3ad7a000}, {0x3ad7c000}, {0x3ad7e000}, + {0x3ad80000}, {0x3ad82000}, {0x3ad84000}, {0x3ad86000}, + {0x3ad88000}, {0x3ad8a000}, {0x3ad8c000}, {0x3ad8e000}, + {0x3ad90000}, {0x3ad92000}, {0x3ad94000}, {0x3ad96000}, + {0x3ad98000}, {0x3ad9a000}, {0x3ad9c000}, {0x3ad9e000}, + {0x3ada0000}, {0x3ada2000}, {0x3ada4000}, {0x3ada6000}, + {0x3ada8000}, {0x3adaa000}, {0x3adac000}, {0x3adae000}, + {0x3adb0000}, {0x3adb2000}, {0x3adb4000}, {0x3adb6000}, + {0x3adb8000}, {0x3adba000}, {0x3adbc000}, {0x3adbe000}, + {0x3adc0000}, {0x3adc2000}, {0x3adc4000}, {0x3adc6000}, + {0x3adc8000}, {0x3adca000}, {0x3adcc000}, {0x3adce000}, + {0x3add0000}, {0x3add2000}, {0x3add4000}, {0x3add6000}, + {0x3add8000}, {0x3adda000}, {0x3addc000}, {0x3adde000}, + {0x3ade0000}, {0x3ade2000}, {0x3ade4000}, {0x3ade6000}, + {0x3ade8000}, {0x3adea000}, {0x3adec000}, {0x3adee000}, + {0x3adf0000}, {0x3adf2000}, {0x3adf4000}, {0x3adf6000}, + {0x3adf8000}, {0x3adfa000}, {0x3adfc000}, {0x3adfe000}, + {0x3ae00000}, {0x3ae02000}, {0x3ae04000}, {0x3ae06000}, + {0x3ae08000}, {0x3ae0a000}, {0x3ae0c000}, {0x3ae0e000}, + {0x3ae10000}, {0x3ae12000}, {0x3ae14000}, {0x3ae16000}, + {0x3ae18000}, {0x3ae1a000}, {0x3ae1c000}, {0x3ae1e000}, + {0x3ae20000}, {0x3ae22000}, {0x3ae24000}, {0x3ae26000}, + {0x3ae28000}, {0x3ae2a000}, {0x3ae2c000}, {0x3ae2e000}, + {0x3ae30000}, {0x3ae32000}, {0x3ae34000}, {0x3ae36000}, + {0x3ae38000}, {0x3ae3a000}, {0x3ae3c000}, {0x3ae3e000}, + {0x3ae40000}, {0x3ae42000}, {0x3ae44000}, {0x3ae46000}, + {0x3ae48000}, {0x3ae4a000}, {0x3ae4c000}, {0x3ae4e000}, + {0x3ae50000}, {0x3ae52000}, {0x3ae54000}, {0x3ae56000}, + {0x3ae58000}, {0x3ae5a000}, {0x3ae5c000}, {0x3ae5e000}, + {0x3ae60000}, {0x3ae62000}, {0x3ae64000}, {0x3ae66000}, + {0x3ae68000}, {0x3ae6a000}, {0x3ae6c000}, {0x3ae6e000}, + {0x3ae70000}, {0x3ae72000}, {0x3ae74000}, {0x3ae76000}, + {0x3ae78000}, {0x3ae7a000}, {0x3ae7c000}, {0x3ae7e000}, + {0x3ae80000}, {0x3ae82000}, {0x3ae84000}, {0x3ae86000}, + {0x3ae88000}, {0x3ae8a000}, {0x3ae8c000}, {0x3ae8e000}, + {0x3ae90000}, {0x3ae92000}, {0x3ae94000}, {0x3ae96000}, + {0x3ae98000}, {0x3ae9a000}, {0x3ae9c000}, {0x3ae9e000}, + {0x3aea0000}, {0x3aea2000}, {0x3aea4000}, {0x3aea6000}, + {0x3aea8000}, {0x3aeaa000}, {0x3aeac000}, {0x3aeae000}, + {0x3aeb0000}, {0x3aeb2000}, {0x3aeb4000}, {0x3aeb6000}, + {0x3aeb8000}, {0x3aeba000}, {0x3aebc000}, {0x3aebe000}, + {0x3aec0000}, {0x3aec2000}, {0x3aec4000}, {0x3aec6000}, + {0x3aec8000}, {0x3aeca000}, {0x3aecc000}, {0x3aece000}, + {0x3aed0000}, {0x3aed2000}, {0x3aed4000}, {0x3aed6000}, + {0x3aed8000}, {0x3aeda000}, {0x3aedc000}, {0x3aede000}, + {0x3aee0000}, {0x3aee2000}, {0x3aee4000}, {0x3aee6000}, + {0x3aee8000}, {0x3aeea000}, {0x3aeec000}, {0x3aeee000}, + {0x3aef0000}, {0x3aef2000}, {0x3aef4000}, {0x3aef6000}, + {0x3aef8000}, {0x3aefa000}, {0x3aefc000}, {0x3aefe000}, + {0x3af00000}, {0x3af02000}, {0x3af04000}, {0x3af06000}, + {0x3af08000}, {0x3af0a000}, {0x3af0c000}, {0x3af0e000}, + {0x3af10000}, {0x3af12000}, {0x3af14000}, {0x3af16000}, + {0x3af18000}, {0x3af1a000}, {0x3af1c000}, {0x3af1e000}, + {0x3af20000}, {0x3af22000}, {0x3af24000}, {0x3af26000}, + {0x3af28000}, {0x3af2a000}, {0x3af2c000}, {0x3af2e000}, + {0x3af30000}, {0x3af32000}, {0x3af34000}, {0x3af36000}, + {0x3af38000}, {0x3af3a000}, {0x3af3c000}, {0x3af3e000}, + {0x3af40000}, {0x3af42000}, {0x3af44000}, {0x3af46000}, + {0x3af48000}, {0x3af4a000}, {0x3af4c000}, {0x3af4e000}, + {0x3af50000}, {0x3af52000}, {0x3af54000}, {0x3af56000}, + {0x3af58000}, {0x3af5a000}, {0x3af5c000}, {0x3af5e000}, + {0x3af60000}, {0x3af62000}, {0x3af64000}, {0x3af66000}, + {0x3af68000}, {0x3af6a000}, {0x3af6c000}, {0x3af6e000}, + {0x3af70000}, {0x3af72000}, {0x3af74000}, {0x3af76000}, + {0x3af78000}, {0x3af7a000}, {0x3af7c000}, {0x3af7e000}, + {0x3af80000}, {0x3af82000}, {0x3af84000}, {0x3af86000}, + {0x3af88000}, {0x3af8a000}, {0x3af8c000}, {0x3af8e000}, + {0x3af90000}, {0x3af92000}, {0x3af94000}, {0x3af96000}, + {0x3af98000}, {0x3af9a000}, {0x3af9c000}, {0x3af9e000}, + {0x3afa0000}, {0x3afa2000}, {0x3afa4000}, {0x3afa6000}, + {0x3afa8000}, {0x3afaa000}, {0x3afac000}, {0x3afae000}, + {0x3afb0000}, {0x3afb2000}, {0x3afb4000}, {0x3afb6000}, + {0x3afb8000}, {0x3afba000}, {0x3afbc000}, {0x3afbe000}, + {0x3afc0000}, {0x3afc2000}, {0x3afc4000}, {0x3afc6000}, + {0x3afc8000}, {0x3afca000}, {0x3afcc000}, {0x3afce000}, + {0x3afd0000}, {0x3afd2000}, {0x3afd4000}, {0x3afd6000}, + {0x3afd8000}, {0x3afda000}, {0x3afdc000}, {0x3afde000}, + {0x3afe0000}, {0x3afe2000}, {0x3afe4000}, {0x3afe6000}, + {0x3afe8000}, {0x3afea000}, {0x3afec000}, {0x3afee000}, + {0x3aff0000}, {0x3aff2000}, {0x3aff4000}, {0x3aff6000}, + {0x3aff8000}, {0x3affa000}, {0x3affc000}, {0x3affe000}, + {0x3b000000}, {0x3b002000}, {0x3b004000}, {0x3b006000}, + {0x3b008000}, {0x3b00a000}, {0x3b00c000}, {0x3b00e000}, + {0x3b010000}, {0x3b012000}, {0x3b014000}, {0x3b016000}, + {0x3b018000}, {0x3b01a000}, {0x3b01c000}, {0x3b01e000}, + {0x3b020000}, {0x3b022000}, {0x3b024000}, {0x3b026000}, + {0x3b028000}, {0x3b02a000}, {0x3b02c000}, {0x3b02e000}, + {0x3b030000}, {0x3b032000}, {0x3b034000}, {0x3b036000}, + {0x3b038000}, {0x3b03a000}, {0x3b03c000}, {0x3b03e000}, + {0x3b040000}, {0x3b042000}, {0x3b044000}, {0x3b046000}, + {0x3b048000}, {0x3b04a000}, {0x3b04c000}, {0x3b04e000}, + {0x3b050000}, {0x3b052000}, {0x3b054000}, {0x3b056000}, + {0x3b058000}, {0x3b05a000}, {0x3b05c000}, {0x3b05e000}, + {0x3b060000}, {0x3b062000}, {0x3b064000}, {0x3b066000}, + {0x3b068000}, {0x3b06a000}, {0x3b06c000}, {0x3b06e000}, + {0x3b070000}, {0x3b072000}, {0x3b074000}, {0x3b076000}, + {0x3b078000}, {0x3b07a000}, {0x3b07c000}, {0x3b07e000}, + {0x3b080000}, {0x3b082000}, {0x3b084000}, {0x3b086000}, + {0x3b088000}, {0x3b08a000}, {0x3b08c000}, {0x3b08e000}, + {0x3b090000}, {0x3b092000}, {0x3b094000}, {0x3b096000}, + {0x3b098000}, {0x3b09a000}, {0x3b09c000}, {0x3b09e000}, + {0x3b0a0000}, {0x3b0a2000}, {0x3b0a4000}, {0x3b0a6000}, + {0x3b0a8000}, {0x3b0aa000}, {0x3b0ac000}, {0x3b0ae000}, + {0x3b0b0000}, {0x3b0b2000}, {0x3b0b4000}, {0x3b0b6000}, + {0x3b0b8000}, {0x3b0ba000}, {0x3b0bc000}, {0x3b0be000}, + {0x3b0c0000}, {0x3b0c2000}, {0x3b0c4000}, {0x3b0c6000}, + {0x3b0c8000}, {0x3b0ca000}, {0x3b0cc000}, {0x3b0ce000}, + {0x3b0d0000}, {0x3b0d2000}, {0x3b0d4000}, {0x3b0d6000}, + {0x3b0d8000}, {0x3b0da000}, {0x3b0dc000}, {0x3b0de000}, + {0x3b0e0000}, {0x3b0e2000}, {0x3b0e4000}, {0x3b0e6000}, + {0x3b0e8000}, {0x3b0ea000}, {0x3b0ec000}, {0x3b0ee000}, + {0x3b0f0000}, {0x3b0f2000}, {0x3b0f4000}, {0x3b0f6000}, + {0x3b0f8000}, {0x3b0fa000}, {0x3b0fc000}, {0x3b0fe000}, + {0x3b100000}, {0x3b102000}, {0x3b104000}, {0x3b106000}, + {0x3b108000}, {0x3b10a000}, {0x3b10c000}, {0x3b10e000}, + {0x3b110000}, {0x3b112000}, {0x3b114000}, {0x3b116000}, + {0x3b118000}, {0x3b11a000}, {0x3b11c000}, {0x3b11e000}, + {0x3b120000}, {0x3b122000}, {0x3b124000}, {0x3b126000}, + {0x3b128000}, {0x3b12a000}, {0x3b12c000}, {0x3b12e000}, + {0x3b130000}, {0x3b132000}, {0x3b134000}, {0x3b136000}, + {0x3b138000}, {0x3b13a000}, {0x3b13c000}, {0x3b13e000}, + {0x3b140000}, {0x3b142000}, {0x3b144000}, {0x3b146000}, + {0x3b148000}, {0x3b14a000}, {0x3b14c000}, {0x3b14e000}, + {0x3b150000}, {0x3b152000}, {0x3b154000}, {0x3b156000}, + {0x3b158000}, {0x3b15a000}, {0x3b15c000}, {0x3b15e000}, + {0x3b160000}, {0x3b162000}, {0x3b164000}, {0x3b166000}, + {0x3b168000}, {0x3b16a000}, {0x3b16c000}, {0x3b16e000}, + {0x3b170000}, {0x3b172000}, {0x3b174000}, {0x3b176000}, + {0x3b178000}, {0x3b17a000}, {0x3b17c000}, {0x3b17e000}, + {0x3b180000}, {0x3b182000}, {0x3b184000}, {0x3b186000}, + {0x3b188000}, {0x3b18a000}, {0x3b18c000}, {0x3b18e000}, + {0x3b190000}, {0x3b192000}, {0x3b194000}, {0x3b196000}, + {0x3b198000}, {0x3b19a000}, {0x3b19c000}, {0x3b19e000}, + {0x3b1a0000}, {0x3b1a2000}, {0x3b1a4000}, {0x3b1a6000}, + {0x3b1a8000}, {0x3b1aa000}, {0x3b1ac000}, {0x3b1ae000}, + {0x3b1b0000}, {0x3b1b2000}, {0x3b1b4000}, {0x3b1b6000}, + {0x3b1b8000}, {0x3b1ba000}, {0x3b1bc000}, {0x3b1be000}, + {0x3b1c0000}, {0x3b1c2000}, {0x3b1c4000}, {0x3b1c6000}, + {0x3b1c8000}, {0x3b1ca000}, {0x3b1cc000}, {0x3b1ce000}, + {0x3b1d0000}, {0x3b1d2000}, {0x3b1d4000}, {0x3b1d6000}, + {0x3b1d8000}, {0x3b1da000}, {0x3b1dc000}, {0x3b1de000}, + {0x3b1e0000}, {0x3b1e2000}, {0x3b1e4000}, {0x3b1e6000}, + {0x3b1e8000}, {0x3b1ea000}, {0x3b1ec000}, {0x3b1ee000}, + {0x3b1f0000}, {0x3b1f2000}, {0x3b1f4000}, {0x3b1f6000}, + {0x3b1f8000}, {0x3b1fa000}, {0x3b1fc000}, {0x3b1fe000}, + {0x3b200000}, {0x3b202000}, {0x3b204000}, {0x3b206000}, + {0x3b208000}, {0x3b20a000}, {0x3b20c000}, {0x3b20e000}, + {0x3b210000}, {0x3b212000}, {0x3b214000}, {0x3b216000}, + {0x3b218000}, {0x3b21a000}, {0x3b21c000}, {0x3b21e000}, + {0x3b220000}, {0x3b222000}, {0x3b224000}, {0x3b226000}, + {0x3b228000}, {0x3b22a000}, {0x3b22c000}, {0x3b22e000}, + {0x3b230000}, {0x3b232000}, {0x3b234000}, {0x3b236000}, + {0x3b238000}, {0x3b23a000}, {0x3b23c000}, {0x3b23e000}, + {0x3b240000}, {0x3b242000}, {0x3b244000}, {0x3b246000}, + {0x3b248000}, {0x3b24a000}, {0x3b24c000}, {0x3b24e000}, + {0x3b250000}, {0x3b252000}, {0x3b254000}, {0x3b256000}, + {0x3b258000}, {0x3b25a000}, {0x3b25c000}, {0x3b25e000}, + {0x3b260000}, {0x3b262000}, {0x3b264000}, {0x3b266000}, + {0x3b268000}, {0x3b26a000}, {0x3b26c000}, {0x3b26e000}, + {0x3b270000}, {0x3b272000}, {0x3b274000}, {0x3b276000}, + {0x3b278000}, {0x3b27a000}, {0x3b27c000}, {0x3b27e000}, + {0x3b280000}, {0x3b282000}, {0x3b284000}, {0x3b286000}, + {0x3b288000}, {0x3b28a000}, {0x3b28c000}, {0x3b28e000}, + {0x3b290000}, {0x3b292000}, {0x3b294000}, {0x3b296000}, + {0x3b298000}, {0x3b29a000}, {0x3b29c000}, {0x3b29e000}, + {0x3b2a0000}, {0x3b2a2000}, {0x3b2a4000}, {0x3b2a6000}, + {0x3b2a8000}, {0x3b2aa000}, {0x3b2ac000}, {0x3b2ae000}, + {0x3b2b0000}, {0x3b2b2000}, {0x3b2b4000}, {0x3b2b6000}, + {0x3b2b8000}, {0x3b2ba000}, {0x3b2bc000}, {0x3b2be000}, + {0x3b2c0000}, {0x3b2c2000}, {0x3b2c4000}, {0x3b2c6000}, + {0x3b2c8000}, {0x3b2ca000}, {0x3b2cc000}, {0x3b2ce000}, + {0x3b2d0000}, {0x3b2d2000}, {0x3b2d4000}, {0x3b2d6000}, + {0x3b2d8000}, {0x3b2da000}, {0x3b2dc000}, {0x3b2de000}, + {0x3b2e0000}, {0x3b2e2000}, {0x3b2e4000}, {0x3b2e6000}, + {0x3b2e8000}, {0x3b2ea000}, {0x3b2ec000}, {0x3b2ee000}, + {0x3b2f0000}, {0x3b2f2000}, {0x3b2f4000}, {0x3b2f6000}, + {0x3b2f8000}, {0x3b2fa000}, {0x3b2fc000}, {0x3b2fe000}, + {0x3b300000}, {0x3b302000}, {0x3b304000}, {0x3b306000}, + {0x3b308000}, {0x3b30a000}, {0x3b30c000}, {0x3b30e000}, + {0x3b310000}, {0x3b312000}, {0x3b314000}, {0x3b316000}, + {0x3b318000}, {0x3b31a000}, {0x3b31c000}, {0x3b31e000}, + {0x3b320000}, {0x3b322000}, {0x3b324000}, {0x3b326000}, + {0x3b328000}, {0x3b32a000}, {0x3b32c000}, {0x3b32e000}, + {0x3b330000}, {0x3b332000}, {0x3b334000}, {0x3b336000}, + {0x3b338000}, {0x3b33a000}, {0x3b33c000}, {0x3b33e000}, + {0x3b340000}, {0x3b342000}, {0x3b344000}, {0x3b346000}, + {0x3b348000}, {0x3b34a000}, {0x3b34c000}, {0x3b34e000}, + {0x3b350000}, {0x3b352000}, {0x3b354000}, {0x3b356000}, + {0x3b358000}, {0x3b35a000}, {0x3b35c000}, {0x3b35e000}, + {0x3b360000}, {0x3b362000}, {0x3b364000}, {0x3b366000}, + {0x3b368000}, {0x3b36a000}, {0x3b36c000}, {0x3b36e000}, + {0x3b370000}, {0x3b372000}, {0x3b374000}, {0x3b376000}, + {0x3b378000}, {0x3b37a000}, {0x3b37c000}, {0x3b37e000}, + {0x3b380000}, {0x3b382000}, {0x3b384000}, {0x3b386000}, + {0x3b388000}, {0x3b38a000}, {0x3b38c000}, {0x3b38e000}, + {0x3b390000}, {0x3b392000}, {0x3b394000}, {0x3b396000}, + {0x3b398000}, {0x3b39a000}, {0x3b39c000}, {0x3b39e000}, + {0x3b3a0000}, {0x3b3a2000}, {0x3b3a4000}, {0x3b3a6000}, + {0x3b3a8000}, {0x3b3aa000}, {0x3b3ac000}, {0x3b3ae000}, + {0x3b3b0000}, {0x3b3b2000}, {0x3b3b4000}, {0x3b3b6000}, + {0x3b3b8000}, {0x3b3ba000}, {0x3b3bc000}, {0x3b3be000}, + {0x3b3c0000}, {0x3b3c2000}, {0x3b3c4000}, {0x3b3c6000}, + {0x3b3c8000}, {0x3b3ca000}, {0x3b3cc000}, {0x3b3ce000}, + {0x3b3d0000}, {0x3b3d2000}, {0x3b3d4000}, {0x3b3d6000}, + {0x3b3d8000}, {0x3b3da000}, {0x3b3dc000}, {0x3b3de000}, + {0x3b3e0000}, {0x3b3e2000}, {0x3b3e4000}, {0x3b3e6000}, + {0x3b3e8000}, {0x3b3ea000}, {0x3b3ec000}, {0x3b3ee000}, + {0x3b3f0000}, {0x3b3f2000}, {0x3b3f4000}, {0x3b3f6000}, + {0x3b3f8000}, {0x3b3fa000}, {0x3b3fc000}, {0x3b3fe000}, + {0x3b400000}, {0x3b402000}, {0x3b404000}, {0x3b406000}, + {0x3b408000}, {0x3b40a000}, {0x3b40c000}, {0x3b40e000}, + {0x3b410000}, {0x3b412000}, {0x3b414000}, {0x3b416000}, + {0x3b418000}, {0x3b41a000}, {0x3b41c000}, {0x3b41e000}, + {0x3b420000}, {0x3b422000}, {0x3b424000}, {0x3b426000}, + {0x3b428000}, {0x3b42a000}, {0x3b42c000}, {0x3b42e000}, + {0x3b430000}, {0x3b432000}, {0x3b434000}, {0x3b436000}, + {0x3b438000}, {0x3b43a000}, {0x3b43c000}, {0x3b43e000}, + {0x3b440000}, {0x3b442000}, {0x3b444000}, {0x3b446000}, + {0x3b448000}, {0x3b44a000}, {0x3b44c000}, {0x3b44e000}, + {0x3b450000}, {0x3b452000}, {0x3b454000}, {0x3b456000}, + {0x3b458000}, {0x3b45a000}, {0x3b45c000}, {0x3b45e000}, + {0x3b460000}, {0x3b462000}, {0x3b464000}, {0x3b466000}, + {0x3b468000}, {0x3b46a000}, {0x3b46c000}, {0x3b46e000}, + {0x3b470000}, {0x3b472000}, {0x3b474000}, {0x3b476000}, + {0x3b478000}, {0x3b47a000}, {0x3b47c000}, {0x3b47e000}, + {0x3b480000}, {0x3b482000}, {0x3b484000}, {0x3b486000}, + {0x3b488000}, {0x3b48a000}, {0x3b48c000}, {0x3b48e000}, + {0x3b490000}, {0x3b492000}, {0x3b494000}, {0x3b496000}, + {0x3b498000}, {0x3b49a000}, {0x3b49c000}, {0x3b49e000}, + {0x3b4a0000}, {0x3b4a2000}, {0x3b4a4000}, {0x3b4a6000}, + {0x3b4a8000}, {0x3b4aa000}, {0x3b4ac000}, {0x3b4ae000}, + {0x3b4b0000}, {0x3b4b2000}, {0x3b4b4000}, {0x3b4b6000}, + {0x3b4b8000}, {0x3b4ba000}, {0x3b4bc000}, {0x3b4be000}, + {0x3b4c0000}, {0x3b4c2000}, {0x3b4c4000}, {0x3b4c6000}, + {0x3b4c8000}, {0x3b4ca000}, {0x3b4cc000}, {0x3b4ce000}, + {0x3b4d0000}, {0x3b4d2000}, {0x3b4d4000}, {0x3b4d6000}, + {0x3b4d8000}, {0x3b4da000}, {0x3b4dc000}, {0x3b4de000}, + {0x3b4e0000}, {0x3b4e2000}, {0x3b4e4000}, {0x3b4e6000}, + {0x3b4e8000}, {0x3b4ea000}, {0x3b4ec000}, {0x3b4ee000}, + {0x3b4f0000}, {0x3b4f2000}, {0x3b4f4000}, {0x3b4f6000}, + {0x3b4f8000}, {0x3b4fa000}, {0x3b4fc000}, {0x3b4fe000}, + {0x3b500000}, {0x3b502000}, {0x3b504000}, {0x3b506000}, + {0x3b508000}, {0x3b50a000}, {0x3b50c000}, {0x3b50e000}, + {0x3b510000}, {0x3b512000}, {0x3b514000}, {0x3b516000}, + {0x3b518000}, {0x3b51a000}, {0x3b51c000}, {0x3b51e000}, + {0x3b520000}, {0x3b522000}, {0x3b524000}, {0x3b526000}, + {0x3b528000}, {0x3b52a000}, {0x3b52c000}, {0x3b52e000}, + {0x3b530000}, {0x3b532000}, {0x3b534000}, {0x3b536000}, + {0x3b538000}, {0x3b53a000}, {0x3b53c000}, {0x3b53e000}, + {0x3b540000}, {0x3b542000}, {0x3b544000}, {0x3b546000}, + {0x3b548000}, {0x3b54a000}, {0x3b54c000}, {0x3b54e000}, + {0x3b550000}, {0x3b552000}, {0x3b554000}, {0x3b556000}, + {0x3b558000}, {0x3b55a000}, {0x3b55c000}, {0x3b55e000}, + {0x3b560000}, {0x3b562000}, {0x3b564000}, {0x3b566000}, + {0x3b568000}, {0x3b56a000}, {0x3b56c000}, {0x3b56e000}, + {0x3b570000}, {0x3b572000}, {0x3b574000}, {0x3b576000}, + {0x3b578000}, {0x3b57a000}, {0x3b57c000}, {0x3b57e000}, + {0x3b580000}, {0x3b582000}, {0x3b584000}, {0x3b586000}, + {0x3b588000}, {0x3b58a000}, {0x3b58c000}, {0x3b58e000}, + {0x3b590000}, {0x3b592000}, {0x3b594000}, {0x3b596000}, + {0x3b598000}, {0x3b59a000}, {0x3b59c000}, {0x3b59e000}, + {0x3b5a0000}, {0x3b5a2000}, {0x3b5a4000}, {0x3b5a6000}, + {0x3b5a8000}, {0x3b5aa000}, {0x3b5ac000}, {0x3b5ae000}, + {0x3b5b0000}, {0x3b5b2000}, {0x3b5b4000}, {0x3b5b6000}, + {0x3b5b8000}, {0x3b5ba000}, {0x3b5bc000}, {0x3b5be000}, + {0x3b5c0000}, {0x3b5c2000}, {0x3b5c4000}, {0x3b5c6000}, + {0x3b5c8000}, {0x3b5ca000}, {0x3b5cc000}, {0x3b5ce000}, + {0x3b5d0000}, {0x3b5d2000}, {0x3b5d4000}, {0x3b5d6000}, + {0x3b5d8000}, {0x3b5da000}, {0x3b5dc000}, {0x3b5de000}, + {0x3b5e0000}, {0x3b5e2000}, {0x3b5e4000}, {0x3b5e6000}, + {0x3b5e8000}, {0x3b5ea000}, {0x3b5ec000}, {0x3b5ee000}, + {0x3b5f0000}, {0x3b5f2000}, {0x3b5f4000}, {0x3b5f6000}, + {0x3b5f8000}, {0x3b5fa000}, {0x3b5fc000}, {0x3b5fe000}, + {0x3b600000}, {0x3b602000}, {0x3b604000}, {0x3b606000}, + {0x3b608000}, {0x3b60a000}, {0x3b60c000}, {0x3b60e000}, + {0x3b610000}, {0x3b612000}, {0x3b614000}, {0x3b616000}, + {0x3b618000}, {0x3b61a000}, {0x3b61c000}, {0x3b61e000}, + {0x3b620000}, {0x3b622000}, {0x3b624000}, {0x3b626000}, + {0x3b628000}, {0x3b62a000}, {0x3b62c000}, {0x3b62e000}, + {0x3b630000}, {0x3b632000}, {0x3b634000}, {0x3b636000}, + {0x3b638000}, {0x3b63a000}, {0x3b63c000}, {0x3b63e000}, + {0x3b640000}, {0x3b642000}, {0x3b644000}, {0x3b646000}, + {0x3b648000}, {0x3b64a000}, {0x3b64c000}, {0x3b64e000}, + {0x3b650000}, {0x3b652000}, {0x3b654000}, {0x3b656000}, + {0x3b658000}, {0x3b65a000}, {0x3b65c000}, {0x3b65e000}, + {0x3b660000}, {0x3b662000}, {0x3b664000}, {0x3b666000}, + {0x3b668000}, {0x3b66a000}, {0x3b66c000}, {0x3b66e000}, + {0x3b670000}, {0x3b672000}, {0x3b674000}, {0x3b676000}, + {0x3b678000}, {0x3b67a000}, {0x3b67c000}, {0x3b67e000}, + {0x3b680000}, {0x3b682000}, {0x3b684000}, {0x3b686000}, + {0x3b688000}, {0x3b68a000}, {0x3b68c000}, {0x3b68e000}, + {0x3b690000}, {0x3b692000}, {0x3b694000}, {0x3b696000}, + {0x3b698000}, {0x3b69a000}, {0x3b69c000}, {0x3b69e000}, + {0x3b6a0000}, {0x3b6a2000}, {0x3b6a4000}, {0x3b6a6000}, + {0x3b6a8000}, {0x3b6aa000}, {0x3b6ac000}, {0x3b6ae000}, + {0x3b6b0000}, {0x3b6b2000}, {0x3b6b4000}, {0x3b6b6000}, + {0x3b6b8000}, {0x3b6ba000}, {0x3b6bc000}, {0x3b6be000}, + {0x3b6c0000}, {0x3b6c2000}, {0x3b6c4000}, {0x3b6c6000}, + {0x3b6c8000}, {0x3b6ca000}, {0x3b6cc000}, {0x3b6ce000}, + {0x3b6d0000}, {0x3b6d2000}, {0x3b6d4000}, {0x3b6d6000}, + {0x3b6d8000}, {0x3b6da000}, {0x3b6dc000}, {0x3b6de000}, + {0x3b6e0000}, {0x3b6e2000}, {0x3b6e4000}, {0x3b6e6000}, + {0x3b6e8000}, {0x3b6ea000}, {0x3b6ec000}, {0x3b6ee000}, + {0x3b6f0000}, {0x3b6f2000}, {0x3b6f4000}, {0x3b6f6000}, + {0x3b6f8000}, {0x3b6fa000}, {0x3b6fc000}, {0x3b6fe000}, + {0x3b700000}, {0x3b702000}, {0x3b704000}, {0x3b706000}, + {0x3b708000}, {0x3b70a000}, {0x3b70c000}, {0x3b70e000}, + {0x3b710000}, {0x3b712000}, {0x3b714000}, {0x3b716000}, + {0x3b718000}, {0x3b71a000}, {0x3b71c000}, {0x3b71e000}, + {0x3b720000}, {0x3b722000}, {0x3b724000}, {0x3b726000}, + {0x3b728000}, {0x3b72a000}, {0x3b72c000}, {0x3b72e000}, + {0x3b730000}, {0x3b732000}, {0x3b734000}, {0x3b736000}, + {0x3b738000}, {0x3b73a000}, {0x3b73c000}, {0x3b73e000}, + {0x3b740000}, {0x3b742000}, {0x3b744000}, {0x3b746000}, + {0x3b748000}, {0x3b74a000}, {0x3b74c000}, {0x3b74e000}, + {0x3b750000}, {0x3b752000}, {0x3b754000}, {0x3b756000}, + {0x3b758000}, {0x3b75a000}, {0x3b75c000}, {0x3b75e000}, + {0x3b760000}, {0x3b762000}, {0x3b764000}, {0x3b766000}, + {0x3b768000}, {0x3b76a000}, {0x3b76c000}, {0x3b76e000}, + {0x3b770000}, {0x3b772000}, {0x3b774000}, {0x3b776000}, + {0x3b778000}, {0x3b77a000}, {0x3b77c000}, {0x3b77e000}, + {0x3b780000}, {0x3b782000}, {0x3b784000}, {0x3b786000}, + {0x3b788000}, {0x3b78a000}, {0x3b78c000}, {0x3b78e000}, + {0x3b790000}, {0x3b792000}, {0x3b794000}, {0x3b796000}, + {0x3b798000}, {0x3b79a000}, {0x3b79c000}, {0x3b79e000}, + {0x3b7a0000}, {0x3b7a2000}, {0x3b7a4000}, {0x3b7a6000}, + {0x3b7a8000}, {0x3b7aa000}, {0x3b7ac000}, {0x3b7ae000}, + {0x3b7b0000}, {0x3b7b2000}, {0x3b7b4000}, {0x3b7b6000}, + {0x3b7b8000}, {0x3b7ba000}, {0x3b7bc000}, {0x3b7be000}, + {0x3b7c0000}, {0x3b7c2000}, {0x3b7c4000}, {0x3b7c6000}, + {0x3b7c8000}, {0x3b7ca000}, {0x3b7cc000}, {0x3b7ce000}, + {0x3b7d0000}, {0x3b7d2000}, {0x3b7d4000}, {0x3b7d6000}, + {0x3b7d8000}, {0x3b7da000}, {0x3b7dc000}, {0x3b7de000}, + {0x3b7e0000}, {0x3b7e2000}, {0x3b7e4000}, {0x3b7e6000}, + {0x3b7e8000}, {0x3b7ea000}, {0x3b7ec000}, {0x3b7ee000}, + {0x3b7f0000}, {0x3b7f2000}, {0x3b7f4000}, {0x3b7f6000}, + {0x3b7f8000}, {0x3b7fa000}, {0x3b7fc000}, {0x3b7fe000}, + {0x3b800000}, {0x3b802000}, {0x3b804000}, {0x3b806000}, + {0x3b808000}, {0x3b80a000}, {0x3b80c000}, {0x3b80e000}, + {0x3b810000}, {0x3b812000}, {0x3b814000}, {0x3b816000}, + {0x3b818000}, {0x3b81a000}, {0x3b81c000}, {0x3b81e000}, + {0x3b820000}, {0x3b822000}, {0x3b824000}, {0x3b826000}, + {0x3b828000}, {0x3b82a000}, {0x3b82c000}, {0x3b82e000}, + {0x3b830000}, {0x3b832000}, {0x3b834000}, {0x3b836000}, + {0x3b838000}, {0x3b83a000}, {0x3b83c000}, {0x3b83e000}, + {0x3b840000}, {0x3b842000}, {0x3b844000}, {0x3b846000}, + {0x3b848000}, {0x3b84a000}, {0x3b84c000}, {0x3b84e000}, + {0x3b850000}, {0x3b852000}, {0x3b854000}, {0x3b856000}, + {0x3b858000}, {0x3b85a000}, {0x3b85c000}, {0x3b85e000}, + {0x3b860000}, {0x3b862000}, {0x3b864000}, {0x3b866000}, + {0x3b868000}, {0x3b86a000}, {0x3b86c000}, {0x3b86e000}, + {0x3b870000}, {0x3b872000}, {0x3b874000}, {0x3b876000}, + {0x3b878000}, {0x3b87a000}, {0x3b87c000}, {0x3b87e000}, + {0x3b880000}, {0x3b882000}, {0x3b884000}, {0x3b886000}, + {0x3b888000}, {0x3b88a000}, {0x3b88c000}, {0x3b88e000}, + {0x3b890000}, {0x3b892000}, {0x3b894000}, {0x3b896000}, + {0x3b898000}, {0x3b89a000}, {0x3b89c000}, {0x3b89e000}, + {0x3b8a0000}, {0x3b8a2000}, {0x3b8a4000}, {0x3b8a6000}, + {0x3b8a8000}, {0x3b8aa000}, {0x3b8ac000}, {0x3b8ae000}, + {0x3b8b0000}, {0x3b8b2000}, {0x3b8b4000}, {0x3b8b6000}, + {0x3b8b8000}, {0x3b8ba000}, {0x3b8bc000}, {0x3b8be000}, + {0x3b8c0000}, {0x3b8c2000}, {0x3b8c4000}, {0x3b8c6000}, + {0x3b8c8000}, {0x3b8ca000}, {0x3b8cc000}, {0x3b8ce000}, + {0x3b8d0000}, {0x3b8d2000}, {0x3b8d4000}, {0x3b8d6000}, + {0x3b8d8000}, {0x3b8da000}, {0x3b8dc000}, {0x3b8de000}, + {0x3b8e0000}, {0x3b8e2000}, {0x3b8e4000}, {0x3b8e6000}, + {0x3b8e8000}, {0x3b8ea000}, {0x3b8ec000}, {0x3b8ee000}, + {0x3b8f0000}, {0x3b8f2000}, {0x3b8f4000}, {0x3b8f6000}, + {0x3b8f8000}, {0x3b8fa000}, {0x3b8fc000}, {0x3b8fe000}, + {0x3b900000}, {0x3b902000}, {0x3b904000}, {0x3b906000}, + {0x3b908000}, {0x3b90a000}, {0x3b90c000}, {0x3b90e000}, + {0x3b910000}, {0x3b912000}, {0x3b914000}, {0x3b916000}, + {0x3b918000}, {0x3b91a000}, {0x3b91c000}, {0x3b91e000}, + {0x3b920000}, {0x3b922000}, {0x3b924000}, {0x3b926000}, + {0x3b928000}, {0x3b92a000}, {0x3b92c000}, {0x3b92e000}, + {0x3b930000}, {0x3b932000}, {0x3b934000}, {0x3b936000}, + {0x3b938000}, {0x3b93a000}, {0x3b93c000}, {0x3b93e000}, + {0x3b940000}, {0x3b942000}, {0x3b944000}, {0x3b946000}, + {0x3b948000}, {0x3b94a000}, {0x3b94c000}, {0x3b94e000}, + {0x3b950000}, {0x3b952000}, {0x3b954000}, {0x3b956000}, + {0x3b958000}, {0x3b95a000}, {0x3b95c000}, {0x3b95e000}, + {0x3b960000}, {0x3b962000}, {0x3b964000}, {0x3b966000}, + {0x3b968000}, {0x3b96a000}, {0x3b96c000}, {0x3b96e000}, + {0x3b970000}, {0x3b972000}, {0x3b974000}, {0x3b976000}, + {0x3b978000}, {0x3b97a000}, {0x3b97c000}, {0x3b97e000}, + {0x3b980000}, {0x3b982000}, {0x3b984000}, {0x3b986000}, + {0x3b988000}, {0x3b98a000}, {0x3b98c000}, {0x3b98e000}, + {0x3b990000}, {0x3b992000}, {0x3b994000}, {0x3b996000}, + {0x3b998000}, {0x3b99a000}, {0x3b99c000}, {0x3b99e000}, + {0x3b9a0000}, {0x3b9a2000}, {0x3b9a4000}, {0x3b9a6000}, + {0x3b9a8000}, {0x3b9aa000}, {0x3b9ac000}, {0x3b9ae000}, + {0x3b9b0000}, {0x3b9b2000}, {0x3b9b4000}, {0x3b9b6000}, + {0x3b9b8000}, {0x3b9ba000}, {0x3b9bc000}, {0x3b9be000}, + {0x3b9c0000}, {0x3b9c2000}, {0x3b9c4000}, {0x3b9c6000}, + {0x3b9c8000}, {0x3b9ca000}, {0x3b9cc000}, {0x3b9ce000}, + {0x3b9d0000}, {0x3b9d2000}, {0x3b9d4000}, {0x3b9d6000}, + {0x3b9d8000}, {0x3b9da000}, {0x3b9dc000}, {0x3b9de000}, + {0x3b9e0000}, {0x3b9e2000}, {0x3b9e4000}, {0x3b9e6000}, + {0x3b9e8000}, {0x3b9ea000}, {0x3b9ec000}, {0x3b9ee000}, + {0x3b9f0000}, {0x3b9f2000}, {0x3b9f4000}, {0x3b9f6000}, + {0x3b9f8000}, {0x3b9fa000}, {0x3b9fc000}, {0x3b9fe000}, + {0x3ba00000}, {0x3ba02000}, {0x3ba04000}, {0x3ba06000}, + {0x3ba08000}, {0x3ba0a000}, {0x3ba0c000}, {0x3ba0e000}, + {0x3ba10000}, {0x3ba12000}, {0x3ba14000}, {0x3ba16000}, + {0x3ba18000}, {0x3ba1a000}, {0x3ba1c000}, {0x3ba1e000}, + {0x3ba20000}, {0x3ba22000}, {0x3ba24000}, {0x3ba26000}, + {0x3ba28000}, {0x3ba2a000}, {0x3ba2c000}, {0x3ba2e000}, + {0x3ba30000}, {0x3ba32000}, {0x3ba34000}, {0x3ba36000}, + {0x3ba38000}, {0x3ba3a000}, {0x3ba3c000}, {0x3ba3e000}, + {0x3ba40000}, {0x3ba42000}, {0x3ba44000}, {0x3ba46000}, + {0x3ba48000}, {0x3ba4a000}, {0x3ba4c000}, {0x3ba4e000}, + {0x3ba50000}, {0x3ba52000}, {0x3ba54000}, {0x3ba56000}, + {0x3ba58000}, {0x3ba5a000}, {0x3ba5c000}, {0x3ba5e000}, + {0x3ba60000}, {0x3ba62000}, {0x3ba64000}, {0x3ba66000}, + {0x3ba68000}, {0x3ba6a000}, {0x3ba6c000}, {0x3ba6e000}, + {0x3ba70000}, {0x3ba72000}, {0x3ba74000}, {0x3ba76000}, + {0x3ba78000}, {0x3ba7a000}, {0x3ba7c000}, {0x3ba7e000}, + {0x3ba80000}, {0x3ba82000}, {0x3ba84000}, {0x3ba86000}, + {0x3ba88000}, {0x3ba8a000}, {0x3ba8c000}, {0x3ba8e000}, + {0x3ba90000}, {0x3ba92000}, {0x3ba94000}, {0x3ba96000}, + {0x3ba98000}, {0x3ba9a000}, {0x3ba9c000}, {0x3ba9e000}, + {0x3baa0000}, {0x3baa2000}, {0x3baa4000}, {0x3baa6000}, + {0x3baa8000}, {0x3baaa000}, {0x3baac000}, {0x3baae000}, + {0x3bab0000}, {0x3bab2000}, {0x3bab4000}, {0x3bab6000}, + {0x3bab8000}, {0x3baba000}, {0x3babc000}, {0x3babe000}, + {0x3bac0000}, {0x3bac2000}, {0x3bac4000}, {0x3bac6000}, + {0x3bac8000}, {0x3baca000}, {0x3bacc000}, {0x3bace000}, + {0x3bad0000}, {0x3bad2000}, {0x3bad4000}, {0x3bad6000}, + {0x3bad8000}, {0x3bada000}, {0x3badc000}, {0x3bade000}, + {0x3bae0000}, {0x3bae2000}, {0x3bae4000}, {0x3bae6000}, + {0x3bae8000}, {0x3baea000}, {0x3baec000}, {0x3baee000}, + {0x3baf0000}, {0x3baf2000}, {0x3baf4000}, {0x3baf6000}, + {0x3baf8000}, {0x3bafa000}, {0x3bafc000}, {0x3bafe000}, + {0x3bb00000}, {0x3bb02000}, {0x3bb04000}, {0x3bb06000}, + {0x3bb08000}, {0x3bb0a000}, {0x3bb0c000}, {0x3bb0e000}, + {0x3bb10000}, {0x3bb12000}, {0x3bb14000}, {0x3bb16000}, + {0x3bb18000}, {0x3bb1a000}, {0x3bb1c000}, {0x3bb1e000}, + {0x3bb20000}, {0x3bb22000}, {0x3bb24000}, {0x3bb26000}, + {0x3bb28000}, {0x3bb2a000}, {0x3bb2c000}, {0x3bb2e000}, + {0x3bb30000}, {0x3bb32000}, {0x3bb34000}, {0x3bb36000}, + {0x3bb38000}, {0x3bb3a000}, {0x3bb3c000}, {0x3bb3e000}, + {0x3bb40000}, {0x3bb42000}, {0x3bb44000}, {0x3bb46000}, + {0x3bb48000}, {0x3bb4a000}, {0x3bb4c000}, {0x3bb4e000}, + {0x3bb50000}, {0x3bb52000}, {0x3bb54000}, {0x3bb56000}, + {0x3bb58000}, {0x3bb5a000}, {0x3bb5c000}, {0x3bb5e000}, + {0x3bb60000}, {0x3bb62000}, {0x3bb64000}, {0x3bb66000}, + {0x3bb68000}, {0x3bb6a000}, {0x3bb6c000}, {0x3bb6e000}, + {0x3bb70000}, {0x3bb72000}, {0x3bb74000}, {0x3bb76000}, + {0x3bb78000}, {0x3bb7a000}, {0x3bb7c000}, {0x3bb7e000}, + {0x3bb80000}, {0x3bb82000}, {0x3bb84000}, {0x3bb86000}, + {0x3bb88000}, {0x3bb8a000}, {0x3bb8c000}, {0x3bb8e000}, + {0x3bb90000}, {0x3bb92000}, {0x3bb94000}, {0x3bb96000}, + {0x3bb98000}, {0x3bb9a000}, {0x3bb9c000}, {0x3bb9e000}, + {0x3bba0000}, {0x3bba2000}, {0x3bba4000}, {0x3bba6000}, + {0x3bba8000}, {0x3bbaa000}, {0x3bbac000}, {0x3bbae000}, + {0x3bbb0000}, {0x3bbb2000}, {0x3bbb4000}, {0x3bbb6000}, + {0x3bbb8000}, {0x3bbba000}, {0x3bbbc000}, {0x3bbbe000}, + {0x3bbc0000}, {0x3bbc2000}, {0x3bbc4000}, {0x3bbc6000}, + {0x3bbc8000}, {0x3bbca000}, {0x3bbcc000}, {0x3bbce000}, + {0x3bbd0000}, {0x3bbd2000}, {0x3bbd4000}, {0x3bbd6000}, + {0x3bbd8000}, {0x3bbda000}, {0x3bbdc000}, {0x3bbde000}, + {0x3bbe0000}, {0x3bbe2000}, {0x3bbe4000}, {0x3bbe6000}, + {0x3bbe8000}, {0x3bbea000}, {0x3bbec000}, {0x3bbee000}, + {0x3bbf0000}, {0x3bbf2000}, {0x3bbf4000}, {0x3bbf6000}, + {0x3bbf8000}, {0x3bbfa000}, {0x3bbfc000}, {0x3bbfe000}, + {0x3bc00000}, {0x3bc02000}, {0x3bc04000}, {0x3bc06000}, + {0x3bc08000}, {0x3bc0a000}, {0x3bc0c000}, {0x3bc0e000}, + {0x3bc10000}, {0x3bc12000}, {0x3bc14000}, {0x3bc16000}, + {0x3bc18000}, {0x3bc1a000}, {0x3bc1c000}, {0x3bc1e000}, + {0x3bc20000}, {0x3bc22000}, {0x3bc24000}, {0x3bc26000}, + {0x3bc28000}, {0x3bc2a000}, {0x3bc2c000}, {0x3bc2e000}, + {0x3bc30000}, {0x3bc32000}, {0x3bc34000}, {0x3bc36000}, + {0x3bc38000}, {0x3bc3a000}, {0x3bc3c000}, {0x3bc3e000}, + {0x3bc40000}, {0x3bc42000}, {0x3bc44000}, {0x3bc46000}, + {0x3bc48000}, {0x3bc4a000}, {0x3bc4c000}, {0x3bc4e000}, + {0x3bc50000}, {0x3bc52000}, {0x3bc54000}, {0x3bc56000}, + {0x3bc58000}, {0x3bc5a000}, {0x3bc5c000}, {0x3bc5e000}, + {0x3bc60000}, {0x3bc62000}, {0x3bc64000}, {0x3bc66000}, + {0x3bc68000}, {0x3bc6a000}, {0x3bc6c000}, {0x3bc6e000}, + {0x3bc70000}, {0x3bc72000}, {0x3bc74000}, {0x3bc76000}, + {0x3bc78000}, {0x3bc7a000}, {0x3bc7c000}, {0x3bc7e000}, + {0x3bc80000}, {0x3bc82000}, {0x3bc84000}, {0x3bc86000}, + {0x3bc88000}, {0x3bc8a000}, {0x3bc8c000}, {0x3bc8e000}, + {0x3bc90000}, {0x3bc92000}, {0x3bc94000}, {0x3bc96000}, + {0x3bc98000}, {0x3bc9a000}, {0x3bc9c000}, {0x3bc9e000}, + {0x3bca0000}, {0x3bca2000}, {0x3bca4000}, {0x3bca6000}, + {0x3bca8000}, {0x3bcaa000}, {0x3bcac000}, {0x3bcae000}, + {0x3bcb0000}, {0x3bcb2000}, {0x3bcb4000}, {0x3bcb6000}, + {0x3bcb8000}, {0x3bcba000}, {0x3bcbc000}, {0x3bcbe000}, + {0x3bcc0000}, {0x3bcc2000}, {0x3bcc4000}, {0x3bcc6000}, + {0x3bcc8000}, {0x3bcca000}, {0x3bccc000}, {0x3bcce000}, + {0x3bcd0000}, {0x3bcd2000}, {0x3bcd4000}, {0x3bcd6000}, + {0x3bcd8000}, {0x3bcda000}, {0x3bcdc000}, {0x3bcde000}, + {0x3bce0000}, {0x3bce2000}, {0x3bce4000}, {0x3bce6000}, + {0x3bce8000}, {0x3bcea000}, {0x3bcec000}, {0x3bcee000}, + {0x3bcf0000}, {0x3bcf2000}, {0x3bcf4000}, {0x3bcf6000}, + {0x3bcf8000}, {0x3bcfa000}, {0x3bcfc000}, {0x3bcfe000}, + {0x3bd00000}, {0x3bd02000}, {0x3bd04000}, {0x3bd06000}, + {0x3bd08000}, {0x3bd0a000}, {0x3bd0c000}, {0x3bd0e000}, + {0x3bd10000}, {0x3bd12000}, {0x3bd14000}, {0x3bd16000}, + {0x3bd18000}, {0x3bd1a000}, {0x3bd1c000}, {0x3bd1e000}, + {0x3bd20000}, {0x3bd22000}, {0x3bd24000}, {0x3bd26000}, + {0x3bd28000}, {0x3bd2a000}, {0x3bd2c000}, {0x3bd2e000}, + {0x3bd30000}, {0x3bd32000}, {0x3bd34000}, {0x3bd36000}, + {0x3bd38000}, {0x3bd3a000}, {0x3bd3c000}, {0x3bd3e000}, + {0x3bd40000}, {0x3bd42000}, {0x3bd44000}, {0x3bd46000}, + {0x3bd48000}, {0x3bd4a000}, {0x3bd4c000}, {0x3bd4e000}, + {0x3bd50000}, {0x3bd52000}, {0x3bd54000}, {0x3bd56000}, + {0x3bd58000}, {0x3bd5a000}, {0x3bd5c000}, {0x3bd5e000}, + {0x3bd60000}, {0x3bd62000}, {0x3bd64000}, {0x3bd66000}, + {0x3bd68000}, {0x3bd6a000}, {0x3bd6c000}, {0x3bd6e000}, + {0x3bd70000}, {0x3bd72000}, {0x3bd74000}, {0x3bd76000}, + {0x3bd78000}, {0x3bd7a000}, {0x3bd7c000}, {0x3bd7e000}, + {0x3bd80000}, {0x3bd82000}, {0x3bd84000}, {0x3bd86000}, + {0x3bd88000}, {0x3bd8a000}, {0x3bd8c000}, {0x3bd8e000}, + {0x3bd90000}, {0x3bd92000}, {0x3bd94000}, {0x3bd96000}, + {0x3bd98000}, {0x3bd9a000}, {0x3bd9c000}, {0x3bd9e000}, + {0x3bda0000}, {0x3bda2000}, {0x3bda4000}, {0x3bda6000}, + {0x3bda8000}, {0x3bdaa000}, {0x3bdac000}, {0x3bdae000}, + {0x3bdb0000}, {0x3bdb2000}, {0x3bdb4000}, {0x3bdb6000}, + {0x3bdb8000}, {0x3bdba000}, {0x3bdbc000}, {0x3bdbe000}, + {0x3bdc0000}, {0x3bdc2000}, {0x3bdc4000}, {0x3bdc6000}, + {0x3bdc8000}, {0x3bdca000}, {0x3bdcc000}, {0x3bdce000}, + {0x3bdd0000}, {0x3bdd2000}, {0x3bdd4000}, {0x3bdd6000}, + {0x3bdd8000}, {0x3bdda000}, {0x3bddc000}, {0x3bdde000}, + {0x3bde0000}, {0x3bde2000}, {0x3bde4000}, {0x3bde6000}, + {0x3bde8000}, {0x3bdea000}, {0x3bdec000}, {0x3bdee000}, + {0x3bdf0000}, {0x3bdf2000}, {0x3bdf4000}, {0x3bdf6000}, + {0x3bdf8000}, {0x3bdfa000}, {0x3bdfc000}, {0x3bdfe000}, + {0x3be00000}, {0x3be02000}, {0x3be04000}, {0x3be06000}, + {0x3be08000}, {0x3be0a000}, {0x3be0c000}, {0x3be0e000}, + {0x3be10000}, {0x3be12000}, {0x3be14000}, {0x3be16000}, + {0x3be18000}, {0x3be1a000}, {0x3be1c000}, {0x3be1e000}, + {0x3be20000}, {0x3be22000}, {0x3be24000}, {0x3be26000}, + {0x3be28000}, {0x3be2a000}, {0x3be2c000}, {0x3be2e000}, + {0x3be30000}, {0x3be32000}, {0x3be34000}, {0x3be36000}, + {0x3be38000}, {0x3be3a000}, {0x3be3c000}, {0x3be3e000}, + {0x3be40000}, {0x3be42000}, {0x3be44000}, {0x3be46000}, + {0x3be48000}, {0x3be4a000}, {0x3be4c000}, {0x3be4e000}, + {0x3be50000}, {0x3be52000}, {0x3be54000}, {0x3be56000}, + {0x3be58000}, {0x3be5a000}, {0x3be5c000}, {0x3be5e000}, + {0x3be60000}, {0x3be62000}, {0x3be64000}, {0x3be66000}, + {0x3be68000}, {0x3be6a000}, {0x3be6c000}, {0x3be6e000}, + {0x3be70000}, {0x3be72000}, {0x3be74000}, {0x3be76000}, + {0x3be78000}, {0x3be7a000}, {0x3be7c000}, {0x3be7e000}, + {0x3be80000}, {0x3be82000}, {0x3be84000}, {0x3be86000}, + {0x3be88000}, {0x3be8a000}, {0x3be8c000}, {0x3be8e000}, + {0x3be90000}, {0x3be92000}, {0x3be94000}, {0x3be96000}, + {0x3be98000}, {0x3be9a000}, {0x3be9c000}, {0x3be9e000}, + {0x3bea0000}, {0x3bea2000}, {0x3bea4000}, {0x3bea6000}, + {0x3bea8000}, {0x3beaa000}, {0x3beac000}, {0x3beae000}, + {0x3beb0000}, {0x3beb2000}, {0x3beb4000}, {0x3beb6000}, + {0x3beb8000}, {0x3beba000}, {0x3bebc000}, {0x3bebe000}, + {0x3bec0000}, {0x3bec2000}, {0x3bec4000}, {0x3bec6000}, + {0x3bec8000}, {0x3beca000}, {0x3becc000}, {0x3bece000}, + {0x3bed0000}, {0x3bed2000}, {0x3bed4000}, {0x3bed6000}, + {0x3bed8000}, {0x3beda000}, {0x3bedc000}, {0x3bede000}, + {0x3bee0000}, {0x3bee2000}, {0x3bee4000}, {0x3bee6000}, + {0x3bee8000}, {0x3beea000}, {0x3beec000}, {0x3beee000}, + {0x3bef0000}, {0x3bef2000}, {0x3bef4000}, {0x3bef6000}, + {0x3bef8000}, {0x3befa000}, {0x3befc000}, {0x3befe000}, + {0x3bf00000}, {0x3bf02000}, {0x3bf04000}, {0x3bf06000}, + {0x3bf08000}, {0x3bf0a000}, {0x3bf0c000}, {0x3bf0e000}, + {0x3bf10000}, {0x3bf12000}, {0x3bf14000}, {0x3bf16000}, + {0x3bf18000}, {0x3bf1a000}, {0x3bf1c000}, {0x3bf1e000}, + {0x3bf20000}, {0x3bf22000}, {0x3bf24000}, {0x3bf26000}, + {0x3bf28000}, {0x3bf2a000}, {0x3bf2c000}, {0x3bf2e000}, + {0x3bf30000}, {0x3bf32000}, {0x3bf34000}, {0x3bf36000}, + {0x3bf38000}, {0x3bf3a000}, {0x3bf3c000}, {0x3bf3e000}, + {0x3bf40000}, {0x3bf42000}, {0x3bf44000}, {0x3bf46000}, + {0x3bf48000}, {0x3bf4a000}, {0x3bf4c000}, {0x3bf4e000}, + {0x3bf50000}, {0x3bf52000}, {0x3bf54000}, {0x3bf56000}, + {0x3bf58000}, {0x3bf5a000}, {0x3bf5c000}, {0x3bf5e000}, + {0x3bf60000}, {0x3bf62000}, {0x3bf64000}, {0x3bf66000}, + {0x3bf68000}, {0x3bf6a000}, {0x3bf6c000}, {0x3bf6e000}, + {0x3bf70000}, {0x3bf72000}, {0x3bf74000}, {0x3bf76000}, + {0x3bf78000}, {0x3bf7a000}, {0x3bf7c000}, {0x3bf7e000}, + {0x3bf80000}, {0x3bf82000}, {0x3bf84000}, {0x3bf86000}, + {0x3bf88000}, {0x3bf8a000}, {0x3bf8c000}, {0x3bf8e000}, + {0x3bf90000}, {0x3bf92000}, {0x3bf94000}, {0x3bf96000}, + {0x3bf98000}, {0x3bf9a000}, {0x3bf9c000}, {0x3bf9e000}, + {0x3bfa0000}, {0x3bfa2000}, {0x3bfa4000}, {0x3bfa6000}, + {0x3bfa8000}, {0x3bfaa000}, {0x3bfac000}, {0x3bfae000}, + {0x3bfb0000}, {0x3bfb2000}, {0x3bfb4000}, {0x3bfb6000}, + {0x3bfb8000}, {0x3bfba000}, {0x3bfbc000}, {0x3bfbe000}, + {0x3bfc0000}, {0x3bfc2000}, {0x3bfc4000}, {0x3bfc6000}, + {0x3bfc8000}, {0x3bfca000}, {0x3bfcc000}, {0x3bfce000}, + {0x3bfd0000}, {0x3bfd2000}, {0x3bfd4000}, {0x3bfd6000}, + {0x3bfd8000}, {0x3bfda000}, {0x3bfdc000}, {0x3bfde000}, + {0x3bfe0000}, {0x3bfe2000}, {0x3bfe4000}, {0x3bfe6000}, + {0x3bfe8000}, {0x3bfea000}, {0x3bfec000}, {0x3bfee000}, + {0x3bff0000}, {0x3bff2000}, {0x3bff4000}, {0x3bff6000}, + {0x3bff8000}, {0x3bffa000}, {0x3bffc000}, {0x3bffe000}, + {0x3c000000}, {0x3c002000}, {0x3c004000}, {0x3c006000}, + {0x3c008000}, {0x3c00a000}, {0x3c00c000}, {0x3c00e000}, + {0x3c010000}, {0x3c012000}, {0x3c014000}, {0x3c016000}, + {0x3c018000}, {0x3c01a000}, {0x3c01c000}, {0x3c01e000}, + {0x3c020000}, {0x3c022000}, {0x3c024000}, {0x3c026000}, + {0x3c028000}, {0x3c02a000}, {0x3c02c000}, {0x3c02e000}, + {0x3c030000}, {0x3c032000}, {0x3c034000}, {0x3c036000}, + {0x3c038000}, {0x3c03a000}, {0x3c03c000}, {0x3c03e000}, + {0x3c040000}, {0x3c042000}, {0x3c044000}, {0x3c046000}, + {0x3c048000}, {0x3c04a000}, {0x3c04c000}, {0x3c04e000}, + {0x3c050000}, {0x3c052000}, {0x3c054000}, {0x3c056000}, + {0x3c058000}, {0x3c05a000}, {0x3c05c000}, {0x3c05e000}, + {0x3c060000}, {0x3c062000}, {0x3c064000}, {0x3c066000}, + {0x3c068000}, {0x3c06a000}, {0x3c06c000}, {0x3c06e000}, + {0x3c070000}, {0x3c072000}, {0x3c074000}, {0x3c076000}, + {0x3c078000}, {0x3c07a000}, {0x3c07c000}, {0x3c07e000}, + {0x3c080000}, {0x3c082000}, {0x3c084000}, {0x3c086000}, + {0x3c088000}, {0x3c08a000}, {0x3c08c000}, {0x3c08e000}, + {0x3c090000}, {0x3c092000}, {0x3c094000}, {0x3c096000}, + {0x3c098000}, {0x3c09a000}, {0x3c09c000}, {0x3c09e000}, + {0x3c0a0000}, {0x3c0a2000}, {0x3c0a4000}, {0x3c0a6000}, + {0x3c0a8000}, {0x3c0aa000}, {0x3c0ac000}, {0x3c0ae000}, + {0x3c0b0000}, {0x3c0b2000}, {0x3c0b4000}, {0x3c0b6000}, + {0x3c0b8000}, {0x3c0ba000}, {0x3c0bc000}, {0x3c0be000}, + {0x3c0c0000}, {0x3c0c2000}, {0x3c0c4000}, {0x3c0c6000}, + {0x3c0c8000}, {0x3c0ca000}, {0x3c0cc000}, {0x3c0ce000}, + {0x3c0d0000}, {0x3c0d2000}, {0x3c0d4000}, {0x3c0d6000}, + {0x3c0d8000}, {0x3c0da000}, {0x3c0dc000}, {0x3c0de000}, + {0x3c0e0000}, {0x3c0e2000}, {0x3c0e4000}, {0x3c0e6000}, + {0x3c0e8000}, {0x3c0ea000}, {0x3c0ec000}, {0x3c0ee000}, + {0x3c0f0000}, {0x3c0f2000}, {0x3c0f4000}, {0x3c0f6000}, + {0x3c0f8000}, {0x3c0fa000}, {0x3c0fc000}, {0x3c0fe000}, + {0x3c100000}, {0x3c102000}, {0x3c104000}, {0x3c106000}, + {0x3c108000}, {0x3c10a000}, {0x3c10c000}, {0x3c10e000}, + {0x3c110000}, {0x3c112000}, {0x3c114000}, {0x3c116000}, + {0x3c118000}, {0x3c11a000}, {0x3c11c000}, {0x3c11e000}, + {0x3c120000}, {0x3c122000}, {0x3c124000}, {0x3c126000}, + {0x3c128000}, {0x3c12a000}, {0x3c12c000}, {0x3c12e000}, + {0x3c130000}, {0x3c132000}, {0x3c134000}, {0x3c136000}, + {0x3c138000}, {0x3c13a000}, {0x3c13c000}, {0x3c13e000}, + {0x3c140000}, {0x3c142000}, {0x3c144000}, {0x3c146000}, + {0x3c148000}, {0x3c14a000}, {0x3c14c000}, {0x3c14e000}, + {0x3c150000}, {0x3c152000}, {0x3c154000}, {0x3c156000}, + {0x3c158000}, {0x3c15a000}, {0x3c15c000}, {0x3c15e000}, + {0x3c160000}, {0x3c162000}, {0x3c164000}, {0x3c166000}, + {0x3c168000}, {0x3c16a000}, {0x3c16c000}, {0x3c16e000}, + {0x3c170000}, {0x3c172000}, {0x3c174000}, {0x3c176000}, + {0x3c178000}, {0x3c17a000}, {0x3c17c000}, {0x3c17e000}, + {0x3c180000}, {0x3c182000}, {0x3c184000}, {0x3c186000}, + {0x3c188000}, {0x3c18a000}, {0x3c18c000}, {0x3c18e000}, + {0x3c190000}, {0x3c192000}, {0x3c194000}, {0x3c196000}, + {0x3c198000}, {0x3c19a000}, {0x3c19c000}, {0x3c19e000}, + {0x3c1a0000}, {0x3c1a2000}, {0x3c1a4000}, {0x3c1a6000}, + {0x3c1a8000}, {0x3c1aa000}, {0x3c1ac000}, {0x3c1ae000}, + {0x3c1b0000}, {0x3c1b2000}, {0x3c1b4000}, {0x3c1b6000}, + {0x3c1b8000}, {0x3c1ba000}, {0x3c1bc000}, {0x3c1be000}, + {0x3c1c0000}, {0x3c1c2000}, {0x3c1c4000}, {0x3c1c6000}, + {0x3c1c8000}, {0x3c1ca000}, {0x3c1cc000}, {0x3c1ce000}, + {0x3c1d0000}, {0x3c1d2000}, {0x3c1d4000}, {0x3c1d6000}, + {0x3c1d8000}, {0x3c1da000}, {0x3c1dc000}, {0x3c1de000}, + {0x3c1e0000}, {0x3c1e2000}, {0x3c1e4000}, {0x3c1e6000}, + {0x3c1e8000}, {0x3c1ea000}, {0x3c1ec000}, {0x3c1ee000}, + {0x3c1f0000}, {0x3c1f2000}, {0x3c1f4000}, {0x3c1f6000}, + {0x3c1f8000}, {0x3c1fa000}, {0x3c1fc000}, {0x3c1fe000}, + {0x3c200000}, {0x3c202000}, {0x3c204000}, {0x3c206000}, + {0x3c208000}, {0x3c20a000}, {0x3c20c000}, {0x3c20e000}, + {0x3c210000}, {0x3c212000}, {0x3c214000}, {0x3c216000}, + {0x3c218000}, {0x3c21a000}, {0x3c21c000}, {0x3c21e000}, + {0x3c220000}, {0x3c222000}, {0x3c224000}, {0x3c226000}, + {0x3c228000}, {0x3c22a000}, {0x3c22c000}, {0x3c22e000}, + {0x3c230000}, {0x3c232000}, {0x3c234000}, {0x3c236000}, + {0x3c238000}, {0x3c23a000}, {0x3c23c000}, {0x3c23e000}, + {0x3c240000}, {0x3c242000}, {0x3c244000}, {0x3c246000}, + {0x3c248000}, {0x3c24a000}, {0x3c24c000}, {0x3c24e000}, + {0x3c250000}, {0x3c252000}, {0x3c254000}, {0x3c256000}, + {0x3c258000}, {0x3c25a000}, {0x3c25c000}, {0x3c25e000}, + {0x3c260000}, {0x3c262000}, {0x3c264000}, {0x3c266000}, + {0x3c268000}, {0x3c26a000}, {0x3c26c000}, {0x3c26e000}, + {0x3c270000}, {0x3c272000}, {0x3c274000}, {0x3c276000}, + {0x3c278000}, {0x3c27a000}, {0x3c27c000}, {0x3c27e000}, + {0x3c280000}, {0x3c282000}, {0x3c284000}, {0x3c286000}, + {0x3c288000}, {0x3c28a000}, {0x3c28c000}, {0x3c28e000}, + {0x3c290000}, {0x3c292000}, {0x3c294000}, {0x3c296000}, + {0x3c298000}, {0x3c29a000}, {0x3c29c000}, {0x3c29e000}, + {0x3c2a0000}, {0x3c2a2000}, {0x3c2a4000}, {0x3c2a6000}, + {0x3c2a8000}, {0x3c2aa000}, {0x3c2ac000}, {0x3c2ae000}, + {0x3c2b0000}, {0x3c2b2000}, {0x3c2b4000}, {0x3c2b6000}, + {0x3c2b8000}, {0x3c2ba000}, {0x3c2bc000}, {0x3c2be000}, + {0x3c2c0000}, {0x3c2c2000}, {0x3c2c4000}, {0x3c2c6000}, + {0x3c2c8000}, {0x3c2ca000}, {0x3c2cc000}, {0x3c2ce000}, + {0x3c2d0000}, {0x3c2d2000}, {0x3c2d4000}, {0x3c2d6000}, + {0x3c2d8000}, {0x3c2da000}, {0x3c2dc000}, {0x3c2de000}, + {0x3c2e0000}, {0x3c2e2000}, {0x3c2e4000}, {0x3c2e6000}, + {0x3c2e8000}, {0x3c2ea000}, {0x3c2ec000}, {0x3c2ee000}, + {0x3c2f0000}, {0x3c2f2000}, {0x3c2f4000}, {0x3c2f6000}, + {0x3c2f8000}, {0x3c2fa000}, {0x3c2fc000}, {0x3c2fe000}, + {0x3c300000}, {0x3c302000}, {0x3c304000}, {0x3c306000}, + {0x3c308000}, {0x3c30a000}, {0x3c30c000}, {0x3c30e000}, + {0x3c310000}, {0x3c312000}, {0x3c314000}, {0x3c316000}, + {0x3c318000}, {0x3c31a000}, {0x3c31c000}, {0x3c31e000}, + {0x3c320000}, {0x3c322000}, {0x3c324000}, {0x3c326000}, + {0x3c328000}, {0x3c32a000}, {0x3c32c000}, {0x3c32e000}, + {0x3c330000}, {0x3c332000}, {0x3c334000}, {0x3c336000}, + {0x3c338000}, {0x3c33a000}, {0x3c33c000}, {0x3c33e000}, + {0x3c340000}, {0x3c342000}, {0x3c344000}, {0x3c346000}, + {0x3c348000}, {0x3c34a000}, {0x3c34c000}, {0x3c34e000}, + {0x3c350000}, {0x3c352000}, {0x3c354000}, {0x3c356000}, + {0x3c358000}, {0x3c35a000}, {0x3c35c000}, {0x3c35e000}, + {0x3c360000}, {0x3c362000}, {0x3c364000}, {0x3c366000}, + {0x3c368000}, {0x3c36a000}, {0x3c36c000}, {0x3c36e000}, + {0x3c370000}, {0x3c372000}, {0x3c374000}, {0x3c376000}, + {0x3c378000}, {0x3c37a000}, {0x3c37c000}, {0x3c37e000}, + {0x3c380000}, {0x3c382000}, {0x3c384000}, {0x3c386000}, + {0x3c388000}, {0x3c38a000}, {0x3c38c000}, {0x3c38e000}, + {0x3c390000}, {0x3c392000}, {0x3c394000}, {0x3c396000}, + {0x3c398000}, {0x3c39a000}, {0x3c39c000}, {0x3c39e000}, + {0x3c3a0000}, {0x3c3a2000}, {0x3c3a4000}, {0x3c3a6000}, + {0x3c3a8000}, {0x3c3aa000}, {0x3c3ac000}, {0x3c3ae000}, + {0x3c3b0000}, {0x3c3b2000}, {0x3c3b4000}, {0x3c3b6000}, + {0x3c3b8000}, {0x3c3ba000}, {0x3c3bc000}, {0x3c3be000}, + {0x3c3c0000}, {0x3c3c2000}, {0x3c3c4000}, {0x3c3c6000}, + {0x3c3c8000}, {0x3c3ca000}, {0x3c3cc000}, {0x3c3ce000}, + {0x3c3d0000}, {0x3c3d2000}, {0x3c3d4000}, {0x3c3d6000}, + {0x3c3d8000}, {0x3c3da000}, {0x3c3dc000}, {0x3c3de000}, + {0x3c3e0000}, {0x3c3e2000}, {0x3c3e4000}, {0x3c3e6000}, + {0x3c3e8000}, {0x3c3ea000}, {0x3c3ec000}, {0x3c3ee000}, + {0x3c3f0000}, {0x3c3f2000}, {0x3c3f4000}, {0x3c3f6000}, + {0x3c3f8000}, {0x3c3fa000}, {0x3c3fc000}, {0x3c3fe000}, + {0x3c400000}, {0x3c402000}, {0x3c404000}, {0x3c406000}, + {0x3c408000}, {0x3c40a000}, {0x3c40c000}, {0x3c40e000}, + {0x3c410000}, {0x3c412000}, {0x3c414000}, {0x3c416000}, + {0x3c418000}, {0x3c41a000}, {0x3c41c000}, {0x3c41e000}, + {0x3c420000}, {0x3c422000}, {0x3c424000}, {0x3c426000}, + {0x3c428000}, {0x3c42a000}, {0x3c42c000}, {0x3c42e000}, + {0x3c430000}, {0x3c432000}, {0x3c434000}, {0x3c436000}, + {0x3c438000}, {0x3c43a000}, {0x3c43c000}, {0x3c43e000}, + {0x3c440000}, {0x3c442000}, {0x3c444000}, {0x3c446000}, + {0x3c448000}, {0x3c44a000}, {0x3c44c000}, {0x3c44e000}, + {0x3c450000}, {0x3c452000}, {0x3c454000}, {0x3c456000}, + {0x3c458000}, {0x3c45a000}, {0x3c45c000}, {0x3c45e000}, + {0x3c460000}, {0x3c462000}, {0x3c464000}, {0x3c466000}, + {0x3c468000}, {0x3c46a000}, {0x3c46c000}, {0x3c46e000}, + {0x3c470000}, {0x3c472000}, {0x3c474000}, {0x3c476000}, + {0x3c478000}, {0x3c47a000}, {0x3c47c000}, {0x3c47e000}, + {0x3c480000}, {0x3c482000}, {0x3c484000}, {0x3c486000}, + {0x3c488000}, {0x3c48a000}, {0x3c48c000}, {0x3c48e000}, + {0x3c490000}, {0x3c492000}, {0x3c494000}, {0x3c496000}, + {0x3c498000}, {0x3c49a000}, {0x3c49c000}, {0x3c49e000}, + {0x3c4a0000}, {0x3c4a2000}, {0x3c4a4000}, {0x3c4a6000}, + {0x3c4a8000}, {0x3c4aa000}, {0x3c4ac000}, {0x3c4ae000}, + {0x3c4b0000}, {0x3c4b2000}, {0x3c4b4000}, {0x3c4b6000}, + {0x3c4b8000}, {0x3c4ba000}, {0x3c4bc000}, {0x3c4be000}, + {0x3c4c0000}, {0x3c4c2000}, {0x3c4c4000}, {0x3c4c6000}, + {0x3c4c8000}, {0x3c4ca000}, {0x3c4cc000}, {0x3c4ce000}, + {0x3c4d0000}, {0x3c4d2000}, {0x3c4d4000}, {0x3c4d6000}, + {0x3c4d8000}, {0x3c4da000}, {0x3c4dc000}, {0x3c4de000}, + {0x3c4e0000}, {0x3c4e2000}, {0x3c4e4000}, {0x3c4e6000}, + {0x3c4e8000}, {0x3c4ea000}, {0x3c4ec000}, {0x3c4ee000}, + {0x3c4f0000}, {0x3c4f2000}, {0x3c4f4000}, {0x3c4f6000}, + {0x3c4f8000}, {0x3c4fa000}, {0x3c4fc000}, {0x3c4fe000}, + {0x3c500000}, {0x3c502000}, {0x3c504000}, {0x3c506000}, + {0x3c508000}, {0x3c50a000}, {0x3c50c000}, {0x3c50e000}, + {0x3c510000}, {0x3c512000}, {0x3c514000}, {0x3c516000}, + {0x3c518000}, {0x3c51a000}, {0x3c51c000}, {0x3c51e000}, + {0x3c520000}, {0x3c522000}, {0x3c524000}, {0x3c526000}, + {0x3c528000}, {0x3c52a000}, {0x3c52c000}, {0x3c52e000}, + {0x3c530000}, {0x3c532000}, {0x3c534000}, {0x3c536000}, + {0x3c538000}, {0x3c53a000}, {0x3c53c000}, {0x3c53e000}, + {0x3c540000}, {0x3c542000}, {0x3c544000}, {0x3c546000}, + {0x3c548000}, {0x3c54a000}, {0x3c54c000}, {0x3c54e000}, + {0x3c550000}, {0x3c552000}, {0x3c554000}, {0x3c556000}, + {0x3c558000}, {0x3c55a000}, {0x3c55c000}, {0x3c55e000}, + {0x3c560000}, {0x3c562000}, {0x3c564000}, {0x3c566000}, + {0x3c568000}, {0x3c56a000}, {0x3c56c000}, {0x3c56e000}, + {0x3c570000}, {0x3c572000}, {0x3c574000}, {0x3c576000}, + {0x3c578000}, {0x3c57a000}, {0x3c57c000}, {0x3c57e000}, + {0x3c580000}, {0x3c582000}, {0x3c584000}, {0x3c586000}, + {0x3c588000}, {0x3c58a000}, {0x3c58c000}, {0x3c58e000}, + {0x3c590000}, {0x3c592000}, {0x3c594000}, {0x3c596000}, + {0x3c598000}, {0x3c59a000}, {0x3c59c000}, {0x3c59e000}, + {0x3c5a0000}, {0x3c5a2000}, {0x3c5a4000}, {0x3c5a6000}, + {0x3c5a8000}, {0x3c5aa000}, {0x3c5ac000}, {0x3c5ae000}, + {0x3c5b0000}, {0x3c5b2000}, {0x3c5b4000}, {0x3c5b6000}, + {0x3c5b8000}, {0x3c5ba000}, {0x3c5bc000}, {0x3c5be000}, + {0x3c5c0000}, {0x3c5c2000}, {0x3c5c4000}, {0x3c5c6000}, + {0x3c5c8000}, {0x3c5ca000}, {0x3c5cc000}, {0x3c5ce000}, + {0x3c5d0000}, {0x3c5d2000}, {0x3c5d4000}, {0x3c5d6000}, + {0x3c5d8000}, {0x3c5da000}, {0x3c5dc000}, {0x3c5de000}, + {0x3c5e0000}, {0x3c5e2000}, {0x3c5e4000}, {0x3c5e6000}, + {0x3c5e8000}, {0x3c5ea000}, {0x3c5ec000}, {0x3c5ee000}, + {0x3c5f0000}, {0x3c5f2000}, {0x3c5f4000}, {0x3c5f6000}, + {0x3c5f8000}, {0x3c5fa000}, {0x3c5fc000}, {0x3c5fe000}, + {0x3c600000}, {0x3c602000}, {0x3c604000}, {0x3c606000}, + {0x3c608000}, {0x3c60a000}, {0x3c60c000}, {0x3c60e000}, + {0x3c610000}, {0x3c612000}, {0x3c614000}, {0x3c616000}, + {0x3c618000}, {0x3c61a000}, {0x3c61c000}, {0x3c61e000}, + {0x3c620000}, {0x3c622000}, {0x3c624000}, {0x3c626000}, + {0x3c628000}, {0x3c62a000}, {0x3c62c000}, {0x3c62e000}, + {0x3c630000}, {0x3c632000}, {0x3c634000}, {0x3c636000}, + {0x3c638000}, {0x3c63a000}, {0x3c63c000}, {0x3c63e000}, + {0x3c640000}, {0x3c642000}, {0x3c644000}, {0x3c646000}, + {0x3c648000}, {0x3c64a000}, {0x3c64c000}, {0x3c64e000}, + {0x3c650000}, {0x3c652000}, {0x3c654000}, {0x3c656000}, + {0x3c658000}, {0x3c65a000}, {0x3c65c000}, {0x3c65e000}, + {0x3c660000}, {0x3c662000}, {0x3c664000}, {0x3c666000}, + {0x3c668000}, {0x3c66a000}, {0x3c66c000}, {0x3c66e000}, + {0x3c670000}, {0x3c672000}, {0x3c674000}, {0x3c676000}, + {0x3c678000}, {0x3c67a000}, {0x3c67c000}, {0x3c67e000}, + {0x3c680000}, {0x3c682000}, {0x3c684000}, {0x3c686000}, + {0x3c688000}, {0x3c68a000}, {0x3c68c000}, {0x3c68e000}, + {0x3c690000}, {0x3c692000}, {0x3c694000}, {0x3c696000}, + {0x3c698000}, {0x3c69a000}, {0x3c69c000}, {0x3c69e000}, + {0x3c6a0000}, {0x3c6a2000}, {0x3c6a4000}, {0x3c6a6000}, + {0x3c6a8000}, {0x3c6aa000}, {0x3c6ac000}, {0x3c6ae000}, + {0x3c6b0000}, {0x3c6b2000}, {0x3c6b4000}, {0x3c6b6000}, + {0x3c6b8000}, {0x3c6ba000}, {0x3c6bc000}, {0x3c6be000}, + {0x3c6c0000}, {0x3c6c2000}, {0x3c6c4000}, {0x3c6c6000}, + {0x3c6c8000}, {0x3c6ca000}, {0x3c6cc000}, {0x3c6ce000}, + {0x3c6d0000}, {0x3c6d2000}, {0x3c6d4000}, {0x3c6d6000}, + {0x3c6d8000}, {0x3c6da000}, {0x3c6dc000}, {0x3c6de000}, + {0x3c6e0000}, {0x3c6e2000}, {0x3c6e4000}, {0x3c6e6000}, + {0x3c6e8000}, {0x3c6ea000}, {0x3c6ec000}, {0x3c6ee000}, + {0x3c6f0000}, {0x3c6f2000}, {0x3c6f4000}, {0x3c6f6000}, + {0x3c6f8000}, {0x3c6fa000}, {0x3c6fc000}, {0x3c6fe000}, + {0x3c700000}, {0x3c702000}, {0x3c704000}, {0x3c706000}, + {0x3c708000}, {0x3c70a000}, {0x3c70c000}, {0x3c70e000}, + {0x3c710000}, {0x3c712000}, {0x3c714000}, {0x3c716000}, + {0x3c718000}, {0x3c71a000}, {0x3c71c000}, {0x3c71e000}, + {0x3c720000}, {0x3c722000}, {0x3c724000}, {0x3c726000}, + {0x3c728000}, {0x3c72a000}, {0x3c72c000}, {0x3c72e000}, + {0x3c730000}, {0x3c732000}, {0x3c734000}, {0x3c736000}, + {0x3c738000}, {0x3c73a000}, {0x3c73c000}, {0x3c73e000}, + {0x3c740000}, {0x3c742000}, {0x3c744000}, {0x3c746000}, + {0x3c748000}, {0x3c74a000}, {0x3c74c000}, {0x3c74e000}, + {0x3c750000}, {0x3c752000}, {0x3c754000}, {0x3c756000}, + {0x3c758000}, {0x3c75a000}, {0x3c75c000}, {0x3c75e000}, + {0x3c760000}, {0x3c762000}, {0x3c764000}, {0x3c766000}, + {0x3c768000}, {0x3c76a000}, {0x3c76c000}, {0x3c76e000}, + {0x3c770000}, {0x3c772000}, {0x3c774000}, {0x3c776000}, + {0x3c778000}, {0x3c77a000}, {0x3c77c000}, {0x3c77e000}, + {0x3c780000}, {0x3c782000}, {0x3c784000}, {0x3c786000}, + {0x3c788000}, {0x3c78a000}, {0x3c78c000}, {0x3c78e000}, + {0x3c790000}, {0x3c792000}, {0x3c794000}, {0x3c796000}, + {0x3c798000}, {0x3c79a000}, {0x3c79c000}, {0x3c79e000}, + {0x3c7a0000}, {0x3c7a2000}, {0x3c7a4000}, {0x3c7a6000}, + {0x3c7a8000}, {0x3c7aa000}, {0x3c7ac000}, {0x3c7ae000}, + {0x3c7b0000}, {0x3c7b2000}, {0x3c7b4000}, {0x3c7b6000}, + {0x3c7b8000}, {0x3c7ba000}, {0x3c7bc000}, {0x3c7be000}, + {0x3c7c0000}, {0x3c7c2000}, {0x3c7c4000}, {0x3c7c6000}, + {0x3c7c8000}, {0x3c7ca000}, {0x3c7cc000}, {0x3c7ce000}, + {0x3c7d0000}, {0x3c7d2000}, {0x3c7d4000}, {0x3c7d6000}, + {0x3c7d8000}, {0x3c7da000}, {0x3c7dc000}, {0x3c7de000}, + {0x3c7e0000}, {0x3c7e2000}, {0x3c7e4000}, {0x3c7e6000}, + {0x3c7e8000}, {0x3c7ea000}, {0x3c7ec000}, {0x3c7ee000}, + {0x3c7f0000}, {0x3c7f2000}, {0x3c7f4000}, {0x3c7f6000}, + {0x3c7f8000}, {0x3c7fa000}, {0x3c7fc000}, {0x3c7fe000}, + {0x3c800000}, {0x3c802000}, {0x3c804000}, {0x3c806000}, + {0x3c808000}, {0x3c80a000}, {0x3c80c000}, {0x3c80e000}, + {0x3c810000}, {0x3c812000}, {0x3c814000}, {0x3c816000}, + {0x3c818000}, {0x3c81a000}, {0x3c81c000}, {0x3c81e000}, + {0x3c820000}, {0x3c822000}, {0x3c824000}, {0x3c826000}, + {0x3c828000}, {0x3c82a000}, {0x3c82c000}, {0x3c82e000}, + {0x3c830000}, {0x3c832000}, {0x3c834000}, {0x3c836000}, + {0x3c838000}, {0x3c83a000}, {0x3c83c000}, {0x3c83e000}, + {0x3c840000}, {0x3c842000}, {0x3c844000}, {0x3c846000}, + {0x3c848000}, {0x3c84a000}, {0x3c84c000}, {0x3c84e000}, + {0x3c850000}, {0x3c852000}, {0x3c854000}, {0x3c856000}, + {0x3c858000}, {0x3c85a000}, {0x3c85c000}, {0x3c85e000}, + {0x3c860000}, {0x3c862000}, {0x3c864000}, {0x3c866000}, + {0x3c868000}, {0x3c86a000}, {0x3c86c000}, {0x3c86e000}, + {0x3c870000}, {0x3c872000}, {0x3c874000}, {0x3c876000}, + {0x3c878000}, {0x3c87a000}, {0x3c87c000}, {0x3c87e000}, + {0x3c880000}, {0x3c882000}, {0x3c884000}, {0x3c886000}, + {0x3c888000}, {0x3c88a000}, {0x3c88c000}, {0x3c88e000}, + {0x3c890000}, {0x3c892000}, {0x3c894000}, {0x3c896000}, + {0x3c898000}, {0x3c89a000}, {0x3c89c000}, {0x3c89e000}, + {0x3c8a0000}, {0x3c8a2000}, {0x3c8a4000}, {0x3c8a6000}, + {0x3c8a8000}, {0x3c8aa000}, {0x3c8ac000}, {0x3c8ae000}, + {0x3c8b0000}, {0x3c8b2000}, {0x3c8b4000}, {0x3c8b6000}, + {0x3c8b8000}, {0x3c8ba000}, {0x3c8bc000}, {0x3c8be000}, + {0x3c8c0000}, {0x3c8c2000}, {0x3c8c4000}, {0x3c8c6000}, + {0x3c8c8000}, {0x3c8ca000}, {0x3c8cc000}, {0x3c8ce000}, + {0x3c8d0000}, {0x3c8d2000}, {0x3c8d4000}, {0x3c8d6000}, + {0x3c8d8000}, {0x3c8da000}, {0x3c8dc000}, {0x3c8de000}, + {0x3c8e0000}, {0x3c8e2000}, {0x3c8e4000}, {0x3c8e6000}, + {0x3c8e8000}, {0x3c8ea000}, {0x3c8ec000}, {0x3c8ee000}, + {0x3c8f0000}, {0x3c8f2000}, {0x3c8f4000}, {0x3c8f6000}, + {0x3c8f8000}, {0x3c8fa000}, {0x3c8fc000}, {0x3c8fe000}, + {0x3c900000}, {0x3c902000}, {0x3c904000}, {0x3c906000}, + {0x3c908000}, {0x3c90a000}, {0x3c90c000}, {0x3c90e000}, + {0x3c910000}, {0x3c912000}, {0x3c914000}, {0x3c916000}, + {0x3c918000}, {0x3c91a000}, {0x3c91c000}, {0x3c91e000}, + {0x3c920000}, {0x3c922000}, {0x3c924000}, {0x3c926000}, + {0x3c928000}, {0x3c92a000}, {0x3c92c000}, {0x3c92e000}, + {0x3c930000}, {0x3c932000}, {0x3c934000}, {0x3c936000}, + {0x3c938000}, {0x3c93a000}, {0x3c93c000}, {0x3c93e000}, + {0x3c940000}, {0x3c942000}, {0x3c944000}, {0x3c946000}, + {0x3c948000}, {0x3c94a000}, {0x3c94c000}, {0x3c94e000}, + {0x3c950000}, {0x3c952000}, {0x3c954000}, {0x3c956000}, + {0x3c958000}, {0x3c95a000}, {0x3c95c000}, {0x3c95e000}, + {0x3c960000}, {0x3c962000}, {0x3c964000}, {0x3c966000}, + {0x3c968000}, {0x3c96a000}, {0x3c96c000}, {0x3c96e000}, + {0x3c970000}, {0x3c972000}, {0x3c974000}, {0x3c976000}, + {0x3c978000}, {0x3c97a000}, {0x3c97c000}, {0x3c97e000}, + {0x3c980000}, {0x3c982000}, {0x3c984000}, {0x3c986000}, + {0x3c988000}, {0x3c98a000}, {0x3c98c000}, {0x3c98e000}, + {0x3c990000}, {0x3c992000}, {0x3c994000}, {0x3c996000}, + {0x3c998000}, {0x3c99a000}, {0x3c99c000}, {0x3c99e000}, + {0x3c9a0000}, {0x3c9a2000}, {0x3c9a4000}, {0x3c9a6000}, + {0x3c9a8000}, {0x3c9aa000}, {0x3c9ac000}, {0x3c9ae000}, + {0x3c9b0000}, {0x3c9b2000}, {0x3c9b4000}, {0x3c9b6000}, + {0x3c9b8000}, {0x3c9ba000}, {0x3c9bc000}, {0x3c9be000}, + {0x3c9c0000}, {0x3c9c2000}, {0x3c9c4000}, {0x3c9c6000}, + {0x3c9c8000}, {0x3c9ca000}, {0x3c9cc000}, {0x3c9ce000}, + {0x3c9d0000}, {0x3c9d2000}, {0x3c9d4000}, {0x3c9d6000}, + {0x3c9d8000}, {0x3c9da000}, {0x3c9dc000}, {0x3c9de000}, + {0x3c9e0000}, {0x3c9e2000}, {0x3c9e4000}, {0x3c9e6000}, + {0x3c9e8000}, {0x3c9ea000}, {0x3c9ec000}, {0x3c9ee000}, + {0x3c9f0000}, {0x3c9f2000}, {0x3c9f4000}, {0x3c9f6000}, + {0x3c9f8000}, {0x3c9fa000}, {0x3c9fc000}, {0x3c9fe000}, + {0x3ca00000}, {0x3ca02000}, {0x3ca04000}, {0x3ca06000}, + {0x3ca08000}, {0x3ca0a000}, {0x3ca0c000}, {0x3ca0e000}, + {0x3ca10000}, {0x3ca12000}, {0x3ca14000}, {0x3ca16000}, + {0x3ca18000}, {0x3ca1a000}, {0x3ca1c000}, {0x3ca1e000}, + {0x3ca20000}, {0x3ca22000}, {0x3ca24000}, {0x3ca26000}, + {0x3ca28000}, {0x3ca2a000}, {0x3ca2c000}, {0x3ca2e000}, + {0x3ca30000}, {0x3ca32000}, {0x3ca34000}, {0x3ca36000}, + {0x3ca38000}, {0x3ca3a000}, {0x3ca3c000}, {0x3ca3e000}, + {0x3ca40000}, {0x3ca42000}, {0x3ca44000}, {0x3ca46000}, + {0x3ca48000}, {0x3ca4a000}, {0x3ca4c000}, {0x3ca4e000}, + {0x3ca50000}, {0x3ca52000}, {0x3ca54000}, {0x3ca56000}, + {0x3ca58000}, {0x3ca5a000}, {0x3ca5c000}, {0x3ca5e000}, + {0x3ca60000}, {0x3ca62000}, {0x3ca64000}, {0x3ca66000}, + {0x3ca68000}, {0x3ca6a000}, {0x3ca6c000}, {0x3ca6e000}, + {0x3ca70000}, {0x3ca72000}, {0x3ca74000}, {0x3ca76000}, + {0x3ca78000}, {0x3ca7a000}, {0x3ca7c000}, {0x3ca7e000}, + {0x3ca80000}, {0x3ca82000}, {0x3ca84000}, {0x3ca86000}, + {0x3ca88000}, {0x3ca8a000}, {0x3ca8c000}, {0x3ca8e000}, + {0x3ca90000}, {0x3ca92000}, {0x3ca94000}, {0x3ca96000}, + {0x3ca98000}, {0x3ca9a000}, {0x3ca9c000}, {0x3ca9e000}, + {0x3caa0000}, {0x3caa2000}, {0x3caa4000}, {0x3caa6000}, + {0x3caa8000}, {0x3caaa000}, {0x3caac000}, {0x3caae000}, + {0x3cab0000}, {0x3cab2000}, {0x3cab4000}, {0x3cab6000}, + {0x3cab8000}, {0x3caba000}, {0x3cabc000}, {0x3cabe000}, + {0x3cac0000}, {0x3cac2000}, {0x3cac4000}, {0x3cac6000}, + {0x3cac8000}, {0x3caca000}, {0x3cacc000}, {0x3cace000}, + {0x3cad0000}, {0x3cad2000}, {0x3cad4000}, {0x3cad6000}, + {0x3cad8000}, {0x3cada000}, {0x3cadc000}, {0x3cade000}, + {0x3cae0000}, {0x3cae2000}, {0x3cae4000}, {0x3cae6000}, + {0x3cae8000}, {0x3caea000}, {0x3caec000}, {0x3caee000}, + {0x3caf0000}, {0x3caf2000}, {0x3caf4000}, {0x3caf6000}, + {0x3caf8000}, {0x3cafa000}, {0x3cafc000}, {0x3cafe000}, + {0x3cb00000}, {0x3cb02000}, {0x3cb04000}, {0x3cb06000}, + {0x3cb08000}, {0x3cb0a000}, {0x3cb0c000}, {0x3cb0e000}, + {0x3cb10000}, {0x3cb12000}, {0x3cb14000}, {0x3cb16000}, + {0x3cb18000}, {0x3cb1a000}, {0x3cb1c000}, {0x3cb1e000}, + {0x3cb20000}, {0x3cb22000}, {0x3cb24000}, {0x3cb26000}, + {0x3cb28000}, {0x3cb2a000}, {0x3cb2c000}, {0x3cb2e000}, + {0x3cb30000}, {0x3cb32000}, {0x3cb34000}, {0x3cb36000}, + {0x3cb38000}, {0x3cb3a000}, {0x3cb3c000}, {0x3cb3e000}, + {0x3cb40000}, {0x3cb42000}, {0x3cb44000}, {0x3cb46000}, + {0x3cb48000}, {0x3cb4a000}, {0x3cb4c000}, {0x3cb4e000}, + {0x3cb50000}, {0x3cb52000}, {0x3cb54000}, {0x3cb56000}, + {0x3cb58000}, {0x3cb5a000}, {0x3cb5c000}, {0x3cb5e000}, + {0x3cb60000}, {0x3cb62000}, {0x3cb64000}, {0x3cb66000}, + {0x3cb68000}, {0x3cb6a000}, {0x3cb6c000}, {0x3cb6e000}, + {0x3cb70000}, {0x3cb72000}, {0x3cb74000}, {0x3cb76000}, + {0x3cb78000}, {0x3cb7a000}, {0x3cb7c000}, {0x3cb7e000}, + {0x3cb80000}, {0x3cb82000}, {0x3cb84000}, {0x3cb86000}, + {0x3cb88000}, {0x3cb8a000}, {0x3cb8c000}, {0x3cb8e000}, + {0x3cb90000}, {0x3cb92000}, {0x3cb94000}, {0x3cb96000}, + {0x3cb98000}, {0x3cb9a000}, {0x3cb9c000}, {0x3cb9e000}, + {0x3cba0000}, {0x3cba2000}, {0x3cba4000}, {0x3cba6000}, + {0x3cba8000}, {0x3cbaa000}, {0x3cbac000}, {0x3cbae000}, + {0x3cbb0000}, {0x3cbb2000}, {0x3cbb4000}, {0x3cbb6000}, + {0x3cbb8000}, {0x3cbba000}, {0x3cbbc000}, {0x3cbbe000}, + {0x3cbc0000}, {0x3cbc2000}, {0x3cbc4000}, {0x3cbc6000}, + {0x3cbc8000}, {0x3cbca000}, {0x3cbcc000}, {0x3cbce000}, + {0x3cbd0000}, {0x3cbd2000}, {0x3cbd4000}, {0x3cbd6000}, + {0x3cbd8000}, {0x3cbda000}, {0x3cbdc000}, {0x3cbde000}, + {0x3cbe0000}, {0x3cbe2000}, {0x3cbe4000}, {0x3cbe6000}, + {0x3cbe8000}, {0x3cbea000}, {0x3cbec000}, {0x3cbee000}, + {0x3cbf0000}, {0x3cbf2000}, {0x3cbf4000}, {0x3cbf6000}, + {0x3cbf8000}, {0x3cbfa000}, {0x3cbfc000}, {0x3cbfe000}, + {0x3cc00000}, {0x3cc02000}, {0x3cc04000}, {0x3cc06000}, + {0x3cc08000}, {0x3cc0a000}, {0x3cc0c000}, {0x3cc0e000}, + {0x3cc10000}, {0x3cc12000}, {0x3cc14000}, {0x3cc16000}, + {0x3cc18000}, {0x3cc1a000}, {0x3cc1c000}, {0x3cc1e000}, + {0x3cc20000}, {0x3cc22000}, {0x3cc24000}, {0x3cc26000}, + {0x3cc28000}, {0x3cc2a000}, {0x3cc2c000}, {0x3cc2e000}, + {0x3cc30000}, {0x3cc32000}, {0x3cc34000}, {0x3cc36000}, + {0x3cc38000}, {0x3cc3a000}, {0x3cc3c000}, {0x3cc3e000}, + {0x3cc40000}, {0x3cc42000}, {0x3cc44000}, {0x3cc46000}, + {0x3cc48000}, {0x3cc4a000}, {0x3cc4c000}, {0x3cc4e000}, + {0x3cc50000}, {0x3cc52000}, {0x3cc54000}, {0x3cc56000}, + {0x3cc58000}, {0x3cc5a000}, {0x3cc5c000}, {0x3cc5e000}, + {0x3cc60000}, {0x3cc62000}, {0x3cc64000}, {0x3cc66000}, + {0x3cc68000}, {0x3cc6a000}, {0x3cc6c000}, {0x3cc6e000}, + {0x3cc70000}, {0x3cc72000}, {0x3cc74000}, {0x3cc76000}, + {0x3cc78000}, {0x3cc7a000}, {0x3cc7c000}, {0x3cc7e000}, + {0x3cc80000}, {0x3cc82000}, {0x3cc84000}, {0x3cc86000}, + {0x3cc88000}, {0x3cc8a000}, {0x3cc8c000}, {0x3cc8e000}, + {0x3cc90000}, {0x3cc92000}, {0x3cc94000}, {0x3cc96000}, + {0x3cc98000}, {0x3cc9a000}, {0x3cc9c000}, {0x3cc9e000}, + {0x3cca0000}, {0x3cca2000}, {0x3cca4000}, {0x3cca6000}, + {0x3cca8000}, {0x3ccaa000}, {0x3ccac000}, {0x3ccae000}, + {0x3ccb0000}, {0x3ccb2000}, {0x3ccb4000}, {0x3ccb6000}, + {0x3ccb8000}, {0x3ccba000}, {0x3ccbc000}, {0x3ccbe000}, + {0x3ccc0000}, {0x3ccc2000}, {0x3ccc4000}, {0x3ccc6000}, + {0x3ccc8000}, {0x3ccca000}, {0x3cccc000}, {0x3ccce000}, + {0x3ccd0000}, {0x3ccd2000}, {0x3ccd4000}, {0x3ccd6000}, + {0x3ccd8000}, {0x3ccda000}, {0x3ccdc000}, {0x3ccde000}, + {0x3cce0000}, {0x3cce2000}, {0x3cce4000}, {0x3cce6000}, + {0x3cce8000}, {0x3ccea000}, {0x3ccec000}, {0x3ccee000}, + {0x3ccf0000}, {0x3ccf2000}, {0x3ccf4000}, {0x3ccf6000}, + {0x3ccf8000}, {0x3ccfa000}, {0x3ccfc000}, {0x3ccfe000}, + {0x3cd00000}, {0x3cd02000}, {0x3cd04000}, {0x3cd06000}, + {0x3cd08000}, {0x3cd0a000}, {0x3cd0c000}, {0x3cd0e000}, + {0x3cd10000}, {0x3cd12000}, {0x3cd14000}, {0x3cd16000}, + {0x3cd18000}, {0x3cd1a000}, {0x3cd1c000}, {0x3cd1e000}, + {0x3cd20000}, {0x3cd22000}, {0x3cd24000}, {0x3cd26000}, + {0x3cd28000}, {0x3cd2a000}, {0x3cd2c000}, {0x3cd2e000}, + {0x3cd30000}, {0x3cd32000}, {0x3cd34000}, {0x3cd36000}, + {0x3cd38000}, {0x3cd3a000}, {0x3cd3c000}, {0x3cd3e000}, + {0x3cd40000}, {0x3cd42000}, {0x3cd44000}, {0x3cd46000}, + {0x3cd48000}, {0x3cd4a000}, {0x3cd4c000}, {0x3cd4e000}, + {0x3cd50000}, {0x3cd52000}, {0x3cd54000}, {0x3cd56000}, + {0x3cd58000}, {0x3cd5a000}, {0x3cd5c000}, {0x3cd5e000}, + {0x3cd60000}, {0x3cd62000}, {0x3cd64000}, {0x3cd66000}, + {0x3cd68000}, {0x3cd6a000}, {0x3cd6c000}, {0x3cd6e000}, + {0x3cd70000}, {0x3cd72000}, {0x3cd74000}, {0x3cd76000}, + {0x3cd78000}, {0x3cd7a000}, {0x3cd7c000}, {0x3cd7e000}, + {0x3cd80000}, {0x3cd82000}, {0x3cd84000}, {0x3cd86000}, + {0x3cd88000}, {0x3cd8a000}, {0x3cd8c000}, {0x3cd8e000}, + {0x3cd90000}, {0x3cd92000}, {0x3cd94000}, {0x3cd96000}, + {0x3cd98000}, {0x3cd9a000}, {0x3cd9c000}, {0x3cd9e000}, + {0x3cda0000}, {0x3cda2000}, {0x3cda4000}, {0x3cda6000}, + {0x3cda8000}, {0x3cdaa000}, {0x3cdac000}, {0x3cdae000}, + {0x3cdb0000}, {0x3cdb2000}, {0x3cdb4000}, {0x3cdb6000}, + {0x3cdb8000}, {0x3cdba000}, {0x3cdbc000}, {0x3cdbe000}, + {0x3cdc0000}, {0x3cdc2000}, {0x3cdc4000}, {0x3cdc6000}, + {0x3cdc8000}, {0x3cdca000}, {0x3cdcc000}, {0x3cdce000}, + {0x3cdd0000}, {0x3cdd2000}, {0x3cdd4000}, {0x3cdd6000}, + {0x3cdd8000}, {0x3cdda000}, {0x3cddc000}, {0x3cdde000}, + {0x3cde0000}, {0x3cde2000}, {0x3cde4000}, {0x3cde6000}, + {0x3cde8000}, {0x3cdea000}, {0x3cdec000}, {0x3cdee000}, + {0x3cdf0000}, {0x3cdf2000}, {0x3cdf4000}, {0x3cdf6000}, + {0x3cdf8000}, {0x3cdfa000}, {0x3cdfc000}, {0x3cdfe000}, + {0x3ce00000}, {0x3ce02000}, {0x3ce04000}, {0x3ce06000}, + {0x3ce08000}, {0x3ce0a000}, {0x3ce0c000}, {0x3ce0e000}, + {0x3ce10000}, {0x3ce12000}, {0x3ce14000}, {0x3ce16000}, + {0x3ce18000}, {0x3ce1a000}, {0x3ce1c000}, {0x3ce1e000}, + {0x3ce20000}, {0x3ce22000}, {0x3ce24000}, {0x3ce26000}, + {0x3ce28000}, {0x3ce2a000}, {0x3ce2c000}, {0x3ce2e000}, + {0x3ce30000}, {0x3ce32000}, {0x3ce34000}, {0x3ce36000}, + {0x3ce38000}, {0x3ce3a000}, {0x3ce3c000}, {0x3ce3e000}, + {0x3ce40000}, {0x3ce42000}, {0x3ce44000}, {0x3ce46000}, + {0x3ce48000}, {0x3ce4a000}, {0x3ce4c000}, {0x3ce4e000}, + {0x3ce50000}, {0x3ce52000}, {0x3ce54000}, {0x3ce56000}, + {0x3ce58000}, {0x3ce5a000}, {0x3ce5c000}, {0x3ce5e000}, + {0x3ce60000}, {0x3ce62000}, {0x3ce64000}, {0x3ce66000}, + {0x3ce68000}, {0x3ce6a000}, {0x3ce6c000}, {0x3ce6e000}, + {0x3ce70000}, {0x3ce72000}, {0x3ce74000}, {0x3ce76000}, + {0x3ce78000}, {0x3ce7a000}, {0x3ce7c000}, {0x3ce7e000}, + {0x3ce80000}, {0x3ce82000}, {0x3ce84000}, {0x3ce86000}, + {0x3ce88000}, {0x3ce8a000}, {0x3ce8c000}, {0x3ce8e000}, + {0x3ce90000}, {0x3ce92000}, {0x3ce94000}, {0x3ce96000}, + {0x3ce98000}, {0x3ce9a000}, {0x3ce9c000}, {0x3ce9e000}, + {0x3cea0000}, {0x3cea2000}, {0x3cea4000}, {0x3cea6000}, + {0x3cea8000}, {0x3ceaa000}, {0x3ceac000}, {0x3ceae000}, + {0x3ceb0000}, {0x3ceb2000}, {0x3ceb4000}, {0x3ceb6000}, + {0x3ceb8000}, {0x3ceba000}, {0x3cebc000}, {0x3cebe000}, + {0x3cec0000}, {0x3cec2000}, {0x3cec4000}, {0x3cec6000}, + {0x3cec8000}, {0x3ceca000}, {0x3cecc000}, {0x3cece000}, + {0x3ced0000}, {0x3ced2000}, {0x3ced4000}, {0x3ced6000}, + {0x3ced8000}, {0x3ceda000}, {0x3cedc000}, {0x3cede000}, + {0x3cee0000}, {0x3cee2000}, {0x3cee4000}, {0x3cee6000}, + {0x3cee8000}, {0x3ceea000}, {0x3ceec000}, {0x3ceee000}, + {0x3cef0000}, {0x3cef2000}, {0x3cef4000}, {0x3cef6000}, + {0x3cef8000}, {0x3cefa000}, {0x3cefc000}, {0x3cefe000}, + {0x3cf00000}, {0x3cf02000}, {0x3cf04000}, {0x3cf06000}, + {0x3cf08000}, {0x3cf0a000}, {0x3cf0c000}, {0x3cf0e000}, + {0x3cf10000}, {0x3cf12000}, {0x3cf14000}, {0x3cf16000}, + {0x3cf18000}, {0x3cf1a000}, {0x3cf1c000}, {0x3cf1e000}, + {0x3cf20000}, {0x3cf22000}, {0x3cf24000}, {0x3cf26000}, + {0x3cf28000}, {0x3cf2a000}, {0x3cf2c000}, {0x3cf2e000}, + {0x3cf30000}, {0x3cf32000}, {0x3cf34000}, {0x3cf36000}, + {0x3cf38000}, {0x3cf3a000}, {0x3cf3c000}, {0x3cf3e000}, + {0x3cf40000}, {0x3cf42000}, {0x3cf44000}, {0x3cf46000}, + {0x3cf48000}, {0x3cf4a000}, {0x3cf4c000}, {0x3cf4e000}, + {0x3cf50000}, {0x3cf52000}, {0x3cf54000}, {0x3cf56000}, + {0x3cf58000}, {0x3cf5a000}, {0x3cf5c000}, {0x3cf5e000}, + {0x3cf60000}, {0x3cf62000}, {0x3cf64000}, {0x3cf66000}, + {0x3cf68000}, {0x3cf6a000}, {0x3cf6c000}, {0x3cf6e000}, + {0x3cf70000}, {0x3cf72000}, {0x3cf74000}, {0x3cf76000}, + {0x3cf78000}, {0x3cf7a000}, {0x3cf7c000}, {0x3cf7e000}, + {0x3cf80000}, {0x3cf82000}, {0x3cf84000}, {0x3cf86000}, + {0x3cf88000}, {0x3cf8a000}, {0x3cf8c000}, {0x3cf8e000}, + {0x3cf90000}, {0x3cf92000}, {0x3cf94000}, {0x3cf96000}, + {0x3cf98000}, {0x3cf9a000}, {0x3cf9c000}, {0x3cf9e000}, + {0x3cfa0000}, {0x3cfa2000}, {0x3cfa4000}, {0x3cfa6000}, + {0x3cfa8000}, {0x3cfaa000}, {0x3cfac000}, {0x3cfae000}, + {0x3cfb0000}, {0x3cfb2000}, {0x3cfb4000}, {0x3cfb6000}, + {0x3cfb8000}, {0x3cfba000}, {0x3cfbc000}, {0x3cfbe000}, + {0x3cfc0000}, {0x3cfc2000}, {0x3cfc4000}, {0x3cfc6000}, + {0x3cfc8000}, {0x3cfca000}, {0x3cfcc000}, {0x3cfce000}, + {0x3cfd0000}, {0x3cfd2000}, {0x3cfd4000}, {0x3cfd6000}, + {0x3cfd8000}, {0x3cfda000}, {0x3cfdc000}, {0x3cfde000}, + {0x3cfe0000}, {0x3cfe2000}, {0x3cfe4000}, {0x3cfe6000}, + {0x3cfe8000}, {0x3cfea000}, {0x3cfec000}, {0x3cfee000}, + {0x3cff0000}, {0x3cff2000}, {0x3cff4000}, {0x3cff6000}, + {0x3cff8000}, {0x3cffa000}, {0x3cffc000}, {0x3cffe000}, + {0x3d000000}, {0x3d002000}, {0x3d004000}, {0x3d006000}, + {0x3d008000}, {0x3d00a000}, {0x3d00c000}, {0x3d00e000}, + {0x3d010000}, {0x3d012000}, {0x3d014000}, {0x3d016000}, + {0x3d018000}, {0x3d01a000}, {0x3d01c000}, {0x3d01e000}, + {0x3d020000}, {0x3d022000}, {0x3d024000}, {0x3d026000}, + {0x3d028000}, {0x3d02a000}, {0x3d02c000}, {0x3d02e000}, + {0x3d030000}, {0x3d032000}, {0x3d034000}, {0x3d036000}, + {0x3d038000}, {0x3d03a000}, {0x3d03c000}, {0x3d03e000}, + {0x3d040000}, {0x3d042000}, {0x3d044000}, {0x3d046000}, + {0x3d048000}, {0x3d04a000}, {0x3d04c000}, {0x3d04e000}, + {0x3d050000}, {0x3d052000}, {0x3d054000}, {0x3d056000}, + {0x3d058000}, {0x3d05a000}, {0x3d05c000}, {0x3d05e000}, + {0x3d060000}, {0x3d062000}, {0x3d064000}, {0x3d066000}, + {0x3d068000}, {0x3d06a000}, {0x3d06c000}, {0x3d06e000}, + {0x3d070000}, {0x3d072000}, {0x3d074000}, {0x3d076000}, + {0x3d078000}, {0x3d07a000}, {0x3d07c000}, {0x3d07e000}, + {0x3d080000}, {0x3d082000}, {0x3d084000}, {0x3d086000}, + {0x3d088000}, {0x3d08a000}, {0x3d08c000}, {0x3d08e000}, + {0x3d090000}, {0x3d092000}, {0x3d094000}, {0x3d096000}, + {0x3d098000}, {0x3d09a000}, {0x3d09c000}, {0x3d09e000}, + {0x3d0a0000}, {0x3d0a2000}, {0x3d0a4000}, {0x3d0a6000}, + {0x3d0a8000}, {0x3d0aa000}, {0x3d0ac000}, {0x3d0ae000}, + {0x3d0b0000}, {0x3d0b2000}, {0x3d0b4000}, {0x3d0b6000}, + {0x3d0b8000}, {0x3d0ba000}, {0x3d0bc000}, {0x3d0be000}, + {0x3d0c0000}, {0x3d0c2000}, {0x3d0c4000}, {0x3d0c6000}, + {0x3d0c8000}, {0x3d0ca000}, {0x3d0cc000}, {0x3d0ce000}, + {0x3d0d0000}, {0x3d0d2000}, {0x3d0d4000}, {0x3d0d6000}, + {0x3d0d8000}, {0x3d0da000}, {0x3d0dc000}, {0x3d0de000}, + {0x3d0e0000}, {0x3d0e2000}, {0x3d0e4000}, {0x3d0e6000}, + {0x3d0e8000}, {0x3d0ea000}, {0x3d0ec000}, {0x3d0ee000}, + {0x3d0f0000}, {0x3d0f2000}, {0x3d0f4000}, {0x3d0f6000}, + {0x3d0f8000}, {0x3d0fa000}, {0x3d0fc000}, {0x3d0fe000}, + {0x3d100000}, {0x3d102000}, {0x3d104000}, {0x3d106000}, + {0x3d108000}, {0x3d10a000}, {0x3d10c000}, {0x3d10e000}, + {0x3d110000}, {0x3d112000}, {0x3d114000}, {0x3d116000}, + {0x3d118000}, {0x3d11a000}, {0x3d11c000}, {0x3d11e000}, + {0x3d120000}, {0x3d122000}, {0x3d124000}, {0x3d126000}, + {0x3d128000}, {0x3d12a000}, {0x3d12c000}, {0x3d12e000}, + {0x3d130000}, {0x3d132000}, {0x3d134000}, {0x3d136000}, + {0x3d138000}, {0x3d13a000}, {0x3d13c000}, {0x3d13e000}, + {0x3d140000}, {0x3d142000}, {0x3d144000}, {0x3d146000}, + {0x3d148000}, {0x3d14a000}, {0x3d14c000}, {0x3d14e000}, + {0x3d150000}, {0x3d152000}, {0x3d154000}, {0x3d156000}, + {0x3d158000}, {0x3d15a000}, {0x3d15c000}, {0x3d15e000}, + {0x3d160000}, {0x3d162000}, {0x3d164000}, {0x3d166000}, + {0x3d168000}, {0x3d16a000}, {0x3d16c000}, {0x3d16e000}, + {0x3d170000}, {0x3d172000}, {0x3d174000}, {0x3d176000}, + {0x3d178000}, {0x3d17a000}, {0x3d17c000}, {0x3d17e000}, + {0x3d180000}, {0x3d182000}, {0x3d184000}, {0x3d186000}, + {0x3d188000}, {0x3d18a000}, {0x3d18c000}, {0x3d18e000}, + {0x3d190000}, {0x3d192000}, {0x3d194000}, {0x3d196000}, + {0x3d198000}, {0x3d19a000}, {0x3d19c000}, {0x3d19e000}, + {0x3d1a0000}, {0x3d1a2000}, {0x3d1a4000}, {0x3d1a6000}, + {0x3d1a8000}, {0x3d1aa000}, {0x3d1ac000}, {0x3d1ae000}, + {0x3d1b0000}, {0x3d1b2000}, {0x3d1b4000}, {0x3d1b6000}, + {0x3d1b8000}, {0x3d1ba000}, {0x3d1bc000}, {0x3d1be000}, + {0x3d1c0000}, {0x3d1c2000}, {0x3d1c4000}, {0x3d1c6000}, + {0x3d1c8000}, {0x3d1ca000}, {0x3d1cc000}, {0x3d1ce000}, + {0x3d1d0000}, {0x3d1d2000}, {0x3d1d4000}, {0x3d1d6000}, + {0x3d1d8000}, {0x3d1da000}, {0x3d1dc000}, {0x3d1de000}, + {0x3d1e0000}, {0x3d1e2000}, {0x3d1e4000}, {0x3d1e6000}, + {0x3d1e8000}, {0x3d1ea000}, {0x3d1ec000}, {0x3d1ee000}, + {0x3d1f0000}, {0x3d1f2000}, {0x3d1f4000}, {0x3d1f6000}, + {0x3d1f8000}, {0x3d1fa000}, {0x3d1fc000}, {0x3d1fe000}, + {0x3d200000}, {0x3d202000}, {0x3d204000}, {0x3d206000}, + {0x3d208000}, {0x3d20a000}, {0x3d20c000}, {0x3d20e000}, + {0x3d210000}, {0x3d212000}, {0x3d214000}, {0x3d216000}, + {0x3d218000}, {0x3d21a000}, {0x3d21c000}, {0x3d21e000}, + {0x3d220000}, {0x3d222000}, {0x3d224000}, {0x3d226000}, + {0x3d228000}, {0x3d22a000}, {0x3d22c000}, {0x3d22e000}, + {0x3d230000}, {0x3d232000}, {0x3d234000}, {0x3d236000}, + {0x3d238000}, {0x3d23a000}, {0x3d23c000}, {0x3d23e000}, + {0x3d240000}, {0x3d242000}, {0x3d244000}, {0x3d246000}, + {0x3d248000}, {0x3d24a000}, {0x3d24c000}, {0x3d24e000}, + {0x3d250000}, {0x3d252000}, {0x3d254000}, {0x3d256000}, + {0x3d258000}, {0x3d25a000}, {0x3d25c000}, {0x3d25e000}, + {0x3d260000}, {0x3d262000}, {0x3d264000}, {0x3d266000}, + {0x3d268000}, {0x3d26a000}, {0x3d26c000}, {0x3d26e000}, + {0x3d270000}, {0x3d272000}, {0x3d274000}, {0x3d276000}, + {0x3d278000}, {0x3d27a000}, {0x3d27c000}, {0x3d27e000}, + {0x3d280000}, {0x3d282000}, {0x3d284000}, {0x3d286000}, + {0x3d288000}, {0x3d28a000}, {0x3d28c000}, {0x3d28e000}, + {0x3d290000}, {0x3d292000}, {0x3d294000}, {0x3d296000}, + {0x3d298000}, {0x3d29a000}, {0x3d29c000}, {0x3d29e000}, + {0x3d2a0000}, {0x3d2a2000}, {0x3d2a4000}, {0x3d2a6000}, + {0x3d2a8000}, {0x3d2aa000}, {0x3d2ac000}, {0x3d2ae000}, + {0x3d2b0000}, {0x3d2b2000}, {0x3d2b4000}, {0x3d2b6000}, + {0x3d2b8000}, {0x3d2ba000}, {0x3d2bc000}, {0x3d2be000}, + {0x3d2c0000}, {0x3d2c2000}, {0x3d2c4000}, {0x3d2c6000}, + {0x3d2c8000}, {0x3d2ca000}, {0x3d2cc000}, {0x3d2ce000}, + {0x3d2d0000}, {0x3d2d2000}, {0x3d2d4000}, {0x3d2d6000}, + {0x3d2d8000}, {0x3d2da000}, {0x3d2dc000}, {0x3d2de000}, + {0x3d2e0000}, {0x3d2e2000}, {0x3d2e4000}, {0x3d2e6000}, + {0x3d2e8000}, {0x3d2ea000}, {0x3d2ec000}, {0x3d2ee000}, + {0x3d2f0000}, {0x3d2f2000}, {0x3d2f4000}, {0x3d2f6000}, + {0x3d2f8000}, {0x3d2fa000}, {0x3d2fc000}, {0x3d2fe000}, + {0x3d300000}, {0x3d302000}, {0x3d304000}, {0x3d306000}, + {0x3d308000}, {0x3d30a000}, {0x3d30c000}, {0x3d30e000}, + {0x3d310000}, {0x3d312000}, {0x3d314000}, {0x3d316000}, + {0x3d318000}, {0x3d31a000}, {0x3d31c000}, {0x3d31e000}, + {0x3d320000}, {0x3d322000}, {0x3d324000}, {0x3d326000}, + {0x3d328000}, {0x3d32a000}, {0x3d32c000}, {0x3d32e000}, + {0x3d330000}, {0x3d332000}, {0x3d334000}, {0x3d336000}, + {0x3d338000}, {0x3d33a000}, {0x3d33c000}, {0x3d33e000}, + {0x3d340000}, {0x3d342000}, {0x3d344000}, {0x3d346000}, + {0x3d348000}, {0x3d34a000}, {0x3d34c000}, {0x3d34e000}, + {0x3d350000}, {0x3d352000}, {0x3d354000}, {0x3d356000}, + {0x3d358000}, {0x3d35a000}, {0x3d35c000}, {0x3d35e000}, + {0x3d360000}, {0x3d362000}, {0x3d364000}, {0x3d366000}, + {0x3d368000}, {0x3d36a000}, {0x3d36c000}, {0x3d36e000}, + {0x3d370000}, {0x3d372000}, {0x3d374000}, {0x3d376000}, + {0x3d378000}, {0x3d37a000}, {0x3d37c000}, {0x3d37e000}, + {0x3d380000}, {0x3d382000}, {0x3d384000}, {0x3d386000}, + {0x3d388000}, {0x3d38a000}, {0x3d38c000}, {0x3d38e000}, + {0x3d390000}, {0x3d392000}, {0x3d394000}, {0x3d396000}, + {0x3d398000}, {0x3d39a000}, {0x3d39c000}, {0x3d39e000}, + {0x3d3a0000}, {0x3d3a2000}, {0x3d3a4000}, {0x3d3a6000}, + {0x3d3a8000}, {0x3d3aa000}, {0x3d3ac000}, {0x3d3ae000}, + {0x3d3b0000}, {0x3d3b2000}, {0x3d3b4000}, {0x3d3b6000}, + {0x3d3b8000}, {0x3d3ba000}, {0x3d3bc000}, {0x3d3be000}, + {0x3d3c0000}, {0x3d3c2000}, {0x3d3c4000}, {0x3d3c6000}, + {0x3d3c8000}, {0x3d3ca000}, {0x3d3cc000}, {0x3d3ce000}, + {0x3d3d0000}, {0x3d3d2000}, {0x3d3d4000}, {0x3d3d6000}, + {0x3d3d8000}, {0x3d3da000}, {0x3d3dc000}, {0x3d3de000}, + {0x3d3e0000}, {0x3d3e2000}, {0x3d3e4000}, {0x3d3e6000}, + {0x3d3e8000}, {0x3d3ea000}, {0x3d3ec000}, {0x3d3ee000}, + {0x3d3f0000}, {0x3d3f2000}, {0x3d3f4000}, {0x3d3f6000}, + {0x3d3f8000}, {0x3d3fa000}, {0x3d3fc000}, {0x3d3fe000}, + {0x3d400000}, {0x3d402000}, {0x3d404000}, {0x3d406000}, + {0x3d408000}, {0x3d40a000}, {0x3d40c000}, {0x3d40e000}, + {0x3d410000}, {0x3d412000}, {0x3d414000}, {0x3d416000}, + {0x3d418000}, {0x3d41a000}, {0x3d41c000}, {0x3d41e000}, + {0x3d420000}, {0x3d422000}, {0x3d424000}, {0x3d426000}, + {0x3d428000}, {0x3d42a000}, {0x3d42c000}, {0x3d42e000}, + {0x3d430000}, {0x3d432000}, {0x3d434000}, {0x3d436000}, + {0x3d438000}, {0x3d43a000}, {0x3d43c000}, {0x3d43e000}, + {0x3d440000}, {0x3d442000}, {0x3d444000}, {0x3d446000}, + {0x3d448000}, {0x3d44a000}, {0x3d44c000}, {0x3d44e000}, + {0x3d450000}, {0x3d452000}, {0x3d454000}, {0x3d456000}, + {0x3d458000}, {0x3d45a000}, {0x3d45c000}, {0x3d45e000}, + {0x3d460000}, {0x3d462000}, {0x3d464000}, {0x3d466000}, + {0x3d468000}, {0x3d46a000}, {0x3d46c000}, {0x3d46e000}, + {0x3d470000}, {0x3d472000}, {0x3d474000}, {0x3d476000}, + {0x3d478000}, {0x3d47a000}, {0x3d47c000}, {0x3d47e000}, + {0x3d480000}, {0x3d482000}, {0x3d484000}, {0x3d486000}, + {0x3d488000}, {0x3d48a000}, {0x3d48c000}, {0x3d48e000}, + {0x3d490000}, {0x3d492000}, {0x3d494000}, {0x3d496000}, + {0x3d498000}, {0x3d49a000}, {0x3d49c000}, {0x3d49e000}, + {0x3d4a0000}, {0x3d4a2000}, {0x3d4a4000}, {0x3d4a6000}, + {0x3d4a8000}, {0x3d4aa000}, {0x3d4ac000}, {0x3d4ae000}, + {0x3d4b0000}, {0x3d4b2000}, {0x3d4b4000}, {0x3d4b6000}, + {0x3d4b8000}, {0x3d4ba000}, {0x3d4bc000}, {0x3d4be000}, + {0x3d4c0000}, {0x3d4c2000}, {0x3d4c4000}, {0x3d4c6000}, + {0x3d4c8000}, {0x3d4ca000}, {0x3d4cc000}, {0x3d4ce000}, + {0x3d4d0000}, {0x3d4d2000}, {0x3d4d4000}, {0x3d4d6000}, + {0x3d4d8000}, {0x3d4da000}, {0x3d4dc000}, {0x3d4de000}, + {0x3d4e0000}, {0x3d4e2000}, {0x3d4e4000}, {0x3d4e6000}, + {0x3d4e8000}, {0x3d4ea000}, {0x3d4ec000}, {0x3d4ee000}, + {0x3d4f0000}, {0x3d4f2000}, {0x3d4f4000}, {0x3d4f6000}, + {0x3d4f8000}, {0x3d4fa000}, {0x3d4fc000}, {0x3d4fe000}, + {0x3d500000}, {0x3d502000}, {0x3d504000}, {0x3d506000}, + {0x3d508000}, {0x3d50a000}, {0x3d50c000}, {0x3d50e000}, + {0x3d510000}, {0x3d512000}, {0x3d514000}, {0x3d516000}, + {0x3d518000}, {0x3d51a000}, {0x3d51c000}, {0x3d51e000}, + {0x3d520000}, {0x3d522000}, {0x3d524000}, {0x3d526000}, + {0x3d528000}, {0x3d52a000}, {0x3d52c000}, {0x3d52e000}, + {0x3d530000}, {0x3d532000}, {0x3d534000}, {0x3d536000}, + {0x3d538000}, {0x3d53a000}, {0x3d53c000}, {0x3d53e000}, + {0x3d540000}, {0x3d542000}, {0x3d544000}, {0x3d546000}, + {0x3d548000}, {0x3d54a000}, {0x3d54c000}, {0x3d54e000}, + {0x3d550000}, {0x3d552000}, {0x3d554000}, {0x3d556000}, + {0x3d558000}, {0x3d55a000}, {0x3d55c000}, {0x3d55e000}, + {0x3d560000}, {0x3d562000}, {0x3d564000}, {0x3d566000}, + {0x3d568000}, {0x3d56a000}, {0x3d56c000}, {0x3d56e000}, + {0x3d570000}, {0x3d572000}, {0x3d574000}, {0x3d576000}, + {0x3d578000}, {0x3d57a000}, {0x3d57c000}, {0x3d57e000}, + {0x3d580000}, {0x3d582000}, {0x3d584000}, {0x3d586000}, + {0x3d588000}, {0x3d58a000}, {0x3d58c000}, {0x3d58e000}, + {0x3d590000}, {0x3d592000}, {0x3d594000}, {0x3d596000}, + {0x3d598000}, {0x3d59a000}, {0x3d59c000}, {0x3d59e000}, + {0x3d5a0000}, {0x3d5a2000}, {0x3d5a4000}, {0x3d5a6000}, + {0x3d5a8000}, {0x3d5aa000}, {0x3d5ac000}, {0x3d5ae000}, + {0x3d5b0000}, {0x3d5b2000}, {0x3d5b4000}, {0x3d5b6000}, + {0x3d5b8000}, {0x3d5ba000}, {0x3d5bc000}, {0x3d5be000}, + {0x3d5c0000}, {0x3d5c2000}, {0x3d5c4000}, {0x3d5c6000}, + {0x3d5c8000}, {0x3d5ca000}, {0x3d5cc000}, {0x3d5ce000}, + {0x3d5d0000}, {0x3d5d2000}, {0x3d5d4000}, {0x3d5d6000}, + {0x3d5d8000}, {0x3d5da000}, {0x3d5dc000}, {0x3d5de000}, + {0x3d5e0000}, {0x3d5e2000}, {0x3d5e4000}, {0x3d5e6000}, + {0x3d5e8000}, {0x3d5ea000}, {0x3d5ec000}, {0x3d5ee000}, + {0x3d5f0000}, {0x3d5f2000}, {0x3d5f4000}, {0x3d5f6000}, + {0x3d5f8000}, {0x3d5fa000}, {0x3d5fc000}, {0x3d5fe000}, + {0x3d600000}, {0x3d602000}, {0x3d604000}, {0x3d606000}, + {0x3d608000}, {0x3d60a000}, {0x3d60c000}, {0x3d60e000}, + {0x3d610000}, {0x3d612000}, {0x3d614000}, {0x3d616000}, + {0x3d618000}, {0x3d61a000}, {0x3d61c000}, {0x3d61e000}, + {0x3d620000}, {0x3d622000}, {0x3d624000}, {0x3d626000}, + {0x3d628000}, {0x3d62a000}, {0x3d62c000}, {0x3d62e000}, + {0x3d630000}, {0x3d632000}, {0x3d634000}, {0x3d636000}, + {0x3d638000}, {0x3d63a000}, {0x3d63c000}, {0x3d63e000}, + {0x3d640000}, {0x3d642000}, {0x3d644000}, {0x3d646000}, + {0x3d648000}, {0x3d64a000}, {0x3d64c000}, {0x3d64e000}, + {0x3d650000}, {0x3d652000}, {0x3d654000}, {0x3d656000}, + {0x3d658000}, {0x3d65a000}, {0x3d65c000}, {0x3d65e000}, + {0x3d660000}, {0x3d662000}, {0x3d664000}, {0x3d666000}, + {0x3d668000}, {0x3d66a000}, {0x3d66c000}, {0x3d66e000}, + {0x3d670000}, {0x3d672000}, {0x3d674000}, {0x3d676000}, + {0x3d678000}, {0x3d67a000}, {0x3d67c000}, {0x3d67e000}, + {0x3d680000}, {0x3d682000}, {0x3d684000}, {0x3d686000}, + {0x3d688000}, {0x3d68a000}, {0x3d68c000}, {0x3d68e000}, + {0x3d690000}, {0x3d692000}, {0x3d694000}, {0x3d696000}, + {0x3d698000}, {0x3d69a000}, {0x3d69c000}, {0x3d69e000}, + {0x3d6a0000}, {0x3d6a2000}, {0x3d6a4000}, {0x3d6a6000}, + {0x3d6a8000}, {0x3d6aa000}, {0x3d6ac000}, {0x3d6ae000}, + {0x3d6b0000}, {0x3d6b2000}, {0x3d6b4000}, {0x3d6b6000}, + {0x3d6b8000}, {0x3d6ba000}, {0x3d6bc000}, {0x3d6be000}, + {0x3d6c0000}, {0x3d6c2000}, {0x3d6c4000}, {0x3d6c6000}, + {0x3d6c8000}, {0x3d6ca000}, {0x3d6cc000}, {0x3d6ce000}, + {0x3d6d0000}, {0x3d6d2000}, {0x3d6d4000}, {0x3d6d6000}, + {0x3d6d8000}, {0x3d6da000}, {0x3d6dc000}, {0x3d6de000}, + {0x3d6e0000}, {0x3d6e2000}, {0x3d6e4000}, {0x3d6e6000}, + {0x3d6e8000}, {0x3d6ea000}, {0x3d6ec000}, {0x3d6ee000}, + {0x3d6f0000}, {0x3d6f2000}, {0x3d6f4000}, {0x3d6f6000}, + {0x3d6f8000}, {0x3d6fa000}, {0x3d6fc000}, {0x3d6fe000}, + {0x3d700000}, {0x3d702000}, {0x3d704000}, {0x3d706000}, + {0x3d708000}, {0x3d70a000}, {0x3d70c000}, {0x3d70e000}, + {0x3d710000}, {0x3d712000}, {0x3d714000}, {0x3d716000}, + {0x3d718000}, {0x3d71a000}, {0x3d71c000}, {0x3d71e000}, + {0x3d720000}, {0x3d722000}, {0x3d724000}, {0x3d726000}, + {0x3d728000}, {0x3d72a000}, {0x3d72c000}, {0x3d72e000}, + {0x3d730000}, {0x3d732000}, {0x3d734000}, {0x3d736000}, + {0x3d738000}, {0x3d73a000}, {0x3d73c000}, {0x3d73e000}, + {0x3d740000}, {0x3d742000}, {0x3d744000}, {0x3d746000}, + {0x3d748000}, {0x3d74a000}, {0x3d74c000}, {0x3d74e000}, + {0x3d750000}, {0x3d752000}, {0x3d754000}, {0x3d756000}, + {0x3d758000}, {0x3d75a000}, {0x3d75c000}, {0x3d75e000}, + {0x3d760000}, {0x3d762000}, {0x3d764000}, {0x3d766000}, + {0x3d768000}, {0x3d76a000}, {0x3d76c000}, {0x3d76e000}, + {0x3d770000}, {0x3d772000}, {0x3d774000}, {0x3d776000}, + {0x3d778000}, {0x3d77a000}, {0x3d77c000}, {0x3d77e000}, + {0x3d780000}, {0x3d782000}, {0x3d784000}, {0x3d786000}, + {0x3d788000}, {0x3d78a000}, {0x3d78c000}, {0x3d78e000}, + {0x3d790000}, {0x3d792000}, {0x3d794000}, {0x3d796000}, + {0x3d798000}, {0x3d79a000}, {0x3d79c000}, {0x3d79e000}, + {0x3d7a0000}, {0x3d7a2000}, {0x3d7a4000}, {0x3d7a6000}, + {0x3d7a8000}, {0x3d7aa000}, {0x3d7ac000}, {0x3d7ae000}, + {0x3d7b0000}, {0x3d7b2000}, {0x3d7b4000}, {0x3d7b6000}, + {0x3d7b8000}, {0x3d7ba000}, {0x3d7bc000}, {0x3d7be000}, + {0x3d7c0000}, {0x3d7c2000}, {0x3d7c4000}, {0x3d7c6000}, + {0x3d7c8000}, {0x3d7ca000}, {0x3d7cc000}, {0x3d7ce000}, + {0x3d7d0000}, {0x3d7d2000}, {0x3d7d4000}, {0x3d7d6000}, + {0x3d7d8000}, {0x3d7da000}, {0x3d7dc000}, {0x3d7de000}, + {0x3d7e0000}, {0x3d7e2000}, {0x3d7e4000}, {0x3d7e6000}, + {0x3d7e8000}, {0x3d7ea000}, {0x3d7ec000}, {0x3d7ee000}, + {0x3d7f0000}, {0x3d7f2000}, {0x3d7f4000}, {0x3d7f6000}, + {0x3d7f8000}, {0x3d7fa000}, {0x3d7fc000}, {0x3d7fe000}, + {0x3d800000}, {0x3d802000}, {0x3d804000}, {0x3d806000}, + {0x3d808000}, {0x3d80a000}, {0x3d80c000}, {0x3d80e000}, + {0x3d810000}, {0x3d812000}, {0x3d814000}, {0x3d816000}, + {0x3d818000}, {0x3d81a000}, {0x3d81c000}, {0x3d81e000}, + {0x3d820000}, {0x3d822000}, {0x3d824000}, {0x3d826000}, + {0x3d828000}, {0x3d82a000}, {0x3d82c000}, {0x3d82e000}, + {0x3d830000}, {0x3d832000}, {0x3d834000}, {0x3d836000}, + {0x3d838000}, {0x3d83a000}, {0x3d83c000}, {0x3d83e000}, + {0x3d840000}, {0x3d842000}, {0x3d844000}, {0x3d846000}, + {0x3d848000}, {0x3d84a000}, {0x3d84c000}, {0x3d84e000}, + {0x3d850000}, {0x3d852000}, {0x3d854000}, {0x3d856000}, + {0x3d858000}, {0x3d85a000}, {0x3d85c000}, {0x3d85e000}, + {0x3d860000}, {0x3d862000}, {0x3d864000}, {0x3d866000}, + {0x3d868000}, {0x3d86a000}, {0x3d86c000}, {0x3d86e000}, + {0x3d870000}, {0x3d872000}, {0x3d874000}, {0x3d876000}, + {0x3d878000}, {0x3d87a000}, {0x3d87c000}, {0x3d87e000}, + {0x3d880000}, {0x3d882000}, {0x3d884000}, {0x3d886000}, + {0x3d888000}, {0x3d88a000}, {0x3d88c000}, {0x3d88e000}, + {0x3d890000}, {0x3d892000}, {0x3d894000}, {0x3d896000}, + {0x3d898000}, {0x3d89a000}, {0x3d89c000}, {0x3d89e000}, + {0x3d8a0000}, {0x3d8a2000}, {0x3d8a4000}, {0x3d8a6000}, + {0x3d8a8000}, {0x3d8aa000}, {0x3d8ac000}, {0x3d8ae000}, + {0x3d8b0000}, {0x3d8b2000}, {0x3d8b4000}, {0x3d8b6000}, + {0x3d8b8000}, {0x3d8ba000}, {0x3d8bc000}, {0x3d8be000}, + {0x3d8c0000}, {0x3d8c2000}, {0x3d8c4000}, {0x3d8c6000}, + {0x3d8c8000}, {0x3d8ca000}, {0x3d8cc000}, {0x3d8ce000}, + {0x3d8d0000}, {0x3d8d2000}, {0x3d8d4000}, {0x3d8d6000}, + {0x3d8d8000}, {0x3d8da000}, {0x3d8dc000}, {0x3d8de000}, + {0x3d8e0000}, {0x3d8e2000}, {0x3d8e4000}, {0x3d8e6000}, + {0x3d8e8000}, {0x3d8ea000}, {0x3d8ec000}, {0x3d8ee000}, + {0x3d8f0000}, {0x3d8f2000}, {0x3d8f4000}, {0x3d8f6000}, + {0x3d8f8000}, {0x3d8fa000}, {0x3d8fc000}, {0x3d8fe000}, + {0x3d900000}, {0x3d902000}, {0x3d904000}, {0x3d906000}, + {0x3d908000}, {0x3d90a000}, {0x3d90c000}, {0x3d90e000}, + {0x3d910000}, {0x3d912000}, {0x3d914000}, {0x3d916000}, + {0x3d918000}, {0x3d91a000}, {0x3d91c000}, {0x3d91e000}, + {0x3d920000}, {0x3d922000}, {0x3d924000}, {0x3d926000}, + {0x3d928000}, {0x3d92a000}, {0x3d92c000}, {0x3d92e000}, + {0x3d930000}, {0x3d932000}, {0x3d934000}, {0x3d936000}, + {0x3d938000}, {0x3d93a000}, {0x3d93c000}, {0x3d93e000}, + {0x3d940000}, {0x3d942000}, {0x3d944000}, {0x3d946000}, + {0x3d948000}, {0x3d94a000}, {0x3d94c000}, {0x3d94e000}, + {0x3d950000}, {0x3d952000}, {0x3d954000}, {0x3d956000}, + {0x3d958000}, {0x3d95a000}, {0x3d95c000}, {0x3d95e000}, + {0x3d960000}, {0x3d962000}, {0x3d964000}, {0x3d966000}, + {0x3d968000}, {0x3d96a000}, {0x3d96c000}, {0x3d96e000}, + {0x3d970000}, {0x3d972000}, {0x3d974000}, {0x3d976000}, + {0x3d978000}, {0x3d97a000}, {0x3d97c000}, {0x3d97e000}, + {0x3d980000}, {0x3d982000}, {0x3d984000}, {0x3d986000}, + {0x3d988000}, {0x3d98a000}, {0x3d98c000}, {0x3d98e000}, + {0x3d990000}, {0x3d992000}, {0x3d994000}, {0x3d996000}, + {0x3d998000}, {0x3d99a000}, {0x3d99c000}, {0x3d99e000}, + {0x3d9a0000}, {0x3d9a2000}, {0x3d9a4000}, {0x3d9a6000}, + {0x3d9a8000}, {0x3d9aa000}, {0x3d9ac000}, {0x3d9ae000}, + {0x3d9b0000}, {0x3d9b2000}, {0x3d9b4000}, {0x3d9b6000}, + {0x3d9b8000}, {0x3d9ba000}, {0x3d9bc000}, {0x3d9be000}, + {0x3d9c0000}, {0x3d9c2000}, {0x3d9c4000}, {0x3d9c6000}, + {0x3d9c8000}, {0x3d9ca000}, {0x3d9cc000}, {0x3d9ce000}, + {0x3d9d0000}, {0x3d9d2000}, {0x3d9d4000}, {0x3d9d6000}, + {0x3d9d8000}, {0x3d9da000}, {0x3d9dc000}, {0x3d9de000}, + {0x3d9e0000}, {0x3d9e2000}, {0x3d9e4000}, {0x3d9e6000}, + {0x3d9e8000}, {0x3d9ea000}, {0x3d9ec000}, {0x3d9ee000}, + {0x3d9f0000}, {0x3d9f2000}, {0x3d9f4000}, {0x3d9f6000}, + {0x3d9f8000}, {0x3d9fa000}, {0x3d9fc000}, {0x3d9fe000}, + {0x3da00000}, {0x3da02000}, {0x3da04000}, {0x3da06000}, + {0x3da08000}, {0x3da0a000}, {0x3da0c000}, {0x3da0e000}, + {0x3da10000}, {0x3da12000}, {0x3da14000}, {0x3da16000}, + {0x3da18000}, {0x3da1a000}, {0x3da1c000}, {0x3da1e000}, + {0x3da20000}, {0x3da22000}, {0x3da24000}, {0x3da26000}, + {0x3da28000}, {0x3da2a000}, {0x3da2c000}, {0x3da2e000}, + {0x3da30000}, {0x3da32000}, {0x3da34000}, {0x3da36000}, + {0x3da38000}, {0x3da3a000}, {0x3da3c000}, {0x3da3e000}, + {0x3da40000}, {0x3da42000}, {0x3da44000}, {0x3da46000}, + {0x3da48000}, {0x3da4a000}, {0x3da4c000}, {0x3da4e000}, + {0x3da50000}, {0x3da52000}, {0x3da54000}, {0x3da56000}, + {0x3da58000}, {0x3da5a000}, {0x3da5c000}, {0x3da5e000}, + {0x3da60000}, {0x3da62000}, {0x3da64000}, {0x3da66000}, + {0x3da68000}, {0x3da6a000}, {0x3da6c000}, {0x3da6e000}, + {0x3da70000}, {0x3da72000}, {0x3da74000}, {0x3da76000}, + {0x3da78000}, {0x3da7a000}, {0x3da7c000}, {0x3da7e000}, + {0x3da80000}, {0x3da82000}, {0x3da84000}, {0x3da86000}, + {0x3da88000}, {0x3da8a000}, {0x3da8c000}, {0x3da8e000}, + {0x3da90000}, {0x3da92000}, {0x3da94000}, {0x3da96000}, + {0x3da98000}, {0x3da9a000}, {0x3da9c000}, {0x3da9e000}, + {0x3daa0000}, {0x3daa2000}, {0x3daa4000}, {0x3daa6000}, + {0x3daa8000}, {0x3daaa000}, {0x3daac000}, {0x3daae000}, + {0x3dab0000}, {0x3dab2000}, {0x3dab4000}, {0x3dab6000}, + {0x3dab8000}, {0x3daba000}, {0x3dabc000}, {0x3dabe000}, + {0x3dac0000}, {0x3dac2000}, {0x3dac4000}, {0x3dac6000}, + {0x3dac8000}, {0x3daca000}, {0x3dacc000}, {0x3dace000}, + {0x3dad0000}, {0x3dad2000}, {0x3dad4000}, {0x3dad6000}, + {0x3dad8000}, {0x3dada000}, {0x3dadc000}, {0x3dade000}, + {0x3dae0000}, {0x3dae2000}, {0x3dae4000}, {0x3dae6000}, + {0x3dae8000}, {0x3daea000}, {0x3daec000}, {0x3daee000}, + {0x3daf0000}, {0x3daf2000}, {0x3daf4000}, {0x3daf6000}, + {0x3daf8000}, {0x3dafa000}, {0x3dafc000}, {0x3dafe000}, + {0x3db00000}, {0x3db02000}, {0x3db04000}, {0x3db06000}, + {0x3db08000}, {0x3db0a000}, {0x3db0c000}, {0x3db0e000}, + {0x3db10000}, {0x3db12000}, {0x3db14000}, {0x3db16000}, + {0x3db18000}, {0x3db1a000}, {0x3db1c000}, {0x3db1e000}, + {0x3db20000}, {0x3db22000}, {0x3db24000}, {0x3db26000}, + {0x3db28000}, {0x3db2a000}, {0x3db2c000}, {0x3db2e000}, + {0x3db30000}, {0x3db32000}, {0x3db34000}, {0x3db36000}, + {0x3db38000}, {0x3db3a000}, {0x3db3c000}, {0x3db3e000}, + {0x3db40000}, {0x3db42000}, {0x3db44000}, {0x3db46000}, + {0x3db48000}, {0x3db4a000}, {0x3db4c000}, {0x3db4e000}, + {0x3db50000}, {0x3db52000}, {0x3db54000}, {0x3db56000}, + {0x3db58000}, {0x3db5a000}, {0x3db5c000}, {0x3db5e000}, + {0x3db60000}, {0x3db62000}, {0x3db64000}, {0x3db66000}, + {0x3db68000}, {0x3db6a000}, {0x3db6c000}, {0x3db6e000}, + {0x3db70000}, {0x3db72000}, {0x3db74000}, {0x3db76000}, + {0x3db78000}, {0x3db7a000}, {0x3db7c000}, {0x3db7e000}, + {0x3db80000}, {0x3db82000}, {0x3db84000}, {0x3db86000}, + {0x3db88000}, {0x3db8a000}, {0x3db8c000}, {0x3db8e000}, + {0x3db90000}, {0x3db92000}, {0x3db94000}, {0x3db96000}, + {0x3db98000}, {0x3db9a000}, {0x3db9c000}, {0x3db9e000}, + {0x3dba0000}, {0x3dba2000}, {0x3dba4000}, {0x3dba6000}, + {0x3dba8000}, {0x3dbaa000}, {0x3dbac000}, {0x3dbae000}, + {0x3dbb0000}, {0x3dbb2000}, {0x3dbb4000}, {0x3dbb6000}, + {0x3dbb8000}, {0x3dbba000}, {0x3dbbc000}, {0x3dbbe000}, + {0x3dbc0000}, {0x3dbc2000}, {0x3dbc4000}, {0x3dbc6000}, + {0x3dbc8000}, {0x3dbca000}, {0x3dbcc000}, {0x3dbce000}, + {0x3dbd0000}, {0x3dbd2000}, {0x3dbd4000}, {0x3dbd6000}, + {0x3dbd8000}, {0x3dbda000}, {0x3dbdc000}, {0x3dbde000}, + {0x3dbe0000}, {0x3dbe2000}, {0x3dbe4000}, {0x3dbe6000}, + {0x3dbe8000}, {0x3dbea000}, {0x3dbec000}, {0x3dbee000}, + {0x3dbf0000}, {0x3dbf2000}, {0x3dbf4000}, {0x3dbf6000}, + {0x3dbf8000}, {0x3dbfa000}, {0x3dbfc000}, {0x3dbfe000}, + {0x3dc00000}, {0x3dc02000}, {0x3dc04000}, {0x3dc06000}, + {0x3dc08000}, {0x3dc0a000}, {0x3dc0c000}, {0x3dc0e000}, + {0x3dc10000}, {0x3dc12000}, {0x3dc14000}, {0x3dc16000}, + {0x3dc18000}, {0x3dc1a000}, {0x3dc1c000}, {0x3dc1e000}, + {0x3dc20000}, {0x3dc22000}, {0x3dc24000}, {0x3dc26000}, + {0x3dc28000}, {0x3dc2a000}, {0x3dc2c000}, {0x3dc2e000}, + {0x3dc30000}, {0x3dc32000}, {0x3dc34000}, {0x3dc36000}, + {0x3dc38000}, {0x3dc3a000}, {0x3dc3c000}, {0x3dc3e000}, + {0x3dc40000}, {0x3dc42000}, {0x3dc44000}, {0x3dc46000}, + {0x3dc48000}, {0x3dc4a000}, {0x3dc4c000}, {0x3dc4e000}, + {0x3dc50000}, {0x3dc52000}, {0x3dc54000}, {0x3dc56000}, + {0x3dc58000}, {0x3dc5a000}, {0x3dc5c000}, {0x3dc5e000}, + {0x3dc60000}, {0x3dc62000}, {0x3dc64000}, {0x3dc66000}, + {0x3dc68000}, {0x3dc6a000}, {0x3dc6c000}, {0x3dc6e000}, + {0x3dc70000}, {0x3dc72000}, {0x3dc74000}, {0x3dc76000}, + {0x3dc78000}, {0x3dc7a000}, {0x3dc7c000}, {0x3dc7e000}, + {0x3dc80000}, {0x3dc82000}, {0x3dc84000}, {0x3dc86000}, + {0x3dc88000}, {0x3dc8a000}, {0x3dc8c000}, {0x3dc8e000}, + {0x3dc90000}, {0x3dc92000}, {0x3dc94000}, {0x3dc96000}, + {0x3dc98000}, {0x3dc9a000}, {0x3dc9c000}, {0x3dc9e000}, + {0x3dca0000}, {0x3dca2000}, {0x3dca4000}, {0x3dca6000}, + {0x3dca8000}, {0x3dcaa000}, {0x3dcac000}, {0x3dcae000}, + {0x3dcb0000}, {0x3dcb2000}, {0x3dcb4000}, {0x3dcb6000}, + {0x3dcb8000}, {0x3dcba000}, {0x3dcbc000}, {0x3dcbe000}, + {0x3dcc0000}, {0x3dcc2000}, {0x3dcc4000}, {0x3dcc6000}, + {0x3dcc8000}, {0x3dcca000}, {0x3dccc000}, {0x3dcce000}, + {0x3dcd0000}, {0x3dcd2000}, {0x3dcd4000}, {0x3dcd6000}, + {0x3dcd8000}, {0x3dcda000}, {0x3dcdc000}, {0x3dcde000}, + {0x3dce0000}, {0x3dce2000}, {0x3dce4000}, {0x3dce6000}, + {0x3dce8000}, {0x3dcea000}, {0x3dcec000}, {0x3dcee000}, + {0x3dcf0000}, {0x3dcf2000}, {0x3dcf4000}, {0x3dcf6000}, + {0x3dcf8000}, {0x3dcfa000}, {0x3dcfc000}, {0x3dcfe000}, + {0x3dd00000}, {0x3dd02000}, {0x3dd04000}, {0x3dd06000}, + {0x3dd08000}, {0x3dd0a000}, {0x3dd0c000}, {0x3dd0e000}, + {0x3dd10000}, {0x3dd12000}, {0x3dd14000}, {0x3dd16000}, + {0x3dd18000}, {0x3dd1a000}, {0x3dd1c000}, {0x3dd1e000}, + {0x3dd20000}, {0x3dd22000}, {0x3dd24000}, {0x3dd26000}, + {0x3dd28000}, {0x3dd2a000}, {0x3dd2c000}, {0x3dd2e000}, + {0x3dd30000}, {0x3dd32000}, {0x3dd34000}, {0x3dd36000}, + {0x3dd38000}, {0x3dd3a000}, {0x3dd3c000}, {0x3dd3e000}, + {0x3dd40000}, {0x3dd42000}, {0x3dd44000}, {0x3dd46000}, + {0x3dd48000}, {0x3dd4a000}, {0x3dd4c000}, {0x3dd4e000}, + {0x3dd50000}, {0x3dd52000}, {0x3dd54000}, {0x3dd56000}, + {0x3dd58000}, {0x3dd5a000}, {0x3dd5c000}, {0x3dd5e000}, + {0x3dd60000}, {0x3dd62000}, {0x3dd64000}, {0x3dd66000}, + {0x3dd68000}, {0x3dd6a000}, {0x3dd6c000}, {0x3dd6e000}, + {0x3dd70000}, {0x3dd72000}, {0x3dd74000}, {0x3dd76000}, + {0x3dd78000}, {0x3dd7a000}, {0x3dd7c000}, {0x3dd7e000}, + {0x3dd80000}, {0x3dd82000}, {0x3dd84000}, {0x3dd86000}, + {0x3dd88000}, {0x3dd8a000}, {0x3dd8c000}, {0x3dd8e000}, + {0x3dd90000}, {0x3dd92000}, {0x3dd94000}, {0x3dd96000}, + {0x3dd98000}, {0x3dd9a000}, {0x3dd9c000}, {0x3dd9e000}, + {0x3dda0000}, {0x3dda2000}, {0x3dda4000}, {0x3dda6000}, + {0x3dda8000}, {0x3ddaa000}, {0x3ddac000}, {0x3ddae000}, + {0x3ddb0000}, {0x3ddb2000}, {0x3ddb4000}, {0x3ddb6000}, + {0x3ddb8000}, {0x3ddba000}, {0x3ddbc000}, {0x3ddbe000}, + {0x3ddc0000}, {0x3ddc2000}, {0x3ddc4000}, {0x3ddc6000}, + {0x3ddc8000}, {0x3ddca000}, {0x3ddcc000}, {0x3ddce000}, + {0x3ddd0000}, {0x3ddd2000}, {0x3ddd4000}, {0x3ddd6000}, + {0x3ddd8000}, {0x3ddda000}, {0x3dddc000}, {0x3ddde000}, + {0x3dde0000}, {0x3dde2000}, {0x3dde4000}, {0x3dde6000}, + {0x3dde8000}, {0x3ddea000}, {0x3ddec000}, {0x3ddee000}, + {0x3ddf0000}, {0x3ddf2000}, {0x3ddf4000}, {0x3ddf6000}, + {0x3ddf8000}, {0x3ddfa000}, {0x3ddfc000}, {0x3ddfe000}, + {0x3de00000}, {0x3de02000}, {0x3de04000}, {0x3de06000}, + {0x3de08000}, {0x3de0a000}, {0x3de0c000}, {0x3de0e000}, + {0x3de10000}, {0x3de12000}, {0x3de14000}, {0x3de16000}, + {0x3de18000}, {0x3de1a000}, {0x3de1c000}, {0x3de1e000}, + {0x3de20000}, {0x3de22000}, {0x3de24000}, {0x3de26000}, + {0x3de28000}, {0x3de2a000}, {0x3de2c000}, {0x3de2e000}, + {0x3de30000}, {0x3de32000}, {0x3de34000}, {0x3de36000}, + {0x3de38000}, {0x3de3a000}, {0x3de3c000}, {0x3de3e000}, + {0x3de40000}, {0x3de42000}, {0x3de44000}, {0x3de46000}, + {0x3de48000}, {0x3de4a000}, {0x3de4c000}, {0x3de4e000}, + {0x3de50000}, {0x3de52000}, {0x3de54000}, {0x3de56000}, + {0x3de58000}, {0x3de5a000}, {0x3de5c000}, {0x3de5e000}, + {0x3de60000}, {0x3de62000}, {0x3de64000}, {0x3de66000}, + {0x3de68000}, {0x3de6a000}, {0x3de6c000}, {0x3de6e000}, + {0x3de70000}, {0x3de72000}, {0x3de74000}, {0x3de76000}, + {0x3de78000}, {0x3de7a000}, {0x3de7c000}, {0x3de7e000}, + {0x3de80000}, {0x3de82000}, {0x3de84000}, {0x3de86000}, + {0x3de88000}, {0x3de8a000}, {0x3de8c000}, {0x3de8e000}, + {0x3de90000}, {0x3de92000}, {0x3de94000}, {0x3de96000}, + {0x3de98000}, {0x3de9a000}, {0x3de9c000}, {0x3de9e000}, + {0x3dea0000}, {0x3dea2000}, {0x3dea4000}, {0x3dea6000}, + {0x3dea8000}, {0x3deaa000}, {0x3deac000}, {0x3deae000}, + {0x3deb0000}, {0x3deb2000}, {0x3deb4000}, {0x3deb6000}, + {0x3deb8000}, {0x3deba000}, {0x3debc000}, {0x3debe000}, + {0x3dec0000}, {0x3dec2000}, {0x3dec4000}, {0x3dec6000}, + {0x3dec8000}, {0x3deca000}, {0x3decc000}, {0x3dece000}, + {0x3ded0000}, {0x3ded2000}, {0x3ded4000}, {0x3ded6000}, + {0x3ded8000}, {0x3deda000}, {0x3dedc000}, {0x3dede000}, + {0x3dee0000}, {0x3dee2000}, {0x3dee4000}, {0x3dee6000}, + {0x3dee8000}, {0x3deea000}, {0x3deec000}, {0x3deee000}, + {0x3def0000}, {0x3def2000}, {0x3def4000}, {0x3def6000}, + {0x3def8000}, {0x3defa000}, {0x3defc000}, {0x3defe000}, + {0x3df00000}, {0x3df02000}, {0x3df04000}, {0x3df06000}, + {0x3df08000}, {0x3df0a000}, {0x3df0c000}, {0x3df0e000}, + {0x3df10000}, {0x3df12000}, {0x3df14000}, {0x3df16000}, + {0x3df18000}, {0x3df1a000}, {0x3df1c000}, {0x3df1e000}, + {0x3df20000}, {0x3df22000}, {0x3df24000}, {0x3df26000}, + {0x3df28000}, {0x3df2a000}, {0x3df2c000}, {0x3df2e000}, + {0x3df30000}, {0x3df32000}, {0x3df34000}, {0x3df36000}, + {0x3df38000}, {0x3df3a000}, {0x3df3c000}, {0x3df3e000}, + {0x3df40000}, {0x3df42000}, {0x3df44000}, {0x3df46000}, + {0x3df48000}, {0x3df4a000}, {0x3df4c000}, {0x3df4e000}, + {0x3df50000}, {0x3df52000}, {0x3df54000}, {0x3df56000}, + {0x3df58000}, {0x3df5a000}, {0x3df5c000}, {0x3df5e000}, + {0x3df60000}, {0x3df62000}, {0x3df64000}, {0x3df66000}, + {0x3df68000}, {0x3df6a000}, {0x3df6c000}, {0x3df6e000}, + {0x3df70000}, {0x3df72000}, {0x3df74000}, {0x3df76000}, + {0x3df78000}, {0x3df7a000}, {0x3df7c000}, {0x3df7e000}, + {0x3df80000}, {0x3df82000}, {0x3df84000}, {0x3df86000}, + {0x3df88000}, {0x3df8a000}, {0x3df8c000}, {0x3df8e000}, + {0x3df90000}, {0x3df92000}, {0x3df94000}, {0x3df96000}, + {0x3df98000}, {0x3df9a000}, {0x3df9c000}, {0x3df9e000}, + {0x3dfa0000}, {0x3dfa2000}, {0x3dfa4000}, {0x3dfa6000}, + {0x3dfa8000}, {0x3dfaa000}, {0x3dfac000}, {0x3dfae000}, + {0x3dfb0000}, {0x3dfb2000}, {0x3dfb4000}, {0x3dfb6000}, + {0x3dfb8000}, {0x3dfba000}, {0x3dfbc000}, {0x3dfbe000}, + {0x3dfc0000}, {0x3dfc2000}, {0x3dfc4000}, {0x3dfc6000}, + {0x3dfc8000}, {0x3dfca000}, {0x3dfcc000}, {0x3dfce000}, + {0x3dfd0000}, {0x3dfd2000}, {0x3dfd4000}, {0x3dfd6000}, + {0x3dfd8000}, {0x3dfda000}, {0x3dfdc000}, {0x3dfde000}, + {0x3dfe0000}, {0x3dfe2000}, {0x3dfe4000}, {0x3dfe6000}, + {0x3dfe8000}, {0x3dfea000}, {0x3dfec000}, {0x3dfee000}, + {0x3dff0000}, {0x3dff2000}, {0x3dff4000}, {0x3dff6000}, + {0x3dff8000}, {0x3dffa000}, {0x3dffc000}, {0x3dffe000}, + {0x3e000000}, {0x3e002000}, {0x3e004000}, {0x3e006000}, + {0x3e008000}, {0x3e00a000}, {0x3e00c000}, {0x3e00e000}, + {0x3e010000}, {0x3e012000}, {0x3e014000}, {0x3e016000}, + {0x3e018000}, {0x3e01a000}, {0x3e01c000}, {0x3e01e000}, + {0x3e020000}, {0x3e022000}, {0x3e024000}, {0x3e026000}, + {0x3e028000}, {0x3e02a000}, {0x3e02c000}, {0x3e02e000}, + {0x3e030000}, {0x3e032000}, {0x3e034000}, {0x3e036000}, + {0x3e038000}, {0x3e03a000}, {0x3e03c000}, {0x3e03e000}, + {0x3e040000}, {0x3e042000}, {0x3e044000}, {0x3e046000}, + {0x3e048000}, {0x3e04a000}, {0x3e04c000}, {0x3e04e000}, + {0x3e050000}, {0x3e052000}, {0x3e054000}, {0x3e056000}, + {0x3e058000}, {0x3e05a000}, {0x3e05c000}, {0x3e05e000}, + {0x3e060000}, {0x3e062000}, {0x3e064000}, {0x3e066000}, + {0x3e068000}, {0x3e06a000}, {0x3e06c000}, {0x3e06e000}, + {0x3e070000}, {0x3e072000}, {0x3e074000}, {0x3e076000}, + {0x3e078000}, {0x3e07a000}, {0x3e07c000}, {0x3e07e000}, + {0x3e080000}, {0x3e082000}, {0x3e084000}, {0x3e086000}, + {0x3e088000}, {0x3e08a000}, {0x3e08c000}, {0x3e08e000}, + {0x3e090000}, {0x3e092000}, {0x3e094000}, {0x3e096000}, + {0x3e098000}, {0x3e09a000}, {0x3e09c000}, {0x3e09e000}, + {0x3e0a0000}, {0x3e0a2000}, {0x3e0a4000}, {0x3e0a6000}, + {0x3e0a8000}, {0x3e0aa000}, {0x3e0ac000}, {0x3e0ae000}, + {0x3e0b0000}, {0x3e0b2000}, {0x3e0b4000}, {0x3e0b6000}, + {0x3e0b8000}, {0x3e0ba000}, {0x3e0bc000}, {0x3e0be000}, + {0x3e0c0000}, {0x3e0c2000}, {0x3e0c4000}, {0x3e0c6000}, + {0x3e0c8000}, {0x3e0ca000}, {0x3e0cc000}, {0x3e0ce000}, + {0x3e0d0000}, {0x3e0d2000}, {0x3e0d4000}, {0x3e0d6000}, + {0x3e0d8000}, {0x3e0da000}, {0x3e0dc000}, {0x3e0de000}, + {0x3e0e0000}, {0x3e0e2000}, {0x3e0e4000}, {0x3e0e6000}, + {0x3e0e8000}, {0x3e0ea000}, {0x3e0ec000}, {0x3e0ee000}, + {0x3e0f0000}, {0x3e0f2000}, {0x3e0f4000}, {0x3e0f6000}, + {0x3e0f8000}, {0x3e0fa000}, {0x3e0fc000}, {0x3e0fe000}, + {0x3e100000}, {0x3e102000}, {0x3e104000}, {0x3e106000}, + {0x3e108000}, {0x3e10a000}, {0x3e10c000}, {0x3e10e000}, + {0x3e110000}, {0x3e112000}, {0x3e114000}, {0x3e116000}, + {0x3e118000}, {0x3e11a000}, {0x3e11c000}, {0x3e11e000}, + {0x3e120000}, {0x3e122000}, {0x3e124000}, {0x3e126000}, + {0x3e128000}, {0x3e12a000}, {0x3e12c000}, {0x3e12e000}, + {0x3e130000}, {0x3e132000}, {0x3e134000}, {0x3e136000}, + {0x3e138000}, {0x3e13a000}, {0x3e13c000}, {0x3e13e000}, + {0x3e140000}, {0x3e142000}, {0x3e144000}, {0x3e146000}, + {0x3e148000}, {0x3e14a000}, {0x3e14c000}, {0x3e14e000}, + {0x3e150000}, {0x3e152000}, {0x3e154000}, {0x3e156000}, + {0x3e158000}, {0x3e15a000}, {0x3e15c000}, {0x3e15e000}, + {0x3e160000}, {0x3e162000}, {0x3e164000}, {0x3e166000}, + {0x3e168000}, {0x3e16a000}, {0x3e16c000}, {0x3e16e000}, + {0x3e170000}, {0x3e172000}, {0x3e174000}, {0x3e176000}, + {0x3e178000}, {0x3e17a000}, {0x3e17c000}, {0x3e17e000}, + {0x3e180000}, {0x3e182000}, {0x3e184000}, {0x3e186000}, + {0x3e188000}, {0x3e18a000}, {0x3e18c000}, {0x3e18e000}, + {0x3e190000}, {0x3e192000}, {0x3e194000}, {0x3e196000}, + {0x3e198000}, {0x3e19a000}, {0x3e19c000}, {0x3e19e000}, + {0x3e1a0000}, {0x3e1a2000}, {0x3e1a4000}, {0x3e1a6000}, + {0x3e1a8000}, {0x3e1aa000}, {0x3e1ac000}, {0x3e1ae000}, + {0x3e1b0000}, {0x3e1b2000}, {0x3e1b4000}, {0x3e1b6000}, + {0x3e1b8000}, {0x3e1ba000}, {0x3e1bc000}, {0x3e1be000}, + {0x3e1c0000}, {0x3e1c2000}, {0x3e1c4000}, {0x3e1c6000}, + {0x3e1c8000}, {0x3e1ca000}, {0x3e1cc000}, {0x3e1ce000}, + {0x3e1d0000}, {0x3e1d2000}, {0x3e1d4000}, {0x3e1d6000}, + {0x3e1d8000}, {0x3e1da000}, {0x3e1dc000}, {0x3e1de000}, + {0x3e1e0000}, {0x3e1e2000}, {0x3e1e4000}, {0x3e1e6000}, + {0x3e1e8000}, {0x3e1ea000}, {0x3e1ec000}, {0x3e1ee000}, + {0x3e1f0000}, {0x3e1f2000}, {0x3e1f4000}, {0x3e1f6000}, + {0x3e1f8000}, {0x3e1fa000}, {0x3e1fc000}, {0x3e1fe000}, + {0x3e200000}, {0x3e202000}, {0x3e204000}, {0x3e206000}, + {0x3e208000}, {0x3e20a000}, {0x3e20c000}, {0x3e20e000}, + {0x3e210000}, {0x3e212000}, {0x3e214000}, {0x3e216000}, + {0x3e218000}, {0x3e21a000}, {0x3e21c000}, {0x3e21e000}, + {0x3e220000}, {0x3e222000}, {0x3e224000}, {0x3e226000}, + {0x3e228000}, {0x3e22a000}, {0x3e22c000}, {0x3e22e000}, + {0x3e230000}, {0x3e232000}, {0x3e234000}, {0x3e236000}, + {0x3e238000}, {0x3e23a000}, {0x3e23c000}, {0x3e23e000}, + {0x3e240000}, {0x3e242000}, {0x3e244000}, {0x3e246000}, + {0x3e248000}, {0x3e24a000}, {0x3e24c000}, {0x3e24e000}, + {0x3e250000}, {0x3e252000}, {0x3e254000}, {0x3e256000}, + {0x3e258000}, {0x3e25a000}, {0x3e25c000}, {0x3e25e000}, + {0x3e260000}, {0x3e262000}, {0x3e264000}, {0x3e266000}, + {0x3e268000}, {0x3e26a000}, {0x3e26c000}, {0x3e26e000}, + {0x3e270000}, {0x3e272000}, {0x3e274000}, {0x3e276000}, + {0x3e278000}, {0x3e27a000}, {0x3e27c000}, {0x3e27e000}, + {0x3e280000}, {0x3e282000}, {0x3e284000}, {0x3e286000}, + {0x3e288000}, {0x3e28a000}, {0x3e28c000}, {0x3e28e000}, + {0x3e290000}, {0x3e292000}, {0x3e294000}, {0x3e296000}, + {0x3e298000}, {0x3e29a000}, {0x3e29c000}, {0x3e29e000}, + {0x3e2a0000}, {0x3e2a2000}, {0x3e2a4000}, {0x3e2a6000}, + {0x3e2a8000}, {0x3e2aa000}, {0x3e2ac000}, {0x3e2ae000}, + {0x3e2b0000}, {0x3e2b2000}, {0x3e2b4000}, {0x3e2b6000}, + {0x3e2b8000}, {0x3e2ba000}, {0x3e2bc000}, {0x3e2be000}, + {0x3e2c0000}, {0x3e2c2000}, {0x3e2c4000}, {0x3e2c6000}, + {0x3e2c8000}, {0x3e2ca000}, {0x3e2cc000}, {0x3e2ce000}, + {0x3e2d0000}, {0x3e2d2000}, {0x3e2d4000}, {0x3e2d6000}, + {0x3e2d8000}, {0x3e2da000}, {0x3e2dc000}, {0x3e2de000}, + {0x3e2e0000}, {0x3e2e2000}, {0x3e2e4000}, {0x3e2e6000}, + {0x3e2e8000}, {0x3e2ea000}, {0x3e2ec000}, {0x3e2ee000}, + {0x3e2f0000}, {0x3e2f2000}, {0x3e2f4000}, {0x3e2f6000}, + {0x3e2f8000}, {0x3e2fa000}, {0x3e2fc000}, {0x3e2fe000}, + {0x3e300000}, {0x3e302000}, {0x3e304000}, {0x3e306000}, + {0x3e308000}, {0x3e30a000}, {0x3e30c000}, {0x3e30e000}, + {0x3e310000}, {0x3e312000}, {0x3e314000}, {0x3e316000}, + {0x3e318000}, {0x3e31a000}, {0x3e31c000}, {0x3e31e000}, + {0x3e320000}, {0x3e322000}, {0x3e324000}, {0x3e326000}, + {0x3e328000}, {0x3e32a000}, {0x3e32c000}, {0x3e32e000}, + {0x3e330000}, {0x3e332000}, {0x3e334000}, {0x3e336000}, + {0x3e338000}, {0x3e33a000}, {0x3e33c000}, {0x3e33e000}, + {0x3e340000}, {0x3e342000}, {0x3e344000}, {0x3e346000}, + {0x3e348000}, {0x3e34a000}, {0x3e34c000}, {0x3e34e000}, + {0x3e350000}, {0x3e352000}, {0x3e354000}, {0x3e356000}, + {0x3e358000}, {0x3e35a000}, {0x3e35c000}, {0x3e35e000}, + {0x3e360000}, {0x3e362000}, {0x3e364000}, {0x3e366000}, + {0x3e368000}, {0x3e36a000}, {0x3e36c000}, {0x3e36e000}, + {0x3e370000}, {0x3e372000}, {0x3e374000}, {0x3e376000}, + {0x3e378000}, {0x3e37a000}, {0x3e37c000}, {0x3e37e000}, + {0x3e380000}, {0x3e382000}, {0x3e384000}, {0x3e386000}, + {0x3e388000}, {0x3e38a000}, {0x3e38c000}, {0x3e38e000}, + {0x3e390000}, {0x3e392000}, {0x3e394000}, {0x3e396000}, + {0x3e398000}, {0x3e39a000}, {0x3e39c000}, {0x3e39e000}, + {0x3e3a0000}, {0x3e3a2000}, {0x3e3a4000}, {0x3e3a6000}, + {0x3e3a8000}, {0x3e3aa000}, {0x3e3ac000}, {0x3e3ae000}, + {0x3e3b0000}, {0x3e3b2000}, {0x3e3b4000}, {0x3e3b6000}, + {0x3e3b8000}, {0x3e3ba000}, {0x3e3bc000}, {0x3e3be000}, + {0x3e3c0000}, {0x3e3c2000}, {0x3e3c4000}, {0x3e3c6000}, + {0x3e3c8000}, {0x3e3ca000}, {0x3e3cc000}, {0x3e3ce000}, + {0x3e3d0000}, {0x3e3d2000}, {0x3e3d4000}, {0x3e3d6000}, + {0x3e3d8000}, {0x3e3da000}, {0x3e3dc000}, {0x3e3de000}, + {0x3e3e0000}, {0x3e3e2000}, {0x3e3e4000}, {0x3e3e6000}, + {0x3e3e8000}, {0x3e3ea000}, {0x3e3ec000}, {0x3e3ee000}, + {0x3e3f0000}, {0x3e3f2000}, {0x3e3f4000}, {0x3e3f6000}, + {0x3e3f8000}, {0x3e3fa000}, {0x3e3fc000}, {0x3e3fe000}, + {0x3e400000}, {0x3e402000}, {0x3e404000}, {0x3e406000}, + {0x3e408000}, {0x3e40a000}, {0x3e40c000}, {0x3e40e000}, + {0x3e410000}, {0x3e412000}, {0x3e414000}, {0x3e416000}, + {0x3e418000}, {0x3e41a000}, {0x3e41c000}, {0x3e41e000}, + {0x3e420000}, {0x3e422000}, {0x3e424000}, {0x3e426000}, + {0x3e428000}, {0x3e42a000}, {0x3e42c000}, {0x3e42e000}, + {0x3e430000}, {0x3e432000}, {0x3e434000}, {0x3e436000}, + {0x3e438000}, {0x3e43a000}, {0x3e43c000}, {0x3e43e000}, + {0x3e440000}, {0x3e442000}, {0x3e444000}, {0x3e446000}, + {0x3e448000}, {0x3e44a000}, {0x3e44c000}, {0x3e44e000}, + {0x3e450000}, {0x3e452000}, {0x3e454000}, {0x3e456000}, + {0x3e458000}, {0x3e45a000}, {0x3e45c000}, {0x3e45e000}, + {0x3e460000}, {0x3e462000}, {0x3e464000}, {0x3e466000}, + {0x3e468000}, {0x3e46a000}, {0x3e46c000}, {0x3e46e000}, + {0x3e470000}, {0x3e472000}, {0x3e474000}, {0x3e476000}, + {0x3e478000}, {0x3e47a000}, {0x3e47c000}, {0x3e47e000}, + {0x3e480000}, {0x3e482000}, {0x3e484000}, {0x3e486000}, + {0x3e488000}, {0x3e48a000}, {0x3e48c000}, {0x3e48e000}, + {0x3e490000}, {0x3e492000}, {0x3e494000}, {0x3e496000}, + {0x3e498000}, {0x3e49a000}, {0x3e49c000}, {0x3e49e000}, + {0x3e4a0000}, {0x3e4a2000}, {0x3e4a4000}, {0x3e4a6000}, + {0x3e4a8000}, {0x3e4aa000}, {0x3e4ac000}, {0x3e4ae000}, + {0x3e4b0000}, {0x3e4b2000}, {0x3e4b4000}, {0x3e4b6000}, + {0x3e4b8000}, {0x3e4ba000}, {0x3e4bc000}, {0x3e4be000}, + {0x3e4c0000}, {0x3e4c2000}, {0x3e4c4000}, {0x3e4c6000}, + {0x3e4c8000}, {0x3e4ca000}, {0x3e4cc000}, {0x3e4ce000}, + {0x3e4d0000}, {0x3e4d2000}, {0x3e4d4000}, {0x3e4d6000}, + {0x3e4d8000}, {0x3e4da000}, {0x3e4dc000}, {0x3e4de000}, + {0x3e4e0000}, {0x3e4e2000}, {0x3e4e4000}, {0x3e4e6000}, + {0x3e4e8000}, {0x3e4ea000}, {0x3e4ec000}, {0x3e4ee000}, + {0x3e4f0000}, {0x3e4f2000}, {0x3e4f4000}, {0x3e4f6000}, + {0x3e4f8000}, {0x3e4fa000}, {0x3e4fc000}, {0x3e4fe000}, + {0x3e500000}, {0x3e502000}, {0x3e504000}, {0x3e506000}, + {0x3e508000}, {0x3e50a000}, {0x3e50c000}, {0x3e50e000}, + {0x3e510000}, {0x3e512000}, {0x3e514000}, {0x3e516000}, + {0x3e518000}, {0x3e51a000}, {0x3e51c000}, {0x3e51e000}, + {0x3e520000}, {0x3e522000}, {0x3e524000}, {0x3e526000}, + {0x3e528000}, {0x3e52a000}, {0x3e52c000}, {0x3e52e000}, + {0x3e530000}, {0x3e532000}, {0x3e534000}, {0x3e536000}, + {0x3e538000}, {0x3e53a000}, {0x3e53c000}, {0x3e53e000}, + {0x3e540000}, {0x3e542000}, {0x3e544000}, {0x3e546000}, + {0x3e548000}, {0x3e54a000}, {0x3e54c000}, {0x3e54e000}, + {0x3e550000}, {0x3e552000}, {0x3e554000}, {0x3e556000}, + {0x3e558000}, {0x3e55a000}, {0x3e55c000}, {0x3e55e000}, + {0x3e560000}, {0x3e562000}, {0x3e564000}, {0x3e566000}, + {0x3e568000}, {0x3e56a000}, {0x3e56c000}, {0x3e56e000}, + {0x3e570000}, {0x3e572000}, {0x3e574000}, {0x3e576000}, + {0x3e578000}, {0x3e57a000}, {0x3e57c000}, {0x3e57e000}, + {0x3e580000}, {0x3e582000}, {0x3e584000}, {0x3e586000}, + {0x3e588000}, {0x3e58a000}, {0x3e58c000}, {0x3e58e000}, + {0x3e590000}, {0x3e592000}, {0x3e594000}, {0x3e596000}, + {0x3e598000}, {0x3e59a000}, {0x3e59c000}, {0x3e59e000}, + {0x3e5a0000}, {0x3e5a2000}, {0x3e5a4000}, {0x3e5a6000}, + {0x3e5a8000}, {0x3e5aa000}, {0x3e5ac000}, {0x3e5ae000}, + {0x3e5b0000}, {0x3e5b2000}, {0x3e5b4000}, {0x3e5b6000}, + {0x3e5b8000}, {0x3e5ba000}, {0x3e5bc000}, {0x3e5be000}, + {0x3e5c0000}, {0x3e5c2000}, {0x3e5c4000}, {0x3e5c6000}, + {0x3e5c8000}, {0x3e5ca000}, {0x3e5cc000}, {0x3e5ce000}, + {0x3e5d0000}, {0x3e5d2000}, {0x3e5d4000}, {0x3e5d6000}, + {0x3e5d8000}, {0x3e5da000}, {0x3e5dc000}, {0x3e5de000}, + {0x3e5e0000}, {0x3e5e2000}, {0x3e5e4000}, {0x3e5e6000}, + {0x3e5e8000}, {0x3e5ea000}, {0x3e5ec000}, {0x3e5ee000}, + {0x3e5f0000}, {0x3e5f2000}, {0x3e5f4000}, {0x3e5f6000}, + {0x3e5f8000}, {0x3e5fa000}, {0x3e5fc000}, {0x3e5fe000}, + {0x3e600000}, {0x3e602000}, {0x3e604000}, {0x3e606000}, + {0x3e608000}, {0x3e60a000}, {0x3e60c000}, {0x3e60e000}, + {0x3e610000}, {0x3e612000}, {0x3e614000}, {0x3e616000}, + {0x3e618000}, {0x3e61a000}, {0x3e61c000}, {0x3e61e000}, + {0x3e620000}, {0x3e622000}, {0x3e624000}, {0x3e626000}, + {0x3e628000}, {0x3e62a000}, {0x3e62c000}, {0x3e62e000}, + {0x3e630000}, {0x3e632000}, {0x3e634000}, {0x3e636000}, + {0x3e638000}, {0x3e63a000}, {0x3e63c000}, {0x3e63e000}, + {0x3e640000}, {0x3e642000}, {0x3e644000}, {0x3e646000}, + {0x3e648000}, {0x3e64a000}, {0x3e64c000}, {0x3e64e000}, + {0x3e650000}, {0x3e652000}, {0x3e654000}, {0x3e656000}, + {0x3e658000}, {0x3e65a000}, {0x3e65c000}, {0x3e65e000}, + {0x3e660000}, {0x3e662000}, {0x3e664000}, {0x3e666000}, + {0x3e668000}, {0x3e66a000}, {0x3e66c000}, {0x3e66e000}, + {0x3e670000}, {0x3e672000}, {0x3e674000}, {0x3e676000}, + {0x3e678000}, {0x3e67a000}, {0x3e67c000}, {0x3e67e000}, + {0x3e680000}, {0x3e682000}, {0x3e684000}, {0x3e686000}, + {0x3e688000}, {0x3e68a000}, {0x3e68c000}, {0x3e68e000}, + {0x3e690000}, {0x3e692000}, {0x3e694000}, {0x3e696000}, + {0x3e698000}, {0x3e69a000}, {0x3e69c000}, {0x3e69e000}, + {0x3e6a0000}, {0x3e6a2000}, {0x3e6a4000}, {0x3e6a6000}, + {0x3e6a8000}, {0x3e6aa000}, {0x3e6ac000}, {0x3e6ae000}, + {0x3e6b0000}, {0x3e6b2000}, {0x3e6b4000}, {0x3e6b6000}, + {0x3e6b8000}, {0x3e6ba000}, {0x3e6bc000}, {0x3e6be000}, + {0x3e6c0000}, {0x3e6c2000}, {0x3e6c4000}, {0x3e6c6000}, + {0x3e6c8000}, {0x3e6ca000}, {0x3e6cc000}, {0x3e6ce000}, + {0x3e6d0000}, {0x3e6d2000}, {0x3e6d4000}, {0x3e6d6000}, + {0x3e6d8000}, {0x3e6da000}, {0x3e6dc000}, {0x3e6de000}, + {0x3e6e0000}, {0x3e6e2000}, {0x3e6e4000}, {0x3e6e6000}, + {0x3e6e8000}, {0x3e6ea000}, {0x3e6ec000}, {0x3e6ee000}, + {0x3e6f0000}, {0x3e6f2000}, {0x3e6f4000}, {0x3e6f6000}, + {0x3e6f8000}, {0x3e6fa000}, {0x3e6fc000}, {0x3e6fe000}, + {0x3e700000}, {0x3e702000}, {0x3e704000}, {0x3e706000}, + {0x3e708000}, {0x3e70a000}, {0x3e70c000}, {0x3e70e000}, + {0x3e710000}, {0x3e712000}, {0x3e714000}, {0x3e716000}, + {0x3e718000}, {0x3e71a000}, {0x3e71c000}, {0x3e71e000}, + {0x3e720000}, {0x3e722000}, {0x3e724000}, {0x3e726000}, + {0x3e728000}, {0x3e72a000}, {0x3e72c000}, {0x3e72e000}, + {0x3e730000}, {0x3e732000}, {0x3e734000}, {0x3e736000}, + {0x3e738000}, {0x3e73a000}, {0x3e73c000}, {0x3e73e000}, + {0x3e740000}, {0x3e742000}, {0x3e744000}, {0x3e746000}, + {0x3e748000}, {0x3e74a000}, {0x3e74c000}, {0x3e74e000}, + {0x3e750000}, {0x3e752000}, {0x3e754000}, {0x3e756000}, + {0x3e758000}, {0x3e75a000}, {0x3e75c000}, {0x3e75e000}, + {0x3e760000}, {0x3e762000}, {0x3e764000}, {0x3e766000}, + {0x3e768000}, {0x3e76a000}, {0x3e76c000}, {0x3e76e000}, + {0x3e770000}, {0x3e772000}, {0x3e774000}, {0x3e776000}, + {0x3e778000}, {0x3e77a000}, {0x3e77c000}, {0x3e77e000}, + {0x3e780000}, {0x3e782000}, {0x3e784000}, {0x3e786000}, + {0x3e788000}, {0x3e78a000}, {0x3e78c000}, {0x3e78e000}, + {0x3e790000}, {0x3e792000}, {0x3e794000}, {0x3e796000}, + {0x3e798000}, {0x3e79a000}, {0x3e79c000}, {0x3e79e000}, + {0x3e7a0000}, {0x3e7a2000}, {0x3e7a4000}, {0x3e7a6000}, + {0x3e7a8000}, {0x3e7aa000}, {0x3e7ac000}, {0x3e7ae000}, + {0x3e7b0000}, {0x3e7b2000}, {0x3e7b4000}, {0x3e7b6000}, + {0x3e7b8000}, {0x3e7ba000}, {0x3e7bc000}, {0x3e7be000}, + {0x3e7c0000}, {0x3e7c2000}, {0x3e7c4000}, {0x3e7c6000}, + {0x3e7c8000}, {0x3e7ca000}, {0x3e7cc000}, {0x3e7ce000}, + {0x3e7d0000}, {0x3e7d2000}, {0x3e7d4000}, {0x3e7d6000}, + {0x3e7d8000}, {0x3e7da000}, {0x3e7dc000}, {0x3e7de000}, + {0x3e7e0000}, {0x3e7e2000}, {0x3e7e4000}, {0x3e7e6000}, + {0x3e7e8000}, {0x3e7ea000}, {0x3e7ec000}, {0x3e7ee000}, + {0x3e7f0000}, {0x3e7f2000}, {0x3e7f4000}, {0x3e7f6000}, + {0x3e7f8000}, {0x3e7fa000}, {0x3e7fc000}, {0x3e7fe000}, + {0x3e800000}, {0x3e802000}, {0x3e804000}, {0x3e806000}, + {0x3e808000}, {0x3e80a000}, {0x3e80c000}, {0x3e80e000}, + {0x3e810000}, {0x3e812000}, {0x3e814000}, {0x3e816000}, + {0x3e818000}, {0x3e81a000}, {0x3e81c000}, {0x3e81e000}, + {0x3e820000}, {0x3e822000}, {0x3e824000}, {0x3e826000}, + {0x3e828000}, {0x3e82a000}, {0x3e82c000}, {0x3e82e000}, + {0x3e830000}, {0x3e832000}, {0x3e834000}, {0x3e836000}, + {0x3e838000}, {0x3e83a000}, {0x3e83c000}, {0x3e83e000}, + {0x3e840000}, {0x3e842000}, {0x3e844000}, {0x3e846000}, + {0x3e848000}, {0x3e84a000}, {0x3e84c000}, {0x3e84e000}, + {0x3e850000}, {0x3e852000}, {0x3e854000}, {0x3e856000}, + {0x3e858000}, {0x3e85a000}, {0x3e85c000}, {0x3e85e000}, + {0x3e860000}, {0x3e862000}, {0x3e864000}, {0x3e866000}, + {0x3e868000}, {0x3e86a000}, {0x3e86c000}, {0x3e86e000}, + {0x3e870000}, {0x3e872000}, {0x3e874000}, {0x3e876000}, + {0x3e878000}, {0x3e87a000}, {0x3e87c000}, {0x3e87e000}, + {0x3e880000}, {0x3e882000}, {0x3e884000}, {0x3e886000}, + {0x3e888000}, {0x3e88a000}, {0x3e88c000}, {0x3e88e000}, + {0x3e890000}, {0x3e892000}, {0x3e894000}, {0x3e896000}, + {0x3e898000}, {0x3e89a000}, {0x3e89c000}, {0x3e89e000}, + {0x3e8a0000}, {0x3e8a2000}, {0x3e8a4000}, {0x3e8a6000}, + {0x3e8a8000}, {0x3e8aa000}, {0x3e8ac000}, {0x3e8ae000}, + {0x3e8b0000}, {0x3e8b2000}, {0x3e8b4000}, {0x3e8b6000}, + {0x3e8b8000}, {0x3e8ba000}, {0x3e8bc000}, {0x3e8be000}, + {0x3e8c0000}, {0x3e8c2000}, {0x3e8c4000}, {0x3e8c6000}, + {0x3e8c8000}, {0x3e8ca000}, {0x3e8cc000}, {0x3e8ce000}, + {0x3e8d0000}, {0x3e8d2000}, {0x3e8d4000}, {0x3e8d6000}, + {0x3e8d8000}, {0x3e8da000}, {0x3e8dc000}, {0x3e8de000}, + {0x3e8e0000}, {0x3e8e2000}, {0x3e8e4000}, {0x3e8e6000}, + {0x3e8e8000}, {0x3e8ea000}, {0x3e8ec000}, {0x3e8ee000}, + {0x3e8f0000}, {0x3e8f2000}, {0x3e8f4000}, {0x3e8f6000}, + {0x3e8f8000}, {0x3e8fa000}, {0x3e8fc000}, {0x3e8fe000}, + {0x3e900000}, {0x3e902000}, {0x3e904000}, {0x3e906000}, + {0x3e908000}, {0x3e90a000}, {0x3e90c000}, {0x3e90e000}, + {0x3e910000}, {0x3e912000}, {0x3e914000}, {0x3e916000}, + {0x3e918000}, {0x3e91a000}, {0x3e91c000}, {0x3e91e000}, + {0x3e920000}, {0x3e922000}, {0x3e924000}, {0x3e926000}, + {0x3e928000}, {0x3e92a000}, {0x3e92c000}, {0x3e92e000}, + {0x3e930000}, {0x3e932000}, {0x3e934000}, {0x3e936000}, + {0x3e938000}, {0x3e93a000}, {0x3e93c000}, {0x3e93e000}, + {0x3e940000}, {0x3e942000}, {0x3e944000}, {0x3e946000}, + {0x3e948000}, {0x3e94a000}, {0x3e94c000}, {0x3e94e000}, + {0x3e950000}, {0x3e952000}, {0x3e954000}, {0x3e956000}, + {0x3e958000}, {0x3e95a000}, {0x3e95c000}, {0x3e95e000}, + {0x3e960000}, {0x3e962000}, {0x3e964000}, {0x3e966000}, + {0x3e968000}, {0x3e96a000}, {0x3e96c000}, {0x3e96e000}, + {0x3e970000}, {0x3e972000}, {0x3e974000}, {0x3e976000}, + {0x3e978000}, {0x3e97a000}, {0x3e97c000}, {0x3e97e000}, + {0x3e980000}, {0x3e982000}, {0x3e984000}, {0x3e986000}, + {0x3e988000}, {0x3e98a000}, {0x3e98c000}, {0x3e98e000}, + {0x3e990000}, {0x3e992000}, {0x3e994000}, {0x3e996000}, + {0x3e998000}, {0x3e99a000}, {0x3e99c000}, {0x3e99e000}, + {0x3e9a0000}, {0x3e9a2000}, {0x3e9a4000}, {0x3e9a6000}, + {0x3e9a8000}, {0x3e9aa000}, {0x3e9ac000}, {0x3e9ae000}, + {0x3e9b0000}, {0x3e9b2000}, {0x3e9b4000}, {0x3e9b6000}, + {0x3e9b8000}, {0x3e9ba000}, {0x3e9bc000}, {0x3e9be000}, + {0x3e9c0000}, {0x3e9c2000}, {0x3e9c4000}, {0x3e9c6000}, + {0x3e9c8000}, {0x3e9ca000}, {0x3e9cc000}, {0x3e9ce000}, + {0x3e9d0000}, {0x3e9d2000}, {0x3e9d4000}, {0x3e9d6000}, + {0x3e9d8000}, {0x3e9da000}, {0x3e9dc000}, {0x3e9de000}, + {0x3e9e0000}, {0x3e9e2000}, {0x3e9e4000}, {0x3e9e6000}, + {0x3e9e8000}, {0x3e9ea000}, {0x3e9ec000}, {0x3e9ee000}, + {0x3e9f0000}, {0x3e9f2000}, {0x3e9f4000}, {0x3e9f6000}, + {0x3e9f8000}, {0x3e9fa000}, {0x3e9fc000}, {0x3e9fe000}, + {0x3ea00000}, {0x3ea02000}, {0x3ea04000}, {0x3ea06000}, + {0x3ea08000}, {0x3ea0a000}, {0x3ea0c000}, {0x3ea0e000}, + {0x3ea10000}, {0x3ea12000}, {0x3ea14000}, {0x3ea16000}, + {0x3ea18000}, {0x3ea1a000}, {0x3ea1c000}, {0x3ea1e000}, + {0x3ea20000}, {0x3ea22000}, {0x3ea24000}, {0x3ea26000}, + {0x3ea28000}, {0x3ea2a000}, {0x3ea2c000}, {0x3ea2e000}, + {0x3ea30000}, {0x3ea32000}, {0x3ea34000}, {0x3ea36000}, + {0x3ea38000}, {0x3ea3a000}, {0x3ea3c000}, {0x3ea3e000}, + {0x3ea40000}, {0x3ea42000}, {0x3ea44000}, {0x3ea46000}, + {0x3ea48000}, {0x3ea4a000}, {0x3ea4c000}, {0x3ea4e000}, + {0x3ea50000}, {0x3ea52000}, {0x3ea54000}, {0x3ea56000}, + {0x3ea58000}, {0x3ea5a000}, {0x3ea5c000}, {0x3ea5e000}, + {0x3ea60000}, {0x3ea62000}, {0x3ea64000}, {0x3ea66000}, + {0x3ea68000}, {0x3ea6a000}, {0x3ea6c000}, {0x3ea6e000}, + {0x3ea70000}, {0x3ea72000}, {0x3ea74000}, {0x3ea76000}, + {0x3ea78000}, {0x3ea7a000}, {0x3ea7c000}, {0x3ea7e000}, + {0x3ea80000}, {0x3ea82000}, {0x3ea84000}, {0x3ea86000}, + {0x3ea88000}, {0x3ea8a000}, {0x3ea8c000}, {0x3ea8e000}, + {0x3ea90000}, {0x3ea92000}, {0x3ea94000}, {0x3ea96000}, + {0x3ea98000}, {0x3ea9a000}, {0x3ea9c000}, {0x3ea9e000}, + {0x3eaa0000}, {0x3eaa2000}, {0x3eaa4000}, {0x3eaa6000}, + {0x3eaa8000}, {0x3eaaa000}, {0x3eaac000}, {0x3eaae000}, + {0x3eab0000}, {0x3eab2000}, {0x3eab4000}, {0x3eab6000}, + {0x3eab8000}, {0x3eaba000}, {0x3eabc000}, {0x3eabe000}, + {0x3eac0000}, {0x3eac2000}, {0x3eac4000}, {0x3eac6000}, + {0x3eac8000}, {0x3eaca000}, {0x3eacc000}, {0x3eace000}, + {0x3ead0000}, {0x3ead2000}, {0x3ead4000}, {0x3ead6000}, + {0x3ead8000}, {0x3eada000}, {0x3eadc000}, {0x3eade000}, + {0x3eae0000}, {0x3eae2000}, {0x3eae4000}, {0x3eae6000}, + {0x3eae8000}, {0x3eaea000}, {0x3eaec000}, {0x3eaee000}, + {0x3eaf0000}, {0x3eaf2000}, {0x3eaf4000}, {0x3eaf6000}, + {0x3eaf8000}, {0x3eafa000}, {0x3eafc000}, {0x3eafe000}, + {0x3eb00000}, {0x3eb02000}, {0x3eb04000}, {0x3eb06000}, + {0x3eb08000}, {0x3eb0a000}, {0x3eb0c000}, {0x3eb0e000}, + {0x3eb10000}, {0x3eb12000}, {0x3eb14000}, {0x3eb16000}, + {0x3eb18000}, {0x3eb1a000}, {0x3eb1c000}, {0x3eb1e000}, + {0x3eb20000}, {0x3eb22000}, {0x3eb24000}, {0x3eb26000}, + {0x3eb28000}, {0x3eb2a000}, {0x3eb2c000}, {0x3eb2e000}, + {0x3eb30000}, {0x3eb32000}, {0x3eb34000}, {0x3eb36000}, + {0x3eb38000}, {0x3eb3a000}, {0x3eb3c000}, {0x3eb3e000}, + {0x3eb40000}, {0x3eb42000}, {0x3eb44000}, {0x3eb46000}, + {0x3eb48000}, {0x3eb4a000}, {0x3eb4c000}, {0x3eb4e000}, + {0x3eb50000}, {0x3eb52000}, {0x3eb54000}, {0x3eb56000}, + {0x3eb58000}, {0x3eb5a000}, {0x3eb5c000}, {0x3eb5e000}, + {0x3eb60000}, {0x3eb62000}, {0x3eb64000}, {0x3eb66000}, + {0x3eb68000}, {0x3eb6a000}, {0x3eb6c000}, {0x3eb6e000}, + {0x3eb70000}, {0x3eb72000}, {0x3eb74000}, {0x3eb76000}, + {0x3eb78000}, {0x3eb7a000}, {0x3eb7c000}, {0x3eb7e000}, + {0x3eb80000}, {0x3eb82000}, {0x3eb84000}, {0x3eb86000}, + {0x3eb88000}, {0x3eb8a000}, {0x3eb8c000}, {0x3eb8e000}, + {0x3eb90000}, {0x3eb92000}, {0x3eb94000}, {0x3eb96000}, + {0x3eb98000}, {0x3eb9a000}, {0x3eb9c000}, {0x3eb9e000}, + {0x3eba0000}, {0x3eba2000}, {0x3eba4000}, {0x3eba6000}, + {0x3eba8000}, {0x3ebaa000}, {0x3ebac000}, {0x3ebae000}, + {0x3ebb0000}, {0x3ebb2000}, {0x3ebb4000}, {0x3ebb6000}, + {0x3ebb8000}, {0x3ebba000}, {0x3ebbc000}, {0x3ebbe000}, + {0x3ebc0000}, {0x3ebc2000}, {0x3ebc4000}, {0x3ebc6000}, + {0x3ebc8000}, {0x3ebca000}, {0x3ebcc000}, {0x3ebce000}, + {0x3ebd0000}, {0x3ebd2000}, {0x3ebd4000}, {0x3ebd6000}, + {0x3ebd8000}, {0x3ebda000}, {0x3ebdc000}, {0x3ebde000}, + {0x3ebe0000}, {0x3ebe2000}, {0x3ebe4000}, {0x3ebe6000}, + {0x3ebe8000}, {0x3ebea000}, {0x3ebec000}, {0x3ebee000}, + {0x3ebf0000}, {0x3ebf2000}, {0x3ebf4000}, {0x3ebf6000}, + {0x3ebf8000}, {0x3ebfa000}, {0x3ebfc000}, {0x3ebfe000}, + {0x3ec00000}, {0x3ec02000}, {0x3ec04000}, {0x3ec06000}, + {0x3ec08000}, {0x3ec0a000}, {0x3ec0c000}, {0x3ec0e000}, + {0x3ec10000}, {0x3ec12000}, {0x3ec14000}, {0x3ec16000}, + {0x3ec18000}, {0x3ec1a000}, {0x3ec1c000}, {0x3ec1e000}, + {0x3ec20000}, {0x3ec22000}, {0x3ec24000}, {0x3ec26000}, + {0x3ec28000}, {0x3ec2a000}, {0x3ec2c000}, {0x3ec2e000}, + {0x3ec30000}, {0x3ec32000}, {0x3ec34000}, {0x3ec36000}, + {0x3ec38000}, {0x3ec3a000}, {0x3ec3c000}, {0x3ec3e000}, + {0x3ec40000}, {0x3ec42000}, {0x3ec44000}, {0x3ec46000}, + {0x3ec48000}, {0x3ec4a000}, {0x3ec4c000}, {0x3ec4e000}, + {0x3ec50000}, {0x3ec52000}, {0x3ec54000}, {0x3ec56000}, + {0x3ec58000}, {0x3ec5a000}, {0x3ec5c000}, {0x3ec5e000}, + {0x3ec60000}, {0x3ec62000}, {0x3ec64000}, {0x3ec66000}, + {0x3ec68000}, {0x3ec6a000}, {0x3ec6c000}, {0x3ec6e000}, + {0x3ec70000}, {0x3ec72000}, {0x3ec74000}, {0x3ec76000}, + {0x3ec78000}, {0x3ec7a000}, {0x3ec7c000}, {0x3ec7e000}, + {0x3ec80000}, {0x3ec82000}, {0x3ec84000}, {0x3ec86000}, + {0x3ec88000}, {0x3ec8a000}, {0x3ec8c000}, {0x3ec8e000}, + {0x3ec90000}, {0x3ec92000}, {0x3ec94000}, {0x3ec96000}, + {0x3ec98000}, {0x3ec9a000}, {0x3ec9c000}, {0x3ec9e000}, + {0x3eca0000}, {0x3eca2000}, {0x3eca4000}, {0x3eca6000}, + {0x3eca8000}, {0x3ecaa000}, {0x3ecac000}, {0x3ecae000}, + {0x3ecb0000}, {0x3ecb2000}, {0x3ecb4000}, {0x3ecb6000}, + {0x3ecb8000}, {0x3ecba000}, {0x3ecbc000}, {0x3ecbe000}, + {0x3ecc0000}, {0x3ecc2000}, {0x3ecc4000}, {0x3ecc6000}, + {0x3ecc8000}, {0x3ecca000}, {0x3eccc000}, {0x3ecce000}, + {0x3ecd0000}, {0x3ecd2000}, {0x3ecd4000}, {0x3ecd6000}, + {0x3ecd8000}, {0x3ecda000}, {0x3ecdc000}, {0x3ecde000}, + {0x3ece0000}, {0x3ece2000}, {0x3ece4000}, {0x3ece6000}, + {0x3ece8000}, {0x3ecea000}, {0x3ecec000}, {0x3ecee000}, + {0x3ecf0000}, {0x3ecf2000}, {0x3ecf4000}, {0x3ecf6000}, + {0x3ecf8000}, {0x3ecfa000}, {0x3ecfc000}, {0x3ecfe000}, + {0x3ed00000}, {0x3ed02000}, {0x3ed04000}, {0x3ed06000}, + {0x3ed08000}, {0x3ed0a000}, {0x3ed0c000}, {0x3ed0e000}, + {0x3ed10000}, {0x3ed12000}, {0x3ed14000}, {0x3ed16000}, + {0x3ed18000}, {0x3ed1a000}, {0x3ed1c000}, {0x3ed1e000}, + {0x3ed20000}, {0x3ed22000}, {0x3ed24000}, {0x3ed26000}, + {0x3ed28000}, {0x3ed2a000}, {0x3ed2c000}, {0x3ed2e000}, + {0x3ed30000}, {0x3ed32000}, {0x3ed34000}, {0x3ed36000}, + {0x3ed38000}, {0x3ed3a000}, {0x3ed3c000}, {0x3ed3e000}, + {0x3ed40000}, {0x3ed42000}, {0x3ed44000}, {0x3ed46000}, + {0x3ed48000}, {0x3ed4a000}, {0x3ed4c000}, {0x3ed4e000}, + {0x3ed50000}, {0x3ed52000}, {0x3ed54000}, {0x3ed56000}, + {0x3ed58000}, {0x3ed5a000}, {0x3ed5c000}, {0x3ed5e000}, + {0x3ed60000}, {0x3ed62000}, {0x3ed64000}, {0x3ed66000}, + {0x3ed68000}, {0x3ed6a000}, {0x3ed6c000}, {0x3ed6e000}, + {0x3ed70000}, {0x3ed72000}, {0x3ed74000}, {0x3ed76000}, + {0x3ed78000}, {0x3ed7a000}, {0x3ed7c000}, {0x3ed7e000}, + {0x3ed80000}, {0x3ed82000}, {0x3ed84000}, {0x3ed86000}, + {0x3ed88000}, {0x3ed8a000}, {0x3ed8c000}, {0x3ed8e000}, + {0x3ed90000}, {0x3ed92000}, {0x3ed94000}, {0x3ed96000}, + {0x3ed98000}, {0x3ed9a000}, {0x3ed9c000}, {0x3ed9e000}, + {0x3eda0000}, {0x3eda2000}, {0x3eda4000}, {0x3eda6000}, + {0x3eda8000}, {0x3edaa000}, {0x3edac000}, {0x3edae000}, + {0x3edb0000}, {0x3edb2000}, {0x3edb4000}, {0x3edb6000}, + {0x3edb8000}, {0x3edba000}, {0x3edbc000}, {0x3edbe000}, + {0x3edc0000}, {0x3edc2000}, {0x3edc4000}, {0x3edc6000}, + {0x3edc8000}, {0x3edca000}, {0x3edcc000}, {0x3edce000}, + {0x3edd0000}, {0x3edd2000}, {0x3edd4000}, {0x3edd6000}, + {0x3edd8000}, {0x3edda000}, {0x3eddc000}, {0x3edde000}, + {0x3ede0000}, {0x3ede2000}, {0x3ede4000}, {0x3ede6000}, + {0x3ede8000}, {0x3edea000}, {0x3edec000}, {0x3edee000}, + {0x3edf0000}, {0x3edf2000}, {0x3edf4000}, {0x3edf6000}, + {0x3edf8000}, {0x3edfa000}, {0x3edfc000}, {0x3edfe000}, + {0x3ee00000}, {0x3ee02000}, {0x3ee04000}, {0x3ee06000}, + {0x3ee08000}, {0x3ee0a000}, {0x3ee0c000}, {0x3ee0e000}, + {0x3ee10000}, {0x3ee12000}, {0x3ee14000}, {0x3ee16000}, + {0x3ee18000}, {0x3ee1a000}, {0x3ee1c000}, {0x3ee1e000}, + {0x3ee20000}, {0x3ee22000}, {0x3ee24000}, {0x3ee26000}, + {0x3ee28000}, {0x3ee2a000}, {0x3ee2c000}, {0x3ee2e000}, + {0x3ee30000}, {0x3ee32000}, {0x3ee34000}, {0x3ee36000}, + {0x3ee38000}, {0x3ee3a000}, {0x3ee3c000}, {0x3ee3e000}, + {0x3ee40000}, {0x3ee42000}, {0x3ee44000}, {0x3ee46000}, + {0x3ee48000}, {0x3ee4a000}, {0x3ee4c000}, {0x3ee4e000}, + {0x3ee50000}, {0x3ee52000}, {0x3ee54000}, {0x3ee56000}, + {0x3ee58000}, {0x3ee5a000}, {0x3ee5c000}, {0x3ee5e000}, + {0x3ee60000}, {0x3ee62000}, {0x3ee64000}, {0x3ee66000}, + {0x3ee68000}, {0x3ee6a000}, {0x3ee6c000}, {0x3ee6e000}, + {0x3ee70000}, {0x3ee72000}, {0x3ee74000}, {0x3ee76000}, + {0x3ee78000}, {0x3ee7a000}, {0x3ee7c000}, {0x3ee7e000}, + {0x3ee80000}, {0x3ee82000}, {0x3ee84000}, {0x3ee86000}, + {0x3ee88000}, {0x3ee8a000}, {0x3ee8c000}, {0x3ee8e000}, + {0x3ee90000}, {0x3ee92000}, {0x3ee94000}, {0x3ee96000}, + {0x3ee98000}, {0x3ee9a000}, {0x3ee9c000}, {0x3ee9e000}, + {0x3eea0000}, {0x3eea2000}, {0x3eea4000}, {0x3eea6000}, + {0x3eea8000}, {0x3eeaa000}, {0x3eeac000}, {0x3eeae000}, + {0x3eeb0000}, {0x3eeb2000}, {0x3eeb4000}, {0x3eeb6000}, + {0x3eeb8000}, {0x3eeba000}, {0x3eebc000}, {0x3eebe000}, + {0x3eec0000}, {0x3eec2000}, {0x3eec4000}, {0x3eec6000}, + {0x3eec8000}, {0x3eeca000}, {0x3eecc000}, {0x3eece000}, + {0x3eed0000}, {0x3eed2000}, {0x3eed4000}, {0x3eed6000}, + {0x3eed8000}, {0x3eeda000}, {0x3eedc000}, {0x3eede000}, + {0x3eee0000}, {0x3eee2000}, {0x3eee4000}, {0x3eee6000}, + {0x3eee8000}, {0x3eeea000}, {0x3eeec000}, {0x3eeee000}, + {0x3eef0000}, {0x3eef2000}, {0x3eef4000}, {0x3eef6000}, + {0x3eef8000}, {0x3eefa000}, {0x3eefc000}, {0x3eefe000}, + {0x3ef00000}, {0x3ef02000}, {0x3ef04000}, {0x3ef06000}, + {0x3ef08000}, {0x3ef0a000}, {0x3ef0c000}, {0x3ef0e000}, + {0x3ef10000}, {0x3ef12000}, {0x3ef14000}, {0x3ef16000}, + {0x3ef18000}, {0x3ef1a000}, {0x3ef1c000}, {0x3ef1e000}, + {0x3ef20000}, {0x3ef22000}, {0x3ef24000}, {0x3ef26000}, + {0x3ef28000}, {0x3ef2a000}, {0x3ef2c000}, {0x3ef2e000}, + {0x3ef30000}, {0x3ef32000}, {0x3ef34000}, {0x3ef36000}, + {0x3ef38000}, {0x3ef3a000}, {0x3ef3c000}, {0x3ef3e000}, + {0x3ef40000}, {0x3ef42000}, {0x3ef44000}, {0x3ef46000}, + {0x3ef48000}, {0x3ef4a000}, {0x3ef4c000}, {0x3ef4e000}, + {0x3ef50000}, {0x3ef52000}, {0x3ef54000}, {0x3ef56000}, + {0x3ef58000}, {0x3ef5a000}, {0x3ef5c000}, {0x3ef5e000}, + {0x3ef60000}, {0x3ef62000}, {0x3ef64000}, {0x3ef66000}, + {0x3ef68000}, {0x3ef6a000}, {0x3ef6c000}, {0x3ef6e000}, + {0x3ef70000}, {0x3ef72000}, {0x3ef74000}, {0x3ef76000}, + {0x3ef78000}, {0x3ef7a000}, {0x3ef7c000}, {0x3ef7e000}, + {0x3ef80000}, {0x3ef82000}, {0x3ef84000}, {0x3ef86000}, + {0x3ef88000}, {0x3ef8a000}, {0x3ef8c000}, {0x3ef8e000}, + {0x3ef90000}, {0x3ef92000}, {0x3ef94000}, {0x3ef96000}, + {0x3ef98000}, {0x3ef9a000}, {0x3ef9c000}, {0x3ef9e000}, + {0x3efa0000}, {0x3efa2000}, {0x3efa4000}, {0x3efa6000}, + {0x3efa8000}, {0x3efaa000}, {0x3efac000}, {0x3efae000}, + {0x3efb0000}, {0x3efb2000}, {0x3efb4000}, {0x3efb6000}, + {0x3efb8000}, {0x3efba000}, {0x3efbc000}, {0x3efbe000}, + {0x3efc0000}, {0x3efc2000}, {0x3efc4000}, {0x3efc6000}, + {0x3efc8000}, {0x3efca000}, {0x3efcc000}, {0x3efce000}, + {0x3efd0000}, {0x3efd2000}, {0x3efd4000}, {0x3efd6000}, + {0x3efd8000}, {0x3efda000}, {0x3efdc000}, {0x3efde000}, + {0x3efe0000}, {0x3efe2000}, {0x3efe4000}, {0x3efe6000}, + {0x3efe8000}, {0x3efea000}, {0x3efec000}, {0x3efee000}, + {0x3eff0000}, {0x3eff2000}, {0x3eff4000}, {0x3eff6000}, + {0x3eff8000}, {0x3effa000}, {0x3effc000}, {0x3effe000}, + {0x3f000000}, {0x3f002000}, {0x3f004000}, {0x3f006000}, + {0x3f008000}, {0x3f00a000}, {0x3f00c000}, {0x3f00e000}, + {0x3f010000}, {0x3f012000}, {0x3f014000}, {0x3f016000}, + {0x3f018000}, {0x3f01a000}, {0x3f01c000}, {0x3f01e000}, + {0x3f020000}, {0x3f022000}, {0x3f024000}, {0x3f026000}, + {0x3f028000}, {0x3f02a000}, {0x3f02c000}, {0x3f02e000}, + {0x3f030000}, {0x3f032000}, {0x3f034000}, {0x3f036000}, + {0x3f038000}, {0x3f03a000}, {0x3f03c000}, {0x3f03e000}, + {0x3f040000}, {0x3f042000}, {0x3f044000}, {0x3f046000}, + {0x3f048000}, {0x3f04a000}, {0x3f04c000}, {0x3f04e000}, + {0x3f050000}, {0x3f052000}, {0x3f054000}, {0x3f056000}, + {0x3f058000}, {0x3f05a000}, {0x3f05c000}, {0x3f05e000}, + {0x3f060000}, {0x3f062000}, {0x3f064000}, {0x3f066000}, + {0x3f068000}, {0x3f06a000}, {0x3f06c000}, {0x3f06e000}, + {0x3f070000}, {0x3f072000}, {0x3f074000}, {0x3f076000}, + {0x3f078000}, {0x3f07a000}, {0x3f07c000}, {0x3f07e000}, + {0x3f080000}, {0x3f082000}, {0x3f084000}, {0x3f086000}, + {0x3f088000}, {0x3f08a000}, {0x3f08c000}, {0x3f08e000}, + {0x3f090000}, {0x3f092000}, {0x3f094000}, {0x3f096000}, + {0x3f098000}, {0x3f09a000}, {0x3f09c000}, {0x3f09e000}, + {0x3f0a0000}, {0x3f0a2000}, {0x3f0a4000}, {0x3f0a6000}, + {0x3f0a8000}, {0x3f0aa000}, {0x3f0ac000}, {0x3f0ae000}, + {0x3f0b0000}, {0x3f0b2000}, {0x3f0b4000}, {0x3f0b6000}, + {0x3f0b8000}, {0x3f0ba000}, {0x3f0bc000}, {0x3f0be000}, + {0x3f0c0000}, {0x3f0c2000}, {0x3f0c4000}, {0x3f0c6000}, + {0x3f0c8000}, {0x3f0ca000}, {0x3f0cc000}, {0x3f0ce000}, + {0x3f0d0000}, {0x3f0d2000}, {0x3f0d4000}, {0x3f0d6000}, + {0x3f0d8000}, {0x3f0da000}, {0x3f0dc000}, {0x3f0de000}, + {0x3f0e0000}, {0x3f0e2000}, {0x3f0e4000}, {0x3f0e6000}, + {0x3f0e8000}, {0x3f0ea000}, {0x3f0ec000}, {0x3f0ee000}, + {0x3f0f0000}, {0x3f0f2000}, {0x3f0f4000}, {0x3f0f6000}, + {0x3f0f8000}, {0x3f0fa000}, {0x3f0fc000}, {0x3f0fe000}, + {0x3f100000}, {0x3f102000}, {0x3f104000}, {0x3f106000}, + {0x3f108000}, {0x3f10a000}, {0x3f10c000}, {0x3f10e000}, + {0x3f110000}, {0x3f112000}, {0x3f114000}, {0x3f116000}, + {0x3f118000}, {0x3f11a000}, {0x3f11c000}, {0x3f11e000}, + {0x3f120000}, {0x3f122000}, {0x3f124000}, {0x3f126000}, + {0x3f128000}, {0x3f12a000}, {0x3f12c000}, {0x3f12e000}, + {0x3f130000}, {0x3f132000}, {0x3f134000}, {0x3f136000}, + {0x3f138000}, {0x3f13a000}, {0x3f13c000}, {0x3f13e000}, + {0x3f140000}, {0x3f142000}, {0x3f144000}, {0x3f146000}, + {0x3f148000}, {0x3f14a000}, {0x3f14c000}, {0x3f14e000}, + {0x3f150000}, {0x3f152000}, {0x3f154000}, {0x3f156000}, + {0x3f158000}, {0x3f15a000}, {0x3f15c000}, {0x3f15e000}, + {0x3f160000}, {0x3f162000}, {0x3f164000}, {0x3f166000}, + {0x3f168000}, {0x3f16a000}, {0x3f16c000}, {0x3f16e000}, + {0x3f170000}, {0x3f172000}, {0x3f174000}, {0x3f176000}, + {0x3f178000}, {0x3f17a000}, {0x3f17c000}, {0x3f17e000}, + {0x3f180000}, {0x3f182000}, {0x3f184000}, {0x3f186000}, + {0x3f188000}, {0x3f18a000}, {0x3f18c000}, {0x3f18e000}, + {0x3f190000}, {0x3f192000}, {0x3f194000}, {0x3f196000}, + {0x3f198000}, {0x3f19a000}, {0x3f19c000}, {0x3f19e000}, + {0x3f1a0000}, {0x3f1a2000}, {0x3f1a4000}, {0x3f1a6000}, + {0x3f1a8000}, {0x3f1aa000}, {0x3f1ac000}, {0x3f1ae000}, + {0x3f1b0000}, {0x3f1b2000}, {0x3f1b4000}, {0x3f1b6000}, + {0x3f1b8000}, {0x3f1ba000}, {0x3f1bc000}, {0x3f1be000}, + {0x3f1c0000}, {0x3f1c2000}, {0x3f1c4000}, {0x3f1c6000}, + {0x3f1c8000}, {0x3f1ca000}, {0x3f1cc000}, {0x3f1ce000}, + {0x3f1d0000}, {0x3f1d2000}, {0x3f1d4000}, {0x3f1d6000}, + {0x3f1d8000}, {0x3f1da000}, {0x3f1dc000}, {0x3f1de000}, + {0x3f1e0000}, {0x3f1e2000}, {0x3f1e4000}, {0x3f1e6000}, + {0x3f1e8000}, {0x3f1ea000}, {0x3f1ec000}, {0x3f1ee000}, + {0x3f1f0000}, {0x3f1f2000}, {0x3f1f4000}, {0x3f1f6000}, + {0x3f1f8000}, {0x3f1fa000}, {0x3f1fc000}, {0x3f1fe000}, + {0x3f200000}, {0x3f202000}, {0x3f204000}, {0x3f206000}, + {0x3f208000}, {0x3f20a000}, {0x3f20c000}, {0x3f20e000}, + {0x3f210000}, {0x3f212000}, {0x3f214000}, {0x3f216000}, + {0x3f218000}, {0x3f21a000}, {0x3f21c000}, {0x3f21e000}, + {0x3f220000}, {0x3f222000}, {0x3f224000}, {0x3f226000}, + {0x3f228000}, {0x3f22a000}, {0x3f22c000}, {0x3f22e000}, + {0x3f230000}, {0x3f232000}, {0x3f234000}, {0x3f236000}, + {0x3f238000}, {0x3f23a000}, {0x3f23c000}, {0x3f23e000}, + {0x3f240000}, {0x3f242000}, {0x3f244000}, {0x3f246000}, + {0x3f248000}, {0x3f24a000}, {0x3f24c000}, {0x3f24e000}, + {0x3f250000}, {0x3f252000}, {0x3f254000}, {0x3f256000}, + {0x3f258000}, {0x3f25a000}, {0x3f25c000}, {0x3f25e000}, + {0x3f260000}, {0x3f262000}, {0x3f264000}, {0x3f266000}, + {0x3f268000}, {0x3f26a000}, {0x3f26c000}, {0x3f26e000}, + {0x3f270000}, {0x3f272000}, {0x3f274000}, {0x3f276000}, + {0x3f278000}, {0x3f27a000}, {0x3f27c000}, {0x3f27e000}, + {0x3f280000}, {0x3f282000}, {0x3f284000}, {0x3f286000}, + {0x3f288000}, {0x3f28a000}, {0x3f28c000}, {0x3f28e000}, + {0x3f290000}, {0x3f292000}, {0x3f294000}, {0x3f296000}, + {0x3f298000}, {0x3f29a000}, {0x3f29c000}, {0x3f29e000}, + {0x3f2a0000}, {0x3f2a2000}, {0x3f2a4000}, {0x3f2a6000}, + {0x3f2a8000}, {0x3f2aa000}, {0x3f2ac000}, {0x3f2ae000}, + {0x3f2b0000}, {0x3f2b2000}, {0x3f2b4000}, {0x3f2b6000}, + {0x3f2b8000}, {0x3f2ba000}, {0x3f2bc000}, {0x3f2be000}, + {0x3f2c0000}, {0x3f2c2000}, {0x3f2c4000}, {0x3f2c6000}, + {0x3f2c8000}, {0x3f2ca000}, {0x3f2cc000}, {0x3f2ce000}, + {0x3f2d0000}, {0x3f2d2000}, {0x3f2d4000}, {0x3f2d6000}, + {0x3f2d8000}, {0x3f2da000}, {0x3f2dc000}, {0x3f2de000}, + {0x3f2e0000}, {0x3f2e2000}, {0x3f2e4000}, {0x3f2e6000}, + {0x3f2e8000}, {0x3f2ea000}, {0x3f2ec000}, {0x3f2ee000}, + {0x3f2f0000}, {0x3f2f2000}, {0x3f2f4000}, {0x3f2f6000}, + {0x3f2f8000}, {0x3f2fa000}, {0x3f2fc000}, {0x3f2fe000}, + {0x3f300000}, {0x3f302000}, {0x3f304000}, {0x3f306000}, + {0x3f308000}, {0x3f30a000}, {0x3f30c000}, {0x3f30e000}, + {0x3f310000}, {0x3f312000}, {0x3f314000}, {0x3f316000}, + {0x3f318000}, {0x3f31a000}, {0x3f31c000}, {0x3f31e000}, + {0x3f320000}, {0x3f322000}, {0x3f324000}, {0x3f326000}, + {0x3f328000}, {0x3f32a000}, {0x3f32c000}, {0x3f32e000}, + {0x3f330000}, {0x3f332000}, {0x3f334000}, {0x3f336000}, + {0x3f338000}, {0x3f33a000}, {0x3f33c000}, {0x3f33e000}, + {0x3f340000}, {0x3f342000}, {0x3f344000}, {0x3f346000}, + {0x3f348000}, {0x3f34a000}, {0x3f34c000}, {0x3f34e000}, + {0x3f350000}, {0x3f352000}, {0x3f354000}, {0x3f356000}, + {0x3f358000}, {0x3f35a000}, {0x3f35c000}, {0x3f35e000}, + {0x3f360000}, {0x3f362000}, {0x3f364000}, {0x3f366000}, + {0x3f368000}, {0x3f36a000}, {0x3f36c000}, {0x3f36e000}, + {0x3f370000}, {0x3f372000}, {0x3f374000}, {0x3f376000}, + {0x3f378000}, {0x3f37a000}, {0x3f37c000}, {0x3f37e000}, + {0x3f380000}, {0x3f382000}, {0x3f384000}, {0x3f386000}, + {0x3f388000}, {0x3f38a000}, {0x3f38c000}, {0x3f38e000}, + {0x3f390000}, {0x3f392000}, {0x3f394000}, {0x3f396000}, + {0x3f398000}, {0x3f39a000}, {0x3f39c000}, {0x3f39e000}, + {0x3f3a0000}, {0x3f3a2000}, {0x3f3a4000}, {0x3f3a6000}, + {0x3f3a8000}, {0x3f3aa000}, {0x3f3ac000}, {0x3f3ae000}, + {0x3f3b0000}, {0x3f3b2000}, {0x3f3b4000}, {0x3f3b6000}, + {0x3f3b8000}, {0x3f3ba000}, {0x3f3bc000}, {0x3f3be000}, + {0x3f3c0000}, {0x3f3c2000}, {0x3f3c4000}, {0x3f3c6000}, + {0x3f3c8000}, {0x3f3ca000}, {0x3f3cc000}, {0x3f3ce000}, + {0x3f3d0000}, {0x3f3d2000}, {0x3f3d4000}, {0x3f3d6000}, + {0x3f3d8000}, {0x3f3da000}, {0x3f3dc000}, {0x3f3de000}, + {0x3f3e0000}, {0x3f3e2000}, {0x3f3e4000}, {0x3f3e6000}, + {0x3f3e8000}, {0x3f3ea000}, {0x3f3ec000}, {0x3f3ee000}, + {0x3f3f0000}, {0x3f3f2000}, {0x3f3f4000}, {0x3f3f6000}, + {0x3f3f8000}, {0x3f3fa000}, {0x3f3fc000}, {0x3f3fe000}, + {0x3f400000}, {0x3f402000}, {0x3f404000}, {0x3f406000}, + {0x3f408000}, {0x3f40a000}, {0x3f40c000}, {0x3f40e000}, + {0x3f410000}, {0x3f412000}, {0x3f414000}, {0x3f416000}, + {0x3f418000}, {0x3f41a000}, {0x3f41c000}, {0x3f41e000}, + {0x3f420000}, {0x3f422000}, {0x3f424000}, {0x3f426000}, + {0x3f428000}, {0x3f42a000}, {0x3f42c000}, {0x3f42e000}, + {0x3f430000}, {0x3f432000}, {0x3f434000}, {0x3f436000}, + {0x3f438000}, {0x3f43a000}, {0x3f43c000}, {0x3f43e000}, + {0x3f440000}, {0x3f442000}, {0x3f444000}, {0x3f446000}, + {0x3f448000}, {0x3f44a000}, {0x3f44c000}, {0x3f44e000}, + {0x3f450000}, {0x3f452000}, {0x3f454000}, {0x3f456000}, + {0x3f458000}, {0x3f45a000}, {0x3f45c000}, {0x3f45e000}, + {0x3f460000}, {0x3f462000}, {0x3f464000}, {0x3f466000}, + {0x3f468000}, {0x3f46a000}, {0x3f46c000}, {0x3f46e000}, + {0x3f470000}, {0x3f472000}, {0x3f474000}, {0x3f476000}, + {0x3f478000}, {0x3f47a000}, {0x3f47c000}, {0x3f47e000}, + {0x3f480000}, {0x3f482000}, {0x3f484000}, {0x3f486000}, + {0x3f488000}, {0x3f48a000}, {0x3f48c000}, {0x3f48e000}, + {0x3f490000}, {0x3f492000}, {0x3f494000}, {0x3f496000}, + {0x3f498000}, {0x3f49a000}, {0x3f49c000}, {0x3f49e000}, + {0x3f4a0000}, {0x3f4a2000}, {0x3f4a4000}, {0x3f4a6000}, + {0x3f4a8000}, {0x3f4aa000}, {0x3f4ac000}, {0x3f4ae000}, + {0x3f4b0000}, {0x3f4b2000}, {0x3f4b4000}, {0x3f4b6000}, + {0x3f4b8000}, {0x3f4ba000}, {0x3f4bc000}, {0x3f4be000}, + {0x3f4c0000}, {0x3f4c2000}, {0x3f4c4000}, {0x3f4c6000}, + {0x3f4c8000}, {0x3f4ca000}, {0x3f4cc000}, {0x3f4ce000}, + {0x3f4d0000}, {0x3f4d2000}, {0x3f4d4000}, {0x3f4d6000}, + {0x3f4d8000}, {0x3f4da000}, {0x3f4dc000}, {0x3f4de000}, + {0x3f4e0000}, {0x3f4e2000}, {0x3f4e4000}, {0x3f4e6000}, + {0x3f4e8000}, {0x3f4ea000}, {0x3f4ec000}, {0x3f4ee000}, + {0x3f4f0000}, {0x3f4f2000}, {0x3f4f4000}, {0x3f4f6000}, + {0x3f4f8000}, {0x3f4fa000}, {0x3f4fc000}, {0x3f4fe000}, + {0x3f500000}, {0x3f502000}, {0x3f504000}, {0x3f506000}, + {0x3f508000}, {0x3f50a000}, {0x3f50c000}, {0x3f50e000}, + {0x3f510000}, {0x3f512000}, {0x3f514000}, {0x3f516000}, + {0x3f518000}, {0x3f51a000}, {0x3f51c000}, {0x3f51e000}, + {0x3f520000}, {0x3f522000}, {0x3f524000}, {0x3f526000}, + {0x3f528000}, {0x3f52a000}, {0x3f52c000}, {0x3f52e000}, + {0x3f530000}, {0x3f532000}, {0x3f534000}, {0x3f536000}, + {0x3f538000}, {0x3f53a000}, {0x3f53c000}, {0x3f53e000}, + {0x3f540000}, {0x3f542000}, {0x3f544000}, {0x3f546000}, + {0x3f548000}, {0x3f54a000}, {0x3f54c000}, {0x3f54e000}, + {0x3f550000}, {0x3f552000}, {0x3f554000}, {0x3f556000}, + {0x3f558000}, {0x3f55a000}, {0x3f55c000}, {0x3f55e000}, + {0x3f560000}, {0x3f562000}, {0x3f564000}, {0x3f566000}, + {0x3f568000}, {0x3f56a000}, {0x3f56c000}, {0x3f56e000}, + {0x3f570000}, {0x3f572000}, {0x3f574000}, {0x3f576000}, + {0x3f578000}, {0x3f57a000}, {0x3f57c000}, {0x3f57e000}, + {0x3f580000}, {0x3f582000}, {0x3f584000}, {0x3f586000}, + {0x3f588000}, {0x3f58a000}, {0x3f58c000}, {0x3f58e000}, + {0x3f590000}, {0x3f592000}, {0x3f594000}, {0x3f596000}, + {0x3f598000}, {0x3f59a000}, {0x3f59c000}, {0x3f59e000}, + {0x3f5a0000}, {0x3f5a2000}, {0x3f5a4000}, {0x3f5a6000}, + {0x3f5a8000}, {0x3f5aa000}, {0x3f5ac000}, {0x3f5ae000}, + {0x3f5b0000}, {0x3f5b2000}, {0x3f5b4000}, {0x3f5b6000}, + {0x3f5b8000}, {0x3f5ba000}, {0x3f5bc000}, {0x3f5be000}, + {0x3f5c0000}, {0x3f5c2000}, {0x3f5c4000}, {0x3f5c6000}, + {0x3f5c8000}, {0x3f5ca000}, {0x3f5cc000}, {0x3f5ce000}, + {0x3f5d0000}, {0x3f5d2000}, {0x3f5d4000}, {0x3f5d6000}, + {0x3f5d8000}, {0x3f5da000}, {0x3f5dc000}, {0x3f5de000}, + {0x3f5e0000}, {0x3f5e2000}, {0x3f5e4000}, {0x3f5e6000}, + {0x3f5e8000}, {0x3f5ea000}, {0x3f5ec000}, {0x3f5ee000}, + {0x3f5f0000}, {0x3f5f2000}, {0x3f5f4000}, {0x3f5f6000}, + {0x3f5f8000}, {0x3f5fa000}, {0x3f5fc000}, {0x3f5fe000}, + {0x3f600000}, {0x3f602000}, {0x3f604000}, {0x3f606000}, + {0x3f608000}, {0x3f60a000}, {0x3f60c000}, {0x3f60e000}, + {0x3f610000}, {0x3f612000}, {0x3f614000}, {0x3f616000}, + {0x3f618000}, {0x3f61a000}, {0x3f61c000}, {0x3f61e000}, + {0x3f620000}, {0x3f622000}, {0x3f624000}, {0x3f626000}, + {0x3f628000}, {0x3f62a000}, {0x3f62c000}, {0x3f62e000}, + {0x3f630000}, {0x3f632000}, {0x3f634000}, {0x3f636000}, + {0x3f638000}, {0x3f63a000}, {0x3f63c000}, {0x3f63e000}, + {0x3f640000}, {0x3f642000}, {0x3f644000}, {0x3f646000}, + {0x3f648000}, {0x3f64a000}, {0x3f64c000}, {0x3f64e000}, + {0x3f650000}, {0x3f652000}, {0x3f654000}, {0x3f656000}, + {0x3f658000}, {0x3f65a000}, {0x3f65c000}, {0x3f65e000}, + {0x3f660000}, {0x3f662000}, {0x3f664000}, {0x3f666000}, + {0x3f668000}, {0x3f66a000}, {0x3f66c000}, {0x3f66e000}, + {0x3f670000}, {0x3f672000}, {0x3f674000}, {0x3f676000}, + {0x3f678000}, {0x3f67a000}, {0x3f67c000}, {0x3f67e000}, + {0x3f680000}, {0x3f682000}, {0x3f684000}, {0x3f686000}, + {0x3f688000}, {0x3f68a000}, {0x3f68c000}, {0x3f68e000}, + {0x3f690000}, {0x3f692000}, {0x3f694000}, {0x3f696000}, + {0x3f698000}, {0x3f69a000}, {0x3f69c000}, {0x3f69e000}, + {0x3f6a0000}, {0x3f6a2000}, {0x3f6a4000}, {0x3f6a6000}, + {0x3f6a8000}, {0x3f6aa000}, {0x3f6ac000}, {0x3f6ae000}, + {0x3f6b0000}, {0x3f6b2000}, {0x3f6b4000}, {0x3f6b6000}, + {0x3f6b8000}, {0x3f6ba000}, {0x3f6bc000}, {0x3f6be000}, + {0x3f6c0000}, {0x3f6c2000}, {0x3f6c4000}, {0x3f6c6000}, + {0x3f6c8000}, {0x3f6ca000}, {0x3f6cc000}, {0x3f6ce000}, + {0x3f6d0000}, {0x3f6d2000}, {0x3f6d4000}, {0x3f6d6000}, + {0x3f6d8000}, {0x3f6da000}, {0x3f6dc000}, {0x3f6de000}, + {0x3f6e0000}, {0x3f6e2000}, {0x3f6e4000}, {0x3f6e6000}, + {0x3f6e8000}, {0x3f6ea000}, {0x3f6ec000}, {0x3f6ee000}, + {0x3f6f0000}, {0x3f6f2000}, {0x3f6f4000}, {0x3f6f6000}, + {0x3f6f8000}, {0x3f6fa000}, {0x3f6fc000}, {0x3f6fe000}, + {0x3f700000}, {0x3f702000}, {0x3f704000}, {0x3f706000}, + {0x3f708000}, {0x3f70a000}, {0x3f70c000}, {0x3f70e000}, + {0x3f710000}, {0x3f712000}, {0x3f714000}, {0x3f716000}, + {0x3f718000}, {0x3f71a000}, {0x3f71c000}, {0x3f71e000}, + {0x3f720000}, {0x3f722000}, {0x3f724000}, {0x3f726000}, + {0x3f728000}, {0x3f72a000}, {0x3f72c000}, {0x3f72e000}, + {0x3f730000}, {0x3f732000}, {0x3f734000}, {0x3f736000}, + {0x3f738000}, {0x3f73a000}, {0x3f73c000}, {0x3f73e000}, + {0x3f740000}, {0x3f742000}, {0x3f744000}, {0x3f746000}, + {0x3f748000}, {0x3f74a000}, {0x3f74c000}, {0x3f74e000}, + {0x3f750000}, {0x3f752000}, {0x3f754000}, {0x3f756000}, + {0x3f758000}, {0x3f75a000}, {0x3f75c000}, {0x3f75e000}, + {0x3f760000}, {0x3f762000}, {0x3f764000}, {0x3f766000}, + {0x3f768000}, {0x3f76a000}, {0x3f76c000}, {0x3f76e000}, + {0x3f770000}, {0x3f772000}, {0x3f774000}, {0x3f776000}, + {0x3f778000}, {0x3f77a000}, {0x3f77c000}, {0x3f77e000}, + {0x3f780000}, {0x3f782000}, {0x3f784000}, {0x3f786000}, + {0x3f788000}, {0x3f78a000}, {0x3f78c000}, {0x3f78e000}, + {0x3f790000}, {0x3f792000}, {0x3f794000}, {0x3f796000}, + {0x3f798000}, {0x3f79a000}, {0x3f79c000}, {0x3f79e000}, + {0x3f7a0000}, {0x3f7a2000}, {0x3f7a4000}, {0x3f7a6000}, + {0x3f7a8000}, {0x3f7aa000}, {0x3f7ac000}, {0x3f7ae000}, + {0x3f7b0000}, {0x3f7b2000}, {0x3f7b4000}, {0x3f7b6000}, + {0x3f7b8000}, {0x3f7ba000}, {0x3f7bc000}, {0x3f7be000}, + {0x3f7c0000}, {0x3f7c2000}, {0x3f7c4000}, {0x3f7c6000}, + {0x3f7c8000}, {0x3f7ca000}, {0x3f7cc000}, {0x3f7ce000}, + {0x3f7d0000}, {0x3f7d2000}, {0x3f7d4000}, {0x3f7d6000}, + {0x3f7d8000}, {0x3f7da000}, {0x3f7dc000}, {0x3f7de000}, + {0x3f7e0000}, {0x3f7e2000}, {0x3f7e4000}, {0x3f7e6000}, + {0x3f7e8000}, {0x3f7ea000}, {0x3f7ec000}, {0x3f7ee000}, + {0x3f7f0000}, {0x3f7f2000}, {0x3f7f4000}, {0x3f7f6000}, + {0x3f7f8000}, {0x3f7fa000}, {0x3f7fc000}, {0x3f7fe000}, + {0x3f800000}, {0x3f802000}, {0x3f804000}, {0x3f806000}, + {0x3f808000}, {0x3f80a000}, {0x3f80c000}, {0x3f80e000}, + {0x3f810000}, {0x3f812000}, {0x3f814000}, {0x3f816000}, + {0x3f818000}, {0x3f81a000}, {0x3f81c000}, {0x3f81e000}, + {0x3f820000}, {0x3f822000}, {0x3f824000}, {0x3f826000}, + {0x3f828000}, {0x3f82a000}, {0x3f82c000}, {0x3f82e000}, + {0x3f830000}, {0x3f832000}, {0x3f834000}, {0x3f836000}, + {0x3f838000}, {0x3f83a000}, {0x3f83c000}, {0x3f83e000}, + {0x3f840000}, {0x3f842000}, {0x3f844000}, {0x3f846000}, + {0x3f848000}, {0x3f84a000}, {0x3f84c000}, {0x3f84e000}, + {0x3f850000}, {0x3f852000}, {0x3f854000}, {0x3f856000}, + {0x3f858000}, {0x3f85a000}, {0x3f85c000}, {0x3f85e000}, + {0x3f860000}, {0x3f862000}, {0x3f864000}, {0x3f866000}, + {0x3f868000}, {0x3f86a000}, {0x3f86c000}, {0x3f86e000}, + {0x3f870000}, {0x3f872000}, {0x3f874000}, {0x3f876000}, + {0x3f878000}, {0x3f87a000}, {0x3f87c000}, {0x3f87e000}, + {0x3f880000}, {0x3f882000}, {0x3f884000}, {0x3f886000}, + {0x3f888000}, {0x3f88a000}, {0x3f88c000}, {0x3f88e000}, + {0x3f890000}, {0x3f892000}, {0x3f894000}, {0x3f896000}, + {0x3f898000}, {0x3f89a000}, {0x3f89c000}, {0x3f89e000}, + {0x3f8a0000}, {0x3f8a2000}, {0x3f8a4000}, {0x3f8a6000}, + {0x3f8a8000}, {0x3f8aa000}, {0x3f8ac000}, {0x3f8ae000}, + {0x3f8b0000}, {0x3f8b2000}, {0x3f8b4000}, {0x3f8b6000}, + {0x3f8b8000}, {0x3f8ba000}, {0x3f8bc000}, {0x3f8be000}, + {0x3f8c0000}, {0x3f8c2000}, {0x3f8c4000}, {0x3f8c6000}, + {0x3f8c8000}, {0x3f8ca000}, {0x3f8cc000}, {0x3f8ce000}, + {0x3f8d0000}, {0x3f8d2000}, {0x3f8d4000}, {0x3f8d6000}, + {0x3f8d8000}, {0x3f8da000}, {0x3f8dc000}, {0x3f8de000}, + {0x3f8e0000}, {0x3f8e2000}, {0x3f8e4000}, {0x3f8e6000}, + {0x3f8e8000}, {0x3f8ea000}, {0x3f8ec000}, {0x3f8ee000}, + {0x3f8f0000}, {0x3f8f2000}, {0x3f8f4000}, {0x3f8f6000}, + {0x3f8f8000}, {0x3f8fa000}, {0x3f8fc000}, {0x3f8fe000}, + {0x3f900000}, {0x3f902000}, {0x3f904000}, {0x3f906000}, + {0x3f908000}, {0x3f90a000}, {0x3f90c000}, {0x3f90e000}, + {0x3f910000}, {0x3f912000}, {0x3f914000}, {0x3f916000}, + {0x3f918000}, {0x3f91a000}, {0x3f91c000}, {0x3f91e000}, + {0x3f920000}, {0x3f922000}, {0x3f924000}, {0x3f926000}, + {0x3f928000}, {0x3f92a000}, {0x3f92c000}, {0x3f92e000}, + {0x3f930000}, {0x3f932000}, {0x3f934000}, {0x3f936000}, + {0x3f938000}, {0x3f93a000}, {0x3f93c000}, {0x3f93e000}, + {0x3f940000}, {0x3f942000}, {0x3f944000}, {0x3f946000}, + {0x3f948000}, {0x3f94a000}, {0x3f94c000}, {0x3f94e000}, + {0x3f950000}, {0x3f952000}, {0x3f954000}, {0x3f956000}, + {0x3f958000}, {0x3f95a000}, {0x3f95c000}, {0x3f95e000}, + {0x3f960000}, {0x3f962000}, {0x3f964000}, {0x3f966000}, + {0x3f968000}, {0x3f96a000}, {0x3f96c000}, {0x3f96e000}, + {0x3f970000}, {0x3f972000}, {0x3f974000}, {0x3f976000}, + {0x3f978000}, {0x3f97a000}, {0x3f97c000}, {0x3f97e000}, + {0x3f980000}, {0x3f982000}, {0x3f984000}, {0x3f986000}, + {0x3f988000}, {0x3f98a000}, {0x3f98c000}, {0x3f98e000}, + {0x3f990000}, {0x3f992000}, {0x3f994000}, {0x3f996000}, + {0x3f998000}, {0x3f99a000}, {0x3f99c000}, {0x3f99e000}, + {0x3f9a0000}, {0x3f9a2000}, {0x3f9a4000}, {0x3f9a6000}, + {0x3f9a8000}, {0x3f9aa000}, {0x3f9ac000}, {0x3f9ae000}, + {0x3f9b0000}, {0x3f9b2000}, {0x3f9b4000}, {0x3f9b6000}, + {0x3f9b8000}, {0x3f9ba000}, {0x3f9bc000}, {0x3f9be000}, + {0x3f9c0000}, {0x3f9c2000}, {0x3f9c4000}, {0x3f9c6000}, + {0x3f9c8000}, {0x3f9ca000}, {0x3f9cc000}, {0x3f9ce000}, + {0x3f9d0000}, {0x3f9d2000}, {0x3f9d4000}, {0x3f9d6000}, + {0x3f9d8000}, {0x3f9da000}, {0x3f9dc000}, {0x3f9de000}, + {0x3f9e0000}, {0x3f9e2000}, {0x3f9e4000}, {0x3f9e6000}, + {0x3f9e8000}, {0x3f9ea000}, {0x3f9ec000}, {0x3f9ee000}, + {0x3f9f0000}, {0x3f9f2000}, {0x3f9f4000}, {0x3f9f6000}, + {0x3f9f8000}, {0x3f9fa000}, {0x3f9fc000}, {0x3f9fe000}, + {0x3fa00000}, {0x3fa02000}, {0x3fa04000}, {0x3fa06000}, + {0x3fa08000}, {0x3fa0a000}, {0x3fa0c000}, {0x3fa0e000}, + {0x3fa10000}, {0x3fa12000}, {0x3fa14000}, {0x3fa16000}, + {0x3fa18000}, {0x3fa1a000}, {0x3fa1c000}, {0x3fa1e000}, + {0x3fa20000}, {0x3fa22000}, {0x3fa24000}, {0x3fa26000}, + {0x3fa28000}, {0x3fa2a000}, {0x3fa2c000}, {0x3fa2e000}, + {0x3fa30000}, {0x3fa32000}, {0x3fa34000}, {0x3fa36000}, + {0x3fa38000}, {0x3fa3a000}, {0x3fa3c000}, {0x3fa3e000}, + {0x3fa40000}, {0x3fa42000}, {0x3fa44000}, {0x3fa46000}, + {0x3fa48000}, {0x3fa4a000}, {0x3fa4c000}, {0x3fa4e000}, + {0x3fa50000}, {0x3fa52000}, {0x3fa54000}, {0x3fa56000}, + {0x3fa58000}, {0x3fa5a000}, {0x3fa5c000}, {0x3fa5e000}, + {0x3fa60000}, {0x3fa62000}, {0x3fa64000}, {0x3fa66000}, + {0x3fa68000}, {0x3fa6a000}, {0x3fa6c000}, {0x3fa6e000}, + {0x3fa70000}, {0x3fa72000}, {0x3fa74000}, {0x3fa76000}, + {0x3fa78000}, {0x3fa7a000}, {0x3fa7c000}, {0x3fa7e000}, + {0x3fa80000}, {0x3fa82000}, {0x3fa84000}, {0x3fa86000}, + {0x3fa88000}, {0x3fa8a000}, {0x3fa8c000}, {0x3fa8e000}, + {0x3fa90000}, {0x3fa92000}, {0x3fa94000}, {0x3fa96000}, + {0x3fa98000}, {0x3fa9a000}, {0x3fa9c000}, {0x3fa9e000}, + {0x3faa0000}, {0x3faa2000}, {0x3faa4000}, {0x3faa6000}, + {0x3faa8000}, {0x3faaa000}, {0x3faac000}, {0x3faae000}, + {0x3fab0000}, {0x3fab2000}, {0x3fab4000}, {0x3fab6000}, + {0x3fab8000}, {0x3faba000}, {0x3fabc000}, {0x3fabe000}, + {0x3fac0000}, {0x3fac2000}, {0x3fac4000}, {0x3fac6000}, + {0x3fac8000}, {0x3faca000}, {0x3facc000}, {0x3face000}, + {0x3fad0000}, {0x3fad2000}, {0x3fad4000}, {0x3fad6000}, + {0x3fad8000}, {0x3fada000}, {0x3fadc000}, {0x3fade000}, + {0x3fae0000}, {0x3fae2000}, {0x3fae4000}, {0x3fae6000}, + {0x3fae8000}, {0x3faea000}, {0x3faec000}, {0x3faee000}, + {0x3faf0000}, {0x3faf2000}, {0x3faf4000}, {0x3faf6000}, + {0x3faf8000}, {0x3fafa000}, {0x3fafc000}, {0x3fafe000}, + {0x3fb00000}, {0x3fb02000}, {0x3fb04000}, {0x3fb06000}, + {0x3fb08000}, {0x3fb0a000}, {0x3fb0c000}, {0x3fb0e000}, + {0x3fb10000}, {0x3fb12000}, {0x3fb14000}, {0x3fb16000}, + {0x3fb18000}, {0x3fb1a000}, {0x3fb1c000}, {0x3fb1e000}, + {0x3fb20000}, {0x3fb22000}, {0x3fb24000}, {0x3fb26000}, + {0x3fb28000}, {0x3fb2a000}, {0x3fb2c000}, {0x3fb2e000}, + {0x3fb30000}, {0x3fb32000}, {0x3fb34000}, {0x3fb36000}, + {0x3fb38000}, {0x3fb3a000}, {0x3fb3c000}, {0x3fb3e000}, + {0x3fb40000}, {0x3fb42000}, {0x3fb44000}, {0x3fb46000}, + {0x3fb48000}, {0x3fb4a000}, {0x3fb4c000}, {0x3fb4e000}, + {0x3fb50000}, {0x3fb52000}, {0x3fb54000}, {0x3fb56000}, + {0x3fb58000}, {0x3fb5a000}, {0x3fb5c000}, {0x3fb5e000}, + {0x3fb60000}, {0x3fb62000}, {0x3fb64000}, {0x3fb66000}, + {0x3fb68000}, {0x3fb6a000}, {0x3fb6c000}, {0x3fb6e000}, + {0x3fb70000}, {0x3fb72000}, {0x3fb74000}, {0x3fb76000}, + {0x3fb78000}, {0x3fb7a000}, {0x3fb7c000}, {0x3fb7e000}, + {0x3fb80000}, {0x3fb82000}, {0x3fb84000}, {0x3fb86000}, + {0x3fb88000}, {0x3fb8a000}, {0x3fb8c000}, {0x3fb8e000}, + {0x3fb90000}, {0x3fb92000}, {0x3fb94000}, {0x3fb96000}, + {0x3fb98000}, {0x3fb9a000}, {0x3fb9c000}, {0x3fb9e000}, + {0x3fba0000}, {0x3fba2000}, {0x3fba4000}, {0x3fba6000}, + {0x3fba8000}, {0x3fbaa000}, {0x3fbac000}, {0x3fbae000}, + {0x3fbb0000}, {0x3fbb2000}, {0x3fbb4000}, {0x3fbb6000}, + {0x3fbb8000}, {0x3fbba000}, {0x3fbbc000}, {0x3fbbe000}, + {0x3fbc0000}, {0x3fbc2000}, {0x3fbc4000}, {0x3fbc6000}, + {0x3fbc8000}, {0x3fbca000}, {0x3fbcc000}, {0x3fbce000}, + {0x3fbd0000}, {0x3fbd2000}, {0x3fbd4000}, {0x3fbd6000}, + {0x3fbd8000}, {0x3fbda000}, {0x3fbdc000}, {0x3fbde000}, + {0x3fbe0000}, {0x3fbe2000}, {0x3fbe4000}, {0x3fbe6000}, + {0x3fbe8000}, {0x3fbea000}, {0x3fbec000}, {0x3fbee000}, + {0x3fbf0000}, {0x3fbf2000}, {0x3fbf4000}, {0x3fbf6000}, + {0x3fbf8000}, {0x3fbfa000}, {0x3fbfc000}, {0x3fbfe000}, + {0x3fc00000}, {0x3fc02000}, {0x3fc04000}, {0x3fc06000}, + {0x3fc08000}, {0x3fc0a000}, {0x3fc0c000}, {0x3fc0e000}, + {0x3fc10000}, {0x3fc12000}, {0x3fc14000}, {0x3fc16000}, + {0x3fc18000}, {0x3fc1a000}, {0x3fc1c000}, {0x3fc1e000}, + {0x3fc20000}, {0x3fc22000}, {0x3fc24000}, {0x3fc26000}, + {0x3fc28000}, {0x3fc2a000}, {0x3fc2c000}, {0x3fc2e000}, + {0x3fc30000}, {0x3fc32000}, {0x3fc34000}, {0x3fc36000}, + {0x3fc38000}, {0x3fc3a000}, {0x3fc3c000}, {0x3fc3e000}, + {0x3fc40000}, {0x3fc42000}, {0x3fc44000}, {0x3fc46000}, + {0x3fc48000}, {0x3fc4a000}, {0x3fc4c000}, {0x3fc4e000}, + {0x3fc50000}, {0x3fc52000}, {0x3fc54000}, {0x3fc56000}, + {0x3fc58000}, {0x3fc5a000}, {0x3fc5c000}, {0x3fc5e000}, + {0x3fc60000}, {0x3fc62000}, {0x3fc64000}, {0x3fc66000}, + {0x3fc68000}, {0x3fc6a000}, {0x3fc6c000}, {0x3fc6e000}, + {0x3fc70000}, {0x3fc72000}, {0x3fc74000}, {0x3fc76000}, + {0x3fc78000}, {0x3fc7a000}, {0x3fc7c000}, {0x3fc7e000}, + {0x3fc80000}, {0x3fc82000}, {0x3fc84000}, {0x3fc86000}, + {0x3fc88000}, {0x3fc8a000}, {0x3fc8c000}, {0x3fc8e000}, + {0x3fc90000}, {0x3fc92000}, {0x3fc94000}, {0x3fc96000}, + {0x3fc98000}, {0x3fc9a000}, {0x3fc9c000}, {0x3fc9e000}, + {0x3fca0000}, {0x3fca2000}, {0x3fca4000}, {0x3fca6000}, + {0x3fca8000}, {0x3fcaa000}, {0x3fcac000}, {0x3fcae000}, + {0x3fcb0000}, {0x3fcb2000}, {0x3fcb4000}, {0x3fcb6000}, + {0x3fcb8000}, {0x3fcba000}, {0x3fcbc000}, {0x3fcbe000}, + {0x3fcc0000}, {0x3fcc2000}, {0x3fcc4000}, {0x3fcc6000}, + {0x3fcc8000}, {0x3fcca000}, {0x3fccc000}, {0x3fcce000}, + {0x3fcd0000}, {0x3fcd2000}, {0x3fcd4000}, {0x3fcd6000}, + {0x3fcd8000}, {0x3fcda000}, {0x3fcdc000}, {0x3fcde000}, + {0x3fce0000}, {0x3fce2000}, {0x3fce4000}, {0x3fce6000}, + {0x3fce8000}, {0x3fcea000}, {0x3fcec000}, {0x3fcee000}, + {0x3fcf0000}, {0x3fcf2000}, {0x3fcf4000}, {0x3fcf6000}, + {0x3fcf8000}, {0x3fcfa000}, {0x3fcfc000}, {0x3fcfe000}, + {0x3fd00000}, {0x3fd02000}, {0x3fd04000}, {0x3fd06000}, + {0x3fd08000}, {0x3fd0a000}, {0x3fd0c000}, {0x3fd0e000}, + {0x3fd10000}, {0x3fd12000}, {0x3fd14000}, {0x3fd16000}, + {0x3fd18000}, {0x3fd1a000}, {0x3fd1c000}, {0x3fd1e000}, + {0x3fd20000}, {0x3fd22000}, {0x3fd24000}, {0x3fd26000}, + {0x3fd28000}, {0x3fd2a000}, {0x3fd2c000}, {0x3fd2e000}, + {0x3fd30000}, {0x3fd32000}, {0x3fd34000}, {0x3fd36000}, + {0x3fd38000}, {0x3fd3a000}, {0x3fd3c000}, {0x3fd3e000}, + {0x3fd40000}, {0x3fd42000}, {0x3fd44000}, {0x3fd46000}, + {0x3fd48000}, {0x3fd4a000}, {0x3fd4c000}, {0x3fd4e000}, + {0x3fd50000}, {0x3fd52000}, {0x3fd54000}, {0x3fd56000}, + {0x3fd58000}, {0x3fd5a000}, {0x3fd5c000}, {0x3fd5e000}, + {0x3fd60000}, {0x3fd62000}, {0x3fd64000}, {0x3fd66000}, + {0x3fd68000}, {0x3fd6a000}, {0x3fd6c000}, {0x3fd6e000}, + {0x3fd70000}, {0x3fd72000}, {0x3fd74000}, {0x3fd76000}, + {0x3fd78000}, {0x3fd7a000}, {0x3fd7c000}, {0x3fd7e000}, + {0x3fd80000}, {0x3fd82000}, {0x3fd84000}, {0x3fd86000}, + {0x3fd88000}, {0x3fd8a000}, {0x3fd8c000}, {0x3fd8e000}, + {0x3fd90000}, {0x3fd92000}, {0x3fd94000}, {0x3fd96000}, + {0x3fd98000}, {0x3fd9a000}, {0x3fd9c000}, {0x3fd9e000}, + {0x3fda0000}, {0x3fda2000}, {0x3fda4000}, {0x3fda6000}, + {0x3fda8000}, {0x3fdaa000}, {0x3fdac000}, {0x3fdae000}, + {0x3fdb0000}, {0x3fdb2000}, {0x3fdb4000}, {0x3fdb6000}, + {0x3fdb8000}, {0x3fdba000}, {0x3fdbc000}, {0x3fdbe000}, + {0x3fdc0000}, {0x3fdc2000}, {0x3fdc4000}, {0x3fdc6000}, + {0x3fdc8000}, {0x3fdca000}, {0x3fdcc000}, {0x3fdce000}, + {0x3fdd0000}, {0x3fdd2000}, {0x3fdd4000}, {0x3fdd6000}, + {0x3fdd8000}, {0x3fdda000}, {0x3fddc000}, {0x3fdde000}, + {0x3fde0000}, {0x3fde2000}, {0x3fde4000}, {0x3fde6000}, + {0x3fde8000}, {0x3fdea000}, {0x3fdec000}, {0x3fdee000}, + {0x3fdf0000}, {0x3fdf2000}, {0x3fdf4000}, {0x3fdf6000}, + {0x3fdf8000}, {0x3fdfa000}, {0x3fdfc000}, {0x3fdfe000}, + {0x3fe00000}, {0x3fe02000}, {0x3fe04000}, {0x3fe06000}, + {0x3fe08000}, {0x3fe0a000}, {0x3fe0c000}, {0x3fe0e000}, + {0x3fe10000}, {0x3fe12000}, {0x3fe14000}, {0x3fe16000}, + {0x3fe18000}, {0x3fe1a000}, {0x3fe1c000}, {0x3fe1e000}, + {0x3fe20000}, {0x3fe22000}, {0x3fe24000}, {0x3fe26000}, + {0x3fe28000}, {0x3fe2a000}, {0x3fe2c000}, {0x3fe2e000}, + {0x3fe30000}, {0x3fe32000}, {0x3fe34000}, {0x3fe36000}, + {0x3fe38000}, {0x3fe3a000}, {0x3fe3c000}, {0x3fe3e000}, + {0x3fe40000}, {0x3fe42000}, {0x3fe44000}, {0x3fe46000}, + {0x3fe48000}, {0x3fe4a000}, {0x3fe4c000}, {0x3fe4e000}, + {0x3fe50000}, {0x3fe52000}, {0x3fe54000}, {0x3fe56000}, + {0x3fe58000}, {0x3fe5a000}, {0x3fe5c000}, {0x3fe5e000}, + {0x3fe60000}, {0x3fe62000}, {0x3fe64000}, {0x3fe66000}, + {0x3fe68000}, {0x3fe6a000}, {0x3fe6c000}, {0x3fe6e000}, + {0x3fe70000}, {0x3fe72000}, {0x3fe74000}, {0x3fe76000}, + {0x3fe78000}, {0x3fe7a000}, {0x3fe7c000}, {0x3fe7e000}, + {0x3fe80000}, {0x3fe82000}, {0x3fe84000}, {0x3fe86000}, + {0x3fe88000}, {0x3fe8a000}, {0x3fe8c000}, {0x3fe8e000}, + {0x3fe90000}, {0x3fe92000}, {0x3fe94000}, {0x3fe96000}, + {0x3fe98000}, {0x3fe9a000}, {0x3fe9c000}, {0x3fe9e000}, + {0x3fea0000}, {0x3fea2000}, {0x3fea4000}, {0x3fea6000}, + {0x3fea8000}, {0x3feaa000}, {0x3feac000}, {0x3feae000}, + {0x3feb0000}, {0x3feb2000}, {0x3feb4000}, {0x3feb6000}, + {0x3feb8000}, {0x3feba000}, {0x3febc000}, {0x3febe000}, + {0x3fec0000}, {0x3fec2000}, {0x3fec4000}, {0x3fec6000}, + {0x3fec8000}, {0x3feca000}, {0x3fecc000}, {0x3fece000}, + {0x3fed0000}, {0x3fed2000}, {0x3fed4000}, {0x3fed6000}, + {0x3fed8000}, {0x3feda000}, {0x3fedc000}, {0x3fede000}, + {0x3fee0000}, {0x3fee2000}, {0x3fee4000}, {0x3fee6000}, + {0x3fee8000}, {0x3feea000}, {0x3feec000}, {0x3feee000}, + {0x3fef0000}, {0x3fef2000}, {0x3fef4000}, {0x3fef6000}, + {0x3fef8000}, {0x3fefa000}, {0x3fefc000}, {0x3fefe000}, + {0x3ff00000}, {0x3ff02000}, {0x3ff04000}, {0x3ff06000}, + {0x3ff08000}, {0x3ff0a000}, {0x3ff0c000}, {0x3ff0e000}, + {0x3ff10000}, {0x3ff12000}, {0x3ff14000}, {0x3ff16000}, + {0x3ff18000}, {0x3ff1a000}, {0x3ff1c000}, {0x3ff1e000}, + {0x3ff20000}, {0x3ff22000}, {0x3ff24000}, {0x3ff26000}, + {0x3ff28000}, {0x3ff2a000}, {0x3ff2c000}, {0x3ff2e000}, + {0x3ff30000}, {0x3ff32000}, {0x3ff34000}, {0x3ff36000}, + {0x3ff38000}, {0x3ff3a000}, {0x3ff3c000}, {0x3ff3e000}, + {0x3ff40000}, {0x3ff42000}, {0x3ff44000}, {0x3ff46000}, + {0x3ff48000}, {0x3ff4a000}, {0x3ff4c000}, {0x3ff4e000}, + {0x3ff50000}, {0x3ff52000}, {0x3ff54000}, {0x3ff56000}, + {0x3ff58000}, {0x3ff5a000}, {0x3ff5c000}, {0x3ff5e000}, + {0x3ff60000}, {0x3ff62000}, {0x3ff64000}, {0x3ff66000}, + {0x3ff68000}, {0x3ff6a000}, {0x3ff6c000}, {0x3ff6e000}, + {0x3ff70000}, {0x3ff72000}, {0x3ff74000}, {0x3ff76000}, + {0x3ff78000}, {0x3ff7a000}, {0x3ff7c000}, {0x3ff7e000}, + {0x3ff80000}, {0x3ff82000}, {0x3ff84000}, {0x3ff86000}, + {0x3ff88000}, {0x3ff8a000}, {0x3ff8c000}, {0x3ff8e000}, + {0x3ff90000}, {0x3ff92000}, {0x3ff94000}, {0x3ff96000}, + {0x3ff98000}, {0x3ff9a000}, {0x3ff9c000}, {0x3ff9e000}, + {0x3ffa0000}, {0x3ffa2000}, {0x3ffa4000}, {0x3ffa6000}, + {0x3ffa8000}, {0x3ffaa000}, {0x3ffac000}, {0x3ffae000}, + {0x3ffb0000}, {0x3ffb2000}, {0x3ffb4000}, {0x3ffb6000}, + {0x3ffb8000}, {0x3ffba000}, {0x3ffbc000}, {0x3ffbe000}, + {0x3ffc0000}, {0x3ffc2000}, {0x3ffc4000}, {0x3ffc6000}, + {0x3ffc8000}, {0x3ffca000}, {0x3ffcc000}, {0x3ffce000}, + {0x3ffd0000}, {0x3ffd2000}, {0x3ffd4000}, {0x3ffd6000}, + {0x3ffd8000}, {0x3ffda000}, {0x3ffdc000}, {0x3ffde000}, + {0x3ffe0000}, {0x3ffe2000}, {0x3ffe4000}, {0x3ffe6000}, + {0x3ffe8000}, {0x3ffea000}, {0x3ffec000}, {0x3ffee000}, + {0x3fff0000}, {0x3fff2000}, {0x3fff4000}, {0x3fff6000}, + {0x3fff8000}, {0x3fffa000}, {0x3fffc000}, {0x3fffe000}, + {0x40000000}, {0x40002000}, {0x40004000}, {0x40006000}, + {0x40008000}, {0x4000a000}, {0x4000c000}, {0x4000e000}, + {0x40010000}, {0x40012000}, {0x40014000}, {0x40016000}, + {0x40018000}, {0x4001a000}, {0x4001c000}, {0x4001e000}, + {0x40020000}, {0x40022000}, {0x40024000}, {0x40026000}, + {0x40028000}, {0x4002a000}, {0x4002c000}, {0x4002e000}, + {0x40030000}, {0x40032000}, {0x40034000}, {0x40036000}, + {0x40038000}, {0x4003a000}, {0x4003c000}, {0x4003e000}, + {0x40040000}, {0x40042000}, {0x40044000}, {0x40046000}, + {0x40048000}, {0x4004a000}, {0x4004c000}, {0x4004e000}, + {0x40050000}, {0x40052000}, {0x40054000}, {0x40056000}, + {0x40058000}, {0x4005a000}, {0x4005c000}, {0x4005e000}, + {0x40060000}, {0x40062000}, {0x40064000}, {0x40066000}, + {0x40068000}, {0x4006a000}, {0x4006c000}, {0x4006e000}, + {0x40070000}, {0x40072000}, {0x40074000}, {0x40076000}, + {0x40078000}, {0x4007a000}, {0x4007c000}, {0x4007e000}, + {0x40080000}, {0x40082000}, {0x40084000}, {0x40086000}, + {0x40088000}, {0x4008a000}, {0x4008c000}, {0x4008e000}, + {0x40090000}, {0x40092000}, {0x40094000}, {0x40096000}, + {0x40098000}, {0x4009a000}, {0x4009c000}, {0x4009e000}, + {0x400a0000}, {0x400a2000}, {0x400a4000}, {0x400a6000}, + {0x400a8000}, {0x400aa000}, {0x400ac000}, {0x400ae000}, + {0x400b0000}, {0x400b2000}, {0x400b4000}, {0x400b6000}, + {0x400b8000}, {0x400ba000}, {0x400bc000}, {0x400be000}, + {0x400c0000}, {0x400c2000}, {0x400c4000}, {0x400c6000}, + {0x400c8000}, {0x400ca000}, {0x400cc000}, {0x400ce000}, + {0x400d0000}, {0x400d2000}, {0x400d4000}, {0x400d6000}, + {0x400d8000}, {0x400da000}, {0x400dc000}, {0x400de000}, + {0x400e0000}, {0x400e2000}, {0x400e4000}, {0x400e6000}, + {0x400e8000}, {0x400ea000}, {0x400ec000}, {0x400ee000}, + {0x400f0000}, {0x400f2000}, {0x400f4000}, {0x400f6000}, + {0x400f8000}, {0x400fa000}, {0x400fc000}, {0x400fe000}, + {0x40100000}, {0x40102000}, {0x40104000}, {0x40106000}, + {0x40108000}, {0x4010a000}, {0x4010c000}, {0x4010e000}, + {0x40110000}, {0x40112000}, {0x40114000}, {0x40116000}, + {0x40118000}, {0x4011a000}, {0x4011c000}, {0x4011e000}, + {0x40120000}, {0x40122000}, {0x40124000}, {0x40126000}, + {0x40128000}, {0x4012a000}, {0x4012c000}, {0x4012e000}, + {0x40130000}, {0x40132000}, {0x40134000}, {0x40136000}, + {0x40138000}, {0x4013a000}, {0x4013c000}, {0x4013e000}, + {0x40140000}, {0x40142000}, {0x40144000}, {0x40146000}, + {0x40148000}, {0x4014a000}, {0x4014c000}, {0x4014e000}, + {0x40150000}, {0x40152000}, {0x40154000}, {0x40156000}, + {0x40158000}, {0x4015a000}, {0x4015c000}, {0x4015e000}, + {0x40160000}, {0x40162000}, {0x40164000}, {0x40166000}, + {0x40168000}, {0x4016a000}, {0x4016c000}, {0x4016e000}, + {0x40170000}, {0x40172000}, {0x40174000}, {0x40176000}, + {0x40178000}, {0x4017a000}, {0x4017c000}, {0x4017e000}, + {0x40180000}, {0x40182000}, {0x40184000}, {0x40186000}, + {0x40188000}, {0x4018a000}, {0x4018c000}, {0x4018e000}, + {0x40190000}, {0x40192000}, {0x40194000}, {0x40196000}, + {0x40198000}, {0x4019a000}, {0x4019c000}, {0x4019e000}, + {0x401a0000}, {0x401a2000}, {0x401a4000}, {0x401a6000}, + {0x401a8000}, {0x401aa000}, {0x401ac000}, {0x401ae000}, + {0x401b0000}, {0x401b2000}, {0x401b4000}, {0x401b6000}, + {0x401b8000}, {0x401ba000}, {0x401bc000}, {0x401be000}, + {0x401c0000}, {0x401c2000}, {0x401c4000}, {0x401c6000}, + {0x401c8000}, {0x401ca000}, {0x401cc000}, {0x401ce000}, + {0x401d0000}, {0x401d2000}, {0x401d4000}, {0x401d6000}, + {0x401d8000}, {0x401da000}, {0x401dc000}, {0x401de000}, + {0x401e0000}, {0x401e2000}, {0x401e4000}, {0x401e6000}, + {0x401e8000}, {0x401ea000}, {0x401ec000}, {0x401ee000}, + {0x401f0000}, {0x401f2000}, {0x401f4000}, {0x401f6000}, + {0x401f8000}, {0x401fa000}, {0x401fc000}, {0x401fe000}, + {0x40200000}, {0x40202000}, {0x40204000}, {0x40206000}, + {0x40208000}, {0x4020a000}, {0x4020c000}, {0x4020e000}, + {0x40210000}, {0x40212000}, {0x40214000}, {0x40216000}, + {0x40218000}, {0x4021a000}, {0x4021c000}, {0x4021e000}, + {0x40220000}, {0x40222000}, {0x40224000}, {0x40226000}, + {0x40228000}, {0x4022a000}, {0x4022c000}, {0x4022e000}, + {0x40230000}, {0x40232000}, {0x40234000}, {0x40236000}, + {0x40238000}, {0x4023a000}, {0x4023c000}, {0x4023e000}, + {0x40240000}, {0x40242000}, {0x40244000}, {0x40246000}, + {0x40248000}, {0x4024a000}, {0x4024c000}, {0x4024e000}, + {0x40250000}, {0x40252000}, {0x40254000}, {0x40256000}, + {0x40258000}, {0x4025a000}, {0x4025c000}, {0x4025e000}, + {0x40260000}, {0x40262000}, {0x40264000}, {0x40266000}, + {0x40268000}, {0x4026a000}, {0x4026c000}, {0x4026e000}, + {0x40270000}, {0x40272000}, {0x40274000}, {0x40276000}, + {0x40278000}, {0x4027a000}, {0x4027c000}, {0x4027e000}, + {0x40280000}, {0x40282000}, {0x40284000}, {0x40286000}, + {0x40288000}, {0x4028a000}, {0x4028c000}, {0x4028e000}, + {0x40290000}, {0x40292000}, {0x40294000}, {0x40296000}, + {0x40298000}, {0x4029a000}, {0x4029c000}, {0x4029e000}, + {0x402a0000}, {0x402a2000}, {0x402a4000}, {0x402a6000}, + {0x402a8000}, {0x402aa000}, {0x402ac000}, {0x402ae000}, + {0x402b0000}, {0x402b2000}, {0x402b4000}, {0x402b6000}, + {0x402b8000}, {0x402ba000}, {0x402bc000}, {0x402be000}, + {0x402c0000}, {0x402c2000}, {0x402c4000}, {0x402c6000}, + {0x402c8000}, {0x402ca000}, {0x402cc000}, {0x402ce000}, + {0x402d0000}, {0x402d2000}, {0x402d4000}, {0x402d6000}, + {0x402d8000}, {0x402da000}, {0x402dc000}, {0x402de000}, + {0x402e0000}, {0x402e2000}, {0x402e4000}, {0x402e6000}, + {0x402e8000}, {0x402ea000}, {0x402ec000}, {0x402ee000}, + {0x402f0000}, {0x402f2000}, {0x402f4000}, {0x402f6000}, + {0x402f8000}, {0x402fa000}, {0x402fc000}, {0x402fe000}, + {0x40300000}, {0x40302000}, {0x40304000}, {0x40306000}, + {0x40308000}, {0x4030a000}, {0x4030c000}, {0x4030e000}, + {0x40310000}, {0x40312000}, {0x40314000}, {0x40316000}, + {0x40318000}, {0x4031a000}, {0x4031c000}, {0x4031e000}, + {0x40320000}, {0x40322000}, {0x40324000}, {0x40326000}, + {0x40328000}, {0x4032a000}, {0x4032c000}, {0x4032e000}, + {0x40330000}, {0x40332000}, {0x40334000}, {0x40336000}, + {0x40338000}, {0x4033a000}, {0x4033c000}, {0x4033e000}, + {0x40340000}, {0x40342000}, {0x40344000}, {0x40346000}, + {0x40348000}, {0x4034a000}, {0x4034c000}, {0x4034e000}, + {0x40350000}, {0x40352000}, {0x40354000}, {0x40356000}, + {0x40358000}, {0x4035a000}, {0x4035c000}, {0x4035e000}, + {0x40360000}, {0x40362000}, {0x40364000}, {0x40366000}, + {0x40368000}, {0x4036a000}, {0x4036c000}, {0x4036e000}, + {0x40370000}, {0x40372000}, {0x40374000}, {0x40376000}, + {0x40378000}, {0x4037a000}, {0x4037c000}, {0x4037e000}, + {0x40380000}, {0x40382000}, {0x40384000}, {0x40386000}, + {0x40388000}, {0x4038a000}, {0x4038c000}, {0x4038e000}, + {0x40390000}, {0x40392000}, {0x40394000}, {0x40396000}, + {0x40398000}, {0x4039a000}, {0x4039c000}, {0x4039e000}, + {0x403a0000}, {0x403a2000}, {0x403a4000}, {0x403a6000}, + {0x403a8000}, {0x403aa000}, {0x403ac000}, {0x403ae000}, + {0x403b0000}, {0x403b2000}, {0x403b4000}, {0x403b6000}, + {0x403b8000}, {0x403ba000}, {0x403bc000}, {0x403be000}, + {0x403c0000}, {0x403c2000}, {0x403c4000}, {0x403c6000}, + {0x403c8000}, {0x403ca000}, {0x403cc000}, {0x403ce000}, + {0x403d0000}, {0x403d2000}, {0x403d4000}, {0x403d6000}, + {0x403d8000}, {0x403da000}, {0x403dc000}, {0x403de000}, + {0x403e0000}, {0x403e2000}, {0x403e4000}, {0x403e6000}, + {0x403e8000}, {0x403ea000}, {0x403ec000}, {0x403ee000}, + {0x403f0000}, {0x403f2000}, {0x403f4000}, {0x403f6000}, + {0x403f8000}, {0x403fa000}, {0x403fc000}, {0x403fe000}, + {0x40400000}, {0x40402000}, {0x40404000}, {0x40406000}, + {0x40408000}, {0x4040a000}, {0x4040c000}, {0x4040e000}, + {0x40410000}, {0x40412000}, {0x40414000}, {0x40416000}, + {0x40418000}, {0x4041a000}, {0x4041c000}, {0x4041e000}, + {0x40420000}, {0x40422000}, {0x40424000}, {0x40426000}, + {0x40428000}, {0x4042a000}, {0x4042c000}, {0x4042e000}, + {0x40430000}, {0x40432000}, {0x40434000}, {0x40436000}, + {0x40438000}, {0x4043a000}, {0x4043c000}, {0x4043e000}, + {0x40440000}, {0x40442000}, {0x40444000}, {0x40446000}, + {0x40448000}, {0x4044a000}, {0x4044c000}, {0x4044e000}, + {0x40450000}, {0x40452000}, {0x40454000}, {0x40456000}, + {0x40458000}, {0x4045a000}, {0x4045c000}, {0x4045e000}, + {0x40460000}, {0x40462000}, {0x40464000}, {0x40466000}, + {0x40468000}, {0x4046a000}, {0x4046c000}, {0x4046e000}, + {0x40470000}, {0x40472000}, {0x40474000}, {0x40476000}, + {0x40478000}, {0x4047a000}, {0x4047c000}, {0x4047e000}, + {0x40480000}, {0x40482000}, {0x40484000}, {0x40486000}, + {0x40488000}, {0x4048a000}, {0x4048c000}, {0x4048e000}, + {0x40490000}, {0x40492000}, {0x40494000}, {0x40496000}, + {0x40498000}, {0x4049a000}, {0x4049c000}, {0x4049e000}, + {0x404a0000}, {0x404a2000}, {0x404a4000}, {0x404a6000}, + {0x404a8000}, {0x404aa000}, {0x404ac000}, {0x404ae000}, + {0x404b0000}, {0x404b2000}, {0x404b4000}, {0x404b6000}, + {0x404b8000}, {0x404ba000}, {0x404bc000}, {0x404be000}, + {0x404c0000}, {0x404c2000}, {0x404c4000}, {0x404c6000}, + {0x404c8000}, {0x404ca000}, {0x404cc000}, {0x404ce000}, + {0x404d0000}, {0x404d2000}, {0x404d4000}, {0x404d6000}, + {0x404d8000}, {0x404da000}, {0x404dc000}, {0x404de000}, + {0x404e0000}, {0x404e2000}, {0x404e4000}, {0x404e6000}, + {0x404e8000}, {0x404ea000}, {0x404ec000}, {0x404ee000}, + {0x404f0000}, {0x404f2000}, {0x404f4000}, {0x404f6000}, + {0x404f8000}, {0x404fa000}, {0x404fc000}, {0x404fe000}, + {0x40500000}, {0x40502000}, {0x40504000}, {0x40506000}, + {0x40508000}, {0x4050a000}, {0x4050c000}, {0x4050e000}, + {0x40510000}, {0x40512000}, {0x40514000}, {0x40516000}, + {0x40518000}, {0x4051a000}, {0x4051c000}, {0x4051e000}, + {0x40520000}, {0x40522000}, {0x40524000}, {0x40526000}, + {0x40528000}, {0x4052a000}, {0x4052c000}, {0x4052e000}, + {0x40530000}, {0x40532000}, {0x40534000}, {0x40536000}, + {0x40538000}, {0x4053a000}, {0x4053c000}, {0x4053e000}, + {0x40540000}, {0x40542000}, {0x40544000}, {0x40546000}, + {0x40548000}, {0x4054a000}, {0x4054c000}, {0x4054e000}, + {0x40550000}, {0x40552000}, {0x40554000}, {0x40556000}, + {0x40558000}, {0x4055a000}, {0x4055c000}, {0x4055e000}, + {0x40560000}, {0x40562000}, {0x40564000}, {0x40566000}, + {0x40568000}, {0x4056a000}, {0x4056c000}, {0x4056e000}, + {0x40570000}, {0x40572000}, {0x40574000}, {0x40576000}, + {0x40578000}, {0x4057a000}, {0x4057c000}, {0x4057e000}, + {0x40580000}, {0x40582000}, {0x40584000}, {0x40586000}, + {0x40588000}, {0x4058a000}, {0x4058c000}, {0x4058e000}, + {0x40590000}, {0x40592000}, {0x40594000}, {0x40596000}, + {0x40598000}, {0x4059a000}, {0x4059c000}, {0x4059e000}, + {0x405a0000}, {0x405a2000}, {0x405a4000}, {0x405a6000}, + {0x405a8000}, {0x405aa000}, {0x405ac000}, {0x405ae000}, + {0x405b0000}, {0x405b2000}, {0x405b4000}, {0x405b6000}, + {0x405b8000}, {0x405ba000}, {0x405bc000}, {0x405be000}, + {0x405c0000}, {0x405c2000}, {0x405c4000}, {0x405c6000}, + {0x405c8000}, {0x405ca000}, {0x405cc000}, {0x405ce000}, + {0x405d0000}, {0x405d2000}, {0x405d4000}, {0x405d6000}, + {0x405d8000}, {0x405da000}, {0x405dc000}, {0x405de000}, + {0x405e0000}, {0x405e2000}, {0x405e4000}, {0x405e6000}, + {0x405e8000}, {0x405ea000}, {0x405ec000}, {0x405ee000}, + {0x405f0000}, {0x405f2000}, {0x405f4000}, {0x405f6000}, + {0x405f8000}, {0x405fa000}, {0x405fc000}, {0x405fe000}, + {0x40600000}, {0x40602000}, {0x40604000}, {0x40606000}, + {0x40608000}, {0x4060a000}, {0x4060c000}, {0x4060e000}, + {0x40610000}, {0x40612000}, {0x40614000}, {0x40616000}, + {0x40618000}, {0x4061a000}, {0x4061c000}, {0x4061e000}, + {0x40620000}, {0x40622000}, {0x40624000}, {0x40626000}, + {0x40628000}, {0x4062a000}, {0x4062c000}, {0x4062e000}, + {0x40630000}, {0x40632000}, {0x40634000}, {0x40636000}, + {0x40638000}, {0x4063a000}, {0x4063c000}, {0x4063e000}, + {0x40640000}, {0x40642000}, {0x40644000}, {0x40646000}, + {0x40648000}, {0x4064a000}, {0x4064c000}, {0x4064e000}, + {0x40650000}, {0x40652000}, {0x40654000}, {0x40656000}, + {0x40658000}, {0x4065a000}, {0x4065c000}, {0x4065e000}, + {0x40660000}, {0x40662000}, {0x40664000}, {0x40666000}, + {0x40668000}, {0x4066a000}, {0x4066c000}, {0x4066e000}, + {0x40670000}, {0x40672000}, {0x40674000}, {0x40676000}, + {0x40678000}, {0x4067a000}, {0x4067c000}, {0x4067e000}, + {0x40680000}, {0x40682000}, {0x40684000}, {0x40686000}, + {0x40688000}, {0x4068a000}, {0x4068c000}, {0x4068e000}, + {0x40690000}, {0x40692000}, {0x40694000}, {0x40696000}, + {0x40698000}, {0x4069a000}, {0x4069c000}, {0x4069e000}, + {0x406a0000}, {0x406a2000}, {0x406a4000}, {0x406a6000}, + {0x406a8000}, {0x406aa000}, {0x406ac000}, {0x406ae000}, + {0x406b0000}, {0x406b2000}, {0x406b4000}, {0x406b6000}, + {0x406b8000}, {0x406ba000}, {0x406bc000}, {0x406be000}, + {0x406c0000}, {0x406c2000}, {0x406c4000}, {0x406c6000}, + {0x406c8000}, {0x406ca000}, {0x406cc000}, {0x406ce000}, + {0x406d0000}, {0x406d2000}, {0x406d4000}, {0x406d6000}, + {0x406d8000}, {0x406da000}, {0x406dc000}, {0x406de000}, + {0x406e0000}, {0x406e2000}, {0x406e4000}, {0x406e6000}, + {0x406e8000}, {0x406ea000}, {0x406ec000}, {0x406ee000}, + {0x406f0000}, {0x406f2000}, {0x406f4000}, {0x406f6000}, + {0x406f8000}, {0x406fa000}, {0x406fc000}, {0x406fe000}, + {0x40700000}, {0x40702000}, {0x40704000}, {0x40706000}, + {0x40708000}, {0x4070a000}, {0x4070c000}, {0x4070e000}, + {0x40710000}, {0x40712000}, {0x40714000}, {0x40716000}, + {0x40718000}, {0x4071a000}, {0x4071c000}, {0x4071e000}, + {0x40720000}, {0x40722000}, {0x40724000}, {0x40726000}, + {0x40728000}, {0x4072a000}, {0x4072c000}, {0x4072e000}, + {0x40730000}, {0x40732000}, {0x40734000}, {0x40736000}, + {0x40738000}, {0x4073a000}, {0x4073c000}, {0x4073e000}, + {0x40740000}, {0x40742000}, {0x40744000}, {0x40746000}, + {0x40748000}, {0x4074a000}, {0x4074c000}, {0x4074e000}, + {0x40750000}, {0x40752000}, {0x40754000}, {0x40756000}, + {0x40758000}, {0x4075a000}, {0x4075c000}, {0x4075e000}, + {0x40760000}, {0x40762000}, {0x40764000}, {0x40766000}, + {0x40768000}, {0x4076a000}, {0x4076c000}, {0x4076e000}, + {0x40770000}, {0x40772000}, {0x40774000}, {0x40776000}, + {0x40778000}, {0x4077a000}, {0x4077c000}, {0x4077e000}, + {0x40780000}, {0x40782000}, {0x40784000}, {0x40786000}, + {0x40788000}, {0x4078a000}, {0x4078c000}, {0x4078e000}, + {0x40790000}, {0x40792000}, {0x40794000}, {0x40796000}, + {0x40798000}, {0x4079a000}, {0x4079c000}, {0x4079e000}, + {0x407a0000}, {0x407a2000}, {0x407a4000}, {0x407a6000}, + {0x407a8000}, {0x407aa000}, {0x407ac000}, {0x407ae000}, + {0x407b0000}, {0x407b2000}, {0x407b4000}, {0x407b6000}, + {0x407b8000}, {0x407ba000}, {0x407bc000}, {0x407be000}, + {0x407c0000}, {0x407c2000}, {0x407c4000}, {0x407c6000}, + {0x407c8000}, {0x407ca000}, {0x407cc000}, {0x407ce000}, + {0x407d0000}, {0x407d2000}, {0x407d4000}, {0x407d6000}, + {0x407d8000}, {0x407da000}, {0x407dc000}, {0x407de000}, + {0x407e0000}, {0x407e2000}, {0x407e4000}, {0x407e6000}, + {0x407e8000}, {0x407ea000}, {0x407ec000}, {0x407ee000}, + {0x407f0000}, {0x407f2000}, {0x407f4000}, {0x407f6000}, + {0x407f8000}, {0x407fa000}, {0x407fc000}, {0x407fe000}, + {0x40800000}, {0x40802000}, {0x40804000}, {0x40806000}, + {0x40808000}, {0x4080a000}, {0x4080c000}, {0x4080e000}, + {0x40810000}, {0x40812000}, {0x40814000}, {0x40816000}, + {0x40818000}, {0x4081a000}, {0x4081c000}, {0x4081e000}, + {0x40820000}, {0x40822000}, {0x40824000}, {0x40826000}, + {0x40828000}, {0x4082a000}, {0x4082c000}, {0x4082e000}, + {0x40830000}, {0x40832000}, {0x40834000}, {0x40836000}, + {0x40838000}, {0x4083a000}, {0x4083c000}, {0x4083e000}, + {0x40840000}, {0x40842000}, {0x40844000}, {0x40846000}, + {0x40848000}, {0x4084a000}, {0x4084c000}, {0x4084e000}, + {0x40850000}, {0x40852000}, {0x40854000}, {0x40856000}, + {0x40858000}, {0x4085a000}, {0x4085c000}, {0x4085e000}, + {0x40860000}, {0x40862000}, {0x40864000}, {0x40866000}, + {0x40868000}, {0x4086a000}, {0x4086c000}, {0x4086e000}, + {0x40870000}, {0x40872000}, {0x40874000}, {0x40876000}, + {0x40878000}, {0x4087a000}, {0x4087c000}, {0x4087e000}, + {0x40880000}, {0x40882000}, {0x40884000}, {0x40886000}, + {0x40888000}, {0x4088a000}, {0x4088c000}, {0x4088e000}, + {0x40890000}, {0x40892000}, {0x40894000}, {0x40896000}, + {0x40898000}, {0x4089a000}, {0x4089c000}, {0x4089e000}, + {0x408a0000}, {0x408a2000}, {0x408a4000}, {0x408a6000}, + {0x408a8000}, {0x408aa000}, {0x408ac000}, {0x408ae000}, + {0x408b0000}, {0x408b2000}, {0x408b4000}, {0x408b6000}, + {0x408b8000}, {0x408ba000}, {0x408bc000}, {0x408be000}, + {0x408c0000}, {0x408c2000}, {0x408c4000}, {0x408c6000}, + {0x408c8000}, {0x408ca000}, {0x408cc000}, {0x408ce000}, + {0x408d0000}, {0x408d2000}, {0x408d4000}, {0x408d6000}, + {0x408d8000}, {0x408da000}, {0x408dc000}, {0x408de000}, + {0x408e0000}, {0x408e2000}, {0x408e4000}, {0x408e6000}, + {0x408e8000}, {0x408ea000}, {0x408ec000}, {0x408ee000}, + {0x408f0000}, {0x408f2000}, {0x408f4000}, {0x408f6000}, + {0x408f8000}, {0x408fa000}, {0x408fc000}, {0x408fe000}, + {0x40900000}, {0x40902000}, {0x40904000}, {0x40906000}, + {0x40908000}, {0x4090a000}, {0x4090c000}, {0x4090e000}, + {0x40910000}, {0x40912000}, {0x40914000}, {0x40916000}, + {0x40918000}, {0x4091a000}, {0x4091c000}, {0x4091e000}, + {0x40920000}, {0x40922000}, {0x40924000}, {0x40926000}, + {0x40928000}, {0x4092a000}, {0x4092c000}, {0x4092e000}, + {0x40930000}, {0x40932000}, {0x40934000}, {0x40936000}, + {0x40938000}, {0x4093a000}, {0x4093c000}, {0x4093e000}, + {0x40940000}, {0x40942000}, {0x40944000}, {0x40946000}, + {0x40948000}, {0x4094a000}, {0x4094c000}, {0x4094e000}, + {0x40950000}, {0x40952000}, {0x40954000}, {0x40956000}, + {0x40958000}, {0x4095a000}, {0x4095c000}, {0x4095e000}, + {0x40960000}, {0x40962000}, {0x40964000}, {0x40966000}, + {0x40968000}, {0x4096a000}, {0x4096c000}, {0x4096e000}, + {0x40970000}, {0x40972000}, {0x40974000}, {0x40976000}, + {0x40978000}, {0x4097a000}, {0x4097c000}, {0x4097e000}, + {0x40980000}, {0x40982000}, {0x40984000}, {0x40986000}, + {0x40988000}, {0x4098a000}, {0x4098c000}, {0x4098e000}, + {0x40990000}, {0x40992000}, {0x40994000}, {0x40996000}, + {0x40998000}, {0x4099a000}, {0x4099c000}, {0x4099e000}, + {0x409a0000}, {0x409a2000}, {0x409a4000}, {0x409a6000}, + {0x409a8000}, {0x409aa000}, {0x409ac000}, {0x409ae000}, + {0x409b0000}, {0x409b2000}, {0x409b4000}, {0x409b6000}, + {0x409b8000}, {0x409ba000}, {0x409bc000}, {0x409be000}, + {0x409c0000}, {0x409c2000}, {0x409c4000}, {0x409c6000}, + {0x409c8000}, {0x409ca000}, {0x409cc000}, {0x409ce000}, + {0x409d0000}, {0x409d2000}, {0x409d4000}, {0x409d6000}, + {0x409d8000}, {0x409da000}, {0x409dc000}, {0x409de000}, + {0x409e0000}, {0x409e2000}, {0x409e4000}, {0x409e6000}, + {0x409e8000}, {0x409ea000}, {0x409ec000}, {0x409ee000}, + {0x409f0000}, {0x409f2000}, {0x409f4000}, {0x409f6000}, + {0x409f8000}, {0x409fa000}, {0x409fc000}, {0x409fe000}, + {0x40a00000}, {0x40a02000}, {0x40a04000}, {0x40a06000}, + {0x40a08000}, {0x40a0a000}, {0x40a0c000}, {0x40a0e000}, + {0x40a10000}, {0x40a12000}, {0x40a14000}, {0x40a16000}, + {0x40a18000}, {0x40a1a000}, {0x40a1c000}, {0x40a1e000}, + {0x40a20000}, {0x40a22000}, {0x40a24000}, {0x40a26000}, + {0x40a28000}, {0x40a2a000}, {0x40a2c000}, {0x40a2e000}, + {0x40a30000}, {0x40a32000}, {0x40a34000}, {0x40a36000}, + {0x40a38000}, {0x40a3a000}, {0x40a3c000}, {0x40a3e000}, + {0x40a40000}, {0x40a42000}, {0x40a44000}, {0x40a46000}, + {0x40a48000}, {0x40a4a000}, {0x40a4c000}, {0x40a4e000}, + {0x40a50000}, {0x40a52000}, {0x40a54000}, {0x40a56000}, + {0x40a58000}, {0x40a5a000}, {0x40a5c000}, {0x40a5e000}, + {0x40a60000}, {0x40a62000}, {0x40a64000}, {0x40a66000}, + {0x40a68000}, {0x40a6a000}, {0x40a6c000}, {0x40a6e000}, + {0x40a70000}, {0x40a72000}, {0x40a74000}, {0x40a76000}, + {0x40a78000}, {0x40a7a000}, {0x40a7c000}, {0x40a7e000}, + {0x40a80000}, {0x40a82000}, {0x40a84000}, {0x40a86000}, + {0x40a88000}, {0x40a8a000}, {0x40a8c000}, {0x40a8e000}, + {0x40a90000}, {0x40a92000}, {0x40a94000}, {0x40a96000}, + {0x40a98000}, {0x40a9a000}, {0x40a9c000}, {0x40a9e000}, + {0x40aa0000}, {0x40aa2000}, {0x40aa4000}, {0x40aa6000}, + {0x40aa8000}, {0x40aaa000}, {0x40aac000}, {0x40aae000}, + {0x40ab0000}, {0x40ab2000}, {0x40ab4000}, {0x40ab6000}, + {0x40ab8000}, {0x40aba000}, {0x40abc000}, {0x40abe000}, + {0x40ac0000}, {0x40ac2000}, {0x40ac4000}, {0x40ac6000}, + {0x40ac8000}, {0x40aca000}, {0x40acc000}, {0x40ace000}, + {0x40ad0000}, {0x40ad2000}, {0x40ad4000}, {0x40ad6000}, + {0x40ad8000}, {0x40ada000}, {0x40adc000}, {0x40ade000}, + {0x40ae0000}, {0x40ae2000}, {0x40ae4000}, {0x40ae6000}, + {0x40ae8000}, {0x40aea000}, {0x40aec000}, {0x40aee000}, + {0x40af0000}, {0x40af2000}, {0x40af4000}, {0x40af6000}, + {0x40af8000}, {0x40afa000}, {0x40afc000}, {0x40afe000}, + {0x40b00000}, {0x40b02000}, {0x40b04000}, {0x40b06000}, + {0x40b08000}, {0x40b0a000}, {0x40b0c000}, {0x40b0e000}, + {0x40b10000}, {0x40b12000}, {0x40b14000}, {0x40b16000}, + {0x40b18000}, {0x40b1a000}, {0x40b1c000}, {0x40b1e000}, + {0x40b20000}, {0x40b22000}, {0x40b24000}, {0x40b26000}, + {0x40b28000}, {0x40b2a000}, {0x40b2c000}, {0x40b2e000}, + {0x40b30000}, {0x40b32000}, {0x40b34000}, {0x40b36000}, + {0x40b38000}, {0x40b3a000}, {0x40b3c000}, {0x40b3e000}, + {0x40b40000}, {0x40b42000}, {0x40b44000}, {0x40b46000}, + {0x40b48000}, {0x40b4a000}, {0x40b4c000}, {0x40b4e000}, + {0x40b50000}, {0x40b52000}, {0x40b54000}, {0x40b56000}, + {0x40b58000}, {0x40b5a000}, {0x40b5c000}, {0x40b5e000}, + {0x40b60000}, {0x40b62000}, {0x40b64000}, {0x40b66000}, + {0x40b68000}, {0x40b6a000}, {0x40b6c000}, {0x40b6e000}, + {0x40b70000}, {0x40b72000}, {0x40b74000}, {0x40b76000}, + {0x40b78000}, {0x40b7a000}, {0x40b7c000}, {0x40b7e000}, + {0x40b80000}, {0x40b82000}, {0x40b84000}, {0x40b86000}, + {0x40b88000}, {0x40b8a000}, {0x40b8c000}, {0x40b8e000}, + {0x40b90000}, {0x40b92000}, {0x40b94000}, {0x40b96000}, + {0x40b98000}, {0x40b9a000}, {0x40b9c000}, {0x40b9e000}, + {0x40ba0000}, {0x40ba2000}, {0x40ba4000}, {0x40ba6000}, + {0x40ba8000}, {0x40baa000}, {0x40bac000}, {0x40bae000}, + {0x40bb0000}, {0x40bb2000}, {0x40bb4000}, {0x40bb6000}, + {0x40bb8000}, {0x40bba000}, {0x40bbc000}, {0x40bbe000}, + {0x40bc0000}, {0x40bc2000}, {0x40bc4000}, {0x40bc6000}, + {0x40bc8000}, {0x40bca000}, {0x40bcc000}, {0x40bce000}, + {0x40bd0000}, {0x40bd2000}, {0x40bd4000}, {0x40bd6000}, + {0x40bd8000}, {0x40bda000}, {0x40bdc000}, {0x40bde000}, + {0x40be0000}, {0x40be2000}, {0x40be4000}, {0x40be6000}, + {0x40be8000}, {0x40bea000}, {0x40bec000}, {0x40bee000}, + {0x40bf0000}, {0x40bf2000}, {0x40bf4000}, {0x40bf6000}, + {0x40bf8000}, {0x40bfa000}, {0x40bfc000}, {0x40bfe000}, + {0x40c00000}, {0x40c02000}, {0x40c04000}, {0x40c06000}, + {0x40c08000}, {0x40c0a000}, {0x40c0c000}, {0x40c0e000}, + {0x40c10000}, {0x40c12000}, {0x40c14000}, {0x40c16000}, + {0x40c18000}, {0x40c1a000}, {0x40c1c000}, {0x40c1e000}, + {0x40c20000}, {0x40c22000}, {0x40c24000}, {0x40c26000}, + {0x40c28000}, {0x40c2a000}, {0x40c2c000}, {0x40c2e000}, + {0x40c30000}, {0x40c32000}, {0x40c34000}, {0x40c36000}, + {0x40c38000}, {0x40c3a000}, {0x40c3c000}, {0x40c3e000}, + {0x40c40000}, {0x40c42000}, {0x40c44000}, {0x40c46000}, + {0x40c48000}, {0x40c4a000}, {0x40c4c000}, {0x40c4e000}, + {0x40c50000}, {0x40c52000}, {0x40c54000}, {0x40c56000}, + {0x40c58000}, {0x40c5a000}, {0x40c5c000}, {0x40c5e000}, + {0x40c60000}, {0x40c62000}, {0x40c64000}, {0x40c66000}, + {0x40c68000}, {0x40c6a000}, {0x40c6c000}, {0x40c6e000}, + {0x40c70000}, {0x40c72000}, {0x40c74000}, {0x40c76000}, + {0x40c78000}, {0x40c7a000}, {0x40c7c000}, {0x40c7e000}, + {0x40c80000}, {0x40c82000}, {0x40c84000}, {0x40c86000}, + {0x40c88000}, {0x40c8a000}, {0x40c8c000}, {0x40c8e000}, + {0x40c90000}, {0x40c92000}, {0x40c94000}, {0x40c96000}, + {0x40c98000}, {0x40c9a000}, {0x40c9c000}, {0x40c9e000}, + {0x40ca0000}, {0x40ca2000}, {0x40ca4000}, {0x40ca6000}, + {0x40ca8000}, {0x40caa000}, {0x40cac000}, {0x40cae000}, + {0x40cb0000}, {0x40cb2000}, {0x40cb4000}, {0x40cb6000}, + {0x40cb8000}, {0x40cba000}, {0x40cbc000}, {0x40cbe000}, + {0x40cc0000}, {0x40cc2000}, {0x40cc4000}, {0x40cc6000}, + {0x40cc8000}, {0x40cca000}, {0x40ccc000}, {0x40cce000}, + {0x40cd0000}, {0x40cd2000}, {0x40cd4000}, {0x40cd6000}, + {0x40cd8000}, {0x40cda000}, {0x40cdc000}, {0x40cde000}, + {0x40ce0000}, {0x40ce2000}, {0x40ce4000}, {0x40ce6000}, + {0x40ce8000}, {0x40cea000}, {0x40cec000}, {0x40cee000}, + {0x40cf0000}, {0x40cf2000}, {0x40cf4000}, {0x40cf6000}, + {0x40cf8000}, {0x40cfa000}, {0x40cfc000}, {0x40cfe000}, + {0x40d00000}, {0x40d02000}, {0x40d04000}, {0x40d06000}, + {0x40d08000}, {0x40d0a000}, {0x40d0c000}, {0x40d0e000}, + {0x40d10000}, {0x40d12000}, {0x40d14000}, {0x40d16000}, + {0x40d18000}, {0x40d1a000}, {0x40d1c000}, {0x40d1e000}, + {0x40d20000}, {0x40d22000}, {0x40d24000}, {0x40d26000}, + {0x40d28000}, {0x40d2a000}, {0x40d2c000}, {0x40d2e000}, + {0x40d30000}, {0x40d32000}, {0x40d34000}, {0x40d36000}, + {0x40d38000}, {0x40d3a000}, {0x40d3c000}, {0x40d3e000}, + {0x40d40000}, {0x40d42000}, {0x40d44000}, {0x40d46000}, + {0x40d48000}, {0x40d4a000}, {0x40d4c000}, {0x40d4e000}, + {0x40d50000}, {0x40d52000}, {0x40d54000}, {0x40d56000}, + {0x40d58000}, {0x40d5a000}, {0x40d5c000}, {0x40d5e000}, + {0x40d60000}, {0x40d62000}, {0x40d64000}, {0x40d66000}, + {0x40d68000}, {0x40d6a000}, {0x40d6c000}, {0x40d6e000}, + {0x40d70000}, {0x40d72000}, {0x40d74000}, {0x40d76000}, + {0x40d78000}, {0x40d7a000}, {0x40d7c000}, {0x40d7e000}, + {0x40d80000}, {0x40d82000}, {0x40d84000}, {0x40d86000}, + {0x40d88000}, {0x40d8a000}, {0x40d8c000}, {0x40d8e000}, + {0x40d90000}, {0x40d92000}, {0x40d94000}, {0x40d96000}, + {0x40d98000}, {0x40d9a000}, {0x40d9c000}, {0x40d9e000}, + {0x40da0000}, {0x40da2000}, {0x40da4000}, {0x40da6000}, + {0x40da8000}, {0x40daa000}, {0x40dac000}, {0x40dae000}, + {0x40db0000}, {0x40db2000}, {0x40db4000}, {0x40db6000}, + {0x40db8000}, {0x40dba000}, {0x40dbc000}, {0x40dbe000}, + {0x40dc0000}, {0x40dc2000}, {0x40dc4000}, {0x40dc6000}, + {0x40dc8000}, {0x40dca000}, {0x40dcc000}, {0x40dce000}, + {0x40dd0000}, {0x40dd2000}, {0x40dd4000}, {0x40dd6000}, + {0x40dd8000}, {0x40dda000}, {0x40ddc000}, {0x40dde000}, + {0x40de0000}, {0x40de2000}, {0x40de4000}, {0x40de6000}, + {0x40de8000}, {0x40dea000}, {0x40dec000}, {0x40dee000}, + {0x40df0000}, {0x40df2000}, {0x40df4000}, {0x40df6000}, + {0x40df8000}, {0x40dfa000}, {0x40dfc000}, {0x40dfe000}, + {0x40e00000}, {0x40e02000}, {0x40e04000}, {0x40e06000}, + {0x40e08000}, {0x40e0a000}, {0x40e0c000}, {0x40e0e000}, + {0x40e10000}, {0x40e12000}, {0x40e14000}, {0x40e16000}, + {0x40e18000}, {0x40e1a000}, {0x40e1c000}, {0x40e1e000}, + {0x40e20000}, {0x40e22000}, {0x40e24000}, {0x40e26000}, + {0x40e28000}, {0x40e2a000}, {0x40e2c000}, {0x40e2e000}, + {0x40e30000}, {0x40e32000}, {0x40e34000}, {0x40e36000}, + {0x40e38000}, {0x40e3a000}, {0x40e3c000}, {0x40e3e000}, + {0x40e40000}, {0x40e42000}, {0x40e44000}, {0x40e46000}, + {0x40e48000}, {0x40e4a000}, {0x40e4c000}, {0x40e4e000}, + {0x40e50000}, {0x40e52000}, {0x40e54000}, {0x40e56000}, + {0x40e58000}, {0x40e5a000}, {0x40e5c000}, {0x40e5e000}, + {0x40e60000}, {0x40e62000}, {0x40e64000}, {0x40e66000}, + {0x40e68000}, {0x40e6a000}, {0x40e6c000}, {0x40e6e000}, + {0x40e70000}, {0x40e72000}, {0x40e74000}, {0x40e76000}, + {0x40e78000}, {0x40e7a000}, {0x40e7c000}, {0x40e7e000}, + {0x40e80000}, {0x40e82000}, {0x40e84000}, {0x40e86000}, + {0x40e88000}, {0x40e8a000}, {0x40e8c000}, {0x40e8e000}, + {0x40e90000}, {0x40e92000}, {0x40e94000}, {0x40e96000}, + {0x40e98000}, {0x40e9a000}, {0x40e9c000}, {0x40e9e000}, + {0x40ea0000}, {0x40ea2000}, {0x40ea4000}, {0x40ea6000}, + {0x40ea8000}, {0x40eaa000}, {0x40eac000}, {0x40eae000}, + {0x40eb0000}, {0x40eb2000}, {0x40eb4000}, {0x40eb6000}, + {0x40eb8000}, {0x40eba000}, {0x40ebc000}, {0x40ebe000}, + {0x40ec0000}, {0x40ec2000}, {0x40ec4000}, {0x40ec6000}, + {0x40ec8000}, {0x40eca000}, {0x40ecc000}, {0x40ece000}, + {0x40ed0000}, {0x40ed2000}, {0x40ed4000}, {0x40ed6000}, + {0x40ed8000}, {0x40eda000}, {0x40edc000}, {0x40ede000}, + {0x40ee0000}, {0x40ee2000}, {0x40ee4000}, {0x40ee6000}, + {0x40ee8000}, {0x40eea000}, {0x40eec000}, {0x40eee000}, + {0x40ef0000}, {0x40ef2000}, {0x40ef4000}, {0x40ef6000}, + {0x40ef8000}, {0x40efa000}, {0x40efc000}, {0x40efe000}, + {0x40f00000}, {0x40f02000}, {0x40f04000}, {0x40f06000}, + {0x40f08000}, {0x40f0a000}, {0x40f0c000}, {0x40f0e000}, + {0x40f10000}, {0x40f12000}, {0x40f14000}, {0x40f16000}, + {0x40f18000}, {0x40f1a000}, {0x40f1c000}, {0x40f1e000}, + {0x40f20000}, {0x40f22000}, {0x40f24000}, {0x40f26000}, + {0x40f28000}, {0x40f2a000}, {0x40f2c000}, {0x40f2e000}, + {0x40f30000}, {0x40f32000}, {0x40f34000}, {0x40f36000}, + {0x40f38000}, {0x40f3a000}, {0x40f3c000}, {0x40f3e000}, + {0x40f40000}, {0x40f42000}, {0x40f44000}, {0x40f46000}, + {0x40f48000}, {0x40f4a000}, {0x40f4c000}, {0x40f4e000}, + {0x40f50000}, {0x40f52000}, {0x40f54000}, {0x40f56000}, + {0x40f58000}, {0x40f5a000}, {0x40f5c000}, {0x40f5e000}, + {0x40f60000}, {0x40f62000}, {0x40f64000}, {0x40f66000}, + {0x40f68000}, {0x40f6a000}, {0x40f6c000}, {0x40f6e000}, + {0x40f70000}, {0x40f72000}, {0x40f74000}, {0x40f76000}, + {0x40f78000}, {0x40f7a000}, {0x40f7c000}, {0x40f7e000}, + {0x40f80000}, {0x40f82000}, {0x40f84000}, {0x40f86000}, + {0x40f88000}, {0x40f8a000}, {0x40f8c000}, {0x40f8e000}, + {0x40f90000}, {0x40f92000}, {0x40f94000}, {0x40f96000}, + {0x40f98000}, {0x40f9a000}, {0x40f9c000}, {0x40f9e000}, + {0x40fa0000}, {0x40fa2000}, {0x40fa4000}, {0x40fa6000}, + {0x40fa8000}, {0x40faa000}, {0x40fac000}, {0x40fae000}, + {0x40fb0000}, {0x40fb2000}, {0x40fb4000}, {0x40fb6000}, + {0x40fb8000}, {0x40fba000}, {0x40fbc000}, {0x40fbe000}, + {0x40fc0000}, {0x40fc2000}, {0x40fc4000}, {0x40fc6000}, + {0x40fc8000}, {0x40fca000}, {0x40fcc000}, {0x40fce000}, + {0x40fd0000}, {0x40fd2000}, {0x40fd4000}, {0x40fd6000}, + {0x40fd8000}, {0x40fda000}, {0x40fdc000}, {0x40fde000}, + {0x40fe0000}, {0x40fe2000}, {0x40fe4000}, {0x40fe6000}, + {0x40fe8000}, {0x40fea000}, {0x40fec000}, {0x40fee000}, + {0x40ff0000}, {0x40ff2000}, {0x40ff4000}, {0x40ff6000}, + {0x40ff8000}, {0x40ffa000}, {0x40ffc000}, {0x40ffe000}, + {0x41000000}, {0x41002000}, {0x41004000}, {0x41006000}, + {0x41008000}, {0x4100a000}, {0x4100c000}, {0x4100e000}, + {0x41010000}, {0x41012000}, {0x41014000}, {0x41016000}, + {0x41018000}, {0x4101a000}, {0x4101c000}, {0x4101e000}, + {0x41020000}, {0x41022000}, {0x41024000}, {0x41026000}, + {0x41028000}, {0x4102a000}, {0x4102c000}, {0x4102e000}, + {0x41030000}, {0x41032000}, {0x41034000}, {0x41036000}, + {0x41038000}, {0x4103a000}, {0x4103c000}, {0x4103e000}, + {0x41040000}, {0x41042000}, {0x41044000}, {0x41046000}, + {0x41048000}, {0x4104a000}, {0x4104c000}, {0x4104e000}, + {0x41050000}, {0x41052000}, {0x41054000}, {0x41056000}, + {0x41058000}, {0x4105a000}, {0x4105c000}, {0x4105e000}, + {0x41060000}, {0x41062000}, {0x41064000}, {0x41066000}, + {0x41068000}, {0x4106a000}, {0x4106c000}, {0x4106e000}, + {0x41070000}, {0x41072000}, {0x41074000}, {0x41076000}, + {0x41078000}, {0x4107a000}, {0x4107c000}, {0x4107e000}, + {0x41080000}, {0x41082000}, {0x41084000}, {0x41086000}, + {0x41088000}, {0x4108a000}, {0x4108c000}, {0x4108e000}, + {0x41090000}, {0x41092000}, {0x41094000}, {0x41096000}, + {0x41098000}, {0x4109a000}, {0x4109c000}, {0x4109e000}, + {0x410a0000}, {0x410a2000}, {0x410a4000}, {0x410a6000}, + {0x410a8000}, {0x410aa000}, {0x410ac000}, {0x410ae000}, + {0x410b0000}, {0x410b2000}, {0x410b4000}, {0x410b6000}, + {0x410b8000}, {0x410ba000}, {0x410bc000}, {0x410be000}, + {0x410c0000}, {0x410c2000}, {0x410c4000}, {0x410c6000}, + {0x410c8000}, {0x410ca000}, {0x410cc000}, {0x410ce000}, + {0x410d0000}, {0x410d2000}, {0x410d4000}, {0x410d6000}, + {0x410d8000}, {0x410da000}, {0x410dc000}, {0x410de000}, + {0x410e0000}, {0x410e2000}, {0x410e4000}, {0x410e6000}, + {0x410e8000}, {0x410ea000}, {0x410ec000}, {0x410ee000}, + {0x410f0000}, {0x410f2000}, {0x410f4000}, {0x410f6000}, + {0x410f8000}, {0x410fa000}, {0x410fc000}, {0x410fe000}, + {0x41100000}, {0x41102000}, {0x41104000}, {0x41106000}, + {0x41108000}, {0x4110a000}, {0x4110c000}, {0x4110e000}, + {0x41110000}, {0x41112000}, {0x41114000}, {0x41116000}, + {0x41118000}, {0x4111a000}, {0x4111c000}, {0x4111e000}, + {0x41120000}, {0x41122000}, {0x41124000}, {0x41126000}, + {0x41128000}, {0x4112a000}, {0x4112c000}, {0x4112e000}, + {0x41130000}, {0x41132000}, {0x41134000}, {0x41136000}, + {0x41138000}, {0x4113a000}, {0x4113c000}, {0x4113e000}, + {0x41140000}, {0x41142000}, {0x41144000}, {0x41146000}, + {0x41148000}, {0x4114a000}, {0x4114c000}, {0x4114e000}, + {0x41150000}, {0x41152000}, {0x41154000}, {0x41156000}, + {0x41158000}, {0x4115a000}, {0x4115c000}, {0x4115e000}, + {0x41160000}, {0x41162000}, {0x41164000}, {0x41166000}, + {0x41168000}, {0x4116a000}, {0x4116c000}, {0x4116e000}, + {0x41170000}, {0x41172000}, {0x41174000}, {0x41176000}, + {0x41178000}, {0x4117a000}, {0x4117c000}, {0x4117e000}, + {0x41180000}, {0x41182000}, {0x41184000}, {0x41186000}, + {0x41188000}, {0x4118a000}, {0x4118c000}, {0x4118e000}, + {0x41190000}, {0x41192000}, {0x41194000}, {0x41196000}, + {0x41198000}, {0x4119a000}, {0x4119c000}, {0x4119e000}, + {0x411a0000}, {0x411a2000}, {0x411a4000}, {0x411a6000}, + {0x411a8000}, {0x411aa000}, {0x411ac000}, {0x411ae000}, + {0x411b0000}, {0x411b2000}, {0x411b4000}, {0x411b6000}, + {0x411b8000}, {0x411ba000}, {0x411bc000}, {0x411be000}, + {0x411c0000}, {0x411c2000}, {0x411c4000}, {0x411c6000}, + {0x411c8000}, {0x411ca000}, {0x411cc000}, {0x411ce000}, + {0x411d0000}, {0x411d2000}, {0x411d4000}, {0x411d6000}, + {0x411d8000}, {0x411da000}, {0x411dc000}, {0x411de000}, + {0x411e0000}, {0x411e2000}, {0x411e4000}, {0x411e6000}, + {0x411e8000}, {0x411ea000}, {0x411ec000}, {0x411ee000}, + {0x411f0000}, {0x411f2000}, {0x411f4000}, {0x411f6000}, + {0x411f8000}, {0x411fa000}, {0x411fc000}, {0x411fe000}, + {0x41200000}, {0x41202000}, {0x41204000}, {0x41206000}, + {0x41208000}, {0x4120a000}, {0x4120c000}, {0x4120e000}, + {0x41210000}, {0x41212000}, {0x41214000}, {0x41216000}, + {0x41218000}, {0x4121a000}, {0x4121c000}, {0x4121e000}, + {0x41220000}, {0x41222000}, {0x41224000}, {0x41226000}, + {0x41228000}, {0x4122a000}, {0x4122c000}, {0x4122e000}, + {0x41230000}, {0x41232000}, {0x41234000}, {0x41236000}, + {0x41238000}, {0x4123a000}, {0x4123c000}, {0x4123e000}, + {0x41240000}, {0x41242000}, {0x41244000}, {0x41246000}, + {0x41248000}, {0x4124a000}, {0x4124c000}, {0x4124e000}, + {0x41250000}, {0x41252000}, {0x41254000}, {0x41256000}, + {0x41258000}, {0x4125a000}, {0x4125c000}, {0x4125e000}, + {0x41260000}, {0x41262000}, {0x41264000}, {0x41266000}, + {0x41268000}, {0x4126a000}, {0x4126c000}, {0x4126e000}, + {0x41270000}, {0x41272000}, {0x41274000}, {0x41276000}, + {0x41278000}, {0x4127a000}, {0x4127c000}, {0x4127e000}, + {0x41280000}, {0x41282000}, {0x41284000}, {0x41286000}, + {0x41288000}, {0x4128a000}, {0x4128c000}, {0x4128e000}, + {0x41290000}, {0x41292000}, {0x41294000}, {0x41296000}, + {0x41298000}, {0x4129a000}, {0x4129c000}, {0x4129e000}, + {0x412a0000}, {0x412a2000}, {0x412a4000}, {0x412a6000}, + {0x412a8000}, {0x412aa000}, {0x412ac000}, {0x412ae000}, + {0x412b0000}, {0x412b2000}, {0x412b4000}, {0x412b6000}, + {0x412b8000}, {0x412ba000}, {0x412bc000}, {0x412be000}, + {0x412c0000}, {0x412c2000}, {0x412c4000}, {0x412c6000}, + {0x412c8000}, {0x412ca000}, {0x412cc000}, {0x412ce000}, + {0x412d0000}, {0x412d2000}, {0x412d4000}, {0x412d6000}, + {0x412d8000}, {0x412da000}, {0x412dc000}, {0x412de000}, + {0x412e0000}, {0x412e2000}, {0x412e4000}, {0x412e6000}, + {0x412e8000}, {0x412ea000}, {0x412ec000}, {0x412ee000}, + {0x412f0000}, {0x412f2000}, {0x412f4000}, {0x412f6000}, + {0x412f8000}, {0x412fa000}, {0x412fc000}, {0x412fe000}, + {0x41300000}, {0x41302000}, {0x41304000}, {0x41306000}, + {0x41308000}, {0x4130a000}, {0x4130c000}, {0x4130e000}, + {0x41310000}, {0x41312000}, {0x41314000}, {0x41316000}, + {0x41318000}, {0x4131a000}, {0x4131c000}, {0x4131e000}, + {0x41320000}, {0x41322000}, {0x41324000}, {0x41326000}, + {0x41328000}, {0x4132a000}, {0x4132c000}, {0x4132e000}, + {0x41330000}, {0x41332000}, {0x41334000}, {0x41336000}, + {0x41338000}, {0x4133a000}, {0x4133c000}, {0x4133e000}, + {0x41340000}, {0x41342000}, {0x41344000}, {0x41346000}, + {0x41348000}, {0x4134a000}, {0x4134c000}, {0x4134e000}, + {0x41350000}, {0x41352000}, {0x41354000}, {0x41356000}, + {0x41358000}, {0x4135a000}, {0x4135c000}, {0x4135e000}, + {0x41360000}, {0x41362000}, {0x41364000}, {0x41366000}, + {0x41368000}, {0x4136a000}, {0x4136c000}, {0x4136e000}, + {0x41370000}, {0x41372000}, {0x41374000}, {0x41376000}, + {0x41378000}, {0x4137a000}, {0x4137c000}, {0x4137e000}, + {0x41380000}, {0x41382000}, {0x41384000}, {0x41386000}, + {0x41388000}, {0x4138a000}, {0x4138c000}, {0x4138e000}, + {0x41390000}, {0x41392000}, {0x41394000}, {0x41396000}, + {0x41398000}, {0x4139a000}, {0x4139c000}, {0x4139e000}, + {0x413a0000}, {0x413a2000}, {0x413a4000}, {0x413a6000}, + {0x413a8000}, {0x413aa000}, {0x413ac000}, {0x413ae000}, + {0x413b0000}, {0x413b2000}, {0x413b4000}, {0x413b6000}, + {0x413b8000}, {0x413ba000}, {0x413bc000}, {0x413be000}, + {0x413c0000}, {0x413c2000}, {0x413c4000}, {0x413c6000}, + {0x413c8000}, {0x413ca000}, {0x413cc000}, {0x413ce000}, + {0x413d0000}, {0x413d2000}, {0x413d4000}, {0x413d6000}, + {0x413d8000}, {0x413da000}, {0x413dc000}, {0x413de000}, + {0x413e0000}, {0x413e2000}, {0x413e4000}, {0x413e6000}, + {0x413e8000}, {0x413ea000}, {0x413ec000}, {0x413ee000}, + {0x413f0000}, {0x413f2000}, {0x413f4000}, {0x413f6000}, + {0x413f8000}, {0x413fa000}, {0x413fc000}, {0x413fe000}, + {0x41400000}, {0x41402000}, {0x41404000}, {0x41406000}, + {0x41408000}, {0x4140a000}, {0x4140c000}, {0x4140e000}, + {0x41410000}, {0x41412000}, {0x41414000}, {0x41416000}, + {0x41418000}, {0x4141a000}, {0x4141c000}, {0x4141e000}, + {0x41420000}, {0x41422000}, {0x41424000}, {0x41426000}, + {0x41428000}, {0x4142a000}, {0x4142c000}, {0x4142e000}, + {0x41430000}, {0x41432000}, {0x41434000}, {0x41436000}, + {0x41438000}, {0x4143a000}, {0x4143c000}, {0x4143e000}, + {0x41440000}, {0x41442000}, {0x41444000}, {0x41446000}, + {0x41448000}, {0x4144a000}, {0x4144c000}, {0x4144e000}, + {0x41450000}, {0x41452000}, {0x41454000}, {0x41456000}, + {0x41458000}, {0x4145a000}, {0x4145c000}, {0x4145e000}, + {0x41460000}, {0x41462000}, {0x41464000}, {0x41466000}, + {0x41468000}, {0x4146a000}, {0x4146c000}, {0x4146e000}, + {0x41470000}, {0x41472000}, {0x41474000}, {0x41476000}, + {0x41478000}, {0x4147a000}, {0x4147c000}, {0x4147e000}, + {0x41480000}, {0x41482000}, {0x41484000}, {0x41486000}, + {0x41488000}, {0x4148a000}, {0x4148c000}, {0x4148e000}, + {0x41490000}, {0x41492000}, {0x41494000}, {0x41496000}, + {0x41498000}, {0x4149a000}, {0x4149c000}, {0x4149e000}, + {0x414a0000}, {0x414a2000}, {0x414a4000}, {0x414a6000}, + {0x414a8000}, {0x414aa000}, {0x414ac000}, {0x414ae000}, + {0x414b0000}, {0x414b2000}, {0x414b4000}, {0x414b6000}, + {0x414b8000}, {0x414ba000}, {0x414bc000}, {0x414be000}, + {0x414c0000}, {0x414c2000}, {0x414c4000}, {0x414c6000}, + {0x414c8000}, {0x414ca000}, {0x414cc000}, {0x414ce000}, + {0x414d0000}, {0x414d2000}, {0x414d4000}, {0x414d6000}, + {0x414d8000}, {0x414da000}, {0x414dc000}, {0x414de000}, + {0x414e0000}, {0x414e2000}, {0x414e4000}, {0x414e6000}, + {0x414e8000}, {0x414ea000}, {0x414ec000}, {0x414ee000}, + {0x414f0000}, {0x414f2000}, {0x414f4000}, {0x414f6000}, + {0x414f8000}, {0x414fa000}, {0x414fc000}, {0x414fe000}, + {0x41500000}, {0x41502000}, {0x41504000}, {0x41506000}, + {0x41508000}, {0x4150a000}, {0x4150c000}, {0x4150e000}, + {0x41510000}, {0x41512000}, {0x41514000}, {0x41516000}, + {0x41518000}, {0x4151a000}, {0x4151c000}, {0x4151e000}, + {0x41520000}, {0x41522000}, {0x41524000}, {0x41526000}, + {0x41528000}, {0x4152a000}, {0x4152c000}, {0x4152e000}, + {0x41530000}, {0x41532000}, {0x41534000}, {0x41536000}, + {0x41538000}, {0x4153a000}, {0x4153c000}, {0x4153e000}, + {0x41540000}, {0x41542000}, {0x41544000}, {0x41546000}, + {0x41548000}, {0x4154a000}, {0x4154c000}, {0x4154e000}, + {0x41550000}, {0x41552000}, {0x41554000}, {0x41556000}, + {0x41558000}, {0x4155a000}, {0x4155c000}, {0x4155e000}, + {0x41560000}, {0x41562000}, {0x41564000}, {0x41566000}, + {0x41568000}, {0x4156a000}, {0x4156c000}, {0x4156e000}, + {0x41570000}, {0x41572000}, {0x41574000}, {0x41576000}, + {0x41578000}, {0x4157a000}, {0x4157c000}, {0x4157e000}, + {0x41580000}, {0x41582000}, {0x41584000}, {0x41586000}, + {0x41588000}, {0x4158a000}, {0x4158c000}, {0x4158e000}, + {0x41590000}, {0x41592000}, {0x41594000}, {0x41596000}, + {0x41598000}, {0x4159a000}, {0x4159c000}, {0x4159e000}, + {0x415a0000}, {0x415a2000}, {0x415a4000}, {0x415a6000}, + {0x415a8000}, {0x415aa000}, {0x415ac000}, {0x415ae000}, + {0x415b0000}, {0x415b2000}, {0x415b4000}, {0x415b6000}, + {0x415b8000}, {0x415ba000}, {0x415bc000}, {0x415be000}, + {0x415c0000}, {0x415c2000}, {0x415c4000}, {0x415c6000}, + {0x415c8000}, {0x415ca000}, {0x415cc000}, {0x415ce000}, + {0x415d0000}, {0x415d2000}, {0x415d4000}, {0x415d6000}, + {0x415d8000}, {0x415da000}, {0x415dc000}, {0x415de000}, + {0x415e0000}, {0x415e2000}, {0x415e4000}, {0x415e6000}, + {0x415e8000}, {0x415ea000}, {0x415ec000}, {0x415ee000}, + {0x415f0000}, {0x415f2000}, {0x415f4000}, {0x415f6000}, + {0x415f8000}, {0x415fa000}, {0x415fc000}, {0x415fe000}, + {0x41600000}, {0x41602000}, {0x41604000}, {0x41606000}, + {0x41608000}, {0x4160a000}, {0x4160c000}, {0x4160e000}, + {0x41610000}, {0x41612000}, {0x41614000}, {0x41616000}, + {0x41618000}, {0x4161a000}, {0x4161c000}, {0x4161e000}, + {0x41620000}, {0x41622000}, {0x41624000}, {0x41626000}, + {0x41628000}, {0x4162a000}, {0x4162c000}, {0x4162e000}, + {0x41630000}, {0x41632000}, {0x41634000}, {0x41636000}, + {0x41638000}, {0x4163a000}, {0x4163c000}, {0x4163e000}, + {0x41640000}, {0x41642000}, {0x41644000}, {0x41646000}, + {0x41648000}, {0x4164a000}, {0x4164c000}, {0x4164e000}, + {0x41650000}, {0x41652000}, {0x41654000}, {0x41656000}, + {0x41658000}, {0x4165a000}, {0x4165c000}, {0x4165e000}, + {0x41660000}, {0x41662000}, {0x41664000}, {0x41666000}, + {0x41668000}, {0x4166a000}, {0x4166c000}, {0x4166e000}, + {0x41670000}, {0x41672000}, {0x41674000}, {0x41676000}, + {0x41678000}, {0x4167a000}, {0x4167c000}, {0x4167e000}, + {0x41680000}, {0x41682000}, {0x41684000}, {0x41686000}, + {0x41688000}, {0x4168a000}, {0x4168c000}, {0x4168e000}, + {0x41690000}, {0x41692000}, {0x41694000}, {0x41696000}, + {0x41698000}, {0x4169a000}, {0x4169c000}, {0x4169e000}, + {0x416a0000}, {0x416a2000}, {0x416a4000}, {0x416a6000}, + {0x416a8000}, {0x416aa000}, {0x416ac000}, {0x416ae000}, + {0x416b0000}, {0x416b2000}, {0x416b4000}, {0x416b6000}, + {0x416b8000}, {0x416ba000}, {0x416bc000}, {0x416be000}, + {0x416c0000}, {0x416c2000}, {0x416c4000}, {0x416c6000}, + {0x416c8000}, {0x416ca000}, {0x416cc000}, {0x416ce000}, + {0x416d0000}, {0x416d2000}, {0x416d4000}, {0x416d6000}, + {0x416d8000}, {0x416da000}, {0x416dc000}, {0x416de000}, + {0x416e0000}, {0x416e2000}, {0x416e4000}, {0x416e6000}, + {0x416e8000}, {0x416ea000}, {0x416ec000}, {0x416ee000}, + {0x416f0000}, {0x416f2000}, {0x416f4000}, {0x416f6000}, + {0x416f8000}, {0x416fa000}, {0x416fc000}, {0x416fe000}, + {0x41700000}, {0x41702000}, {0x41704000}, {0x41706000}, + {0x41708000}, {0x4170a000}, {0x4170c000}, {0x4170e000}, + {0x41710000}, {0x41712000}, {0x41714000}, {0x41716000}, + {0x41718000}, {0x4171a000}, {0x4171c000}, {0x4171e000}, + {0x41720000}, {0x41722000}, {0x41724000}, {0x41726000}, + {0x41728000}, {0x4172a000}, {0x4172c000}, {0x4172e000}, + {0x41730000}, {0x41732000}, {0x41734000}, {0x41736000}, + {0x41738000}, {0x4173a000}, {0x4173c000}, {0x4173e000}, + {0x41740000}, {0x41742000}, {0x41744000}, {0x41746000}, + {0x41748000}, {0x4174a000}, {0x4174c000}, {0x4174e000}, + {0x41750000}, {0x41752000}, {0x41754000}, {0x41756000}, + {0x41758000}, {0x4175a000}, {0x4175c000}, {0x4175e000}, + {0x41760000}, {0x41762000}, {0x41764000}, {0x41766000}, + {0x41768000}, {0x4176a000}, {0x4176c000}, {0x4176e000}, + {0x41770000}, {0x41772000}, {0x41774000}, {0x41776000}, + {0x41778000}, {0x4177a000}, {0x4177c000}, {0x4177e000}, + {0x41780000}, {0x41782000}, {0x41784000}, {0x41786000}, + {0x41788000}, {0x4178a000}, {0x4178c000}, {0x4178e000}, + {0x41790000}, {0x41792000}, {0x41794000}, {0x41796000}, + {0x41798000}, {0x4179a000}, {0x4179c000}, {0x4179e000}, + {0x417a0000}, {0x417a2000}, {0x417a4000}, {0x417a6000}, + {0x417a8000}, {0x417aa000}, {0x417ac000}, {0x417ae000}, + {0x417b0000}, {0x417b2000}, {0x417b4000}, {0x417b6000}, + {0x417b8000}, {0x417ba000}, {0x417bc000}, {0x417be000}, + {0x417c0000}, {0x417c2000}, {0x417c4000}, {0x417c6000}, + {0x417c8000}, {0x417ca000}, {0x417cc000}, {0x417ce000}, + {0x417d0000}, {0x417d2000}, {0x417d4000}, {0x417d6000}, + {0x417d8000}, {0x417da000}, {0x417dc000}, {0x417de000}, + {0x417e0000}, {0x417e2000}, {0x417e4000}, {0x417e6000}, + {0x417e8000}, {0x417ea000}, {0x417ec000}, {0x417ee000}, + {0x417f0000}, {0x417f2000}, {0x417f4000}, {0x417f6000}, + {0x417f8000}, {0x417fa000}, {0x417fc000}, {0x417fe000}, + {0x41800000}, {0x41802000}, {0x41804000}, {0x41806000}, + {0x41808000}, {0x4180a000}, {0x4180c000}, {0x4180e000}, + {0x41810000}, {0x41812000}, {0x41814000}, {0x41816000}, + {0x41818000}, {0x4181a000}, {0x4181c000}, {0x4181e000}, + {0x41820000}, {0x41822000}, {0x41824000}, {0x41826000}, + {0x41828000}, {0x4182a000}, {0x4182c000}, {0x4182e000}, + {0x41830000}, {0x41832000}, {0x41834000}, {0x41836000}, + {0x41838000}, {0x4183a000}, {0x4183c000}, {0x4183e000}, + {0x41840000}, {0x41842000}, {0x41844000}, {0x41846000}, + {0x41848000}, {0x4184a000}, {0x4184c000}, {0x4184e000}, + {0x41850000}, {0x41852000}, {0x41854000}, {0x41856000}, + {0x41858000}, {0x4185a000}, {0x4185c000}, {0x4185e000}, + {0x41860000}, {0x41862000}, {0x41864000}, {0x41866000}, + {0x41868000}, {0x4186a000}, {0x4186c000}, {0x4186e000}, + {0x41870000}, {0x41872000}, {0x41874000}, {0x41876000}, + {0x41878000}, {0x4187a000}, {0x4187c000}, {0x4187e000}, + {0x41880000}, {0x41882000}, {0x41884000}, {0x41886000}, + {0x41888000}, {0x4188a000}, {0x4188c000}, {0x4188e000}, + {0x41890000}, {0x41892000}, {0x41894000}, {0x41896000}, + {0x41898000}, {0x4189a000}, {0x4189c000}, {0x4189e000}, + {0x418a0000}, {0x418a2000}, {0x418a4000}, {0x418a6000}, + {0x418a8000}, {0x418aa000}, {0x418ac000}, {0x418ae000}, + {0x418b0000}, {0x418b2000}, {0x418b4000}, {0x418b6000}, + {0x418b8000}, {0x418ba000}, {0x418bc000}, {0x418be000}, + {0x418c0000}, {0x418c2000}, {0x418c4000}, {0x418c6000}, + {0x418c8000}, {0x418ca000}, {0x418cc000}, {0x418ce000}, + {0x418d0000}, {0x418d2000}, {0x418d4000}, {0x418d6000}, + {0x418d8000}, {0x418da000}, {0x418dc000}, {0x418de000}, + {0x418e0000}, {0x418e2000}, {0x418e4000}, {0x418e6000}, + {0x418e8000}, {0x418ea000}, {0x418ec000}, {0x418ee000}, + {0x418f0000}, {0x418f2000}, {0x418f4000}, {0x418f6000}, + {0x418f8000}, {0x418fa000}, {0x418fc000}, {0x418fe000}, + {0x41900000}, {0x41902000}, {0x41904000}, {0x41906000}, + {0x41908000}, {0x4190a000}, {0x4190c000}, {0x4190e000}, + {0x41910000}, {0x41912000}, {0x41914000}, {0x41916000}, + {0x41918000}, {0x4191a000}, {0x4191c000}, {0x4191e000}, + {0x41920000}, {0x41922000}, {0x41924000}, {0x41926000}, + {0x41928000}, {0x4192a000}, {0x4192c000}, {0x4192e000}, + {0x41930000}, {0x41932000}, {0x41934000}, {0x41936000}, + {0x41938000}, {0x4193a000}, {0x4193c000}, {0x4193e000}, + {0x41940000}, {0x41942000}, {0x41944000}, {0x41946000}, + {0x41948000}, {0x4194a000}, {0x4194c000}, {0x4194e000}, + {0x41950000}, {0x41952000}, {0x41954000}, {0x41956000}, + {0x41958000}, {0x4195a000}, {0x4195c000}, {0x4195e000}, + {0x41960000}, {0x41962000}, {0x41964000}, {0x41966000}, + {0x41968000}, {0x4196a000}, {0x4196c000}, {0x4196e000}, + {0x41970000}, {0x41972000}, {0x41974000}, {0x41976000}, + {0x41978000}, {0x4197a000}, {0x4197c000}, {0x4197e000}, + {0x41980000}, {0x41982000}, {0x41984000}, {0x41986000}, + {0x41988000}, {0x4198a000}, {0x4198c000}, {0x4198e000}, + {0x41990000}, {0x41992000}, {0x41994000}, {0x41996000}, + {0x41998000}, {0x4199a000}, {0x4199c000}, {0x4199e000}, + {0x419a0000}, {0x419a2000}, {0x419a4000}, {0x419a6000}, + {0x419a8000}, {0x419aa000}, {0x419ac000}, {0x419ae000}, + {0x419b0000}, {0x419b2000}, {0x419b4000}, {0x419b6000}, + {0x419b8000}, {0x419ba000}, {0x419bc000}, {0x419be000}, + {0x419c0000}, {0x419c2000}, {0x419c4000}, {0x419c6000}, + {0x419c8000}, {0x419ca000}, {0x419cc000}, {0x419ce000}, + {0x419d0000}, {0x419d2000}, {0x419d4000}, {0x419d6000}, + {0x419d8000}, {0x419da000}, {0x419dc000}, {0x419de000}, + {0x419e0000}, {0x419e2000}, {0x419e4000}, {0x419e6000}, + {0x419e8000}, {0x419ea000}, {0x419ec000}, {0x419ee000}, + {0x419f0000}, {0x419f2000}, {0x419f4000}, {0x419f6000}, + {0x419f8000}, {0x419fa000}, {0x419fc000}, {0x419fe000}, + {0x41a00000}, {0x41a02000}, {0x41a04000}, {0x41a06000}, + {0x41a08000}, {0x41a0a000}, {0x41a0c000}, {0x41a0e000}, + {0x41a10000}, {0x41a12000}, {0x41a14000}, {0x41a16000}, + {0x41a18000}, {0x41a1a000}, {0x41a1c000}, {0x41a1e000}, + {0x41a20000}, {0x41a22000}, {0x41a24000}, {0x41a26000}, + {0x41a28000}, {0x41a2a000}, {0x41a2c000}, {0x41a2e000}, + {0x41a30000}, {0x41a32000}, {0x41a34000}, {0x41a36000}, + {0x41a38000}, {0x41a3a000}, {0x41a3c000}, {0x41a3e000}, + {0x41a40000}, {0x41a42000}, {0x41a44000}, {0x41a46000}, + {0x41a48000}, {0x41a4a000}, {0x41a4c000}, {0x41a4e000}, + {0x41a50000}, {0x41a52000}, {0x41a54000}, {0x41a56000}, + {0x41a58000}, {0x41a5a000}, {0x41a5c000}, {0x41a5e000}, + {0x41a60000}, {0x41a62000}, {0x41a64000}, {0x41a66000}, + {0x41a68000}, {0x41a6a000}, {0x41a6c000}, {0x41a6e000}, + {0x41a70000}, {0x41a72000}, {0x41a74000}, {0x41a76000}, + {0x41a78000}, {0x41a7a000}, {0x41a7c000}, {0x41a7e000}, + {0x41a80000}, {0x41a82000}, {0x41a84000}, {0x41a86000}, + {0x41a88000}, {0x41a8a000}, {0x41a8c000}, {0x41a8e000}, + {0x41a90000}, {0x41a92000}, {0x41a94000}, {0x41a96000}, + {0x41a98000}, {0x41a9a000}, {0x41a9c000}, {0x41a9e000}, + {0x41aa0000}, {0x41aa2000}, {0x41aa4000}, {0x41aa6000}, + {0x41aa8000}, {0x41aaa000}, {0x41aac000}, {0x41aae000}, + {0x41ab0000}, {0x41ab2000}, {0x41ab4000}, {0x41ab6000}, + {0x41ab8000}, {0x41aba000}, {0x41abc000}, {0x41abe000}, + {0x41ac0000}, {0x41ac2000}, {0x41ac4000}, {0x41ac6000}, + {0x41ac8000}, {0x41aca000}, {0x41acc000}, {0x41ace000}, + {0x41ad0000}, {0x41ad2000}, {0x41ad4000}, {0x41ad6000}, + {0x41ad8000}, {0x41ada000}, {0x41adc000}, {0x41ade000}, + {0x41ae0000}, {0x41ae2000}, {0x41ae4000}, {0x41ae6000}, + {0x41ae8000}, {0x41aea000}, {0x41aec000}, {0x41aee000}, + {0x41af0000}, {0x41af2000}, {0x41af4000}, {0x41af6000}, + {0x41af8000}, {0x41afa000}, {0x41afc000}, {0x41afe000}, + {0x41b00000}, {0x41b02000}, {0x41b04000}, {0x41b06000}, + {0x41b08000}, {0x41b0a000}, {0x41b0c000}, {0x41b0e000}, + {0x41b10000}, {0x41b12000}, {0x41b14000}, {0x41b16000}, + {0x41b18000}, {0x41b1a000}, {0x41b1c000}, {0x41b1e000}, + {0x41b20000}, {0x41b22000}, {0x41b24000}, {0x41b26000}, + {0x41b28000}, {0x41b2a000}, {0x41b2c000}, {0x41b2e000}, + {0x41b30000}, {0x41b32000}, {0x41b34000}, {0x41b36000}, + {0x41b38000}, {0x41b3a000}, {0x41b3c000}, {0x41b3e000}, + {0x41b40000}, {0x41b42000}, {0x41b44000}, {0x41b46000}, + {0x41b48000}, {0x41b4a000}, {0x41b4c000}, {0x41b4e000}, + {0x41b50000}, {0x41b52000}, {0x41b54000}, {0x41b56000}, + {0x41b58000}, {0x41b5a000}, {0x41b5c000}, {0x41b5e000}, + {0x41b60000}, {0x41b62000}, {0x41b64000}, {0x41b66000}, + {0x41b68000}, {0x41b6a000}, {0x41b6c000}, {0x41b6e000}, + {0x41b70000}, {0x41b72000}, {0x41b74000}, {0x41b76000}, + {0x41b78000}, {0x41b7a000}, {0x41b7c000}, {0x41b7e000}, + {0x41b80000}, {0x41b82000}, {0x41b84000}, {0x41b86000}, + {0x41b88000}, {0x41b8a000}, {0x41b8c000}, {0x41b8e000}, + {0x41b90000}, {0x41b92000}, {0x41b94000}, {0x41b96000}, + {0x41b98000}, {0x41b9a000}, {0x41b9c000}, {0x41b9e000}, + {0x41ba0000}, {0x41ba2000}, {0x41ba4000}, {0x41ba6000}, + {0x41ba8000}, {0x41baa000}, {0x41bac000}, {0x41bae000}, + {0x41bb0000}, {0x41bb2000}, {0x41bb4000}, {0x41bb6000}, + {0x41bb8000}, {0x41bba000}, {0x41bbc000}, {0x41bbe000}, + {0x41bc0000}, {0x41bc2000}, {0x41bc4000}, {0x41bc6000}, + {0x41bc8000}, {0x41bca000}, {0x41bcc000}, {0x41bce000}, + {0x41bd0000}, {0x41bd2000}, {0x41bd4000}, {0x41bd6000}, + {0x41bd8000}, {0x41bda000}, {0x41bdc000}, {0x41bde000}, + {0x41be0000}, {0x41be2000}, {0x41be4000}, {0x41be6000}, + {0x41be8000}, {0x41bea000}, {0x41bec000}, {0x41bee000}, + {0x41bf0000}, {0x41bf2000}, {0x41bf4000}, {0x41bf6000}, + {0x41bf8000}, {0x41bfa000}, {0x41bfc000}, {0x41bfe000}, + {0x41c00000}, {0x41c02000}, {0x41c04000}, {0x41c06000}, + {0x41c08000}, {0x41c0a000}, {0x41c0c000}, {0x41c0e000}, + {0x41c10000}, {0x41c12000}, {0x41c14000}, {0x41c16000}, + {0x41c18000}, {0x41c1a000}, {0x41c1c000}, {0x41c1e000}, + {0x41c20000}, {0x41c22000}, {0x41c24000}, {0x41c26000}, + {0x41c28000}, {0x41c2a000}, {0x41c2c000}, {0x41c2e000}, + {0x41c30000}, {0x41c32000}, {0x41c34000}, {0x41c36000}, + {0x41c38000}, {0x41c3a000}, {0x41c3c000}, {0x41c3e000}, + {0x41c40000}, {0x41c42000}, {0x41c44000}, {0x41c46000}, + {0x41c48000}, {0x41c4a000}, {0x41c4c000}, {0x41c4e000}, + {0x41c50000}, {0x41c52000}, {0x41c54000}, {0x41c56000}, + {0x41c58000}, {0x41c5a000}, {0x41c5c000}, {0x41c5e000}, + {0x41c60000}, {0x41c62000}, {0x41c64000}, {0x41c66000}, + {0x41c68000}, {0x41c6a000}, {0x41c6c000}, {0x41c6e000}, + {0x41c70000}, {0x41c72000}, {0x41c74000}, {0x41c76000}, + {0x41c78000}, {0x41c7a000}, {0x41c7c000}, {0x41c7e000}, + {0x41c80000}, {0x41c82000}, {0x41c84000}, {0x41c86000}, + {0x41c88000}, {0x41c8a000}, {0x41c8c000}, {0x41c8e000}, + {0x41c90000}, {0x41c92000}, {0x41c94000}, {0x41c96000}, + {0x41c98000}, {0x41c9a000}, {0x41c9c000}, {0x41c9e000}, + {0x41ca0000}, {0x41ca2000}, {0x41ca4000}, {0x41ca6000}, + {0x41ca8000}, {0x41caa000}, {0x41cac000}, {0x41cae000}, + {0x41cb0000}, {0x41cb2000}, {0x41cb4000}, {0x41cb6000}, + {0x41cb8000}, {0x41cba000}, {0x41cbc000}, {0x41cbe000}, + {0x41cc0000}, {0x41cc2000}, {0x41cc4000}, {0x41cc6000}, + {0x41cc8000}, {0x41cca000}, {0x41ccc000}, {0x41cce000}, + {0x41cd0000}, {0x41cd2000}, {0x41cd4000}, {0x41cd6000}, + {0x41cd8000}, {0x41cda000}, {0x41cdc000}, {0x41cde000}, + {0x41ce0000}, {0x41ce2000}, {0x41ce4000}, {0x41ce6000}, + {0x41ce8000}, {0x41cea000}, {0x41cec000}, {0x41cee000}, + {0x41cf0000}, {0x41cf2000}, {0x41cf4000}, {0x41cf6000}, + {0x41cf8000}, {0x41cfa000}, {0x41cfc000}, {0x41cfe000}, + {0x41d00000}, {0x41d02000}, {0x41d04000}, {0x41d06000}, + {0x41d08000}, {0x41d0a000}, {0x41d0c000}, {0x41d0e000}, + {0x41d10000}, {0x41d12000}, {0x41d14000}, {0x41d16000}, + {0x41d18000}, {0x41d1a000}, {0x41d1c000}, {0x41d1e000}, + {0x41d20000}, {0x41d22000}, {0x41d24000}, {0x41d26000}, + {0x41d28000}, {0x41d2a000}, {0x41d2c000}, {0x41d2e000}, + {0x41d30000}, {0x41d32000}, {0x41d34000}, {0x41d36000}, + {0x41d38000}, {0x41d3a000}, {0x41d3c000}, {0x41d3e000}, + {0x41d40000}, {0x41d42000}, {0x41d44000}, {0x41d46000}, + {0x41d48000}, {0x41d4a000}, {0x41d4c000}, {0x41d4e000}, + {0x41d50000}, {0x41d52000}, {0x41d54000}, {0x41d56000}, + {0x41d58000}, {0x41d5a000}, {0x41d5c000}, {0x41d5e000}, + {0x41d60000}, {0x41d62000}, {0x41d64000}, {0x41d66000}, + {0x41d68000}, {0x41d6a000}, {0x41d6c000}, {0x41d6e000}, + {0x41d70000}, {0x41d72000}, {0x41d74000}, {0x41d76000}, + {0x41d78000}, {0x41d7a000}, {0x41d7c000}, {0x41d7e000}, + {0x41d80000}, {0x41d82000}, {0x41d84000}, {0x41d86000}, + {0x41d88000}, {0x41d8a000}, {0x41d8c000}, {0x41d8e000}, + {0x41d90000}, {0x41d92000}, {0x41d94000}, {0x41d96000}, + {0x41d98000}, {0x41d9a000}, {0x41d9c000}, {0x41d9e000}, + {0x41da0000}, {0x41da2000}, {0x41da4000}, {0x41da6000}, + {0x41da8000}, {0x41daa000}, {0x41dac000}, {0x41dae000}, + {0x41db0000}, {0x41db2000}, {0x41db4000}, {0x41db6000}, + {0x41db8000}, {0x41dba000}, {0x41dbc000}, {0x41dbe000}, + {0x41dc0000}, {0x41dc2000}, {0x41dc4000}, {0x41dc6000}, + {0x41dc8000}, {0x41dca000}, {0x41dcc000}, {0x41dce000}, + {0x41dd0000}, {0x41dd2000}, {0x41dd4000}, {0x41dd6000}, + {0x41dd8000}, {0x41dda000}, {0x41ddc000}, {0x41dde000}, + {0x41de0000}, {0x41de2000}, {0x41de4000}, {0x41de6000}, + {0x41de8000}, {0x41dea000}, {0x41dec000}, {0x41dee000}, + {0x41df0000}, {0x41df2000}, {0x41df4000}, {0x41df6000}, + {0x41df8000}, {0x41dfa000}, {0x41dfc000}, {0x41dfe000}, + {0x41e00000}, {0x41e02000}, {0x41e04000}, {0x41e06000}, + {0x41e08000}, {0x41e0a000}, {0x41e0c000}, {0x41e0e000}, + {0x41e10000}, {0x41e12000}, {0x41e14000}, {0x41e16000}, + {0x41e18000}, {0x41e1a000}, {0x41e1c000}, {0x41e1e000}, + {0x41e20000}, {0x41e22000}, {0x41e24000}, {0x41e26000}, + {0x41e28000}, {0x41e2a000}, {0x41e2c000}, {0x41e2e000}, + {0x41e30000}, {0x41e32000}, {0x41e34000}, {0x41e36000}, + {0x41e38000}, {0x41e3a000}, {0x41e3c000}, {0x41e3e000}, + {0x41e40000}, {0x41e42000}, {0x41e44000}, {0x41e46000}, + {0x41e48000}, {0x41e4a000}, {0x41e4c000}, {0x41e4e000}, + {0x41e50000}, {0x41e52000}, {0x41e54000}, {0x41e56000}, + {0x41e58000}, {0x41e5a000}, {0x41e5c000}, {0x41e5e000}, + {0x41e60000}, {0x41e62000}, {0x41e64000}, {0x41e66000}, + {0x41e68000}, {0x41e6a000}, {0x41e6c000}, {0x41e6e000}, + {0x41e70000}, {0x41e72000}, {0x41e74000}, {0x41e76000}, + {0x41e78000}, {0x41e7a000}, {0x41e7c000}, {0x41e7e000}, + {0x41e80000}, {0x41e82000}, {0x41e84000}, {0x41e86000}, + {0x41e88000}, {0x41e8a000}, {0x41e8c000}, {0x41e8e000}, + {0x41e90000}, {0x41e92000}, {0x41e94000}, {0x41e96000}, + {0x41e98000}, {0x41e9a000}, {0x41e9c000}, {0x41e9e000}, + {0x41ea0000}, {0x41ea2000}, {0x41ea4000}, {0x41ea6000}, + {0x41ea8000}, {0x41eaa000}, {0x41eac000}, {0x41eae000}, + {0x41eb0000}, {0x41eb2000}, {0x41eb4000}, {0x41eb6000}, + {0x41eb8000}, {0x41eba000}, {0x41ebc000}, {0x41ebe000}, + {0x41ec0000}, {0x41ec2000}, {0x41ec4000}, {0x41ec6000}, + {0x41ec8000}, {0x41eca000}, {0x41ecc000}, {0x41ece000}, + {0x41ed0000}, {0x41ed2000}, {0x41ed4000}, {0x41ed6000}, + {0x41ed8000}, {0x41eda000}, {0x41edc000}, {0x41ede000}, + {0x41ee0000}, {0x41ee2000}, {0x41ee4000}, {0x41ee6000}, + {0x41ee8000}, {0x41eea000}, {0x41eec000}, {0x41eee000}, + {0x41ef0000}, {0x41ef2000}, {0x41ef4000}, {0x41ef6000}, + {0x41ef8000}, {0x41efa000}, {0x41efc000}, {0x41efe000}, + {0x41f00000}, {0x41f02000}, {0x41f04000}, {0x41f06000}, + {0x41f08000}, {0x41f0a000}, {0x41f0c000}, {0x41f0e000}, + {0x41f10000}, {0x41f12000}, {0x41f14000}, {0x41f16000}, + {0x41f18000}, {0x41f1a000}, {0x41f1c000}, {0x41f1e000}, + {0x41f20000}, {0x41f22000}, {0x41f24000}, {0x41f26000}, + {0x41f28000}, {0x41f2a000}, {0x41f2c000}, {0x41f2e000}, + {0x41f30000}, {0x41f32000}, {0x41f34000}, {0x41f36000}, + {0x41f38000}, {0x41f3a000}, {0x41f3c000}, {0x41f3e000}, + {0x41f40000}, {0x41f42000}, {0x41f44000}, {0x41f46000}, + {0x41f48000}, {0x41f4a000}, {0x41f4c000}, {0x41f4e000}, + {0x41f50000}, {0x41f52000}, {0x41f54000}, {0x41f56000}, + {0x41f58000}, {0x41f5a000}, {0x41f5c000}, {0x41f5e000}, + {0x41f60000}, {0x41f62000}, {0x41f64000}, {0x41f66000}, + {0x41f68000}, {0x41f6a000}, {0x41f6c000}, {0x41f6e000}, + {0x41f70000}, {0x41f72000}, {0x41f74000}, {0x41f76000}, + {0x41f78000}, {0x41f7a000}, {0x41f7c000}, {0x41f7e000}, + {0x41f80000}, {0x41f82000}, {0x41f84000}, {0x41f86000}, + {0x41f88000}, {0x41f8a000}, {0x41f8c000}, {0x41f8e000}, + {0x41f90000}, {0x41f92000}, {0x41f94000}, {0x41f96000}, + {0x41f98000}, {0x41f9a000}, {0x41f9c000}, {0x41f9e000}, + {0x41fa0000}, {0x41fa2000}, {0x41fa4000}, {0x41fa6000}, + {0x41fa8000}, {0x41faa000}, {0x41fac000}, {0x41fae000}, + {0x41fb0000}, {0x41fb2000}, {0x41fb4000}, {0x41fb6000}, + {0x41fb8000}, {0x41fba000}, {0x41fbc000}, {0x41fbe000}, + {0x41fc0000}, {0x41fc2000}, {0x41fc4000}, {0x41fc6000}, + {0x41fc8000}, {0x41fca000}, {0x41fcc000}, {0x41fce000}, + {0x41fd0000}, {0x41fd2000}, {0x41fd4000}, {0x41fd6000}, + {0x41fd8000}, {0x41fda000}, {0x41fdc000}, {0x41fde000}, + {0x41fe0000}, {0x41fe2000}, {0x41fe4000}, {0x41fe6000}, + {0x41fe8000}, {0x41fea000}, {0x41fec000}, {0x41fee000}, + {0x41ff0000}, {0x41ff2000}, {0x41ff4000}, {0x41ff6000}, + {0x41ff8000}, {0x41ffa000}, {0x41ffc000}, {0x41ffe000}, + {0x42000000}, {0x42002000}, {0x42004000}, {0x42006000}, + {0x42008000}, {0x4200a000}, {0x4200c000}, {0x4200e000}, + {0x42010000}, {0x42012000}, {0x42014000}, {0x42016000}, + {0x42018000}, {0x4201a000}, {0x4201c000}, {0x4201e000}, + {0x42020000}, {0x42022000}, {0x42024000}, {0x42026000}, + {0x42028000}, {0x4202a000}, {0x4202c000}, {0x4202e000}, + {0x42030000}, {0x42032000}, {0x42034000}, {0x42036000}, + {0x42038000}, {0x4203a000}, {0x4203c000}, {0x4203e000}, + {0x42040000}, {0x42042000}, {0x42044000}, {0x42046000}, + {0x42048000}, {0x4204a000}, {0x4204c000}, {0x4204e000}, + {0x42050000}, {0x42052000}, {0x42054000}, {0x42056000}, + {0x42058000}, {0x4205a000}, {0x4205c000}, {0x4205e000}, + {0x42060000}, {0x42062000}, {0x42064000}, {0x42066000}, + {0x42068000}, {0x4206a000}, {0x4206c000}, {0x4206e000}, + {0x42070000}, {0x42072000}, {0x42074000}, {0x42076000}, + {0x42078000}, {0x4207a000}, {0x4207c000}, {0x4207e000}, + {0x42080000}, {0x42082000}, {0x42084000}, {0x42086000}, + {0x42088000}, {0x4208a000}, {0x4208c000}, {0x4208e000}, + {0x42090000}, {0x42092000}, {0x42094000}, {0x42096000}, + {0x42098000}, {0x4209a000}, {0x4209c000}, {0x4209e000}, + {0x420a0000}, {0x420a2000}, {0x420a4000}, {0x420a6000}, + {0x420a8000}, {0x420aa000}, {0x420ac000}, {0x420ae000}, + {0x420b0000}, {0x420b2000}, {0x420b4000}, {0x420b6000}, + {0x420b8000}, {0x420ba000}, {0x420bc000}, {0x420be000}, + {0x420c0000}, {0x420c2000}, {0x420c4000}, {0x420c6000}, + {0x420c8000}, {0x420ca000}, {0x420cc000}, {0x420ce000}, + {0x420d0000}, {0x420d2000}, {0x420d4000}, {0x420d6000}, + {0x420d8000}, {0x420da000}, {0x420dc000}, {0x420de000}, + {0x420e0000}, {0x420e2000}, {0x420e4000}, {0x420e6000}, + {0x420e8000}, {0x420ea000}, {0x420ec000}, {0x420ee000}, + {0x420f0000}, {0x420f2000}, {0x420f4000}, {0x420f6000}, + {0x420f8000}, {0x420fa000}, {0x420fc000}, {0x420fe000}, + {0x42100000}, {0x42102000}, {0x42104000}, {0x42106000}, + {0x42108000}, {0x4210a000}, {0x4210c000}, {0x4210e000}, + {0x42110000}, {0x42112000}, {0x42114000}, {0x42116000}, + {0x42118000}, {0x4211a000}, {0x4211c000}, {0x4211e000}, + {0x42120000}, {0x42122000}, {0x42124000}, {0x42126000}, + {0x42128000}, {0x4212a000}, {0x4212c000}, {0x4212e000}, + {0x42130000}, {0x42132000}, {0x42134000}, {0x42136000}, + {0x42138000}, {0x4213a000}, {0x4213c000}, {0x4213e000}, + {0x42140000}, {0x42142000}, {0x42144000}, {0x42146000}, + {0x42148000}, {0x4214a000}, {0x4214c000}, {0x4214e000}, + {0x42150000}, {0x42152000}, {0x42154000}, {0x42156000}, + {0x42158000}, {0x4215a000}, {0x4215c000}, {0x4215e000}, + {0x42160000}, {0x42162000}, {0x42164000}, {0x42166000}, + {0x42168000}, {0x4216a000}, {0x4216c000}, {0x4216e000}, + {0x42170000}, {0x42172000}, {0x42174000}, {0x42176000}, + {0x42178000}, {0x4217a000}, {0x4217c000}, {0x4217e000}, + {0x42180000}, {0x42182000}, {0x42184000}, {0x42186000}, + {0x42188000}, {0x4218a000}, {0x4218c000}, {0x4218e000}, + {0x42190000}, {0x42192000}, {0x42194000}, {0x42196000}, + {0x42198000}, {0x4219a000}, {0x4219c000}, {0x4219e000}, + {0x421a0000}, {0x421a2000}, {0x421a4000}, {0x421a6000}, + {0x421a8000}, {0x421aa000}, {0x421ac000}, {0x421ae000}, + {0x421b0000}, {0x421b2000}, {0x421b4000}, {0x421b6000}, + {0x421b8000}, {0x421ba000}, {0x421bc000}, {0x421be000}, + {0x421c0000}, {0x421c2000}, {0x421c4000}, {0x421c6000}, + {0x421c8000}, {0x421ca000}, {0x421cc000}, {0x421ce000}, + {0x421d0000}, {0x421d2000}, {0x421d4000}, {0x421d6000}, + {0x421d8000}, {0x421da000}, {0x421dc000}, {0x421de000}, + {0x421e0000}, {0x421e2000}, {0x421e4000}, {0x421e6000}, + {0x421e8000}, {0x421ea000}, {0x421ec000}, {0x421ee000}, + {0x421f0000}, {0x421f2000}, {0x421f4000}, {0x421f6000}, + {0x421f8000}, {0x421fa000}, {0x421fc000}, {0x421fe000}, + {0x42200000}, {0x42202000}, {0x42204000}, {0x42206000}, + {0x42208000}, {0x4220a000}, {0x4220c000}, {0x4220e000}, + {0x42210000}, {0x42212000}, {0x42214000}, {0x42216000}, + {0x42218000}, {0x4221a000}, {0x4221c000}, {0x4221e000}, + {0x42220000}, {0x42222000}, {0x42224000}, {0x42226000}, + {0x42228000}, {0x4222a000}, {0x4222c000}, {0x4222e000}, + {0x42230000}, {0x42232000}, {0x42234000}, {0x42236000}, + {0x42238000}, {0x4223a000}, {0x4223c000}, {0x4223e000}, + {0x42240000}, {0x42242000}, {0x42244000}, {0x42246000}, + {0x42248000}, {0x4224a000}, {0x4224c000}, {0x4224e000}, + {0x42250000}, {0x42252000}, {0x42254000}, {0x42256000}, + {0x42258000}, {0x4225a000}, {0x4225c000}, {0x4225e000}, + {0x42260000}, {0x42262000}, {0x42264000}, {0x42266000}, + {0x42268000}, {0x4226a000}, {0x4226c000}, {0x4226e000}, + {0x42270000}, {0x42272000}, {0x42274000}, {0x42276000}, + {0x42278000}, {0x4227a000}, {0x4227c000}, {0x4227e000}, + {0x42280000}, {0x42282000}, {0x42284000}, {0x42286000}, + {0x42288000}, {0x4228a000}, {0x4228c000}, {0x4228e000}, + {0x42290000}, {0x42292000}, {0x42294000}, {0x42296000}, + {0x42298000}, {0x4229a000}, {0x4229c000}, {0x4229e000}, + {0x422a0000}, {0x422a2000}, {0x422a4000}, {0x422a6000}, + {0x422a8000}, {0x422aa000}, {0x422ac000}, {0x422ae000}, + {0x422b0000}, {0x422b2000}, {0x422b4000}, {0x422b6000}, + {0x422b8000}, {0x422ba000}, {0x422bc000}, {0x422be000}, + {0x422c0000}, {0x422c2000}, {0x422c4000}, {0x422c6000}, + {0x422c8000}, {0x422ca000}, {0x422cc000}, {0x422ce000}, + {0x422d0000}, {0x422d2000}, {0x422d4000}, {0x422d6000}, + {0x422d8000}, {0x422da000}, {0x422dc000}, {0x422de000}, + {0x422e0000}, {0x422e2000}, {0x422e4000}, {0x422e6000}, + {0x422e8000}, {0x422ea000}, {0x422ec000}, {0x422ee000}, + {0x422f0000}, {0x422f2000}, {0x422f4000}, {0x422f6000}, + {0x422f8000}, {0x422fa000}, {0x422fc000}, {0x422fe000}, + {0x42300000}, {0x42302000}, {0x42304000}, {0x42306000}, + {0x42308000}, {0x4230a000}, {0x4230c000}, {0x4230e000}, + {0x42310000}, {0x42312000}, {0x42314000}, {0x42316000}, + {0x42318000}, {0x4231a000}, {0x4231c000}, {0x4231e000}, + {0x42320000}, {0x42322000}, {0x42324000}, {0x42326000}, + {0x42328000}, {0x4232a000}, {0x4232c000}, {0x4232e000}, + {0x42330000}, {0x42332000}, {0x42334000}, {0x42336000}, + {0x42338000}, {0x4233a000}, {0x4233c000}, {0x4233e000}, + {0x42340000}, {0x42342000}, {0x42344000}, {0x42346000}, + {0x42348000}, {0x4234a000}, {0x4234c000}, {0x4234e000}, + {0x42350000}, {0x42352000}, {0x42354000}, {0x42356000}, + {0x42358000}, {0x4235a000}, {0x4235c000}, {0x4235e000}, + {0x42360000}, {0x42362000}, {0x42364000}, {0x42366000}, + {0x42368000}, {0x4236a000}, {0x4236c000}, {0x4236e000}, + {0x42370000}, {0x42372000}, {0x42374000}, {0x42376000}, + {0x42378000}, {0x4237a000}, {0x4237c000}, {0x4237e000}, + {0x42380000}, {0x42382000}, {0x42384000}, {0x42386000}, + {0x42388000}, {0x4238a000}, {0x4238c000}, {0x4238e000}, + {0x42390000}, {0x42392000}, {0x42394000}, {0x42396000}, + {0x42398000}, {0x4239a000}, {0x4239c000}, {0x4239e000}, + {0x423a0000}, {0x423a2000}, {0x423a4000}, {0x423a6000}, + {0x423a8000}, {0x423aa000}, {0x423ac000}, {0x423ae000}, + {0x423b0000}, {0x423b2000}, {0x423b4000}, {0x423b6000}, + {0x423b8000}, {0x423ba000}, {0x423bc000}, {0x423be000}, + {0x423c0000}, {0x423c2000}, {0x423c4000}, {0x423c6000}, + {0x423c8000}, {0x423ca000}, {0x423cc000}, {0x423ce000}, + {0x423d0000}, {0x423d2000}, {0x423d4000}, {0x423d6000}, + {0x423d8000}, {0x423da000}, {0x423dc000}, {0x423de000}, + {0x423e0000}, {0x423e2000}, {0x423e4000}, {0x423e6000}, + {0x423e8000}, {0x423ea000}, {0x423ec000}, {0x423ee000}, + {0x423f0000}, {0x423f2000}, {0x423f4000}, {0x423f6000}, + {0x423f8000}, {0x423fa000}, {0x423fc000}, {0x423fe000}, + {0x42400000}, {0x42402000}, {0x42404000}, {0x42406000}, + {0x42408000}, {0x4240a000}, {0x4240c000}, {0x4240e000}, + {0x42410000}, {0x42412000}, {0x42414000}, {0x42416000}, + {0x42418000}, {0x4241a000}, {0x4241c000}, {0x4241e000}, + {0x42420000}, {0x42422000}, {0x42424000}, {0x42426000}, + {0x42428000}, {0x4242a000}, {0x4242c000}, {0x4242e000}, + {0x42430000}, {0x42432000}, {0x42434000}, {0x42436000}, + {0x42438000}, {0x4243a000}, {0x4243c000}, {0x4243e000}, + {0x42440000}, {0x42442000}, {0x42444000}, {0x42446000}, + {0x42448000}, {0x4244a000}, {0x4244c000}, {0x4244e000}, + {0x42450000}, {0x42452000}, {0x42454000}, {0x42456000}, + {0x42458000}, {0x4245a000}, {0x4245c000}, {0x4245e000}, + {0x42460000}, {0x42462000}, {0x42464000}, {0x42466000}, + {0x42468000}, {0x4246a000}, {0x4246c000}, {0x4246e000}, + {0x42470000}, {0x42472000}, {0x42474000}, {0x42476000}, + {0x42478000}, {0x4247a000}, {0x4247c000}, {0x4247e000}, + {0x42480000}, {0x42482000}, {0x42484000}, {0x42486000}, + {0x42488000}, {0x4248a000}, {0x4248c000}, {0x4248e000}, + {0x42490000}, {0x42492000}, {0x42494000}, {0x42496000}, + {0x42498000}, {0x4249a000}, {0x4249c000}, {0x4249e000}, + {0x424a0000}, {0x424a2000}, {0x424a4000}, {0x424a6000}, + {0x424a8000}, {0x424aa000}, {0x424ac000}, {0x424ae000}, + {0x424b0000}, {0x424b2000}, {0x424b4000}, {0x424b6000}, + {0x424b8000}, {0x424ba000}, {0x424bc000}, {0x424be000}, + {0x424c0000}, {0x424c2000}, {0x424c4000}, {0x424c6000}, + {0x424c8000}, {0x424ca000}, {0x424cc000}, {0x424ce000}, + {0x424d0000}, {0x424d2000}, {0x424d4000}, {0x424d6000}, + {0x424d8000}, {0x424da000}, {0x424dc000}, {0x424de000}, + {0x424e0000}, {0x424e2000}, {0x424e4000}, {0x424e6000}, + {0x424e8000}, {0x424ea000}, {0x424ec000}, {0x424ee000}, + {0x424f0000}, {0x424f2000}, {0x424f4000}, {0x424f6000}, + {0x424f8000}, {0x424fa000}, {0x424fc000}, {0x424fe000}, + {0x42500000}, {0x42502000}, {0x42504000}, {0x42506000}, + {0x42508000}, {0x4250a000}, {0x4250c000}, {0x4250e000}, + {0x42510000}, {0x42512000}, {0x42514000}, {0x42516000}, + {0x42518000}, {0x4251a000}, {0x4251c000}, {0x4251e000}, + {0x42520000}, {0x42522000}, {0x42524000}, {0x42526000}, + {0x42528000}, {0x4252a000}, {0x4252c000}, {0x4252e000}, + {0x42530000}, {0x42532000}, {0x42534000}, {0x42536000}, + {0x42538000}, {0x4253a000}, {0x4253c000}, {0x4253e000}, + {0x42540000}, {0x42542000}, {0x42544000}, {0x42546000}, + {0x42548000}, {0x4254a000}, {0x4254c000}, {0x4254e000}, + {0x42550000}, {0x42552000}, {0x42554000}, {0x42556000}, + {0x42558000}, {0x4255a000}, {0x4255c000}, {0x4255e000}, + {0x42560000}, {0x42562000}, {0x42564000}, {0x42566000}, + {0x42568000}, {0x4256a000}, {0x4256c000}, {0x4256e000}, + {0x42570000}, {0x42572000}, {0x42574000}, {0x42576000}, + {0x42578000}, {0x4257a000}, {0x4257c000}, {0x4257e000}, + {0x42580000}, {0x42582000}, {0x42584000}, {0x42586000}, + {0x42588000}, {0x4258a000}, {0x4258c000}, {0x4258e000}, + {0x42590000}, {0x42592000}, {0x42594000}, {0x42596000}, + {0x42598000}, {0x4259a000}, {0x4259c000}, {0x4259e000}, + {0x425a0000}, {0x425a2000}, {0x425a4000}, {0x425a6000}, + {0x425a8000}, {0x425aa000}, {0x425ac000}, {0x425ae000}, + {0x425b0000}, {0x425b2000}, {0x425b4000}, {0x425b6000}, + {0x425b8000}, {0x425ba000}, {0x425bc000}, {0x425be000}, + {0x425c0000}, {0x425c2000}, {0x425c4000}, {0x425c6000}, + {0x425c8000}, {0x425ca000}, {0x425cc000}, {0x425ce000}, + {0x425d0000}, {0x425d2000}, {0x425d4000}, {0x425d6000}, + {0x425d8000}, {0x425da000}, {0x425dc000}, {0x425de000}, + {0x425e0000}, {0x425e2000}, {0x425e4000}, {0x425e6000}, + {0x425e8000}, {0x425ea000}, {0x425ec000}, {0x425ee000}, + {0x425f0000}, {0x425f2000}, {0x425f4000}, {0x425f6000}, + {0x425f8000}, {0x425fa000}, {0x425fc000}, {0x425fe000}, + {0x42600000}, {0x42602000}, {0x42604000}, {0x42606000}, + {0x42608000}, {0x4260a000}, {0x4260c000}, {0x4260e000}, + {0x42610000}, {0x42612000}, {0x42614000}, {0x42616000}, + {0x42618000}, {0x4261a000}, {0x4261c000}, {0x4261e000}, + {0x42620000}, {0x42622000}, {0x42624000}, {0x42626000}, + {0x42628000}, {0x4262a000}, {0x4262c000}, {0x4262e000}, + {0x42630000}, {0x42632000}, {0x42634000}, {0x42636000}, + {0x42638000}, {0x4263a000}, {0x4263c000}, {0x4263e000}, + {0x42640000}, {0x42642000}, {0x42644000}, {0x42646000}, + {0x42648000}, {0x4264a000}, {0x4264c000}, {0x4264e000}, + {0x42650000}, {0x42652000}, {0x42654000}, {0x42656000}, + {0x42658000}, {0x4265a000}, {0x4265c000}, {0x4265e000}, + {0x42660000}, {0x42662000}, {0x42664000}, {0x42666000}, + {0x42668000}, {0x4266a000}, {0x4266c000}, {0x4266e000}, + {0x42670000}, {0x42672000}, {0x42674000}, {0x42676000}, + {0x42678000}, {0x4267a000}, {0x4267c000}, {0x4267e000}, + {0x42680000}, {0x42682000}, {0x42684000}, {0x42686000}, + {0x42688000}, {0x4268a000}, {0x4268c000}, {0x4268e000}, + {0x42690000}, {0x42692000}, {0x42694000}, {0x42696000}, + {0x42698000}, {0x4269a000}, {0x4269c000}, {0x4269e000}, + {0x426a0000}, {0x426a2000}, {0x426a4000}, {0x426a6000}, + {0x426a8000}, {0x426aa000}, {0x426ac000}, {0x426ae000}, + {0x426b0000}, {0x426b2000}, {0x426b4000}, {0x426b6000}, + {0x426b8000}, {0x426ba000}, {0x426bc000}, {0x426be000}, + {0x426c0000}, {0x426c2000}, {0x426c4000}, {0x426c6000}, + {0x426c8000}, {0x426ca000}, {0x426cc000}, {0x426ce000}, + {0x426d0000}, {0x426d2000}, {0x426d4000}, {0x426d6000}, + {0x426d8000}, {0x426da000}, {0x426dc000}, {0x426de000}, + {0x426e0000}, {0x426e2000}, {0x426e4000}, {0x426e6000}, + {0x426e8000}, {0x426ea000}, {0x426ec000}, {0x426ee000}, + {0x426f0000}, {0x426f2000}, {0x426f4000}, {0x426f6000}, + {0x426f8000}, {0x426fa000}, {0x426fc000}, {0x426fe000}, + {0x42700000}, {0x42702000}, {0x42704000}, {0x42706000}, + {0x42708000}, {0x4270a000}, {0x4270c000}, {0x4270e000}, + {0x42710000}, {0x42712000}, {0x42714000}, {0x42716000}, + {0x42718000}, {0x4271a000}, {0x4271c000}, {0x4271e000}, + {0x42720000}, {0x42722000}, {0x42724000}, {0x42726000}, + {0x42728000}, {0x4272a000}, {0x4272c000}, {0x4272e000}, + {0x42730000}, {0x42732000}, {0x42734000}, {0x42736000}, + {0x42738000}, {0x4273a000}, {0x4273c000}, {0x4273e000}, + {0x42740000}, {0x42742000}, {0x42744000}, {0x42746000}, + {0x42748000}, {0x4274a000}, {0x4274c000}, {0x4274e000}, + {0x42750000}, {0x42752000}, {0x42754000}, {0x42756000}, + {0x42758000}, {0x4275a000}, {0x4275c000}, {0x4275e000}, + {0x42760000}, {0x42762000}, {0x42764000}, {0x42766000}, + {0x42768000}, {0x4276a000}, {0x4276c000}, {0x4276e000}, + {0x42770000}, {0x42772000}, {0x42774000}, {0x42776000}, + {0x42778000}, {0x4277a000}, {0x4277c000}, {0x4277e000}, + {0x42780000}, {0x42782000}, {0x42784000}, {0x42786000}, + {0x42788000}, {0x4278a000}, {0x4278c000}, {0x4278e000}, + {0x42790000}, {0x42792000}, {0x42794000}, {0x42796000}, + {0x42798000}, {0x4279a000}, {0x4279c000}, {0x4279e000}, + {0x427a0000}, {0x427a2000}, {0x427a4000}, {0x427a6000}, + {0x427a8000}, {0x427aa000}, {0x427ac000}, {0x427ae000}, + {0x427b0000}, {0x427b2000}, {0x427b4000}, {0x427b6000}, + {0x427b8000}, {0x427ba000}, {0x427bc000}, {0x427be000}, + {0x427c0000}, {0x427c2000}, {0x427c4000}, {0x427c6000}, + {0x427c8000}, {0x427ca000}, {0x427cc000}, {0x427ce000}, + {0x427d0000}, {0x427d2000}, {0x427d4000}, {0x427d6000}, + {0x427d8000}, {0x427da000}, {0x427dc000}, {0x427de000}, + {0x427e0000}, {0x427e2000}, {0x427e4000}, {0x427e6000}, + {0x427e8000}, {0x427ea000}, {0x427ec000}, {0x427ee000}, + {0x427f0000}, {0x427f2000}, {0x427f4000}, {0x427f6000}, + {0x427f8000}, {0x427fa000}, {0x427fc000}, {0x427fe000}, + {0x42800000}, {0x42802000}, {0x42804000}, {0x42806000}, + {0x42808000}, {0x4280a000}, {0x4280c000}, {0x4280e000}, + {0x42810000}, {0x42812000}, {0x42814000}, {0x42816000}, + {0x42818000}, {0x4281a000}, {0x4281c000}, {0x4281e000}, + {0x42820000}, {0x42822000}, {0x42824000}, {0x42826000}, + {0x42828000}, {0x4282a000}, {0x4282c000}, {0x4282e000}, + {0x42830000}, {0x42832000}, {0x42834000}, {0x42836000}, + {0x42838000}, {0x4283a000}, {0x4283c000}, {0x4283e000}, + {0x42840000}, {0x42842000}, {0x42844000}, {0x42846000}, + {0x42848000}, {0x4284a000}, {0x4284c000}, {0x4284e000}, + {0x42850000}, {0x42852000}, {0x42854000}, {0x42856000}, + {0x42858000}, {0x4285a000}, {0x4285c000}, {0x4285e000}, + {0x42860000}, {0x42862000}, {0x42864000}, {0x42866000}, + {0x42868000}, {0x4286a000}, {0x4286c000}, {0x4286e000}, + {0x42870000}, {0x42872000}, {0x42874000}, {0x42876000}, + {0x42878000}, {0x4287a000}, {0x4287c000}, {0x4287e000}, + {0x42880000}, {0x42882000}, {0x42884000}, {0x42886000}, + {0x42888000}, {0x4288a000}, {0x4288c000}, {0x4288e000}, + {0x42890000}, {0x42892000}, {0x42894000}, {0x42896000}, + {0x42898000}, {0x4289a000}, {0x4289c000}, {0x4289e000}, + {0x428a0000}, {0x428a2000}, {0x428a4000}, {0x428a6000}, + {0x428a8000}, {0x428aa000}, {0x428ac000}, {0x428ae000}, + {0x428b0000}, {0x428b2000}, {0x428b4000}, {0x428b6000}, + {0x428b8000}, {0x428ba000}, {0x428bc000}, {0x428be000}, + {0x428c0000}, {0x428c2000}, {0x428c4000}, {0x428c6000}, + {0x428c8000}, {0x428ca000}, {0x428cc000}, {0x428ce000}, + {0x428d0000}, {0x428d2000}, {0x428d4000}, {0x428d6000}, + {0x428d8000}, {0x428da000}, {0x428dc000}, {0x428de000}, + {0x428e0000}, {0x428e2000}, {0x428e4000}, {0x428e6000}, + {0x428e8000}, {0x428ea000}, {0x428ec000}, {0x428ee000}, + {0x428f0000}, {0x428f2000}, {0x428f4000}, {0x428f6000}, + {0x428f8000}, {0x428fa000}, {0x428fc000}, {0x428fe000}, + {0x42900000}, {0x42902000}, {0x42904000}, {0x42906000}, + {0x42908000}, {0x4290a000}, {0x4290c000}, {0x4290e000}, + {0x42910000}, {0x42912000}, {0x42914000}, {0x42916000}, + {0x42918000}, {0x4291a000}, {0x4291c000}, {0x4291e000}, + {0x42920000}, {0x42922000}, {0x42924000}, {0x42926000}, + {0x42928000}, {0x4292a000}, {0x4292c000}, {0x4292e000}, + {0x42930000}, {0x42932000}, {0x42934000}, {0x42936000}, + {0x42938000}, {0x4293a000}, {0x4293c000}, {0x4293e000}, + {0x42940000}, {0x42942000}, {0x42944000}, {0x42946000}, + {0x42948000}, {0x4294a000}, {0x4294c000}, {0x4294e000}, + {0x42950000}, {0x42952000}, {0x42954000}, {0x42956000}, + {0x42958000}, {0x4295a000}, {0x4295c000}, {0x4295e000}, + {0x42960000}, {0x42962000}, {0x42964000}, {0x42966000}, + {0x42968000}, {0x4296a000}, {0x4296c000}, {0x4296e000}, + {0x42970000}, {0x42972000}, {0x42974000}, {0x42976000}, + {0x42978000}, {0x4297a000}, {0x4297c000}, {0x4297e000}, + {0x42980000}, {0x42982000}, {0x42984000}, {0x42986000}, + {0x42988000}, {0x4298a000}, {0x4298c000}, {0x4298e000}, + {0x42990000}, {0x42992000}, {0x42994000}, {0x42996000}, + {0x42998000}, {0x4299a000}, {0x4299c000}, {0x4299e000}, + {0x429a0000}, {0x429a2000}, {0x429a4000}, {0x429a6000}, + {0x429a8000}, {0x429aa000}, {0x429ac000}, {0x429ae000}, + {0x429b0000}, {0x429b2000}, {0x429b4000}, {0x429b6000}, + {0x429b8000}, {0x429ba000}, {0x429bc000}, {0x429be000}, + {0x429c0000}, {0x429c2000}, {0x429c4000}, {0x429c6000}, + {0x429c8000}, {0x429ca000}, {0x429cc000}, {0x429ce000}, + {0x429d0000}, {0x429d2000}, {0x429d4000}, {0x429d6000}, + {0x429d8000}, {0x429da000}, {0x429dc000}, {0x429de000}, + {0x429e0000}, {0x429e2000}, {0x429e4000}, {0x429e6000}, + {0x429e8000}, {0x429ea000}, {0x429ec000}, {0x429ee000}, + {0x429f0000}, {0x429f2000}, {0x429f4000}, {0x429f6000}, + {0x429f8000}, {0x429fa000}, {0x429fc000}, {0x429fe000}, + {0x42a00000}, {0x42a02000}, {0x42a04000}, {0x42a06000}, + {0x42a08000}, {0x42a0a000}, {0x42a0c000}, {0x42a0e000}, + {0x42a10000}, {0x42a12000}, {0x42a14000}, {0x42a16000}, + {0x42a18000}, {0x42a1a000}, {0x42a1c000}, {0x42a1e000}, + {0x42a20000}, {0x42a22000}, {0x42a24000}, {0x42a26000}, + {0x42a28000}, {0x42a2a000}, {0x42a2c000}, {0x42a2e000}, + {0x42a30000}, {0x42a32000}, {0x42a34000}, {0x42a36000}, + {0x42a38000}, {0x42a3a000}, {0x42a3c000}, {0x42a3e000}, + {0x42a40000}, {0x42a42000}, {0x42a44000}, {0x42a46000}, + {0x42a48000}, {0x42a4a000}, {0x42a4c000}, {0x42a4e000}, + {0x42a50000}, {0x42a52000}, {0x42a54000}, {0x42a56000}, + {0x42a58000}, {0x42a5a000}, {0x42a5c000}, {0x42a5e000}, + {0x42a60000}, {0x42a62000}, {0x42a64000}, {0x42a66000}, + {0x42a68000}, {0x42a6a000}, {0x42a6c000}, {0x42a6e000}, + {0x42a70000}, {0x42a72000}, {0x42a74000}, {0x42a76000}, + {0x42a78000}, {0x42a7a000}, {0x42a7c000}, {0x42a7e000}, + {0x42a80000}, {0x42a82000}, {0x42a84000}, {0x42a86000}, + {0x42a88000}, {0x42a8a000}, {0x42a8c000}, {0x42a8e000}, + {0x42a90000}, {0x42a92000}, {0x42a94000}, {0x42a96000}, + {0x42a98000}, {0x42a9a000}, {0x42a9c000}, {0x42a9e000}, + {0x42aa0000}, {0x42aa2000}, {0x42aa4000}, {0x42aa6000}, + {0x42aa8000}, {0x42aaa000}, {0x42aac000}, {0x42aae000}, + {0x42ab0000}, {0x42ab2000}, {0x42ab4000}, {0x42ab6000}, + {0x42ab8000}, {0x42aba000}, {0x42abc000}, {0x42abe000}, + {0x42ac0000}, {0x42ac2000}, {0x42ac4000}, {0x42ac6000}, + {0x42ac8000}, {0x42aca000}, {0x42acc000}, {0x42ace000}, + {0x42ad0000}, {0x42ad2000}, {0x42ad4000}, {0x42ad6000}, + {0x42ad8000}, {0x42ada000}, {0x42adc000}, {0x42ade000}, + {0x42ae0000}, {0x42ae2000}, {0x42ae4000}, {0x42ae6000}, + {0x42ae8000}, {0x42aea000}, {0x42aec000}, {0x42aee000}, + {0x42af0000}, {0x42af2000}, {0x42af4000}, {0x42af6000}, + {0x42af8000}, {0x42afa000}, {0x42afc000}, {0x42afe000}, + {0x42b00000}, {0x42b02000}, {0x42b04000}, {0x42b06000}, + {0x42b08000}, {0x42b0a000}, {0x42b0c000}, {0x42b0e000}, + {0x42b10000}, {0x42b12000}, {0x42b14000}, {0x42b16000}, + {0x42b18000}, {0x42b1a000}, {0x42b1c000}, {0x42b1e000}, + {0x42b20000}, {0x42b22000}, {0x42b24000}, {0x42b26000}, + {0x42b28000}, {0x42b2a000}, {0x42b2c000}, {0x42b2e000}, + {0x42b30000}, {0x42b32000}, {0x42b34000}, {0x42b36000}, + {0x42b38000}, {0x42b3a000}, {0x42b3c000}, {0x42b3e000}, + {0x42b40000}, {0x42b42000}, {0x42b44000}, {0x42b46000}, + {0x42b48000}, {0x42b4a000}, {0x42b4c000}, {0x42b4e000}, + {0x42b50000}, {0x42b52000}, {0x42b54000}, {0x42b56000}, + {0x42b58000}, {0x42b5a000}, {0x42b5c000}, {0x42b5e000}, + {0x42b60000}, {0x42b62000}, {0x42b64000}, {0x42b66000}, + {0x42b68000}, {0x42b6a000}, {0x42b6c000}, {0x42b6e000}, + {0x42b70000}, {0x42b72000}, {0x42b74000}, {0x42b76000}, + {0x42b78000}, {0x42b7a000}, {0x42b7c000}, {0x42b7e000}, + {0x42b80000}, {0x42b82000}, {0x42b84000}, {0x42b86000}, + {0x42b88000}, {0x42b8a000}, {0x42b8c000}, {0x42b8e000}, + {0x42b90000}, {0x42b92000}, {0x42b94000}, {0x42b96000}, + {0x42b98000}, {0x42b9a000}, {0x42b9c000}, {0x42b9e000}, + {0x42ba0000}, {0x42ba2000}, {0x42ba4000}, {0x42ba6000}, + {0x42ba8000}, {0x42baa000}, {0x42bac000}, {0x42bae000}, + {0x42bb0000}, {0x42bb2000}, {0x42bb4000}, {0x42bb6000}, + {0x42bb8000}, {0x42bba000}, {0x42bbc000}, {0x42bbe000}, + {0x42bc0000}, {0x42bc2000}, {0x42bc4000}, {0x42bc6000}, + {0x42bc8000}, {0x42bca000}, {0x42bcc000}, {0x42bce000}, + {0x42bd0000}, {0x42bd2000}, {0x42bd4000}, {0x42bd6000}, + {0x42bd8000}, {0x42bda000}, {0x42bdc000}, {0x42bde000}, + {0x42be0000}, {0x42be2000}, {0x42be4000}, {0x42be6000}, + {0x42be8000}, {0x42bea000}, {0x42bec000}, {0x42bee000}, + {0x42bf0000}, {0x42bf2000}, {0x42bf4000}, {0x42bf6000}, + {0x42bf8000}, {0x42bfa000}, {0x42bfc000}, {0x42bfe000}, + {0x42c00000}, {0x42c02000}, {0x42c04000}, {0x42c06000}, + {0x42c08000}, {0x42c0a000}, {0x42c0c000}, {0x42c0e000}, + {0x42c10000}, {0x42c12000}, {0x42c14000}, {0x42c16000}, + {0x42c18000}, {0x42c1a000}, {0x42c1c000}, {0x42c1e000}, + {0x42c20000}, {0x42c22000}, {0x42c24000}, {0x42c26000}, + {0x42c28000}, {0x42c2a000}, {0x42c2c000}, {0x42c2e000}, + {0x42c30000}, {0x42c32000}, {0x42c34000}, {0x42c36000}, + {0x42c38000}, {0x42c3a000}, {0x42c3c000}, {0x42c3e000}, + {0x42c40000}, {0x42c42000}, {0x42c44000}, {0x42c46000}, + {0x42c48000}, {0x42c4a000}, {0x42c4c000}, {0x42c4e000}, + {0x42c50000}, {0x42c52000}, {0x42c54000}, {0x42c56000}, + {0x42c58000}, {0x42c5a000}, {0x42c5c000}, {0x42c5e000}, + {0x42c60000}, {0x42c62000}, {0x42c64000}, {0x42c66000}, + {0x42c68000}, {0x42c6a000}, {0x42c6c000}, {0x42c6e000}, + {0x42c70000}, {0x42c72000}, {0x42c74000}, {0x42c76000}, + {0x42c78000}, {0x42c7a000}, {0x42c7c000}, {0x42c7e000}, + {0x42c80000}, {0x42c82000}, {0x42c84000}, {0x42c86000}, + {0x42c88000}, {0x42c8a000}, {0x42c8c000}, {0x42c8e000}, + {0x42c90000}, {0x42c92000}, {0x42c94000}, {0x42c96000}, + {0x42c98000}, {0x42c9a000}, {0x42c9c000}, {0x42c9e000}, + {0x42ca0000}, {0x42ca2000}, {0x42ca4000}, {0x42ca6000}, + {0x42ca8000}, {0x42caa000}, {0x42cac000}, {0x42cae000}, + {0x42cb0000}, {0x42cb2000}, {0x42cb4000}, {0x42cb6000}, + {0x42cb8000}, {0x42cba000}, {0x42cbc000}, {0x42cbe000}, + {0x42cc0000}, {0x42cc2000}, {0x42cc4000}, {0x42cc6000}, + {0x42cc8000}, {0x42cca000}, {0x42ccc000}, {0x42cce000}, + {0x42cd0000}, {0x42cd2000}, {0x42cd4000}, {0x42cd6000}, + {0x42cd8000}, {0x42cda000}, {0x42cdc000}, {0x42cde000}, + {0x42ce0000}, {0x42ce2000}, {0x42ce4000}, {0x42ce6000}, + {0x42ce8000}, {0x42cea000}, {0x42cec000}, {0x42cee000}, + {0x42cf0000}, {0x42cf2000}, {0x42cf4000}, {0x42cf6000}, + {0x42cf8000}, {0x42cfa000}, {0x42cfc000}, {0x42cfe000}, + {0x42d00000}, {0x42d02000}, {0x42d04000}, {0x42d06000}, + {0x42d08000}, {0x42d0a000}, {0x42d0c000}, {0x42d0e000}, + {0x42d10000}, {0x42d12000}, {0x42d14000}, {0x42d16000}, + {0x42d18000}, {0x42d1a000}, {0x42d1c000}, {0x42d1e000}, + {0x42d20000}, {0x42d22000}, {0x42d24000}, {0x42d26000}, + {0x42d28000}, {0x42d2a000}, {0x42d2c000}, {0x42d2e000}, + {0x42d30000}, {0x42d32000}, {0x42d34000}, {0x42d36000}, + {0x42d38000}, {0x42d3a000}, {0x42d3c000}, {0x42d3e000}, + {0x42d40000}, {0x42d42000}, {0x42d44000}, {0x42d46000}, + {0x42d48000}, {0x42d4a000}, {0x42d4c000}, {0x42d4e000}, + {0x42d50000}, {0x42d52000}, {0x42d54000}, {0x42d56000}, + {0x42d58000}, {0x42d5a000}, {0x42d5c000}, {0x42d5e000}, + {0x42d60000}, {0x42d62000}, {0x42d64000}, {0x42d66000}, + {0x42d68000}, {0x42d6a000}, {0x42d6c000}, {0x42d6e000}, + {0x42d70000}, {0x42d72000}, {0x42d74000}, {0x42d76000}, + {0x42d78000}, {0x42d7a000}, {0x42d7c000}, {0x42d7e000}, + {0x42d80000}, {0x42d82000}, {0x42d84000}, {0x42d86000}, + {0x42d88000}, {0x42d8a000}, {0x42d8c000}, {0x42d8e000}, + {0x42d90000}, {0x42d92000}, {0x42d94000}, {0x42d96000}, + {0x42d98000}, {0x42d9a000}, {0x42d9c000}, {0x42d9e000}, + {0x42da0000}, {0x42da2000}, {0x42da4000}, {0x42da6000}, + {0x42da8000}, {0x42daa000}, {0x42dac000}, {0x42dae000}, + {0x42db0000}, {0x42db2000}, {0x42db4000}, {0x42db6000}, + {0x42db8000}, {0x42dba000}, {0x42dbc000}, {0x42dbe000}, + {0x42dc0000}, {0x42dc2000}, {0x42dc4000}, {0x42dc6000}, + {0x42dc8000}, {0x42dca000}, {0x42dcc000}, {0x42dce000}, + {0x42dd0000}, {0x42dd2000}, {0x42dd4000}, {0x42dd6000}, + {0x42dd8000}, {0x42dda000}, {0x42ddc000}, {0x42dde000}, + {0x42de0000}, {0x42de2000}, {0x42de4000}, {0x42de6000}, + {0x42de8000}, {0x42dea000}, {0x42dec000}, {0x42dee000}, + {0x42df0000}, {0x42df2000}, {0x42df4000}, {0x42df6000}, + {0x42df8000}, {0x42dfa000}, {0x42dfc000}, {0x42dfe000}, + {0x42e00000}, {0x42e02000}, {0x42e04000}, {0x42e06000}, + {0x42e08000}, {0x42e0a000}, {0x42e0c000}, {0x42e0e000}, + {0x42e10000}, {0x42e12000}, {0x42e14000}, {0x42e16000}, + {0x42e18000}, {0x42e1a000}, {0x42e1c000}, {0x42e1e000}, + {0x42e20000}, {0x42e22000}, {0x42e24000}, {0x42e26000}, + {0x42e28000}, {0x42e2a000}, {0x42e2c000}, {0x42e2e000}, + {0x42e30000}, {0x42e32000}, {0x42e34000}, {0x42e36000}, + {0x42e38000}, {0x42e3a000}, {0x42e3c000}, {0x42e3e000}, + {0x42e40000}, {0x42e42000}, {0x42e44000}, {0x42e46000}, + {0x42e48000}, {0x42e4a000}, {0x42e4c000}, {0x42e4e000}, + {0x42e50000}, {0x42e52000}, {0x42e54000}, {0x42e56000}, + {0x42e58000}, {0x42e5a000}, {0x42e5c000}, {0x42e5e000}, + {0x42e60000}, {0x42e62000}, {0x42e64000}, {0x42e66000}, + {0x42e68000}, {0x42e6a000}, {0x42e6c000}, {0x42e6e000}, + {0x42e70000}, {0x42e72000}, {0x42e74000}, {0x42e76000}, + {0x42e78000}, {0x42e7a000}, {0x42e7c000}, {0x42e7e000}, + {0x42e80000}, {0x42e82000}, {0x42e84000}, {0x42e86000}, + {0x42e88000}, {0x42e8a000}, {0x42e8c000}, {0x42e8e000}, + {0x42e90000}, {0x42e92000}, {0x42e94000}, {0x42e96000}, + {0x42e98000}, {0x42e9a000}, {0x42e9c000}, {0x42e9e000}, + {0x42ea0000}, {0x42ea2000}, {0x42ea4000}, {0x42ea6000}, + {0x42ea8000}, {0x42eaa000}, {0x42eac000}, {0x42eae000}, + {0x42eb0000}, {0x42eb2000}, {0x42eb4000}, {0x42eb6000}, + {0x42eb8000}, {0x42eba000}, {0x42ebc000}, {0x42ebe000}, + {0x42ec0000}, {0x42ec2000}, {0x42ec4000}, {0x42ec6000}, + {0x42ec8000}, {0x42eca000}, {0x42ecc000}, {0x42ece000}, + {0x42ed0000}, {0x42ed2000}, {0x42ed4000}, {0x42ed6000}, + {0x42ed8000}, {0x42eda000}, {0x42edc000}, {0x42ede000}, + {0x42ee0000}, {0x42ee2000}, {0x42ee4000}, {0x42ee6000}, + {0x42ee8000}, {0x42eea000}, {0x42eec000}, {0x42eee000}, + {0x42ef0000}, {0x42ef2000}, {0x42ef4000}, {0x42ef6000}, + {0x42ef8000}, {0x42efa000}, {0x42efc000}, {0x42efe000}, + {0x42f00000}, {0x42f02000}, {0x42f04000}, {0x42f06000}, + {0x42f08000}, {0x42f0a000}, {0x42f0c000}, {0x42f0e000}, + {0x42f10000}, {0x42f12000}, {0x42f14000}, {0x42f16000}, + {0x42f18000}, {0x42f1a000}, {0x42f1c000}, {0x42f1e000}, + {0x42f20000}, {0x42f22000}, {0x42f24000}, {0x42f26000}, + {0x42f28000}, {0x42f2a000}, {0x42f2c000}, {0x42f2e000}, + {0x42f30000}, {0x42f32000}, {0x42f34000}, {0x42f36000}, + {0x42f38000}, {0x42f3a000}, {0x42f3c000}, {0x42f3e000}, + {0x42f40000}, {0x42f42000}, {0x42f44000}, {0x42f46000}, + {0x42f48000}, {0x42f4a000}, {0x42f4c000}, {0x42f4e000}, + {0x42f50000}, {0x42f52000}, {0x42f54000}, {0x42f56000}, + {0x42f58000}, {0x42f5a000}, {0x42f5c000}, {0x42f5e000}, + {0x42f60000}, {0x42f62000}, {0x42f64000}, {0x42f66000}, + {0x42f68000}, {0x42f6a000}, {0x42f6c000}, {0x42f6e000}, + {0x42f70000}, {0x42f72000}, {0x42f74000}, {0x42f76000}, + {0x42f78000}, {0x42f7a000}, {0x42f7c000}, {0x42f7e000}, + {0x42f80000}, {0x42f82000}, {0x42f84000}, {0x42f86000}, + {0x42f88000}, {0x42f8a000}, {0x42f8c000}, {0x42f8e000}, + {0x42f90000}, {0x42f92000}, {0x42f94000}, {0x42f96000}, + {0x42f98000}, {0x42f9a000}, {0x42f9c000}, {0x42f9e000}, + {0x42fa0000}, {0x42fa2000}, {0x42fa4000}, {0x42fa6000}, + {0x42fa8000}, {0x42faa000}, {0x42fac000}, {0x42fae000}, + {0x42fb0000}, {0x42fb2000}, {0x42fb4000}, {0x42fb6000}, + {0x42fb8000}, {0x42fba000}, {0x42fbc000}, {0x42fbe000}, + {0x42fc0000}, {0x42fc2000}, {0x42fc4000}, {0x42fc6000}, + {0x42fc8000}, {0x42fca000}, {0x42fcc000}, {0x42fce000}, + {0x42fd0000}, {0x42fd2000}, {0x42fd4000}, {0x42fd6000}, + {0x42fd8000}, {0x42fda000}, {0x42fdc000}, {0x42fde000}, + {0x42fe0000}, {0x42fe2000}, {0x42fe4000}, {0x42fe6000}, + {0x42fe8000}, {0x42fea000}, {0x42fec000}, {0x42fee000}, + {0x42ff0000}, {0x42ff2000}, {0x42ff4000}, {0x42ff6000}, + {0x42ff8000}, {0x42ffa000}, {0x42ffc000}, {0x42ffe000}, + {0x43000000}, {0x43002000}, {0x43004000}, {0x43006000}, + {0x43008000}, {0x4300a000}, {0x4300c000}, {0x4300e000}, + {0x43010000}, {0x43012000}, {0x43014000}, {0x43016000}, + {0x43018000}, {0x4301a000}, {0x4301c000}, {0x4301e000}, + {0x43020000}, {0x43022000}, {0x43024000}, {0x43026000}, + {0x43028000}, {0x4302a000}, {0x4302c000}, {0x4302e000}, + {0x43030000}, {0x43032000}, {0x43034000}, {0x43036000}, + {0x43038000}, {0x4303a000}, {0x4303c000}, {0x4303e000}, + {0x43040000}, {0x43042000}, {0x43044000}, {0x43046000}, + {0x43048000}, {0x4304a000}, {0x4304c000}, {0x4304e000}, + {0x43050000}, {0x43052000}, {0x43054000}, {0x43056000}, + {0x43058000}, {0x4305a000}, {0x4305c000}, {0x4305e000}, + {0x43060000}, {0x43062000}, {0x43064000}, {0x43066000}, + {0x43068000}, {0x4306a000}, {0x4306c000}, {0x4306e000}, + {0x43070000}, {0x43072000}, {0x43074000}, {0x43076000}, + {0x43078000}, {0x4307a000}, {0x4307c000}, {0x4307e000}, + {0x43080000}, {0x43082000}, {0x43084000}, {0x43086000}, + {0x43088000}, {0x4308a000}, {0x4308c000}, {0x4308e000}, + {0x43090000}, {0x43092000}, {0x43094000}, {0x43096000}, + {0x43098000}, {0x4309a000}, {0x4309c000}, {0x4309e000}, + {0x430a0000}, {0x430a2000}, {0x430a4000}, {0x430a6000}, + {0x430a8000}, {0x430aa000}, {0x430ac000}, {0x430ae000}, + {0x430b0000}, {0x430b2000}, {0x430b4000}, {0x430b6000}, + {0x430b8000}, {0x430ba000}, {0x430bc000}, {0x430be000}, + {0x430c0000}, {0x430c2000}, {0x430c4000}, {0x430c6000}, + {0x430c8000}, {0x430ca000}, {0x430cc000}, {0x430ce000}, + {0x430d0000}, {0x430d2000}, {0x430d4000}, {0x430d6000}, + {0x430d8000}, {0x430da000}, {0x430dc000}, {0x430de000}, + {0x430e0000}, {0x430e2000}, {0x430e4000}, {0x430e6000}, + {0x430e8000}, {0x430ea000}, {0x430ec000}, {0x430ee000}, + {0x430f0000}, {0x430f2000}, {0x430f4000}, {0x430f6000}, + {0x430f8000}, {0x430fa000}, {0x430fc000}, {0x430fe000}, + {0x43100000}, {0x43102000}, {0x43104000}, {0x43106000}, + {0x43108000}, {0x4310a000}, {0x4310c000}, {0x4310e000}, + {0x43110000}, {0x43112000}, {0x43114000}, {0x43116000}, + {0x43118000}, {0x4311a000}, {0x4311c000}, {0x4311e000}, + {0x43120000}, {0x43122000}, {0x43124000}, {0x43126000}, + {0x43128000}, {0x4312a000}, {0x4312c000}, {0x4312e000}, + {0x43130000}, {0x43132000}, {0x43134000}, {0x43136000}, + {0x43138000}, {0x4313a000}, {0x4313c000}, {0x4313e000}, + {0x43140000}, {0x43142000}, {0x43144000}, {0x43146000}, + {0x43148000}, {0x4314a000}, {0x4314c000}, {0x4314e000}, + {0x43150000}, {0x43152000}, {0x43154000}, {0x43156000}, + {0x43158000}, {0x4315a000}, {0x4315c000}, {0x4315e000}, + {0x43160000}, {0x43162000}, {0x43164000}, {0x43166000}, + {0x43168000}, {0x4316a000}, {0x4316c000}, {0x4316e000}, + {0x43170000}, {0x43172000}, {0x43174000}, {0x43176000}, + {0x43178000}, {0x4317a000}, {0x4317c000}, {0x4317e000}, + {0x43180000}, {0x43182000}, {0x43184000}, {0x43186000}, + {0x43188000}, {0x4318a000}, {0x4318c000}, {0x4318e000}, + {0x43190000}, {0x43192000}, {0x43194000}, {0x43196000}, + {0x43198000}, {0x4319a000}, {0x4319c000}, {0x4319e000}, + {0x431a0000}, {0x431a2000}, {0x431a4000}, {0x431a6000}, + {0x431a8000}, {0x431aa000}, {0x431ac000}, {0x431ae000}, + {0x431b0000}, {0x431b2000}, {0x431b4000}, {0x431b6000}, + {0x431b8000}, {0x431ba000}, {0x431bc000}, {0x431be000}, + {0x431c0000}, {0x431c2000}, {0x431c4000}, {0x431c6000}, + {0x431c8000}, {0x431ca000}, {0x431cc000}, {0x431ce000}, + {0x431d0000}, {0x431d2000}, {0x431d4000}, {0x431d6000}, + {0x431d8000}, {0x431da000}, {0x431dc000}, {0x431de000}, + {0x431e0000}, {0x431e2000}, {0x431e4000}, {0x431e6000}, + {0x431e8000}, {0x431ea000}, {0x431ec000}, {0x431ee000}, + {0x431f0000}, {0x431f2000}, {0x431f4000}, {0x431f6000}, + {0x431f8000}, {0x431fa000}, {0x431fc000}, {0x431fe000}, + {0x43200000}, {0x43202000}, {0x43204000}, {0x43206000}, + {0x43208000}, {0x4320a000}, {0x4320c000}, {0x4320e000}, + {0x43210000}, {0x43212000}, {0x43214000}, {0x43216000}, + {0x43218000}, {0x4321a000}, {0x4321c000}, {0x4321e000}, + {0x43220000}, {0x43222000}, {0x43224000}, {0x43226000}, + {0x43228000}, {0x4322a000}, {0x4322c000}, {0x4322e000}, + {0x43230000}, {0x43232000}, {0x43234000}, {0x43236000}, + {0x43238000}, {0x4323a000}, {0x4323c000}, {0x4323e000}, + {0x43240000}, {0x43242000}, {0x43244000}, {0x43246000}, + {0x43248000}, {0x4324a000}, {0x4324c000}, {0x4324e000}, + {0x43250000}, {0x43252000}, {0x43254000}, {0x43256000}, + {0x43258000}, {0x4325a000}, {0x4325c000}, {0x4325e000}, + {0x43260000}, {0x43262000}, {0x43264000}, {0x43266000}, + {0x43268000}, {0x4326a000}, {0x4326c000}, {0x4326e000}, + {0x43270000}, {0x43272000}, {0x43274000}, {0x43276000}, + {0x43278000}, {0x4327a000}, {0x4327c000}, {0x4327e000}, + {0x43280000}, {0x43282000}, {0x43284000}, {0x43286000}, + {0x43288000}, {0x4328a000}, {0x4328c000}, {0x4328e000}, + {0x43290000}, {0x43292000}, {0x43294000}, {0x43296000}, + {0x43298000}, {0x4329a000}, {0x4329c000}, {0x4329e000}, + {0x432a0000}, {0x432a2000}, {0x432a4000}, {0x432a6000}, + {0x432a8000}, {0x432aa000}, {0x432ac000}, {0x432ae000}, + {0x432b0000}, {0x432b2000}, {0x432b4000}, {0x432b6000}, + {0x432b8000}, {0x432ba000}, {0x432bc000}, {0x432be000}, + {0x432c0000}, {0x432c2000}, {0x432c4000}, {0x432c6000}, + {0x432c8000}, {0x432ca000}, {0x432cc000}, {0x432ce000}, + {0x432d0000}, {0x432d2000}, {0x432d4000}, {0x432d6000}, + {0x432d8000}, {0x432da000}, {0x432dc000}, {0x432de000}, + {0x432e0000}, {0x432e2000}, {0x432e4000}, {0x432e6000}, + {0x432e8000}, {0x432ea000}, {0x432ec000}, {0x432ee000}, + {0x432f0000}, {0x432f2000}, {0x432f4000}, {0x432f6000}, + {0x432f8000}, {0x432fa000}, {0x432fc000}, {0x432fe000}, + {0x43300000}, {0x43302000}, {0x43304000}, {0x43306000}, + {0x43308000}, {0x4330a000}, {0x4330c000}, {0x4330e000}, + {0x43310000}, {0x43312000}, {0x43314000}, {0x43316000}, + {0x43318000}, {0x4331a000}, {0x4331c000}, {0x4331e000}, + {0x43320000}, {0x43322000}, {0x43324000}, {0x43326000}, + {0x43328000}, {0x4332a000}, {0x4332c000}, {0x4332e000}, + {0x43330000}, {0x43332000}, {0x43334000}, {0x43336000}, + {0x43338000}, {0x4333a000}, {0x4333c000}, {0x4333e000}, + {0x43340000}, {0x43342000}, {0x43344000}, {0x43346000}, + {0x43348000}, {0x4334a000}, {0x4334c000}, {0x4334e000}, + {0x43350000}, {0x43352000}, {0x43354000}, {0x43356000}, + {0x43358000}, {0x4335a000}, {0x4335c000}, {0x4335e000}, + {0x43360000}, {0x43362000}, {0x43364000}, {0x43366000}, + {0x43368000}, {0x4336a000}, {0x4336c000}, {0x4336e000}, + {0x43370000}, {0x43372000}, {0x43374000}, {0x43376000}, + {0x43378000}, {0x4337a000}, {0x4337c000}, {0x4337e000}, + {0x43380000}, {0x43382000}, {0x43384000}, {0x43386000}, + {0x43388000}, {0x4338a000}, {0x4338c000}, {0x4338e000}, + {0x43390000}, {0x43392000}, {0x43394000}, {0x43396000}, + {0x43398000}, {0x4339a000}, {0x4339c000}, {0x4339e000}, + {0x433a0000}, {0x433a2000}, {0x433a4000}, {0x433a6000}, + {0x433a8000}, {0x433aa000}, {0x433ac000}, {0x433ae000}, + {0x433b0000}, {0x433b2000}, {0x433b4000}, {0x433b6000}, + {0x433b8000}, {0x433ba000}, {0x433bc000}, {0x433be000}, + {0x433c0000}, {0x433c2000}, {0x433c4000}, {0x433c6000}, + {0x433c8000}, {0x433ca000}, {0x433cc000}, {0x433ce000}, + {0x433d0000}, {0x433d2000}, {0x433d4000}, {0x433d6000}, + {0x433d8000}, {0x433da000}, {0x433dc000}, {0x433de000}, + {0x433e0000}, {0x433e2000}, {0x433e4000}, {0x433e6000}, + {0x433e8000}, {0x433ea000}, {0x433ec000}, {0x433ee000}, + {0x433f0000}, {0x433f2000}, {0x433f4000}, {0x433f6000}, + {0x433f8000}, {0x433fa000}, {0x433fc000}, {0x433fe000}, + {0x43400000}, {0x43402000}, {0x43404000}, {0x43406000}, + {0x43408000}, {0x4340a000}, {0x4340c000}, {0x4340e000}, + {0x43410000}, {0x43412000}, {0x43414000}, {0x43416000}, + {0x43418000}, {0x4341a000}, {0x4341c000}, {0x4341e000}, + {0x43420000}, {0x43422000}, {0x43424000}, {0x43426000}, + {0x43428000}, {0x4342a000}, {0x4342c000}, {0x4342e000}, + {0x43430000}, {0x43432000}, {0x43434000}, {0x43436000}, + {0x43438000}, {0x4343a000}, {0x4343c000}, {0x4343e000}, + {0x43440000}, {0x43442000}, {0x43444000}, {0x43446000}, + {0x43448000}, {0x4344a000}, {0x4344c000}, {0x4344e000}, + {0x43450000}, {0x43452000}, {0x43454000}, {0x43456000}, + {0x43458000}, {0x4345a000}, {0x4345c000}, {0x4345e000}, + {0x43460000}, {0x43462000}, {0x43464000}, {0x43466000}, + {0x43468000}, {0x4346a000}, {0x4346c000}, {0x4346e000}, + {0x43470000}, {0x43472000}, {0x43474000}, {0x43476000}, + {0x43478000}, {0x4347a000}, {0x4347c000}, {0x4347e000}, + {0x43480000}, {0x43482000}, {0x43484000}, {0x43486000}, + {0x43488000}, {0x4348a000}, {0x4348c000}, {0x4348e000}, + {0x43490000}, {0x43492000}, {0x43494000}, {0x43496000}, + {0x43498000}, {0x4349a000}, {0x4349c000}, {0x4349e000}, + {0x434a0000}, {0x434a2000}, {0x434a4000}, {0x434a6000}, + {0x434a8000}, {0x434aa000}, {0x434ac000}, {0x434ae000}, + {0x434b0000}, {0x434b2000}, {0x434b4000}, {0x434b6000}, + {0x434b8000}, {0x434ba000}, {0x434bc000}, {0x434be000}, + {0x434c0000}, {0x434c2000}, {0x434c4000}, {0x434c6000}, + {0x434c8000}, {0x434ca000}, {0x434cc000}, {0x434ce000}, + {0x434d0000}, {0x434d2000}, {0x434d4000}, {0x434d6000}, + {0x434d8000}, {0x434da000}, {0x434dc000}, {0x434de000}, + {0x434e0000}, {0x434e2000}, {0x434e4000}, {0x434e6000}, + {0x434e8000}, {0x434ea000}, {0x434ec000}, {0x434ee000}, + {0x434f0000}, {0x434f2000}, {0x434f4000}, {0x434f6000}, + {0x434f8000}, {0x434fa000}, {0x434fc000}, {0x434fe000}, + {0x43500000}, {0x43502000}, {0x43504000}, {0x43506000}, + {0x43508000}, {0x4350a000}, {0x4350c000}, {0x4350e000}, + {0x43510000}, {0x43512000}, {0x43514000}, {0x43516000}, + {0x43518000}, {0x4351a000}, {0x4351c000}, {0x4351e000}, + {0x43520000}, {0x43522000}, {0x43524000}, {0x43526000}, + {0x43528000}, {0x4352a000}, {0x4352c000}, {0x4352e000}, + {0x43530000}, {0x43532000}, {0x43534000}, {0x43536000}, + {0x43538000}, {0x4353a000}, {0x4353c000}, {0x4353e000}, + {0x43540000}, {0x43542000}, {0x43544000}, {0x43546000}, + {0x43548000}, {0x4354a000}, {0x4354c000}, {0x4354e000}, + {0x43550000}, {0x43552000}, {0x43554000}, {0x43556000}, + {0x43558000}, {0x4355a000}, {0x4355c000}, {0x4355e000}, + {0x43560000}, {0x43562000}, {0x43564000}, {0x43566000}, + {0x43568000}, {0x4356a000}, {0x4356c000}, {0x4356e000}, + {0x43570000}, {0x43572000}, {0x43574000}, {0x43576000}, + {0x43578000}, {0x4357a000}, {0x4357c000}, {0x4357e000}, + {0x43580000}, {0x43582000}, {0x43584000}, {0x43586000}, + {0x43588000}, {0x4358a000}, {0x4358c000}, {0x4358e000}, + {0x43590000}, {0x43592000}, {0x43594000}, {0x43596000}, + {0x43598000}, {0x4359a000}, {0x4359c000}, {0x4359e000}, + {0x435a0000}, {0x435a2000}, {0x435a4000}, {0x435a6000}, + {0x435a8000}, {0x435aa000}, {0x435ac000}, {0x435ae000}, + {0x435b0000}, {0x435b2000}, {0x435b4000}, {0x435b6000}, + {0x435b8000}, {0x435ba000}, {0x435bc000}, {0x435be000}, + {0x435c0000}, {0x435c2000}, {0x435c4000}, {0x435c6000}, + {0x435c8000}, {0x435ca000}, {0x435cc000}, {0x435ce000}, + {0x435d0000}, {0x435d2000}, {0x435d4000}, {0x435d6000}, + {0x435d8000}, {0x435da000}, {0x435dc000}, {0x435de000}, + {0x435e0000}, {0x435e2000}, {0x435e4000}, {0x435e6000}, + {0x435e8000}, {0x435ea000}, {0x435ec000}, {0x435ee000}, + {0x435f0000}, {0x435f2000}, {0x435f4000}, {0x435f6000}, + {0x435f8000}, {0x435fa000}, {0x435fc000}, {0x435fe000}, + {0x43600000}, {0x43602000}, {0x43604000}, {0x43606000}, + {0x43608000}, {0x4360a000}, {0x4360c000}, {0x4360e000}, + {0x43610000}, {0x43612000}, {0x43614000}, {0x43616000}, + {0x43618000}, {0x4361a000}, {0x4361c000}, {0x4361e000}, + {0x43620000}, {0x43622000}, {0x43624000}, {0x43626000}, + {0x43628000}, {0x4362a000}, {0x4362c000}, {0x4362e000}, + {0x43630000}, {0x43632000}, {0x43634000}, {0x43636000}, + {0x43638000}, {0x4363a000}, {0x4363c000}, {0x4363e000}, + {0x43640000}, {0x43642000}, {0x43644000}, {0x43646000}, + {0x43648000}, {0x4364a000}, {0x4364c000}, {0x4364e000}, + {0x43650000}, {0x43652000}, {0x43654000}, {0x43656000}, + {0x43658000}, {0x4365a000}, {0x4365c000}, {0x4365e000}, + {0x43660000}, {0x43662000}, {0x43664000}, {0x43666000}, + {0x43668000}, {0x4366a000}, {0x4366c000}, {0x4366e000}, + {0x43670000}, {0x43672000}, {0x43674000}, {0x43676000}, + {0x43678000}, {0x4367a000}, {0x4367c000}, {0x4367e000}, + {0x43680000}, {0x43682000}, {0x43684000}, {0x43686000}, + {0x43688000}, {0x4368a000}, {0x4368c000}, {0x4368e000}, + {0x43690000}, {0x43692000}, {0x43694000}, {0x43696000}, + {0x43698000}, {0x4369a000}, {0x4369c000}, {0x4369e000}, + {0x436a0000}, {0x436a2000}, {0x436a4000}, {0x436a6000}, + {0x436a8000}, {0x436aa000}, {0x436ac000}, {0x436ae000}, + {0x436b0000}, {0x436b2000}, {0x436b4000}, {0x436b6000}, + {0x436b8000}, {0x436ba000}, {0x436bc000}, {0x436be000}, + {0x436c0000}, {0x436c2000}, {0x436c4000}, {0x436c6000}, + {0x436c8000}, {0x436ca000}, {0x436cc000}, {0x436ce000}, + {0x436d0000}, {0x436d2000}, {0x436d4000}, {0x436d6000}, + {0x436d8000}, {0x436da000}, {0x436dc000}, {0x436de000}, + {0x436e0000}, {0x436e2000}, {0x436e4000}, {0x436e6000}, + {0x436e8000}, {0x436ea000}, {0x436ec000}, {0x436ee000}, + {0x436f0000}, {0x436f2000}, {0x436f4000}, {0x436f6000}, + {0x436f8000}, {0x436fa000}, {0x436fc000}, {0x436fe000}, + {0x43700000}, {0x43702000}, {0x43704000}, {0x43706000}, + {0x43708000}, {0x4370a000}, {0x4370c000}, {0x4370e000}, + {0x43710000}, {0x43712000}, {0x43714000}, {0x43716000}, + {0x43718000}, {0x4371a000}, {0x4371c000}, {0x4371e000}, + {0x43720000}, {0x43722000}, {0x43724000}, {0x43726000}, + {0x43728000}, {0x4372a000}, {0x4372c000}, {0x4372e000}, + {0x43730000}, {0x43732000}, {0x43734000}, {0x43736000}, + {0x43738000}, {0x4373a000}, {0x4373c000}, {0x4373e000}, + {0x43740000}, {0x43742000}, {0x43744000}, {0x43746000}, + {0x43748000}, {0x4374a000}, {0x4374c000}, {0x4374e000}, + {0x43750000}, {0x43752000}, {0x43754000}, {0x43756000}, + {0x43758000}, {0x4375a000}, {0x4375c000}, {0x4375e000}, + {0x43760000}, {0x43762000}, {0x43764000}, {0x43766000}, + {0x43768000}, {0x4376a000}, {0x4376c000}, {0x4376e000}, + {0x43770000}, {0x43772000}, {0x43774000}, {0x43776000}, + {0x43778000}, {0x4377a000}, {0x4377c000}, {0x4377e000}, + {0x43780000}, {0x43782000}, {0x43784000}, {0x43786000}, + {0x43788000}, {0x4378a000}, {0x4378c000}, {0x4378e000}, + {0x43790000}, {0x43792000}, {0x43794000}, {0x43796000}, + {0x43798000}, {0x4379a000}, {0x4379c000}, {0x4379e000}, + {0x437a0000}, {0x437a2000}, {0x437a4000}, {0x437a6000}, + {0x437a8000}, {0x437aa000}, {0x437ac000}, {0x437ae000}, + {0x437b0000}, {0x437b2000}, {0x437b4000}, {0x437b6000}, + {0x437b8000}, {0x437ba000}, {0x437bc000}, {0x437be000}, + {0x437c0000}, {0x437c2000}, {0x437c4000}, {0x437c6000}, + {0x437c8000}, {0x437ca000}, {0x437cc000}, {0x437ce000}, + {0x437d0000}, {0x437d2000}, {0x437d4000}, {0x437d6000}, + {0x437d8000}, {0x437da000}, {0x437dc000}, {0x437de000}, + {0x437e0000}, {0x437e2000}, {0x437e4000}, {0x437e6000}, + {0x437e8000}, {0x437ea000}, {0x437ec000}, {0x437ee000}, + {0x437f0000}, {0x437f2000}, {0x437f4000}, {0x437f6000}, + {0x437f8000}, {0x437fa000}, {0x437fc000}, {0x437fe000}, + {0x43800000}, {0x43802000}, {0x43804000}, {0x43806000}, + {0x43808000}, {0x4380a000}, {0x4380c000}, {0x4380e000}, + {0x43810000}, {0x43812000}, {0x43814000}, {0x43816000}, + {0x43818000}, {0x4381a000}, {0x4381c000}, {0x4381e000}, + {0x43820000}, {0x43822000}, {0x43824000}, {0x43826000}, + {0x43828000}, {0x4382a000}, {0x4382c000}, {0x4382e000}, + {0x43830000}, {0x43832000}, {0x43834000}, {0x43836000}, + {0x43838000}, {0x4383a000}, {0x4383c000}, {0x4383e000}, + {0x43840000}, {0x43842000}, {0x43844000}, {0x43846000}, + {0x43848000}, {0x4384a000}, {0x4384c000}, {0x4384e000}, + {0x43850000}, {0x43852000}, {0x43854000}, {0x43856000}, + {0x43858000}, {0x4385a000}, {0x4385c000}, {0x4385e000}, + {0x43860000}, {0x43862000}, {0x43864000}, {0x43866000}, + {0x43868000}, {0x4386a000}, {0x4386c000}, {0x4386e000}, + {0x43870000}, {0x43872000}, {0x43874000}, {0x43876000}, + {0x43878000}, {0x4387a000}, {0x4387c000}, {0x4387e000}, + {0x43880000}, {0x43882000}, {0x43884000}, {0x43886000}, + {0x43888000}, {0x4388a000}, {0x4388c000}, {0x4388e000}, + {0x43890000}, {0x43892000}, {0x43894000}, {0x43896000}, + {0x43898000}, {0x4389a000}, {0x4389c000}, {0x4389e000}, + {0x438a0000}, {0x438a2000}, {0x438a4000}, {0x438a6000}, + {0x438a8000}, {0x438aa000}, {0x438ac000}, {0x438ae000}, + {0x438b0000}, {0x438b2000}, {0x438b4000}, {0x438b6000}, + {0x438b8000}, {0x438ba000}, {0x438bc000}, {0x438be000}, + {0x438c0000}, {0x438c2000}, {0x438c4000}, {0x438c6000}, + {0x438c8000}, {0x438ca000}, {0x438cc000}, {0x438ce000}, + {0x438d0000}, {0x438d2000}, {0x438d4000}, {0x438d6000}, + {0x438d8000}, {0x438da000}, {0x438dc000}, {0x438de000}, + {0x438e0000}, {0x438e2000}, {0x438e4000}, {0x438e6000}, + {0x438e8000}, {0x438ea000}, {0x438ec000}, {0x438ee000}, + {0x438f0000}, {0x438f2000}, {0x438f4000}, {0x438f6000}, + {0x438f8000}, {0x438fa000}, {0x438fc000}, {0x438fe000}, + {0x43900000}, {0x43902000}, {0x43904000}, {0x43906000}, + {0x43908000}, {0x4390a000}, {0x4390c000}, {0x4390e000}, + {0x43910000}, {0x43912000}, {0x43914000}, {0x43916000}, + {0x43918000}, {0x4391a000}, {0x4391c000}, {0x4391e000}, + {0x43920000}, {0x43922000}, {0x43924000}, {0x43926000}, + {0x43928000}, {0x4392a000}, {0x4392c000}, {0x4392e000}, + {0x43930000}, {0x43932000}, {0x43934000}, {0x43936000}, + {0x43938000}, {0x4393a000}, {0x4393c000}, {0x4393e000}, + {0x43940000}, {0x43942000}, {0x43944000}, {0x43946000}, + {0x43948000}, {0x4394a000}, {0x4394c000}, {0x4394e000}, + {0x43950000}, {0x43952000}, {0x43954000}, {0x43956000}, + {0x43958000}, {0x4395a000}, {0x4395c000}, {0x4395e000}, + {0x43960000}, {0x43962000}, {0x43964000}, {0x43966000}, + {0x43968000}, {0x4396a000}, {0x4396c000}, {0x4396e000}, + {0x43970000}, {0x43972000}, {0x43974000}, {0x43976000}, + {0x43978000}, {0x4397a000}, {0x4397c000}, {0x4397e000}, + {0x43980000}, {0x43982000}, {0x43984000}, {0x43986000}, + {0x43988000}, {0x4398a000}, {0x4398c000}, {0x4398e000}, + {0x43990000}, {0x43992000}, {0x43994000}, {0x43996000}, + {0x43998000}, {0x4399a000}, {0x4399c000}, {0x4399e000}, + {0x439a0000}, {0x439a2000}, {0x439a4000}, {0x439a6000}, + {0x439a8000}, {0x439aa000}, {0x439ac000}, {0x439ae000}, + {0x439b0000}, {0x439b2000}, {0x439b4000}, {0x439b6000}, + {0x439b8000}, {0x439ba000}, {0x439bc000}, {0x439be000}, + {0x439c0000}, {0x439c2000}, {0x439c4000}, {0x439c6000}, + {0x439c8000}, {0x439ca000}, {0x439cc000}, {0x439ce000}, + {0x439d0000}, {0x439d2000}, {0x439d4000}, {0x439d6000}, + {0x439d8000}, {0x439da000}, {0x439dc000}, {0x439de000}, + {0x439e0000}, {0x439e2000}, {0x439e4000}, {0x439e6000}, + {0x439e8000}, {0x439ea000}, {0x439ec000}, {0x439ee000}, + {0x439f0000}, {0x439f2000}, {0x439f4000}, {0x439f6000}, + {0x439f8000}, {0x439fa000}, {0x439fc000}, {0x439fe000}, + {0x43a00000}, {0x43a02000}, {0x43a04000}, {0x43a06000}, + {0x43a08000}, {0x43a0a000}, {0x43a0c000}, {0x43a0e000}, + {0x43a10000}, {0x43a12000}, {0x43a14000}, {0x43a16000}, + {0x43a18000}, {0x43a1a000}, {0x43a1c000}, {0x43a1e000}, + {0x43a20000}, {0x43a22000}, {0x43a24000}, {0x43a26000}, + {0x43a28000}, {0x43a2a000}, {0x43a2c000}, {0x43a2e000}, + {0x43a30000}, {0x43a32000}, {0x43a34000}, {0x43a36000}, + {0x43a38000}, {0x43a3a000}, {0x43a3c000}, {0x43a3e000}, + {0x43a40000}, {0x43a42000}, {0x43a44000}, {0x43a46000}, + {0x43a48000}, {0x43a4a000}, {0x43a4c000}, {0x43a4e000}, + {0x43a50000}, {0x43a52000}, {0x43a54000}, {0x43a56000}, + {0x43a58000}, {0x43a5a000}, {0x43a5c000}, {0x43a5e000}, + {0x43a60000}, {0x43a62000}, {0x43a64000}, {0x43a66000}, + {0x43a68000}, {0x43a6a000}, {0x43a6c000}, {0x43a6e000}, + {0x43a70000}, {0x43a72000}, {0x43a74000}, {0x43a76000}, + {0x43a78000}, {0x43a7a000}, {0x43a7c000}, {0x43a7e000}, + {0x43a80000}, {0x43a82000}, {0x43a84000}, {0x43a86000}, + {0x43a88000}, {0x43a8a000}, {0x43a8c000}, {0x43a8e000}, + {0x43a90000}, {0x43a92000}, {0x43a94000}, {0x43a96000}, + {0x43a98000}, {0x43a9a000}, {0x43a9c000}, {0x43a9e000}, + {0x43aa0000}, {0x43aa2000}, {0x43aa4000}, {0x43aa6000}, + {0x43aa8000}, {0x43aaa000}, {0x43aac000}, {0x43aae000}, + {0x43ab0000}, {0x43ab2000}, {0x43ab4000}, {0x43ab6000}, + {0x43ab8000}, {0x43aba000}, {0x43abc000}, {0x43abe000}, + {0x43ac0000}, {0x43ac2000}, {0x43ac4000}, {0x43ac6000}, + {0x43ac8000}, {0x43aca000}, {0x43acc000}, {0x43ace000}, + {0x43ad0000}, {0x43ad2000}, {0x43ad4000}, {0x43ad6000}, + {0x43ad8000}, {0x43ada000}, {0x43adc000}, {0x43ade000}, + {0x43ae0000}, {0x43ae2000}, {0x43ae4000}, {0x43ae6000}, + {0x43ae8000}, {0x43aea000}, {0x43aec000}, {0x43aee000}, + {0x43af0000}, {0x43af2000}, {0x43af4000}, {0x43af6000}, + {0x43af8000}, {0x43afa000}, {0x43afc000}, {0x43afe000}, + {0x43b00000}, {0x43b02000}, {0x43b04000}, {0x43b06000}, + {0x43b08000}, {0x43b0a000}, {0x43b0c000}, {0x43b0e000}, + {0x43b10000}, {0x43b12000}, {0x43b14000}, {0x43b16000}, + {0x43b18000}, {0x43b1a000}, {0x43b1c000}, {0x43b1e000}, + {0x43b20000}, {0x43b22000}, {0x43b24000}, {0x43b26000}, + {0x43b28000}, {0x43b2a000}, {0x43b2c000}, {0x43b2e000}, + {0x43b30000}, {0x43b32000}, {0x43b34000}, {0x43b36000}, + {0x43b38000}, {0x43b3a000}, {0x43b3c000}, {0x43b3e000}, + {0x43b40000}, {0x43b42000}, {0x43b44000}, {0x43b46000}, + {0x43b48000}, {0x43b4a000}, {0x43b4c000}, {0x43b4e000}, + {0x43b50000}, {0x43b52000}, {0x43b54000}, {0x43b56000}, + {0x43b58000}, {0x43b5a000}, {0x43b5c000}, {0x43b5e000}, + {0x43b60000}, {0x43b62000}, {0x43b64000}, {0x43b66000}, + {0x43b68000}, {0x43b6a000}, {0x43b6c000}, {0x43b6e000}, + {0x43b70000}, {0x43b72000}, {0x43b74000}, {0x43b76000}, + {0x43b78000}, {0x43b7a000}, {0x43b7c000}, {0x43b7e000}, + {0x43b80000}, {0x43b82000}, {0x43b84000}, {0x43b86000}, + {0x43b88000}, {0x43b8a000}, {0x43b8c000}, {0x43b8e000}, + {0x43b90000}, {0x43b92000}, {0x43b94000}, {0x43b96000}, + {0x43b98000}, {0x43b9a000}, {0x43b9c000}, {0x43b9e000}, + {0x43ba0000}, {0x43ba2000}, {0x43ba4000}, {0x43ba6000}, + {0x43ba8000}, {0x43baa000}, {0x43bac000}, {0x43bae000}, + {0x43bb0000}, {0x43bb2000}, {0x43bb4000}, {0x43bb6000}, + {0x43bb8000}, {0x43bba000}, {0x43bbc000}, {0x43bbe000}, + {0x43bc0000}, {0x43bc2000}, {0x43bc4000}, {0x43bc6000}, + {0x43bc8000}, {0x43bca000}, {0x43bcc000}, {0x43bce000}, + {0x43bd0000}, {0x43bd2000}, {0x43bd4000}, {0x43bd6000}, + {0x43bd8000}, {0x43bda000}, {0x43bdc000}, {0x43bde000}, + {0x43be0000}, {0x43be2000}, {0x43be4000}, {0x43be6000}, + {0x43be8000}, {0x43bea000}, {0x43bec000}, {0x43bee000}, + {0x43bf0000}, {0x43bf2000}, {0x43bf4000}, {0x43bf6000}, + {0x43bf8000}, {0x43bfa000}, {0x43bfc000}, {0x43bfe000}, + {0x43c00000}, {0x43c02000}, {0x43c04000}, {0x43c06000}, + {0x43c08000}, {0x43c0a000}, {0x43c0c000}, {0x43c0e000}, + {0x43c10000}, {0x43c12000}, {0x43c14000}, {0x43c16000}, + {0x43c18000}, {0x43c1a000}, {0x43c1c000}, {0x43c1e000}, + {0x43c20000}, {0x43c22000}, {0x43c24000}, {0x43c26000}, + {0x43c28000}, {0x43c2a000}, {0x43c2c000}, {0x43c2e000}, + {0x43c30000}, {0x43c32000}, {0x43c34000}, {0x43c36000}, + {0x43c38000}, {0x43c3a000}, {0x43c3c000}, {0x43c3e000}, + {0x43c40000}, {0x43c42000}, {0x43c44000}, {0x43c46000}, + {0x43c48000}, {0x43c4a000}, {0x43c4c000}, {0x43c4e000}, + {0x43c50000}, {0x43c52000}, {0x43c54000}, {0x43c56000}, + {0x43c58000}, {0x43c5a000}, {0x43c5c000}, {0x43c5e000}, + {0x43c60000}, {0x43c62000}, {0x43c64000}, {0x43c66000}, + {0x43c68000}, {0x43c6a000}, {0x43c6c000}, {0x43c6e000}, + {0x43c70000}, {0x43c72000}, {0x43c74000}, {0x43c76000}, + {0x43c78000}, {0x43c7a000}, {0x43c7c000}, {0x43c7e000}, + {0x43c80000}, {0x43c82000}, {0x43c84000}, {0x43c86000}, + {0x43c88000}, {0x43c8a000}, {0x43c8c000}, {0x43c8e000}, + {0x43c90000}, {0x43c92000}, {0x43c94000}, {0x43c96000}, + {0x43c98000}, {0x43c9a000}, {0x43c9c000}, {0x43c9e000}, + {0x43ca0000}, {0x43ca2000}, {0x43ca4000}, {0x43ca6000}, + {0x43ca8000}, {0x43caa000}, {0x43cac000}, {0x43cae000}, + {0x43cb0000}, {0x43cb2000}, {0x43cb4000}, {0x43cb6000}, + {0x43cb8000}, {0x43cba000}, {0x43cbc000}, {0x43cbe000}, + {0x43cc0000}, {0x43cc2000}, {0x43cc4000}, {0x43cc6000}, + {0x43cc8000}, {0x43cca000}, {0x43ccc000}, {0x43cce000}, + {0x43cd0000}, {0x43cd2000}, {0x43cd4000}, {0x43cd6000}, + {0x43cd8000}, {0x43cda000}, {0x43cdc000}, {0x43cde000}, + {0x43ce0000}, {0x43ce2000}, {0x43ce4000}, {0x43ce6000}, + {0x43ce8000}, {0x43cea000}, {0x43cec000}, {0x43cee000}, + {0x43cf0000}, {0x43cf2000}, {0x43cf4000}, {0x43cf6000}, + {0x43cf8000}, {0x43cfa000}, {0x43cfc000}, {0x43cfe000}, + {0x43d00000}, {0x43d02000}, {0x43d04000}, {0x43d06000}, + {0x43d08000}, {0x43d0a000}, {0x43d0c000}, {0x43d0e000}, + {0x43d10000}, {0x43d12000}, {0x43d14000}, {0x43d16000}, + {0x43d18000}, {0x43d1a000}, {0x43d1c000}, {0x43d1e000}, + {0x43d20000}, {0x43d22000}, {0x43d24000}, {0x43d26000}, + {0x43d28000}, {0x43d2a000}, {0x43d2c000}, {0x43d2e000}, + {0x43d30000}, {0x43d32000}, {0x43d34000}, {0x43d36000}, + {0x43d38000}, {0x43d3a000}, {0x43d3c000}, {0x43d3e000}, + {0x43d40000}, {0x43d42000}, {0x43d44000}, {0x43d46000}, + {0x43d48000}, {0x43d4a000}, {0x43d4c000}, {0x43d4e000}, + {0x43d50000}, {0x43d52000}, {0x43d54000}, {0x43d56000}, + {0x43d58000}, {0x43d5a000}, {0x43d5c000}, {0x43d5e000}, + {0x43d60000}, {0x43d62000}, {0x43d64000}, {0x43d66000}, + {0x43d68000}, {0x43d6a000}, {0x43d6c000}, {0x43d6e000}, + {0x43d70000}, {0x43d72000}, {0x43d74000}, {0x43d76000}, + {0x43d78000}, {0x43d7a000}, {0x43d7c000}, {0x43d7e000}, + {0x43d80000}, {0x43d82000}, {0x43d84000}, {0x43d86000}, + {0x43d88000}, {0x43d8a000}, {0x43d8c000}, {0x43d8e000}, + {0x43d90000}, {0x43d92000}, {0x43d94000}, {0x43d96000}, + {0x43d98000}, {0x43d9a000}, {0x43d9c000}, {0x43d9e000}, + {0x43da0000}, {0x43da2000}, {0x43da4000}, {0x43da6000}, + {0x43da8000}, {0x43daa000}, {0x43dac000}, {0x43dae000}, + {0x43db0000}, {0x43db2000}, {0x43db4000}, {0x43db6000}, + {0x43db8000}, {0x43dba000}, {0x43dbc000}, {0x43dbe000}, + {0x43dc0000}, {0x43dc2000}, {0x43dc4000}, {0x43dc6000}, + {0x43dc8000}, {0x43dca000}, {0x43dcc000}, {0x43dce000}, + {0x43dd0000}, {0x43dd2000}, {0x43dd4000}, {0x43dd6000}, + {0x43dd8000}, {0x43dda000}, {0x43ddc000}, {0x43dde000}, + {0x43de0000}, {0x43de2000}, {0x43de4000}, {0x43de6000}, + {0x43de8000}, {0x43dea000}, {0x43dec000}, {0x43dee000}, + {0x43df0000}, {0x43df2000}, {0x43df4000}, {0x43df6000}, + {0x43df8000}, {0x43dfa000}, {0x43dfc000}, {0x43dfe000}, + {0x43e00000}, {0x43e02000}, {0x43e04000}, {0x43e06000}, + {0x43e08000}, {0x43e0a000}, {0x43e0c000}, {0x43e0e000}, + {0x43e10000}, {0x43e12000}, {0x43e14000}, {0x43e16000}, + {0x43e18000}, {0x43e1a000}, {0x43e1c000}, {0x43e1e000}, + {0x43e20000}, {0x43e22000}, {0x43e24000}, {0x43e26000}, + {0x43e28000}, {0x43e2a000}, {0x43e2c000}, {0x43e2e000}, + {0x43e30000}, {0x43e32000}, {0x43e34000}, {0x43e36000}, + {0x43e38000}, {0x43e3a000}, {0x43e3c000}, {0x43e3e000}, + {0x43e40000}, {0x43e42000}, {0x43e44000}, {0x43e46000}, + {0x43e48000}, {0x43e4a000}, {0x43e4c000}, {0x43e4e000}, + {0x43e50000}, {0x43e52000}, {0x43e54000}, {0x43e56000}, + {0x43e58000}, {0x43e5a000}, {0x43e5c000}, {0x43e5e000}, + {0x43e60000}, {0x43e62000}, {0x43e64000}, {0x43e66000}, + {0x43e68000}, {0x43e6a000}, {0x43e6c000}, {0x43e6e000}, + {0x43e70000}, {0x43e72000}, {0x43e74000}, {0x43e76000}, + {0x43e78000}, {0x43e7a000}, {0x43e7c000}, {0x43e7e000}, + {0x43e80000}, {0x43e82000}, {0x43e84000}, {0x43e86000}, + {0x43e88000}, {0x43e8a000}, {0x43e8c000}, {0x43e8e000}, + {0x43e90000}, {0x43e92000}, {0x43e94000}, {0x43e96000}, + {0x43e98000}, {0x43e9a000}, {0x43e9c000}, {0x43e9e000}, + {0x43ea0000}, {0x43ea2000}, {0x43ea4000}, {0x43ea6000}, + {0x43ea8000}, {0x43eaa000}, {0x43eac000}, {0x43eae000}, + {0x43eb0000}, {0x43eb2000}, {0x43eb4000}, {0x43eb6000}, + {0x43eb8000}, {0x43eba000}, {0x43ebc000}, {0x43ebe000}, + {0x43ec0000}, {0x43ec2000}, {0x43ec4000}, {0x43ec6000}, + {0x43ec8000}, {0x43eca000}, {0x43ecc000}, {0x43ece000}, + {0x43ed0000}, {0x43ed2000}, {0x43ed4000}, {0x43ed6000}, + {0x43ed8000}, {0x43eda000}, {0x43edc000}, {0x43ede000}, + {0x43ee0000}, {0x43ee2000}, {0x43ee4000}, {0x43ee6000}, + {0x43ee8000}, {0x43eea000}, {0x43eec000}, {0x43eee000}, + {0x43ef0000}, {0x43ef2000}, {0x43ef4000}, {0x43ef6000}, + {0x43ef8000}, {0x43efa000}, {0x43efc000}, {0x43efe000}, + {0x43f00000}, {0x43f02000}, {0x43f04000}, {0x43f06000}, + {0x43f08000}, {0x43f0a000}, {0x43f0c000}, {0x43f0e000}, + {0x43f10000}, {0x43f12000}, {0x43f14000}, {0x43f16000}, + {0x43f18000}, {0x43f1a000}, {0x43f1c000}, {0x43f1e000}, + {0x43f20000}, {0x43f22000}, {0x43f24000}, {0x43f26000}, + {0x43f28000}, {0x43f2a000}, {0x43f2c000}, {0x43f2e000}, + {0x43f30000}, {0x43f32000}, {0x43f34000}, {0x43f36000}, + {0x43f38000}, {0x43f3a000}, {0x43f3c000}, {0x43f3e000}, + {0x43f40000}, {0x43f42000}, {0x43f44000}, {0x43f46000}, + {0x43f48000}, {0x43f4a000}, {0x43f4c000}, {0x43f4e000}, + {0x43f50000}, {0x43f52000}, {0x43f54000}, {0x43f56000}, + {0x43f58000}, {0x43f5a000}, {0x43f5c000}, {0x43f5e000}, + {0x43f60000}, {0x43f62000}, {0x43f64000}, {0x43f66000}, + {0x43f68000}, {0x43f6a000}, {0x43f6c000}, {0x43f6e000}, + {0x43f70000}, {0x43f72000}, {0x43f74000}, {0x43f76000}, + {0x43f78000}, {0x43f7a000}, {0x43f7c000}, {0x43f7e000}, + {0x43f80000}, {0x43f82000}, {0x43f84000}, {0x43f86000}, + {0x43f88000}, {0x43f8a000}, {0x43f8c000}, {0x43f8e000}, + {0x43f90000}, {0x43f92000}, {0x43f94000}, {0x43f96000}, + {0x43f98000}, {0x43f9a000}, {0x43f9c000}, {0x43f9e000}, + {0x43fa0000}, {0x43fa2000}, {0x43fa4000}, {0x43fa6000}, + {0x43fa8000}, {0x43faa000}, {0x43fac000}, {0x43fae000}, + {0x43fb0000}, {0x43fb2000}, {0x43fb4000}, {0x43fb6000}, + {0x43fb8000}, {0x43fba000}, {0x43fbc000}, {0x43fbe000}, + {0x43fc0000}, {0x43fc2000}, {0x43fc4000}, {0x43fc6000}, + {0x43fc8000}, {0x43fca000}, {0x43fcc000}, {0x43fce000}, + {0x43fd0000}, {0x43fd2000}, {0x43fd4000}, {0x43fd6000}, + {0x43fd8000}, {0x43fda000}, {0x43fdc000}, {0x43fde000}, + {0x43fe0000}, {0x43fe2000}, {0x43fe4000}, {0x43fe6000}, + {0x43fe8000}, {0x43fea000}, {0x43fec000}, {0x43fee000}, + {0x43ff0000}, {0x43ff2000}, {0x43ff4000}, {0x43ff6000}, + {0x43ff8000}, {0x43ffa000}, {0x43ffc000}, {0x43ffe000}, + {0x44000000}, {0x44002000}, {0x44004000}, {0x44006000}, + {0x44008000}, {0x4400a000}, {0x4400c000}, {0x4400e000}, + {0x44010000}, {0x44012000}, {0x44014000}, {0x44016000}, + {0x44018000}, {0x4401a000}, {0x4401c000}, {0x4401e000}, + {0x44020000}, {0x44022000}, {0x44024000}, {0x44026000}, + {0x44028000}, {0x4402a000}, {0x4402c000}, {0x4402e000}, + {0x44030000}, {0x44032000}, {0x44034000}, {0x44036000}, + {0x44038000}, {0x4403a000}, {0x4403c000}, {0x4403e000}, + {0x44040000}, {0x44042000}, {0x44044000}, {0x44046000}, + {0x44048000}, {0x4404a000}, {0x4404c000}, {0x4404e000}, + {0x44050000}, {0x44052000}, {0x44054000}, {0x44056000}, + {0x44058000}, {0x4405a000}, {0x4405c000}, {0x4405e000}, + {0x44060000}, {0x44062000}, {0x44064000}, {0x44066000}, + {0x44068000}, {0x4406a000}, {0x4406c000}, {0x4406e000}, + {0x44070000}, {0x44072000}, {0x44074000}, {0x44076000}, + {0x44078000}, {0x4407a000}, {0x4407c000}, {0x4407e000}, + {0x44080000}, {0x44082000}, {0x44084000}, {0x44086000}, + {0x44088000}, {0x4408a000}, {0x4408c000}, {0x4408e000}, + {0x44090000}, {0x44092000}, {0x44094000}, {0x44096000}, + {0x44098000}, {0x4409a000}, {0x4409c000}, {0x4409e000}, + {0x440a0000}, {0x440a2000}, {0x440a4000}, {0x440a6000}, + {0x440a8000}, {0x440aa000}, {0x440ac000}, {0x440ae000}, + {0x440b0000}, {0x440b2000}, {0x440b4000}, {0x440b6000}, + {0x440b8000}, {0x440ba000}, {0x440bc000}, {0x440be000}, + {0x440c0000}, {0x440c2000}, {0x440c4000}, {0x440c6000}, + {0x440c8000}, {0x440ca000}, {0x440cc000}, {0x440ce000}, + {0x440d0000}, {0x440d2000}, {0x440d4000}, {0x440d6000}, + {0x440d8000}, {0x440da000}, {0x440dc000}, {0x440de000}, + {0x440e0000}, {0x440e2000}, {0x440e4000}, {0x440e6000}, + {0x440e8000}, {0x440ea000}, {0x440ec000}, {0x440ee000}, + {0x440f0000}, {0x440f2000}, {0x440f4000}, {0x440f6000}, + {0x440f8000}, {0x440fa000}, {0x440fc000}, {0x440fe000}, + {0x44100000}, {0x44102000}, {0x44104000}, {0x44106000}, + {0x44108000}, {0x4410a000}, {0x4410c000}, {0x4410e000}, + {0x44110000}, {0x44112000}, {0x44114000}, {0x44116000}, + {0x44118000}, {0x4411a000}, {0x4411c000}, {0x4411e000}, + {0x44120000}, {0x44122000}, {0x44124000}, {0x44126000}, + {0x44128000}, {0x4412a000}, {0x4412c000}, {0x4412e000}, + {0x44130000}, {0x44132000}, {0x44134000}, {0x44136000}, + {0x44138000}, {0x4413a000}, {0x4413c000}, {0x4413e000}, + {0x44140000}, {0x44142000}, {0x44144000}, {0x44146000}, + {0x44148000}, {0x4414a000}, {0x4414c000}, {0x4414e000}, + {0x44150000}, {0x44152000}, {0x44154000}, {0x44156000}, + {0x44158000}, {0x4415a000}, {0x4415c000}, {0x4415e000}, + {0x44160000}, {0x44162000}, {0x44164000}, {0x44166000}, + {0x44168000}, {0x4416a000}, {0x4416c000}, {0x4416e000}, + {0x44170000}, {0x44172000}, {0x44174000}, {0x44176000}, + {0x44178000}, {0x4417a000}, {0x4417c000}, {0x4417e000}, + {0x44180000}, {0x44182000}, {0x44184000}, {0x44186000}, + {0x44188000}, {0x4418a000}, {0x4418c000}, {0x4418e000}, + {0x44190000}, {0x44192000}, {0x44194000}, {0x44196000}, + {0x44198000}, {0x4419a000}, {0x4419c000}, {0x4419e000}, + {0x441a0000}, {0x441a2000}, {0x441a4000}, {0x441a6000}, + {0x441a8000}, {0x441aa000}, {0x441ac000}, {0x441ae000}, + {0x441b0000}, {0x441b2000}, {0x441b4000}, {0x441b6000}, + {0x441b8000}, {0x441ba000}, {0x441bc000}, {0x441be000}, + {0x441c0000}, {0x441c2000}, {0x441c4000}, {0x441c6000}, + {0x441c8000}, {0x441ca000}, {0x441cc000}, {0x441ce000}, + {0x441d0000}, {0x441d2000}, {0x441d4000}, {0x441d6000}, + {0x441d8000}, {0x441da000}, {0x441dc000}, {0x441de000}, + {0x441e0000}, {0x441e2000}, {0x441e4000}, {0x441e6000}, + {0x441e8000}, {0x441ea000}, {0x441ec000}, {0x441ee000}, + {0x441f0000}, {0x441f2000}, {0x441f4000}, {0x441f6000}, + {0x441f8000}, {0x441fa000}, {0x441fc000}, {0x441fe000}, + {0x44200000}, {0x44202000}, {0x44204000}, {0x44206000}, + {0x44208000}, {0x4420a000}, {0x4420c000}, {0x4420e000}, + {0x44210000}, {0x44212000}, {0x44214000}, {0x44216000}, + {0x44218000}, {0x4421a000}, {0x4421c000}, {0x4421e000}, + {0x44220000}, {0x44222000}, {0x44224000}, {0x44226000}, + {0x44228000}, {0x4422a000}, {0x4422c000}, {0x4422e000}, + {0x44230000}, {0x44232000}, {0x44234000}, {0x44236000}, + {0x44238000}, {0x4423a000}, {0x4423c000}, {0x4423e000}, + {0x44240000}, {0x44242000}, {0x44244000}, {0x44246000}, + {0x44248000}, {0x4424a000}, {0x4424c000}, {0x4424e000}, + {0x44250000}, {0x44252000}, {0x44254000}, {0x44256000}, + {0x44258000}, {0x4425a000}, {0x4425c000}, {0x4425e000}, + {0x44260000}, {0x44262000}, {0x44264000}, {0x44266000}, + {0x44268000}, {0x4426a000}, {0x4426c000}, {0x4426e000}, + {0x44270000}, {0x44272000}, {0x44274000}, {0x44276000}, + {0x44278000}, {0x4427a000}, {0x4427c000}, {0x4427e000}, + {0x44280000}, {0x44282000}, {0x44284000}, {0x44286000}, + {0x44288000}, {0x4428a000}, {0x4428c000}, {0x4428e000}, + {0x44290000}, {0x44292000}, {0x44294000}, {0x44296000}, + {0x44298000}, {0x4429a000}, {0x4429c000}, {0x4429e000}, + {0x442a0000}, {0x442a2000}, {0x442a4000}, {0x442a6000}, + {0x442a8000}, {0x442aa000}, {0x442ac000}, {0x442ae000}, + {0x442b0000}, {0x442b2000}, {0x442b4000}, {0x442b6000}, + {0x442b8000}, {0x442ba000}, {0x442bc000}, {0x442be000}, + {0x442c0000}, {0x442c2000}, {0x442c4000}, {0x442c6000}, + {0x442c8000}, {0x442ca000}, {0x442cc000}, {0x442ce000}, + {0x442d0000}, {0x442d2000}, {0x442d4000}, {0x442d6000}, + {0x442d8000}, {0x442da000}, {0x442dc000}, {0x442de000}, + {0x442e0000}, {0x442e2000}, {0x442e4000}, {0x442e6000}, + {0x442e8000}, {0x442ea000}, {0x442ec000}, {0x442ee000}, + {0x442f0000}, {0x442f2000}, {0x442f4000}, {0x442f6000}, + {0x442f8000}, {0x442fa000}, {0x442fc000}, {0x442fe000}, + {0x44300000}, {0x44302000}, {0x44304000}, {0x44306000}, + {0x44308000}, {0x4430a000}, {0x4430c000}, {0x4430e000}, + {0x44310000}, {0x44312000}, {0x44314000}, {0x44316000}, + {0x44318000}, {0x4431a000}, {0x4431c000}, {0x4431e000}, + {0x44320000}, {0x44322000}, {0x44324000}, {0x44326000}, + {0x44328000}, {0x4432a000}, {0x4432c000}, {0x4432e000}, + {0x44330000}, {0x44332000}, {0x44334000}, {0x44336000}, + {0x44338000}, {0x4433a000}, {0x4433c000}, {0x4433e000}, + {0x44340000}, {0x44342000}, {0x44344000}, {0x44346000}, + {0x44348000}, {0x4434a000}, {0x4434c000}, {0x4434e000}, + {0x44350000}, {0x44352000}, {0x44354000}, {0x44356000}, + {0x44358000}, {0x4435a000}, {0x4435c000}, {0x4435e000}, + {0x44360000}, {0x44362000}, {0x44364000}, {0x44366000}, + {0x44368000}, {0x4436a000}, {0x4436c000}, {0x4436e000}, + {0x44370000}, {0x44372000}, {0x44374000}, {0x44376000}, + {0x44378000}, {0x4437a000}, {0x4437c000}, {0x4437e000}, + {0x44380000}, {0x44382000}, {0x44384000}, {0x44386000}, + {0x44388000}, {0x4438a000}, {0x4438c000}, {0x4438e000}, + {0x44390000}, {0x44392000}, {0x44394000}, {0x44396000}, + {0x44398000}, {0x4439a000}, {0x4439c000}, {0x4439e000}, + {0x443a0000}, {0x443a2000}, {0x443a4000}, {0x443a6000}, + {0x443a8000}, {0x443aa000}, {0x443ac000}, {0x443ae000}, + {0x443b0000}, {0x443b2000}, {0x443b4000}, {0x443b6000}, + {0x443b8000}, {0x443ba000}, {0x443bc000}, {0x443be000}, + {0x443c0000}, {0x443c2000}, {0x443c4000}, {0x443c6000}, + {0x443c8000}, {0x443ca000}, {0x443cc000}, {0x443ce000}, + {0x443d0000}, {0x443d2000}, {0x443d4000}, {0x443d6000}, + {0x443d8000}, {0x443da000}, {0x443dc000}, {0x443de000}, + {0x443e0000}, {0x443e2000}, {0x443e4000}, {0x443e6000}, + {0x443e8000}, {0x443ea000}, {0x443ec000}, {0x443ee000}, + {0x443f0000}, {0x443f2000}, {0x443f4000}, {0x443f6000}, + {0x443f8000}, {0x443fa000}, {0x443fc000}, {0x443fe000}, + {0x44400000}, {0x44402000}, {0x44404000}, {0x44406000}, + {0x44408000}, {0x4440a000}, {0x4440c000}, {0x4440e000}, + {0x44410000}, {0x44412000}, {0x44414000}, {0x44416000}, + {0x44418000}, {0x4441a000}, {0x4441c000}, {0x4441e000}, + {0x44420000}, {0x44422000}, {0x44424000}, {0x44426000}, + {0x44428000}, {0x4442a000}, {0x4442c000}, {0x4442e000}, + {0x44430000}, {0x44432000}, {0x44434000}, {0x44436000}, + {0x44438000}, {0x4443a000}, {0x4443c000}, {0x4443e000}, + {0x44440000}, {0x44442000}, {0x44444000}, {0x44446000}, + {0x44448000}, {0x4444a000}, {0x4444c000}, {0x4444e000}, + {0x44450000}, {0x44452000}, {0x44454000}, {0x44456000}, + {0x44458000}, {0x4445a000}, {0x4445c000}, {0x4445e000}, + {0x44460000}, {0x44462000}, {0x44464000}, {0x44466000}, + {0x44468000}, {0x4446a000}, {0x4446c000}, {0x4446e000}, + {0x44470000}, {0x44472000}, {0x44474000}, {0x44476000}, + {0x44478000}, {0x4447a000}, {0x4447c000}, {0x4447e000}, + {0x44480000}, {0x44482000}, {0x44484000}, {0x44486000}, + {0x44488000}, {0x4448a000}, {0x4448c000}, {0x4448e000}, + {0x44490000}, {0x44492000}, {0x44494000}, {0x44496000}, + {0x44498000}, {0x4449a000}, {0x4449c000}, {0x4449e000}, + {0x444a0000}, {0x444a2000}, {0x444a4000}, {0x444a6000}, + {0x444a8000}, {0x444aa000}, {0x444ac000}, {0x444ae000}, + {0x444b0000}, {0x444b2000}, {0x444b4000}, {0x444b6000}, + {0x444b8000}, {0x444ba000}, {0x444bc000}, {0x444be000}, + {0x444c0000}, {0x444c2000}, {0x444c4000}, {0x444c6000}, + {0x444c8000}, {0x444ca000}, {0x444cc000}, {0x444ce000}, + {0x444d0000}, {0x444d2000}, {0x444d4000}, {0x444d6000}, + {0x444d8000}, {0x444da000}, {0x444dc000}, {0x444de000}, + {0x444e0000}, {0x444e2000}, {0x444e4000}, {0x444e6000}, + {0x444e8000}, {0x444ea000}, {0x444ec000}, {0x444ee000}, + {0x444f0000}, {0x444f2000}, {0x444f4000}, {0x444f6000}, + {0x444f8000}, {0x444fa000}, {0x444fc000}, {0x444fe000}, + {0x44500000}, {0x44502000}, {0x44504000}, {0x44506000}, + {0x44508000}, {0x4450a000}, {0x4450c000}, {0x4450e000}, + {0x44510000}, {0x44512000}, {0x44514000}, {0x44516000}, + {0x44518000}, {0x4451a000}, {0x4451c000}, {0x4451e000}, + {0x44520000}, {0x44522000}, {0x44524000}, {0x44526000}, + {0x44528000}, {0x4452a000}, {0x4452c000}, {0x4452e000}, + {0x44530000}, {0x44532000}, {0x44534000}, {0x44536000}, + {0x44538000}, {0x4453a000}, {0x4453c000}, {0x4453e000}, + {0x44540000}, {0x44542000}, {0x44544000}, {0x44546000}, + {0x44548000}, {0x4454a000}, {0x4454c000}, {0x4454e000}, + {0x44550000}, {0x44552000}, {0x44554000}, {0x44556000}, + {0x44558000}, {0x4455a000}, {0x4455c000}, {0x4455e000}, + {0x44560000}, {0x44562000}, {0x44564000}, {0x44566000}, + {0x44568000}, {0x4456a000}, {0x4456c000}, {0x4456e000}, + {0x44570000}, {0x44572000}, {0x44574000}, {0x44576000}, + {0x44578000}, {0x4457a000}, {0x4457c000}, {0x4457e000}, + {0x44580000}, {0x44582000}, {0x44584000}, {0x44586000}, + {0x44588000}, {0x4458a000}, {0x4458c000}, {0x4458e000}, + {0x44590000}, {0x44592000}, {0x44594000}, {0x44596000}, + {0x44598000}, {0x4459a000}, {0x4459c000}, {0x4459e000}, + {0x445a0000}, {0x445a2000}, {0x445a4000}, {0x445a6000}, + {0x445a8000}, {0x445aa000}, {0x445ac000}, {0x445ae000}, + {0x445b0000}, {0x445b2000}, {0x445b4000}, {0x445b6000}, + {0x445b8000}, {0x445ba000}, {0x445bc000}, {0x445be000}, + {0x445c0000}, {0x445c2000}, {0x445c4000}, {0x445c6000}, + {0x445c8000}, {0x445ca000}, {0x445cc000}, {0x445ce000}, + {0x445d0000}, {0x445d2000}, {0x445d4000}, {0x445d6000}, + {0x445d8000}, {0x445da000}, {0x445dc000}, {0x445de000}, + {0x445e0000}, {0x445e2000}, {0x445e4000}, {0x445e6000}, + {0x445e8000}, {0x445ea000}, {0x445ec000}, {0x445ee000}, + {0x445f0000}, {0x445f2000}, {0x445f4000}, {0x445f6000}, + {0x445f8000}, {0x445fa000}, {0x445fc000}, {0x445fe000}, + {0x44600000}, {0x44602000}, {0x44604000}, {0x44606000}, + {0x44608000}, {0x4460a000}, {0x4460c000}, {0x4460e000}, + {0x44610000}, {0x44612000}, {0x44614000}, {0x44616000}, + {0x44618000}, {0x4461a000}, {0x4461c000}, {0x4461e000}, + {0x44620000}, {0x44622000}, {0x44624000}, {0x44626000}, + {0x44628000}, {0x4462a000}, {0x4462c000}, {0x4462e000}, + {0x44630000}, {0x44632000}, {0x44634000}, {0x44636000}, + {0x44638000}, {0x4463a000}, {0x4463c000}, {0x4463e000}, + {0x44640000}, {0x44642000}, {0x44644000}, {0x44646000}, + {0x44648000}, {0x4464a000}, {0x4464c000}, {0x4464e000}, + {0x44650000}, {0x44652000}, {0x44654000}, {0x44656000}, + {0x44658000}, {0x4465a000}, {0x4465c000}, {0x4465e000}, + {0x44660000}, {0x44662000}, {0x44664000}, {0x44666000}, + {0x44668000}, {0x4466a000}, {0x4466c000}, {0x4466e000}, + {0x44670000}, {0x44672000}, {0x44674000}, {0x44676000}, + {0x44678000}, {0x4467a000}, {0x4467c000}, {0x4467e000}, + {0x44680000}, {0x44682000}, {0x44684000}, {0x44686000}, + {0x44688000}, {0x4468a000}, {0x4468c000}, {0x4468e000}, + {0x44690000}, {0x44692000}, {0x44694000}, {0x44696000}, + {0x44698000}, {0x4469a000}, {0x4469c000}, {0x4469e000}, + {0x446a0000}, {0x446a2000}, {0x446a4000}, {0x446a6000}, + {0x446a8000}, {0x446aa000}, {0x446ac000}, {0x446ae000}, + {0x446b0000}, {0x446b2000}, {0x446b4000}, {0x446b6000}, + {0x446b8000}, {0x446ba000}, {0x446bc000}, {0x446be000}, + {0x446c0000}, {0x446c2000}, {0x446c4000}, {0x446c6000}, + {0x446c8000}, {0x446ca000}, {0x446cc000}, {0x446ce000}, + {0x446d0000}, {0x446d2000}, {0x446d4000}, {0x446d6000}, + {0x446d8000}, {0x446da000}, {0x446dc000}, {0x446de000}, + {0x446e0000}, {0x446e2000}, {0x446e4000}, {0x446e6000}, + {0x446e8000}, {0x446ea000}, {0x446ec000}, {0x446ee000}, + {0x446f0000}, {0x446f2000}, {0x446f4000}, {0x446f6000}, + {0x446f8000}, {0x446fa000}, {0x446fc000}, {0x446fe000}, + {0x44700000}, {0x44702000}, {0x44704000}, {0x44706000}, + {0x44708000}, {0x4470a000}, {0x4470c000}, {0x4470e000}, + {0x44710000}, {0x44712000}, {0x44714000}, {0x44716000}, + {0x44718000}, {0x4471a000}, {0x4471c000}, {0x4471e000}, + {0x44720000}, {0x44722000}, {0x44724000}, {0x44726000}, + {0x44728000}, {0x4472a000}, {0x4472c000}, {0x4472e000}, + {0x44730000}, {0x44732000}, {0x44734000}, {0x44736000}, + {0x44738000}, {0x4473a000}, {0x4473c000}, {0x4473e000}, + {0x44740000}, {0x44742000}, {0x44744000}, {0x44746000}, + {0x44748000}, {0x4474a000}, {0x4474c000}, {0x4474e000}, + {0x44750000}, {0x44752000}, {0x44754000}, {0x44756000}, + {0x44758000}, {0x4475a000}, {0x4475c000}, {0x4475e000}, + {0x44760000}, {0x44762000}, {0x44764000}, {0x44766000}, + {0x44768000}, {0x4476a000}, {0x4476c000}, {0x4476e000}, + {0x44770000}, {0x44772000}, {0x44774000}, {0x44776000}, + {0x44778000}, {0x4477a000}, {0x4477c000}, {0x4477e000}, + {0x44780000}, {0x44782000}, {0x44784000}, {0x44786000}, + {0x44788000}, {0x4478a000}, {0x4478c000}, {0x4478e000}, + {0x44790000}, {0x44792000}, {0x44794000}, {0x44796000}, + {0x44798000}, {0x4479a000}, {0x4479c000}, {0x4479e000}, + {0x447a0000}, {0x447a2000}, {0x447a4000}, {0x447a6000}, + {0x447a8000}, {0x447aa000}, {0x447ac000}, {0x447ae000}, + {0x447b0000}, {0x447b2000}, {0x447b4000}, {0x447b6000}, + {0x447b8000}, {0x447ba000}, {0x447bc000}, {0x447be000}, + {0x447c0000}, {0x447c2000}, {0x447c4000}, {0x447c6000}, + {0x447c8000}, {0x447ca000}, {0x447cc000}, {0x447ce000}, + {0x447d0000}, {0x447d2000}, {0x447d4000}, {0x447d6000}, + {0x447d8000}, {0x447da000}, {0x447dc000}, {0x447de000}, + {0x447e0000}, {0x447e2000}, {0x447e4000}, {0x447e6000}, + {0x447e8000}, {0x447ea000}, {0x447ec000}, {0x447ee000}, + {0x447f0000}, {0x447f2000}, {0x447f4000}, {0x447f6000}, + {0x447f8000}, {0x447fa000}, {0x447fc000}, {0x447fe000}, + {0x44800000}, {0x44802000}, {0x44804000}, {0x44806000}, + {0x44808000}, {0x4480a000}, {0x4480c000}, {0x4480e000}, + {0x44810000}, {0x44812000}, {0x44814000}, {0x44816000}, + {0x44818000}, {0x4481a000}, {0x4481c000}, {0x4481e000}, + {0x44820000}, {0x44822000}, {0x44824000}, {0x44826000}, + {0x44828000}, {0x4482a000}, {0x4482c000}, {0x4482e000}, + {0x44830000}, {0x44832000}, {0x44834000}, {0x44836000}, + {0x44838000}, {0x4483a000}, {0x4483c000}, {0x4483e000}, + {0x44840000}, {0x44842000}, {0x44844000}, {0x44846000}, + {0x44848000}, {0x4484a000}, {0x4484c000}, {0x4484e000}, + {0x44850000}, {0x44852000}, {0x44854000}, {0x44856000}, + {0x44858000}, {0x4485a000}, {0x4485c000}, {0x4485e000}, + {0x44860000}, {0x44862000}, {0x44864000}, {0x44866000}, + {0x44868000}, {0x4486a000}, {0x4486c000}, {0x4486e000}, + {0x44870000}, {0x44872000}, {0x44874000}, {0x44876000}, + {0x44878000}, {0x4487a000}, {0x4487c000}, {0x4487e000}, + {0x44880000}, {0x44882000}, {0x44884000}, {0x44886000}, + {0x44888000}, {0x4488a000}, {0x4488c000}, {0x4488e000}, + {0x44890000}, {0x44892000}, {0x44894000}, {0x44896000}, + {0x44898000}, {0x4489a000}, {0x4489c000}, {0x4489e000}, + {0x448a0000}, {0x448a2000}, {0x448a4000}, {0x448a6000}, + {0x448a8000}, {0x448aa000}, {0x448ac000}, {0x448ae000}, + {0x448b0000}, {0x448b2000}, {0x448b4000}, {0x448b6000}, + {0x448b8000}, {0x448ba000}, {0x448bc000}, {0x448be000}, + {0x448c0000}, {0x448c2000}, {0x448c4000}, {0x448c6000}, + {0x448c8000}, {0x448ca000}, {0x448cc000}, {0x448ce000}, + {0x448d0000}, {0x448d2000}, {0x448d4000}, {0x448d6000}, + {0x448d8000}, {0x448da000}, {0x448dc000}, {0x448de000}, + {0x448e0000}, {0x448e2000}, {0x448e4000}, {0x448e6000}, + {0x448e8000}, {0x448ea000}, {0x448ec000}, {0x448ee000}, + {0x448f0000}, {0x448f2000}, {0x448f4000}, {0x448f6000}, + {0x448f8000}, {0x448fa000}, {0x448fc000}, {0x448fe000}, + {0x44900000}, {0x44902000}, {0x44904000}, {0x44906000}, + {0x44908000}, {0x4490a000}, {0x4490c000}, {0x4490e000}, + {0x44910000}, {0x44912000}, {0x44914000}, {0x44916000}, + {0x44918000}, {0x4491a000}, {0x4491c000}, {0x4491e000}, + {0x44920000}, {0x44922000}, {0x44924000}, {0x44926000}, + {0x44928000}, {0x4492a000}, {0x4492c000}, {0x4492e000}, + {0x44930000}, {0x44932000}, {0x44934000}, {0x44936000}, + {0x44938000}, {0x4493a000}, {0x4493c000}, {0x4493e000}, + {0x44940000}, {0x44942000}, {0x44944000}, {0x44946000}, + {0x44948000}, {0x4494a000}, {0x4494c000}, {0x4494e000}, + {0x44950000}, {0x44952000}, {0x44954000}, {0x44956000}, + {0x44958000}, {0x4495a000}, {0x4495c000}, {0x4495e000}, + {0x44960000}, {0x44962000}, {0x44964000}, {0x44966000}, + {0x44968000}, {0x4496a000}, {0x4496c000}, {0x4496e000}, + {0x44970000}, {0x44972000}, {0x44974000}, {0x44976000}, + {0x44978000}, {0x4497a000}, {0x4497c000}, {0x4497e000}, + {0x44980000}, {0x44982000}, {0x44984000}, {0x44986000}, + {0x44988000}, {0x4498a000}, {0x4498c000}, {0x4498e000}, + {0x44990000}, {0x44992000}, {0x44994000}, {0x44996000}, + {0x44998000}, {0x4499a000}, {0x4499c000}, {0x4499e000}, + {0x449a0000}, {0x449a2000}, {0x449a4000}, {0x449a6000}, + {0x449a8000}, {0x449aa000}, {0x449ac000}, {0x449ae000}, + {0x449b0000}, {0x449b2000}, {0x449b4000}, {0x449b6000}, + {0x449b8000}, {0x449ba000}, {0x449bc000}, {0x449be000}, + {0x449c0000}, {0x449c2000}, {0x449c4000}, {0x449c6000}, + {0x449c8000}, {0x449ca000}, {0x449cc000}, {0x449ce000}, + {0x449d0000}, {0x449d2000}, {0x449d4000}, {0x449d6000}, + {0x449d8000}, {0x449da000}, {0x449dc000}, {0x449de000}, + {0x449e0000}, {0x449e2000}, {0x449e4000}, {0x449e6000}, + {0x449e8000}, {0x449ea000}, {0x449ec000}, {0x449ee000}, + {0x449f0000}, {0x449f2000}, {0x449f4000}, {0x449f6000}, + {0x449f8000}, {0x449fa000}, {0x449fc000}, {0x449fe000}, + {0x44a00000}, {0x44a02000}, {0x44a04000}, {0x44a06000}, + {0x44a08000}, {0x44a0a000}, {0x44a0c000}, {0x44a0e000}, + {0x44a10000}, {0x44a12000}, {0x44a14000}, {0x44a16000}, + {0x44a18000}, {0x44a1a000}, {0x44a1c000}, {0x44a1e000}, + {0x44a20000}, {0x44a22000}, {0x44a24000}, {0x44a26000}, + {0x44a28000}, {0x44a2a000}, {0x44a2c000}, {0x44a2e000}, + {0x44a30000}, {0x44a32000}, {0x44a34000}, {0x44a36000}, + {0x44a38000}, {0x44a3a000}, {0x44a3c000}, {0x44a3e000}, + {0x44a40000}, {0x44a42000}, {0x44a44000}, {0x44a46000}, + {0x44a48000}, {0x44a4a000}, {0x44a4c000}, {0x44a4e000}, + {0x44a50000}, {0x44a52000}, {0x44a54000}, {0x44a56000}, + {0x44a58000}, {0x44a5a000}, {0x44a5c000}, {0x44a5e000}, + {0x44a60000}, {0x44a62000}, {0x44a64000}, {0x44a66000}, + {0x44a68000}, {0x44a6a000}, {0x44a6c000}, {0x44a6e000}, + {0x44a70000}, {0x44a72000}, {0x44a74000}, {0x44a76000}, + {0x44a78000}, {0x44a7a000}, {0x44a7c000}, {0x44a7e000}, + {0x44a80000}, {0x44a82000}, {0x44a84000}, {0x44a86000}, + {0x44a88000}, {0x44a8a000}, {0x44a8c000}, {0x44a8e000}, + {0x44a90000}, {0x44a92000}, {0x44a94000}, {0x44a96000}, + {0x44a98000}, {0x44a9a000}, {0x44a9c000}, {0x44a9e000}, + {0x44aa0000}, {0x44aa2000}, {0x44aa4000}, {0x44aa6000}, + {0x44aa8000}, {0x44aaa000}, {0x44aac000}, {0x44aae000}, + {0x44ab0000}, {0x44ab2000}, {0x44ab4000}, {0x44ab6000}, + {0x44ab8000}, {0x44aba000}, {0x44abc000}, {0x44abe000}, + {0x44ac0000}, {0x44ac2000}, {0x44ac4000}, {0x44ac6000}, + {0x44ac8000}, {0x44aca000}, {0x44acc000}, {0x44ace000}, + {0x44ad0000}, {0x44ad2000}, {0x44ad4000}, {0x44ad6000}, + {0x44ad8000}, {0x44ada000}, {0x44adc000}, {0x44ade000}, + {0x44ae0000}, {0x44ae2000}, {0x44ae4000}, {0x44ae6000}, + {0x44ae8000}, {0x44aea000}, {0x44aec000}, {0x44aee000}, + {0x44af0000}, {0x44af2000}, {0x44af4000}, {0x44af6000}, + {0x44af8000}, {0x44afa000}, {0x44afc000}, {0x44afe000}, + {0x44b00000}, {0x44b02000}, {0x44b04000}, {0x44b06000}, + {0x44b08000}, {0x44b0a000}, {0x44b0c000}, {0x44b0e000}, + {0x44b10000}, {0x44b12000}, {0x44b14000}, {0x44b16000}, + {0x44b18000}, {0x44b1a000}, {0x44b1c000}, {0x44b1e000}, + {0x44b20000}, {0x44b22000}, {0x44b24000}, {0x44b26000}, + {0x44b28000}, {0x44b2a000}, {0x44b2c000}, {0x44b2e000}, + {0x44b30000}, {0x44b32000}, {0x44b34000}, {0x44b36000}, + {0x44b38000}, {0x44b3a000}, {0x44b3c000}, {0x44b3e000}, + {0x44b40000}, {0x44b42000}, {0x44b44000}, {0x44b46000}, + {0x44b48000}, {0x44b4a000}, {0x44b4c000}, {0x44b4e000}, + {0x44b50000}, {0x44b52000}, {0x44b54000}, {0x44b56000}, + {0x44b58000}, {0x44b5a000}, {0x44b5c000}, {0x44b5e000}, + {0x44b60000}, {0x44b62000}, {0x44b64000}, {0x44b66000}, + {0x44b68000}, {0x44b6a000}, {0x44b6c000}, {0x44b6e000}, + {0x44b70000}, {0x44b72000}, {0x44b74000}, {0x44b76000}, + {0x44b78000}, {0x44b7a000}, {0x44b7c000}, {0x44b7e000}, + {0x44b80000}, {0x44b82000}, {0x44b84000}, {0x44b86000}, + {0x44b88000}, {0x44b8a000}, {0x44b8c000}, {0x44b8e000}, + {0x44b90000}, {0x44b92000}, {0x44b94000}, {0x44b96000}, + {0x44b98000}, {0x44b9a000}, {0x44b9c000}, {0x44b9e000}, + {0x44ba0000}, {0x44ba2000}, {0x44ba4000}, {0x44ba6000}, + {0x44ba8000}, {0x44baa000}, {0x44bac000}, {0x44bae000}, + {0x44bb0000}, {0x44bb2000}, {0x44bb4000}, {0x44bb6000}, + {0x44bb8000}, {0x44bba000}, {0x44bbc000}, {0x44bbe000}, + {0x44bc0000}, {0x44bc2000}, {0x44bc4000}, {0x44bc6000}, + {0x44bc8000}, {0x44bca000}, {0x44bcc000}, {0x44bce000}, + {0x44bd0000}, {0x44bd2000}, {0x44bd4000}, {0x44bd6000}, + {0x44bd8000}, {0x44bda000}, {0x44bdc000}, {0x44bde000}, + {0x44be0000}, {0x44be2000}, {0x44be4000}, {0x44be6000}, + {0x44be8000}, {0x44bea000}, {0x44bec000}, {0x44bee000}, + {0x44bf0000}, {0x44bf2000}, {0x44bf4000}, {0x44bf6000}, + {0x44bf8000}, {0x44bfa000}, {0x44bfc000}, {0x44bfe000}, + {0x44c00000}, {0x44c02000}, {0x44c04000}, {0x44c06000}, + {0x44c08000}, {0x44c0a000}, {0x44c0c000}, {0x44c0e000}, + {0x44c10000}, {0x44c12000}, {0x44c14000}, {0x44c16000}, + {0x44c18000}, {0x44c1a000}, {0x44c1c000}, {0x44c1e000}, + {0x44c20000}, {0x44c22000}, {0x44c24000}, {0x44c26000}, + {0x44c28000}, {0x44c2a000}, {0x44c2c000}, {0x44c2e000}, + {0x44c30000}, {0x44c32000}, {0x44c34000}, {0x44c36000}, + {0x44c38000}, {0x44c3a000}, {0x44c3c000}, {0x44c3e000}, + {0x44c40000}, {0x44c42000}, {0x44c44000}, {0x44c46000}, + {0x44c48000}, {0x44c4a000}, {0x44c4c000}, {0x44c4e000}, + {0x44c50000}, {0x44c52000}, {0x44c54000}, {0x44c56000}, + {0x44c58000}, {0x44c5a000}, {0x44c5c000}, {0x44c5e000}, + {0x44c60000}, {0x44c62000}, {0x44c64000}, {0x44c66000}, + {0x44c68000}, {0x44c6a000}, {0x44c6c000}, {0x44c6e000}, + {0x44c70000}, {0x44c72000}, {0x44c74000}, {0x44c76000}, + {0x44c78000}, {0x44c7a000}, {0x44c7c000}, {0x44c7e000}, + {0x44c80000}, {0x44c82000}, {0x44c84000}, {0x44c86000}, + {0x44c88000}, {0x44c8a000}, {0x44c8c000}, {0x44c8e000}, + {0x44c90000}, {0x44c92000}, {0x44c94000}, {0x44c96000}, + {0x44c98000}, {0x44c9a000}, {0x44c9c000}, {0x44c9e000}, + {0x44ca0000}, {0x44ca2000}, {0x44ca4000}, {0x44ca6000}, + {0x44ca8000}, {0x44caa000}, {0x44cac000}, {0x44cae000}, + {0x44cb0000}, {0x44cb2000}, {0x44cb4000}, {0x44cb6000}, + {0x44cb8000}, {0x44cba000}, {0x44cbc000}, {0x44cbe000}, + {0x44cc0000}, {0x44cc2000}, {0x44cc4000}, {0x44cc6000}, + {0x44cc8000}, {0x44cca000}, {0x44ccc000}, {0x44cce000}, + {0x44cd0000}, {0x44cd2000}, {0x44cd4000}, {0x44cd6000}, + {0x44cd8000}, {0x44cda000}, {0x44cdc000}, {0x44cde000}, + {0x44ce0000}, {0x44ce2000}, {0x44ce4000}, {0x44ce6000}, + {0x44ce8000}, {0x44cea000}, {0x44cec000}, {0x44cee000}, + {0x44cf0000}, {0x44cf2000}, {0x44cf4000}, {0x44cf6000}, + {0x44cf8000}, {0x44cfa000}, {0x44cfc000}, {0x44cfe000}, + {0x44d00000}, {0x44d02000}, {0x44d04000}, {0x44d06000}, + {0x44d08000}, {0x44d0a000}, {0x44d0c000}, {0x44d0e000}, + {0x44d10000}, {0x44d12000}, {0x44d14000}, {0x44d16000}, + {0x44d18000}, {0x44d1a000}, {0x44d1c000}, {0x44d1e000}, + {0x44d20000}, {0x44d22000}, {0x44d24000}, {0x44d26000}, + {0x44d28000}, {0x44d2a000}, {0x44d2c000}, {0x44d2e000}, + {0x44d30000}, {0x44d32000}, {0x44d34000}, {0x44d36000}, + {0x44d38000}, {0x44d3a000}, {0x44d3c000}, {0x44d3e000}, + {0x44d40000}, {0x44d42000}, {0x44d44000}, {0x44d46000}, + {0x44d48000}, {0x44d4a000}, {0x44d4c000}, {0x44d4e000}, + {0x44d50000}, {0x44d52000}, {0x44d54000}, {0x44d56000}, + {0x44d58000}, {0x44d5a000}, {0x44d5c000}, {0x44d5e000}, + {0x44d60000}, {0x44d62000}, {0x44d64000}, {0x44d66000}, + {0x44d68000}, {0x44d6a000}, {0x44d6c000}, {0x44d6e000}, + {0x44d70000}, {0x44d72000}, {0x44d74000}, {0x44d76000}, + {0x44d78000}, {0x44d7a000}, {0x44d7c000}, {0x44d7e000}, + {0x44d80000}, {0x44d82000}, {0x44d84000}, {0x44d86000}, + {0x44d88000}, {0x44d8a000}, {0x44d8c000}, {0x44d8e000}, + {0x44d90000}, {0x44d92000}, {0x44d94000}, {0x44d96000}, + {0x44d98000}, {0x44d9a000}, {0x44d9c000}, {0x44d9e000}, + {0x44da0000}, {0x44da2000}, {0x44da4000}, {0x44da6000}, + {0x44da8000}, {0x44daa000}, {0x44dac000}, {0x44dae000}, + {0x44db0000}, {0x44db2000}, {0x44db4000}, {0x44db6000}, + {0x44db8000}, {0x44dba000}, {0x44dbc000}, {0x44dbe000}, + {0x44dc0000}, {0x44dc2000}, {0x44dc4000}, {0x44dc6000}, + {0x44dc8000}, {0x44dca000}, {0x44dcc000}, {0x44dce000}, + {0x44dd0000}, {0x44dd2000}, {0x44dd4000}, {0x44dd6000}, + {0x44dd8000}, {0x44dda000}, {0x44ddc000}, {0x44dde000}, + {0x44de0000}, {0x44de2000}, {0x44de4000}, {0x44de6000}, + {0x44de8000}, {0x44dea000}, {0x44dec000}, {0x44dee000}, + {0x44df0000}, {0x44df2000}, {0x44df4000}, {0x44df6000}, + {0x44df8000}, {0x44dfa000}, {0x44dfc000}, {0x44dfe000}, + {0x44e00000}, {0x44e02000}, {0x44e04000}, {0x44e06000}, + {0x44e08000}, {0x44e0a000}, {0x44e0c000}, {0x44e0e000}, + {0x44e10000}, {0x44e12000}, {0x44e14000}, {0x44e16000}, + {0x44e18000}, {0x44e1a000}, {0x44e1c000}, {0x44e1e000}, + {0x44e20000}, {0x44e22000}, {0x44e24000}, {0x44e26000}, + {0x44e28000}, {0x44e2a000}, {0x44e2c000}, {0x44e2e000}, + {0x44e30000}, {0x44e32000}, {0x44e34000}, {0x44e36000}, + {0x44e38000}, {0x44e3a000}, {0x44e3c000}, {0x44e3e000}, + {0x44e40000}, {0x44e42000}, {0x44e44000}, {0x44e46000}, + {0x44e48000}, {0x44e4a000}, {0x44e4c000}, {0x44e4e000}, + {0x44e50000}, {0x44e52000}, {0x44e54000}, {0x44e56000}, + {0x44e58000}, {0x44e5a000}, {0x44e5c000}, {0x44e5e000}, + {0x44e60000}, {0x44e62000}, {0x44e64000}, {0x44e66000}, + {0x44e68000}, {0x44e6a000}, {0x44e6c000}, {0x44e6e000}, + {0x44e70000}, {0x44e72000}, {0x44e74000}, {0x44e76000}, + {0x44e78000}, {0x44e7a000}, {0x44e7c000}, {0x44e7e000}, + {0x44e80000}, {0x44e82000}, {0x44e84000}, {0x44e86000}, + {0x44e88000}, {0x44e8a000}, {0x44e8c000}, {0x44e8e000}, + {0x44e90000}, {0x44e92000}, {0x44e94000}, {0x44e96000}, + {0x44e98000}, {0x44e9a000}, {0x44e9c000}, {0x44e9e000}, + {0x44ea0000}, {0x44ea2000}, {0x44ea4000}, {0x44ea6000}, + {0x44ea8000}, {0x44eaa000}, {0x44eac000}, {0x44eae000}, + {0x44eb0000}, {0x44eb2000}, {0x44eb4000}, {0x44eb6000}, + {0x44eb8000}, {0x44eba000}, {0x44ebc000}, {0x44ebe000}, + {0x44ec0000}, {0x44ec2000}, {0x44ec4000}, {0x44ec6000}, + {0x44ec8000}, {0x44eca000}, {0x44ecc000}, {0x44ece000}, + {0x44ed0000}, {0x44ed2000}, {0x44ed4000}, {0x44ed6000}, + {0x44ed8000}, {0x44eda000}, {0x44edc000}, {0x44ede000}, + {0x44ee0000}, {0x44ee2000}, {0x44ee4000}, {0x44ee6000}, + {0x44ee8000}, {0x44eea000}, {0x44eec000}, {0x44eee000}, + {0x44ef0000}, {0x44ef2000}, {0x44ef4000}, {0x44ef6000}, + {0x44ef8000}, {0x44efa000}, {0x44efc000}, {0x44efe000}, + {0x44f00000}, {0x44f02000}, {0x44f04000}, {0x44f06000}, + {0x44f08000}, {0x44f0a000}, {0x44f0c000}, {0x44f0e000}, + {0x44f10000}, {0x44f12000}, {0x44f14000}, {0x44f16000}, + {0x44f18000}, {0x44f1a000}, {0x44f1c000}, {0x44f1e000}, + {0x44f20000}, {0x44f22000}, {0x44f24000}, {0x44f26000}, + {0x44f28000}, {0x44f2a000}, {0x44f2c000}, {0x44f2e000}, + {0x44f30000}, {0x44f32000}, {0x44f34000}, {0x44f36000}, + {0x44f38000}, {0x44f3a000}, {0x44f3c000}, {0x44f3e000}, + {0x44f40000}, {0x44f42000}, {0x44f44000}, {0x44f46000}, + {0x44f48000}, {0x44f4a000}, {0x44f4c000}, {0x44f4e000}, + {0x44f50000}, {0x44f52000}, {0x44f54000}, {0x44f56000}, + {0x44f58000}, {0x44f5a000}, {0x44f5c000}, {0x44f5e000}, + {0x44f60000}, {0x44f62000}, {0x44f64000}, {0x44f66000}, + {0x44f68000}, {0x44f6a000}, {0x44f6c000}, {0x44f6e000}, + {0x44f70000}, {0x44f72000}, {0x44f74000}, {0x44f76000}, + {0x44f78000}, {0x44f7a000}, {0x44f7c000}, {0x44f7e000}, + {0x44f80000}, {0x44f82000}, {0x44f84000}, {0x44f86000}, + {0x44f88000}, {0x44f8a000}, {0x44f8c000}, {0x44f8e000}, + {0x44f90000}, {0x44f92000}, {0x44f94000}, {0x44f96000}, + {0x44f98000}, {0x44f9a000}, {0x44f9c000}, {0x44f9e000}, + {0x44fa0000}, {0x44fa2000}, {0x44fa4000}, {0x44fa6000}, + {0x44fa8000}, {0x44faa000}, {0x44fac000}, {0x44fae000}, + {0x44fb0000}, {0x44fb2000}, {0x44fb4000}, {0x44fb6000}, + {0x44fb8000}, {0x44fba000}, {0x44fbc000}, {0x44fbe000}, + {0x44fc0000}, {0x44fc2000}, {0x44fc4000}, {0x44fc6000}, + {0x44fc8000}, {0x44fca000}, {0x44fcc000}, {0x44fce000}, + {0x44fd0000}, {0x44fd2000}, {0x44fd4000}, {0x44fd6000}, + {0x44fd8000}, {0x44fda000}, {0x44fdc000}, {0x44fde000}, + {0x44fe0000}, {0x44fe2000}, {0x44fe4000}, {0x44fe6000}, + {0x44fe8000}, {0x44fea000}, {0x44fec000}, {0x44fee000}, + {0x44ff0000}, {0x44ff2000}, {0x44ff4000}, {0x44ff6000}, + {0x44ff8000}, {0x44ffa000}, {0x44ffc000}, {0x44ffe000}, + {0x45000000}, {0x45002000}, {0x45004000}, {0x45006000}, + {0x45008000}, {0x4500a000}, {0x4500c000}, {0x4500e000}, + {0x45010000}, {0x45012000}, {0x45014000}, {0x45016000}, + {0x45018000}, {0x4501a000}, {0x4501c000}, {0x4501e000}, + {0x45020000}, {0x45022000}, {0x45024000}, {0x45026000}, + {0x45028000}, {0x4502a000}, {0x4502c000}, {0x4502e000}, + {0x45030000}, {0x45032000}, {0x45034000}, {0x45036000}, + {0x45038000}, {0x4503a000}, {0x4503c000}, {0x4503e000}, + {0x45040000}, {0x45042000}, {0x45044000}, {0x45046000}, + {0x45048000}, {0x4504a000}, {0x4504c000}, {0x4504e000}, + {0x45050000}, {0x45052000}, {0x45054000}, {0x45056000}, + {0x45058000}, {0x4505a000}, {0x4505c000}, {0x4505e000}, + {0x45060000}, {0x45062000}, {0x45064000}, {0x45066000}, + {0x45068000}, {0x4506a000}, {0x4506c000}, {0x4506e000}, + {0x45070000}, {0x45072000}, {0x45074000}, {0x45076000}, + {0x45078000}, {0x4507a000}, {0x4507c000}, {0x4507e000}, + {0x45080000}, {0x45082000}, {0x45084000}, {0x45086000}, + {0x45088000}, {0x4508a000}, {0x4508c000}, {0x4508e000}, + {0x45090000}, {0x45092000}, {0x45094000}, {0x45096000}, + {0x45098000}, {0x4509a000}, {0x4509c000}, {0x4509e000}, + {0x450a0000}, {0x450a2000}, {0x450a4000}, {0x450a6000}, + {0x450a8000}, {0x450aa000}, {0x450ac000}, {0x450ae000}, + {0x450b0000}, {0x450b2000}, {0x450b4000}, {0x450b6000}, + {0x450b8000}, {0x450ba000}, {0x450bc000}, {0x450be000}, + {0x450c0000}, {0x450c2000}, {0x450c4000}, {0x450c6000}, + {0x450c8000}, {0x450ca000}, {0x450cc000}, {0x450ce000}, + {0x450d0000}, {0x450d2000}, {0x450d4000}, {0x450d6000}, + {0x450d8000}, {0x450da000}, {0x450dc000}, {0x450de000}, + {0x450e0000}, {0x450e2000}, {0x450e4000}, {0x450e6000}, + {0x450e8000}, {0x450ea000}, {0x450ec000}, {0x450ee000}, + {0x450f0000}, {0x450f2000}, {0x450f4000}, {0x450f6000}, + {0x450f8000}, {0x450fa000}, {0x450fc000}, {0x450fe000}, + {0x45100000}, {0x45102000}, {0x45104000}, {0x45106000}, + {0x45108000}, {0x4510a000}, {0x4510c000}, {0x4510e000}, + {0x45110000}, {0x45112000}, {0x45114000}, {0x45116000}, + {0x45118000}, {0x4511a000}, {0x4511c000}, {0x4511e000}, + {0x45120000}, {0x45122000}, {0x45124000}, {0x45126000}, + {0x45128000}, {0x4512a000}, {0x4512c000}, {0x4512e000}, + {0x45130000}, {0x45132000}, {0x45134000}, {0x45136000}, + {0x45138000}, {0x4513a000}, {0x4513c000}, {0x4513e000}, + {0x45140000}, {0x45142000}, {0x45144000}, {0x45146000}, + {0x45148000}, {0x4514a000}, {0x4514c000}, {0x4514e000}, + {0x45150000}, {0x45152000}, {0x45154000}, {0x45156000}, + {0x45158000}, {0x4515a000}, {0x4515c000}, {0x4515e000}, + {0x45160000}, {0x45162000}, {0x45164000}, {0x45166000}, + {0x45168000}, {0x4516a000}, {0x4516c000}, {0x4516e000}, + {0x45170000}, {0x45172000}, {0x45174000}, {0x45176000}, + {0x45178000}, {0x4517a000}, {0x4517c000}, {0x4517e000}, + {0x45180000}, {0x45182000}, {0x45184000}, {0x45186000}, + {0x45188000}, {0x4518a000}, {0x4518c000}, {0x4518e000}, + {0x45190000}, {0x45192000}, {0x45194000}, {0x45196000}, + {0x45198000}, {0x4519a000}, {0x4519c000}, {0x4519e000}, + {0x451a0000}, {0x451a2000}, {0x451a4000}, {0x451a6000}, + {0x451a8000}, {0x451aa000}, {0x451ac000}, {0x451ae000}, + {0x451b0000}, {0x451b2000}, {0x451b4000}, {0x451b6000}, + {0x451b8000}, {0x451ba000}, {0x451bc000}, {0x451be000}, + {0x451c0000}, {0x451c2000}, {0x451c4000}, {0x451c6000}, + {0x451c8000}, {0x451ca000}, {0x451cc000}, {0x451ce000}, + {0x451d0000}, {0x451d2000}, {0x451d4000}, {0x451d6000}, + {0x451d8000}, {0x451da000}, {0x451dc000}, {0x451de000}, + {0x451e0000}, {0x451e2000}, {0x451e4000}, {0x451e6000}, + {0x451e8000}, {0x451ea000}, {0x451ec000}, {0x451ee000}, + {0x451f0000}, {0x451f2000}, {0x451f4000}, {0x451f6000}, + {0x451f8000}, {0x451fa000}, {0x451fc000}, {0x451fe000}, + {0x45200000}, {0x45202000}, {0x45204000}, {0x45206000}, + {0x45208000}, {0x4520a000}, {0x4520c000}, {0x4520e000}, + {0x45210000}, {0x45212000}, {0x45214000}, {0x45216000}, + {0x45218000}, {0x4521a000}, {0x4521c000}, {0x4521e000}, + {0x45220000}, {0x45222000}, {0x45224000}, {0x45226000}, + {0x45228000}, {0x4522a000}, {0x4522c000}, {0x4522e000}, + {0x45230000}, {0x45232000}, {0x45234000}, {0x45236000}, + {0x45238000}, {0x4523a000}, {0x4523c000}, {0x4523e000}, + {0x45240000}, {0x45242000}, {0x45244000}, {0x45246000}, + {0x45248000}, {0x4524a000}, {0x4524c000}, {0x4524e000}, + {0x45250000}, {0x45252000}, {0x45254000}, {0x45256000}, + {0x45258000}, {0x4525a000}, {0x4525c000}, {0x4525e000}, + {0x45260000}, {0x45262000}, {0x45264000}, {0x45266000}, + {0x45268000}, {0x4526a000}, {0x4526c000}, {0x4526e000}, + {0x45270000}, {0x45272000}, {0x45274000}, {0x45276000}, + {0x45278000}, {0x4527a000}, {0x4527c000}, {0x4527e000}, + {0x45280000}, {0x45282000}, {0x45284000}, {0x45286000}, + {0x45288000}, {0x4528a000}, {0x4528c000}, {0x4528e000}, + {0x45290000}, {0x45292000}, {0x45294000}, {0x45296000}, + {0x45298000}, {0x4529a000}, {0x4529c000}, {0x4529e000}, + {0x452a0000}, {0x452a2000}, {0x452a4000}, {0x452a6000}, + {0x452a8000}, {0x452aa000}, {0x452ac000}, {0x452ae000}, + {0x452b0000}, {0x452b2000}, {0x452b4000}, {0x452b6000}, + {0x452b8000}, {0x452ba000}, {0x452bc000}, {0x452be000}, + {0x452c0000}, {0x452c2000}, {0x452c4000}, {0x452c6000}, + {0x452c8000}, {0x452ca000}, {0x452cc000}, {0x452ce000}, + {0x452d0000}, {0x452d2000}, {0x452d4000}, {0x452d6000}, + {0x452d8000}, {0x452da000}, {0x452dc000}, {0x452de000}, + {0x452e0000}, {0x452e2000}, {0x452e4000}, {0x452e6000}, + {0x452e8000}, {0x452ea000}, {0x452ec000}, {0x452ee000}, + {0x452f0000}, {0x452f2000}, {0x452f4000}, {0x452f6000}, + {0x452f8000}, {0x452fa000}, {0x452fc000}, {0x452fe000}, + {0x45300000}, {0x45302000}, {0x45304000}, {0x45306000}, + {0x45308000}, {0x4530a000}, {0x4530c000}, {0x4530e000}, + {0x45310000}, {0x45312000}, {0x45314000}, {0x45316000}, + {0x45318000}, {0x4531a000}, {0x4531c000}, {0x4531e000}, + {0x45320000}, {0x45322000}, {0x45324000}, {0x45326000}, + {0x45328000}, {0x4532a000}, {0x4532c000}, {0x4532e000}, + {0x45330000}, {0x45332000}, {0x45334000}, {0x45336000}, + {0x45338000}, {0x4533a000}, {0x4533c000}, {0x4533e000}, + {0x45340000}, {0x45342000}, {0x45344000}, {0x45346000}, + {0x45348000}, {0x4534a000}, {0x4534c000}, {0x4534e000}, + {0x45350000}, {0x45352000}, {0x45354000}, {0x45356000}, + {0x45358000}, {0x4535a000}, {0x4535c000}, {0x4535e000}, + {0x45360000}, {0x45362000}, {0x45364000}, {0x45366000}, + {0x45368000}, {0x4536a000}, {0x4536c000}, {0x4536e000}, + {0x45370000}, {0x45372000}, {0x45374000}, {0x45376000}, + {0x45378000}, {0x4537a000}, {0x4537c000}, {0x4537e000}, + {0x45380000}, {0x45382000}, {0x45384000}, {0x45386000}, + {0x45388000}, {0x4538a000}, {0x4538c000}, {0x4538e000}, + {0x45390000}, {0x45392000}, {0x45394000}, {0x45396000}, + {0x45398000}, {0x4539a000}, {0x4539c000}, {0x4539e000}, + {0x453a0000}, {0x453a2000}, {0x453a4000}, {0x453a6000}, + {0x453a8000}, {0x453aa000}, {0x453ac000}, {0x453ae000}, + {0x453b0000}, {0x453b2000}, {0x453b4000}, {0x453b6000}, + {0x453b8000}, {0x453ba000}, {0x453bc000}, {0x453be000}, + {0x453c0000}, {0x453c2000}, {0x453c4000}, {0x453c6000}, + {0x453c8000}, {0x453ca000}, {0x453cc000}, {0x453ce000}, + {0x453d0000}, {0x453d2000}, {0x453d4000}, {0x453d6000}, + {0x453d8000}, {0x453da000}, {0x453dc000}, {0x453de000}, + {0x453e0000}, {0x453e2000}, {0x453e4000}, {0x453e6000}, + {0x453e8000}, {0x453ea000}, {0x453ec000}, {0x453ee000}, + {0x453f0000}, {0x453f2000}, {0x453f4000}, {0x453f6000}, + {0x453f8000}, {0x453fa000}, {0x453fc000}, {0x453fe000}, + {0x45400000}, {0x45402000}, {0x45404000}, {0x45406000}, + {0x45408000}, {0x4540a000}, {0x4540c000}, {0x4540e000}, + {0x45410000}, {0x45412000}, {0x45414000}, {0x45416000}, + {0x45418000}, {0x4541a000}, {0x4541c000}, {0x4541e000}, + {0x45420000}, {0x45422000}, {0x45424000}, {0x45426000}, + {0x45428000}, {0x4542a000}, {0x4542c000}, {0x4542e000}, + {0x45430000}, {0x45432000}, {0x45434000}, {0x45436000}, + {0x45438000}, {0x4543a000}, {0x4543c000}, {0x4543e000}, + {0x45440000}, {0x45442000}, {0x45444000}, {0x45446000}, + {0x45448000}, {0x4544a000}, {0x4544c000}, {0x4544e000}, + {0x45450000}, {0x45452000}, {0x45454000}, {0x45456000}, + {0x45458000}, {0x4545a000}, {0x4545c000}, {0x4545e000}, + {0x45460000}, {0x45462000}, {0x45464000}, {0x45466000}, + {0x45468000}, {0x4546a000}, {0x4546c000}, {0x4546e000}, + {0x45470000}, {0x45472000}, {0x45474000}, {0x45476000}, + {0x45478000}, {0x4547a000}, {0x4547c000}, {0x4547e000}, + {0x45480000}, {0x45482000}, {0x45484000}, {0x45486000}, + {0x45488000}, {0x4548a000}, {0x4548c000}, {0x4548e000}, + {0x45490000}, {0x45492000}, {0x45494000}, {0x45496000}, + {0x45498000}, {0x4549a000}, {0x4549c000}, {0x4549e000}, + {0x454a0000}, {0x454a2000}, {0x454a4000}, {0x454a6000}, + {0x454a8000}, {0x454aa000}, {0x454ac000}, {0x454ae000}, + {0x454b0000}, {0x454b2000}, {0x454b4000}, {0x454b6000}, + {0x454b8000}, {0x454ba000}, {0x454bc000}, {0x454be000}, + {0x454c0000}, {0x454c2000}, {0x454c4000}, {0x454c6000}, + {0x454c8000}, {0x454ca000}, {0x454cc000}, {0x454ce000}, + {0x454d0000}, {0x454d2000}, {0x454d4000}, {0x454d6000}, + {0x454d8000}, {0x454da000}, {0x454dc000}, {0x454de000}, + {0x454e0000}, {0x454e2000}, {0x454e4000}, {0x454e6000}, + {0x454e8000}, {0x454ea000}, {0x454ec000}, {0x454ee000}, + {0x454f0000}, {0x454f2000}, {0x454f4000}, {0x454f6000}, + {0x454f8000}, {0x454fa000}, {0x454fc000}, {0x454fe000}, + {0x45500000}, {0x45502000}, {0x45504000}, {0x45506000}, + {0x45508000}, {0x4550a000}, {0x4550c000}, {0x4550e000}, + {0x45510000}, {0x45512000}, {0x45514000}, {0x45516000}, + {0x45518000}, {0x4551a000}, {0x4551c000}, {0x4551e000}, + {0x45520000}, {0x45522000}, {0x45524000}, {0x45526000}, + {0x45528000}, {0x4552a000}, {0x4552c000}, {0x4552e000}, + {0x45530000}, {0x45532000}, {0x45534000}, {0x45536000}, + {0x45538000}, {0x4553a000}, {0x4553c000}, {0x4553e000}, + {0x45540000}, {0x45542000}, {0x45544000}, {0x45546000}, + {0x45548000}, {0x4554a000}, {0x4554c000}, {0x4554e000}, + {0x45550000}, {0x45552000}, {0x45554000}, {0x45556000}, + {0x45558000}, {0x4555a000}, {0x4555c000}, {0x4555e000}, + {0x45560000}, {0x45562000}, {0x45564000}, {0x45566000}, + {0x45568000}, {0x4556a000}, {0x4556c000}, {0x4556e000}, + {0x45570000}, {0x45572000}, {0x45574000}, {0x45576000}, + {0x45578000}, {0x4557a000}, {0x4557c000}, {0x4557e000}, + {0x45580000}, {0x45582000}, {0x45584000}, {0x45586000}, + {0x45588000}, {0x4558a000}, {0x4558c000}, {0x4558e000}, + {0x45590000}, {0x45592000}, {0x45594000}, {0x45596000}, + {0x45598000}, {0x4559a000}, {0x4559c000}, {0x4559e000}, + {0x455a0000}, {0x455a2000}, {0x455a4000}, {0x455a6000}, + {0x455a8000}, {0x455aa000}, {0x455ac000}, {0x455ae000}, + {0x455b0000}, {0x455b2000}, {0x455b4000}, {0x455b6000}, + {0x455b8000}, {0x455ba000}, {0x455bc000}, {0x455be000}, + {0x455c0000}, {0x455c2000}, {0x455c4000}, {0x455c6000}, + {0x455c8000}, {0x455ca000}, {0x455cc000}, {0x455ce000}, + {0x455d0000}, {0x455d2000}, {0x455d4000}, {0x455d6000}, + {0x455d8000}, {0x455da000}, {0x455dc000}, {0x455de000}, + {0x455e0000}, {0x455e2000}, {0x455e4000}, {0x455e6000}, + {0x455e8000}, {0x455ea000}, {0x455ec000}, {0x455ee000}, + {0x455f0000}, {0x455f2000}, {0x455f4000}, {0x455f6000}, + {0x455f8000}, {0x455fa000}, {0x455fc000}, {0x455fe000}, + {0x45600000}, {0x45602000}, {0x45604000}, {0x45606000}, + {0x45608000}, {0x4560a000}, {0x4560c000}, {0x4560e000}, + {0x45610000}, {0x45612000}, {0x45614000}, {0x45616000}, + {0x45618000}, {0x4561a000}, {0x4561c000}, {0x4561e000}, + {0x45620000}, {0x45622000}, {0x45624000}, {0x45626000}, + {0x45628000}, {0x4562a000}, {0x4562c000}, {0x4562e000}, + {0x45630000}, {0x45632000}, {0x45634000}, {0x45636000}, + {0x45638000}, {0x4563a000}, {0x4563c000}, {0x4563e000}, + {0x45640000}, {0x45642000}, {0x45644000}, {0x45646000}, + {0x45648000}, {0x4564a000}, {0x4564c000}, {0x4564e000}, + {0x45650000}, {0x45652000}, {0x45654000}, {0x45656000}, + {0x45658000}, {0x4565a000}, {0x4565c000}, {0x4565e000}, + {0x45660000}, {0x45662000}, {0x45664000}, {0x45666000}, + {0x45668000}, {0x4566a000}, {0x4566c000}, {0x4566e000}, + {0x45670000}, {0x45672000}, {0x45674000}, {0x45676000}, + {0x45678000}, {0x4567a000}, {0x4567c000}, {0x4567e000}, + {0x45680000}, {0x45682000}, {0x45684000}, {0x45686000}, + {0x45688000}, {0x4568a000}, {0x4568c000}, {0x4568e000}, + {0x45690000}, {0x45692000}, {0x45694000}, {0x45696000}, + {0x45698000}, {0x4569a000}, {0x4569c000}, {0x4569e000}, + {0x456a0000}, {0x456a2000}, {0x456a4000}, {0x456a6000}, + {0x456a8000}, {0x456aa000}, {0x456ac000}, {0x456ae000}, + {0x456b0000}, {0x456b2000}, {0x456b4000}, {0x456b6000}, + {0x456b8000}, {0x456ba000}, {0x456bc000}, {0x456be000}, + {0x456c0000}, {0x456c2000}, {0x456c4000}, {0x456c6000}, + {0x456c8000}, {0x456ca000}, {0x456cc000}, {0x456ce000}, + {0x456d0000}, {0x456d2000}, {0x456d4000}, {0x456d6000}, + {0x456d8000}, {0x456da000}, {0x456dc000}, {0x456de000}, + {0x456e0000}, {0x456e2000}, {0x456e4000}, {0x456e6000}, + {0x456e8000}, {0x456ea000}, {0x456ec000}, {0x456ee000}, + {0x456f0000}, {0x456f2000}, {0x456f4000}, {0x456f6000}, + {0x456f8000}, {0x456fa000}, {0x456fc000}, {0x456fe000}, + {0x45700000}, {0x45702000}, {0x45704000}, {0x45706000}, + {0x45708000}, {0x4570a000}, {0x4570c000}, {0x4570e000}, + {0x45710000}, {0x45712000}, {0x45714000}, {0x45716000}, + {0x45718000}, {0x4571a000}, {0x4571c000}, {0x4571e000}, + {0x45720000}, {0x45722000}, {0x45724000}, {0x45726000}, + {0x45728000}, {0x4572a000}, {0x4572c000}, {0x4572e000}, + {0x45730000}, {0x45732000}, {0x45734000}, {0x45736000}, + {0x45738000}, {0x4573a000}, {0x4573c000}, {0x4573e000}, + {0x45740000}, {0x45742000}, {0x45744000}, {0x45746000}, + {0x45748000}, {0x4574a000}, {0x4574c000}, {0x4574e000}, + {0x45750000}, {0x45752000}, {0x45754000}, {0x45756000}, + {0x45758000}, {0x4575a000}, {0x4575c000}, {0x4575e000}, + {0x45760000}, {0x45762000}, {0x45764000}, {0x45766000}, + {0x45768000}, {0x4576a000}, {0x4576c000}, {0x4576e000}, + {0x45770000}, {0x45772000}, {0x45774000}, {0x45776000}, + {0x45778000}, {0x4577a000}, {0x4577c000}, {0x4577e000}, + {0x45780000}, {0x45782000}, {0x45784000}, {0x45786000}, + {0x45788000}, {0x4578a000}, {0x4578c000}, {0x4578e000}, + {0x45790000}, {0x45792000}, {0x45794000}, {0x45796000}, + {0x45798000}, {0x4579a000}, {0x4579c000}, {0x4579e000}, + {0x457a0000}, {0x457a2000}, {0x457a4000}, {0x457a6000}, + {0x457a8000}, {0x457aa000}, {0x457ac000}, {0x457ae000}, + {0x457b0000}, {0x457b2000}, {0x457b4000}, {0x457b6000}, + {0x457b8000}, {0x457ba000}, {0x457bc000}, {0x457be000}, + {0x457c0000}, {0x457c2000}, {0x457c4000}, {0x457c6000}, + {0x457c8000}, {0x457ca000}, {0x457cc000}, {0x457ce000}, + {0x457d0000}, {0x457d2000}, {0x457d4000}, {0x457d6000}, + {0x457d8000}, {0x457da000}, {0x457dc000}, {0x457de000}, + {0x457e0000}, {0x457e2000}, {0x457e4000}, {0x457e6000}, + {0x457e8000}, {0x457ea000}, {0x457ec000}, {0x457ee000}, + {0x457f0000}, {0x457f2000}, {0x457f4000}, {0x457f6000}, + {0x457f8000}, {0x457fa000}, {0x457fc000}, {0x457fe000}, + {0x45800000}, {0x45802000}, {0x45804000}, {0x45806000}, + {0x45808000}, {0x4580a000}, {0x4580c000}, {0x4580e000}, + {0x45810000}, {0x45812000}, {0x45814000}, {0x45816000}, + {0x45818000}, {0x4581a000}, {0x4581c000}, {0x4581e000}, + {0x45820000}, {0x45822000}, {0x45824000}, {0x45826000}, + {0x45828000}, {0x4582a000}, {0x4582c000}, {0x4582e000}, + {0x45830000}, {0x45832000}, {0x45834000}, {0x45836000}, + {0x45838000}, {0x4583a000}, {0x4583c000}, {0x4583e000}, + {0x45840000}, {0x45842000}, {0x45844000}, {0x45846000}, + {0x45848000}, {0x4584a000}, {0x4584c000}, {0x4584e000}, + {0x45850000}, {0x45852000}, {0x45854000}, {0x45856000}, + {0x45858000}, {0x4585a000}, {0x4585c000}, {0x4585e000}, + {0x45860000}, {0x45862000}, {0x45864000}, {0x45866000}, + {0x45868000}, {0x4586a000}, {0x4586c000}, {0x4586e000}, + {0x45870000}, {0x45872000}, {0x45874000}, {0x45876000}, + {0x45878000}, {0x4587a000}, {0x4587c000}, {0x4587e000}, + {0x45880000}, {0x45882000}, {0x45884000}, {0x45886000}, + {0x45888000}, {0x4588a000}, {0x4588c000}, {0x4588e000}, + {0x45890000}, {0x45892000}, {0x45894000}, {0x45896000}, + {0x45898000}, {0x4589a000}, {0x4589c000}, {0x4589e000}, + {0x458a0000}, {0x458a2000}, {0x458a4000}, {0x458a6000}, + {0x458a8000}, {0x458aa000}, {0x458ac000}, {0x458ae000}, + {0x458b0000}, {0x458b2000}, {0x458b4000}, {0x458b6000}, + {0x458b8000}, {0x458ba000}, {0x458bc000}, {0x458be000}, + {0x458c0000}, {0x458c2000}, {0x458c4000}, {0x458c6000}, + {0x458c8000}, {0x458ca000}, {0x458cc000}, {0x458ce000}, + {0x458d0000}, {0x458d2000}, {0x458d4000}, {0x458d6000}, + {0x458d8000}, {0x458da000}, {0x458dc000}, {0x458de000}, + {0x458e0000}, {0x458e2000}, {0x458e4000}, {0x458e6000}, + {0x458e8000}, {0x458ea000}, {0x458ec000}, {0x458ee000}, + {0x458f0000}, {0x458f2000}, {0x458f4000}, {0x458f6000}, + {0x458f8000}, {0x458fa000}, {0x458fc000}, {0x458fe000}, + {0x45900000}, {0x45902000}, {0x45904000}, {0x45906000}, + {0x45908000}, {0x4590a000}, {0x4590c000}, {0x4590e000}, + {0x45910000}, {0x45912000}, {0x45914000}, {0x45916000}, + {0x45918000}, {0x4591a000}, {0x4591c000}, {0x4591e000}, + {0x45920000}, {0x45922000}, {0x45924000}, {0x45926000}, + {0x45928000}, {0x4592a000}, {0x4592c000}, {0x4592e000}, + {0x45930000}, {0x45932000}, {0x45934000}, {0x45936000}, + {0x45938000}, {0x4593a000}, {0x4593c000}, {0x4593e000}, + {0x45940000}, {0x45942000}, {0x45944000}, {0x45946000}, + {0x45948000}, {0x4594a000}, {0x4594c000}, {0x4594e000}, + {0x45950000}, {0x45952000}, {0x45954000}, {0x45956000}, + {0x45958000}, {0x4595a000}, {0x4595c000}, {0x4595e000}, + {0x45960000}, {0x45962000}, {0x45964000}, {0x45966000}, + {0x45968000}, {0x4596a000}, {0x4596c000}, {0x4596e000}, + {0x45970000}, {0x45972000}, {0x45974000}, {0x45976000}, + {0x45978000}, {0x4597a000}, {0x4597c000}, {0x4597e000}, + {0x45980000}, {0x45982000}, {0x45984000}, {0x45986000}, + {0x45988000}, {0x4598a000}, {0x4598c000}, {0x4598e000}, + {0x45990000}, {0x45992000}, {0x45994000}, {0x45996000}, + {0x45998000}, {0x4599a000}, {0x4599c000}, {0x4599e000}, + {0x459a0000}, {0x459a2000}, {0x459a4000}, {0x459a6000}, + {0x459a8000}, {0x459aa000}, {0x459ac000}, {0x459ae000}, + {0x459b0000}, {0x459b2000}, {0x459b4000}, {0x459b6000}, + {0x459b8000}, {0x459ba000}, {0x459bc000}, {0x459be000}, + {0x459c0000}, {0x459c2000}, {0x459c4000}, {0x459c6000}, + {0x459c8000}, {0x459ca000}, {0x459cc000}, {0x459ce000}, + {0x459d0000}, {0x459d2000}, {0x459d4000}, {0x459d6000}, + {0x459d8000}, {0x459da000}, {0x459dc000}, {0x459de000}, + {0x459e0000}, {0x459e2000}, {0x459e4000}, {0x459e6000}, + {0x459e8000}, {0x459ea000}, {0x459ec000}, {0x459ee000}, + {0x459f0000}, {0x459f2000}, {0x459f4000}, {0x459f6000}, + {0x459f8000}, {0x459fa000}, {0x459fc000}, {0x459fe000}, + {0x45a00000}, {0x45a02000}, {0x45a04000}, {0x45a06000}, + {0x45a08000}, {0x45a0a000}, {0x45a0c000}, {0x45a0e000}, + {0x45a10000}, {0x45a12000}, {0x45a14000}, {0x45a16000}, + {0x45a18000}, {0x45a1a000}, {0x45a1c000}, {0x45a1e000}, + {0x45a20000}, {0x45a22000}, {0x45a24000}, {0x45a26000}, + {0x45a28000}, {0x45a2a000}, {0x45a2c000}, {0x45a2e000}, + {0x45a30000}, {0x45a32000}, {0x45a34000}, {0x45a36000}, + {0x45a38000}, {0x45a3a000}, {0x45a3c000}, {0x45a3e000}, + {0x45a40000}, {0x45a42000}, {0x45a44000}, {0x45a46000}, + {0x45a48000}, {0x45a4a000}, {0x45a4c000}, {0x45a4e000}, + {0x45a50000}, {0x45a52000}, {0x45a54000}, {0x45a56000}, + {0x45a58000}, {0x45a5a000}, {0x45a5c000}, {0x45a5e000}, + {0x45a60000}, {0x45a62000}, {0x45a64000}, {0x45a66000}, + {0x45a68000}, {0x45a6a000}, {0x45a6c000}, {0x45a6e000}, + {0x45a70000}, {0x45a72000}, {0x45a74000}, {0x45a76000}, + {0x45a78000}, {0x45a7a000}, {0x45a7c000}, {0x45a7e000}, + {0x45a80000}, {0x45a82000}, {0x45a84000}, {0x45a86000}, + {0x45a88000}, {0x45a8a000}, {0x45a8c000}, {0x45a8e000}, + {0x45a90000}, {0x45a92000}, {0x45a94000}, {0x45a96000}, + {0x45a98000}, {0x45a9a000}, {0x45a9c000}, {0x45a9e000}, + {0x45aa0000}, {0x45aa2000}, {0x45aa4000}, {0x45aa6000}, + {0x45aa8000}, {0x45aaa000}, {0x45aac000}, {0x45aae000}, + {0x45ab0000}, {0x45ab2000}, {0x45ab4000}, {0x45ab6000}, + {0x45ab8000}, {0x45aba000}, {0x45abc000}, {0x45abe000}, + {0x45ac0000}, {0x45ac2000}, {0x45ac4000}, {0x45ac6000}, + {0x45ac8000}, {0x45aca000}, {0x45acc000}, {0x45ace000}, + {0x45ad0000}, {0x45ad2000}, {0x45ad4000}, {0x45ad6000}, + {0x45ad8000}, {0x45ada000}, {0x45adc000}, {0x45ade000}, + {0x45ae0000}, {0x45ae2000}, {0x45ae4000}, {0x45ae6000}, + {0x45ae8000}, {0x45aea000}, {0x45aec000}, {0x45aee000}, + {0x45af0000}, {0x45af2000}, {0x45af4000}, {0x45af6000}, + {0x45af8000}, {0x45afa000}, {0x45afc000}, {0x45afe000}, + {0x45b00000}, {0x45b02000}, {0x45b04000}, {0x45b06000}, + {0x45b08000}, {0x45b0a000}, {0x45b0c000}, {0x45b0e000}, + {0x45b10000}, {0x45b12000}, {0x45b14000}, {0x45b16000}, + {0x45b18000}, {0x45b1a000}, {0x45b1c000}, {0x45b1e000}, + {0x45b20000}, {0x45b22000}, {0x45b24000}, {0x45b26000}, + {0x45b28000}, {0x45b2a000}, {0x45b2c000}, {0x45b2e000}, + {0x45b30000}, {0x45b32000}, {0x45b34000}, {0x45b36000}, + {0x45b38000}, {0x45b3a000}, {0x45b3c000}, {0x45b3e000}, + {0x45b40000}, {0x45b42000}, {0x45b44000}, {0x45b46000}, + {0x45b48000}, {0x45b4a000}, {0x45b4c000}, {0x45b4e000}, + {0x45b50000}, {0x45b52000}, {0x45b54000}, {0x45b56000}, + {0x45b58000}, {0x45b5a000}, {0x45b5c000}, {0x45b5e000}, + {0x45b60000}, {0x45b62000}, {0x45b64000}, {0x45b66000}, + {0x45b68000}, {0x45b6a000}, {0x45b6c000}, {0x45b6e000}, + {0x45b70000}, {0x45b72000}, {0x45b74000}, {0x45b76000}, + {0x45b78000}, {0x45b7a000}, {0x45b7c000}, {0x45b7e000}, + {0x45b80000}, {0x45b82000}, {0x45b84000}, {0x45b86000}, + {0x45b88000}, {0x45b8a000}, {0x45b8c000}, {0x45b8e000}, + {0x45b90000}, {0x45b92000}, {0x45b94000}, {0x45b96000}, + {0x45b98000}, {0x45b9a000}, {0x45b9c000}, {0x45b9e000}, + {0x45ba0000}, {0x45ba2000}, {0x45ba4000}, {0x45ba6000}, + {0x45ba8000}, {0x45baa000}, {0x45bac000}, {0x45bae000}, + {0x45bb0000}, {0x45bb2000}, {0x45bb4000}, {0x45bb6000}, + {0x45bb8000}, {0x45bba000}, {0x45bbc000}, {0x45bbe000}, + {0x45bc0000}, {0x45bc2000}, {0x45bc4000}, {0x45bc6000}, + {0x45bc8000}, {0x45bca000}, {0x45bcc000}, {0x45bce000}, + {0x45bd0000}, {0x45bd2000}, {0x45bd4000}, {0x45bd6000}, + {0x45bd8000}, {0x45bda000}, {0x45bdc000}, {0x45bde000}, + {0x45be0000}, {0x45be2000}, {0x45be4000}, {0x45be6000}, + {0x45be8000}, {0x45bea000}, {0x45bec000}, {0x45bee000}, + {0x45bf0000}, {0x45bf2000}, {0x45bf4000}, {0x45bf6000}, + {0x45bf8000}, {0x45bfa000}, {0x45bfc000}, {0x45bfe000}, + {0x45c00000}, {0x45c02000}, {0x45c04000}, {0x45c06000}, + {0x45c08000}, {0x45c0a000}, {0x45c0c000}, {0x45c0e000}, + {0x45c10000}, {0x45c12000}, {0x45c14000}, {0x45c16000}, + {0x45c18000}, {0x45c1a000}, {0x45c1c000}, {0x45c1e000}, + {0x45c20000}, {0x45c22000}, {0x45c24000}, {0x45c26000}, + {0x45c28000}, {0x45c2a000}, {0x45c2c000}, {0x45c2e000}, + {0x45c30000}, {0x45c32000}, {0x45c34000}, {0x45c36000}, + {0x45c38000}, {0x45c3a000}, {0x45c3c000}, {0x45c3e000}, + {0x45c40000}, {0x45c42000}, {0x45c44000}, {0x45c46000}, + {0x45c48000}, {0x45c4a000}, {0x45c4c000}, {0x45c4e000}, + {0x45c50000}, {0x45c52000}, {0x45c54000}, {0x45c56000}, + {0x45c58000}, {0x45c5a000}, {0x45c5c000}, {0x45c5e000}, + {0x45c60000}, {0x45c62000}, {0x45c64000}, {0x45c66000}, + {0x45c68000}, {0x45c6a000}, {0x45c6c000}, {0x45c6e000}, + {0x45c70000}, {0x45c72000}, {0x45c74000}, {0x45c76000}, + {0x45c78000}, {0x45c7a000}, {0x45c7c000}, {0x45c7e000}, + {0x45c80000}, {0x45c82000}, {0x45c84000}, {0x45c86000}, + {0x45c88000}, {0x45c8a000}, {0x45c8c000}, {0x45c8e000}, + {0x45c90000}, {0x45c92000}, {0x45c94000}, {0x45c96000}, + {0x45c98000}, {0x45c9a000}, {0x45c9c000}, {0x45c9e000}, + {0x45ca0000}, {0x45ca2000}, {0x45ca4000}, {0x45ca6000}, + {0x45ca8000}, {0x45caa000}, {0x45cac000}, {0x45cae000}, + {0x45cb0000}, {0x45cb2000}, {0x45cb4000}, {0x45cb6000}, + {0x45cb8000}, {0x45cba000}, {0x45cbc000}, {0x45cbe000}, + {0x45cc0000}, {0x45cc2000}, {0x45cc4000}, {0x45cc6000}, + {0x45cc8000}, {0x45cca000}, {0x45ccc000}, {0x45cce000}, + {0x45cd0000}, {0x45cd2000}, {0x45cd4000}, {0x45cd6000}, + {0x45cd8000}, {0x45cda000}, {0x45cdc000}, {0x45cde000}, + {0x45ce0000}, {0x45ce2000}, {0x45ce4000}, {0x45ce6000}, + {0x45ce8000}, {0x45cea000}, {0x45cec000}, {0x45cee000}, + {0x45cf0000}, {0x45cf2000}, {0x45cf4000}, {0x45cf6000}, + {0x45cf8000}, {0x45cfa000}, {0x45cfc000}, {0x45cfe000}, + {0x45d00000}, {0x45d02000}, {0x45d04000}, {0x45d06000}, + {0x45d08000}, {0x45d0a000}, {0x45d0c000}, {0x45d0e000}, + {0x45d10000}, {0x45d12000}, {0x45d14000}, {0x45d16000}, + {0x45d18000}, {0x45d1a000}, {0x45d1c000}, {0x45d1e000}, + {0x45d20000}, {0x45d22000}, {0x45d24000}, {0x45d26000}, + {0x45d28000}, {0x45d2a000}, {0x45d2c000}, {0x45d2e000}, + {0x45d30000}, {0x45d32000}, {0x45d34000}, {0x45d36000}, + {0x45d38000}, {0x45d3a000}, {0x45d3c000}, {0x45d3e000}, + {0x45d40000}, {0x45d42000}, {0x45d44000}, {0x45d46000}, + {0x45d48000}, {0x45d4a000}, {0x45d4c000}, {0x45d4e000}, + {0x45d50000}, {0x45d52000}, {0x45d54000}, {0x45d56000}, + {0x45d58000}, {0x45d5a000}, {0x45d5c000}, {0x45d5e000}, + {0x45d60000}, {0x45d62000}, {0x45d64000}, {0x45d66000}, + {0x45d68000}, {0x45d6a000}, {0x45d6c000}, {0x45d6e000}, + {0x45d70000}, {0x45d72000}, {0x45d74000}, {0x45d76000}, + {0x45d78000}, {0x45d7a000}, {0x45d7c000}, {0x45d7e000}, + {0x45d80000}, {0x45d82000}, {0x45d84000}, {0x45d86000}, + {0x45d88000}, {0x45d8a000}, {0x45d8c000}, {0x45d8e000}, + {0x45d90000}, {0x45d92000}, {0x45d94000}, {0x45d96000}, + {0x45d98000}, {0x45d9a000}, {0x45d9c000}, {0x45d9e000}, + {0x45da0000}, {0x45da2000}, {0x45da4000}, {0x45da6000}, + {0x45da8000}, {0x45daa000}, {0x45dac000}, {0x45dae000}, + {0x45db0000}, {0x45db2000}, {0x45db4000}, {0x45db6000}, + {0x45db8000}, {0x45dba000}, {0x45dbc000}, {0x45dbe000}, + {0x45dc0000}, {0x45dc2000}, {0x45dc4000}, {0x45dc6000}, + {0x45dc8000}, {0x45dca000}, {0x45dcc000}, {0x45dce000}, + {0x45dd0000}, {0x45dd2000}, {0x45dd4000}, {0x45dd6000}, + {0x45dd8000}, {0x45dda000}, {0x45ddc000}, {0x45dde000}, + {0x45de0000}, {0x45de2000}, {0x45de4000}, {0x45de6000}, + {0x45de8000}, {0x45dea000}, {0x45dec000}, {0x45dee000}, + {0x45df0000}, {0x45df2000}, {0x45df4000}, {0x45df6000}, + {0x45df8000}, {0x45dfa000}, {0x45dfc000}, {0x45dfe000}, + {0x45e00000}, {0x45e02000}, {0x45e04000}, {0x45e06000}, + {0x45e08000}, {0x45e0a000}, {0x45e0c000}, {0x45e0e000}, + {0x45e10000}, {0x45e12000}, {0x45e14000}, {0x45e16000}, + {0x45e18000}, {0x45e1a000}, {0x45e1c000}, {0x45e1e000}, + {0x45e20000}, {0x45e22000}, {0x45e24000}, {0x45e26000}, + {0x45e28000}, {0x45e2a000}, {0x45e2c000}, {0x45e2e000}, + {0x45e30000}, {0x45e32000}, {0x45e34000}, {0x45e36000}, + {0x45e38000}, {0x45e3a000}, {0x45e3c000}, {0x45e3e000}, + {0x45e40000}, {0x45e42000}, {0x45e44000}, {0x45e46000}, + {0x45e48000}, {0x45e4a000}, {0x45e4c000}, {0x45e4e000}, + {0x45e50000}, {0x45e52000}, {0x45e54000}, {0x45e56000}, + {0x45e58000}, {0x45e5a000}, {0x45e5c000}, {0x45e5e000}, + {0x45e60000}, {0x45e62000}, {0x45e64000}, {0x45e66000}, + {0x45e68000}, {0x45e6a000}, {0x45e6c000}, {0x45e6e000}, + {0x45e70000}, {0x45e72000}, {0x45e74000}, {0x45e76000}, + {0x45e78000}, {0x45e7a000}, {0x45e7c000}, {0x45e7e000}, + {0x45e80000}, {0x45e82000}, {0x45e84000}, {0x45e86000}, + {0x45e88000}, {0x45e8a000}, {0x45e8c000}, {0x45e8e000}, + {0x45e90000}, {0x45e92000}, {0x45e94000}, {0x45e96000}, + {0x45e98000}, {0x45e9a000}, {0x45e9c000}, {0x45e9e000}, + {0x45ea0000}, {0x45ea2000}, {0x45ea4000}, {0x45ea6000}, + {0x45ea8000}, {0x45eaa000}, {0x45eac000}, {0x45eae000}, + {0x45eb0000}, {0x45eb2000}, {0x45eb4000}, {0x45eb6000}, + {0x45eb8000}, {0x45eba000}, {0x45ebc000}, {0x45ebe000}, + {0x45ec0000}, {0x45ec2000}, {0x45ec4000}, {0x45ec6000}, + {0x45ec8000}, {0x45eca000}, {0x45ecc000}, {0x45ece000}, + {0x45ed0000}, {0x45ed2000}, {0x45ed4000}, {0x45ed6000}, + {0x45ed8000}, {0x45eda000}, {0x45edc000}, {0x45ede000}, + {0x45ee0000}, {0x45ee2000}, {0x45ee4000}, {0x45ee6000}, + {0x45ee8000}, {0x45eea000}, {0x45eec000}, {0x45eee000}, + {0x45ef0000}, {0x45ef2000}, {0x45ef4000}, {0x45ef6000}, + {0x45ef8000}, {0x45efa000}, {0x45efc000}, {0x45efe000}, + {0x45f00000}, {0x45f02000}, {0x45f04000}, {0x45f06000}, + {0x45f08000}, {0x45f0a000}, {0x45f0c000}, {0x45f0e000}, + {0x45f10000}, {0x45f12000}, {0x45f14000}, {0x45f16000}, + {0x45f18000}, {0x45f1a000}, {0x45f1c000}, {0x45f1e000}, + {0x45f20000}, {0x45f22000}, {0x45f24000}, {0x45f26000}, + {0x45f28000}, {0x45f2a000}, {0x45f2c000}, {0x45f2e000}, + {0x45f30000}, {0x45f32000}, {0x45f34000}, {0x45f36000}, + {0x45f38000}, {0x45f3a000}, {0x45f3c000}, {0x45f3e000}, + {0x45f40000}, {0x45f42000}, {0x45f44000}, {0x45f46000}, + {0x45f48000}, {0x45f4a000}, {0x45f4c000}, {0x45f4e000}, + {0x45f50000}, {0x45f52000}, {0x45f54000}, {0x45f56000}, + {0x45f58000}, {0x45f5a000}, {0x45f5c000}, {0x45f5e000}, + {0x45f60000}, {0x45f62000}, {0x45f64000}, {0x45f66000}, + {0x45f68000}, {0x45f6a000}, {0x45f6c000}, {0x45f6e000}, + {0x45f70000}, {0x45f72000}, {0x45f74000}, {0x45f76000}, + {0x45f78000}, {0x45f7a000}, {0x45f7c000}, {0x45f7e000}, + {0x45f80000}, {0x45f82000}, {0x45f84000}, {0x45f86000}, + {0x45f88000}, {0x45f8a000}, {0x45f8c000}, {0x45f8e000}, + {0x45f90000}, {0x45f92000}, {0x45f94000}, {0x45f96000}, + {0x45f98000}, {0x45f9a000}, {0x45f9c000}, {0x45f9e000}, + {0x45fa0000}, {0x45fa2000}, {0x45fa4000}, {0x45fa6000}, + {0x45fa8000}, {0x45faa000}, {0x45fac000}, {0x45fae000}, + {0x45fb0000}, {0x45fb2000}, {0x45fb4000}, {0x45fb6000}, + {0x45fb8000}, {0x45fba000}, {0x45fbc000}, {0x45fbe000}, + {0x45fc0000}, {0x45fc2000}, {0x45fc4000}, {0x45fc6000}, + {0x45fc8000}, {0x45fca000}, {0x45fcc000}, {0x45fce000}, + {0x45fd0000}, {0x45fd2000}, {0x45fd4000}, {0x45fd6000}, + {0x45fd8000}, {0x45fda000}, {0x45fdc000}, {0x45fde000}, + {0x45fe0000}, {0x45fe2000}, {0x45fe4000}, {0x45fe6000}, + {0x45fe8000}, {0x45fea000}, {0x45fec000}, {0x45fee000}, + {0x45ff0000}, {0x45ff2000}, {0x45ff4000}, {0x45ff6000}, + {0x45ff8000}, {0x45ffa000}, {0x45ffc000}, {0x45ffe000}, + {0x46000000}, {0x46002000}, {0x46004000}, {0x46006000}, + {0x46008000}, {0x4600a000}, {0x4600c000}, {0x4600e000}, + {0x46010000}, {0x46012000}, {0x46014000}, {0x46016000}, + {0x46018000}, {0x4601a000}, {0x4601c000}, {0x4601e000}, + {0x46020000}, {0x46022000}, {0x46024000}, {0x46026000}, + {0x46028000}, {0x4602a000}, {0x4602c000}, {0x4602e000}, + {0x46030000}, {0x46032000}, {0x46034000}, {0x46036000}, + {0x46038000}, {0x4603a000}, {0x4603c000}, {0x4603e000}, + {0x46040000}, {0x46042000}, {0x46044000}, {0x46046000}, + {0x46048000}, {0x4604a000}, {0x4604c000}, {0x4604e000}, + {0x46050000}, {0x46052000}, {0x46054000}, {0x46056000}, + {0x46058000}, {0x4605a000}, {0x4605c000}, {0x4605e000}, + {0x46060000}, {0x46062000}, {0x46064000}, {0x46066000}, + {0x46068000}, {0x4606a000}, {0x4606c000}, {0x4606e000}, + {0x46070000}, {0x46072000}, {0x46074000}, {0x46076000}, + {0x46078000}, {0x4607a000}, {0x4607c000}, {0x4607e000}, + {0x46080000}, {0x46082000}, {0x46084000}, {0x46086000}, + {0x46088000}, {0x4608a000}, {0x4608c000}, {0x4608e000}, + {0x46090000}, {0x46092000}, {0x46094000}, {0x46096000}, + {0x46098000}, {0x4609a000}, {0x4609c000}, {0x4609e000}, + {0x460a0000}, {0x460a2000}, {0x460a4000}, {0x460a6000}, + {0x460a8000}, {0x460aa000}, {0x460ac000}, {0x460ae000}, + {0x460b0000}, {0x460b2000}, {0x460b4000}, {0x460b6000}, + {0x460b8000}, {0x460ba000}, {0x460bc000}, {0x460be000}, + {0x460c0000}, {0x460c2000}, {0x460c4000}, {0x460c6000}, + {0x460c8000}, {0x460ca000}, {0x460cc000}, {0x460ce000}, + {0x460d0000}, {0x460d2000}, {0x460d4000}, {0x460d6000}, + {0x460d8000}, {0x460da000}, {0x460dc000}, {0x460de000}, + {0x460e0000}, {0x460e2000}, {0x460e4000}, {0x460e6000}, + {0x460e8000}, {0x460ea000}, {0x460ec000}, {0x460ee000}, + {0x460f0000}, {0x460f2000}, {0x460f4000}, {0x460f6000}, + {0x460f8000}, {0x460fa000}, {0x460fc000}, {0x460fe000}, + {0x46100000}, {0x46102000}, {0x46104000}, {0x46106000}, + {0x46108000}, {0x4610a000}, {0x4610c000}, {0x4610e000}, + {0x46110000}, {0x46112000}, {0x46114000}, {0x46116000}, + {0x46118000}, {0x4611a000}, {0x4611c000}, {0x4611e000}, + {0x46120000}, {0x46122000}, {0x46124000}, {0x46126000}, + {0x46128000}, {0x4612a000}, {0x4612c000}, {0x4612e000}, + {0x46130000}, {0x46132000}, {0x46134000}, {0x46136000}, + {0x46138000}, {0x4613a000}, {0x4613c000}, {0x4613e000}, + {0x46140000}, {0x46142000}, {0x46144000}, {0x46146000}, + {0x46148000}, {0x4614a000}, {0x4614c000}, {0x4614e000}, + {0x46150000}, {0x46152000}, {0x46154000}, {0x46156000}, + {0x46158000}, {0x4615a000}, {0x4615c000}, {0x4615e000}, + {0x46160000}, {0x46162000}, {0x46164000}, {0x46166000}, + {0x46168000}, {0x4616a000}, {0x4616c000}, {0x4616e000}, + {0x46170000}, {0x46172000}, {0x46174000}, {0x46176000}, + {0x46178000}, {0x4617a000}, {0x4617c000}, {0x4617e000}, + {0x46180000}, {0x46182000}, {0x46184000}, {0x46186000}, + {0x46188000}, {0x4618a000}, {0x4618c000}, {0x4618e000}, + {0x46190000}, {0x46192000}, {0x46194000}, {0x46196000}, + {0x46198000}, {0x4619a000}, {0x4619c000}, {0x4619e000}, + {0x461a0000}, {0x461a2000}, {0x461a4000}, {0x461a6000}, + {0x461a8000}, {0x461aa000}, {0x461ac000}, {0x461ae000}, + {0x461b0000}, {0x461b2000}, {0x461b4000}, {0x461b6000}, + {0x461b8000}, {0x461ba000}, {0x461bc000}, {0x461be000}, + {0x461c0000}, {0x461c2000}, {0x461c4000}, {0x461c6000}, + {0x461c8000}, {0x461ca000}, {0x461cc000}, {0x461ce000}, + {0x461d0000}, {0x461d2000}, {0x461d4000}, {0x461d6000}, + {0x461d8000}, {0x461da000}, {0x461dc000}, {0x461de000}, + {0x461e0000}, {0x461e2000}, {0x461e4000}, {0x461e6000}, + {0x461e8000}, {0x461ea000}, {0x461ec000}, {0x461ee000}, + {0x461f0000}, {0x461f2000}, {0x461f4000}, {0x461f6000}, + {0x461f8000}, {0x461fa000}, {0x461fc000}, {0x461fe000}, + {0x46200000}, {0x46202000}, {0x46204000}, {0x46206000}, + {0x46208000}, {0x4620a000}, {0x4620c000}, {0x4620e000}, + {0x46210000}, {0x46212000}, {0x46214000}, {0x46216000}, + {0x46218000}, {0x4621a000}, {0x4621c000}, {0x4621e000}, + {0x46220000}, {0x46222000}, {0x46224000}, {0x46226000}, + {0x46228000}, {0x4622a000}, {0x4622c000}, {0x4622e000}, + {0x46230000}, {0x46232000}, {0x46234000}, {0x46236000}, + {0x46238000}, {0x4623a000}, {0x4623c000}, {0x4623e000}, + {0x46240000}, {0x46242000}, {0x46244000}, {0x46246000}, + {0x46248000}, {0x4624a000}, {0x4624c000}, {0x4624e000}, + {0x46250000}, {0x46252000}, {0x46254000}, {0x46256000}, + {0x46258000}, {0x4625a000}, {0x4625c000}, {0x4625e000}, + {0x46260000}, {0x46262000}, {0x46264000}, {0x46266000}, + {0x46268000}, {0x4626a000}, {0x4626c000}, {0x4626e000}, + {0x46270000}, {0x46272000}, {0x46274000}, {0x46276000}, + {0x46278000}, {0x4627a000}, {0x4627c000}, {0x4627e000}, + {0x46280000}, {0x46282000}, {0x46284000}, {0x46286000}, + {0x46288000}, {0x4628a000}, {0x4628c000}, {0x4628e000}, + {0x46290000}, {0x46292000}, {0x46294000}, {0x46296000}, + {0x46298000}, {0x4629a000}, {0x4629c000}, {0x4629e000}, + {0x462a0000}, {0x462a2000}, {0x462a4000}, {0x462a6000}, + {0x462a8000}, {0x462aa000}, {0x462ac000}, {0x462ae000}, + {0x462b0000}, {0x462b2000}, {0x462b4000}, {0x462b6000}, + {0x462b8000}, {0x462ba000}, {0x462bc000}, {0x462be000}, + {0x462c0000}, {0x462c2000}, {0x462c4000}, {0x462c6000}, + {0x462c8000}, {0x462ca000}, {0x462cc000}, {0x462ce000}, + {0x462d0000}, {0x462d2000}, {0x462d4000}, {0x462d6000}, + {0x462d8000}, {0x462da000}, {0x462dc000}, {0x462de000}, + {0x462e0000}, {0x462e2000}, {0x462e4000}, {0x462e6000}, + {0x462e8000}, {0x462ea000}, {0x462ec000}, {0x462ee000}, + {0x462f0000}, {0x462f2000}, {0x462f4000}, {0x462f6000}, + {0x462f8000}, {0x462fa000}, {0x462fc000}, {0x462fe000}, + {0x46300000}, {0x46302000}, {0x46304000}, {0x46306000}, + {0x46308000}, {0x4630a000}, {0x4630c000}, {0x4630e000}, + {0x46310000}, {0x46312000}, {0x46314000}, {0x46316000}, + {0x46318000}, {0x4631a000}, {0x4631c000}, {0x4631e000}, + {0x46320000}, {0x46322000}, {0x46324000}, {0x46326000}, + {0x46328000}, {0x4632a000}, {0x4632c000}, {0x4632e000}, + {0x46330000}, {0x46332000}, {0x46334000}, {0x46336000}, + {0x46338000}, {0x4633a000}, {0x4633c000}, {0x4633e000}, + {0x46340000}, {0x46342000}, {0x46344000}, {0x46346000}, + {0x46348000}, {0x4634a000}, {0x4634c000}, {0x4634e000}, + {0x46350000}, {0x46352000}, {0x46354000}, {0x46356000}, + {0x46358000}, {0x4635a000}, {0x4635c000}, {0x4635e000}, + {0x46360000}, {0x46362000}, {0x46364000}, {0x46366000}, + {0x46368000}, {0x4636a000}, {0x4636c000}, {0x4636e000}, + {0x46370000}, {0x46372000}, {0x46374000}, {0x46376000}, + {0x46378000}, {0x4637a000}, {0x4637c000}, {0x4637e000}, + {0x46380000}, {0x46382000}, {0x46384000}, {0x46386000}, + {0x46388000}, {0x4638a000}, {0x4638c000}, {0x4638e000}, + {0x46390000}, {0x46392000}, {0x46394000}, {0x46396000}, + {0x46398000}, {0x4639a000}, {0x4639c000}, {0x4639e000}, + {0x463a0000}, {0x463a2000}, {0x463a4000}, {0x463a6000}, + {0x463a8000}, {0x463aa000}, {0x463ac000}, {0x463ae000}, + {0x463b0000}, {0x463b2000}, {0x463b4000}, {0x463b6000}, + {0x463b8000}, {0x463ba000}, {0x463bc000}, {0x463be000}, + {0x463c0000}, {0x463c2000}, {0x463c4000}, {0x463c6000}, + {0x463c8000}, {0x463ca000}, {0x463cc000}, {0x463ce000}, + {0x463d0000}, {0x463d2000}, {0x463d4000}, {0x463d6000}, + {0x463d8000}, {0x463da000}, {0x463dc000}, {0x463de000}, + {0x463e0000}, {0x463e2000}, {0x463e4000}, {0x463e6000}, + {0x463e8000}, {0x463ea000}, {0x463ec000}, {0x463ee000}, + {0x463f0000}, {0x463f2000}, {0x463f4000}, {0x463f6000}, + {0x463f8000}, {0x463fa000}, {0x463fc000}, {0x463fe000}, + {0x46400000}, {0x46402000}, {0x46404000}, {0x46406000}, + {0x46408000}, {0x4640a000}, {0x4640c000}, {0x4640e000}, + {0x46410000}, {0x46412000}, {0x46414000}, {0x46416000}, + {0x46418000}, {0x4641a000}, {0x4641c000}, {0x4641e000}, + {0x46420000}, {0x46422000}, {0x46424000}, {0x46426000}, + {0x46428000}, {0x4642a000}, {0x4642c000}, {0x4642e000}, + {0x46430000}, {0x46432000}, {0x46434000}, {0x46436000}, + {0x46438000}, {0x4643a000}, {0x4643c000}, {0x4643e000}, + {0x46440000}, {0x46442000}, {0x46444000}, {0x46446000}, + {0x46448000}, {0x4644a000}, {0x4644c000}, {0x4644e000}, + {0x46450000}, {0x46452000}, {0x46454000}, {0x46456000}, + {0x46458000}, {0x4645a000}, {0x4645c000}, {0x4645e000}, + {0x46460000}, {0x46462000}, {0x46464000}, {0x46466000}, + {0x46468000}, {0x4646a000}, {0x4646c000}, {0x4646e000}, + {0x46470000}, {0x46472000}, {0x46474000}, {0x46476000}, + {0x46478000}, {0x4647a000}, {0x4647c000}, {0x4647e000}, + {0x46480000}, {0x46482000}, {0x46484000}, {0x46486000}, + {0x46488000}, {0x4648a000}, {0x4648c000}, {0x4648e000}, + {0x46490000}, {0x46492000}, {0x46494000}, {0x46496000}, + {0x46498000}, {0x4649a000}, {0x4649c000}, {0x4649e000}, + {0x464a0000}, {0x464a2000}, {0x464a4000}, {0x464a6000}, + {0x464a8000}, {0x464aa000}, {0x464ac000}, {0x464ae000}, + {0x464b0000}, {0x464b2000}, {0x464b4000}, {0x464b6000}, + {0x464b8000}, {0x464ba000}, {0x464bc000}, {0x464be000}, + {0x464c0000}, {0x464c2000}, {0x464c4000}, {0x464c6000}, + {0x464c8000}, {0x464ca000}, {0x464cc000}, {0x464ce000}, + {0x464d0000}, {0x464d2000}, {0x464d4000}, {0x464d6000}, + {0x464d8000}, {0x464da000}, {0x464dc000}, {0x464de000}, + {0x464e0000}, {0x464e2000}, {0x464e4000}, {0x464e6000}, + {0x464e8000}, {0x464ea000}, {0x464ec000}, {0x464ee000}, + {0x464f0000}, {0x464f2000}, {0x464f4000}, {0x464f6000}, + {0x464f8000}, {0x464fa000}, {0x464fc000}, {0x464fe000}, + {0x46500000}, {0x46502000}, {0x46504000}, {0x46506000}, + {0x46508000}, {0x4650a000}, {0x4650c000}, {0x4650e000}, + {0x46510000}, {0x46512000}, {0x46514000}, {0x46516000}, + {0x46518000}, {0x4651a000}, {0x4651c000}, {0x4651e000}, + {0x46520000}, {0x46522000}, {0x46524000}, {0x46526000}, + {0x46528000}, {0x4652a000}, {0x4652c000}, {0x4652e000}, + {0x46530000}, {0x46532000}, {0x46534000}, {0x46536000}, + {0x46538000}, {0x4653a000}, {0x4653c000}, {0x4653e000}, + {0x46540000}, {0x46542000}, {0x46544000}, {0x46546000}, + {0x46548000}, {0x4654a000}, {0x4654c000}, {0x4654e000}, + {0x46550000}, {0x46552000}, {0x46554000}, {0x46556000}, + {0x46558000}, {0x4655a000}, {0x4655c000}, {0x4655e000}, + {0x46560000}, {0x46562000}, {0x46564000}, {0x46566000}, + {0x46568000}, {0x4656a000}, {0x4656c000}, {0x4656e000}, + {0x46570000}, {0x46572000}, {0x46574000}, {0x46576000}, + {0x46578000}, {0x4657a000}, {0x4657c000}, {0x4657e000}, + {0x46580000}, {0x46582000}, {0x46584000}, {0x46586000}, + {0x46588000}, {0x4658a000}, {0x4658c000}, {0x4658e000}, + {0x46590000}, {0x46592000}, {0x46594000}, {0x46596000}, + {0x46598000}, {0x4659a000}, {0x4659c000}, {0x4659e000}, + {0x465a0000}, {0x465a2000}, {0x465a4000}, {0x465a6000}, + {0x465a8000}, {0x465aa000}, {0x465ac000}, {0x465ae000}, + {0x465b0000}, {0x465b2000}, {0x465b4000}, {0x465b6000}, + {0x465b8000}, {0x465ba000}, {0x465bc000}, {0x465be000}, + {0x465c0000}, {0x465c2000}, {0x465c4000}, {0x465c6000}, + {0x465c8000}, {0x465ca000}, {0x465cc000}, {0x465ce000}, + {0x465d0000}, {0x465d2000}, {0x465d4000}, {0x465d6000}, + {0x465d8000}, {0x465da000}, {0x465dc000}, {0x465de000}, + {0x465e0000}, {0x465e2000}, {0x465e4000}, {0x465e6000}, + {0x465e8000}, {0x465ea000}, {0x465ec000}, {0x465ee000}, + {0x465f0000}, {0x465f2000}, {0x465f4000}, {0x465f6000}, + {0x465f8000}, {0x465fa000}, {0x465fc000}, {0x465fe000}, + {0x46600000}, {0x46602000}, {0x46604000}, {0x46606000}, + {0x46608000}, {0x4660a000}, {0x4660c000}, {0x4660e000}, + {0x46610000}, {0x46612000}, {0x46614000}, {0x46616000}, + {0x46618000}, {0x4661a000}, {0x4661c000}, {0x4661e000}, + {0x46620000}, {0x46622000}, {0x46624000}, {0x46626000}, + {0x46628000}, {0x4662a000}, {0x4662c000}, {0x4662e000}, + {0x46630000}, {0x46632000}, {0x46634000}, {0x46636000}, + {0x46638000}, {0x4663a000}, {0x4663c000}, {0x4663e000}, + {0x46640000}, {0x46642000}, {0x46644000}, {0x46646000}, + {0x46648000}, {0x4664a000}, {0x4664c000}, {0x4664e000}, + {0x46650000}, {0x46652000}, {0x46654000}, {0x46656000}, + {0x46658000}, {0x4665a000}, {0x4665c000}, {0x4665e000}, + {0x46660000}, {0x46662000}, {0x46664000}, {0x46666000}, + {0x46668000}, {0x4666a000}, {0x4666c000}, {0x4666e000}, + {0x46670000}, {0x46672000}, {0x46674000}, {0x46676000}, + {0x46678000}, {0x4667a000}, {0x4667c000}, {0x4667e000}, + {0x46680000}, {0x46682000}, {0x46684000}, {0x46686000}, + {0x46688000}, {0x4668a000}, {0x4668c000}, {0x4668e000}, + {0x46690000}, {0x46692000}, {0x46694000}, {0x46696000}, + {0x46698000}, {0x4669a000}, {0x4669c000}, {0x4669e000}, + {0x466a0000}, {0x466a2000}, {0x466a4000}, {0x466a6000}, + {0x466a8000}, {0x466aa000}, {0x466ac000}, {0x466ae000}, + {0x466b0000}, {0x466b2000}, {0x466b4000}, {0x466b6000}, + {0x466b8000}, {0x466ba000}, {0x466bc000}, {0x466be000}, + {0x466c0000}, {0x466c2000}, {0x466c4000}, {0x466c6000}, + {0x466c8000}, {0x466ca000}, {0x466cc000}, {0x466ce000}, + {0x466d0000}, {0x466d2000}, {0x466d4000}, {0x466d6000}, + {0x466d8000}, {0x466da000}, {0x466dc000}, {0x466de000}, + {0x466e0000}, {0x466e2000}, {0x466e4000}, {0x466e6000}, + {0x466e8000}, {0x466ea000}, {0x466ec000}, {0x466ee000}, + {0x466f0000}, {0x466f2000}, {0x466f4000}, {0x466f6000}, + {0x466f8000}, {0x466fa000}, {0x466fc000}, {0x466fe000}, + {0x46700000}, {0x46702000}, {0x46704000}, {0x46706000}, + {0x46708000}, {0x4670a000}, {0x4670c000}, {0x4670e000}, + {0x46710000}, {0x46712000}, {0x46714000}, {0x46716000}, + {0x46718000}, {0x4671a000}, {0x4671c000}, {0x4671e000}, + {0x46720000}, {0x46722000}, {0x46724000}, {0x46726000}, + {0x46728000}, {0x4672a000}, {0x4672c000}, {0x4672e000}, + {0x46730000}, {0x46732000}, {0x46734000}, {0x46736000}, + {0x46738000}, {0x4673a000}, {0x4673c000}, {0x4673e000}, + {0x46740000}, {0x46742000}, {0x46744000}, {0x46746000}, + {0x46748000}, {0x4674a000}, {0x4674c000}, {0x4674e000}, + {0x46750000}, {0x46752000}, {0x46754000}, {0x46756000}, + {0x46758000}, {0x4675a000}, {0x4675c000}, {0x4675e000}, + {0x46760000}, {0x46762000}, {0x46764000}, {0x46766000}, + {0x46768000}, {0x4676a000}, {0x4676c000}, {0x4676e000}, + {0x46770000}, {0x46772000}, {0x46774000}, {0x46776000}, + {0x46778000}, {0x4677a000}, {0x4677c000}, {0x4677e000}, + {0x46780000}, {0x46782000}, {0x46784000}, {0x46786000}, + {0x46788000}, {0x4678a000}, {0x4678c000}, {0x4678e000}, + {0x46790000}, {0x46792000}, {0x46794000}, {0x46796000}, + {0x46798000}, {0x4679a000}, {0x4679c000}, {0x4679e000}, + {0x467a0000}, {0x467a2000}, {0x467a4000}, {0x467a6000}, + {0x467a8000}, {0x467aa000}, {0x467ac000}, {0x467ae000}, + {0x467b0000}, {0x467b2000}, {0x467b4000}, {0x467b6000}, + {0x467b8000}, {0x467ba000}, {0x467bc000}, {0x467be000}, + {0x467c0000}, {0x467c2000}, {0x467c4000}, {0x467c6000}, + {0x467c8000}, {0x467ca000}, {0x467cc000}, {0x467ce000}, + {0x467d0000}, {0x467d2000}, {0x467d4000}, {0x467d6000}, + {0x467d8000}, {0x467da000}, {0x467dc000}, {0x467de000}, + {0x467e0000}, {0x467e2000}, {0x467e4000}, {0x467e6000}, + {0x467e8000}, {0x467ea000}, {0x467ec000}, {0x467ee000}, + {0x467f0000}, {0x467f2000}, {0x467f4000}, {0x467f6000}, + {0x467f8000}, {0x467fa000}, {0x467fc000}, {0x467fe000}, + {0x46800000}, {0x46802000}, {0x46804000}, {0x46806000}, + {0x46808000}, {0x4680a000}, {0x4680c000}, {0x4680e000}, + {0x46810000}, {0x46812000}, {0x46814000}, {0x46816000}, + {0x46818000}, {0x4681a000}, {0x4681c000}, {0x4681e000}, + {0x46820000}, {0x46822000}, {0x46824000}, {0x46826000}, + {0x46828000}, {0x4682a000}, {0x4682c000}, {0x4682e000}, + {0x46830000}, {0x46832000}, {0x46834000}, {0x46836000}, + {0x46838000}, {0x4683a000}, {0x4683c000}, {0x4683e000}, + {0x46840000}, {0x46842000}, {0x46844000}, {0x46846000}, + {0x46848000}, {0x4684a000}, {0x4684c000}, {0x4684e000}, + {0x46850000}, {0x46852000}, {0x46854000}, {0x46856000}, + {0x46858000}, {0x4685a000}, {0x4685c000}, {0x4685e000}, + {0x46860000}, {0x46862000}, {0x46864000}, {0x46866000}, + {0x46868000}, {0x4686a000}, {0x4686c000}, {0x4686e000}, + {0x46870000}, {0x46872000}, {0x46874000}, {0x46876000}, + {0x46878000}, {0x4687a000}, {0x4687c000}, {0x4687e000}, + {0x46880000}, {0x46882000}, {0x46884000}, {0x46886000}, + {0x46888000}, {0x4688a000}, {0x4688c000}, {0x4688e000}, + {0x46890000}, {0x46892000}, {0x46894000}, {0x46896000}, + {0x46898000}, {0x4689a000}, {0x4689c000}, {0x4689e000}, + {0x468a0000}, {0x468a2000}, {0x468a4000}, {0x468a6000}, + {0x468a8000}, {0x468aa000}, {0x468ac000}, {0x468ae000}, + {0x468b0000}, {0x468b2000}, {0x468b4000}, {0x468b6000}, + {0x468b8000}, {0x468ba000}, {0x468bc000}, {0x468be000}, + {0x468c0000}, {0x468c2000}, {0x468c4000}, {0x468c6000}, + {0x468c8000}, {0x468ca000}, {0x468cc000}, {0x468ce000}, + {0x468d0000}, {0x468d2000}, {0x468d4000}, {0x468d6000}, + {0x468d8000}, {0x468da000}, {0x468dc000}, {0x468de000}, + {0x468e0000}, {0x468e2000}, {0x468e4000}, {0x468e6000}, + {0x468e8000}, {0x468ea000}, {0x468ec000}, {0x468ee000}, + {0x468f0000}, {0x468f2000}, {0x468f4000}, {0x468f6000}, + {0x468f8000}, {0x468fa000}, {0x468fc000}, {0x468fe000}, + {0x46900000}, {0x46902000}, {0x46904000}, {0x46906000}, + {0x46908000}, {0x4690a000}, {0x4690c000}, {0x4690e000}, + {0x46910000}, {0x46912000}, {0x46914000}, {0x46916000}, + {0x46918000}, {0x4691a000}, {0x4691c000}, {0x4691e000}, + {0x46920000}, {0x46922000}, {0x46924000}, {0x46926000}, + {0x46928000}, {0x4692a000}, {0x4692c000}, {0x4692e000}, + {0x46930000}, {0x46932000}, {0x46934000}, {0x46936000}, + {0x46938000}, {0x4693a000}, {0x4693c000}, {0x4693e000}, + {0x46940000}, {0x46942000}, {0x46944000}, {0x46946000}, + {0x46948000}, {0x4694a000}, {0x4694c000}, {0x4694e000}, + {0x46950000}, {0x46952000}, {0x46954000}, {0x46956000}, + {0x46958000}, {0x4695a000}, {0x4695c000}, {0x4695e000}, + {0x46960000}, {0x46962000}, {0x46964000}, {0x46966000}, + {0x46968000}, {0x4696a000}, {0x4696c000}, {0x4696e000}, + {0x46970000}, {0x46972000}, {0x46974000}, {0x46976000}, + {0x46978000}, {0x4697a000}, {0x4697c000}, {0x4697e000}, + {0x46980000}, {0x46982000}, {0x46984000}, {0x46986000}, + {0x46988000}, {0x4698a000}, {0x4698c000}, {0x4698e000}, + {0x46990000}, {0x46992000}, {0x46994000}, {0x46996000}, + {0x46998000}, {0x4699a000}, {0x4699c000}, {0x4699e000}, + {0x469a0000}, {0x469a2000}, {0x469a4000}, {0x469a6000}, + {0x469a8000}, {0x469aa000}, {0x469ac000}, {0x469ae000}, + {0x469b0000}, {0x469b2000}, {0x469b4000}, {0x469b6000}, + {0x469b8000}, {0x469ba000}, {0x469bc000}, {0x469be000}, + {0x469c0000}, {0x469c2000}, {0x469c4000}, {0x469c6000}, + {0x469c8000}, {0x469ca000}, {0x469cc000}, {0x469ce000}, + {0x469d0000}, {0x469d2000}, {0x469d4000}, {0x469d6000}, + {0x469d8000}, {0x469da000}, {0x469dc000}, {0x469de000}, + {0x469e0000}, {0x469e2000}, {0x469e4000}, {0x469e6000}, + {0x469e8000}, {0x469ea000}, {0x469ec000}, {0x469ee000}, + {0x469f0000}, {0x469f2000}, {0x469f4000}, {0x469f6000}, + {0x469f8000}, {0x469fa000}, {0x469fc000}, {0x469fe000}, + {0x46a00000}, {0x46a02000}, {0x46a04000}, {0x46a06000}, + {0x46a08000}, {0x46a0a000}, {0x46a0c000}, {0x46a0e000}, + {0x46a10000}, {0x46a12000}, {0x46a14000}, {0x46a16000}, + {0x46a18000}, {0x46a1a000}, {0x46a1c000}, {0x46a1e000}, + {0x46a20000}, {0x46a22000}, {0x46a24000}, {0x46a26000}, + {0x46a28000}, {0x46a2a000}, {0x46a2c000}, {0x46a2e000}, + {0x46a30000}, {0x46a32000}, {0x46a34000}, {0x46a36000}, + {0x46a38000}, {0x46a3a000}, {0x46a3c000}, {0x46a3e000}, + {0x46a40000}, {0x46a42000}, {0x46a44000}, {0x46a46000}, + {0x46a48000}, {0x46a4a000}, {0x46a4c000}, {0x46a4e000}, + {0x46a50000}, {0x46a52000}, {0x46a54000}, {0x46a56000}, + {0x46a58000}, {0x46a5a000}, {0x46a5c000}, {0x46a5e000}, + {0x46a60000}, {0x46a62000}, {0x46a64000}, {0x46a66000}, + {0x46a68000}, {0x46a6a000}, {0x46a6c000}, {0x46a6e000}, + {0x46a70000}, {0x46a72000}, {0x46a74000}, {0x46a76000}, + {0x46a78000}, {0x46a7a000}, {0x46a7c000}, {0x46a7e000}, + {0x46a80000}, {0x46a82000}, {0x46a84000}, {0x46a86000}, + {0x46a88000}, {0x46a8a000}, {0x46a8c000}, {0x46a8e000}, + {0x46a90000}, {0x46a92000}, {0x46a94000}, {0x46a96000}, + {0x46a98000}, {0x46a9a000}, {0x46a9c000}, {0x46a9e000}, + {0x46aa0000}, {0x46aa2000}, {0x46aa4000}, {0x46aa6000}, + {0x46aa8000}, {0x46aaa000}, {0x46aac000}, {0x46aae000}, + {0x46ab0000}, {0x46ab2000}, {0x46ab4000}, {0x46ab6000}, + {0x46ab8000}, {0x46aba000}, {0x46abc000}, {0x46abe000}, + {0x46ac0000}, {0x46ac2000}, {0x46ac4000}, {0x46ac6000}, + {0x46ac8000}, {0x46aca000}, {0x46acc000}, {0x46ace000}, + {0x46ad0000}, {0x46ad2000}, {0x46ad4000}, {0x46ad6000}, + {0x46ad8000}, {0x46ada000}, {0x46adc000}, {0x46ade000}, + {0x46ae0000}, {0x46ae2000}, {0x46ae4000}, {0x46ae6000}, + {0x46ae8000}, {0x46aea000}, {0x46aec000}, {0x46aee000}, + {0x46af0000}, {0x46af2000}, {0x46af4000}, {0x46af6000}, + {0x46af8000}, {0x46afa000}, {0x46afc000}, {0x46afe000}, + {0x46b00000}, {0x46b02000}, {0x46b04000}, {0x46b06000}, + {0x46b08000}, {0x46b0a000}, {0x46b0c000}, {0x46b0e000}, + {0x46b10000}, {0x46b12000}, {0x46b14000}, {0x46b16000}, + {0x46b18000}, {0x46b1a000}, {0x46b1c000}, {0x46b1e000}, + {0x46b20000}, {0x46b22000}, {0x46b24000}, {0x46b26000}, + {0x46b28000}, {0x46b2a000}, {0x46b2c000}, {0x46b2e000}, + {0x46b30000}, {0x46b32000}, {0x46b34000}, {0x46b36000}, + {0x46b38000}, {0x46b3a000}, {0x46b3c000}, {0x46b3e000}, + {0x46b40000}, {0x46b42000}, {0x46b44000}, {0x46b46000}, + {0x46b48000}, {0x46b4a000}, {0x46b4c000}, {0x46b4e000}, + {0x46b50000}, {0x46b52000}, {0x46b54000}, {0x46b56000}, + {0x46b58000}, {0x46b5a000}, {0x46b5c000}, {0x46b5e000}, + {0x46b60000}, {0x46b62000}, {0x46b64000}, {0x46b66000}, + {0x46b68000}, {0x46b6a000}, {0x46b6c000}, {0x46b6e000}, + {0x46b70000}, {0x46b72000}, {0x46b74000}, {0x46b76000}, + {0x46b78000}, {0x46b7a000}, {0x46b7c000}, {0x46b7e000}, + {0x46b80000}, {0x46b82000}, {0x46b84000}, {0x46b86000}, + {0x46b88000}, {0x46b8a000}, {0x46b8c000}, {0x46b8e000}, + {0x46b90000}, {0x46b92000}, {0x46b94000}, {0x46b96000}, + {0x46b98000}, {0x46b9a000}, {0x46b9c000}, {0x46b9e000}, + {0x46ba0000}, {0x46ba2000}, {0x46ba4000}, {0x46ba6000}, + {0x46ba8000}, {0x46baa000}, {0x46bac000}, {0x46bae000}, + {0x46bb0000}, {0x46bb2000}, {0x46bb4000}, {0x46bb6000}, + {0x46bb8000}, {0x46bba000}, {0x46bbc000}, {0x46bbe000}, + {0x46bc0000}, {0x46bc2000}, {0x46bc4000}, {0x46bc6000}, + {0x46bc8000}, {0x46bca000}, {0x46bcc000}, {0x46bce000}, + {0x46bd0000}, {0x46bd2000}, {0x46bd4000}, {0x46bd6000}, + {0x46bd8000}, {0x46bda000}, {0x46bdc000}, {0x46bde000}, + {0x46be0000}, {0x46be2000}, {0x46be4000}, {0x46be6000}, + {0x46be8000}, {0x46bea000}, {0x46bec000}, {0x46bee000}, + {0x46bf0000}, {0x46bf2000}, {0x46bf4000}, {0x46bf6000}, + {0x46bf8000}, {0x46bfa000}, {0x46bfc000}, {0x46bfe000}, + {0x46c00000}, {0x46c02000}, {0x46c04000}, {0x46c06000}, + {0x46c08000}, {0x46c0a000}, {0x46c0c000}, {0x46c0e000}, + {0x46c10000}, {0x46c12000}, {0x46c14000}, {0x46c16000}, + {0x46c18000}, {0x46c1a000}, {0x46c1c000}, {0x46c1e000}, + {0x46c20000}, {0x46c22000}, {0x46c24000}, {0x46c26000}, + {0x46c28000}, {0x46c2a000}, {0x46c2c000}, {0x46c2e000}, + {0x46c30000}, {0x46c32000}, {0x46c34000}, {0x46c36000}, + {0x46c38000}, {0x46c3a000}, {0x46c3c000}, {0x46c3e000}, + {0x46c40000}, {0x46c42000}, {0x46c44000}, {0x46c46000}, + {0x46c48000}, {0x46c4a000}, {0x46c4c000}, {0x46c4e000}, + {0x46c50000}, {0x46c52000}, {0x46c54000}, {0x46c56000}, + {0x46c58000}, {0x46c5a000}, {0x46c5c000}, {0x46c5e000}, + {0x46c60000}, {0x46c62000}, {0x46c64000}, {0x46c66000}, + {0x46c68000}, {0x46c6a000}, {0x46c6c000}, {0x46c6e000}, + {0x46c70000}, {0x46c72000}, {0x46c74000}, {0x46c76000}, + {0x46c78000}, {0x46c7a000}, {0x46c7c000}, {0x46c7e000}, + {0x46c80000}, {0x46c82000}, {0x46c84000}, {0x46c86000}, + {0x46c88000}, {0x46c8a000}, {0x46c8c000}, {0x46c8e000}, + {0x46c90000}, {0x46c92000}, {0x46c94000}, {0x46c96000}, + {0x46c98000}, {0x46c9a000}, {0x46c9c000}, {0x46c9e000}, + {0x46ca0000}, {0x46ca2000}, {0x46ca4000}, {0x46ca6000}, + {0x46ca8000}, {0x46caa000}, {0x46cac000}, {0x46cae000}, + {0x46cb0000}, {0x46cb2000}, {0x46cb4000}, {0x46cb6000}, + {0x46cb8000}, {0x46cba000}, {0x46cbc000}, {0x46cbe000}, + {0x46cc0000}, {0x46cc2000}, {0x46cc4000}, {0x46cc6000}, + {0x46cc8000}, {0x46cca000}, {0x46ccc000}, {0x46cce000}, + {0x46cd0000}, {0x46cd2000}, {0x46cd4000}, {0x46cd6000}, + {0x46cd8000}, {0x46cda000}, {0x46cdc000}, {0x46cde000}, + {0x46ce0000}, {0x46ce2000}, {0x46ce4000}, {0x46ce6000}, + {0x46ce8000}, {0x46cea000}, {0x46cec000}, {0x46cee000}, + {0x46cf0000}, {0x46cf2000}, {0x46cf4000}, {0x46cf6000}, + {0x46cf8000}, {0x46cfa000}, {0x46cfc000}, {0x46cfe000}, + {0x46d00000}, {0x46d02000}, {0x46d04000}, {0x46d06000}, + {0x46d08000}, {0x46d0a000}, {0x46d0c000}, {0x46d0e000}, + {0x46d10000}, {0x46d12000}, {0x46d14000}, {0x46d16000}, + {0x46d18000}, {0x46d1a000}, {0x46d1c000}, {0x46d1e000}, + {0x46d20000}, {0x46d22000}, {0x46d24000}, {0x46d26000}, + {0x46d28000}, {0x46d2a000}, {0x46d2c000}, {0x46d2e000}, + {0x46d30000}, {0x46d32000}, {0x46d34000}, {0x46d36000}, + {0x46d38000}, {0x46d3a000}, {0x46d3c000}, {0x46d3e000}, + {0x46d40000}, {0x46d42000}, {0x46d44000}, {0x46d46000}, + {0x46d48000}, {0x46d4a000}, {0x46d4c000}, {0x46d4e000}, + {0x46d50000}, {0x46d52000}, {0x46d54000}, {0x46d56000}, + {0x46d58000}, {0x46d5a000}, {0x46d5c000}, {0x46d5e000}, + {0x46d60000}, {0x46d62000}, {0x46d64000}, {0x46d66000}, + {0x46d68000}, {0x46d6a000}, {0x46d6c000}, {0x46d6e000}, + {0x46d70000}, {0x46d72000}, {0x46d74000}, {0x46d76000}, + {0x46d78000}, {0x46d7a000}, {0x46d7c000}, {0x46d7e000}, + {0x46d80000}, {0x46d82000}, {0x46d84000}, {0x46d86000}, + {0x46d88000}, {0x46d8a000}, {0x46d8c000}, {0x46d8e000}, + {0x46d90000}, {0x46d92000}, {0x46d94000}, {0x46d96000}, + {0x46d98000}, {0x46d9a000}, {0x46d9c000}, {0x46d9e000}, + {0x46da0000}, {0x46da2000}, {0x46da4000}, {0x46da6000}, + {0x46da8000}, {0x46daa000}, {0x46dac000}, {0x46dae000}, + {0x46db0000}, {0x46db2000}, {0x46db4000}, {0x46db6000}, + {0x46db8000}, {0x46dba000}, {0x46dbc000}, {0x46dbe000}, + {0x46dc0000}, {0x46dc2000}, {0x46dc4000}, {0x46dc6000}, + {0x46dc8000}, {0x46dca000}, {0x46dcc000}, {0x46dce000}, + {0x46dd0000}, {0x46dd2000}, {0x46dd4000}, {0x46dd6000}, + {0x46dd8000}, {0x46dda000}, {0x46ddc000}, {0x46dde000}, + {0x46de0000}, {0x46de2000}, {0x46de4000}, {0x46de6000}, + {0x46de8000}, {0x46dea000}, {0x46dec000}, {0x46dee000}, + {0x46df0000}, {0x46df2000}, {0x46df4000}, {0x46df6000}, + {0x46df8000}, {0x46dfa000}, {0x46dfc000}, {0x46dfe000}, + {0x46e00000}, {0x46e02000}, {0x46e04000}, {0x46e06000}, + {0x46e08000}, {0x46e0a000}, {0x46e0c000}, {0x46e0e000}, + {0x46e10000}, {0x46e12000}, {0x46e14000}, {0x46e16000}, + {0x46e18000}, {0x46e1a000}, {0x46e1c000}, {0x46e1e000}, + {0x46e20000}, {0x46e22000}, {0x46e24000}, {0x46e26000}, + {0x46e28000}, {0x46e2a000}, {0x46e2c000}, {0x46e2e000}, + {0x46e30000}, {0x46e32000}, {0x46e34000}, {0x46e36000}, + {0x46e38000}, {0x46e3a000}, {0x46e3c000}, {0x46e3e000}, + {0x46e40000}, {0x46e42000}, {0x46e44000}, {0x46e46000}, + {0x46e48000}, {0x46e4a000}, {0x46e4c000}, {0x46e4e000}, + {0x46e50000}, {0x46e52000}, {0x46e54000}, {0x46e56000}, + {0x46e58000}, {0x46e5a000}, {0x46e5c000}, {0x46e5e000}, + {0x46e60000}, {0x46e62000}, {0x46e64000}, {0x46e66000}, + {0x46e68000}, {0x46e6a000}, {0x46e6c000}, {0x46e6e000}, + {0x46e70000}, {0x46e72000}, {0x46e74000}, {0x46e76000}, + {0x46e78000}, {0x46e7a000}, {0x46e7c000}, {0x46e7e000}, + {0x46e80000}, {0x46e82000}, {0x46e84000}, {0x46e86000}, + {0x46e88000}, {0x46e8a000}, {0x46e8c000}, {0x46e8e000}, + {0x46e90000}, {0x46e92000}, {0x46e94000}, {0x46e96000}, + {0x46e98000}, {0x46e9a000}, {0x46e9c000}, {0x46e9e000}, + {0x46ea0000}, {0x46ea2000}, {0x46ea4000}, {0x46ea6000}, + {0x46ea8000}, {0x46eaa000}, {0x46eac000}, {0x46eae000}, + {0x46eb0000}, {0x46eb2000}, {0x46eb4000}, {0x46eb6000}, + {0x46eb8000}, {0x46eba000}, {0x46ebc000}, {0x46ebe000}, + {0x46ec0000}, {0x46ec2000}, {0x46ec4000}, {0x46ec6000}, + {0x46ec8000}, {0x46eca000}, {0x46ecc000}, {0x46ece000}, + {0x46ed0000}, {0x46ed2000}, {0x46ed4000}, {0x46ed6000}, + {0x46ed8000}, {0x46eda000}, {0x46edc000}, {0x46ede000}, + {0x46ee0000}, {0x46ee2000}, {0x46ee4000}, {0x46ee6000}, + {0x46ee8000}, {0x46eea000}, {0x46eec000}, {0x46eee000}, + {0x46ef0000}, {0x46ef2000}, {0x46ef4000}, {0x46ef6000}, + {0x46ef8000}, {0x46efa000}, {0x46efc000}, {0x46efe000}, + {0x46f00000}, {0x46f02000}, {0x46f04000}, {0x46f06000}, + {0x46f08000}, {0x46f0a000}, {0x46f0c000}, {0x46f0e000}, + {0x46f10000}, {0x46f12000}, {0x46f14000}, {0x46f16000}, + {0x46f18000}, {0x46f1a000}, {0x46f1c000}, {0x46f1e000}, + {0x46f20000}, {0x46f22000}, {0x46f24000}, {0x46f26000}, + {0x46f28000}, {0x46f2a000}, {0x46f2c000}, {0x46f2e000}, + {0x46f30000}, {0x46f32000}, {0x46f34000}, {0x46f36000}, + {0x46f38000}, {0x46f3a000}, {0x46f3c000}, {0x46f3e000}, + {0x46f40000}, {0x46f42000}, {0x46f44000}, {0x46f46000}, + {0x46f48000}, {0x46f4a000}, {0x46f4c000}, {0x46f4e000}, + {0x46f50000}, {0x46f52000}, {0x46f54000}, {0x46f56000}, + {0x46f58000}, {0x46f5a000}, {0x46f5c000}, {0x46f5e000}, + {0x46f60000}, {0x46f62000}, {0x46f64000}, {0x46f66000}, + {0x46f68000}, {0x46f6a000}, {0x46f6c000}, {0x46f6e000}, + {0x46f70000}, {0x46f72000}, {0x46f74000}, {0x46f76000}, + {0x46f78000}, {0x46f7a000}, {0x46f7c000}, {0x46f7e000}, + {0x46f80000}, {0x46f82000}, {0x46f84000}, {0x46f86000}, + {0x46f88000}, {0x46f8a000}, {0x46f8c000}, {0x46f8e000}, + {0x46f90000}, {0x46f92000}, {0x46f94000}, {0x46f96000}, + {0x46f98000}, {0x46f9a000}, {0x46f9c000}, {0x46f9e000}, + {0x46fa0000}, {0x46fa2000}, {0x46fa4000}, {0x46fa6000}, + {0x46fa8000}, {0x46faa000}, {0x46fac000}, {0x46fae000}, + {0x46fb0000}, {0x46fb2000}, {0x46fb4000}, {0x46fb6000}, + {0x46fb8000}, {0x46fba000}, {0x46fbc000}, {0x46fbe000}, + {0x46fc0000}, {0x46fc2000}, {0x46fc4000}, {0x46fc6000}, + {0x46fc8000}, {0x46fca000}, {0x46fcc000}, {0x46fce000}, + {0x46fd0000}, {0x46fd2000}, {0x46fd4000}, {0x46fd6000}, + {0x46fd8000}, {0x46fda000}, {0x46fdc000}, {0x46fde000}, + {0x46fe0000}, {0x46fe2000}, {0x46fe4000}, {0x46fe6000}, + {0x46fe8000}, {0x46fea000}, {0x46fec000}, {0x46fee000}, + {0x46ff0000}, {0x46ff2000}, {0x46ff4000}, {0x46ff6000}, + {0x46ff8000}, {0x46ffa000}, {0x46ffc000}, {0x46ffe000}, + {0x47000000}, {0x47002000}, {0x47004000}, {0x47006000}, + {0x47008000}, {0x4700a000}, {0x4700c000}, {0x4700e000}, + {0x47010000}, {0x47012000}, {0x47014000}, {0x47016000}, + {0x47018000}, {0x4701a000}, {0x4701c000}, {0x4701e000}, + {0x47020000}, {0x47022000}, {0x47024000}, {0x47026000}, + {0x47028000}, {0x4702a000}, {0x4702c000}, {0x4702e000}, + {0x47030000}, {0x47032000}, {0x47034000}, {0x47036000}, + {0x47038000}, {0x4703a000}, {0x4703c000}, {0x4703e000}, + {0x47040000}, {0x47042000}, {0x47044000}, {0x47046000}, + {0x47048000}, {0x4704a000}, {0x4704c000}, {0x4704e000}, + {0x47050000}, {0x47052000}, {0x47054000}, {0x47056000}, + {0x47058000}, {0x4705a000}, {0x4705c000}, {0x4705e000}, + {0x47060000}, {0x47062000}, {0x47064000}, {0x47066000}, + {0x47068000}, {0x4706a000}, {0x4706c000}, {0x4706e000}, + {0x47070000}, {0x47072000}, {0x47074000}, {0x47076000}, + {0x47078000}, {0x4707a000}, {0x4707c000}, {0x4707e000}, + {0x47080000}, {0x47082000}, {0x47084000}, {0x47086000}, + {0x47088000}, {0x4708a000}, {0x4708c000}, {0x4708e000}, + {0x47090000}, {0x47092000}, {0x47094000}, {0x47096000}, + {0x47098000}, {0x4709a000}, {0x4709c000}, {0x4709e000}, + {0x470a0000}, {0x470a2000}, {0x470a4000}, {0x470a6000}, + {0x470a8000}, {0x470aa000}, {0x470ac000}, {0x470ae000}, + {0x470b0000}, {0x470b2000}, {0x470b4000}, {0x470b6000}, + {0x470b8000}, {0x470ba000}, {0x470bc000}, {0x470be000}, + {0x470c0000}, {0x470c2000}, {0x470c4000}, {0x470c6000}, + {0x470c8000}, {0x470ca000}, {0x470cc000}, {0x470ce000}, + {0x470d0000}, {0x470d2000}, {0x470d4000}, {0x470d6000}, + {0x470d8000}, {0x470da000}, {0x470dc000}, {0x470de000}, + {0x470e0000}, {0x470e2000}, {0x470e4000}, {0x470e6000}, + {0x470e8000}, {0x470ea000}, {0x470ec000}, {0x470ee000}, + {0x470f0000}, {0x470f2000}, {0x470f4000}, {0x470f6000}, + {0x470f8000}, {0x470fa000}, {0x470fc000}, {0x470fe000}, + {0x47100000}, {0x47102000}, {0x47104000}, {0x47106000}, + {0x47108000}, {0x4710a000}, {0x4710c000}, {0x4710e000}, + {0x47110000}, {0x47112000}, {0x47114000}, {0x47116000}, + {0x47118000}, {0x4711a000}, {0x4711c000}, {0x4711e000}, + {0x47120000}, {0x47122000}, {0x47124000}, {0x47126000}, + {0x47128000}, {0x4712a000}, {0x4712c000}, {0x4712e000}, + {0x47130000}, {0x47132000}, {0x47134000}, {0x47136000}, + {0x47138000}, {0x4713a000}, {0x4713c000}, {0x4713e000}, + {0x47140000}, {0x47142000}, {0x47144000}, {0x47146000}, + {0x47148000}, {0x4714a000}, {0x4714c000}, {0x4714e000}, + {0x47150000}, {0x47152000}, {0x47154000}, {0x47156000}, + {0x47158000}, {0x4715a000}, {0x4715c000}, {0x4715e000}, + {0x47160000}, {0x47162000}, {0x47164000}, {0x47166000}, + {0x47168000}, {0x4716a000}, {0x4716c000}, {0x4716e000}, + {0x47170000}, {0x47172000}, {0x47174000}, {0x47176000}, + {0x47178000}, {0x4717a000}, {0x4717c000}, {0x4717e000}, + {0x47180000}, {0x47182000}, {0x47184000}, {0x47186000}, + {0x47188000}, {0x4718a000}, {0x4718c000}, {0x4718e000}, + {0x47190000}, {0x47192000}, {0x47194000}, {0x47196000}, + {0x47198000}, {0x4719a000}, {0x4719c000}, {0x4719e000}, + {0x471a0000}, {0x471a2000}, {0x471a4000}, {0x471a6000}, + {0x471a8000}, {0x471aa000}, {0x471ac000}, {0x471ae000}, + {0x471b0000}, {0x471b2000}, {0x471b4000}, {0x471b6000}, + {0x471b8000}, {0x471ba000}, {0x471bc000}, {0x471be000}, + {0x471c0000}, {0x471c2000}, {0x471c4000}, {0x471c6000}, + {0x471c8000}, {0x471ca000}, {0x471cc000}, {0x471ce000}, + {0x471d0000}, {0x471d2000}, {0x471d4000}, {0x471d6000}, + {0x471d8000}, {0x471da000}, {0x471dc000}, {0x471de000}, + {0x471e0000}, {0x471e2000}, {0x471e4000}, {0x471e6000}, + {0x471e8000}, {0x471ea000}, {0x471ec000}, {0x471ee000}, + {0x471f0000}, {0x471f2000}, {0x471f4000}, {0x471f6000}, + {0x471f8000}, {0x471fa000}, {0x471fc000}, {0x471fe000}, + {0x47200000}, {0x47202000}, {0x47204000}, {0x47206000}, + {0x47208000}, {0x4720a000}, {0x4720c000}, {0x4720e000}, + {0x47210000}, {0x47212000}, {0x47214000}, {0x47216000}, + {0x47218000}, {0x4721a000}, {0x4721c000}, {0x4721e000}, + {0x47220000}, {0x47222000}, {0x47224000}, {0x47226000}, + {0x47228000}, {0x4722a000}, {0x4722c000}, {0x4722e000}, + {0x47230000}, {0x47232000}, {0x47234000}, {0x47236000}, + {0x47238000}, {0x4723a000}, {0x4723c000}, {0x4723e000}, + {0x47240000}, {0x47242000}, {0x47244000}, {0x47246000}, + {0x47248000}, {0x4724a000}, {0x4724c000}, {0x4724e000}, + {0x47250000}, {0x47252000}, {0x47254000}, {0x47256000}, + {0x47258000}, {0x4725a000}, {0x4725c000}, {0x4725e000}, + {0x47260000}, {0x47262000}, {0x47264000}, {0x47266000}, + {0x47268000}, {0x4726a000}, {0x4726c000}, {0x4726e000}, + {0x47270000}, {0x47272000}, {0x47274000}, {0x47276000}, + {0x47278000}, {0x4727a000}, {0x4727c000}, {0x4727e000}, + {0x47280000}, {0x47282000}, {0x47284000}, {0x47286000}, + {0x47288000}, {0x4728a000}, {0x4728c000}, {0x4728e000}, + {0x47290000}, {0x47292000}, {0x47294000}, {0x47296000}, + {0x47298000}, {0x4729a000}, {0x4729c000}, {0x4729e000}, + {0x472a0000}, {0x472a2000}, {0x472a4000}, {0x472a6000}, + {0x472a8000}, {0x472aa000}, {0x472ac000}, {0x472ae000}, + {0x472b0000}, {0x472b2000}, {0x472b4000}, {0x472b6000}, + {0x472b8000}, {0x472ba000}, {0x472bc000}, {0x472be000}, + {0x472c0000}, {0x472c2000}, {0x472c4000}, {0x472c6000}, + {0x472c8000}, {0x472ca000}, {0x472cc000}, {0x472ce000}, + {0x472d0000}, {0x472d2000}, {0x472d4000}, {0x472d6000}, + {0x472d8000}, {0x472da000}, {0x472dc000}, {0x472de000}, + {0x472e0000}, {0x472e2000}, {0x472e4000}, {0x472e6000}, + {0x472e8000}, {0x472ea000}, {0x472ec000}, {0x472ee000}, + {0x472f0000}, {0x472f2000}, {0x472f4000}, {0x472f6000}, + {0x472f8000}, {0x472fa000}, {0x472fc000}, {0x472fe000}, + {0x47300000}, {0x47302000}, {0x47304000}, {0x47306000}, + {0x47308000}, {0x4730a000}, {0x4730c000}, {0x4730e000}, + {0x47310000}, {0x47312000}, {0x47314000}, {0x47316000}, + {0x47318000}, {0x4731a000}, {0x4731c000}, {0x4731e000}, + {0x47320000}, {0x47322000}, {0x47324000}, {0x47326000}, + {0x47328000}, {0x4732a000}, {0x4732c000}, {0x4732e000}, + {0x47330000}, {0x47332000}, {0x47334000}, {0x47336000}, + {0x47338000}, {0x4733a000}, {0x4733c000}, {0x4733e000}, + {0x47340000}, {0x47342000}, {0x47344000}, {0x47346000}, + {0x47348000}, {0x4734a000}, {0x4734c000}, {0x4734e000}, + {0x47350000}, {0x47352000}, {0x47354000}, {0x47356000}, + {0x47358000}, {0x4735a000}, {0x4735c000}, {0x4735e000}, + {0x47360000}, {0x47362000}, {0x47364000}, {0x47366000}, + {0x47368000}, {0x4736a000}, {0x4736c000}, {0x4736e000}, + {0x47370000}, {0x47372000}, {0x47374000}, {0x47376000}, + {0x47378000}, {0x4737a000}, {0x4737c000}, {0x4737e000}, + {0x47380000}, {0x47382000}, {0x47384000}, {0x47386000}, + {0x47388000}, {0x4738a000}, {0x4738c000}, {0x4738e000}, + {0x47390000}, {0x47392000}, {0x47394000}, {0x47396000}, + {0x47398000}, {0x4739a000}, {0x4739c000}, {0x4739e000}, + {0x473a0000}, {0x473a2000}, {0x473a4000}, {0x473a6000}, + {0x473a8000}, {0x473aa000}, {0x473ac000}, {0x473ae000}, + {0x473b0000}, {0x473b2000}, {0x473b4000}, {0x473b6000}, + {0x473b8000}, {0x473ba000}, {0x473bc000}, {0x473be000}, + {0x473c0000}, {0x473c2000}, {0x473c4000}, {0x473c6000}, + {0x473c8000}, {0x473ca000}, {0x473cc000}, {0x473ce000}, + {0x473d0000}, {0x473d2000}, {0x473d4000}, {0x473d6000}, + {0x473d8000}, {0x473da000}, {0x473dc000}, {0x473de000}, + {0x473e0000}, {0x473e2000}, {0x473e4000}, {0x473e6000}, + {0x473e8000}, {0x473ea000}, {0x473ec000}, {0x473ee000}, + {0x473f0000}, {0x473f2000}, {0x473f4000}, {0x473f6000}, + {0x473f8000}, {0x473fa000}, {0x473fc000}, {0x473fe000}, + {0x47400000}, {0x47402000}, {0x47404000}, {0x47406000}, + {0x47408000}, {0x4740a000}, {0x4740c000}, {0x4740e000}, + {0x47410000}, {0x47412000}, {0x47414000}, {0x47416000}, + {0x47418000}, {0x4741a000}, {0x4741c000}, {0x4741e000}, + {0x47420000}, {0x47422000}, {0x47424000}, {0x47426000}, + {0x47428000}, {0x4742a000}, {0x4742c000}, {0x4742e000}, + {0x47430000}, {0x47432000}, {0x47434000}, {0x47436000}, + {0x47438000}, {0x4743a000}, {0x4743c000}, {0x4743e000}, + {0x47440000}, {0x47442000}, {0x47444000}, {0x47446000}, + {0x47448000}, {0x4744a000}, {0x4744c000}, {0x4744e000}, + {0x47450000}, {0x47452000}, {0x47454000}, {0x47456000}, + {0x47458000}, {0x4745a000}, {0x4745c000}, {0x4745e000}, + {0x47460000}, {0x47462000}, {0x47464000}, {0x47466000}, + {0x47468000}, {0x4746a000}, {0x4746c000}, {0x4746e000}, + {0x47470000}, {0x47472000}, {0x47474000}, {0x47476000}, + {0x47478000}, {0x4747a000}, {0x4747c000}, {0x4747e000}, + {0x47480000}, {0x47482000}, {0x47484000}, {0x47486000}, + {0x47488000}, {0x4748a000}, {0x4748c000}, {0x4748e000}, + {0x47490000}, {0x47492000}, {0x47494000}, {0x47496000}, + {0x47498000}, {0x4749a000}, {0x4749c000}, {0x4749e000}, + {0x474a0000}, {0x474a2000}, {0x474a4000}, {0x474a6000}, + {0x474a8000}, {0x474aa000}, {0x474ac000}, {0x474ae000}, + {0x474b0000}, {0x474b2000}, {0x474b4000}, {0x474b6000}, + {0x474b8000}, {0x474ba000}, {0x474bc000}, {0x474be000}, + {0x474c0000}, {0x474c2000}, {0x474c4000}, {0x474c6000}, + {0x474c8000}, {0x474ca000}, {0x474cc000}, {0x474ce000}, + {0x474d0000}, {0x474d2000}, {0x474d4000}, {0x474d6000}, + {0x474d8000}, {0x474da000}, {0x474dc000}, {0x474de000}, + {0x474e0000}, {0x474e2000}, {0x474e4000}, {0x474e6000}, + {0x474e8000}, {0x474ea000}, {0x474ec000}, {0x474ee000}, + {0x474f0000}, {0x474f2000}, {0x474f4000}, {0x474f6000}, + {0x474f8000}, {0x474fa000}, {0x474fc000}, {0x474fe000}, + {0x47500000}, {0x47502000}, {0x47504000}, {0x47506000}, + {0x47508000}, {0x4750a000}, {0x4750c000}, {0x4750e000}, + {0x47510000}, {0x47512000}, {0x47514000}, {0x47516000}, + {0x47518000}, {0x4751a000}, {0x4751c000}, {0x4751e000}, + {0x47520000}, {0x47522000}, {0x47524000}, {0x47526000}, + {0x47528000}, {0x4752a000}, {0x4752c000}, {0x4752e000}, + {0x47530000}, {0x47532000}, {0x47534000}, {0x47536000}, + {0x47538000}, {0x4753a000}, {0x4753c000}, {0x4753e000}, + {0x47540000}, {0x47542000}, {0x47544000}, {0x47546000}, + {0x47548000}, {0x4754a000}, {0x4754c000}, {0x4754e000}, + {0x47550000}, {0x47552000}, {0x47554000}, {0x47556000}, + {0x47558000}, {0x4755a000}, {0x4755c000}, {0x4755e000}, + {0x47560000}, {0x47562000}, {0x47564000}, {0x47566000}, + {0x47568000}, {0x4756a000}, {0x4756c000}, {0x4756e000}, + {0x47570000}, {0x47572000}, {0x47574000}, {0x47576000}, + {0x47578000}, {0x4757a000}, {0x4757c000}, {0x4757e000}, + {0x47580000}, {0x47582000}, {0x47584000}, {0x47586000}, + {0x47588000}, {0x4758a000}, {0x4758c000}, {0x4758e000}, + {0x47590000}, {0x47592000}, {0x47594000}, {0x47596000}, + {0x47598000}, {0x4759a000}, {0x4759c000}, {0x4759e000}, + {0x475a0000}, {0x475a2000}, {0x475a4000}, {0x475a6000}, + {0x475a8000}, {0x475aa000}, {0x475ac000}, {0x475ae000}, + {0x475b0000}, {0x475b2000}, {0x475b4000}, {0x475b6000}, + {0x475b8000}, {0x475ba000}, {0x475bc000}, {0x475be000}, + {0x475c0000}, {0x475c2000}, {0x475c4000}, {0x475c6000}, + {0x475c8000}, {0x475ca000}, {0x475cc000}, {0x475ce000}, + {0x475d0000}, {0x475d2000}, {0x475d4000}, {0x475d6000}, + {0x475d8000}, {0x475da000}, {0x475dc000}, {0x475de000}, + {0x475e0000}, {0x475e2000}, {0x475e4000}, {0x475e6000}, + {0x475e8000}, {0x475ea000}, {0x475ec000}, {0x475ee000}, + {0x475f0000}, {0x475f2000}, {0x475f4000}, {0x475f6000}, + {0x475f8000}, {0x475fa000}, {0x475fc000}, {0x475fe000}, + {0x47600000}, {0x47602000}, {0x47604000}, {0x47606000}, + {0x47608000}, {0x4760a000}, {0x4760c000}, {0x4760e000}, + {0x47610000}, {0x47612000}, {0x47614000}, {0x47616000}, + {0x47618000}, {0x4761a000}, {0x4761c000}, {0x4761e000}, + {0x47620000}, {0x47622000}, {0x47624000}, {0x47626000}, + {0x47628000}, {0x4762a000}, {0x4762c000}, {0x4762e000}, + {0x47630000}, {0x47632000}, {0x47634000}, {0x47636000}, + {0x47638000}, {0x4763a000}, {0x4763c000}, {0x4763e000}, + {0x47640000}, {0x47642000}, {0x47644000}, {0x47646000}, + {0x47648000}, {0x4764a000}, {0x4764c000}, {0x4764e000}, + {0x47650000}, {0x47652000}, {0x47654000}, {0x47656000}, + {0x47658000}, {0x4765a000}, {0x4765c000}, {0x4765e000}, + {0x47660000}, {0x47662000}, {0x47664000}, {0x47666000}, + {0x47668000}, {0x4766a000}, {0x4766c000}, {0x4766e000}, + {0x47670000}, {0x47672000}, {0x47674000}, {0x47676000}, + {0x47678000}, {0x4767a000}, {0x4767c000}, {0x4767e000}, + {0x47680000}, {0x47682000}, {0x47684000}, {0x47686000}, + {0x47688000}, {0x4768a000}, {0x4768c000}, {0x4768e000}, + {0x47690000}, {0x47692000}, {0x47694000}, {0x47696000}, + {0x47698000}, {0x4769a000}, {0x4769c000}, {0x4769e000}, + {0x476a0000}, {0x476a2000}, {0x476a4000}, {0x476a6000}, + {0x476a8000}, {0x476aa000}, {0x476ac000}, {0x476ae000}, + {0x476b0000}, {0x476b2000}, {0x476b4000}, {0x476b6000}, + {0x476b8000}, {0x476ba000}, {0x476bc000}, {0x476be000}, + {0x476c0000}, {0x476c2000}, {0x476c4000}, {0x476c6000}, + {0x476c8000}, {0x476ca000}, {0x476cc000}, {0x476ce000}, + {0x476d0000}, {0x476d2000}, {0x476d4000}, {0x476d6000}, + {0x476d8000}, {0x476da000}, {0x476dc000}, {0x476de000}, + {0x476e0000}, {0x476e2000}, {0x476e4000}, {0x476e6000}, + {0x476e8000}, {0x476ea000}, {0x476ec000}, {0x476ee000}, + {0x476f0000}, {0x476f2000}, {0x476f4000}, {0x476f6000}, + {0x476f8000}, {0x476fa000}, {0x476fc000}, {0x476fe000}, + {0x47700000}, {0x47702000}, {0x47704000}, {0x47706000}, + {0x47708000}, {0x4770a000}, {0x4770c000}, {0x4770e000}, + {0x47710000}, {0x47712000}, {0x47714000}, {0x47716000}, + {0x47718000}, {0x4771a000}, {0x4771c000}, {0x4771e000}, + {0x47720000}, {0x47722000}, {0x47724000}, {0x47726000}, + {0x47728000}, {0x4772a000}, {0x4772c000}, {0x4772e000}, + {0x47730000}, {0x47732000}, {0x47734000}, {0x47736000}, + {0x47738000}, {0x4773a000}, {0x4773c000}, {0x4773e000}, + {0x47740000}, {0x47742000}, {0x47744000}, {0x47746000}, + {0x47748000}, {0x4774a000}, {0x4774c000}, {0x4774e000}, + {0x47750000}, {0x47752000}, {0x47754000}, {0x47756000}, + {0x47758000}, {0x4775a000}, {0x4775c000}, {0x4775e000}, + {0x47760000}, {0x47762000}, {0x47764000}, {0x47766000}, + {0x47768000}, {0x4776a000}, {0x4776c000}, {0x4776e000}, + {0x47770000}, {0x47772000}, {0x47774000}, {0x47776000}, + {0x47778000}, {0x4777a000}, {0x4777c000}, {0x4777e000}, + {0x47780000}, {0x47782000}, {0x47784000}, {0x47786000}, + {0x47788000}, {0x4778a000}, {0x4778c000}, {0x4778e000}, + {0x47790000}, {0x47792000}, {0x47794000}, {0x47796000}, + {0x47798000}, {0x4779a000}, {0x4779c000}, {0x4779e000}, + {0x477a0000}, {0x477a2000}, {0x477a4000}, {0x477a6000}, + {0x477a8000}, {0x477aa000}, {0x477ac000}, {0x477ae000}, + {0x477b0000}, {0x477b2000}, {0x477b4000}, {0x477b6000}, + {0x477b8000}, {0x477ba000}, {0x477bc000}, {0x477be000}, + {0x477c0000}, {0x477c2000}, {0x477c4000}, {0x477c6000}, + {0x477c8000}, {0x477ca000}, {0x477cc000}, {0x477ce000}, + {0x477d0000}, {0x477d2000}, {0x477d4000}, {0x477d6000}, + {0x477d8000}, {0x477da000}, {0x477dc000}, {0x477de000}, + {0x477e0000}, {0x477e2000}, {0x477e4000}, {0x477e6000}, + {0x477e8000}, {0x477ea000}, {0x477ec000}, {0x477ee000}, + {0x477f0000}, {0x477f2000}, {0x477f4000}, {0x477f6000}, + {0x477f8000}, {0x477fa000}, {0x477fc000}, {0x477fe000}, + {0x7f800000}, {0x7f802000}, {0x7f804000}, {0x7f806000}, + {0x7f808000}, {0x7f80a000}, {0x7f80c000}, {0x7f80e000}, + {0x7f810000}, {0x7f812000}, {0x7f814000}, {0x7f816000}, + {0x7f818000}, {0x7f81a000}, {0x7f81c000}, {0x7f81e000}, + {0x7f820000}, {0x7f822000}, {0x7f824000}, {0x7f826000}, + {0x7f828000}, {0x7f82a000}, {0x7f82c000}, {0x7f82e000}, + {0x7f830000}, {0x7f832000}, {0x7f834000}, {0x7f836000}, + {0x7f838000}, {0x7f83a000}, {0x7f83c000}, {0x7f83e000}, + {0x7f840000}, {0x7f842000}, {0x7f844000}, {0x7f846000}, + {0x7f848000}, {0x7f84a000}, {0x7f84c000}, {0x7f84e000}, + {0x7f850000}, {0x7f852000}, {0x7f854000}, {0x7f856000}, + {0x7f858000}, {0x7f85a000}, {0x7f85c000}, {0x7f85e000}, + {0x7f860000}, {0x7f862000}, {0x7f864000}, {0x7f866000}, + {0x7f868000}, {0x7f86a000}, {0x7f86c000}, {0x7f86e000}, + {0x7f870000}, {0x7f872000}, {0x7f874000}, {0x7f876000}, + {0x7f878000}, {0x7f87a000}, {0x7f87c000}, {0x7f87e000}, + {0x7f880000}, {0x7f882000}, {0x7f884000}, {0x7f886000}, + {0x7f888000}, {0x7f88a000}, {0x7f88c000}, {0x7f88e000}, + {0x7f890000}, {0x7f892000}, {0x7f894000}, {0x7f896000}, + {0x7f898000}, {0x7f89a000}, {0x7f89c000}, {0x7f89e000}, + {0x7f8a0000}, {0x7f8a2000}, {0x7f8a4000}, {0x7f8a6000}, + {0x7f8a8000}, {0x7f8aa000}, {0x7f8ac000}, {0x7f8ae000}, + {0x7f8b0000}, {0x7f8b2000}, {0x7f8b4000}, {0x7f8b6000}, + {0x7f8b8000}, {0x7f8ba000}, {0x7f8bc000}, {0x7f8be000}, + {0x7f8c0000}, {0x7f8c2000}, {0x7f8c4000}, {0x7f8c6000}, + {0x7f8c8000}, {0x7f8ca000}, {0x7f8cc000}, {0x7f8ce000}, + {0x7f8d0000}, {0x7f8d2000}, {0x7f8d4000}, {0x7f8d6000}, + {0x7f8d8000}, {0x7f8da000}, {0x7f8dc000}, {0x7f8de000}, + {0x7f8e0000}, {0x7f8e2000}, {0x7f8e4000}, {0x7f8e6000}, + {0x7f8e8000}, {0x7f8ea000}, {0x7f8ec000}, {0x7f8ee000}, + {0x7f8f0000}, {0x7f8f2000}, {0x7f8f4000}, {0x7f8f6000}, + {0x7f8f8000}, {0x7f8fa000}, {0x7f8fc000}, {0x7f8fe000}, + {0x7f900000}, {0x7f902000}, {0x7f904000}, {0x7f906000}, + {0x7f908000}, {0x7f90a000}, {0x7f90c000}, {0x7f90e000}, + {0x7f910000}, {0x7f912000}, {0x7f914000}, {0x7f916000}, + {0x7f918000}, {0x7f91a000}, {0x7f91c000}, {0x7f91e000}, + {0x7f920000}, {0x7f922000}, {0x7f924000}, {0x7f926000}, + {0x7f928000}, {0x7f92a000}, {0x7f92c000}, {0x7f92e000}, + {0x7f930000}, {0x7f932000}, {0x7f934000}, {0x7f936000}, + {0x7f938000}, {0x7f93a000}, {0x7f93c000}, {0x7f93e000}, + {0x7f940000}, {0x7f942000}, {0x7f944000}, {0x7f946000}, + {0x7f948000}, {0x7f94a000}, {0x7f94c000}, {0x7f94e000}, + {0x7f950000}, {0x7f952000}, {0x7f954000}, {0x7f956000}, + {0x7f958000}, {0x7f95a000}, {0x7f95c000}, {0x7f95e000}, + {0x7f960000}, {0x7f962000}, {0x7f964000}, {0x7f966000}, + {0x7f968000}, {0x7f96a000}, {0x7f96c000}, {0x7f96e000}, + {0x7f970000}, {0x7f972000}, {0x7f974000}, {0x7f976000}, + {0x7f978000}, {0x7f97a000}, {0x7f97c000}, {0x7f97e000}, + {0x7f980000}, {0x7f982000}, {0x7f984000}, {0x7f986000}, + {0x7f988000}, {0x7f98a000}, {0x7f98c000}, {0x7f98e000}, + {0x7f990000}, {0x7f992000}, {0x7f994000}, {0x7f996000}, + {0x7f998000}, {0x7f99a000}, {0x7f99c000}, {0x7f99e000}, + {0x7f9a0000}, {0x7f9a2000}, {0x7f9a4000}, {0x7f9a6000}, + {0x7f9a8000}, {0x7f9aa000}, {0x7f9ac000}, {0x7f9ae000}, + {0x7f9b0000}, {0x7f9b2000}, {0x7f9b4000}, {0x7f9b6000}, + {0x7f9b8000}, {0x7f9ba000}, {0x7f9bc000}, {0x7f9be000}, + {0x7f9c0000}, {0x7f9c2000}, {0x7f9c4000}, {0x7f9c6000}, + {0x7f9c8000}, {0x7f9ca000}, {0x7f9cc000}, {0x7f9ce000}, + {0x7f9d0000}, {0x7f9d2000}, {0x7f9d4000}, {0x7f9d6000}, + {0x7f9d8000}, {0x7f9da000}, {0x7f9dc000}, {0x7f9de000}, + {0x7f9e0000}, {0x7f9e2000}, {0x7f9e4000}, {0x7f9e6000}, + {0x7f9e8000}, {0x7f9ea000}, {0x7f9ec000}, {0x7f9ee000}, + {0x7f9f0000}, {0x7f9f2000}, {0x7f9f4000}, {0x7f9f6000}, + {0x7f9f8000}, {0x7f9fa000}, {0x7f9fc000}, {0x7f9fe000}, + {0x7fa00000}, {0x7fa02000}, {0x7fa04000}, {0x7fa06000}, + {0x7fa08000}, {0x7fa0a000}, {0x7fa0c000}, {0x7fa0e000}, + {0x7fa10000}, {0x7fa12000}, {0x7fa14000}, {0x7fa16000}, + {0x7fa18000}, {0x7fa1a000}, {0x7fa1c000}, {0x7fa1e000}, + {0x7fa20000}, {0x7fa22000}, {0x7fa24000}, {0x7fa26000}, + {0x7fa28000}, {0x7fa2a000}, {0x7fa2c000}, {0x7fa2e000}, + {0x7fa30000}, {0x7fa32000}, {0x7fa34000}, {0x7fa36000}, + {0x7fa38000}, {0x7fa3a000}, {0x7fa3c000}, {0x7fa3e000}, + {0x7fa40000}, {0x7fa42000}, {0x7fa44000}, {0x7fa46000}, + {0x7fa48000}, {0x7fa4a000}, {0x7fa4c000}, {0x7fa4e000}, + {0x7fa50000}, {0x7fa52000}, {0x7fa54000}, {0x7fa56000}, + {0x7fa58000}, {0x7fa5a000}, {0x7fa5c000}, {0x7fa5e000}, + {0x7fa60000}, {0x7fa62000}, {0x7fa64000}, {0x7fa66000}, + {0x7fa68000}, {0x7fa6a000}, {0x7fa6c000}, {0x7fa6e000}, + {0x7fa70000}, {0x7fa72000}, {0x7fa74000}, {0x7fa76000}, + {0x7fa78000}, {0x7fa7a000}, {0x7fa7c000}, {0x7fa7e000}, + {0x7fa80000}, {0x7fa82000}, {0x7fa84000}, {0x7fa86000}, + {0x7fa88000}, {0x7fa8a000}, {0x7fa8c000}, {0x7fa8e000}, + {0x7fa90000}, {0x7fa92000}, {0x7fa94000}, {0x7fa96000}, + {0x7fa98000}, {0x7fa9a000}, {0x7fa9c000}, {0x7fa9e000}, + {0x7faa0000}, {0x7faa2000}, {0x7faa4000}, {0x7faa6000}, + {0x7faa8000}, {0x7faaa000}, {0x7faac000}, {0x7faae000}, + {0x7fab0000}, {0x7fab2000}, {0x7fab4000}, {0x7fab6000}, + {0x7fab8000}, {0x7faba000}, {0x7fabc000}, {0x7fabe000}, + {0x7fac0000}, {0x7fac2000}, {0x7fac4000}, {0x7fac6000}, + {0x7fac8000}, {0x7faca000}, {0x7facc000}, {0x7face000}, + {0x7fad0000}, {0x7fad2000}, {0x7fad4000}, {0x7fad6000}, + {0x7fad8000}, {0x7fada000}, {0x7fadc000}, {0x7fade000}, + {0x7fae0000}, {0x7fae2000}, {0x7fae4000}, {0x7fae6000}, + {0x7fae8000}, {0x7faea000}, {0x7faec000}, {0x7faee000}, + {0x7faf0000}, {0x7faf2000}, {0x7faf4000}, {0x7faf6000}, + {0x7faf8000}, {0x7fafa000}, {0x7fafc000}, {0x7fafe000}, + {0x7fb00000}, {0x7fb02000}, {0x7fb04000}, {0x7fb06000}, + {0x7fb08000}, {0x7fb0a000}, {0x7fb0c000}, {0x7fb0e000}, + {0x7fb10000}, {0x7fb12000}, {0x7fb14000}, {0x7fb16000}, + {0x7fb18000}, {0x7fb1a000}, {0x7fb1c000}, {0x7fb1e000}, + {0x7fb20000}, {0x7fb22000}, {0x7fb24000}, {0x7fb26000}, + {0x7fb28000}, {0x7fb2a000}, {0x7fb2c000}, {0x7fb2e000}, + {0x7fb30000}, {0x7fb32000}, {0x7fb34000}, {0x7fb36000}, + {0x7fb38000}, {0x7fb3a000}, {0x7fb3c000}, {0x7fb3e000}, + {0x7fb40000}, {0x7fb42000}, {0x7fb44000}, {0x7fb46000}, + {0x7fb48000}, {0x7fb4a000}, {0x7fb4c000}, {0x7fb4e000}, + {0x7fb50000}, {0x7fb52000}, {0x7fb54000}, {0x7fb56000}, + {0x7fb58000}, {0x7fb5a000}, {0x7fb5c000}, {0x7fb5e000}, + {0x7fb60000}, {0x7fb62000}, {0x7fb64000}, {0x7fb66000}, + {0x7fb68000}, {0x7fb6a000}, {0x7fb6c000}, {0x7fb6e000}, + {0x7fb70000}, {0x7fb72000}, {0x7fb74000}, {0x7fb76000}, + {0x7fb78000}, {0x7fb7a000}, {0x7fb7c000}, {0x7fb7e000}, + {0x7fb80000}, {0x7fb82000}, {0x7fb84000}, {0x7fb86000}, + {0x7fb88000}, {0x7fb8a000}, {0x7fb8c000}, {0x7fb8e000}, + {0x7fb90000}, {0x7fb92000}, {0x7fb94000}, {0x7fb96000}, + {0x7fb98000}, {0x7fb9a000}, {0x7fb9c000}, {0x7fb9e000}, + {0x7fba0000}, {0x7fba2000}, {0x7fba4000}, {0x7fba6000}, + {0x7fba8000}, {0x7fbaa000}, {0x7fbac000}, {0x7fbae000}, + {0x7fbb0000}, {0x7fbb2000}, {0x7fbb4000}, {0x7fbb6000}, + {0x7fbb8000}, {0x7fbba000}, {0x7fbbc000}, {0x7fbbe000}, + {0x7fbc0000}, {0x7fbc2000}, {0x7fbc4000}, {0x7fbc6000}, + {0x7fbc8000}, {0x7fbca000}, {0x7fbcc000}, {0x7fbce000}, + {0x7fbd0000}, {0x7fbd2000}, {0x7fbd4000}, {0x7fbd6000}, + {0x7fbd8000}, {0x7fbda000}, {0x7fbdc000}, {0x7fbde000}, + {0x7fbe0000}, {0x7fbe2000}, {0x7fbe4000}, {0x7fbe6000}, + {0x7fbe8000}, {0x7fbea000}, {0x7fbec000}, {0x7fbee000}, + {0x7fbf0000}, {0x7fbf2000}, {0x7fbf4000}, {0x7fbf6000}, + {0x7fbf8000}, {0x7fbfa000}, {0x7fbfc000}, {0x7fbfe000}, + {0x7fc00000}, {0x7fc02000}, {0x7fc04000}, {0x7fc06000}, + {0x7fc08000}, {0x7fc0a000}, {0x7fc0c000}, {0x7fc0e000}, + {0x7fc10000}, {0x7fc12000}, {0x7fc14000}, {0x7fc16000}, + {0x7fc18000}, {0x7fc1a000}, {0x7fc1c000}, {0x7fc1e000}, + {0x7fc20000}, {0x7fc22000}, {0x7fc24000}, {0x7fc26000}, + {0x7fc28000}, {0x7fc2a000}, {0x7fc2c000}, {0x7fc2e000}, + {0x7fc30000}, {0x7fc32000}, {0x7fc34000}, {0x7fc36000}, + {0x7fc38000}, {0x7fc3a000}, {0x7fc3c000}, {0x7fc3e000}, + {0x7fc40000}, {0x7fc42000}, {0x7fc44000}, {0x7fc46000}, + {0x7fc48000}, {0x7fc4a000}, {0x7fc4c000}, {0x7fc4e000}, + {0x7fc50000}, {0x7fc52000}, {0x7fc54000}, {0x7fc56000}, + {0x7fc58000}, {0x7fc5a000}, {0x7fc5c000}, {0x7fc5e000}, + {0x7fc60000}, {0x7fc62000}, {0x7fc64000}, {0x7fc66000}, + {0x7fc68000}, {0x7fc6a000}, {0x7fc6c000}, {0x7fc6e000}, + {0x7fc70000}, {0x7fc72000}, {0x7fc74000}, {0x7fc76000}, + {0x7fc78000}, {0x7fc7a000}, {0x7fc7c000}, {0x7fc7e000}, + {0x7fc80000}, {0x7fc82000}, {0x7fc84000}, {0x7fc86000}, + {0x7fc88000}, {0x7fc8a000}, {0x7fc8c000}, {0x7fc8e000}, + {0x7fc90000}, {0x7fc92000}, {0x7fc94000}, {0x7fc96000}, + {0x7fc98000}, {0x7fc9a000}, {0x7fc9c000}, {0x7fc9e000}, + {0x7fca0000}, {0x7fca2000}, {0x7fca4000}, {0x7fca6000}, + {0x7fca8000}, {0x7fcaa000}, {0x7fcac000}, {0x7fcae000}, + {0x7fcb0000}, {0x7fcb2000}, {0x7fcb4000}, {0x7fcb6000}, + {0x7fcb8000}, {0x7fcba000}, {0x7fcbc000}, {0x7fcbe000}, + {0x7fcc0000}, {0x7fcc2000}, {0x7fcc4000}, {0x7fcc6000}, + {0x7fcc8000}, {0x7fcca000}, {0x7fccc000}, {0x7fcce000}, + {0x7fcd0000}, {0x7fcd2000}, {0x7fcd4000}, {0x7fcd6000}, + {0x7fcd8000}, {0x7fcda000}, {0x7fcdc000}, {0x7fcde000}, + {0x7fce0000}, {0x7fce2000}, {0x7fce4000}, {0x7fce6000}, + {0x7fce8000}, {0x7fcea000}, {0x7fcec000}, {0x7fcee000}, + {0x7fcf0000}, {0x7fcf2000}, {0x7fcf4000}, {0x7fcf6000}, + {0x7fcf8000}, {0x7fcfa000}, {0x7fcfc000}, {0x7fcfe000}, + {0x7fd00000}, {0x7fd02000}, {0x7fd04000}, {0x7fd06000}, + {0x7fd08000}, {0x7fd0a000}, {0x7fd0c000}, {0x7fd0e000}, + {0x7fd10000}, {0x7fd12000}, {0x7fd14000}, {0x7fd16000}, + {0x7fd18000}, {0x7fd1a000}, {0x7fd1c000}, {0x7fd1e000}, + {0x7fd20000}, {0x7fd22000}, {0x7fd24000}, {0x7fd26000}, + {0x7fd28000}, {0x7fd2a000}, {0x7fd2c000}, {0x7fd2e000}, + {0x7fd30000}, {0x7fd32000}, {0x7fd34000}, {0x7fd36000}, + {0x7fd38000}, {0x7fd3a000}, {0x7fd3c000}, {0x7fd3e000}, + {0x7fd40000}, {0x7fd42000}, {0x7fd44000}, {0x7fd46000}, + {0x7fd48000}, {0x7fd4a000}, {0x7fd4c000}, {0x7fd4e000}, + {0x7fd50000}, {0x7fd52000}, {0x7fd54000}, {0x7fd56000}, + {0x7fd58000}, {0x7fd5a000}, {0x7fd5c000}, {0x7fd5e000}, + {0x7fd60000}, {0x7fd62000}, {0x7fd64000}, {0x7fd66000}, + {0x7fd68000}, {0x7fd6a000}, {0x7fd6c000}, {0x7fd6e000}, + {0x7fd70000}, {0x7fd72000}, {0x7fd74000}, {0x7fd76000}, + {0x7fd78000}, {0x7fd7a000}, {0x7fd7c000}, {0x7fd7e000}, + {0x7fd80000}, {0x7fd82000}, {0x7fd84000}, {0x7fd86000}, + {0x7fd88000}, {0x7fd8a000}, {0x7fd8c000}, {0x7fd8e000}, + {0x7fd90000}, {0x7fd92000}, {0x7fd94000}, {0x7fd96000}, + {0x7fd98000}, {0x7fd9a000}, {0x7fd9c000}, {0x7fd9e000}, + {0x7fda0000}, {0x7fda2000}, {0x7fda4000}, {0x7fda6000}, + {0x7fda8000}, {0x7fdaa000}, {0x7fdac000}, {0x7fdae000}, + {0x7fdb0000}, {0x7fdb2000}, {0x7fdb4000}, {0x7fdb6000}, + {0x7fdb8000}, {0x7fdba000}, {0x7fdbc000}, {0x7fdbe000}, + {0x7fdc0000}, {0x7fdc2000}, {0x7fdc4000}, {0x7fdc6000}, + {0x7fdc8000}, {0x7fdca000}, {0x7fdcc000}, {0x7fdce000}, + {0x7fdd0000}, {0x7fdd2000}, {0x7fdd4000}, {0x7fdd6000}, + {0x7fdd8000}, {0x7fdda000}, {0x7fddc000}, {0x7fdde000}, + {0x7fde0000}, {0x7fde2000}, {0x7fde4000}, {0x7fde6000}, + {0x7fde8000}, {0x7fdea000}, {0x7fdec000}, {0x7fdee000}, + {0x7fdf0000}, {0x7fdf2000}, {0x7fdf4000}, {0x7fdf6000}, + {0x7fdf8000}, {0x7fdfa000}, {0x7fdfc000}, {0x7fdfe000}, + {0x7fe00000}, {0x7fe02000}, {0x7fe04000}, {0x7fe06000}, + {0x7fe08000}, {0x7fe0a000}, {0x7fe0c000}, {0x7fe0e000}, + {0x7fe10000}, {0x7fe12000}, {0x7fe14000}, {0x7fe16000}, + {0x7fe18000}, {0x7fe1a000}, {0x7fe1c000}, {0x7fe1e000}, + {0x7fe20000}, {0x7fe22000}, {0x7fe24000}, {0x7fe26000}, + {0x7fe28000}, {0x7fe2a000}, {0x7fe2c000}, {0x7fe2e000}, + {0x7fe30000}, {0x7fe32000}, {0x7fe34000}, {0x7fe36000}, + {0x7fe38000}, {0x7fe3a000}, {0x7fe3c000}, {0x7fe3e000}, + {0x7fe40000}, {0x7fe42000}, {0x7fe44000}, {0x7fe46000}, + {0x7fe48000}, {0x7fe4a000}, {0x7fe4c000}, {0x7fe4e000}, + {0x7fe50000}, {0x7fe52000}, {0x7fe54000}, {0x7fe56000}, + {0x7fe58000}, {0x7fe5a000}, {0x7fe5c000}, {0x7fe5e000}, + {0x7fe60000}, {0x7fe62000}, {0x7fe64000}, {0x7fe66000}, + {0x7fe68000}, {0x7fe6a000}, {0x7fe6c000}, {0x7fe6e000}, + {0x7fe70000}, {0x7fe72000}, {0x7fe74000}, {0x7fe76000}, + {0x7fe78000}, {0x7fe7a000}, {0x7fe7c000}, {0x7fe7e000}, + {0x7fe80000}, {0x7fe82000}, {0x7fe84000}, {0x7fe86000}, + {0x7fe88000}, {0x7fe8a000}, {0x7fe8c000}, {0x7fe8e000}, + {0x7fe90000}, {0x7fe92000}, {0x7fe94000}, {0x7fe96000}, + {0x7fe98000}, {0x7fe9a000}, {0x7fe9c000}, {0x7fe9e000}, + {0x7fea0000}, {0x7fea2000}, {0x7fea4000}, {0x7fea6000}, + {0x7fea8000}, {0x7feaa000}, {0x7feac000}, {0x7feae000}, + {0x7feb0000}, {0x7feb2000}, {0x7feb4000}, {0x7feb6000}, + {0x7feb8000}, {0x7feba000}, {0x7febc000}, {0x7febe000}, + {0x7fec0000}, {0x7fec2000}, {0x7fec4000}, {0x7fec6000}, + {0x7fec8000}, {0x7feca000}, {0x7fecc000}, {0x7fece000}, + {0x7fed0000}, {0x7fed2000}, {0x7fed4000}, {0x7fed6000}, + {0x7fed8000}, {0x7feda000}, {0x7fedc000}, {0x7fede000}, + {0x7fee0000}, {0x7fee2000}, {0x7fee4000}, {0x7fee6000}, + {0x7fee8000}, {0x7feea000}, {0x7feec000}, {0x7feee000}, + {0x7fef0000}, {0x7fef2000}, {0x7fef4000}, {0x7fef6000}, + {0x7fef8000}, {0x7fefa000}, {0x7fefc000}, {0x7fefe000}, + {0x7ff00000}, {0x7ff02000}, {0x7ff04000}, {0x7ff06000}, + {0x7ff08000}, {0x7ff0a000}, {0x7ff0c000}, {0x7ff0e000}, + {0x7ff10000}, {0x7ff12000}, {0x7ff14000}, {0x7ff16000}, + {0x7ff18000}, {0x7ff1a000}, {0x7ff1c000}, {0x7ff1e000}, + {0x7ff20000}, {0x7ff22000}, {0x7ff24000}, {0x7ff26000}, + {0x7ff28000}, {0x7ff2a000}, {0x7ff2c000}, {0x7ff2e000}, + {0x7ff30000}, {0x7ff32000}, {0x7ff34000}, {0x7ff36000}, + {0x7ff38000}, {0x7ff3a000}, {0x7ff3c000}, {0x7ff3e000}, + {0x7ff40000}, {0x7ff42000}, {0x7ff44000}, {0x7ff46000}, + {0x7ff48000}, {0x7ff4a000}, {0x7ff4c000}, {0x7ff4e000}, + {0x7ff50000}, {0x7ff52000}, {0x7ff54000}, {0x7ff56000}, + {0x7ff58000}, {0x7ff5a000}, {0x7ff5c000}, {0x7ff5e000}, + {0x7ff60000}, {0x7ff62000}, {0x7ff64000}, {0x7ff66000}, + {0x7ff68000}, {0x7ff6a000}, {0x7ff6c000}, {0x7ff6e000}, + {0x7ff70000}, {0x7ff72000}, {0x7ff74000}, {0x7ff76000}, + {0x7ff78000}, {0x7ff7a000}, {0x7ff7c000}, {0x7ff7e000}, + {0x7ff80000}, {0x7ff82000}, {0x7ff84000}, {0x7ff86000}, + {0x7ff88000}, {0x7ff8a000}, {0x7ff8c000}, {0x7ff8e000}, + {0x7ff90000}, {0x7ff92000}, {0x7ff94000}, {0x7ff96000}, + {0x7ff98000}, {0x7ff9a000}, {0x7ff9c000}, {0x7ff9e000}, + {0x7ffa0000}, {0x7ffa2000}, {0x7ffa4000}, {0x7ffa6000}, + {0x7ffa8000}, {0x7ffaa000}, {0x7ffac000}, {0x7ffae000}, + {0x7ffb0000}, {0x7ffb2000}, {0x7ffb4000}, {0x7ffb6000}, + {0x7ffb8000}, {0x7ffba000}, {0x7ffbc000}, {0x7ffbe000}, + {0x7ffc0000}, {0x7ffc2000}, {0x7ffc4000}, {0x7ffc6000}, + {0x7ffc8000}, {0x7ffca000}, {0x7ffcc000}, {0x7ffce000}, + {0x7ffd0000}, {0x7ffd2000}, {0x7ffd4000}, {0x7ffd6000}, + {0x7ffd8000}, {0x7ffda000}, {0x7ffdc000}, {0x7ffde000}, + {0x7ffe0000}, {0x7ffe2000}, {0x7ffe4000}, {0x7ffe6000}, + {0x7ffe8000}, {0x7ffea000}, {0x7ffec000}, {0x7ffee000}, + {0x7fff0000}, {0x7fff2000}, {0x7fff4000}, {0x7fff6000}, + {0x7fff8000}, {0x7fffa000}, {0x7fffc000}, {0x7fffe000}, + {0x80000000}, {0xb3800000}, {0xb4000000}, {0xb4400000}, + {0xb4800000}, {0xb4a00000}, {0xb4c00000}, {0xb4e00000}, + {0xb5000000}, {0xb5100000}, {0xb5200000}, {0xb5300000}, + {0xb5400000}, {0xb5500000}, {0xb5600000}, {0xb5700000}, + {0xb5800000}, {0xb5880000}, {0xb5900000}, {0xb5980000}, + {0xb5a00000}, {0xb5a80000}, {0xb5b00000}, {0xb5b80000}, + {0xb5c00000}, {0xb5c80000}, {0xb5d00000}, {0xb5d80000}, + {0xb5e00000}, {0xb5e80000}, {0xb5f00000}, {0xb5f80000}, + {0xb6000000}, {0xb6040000}, {0xb6080000}, {0xb60c0000}, + {0xb6100000}, {0xb6140000}, {0xb6180000}, {0xb61c0000}, + {0xb6200000}, {0xb6240000}, {0xb6280000}, {0xb62c0000}, + {0xb6300000}, {0xb6340000}, {0xb6380000}, {0xb63c0000}, + {0xb6400000}, {0xb6440000}, {0xb6480000}, {0xb64c0000}, + {0xb6500000}, {0xb6540000}, {0xb6580000}, {0xb65c0000}, + {0xb6600000}, {0xb6640000}, {0xb6680000}, {0xb66c0000}, + {0xb6700000}, {0xb6740000}, {0xb6780000}, {0xb67c0000}, + {0xb6800000}, {0xb6820000}, {0xb6840000}, {0xb6860000}, + {0xb6880000}, {0xb68a0000}, {0xb68c0000}, {0xb68e0000}, + {0xb6900000}, {0xb6920000}, {0xb6940000}, {0xb6960000}, + {0xb6980000}, {0xb69a0000}, {0xb69c0000}, {0xb69e0000}, + {0xb6a00000}, {0xb6a20000}, {0xb6a40000}, {0xb6a60000}, + {0xb6a80000}, {0xb6aa0000}, {0xb6ac0000}, {0xb6ae0000}, + {0xb6b00000}, {0xb6b20000}, {0xb6b40000}, {0xb6b60000}, + {0xb6b80000}, {0xb6ba0000}, {0xb6bc0000}, {0xb6be0000}, + {0xb6c00000}, {0xb6c20000}, {0xb6c40000}, {0xb6c60000}, + {0xb6c80000}, {0xb6ca0000}, {0xb6cc0000}, {0xb6ce0000}, + {0xb6d00000}, {0xb6d20000}, {0xb6d40000}, {0xb6d60000}, + {0xb6d80000}, {0xb6da0000}, {0xb6dc0000}, {0xb6de0000}, + {0xb6e00000}, {0xb6e20000}, {0xb6e40000}, {0xb6e60000}, + {0xb6e80000}, {0xb6ea0000}, {0xb6ec0000}, {0xb6ee0000}, + {0xb6f00000}, {0xb6f20000}, {0xb6f40000}, {0xb6f60000}, + {0xb6f80000}, {0xb6fa0000}, {0xb6fc0000}, {0xb6fe0000}, + {0xb7000000}, {0xb7010000}, {0xb7020000}, {0xb7030000}, + {0xb7040000}, {0xb7050000}, {0xb7060000}, {0xb7070000}, + {0xb7080000}, {0xb7090000}, {0xb70a0000}, {0xb70b0000}, + {0xb70c0000}, {0xb70d0000}, {0xb70e0000}, {0xb70f0000}, + {0xb7100000}, {0xb7110000}, {0xb7120000}, {0xb7130000}, + {0xb7140000}, {0xb7150000}, {0xb7160000}, {0xb7170000}, + {0xb7180000}, {0xb7190000}, {0xb71a0000}, {0xb71b0000}, + {0xb71c0000}, {0xb71d0000}, {0xb71e0000}, {0xb71f0000}, + {0xb7200000}, {0xb7210000}, {0xb7220000}, {0xb7230000}, + {0xb7240000}, {0xb7250000}, {0xb7260000}, {0xb7270000}, + {0xb7280000}, {0xb7290000}, {0xb72a0000}, {0xb72b0000}, + {0xb72c0000}, {0xb72d0000}, {0xb72e0000}, {0xb72f0000}, + {0xb7300000}, {0xb7310000}, {0xb7320000}, {0xb7330000}, + {0xb7340000}, {0xb7350000}, {0xb7360000}, {0xb7370000}, + {0xb7380000}, {0xb7390000}, {0xb73a0000}, {0xb73b0000}, + {0xb73c0000}, {0xb73d0000}, {0xb73e0000}, {0xb73f0000}, + {0xb7400000}, {0xb7410000}, {0xb7420000}, {0xb7430000}, + {0xb7440000}, {0xb7450000}, {0xb7460000}, {0xb7470000}, + {0xb7480000}, {0xb7490000}, {0xb74a0000}, {0xb74b0000}, + {0xb74c0000}, {0xb74d0000}, {0xb74e0000}, {0xb74f0000}, + {0xb7500000}, {0xb7510000}, {0xb7520000}, {0xb7530000}, + {0xb7540000}, {0xb7550000}, {0xb7560000}, {0xb7570000}, + {0xb7580000}, {0xb7590000}, {0xb75a0000}, {0xb75b0000}, + {0xb75c0000}, {0xb75d0000}, {0xb75e0000}, {0xb75f0000}, + {0xb7600000}, {0xb7610000}, {0xb7620000}, {0xb7630000}, + {0xb7640000}, {0xb7650000}, {0xb7660000}, {0xb7670000}, + {0xb7680000}, {0xb7690000}, {0xb76a0000}, {0xb76b0000}, + {0xb76c0000}, {0xb76d0000}, {0xb76e0000}, {0xb76f0000}, + {0xb7700000}, {0xb7710000}, {0xb7720000}, {0xb7730000}, + {0xb7740000}, {0xb7750000}, {0xb7760000}, {0xb7770000}, + {0xb7780000}, {0xb7790000}, {0xb77a0000}, {0xb77b0000}, + {0xb77c0000}, {0xb77d0000}, {0xb77e0000}, {0xb77f0000}, + {0xb7800000}, {0xb7808000}, {0xb7810000}, {0xb7818000}, + {0xb7820000}, {0xb7828000}, {0xb7830000}, {0xb7838000}, + {0xb7840000}, {0xb7848000}, {0xb7850000}, {0xb7858000}, + {0xb7860000}, {0xb7868000}, {0xb7870000}, {0xb7878000}, + {0xb7880000}, {0xb7888000}, {0xb7890000}, {0xb7898000}, + {0xb78a0000}, {0xb78a8000}, {0xb78b0000}, {0xb78b8000}, + {0xb78c0000}, {0xb78c8000}, {0xb78d0000}, {0xb78d8000}, + {0xb78e0000}, {0xb78e8000}, {0xb78f0000}, {0xb78f8000}, + {0xb7900000}, {0xb7908000}, {0xb7910000}, {0xb7918000}, + {0xb7920000}, {0xb7928000}, {0xb7930000}, {0xb7938000}, + {0xb7940000}, {0xb7948000}, {0xb7950000}, {0xb7958000}, + {0xb7960000}, {0xb7968000}, {0xb7970000}, {0xb7978000}, + {0xb7980000}, {0xb7988000}, {0xb7990000}, {0xb7998000}, + {0xb79a0000}, {0xb79a8000}, {0xb79b0000}, {0xb79b8000}, + {0xb79c0000}, {0xb79c8000}, {0xb79d0000}, {0xb79d8000}, + {0xb79e0000}, {0xb79e8000}, {0xb79f0000}, {0xb79f8000}, + {0xb7a00000}, {0xb7a08000}, {0xb7a10000}, {0xb7a18000}, + {0xb7a20000}, {0xb7a28000}, {0xb7a30000}, {0xb7a38000}, + {0xb7a40000}, {0xb7a48000}, {0xb7a50000}, {0xb7a58000}, + {0xb7a60000}, {0xb7a68000}, {0xb7a70000}, {0xb7a78000}, + {0xb7a80000}, {0xb7a88000}, {0xb7a90000}, {0xb7a98000}, + {0xb7aa0000}, {0xb7aa8000}, {0xb7ab0000}, {0xb7ab8000}, + {0xb7ac0000}, {0xb7ac8000}, {0xb7ad0000}, {0xb7ad8000}, + {0xb7ae0000}, {0xb7ae8000}, {0xb7af0000}, {0xb7af8000}, + {0xb7b00000}, {0xb7b08000}, {0xb7b10000}, {0xb7b18000}, + {0xb7b20000}, {0xb7b28000}, {0xb7b30000}, {0xb7b38000}, + {0xb7b40000}, {0xb7b48000}, {0xb7b50000}, {0xb7b58000}, + {0xb7b60000}, {0xb7b68000}, {0xb7b70000}, {0xb7b78000}, + {0xb7b80000}, {0xb7b88000}, {0xb7b90000}, {0xb7b98000}, + {0xb7ba0000}, {0xb7ba8000}, {0xb7bb0000}, {0xb7bb8000}, + {0xb7bc0000}, {0xb7bc8000}, {0xb7bd0000}, {0xb7bd8000}, + {0xb7be0000}, {0xb7be8000}, {0xb7bf0000}, {0xb7bf8000}, + {0xb7c00000}, {0xb7c08000}, {0xb7c10000}, {0xb7c18000}, + {0xb7c20000}, {0xb7c28000}, {0xb7c30000}, {0xb7c38000}, + {0xb7c40000}, {0xb7c48000}, {0xb7c50000}, {0xb7c58000}, + {0xb7c60000}, {0xb7c68000}, {0xb7c70000}, {0xb7c78000}, + {0xb7c80000}, {0xb7c88000}, {0xb7c90000}, {0xb7c98000}, + {0xb7ca0000}, {0xb7ca8000}, {0xb7cb0000}, {0xb7cb8000}, + {0xb7cc0000}, {0xb7cc8000}, {0xb7cd0000}, {0xb7cd8000}, + {0xb7ce0000}, {0xb7ce8000}, {0xb7cf0000}, {0xb7cf8000}, + {0xb7d00000}, {0xb7d08000}, {0xb7d10000}, {0xb7d18000}, + {0xb7d20000}, {0xb7d28000}, {0xb7d30000}, {0xb7d38000}, + {0xb7d40000}, {0xb7d48000}, {0xb7d50000}, {0xb7d58000}, + {0xb7d60000}, {0xb7d68000}, {0xb7d70000}, {0xb7d78000}, + {0xb7d80000}, {0xb7d88000}, {0xb7d90000}, {0xb7d98000}, + {0xb7da0000}, {0xb7da8000}, {0xb7db0000}, {0xb7db8000}, + {0xb7dc0000}, {0xb7dc8000}, {0xb7dd0000}, {0xb7dd8000}, + {0xb7de0000}, {0xb7de8000}, {0xb7df0000}, {0xb7df8000}, + {0xb7e00000}, {0xb7e08000}, {0xb7e10000}, {0xb7e18000}, + {0xb7e20000}, {0xb7e28000}, {0xb7e30000}, {0xb7e38000}, + {0xb7e40000}, {0xb7e48000}, {0xb7e50000}, {0xb7e58000}, + {0xb7e60000}, {0xb7e68000}, {0xb7e70000}, {0xb7e78000}, + {0xb7e80000}, {0xb7e88000}, {0xb7e90000}, {0xb7e98000}, + {0xb7ea0000}, {0xb7ea8000}, {0xb7eb0000}, {0xb7eb8000}, + {0xb7ec0000}, {0xb7ec8000}, {0xb7ed0000}, {0xb7ed8000}, + {0xb7ee0000}, {0xb7ee8000}, {0xb7ef0000}, {0xb7ef8000}, + {0xb7f00000}, {0xb7f08000}, {0xb7f10000}, {0xb7f18000}, + {0xb7f20000}, {0xb7f28000}, {0xb7f30000}, {0xb7f38000}, + {0xb7f40000}, {0xb7f48000}, {0xb7f50000}, {0xb7f58000}, + {0xb7f60000}, {0xb7f68000}, {0xb7f70000}, {0xb7f78000}, + {0xb7f80000}, {0xb7f88000}, {0xb7f90000}, {0xb7f98000}, + {0xb7fa0000}, {0xb7fa8000}, {0xb7fb0000}, {0xb7fb8000}, + {0xb7fc0000}, {0xb7fc8000}, {0xb7fd0000}, {0xb7fd8000}, + {0xb7fe0000}, {0xb7fe8000}, {0xb7ff0000}, {0xb7ff8000}, + {0xb8000000}, {0xb8004000}, {0xb8008000}, {0xb800c000}, + {0xb8010000}, {0xb8014000}, {0xb8018000}, {0xb801c000}, + {0xb8020000}, {0xb8024000}, {0xb8028000}, {0xb802c000}, + {0xb8030000}, {0xb8034000}, {0xb8038000}, {0xb803c000}, + {0xb8040000}, {0xb8044000}, {0xb8048000}, {0xb804c000}, + {0xb8050000}, {0xb8054000}, {0xb8058000}, {0xb805c000}, + {0xb8060000}, {0xb8064000}, {0xb8068000}, {0xb806c000}, + {0xb8070000}, {0xb8074000}, {0xb8078000}, {0xb807c000}, + {0xb8080000}, {0xb8084000}, {0xb8088000}, {0xb808c000}, + {0xb8090000}, {0xb8094000}, {0xb8098000}, {0xb809c000}, + {0xb80a0000}, {0xb80a4000}, {0xb80a8000}, {0xb80ac000}, + {0xb80b0000}, {0xb80b4000}, {0xb80b8000}, {0xb80bc000}, + {0xb80c0000}, {0xb80c4000}, {0xb80c8000}, {0xb80cc000}, + {0xb80d0000}, {0xb80d4000}, {0xb80d8000}, {0xb80dc000}, + {0xb80e0000}, {0xb80e4000}, {0xb80e8000}, {0xb80ec000}, + {0xb80f0000}, {0xb80f4000}, {0xb80f8000}, {0xb80fc000}, + {0xb8100000}, {0xb8104000}, {0xb8108000}, {0xb810c000}, + {0xb8110000}, {0xb8114000}, {0xb8118000}, {0xb811c000}, + {0xb8120000}, {0xb8124000}, {0xb8128000}, {0xb812c000}, + {0xb8130000}, {0xb8134000}, {0xb8138000}, {0xb813c000}, + {0xb8140000}, {0xb8144000}, {0xb8148000}, {0xb814c000}, + {0xb8150000}, {0xb8154000}, {0xb8158000}, {0xb815c000}, + {0xb8160000}, {0xb8164000}, {0xb8168000}, {0xb816c000}, + {0xb8170000}, {0xb8174000}, {0xb8178000}, {0xb817c000}, + {0xb8180000}, {0xb8184000}, {0xb8188000}, {0xb818c000}, + {0xb8190000}, {0xb8194000}, {0xb8198000}, {0xb819c000}, + {0xb81a0000}, {0xb81a4000}, {0xb81a8000}, {0xb81ac000}, + {0xb81b0000}, {0xb81b4000}, {0xb81b8000}, {0xb81bc000}, + {0xb81c0000}, {0xb81c4000}, {0xb81c8000}, {0xb81cc000}, + {0xb81d0000}, {0xb81d4000}, {0xb81d8000}, {0xb81dc000}, + {0xb81e0000}, {0xb81e4000}, {0xb81e8000}, {0xb81ec000}, + {0xb81f0000}, {0xb81f4000}, {0xb81f8000}, {0xb81fc000}, + {0xb8200000}, {0xb8204000}, {0xb8208000}, {0xb820c000}, + {0xb8210000}, {0xb8214000}, {0xb8218000}, {0xb821c000}, + {0xb8220000}, {0xb8224000}, {0xb8228000}, {0xb822c000}, + {0xb8230000}, {0xb8234000}, {0xb8238000}, {0xb823c000}, + {0xb8240000}, {0xb8244000}, {0xb8248000}, {0xb824c000}, + {0xb8250000}, {0xb8254000}, {0xb8258000}, {0xb825c000}, + {0xb8260000}, {0xb8264000}, {0xb8268000}, {0xb826c000}, + {0xb8270000}, {0xb8274000}, {0xb8278000}, {0xb827c000}, + {0xb8280000}, {0xb8284000}, {0xb8288000}, {0xb828c000}, + {0xb8290000}, {0xb8294000}, {0xb8298000}, {0xb829c000}, + {0xb82a0000}, {0xb82a4000}, {0xb82a8000}, {0xb82ac000}, + {0xb82b0000}, {0xb82b4000}, {0xb82b8000}, {0xb82bc000}, + {0xb82c0000}, {0xb82c4000}, {0xb82c8000}, {0xb82cc000}, + {0xb82d0000}, {0xb82d4000}, {0xb82d8000}, {0xb82dc000}, + {0xb82e0000}, {0xb82e4000}, {0xb82e8000}, {0xb82ec000}, + {0xb82f0000}, {0xb82f4000}, {0xb82f8000}, {0xb82fc000}, + {0xb8300000}, {0xb8304000}, {0xb8308000}, {0xb830c000}, + {0xb8310000}, {0xb8314000}, {0xb8318000}, {0xb831c000}, + {0xb8320000}, {0xb8324000}, {0xb8328000}, {0xb832c000}, + {0xb8330000}, {0xb8334000}, {0xb8338000}, {0xb833c000}, + {0xb8340000}, {0xb8344000}, {0xb8348000}, {0xb834c000}, + {0xb8350000}, {0xb8354000}, {0xb8358000}, {0xb835c000}, + {0xb8360000}, {0xb8364000}, {0xb8368000}, {0xb836c000}, + {0xb8370000}, {0xb8374000}, {0xb8378000}, {0xb837c000}, + {0xb8380000}, {0xb8384000}, {0xb8388000}, {0xb838c000}, + {0xb8390000}, {0xb8394000}, {0xb8398000}, {0xb839c000}, + {0xb83a0000}, {0xb83a4000}, {0xb83a8000}, {0xb83ac000}, + {0xb83b0000}, {0xb83b4000}, {0xb83b8000}, {0xb83bc000}, + {0xb83c0000}, {0xb83c4000}, {0xb83c8000}, {0xb83cc000}, + {0xb83d0000}, {0xb83d4000}, {0xb83d8000}, {0xb83dc000}, + {0xb83e0000}, {0xb83e4000}, {0xb83e8000}, {0xb83ec000}, + {0xb83f0000}, {0xb83f4000}, {0xb83f8000}, {0xb83fc000}, + {0xb8400000}, {0xb8404000}, {0xb8408000}, {0xb840c000}, + {0xb8410000}, {0xb8414000}, {0xb8418000}, {0xb841c000}, + {0xb8420000}, {0xb8424000}, {0xb8428000}, {0xb842c000}, + {0xb8430000}, {0xb8434000}, {0xb8438000}, {0xb843c000}, + {0xb8440000}, {0xb8444000}, {0xb8448000}, {0xb844c000}, + {0xb8450000}, {0xb8454000}, {0xb8458000}, {0xb845c000}, + {0xb8460000}, {0xb8464000}, {0xb8468000}, {0xb846c000}, + {0xb8470000}, {0xb8474000}, {0xb8478000}, {0xb847c000}, + {0xb8480000}, {0xb8484000}, {0xb8488000}, {0xb848c000}, + {0xb8490000}, {0xb8494000}, {0xb8498000}, {0xb849c000}, + {0xb84a0000}, {0xb84a4000}, {0xb84a8000}, {0xb84ac000}, + {0xb84b0000}, {0xb84b4000}, {0xb84b8000}, {0xb84bc000}, + {0xb84c0000}, {0xb84c4000}, {0xb84c8000}, {0xb84cc000}, + {0xb84d0000}, {0xb84d4000}, {0xb84d8000}, {0xb84dc000}, + {0xb84e0000}, {0xb84e4000}, {0xb84e8000}, {0xb84ec000}, + {0xb84f0000}, {0xb84f4000}, {0xb84f8000}, {0xb84fc000}, + {0xb8500000}, {0xb8504000}, {0xb8508000}, {0xb850c000}, + {0xb8510000}, {0xb8514000}, {0xb8518000}, {0xb851c000}, + {0xb8520000}, {0xb8524000}, {0xb8528000}, {0xb852c000}, + {0xb8530000}, {0xb8534000}, {0xb8538000}, {0xb853c000}, + {0xb8540000}, {0xb8544000}, {0xb8548000}, {0xb854c000}, + {0xb8550000}, {0xb8554000}, {0xb8558000}, {0xb855c000}, + {0xb8560000}, {0xb8564000}, {0xb8568000}, {0xb856c000}, + {0xb8570000}, {0xb8574000}, {0xb8578000}, {0xb857c000}, + {0xb8580000}, {0xb8584000}, {0xb8588000}, {0xb858c000}, + {0xb8590000}, {0xb8594000}, {0xb8598000}, {0xb859c000}, + {0xb85a0000}, {0xb85a4000}, {0xb85a8000}, {0xb85ac000}, + {0xb85b0000}, {0xb85b4000}, {0xb85b8000}, {0xb85bc000}, + {0xb85c0000}, {0xb85c4000}, {0xb85c8000}, {0xb85cc000}, + {0xb85d0000}, {0xb85d4000}, {0xb85d8000}, {0xb85dc000}, + {0xb85e0000}, {0xb85e4000}, {0xb85e8000}, {0xb85ec000}, + {0xb85f0000}, {0xb85f4000}, {0xb85f8000}, {0xb85fc000}, + {0xb8600000}, {0xb8604000}, {0xb8608000}, {0xb860c000}, + {0xb8610000}, {0xb8614000}, {0xb8618000}, {0xb861c000}, + {0xb8620000}, {0xb8624000}, {0xb8628000}, {0xb862c000}, + {0xb8630000}, {0xb8634000}, {0xb8638000}, {0xb863c000}, + {0xb8640000}, {0xb8644000}, {0xb8648000}, {0xb864c000}, + {0xb8650000}, {0xb8654000}, {0xb8658000}, {0xb865c000}, + {0xb8660000}, {0xb8664000}, {0xb8668000}, {0xb866c000}, + {0xb8670000}, {0xb8674000}, {0xb8678000}, {0xb867c000}, + {0xb8680000}, {0xb8684000}, {0xb8688000}, {0xb868c000}, + {0xb8690000}, {0xb8694000}, {0xb8698000}, {0xb869c000}, + {0xb86a0000}, {0xb86a4000}, {0xb86a8000}, {0xb86ac000}, + {0xb86b0000}, {0xb86b4000}, {0xb86b8000}, {0xb86bc000}, + {0xb86c0000}, {0xb86c4000}, {0xb86c8000}, {0xb86cc000}, + {0xb86d0000}, {0xb86d4000}, {0xb86d8000}, {0xb86dc000}, + {0xb86e0000}, {0xb86e4000}, {0xb86e8000}, {0xb86ec000}, + {0xb86f0000}, {0xb86f4000}, {0xb86f8000}, {0xb86fc000}, + {0xb8700000}, {0xb8704000}, {0xb8708000}, {0xb870c000}, + {0xb8710000}, {0xb8714000}, {0xb8718000}, {0xb871c000}, + {0xb8720000}, {0xb8724000}, {0xb8728000}, {0xb872c000}, + {0xb8730000}, {0xb8734000}, {0xb8738000}, {0xb873c000}, + {0xb8740000}, {0xb8744000}, {0xb8748000}, {0xb874c000}, + {0xb8750000}, {0xb8754000}, {0xb8758000}, {0xb875c000}, + {0xb8760000}, {0xb8764000}, {0xb8768000}, {0xb876c000}, + {0xb8770000}, {0xb8774000}, {0xb8778000}, {0xb877c000}, + {0xb8780000}, {0xb8784000}, {0xb8788000}, {0xb878c000}, + {0xb8790000}, {0xb8794000}, {0xb8798000}, {0xb879c000}, + {0xb87a0000}, {0xb87a4000}, {0xb87a8000}, {0xb87ac000}, + {0xb87b0000}, {0xb87b4000}, {0xb87b8000}, {0xb87bc000}, + {0xb87c0000}, {0xb87c4000}, {0xb87c8000}, {0xb87cc000}, + {0xb87d0000}, {0xb87d4000}, {0xb87d8000}, {0xb87dc000}, + {0xb87e0000}, {0xb87e4000}, {0xb87e8000}, {0xb87ec000}, + {0xb87f0000}, {0xb87f4000}, {0xb87f8000}, {0xb87fc000}, + {0xb8800000}, {0xb8802000}, {0xb8804000}, {0xb8806000}, + {0xb8808000}, {0xb880a000}, {0xb880c000}, {0xb880e000}, + {0xb8810000}, {0xb8812000}, {0xb8814000}, {0xb8816000}, + {0xb8818000}, {0xb881a000}, {0xb881c000}, {0xb881e000}, + {0xb8820000}, {0xb8822000}, {0xb8824000}, {0xb8826000}, + {0xb8828000}, {0xb882a000}, {0xb882c000}, {0xb882e000}, + {0xb8830000}, {0xb8832000}, {0xb8834000}, {0xb8836000}, + {0xb8838000}, {0xb883a000}, {0xb883c000}, {0xb883e000}, + {0xb8840000}, {0xb8842000}, {0xb8844000}, {0xb8846000}, + {0xb8848000}, {0xb884a000}, {0xb884c000}, {0xb884e000}, + {0xb8850000}, {0xb8852000}, {0xb8854000}, {0xb8856000}, + {0xb8858000}, {0xb885a000}, {0xb885c000}, {0xb885e000}, + {0xb8860000}, {0xb8862000}, {0xb8864000}, {0xb8866000}, + {0xb8868000}, {0xb886a000}, {0xb886c000}, {0xb886e000}, + {0xb8870000}, {0xb8872000}, {0xb8874000}, {0xb8876000}, + {0xb8878000}, {0xb887a000}, {0xb887c000}, {0xb887e000}, + {0xb8880000}, {0xb8882000}, {0xb8884000}, {0xb8886000}, + {0xb8888000}, {0xb888a000}, {0xb888c000}, {0xb888e000}, + {0xb8890000}, {0xb8892000}, {0xb8894000}, {0xb8896000}, + {0xb8898000}, {0xb889a000}, {0xb889c000}, {0xb889e000}, + {0xb88a0000}, {0xb88a2000}, {0xb88a4000}, {0xb88a6000}, + {0xb88a8000}, {0xb88aa000}, {0xb88ac000}, {0xb88ae000}, + {0xb88b0000}, {0xb88b2000}, {0xb88b4000}, {0xb88b6000}, + {0xb88b8000}, {0xb88ba000}, {0xb88bc000}, {0xb88be000}, + {0xb88c0000}, {0xb88c2000}, {0xb88c4000}, {0xb88c6000}, + {0xb88c8000}, {0xb88ca000}, {0xb88cc000}, {0xb88ce000}, + {0xb88d0000}, {0xb88d2000}, {0xb88d4000}, {0xb88d6000}, + {0xb88d8000}, {0xb88da000}, {0xb88dc000}, {0xb88de000}, + {0xb88e0000}, {0xb88e2000}, {0xb88e4000}, {0xb88e6000}, + {0xb88e8000}, {0xb88ea000}, {0xb88ec000}, {0xb88ee000}, + {0xb88f0000}, {0xb88f2000}, {0xb88f4000}, {0xb88f6000}, + {0xb88f8000}, {0xb88fa000}, {0xb88fc000}, {0xb88fe000}, + {0xb8900000}, {0xb8902000}, {0xb8904000}, {0xb8906000}, + {0xb8908000}, {0xb890a000}, {0xb890c000}, {0xb890e000}, + {0xb8910000}, {0xb8912000}, {0xb8914000}, {0xb8916000}, + {0xb8918000}, {0xb891a000}, {0xb891c000}, {0xb891e000}, + {0xb8920000}, {0xb8922000}, {0xb8924000}, {0xb8926000}, + {0xb8928000}, {0xb892a000}, {0xb892c000}, {0xb892e000}, + {0xb8930000}, {0xb8932000}, {0xb8934000}, {0xb8936000}, + {0xb8938000}, {0xb893a000}, {0xb893c000}, {0xb893e000}, + {0xb8940000}, {0xb8942000}, {0xb8944000}, {0xb8946000}, + {0xb8948000}, {0xb894a000}, {0xb894c000}, {0xb894e000}, + {0xb8950000}, {0xb8952000}, {0xb8954000}, {0xb8956000}, + {0xb8958000}, {0xb895a000}, {0xb895c000}, {0xb895e000}, + {0xb8960000}, {0xb8962000}, {0xb8964000}, {0xb8966000}, + {0xb8968000}, {0xb896a000}, {0xb896c000}, {0xb896e000}, + {0xb8970000}, {0xb8972000}, {0xb8974000}, {0xb8976000}, + {0xb8978000}, {0xb897a000}, {0xb897c000}, {0xb897e000}, + {0xb8980000}, {0xb8982000}, {0xb8984000}, {0xb8986000}, + {0xb8988000}, {0xb898a000}, {0xb898c000}, {0xb898e000}, + {0xb8990000}, {0xb8992000}, {0xb8994000}, {0xb8996000}, + {0xb8998000}, {0xb899a000}, {0xb899c000}, {0xb899e000}, + {0xb89a0000}, {0xb89a2000}, {0xb89a4000}, {0xb89a6000}, + {0xb89a8000}, {0xb89aa000}, {0xb89ac000}, {0xb89ae000}, + {0xb89b0000}, {0xb89b2000}, {0xb89b4000}, {0xb89b6000}, + {0xb89b8000}, {0xb89ba000}, {0xb89bc000}, {0xb89be000}, + {0xb89c0000}, {0xb89c2000}, {0xb89c4000}, {0xb89c6000}, + {0xb89c8000}, {0xb89ca000}, {0xb89cc000}, {0xb89ce000}, + {0xb89d0000}, {0xb89d2000}, {0xb89d4000}, {0xb89d6000}, + {0xb89d8000}, {0xb89da000}, {0xb89dc000}, {0xb89de000}, + {0xb89e0000}, {0xb89e2000}, {0xb89e4000}, {0xb89e6000}, + {0xb89e8000}, {0xb89ea000}, {0xb89ec000}, {0xb89ee000}, + {0xb89f0000}, {0xb89f2000}, {0xb89f4000}, {0xb89f6000}, + {0xb89f8000}, {0xb89fa000}, {0xb89fc000}, {0xb89fe000}, + {0xb8a00000}, {0xb8a02000}, {0xb8a04000}, {0xb8a06000}, + {0xb8a08000}, {0xb8a0a000}, {0xb8a0c000}, {0xb8a0e000}, + {0xb8a10000}, {0xb8a12000}, {0xb8a14000}, {0xb8a16000}, + {0xb8a18000}, {0xb8a1a000}, {0xb8a1c000}, {0xb8a1e000}, + {0xb8a20000}, {0xb8a22000}, {0xb8a24000}, {0xb8a26000}, + {0xb8a28000}, {0xb8a2a000}, {0xb8a2c000}, {0xb8a2e000}, + {0xb8a30000}, {0xb8a32000}, {0xb8a34000}, {0xb8a36000}, + {0xb8a38000}, {0xb8a3a000}, {0xb8a3c000}, {0xb8a3e000}, + {0xb8a40000}, {0xb8a42000}, {0xb8a44000}, {0xb8a46000}, + {0xb8a48000}, {0xb8a4a000}, {0xb8a4c000}, {0xb8a4e000}, + {0xb8a50000}, {0xb8a52000}, {0xb8a54000}, {0xb8a56000}, + {0xb8a58000}, {0xb8a5a000}, {0xb8a5c000}, {0xb8a5e000}, + {0xb8a60000}, {0xb8a62000}, {0xb8a64000}, {0xb8a66000}, + {0xb8a68000}, {0xb8a6a000}, {0xb8a6c000}, {0xb8a6e000}, + {0xb8a70000}, {0xb8a72000}, {0xb8a74000}, {0xb8a76000}, + {0xb8a78000}, {0xb8a7a000}, {0xb8a7c000}, {0xb8a7e000}, + {0xb8a80000}, {0xb8a82000}, {0xb8a84000}, {0xb8a86000}, + {0xb8a88000}, {0xb8a8a000}, {0xb8a8c000}, {0xb8a8e000}, + {0xb8a90000}, {0xb8a92000}, {0xb8a94000}, {0xb8a96000}, + {0xb8a98000}, {0xb8a9a000}, {0xb8a9c000}, {0xb8a9e000}, + {0xb8aa0000}, {0xb8aa2000}, {0xb8aa4000}, {0xb8aa6000}, + {0xb8aa8000}, {0xb8aaa000}, {0xb8aac000}, {0xb8aae000}, + {0xb8ab0000}, {0xb8ab2000}, {0xb8ab4000}, {0xb8ab6000}, + {0xb8ab8000}, {0xb8aba000}, {0xb8abc000}, {0xb8abe000}, + {0xb8ac0000}, {0xb8ac2000}, {0xb8ac4000}, {0xb8ac6000}, + {0xb8ac8000}, {0xb8aca000}, {0xb8acc000}, {0xb8ace000}, + {0xb8ad0000}, {0xb8ad2000}, {0xb8ad4000}, {0xb8ad6000}, + {0xb8ad8000}, {0xb8ada000}, {0xb8adc000}, {0xb8ade000}, + {0xb8ae0000}, {0xb8ae2000}, {0xb8ae4000}, {0xb8ae6000}, + {0xb8ae8000}, {0xb8aea000}, {0xb8aec000}, {0xb8aee000}, + {0xb8af0000}, {0xb8af2000}, {0xb8af4000}, {0xb8af6000}, + {0xb8af8000}, {0xb8afa000}, {0xb8afc000}, {0xb8afe000}, + {0xb8b00000}, {0xb8b02000}, {0xb8b04000}, {0xb8b06000}, + {0xb8b08000}, {0xb8b0a000}, {0xb8b0c000}, {0xb8b0e000}, + {0xb8b10000}, {0xb8b12000}, {0xb8b14000}, {0xb8b16000}, + {0xb8b18000}, {0xb8b1a000}, {0xb8b1c000}, {0xb8b1e000}, + {0xb8b20000}, {0xb8b22000}, {0xb8b24000}, {0xb8b26000}, + {0xb8b28000}, {0xb8b2a000}, {0xb8b2c000}, {0xb8b2e000}, + {0xb8b30000}, {0xb8b32000}, {0xb8b34000}, {0xb8b36000}, + {0xb8b38000}, {0xb8b3a000}, {0xb8b3c000}, {0xb8b3e000}, + {0xb8b40000}, {0xb8b42000}, {0xb8b44000}, {0xb8b46000}, + {0xb8b48000}, {0xb8b4a000}, {0xb8b4c000}, {0xb8b4e000}, + {0xb8b50000}, {0xb8b52000}, {0xb8b54000}, {0xb8b56000}, + {0xb8b58000}, {0xb8b5a000}, {0xb8b5c000}, {0xb8b5e000}, + {0xb8b60000}, {0xb8b62000}, {0xb8b64000}, {0xb8b66000}, + {0xb8b68000}, {0xb8b6a000}, {0xb8b6c000}, {0xb8b6e000}, + {0xb8b70000}, {0xb8b72000}, {0xb8b74000}, {0xb8b76000}, + {0xb8b78000}, {0xb8b7a000}, {0xb8b7c000}, {0xb8b7e000}, + {0xb8b80000}, {0xb8b82000}, {0xb8b84000}, {0xb8b86000}, + {0xb8b88000}, {0xb8b8a000}, {0xb8b8c000}, {0xb8b8e000}, + {0xb8b90000}, {0xb8b92000}, {0xb8b94000}, {0xb8b96000}, + {0xb8b98000}, {0xb8b9a000}, {0xb8b9c000}, {0xb8b9e000}, + {0xb8ba0000}, {0xb8ba2000}, {0xb8ba4000}, {0xb8ba6000}, + {0xb8ba8000}, {0xb8baa000}, {0xb8bac000}, {0xb8bae000}, + {0xb8bb0000}, {0xb8bb2000}, {0xb8bb4000}, {0xb8bb6000}, + {0xb8bb8000}, {0xb8bba000}, {0xb8bbc000}, {0xb8bbe000}, + {0xb8bc0000}, {0xb8bc2000}, {0xb8bc4000}, {0xb8bc6000}, + {0xb8bc8000}, {0xb8bca000}, {0xb8bcc000}, {0xb8bce000}, + {0xb8bd0000}, {0xb8bd2000}, {0xb8bd4000}, {0xb8bd6000}, + {0xb8bd8000}, {0xb8bda000}, {0xb8bdc000}, {0xb8bde000}, + {0xb8be0000}, {0xb8be2000}, {0xb8be4000}, {0xb8be6000}, + {0xb8be8000}, {0xb8bea000}, {0xb8bec000}, {0xb8bee000}, + {0xb8bf0000}, {0xb8bf2000}, {0xb8bf4000}, {0xb8bf6000}, + {0xb8bf8000}, {0xb8bfa000}, {0xb8bfc000}, {0xb8bfe000}, + {0xb8c00000}, {0xb8c02000}, {0xb8c04000}, {0xb8c06000}, + {0xb8c08000}, {0xb8c0a000}, {0xb8c0c000}, {0xb8c0e000}, + {0xb8c10000}, {0xb8c12000}, {0xb8c14000}, {0xb8c16000}, + {0xb8c18000}, {0xb8c1a000}, {0xb8c1c000}, {0xb8c1e000}, + {0xb8c20000}, {0xb8c22000}, {0xb8c24000}, {0xb8c26000}, + {0xb8c28000}, {0xb8c2a000}, {0xb8c2c000}, {0xb8c2e000}, + {0xb8c30000}, {0xb8c32000}, {0xb8c34000}, {0xb8c36000}, + {0xb8c38000}, {0xb8c3a000}, {0xb8c3c000}, {0xb8c3e000}, + {0xb8c40000}, {0xb8c42000}, {0xb8c44000}, {0xb8c46000}, + {0xb8c48000}, {0xb8c4a000}, {0xb8c4c000}, {0xb8c4e000}, + {0xb8c50000}, {0xb8c52000}, {0xb8c54000}, {0xb8c56000}, + {0xb8c58000}, {0xb8c5a000}, {0xb8c5c000}, {0xb8c5e000}, + {0xb8c60000}, {0xb8c62000}, {0xb8c64000}, {0xb8c66000}, + {0xb8c68000}, {0xb8c6a000}, {0xb8c6c000}, {0xb8c6e000}, + {0xb8c70000}, {0xb8c72000}, {0xb8c74000}, {0xb8c76000}, + {0xb8c78000}, {0xb8c7a000}, {0xb8c7c000}, {0xb8c7e000}, + {0xb8c80000}, {0xb8c82000}, {0xb8c84000}, {0xb8c86000}, + {0xb8c88000}, {0xb8c8a000}, {0xb8c8c000}, {0xb8c8e000}, + {0xb8c90000}, {0xb8c92000}, {0xb8c94000}, {0xb8c96000}, + {0xb8c98000}, {0xb8c9a000}, {0xb8c9c000}, {0xb8c9e000}, + {0xb8ca0000}, {0xb8ca2000}, {0xb8ca4000}, {0xb8ca6000}, + {0xb8ca8000}, {0xb8caa000}, {0xb8cac000}, {0xb8cae000}, + {0xb8cb0000}, {0xb8cb2000}, {0xb8cb4000}, {0xb8cb6000}, + {0xb8cb8000}, {0xb8cba000}, {0xb8cbc000}, {0xb8cbe000}, + {0xb8cc0000}, {0xb8cc2000}, {0xb8cc4000}, {0xb8cc6000}, + {0xb8cc8000}, {0xb8cca000}, {0xb8ccc000}, {0xb8cce000}, + {0xb8cd0000}, {0xb8cd2000}, {0xb8cd4000}, {0xb8cd6000}, + {0xb8cd8000}, {0xb8cda000}, {0xb8cdc000}, {0xb8cde000}, + {0xb8ce0000}, {0xb8ce2000}, {0xb8ce4000}, {0xb8ce6000}, + {0xb8ce8000}, {0xb8cea000}, {0xb8cec000}, {0xb8cee000}, + {0xb8cf0000}, {0xb8cf2000}, {0xb8cf4000}, {0xb8cf6000}, + {0xb8cf8000}, {0xb8cfa000}, {0xb8cfc000}, {0xb8cfe000}, + {0xb8d00000}, {0xb8d02000}, {0xb8d04000}, {0xb8d06000}, + {0xb8d08000}, {0xb8d0a000}, {0xb8d0c000}, {0xb8d0e000}, + {0xb8d10000}, {0xb8d12000}, {0xb8d14000}, {0xb8d16000}, + {0xb8d18000}, {0xb8d1a000}, {0xb8d1c000}, {0xb8d1e000}, + {0xb8d20000}, {0xb8d22000}, {0xb8d24000}, {0xb8d26000}, + {0xb8d28000}, {0xb8d2a000}, {0xb8d2c000}, {0xb8d2e000}, + {0xb8d30000}, {0xb8d32000}, {0xb8d34000}, {0xb8d36000}, + {0xb8d38000}, {0xb8d3a000}, {0xb8d3c000}, {0xb8d3e000}, + {0xb8d40000}, {0xb8d42000}, {0xb8d44000}, {0xb8d46000}, + {0xb8d48000}, {0xb8d4a000}, {0xb8d4c000}, {0xb8d4e000}, + {0xb8d50000}, {0xb8d52000}, {0xb8d54000}, {0xb8d56000}, + {0xb8d58000}, {0xb8d5a000}, {0xb8d5c000}, {0xb8d5e000}, + {0xb8d60000}, {0xb8d62000}, {0xb8d64000}, {0xb8d66000}, + {0xb8d68000}, {0xb8d6a000}, {0xb8d6c000}, {0xb8d6e000}, + {0xb8d70000}, {0xb8d72000}, {0xb8d74000}, {0xb8d76000}, + {0xb8d78000}, {0xb8d7a000}, {0xb8d7c000}, {0xb8d7e000}, + {0xb8d80000}, {0xb8d82000}, {0xb8d84000}, {0xb8d86000}, + {0xb8d88000}, {0xb8d8a000}, {0xb8d8c000}, {0xb8d8e000}, + {0xb8d90000}, {0xb8d92000}, {0xb8d94000}, {0xb8d96000}, + {0xb8d98000}, {0xb8d9a000}, {0xb8d9c000}, {0xb8d9e000}, + {0xb8da0000}, {0xb8da2000}, {0xb8da4000}, {0xb8da6000}, + {0xb8da8000}, {0xb8daa000}, {0xb8dac000}, {0xb8dae000}, + {0xb8db0000}, {0xb8db2000}, {0xb8db4000}, {0xb8db6000}, + {0xb8db8000}, {0xb8dba000}, {0xb8dbc000}, {0xb8dbe000}, + {0xb8dc0000}, {0xb8dc2000}, {0xb8dc4000}, {0xb8dc6000}, + {0xb8dc8000}, {0xb8dca000}, {0xb8dcc000}, {0xb8dce000}, + {0xb8dd0000}, {0xb8dd2000}, {0xb8dd4000}, {0xb8dd6000}, + {0xb8dd8000}, {0xb8dda000}, {0xb8ddc000}, {0xb8dde000}, + {0xb8de0000}, {0xb8de2000}, {0xb8de4000}, {0xb8de6000}, + {0xb8de8000}, {0xb8dea000}, {0xb8dec000}, {0xb8dee000}, + {0xb8df0000}, {0xb8df2000}, {0xb8df4000}, {0xb8df6000}, + {0xb8df8000}, {0xb8dfa000}, {0xb8dfc000}, {0xb8dfe000}, + {0xb8e00000}, {0xb8e02000}, {0xb8e04000}, {0xb8e06000}, + {0xb8e08000}, {0xb8e0a000}, {0xb8e0c000}, {0xb8e0e000}, + {0xb8e10000}, {0xb8e12000}, {0xb8e14000}, {0xb8e16000}, + {0xb8e18000}, {0xb8e1a000}, {0xb8e1c000}, {0xb8e1e000}, + {0xb8e20000}, {0xb8e22000}, {0xb8e24000}, {0xb8e26000}, + {0xb8e28000}, {0xb8e2a000}, {0xb8e2c000}, {0xb8e2e000}, + {0xb8e30000}, {0xb8e32000}, {0xb8e34000}, {0xb8e36000}, + {0xb8e38000}, {0xb8e3a000}, {0xb8e3c000}, {0xb8e3e000}, + {0xb8e40000}, {0xb8e42000}, {0xb8e44000}, {0xb8e46000}, + {0xb8e48000}, {0xb8e4a000}, {0xb8e4c000}, {0xb8e4e000}, + {0xb8e50000}, {0xb8e52000}, {0xb8e54000}, {0xb8e56000}, + {0xb8e58000}, {0xb8e5a000}, {0xb8e5c000}, {0xb8e5e000}, + {0xb8e60000}, {0xb8e62000}, {0xb8e64000}, {0xb8e66000}, + {0xb8e68000}, {0xb8e6a000}, {0xb8e6c000}, {0xb8e6e000}, + {0xb8e70000}, {0xb8e72000}, {0xb8e74000}, {0xb8e76000}, + {0xb8e78000}, {0xb8e7a000}, {0xb8e7c000}, {0xb8e7e000}, + {0xb8e80000}, {0xb8e82000}, {0xb8e84000}, {0xb8e86000}, + {0xb8e88000}, {0xb8e8a000}, {0xb8e8c000}, {0xb8e8e000}, + {0xb8e90000}, {0xb8e92000}, {0xb8e94000}, {0xb8e96000}, + {0xb8e98000}, {0xb8e9a000}, {0xb8e9c000}, {0xb8e9e000}, + {0xb8ea0000}, {0xb8ea2000}, {0xb8ea4000}, {0xb8ea6000}, + {0xb8ea8000}, {0xb8eaa000}, {0xb8eac000}, {0xb8eae000}, + {0xb8eb0000}, {0xb8eb2000}, {0xb8eb4000}, {0xb8eb6000}, + {0xb8eb8000}, {0xb8eba000}, {0xb8ebc000}, {0xb8ebe000}, + {0xb8ec0000}, {0xb8ec2000}, {0xb8ec4000}, {0xb8ec6000}, + {0xb8ec8000}, {0xb8eca000}, {0xb8ecc000}, {0xb8ece000}, + {0xb8ed0000}, {0xb8ed2000}, {0xb8ed4000}, {0xb8ed6000}, + {0xb8ed8000}, {0xb8eda000}, {0xb8edc000}, {0xb8ede000}, + {0xb8ee0000}, {0xb8ee2000}, {0xb8ee4000}, {0xb8ee6000}, + {0xb8ee8000}, {0xb8eea000}, {0xb8eec000}, {0xb8eee000}, + {0xb8ef0000}, {0xb8ef2000}, {0xb8ef4000}, {0xb8ef6000}, + {0xb8ef8000}, {0xb8efa000}, {0xb8efc000}, {0xb8efe000}, + {0xb8f00000}, {0xb8f02000}, {0xb8f04000}, {0xb8f06000}, + {0xb8f08000}, {0xb8f0a000}, {0xb8f0c000}, {0xb8f0e000}, + {0xb8f10000}, {0xb8f12000}, {0xb8f14000}, {0xb8f16000}, + {0xb8f18000}, {0xb8f1a000}, {0xb8f1c000}, {0xb8f1e000}, + {0xb8f20000}, {0xb8f22000}, {0xb8f24000}, {0xb8f26000}, + {0xb8f28000}, {0xb8f2a000}, {0xb8f2c000}, {0xb8f2e000}, + {0xb8f30000}, {0xb8f32000}, {0xb8f34000}, {0xb8f36000}, + {0xb8f38000}, {0xb8f3a000}, {0xb8f3c000}, {0xb8f3e000}, + {0xb8f40000}, {0xb8f42000}, {0xb8f44000}, {0xb8f46000}, + {0xb8f48000}, {0xb8f4a000}, {0xb8f4c000}, {0xb8f4e000}, + {0xb8f50000}, {0xb8f52000}, {0xb8f54000}, {0xb8f56000}, + {0xb8f58000}, {0xb8f5a000}, {0xb8f5c000}, {0xb8f5e000}, + {0xb8f60000}, {0xb8f62000}, {0xb8f64000}, {0xb8f66000}, + {0xb8f68000}, {0xb8f6a000}, {0xb8f6c000}, {0xb8f6e000}, + {0xb8f70000}, {0xb8f72000}, {0xb8f74000}, {0xb8f76000}, + {0xb8f78000}, {0xb8f7a000}, {0xb8f7c000}, {0xb8f7e000}, + {0xb8f80000}, {0xb8f82000}, {0xb8f84000}, {0xb8f86000}, + {0xb8f88000}, {0xb8f8a000}, {0xb8f8c000}, {0xb8f8e000}, + {0xb8f90000}, {0xb8f92000}, {0xb8f94000}, {0xb8f96000}, + {0xb8f98000}, {0xb8f9a000}, {0xb8f9c000}, {0xb8f9e000}, + {0xb8fa0000}, {0xb8fa2000}, {0xb8fa4000}, {0xb8fa6000}, + {0xb8fa8000}, {0xb8faa000}, {0xb8fac000}, {0xb8fae000}, + {0xb8fb0000}, {0xb8fb2000}, {0xb8fb4000}, {0xb8fb6000}, + {0xb8fb8000}, {0xb8fba000}, {0xb8fbc000}, {0xb8fbe000}, + {0xb8fc0000}, {0xb8fc2000}, {0xb8fc4000}, {0xb8fc6000}, + {0xb8fc8000}, {0xb8fca000}, {0xb8fcc000}, {0xb8fce000}, + {0xb8fd0000}, {0xb8fd2000}, {0xb8fd4000}, {0xb8fd6000}, + {0xb8fd8000}, {0xb8fda000}, {0xb8fdc000}, {0xb8fde000}, + {0xb8fe0000}, {0xb8fe2000}, {0xb8fe4000}, {0xb8fe6000}, + {0xb8fe8000}, {0xb8fea000}, {0xb8fec000}, {0xb8fee000}, + {0xb8ff0000}, {0xb8ff2000}, {0xb8ff4000}, {0xb8ff6000}, + {0xb8ff8000}, {0xb8ffa000}, {0xb8ffc000}, {0xb8ffe000}, + {0xb9000000}, {0xb9002000}, {0xb9004000}, {0xb9006000}, + {0xb9008000}, {0xb900a000}, {0xb900c000}, {0xb900e000}, + {0xb9010000}, {0xb9012000}, {0xb9014000}, {0xb9016000}, + {0xb9018000}, {0xb901a000}, {0xb901c000}, {0xb901e000}, + {0xb9020000}, {0xb9022000}, {0xb9024000}, {0xb9026000}, + {0xb9028000}, {0xb902a000}, {0xb902c000}, {0xb902e000}, + {0xb9030000}, {0xb9032000}, {0xb9034000}, {0xb9036000}, + {0xb9038000}, {0xb903a000}, {0xb903c000}, {0xb903e000}, + {0xb9040000}, {0xb9042000}, {0xb9044000}, {0xb9046000}, + {0xb9048000}, {0xb904a000}, {0xb904c000}, {0xb904e000}, + {0xb9050000}, {0xb9052000}, {0xb9054000}, {0xb9056000}, + {0xb9058000}, {0xb905a000}, {0xb905c000}, {0xb905e000}, + {0xb9060000}, {0xb9062000}, {0xb9064000}, {0xb9066000}, + {0xb9068000}, {0xb906a000}, {0xb906c000}, {0xb906e000}, + {0xb9070000}, {0xb9072000}, {0xb9074000}, {0xb9076000}, + {0xb9078000}, {0xb907a000}, {0xb907c000}, {0xb907e000}, + {0xb9080000}, {0xb9082000}, {0xb9084000}, {0xb9086000}, + {0xb9088000}, {0xb908a000}, {0xb908c000}, {0xb908e000}, + {0xb9090000}, {0xb9092000}, {0xb9094000}, {0xb9096000}, + {0xb9098000}, {0xb909a000}, {0xb909c000}, {0xb909e000}, + {0xb90a0000}, {0xb90a2000}, {0xb90a4000}, {0xb90a6000}, + {0xb90a8000}, {0xb90aa000}, {0xb90ac000}, {0xb90ae000}, + {0xb90b0000}, {0xb90b2000}, {0xb90b4000}, {0xb90b6000}, + {0xb90b8000}, {0xb90ba000}, {0xb90bc000}, {0xb90be000}, + {0xb90c0000}, {0xb90c2000}, {0xb90c4000}, {0xb90c6000}, + {0xb90c8000}, {0xb90ca000}, {0xb90cc000}, {0xb90ce000}, + {0xb90d0000}, {0xb90d2000}, {0xb90d4000}, {0xb90d6000}, + {0xb90d8000}, {0xb90da000}, {0xb90dc000}, {0xb90de000}, + {0xb90e0000}, {0xb90e2000}, {0xb90e4000}, {0xb90e6000}, + {0xb90e8000}, {0xb90ea000}, {0xb90ec000}, {0xb90ee000}, + {0xb90f0000}, {0xb90f2000}, {0xb90f4000}, {0xb90f6000}, + {0xb90f8000}, {0xb90fa000}, {0xb90fc000}, {0xb90fe000}, + {0xb9100000}, {0xb9102000}, {0xb9104000}, {0xb9106000}, + {0xb9108000}, {0xb910a000}, {0xb910c000}, {0xb910e000}, + {0xb9110000}, {0xb9112000}, {0xb9114000}, {0xb9116000}, + {0xb9118000}, {0xb911a000}, {0xb911c000}, {0xb911e000}, + {0xb9120000}, {0xb9122000}, {0xb9124000}, {0xb9126000}, + {0xb9128000}, {0xb912a000}, {0xb912c000}, {0xb912e000}, + {0xb9130000}, {0xb9132000}, {0xb9134000}, {0xb9136000}, + {0xb9138000}, {0xb913a000}, {0xb913c000}, {0xb913e000}, + {0xb9140000}, {0xb9142000}, {0xb9144000}, {0xb9146000}, + {0xb9148000}, {0xb914a000}, {0xb914c000}, {0xb914e000}, + {0xb9150000}, {0xb9152000}, {0xb9154000}, {0xb9156000}, + {0xb9158000}, {0xb915a000}, {0xb915c000}, {0xb915e000}, + {0xb9160000}, {0xb9162000}, {0xb9164000}, {0xb9166000}, + {0xb9168000}, {0xb916a000}, {0xb916c000}, {0xb916e000}, + {0xb9170000}, {0xb9172000}, {0xb9174000}, {0xb9176000}, + {0xb9178000}, {0xb917a000}, {0xb917c000}, {0xb917e000}, + {0xb9180000}, {0xb9182000}, {0xb9184000}, {0xb9186000}, + {0xb9188000}, {0xb918a000}, {0xb918c000}, {0xb918e000}, + {0xb9190000}, {0xb9192000}, {0xb9194000}, {0xb9196000}, + {0xb9198000}, {0xb919a000}, {0xb919c000}, {0xb919e000}, + {0xb91a0000}, {0xb91a2000}, {0xb91a4000}, {0xb91a6000}, + {0xb91a8000}, {0xb91aa000}, {0xb91ac000}, {0xb91ae000}, + {0xb91b0000}, {0xb91b2000}, {0xb91b4000}, {0xb91b6000}, + {0xb91b8000}, {0xb91ba000}, {0xb91bc000}, {0xb91be000}, + {0xb91c0000}, {0xb91c2000}, {0xb91c4000}, {0xb91c6000}, + {0xb91c8000}, {0xb91ca000}, {0xb91cc000}, {0xb91ce000}, + {0xb91d0000}, {0xb91d2000}, {0xb91d4000}, {0xb91d6000}, + {0xb91d8000}, {0xb91da000}, {0xb91dc000}, {0xb91de000}, + {0xb91e0000}, {0xb91e2000}, {0xb91e4000}, {0xb91e6000}, + {0xb91e8000}, {0xb91ea000}, {0xb91ec000}, {0xb91ee000}, + {0xb91f0000}, {0xb91f2000}, {0xb91f4000}, {0xb91f6000}, + {0xb91f8000}, {0xb91fa000}, {0xb91fc000}, {0xb91fe000}, + {0xb9200000}, {0xb9202000}, {0xb9204000}, {0xb9206000}, + {0xb9208000}, {0xb920a000}, {0xb920c000}, {0xb920e000}, + {0xb9210000}, {0xb9212000}, {0xb9214000}, {0xb9216000}, + {0xb9218000}, {0xb921a000}, {0xb921c000}, {0xb921e000}, + {0xb9220000}, {0xb9222000}, {0xb9224000}, {0xb9226000}, + {0xb9228000}, {0xb922a000}, {0xb922c000}, {0xb922e000}, + {0xb9230000}, {0xb9232000}, {0xb9234000}, {0xb9236000}, + {0xb9238000}, {0xb923a000}, {0xb923c000}, {0xb923e000}, + {0xb9240000}, {0xb9242000}, {0xb9244000}, {0xb9246000}, + {0xb9248000}, {0xb924a000}, {0xb924c000}, {0xb924e000}, + {0xb9250000}, {0xb9252000}, {0xb9254000}, {0xb9256000}, + {0xb9258000}, {0xb925a000}, {0xb925c000}, {0xb925e000}, + {0xb9260000}, {0xb9262000}, {0xb9264000}, {0xb9266000}, + {0xb9268000}, {0xb926a000}, {0xb926c000}, {0xb926e000}, + {0xb9270000}, {0xb9272000}, {0xb9274000}, {0xb9276000}, + {0xb9278000}, {0xb927a000}, {0xb927c000}, {0xb927e000}, + {0xb9280000}, {0xb9282000}, {0xb9284000}, {0xb9286000}, + {0xb9288000}, {0xb928a000}, {0xb928c000}, {0xb928e000}, + {0xb9290000}, {0xb9292000}, {0xb9294000}, {0xb9296000}, + {0xb9298000}, {0xb929a000}, {0xb929c000}, {0xb929e000}, + {0xb92a0000}, {0xb92a2000}, {0xb92a4000}, {0xb92a6000}, + {0xb92a8000}, {0xb92aa000}, {0xb92ac000}, {0xb92ae000}, + {0xb92b0000}, {0xb92b2000}, {0xb92b4000}, {0xb92b6000}, + {0xb92b8000}, {0xb92ba000}, {0xb92bc000}, {0xb92be000}, + {0xb92c0000}, {0xb92c2000}, {0xb92c4000}, {0xb92c6000}, + {0xb92c8000}, {0xb92ca000}, {0xb92cc000}, {0xb92ce000}, + {0xb92d0000}, {0xb92d2000}, {0xb92d4000}, {0xb92d6000}, + {0xb92d8000}, {0xb92da000}, {0xb92dc000}, {0xb92de000}, + {0xb92e0000}, {0xb92e2000}, {0xb92e4000}, {0xb92e6000}, + {0xb92e8000}, {0xb92ea000}, {0xb92ec000}, {0xb92ee000}, + {0xb92f0000}, {0xb92f2000}, {0xb92f4000}, {0xb92f6000}, + {0xb92f8000}, {0xb92fa000}, {0xb92fc000}, {0xb92fe000}, + {0xb9300000}, {0xb9302000}, {0xb9304000}, {0xb9306000}, + {0xb9308000}, {0xb930a000}, {0xb930c000}, {0xb930e000}, + {0xb9310000}, {0xb9312000}, {0xb9314000}, {0xb9316000}, + {0xb9318000}, {0xb931a000}, {0xb931c000}, {0xb931e000}, + {0xb9320000}, {0xb9322000}, {0xb9324000}, {0xb9326000}, + {0xb9328000}, {0xb932a000}, {0xb932c000}, {0xb932e000}, + {0xb9330000}, {0xb9332000}, {0xb9334000}, {0xb9336000}, + {0xb9338000}, {0xb933a000}, {0xb933c000}, {0xb933e000}, + {0xb9340000}, {0xb9342000}, {0xb9344000}, {0xb9346000}, + {0xb9348000}, {0xb934a000}, {0xb934c000}, {0xb934e000}, + {0xb9350000}, {0xb9352000}, {0xb9354000}, {0xb9356000}, + {0xb9358000}, {0xb935a000}, {0xb935c000}, {0xb935e000}, + {0xb9360000}, {0xb9362000}, {0xb9364000}, {0xb9366000}, + {0xb9368000}, {0xb936a000}, {0xb936c000}, {0xb936e000}, + {0xb9370000}, {0xb9372000}, {0xb9374000}, {0xb9376000}, + {0xb9378000}, {0xb937a000}, {0xb937c000}, {0xb937e000}, + {0xb9380000}, {0xb9382000}, {0xb9384000}, {0xb9386000}, + {0xb9388000}, {0xb938a000}, {0xb938c000}, {0xb938e000}, + {0xb9390000}, {0xb9392000}, {0xb9394000}, {0xb9396000}, + {0xb9398000}, {0xb939a000}, {0xb939c000}, {0xb939e000}, + {0xb93a0000}, {0xb93a2000}, {0xb93a4000}, {0xb93a6000}, + {0xb93a8000}, {0xb93aa000}, {0xb93ac000}, {0xb93ae000}, + {0xb93b0000}, {0xb93b2000}, {0xb93b4000}, {0xb93b6000}, + {0xb93b8000}, {0xb93ba000}, {0xb93bc000}, {0xb93be000}, + {0xb93c0000}, {0xb93c2000}, {0xb93c4000}, {0xb93c6000}, + {0xb93c8000}, {0xb93ca000}, {0xb93cc000}, {0xb93ce000}, + {0xb93d0000}, {0xb93d2000}, {0xb93d4000}, {0xb93d6000}, + {0xb93d8000}, {0xb93da000}, {0xb93dc000}, {0xb93de000}, + {0xb93e0000}, {0xb93e2000}, {0xb93e4000}, {0xb93e6000}, + {0xb93e8000}, {0xb93ea000}, {0xb93ec000}, {0xb93ee000}, + {0xb93f0000}, {0xb93f2000}, {0xb93f4000}, {0xb93f6000}, + {0xb93f8000}, {0xb93fa000}, {0xb93fc000}, {0xb93fe000}, + {0xb9400000}, {0xb9402000}, {0xb9404000}, {0xb9406000}, + {0xb9408000}, {0xb940a000}, {0xb940c000}, {0xb940e000}, + {0xb9410000}, {0xb9412000}, {0xb9414000}, {0xb9416000}, + {0xb9418000}, {0xb941a000}, {0xb941c000}, {0xb941e000}, + {0xb9420000}, {0xb9422000}, {0xb9424000}, {0xb9426000}, + {0xb9428000}, {0xb942a000}, {0xb942c000}, {0xb942e000}, + {0xb9430000}, {0xb9432000}, {0xb9434000}, {0xb9436000}, + {0xb9438000}, {0xb943a000}, {0xb943c000}, {0xb943e000}, + {0xb9440000}, {0xb9442000}, {0xb9444000}, {0xb9446000}, + {0xb9448000}, {0xb944a000}, {0xb944c000}, {0xb944e000}, + {0xb9450000}, {0xb9452000}, {0xb9454000}, {0xb9456000}, + {0xb9458000}, {0xb945a000}, {0xb945c000}, {0xb945e000}, + {0xb9460000}, {0xb9462000}, {0xb9464000}, {0xb9466000}, + {0xb9468000}, {0xb946a000}, {0xb946c000}, {0xb946e000}, + {0xb9470000}, {0xb9472000}, {0xb9474000}, {0xb9476000}, + {0xb9478000}, {0xb947a000}, {0xb947c000}, {0xb947e000}, + {0xb9480000}, {0xb9482000}, {0xb9484000}, {0xb9486000}, + {0xb9488000}, {0xb948a000}, {0xb948c000}, {0xb948e000}, + {0xb9490000}, {0xb9492000}, {0xb9494000}, {0xb9496000}, + {0xb9498000}, {0xb949a000}, {0xb949c000}, {0xb949e000}, + {0xb94a0000}, {0xb94a2000}, {0xb94a4000}, {0xb94a6000}, + {0xb94a8000}, {0xb94aa000}, {0xb94ac000}, {0xb94ae000}, + {0xb94b0000}, {0xb94b2000}, {0xb94b4000}, {0xb94b6000}, + {0xb94b8000}, {0xb94ba000}, {0xb94bc000}, {0xb94be000}, + {0xb94c0000}, {0xb94c2000}, {0xb94c4000}, {0xb94c6000}, + {0xb94c8000}, {0xb94ca000}, {0xb94cc000}, {0xb94ce000}, + {0xb94d0000}, {0xb94d2000}, {0xb94d4000}, {0xb94d6000}, + {0xb94d8000}, {0xb94da000}, {0xb94dc000}, {0xb94de000}, + {0xb94e0000}, {0xb94e2000}, {0xb94e4000}, {0xb94e6000}, + {0xb94e8000}, {0xb94ea000}, {0xb94ec000}, {0xb94ee000}, + {0xb94f0000}, {0xb94f2000}, {0xb94f4000}, {0xb94f6000}, + {0xb94f8000}, {0xb94fa000}, {0xb94fc000}, {0xb94fe000}, + {0xb9500000}, {0xb9502000}, {0xb9504000}, {0xb9506000}, + {0xb9508000}, {0xb950a000}, {0xb950c000}, {0xb950e000}, + {0xb9510000}, {0xb9512000}, {0xb9514000}, {0xb9516000}, + {0xb9518000}, {0xb951a000}, {0xb951c000}, {0xb951e000}, + {0xb9520000}, {0xb9522000}, {0xb9524000}, {0xb9526000}, + {0xb9528000}, {0xb952a000}, {0xb952c000}, {0xb952e000}, + {0xb9530000}, {0xb9532000}, {0xb9534000}, {0xb9536000}, + {0xb9538000}, {0xb953a000}, {0xb953c000}, {0xb953e000}, + {0xb9540000}, {0xb9542000}, {0xb9544000}, {0xb9546000}, + {0xb9548000}, {0xb954a000}, {0xb954c000}, {0xb954e000}, + {0xb9550000}, {0xb9552000}, {0xb9554000}, {0xb9556000}, + {0xb9558000}, {0xb955a000}, {0xb955c000}, {0xb955e000}, + {0xb9560000}, {0xb9562000}, {0xb9564000}, {0xb9566000}, + {0xb9568000}, {0xb956a000}, {0xb956c000}, {0xb956e000}, + {0xb9570000}, {0xb9572000}, {0xb9574000}, {0xb9576000}, + {0xb9578000}, {0xb957a000}, {0xb957c000}, {0xb957e000}, + {0xb9580000}, {0xb9582000}, {0xb9584000}, {0xb9586000}, + {0xb9588000}, {0xb958a000}, {0xb958c000}, {0xb958e000}, + {0xb9590000}, {0xb9592000}, {0xb9594000}, {0xb9596000}, + {0xb9598000}, {0xb959a000}, {0xb959c000}, {0xb959e000}, + {0xb95a0000}, {0xb95a2000}, {0xb95a4000}, {0xb95a6000}, + {0xb95a8000}, {0xb95aa000}, {0xb95ac000}, {0xb95ae000}, + {0xb95b0000}, {0xb95b2000}, {0xb95b4000}, {0xb95b6000}, + {0xb95b8000}, {0xb95ba000}, {0xb95bc000}, {0xb95be000}, + {0xb95c0000}, {0xb95c2000}, {0xb95c4000}, {0xb95c6000}, + {0xb95c8000}, {0xb95ca000}, {0xb95cc000}, {0xb95ce000}, + {0xb95d0000}, {0xb95d2000}, {0xb95d4000}, {0xb95d6000}, + {0xb95d8000}, {0xb95da000}, {0xb95dc000}, {0xb95de000}, + {0xb95e0000}, {0xb95e2000}, {0xb95e4000}, {0xb95e6000}, + {0xb95e8000}, {0xb95ea000}, {0xb95ec000}, {0xb95ee000}, + {0xb95f0000}, {0xb95f2000}, {0xb95f4000}, {0xb95f6000}, + {0xb95f8000}, {0xb95fa000}, {0xb95fc000}, {0xb95fe000}, + {0xb9600000}, {0xb9602000}, {0xb9604000}, {0xb9606000}, + {0xb9608000}, {0xb960a000}, {0xb960c000}, {0xb960e000}, + {0xb9610000}, {0xb9612000}, {0xb9614000}, {0xb9616000}, + {0xb9618000}, {0xb961a000}, {0xb961c000}, {0xb961e000}, + {0xb9620000}, {0xb9622000}, {0xb9624000}, {0xb9626000}, + {0xb9628000}, {0xb962a000}, {0xb962c000}, {0xb962e000}, + {0xb9630000}, {0xb9632000}, {0xb9634000}, {0xb9636000}, + {0xb9638000}, {0xb963a000}, {0xb963c000}, {0xb963e000}, + {0xb9640000}, {0xb9642000}, {0xb9644000}, {0xb9646000}, + {0xb9648000}, {0xb964a000}, {0xb964c000}, {0xb964e000}, + {0xb9650000}, {0xb9652000}, {0xb9654000}, {0xb9656000}, + {0xb9658000}, {0xb965a000}, {0xb965c000}, {0xb965e000}, + {0xb9660000}, {0xb9662000}, {0xb9664000}, {0xb9666000}, + {0xb9668000}, {0xb966a000}, {0xb966c000}, {0xb966e000}, + {0xb9670000}, {0xb9672000}, {0xb9674000}, {0xb9676000}, + {0xb9678000}, {0xb967a000}, {0xb967c000}, {0xb967e000}, + {0xb9680000}, {0xb9682000}, {0xb9684000}, {0xb9686000}, + {0xb9688000}, {0xb968a000}, {0xb968c000}, {0xb968e000}, + {0xb9690000}, {0xb9692000}, {0xb9694000}, {0xb9696000}, + {0xb9698000}, {0xb969a000}, {0xb969c000}, {0xb969e000}, + {0xb96a0000}, {0xb96a2000}, {0xb96a4000}, {0xb96a6000}, + {0xb96a8000}, {0xb96aa000}, {0xb96ac000}, {0xb96ae000}, + {0xb96b0000}, {0xb96b2000}, {0xb96b4000}, {0xb96b6000}, + {0xb96b8000}, {0xb96ba000}, {0xb96bc000}, {0xb96be000}, + {0xb96c0000}, {0xb96c2000}, {0xb96c4000}, {0xb96c6000}, + {0xb96c8000}, {0xb96ca000}, {0xb96cc000}, {0xb96ce000}, + {0xb96d0000}, {0xb96d2000}, {0xb96d4000}, {0xb96d6000}, + {0xb96d8000}, {0xb96da000}, {0xb96dc000}, {0xb96de000}, + {0xb96e0000}, {0xb96e2000}, {0xb96e4000}, {0xb96e6000}, + {0xb96e8000}, {0xb96ea000}, {0xb96ec000}, {0xb96ee000}, + {0xb96f0000}, {0xb96f2000}, {0xb96f4000}, {0xb96f6000}, + {0xb96f8000}, {0xb96fa000}, {0xb96fc000}, {0xb96fe000}, + {0xb9700000}, {0xb9702000}, {0xb9704000}, {0xb9706000}, + {0xb9708000}, {0xb970a000}, {0xb970c000}, {0xb970e000}, + {0xb9710000}, {0xb9712000}, {0xb9714000}, {0xb9716000}, + {0xb9718000}, {0xb971a000}, {0xb971c000}, {0xb971e000}, + {0xb9720000}, {0xb9722000}, {0xb9724000}, {0xb9726000}, + {0xb9728000}, {0xb972a000}, {0xb972c000}, {0xb972e000}, + {0xb9730000}, {0xb9732000}, {0xb9734000}, {0xb9736000}, + {0xb9738000}, {0xb973a000}, {0xb973c000}, {0xb973e000}, + {0xb9740000}, {0xb9742000}, {0xb9744000}, {0xb9746000}, + {0xb9748000}, {0xb974a000}, {0xb974c000}, {0xb974e000}, + {0xb9750000}, {0xb9752000}, {0xb9754000}, {0xb9756000}, + {0xb9758000}, {0xb975a000}, {0xb975c000}, {0xb975e000}, + {0xb9760000}, {0xb9762000}, {0xb9764000}, {0xb9766000}, + {0xb9768000}, {0xb976a000}, {0xb976c000}, {0xb976e000}, + {0xb9770000}, {0xb9772000}, {0xb9774000}, {0xb9776000}, + {0xb9778000}, {0xb977a000}, {0xb977c000}, {0xb977e000}, + {0xb9780000}, {0xb9782000}, {0xb9784000}, {0xb9786000}, + {0xb9788000}, {0xb978a000}, {0xb978c000}, {0xb978e000}, + {0xb9790000}, {0xb9792000}, {0xb9794000}, {0xb9796000}, + {0xb9798000}, {0xb979a000}, {0xb979c000}, {0xb979e000}, + {0xb97a0000}, {0xb97a2000}, {0xb97a4000}, {0xb97a6000}, + {0xb97a8000}, {0xb97aa000}, {0xb97ac000}, {0xb97ae000}, + {0xb97b0000}, {0xb97b2000}, {0xb97b4000}, {0xb97b6000}, + {0xb97b8000}, {0xb97ba000}, {0xb97bc000}, {0xb97be000}, + {0xb97c0000}, {0xb97c2000}, {0xb97c4000}, {0xb97c6000}, + {0xb97c8000}, {0xb97ca000}, {0xb97cc000}, {0xb97ce000}, + {0xb97d0000}, {0xb97d2000}, {0xb97d4000}, {0xb97d6000}, + {0xb97d8000}, {0xb97da000}, {0xb97dc000}, {0xb97de000}, + {0xb97e0000}, {0xb97e2000}, {0xb97e4000}, {0xb97e6000}, + {0xb97e8000}, {0xb97ea000}, {0xb97ec000}, {0xb97ee000}, + {0xb97f0000}, {0xb97f2000}, {0xb97f4000}, {0xb97f6000}, + {0xb97f8000}, {0xb97fa000}, {0xb97fc000}, {0xb97fe000}, + {0xb9800000}, {0xb9802000}, {0xb9804000}, {0xb9806000}, + {0xb9808000}, {0xb980a000}, {0xb980c000}, {0xb980e000}, + {0xb9810000}, {0xb9812000}, {0xb9814000}, {0xb9816000}, + {0xb9818000}, {0xb981a000}, {0xb981c000}, {0xb981e000}, + {0xb9820000}, {0xb9822000}, {0xb9824000}, {0xb9826000}, + {0xb9828000}, {0xb982a000}, {0xb982c000}, {0xb982e000}, + {0xb9830000}, {0xb9832000}, {0xb9834000}, {0xb9836000}, + {0xb9838000}, {0xb983a000}, {0xb983c000}, {0xb983e000}, + {0xb9840000}, {0xb9842000}, {0xb9844000}, {0xb9846000}, + {0xb9848000}, {0xb984a000}, {0xb984c000}, {0xb984e000}, + {0xb9850000}, {0xb9852000}, {0xb9854000}, {0xb9856000}, + {0xb9858000}, {0xb985a000}, {0xb985c000}, {0xb985e000}, + {0xb9860000}, {0xb9862000}, {0xb9864000}, {0xb9866000}, + {0xb9868000}, {0xb986a000}, {0xb986c000}, {0xb986e000}, + {0xb9870000}, {0xb9872000}, {0xb9874000}, {0xb9876000}, + {0xb9878000}, {0xb987a000}, {0xb987c000}, {0xb987e000}, + {0xb9880000}, {0xb9882000}, {0xb9884000}, {0xb9886000}, + {0xb9888000}, {0xb988a000}, {0xb988c000}, {0xb988e000}, + {0xb9890000}, {0xb9892000}, {0xb9894000}, {0xb9896000}, + {0xb9898000}, {0xb989a000}, {0xb989c000}, {0xb989e000}, + {0xb98a0000}, {0xb98a2000}, {0xb98a4000}, {0xb98a6000}, + {0xb98a8000}, {0xb98aa000}, {0xb98ac000}, {0xb98ae000}, + {0xb98b0000}, {0xb98b2000}, {0xb98b4000}, {0xb98b6000}, + {0xb98b8000}, {0xb98ba000}, {0xb98bc000}, {0xb98be000}, + {0xb98c0000}, {0xb98c2000}, {0xb98c4000}, {0xb98c6000}, + {0xb98c8000}, {0xb98ca000}, {0xb98cc000}, {0xb98ce000}, + {0xb98d0000}, {0xb98d2000}, {0xb98d4000}, {0xb98d6000}, + {0xb98d8000}, {0xb98da000}, {0xb98dc000}, {0xb98de000}, + {0xb98e0000}, {0xb98e2000}, {0xb98e4000}, {0xb98e6000}, + {0xb98e8000}, {0xb98ea000}, {0xb98ec000}, {0xb98ee000}, + {0xb98f0000}, {0xb98f2000}, {0xb98f4000}, {0xb98f6000}, + {0xb98f8000}, {0xb98fa000}, {0xb98fc000}, {0xb98fe000}, + {0xb9900000}, {0xb9902000}, {0xb9904000}, {0xb9906000}, + {0xb9908000}, {0xb990a000}, {0xb990c000}, {0xb990e000}, + {0xb9910000}, {0xb9912000}, {0xb9914000}, {0xb9916000}, + {0xb9918000}, {0xb991a000}, {0xb991c000}, {0xb991e000}, + {0xb9920000}, {0xb9922000}, {0xb9924000}, {0xb9926000}, + {0xb9928000}, {0xb992a000}, {0xb992c000}, {0xb992e000}, + {0xb9930000}, {0xb9932000}, {0xb9934000}, {0xb9936000}, + {0xb9938000}, {0xb993a000}, {0xb993c000}, {0xb993e000}, + {0xb9940000}, {0xb9942000}, {0xb9944000}, {0xb9946000}, + {0xb9948000}, {0xb994a000}, {0xb994c000}, {0xb994e000}, + {0xb9950000}, {0xb9952000}, {0xb9954000}, {0xb9956000}, + {0xb9958000}, {0xb995a000}, {0xb995c000}, {0xb995e000}, + {0xb9960000}, {0xb9962000}, {0xb9964000}, {0xb9966000}, + {0xb9968000}, {0xb996a000}, {0xb996c000}, {0xb996e000}, + {0xb9970000}, {0xb9972000}, {0xb9974000}, {0xb9976000}, + {0xb9978000}, {0xb997a000}, {0xb997c000}, {0xb997e000}, + {0xb9980000}, {0xb9982000}, {0xb9984000}, {0xb9986000}, + {0xb9988000}, {0xb998a000}, {0xb998c000}, {0xb998e000}, + {0xb9990000}, {0xb9992000}, {0xb9994000}, {0xb9996000}, + {0xb9998000}, {0xb999a000}, {0xb999c000}, {0xb999e000}, + {0xb99a0000}, {0xb99a2000}, {0xb99a4000}, {0xb99a6000}, + {0xb99a8000}, {0xb99aa000}, {0xb99ac000}, {0xb99ae000}, + {0xb99b0000}, {0xb99b2000}, {0xb99b4000}, {0xb99b6000}, + {0xb99b8000}, {0xb99ba000}, {0xb99bc000}, {0xb99be000}, + {0xb99c0000}, {0xb99c2000}, {0xb99c4000}, {0xb99c6000}, + {0xb99c8000}, {0xb99ca000}, {0xb99cc000}, {0xb99ce000}, + {0xb99d0000}, {0xb99d2000}, {0xb99d4000}, {0xb99d6000}, + {0xb99d8000}, {0xb99da000}, {0xb99dc000}, {0xb99de000}, + {0xb99e0000}, {0xb99e2000}, {0xb99e4000}, {0xb99e6000}, + {0xb99e8000}, {0xb99ea000}, {0xb99ec000}, {0xb99ee000}, + {0xb99f0000}, {0xb99f2000}, {0xb99f4000}, {0xb99f6000}, + {0xb99f8000}, {0xb99fa000}, {0xb99fc000}, {0xb99fe000}, + {0xb9a00000}, {0xb9a02000}, {0xb9a04000}, {0xb9a06000}, + {0xb9a08000}, {0xb9a0a000}, {0xb9a0c000}, {0xb9a0e000}, + {0xb9a10000}, {0xb9a12000}, {0xb9a14000}, {0xb9a16000}, + {0xb9a18000}, {0xb9a1a000}, {0xb9a1c000}, {0xb9a1e000}, + {0xb9a20000}, {0xb9a22000}, {0xb9a24000}, {0xb9a26000}, + {0xb9a28000}, {0xb9a2a000}, {0xb9a2c000}, {0xb9a2e000}, + {0xb9a30000}, {0xb9a32000}, {0xb9a34000}, {0xb9a36000}, + {0xb9a38000}, {0xb9a3a000}, {0xb9a3c000}, {0xb9a3e000}, + {0xb9a40000}, {0xb9a42000}, {0xb9a44000}, {0xb9a46000}, + {0xb9a48000}, {0xb9a4a000}, {0xb9a4c000}, {0xb9a4e000}, + {0xb9a50000}, {0xb9a52000}, {0xb9a54000}, {0xb9a56000}, + {0xb9a58000}, {0xb9a5a000}, {0xb9a5c000}, {0xb9a5e000}, + {0xb9a60000}, {0xb9a62000}, {0xb9a64000}, {0xb9a66000}, + {0xb9a68000}, {0xb9a6a000}, {0xb9a6c000}, {0xb9a6e000}, + {0xb9a70000}, {0xb9a72000}, {0xb9a74000}, {0xb9a76000}, + {0xb9a78000}, {0xb9a7a000}, {0xb9a7c000}, {0xb9a7e000}, + {0xb9a80000}, {0xb9a82000}, {0xb9a84000}, {0xb9a86000}, + {0xb9a88000}, {0xb9a8a000}, {0xb9a8c000}, {0xb9a8e000}, + {0xb9a90000}, {0xb9a92000}, {0xb9a94000}, {0xb9a96000}, + {0xb9a98000}, {0xb9a9a000}, {0xb9a9c000}, {0xb9a9e000}, + {0xb9aa0000}, {0xb9aa2000}, {0xb9aa4000}, {0xb9aa6000}, + {0xb9aa8000}, {0xb9aaa000}, {0xb9aac000}, {0xb9aae000}, + {0xb9ab0000}, {0xb9ab2000}, {0xb9ab4000}, {0xb9ab6000}, + {0xb9ab8000}, {0xb9aba000}, {0xb9abc000}, {0xb9abe000}, + {0xb9ac0000}, {0xb9ac2000}, {0xb9ac4000}, {0xb9ac6000}, + {0xb9ac8000}, {0xb9aca000}, {0xb9acc000}, {0xb9ace000}, + {0xb9ad0000}, {0xb9ad2000}, {0xb9ad4000}, {0xb9ad6000}, + {0xb9ad8000}, {0xb9ada000}, {0xb9adc000}, {0xb9ade000}, + {0xb9ae0000}, {0xb9ae2000}, {0xb9ae4000}, {0xb9ae6000}, + {0xb9ae8000}, {0xb9aea000}, {0xb9aec000}, {0xb9aee000}, + {0xb9af0000}, {0xb9af2000}, {0xb9af4000}, {0xb9af6000}, + {0xb9af8000}, {0xb9afa000}, {0xb9afc000}, {0xb9afe000}, + {0xb9b00000}, {0xb9b02000}, {0xb9b04000}, {0xb9b06000}, + {0xb9b08000}, {0xb9b0a000}, {0xb9b0c000}, {0xb9b0e000}, + {0xb9b10000}, {0xb9b12000}, {0xb9b14000}, {0xb9b16000}, + {0xb9b18000}, {0xb9b1a000}, {0xb9b1c000}, {0xb9b1e000}, + {0xb9b20000}, {0xb9b22000}, {0xb9b24000}, {0xb9b26000}, + {0xb9b28000}, {0xb9b2a000}, {0xb9b2c000}, {0xb9b2e000}, + {0xb9b30000}, {0xb9b32000}, {0xb9b34000}, {0xb9b36000}, + {0xb9b38000}, {0xb9b3a000}, {0xb9b3c000}, {0xb9b3e000}, + {0xb9b40000}, {0xb9b42000}, {0xb9b44000}, {0xb9b46000}, + {0xb9b48000}, {0xb9b4a000}, {0xb9b4c000}, {0xb9b4e000}, + {0xb9b50000}, {0xb9b52000}, {0xb9b54000}, {0xb9b56000}, + {0xb9b58000}, {0xb9b5a000}, {0xb9b5c000}, {0xb9b5e000}, + {0xb9b60000}, {0xb9b62000}, {0xb9b64000}, {0xb9b66000}, + {0xb9b68000}, {0xb9b6a000}, {0xb9b6c000}, {0xb9b6e000}, + {0xb9b70000}, {0xb9b72000}, {0xb9b74000}, {0xb9b76000}, + {0xb9b78000}, {0xb9b7a000}, {0xb9b7c000}, {0xb9b7e000}, + {0xb9b80000}, {0xb9b82000}, {0xb9b84000}, {0xb9b86000}, + {0xb9b88000}, {0xb9b8a000}, {0xb9b8c000}, {0xb9b8e000}, + {0xb9b90000}, {0xb9b92000}, {0xb9b94000}, {0xb9b96000}, + {0xb9b98000}, {0xb9b9a000}, {0xb9b9c000}, {0xb9b9e000}, + {0xb9ba0000}, {0xb9ba2000}, {0xb9ba4000}, {0xb9ba6000}, + {0xb9ba8000}, {0xb9baa000}, {0xb9bac000}, {0xb9bae000}, + {0xb9bb0000}, {0xb9bb2000}, {0xb9bb4000}, {0xb9bb6000}, + {0xb9bb8000}, {0xb9bba000}, {0xb9bbc000}, {0xb9bbe000}, + {0xb9bc0000}, {0xb9bc2000}, {0xb9bc4000}, {0xb9bc6000}, + {0xb9bc8000}, {0xb9bca000}, {0xb9bcc000}, {0xb9bce000}, + {0xb9bd0000}, {0xb9bd2000}, {0xb9bd4000}, {0xb9bd6000}, + {0xb9bd8000}, {0xb9bda000}, {0xb9bdc000}, {0xb9bde000}, + {0xb9be0000}, {0xb9be2000}, {0xb9be4000}, {0xb9be6000}, + {0xb9be8000}, {0xb9bea000}, {0xb9bec000}, {0xb9bee000}, + {0xb9bf0000}, {0xb9bf2000}, {0xb9bf4000}, {0xb9bf6000}, + {0xb9bf8000}, {0xb9bfa000}, {0xb9bfc000}, {0xb9bfe000}, + {0xb9c00000}, {0xb9c02000}, {0xb9c04000}, {0xb9c06000}, + {0xb9c08000}, {0xb9c0a000}, {0xb9c0c000}, {0xb9c0e000}, + {0xb9c10000}, {0xb9c12000}, {0xb9c14000}, {0xb9c16000}, + {0xb9c18000}, {0xb9c1a000}, {0xb9c1c000}, {0xb9c1e000}, + {0xb9c20000}, {0xb9c22000}, {0xb9c24000}, {0xb9c26000}, + {0xb9c28000}, {0xb9c2a000}, {0xb9c2c000}, {0xb9c2e000}, + {0xb9c30000}, {0xb9c32000}, {0xb9c34000}, {0xb9c36000}, + {0xb9c38000}, {0xb9c3a000}, {0xb9c3c000}, {0xb9c3e000}, + {0xb9c40000}, {0xb9c42000}, {0xb9c44000}, {0xb9c46000}, + {0xb9c48000}, {0xb9c4a000}, {0xb9c4c000}, {0xb9c4e000}, + {0xb9c50000}, {0xb9c52000}, {0xb9c54000}, {0xb9c56000}, + {0xb9c58000}, {0xb9c5a000}, {0xb9c5c000}, {0xb9c5e000}, + {0xb9c60000}, {0xb9c62000}, {0xb9c64000}, {0xb9c66000}, + {0xb9c68000}, {0xb9c6a000}, {0xb9c6c000}, {0xb9c6e000}, + {0xb9c70000}, {0xb9c72000}, {0xb9c74000}, {0xb9c76000}, + {0xb9c78000}, {0xb9c7a000}, {0xb9c7c000}, {0xb9c7e000}, + {0xb9c80000}, {0xb9c82000}, {0xb9c84000}, {0xb9c86000}, + {0xb9c88000}, {0xb9c8a000}, {0xb9c8c000}, {0xb9c8e000}, + {0xb9c90000}, {0xb9c92000}, {0xb9c94000}, {0xb9c96000}, + {0xb9c98000}, {0xb9c9a000}, {0xb9c9c000}, {0xb9c9e000}, + {0xb9ca0000}, {0xb9ca2000}, {0xb9ca4000}, {0xb9ca6000}, + {0xb9ca8000}, {0xb9caa000}, {0xb9cac000}, {0xb9cae000}, + {0xb9cb0000}, {0xb9cb2000}, {0xb9cb4000}, {0xb9cb6000}, + {0xb9cb8000}, {0xb9cba000}, {0xb9cbc000}, {0xb9cbe000}, + {0xb9cc0000}, {0xb9cc2000}, {0xb9cc4000}, {0xb9cc6000}, + {0xb9cc8000}, {0xb9cca000}, {0xb9ccc000}, {0xb9cce000}, + {0xb9cd0000}, {0xb9cd2000}, {0xb9cd4000}, {0xb9cd6000}, + {0xb9cd8000}, {0xb9cda000}, {0xb9cdc000}, {0xb9cde000}, + {0xb9ce0000}, {0xb9ce2000}, {0xb9ce4000}, {0xb9ce6000}, + {0xb9ce8000}, {0xb9cea000}, {0xb9cec000}, {0xb9cee000}, + {0xb9cf0000}, {0xb9cf2000}, {0xb9cf4000}, {0xb9cf6000}, + {0xb9cf8000}, {0xb9cfa000}, {0xb9cfc000}, {0xb9cfe000}, + {0xb9d00000}, {0xb9d02000}, {0xb9d04000}, {0xb9d06000}, + {0xb9d08000}, {0xb9d0a000}, {0xb9d0c000}, {0xb9d0e000}, + {0xb9d10000}, {0xb9d12000}, {0xb9d14000}, {0xb9d16000}, + {0xb9d18000}, {0xb9d1a000}, {0xb9d1c000}, {0xb9d1e000}, + {0xb9d20000}, {0xb9d22000}, {0xb9d24000}, {0xb9d26000}, + {0xb9d28000}, {0xb9d2a000}, {0xb9d2c000}, {0xb9d2e000}, + {0xb9d30000}, {0xb9d32000}, {0xb9d34000}, {0xb9d36000}, + {0xb9d38000}, {0xb9d3a000}, {0xb9d3c000}, {0xb9d3e000}, + {0xb9d40000}, {0xb9d42000}, {0xb9d44000}, {0xb9d46000}, + {0xb9d48000}, {0xb9d4a000}, {0xb9d4c000}, {0xb9d4e000}, + {0xb9d50000}, {0xb9d52000}, {0xb9d54000}, {0xb9d56000}, + {0xb9d58000}, {0xb9d5a000}, {0xb9d5c000}, {0xb9d5e000}, + {0xb9d60000}, {0xb9d62000}, {0xb9d64000}, {0xb9d66000}, + {0xb9d68000}, {0xb9d6a000}, {0xb9d6c000}, {0xb9d6e000}, + {0xb9d70000}, {0xb9d72000}, {0xb9d74000}, {0xb9d76000}, + {0xb9d78000}, {0xb9d7a000}, {0xb9d7c000}, {0xb9d7e000}, + {0xb9d80000}, {0xb9d82000}, {0xb9d84000}, {0xb9d86000}, + {0xb9d88000}, {0xb9d8a000}, {0xb9d8c000}, {0xb9d8e000}, + {0xb9d90000}, {0xb9d92000}, {0xb9d94000}, {0xb9d96000}, + {0xb9d98000}, {0xb9d9a000}, {0xb9d9c000}, {0xb9d9e000}, + {0xb9da0000}, {0xb9da2000}, {0xb9da4000}, {0xb9da6000}, + {0xb9da8000}, {0xb9daa000}, {0xb9dac000}, {0xb9dae000}, + {0xb9db0000}, {0xb9db2000}, {0xb9db4000}, {0xb9db6000}, + {0xb9db8000}, {0xb9dba000}, {0xb9dbc000}, {0xb9dbe000}, + {0xb9dc0000}, {0xb9dc2000}, {0xb9dc4000}, {0xb9dc6000}, + {0xb9dc8000}, {0xb9dca000}, {0xb9dcc000}, {0xb9dce000}, + {0xb9dd0000}, {0xb9dd2000}, {0xb9dd4000}, {0xb9dd6000}, + {0xb9dd8000}, {0xb9dda000}, {0xb9ddc000}, {0xb9dde000}, + {0xb9de0000}, {0xb9de2000}, {0xb9de4000}, {0xb9de6000}, + {0xb9de8000}, {0xb9dea000}, {0xb9dec000}, {0xb9dee000}, + {0xb9df0000}, {0xb9df2000}, {0xb9df4000}, {0xb9df6000}, + {0xb9df8000}, {0xb9dfa000}, {0xb9dfc000}, {0xb9dfe000}, + {0xb9e00000}, {0xb9e02000}, {0xb9e04000}, {0xb9e06000}, + {0xb9e08000}, {0xb9e0a000}, {0xb9e0c000}, {0xb9e0e000}, + {0xb9e10000}, {0xb9e12000}, {0xb9e14000}, {0xb9e16000}, + {0xb9e18000}, {0xb9e1a000}, {0xb9e1c000}, {0xb9e1e000}, + {0xb9e20000}, {0xb9e22000}, {0xb9e24000}, {0xb9e26000}, + {0xb9e28000}, {0xb9e2a000}, {0xb9e2c000}, {0xb9e2e000}, + {0xb9e30000}, {0xb9e32000}, {0xb9e34000}, {0xb9e36000}, + {0xb9e38000}, {0xb9e3a000}, {0xb9e3c000}, {0xb9e3e000}, + {0xb9e40000}, {0xb9e42000}, {0xb9e44000}, {0xb9e46000}, + {0xb9e48000}, {0xb9e4a000}, {0xb9e4c000}, {0xb9e4e000}, + {0xb9e50000}, {0xb9e52000}, {0xb9e54000}, {0xb9e56000}, + {0xb9e58000}, {0xb9e5a000}, {0xb9e5c000}, {0xb9e5e000}, + {0xb9e60000}, {0xb9e62000}, {0xb9e64000}, {0xb9e66000}, + {0xb9e68000}, {0xb9e6a000}, {0xb9e6c000}, {0xb9e6e000}, + {0xb9e70000}, {0xb9e72000}, {0xb9e74000}, {0xb9e76000}, + {0xb9e78000}, {0xb9e7a000}, {0xb9e7c000}, {0xb9e7e000}, + {0xb9e80000}, {0xb9e82000}, {0xb9e84000}, {0xb9e86000}, + {0xb9e88000}, {0xb9e8a000}, {0xb9e8c000}, {0xb9e8e000}, + {0xb9e90000}, {0xb9e92000}, {0xb9e94000}, {0xb9e96000}, + {0xb9e98000}, {0xb9e9a000}, {0xb9e9c000}, {0xb9e9e000}, + {0xb9ea0000}, {0xb9ea2000}, {0xb9ea4000}, {0xb9ea6000}, + {0xb9ea8000}, {0xb9eaa000}, {0xb9eac000}, {0xb9eae000}, + {0xb9eb0000}, {0xb9eb2000}, {0xb9eb4000}, {0xb9eb6000}, + {0xb9eb8000}, {0xb9eba000}, {0xb9ebc000}, {0xb9ebe000}, + {0xb9ec0000}, {0xb9ec2000}, {0xb9ec4000}, {0xb9ec6000}, + {0xb9ec8000}, {0xb9eca000}, {0xb9ecc000}, {0xb9ece000}, + {0xb9ed0000}, {0xb9ed2000}, {0xb9ed4000}, {0xb9ed6000}, + {0xb9ed8000}, {0xb9eda000}, {0xb9edc000}, {0xb9ede000}, + {0xb9ee0000}, {0xb9ee2000}, {0xb9ee4000}, {0xb9ee6000}, + {0xb9ee8000}, {0xb9eea000}, {0xb9eec000}, {0xb9eee000}, + {0xb9ef0000}, {0xb9ef2000}, {0xb9ef4000}, {0xb9ef6000}, + {0xb9ef8000}, {0xb9efa000}, {0xb9efc000}, {0xb9efe000}, + {0xb9f00000}, {0xb9f02000}, {0xb9f04000}, {0xb9f06000}, + {0xb9f08000}, {0xb9f0a000}, {0xb9f0c000}, {0xb9f0e000}, + {0xb9f10000}, {0xb9f12000}, {0xb9f14000}, {0xb9f16000}, + {0xb9f18000}, {0xb9f1a000}, {0xb9f1c000}, {0xb9f1e000}, + {0xb9f20000}, {0xb9f22000}, {0xb9f24000}, {0xb9f26000}, + {0xb9f28000}, {0xb9f2a000}, {0xb9f2c000}, {0xb9f2e000}, + {0xb9f30000}, {0xb9f32000}, {0xb9f34000}, {0xb9f36000}, + {0xb9f38000}, {0xb9f3a000}, {0xb9f3c000}, {0xb9f3e000}, + {0xb9f40000}, {0xb9f42000}, {0xb9f44000}, {0xb9f46000}, + {0xb9f48000}, {0xb9f4a000}, {0xb9f4c000}, {0xb9f4e000}, + {0xb9f50000}, {0xb9f52000}, {0xb9f54000}, {0xb9f56000}, + {0xb9f58000}, {0xb9f5a000}, {0xb9f5c000}, {0xb9f5e000}, + {0xb9f60000}, {0xb9f62000}, {0xb9f64000}, {0xb9f66000}, + {0xb9f68000}, {0xb9f6a000}, {0xb9f6c000}, {0xb9f6e000}, + {0xb9f70000}, {0xb9f72000}, {0xb9f74000}, {0xb9f76000}, + {0xb9f78000}, {0xb9f7a000}, {0xb9f7c000}, {0xb9f7e000}, + {0xb9f80000}, {0xb9f82000}, {0xb9f84000}, {0xb9f86000}, + {0xb9f88000}, {0xb9f8a000}, {0xb9f8c000}, {0xb9f8e000}, + {0xb9f90000}, {0xb9f92000}, {0xb9f94000}, {0xb9f96000}, + {0xb9f98000}, {0xb9f9a000}, {0xb9f9c000}, {0xb9f9e000}, + {0xb9fa0000}, {0xb9fa2000}, {0xb9fa4000}, {0xb9fa6000}, + {0xb9fa8000}, {0xb9faa000}, {0xb9fac000}, {0xb9fae000}, + {0xb9fb0000}, {0xb9fb2000}, {0xb9fb4000}, {0xb9fb6000}, + {0xb9fb8000}, {0xb9fba000}, {0xb9fbc000}, {0xb9fbe000}, + {0xb9fc0000}, {0xb9fc2000}, {0xb9fc4000}, {0xb9fc6000}, + {0xb9fc8000}, {0xb9fca000}, {0xb9fcc000}, {0xb9fce000}, + {0xb9fd0000}, {0xb9fd2000}, {0xb9fd4000}, {0xb9fd6000}, + {0xb9fd8000}, {0xb9fda000}, {0xb9fdc000}, {0xb9fde000}, + {0xb9fe0000}, {0xb9fe2000}, {0xb9fe4000}, {0xb9fe6000}, + {0xb9fe8000}, {0xb9fea000}, {0xb9fec000}, {0xb9fee000}, + {0xb9ff0000}, {0xb9ff2000}, {0xb9ff4000}, {0xb9ff6000}, + {0xb9ff8000}, {0xb9ffa000}, {0xb9ffc000}, {0xb9ffe000}, + {0xba000000}, {0xba002000}, {0xba004000}, {0xba006000}, + {0xba008000}, {0xba00a000}, {0xba00c000}, {0xba00e000}, + {0xba010000}, {0xba012000}, {0xba014000}, {0xba016000}, + {0xba018000}, {0xba01a000}, {0xba01c000}, {0xba01e000}, + {0xba020000}, {0xba022000}, {0xba024000}, {0xba026000}, + {0xba028000}, {0xba02a000}, {0xba02c000}, {0xba02e000}, + {0xba030000}, {0xba032000}, {0xba034000}, {0xba036000}, + {0xba038000}, {0xba03a000}, {0xba03c000}, {0xba03e000}, + {0xba040000}, {0xba042000}, {0xba044000}, {0xba046000}, + {0xba048000}, {0xba04a000}, {0xba04c000}, {0xba04e000}, + {0xba050000}, {0xba052000}, {0xba054000}, {0xba056000}, + {0xba058000}, {0xba05a000}, {0xba05c000}, {0xba05e000}, + {0xba060000}, {0xba062000}, {0xba064000}, {0xba066000}, + {0xba068000}, {0xba06a000}, {0xba06c000}, {0xba06e000}, + {0xba070000}, {0xba072000}, {0xba074000}, {0xba076000}, + {0xba078000}, {0xba07a000}, {0xba07c000}, {0xba07e000}, + {0xba080000}, {0xba082000}, {0xba084000}, {0xba086000}, + {0xba088000}, {0xba08a000}, {0xba08c000}, {0xba08e000}, + {0xba090000}, {0xba092000}, {0xba094000}, {0xba096000}, + {0xba098000}, {0xba09a000}, {0xba09c000}, {0xba09e000}, + {0xba0a0000}, {0xba0a2000}, {0xba0a4000}, {0xba0a6000}, + {0xba0a8000}, {0xba0aa000}, {0xba0ac000}, {0xba0ae000}, + {0xba0b0000}, {0xba0b2000}, {0xba0b4000}, {0xba0b6000}, + {0xba0b8000}, {0xba0ba000}, {0xba0bc000}, {0xba0be000}, + {0xba0c0000}, {0xba0c2000}, {0xba0c4000}, {0xba0c6000}, + {0xba0c8000}, {0xba0ca000}, {0xba0cc000}, {0xba0ce000}, + {0xba0d0000}, {0xba0d2000}, {0xba0d4000}, {0xba0d6000}, + {0xba0d8000}, {0xba0da000}, {0xba0dc000}, {0xba0de000}, + {0xba0e0000}, {0xba0e2000}, {0xba0e4000}, {0xba0e6000}, + {0xba0e8000}, {0xba0ea000}, {0xba0ec000}, {0xba0ee000}, + {0xba0f0000}, {0xba0f2000}, {0xba0f4000}, {0xba0f6000}, + {0xba0f8000}, {0xba0fa000}, {0xba0fc000}, {0xba0fe000}, + {0xba100000}, {0xba102000}, {0xba104000}, {0xba106000}, + {0xba108000}, {0xba10a000}, {0xba10c000}, {0xba10e000}, + {0xba110000}, {0xba112000}, {0xba114000}, {0xba116000}, + {0xba118000}, {0xba11a000}, {0xba11c000}, {0xba11e000}, + {0xba120000}, {0xba122000}, {0xba124000}, {0xba126000}, + {0xba128000}, {0xba12a000}, {0xba12c000}, {0xba12e000}, + {0xba130000}, {0xba132000}, {0xba134000}, {0xba136000}, + {0xba138000}, {0xba13a000}, {0xba13c000}, {0xba13e000}, + {0xba140000}, {0xba142000}, {0xba144000}, {0xba146000}, + {0xba148000}, {0xba14a000}, {0xba14c000}, {0xba14e000}, + {0xba150000}, {0xba152000}, {0xba154000}, {0xba156000}, + {0xba158000}, {0xba15a000}, {0xba15c000}, {0xba15e000}, + {0xba160000}, {0xba162000}, {0xba164000}, {0xba166000}, + {0xba168000}, {0xba16a000}, {0xba16c000}, {0xba16e000}, + {0xba170000}, {0xba172000}, {0xba174000}, {0xba176000}, + {0xba178000}, {0xba17a000}, {0xba17c000}, {0xba17e000}, + {0xba180000}, {0xba182000}, {0xba184000}, {0xba186000}, + {0xba188000}, {0xba18a000}, {0xba18c000}, {0xba18e000}, + {0xba190000}, {0xba192000}, {0xba194000}, {0xba196000}, + {0xba198000}, {0xba19a000}, {0xba19c000}, {0xba19e000}, + {0xba1a0000}, {0xba1a2000}, {0xba1a4000}, {0xba1a6000}, + {0xba1a8000}, {0xba1aa000}, {0xba1ac000}, {0xba1ae000}, + {0xba1b0000}, {0xba1b2000}, {0xba1b4000}, {0xba1b6000}, + {0xba1b8000}, {0xba1ba000}, {0xba1bc000}, {0xba1be000}, + {0xba1c0000}, {0xba1c2000}, {0xba1c4000}, {0xba1c6000}, + {0xba1c8000}, {0xba1ca000}, {0xba1cc000}, {0xba1ce000}, + {0xba1d0000}, {0xba1d2000}, {0xba1d4000}, {0xba1d6000}, + {0xba1d8000}, {0xba1da000}, {0xba1dc000}, {0xba1de000}, + {0xba1e0000}, {0xba1e2000}, {0xba1e4000}, {0xba1e6000}, + {0xba1e8000}, {0xba1ea000}, {0xba1ec000}, {0xba1ee000}, + {0xba1f0000}, {0xba1f2000}, {0xba1f4000}, {0xba1f6000}, + {0xba1f8000}, {0xba1fa000}, {0xba1fc000}, {0xba1fe000}, + {0xba200000}, {0xba202000}, {0xba204000}, {0xba206000}, + {0xba208000}, {0xba20a000}, {0xba20c000}, {0xba20e000}, + {0xba210000}, {0xba212000}, {0xba214000}, {0xba216000}, + {0xba218000}, {0xba21a000}, {0xba21c000}, {0xba21e000}, + {0xba220000}, {0xba222000}, {0xba224000}, {0xba226000}, + {0xba228000}, {0xba22a000}, {0xba22c000}, {0xba22e000}, + {0xba230000}, {0xba232000}, {0xba234000}, {0xba236000}, + {0xba238000}, {0xba23a000}, {0xba23c000}, {0xba23e000}, + {0xba240000}, {0xba242000}, {0xba244000}, {0xba246000}, + {0xba248000}, {0xba24a000}, {0xba24c000}, {0xba24e000}, + {0xba250000}, {0xba252000}, {0xba254000}, {0xba256000}, + {0xba258000}, {0xba25a000}, {0xba25c000}, {0xba25e000}, + {0xba260000}, {0xba262000}, {0xba264000}, {0xba266000}, + {0xba268000}, {0xba26a000}, {0xba26c000}, {0xba26e000}, + {0xba270000}, {0xba272000}, {0xba274000}, {0xba276000}, + {0xba278000}, {0xba27a000}, {0xba27c000}, {0xba27e000}, + {0xba280000}, {0xba282000}, {0xba284000}, {0xba286000}, + {0xba288000}, {0xba28a000}, {0xba28c000}, {0xba28e000}, + {0xba290000}, {0xba292000}, {0xba294000}, {0xba296000}, + {0xba298000}, {0xba29a000}, {0xba29c000}, {0xba29e000}, + {0xba2a0000}, {0xba2a2000}, {0xba2a4000}, {0xba2a6000}, + {0xba2a8000}, {0xba2aa000}, {0xba2ac000}, {0xba2ae000}, + {0xba2b0000}, {0xba2b2000}, {0xba2b4000}, {0xba2b6000}, + {0xba2b8000}, {0xba2ba000}, {0xba2bc000}, {0xba2be000}, + {0xba2c0000}, {0xba2c2000}, {0xba2c4000}, {0xba2c6000}, + {0xba2c8000}, {0xba2ca000}, {0xba2cc000}, {0xba2ce000}, + {0xba2d0000}, {0xba2d2000}, {0xba2d4000}, {0xba2d6000}, + {0xba2d8000}, {0xba2da000}, {0xba2dc000}, {0xba2de000}, + {0xba2e0000}, {0xba2e2000}, {0xba2e4000}, {0xba2e6000}, + {0xba2e8000}, {0xba2ea000}, {0xba2ec000}, {0xba2ee000}, + {0xba2f0000}, {0xba2f2000}, {0xba2f4000}, {0xba2f6000}, + {0xba2f8000}, {0xba2fa000}, {0xba2fc000}, {0xba2fe000}, + {0xba300000}, {0xba302000}, {0xba304000}, {0xba306000}, + {0xba308000}, {0xba30a000}, {0xba30c000}, {0xba30e000}, + {0xba310000}, {0xba312000}, {0xba314000}, {0xba316000}, + {0xba318000}, {0xba31a000}, {0xba31c000}, {0xba31e000}, + {0xba320000}, {0xba322000}, {0xba324000}, {0xba326000}, + {0xba328000}, {0xba32a000}, {0xba32c000}, {0xba32e000}, + {0xba330000}, {0xba332000}, {0xba334000}, {0xba336000}, + {0xba338000}, {0xba33a000}, {0xba33c000}, {0xba33e000}, + {0xba340000}, {0xba342000}, {0xba344000}, {0xba346000}, + {0xba348000}, {0xba34a000}, {0xba34c000}, {0xba34e000}, + {0xba350000}, {0xba352000}, {0xba354000}, {0xba356000}, + {0xba358000}, {0xba35a000}, {0xba35c000}, {0xba35e000}, + {0xba360000}, {0xba362000}, {0xba364000}, {0xba366000}, + {0xba368000}, {0xba36a000}, {0xba36c000}, {0xba36e000}, + {0xba370000}, {0xba372000}, {0xba374000}, {0xba376000}, + {0xba378000}, {0xba37a000}, {0xba37c000}, {0xba37e000}, + {0xba380000}, {0xba382000}, {0xba384000}, {0xba386000}, + {0xba388000}, {0xba38a000}, {0xba38c000}, {0xba38e000}, + {0xba390000}, {0xba392000}, {0xba394000}, {0xba396000}, + {0xba398000}, {0xba39a000}, {0xba39c000}, {0xba39e000}, + {0xba3a0000}, {0xba3a2000}, {0xba3a4000}, {0xba3a6000}, + {0xba3a8000}, {0xba3aa000}, {0xba3ac000}, {0xba3ae000}, + {0xba3b0000}, {0xba3b2000}, {0xba3b4000}, {0xba3b6000}, + {0xba3b8000}, {0xba3ba000}, {0xba3bc000}, {0xba3be000}, + {0xba3c0000}, {0xba3c2000}, {0xba3c4000}, {0xba3c6000}, + {0xba3c8000}, {0xba3ca000}, {0xba3cc000}, {0xba3ce000}, + {0xba3d0000}, {0xba3d2000}, {0xba3d4000}, {0xba3d6000}, + {0xba3d8000}, {0xba3da000}, {0xba3dc000}, {0xba3de000}, + {0xba3e0000}, {0xba3e2000}, {0xba3e4000}, {0xba3e6000}, + {0xba3e8000}, {0xba3ea000}, {0xba3ec000}, {0xba3ee000}, + {0xba3f0000}, {0xba3f2000}, {0xba3f4000}, {0xba3f6000}, + {0xba3f8000}, {0xba3fa000}, {0xba3fc000}, {0xba3fe000}, + {0xba400000}, {0xba402000}, {0xba404000}, {0xba406000}, + {0xba408000}, {0xba40a000}, {0xba40c000}, {0xba40e000}, + {0xba410000}, {0xba412000}, {0xba414000}, {0xba416000}, + {0xba418000}, {0xba41a000}, {0xba41c000}, {0xba41e000}, + {0xba420000}, {0xba422000}, {0xba424000}, {0xba426000}, + {0xba428000}, {0xba42a000}, {0xba42c000}, {0xba42e000}, + {0xba430000}, {0xba432000}, {0xba434000}, {0xba436000}, + {0xba438000}, {0xba43a000}, {0xba43c000}, {0xba43e000}, + {0xba440000}, {0xba442000}, {0xba444000}, {0xba446000}, + {0xba448000}, {0xba44a000}, {0xba44c000}, {0xba44e000}, + {0xba450000}, {0xba452000}, {0xba454000}, {0xba456000}, + {0xba458000}, {0xba45a000}, {0xba45c000}, {0xba45e000}, + {0xba460000}, {0xba462000}, {0xba464000}, {0xba466000}, + {0xba468000}, {0xba46a000}, {0xba46c000}, {0xba46e000}, + {0xba470000}, {0xba472000}, {0xba474000}, {0xba476000}, + {0xba478000}, {0xba47a000}, {0xba47c000}, {0xba47e000}, + {0xba480000}, {0xba482000}, {0xba484000}, {0xba486000}, + {0xba488000}, {0xba48a000}, {0xba48c000}, {0xba48e000}, + {0xba490000}, {0xba492000}, {0xba494000}, {0xba496000}, + {0xba498000}, {0xba49a000}, {0xba49c000}, {0xba49e000}, + {0xba4a0000}, {0xba4a2000}, {0xba4a4000}, {0xba4a6000}, + {0xba4a8000}, {0xba4aa000}, {0xba4ac000}, {0xba4ae000}, + {0xba4b0000}, {0xba4b2000}, {0xba4b4000}, {0xba4b6000}, + {0xba4b8000}, {0xba4ba000}, {0xba4bc000}, {0xba4be000}, + {0xba4c0000}, {0xba4c2000}, {0xba4c4000}, {0xba4c6000}, + {0xba4c8000}, {0xba4ca000}, {0xba4cc000}, {0xba4ce000}, + {0xba4d0000}, {0xba4d2000}, {0xba4d4000}, {0xba4d6000}, + {0xba4d8000}, {0xba4da000}, {0xba4dc000}, {0xba4de000}, + {0xba4e0000}, {0xba4e2000}, {0xba4e4000}, {0xba4e6000}, + {0xba4e8000}, {0xba4ea000}, {0xba4ec000}, {0xba4ee000}, + {0xba4f0000}, {0xba4f2000}, {0xba4f4000}, {0xba4f6000}, + {0xba4f8000}, {0xba4fa000}, {0xba4fc000}, {0xba4fe000}, + {0xba500000}, {0xba502000}, {0xba504000}, {0xba506000}, + {0xba508000}, {0xba50a000}, {0xba50c000}, {0xba50e000}, + {0xba510000}, {0xba512000}, {0xba514000}, {0xba516000}, + {0xba518000}, {0xba51a000}, {0xba51c000}, {0xba51e000}, + {0xba520000}, {0xba522000}, {0xba524000}, {0xba526000}, + {0xba528000}, {0xba52a000}, {0xba52c000}, {0xba52e000}, + {0xba530000}, {0xba532000}, {0xba534000}, {0xba536000}, + {0xba538000}, {0xba53a000}, {0xba53c000}, {0xba53e000}, + {0xba540000}, {0xba542000}, {0xba544000}, {0xba546000}, + {0xba548000}, {0xba54a000}, {0xba54c000}, {0xba54e000}, + {0xba550000}, {0xba552000}, {0xba554000}, {0xba556000}, + {0xba558000}, {0xba55a000}, {0xba55c000}, {0xba55e000}, + {0xba560000}, {0xba562000}, {0xba564000}, {0xba566000}, + {0xba568000}, {0xba56a000}, {0xba56c000}, {0xba56e000}, + {0xba570000}, {0xba572000}, {0xba574000}, {0xba576000}, + {0xba578000}, {0xba57a000}, {0xba57c000}, {0xba57e000}, + {0xba580000}, {0xba582000}, {0xba584000}, {0xba586000}, + {0xba588000}, {0xba58a000}, {0xba58c000}, {0xba58e000}, + {0xba590000}, {0xba592000}, {0xba594000}, {0xba596000}, + {0xba598000}, {0xba59a000}, {0xba59c000}, {0xba59e000}, + {0xba5a0000}, {0xba5a2000}, {0xba5a4000}, {0xba5a6000}, + {0xba5a8000}, {0xba5aa000}, {0xba5ac000}, {0xba5ae000}, + {0xba5b0000}, {0xba5b2000}, {0xba5b4000}, {0xba5b6000}, + {0xba5b8000}, {0xba5ba000}, {0xba5bc000}, {0xba5be000}, + {0xba5c0000}, {0xba5c2000}, {0xba5c4000}, {0xba5c6000}, + {0xba5c8000}, {0xba5ca000}, {0xba5cc000}, {0xba5ce000}, + {0xba5d0000}, {0xba5d2000}, {0xba5d4000}, {0xba5d6000}, + {0xba5d8000}, {0xba5da000}, {0xba5dc000}, {0xba5de000}, + {0xba5e0000}, {0xba5e2000}, {0xba5e4000}, {0xba5e6000}, + {0xba5e8000}, {0xba5ea000}, {0xba5ec000}, {0xba5ee000}, + {0xba5f0000}, {0xba5f2000}, {0xba5f4000}, {0xba5f6000}, + {0xba5f8000}, {0xba5fa000}, {0xba5fc000}, {0xba5fe000}, + {0xba600000}, {0xba602000}, {0xba604000}, {0xba606000}, + {0xba608000}, {0xba60a000}, {0xba60c000}, {0xba60e000}, + {0xba610000}, {0xba612000}, {0xba614000}, {0xba616000}, + {0xba618000}, {0xba61a000}, {0xba61c000}, {0xba61e000}, + {0xba620000}, {0xba622000}, {0xba624000}, {0xba626000}, + {0xba628000}, {0xba62a000}, {0xba62c000}, {0xba62e000}, + {0xba630000}, {0xba632000}, {0xba634000}, {0xba636000}, + {0xba638000}, {0xba63a000}, {0xba63c000}, {0xba63e000}, + {0xba640000}, {0xba642000}, {0xba644000}, {0xba646000}, + {0xba648000}, {0xba64a000}, {0xba64c000}, {0xba64e000}, + {0xba650000}, {0xba652000}, {0xba654000}, {0xba656000}, + {0xba658000}, {0xba65a000}, {0xba65c000}, {0xba65e000}, + {0xba660000}, {0xba662000}, {0xba664000}, {0xba666000}, + {0xba668000}, {0xba66a000}, {0xba66c000}, {0xba66e000}, + {0xba670000}, {0xba672000}, {0xba674000}, {0xba676000}, + {0xba678000}, {0xba67a000}, {0xba67c000}, {0xba67e000}, + {0xba680000}, {0xba682000}, {0xba684000}, {0xba686000}, + {0xba688000}, {0xba68a000}, {0xba68c000}, {0xba68e000}, + {0xba690000}, {0xba692000}, {0xba694000}, {0xba696000}, + {0xba698000}, {0xba69a000}, {0xba69c000}, {0xba69e000}, + {0xba6a0000}, {0xba6a2000}, {0xba6a4000}, {0xba6a6000}, + {0xba6a8000}, {0xba6aa000}, {0xba6ac000}, {0xba6ae000}, + {0xba6b0000}, {0xba6b2000}, {0xba6b4000}, {0xba6b6000}, + {0xba6b8000}, {0xba6ba000}, {0xba6bc000}, {0xba6be000}, + {0xba6c0000}, {0xba6c2000}, {0xba6c4000}, {0xba6c6000}, + {0xba6c8000}, {0xba6ca000}, {0xba6cc000}, {0xba6ce000}, + {0xba6d0000}, {0xba6d2000}, {0xba6d4000}, {0xba6d6000}, + {0xba6d8000}, {0xba6da000}, {0xba6dc000}, {0xba6de000}, + {0xba6e0000}, {0xba6e2000}, {0xba6e4000}, {0xba6e6000}, + {0xba6e8000}, {0xba6ea000}, {0xba6ec000}, {0xba6ee000}, + {0xba6f0000}, {0xba6f2000}, {0xba6f4000}, {0xba6f6000}, + {0xba6f8000}, {0xba6fa000}, {0xba6fc000}, {0xba6fe000}, + {0xba700000}, {0xba702000}, {0xba704000}, {0xba706000}, + {0xba708000}, {0xba70a000}, {0xba70c000}, {0xba70e000}, + {0xba710000}, {0xba712000}, {0xba714000}, {0xba716000}, + {0xba718000}, {0xba71a000}, {0xba71c000}, {0xba71e000}, + {0xba720000}, {0xba722000}, {0xba724000}, {0xba726000}, + {0xba728000}, {0xba72a000}, {0xba72c000}, {0xba72e000}, + {0xba730000}, {0xba732000}, {0xba734000}, {0xba736000}, + {0xba738000}, {0xba73a000}, {0xba73c000}, {0xba73e000}, + {0xba740000}, {0xba742000}, {0xba744000}, {0xba746000}, + {0xba748000}, {0xba74a000}, {0xba74c000}, {0xba74e000}, + {0xba750000}, {0xba752000}, {0xba754000}, {0xba756000}, + {0xba758000}, {0xba75a000}, {0xba75c000}, {0xba75e000}, + {0xba760000}, {0xba762000}, {0xba764000}, {0xba766000}, + {0xba768000}, {0xba76a000}, {0xba76c000}, {0xba76e000}, + {0xba770000}, {0xba772000}, {0xba774000}, {0xba776000}, + {0xba778000}, {0xba77a000}, {0xba77c000}, {0xba77e000}, + {0xba780000}, {0xba782000}, {0xba784000}, {0xba786000}, + {0xba788000}, {0xba78a000}, {0xba78c000}, {0xba78e000}, + {0xba790000}, {0xba792000}, {0xba794000}, {0xba796000}, + {0xba798000}, {0xba79a000}, {0xba79c000}, {0xba79e000}, + {0xba7a0000}, {0xba7a2000}, {0xba7a4000}, {0xba7a6000}, + {0xba7a8000}, {0xba7aa000}, {0xba7ac000}, {0xba7ae000}, + {0xba7b0000}, {0xba7b2000}, {0xba7b4000}, {0xba7b6000}, + {0xba7b8000}, {0xba7ba000}, {0xba7bc000}, {0xba7be000}, + {0xba7c0000}, {0xba7c2000}, {0xba7c4000}, {0xba7c6000}, + {0xba7c8000}, {0xba7ca000}, {0xba7cc000}, {0xba7ce000}, + {0xba7d0000}, {0xba7d2000}, {0xba7d4000}, {0xba7d6000}, + {0xba7d8000}, {0xba7da000}, {0xba7dc000}, {0xba7de000}, + {0xba7e0000}, {0xba7e2000}, {0xba7e4000}, {0xba7e6000}, + {0xba7e8000}, {0xba7ea000}, {0xba7ec000}, {0xba7ee000}, + {0xba7f0000}, {0xba7f2000}, {0xba7f4000}, {0xba7f6000}, + {0xba7f8000}, {0xba7fa000}, {0xba7fc000}, {0xba7fe000}, + {0xba800000}, {0xba802000}, {0xba804000}, {0xba806000}, + {0xba808000}, {0xba80a000}, {0xba80c000}, {0xba80e000}, + {0xba810000}, {0xba812000}, {0xba814000}, {0xba816000}, + {0xba818000}, {0xba81a000}, {0xba81c000}, {0xba81e000}, + {0xba820000}, {0xba822000}, {0xba824000}, {0xba826000}, + {0xba828000}, {0xba82a000}, {0xba82c000}, {0xba82e000}, + {0xba830000}, {0xba832000}, {0xba834000}, {0xba836000}, + {0xba838000}, {0xba83a000}, {0xba83c000}, {0xba83e000}, + {0xba840000}, {0xba842000}, {0xba844000}, {0xba846000}, + {0xba848000}, {0xba84a000}, {0xba84c000}, {0xba84e000}, + {0xba850000}, {0xba852000}, {0xba854000}, {0xba856000}, + {0xba858000}, {0xba85a000}, {0xba85c000}, {0xba85e000}, + {0xba860000}, {0xba862000}, {0xba864000}, {0xba866000}, + {0xba868000}, {0xba86a000}, {0xba86c000}, {0xba86e000}, + {0xba870000}, {0xba872000}, {0xba874000}, {0xba876000}, + {0xba878000}, {0xba87a000}, {0xba87c000}, {0xba87e000}, + {0xba880000}, {0xba882000}, {0xba884000}, {0xba886000}, + {0xba888000}, {0xba88a000}, {0xba88c000}, {0xba88e000}, + {0xba890000}, {0xba892000}, {0xba894000}, {0xba896000}, + {0xba898000}, {0xba89a000}, {0xba89c000}, {0xba89e000}, + {0xba8a0000}, {0xba8a2000}, {0xba8a4000}, {0xba8a6000}, + {0xba8a8000}, {0xba8aa000}, {0xba8ac000}, {0xba8ae000}, + {0xba8b0000}, {0xba8b2000}, {0xba8b4000}, {0xba8b6000}, + {0xba8b8000}, {0xba8ba000}, {0xba8bc000}, {0xba8be000}, + {0xba8c0000}, {0xba8c2000}, {0xba8c4000}, {0xba8c6000}, + {0xba8c8000}, {0xba8ca000}, {0xba8cc000}, {0xba8ce000}, + {0xba8d0000}, {0xba8d2000}, {0xba8d4000}, {0xba8d6000}, + {0xba8d8000}, {0xba8da000}, {0xba8dc000}, {0xba8de000}, + {0xba8e0000}, {0xba8e2000}, {0xba8e4000}, {0xba8e6000}, + {0xba8e8000}, {0xba8ea000}, {0xba8ec000}, {0xba8ee000}, + {0xba8f0000}, {0xba8f2000}, {0xba8f4000}, {0xba8f6000}, + {0xba8f8000}, {0xba8fa000}, {0xba8fc000}, {0xba8fe000}, + {0xba900000}, {0xba902000}, {0xba904000}, {0xba906000}, + {0xba908000}, {0xba90a000}, {0xba90c000}, {0xba90e000}, + {0xba910000}, {0xba912000}, {0xba914000}, {0xba916000}, + {0xba918000}, {0xba91a000}, {0xba91c000}, {0xba91e000}, + {0xba920000}, {0xba922000}, {0xba924000}, {0xba926000}, + {0xba928000}, {0xba92a000}, {0xba92c000}, {0xba92e000}, + {0xba930000}, {0xba932000}, {0xba934000}, {0xba936000}, + {0xba938000}, {0xba93a000}, {0xba93c000}, {0xba93e000}, + {0xba940000}, {0xba942000}, {0xba944000}, {0xba946000}, + {0xba948000}, {0xba94a000}, {0xba94c000}, {0xba94e000}, + {0xba950000}, {0xba952000}, {0xba954000}, {0xba956000}, + {0xba958000}, {0xba95a000}, {0xba95c000}, {0xba95e000}, + {0xba960000}, {0xba962000}, {0xba964000}, {0xba966000}, + {0xba968000}, {0xba96a000}, {0xba96c000}, {0xba96e000}, + {0xba970000}, {0xba972000}, {0xba974000}, {0xba976000}, + {0xba978000}, {0xba97a000}, {0xba97c000}, {0xba97e000}, + {0xba980000}, {0xba982000}, {0xba984000}, {0xba986000}, + {0xba988000}, {0xba98a000}, {0xba98c000}, {0xba98e000}, + {0xba990000}, {0xba992000}, {0xba994000}, {0xba996000}, + {0xba998000}, {0xba99a000}, {0xba99c000}, {0xba99e000}, + {0xba9a0000}, {0xba9a2000}, {0xba9a4000}, {0xba9a6000}, + {0xba9a8000}, {0xba9aa000}, {0xba9ac000}, {0xba9ae000}, + {0xba9b0000}, {0xba9b2000}, {0xba9b4000}, {0xba9b6000}, + {0xba9b8000}, {0xba9ba000}, {0xba9bc000}, {0xba9be000}, + {0xba9c0000}, {0xba9c2000}, {0xba9c4000}, {0xba9c6000}, + {0xba9c8000}, {0xba9ca000}, {0xba9cc000}, {0xba9ce000}, + {0xba9d0000}, {0xba9d2000}, {0xba9d4000}, {0xba9d6000}, + {0xba9d8000}, {0xba9da000}, {0xba9dc000}, {0xba9de000}, + {0xba9e0000}, {0xba9e2000}, {0xba9e4000}, {0xba9e6000}, + {0xba9e8000}, {0xba9ea000}, {0xba9ec000}, {0xba9ee000}, + {0xba9f0000}, {0xba9f2000}, {0xba9f4000}, {0xba9f6000}, + {0xba9f8000}, {0xba9fa000}, {0xba9fc000}, {0xba9fe000}, + {0xbaa00000}, {0xbaa02000}, {0xbaa04000}, {0xbaa06000}, + {0xbaa08000}, {0xbaa0a000}, {0xbaa0c000}, {0xbaa0e000}, + {0xbaa10000}, {0xbaa12000}, {0xbaa14000}, {0xbaa16000}, + {0xbaa18000}, {0xbaa1a000}, {0xbaa1c000}, {0xbaa1e000}, + {0xbaa20000}, {0xbaa22000}, {0xbaa24000}, {0xbaa26000}, + {0xbaa28000}, {0xbaa2a000}, {0xbaa2c000}, {0xbaa2e000}, + {0xbaa30000}, {0xbaa32000}, {0xbaa34000}, {0xbaa36000}, + {0xbaa38000}, {0xbaa3a000}, {0xbaa3c000}, {0xbaa3e000}, + {0xbaa40000}, {0xbaa42000}, {0xbaa44000}, {0xbaa46000}, + {0xbaa48000}, {0xbaa4a000}, {0xbaa4c000}, {0xbaa4e000}, + {0xbaa50000}, {0xbaa52000}, {0xbaa54000}, {0xbaa56000}, + {0xbaa58000}, {0xbaa5a000}, {0xbaa5c000}, {0xbaa5e000}, + {0xbaa60000}, {0xbaa62000}, {0xbaa64000}, {0xbaa66000}, + {0xbaa68000}, {0xbaa6a000}, {0xbaa6c000}, {0xbaa6e000}, + {0xbaa70000}, {0xbaa72000}, {0xbaa74000}, {0xbaa76000}, + {0xbaa78000}, {0xbaa7a000}, {0xbaa7c000}, {0xbaa7e000}, + {0xbaa80000}, {0xbaa82000}, {0xbaa84000}, {0xbaa86000}, + {0xbaa88000}, {0xbaa8a000}, {0xbaa8c000}, {0xbaa8e000}, + {0xbaa90000}, {0xbaa92000}, {0xbaa94000}, {0xbaa96000}, + {0xbaa98000}, {0xbaa9a000}, {0xbaa9c000}, {0xbaa9e000}, + {0xbaaa0000}, {0xbaaa2000}, {0xbaaa4000}, {0xbaaa6000}, + {0xbaaa8000}, {0xbaaaa000}, {0xbaaac000}, {0xbaaae000}, + {0xbaab0000}, {0xbaab2000}, {0xbaab4000}, {0xbaab6000}, + {0xbaab8000}, {0xbaaba000}, {0xbaabc000}, {0xbaabe000}, + {0xbaac0000}, {0xbaac2000}, {0xbaac4000}, {0xbaac6000}, + {0xbaac8000}, {0xbaaca000}, {0xbaacc000}, {0xbaace000}, + {0xbaad0000}, {0xbaad2000}, {0xbaad4000}, {0xbaad6000}, + {0xbaad8000}, {0xbaada000}, {0xbaadc000}, {0xbaade000}, + {0xbaae0000}, {0xbaae2000}, {0xbaae4000}, {0xbaae6000}, + {0xbaae8000}, {0xbaaea000}, {0xbaaec000}, {0xbaaee000}, + {0xbaaf0000}, {0xbaaf2000}, {0xbaaf4000}, {0xbaaf6000}, + {0xbaaf8000}, {0xbaafa000}, {0xbaafc000}, {0xbaafe000}, + {0xbab00000}, {0xbab02000}, {0xbab04000}, {0xbab06000}, + {0xbab08000}, {0xbab0a000}, {0xbab0c000}, {0xbab0e000}, + {0xbab10000}, {0xbab12000}, {0xbab14000}, {0xbab16000}, + {0xbab18000}, {0xbab1a000}, {0xbab1c000}, {0xbab1e000}, + {0xbab20000}, {0xbab22000}, {0xbab24000}, {0xbab26000}, + {0xbab28000}, {0xbab2a000}, {0xbab2c000}, {0xbab2e000}, + {0xbab30000}, {0xbab32000}, {0xbab34000}, {0xbab36000}, + {0xbab38000}, {0xbab3a000}, {0xbab3c000}, {0xbab3e000}, + {0xbab40000}, {0xbab42000}, {0xbab44000}, {0xbab46000}, + {0xbab48000}, {0xbab4a000}, {0xbab4c000}, {0xbab4e000}, + {0xbab50000}, {0xbab52000}, {0xbab54000}, {0xbab56000}, + {0xbab58000}, {0xbab5a000}, {0xbab5c000}, {0xbab5e000}, + {0xbab60000}, {0xbab62000}, {0xbab64000}, {0xbab66000}, + {0xbab68000}, {0xbab6a000}, {0xbab6c000}, {0xbab6e000}, + {0xbab70000}, {0xbab72000}, {0xbab74000}, {0xbab76000}, + {0xbab78000}, {0xbab7a000}, {0xbab7c000}, {0xbab7e000}, + {0xbab80000}, {0xbab82000}, {0xbab84000}, {0xbab86000}, + {0xbab88000}, {0xbab8a000}, {0xbab8c000}, {0xbab8e000}, + {0xbab90000}, {0xbab92000}, {0xbab94000}, {0xbab96000}, + {0xbab98000}, {0xbab9a000}, {0xbab9c000}, {0xbab9e000}, + {0xbaba0000}, {0xbaba2000}, {0xbaba4000}, {0xbaba6000}, + {0xbaba8000}, {0xbabaa000}, {0xbabac000}, {0xbabae000}, + {0xbabb0000}, {0xbabb2000}, {0xbabb4000}, {0xbabb6000}, + {0xbabb8000}, {0xbabba000}, {0xbabbc000}, {0xbabbe000}, + {0xbabc0000}, {0xbabc2000}, {0xbabc4000}, {0xbabc6000}, + {0xbabc8000}, {0xbabca000}, {0xbabcc000}, {0xbabce000}, + {0xbabd0000}, {0xbabd2000}, {0xbabd4000}, {0xbabd6000}, + {0xbabd8000}, {0xbabda000}, {0xbabdc000}, {0xbabde000}, + {0xbabe0000}, {0xbabe2000}, {0xbabe4000}, {0xbabe6000}, + {0xbabe8000}, {0xbabea000}, {0xbabec000}, {0xbabee000}, + {0xbabf0000}, {0xbabf2000}, {0xbabf4000}, {0xbabf6000}, + {0xbabf8000}, {0xbabfa000}, {0xbabfc000}, {0xbabfe000}, + {0xbac00000}, {0xbac02000}, {0xbac04000}, {0xbac06000}, + {0xbac08000}, {0xbac0a000}, {0xbac0c000}, {0xbac0e000}, + {0xbac10000}, {0xbac12000}, {0xbac14000}, {0xbac16000}, + {0xbac18000}, {0xbac1a000}, {0xbac1c000}, {0xbac1e000}, + {0xbac20000}, {0xbac22000}, {0xbac24000}, {0xbac26000}, + {0xbac28000}, {0xbac2a000}, {0xbac2c000}, {0xbac2e000}, + {0xbac30000}, {0xbac32000}, {0xbac34000}, {0xbac36000}, + {0xbac38000}, {0xbac3a000}, {0xbac3c000}, {0xbac3e000}, + {0xbac40000}, {0xbac42000}, {0xbac44000}, {0xbac46000}, + {0xbac48000}, {0xbac4a000}, {0xbac4c000}, {0xbac4e000}, + {0xbac50000}, {0xbac52000}, {0xbac54000}, {0xbac56000}, + {0xbac58000}, {0xbac5a000}, {0xbac5c000}, {0xbac5e000}, + {0xbac60000}, {0xbac62000}, {0xbac64000}, {0xbac66000}, + {0xbac68000}, {0xbac6a000}, {0xbac6c000}, {0xbac6e000}, + {0xbac70000}, {0xbac72000}, {0xbac74000}, {0xbac76000}, + {0xbac78000}, {0xbac7a000}, {0xbac7c000}, {0xbac7e000}, + {0xbac80000}, {0xbac82000}, {0xbac84000}, {0xbac86000}, + {0xbac88000}, {0xbac8a000}, {0xbac8c000}, {0xbac8e000}, + {0xbac90000}, {0xbac92000}, {0xbac94000}, {0xbac96000}, + {0xbac98000}, {0xbac9a000}, {0xbac9c000}, {0xbac9e000}, + {0xbaca0000}, {0xbaca2000}, {0xbaca4000}, {0xbaca6000}, + {0xbaca8000}, {0xbacaa000}, {0xbacac000}, {0xbacae000}, + {0xbacb0000}, {0xbacb2000}, {0xbacb4000}, {0xbacb6000}, + {0xbacb8000}, {0xbacba000}, {0xbacbc000}, {0xbacbe000}, + {0xbacc0000}, {0xbacc2000}, {0xbacc4000}, {0xbacc6000}, + {0xbacc8000}, {0xbacca000}, {0xbaccc000}, {0xbacce000}, + {0xbacd0000}, {0xbacd2000}, {0xbacd4000}, {0xbacd6000}, + {0xbacd8000}, {0xbacda000}, {0xbacdc000}, {0xbacde000}, + {0xbace0000}, {0xbace2000}, {0xbace4000}, {0xbace6000}, + {0xbace8000}, {0xbacea000}, {0xbacec000}, {0xbacee000}, + {0xbacf0000}, {0xbacf2000}, {0xbacf4000}, {0xbacf6000}, + {0xbacf8000}, {0xbacfa000}, {0xbacfc000}, {0xbacfe000}, + {0xbad00000}, {0xbad02000}, {0xbad04000}, {0xbad06000}, + {0xbad08000}, {0xbad0a000}, {0xbad0c000}, {0xbad0e000}, + {0xbad10000}, {0xbad12000}, {0xbad14000}, {0xbad16000}, + {0xbad18000}, {0xbad1a000}, {0xbad1c000}, {0xbad1e000}, + {0xbad20000}, {0xbad22000}, {0xbad24000}, {0xbad26000}, + {0xbad28000}, {0xbad2a000}, {0xbad2c000}, {0xbad2e000}, + {0xbad30000}, {0xbad32000}, {0xbad34000}, {0xbad36000}, + {0xbad38000}, {0xbad3a000}, {0xbad3c000}, {0xbad3e000}, + {0xbad40000}, {0xbad42000}, {0xbad44000}, {0xbad46000}, + {0xbad48000}, {0xbad4a000}, {0xbad4c000}, {0xbad4e000}, + {0xbad50000}, {0xbad52000}, {0xbad54000}, {0xbad56000}, + {0xbad58000}, {0xbad5a000}, {0xbad5c000}, {0xbad5e000}, + {0xbad60000}, {0xbad62000}, {0xbad64000}, {0xbad66000}, + {0xbad68000}, {0xbad6a000}, {0xbad6c000}, {0xbad6e000}, + {0xbad70000}, {0xbad72000}, {0xbad74000}, {0xbad76000}, + {0xbad78000}, {0xbad7a000}, {0xbad7c000}, {0xbad7e000}, + {0xbad80000}, {0xbad82000}, {0xbad84000}, {0xbad86000}, + {0xbad88000}, {0xbad8a000}, {0xbad8c000}, {0xbad8e000}, + {0xbad90000}, {0xbad92000}, {0xbad94000}, {0xbad96000}, + {0xbad98000}, {0xbad9a000}, {0xbad9c000}, {0xbad9e000}, + {0xbada0000}, {0xbada2000}, {0xbada4000}, {0xbada6000}, + {0xbada8000}, {0xbadaa000}, {0xbadac000}, {0xbadae000}, + {0xbadb0000}, {0xbadb2000}, {0xbadb4000}, {0xbadb6000}, + {0xbadb8000}, {0xbadba000}, {0xbadbc000}, {0xbadbe000}, + {0xbadc0000}, {0xbadc2000}, {0xbadc4000}, {0xbadc6000}, + {0xbadc8000}, {0xbadca000}, {0xbadcc000}, {0xbadce000}, + {0xbadd0000}, {0xbadd2000}, {0xbadd4000}, {0xbadd6000}, + {0xbadd8000}, {0xbadda000}, {0xbaddc000}, {0xbadde000}, + {0xbade0000}, {0xbade2000}, {0xbade4000}, {0xbade6000}, + {0xbade8000}, {0xbadea000}, {0xbadec000}, {0xbadee000}, + {0xbadf0000}, {0xbadf2000}, {0xbadf4000}, {0xbadf6000}, + {0xbadf8000}, {0xbadfa000}, {0xbadfc000}, {0xbadfe000}, + {0xbae00000}, {0xbae02000}, {0xbae04000}, {0xbae06000}, + {0xbae08000}, {0xbae0a000}, {0xbae0c000}, {0xbae0e000}, + {0xbae10000}, {0xbae12000}, {0xbae14000}, {0xbae16000}, + {0xbae18000}, {0xbae1a000}, {0xbae1c000}, {0xbae1e000}, + {0xbae20000}, {0xbae22000}, {0xbae24000}, {0xbae26000}, + {0xbae28000}, {0xbae2a000}, {0xbae2c000}, {0xbae2e000}, + {0xbae30000}, {0xbae32000}, {0xbae34000}, {0xbae36000}, + {0xbae38000}, {0xbae3a000}, {0xbae3c000}, {0xbae3e000}, + {0xbae40000}, {0xbae42000}, {0xbae44000}, {0xbae46000}, + {0xbae48000}, {0xbae4a000}, {0xbae4c000}, {0xbae4e000}, + {0xbae50000}, {0xbae52000}, {0xbae54000}, {0xbae56000}, + {0xbae58000}, {0xbae5a000}, {0xbae5c000}, {0xbae5e000}, + {0xbae60000}, {0xbae62000}, {0xbae64000}, {0xbae66000}, + {0xbae68000}, {0xbae6a000}, {0xbae6c000}, {0xbae6e000}, + {0xbae70000}, {0xbae72000}, {0xbae74000}, {0xbae76000}, + {0xbae78000}, {0xbae7a000}, {0xbae7c000}, {0xbae7e000}, + {0xbae80000}, {0xbae82000}, {0xbae84000}, {0xbae86000}, + {0xbae88000}, {0xbae8a000}, {0xbae8c000}, {0xbae8e000}, + {0xbae90000}, {0xbae92000}, {0xbae94000}, {0xbae96000}, + {0xbae98000}, {0xbae9a000}, {0xbae9c000}, {0xbae9e000}, + {0xbaea0000}, {0xbaea2000}, {0xbaea4000}, {0xbaea6000}, + {0xbaea8000}, {0xbaeaa000}, {0xbaeac000}, {0xbaeae000}, + {0xbaeb0000}, {0xbaeb2000}, {0xbaeb4000}, {0xbaeb6000}, + {0xbaeb8000}, {0xbaeba000}, {0xbaebc000}, {0xbaebe000}, + {0xbaec0000}, {0xbaec2000}, {0xbaec4000}, {0xbaec6000}, + {0xbaec8000}, {0xbaeca000}, {0xbaecc000}, {0xbaece000}, + {0xbaed0000}, {0xbaed2000}, {0xbaed4000}, {0xbaed6000}, + {0xbaed8000}, {0xbaeda000}, {0xbaedc000}, {0xbaede000}, + {0xbaee0000}, {0xbaee2000}, {0xbaee4000}, {0xbaee6000}, + {0xbaee8000}, {0xbaeea000}, {0xbaeec000}, {0xbaeee000}, + {0xbaef0000}, {0xbaef2000}, {0xbaef4000}, {0xbaef6000}, + {0xbaef8000}, {0xbaefa000}, {0xbaefc000}, {0xbaefe000}, + {0xbaf00000}, {0xbaf02000}, {0xbaf04000}, {0xbaf06000}, + {0xbaf08000}, {0xbaf0a000}, {0xbaf0c000}, {0xbaf0e000}, + {0xbaf10000}, {0xbaf12000}, {0xbaf14000}, {0xbaf16000}, + {0xbaf18000}, {0xbaf1a000}, {0xbaf1c000}, {0xbaf1e000}, + {0xbaf20000}, {0xbaf22000}, {0xbaf24000}, {0xbaf26000}, + {0xbaf28000}, {0xbaf2a000}, {0xbaf2c000}, {0xbaf2e000}, + {0xbaf30000}, {0xbaf32000}, {0xbaf34000}, {0xbaf36000}, + {0xbaf38000}, {0xbaf3a000}, {0xbaf3c000}, {0xbaf3e000}, + {0xbaf40000}, {0xbaf42000}, {0xbaf44000}, {0xbaf46000}, + {0xbaf48000}, {0xbaf4a000}, {0xbaf4c000}, {0xbaf4e000}, + {0xbaf50000}, {0xbaf52000}, {0xbaf54000}, {0xbaf56000}, + {0xbaf58000}, {0xbaf5a000}, {0xbaf5c000}, {0xbaf5e000}, + {0xbaf60000}, {0xbaf62000}, {0xbaf64000}, {0xbaf66000}, + {0xbaf68000}, {0xbaf6a000}, {0xbaf6c000}, {0xbaf6e000}, + {0xbaf70000}, {0xbaf72000}, {0xbaf74000}, {0xbaf76000}, + {0xbaf78000}, {0xbaf7a000}, {0xbaf7c000}, {0xbaf7e000}, + {0xbaf80000}, {0xbaf82000}, {0xbaf84000}, {0xbaf86000}, + {0xbaf88000}, {0xbaf8a000}, {0xbaf8c000}, {0xbaf8e000}, + {0xbaf90000}, {0xbaf92000}, {0xbaf94000}, {0xbaf96000}, + {0xbaf98000}, {0xbaf9a000}, {0xbaf9c000}, {0xbaf9e000}, + {0xbafa0000}, {0xbafa2000}, {0xbafa4000}, {0xbafa6000}, + {0xbafa8000}, {0xbafaa000}, {0xbafac000}, {0xbafae000}, + {0xbafb0000}, {0xbafb2000}, {0xbafb4000}, {0xbafb6000}, + {0xbafb8000}, {0xbafba000}, {0xbafbc000}, {0xbafbe000}, + {0xbafc0000}, {0xbafc2000}, {0xbafc4000}, {0xbafc6000}, + {0xbafc8000}, {0xbafca000}, {0xbafcc000}, {0xbafce000}, + {0xbafd0000}, {0xbafd2000}, {0xbafd4000}, {0xbafd6000}, + {0xbafd8000}, {0xbafda000}, {0xbafdc000}, {0xbafde000}, + {0xbafe0000}, {0xbafe2000}, {0xbafe4000}, {0xbafe6000}, + {0xbafe8000}, {0xbafea000}, {0xbafec000}, {0xbafee000}, + {0xbaff0000}, {0xbaff2000}, {0xbaff4000}, {0xbaff6000}, + {0xbaff8000}, {0xbaffa000}, {0xbaffc000}, {0xbaffe000}, + {0xbb000000}, {0xbb002000}, {0xbb004000}, {0xbb006000}, + {0xbb008000}, {0xbb00a000}, {0xbb00c000}, {0xbb00e000}, + {0xbb010000}, {0xbb012000}, {0xbb014000}, {0xbb016000}, + {0xbb018000}, {0xbb01a000}, {0xbb01c000}, {0xbb01e000}, + {0xbb020000}, {0xbb022000}, {0xbb024000}, {0xbb026000}, + {0xbb028000}, {0xbb02a000}, {0xbb02c000}, {0xbb02e000}, + {0xbb030000}, {0xbb032000}, {0xbb034000}, {0xbb036000}, + {0xbb038000}, {0xbb03a000}, {0xbb03c000}, {0xbb03e000}, + {0xbb040000}, {0xbb042000}, {0xbb044000}, {0xbb046000}, + {0xbb048000}, {0xbb04a000}, {0xbb04c000}, {0xbb04e000}, + {0xbb050000}, {0xbb052000}, {0xbb054000}, {0xbb056000}, + {0xbb058000}, {0xbb05a000}, {0xbb05c000}, {0xbb05e000}, + {0xbb060000}, {0xbb062000}, {0xbb064000}, {0xbb066000}, + {0xbb068000}, {0xbb06a000}, {0xbb06c000}, {0xbb06e000}, + {0xbb070000}, {0xbb072000}, {0xbb074000}, {0xbb076000}, + {0xbb078000}, {0xbb07a000}, {0xbb07c000}, {0xbb07e000}, + {0xbb080000}, {0xbb082000}, {0xbb084000}, {0xbb086000}, + {0xbb088000}, {0xbb08a000}, {0xbb08c000}, {0xbb08e000}, + {0xbb090000}, {0xbb092000}, {0xbb094000}, {0xbb096000}, + {0xbb098000}, {0xbb09a000}, {0xbb09c000}, {0xbb09e000}, + {0xbb0a0000}, {0xbb0a2000}, {0xbb0a4000}, {0xbb0a6000}, + {0xbb0a8000}, {0xbb0aa000}, {0xbb0ac000}, {0xbb0ae000}, + {0xbb0b0000}, {0xbb0b2000}, {0xbb0b4000}, {0xbb0b6000}, + {0xbb0b8000}, {0xbb0ba000}, {0xbb0bc000}, {0xbb0be000}, + {0xbb0c0000}, {0xbb0c2000}, {0xbb0c4000}, {0xbb0c6000}, + {0xbb0c8000}, {0xbb0ca000}, {0xbb0cc000}, {0xbb0ce000}, + {0xbb0d0000}, {0xbb0d2000}, {0xbb0d4000}, {0xbb0d6000}, + {0xbb0d8000}, {0xbb0da000}, {0xbb0dc000}, {0xbb0de000}, + {0xbb0e0000}, {0xbb0e2000}, {0xbb0e4000}, {0xbb0e6000}, + {0xbb0e8000}, {0xbb0ea000}, {0xbb0ec000}, {0xbb0ee000}, + {0xbb0f0000}, {0xbb0f2000}, {0xbb0f4000}, {0xbb0f6000}, + {0xbb0f8000}, {0xbb0fa000}, {0xbb0fc000}, {0xbb0fe000}, + {0xbb100000}, {0xbb102000}, {0xbb104000}, {0xbb106000}, + {0xbb108000}, {0xbb10a000}, {0xbb10c000}, {0xbb10e000}, + {0xbb110000}, {0xbb112000}, {0xbb114000}, {0xbb116000}, + {0xbb118000}, {0xbb11a000}, {0xbb11c000}, {0xbb11e000}, + {0xbb120000}, {0xbb122000}, {0xbb124000}, {0xbb126000}, + {0xbb128000}, {0xbb12a000}, {0xbb12c000}, {0xbb12e000}, + {0xbb130000}, {0xbb132000}, {0xbb134000}, {0xbb136000}, + {0xbb138000}, {0xbb13a000}, {0xbb13c000}, {0xbb13e000}, + {0xbb140000}, {0xbb142000}, {0xbb144000}, {0xbb146000}, + {0xbb148000}, {0xbb14a000}, {0xbb14c000}, {0xbb14e000}, + {0xbb150000}, {0xbb152000}, {0xbb154000}, {0xbb156000}, + {0xbb158000}, {0xbb15a000}, {0xbb15c000}, {0xbb15e000}, + {0xbb160000}, {0xbb162000}, {0xbb164000}, {0xbb166000}, + {0xbb168000}, {0xbb16a000}, {0xbb16c000}, {0xbb16e000}, + {0xbb170000}, {0xbb172000}, {0xbb174000}, {0xbb176000}, + {0xbb178000}, {0xbb17a000}, {0xbb17c000}, {0xbb17e000}, + {0xbb180000}, {0xbb182000}, {0xbb184000}, {0xbb186000}, + {0xbb188000}, {0xbb18a000}, {0xbb18c000}, {0xbb18e000}, + {0xbb190000}, {0xbb192000}, {0xbb194000}, {0xbb196000}, + {0xbb198000}, {0xbb19a000}, {0xbb19c000}, {0xbb19e000}, + {0xbb1a0000}, {0xbb1a2000}, {0xbb1a4000}, {0xbb1a6000}, + {0xbb1a8000}, {0xbb1aa000}, {0xbb1ac000}, {0xbb1ae000}, + {0xbb1b0000}, {0xbb1b2000}, {0xbb1b4000}, {0xbb1b6000}, + {0xbb1b8000}, {0xbb1ba000}, {0xbb1bc000}, {0xbb1be000}, + {0xbb1c0000}, {0xbb1c2000}, {0xbb1c4000}, {0xbb1c6000}, + {0xbb1c8000}, {0xbb1ca000}, {0xbb1cc000}, {0xbb1ce000}, + {0xbb1d0000}, {0xbb1d2000}, {0xbb1d4000}, {0xbb1d6000}, + {0xbb1d8000}, {0xbb1da000}, {0xbb1dc000}, {0xbb1de000}, + {0xbb1e0000}, {0xbb1e2000}, {0xbb1e4000}, {0xbb1e6000}, + {0xbb1e8000}, {0xbb1ea000}, {0xbb1ec000}, {0xbb1ee000}, + {0xbb1f0000}, {0xbb1f2000}, {0xbb1f4000}, {0xbb1f6000}, + {0xbb1f8000}, {0xbb1fa000}, {0xbb1fc000}, {0xbb1fe000}, + {0xbb200000}, {0xbb202000}, {0xbb204000}, {0xbb206000}, + {0xbb208000}, {0xbb20a000}, {0xbb20c000}, {0xbb20e000}, + {0xbb210000}, {0xbb212000}, {0xbb214000}, {0xbb216000}, + {0xbb218000}, {0xbb21a000}, {0xbb21c000}, {0xbb21e000}, + {0xbb220000}, {0xbb222000}, {0xbb224000}, {0xbb226000}, + {0xbb228000}, {0xbb22a000}, {0xbb22c000}, {0xbb22e000}, + {0xbb230000}, {0xbb232000}, {0xbb234000}, {0xbb236000}, + {0xbb238000}, {0xbb23a000}, {0xbb23c000}, {0xbb23e000}, + {0xbb240000}, {0xbb242000}, {0xbb244000}, {0xbb246000}, + {0xbb248000}, {0xbb24a000}, {0xbb24c000}, {0xbb24e000}, + {0xbb250000}, {0xbb252000}, {0xbb254000}, {0xbb256000}, + {0xbb258000}, {0xbb25a000}, {0xbb25c000}, {0xbb25e000}, + {0xbb260000}, {0xbb262000}, {0xbb264000}, {0xbb266000}, + {0xbb268000}, {0xbb26a000}, {0xbb26c000}, {0xbb26e000}, + {0xbb270000}, {0xbb272000}, {0xbb274000}, {0xbb276000}, + {0xbb278000}, {0xbb27a000}, {0xbb27c000}, {0xbb27e000}, + {0xbb280000}, {0xbb282000}, {0xbb284000}, {0xbb286000}, + {0xbb288000}, {0xbb28a000}, {0xbb28c000}, {0xbb28e000}, + {0xbb290000}, {0xbb292000}, {0xbb294000}, {0xbb296000}, + {0xbb298000}, {0xbb29a000}, {0xbb29c000}, {0xbb29e000}, + {0xbb2a0000}, {0xbb2a2000}, {0xbb2a4000}, {0xbb2a6000}, + {0xbb2a8000}, {0xbb2aa000}, {0xbb2ac000}, {0xbb2ae000}, + {0xbb2b0000}, {0xbb2b2000}, {0xbb2b4000}, {0xbb2b6000}, + {0xbb2b8000}, {0xbb2ba000}, {0xbb2bc000}, {0xbb2be000}, + {0xbb2c0000}, {0xbb2c2000}, {0xbb2c4000}, {0xbb2c6000}, + {0xbb2c8000}, {0xbb2ca000}, {0xbb2cc000}, {0xbb2ce000}, + {0xbb2d0000}, {0xbb2d2000}, {0xbb2d4000}, {0xbb2d6000}, + {0xbb2d8000}, {0xbb2da000}, {0xbb2dc000}, {0xbb2de000}, + {0xbb2e0000}, {0xbb2e2000}, {0xbb2e4000}, {0xbb2e6000}, + {0xbb2e8000}, {0xbb2ea000}, {0xbb2ec000}, {0xbb2ee000}, + {0xbb2f0000}, {0xbb2f2000}, {0xbb2f4000}, {0xbb2f6000}, + {0xbb2f8000}, {0xbb2fa000}, {0xbb2fc000}, {0xbb2fe000}, + {0xbb300000}, {0xbb302000}, {0xbb304000}, {0xbb306000}, + {0xbb308000}, {0xbb30a000}, {0xbb30c000}, {0xbb30e000}, + {0xbb310000}, {0xbb312000}, {0xbb314000}, {0xbb316000}, + {0xbb318000}, {0xbb31a000}, {0xbb31c000}, {0xbb31e000}, + {0xbb320000}, {0xbb322000}, {0xbb324000}, {0xbb326000}, + {0xbb328000}, {0xbb32a000}, {0xbb32c000}, {0xbb32e000}, + {0xbb330000}, {0xbb332000}, {0xbb334000}, {0xbb336000}, + {0xbb338000}, {0xbb33a000}, {0xbb33c000}, {0xbb33e000}, + {0xbb340000}, {0xbb342000}, {0xbb344000}, {0xbb346000}, + {0xbb348000}, {0xbb34a000}, {0xbb34c000}, {0xbb34e000}, + {0xbb350000}, {0xbb352000}, {0xbb354000}, {0xbb356000}, + {0xbb358000}, {0xbb35a000}, {0xbb35c000}, {0xbb35e000}, + {0xbb360000}, {0xbb362000}, {0xbb364000}, {0xbb366000}, + {0xbb368000}, {0xbb36a000}, {0xbb36c000}, {0xbb36e000}, + {0xbb370000}, {0xbb372000}, {0xbb374000}, {0xbb376000}, + {0xbb378000}, {0xbb37a000}, {0xbb37c000}, {0xbb37e000}, + {0xbb380000}, {0xbb382000}, {0xbb384000}, {0xbb386000}, + {0xbb388000}, {0xbb38a000}, {0xbb38c000}, {0xbb38e000}, + {0xbb390000}, {0xbb392000}, {0xbb394000}, {0xbb396000}, + {0xbb398000}, {0xbb39a000}, {0xbb39c000}, {0xbb39e000}, + {0xbb3a0000}, {0xbb3a2000}, {0xbb3a4000}, {0xbb3a6000}, + {0xbb3a8000}, {0xbb3aa000}, {0xbb3ac000}, {0xbb3ae000}, + {0xbb3b0000}, {0xbb3b2000}, {0xbb3b4000}, {0xbb3b6000}, + {0xbb3b8000}, {0xbb3ba000}, {0xbb3bc000}, {0xbb3be000}, + {0xbb3c0000}, {0xbb3c2000}, {0xbb3c4000}, {0xbb3c6000}, + {0xbb3c8000}, {0xbb3ca000}, {0xbb3cc000}, {0xbb3ce000}, + {0xbb3d0000}, {0xbb3d2000}, {0xbb3d4000}, {0xbb3d6000}, + {0xbb3d8000}, {0xbb3da000}, {0xbb3dc000}, {0xbb3de000}, + {0xbb3e0000}, {0xbb3e2000}, {0xbb3e4000}, {0xbb3e6000}, + {0xbb3e8000}, {0xbb3ea000}, {0xbb3ec000}, {0xbb3ee000}, + {0xbb3f0000}, {0xbb3f2000}, {0xbb3f4000}, {0xbb3f6000}, + {0xbb3f8000}, {0xbb3fa000}, {0xbb3fc000}, {0xbb3fe000}, + {0xbb400000}, {0xbb402000}, {0xbb404000}, {0xbb406000}, + {0xbb408000}, {0xbb40a000}, {0xbb40c000}, {0xbb40e000}, + {0xbb410000}, {0xbb412000}, {0xbb414000}, {0xbb416000}, + {0xbb418000}, {0xbb41a000}, {0xbb41c000}, {0xbb41e000}, + {0xbb420000}, {0xbb422000}, {0xbb424000}, {0xbb426000}, + {0xbb428000}, {0xbb42a000}, {0xbb42c000}, {0xbb42e000}, + {0xbb430000}, {0xbb432000}, {0xbb434000}, {0xbb436000}, + {0xbb438000}, {0xbb43a000}, {0xbb43c000}, {0xbb43e000}, + {0xbb440000}, {0xbb442000}, {0xbb444000}, {0xbb446000}, + {0xbb448000}, {0xbb44a000}, {0xbb44c000}, {0xbb44e000}, + {0xbb450000}, {0xbb452000}, {0xbb454000}, {0xbb456000}, + {0xbb458000}, {0xbb45a000}, {0xbb45c000}, {0xbb45e000}, + {0xbb460000}, {0xbb462000}, {0xbb464000}, {0xbb466000}, + {0xbb468000}, {0xbb46a000}, {0xbb46c000}, {0xbb46e000}, + {0xbb470000}, {0xbb472000}, {0xbb474000}, {0xbb476000}, + {0xbb478000}, {0xbb47a000}, {0xbb47c000}, {0xbb47e000}, + {0xbb480000}, {0xbb482000}, {0xbb484000}, {0xbb486000}, + {0xbb488000}, {0xbb48a000}, {0xbb48c000}, {0xbb48e000}, + {0xbb490000}, {0xbb492000}, {0xbb494000}, {0xbb496000}, + {0xbb498000}, {0xbb49a000}, {0xbb49c000}, {0xbb49e000}, + {0xbb4a0000}, {0xbb4a2000}, {0xbb4a4000}, {0xbb4a6000}, + {0xbb4a8000}, {0xbb4aa000}, {0xbb4ac000}, {0xbb4ae000}, + {0xbb4b0000}, {0xbb4b2000}, {0xbb4b4000}, {0xbb4b6000}, + {0xbb4b8000}, {0xbb4ba000}, {0xbb4bc000}, {0xbb4be000}, + {0xbb4c0000}, {0xbb4c2000}, {0xbb4c4000}, {0xbb4c6000}, + {0xbb4c8000}, {0xbb4ca000}, {0xbb4cc000}, {0xbb4ce000}, + {0xbb4d0000}, {0xbb4d2000}, {0xbb4d4000}, {0xbb4d6000}, + {0xbb4d8000}, {0xbb4da000}, {0xbb4dc000}, {0xbb4de000}, + {0xbb4e0000}, {0xbb4e2000}, {0xbb4e4000}, {0xbb4e6000}, + {0xbb4e8000}, {0xbb4ea000}, {0xbb4ec000}, {0xbb4ee000}, + {0xbb4f0000}, {0xbb4f2000}, {0xbb4f4000}, {0xbb4f6000}, + {0xbb4f8000}, {0xbb4fa000}, {0xbb4fc000}, {0xbb4fe000}, + {0xbb500000}, {0xbb502000}, {0xbb504000}, {0xbb506000}, + {0xbb508000}, {0xbb50a000}, {0xbb50c000}, {0xbb50e000}, + {0xbb510000}, {0xbb512000}, {0xbb514000}, {0xbb516000}, + {0xbb518000}, {0xbb51a000}, {0xbb51c000}, {0xbb51e000}, + {0xbb520000}, {0xbb522000}, {0xbb524000}, {0xbb526000}, + {0xbb528000}, {0xbb52a000}, {0xbb52c000}, {0xbb52e000}, + {0xbb530000}, {0xbb532000}, {0xbb534000}, {0xbb536000}, + {0xbb538000}, {0xbb53a000}, {0xbb53c000}, {0xbb53e000}, + {0xbb540000}, {0xbb542000}, {0xbb544000}, {0xbb546000}, + {0xbb548000}, {0xbb54a000}, {0xbb54c000}, {0xbb54e000}, + {0xbb550000}, {0xbb552000}, {0xbb554000}, {0xbb556000}, + {0xbb558000}, {0xbb55a000}, {0xbb55c000}, {0xbb55e000}, + {0xbb560000}, {0xbb562000}, {0xbb564000}, {0xbb566000}, + {0xbb568000}, {0xbb56a000}, {0xbb56c000}, {0xbb56e000}, + {0xbb570000}, {0xbb572000}, {0xbb574000}, {0xbb576000}, + {0xbb578000}, {0xbb57a000}, {0xbb57c000}, {0xbb57e000}, + {0xbb580000}, {0xbb582000}, {0xbb584000}, {0xbb586000}, + {0xbb588000}, {0xbb58a000}, {0xbb58c000}, {0xbb58e000}, + {0xbb590000}, {0xbb592000}, {0xbb594000}, {0xbb596000}, + {0xbb598000}, {0xbb59a000}, {0xbb59c000}, {0xbb59e000}, + {0xbb5a0000}, {0xbb5a2000}, {0xbb5a4000}, {0xbb5a6000}, + {0xbb5a8000}, {0xbb5aa000}, {0xbb5ac000}, {0xbb5ae000}, + {0xbb5b0000}, {0xbb5b2000}, {0xbb5b4000}, {0xbb5b6000}, + {0xbb5b8000}, {0xbb5ba000}, {0xbb5bc000}, {0xbb5be000}, + {0xbb5c0000}, {0xbb5c2000}, {0xbb5c4000}, {0xbb5c6000}, + {0xbb5c8000}, {0xbb5ca000}, {0xbb5cc000}, {0xbb5ce000}, + {0xbb5d0000}, {0xbb5d2000}, {0xbb5d4000}, {0xbb5d6000}, + {0xbb5d8000}, {0xbb5da000}, {0xbb5dc000}, {0xbb5de000}, + {0xbb5e0000}, {0xbb5e2000}, {0xbb5e4000}, {0xbb5e6000}, + {0xbb5e8000}, {0xbb5ea000}, {0xbb5ec000}, {0xbb5ee000}, + {0xbb5f0000}, {0xbb5f2000}, {0xbb5f4000}, {0xbb5f6000}, + {0xbb5f8000}, {0xbb5fa000}, {0xbb5fc000}, {0xbb5fe000}, + {0xbb600000}, {0xbb602000}, {0xbb604000}, {0xbb606000}, + {0xbb608000}, {0xbb60a000}, {0xbb60c000}, {0xbb60e000}, + {0xbb610000}, {0xbb612000}, {0xbb614000}, {0xbb616000}, + {0xbb618000}, {0xbb61a000}, {0xbb61c000}, {0xbb61e000}, + {0xbb620000}, {0xbb622000}, {0xbb624000}, {0xbb626000}, + {0xbb628000}, {0xbb62a000}, {0xbb62c000}, {0xbb62e000}, + {0xbb630000}, {0xbb632000}, {0xbb634000}, {0xbb636000}, + {0xbb638000}, {0xbb63a000}, {0xbb63c000}, {0xbb63e000}, + {0xbb640000}, {0xbb642000}, {0xbb644000}, {0xbb646000}, + {0xbb648000}, {0xbb64a000}, {0xbb64c000}, {0xbb64e000}, + {0xbb650000}, {0xbb652000}, {0xbb654000}, {0xbb656000}, + {0xbb658000}, {0xbb65a000}, {0xbb65c000}, {0xbb65e000}, + {0xbb660000}, {0xbb662000}, {0xbb664000}, {0xbb666000}, + {0xbb668000}, {0xbb66a000}, {0xbb66c000}, {0xbb66e000}, + {0xbb670000}, {0xbb672000}, {0xbb674000}, {0xbb676000}, + {0xbb678000}, {0xbb67a000}, {0xbb67c000}, {0xbb67e000}, + {0xbb680000}, {0xbb682000}, {0xbb684000}, {0xbb686000}, + {0xbb688000}, {0xbb68a000}, {0xbb68c000}, {0xbb68e000}, + {0xbb690000}, {0xbb692000}, {0xbb694000}, {0xbb696000}, + {0xbb698000}, {0xbb69a000}, {0xbb69c000}, {0xbb69e000}, + {0xbb6a0000}, {0xbb6a2000}, {0xbb6a4000}, {0xbb6a6000}, + {0xbb6a8000}, {0xbb6aa000}, {0xbb6ac000}, {0xbb6ae000}, + {0xbb6b0000}, {0xbb6b2000}, {0xbb6b4000}, {0xbb6b6000}, + {0xbb6b8000}, {0xbb6ba000}, {0xbb6bc000}, {0xbb6be000}, + {0xbb6c0000}, {0xbb6c2000}, {0xbb6c4000}, {0xbb6c6000}, + {0xbb6c8000}, {0xbb6ca000}, {0xbb6cc000}, {0xbb6ce000}, + {0xbb6d0000}, {0xbb6d2000}, {0xbb6d4000}, {0xbb6d6000}, + {0xbb6d8000}, {0xbb6da000}, {0xbb6dc000}, {0xbb6de000}, + {0xbb6e0000}, {0xbb6e2000}, {0xbb6e4000}, {0xbb6e6000}, + {0xbb6e8000}, {0xbb6ea000}, {0xbb6ec000}, {0xbb6ee000}, + {0xbb6f0000}, {0xbb6f2000}, {0xbb6f4000}, {0xbb6f6000}, + {0xbb6f8000}, {0xbb6fa000}, {0xbb6fc000}, {0xbb6fe000}, + {0xbb700000}, {0xbb702000}, {0xbb704000}, {0xbb706000}, + {0xbb708000}, {0xbb70a000}, {0xbb70c000}, {0xbb70e000}, + {0xbb710000}, {0xbb712000}, {0xbb714000}, {0xbb716000}, + {0xbb718000}, {0xbb71a000}, {0xbb71c000}, {0xbb71e000}, + {0xbb720000}, {0xbb722000}, {0xbb724000}, {0xbb726000}, + {0xbb728000}, {0xbb72a000}, {0xbb72c000}, {0xbb72e000}, + {0xbb730000}, {0xbb732000}, {0xbb734000}, {0xbb736000}, + {0xbb738000}, {0xbb73a000}, {0xbb73c000}, {0xbb73e000}, + {0xbb740000}, {0xbb742000}, {0xbb744000}, {0xbb746000}, + {0xbb748000}, {0xbb74a000}, {0xbb74c000}, {0xbb74e000}, + {0xbb750000}, {0xbb752000}, {0xbb754000}, {0xbb756000}, + {0xbb758000}, {0xbb75a000}, {0xbb75c000}, {0xbb75e000}, + {0xbb760000}, {0xbb762000}, {0xbb764000}, {0xbb766000}, + {0xbb768000}, {0xbb76a000}, {0xbb76c000}, {0xbb76e000}, + {0xbb770000}, {0xbb772000}, {0xbb774000}, {0xbb776000}, + {0xbb778000}, {0xbb77a000}, {0xbb77c000}, {0xbb77e000}, + {0xbb780000}, {0xbb782000}, {0xbb784000}, {0xbb786000}, + {0xbb788000}, {0xbb78a000}, {0xbb78c000}, {0xbb78e000}, + {0xbb790000}, {0xbb792000}, {0xbb794000}, {0xbb796000}, + {0xbb798000}, {0xbb79a000}, {0xbb79c000}, {0xbb79e000}, + {0xbb7a0000}, {0xbb7a2000}, {0xbb7a4000}, {0xbb7a6000}, + {0xbb7a8000}, {0xbb7aa000}, {0xbb7ac000}, {0xbb7ae000}, + {0xbb7b0000}, {0xbb7b2000}, {0xbb7b4000}, {0xbb7b6000}, + {0xbb7b8000}, {0xbb7ba000}, {0xbb7bc000}, {0xbb7be000}, + {0xbb7c0000}, {0xbb7c2000}, {0xbb7c4000}, {0xbb7c6000}, + {0xbb7c8000}, {0xbb7ca000}, {0xbb7cc000}, {0xbb7ce000}, + {0xbb7d0000}, {0xbb7d2000}, {0xbb7d4000}, {0xbb7d6000}, + {0xbb7d8000}, {0xbb7da000}, {0xbb7dc000}, {0xbb7de000}, + {0xbb7e0000}, {0xbb7e2000}, {0xbb7e4000}, {0xbb7e6000}, + {0xbb7e8000}, {0xbb7ea000}, {0xbb7ec000}, {0xbb7ee000}, + {0xbb7f0000}, {0xbb7f2000}, {0xbb7f4000}, {0xbb7f6000}, + {0xbb7f8000}, {0xbb7fa000}, {0xbb7fc000}, {0xbb7fe000}, + {0xbb800000}, {0xbb802000}, {0xbb804000}, {0xbb806000}, + {0xbb808000}, {0xbb80a000}, {0xbb80c000}, {0xbb80e000}, + {0xbb810000}, {0xbb812000}, {0xbb814000}, {0xbb816000}, + {0xbb818000}, {0xbb81a000}, {0xbb81c000}, {0xbb81e000}, + {0xbb820000}, {0xbb822000}, {0xbb824000}, {0xbb826000}, + {0xbb828000}, {0xbb82a000}, {0xbb82c000}, {0xbb82e000}, + {0xbb830000}, {0xbb832000}, {0xbb834000}, {0xbb836000}, + {0xbb838000}, {0xbb83a000}, {0xbb83c000}, {0xbb83e000}, + {0xbb840000}, {0xbb842000}, {0xbb844000}, {0xbb846000}, + {0xbb848000}, {0xbb84a000}, {0xbb84c000}, {0xbb84e000}, + {0xbb850000}, {0xbb852000}, {0xbb854000}, {0xbb856000}, + {0xbb858000}, {0xbb85a000}, {0xbb85c000}, {0xbb85e000}, + {0xbb860000}, {0xbb862000}, {0xbb864000}, {0xbb866000}, + {0xbb868000}, {0xbb86a000}, {0xbb86c000}, {0xbb86e000}, + {0xbb870000}, {0xbb872000}, {0xbb874000}, {0xbb876000}, + {0xbb878000}, {0xbb87a000}, {0xbb87c000}, {0xbb87e000}, + {0xbb880000}, {0xbb882000}, {0xbb884000}, {0xbb886000}, + {0xbb888000}, {0xbb88a000}, {0xbb88c000}, {0xbb88e000}, + {0xbb890000}, {0xbb892000}, {0xbb894000}, {0xbb896000}, + {0xbb898000}, {0xbb89a000}, {0xbb89c000}, {0xbb89e000}, + {0xbb8a0000}, {0xbb8a2000}, {0xbb8a4000}, {0xbb8a6000}, + {0xbb8a8000}, {0xbb8aa000}, {0xbb8ac000}, {0xbb8ae000}, + {0xbb8b0000}, {0xbb8b2000}, {0xbb8b4000}, {0xbb8b6000}, + {0xbb8b8000}, {0xbb8ba000}, {0xbb8bc000}, {0xbb8be000}, + {0xbb8c0000}, {0xbb8c2000}, {0xbb8c4000}, {0xbb8c6000}, + {0xbb8c8000}, {0xbb8ca000}, {0xbb8cc000}, {0xbb8ce000}, + {0xbb8d0000}, {0xbb8d2000}, {0xbb8d4000}, {0xbb8d6000}, + {0xbb8d8000}, {0xbb8da000}, {0xbb8dc000}, {0xbb8de000}, + {0xbb8e0000}, {0xbb8e2000}, {0xbb8e4000}, {0xbb8e6000}, + {0xbb8e8000}, {0xbb8ea000}, {0xbb8ec000}, {0xbb8ee000}, + {0xbb8f0000}, {0xbb8f2000}, {0xbb8f4000}, {0xbb8f6000}, + {0xbb8f8000}, {0xbb8fa000}, {0xbb8fc000}, {0xbb8fe000}, + {0xbb900000}, {0xbb902000}, {0xbb904000}, {0xbb906000}, + {0xbb908000}, {0xbb90a000}, {0xbb90c000}, {0xbb90e000}, + {0xbb910000}, {0xbb912000}, {0xbb914000}, {0xbb916000}, + {0xbb918000}, {0xbb91a000}, {0xbb91c000}, {0xbb91e000}, + {0xbb920000}, {0xbb922000}, {0xbb924000}, {0xbb926000}, + {0xbb928000}, {0xbb92a000}, {0xbb92c000}, {0xbb92e000}, + {0xbb930000}, {0xbb932000}, {0xbb934000}, {0xbb936000}, + {0xbb938000}, {0xbb93a000}, {0xbb93c000}, {0xbb93e000}, + {0xbb940000}, {0xbb942000}, {0xbb944000}, {0xbb946000}, + {0xbb948000}, {0xbb94a000}, {0xbb94c000}, {0xbb94e000}, + {0xbb950000}, {0xbb952000}, {0xbb954000}, {0xbb956000}, + {0xbb958000}, {0xbb95a000}, {0xbb95c000}, {0xbb95e000}, + {0xbb960000}, {0xbb962000}, {0xbb964000}, {0xbb966000}, + {0xbb968000}, {0xbb96a000}, {0xbb96c000}, {0xbb96e000}, + {0xbb970000}, {0xbb972000}, {0xbb974000}, {0xbb976000}, + {0xbb978000}, {0xbb97a000}, {0xbb97c000}, {0xbb97e000}, + {0xbb980000}, {0xbb982000}, {0xbb984000}, {0xbb986000}, + {0xbb988000}, {0xbb98a000}, {0xbb98c000}, {0xbb98e000}, + {0xbb990000}, {0xbb992000}, {0xbb994000}, {0xbb996000}, + {0xbb998000}, {0xbb99a000}, {0xbb99c000}, {0xbb99e000}, + {0xbb9a0000}, {0xbb9a2000}, {0xbb9a4000}, {0xbb9a6000}, + {0xbb9a8000}, {0xbb9aa000}, {0xbb9ac000}, {0xbb9ae000}, + {0xbb9b0000}, {0xbb9b2000}, {0xbb9b4000}, {0xbb9b6000}, + {0xbb9b8000}, {0xbb9ba000}, {0xbb9bc000}, {0xbb9be000}, + {0xbb9c0000}, {0xbb9c2000}, {0xbb9c4000}, {0xbb9c6000}, + {0xbb9c8000}, {0xbb9ca000}, {0xbb9cc000}, {0xbb9ce000}, + {0xbb9d0000}, {0xbb9d2000}, {0xbb9d4000}, {0xbb9d6000}, + {0xbb9d8000}, {0xbb9da000}, {0xbb9dc000}, {0xbb9de000}, + {0xbb9e0000}, {0xbb9e2000}, {0xbb9e4000}, {0xbb9e6000}, + {0xbb9e8000}, {0xbb9ea000}, {0xbb9ec000}, {0xbb9ee000}, + {0xbb9f0000}, {0xbb9f2000}, {0xbb9f4000}, {0xbb9f6000}, + {0xbb9f8000}, {0xbb9fa000}, {0xbb9fc000}, {0xbb9fe000}, + {0xbba00000}, {0xbba02000}, {0xbba04000}, {0xbba06000}, + {0xbba08000}, {0xbba0a000}, {0xbba0c000}, {0xbba0e000}, + {0xbba10000}, {0xbba12000}, {0xbba14000}, {0xbba16000}, + {0xbba18000}, {0xbba1a000}, {0xbba1c000}, {0xbba1e000}, + {0xbba20000}, {0xbba22000}, {0xbba24000}, {0xbba26000}, + {0xbba28000}, {0xbba2a000}, {0xbba2c000}, {0xbba2e000}, + {0xbba30000}, {0xbba32000}, {0xbba34000}, {0xbba36000}, + {0xbba38000}, {0xbba3a000}, {0xbba3c000}, {0xbba3e000}, + {0xbba40000}, {0xbba42000}, {0xbba44000}, {0xbba46000}, + {0xbba48000}, {0xbba4a000}, {0xbba4c000}, {0xbba4e000}, + {0xbba50000}, {0xbba52000}, {0xbba54000}, {0xbba56000}, + {0xbba58000}, {0xbba5a000}, {0xbba5c000}, {0xbba5e000}, + {0xbba60000}, {0xbba62000}, {0xbba64000}, {0xbba66000}, + {0xbba68000}, {0xbba6a000}, {0xbba6c000}, {0xbba6e000}, + {0xbba70000}, {0xbba72000}, {0xbba74000}, {0xbba76000}, + {0xbba78000}, {0xbba7a000}, {0xbba7c000}, {0xbba7e000}, + {0xbba80000}, {0xbba82000}, {0xbba84000}, {0xbba86000}, + {0xbba88000}, {0xbba8a000}, {0xbba8c000}, {0xbba8e000}, + {0xbba90000}, {0xbba92000}, {0xbba94000}, {0xbba96000}, + {0xbba98000}, {0xbba9a000}, {0xbba9c000}, {0xbba9e000}, + {0xbbaa0000}, {0xbbaa2000}, {0xbbaa4000}, {0xbbaa6000}, + {0xbbaa8000}, {0xbbaaa000}, {0xbbaac000}, {0xbbaae000}, + {0xbbab0000}, {0xbbab2000}, {0xbbab4000}, {0xbbab6000}, + {0xbbab8000}, {0xbbaba000}, {0xbbabc000}, {0xbbabe000}, + {0xbbac0000}, {0xbbac2000}, {0xbbac4000}, {0xbbac6000}, + {0xbbac8000}, {0xbbaca000}, {0xbbacc000}, {0xbbace000}, + {0xbbad0000}, {0xbbad2000}, {0xbbad4000}, {0xbbad6000}, + {0xbbad8000}, {0xbbada000}, {0xbbadc000}, {0xbbade000}, + {0xbbae0000}, {0xbbae2000}, {0xbbae4000}, {0xbbae6000}, + {0xbbae8000}, {0xbbaea000}, {0xbbaec000}, {0xbbaee000}, + {0xbbaf0000}, {0xbbaf2000}, {0xbbaf4000}, {0xbbaf6000}, + {0xbbaf8000}, {0xbbafa000}, {0xbbafc000}, {0xbbafe000}, + {0xbbb00000}, {0xbbb02000}, {0xbbb04000}, {0xbbb06000}, + {0xbbb08000}, {0xbbb0a000}, {0xbbb0c000}, {0xbbb0e000}, + {0xbbb10000}, {0xbbb12000}, {0xbbb14000}, {0xbbb16000}, + {0xbbb18000}, {0xbbb1a000}, {0xbbb1c000}, {0xbbb1e000}, + {0xbbb20000}, {0xbbb22000}, {0xbbb24000}, {0xbbb26000}, + {0xbbb28000}, {0xbbb2a000}, {0xbbb2c000}, {0xbbb2e000}, + {0xbbb30000}, {0xbbb32000}, {0xbbb34000}, {0xbbb36000}, + {0xbbb38000}, {0xbbb3a000}, {0xbbb3c000}, {0xbbb3e000}, + {0xbbb40000}, {0xbbb42000}, {0xbbb44000}, {0xbbb46000}, + {0xbbb48000}, {0xbbb4a000}, {0xbbb4c000}, {0xbbb4e000}, + {0xbbb50000}, {0xbbb52000}, {0xbbb54000}, {0xbbb56000}, + {0xbbb58000}, {0xbbb5a000}, {0xbbb5c000}, {0xbbb5e000}, + {0xbbb60000}, {0xbbb62000}, {0xbbb64000}, {0xbbb66000}, + {0xbbb68000}, {0xbbb6a000}, {0xbbb6c000}, {0xbbb6e000}, + {0xbbb70000}, {0xbbb72000}, {0xbbb74000}, {0xbbb76000}, + {0xbbb78000}, {0xbbb7a000}, {0xbbb7c000}, {0xbbb7e000}, + {0xbbb80000}, {0xbbb82000}, {0xbbb84000}, {0xbbb86000}, + {0xbbb88000}, {0xbbb8a000}, {0xbbb8c000}, {0xbbb8e000}, + {0xbbb90000}, {0xbbb92000}, {0xbbb94000}, {0xbbb96000}, + {0xbbb98000}, {0xbbb9a000}, {0xbbb9c000}, {0xbbb9e000}, + {0xbbba0000}, {0xbbba2000}, {0xbbba4000}, {0xbbba6000}, + {0xbbba8000}, {0xbbbaa000}, {0xbbbac000}, {0xbbbae000}, + {0xbbbb0000}, {0xbbbb2000}, {0xbbbb4000}, {0xbbbb6000}, + {0xbbbb8000}, {0xbbbba000}, {0xbbbbc000}, {0xbbbbe000}, + {0xbbbc0000}, {0xbbbc2000}, {0xbbbc4000}, {0xbbbc6000}, + {0xbbbc8000}, {0xbbbca000}, {0xbbbcc000}, {0xbbbce000}, + {0xbbbd0000}, {0xbbbd2000}, {0xbbbd4000}, {0xbbbd6000}, + {0xbbbd8000}, {0xbbbda000}, {0xbbbdc000}, {0xbbbde000}, + {0xbbbe0000}, {0xbbbe2000}, {0xbbbe4000}, {0xbbbe6000}, + {0xbbbe8000}, {0xbbbea000}, {0xbbbec000}, {0xbbbee000}, + {0xbbbf0000}, {0xbbbf2000}, {0xbbbf4000}, {0xbbbf6000}, + {0xbbbf8000}, {0xbbbfa000}, {0xbbbfc000}, {0xbbbfe000}, + {0xbbc00000}, {0xbbc02000}, {0xbbc04000}, {0xbbc06000}, + {0xbbc08000}, {0xbbc0a000}, {0xbbc0c000}, {0xbbc0e000}, + {0xbbc10000}, {0xbbc12000}, {0xbbc14000}, {0xbbc16000}, + {0xbbc18000}, {0xbbc1a000}, {0xbbc1c000}, {0xbbc1e000}, + {0xbbc20000}, {0xbbc22000}, {0xbbc24000}, {0xbbc26000}, + {0xbbc28000}, {0xbbc2a000}, {0xbbc2c000}, {0xbbc2e000}, + {0xbbc30000}, {0xbbc32000}, {0xbbc34000}, {0xbbc36000}, + {0xbbc38000}, {0xbbc3a000}, {0xbbc3c000}, {0xbbc3e000}, + {0xbbc40000}, {0xbbc42000}, {0xbbc44000}, {0xbbc46000}, + {0xbbc48000}, {0xbbc4a000}, {0xbbc4c000}, {0xbbc4e000}, + {0xbbc50000}, {0xbbc52000}, {0xbbc54000}, {0xbbc56000}, + {0xbbc58000}, {0xbbc5a000}, {0xbbc5c000}, {0xbbc5e000}, + {0xbbc60000}, {0xbbc62000}, {0xbbc64000}, {0xbbc66000}, + {0xbbc68000}, {0xbbc6a000}, {0xbbc6c000}, {0xbbc6e000}, + {0xbbc70000}, {0xbbc72000}, {0xbbc74000}, {0xbbc76000}, + {0xbbc78000}, {0xbbc7a000}, {0xbbc7c000}, {0xbbc7e000}, + {0xbbc80000}, {0xbbc82000}, {0xbbc84000}, {0xbbc86000}, + {0xbbc88000}, {0xbbc8a000}, {0xbbc8c000}, {0xbbc8e000}, + {0xbbc90000}, {0xbbc92000}, {0xbbc94000}, {0xbbc96000}, + {0xbbc98000}, {0xbbc9a000}, {0xbbc9c000}, {0xbbc9e000}, + {0xbbca0000}, {0xbbca2000}, {0xbbca4000}, {0xbbca6000}, + {0xbbca8000}, {0xbbcaa000}, {0xbbcac000}, {0xbbcae000}, + {0xbbcb0000}, {0xbbcb2000}, {0xbbcb4000}, {0xbbcb6000}, + {0xbbcb8000}, {0xbbcba000}, {0xbbcbc000}, {0xbbcbe000}, + {0xbbcc0000}, {0xbbcc2000}, {0xbbcc4000}, {0xbbcc6000}, + {0xbbcc8000}, {0xbbcca000}, {0xbbccc000}, {0xbbcce000}, + {0xbbcd0000}, {0xbbcd2000}, {0xbbcd4000}, {0xbbcd6000}, + {0xbbcd8000}, {0xbbcda000}, {0xbbcdc000}, {0xbbcde000}, + {0xbbce0000}, {0xbbce2000}, {0xbbce4000}, {0xbbce6000}, + {0xbbce8000}, {0xbbcea000}, {0xbbcec000}, {0xbbcee000}, + {0xbbcf0000}, {0xbbcf2000}, {0xbbcf4000}, {0xbbcf6000}, + {0xbbcf8000}, {0xbbcfa000}, {0xbbcfc000}, {0xbbcfe000}, + {0xbbd00000}, {0xbbd02000}, {0xbbd04000}, {0xbbd06000}, + {0xbbd08000}, {0xbbd0a000}, {0xbbd0c000}, {0xbbd0e000}, + {0xbbd10000}, {0xbbd12000}, {0xbbd14000}, {0xbbd16000}, + {0xbbd18000}, {0xbbd1a000}, {0xbbd1c000}, {0xbbd1e000}, + {0xbbd20000}, {0xbbd22000}, {0xbbd24000}, {0xbbd26000}, + {0xbbd28000}, {0xbbd2a000}, {0xbbd2c000}, {0xbbd2e000}, + {0xbbd30000}, {0xbbd32000}, {0xbbd34000}, {0xbbd36000}, + {0xbbd38000}, {0xbbd3a000}, {0xbbd3c000}, {0xbbd3e000}, + {0xbbd40000}, {0xbbd42000}, {0xbbd44000}, {0xbbd46000}, + {0xbbd48000}, {0xbbd4a000}, {0xbbd4c000}, {0xbbd4e000}, + {0xbbd50000}, {0xbbd52000}, {0xbbd54000}, {0xbbd56000}, + {0xbbd58000}, {0xbbd5a000}, {0xbbd5c000}, {0xbbd5e000}, + {0xbbd60000}, {0xbbd62000}, {0xbbd64000}, {0xbbd66000}, + {0xbbd68000}, {0xbbd6a000}, {0xbbd6c000}, {0xbbd6e000}, + {0xbbd70000}, {0xbbd72000}, {0xbbd74000}, {0xbbd76000}, + {0xbbd78000}, {0xbbd7a000}, {0xbbd7c000}, {0xbbd7e000}, + {0xbbd80000}, {0xbbd82000}, {0xbbd84000}, {0xbbd86000}, + {0xbbd88000}, {0xbbd8a000}, {0xbbd8c000}, {0xbbd8e000}, + {0xbbd90000}, {0xbbd92000}, {0xbbd94000}, {0xbbd96000}, + {0xbbd98000}, {0xbbd9a000}, {0xbbd9c000}, {0xbbd9e000}, + {0xbbda0000}, {0xbbda2000}, {0xbbda4000}, {0xbbda6000}, + {0xbbda8000}, {0xbbdaa000}, {0xbbdac000}, {0xbbdae000}, + {0xbbdb0000}, {0xbbdb2000}, {0xbbdb4000}, {0xbbdb6000}, + {0xbbdb8000}, {0xbbdba000}, {0xbbdbc000}, {0xbbdbe000}, + {0xbbdc0000}, {0xbbdc2000}, {0xbbdc4000}, {0xbbdc6000}, + {0xbbdc8000}, {0xbbdca000}, {0xbbdcc000}, {0xbbdce000}, + {0xbbdd0000}, {0xbbdd2000}, {0xbbdd4000}, {0xbbdd6000}, + {0xbbdd8000}, {0xbbdda000}, {0xbbddc000}, {0xbbdde000}, + {0xbbde0000}, {0xbbde2000}, {0xbbde4000}, {0xbbde6000}, + {0xbbde8000}, {0xbbdea000}, {0xbbdec000}, {0xbbdee000}, + {0xbbdf0000}, {0xbbdf2000}, {0xbbdf4000}, {0xbbdf6000}, + {0xbbdf8000}, {0xbbdfa000}, {0xbbdfc000}, {0xbbdfe000}, + {0xbbe00000}, {0xbbe02000}, {0xbbe04000}, {0xbbe06000}, + {0xbbe08000}, {0xbbe0a000}, {0xbbe0c000}, {0xbbe0e000}, + {0xbbe10000}, {0xbbe12000}, {0xbbe14000}, {0xbbe16000}, + {0xbbe18000}, {0xbbe1a000}, {0xbbe1c000}, {0xbbe1e000}, + {0xbbe20000}, {0xbbe22000}, {0xbbe24000}, {0xbbe26000}, + {0xbbe28000}, {0xbbe2a000}, {0xbbe2c000}, {0xbbe2e000}, + {0xbbe30000}, {0xbbe32000}, {0xbbe34000}, {0xbbe36000}, + {0xbbe38000}, {0xbbe3a000}, {0xbbe3c000}, {0xbbe3e000}, + {0xbbe40000}, {0xbbe42000}, {0xbbe44000}, {0xbbe46000}, + {0xbbe48000}, {0xbbe4a000}, {0xbbe4c000}, {0xbbe4e000}, + {0xbbe50000}, {0xbbe52000}, {0xbbe54000}, {0xbbe56000}, + {0xbbe58000}, {0xbbe5a000}, {0xbbe5c000}, {0xbbe5e000}, + {0xbbe60000}, {0xbbe62000}, {0xbbe64000}, {0xbbe66000}, + {0xbbe68000}, {0xbbe6a000}, {0xbbe6c000}, {0xbbe6e000}, + {0xbbe70000}, {0xbbe72000}, {0xbbe74000}, {0xbbe76000}, + {0xbbe78000}, {0xbbe7a000}, {0xbbe7c000}, {0xbbe7e000}, + {0xbbe80000}, {0xbbe82000}, {0xbbe84000}, {0xbbe86000}, + {0xbbe88000}, {0xbbe8a000}, {0xbbe8c000}, {0xbbe8e000}, + {0xbbe90000}, {0xbbe92000}, {0xbbe94000}, {0xbbe96000}, + {0xbbe98000}, {0xbbe9a000}, {0xbbe9c000}, {0xbbe9e000}, + {0xbbea0000}, {0xbbea2000}, {0xbbea4000}, {0xbbea6000}, + {0xbbea8000}, {0xbbeaa000}, {0xbbeac000}, {0xbbeae000}, + {0xbbeb0000}, {0xbbeb2000}, {0xbbeb4000}, {0xbbeb6000}, + {0xbbeb8000}, {0xbbeba000}, {0xbbebc000}, {0xbbebe000}, + {0xbbec0000}, {0xbbec2000}, {0xbbec4000}, {0xbbec6000}, + {0xbbec8000}, {0xbbeca000}, {0xbbecc000}, {0xbbece000}, + {0xbbed0000}, {0xbbed2000}, {0xbbed4000}, {0xbbed6000}, + {0xbbed8000}, {0xbbeda000}, {0xbbedc000}, {0xbbede000}, + {0xbbee0000}, {0xbbee2000}, {0xbbee4000}, {0xbbee6000}, + {0xbbee8000}, {0xbbeea000}, {0xbbeec000}, {0xbbeee000}, + {0xbbef0000}, {0xbbef2000}, {0xbbef4000}, {0xbbef6000}, + {0xbbef8000}, {0xbbefa000}, {0xbbefc000}, {0xbbefe000}, + {0xbbf00000}, {0xbbf02000}, {0xbbf04000}, {0xbbf06000}, + {0xbbf08000}, {0xbbf0a000}, {0xbbf0c000}, {0xbbf0e000}, + {0xbbf10000}, {0xbbf12000}, {0xbbf14000}, {0xbbf16000}, + {0xbbf18000}, {0xbbf1a000}, {0xbbf1c000}, {0xbbf1e000}, + {0xbbf20000}, {0xbbf22000}, {0xbbf24000}, {0xbbf26000}, + {0xbbf28000}, {0xbbf2a000}, {0xbbf2c000}, {0xbbf2e000}, + {0xbbf30000}, {0xbbf32000}, {0xbbf34000}, {0xbbf36000}, + {0xbbf38000}, {0xbbf3a000}, {0xbbf3c000}, {0xbbf3e000}, + {0xbbf40000}, {0xbbf42000}, {0xbbf44000}, {0xbbf46000}, + {0xbbf48000}, {0xbbf4a000}, {0xbbf4c000}, {0xbbf4e000}, + {0xbbf50000}, {0xbbf52000}, {0xbbf54000}, {0xbbf56000}, + {0xbbf58000}, {0xbbf5a000}, {0xbbf5c000}, {0xbbf5e000}, + {0xbbf60000}, {0xbbf62000}, {0xbbf64000}, {0xbbf66000}, + {0xbbf68000}, {0xbbf6a000}, {0xbbf6c000}, {0xbbf6e000}, + {0xbbf70000}, {0xbbf72000}, {0xbbf74000}, {0xbbf76000}, + {0xbbf78000}, {0xbbf7a000}, {0xbbf7c000}, {0xbbf7e000}, + {0xbbf80000}, {0xbbf82000}, {0xbbf84000}, {0xbbf86000}, + {0xbbf88000}, {0xbbf8a000}, {0xbbf8c000}, {0xbbf8e000}, + {0xbbf90000}, {0xbbf92000}, {0xbbf94000}, {0xbbf96000}, + {0xbbf98000}, {0xbbf9a000}, {0xbbf9c000}, {0xbbf9e000}, + {0xbbfa0000}, {0xbbfa2000}, {0xbbfa4000}, {0xbbfa6000}, + {0xbbfa8000}, {0xbbfaa000}, {0xbbfac000}, {0xbbfae000}, + {0xbbfb0000}, {0xbbfb2000}, {0xbbfb4000}, {0xbbfb6000}, + {0xbbfb8000}, {0xbbfba000}, {0xbbfbc000}, {0xbbfbe000}, + {0xbbfc0000}, {0xbbfc2000}, {0xbbfc4000}, {0xbbfc6000}, + {0xbbfc8000}, {0xbbfca000}, {0xbbfcc000}, {0xbbfce000}, + {0xbbfd0000}, {0xbbfd2000}, {0xbbfd4000}, {0xbbfd6000}, + {0xbbfd8000}, {0xbbfda000}, {0xbbfdc000}, {0xbbfde000}, + {0xbbfe0000}, {0xbbfe2000}, {0xbbfe4000}, {0xbbfe6000}, + {0xbbfe8000}, {0xbbfea000}, {0xbbfec000}, {0xbbfee000}, + {0xbbff0000}, {0xbbff2000}, {0xbbff4000}, {0xbbff6000}, + {0xbbff8000}, {0xbbffa000}, {0xbbffc000}, {0xbbffe000}, + {0xbc000000}, {0xbc002000}, {0xbc004000}, {0xbc006000}, + {0xbc008000}, {0xbc00a000}, {0xbc00c000}, {0xbc00e000}, + {0xbc010000}, {0xbc012000}, {0xbc014000}, {0xbc016000}, + {0xbc018000}, {0xbc01a000}, {0xbc01c000}, {0xbc01e000}, + {0xbc020000}, {0xbc022000}, {0xbc024000}, {0xbc026000}, + {0xbc028000}, {0xbc02a000}, {0xbc02c000}, {0xbc02e000}, + {0xbc030000}, {0xbc032000}, {0xbc034000}, {0xbc036000}, + {0xbc038000}, {0xbc03a000}, {0xbc03c000}, {0xbc03e000}, + {0xbc040000}, {0xbc042000}, {0xbc044000}, {0xbc046000}, + {0xbc048000}, {0xbc04a000}, {0xbc04c000}, {0xbc04e000}, + {0xbc050000}, {0xbc052000}, {0xbc054000}, {0xbc056000}, + {0xbc058000}, {0xbc05a000}, {0xbc05c000}, {0xbc05e000}, + {0xbc060000}, {0xbc062000}, {0xbc064000}, {0xbc066000}, + {0xbc068000}, {0xbc06a000}, {0xbc06c000}, {0xbc06e000}, + {0xbc070000}, {0xbc072000}, {0xbc074000}, {0xbc076000}, + {0xbc078000}, {0xbc07a000}, {0xbc07c000}, {0xbc07e000}, + {0xbc080000}, {0xbc082000}, {0xbc084000}, {0xbc086000}, + {0xbc088000}, {0xbc08a000}, {0xbc08c000}, {0xbc08e000}, + {0xbc090000}, {0xbc092000}, {0xbc094000}, {0xbc096000}, + {0xbc098000}, {0xbc09a000}, {0xbc09c000}, {0xbc09e000}, + {0xbc0a0000}, {0xbc0a2000}, {0xbc0a4000}, {0xbc0a6000}, + {0xbc0a8000}, {0xbc0aa000}, {0xbc0ac000}, {0xbc0ae000}, + {0xbc0b0000}, {0xbc0b2000}, {0xbc0b4000}, {0xbc0b6000}, + {0xbc0b8000}, {0xbc0ba000}, {0xbc0bc000}, {0xbc0be000}, + {0xbc0c0000}, {0xbc0c2000}, {0xbc0c4000}, {0xbc0c6000}, + {0xbc0c8000}, {0xbc0ca000}, {0xbc0cc000}, {0xbc0ce000}, + {0xbc0d0000}, {0xbc0d2000}, {0xbc0d4000}, {0xbc0d6000}, + {0xbc0d8000}, {0xbc0da000}, {0xbc0dc000}, {0xbc0de000}, + {0xbc0e0000}, {0xbc0e2000}, {0xbc0e4000}, {0xbc0e6000}, + {0xbc0e8000}, {0xbc0ea000}, {0xbc0ec000}, {0xbc0ee000}, + {0xbc0f0000}, {0xbc0f2000}, {0xbc0f4000}, {0xbc0f6000}, + {0xbc0f8000}, {0xbc0fa000}, {0xbc0fc000}, {0xbc0fe000}, + {0xbc100000}, {0xbc102000}, {0xbc104000}, {0xbc106000}, + {0xbc108000}, {0xbc10a000}, {0xbc10c000}, {0xbc10e000}, + {0xbc110000}, {0xbc112000}, {0xbc114000}, {0xbc116000}, + {0xbc118000}, {0xbc11a000}, {0xbc11c000}, {0xbc11e000}, + {0xbc120000}, {0xbc122000}, {0xbc124000}, {0xbc126000}, + {0xbc128000}, {0xbc12a000}, {0xbc12c000}, {0xbc12e000}, + {0xbc130000}, {0xbc132000}, {0xbc134000}, {0xbc136000}, + {0xbc138000}, {0xbc13a000}, {0xbc13c000}, {0xbc13e000}, + {0xbc140000}, {0xbc142000}, {0xbc144000}, {0xbc146000}, + {0xbc148000}, {0xbc14a000}, {0xbc14c000}, {0xbc14e000}, + {0xbc150000}, {0xbc152000}, {0xbc154000}, {0xbc156000}, + {0xbc158000}, {0xbc15a000}, {0xbc15c000}, {0xbc15e000}, + {0xbc160000}, {0xbc162000}, {0xbc164000}, {0xbc166000}, + {0xbc168000}, {0xbc16a000}, {0xbc16c000}, {0xbc16e000}, + {0xbc170000}, {0xbc172000}, {0xbc174000}, {0xbc176000}, + {0xbc178000}, {0xbc17a000}, {0xbc17c000}, {0xbc17e000}, + {0xbc180000}, {0xbc182000}, {0xbc184000}, {0xbc186000}, + {0xbc188000}, {0xbc18a000}, {0xbc18c000}, {0xbc18e000}, + {0xbc190000}, {0xbc192000}, {0xbc194000}, {0xbc196000}, + {0xbc198000}, {0xbc19a000}, {0xbc19c000}, {0xbc19e000}, + {0xbc1a0000}, {0xbc1a2000}, {0xbc1a4000}, {0xbc1a6000}, + {0xbc1a8000}, {0xbc1aa000}, {0xbc1ac000}, {0xbc1ae000}, + {0xbc1b0000}, {0xbc1b2000}, {0xbc1b4000}, {0xbc1b6000}, + {0xbc1b8000}, {0xbc1ba000}, {0xbc1bc000}, {0xbc1be000}, + {0xbc1c0000}, {0xbc1c2000}, {0xbc1c4000}, {0xbc1c6000}, + {0xbc1c8000}, {0xbc1ca000}, {0xbc1cc000}, {0xbc1ce000}, + {0xbc1d0000}, {0xbc1d2000}, {0xbc1d4000}, {0xbc1d6000}, + {0xbc1d8000}, {0xbc1da000}, {0xbc1dc000}, {0xbc1de000}, + {0xbc1e0000}, {0xbc1e2000}, {0xbc1e4000}, {0xbc1e6000}, + {0xbc1e8000}, {0xbc1ea000}, {0xbc1ec000}, {0xbc1ee000}, + {0xbc1f0000}, {0xbc1f2000}, {0xbc1f4000}, {0xbc1f6000}, + {0xbc1f8000}, {0xbc1fa000}, {0xbc1fc000}, {0xbc1fe000}, + {0xbc200000}, {0xbc202000}, {0xbc204000}, {0xbc206000}, + {0xbc208000}, {0xbc20a000}, {0xbc20c000}, {0xbc20e000}, + {0xbc210000}, {0xbc212000}, {0xbc214000}, {0xbc216000}, + {0xbc218000}, {0xbc21a000}, {0xbc21c000}, {0xbc21e000}, + {0xbc220000}, {0xbc222000}, {0xbc224000}, {0xbc226000}, + {0xbc228000}, {0xbc22a000}, {0xbc22c000}, {0xbc22e000}, + {0xbc230000}, {0xbc232000}, {0xbc234000}, {0xbc236000}, + {0xbc238000}, {0xbc23a000}, {0xbc23c000}, {0xbc23e000}, + {0xbc240000}, {0xbc242000}, {0xbc244000}, {0xbc246000}, + {0xbc248000}, {0xbc24a000}, {0xbc24c000}, {0xbc24e000}, + {0xbc250000}, {0xbc252000}, {0xbc254000}, {0xbc256000}, + {0xbc258000}, {0xbc25a000}, {0xbc25c000}, {0xbc25e000}, + {0xbc260000}, {0xbc262000}, {0xbc264000}, {0xbc266000}, + {0xbc268000}, {0xbc26a000}, {0xbc26c000}, {0xbc26e000}, + {0xbc270000}, {0xbc272000}, {0xbc274000}, {0xbc276000}, + {0xbc278000}, {0xbc27a000}, {0xbc27c000}, {0xbc27e000}, + {0xbc280000}, {0xbc282000}, {0xbc284000}, {0xbc286000}, + {0xbc288000}, {0xbc28a000}, {0xbc28c000}, {0xbc28e000}, + {0xbc290000}, {0xbc292000}, {0xbc294000}, {0xbc296000}, + {0xbc298000}, {0xbc29a000}, {0xbc29c000}, {0xbc29e000}, + {0xbc2a0000}, {0xbc2a2000}, {0xbc2a4000}, {0xbc2a6000}, + {0xbc2a8000}, {0xbc2aa000}, {0xbc2ac000}, {0xbc2ae000}, + {0xbc2b0000}, {0xbc2b2000}, {0xbc2b4000}, {0xbc2b6000}, + {0xbc2b8000}, {0xbc2ba000}, {0xbc2bc000}, {0xbc2be000}, + {0xbc2c0000}, {0xbc2c2000}, {0xbc2c4000}, {0xbc2c6000}, + {0xbc2c8000}, {0xbc2ca000}, {0xbc2cc000}, {0xbc2ce000}, + {0xbc2d0000}, {0xbc2d2000}, {0xbc2d4000}, {0xbc2d6000}, + {0xbc2d8000}, {0xbc2da000}, {0xbc2dc000}, {0xbc2de000}, + {0xbc2e0000}, {0xbc2e2000}, {0xbc2e4000}, {0xbc2e6000}, + {0xbc2e8000}, {0xbc2ea000}, {0xbc2ec000}, {0xbc2ee000}, + {0xbc2f0000}, {0xbc2f2000}, {0xbc2f4000}, {0xbc2f6000}, + {0xbc2f8000}, {0xbc2fa000}, {0xbc2fc000}, {0xbc2fe000}, + {0xbc300000}, {0xbc302000}, {0xbc304000}, {0xbc306000}, + {0xbc308000}, {0xbc30a000}, {0xbc30c000}, {0xbc30e000}, + {0xbc310000}, {0xbc312000}, {0xbc314000}, {0xbc316000}, + {0xbc318000}, {0xbc31a000}, {0xbc31c000}, {0xbc31e000}, + {0xbc320000}, {0xbc322000}, {0xbc324000}, {0xbc326000}, + {0xbc328000}, {0xbc32a000}, {0xbc32c000}, {0xbc32e000}, + {0xbc330000}, {0xbc332000}, {0xbc334000}, {0xbc336000}, + {0xbc338000}, {0xbc33a000}, {0xbc33c000}, {0xbc33e000}, + {0xbc340000}, {0xbc342000}, {0xbc344000}, {0xbc346000}, + {0xbc348000}, {0xbc34a000}, {0xbc34c000}, {0xbc34e000}, + {0xbc350000}, {0xbc352000}, {0xbc354000}, {0xbc356000}, + {0xbc358000}, {0xbc35a000}, {0xbc35c000}, {0xbc35e000}, + {0xbc360000}, {0xbc362000}, {0xbc364000}, {0xbc366000}, + {0xbc368000}, {0xbc36a000}, {0xbc36c000}, {0xbc36e000}, + {0xbc370000}, {0xbc372000}, {0xbc374000}, {0xbc376000}, + {0xbc378000}, {0xbc37a000}, {0xbc37c000}, {0xbc37e000}, + {0xbc380000}, {0xbc382000}, {0xbc384000}, {0xbc386000}, + {0xbc388000}, {0xbc38a000}, {0xbc38c000}, {0xbc38e000}, + {0xbc390000}, {0xbc392000}, {0xbc394000}, {0xbc396000}, + {0xbc398000}, {0xbc39a000}, {0xbc39c000}, {0xbc39e000}, + {0xbc3a0000}, {0xbc3a2000}, {0xbc3a4000}, {0xbc3a6000}, + {0xbc3a8000}, {0xbc3aa000}, {0xbc3ac000}, {0xbc3ae000}, + {0xbc3b0000}, {0xbc3b2000}, {0xbc3b4000}, {0xbc3b6000}, + {0xbc3b8000}, {0xbc3ba000}, {0xbc3bc000}, {0xbc3be000}, + {0xbc3c0000}, {0xbc3c2000}, {0xbc3c4000}, {0xbc3c6000}, + {0xbc3c8000}, {0xbc3ca000}, {0xbc3cc000}, {0xbc3ce000}, + {0xbc3d0000}, {0xbc3d2000}, {0xbc3d4000}, {0xbc3d6000}, + {0xbc3d8000}, {0xbc3da000}, {0xbc3dc000}, {0xbc3de000}, + {0xbc3e0000}, {0xbc3e2000}, {0xbc3e4000}, {0xbc3e6000}, + {0xbc3e8000}, {0xbc3ea000}, {0xbc3ec000}, {0xbc3ee000}, + {0xbc3f0000}, {0xbc3f2000}, {0xbc3f4000}, {0xbc3f6000}, + {0xbc3f8000}, {0xbc3fa000}, {0xbc3fc000}, {0xbc3fe000}, + {0xbc400000}, {0xbc402000}, {0xbc404000}, {0xbc406000}, + {0xbc408000}, {0xbc40a000}, {0xbc40c000}, {0xbc40e000}, + {0xbc410000}, {0xbc412000}, {0xbc414000}, {0xbc416000}, + {0xbc418000}, {0xbc41a000}, {0xbc41c000}, {0xbc41e000}, + {0xbc420000}, {0xbc422000}, {0xbc424000}, {0xbc426000}, + {0xbc428000}, {0xbc42a000}, {0xbc42c000}, {0xbc42e000}, + {0xbc430000}, {0xbc432000}, {0xbc434000}, {0xbc436000}, + {0xbc438000}, {0xbc43a000}, {0xbc43c000}, {0xbc43e000}, + {0xbc440000}, {0xbc442000}, {0xbc444000}, {0xbc446000}, + {0xbc448000}, {0xbc44a000}, {0xbc44c000}, {0xbc44e000}, + {0xbc450000}, {0xbc452000}, {0xbc454000}, {0xbc456000}, + {0xbc458000}, {0xbc45a000}, {0xbc45c000}, {0xbc45e000}, + {0xbc460000}, {0xbc462000}, {0xbc464000}, {0xbc466000}, + {0xbc468000}, {0xbc46a000}, {0xbc46c000}, {0xbc46e000}, + {0xbc470000}, {0xbc472000}, {0xbc474000}, {0xbc476000}, + {0xbc478000}, {0xbc47a000}, {0xbc47c000}, {0xbc47e000}, + {0xbc480000}, {0xbc482000}, {0xbc484000}, {0xbc486000}, + {0xbc488000}, {0xbc48a000}, {0xbc48c000}, {0xbc48e000}, + {0xbc490000}, {0xbc492000}, {0xbc494000}, {0xbc496000}, + {0xbc498000}, {0xbc49a000}, {0xbc49c000}, {0xbc49e000}, + {0xbc4a0000}, {0xbc4a2000}, {0xbc4a4000}, {0xbc4a6000}, + {0xbc4a8000}, {0xbc4aa000}, {0xbc4ac000}, {0xbc4ae000}, + {0xbc4b0000}, {0xbc4b2000}, {0xbc4b4000}, {0xbc4b6000}, + {0xbc4b8000}, {0xbc4ba000}, {0xbc4bc000}, {0xbc4be000}, + {0xbc4c0000}, {0xbc4c2000}, {0xbc4c4000}, {0xbc4c6000}, + {0xbc4c8000}, {0xbc4ca000}, {0xbc4cc000}, {0xbc4ce000}, + {0xbc4d0000}, {0xbc4d2000}, {0xbc4d4000}, {0xbc4d6000}, + {0xbc4d8000}, {0xbc4da000}, {0xbc4dc000}, {0xbc4de000}, + {0xbc4e0000}, {0xbc4e2000}, {0xbc4e4000}, {0xbc4e6000}, + {0xbc4e8000}, {0xbc4ea000}, {0xbc4ec000}, {0xbc4ee000}, + {0xbc4f0000}, {0xbc4f2000}, {0xbc4f4000}, {0xbc4f6000}, + {0xbc4f8000}, {0xbc4fa000}, {0xbc4fc000}, {0xbc4fe000}, + {0xbc500000}, {0xbc502000}, {0xbc504000}, {0xbc506000}, + {0xbc508000}, {0xbc50a000}, {0xbc50c000}, {0xbc50e000}, + {0xbc510000}, {0xbc512000}, {0xbc514000}, {0xbc516000}, + {0xbc518000}, {0xbc51a000}, {0xbc51c000}, {0xbc51e000}, + {0xbc520000}, {0xbc522000}, {0xbc524000}, {0xbc526000}, + {0xbc528000}, {0xbc52a000}, {0xbc52c000}, {0xbc52e000}, + {0xbc530000}, {0xbc532000}, {0xbc534000}, {0xbc536000}, + {0xbc538000}, {0xbc53a000}, {0xbc53c000}, {0xbc53e000}, + {0xbc540000}, {0xbc542000}, {0xbc544000}, {0xbc546000}, + {0xbc548000}, {0xbc54a000}, {0xbc54c000}, {0xbc54e000}, + {0xbc550000}, {0xbc552000}, {0xbc554000}, {0xbc556000}, + {0xbc558000}, {0xbc55a000}, {0xbc55c000}, {0xbc55e000}, + {0xbc560000}, {0xbc562000}, {0xbc564000}, {0xbc566000}, + {0xbc568000}, {0xbc56a000}, {0xbc56c000}, {0xbc56e000}, + {0xbc570000}, {0xbc572000}, {0xbc574000}, {0xbc576000}, + {0xbc578000}, {0xbc57a000}, {0xbc57c000}, {0xbc57e000}, + {0xbc580000}, {0xbc582000}, {0xbc584000}, {0xbc586000}, + {0xbc588000}, {0xbc58a000}, {0xbc58c000}, {0xbc58e000}, + {0xbc590000}, {0xbc592000}, {0xbc594000}, {0xbc596000}, + {0xbc598000}, {0xbc59a000}, {0xbc59c000}, {0xbc59e000}, + {0xbc5a0000}, {0xbc5a2000}, {0xbc5a4000}, {0xbc5a6000}, + {0xbc5a8000}, {0xbc5aa000}, {0xbc5ac000}, {0xbc5ae000}, + {0xbc5b0000}, {0xbc5b2000}, {0xbc5b4000}, {0xbc5b6000}, + {0xbc5b8000}, {0xbc5ba000}, {0xbc5bc000}, {0xbc5be000}, + {0xbc5c0000}, {0xbc5c2000}, {0xbc5c4000}, {0xbc5c6000}, + {0xbc5c8000}, {0xbc5ca000}, {0xbc5cc000}, {0xbc5ce000}, + {0xbc5d0000}, {0xbc5d2000}, {0xbc5d4000}, {0xbc5d6000}, + {0xbc5d8000}, {0xbc5da000}, {0xbc5dc000}, {0xbc5de000}, + {0xbc5e0000}, {0xbc5e2000}, {0xbc5e4000}, {0xbc5e6000}, + {0xbc5e8000}, {0xbc5ea000}, {0xbc5ec000}, {0xbc5ee000}, + {0xbc5f0000}, {0xbc5f2000}, {0xbc5f4000}, {0xbc5f6000}, + {0xbc5f8000}, {0xbc5fa000}, {0xbc5fc000}, {0xbc5fe000}, + {0xbc600000}, {0xbc602000}, {0xbc604000}, {0xbc606000}, + {0xbc608000}, {0xbc60a000}, {0xbc60c000}, {0xbc60e000}, + {0xbc610000}, {0xbc612000}, {0xbc614000}, {0xbc616000}, + {0xbc618000}, {0xbc61a000}, {0xbc61c000}, {0xbc61e000}, + {0xbc620000}, {0xbc622000}, {0xbc624000}, {0xbc626000}, + {0xbc628000}, {0xbc62a000}, {0xbc62c000}, {0xbc62e000}, + {0xbc630000}, {0xbc632000}, {0xbc634000}, {0xbc636000}, + {0xbc638000}, {0xbc63a000}, {0xbc63c000}, {0xbc63e000}, + {0xbc640000}, {0xbc642000}, {0xbc644000}, {0xbc646000}, + {0xbc648000}, {0xbc64a000}, {0xbc64c000}, {0xbc64e000}, + {0xbc650000}, {0xbc652000}, {0xbc654000}, {0xbc656000}, + {0xbc658000}, {0xbc65a000}, {0xbc65c000}, {0xbc65e000}, + {0xbc660000}, {0xbc662000}, {0xbc664000}, {0xbc666000}, + {0xbc668000}, {0xbc66a000}, {0xbc66c000}, {0xbc66e000}, + {0xbc670000}, {0xbc672000}, {0xbc674000}, {0xbc676000}, + {0xbc678000}, {0xbc67a000}, {0xbc67c000}, {0xbc67e000}, + {0xbc680000}, {0xbc682000}, {0xbc684000}, {0xbc686000}, + {0xbc688000}, {0xbc68a000}, {0xbc68c000}, {0xbc68e000}, + {0xbc690000}, {0xbc692000}, {0xbc694000}, {0xbc696000}, + {0xbc698000}, {0xbc69a000}, {0xbc69c000}, {0xbc69e000}, + {0xbc6a0000}, {0xbc6a2000}, {0xbc6a4000}, {0xbc6a6000}, + {0xbc6a8000}, {0xbc6aa000}, {0xbc6ac000}, {0xbc6ae000}, + {0xbc6b0000}, {0xbc6b2000}, {0xbc6b4000}, {0xbc6b6000}, + {0xbc6b8000}, {0xbc6ba000}, {0xbc6bc000}, {0xbc6be000}, + {0xbc6c0000}, {0xbc6c2000}, {0xbc6c4000}, {0xbc6c6000}, + {0xbc6c8000}, {0xbc6ca000}, {0xbc6cc000}, {0xbc6ce000}, + {0xbc6d0000}, {0xbc6d2000}, {0xbc6d4000}, {0xbc6d6000}, + {0xbc6d8000}, {0xbc6da000}, {0xbc6dc000}, {0xbc6de000}, + {0xbc6e0000}, {0xbc6e2000}, {0xbc6e4000}, {0xbc6e6000}, + {0xbc6e8000}, {0xbc6ea000}, {0xbc6ec000}, {0xbc6ee000}, + {0xbc6f0000}, {0xbc6f2000}, {0xbc6f4000}, {0xbc6f6000}, + {0xbc6f8000}, {0xbc6fa000}, {0xbc6fc000}, {0xbc6fe000}, + {0xbc700000}, {0xbc702000}, {0xbc704000}, {0xbc706000}, + {0xbc708000}, {0xbc70a000}, {0xbc70c000}, {0xbc70e000}, + {0xbc710000}, {0xbc712000}, {0xbc714000}, {0xbc716000}, + {0xbc718000}, {0xbc71a000}, {0xbc71c000}, {0xbc71e000}, + {0xbc720000}, {0xbc722000}, {0xbc724000}, {0xbc726000}, + {0xbc728000}, {0xbc72a000}, {0xbc72c000}, {0xbc72e000}, + {0xbc730000}, {0xbc732000}, {0xbc734000}, {0xbc736000}, + {0xbc738000}, {0xbc73a000}, {0xbc73c000}, {0xbc73e000}, + {0xbc740000}, {0xbc742000}, {0xbc744000}, {0xbc746000}, + {0xbc748000}, {0xbc74a000}, {0xbc74c000}, {0xbc74e000}, + {0xbc750000}, {0xbc752000}, {0xbc754000}, {0xbc756000}, + {0xbc758000}, {0xbc75a000}, {0xbc75c000}, {0xbc75e000}, + {0xbc760000}, {0xbc762000}, {0xbc764000}, {0xbc766000}, + {0xbc768000}, {0xbc76a000}, {0xbc76c000}, {0xbc76e000}, + {0xbc770000}, {0xbc772000}, {0xbc774000}, {0xbc776000}, + {0xbc778000}, {0xbc77a000}, {0xbc77c000}, {0xbc77e000}, + {0xbc780000}, {0xbc782000}, {0xbc784000}, {0xbc786000}, + {0xbc788000}, {0xbc78a000}, {0xbc78c000}, {0xbc78e000}, + {0xbc790000}, {0xbc792000}, {0xbc794000}, {0xbc796000}, + {0xbc798000}, {0xbc79a000}, {0xbc79c000}, {0xbc79e000}, + {0xbc7a0000}, {0xbc7a2000}, {0xbc7a4000}, {0xbc7a6000}, + {0xbc7a8000}, {0xbc7aa000}, {0xbc7ac000}, {0xbc7ae000}, + {0xbc7b0000}, {0xbc7b2000}, {0xbc7b4000}, {0xbc7b6000}, + {0xbc7b8000}, {0xbc7ba000}, {0xbc7bc000}, {0xbc7be000}, + {0xbc7c0000}, {0xbc7c2000}, {0xbc7c4000}, {0xbc7c6000}, + {0xbc7c8000}, {0xbc7ca000}, {0xbc7cc000}, {0xbc7ce000}, + {0xbc7d0000}, {0xbc7d2000}, {0xbc7d4000}, {0xbc7d6000}, + {0xbc7d8000}, {0xbc7da000}, {0xbc7dc000}, {0xbc7de000}, + {0xbc7e0000}, {0xbc7e2000}, {0xbc7e4000}, {0xbc7e6000}, + {0xbc7e8000}, {0xbc7ea000}, {0xbc7ec000}, {0xbc7ee000}, + {0xbc7f0000}, {0xbc7f2000}, {0xbc7f4000}, {0xbc7f6000}, + {0xbc7f8000}, {0xbc7fa000}, {0xbc7fc000}, {0xbc7fe000}, + {0xbc800000}, {0xbc802000}, {0xbc804000}, {0xbc806000}, + {0xbc808000}, {0xbc80a000}, {0xbc80c000}, {0xbc80e000}, + {0xbc810000}, {0xbc812000}, {0xbc814000}, {0xbc816000}, + {0xbc818000}, {0xbc81a000}, {0xbc81c000}, {0xbc81e000}, + {0xbc820000}, {0xbc822000}, {0xbc824000}, {0xbc826000}, + {0xbc828000}, {0xbc82a000}, {0xbc82c000}, {0xbc82e000}, + {0xbc830000}, {0xbc832000}, {0xbc834000}, {0xbc836000}, + {0xbc838000}, {0xbc83a000}, {0xbc83c000}, {0xbc83e000}, + {0xbc840000}, {0xbc842000}, {0xbc844000}, {0xbc846000}, + {0xbc848000}, {0xbc84a000}, {0xbc84c000}, {0xbc84e000}, + {0xbc850000}, {0xbc852000}, {0xbc854000}, {0xbc856000}, + {0xbc858000}, {0xbc85a000}, {0xbc85c000}, {0xbc85e000}, + {0xbc860000}, {0xbc862000}, {0xbc864000}, {0xbc866000}, + {0xbc868000}, {0xbc86a000}, {0xbc86c000}, {0xbc86e000}, + {0xbc870000}, {0xbc872000}, {0xbc874000}, {0xbc876000}, + {0xbc878000}, {0xbc87a000}, {0xbc87c000}, {0xbc87e000}, + {0xbc880000}, {0xbc882000}, {0xbc884000}, {0xbc886000}, + {0xbc888000}, {0xbc88a000}, {0xbc88c000}, {0xbc88e000}, + {0xbc890000}, {0xbc892000}, {0xbc894000}, {0xbc896000}, + {0xbc898000}, {0xbc89a000}, {0xbc89c000}, {0xbc89e000}, + {0xbc8a0000}, {0xbc8a2000}, {0xbc8a4000}, {0xbc8a6000}, + {0xbc8a8000}, {0xbc8aa000}, {0xbc8ac000}, {0xbc8ae000}, + {0xbc8b0000}, {0xbc8b2000}, {0xbc8b4000}, {0xbc8b6000}, + {0xbc8b8000}, {0xbc8ba000}, {0xbc8bc000}, {0xbc8be000}, + {0xbc8c0000}, {0xbc8c2000}, {0xbc8c4000}, {0xbc8c6000}, + {0xbc8c8000}, {0xbc8ca000}, {0xbc8cc000}, {0xbc8ce000}, + {0xbc8d0000}, {0xbc8d2000}, {0xbc8d4000}, {0xbc8d6000}, + {0xbc8d8000}, {0xbc8da000}, {0xbc8dc000}, {0xbc8de000}, + {0xbc8e0000}, {0xbc8e2000}, {0xbc8e4000}, {0xbc8e6000}, + {0xbc8e8000}, {0xbc8ea000}, {0xbc8ec000}, {0xbc8ee000}, + {0xbc8f0000}, {0xbc8f2000}, {0xbc8f4000}, {0xbc8f6000}, + {0xbc8f8000}, {0xbc8fa000}, {0xbc8fc000}, {0xbc8fe000}, + {0xbc900000}, {0xbc902000}, {0xbc904000}, {0xbc906000}, + {0xbc908000}, {0xbc90a000}, {0xbc90c000}, {0xbc90e000}, + {0xbc910000}, {0xbc912000}, {0xbc914000}, {0xbc916000}, + {0xbc918000}, {0xbc91a000}, {0xbc91c000}, {0xbc91e000}, + {0xbc920000}, {0xbc922000}, {0xbc924000}, {0xbc926000}, + {0xbc928000}, {0xbc92a000}, {0xbc92c000}, {0xbc92e000}, + {0xbc930000}, {0xbc932000}, {0xbc934000}, {0xbc936000}, + {0xbc938000}, {0xbc93a000}, {0xbc93c000}, {0xbc93e000}, + {0xbc940000}, {0xbc942000}, {0xbc944000}, {0xbc946000}, + {0xbc948000}, {0xbc94a000}, {0xbc94c000}, {0xbc94e000}, + {0xbc950000}, {0xbc952000}, {0xbc954000}, {0xbc956000}, + {0xbc958000}, {0xbc95a000}, {0xbc95c000}, {0xbc95e000}, + {0xbc960000}, {0xbc962000}, {0xbc964000}, {0xbc966000}, + {0xbc968000}, {0xbc96a000}, {0xbc96c000}, {0xbc96e000}, + {0xbc970000}, {0xbc972000}, {0xbc974000}, {0xbc976000}, + {0xbc978000}, {0xbc97a000}, {0xbc97c000}, {0xbc97e000}, + {0xbc980000}, {0xbc982000}, {0xbc984000}, {0xbc986000}, + {0xbc988000}, {0xbc98a000}, {0xbc98c000}, {0xbc98e000}, + {0xbc990000}, {0xbc992000}, {0xbc994000}, {0xbc996000}, + {0xbc998000}, {0xbc99a000}, {0xbc99c000}, {0xbc99e000}, + {0xbc9a0000}, {0xbc9a2000}, {0xbc9a4000}, {0xbc9a6000}, + {0xbc9a8000}, {0xbc9aa000}, {0xbc9ac000}, {0xbc9ae000}, + {0xbc9b0000}, {0xbc9b2000}, {0xbc9b4000}, {0xbc9b6000}, + {0xbc9b8000}, {0xbc9ba000}, {0xbc9bc000}, {0xbc9be000}, + {0xbc9c0000}, {0xbc9c2000}, {0xbc9c4000}, {0xbc9c6000}, + {0xbc9c8000}, {0xbc9ca000}, {0xbc9cc000}, {0xbc9ce000}, + {0xbc9d0000}, {0xbc9d2000}, {0xbc9d4000}, {0xbc9d6000}, + {0xbc9d8000}, {0xbc9da000}, {0xbc9dc000}, {0xbc9de000}, + {0xbc9e0000}, {0xbc9e2000}, {0xbc9e4000}, {0xbc9e6000}, + {0xbc9e8000}, {0xbc9ea000}, {0xbc9ec000}, {0xbc9ee000}, + {0xbc9f0000}, {0xbc9f2000}, {0xbc9f4000}, {0xbc9f6000}, + {0xbc9f8000}, {0xbc9fa000}, {0xbc9fc000}, {0xbc9fe000}, + {0xbca00000}, {0xbca02000}, {0xbca04000}, {0xbca06000}, + {0xbca08000}, {0xbca0a000}, {0xbca0c000}, {0xbca0e000}, + {0xbca10000}, {0xbca12000}, {0xbca14000}, {0xbca16000}, + {0xbca18000}, {0xbca1a000}, {0xbca1c000}, {0xbca1e000}, + {0xbca20000}, {0xbca22000}, {0xbca24000}, {0xbca26000}, + {0xbca28000}, {0xbca2a000}, {0xbca2c000}, {0xbca2e000}, + {0xbca30000}, {0xbca32000}, {0xbca34000}, {0xbca36000}, + {0xbca38000}, {0xbca3a000}, {0xbca3c000}, {0xbca3e000}, + {0xbca40000}, {0xbca42000}, {0xbca44000}, {0xbca46000}, + {0xbca48000}, {0xbca4a000}, {0xbca4c000}, {0xbca4e000}, + {0xbca50000}, {0xbca52000}, {0xbca54000}, {0xbca56000}, + {0xbca58000}, {0xbca5a000}, {0xbca5c000}, {0xbca5e000}, + {0xbca60000}, {0xbca62000}, {0xbca64000}, {0xbca66000}, + {0xbca68000}, {0xbca6a000}, {0xbca6c000}, {0xbca6e000}, + {0xbca70000}, {0xbca72000}, {0xbca74000}, {0xbca76000}, + {0xbca78000}, {0xbca7a000}, {0xbca7c000}, {0xbca7e000}, + {0xbca80000}, {0xbca82000}, {0xbca84000}, {0xbca86000}, + {0xbca88000}, {0xbca8a000}, {0xbca8c000}, {0xbca8e000}, + {0xbca90000}, {0xbca92000}, {0xbca94000}, {0xbca96000}, + {0xbca98000}, {0xbca9a000}, {0xbca9c000}, {0xbca9e000}, + {0xbcaa0000}, {0xbcaa2000}, {0xbcaa4000}, {0xbcaa6000}, + {0xbcaa8000}, {0xbcaaa000}, {0xbcaac000}, {0xbcaae000}, + {0xbcab0000}, {0xbcab2000}, {0xbcab4000}, {0xbcab6000}, + {0xbcab8000}, {0xbcaba000}, {0xbcabc000}, {0xbcabe000}, + {0xbcac0000}, {0xbcac2000}, {0xbcac4000}, {0xbcac6000}, + {0xbcac8000}, {0xbcaca000}, {0xbcacc000}, {0xbcace000}, + {0xbcad0000}, {0xbcad2000}, {0xbcad4000}, {0xbcad6000}, + {0xbcad8000}, {0xbcada000}, {0xbcadc000}, {0xbcade000}, + {0xbcae0000}, {0xbcae2000}, {0xbcae4000}, {0xbcae6000}, + {0xbcae8000}, {0xbcaea000}, {0xbcaec000}, {0xbcaee000}, + {0xbcaf0000}, {0xbcaf2000}, {0xbcaf4000}, {0xbcaf6000}, + {0xbcaf8000}, {0xbcafa000}, {0xbcafc000}, {0xbcafe000}, + {0xbcb00000}, {0xbcb02000}, {0xbcb04000}, {0xbcb06000}, + {0xbcb08000}, {0xbcb0a000}, {0xbcb0c000}, {0xbcb0e000}, + {0xbcb10000}, {0xbcb12000}, {0xbcb14000}, {0xbcb16000}, + {0xbcb18000}, {0xbcb1a000}, {0xbcb1c000}, {0xbcb1e000}, + {0xbcb20000}, {0xbcb22000}, {0xbcb24000}, {0xbcb26000}, + {0xbcb28000}, {0xbcb2a000}, {0xbcb2c000}, {0xbcb2e000}, + {0xbcb30000}, {0xbcb32000}, {0xbcb34000}, {0xbcb36000}, + {0xbcb38000}, {0xbcb3a000}, {0xbcb3c000}, {0xbcb3e000}, + {0xbcb40000}, {0xbcb42000}, {0xbcb44000}, {0xbcb46000}, + {0xbcb48000}, {0xbcb4a000}, {0xbcb4c000}, {0xbcb4e000}, + {0xbcb50000}, {0xbcb52000}, {0xbcb54000}, {0xbcb56000}, + {0xbcb58000}, {0xbcb5a000}, {0xbcb5c000}, {0xbcb5e000}, + {0xbcb60000}, {0xbcb62000}, {0xbcb64000}, {0xbcb66000}, + {0xbcb68000}, {0xbcb6a000}, {0xbcb6c000}, {0xbcb6e000}, + {0xbcb70000}, {0xbcb72000}, {0xbcb74000}, {0xbcb76000}, + {0xbcb78000}, {0xbcb7a000}, {0xbcb7c000}, {0xbcb7e000}, + {0xbcb80000}, {0xbcb82000}, {0xbcb84000}, {0xbcb86000}, + {0xbcb88000}, {0xbcb8a000}, {0xbcb8c000}, {0xbcb8e000}, + {0xbcb90000}, {0xbcb92000}, {0xbcb94000}, {0xbcb96000}, + {0xbcb98000}, {0xbcb9a000}, {0xbcb9c000}, {0xbcb9e000}, + {0xbcba0000}, {0xbcba2000}, {0xbcba4000}, {0xbcba6000}, + {0xbcba8000}, {0xbcbaa000}, {0xbcbac000}, {0xbcbae000}, + {0xbcbb0000}, {0xbcbb2000}, {0xbcbb4000}, {0xbcbb6000}, + {0xbcbb8000}, {0xbcbba000}, {0xbcbbc000}, {0xbcbbe000}, + {0xbcbc0000}, {0xbcbc2000}, {0xbcbc4000}, {0xbcbc6000}, + {0xbcbc8000}, {0xbcbca000}, {0xbcbcc000}, {0xbcbce000}, + {0xbcbd0000}, {0xbcbd2000}, {0xbcbd4000}, {0xbcbd6000}, + {0xbcbd8000}, {0xbcbda000}, {0xbcbdc000}, {0xbcbde000}, + {0xbcbe0000}, {0xbcbe2000}, {0xbcbe4000}, {0xbcbe6000}, + {0xbcbe8000}, {0xbcbea000}, {0xbcbec000}, {0xbcbee000}, + {0xbcbf0000}, {0xbcbf2000}, {0xbcbf4000}, {0xbcbf6000}, + {0xbcbf8000}, {0xbcbfa000}, {0xbcbfc000}, {0xbcbfe000}, + {0xbcc00000}, {0xbcc02000}, {0xbcc04000}, {0xbcc06000}, + {0xbcc08000}, {0xbcc0a000}, {0xbcc0c000}, {0xbcc0e000}, + {0xbcc10000}, {0xbcc12000}, {0xbcc14000}, {0xbcc16000}, + {0xbcc18000}, {0xbcc1a000}, {0xbcc1c000}, {0xbcc1e000}, + {0xbcc20000}, {0xbcc22000}, {0xbcc24000}, {0xbcc26000}, + {0xbcc28000}, {0xbcc2a000}, {0xbcc2c000}, {0xbcc2e000}, + {0xbcc30000}, {0xbcc32000}, {0xbcc34000}, {0xbcc36000}, + {0xbcc38000}, {0xbcc3a000}, {0xbcc3c000}, {0xbcc3e000}, + {0xbcc40000}, {0xbcc42000}, {0xbcc44000}, {0xbcc46000}, + {0xbcc48000}, {0xbcc4a000}, {0xbcc4c000}, {0xbcc4e000}, + {0xbcc50000}, {0xbcc52000}, {0xbcc54000}, {0xbcc56000}, + {0xbcc58000}, {0xbcc5a000}, {0xbcc5c000}, {0xbcc5e000}, + {0xbcc60000}, {0xbcc62000}, {0xbcc64000}, {0xbcc66000}, + {0xbcc68000}, {0xbcc6a000}, {0xbcc6c000}, {0xbcc6e000}, + {0xbcc70000}, {0xbcc72000}, {0xbcc74000}, {0xbcc76000}, + {0xbcc78000}, {0xbcc7a000}, {0xbcc7c000}, {0xbcc7e000}, + {0xbcc80000}, {0xbcc82000}, {0xbcc84000}, {0xbcc86000}, + {0xbcc88000}, {0xbcc8a000}, {0xbcc8c000}, {0xbcc8e000}, + {0xbcc90000}, {0xbcc92000}, {0xbcc94000}, {0xbcc96000}, + {0xbcc98000}, {0xbcc9a000}, {0xbcc9c000}, {0xbcc9e000}, + {0xbcca0000}, {0xbcca2000}, {0xbcca4000}, {0xbcca6000}, + {0xbcca8000}, {0xbccaa000}, {0xbccac000}, {0xbccae000}, + {0xbccb0000}, {0xbccb2000}, {0xbccb4000}, {0xbccb6000}, + {0xbccb8000}, {0xbccba000}, {0xbccbc000}, {0xbccbe000}, + {0xbccc0000}, {0xbccc2000}, {0xbccc4000}, {0xbccc6000}, + {0xbccc8000}, {0xbccca000}, {0xbcccc000}, {0xbccce000}, + {0xbccd0000}, {0xbccd2000}, {0xbccd4000}, {0xbccd6000}, + {0xbccd8000}, {0xbccda000}, {0xbccdc000}, {0xbccde000}, + {0xbcce0000}, {0xbcce2000}, {0xbcce4000}, {0xbcce6000}, + {0xbcce8000}, {0xbccea000}, {0xbccec000}, {0xbccee000}, + {0xbccf0000}, {0xbccf2000}, {0xbccf4000}, {0xbccf6000}, + {0xbccf8000}, {0xbccfa000}, {0xbccfc000}, {0xbccfe000}, + {0xbcd00000}, {0xbcd02000}, {0xbcd04000}, {0xbcd06000}, + {0xbcd08000}, {0xbcd0a000}, {0xbcd0c000}, {0xbcd0e000}, + {0xbcd10000}, {0xbcd12000}, {0xbcd14000}, {0xbcd16000}, + {0xbcd18000}, {0xbcd1a000}, {0xbcd1c000}, {0xbcd1e000}, + {0xbcd20000}, {0xbcd22000}, {0xbcd24000}, {0xbcd26000}, + {0xbcd28000}, {0xbcd2a000}, {0xbcd2c000}, {0xbcd2e000}, + {0xbcd30000}, {0xbcd32000}, {0xbcd34000}, {0xbcd36000}, + {0xbcd38000}, {0xbcd3a000}, {0xbcd3c000}, {0xbcd3e000}, + {0xbcd40000}, {0xbcd42000}, {0xbcd44000}, {0xbcd46000}, + {0xbcd48000}, {0xbcd4a000}, {0xbcd4c000}, {0xbcd4e000}, + {0xbcd50000}, {0xbcd52000}, {0xbcd54000}, {0xbcd56000}, + {0xbcd58000}, {0xbcd5a000}, {0xbcd5c000}, {0xbcd5e000}, + {0xbcd60000}, {0xbcd62000}, {0xbcd64000}, {0xbcd66000}, + {0xbcd68000}, {0xbcd6a000}, {0xbcd6c000}, {0xbcd6e000}, + {0xbcd70000}, {0xbcd72000}, {0xbcd74000}, {0xbcd76000}, + {0xbcd78000}, {0xbcd7a000}, {0xbcd7c000}, {0xbcd7e000}, + {0xbcd80000}, {0xbcd82000}, {0xbcd84000}, {0xbcd86000}, + {0xbcd88000}, {0xbcd8a000}, {0xbcd8c000}, {0xbcd8e000}, + {0xbcd90000}, {0xbcd92000}, {0xbcd94000}, {0xbcd96000}, + {0xbcd98000}, {0xbcd9a000}, {0xbcd9c000}, {0xbcd9e000}, + {0xbcda0000}, {0xbcda2000}, {0xbcda4000}, {0xbcda6000}, + {0xbcda8000}, {0xbcdaa000}, {0xbcdac000}, {0xbcdae000}, + {0xbcdb0000}, {0xbcdb2000}, {0xbcdb4000}, {0xbcdb6000}, + {0xbcdb8000}, {0xbcdba000}, {0xbcdbc000}, {0xbcdbe000}, + {0xbcdc0000}, {0xbcdc2000}, {0xbcdc4000}, {0xbcdc6000}, + {0xbcdc8000}, {0xbcdca000}, {0xbcdcc000}, {0xbcdce000}, + {0xbcdd0000}, {0xbcdd2000}, {0xbcdd4000}, {0xbcdd6000}, + {0xbcdd8000}, {0xbcdda000}, {0xbcddc000}, {0xbcdde000}, + {0xbcde0000}, {0xbcde2000}, {0xbcde4000}, {0xbcde6000}, + {0xbcde8000}, {0xbcdea000}, {0xbcdec000}, {0xbcdee000}, + {0xbcdf0000}, {0xbcdf2000}, {0xbcdf4000}, {0xbcdf6000}, + {0xbcdf8000}, {0xbcdfa000}, {0xbcdfc000}, {0xbcdfe000}, + {0xbce00000}, {0xbce02000}, {0xbce04000}, {0xbce06000}, + {0xbce08000}, {0xbce0a000}, {0xbce0c000}, {0xbce0e000}, + {0xbce10000}, {0xbce12000}, {0xbce14000}, {0xbce16000}, + {0xbce18000}, {0xbce1a000}, {0xbce1c000}, {0xbce1e000}, + {0xbce20000}, {0xbce22000}, {0xbce24000}, {0xbce26000}, + {0xbce28000}, {0xbce2a000}, {0xbce2c000}, {0xbce2e000}, + {0xbce30000}, {0xbce32000}, {0xbce34000}, {0xbce36000}, + {0xbce38000}, {0xbce3a000}, {0xbce3c000}, {0xbce3e000}, + {0xbce40000}, {0xbce42000}, {0xbce44000}, {0xbce46000}, + {0xbce48000}, {0xbce4a000}, {0xbce4c000}, {0xbce4e000}, + {0xbce50000}, {0xbce52000}, {0xbce54000}, {0xbce56000}, + {0xbce58000}, {0xbce5a000}, {0xbce5c000}, {0xbce5e000}, + {0xbce60000}, {0xbce62000}, {0xbce64000}, {0xbce66000}, + {0xbce68000}, {0xbce6a000}, {0xbce6c000}, {0xbce6e000}, + {0xbce70000}, {0xbce72000}, {0xbce74000}, {0xbce76000}, + {0xbce78000}, {0xbce7a000}, {0xbce7c000}, {0xbce7e000}, + {0xbce80000}, {0xbce82000}, {0xbce84000}, {0xbce86000}, + {0xbce88000}, {0xbce8a000}, {0xbce8c000}, {0xbce8e000}, + {0xbce90000}, {0xbce92000}, {0xbce94000}, {0xbce96000}, + {0xbce98000}, {0xbce9a000}, {0xbce9c000}, {0xbce9e000}, + {0xbcea0000}, {0xbcea2000}, {0xbcea4000}, {0xbcea6000}, + {0xbcea8000}, {0xbceaa000}, {0xbceac000}, {0xbceae000}, + {0xbceb0000}, {0xbceb2000}, {0xbceb4000}, {0xbceb6000}, + {0xbceb8000}, {0xbceba000}, {0xbcebc000}, {0xbcebe000}, + {0xbcec0000}, {0xbcec2000}, {0xbcec4000}, {0xbcec6000}, + {0xbcec8000}, {0xbceca000}, {0xbcecc000}, {0xbcece000}, + {0xbced0000}, {0xbced2000}, {0xbced4000}, {0xbced6000}, + {0xbced8000}, {0xbceda000}, {0xbcedc000}, {0xbcede000}, + {0xbcee0000}, {0xbcee2000}, {0xbcee4000}, {0xbcee6000}, + {0xbcee8000}, {0xbceea000}, {0xbceec000}, {0xbceee000}, + {0xbcef0000}, {0xbcef2000}, {0xbcef4000}, {0xbcef6000}, + {0xbcef8000}, {0xbcefa000}, {0xbcefc000}, {0xbcefe000}, + {0xbcf00000}, {0xbcf02000}, {0xbcf04000}, {0xbcf06000}, + {0xbcf08000}, {0xbcf0a000}, {0xbcf0c000}, {0xbcf0e000}, + {0xbcf10000}, {0xbcf12000}, {0xbcf14000}, {0xbcf16000}, + {0xbcf18000}, {0xbcf1a000}, {0xbcf1c000}, {0xbcf1e000}, + {0xbcf20000}, {0xbcf22000}, {0xbcf24000}, {0xbcf26000}, + {0xbcf28000}, {0xbcf2a000}, {0xbcf2c000}, {0xbcf2e000}, + {0xbcf30000}, {0xbcf32000}, {0xbcf34000}, {0xbcf36000}, + {0xbcf38000}, {0xbcf3a000}, {0xbcf3c000}, {0xbcf3e000}, + {0xbcf40000}, {0xbcf42000}, {0xbcf44000}, {0xbcf46000}, + {0xbcf48000}, {0xbcf4a000}, {0xbcf4c000}, {0xbcf4e000}, + {0xbcf50000}, {0xbcf52000}, {0xbcf54000}, {0xbcf56000}, + {0xbcf58000}, {0xbcf5a000}, {0xbcf5c000}, {0xbcf5e000}, + {0xbcf60000}, {0xbcf62000}, {0xbcf64000}, {0xbcf66000}, + {0xbcf68000}, {0xbcf6a000}, {0xbcf6c000}, {0xbcf6e000}, + {0xbcf70000}, {0xbcf72000}, {0xbcf74000}, {0xbcf76000}, + {0xbcf78000}, {0xbcf7a000}, {0xbcf7c000}, {0xbcf7e000}, + {0xbcf80000}, {0xbcf82000}, {0xbcf84000}, {0xbcf86000}, + {0xbcf88000}, {0xbcf8a000}, {0xbcf8c000}, {0xbcf8e000}, + {0xbcf90000}, {0xbcf92000}, {0xbcf94000}, {0xbcf96000}, + {0xbcf98000}, {0xbcf9a000}, {0xbcf9c000}, {0xbcf9e000}, + {0xbcfa0000}, {0xbcfa2000}, {0xbcfa4000}, {0xbcfa6000}, + {0xbcfa8000}, {0xbcfaa000}, {0xbcfac000}, {0xbcfae000}, + {0xbcfb0000}, {0xbcfb2000}, {0xbcfb4000}, {0xbcfb6000}, + {0xbcfb8000}, {0xbcfba000}, {0xbcfbc000}, {0xbcfbe000}, + {0xbcfc0000}, {0xbcfc2000}, {0xbcfc4000}, {0xbcfc6000}, + {0xbcfc8000}, {0xbcfca000}, {0xbcfcc000}, {0xbcfce000}, + {0xbcfd0000}, {0xbcfd2000}, {0xbcfd4000}, {0xbcfd6000}, + {0xbcfd8000}, {0xbcfda000}, {0xbcfdc000}, {0xbcfde000}, + {0xbcfe0000}, {0xbcfe2000}, {0xbcfe4000}, {0xbcfe6000}, + {0xbcfe8000}, {0xbcfea000}, {0xbcfec000}, {0xbcfee000}, + {0xbcff0000}, {0xbcff2000}, {0xbcff4000}, {0xbcff6000}, + {0xbcff8000}, {0xbcffa000}, {0xbcffc000}, {0xbcffe000}, + {0xbd000000}, {0xbd002000}, {0xbd004000}, {0xbd006000}, + {0xbd008000}, {0xbd00a000}, {0xbd00c000}, {0xbd00e000}, + {0xbd010000}, {0xbd012000}, {0xbd014000}, {0xbd016000}, + {0xbd018000}, {0xbd01a000}, {0xbd01c000}, {0xbd01e000}, + {0xbd020000}, {0xbd022000}, {0xbd024000}, {0xbd026000}, + {0xbd028000}, {0xbd02a000}, {0xbd02c000}, {0xbd02e000}, + {0xbd030000}, {0xbd032000}, {0xbd034000}, {0xbd036000}, + {0xbd038000}, {0xbd03a000}, {0xbd03c000}, {0xbd03e000}, + {0xbd040000}, {0xbd042000}, {0xbd044000}, {0xbd046000}, + {0xbd048000}, {0xbd04a000}, {0xbd04c000}, {0xbd04e000}, + {0xbd050000}, {0xbd052000}, {0xbd054000}, {0xbd056000}, + {0xbd058000}, {0xbd05a000}, {0xbd05c000}, {0xbd05e000}, + {0xbd060000}, {0xbd062000}, {0xbd064000}, {0xbd066000}, + {0xbd068000}, {0xbd06a000}, {0xbd06c000}, {0xbd06e000}, + {0xbd070000}, {0xbd072000}, {0xbd074000}, {0xbd076000}, + {0xbd078000}, {0xbd07a000}, {0xbd07c000}, {0xbd07e000}, + {0xbd080000}, {0xbd082000}, {0xbd084000}, {0xbd086000}, + {0xbd088000}, {0xbd08a000}, {0xbd08c000}, {0xbd08e000}, + {0xbd090000}, {0xbd092000}, {0xbd094000}, {0xbd096000}, + {0xbd098000}, {0xbd09a000}, {0xbd09c000}, {0xbd09e000}, + {0xbd0a0000}, {0xbd0a2000}, {0xbd0a4000}, {0xbd0a6000}, + {0xbd0a8000}, {0xbd0aa000}, {0xbd0ac000}, {0xbd0ae000}, + {0xbd0b0000}, {0xbd0b2000}, {0xbd0b4000}, {0xbd0b6000}, + {0xbd0b8000}, {0xbd0ba000}, {0xbd0bc000}, {0xbd0be000}, + {0xbd0c0000}, {0xbd0c2000}, {0xbd0c4000}, {0xbd0c6000}, + {0xbd0c8000}, {0xbd0ca000}, {0xbd0cc000}, {0xbd0ce000}, + {0xbd0d0000}, {0xbd0d2000}, {0xbd0d4000}, {0xbd0d6000}, + {0xbd0d8000}, {0xbd0da000}, {0xbd0dc000}, {0xbd0de000}, + {0xbd0e0000}, {0xbd0e2000}, {0xbd0e4000}, {0xbd0e6000}, + {0xbd0e8000}, {0xbd0ea000}, {0xbd0ec000}, {0xbd0ee000}, + {0xbd0f0000}, {0xbd0f2000}, {0xbd0f4000}, {0xbd0f6000}, + {0xbd0f8000}, {0xbd0fa000}, {0xbd0fc000}, {0xbd0fe000}, + {0xbd100000}, {0xbd102000}, {0xbd104000}, {0xbd106000}, + {0xbd108000}, {0xbd10a000}, {0xbd10c000}, {0xbd10e000}, + {0xbd110000}, {0xbd112000}, {0xbd114000}, {0xbd116000}, + {0xbd118000}, {0xbd11a000}, {0xbd11c000}, {0xbd11e000}, + {0xbd120000}, {0xbd122000}, {0xbd124000}, {0xbd126000}, + {0xbd128000}, {0xbd12a000}, {0xbd12c000}, {0xbd12e000}, + {0xbd130000}, {0xbd132000}, {0xbd134000}, {0xbd136000}, + {0xbd138000}, {0xbd13a000}, {0xbd13c000}, {0xbd13e000}, + {0xbd140000}, {0xbd142000}, {0xbd144000}, {0xbd146000}, + {0xbd148000}, {0xbd14a000}, {0xbd14c000}, {0xbd14e000}, + {0xbd150000}, {0xbd152000}, {0xbd154000}, {0xbd156000}, + {0xbd158000}, {0xbd15a000}, {0xbd15c000}, {0xbd15e000}, + {0xbd160000}, {0xbd162000}, {0xbd164000}, {0xbd166000}, + {0xbd168000}, {0xbd16a000}, {0xbd16c000}, {0xbd16e000}, + {0xbd170000}, {0xbd172000}, {0xbd174000}, {0xbd176000}, + {0xbd178000}, {0xbd17a000}, {0xbd17c000}, {0xbd17e000}, + {0xbd180000}, {0xbd182000}, {0xbd184000}, {0xbd186000}, + {0xbd188000}, {0xbd18a000}, {0xbd18c000}, {0xbd18e000}, + {0xbd190000}, {0xbd192000}, {0xbd194000}, {0xbd196000}, + {0xbd198000}, {0xbd19a000}, {0xbd19c000}, {0xbd19e000}, + {0xbd1a0000}, {0xbd1a2000}, {0xbd1a4000}, {0xbd1a6000}, + {0xbd1a8000}, {0xbd1aa000}, {0xbd1ac000}, {0xbd1ae000}, + {0xbd1b0000}, {0xbd1b2000}, {0xbd1b4000}, {0xbd1b6000}, + {0xbd1b8000}, {0xbd1ba000}, {0xbd1bc000}, {0xbd1be000}, + {0xbd1c0000}, {0xbd1c2000}, {0xbd1c4000}, {0xbd1c6000}, + {0xbd1c8000}, {0xbd1ca000}, {0xbd1cc000}, {0xbd1ce000}, + {0xbd1d0000}, {0xbd1d2000}, {0xbd1d4000}, {0xbd1d6000}, + {0xbd1d8000}, {0xbd1da000}, {0xbd1dc000}, {0xbd1de000}, + {0xbd1e0000}, {0xbd1e2000}, {0xbd1e4000}, {0xbd1e6000}, + {0xbd1e8000}, {0xbd1ea000}, {0xbd1ec000}, {0xbd1ee000}, + {0xbd1f0000}, {0xbd1f2000}, {0xbd1f4000}, {0xbd1f6000}, + {0xbd1f8000}, {0xbd1fa000}, {0xbd1fc000}, {0xbd1fe000}, + {0xbd200000}, {0xbd202000}, {0xbd204000}, {0xbd206000}, + {0xbd208000}, {0xbd20a000}, {0xbd20c000}, {0xbd20e000}, + {0xbd210000}, {0xbd212000}, {0xbd214000}, {0xbd216000}, + {0xbd218000}, {0xbd21a000}, {0xbd21c000}, {0xbd21e000}, + {0xbd220000}, {0xbd222000}, {0xbd224000}, {0xbd226000}, + {0xbd228000}, {0xbd22a000}, {0xbd22c000}, {0xbd22e000}, + {0xbd230000}, {0xbd232000}, {0xbd234000}, {0xbd236000}, + {0xbd238000}, {0xbd23a000}, {0xbd23c000}, {0xbd23e000}, + {0xbd240000}, {0xbd242000}, {0xbd244000}, {0xbd246000}, + {0xbd248000}, {0xbd24a000}, {0xbd24c000}, {0xbd24e000}, + {0xbd250000}, {0xbd252000}, {0xbd254000}, {0xbd256000}, + {0xbd258000}, {0xbd25a000}, {0xbd25c000}, {0xbd25e000}, + {0xbd260000}, {0xbd262000}, {0xbd264000}, {0xbd266000}, + {0xbd268000}, {0xbd26a000}, {0xbd26c000}, {0xbd26e000}, + {0xbd270000}, {0xbd272000}, {0xbd274000}, {0xbd276000}, + {0xbd278000}, {0xbd27a000}, {0xbd27c000}, {0xbd27e000}, + {0xbd280000}, {0xbd282000}, {0xbd284000}, {0xbd286000}, + {0xbd288000}, {0xbd28a000}, {0xbd28c000}, {0xbd28e000}, + {0xbd290000}, {0xbd292000}, {0xbd294000}, {0xbd296000}, + {0xbd298000}, {0xbd29a000}, {0xbd29c000}, {0xbd29e000}, + {0xbd2a0000}, {0xbd2a2000}, {0xbd2a4000}, {0xbd2a6000}, + {0xbd2a8000}, {0xbd2aa000}, {0xbd2ac000}, {0xbd2ae000}, + {0xbd2b0000}, {0xbd2b2000}, {0xbd2b4000}, {0xbd2b6000}, + {0xbd2b8000}, {0xbd2ba000}, {0xbd2bc000}, {0xbd2be000}, + {0xbd2c0000}, {0xbd2c2000}, {0xbd2c4000}, {0xbd2c6000}, + {0xbd2c8000}, {0xbd2ca000}, {0xbd2cc000}, {0xbd2ce000}, + {0xbd2d0000}, {0xbd2d2000}, {0xbd2d4000}, {0xbd2d6000}, + {0xbd2d8000}, {0xbd2da000}, {0xbd2dc000}, {0xbd2de000}, + {0xbd2e0000}, {0xbd2e2000}, {0xbd2e4000}, {0xbd2e6000}, + {0xbd2e8000}, {0xbd2ea000}, {0xbd2ec000}, {0xbd2ee000}, + {0xbd2f0000}, {0xbd2f2000}, {0xbd2f4000}, {0xbd2f6000}, + {0xbd2f8000}, {0xbd2fa000}, {0xbd2fc000}, {0xbd2fe000}, + {0xbd300000}, {0xbd302000}, {0xbd304000}, {0xbd306000}, + {0xbd308000}, {0xbd30a000}, {0xbd30c000}, {0xbd30e000}, + {0xbd310000}, {0xbd312000}, {0xbd314000}, {0xbd316000}, + {0xbd318000}, {0xbd31a000}, {0xbd31c000}, {0xbd31e000}, + {0xbd320000}, {0xbd322000}, {0xbd324000}, {0xbd326000}, + {0xbd328000}, {0xbd32a000}, {0xbd32c000}, {0xbd32e000}, + {0xbd330000}, {0xbd332000}, {0xbd334000}, {0xbd336000}, + {0xbd338000}, {0xbd33a000}, {0xbd33c000}, {0xbd33e000}, + {0xbd340000}, {0xbd342000}, {0xbd344000}, {0xbd346000}, + {0xbd348000}, {0xbd34a000}, {0xbd34c000}, {0xbd34e000}, + {0xbd350000}, {0xbd352000}, {0xbd354000}, {0xbd356000}, + {0xbd358000}, {0xbd35a000}, {0xbd35c000}, {0xbd35e000}, + {0xbd360000}, {0xbd362000}, {0xbd364000}, {0xbd366000}, + {0xbd368000}, {0xbd36a000}, {0xbd36c000}, {0xbd36e000}, + {0xbd370000}, {0xbd372000}, {0xbd374000}, {0xbd376000}, + {0xbd378000}, {0xbd37a000}, {0xbd37c000}, {0xbd37e000}, + {0xbd380000}, {0xbd382000}, {0xbd384000}, {0xbd386000}, + {0xbd388000}, {0xbd38a000}, {0xbd38c000}, {0xbd38e000}, + {0xbd390000}, {0xbd392000}, {0xbd394000}, {0xbd396000}, + {0xbd398000}, {0xbd39a000}, {0xbd39c000}, {0xbd39e000}, + {0xbd3a0000}, {0xbd3a2000}, {0xbd3a4000}, {0xbd3a6000}, + {0xbd3a8000}, {0xbd3aa000}, {0xbd3ac000}, {0xbd3ae000}, + {0xbd3b0000}, {0xbd3b2000}, {0xbd3b4000}, {0xbd3b6000}, + {0xbd3b8000}, {0xbd3ba000}, {0xbd3bc000}, {0xbd3be000}, + {0xbd3c0000}, {0xbd3c2000}, {0xbd3c4000}, {0xbd3c6000}, + {0xbd3c8000}, {0xbd3ca000}, {0xbd3cc000}, {0xbd3ce000}, + {0xbd3d0000}, {0xbd3d2000}, {0xbd3d4000}, {0xbd3d6000}, + {0xbd3d8000}, {0xbd3da000}, {0xbd3dc000}, {0xbd3de000}, + {0xbd3e0000}, {0xbd3e2000}, {0xbd3e4000}, {0xbd3e6000}, + {0xbd3e8000}, {0xbd3ea000}, {0xbd3ec000}, {0xbd3ee000}, + {0xbd3f0000}, {0xbd3f2000}, {0xbd3f4000}, {0xbd3f6000}, + {0xbd3f8000}, {0xbd3fa000}, {0xbd3fc000}, {0xbd3fe000}, + {0xbd400000}, {0xbd402000}, {0xbd404000}, {0xbd406000}, + {0xbd408000}, {0xbd40a000}, {0xbd40c000}, {0xbd40e000}, + {0xbd410000}, {0xbd412000}, {0xbd414000}, {0xbd416000}, + {0xbd418000}, {0xbd41a000}, {0xbd41c000}, {0xbd41e000}, + {0xbd420000}, {0xbd422000}, {0xbd424000}, {0xbd426000}, + {0xbd428000}, {0xbd42a000}, {0xbd42c000}, {0xbd42e000}, + {0xbd430000}, {0xbd432000}, {0xbd434000}, {0xbd436000}, + {0xbd438000}, {0xbd43a000}, {0xbd43c000}, {0xbd43e000}, + {0xbd440000}, {0xbd442000}, {0xbd444000}, {0xbd446000}, + {0xbd448000}, {0xbd44a000}, {0xbd44c000}, {0xbd44e000}, + {0xbd450000}, {0xbd452000}, {0xbd454000}, {0xbd456000}, + {0xbd458000}, {0xbd45a000}, {0xbd45c000}, {0xbd45e000}, + {0xbd460000}, {0xbd462000}, {0xbd464000}, {0xbd466000}, + {0xbd468000}, {0xbd46a000}, {0xbd46c000}, {0xbd46e000}, + {0xbd470000}, {0xbd472000}, {0xbd474000}, {0xbd476000}, + {0xbd478000}, {0xbd47a000}, {0xbd47c000}, {0xbd47e000}, + {0xbd480000}, {0xbd482000}, {0xbd484000}, {0xbd486000}, + {0xbd488000}, {0xbd48a000}, {0xbd48c000}, {0xbd48e000}, + {0xbd490000}, {0xbd492000}, {0xbd494000}, {0xbd496000}, + {0xbd498000}, {0xbd49a000}, {0xbd49c000}, {0xbd49e000}, + {0xbd4a0000}, {0xbd4a2000}, {0xbd4a4000}, {0xbd4a6000}, + {0xbd4a8000}, {0xbd4aa000}, {0xbd4ac000}, {0xbd4ae000}, + {0xbd4b0000}, {0xbd4b2000}, {0xbd4b4000}, {0xbd4b6000}, + {0xbd4b8000}, {0xbd4ba000}, {0xbd4bc000}, {0xbd4be000}, + {0xbd4c0000}, {0xbd4c2000}, {0xbd4c4000}, {0xbd4c6000}, + {0xbd4c8000}, {0xbd4ca000}, {0xbd4cc000}, {0xbd4ce000}, + {0xbd4d0000}, {0xbd4d2000}, {0xbd4d4000}, {0xbd4d6000}, + {0xbd4d8000}, {0xbd4da000}, {0xbd4dc000}, {0xbd4de000}, + {0xbd4e0000}, {0xbd4e2000}, {0xbd4e4000}, {0xbd4e6000}, + {0xbd4e8000}, {0xbd4ea000}, {0xbd4ec000}, {0xbd4ee000}, + {0xbd4f0000}, {0xbd4f2000}, {0xbd4f4000}, {0xbd4f6000}, + {0xbd4f8000}, {0xbd4fa000}, {0xbd4fc000}, {0xbd4fe000}, + {0xbd500000}, {0xbd502000}, {0xbd504000}, {0xbd506000}, + {0xbd508000}, {0xbd50a000}, {0xbd50c000}, {0xbd50e000}, + {0xbd510000}, {0xbd512000}, {0xbd514000}, {0xbd516000}, + {0xbd518000}, {0xbd51a000}, {0xbd51c000}, {0xbd51e000}, + {0xbd520000}, {0xbd522000}, {0xbd524000}, {0xbd526000}, + {0xbd528000}, {0xbd52a000}, {0xbd52c000}, {0xbd52e000}, + {0xbd530000}, {0xbd532000}, {0xbd534000}, {0xbd536000}, + {0xbd538000}, {0xbd53a000}, {0xbd53c000}, {0xbd53e000}, + {0xbd540000}, {0xbd542000}, {0xbd544000}, {0xbd546000}, + {0xbd548000}, {0xbd54a000}, {0xbd54c000}, {0xbd54e000}, + {0xbd550000}, {0xbd552000}, {0xbd554000}, {0xbd556000}, + {0xbd558000}, {0xbd55a000}, {0xbd55c000}, {0xbd55e000}, + {0xbd560000}, {0xbd562000}, {0xbd564000}, {0xbd566000}, + {0xbd568000}, {0xbd56a000}, {0xbd56c000}, {0xbd56e000}, + {0xbd570000}, {0xbd572000}, {0xbd574000}, {0xbd576000}, + {0xbd578000}, {0xbd57a000}, {0xbd57c000}, {0xbd57e000}, + {0xbd580000}, {0xbd582000}, {0xbd584000}, {0xbd586000}, + {0xbd588000}, {0xbd58a000}, {0xbd58c000}, {0xbd58e000}, + {0xbd590000}, {0xbd592000}, {0xbd594000}, {0xbd596000}, + {0xbd598000}, {0xbd59a000}, {0xbd59c000}, {0xbd59e000}, + {0xbd5a0000}, {0xbd5a2000}, {0xbd5a4000}, {0xbd5a6000}, + {0xbd5a8000}, {0xbd5aa000}, {0xbd5ac000}, {0xbd5ae000}, + {0xbd5b0000}, {0xbd5b2000}, {0xbd5b4000}, {0xbd5b6000}, + {0xbd5b8000}, {0xbd5ba000}, {0xbd5bc000}, {0xbd5be000}, + {0xbd5c0000}, {0xbd5c2000}, {0xbd5c4000}, {0xbd5c6000}, + {0xbd5c8000}, {0xbd5ca000}, {0xbd5cc000}, {0xbd5ce000}, + {0xbd5d0000}, {0xbd5d2000}, {0xbd5d4000}, {0xbd5d6000}, + {0xbd5d8000}, {0xbd5da000}, {0xbd5dc000}, {0xbd5de000}, + {0xbd5e0000}, {0xbd5e2000}, {0xbd5e4000}, {0xbd5e6000}, + {0xbd5e8000}, {0xbd5ea000}, {0xbd5ec000}, {0xbd5ee000}, + {0xbd5f0000}, {0xbd5f2000}, {0xbd5f4000}, {0xbd5f6000}, + {0xbd5f8000}, {0xbd5fa000}, {0xbd5fc000}, {0xbd5fe000}, + {0xbd600000}, {0xbd602000}, {0xbd604000}, {0xbd606000}, + {0xbd608000}, {0xbd60a000}, {0xbd60c000}, {0xbd60e000}, + {0xbd610000}, {0xbd612000}, {0xbd614000}, {0xbd616000}, + {0xbd618000}, {0xbd61a000}, {0xbd61c000}, {0xbd61e000}, + {0xbd620000}, {0xbd622000}, {0xbd624000}, {0xbd626000}, + {0xbd628000}, {0xbd62a000}, {0xbd62c000}, {0xbd62e000}, + {0xbd630000}, {0xbd632000}, {0xbd634000}, {0xbd636000}, + {0xbd638000}, {0xbd63a000}, {0xbd63c000}, {0xbd63e000}, + {0xbd640000}, {0xbd642000}, {0xbd644000}, {0xbd646000}, + {0xbd648000}, {0xbd64a000}, {0xbd64c000}, {0xbd64e000}, + {0xbd650000}, {0xbd652000}, {0xbd654000}, {0xbd656000}, + {0xbd658000}, {0xbd65a000}, {0xbd65c000}, {0xbd65e000}, + {0xbd660000}, {0xbd662000}, {0xbd664000}, {0xbd666000}, + {0xbd668000}, {0xbd66a000}, {0xbd66c000}, {0xbd66e000}, + {0xbd670000}, {0xbd672000}, {0xbd674000}, {0xbd676000}, + {0xbd678000}, {0xbd67a000}, {0xbd67c000}, {0xbd67e000}, + {0xbd680000}, {0xbd682000}, {0xbd684000}, {0xbd686000}, + {0xbd688000}, {0xbd68a000}, {0xbd68c000}, {0xbd68e000}, + {0xbd690000}, {0xbd692000}, {0xbd694000}, {0xbd696000}, + {0xbd698000}, {0xbd69a000}, {0xbd69c000}, {0xbd69e000}, + {0xbd6a0000}, {0xbd6a2000}, {0xbd6a4000}, {0xbd6a6000}, + {0xbd6a8000}, {0xbd6aa000}, {0xbd6ac000}, {0xbd6ae000}, + {0xbd6b0000}, {0xbd6b2000}, {0xbd6b4000}, {0xbd6b6000}, + {0xbd6b8000}, {0xbd6ba000}, {0xbd6bc000}, {0xbd6be000}, + {0xbd6c0000}, {0xbd6c2000}, {0xbd6c4000}, {0xbd6c6000}, + {0xbd6c8000}, {0xbd6ca000}, {0xbd6cc000}, {0xbd6ce000}, + {0xbd6d0000}, {0xbd6d2000}, {0xbd6d4000}, {0xbd6d6000}, + {0xbd6d8000}, {0xbd6da000}, {0xbd6dc000}, {0xbd6de000}, + {0xbd6e0000}, {0xbd6e2000}, {0xbd6e4000}, {0xbd6e6000}, + {0xbd6e8000}, {0xbd6ea000}, {0xbd6ec000}, {0xbd6ee000}, + {0xbd6f0000}, {0xbd6f2000}, {0xbd6f4000}, {0xbd6f6000}, + {0xbd6f8000}, {0xbd6fa000}, {0xbd6fc000}, {0xbd6fe000}, + {0xbd700000}, {0xbd702000}, {0xbd704000}, {0xbd706000}, + {0xbd708000}, {0xbd70a000}, {0xbd70c000}, {0xbd70e000}, + {0xbd710000}, {0xbd712000}, {0xbd714000}, {0xbd716000}, + {0xbd718000}, {0xbd71a000}, {0xbd71c000}, {0xbd71e000}, + {0xbd720000}, {0xbd722000}, {0xbd724000}, {0xbd726000}, + {0xbd728000}, {0xbd72a000}, {0xbd72c000}, {0xbd72e000}, + {0xbd730000}, {0xbd732000}, {0xbd734000}, {0xbd736000}, + {0xbd738000}, {0xbd73a000}, {0xbd73c000}, {0xbd73e000}, + {0xbd740000}, {0xbd742000}, {0xbd744000}, {0xbd746000}, + {0xbd748000}, {0xbd74a000}, {0xbd74c000}, {0xbd74e000}, + {0xbd750000}, {0xbd752000}, {0xbd754000}, {0xbd756000}, + {0xbd758000}, {0xbd75a000}, {0xbd75c000}, {0xbd75e000}, + {0xbd760000}, {0xbd762000}, {0xbd764000}, {0xbd766000}, + {0xbd768000}, {0xbd76a000}, {0xbd76c000}, {0xbd76e000}, + {0xbd770000}, {0xbd772000}, {0xbd774000}, {0xbd776000}, + {0xbd778000}, {0xbd77a000}, {0xbd77c000}, {0xbd77e000}, + {0xbd780000}, {0xbd782000}, {0xbd784000}, {0xbd786000}, + {0xbd788000}, {0xbd78a000}, {0xbd78c000}, {0xbd78e000}, + {0xbd790000}, {0xbd792000}, {0xbd794000}, {0xbd796000}, + {0xbd798000}, {0xbd79a000}, {0xbd79c000}, {0xbd79e000}, + {0xbd7a0000}, {0xbd7a2000}, {0xbd7a4000}, {0xbd7a6000}, + {0xbd7a8000}, {0xbd7aa000}, {0xbd7ac000}, {0xbd7ae000}, + {0xbd7b0000}, {0xbd7b2000}, {0xbd7b4000}, {0xbd7b6000}, + {0xbd7b8000}, {0xbd7ba000}, {0xbd7bc000}, {0xbd7be000}, + {0xbd7c0000}, {0xbd7c2000}, {0xbd7c4000}, {0xbd7c6000}, + {0xbd7c8000}, {0xbd7ca000}, {0xbd7cc000}, {0xbd7ce000}, + {0xbd7d0000}, {0xbd7d2000}, {0xbd7d4000}, {0xbd7d6000}, + {0xbd7d8000}, {0xbd7da000}, {0xbd7dc000}, {0xbd7de000}, + {0xbd7e0000}, {0xbd7e2000}, {0xbd7e4000}, {0xbd7e6000}, + {0xbd7e8000}, {0xbd7ea000}, {0xbd7ec000}, {0xbd7ee000}, + {0xbd7f0000}, {0xbd7f2000}, {0xbd7f4000}, {0xbd7f6000}, + {0xbd7f8000}, {0xbd7fa000}, {0xbd7fc000}, {0xbd7fe000}, + {0xbd800000}, {0xbd802000}, {0xbd804000}, {0xbd806000}, + {0xbd808000}, {0xbd80a000}, {0xbd80c000}, {0xbd80e000}, + {0xbd810000}, {0xbd812000}, {0xbd814000}, {0xbd816000}, + {0xbd818000}, {0xbd81a000}, {0xbd81c000}, {0xbd81e000}, + {0xbd820000}, {0xbd822000}, {0xbd824000}, {0xbd826000}, + {0xbd828000}, {0xbd82a000}, {0xbd82c000}, {0xbd82e000}, + {0xbd830000}, {0xbd832000}, {0xbd834000}, {0xbd836000}, + {0xbd838000}, {0xbd83a000}, {0xbd83c000}, {0xbd83e000}, + {0xbd840000}, {0xbd842000}, {0xbd844000}, {0xbd846000}, + {0xbd848000}, {0xbd84a000}, {0xbd84c000}, {0xbd84e000}, + {0xbd850000}, {0xbd852000}, {0xbd854000}, {0xbd856000}, + {0xbd858000}, {0xbd85a000}, {0xbd85c000}, {0xbd85e000}, + {0xbd860000}, {0xbd862000}, {0xbd864000}, {0xbd866000}, + {0xbd868000}, {0xbd86a000}, {0xbd86c000}, {0xbd86e000}, + {0xbd870000}, {0xbd872000}, {0xbd874000}, {0xbd876000}, + {0xbd878000}, {0xbd87a000}, {0xbd87c000}, {0xbd87e000}, + {0xbd880000}, {0xbd882000}, {0xbd884000}, {0xbd886000}, + {0xbd888000}, {0xbd88a000}, {0xbd88c000}, {0xbd88e000}, + {0xbd890000}, {0xbd892000}, {0xbd894000}, {0xbd896000}, + {0xbd898000}, {0xbd89a000}, {0xbd89c000}, {0xbd89e000}, + {0xbd8a0000}, {0xbd8a2000}, {0xbd8a4000}, {0xbd8a6000}, + {0xbd8a8000}, {0xbd8aa000}, {0xbd8ac000}, {0xbd8ae000}, + {0xbd8b0000}, {0xbd8b2000}, {0xbd8b4000}, {0xbd8b6000}, + {0xbd8b8000}, {0xbd8ba000}, {0xbd8bc000}, {0xbd8be000}, + {0xbd8c0000}, {0xbd8c2000}, {0xbd8c4000}, {0xbd8c6000}, + {0xbd8c8000}, {0xbd8ca000}, {0xbd8cc000}, {0xbd8ce000}, + {0xbd8d0000}, {0xbd8d2000}, {0xbd8d4000}, {0xbd8d6000}, + {0xbd8d8000}, {0xbd8da000}, {0xbd8dc000}, {0xbd8de000}, + {0xbd8e0000}, {0xbd8e2000}, {0xbd8e4000}, {0xbd8e6000}, + {0xbd8e8000}, {0xbd8ea000}, {0xbd8ec000}, {0xbd8ee000}, + {0xbd8f0000}, {0xbd8f2000}, {0xbd8f4000}, {0xbd8f6000}, + {0xbd8f8000}, {0xbd8fa000}, {0xbd8fc000}, {0xbd8fe000}, + {0xbd900000}, {0xbd902000}, {0xbd904000}, {0xbd906000}, + {0xbd908000}, {0xbd90a000}, {0xbd90c000}, {0xbd90e000}, + {0xbd910000}, {0xbd912000}, {0xbd914000}, {0xbd916000}, + {0xbd918000}, {0xbd91a000}, {0xbd91c000}, {0xbd91e000}, + {0xbd920000}, {0xbd922000}, {0xbd924000}, {0xbd926000}, + {0xbd928000}, {0xbd92a000}, {0xbd92c000}, {0xbd92e000}, + {0xbd930000}, {0xbd932000}, {0xbd934000}, {0xbd936000}, + {0xbd938000}, {0xbd93a000}, {0xbd93c000}, {0xbd93e000}, + {0xbd940000}, {0xbd942000}, {0xbd944000}, {0xbd946000}, + {0xbd948000}, {0xbd94a000}, {0xbd94c000}, {0xbd94e000}, + {0xbd950000}, {0xbd952000}, {0xbd954000}, {0xbd956000}, + {0xbd958000}, {0xbd95a000}, {0xbd95c000}, {0xbd95e000}, + {0xbd960000}, {0xbd962000}, {0xbd964000}, {0xbd966000}, + {0xbd968000}, {0xbd96a000}, {0xbd96c000}, {0xbd96e000}, + {0xbd970000}, {0xbd972000}, {0xbd974000}, {0xbd976000}, + {0xbd978000}, {0xbd97a000}, {0xbd97c000}, {0xbd97e000}, + {0xbd980000}, {0xbd982000}, {0xbd984000}, {0xbd986000}, + {0xbd988000}, {0xbd98a000}, {0xbd98c000}, {0xbd98e000}, + {0xbd990000}, {0xbd992000}, {0xbd994000}, {0xbd996000}, + {0xbd998000}, {0xbd99a000}, {0xbd99c000}, {0xbd99e000}, + {0xbd9a0000}, {0xbd9a2000}, {0xbd9a4000}, {0xbd9a6000}, + {0xbd9a8000}, {0xbd9aa000}, {0xbd9ac000}, {0xbd9ae000}, + {0xbd9b0000}, {0xbd9b2000}, {0xbd9b4000}, {0xbd9b6000}, + {0xbd9b8000}, {0xbd9ba000}, {0xbd9bc000}, {0xbd9be000}, + {0xbd9c0000}, {0xbd9c2000}, {0xbd9c4000}, {0xbd9c6000}, + {0xbd9c8000}, {0xbd9ca000}, {0xbd9cc000}, {0xbd9ce000}, + {0xbd9d0000}, {0xbd9d2000}, {0xbd9d4000}, {0xbd9d6000}, + {0xbd9d8000}, {0xbd9da000}, {0xbd9dc000}, {0xbd9de000}, + {0xbd9e0000}, {0xbd9e2000}, {0xbd9e4000}, {0xbd9e6000}, + {0xbd9e8000}, {0xbd9ea000}, {0xbd9ec000}, {0xbd9ee000}, + {0xbd9f0000}, {0xbd9f2000}, {0xbd9f4000}, {0xbd9f6000}, + {0xbd9f8000}, {0xbd9fa000}, {0xbd9fc000}, {0xbd9fe000}, + {0xbda00000}, {0xbda02000}, {0xbda04000}, {0xbda06000}, + {0xbda08000}, {0xbda0a000}, {0xbda0c000}, {0xbda0e000}, + {0xbda10000}, {0xbda12000}, {0xbda14000}, {0xbda16000}, + {0xbda18000}, {0xbda1a000}, {0xbda1c000}, {0xbda1e000}, + {0xbda20000}, {0xbda22000}, {0xbda24000}, {0xbda26000}, + {0xbda28000}, {0xbda2a000}, {0xbda2c000}, {0xbda2e000}, + {0xbda30000}, {0xbda32000}, {0xbda34000}, {0xbda36000}, + {0xbda38000}, {0xbda3a000}, {0xbda3c000}, {0xbda3e000}, + {0xbda40000}, {0xbda42000}, {0xbda44000}, {0xbda46000}, + {0xbda48000}, {0xbda4a000}, {0xbda4c000}, {0xbda4e000}, + {0xbda50000}, {0xbda52000}, {0xbda54000}, {0xbda56000}, + {0xbda58000}, {0xbda5a000}, {0xbda5c000}, {0xbda5e000}, + {0xbda60000}, {0xbda62000}, {0xbda64000}, {0xbda66000}, + {0xbda68000}, {0xbda6a000}, {0xbda6c000}, {0xbda6e000}, + {0xbda70000}, {0xbda72000}, {0xbda74000}, {0xbda76000}, + {0xbda78000}, {0xbda7a000}, {0xbda7c000}, {0xbda7e000}, + {0xbda80000}, {0xbda82000}, {0xbda84000}, {0xbda86000}, + {0xbda88000}, {0xbda8a000}, {0xbda8c000}, {0xbda8e000}, + {0xbda90000}, {0xbda92000}, {0xbda94000}, {0xbda96000}, + {0xbda98000}, {0xbda9a000}, {0xbda9c000}, {0xbda9e000}, + {0xbdaa0000}, {0xbdaa2000}, {0xbdaa4000}, {0xbdaa6000}, + {0xbdaa8000}, {0xbdaaa000}, {0xbdaac000}, {0xbdaae000}, + {0xbdab0000}, {0xbdab2000}, {0xbdab4000}, {0xbdab6000}, + {0xbdab8000}, {0xbdaba000}, {0xbdabc000}, {0xbdabe000}, + {0xbdac0000}, {0xbdac2000}, {0xbdac4000}, {0xbdac6000}, + {0xbdac8000}, {0xbdaca000}, {0xbdacc000}, {0xbdace000}, + {0xbdad0000}, {0xbdad2000}, {0xbdad4000}, {0xbdad6000}, + {0xbdad8000}, {0xbdada000}, {0xbdadc000}, {0xbdade000}, + {0xbdae0000}, {0xbdae2000}, {0xbdae4000}, {0xbdae6000}, + {0xbdae8000}, {0xbdaea000}, {0xbdaec000}, {0xbdaee000}, + {0xbdaf0000}, {0xbdaf2000}, {0xbdaf4000}, {0xbdaf6000}, + {0xbdaf8000}, {0xbdafa000}, {0xbdafc000}, {0xbdafe000}, + {0xbdb00000}, {0xbdb02000}, {0xbdb04000}, {0xbdb06000}, + {0xbdb08000}, {0xbdb0a000}, {0xbdb0c000}, {0xbdb0e000}, + {0xbdb10000}, {0xbdb12000}, {0xbdb14000}, {0xbdb16000}, + {0xbdb18000}, {0xbdb1a000}, {0xbdb1c000}, {0xbdb1e000}, + {0xbdb20000}, {0xbdb22000}, {0xbdb24000}, {0xbdb26000}, + {0xbdb28000}, {0xbdb2a000}, {0xbdb2c000}, {0xbdb2e000}, + {0xbdb30000}, {0xbdb32000}, {0xbdb34000}, {0xbdb36000}, + {0xbdb38000}, {0xbdb3a000}, {0xbdb3c000}, {0xbdb3e000}, + {0xbdb40000}, {0xbdb42000}, {0xbdb44000}, {0xbdb46000}, + {0xbdb48000}, {0xbdb4a000}, {0xbdb4c000}, {0xbdb4e000}, + {0xbdb50000}, {0xbdb52000}, {0xbdb54000}, {0xbdb56000}, + {0xbdb58000}, {0xbdb5a000}, {0xbdb5c000}, {0xbdb5e000}, + {0xbdb60000}, {0xbdb62000}, {0xbdb64000}, {0xbdb66000}, + {0xbdb68000}, {0xbdb6a000}, {0xbdb6c000}, {0xbdb6e000}, + {0xbdb70000}, {0xbdb72000}, {0xbdb74000}, {0xbdb76000}, + {0xbdb78000}, {0xbdb7a000}, {0xbdb7c000}, {0xbdb7e000}, + {0xbdb80000}, {0xbdb82000}, {0xbdb84000}, {0xbdb86000}, + {0xbdb88000}, {0xbdb8a000}, {0xbdb8c000}, {0xbdb8e000}, + {0xbdb90000}, {0xbdb92000}, {0xbdb94000}, {0xbdb96000}, + {0xbdb98000}, {0xbdb9a000}, {0xbdb9c000}, {0xbdb9e000}, + {0xbdba0000}, {0xbdba2000}, {0xbdba4000}, {0xbdba6000}, + {0xbdba8000}, {0xbdbaa000}, {0xbdbac000}, {0xbdbae000}, + {0xbdbb0000}, {0xbdbb2000}, {0xbdbb4000}, {0xbdbb6000}, + {0xbdbb8000}, {0xbdbba000}, {0xbdbbc000}, {0xbdbbe000}, + {0xbdbc0000}, {0xbdbc2000}, {0xbdbc4000}, {0xbdbc6000}, + {0xbdbc8000}, {0xbdbca000}, {0xbdbcc000}, {0xbdbce000}, + {0xbdbd0000}, {0xbdbd2000}, {0xbdbd4000}, {0xbdbd6000}, + {0xbdbd8000}, {0xbdbda000}, {0xbdbdc000}, {0xbdbde000}, + {0xbdbe0000}, {0xbdbe2000}, {0xbdbe4000}, {0xbdbe6000}, + {0xbdbe8000}, {0xbdbea000}, {0xbdbec000}, {0xbdbee000}, + {0xbdbf0000}, {0xbdbf2000}, {0xbdbf4000}, {0xbdbf6000}, + {0xbdbf8000}, {0xbdbfa000}, {0xbdbfc000}, {0xbdbfe000}, + {0xbdc00000}, {0xbdc02000}, {0xbdc04000}, {0xbdc06000}, + {0xbdc08000}, {0xbdc0a000}, {0xbdc0c000}, {0xbdc0e000}, + {0xbdc10000}, {0xbdc12000}, {0xbdc14000}, {0xbdc16000}, + {0xbdc18000}, {0xbdc1a000}, {0xbdc1c000}, {0xbdc1e000}, + {0xbdc20000}, {0xbdc22000}, {0xbdc24000}, {0xbdc26000}, + {0xbdc28000}, {0xbdc2a000}, {0xbdc2c000}, {0xbdc2e000}, + {0xbdc30000}, {0xbdc32000}, {0xbdc34000}, {0xbdc36000}, + {0xbdc38000}, {0xbdc3a000}, {0xbdc3c000}, {0xbdc3e000}, + {0xbdc40000}, {0xbdc42000}, {0xbdc44000}, {0xbdc46000}, + {0xbdc48000}, {0xbdc4a000}, {0xbdc4c000}, {0xbdc4e000}, + {0xbdc50000}, {0xbdc52000}, {0xbdc54000}, {0xbdc56000}, + {0xbdc58000}, {0xbdc5a000}, {0xbdc5c000}, {0xbdc5e000}, + {0xbdc60000}, {0xbdc62000}, {0xbdc64000}, {0xbdc66000}, + {0xbdc68000}, {0xbdc6a000}, {0xbdc6c000}, {0xbdc6e000}, + {0xbdc70000}, {0xbdc72000}, {0xbdc74000}, {0xbdc76000}, + {0xbdc78000}, {0xbdc7a000}, {0xbdc7c000}, {0xbdc7e000}, + {0xbdc80000}, {0xbdc82000}, {0xbdc84000}, {0xbdc86000}, + {0xbdc88000}, {0xbdc8a000}, {0xbdc8c000}, {0xbdc8e000}, + {0xbdc90000}, {0xbdc92000}, {0xbdc94000}, {0xbdc96000}, + {0xbdc98000}, {0xbdc9a000}, {0xbdc9c000}, {0xbdc9e000}, + {0xbdca0000}, {0xbdca2000}, {0xbdca4000}, {0xbdca6000}, + {0xbdca8000}, {0xbdcaa000}, {0xbdcac000}, {0xbdcae000}, + {0xbdcb0000}, {0xbdcb2000}, {0xbdcb4000}, {0xbdcb6000}, + {0xbdcb8000}, {0xbdcba000}, {0xbdcbc000}, {0xbdcbe000}, + {0xbdcc0000}, {0xbdcc2000}, {0xbdcc4000}, {0xbdcc6000}, + {0xbdcc8000}, {0xbdcca000}, {0xbdccc000}, {0xbdcce000}, + {0xbdcd0000}, {0xbdcd2000}, {0xbdcd4000}, {0xbdcd6000}, + {0xbdcd8000}, {0xbdcda000}, {0xbdcdc000}, {0xbdcde000}, + {0xbdce0000}, {0xbdce2000}, {0xbdce4000}, {0xbdce6000}, + {0xbdce8000}, {0xbdcea000}, {0xbdcec000}, {0xbdcee000}, + {0xbdcf0000}, {0xbdcf2000}, {0xbdcf4000}, {0xbdcf6000}, + {0xbdcf8000}, {0xbdcfa000}, {0xbdcfc000}, {0xbdcfe000}, + {0xbdd00000}, {0xbdd02000}, {0xbdd04000}, {0xbdd06000}, + {0xbdd08000}, {0xbdd0a000}, {0xbdd0c000}, {0xbdd0e000}, + {0xbdd10000}, {0xbdd12000}, {0xbdd14000}, {0xbdd16000}, + {0xbdd18000}, {0xbdd1a000}, {0xbdd1c000}, {0xbdd1e000}, + {0xbdd20000}, {0xbdd22000}, {0xbdd24000}, {0xbdd26000}, + {0xbdd28000}, {0xbdd2a000}, {0xbdd2c000}, {0xbdd2e000}, + {0xbdd30000}, {0xbdd32000}, {0xbdd34000}, {0xbdd36000}, + {0xbdd38000}, {0xbdd3a000}, {0xbdd3c000}, {0xbdd3e000}, + {0xbdd40000}, {0xbdd42000}, {0xbdd44000}, {0xbdd46000}, + {0xbdd48000}, {0xbdd4a000}, {0xbdd4c000}, {0xbdd4e000}, + {0xbdd50000}, {0xbdd52000}, {0xbdd54000}, {0xbdd56000}, + {0xbdd58000}, {0xbdd5a000}, {0xbdd5c000}, {0xbdd5e000}, + {0xbdd60000}, {0xbdd62000}, {0xbdd64000}, {0xbdd66000}, + {0xbdd68000}, {0xbdd6a000}, {0xbdd6c000}, {0xbdd6e000}, + {0xbdd70000}, {0xbdd72000}, {0xbdd74000}, {0xbdd76000}, + {0xbdd78000}, {0xbdd7a000}, {0xbdd7c000}, {0xbdd7e000}, + {0xbdd80000}, {0xbdd82000}, {0xbdd84000}, {0xbdd86000}, + {0xbdd88000}, {0xbdd8a000}, {0xbdd8c000}, {0xbdd8e000}, + {0xbdd90000}, {0xbdd92000}, {0xbdd94000}, {0xbdd96000}, + {0xbdd98000}, {0xbdd9a000}, {0xbdd9c000}, {0xbdd9e000}, + {0xbdda0000}, {0xbdda2000}, {0xbdda4000}, {0xbdda6000}, + {0xbdda8000}, {0xbddaa000}, {0xbddac000}, {0xbddae000}, + {0xbddb0000}, {0xbddb2000}, {0xbddb4000}, {0xbddb6000}, + {0xbddb8000}, {0xbddba000}, {0xbddbc000}, {0xbddbe000}, + {0xbddc0000}, {0xbddc2000}, {0xbddc4000}, {0xbddc6000}, + {0xbddc8000}, {0xbddca000}, {0xbddcc000}, {0xbddce000}, + {0xbddd0000}, {0xbddd2000}, {0xbddd4000}, {0xbddd6000}, + {0xbddd8000}, {0xbddda000}, {0xbdddc000}, {0xbddde000}, + {0xbdde0000}, {0xbdde2000}, {0xbdde4000}, {0xbdde6000}, + {0xbdde8000}, {0xbddea000}, {0xbddec000}, {0xbddee000}, + {0xbddf0000}, {0xbddf2000}, {0xbddf4000}, {0xbddf6000}, + {0xbddf8000}, {0xbddfa000}, {0xbddfc000}, {0xbddfe000}, + {0xbde00000}, {0xbde02000}, {0xbde04000}, {0xbde06000}, + {0xbde08000}, {0xbde0a000}, {0xbde0c000}, {0xbde0e000}, + {0xbde10000}, {0xbde12000}, {0xbde14000}, {0xbde16000}, + {0xbde18000}, {0xbde1a000}, {0xbde1c000}, {0xbde1e000}, + {0xbde20000}, {0xbde22000}, {0xbde24000}, {0xbde26000}, + {0xbde28000}, {0xbde2a000}, {0xbde2c000}, {0xbde2e000}, + {0xbde30000}, {0xbde32000}, {0xbde34000}, {0xbde36000}, + {0xbde38000}, {0xbde3a000}, {0xbde3c000}, {0xbde3e000}, + {0xbde40000}, {0xbde42000}, {0xbde44000}, {0xbde46000}, + {0xbde48000}, {0xbde4a000}, {0xbde4c000}, {0xbde4e000}, + {0xbde50000}, {0xbde52000}, {0xbde54000}, {0xbde56000}, + {0xbde58000}, {0xbde5a000}, {0xbde5c000}, {0xbde5e000}, + {0xbde60000}, {0xbde62000}, {0xbde64000}, {0xbde66000}, + {0xbde68000}, {0xbde6a000}, {0xbde6c000}, {0xbde6e000}, + {0xbde70000}, {0xbde72000}, {0xbde74000}, {0xbde76000}, + {0xbde78000}, {0xbde7a000}, {0xbde7c000}, {0xbde7e000}, + {0xbde80000}, {0xbde82000}, {0xbde84000}, {0xbde86000}, + {0xbde88000}, {0xbde8a000}, {0xbde8c000}, {0xbde8e000}, + {0xbde90000}, {0xbde92000}, {0xbde94000}, {0xbde96000}, + {0xbde98000}, {0xbde9a000}, {0xbde9c000}, {0xbde9e000}, + {0xbdea0000}, {0xbdea2000}, {0xbdea4000}, {0xbdea6000}, + {0xbdea8000}, {0xbdeaa000}, {0xbdeac000}, {0xbdeae000}, + {0xbdeb0000}, {0xbdeb2000}, {0xbdeb4000}, {0xbdeb6000}, + {0xbdeb8000}, {0xbdeba000}, {0xbdebc000}, {0xbdebe000}, + {0xbdec0000}, {0xbdec2000}, {0xbdec4000}, {0xbdec6000}, + {0xbdec8000}, {0xbdeca000}, {0xbdecc000}, {0xbdece000}, + {0xbded0000}, {0xbded2000}, {0xbded4000}, {0xbded6000}, + {0xbded8000}, {0xbdeda000}, {0xbdedc000}, {0xbdede000}, + {0xbdee0000}, {0xbdee2000}, {0xbdee4000}, {0xbdee6000}, + {0xbdee8000}, {0xbdeea000}, {0xbdeec000}, {0xbdeee000}, + {0xbdef0000}, {0xbdef2000}, {0xbdef4000}, {0xbdef6000}, + {0xbdef8000}, {0xbdefa000}, {0xbdefc000}, {0xbdefe000}, + {0xbdf00000}, {0xbdf02000}, {0xbdf04000}, {0xbdf06000}, + {0xbdf08000}, {0xbdf0a000}, {0xbdf0c000}, {0xbdf0e000}, + {0xbdf10000}, {0xbdf12000}, {0xbdf14000}, {0xbdf16000}, + {0xbdf18000}, {0xbdf1a000}, {0xbdf1c000}, {0xbdf1e000}, + {0xbdf20000}, {0xbdf22000}, {0xbdf24000}, {0xbdf26000}, + {0xbdf28000}, {0xbdf2a000}, {0xbdf2c000}, {0xbdf2e000}, + {0xbdf30000}, {0xbdf32000}, {0xbdf34000}, {0xbdf36000}, + {0xbdf38000}, {0xbdf3a000}, {0xbdf3c000}, {0xbdf3e000}, + {0xbdf40000}, {0xbdf42000}, {0xbdf44000}, {0xbdf46000}, + {0xbdf48000}, {0xbdf4a000}, {0xbdf4c000}, {0xbdf4e000}, + {0xbdf50000}, {0xbdf52000}, {0xbdf54000}, {0xbdf56000}, + {0xbdf58000}, {0xbdf5a000}, {0xbdf5c000}, {0xbdf5e000}, + {0xbdf60000}, {0xbdf62000}, {0xbdf64000}, {0xbdf66000}, + {0xbdf68000}, {0xbdf6a000}, {0xbdf6c000}, {0xbdf6e000}, + {0xbdf70000}, {0xbdf72000}, {0xbdf74000}, {0xbdf76000}, + {0xbdf78000}, {0xbdf7a000}, {0xbdf7c000}, {0xbdf7e000}, + {0xbdf80000}, {0xbdf82000}, {0xbdf84000}, {0xbdf86000}, + {0xbdf88000}, {0xbdf8a000}, {0xbdf8c000}, {0xbdf8e000}, + {0xbdf90000}, {0xbdf92000}, {0xbdf94000}, {0xbdf96000}, + {0xbdf98000}, {0xbdf9a000}, {0xbdf9c000}, {0xbdf9e000}, + {0xbdfa0000}, {0xbdfa2000}, {0xbdfa4000}, {0xbdfa6000}, + {0xbdfa8000}, {0xbdfaa000}, {0xbdfac000}, {0xbdfae000}, + {0xbdfb0000}, {0xbdfb2000}, {0xbdfb4000}, {0xbdfb6000}, + {0xbdfb8000}, {0xbdfba000}, {0xbdfbc000}, {0xbdfbe000}, + {0xbdfc0000}, {0xbdfc2000}, {0xbdfc4000}, {0xbdfc6000}, + {0xbdfc8000}, {0xbdfca000}, {0xbdfcc000}, {0xbdfce000}, + {0xbdfd0000}, {0xbdfd2000}, {0xbdfd4000}, {0xbdfd6000}, + {0xbdfd8000}, {0xbdfda000}, {0xbdfdc000}, {0xbdfde000}, + {0xbdfe0000}, {0xbdfe2000}, {0xbdfe4000}, {0xbdfe6000}, + {0xbdfe8000}, {0xbdfea000}, {0xbdfec000}, {0xbdfee000}, + {0xbdff0000}, {0xbdff2000}, {0xbdff4000}, {0xbdff6000}, + {0xbdff8000}, {0xbdffa000}, {0xbdffc000}, {0xbdffe000}, + {0xbe000000}, {0xbe002000}, {0xbe004000}, {0xbe006000}, + {0xbe008000}, {0xbe00a000}, {0xbe00c000}, {0xbe00e000}, + {0xbe010000}, {0xbe012000}, {0xbe014000}, {0xbe016000}, + {0xbe018000}, {0xbe01a000}, {0xbe01c000}, {0xbe01e000}, + {0xbe020000}, {0xbe022000}, {0xbe024000}, {0xbe026000}, + {0xbe028000}, {0xbe02a000}, {0xbe02c000}, {0xbe02e000}, + {0xbe030000}, {0xbe032000}, {0xbe034000}, {0xbe036000}, + {0xbe038000}, {0xbe03a000}, {0xbe03c000}, {0xbe03e000}, + {0xbe040000}, {0xbe042000}, {0xbe044000}, {0xbe046000}, + {0xbe048000}, {0xbe04a000}, {0xbe04c000}, {0xbe04e000}, + {0xbe050000}, {0xbe052000}, {0xbe054000}, {0xbe056000}, + {0xbe058000}, {0xbe05a000}, {0xbe05c000}, {0xbe05e000}, + {0xbe060000}, {0xbe062000}, {0xbe064000}, {0xbe066000}, + {0xbe068000}, {0xbe06a000}, {0xbe06c000}, {0xbe06e000}, + {0xbe070000}, {0xbe072000}, {0xbe074000}, {0xbe076000}, + {0xbe078000}, {0xbe07a000}, {0xbe07c000}, {0xbe07e000}, + {0xbe080000}, {0xbe082000}, {0xbe084000}, {0xbe086000}, + {0xbe088000}, {0xbe08a000}, {0xbe08c000}, {0xbe08e000}, + {0xbe090000}, {0xbe092000}, {0xbe094000}, {0xbe096000}, + {0xbe098000}, {0xbe09a000}, {0xbe09c000}, {0xbe09e000}, + {0xbe0a0000}, {0xbe0a2000}, {0xbe0a4000}, {0xbe0a6000}, + {0xbe0a8000}, {0xbe0aa000}, {0xbe0ac000}, {0xbe0ae000}, + {0xbe0b0000}, {0xbe0b2000}, {0xbe0b4000}, {0xbe0b6000}, + {0xbe0b8000}, {0xbe0ba000}, {0xbe0bc000}, {0xbe0be000}, + {0xbe0c0000}, {0xbe0c2000}, {0xbe0c4000}, {0xbe0c6000}, + {0xbe0c8000}, {0xbe0ca000}, {0xbe0cc000}, {0xbe0ce000}, + {0xbe0d0000}, {0xbe0d2000}, {0xbe0d4000}, {0xbe0d6000}, + {0xbe0d8000}, {0xbe0da000}, {0xbe0dc000}, {0xbe0de000}, + {0xbe0e0000}, {0xbe0e2000}, {0xbe0e4000}, {0xbe0e6000}, + {0xbe0e8000}, {0xbe0ea000}, {0xbe0ec000}, {0xbe0ee000}, + {0xbe0f0000}, {0xbe0f2000}, {0xbe0f4000}, {0xbe0f6000}, + {0xbe0f8000}, {0xbe0fa000}, {0xbe0fc000}, {0xbe0fe000}, + {0xbe100000}, {0xbe102000}, {0xbe104000}, {0xbe106000}, + {0xbe108000}, {0xbe10a000}, {0xbe10c000}, {0xbe10e000}, + {0xbe110000}, {0xbe112000}, {0xbe114000}, {0xbe116000}, + {0xbe118000}, {0xbe11a000}, {0xbe11c000}, {0xbe11e000}, + {0xbe120000}, {0xbe122000}, {0xbe124000}, {0xbe126000}, + {0xbe128000}, {0xbe12a000}, {0xbe12c000}, {0xbe12e000}, + {0xbe130000}, {0xbe132000}, {0xbe134000}, {0xbe136000}, + {0xbe138000}, {0xbe13a000}, {0xbe13c000}, {0xbe13e000}, + {0xbe140000}, {0xbe142000}, {0xbe144000}, {0xbe146000}, + {0xbe148000}, {0xbe14a000}, {0xbe14c000}, {0xbe14e000}, + {0xbe150000}, {0xbe152000}, {0xbe154000}, {0xbe156000}, + {0xbe158000}, {0xbe15a000}, {0xbe15c000}, {0xbe15e000}, + {0xbe160000}, {0xbe162000}, {0xbe164000}, {0xbe166000}, + {0xbe168000}, {0xbe16a000}, {0xbe16c000}, {0xbe16e000}, + {0xbe170000}, {0xbe172000}, {0xbe174000}, {0xbe176000}, + {0xbe178000}, {0xbe17a000}, {0xbe17c000}, {0xbe17e000}, + {0xbe180000}, {0xbe182000}, {0xbe184000}, {0xbe186000}, + {0xbe188000}, {0xbe18a000}, {0xbe18c000}, {0xbe18e000}, + {0xbe190000}, {0xbe192000}, {0xbe194000}, {0xbe196000}, + {0xbe198000}, {0xbe19a000}, {0xbe19c000}, {0xbe19e000}, + {0xbe1a0000}, {0xbe1a2000}, {0xbe1a4000}, {0xbe1a6000}, + {0xbe1a8000}, {0xbe1aa000}, {0xbe1ac000}, {0xbe1ae000}, + {0xbe1b0000}, {0xbe1b2000}, {0xbe1b4000}, {0xbe1b6000}, + {0xbe1b8000}, {0xbe1ba000}, {0xbe1bc000}, {0xbe1be000}, + {0xbe1c0000}, {0xbe1c2000}, {0xbe1c4000}, {0xbe1c6000}, + {0xbe1c8000}, {0xbe1ca000}, {0xbe1cc000}, {0xbe1ce000}, + {0xbe1d0000}, {0xbe1d2000}, {0xbe1d4000}, {0xbe1d6000}, + {0xbe1d8000}, {0xbe1da000}, {0xbe1dc000}, {0xbe1de000}, + {0xbe1e0000}, {0xbe1e2000}, {0xbe1e4000}, {0xbe1e6000}, + {0xbe1e8000}, {0xbe1ea000}, {0xbe1ec000}, {0xbe1ee000}, + {0xbe1f0000}, {0xbe1f2000}, {0xbe1f4000}, {0xbe1f6000}, + {0xbe1f8000}, {0xbe1fa000}, {0xbe1fc000}, {0xbe1fe000}, + {0xbe200000}, {0xbe202000}, {0xbe204000}, {0xbe206000}, + {0xbe208000}, {0xbe20a000}, {0xbe20c000}, {0xbe20e000}, + {0xbe210000}, {0xbe212000}, {0xbe214000}, {0xbe216000}, + {0xbe218000}, {0xbe21a000}, {0xbe21c000}, {0xbe21e000}, + {0xbe220000}, {0xbe222000}, {0xbe224000}, {0xbe226000}, + {0xbe228000}, {0xbe22a000}, {0xbe22c000}, {0xbe22e000}, + {0xbe230000}, {0xbe232000}, {0xbe234000}, {0xbe236000}, + {0xbe238000}, {0xbe23a000}, {0xbe23c000}, {0xbe23e000}, + {0xbe240000}, {0xbe242000}, {0xbe244000}, {0xbe246000}, + {0xbe248000}, {0xbe24a000}, {0xbe24c000}, {0xbe24e000}, + {0xbe250000}, {0xbe252000}, {0xbe254000}, {0xbe256000}, + {0xbe258000}, {0xbe25a000}, {0xbe25c000}, {0xbe25e000}, + {0xbe260000}, {0xbe262000}, {0xbe264000}, {0xbe266000}, + {0xbe268000}, {0xbe26a000}, {0xbe26c000}, {0xbe26e000}, + {0xbe270000}, {0xbe272000}, {0xbe274000}, {0xbe276000}, + {0xbe278000}, {0xbe27a000}, {0xbe27c000}, {0xbe27e000}, + {0xbe280000}, {0xbe282000}, {0xbe284000}, {0xbe286000}, + {0xbe288000}, {0xbe28a000}, {0xbe28c000}, {0xbe28e000}, + {0xbe290000}, {0xbe292000}, {0xbe294000}, {0xbe296000}, + {0xbe298000}, {0xbe29a000}, {0xbe29c000}, {0xbe29e000}, + {0xbe2a0000}, {0xbe2a2000}, {0xbe2a4000}, {0xbe2a6000}, + {0xbe2a8000}, {0xbe2aa000}, {0xbe2ac000}, {0xbe2ae000}, + {0xbe2b0000}, {0xbe2b2000}, {0xbe2b4000}, {0xbe2b6000}, + {0xbe2b8000}, {0xbe2ba000}, {0xbe2bc000}, {0xbe2be000}, + {0xbe2c0000}, {0xbe2c2000}, {0xbe2c4000}, {0xbe2c6000}, + {0xbe2c8000}, {0xbe2ca000}, {0xbe2cc000}, {0xbe2ce000}, + {0xbe2d0000}, {0xbe2d2000}, {0xbe2d4000}, {0xbe2d6000}, + {0xbe2d8000}, {0xbe2da000}, {0xbe2dc000}, {0xbe2de000}, + {0xbe2e0000}, {0xbe2e2000}, {0xbe2e4000}, {0xbe2e6000}, + {0xbe2e8000}, {0xbe2ea000}, {0xbe2ec000}, {0xbe2ee000}, + {0xbe2f0000}, {0xbe2f2000}, {0xbe2f4000}, {0xbe2f6000}, + {0xbe2f8000}, {0xbe2fa000}, {0xbe2fc000}, {0xbe2fe000}, + {0xbe300000}, {0xbe302000}, {0xbe304000}, {0xbe306000}, + {0xbe308000}, {0xbe30a000}, {0xbe30c000}, {0xbe30e000}, + {0xbe310000}, {0xbe312000}, {0xbe314000}, {0xbe316000}, + {0xbe318000}, {0xbe31a000}, {0xbe31c000}, {0xbe31e000}, + {0xbe320000}, {0xbe322000}, {0xbe324000}, {0xbe326000}, + {0xbe328000}, {0xbe32a000}, {0xbe32c000}, {0xbe32e000}, + {0xbe330000}, {0xbe332000}, {0xbe334000}, {0xbe336000}, + {0xbe338000}, {0xbe33a000}, {0xbe33c000}, {0xbe33e000}, + {0xbe340000}, {0xbe342000}, {0xbe344000}, {0xbe346000}, + {0xbe348000}, {0xbe34a000}, {0xbe34c000}, {0xbe34e000}, + {0xbe350000}, {0xbe352000}, {0xbe354000}, {0xbe356000}, + {0xbe358000}, {0xbe35a000}, {0xbe35c000}, {0xbe35e000}, + {0xbe360000}, {0xbe362000}, {0xbe364000}, {0xbe366000}, + {0xbe368000}, {0xbe36a000}, {0xbe36c000}, {0xbe36e000}, + {0xbe370000}, {0xbe372000}, {0xbe374000}, {0xbe376000}, + {0xbe378000}, {0xbe37a000}, {0xbe37c000}, {0xbe37e000}, + {0xbe380000}, {0xbe382000}, {0xbe384000}, {0xbe386000}, + {0xbe388000}, {0xbe38a000}, {0xbe38c000}, {0xbe38e000}, + {0xbe390000}, {0xbe392000}, {0xbe394000}, {0xbe396000}, + {0xbe398000}, {0xbe39a000}, {0xbe39c000}, {0xbe39e000}, + {0xbe3a0000}, {0xbe3a2000}, {0xbe3a4000}, {0xbe3a6000}, + {0xbe3a8000}, {0xbe3aa000}, {0xbe3ac000}, {0xbe3ae000}, + {0xbe3b0000}, {0xbe3b2000}, {0xbe3b4000}, {0xbe3b6000}, + {0xbe3b8000}, {0xbe3ba000}, {0xbe3bc000}, {0xbe3be000}, + {0xbe3c0000}, {0xbe3c2000}, {0xbe3c4000}, {0xbe3c6000}, + {0xbe3c8000}, {0xbe3ca000}, {0xbe3cc000}, {0xbe3ce000}, + {0xbe3d0000}, {0xbe3d2000}, {0xbe3d4000}, {0xbe3d6000}, + {0xbe3d8000}, {0xbe3da000}, {0xbe3dc000}, {0xbe3de000}, + {0xbe3e0000}, {0xbe3e2000}, {0xbe3e4000}, {0xbe3e6000}, + {0xbe3e8000}, {0xbe3ea000}, {0xbe3ec000}, {0xbe3ee000}, + {0xbe3f0000}, {0xbe3f2000}, {0xbe3f4000}, {0xbe3f6000}, + {0xbe3f8000}, {0xbe3fa000}, {0xbe3fc000}, {0xbe3fe000}, + {0xbe400000}, {0xbe402000}, {0xbe404000}, {0xbe406000}, + {0xbe408000}, {0xbe40a000}, {0xbe40c000}, {0xbe40e000}, + {0xbe410000}, {0xbe412000}, {0xbe414000}, {0xbe416000}, + {0xbe418000}, {0xbe41a000}, {0xbe41c000}, {0xbe41e000}, + {0xbe420000}, {0xbe422000}, {0xbe424000}, {0xbe426000}, + {0xbe428000}, {0xbe42a000}, {0xbe42c000}, {0xbe42e000}, + {0xbe430000}, {0xbe432000}, {0xbe434000}, {0xbe436000}, + {0xbe438000}, {0xbe43a000}, {0xbe43c000}, {0xbe43e000}, + {0xbe440000}, {0xbe442000}, {0xbe444000}, {0xbe446000}, + {0xbe448000}, {0xbe44a000}, {0xbe44c000}, {0xbe44e000}, + {0xbe450000}, {0xbe452000}, {0xbe454000}, {0xbe456000}, + {0xbe458000}, {0xbe45a000}, {0xbe45c000}, {0xbe45e000}, + {0xbe460000}, {0xbe462000}, {0xbe464000}, {0xbe466000}, + {0xbe468000}, {0xbe46a000}, {0xbe46c000}, {0xbe46e000}, + {0xbe470000}, {0xbe472000}, {0xbe474000}, {0xbe476000}, + {0xbe478000}, {0xbe47a000}, {0xbe47c000}, {0xbe47e000}, + {0xbe480000}, {0xbe482000}, {0xbe484000}, {0xbe486000}, + {0xbe488000}, {0xbe48a000}, {0xbe48c000}, {0xbe48e000}, + {0xbe490000}, {0xbe492000}, {0xbe494000}, {0xbe496000}, + {0xbe498000}, {0xbe49a000}, {0xbe49c000}, {0xbe49e000}, + {0xbe4a0000}, {0xbe4a2000}, {0xbe4a4000}, {0xbe4a6000}, + {0xbe4a8000}, {0xbe4aa000}, {0xbe4ac000}, {0xbe4ae000}, + {0xbe4b0000}, {0xbe4b2000}, {0xbe4b4000}, {0xbe4b6000}, + {0xbe4b8000}, {0xbe4ba000}, {0xbe4bc000}, {0xbe4be000}, + {0xbe4c0000}, {0xbe4c2000}, {0xbe4c4000}, {0xbe4c6000}, + {0xbe4c8000}, {0xbe4ca000}, {0xbe4cc000}, {0xbe4ce000}, + {0xbe4d0000}, {0xbe4d2000}, {0xbe4d4000}, {0xbe4d6000}, + {0xbe4d8000}, {0xbe4da000}, {0xbe4dc000}, {0xbe4de000}, + {0xbe4e0000}, {0xbe4e2000}, {0xbe4e4000}, {0xbe4e6000}, + {0xbe4e8000}, {0xbe4ea000}, {0xbe4ec000}, {0xbe4ee000}, + {0xbe4f0000}, {0xbe4f2000}, {0xbe4f4000}, {0xbe4f6000}, + {0xbe4f8000}, {0xbe4fa000}, {0xbe4fc000}, {0xbe4fe000}, + {0xbe500000}, {0xbe502000}, {0xbe504000}, {0xbe506000}, + {0xbe508000}, {0xbe50a000}, {0xbe50c000}, {0xbe50e000}, + {0xbe510000}, {0xbe512000}, {0xbe514000}, {0xbe516000}, + {0xbe518000}, {0xbe51a000}, {0xbe51c000}, {0xbe51e000}, + {0xbe520000}, {0xbe522000}, {0xbe524000}, {0xbe526000}, + {0xbe528000}, {0xbe52a000}, {0xbe52c000}, {0xbe52e000}, + {0xbe530000}, {0xbe532000}, {0xbe534000}, {0xbe536000}, + {0xbe538000}, {0xbe53a000}, {0xbe53c000}, {0xbe53e000}, + {0xbe540000}, {0xbe542000}, {0xbe544000}, {0xbe546000}, + {0xbe548000}, {0xbe54a000}, {0xbe54c000}, {0xbe54e000}, + {0xbe550000}, {0xbe552000}, {0xbe554000}, {0xbe556000}, + {0xbe558000}, {0xbe55a000}, {0xbe55c000}, {0xbe55e000}, + {0xbe560000}, {0xbe562000}, {0xbe564000}, {0xbe566000}, + {0xbe568000}, {0xbe56a000}, {0xbe56c000}, {0xbe56e000}, + {0xbe570000}, {0xbe572000}, {0xbe574000}, {0xbe576000}, + {0xbe578000}, {0xbe57a000}, {0xbe57c000}, {0xbe57e000}, + {0xbe580000}, {0xbe582000}, {0xbe584000}, {0xbe586000}, + {0xbe588000}, {0xbe58a000}, {0xbe58c000}, {0xbe58e000}, + {0xbe590000}, {0xbe592000}, {0xbe594000}, {0xbe596000}, + {0xbe598000}, {0xbe59a000}, {0xbe59c000}, {0xbe59e000}, + {0xbe5a0000}, {0xbe5a2000}, {0xbe5a4000}, {0xbe5a6000}, + {0xbe5a8000}, {0xbe5aa000}, {0xbe5ac000}, {0xbe5ae000}, + {0xbe5b0000}, {0xbe5b2000}, {0xbe5b4000}, {0xbe5b6000}, + {0xbe5b8000}, {0xbe5ba000}, {0xbe5bc000}, {0xbe5be000}, + {0xbe5c0000}, {0xbe5c2000}, {0xbe5c4000}, {0xbe5c6000}, + {0xbe5c8000}, {0xbe5ca000}, {0xbe5cc000}, {0xbe5ce000}, + {0xbe5d0000}, {0xbe5d2000}, {0xbe5d4000}, {0xbe5d6000}, + {0xbe5d8000}, {0xbe5da000}, {0xbe5dc000}, {0xbe5de000}, + {0xbe5e0000}, {0xbe5e2000}, {0xbe5e4000}, {0xbe5e6000}, + {0xbe5e8000}, {0xbe5ea000}, {0xbe5ec000}, {0xbe5ee000}, + {0xbe5f0000}, {0xbe5f2000}, {0xbe5f4000}, {0xbe5f6000}, + {0xbe5f8000}, {0xbe5fa000}, {0xbe5fc000}, {0xbe5fe000}, + {0xbe600000}, {0xbe602000}, {0xbe604000}, {0xbe606000}, + {0xbe608000}, {0xbe60a000}, {0xbe60c000}, {0xbe60e000}, + {0xbe610000}, {0xbe612000}, {0xbe614000}, {0xbe616000}, + {0xbe618000}, {0xbe61a000}, {0xbe61c000}, {0xbe61e000}, + {0xbe620000}, {0xbe622000}, {0xbe624000}, {0xbe626000}, + {0xbe628000}, {0xbe62a000}, {0xbe62c000}, {0xbe62e000}, + {0xbe630000}, {0xbe632000}, {0xbe634000}, {0xbe636000}, + {0xbe638000}, {0xbe63a000}, {0xbe63c000}, {0xbe63e000}, + {0xbe640000}, {0xbe642000}, {0xbe644000}, {0xbe646000}, + {0xbe648000}, {0xbe64a000}, {0xbe64c000}, {0xbe64e000}, + {0xbe650000}, {0xbe652000}, {0xbe654000}, {0xbe656000}, + {0xbe658000}, {0xbe65a000}, {0xbe65c000}, {0xbe65e000}, + {0xbe660000}, {0xbe662000}, {0xbe664000}, {0xbe666000}, + {0xbe668000}, {0xbe66a000}, {0xbe66c000}, {0xbe66e000}, + {0xbe670000}, {0xbe672000}, {0xbe674000}, {0xbe676000}, + {0xbe678000}, {0xbe67a000}, {0xbe67c000}, {0xbe67e000}, + {0xbe680000}, {0xbe682000}, {0xbe684000}, {0xbe686000}, + {0xbe688000}, {0xbe68a000}, {0xbe68c000}, {0xbe68e000}, + {0xbe690000}, {0xbe692000}, {0xbe694000}, {0xbe696000}, + {0xbe698000}, {0xbe69a000}, {0xbe69c000}, {0xbe69e000}, + {0xbe6a0000}, {0xbe6a2000}, {0xbe6a4000}, {0xbe6a6000}, + {0xbe6a8000}, {0xbe6aa000}, {0xbe6ac000}, {0xbe6ae000}, + {0xbe6b0000}, {0xbe6b2000}, {0xbe6b4000}, {0xbe6b6000}, + {0xbe6b8000}, {0xbe6ba000}, {0xbe6bc000}, {0xbe6be000}, + {0xbe6c0000}, {0xbe6c2000}, {0xbe6c4000}, {0xbe6c6000}, + {0xbe6c8000}, {0xbe6ca000}, {0xbe6cc000}, {0xbe6ce000}, + {0xbe6d0000}, {0xbe6d2000}, {0xbe6d4000}, {0xbe6d6000}, + {0xbe6d8000}, {0xbe6da000}, {0xbe6dc000}, {0xbe6de000}, + {0xbe6e0000}, {0xbe6e2000}, {0xbe6e4000}, {0xbe6e6000}, + {0xbe6e8000}, {0xbe6ea000}, {0xbe6ec000}, {0xbe6ee000}, + {0xbe6f0000}, {0xbe6f2000}, {0xbe6f4000}, {0xbe6f6000}, + {0xbe6f8000}, {0xbe6fa000}, {0xbe6fc000}, {0xbe6fe000}, + {0xbe700000}, {0xbe702000}, {0xbe704000}, {0xbe706000}, + {0xbe708000}, {0xbe70a000}, {0xbe70c000}, {0xbe70e000}, + {0xbe710000}, {0xbe712000}, {0xbe714000}, {0xbe716000}, + {0xbe718000}, {0xbe71a000}, {0xbe71c000}, {0xbe71e000}, + {0xbe720000}, {0xbe722000}, {0xbe724000}, {0xbe726000}, + {0xbe728000}, {0xbe72a000}, {0xbe72c000}, {0xbe72e000}, + {0xbe730000}, {0xbe732000}, {0xbe734000}, {0xbe736000}, + {0xbe738000}, {0xbe73a000}, {0xbe73c000}, {0xbe73e000}, + {0xbe740000}, {0xbe742000}, {0xbe744000}, {0xbe746000}, + {0xbe748000}, {0xbe74a000}, {0xbe74c000}, {0xbe74e000}, + {0xbe750000}, {0xbe752000}, {0xbe754000}, {0xbe756000}, + {0xbe758000}, {0xbe75a000}, {0xbe75c000}, {0xbe75e000}, + {0xbe760000}, {0xbe762000}, {0xbe764000}, {0xbe766000}, + {0xbe768000}, {0xbe76a000}, {0xbe76c000}, {0xbe76e000}, + {0xbe770000}, {0xbe772000}, {0xbe774000}, {0xbe776000}, + {0xbe778000}, {0xbe77a000}, {0xbe77c000}, {0xbe77e000}, + {0xbe780000}, {0xbe782000}, {0xbe784000}, {0xbe786000}, + {0xbe788000}, {0xbe78a000}, {0xbe78c000}, {0xbe78e000}, + {0xbe790000}, {0xbe792000}, {0xbe794000}, {0xbe796000}, + {0xbe798000}, {0xbe79a000}, {0xbe79c000}, {0xbe79e000}, + {0xbe7a0000}, {0xbe7a2000}, {0xbe7a4000}, {0xbe7a6000}, + {0xbe7a8000}, {0xbe7aa000}, {0xbe7ac000}, {0xbe7ae000}, + {0xbe7b0000}, {0xbe7b2000}, {0xbe7b4000}, {0xbe7b6000}, + {0xbe7b8000}, {0xbe7ba000}, {0xbe7bc000}, {0xbe7be000}, + {0xbe7c0000}, {0xbe7c2000}, {0xbe7c4000}, {0xbe7c6000}, + {0xbe7c8000}, {0xbe7ca000}, {0xbe7cc000}, {0xbe7ce000}, + {0xbe7d0000}, {0xbe7d2000}, {0xbe7d4000}, {0xbe7d6000}, + {0xbe7d8000}, {0xbe7da000}, {0xbe7dc000}, {0xbe7de000}, + {0xbe7e0000}, {0xbe7e2000}, {0xbe7e4000}, {0xbe7e6000}, + {0xbe7e8000}, {0xbe7ea000}, {0xbe7ec000}, {0xbe7ee000}, + {0xbe7f0000}, {0xbe7f2000}, {0xbe7f4000}, {0xbe7f6000}, + {0xbe7f8000}, {0xbe7fa000}, {0xbe7fc000}, {0xbe7fe000}, + {0xbe800000}, {0xbe802000}, {0xbe804000}, {0xbe806000}, + {0xbe808000}, {0xbe80a000}, {0xbe80c000}, {0xbe80e000}, + {0xbe810000}, {0xbe812000}, {0xbe814000}, {0xbe816000}, + {0xbe818000}, {0xbe81a000}, {0xbe81c000}, {0xbe81e000}, + {0xbe820000}, {0xbe822000}, {0xbe824000}, {0xbe826000}, + {0xbe828000}, {0xbe82a000}, {0xbe82c000}, {0xbe82e000}, + {0xbe830000}, {0xbe832000}, {0xbe834000}, {0xbe836000}, + {0xbe838000}, {0xbe83a000}, {0xbe83c000}, {0xbe83e000}, + {0xbe840000}, {0xbe842000}, {0xbe844000}, {0xbe846000}, + {0xbe848000}, {0xbe84a000}, {0xbe84c000}, {0xbe84e000}, + {0xbe850000}, {0xbe852000}, {0xbe854000}, {0xbe856000}, + {0xbe858000}, {0xbe85a000}, {0xbe85c000}, {0xbe85e000}, + {0xbe860000}, {0xbe862000}, {0xbe864000}, {0xbe866000}, + {0xbe868000}, {0xbe86a000}, {0xbe86c000}, {0xbe86e000}, + {0xbe870000}, {0xbe872000}, {0xbe874000}, {0xbe876000}, + {0xbe878000}, {0xbe87a000}, {0xbe87c000}, {0xbe87e000}, + {0xbe880000}, {0xbe882000}, {0xbe884000}, {0xbe886000}, + {0xbe888000}, {0xbe88a000}, {0xbe88c000}, {0xbe88e000}, + {0xbe890000}, {0xbe892000}, {0xbe894000}, {0xbe896000}, + {0xbe898000}, {0xbe89a000}, {0xbe89c000}, {0xbe89e000}, + {0xbe8a0000}, {0xbe8a2000}, {0xbe8a4000}, {0xbe8a6000}, + {0xbe8a8000}, {0xbe8aa000}, {0xbe8ac000}, {0xbe8ae000}, + {0xbe8b0000}, {0xbe8b2000}, {0xbe8b4000}, {0xbe8b6000}, + {0xbe8b8000}, {0xbe8ba000}, {0xbe8bc000}, {0xbe8be000}, + {0xbe8c0000}, {0xbe8c2000}, {0xbe8c4000}, {0xbe8c6000}, + {0xbe8c8000}, {0xbe8ca000}, {0xbe8cc000}, {0xbe8ce000}, + {0xbe8d0000}, {0xbe8d2000}, {0xbe8d4000}, {0xbe8d6000}, + {0xbe8d8000}, {0xbe8da000}, {0xbe8dc000}, {0xbe8de000}, + {0xbe8e0000}, {0xbe8e2000}, {0xbe8e4000}, {0xbe8e6000}, + {0xbe8e8000}, {0xbe8ea000}, {0xbe8ec000}, {0xbe8ee000}, + {0xbe8f0000}, {0xbe8f2000}, {0xbe8f4000}, {0xbe8f6000}, + {0xbe8f8000}, {0xbe8fa000}, {0xbe8fc000}, {0xbe8fe000}, + {0xbe900000}, {0xbe902000}, {0xbe904000}, {0xbe906000}, + {0xbe908000}, {0xbe90a000}, {0xbe90c000}, {0xbe90e000}, + {0xbe910000}, {0xbe912000}, {0xbe914000}, {0xbe916000}, + {0xbe918000}, {0xbe91a000}, {0xbe91c000}, {0xbe91e000}, + {0xbe920000}, {0xbe922000}, {0xbe924000}, {0xbe926000}, + {0xbe928000}, {0xbe92a000}, {0xbe92c000}, {0xbe92e000}, + {0xbe930000}, {0xbe932000}, {0xbe934000}, {0xbe936000}, + {0xbe938000}, {0xbe93a000}, {0xbe93c000}, {0xbe93e000}, + {0xbe940000}, {0xbe942000}, {0xbe944000}, {0xbe946000}, + {0xbe948000}, {0xbe94a000}, {0xbe94c000}, {0xbe94e000}, + {0xbe950000}, {0xbe952000}, {0xbe954000}, {0xbe956000}, + {0xbe958000}, {0xbe95a000}, {0xbe95c000}, {0xbe95e000}, + {0xbe960000}, {0xbe962000}, {0xbe964000}, {0xbe966000}, + {0xbe968000}, {0xbe96a000}, {0xbe96c000}, {0xbe96e000}, + {0xbe970000}, {0xbe972000}, {0xbe974000}, {0xbe976000}, + {0xbe978000}, {0xbe97a000}, {0xbe97c000}, {0xbe97e000}, + {0xbe980000}, {0xbe982000}, {0xbe984000}, {0xbe986000}, + {0xbe988000}, {0xbe98a000}, {0xbe98c000}, {0xbe98e000}, + {0xbe990000}, {0xbe992000}, {0xbe994000}, {0xbe996000}, + {0xbe998000}, {0xbe99a000}, {0xbe99c000}, {0xbe99e000}, + {0xbe9a0000}, {0xbe9a2000}, {0xbe9a4000}, {0xbe9a6000}, + {0xbe9a8000}, {0xbe9aa000}, {0xbe9ac000}, {0xbe9ae000}, + {0xbe9b0000}, {0xbe9b2000}, {0xbe9b4000}, {0xbe9b6000}, + {0xbe9b8000}, {0xbe9ba000}, {0xbe9bc000}, {0xbe9be000}, + {0xbe9c0000}, {0xbe9c2000}, {0xbe9c4000}, {0xbe9c6000}, + {0xbe9c8000}, {0xbe9ca000}, {0xbe9cc000}, {0xbe9ce000}, + {0xbe9d0000}, {0xbe9d2000}, {0xbe9d4000}, {0xbe9d6000}, + {0xbe9d8000}, {0xbe9da000}, {0xbe9dc000}, {0xbe9de000}, + {0xbe9e0000}, {0xbe9e2000}, {0xbe9e4000}, {0xbe9e6000}, + {0xbe9e8000}, {0xbe9ea000}, {0xbe9ec000}, {0xbe9ee000}, + {0xbe9f0000}, {0xbe9f2000}, {0xbe9f4000}, {0xbe9f6000}, + {0xbe9f8000}, {0xbe9fa000}, {0xbe9fc000}, {0xbe9fe000}, + {0xbea00000}, {0xbea02000}, {0xbea04000}, {0xbea06000}, + {0xbea08000}, {0xbea0a000}, {0xbea0c000}, {0xbea0e000}, + {0xbea10000}, {0xbea12000}, {0xbea14000}, {0xbea16000}, + {0xbea18000}, {0xbea1a000}, {0xbea1c000}, {0xbea1e000}, + {0xbea20000}, {0xbea22000}, {0xbea24000}, {0xbea26000}, + {0xbea28000}, {0xbea2a000}, {0xbea2c000}, {0xbea2e000}, + {0xbea30000}, {0xbea32000}, {0xbea34000}, {0xbea36000}, + {0xbea38000}, {0xbea3a000}, {0xbea3c000}, {0xbea3e000}, + {0xbea40000}, {0xbea42000}, {0xbea44000}, {0xbea46000}, + {0xbea48000}, {0xbea4a000}, {0xbea4c000}, {0xbea4e000}, + {0xbea50000}, {0xbea52000}, {0xbea54000}, {0xbea56000}, + {0xbea58000}, {0xbea5a000}, {0xbea5c000}, {0xbea5e000}, + {0xbea60000}, {0xbea62000}, {0xbea64000}, {0xbea66000}, + {0xbea68000}, {0xbea6a000}, {0xbea6c000}, {0xbea6e000}, + {0xbea70000}, {0xbea72000}, {0xbea74000}, {0xbea76000}, + {0xbea78000}, {0xbea7a000}, {0xbea7c000}, {0xbea7e000}, + {0xbea80000}, {0xbea82000}, {0xbea84000}, {0xbea86000}, + {0xbea88000}, {0xbea8a000}, {0xbea8c000}, {0xbea8e000}, + {0xbea90000}, {0xbea92000}, {0xbea94000}, {0xbea96000}, + {0xbea98000}, {0xbea9a000}, {0xbea9c000}, {0xbea9e000}, + {0xbeaa0000}, {0xbeaa2000}, {0xbeaa4000}, {0xbeaa6000}, + {0xbeaa8000}, {0xbeaaa000}, {0xbeaac000}, {0xbeaae000}, + {0xbeab0000}, {0xbeab2000}, {0xbeab4000}, {0xbeab6000}, + {0xbeab8000}, {0xbeaba000}, {0xbeabc000}, {0xbeabe000}, + {0xbeac0000}, {0xbeac2000}, {0xbeac4000}, {0xbeac6000}, + {0xbeac8000}, {0xbeaca000}, {0xbeacc000}, {0xbeace000}, + {0xbead0000}, {0xbead2000}, {0xbead4000}, {0xbead6000}, + {0xbead8000}, {0xbeada000}, {0xbeadc000}, {0xbeade000}, + {0xbeae0000}, {0xbeae2000}, {0xbeae4000}, {0xbeae6000}, + {0xbeae8000}, {0xbeaea000}, {0xbeaec000}, {0xbeaee000}, + {0xbeaf0000}, {0xbeaf2000}, {0xbeaf4000}, {0xbeaf6000}, + {0xbeaf8000}, {0xbeafa000}, {0xbeafc000}, {0xbeafe000}, + {0xbeb00000}, {0xbeb02000}, {0xbeb04000}, {0xbeb06000}, + {0xbeb08000}, {0xbeb0a000}, {0xbeb0c000}, {0xbeb0e000}, + {0xbeb10000}, {0xbeb12000}, {0xbeb14000}, {0xbeb16000}, + {0xbeb18000}, {0xbeb1a000}, {0xbeb1c000}, {0xbeb1e000}, + {0xbeb20000}, {0xbeb22000}, {0xbeb24000}, {0xbeb26000}, + {0xbeb28000}, {0xbeb2a000}, {0xbeb2c000}, {0xbeb2e000}, + {0xbeb30000}, {0xbeb32000}, {0xbeb34000}, {0xbeb36000}, + {0xbeb38000}, {0xbeb3a000}, {0xbeb3c000}, {0xbeb3e000}, + {0xbeb40000}, {0xbeb42000}, {0xbeb44000}, {0xbeb46000}, + {0xbeb48000}, {0xbeb4a000}, {0xbeb4c000}, {0xbeb4e000}, + {0xbeb50000}, {0xbeb52000}, {0xbeb54000}, {0xbeb56000}, + {0xbeb58000}, {0xbeb5a000}, {0xbeb5c000}, {0xbeb5e000}, + {0xbeb60000}, {0xbeb62000}, {0xbeb64000}, {0xbeb66000}, + {0xbeb68000}, {0xbeb6a000}, {0xbeb6c000}, {0xbeb6e000}, + {0xbeb70000}, {0xbeb72000}, {0xbeb74000}, {0xbeb76000}, + {0xbeb78000}, {0xbeb7a000}, {0xbeb7c000}, {0xbeb7e000}, + {0xbeb80000}, {0xbeb82000}, {0xbeb84000}, {0xbeb86000}, + {0xbeb88000}, {0xbeb8a000}, {0xbeb8c000}, {0xbeb8e000}, + {0xbeb90000}, {0xbeb92000}, {0xbeb94000}, {0xbeb96000}, + {0xbeb98000}, {0xbeb9a000}, {0xbeb9c000}, {0xbeb9e000}, + {0xbeba0000}, {0xbeba2000}, {0xbeba4000}, {0xbeba6000}, + {0xbeba8000}, {0xbebaa000}, {0xbebac000}, {0xbebae000}, + {0xbebb0000}, {0xbebb2000}, {0xbebb4000}, {0xbebb6000}, + {0xbebb8000}, {0xbebba000}, {0xbebbc000}, {0xbebbe000}, + {0xbebc0000}, {0xbebc2000}, {0xbebc4000}, {0xbebc6000}, + {0xbebc8000}, {0xbebca000}, {0xbebcc000}, {0xbebce000}, + {0xbebd0000}, {0xbebd2000}, {0xbebd4000}, {0xbebd6000}, + {0xbebd8000}, {0xbebda000}, {0xbebdc000}, {0xbebde000}, + {0xbebe0000}, {0xbebe2000}, {0xbebe4000}, {0xbebe6000}, + {0xbebe8000}, {0xbebea000}, {0xbebec000}, {0xbebee000}, + {0xbebf0000}, {0xbebf2000}, {0xbebf4000}, {0xbebf6000}, + {0xbebf8000}, {0xbebfa000}, {0xbebfc000}, {0xbebfe000}, + {0xbec00000}, {0xbec02000}, {0xbec04000}, {0xbec06000}, + {0xbec08000}, {0xbec0a000}, {0xbec0c000}, {0xbec0e000}, + {0xbec10000}, {0xbec12000}, {0xbec14000}, {0xbec16000}, + {0xbec18000}, {0xbec1a000}, {0xbec1c000}, {0xbec1e000}, + {0xbec20000}, {0xbec22000}, {0xbec24000}, {0xbec26000}, + {0xbec28000}, {0xbec2a000}, {0xbec2c000}, {0xbec2e000}, + {0xbec30000}, {0xbec32000}, {0xbec34000}, {0xbec36000}, + {0xbec38000}, {0xbec3a000}, {0xbec3c000}, {0xbec3e000}, + {0xbec40000}, {0xbec42000}, {0xbec44000}, {0xbec46000}, + {0xbec48000}, {0xbec4a000}, {0xbec4c000}, {0xbec4e000}, + {0xbec50000}, {0xbec52000}, {0xbec54000}, {0xbec56000}, + {0xbec58000}, {0xbec5a000}, {0xbec5c000}, {0xbec5e000}, + {0xbec60000}, {0xbec62000}, {0xbec64000}, {0xbec66000}, + {0xbec68000}, {0xbec6a000}, {0xbec6c000}, {0xbec6e000}, + {0xbec70000}, {0xbec72000}, {0xbec74000}, {0xbec76000}, + {0xbec78000}, {0xbec7a000}, {0xbec7c000}, {0xbec7e000}, + {0xbec80000}, {0xbec82000}, {0xbec84000}, {0xbec86000}, + {0xbec88000}, {0xbec8a000}, {0xbec8c000}, {0xbec8e000}, + {0xbec90000}, {0xbec92000}, {0xbec94000}, {0xbec96000}, + {0xbec98000}, {0xbec9a000}, {0xbec9c000}, {0xbec9e000}, + {0xbeca0000}, {0xbeca2000}, {0xbeca4000}, {0xbeca6000}, + {0xbeca8000}, {0xbecaa000}, {0xbecac000}, {0xbecae000}, + {0xbecb0000}, {0xbecb2000}, {0xbecb4000}, {0xbecb6000}, + {0xbecb8000}, {0xbecba000}, {0xbecbc000}, {0xbecbe000}, + {0xbecc0000}, {0xbecc2000}, {0xbecc4000}, {0xbecc6000}, + {0xbecc8000}, {0xbecca000}, {0xbeccc000}, {0xbecce000}, + {0xbecd0000}, {0xbecd2000}, {0xbecd4000}, {0xbecd6000}, + {0xbecd8000}, {0xbecda000}, {0xbecdc000}, {0xbecde000}, + {0xbece0000}, {0xbece2000}, {0xbece4000}, {0xbece6000}, + {0xbece8000}, {0xbecea000}, {0xbecec000}, {0xbecee000}, + {0xbecf0000}, {0xbecf2000}, {0xbecf4000}, {0xbecf6000}, + {0xbecf8000}, {0xbecfa000}, {0xbecfc000}, {0xbecfe000}, + {0xbed00000}, {0xbed02000}, {0xbed04000}, {0xbed06000}, + {0xbed08000}, {0xbed0a000}, {0xbed0c000}, {0xbed0e000}, + {0xbed10000}, {0xbed12000}, {0xbed14000}, {0xbed16000}, + {0xbed18000}, {0xbed1a000}, {0xbed1c000}, {0xbed1e000}, + {0xbed20000}, {0xbed22000}, {0xbed24000}, {0xbed26000}, + {0xbed28000}, {0xbed2a000}, {0xbed2c000}, {0xbed2e000}, + {0xbed30000}, {0xbed32000}, {0xbed34000}, {0xbed36000}, + {0xbed38000}, {0xbed3a000}, {0xbed3c000}, {0xbed3e000}, + {0xbed40000}, {0xbed42000}, {0xbed44000}, {0xbed46000}, + {0xbed48000}, {0xbed4a000}, {0xbed4c000}, {0xbed4e000}, + {0xbed50000}, {0xbed52000}, {0xbed54000}, {0xbed56000}, + {0xbed58000}, {0xbed5a000}, {0xbed5c000}, {0xbed5e000}, + {0xbed60000}, {0xbed62000}, {0xbed64000}, {0xbed66000}, + {0xbed68000}, {0xbed6a000}, {0xbed6c000}, {0xbed6e000}, + {0xbed70000}, {0xbed72000}, {0xbed74000}, {0xbed76000}, + {0xbed78000}, {0xbed7a000}, {0xbed7c000}, {0xbed7e000}, + {0xbed80000}, {0xbed82000}, {0xbed84000}, {0xbed86000}, + {0xbed88000}, {0xbed8a000}, {0xbed8c000}, {0xbed8e000}, + {0xbed90000}, {0xbed92000}, {0xbed94000}, {0xbed96000}, + {0xbed98000}, {0xbed9a000}, {0xbed9c000}, {0xbed9e000}, + {0xbeda0000}, {0xbeda2000}, {0xbeda4000}, {0xbeda6000}, + {0xbeda8000}, {0xbedaa000}, {0xbedac000}, {0xbedae000}, + {0xbedb0000}, {0xbedb2000}, {0xbedb4000}, {0xbedb6000}, + {0xbedb8000}, {0xbedba000}, {0xbedbc000}, {0xbedbe000}, + {0xbedc0000}, {0xbedc2000}, {0xbedc4000}, {0xbedc6000}, + {0xbedc8000}, {0xbedca000}, {0xbedcc000}, {0xbedce000}, + {0xbedd0000}, {0xbedd2000}, {0xbedd4000}, {0xbedd6000}, + {0xbedd8000}, {0xbedda000}, {0xbeddc000}, {0xbedde000}, + {0xbede0000}, {0xbede2000}, {0xbede4000}, {0xbede6000}, + {0xbede8000}, {0xbedea000}, {0xbedec000}, {0xbedee000}, + {0xbedf0000}, {0xbedf2000}, {0xbedf4000}, {0xbedf6000}, + {0xbedf8000}, {0xbedfa000}, {0xbedfc000}, {0xbedfe000}, + {0xbee00000}, {0xbee02000}, {0xbee04000}, {0xbee06000}, + {0xbee08000}, {0xbee0a000}, {0xbee0c000}, {0xbee0e000}, + {0xbee10000}, {0xbee12000}, {0xbee14000}, {0xbee16000}, + {0xbee18000}, {0xbee1a000}, {0xbee1c000}, {0xbee1e000}, + {0xbee20000}, {0xbee22000}, {0xbee24000}, {0xbee26000}, + {0xbee28000}, {0xbee2a000}, {0xbee2c000}, {0xbee2e000}, + {0xbee30000}, {0xbee32000}, {0xbee34000}, {0xbee36000}, + {0xbee38000}, {0xbee3a000}, {0xbee3c000}, {0xbee3e000}, + {0xbee40000}, {0xbee42000}, {0xbee44000}, {0xbee46000}, + {0xbee48000}, {0xbee4a000}, {0xbee4c000}, {0xbee4e000}, + {0xbee50000}, {0xbee52000}, {0xbee54000}, {0xbee56000}, + {0xbee58000}, {0xbee5a000}, {0xbee5c000}, {0xbee5e000}, + {0xbee60000}, {0xbee62000}, {0xbee64000}, {0xbee66000}, + {0xbee68000}, {0xbee6a000}, {0xbee6c000}, {0xbee6e000}, + {0xbee70000}, {0xbee72000}, {0xbee74000}, {0xbee76000}, + {0xbee78000}, {0xbee7a000}, {0xbee7c000}, {0xbee7e000}, + {0xbee80000}, {0xbee82000}, {0xbee84000}, {0xbee86000}, + {0xbee88000}, {0xbee8a000}, {0xbee8c000}, {0xbee8e000}, + {0xbee90000}, {0xbee92000}, {0xbee94000}, {0xbee96000}, + {0xbee98000}, {0xbee9a000}, {0xbee9c000}, {0xbee9e000}, + {0xbeea0000}, {0xbeea2000}, {0xbeea4000}, {0xbeea6000}, + {0xbeea8000}, {0xbeeaa000}, {0xbeeac000}, {0xbeeae000}, + {0xbeeb0000}, {0xbeeb2000}, {0xbeeb4000}, {0xbeeb6000}, + {0xbeeb8000}, {0xbeeba000}, {0xbeebc000}, {0xbeebe000}, + {0xbeec0000}, {0xbeec2000}, {0xbeec4000}, {0xbeec6000}, + {0xbeec8000}, {0xbeeca000}, {0xbeecc000}, {0xbeece000}, + {0xbeed0000}, {0xbeed2000}, {0xbeed4000}, {0xbeed6000}, + {0xbeed8000}, {0xbeeda000}, {0xbeedc000}, {0xbeede000}, + {0xbeee0000}, {0xbeee2000}, {0xbeee4000}, {0xbeee6000}, + {0xbeee8000}, {0xbeeea000}, {0xbeeec000}, {0xbeeee000}, + {0xbeef0000}, {0xbeef2000}, {0xbeef4000}, {0xbeef6000}, + {0xbeef8000}, {0xbeefa000}, {0xbeefc000}, {0xbeefe000}, + {0xbef00000}, {0xbef02000}, {0xbef04000}, {0xbef06000}, + {0xbef08000}, {0xbef0a000}, {0xbef0c000}, {0xbef0e000}, + {0xbef10000}, {0xbef12000}, {0xbef14000}, {0xbef16000}, + {0xbef18000}, {0xbef1a000}, {0xbef1c000}, {0xbef1e000}, + {0xbef20000}, {0xbef22000}, {0xbef24000}, {0xbef26000}, + {0xbef28000}, {0xbef2a000}, {0xbef2c000}, {0xbef2e000}, + {0xbef30000}, {0xbef32000}, {0xbef34000}, {0xbef36000}, + {0xbef38000}, {0xbef3a000}, {0xbef3c000}, {0xbef3e000}, + {0xbef40000}, {0xbef42000}, {0xbef44000}, {0xbef46000}, + {0xbef48000}, {0xbef4a000}, {0xbef4c000}, {0xbef4e000}, + {0xbef50000}, {0xbef52000}, {0xbef54000}, {0xbef56000}, + {0xbef58000}, {0xbef5a000}, {0xbef5c000}, {0xbef5e000}, + {0xbef60000}, {0xbef62000}, {0xbef64000}, {0xbef66000}, + {0xbef68000}, {0xbef6a000}, {0xbef6c000}, {0xbef6e000}, + {0xbef70000}, {0xbef72000}, {0xbef74000}, {0xbef76000}, + {0xbef78000}, {0xbef7a000}, {0xbef7c000}, {0xbef7e000}, + {0xbef80000}, {0xbef82000}, {0xbef84000}, {0xbef86000}, + {0xbef88000}, {0xbef8a000}, {0xbef8c000}, {0xbef8e000}, + {0xbef90000}, {0xbef92000}, {0xbef94000}, {0xbef96000}, + {0xbef98000}, {0xbef9a000}, {0xbef9c000}, {0xbef9e000}, + {0xbefa0000}, {0xbefa2000}, {0xbefa4000}, {0xbefa6000}, + {0xbefa8000}, {0xbefaa000}, {0xbefac000}, {0xbefae000}, + {0xbefb0000}, {0xbefb2000}, {0xbefb4000}, {0xbefb6000}, + {0xbefb8000}, {0xbefba000}, {0xbefbc000}, {0xbefbe000}, + {0xbefc0000}, {0xbefc2000}, {0xbefc4000}, {0xbefc6000}, + {0xbefc8000}, {0xbefca000}, {0xbefcc000}, {0xbefce000}, + {0xbefd0000}, {0xbefd2000}, {0xbefd4000}, {0xbefd6000}, + {0xbefd8000}, {0xbefda000}, {0xbefdc000}, {0xbefde000}, + {0xbefe0000}, {0xbefe2000}, {0xbefe4000}, {0xbefe6000}, + {0xbefe8000}, {0xbefea000}, {0xbefec000}, {0xbefee000}, + {0xbeff0000}, {0xbeff2000}, {0xbeff4000}, {0xbeff6000}, + {0xbeff8000}, {0xbeffa000}, {0xbeffc000}, {0xbeffe000}, + {0xbf000000}, {0xbf002000}, {0xbf004000}, {0xbf006000}, + {0xbf008000}, {0xbf00a000}, {0xbf00c000}, {0xbf00e000}, + {0xbf010000}, {0xbf012000}, {0xbf014000}, {0xbf016000}, + {0xbf018000}, {0xbf01a000}, {0xbf01c000}, {0xbf01e000}, + {0xbf020000}, {0xbf022000}, {0xbf024000}, {0xbf026000}, + {0xbf028000}, {0xbf02a000}, {0xbf02c000}, {0xbf02e000}, + {0xbf030000}, {0xbf032000}, {0xbf034000}, {0xbf036000}, + {0xbf038000}, {0xbf03a000}, {0xbf03c000}, {0xbf03e000}, + {0xbf040000}, {0xbf042000}, {0xbf044000}, {0xbf046000}, + {0xbf048000}, {0xbf04a000}, {0xbf04c000}, {0xbf04e000}, + {0xbf050000}, {0xbf052000}, {0xbf054000}, {0xbf056000}, + {0xbf058000}, {0xbf05a000}, {0xbf05c000}, {0xbf05e000}, + {0xbf060000}, {0xbf062000}, {0xbf064000}, {0xbf066000}, + {0xbf068000}, {0xbf06a000}, {0xbf06c000}, {0xbf06e000}, + {0xbf070000}, {0xbf072000}, {0xbf074000}, {0xbf076000}, + {0xbf078000}, {0xbf07a000}, {0xbf07c000}, {0xbf07e000}, + {0xbf080000}, {0xbf082000}, {0xbf084000}, {0xbf086000}, + {0xbf088000}, {0xbf08a000}, {0xbf08c000}, {0xbf08e000}, + {0xbf090000}, {0xbf092000}, {0xbf094000}, {0xbf096000}, + {0xbf098000}, {0xbf09a000}, {0xbf09c000}, {0xbf09e000}, + {0xbf0a0000}, {0xbf0a2000}, {0xbf0a4000}, {0xbf0a6000}, + {0xbf0a8000}, {0xbf0aa000}, {0xbf0ac000}, {0xbf0ae000}, + {0xbf0b0000}, {0xbf0b2000}, {0xbf0b4000}, {0xbf0b6000}, + {0xbf0b8000}, {0xbf0ba000}, {0xbf0bc000}, {0xbf0be000}, + {0xbf0c0000}, {0xbf0c2000}, {0xbf0c4000}, {0xbf0c6000}, + {0xbf0c8000}, {0xbf0ca000}, {0xbf0cc000}, {0xbf0ce000}, + {0xbf0d0000}, {0xbf0d2000}, {0xbf0d4000}, {0xbf0d6000}, + {0xbf0d8000}, {0xbf0da000}, {0xbf0dc000}, {0xbf0de000}, + {0xbf0e0000}, {0xbf0e2000}, {0xbf0e4000}, {0xbf0e6000}, + {0xbf0e8000}, {0xbf0ea000}, {0xbf0ec000}, {0xbf0ee000}, + {0xbf0f0000}, {0xbf0f2000}, {0xbf0f4000}, {0xbf0f6000}, + {0xbf0f8000}, {0xbf0fa000}, {0xbf0fc000}, {0xbf0fe000}, + {0xbf100000}, {0xbf102000}, {0xbf104000}, {0xbf106000}, + {0xbf108000}, {0xbf10a000}, {0xbf10c000}, {0xbf10e000}, + {0xbf110000}, {0xbf112000}, {0xbf114000}, {0xbf116000}, + {0xbf118000}, {0xbf11a000}, {0xbf11c000}, {0xbf11e000}, + {0xbf120000}, {0xbf122000}, {0xbf124000}, {0xbf126000}, + {0xbf128000}, {0xbf12a000}, {0xbf12c000}, {0xbf12e000}, + {0xbf130000}, {0xbf132000}, {0xbf134000}, {0xbf136000}, + {0xbf138000}, {0xbf13a000}, {0xbf13c000}, {0xbf13e000}, + {0xbf140000}, {0xbf142000}, {0xbf144000}, {0xbf146000}, + {0xbf148000}, {0xbf14a000}, {0xbf14c000}, {0xbf14e000}, + {0xbf150000}, {0xbf152000}, {0xbf154000}, {0xbf156000}, + {0xbf158000}, {0xbf15a000}, {0xbf15c000}, {0xbf15e000}, + {0xbf160000}, {0xbf162000}, {0xbf164000}, {0xbf166000}, + {0xbf168000}, {0xbf16a000}, {0xbf16c000}, {0xbf16e000}, + {0xbf170000}, {0xbf172000}, {0xbf174000}, {0xbf176000}, + {0xbf178000}, {0xbf17a000}, {0xbf17c000}, {0xbf17e000}, + {0xbf180000}, {0xbf182000}, {0xbf184000}, {0xbf186000}, + {0xbf188000}, {0xbf18a000}, {0xbf18c000}, {0xbf18e000}, + {0xbf190000}, {0xbf192000}, {0xbf194000}, {0xbf196000}, + {0xbf198000}, {0xbf19a000}, {0xbf19c000}, {0xbf19e000}, + {0xbf1a0000}, {0xbf1a2000}, {0xbf1a4000}, {0xbf1a6000}, + {0xbf1a8000}, {0xbf1aa000}, {0xbf1ac000}, {0xbf1ae000}, + {0xbf1b0000}, {0xbf1b2000}, {0xbf1b4000}, {0xbf1b6000}, + {0xbf1b8000}, {0xbf1ba000}, {0xbf1bc000}, {0xbf1be000}, + {0xbf1c0000}, {0xbf1c2000}, {0xbf1c4000}, {0xbf1c6000}, + {0xbf1c8000}, {0xbf1ca000}, {0xbf1cc000}, {0xbf1ce000}, + {0xbf1d0000}, {0xbf1d2000}, {0xbf1d4000}, {0xbf1d6000}, + {0xbf1d8000}, {0xbf1da000}, {0xbf1dc000}, {0xbf1de000}, + {0xbf1e0000}, {0xbf1e2000}, {0xbf1e4000}, {0xbf1e6000}, + {0xbf1e8000}, {0xbf1ea000}, {0xbf1ec000}, {0xbf1ee000}, + {0xbf1f0000}, {0xbf1f2000}, {0xbf1f4000}, {0xbf1f6000}, + {0xbf1f8000}, {0xbf1fa000}, {0xbf1fc000}, {0xbf1fe000}, + {0xbf200000}, {0xbf202000}, {0xbf204000}, {0xbf206000}, + {0xbf208000}, {0xbf20a000}, {0xbf20c000}, {0xbf20e000}, + {0xbf210000}, {0xbf212000}, {0xbf214000}, {0xbf216000}, + {0xbf218000}, {0xbf21a000}, {0xbf21c000}, {0xbf21e000}, + {0xbf220000}, {0xbf222000}, {0xbf224000}, {0xbf226000}, + {0xbf228000}, {0xbf22a000}, {0xbf22c000}, {0xbf22e000}, + {0xbf230000}, {0xbf232000}, {0xbf234000}, {0xbf236000}, + {0xbf238000}, {0xbf23a000}, {0xbf23c000}, {0xbf23e000}, + {0xbf240000}, {0xbf242000}, {0xbf244000}, {0xbf246000}, + {0xbf248000}, {0xbf24a000}, {0xbf24c000}, {0xbf24e000}, + {0xbf250000}, {0xbf252000}, {0xbf254000}, {0xbf256000}, + {0xbf258000}, {0xbf25a000}, {0xbf25c000}, {0xbf25e000}, + {0xbf260000}, {0xbf262000}, {0xbf264000}, {0xbf266000}, + {0xbf268000}, {0xbf26a000}, {0xbf26c000}, {0xbf26e000}, + {0xbf270000}, {0xbf272000}, {0xbf274000}, {0xbf276000}, + {0xbf278000}, {0xbf27a000}, {0xbf27c000}, {0xbf27e000}, + {0xbf280000}, {0xbf282000}, {0xbf284000}, {0xbf286000}, + {0xbf288000}, {0xbf28a000}, {0xbf28c000}, {0xbf28e000}, + {0xbf290000}, {0xbf292000}, {0xbf294000}, {0xbf296000}, + {0xbf298000}, {0xbf29a000}, {0xbf29c000}, {0xbf29e000}, + {0xbf2a0000}, {0xbf2a2000}, {0xbf2a4000}, {0xbf2a6000}, + {0xbf2a8000}, {0xbf2aa000}, {0xbf2ac000}, {0xbf2ae000}, + {0xbf2b0000}, {0xbf2b2000}, {0xbf2b4000}, {0xbf2b6000}, + {0xbf2b8000}, {0xbf2ba000}, {0xbf2bc000}, {0xbf2be000}, + {0xbf2c0000}, {0xbf2c2000}, {0xbf2c4000}, {0xbf2c6000}, + {0xbf2c8000}, {0xbf2ca000}, {0xbf2cc000}, {0xbf2ce000}, + {0xbf2d0000}, {0xbf2d2000}, {0xbf2d4000}, {0xbf2d6000}, + {0xbf2d8000}, {0xbf2da000}, {0xbf2dc000}, {0xbf2de000}, + {0xbf2e0000}, {0xbf2e2000}, {0xbf2e4000}, {0xbf2e6000}, + {0xbf2e8000}, {0xbf2ea000}, {0xbf2ec000}, {0xbf2ee000}, + {0xbf2f0000}, {0xbf2f2000}, {0xbf2f4000}, {0xbf2f6000}, + {0xbf2f8000}, {0xbf2fa000}, {0xbf2fc000}, {0xbf2fe000}, + {0xbf300000}, {0xbf302000}, {0xbf304000}, {0xbf306000}, + {0xbf308000}, {0xbf30a000}, {0xbf30c000}, {0xbf30e000}, + {0xbf310000}, {0xbf312000}, {0xbf314000}, {0xbf316000}, + {0xbf318000}, {0xbf31a000}, {0xbf31c000}, {0xbf31e000}, + {0xbf320000}, {0xbf322000}, {0xbf324000}, {0xbf326000}, + {0xbf328000}, {0xbf32a000}, {0xbf32c000}, {0xbf32e000}, + {0xbf330000}, {0xbf332000}, {0xbf334000}, {0xbf336000}, + {0xbf338000}, {0xbf33a000}, {0xbf33c000}, {0xbf33e000}, + {0xbf340000}, {0xbf342000}, {0xbf344000}, {0xbf346000}, + {0xbf348000}, {0xbf34a000}, {0xbf34c000}, {0xbf34e000}, + {0xbf350000}, {0xbf352000}, {0xbf354000}, {0xbf356000}, + {0xbf358000}, {0xbf35a000}, {0xbf35c000}, {0xbf35e000}, + {0xbf360000}, {0xbf362000}, {0xbf364000}, {0xbf366000}, + {0xbf368000}, {0xbf36a000}, {0xbf36c000}, {0xbf36e000}, + {0xbf370000}, {0xbf372000}, {0xbf374000}, {0xbf376000}, + {0xbf378000}, {0xbf37a000}, {0xbf37c000}, {0xbf37e000}, + {0xbf380000}, {0xbf382000}, {0xbf384000}, {0xbf386000}, + {0xbf388000}, {0xbf38a000}, {0xbf38c000}, {0xbf38e000}, + {0xbf390000}, {0xbf392000}, {0xbf394000}, {0xbf396000}, + {0xbf398000}, {0xbf39a000}, {0xbf39c000}, {0xbf39e000}, + {0xbf3a0000}, {0xbf3a2000}, {0xbf3a4000}, {0xbf3a6000}, + {0xbf3a8000}, {0xbf3aa000}, {0xbf3ac000}, {0xbf3ae000}, + {0xbf3b0000}, {0xbf3b2000}, {0xbf3b4000}, {0xbf3b6000}, + {0xbf3b8000}, {0xbf3ba000}, {0xbf3bc000}, {0xbf3be000}, + {0xbf3c0000}, {0xbf3c2000}, {0xbf3c4000}, {0xbf3c6000}, + {0xbf3c8000}, {0xbf3ca000}, {0xbf3cc000}, {0xbf3ce000}, + {0xbf3d0000}, {0xbf3d2000}, {0xbf3d4000}, {0xbf3d6000}, + {0xbf3d8000}, {0xbf3da000}, {0xbf3dc000}, {0xbf3de000}, + {0xbf3e0000}, {0xbf3e2000}, {0xbf3e4000}, {0xbf3e6000}, + {0xbf3e8000}, {0xbf3ea000}, {0xbf3ec000}, {0xbf3ee000}, + {0xbf3f0000}, {0xbf3f2000}, {0xbf3f4000}, {0xbf3f6000}, + {0xbf3f8000}, {0xbf3fa000}, {0xbf3fc000}, {0xbf3fe000}, + {0xbf400000}, {0xbf402000}, {0xbf404000}, {0xbf406000}, + {0xbf408000}, {0xbf40a000}, {0xbf40c000}, {0xbf40e000}, + {0xbf410000}, {0xbf412000}, {0xbf414000}, {0xbf416000}, + {0xbf418000}, {0xbf41a000}, {0xbf41c000}, {0xbf41e000}, + {0xbf420000}, {0xbf422000}, {0xbf424000}, {0xbf426000}, + {0xbf428000}, {0xbf42a000}, {0xbf42c000}, {0xbf42e000}, + {0xbf430000}, {0xbf432000}, {0xbf434000}, {0xbf436000}, + {0xbf438000}, {0xbf43a000}, {0xbf43c000}, {0xbf43e000}, + {0xbf440000}, {0xbf442000}, {0xbf444000}, {0xbf446000}, + {0xbf448000}, {0xbf44a000}, {0xbf44c000}, {0xbf44e000}, + {0xbf450000}, {0xbf452000}, {0xbf454000}, {0xbf456000}, + {0xbf458000}, {0xbf45a000}, {0xbf45c000}, {0xbf45e000}, + {0xbf460000}, {0xbf462000}, {0xbf464000}, {0xbf466000}, + {0xbf468000}, {0xbf46a000}, {0xbf46c000}, {0xbf46e000}, + {0xbf470000}, {0xbf472000}, {0xbf474000}, {0xbf476000}, + {0xbf478000}, {0xbf47a000}, {0xbf47c000}, {0xbf47e000}, + {0xbf480000}, {0xbf482000}, {0xbf484000}, {0xbf486000}, + {0xbf488000}, {0xbf48a000}, {0xbf48c000}, {0xbf48e000}, + {0xbf490000}, {0xbf492000}, {0xbf494000}, {0xbf496000}, + {0xbf498000}, {0xbf49a000}, {0xbf49c000}, {0xbf49e000}, + {0xbf4a0000}, {0xbf4a2000}, {0xbf4a4000}, {0xbf4a6000}, + {0xbf4a8000}, {0xbf4aa000}, {0xbf4ac000}, {0xbf4ae000}, + {0xbf4b0000}, {0xbf4b2000}, {0xbf4b4000}, {0xbf4b6000}, + {0xbf4b8000}, {0xbf4ba000}, {0xbf4bc000}, {0xbf4be000}, + {0xbf4c0000}, {0xbf4c2000}, {0xbf4c4000}, {0xbf4c6000}, + {0xbf4c8000}, {0xbf4ca000}, {0xbf4cc000}, {0xbf4ce000}, + {0xbf4d0000}, {0xbf4d2000}, {0xbf4d4000}, {0xbf4d6000}, + {0xbf4d8000}, {0xbf4da000}, {0xbf4dc000}, {0xbf4de000}, + {0xbf4e0000}, {0xbf4e2000}, {0xbf4e4000}, {0xbf4e6000}, + {0xbf4e8000}, {0xbf4ea000}, {0xbf4ec000}, {0xbf4ee000}, + {0xbf4f0000}, {0xbf4f2000}, {0xbf4f4000}, {0xbf4f6000}, + {0xbf4f8000}, {0xbf4fa000}, {0xbf4fc000}, {0xbf4fe000}, + {0xbf500000}, {0xbf502000}, {0xbf504000}, {0xbf506000}, + {0xbf508000}, {0xbf50a000}, {0xbf50c000}, {0xbf50e000}, + {0xbf510000}, {0xbf512000}, {0xbf514000}, {0xbf516000}, + {0xbf518000}, {0xbf51a000}, {0xbf51c000}, {0xbf51e000}, + {0xbf520000}, {0xbf522000}, {0xbf524000}, {0xbf526000}, + {0xbf528000}, {0xbf52a000}, {0xbf52c000}, {0xbf52e000}, + {0xbf530000}, {0xbf532000}, {0xbf534000}, {0xbf536000}, + {0xbf538000}, {0xbf53a000}, {0xbf53c000}, {0xbf53e000}, + {0xbf540000}, {0xbf542000}, {0xbf544000}, {0xbf546000}, + {0xbf548000}, {0xbf54a000}, {0xbf54c000}, {0xbf54e000}, + {0xbf550000}, {0xbf552000}, {0xbf554000}, {0xbf556000}, + {0xbf558000}, {0xbf55a000}, {0xbf55c000}, {0xbf55e000}, + {0xbf560000}, {0xbf562000}, {0xbf564000}, {0xbf566000}, + {0xbf568000}, {0xbf56a000}, {0xbf56c000}, {0xbf56e000}, + {0xbf570000}, {0xbf572000}, {0xbf574000}, {0xbf576000}, + {0xbf578000}, {0xbf57a000}, {0xbf57c000}, {0xbf57e000}, + {0xbf580000}, {0xbf582000}, {0xbf584000}, {0xbf586000}, + {0xbf588000}, {0xbf58a000}, {0xbf58c000}, {0xbf58e000}, + {0xbf590000}, {0xbf592000}, {0xbf594000}, {0xbf596000}, + {0xbf598000}, {0xbf59a000}, {0xbf59c000}, {0xbf59e000}, + {0xbf5a0000}, {0xbf5a2000}, {0xbf5a4000}, {0xbf5a6000}, + {0xbf5a8000}, {0xbf5aa000}, {0xbf5ac000}, {0xbf5ae000}, + {0xbf5b0000}, {0xbf5b2000}, {0xbf5b4000}, {0xbf5b6000}, + {0xbf5b8000}, {0xbf5ba000}, {0xbf5bc000}, {0xbf5be000}, + {0xbf5c0000}, {0xbf5c2000}, {0xbf5c4000}, {0xbf5c6000}, + {0xbf5c8000}, {0xbf5ca000}, {0xbf5cc000}, {0xbf5ce000}, + {0xbf5d0000}, {0xbf5d2000}, {0xbf5d4000}, {0xbf5d6000}, + {0xbf5d8000}, {0xbf5da000}, {0xbf5dc000}, {0xbf5de000}, + {0xbf5e0000}, {0xbf5e2000}, {0xbf5e4000}, {0xbf5e6000}, + {0xbf5e8000}, {0xbf5ea000}, {0xbf5ec000}, {0xbf5ee000}, + {0xbf5f0000}, {0xbf5f2000}, {0xbf5f4000}, {0xbf5f6000}, + {0xbf5f8000}, {0xbf5fa000}, {0xbf5fc000}, {0xbf5fe000}, + {0xbf600000}, {0xbf602000}, {0xbf604000}, {0xbf606000}, + {0xbf608000}, {0xbf60a000}, {0xbf60c000}, {0xbf60e000}, + {0xbf610000}, {0xbf612000}, {0xbf614000}, {0xbf616000}, + {0xbf618000}, {0xbf61a000}, {0xbf61c000}, {0xbf61e000}, + {0xbf620000}, {0xbf622000}, {0xbf624000}, {0xbf626000}, + {0xbf628000}, {0xbf62a000}, {0xbf62c000}, {0xbf62e000}, + {0xbf630000}, {0xbf632000}, {0xbf634000}, {0xbf636000}, + {0xbf638000}, {0xbf63a000}, {0xbf63c000}, {0xbf63e000}, + {0xbf640000}, {0xbf642000}, {0xbf644000}, {0xbf646000}, + {0xbf648000}, {0xbf64a000}, {0xbf64c000}, {0xbf64e000}, + {0xbf650000}, {0xbf652000}, {0xbf654000}, {0xbf656000}, + {0xbf658000}, {0xbf65a000}, {0xbf65c000}, {0xbf65e000}, + {0xbf660000}, {0xbf662000}, {0xbf664000}, {0xbf666000}, + {0xbf668000}, {0xbf66a000}, {0xbf66c000}, {0xbf66e000}, + {0xbf670000}, {0xbf672000}, {0xbf674000}, {0xbf676000}, + {0xbf678000}, {0xbf67a000}, {0xbf67c000}, {0xbf67e000}, + {0xbf680000}, {0xbf682000}, {0xbf684000}, {0xbf686000}, + {0xbf688000}, {0xbf68a000}, {0xbf68c000}, {0xbf68e000}, + {0xbf690000}, {0xbf692000}, {0xbf694000}, {0xbf696000}, + {0xbf698000}, {0xbf69a000}, {0xbf69c000}, {0xbf69e000}, + {0xbf6a0000}, {0xbf6a2000}, {0xbf6a4000}, {0xbf6a6000}, + {0xbf6a8000}, {0xbf6aa000}, {0xbf6ac000}, {0xbf6ae000}, + {0xbf6b0000}, {0xbf6b2000}, {0xbf6b4000}, {0xbf6b6000}, + {0xbf6b8000}, {0xbf6ba000}, {0xbf6bc000}, {0xbf6be000}, + {0xbf6c0000}, {0xbf6c2000}, {0xbf6c4000}, {0xbf6c6000}, + {0xbf6c8000}, {0xbf6ca000}, {0xbf6cc000}, {0xbf6ce000}, + {0xbf6d0000}, {0xbf6d2000}, {0xbf6d4000}, {0xbf6d6000}, + {0xbf6d8000}, {0xbf6da000}, {0xbf6dc000}, {0xbf6de000}, + {0xbf6e0000}, {0xbf6e2000}, {0xbf6e4000}, {0xbf6e6000}, + {0xbf6e8000}, {0xbf6ea000}, {0xbf6ec000}, {0xbf6ee000}, + {0xbf6f0000}, {0xbf6f2000}, {0xbf6f4000}, {0xbf6f6000}, + {0xbf6f8000}, {0xbf6fa000}, {0xbf6fc000}, {0xbf6fe000}, + {0xbf700000}, {0xbf702000}, {0xbf704000}, {0xbf706000}, + {0xbf708000}, {0xbf70a000}, {0xbf70c000}, {0xbf70e000}, + {0xbf710000}, {0xbf712000}, {0xbf714000}, {0xbf716000}, + {0xbf718000}, {0xbf71a000}, {0xbf71c000}, {0xbf71e000}, + {0xbf720000}, {0xbf722000}, {0xbf724000}, {0xbf726000}, + {0xbf728000}, {0xbf72a000}, {0xbf72c000}, {0xbf72e000}, + {0xbf730000}, {0xbf732000}, {0xbf734000}, {0xbf736000}, + {0xbf738000}, {0xbf73a000}, {0xbf73c000}, {0xbf73e000}, + {0xbf740000}, {0xbf742000}, {0xbf744000}, {0xbf746000}, + {0xbf748000}, {0xbf74a000}, {0xbf74c000}, {0xbf74e000}, + {0xbf750000}, {0xbf752000}, {0xbf754000}, {0xbf756000}, + {0xbf758000}, {0xbf75a000}, {0xbf75c000}, {0xbf75e000}, + {0xbf760000}, {0xbf762000}, {0xbf764000}, {0xbf766000}, + {0xbf768000}, {0xbf76a000}, {0xbf76c000}, {0xbf76e000}, + {0xbf770000}, {0xbf772000}, {0xbf774000}, {0xbf776000}, + {0xbf778000}, {0xbf77a000}, {0xbf77c000}, {0xbf77e000}, + {0xbf780000}, {0xbf782000}, {0xbf784000}, {0xbf786000}, + {0xbf788000}, {0xbf78a000}, {0xbf78c000}, {0xbf78e000}, + {0xbf790000}, {0xbf792000}, {0xbf794000}, {0xbf796000}, + {0xbf798000}, {0xbf79a000}, {0xbf79c000}, {0xbf79e000}, + {0xbf7a0000}, {0xbf7a2000}, {0xbf7a4000}, {0xbf7a6000}, + {0xbf7a8000}, {0xbf7aa000}, {0xbf7ac000}, {0xbf7ae000}, + {0xbf7b0000}, {0xbf7b2000}, {0xbf7b4000}, {0xbf7b6000}, + {0xbf7b8000}, {0xbf7ba000}, {0xbf7bc000}, {0xbf7be000}, + {0xbf7c0000}, {0xbf7c2000}, {0xbf7c4000}, {0xbf7c6000}, + {0xbf7c8000}, {0xbf7ca000}, {0xbf7cc000}, {0xbf7ce000}, + {0xbf7d0000}, {0xbf7d2000}, {0xbf7d4000}, {0xbf7d6000}, + {0xbf7d8000}, {0xbf7da000}, {0xbf7dc000}, {0xbf7de000}, + {0xbf7e0000}, {0xbf7e2000}, {0xbf7e4000}, {0xbf7e6000}, + {0xbf7e8000}, {0xbf7ea000}, {0xbf7ec000}, {0xbf7ee000}, + {0xbf7f0000}, {0xbf7f2000}, {0xbf7f4000}, {0xbf7f6000}, + {0xbf7f8000}, {0xbf7fa000}, {0xbf7fc000}, {0xbf7fe000}, + {0xbf800000}, {0xbf802000}, {0xbf804000}, {0xbf806000}, + {0xbf808000}, {0xbf80a000}, {0xbf80c000}, {0xbf80e000}, + {0xbf810000}, {0xbf812000}, {0xbf814000}, {0xbf816000}, + {0xbf818000}, {0xbf81a000}, {0xbf81c000}, {0xbf81e000}, + {0xbf820000}, {0xbf822000}, {0xbf824000}, {0xbf826000}, + {0xbf828000}, {0xbf82a000}, {0xbf82c000}, {0xbf82e000}, + {0xbf830000}, {0xbf832000}, {0xbf834000}, {0xbf836000}, + {0xbf838000}, {0xbf83a000}, {0xbf83c000}, {0xbf83e000}, + {0xbf840000}, {0xbf842000}, {0xbf844000}, {0xbf846000}, + {0xbf848000}, {0xbf84a000}, {0xbf84c000}, {0xbf84e000}, + {0xbf850000}, {0xbf852000}, {0xbf854000}, {0xbf856000}, + {0xbf858000}, {0xbf85a000}, {0xbf85c000}, {0xbf85e000}, + {0xbf860000}, {0xbf862000}, {0xbf864000}, {0xbf866000}, + {0xbf868000}, {0xbf86a000}, {0xbf86c000}, {0xbf86e000}, + {0xbf870000}, {0xbf872000}, {0xbf874000}, {0xbf876000}, + {0xbf878000}, {0xbf87a000}, {0xbf87c000}, {0xbf87e000}, + {0xbf880000}, {0xbf882000}, {0xbf884000}, {0xbf886000}, + {0xbf888000}, {0xbf88a000}, {0xbf88c000}, {0xbf88e000}, + {0xbf890000}, {0xbf892000}, {0xbf894000}, {0xbf896000}, + {0xbf898000}, {0xbf89a000}, {0xbf89c000}, {0xbf89e000}, + {0xbf8a0000}, {0xbf8a2000}, {0xbf8a4000}, {0xbf8a6000}, + {0xbf8a8000}, {0xbf8aa000}, {0xbf8ac000}, {0xbf8ae000}, + {0xbf8b0000}, {0xbf8b2000}, {0xbf8b4000}, {0xbf8b6000}, + {0xbf8b8000}, {0xbf8ba000}, {0xbf8bc000}, {0xbf8be000}, + {0xbf8c0000}, {0xbf8c2000}, {0xbf8c4000}, {0xbf8c6000}, + {0xbf8c8000}, {0xbf8ca000}, {0xbf8cc000}, {0xbf8ce000}, + {0xbf8d0000}, {0xbf8d2000}, {0xbf8d4000}, {0xbf8d6000}, + {0xbf8d8000}, {0xbf8da000}, {0xbf8dc000}, {0xbf8de000}, + {0xbf8e0000}, {0xbf8e2000}, {0xbf8e4000}, {0xbf8e6000}, + {0xbf8e8000}, {0xbf8ea000}, {0xbf8ec000}, {0xbf8ee000}, + {0xbf8f0000}, {0xbf8f2000}, {0xbf8f4000}, {0xbf8f6000}, + {0xbf8f8000}, {0xbf8fa000}, {0xbf8fc000}, {0xbf8fe000}, + {0xbf900000}, {0xbf902000}, {0xbf904000}, {0xbf906000}, + {0xbf908000}, {0xbf90a000}, {0xbf90c000}, {0xbf90e000}, + {0xbf910000}, {0xbf912000}, {0xbf914000}, {0xbf916000}, + {0xbf918000}, {0xbf91a000}, {0xbf91c000}, {0xbf91e000}, + {0xbf920000}, {0xbf922000}, {0xbf924000}, {0xbf926000}, + {0xbf928000}, {0xbf92a000}, {0xbf92c000}, {0xbf92e000}, + {0xbf930000}, {0xbf932000}, {0xbf934000}, {0xbf936000}, + {0xbf938000}, {0xbf93a000}, {0xbf93c000}, {0xbf93e000}, + {0xbf940000}, {0xbf942000}, {0xbf944000}, {0xbf946000}, + {0xbf948000}, {0xbf94a000}, {0xbf94c000}, {0xbf94e000}, + {0xbf950000}, {0xbf952000}, {0xbf954000}, {0xbf956000}, + {0xbf958000}, {0xbf95a000}, {0xbf95c000}, {0xbf95e000}, + {0xbf960000}, {0xbf962000}, {0xbf964000}, {0xbf966000}, + {0xbf968000}, {0xbf96a000}, {0xbf96c000}, {0xbf96e000}, + {0xbf970000}, {0xbf972000}, {0xbf974000}, {0xbf976000}, + {0xbf978000}, {0xbf97a000}, {0xbf97c000}, {0xbf97e000}, + {0xbf980000}, {0xbf982000}, {0xbf984000}, {0xbf986000}, + {0xbf988000}, {0xbf98a000}, {0xbf98c000}, {0xbf98e000}, + {0xbf990000}, {0xbf992000}, {0xbf994000}, {0xbf996000}, + {0xbf998000}, {0xbf99a000}, {0xbf99c000}, {0xbf99e000}, + {0xbf9a0000}, {0xbf9a2000}, {0xbf9a4000}, {0xbf9a6000}, + {0xbf9a8000}, {0xbf9aa000}, {0xbf9ac000}, {0xbf9ae000}, + {0xbf9b0000}, {0xbf9b2000}, {0xbf9b4000}, {0xbf9b6000}, + {0xbf9b8000}, {0xbf9ba000}, {0xbf9bc000}, {0xbf9be000}, + {0xbf9c0000}, {0xbf9c2000}, {0xbf9c4000}, {0xbf9c6000}, + {0xbf9c8000}, {0xbf9ca000}, {0xbf9cc000}, {0xbf9ce000}, + {0xbf9d0000}, {0xbf9d2000}, {0xbf9d4000}, {0xbf9d6000}, + {0xbf9d8000}, {0xbf9da000}, {0xbf9dc000}, {0xbf9de000}, + {0xbf9e0000}, {0xbf9e2000}, {0xbf9e4000}, {0xbf9e6000}, + {0xbf9e8000}, {0xbf9ea000}, {0xbf9ec000}, {0xbf9ee000}, + {0xbf9f0000}, {0xbf9f2000}, {0xbf9f4000}, {0xbf9f6000}, + {0xbf9f8000}, {0xbf9fa000}, {0xbf9fc000}, {0xbf9fe000}, + {0xbfa00000}, {0xbfa02000}, {0xbfa04000}, {0xbfa06000}, + {0xbfa08000}, {0xbfa0a000}, {0xbfa0c000}, {0xbfa0e000}, + {0xbfa10000}, {0xbfa12000}, {0xbfa14000}, {0xbfa16000}, + {0xbfa18000}, {0xbfa1a000}, {0xbfa1c000}, {0xbfa1e000}, + {0xbfa20000}, {0xbfa22000}, {0xbfa24000}, {0xbfa26000}, + {0xbfa28000}, {0xbfa2a000}, {0xbfa2c000}, {0xbfa2e000}, + {0xbfa30000}, {0xbfa32000}, {0xbfa34000}, {0xbfa36000}, + {0xbfa38000}, {0xbfa3a000}, {0xbfa3c000}, {0xbfa3e000}, + {0xbfa40000}, {0xbfa42000}, {0xbfa44000}, {0xbfa46000}, + {0xbfa48000}, {0xbfa4a000}, {0xbfa4c000}, {0xbfa4e000}, + {0xbfa50000}, {0xbfa52000}, {0xbfa54000}, {0xbfa56000}, + {0xbfa58000}, {0xbfa5a000}, {0xbfa5c000}, {0xbfa5e000}, + {0xbfa60000}, {0xbfa62000}, {0xbfa64000}, {0xbfa66000}, + {0xbfa68000}, {0xbfa6a000}, {0xbfa6c000}, {0xbfa6e000}, + {0xbfa70000}, {0xbfa72000}, {0xbfa74000}, {0xbfa76000}, + {0xbfa78000}, {0xbfa7a000}, {0xbfa7c000}, {0xbfa7e000}, + {0xbfa80000}, {0xbfa82000}, {0xbfa84000}, {0xbfa86000}, + {0xbfa88000}, {0xbfa8a000}, {0xbfa8c000}, {0xbfa8e000}, + {0xbfa90000}, {0xbfa92000}, {0xbfa94000}, {0xbfa96000}, + {0xbfa98000}, {0xbfa9a000}, {0xbfa9c000}, {0xbfa9e000}, + {0xbfaa0000}, {0xbfaa2000}, {0xbfaa4000}, {0xbfaa6000}, + {0xbfaa8000}, {0xbfaaa000}, {0xbfaac000}, {0xbfaae000}, + {0xbfab0000}, {0xbfab2000}, {0xbfab4000}, {0xbfab6000}, + {0xbfab8000}, {0xbfaba000}, {0xbfabc000}, {0xbfabe000}, + {0xbfac0000}, {0xbfac2000}, {0xbfac4000}, {0xbfac6000}, + {0xbfac8000}, {0xbfaca000}, {0xbfacc000}, {0xbface000}, + {0xbfad0000}, {0xbfad2000}, {0xbfad4000}, {0xbfad6000}, + {0xbfad8000}, {0xbfada000}, {0xbfadc000}, {0xbfade000}, + {0xbfae0000}, {0xbfae2000}, {0xbfae4000}, {0xbfae6000}, + {0xbfae8000}, {0xbfaea000}, {0xbfaec000}, {0xbfaee000}, + {0xbfaf0000}, {0xbfaf2000}, {0xbfaf4000}, {0xbfaf6000}, + {0xbfaf8000}, {0xbfafa000}, {0xbfafc000}, {0xbfafe000}, + {0xbfb00000}, {0xbfb02000}, {0xbfb04000}, {0xbfb06000}, + {0xbfb08000}, {0xbfb0a000}, {0xbfb0c000}, {0xbfb0e000}, + {0xbfb10000}, {0xbfb12000}, {0xbfb14000}, {0xbfb16000}, + {0xbfb18000}, {0xbfb1a000}, {0xbfb1c000}, {0xbfb1e000}, + {0xbfb20000}, {0xbfb22000}, {0xbfb24000}, {0xbfb26000}, + {0xbfb28000}, {0xbfb2a000}, {0xbfb2c000}, {0xbfb2e000}, + {0xbfb30000}, {0xbfb32000}, {0xbfb34000}, {0xbfb36000}, + {0xbfb38000}, {0xbfb3a000}, {0xbfb3c000}, {0xbfb3e000}, + {0xbfb40000}, {0xbfb42000}, {0xbfb44000}, {0xbfb46000}, + {0xbfb48000}, {0xbfb4a000}, {0xbfb4c000}, {0xbfb4e000}, + {0xbfb50000}, {0xbfb52000}, {0xbfb54000}, {0xbfb56000}, + {0xbfb58000}, {0xbfb5a000}, {0xbfb5c000}, {0xbfb5e000}, + {0xbfb60000}, {0xbfb62000}, {0xbfb64000}, {0xbfb66000}, + {0xbfb68000}, {0xbfb6a000}, {0xbfb6c000}, {0xbfb6e000}, + {0xbfb70000}, {0xbfb72000}, {0xbfb74000}, {0xbfb76000}, + {0xbfb78000}, {0xbfb7a000}, {0xbfb7c000}, {0xbfb7e000}, + {0xbfb80000}, {0xbfb82000}, {0xbfb84000}, {0xbfb86000}, + {0xbfb88000}, {0xbfb8a000}, {0xbfb8c000}, {0xbfb8e000}, + {0xbfb90000}, {0xbfb92000}, {0xbfb94000}, {0xbfb96000}, + {0xbfb98000}, {0xbfb9a000}, {0xbfb9c000}, {0xbfb9e000}, + {0xbfba0000}, {0xbfba2000}, {0xbfba4000}, {0xbfba6000}, + {0xbfba8000}, {0xbfbaa000}, {0xbfbac000}, {0xbfbae000}, + {0xbfbb0000}, {0xbfbb2000}, {0xbfbb4000}, {0xbfbb6000}, + {0xbfbb8000}, {0xbfbba000}, {0xbfbbc000}, {0xbfbbe000}, + {0xbfbc0000}, {0xbfbc2000}, {0xbfbc4000}, {0xbfbc6000}, + {0xbfbc8000}, {0xbfbca000}, {0xbfbcc000}, {0xbfbce000}, + {0xbfbd0000}, {0xbfbd2000}, {0xbfbd4000}, {0xbfbd6000}, + {0xbfbd8000}, {0xbfbda000}, {0xbfbdc000}, {0xbfbde000}, + {0xbfbe0000}, {0xbfbe2000}, {0xbfbe4000}, {0xbfbe6000}, + {0xbfbe8000}, {0xbfbea000}, {0xbfbec000}, {0xbfbee000}, + {0xbfbf0000}, {0xbfbf2000}, {0xbfbf4000}, {0xbfbf6000}, + {0xbfbf8000}, {0xbfbfa000}, {0xbfbfc000}, {0xbfbfe000}, + {0xbfc00000}, {0xbfc02000}, {0xbfc04000}, {0xbfc06000}, + {0xbfc08000}, {0xbfc0a000}, {0xbfc0c000}, {0xbfc0e000}, + {0xbfc10000}, {0xbfc12000}, {0xbfc14000}, {0xbfc16000}, + {0xbfc18000}, {0xbfc1a000}, {0xbfc1c000}, {0xbfc1e000}, + {0xbfc20000}, {0xbfc22000}, {0xbfc24000}, {0xbfc26000}, + {0xbfc28000}, {0xbfc2a000}, {0xbfc2c000}, {0xbfc2e000}, + {0xbfc30000}, {0xbfc32000}, {0xbfc34000}, {0xbfc36000}, + {0xbfc38000}, {0xbfc3a000}, {0xbfc3c000}, {0xbfc3e000}, + {0xbfc40000}, {0xbfc42000}, {0xbfc44000}, {0xbfc46000}, + {0xbfc48000}, {0xbfc4a000}, {0xbfc4c000}, {0xbfc4e000}, + {0xbfc50000}, {0xbfc52000}, {0xbfc54000}, {0xbfc56000}, + {0xbfc58000}, {0xbfc5a000}, {0xbfc5c000}, {0xbfc5e000}, + {0xbfc60000}, {0xbfc62000}, {0xbfc64000}, {0xbfc66000}, + {0xbfc68000}, {0xbfc6a000}, {0xbfc6c000}, {0xbfc6e000}, + {0xbfc70000}, {0xbfc72000}, {0xbfc74000}, {0xbfc76000}, + {0xbfc78000}, {0xbfc7a000}, {0xbfc7c000}, {0xbfc7e000}, + {0xbfc80000}, {0xbfc82000}, {0xbfc84000}, {0xbfc86000}, + {0xbfc88000}, {0xbfc8a000}, {0xbfc8c000}, {0xbfc8e000}, + {0xbfc90000}, {0xbfc92000}, {0xbfc94000}, {0xbfc96000}, + {0xbfc98000}, {0xbfc9a000}, {0xbfc9c000}, {0xbfc9e000}, + {0xbfca0000}, {0xbfca2000}, {0xbfca4000}, {0xbfca6000}, + {0xbfca8000}, {0xbfcaa000}, {0xbfcac000}, {0xbfcae000}, + {0xbfcb0000}, {0xbfcb2000}, {0xbfcb4000}, {0xbfcb6000}, + {0xbfcb8000}, {0xbfcba000}, {0xbfcbc000}, {0xbfcbe000}, + {0xbfcc0000}, {0xbfcc2000}, {0xbfcc4000}, {0xbfcc6000}, + {0xbfcc8000}, {0xbfcca000}, {0xbfccc000}, {0xbfcce000}, + {0xbfcd0000}, {0xbfcd2000}, {0xbfcd4000}, {0xbfcd6000}, + {0xbfcd8000}, {0xbfcda000}, {0xbfcdc000}, {0xbfcde000}, + {0xbfce0000}, {0xbfce2000}, {0xbfce4000}, {0xbfce6000}, + {0xbfce8000}, {0xbfcea000}, {0xbfcec000}, {0xbfcee000}, + {0xbfcf0000}, {0xbfcf2000}, {0xbfcf4000}, {0xbfcf6000}, + {0xbfcf8000}, {0xbfcfa000}, {0xbfcfc000}, {0xbfcfe000}, + {0xbfd00000}, {0xbfd02000}, {0xbfd04000}, {0xbfd06000}, + {0xbfd08000}, {0xbfd0a000}, {0xbfd0c000}, {0xbfd0e000}, + {0xbfd10000}, {0xbfd12000}, {0xbfd14000}, {0xbfd16000}, + {0xbfd18000}, {0xbfd1a000}, {0xbfd1c000}, {0xbfd1e000}, + {0xbfd20000}, {0xbfd22000}, {0xbfd24000}, {0xbfd26000}, + {0xbfd28000}, {0xbfd2a000}, {0xbfd2c000}, {0xbfd2e000}, + {0xbfd30000}, {0xbfd32000}, {0xbfd34000}, {0xbfd36000}, + {0xbfd38000}, {0xbfd3a000}, {0xbfd3c000}, {0xbfd3e000}, + {0xbfd40000}, {0xbfd42000}, {0xbfd44000}, {0xbfd46000}, + {0xbfd48000}, {0xbfd4a000}, {0xbfd4c000}, {0xbfd4e000}, + {0xbfd50000}, {0xbfd52000}, {0xbfd54000}, {0xbfd56000}, + {0xbfd58000}, {0xbfd5a000}, {0xbfd5c000}, {0xbfd5e000}, + {0xbfd60000}, {0xbfd62000}, {0xbfd64000}, {0xbfd66000}, + {0xbfd68000}, {0xbfd6a000}, {0xbfd6c000}, {0xbfd6e000}, + {0xbfd70000}, {0xbfd72000}, {0xbfd74000}, {0xbfd76000}, + {0xbfd78000}, {0xbfd7a000}, {0xbfd7c000}, {0xbfd7e000}, + {0xbfd80000}, {0xbfd82000}, {0xbfd84000}, {0xbfd86000}, + {0xbfd88000}, {0xbfd8a000}, {0xbfd8c000}, {0xbfd8e000}, + {0xbfd90000}, {0xbfd92000}, {0xbfd94000}, {0xbfd96000}, + {0xbfd98000}, {0xbfd9a000}, {0xbfd9c000}, {0xbfd9e000}, + {0xbfda0000}, {0xbfda2000}, {0xbfda4000}, {0xbfda6000}, + {0xbfda8000}, {0xbfdaa000}, {0xbfdac000}, {0xbfdae000}, + {0xbfdb0000}, {0xbfdb2000}, {0xbfdb4000}, {0xbfdb6000}, + {0xbfdb8000}, {0xbfdba000}, {0xbfdbc000}, {0xbfdbe000}, + {0xbfdc0000}, {0xbfdc2000}, {0xbfdc4000}, {0xbfdc6000}, + {0xbfdc8000}, {0xbfdca000}, {0xbfdcc000}, {0xbfdce000}, + {0xbfdd0000}, {0xbfdd2000}, {0xbfdd4000}, {0xbfdd6000}, + {0xbfdd8000}, {0xbfdda000}, {0xbfddc000}, {0xbfdde000}, + {0xbfde0000}, {0xbfde2000}, {0xbfde4000}, {0xbfde6000}, + {0xbfde8000}, {0xbfdea000}, {0xbfdec000}, {0xbfdee000}, + {0xbfdf0000}, {0xbfdf2000}, {0xbfdf4000}, {0xbfdf6000}, + {0xbfdf8000}, {0xbfdfa000}, {0xbfdfc000}, {0xbfdfe000}, + {0xbfe00000}, {0xbfe02000}, {0xbfe04000}, {0xbfe06000}, + {0xbfe08000}, {0xbfe0a000}, {0xbfe0c000}, {0xbfe0e000}, + {0xbfe10000}, {0xbfe12000}, {0xbfe14000}, {0xbfe16000}, + {0xbfe18000}, {0xbfe1a000}, {0xbfe1c000}, {0xbfe1e000}, + {0xbfe20000}, {0xbfe22000}, {0xbfe24000}, {0xbfe26000}, + {0xbfe28000}, {0xbfe2a000}, {0xbfe2c000}, {0xbfe2e000}, + {0xbfe30000}, {0xbfe32000}, {0xbfe34000}, {0xbfe36000}, + {0xbfe38000}, {0xbfe3a000}, {0xbfe3c000}, {0xbfe3e000}, + {0xbfe40000}, {0xbfe42000}, {0xbfe44000}, {0xbfe46000}, + {0xbfe48000}, {0xbfe4a000}, {0xbfe4c000}, {0xbfe4e000}, + {0xbfe50000}, {0xbfe52000}, {0xbfe54000}, {0xbfe56000}, + {0xbfe58000}, {0xbfe5a000}, {0xbfe5c000}, {0xbfe5e000}, + {0xbfe60000}, {0xbfe62000}, {0xbfe64000}, {0xbfe66000}, + {0xbfe68000}, {0xbfe6a000}, {0xbfe6c000}, {0xbfe6e000}, + {0xbfe70000}, {0xbfe72000}, {0xbfe74000}, {0xbfe76000}, + {0xbfe78000}, {0xbfe7a000}, {0xbfe7c000}, {0xbfe7e000}, + {0xbfe80000}, {0xbfe82000}, {0xbfe84000}, {0xbfe86000}, + {0xbfe88000}, {0xbfe8a000}, {0xbfe8c000}, {0xbfe8e000}, + {0xbfe90000}, {0xbfe92000}, {0xbfe94000}, {0xbfe96000}, + {0xbfe98000}, {0xbfe9a000}, {0xbfe9c000}, {0xbfe9e000}, + {0xbfea0000}, {0xbfea2000}, {0xbfea4000}, {0xbfea6000}, + {0xbfea8000}, {0xbfeaa000}, {0xbfeac000}, {0xbfeae000}, + {0xbfeb0000}, {0xbfeb2000}, {0xbfeb4000}, {0xbfeb6000}, + {0xbfeb8000}, {0xbfeba000}, {0xbfebc000}, {0xbfebe000}, + {0xbfec0000}, {0xbfec2000}, {0xbfec4000}, {0xbfec6000}, + {0xbfec8000}, {0xbfeca000}, {0xbfecc000}, {0xbfece000}, + {0xbfed0000}, {0xbfed2000}, {0xbfed4000}, {0xbfed6000}, + {0xbfed8000}, {0xbfeda000}, {0xbfedc000}, {0xbfede000}, + {0xbfee0000}, {0xbfee2000}, {0xbfee4000}, {0xbfee6000}, + {0xbfee8000}, {0xbfeea000}, {0xbfeec000}, {0xbfeee000}, + {0xbfef0000}, {0xbfef2000}, {0xbfef4000}, {0xbfef6000}, + {0xbfef8000}, {0xbfefa000}, {0xbfefc000}, {0xbfefe000}, + {0xbff00000}, {0xbff02000}, {0xbff04000}, {0xbff06000}, + {0xbff08000}, {0xbff0a000}, {0xbff0c000}, {0xbff0e000}, + {0xbff10000}, {0xbff12000}, {0xbff14000}, {0xbff16000}, + {0xbff18000}, {0xbff1a000}, {0xbff1c000}, {0xbff1e000}, + {0xbff20000}, {0xbff22000}, {0xbff24000}, {0xbff26000}, + {0xbff28000}, {0xbff2a000}, {0xbff2c000}, {0xbff2e000}, + {0xbff30000}, {0xbff32000}, {0xbff34000}, {0xbff36000}, + {0xbff38000}, {0xbff3a000}, {0xbff3c000}, {0xbff3e000}, + {0xbff40000}, {0xbff42000}, {0xbff44000}, {0xbff46000}, + {0xbff48000}, {0xbff4a000}, {0xbff4c000}, {0xbff4e000}, + {0xbff50000}, {0xbff52000}, {0xbff54000}, {0xbff56000}, + {0xbff58000}, {0xbff5a000}, {0xbff5c000}, {0xbff5e000}, + {0xbff60000}, {0xbff62000}, {0xbff64000}, {0xbff66000}, + {0xbff68000}, {0xbff6a000}, {0xbff6c000}, {0xbff6e000}, + {0xbff70000}, {0xbff72000}, {0xbff74000}, {0xbff76000}, + {0xbff78000}, {0xbff7a000}, {0xbff7c000}, {0xbff7e000}, + {0xbff80000}, {0xbff82000}, {0xbff84000}, {0xbff86000}, + {0xbff88000}, {0xbff8a000}, {0xbff8c000}, {0xbff8e000}, + {0xbff90000}, {0xbff92000}, {0xbff94000}, {0xbff96000}, + {0xbff98000}, {0xbff9a000}, {0xbff9c000}, {0xbff9e000}, + {0xbffa0000}, {0xbffa2000}, {0xbffa4000}, {0xbffa6000}, + {0xbffa8000}, {0xbffaa000}, {0xbffac000}, {0xbffae000}, + {0xbffb0000}, {0xbffb2000}, {0xbffb4000}, {0xbffb6000}, + {0xbffb8000}, {0xbffba000}, {0xbffbc000}, {0xbffbe000}, + {0xbffc0000}, {0xbffc2000}, {0xbffc4000}, {0xbffc6000}, + {0xbffc8000}, {0xbffca000}, {0xbffcc000}, {0xbffce000}, + {0xbffd0000}, {0xbffd2000}, {0xbffd4000}, {0xbffd6000}, + {0xbffd8000}, {0xbffda000}, {0xbffdc000}, {0xbffde000}, + {0xbffe0000}, {0xbffe2000}, {0xbffe4000}, {0xbffe6000}, + {0xbffe8000}, {0xbffea000}, {0xbffec000}, {0xbffee000}, + {0xbfff0000}, {0xbfff2000}, {0xbfff4000}, {0xbfff6000}, + {0xbfff8000}, {0xbfffa000}, {0xbfffc000}, {0xbfffe000}, + {0xc0000000}, {0xc0002000}, {0xc0004000}, {0xc0006000}, + {0xc0008000}, {0xc000a000}, {0xc000c000}, {0xc000e000}, + {0xc0010000}, {0xc0012000}, {0xc0014000}, {0xc0016000}, + {0xc0018000}, {0xc001a000}, {0xc001c000}, {0xc001e000}, + {0xc0020000}, {0xc0022000}, {0xc0024000}, {0xc0026000}, + {0xc0028000}, {0xc002a000}, {0xc002c000}, {0xc002e000}, + {0xc0030000}, {0xc0032000}, {0xc0034000}, {0xc0036000}, + {0xc0038000}, {0xc003a000}, {0xc003c000}, {0xc003e000}, + {0xc0040000}, {0xc0042000}, {0xc0044000}, {0xc0046000}, + {0xc0048000}, {0xc004a000}, {0xc004c000}, {0xc004e000}, + {0xc0050000}, {0xc0052000}, {0xc0054000}, {0xc0056000}, + {0xc0058000}, {0xc005a000}, {0xc005c000}, {0xc005e000}, + {0xc0060000}, {0xc0062000}, {0xc0064000}, {0xc0066000}, + {0xc0068000}, {0xc006a000}, {0xc006c000}, {0xc006e000}, + {0xc0070000}, {0xc0072000}, {0xc0074000}, {0xc0076000}, + {0xc0078000}, {0xc007a000}, {0xc007c000}, {0xc007e000}, + {0xc0080000}, {0xc0082000}, {0xc0084000}, {0xc0086000}, + {0xc0088000}, {0xc008a000}, {0xc008c000}, {0xc008e000}, + {0xc0090000}, {0xc0092000}, {0xc0094000}, {0xc0096000}, + {0xc0098000}, {0xc009a000}, {0xc009c000}, {0xc009e000}, + {0xc00a0000}, {0xc00a2000}, {0xc00a4000}, {0xc00a6000}, + {0xc00a8000}, {0xc00aa000}, {0xc00ac000}, {0xc00ae000}, + {0xc00b0000}, {0xc00b2000}, {0xc00b4000}, {0xc00b6000}, + {0xc00b8000}, {0xc00ba000}, {0xc00bc000}, {0xc00be000}, + {0xc00c0000}, {0xc00c2000}, {0xc00c4000}, {0xc00c6000}, + {0xc00c8000}, {0xc00ca000}, {0xc00cc000}, {0xc00ce000}, + {0xc00d0000}, {0xc00d2000}, {0xc00d4000}, {0xc00d6000}, + {0xc00d8000}, {0xc00da000}, {0xc00dc000}, {0xc00de000}, + {0xc00e0000}, {0xc00e2000}, {0xc00e4000}, {0xc00e6000}, + {0xc00e8000}, {0xc00ea000}, {0xc00ec000}, {0xc00ee000}, + {0xc00f0000}, {0xc00f2000}, {0xc00f4000}, {0xc00f6000}, + {0xc00f8000}, {0xc00fa000}, {0xc00fc000}, {0xc00fe000}, + {0xc0100000}, {0xc0102000}, {0xc0104000}, {0xc0106000}, + {0xc0108000}, {0xc010a000}, {0xc010c000}, {0xc010e000}, + {0xc0110000}, {0xc0112000}, {0xc0114000}, {0xc0116000}, + {0xc0118000}, {0xc011a000}, {0xc011c000}, {0xc011e000}, + {0xc0120000}, {0xc0122000}, {0xc0124000}, {0xc0126000}, + {0xc0128000}, {0xc012a000}, {0xc012c000}, {0xc012e000}, + {0xc0130000}, {0xc0132000}, {0xc0134000}, {0xc0136000}, + {0xc0138000}, {0xc013a000}, {0xc013c000}, {0xc013e000}, + {0xc0140000}, {0xc0142000}, {0xc0144000}, {0xc0146000}, + {0xc0148000}, {0xc014a000}, {0xc014c000}, {0xc014e000}, + {0xc0150000}, {0xc0152000}, {0xc0154000}, {0xc0156000}, + {0xc0158000}, {0xc015a000}, {0xc015c000}, {0xc015e000}, + {0xc0160000}, {0xc0162000}, {0xc0164000}, {0xc0166000}, + {0xc0168000}, {0xc016a000}, {0xc016c000}, {0xc016e000}, + {0xc0170000}, {0xc0172000}, {0xc0174000}, {0xc0176000}, + {0xc0178000}, {0xc017a000}, {0xc017c000}, {0xc017e000}, + {0xc0180000}, {0xc0182000}, {0xc0184000}, {0xc0186000}, + {0xc0188000}, {0xc018a000}, {0xc018c000}, {0xc018e000}, + {0xc0190000}, {0xc0192000}, {0xc0194000}, {0xc0196000}, + {0xc0198000}, {0xc019a000}, {0xc019c000}, {0xc019e000}, + {0xc01a0000}, {0xc01a2000}, {0xc01a4000}, {0xc01a6000}, + {0xc01a8000}, {0xc01aa000}, {0xc01ac000}, {0xc01ae000}, + {0xc01b0000}, {0xc01b2000}, {0xc01b4000}, {0xc01b6000}, + {0xc01b8000}, {0xc01ba000}, {0xc01bc000}, {0xc01be000}, + {0xc01c0000}, {0xc01c2000}, {0xc01c4000}, {0xc01c6000}, + {0xc01c8000}, {0xc01ca000}, {0xc01cc000}, {0xc01ce000}, + {0xc01d0000}, {0xc01d2000}, {0xc01d4000}, {0xc01d6000}, + {0xc01d8000}, {0xc01da000}, {0xc01dc000}, {0xc01de000}, + {0xc01e0000}, {0xc01e2000}, {0xc01e4000}, {0xc01e6000}, + {0xc01e8000}, {0xc01ea000}, {0xc01ec000}, {0xc01ee000}, + {0xc01f0000}, {0xc01f2000}, {0xc01f4000}, {0xc01f6000}, + {0xc01f8000}, {0xc01fa000}, {0xc01fc000}, {0xc01fe000}, + {0xc0200000}, {0xc0202000}, {0xc0204000}, {0xc0206000}, + {0xc0208000}, {0xc020a000}, {0xc020c000}, {0xc020e000}, + {0xc0210000}, {0xc0212000}, {0xc0214000}, {0xc0216000}, + {0xc0218000}, {0xc021a000}, {0xc021c000}, {0xc021e000}, + {0xc0220000}, {0xc0222000}, {0xc0224000}, {0xc0226000}, + {0xc0228000}, {0xc022a000}, {0xc022c000}, {0xc022e000}, + {0xc0230000}, {0xc0232000}, {0xc0234000}, {0xc0236000}, + {0xc0238000}, {0xc023a000}, {0xc023c000}, {0xc023e000}, + {0xc0240000}, {0xc0242000}, {0xc0244000}, {0xc0246000}, + {0xc0248000}, {0xc024a000}, {0xc024c000}, {0xc024e000}, + {0xc0250000}, {0xc0252000}, {0xc0254000}, {0xc0256000}, + {0xc0258000}, {0xc025a000}, {0xc025c000}, {0xc025e000}, + {0xc0260000}, {0xc0262000}, {0xc0264000}, {0xc0266000}, + {0xc0268000}, {0xc026a000}, {0xc026c000}, {0xc026e000}, + {0xc0270000}, {0xc0272000}, {0xc0274000}, {0xc0276000}, + {0xc0278000}, {0xc027a000}, {0xc027c000}, {0xc027e000}, + {0xc0280000}, {0xc0282000}, {0xc0284000}, {0xc0286000}, + {0xc0288000}, {0xc028a000}, {0xc028c000}, {0xc028e000}, + {0xc0290000}, {0xc0292000}, {0xc0294000}, {0xc0296000}, + {0xc0298000}, {0xc029a000}, {0xc029c000}, {0xc029e000}, + {0xc02a0000}, {0xc02a2000}, {0xc02a4000}, {0xc02a6000}, + {0xc02a8000}, {0xc02aa000}, {0xc02ac000}, {0xc02ae000}, + {0xc02b0000}, {0xc02b2000}, {0xc02b4000}, {0xc02b6000}, + {0xc02b8000}, {0xc02ba000}, {0xc02bc000}, {0xc02be000}, + {0xc02c0000}, {0xc02c2000}, {0xc02c4000}, {0xc02c6000}, + {0xc02c8000}, {0xc02ca000}, {0xc02cc000}, {0xc02ce000}, + {0xc02d0000}, {0xc02d2000}, {0xc02d4000}, {0xc02d6000}, + {0xc02d8000}, {0xc02da000}, {0xc02dc000}, {0xc02de000}, + {0xc02e0000}, {0xc02e2000}, {0xc02e4000}, {0xc02e6000}, + {0xc02e8000}, {0xc02ea000}, {0xc02ec000}, {0xc02ee000}, + {0xc02f0000}, {0xc02f2000}, {0xc02f4000}, {0xc02f6000}, + {0xc02f8000}, {0xc02fa000}, {0xc02fc000}, {0xc02fe000}, + {0xc0300000}, {0xc0302000}, {0xc0304000}, {0xc0306000}, + {0xc0308000}, {0xc030a000}, {0xc030c000}, {0xc030e000}, + {0xc0310000}, {0xc0312000}, {0xc0314000}, {0xc0316000}, + {0xc0318000}, {0xc031a000}, {0xc031c000}, {0xc031e000}, + {0xc0320000}, {0xc0322000}, {0xc0324000}, {0xc0326000}, + {0xc0328000}, {0xc032a000}, {0xc032c000}, {0xc032e000}, + {0xc0330000}, {0xc0332000}, {0xc0334000}, {0xc0336000}, + {0xc0338000}, {0xc033a000}, {0xc033c000}, {0xc033e000}, + {0xc0340000}, {0xc0342000}, {0xc0344000}, {0xc0346000}, + {0xc0348000}, {0xc034a000}, {0xc034c000}, {0xc034e000}, + {0xc0350000}, {0xc0352000}, {0xc0354000}, {0xc0356000}, + {0xc0358000}, {0xc035a000}, {0xc035c000}, {0xc035e000}, + {0xc0360000}, {0xc0362000}, {0xc0364000}, {0xc0366000}, + {0xc0368000}, {0xc036a000}, {0xc036c000}, {0xc036e000}, + {0xc0370000}, {0xc0372000}, {0xc0374000}, {0xc0376000}, + {0xc0378000}, {0xc037a000}, {0xc037c000}, {0xc037e000}, + {0xc0380000}, {0xc0382000}, {0xc0384000}, {0xc0386000}, + {0xc0388000}, {0xc038a000}, {0xc038c000}, {0xc038e000}, + {0xc0390000}, {0xc0392000}, {0xc0394000}, {0xc0396000}, + {0xc0398000}, {0xc039a000}, {0xc039c000}, {0xc039e000}, + {0xc03a0000}, {0xc03a2000}, {0xc03a4000}, {0xc03a6000}, + {0xc03a8000}, {0xc03aa000}, {0xc03ac000}, {0xc03ae000}, + {0xc03b0000}, {0xc03b2000}, {0xc03b4000}, {0xc03b6000}, + {0xc03b8000}, {0xc03ba000}, {0xc03bc000}, {0xc03be000}, + {0xc03c0000}, {0xc03c2000}, {0xc03c4000}, {0xc03c6000}, + {0xc03c8000}, {0xc03ca000}, {0xc03cc000}, {0xc03ce000}, + {0xc03d0000}, {0xc03d2000}, {0xc03d4000}, {0xc03d6000}, + {0xc03d8000}, {0xc03da000}, {0xc03dc000}, {0xc03de000}, + {0xc03e0000}, {0xc03e2000}, {0xc03e4000}, {0xc03e6000}, + {0xc03e8000}, {0xc03ea000}, {0xc03ec000}, {0xc03ee000}, + {0xc03f0000}, {0xc03f2000}, {0xc03f4000}, {0xc03f6000}, + {0xc03f8000}, {0xc03fa000}, {0xc03fc000}, {0xc03fe000}, + {0xc0400000}, {0xc0402000}, {0xc0404000}, {0xc0406000}, + {0xc0408000}, {0xc040a000}, {0xc040c000}, {0xc040e000}, + {0xc0410000}, {0xc0412000}, {0xc0414000}, {0xc0416000}, + {0xc0418000}, {0xc041a000}, {0xc041c000}, {0xc041e000}, + {0xc0420000}, {0xc0422000}, {0xc0424000}, {0xc0426000}, + {0xc0428000}, {0xc042a000}, {0xc042c000}, {0xc042e000}, + {0xc0430000}, {0xc0432000}, {0xc0434000}, {0xc0436000}, + {0xc0438000}, {0xc043a000}, {0xc043c000}, {0xc043e000}, + {0xc0440000}, {0xc0442000}, {0xc0444000}, {0xc0446000}, + {0xc0448000}, {0xc044a000}, {0xc044c000}, {0xc044e000}, + {0xc0450000}, {0xc0452000}, {0xc0454000}, {0xc0456000}, + {0xc0458000}, {0xc045a000}, {0xc045c000}, {0xc045e000}, + {0xc0460000}, {0xc0462000}, {0xc0464000}, {0xc0466000}, + {0xc0468000}, {0xc046a000}, {0xc046c000}, {0xc046e000}, + {0xc0470000}, {0xc0472000}, {0xc0474000}, {0xc0476000}, + {0xc0478000}, {0xc047a000}, {0xc047c000}, {0xc047e000}, + {0xc0480000}, {0xc0482000}, {0xc0484000}, {0xc0486000}, + {0xc0488000}, {0xc048a000}, {0xc048c000}, {0xc048e000}, + {0xc0490000}, {0xc0492000}, {0xc0494000}, {0xc0496000}, + {0xc0498000}, {0xc049a000}, {0xc049c000}, {0xc049e000}, + {0xc04a0000}, {0xc04a2000}, {0xc04a4000}, {0xc04a6000}, + {0xc04a8000}, {0xc04aa000}, {0xc04ac000}, {0xc04ae000}, + {0xc04b0000}, {0xc04b2000}, {0xc04b4000}, {0xc04b6000}, + {0xc04b8000}, {0xc04ba000}, {0xc04bc000}, {0xc04be000}, + {0xc04c0000}, {0xc04c2000}, {0xc04c4000}, {0xc04c6000}, + {0xc04c8000}, {0xc04ca000}, {0xc04cc000}, {0xc04ce000}, + {0xc04d0000}, {0xc04d2000}, {0xc04d4000}, {0xc04d6000}, + {0xc04d8000}, {0xc04da000}, {0xc04dc000}, {0xc04de000}, + {0xc04e0000}, {0xc04e2000}, {0xc04e4000}, {0xc04e6000}, + {0xc04e8000}, {0xc04ea000}, {0xc04ec000}, {0xc04ee000}, + {0xc04f0000}, {0xc04f2000}, {0xc04f4000}, {0xc04f6000}, + {0xc04f8000}, {0xc04fa000}, {0xc04fc000}, {0xc04fe000}, + {0xc0500000}, {0xc0502000}, {0xc0504000}, {0xc0506000}, + {0xc0508000}, {0xc050a000}, {0xc050c000}, {0xc050e000}, + {0xc0510000}, {0xc0512000}, {0xc0514000}, {0xc0516000}, + {0xc0518000}, {0xc051a000}, {0xc051c000}, {0xc051e000}, + {0xc0520000}, {0xc0522000}, {0xc0524000}, {0xc0526000}, + {0xc0528000}, {0xc052a000}, {0xc052c000}, {0xc052e000}, + {0xc0530000}, {0xc0532000}, {0xc0534000}, {0xc0536000}, + {0xc0538000}, {0xc053a000}, {0xc053c000}, {0xc053e000}, + {0xc0540000}, {0xc0542000}, {0xc0544000}, {0xc0546000}, + {0xc0548000}, {0xc054a000}, {0xc054c000}, {0xc054e000}, + {0xc0550000}, {0xc0552000}, {0xc0554000}, {0xc0556000}, + {0xc0558000}, {0xc055a000}, {0xc055c000}, {0xc055e000}, + {0xc0560000}, {0xc0562000}, {0xc0564000}, {0xc0566000}, + {0xc0568000}, {0xc056a000}, {0xc056c000}, {0xc056e000}, + {0xc0570000}, {0xc0572000}, {0xc0574000}, {0xc0576000}, + {0xc0578000}, {0xc057a000}, {0xc057c000}, {0xc057e000}, + {0xc0580000}, {0xc0582000}, {0xc0584000}, {0xc0586000}, + {0xc0588000}, {0xc058a000}, {0xc058c000}, {0xc058e000}, + {0xc0590000}, {0xc0592000}, {0xc0594000}, {0xc0596000}, + {0xc0598000}, {0xc059a000}, {0xc059c000}, {0xc059e000}, + {0xc05a0000}, {0xc05a2000}, {0xc05a4000}, {0xc05a6000}, + {0xc05a8000}, {0xc05aa000}, {0xc05ac000}, {0xc05ae000}, + {0xc05b0000}, {0xc05b2000}, {0xc05b4000}, {0xc05b6000}, + {0xc05b8000}, {0xc05ba000}, {0xc05bc000}, {0xc05be000}, + {0xc05c0000}, {0xc05c2000}, {0xc05c4000}, {0xc05c6000}, + {0xc05c8000}, {0xc05ca000}, {0xc05cc000}, {0xc05ce000}, + {0xc05d0000}, {0xc05d2000}, {0xc05d4000}, {0xc05d6000}, + {0xc05d8000}, {0xc05da000}, {0xc05dc000}, {0xc05de000}, + {0xc05e0000}, {0xc05e2000}, {0xc05e4000}, {0xc05e6000}, + {0xc05e8000}, {0xc05ea000}, {0xc05ec000}, {0xc05ee000}, + {0xc05f0000}, {0xc05f2000}, {0xc05f4000}, {0xc05f6000}, + {0xc05f8000}, {0xc05fa000}, {0xc05fc000}, {0xc05fe000}, + {0xc0600000}, {0xc0602000}, {0xc0604000}, {0xc0606000}, + {0xc0608000}, {0xc060a000}, {0xc060c000}, {0xc060e000}, + {0xc0610000}, {0xc0612000}, {0xc0614000}, {0xc0616000}, + {0xc0618000}, {0xc061a000}, {0xc061c000}, {0xc061e000}, + {0xc0620000}, {0xc0622000}, {0xc0624000}, {0xc0626000}, + {0xc0628000}, {0xc062a000}, {0xc062c000}, {0xc062e000}, + {0xc0630000}, {0xc0632000}, {0xc0634000}, {0xc0636000}, + {0xc0638000}, {0xc063a000}, {0xc063c000}, {0xc063e000}, + {0xc0640000}, {0xc0642000}, {0xc0644000}, {0xc0646000}, + {0xc0648000}, {0xc064a000}, {0xc064c000}, {0xc064e000}, + {0xc0650000}, {0xc0652000}, {0xc0654000}, {0xc0656000}, + {0xc0658000}, {0xc065a000}, {0xc065c000}, {0xc065e000}, + {0xc0660000}, {0xc0662000}, {0xc0664000}, {0xc0666000}, + {0xc0668000}, {0xc066a000}, {0xc066c000}, {0xc066e000}, + {0xc0670000}, {0xc0672000}, {0xc0674000}, {0xc0676000}, + {0xc0678000}, {0xc067a000}, {0xc067c000}, {0xc067e000}, + {0xc0680000}, {0xc0682000}, {0xc0684000}, {0xc0686000}, + {0xc0688000}, {0xc068a000}, {0xc068c000}, {0xc068e000}, + {0xc0690000}, {0xc0692000}, {0xc0694000}, {0xc0696000}, + {0xc0698000}, {0xc069a000}, {0xc069c000}, {0xc069e000}, + {0xc06a0000}, {0xc06a2000}, {0xc06a4000}, {0xc06a6000}, + {0xc06a8000}, {0xc06aa000}, {0xc06ac000}, {0xc06ae000}, + {0xc06b0000}, {0xc06b2000}, {0xc06b4000}, {0xc06b6000}, + {0xc06b8000}, {0xc06ba000}, {0xc06bc000}, {0xc06be000}, + {0xc06c0000}, {0xc06c2000}, {0xc06c4000}, {0xc06c6000}, + {0xc06c8000}, {0xc06ca000}, {0xc06cc000}, {0xc06ce000}, + {0xc06d0000}, {0xc06d2000}, {0xc06d4000}, {0xc06d6000}, + {0xc06d8000}, {0xc06da000}, {0xc06dc000}, {0xc06de000}, + {0xc06e0000}, {0xc06e2000}, {0xc06e4000}, {0xc06e6000}, + {0xc06e8000}, {0xc06ea000}, {0xc06ec000}, {0xc06ee000}, + {0xc06f0000}, {0xc06f2000}, {0xc06f4000}, {0xc06f6000}, + {0xc06f8000}, {0xc06fa000}, {0xc06fc000}, {0xc06fe000}, + {0xc0700000}, {0xc0702000}, {0xc0704000}, {0xc0706000}, + {0xc0708000}, {0xc070a000}, {0xc070c000}, {0xc070e000}, + {0xc0710000}, {0xc0712000}, {0xc0714000}, {0xc0716000}, + {0xc0718000}, {0xc071a000}, {0xc071c000}, {0xc071e000}, + {0xc0720000}, {0xc0722000}, {0xc0724000}, {0xc0726000}, + {0xc0728000}, {0xc072a000}, {0xc072c000}, {0xc072e000}, + {0xc0730000}, {0xc0732000}, {0xc0734000}, {0xc0736000}, + {0xc0738000}, {0xc073a000}, {0xc073c000}, {0xc073e000}, + {0xc0740000}, {0xc0742000}, {0xc0744000}, {0xc0746000}, + {0xc0748000}, {0xc074a000}, {0xc074c000}, {0xc074e000}, + {0xc0750000}, {0xc0752000}, {0xc0754000}, {0xc0756000}, + {0xc0758000}, {0xc075a000}, {0xc075c000}, {0xc075e000}, + {0xc0760000}, {0xc0762000}, {0xc0764000}, {0xc0766000}, + {0xc0768000}, {0xc076a000}, {0xc076c000}, {0xc076e000}, + {0xc0770000}, {0xc0772000}, {0xc0774000}, {0xc0776000}, + {0xc0778000}, {0xc077a000}, {0xc077c000}, {0xc077e000}, + {0xc0780000}, {0xc0782000}, {0xc0784000}, {0xc0786000}, + {0xc0788000}, {0xc078a000}, {0xc078c000}, {0xc078e000}, + {0xc0790000}, {0xc0792000}, {0xc0794000}, {0xc0796000}, + {0xc0798000}, {0xc079a000}, {0xc079c000}, {0xc079e000}, + {0xc07a0000}, {0xc07a2000}, {0xc07a4000}, {0xc07a6000}, + {0xc07a8000}, {0xc07aa000}, {0xc07ac000}, {0xc07ae000}, + {0xc07b0000}, {0xc07b2000}, {0xc07b4000}, {0xc07b6000}, + {0xc07b8000}, {0xc07ba000}, {0xc07bc000}, {0xc07be000}, + {0xc07c0000}, {0xc07c2000}, {0xc07c4000}, {0xc07c6000}, + {0xc07c8000}, {0xc07ca000}, {0xc07cc000}, {0xc07ce000}, + {0xc07d0000}, {0xc07d2000}, {0xc07d4000}, {0xc07d6000}, + {0xc07d8000}, {0xc07da000}, {0xc07dc000}, {0xc07de000}, + {0xc07e0000}, {0xc07e2000}, {0xc07e4000}, {0xc07e6000}, + {0xc07e8000}, {0xc07ea000}, {0xc07ec000}, {0xc07ee000}, + {0xc07f0000}, {0xc07f2000}, {0xc07f4000}, {0xc07f6000}, + {0xc07f8000}, {0xc07fa000}, {0xc07fc000}, {0xc07fe000}, + {0xc0800000}, {0xc0802000}, {0xc0804000}, {0xc0806000}, + {0xc0808000}, {0xc080a000}, {0xc080c000}, {0xc080e000}, + {0xc0810000}, {0xc0812000}, {0xc0814000}, {0xc0816000}, + {0xc0818000}, {0xc081a000}, {0xc081c000}, {0xc081e000}, + {0xc0820000}, {0xc0822000}, {0xc0824000}, {0xc0826000}, + {0xc0828000}, {0xc082a000}, {0xc082c000}, {0xc082e000}, + {0xc0830000}, {0xc0832000}, {0xc0834000}, {0xc0836000}, + {0xc0838000}, {0xc083a000}, {0xc083c000}, {0xc083e000}, + {0xc0840000}, {0xc0842000}, {0xc0844000}, {0xc0846000}, + {0xc0848000}, {0xc084a000}, {0xc084c000}, {0xc084e000}, + {0xc0850000}, {0xc0852000}, {0xc0854000}, {0xc0856000}, + {0xc0858000}, {0xc085a000}, {0xc085c000}, {0xc085e000}, + {0xc0860000}, {0xc0862000}, {0xc0864000}, {0xc0866000}, + {0xc0868000}, {0xc086a000}, {0xc086c000}, {0xc086e000}, + {0xc0870000}, {0xc0872000}, {0xc0874000}, {0xc0876000}, + {0xc0878000}, {0xc087a000}, {0xc087c000}, {0xc087e000}, + {0xc0880000}, {0xc0882000}, {0xc0884000}, {0xc0886000}, + {0xc0888000}, {0xc088a000}, {0xc088c000}, {0xc088e000}, + {0xc0890000}, {0xc0892000}, {0xc0894000}, {0xc0896000}, + {0xc0898000}, {0xc089a000}, {0xc089c000}, {0xc089e000}, + {0xc08a0000}, {0xc08a2000}, {0xc08a4000}, {0xc08a6000}, + {0xc08a8000}, {0xc08aa000}, {0xc08ac000}, {0xc08ae000}, + {0xc08b0000}, {0xc08b2000}, {0xc08b4000}, {0xc08b6000}, + {0xc08b8000}, {0xc08ba000}, {0xc08bc000}, {0xc08be000}, + {0xc08c0000}, {0xc08c2000}, {0xc08c4000}, {0xc08c6000}, + {0xc08c8000}, {0xc08ca000}, {0xc08cc000}, {0xc08ce000}, + {0xc08d0000}, {0xc08d2000}, {0xc08d4000}, {0xc08d6000}, + {0xc08d8000}, {0xc08da000}, {0xc08dc000}, {0xc08de000}, + {0xc08e0000}, {0xc08e2000}, {0xc08e4000}, {0xc08e6000}, + {0xc08e8000}, {0xc08ea000}, {0xc08ec000}, {0xc08ee000}, + {0xc08f0000}, {0xc08f2000}, {0xc08f4000}, {0xc08f6000}, + {0xc08f8000}, {0xc08fa000}, {0xc08fc000}, {0xc08fe000}, + {0xc0900000}, {0xc0902000}, {0xc0904000}, {0xc0906000}, + {0xc0908000}, {0xc090a000}, {0xc090c000}, {0xc090e000}, + {0xc0910000}, {0xc0912000}, {0xc0914000}, {0xc0916000}, + {0xc0918000}, {0xc091a000}, {0xc091c000}, {0xc091e000}, + {0xc0920000}, {0xc0922000}, {0xc0924000}, {0xc0926000}, + {0xc0928000}, {0xc092a000}, {0xc092c000}, {0xc092e000}, + {0xc0930000}, {0xc0932000}, {0xc0934000}, {0xc0936000}, + {0xc0938000}, {0xc093a000}, {0xc093c000}, {0xc093e000}, + {0xc0940000}, {0xc0942000}, {0xc0944000}, {0xc0946000}, + {0xc0948000}, {0xc094a000}, {0xc094c000}, {0xc094e000}, + {0xc0950000}, {0xc0952000}, {0xc0954000}, {0xc0956000}, + {0xc0958000}, {0xc095a000}, {0xc095c000}, {0xc095e000}, + {0xc0960000}, {0xc0962000}, {0xc0964000}, {0xc0966000}, + {0xc0968000}, {0xc096a000}, {0xc096c000}, {0xc096e000}, + {0xc0970000}, {0xc0972000}, {0xc0974000}, {0xc0976000}, + {0xc0978000}, {0xc097a000}, {0xc097c000}, {0xc097e000}, + {0xc0980000}, {0xc0982000}, {0xc0984000}, {0xc0986000}, + {0xc0988000}, {0xc098a000}, {0xc098c000}, {0xc098e000}, + {0xc0990000}, {0xc0992000}, {0xc0994000}, {0xc0996000}, + {0xc0998000}, {0xc099a000}, {0xc099c000}, {0xc099e000}, + {0xc09a0000}, {0xc09a2000}, {0xc09a4000}, {0xc09a6000}, + {0xc09a8000}, {0xc09aa000}, {0xc09ac000}, {0xc09ae000}, + {0xc09b0000}, {0xc09b2000}, {0xc09b4000}, {0xc09b6000}, + {0xc09b8000}, {0xc09ba000}, {0xc09bc000}, {0xc09be000}, + {0xc09c0000}, {0xc09c2000}, {0xc09c4000}, {0xc09c6000}, + {0xc09c8000}, {0xc09ca000}, {0xc09cc000}, {0xc09ce000}, + {0xc09d0000}, {0xc09d2000}, {0xc09d4000}, {0xc09d6000}, + {0xc09d8000}, {0xc09da000}, {0xc09dc000}, {0xc09de000}, + {0xc09e0000}, {0xc09e2000}, {0xc09e4000}, {0xc09e6000}, + {0xc09e8000}, {0xc09ea000}, {0xc09ec000}, {0xc09ee000}, + {0xc09f0000}, {0xc09f2000}, {0xc09f4000}, {0xc09f6000}, + {0xc09f8000}, {0xc09fa000}, {0xc09fc000}, {0xc09fe000}, + {0xc0a00000}, {0xc0a02000}, {0xc0a04000}, {0xc0a06000}, + {0xc0a08000}, {0xc0a0a000}, {0xc0a0c000}, {0xc0a0e000}, + {0xc0a10000}, {0xc0a12000}, {0xc0a14000}, {0xc0a16000}, + {0xc0a18000}, {0xc0a1a000}, {0xc0a1c000}, {0xc0a1e000}, + {0xc0a20000}, {0xc0a22000}, {0xc0a24000}, {0xc0a26000}, + {0xc0a28000}, {0xc0a2a000}, {0xc0a2c000}, {0xc0a2e000}, + {0xc0a30000}, {0xc0a32000}, {0xc0a34000}, {0xc0a36000}, + {0xc0a38000}, {0xc0a3a000}, {0xc0a3c000}, {0xc0a3e000}, + {0xc0a40000}, {0xc0a42000}, {0xc0a44000}, {0xc0a46000}, + {0xc0a48000}, {0xc0a4a000}, {0xc0a4c000}, {0xc0a4e000}, + {0xc0a50000}, {0xc0a52000}, {0xc0a54000}, {0xc0a56000}, + {0xc0a58000}, {0xc0a5a000}, {0xc0a5c000}, {0xc0a5e000}, + {0xc0a60000}, {0xc0a62000}, {0xc0a64000}, {0xc0a66000}, + {0xc0a68000}, {0xc0a6a000}, {0xc0a6c000}, {0xc0a6e000}, + {0xc0a70000}, {0xc0a72000}, {0xc0a74000}, {0xc0a76000}, + {0xc0a78000}, {0xc0a7a000}, {0xc0a7c000}, {0xc0a7e000}, + {0xc0a80000}, {0xc0a82000}, {0xc0a84000}, {0xc0a86000}, + {0xc0a88000}, {0xc0a8a000}, {0xc0a8c000}, {0xc0a8e000}, + {0xc0a90000}, {0xc0a92000}, {0xc0a94000}, {0xc0a96000}, + {0xc0a98000}, {0xc0a9a000}, {0xc0a9c000}, {0xc0a9e000}, + {0xc0aa0000}, {0xc0aa2000}, {0xc0aa4000}, {0xc0aa6000}, + {0xc0aa8000}, {0xc0aaa000}, {0xc0aac000}, {0xc0aae000}, + {0xc0ab0000}, {0xc0ab2000}, {0xc0ab4000}, {0xc0ab6000}, + {0xc0ab8000}, {0xc0aba000}, {0xc0abc000}, {0xc0abe000}, + {0xc0ac0000}, {0xc0ac2000}, {0xc0ac4000}, {0xc0ac6000}, + {0xc0ac8000}, {0xc0aca000}, {0xc0acc000}, {0xc0ace000}, + {0xc0ad0000}, {0xc0ad2000}, {0xc0ad4000}, {0xc0ad6000}, + {0xc0ad8000}, {0xc0ada000}, {0xc0adc000}, {0xc0ade000}, + {0xc0ae0000}, {0xc0ae2000}, {0xc0ae4000}, {0xc0ae6000}, + {0xc0ae8000}, {0xc0aea000}, {0xc0aec000}, {0xc0aee000}, + {0xc0af0000}, {0xc0af2000}, {0xc0af4000}, {0xc0af6000}, + {0xc0af8000}, {0xc0afa000}, {0xc0afc000}, {0xc0afe000}, + {0xc0b00000}, {0xc0b02000}, {0xc0b04000}, {0xc0b06000}, + {0xc0b08000}, {0xc0b0a000}, {0xc0b0c000}, {0xc0b0e000}, + {0xc0b10000}, {0xc0b12000}, {0xc0b14000}, {0xc0b16000}, + {0xc0b18000}, {0xc0b1a000}, {0xc0b1c000}, {0xc0b1e000}, + {0xc0b20000}, {0xc0b22000}, {0xc0b24000}, {0xc0b26000}, + {0xc0b28000}, {0xc0b2a000}, {0xc0b2c000}, {0xc0b2e000}, + {0xc0b30000}, {0xc0b32000}, {0xc0b34000}, {0xc0b36000}, + {0xc0b38000}, {0xc0b3a000}, {0xc0b3c000}, {0xc0b3e000}, + {0xc0b40000}, {0xc0b42000}, {0xc0b44000}, {0xc0b46000}, + {0xc0b48000}, {0xc0b4a000}, {0xc0b4c000}, {0xc0b4e000}, + {0xc0b50000}, {0xc0b52000}, {0xc0b54000}, {0xc0b56000}, + {0xc0b58000}, {0xc0b5a000}, {0xc0b5c000}, {0xc0b5e000}, + {0xc0b60000}, {0xc0b62000}, {0xc0b64000}, {0xc0b66000}, + {0xc0b68000}, {0xc0b6a000}, {0xc0b6c000}, {0xc0b6e000}, + {0xc0b70000}, {0xc0b72000}, {0xc0b74000}, {0xc0b76000}, + {0xc0b78000}, {0xc0b7a000}, {0xc0b7c000}, {0xc0b7e000}, + {0xc0b80000}, {0xc0b82000}, {0xc0b84000}, {0xc0b86000}, + {0xc0b88000}, {0xc0b8a000}, {0xc0b8c000}, {0xc0b8e000}, + {0xc0b90000}, {0xc0b92000}, {0xc0b94000}, {0xc0b96000}, + {0xc0b98000}, {0xc0b9a000}, {0xc0b9c000}, {0xc0b9e000}, + {0xc0ba0000}, {0xc0ba2000}, {0xc0ba4000}, {0xc0ba6000}, + {0xc0ba8000}, {0xc0baa000}, {0xc0bac000}, {0xc0bae000}, + {0xc0bb0000}, {0xc0bb2000}, {0xc0bb4000}, {0xc0bb6000}, + {0xc0bb8000}, {0xc0bba000}, {0xc0bbc000}, {0xc0bbe000}, + {0xc0bc0000}, {0xc0bc2000}, {0xc0bc4000}, {0xc0bc6000}, + {0xc0bc8000}, {0xc0bca000}, {0xc0bcc000}, {0xc0bce000}, + {0xc0bd0000}, {0xc0bd2000}, {0xc0bd4000}, {0xc0bd6000}, + {0xc0bd8000}, {0xc0bda000}, {0xc0bdc000}, {0xc0bde000}, + {0xc0be0000}, {0xc0be2000}, {0xc0be4000}, {0xc0be6000}, + {0xc0be8000}, {0xc0bea000}, {0xc0bec000}, {0xc0bee000}, + {0xc0bf0000}, {0xc0bf2000}, {0xc0bf4000}, {0xc0bf6000}, + {0xc0bf8000}, {0xc0bfa000}, {0xc0bfc000}, {0xc0bfe000}, + {0xc0c00000}, {0xc0c02000}, {0xc0c04000}, {0xc0c06000}, + {0xc0c08000}, {0xc0c0a000}, {0xc0c0c000}, {0xc0c0e000}, + {0xc0c10000}, {0xc0c12000}, {0xc0c14000}, {0xc0c16000}, + {0xc0c18000}, {0xc0c1a000}, {0xc0c1c000}, {0xc0c1e000}, + {0xc0c20000}, {0xc0c22000}, {0xc0c24000}, {0xc0c26000}, + {0xc0c28000}, {0xc0c2a000}, {0xc0c2c000}, {0xc0c2e000}, + {0xc0c30000}, {0xc0c32000}, {0xc0c34000}, {0xc0c36000}, + {0xc0c38000}, {0xc0c3a000}, {0xc0c3c000}, {0xc0c3e000}, + {0xc0c40000}, {0xc0c42000}, {0xc0c44000}, {0xc0c46000}, + {0xc0c48000}, {0xc0c4a000}, {0xc0c4c000}, {0xc0c4e000}, + {0xc0c50000}, {0xc0c52000}, {0xc0c54000}, {0xc0c56000}, + {0xc0c58000}, {0xc0c5a000}, {0xc0c5c000}, {0xc0c5e000}, + {0xc0c60000}, {0xc0c62000}, {0xc0c64000}, {0xc0c66000}, + {0xc0c68000}, {0xc0c6a000}, {0xc0c6c000}, {0xc0c6e000}, + {0xc0c70000}, {0xc0c72000}, {0xc0c74000}, {0xc0c76000}, + {0xc0c78000}, {0xc0c7a000}, {0xc0c7c000}, {0xc0c7e000}, + {0xc0c80000}, {0xc0c82000}, {0xc0c84000}, {0xc0c86000}, + {0xc0c88000}, {0xc0c8a000}, {0xc0c8c000}, {0xc0c8e000}, + {0xc0c90000}, {0xc0c92000}, {0xc0c94000}, {0xc0c96000}, + {0xc0c98000}, {0xc0c9a000}, {0xc0c9c000}, {0xc0c9e000}, + {0xc0ca0000}, {0xc0ca2000}, {0xc0ca4000}, {0xc0ca6000}, + {0xc0ca8000}, {0xc0caa000}, {0xc0cac000}, {0xc0cae000}, + {0xc0cb0000}, {0xc0cb2000}, {0xc0cb4000}, {0xc0cb6000}, + {0xc0cb8000}, {0xc0cba000}, {0xc0cbc000}, {0xc0cbe000}, + {0xc0cc0000}, {0xc0cc2000}, {0xc0cc4000}, {0xc0cc6000}, + {0xc0cc8000}, {0xc0cca000}, {0xc0ccc000}, {0xc0cce000}, + {0xc0cd0000}, {0xc0cd2000}, {0xc0cd4000}, {0xc0cd6000}, + {0xc0cd8000}, {0xc0cda000}, {0xc0cdc000}, {0xc0cde000}, + {0xc0ce0000}, {0xc0ce2000}, {0xc0ce4000}, {0xc0ce6000}, + {0xc0ce8000}, {0xc0cea000}, {0xc0cec000}, {0xc0cee000}, + {0xc0cf0000}, {0xc0cf2000}, {0xc0cf4000}, {0xc0cf6000}, + {0xc0cf8000}, {0xc0cfa000}, {0xc0cfc000}, {0xc0cfe000}, + {0xc0d00000}, {0xc0d02000}, {0xc0d04000}, {0xc0d06000}, + {0xc0d08000}, {0xc0d0a000}, {0xc0d0c000}, {0xc0d0e000}, + {0xc0d10000}, {0xc0d12000}, {0xc0d14000}, {0xc0d16000}, + {0xc0d18000}, {0xc0d1a000}, {0xc0d1c000}, {0xc0d1e000}, + {0xc0d20000}, {0xc0d22000}, {0xc0d24000}, {0xc0d26000}, + {0xc0d28000}, {0xc0d2a000}, {0xc0d2c000}, {0xc0d2e000}, + {0xc0d30000}, {0xc0d32000}, {0xc0d34000}, {0xc0d36000}, + {0xc0d38000}, {0xc0d3a000}, {0xc0d3c000}, {0xc0d3e000}, + {0xc0d40000}, {0xc0d42000}, {0xc0d44000}, {0xc0d46000}, + {0xc0d48000}, {0xc0d4a000}, {0xc0d4c000}, {0xc0d4e000}, + {0xc0d50000}, {0xc0d52000}, {0xc0d54000}, {0xc0d56000}, + {0xc0d58000}, {0xc0d5a000}, {0xc0d5c000}, {0xc0d5e000}, + {0xc0d60000}, {0xc0d62000}, {0xc0d64000}, {0xc0d66000}, + {0xc0d68000}, {0xc0d6a000}, {0xc0d6c000}, {0xc0d6e000}, + {0xc0d70000}, {0xc0d72000}, {0xc0d74000}, {0xc0d76000}, + {0xc0d78000}, {0xc0d7a000}, {0xc0d7c000}, {0xc0d7e000}, + {0xc0d80000}, {0xc0d82000}, {0xc0d84000}, {0xc0d86000}, + {0xc0d88000}, {0xc0d8a000}, {0xc0d8c000}, {0xc0d8e000}, + {0xc0d90000}, {0xc0d92000}, {0xc0d94000}, {0xc0d96000}, + {0xc0d98000}, {0xc0d9a000}, {0xc0d9c000}, {0xc0d9e000}, + {0xc0da0000}, {0xc0da2000}, {0xc0da4000}, {0xc0da6000}, + {0xc0da8000}, {0xc0daa000}, {0xc0dac000}, {0xc0dae000}, + {0xc0db0000}, {0xc0db2000}, {0xc0db4000}, {0xc0db6000}, + {0xc0db8000}, {0xc0dba000}, {0xc0dbc000}, {0xc0dbe000}, + {0xc0dc0000}, {0xc0dc2000}, {0xc0dc4000}, {0xc0dc6000}, + {0xc0dc8000}, {0xc0dca000}, {0xc0dcc000}, {0xc0dce000}, + {0xc0dd0000}, {0xc0dd2000}, {0xc0dd4000}, {0xc0dd6000}, + {0xc0dd8000}, {0xc0dda000}, {0xc0ddc000}, {0xc0dde000}, + {0xc0de0000}, {0xc0de2000}, {0xc0de4000}, {0xc0de6000}, + {0xc0de8000}, {0xc0dea000}, {0xc0dec000}, {0xc0dee000}, + {0xc0df0000}, {0xc0df2000}, {0xc0df4000}, {0xc0df6000}, + {0xc0df8000}, {0xc0dfa000}, {0xc0dfc000}, {0xc0dfe000}, + {0xc0e00000}, {0xc0e02000}, {0xc0e04000}, {0xc0e06000}, + {0xc0e08000}, {0xc0e0a000}, {0xc0e0c000}, {0xc0e0e000}, + {0xc0e10000}, {0xc0e12000}, {0xc0e14000}, {0xc0e16000}, + {0xc0e18000}, {0xc0e1a000}, {0xc0e1c000}, {0xc0e1e000}, + {0xc0e20000}, {0xc0e22000}, {0xc0e24000}, {0xc0e26000}, + {0xc0e28000}, {0xc0e2a000}, {0xc0e2c000}, {0xc0e2e000}, + {0xc0e30000}, {0xc0e32000}, {0xc0e34000}, {0xc0e36000}, + {0xc0e38000}, {0xc0e3a000}, {0xc0e3c000}, {0xc0e3e000}, + {0xc0e40000}, {0xc0e42000}, {0xc0e44000}, {0xc0e46000}, + {0xc0e48000}, {0xc0e4a000}, {0xc0e4c000}, {0xc0e4e000}, + {0xc0e50000}, {0xc0e52000}, {0xc0e54000}, {0xc0e56000}, + {0xc0e58000}, {0xc0e5a000}, {0xc0e5c000}, {0xc0e5e000}, + {0xc0e60000}, {0xc0e62000}, {0xc0e64000}, {0xc0e66000}, + {0xc0e68000}, {0xc0e6a000}, {0xc0e6c000}, {0xc0e6e000}, + {0xc0e70000}, {0xc0e72000}, {0xc0e74000}, {0xc0e76000}, + {0xc0e78000}, {0xc0e7a000}, {0xc0e7c000}, {0xc0e7e000}, + {0xc0e80000}, {0xc0e82000}, {0xc0e84000}, {0xc0e86000}, + {0xc0e88000}, {0xc0e8a000}, {0xc0e8c000}, {0xc0e8e000}, + {0xc0e90000}, {0xc0e92000}, {0xc0e94000}, {0xc0e96000}, + {0xc0e98000}, {0xc0e9a000}, {0xc0e9c000}, {0xc0e9e000}, + {0xc0ea0000}, {0xc0ea2000}, {0xc0ea4000}, {0xc0ea6000}, + {0xc0ea8000}, {0xc0eaa000}, {0xc0eac000}, {0xc0eae000}, + {0xc0eb0000}, {0xc0eb2000}, {0xc0eb4000}, {0xc0eb6000}, + {0xc0eb8000}, {0xc0eba000}, {0xc0ebc000}, {0xc0ebe000}, + {0xc0ec0000}, {0xc0ec2000}, {0xc0ec4000}, {0xc0ec6000}, + {0xc0ec8000}, {0xc0eca000}, {0xc0ecc000}, {0xc0ece000}, + {0xc0ed0000}, {0xc0ed2000}, {0xc0ed4000}, {0xc0ed6000}, + {0xc0ed8000}, {0xc0eda000}, {0xc0edc000}, {0xc0ede000}, + {0xc0ee0000}, {0xc0ee2000}, {0xc0ee4000}, {0xc0ee6000}, + {0xc0ee8000}, {0xc0eea000}, {0xc0eec000}, {0xc0eee000}, + {0xc0ef0000}, {0xc0ef2000}, {0xc0ef4000}, {0xc0ef6000}, + {0xc0ef8000}, {0xc0efa000}, {0xc0efc000}, {0xc0efe000}, + {0xc0f00000}, {0xc0f02000}, {0xc0f04000}, {0xc0f06000}, + {0xc0f08000}, {0xc0f0a000}, {0xc0f0c000}, {0xc0f0e000}, + {0xc0f10000}, {0xc0f12000}, {0xc0f14000}, {0xc0f16000}, + {0xc0f18000}, {0xc0f1a000}, {0xc0f1c000}, {0xc0f1e000}, + {0xc0f20000}, {0xc0f22000}, {0xc0f24000}, {0xc0f26000}, + {0xc0f28000}, {0xc0f2a000}, {0xc0f2c000}, {0xc0f2e000}, + {0xc0f30000}, {0xc0f32000}, {0xc0f34000}, {0xc0f36000}, + {0xc0f38000}, {0xc0f3a000}, {0xc0f3c000}, {0xc0f3e000}, + {0xc0f40000}, {0xc0f42000}, {0xc0f44000}, {0xc0f46000}, + {0xc0f48000}, {0xc0f4a000}, {0xc0f4c000}, {0xc0f4e000}, + {0xc0f50000}, {0xc0f52000}, {0xc0f54000}, {0xc0f56000}, + {0xc0f58000}, {0xc0f5a000}, {0xc0f5c000}, {0xc0f5e000}, + {0xc0f60000}, {0xc0f62000}, {0xc0f64000}, {0xc0f66000}, + {0xc0f68000}, {0xc0f6a000}, {0xc0f6c000}, {0xc0f6e000}, + {0xc0f70000}, {0xc0f72000}, {0xc0f74000}, {0xc0f76000}, + {0xc0f78000}, {0xc0f7a000}, {0xc0f7c000}, {0xc0f7e000}, + {0xc0f80000}, {0xc0f82000}, {0xc0f84000}, {0xc0f86000}, + {0xc0f88000}, {0xc0f8a000}, {0xc0f8c000}, {0xc0f8e000}, + {0xc0f90000}, {0xc0f92000}, {0xc0f94000}, {0xc0f96000}, + {0xc0f98000}, {0xc0f9a000}, {0xc0f9c000}, {0xc0f9e000}, + {0xc0fa0000}, {0xc0fa2000}, {0xc0fa4000}, {0xc0fa6000}, + {0xc0fa8000}, {0xc0faa000}, {0xc0fac000}, {0xc0fae000}, + {0xc0fb0000}, {0xc0fb2000}, {0xc0fb4000}, {0xc0fb6000}, + {0xc0fb8000}, {0xc0fba000}, {0xc0fbc000}, {0xc0fbe000}, + {0xc0fc0000}, {0xc0fc2000}, {0xc0fc4000}, {0xc0fc6000}, + {0xc0fc8000}, {0xc0fca000}, {0xc0fcc000}, {0xc0fce000}, + {0xc0fd0000}, {0xc0fd2000}, {0xc0fd4000}, {0xc0fd6000}, + {0xc0fd8000}, {0xc0fda000}, {0xc0fdc000}, {0xc0fde000}, + {0xc0fe0000}, {0xc0fe2000}, {0xc0fe4000}, {0xc0fe6000}, + {0xc0fe8000}, {0xc0fea000}, {0xc0fec000}, {0xc0fee000}, + {0xc0ff0000}, {0xc0ff2000}, {0xc0ff4000}, {0xc0ff6000}, + {0xc0ff8000}, {0xc0ffa000}, {0xc0ffc000}, {0xc0ffe000}, + {0xc1000000}, {0xc1002000}, {0xc1004000}, {0xc1006000}, + {0xc1008000}, {0xc100a000}, {0xc100c000}, {0xc100e000}, + {0xc1010000}, {0xc1012000}, {0xc1014000}, {0xc1016000}, + {0xc1018000}, {0xc101a000}, {0xc101c000}, {0xc101e000}, + {0xc1020000}, {0xc1022000}, {0xc1024000}, {0xc1026000}, + {0xc1028000}, {0xc102a000}, {0xc102c000}, {0xc102e000}, + {0xc1030000}, {0xc1032000}, {0xc1034000}, {0xc1036000}, + {0xc1038000}, {0xc103a000}, {0xc103c000}, {0xc103e000}, + {0xc1040000}, {0xc1042000}, {0xc1044000}, {0xc1046000}, + {0xc1048000}, {0xc104a000}, {0xc104c000}, {0xc104e000}, + {0xc1050000}, {0xc1052000}, {0xc1054000}, {0xc1056000}, + {0xc1058000}, {0xc105a000}, {0xc105c000}, {0xc105e000}, + {0xc1060000}, {0xc1062000}, {0xc1064000}, {0xc1066000}, + {0xc1068000}, {0xc106a000}, {0xc106c000}, {0xc106e000}, + {0xc1070000}, {0xc1072000}, {0xc1074000}, {0xc1076000}, + {0xc1078000}, {0xc107a000}, {0xc107c000}, {0xc107e000}, + {0xc1080000}, {0xc1082000}, {0xc1084000}, {0xc1086000}, + {0xc1088000}, {0xc108a000}, {0xc108c000}, {0xc108e000}, + {0xc1090000}, {0xc1092000}, {0xc1094000}, {0xc1096000}, + {0xc1098000}, {0xc109a000}, {0xc109c000}, {0xc109e000}, + {0xc10a0000}, {0xc10a2000}, {0xc10a4000}, {0xc10a6000}, + {0xc10a8000}, {0xc10aa000}, {0xc10ac000}, {0xc10ae000}, + {0xc10b0000}, {0xc10b2000}, {0xc10b4000}, {0xc10b6000}, + {0xc10b8000}, {0xc10ba000}, {0xc10bc000}, {0xc10be000}, + {0xc10c0000}, {0xc10c2000}, {0xc10c4000}, {0xc10c6000}, + {0xc10c8000}, {0xc10ca000}, {0xc10cc000}, {0xc10ce000}, + {0xc10d0000}, {0xc10d2000}, {0xc10d4000}, {0xc10d6000}, + {0xc10d8000}, {0xc10da000}, {0xc10dc000}, {0xc10de000}, + {0xc10e0000}, {0xc10e2000}, {0xc10e4000}, {0xc10e6000}, + {0xc10e8000}, {0xc10ea000}, {0xc10ec000}, {0xc10ee000}, + {0xc10f0000}, {0xc10f2000}, {0xc10f4000}, {0xc10f6000}, + {0xc10f8000}, {0xc10fa000}, {0xc10fc000}, {0xc10fe000}, + {0xc1100000}, {0xc1102000}, {0xc1104000}, {0xc1106000}, + {0xc1108000}, {0xc110a000}, {0xc110c000}, {0xc110e000}, + {0xc1110000}, {0xc1112000}, {0xc1114000}, {0xc1116000}, + {0xc1118000}, {0xc111a000}, {0xc111c000}, {0xc111e000}, + {0xc1120000}, {0xc1122000}, {0xc1124000}, {0xc1126000}, + {0xc1128000}, {0xc112a000}, {0xc112c000}, {0xc112e000}, + {0xc1130000}, {0xc1132000}, {0xc1134000}, {0xc1136000}, + {0xc1138000}, {0xc113a000}, {0xc113c000}, {0xc113e000}, + {0xc1140000}, {0xc1142000}, {0xc1144000}, {0xc1146000}, + {0xc1148000}, {0xc114a000}, {0xc114c000}, {0xc114e000}, + {0xc1150000}, {0xc1152000}, {0xc1154000}, {0xc1156000}, + {0xc1158000}, {0xc115a000}, {0xc115c000}, {0xc115e000}, + {0xc1160000}, {0xc1162000}, {0xc1164000}, {0xc1166000}, + {0xc1168000}, {0xc116a000}, {0xc116c000}, {0xc116e000}, + {0xc1170000}, {0xc1172000}, {0xc1174000}, {0xc1176000}, + {0xc1178000}, {0xc117a000}, {0xc117c000}, {0xc117e000}, + {0xc1180000}, {0xc1182000}, {0xc1184000}, {0xc1186000}, + {0xc1188000}, {0xc118a000}, {0xc118c000}, {0xc118e000}, + {0xc1190000}, {0xc1192000}, {0xc1194000}, {0xc1196000}, + {0xc1198000}, {0xc119a000}, {0xc119c000}, {0xc119e000}, + {0xc11a0000}, {0xc11a2000}, {0xc11a4000}, {0xc11a6000}, + {0xc11a8000}, {0xc11aa000}, {0xc11ac000}, {0xc11ae000}, + {0xc11b0000}, {0xc11b2000}, {0xc11b4000}, {0xc11b6000}, + {0xc11b8000}, {0xc11ba000}, {0xc11bc000}, {0xc11be000}, + {0xc11c0000}, {0xc11c2000}, {0xc11c4000}, {0xc11c6000}, + {0xc11c8000}, {0xc11ca000}, {0xc11cc000}, {0xc11ce000}, + {0xc11d0000}, {0xc11d2000}, {0xc11d4000}, {0xc11d6000}, + {0xc11d8000}, {0xc11da000}, {0xc11dc000}, {0xc11de000}, + {0xc11e0000}, {0xc11e2000}, {0xc11e4000}, {0xc11e6000}, + {0xc11e8000}, {0xc11ea000}, {0xc11ec000}, {0xc11ee000}, + {0xc11f0000}, {0xc11f2000}, {0xc11f4000}, {0xc11f6000}, + {0xc11f8000}, {0xc11fa000}, {0xc11fc000}, {0xc11fe000}, + {0xc1200000}, {0xc1202000}, {0xc1204000}, {0xc1206000}, + {0xc1208000}, {0xc120a000}, {0xc120c000}, {0xc120e000}, + {0xc1210000}, {0xc1212000}, {0xc1214000}, {0xc1216000}, + {0xc1218000}, {0xc121a000}, {0xc121c000}, {0xc121e000}, + {0xc1220000}, {0xc1222000}, {0xc1224000}, {0xc1226000}, + {0xc1228000}, {0xc122a000}, {0xc122c000}, {0xc122e000}, + {0xc1230000}, {0xc1232000}, {0xc1234000}, {0xc1236000}, + {0xc1238000}, {0xc123a000}, {0xc123c000}, {0xc123e000}, + {0xc1240000}, {0xc1242000}, {0xc1244000}, {0xc1246000}, + {0xc1248000}, {0xc124a000}, {0xc124c000}, {0xc124e000}, + {0xc1250000}, {0xc1252000}, {0xc1254000}, {0xc1256000}, + {0xc1258000}, {0xc125a000}, {0xc125c000}, {0xc125e000}, + {0xc1260000}, {0xc1262000}, {0xc1264000}, {0xc1266000}, + {0xc1268000}, {0xc126a000}, {0xc126c000}, {0xc126e000}, + {0xc1270000}, {0xc1272000}, {0xc1274000}, {0xc1276000}, + {0xc1278000}, {0xc127a000}, {0xc127c000}, {0xc127e000}, + {0xc1280000}, {0xc1282000}, {0xc1284000}, {0xc1286000}, + {0xc1288000}, {0xc128a000}, {0xc128c000}, {0xc128e000}, + {0xc1290000}, {0xc1292000}, {0xc1294000}, {0xc1296000}, + {0xc1298000}, {0xc129a000}, {0xc129c000}, {0xc129e000}, + {0xc12a0000}, {0xc12a2000}, {0xc12a4000}, {0xc12a6000}, + {0xc12a8000}, {0xc12aa000}, {0xc12ac000}, {0xc12ae000}, + {0xc12b0000}, {0xc12b2000}, {0xc12b4000}, {0xc12b6000}, + {0xc12b8000}, {0xc12ba000}, {0xc12bc000}, {0xc12be000}, + {0xc12c0000}, {0xc12c2000}, {0xc12c4000}, {0xc12c6000}, + {0xc12c8000}, {0xc12ca000}, {0xc12cc000}, {0xc12ce000}, + {0xc12d0000}, {0xc12d2000}, {0xc12d4000}, {0xc12d6000}, + {0xc12d8000}, {0xc12da000}, {0xc12dc000}, {0xc12de000}, + {0xc12e0000}, {0xc12e2000}, {0xc12e4000}, {0xc12e6000}, + {0xc12e8000}, {0xc12ea000}, {0xc12ec000}, {0xc12ee000}, + {0xc12f0000}, {0xc12f2000}, {0xc12f4000}, {0xc12f6000}, + {0xc12f8000}, {0xc12fa000}, {0xc12fc000}, {0xc12fe000}, + {0xc1300000}, {0xc1302000}, {0xc1304000}, {0xc1306000}, + {0xc1308000}, {0xc130a000}, {0xc130c000}, {0xc130e000}, + {0xc1310000}, {0xc1312000}, {0xc1314000}, {0xc1316000}, + {0xc1318000}, {0xc131a000}, {0xc131c000}, {0xc131e000}, + {0xc1320000}, {0xc1322000}, {0xc1324000}, {0xc1326000}, + {0xc1328000}, {0xc132a000}, {0xc132c000}, {0xc132e000}, + {0xc1330000}, {0xc1332000}, {0xc1334000}, {0xc1336000}, + {0xc1338000}, {0xc133a000}, {0xc133c000}, {0xc133e000}, + {0xc1340000}, {0xc1342000}, {0xc1344000}, {0xc1346000}, + {0xc1348000}, {0xc134a000}, {0xc134c000}, {0xc134e000}, + {0xc1350000}, {0xc1352000}, {0xc1354000}, {0xc1356000}, + {0xc1358000}, {0xc135a000}, {0xc135c000}, {0xc135e000}, + {0xc1360000}, {0xc1362000}, {0xc1364000}, {0xc1366000}, + {0xc1368000}, {0xc136a000}, {0xc136c000}, {0xc136e000}, + {0xc1370000}, {0xc1372000}, {0xc1374000}, {0xc1376000}, + {0xc1378000}, {0xc137a000}, {0xc137c000}, {0xc137e000}, + {0xc1380000}, {0xc1382000}, {0xc1384000}, {0xc1386000}, + {0xc1388000}, {0xc138a000}, {0xc138c000}, {0xc138e000}, + {0xc1390000}, {0xc1392000}, {0xc1394000}, {0xc1396000}, + {0xc1398000}, {0xc139a000}, {0xc139c000}, {0xc139e000}, + {0xc13a0000}, {0xc13a2000}, {0xc13a4000}, {0xc13a6000}, + {0xc13a8000}, {0xc13aa000}, {0xc13ac000}, {0xc13ae000}, + {0xc13b0000}, {0xc13b2000}, {0xc13b4000}, {0xc13b6000}, + {0xc13b8000}, {0xc13ba000}, {0xc13bc000}, {0xc13be000}, + {0xc13c0000}, {0xc13c2000}, {0xc13c4000}, {0xc13c6000}, + {0xc13c8000}, {0xc13ca000}, {0xc13cc000}, {0xc13ce000}, + {0xc13d0000}, {0xc13d2000}, {0xc13d4000}, {0xc13d6000}, + {0xc13d8000}, {0xc13da000}, {0xc13dc000}, {0xc13de000}, + {0xc13e0000}, {0xc13e2000}, {0xc13e4000}, {0xc13e6000}, + {0xc13e8000}, {0xc13ea000}, {0xc13ec000}, {0xc13ee000}, + {0xc13f0000}, {0xc13f2000}, {0xc13f4000}, {0xc13f6000}, + {0xc13f8000}, {0xc13fa000}, {0xc13fc000}, {0xc13fe000}, + {0xc1400000}, {0xc1402000}, {0xc1404000}, {0xc1406000}, + {0xc1408000}, {0xc140a000}, {0xc140c000}, {0xc140e000}, + {0xc1410000}, {0xc1412000}, {0xc1414000}, {0xc1416000}, + {0xc1418000}, {0xc141a000}, {0xc141c000}, {0xc141e000}, + {0xc1420000}, {0xc1422000}, {0xc1424000}, {0xc1426000}, + {0xc1428000}, {0xc142a000}, {0xc142c000}, {0xc142e000}, + {0xc1430000}, {0xc1432000}, {0xc1434000}, {0xc1436000}, + {0xc1438000}, {0xc143a000}, {0xc143c000}, {0xc143e000}, + {0xc1440000}, {0xc1442000}, {0xc1444000}, {0xc1446000}, + {0xc1448000}, {0xc144a000}, {0xc144c000}, {0xc144e000}, + {0xc1450000}, {0xc1452000}, {0xc1454000}, {0xc1456000}, + {0xc1458000}, {0xc145a000}, {0xc145c000}, {0xc145e000}, + {0xc1460000}, {0xc1462000}, {0xc1464000}, {0xc1466000}, + {0xc1468000}, {0xc146a000}, {0xc146c000}, {0xc146e000}, + {0xc1470000}, {0xc1472000}, {0xc1474000}, {0xc1476000}, + {0xc1478000}, {0xc147a000}, {0xc147c000}, {0xc147e000}, + {0xc1480000}, {0xc1482000}, {0xc1484000}, {0xc1486000}, + {0xc1488000}, {0xc148a000}, {0xc148c000}, {0xc148e000}, + {0xc1490000}, {0xc1492000}, {0xc1494000}, {0xc1496000}, + {0xc1498000}, {0xc149a000}, {0xc149c000}, {0xc149e000}, + {0xc14a0000}, {0xc14a2000}, {0xc14a4000}, {0xc14a6000}, + {0xc14a8000}, {0xc14aa000}, {0xc14ac000}, {0xc14ae000}, + {0xc14b0000}, {0xc14b2000}, {0xc14b4000}, {0xc14b6000}, + {0xc14b8000}, {0xc14ba000}, {0xc14bc000}, {0xc14be000}, + {0xc14c0000}, {0xc14c2000}, {0xc14c4000}, {0xc14c6000}, + {0xc14c8000}, {0xc14ca000}, {0xc14cc000}, {0xc14ce000}, + {0xc14d0000}, {0xc14d2000}, {0xc14d4000}, {0xc14d6000}, + {0xc14d8000}, {0xc14da000}, {0xc14dc000}, {0xc14de000}, + {0xc14e0000}, {0xc14e2000}, {0xc14e4000}, {0xc14e6000}, + {0xc14e8000}, {0xc14ea000}, {0xc14ec000}, {0xc14ee000}, + {0xc14f0000}, {0xc14f2000}, {0xc14f4000}, {0xc14f6000}, + {0xc14f8000}, {0xc14fa000}, {0xc14fc000}, {0xc14fe000}, + {0xc1500000}, {0xc1502000}, {0xc1504000}, {0xc1506000}, + {0xc1508000}, {0xc150a000}, {0xc150c000}, {0xc150e000}, + {0xc1510000}, {0xc1512000}, {0xc1514000}, {0xc1516000}, + {0xc1518000}, {0xc151a000}, {0xc151c000}, {0xc151e000}, + {0xc1520000}, {0xc1522000}, {0xc1524000}, {0xc1526000}, + {0xc1528000}, {0xc152a000}, {0xc152c000}, {0xc152e000}, + {0xc1530000}, {0xc1532000}, {0xc1534000}, {0xc1536000}, + {0xc1538000}, {0xc153a000}, {0xc153c000}, {0xc153e000}, + {0xc1540000}, {0xc1542000}, {0xc1544000}, {0xc1546000}, + {0xc1548000}, {0xc154a000}, {0xc154c000}, {0xc154e000}, + {0xc1550000}, {0xc1552000}, {0xc1554000}, {0xc1556000}, + {0xc1558000}, {0xc155a000}, {0xc155c000}, {0xc155e000}, + {0xc1560000}, {0xc1562000}, {0xc1564000}, {0xc1566000}, + {0xc1568000}, {0xc156a000}, {0xc156c000}, {0xc156e000}, + {0xc1570000}, {0xc1572000}, {0xc1574000}, {0xc1576000}, + {0xc1578000}, {0xc157a000}, {0xc157c000}, {0xc157e000}, + {0xc1580000}, {0xc1582000}, {0xc1584000}, {0xc1586000}, + {0xc1588000}, {0xc158a000}, {0xc158c000}, {0xc158e000}, + {0xc1590000}, {0xc1592000}, {0xc1594000}, {0xc1596000}, + {0xc1598000}, {0xc159a000}, {0xc159c000}, {0xc159e000}, + {0xc15a0000}, {0xc15a2000}, {0xc15a4000}, {0xc15a6000}, + {0xc15a8000}, {0xc15aa000}, {0xc15ac000}, {0xc15ae000}, + {0xc15b0000}, {0xc15b2000}, {0xc15b4000}, {0xc15b6000}, + {0xc15b8000}, {0xc15ba000}, {0xc15bc000}, {0xc15be000}, + {0xc15c0000}, {0xc15c2000}, {0xc15c4000}, {0xc15c6000}, + {0xc15c8000}, {0xc15ca000}, {0xc15cc000}, {0xc15ce000}, + {0xc15d0000}, {0xc15d2000}, {0xc15d4000}, {0xc15d6000}, + {0xc15d8000}, {0xc15da000}, {0xc15dc000}, {0xc15de000}, + {0xc15e0000}, {0xc15e2000}, {0xc15e4000}, {0xc15e6000}, + {0xc15e8000}, {0xc15ea000}, {0xc15ec000}, {0xc15ee000}, + {0xc15f0000}, {0xc15f2000}, {0xc15f4000}, {0xc15f6000}, + {0xc15f8000}, {0xc15fa000}, {0xc15fc000}, {0xc15fe000}, + {0xc1600000}, {0xc1602000}, {0xc1604000}, {0xc1606000}, + {0xc1608000}, {0xc160a000}, {0xc160c000}, {0xc160e000}, + {0xc1610000}, {0xc1612000}, {0xc1614000}, {0xc1616000}, + {0xc1618000}, {0xc161a000}, {0xc161c000}, {0xc161e000}, + {0xc1620000}, {0xc1622000}, {0xc1624000}, {0xc1626000}, + {0xc1628000}, {0xc162a000}, {0xc162c000}, {0xc162e000}, + {0xc1630000}, {0xc1632000}, {0xc1634000}, {0xc1636000}, + {0xc1638000}, {0xc163a000}, {0xc163c000}, {0xc163e000}, + {0xc1640000}, {0xc1642000}, {0xc1644000}, {0xc1646000}, + {0xc1648000}, {0xc164a000}, {0xc164c000}, {0xc164e000}, + {0xc1650000}, {0xc1652000}, {0xc1654000}, {0xc1656000}, + {0xc1658000}, {0xc165a000}, {0xc165c000}, {0xc165e000}, + {0xc1660000}, {0xc1662000}, {0xc1664000}, {0xc1666000}, + {0xc1668000}, {0xc166a000}, {0xc166c000}, {0xc166e000}, + {0xc1670000}, {0xc1672000}, {0xc1674000}, {0xc1676000}, + {0xc1678000}, {0xc167a000}, {0xc167c000}, {0xc167e000}, + {0xc1680000}, {0xc1682000}, {0xc1684000}, {0xc1686000}, + {0xc1688000}, {0xc168a000}, {0xc168c000}, {0xc168e000}, + {0xc1690000}, {0xc1692000}, {0xc1694000}, {0xc1696000}, + {0xc1698000}, {0xc169a000}, {0xc169c000}, {0xc169e000}, + {0xc16a0000}, {0xc16a2000}, {0xc16a4000}, {0xc16a6000}, + {0xc16a8000}, {0xc16aa000}, {0xc16ac000}, {0xc16ae000}, + {0xc16b0000}, {0xc16b2000}, {0xc16b4000}, {0xc16b6000}, + {0xc16b8000}, {0xc16ba000}, {0xc16bc000}, {0xc16be000}, + {0xc16c0000}, {0xc16c2000}, {0xc16c4000}, {0xc16c6000}, + {0xc16c8000}, {0xc16ca000}, {0xc16cc000}, {0xc16ce000}, + {0xc16d0000}, {0xc16d2000}, {0xc16d4000}, {0xc16d6000}, + {0xc16d8000}, {0xc16da000}, {0xc16dc000}, {0xc16de000}, + {0xc16e0000}, {0xc16e2000}, {0xc16e4000}, {0xc16e6000}, + {0xc16e8000}, {0xc16ea000}, {0xc16ec000}, {0xc16ee000}, + {0xc16f0000}, {0xc16f2000}, {0xc16f4000}, {0xc16f6000}, + {0xc16f8000}, {0xc16fa000}, {0xc16fc000}, {0xc16fe000}, + {0xc1700000}, {0xc1702000}, {0xc1704000}, {0xc1706000}, + {0xc1708000}, {0xc170a000}, {0xc170c000}, {0xc170e000}, + {0xc1710000}, {0xc1712000}, {0xc1714000}, {0xc1716000}, + {0xc1718000}, {0xc171a000}, {0xc171c000}, {0xc171e000}, + {0xc1720000}, {0xc1722000}, {0xc1724000}, {0xc1726000}, + {0xc1728000}, {0xc172a000}, {0xc172c000}, {0xc172e000}, + {0xc1730000}, {0xc1732000}, {0xc1734000}, {0xc1736000}, + {0xc1738000}, {0xc173a000}, {0xc173c000}, {0xc173e000}, + {0xc1740000}, {0xc1742000}, {0xc1744000}, {0xc1746000}, + {0xc1748000}, {0xc174a000}, {0xc174c000}, {0xc174e000}, + {0xc1750000}, {0xc1752000}, {0xc1754000}, {0xc1756000}, + {0xc1758000}, {0xc175a000}, {0xc175c000}, {0xc175e000}, + {0xc1760000}, {0xc1762000}, {0xc1764000}, {0xc1766000}, + {0xc1768000}, {0xc176a000}, {0xc176c000}, {0xc176e000}, + {0xc1770000}, {0xc1772000}, {0xc1774000}, {0xc1776000}, + {0xc1778000}, {0xc177a000}, {0xc177c000}, {0xc177e000}, + {0xc1780000}, {0xc1782000}, {0xc1784000}, {0xc1786000}, + {0xc1788000}, {0xc178a000}, {0xc178c000}, {0xc178e000}, + {0xc1790000}, {0xc1792000}, {0xc1794000}, {0xc1796000}, + {0xc1798000}, {0xc179a000}, {0xc179c000}, {0xc179e000}, + {0xc17a0000}, {0xc17a2000}, {0xc17a4000}, {0xc17a6000}, + {0xc17a8000}, {0xc17aa000}, {0xc17ac000}, {0xc17ae000}, + {0xc17b0000}, {0xc17b2000}, {0xc17b4000}, {0xc17b6000}, + {0xc17b8000}, {0xc17ba000}, {0xc17bc000}, {0xc17be000}, + {0xc17c0000}, {0xc17c2000}, {0xc17c4000}, {0xc17c6000}, + {0xc17c8000}, {0xc17ca000}, {0xc17cc000}, {0xc17ce000}, + {0xc17d0000}, {0xc17d2000}, {0xc17d4000}, {0xc17d6000}, + {0xc17d8000}, {0xc17da000}, {0xc17dc000}, {0xc17de000}, + {0xc17e0000}, {0xc17e2000}, {0xc17e4000}, {0xc17e6000}, + {0xc17e8000}, {0xc17ea000}, {0xc17ec000}, {0xc17ee000}, + {0xc17f0000}, {0xc17f2000}, {0xc17f4000}, {0xc17f6000}, + {0xc17f8000}, {0xc17fa000}, {0xc17fc000}, {0xc17fe000}, + {0xc1800000}, {0xc1802000}, {0xc1804000}, {0xc1806000}, + {0xc1808000}, {0xc180a000}, {0xc180c000}, {0xc180e000}, + {0xc1810000}, {0xc1812000}, {0xc1814000}, {0xc1816000}, + {0xc1818000}, {0xc181a000}, {0xc181c000}, {0xc181e000}, + {0xc1820000}, {0xc1822000}, {0xc1824000}, {0xc1826000}, + {0xc1828000}, {0xc182a000}, {0xc182c000}, {0xc182e000}, + {0xc1830000}, {0xc1832000}, {0xc1834000}, {0xc1836000}, + {0xc1838000}, {0xc183a000}, {0xc183c000}, {0xc183e000}, + {0xc1840000}, {0xc1842000}, {0xc1844000}, {0xc1846000}, + {0xc1848000}, {0xc184a000}, {0xc184c000}, {0xc184e000}, + {0xc1850000}, {0xc1852000}, {0xc1854000}, {0xc1856000}, + {0xc1858000}, {0xc185a000}, {0xc185c000}, {0xc185e000}, + {0xc1860000}, {0xc1862000}, {0xc1864000}, {0xc1866000}, + {0xc1868000}, {0xc186a000}, {0xc186c000}, {0xc186e000}, + {0xc1870000}, {0xc1872000}, {0xc1874000}, {0xc1876000}, + {0xc1878000}, {0xc187a000}, {0xc187c000}, {0xc187e000}, + {0xc1880000}, {0xc1882000}, {0xc1884000}, {0xc1886000}, + {0xc1888000}, {0xc188a000}, {0xc188c000}, {0xc188e000}, + {0xc1890000}, {0xc1892000}, {0xc1894000}, {0xc1896000}, + {0xc1898000}, {0xc189a000}, {0xc189c000}, {0xc189e000}, + {0xc18a0000}, {0xc18a2000}, {0xc18a4000}, {0xc18a6000}, + {0xc18a8000}, {0xc18aa000}, {0xc18ac000}, {0xc18ae000}, + {0xc18b0000}, {0xc18b2000}, {0xc18b4000}, {0xc18b6000}, + {0xc18b8000}, {0xc18ba000}, {0xc18bc000}, {0xc18be000}, + {0xc18c0000}, {0xc18c2000}, {0xc18c4000}, {0xc18c6000}, + {0xc18c8000}, {0xc18ca000}, {0xc18cc000}, {0xc18ce000}, + {0xc18d0000}, {0xc18d2000}, {0xc18d4000}, {0xc18d6000}, + {0xc18d8000}, {0xc18da000}, {0xc18dc000}, {0xc18de000}, + {0xc18e0000}, {0xc18e2000}, {0xc18e4000}, {0xc18e6000}, + {0xc18e8000}, {0xc18ea000}, {0xc18ec000}, {0xc18ee000}, + {0xc18f0000}, {0xc18f2000}, {0xc18f4000}, {0xc18f6000}, + {0xc18f8000}, {0xc18fa000}, {0xc18fc000}, {0xc18fe000}, + {0xc1900000}, {0xc1902000}, {0xc1904000}, {0xc1906000}, + {0xc1908000}, {0xc190a000}, {0xc190c000}, {0xc190e000}, + {0xc1910000}, {0xc1912000}, {0xc1914000}, {0xc1916000}, + {0xc1918000}, {0xc191a000}, {0xc191c000}, {0xc191e000}, + {0xc1920000}, {0xc1922000}, {0xc1924000}, {0xc1926000}, + {0xc1928000}, {0xc192a000}, {0xc192c000}, {0xc192e000}, + {0xc1930000}, {0xc1932000}, {0xc1934000}, {0xc1936000}, + {0xc1938000}, {0xc193a000}, {0xc193c000}, {0xc193e000}, + {0xc1940000}, {0xc1942000}, {0xc1944000}, {0xc1946000}, + {0xc1948000}, {0xc194a000}, {0xc194c000}, {0xc194e000}, + {0xc1950000}, {0xc1952000}, {0xc1954000}, {0xc1956000}, + {0xc1958000}, {0xc195a000}, {0xc195c000}, {0xc195e000}, + {0xc1960000}, {0xc1962000}, {0xc1964000}, {0xc1966000}, + {0xc1968000}, {0xc196a000}, {0xc196c000}, {0xc196e000}, + {0xc1970000}, {0xc1972000}, {0xc1974000}, {0xc1976000}, + {0xc1978000}, {0xc197a000}, {0xc197c000}, {0xc197e000}, + {0xc1980000}, {0xc1982000}, {0xc1984000}, {0xc1986000}, + {0xc1988000}, {0xc198a000}, {0xc198c000}, {0xc198e000}, + {0xc1990000}, {0xc1992000}, {0xc1994000}, {0xc1996000}, + {0xc1998000}, {0xc199a000}, {0xc199c000}, {0xc199e000}, + {0xc19a0000}, {0xc19a2000}, {0xc19a4000}, {0xc19a6000}, + {0xc19a8000}, {0xc19aa000}, {0xc19ac000}, {0xc19ae000}, + {0xc19b0000}, {0xc19b2000}, {0xc19b4000}, {0xc19b6000}, + {0xc19b8000}, {0xc19ba000}, {0xc19bc000}, {0xc19be000}, + {0xc19c0000}, {0xc19c2000}, {0xc19c4000}, {0xc19c6000}, + {0xc19c8000}, {0xc19ca000}, {0xc19cc000}, {0xc19ce000}, + {0xc19d0000}, {0xc19d2000}, {0xc19d4000}, {0xc19d6000}, + {0xc19d8000}, {0xc19da000}, {0xc19dc000}, {0xc19de000}, + {0xc19e0000}, {0xc19e2000}, {0xc19e4000}, {0xc19e6000}, + {0xc19e8000}, {0xc19ea000}, {0xc19ec000}, {0xc19ee000}, + {0xc19f0000}, {0xc19f2000}, {0xc19f4000}, {0xc19f6000}, + {0xc19f8000}, {0xc19fa000}, {0xc19fc000}, {0xc19fe000}, + {0xc1a00000}, {0xc1a02000}, {0xc1a04000}, {0xc1a06000}, + {0xc1a08000}, {0xc1a0a000}, {0xc1a0c000}, {0xc1a0e000}, + {0xc1a10000}, {0xc1a12000}, {0xc1a14000}, {0xc1a16000}, + {0xc1a18000}, {0xc1a1a000}, {0xc1a1c000}, {0xc1a1e000}, + {0xc1a20000}, {0xc1a22000}, {0xc1a24000}, {0xc1a26000}, + {0xc1a28000}, {0xc1a2a000}, {0xc1a2c000}, {0xc1a2e000}, + {0xc1a30000}, {0xc1a32000}, {0xc1a34000}, {0xc1a36000}, + {0xc1a38000}, {0xc1a3a000}, {0xc1a3c000}, {0xc1a3e000}, + {0xc1a40000}, {0xc1a42000}, {0xc1a44000}, {0xc1a46000}, + {0xc1a48000}, {0xc1a4a000}, {0xc1a4c000}, {0xc1a4e000}, + {0xc1a50000}, {0xc1a52000}, {0xc1a54000}, {0xc1a56000}, + {0xc1a58000}, {0xc1a5a000}, {0xc1a5c000}, {0xc1a5e000}, + {0xc1a60000}, {0xc1a62000}, {0xc1a64000}, {0xc1a66000}, + {0xc1a68000}, {0xc1a6a000}, {0xc1a6c000}, {0xc1a6e000}, + {0xc1a70000}, {0xc1a72000}, {0xc1a74000}, {0xc1a76000}, + {0xc1a78000}, {0xc1a7a000}, {0xc1a7c000}, {0xc1a7e000}, + {0xc1a80000}, {0xc1a82000}, {0xc1a84000}, {0xc1a86000}, + {0xc1a88000}, {0xc1a8a000}, {0xc1a8c000}, {0xc1a8e000}, + {0xc1a90000}, {0xc1a92000}, {0xc1a94000}, {0xc1a96000}, + {0xc1a98000}, {0xc1a9a000}, {0xc1a9c000}, {0xc1a9e000}, + {0xc1aa0000}, {0xc1aa2000}, {0xc1aa4000}, {0xc1aa6000}, + {0xc1aa8000}, {0xc1aaa000}, {0xc1aac000}, {0xc1aae000}, + {0xc1ab0000}, {0xc1ab2000}, {0xc1ab4000}, {0xc1ab6000}, + {0xc1ab8000}, {0xc1aba000}, {0xc1abc000}, {0xc1abe000}, + {0xc1ac0000}, {0xc1ac2000}, {0xc1ac4000}, {0xc1ac6000}, + {0xc1ac8000}, {0xc1aca000}, {0xc1acc000}, {0xc1ace000}, + {0xc1ad0000}, {0xc1ad2000}, {0xc1ad4000}, {0xc1ad6000}, + {0xc1ad8000}, {0xc1ada000}, {0xc1adc000}, {0xc1ade000}, + {0xc1ae0000}, {0xc1ae2000}, {0xc1ae4000}, {0xc1ae6000}, + {0xc1ae8000}, {0xc1aea000}, {0xc1aec000}, {0xc1aee000}, + {0xc1af0000}, {0xc1af2000}, {0xc1af4000}, {0xc1af6000}, + {0xc1af8000}, {0xc1afa000}, {0xc1afc000}, {0xc1afe000}, + {0xc1b00000}, {0xc1b02000}, {0xc1b04000}, {0xc1b06000}, + {0xc1b08000}, {0xc1b0a000}, {0xc1b0c000}, {0xc1b0e000}, + {0xc1b10000}, {0xc1b12000}, {0xc1b14000}, {0xc1b16000}, + {0xc1b18000}, {0xc1b1a000}, {0xc1b1c000}, {0xc1b1e000}, + {0xc1b20000}, {0xc1b22000}, {0xc1b24000}, {0xc1b26000}, + {0xc1b28000}, {0xc1b2a000}, {0xc1b2c000}, {0xc1b2e000}, + {0xc1b30000}, {0xc1b32000}, {0xc1b34000}, {0xc1b36000}, + {0xc1b38000}, {0xc1b3a000}, {0xc1b3c000}, {0xc1b3e000}, + {0xc1b40000}, {0xc1b42000}, {0xc1b44000}, {0xc1b46000}, + {0xc1b48000}, {0xc1b4a000}, {0xc1b4c000}, {0xc1b4e000}, + {0xc1b50000}, {0xc1b52000}, {0xc1b54000}, {0xc1b56000}, + {0xc1b58000}, {0xc1b5a000}, {0xc1b5c000}, {0xc1b5e000}, + {0xc1b60000}, {0xc1b62000}, {0xc1b64000}, {0xc1b66000}, + {0xc1b68000}, {0xc1b6a000}, {0xc1b6c000}, {0xc1b6e000}, + {0xc1b70000}, {0xc1b72000}, {0xc1b74000}, {0xc1b76000}, + {0xc1b78000}, {0xc1b7a000}, {0xc1b7c000}, {0xc1b7e000}, + {0xc1b80000}, {0xc1b82000}, {0xc1b84000}, {0xc1b86000}, + {0xc1b88000}, {0xc1b8a000}, {0xc1b8c000}, {0xc1b8e000}, + {0xc1b90000}, {0xc1b92000}, {0xc1b94000}, {0xc1b96000}, + {0xc1b98000}, {0xc1b9a000}, {0xc1b9c000}, {0xc1b9e000}, + {0xc1ba0000}, {0xc1ba2000}, {0xc1ba4000}, {0xc1ba6000}, + {0xc1ba8000}, {0xc1baa000}, {0xc1bac000}, {0xc1bae000}, + {0xc1bb0000}, {0xc1bb2000}, {0xc1bb4000}, {0xc1bb6000}, + {0xc1bb8000}, {0xc1bba000}, {0xc1bbc000}, {0xc1bbe000}, + {0xc1bc0000}, {0xc1bc2000}, {0xc1bc4000}, {0xc1bc6000}, + {0xc1bc8000}, {0xc1bca000}, {0xc1bcc000}, {0xc1bce000}, + {0xc1bd0000}, {0xc1bd2000}, {0xc1bd4000}, {0xc1bd6000}, + {0xc1bd8000}, {0xc1bda000}, {0xc1bdc000}, {0xc1bde000}, + {0xc1be0000}, {0xc1be2000}, {0xc1be4000}, {0xc1be6000}, + {0xc1be8000}, {0xc1bea000}, {0xc1bec000}, {0xc1bee000}, + {0xc1bf0000}, {0xc1bf2000}, {0xc1bf4000}, {0xc1bf6000}, + {0xc1bf8000}, {0xc1bfa000}, {0xc1bfc000}, {0xc1bfe000}, + {0xc1c00000}, {0xc1c02000}, {0xc1c04000}, {0xc1c06000}, + {0xc1c08000}, {0xc1c0a000}, {0xc1c0c000}, {0xc1c0e000}, + {0xc1c10000}, {0xc1c12000}, {0xc1c14000}, {0xc1c16000}, + {0xc1c18000}, {0xc1c1a000}, {0xc1c1c000}, {0xc1c1e000}, + {0xc1c20000}, {0xc1c22000}, {0xc1c24000}, {0xc1c26000}, + {0xc1c28000}, {0xc1c2a000}, {0xc1c2c000}, {0xc1c2e000}, + {0xc1c30000}, {0xc1c32000}, {0xc1c34000}, {0xc1c36000}, + {0xc1c38000}, {0xc1c3a000}, {0xc1c3c000}, {0xc1c3e000}, + {0xc1c40000}, {0xc1c42000}, {0xc1c44000}, {0xc1c46000}, + {0xc1c48000}, {0xc1c4a000}, {0xc1c4c000}, {0xc1c4e000}, + {0xc1c50000}, {0xc1c52000}, {0xc1c54000}, {0xc1c56000}, + {0xc1c58000}, {0xc1c5a000}, {0xc1c5c000}, {0xc1c5e000}, + {0xc1c60000}, {0xc1c62000}, {0xc1c64000}, {0xc1c66000}, + {0xc1c68000}, {0xc1c6a000}, {0xc1c6c000}, {0xc1c6e000}, + {0xc1c70000}, {0xc1c72000}, {0xc1c74000}, {0xc1c76000}, + {0xc1c78000}, {0xc1c7a000}, {0xc1c7c000}, {0xc1c7e000}, + {0xc1c80000}, {0xc1c82000}, {0xc1c84000}, {0xc1c86000}, + {0xc1c88000}, {0xc1c8a000}, {0xc1c8c000}, {0xc1c8e000}, + {0xc1c90000}, {0xc1c92000}, {0xc1c94000}, {0xc1c96000}, + {0xc1c98000}, {0xc1c9a000}, {0xc1c9c000}, {0xc1c9e000}, + {0xc1ca0000}, {0xc1ca2000}, {0xc1ca4000}, {0xc1ca6000}, + {0xc1ca8000}, {0xc1caa000}, {0xc1cac000}, {0xc1cae000}, + {0xc1cb0000}, {0xc1cb2000}, {0xc1cb4000}, {0xc1cb6000}, + {0xc1cb8000}, {0xc1cba000}, {0xc1cbc000}, {0xc1cbe000}, + {0xc1cc0000}, {0xc1cc2000}, {0xc1cc4000}, {0xc1cc6000}, + {0xc1cc8000}, {0xc1cca000}, {0xc1ccc000}, {0xc1cce000}, + {0xc1cd0000}, {0xc1cd2000}, {0xc1cd4000}, {0xc1cd6000}, + {0xc1cd8000}, {0xc1cda000}, {0xc1cdc000}, {0xc1cde000}, + {0xc1ce0000}, {0xc1ce2000}, {0xc1ce4000}, {0xc1ce6000}, + {0xc1ce8000}, {0xc1cea000}, {0xc1cec000}, {0xc1cee000}, + {0xc1cf0000}, {0xc1cf2000}, {0xc1cf4000}, {0xc1cf6000}, + {0xc1cf8000}, {0xc1cfa000}, {0xc1cfc000}, {0xc1cfe000}, + {0xc1d00000}, {0xc1d02000}, {0xc1d04000}, {0xc1d06000}, + {0xc1d08000}, {0xc1d0a000}, {0xc1d0c000}, {0xc1d0e000}, + {0xc1d10000}, {0xc1d12000}, {0xc1d14000}, {0xc1d16000}, + {0xc1d18000}, {0xc1d1a000}, {0xc1d1c000}, {0xc1d1e000}, + {0xc1d20000}, {0xc1d22000}, {0xc1d24000}, {0xc1d26000}, + {0xc1d28000}, {0xc1d2a000}, {0xc1d2c000}, {0xc1d2e000}, + {0xc1d30000}, {0xc1d32000}, {0xc1d34000}, {0xc1d36000}, + {0xc1d38000}, {0xc1d3a000}, {0xc1d3c000}, {0xc1d3e000}, + {0xc1d40000}, {0xc1d42000}, {0xc1d44000}, {0xc1d46000}, + {0xc1d48000}, {0xc1d4a000}, {0xc1d4c000}, {0xc1d4e000}, + {0xc1d50000}, {0xc1d52000}, {0xc1d54000}, {0xc1d56000}, + {0xc1d58000}, {0xc1d5a000}, {0xc1d5c000}, {0xc1d5e000}, + {0xc1d60000}, {0xc1d62000}, {0xc1d64000}, {0xc1d66000}, + {0xc1d68000}, {0xc1d6a000}, {0xc1d6c000}, {0xc1d6e000}, + {0xc1d70000}, {0xc1d72000}, {0xc1d74000}, {0xc1d76000}, + {0xc1d78000}, {0xc1d7a000}, {0xc1d7c000}, {0xc1d7e000}, + {0xc1d80000}, {0xc1d82000}, {0xc1d84000}, {0xc1d86000}, + {0xc1d88000}, {0xc1d8a000}, {0xc1d8c000}, {0xc1d8e000}, + {0xc1d90000}, {0xc1d92000}, {0xc1d94000}, {0xc1d96000}, + {0xc1d98000}, {0xc1d9a000}, {0xc1d9c000}, {0xc1d9e000}, + {0xc1da0000}, {0xc1da2000}, {0xc1da4000}, {0xc1da6000}, + {0xc1da8000}, {0xc1daa000}, {0xc1dac000}, {0xc1dae000}, + {0xc1db0000}, {0xc1db2000}, {0xc1db4000}, {0xc1db6000}, + {0xc1db8000}, {0xc1dba000}, {0xc1dbc000}, {0xc1dbe000}, + {0xc1dc0000}, {0xc1dc2000}, {0xc1dc4000}, {0xc1dc6000}, + {0xc1dc8000}, {0xc1dca000}, {0xc1dcc000}, {0xc1dce000}, + {0xc1dd0000}, {0xc1dd2000}, {0xc1dd4000}, {0xc1dd6000}, + {0xc1dd8000}, {0xc1dda000}, {0xc1ddc000}, {0xc1dde000}, + {0xc1de0000}, {0xc1de2000}, {0xc1de4000}, {0xc1de6000}, + {0xc1de8000}, {0xc1dea000}, {0xc1dec000}, {0xc1dee000}, + {0xc1df0000}, {0xc1df2000}, {0xc1df4000}, {0xc1df6000}, + {0xc1df8000}, {0xc1dfa000}, {0xc1dfc000}, {0xc1dfe000}, + {0xc1e00000}, {0xc1e02000}, {0xc1e04000}, {0xc1e06000}, + {0xc1e08000}, {0xc1e0a000}, {0xc1e0c000}, {0xc1e0e000}, + {0xc1e10000}, {0xc1e12000}, {0xc1e14000}, {0xc1e16000}, + {0xc1e18000}, {0xc1e1a000}, {0xc1e1c000}, {0xc1e1e000}, + {0xc1e20000}, {0xc1e22000}, {0xc1e24000}, {0xc1e26000}, + {0xc1e28000}, {0xc1e2a000}, {0xc1e2c000}, {0xc1e2e000}, + {0xc1e30000}, {0xc1e32000}, {0xc1e34000}, {0xc1e36000}, + {0xc1e38000}, {0xc1e3a000}, {0xc1e3c000}, {0xc1e3e000}, + {0xc1e40000}, {0xc1e42000}, {0xc1e44000}, {0xc1e46000}, + {0xc1e48000}, {0xc1e4a000}, {0xc1e4c000}, {0xc1e4e000}, + {0xc1e50000}, {0xc1e52000}, {0xc1e54000}, {0xc1e56000}, + {0xc1e58000}, {0xc1e5a000}, {0xc1e5c000}, {0xc1e5e000}, + {0xc1e60000}, {0xc1e62000}, {0xc1e64000}, {0xc1e66000}, + {0xc1e68000}, {0xc1e6a000}, {0xc1e6c000}, {0xc1e6e000}, + {0xc1e70000}, {0xc1e72000}, {0xc1e74000}, {0xc1e76000}, + {0xc1e78000}, {0xc1e7a000}, {0xc1e7c000}, {0xc1e7e000}, + {0xc1e80000}, {0xc1e82000}, {0xc1e84000}, {0xc1e86000}, + {0xc1e88000}, {0xc1e8a000}, {0xc1e8c000}, {0xc1e8e000}, + {0xc1e90000}, {0xc1e92000}, {0xc1e94000}, {0xc1e96000}, + {0xc1e98000}, {0xc1e9a000}, {0xc1e9c000}, {0xc1e9e000}, + {0xc1ea0000}, {0xc1ea2000}, {0xc1ea4000}, {0xc1ea6000}, + {0xc1ea8000}, {0xc1eaa000}, {0xc1eac000}, {0xc1eae000}, + {0xc1eb0000}, {0xc1eb2000}, {0xc1eb4000}, {0xc1eb6000}, + {0xc1eb8000}, {0xc1eba000}, {0xc1ebc000}, {0xc1ebe000}, + {0xc1ec0000}, {0xc1ec2000}, {0xc1ec4000}, {0xc1ec6000}, + {0xc1ec8000}, {0xc1eca000}, {0xc1ecc000}, {0xc1ece000}, + {0xc1ed0000}, {0xc1ed2000}, {0xc1ed4000}, {0xc1ed6000}, + {0xc1ed8000}, {0xc1eda000}, {0xc1edc000}, {0xc1ede000}, + {0xc1ee0000}, {0xc1ee2000}, {0xc1ee4000}, {0xc1ee6000}, + {0xc1ee8000}, {0xc1eea000}, {0xc1eec000}, {0xc1eee000}, + {0xc1ef0000}, {0xc1ef2000}, {0xc1ef4000}, {0xc1ef6000}, + {0xc1ef8000}, {0xc1efa000}, {0xc1efc000}, {0xc1efe000}, + {0xc1f00000}, {0xc1f02000}, {0xc1f04000}, {0xc1f06000}, + {0xc1f08000}, {0xc1f0a000}, {0xc1f0c000}, {0xc1f0e000}, + {0xc1f10000}, {0xc1f12000}, {0xc1f14000}, {0xc1f16000}, + {0xc1f18000}, {0xc1f1a000}, {0xc1f1c000}, {0xc1f1e000}, + {0xc1f20000}, {0xc1f22000}, {0xc1f24000}, {0xc1f26000}, + {0xc1f28000}, {0xc1f2a000}, {0xc1f2c000}, {0xc1f2e000}, + {0xc1f30000}, {0xc1f32000}, {0xc1f34000}, {0xc1f36000}, + {0xc1f38000}, {0xc1f3a000}, {0xc1f3c000}, {0xc1f3e000}, + {0xc1f40000}, {0xc1f42000}, {0xc1f44000}, {0xc1f46000}, + {0xc1f48000}, {0xc1f4a000}, {0xc1f4c000}, {0xc1f4e000}, + {0xc1f50000}, {0xc1f52000}, {0xc1f54000}, {0xc1f56000}, + {0xc1f58000}, {0xc1f5a000}, {0xc1f5c000}, {0xc1f5e000}, + {0xc1f60000}, {0xc1f62000}, {0xc1f64000}, {0xc1f66000}, + {0xc1f68000}, {0xc1f6a000}, {0xc1f6c000}, {0xc1f6e000}, + {0xc1f70000}, {0xc1f72000}, {0xc1f74000}, {0xc1f76000}, + {0xc1f78000}, {0xc1f7a000}, {0xc1f7c000}, {0xc1f7e000}, + {0xc1f80000}, {0xc1f82000}, {0xc1f84000}, {0xc1f86000}, + {0xc1f88000}, {0xc1f8a000}, {0xc1f8c000}, {0xc1f8e000}, + {0xc1f90000}, {0xc1f92000}, {0xc1f94000}, {0xc1f96000}, + {0xc1f98000}, {0xc1f9a000}, {0xc1f9c000}, {0xc1f9e000}, + {0xc1fa0000}, {0xc1fa2000}, {0xc1fa4000}, {0xc1fa6000}, + {0xc1fa8000}, {0xc1faa000}, {0xc1fac000}, {0xc1fae000}, + {0xc1fb0000}, {0xc1fb2000}, {0xc1fb4000}, {0xc1fb6000}, + {0xc1fb8000}, {0xc1fba000}, {0xc1fbc000}, {0xc1fbe000}, + {0xc1fc0000}, {0xc1fc2000}, {0xc1fc4000}, {0xc1fc6000}, + {0xc1fc8000}, {0xc1fca000}, {0xc1fcc000}, {0xc1fce000}, + {0xc1fd0000}, {0xc1fd2000}, {0xc1fd4000}, {0xc1fd6000}, + {0xc1fd8000}, {0xc1fda000}, {0xc1fdc000}, {0xc1fde000}, + {0xc1fe0000}, {0xc1fe2000}, {0xc1fe4000}, {0xc1fe6000}, + {0xc1fe8000}, {0xc1fea000}, {0xc1fec000}, {0xc1fee000}, + {0xc1ff0000}, {0xc1ff2000}, {0xc1ff4000}, {0xc1ff6000}, + {0xc1ff8000}, {0xc1ffa000}, {0xc1ffc000}, {0xc1ffe000}, + {0xc2000000}, {0xc2002000}, {0xc2004000}, {0xc2006000}, + {0xc2008000}, {0xc200a000}, {0xc200c000}, {0xc200e000}, + {0xc2010000}, {0xc2012000}, {0xc2014000}, {0xc2016000}, + {0xc2018000}, {0xc201a000}, {0xc201c000}, {0xc201e000}, + {0xc2020000}, {0xc2022000}, {0xc2024000}, {0xc2026000}, + {0xc2028000}, {0xc202a000}, {0xc202c000}, {0xc202e000}, + {0xc2030000}, {0xc2032000}, {0xc2034000}, {0xc2036000}, + {0xc2038000}, {0xc203a000}, {0xc203c000}, {0xc203e000}, + {0xc2040000}, {0xc2042000}, {0xc2044000}, {0xc2046000}, + {0xc2048000}, {0xc204a000}, {0xc204c000}, {0xc204e000}, + {0xc2050000}, {0xc2052000}, {0xc2054000}, {0xc2056000}, + {0xc2058000}, {0xc205a000}, {0xc205c000}, {0xc205e000}, + {0xc2060000}, {0xc2062000}, {0xc2064000}, {0xc2066000}, + {0xc2068000}, {0xc206a000}, {0xc206c000}, {0xc206e000}, + {0xc2070000}, {0xc2072000}, {0xc2074000}, {0xc2076000}, + {0xc2078000}, {0xc207a000}, {0xc207c000}, {0xc207e000}, + {0xc2080000}, {0xc2082000}, {0xc2084000}, {0xc2086000}, + {0xc2088000}, {0xc208a000}, {0xc208c000}, {0xc208e000}, + {0xc2090000}, {0xc2092000}, {0xc2094000}, {0xc2096000}, + {0xc2098000}, {0xc209a000}, {0xc209c000}, {0xc209e000}, + {0xc20a0000}, {0xc20a2000}, {0xc20a4000}, {0xc20a6000}, + {0xc20a8000}, {0xc20aa000}, {0xc20ac000}, {0xc20ae000}, + {0xc20b0000}, {0xc20b2000}, {0xc20b4000}, {0xc20b6000}, + {0xc20b8000}, {0xc20ba000}, {0xc20bc000}, {0xc20be000}, + {0xc20c0000}, {0xc20c2000}, {0xc20c4000}, {0xc20c6000}, + {0xc20c8000}, {0xc20ca000}, {0xc20cc000}, {0xc20ce000}, + {0xc20d0000}, {0xc20d2000}, {0xc20d4000}, {0xc20d6000}, + {0xc20d8000}, {0xc20da000}, {0xc20dc000}, {0xc20de000}, + {0xc20e0000}, {0xc20e2000}, {0xc20e4000}, {0xc20e6000}, + {0xc20e8000}, {0xc20ea000}, {0xc20ec000}, {0xc20ee000}, + {0xc20f0000}, {0xc20f2000}, {0xc20f4000}, {0xc20f6000}, + {0xc20f8000}, {0xc20fa000}, {0xc20fc000}, {0xc20fe000}, + {0xc2100000}, {0xc2102000}, {0xc2104000}, {0xc2106000}, + {0xc2108000}, {0xc210a000}, {0xc210c000}, {0xc210e000}, + {0xc2110000}, {0xc2112000}, {0xc2114000}, {0xc2116000}, + {0xc2118000}, {0xc211a000}, {0xc211c000}, {0xc211e000}, + {0xc2120000}, {0xc2122000}, {0xc2124000}, {0xc2126000}, + {0xc2128000}, {0xc212a000}, {0xc212c000}, {0xc212e000}, + {0xc2130000}, {0xc2132000}, {0xc2134000}, {0xc2136000}, + {0xc2138000}, {0xc213a000}, {0xc213c000}, {0xc213e000}, + {0xc2140000}, {0xc2142000}, {0xc2144000}, {0xc2146000}, + {0xc2148000}, {0xc214a000}, {0xc214c000}, {0xc214e000}, + {0xc2150000}, {0xc2152000}, {0xc2154000}, {0xc2156000}, + {0xc2158000}, {0xc215a000}, {0xc215c000}, {0xc215e000}, + {0xc2160000}, {0xc2162000}, {0xc2164000}, {0xc2166000}, + {0xc2168000}, {0xc216a000}, {0xc216c000}, {0xc216e000}, + {0xc2170000}, {0xc2172000}, {0xc2174000}, {0xc2176000}, + {0xc2178000}, {0xc217a000}, {0xc217c000}, {0xc217e000}, + {0xc2180000}, {0xc2182000}, {0xc2184000}, {0xc2186000}, + {0xc2188000}, {0xc218a000}, {0xc218c000}, {0xc218e000}, + {0xc2190000}, {0xc2192000}, {0xc2194000}, {0xc2196000}, + {0xc2198000}, {0xc219a000}, {0xc219c000}, {0xc219e000}, + {0xc21a0000}, {0xc21a2000}, {0xc21a4000}, {0xc21a6000}, + {0xc21a8000}, {0xc21aa000}, {0xc21ac000}, {0xc21ae000}, + {0xc21b0000}, {0xc21b2000}, {0xc21b4000}, {0xc21b6000}, + {0xc21b8000}, {0xc21ba000}, {0xc21bc000}, {0xc21be000}, + {0xc21c0000}, {0xc21c2000}, {0xc21c4000}, {0xc21c6000}, + {0xc21c8000}, {0xc21ca000}, {0xc21cc000}, {0xc21ce000}, + {0xc21d0000}, {0xc21d2000}, {0xc21d4000}, {0xc21d6000}, + {0xc21d8000}, {0xc21da000}, {0xc21dc000}, {0xc21de000}, + {0xc21e0000}, {0xc21e2000}, {0xc21e4000}, {0xc21e6000}, + {0xc21e8000}, {0xc21ea000}, {0xc21ec000}, {0xc21ee000}, + {0xc21f0000}, {0xc21f2000}, {0xc21f4000}, {0xc21f6000}, + {0xc21f8000}, {0xc21fa000}, {0xc21fc000}, {0xc21fe000}, + {0xc2200000}, {0xc2202000}, {0xc2204000}, {0xc2206000}, + {0xc2208000}, {0xc220a000}, {0xc220c000}, {0xc220e000}, + {0xc2210000}, {0xc2212000}, {0xc2214000}, {0xc2216000}, + {0xc2218000}, {0xc221a000}, {0xc221c000}, {0xc221e000}, + {0xc2220000}, {0xc2222000}, {0xc2224000}, {0xc2226000}, + {0xc2228000}, {0xc222a000}, {0xc222c000}, {0xc222e000}, + {0xc2230000}, {0xc2232000}, {0xc2234000}, {0xc2236000}, + {0xc2238000}, {0xc223a000}, {0xc223c000}, {0xc223e000}, + {0xc2240000}, {0xc2242000}, {0xc2244000}, {0xc2246000}, + {0xc2248000}, {0xc224a000}, {0xc224c000}, {0xc224e000}, + {0xc2250000}, {0xc2252000}, {0xc2254000}, {0xc2256000}, + {0xc2258000}, {0xc225a000}, {0xc225c000}, {0xc225e000}, + {0xc2260000}, {0xc2262000}, {0xc2264000}, {0xc2266000}, + {0xc2268000}, {0xc226a000}, {0xc226c000}, {0xc226e000}, + {0xc2270000}, {0xc2272000}, {0xc2274000}, {0xc2276000}, + {0xc2278000}, {0xc227a000}, {0xc227c000}, {0xc227e000}, + {0xc2280000}, {0xc2282000}, {0xc2284000}, {0xc2286000}, + {0xc2288000}, {0xc228a000}, {0xc228c000}, {0xc228e000}, + {0xc2290000}, {0xc2292000}, {0xc2294000}, {0xc2296000}, + {0xc2298000}, {0xc229a000}, {0xc229c000}, {0xc229e000}, + {0xc22a0000}, {0xc22a2000}, {0xc22a4000}, {0xc22a6000}, + {0xc22a8000}, {0xc22aa000}, {0xc22ac000}, {0xc22ae000}, + {0xc22b0000}, {0xc22b2000}, {0xc22b4000}, {0xc22b6000}, + {0xc22b8000}, {0xc22ba000}, {0xc22bc000}, {0xc22be000}, + {0xc22c0000}, {0xc22c2000}, {0xc22c4000}, {0xc22c6000}, + {0xc22c8000}, {0xc22ca000}, {0xc22cc000}, {0xc22ce000}, + {0xc22d0000}, {0xc22d2000}, {0xc22d4000}, {0xc22d6000}, + {0xc22d8000}, {0xc22da000}, {0xc22dc000}, {0xc22de000}, + {0xc22e0000}, {0xc22e2000}, {0xc22e4000}, {0xc22e6000}, + {0xc22e8000}, {0xc22ea000}, {0xc22ec000}, {0xc22ee000}, + {0xc22f0000}, {0xc22f2000}, {0xc22f4000}, {0xc22f6000}, + {0xc22f8000}, {0xc22fa000}, {0xc22fc000}, {0xc22fe000}, + {0xc2300000}, {0xc2302000}, {0xc2304000}, {0xc2306000}, + {0xc2308000}, {0xc230a000}, {0xc230c000}, {0xc230e000}, + {0xc2310000}, {0xc2312000}, {0xc2314000}, {0xc2316000}, + {0xc2318000}, {0xc231a000}, {0xc231c000}, {0xc231e000}, + {0xc2320000}, {0xc2322000}, {0xc2324000}, {0xc2326000}, + {0xc2328000}, {0xc232a000}, {0xc232c000}, {0xc232e000}, + {0xc2330000}, {0xc2332000}, {0xc2334000}, {0xc2336000}, + {0xc2338000}, {0xc233a000}, {0xc233c000}, {0xc233e000}, + {0xc2340000}, {0xc2342000}, {0xc2344000}, {0xc2346000}, + {0xc2348000}, {0xc234a000}, {0xc234c000}, {0xc234e000}, + {0xc2350000}, {0xc2352000}, {0xc2354000}, {0xc2356000}, + {0xc2358000}, {0xc235a000}, {0xc235c000}, {0xc235e000}, + {0xc2360000}, {0xc2362000}, {0xc2364000}, {0xc2366000}, + {0xc2368000}, {0xc236a000}, {0xc236c000}, {0xc236e000}, + {0xc2370000}, {0xc2372000}, {0xc2374000}, {0xc2376000}, + {0xc2378000}, {0xc237a000}, {0xc237c000}, {0xc237e000}, + {0xc2380000}, {0xc2382000}, {0xc2384000}, {0xc2386000}, + {0xc2388000}, {0xc238a000}, {0xc238c000}, {0xc238e000}, + {0xc2390000}, {0xc2392000}, {0xc2394000}, {0xc2396000}, + {0xc2398000}, {0xc239a000}, {0xc239c000}, {0xc239e000}, + {0xc23a0000}, {0xc23a2000}, {0xc23a4000}, {0xc23a6000}, + {0xc23a8000}, {0xc23aa000}, {0xc23ac000}, {0xc23ae000}, + {0xc23b0000}, {0xc23b2000}, {0xc23b4000}, {0xc23b6000}, + {0xc23b8000}, {0xc23ba000}, {0xc23bc000}, {0xc23be000}, + {0xc23c0000}, {0xc23c2000}, {0xc23c4000}, {0xc23c6000}, + {0xc23c8000}, {0xc23ca000}, {0xc23cc000}, {0xc23ce000}, + {0xc23d0000}, {0xc23d2000}, {0xc23d4000}, {0xc23d6000}, + {0xc23d8000}, {0xc23da000}, {0xc23dc000}, {0xc23de000}, + {0xc23e0000}, {0xc23e2000}, {0xc23e4000}, {0xc23e6000}, + {0xc23e8000}, {0xc23ea000}, {0xc23ec000}, {0xc23ee000}, + {0xc23f0000}, {0xc23f2000}, {0xc23f4000}, {0xc23f6000}, + {0xc23f8000}, {0xc23fa000}, {0xc23fc000}, {0xc23fe000}, + {0xc2400000}, {0xc2402000}, {0xc2404000}, {0xc2406000}, + {0xc2408000}, {0xc240a000}, {0xc240c000}, {0xc240e000}, + {0xc2410000}, {0xc2412000}, {0xc2414000}, {0xc2416000}, + {0xc2418000}, {0xc241a000}, {0xc241c000}, {0xc241e000}, + {0xc2420000}, {0xc2422000}, {0xc2424000}, {0xc2426000}, + {0xc2428000}, {0xc242a000}, {0xc242c000}, {0xc242e000}, + {0xc2430000}, {0xc2432000}, {0xc2434000}, {0xc2436000}, + {0xc2438000}, {0xc243a000}, {0xc243c000}, {0xc243e000}, + {0xc2440000}, {0xc2442000}, {0xc2444000}, {0xc2446000}, + {0xc2448000}, {0xc244a000}, {0xc244c000}, {0xc244e000}, + {0xc2450000}, {0xc2452000}, {0xc2454000}, {0xc2456000}, + {0xc2458000}, {0xc245a000}, {0xc245c000}, {0xc245e000}, + {0xc2460000}, {0xc2462000}, {0xc2464000}, {0xc2466000}, + {0xc2468000}, {0xc246a000}, {0xc246c000}, {0xc246e000}, + {0xc2470000}, {0xc2472000}, {0xc2474000}, {0xc2476000}, + {0xc2478000}, {0xc247a000}, {0xc247c000}, {0xc247e000}, + {0xc2480000}, {0xc2482000}, {0xc2484000}, {0xc2486000}, + {0xc2488000}, {0xc248a000}, {0xc248c000}, {0xc248e000}, + {0xc2490000}, {0xc2492000}, {0xc2494000}, {0xc2496000}, + {0xc2498000}, {0xc249a000}, {0xc249c000}, {0xc249e000}, + {0xc24a0000}, {0xc24a2000}, {0xc24a4000}, {0xc24a6000}, + {0xc24a8000}, {0xc24aa000}, {0xc24ac000}, {0xc24ae000}, + {0xc24b0000}, {0xc24b2000}, {0xc24b4000}, {0xc24b6000}, + {0xc24b8000}, {0xc24ba000}, {0xc24bc000}, {0xc24be000}, + {0xc24c0000}, {0xc24c2000}, {0xc24c4000}, {0xc24c6000}, + {0xc24c8000}, {0xc24ca000}, {0xc24cc000}, {0xc24ce000}, + {0xc24d0000}, {0xc24d2000}, {0xc24d4000}, {0xc24d6000}, + {0xc24d8000}, {0xc24da000}, {0xc24dc000}, {0xc24de000}, + {0xc24e0000}, {0xc24e2000}, {0xc24e4000}, {0xc24e6000}, + {0xc24e8000}, {0xc24ea000}, {0xc24ec000}, {0xc24ee000}, + {0xc24f0000}, {0xc24f2000}, {0xc24f4000}, {0xc24f6000}, + {0xc24f8000}, {0xc24fa000}, {0xc24fc000}, {0xc24fe000}, + {0xc2500000}, {0xc2502000}, {0xc2504000}, {0xc2506000}, + {0xc2508000}, {0xc250a000}, {0xc250c000}, {0xc250e000}, + {0xc2510000}, {0xc2512000}, {0xc2514000}, {0xc2516000}, + {0xc2518000}, {0xc251a000}, {0xc251c000}, {0xc251e000}, + {0xc2520000}, {0xc2522000}, {0xc2524000}, {0xc2526000}, + {0xc2528000}, {0xc252a000}, {0xc252c000}, {0xc252e000}, + {0xc2530000}, {0xc2532000}, {0xc2534000}, {0xc2536000}, + {0xc2538000}, {0xc253a000}, {0xc253c000}, {0xc253e000}, + {0xc2540000}, {0xc2542000}, {0xc2544000}, {0xc2546000}, + {0xc2548000}, {0xc254a000}, {0xc254c000}, {0xc254e000}, + {0xc2550000}, {0xc2552000}, {0xc2554000}, {0xc2556000}, + {0xc2558000}, {0xc255a000}, {0xc255c000}, {0xc255e000}, + {0xc2560000}, {0xc2562000}, {0xc2564000}, {0xc2566000}, + {0xc2568000}, {0xc256a000}, {0xc256c000}, {0xc256e000}, + {0xc2570000}, {0xc2572000}, {0xc2574000}, {0xc2576000}, + {0xc2578000}, {0xc257a000}, {0xc257c000}, {0xc257e000}, + {0xc2580000}, {0xc2582000}, {0xc2584000}, {0xc2586000}, + {0xc2588000}, {0xc258a000}, {0xc258c000}, {0xc258e000}, + {0xc2590000}, {0xc2592000}, {0xc2594000}, {0xc2596000}, + {0xc2598000}, {0xc259a000}, {0xc259c000}, {0xc259e000}, + {0xc25a0000}, {0xc25a2000}, {0xc25a4000}, {0xc25a6000}, + {0xc25a8000}, {0xc25aa000}, {0xc25ac000}, {0xc25ae000}, + {0xc25b0000}, {0xc25b2000}, {0xc25b4000}, {0xc25b6000}, + {0xc25b8000}, {0xc25ba000}, {0xc25bc000}, {0xc25be000}, + {0xc25c0000}, {0xc25c2000}, {0xc25c4000}, {0xc25c6000}, + {0xc25c8000}, {0xc25ca000}, {0xc25cc000}, {0xc25ce000}, + {0xc25d0000}, {0xc25d2000}, {0xc25d4000}, {0xc25d6000}, + {0xc25d8000}, {0xc25da000}, {0xc25dc000}, {0xc25de000}, + {0xc25e0000}, {0xc25e2000}, {0xc25e4000}, {0xc25e6000}, + {0xc25e8000}, {0xc25ea000}, {0xc25ec000}, {0xc25ee000}, + {0xc25f0000}, {0xc25f2000}, {0xc25f4000}, {0xc25f6000}, + {0xc25f8000}, {0xc25fa000}, {0xc25fc000}, {0xc25fe000}, + {0xc2600000}, {0xc2602000}, {0xc2604000}, {0xc2606000}, + {0xc2608000}, {0xc260a000}, {0xc260c000}, {0xc260e000}, + {0xc2610000}, {0xc2612000}, {0xc2614000}, {0xc2616000}, + {0xc2618000}, {0xc261a000}, {0xc261c000}, {0xc261e000}, + {0xc2620000}, {0xc2622000}, {0xc2624000}, {0xc2626000}, + {0xc2628000}, {0xc262a000}, {0xc262c000}, {0xc262e000}, + {0xc2630000}, {0xc2632000}, {0xc2634000}, {0xc2636000}, + {0xc2638000}, {0xc263a000}, {0xc263c000}, {0xc263e000}, + {0xc2640000}, {0xc2642000}, {0xc2644000}, {0xc2646000}, + {0xc2648000}, {0xc264a000}, {0xc264c000}, {0xc264e000}, + {0xc2650000}, {0xc2652000}, {0xc2654000}, {0xc2656000}, + {0xc2658000}, {0xc265a000}, {0xc265c000}, {0xc265e000}, + {0xc2660000}, {0xc2662000}, {0xc2664000}, {0xc2666000}, + {0xc2668000}, {0xc266a000}, {0xc266c000}, {0xc266e000}, + {0xc2670000}, {0xc2672000}, {0xc2674000}, {0xc2676000}, + {0xc2678000}, {0xc267a000}, {0xc267c000}, {0xc267e000}, + {0xc2680000}, {0xc2682000}, {0xc2684000}, {0xc2686000}, + {0xc2688000}, {0xc268a000}, {0xc268c000}, {0xc268e000}, + {0xc2690000}, {0xc2692000}, {0xc2694000}, {0xc2696000}, + {0xc2698000}, {0xc269a000}, {0xc269c000}, {0xc269e000}, + {0xc26a0000}, {0xc26a2000}, {0xc26a4000}, {0xc26a6000}, + {0xc26a8000}, {0xc26aa000}, {0xc26ac000}, {0xc26ae000}, + {0xc26b0000}, {0xc26b2000}, {0xc26b4000}, {0xc26b6000}, + {0xc26b8000}, {0xc26ba000}, {0xc26bc000}, {0xc26be000}, + {0xc26c0000}, {0xc26c2000}, {0xc26c4000}, {0xc26c6000}, + {0xc26c8000}, {0xc26ca000}, {0xc26cc000}, {0xc26ce000}, + {0xc26d0000}, {0xc26d2000}, {0xc26d4000}, {0xc26d6000}, + {0xc26d8000}, {0xc26da000}, {0xc26dc000}, {0xc26de000}, + {0xc26e0000}, {0xc26e2000}, {0xc26e4000}, {0xc26e6000}, + {0xc26e8000}, {0xc26ea000}, {0xc26ec000}, {0xc26ee000}, + {0xc26f0000}, {0xc26f2000}, {0xc26f4000}, {0xc26f6000}, + {0xc26f8000}, {0xc26fa000}, {0xc26fc000}, {0xc26fe000}, + {0xc2700000}, {0xc2702000}, {0xc2704000}, {0xc2706000}, + {0xc2708000}, {0xc270a000}, {0xc270c000}, {0xc270e000}, + {0xc2710000}, {0xc2712000}, {0xc2714000}, {0xc2716000}, + {0xc2718000}, {0xc271a000}, {0xc271c000}, {0xc271e000}, + {0xc2720000}, {0xc2722000}, {0xc2724000}, {0xc2726000}, + {0xc2728000}, {0xc272a000}, {0xc272c000}, {0xc272e000}, + {0xc2730000}, {0xc2732000}, {0xc2734000}, {0xc2736000}, + {0xc2738000}, {0xc273a000}, {0xc273c000}, {0xc273e000}, + {0xc2740000}, {0xc2742000}, {0xc2744000}, {0xc2746000}, + {0xc2748000}, {0xc274a000}, {0xc274c000}, {0xc274e000}, + {0xc2750000}, {0xc2752000}, {0xc2754000}, {0xc2756000}, + {0xc2758000}, {0xc275a000}, {0xc275c000}, {0xc275e000}, + {0xc2760000}, {0xc2762000}, {0xc2764000}, {0xc2766000}, + {0xc2768000}, {0xc276a000}, {0xc276c000}, {0xc276e000}, + {0xc2770000}, {0xc2772000}, {0xc2774000}, {0xc2776000}, + {0xc2778000}, {0xc277a000}, {0xc277c000}, {0xc277e000}, + {0xc2780000}, {0xc2782000}, {0xc2784000}, {0xc2786000}, + {0xc2788000}, {0xc278a000}, {0xc278c000}, {0xc278e000}, + {0xc2790000}, {0xc2792000}, {0xc2794000}, {0xc2796000}, + {0xc2798000}, {0xc279a000}, {0xc279c000}, {0xc279e000}, + {0xc27a0000}, {0xc27a2000}, {0xc27a4000}, {0xc27a6000}, + {0xc27a8000}, {0xc27aa000}, {0xc27ac000}, {0xc27ae000}, + {0xc27b0000}, {0xc27b2000}, {0xc27b4000}, {0xc27b6000}, + {0xc27b8000}, {0xc27ba000}, {0xc27bc000}, {0xc27be000}, + {0xc27c0000}, {0xc27c2000}, {0xc27c4000}, {0xc27c6000}, + {0xc27c8000}, {0xc27ca000}, {0xc27cc000}, {0xc27ce000}, + {0xc27d0000}, {0xc27d2000}, {0xc27d4000}, {0xc27d6000}, + {0xc27d8000}, {0xc27da000}, {0xc27dc000}, {0xc27de000}, + {0xc27e0000}, {0xc27e2000}, {0xc27e4000}, {0xc27e6000}, + {0xc27e8000}, {0xc27ea000}, {0xc27ec000}, {0xc27ee000}, + {0xc27f0000}, {0xc27f2000}, {0xc27f4000}, {0xc27f6000}, + {0xc27f8000}, {0xc27fa000}, {0xc27fc000}, {0xc27fe000}, + {0xc2800000}, {0xc2802000}, {0xc2804000}, {0xc2806000}, + {0xc2808000}, {0xc280a000}, {0xc280c000}, {0xc280e000}, + {0xc2810000}, {0xc2812000}, {0xc2814000}, {0xc2816000}, + {0xc2818000}, {0xc281a000}, {0xc281c000}, {0xc281e000}, + {0xc2820000}, {0xc2822000}, {0xc2824000}, {0xc2826000}, + {0xc2828000}, {0xc282a000}, {0xc282c000}, {0xc282e000}, + {0xc2830000}, {0xc2832000}, {0xc2834000}, {0xc2836000}, + {0xc2838000}, {0xc283a000}, {0xc283c000}, {0xc283e000}, + {0xc2840000}, {0xc2842000}, {0xc2844000}, {0xc2846000}, + {0xc2848000}, {0xc284a000}, {0xc284c000}, {0xc284e000}, + {0xc2850000}, {0xc2852000}, {0xc2854000}, {0xc2856000}, + {0xc2858000}, {0xc285a000}, {0xc285c000}, {0xc285e000}, + {0xc2860000}, {0xc2862000}, {0xc2864000}, {0xc2866000}, + {0xc2868000}, {0xc286a000}, {0xc286c000}, {0xc286e000}, + {0xc2870000}, {0xc2872000}, {0xc2874000}, {0xc2876000}, + {0xc2878000}, {0xc287a000}, {0xc287c000}, {0xc287e000}, + {0xc2880000}, {0xc2882000}, {0xc2884000}, {0xc2886000}, + {0xc2888000}, {0xc288a000}, {0xc288c000}, {0xc288e000}, + {0xc2890000}, {0xc2892000}, {0xc2894000}, {0xc2896000}, + {0xc2898000}, {0xc289a000}, {0xc289c000}, {0xc289e000}, + {0xc28a0000}, {0xc28a2000}, {0xc28a4000}, {0xc28a6000}, + {0xc28a8000}, {0xc28aa000}, {0xc28ac000}, {0xc28ae000}, + {0xc28b0000}, {0xc28b2000}, {0xc28b4000}, {0xc28b6000}, + {0xc28b8000}, {0xc28ba000}, {0xc28bc000}, {0xc28be000}, + {0xc28c0000}, {0xc28c2000}, {0xc28c4000}, {0xc28c6000}, + {0xc28c8000}, {0xc28ca000}, {0xc28cc000}, {0xc28ce000}, + {0xc28d0000}, {0xc28d2000}, {0xc28d4000}, {0xc28d6000}, + {0xc28d8000}, {0xc28da000}, {0xc28dc000}, {0xc28de000}, + {0xc28e0000}, {0xc28e2000}, {0xc28e4000}, {0xc28e6000}, + {0xc28e8000}, {0xc28ea000}, {0xc28ec000}, {0xc28ee000}, + {0xc28f0000}, {0xc28f2000}, {0xc28f4000}, {0xc28f6000}, + {0xc28f8000}, {0xc28fa000}, {0xc28fc000}, {0xc28fe000}, + {0xc2900000}, {0xc2902000}, {0xc2904000}, {0xc2906000}, + {0xc2908000}, {0xc290a000}, {0xc290c000}, {0xc290e000}, + {0xc2910000}, {0xc2912000}, {0xc2914000}, {0xc2916000}, + {0xc2918000}, {0xc291a000}, {0xc291c000}, {0xc291e000}, + {0xc2920000}, {0xc2922000}, {0xc2924000}, {0xc2926000}, + {0xc2928000}, {0xc292a000}, {0xc292c000}, {0xc292e000}, + {0xc2930000}, {0xc2932000}, {0xc2934000}, {0xc2936000}, + {0xc2938000}, {0xc293a000}, {0xc293c000}, {0xc293e000}, + {0xc2940000}, {0xc2942000}, {0xc2944000}, {0xc2946000}, + {0xc2948000}, {0xc294a000}, {0xc294c000}, {0xc294e000}, + {0xc2950000}, {0xc2952000}, {0xc2954000}, {0xc2956000}, + {0xc2958000}, {0xc295a000}, {0xc295c000}, {0xc295e000}, + {0xc2960000}, {0xc2962000}, {0xc2964000}, {0xc2966000}, + {0xc2968000}, {0xc296a000}, {0xc296c000}, {0xc296e000}, + {0xc2970000}, {0xc2972000}, {0xc2974000}, {0xc2976000}, + {0xc2978000}, {0xc297a000}, {0xc297c000}, {0xc297e000}, + {0xc2980000}, {0xc2982000}, {0xc2984000}, {0xc2986000}, + {0xc2988000}, {0xc298a000}, {0xc298c000}, {0xc298e000}, + {0xc2990000}, {0xc2992000}, {0xc2994000}, {0xc2996000}, + {0xc2998000}, {0xc299a000}, {0xc299c000}, {0xc299e000}, + {0xc29a0000}, {0xc29a2000}, {0xc29a4000}, {0xc29a6000}, + {0xc29a8000}, {0xc29aa000}, {0xc29ac000}, {0xc29ae000}, + {0xc29b0000}, {0xc29b2000}, {0xc29b4000}, {0xc29b6000}, + {0xc29b8000}, {0xc29ba000}, {0xc29bc000}, {0xc29be000}, + {0xc29c0000}, {0xc29c2000}, {0xc29c4000}, {0xc29c6000}, + {0xc29c8000}, {0xc29ca000}, {0xc29cc000}, {0xc29ce000}, + {0xc29d0000}, {0xc29d2000}, {0xc29d4000}, {0xc29d6000}, + {0xc29d8000}, {0xc29da000}, {0xc29dc000}, {0xc29de000}, + {0xc29e0000}, {0xc29e2000}, {0xc29e4000}, {0xc29e6000}, + {0xc29e8000}, {0xc29ea000}, {0xc29ec000}, {0xc29ee000}, + {0xc29f0000}, {0xc29f2000}, {0xc29f4000}, {0xc29f6000}, + {0xc29f8000}, {0xc29fa000}, {0xc29fc000}, {0xc29fe000}, + {0xc2a00000}, {0xc2a02000}, {0xc2a04000}, {0xc2a06000}, + {0xc2a08000}, {0xc2a0a000}, {0xc2a0c000}, {0xc2a0e000}, + {0xc2a10000}, {0xc2a12000}, {0xc2a14000}, {0xc2a16000}, + {0xc2a18000}, {0xc2a1a000}, {0xc2a1c000}, {0xc2a1e000}, + {0xc2a20000}, {0xc2a22000}, {0xc2a24000}, {0xc2a26000}, + {0xc2a28000}, {0xc2a2a000}, {0xc2a2c000}, {0xc2a2e000}, + {0xc2a30000}, {0xc2a32000}, {0xc2a34000}, {0xc2a36000}, + {0xc2a38000}, {0xc2a3a000}, {0xc2a3c000}, {0xc2a3e000}, + {0xc2a40000}, {0xc2a42000}, {0xc2a44000}, {0xc2a46000}, + {0xc2a48000}, {0xc2a4a000}, {0xc2a4c000}, {0xc2a4e000}, + {0xc2a50000}, {0xc2a52000}, {0xc2a54000}, {0xc2a56000}, + {0xc2a58000}, {0xc2a5a000}, {0xc2a5c000}, {0xc2a5e000}, + {0xc2a60000}, {0xc2a62000}, {0xc2a64000}, {0xc2a66000}, + {0xc2a68000}, {0xc2a6a000}, {0xc2a6c000}, {0xc2a6e000}, + {0xc2a70000}, {0xc2a72000}, {0xc2a74000}, {0xc2a76000}, + {0xc2a78000}, {0xc2a7a000}, {0xc2a7c000}, {0xc2a7e000}, + {0xc2a80000}, {0xc2a82000}, {0xc2a84000}, {0xc2a86000}, + {0xc2a88000}, {0xc2a8a000}, {0xc2a8c000}, {0xc2a8e000}, + {0xc2a90000}, {0xc2a92000}, {0xc2a94000}, {0xc2a96000}, + {0xc2a98000}, {0xc2a9a000}, {0xc2a9c000}, {0xc2a9e000}, + {0xc2aa0000}, {0xc2aa2000}, {0xc2aa4000}, {0xc2aa6000}, + {0xc2aa8000}, {0xc2aaa000}, {0xc2aac000}, {0xc2aae000}, + {0xc2ab0000}, {0xc2ab2000}, {0xc2ab4000}, {0xc2ab6000}, + {0xc2ab8000}, {0xc2aba000}, {0xc2abc000}, {0xc2abe000}, + {0xc2ac0000}, {0xc2ac2000}, {0xc2ac4000}, {0xc2ac6000}, + {0xc2ac8000}, {0xc2aca000}, {0xc2acc000}, {0xc2ace000}, + {0xc2ad0000}, {0xc2ad2000}, {0xc2ad4000}, {0xc2ad6000}, + {0xc2ad8000}, {0xc2ada000}, {0xc2adc000}, {0xc2ade000}, + {0xc2ae0000}, {0xc2ae2000}, {0xc2ae4000}, {0xc2ae6000}, + {0xc2ae8000}, {0xc2aea000}, {0xc2aec000}, {0xc2aee000}, + {0xc2af0000}, {0xc2af2000}, {0xc2af4000}, {0xc2af6000}, + {0xc2af8000}, {0xc2afa000}, {0xc2afc000}, {0xc2afe000}, + {0xc2b00000}, {0xc2b02000}, {0xc2b04000}, {0xc2b06000}, + {0xc2b08000}, {0xc2b0a000}, {0xc2b0c000}, {0xc2b0e000}, + {0xc2b10000}, {0xc2b12000}, {0xc2b14000}, {0xc2b16000}, + {0xc2b18000}, {0xc2b1a000}, {0xc2b1c000}, {0xc2b1e000}, + {0xc2b20000}, {0xc2b22000}, {0xc2b24000}, {0xc2b26000}, + {0xc2b28000}, {0xc2b2a000}, {0xc2b2c000}, {0xc2b2e000}, + {0xc2b30000}, {0xc2b32000}, {0xc2b34000}, {0xc2b36000}, + {0xc2b38000}, {0xc2b3a000}, {0xc2b3c000}, {0xc2b3e000}, + {0xc2b40000}, {0xc2b42000}, {0xc2b44000}, {0xc2b46000}, + {0xc2b48000}, {0xc2b4a000}, {0xc2b4c000}, {0xc2b4e000}, + {0xc2b50000}, {0xc2b52000}, {0xc2b54000}, {0xc2b56000}, + {0xc2b58000}, {0xc2b5a000}, {0xc2b5c000}, {0xc2b5e000}, + {0xc2b60000}, {0xc2b62000}, {0xc2b64000}, {0xc2b66000}, + {0xc2b68000}, {0xc2b6a000}, {0xc2b6c000}, {0xc2b6e000}, + {0xc2b70000}, {0xc2b72000}, {0xc2b74000}, {0xc2b76000}, + {0xc2b78000}, {0xc2b7a000}, {0xc2b7c000}, {0xc2b7e000}, + {0xc2b80000}, {0xc2b82000}, {0xc2b84000}, {0xc2b86000}, + {0xc2b88000}, {0xc2b8a000}, {0xc2b8c000}, {0xc2b8e000}, + {0xc2b90000}, {0xc2b92000}, {0xc2b94000}, {0xc2b96000}, + {0xc2b98000}, {0xc2b9a000}, {0xc2b9c000}, {0xc2b9e000}, + {0xc2ba0000}, {0xc2ba2000}, {0xc2ba4000}, {0xc2ba6000}, + {0xc2ba8000}, {0xc2baa000}, {0xc2bac000}, {0xc2bae000}, + {0xc2bb0000}, {0xc2bb2000}, {0xc2bb4000}, {0xc2bb6000}, + {0xc2bb8000}, {0xc2bba000}, {0xc2bbc000}, {0xc2bbe000}, + {0xc2bc0000}, {0xc2bc2000}, {0xc2bc4000}, {0xc2bc6000}, + {0xc2bc8000}, {0xc2bca000}, {0xc2bcc000}, {0xc2bce000}, + {0xc2bd0000}, {0xc2bd2000}, {0xc2bd4000}, {0xc2bd6000}, + {0xc2bd8000}, {0xc2bda000}, {0xc2bdc000}, {0xc2bde000}, + {0xc2be0000}, {0xc2be2000}, {0xc2be4000}, {0xc2be6000}, + {0xc2be8000}, {0xc2bea000}, {0xc2bec000}, {0xc2bee000}, + {0xc2bf0000}, {0xc2bf2000}, {0xc2bf4000}, {0xc2bf6000}, + {0xc2bf8000}, {0xc2bfa000}, {0xc2bfc000}, {0xc2bfe000}, + {0xc2c00000}, {0xc2c02000}, {0xc2c04000}, {0xc2c06000}, + {0xc2c08000}, {0xc2c0a000}, {0xc2c0c000}, {0xc2c0e000}, + {0xc2c10000}, {0xc2c12000}, {0xc2c14000}, {0xc2c16000}, + {0xc2c18000}, {0xc2c1a000}, {0xc2c1c000}, {0xc2c1e000}, + {0xc2c20000}, {0xc2c22000}, {0xc2c24000}, {0xc2c26000}, + {0xc2c28000}, {0xc2c2a000}, {0xc2c2c000}, {0xc2c2e000}, + {0xc2c30000}, {0xc2c32000}, {0xc2c34000}, {0xc2c36000}, + {0xc2c38000}, {0xc2c3a000}, {0xc2c3c000}, {0xc2c3e000}, + {0xc2c40000}, {0xc2c42000}, {0xc2c44000}, {0xc2c46000}, + {0xc2c48000}, {0xc2c4a000}, {0xc2c4c000}, {0xc2c4e000}, + {0xc2c50000}, {0xc2c52000}, {0xc2c54000}, {0xc2c56000}, + {0xc2c58000}, {0xc2c5a000}, {0xc2c5c000}, {0xc2c5e000}, + {0xc2c60000}, {0xc2c62000}, {0xc2c64000}, {0xc2c66000}, + {0xc2c68000}, {0xc2c6a000}, {0xc2c6c000}, {0xc2c6e000}, + {0xc2c70000}, {0xc2c72000}, {0xc2c74000}, {0xc2c76000}, + {0xc2c78000}, {0xc2c7a000}, {0xc2c7c000}, {0xc2c7e000}, + {0xc2c80000}, {0xc2c82000}, {0xc2c84000}, {0xc2c86000}, + {0xc2c88000}, {0xc2c8a000}, {0xc2c8c000}, {0xc2c8e000}, + {0xc2c90000}, {0xc2c92000}, {0xc2c94000}, {0xc2c96000}, + {0xc2c98000}, {0xc2c9a000}, {0xc2c9c000}, {0xc2c9e000}, + {0xc2ca0000}, {0xc2ca2000}, {0xc2ca4000}, {0xc2ca6000}, + {0xc2ca8000}, {0xc2caa000}, {0xc2cac000}, {0xc2cae000}, + {0xc2cb0000}, {0xc2cb2000}, {0xc2cb4000}, {0xc2cb6000}, + {0xc2cb8000}, {0xc2cba000}, {0xc2cbc000}, {0xc2cbe000}, + {0xc2cc0000}, {0xc2cc2000}, {0xc2cc4000}, {0xc2cc6000}, + {0xc2cc8000}, {0xc2cca000}, {0xc2ccc000}, {0xc2cce000}, + {0xc2cd0000}, {0xc2cd2000}, {0xc2cd4000}, {0xc2cd6000}, + {0xc2cd8000}, {0xc2cda000}, {0xc2cdc000}, {0xc2cde000}, + {0xc2ce0000}, {0xc2ce2000}, {0xc2ce4000}, {0xc2ce6000}, + {0xc2ce8000}, {0xc2cea000}, {0xc2cec000}, {0xc2cee000}, + {0xc2cf0000}, {0xc2cf2000}, {0xc2cf4000}, {0xc2cf6000}, + {0xc2cf8000}, {0xc2cfa000}, {0xc2cfc000}, {0xc2cfe000}, + {0xc2d00000}, {0xc2d02000}, {0xc2d04000}, {0xc2d06000}, + {0xc2d08000}, {0xc2d0a000}, {0xc2d0c000}, {0xc2d0e000}, + {0xc2d10000}, {0xc2d12000}, {0xc2d14000}, {0xc2d16000}, + {0xc2d18000}, {0xc2d1a000}, {0xc2d1c000}, {0xc2d1e000}, + {0xc2d20000}, {0xc2d22000}, {0xc2d24000}, {0xc2d26000}, + {0xc2d28000}, {0xc2d2a000}, {0xc2d2c000}, {0xc2d2e000}, + {0xc2d30000}, {0xc2d32000}, {0xc2d34000}, {0xc2d36000}, + {0xc2d38000}, {0xc2d3a000}, {0xc2d3c000}, {0xc2d3e000}, + {0xc2d40000}, {0xc2d42000}, {0xc2d44000}, {0xc2d46000}, + {0xc2d48000}, {0xc2d4a000}, {0xc2d4c000}, {0xc2d4e000}, + {0xc2d50000}, {0xc2d52000}, {0xc2d54000}, {0xc2d56000}, + {0xc2d58000}, {0xc2d5a000}, {0xc2d5c000}, {0xc2d5e000}, + {0xc2d60000}, {0xc2d62000}, {0xc2d64000}, {0xc2d66000}, + {0xc2d68000}, {0xc2d6a000}, {0xc2d6c000}, {0xc2d6e000}, + {0xc2d70000}, {0xc2d72000}, {0xc2d74000}, {0xc2d76000}, + {0xc2d78000}, {0xc2d7a000}, {0xc2d7c000}, {0xc2d7e000}, + {0xc2d80000}, {0xc2d82000}, {0xc2d84000}, {0xc2d86000}, + {0xc2d88000}, {0xc2d8a000}, {0xc2d8c000}, {0xc2d8e000}, + {0xc2d90000}, {0xc2d92000}, {0xc2d94000}, {0xc2d96000}, + {0xc2d98000}, {0xc2d9a000}, {0xc2d9c000}, {0xc2d9e000}, + {0xc2da0000}, {0xc2da2000}, {0xc2da4000}, {0xc2da6000}, + {0xc2da8000}, {0xc2daa000}, {0xc2dac000}, {0xc2dae000}, + {0xc2db0000}, {0xc2db2000}, {0xc2db4000}, {0xc2db6000}, + {0xc2db8000}, {0xc2dba000}, {0xc2dbc000}, {0xc2dbe000}, + {0xc2dc0000}, {0xc2dc2000}, {0xc2dc4000}, {0xc2dc6000}, + {0xc2dc8000}, {0xc2dca000}, {0xc2dcc000}, {0xc2dce000}, + {0xc2dd0000}, {0xc2dd2000}, {0xc2dd4000}, {0xc2dd6000}, + {0xc2dd8000}, {0xc2dda000}, {0xc2ddc000}, {0xc2dde000}, + {0xc2de0000}, {0xc2de2000}, {0xc2de4000}, {0xc2de6000}, + {0xc2de8000}, {0xc2dea000}, {0xc2dec000}, {0xc2dee000}, + {0xc2df0000}, {0xc2df2000}, {0xc2df4000}, {0xc2df6000}, + {0xc2df8000}, {0xc2dfa000}, {0xc2dfc000}, {0xc2dfe000}, + {0xc2e00000}, {0xc2e02000}, {0xc2e04000}, {0xc2e06000}, + {0xc2e08000}, {0xc2e0a000}, {0xc2e0c000}, {0xc2e0e000}, + {0xc2e10000}, {0xc2e12000}, {0xc2e14000}, {0xc2e16000}, + {0xc2e18000}, {0xc2e1a000}, {0xc2e1c000}, {0xc2e1e000}, + {0xc2e20000}, {0xc2e22000}, {0xc2e24000}, {0xc2e26000}, + {0xc2e28000}, {0xc2e2a000}, {0xc2e2c000}, {0xc2e2e000}, + {0xc2e30000}, {0xc2e32000}, {0xc2e34000}, {0xc2e36000}, + {0xc2e38000}, {0xc2e3a000}, {0xc2e3c000}, {0xc2e3e000}, + {0xc2e40000}, {0xc2e42000}, {0xc2e44000}, {0xc2e46000}, + {0xc2e48000}, {0xc2e4a000}, {0xc2e4c000}, {0xc2e4e000}, + {0xc2e50000}, {0xc2e52000}, {0xc2e54000}, {0xc2e56000}, + {0xc2e58000}, {0xc2e5a000}, {0xc2e5c000}, {0xc2e5e000}, + {0xc2e60000}, {0xc2e62000}, {0xc2e64000}, {0xc2e66000}, + {0xc2e68000}, {0xc2e6a000}, {0xc2e6c000}, {0xc2e6e000}, + {0xc2e70000}, {0xc2e72000}, {0xc2e74000}, {0xc2e76000}, + {0xc2e78000}, {0xc2e7a000}, {0xc2e7c000}, {0xc2e7e000}, + {0xc2e80000}, {0xc2e82000}, {0xc2e84000}, {0xc2e86000}, + {0xc2e88000}, {0xc2e8a000}, {0xc2e8c000}, {0xc2e8e000}, + {0xc2e90000}, {0xc2e92000}, {0xc2e94000}, {0xc2e96000}, + {0xc2e98000}, {0xc2e9a000}, {0xc2e9c000}, {0xc2e9e000}, + {0xc2ea0000}, {0xc2ea2000}, {0xc2ea4000}, {0xc2ea6000}, + {0xc2ea8000}, {0xc2eaa000}, {0xc2eac000}, {0xc2eae000}, + {0xc2eb0000}, {0xc2eb2000}, {0xc2eb4000}, {0xc2eb6000}, + {0xc2eb8000}, {0xc2eba000}, {0xc2ebc000}, {0xc2ebe000}, + {0xc2ec0000}, {0xc2ec2000}, {0xc2ec4000}, {0xc2ec6000}, + {0xc2ec8000}, {0xc2eca000}, {0xc2ecc000}, {0xc2ece000}, + {0xc2ed0000}, {0xc2ed2000}, {0xc2ed4000}, {0xc2ed6000}, + {0xc2ed8000}, {0xc2eda000}, {0xc2edc000}, {0xc2ede000}, + {0xc2ee0000}, {0xc2ee2000}, {0xc2ee4000}, {0xc2ee6000}, + {0xc2ee8000}, {0xc2eea000}, {0xc2eec000}, {0xc2eee000}, + {0xc2ef0000}, {0xc2ef2000}, {0xc2ef4000}, {0xc2ef6000}, + {0xc2ef8000}, {0xc2efa000}, {0xc2efc000}, {0xc2efe000}, + {0xc2f00000}, {0xc2f02000}, {0xc2f04000}, {0xc2f06000}, + {0xc2f08000}, {0xc2f0a000}, {0xc2f0c000}, {0xc2f0e000}, + {0xc2f10000}, {0xc2f12000}, {0xc2f14000}, {0xc2f16000}, + {0xc2f18000}, {0xc2f1a000}, {0xc2f1c000}, {0xc2f1e000}, + {0xc2f20000}, {0xc2f22000}, {0xc2f24000}, {0xc2f26000}, + {0xc2f28000}, {0xc2f2a000}, {0xc2f2c000}, {0xc2f2e000}, + {0xc2f30000}, {0xc2f32000}, {0xc2f34000}, {0xc2f36000}, + {0xc2f38000}, {0xc2f3a000}, {0xc2f3c000}, {0xc2f3e000}, + {0xc2f40000}, {0xc2f42000}, {0xc2f44000}, {0xc2f46000}, + {0xc2f48000}, {0xc2f4a000}, {0xc2f4c000}, {0xc2f4e000}, + {0xc2f50000}, {0xc2f52000}, {0xc2f54000}, {0xc2f56000}, + {0xc2f58000}, {0xc2f5a000}, {0xc2f5c000}, {0xc2f5e000}, + {0xc2f60000}, {0xc2f62000}, {0xc2f64000}, {0xc2f66000}, + {0xc2f68000}, {0xc2f6a000}, {0xc2f6c000}, {0xc2f6e000}, + {0xc2f70000}, {0xc2f72000}, {0xc2f74000}, {0xc2f76000}, + {0xc2f78000}, {0xc2f7a000}, {0xc2f7c000}, {0xc2f7e000}, + {0xc2f80000}, {0xc2f82000}, {0xc2f84000}, {0xc2f86000}, + {0xc2f88000}, {0xc2f8a000}, {0xc2f8c000}, {0xc2f8e000}, + {0xc2f90000}, {0xc2f92000}, {0xc2f94000}, {0xc2f96000}, + {0xc2f98000}, {0xc2f9a000}, {0xc2f9c000}, {0xc2f9e000}, + {0xc2fa0000}, {0xc2fa2000}, {0xc2fa4000}, {0xc2fa6000}, + {0xc2fa8000}, {0xc2faa000}, {0xc2fac000}, {0xc2fae000}, + {0xc2fb0000}, {0xc2fb2000}, {0xc2fb4000}, {0xc2fb6000}, + {0xc2fb8000}, {0xc2fba000}, {0xc2fbc000}, {0xc2fbe000}, + {0xc2fc0000}, {0xc2fc2000}, {0xc2fc4000}, {0xc2fc6000}, + {0xc2fc8000}, {0xc2fca000}, {0xc2fcc000}, {0xc2fce000}, + {0xc2fd0000}, {0xc2fd2000}, {0xc2fd4000}, {0xc2fd6000}, + {0xc2fd8000}, {0xc2fda000}, {0xc2fdc000}, {0xc2fde000}, + {0xc2fe0000}, {0xc2fe2000}, {0xc2fe4000}, {0xc2fe6000}, + {0xc2fe8000}, {0xc2fea000}, {0xc2fec000}, {0xc2fee000}, + {0xc2ff0000}, {0xc2ff2000}, {0xc2ff4000}, {0xc2ff6000}, + {0xc2ff8000}, {0xc2ffa000}, {0xc2ffc000}, {0xc2ffe000}, + {0xc3000000}, {0xc3002000}, {0xc3004000}, {0xc3006000}, + {0xc3008000}, {0xc300a000}, {0xc300c000}, {0xc300e000}, + {0xc3010000}, {0xc3012000}, {0xc3014000}, {0xc3016000}, + {0xc3018000}, {0xc301a000}, {0xc301c000}, {0xc301e000}, + {0xc3020000}, {0xc3022000}, {0xc3024000}, {0xc3026000}, + {0xc3028000}, {0xc302a000}, {0xc302c000}, {0xc302e000}, + {0xc3030000}, {0xc3032000}, {0xc3034000}, {0xc3036000}, + {0xc3038000}, {0xc303a000}, {0xc303c000}, {0xc303e000}, + {0xc3040000}, {0xc3042000}, {0xc3044000}, {0xc3046000}, + {0xc3048000}, {0xc304a000}, {0xc304c000}, {0xc304e000}, + {0xc3050000}, {0xc3052000}, {0xc3054000}, {0xc3056000}, + {0xc3058000}, {0xc305a000}, {0xc305c000}, {0xc305e000}, + {0xc3060000}, {0xc3062000}, {0xc3064000}, {0xc3066000}, + {0xc3068000}, {0xc306a000}, {0xc306c000}, {0xc306e000}, + {0xc3070000}, {0xc3072000}, {0xc3074000}, {0xc3076000}, + {0xc3078000}, {0xc307a000}, {0xc307c000}, {0xc307e000}, + {0xc3080000}, {0xc3082000}, {0xc3084000}, {0xc3086000}, + {0xc3088000}, {0xc308a000}, {0xc308c000}, {0xc308e000}, + {0xc3090000}, {0xc3092000}, {0xc3094000}, {0xc3096000}, + {0xc3098000}, {0xc309a000}, {0xc309c000}, {0xc309e000}, + {0xc30a0000}, {0xc30a2000}, {0xc30a4000}, {0xc30a6000}, + {0xc30a8000}, {0xc30aa000}, {0xc30ac000}, {0xc30ae000}, + {0xc30b0000}, {0xc30b2000}, {0xc30b4000}, {0xc30b6000}, + {0xc30b8000}, {0xc30ba000}, {0xc30bc000}, {0xc30be000}, + {0xc30c0000}, {0xc30c2000}, {0xc30c4000}, {0xc30c6000}, + {0xc30c8000}, {0xc30ca000}, {0xc30cc000}, {0xc30ce000}, + {0xc30d0000}, {0xc30d2000}, {0xc30d4000}, {0xc30d6000}, + {0xc30d8000}, {0xc30da000}, {0xc30dc000}, {0xc30de000}, + {0xc30e0000}, {0xc30e2000}, {0xc30e4000}, {0xc30e6000}, + {0xc30e8000}, {0xc30ea000}, {0xc30ec000}, {0xc30ee000}, + {0xc30f0000}, {0xc30f2000}, {0xc30f4000}, {0xc30f6000}, + {0xc30f8000}, {0xc30fa000}, {0xc30fc000}, {0xc30fe000}, + {0xc3100000}, {0xc3102000}, {0xc3104000}, {0xc3106000}, + {0xc3108000}, {0xc310a000}, {0xc310c000}, {0xc310e000}, + {0xc3110000}, {0xc3112000}, {0xc3114000}, {0xc3116000}, + {0xc3118000}, {0xc311a000}, {0xc311c000}, {0xc311e000}, + {0xc3120000}, {0xc3122000}, {0xc3124000}, {0xc3126000}, + {0xc3128000}, {0xc312a000}, {0xc312c000}, {0xc312e000}, + {0xc3130000}, {0xc3132000}, {0xc3134000}, {0xc3136000}, + {0xc3138000}, {0xc313a000}, {0xc313c000}, {0xc313e000}, + {0xc3140000}, {0xc3142000}, {0xc3144000}, {0xc3146000}, + {0xc3148000}, {0xc314a000}, {0xc314c000}, {0xc314e000}, + {0xc3150000}, {0xc3152000}, {0xc3154000}, {0xc3156000}, + {0xc3158000}, {0xc315a000}, {0xc315c000}, {0xc315e000}, + {0xc3160000}, {0xc3162000}, {0xc3164000}, {0xc3166000}, + {0xc3168000}, {0xc316a000}, {0xc316c000}, {0xc316e000}, + {0xc3170000}, {0xc3172000}, {0xc3174000}, {0xc3176000}, + {0xc3178000}, {0xc317a000}, {0xc317c000}, {0xc317e000}, + {0xc3180000}, {0xc3182000}, {0xc3184000}, {0xc3186000}, + {0xc3188000}, {0xc318a000}, {0xc318c000}, {0xc318e000}, + {0xc3190000}, {0xc3192000}, {0xc3194000}, {0xc3196000}, + {0xc3198000}, {0xc319a000}, {0xc319c000}, {0xc319e000}, + {0xc31a0000}, {0xc31a2000}, {0xc31a4000}, {0xc31a6000}, + {0xc31a8000}, {0xc31aa000}, {0xc31ac000}, {0xc31ae000}, + {0xc31b0000}, {0xc31b2000}, {0xc31b4000}, {0xc31b6000}, + {0xc31b8000}, {0xc31ba000}, {0xc31bc000}, {0xc31be000}, + {0xc31c0000}, {0xc31c2000}, {0xc31c4000}, {0xc31c6000}, + {0xc31c8000}, {0xc31ca000}, {0xc31cc000}, {0xc31ce000}, + {0xc31d0000}, {0xc31d2000}, {0xc31d4000}, {0xc31d6000}, + {0xc31d8000}, {0xc31da000}, {0xc31dc000}, {0xc31de000}, + {0xc31e0000}, {0xc31e2000}, {0xc31e4000}, {0xc31e6000}, + {0xc31e8000}, {0xc31ea000}, {0xc31ec000}, {0xc31ee000}, + {0xc31f0000}, {0xc31f2000}, {0xc31f4000}, {0xc31f6000}, + {0xc31f8000}, {0xc31fa000}, {0xc31fc000}, {0xc31fe000}, + {0xc3200000}, {0xc3202000}, {0xc3204000}, {0xc3206000}, + {0xc3208000}, {0xc320a000}, {0xc320c000}, {0xc320e000}, + {0xc3210000}, {0xc3212000}, {0xc3214000}, {0xc3216000}, + {0xc3218000}, {0xc321a000}, {0xc321c000}, {0xc321e000}, + {0xc3220000}, {0xc3222000}, {0xc3224000}, {0xc3226000}, + {0xc3228000}, {0xc322a000}, {0xc322c000}, {0xc322e000}, + {0xc3230000}, {0xc3232000}, {0xc3234000}, {0xc3236000}, + {0xc3238000}, {0xc323a000}, {0xc323c000}, {0xc323e000}, + {0xc3240000}, {0xc3242000}, {0xc3244000}, {0xc3246000}, + {0xc3248000}, {0xc324a000}, {0xc324c000}, {0xc324e000}, + {0xc3250000}, {0xc3252000}, {0xc3254000}, {0xc3256000}, + {0xc3258000}, {0xc325a000}, {0xc325c000}, {0xc325e000}, + {0xc3260000}, {0xc3262000}, {0xc3264000}, {0xc3266000}, + {0xc3268000}, {0xc326a000}, {0xc326c000}, {0xc326e000}, + {0xc3270000}, {0xc3272000}, {0xc3274000}, {0xc3276000}, + {0xc3278000}, {0xc327a000}, {0xc327c000}, {0xc327e000}, + {0xc3280000}, {0xc3282000}, {0xc3284000}, {0xc3286000}, + {0xc3288000}, {0xc328a000}, {0xc328c000}, {0xc328e000}, + {0xc3290000}, {0xc3292000}, {0xc3294000}, {0xc3296000}, + {0xc3298000}, {0xc329a000}, {0xc329c000}, {0xc329e000}, + {0xc32a0000}, {0xc32a2000}, {0xc32a4000}, {0xc32a6000}, + {0xc32a8000}, {0xc32aa000}, {0xc32ac000}, {0xc32ae000}, + {0xc32b0000}, {0xc32b2000}, {0xc32b4000}, {0xc32b6000}, + {0xc32b8000}, {0xc32ba000}, {0xc32bc000}, {0xc32be000}, + {0xc32c0000}, {0xc32c2000}, {0xc32c4000}, {0xc32c6000}, + {0xc32c8000}, {0xc32ca000}, {0xc32cc000}, {0xc32ce000}, + {0xc32d0000}, {0xc32d2000}, {0xc32d4000}, {0xc32d6000}, + {0xc32d8000}, {0xc32da000}, {0xc32dc000}, {0xc32de000}, + {0xc32e0000}, {0xc32e2000}, {0xc32e4000}, {0xc32e6000}, + {0xc32e8000}, {0xc32ea000}, {0xc32ec000}, {0xc32ee000}, + {0xc32f0000}, {0xc32f2000}, {0xc32f4000}, {0xc32f6000}, + {0xc32f8000}, {0xc32fa000}, {0xc32fc000}, {0xc32fe000}, + {0xc3300000}, {0xc3302000}, {0xc3304000}, {0xc3306000}, + {0xc3308000}, {0xc330a000}, {0xc330c000}, {0xc330e000}, + {0xc3310000}, {0xc3312000}, {0xc3314000}, {0xc3316000}, + {0xc3318000}, {0xc331a000}, {0xc331c000}, {0xc331e000}, + {0xc3320000}, {0xc3322000}, {0xc3324000}, {0xc3326000}, + {0xc3328000}, {0xc332a000}, {0xc332c000}, {0xc332e000}, + {0xc3330000}, {0xc3332000}, {0xc3334000}, {0xc3336000}, + {0xc3338000}, {0xc333a000}, {0xc333c000}, {0xc333e000}, + {0xc3340000}, {0xc3342000}, {0xc3344000}, {0xc3346000}, + {0xc3348000}, {0xc334a000}, {0xc334c000}, {0xc334e000}, + {0xc3350000}, {0xc3352000}, {0xc3354000}, {0xc3356000}, + {0xc3358000}, {0xc335a000}, {0xc335c000}, {0xc335e000}, + {0xc3360000}, {0xc3362000}, {0xc3364000}, {0xc3366000}, + {0xc3368000}, {0xc336a000}, {0xc336c000}, {0xc336e000}, + {0xc3370000}, {0xc3372000}, {0xc3374000}, {0xc3376000}, + {0xc3378000}, {0xc337a000}, {0xc337c000}, {0xc337e000}, + {0xc3380000}, {0xc3382000}, {0xc3384000}, {0xc3386000}, + {0xc3388000}, {0xc338a000}, {0xc338c000}, {0xc338e000}, + {0xc3390000}, {0xc3392000}, {0xc3394000}, {0xc3396000}, + {0xc3398000}, {0xc339a000}, {0xc339c000}, {0xc339e000}, + {0xc33a0000}, {0xc33a2000}, {0xc33a4000}, {0xc33a6000}, + {0xc33a8000}, {0xc33aa000}, {0xc33ac000}, {0xc33ae000}, + {0xc33b0000}, {0xc33b2000}, {0xc33b4000}, {0xc33b6000}, + {0xc33b8000}, {0xc33ba000}, {0xc33bc000}, {0xc33be000}, + {0xc33c0000}, {0xc33c2000}, {0xc33c4000}, {0xc33c6000}, + {0xc33c8000}, {0xc33ca000}, {0xc33cc000}, {0xc33ce000}, + {0xc33d0000}, {0xc33d2000}, {0xc33d4000}, {0xc33d6000}, + {0xc33d8000}, {0xc33da000}, {0xc33dc000}, {0xc33de000}, + {0xc33e0000}, {0xc33e2000}, {0xc33e4000}, {0xc33e6000}, + {0xc33e8000}, {0xc33ea000}, {0xc33ec000}, {0xc33ee000}, + {0xc33f0000}, {0xc33f2000}, {0xc33f4000}, {0xc33f6000}, + {0xc33f8000}, {0xc33fa000}, {0xc33fc000}, {0xc33fe000}, + {0xc3400000}, {0xc3402000}, {0xc3404000}, {0xc3406000}, + {0xc3408000}, {0xc340a000}, {0xc340c000}, {0xc340e000}, + {0xc3410000}, {0xc3412000}, {0xc3414000}, {0xc3416000}, + {0xc3418000}, {0xc341a000}, {0xc341c000}, {0xc341e000}, + {0xc3420000}, {0xc3422000}, {0xc3424000}, {0xc3426000}, + {0xc3428000}, {0xc342a000}, {0xc342c000}, {0xc342e000}, + {0xc3430000}, {0xc3432000}, {0xc3434000}, {0xc3436000}, + {0xc3438000}, {0xc343a000}, {0xc343c000}, {0xc343e000}, + {0xc3440000}, {0xc3442000}, {0xc3444000}, {0xc3446000}, + {0xc3448000}, {0xc344a000}, {0xc344c000}, {0xc344e000}, + {0xc3450000}, {0xc3452000}, {0xc3454000}, {0xc3456000}, + {0xc3458000}, {0xc345a000}, {0xc345c000}, {0xc345e000}, + {0xc3460000}, {0xc3462000}, {0xc3464000}, {0xc3466000}, + {0xc3468000}, {0xc346a000}, {0xc346c000}, {0xc346e000}, + {0xc3470000}, {0xc3472000}, {0xc3474000}, {0xc3476000}, + {0xc3478000}, {0xc347a000}, {0xc347c000}, {0xc347e000}, + {0xc3480000}, {0xc3482000}, {0xc3484000}, {0xc3486000}, + {0xc3488000}, {0xc348a000}, {0xc348c000}, {0xc348e000}, + {0xc3490000}, {0xc3492000}, {0xc3494000}, {0xc3496000}, + {0xc3498000}, {0xc349a000}, {0xc349c000}, {0xc349e000}, + {0xc34a0000}, {0xc34a2000}, {0xc34a4000}, {0xc34a6000}, + {0xc34a8000}, {0xc34aa000}, {0xc34ac000}, {0xc34ae000}, + {0xc34b0000}, {0xc34b2000}, {0xc34b4000}, {0xc34b6000}, + {0xc34b8000}, {0xc34ba000}, {0xc34bc000}, {0xc34be000}, + {0xc34c0000}, {0xc34c2000}, {0xc34c4000}, {0xc34c6000}, + {0xc34c8000}, {0xc34ca000}, {0xc34cc000}, {0xc34ce000}, + {0xc34d0000}, {0xc34d2000}, {0xc34d4000}, {0xc34d6000}, + {0xc34d8000}, {0xc34da000}, {0xc34dc000}, {0xc34de000}, + {0xc34e0000}, {0xc34e2000}, {0xc34e4000}, {0xc34e6000}, + {0xc34e8000}, {0xc34ea000}, {0xc34ec000}, {0xc34ee000}, + {0xc34f0000}, {0xc34f2000}, {0xc34f4000}, {0xc34f6000}, + {0xc34f8000}, {0xc34fa000}, {0xc34fc000}, {0xc34fe000}, + {0xc3500000}, {0xc3502000}, {0xc3504000}, {0xc3506000}, + {0xc3508000}, {0xc350a000}, {0xc350c000}, {0xc350e000}, + {0xc3510000}, {0xc3512000}, {0xc3514000}, {0xc3516000}, + {0xc3518000}, {0xc351a000}, {0xc351c000}, {0xc351e000}, + {0xc3520000}, {0xc3522000}, {0xc3524000}, {0xc3526000}, + {0xc3528000}, {0xc352a000}, {0xc352c000}, {0xc352e000}, + {0xc3530000}, {0xc3532000}, {0xc3534000}, {0xc3536000}, + {0xc3538000}, {0xc353a000}, {0xc353c000}, {0xc353e000}, + {0xc3540000}, {0xc3542000}, {0xc3544000}, {0xc3546000}, + {0xc3548000}, {0xc354a000}, {0xc354c000}, {0xc354e000}, + {0xc3550000}, {0xc3552000}, {0xc3554000}, {0xc3556000}, + {0xc3558000}, {0xc355a000}, {0xc355c000}, {0xc355e000}, + {0xc3560000}, {0xc3562000}, {0xc3564000}, {0xc3566000}, + {0xc3568000}, {0xc356a000}, {0xc356c000}, {0xc356e000}, + {0xc3570000}, {0xc3572000}, {0xc3574000}, {0xc3576000}, + {0xc3578000}, {0xc357a000}, {0xc357c000}, {0xc357e000}, + {0xc3580000}, {0xc3582000}, {0xc3584000}, {0xc3586000}, + {0xc3588000}, {0xc358a000}, {0xc358c000}, {0xc358e000}, + {0xc3590000}, {0xc3592000}, {0xc3594000}, {0xc3596000}, + {0xc3598000}, {0xc359a000}, {0xc359c000}, {0xc359e000}, + {0xc35a0000}, {0xc35a2000}, {0xc35a4000}, {0xc35a6000}, + {0xc35a8000}, {0xc35aa000}, {0xc35ac000}, {0xc35ae000}, + {0xc35b0000}, {0xc35b2000}, {0xc35b4000}, {0xc35b6000}, + {0xc35b8000}, {0xc35ba000}, {0xc35bc000}, {0xc35be000}, + {0xc35c0000}, {0xc35c2000}, {0xc35c4000}, {0xc35c6000}, + {0xc35c8000}, {0xc35ca000}, {0xc35cc000}, {0xc35ce000}, + {0xc35d0000}, {0xc35d2000}, {0xc35d4000}, {0xc35d6000}, + {0xc35d8000}, {0xc35da000}, {0xc35dc000}, {0xc35de000}, + {0xc35e0000}, {0xc35e2000}, {0xc35e4000}, {0xc35e6000}, + {0xc35e8000}, {0xc35ea000}, {0xc35ec000}, {0xc35ee000}, + {0xc35f0000}, {0xc35f2000}, {0xc35f4000}, {0xc35f6000}, + {0xc35f8000}, {0xc35fa000}, {0xc35fc000}, {0xc35fe000}, + {0xc3600000}, {0xc3602000}, {0xc3604000}, {0xc3606000}, + {0xc3608000}, {0xc360a000}, {0xc360c000}, {0xc360e000}, + {0xc3610000}, {0xc3612000}, {0xc3614000}, {0xc3616000}, + {0xc3618000}, {0xc361a000}, {0xc361c000}, {0xc361e000}, + {0xc3620000}, {0xc3622000}, {0xc3624000}, {0xc3626000}, + {0xc3628000}, {0xc362a000}, {0xc362c000}, {0xc362e000}, + {0xc3630000}, {0xc3632000}, {0xc3634000}, {0xc3636000}, + {0xc3638000}, {0xc363a000}, {0xc363c000}, {0xc363e000}, + {0xc3640000}, {0xc3642000}, {0xc3644000}, {0xc3646000}, + {0xc3648000}, {0xc364a000}, {0xc364c000}, {0xc364e000}, + {0xc3650000}, {0xc3652000}, {0xc3654000}, {0xc3656000}, + {0xc3658000}, {0xc365a000}, {0xc365c000}, {0xc365e000}, + {0xc3660000}, {0xc3662000}, {0xc3664000}, {0xc3666000}, + {0xc3668000}, {0xc366a000}, {0xc366c000}, {0xc366e000}, + {0xc3670000}, {0xc3672000}, {0xc3674000}, {0xc3676000}, + {0xc3678000}, {0xc367a000}, {0xc367c000}, {0xc367e000}, + {0xc3680000}, {0xc3682000}, {0xc3684000}, {0xc3686000}, + {0xc3688000}, {0xc368a000}, {0xc368c000}, {0xc368e000}, + {0xc3690000}, {0xc3692000}, {0xc3694000}, {0xc3696000}, + {0xc3698000}, {0xc369a000}, {0xc369c000}, {0xc369e000}, + {0xc36a0000}, {0xc36a2000}, {0xc36a4000}, {0xc36a6000}, + {0xc36a8000}, {0xc36aa000}, {0xc36ac000}, {0xc36ae000}, + {0xc36b0000}, {0xc36b2000}, {0xc36b4000}, {0xc36b6000}, + {0xc36b8000}, {0xc36ba000}, {0xc36bc000}, {0xc36be000}, + {0xc36c0000}, {0xc36c2000}, {0xc36c4000}, {0xc36c6000}, + {0xc36c8000}, {0xc36ca000}, {0xc36cc000}, {0xc36ce000}, + {0xc36d0000}, {0xc36d2000}, {0xc36d4000}, {0xc36d6000}, + {0xc36d8000}, {0xc36da000}, {0xc36dc000}, {0xc36de000}, + {0xc36e0000}, {0xc36e2000}, {0xc36e4000}, {0xc36e6000}, + {0xc36e8000}, {0xc36ea000}, {0xc36ec000}, {0xc36ee000}, + {0xc36f0000}, {0xc36f2000}, {0xc36f4000}, {0xc36f6000}, + {0xc36f8000}, {0xc36fa000}, {0xc36fc000}, {0xc36fe000}, + {0xc3700000}, {0xc3702000}, {0xc3704000}, {0xc3706000}, + {0xc3708000}, {0xc370a000}, {0xc370c000}, {0xc370e000}, + {0xc3710000}, {0xc3712000}, {0xc3714000}, {0xc3716000}, + {0xc3718000}, {0xc371a000}, {0xc371c000}, {0xc371e000}, + {0xc3720000}, {0xc3722000}, {0xc3724000}, {0xc3726000}, + {0xc3728000}, {0xc372a000}, {0xc372c000}, {0xc372e000}, + {0xc3730000}, {0xc3732000}, {0xc3734000}, {0xc3736000}, + {0xc3738000}, {0xc373a000}, {0xc373c000}, {0xc373e000}, + {0xc3740000}, {0xc3742000}, {0xc3744000}, {0xc3746000}, + {0xc3748000}, {0xc374a000}, {0xc374c000}, {0xc374e000}, + {0xc3750000}, {0xc3752000}, {0xc3754000}, {0xc3756000}, + {0xc3758000}, {0xc375a000}, {0xc375c000}, {0xc375e000}, + {0xc3760000}, {0xc3762000}, {0xc3764000}, {0xc3766000}, + {0xc3768000}, {0xc376a000}, {0xc376c000}, {0xc376e000}, + {0xc3770000}, {0xc3772000}, {0xc3774000}, {0xc3776000}, + {0xc3778000}, {0xc377a000}, {0xc377c000}, {0xc377e000}, + {0xc3780000}, {0xc3782000}, {0xc3784000}, {0xc3786000}, + {0xc3788000}, {0xc378a000}, {0xc378c000}, {0xc378e000}, + {0xc3790000}, {0xc3792000}, {0xc3794000}, {0xc3796000}, + {0xc3798000}, {0xc379a000}, {0xc379c000}, {0xc379e000}, + {0xc37a0000}, {0xc37a2000}, {0xc37a4000}, {0xc37a6000}, + {0xc37a8000}, {0xc37aa000}, {0xc37ac000}, {0xc37ae000}, + {0xc37b0000}, {0xc37b2000}, {0xc37b4000}, {0xc37b6000}, + {0xc37b8000}, {0xc37ba000}, {0xc37bc000}, {0xc37be000}, + {0xc37c0000}, {0xc37c2000}, {0xc37c4000}, {0xc37c6000}, + {0xc37c8000}, {0xc37ca000}, {0xc37cc000}, {0xc37ce000}, + {0xc37d0000}, {0xc37d2000}, {0xc37d4000}, {0xc37d6000}, + {0xc37d8000}, {0xc37da000}, {0xc37dc000}, {0xc37de000}, + {0xc37e0000}, {0xc37e2000}, {0xc37e4000}, {0xc37e6000}, + {0xc37e8000}, {0xc37ea000}, {0xc37ec000}, {0xc37ee000}, + {0xc37f0000}, {0xc37f2000}, {0xc37f4000}, {0xc37f6000}, + {0xc37f8000}, {0xc37fa000}, {0xc37fc000}, {0xc37fe000}, + {0xc3800000}, {0xc3802000}, {0xc3804000}, {0xc3806000}, + {0xc3808000}, {0xc380a000}, {0xc380c000}, {0xc380e000}, + {0xc3810000}, {0xc3812000}, {0xc3814000}, {0xc3816000}, + {0xc3818000}, {0xc381a000}, {0xc381c000}, {0xc381e000}, + {0xc3820000}, {0xc3822000}, {0xc3824000}, {0xc3826000}, + {0xc3828000}, {0xc382a000}, {0xc382c000}, {0xc382e000}, + {0xc3830000}, {0xc3832000}, {0xc3834000}, {0xc3836000}, + {0xc3838000}, {0xc383a000}, {0xc383c000}, {0xc383e000}, + {0xc3840000}, {0xc3842000}, {0xc3844000}, {0xc3846000}, + {0xc3848000}, {0xc384a000}, {0xc384c000}, {0xc384e000}, + {0xc3850000}, {0xc3852000}, {0xc3854000}, {0xc3856000}, + {0xc3858000}, {0xc385a000}, {0xc385c000}, {0xc385e000}, + {0xc3860000}, {0xc3862000}, {0xc3864000}, {0xc3866000}, + {0xc3868000}, {0xc386a000}, {0xc386c000}, {0xc386e000}, + {0xc3870000}, {0xc3872000}, {0xc3874000}, {0xc3876000}, + {0xc3878000}, {0xc387a000}, {0xc387c000}, {0xc387e000}, + {0xc3880000}, {0xc3882000}, {0xc3884000}, {0xc3886000}, + {0xc3888000}, {0xc388a000}, {0xc388c000}, {0xc388e000}, + {0xc3890000}, {0xc3892000}, {0xc3894000}, {0xc3896000}, + {0xc3898000}, {0xc389a000}, {0xc389c000}, {0xc389e000}, + {0xc38a0000}, {0xc38a2000}, {0xc38a4000}, {0xc38a6000}, + {0xc38a8000}, {0xc38aa000}, {0xc38ac000}, {0xc38ae000}, + {0xc38b0000}, {0xc38b2000}, {0xc38b4000}, {0xc38b6000}, + {0xc38b8000}, {0xc38ba000}, {0xc38bc000}, {0xc38be000}, + {0xc38c0000}, {0xc38c2000}, {0xc38c4000}, {0xc38c6000}, + {0xc38c8000}, {0xc38ca000}, {0xc38cc000}, {0xc38ce000}, + {0xc38d0000}, {0xc38d2000}, {0xc38d4000}, {0xc38d6000}, + {0xc38d8000}, {0xc38da000}, {0xc38dc000}, {0xc38de000}, + {0xc38e0000}, {0xc38e2000}, {0xc38e4000}, {0xc38e6000}, + {0xc38e8000}, {0xc38ea000}, {0xc38ec000}, {0xc38ee000}, + {0xc38f0000}, {0xc38f2000}, {0xc38f4000}, {0xc38f6000}, + {0xc38f8000}, {0xc38fa000}, {0xc38fc000}, {0xc38fe000}, + {0xc3900000}, {0xc3902000}, {0xc3904000}, {0xc3906000}, + {0xc3908000}, {0xc390a000}, {0xc390c000}, {0xc390e000}, + {0xc3910000}, {0xc3912000}, {0xc3914000}, {0xc3916000}, + {0xc3918000}, {0xc391a000}, {0xc391c000}, {0xc391e000}, + {0xc3920000}, {0xc3922000}, {0xc3924000}, {0xc3926000}, + {0xc3928000}, {0xc392a000}, {0xc392c000}, {0xc392e000}, + {0xc3930000}, {0xc3932000}, {0xc3934000}, {0xc3936000}, + {0xc3938000}, {0xc393a000}, {0xc393c000}, {0xc393e000}, + {0xc3940000}, {0xc3942000}, {0xc3944000}, {0xc3946000}, + {0xc3948000}, {0xc394a000}, {0xc394c000}, {0xc394e000}, + {0xc3950000}, {0xc3952000}, {0xc3954000}, {0xc3956000}, + {0xc3958000}, {0xc395a000}, {0xc395c000}, {0xc395e000}, + {0xc3960000}, {0xc3962000}, {0xc3964000}, {0xc3966000}, + {0xc3968000}, {0xc396a000}, {0xc396c000}, {0xc396e000}, + {0xc3970000}, {0xc3972000}, {0xc3974000}, {0xc3976000}, + {0xc3978000}, {0xc397a000}, {0xc397c000}, {0xc397e000}, + {0xc3980000}, {0xc3982000}, {0xc3984000}, {0xc3986000}, + {0xc3988000}, {0xc398a000}, {0xc398c000}, {0xc398e000}, + {0xc3990000}, {0xc3992000}, {0xc3994000}, {0xc3996000}, + {0xc3998000}, {0xc399a000}, {0xc399c000}, {0xc399e000}, + {0xc39a0000}, {0xc39a2000}, {0xc39a4000}, {0xc39a6000}, + {0xc39a8000}, {0xc39aa000}, {0xc39ac000}, {0xc39ae000}, + {0xc39b0000}, {0xc39b2000}, {0xc39b4000}, {0xc39b6000}, + {0xc39b8000}, {0xc39ba000}, {0xc39bc000}, {0xc39be000}, + {0xc39c0000}, {0xc39c2000}, {0xc39c4000}, {0xc39c6000}, + {0xc39c8000}, {0xc39ca000}, {0xc39cc000}, {0xc39ce000}, + {0xc39d0000}, {0xc39d2000}, {0xc39d4000}, {0xc39d6000}, + {0xc39d8000}, {0xc39da000}, {0xc39dc000}, {0xc39de000}, + {0xc39e0000}, {0xc39e2000}, {0xc39e4000}, {0xc39e6000}, + {0xc39e8000}, {0xc39ea000}, {0xc39ec000}, {0xc39ee000}, + {0xc39f0000}, {0xc39f2000}, {0xc39f4000}, {0xc39f6000}, + {0xc39f8000}, {0xc39fa000}, {0xc39fc000}, {0xc39fe000}, + {0xc3a00000}, {0xc3a02000}, {0xc3a04000}, {0xc3a06000}, + {0xc3a08000}, {0xc3a0a000}, {0xc3a0c000}, {0xc3a0e000}, + {0xc3a10000}, {0xc3a12000}, {0xc3a14000}, {0xc3a16000}, + {0xc3a18000}, {0xc3a1a000}, {0xc3a1c000}, {0xc3a1e000}, + {0xc3a20000}, {0xc3a22000}, {0xc3a24000}, {0xc3a26000}, + {0xc3a28000}, {0xc3a2a000}, {0xc3a2c000}, {0xc3a2e000}, + {0xc3a30000}, {0xc3a32000}, {0xc3a34000}, {0xc3a36000}, + {0xc3a38000}, {0xc3a3a000}, {0xc3a3c000}, {0xc3a3e000}, + {0xc3a40000}, {0xc3a42000}, {0xc3a44000}, {0xc3a46000}, + {0xc3a48000}, {0xc3a4a000}, {0xc3a4c000}, {0xc3a4e000}, + {0xc3a50000}, {0xc3a52000}, {0xc3a54000}, {0xc3a56000}, + {0xc3a58000}, {0xc3a5a000}, {0xc3a5c000}, {0xc3a5e000}, + {0xc3a60000}, {0xc3a62000}, {0xc3a64000}, {0xc3a66000}, + {0xc3a68000}, {0xc3a6a000}, {0xc3a6c000}, {0xc3a6e000}, + {0xc3a70000}, {0xc3a72000}, {0xc3a74000}, {0xc3a76000}, + {0xc3a78000}, {0xc3a7a000}, {0xc3a7c000}, {0xc3a7e000}, + {0xc3a80000}, {0xc3a82000}, {0xc3a84000}, {0xc3a86000}, + {0xc3a88000}, {0xc3a8a000}, {0xc3a8c000}, {0xc3a8e000}, + {0xc3a90000}, {0xc3a92000}, {0xc3a94000}, {0xc3a96000}, + {0xc3a98000}, {0xc3a9a000}, {0xc3a9c000}, {0xc3a9e000}, + {0xc3aa0000}, {0xc3aa2000}, {0xc3aa4000}, {0xc3aa6000}, + {0xc3aa8000}, {0xc3aaa000}, {0xc3aac000}, {0xc3aae000}, + {0xc3ab0000}, {0xc3ab2000}, {0xc3ab4000}, {0xc3ab6000}, + {0xc3ab8000}, {0xc3aba000}, {0xc3abc000}, {0xc3abe000}, + {0xc3ac0000}, {0xc3ac2000}, {0xc3ac4000}, {0xc3ac6000}, + {0xc3ac8000}, {0xc3aca000}, {0xc3acc000}, {0xc3ace000}, + {0xc3ad0000}, {0xc3ad2000}, {0xc3ad4000}, {0xc3ad6000}, + {0xc3ad8000}, {0xc3ada000}, {0xc3adc000}, {0xc3ade000}, + {0xc3ae0000}, {0xc3ae2000}, {0xc3ae4000}, {0xc3ae6000}, + {0xc3ae8000}, {0xc3aea000}, {0xc3aec000}, {0xc3aee000}, + {0xc3af0000}, {0xc3af2000}, {0xc3af4000}, {0xc3af6000}, + {0xc3af8000}, {0xc3afa000}, {0xc3afc000}, {0xc3afe000}, + {0xc3b00000}, {0xc3b02000}, {0xc3b04000}, {0xc3b06000}, + {0xc3b08000}, {0xc3b0a000}, {0xc3b0c000}, {0xc3b0e000}, + {0xc3b10000}, {0xc3b12000}, {0xc3b14000}, {0xc3b16000}, + {0xc3b18000}, {0xc3b1a000}, {0xc3b1c000}, {0xc3b1e000}, + {0xc3b20000}, {0xc3b22000}, {0xc3b24000}, {0xc3b26000}, + {0xc3b28000}, {0xc3b2a000}, {0xc3b2c000}, {0xc3b2e000}, + {0xc3b30000}, {0xc3b32000}, {0xc3b34000}, {0xc3b36000}, + {0xc3b38000}, {0xc3b3a000}, {0xc3b3c000}, {0xc3b3e000}, + {0xc3b40000}, {0xc3b42000}, {0xc3b44000}, {0xc3b46000}, + {0xc3b48000}, {0xc3b4a000}, {0xc3b4c000}, {0xc3b4e000}, + {0xc3b50000}, {0xc3b52000}, {0xc3b54000}, {0xc3b56000}, + {0xc3b58000}, {0xc3b5a000}, {0xc3b5c000}, {0xc3b5e000}, + {0xc3b60000}, {0xc3b62000}, {0xc3b64000}, {0xc3b66000}, + {0xc3b68000}, {0xc3b6a000}, {0xc3b6c000}, {0xc3b6e000}, + {0xc3b70000}, {0xc3b72000}, {0xc3b74000}, {0xc3b76000}, + {0xc3b78000}, {0xc3b7a000}, {0xc3b7c000}, {0xc3b7e000}, + {0xc3b80000}, {0xc3b82000}, {0xc3b84000}, {0xc3b86000}, + {0xc3b88000}, {0xc3b8a000}, {0xc3b8c000}, {0xc3b8e000}, + {0xc3b90000}, {0xc3b92000}, {0xc3b94000}, {0xc3b96000}, + {0xc3b98000}, {0xc3b9a000}, {0xc3b9c000}, {0xc3b9e000}, + {0xc3ba0000}, {0xc3ba2000}, {0xc3ba4000}, {0xc3ba6000}, + {0xc3ba8000}, {0xc3baa000}, {0xc3bac000}, {0xc3bae000}, + {0xc3bb0000}, {0xc3bb2000}, {0xc3bb4000}, {0xc3bb6000}, + {0xc3bb8000}, {0xc3bba000}, {0xc3bbc000}, {0xc3bbe000}, + {0xc3bc0000}, {0xc3bc2000}, {0xc3bc4000}, {0xc3bc6000}, + {0xc3bc8000}, {0xc3bca000}, {0xc3bcc000}, {0xc3bce000}, + {0xc3bd0000}, {0xc3bd2000}, {0xc3bd4000}, {0xc3bd6000}, + {0xc3bd8000}, {0xc3bda000}, {0xc3bdc000}, {0xc3bde000}, + {0xc3be0000}, {0xc3be2000}, {0xc3be4000}, {0xc3be6000}, + {0xc3be8000}, {0xc3bea000}, {0xc3bec000}, {0xc3bee000}, + {0xc3bf0000}, {0xc3bf2000}, {0xc3bf4000}, {0xc3bf6000}, + {0xc3bf8000}, {0xc3bfa000}, {0xc3bfc000}, {0xc3bfe000}, + {0xc3c00000}, {0xc3c02000}, {0xc3c04000}, {0xc3c06000}, + {0xc3c08000}, {0xc3c0a000}, {0xc3c0c000}, {0xc3c0e000}, + {0xc3c10000}, {0xc3c12000}, {0xc3c14000}, {0xc3c16000}, + {0xc3c18000}, {0xc3c1a000}, {0xc3c1c000}, {0xc3c1e000}, + {0xc3c20000}, {0xc3c22000}, {0xc3c24000}, {0xc3c26000}, + {0xc3c28000}, {0xc3c2a000}, {0xc3c2c000}, {0xc3c2e000}, + {0xc3c30000}, {0xc3c32000}, {0xc3c34000}, {0xc3c36000}, + {0xc3c38000}, {0xc3c3a000}, {0xc3c3c000}, {0xc3c3e000}, + {0xc3c40000}, {0xc3c42000}, {0xc3c44000}, {0xc3c46000}, + {0xc3c48000}, {0xc3c4a000}, {0xc3c4c000}, {0xc3c4e000}, + {0xc3c50000}, {0xc3c52000}, {0xc3c54000}, {0xc3c56000}, + {0xc3c58000}, {0xc3c5a000}, {0xc3c5c000}, {0xc3c5e000}, + {0xc3c60000}, {0xc3c62000}, {0xc3c64000}, {0xc3c66000}, + {0xc3c68000}, {0xc3c6a000}, {0xc3c6c000}, {0xc3c6e000}, + {0xc3c70000}, {0xc3c72000}, {0xc3c74000}, {0xc3c76000}, + {0xc3c78000}, {0xc3c7a000}, {0xc3c7c000}, {0xc3c7e000}, + {0xc3c80000}, {0xc3c82000}, {0xc3c84000}, {0xc3c86000}, + {0xc3c88000}, {0xc3c8a000}, {0xc3c8c000}, {0xc3c8e000}, + {0xc3c90000}, {0xc3c92000}, {0xc3c94000}, {0xc3c96000}, + {0xc3c98000}, {0xc3c9a000}, {0xc3c9c000}, {0xc3c9e000}, + {0xc3ca0000}, {0xc3ca2000}, {0xc3ca4000}, {0xc3ca6000}, + {0xc3ca8000}, {0xc3caa000}, {0xc3cac000}, {0xc3cae000}, + {0xc3cb0000}, {0xc3cb2000}, {0xc3cb4000}, {0xc3cb6000}, + {0xc3cb8000}, {0xc3cba000}, {0xc3cbc000}, {0xc3cbe000}, + {0xc3cc0000}, {0xc3cc2000}, {0xc3cc4000}, {0xc3cc6000}, + {0xc3cc8000}, {0xc3cca000}, {0xc3ccc000}, {0xc3cce000}, + {0xc3cd0000}, {0xc3cd2000}, {0xc3cd4000}, {0xc3cd6000}, + {0xc3cd8000}, {0xc3cda000}, {0xc3cdc000}, {0xc3cde000}, + {0xc3ce0000}, {0xc3ce2000}, {0xc3ce4000}, {0xc3ce6000}, + {0xc3ce8000}, {0xc3cea000}, {0xc3cec000}, {0xc3cee000}, + {0xc3cf0000}, {0xc3cf2000}, {0xc3cf4000}, {0xc3cf6000}, + {0xc3cf8000}, {0xc3cfa000}, {0xc3cfc000}, {0xc3cfe000}, + {0xc3d00000}, {0xc3d02000}, {0xc3d04000}, {0xc3d06000}, + {0xc3d08000}, {0xc3d0a000}, {0xc3d0c000}, {0xc3d0e000}, + {0xc3d10000}, {0xc3d12000}, {0xc3d14000}, {0xc3d16000}, + {0xc3d18000}, {0xc3d1a000}, {0xc3d1c000}, {0xc3d1e000}, + {0xc3d20000}, {0xc3d22000}, {0xc3d24000}, {0xc3d26000}, + {0xc3d28000}, {0xc3d2a000}, {0xc3d2c000}, {0xc3d2e000}, + {0xc3d30000}, {0xc3d32000}, {0xc3d34000}, {0xc3d36000}, + {0xc3d38000}, {0xc3d3a000}, {0xc3d3c000}, {0xc3d3e000}, + {0xc3d40000}, {0xc3d42000}, {0xc3d44000}, {0xc3d46000}, + {0xc3d48000}, {0xc3d4a000}, {0xc3d4c000}, {0xc3d4e000}, + {0xc3d50000}, {0xc3d52000}, {0xc3d54000}, {0xc3d56000}, + {0xc3d58000}, {0xc3d5a000}, {0xc3d5c000}, {0xc3d5e000}, + {0xc3d60000}, {0xc3d62000}, {0xc3d64000}, {0xc3d66000}, + {0xc3d68000}, {0xc3d6a000}, {0xc3d6c000}, {0xc3d6e000}, + {0xc3d70000}, {0xc3d72000}, {0xc3d74000}, {0xc3d76000}, + {0xc3d78000}, {0xc3d7a000}, {0xc3d7c000}, {0xc3d7e000}, + {0xc3d80000}, {0xc3d82000}, {0xc3d84000}, {0xc3d86000}, + {0xc3d88000}, {0xc3d8a000}, {0xc3d8c000}, {0xc3d8e000}, + {0xc3d90000}, {0xc3d92000}, {0xc3d94000}, {0xc3d96000}, + {0xc3d98000}, {0xc3d9a000}, {0xc3d9c000}, {0xc3d9e000}, + {0xc3da0000}, {0xc3da2000}, {0xc3da4000}, {0xc3da6000}, + {0xc3da8000}, {0xc3daa000}, {0xc3dac000}, {0xc3dae000}, + {0xc3db0000}, {0xc3db2000}, {0xc3db4000}, {0xc3db6000}, + {0xc3db8000}, {0xc3dba000}, {0xc3dbc000}, {0xc3dbe000}, + {0xc3dc0000}, {0xc3dc2000}, {0xc3dc4000}, {0xc3dc6000}, + {0xc3dc8000}, {0xc3dca000}, {0xc3dcc000}, {0xc3dce000}, + {0xc3dd0000}, {0xc3dd2000}, {0xc3dd4000}, {0xc3dd6000}, + {0xc3dd8000}, {0xc3dda000}, {0xc3ddc000}, {0xc3dde000}, + {0xc3de0000}, {0xc3de2000}, {0xc3de4000}, {0xc3de6000}, + {0xc3de8000}, {0xc3dea000}, {0xc3dec000}, {0xc3dee000}, + {0xc3df0000}, {0xc3df2000}, {0xc3df4000}, {0xc3df6000}, + {0xc3df8000}, {0xc3dfa000}, {0xc3dfc000}, {0xc3dfe000}, + {0xc3e00000}, {0xc3e02000}, {0xc3e04000}, {0xc3e06000}, + {0xc3e08000}, {0xc3e0a000}, {0xc3e0c000}, {0xc3e0e000}, + {0xc3e10000}, {0xc3e12000}, {0xc3e14000}, {0xc3e16000}, + {0xc3e18000}, {0xc3e1a000}, {0xc3e1c000}, {0xc3e1e000}, + {0xc3e20000}, {0xc3e22000}, {0xc3e24000}, {0xc3e26000}, + {0xc3e28000}, {0xc3e2a000}, {0xc3e2c000}, {0xc3e2e000}, + {0xc3e30000}, {0xc3e32000}, {0xc3e34000}, {0xc3e36000}, + {0xc3e38000}, {0xc3e3a000}, {0xc3e3c000}, {0xc3e3e000}, + {0xc3e40000}, {0xc3e42000}, {0xc3e44000}, {0xc3e46000}, + {0xc3e48000}, {0xc3e4a000}, {0xc3e4c000}, {0xc3e4e000}, + {0xc3e50000}, {0xc3e52000}, {0xc3e54000}, {0xc3e56000}, + {0xc3e58000}, {0xc3e5a000}, {0xc3e5c000}, {0xc3e5e000}, + {0xc3e60000}, {0xc3e62000}, {0xc3e64000}, {0xc3e66000}, + {0xc3e68000}, {0xc3e6a000}, {0xc3e6c000}, {0xc3e6e000}, + {0xc3e70000}, {0xc3e72000}, {0xc3e74000}, {0xc3e76000}, + {0xc3e78000}, {0xc3e7a000}, {0xc3e7c000}, {0xc3e7e000}, + {0xc3e80000}, {0xc3e82000}, {0xc3e84000}, {0xc3e86000}, + {0xc3e88000}, {0xc3e8a000}, {0xc3e8c000}, {0xc3e8e000}, + {0xc3e90000}, {0xc3e92000}, {0xc3e94000}, {0xc3e96000}, + {0xc3e98000}, {0xc3e9a000}, {0xc3e9c000}, {0xc3e9e000}, + {0xc3ea0000}, {0xc3ea2000}, {0xc3ea4000}, {0xc3ea6000}, + {0xc3ea8000}, {0xc3eaa000}, {0xc3eac000}, {0xc3eae000}, + {0xc3eb0000}, {0xc3eb2000}, {0xc3eb4000}, {0xc3eb6000}, + {0xc3eb8000}, {0xc3eba000}, {0xc3ebc000}, {0xc3ebe000}, + {0xc3ec0000}, {0xc3ec2000}, {0xc3ec4000}, {0xc3ec6000}, + {0xc3ec8000}, {0xc3eca000}, {0xc3ecc000}, {0xc3ece000}, + {0xc3ed0000}, {0xc3ed2000}, {0xc3ed4000}, {0xc3ed6000}, + {0xc3ed8000}, {0xc3eda000}, {0xc3edc000}, {0xc3ede000}, + {0xc3ee0000}, {0xc3ee2000}, {0xc3ee4000}, {0xc3ee6000}, + {0xc3ee8000}, {0xc3eea000}, {0xc3eec000}, {0xc3eee000}, + {0xc3ef0000}, {0xc3ef2000}, {0xc3ef4000}, {0xc3ef6000}, + {0xc3ef8000}, {0xc3efa000}, {0xc3efc000}, {0xc3efe000}, + {0xc3f00000}, {0xc3f02000}, {0xc3f04000}, {0xc3f06000}, + {0xc3f08000}, {0xc3f0a000}, {0xc3f0c000}, {0xc3f0e000}, + {0xc3f10000}, {0xc3f12000}, {0xc3f14000}, {0xc3f16000}, + {0xc3f18000}, {0xc3f1a000}, {0xc3f1c000}, {0xc3f1e000}, + {0xc3f20000}, {0xc3f22000}, {0xc3f24000}, {0xc3f26000}, + {0xc3f28000}, {0xc3f2a000}, {0xc3f2c000}, {0xc3f2e000}, + {0xc3f30000}, {0xc3f32000}, {0xc3f34000}, {0xc3f36000}, + {0xc3f38000}, {0xc3f3a000}, {0xc3f3c000}, {0xc3f3e000}, + {0xc3f40000}, {0xc3f42000}, {0xc3f44000}, {0xc3f46000}, + {0xc3f48000}, {0xc3f4a000}, {0xc3f4c000}, {0xc3f4e000}, + {0xc3f50000}, {0xc3f52000}, {0xc3f54000}, {0xc3f56000}, + {0xc3f58000}, {0xc3f5a000}, {0xc3f5c000}, {0xc3f5e000}, + {0xc3f60000}, {0xc3f62000}, {0xc3f64000}, {0xc3f66000}, + {0xc3f68000}, {0xc3f6a000}, {0xc3f6c000}, {0xc3f6e000}, + {0xc3f70000}, {0xc3f72000}, {0xc3f74000}, {0xc3f76000}, + {0xc3f78000}, {0xc3f7a000}, {0xc3f7c000}, {0xc3f7e000}, + {0xc3f80000}, {0xc3f82000}, {0xc3f84000}, {0xc3f86000}, + {0xc3f88000}, {0xc3f8a000}, {0xc3f8c000}, {0xc3f8e000}, + {0xc3f90000}, {0xc3f92000}, {0xc3f94000}, {0xc3f96000}, + {0xc3f98000}, {0xc3f9a000}, {0xc3f9c000}, {0xc3f9e000}, + {0xc3fa0000}, {0xc3fa2000}, {0xc3fa4000}, {0xc3fa6000}, + {0xc3fa8000}, {0xc3faa000}, {0xc3fac000}, {0xc3fae000}, + {0xc3fb0000}, {0xc3fb2000}, {0xc3fb4000}, {0xc3fb6000}, + {0xc3fb8000}, {0xc3fba000}, {0xc3fbc000}, {0xc3fbe000}, + {0xc3fc0000}, {0xc3fc2000}, {0xc3fc4000}, {0xc3fc6000}, + {0xc3fc8000}, {0xc3fca000}, {0xc3fcc000}, {0xc3fce000}, + {0xc3fd0000}, {0xc3fd2000}, {0xc3fd4000}, {0xc3fd6000}, + {0xc3fd8000}, {0xc3fda000}, {0xc3fdc000}, {0xc3fde000}, + {0xc3fe0000}, {0xc3fe2000}, {0xc3fe4000}, {0xc3fe6000}, + {0xc3fe8000}, {0xc3fea000}, {0xc3fec000}, {0xc3fee000}, + {0xc3ff0000}, {0xc3ff2000}, {0xc3ff4000}, {0xc3ff6000}, + {0xc3ff8000}, {0xc3ffa000}, {0xc3ffc000}, {0xc3ffe000}, + {0xc4000000}, {0xc4002000}, {0xc4004000}, {0xc4006000}, + {0xc4008000}, {0xc400a000}, {0xc400c000}, {0xc400e000}, + {0xc4010000}, {0xc4012000}, {0xc4014000}, {0xc4016000}, + {0xc4018000}, {0xc401a000}, {0xc401c000}, {0xc401e000}, + {0xc4020000}, {0xc4022000}, {0xc4024000}, {0xc4026000}, + {0xc4028000}, {0xc402a000}, {0xc402c000}, {0xc402e000}, + {0xc4030000}, {0xc4032000}, {0xc4034000}, {0xc4036000}, + {0xc4038000}, {0xc403a000}, {0xc403c000}, {0xc403e000}, + {0xc4040000}, {0xc4042000}, {0xc4044000}, {0xc4046000}, + {0xc4048000}, {0xc404a000}, {0xc404c000}, {0xc404e000}, + {0xc4050000}, {0xc4052000}, {0xc4054000}, {0xc4056000}, + {0xc4058000}, {0xc405a000}, {0xc405c000}, {0xc405e000}, + {0xc4060000}, {0xc4062000}, {0xc4064000}, {0xc4066000}, + {0xc4068000}, {0xc406a000}, {0xc406c000}, {0xc406e000}, + {0xc4070000}, {0xc4072000}, {0xc4074000}, {0xc4076000}, + {0xc4078000}, {0xc407a000}, {0xc407c000}, {0xc407e000}, + {0xc4080000}, {0xc4082000}, {0xc4084000}, {0xc4086000}, + {0xc4088000}, {0xc408a000}, {0xc408c000}, {0xc408e000}, + {0xc4090000}, {0xc4092000}, {0xc4094000}, {0xc4096000}, + {0xc4098000}, {0xc409a000}, {0xc409c000}, {0xc409e000}, + {0xc40a0000}, {0xc40a2000}, {0xc40a4000}, {0xc40a6000}, + {0xc40a8000}, {0xc40aa000}, {0xc40ac000}, {0xc40ae000}, + {0xc40b0000}, {0xc40b2000}, {0xc40b4000}, {0xc40b6000}, + {0xc40b8000}, {0xc40ba000}, {0xc40bc000}, {0xc40be000}, + {0xc40c0000}, {0xc40c2000}, {0xc40c4000}, {0xc40c6000}, + {0xc40c8000}, {0xc40ca000}, {0xc40cc000}, {0xc40ce000}, + {0xc40d0000}, {0xc40d2000}, {0xc40d4000}, {0xc40d6000}, + {0xc40d8000}, {0xc40da000}, {0xc40dc000}, {0xc40de000}, + {0xc40e0000}, {0xc40e2000}, {0xc40e4000}, {0xc40e6000}, + {0xc40e8000}, {0xc40ea000}, {0xc40ec000}, {0xc40ee000}, + {0xc40f0000}, {0xc40f2000}, {0xc40f4000}, {0xc40f6000}, + {0xc40f8000}, {0xc40fa000}, {0xc40fc000}, {0xc40fe000}, + {0xc4100000}, {0xc4102000}, {0xc4104000}, {0xc4106000}, + {0xc4108000}, {0xc410a000}, {0xc410c000}, {0xc410e000}, + {0xc4110000}, {0xc4112000}, {0xc4114000}, {0xc4116000}, + {0xc4118000}, {0xc411a000}, {0xc411c000}, {0xc411e000}, + {0xc4120000}, {0xc4122000}, {0xc4124000}, {0xc4126000}, + {0xc4128000}, {0xc412a000}, {0xc412c000}, {0xc412e000}, + {0xc4130000}, {0xc4132000}, {0xc4134000}, {0xc4136000}, + {0xc4138000}, {0xc413a000}, {0xc413c000}, {0xc413e000}, + {0xc4140000}, {0xc4142000}, {0xc4144000}, {0xc4146000}, + {0xc4148000}, {0xc414a000}, {0xc414c000}, {0xc414e000}, + {0xc4150000}, {0xc4152000}, {0xc4154000}, {0xc4156000}, + {0xc4158000}, {0xc415a000}, {0xc415c000}, {0xc415e000}, + {0xc4160000}, {0xc4162000}, {0xc4164000}, {0xc4166000}, + {0xc4168000}, {0xc416a000}, {0xc416c000}, {0xc416e000}, + {0xc4170000}, {0xc4172000}, {0xc4174000}, {0xc4176000}, + {0xc4178000}, {0xc417a000}, {0xc417c000}, {0xc417e000}, + {0xc4180000}, {0xc4182000}, {0xc4184000}, {0xc4186000}, + {0xc4188000}, {0xc418a000}, {0xc418c000}, {0xc418e000}, + {0xc4190000}, {0xc4192000}, {0xc4194000}, {0xc4196000}, + {0xc4198000}, {0xc419a000}, {0xc419c000}, {0xc419e000}, + {0xc41a0000}, {0xc41a2000}, {0xc41a4000}, {0xc41a6000}, + {0xc41a8000}, {0xc41aa000}, {0xc41ac000}, {0xc41ae000}, + {0xc41b0000}, {0xc41b2000}, {0xc41b4000}, {0xc41b6000}, + {0xc41b8000}, {0xc41ba000}, {0xc41bc000}, {0xc41be000}, + {0xc41c0000}, {0xc41c2000}, {0xc41c4000}, {0xc41c6000}, + {0xc41c8000}, {0xc41ca000}, {0xc41cc000}, {0xc41ce000}, + {0xc41d0000}, {0xc41d2000}, {0xc41d4000}, {0xc41d6000}, + {0xc41d8000}, {0xc41da000}, {0xc41dc000}, {0xc41de000}, + {0xc41e0000}, {0xc41e2000}, {0xc41e4000}, {0xc41e6000}, + {0xc41e8000}, {0xc41ea000}, {0xc41ec000}, {0xc41ee000}, + {0xc41f0000}, {0xc41f2000}, {0xc41f4000}, {0xc41f6000}, + {0xc41f8000}, {0xc41fa000}, {0xc41fc000}, {0xc41fe000}, + {0xc4200000}, {0xc4202000}, {0xc4204000}, {0xc4206000}, + {0xc4208000}, {0xc420a000}, {0xc420c000}, {0xc420e000}, + {0xc4210000}, {0xc4212000}, {0xc4214000}, {0xc4216000}, + {0xc4218000}, {0xc421a000}, {0xc421c000}, {0xc421e000}, + {0xc4220000}, {0xc4222000}, {0xc4224000}, {0xc4226000}, + {0xc4228000}, {0xc422a000}, {0xc422c000}, {0xc422e000}, + {0xc4230000}, {0xc4232000}, {0xc4234000}, {0xc4236000}, + {0xc4238000}, {0xc423a000}, {0xc423c000}, {0xc423e000}, + {0xc4240000}, {0xc4242000}, {0xc4244000}, {0xc4246000}, + {0xc4248000}, {0xc424a000}, {0xc424c000}, {0xc424e000}, + {0xc4250000}, {0xc4252000}, {0xc4254000}, {0xc4256000}, + {0xc4258000}, {0xc425a000}, {0xc425c000}, {0xc425e000}, + {0xc4260000}, {0xc4262000}, {0xc4264000}, {0xc4266000}, + {0xc4268000}, {0xc426a000}, {0xc426c000}, {0xc426e000}, + {0xc4270000}, {0xc4272000}, {0xc4274000}, {0xc4276000}, + {0xc4278000}, {0xc427a000}, {0xc427c000}, {0xc427e000}, + {0xc4280000}, {0xc4282000}, {0xc4284000}, {0xc4286000}, + {0xc4288000}, {0xc428a000}, {0xc428c000}, {0xc428e000}, + {0xc4290000}, {0xc4292000}, {0xc4294000}, {0xc4296000}, + {0xc4298000}, {0xc429a000}, {0xc429c000}, {0xc429e000}, + {0xc42a0000}, {0xc42a2000}, {0xc42a4000}, {0xc42a6000}, + {0xc42a8000}, {0xc42aa000}, {0xc42ac000}, {0xc42ae000}, + {0xc42b0000}, {0xc42b2000}, {0xc42b4000}, {0xc42b6000}, + {0xc42b8000}, {0xc42ba000}, {0xc42bc000}, {0xc42be000}, + {0xc42c0000}, {0xc42c2000}, {0xc42c4000}, {0xc42c6000}, + {0xc42c8000}, {0xc42ca000}, {0xc42cc000}, {0xc42ce000}, + {0xc42d0000}, {0xc42d2000}, {0xc42d4000}, {0xc42d6000}, + {0xc42d8000}, {0xc42da000}, {0xc42dc000}, {0xc42de000}, + {0xc42e0000}, {0xc42e2000}, {0xc42e4000}, {0xc42e6000}, + {0xc42e8000}, {0xc42ea000}, {0xc42ec000}, {0xc42ee000}, + {0xc42f0000}, {0xc42f2000}, {0xc42f4000}, {0xc42f6000}, + {0xc42f8000}, {0xc42fa000}, {0xc42fc000}, {0xc42fe000}, + {0xc4300000}, {0xc4302000}, {0xc4304000}, {0xc4306000}, + {0xc4308000}, {0xc430a000}, {0xc430c000}, {0xc430e000}, + {0xc4310000}, {0xc4312000}, {0xc4314000}, {0xc4316000}, + {0xc4318000}, {0xc431a000}, {0xc431c000}, {0xc431e000}, + {0xc4320000}, {0xc4322000}, {0xc4324000}, {0xc4326000}, + {0xc4328000}, {0xc432a000}, {0xc432c000}, {0xc432e000}, + {0xc4330000}, {0xc4332000}, {0xc4334000}, {0xc4336000}, + {0xc4338000}, {0xc433a000}, {0xc433c000}, {0xc433e000}, + {0xc4340000}, {0xc4342000}, {0xc4344000}, {0xc4346000}, + {0xc4348000}, {0xc434a000}, {0xc434c000}, {0xc434e000}, + {0xc4350000}, {0xc4352000}, {0xc4354000}, {0xc4356000}, + {0xc4358000}, {0xc435a000}, {0xc435c000}, {0xc435e000}, + {0xc4360000}, {0xc4362000}, {0xc4364000}, {0xc4366000}, + {0xc4368000}, {0xc436a000}, {0xc436c000}, {0xc436e000}, + {0xc4370000}, {0xc4372000}, {0xc4374000}, {0xc4376000}, + {0xc4378000}, {0xc437a000}, {0xc437c000}, {0xc437e000}, + {0xc4380000}, {0xc4382000}, {0xc4384000}, {0xc4386000}, + {0xc4388000}, {0xc438a000}, {0xc438c000}, {0xc438e000}, + {0xc4390000}, {0xc4392000}, {0xc4394000}, {0xc4396000}, + {0xc4398000}, {0xc439a000}, {0xc439c000}, {0xc439e000}, + {0xc43a0000}, {0xc43a2000}, {0xc43a4000}, {0xc43a6000}, + {0xc43a8000}, {0xc43aa000}, {0xc43ac000}, {0xc43ae000}, + {0xc43b0000}, {0xc43b2000}, {0xc43b4000}, {0xc43b6000}, + {0xc43b8000}, {0xc43ba000}, {0xc43bc000}, {0xc43be000}, + {0xc43c0000}, {0xc43c2000}, {0xc43c4000}, {0xc43c6000}, + {0xc43c8000}, {0xc43ca000}, {0xc43cc000}, {0xc43ce000}, + {0xc43d0000}, {0xc43d2000}, {0xc43d4000}, {0xc43d6000}, + {0xc43d8000}, {0xc43da000}, {0xc43dc000}, {0xc43de000}, + {0xc43e0000}, {0xc43e2000}, {0xc43e4000}, {0xc43e6000}, + {0xc43e8000}, {0xc43ea000}, {0xc43ec000}, {0xc43ee000}, + {0xc43f0000}, {0xc43f2000}, {0xc43f4000}, {0xc43f6000}, + {0xc43f8000}, {0xc43fa000}, {0xc43fc000}, {0xc43fe000}, + {0xc4400000}, {0xc4402000}, {0xc4404000}, {0xc4406000}, + {0xc4408000}, {0xc440a000}, {0xc440c000}, {0xc440e000}, + {0xc4410000}, {0xc4412000}, {0xc4414000}, {0xc4416000}, + {0xc4418000}, {0xc441a000}, {0xc441c000}, {0xc441e000}, + {0xc4420000}, {0xc4422000}, {0xc4424000}, {0xc4426000}, + {0xc4428000}, {0xc442a000}, {0xc442c000}, {0xc442e000}, + {0xc4430000}, {0xc4432000}, {0xc4434000}, {0xc4436000}, + {0xc4438000}, {0xc443a000}, {0xc443c000}, {0xc443e000}, + {0xc4440000}, {0xc4442000}, {0xc4444000}, {0xc4446000}, + {0xc4448000}, {0xc444a000}, {0xc444c000}, {0xc444e000}, + {0xc4450000}, {0xc4452000}, {0xc4454000}, {0xc4456000}, + {0xc4458000}, {0xc445a000}, {0xc445c000}, {0xc445e000}, + {0xc4460000}, {0xc4462000}, {0xc4464000}, {0xc4466000}, + {0xc4468000}, {0xc446a000}, {0xc446c000}, {0xc446e000}, + {0xc4470000}, {0xc4472000}, {0xc4474000}, {0xc4476000}, + {0xc4478000}, {0xc447a000}, {0xc447c000}, {0xc447e000}, + {0xc4480000}, {0xc4482000}, {0xc4484000}, {0xc4486000}, + {0xc4488000}, {0xc448a000}, {0xc448c000}, {0xc448e000}, + {0xc4490000}, {0xc4492000}, {0xc4494000}, {0xc4496000}, + {0xc4498000}, {0xc449a000}, {0xc449c000}, {0xc449e000}, + {0xc44a0000}, {0xc44a2000}, {0xc44a4000}, {0xc44a6000}, + {0xc44a8000}, {0xc44aa000}, {0xc44ac000}, {0xc44ae000}, + {0xc44b0000}, {0xc44b2000}, {0xc44b4000}, {0xc44b6000}, + {0xc44b8000}, {0xc44ba000}, {0xc44bc000}, {0xc44be000}, + {0xc44c0000}, {0xc44c2000}, {0xc44c4000}, {0xc44c6000}, + {0xc44c8000}, {0xc44ca000}, {0xc44cc000}, {0xc44ce000}, + {0xc44d0000}, {0xc44d2000}, {0xc44d4000}, {0xc44d6000}, + {0xc44d8000}, {0xc44da000}, {0xc44dc000}, {0xc44de000}, + {0xc44e0000}, {0xc44e2000}, {0xc44e4000}, {0xc44e6000}, + {0xc44e8000}, {0xc44ea000}, {0xc44ec000}, {0xc44ee000}, + {0xc44f0000}, {0xc44f2000}, {0xc44f4000}, {0xc44f6000}, + {0xc44f8000}, {0xc44fa000}, {0xc44fc000}, {0xc44fe000}, + {0xc4500000}, {0xc4502000}, {0xc4504000}, {0xc4506000}, + {0xc4508000}, {0xc450a000}, {0xc450c000}, {0xc450e000}, + {0xc4510000}, {0xc4512000}, {0xc4514000}, {0xc4516000}, + {0xc4518000}, {0xc451a000}, {0xc451c000}, {0xc451e000}, + {0xc4520000}, {0xc4522000}, {0xc4524000}, {0xc4526000}, + {0xc4528000}, {0xc452a000}, {0xc452c000}, {0xc452e000}, + {0xc4530000}, {0xc4532000}, {0xc4534000}, {0xc4536000}, + {0xc4538000}, {0xc453a000}, {0xc453c000}, {0xc453e000}, + {0xc4540000}, {0xc4542000}, {0xc4544000}, {0xc4546000}, + {0xc4548000}, {0xc454a000}, {0xc454c000}, {0xc454e000}, + {0xc4550000}, {0xc4552000}, {0xc4554000}, {0xc4556000}, + {0xc4558000}, {0xc455a000}, {0xc455c000}, {0xc455e000}, + {0xc4560000}, {0xc4562000}, {0xc4564000}, {0xc4566000}, + {0xc4568000}, {0xc456a000}, {0xc456c000}, {0xc456e000}, + {0xc4570000}, {0xc4572000}, {0xc4574000}, {0xc4576000}, + {0xc4578000}, {0xc457a000}, {0xc457c000}, {0xc457e000}, + {0xc4580000}, {0xc4582000}, {0xc4584000}, {0xc4586000}, + {0xc4588000}, {0xc458a000}, {0xc458c000}, {0xc458e000}, + {0xc4590000}, {0xc4592000}, {0xc4594000}, {0xc4596000}, + {0xc4598000}, {0xc459a000}, {0xc459c000}, {0xc459e000}, + {0xc45a0000}, {0xc45a2000}, {0xc45a4000}, {0xc45a6000}, + {0xc45a8000}, {0xc45aa000}, {0xc45ac000}, {0xc45ae000}, + {0xc45b0000}, {0xc45b2000}, {0xc45b4000}, {0xc45b6000}, + {0xc45b8000}, {0xc45ba000}, {0xc45bc000}, {0xc45be000}, + {0xc45c0000}, {0xc45c2000}, {0xc45c4000}, {0xc45c6000}, + {0xc45c8000}, {0xc45ca000}, {0xc45cc000}, {0xc45ce000}, + {0xc45d0000}, {0xc45d2000}, {0xc45d4000}, {0xc45d6000}, + {0xc45d8000}, {0xc45da000}, {0xc45dc000}, {0xc45de000}, + {0xc45e0000}, {0xc45e2000}, {0xc45e4000}, {0xc45e6000}, + {0xc45e8000}, {0xc45ea000}, {0xc45ec000}, {0xc45ee000}, + {0xc45f0000}, {0xc45f2000}, {0xc45f4000}, {0xc45f6000}, + {0xc45f8000}, {0xc45fa000}, {0xc45fc000}, {0xc45fe000}, + {0xc4600000}, {0xc4602000}, {0xc4604000}, {0xc4606000}, + {0xc4608000}, {0xc460a000}, {0xc460c000}, {0xc460e000}, + {0xc4610000}, {0xc4612000}, {0xc4614000}, {0xc4616000}, + {0xc4618000}, {0xc461a000}, {0xc461c000}, {0xc461e000}, + {0xc4620000}, {0xc4622000}, {0xc4624000}, {0xc4626000}, + {0xc4628000}, {0xc462a000}, {0xc462c000}, {0xc462e000}, + {0xc4630000}, {0xc4632000}, {0xc4634000}, {0xc4636000}, + {0xc4638000}, {0xc463a000}, {0xc463c000}, {0xc463e000}, + {0xc4640000}, {0xc4642000}, {0xc4644000}, {0xc4646000}, + {0xc4648000}, {0xc464a000}, {0xc464c000}, {0xc464e000}, + {0xc4650000}, {0xc4652000}, {0xc4654000}, {0xc4656000}, + {0xc4658000}, {0xc465a000}, {0xc465c000}, {0xc465e000}, + {0xc4660000}, {0xc4662000}, {0xc4664000}, {0xc4666000}, + {0xc4668000}, {0xc466a000}, {0xc466c000}, {0xc466e000}, + {0xc4670000}, {0xc4672000}, {0xc4674000}, {0xc4676000}, + {0xc4678000}, {0xc467a000}, {0xc467c000}, {0xc467e000}, + {0xc4680000}, {0xc4682000}, {0xc4684000}, {0xc4686000}, + {0xc4688000}, {0xc468a000}, {0xc468c000}, {0xc468e000}, + {0xc4690000}, {0xc4692000}, {0xc4694000}, {0xc4696000}, + {0xc4698000}, {0xc469a000}, {0xc469c000}, {0xc469e000}, + {0xc46a0000}, {0xc46a2000}, {0xc46a4000}, {0xc46a6000}, + {0xc46a8000}, {0xc46aa000}, {0xc46ac000}, {0xc46ae000}, + {0xc46b0000}, {0xc46b2000}, {0xc46b4000}, {0xc46b6000}, + {0xc46b8000}, {0xc46ba000}, {0xc46bc000}, {0xc46be000}, + {0xc46c0000}, {0xc46c2000}, {0xc46c4000}, {0xc46c6000}, + {0xc46c8000}, {0xc46ca000}, {0xc46cc000}, {0xc46ce000}, + {0xc46d0000}, {0xc46d2000}, {0xc46d4000}, {0xc46d6000}, + {0xc46d8000}, {0xc46da000}, {0xc46dc000}, {0xc46de000}, + {0xc46e0000}, {0xc46e2000}, {0xc46e4000}, {0xc46e6000}, + {0xc46e8000}, {0xc46ea000}, {0xc46ec000}, {0xc46ee000}, + {0xc46f0000}, {0xc46f2000}, {0xc46f4000}, {0xc46f6000}, + {0xc46f8000}, {0xc46fa000}, {0xc46fc000}, {0xc46fe000}, + {0xc4700000}, {0xc4702000}, {0xc4704000}, {0xc4706000}, + {0xc4708000}, {0xc470a000}, {0xc470c000}, {0xc470e000}, + {0xc4710000}, {0xc4712000}, {0xc4714000}, {0xc4716000}, + {0xc4718000}, {0xc471a000}, {0xc471c000}, {0xc471e000}, + {0xc4720000}, {0xc4722000}, {0xc4724000}, {0xc4726000}, + {0xc4728000}, {0xc472a000}, {0xc472c000}, {0xc472e000}, + {0xc4730000}, {0xc4732000}, {0xc4734000}, {0xc4736000}, + {0xc4738000}, {0xc473a000}, {0xc473c000}, {0xc473e000}, + {0xc4740000}, {0xc4742000}, {0xc4744000}, {0xc4746000}, + {0xc4748000}, {0xc474a000}, {0xc474c000}, {0xc474e000}, + {0xc4750000}, {0xc4752000}, {0xc4754000}, {0xc4756000}, + {0xc4758000}, {0xc475a000}, {0xc475c000}, {0xc475e000}, + {0xc4760000}, {0xc4762000}, {0xc4764000}, {0xc4766000}, + {0xc4768000}, {0xc476a000}, {0xc476c000}, {0xc476e000}, + {0xc4770000}, {0xc4772000}, {0xc4774000}, {0xc4776000}, + {0xc4778000}, {0xc477a000}, {0xc477c000}, {0xc477e000}, + {0xc4780000}, {0xc4782000}, {0xc4784000}, {0xc4786000}, + {0xc4788000}, {0xc478a000}, {0xc478c000}, {0xc478e000}, + {0xc4790000}, {0xc4792000}, {0xc4794000}, {0xc4796000}, + {0xc4798000}, {0xc479a000}, {0xc479c000}, {0xc479e000}, + {0xc47a0000}, {0xc47a2000}, {0xc47a4000}, {0xc47a6000}, + {0xc47a8000}, {0xc47aa000}, {0xc47ac000}, {0xc47ae000}, + {0xc47b0000}, {0xc47b2000}, {0xc47b4000}, {0xc47b6000}, + {0xc47b8000}, {0xc47ba000}, {0xc47bc000}, {0xc47be000}, + {0xc47c0000}, {0xc47c2000}, {0xc47c4000}, {0xc47c6000}, + {0xc47c8000}, {0xc47ca000}, {0xc47cc000}, {0xc47ce000}, + {0xc47d0000}, {0xc47d2000}, {0xc47d4000}, {0xc47d6000}, + {0xc47d8000}, {0xc47da000}, {0xc47dc000}, {0xc47de000}, + {0xc47e0000}, {0xc47e2000}, {0xc47e4000}, {0xc47e6000}, + {0xc47e8000}, {0xc47ea000}, {0xc47ec000}, {0xc47ee000}, + {0xc47f0000}, {0xc47f2000}, {0xc47f4000}, {0xc47f6000}, + {0xc47f8000}, {0xc47fa000}, {0xc47fc000}, {0xc47fe000}, + {0xc4800000}, {0xc4802000}, {0xc4804000}, {0xc4806000}, + {0xc4808000}, {0xc480a000}, {0xc480c000}, {0xc480e000}, + {0xc4810000}, {0xc4812000}, {0xc4814000}, {0xc4816000}, + {0xc4818000}, {0xc481a000}, {0xc481c000}, {0xc481e000}, + {0xc4820000}, {0xc4822000}, {0xc4824000}, {0xc4826000}, + {0xc4828000}, {0xc482a000}, {0xc482c000}, {0xc482e000}, + {0xc4830000}, {0xc4832000}, {0xc4834000}, {0xc4836000}, + {0xc4838000}, {0xc483a000}, {0xc483c000}, {0xc483e000}, + {0xc4840000}, {0xc4842000}, {0xc4844000}, {0xc4846000}, + {0xc4848000}, {0xc484a000}, {0xc484c000}, {0xc484e000}, + {0xc4850000}, {0xc4852000}, {0xc4854000}, {0xc4856000}, + {0xc4858000}, {0xc485a000}, {0xc485c000}, {0xc485e000}, + {0xc4860000}, {0xc4862000}, {0xc4864000}, {0xc4866000}, + {0xc4868000}, {0xc486a000}, {0xc486c000}, {0xc486e000}, + {0xc4870000}, {0xc4872000}, {0xc4874000}, {0xc4876000}, + {0xc4878000}, {0xc487a000}, {0xc487c000}, {0xc487e000}, + {0xc4880000}, {0xc4882000}, {0xc4884000}, {0xc4886000}, + {0xc4888000}, {0xc488a000}, {0xc488c000}, {0xc488e000}, + {0xc4890000}, {0xc4892000}, {0xc4894000}, {0xc4896000}, + {0xc4898000}, {0xc489a000}, {0xc489c000}, {0xc489e000}, + {0xc48a0000}, {0xc48a2000}, {0xc48a4000}, {0xc48a6000}, + {0xc48a8000}, {0xc48aa000}, {0xc48ac000}, {0xc48ae000}, + {0xc48b0000}, {0xc48b2000}, {0xc48b4000}, {0xc48b6000}, + {0xc48b8000}, {0xc48ba000}, {0xc48bc000}, {0xc48be000}, + {0xc48c0000}, {0xc48c2000}, {0xc48c4000}, {0xc48c6000}, + {0xc48c8000}, {0xc48ca000}, {0xc48cc000}, {0xc48ce000}, + {0xc48d0000}, {0xc48d2000}, {0xc48d4000}, {0xc48d6000}, + {0xc48d8000}, {0xc48da000}, {0xc48dc000}, {0xc48de000}, + {0xc48e0000}, {0xc48e2000}, {0xc48e4000}, {0xc48e6000}, + {0xc48e8000}, {0xc48ea000}, {0xc48ec000}, {0xc48ee000}, + {0xc48f0000}, {0xc48f2000}, {0xc48f4000}, {0xc48f6000}, + {0xc48f8000}, {0xc48fa000}, {0xc48fc000}, {0xc48fe000}, + {0xc4900000}, {0xc4902000}, {0xc4904000}, {0xc4906000}, + {0xc4908000}, {0xc490a000}, {0xc490c000}, {0xc490e000}, + {0xc4910000}, {0xc4912000}, {0xc4914000}, {0xc4916000}, + {0xc4918000}, {0xc491a000}, {0xc491c000}, {0xc491e000}, + {0xc4920000}, {0xc4922000}, {0xc4924000}, {0xc4926000}, + {0xc4928000}, {0xc492a000}, {0xc492c000}, {0xc492e000}, + {0xc4930000}, {0xc4932000}, {0xc4934000}, {0xc4936000}, + {0xc4938000}, {0xc493a000}, {0xc493c000}, {0xc493e000}, + {0xc4940000}, {0xc4942000}, {0xc4944000}, {0xc4946000}, + {0xc4948000}, {0xc494a000}, {0xc494c000}, {0xc494e000}, + {0xc4950000}, {0xc4952000}, {0xc4954000}, {0xc4956000}, + {0xc4958000}, {0xc495a000}, {0xc495c000}, {0xc495e000}, + {0xc4960000}, {0xc4962000}, {0xc4964000}, {0xc4966000}, + {0xc4968000}, {0xc496a000}, {0xc496c000}, {0xc496e000}, + {0xc4970000}, {0xc4972000}, {0xc4974000}, {0xc4976000}, + {0xc4978000}, {0xc497a000}, {0xc497c000}, {0xc497e000}, + {0xc4980000}, {0xc4982000}, {0xc4984000}, {0xc4986000}, + {0xc4988000}, {0xc498a000}, {0xc498c000}, {0xc498e000}, + {0xc4990000}, {0xc4992000}, {0xc4994000}, {0xc4996000}, + {0xc4998000}, {0xc499a000}, {0xc499c000}, {0xc499e000}, + {0xc49a0000}, {0xc49a2000}, {0xc49a4000}, {0xc49a6000}, + {0xc49a8000}, {0xc49aa000}, {0xc49ac000}, {0xc49ae000}, + {0xc49b0000}, {0xc49b2000}, {0xc49b4000}, {0xc49b6000}, + {0xc49b8000}, {0xc49ba000}, {0xc49bc000}, {0xc49be000}, + {0xc49c0000}, {0xc49c2000}, {0xc49c4000}, {0xc49c6000}, + {0xc49c8000}, {0xc49ca000}, {0xc49cc000}, {0xc49ce000}, + {0xc49d0000}, {0xc49d2000}, {0xc49d4000}, {0xc49d6000}, + {0xc49d8000}, {0xc49da000}, {0xc49dc000}, {0xc49de000}, + {0xc49e0000}, {0xc49e2000}, {0xc49e4000}, {0xc49e6000}, + {0xc49e8000}, {0xc49ea000}, {0xc49ec000}, {0xc49ee000}, + {0xc49f0000}, {0xc49f2000}, {0xc49f4000}, {0xc49f6000}, + {0xc49f8000}, {0xc49fa000}, {0xc49fc000}, {0xc49fe000}, + {0xc4a00000}, {0xc4a02000}, {0xc4a04000}, {0xc4a06000}, + {0xc4a08000}, {0xc4a0a000}, {0xc4a0c000}, {0xc4a0e000}, + {0xc4a10000}, {0xc4a12000}, {0xc4a14000}, {0xc4a16000}, + {0xc4a18000}, {0xc4a1a000}, {0xc4a1c000}, {0xc4a1e000}, + {0xc4a20000}, {0xc4a22000}, {0xc4a24000}, {0xc4a26000}, + {0xc4a28000}, {0xc4a2a000}, {0xc4a2c000}, {0xc4a2e000}, + {0xc4a30000}, {0xc4a32000}, {0xc4a34000}, {0xc4a36000}, + {0xc4a38000}, {0xc4a3a000}, {0xc4a3c000}, {0xc4a3e000}, + {0xc4a40000}, {0xc4a42000}, {0xc4a44000}, {0xc4a46000}, + {0xc4a48000}, {0xc4a4a000}, {0xc4a4c000}, {0xc4a4e000}, + {0xc4a50000}, {0xc4a52000}, {0xc4a54000}, {0xc4a56000}, + {0xc4a58000}, {0xc4a5a000}, {0xc4a5c000}, {0xc4a5e000}, + {0xc4a60000}, {0xc4a62000}, {0xc4a64000}, {0xc4a66000}, + {0xc4a68000}, {0xc4a6a000}, {0xc4a6c000}, {0xc4a6e000}, + {0xc4a70000}, {0xc4a72000}, {0xc4a74000}, {0xc4a76000}, + {0xc4a78000}, {0xc4a7a000}, {0xc4a7c000}, {0xc4a7e000}, + {0xc4a80000}, {0xc4a82000}, {0xc4a84000}, {0xc4a86000}, + {0xc4a88000}, {0xc4a8a000}, {0xc4a8c000}, {0xc4a8e000}, + {0xc4a90000}, {0xc4a92000}, {0xc4a94000}, {0xc4a96000}, + {0xc4a98000}, {0xc4a9a000}, {0xc4a9c000}, {0xc4a9e000}, + {0xc4aa0000}, {0xc4aa2000}, {0xc4aa4000}, {0xc4aa6000}, + {0xc4aa8000}, {0xc4aaa000}, {0xc4aac000}, {0xc4aae000}, + {0xc4ab0000}, {0xc4ab2000}, {0xc4ab4000}, {0xc4ab6000}, + {0xc4ab8000}, {0xc4aba000}, {0xc4abc000}, {0xc4abe000}, + {0xc4ac0000}, {0xc4ac2000}, {0xc4ac4000}, {0xc4ac6000}, + {0xc4ac8000}, {0xc4aca000}, {0xc4acc000}, {0xc4ace000}, + {0xc4ad0000}, {0xc4ad2000}, {0xc4ad4000}, {0xc4ad6000}, + {0xc4ad8000}, {0xc4ada000}, {0xc4adc000}, {0xc4ade000}, + {0xc4ae0000}, {0xc4ae2000}, {0xc4ae4000}, {0xc4ae6000}, + {0xc4ae8000}, {0xc4aea000}, {0xc4aec000}, {0xc4aee000}, + {0xc4af0000}, {0xc4af2000}, {0xc4af4000}, {0xc4af6000}, + {0xc4af8000}, {0xc4afa000}, {0xc4afc000}, {0xc4afe000}, + {0xc4b00000}, {0xc4b02000}, {0xc4b04000}, {0xc4b06000}, + {0xc4b08000}, {0xc4b0a000}, {0xc4b0c000}, {0xc4b0e000}, + {0xc4b10000}, {0xc4b12000}, {0xc4b14000}, {0xc4b16000}, + {0xc4b18000}, {0xc4b1a000}, {0xc4b1c000}, {0xc4b1e000}, + {0xc4b20000}, {0xc4b22000}, {0xc4b24000}, {0xc4b26000}, + {0xc4b28000}, {0xc4b2a000}, {0xc4b2c000}, {0xc4b2e000}, + {0xc4b30000}, {0xc4b32000}, {0xc4b34000}, {0xc4b36000}, + {0xc4b38000}, {0xc4b3a000}, {0xc4b3c000}, {0xc4b3e000}, + {0xc4b40000}, {0xc4b42000}, {0xc4b44000}, {0xc4b46000}, + {0xc4b48000}, {0xc4b4a000}, {0xc4b4c000}, {0xc4b4e000}, + {0xc4b50000}, {0xc4b52000}, {0xc4b54000}, {0xc4b56000}, + {0xc4b58000}, {0xc4b5a000}, {0xc4b5c000}, {0xc4b5e000}, + {0xc4b60000}, {0xc4b62000}, {0xc4b64000}, {0xc4b66000}, + {0xc4b68000}, {0xc4b6a000}, {0xc4b6c000}, {0xc4b6e000}, + {0xc4b70000}, {0xc4b72000}, {0xc4b74000}, {0xc4b76000}, + {0xc4b78000}, {0xc4b7a000}, {0xc4b7c000}, {0xc4b7e000}, + {0xc4b80000}, {0xc4b82000}, {0xc4b84000}, {0xc4b86000}, + {0xc4b88000}, {0xc4b8a000}, {0xc4b8c000}, {0xc4b8e000}, + {0xc4b90000}, {0xc4b92000}, {0xc4b94000}, {0xc4b96000}, + {0xc4b98000}, {0xc4b9a000}, {0xc4b9c000}, {0xc4b9e000}, + {0xc4ba0000}, {0xc4ba2000}, {0xc4ba4000}, {0xc4ba6000}, + {0xc4ba8000}, {0xc4baa000}, {0xc4bac000}, {0xc4bae000}, + {0xc4bb0000}, {0xc4bb2000}, {0xc4bb4000}, {0xc4bb6000}, + {0xc4bb8000}, {0xc4bba000}, {0xc4bbc000}, {0xc4bbe000}, + {0xc4bc0000}, {0xc4bc2000}, {0xc4bc4000}, {0xc4bc6000}, + {0xc4bc8000}, {0xc4bca000}, {0xc4bcc000}, {0xc4bce000}, + {0xc4bd0000}, {0xc4bd2000}, {0xc4bd4000}, {0xc4bd6000}, + {0xc4bd8000}, {0xc4bda000}, {0xc4bdc000}, {0xc4bde000}, + {0xc4be0000}, {0xc4be2000}, {0xc4be4000}, {0xc4be6000}, + {0xc4be8000}, {0xc4bea000}, {0xc4bec000}, {0xc4bee000}, + {0xc4bf0000}, {0xc4bf2000}, {0xc4bf4000}, {0xc4bf6000}, + {0xc4bf8000}, {0xc4bfa000}, {0xc4bfc000}, {0xc4bfe000}, + {0xc4c00000}, {0xc4c02000}, {0xc4c04000}, {0xc4c06000}, + {0xc4c08000}, {0xc4c0a000}, {0xc4c0c000}, {0xc4c0e000}, + {0xc4c10000}, {0xc4c12000}, {0xc4c14000}, {0xc4c16000}, + {0xc4c18000}, {0xc4c1a000}, {0xc4c1c000}, {0xc4c1e000}, + {0xc4c20000}, {0xc4c22000}, {0xc4c24000}, {0xc4c26000}, + {0xc4c28000}, {0xc4c2a000}, {0xc4c2c000}, {0xc4c2e000}, + {0xc4c30000}, {0xc4c32000}, {0xc4c34000}, {0xc4c36000}, + {0xc4c38000}, {0xc4c3a000}, {0xc4c3c000}, {0xc4c3e000}, + {0xc4c40000}, {0xc4c42000}, {0xc4c44000}, {0xc4c46000}, + {0xc4c48000}, {0xc4c4a000}, {0xc4c4c000}, {0xc4c4e000}, + {0xc4c50000}, {0xc4c52000}, {0xc4c54000}, {0xc4c56000}, + {0xc4c58000}, {0xc4c5a000}, {0xc4c5c000}, {0xc4c5e000}, + {0xc4c60000}, {0xc4c62000}, {0xc4c64000}, {0xc4c66000}, + {0xc4c68000}, {0xc4c6a000}, {0xc4c6c000}, {0xc4c6e000}, + {0xc4c70000}, {0xc4c72000}, {0xc4c74000}, {0xc4c76000}, + {0xc4c78000}, {0xc4c7a000}, {0xc4c7c000}, {0xc4c7e000}, + {0xc4c80000}, {0xc4c82000}, {0xc4c84000}, {0xc4c86000}, + {0xc4c88000}, {0xc4c8a000}, {0xc4c8c000}, {0xc4c8e000}, + {0xc4c90000}, {0xc4c92000}, {0xc4c94000}, {0xc4c96000}, + {0xc4c98000}, {0xc4c9a000}, {0xc4c9c000}, {0xc4c9e000}, + {0xc4ca0000}, {0xc4ca2000}, {0xc4ca4000}, {0xc4ca6000}, + {0xc4ca8000}, {0xc4caa000}, {0xc4cac000}, {0xc4cae000}, + {0xc4cb0000}, {0xc4cb2000}, {0xc4cb4000}, {0xc4cb6000}, + {0xc4cb8000}, {0xc4cba000}, {0xc4cbc000}, {0xc4cbe000}, + {0xc4cc0000}, {0xc4cc2000}, {0xc4cc4000}, {0xc4cc6000}, + {0xc4cc8000}, {0xc4cca000}, {0xc4ccc000}, {0xc4cce000}, + {0xc4cd0000}, {0xc4cd2000}, {0xc4cd4000}, {0xc4cd6000}, + {0xc4cd8000}, {0xc4cda000}, {0xc4cdc000}, {0xc4cde000}, + {0xc4ce0000}, {0xc4ce2000}, {0xc4ce4000}, {0xc4ce6000}, + {0xc4ce8000}, {0xc4cea000}, {0xc4cec000}, {0xc4cee000}, + {0xc4cf0000}, {0xc4cf2000}, {0xc4cf4000}, {0xc4cf6000}, + {0xc4cf8000}, {0xc4cfa000}, {0xc4cfc000}, {0xc4cfe000}, + {0xc4d00000}, {0xc4d02000}, {0xc4d04000}, {0xc4d06000}, + {0xc4d08000}, {0xc4d0a000}, {0xc4d0c000}, {0xc4d0e000}, + {0xc4d10000}, {0xc4d12000}, {0xc4d14000}, {0xc4d16000}, + {0xc4d18000}, {0xc4d1a000}, {0xc4d1c000}, {0xc4d1e000}, + {0xc4d20000}, {0xc4d22000}, {0xc4d24000}, {0xc4d26000}, + {0xc4d28000}, {0xc4d2a000}, {0xc4d2c000}, {0xc4d2e000}, + {0xc4d30000}, {0xc4d32000}, {0xc4d34000}, {0xc4d36000}, + {0xc4d38000}, {0xc4d3a000}, {0xc4d3c000}, {0xc4d3e000}, + {0xc4d40000}, {0xc4d42000}, {0xc4d44000}, {0xc4d46000}, + {0xc4d48000}, {0xc4d4a000}, {0xc4d4c000}, {0xc4d4e000}, + {0xc4d50000}, {0xc4d52000}, {0xc4d54000}, {0xc4d56000}, + {0xc4d58000}, {0xc4d5a000}, {0xc4d5c000}, {0xc4d5e000}, + {0xc4d60000}, {0xc4d62000}, {0xc4d64000}, {0xc4d66000}, + {0xc4d68000}, {0xc4d6a000}, {0xc4d6c000}, {0xc4d6e000}, + {0xc4d70000}, {0xc4d72000}, {0xc4d74000}, {0xc4d76000}, + {0xc4d78000}, {0xc4d7a000}, {0xc4d7c000}, {0xc4d7e000}, + {0xc4d80000}, {0xc4d82000}, {0xc4d84000}, {0xc4d86000}, + {0xc4d88000}, {0xc4d8a000}, {0xc4d8c000}, {0xc4d8e000}, + {0xc4d90000}, {0xc4d92000}, {0xc4d94000}, {0xc4d96000}, + {0xc4d98000}, {0xc4d9a000}, {0xc4d9c000}, {0xc4d9e000}, + {0xc4da0000}, {0xc4da2000}, {0xc4da4000}, {0xc4da6000}, + {0xc4da8000}, {0xc4daa000}, {0xc4dac000}, {0xc4dae000}, + {0xc4db0000}, {0xc4db2000}, {0xc4db4000}, {0xc4db6000}, + {0xc4db8000}, {0xc4dba000}, {0xc4dbc000}, {0xc4dbe000}, + {0xc4dc0000}, {0xc4dc2000}, {0xc4dc4000}, {0xc4dc6000}, + {0xc4dc8000}, {0xc4dca000}, {0xc4dcc000}, {0xc4dce000}, + {0xc4dd0000}, {0xc4dd2000}, {0xc4dd4000}, {0xc4dd6000}, + {0xc4dd8000}, {0xc4dda000}, {0xc4ddc000}, {0xc4dde000}, + {0xc4de0000}, {0xc4de2000}, {0xc4de4000}, {0xc4de6000}, + {0xc4de8000}, {0xc4dea000}, {0xc4dec000}, {0xc4dee000}, + {0xc4df0000}, {0xc4df2000}, {0xc4df4000}, {0xc4df6000}, + {0xc4df8000}, {0xc4dfa000}, {0xc4dfc000}, {0xc4dfe000}, + {0xc4e00000}, {0xc4e02000}, {0xc4e04000}, {0xc4e06000}, + {0xc4e08000}, {0xc4e0a000}, {0xc4e0c000}, {0xc4e0e000}, + {0xc4e10000}, {0xc4e12000}, {0xc4e14000}, {0xc4e16000}, + {0xc4e18000}, {0xc4e1a000}, {0xc4e1c000}, {0xc4e1e000}, + {0xc4e20000}, {0xc4e22000}, {0xc4e24000}, {0xc4e26000}, + {0xc4e28000}, {0xc4e2a000}, {0xc4e2c000}, {0xc4e2e000}, + {0xc4e30000}, {0xc4e32000}, {0xc4e34000}, {0xc4e36000}, + {0xc4e38000}, {0xc4e3a000}, {0xc4e3c000}, {0xc4e3e000}, + {0xc4e40000}, {0xc4e42000}, {0xc4e44000}, {0xc4e46000}, + {0xc4e48000}, {0xc4e4a000}, {0xc4e4c000}, {0xc4e4e000}, + {0xc4e50000}, {0xc4e52000}, {0xc4e54000}, {0xc4e56000}, + {0xc4e58000}, {0xc4e5a000}, {0xc4e5c000}, {0xc4e5e000}, + {0xc4e60000}, {0xc4e62000}, {0xc4e64000}, {0xc4e66000}, + {0xc4e68000}, {0xc4e6a000}, {0xc4e6c000}, {0xc4e6e000}, + {0xc4e70000}, {0xc4e72000}, {0xc4e74000}, {0xc4e76000}, + {0xc4e78000}, {0xc4e7a000}, {0xc4e7c000}, {0xc4e7e000}, + {0xc4e80000}, {0xc4e82000}, {0xc4e84000}, {0xc4e86000}, + {0xc4e88000}, {0xc4e8a000}, {0xc4e8c000}, {0xc4e8e000}, + {0xc4e90000}, {0xc4e92000}, {0xc4e94000}, {0xc4e96000}, + {0xc4e98000}, {0xc4e9a000}, {0xc4e9c000}, {0xc4e9e000}, + {0xc4ea0000}, {0xc4ea2000}, {0xc4ea4000}, {0xc4ea6000}, + {0xc4ea8000}, {0xc4eaa000}, {0xc4eac000}, {0xc4eae000}, + {0xc4eb0000}, {0xc4eb2000}, {0xc4eb4000}, {0xc4eb6000}, + {0xc4eb8000}, {0xc4eba000}, {0xc4ebc000}, {0xc4ebe000}, + {0xc4ec0000}, {0xc4ec2000}, {0xc4ec4000}, {0xc4ec6000}, + {0xc4ec8000}, {0xc4eca000}, {0xc4ecc000}, {0xc4ece000}, + {0xc4ed0000}, {0xc4ed2000}, {0xc4ed4000}, {0xc4ed6000}, + {0xc4ed8000}, {0xc4eda000}, {0xc4edc000}, {0xc4ede000}, + {0xc4ee0000}, {0xc4ee2000}, {0xc4ee4000}, {0xc4ee6000}, + {0xc4ee8000}, {0xc4eea000}, {0xc4eec000}, {0xc4eee000}, + {0xc4ef0000}, {0xc4ef2000}, {0xc4ef4000}, {0xc4ef6000}, + {0xc4ef8000}, {0xc4efa000}, {0xc4efc000}, {0xc4efe000}, + {0xc4f00000}, {0xc4f02000}, {0xc4f04000}, {0xc4f06000}, + {0xc4f08000}, {0xc4f0a000}, {0xc4f0c000}, {0xc4f0e000}, + {0xc4f10000}, {0xc4f12000}, {0xc4f14000}, {0xc4f16000}, + {0xc4f18000}, {0xc4f1a000}, {0xc4f1c000}, {0xc4f1e000}, + {0xc4f20000}, {0xc4f22000}, {0xc4f24000}, {0xc4f26000}, + {0xc4f28000}, {0xc4f2a000}, {0xc4f2c000}, {0xc4f2e000}, + {0xc4f30000}, {0xc4f32000}, {0xc4f34000}, {0xc4f36000}, + {0xc4f38000}, {0xc4f3a000}, {0xc4f3c000}, {0xc4f3e000}, + {0xc4f40000}, {0xc4f42000}, {0xc4f44000}, {0xc4f46000}, + {0xc4f48000}, {0xc4f4a000}, {0xc4f4c000}, {0xc4f4e000}, + {0xc4f50000}, {0xc4f52000}, {0xc4f54000}, {0xc4f56000}, + {0xc4f58000}, {0xc4f5a000}, {0xc4f5c000}, {0xc4f5e000}, + {0xc4f60000}, {0xc4f62000}, {0xc4f64000}, {0xc4f66000}, + {0xc4f68000}, {0xc4f6a000}, {0xc4f6c000}, {0xc4f6e000}, + {0xc4f70000}, {0xc4f72000}, {0xc4f74000}, {0xc4f76000}, + {0xc4f78000}, {0xc4f7a000}, {0xc4f7c000}, {0xc4f7e000}, + {0xc4f80000}, {0xc4f82000}, {0xc4f84000}, {0xc4f86000}, + {0xc4f88000}, {0xc4f8a000}, {0xc4f8c000}, {0xc4f8e000}, + {0xc4f90000}, {0xc4f92000}, {0xc4f94000}, {0xc4f96000}, + {0xc4f98000}, {0xc4f9a000}, {0xc4f9c000}, {0xc4f9e000}, + {0xc4fa0000}, {0xc4fa2000}, {0xc4fa4000}, {0xc4fa6000}, + {0xc4fa8000}, {0xc4faa000}, {0xc4fac000}, {0xc4fae000}, + {0xc4fb0000}, {0xc4fb2000}, {0xc4fb4000}, {0xc4fb6000}, + {0xc4fb8000}, {0xc4fba000}, {0xc4fbc000}, {0xc4fbe000}, + {0xc4fc0000}, {0xc4fc2000}, {0xc4fc4000}, {0xc4fc6000}, + {0xc4fc8000}, {0xc4fca000}, {0xc4fcc000}, {0xc4fce000}, + {0xc4fd0000}, {0xc4fd2000}, {0xc4fd4000}, {0xc4fd6000}, + {0xc4fd8000}, {0xc4fda000}, {0xc4fdc000}, {0xc4fde000}, + {0xc4fe0000}, {0xc4fe2000}, {0xc4fe4000}, {0xc4fe6000}, + {0xc4fe8000}, {0xc4fea000}, {0xc4fec000}, {0xc4fee000}, + {0xc4ff0000}, {0xc4ff2000}, {0xc4ff4000}, {0xc4ff6000}, + {0xc4ff8000}, {0xc4ffa000}, {0xc4ffc000}, {0xc4ffe000}, + {0xc5000000}, {0xc5002000}, {0xc5004000}, {0xc5006000}, + {0xc5008000}, {0xc500a000}, {0xc500c000}, {0xc500e000}, + {0xc5010000}, {0xc5012000}, {0xc5014000}, {0xc5016000}, + {0xc5018000}, {0xc501a000}, {0xc501c000}, {0xc501e000}, + {0xc5020000}, {0xc5022000}, {0xc5024000}, {0xc5026000}, + {0xc5028000}, {0xc502a000}, {0xc502c000}, {0xc502e000}, + {0xc5030000}, {0xc5032000}, {0xc5034000}, {0xc5036000}, + {0xc5038000}, {0xc503a000}, {0xc503c000}, {0xc503e000}, + {0xc5040000}, {0xc5042000}, {0xc5044000}, {0xc5046000}, + {0xc5048000}, {0xc504a000}, {0xc504c000}, {0xc504e000}, + {0xc5050000}, {0xc5052000}, {0xc5054000}, {0xc5056000}, + {0xc5058000}, {0xc505a000}, {0xc505c000}, {0xc505e000}, + {0xc5060000}, {0xc5062000}, {0xc5064000}, {0xc5066000}, + {0xc5068000}, {0xc506a000}, {0xc506c000}, {0xc506e000}, + {0xc5070000}, {0xc5072000}, {0xc5074000}, {0xc5076000}, + {0xc5078000}, {0xc507a000}, {0xc507c000}, {0xc507e000}, + {0xc5080000}, {0xc5082000}, {0xc5084000}, {0xc5086000}, + {0xc5088000}, {0xc508a000}, {0xc508c000}, {0xc508e000}, + {0xc5090000}, {0xc5092000}, {0xc5094000}, {0xc5096000}, + {0xc5098000}, {0xc509a000}, {0xc509c000}, {0xc509e000}, + {0xc50a0000}, {0xc50a2000}, {0xc50a4000}, {0xc50a6000}, + {0xc50a8000}, {0xc50aa000}, {0xc50ac000}, {0xc50ae000}, + {0xc50b0000}, {0xc50b2000}, {0xc50b4000}, {0xc50b6000}, + {0xc50b8000}, {0xc50ba000}, {0xc50bc000}, {0xc50be000}, + {0xc50c0000}, {0xc50c2000}, {0xc50c4000}, {0xc50c6000}, + {0xc50c8000}, {0xc50ca000}, {0xc50cc000}, {0xc50ce000}, + {0xc50d0000}, {0xc50d2000}, {0xc50d4000}, {0xc50d6000}, + {0xc50d8000}, {0xc50da000}, {0xc50dc000}, {0xc50de000}, + {0xc50e0000}, {0xc50e2000}, {0xc50e4000}, {0xc50e6000}, + {0xc50e8000}, {0xc50ea000}, {0xc50ec000}, {0xc50ee000}, + {0xc50f0000}, {0xc50f2000}, {0xc50f4000}, {0xc50f6000}, + {0xc50f8000}, {0xc50fa000}, {0xc50fc000}, {0xc50fe000}, + {0xc5100000}, {0xc5102000}, {0xc5104000}, {0xc5106000}, + {0xc5108000}, {0xc510a000}, {0xc510c000}, {0xc510e000}, + {0xc5110000}, {0xc5112000}, {0xc5114000}, {0xc5116000}, + {0xc5118000}, {0xc511a000}, {0xc511c000}, {0xc511e000}, + {0xc5120000}, {0xc5122000}, {0xc5124000}, {0xc5126000}, + {0xc5128000}, {0xc512a000}, {0xc512c000}, {0xc512e000}, + {0xc5130000}, {0xc5132000}, {0xc5134000}, {0xc5136000}, + {0xc5138000}, {0xc513a000}, {0xc513c000}, {0xc513e000}, + {0xc5140000}, {0xc5142000}, {0xc5144000}, {0xc5146000}, + {0xc5148000}, {0xc514a000}, {0xc514c000}, {0xc514e000}, + {0xc5150000}, {0xc5152000}, {0xc5154000}, {0xc5156000}, + {0xc5158000}, {0xc515a000}, {0xc515c000}, {0xc515e000}, + {0xc5160000}, {0xc5162000}, {0xc5164000}, {0xc5166000}, + {0xc5168000}, {0xc516a000}, {0xc516c000}, {0xc516e000}, + {0xc5170000}, {0xc5172000}, {0xc5174000}, {0xc5176000}, + {0xc5178000}, {0xc517a000}, {0xc517c000}, {0xc517e000}, + {0xc5180000}, {0xc5182000}, {0xc5184000}, {0xc5186000}, + {0xc5188000}, {0xc518a000}, {0xc518c000}, {0xc518e000}, + {0xc5190000}, {0xc5192000}, {0xc5194000}, {0xc5196000}, + {0xc5198000}, {0xc519a000}, {0xc519c000}, {0xc519e000}, + {0xc51a0000}, {0xc51a2000}, {0xc51a4000}, {0xc51a6000}, + {0xc51a8000}, {0xc51aa000}, {0xc51ac000}, {0xc51ae000}, + {0xc51b0000}, {0xc51b2000}, {0xc51b4000}, {0xc51b6000}, + {0xc51b8000}, {0xc51ba000}, {0xc51bc000}, {0xc51be000}, + {0xc51c0000}, {0xc51c2000}, {0xc51c4000}, {0xc51c6000}, + {0xc51c8000}, {0xc51ca000}, {0xc51cc000}, {0xc51ce000}, + {0xc51d0000}, {0xc51d2000}, {0xc51d4000}, {0xc51d6000}, + {0xc51d8000}, {0xc51da000}, {0xc51dc000}, {0xc51de000}, + {0xc51e0000}, {0xc51e2000}, {0xc51e4000}, {0xc51e6000}, + {0xc51e8000}, {0xc51ea000}, {0xc51ec000}, {0xc51ee000}, + {0xc51f0000}, {0xc51f2000}, {0xc51f4000}, {0xc51f6000}, + {0xc51f8000}, {0xc51fa000}, {0xc51fc000}, {0xc51fe000}, + {0xc5200000}, {0xc5202000}, {0xc5204000}, {0xc5206000}, + {0xc5208000}, {0xc520a000}, {0xc520c000}, {0xc520e000}, + {0xc5210000}, {0xc5212000}, {0xc5214000}, {0xc5216000}, + {0xc5218000}, {0xc521a000}, {0xc521c000}, {0xc521e000}, + {0xc5220000}, {0xc5222000}, {0xc5224000}, {0xc5226000}, + {0xc5228000}, {0xc522a000}, {0xc522c000}, {0xc522e000}, + {0xc5230000}, {0xc5232000}, {0xc5234000}, {0xc5236000}, + {0xc5238000}, {0xc523a000}, {0xc523c000}, {0xc523e000}, + {0xc5240000}, {0xc5242000}, {0xc5244000}, {0xc5246000}, + {0xc5248000}, {0xc524a000}, {0xc524c000}, {0xc524e000}, + {0xc5250000}, {0xc5252000}, {0xc5254000}, {0xc5256000}, + {0xc5258000}, {0xc525a000}, {0xc525c000}, {0xc525e000}, + {0xc5260000}, {0xc5262000}, {0xc5264000}, {0xc5266000}, + {0xc5268000}, {0xc526a000}, {0xc526c000}, {0xc526e000}, + {0xc5270000}, {0xc5272000}, {0xc5274000}, {0xc5276000}, + {0xc5278000}, {0xc527a000}, {0xc527c000}, {0xc527e000}, + {0xc5280000}, {0xc5282000}, {0xc5284000}, {0xc5286000}, + {0xc5288000}, {0xc528a000}, {0xc528c000}, {0xc528e000}, + {0xc5290000}, {0xc5292000}, {0xc5294000}, {0xc5296000}, + {0xc5298000}, {0xc529a000}, {0xc529c000}, {0xc529e000}, + {0xc52a0000}, {0xc52a2000}, {0xc52a4000}, {0xc52a6000}, + {0xc52a8000}, {0xc52aa000}, {0xc52ac000}, {0xc52ae000}, + {0xc52b0000}, {0xc52b2000}, {0xc52b4000}, {0xc52b6000}, + {0xc52b8000}, {0xc52ba000}, {0xc52bc000}, {0xc52be000}, + {0xc52c0000}, {0xc52c2000}, {0xc52c4000}, {0xc52c6000}, + {0xc52c8000}, {0xc52ca000}, {0xc52cc000}, {0xc52ce000}, + {0xc52d0000}, {0xc52d2000}, {0xc52d4000}, {0xc52d6000}, + {0xc52d8000}, {0xc52da000}, {0xc52dc000}, {0xc52de000}, + {0xc52e0000}, {0xc52e2000}, {0xc52e4000}, {0xc52e6000}, + {0xc52e8000}, {0xc52ea000}, {0xc52ec000}, {0xc52ee000}, + {0xc52f0000}, {0xc52f2000}, {0xc52f4000}, {0xc52f6000}, + {0xc52f8000}, {0xc52fa000}, {0xc52fc000}, {0xc52fe000}, + {0xc5300000}, {0xc5302000}, {0xc5304000}, {0xc5306000}, + {0xc5308000}, {0xc530a000}, {0xc530c000}, {0xc530e000}, + {0xc5310000}, {0xc5312000}, {0xc5314000}, {0xc5316000}, + {0xc5318000}, {0xc531a000}, {0xc531c000}, {0xc531e000}, + {0xc5320000}, {0xc5322000}, {0xc5324000}, {0xc5326000}, + {0xc5328000}, {0xc532a000}, {0xc532c000}, {0xc532e000}, + {0xc5330000}, {0xc5332000}, {0xc5334000}, {0xc5336000}, + {0xc5338000}, {0xc533a000}, {0xc533c000}, {0xc533e000}, + {0xc5340000}, {0xc5342000}, {0xc5344000}, {0xc5346000}, + {0xc5348000}, {0xc534a000}, {0xc534c000}, {0xc534e000}, + {0xc5350000}, {0xc5352000}, {0xc5354000}, {0xc5356000}, + {0xc5358000}, {0xc535a000}, {0xc535c000}, {0xc535e000}, + {0xc5360000}, {0xc5362000}, {0xc5364000}, {0xc5366000}, + {0xc5368000}, {0xc536a000}, {0xc536c000}, {0xc536e000}, + {0xc5370000}, {0xc5372000}, {0xc5374000}, {0xc5376000}, + {0xc5378000}, {0xc537a000}, {0xc537c000}, {0xc537e000}, + {0xc5380000}, {0xc5382000}, {0xc5384000}, {0xc5386000}, + {0xc5388000}, {0xc538a000}, {0xc538c000}, {0xc538e000}, + {0xc5390000}, {0xc5392000}, {0xc5394000}, {0xc5396000}, + {0xc5398000}, {0xc539a000}, {0xc539c000}, {0xc539e000}, + {0xc53a0000}, {0xc53a2000}, {0xc53a4000}, {0xc53a6000}, + {0xc53a8000}, {0xc53aa000}, {0xc53ac000}, {0xc53ae000}, + {0xc53b0000}, {0xc53b2000}, {0xc53b4000}, {0xc53b6000}, + {0xc53b8000}, {0xc53ba000}, {0xc53bc000}, {0xc53be000}, + {0xc53c0000}, {0xc53c2000}, {0xc53c4000}, {0xc53c6000}, + {0xc53c8000}, {0xc53ca000}, {0xc53cc000}, {0xc53ce000}, + {0xc53d0000}, {0xc53d2000}, {0xc53d4000}, {0xc53d6000}, + {0xc53d8000}, {0xc53da000}, {0xc53dc000}, {0xc53de000}, + {0xc53e0000}, {0xc53e2000}, {0xc53e4000}, {0xc53e6000}, + {0xc53e8000}, {0xc53ea000}, {0xc53ec000}, {0xc53ee000}, + {0xc53f0000}, {0xc53f2000}, {0xc53f4000}, {0xc53f6000}, + {0xc53f8000}, {0xc53fa000}, {0xc53fc000}, {0xc53fe000}, + {0xc5400000}, {0xc5402000}, {0xc5404000}, {0xc5406000}, + {0xc5408000}, {0xc540a000}, {0xc540c000}, {0xc540e000}, + {0xc5410000}, {0xc5412000}, {0xc5414000}, {0xc5416000}, + {0xc5418000}, {0xc541a000}, {0xc541c000}, {0xc541e000}, + {0xc5420000}, {0xc5422000}, {0xc5424000}, {0xc5426000}, + {0xc5428000}, {0xc542a000}, {0xc542c000}, {0xc542e000}, + {0xc5430000}, {0xc5432000}, {0xc5434000}, {0xc5436000}, + {0xc5438000}, {0xc543a000}, {0xc543c000}, {0xc543e000}, + {0xc5440000}, {0xc5442000}, {0xc5444000}, {0xc5446000}, + {0xc5448000}, {0xc544a000}, {0xc544c000}, {0xc544e000}, + {0xc5450000}, {0xc5452000}, {0xc5454000}, {0xc5456000}, + {0xc5458000}, {0xc545a000}, {0xc545c000}, {0xc545e000}, + {0xc5460000}, {0xc5462000}, {0xc5464000}, {0xc5466000}, + {0xc5468000}, {0xc546a000}, {0xc546c000}, {0xc546e000}, + {0xc5470000}, {0xc5472000}, {0xc5474000}, {0xc5476000}, + {0xc5478000}, {0xc547a000}, {0xc547c000}, {0xc547e000}, + {0xc5480000}, {0xc5482000}, {0xc5484000}, {0xc5486000}, + {0xc5488000}, {0xc548a000}, {0xc548c000}, {0xc548e000}, + {0xc5490000}, {0xc5492000}, {0xc5494000}, {0xc5496000}, + {0xc5498000}, {0xc549a000}, {0xc549c000}, {0xc549e000}, + {0xc54a0000}, {0xc54a2000}, {0xc54a4000}, {0xc54a6000}, + {0xc54a8000}, {0xc54aa000}, {0xc54ac000}, {0xc54ae000}, + {0xc54b0000}, {0xc54b2000}, {0xc54b4000}, {0xc54b6000}, + {0xc54b8000}, {0xc54ba000}, {0xc54bc000}, {0xc54be000}, + {0xc54c0000}, {0xc54c2000}, {0xc54c4000}, {0xc54c6000}, + {0xc54c8000}, {0xc54ca000}, {0xc54cc000}, {0xc54ce000}, + {0xc54d0000}, {0xc54d2000}, {0xc54d4000}, {0xc54d6000}, + {0xc54d8000}, {0xc54da000}, {0xc54dc000}, {0xc54de000}, + {0xc54e0000}, {0xc54e2000}, {0xc54e4000}, {0xc54e6000}, + {0xc54e8000}, {0xc54ea000}, {0xc54ec000}, {0xc54ee000}, + {0xc54f0000}, {0xc54f2000}, {0xc54f4000}, {0xc54f6000}, + {0xc54f8000}, {0xc54fa000}, {0xc54fc000}, {0xc54fe000}, + {0xc5500000}, {0xc5502000}, {0xc5504000}, {0xc5506000}, + {0xc5508000}, {0xc550a000}, {0xc550c000}, {0xc550e000}, + {0xc5510000}, {0xc5512000}, {0xc5514000}, {0xc5516000}, + {0xc5518000}, {0xc551a000}, {0xc551c000}, {0xc551e000}, + {0xc5520000}, {0xc5522000}, {0xc5524000}, {0xc5526000}, + {0xc5528000}, {0xc552a000}, {0xc552c000}, {0xc552e000}, + {0xc5530000}, {0xc5532000}, {0xc5534000}, {0xc5536000}, + {0xc5538000}, {0xc553a000}, {0xc553c000}, {0xc553e000}, + {0xc5540000}, {0xc5542000}, {0xc5544000}, {0xc5546000}, + {0xc5548000}, {0xc554a000}, {0xc554c000}, {0xc554e000}, + {0xc5550000}, {0xc5552000}, {0xc5554000}, {0xc5556000}, + {0xc5558000}, {0xc555a000}, {0xc555c000}, {0xc555e000}, + {0xc5560000}, {0xc5562000}, {0xc5564000}, {0xc5566000}, + {0xc5568000}, {0xc556a000}, {0xc556c000}, {0xc556e000}, + {0xc5570000}, {0xc5572000}, {0xc5574000}, {0xc5576000}, + {0xc5578000}, {0xc557a000}, {0xc557c000}, {0xc557e000}, + {0xc5580000}, {0xc5582000}, {0xc5584000}, {0xc5586000}, + {0xc5588000}, {0xc558a000}, {0xc558c000}, {0xc558e000}, + {0xc5590000}, {0xc5592000}, {0xc5594000}, {0xc5596000}, + {0xc5598000}, {0xc559a000}, {0xc559c000}, {0xc559e000}, + {0xc55a0000}, {0xc55a2000}, {0xc55a4000}, {0xc55a6000}, + {0xc55a8000}, {0xc55aa000}, {0xc55ac000}, {0xc55ae000}, + {0xc55b0000}, {0xc55b2000}, {0xc55b4000}, {0xc55b6000}, + {0xc55b8000}, {0xc55ba000}, {0xc55bc000}, {0xc55be000}, + {0xc55c0000}, {0xc55c2000}, {0xc55c4000}, {0xc55c6000}, + {0xc55c8000}, {0xc55ca000}, {0xc55cc000}, {0xc55ce000}, + {0xc55d0000}, {0xc55d2000}, {0xc55d4000}, {0xc55d6000}, + {0xc55d8000}, {0xc55da000}, {0xc55dc000}, {0xc55de000}, + {0xc55e0000}, {0xc55e2000}, {0xc55e4000}, {0xc55e6000}, + {0xc55e8000}, {0xc55ea000}, {0xc55ec000}, {0xc55ee000}, + {0xc55f0000}, {0xc55f2000}, {0xc55f4000}, {0xc55f6000}, + {0xc55f8000}, {0xc55fa000}, {0xc55fc000}, {0xc55fe000}, + {0xc5600000}, {0xc5602000}, {0xc5604000}, {0xc5606000}, + {0xc5608000}, {0xc560a000}, {0xc560c000}, {0xc560e000}, + {0xc5610000}, {0xc5612000}, {0xc5614000}, {0xc5616000}, + {0xc5618000}, {0xc561a000}, {0xc561c000}, {0xc561e000}, + {0xc5620000}, {0xc5622000}, {0xc5624000}, {0xc5626000}, + {0xc5628000}, {0xc562a000}, {0xc562c000}, {0xc562e000}, + {0xc5630000}, {0xc5632000}, {0xc5634000}, {0xc5636000}, + {0xc5638000}, {0xc563a000}, {0xc563c000}, {0xc563e000}, + {0xc5640000}, {0xc5642000}, {0xc5644000}, {0xc5646000}, + {0xc5648000}, {0xc564a000}, {0xc564c000}, {0xc564e000}, + {0xc5650000}, {0xc5652000}, {0xc5654000}, {0xc5656000}, + {0xc5658000}, {0xc565a000}, {0xc565c000}, {0xc565e000}, + {0xc5660000}, {0xc5662000}, {0xc5664000}, {0xc5666000}, + {0xc5668000}, {0xc566a000}, {0xc566c000}, {0xc566e000}, + {0xc5670000}, {0xc5672000}, {0xc5674000}, {0xc5676000}, + {0xc5678000}, {0xc567a000}, {0xc567c000}, {0xc567e000}, + {0xc5680000}, {0xc5682000}, {0xc5684000}, {0xc5686000}, + {0xc5688000}, {0xc568a000}, {0xc568c000}, {0xc568e000}, + {0xc5690000}, {0xc5692000}, {0xc5694000}, {0xc5696000}, + {0xc5698000}, {0xc569a000}, {0xc569c000}, {0xc569e000}, + {0xc56a0000}, {0xc56a2000}, {0xc56a4000}, {0xc56a6000}, + {0xc56a8000}, {0xc56aa000}, {0xc56ac000}, {0xc56ae000}, + {0xc56b0000}, {0xc56b2000}, {0xc56b4000}, {0xc56b6000}, + {0xc56b8000}, {0xc56ba000}, {0xc56bc000}, {0xc56be000}, + {0xc56c0000}, {0xc56c2000}, {0xc56c4000}, {0xc56c6000}, + {0xc56c8000}, {0xc56ca000}, {0xc56cc000}, {0xc56ce000}, + {0xc56d0000}, {0xc56d2000}, {0xc56d4000}, {0xc56d6000}, + {0xc56d8000}, {0xc56da000}, {0xc56dc000}, {0xc56de000}, + {0xc56e0000}, {0xc56e2000}, {0xc56e4000}, {0xc56e6000}, + {0xc56e8000}, {0xc56ea000}, {0xc56ec000}, {0xc56ee000}, + {0xc56f0000}, {0xc56f2000}, {0xc56f4000}, {0xc56f6000}, + {0xc56f8000}, {0xc56fa000}, {0xc56fc000}, {0xc56fe000}, + {0xc5700000}, {0xc5702000}, {0xc5704000}, {0xc5706000}, + {0xc5708000}, {0xc570a000}, {0xc570c000}, {0xc570e000}, + {0xc5710000}, {0xc5712000}, {0xc5714000}, {0xc5716000}, + {0xc5718000}, {0xc571a000}, {0xc571c000}, {0xc571e000}, + {0xc5720000}, {0xc5722000}, {0xc5724000}, {0xc5726000}, + {0xc5728000}, {0xc572a000}, {0xc572c000}, {0xc572e000}, + {0xc5730000}, {0xc5732000}, {0xc5734000}, {0xc5736000}, + {0xc5738000}, {0xc573a000}, {0xc573c000}, {0xc573e000}, + {0xc5740000}, {0xc5742000}, {0xc5744000}, {0xc5746000}, + {0xc5748000}, {0xc574a000}, {0xc574c000}, {0xc574e000}, + {0xc5750000}, {0xc5752000}, {0xc5754000}, {0xc5756000}, + {0xc5758000}, {0xc575a000}, {0xc575c000}, {0xc575e000}, + {0xc5760000}, {0xc5762000}, {0xc5764000}, {0xc5766000}, + {0xc5768000}, {0xc576a000}, {0xc576c000}, {0xc576e000}, + {0xc5770000}, {0xc5772000}, {0xc5774000}, {0xc5776000}, + {0xc5778000}, {0xc577a000}, {0xc577c000}, {0xc577e000}, + {0xc5780000}, {0xc5782000}, {0xc5784000}, {0xc5786000}, + {0xc5788000}, {0xc578a000}, {0xc578c000}, {0xc578e000}, + {0xc5790000}, {0xc5792000}, {0xc5794000}, {0xc5796000}, + {0xc5798000}, {0xc579a000}, {0xc579c000}, {0xc579e000}, + {0xc57a0000}, {0xc57a2000}, {0xc57a4000}, {0xc57a6000}, + {0xc57a8000}, {0xc57aa000}, {0xc57ac000}, {0xc57ae000}, + {0xc57b0000}, {0xc57b2000}, {0xc57b4000}, {0xc57b6000}, + {0xc57b8000}, {0xc57ba000}, {0xc57bc000}, {0xc57be000}, + {0xc57c0000}, {0xc57c2000}, {0xc57c4000}, {0xc57c6000}, + {0xc57c8000}, {0xc57ca000}, {0xc57cc000}, {0xc57ce000}, + {0xc57d0000}, {0xc57d2000}, {0xc57d4000}, {0xc57d6000}, + {0xc57d8000}, {0xc57da000}, {0xc57dc000}, {0xc57de000}, + {0xc57e0000}, {0xc57e2000}, {0xc57e4000}, {0xc57e6000}, + {0xc57e8000}, {0xc57ea000}, {0xc57ec000}, {0xc57ee000}, + {0xc57f0000}, {0xc57f2000}, {0xc57f4000}, {0xc57f6000}, + {0xc57f8000}, {0xc57fa000}, {0xc57fc000}, {0xc57fe000}, + {0xc5800000}, {0xc5802000}, {0xc5804000}, {0xc5806000}, + {0xc5808000}, {0xc580a000}, {0xc580c000}, {0xc580e000}, + {0xc5810000}, {0xc5812000}, {0xc5814000}, {0xc5816000}, + {0xc5818000}, {0xc581a000}, {0xc581c000}, {0xc581e000}, + {0xc5820000}, {0xc5822000}, {0xc5824000}, {0xc5826000}, + {0xc5828000}, {0xc582a000}, {0xc582c000}, {0xc582e000}, + {0xc5830000}, {0xc5832000}, {0xc5834000}, {0xc5836000}, + {0xc5838000}, {0xc583a000}, {0xc583c000}, {0xc583e000}, + {0xc5840000}, {0xc5842000}, {0xc5844000}, {0xc5846000}, + {0xc5848000}, {0xc584a000}, {0xc584c000}, {0xc584e000}, + {0xc5850000}, {0xc5852000}, {0xc5854000}, {0xc5856000}, + {0xc5858000}, {0xc585a000}, {0xc585c000}, {0xc585e000}, + {0xc5860000}, {0xc5862000}, {0xc5864000}, {0xc5866000}, + {0xc5868000}, {0xc586a000}, {0xc586c000}, {0xc586e000}, + {0xc5870000}, {0xc5872000}, {0xc5874000}, {0xc5876000}, + {0xc5878000}, {0xc587a000}, {0xc587c000}, {0xc587e000}, + {0xc5880000}, {0xc5882000}, {0xc5884000}, {0xc5886000}, + {0xc5888000}, {0xc588a000}, {0xc588c000}, {0xc588e000}, + {0xc5890000}, {0xc5892000}, {0xc5894000}, {0xc5896000}, + {0xc5898000}, {0xc589a000}, {0xc589c000}, {0xc589e000}, + {0xc58a0000}, {0xc58a2000}, {0xc58a4000}, {0xc58a6000}, + {0xc58a8000}, {0xc58aa000}, {0xc58ac000}, {0xc58ae000}, + {0xc58b0000}, {0xc58b2000}, {0xc58b4000}, {0xc58b6000}, + {0xc58b8000}, {0xc58ba000}, {0xc58bc000}, {0xc58be000}, + {0xc58c0000}, {0xc58c2000}, {0xc58c4000}, {0xc58c6000}, + {0xc58c8000}, {0xc58ca000}, {0xc58cc000}, {0xc58ce000}, + {0xc58d0000}, {0xc58d2000}, {0xc58d4000}, {0xc58d6000}, + {0xc58d8000}, {0xc58da000}, {0xc58dc000}, {0xc58de000}, + {0xc58e0000}, {0xc58e2000}, {0xc58e4000}, {0xc58e6000}, + {0xc58e8000}, {0xc58ea000}, {0xc58ec000}, {0xc58ee000}, + {0xc58f0000}, {0xc58f2000}, {0xc58f4000}, {0xc58f6000}, + {0xc58f8000}, {0xc58fa000}, {0xc58fc000}, {0xc58fe000}, + {0xc5900000}, {0xc5902000}, {0xc5904000}, {0xc5906000}, + {0xc5908000}, {0xc590a000}, {0xc590c000}, {0xc590e000}, + {0xc5910000}, {0xc5912000}, {0xc5914000}, {0xc5916000}, + {0xc5918000}, {0xc591a000}, {0xc591c000}, {0xc591e000}, + {0xc5920000}, {0xc5922000}, {0xc5924000}, {0xc5926000}, + {0xc5928000}, {0xc592a000}, {0xc592c000}, {0xc592e000}, + {0xc5930000}, {0xc5932000}, {0xc5934000}, {0xc5936000}, + {0xc5938000}, {0xc593a000}, {0xc593c000}, {0xc593e000}, + {0xc5940000}, {0xc5942000}, {0xc5944000}, {0xc5946000}, + {0xc5948000}, {0xc594a000}, {0xc594c000}, {0xc594e000}, + {0xc5950000}, {0xc5952000}, {0xc5954000}, {0xc5956000}, + {0xc5958000}, {0xc595a000}, {0xc595c000}, {0xc595e000}, + {0xc5960000}, {0xc5962000}, {0xc5964000}, {0xc5966000}, + {0xc5968000}, {0xc596a000}, {0xc596c000}, {0xc596e000}, + {0xc5970000}, {0xc5972000}, {0xc5974000}, {0xc5976000}, + {0xc5978000}, {0xc597a000}, {0xc597c000}, {0xc597e000}, + {0xc5980000}, {0xc5982000}, {0xc5984000}, {0xc5986000}, + {0xc5988000}, {0xc598a000}, {0xc598c000}, {0xc598e000}, + {0xc5990000}, {0xc5992000}, {0xc5994000}, {0xc5996000}, + {0xc5998000}, {0xc599a000}, {0xc599c000}, {0xc599e000}, + {0xc59a0000}, {0xc59a2000}, {0xc59a4000}, {0xc59a6000}, + {0xc59a8000}, {0xc59aa000}, {0xc59ac000}, {0xc59ae000}, + {0xc59b0000}, {0xc59b2000}, {0xc59b4000}, {0xc59b6000}, + {0xc59b8000}, {0xc59ba000}, {0xc59bc000}, {0xc59be000}, + {0xc59c0000}, {0xc59c2000}, {0xc59c4000}, {0xc59c6000}, + {0xc59c8000}, {0xc59ca000}, {0xc59cc000}, {0xc59ce000}, + {0xc59d0000}, {0xc59d2000}, {0xc59d4000}, {0xc59d6000}, + {0xc59d8000}, {0xc59da000}, {0xc59dc000}, {0xc59de000}, + {0xc59e0000}, {0xc59e2000}, {0xc59e4000}, {0xc59e6000}, + {0xc59e8000}, {0xc59ea000}, {0xc59ec000}, {0xc59ee000}, + {0xc59f0000}, {0xc59f2000}, {0xc59f4000}, {0xc59f6000}, + {0xc59f8000}, {0xc59fa000}, {0xc59fc000}, {0xc59fe000}, + {0xc5a00000}, {0xc5a02000}, {0xc5a04000}, {0xc5a06000}, + {0xc5a08000}, {0xc5a0a000}, {0xc5a0c000}, {0xc5a0e000}, + {0xc5a10000}, {0xc5a12000}, {0xc5a14000}, {0xc5a16000}, + {0xc5a18000}, {0xc5a1a000}, {0xc5a1c000}, {0xc5a1e000}, + {0xc5a20000}, {0xc5a22000}, {0xc5a24000}, {0xc5a26000}, + {0xc5a28000}, {0xc5a2a000}, {0xc5a2c000}, {0xc5a2e000}, + {0xc5a30000}, {0xc5a32000}, {0xc5a34000}, {0xc5a36000}, + {0xc5a38000}, {0xc5a3a000}, {0xc5a3c000}, {0xc5a3e000}, + {0xc5a40000}, {0xc5a42000}, {0xc5a44000}, {0xc5a46000}, + {0xc5a48000}, {0xc5a4a000}, {0xc5a4c000}, {0xc5a4e000}, + {0xc5a50000}, {0xc5a52000}, {0xc5a54000}, {0xc5a56000}, + {0xc5a58000}, {0xc5a5a000}, {0xc5a5c000}, {0xc5a5e000}, + {0xc5a60000}, {0xc5a62000}, {0xc5a64000}, {0xc5a66000}, + {0xc5a68000}, {0xc5a6a000}, {0xc5a6c000}, {0xc5a6e000}, + {0xc5a70000}, {0xc5a72000}, {0xc5a74000}, {0xc5a76000}, + {0xc5a78000}, {0xc5a7a000}, {0xc5a7c000}, {0xc5a7e000}, + {0xc5a80000}, {0xc5a82000}, {0xc5a84000}, {0xc5a86000}, + {0xc5a88000}, {0xc5a8a000}, {0xc5a8c000}, {0xc5a8e000}, + {0xc5a90000}, {0xc5a92000}, {0xc5a94000}, {0xc5a96000}, + {0xc5a98000}, {0xc5a9a000}, {0xc5a9c000}, {0xc5a9e000}, + {0xc5aa0000}, {0xc5aa2000}, {0xc5aa4000}, {0xc5aa6000}, + {0xc5aa8000}, {0xc5aaa000}, {0xc5aac000}, {0xc5aae000}, + {0xc5ab0000}, {0xc5ab2000}, {0xc5ab4000}, {0xc5ab6000}, + {0xc5ab8000}, {0xc5aba000}, {0xc5abc000}, {0xc5abe000}, + {0xc5ac0000}, {0xc5ac2000}, {0xc5ac4000}, {0xc5ac6000}, + {0xc5ac8000}, {0xc5aca000}, {0xc5acc000}, {0xc5ace000}, + {0xc5ad0000}, {0xc5ad2000}, {0xc5ad4000}, {0xc5ad6000}, + {0xc5ad8000}, {0xc5ada000}, {0xc5adc000}, {0xc5ade000}, + {0xc5ae0000}, {0xc5ae2000}, {0xc5ae4000}, {0xc5ae6000}, + {0xc5ae8000}, {0xc5aea000}, {0xc5aec000}, {0xc5aee000}, + {0xc5af0000}, {0xc5af2000}, {0xc5af4000}, {0xc5af6000}, + {0xc5af8000}, {0xc5afa000}, {0xc5afc000}, {0xc5afe000}, + {0xc5b00000}, {0xc5b02000}, {0xc5b04000}, {0xc5b06000}, + {0xc5b08000}, {0xc5b0a000}, {0xc5b0c000}, {0xc5b0e000}, + {0xc5b10000}, {0xc5b12000}, {0xc5b14000}, {0xc5b16000}, + {0xc5b18000}, {0xc5b1a000}, {0xc5b1c000}, {0xc5b1e000}, + {0xc5b20000}, {0xc5b22000}, {0xc5b24000}, {0xc5b26000}, + {0xc5b28000}, {0xc5b2a000}, {0xc5b2c000}, {0xc5b2e000}, + {0xc5b30000}, {0xc5b32000}, {0xc5b34000}, {0xc5b36000}, + {0xc5b38000}, {0xc5b3a000}, {0xc5b3c000}, {0xc5b3e000}, + {0xc5b40000}, {0xc5b42000}, {0xc5b44000}, {0xc5b46000}, + {0xc5b48000}, {0xc5b4a000}, {0xc5b4c000}, {0xc5b4e000}, + {0xc5b50000}, {0xc5b52000}, {0xc5b54000}, {0xc5b56000}, + {0xc5b58000}, {0xc5b5a000}, {0xc5b5c000}, {0xc5b5e000}, + {0xc5b60000}, {0xc5b62000}, {0xc5b64000}, {0xc5b66000}, + {0xc5b68000}, {0xc5b6a000}, {0xc5b6c000}, {0xc5b6e000}, + {0xc5b70000}, {0xc5b72000}, {0xc5b74000}, {0xc5b76000}, + {0xc5b78000}, {0xc5b7a000}, {0xc5b7c000}, {0xc5b7e000}, + {0xc5b80000}, {0xc5b82000}, {0xc5b84000}, {0xc5b86000}, + {0xc5b88000}, {0xc5b8a000}, {0xc5b8c000}, {0xc5b8e000}, + {0xc5b90000}, {0xc5b92000}, {0xc5b94000}, {0xc5b96000}, + {0xc5b98000}, {0xc5b9a000}, {0xc5b9c000}, {0xc5b9e000}, + {0xc5ba0000}, {0xc5ba2000}, {0xc5ba4000}, {0xc5ba6000}, + {0xc5ba8000}, {0xc5baa000}, {0xc5bac000}, {0xc5bae000}, + {0xc5bb0000}, {0xc5bb2000}, {0xc5bb4000}, {0xc5bb6000}, + {0xc5bb8000}, {0xc5bba000}, {0xc5bbc000}, {0xc5bbe000}, + {0xc5bc0000}, {0xc5bc2000}, {0xc5bc4000}, {0xc5bc6000}, + {0xc5bc8000}, {0xc5bca000}, {0xc5bcc000}, {0xc5bce000}, + {0xc5bd0000}, {0xc5bd2000}, {0xc5bd4000}, {0xc5bd6000}, + {0xc5bd8000}, {0xc5bda000}, {0xc5bdc000}, {0xc5bde000}, + {0xc5be0000}, {0xc5be2000}, {0xc5be4000}, {0xc5be6000}, + {0xc5be8000}, {0xc5bea000}, {0xc5bec000}, {0xc5bee000}, + {0xc5bf0000}, {0xc5bf2000}, {0xc5bf4000}, {0xc5bf6000}, + {0xc5bf8000}, {0xc5bfa000}, {0xc5bfc000}, {0xc5bfe000}, + {0xc5c00000}, {0xc5c02000}, {0xc5c04000}, {0xc5c06000}, + {0xc5c08000}, {0xc5c0a000}, {0xc5c0c000}, {0xc5c0e000}, + {0xc5c10000}, {0xc5c12000}, {0xc5c14000}, {0xc5c16000}, + {0xc5c18000}, {0xc5c1a000}, {0xc5c1c000}, {0xc5c1e000}, + {0xc5c20000}, {0xc5c22000}, {0xc5c24000}, {0xc5c26000}, + {0xc5c28000}, {0xc5c2a000}, {0xc5c2c000}, {0xc5c2e000}, + {0xc5c30000}, {0xc5c32000}, {0xc5c34000}, {0xc5c36000}, + {0xc5c38000}, {0xc5c3a000}, {0xc5c3c000}, {0xc5c3e000}, + {0xc5c40000}, {0xc5c42000}, {0xc5c44000}, {0xc5c46000}, + {0xc5c48000}, {0xc5c4a000}, {0xc5c4c000}, {0xc5c4e000}, + {0xc5c50000}, {0xc5c52000}, {0xc5c54000}, {0xc5c56000}, + {0xc5c58000}, {0xc5c5a000}, {0xc5c5c000}, {0xc5c5e000}, + {0xc5c60000}, {0xc5c62000}, {0xc5c64000}, {0xc5c66000}, + {0xc5c68000}, {0xc5c6a000}, {0xc5c6c000}, {0xc5c6e000}, + {0xc5c70000}, {0xc5c72000}, {0xc5c74000}, {0xc5c76000}, + {0xc5c78000}, {0xc5c7a000}, {0xc5c7c000}, {0xc5c7e000}, + {0xc5c80000}, {0xc5c82000}, {0xc5c84000}, {0xc5c86000}, + {0xc5c88000}, {0xc5c8a000}, {0xc5c8c000}, {0xc5c8e000}, + {0xc5c90000}, {0xc5c92000}, {0xc5c94000}, {0xc5c96000}, + {0xc5c98000}, {0xc5c9a000}, {0xc5c9c000}, {0xc5c9e000}, + {0xc5ca0000}, {0xc5ca2000}, {0xc5ca4000}, {0xc5ca6000}, + {0xc5ca8000}, {0xc5caa000}, {0xc5cac000}, {0xc5cae000}, + {0xc5cb0000}, {0xc5cb2000}, {0xc5cb4000}, {0xc5cb6000}, + {0xc5cb8000}, {0xc5cba000}, {0xc5cbc000}, {0xc5cbe000}, + {0xc5cc0000}, {0xc5cc2000}, {0xc5cc4000}, {0xc5cc6000}, + {0xc5cc8000}, {0xc5cca000}, {0xc5ccc000}, {0xc5cce000}, + {0xc5cd0000}, {0xc5cd2000}, {0xc5cd4000}, {0xc5cd6000}, + {0xc5cd8000}, {0xc5cda000}, {0xc5cdc000}, {0xc5cde000}, + {0xc5ce0000}, {0xc5ce2000}, {0xc5ce4000}, {0xc5ce6000}, + {0xc5ce8000}, {0xc5cea000}, {0xc5cec000}, {0xc5cee000}, + {0xc5cf0000}, {0xc5cf2000}, {0xc5cf4000}, {0xc5cf6000}, + {0xc5cf8000}, {0xc5cfa000}, {0xc5cfc000}, {0xc5cfe000}, + {0xc5d00000}, {0xc5d02000}, {0xc5d04000}, {0xc5d06000}, + {0xc5d08000}, {0xc5d0a000}, {0xc5d0c000}, {0xc5d0e000}, + {0xc5d10000}, {0xc5d12000}, {0xc5d14000}, {0xc5d16000}, + {0xc5d18000}, {0xc5d1a000}, {0xc5d1c000}, {0xc5d1e000}, + {0xc5d20000}, {0xc5d22000}, {0xc5d24000}, {0xc5d26000}, + {0xc5d28000}, {0xc5d2a000}, {0xc5d2c000}, {0xc5d2e000}, + {0xc5d30000}, {0xc5d32000}, {0xc5d34000}, {0xc5d36000}, + {0xc5d38000}, {0xc5d3a000}, {0xc5d3c000}, {0xc5d3e000}, + {0xc5d40000}, {0xc5d42000}, {0xc5d44000}, {0xc5d46000}, + {0xc5d48000}, {0xc5d4a000}, {0xc5d4c000}, {0xc5d4e000}, + {0xc5d50000}, {0xc5d52000}, {0xc5d54000}, {0xc5d56000}, + {0xc5d58000}, {0xc5d5a000}, {0xc5d5c000}, {0xc5d5e000}, + {0xc5d60000}, {0xc5d62000}, {0xc5d64000}, {0xc5d66000}, + {0xc5d68000}, {0xc5d6a000}, {0xc5d6c000}, {0xc5d6e000}, + {0xc5d70000}, {0xc5d72000}, {0xc5d74000}, {0xc5d76000}, + {0xc5d78000}, {0xc5d7a000}, {0xc5d7c000}, {0xc5d7e000}, + {0xc5d80000}, {0xc5d82000}, {0xc5d84000}, {0xc5d86000}, + {0xc5d88000}, {0xc5d8a000}, {0xc5d8c000}, {0xc5d8e000}, + {0xc5d90000}, {0xc5d92000}, {0xc5d94000}, {0xc5d96000}, + {0xc5d98000}, {0xc5d9a000}, {0xc5d9c000}, {0xc5d9e000}, + {0xc5da0000}, {0xc5da2000}, {0xc5da4000}, {0xc5da6000}, + {0xc5da8000}, {0xc5daa000}, {0xc5dac000}, {0xc5dae000}, + {0xc5db0000}, {0xc5db2000}, {0xc5db4000}, {0xc5db6000}, + {0xc5db8000}, {0xc5dba000}, {0xc5dbc000}, {0xc5dbe000}, + {0xc5dc0000}, {0xc5dc2000}, {0xc5dc4000}, {0xc5dc6000}, + {0xc5dc8000}, {0xc5dca000}, {0xc5dcc000}, {0xc5dce000}, + {0xc5dd0000}, {0xc5dd2000}, {0xc5dd4000}, {0xc5dd6000}, + {0xc5dd8000}, {0xc5dda000}, {0xc5ddc000}, {0xc5dde000}, + {0xc5de0000}, {0xc5de2000}, {0xc5de4000}, {0xc5de6000}, + {0xc5de8000}, {0xc5dea000}, {0xc5dec000}, {0xc5dee000}, + {0xc5df0000}, {0xc5df2000}, {0xc5df4000}, {0xc5df6000}, + {0xc5df8000}, {0xc5dfa000}, {0xc5dfc000}, {0xc5dfe000}, + {0xc5e00000}, {0xc5e02000}, {0xc5e04000}, {0xc5e06000}, + {0xc5e08000}, {0xc5e0a000}, {0xc5e0c000}, {0xc5e0e000}, + {0xc5e10000}, {0xc5e12000}, {0xc5e14000}, {0xc5e16000}, + {0xc5e18000}, {0xc5e1a000}, {0xc5e1c000}, {0xc5e1e000}, + {0xc5e20000}, {0xc5e22000}, {0xc5e24000}, {0xc5e26000}, + {0xc5e28000}, {0xc5e2a000}, {0xc5e2c000}, {0xc5e2e000}, + {0xc5e30000}, {0xc5e32000}, {0xc5e34000}, {0xc5e36000}, + {0xc5e38000}, {0xc5e3a000}, {0xc5e3c000}, {0xc5e3e000}, + {0xc5e40000}, {0xc5e42000}, {0xc5e44000}, {0xc5e46000}, + {0xc5e48000}, {0xc5e4a000}, {0xc5e4c000}, {0xc5e4e000}, + {0xc5e50000}, {0xc5e52000}, {0xc5e54000}, {0xc5e56000}, + {0xc5e58000}, {0xc5e5a000}, {0xc5e5c000}, {0xc5e5e000}, + {0xc5e60000}, {0xc5e62000}, {0xc5e64000}, {0xc5e66000}, + {0xc5e68000}, {0xc5e6a000}, {0xc5e6c000}, {0xc5e6e000}, + {0xc5e70000}, {0xc5e72000}, {0xc5e74000}, {0xc5e76000}, + {0xc5e78000}, {0xc5e7a000}, {0xc5e7c000}, {0xc5e7e000}, + {0xc5e80000}, {0xc5e82000}, {0xc5e84000}, {0xc5e86000}, + {0xc5e88000}, {0xc5e8a000}, {0xc5e8c000}, {0xc5e8e000}, + {0xc5e90000}, {0xc5e92000}, {0xc5e94000}, {0xc5e96000}, + {0xc5e98000}, {0xc5e9a000}, {0xc5e9c000}, {0xc5e9e000}, + {0xc5ea0000}, {0xc5ea2000}, {0xc5ea4000}, {0xc5ea6000}, + {0xc5ea8000}, {0xc5eaa000}, {0xc5eac000}, {0xc5eae000}, + {0xc5eb0000}, {0xc5eb2000}, {0xc5eb4000}, {0xc5eb6000}, + {0xc5eb8000}, {0xc5eba000}, {0xc5ebc000}, {0xc5ebe000}, + {0xc5ec0000}, {0xc5ec2000}, {0xc5ec4000}, {0xc5ec6000}, + {0xc5ec8000}, {0xc5eca000}, {0xc5ecc000}, {0xc5ece000}, + {0xc5ed0000}, {0xc5ed2000}, {0xc5ed4000}, {0xc5ed6000}, + {0xc5ed8000}, {0xc5eda000}, {0xc5edc000}, {0xc5ede000}, + {0xc5ee0000}, {0xc5ee2000}, {0xc5ee4000}, {0xc5ee6000}, + {0xc5ee8000}, {0xc5eea000}, {0xc5eec000}, {0xc5eee000}, + {0xc5ef0000}, {0xc5ef2000}, {0xc5ef4000}, {0xc5ef6000}, + {0xc5ef8000}, {0xc5efa000}, {0xc5efc000}, {0xc5efe000}, + {0xc5f00000}, {0xc5f02000}, {0xc5f04000}, {0xc5f06000}, + {0xc5f08000}, {0xc5f0a000}, {0xc5f0c000}, {0xc5f0e000}, + {0xc5f10000}, {0xc5f12000}, {0xc5f14000}, {0xc5f16000}, + {0xc5f18000}, {0xc5f1a000}, {0xc5f1c000}, {0xc5f1e000}, + {0xc5f20000}, {0xc5f22000}, {0xc5f24000}, {0xc5f26000}, + {0xc5f28000}, {0xc5f2a000}, {0xc5f2c000}, {0xc5f2e000}, + {0xc5f30000}, {0xc5f32000}, {0xc5f34000}, {0xc5f36000}, + {0xc5f38000}, {0xc5f3a000}, {0xc5f3c000}, {0xc5f3e000}, + {0xc5f40000}, {0xc5f42000}, {0xc5f44000}, {0xc5f46000}, + {0xc5f48000}, {0xc5f4a000}, {0xc5f4c000}, {0xc5f4e000}, + {0xc5f50000}, {0xc5f52000}, {0xc5f54000}, {0xc5f56000}, + {0xc5f58000}, {0xc5f5a000}, {0xc5f5c000}, {0xc5f5e000}, + {0xc5f60000}, {0xc5f62000}, {0xc5f64000}, {0xc5f66000}, + {0xc5f68000}, {0xc5f6a000}, {0xc5f6c000}, {0xc5f6e000}, + {0xc5f70000}, {0xc5f72000}, {0xc5f74000}, {0xc5f76000}, + {0xc5f78000}, {0xc5f7a000}, {0xc5f7c000}, {0xc5f7e000}, + {0xc5f80000}, {0xc5f82000}, {0xc5f84000}, {0xc5f86000}, + {0xc5f88000}, {0xc5f8a000}, {0xc5f8c000}, {0xc5f8e000}, + {0xc5f90000}, {0xc5f92000}, {0xc5f94000}, {0xc5f96000}, + {0xc5f98000}, {0xc5f9a000}, {0xc5f9c000}, {0xc5f9e000}, + {0xc5fa0000}, {0xc5fa2000}, {0xc5fa4000}, {0xc5fa6000}, + {0xc5fa8000}, {0xc5faa000}, {0xc5fac000}, {0xc5fae000}, + {0xc5fb0000}, {0xc5fb2000}, {0xc5fb4000}, {0xc5fb6000}, + {0xc5fb8000}, {0xc5fba000}, {0xc5fbc000}, {0xc5fbe000}, + {0xc5fc0000}, {0xc5fc2000}, {0xc5fc4000}, {0xc5fc6000}, + {0xc5fc8000}, {0xc5fca000}, {0xc5fcc000}, {0xc5fce000}, + {0xc5fd0000}, {0xc5fd2000}, {0xc5fd4000}, {0xc5fd6000}, + {0xc5fd8000}, {0xc5fda000}, {0xc5fdc000}, {0xc5fde000}, + {0xc5fe0000}, {0xc5fe2000}, {0xc5fe4000}, {0xc5fe6000}, + {0xc5fe8000}, {0xc5fea000}, {0xc5fec000}, {0xc5fee000}, + {0xc5ff0000}, {0xc5ff2000}, {0xc5ff4000}, {0xc5ff6000}, + {0xc5ff8000}, {0xc5ffa000}, {0xc5ffc000}, {0xc5ffe000}, + {0xc6000000}, {0xc6002000}, {0xc6004000}, {0xc6006000}, + {0xc6008000}, {0xc600a000}, {0xc600c000}, {0xc600e000}, + {0xc6010000}, {0xc6012000}, {0xc6014000}, {0xc6016000}, + {0xc6018000}, {0xc601a000}, {0xc601c000}, {0xc601e000}, + {0xc6020000}, {0xc6022000}, {0xc6024000}, {0xc6026000}, + {0xc6028000}, {0xc602a000}, {0xc602c000}, {0xc602e000}, + {0xc6030000}, {0xc6032000}, {0xc6034000}, {0xc6036000}, + {0xc6038000}, {0xc603a000}, {0xc603c000}, {0xc603e000}, + {0xc6040000}, {0xc6042000}, {0xc6044000}, {0xc6046000}, + {0xc6048000}, {0xc604a000}, {0xc604c000}, {0xc604e000}, + {0xc6050000}, {0xc6052000}, {0xc6054000}, {0xc6056000}, + {0xc6058000}, {0xc605a000}, {0xc605c000}, {0xc605e000}, + {0xc6060000}, {0xc6062000}, {0xc6064000}, {0xc6066000}, + {0xc6068000}, {0xc606a000}, {0xc606c000}, {0xc606e000}, + {0xc6070000}, {0xc6072000}, {0xc6074000}, {0xc6076000}, + {0xc6078000}, {0xc607a000}, {0xc607c000}, {0xc607e000}, + {0xc6080000}, {0xc6082000}, {0xc6084000}, {0xc6086000}, + {0xc6088000}, {0xc608a000}, {0xc608c000}, {0xc608e000}, + {0xc6090000}, {0xc6092000}, {0xc6094000}, {0xc6096000}, + {0xc6098000}, {0xc609a000}, {0xc609c000}, {0xc609e000}, + {0xc60a0000}, {0xc60a2000}, {0xc60a4000}, {0xc60a6000}, + {0xc60a8000}, {0xc60aa000}, {0xc60ac000}, {0xc60ae000}, + {0xc60b0000}, {0xc60b2000}, {0xc60b4000}, {0xc60b6000}, + {0xc60b8000}, {0xc60ba000}, {0xc60bc000}, {0xc60be000}, + {0xc60c0000}, {0xc60c2000}, {0xc60c4000}, {0xc60c6000}, + {0xc60c8000}, {0xc60ca000}, {0xc60cc000}, {0xc60ce000}, + {0xc60d0000}, {0xc60d2000}, {0xc60d4000}, {0xc60d6000}, + {0xc60d8000}, {0xc60da000}, {0xc60dc000}, {0xc60de000}, + {0xc60e0000}, {0xc60e2000}, {0xc60e4000}, {0xc60e6000}, + {0xc60e8000}, {0xc60ea000}, {0xc60ec000}, {0xc60ee000}, + {0xc60f0000}, {0xc60f2000}, {0xc60f4000}, {0xc60f6000}, + {0xc60f8000}, {0xc60fa000}, {0xc60fc000}, {0xc60fe000}, + {0xc6100000}, {0xc6102000}, {0xc6104000}, {0xc6106000}, + {0xc6108000}, {0xc610a000}, {0xc610c000}, {0xc610e000}, + {0xc6110000}, {0xc6112000}, {0xc6114000}, {0xc6116000}, + {0xc6118000}, {0xc611a000}, {0xc611c000}, {0xc611e000}, + {0xc6120000}, {0xc6122000}, {0xc6124000}, {0xc6126000}, + {0xc6128000}, {0xc612a000}, {0xc612c000}, {0xc612e000}, + {0xc6130000}, {0xc6132000}, {0xc6134000}, {0xc6136000}, + {0xc6138000}, {0xc613a000}, {0xc613c000}, {0xc613e000}, + {0xc6140000}, {0xc6142000}, {0xc6144000}, {0xc6146000}, + {0xc6148000}, {0xc614a000}, {0xc614c000}, {0xc614e000}, + {0xc6150000}, {0xc6152000}, {0xc6154000}, {0xc6156000}, + {0xc6158000}, {0xc615a000}, {0xc615c000}, {0xc615e000}, + {0xc6160000}, {0xc6162000}, {0xc6164000}, {0xc6166000}, + {0xc6168000}, {0xc616a000}, {0xc616c000}, {0xc616e000}, + {0xc6170000}, {0xc6172000}, {0xc6174000}, {0xc6176000}, + {0xc6178000}, {0xc617a000}, {0xc617c000}, {0xc617e000}, + {0xc6180000}, {0xc6182000}, {0xc6184000}, {0xc6186000}, + {0xc6188000}, {0xc618a000}, {0xc618c000}, {0xc618e000}, + {0xc6190000}, {0xc6192000}, {0xc6194000}, {0xc6196000}, + {0xc6198000}, {0xc619a000}, {0xc619c000}, {0xc619e000}, + {0xc61a0000}, {0xc61a2000}, {0xc61a4000}, {0xc61a6000}, + {0xc61a8000}, {0xc61aa000}, {0xc61ac000}, {0xc61ae000}, + {0xc61b0000}, {0xc61b2000}, {0xc61b4000}, {0xc61b6000}, + {0xc61b8000}, {0xc61ba000}, {0xc61bc000}, {0xc61be000}, + {0xc61c0000}, {0xc61c2000}, {0xc61c4000}, {0xc61c6000}, + {0xc61c8000}, {0xc61ca000}, {0xc61cc000}, {0xc61ce000}, + {0xc61d0000}, {0xc61d2000}, {0xc61d4000}, {0xc61d6000}, + {0xc61d8000}, {0xc61da000}, {0xc61dc000}, {0xc61de000}, + {0xc61e0000}, {0xc61e2000}, {0xc61e4000}, {0xc61e6000}, + {0xc61e8000}, {0xc61ea000}, {0xc61ec000}, {0xc61ee000}, + {0xc61f0000}, {0xc61f2000}, {0xc61f4000}, {0xc61f6000}, + {0xc61f8000}, {0xc61fa000}, {0xc61fc000}, {0xc61fe000}, + {0xc6200000}, {0xc6202000}, {0xc6204000}, {0xc6206000}, + {0xc6208000}, {0xc620a000}, {0xc620c000}, {0xc620e000}, + {0xc6210000}, {0xc6212000}, {0xc6214000}, {0xc6216000}, + {0xc6218000}, {0xc621a000}, {0xc621c000}, {0xc621e000}, + {0xc6220000}, {0xc6222000}, {0xc6224000}, {0xc6226000}, + {0xc6228000}, {0xc622a000}, {0xc622c000}, {0xc622e000}, + {0xc6230000}, {0xc6232000}, {0xc6234000}, {0xc6236000}, + {0xc6238000}, {0xc623a000}, {0xc623c000}, {0xc623e000}, + {0xc6240000}, {0xc6242000}, {0xc6244000}, {0xc6246000}, + {0xc6248000}, {0xc624a000}, {0xc624c000}, {0xc624e000}, + {0xc6250000}, {0xc6252000}, {0xc6254000}, {0xc6256000}, + {0xc6258000}, {0xc625a000}, {0xc625c000}, {0xc625e000}, + {0xc6260000}, {0xc6262000}, {0xc6264000}, {0xc6266000}, + {0xc6268000}, {0xc626a000}, {0xc626c000}, {0xc626e000}, + {0xc6270000}, {0xc6272000}, {0xc6274000}, {0xc6276000}, + {0xc6278000}, {0xc627a000}, {0xc627c000}, {0xc627e000}, + {0xc6280000}, {0xc6282000}, {0xc6284000}, {0xc6286000}, + {0xc6288000}, {0xc628a000}, {0xc628c000}, {0xc628e000}, + {0xc6290000}, {0xc6292000}, {0xc6294000}, {0xc6296000}, + {0xc6298000}, {0xc629a000}, {0xc629c000}, {0xc629e000}, + {0xc62a0000}, {0xc62a2000}, {0xc62a4000}, {0xc62a6000}, + {0xc62a8000}, {0xc62aa000}, {0xc62ac000}, {0xc62ae000}, + {0xc62b0000}, {0xc62b2000}, {0xc62b4000}, {0xc62b6000}, + {0xc62b8000}, {0xc62ba000}, {0xc62bc000}, {0xc62be000}, + {0xc62c0000}, {0xc62c2000}, {0xc62c4000}, {0xc62c6000}, + {0xc62c8000}, {0xc62ca000}, {0xc62cc000}, {0xc62ce000}, + {0xc62d0000}, {0xc62d2000}, {0xc62d4000}, {0xc62d6000}, + {0xc62d8000}, {0xc62da000}, {0xc62dc000}, {0xc62de000}, + {0xc62e0000}, {0xc62e2000}, {0xc62e4000}, {0xc62e6000}, + {0xc62e8000}, {0xc62ea000}, {0xc62ec000}, {0xc62ee000}, + {0xc62f0000}, {0xc62f2000}, {0xc62f4000}, {0xc62f6000}, + {0xc62f8000}, {0xc62fa000}, {0xc62fc000}, {0xc62fe000}, + {0xc6300000}, {0xc6302000}, {0xc6304000}, {0xc6306000}, + {0xc6308000}, {0xc630a000}, {0xc630c000}, {0xc630e000}, + {0xc6310000}, {0xc6312000}, {0xc6314000}, {0xc6316000}, + {0xc6318000}, {0xc631a000}, {0xc631c000}, {0xc631e000}, + {0xc6320000}, {0xc6322000}, {0xc6324000}, {0xc6326000}, + {0xc6328000}, {0xc632a000}, {0xc632c000}, {0xc632e000}, + {0xc6330000}, {0xc6332000}, {0xc6334000}, {0xc6336000}, + {0xc6338000}, {0xc633a000}, {0xc633c000}, {0xc633e000}, + {0xc6340000}, {0xc6342000}, {0xc6344000}, {0xc6346000}, + {0xc6348000}, {0xc634a000}, {0xc634c000}, {0xc634e000}, + {0xc6350000}, {0xc6352000}, {0xc6354000}, {0xc6356000}, + {0xc6358000}, {0xc635a000}, {0xc635c000}, {0xc635e000}, + {0xc6360000}, {0xc6362000}, {0xc6364000}, {0xc6366000}, + {0xc6368000}, {0xc636a000}, {0xc636c000}, {0xc636e000}, + {0xc6370000}, {0xc6372000}, {0xc6374000}, {0xc6376000}, + {0xc6378000}, {0xc637a000}, {0xc637c000}, {0xc637e000}, + {0xc6380000}, {0xc6382000}, {0xc6384000}, {0xc6386000}, + {0xc6388000}, {0xc638a000}, {0xc638c000}, {0xc638e000}, + {0xc6390000}, {0xc6392000}, {0xc6394000}, {0xc6396000}, + {0xc6398000}, {0xc639a000}, {0xc639c000}, {0xc639e000}, + {0xc63a0000}, {0xc63a2000}, {0xc63a4000}, {0xc63a6000}, + {0xc63a8000}, {0xc63aa000}, {0xc63ac000}, {0xc63ae000}, + {0xc63b0000}, {0xc63b2000}, {0xc63b4000}, {0xc63b6000}, + {0xc63b8000}, {0xc63ba000}, {0xc63bc000}, {0xc63be000}, + {0xc63c0000}, {0xc63c2000}, {0xc63c4000}, {0xc63c6000}, + {0xc63c8000}, {0xc63ca000}, {0xc63cc000}, {0xc63ce000}, + {0xc63d0000}, {0xc63d2000}, {0xc63d4000}, {0xc63d6000}, + {0xc63d8000}, {0xc63da000}, {0xc63dc000}, {0xc63de000}, + {0xc63e0000}, {0xc63e2000}, {0xc63e4000}, {0xc63e6000}, + {0xc63e8000}, {0xc63ea000}, {0xc63ec000}, {0xc63ee000}, + {0xc63f0000}, {0xc63f2000}, {0xc63f4000}, {0xc63f6000}, + {0xc63f8000}, {0xc63fa000}, {0xc63fc000}, {0xc63fe000}, + {0xc6400000}, {0xc6402000}, {0xc6404000}, {0xc6406000}, + {0xc6408000}, {0xc640a000}, {0xc640c000}, {0xc640e000}, + {0xc6410000}, {0xc6412000}, {0xc6414000}, {0xc6416000}, + {0xc6418000}, {0xc641a000}, {0xc641c000}, {0xc641e000}, + {0xc6420000}, {0xc6422000}, {0xc6424000}, {0xc6426000}, + {0xc6428000}, {0xc642a000}, {0xc642c000}, {0xc642e000}, + {0xc6430000}, {0xc6432000}, {0xc6434000}, {0xc6436000}, + {0xc6438000}, {0xc643a000}, {0xc643c000}, {0xc643e000}, + {0xc6440000}, {0xc6442000}, {0xc6444000}, {0xc6446000}, + {0xc6448000}, {0xc644a000}, {0xc644c000}, {0xc644e000}, + {0xc6450000}, {0xc6452000}, {0xc6454000}, {0xc6456000}, + {0xc6458000}, {0xc645a000}, {0xc645c000}, {0xc645e000}, + {0xc6460000}, {0xc6462000}, {0xc6464000}, {0xc6466000}, + {0xc6468000}, {0xc646a000}, {0xc646c000}, {0xc646e000}, + {0xc6470000}, {0xc6472000}, {0xc6474000}, {0xc6476000}, + {0xc6478000}, {0xc647a000}, {0xc647c000}, {0xc647e000}, + {0xc6480000}, {0xc6482000}, {0xc6484000}, {0xc6486000}, + {0xc6488000}, {0xc648a000}, {0xc648c000}, {0xc648e000}, + {0xc6490000}, {0xc6492000}, {0xc6494000}, {0xc6496000}, + {0xc6498000}, {0xc649a000}, {0xc649c000}, {0xc649e000}, + {0xc64a0000}, {0xc64a2000}, {0xc64a4000}, {0xc64a6000}, + {0xc64a8000}, {0xc64aa000}, {0xc64ac000}, {0xc64ae000}, + {0xc64b0000}, {0xc64b2000}, {0xc64b4000}, {0xc64b6000}, + {0xc64b8000}, {0xc64ba000}, {0xc64bc000}, {0xc64be000}, + {0xc64c0000}, {0xc64c2000}, {0xc64c4000}, {0xc64c6000}, + {0xc64c8000}, {0xc64ca000}, {0xc64cc000}, {0xc64ce000}, + {0xc64d0000}, {0xc64d2000}, {0xc64d4000}, {0xc64d6000}, + {0xc64d8000}, {0xc64da000}, {0xc64dc000}, {0xc64de000}, + {0xc64e0000}, {0xc64e2000}, {0xc64e4000}, {0xc64e6000}, + {0xc64e8000}, {0xc64ea000}, {0xc64ec000}, {0xc64ee000}, + {0xc64f0000}, {0xc64f2000}, {0xc64f4000}, {0xc64f6000}, + {0xc64f8000}, {0xc64fa000}, {0xc64fc000}, {0xc64fe000}, + {0xc6500000}, {0xc6502000}, {0xc6504000}, {0xc6506000}, + {0xc6508000}, {0xc650a000}, {0xc650c000}, {0xc650e000}, + {0xc6510000}, {0xc6512000}, {0xc6514000}, {0xc6516000}, + {0xc6518000}, {0xc651a000}, {0xc651c000}, {0xc651e000}, + {0xc6520000}, {0xc6522000}, {0xc6524000}, {0xc6526000}, + {0xc6528000}, {0xc652a000}, {0xc652c000}, {0xc652e000}, + {0xc6530000}, {0xc6532000}, {0xc6534000}, {0xc6536000}, + {0xc6538000}, {0xc653a000}, {0xc653c000}, {0xc653e000}, + {0xc6540000}, {0xc6542000}, {0xc6544000}, {0xc6546000}, + {0xc6548000}, {0xc654a000}, {0xc654c000}, {0xc654e000}, + {0xc6550000}, {0xc6552000}, {0xc6554000}, {0xc6556000}, + {0xc6558000}, {0xc655a000}, {0xc655c000}, {0xc655e000}, + {0xc6560000}, {0xc6562000}, {0xc6564000}, {0xc6566000}, + {0xc6568000}, {0xc656a000}, {0xc656c000}, {0xc656e000}, + {0xc6570000}, {0xc6572000}, {0xc6574000}, {0xc6576000}, + {0xc6578000}, {0xc657a000}, {0xc657c000}, {0xc657e000}, + {0xc6580000}, {0xc6582000}, {0xc6584000}, {0xc6586000}, + {0xc6588000}, {0xc658a000}, {0xc658c000}, {0xc658e000}, + {0xc6590000}, {0xc6592000}, {0xc6594000}, {0xc6596000}, + {0xc6598000}, {0xc659a000}, {0xc659c000}, {0xc659e000}, + {0xc65a0000}, {0xc65a2000}, {0xc65a4000}, {0xc65a6000}, + {0xc65a8000}, {0xc65aa000}, {0xc65ac000}, {0xc65ae000}, + {0xc65b0000}, {0xc65b2000}, {0xc65b4000}, {0xc65b6000}, + {0xc65b8000}, {0xc65ba000}, {0xc65bc000}, {0xc65be000}, + {0xc65c0000}, {0xc65c2000}, {0xc65c4000}, {0xc65c6000}, + {0xc65c8000}, {0xc65ca000}, {0xc65cc000}, {0xc65ce000}, + {0xc65d0000}, {0xc65d2000}, {0xc65d4000}, {0xc65d6000}, + {0xc65d8000}, {0xc65da000}, {0xc65dc000}, {0xc65de000}, + {0xc65e0000}, {0xc65e2000}, {0xc65e4000}, {0xc65e6000}, + {0xc65e8000}, {0xc65ea000}, {0xc65ec000}, {0xc65ee000}, + {0xc65f0000}, {0xc65f2000}, {0xc65f4000}, {0xc65f6000}, + {0xc65f8000}, {0xc65fa000}, {0xc65fc000}, {0xc65fe000}, + {0xc6600000}, {0xc6602000}, {0xc6604000}, {0xc6606000}, + {0xc6608000}, {0xc660a000}, {0xc660c000}, {0xc660e000}, + {0xc6610000}, {0xc6612000}, {0xc6614000}, {0xc6616000}, + {0xc6618000}, {0xc661a000}, {0xc661c000}, {0xc661e000}, + {0xc6620000}, {0xc6622000}, {0xc6624000}, {0xc6626000}, + {0xc6628000}, {0xc662a000}, {0xc662c000}, {0xc662e000}, + {0xc6630000}, {0xc6632000}, {0xc6634000}, {0xc6636000}, + {0xc6638000}, {0xc663a000}, {0xc663c000}, {0xc663e000}, + {0xc6640000}, {0xc6642000}, {0xc6644000}, {0xc6646000}, + {0xc6648000}, {0xc664a000}, {0xc664c000}, {0xc664e000}, + {0xc6650000}, {0xc6652000}, {0xc6654000}, {0xc6656000}, + {0xc6658000}, {0xc665a000}, {0xc665c000}, {0xc665e000}, + {0xc6660000}, {0xc6662000}, {0xc6664000}, {0xc6666000}, + {0xc6668000}, {0xc666a000}, {0xc666c000}, {0xc666e000}, + {0xc6670000}, {0xc6672000}, {0xc6674000}, {0xc6676000}, + {0xc6678000}, {0xc667a000}, {0xc667c000}, {0xc667e000}, + {0xc6680000}, {0xc6682000}, {0xc6684000}, {0xc6686000}, + {0xc6688000}, {0xc668a000}, {0xc668c000}, {0xc668e000}, + {0xc6690000}, {0xc6692000}, {0xc6694000}, {0xc6696000}, + {0xc6698000}, {0xc669a000}, {0xc669c000}, {0xc669e000}, + {0xc66a0000}, {0xc66a2000}, {0xc66a4000}, {0xc66a6000}, + {0xc66a8000}, {0xc66aa000}, {0xc66ac000}, {0xc66ae000}, + {0xc66b0000}, {0xc66b2000}, {0xc66b4000}, {0xc66b6000}, + {0xc66b8000}, {0xc66ba000}, {0xc66bc000}, {0xc66be000}, + {0xc66c0000}, {0xc66c2000}, {0xc66c4000}, {0xc66c6000}, + {0xc66c8000}, {0xc66ca000}, {0xc66cc000}, {0xc66ce000}, + {0xc66d0000}, {0xc66d2000}, {0xc66d4000}, {0xc66d6000}, + {0xc66d8000}, {0xc66da000}, {0xc66dc000}, {0xc66de000}, + {0xc66e0000}, {0xc66e2000}, {0xc66e4000}, {0xc66e6000}, + {0xc66e8000}, {0xc66ea000}, {0xc66ec000}, {0xc66ee000}, + {0xc66f0000}, {0xc66f2000}, {0xc66f4000}, {0xc66f6000}, + {0xc66f8000}, {0xc66fa000}, {0xc66fc000}, {0xc66fe000}, + {0xc6700000}, {0xc6702000}, {0xc6704000}, {0xc6706000}, + {0xc6708000}, {0xc670a000}, {0xc670c000}, {0xc670e000}, + {0xc6710000}, {0xc6712000}, {0xc6714000}, {0xc6716000}, + {0xc6718000}, {0xc671a000}, {0xc671c000}, {0xc671e000}, + {0xc6720000}, {0xc6722000}, {0xc6724000}, {0xc6726000}, + {0xc6728000}, {0xc672a000}, {0xc672c000}, {0xc672e000}, + {0xc6730000}, {0xc6732000}, {0xc6734000}, {0xc6736000}, + {0xc6738000}, {0xc673a000}, {0xc673c000}, {0xc673e000}, + {0xc6740000}, {0xc6742000}, {0xc6744000}, {0xc6746000}, + {0xc6748000}, {0xc674a000}, {0xc674c000}, {0xc674e000}, + {0xc6750000}, {0xc6752000}, {0xc6754000}, {0xc6756000}, + {0xc6758000}, {0xc675a000}, {0xc675c000}, {0xc675e000}, + {0xc6760000}, {0xc6762000}, {0xc6764000}, {0xc6766000}, + {0xc6768000}, {0xc676a000}, {0xc676c000}, {0xc676e000}, + {0xc6770000}, {0xc6772000}, {0xc6774000}, {0xc6776000}, + {0xc6778000}, {0xc677a000}, {0xc677c000}, {0xc677e000}, + {0xc6780000}, {0xc6782000}, {0xc6784000}, {0xc6786000}, + {0xc6788000}, {0xc678a000}, {0xc678c000}, {0xc678e000}, + {0xc6790000}, {0xc6792000}, {0xc6794000}, {0xc6796000}, + {0xc6798000}, {0xc679a000}, {0xc679c000}, {0xc679e000}, + {0xc67a0000}, {0xc67a2000}, {0xc67a4000}, {0xc67a6000}, + {0xc67a8000}, {0xc67aa000}, {0xc67ac000}, {0xc67ae000}, + {0xc67b0000}, {0xc67b2000}, {0xc67b4000}, {0xc67b6000}, + {0xc67b8000}, {0xc67ba000}, {0xc67bc000}, {0xc67be000}, + {0xc67c0000}, {0xc67c2000}, {0xc67c4000}, {0xc67c6000}, + {0xc67c8000}, {0xc67ca000}, {0xc67cc000}, {0xc67ce000}, + {0xc67d0000}, {0xc67d2000}, {0xc67d4000}, {0xc67d6000}, + {0xc67d8000}, {0xc67da000}, {0xc67dc000}, {0xc67de000}, + {0xc67e0000}, {0xc67e2000}, {0xc67e4000}, {0xc67e6000}, + {0xc67e8000}, {0xc67ea000}, {0xc67ec000}, {0xc67ee000}, + {0xc67f0000}, {0xc67f2000}, {0xc67f4000}, {0xc67f6000}, + {0xc67f8000}, {0xc67fa000}, {0xc67fc000}, {0xc67fe000}, + {0xc6800000}, {0xc6802000}, {0xc6804000}, {0xc6806000}, + {0xc6808000}, {0xc680a000}, {0xc680c000}, {0xc680e000}, + {0xc6810000}, {0xc6812000}, {0xc6814000}, {0xc6816000}, + {0xc6818000}, {0xc681a000}, {0xc681c000}, {0xc681e000}, + {0xc6820000}, {0xc6822000}, {0xc6824000}, {0xc6826000}, + {0xc6828000}, {0xc682a000}, {0xc682c000}, {0xc682e000}, + {0xc6830000}, {0xc6832000}, {0xc6834000}, {0xc6836000}, + {0xc6838000}, {0xc683a000}, {0xc683c000}, {0xc683e000}, + {0xc6840000}, {0xc6842000}, {0xc6844000}, {0xc6846000}, + {0xc6848000}, {0xc684a000}, {0xc684c000}, {0xc684e000}, + {0xc6850000}, {0xc6852000}, {0xc6854000}, {0xc6856000}, + {0xc6858000}, {0xc685a000}, {0xc685c000}, {0xc685e000}, + {0xc6860000}, {0xc6862000}, {0xc6864000}, {0xc6866000}, + {0xc6868000}, {0xc686a000}, {0xc686c000}, {0xc686e000}, + {0xc6870000}, {0xc6872000}, {0xc6874000}, {0xc6876000}, + {0xc6878000}, {0xc687a000}, {0xc687c000}, {0xc687e000}, + {0xc6880000}, {0xc6882000}, {0xc6884000}, {0xc6886000}, + {0xc6888000}, {0xc688a000}, {0xc688c000}, {0xc688e000}, + {0xc6890000}, {0xc6892000}, {0xc6894000}, {0xc6896000}, + {0xc6898000}, {0xc689a000}, {0xc689c000}, {0xc689e000}, + {0xc68a0000}, {0xc68a2000}, {0xc68a4000}, {0xc68a6000}, + {0xc68a8000}, {0xc68aa000}, {0xc68ac000}, {0xc68ae000}, + {0xc68b0000}, {0xc68b2000}, {0xc68b4000}, {0xc68b6000}, + {0xc68b8000}, {0xc68ba000}, {0xc68bc000}, {0xc68be000}, + {0xc68c0000}, {0xc68c2000}, {0xc68c4000}, {0xc68c6000}, + {0xc68c8000}, {0xc68ca000}, {0xc68cc000}, {0xc68ce000}, + {0xc68d0000}, {0xc68d2000}, {0xc68d4000}, {0xc68d6000}, + {0xc68d8000}, {0xc68da000}, {0xc68dc000}, {0xc68de000}, + {0xc68e0000}, {0xc68e2000}, {0xc68e4000}, {0xc68e6000}, + {0xc68e8000}, {0xc68ea000}, {0xc68ec000}, {0xc68ee000}, + {0xc68f0000}, {0xc68f2000}, {0xc68f4000}, {0xc68f6000}, + {0xc68f8000}, {0xc68fa000}, {0xc68fc000}, {0xc68fe000}, + {0xc6900000}, {0xc6902000}, {0xc6904000}, {0xc6906000}, + {0xc6908000}, {0xc690a000}, {0xc690c000}, {0xc690e000}, + {0xc6910000}, {0xc6912000}, {0xc6914000}, {0xc6916000}, + {0xc6918000}, {0xc691a000}, {0xc691c000}, {0xc691e000}, + {0xc6920000}, {0xc6922000}, {0xc6924000}, {0xc6926000}, + {0xc6928000}, {0xc692a000}, {0xc692c000}, {0xc692e000}, + {0xc6930000}, {0xc6932000}, {0xc6934000}, {0xc6936000}, + {0xc6938000}, {0xc693a000}, {0xc693c000}, {0xc693e000}, + {0xc6940000}, {0xc6942000}, {0xc6944000}, {0xc6946000}, + {0xc6948000}, {0xc694a000}, {0xc694c000}, {0xc694e000}, + {0xc6950000}, {0xc6952000}, {0xc6954000}, {0xc6956000}, + {0xc6958000}, {0xc695a000}, {0xc695c000}, {0xc695e000}, + {0xc6960000}, {0xc6962000}, {0xc6964000}, {0xc6966000}, + {0xc6968000}, {0xc696a000}, {0xc696c000}, {0xc696e000}, + {0xc6970000}, {0xc6972000}, {0xc6974000}, {0xc6976000}, + {0xc6978000}, {0xc697a000}, {0xc697c000}, {0xc697e000}, + {0xc6980000}, {0xc6982000}, {0xc6984000}, {0xc6986000}, + {0xc6988000}, {0xc698a000}, {0xc698c000}, {0xc698e000}, + {0xc6990000}, {0xc6992000}, {0xc6994000}, {0xc6996000}, + {0xc6998000}, {0xc699a000}, {0xc699c000}, {0xc699e000}, + {0xc69a0000}, {0xc69a2000}, {0xc69a4000}, {0xc69a6000}, + {0xc69a8000}, {0xc69aa000}, {0xc69ac000}, {0xc69ae000}, + {0xc69b0000}, {0xc69b2000}, {0xc69b4000}, {0xc69b6000}, + {0xc69b8000}, {0xc69ba000}, {0xc69bc000}, {0xc69be000}, + {0xc69c0000}, {0xc69c2000}, {0xc69c4000}, {0xc69c6000}, + {0xc69c8000}, {0xc69ca000}, {0xc69cc000}, {0xc69ce000}, + {0xc69d0000}, {0xc69d2000}, {0xc69d4000}, {0xc69d6000}, + {0xc69d8000}, {0xc69da000}, {0xc69dc000}, {0xc69de000}, + {0xc69e0000}, {0xc69e2000}, {0xc69e4000}, {0xc69e6000}, + {0xc69e8000}, {0xc69ea000}, {0xc69ec000}, {0xc69ee000}, + {0xc69f0000}, {0xc69f2000}, {0xc69f4000}, {0xc69f6000}, + {0xc69f8000}, {0xc69fa000}, {0xc69fc000}, {0xc69fe000}, + {0xc6a00000}, {0xc6a02000}, {0xc6a04000}, {0xc6a06000}, + {0xc6a08000}, {0xc6a0a000}, {0xc6a0c000}, {0xc6a0e000}, + {0xc6a10000}, {0xc6a12000}, {0xc6a14000}, {0xc6a16000}, + {0xc6a18000}, {0xc6a1a000}, {0xc6a1c000}, {0xc6a1e000}, + {0xc6a20000}, {0xc6a22000}, {0xc6a24000}, {0xc6a26000}, + {0xc6a28000}, {0xc6a2a000}, {0xc6a2c000}, {0xc6a2e000}, + {0xc6a30000}, {0xc6a32000}, {0xc6a34000}, {0xc6a36000}, + {0xc6a38000}, {0xc6a3a000}, {0xc6a3c000}, {0xc6a3e000}, + {0xc6a40000}, {0xc6a42000}, {0xc6a44000}, {0xc6a46000}, + {0xc6a48000}, {0xc6a4a000}, {0xc6a4c000}, {0xc6a4e000}, + {0xc6a50000}, {0xc6a52000}, {0xc6a54000}, {0xc6a56000}, + {0xc6a58000}, {0xc6a5a000}, {0xc6a5c000}, {0xc6a5e000}, + {0xc6a60000}, {0xc6a62000}, {0xc6a64000}, {0xc6a66000}, + {0xc6a68000}, {0xc6a6a000}, {0xc6a6c000}, {0xc6a6e000}, + {0xc6a70000}, {0xc6a72000}, {0xc6a74000}, {0xc6a76000}, + {0xc6a78000}, {0xc6a7a000}, {0xc6a7c000}, {0xc6a7e000}, + {0xc6a80000}, {0xc6a82000}, {0xc6a84000}, {0xc6a86000}, + {0xc6a88000}, {0xc6a8a000}, {0xc6a8c000}, {0xc6a8e000}, + {0xc6a90000}, {0xc6a92000}, {0xc6a94000}, {0xc6a96000}, + {0xc6a98000}, {0xc6a9a000}, {0xc6a9c000}, {0xc6a9e000}, + {0xc6aa0000}, {0xc6aa2000}, {0xc6aa4000}, {0xc6aa6000}, + {0xc6aa8000}, {0xc6aaa000}, {0xc6aac000}, {0xc6aae000}, + {0xc6ab0000}, {0xc6ab2000}, {0xc6ab4000}, {0xc6ab6000}, + {0xc6ab8000}, {0xc6aba000}, {0xc6abc000}, {0xc6abe000}, + {0xc6ac0000}, {0xc6ac2000}, {0xc6ac4000}, {0xc6ac6000}, + {0xc6ac8000}, {0xc6aca000}, {0xc6acc000}, {0xc6ace000}, + {0xc6ad0000}, {0xc6ad2000}, {0xc6ad4000}, {0xc6ad6000}, + {0xc6ad8000}, {0xc6ada000}, {0xc6adc000}, {0xc6ade000}, + {0xc6ae0000}, {0xc6ae2000}, {0xc6ae4000}, {0xc6ae6000}, + {0xc6ae8000}, {0xc6aea000}, {0xc6aec000}, {0xc6aee000}, + {0xc6af0000}, {0xc6af2000}, {0xc6af4000}, {0xc6af6000}, + {0xc6af8000}, {0xc6afa000}, {0xc6afc000}, {0xc6afe000}, + {0xc6b00000}, {0xc6b02000}, {0xc6b04000}, {0xc6b06000}, + {0xc6b08000}, {0xc6b0a000}, {0xc6b0c000}, {0xc6b0e000}, + {0xc6b10000}, {0xc6b12000}, {0xc6b14000}, {0xc6b16000}, + {0xc6b18000}, {0xc6b1a000}, {0xc6b1c000}, {0xc6b1e000}, + {0xc6b20000}, {0xc6b22000}, {0xc6b24000}, {0xc6b26000}, + {0xc6b28000}, {0xc6b2a000}, {0xc6b2c000}, {0xc6b2e000}, + {0xc6b30000}, {0xc6b32000}, {0xc6b34000}, {0xc6b36000}, + {0xc6b38000}, {0xc6b3a000}, {0xc6b3c000}, {0xc6b3e000}, + {0xc6b40000}, {0xc6b42000}, {0xc6b44000}, {0xc6b46000}, + {0xc6b48000}, {0xc6b4a000}, {0xc6b4c000}, {0xc6b4e000}, + {0xc6b50000}, {0xc6b52000}, {0xc6b54000}, {0xc6b56000}, + {0xc6b58000}, {0xc6b5a000}, {0xc6b5c000}, {0xc6b5e000}, + {0xc6b60000}, {0xc6b62000}, {0xc6b64000}, {0xc6b66000}, + {0xc6b68000}, {0xc6b6a000}, {0xc6b6c000}, {0xc6b6e000}, + {0xc6b70000}, {0xc6b72000}, {0xc6b74000}, {0xc6b76000}, + {0xc6b78000}, {0xc6b7a000}, {0xc6b7c000}, {0xc6b7e000}, + {0xc6b80000}, {0xc6b82000}, {0xc6b84000}, {0xc6b86000}, + {0xc6b88000}, {0xc6b8a000}, {0xc6b8c000}, {0xc6b8e000}, + {0xc6b90000}, {0xc6b92000}, {0xc6b94000}, {0xc6b96000}, + {0xc6b98000}, {0xc6b9a000}, {0xc6b9c000}, {0xc6b9e000}, + {0xc6ba0000}, {0xc6ba2000}, {0xc6ba4000}, {0xc6ba6000}, + {0xc6ba8000}, {0xc6baa000}, {0xc6bac000}, {0xc6bae000}, + {0xc6bb0000}, {0xc6bb2000}, {0xc6bb4000}, {0xc6bb6000}, + {0xc6bb8000}, {0xc6bba000}, {0xc6bbc000}, {0xc6bbe000}, + {0xc6bc0000}, {0xc6bc2000}, {0xc6bc4000}, {0xc6bc6000}, + {0xc6bc8000}, {0xc6bca000}, {0xc6bcc000}, {0xc6bce000}, + {0xc6bd0000}, {0xc6bd2000}, {0xc6bd4000}, {0xc6bd6000}, + {0xc6bd8000}, {0xc6bda000}, {0xc6bdc000}, {0xc6bde000}, + {0xc6be0000}, {0xc6be2000}, {0xc6be4000}, {0xc6be6000}, + {0xc6be8000}, {0xc6bea000}, {0xc6bec000}, {0xc6bee000}, + {0xc6bf0000}, {0xc6bf2000}, {0xc6bf4000}, {0xc6bf6000}, + {0xc6bf8000}, {0xc6bfa000}, {0xc6bfc000}, {0xc6bfe000}, + {0xc6c00000}, {0xc6c02000}, {0xc6c04000}, {0xc6c06000}, + {0xc6c08000}, {0xc6c0a000}, {0xc6c0c000}, {0xc6c0e000}, + {0xc6c10000}, {0xc6c12000}, {0xc6c14000}, {0xc6c16000}, + {0xc6c18000}, {0xc6c1a000}, {0xc6c1c000}, {0xc6c1e000}, + {0xc6c20000}, {0xc6c22000}, {0xc6c24000}, {0xc6c26000}, + {0xc6c28000}, {0xc6c2a000}, {0xc6c2c000}, {0xc6c2e000}, + {0xc6c30000}, {0xc6c32000}, {0xc6c34000}, {0xc6c36000}, + {0xc6c38000}, {0xc6c3a000}, {0xc6c3c000}, {0xc6c3e000}, + {0xc6c40000}, {0xc6c42000}, {0xc6c44000}, {0xc6c46000}, + {0xc6c48000}, {0xc6c4a000}, {0xc6c4c000}, {0xc6c4e000}, + {0xc6c50000}, {0xc6c52000}, {0xc6c54000}, {0xc6c56000}, + {0xc6c58000}, {0xc6c5a000}, {0xc6c5c000}, {0xc6c5e000}, + {0xc6c60000}, {0xc6c62000}, {0xc6c64000}, {0xc6c66000}, + {0xc6c68000}, {0xc6c6a000}, {0xc6c6c000}, {0xc6c6e000}, + {0xc6c70000}, {0xc6c72000}, {0xc6c74000}, {0xc6c76000}, + {0xc6c78000}, {0xc6c7a000}, {0xc6c7c000}, {0xc6c7e000}, + {0xc6c80000}, {0xc6c82000}, {0xc6c84000}, {0xc6c86000}, + {0xc6c88000}, {0xc6c8a000}, {0xc6c8c000}, {0xc6c8e000}, + {0xc6c90000}, {0xc6c92000}, {0xc6c94000}, {0xc6c96000}, + {0xc6c98000}, {0xc6c9a000}, {0xc6c9c000}, {0xc6c9e000}, + {0xc6ca0000}, {0xc6ca2000}, {0xc6ca4000}, {0xc6ca6000}, + {0xc6ca8000}, {0xc6caa000}, {0xc6cac000}, {0xc6cae000}, + {0xc6cb0000}, {0xc6cb2000}, {0xc6cb4000}, {0xc6cb6000}, + {0xc6cb8000}, {0xc6cba000}, {0xc6cbc000}, {0xc6cbe000}, + {0xc6cc0000}, {0xc6cc2000}, {0xc6cc4000}, {0xc6cc6000}, + {0xc6cc8000}, {0xc6cca000}, {0xc6ccc000}, {0xc6cce000}, + {0xc6cd0000}, {0xc6cd2000}, {0xc6cd4000}, {0xc6cd6000}, + {0xc6cd8000}, {0xc6cda000}, {0xc6cdc000}, {0xc6cde000}, + {0xc6ce0000}, {0xc6ce2000}, {0xc6ce4000}, {0xc6ce6000}, + {0xc6ce8000}, {0xc6cea000}, {0xc6cec000}, {0xc6cee000}, + {0xc6cf0000}, {0xc6cf2000}, {0xc6cf4000}, {0xc6cf6000}, + {0xc6cf8000}, {0xc6cfa000}, {0xc6cfc000}, {0xc6cfe000}, + {0xc6d00000}, {0xc6d02000}, {0xc6d04000}, {0xc6d06000}, + {0xc6d08000}, {0xc6d0a000}, {0xc6d0c000}, {0xc6d0e000}, + {0xc6d10000}, {0xc6d12000}, {0xc6d14000}, {0xc6d16000}, + {0xc6d18000}, {0xc6d1a000}, {0xc6d1c000}, {0xc6d1e000}, + {0xc6d20000}, {0xc6d22000}, {0xc6d24000}, {0xc6d26000}, + {0xc6d28000}, {0xc6d2a000}, {0xc6d2c000}, {0xc6d2e000}, + {0xc6d30000}, {0xc6d32000}, {0xc6d34000}, {0xc6d36000}, + {0xc6d38000}, {0xc6d3a000}, {0xc6d3c000}, {0xc6d3e000}, + {0xc6d40000}, {0xc6d42000}, {0xc6d44000}, {0xc6d46000}, + {0xc6d48000}, {0xc6d4a000}, {0xc6d4c000}, {0xc6d4e000}, + {0xc6d50000}, {0xc6d52000}, {0xc6d54000}, {0xc6d56000}, + {0xc6d58000}, {0xc6d5a000}, {0xc6d5c000}, {0xc6d5e000}, + {0xc6d60000}, {0xc6d62000}, {0xc6d64000}, {0xc6d66000}, + {0xc6d68000}, {0xc6d6a000}, {0xc6d6c000}, {0xc6d6e000}, + {0xc6d70000}, {0xc6d72000}, {0xc6d74000}, {0xc6d76000}, + {0xc6d78000}, {0xc6d7a000}, {0xc6d7c000}, {0xc6d7e000}, + {0xc6d80000}, {0xc6d82000}, {0xc6d84000}, {0xc6d86000}, + {0xc6d88000}, {0xc6d8a000}, {0xc6d8c000}, {0xc6d8e000}, + {0xc6d90000}, {0xc6d92000}, {0xc6d94000}, {0xc6d96000}, + {0xc6d98000}, {0xc6d9a000}, {0xc6d9c000}, {0xc6d9e000}, + {0xc6da0000}, {0xc6da2000}, {0xc6da4000}, {0xc6da6000}, + {0xc6da8000}, {0xc6daa000}, {0xc6dac000}, {0xc6dae000}, + {0xc6db0000}, {0xc6db2000}, {0xc6db4000}, {0xc6db6000}, + {0xc6db8000}, {0xc6dba000}, {0xc6dbc000}, {0xc6dbe000}, + {0xc6dc0000}, {0xc6dc2000}, {0xc6dc4000}, {0xc6dc6000}, + {0xc6dc8000}, {0xc6dca000}, {0xc6dcc000}, {0xc6dce000}, + {0xc6dd0000}, {0xc6dd2000}, {0xc6dd4000}, {0xc6dd6000}, + {0xc6dd8000}, {0xc6dda000}, {0xc6ddc000}, {0xc6dde000}, + {0xc6de0000}, {0xc6de2000}, {0xc6de4000}, {0xc6de6000}, + {0xc6de8000}, {0xc6dea000}, {0xc6dec000}, {0xc6dee000}, + {0xc6df0000}, {0xc6df2000}, {0xc6df4000}, {0xc6df6000}, + {0xc6df8000}, {0xc6dfa000}, {0xc6dfc000}, {0xc6dfe000}, + {0xc6e00000}, {0xc6e02000}, {0xc6e04000}, {0xc6e06000}, + {0xc6e08000}, {0xc6e0a000}, {0xc6e0c000}, {0xc6e0e000}, + {0xc6e10000}, {0xc6e12000}, {0xc6e14000}, {0xc6e16000}, + {0xc6e18000}, {0xc6e1a000}, {0xc6e1c000}, {0xc6e1e000}, + {0xc6e20000}, {0xc6e22000}, {0xc6e24000}, {0xc6e26000}, + {0xc6e28000}, {0xc6e2a000}, {0xc6e2c000}, {0xc6e2e000}, + {0xc6e30000}, {0xc6e32000}, {0xc6e34000}, {0xc6e36000}, + {0xc6e38000}, {0xc6e3a000}, {0xc6e3c000}, {0xc6e3e000}, + {0xc6e40000}, {0xc6e42000}, {0xc6e44000}, {0xc6e46000}, + {0xc6e48000}, {0xc6e4a000}, {0xc6e4c000}, {0xc6e4e000}, + {0xc6e50000}, {0xc6e52000}, {0xc6e54000}, {0xc6e56000}, + {0xc6e58000}, {0xc6e5a000}, {0xc6e5c000}, {0xc6e5e000}, + {0xc6e60000}, {0xc6e62000}, {0xc6e64000}, {0xc6e66000}, + {0xc6e68000}, {0xc6e6a000}, {0xc6e6c000}, {0xc6e6e000}, + {0xc6e70000}, {0xc6e72000}, {0xc6e74000}, {0xc6e76000}, + {0xc6e78000}, {0xc6e7a000}, {0xc6e7c000}, {0xc6e7e000}, + {0xc6e80000}, {0xc6e82000}, {0xc6e84000}, {0xc6e86000}, + {0xc6e88000}, {0xc6e8a000}, {0xc6e8c000}, {0xc6e8e000}, + {0xc6e90000}, {0xc6e92000}, {0xc6e94000}, {0xc6e96000}, + {0xc6e98000}, {0xc6e9a000}, {0xc6e9c000}, {0xc6e9e000}, + {0xc6ea0000}, {0xc6ea2000}, {0xc6ea4000}, {0xc6ea6000}, + {0xc6ea8000}, {0xc6eaa000}, {0xc6eac000}, {0xc6eae000}, + {0xc6eb0000}, {0xc6eb2000}, {0xc6eb4000}, {0xc6eb6000}, + {0xc6eb8000}, {0xc6eba000}, {0xc6ebc000}, {0xc6ebe000}, + {0xc6ec0000}, {0xc6ec2000}, {0xc6ec4000}, {0xc6ec6000}, + {0xc6ec8000}, {0xc6eca000}, {0xc6ecc000}, {0xc6ece000}, + {0xc6ed0000}, {0xc6ed2000}, {0xc6ed4000}, {0xc6ed6000}, + {0xc6ed8000}, {0xc6eda000}, {0xc6edc000}, {0xc6ede000}, + {0xc6ee0000}, {0xc6ee2000}, {0xc6ee4000}, {0xc6ee6000}, + {0xc6ee8000}, {0xc6eea000}, {0xc6eec000}, {0xc6eee000}, + {0xc6ef0000}, {0xc6ef2000}, {0xc6ef4000}, {0xc6ef6000}, + {0xc6ef8000}, {0xc6efa000}, {0xc6efc000}, {0xc6efe000}, + {0xc6f00000}, {0xc6f02000}, {0xc6f04000}, {0xc6f06000}, + {0xc6f08000}, {0xc6f0a000}, {0xc6f0c000}, {0xc6f0e000}, + {0xc6f10000}, {0xc6f12000}, {0xc6f14000}, {0xc6f16000}, + {0xc6f18000}, {0xc6f1a000}, {0xc6f1c000}, {0xc6f1e000}, + {0xc6f20000}, {0xc6f22000}, {0xc6f24000}, {0xc6f26000}, + {0xc6f28000}, {0xc6f2a000}, {0xc6f2c000}, {0xc6f2e000}, + {0xc6f30000}, {0xc6f32000}, {0xc6f34000}, {0xc6f36000}, + {0xc6f38000}, {0xc6f3a000}, {0xc6f3c000}, {0xc6f3e000}, + {0xc6f40000}, {0xc6f42000}, {0xc6f44000}, {0xc6f46000}, + {0xc6f48000}, {0xc6f4a000}, {0xc6f4c000}, {0xc6f4e000}, + {0xc6f50000}, {0xc6f52000}, {0xc6f54000}, {0xc6f56000}, + {0xc6f58000}, {0xc6f5a000}, {0xc6f5c000}, {0xc6f5e000}, + {0xc6f60000}, {0xc6f62000}, {0xc6f64000}, {0xc6f66000}, + {0xc6f68000}, {0xc6f6a000}, {0xc6f6c000}, {0xc6f6e000}, + {0xc6f70000}, {0xc6f72000}, {0xc6f74000}, {0xc6f76000}, + {0xc6f78000}, {0xc6f7a000}, {0xc6f7c000}, {0xc6f7e000}, + {0xc6f80000}, {0xc6f82000}, {0xc6f84000}, {0xc6f86000}, + {0xc6f88000}, {0xc6f8a000}, {0xc6f8c000}, {0xc6f8e000}, + {0xc6f90000}, {0xc6f92000}, {0xc6f94000}, {0xc6f96000}, + {0xc6f98000}, {0xc6f9a000}, {0xc6f9c000}, {0xc6f9e000}, + {0xc6fa0000}, {0xc6fa2000}, {0xc6fa4000}, {0xc6fa6000}, + {0xc6fa8000}, {0xc6faa000}, {0xc6fac000}, {0xc6fae000}, + {0xc6fb0000}, {0xc6fb2000}, {0xc6fb4000}, {0xc6fb6000}, + {0xc6fb8000}, {0xc6fba000}, {0xc6fbc000}, {0xc6fbe000}, + {0xc6fc0000}, {0xc6fc2000}, {0xc6fc4000}, {0xc6fc6000}, + {0xc6fc8000}, {0xc6fca000}, {0xc6fcc000}, {0xc6fce000}, + {0xc6fd0000}, {0xc6fd2000}, {0xc6fd4000}, {0xc6fd6000}, + {0xc6fd8000}, {0xc6fda000}, {0xc6fdc000}, {0xc6fde000}, + {0xc6fe0000}, {0xc6fe2000}, {0xc6fe4000}, {0xc6fe6000}, + {0xc6fe8000}, {0xc6fea000}, {0xc6fec000}, {0xc6fee000}, + {0xc6ff0000}, {0xc6ff2000}, {0xc6ff4000}, {0xc6ff6000}, + {0xc6ff8000}, {0xc6ffa000}, {0xc6ffc000}, {0xc6ffe000}, + {0xc7000000}, {0xc7002000}, {0xc7004000}, {0xc7006000}, + {0xc7008000}, {0xc700a000}, {0xc700c000}, {0xc700e000}, + {0xc7010000}, {0xc7012000}, {0xc7014000}, {0xc7016000}, + {0xc7018000}, {0xc701a000}, {0xc701c000}, {0xc701e000}, + {0xc7020000}, {0xc7022000}, {0xc7024000}, {0xc7026000}, + {0xc7028000}, {0xc702a000}, {0xc702c000}, {0xc702e000}, + {0xc7030000}, {0xc7032000}, {0xc7034000}, {0xc7036000}, + {0xc7038000}, {0xc703a000}, {0xc703c000}, {0xc703e000}, + {0xc7040000}, {0xc7042000}, {0xc7044000}, {0xc7046000}, + {0xc7048000}, {0xc704a000}, {0xc704c000}, {0xc704e000}, + {0xc7050000}, {0xc7052000}, {0xc7054000}, {0xc7056000}, + {0xc7058000}, {0xc705a000}, {0xc705c000}, {0xc705e000}, + {0xc7060000}, {0xc7062000}, {0xc7064000}, {0xc7066000}, + {0xc7068000}, {0xc706a000}, {0xc706c000}, {0xc706e000}, + {0xc7070000}, {0xc7072000}, {0xc7074000}, {0xc7076000}, + {0xc7078000}, {0xc707a000}, {0xc707c000}, {0xc707e000}, + {0xc7080000}, {0xc7082000}, {0xc7084000}, {0xc7086000}, + {0xc7088000}, {0xc708a000}, {0xc708c000}, {0xc708e000}, + {0xc7090000}, {0xc7092000}, {0xc7094000}, {0xc7096000}, + {0xc7098000}, {0xc709a000}, {0xc709c000}, {0xc709e000}, + {0xc70a0000}, {0xc70a2000}, {0xc70a4000}, {0xc70a6000}, + {0xc70a8000}, {0xc70aa000}, {0xc70ac000}, {0xc70ae000}, + {0xc70b0000}, {0xc70b2000}, {0xc70b4000}, {0xc70b6000}, + {0xc70b8000}, {0xc70ba000}, {0xc70bc000}, {0xc70be000}, + {0xc70c0000}, {0xc70c2000}, {0xc70c4000}, {0xc70c6000}, + {0xc70c8000}, {0xc70ca000}, {0xc70cc000}, {0xc70ce000}, + {0xc70d0000}, {0xc70d2000}, {0xc70d4000}, {0xc70d6000}, + {0xc70d8000}, {0xc70da000}, {0xc70dc000}, {0xc70de000}, + {0xc70e0000}, {0xc70e2000}, {0xc70e4000}, {0xc70e6000}, + {0xc70e8000}, {0xc70ea000}, {0xc70ec000}, {0xc70ee000}, + {0xc70f0000}, {0xc70f2000}, {0xc70f4000}, {0xc70f6000}, + {0xc70f8000}, {0xc70fa000}, {0xc70fc000}, {0xc70fe000}, + {0xc7100000}, {0xc7102000}, {0xc7104000}, {0xc7106000}, + {0xc7108000}, {0xc710a000}, {0xc710c000}, {0xc710e000}, + {0xc7110000}, {0xc7112000}, {0xc7114000}, {0xc7116000}, + {0xc7118000}, {0xc711a000}, {0xc711c000}, {0xc711e000}, + {0xc7120000}, {0xc7122000}, {0xc7124000}, {0xc7126000}, + {0xc7128000}, {0xc712a000}, {0xc712c000}, {0xc712e000}, + {0xc7130000}, {0xc7132000}, {0xc7134000}, {0xc7136000}, + {0xc7138000}, {0xc713a000}, {0xc713c000}, {0xc713e000}, + {0xc7140000}, {0xc7142000}, {0xc7144000}, {0xc7146000}, + {0xc7148000}, {0xc714a000}, {0xc714c000}, {0xc714e000}, + {0xc7150000}, {0xc7152000}, {0xc7154000}, {0xc7156000}, + {0xc7158000}, {0xc715a000}, {0xc715c000}, {0xc715e000}, + {0xc7160000}, {0xc7162000}, {0xc7164000}, {0xc7166000}, + {0xc7168000}, {0xc716a000}, {0xc716c000}, {0xc716e000}, + {0xc7170000}, {0xc7172000}, {0xc7174000}, {0xc7176000}, + {0xc7178000}, {0xc717a000}, {0xc717c000}, {0xc717e000}, + {0xc7180000}, {0xc7182000}, {0xc7184000}, {0xc7186000}, + {0xc7188000}, {0xc718a000}, {0xc718c000}, {0xc718e000}, + {0xc7190000}, {0xc7192000}, {0xc7194000}, {0xc7196000}, + {0xc7198000}, {0xc719a000}, {0xc719c000}, {0xc719e000}, + {0xc71a0000}, {0xc71a2000}, {0xc71a4000}, {0xc71a6000}, + {0xc71a8000}, {0xc71aa000}, {0xc71ac000}, {0xc71ae000}, + {0xc71b0000}, {0xc71b2000}, {0xc71b4000}, {0xc71b6000}, + {0xc71b8000}, {0xc71ba000}, {0xc71bc000}, {0xc71be000}, + {0xc71c0000}, {0xc71c2000}, {0xc71c4000}, {0xc71c6000}, + {0xc71c8000}, {0xc71ca000}, {0xc71cc000}, {0xc71ce000}, + {0xc71d0000}, {0xc71d2000}, {0xc71d4000}, {0xc71d6000}, + {0xc71d8000}, {0xc71da000}, {0xc71dc000}, {0xc71de000}, + {0xc71e0000}, {0xc71e2000}, {0xc71e4000}, {0xc71e6000}, + {0xc71e8000}, {0xc71ea000}, {0xc71ec000}, {0xc71ee000}, + {0xc71f0000}, {0xc71f2000}, {0xc71f4000}, {0xc71f6000}, + {0xc71f8000}, {0xc71fa000}, {0xc71fc000}, {0xc71fe000}, + {0xc7200000}, {0xc7202000}, {0xc7204000}, {0xc7206000}, + {0xc7208000}, {0xc720a000}, {0xc720c000}, {0xc720e000}, + {0xc7210000}, {0xc7212000}, {0xc7214000}, {0xc7216000}, + {0xc7218000}, {0xc721a000}, {0xc721c000}, {0xc721e000}, + {0xc7220000}, {0xc7222000}, {0xc7224000}, {0xc7226000}, + {0xc7228000}, {0xc722a000}, {0xc722c000}, {0xc722e000}, + {0xc7230000}, {0xc7232000}, {0xc7234000}, {0xc7236000}, + {0xc7238000}, {0xc723a000}, {0xc723c000}, {0xc723e000}, + {0xc7240000}, {0xc7242000}, {0xc7244000}, {0xc7246000}, + {0xc7248000}, {0xc724a000}, {0xc724c000}, {0xc724e000}, + {0xc7250000}, {0xc7252000}, {0xc7254000}, {0xc7256000}, + {0xc7258000}, {0xc725a000}, {0xc725c000}, {0xc725e000}, + {0xc7260000}, {0xc7262000}, {0xc7264000}, {0xc7266000}, + {0xc7268000}, {0xc726a000}, {0xc726c000}, {0xc726e000}, + {0xc7270000}, {0xc7272000}, {0xc7274000}, {0xc7276000}, + {0xc7278000}, {0xc727a000}, {0xc727c000}, {0xc727e000}, + {0xc7280000}, {0xc7282000}, {0xc7284000}, {0xc7286000}, + {0xc7288000}, {0xc728a000}, {0xc728c000}, {0xc728e000}, + {0xc7290000}, {0xc7292000}, {0xc7294000}, {0xc7296000}, + {0xc7298000}, {0xc729a000}, {0xc729c000}, {0xc729e000}, + {0xc72a0000}, {0xc72a2000}, {0xc72a4000}, {0xc72a6000}, + {0xc72a8000}, {0xc72aa000}, {0xc72ac000}, {0xc72ae000}, + {0xc72b0000}, {0xc72b2000}, {0xc72b4000}, {0xc72b6000}, + {0xc72b8000}, {0xc72ba000}, {0xc72bc000}, {0xc72be000}, + {0xc72c0000}, {0xc72c2000}, {0xc72c4000}, {0xc72c6000}, + {0xc72c8000}, {0xc72ca000}, {0xc72cc000}, {0xc72ce000}, + {0xc72d0000}, {0xc72d2000}, {0xc72d4000}, {0xc72d6000}, + {0xc72d8000}, {0xc72da000}, {0xc72dc000}, {0xc72de000}, + {0xc72e0000}, {0xc72e2000}, {0xc72e4000}, {0xc72e6000}, + {0xc72e8000}, {0xc72ea000}, {0xc72ec000}, {0xc72ee000}, + {0xc72f0000}, {0xc72f2000}, {0xc72f4000}, {0xc72f6000}, + {0xc72f8000}, {0xc72fa000}, {0xc72fc000}, {0xc72fe000}, + {0xc7300000}, {0xc7302000}, {0xc7304000}, {0xc7306000}, + {0xc7308000}, {0xc730a000}, {0xc730c000}, {0xc730e000}, + {0xc7310000}, {0xc7312000}, {0xc7314000}, {0xc7316000}, + {0xc7318000}, {0xc731a000}, {0xc731c000}, {0xc731e000}, + {0xc7320000}, {0xc7322000}, {0xc7324000}, {0xc7326000}, + {0xc7328000}, {0xc732a000}, {0xc732c000}, {0xc732e000}, + {0xc7330000}, {0xc7332000}, {0xc7334000}, {0xc7336000}, + {0xc7338000}, {0xc733a000}, {0xc733c000}, {0xc733e000}, + {0xc7340000}, {0xc7342000}, {0xc7344000}, {0xc7346000}, + {0xc7348000}, {0xc734a000}, {0xc734c000}, {0xc734e000}, + {0xc7350000}, {0xc7352000}, {0xc7354000}, {0xc7356000}, + {0xc7358000}, {0xc735a000}, {0xc735c000}, {0xc735e000}, + {0xc7360000}, {0xc7362000}, {0xc7364000}, {0xc7366000}, + {0xc7368000}, {0xc736a000}, {0xc736c000}, {0xc736e000}, + {0xc7370000}, {0xc7372000}, {0xc7374000}, {0xc7376000}, + {0xc7378000}, {0xc737a000}, {0xc737c000}, {0xc737e000}, + {0xc7380000}, {0xc7382000}, {0xc7384000}, {0xc7386000}, + {0xc7388000}, {0xc738a000}, {0xc738c000}, {0xc738e000}, + {0xc7390000}, {0xc7392000}, {0xc7394000}, {0xc7396000}, + {0xc7398000}, {0xc739a000}, {0xc739c000}, {0xc739e000}, + {0xc73a0000}, {0xc73a2000}, {0xc73a4000}, {0xc73a6000}, + {0xc73a8000}, {0xc73aa000}, {0xc73ac000}, {0xc73ae000}, + {0xc73b0000}, {0xc73b2000}, {0xc73b4000}, {0xc73b6000}, + {0xc73b8000}, {0xc73ba000}, {0xc73bc000}, {0xc73be000}, + {0xc73c0000}, {0xc73c2000}, {0xc73c4000}, {0xc73c6000}, + {0xc73c8000}, {0xc73ca000}, {0xc73cc000}, {0xc73ce000}, + {0xc73d0000}, {0xc73d2000}, {0xc73d4000}, {0xc73d6000}, + {0xc73d8000}, {0xc73da000}, {0xc73dc000}, {0xc73de000}, + {0xc73e0000}, {0xc73e2000}, {0xc73e4000}, {0xc73e6000}, + {0xc73e8000}, {0xc73ea000}, {0xc73ec000}, {0xc73ee000}, + {0xc73f0000}, {0xc73f2000}, {0xc73f4000}, {0xc73f6000}, + {0xc73f8000}, {0xc73fa000}, {0xc73fc000}, {0xc73fe000}, + {0xc7400000}, {0xc7402000}, {0xc7404000}, {0xc7406000}, + {0xc7408000}, {0xc740a000}, {0xc740c000}, {0xc740e000}, + {0xc7410000}, {0xc7412000}, {0xc7414000}, {0xc7416000}, + {0xc7418000}, {0xc741a000}, {0xc741c000}, {0xc741e000}, + {0xc7420000}, {0xc7422000}, {0xc7424000}, {0xc7426000}, + {0xc7428000}, {0xc742a000}, {0xc742c000}, {0xc742e000}, + {0xc7430000}, {0xc7432000}, {0xc7434000}, {0xc7436000}, + {0xc7438000}, {0xc743a000}, {0xc743c000}, {0xc743e000}, + {0xc7440000}, {0xc7442000}, {0xc7444000}, {0xc7446000}, + {0xc7448000}, {0xc744a000}, {0xc744c000}, {0xc744e000}, + {0xc7450000}, {0xc7452000}, {0xc7454000}, {0xc7456000}, + {0xc7458000}, {0xc745a000}, {0xc745c000}, {0xc745e000}, + {0xc7460000}, {0xc7462000}, {0xc7464000}, {0xc7466000}, + {0xc7468000}, {0xc746a000}, {0xc746c000}, {0xc746e000}, + {0xc7470000}, {0xc7472000}, {0xc7474000}, {0xc7476000}, + {0xc7478000}, {0xc747a000}, {0xc747c000}, {0xc747e000}, + {0xc7480000}, {0xc7482000}, {0xc7484000}, {0xc7486000}, + {0xc7488000}, {0xc748a000}, {0xc748c000}, {0xc748e000}, + {0xc7490000}, {0xc7492000}, {0xc7494000}, {0xc7496000}, + {0xc7498000}, {0xc749a000}, {0xc749c000}, {0xc749e000}, + {0xc74a0000}, {0xc74a2000}, {0xc74a4000}, {0xc74a6000}, + {0xc74a8000}, {0xc74aa000}, {0xc74ac000}, {0xc74ae000}, + {0xc74b0000}, {0xc74b2000}, {0xc74b4000}, {0xc74b6000}, + {0xc74b8000}, {0xc74ba000}, {0xc74bc000}, {0xc74be000}, + {0xc74c0000}, {0xc74c2000}, {0xc74c4000}, {0xc74c6000}, + {0xc74c8000}, {0xc74ca000}, {0xc74cc000}, {0xc74ce000}, + {0xc74d0000}, {0xc74d2000}, {0xc74d4000}, {0xc74d6000}, + {0xc74d8000}, {0xc74da000}, {0xc74dc000}, {0xc74de000}, + {0xc74e0000}, {0xc74e2000}, {0xc74e4000}, {0xc74e6000}, + {0xc74e8000}, {0xc74ea000}, {0xc74ec000}, {0xc74ee000}, + {0xc74f0000}, {0xc74f2000}, {0xc74f4000}, {0xc74f6000}, + {0xc74f8000}, {0xc74fa000}, {0xc74fc000}, {0xc74fe000}, + {0xc7500000}, {0xc7502000}, {0xc7504000}, {0xc7506000}, + {0xc7508000}, {0xc750a000}, {0xc750c000}, {0xc750e000}, + {0xc7510000}, {0xc7512000}, {0xc7514000}, {0xc7516000}, + {0xc7518000}, {0xc751a000}, {0xc751c000}, {0xc751e000}, + {0xc7520000}, {0xc7522000}, {0xc7524000}, {0xc7526000}, + {0xc7528000}, {0xc752a000}, {0xc752c000}, {0xc752e000}, + {0xc7530000}, {0xc7532000}, {0xc7534000}, {0xc7536000}, + {0xc7538000}, {0xc753a000}, {0xc753c000}, {0xc753e000}, + {0xc7540000}, {0xc7542000}, {0xc7544000}, {0xc7546000}, + {0xc7548000}, {0xc754a000}, {0xc754c000}, {0xc754e000}, + {0xc7550000}, {0xc7552000}, {0xc7554000}, {0xc7556000}, + {0xc7558000}, {0xc755a000}, {0xc755c000}, {0xc755e000}, + {0xc7560000}, {0xc7562000}, {0xc7564000}, {0xc7566000}, + {0xc7568000}, {0xc756a000}, {0xc756c000}, {0xc756e000}, + {0xc7570000}, {0xc7572000}, {0xc7574000}, {0xc7576000}, + {0xc7578000}, {0xc757a000}, {0xc757c000}, {0xc757e000}, + {0xc7580000}, {0xc7582000}, {0xc7584000}, {0xc7586000}, + {0xc7588000}, {0xc758a000}, {0xc758c000}, {0xc758e000}, + {0xc7590000}, {0xc7592000}, {0xc7594000}, {0xc7596000}, + {0xc7598000}, {0xc759a000}, {0xc759c000}, {0xc759e000}, + {0xc75a0000}, {0xc75a2000}, {0xc75a4000}, {0xc75a6000}, + {0xc75a8000}, {0xc75aa000}, {0xc75ac000}, {0xc75ae000}, + {0xc75b0000}, {0xc75b2000}, {0xc75b4000}, {0xc75b6000}, + {0xc75b8000}, {0xc75ba000}, {0xc75bc000}, {0xc75be000}, + {0xc75c0000}, {0xc75c2000}, {0xc75c4000}, {0xc75c6000}, + {0xc75c8000}, {0xc75ca000}, {0xc75cc000}, {0xc75ce000}, + {0xc75d0000}, {0xc75d2000}, {0xc75d4000}, {0xc75d6000}, + {0xc75d8000}, {0xc75da000}, {0xc75dc000}, {0xc75de000}, + {0xc75e0000}, {0xc75e2000}, {0xc75e4000}, {0xc75e6000}, + {0xc75e8000}, {0xc75ea000}, {0xc75ec000}, {0xc75ee000}, + {0xc75f0000}, {0xc75f2000}, {0xc75f4000}, {0xc75f6000}, + {0xc75f8000}, {0xc75fa000}, {0xc75fc000}, {0xc75fe000}, + {0xc7600000}, {0xc7602000}, {0xc7604000}, {0xc7606000}, + {0xc7608000}, {0xc760a000}, {0xc760c000}, {0xc760e000}, + {0xc7610000}, {0xc7612000}, {0xc7614000}, {0xc7616000}, + {0xc7618000}, {0xc761a000}, {0xc761c000}, {0xc761e000}, + {0xc7620000}, {0xc7622000}, {0xc7624000}, {0xc7626000}, + {0xc7628000}, {0xc762a000}, {0xc762c000}, {0xc762e000}, + {0xc7630000}, {0xc7632000}, {0xc7634000}, {0xc7636000}, + {0xc7638000}, {0xc763a000}, {0xc763c000}, {0xc763e000}, + {0xc7640000}, {0xc7642000}, {0xc7644000}, {0xc7646000}, + {0xc7648000}, {0xc764a000}, {0xc764c000}, {0xc764e000}, + {0xc7650000}, {0xc7652000}, {0xc7654000}, {0xc7656000}, + {0xc7658000}, {0xc765a000}, {0xc765c000}, {0xc765e000}, + {0xc7660000}, {0xc7662000}, {0xc7664000}, {0xc7666000}, + {0xc7668000}, {0xc766a000}, {0xc766c000}, {0xc766e000}, + {0xc7670000}, {0xc7672000}, {0xc7674000}, {0xc7676000}, + {0xc7678000}, {0xc767a000}, {0xc767c000}, {0xc767e000}, + {0xc7680000}, {0xc7682000}, {0xc7684000}, {0xc7686000}, + {0xc7688000}, {0xc768a000}, {0xc768c000}, {0xc768e000}, + {0xc7690000}, {0xc7692000}, {0xc7694000}, {0xc7696000}, + {0xc7698000}, {0xc769a000}, {0xc769c000}, {0xc769e000}, + {0xc76a0000}, {0xc76a2000}, {0xc76a4000}, {0xc76a6000}, + {0xc76a8000}, {0xc76aa000}, {0xc76ac000}, {0xc76ae000}, + {0xc76b0000}, {0xc76b2000}, {0xc76b4000}, {0xc76b6000}, + {0xc76b8000}, {0xc76ba000}, {0xc76bc000}, {0xc76be000}, + {0xc76c0000}, {0xc76c2000}, {0xc76c4000}, {0xc76c6000}, + {0xc76c8000}, {0xc76ca000}, {0xc76cc000}, {0xc76ce000}, + {0xc76d0000}, {0xc76d2000}, {0xc76d4000}, {0xc76d6000}, + {0xc76d8000}, {0xc76da000}, {0xc76dc000}, {0xc76de000}, + {0xc76e0000}, {0xc76e2000}, {0xc76e4000}, {0xc76e6000}, + {0xc76e8000}, {0xc76ea000}, {0xc76ec000}, {0xc76ee000}, + {0xc76f0000}, {0xc76f2000}, {0xc76f4000}, {0xc76f6000}, + {0xc76f8000}, {0xc76fa000}, {0xc76fc000}, {0xc76fe000}, + {0xc7700000}, {0xc7702000}, {0xc7704000}, {0xc7706000}, + {0xc7708000}, {0xc770a000}, {0xc770c000}, {0xc770e000}, + {0xc7710000}, {0xc7712000}, {0xc7714000}, {0xc7716000}, + {0xc7718000}, {0xc771a000}, {0xc771c000}, {0xc771e000}, + {0xc7720000}, {0xc7722000}, {0xc7724000}, {0xc7726000}, + {0xc7728000}, {0xc772a000}, {0xc772c000}, {0xc772e000}, + {0xc7730000}, {0xc7732000}, {0xc7734000}, {0xc7736000}, + {0xc7738000}, {0xc773a000}, {0xc773c000}, {0xc773e000}, + {0xc7740000}, {0xc7742000}, {0xc7744000}, {0xc7746000}, + {0xc7748000}, {0xc774a000}, {0xc774c000}, {0xc774e000}, + {0xc7750000}, {0xc7752000}, {0xc7754000}, {0xc7756000}, + {0xc7758000}, {0xc775a000}, {0xc775c000}, {0xc775e000}, + {0xc7760000}, {0xc7762000}, {0xc7764000}, {0xc7766000}, + {0xc7768000}, {0xc776a000}, {0xc776c000}, {0xc776e000}, + {0xc7770000}, {0xc7772000}, {0xc7774000}, {0xc7776000}, + {0xc7778000}, {0xc777a000}, {0xc777c000}, {0xc777e000}, + {0xc7780000}, {0xc7782000}, {0xc7784000}, {0xc7786000}, + {0xc7788000}, {0xc778a000}, {0xc778c000}, {0xc778e000}, + {0xc7790000}, {0xc7792000}, {0xc7794000}, {0xc7796000}, + {0xc7798000}, {0xc779a000}, {0xc779c000}, {0xc779e000}, + {0xc77a0000}, {0xc77a2000}, {0xc77a4000}, {0xc77a6000}, + {0xc77a8000}, {0xc77aa000}, {0xc77ac000}, {0xc77ae000}, + {0xc77b0000}, {0xc77b2000}, {0xc77b4000}, {0xc77b6000}, + {0xc77b8000}, {0xc77ba000}, {0xc77bc000}, {0xc77be000}, + {0xc77c0000}, {0xc77c2000}, {0xc77c4000}, {0xc77c6000}, + {0xc77c8000}, {0xc77ca000}, {0xc77cc000}, {0xc77ce000}, + {0xc77d0000}, {0xc77d2000}, {0xc77d4000}, {0xc77d6000}, + {0xc77d8000}, {0xc77da000}, {0xc77dc000}, {0xc77de000}, + {0xc77e0000}, {0xc77e2000}, {0xc77e4000}, {0xc77e6000}, + {0xc77e8000}, {0xc77ea000}, {0xc77ec000}, {0xc77ee000}, + {0xc77f0000}, {0xc77f2000}, {0xc77f4000}, {0xc77f6000}, + {0xc77f8000}, {0xc77fa000}, {0xc77fc000}, {0xc77fe000}, + {0xff800000}, {0xff802000}, {0xff804000}, {0xff806000}, + {0xff808000}, {0xff80a000}, {0xff80c000}, {0xff80e000}, + {0xff810000}, {0xff812000}, {0xff814000}, {0xff816000}, + {0xff818000}, {0xff81a000}, {0xff81c000}, {0xff81e000}, + {0xff820000}, {0xff822000}, {0xff824000}, {0xff826000}, + {0xff828000}, {0xff82a000}, {0xff82c000}, {0xff82e000}, + {0xff830000}, {0xff832000}, {0xff834000}, {0xff836000}, + {0xff838000}, {0xff83a000}, {0xff83c000}, {0xff83e000}, + {0xff840000}, {0xff842000}, {0xff844000}, {0xff846000}, + {0xff848000}, {0xff84a000}, {0xff84c000}, {0xff84e000}, + {0xff850000}, {0xff852000}, {0xff854000}, {0xff856000}, + {0xff858000}, {0xff85a000}, {0xff85c000}, {0xff85e000}, + {0xff860000}, {0xff862000}, {0xff864000}, {0xff866000}, + {0xff868000}, {0xff86a000}, {0xff86c000}, {0xff86e000}, + {0xff870000}, {0xff872000}, {0xff874000}, {0xff876000}, + {0xff878000}, {0xff87a000}, {0xff87c000}, {0xff87e000}, + {0xff880000}, {0xff882000}, {0xff884000}, {0xff886000}, + {0xff888000}, {0xff88a000}, {0xff88c000}, {0xff88e000}, + {0xff890000}, {0xff892000}, {0xff894000}, {0xff896000}, + {0xff898000}, {0xff89a000}, {0xff89c000}, {0xff89e000}, + {0xff8a0000}, {0xff8a2000}, {0xff8a4000}, {0xff8a6000}, + {0xff8a8000}, {0xff8aa000}, {0xff8ac000}, {0xff8ae000}, + {0xff8b0000}, {0xff8b2000}, {0xff8b4000}, {0xff8b6000}, + {0xff8b8000}, {0xff8ba000}, {0xff8bc000}, {0xff8be000}, + {0xff8c0000}, {0xff8c2000}, {0xff8c4000}, {0xff8c6000}, + {0xff8c8000}, {0xff8ca000}, {0xff8cc000}, {0xff8ce000}, + {0xff8d0000}, {0xff8d2000}, {0xff8d4000}, {0xff8d6000}, + {0xff8d8000}, {0xff8da000}, {0xff8dc000}, {0xff8de000}, + {0xff8e0000}, {0xff8e2000}, {0xff8e4000}, {0xff8e6000}, + {0xff8e8000}, {0xff8ea000}, {0xff8ec000}, {0xff8ee000}, + {0xff8f0000}, {0xff8f2000}, {0xff8f4000}, {0xff8f6000}, + {0xff8f8000}, {0xff8fa000}, {0xff8fc000}, {0xff8fe000}, + {0xff900000}, {0xff902000}, {0xff904000}, {0xff906000}, + {0xff908000}, {0xff90a000}, {0xff90c000}, {0xff90e000}, + {0xff910000}, {0xff912000}, {0xff914000}, {0xff916000}, + {0xff918000}, {0xff91a000}, {0xff91c000}, {0xff91e000}, + {0xff920000}, {0xff922000}, {0xff924000}, {0xff926000}, + {0xff928000}, {0xff92a000}, {0xff92c000}, {0xff92e000}, + {0xff930000}, {0xff932000}, {0xff934000}, {0xff936000}, + {0xff938000}, {0xff93a000}, {0xff93c000}, {0xff93e000}, + {0xff940000}, {0xff942000}, {0xff944000}, {0xff946000}, + {0xff948000}, {0xff94a000}, {0xff94c000}, {0xff94e000}, + {0xff950000}, {0xff952000}, {0xff954000}, {0xff956000}, + {0xff958000}, {0xff95a000}, {0xff95c000}, {0xff95e000}, + {0xff960000}, {0xff962000}, {0xff964000}, {0xff966000}, + {0xff968000}, {0xff96a000}, {0xff96c000}, {0xff96e000}, + {0xff970000}, {0xff972000}, {0xff974000}, {0xff976000}, + {0xff978000}, {0xff97a000}, {0xff97c000}, {0xff97e000}, + {0xff980000}, {0xff982000}, {0xff984000}, {0xff986000}, + {0xff988000}, {0xff98a000}, {0xff98c000}, {0xff98e000}, + {0xff990000}, {0xff992000}, {0xff994000}, {0xff996000}, + {0xff998000}, {0xff99a000}, {0xff99c000}, {0xff99e000}, + {0xff9a0000}, {0xff9a2000}, {0xff9a4000}, {0xff9a6000}, + {0xff9a8000}, {0xff9aa000}, {0xff9ac000}, {0xff9ae000}, + {0xff9b0000}, {0xff9b2000}, {0xff9b4000}, {0xff9b6000}, + {0xff9b8000}, {0xff9ba000}, {0xff9bc000}, {0xff9be000}, + {0xff9c0000}, {0xff9c2000}, {0xff9c4000}, {0xff9c6000}, + {0xff9c8000}, {0xff9ca000}, {0xff9cc000}, {0xff9ce000}, + {0xff9d0000}, {0xff9d2000}, {0xff9d4000}, {0xff9d6000}, + {0xff9d8000}, {0xff9da000}, {0xff9dc000}, {0xff9de000}, + {0xff9e0000}, {0xff9e2000}, {0xff9e4000}, {0xff9e6000}, + {0xff9e8000}, {0xff9ea000}, {0xff9ec000}, {0xff9ee000}, + {0xff9f0000}, {0xff9f2000}, {0xff9f4000}, {0xff9f6000}, + {0xff9f8000}, {0xff9fa000}, {0xff9fc000}, {0xff9fe000}, + {0xffa00000}, {0xffa02000}, {0xffa04000}, {0xffa06000}, + {0xffa08000}, {0xffa0a000}, {0xffa0c000}, {0xffa0e000}, + {0xffa10000}, {0xffa12000}, {0xffa14000}, {0xffa16000}, + {0xffa18000}, {0xffa1a000}, {0xffa1c000}, {0xffa1e000}, + {0xffa20000}, {0xffa22000}, {0xffa24000}, {0xffa26000}, + {0xffa28000}, {0xffa2a000}, {0xffa2c000}, {0xffa2e000}, + {0xffa30000}, {0xffa32000}, {0xffa34000}, {0xffa36000}, + {0xffa38000}, {0xffa3a000}, {0xffa3c000}, {0xffa3e000}, + {0xffa40000}, {0xffa42000}, {0xffa44000}, {0xffa46000}, + {0xffa48000}, {0xffa4a000}, {0xffa4c000}, {0xffa4e000}, + {0xffa50000}, {0xffa52000}, {0xffa54000}, {0xffa56000}, + {0xffa58000}, {0xffa5a000}, {0xffa5c000}, {0xffa5e000}, + {0xffa60000}, {0xffa62000}, {0xffa64000}, {0xffa66000}, + {0xffa68000}, {0xffa6a000}, {0xffa6c000}, {0xffa6e000}, + {0xffa70000}, {0xffa72000}, {0xffa74000}, {0xffa76000}, + {0xffa78000}, {0xffa7a000}, {0xffa7c000}, {0xffa7e000}, + {0xffa80000}, {0xffa82000}, {0xffa84000}, {0xffa86000}, + {0xffa88000}, {0xffa8a000}, {0xffa8c000}, {0xffa8e000}, + {0xffa90000}, {0xffa92000}, {0xffa94000}, {0xffa96000}, + {0xffa98000}, {0xffa9a000}, {0xffa9c000}, {0xffa9e000}, + {0xffaa0000}, {0xffaa2000}, {0xffaa4000}, {0xffaa6000}, + {0xffaa8000}, {0xffaaa000}, {0xffaac000}, {0xffaae000}, + {0xffab0000}, {0xffab2000}, {0xffab4000}, {0xffab6000}, + {0xffab8000}, {0xffaba000}, {0xffabc000}, {0xffabe000}, + {0xffac0000}, {0xffac2000}, {0xffac4000}, {0xffac6000}, + {0xffac8000}, {0xffaca000}, {0xffacc000}, {0xfface000}, + {0xffad0000}, {0xffad2000}, {0xffad4000}, {0xffad6000}, + {0xffad8000}, {0xffada000}, {0xffadc000}, {0xffade000}, + {0xffae0000}, {0xffae2000}, {0xffae4000}, {0xffae6000}, + {0xffae8000}, {0xffaea000}, {0xffaec000}, {0xffaee000}, + {0xffaf0000}, {0xffaf2000}, {0xffaf4000}, {0xffaf6000}, + {0xffaf8000}, {0xffafa000}, {0xffafc000}, {0xffafe000}, + {0xffb00000}, {0xffb02000}, {0xffb04000}, {0xffb06000}, + {0xffb08000}, {0xffb0a000}, {0xffb0c000}, {0xffb0e000}, + {0xffb10000}, {0xffb12000}, {0xffb14000}, {0xffb16000}, + {0xffb18000}, {0xffb1a000}, {0xffb1c000}, {0xffb1e000}, + {0xffb20000}, {0xffb22000}, {0xffb24000}, {0xffb26000}, + {0xffb28000}, {0xffb2a000}, {0xffb2c000}, {0xffb2e000}, + {0xffb30000}, {0xffb32000}, {0xffb34000}, {0xffb36000}, + {0xffb38000}, {0xffb3a000}, {0xffb3c000}, {0xffb3e000}, + {0xffb40000}, {0xffb42000}, {0xffb44000}, {0xffb46000}, + {0xffb48000}, {0xffb4a000}, {0xffb4c000}, {0xffb4e000}, + {0xffb50000}, {0xffb52000}, {0xffb54000}, {0xffb56000}, + {0xffb58000}, {0xffb5a000}, {0xffb5c000}, {0xffb5e000}, + {0xffb60000}, {0xffb62000}, {0xffb64000}, {0xffb66000}, + {0xffb68000}, {0xffb6a000}, {0xffb6c000}, {0xffb6e000}, + {0xffb70000}, {0xffb72000}, {0xffb74000}, {0xffb76000}, + {0xffb78000}, {0xffb7a000}, {0xffb7c000}, {0xffb7e000}, + {0xffb80000}, {0xffb82000}, {0xffb84000}, {0xffb86000}, + {0xffb88000}, {0xffb8a000}, {0xffb8c000}, {0xffb8e000}, + {0xffb90000}, {0xffb92000}, {0xffb94000}, {0xffb96000}, + {0xffb98000}, {0xffb9a000}, {0xffb9c000}, {0xffb9e000}, + {0xffba0000}, {0xffba2000}, {0xffba4000}, {0xffba6000}, + {0xffba8000}, {0xffbaa000}, {0xffbac000}, {0xffbae000}, + {0xffbb0000}, {0xffbb2000}, {0xffbb4000}, {0xffbb6000}, + {0xffbb8000}, {0xffbba000}, {0xffbbc000}, {0xffbbe000}, + {0xffbc0000}, {0xffbc2000}, {0xffbc4000}, {0xffbc6000}, + {0xffbc8000}, {0xffbca000}, {0xffbcc000}, {0xffbce000}, + {0xffbd0000}, {0xffbd2000}, {0xffbd4000}, {0xffbd6000}, + {0xffbd8000}, {0xffbda000}, {0xffbdc000}, {0xffbde000}, + {0xffbe0000}, {0xffbe2000}, {0xffbe4000}, {0xffbe6000}, + {0xffbe8000}, {0xffbea000}, {0xffbec000}, {0xffbee000}, + {0xffbf0000}, {0xffbf2000}, {0xffbf4000}, {0xffbf6000}, + {0xffbf8000}, {0xffbfa000}, {0xffbfc000}, {0xffbfe000}, + {0xffc00000}, {0xffc02000}, {0xffc04000}, {0xffc06000}, + {0xffc08000}, {0xffc0a000}, {0xffc0c000}, {0xffc0e000}, + {0xffc10000}, {0xffc12000}, {0xffc14000}, {0xffc16000}, + {0xffc18000}, {0xffc1a000}, {0xffc1c000}, {0xffc1e000}, + {0xffc20000}, {0xffc22000}, {0xffc24000}, {0xffc26000}, + {0xffc28000}, {0xffc2a000}, {0xffc2c000}, {0xffc2e000}, + {0xffc30000}, {0xffc32000}, {0xffc34000}, {0xffc36000}, + {0xffc38000}, {0xffc3a000}, {0xffc3c000}, {0xffc3e000}, + {0xffc40000}, {0xffc42000}, {0xffc44000}, {0xffc46000}, + {0xffc48000}, {0xffc4a000}, {0xffc4c000}, {0xffc4e000}, + {0xffc50000}, {0xffc52000}, {0xffc54000}, {0xffc56000}, + {0xffc58000}, {0xffc5a000}, {0xffc5c000}, {0xffc5e000}, + {0xffc60000}, {0xffc62000}, {0xffc64000}, {0xffc66000}, + {0xffc68000}, {0xffc6a000}, {0xffc6c000}, {0xffc6e000}, + {0xffc70000}, {0xffc72000}, {0xffc74000}, {0xffc76000}, + {0xffc78000}, {0xffc7a000}, {0xffc7c000}, {0xffc7e000}, + {0xffc80000}, {0xffc82000}, {0xffc84000}, {0xffc86000}, + {0xffc88000}, {0xffc8a000}, {0xffc8c000}, {0xffc8e000}, + {0xffc90000}, {0xffc92000}, {0xffc94000}, {0xffc96000}, + {0xffc98000}, {0xffc9a000}, {0xffc9c000}, {0xffc9e000}, + {0xffca0000}, {0xffca2000}, {0xffca4000}, {0xffca6000}, + {0xffca8000}, {0xffcaa000}, {0xffcac000}, {0xffcae000}, + {0xffcb0000}, {0xffcb2000}, {0xffcb4000}, {0xffcb6000}, + {0xffcb8000}, {0xffcba000}, {0xffcbc000}, {0xffcbe000}, + {0xffcc0000}, {0xffcc2000}, {0xffcc4000}, {0xffcc6000}, + {0xffcc8000}, {0xffcca000}, {0xffccc000}, {0xffcce000}, + {0xffcd0000}, {0xffcd2000}, {0xffcd4000}, {0xffcd6000}, + {0xffcd8000}, {0xffcda000}, {0xffcdc000}, {0xffcde000}, + {0xffce0000}, {0xffce2000}, {0xffce4000}, {0xffce6000}, + {0xffce8000}, {0xffcea000}, {0xffcec000}, {0xffcee000}, + {0xffcf0000}, {0xffcf2000}, {0xffcf4000}, {0xffcf6000}, + {0xffcf8000}, {0xffcfa000}, {0xffcfc000}, {0xffcfe000}, + {0xffd00000}, {0xffd02000}, {0xffd04000}, {0xffd06000}, + {0xffd08000}, {0xffd0a000}, {0xffd0c000}, {0xffd0e000}, + {0xffd10000}, {0xffd12000}, {0xffd14000}, {0xffd16000}, + {0xffd18000}, {0xffd1a000}, {0xffd1c000}, {0xffd1e000}, + {0xffd20000}, {0xffd22000}, {0xffd24000}, {0xffd26000}, + {0xffd28000}, {0xffd2a000}, {0xffd2c000}, {0xffd2e000}, + {0xffd30000}, {0xffd32000}, {0xffd34000}, {0xffd36000}, + {0xffd38000}, {0xffd3a000}, {0xffd3c000}, {0xffd3e000}, + {0xffd40000}, {0xffd42000}, {0xffd44000}, {0xffd46000}, + {0xffd48000}, {0xffd4a000}, {0xffd4c000}, {0xffd4e000}, + {0xffd50000}, {0xffd52000}, {0xffd54000}, {0xffd56000}, + {0xffd58000}, {0xffd5a000}, {0xffd5c000}, {0xffd5e000}, + {0xffd60000}, {0xffd62000}, {0xffd64000}, {0xffd66000}, + {0xffd68000}, {0xffd6a000}, {0xffd6c000}, {0xffd6e000}, + {0xffd70000}, {0xffd72000}, {0xffd74000}, {0xffd76000}, + {0xffd78000}, {0xffd7a000}, {0xffd7c000}, {0xffd7e000}, + {0xffd80000}, {0xffd82000}, {0xffd84000}, {0xffd86000}, + {0xffd88000}, {0xffd8a000}, {0xffd8c000}, {0xffd8e000}, + {0xffd90000}, {0xffd92000}, {0xffd94000}, {0xffd96000}, + {0xffd98000}, {0xffd9a000}, {0xffd9c000}, {0xffd9e000}, + {0xffda0000}, {0xffda2000}, {0xffda4000}, {0xffda6000}, + {0xffda8000}, {0xffdaa000}, {0xffdac000}, {0xffdae000}, + {0xffdb0000}, {0xffdb2000}, {0xffdb4000}, {0xffdb6000}, + {0xffdb8000}, {0xffdba000}, {0xffdbc000}, {0xffdbe000}, + {0xffdc0000}, {0xffdc2000}, {0xffdc4000}, {0xffdc6000}, + {0xffdc8000}, {0xffdca000}, {0xffdcc000}, {0xffdce000}, + {0xffdd0000}, {0xffdd2000}, {0xffdd4000}, {0xffdd6000}, + {0xffdd8000}, {0xffdda000}, {0xffddc000}, {0xffdde000}, + {0xffde0000}, {0xffde2000}, {0xffde4000}, {0xffde6000}, + {0xffde8000}, {0xffdea000}, {0xffdec000}, {0xffdee000}, + {0xffdf0000}, {0xffdf2000}, {0xffdf4000}, {0xffdf6000}, + {0xffdf8000}, {0xffdfa000}, {0xffdfc000}, {0xffdfe000}, + {0xffe00000}, {0xffe02000}, {0xffe04000}, {0xffe06000}, + {0xffe08000}, {0xffe0a000}, {0xffe0c000}, {0xffe0e000}, + {0xffe10000}, {0xffe12000}, {0xffe14000}, {0xffe16000}, + {0xffe18000}, {0xffe1a000}, {0xffe1c000}, {0xffe1e000}, + {0xffe20000}, {0xffe22000}, {0xffe24000}, {0xffe26000}, + {0xffe28000}, {0xffe2a000}, {0xffe2c000}, {0xffe2e000}, + {0xffe30000}, {0xffe32000}, {0xffe34000}, {0xffe36000}, + {0xffe38000}, {0xffe3a000}, {0xffe3c000}, {0xffe3e000}, + {0xffe40000}, {0xffe42000}, {0xffe44000}, {0xffe46000}, + {0xffe48000}, {0xffe4a000}, {0xffe4c000}, {0xffe4e000}, + {0xffe50000}, {0xffe52000}, {0xffe54000}, {0xffe56000}, + {0xffe58000}, {0xffe5a000}, {0xffe5c000}, {0xffe5e000}, + {0xffe60000}, {0xffe62000}, {0xffe64000}, {0xffe66000}, + {0xffe68000}, {0xffe6a000}, {0xffe6c000}, {0xffe6e000}, + {0xffe70000}, {0xffe72000}, {0xffe74000}, {0xffe76000}, + {0xffe78000}, {0xffe7a000}, {0xffe7c000}, {0xffe7e000}, + {0xffe80000}, {0xffe82000}, {0xffe84000}, {0xffe86000}, + {0xffe88000}, {0xffe8a000}, {0xffe8c000}, {0xffe8e000}, + {0xffe90000}, {0xffe92000}, {0xffe94000}, {0xffe96000}, + {0xffe98000}, {0xffe9a000}, {0xffe9c000}, {0xffe9e000}, + {0xffea0000}, {0xffea2000}, {0xffea4000}, {0xffea6000}, + {0xffea8000}, {0xffeaa000}, {0xffeac000}, {0xffeae000}, + {0xffeb0000}, {0xffeb2000}, {0xffeb4000}, {0xffeb6000}, + {0xffeb8000}, {0xffeba000}, {0xffebc000}, {0xffebe000}, + {0xffec0000}, {0xffec2000}, {0xffec4000}, {0xffec6000}, + {0xffec8000}, {0xffeca000}, {0xffecc000}, {0xffece000}, + {0xffed0000}, {0xffed2000}, {0xffed4000}, {0xffed6000}, + {0xffed8000}, {0xffeda000}, {0xffedc000}, {0xffede000}, + {0xffee0000}, {0xffee2000}, {0xffee4000}, {0xffee6000}, + {0xffee8000}, {0xffeea000}, {0xffeec000}, {0xffeee000}, + {0xffef0000}, {0xffef2000}, {0xffef4000}, {0xffef6000}, + {0xffef8000}, {0xffefa000}, {0xffefc000}, {0xffefe000}, + {0xfff00000}, {0xfff02000}, {0xfff04000}, {0xfff06000}, + {0xfff08000}, {0xfff0a000}, {0xfff0c000}, {0xfff0e000}, + {0xfff10000}, {0xfff12000}, {0xfff14000}, {0xfff16000}, + {0xfff18000}, {0xfff1a000}, {0xfff1c000}, {0xfff1e000}, + {0xfff20000}, {0xfff22000}, {0xfff24000}, {0xfff26000}, + {0xfff28000}, {0xfff2a000}, {0xfff2c000}, {0xfff2e000}, + {0xfff30000}, {0xfff32000}, {0xfff34000}, {0xfff36000}, + {0xfff38000}, {0xfff3a000}, {0xfff3c000}, {0xfff3e000}, + {0xfff40000}, {0xfff42000}, {0xfff44000}, {0xfff46000}, + {0xfff48000}, {0xfff4a000}, {0xfff4c000}, {0xfff4e000}, + {0xfff50000}, {0xfff52000}, {0xfff54000}, {0xfff56000}, + {0xfff58000}, {0xfff5a000}, {0xfff5c000}, {0xfff5e000}, + {0xfff60000}, {0xfff62000}, {0xfff64000}, {0xfff66000}, + {0xfff68000}, {0xfff6a000}, {0xfff6c000}, {0xfff6e000}, + {0xfff70000}, {0xfff72000}, {0xfff74000}, {0xfff76000}, + {0xfff78000}, {0xfff7a000}, {0xfff7c000}, {0xfff7e000}, + {0xfff80000}, {0xfff82000}, {0xfff84000}, {0xfff86000}, + {0xfff88000}, {0xfff8a000}, {0xfff8c000}, {0xfff8e000}, + {0xfff90000}, {0xfff92000}, {0xfff94000}, {0xfff96000}, + {0xfff98000}, {0xfff9a000}, {0xfff9c000}, {0xfff9e000}, + {0xfffa0000}, {0xfffa2000}, {0xfffa4000}, {0xfffa6000}, + {0xfffa8000}, {0xfffaa000}, {0xfffac000}, {0xfffae000}, + {0xfffb0000}, {0xfffb2000}, {0xfffb4000}, {0xfffb6000}, + {0xfffb8000}, {0xfffba000}, {0xfffbc000}, {0xfffbe000}, + {0xfffc0000}, {0xfffc2000}, {0xfffc4000}, {0xfffc6000}, + {0xfffc8000}, {0xfffca000}, {0xfffcc000}, {0xfffce000}, + {0xfffd0000}, {0xfffd2000}, {0xfffd4000}, {0xfffd6000}, + {0xfffd8000}, {0xfffda000}, {0xfffdc000}, {0xfffde000}, + {0xfffe0000}, {0xfffe2000}, {0xfffe4000}, {0xfffe6000}, + {0xfffe8000}, {0xfffea000}, {0xfffec000}, {0xfffee000}, + {0xffff0000}, {0xffff2000}, {0xffff4000}, {0xffff6000}, + {0xffff8000}, {0xffffa000}, {0xffffc000}, {0xffffe000}, +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/Iex.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/Iex.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/Iex.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/Iex.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEX_H +#define INCLUDED_IEX_H + + +//-------------------------------- +// +// Exception handling +// +//-------------------------------- + + +#include "IexMacros.h" +#include "IexBaseExc.h" +#include "IexMathExc.h" +#include "IexThrowErrnoExc.h" + +// Note that we do not include file IexErrnoExc.h here. That file +// defines over 150 classes and significantly slows down compilation. +// If you throw ErrnoExc exceptions using the throwErrnoExc() function, +// you don't need IexErrnoExc.h. You have to include IexErrnoExc.h +// only if you want to catch specific subclasses of ErrnoExc. + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,129 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//--------------------------------------------------------------------- +// +// Constructors and destructors for our exception base class. +// +//--------------------------------------------------------------------- + +#include "IexBaseExc.h" + +namespace Iex { +namespace { + + +StackTracer currentStackTracer = 0; + + +} // namespace + + +void +setStackTracer (StackTracer stackTracer) +{ + currentStackTracer = stackTracer; +} + + +StackTracer +stackTracer () +{ + return currentStackTracer; +} + + +BaseExc::BaseExc (const char* s) throw () : + std::string (s? s: ""), + _stackTrace (currentStackTracer? currentStackTracer(): "") +{ + // empty +} + + +BaseExc::BaseExc (const std::string &s) throw () : + std::string (s), + _stackTrace (currentStackTracer? currentStackTracer(): "") +{ + // empty +} + + +BaseExc::BaseExc (std::stringstream &s) throw () : + std::string (s.str()), + _stackTrace (currentStackTracer? currentStackTracer(): "") +{ + // empty +} + + +BaseExc::BaseExc (const BaseExc &be) throw () : + std::string (be), + _stackTrace (be._stackTrace) +{ + // empty +} + + +BaseExc::~BaseExc () throw () +{ + // empty +} + + +const char * +BaseExc::what () const throw () +{ + return c_str(); +} + + +BaseExc & +BaseExc::assign (std::stringstream &s) +{ + std::string::assign (s.str()); + return *this; +} + +BaseExc & +BaseExc::append (std::stringstream &s) +{ + std::string::append (s.str()); + return *this; +} + + +} // namespace Iex diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexBaseExc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,266 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEXBASEEXC_H +#define INCLUDED_IEXBASEEXC_H + + +//---------------------------------------------------------- +// +// A general exception base class, and a few +// useful exceptions derived from the base class. +// +//---------------------------------------------------------- + +#include +#include +#include + +namespace Iex { + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// Tell MS VC++ to suppress exception specification warnings +#pragma warning(disable:4290) +#endif + +//------------------------------- +// Our most basic exception class +//------------------------------- + +class BaseExc: public std::string, public std::exception +{ + public: + + //---------------------------- + // Constructors and destructor + //---------------------------- + + BaseExc (const char *s = 0) throw(); // std::string (s) + BaseExc (const std::string &s) throw(); // std::string (s) + BaseExc (std::stringstream &s) throw(); // std::string (s.str()) + + BaseExc (const BaseExc &be) throw(); + virtual ~BaseExc () throw (); + + //-------------------------------------------- + // what() method -- e.what() returns e.c_str() + //-------------------------------------------- + + virtual const char * what () const throw (); + + + //-------------------------------------------------- + // Convenient methods to change the exception's text + //-------------------------------------------------- + + BaseExc & assign (std::stringstream &s); // assign (s.str()) + BaseExc & operator = (std::stringstream &s); + + BaseExc & append (std::stringstream &s); // append (s.str()) + BaseExc & operator += (std::stringstream &s); + + + //-------------------------------------------------- + // These methods from the base class get obscured by + // the definitions above. + //-------------------------------------------------- + + BaseExc & assign (const char *s); + BaseExc & operator = (const char *s); + + BaseExc & append (const char *s); + BaseExc & operator += (const char *s); + + + //-------------------------------------------------- + // Stack trace for the point at which the exception + // was thrown. The stack trace will be an empty + // string unless a working stack-tracing routine + // has been installed (see below, setStackTracer()). + //-------------------------------------------------- + + const std::string & stackTrace () const; + + private: + + std::string _stackTrace; +}; + + +//----------------------------------------------------- +// A macro to save typing when declararing an exception +// class derived directly or indirectly from BaseExc: +//----------------------------------------------------- + +#define DEFINE_EXC(name, base) \ + class name: public base \ + { \ + public: \ + name (const char* text=0) throw(): base (text) {} \ + name (const std::string &text) throw(): base (text) {} \ + name (std::stringstream &text) throw(): base (text) {} \ + }; + + +//-------------------------------------------------------- +// Some exceptions which should be useful in most programs +//-------------------------------------------------------- + +DEFINE_EXC (ArgExc, BaseExc) // Invalid arguments to a function call + +DEFINE_EXC (LogicExc, BaseExc) // General error in a program's logic, + // for example, a function was called + // in a context where the call does + // not make sense. + +DEFINE_EXC (InputExc, BaseExc) // Invalid input data, e.g. from a file + +DEFINE_EXC (IoExc, BaseExc) // Input or output operation failed + +DEFINE_EXC (MathExc, BaseExc) // Arithmetic exception; more specific + // exceptions derived from this class + // are defined in ExcMath.h + +DEFINE_EXC (ErrnoExc, BaseExc) // Base class for exceptions corresponding + // to errno values (see errno.h); more + // specific exceptions derived from this + // class are defined in ExcErrno.h + +DEFINE_EXC (NoImplExc, BaseExc) // Missing method exception e.g. from a + // call to a method that is only partially + // or not at all implemented. A reminder + // to lazy software people to get back + // to work. + +DEFINE_EXC (NullExc, BaseExc) // A pointer is inappropriately null. + +DEFINE_EXC (TypeExc, BaseExc) // An object is an inappropriate type, + // i.e. a dynamnic_cast failed. + + +//---------------------------------------------------------------------- +// Stack-tracing support: +// +// setStackTracer(st) +// +// installs a stack-tracing routine, st, which will be called from +// class BaseExc's constructor every time an exception derived from +// BaseExc is thrown. The stack-tracing routine should return a +// string that contains a printable representation of the program's +// current call stack. This string will be stored in the BaseExc +// object; the string is accesible via the BaseExc::stackTrace() +// method. +// +// setStackTracer(0) +// +// removes the current stack tracing routine. When an exception +// derived from BaseExc is thrown, the stack trace string stored +// in the BaseExc object will be empty. +// +// stackTracer() +// +// returns a pointer to the current stack-tracing routine, or 0 +// if there is no current stack stack-tracing routine. +// +//---------------------------------------------------------------------- + +typedef std::string (* StackTracer) (); + +void setStackTracer (StackTracer stackTracer); +StackTracer stackTracer (); + + +//----------------- +// Inline functions +//----------------- + +inline BaseExc & +BaseExc::operator = (std::stringstream &s) +{ + return assign (s); +} + + +inline BaseExc & +BaseExc::operator += (std::stringstream &s) +{ + return append (s); +} + + +inline BaseExc & +BaseExc::assign (const char *s) +{ + std::string::assign(s); + return *this; +} + + +inline BaseExc & +BaseExc::operator = (const char *s) +{ + return assign(s); +} + + +inline BaseExc & +BaseExc::append (const char *s) +{ + std::string::append(s); + return *this; +} + + +inline BaseExc & +BaseExc::operator += (const char *s) +{ + return append(s); +} + + +inline const std::string & +BaseExc::stackTrace () const +{ + return _stackTrace; +} + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +#pragma warning(default:4290) +#endif + +} // namespace Iex + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexErrnoExc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexErrnoExc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexErrnoExc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexErrnoExc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,210 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEXERRNOEXC_H +#define INCLUDED_IEXERRNOEXC_H + +//---------------------------------------------------------------- +// +// Exceptions which correspond to "errno" error codes. +// +//---------------------------------------------------------------- + +#include "IexBaseExc.h" + +namespace Iex { + + +DEFINE_EXC (EpermExc, ErrnoExc) +DEFINE_EXC (EnoentExc, ErrnoExc) +DEFINE_EXC (EsrchExc, ErrnoExc) +DEFINE_EXC (EintrExc, ErrnoExc) +DEFINE_EXC (EioExc, ErrnoExc) +DEFINE_EXC (EnxioExc, ErrnoExc) +DEFINE_EXC (E2bigExc, ErrnoExc) +DEFINE_EXC (EnoexecExc, ErrnoExc) +DEFINE_EXC (EbadfExc, ErrnoExc) +DEFINE_EXC (EchildExc, ErrnoExc) +DEFINE_EXC (EagainExc, ErrnoExc) +DEFINE_EXC (EnomemExc, ErrnoExc) +DEFINE_EXC (EaccesExc, ErrnoExc) +DEFINE_EXC (EfaultExc, ErrnoExc) +DEFINE_EXC (EnotblkExc, ErrnoExc) +DEFINE_EXC (EbusyExc, ErrnoExc) +DEFINE_EXC (EexistExc, ErrnoExc) +DEFINE_EXC (ExdevExc, ErrnoExc) +DEFINE_EXC (EnodevExc, ErrnoExc) +DEFINE_EXC (EnotdirExc, ErrnoExc) +DEFINE_EXC (EisdirExc, ErrnoExc) +DEFINE_EXC (EinvalExc, ErrnoExc) +DEFINE_EXC (EnfileExc, ErrnoExc) +DEFINE_EXC (EmfileExc, ErrnoExc) +DEFINE_EXC (EnottyExc, ErrnoExc) +DEFINE_EXC (EtxtbsyExc, ErrnoExc) +DEFINE_EXC (EfbigExc, ErrnoExc) +DEFINE_EXC (EnospcExc, ErrnoExc) +DEFINE_EXC (EspipeExc, ErrnoExc) +DEFINE_EXC (ErofsExc, ErrnoExc) +DEFINE_EXC (EmlinkExc, ErrnoExc) +DEFINE_EXC (EpipeExc, ErrnoExc) +DEFINE_EXC (EdomExc, ErrnoExc) +DEFINE_EXC (ErangeExc, ErrnoExc) +DEFINE_EXC (EnomsgExc, ErrnoExc) +DEFINE_EXC (EidrmExc, ErrnoExc) +DEFINE_EXC (EchrngExc, ErrnoExc) +DEFINE_EXC (El2nsyncExc, ErrnoExc) +DEFINE_EXC (El3hltExc, ErrnoExc) +DEFINE_EXC (El3rstExc, ErrnoExc) +DEFINE_EXC (ElnrngExc, ErrnoExc) +DEFINE_EXC (EunatchExc, ErrnoExc) +DEFINE_EXC (EnocsiExc, ErrnoExc) +DEFINE_EXC (El2hltExc, ErrnoExc) +DEFINE_EXC (EdeadlkExc, ErrnoExc) +DEFINE_EXC (EnolckExc, ErrnoExc) +DEFINE_EXC (EbadeExc, ErrnoExc) +DEFINE_EXC (EbadrExc, ErrnoExc) +DEFINE_EXC (ExfullExc, ErrnoExc) +DEFINE_EXC (EnoanoExc, ErrnoExc) +DEFINE_EXC (EbadrqcExc, ErrnoExc) +DEFINE_EXC (EbadsltExc, ErrnoExc) +DEFINE_EXC (EdeadlockExc, ErrnoExc) +DEFINE_EXC (EbfontExc, ErrnoExc) +DEFINE_EXC (EnostrExc, ErrnoExc) +DEFINE_EXC (EnodataExc, ErrnoExc) +DEFINE_EXC (EtimeExc, ErrnoExc) +DEFINE_EXC (EnosrExc, ErrnoExc) +DEFINE_EXC (EnonetExc, ErrnoExc) +DEFINE_EXC (EnopkgExc, ErrnoExc) +DEFINE_EXC (EremoteExc, ErrnoExc) +DEFINE_EXC (EnolinkExc, ErrnoExc) +DEFINE_EXC (EadvExc, ErrnoExc) +DEFINE_EXC (EsrmntExc, ErrnoExc) +DEFINE_EXC (EcommExc, ErrnoExc) +DEFINE_EXC (EprotoExc, ErrnoExc) +DEFINE_EXC (EmultihopExc, ErrnoExc) +DEFINE_EXC (EbadmsgExc, ErrnoExc) +DEFINE_EXC (EnametoolongExc, ErrnoExc) +DEFINE_EXC (EoverflowExc, ErrnoExc) +DEFINE_EXC (EnotuniqExc, ErrnoExc) +DEFINE_EXC (EbadfdExc, ErrnoExc) +DEFINE_EXC (EremchgExc, ErrnoExc) +DEFINE_EXC (ElibaccExc, ErrnoExc) +DEFINE_EXC (ElibbadExc, ErrnoExc) +DEFINE_EXC (ElibscnExc, ErrnoExc) +DEFINE_EXC (ElibmaxExc, ErrnoExc) +DEFINE_EXC (ElibexecExc, ErrnoExc) +DEFINE_EXC (EilseqExc, ErrnoExc) +DEFINE_EXC (EnosysExc, ErrnoExc) +DEFINE_EXC (EloopExc, ErrnoExc) +DEFINE_EXC (ErestartExc, ErrnoExc) +DEFINE_EXC (EstrpipeExc, ErrnoExc) +DEFINE_EXC (EnotemptyExc, ErrnoExc) +DEFINE_EXC (EusersExc, ErrnoExc) +DEFINE_EXC (EnotsockExc, ErrnoExc) +DEFINE_EXC (EdestaddrreqExc, ErrnoExc) +DEFINE_EXC (EmsgsizeExc, ErrnoExc) +DEFINE_EXC (EprototypeExc, ErrnoExc) +DEFINE_EXC (EnoprotooptExc, ErrnoExc) +DEFINE_EXC (EprotonosupportExc, ErrnoExc) +DEFINE_EXC (EsocktnosupportExc, ErrnoExc) +DEFINE_EXC (EopnotsuppExc, ErrnoExc) +DEFINE_EXC (EpfnosupportExc, ErrnoExc) +DEFINE_EXC (EafnosupportExc, ErrnoExc) +DEFINE_EXC (EaddrinuseExc, ErrnoExc) +DEFINE_EXC (EaddrnotavailExc, ErrnoExc) +DEFINE_EXC (EnetdownExc, ErrnoExc) +DEFINE_EXC (EnetunreachExc, ErrnoExc) +DEFINE_EXC (EnetresetExc, ErrnoExc) +DEFINE_EXC (EconnabortedExc, ErrnoExc) +DEFINE_EXC (EconnresetExc, ErrnoExc) +DEFINE_EXC (EnobufsExc, ErrnoExc) +DEFINE_EXC (EisconnExc, ErrnoExc) +DEFINE_EXC (EnotconnExc, ErrnoExc) +DEFINE_EXC (EshutdownExc, ErrnoExc) +DEFINE_EXC (EtoomanyrefsExc, ErrnoExc) +DEFINE_EXC (EtimedoutExc, ErrnoExc) +DEFINE_EXC (EconnrefusedExc, ErrnoExc) +DEFINE_EXC (EhostdownExc, ErrnoExc) +DEFINE_EXC (EhostunreachExc, ErrnoExc) +DEFINE_EXC (EalreadyExc, ErrnoExc) +DEFINE_EXC (EinprogressExc, ErrnoExc) +DEFINE_EXC (EstaleExc, ErrnoExc) +DEFINE_EXC (EioresidExc, ErrnoExc) +DEFINE_EXC (EucleanExc, ErrnoExc) +DEFINE_EXC (EnotnamExc, ErrnoExc) +DEFINE_EXC (EnavailExc, ErrnoExc) +DEFINE_EXC (EisnamExc, ErrnoExc) +DEFINE_EXC (EremoteioExc, ErrnoExc) +DEFINE_EXC (EinitExc, ErrnoExc) +DEFINE_EXC (EremdevExc, ErrnoExc) +DEFINE_EXC (EcanceledExc, ErrnoExc) +DEFINE_EXC (EnolimfileExc, ErrnoExc) +DEFINE_EXC (EproclimExc, ErrnoExc) +DEFINE_EXC (EdisjointExc, ErrnoExc) +DEFINE_EXC (EnologinExc, ErrnoExc) +DEFINE_EXC (EloginlimExc, ErrnoExc) +DEFINE_EXC (EgrouploopExc, ErrnoExc) +DEFINE_EXC (EnoattachExc, ErrnoExc) +DEFINE_EXC (EnotsupExc, ErrnoExc) +DEFINE_EXC (EnoattrExc, ErrnoExc) +DEFINE_EXC (EdircorruptedExc, ErrnoExc) +DEFINE_EXC (EdquotExc, ErrnoExc) +DEFINE_EXC (EnfsremoteExc, ErrnoExc) +DEFINE_EXC (EcontrollerExc, ErrnoExc) +DEFINE_EXC (EnotcontrollerExc, ErrnoExc) +DEFINE_EXC (EenqueuedExc, ErrnoExc) +DEFINE_EXC (EnotenqueuedExc, ErrnoExc) +DEFINE_EXC (EjoinedExc, ErrnoExc) +DEFINE_EXC (EnotjoinedExc, ErrnoExc) +DEFINE_EXC (EnoprocExc, ErrnoExc) +DEFINE_EXC (EmustrunExc, ErrnoExc) +DEFINE_EXC (EnotstoppedExc, ErrnoExc) +DEFINE_EXC (EclockcpuExc, ErrnoExc) +DEFINE_EXC (EinvalstateExc, ErrnoExc) +DEFINE_EXC (EnoexistExc, ErrnoExc) +DEFINE_EXC (EendofminorExc, ErrnoExc) +DEFINE_EXC (EbufsizeExc, ErrnoExc) +DEFINE_EXC (EemptyExc, ErrnoExc) +DEFINE_EXC (EnointrgroupExc, ErrnoExc) +DEFINE_EXC (EinvalmodeExc, ErrnoExc) +DEFINE_EXC (EcantextentExc, ErrnoExc) +DEFINE_EXC (EinvaltimeExc, ErrnoExc) +DEFINE_EXC (EdestroyedExc, ErrnoExc) + + +} // namespace Iex + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMacros.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMacros.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMacros.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMacros.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,148 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEXMACROS_H +#define INCLUDED_IEXMACROS_H + +//-------------------------------------------------------------------- +// +// Macros which make throwing exceptions more convenient +// +//-------------------------------------------------------------------- + +#include + + +//---------------------------------------------------------------------------- +// A macro to throw exceptions whose text is assembled using stringstreams. +// +// Example: +// +// THROW (InputExc, "Syntax error in line " << line ", " << file << "."); +// +//---------------------------------------------------------------------------- + +#define THROW(type, text) \ + do \ + { \ + std::stringstream s; \ + s << text; \ + throw type (s); \ + } \ + while (0) + + +//---------------------------------------------------------------------------- +// Macros to add to or to replace the text of an exception. +// The new text is assembled using stringstreams. +// +// Examples: +// +// Append to end of an exception's text: +// +// catch (BaseExc &e) +// { +// APPEND_EXC (e, " Directory " << name << " does not exist."); +// throw; +// } +// +// Replace an exception's text: +// +// catch (BaseExc &e) +// { +// REPLACE_EXC (e, "Directory " << name << " does not exist. " << e); +// throw; +// } +//---------------------------------------------------------------------------- + +#define APPEND_EXC(exc, text) \ + do \ + { \ + std::stringstream s; \ + s << text; \ + exc.append (s); \ + } \ + while (0) + +#define REPLACE_EXC(exc, text) \ + do \ + { \ + std::stringstream s; \ + s << text; \ + exc.assign (s); \ + } \ + while (0) + + +//------------------------------------------------------------- +// A macro to throw ErrnoExc exceptions whose text is assembled +// using stringstreams: +// +// Example: +// +// THROW_ERRNO ("Cannot open file " << name << " (%T)."); +// +//------------------------------------------------------------- + +#define THROW_ERRNO(text) \ + do \ + { \ + std::stringstream s; \ + s << text; \ + ::Iex::throwErrnoExc (s.str()); \ + } \ + while (0) + + +//------------------------------------------------------------- +// A macro to throw exceptions if an assertion is false. +// +// Example: +// +// ASSERT (ptr != NULL, NullExc, "Null pointer" ); +// +//------------------------------------------------------------- + +#define ASSERT(assertion, type, text) \ + do \ + { \ + if ((assertion) == false) \ + THROW (type, text); \ + } \ + while (0) + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMathExc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMathExc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMathExc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexMathExc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEXMATHEXC_H +#define INCLUDED_IEXMATHEXC_H + +#include "IexBaseExc.h" + +namespace Iex { + +//--------------------------------------------------------- +// Exception classess which correspond to specific floating +// point exceptions. +//--------------------------------------------------------- + +DEFINE_EXC (OverflowExc, MathExc) // Overflow +DEFINE_EXC (UnderflowExc, MathExc) // Underflow +DEFINE_EXC (DivzeroExc, MathExc) // Division by zero +DEFINE_EXC (InexactExc, MathExc) // Inexact result +DEFINE_EXC (InvalidFpOpExc, MathExc) // Invalid operation + + +} // namespace Iex + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,859 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//---------------------------------------------------------------- +// +// Exceptions that correspond to "errno" error codes, +// and a function to make throwing those exceptions easy. +// +//---------------------------------------------------------------- + +#include "IexThrowErrnoExc.h" +#include "IexErrnoExc.h" +#include +#include + +namespace Iex { + + +void throwErrnoExc (const std::string &text, int errnum) +{ + const char *entext = strerror (errnum); + std::string tmp (text); + std::string::size_type pos; + + while (std::string::npos != (pos = tmp.find ("%T"))) + tmp.replace (pos, 2, entext, strlen (entext)); + + switch (errnum) + { + #if defined (EPERM) + case EPERM: + throw EpermExc (tmp); + #endif + + #if defined (ENOENT) + case ENOENT: + throw EnoentExc (tmp); + #endif + + #if defined (ESRCH) + case ESRCH: + throw EsrchExc (tmp); + #endif + + #if defined (EINTR) + case EINTR: + throw EintrExc (tmp); + #endif + + #if defined (EIO) + case EIO: + throw EioExc (tmp); + #endif + + #if defined (ENXIO) + case ENXIO: + throw EnxioExc (tmp); + #endif + + #if defined (E2BIG) + case E2BIG: + throw E2bigExc (tmp); + #endif + + #if defined (ENOEXEC) + case ENOEXEC: + throw EnoexecExc (tmp); + #endif + + #if defined (EBADF) + case EBADF: + throw EbadfExc (tmp); + #endif + + #if defined (ECHILD) + case ECHILD: + throw EchildExc (tmp); + #endif + + #if defined (EAGAIN) + case EAGAIN: + throw EagainExc (tmp); + #endif + + #if defined (ENOMEM) + case ENOMEM: + throw EnomemExc (tmp); + #endif + + #if defined (EACCES) + case EACCES: + throw EaccesExc (tmp); + #endif + + #if defined (EFAULT) + case EFAULT: + throw EfaultExc (tmp); + #endif + + #if defined (ENOTBLK) + case ENOTBLK: + throw EnotblkExc (tmp); + #endif + + #if defined (EBUSY) + case EBUSY: + throw EbusyExc (tmp); + #endif + + #if defined (EEXIST) + case EEXIST: + throw EexistExc (tmp); + #endif + + #if defined (EXDEV) + case EXDEV: + throw ExdevExc (tmp); + #endif + + #if defined (ENODEV) + case ENODEV: + throw EnodevExc (tmp); + #endif + + #if defined (ENOTDIR) + case ENOTDIR: + throw EnotdirExc (tmp); + #endif + + #if defined (EISDIR) + case EISDIR: + throw EisdirExc (tmp); + #endif + + #if defined (EINVAL) + case EINVAL: + throw EinvalExc (tmp); + #endif + + #if defined (ENFILE) + case ENFILE: + throw EnfileExc (tmp); + #endif + + #if defined (EMFILE) + case EMFILE: + throw EmfileExc (tmp); + #endif + + #if defined (ENOTTY) + case ENOTTY: + throw EnottyExc (tmp); + #endif + + #if defined (ETXTBSY) + case ETXTBSY: + throw EtxtbsyExc (tmp); + #endif + + #if defined (EFBIG) + case EFBIG: + throw EfbigExc (tmp); + #endif + + #if defined (ENOSPC) + case ENOSPC: + throw EnospcExc (tmp); + #endif + + #if defined (ESPIPE) + case ESPIPE: + throw EspipeExc (tmp); + #endif + + #if defined (EROFS) + case EROFS: + throw ErofsExc (tmp); + #endif + + #if defined (EMLINK) + case EMLINK: + throw EmlinkExc (tmp); + #endif + + #if defined (EPIPE) + case EPIPE: + throw EpipeExc (tmp); + #endif + + #if defined (EDOM) + case EDOM: + throw EdomExc (tmp); + #endif + + #if defined (ERANGE) + case ERANGE: + throw ErangeExc (tmp); + #endif + + #if defined (ENOMSG) + case ENOMSG: + throw EnomsgExc (tmp); + #endif + + #if defined (EIDRM) + case EIDRM: + throw EidrmExc (tmp); + #endif + + #if defined (ECHRNG) + case ECHRNG: + throw EchrngExc (tmp); + #endif + + #if defined (EL2NSYNC) + case EL2NSYNC: + throw El2nsyncExc (tmp); + #endif + + #if defined (EL3HLT) + case EL3HLT: + throw El3hltExc (tmp); + #endif + + #if defined (EL3RST) + case EL3RST: + throw El3rstExc (tmp); + #endif + + #if defined (ELNRNG) + case ELNRNG: + throw ElnrngExc (tmp); + #endif + + #if defined (EUNATCH) + case EUNATCH: + throw EunatchExc (tmp); + #endif + + #if defined (ENOSCI) + case ENOCSI: + throw EnocsiExc (tmp); + #endif + + #if defined (EL2HLT) + case EL2HLT: + throw El2hltExc (tmp); + #endif + + #if defined (EDEADLK) + case EDEADLK: + throw EdeadlkExc (tmp); + #endif + + #if defined (ENOLCK) + case ENOLCK: + throw EnolckExc (tmp); + #endif + + #if defined (EBADE) + case EBADE: + throw EbadeExc (tmp); + #endif + + #if defined (EBADR) + case EBADR: + throw EbadrExc (tmp); + #endif + + #if defined (EXFULL) + case EXFULL: + throw ExfullExc (tmp); + #endif + + #if defined (ENOANO) + case ENOANO: + throw EnoanoExc (tmp); + #endif + + #if defined (EBADRQC) + case EBADRQC: + throw EbadrqcExc (tmp); + #endif + + #if defined (EBADSLT) + case EBADSLT: + throw EbadsltExc (tmp); + #endif + + #if defined (EDEADLOCK) && defined (EDEADLK) + #if EDEADLOCK != EDEADLK + case EDEADLOCK: + throw EdeadlockExc (tmp); + #endif + #elif defined (EDEADLOCK) + case EDEADLOCK: + throw EdeadlockExc (tmp); + #endif + + #if defined (EBFONT) + case EBFONT: + throw EbfontExc (tmp); + #endif + + #if defined (ENOSTR) + case ENOSTR: + throw EnostrExc (tmp); + #endif + + #if defined (ENODATA) + case ENODATA: + throw EnodataExc (tmp); + #endif + + #if defined (ETIME) + case ETIME: + throw EtimeExc (tmp); + #endif + + #if defined (ENOSR) + case ENOSR: + throw EnosrExc (tmp); + #endif + + #if defined (ENONET) + case ENONET: + throw EnonetExc (tmp); + #endif + + #if defined (ENOPKG) + case ENOPKG: + throw EnopkgExc (tmp); + #endif + + #if defined (EREMOTE) + case EREMOTE: + throw EremoteExc (tmp); + #endif + + #if defined (ENOLINK) + case ENOLINK: + throw EnolinkExc (tmp); + #endif + + #if defined (EADV) + case EADV: + throw EadvExc (tmp); + #endif + + #if defined (ESRMNT) + case ESRMNT: + throw EsrmntExc (tmp); + #endif + + #if defined (ECOMM) + case ECOMM: + throw EcommExc (tmp); + #endif + + #if defined (EPROTO) + case EPROTO: + throw EprotoExc (tmp); + #endif + + #if defined (EMULTIHOP) + case EMULTIHOP: + throw EmultihopExc (tmp); + #endif + + #if defined (EBADMSG) + case EBADMSG: + throw EbadmsgExc (tmp); + #endif + + #if defined (ENAMETOOLONG) + case ENAMETOOLONG: + throw EnametoolongExc (tmp); + #endif + + #if defined (EOVERFLOW) + case EOVERFLOW: + throw EoverflowExc (tmp); + #endif + + #if defined (ENOTUNIQ) + case ENOTUNIQ: + throw EnotuniqExc (tmp); + #endif + + #if defined (EBADFD) + case EBADFD: + throw EbadfdExc (tmp); + #endif + + #if defined (EREMCHG) + case EREMCHG: + throw EremchgExc (tmp); + #endif + + #if defined (ELIBACC) + case ELIBACC: + throw ElibaccExc (tmp); + #endif + + #if defined (ELIBBAD) + case ELIBBAD: + throw ElibbadExc (tmp); + #endif + + #if defined (ELIBSCN) + case ELIBSCN: + throw ElibscnExc (tmp); + #endif + + #if defined (ELIBMAX) + case ELIBMAX: + throw ElibmaxExc (tmp); + #endif + + #if defined (ELIBEXEC) + case ELIBEXEC: + throw ElibexecExc (tmp); + #endif + + #if defined (EILSEQ) + case EILSEQ: + throw EilseqExc (tmp); + #endif + + #if defined (ENOSYS) + case ENOSYS: + throw EnosysExc (tmp); + #endif + + #if defined (ELOOP) + case ELOOP: + throw EloopExc (tmp); + #endif + + #if defined (ERESTART) + case ERESTART: + throw ErestartExc (tmp); + #endif + + #if defined (ESTRPIPE) + case ESTRPIPE: + throw EstrpipeExc (tmp); + #endif + + #if defined (ENOTEMPTY) + case ENOTEMPTY: + throw EnotemptyExc (tmp); + #endif + + #if defined (EUSERS) + case EUSERS: + throw EusersExc (tmp); + #endif + + #if defined (ENOTSOCK) + case ENOTSOCK: + throw EnotsockExc (tmp); + #endif + + #if defined (EDESTADDRREQ) + case EDESTADDRREQ: + throw EdestaddrreqExc (tmp); + #endif + + #if defined (EMSGSIZE) + case EMSGSIZE: + throw EmsgsizeExc (tmp); + #endif + + #if defined (EPROTOTYPE) + case EPROTOTYPE: + throw EprototypeExc (tmp); + #endif + + #if defined (ENOPROTOOPT) + case ENOPROTOOPT: + throw EnoprotooptExc (tmp); + #endif + + #if defined (EPROTONOSUPPORT) + case EPROTONOSUPPORT: + throw EprotonosupportExc (tmp); + #endif + + #if defined (ESOCKTNOSUPPORT) + case ESOCKTNOSUPPORT: + throw EsocktnosupportExc (tmp); + #endif + + #if defined (EOPNOTSUPP) + case EOPNOTSUPP: + throw EopnotsuppExc (tmp); + #endif + + #if defined (EPFNOSUPPORT) + case EPFNOSUPPORT: + throw EpfnosupportExc (tmp); + #endif + + #if defined (EAFNOSUPPORT) + case EAFNOSUPPORT: + throw EafnosupportExc (tmp); + #endif + + #if defined (EADDRINUSE) + case EADDRINUSE: + throw EaddrinuseExc (tmp); + #endif + + #if defined (EADDRNOTAVAIL) + case EADDRNOTAVAIL: + throw EaddrnotavailExc (tmp); + #endif + + #if defined (ENETDOWN) + case ENETDOWN: + throw EnetdownExc (tmp); + #endif + + #if defined (ENETUNREACH) + case ENETUNREACH: + throw EnetunreachExc (tmp); + #endif + + #if defined (ENETRESET) + case ENETRESET: + throw EnetresetExc (tmp); + #endif + + #if defined (ECONNABORTED) + case ECONNABORTED: + throw EconnabortedExc (tmp); + #endif + + #if defined (ECONNRESET) + case ECONNRESET: + throw EconnresetExc (tmp); + #endif + + #if defined (ENOBUFS) + case ENOBUFS: + throw EnobufsExc (tmp); + #endif + + #if defined (EISCONN) + case EISCONN: + throw EisconnExc (tmp); + #endif + + #if defined (ENOTCONN) + case ENOTCONN: + throw EnotconnExc (tmp); + #endif + + #if defined (ESHUTDOWN) + case ESHUTDOWN: + throw EshutdownExc (tmp); + #endif + + #if defined (ETOOMANYREFS) + case ETOOMANYREFS: + throw EtoomanyrefsExc (tmp); + #endif + + #if defined (ETIMEDOUT) + case ETIMEDOUT: + throw EtimedoutExc (tmp); + #endif + + #if defined (ECONNREFUSED) + case ECONNREFUSED: + throw EconnrefusedExc (tmp); + #endif + + #if defined (EHOSTDOWN) + case EHOSTDOWN: + throw EhostdownExc (tmp); + #endif + + #if defined (EHOSTUNREACH) + case EHOSTUNREACH: + throw EhostunreachExc (tmp); + #endif + + #if defined (EALREADY) + case EALREADY: + throw EalreadyExc (tmp); + #endif + + #if defined (EINPROGRESS) + case EINPROGRESS: + throw EinprogressExc (tmp); + #endif + + #if defined (ESTALE) + case ESTALE: + throw EstaleExc (tmp); + #endif + + #if defined (EIORESID) + case EIORESID: + throw EioresidExc (tmp); + #endif + + #if defined (EUCLEAN) + case EUCLEAN: + throw EucleanExc (tmp); + #endif + + #if defined (ENOTNAM) + case ENOTNAM: + throw EnotnamExc (tmp); + #endif + + #if defined (ENAVAIL) + case ENAVAIL: + throw EnavailExc (tmp); + #endif + + #if defined (EISNAM) + case EISNAM: + throw EisnamExc (tmp); + #endif + + #if defined (EREMOTEIO) + case EREMOTEIO: + throw EremoteioExc (tmp); + #endif + + #if defined (EINIT) + case EINIT: + throw EinitExc (tmp); + #endif + + #if defined (EREMDEV) + case EREMDEV: + throw EremdevExc (tmp); + #endif + + #if defined (ECANCELED) + case ECANCELED: + throw EcanceledExc (tmp); + #endif + + #if defined (ENOLIMFILE) + case ENOLIMFILE: + throw EnolimfileExc (tmp); + #endif + + #if defined (EPROCLIM) + case EPROCLIM: + throw EproclimExc (tmp); + #endif + + #if defined (EDISJOINT) + case EDISJOINT: + throw EdisjointExc (tmp); + #endif + + #if defined (ENOLOGIN) + case ENOLOGIN: + throw EnologinExc (tmp); + #endif + + #if defined (ELOGINLIM) + case ELOGINLIM: + throw EloginlimExc (tmp); + #endif + + #if defined (EGROUPLOOP) + case EGROUPLOOP: + throw EgrouploopExc (tmp); + #endif + + #if defined (ENOATTACH) + case ENOATTACH: + throw EnoattachExc (tmp); + #endif + + #if defined (ENOTSUP) && defined (EOPNOTSUPP) + #if ENOTSUP != EOPNOTSUPP + case ENOTSUP: + throw EnotsupExc (tmp); + #endif + #elif defined (ENOTSUP) + case ENOTSUP: + throw EnotsupExc (tmp); + #endif + + #if defined (ENOATTR) + case ENOATTR: + throw EnoattrExc (tmp); + #endif + + #if defined (EDIRCORRUPTED) + case EDIRCORRUPTED: + throw EdircorruptedExc (tmp); + #endif + + #if defined (EDQUOT) + case EDQUOT: + throw EdquotExc (tmp); + #endif + + #if defined (ENFSREMOTE) + case ENFSREMOTE: + throw EnfsremoteExc (tmp); + #endif + + #if defined (ECONTROLLER) + case ECONTROLLER: + throw EcontrollerExc (tmp); + #endif + + #if defined (ENOTCONTROLLER) + case ENOTCONTROLLER: + throw EnotcontrollerExc (tmp); + #endif + + #if defined (EENQUEUED) + case EENQUEUED: + throw EenqueuedExc (tmp); + #endif + + #if defined (ENOTENQUEUED) + case ENOTENQUEUED: + throw EnotenqueuedExc (tmp); + #endif + + #if defined (EJOINED) + case EJOINED: + throw EjoinedExc (tmp); + #endif + + #if defined (ENOTJOINED) + case ENOTJOINED: + throw EnotjoinedExc (tmp); + #endif + + #if defined (ENOPROC) + case ENOPROC: + throw EnoprocExc (tmp); + #endif + + #if defined (EMUSTRUN) + case EMUSTRUN: + throw EmustrunExc (tmp); + #endif + + #if defined (ENOTSTOPPED) + case ENOTSTOPPED: + throw EnotstoppedExc (tmp); + #endif + + #if defined (ECLOCKCPU) + case ECLOCKCPU: + throw EclockcpuExc (tmp); + #endif + + #if defined (EINVALSTATE) + case EINVALSTATE: + throw EinvalstateExc (tmp); + #endif + + #if defined (ENOEXIST) + case ENOEXIST: + throw EnoexistExc (tmp); + #endif + + #if defined (EENDOFMINOR) + case EENDOFMINOR: + throw EendofminorExc (tmp); + #endif + + #if defined (EBUFSIZE) + case EBUFSIZE: + throw EbufsizeExc (tmp); + #endif + + #if defined (EEMPTY) + case EEMPTY: + throw EemptyExc (tmp); + #endif + + #if defined (ENOINTRGROUP) + case ENOINTRGROUP: + throw EnointrgroupExc (tmp); + #endif + + #if defined (EINVALMODE) + case EINVALMODE: + throw EinvalmodeExc (tmp); + #endif + + #if defined (ECANTEXTENT) + case ECANTEXTENT: + throw EcantextentExc (tmp); + #endif + + #if defined (EINVALTIME) + case EINVALTIME: + throw EinvaltimeExc (tmp); + #endif + + #if defined (EDESTROYED) + case EDESTROYED: + throw EdestroyedExc (tmp); + #endif + } + + throw ErrnoExc (tmp); +} + + +void throwErrnoExc (const std::string &text) +{ + throwErrnoExc (text, errno); +} + + +} // namespace Iex diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Iex/IexThrowErrnoExc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,96 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IEXTHROWERRNOEXC_H +#define INCLUDED_IEXTHROWERRNOEXC_H + +//---------------------------------------------------------- +// +// A function which throws ExcErrno exceptions +// +//---------------------------------------------------------- + +#include "IexBaseExc.h" + +namespace Iex { + + +//-------------------------------------------------------------------------- +// +// Function throwErrnoExc() throws an exception which corresponds to +// error code errnum. The exception text is initialized with a copy +// of the string passed to throwErrnoExc(), where all occurrences of +// "%T" have been replaced with the output of strerror(oserror()). +// +// Example: +// +// If opening file /tmp/output failed with an ENOENT error code, +// calling +// +// throwErrnoExc (); +// +// or +// +// throwErrnoExc ("%T."); +// +// will throw an EnoentExc whose text reads +// +// No such file or directory. +// +// More detailed messages can be assembled using stringstreams: +// +// std::stringstream s; +// s << "Cannot open file " << name << " (%T)."; +// throwErrnoExc (s); +// +// The resulting exception contains the following text: +// +// Cannot open file /tmp/output (No such file or directory). +// +// Alternatively, you may want to use the THROW_ERRNO macro defined +// in IexMacros.h: +// +// THROW_ERRNO ("Cannot open file " << name << " (%T).") +// +//-------------------------------------------------------------------------- + +void throwErrnoExc (const std::string &txt, int errnum); +void throwErrnoExc (const std::string &txt = "%T." /*, int errnum = oserror() */); + + +} // namespace Iex + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h 2013-05-04 20:02:42.000000000 +0000 @@ -0,0 +1,30 @@ +// +// Define and set to 1 if the target system has POSIX thread support +// and you want IlmBase to use it for multithreaded file I/O. +// + +#define HAVE_PTHREAD 0 + +// +// Define and set to 1 if the target system supports POSIX semaphores +// and you want OpenEXR to use them; otherwise, OpenEXR will use its +// own semaphore implementation. +// + +#define HAVE_POSIX_SEMAPHORES 0 + +#undef HAVE_UCONTEXT_H + +// +// Define and set to 1 if the target system has support for large +// stack sizes. +// + +#undef ILMBASE_HAVE_LARGE_STACK + + +// +// Version string for runtime access +// +#define ILMBASE_VERSION_STRING "1.0.3" +#define ILMBASE_PACKAGE_STRING "IlmBase 1.0.3" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h.cmakein diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h.cmakein --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h.cmakein 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmBaseConfig.h.cmakein 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,30 @@ +// +// Define and set to 1 if the target system has POSIX thread support +// and you want IlmBase to use it for multithreaded file I/O. +// + +#cmakedefine01 HAVE_PTHREAD + +// +// Define and set to 1 if the target system supports POSIX semaphores +// and you want OpenEXR to use them; otherwise, OpenEXR will use its +// own semaphore implementation. +// + +#cmakedefine01 HAVE_POSIX_SEMAPHORES + +#undef HAVE_UCONTEXT_H + +// +// Define and set to 1 if the target system has support for large +// stack sizes. +// + +#undef ILMBASE_HAVE_LARGE_STACK + + +// +// Version string for runtime access +// +#define ILMBASE_VERSION_STRING "1.0.3" +#define ILMBASE_PACKAGE_STRING "IlmBase 1.0.3" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// ACES image file I/O. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include + +using namespace std; +using namespace Imath; +using namespace Iex; + +namespace Imf { + + +const Chromaticities & +acesChromaticities () +{ + static const Chromaticities acesChr + (V2f (0.73470, 0.26530), // red + V2f (0.00000, 1.00000), // green + V2f (0.00010, -0.07700), // blue + V2f (0.32168, 0.33767)); // white + + return acesChr; +} + + +class AcesOutputFile::Data +{ + public: + + Data(); + ~Data(); + + RgbaOutputFile * rgbaFile; +}; + + +AcesOutputFile::Data::Data (): + rgbaFile (0) +{ + // empty +} + + +AcesOutputFile::Data::~Data () +{ + delete rgbaFile; +} + + +namespace { + +void +checkCompression (Compression compression) +{ + // + // Not all compression methods are allowed in ACES files. + // + + switch (compression) + { + case NO_COMPRESSION: + case PIZ_COMPRESSION: + case B44A_COMPRESSION: + break; + + default: + throw ArgExc ("Invalid compression type for ACES file."); + } +} + +} // namespace + + +AcesOutputFile::AcesOutputFile + (const std::string &name, + const Header &header, + RgbaChannels rgbaChannels, + int numThreads) +: + _data (new Data) +{ + checkCompression (header.compression()); + + Header newHeader = header; + addChromaticities (newHeader, acesChromaticities()); + addAdoptedNeutral (newHeader, acesChromaticities().white); + + _data->rgbaFile = new RgbaOutputFile (name.c_str(), + newHeader, + rgbaChannels, + numThreads); + + _data->rgbaFile->setYCRounding (7, 6); +} + + +AcesOutputFile::AcesOutputFile + (OStream &os, + const Header &header, + RgbaChannels rgbaChannels, + int numThreads) +: + _data (new Data) +{ + checkCompression (header.compression()); + + Header newHeader = header; + addChromaticities (newHeader, acesChromaticities()); + addAdoptedNeutral (newHeader, acesChromaticities().white); + + _data->rgbaFile = new RgbaOutputFile (os, + header, + rgbaChannels, + numThreads); + + _data->rgbaFile->setYCRounding (7, 6); +} + + +AcesOutputFile::AcesOutputFile + (const std::string &name, + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads) +: + _data (new Data) +{ + checkCompression (compression); + + Header newHeader (displayWindow, + dataWindow.isEmpty()? displayWindow: dataWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + addChromaticities (newHeader, acesChromaticities()); + addAdoptedNeutral (newHeader, acesChromaticities().white); + + _data->rgbaFile = new RgbaOutputFile (name.c_str(), + newHeader, + rgbaChannels, + numThreads); + + _data->rgbaFile->setYCRounding (7, 6); +} + + +AcesOutputFile::AcesOutputFile + (const std::string &name, + int width, + int height, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads) +: + _data (new Data) +{ + checkCompression (compression); + + Header newHeader (width, + height, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + addChromaticities (newHeader, acesChromaticities()); + addAdoptedNeutral (newHeader, acesChromaticities().white); + + _data->rgbaFile = new RgbaOutputFile (name.c_str(), + newHeader, + rgbaChannels, + numThreads); + + _data->rgbaFile->setYCRounding (7, 6); +} + + +AcesOutputFile::~AcesOutputFile () +{ + delete _data; +} + + +void +AcesOutputFile::setFrameBuffer + (const Rgba *base, + size_t xStride, + size_t yStride) +{ + _data->rgbaFile->setFrameBuffer (base, xStride, yStride); +} + + +void +AcesOutputFile::writePixels (int numScanLines) +{ + _data->rgbaFile->writePixels (numScanLines); +} + + +int +AcesOutputFile::currentScanLine () const +{ + return _data->rgbaFile->currentScanLine(); +} + + +const Header & +AcesOutputFile::header () const +{ + return _data->rgbaFile->header(); +} + + +const Imath::Box2i & +AcesOutputFile::displayWindow () const +{ + return _data->rgbaFile->displayWindow(); +} + + +const Imath::Box2i & +AcesOutputFile::dataWindow () const +{ + return _data->rgbaFile->dataWindow(); +} + + +float +AcesOutputFile::pixelAspectRatio () const +{ + return _data->rgbaFile->pixelAspectRatio(); +} + + +const Imath::V2f +AcesOutputFile::screenWindowCenter () const +{ + return _data->rgbaFile->screenWindowCenter(); +} + + +float +AcesOutputFile::screenWindowWidth () const +{ + return _data->rgbaFile->screenWindowWidth(); +} + + +LineOrder +AcesOutputFile::lineOrder () const +{ + return _data->rgbaFile->lineOrder(); +} + + +Compression +AcesOutputFile::compression () const +{ + return _data->rgbaFile->compression(); +} + + +RgbaChannels +AcesOutputFile::channels () const +{ + return _data->rgbaFile->channels(); +} + + +void +AcesOutputFile::updatePreviewImage (const PreviewRgba pixels[]) +{ + _data->rgbaFile->updatePreviewImage (pixels); +} + + +class AcesInputFile::Data +{ + public: + + Data(); + ~Data(); + + void initColorConversion (); + + RgbaInputFile * rgbaFile; + + Rgba * fbBase; + size_t fbXStride; + size_t fbYStride; + int minX; + int maxX; + + bool mustConvertColor; + M44f fileToAces; +}; + + +AcesInputFile::Data::Data (): + rgbaFile (0), + fbBase (0), + fbXStride (0), + fbYStride (0), + minX (0), + maxX (0), + mustConvertColor (false) +{ + // empty +} + + +AcesInputFile::Data::~Data () +{ + delete rgbaFile; +} + + +void +AcesInputFile::Data::initColorConversion () +{ + const Header &header = rgbaFile->header(); + + Chromaticities fileChr; + + if (hasChromaticities (header)) + fileChr = chromaticities (header); + + V2f fileNeutral = fileChr.white; + + if (hasAdoptedNeutral (header)) + fileNeutral = adoptedNeutral (header); + + const Chromaticities acesChr = acesChromaticities(); + + V2f acesNeutral = acesChr.white; + + if (fileChr.red == acesChr.red && + fileChr.green == acesChr.green && + fileChr.blue == acesChr.blue && + fileChr.white == acesChr.white && + fileNeutral == acesNeutral) + { + // + // The file already contains ACES data, + // color conversion is not necessary. + + return; + } + + mustConvertColor = true; + minX = header.dataWindow().min.x; + maxX = header.dataWindow().max.x; + + // + // Create a matrix that transforms colors from the + // RGB space of the input file into the ACES space + // using a color adaptation transform to move the + // white point. + // + + // + // We'll need the Bradford cone primary matrix and its inverse + // + + static const M44f bradfordCPM + (0.895100, -0.750200, 0.038900, 0.000000, + 0.266400, 1.713500, -0.068500, 0.000000, + -0.161400, 0.036700, 1.029600, 0.000000, + 0.000000, 0.000000, 0.000000, 1.000000); + + const static M44f inverseBradfordCPM + (0.986993, 0.432305, -0.008529, 0.000000, + -0.147054, 0.518360, 0.040043, 0.000000, + 0.159963, 0.049291, 0.968487, 0.000000, + 0.000000, 0.000000, 0.000000, 1.000000); + + // + // Convert the white points of the two RGB spaces to XYZ + // + + float fx = fileNeutral.x; + float fy = fileNeutral.y; + V3f fileNeutralXYZ (fx / fy, 1, (1 - fx - fy) / fy); + + float ax = acesNeutral.x; + float ay = acesNeutral.y; + V3f acesNeutralXYZ (ax / ay, 1, (1 - ax - ay) / ay); + + // + // Compute the Bradford transformation matrix + // + + V3f ratio ((acesNeutralXYZ * bradfordCPM) / + (fileNeutralXYZ * bradfordCPM)); + + M44f ratioMat (ratio[0], 0, 0, 0, + 0, ratio[1], 0, 0, + 0, 0, ratio[2], 0, + 0, 0, 0, 1); + + M44f bradfordTrans = bradfordCPM * + ratioMat * + inverseBradfordCPM; + + // + // Build a combined file-RGB-to-ACES-RGB conversion matrix + // + + fileToAces = RGBtoXYZ (fileChr, 1) * bradfordTrans * XYZtoRGB (acesChr, 1); +} + + +AcesInputFile::AcesInputFile (const std::string &name, int numThreads): + _data (new Data) +{ + _data->rgbaFile = new RgbaInputFile (name.c_str(), numThreads); + _data->initColorConversion(); +} + + +AcesInputFile::AcesInputFile (IStream &is, int numThreads): + _data (new Data) +{ + _data->rgbaFile = new RgbaInputFile (is, numThreads); + _data->initColorConversion(); +} + + +AcesInputFile::~AcesInputFile () +{ + delete _data; +} + + +void +AcesInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride) +{ + _data->rgbaFile->setFrameBuffer (base, xStride, yStride); + _data->fbBase = base; + _data->fbXStride = xStride; + _data->fbYStride = yStride; +} + + +void +AcesInputFile::readPixels (int scanLine1, int scanLine2) +{ + // + // Copy the pixels from the RgbaInputFile into the frame buffer. + // + + _data->rgbaFile->readPixels (scanLine1, scanLine2); + + // + // If the RGB space of the input file is not the same as the ACES + // RGB space, then the pixels in the frame buffer must be transformed + // into the ACES RGB space. + // + + if (!_data->mustConvertColor) + return; + + int minY = min (scanLine1, scanLine2); + int maxY = max (scanLine1, scanLine2); + + for (int y = minY; y <= maxY; ++y) + { + Rgba *base = _data->fbBase + + _data->fbXStride * _data->minX + + _data->fbYStride * y; + + for (int x = _data->minX; x <= _data->maxX; ++x) + { + V3f aces = V3f (base->r, base->g, base->b) * _data->fileToAces; + + base->r = aces[0]; + base->g = aces[1]; + base->b = aces[2]; + + base += _data->fbXStride; + } + } +} + + +void +AcesInputFile::readPixels (int scanLine) +{ + readPixels (scanLine, scanLine); +} + + +const Header & +AcesInputFile::header () const +{ + return _data->rgbaFile->header(); +} + + +const Imath::Box2i & +AcesInputFile::displayWindow () const +{ + return _data->rgbaFile->displayWindow(); +} + + +const Imath::Box2i & +AcesInputFile::dataWindow () const +{ + return _data->rgbaFile->dataWindow(); +} + + +float +AcesInputFile::pixelAspectRatio () const +{ + return _data->rgbaFile->pixelAspectRatio(); +} + + +const Imath::V2f +AcesInputFile::screenWindowCenter () const +{ + return _data->rgbaFile->screenWindowCenter(); +} + + +float +AcesInputFile::screenWindowWidth () const +{ + return _data->rgbaFile->screenWindowWidth(); +} + + +LineOrder +AcesInputFile::lineOrder () const +{ + return _data->rgbaFile->lineOrder(); +} + + +Compression +AcesInputFile::compression () const +{ + return _data->rgbaFile->compression(); +} + + +RgbaChannels +AcesInputFile::channels () const +{ + return _data->rgbaFile->channels(); +} + + +const char * +AcesInputFile::fileName () const +{ + return _data->rgbaFile->fileName(); +} + + +bool +AcesInputFile::isComplete () const +{ + return _data->rgbaFile->isComplete(); +} + + +int +AcesInputFile::version () const +{ + return _data->rgbaFile->version(); +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAcesFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,322 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_ACES_FILE_H +#define INCLUDED_IMF_ACES_FILE_H + + +//----------------------------------------------------------------------------- +// +// ACES image file I/O. +// +// This header file declares two classes that directly support +// image file input and output according to the Academy Image +// Interchange Framework. +// +// The Academy Image Interchange file format is a subset of OpenEXR: +// +// - Images are stored as scanlines. Tiles are not allowed. +// +// - Images contain three color channels, either +// R, G, B (red, green, blue) or +// Y, RY, BY (luminance, sub-sampled chroma) +// +// - Images may optionally contain an alpha channel. +// +// - Only three compression types are allowed: +// - NO_COMPRESSION (file is not compressed) +// - PIZ_COMPRESSION (lossless) +// - B44A_COMPRESSION (lossy) +// +// - The "chromaticities" header attribute must specify +// the ACES RGB primaries and white point. +// +// class AcesOutputFile writes an OpenEXR file, enforcing the +// restrictions listed above. Pixel data supplied by application +// software must already be in the ACES RGB space. +// +// class AcesInputFile reads an OpenEXR file. Pixel data delivered +// to application software is guaranteed to be in the ACES RGB space. +// If the RGB space of the file is not the same as the ACES space, +// then the pixels are automatically converted: the pixels are +// converted to CIE XYZ, a color adaptation transform shifts the +// white point, and the result is converted to ACES RGB. +// +//----------------------------------------------------------------------------- + +#include +#include +#include "ImathVec.h" +#include "ImathBox.h" +#include +#include + +namespace Imf { + + +class RgbaOutputFile; +class RgbaInputFile; +struct PreviewRgba; +struct Chromaticities; + +// +// ACES red, green, blue and white-point chromaticities. +// + +const Chromaticities & acesChromaticities (); + + +// +// ACES output file. +// + +class AcesOutputFile +{ + public: + + //--------------------------------------------------- + // Constructor -- header is constructed by the caller + //--------------------------------------------------- + + AcesOutputFile (const std::string &name, + const Header &header, + RgbaChannels rgbaChannels = WRITE_RGBA, + int numThreads = globalThreadCount()); + + + //---------------------------------------------------- + // Constructor -- header is constructed by the caller, + // file is opened by the caller, destructor will not + // automatically close the file. + //---------------------------------------------------- + + AcesOutputFile (OStream &os, + const Header &header, + RgbaChannels rgbaChannels = WRITE_RGBA, + int numThreads = globalThreadCount()); + + + //---------------------------------------------------------------- + // Constructor -- header data are explicitly specified as function + // call arguments (empty dataWindow means "same as displayWindow") + //---------------------------------------------------------------- + + AcesOutputFile (const std::string &name, + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow = Imath::Box2i(), + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = PIZ_COMPRESSION, + int numThreads = globalThreadCount()); + + + //----------------------------------------------- + // Constructor -- like the previous one, but both + // the display window and the data window are + // Box2i (V2i (0, 0), V2i (width - 1, height -1)) + //----------------------------------------------- + + AcesOutputFile (const std::string &name, + int width, + int height, + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = PIZ_COMPRESSION, + int numThreads = globalThreadCount()); + + + //----------- + // Destructor + //----------- + + virtual ~AcesOutputFile (); + + + //------------------------------------------------ + // Define a frame buffer as the pixel data source: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //------------------------------------------------ + + void setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride); + + + //------------------------------------------------- + // Write pixel data (see class Imf::OutputFile) + // The pixels are assumed to contain ACES RGB data. + //------------------------------------------------- + + void writePixels (int numScanLines = 1); + int currentScanLine () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + + + // -------------------------------------------------------------------- + // Update the preview image (see Imf::OutputFile::updatePreviewImage()) + // -------------------------------------------------------------------- + + void updatePreviewImage (const PreviewRgba[]); + + + private: + + AcesOutputFile (const AcesOutputFile &); // not implemented + AcesOutputFile & operator = (const AcesOutputFile &); // not implemented + + class Data; + + Data * _data; +}; + + +// +// ACES input file +// + +class AcesInputFile +{ + public: + + //------------------------------------------------------- + // Constructor -- opens the file with the specified name, + // destructor will automatically close the file. + //------------------------------------------------------- + + AcesInputFile (const std::string &name, + int numThreads = globalThreadCount()); + + + //----------------------------------------------------------- + // Constructor -- attaches the new AcesInputFile object to a + // file that has already been opened by the caller. + // Destroying the AcesInputFile object will not automatically + // close the file. + //----------------------------------------------------------- + + AcesInputFile (IStream &is, + int numThreads = globalThreadCount()); + + + //----------- + // Destructor + //----------- + + virtual ~AcesInputFile (); + + + //----------------------------------------------------- + // Define a frame buffer as the pixel data destination: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //----------------------------------------------------- + + void setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride); + + + //-------------------------------------------- + // Read pixel data (see class Imf::InputFile) + // Pixels returned will contain ACES RGB data. + //-------------------------------------------- + + void readPixels (int scanLine1, int scanLine2); + void readPixels (int scanLine); + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + const char * fileName () const; + bool isComplete () const; + + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + private: + + AcesInputFile (const AcesInputFile &); // not implemented + AcesInputFile & operator = (const AcesInputFile &); // not implemented + + class Data; + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfArray.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfArray.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfArray.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfArray.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,261 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_ARRAY_H +#define INCLUDED_IMF_ARRAY_H + +//------------------------------------------------------------------------- +// +// class Array +// class Array2D +// +// "Arrays of T" whose sizes are not known at compile time. +// When an array goes out of scope, its elements are automatically +// deleted. +// +// Usage example: +// +// struct C +// { +// C () {std::cout << "C::C (" << this << ")\n";}; +// virtual ~C () {std::cout << "C::~C (" << this << ")\n";}; +// }; +// +// int +// main () +// { +// Array a(3); +// +// C &b = a[1]; +// const C &c = a[1]; +// C *d = a + 2; +// const C *e = a; +// +// return 0; +// } +// +//------------------------------------------------------------------------- + +namespace Imf { + + +template +class Array +{ + public: + + //----------------------------- + // Constructors and destructors + //----------------------------- + + Array () {_data = 0;} + Array (long size) {_data = new T[size];} + ~Array () {delete [] _data;} + + + //----------------------------- + // Access to the array elements + //----------------------------- + + operator T * () {return _data;} + operator const T * () const {return _data;} + + + //------------------------------------------------------ + // Resize and clear the array (the contents of the array + // are not preserved across the resize operation). + // + // resizeEraseUnsafe() is more memory efficient than + // resizeErase() because it deletes the old memory block + // before allocating a new one, but if allocating the + // new block throws an exception, resizeEraseUnsafe() + // leaves the array in an unusable state. + // + //------------------------------------------------------ + + void resizeErase (long size); + void resizeEraseUnsafe (long size); + + + private: + + Array (const Array &); // Copying and assignment + Array & operator = (const Array &); // are not implemented + + T * _data; +}; + + +template +class Array2D +{ + public: + + //----------------------------- + // Constructors and destructors + //----------------------------- + + Array2D (); // empty array, 0 by 0 elements + Array2D (long sizeX, long sizeY); // sizeX by sizeY elements + ~Array2D (); + + + //----------------------------- + // Access to the array elements + //----------------------------- + + T * operator [] (long x); + const T * operator [] (long x) const; + + + //------------------------------------------------------ + // Resize and clear the array (the contents of the array + // are not preserved across the resize operation). + // + // resizeEraseUnsafe() is more memory efficient than + // resizeErase() because it deletes the old memory block + // before allocating a new one, but if allocating the + // new block throws an exception, resizeEraseUnsafe() + // leaves the array in an unusable state. + // + //------------------------------------------------------ + + void resizeErase (long sizeX, long sizeY); + void resizeEraseUnsafe (long sizeX, long sizeY); + + + private: + + Array2D (const Array2D &); // Copying and assignment + Array2D & operator = (const Array2D &); // are not implemented + + long _sizeY; + T * _data; +}; + + +//--------------- +// Implementation +//--------------- + +template +inline void +Array::resizeErase (long size) +{ + T *tmp = new T[size]; + delete [] _data; + _data = tmp; +} + + +template +inline void +Array::resizeEraseUnsafe (long size) +{ + delete [] _data; + _data = 0; + _data = new T[size]; +} + + +template +inline +Array2D::Array2D (): + _sizeY (0), _data (0) +{ + // emtpy +} + + +template +inline +Array2D::Array2D (long sizeX, long sizeY): + _sizeY (sizeY), _data (new T[sizeX * sizeY]) +{ + // emtpy +} + + +template +inline +Array2D::~Array2D () +{ + delete [] _data; +} + + +template +inline T * +Array2D::operator [] (long x) +{ + return _data + x * _sizeY; +} + + +template +inline const T * +Array2D::operator [] (long x) const +{ + return _data + x * _sizeY; +} + + +template +inline void +Array2D::resizeErase (long sizeX, long sizeY) +{ + T *tmp = new T[sizeX * sizeY]; + delete [] _data; + _sizeY = sizeY; + _data = tmp; +} + + +template +inline void +Array2D::resizeEraseUnsafe (long sizeX, long sizeY) +{ + delete [] _data; + _data = 0; + _sizeY = 0; + _data = new T[sizeX * sizeY]; + _sizeY = sizeY; +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Attribute +// +//----------------------------------------------------------------------------- + +#include +#include "IlmThreadMutex.h" +#include "Iex.h" +#include +#include + + +namespace Imf { + +using IlmThread::Mutex; +using IlmThread::Lock; + + +Attribute::Attribute () {} + + +Attribute::~Attribute () {} + + +namespace { + +struct NameCompare: std::binary_function +{ + bool + operator () (const char *x, const char *y) const + { + return strcmp (x, y) < 0; + } +}; + + +typedef Attribute* (*Constructor)(); +typedef std::map TypeMap; + + +class LockedTypeMap: public TypeMap +{ + public: + + Mutex mutex; +}; + + +LockedTypeMap & +typeMap () +{ + static Mutex criticalSection; + Lock lock (criticalSection); + + static LockedTypeMap* typeMap = 0; + + if (typeMap == 0) + typeMap = new LockedTypeMap (); + + return *typeMap; +} + + +} // namespace + + +bool +Attribute::knownType (const char typeName[]) +{ + LockedTypeMap& tMap = typeMap(); + Lock lock (tMap.mutex); + + return tMap.find (typeName) != tMap.end(); +} + + +void +Attribute::registerAttributeType (const char typeName[], + Attribute *(*newAttribute)()) +{ + LockedTypeMap& tMap = typeMap(); + Lock lock (tMap.mutex); + + if (tMap.find (typeName) != tMap.end()) + THROW (Iex::ArgExc, "Cannot register image file attribute " + "type \"" << typeName << "\". " + "The type has already been registered."); + + tMap.insert (TypeMap::value_type (typeName, newAttribute)); +} + + +void +Attribute::unRegisterAttributeType (const char typeName[]) +{ + LockedTypeMap& tMap = typeMap(); + Lock lock (tMap.mutex); + + tMap.erase (typeName); +} + + +Attribute * +Attribute::newAttribute (const char typeName[]) +{ + LockedTypeMap& tMap = typeMap(); + Lock lock (tMap.mutex); + + TypeMap::const_iterator i = tMap.find (typeName); + + if (i == tMap.end()) + THROW (Iex::ArgExc, "Cannot create image file attribute of " + "unknown type \"" << typeName << "\"."); + + return (i->second)(); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,427 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_ATTRIBUTE_H +#define INCLUDED_IMF_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class Attribute +// +//----------------------------------------------------------------------------- + +#include "IexBaseExc.h" +#include +#include + + +namespace Imf { + + +class Attribute +{ + public: + + //--------------------------- + // Constructor and destructor + //--------------------------- + + Attribute (); + virtual ~Attribute (); + + + //------------------------------- + // Get this attribute's type name + //------------------------------- + + virtual const char * typeName () const = 0; + + + //------------------------------ + // Make a copy of this attribute + //------------------------------ + + virtual Attribute * copy () const = 0; + + + //---------------------------------------- + // Type-specific attribute I/O and copying + //---------------------------------------- + + virtual void writeValueTo (OStream &os, + int version) const = 0; + + virtual void readValueFrom (IStream &is, + int size, + int version) = 0; + + virtual void copyValueFrom (const Attribute &other) = 0; + + + //------------------ + // Attribute factory + //------------------ + + static Attribute * newAttribute (const char typeName[]); + + + //----------------------------------------------------------- + // Test if a given attribute type has already been registered + //----------------------------------------------------------- + + static bool knownType (const char typeName[]); + + + protected: + + //-------------------------------------------------- + // Register an attribute type so that newAttribute() + // knows how to make objects of this type. + //-------------------------------------------------- + + static void registerAttributeType (const char typeName[], + Attribute *(*newAttribute)()); + + //------------------------------------------------------ + // Un-register an attribute type so that newAttribute() + // no longer knows how to make objects of this type (for + // debugging only). + //------------------------------------------------------ + + static void unRegisterAttributeType (const char typeName[]); +}; + + +//------------------------------------------------- +// Class template for attributes of a specific type +//------------------------------------------------- + +template +class TypedAttribute: public Attribute +{ + public: + + //---------------------------- + // Constructors and destructor + //------------_--------------- + + TypedAttribute (); + TypedAttribute (const T &value); + TypedAttribute (const TypedAttribute &other); + virtual ~TypedAttribute (); + + + //-------------------------------- + // Access to the attribute's value + //-------------------------------- + + T & value (); + const T & value () const; + + + //-------------------------------- + // Get this attribute's type name. + //-------------------------------- + + virtual const char * typeName () const; + + + //--------------------------------------------------------- + // Static version of typeName() + // This function must be specialized for each value type T. + //--------------------------------------------------------- + + static const char * staticTypeName (); + + + //--------------------- + // Make a new attribute + //--------------------- + + static Attribute * makeNewAttribute (); + + + //------------------------------ + // Make a copy of this attribute + //------------------------------ + + virtual Attribute * copy () const; + + + //----------------------------------------------------------------- + // Type-specific attribute I/O and copying. + // Depending on type T, these functions may have to be specialized. + //----------------------------------------------------------------- + + virtual void writeValueTo (OStream &os, + int version) const; + + virtual void readValueFrom (IStream &is, + int size, + int version); + + virtual void copyValueFrom (const Attribute &other); + + + //------------------------------------------------------------ + // Dynamic casts that throw exceptions instead of returning 0. + //------------------------------------------------------------ + + static TypedAttribute * cast (Attribute *attribute); + static const TypedAttribute * cast (const Attribute *attribute); + static TypedAttribute & cast (Attribute &attribute); + static const TypedAttribute & cast (const Attribute &attribute); + + + //--------------------------------------------------------------- + // Register this attribute type so that Attribute::newAttribute() + // knows how to make objects of this type. + // + // Note that this function is not thread-safe because it modifies + // a global variable in the IlmIlm library. A thread in a multi- + // threaded program may call registerAttributeType() only when no + // other thread is accessing any functions or classes in the + // IlmImf library. + // + //--------------------------------------------------------------- + + static void registerAttributeType (); + + + //----------------------------------------------------- + // Un-register this attribute type (for debugging only) + //----------------------------------------------------- + + static void unRegisterAttributeType (); + + + private: + + T _value; +}; + + +//------------------------------------ +// Implementation of TypedAttribute +//------------------------------------ + +template +TypedAttribute::TypedAttribute (): + Attribute (), + _value (T()) +{ + // empty +} + + +template +TypedAttribute::TypedAttribute (const T &value): + Attribute (), + _value (value) +{ + // empty +} + + +template +TypedAttribute::TypedAttribute (const TypedAttribute &other): + Attribute (other), + _value () +{ + copyValueFrom (other); +} + + +template +TypedAttribute::~TypedAttribute () +{ + // empty +} + + +template +inline T & +TypedAttribute::value () +{ + return _value; +} + + +template +inline const T & +TypedAttribute::value () const +{ + return _value; +} + + +template +const char * +TypedAttribute::typeName () const +{ + return staticTypeName(); +} + + +template +Attribute * +TypedAttribute::makeNewAttribute () +{ + return new TypedAttribute(); +} + + +template +Attribute * +TypedAttribute::copy () const +{ + Attribute * attribute = new TypedAttribute(); + attribute->copyValueFrom (*this); + return attribute; +} + + +template +void +TypedAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value); +} + + +template +void +TypedAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value); +} + + +template +void +TypedAttribute::copyValueFrom (const Attribute &other) +{ + _value = cast(other)._value; +} + + +template +TypedAttribute * +TypedAttribute::cast (Attribute *attribute) +{ + TypedAttribute *t = + dynamic_cast *> (attribute); + + if (t == 0) + throw Iex::TypeExc ("Unexpected attribute type."); + + return t; +} + + +template +const TypedAttribute * +TypedAttribute::cast (const Attribute *attribute) +{ + const TypedAttribute *t = + dynamic_cast *> (attribute); + + if (t == 0) + throw Iex::TypeExc ("Unexpected attribute type."); + + return t; +} + + +template +inline TypedAttribute & +TypedAttribute::cast (Attribute &attribute) +{ + return *cast (&attribute); +} + + +template +inline const TypedAttribute & +TypedAttribute::cast (const Attribute &attribute) +{ + return *cast (&attribute); +} + + +template +inline void +TypedAttribute::registerAttributeType () +{ + Attribute::registerAttributeType (staticTypeName(), makeNewAttribute); +} + + +template +inline void +TypedAttribute::unRegisterAttributeType () +{ + Attribute::unRegisterAttributeType (staticTypeName()); +} + + +} // namespace Imf + +#if defined(OPENEXR_DLL) && defined(_MSC_VER) + // Tell MS VC++ to disable "non dll-interface class used as base + // for dll-interface class" and "no suitable definition provided + // for explicit template" + #pragma warning (disable : 4275 4661) + + #if defined (ILMIMF_EXPORTS) + #define IMF_EXPIMP_TEMPLATE + #else + #define IMF_EXPIMP_TEMPLATE extern + #endif + + IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute; + IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute; + + #pragma warning(default : 4251) + #undef EXTERN_TEMPLATE +#endif + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAutoArray.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAutoArray.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAutoArray.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfAutoArray.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_AUTO_ARRAY_H +#define INCLUDED_IMF_AUTO_ARRAY_H + +//----------------------------------------------------------------------------- +// +// class AutoArray -- a workaround for systems with +// insufficient stack space for large auto arrays. +// +//----------------------------------------------------------------------------- + +#include "OpenEXRConfig.h" + +#if !defined (HAVE_LARGE_STACK) +#include +#endif + +namespace Imf { + + +#if !defined (HAVE_LARGE_STACK) + + + template + class AutoArray + { + public: + + AutoArray (): _data (new T [size]) { memset(_data, 0, size*sizeof(T)); } + ~AutoArray () {delete [] _data;} + + operator T * () {return _data;} + operator const T * () const {return _data;} + + private: + + T *_data; + }; + + +#else + + + template + class AutoArray + { + public: + + operator T * () {return _data;} + operator const T * () const {return _data;} + + private: + + T _data[size]; + }; + + +#endif + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1069 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class B44Compressor +// +// This compressor is lossy for HALF channels; the compression rate +// is fixed at 32/14 (approximately 2.28). FLOAT and UINT channels +// are not compressed; their data are preserved exactly. +// +// Each HALF channel is split into blocks of 4 by 4 pixels. An +// uncompressed block occupies 32 bytes, which are re-interpreted +// as sixteen 16-bit unsigned integers, t[0] ... t[15]. Compression +// shrinks the block to 14 bytes. The compressed 14-byte block +// contains +// +// - t[0] +// +// - a 6-bit shift value +// +// - 15 densely packed 6-bit values, r[0] ... r[14], which are +// computed by subtracting adjacent pixel values and right- +// shifting the differences according to the stored shift value. +// +// Differences between adjacent pixels are computed according +// to the following diagram: +// +// 0 --------> 1 --------> 2 --------> 3 +// | 3 7 11 +// | +// | 0 +// | +// v +// 4 --------> 5 --------> 6 --------> 7 +// | 4 8 12 +// | +// | 1 +// | +// v +// 8 --------> 9 --------> 10 --------> 11 +// | 5 9 13 +// | +// | 2 +// | +// v +// 12 --------> 13 --------> 14 --------> 15 +// 6 10 14 +// +// Here +// +// 5 ---------> 6 +// 8 +// +// means that r[8] is the difference between t[5] and t[6]. +// +// - optionally, a 4-by-4 pixel block where all pixels have the +// same value can be treated as a special case, where the +// compressed block contains only 3 instead of 14 bytes: +// t[0], followed by an "impossible" 6-bit shift value and +// two padding bits. +// +// This compressor can handle positive and negative pixel values. +// NaNs and infinities are replaced with zeroes before compression. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Imf { + +using Imath::divp; +using Imath::modp; +using Imath::Box2i; +using Imath::V2i; +using std::min; + +namespace { + +// +// Lookup tables for +// y = exp (x / 8) +// and +// x = 8 * log (y) +// + +#include "b44ExpLogTable.h" + + +inline void +convertFromLinear (unsigned short s[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = expTable[s[i]]; +} + + +inline void +convertToLinear (unsigned short s[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = logTable[s[i]]; +} + + +inline int +shiftAndRound (int x, int shift) +{ + // + // Compute + // + // y = x * pow (2, -shift), + // + // then round y to the nearest integer. + // In case of a tie, where y is exactly + // halfway between two integers, round + // to the even one. + // + + x <<= 1; + int a = (1 << shift) - 1; + shift += 1; + int b = (x >> shift) & 1; + return (x + a + b) >> shift; +} + + +int +pack (const unsigned short s[16], + unsigned char b[14], + bool optFlatFields, + bool exactMax) +{ + // + // Pack a block of 4 by 4 16-bit pixels (32 bytes) into + // either 14 or 3 bytes. + // + + // + // Integers s[0] ... s[15] represent floating-point numbers + // in what is essentially a sign-magnitude format. Convert + // s[0] .. s[15] into a new set of integers, t[0] ... t[15], + // such that if t[i] is greater than t[j], the floating-point + // number that corresponds to s[i] is always greater than + // the floating-point number that corresponds to s[j]. + // + // Also, replace any bit patterns that represent NaNs or + // infinities with bit patterns that represent floating-point + // zeroes. + // + // bit pattern floating-point bit pattern + // in s[i] value in t[i] + // + // 0x7fff NAN 0x8000 + // 0x7ffe NAN 0x8000 + // ... ... + // 0x7c01 NAN 0x8000 + // 0x7c00 +infinity 0x8000 + // 0x7bff +HALF_MAX 0xfbff + // 0x7bfe 0xfbfe + // 0x7bfd 0xfbfd + // ... ... + // 0x0002 +2 * HALF_MIN 0x8002 + // 0x0001 +HALF_MIN 0x8001 + // 0x0000 +0.0 0x8000 + // 0x8000 -0.0 0x7fff + // 0x8001 -HALF_MIN 0x7ffe + // 0x8002 -2 * HALF_MIN 0x7ffd + // ... ... + // 0xfbfd 0x0f02 + // 0xfbfe 0x0401 + // 0xfbff -HALF_MAX 0x0400 + // 0xfc00 -infinity 0x8000 + // 0xfc01 NAN 0x8000 + // ... ... + // 0xfffe NAN 0x8000 + // 0xffff NAN 0x8000 + // + + unsigned short t[16]; + + for (int i = 0; i < 16; ++i) + { + if ((s[i] & 0x7c00) == 0x7c00) + t[i] = 0x8000; + else if (s[i] & 0x8000) + t[i] = ~s[i]; + else + t[i] = s[i] | 0x8000; + } + + // + // Find the maximum, tMax, of t[0] ... t[15]. + // + + unsigned short tMax = 0; + + for (int i = 0; i < 16; ++i) + if (tMax < t[i]) + tMax = t[i]; + + // + // Compute a set of running differences, r[0] ... r[14]: + // Find a shift value such that after rounding off the + // rightmost bits and shifting all differenes are between + // -32 and +31. Then bias the differences so that they + // end up between 0 and 63. + // + + int shift = -1; + int d[16]; + int r[15]; + int rMin; + int rMax; + + const int bias = 0x20; + + do + { + shift += 1; + + // + // Compute absolute differences, d[0] ... d[15], + // between tMax and t[0] ... t[15]. + // + // Shift and round the absolute differences. + // + + for (int i = 0; i < 16; ++i) + d[i] = shiftAndRound (tMax - t[i], shift); + + // + // Convert d[0] .. d[15] into running differences + // + + r[ 0] = d[ 0] - d[ 4] + bias; + r[ 1] = d[ 4] - d[ 8] + bias; + r[ 2] = d[ 8] - d[12] + bias; + + r[ 3] = d[ 0] - d[ 1] + bias; + r[ 4] = d[ 4] - d[ 5] + bias; + r[ 5] = d[ 8] - d[ 9] + bias; + r[ 6] = d[12] - d[13] + bias; + + r[ 7] = d[ 1] - d[ 2] + bias; + r[ 8] = d[ 5] - d[ 6] + bias; + r[ 9] = d[ 9] - d[10] + bias; + r[10] = d[13] - d[14] + bias; + + r[11] = d[ 2] - d[ 3] + bias; + r[12] = d[ 6] - d[ 7] + bias; + r[13] = d[10] - d[11] + bias; + r[14] = d[14] - d[15] + bias; + + rMin = r[0]; + rMax = r[0]; + + for (int i = 1; i < 15; ++i) + { + if (rMin > r[i]) + rMin = r[i]; + + if (rMax < r[i]) + rMax = r[i]; + } + } + while (rMin < 0 || rMax > 0x3f); + + if (rMin == bias && rMax == bias && optFlatFields) + { + // + // Special case - all pixels have the same value. + // We encode this in 3 instead of 14 bytes by + // storing the value 0xfc in the third output byte, + // which cannot occur in the 14-byte encoding. + // + + b[0] = (t[0] >> 8); + b[1] = t[0]; + b[2] = 0xfc; + + return 3; + } + + if (exactMax) + { + // + // Adjust t[0] so that the pixel whose value is equal + // to tMax gets represented as accurately as possible. + // + + t[0] = tMax - (d[0] << shift); + } + + // + // Pack t[0], shift and r[0] ... r[14] into 14 bytes: + // + + b[ 0] = (t[0] >> 8); + b[ 1] = t[0]; + + b[ 2] = (unsigned char) ((shift << 2) | (r[ 0] >> 4)); + b[ 3] = (unsigned char) ((r[ 0] << 4) | (r[ 1] >> 2)); + b[ 4] = (unsigned char) ((r[ 1] << 6) | r[ 2] ); + + b[ 5] = (unsigned char) ((r[ 3] << 2) | (r[ 4] >> 4)); + b[ 6] = (unsigned char) ((r[ 4] << 4) | (r[ 5] >> 2)); + b[ 7] = (unsigned char) ((r[ 5] << 6) | r[ 6] ); + + b[ 8] = (unsigned char) ((r[ 7] << 2) | (r[ 8] >> 4)); + b[ 9] = (unsigned char) ((r[ 8] << 4) | (r[ 9] >> 2)); + b[10] = (unsigned char) ((r[ 9] << 6) | r[10] ); + + b[11] = (unsigned char) ((r[11] << 2) | (r[12] >> 4)); + b[12] = (unsigned char) ((r[12] << 4) | (r[13] >> 2)); + b[13] = (unsigned char) ((r[13] << 6) | r[14] ); + + return 14; +} + + +inline +void +unpack14 (const unsigned char b[14], unsigned short s[16]) +{ + // + // Unpack a 14-byte block into 4 by 4 16-bit pixels. + // + + #if defined (DEBUG) + assert (b[2] != 0xfc); + #endif + + s[ 0] = (b[0] << 8) | b[1]; + + unsigned short shift = (b[ 2] >> 2); + unsigned short bias = (0x20 << shift); + + s[ 4] = s[ 0] + ((((b[ 2] << 4) | (b[ 3] >> 4)) & 0x3f) << shift) - bias; + s[ 8] = s[ 4] + ((((b[ 3] << 2) | (b[ 4] >> 6)) & 0x3f) << shift) - bias; + s[12] = s[ 8] + ((b[ 4] & 0x3f) << shift) - bias; + + s[ 1] = s[ 0] + ((b[ 5] >> 2) << shift) - bias; + s[ 5] = s[ 4] + ((((b[ 5] << 4) | (b[ 6] >> 4)) & 0x3f) << shift) - bias; + s[ 9] = s[ 8] + ((((b[ 6] << 2) | (b[ 7] >> 6)) & 0x3f) << shift) - bias; + s[13] = s[12] + ((b[ 7] & 0x3f) << shift) - bias; + + s[ 2] = s[ 1] + ((b[ 8] >> 2) << shift) - bias; + s[ 6] = s[ 5] + ((((b[ 8] << 4) | (b[ 9] >> 4)) & 0x3f) << shift) - bias; + s[10] = s[ 9] + ((((b[ 9] << 2) | (b[10] >> 6)) & 0x3f) << shift) - bias; + s[14] = s[13] + ((b[10] & 0x3f) << shift) - bias; + + s[ 3] = s[ 2] + ((b[11] >> 2) << shift) - bias; + s[ 7] = s[ 6] + ((((b[11] << 4) | (b[12] >> 4)) & 0x3f) << shift) - bias; + s[11] = s[10] + ((((b[12] << 2) | (b[13] >> 6)) & 0x3f) << shift) - bias; + s[15] = s[14] + ((b[13] & 0x3f) << shift) - bias; + + for (int i = 0; i < 16; ++i) + { + if (s[i] & 0x8000) + s[i] &= 0x7fff; + else + s[i] = ~s[i]; + } +} + + +inline +void +unpack3 (const unsigned char b[3], unsigned short s[16]) +{ + // + // Unpack a 3-byte block into 4 by 4 identical 16-bit pixels. + // + + #if defined (DEBUG) + assert (b[2] == 0xfc); + #endif + + s[0] = (b[0] << 8) | b[1]; + + if (s[0] & 0x8000) + s[0] &= 0x7fff; + else + s[0] = ~s[0]; + + for (int i = 1; i < 16; ++i) + s[i] = s[0]; +} + + +void +notEnoughData () +{ + throw Iex::InputExc ("Error decompressing data " + "(input data are shorter than expected)."); +} + + +void +tooMuchData () +{ + throw Iex::InputExc ("Error decompressing data " + "(input data are longer than expected)."); +} + +} // namespace + + +struct B44Compressor::ChannelData +{ + unsigned short * start; + unsigned short * end; + int nx; + int ny; + int ys; + PixelType type; + bool pLinear; + int size; +}; + + +B44Compressor::B44Compressor + (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines, + bool optFlatFields) +: + Compressor (hdr), + _maxScanLineSize (maxScanLineSize), + _optFlatFields (optFlatFields), + _format (XDR), + _numScanLines (numScanLines), + _tmpBuffer (0), + _outBuffer (0), + _numChans (0), + _channels (hdr.channels()), + _channelData (0) +{ + // + // Allocate buffers for compressed an uncompressed pixel data, + // allocate a set of ChannelData structs to help speed up the + // compress() and uncompress() functions, below, and determine + // if uncompressed pixel data should be in native or Xdr format. + // + + _tmpBuffer = new unsigned short + [checkArraySize (uiMult (maxScanLineSize, numScanLines), + sizeof (unsigned short))]; + + const ChannelList &channels = header().channels(); + int numHalfChans = 0; + + for (ChannelList::ConstIterator c = channels.begin(); + c != channels.end(); + ++c) + { + assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0); + ++_numChans; + + if (c.channel().type == HALF) + ++numHalfChans; + } + + // + // Compressed data may be larger than the input data + // + + size_t padding = 12 * numHalfChans * (numScanLines + 3) / 4; + + _outBuffer = new char + [uiAdd (uiMult (maxScanLineSize, numScanLines), padding)]; + + _channelData = new ChannelData[_numChans]; + + int i = 0; + + for (ChannelList::ConstIterator c = channels.begin(); + c != channels.end(); + ++c, ++i) + { + _channelData[i].ys = c.channel().ySampling; + _channelData[i].type = c.channel().type; + _channelData[i].pLinear = c.channel().pLinear; + _channelData[i].size = + pixelTypeSize (c.channel().type) / pixelTypeSize (HALF); + } + + const Box2i &dataWindow = hdr.dataWindow(); + + _minX = dataWindow.min.x; + _maxX = dataWindow.max.x; + _maxY = dataWindow.max.y; + + // + // We can support uncompressed data in the machine's native + // format only if all image channels are of type HALF. + // + + assert (sizeof (unsigned short) == pixelTypeSize (HALF)); + + if (_numChans == numHalfChans) + _format = NATIVE; +} + + +B44Compressor::~B44Compressor () +{ + delete [] _tmpBuffer; + delete [] _outBuffer; + delete [] _channelData; +} + + +int +B44Compressor::numScanLines () const +{ + return _numScanLines; +} + + +Compressor::Format +B44Compressor::format () const +{ + return _format; +} + + +int +B44Compressor::compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return compress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + numScanLines() - 1)), + outPtr); +} + + +int +B44Compressor::compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + return compress (inPtr, inSize, range, outPtr); +} + + +int +B44Compressor::uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return uncompress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + numScanLines() - 1)), + outPtr); +} + + +int +B44Compressor::uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + return uncompress (inPtr, inSize, range, outPtr); +} + + +int +B44Compressor::compress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + // + // Compress a block of pixel data: First copy the input pixels + // from the input buffer into _tmpBuffer, rearranging them such + // that blocks of 4x4 pixels of a single channel can be accessed + // conveniently. Then compress each 4x4 block of HALF pixel data + // and append the result to the output buffer. Copy UINT and + // FLOAT data to the output buffer without compressing them. + // + + outPtr = _outBuffer; + + if (inSize == 0) + { + // + // Special case - empty input buffer. + // + + return 0; + } + + // + // For each channel, detemine how many pixels are stored + // in the input buffer, and where those pixels will be + // placed in _tmpBuffer. + // + + int minX = range.min.x; + int maxX = min (range.max.x, _maxX); + int minY = range.min.y; + int maxY = min (range.max.y, _maxY); + + unsigned short *tmpBufferEnd = _tmpBuffer; + int i = 0; + + for (ChannelList::ConstIterator c = _channels.begin(); + c != _channels.end(); + ++c, ++i) + { + ChannelData &cd = _channelData[i]; + + cd.start = tmpBufferEnd; + cd.end = cd.start; + + cd.nx = numSamples (c.channel().xSampling, minX, maxX); + cd.ny = numSamples (c.channel().ySampling, minY, maxY); + + tmpBufferEnd += cd.nx * cd.ny * cd.size; + } + + if (_format == XDR) + { + // + // The data in the input buffer are in the machine-independent + // Xdr format. Copy the HALF channels into _tmpBuffer and + // convert them back into native format for compression. + // Copy UINT and FLOAT channels verbatim into _tmpBuffer. + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + if (cd.type == HALF) + { + for (int x = cd.nx; x > 0; --x) + { + Xdr::read (inPtr, *cd.end); + ++cd.end; + } + } + else + { + int n = cd.nx * cd.size; + memcpy (cd.end, inPtr, n * sizeof (unsigned short)); + inPtr += n * sizeof (unsigned short); + cd.end += n; + } + } + } + } + else + { + // + // The input buffer contains only HALF channels, and they + // are in native, machine-dependent format. Copy the pixels + // into _tmpBuffer. + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + #if defined (DEBUG) + assert (cd.type == HALF); + #endif + + if (modp (y, cd.ys) != 0) + continue; + + int n = cd.nx * cd.size; + memcpy (cd.end, inPtr, n * sizeof (unsigned short)); + inPtr += n * sizeof (unsigned short); + cd.end += n; + } + } + } + + // + // The pixels for each channel have been packed into a contiguous + // block in _tmpBuffer. HALF channels are in native format; UINT + // and FLOAT channels are in Xdr format. + // + + #if defined (DEBUG) + + for (int i = 1; i < _numChans; ++i) + assert (_channelData[i-1].end == _channelData[i].start); + + assert (_channelData[_numChans-1].end == tmpBufferEnd); + + #endif + + // + // For each HALF channel, split the data in _tmpBuffer into 4x4 + // pixel blocks. Compress each block and append the compressed + // data to the output buffer. + // + // UINT and FLOAT channels are copied from _tmpBuffer into the + // output buffer without further processing. + // + + char *outEnd = _outBuffer; + + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (cd.type != HALF) + { + // + // UINT or FLOAT channel. + // + + int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short); + memcpy (outEnd, cd.start, n); + outEnd += n; + + continue; + } + + // + // HALF channel + // + + for (int y = 0; y < cd.ny; y += 4) + { + // + // Copy the next 4x4 pixel block into array s. + // If the width, cd.nx, or the height, cd.ny, of + // the pixel data in _tmpBuffer is not divisible + // by 4, then pad the data by repeating the + // rightmost column and the bottom row. + // + + unsigned short *row0 = cd.start + y * cd.nx; + unsigned short *row1 = row0 + cd.nx; + unsigned short *row2 = row1 + cd.nx; + unsigned short *row3 = row2 + cd.nx; + + if (y + 3 >= cd.ny) + { + if (y + 1 >= cd.ny) + row1 = row0; + + if (y + 2 >= cd.ny) + row2 = row1; + + row3 = row2; + } + + for (int x = 0; x < cd.nx; x += 4) + { + unsigned short s[16]; + + if (x + 3 >= cd.nx) + { + int n = cd.nx - x; + + for (int i = 0; i < 4; ++i) + { + int j = min (i, n - 1); + + s[i + 0] = row0[j]; + s[i + 4] = row1[j]; + s[i + 8] = row2[j]; + s[i + 12] = row3[j]; + } + } + else + { + memcpy (&s[ 0], row0, 4 * sizeof (unsigned short)); + memcpy (&s[ 4], row1, 4 * sizeof (unsigned short)); + memcpy (&s[ 8], row2, 4 * sizeof (unsigned short)); + memcpy (&s[12], row3, 4 * sizeof (unsigned short)); + } + + row0 += 4; + row1 += 4; + row2 += 4; + row3 += 4; + + // + // Compress the contents of array s and append the + // results to the output buffer. + // + + if (cd.pLinear) + convertFromLinear (s); + + outEnd += pack (s, (unsigned char *) outEnd, + _optFlatFields, !cd.pLinear); + } + } + } + + return outEnd - _outBuffer; +} + + +int +B44Compressor::uncompress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + // + // This function is the reverse of the compress() function, + // above. First all pixels are moved from the input buffer + // into _tmpBuffer. UINT and FLOAT channels are copied + // verbatim; HALF channels are uncompressed in blocks of + // 4x4 pixels. Then the pixels in _tmpBuffer are copied + // into the output buffer and rearranged such that the data + // for for each scan line form a contiguous block. + // + + outPtr = _outBuffer; + + if (inSize == 0) + { + return 0; + } + + int minX = range.min.x; + int maxX = min (range.max.x, _maxX); + int minY = range.min.y; + int maxY = min (range.max.y, _maxY); + + unsigned short *tmpBufferEnd = _tmpBuffer; + int i = 0; + + for (ChannelList::ConstIterator c = _channels.begin(); + c != _channels.end(); + ++c, ++i) + { + ChannelData &cd = _channelData[i]; + + cd.start = tmpBufferEnd; + cd.end = cd.start; + + cd.nx = numSamples (c.channel().xSampling, minX, maxX); + cd.ny = numSamples (c.channel().ySampling, minY, maxY); + + tmpBufferEnd += cd.nx * cd.ny * cd.size; + } + + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (cd.type != HALF) + { + // + // UINT or FLOAT channel. + // + + int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short); + + if (inSize < n) + notEnoughData(); + + memcpy (cd.start, inPtr, n); + inPtr += n; + inSize -= n; + + continue; + } + + // + // HALF channel + // + + for (int y = 0; y < cd.ny; y += 4) + { + unsigned short *row0 = cd.start + y * cd.nx; + unsigned short *row1 = row0 + cd.nx; + unsigned short *row2 = row1 + cd.nx; + unsigned short *row3 = row2 + cd.nx; + + for (int x = 0; x < cd.nx; x += 4) + { + unsigned short s[16]; + + if (inSize < 3) + notEnoughData(); + + if (((const unsigned char *)inPtr)[2] == 0xfc) + { + unpack3 ((const unsigned char *)inPtr, s); + inPtr += 3; + inSize -= 3; + } + else + { + if (inSize < 14) + notEnoughData(); + + unpack14 ((const unsigned char *)inPtr, s); + inPtr += 14; + inSize -= 14; + } + + if (cd.pLinear) + convertToLinear (s); + + int n = (x + 3 < cd.nx)? + 4 * sizeof (unsigned short) : + (cd.nx - x) * sizeof (unsigned short); + + if (y + 3 < cd.ny) + { + memcpy (row0, &s[ 0], n); + memcpy (row1, &s[ 4], n); + memcpy (row2, &s[ 8], n); + memcpy (row3, &s[12], n); + } + else + { + memcpy (row0, &s[ 0], n); + + if (y + 1 < cd.ny) + memcpy (row1, &s[ 4], n); + + if (y + 2 < cd.ny) + memcpy (row2, &s[ 8], n); + } + + row0 += 4; + row1 += 4; + row2 += 4; + row3 += 4; + } + } + } + + char *outEnd = _outBuffer; + + if (_format == XDR) + { + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + if (cd.type == HALF) + { + for (int x = cd.nx; x > 0; --x) + { + Xdr::write (outEnd, *cd.end); + ++cd.end; + } + } + else + { + int n = cd.nx * cd.size; + memcpy (outEnd, cd.end, n * sizeof (unsigned short)); + outEnd += n * sizeof (unsigned short); + cd.end += n; + } + } + } + } + else + { + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + #if defined (DEBUG) + assert (cd.type == HALF); + #endif + + if (modp (y, cd.ys) != 0) + continue; + + int n = cd.nx * cd.size; + memcpy (outEnd, cd.end, n * sizeof (unsigned short)); + outEnd += n * sizeof (unsigned short); + cd.end += n; + } + } + } + + #if defined (DEBUG) + + for (int i = 1; i < _numChans; ++i) + assert (_channelData[i-1].end == _channelData[i].start); + + assert (_channelData[_numChans-1].end == tmpBufferEnd); + + #endif + + if (inSize > 0) + tooMuchData(); + + outPtr = _outBuffer; + return outEnd - _outBuffer; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfB44Compressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,117 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_B44_COMPRESSOR_H +#define INCLUDED_IMF_B44_COMPRESSOR_H + +//----------------------------------------------------------------------------- +// +// class B44Compressor -- lossy compression of 4x4 pixel blocks +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + +class ChannelList; + + +class B44Compressor: public Compressor +{ + public: + + B44Compressor (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines, + bool optFlatFields); + + virtual ~B44Compressor (); + + virtual int numScanLines () const; + + virtual Format format () const; + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + private: + + struct ChannelData; + + int compress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int uncompress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int _maxScanLineSize; + bool _optFlatFields; + Format _format; + int _numScanLines; + unsigned short * _tmpBuffer; + char * _outBuffer; + int _numChans; + const ChannelList & _channels; + ChannelData * _channelData; + int _minX; + int _maxX; + int _maxY; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,110 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Box2iAttribute +// class Box2fAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +Box2iAttribute::staticTypeName () +{ + return "box2i"; +} + + +template <> +void +Box2iAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.min.x); + Xdr::write (os, _value.min.y); + Xdr::write (os, _value.max.x); + Xdr::write (os, _value.max.y); +} + + +template <> +void +Box2iAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.min.x); + Xdr::read (is, _value.min.y); + Xdr::read (is, _value.max.x); + Xdr::read (is, _value.max.y); +} + + +template <> +const char * +Box2fAttribute::staticTypeName () +{ + return "box2f"; +} + + +template <> +void +Box2fAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.min.x); + Xdr::write (os, _value.min.y); + Xdr::write (os, _value.max.x); + Xdr::write (os, _value.max.y); +} + + +template <> +void +Box2fAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.min.x); + Xdr::read (is, _value.min.y); + Xdr::read (is, _value.max.x); + Xdr::read (is, _value.max.y); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfBoxAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_BOX_ATTRIBUTE_H +#define INCLUDED_IMF_BOX_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class Box2iAttribute +// class Box2fAttribute +// +//----------------------------------------------------------------------------- + +#include +#include "ImathBox.h" + + +namespace Imf { + + +typedef TypedAttribute Box2iAttribute; +template <> const char *Box2iAttribute::staticTypeName (); +template <> void Box2iAttribute::writeValueTo (OStream &, int) const; +template <> void Box2iAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute Box2fAttribute; +template <> const char *Box2fAttribute::staticTypeName (); +template <> void Box2fAttribute::writeValueTo (OStream &, int) const; +template <> void Box2fAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1434 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// C interface to C++ classes Imf::RgbaOutputFile and Imf::RgbaInputFile +// +//----------------------------------------------------------------------------- + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "half.h" +#include + +using Imath::Box2i; +using Imath::Box2f; +using Imath::V2i; +using Imath::V2f; +using Imath::V3i; +using Imath::V3f; +using Imath::M33f; +using Imath::M44f; + + +namespace { + + +const int MAX_ERR_LENGTH = 1024; +char errorMessage[MAX_ERR_LENGTH]; + + +void +setErrorMessage (const std::exception &e) +{ + strncpy (errorMessage, e.what(), MAX_ERR_LENGTH - 1); + errorMessage[MAX_ERR_LENGTH - 1] = 0; +} + + +inline Imf::Header * +header (ImfHeader *hdr) +{ + return (Imf::Header *)(hdr); +} + + +inline const Imf::Header * +header (const ImfHeader *hdr) +{ + return (const Imf::Header *)(hdr); +} + + +inline Imf::RgbaOutputFile * +outfile (ImfOutputFile *out) +{ + return (Imf::RgbaOutputFile *) out; +} + + +inline const Imf::RgbaOutputFile * +outfile (const ImfOutputFile *out) +{ + return (const Imf::RgbaOutputFile *) out; +} + + +inline Imf::TiledRgbaOutputFile * +outfile (ImfTiledOutputFile *out) +{ + return (Imf::TiledRgbaOutputFile *) out; +} + + +inline const Imf::TiledRgbaOutputFile * +outfile (const ImfTiledOutputFile *out) +{ + return (const Imf::TiledRgbaOutputFile *) out; +} + + +inline Imf::RgbaInputFile * +infile (ImfInputFile *in) +{ + return (Imf::RgbaInputFile *) in; +} + + +inline const Imf::RgbaInputFile * +infile (const ImfInputFile *in) +{ + return (const Imf::RgbaInputFile *) in; +} + + +inline Imf::TiledRgbaInputFile * +infile (ImfTiledInputFile *in) +{ + return (Imf::TiledRgbaInputFile *) in; +} + + +inline const Imf::TiledRgbaInputFile * +infile (const ImfTiledInputFile *in) +{ + return (const Imf::TiledRgbaInputFile *) in; +} + + +} // namespace + + +void +ImfFloatToHalf (float f, ImfHalf *h) +{ + *h = half(f).bits(); +} + + +void +ImfFloatToHalfArray (int n, const float f[/*n*/], ImfHalf h[/*n*/]) +{ + for (int i = 0; i < n; ++i) + h[i] = half(f[i]).bits(); +} + + +float +ImfHalfToFloat (ImfHalf h) +{ + return float (*((half *)&h)); +} + + +void +ImfHalfToFloatArray (int n, const ImfHalf h[/*n*/], float f[/*n*/]) +{ + for (int i = 0; i < n; ++i) + f[i] = float (*((half *)(h + i))); +} + + +ImfHeader * +ImfNewHeader (void) +{ + try + { + return (ImfHeader *) new Imf::Header; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +void +ImfDeleteHeader (ImfHeader *hdr) +{ + delete header (hdr); +} + + +ImfHeader * +ImfCopyHeader (const ImfHeader *hdr) +{ + try + { + return (ImfHeader *) new Imf::Header (*header (hdr)); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +void +ImfHeaderSetDisplayWindow (ImfHeader *hdr, + int xMin, int yMin, + int xMax, int yMax) +{ + header(hdr)->displayWindow() = Box2i (V2i (xMin, yMin), V2i (xMax, yMax)); +} + + +void +ImfHeaderDisplayWindow (const ImfHeader *hdr, + int *xMin, int *yMin, + int *xMax, int *yMax) +{ + const Box2i dw = header(hdr)->displayWindow(); + *xMin = dw.min.x; + *yMin = dw.min.y; + *xMax = dw.max.x; + *yMax = dw.max.y; +} + + +void +ImfHeaderSetDataWindow (ImfHeader *hdr, + int xMin, int yMin, + int xMax, int yMax) +{ + header(hdr)->dataWindow() = Box2i (V2i (xMin, yMin), V2i (xMax, yMax)); +} + + +void +ImfHeaderDataWindow (const ImfHeader *hdr, + int *xMin, int *yMin, + int *xMax, int *yMax) +{ + const Box2i dw = header(hdr)->dataWindow(); + *xMin = dw.min.x; + *yMin = dw.min.y; + *xMax = dw.max.x; + *yMax = dw.max.y; +} + + +void +ImfHeaderSetPixelAspectRatio (ImfHeader *hdr, float pixelAspectRatio) +{ + header(hdr)->pixelAspectRatio() = pixelAspectRatio; +} + + +float +ImfHeaderPixelAspectRatio (const ImfHeader *hdr) +{ + return header(hdr)->pixelAspectRatio(); +} + + +void +ImfHeaderSetScreenWindowCenter (ImfHeader *hdr, float x, float y) +{ + header(hdr)->screenWindowCenter() = V2f (x, y); +} + + +void +ImfHeaderScreenWindowCenter (const ImfHeader *hdr, float *x, float *y) +{ + const V2i &swc = header(hdr)->screenWindowCenter(); + *x = swc.x; + *y = swc.y; +} + + +void +ImfHeaderSetScreenWindowWidth (ImfHeader *hdr, float width) +{ + header(hdr)->screenWindowWidth() = width; +} + + +float +ImfHeaderScreenWindowWidth (const ImfHeader *hdr) +{ + return header(hdr)->screenWindowWidth(); +} + + +void +ImfHeaderSetLineOrder (ImfHeader *hdr, int lineOrder) +{ + header(hdr)->lineOrder() = Imf::LineOrder (lineOrder); +} + + +int +ImfHeaderLineOrder (const ImfHeader *hdr) +{ + return header(hdr)->lineOrder(); +} + + +void +ImfHeaderSetCompression (ImfHeader *hdr, int compression) +{ + header(hdr)->compression() = Imf::Compression (compression); +} + + +int +ImfHeaderCompression (const ImfHeader *hdr) +{ + return header(hdr)->compression(); +} + + +int +ImfHeaderSetIntAttribute (ImfHeader *hdr, const char name[], int value) +{ + try + { + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::IntAttribute (value)); + } + else + { + header(hdr)->typedAttribute(name).value() = + value; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderIntAttribute (const ImfHeader *hdr, const char name[], int *value) +{ + try + { + *value = header(hdr)->typedAttribute(name).value(); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetFloatAttribute (ImfHeader *hdr, const char name[], float value) +{ + try + { + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::FloatAttribute (value)); + } + else + { + header(hdr)->typedAttribute(name).value() = + value; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetDoubleAttribute (ImfHeader *hdr, const char name[], double value) +{ + try + { + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::DoubleAttribute (value)); + } + else + { + header(hdr)->typedAttribute(name).value() = + value; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderFloatAttribute (const ImfHeader *hdr, const char name[], float *value) +{ + try + { + *value = header(hdr)->typedAttribute(name).value(); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderDoubleAttribute (const ImfHeader *hdr, + const char name[], + double *value) +{ + try + { + *value = header(hdr)-> + typedAttribute(name).value(); + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetStringAttribute (ImfHeader *hdr, + const char name[], + const char value[]) +{ + try + { + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::StringAttribute (value)); + } + else + { + header(hdr)->typedAttribute(name).value() = + value; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderStringAttribute (const ImfHeader *hdr, + const char name[], + const char **value) +{ + try + { + *value = header(hdr)-> + typedAttribute(name).value().c_str(); + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetBox2iAttribute (ImfHeader *hdr, + const char name[], + int xMin, int yMin, + int xMax, int yMax) +{ + try + { + Box2i box (V2i (xMin, yMin), V2i (xMax, yMax)); + + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::Box2iAttribute (box)); + } + else + { + header(hdr)->typedAttribute(name).value() = + box; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderBox2iAttribute (const ImfHeader *hdr, + const char name[], + int *xMin, int *yMin, + int *xMax, int *yMax) +{ + try + { + const Box2i &box = + header(hdr)->typedAttribute(name).value(); + + *xMin = box.min.x; + *yMin = box.min.y; + *xMax = box.max.x; + *yMax = box.max.y; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetBox2fAttribute (ImfHeader *hdr, + const char name[], + float xMin, float yMin, + float xMax, float yMax) +{ + try + { + Box2f box (V2f (xMin, yMin), V2f (xMax, yMax)); + + if (header(hdr)->find(name) == header(hdr)->end()) + { + header(hdr)->insert (name, Imf::Box2fAttribute (box)); + } + else + { + header(hdr)->typedAttribute(name).value() = + box; + } + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderBox2fAttribute (const ImfHeader *hdr, + const char name[], + float *xMin, float *yMin, + float *xMax, float *yMax) +{ + try + { + const Box2f &box = + header(hdr)->typedAttribute(name).value(); + + *xMin = box.min.x; + *yMin = box.min.y; + *xMax = box.max.x; + *yMax = box.max.y; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetV2iAttribute (ImfHeader *hdr, + const char name[], + int x, int y) +{ + try + { + V2i v (x, y); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::V2iAttribute (v)); + else + header(hdr)->typedAttribute(name).value() = v; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderV2iAttribute (const ImfHeader *hdr, + const char name[], + int *x, int *y) +{ + try + { + const V2i &v = + header(hdr)->typedAttribute(name).value(); + + *x = v.x; + *y = v.y; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetV2fAttribute (ImfHeader *hdr, + const char name[], + float x, float y) +{ + try + { + V2f v (x, y); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::V2fAttribute (v)); + else + header(hdr)->typedAttribute(name).value() = v; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderV2fAttribute (const ImfHeader *hdr, + const char name[], + float *x, float *y) +{ + try + { + const V2f &v = + header(hdr)->typedAttribute(name).value(); + + *x = v.x; + *y = v.y; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetV3iAttribute (ImfHeader *hdr, + const char name[], + int x, int y, int z) +{ + try + { + V3i v (x, y, z); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::V3iAttribute (v)); + else + header(hdr)->typedAttribute(name).value() = v; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderV3iAttribute (const ImfHeader *hdr, + const char name[], + int *x, int *y, int *z) +{ + try + { + const V3i &v = + header(hdr)->typedAttribute(name).value(); + + *x = v.x; + *y = v.y; + *z = v.z; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetV3fAttribute (ImfHeader *hdr, + const char name[], + float x, float y, float z) +{ + try + { + V3f v (x, y, z); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::V3fAttribute (v)); + else + header(hdr)->typedAttribute(name).value() = v; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderV3fAttribute (const ImfHeader *hdr, + const char name[], + float *x, float *y, float *z) +{ + try + { + const V3f &v = + header(hdr)->typedAttribute(name).value(); + + *x = v.x; + *y = v.y; + *z = v.z; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetM33fAttribute (ImfHeader *hdr, + const char name[], + const float m[3][3]) +{ + try + { + M33f m3 (m); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::M33fAttribute (m3)); + else + header(hdr)->typedAttribute(name).value() = m3; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderM33fAttribute (const ImfHeader *hdr, + const char name[], + float m[3][3]) +{ + try + { + const M33f &m3 = + header(hdr)->typedAttribute(name).value(); + + m[0][0] = m3[0][0]; + m[0][1] = m3[0][1]; + m[0][2] = m3[0][2]; + + m[1][0] = m3[1][0]; + m[1][1] = m3[1][1]; + m[1][2] = m3[1][2]; + + m[2][0] = m3[2][0]; + m[2][1] = m3[2][1]; + m[2][2] = m3[2][2]; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderSetM44fAttribute (ImfHeader *hdr, + const char name[], + const float m[4][4]) +{ + try + { + M44f m4 (m); + + if (header(hdr)->find(name) == header(hdr)->end()) + header(hdr)->insert (name, Imf::M44fAttribute (m4)); + else + header(hdr)->typedAttribute(name).value() = m4; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfHeaderM44fAttribute (const ImfHeader *hdr, + const char name[], + float m[4][4]) +{ + try + { + const M44f &m4 = + header(hdr)->typedAttribute(name).value(); + + m[0][0] = m4[0][0]; + m[0][1] = m4[0][1]; + m[0][2] = m4[0][2]; + m[0][3] = m4[0][3]; + + m[1][0] = m4[1][0]; + m[1][1] = m4[1][1]; + m[1][2] = m4[1][2]; + m[1][3] = m4[1][3]; + + m[2][0] = m4[2][0]; + m[2][1] = m4[2][1]; + m[2][2] = m4[2][2]; + m[2][3] = m4[2][3]; + + m[3][0] = m4[3][0]; + m[3][1] = m4[3][1]; + m[3][2] = m4[3][2]; + m[3][3] = m4[3][3]; + + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +ImfOutputFile * +ImfOpenOutputFile (const char name[], const ImfHeader *hdr, int channels) +{ + try + { + return (ImfOutputFile *) new Imf::RgbaOutputFile + (name, *header(hdr), Imf::RgbaChannels (channels)); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfCloseOutputFile (ImfOutputFile *out) +{ + try + { + delete outfile (out); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfOutputSetFrameBuffer (ImfOutputFile *out, + const ImfRgba *base, + size_t xStride, + size_t yStride) +{ + try + { + outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfOutputWritePixels (ImfOutputFile *out, int numScanLines) +{ + try + { + outfile(out)->writePixels (numScanLines); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfOutputCurrentScanLine (const ImfOutputFile *out) +{ + return outfile(out)->currentScanLine(); +} + + +const ImfHeader * +ImfOutputHeader (const ImfOutputFile *out) +{ + return (const ImfHeader *) &outfile(out)->header(); +} + + +int +ImfOutputChannels (const ImfOutputFile *out) +{ + return outfile(out)->channels(); +} + + +ImfTiledOutputFile * +ImfOpenTiledOutputFile (const char name[], + const ImfHeader *hdr, + int channels, + int xSize, int ySize, + int mode, int rmode) +{ + try + { + return (ImfTiledOutputFile *) new Imf::TiledRgbaOutputFile + (name, *header(hdr), + Imf::RgbaChannels (channels), + xSize, ySize, + Imf::LevelMode (mode), + Imf::LevelRoundingMode (rmode)); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfCloseTiledOutputFile (ImfTiledOutputFile *out) +{ + try + { + delete outfile (out); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out, + const ImfRgba *base, + size_t xStride, + size_t yStride) +{ + try + { + outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledOutputWriteTile (ImfTiledOutputFile *out, + int dx, int dy, + int lx, int ly) +{ + try + { + outfile(out)->writeTile (dx, dy, lx, ly); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledOutputWriteTiles (ImfTiledOutputFile *out, + int dxMin, int dxMax, + int dyMin, int dyMax, + int lx, int ly) +{ + try + { + outfile(out)->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +const ImfHeader * +ImfTiledOutputHeader (const ImfTiledOutputFile *out) +{ + return (const ImfHeader *) &outfile(out)->header(); +} + + +int +ImfTiledOutputChannels (const ImfTiledOutputFile *out) +{ + return outfile(out)->channels(); +} + + +int +ImfTiledOutputTileXSize (const ImfTiledOutputFile *out) +{ + return outfile(out)->tileXSize(); +} + + +int +ImfTiledOutputTileYSize (const ImfTiledOutputFile *out) +{ + return outfile(out)->tileYSize(); +} + + +int +ImfTiledOutputLevelMode (const ImfTiledOutputFile *out) +{ + return outfile(out)->levelMode(); +} + + +int +ImfTiledOutputLevelRoundingMode (const ImfTiledOutputFile *out) +{ + return outfile(out)->levelRoundingMode(); +} + + +ImfInputFile * +ImfOpenInputFile (const char name[]) +{ + try + { + return (ImfInputFile *) new Imf::RgbaInputFile (name); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfCloseInputFile (ImfInputFile *in) +{ + try + { + delete infile (in); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfInputSetFrameBuffer (ImfInputFile *in, + ImfRgba *base, + size_t xStride, + size_t yStride) +{ + try + { + infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfInputReadPixels (ImfInputFile *in, int scanLine1, int scanLine2) +{ + try + { + infile(in)->readPixels (scanLine1, scanLine2); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +const ImfHeader * +ImfInputHeader (const ImfInputFile *in) +{ + return (const ImfHeader *) &infile(in)->header(); +} + + +int +ImfInputChannels (const ImfInputFile *in) +{ + return infile(in)->channels(); +} + + +const char * +ImfInputFileName (const ImfInputFile *in) +{ + return infile(in)->fileName(); +} + + +ImfTiledInputFile * +ImfOpenTiledInputFile (const char name[]) +{ + try + { + return (ImfTiledInputFile *) new Imf::TiledRgbaInputFile (name); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfCloseTiledInputFile (ImfTiledInputFile *in) +{ + try + { + delete infile (in); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in, + ImfRgba *base, + size_t xStride, + size_t yStride) +{ + try + { + infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledInputReadTile (ImfTiledInputFile *in, + int dx, int dy, + int lx, int ly) +{ + try + { + infile(in)->readTile (dx, dy, lx, ly); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +int +ImfTiledInputReadTiles (ImfTiledInputFile *in, + int dxMin, int dxMax, + int dyMin, int dyMax, + int lx, int ly) +{ + try + { + infile(in)->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); + return 1; + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +const ImfHeader * +ImfTiledInputHeader (const ImfTiledInputFile *in) +{ + return (const ImfHeader *) &infile(in)->header(); +} + + +int +ImfTiledInputChannels (const ImfTiledInputFile *in) +{ + return infile(in)->channels(); +} + + +const char * +ImfTiledInputFileName (const ImfTiledInputFile *in) +{ + return infile(in)->fileName(); +} + + +int +ImfTiledInputTileXSize (const ImfTiledInputFile *in) +{ + return infile(in)->tileXSize(); +} + + +int +ImfTiledInputTileYSize (const ImfTiledInputFile *in) +{ + return infile(in)->tileYSize(); +} + + +int +ImfTiledInputLevelMode (const ImfTiledInputFile *in) +{ + return infile(in)->levelMode(); +} + + +int +ImfTiledInputLevelRoundingMode (const ImfTiledInputFile *in) +{ + return infile(in)->levelRoundingMode(); +} + + +ImfLut * +ImfNewRound12logLut (int channels) +{ + try + { + return (ImfLut *) new Imf::RgbaLut + (Imf::round12log, Imf::RgbaChannels (channels)); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +ImfLut * +ImfNewRoundNBitLut (unsigned int n, int channels) +{ + try + { + return (ImfLut *) new Imf::RgbaLut + (Imf::roundNBit (n), Imf::RgbaChannels (channels)); + } + catch (const std::exception &e) + { + setErrorMessage (e); + return 0; + } +} + + +void +ImfDeleteLut (ImfLut *lut) +{ + delete (Imf::RgbaLut *) lut; +} + + +void +ImfApplyLut (ImfLut *lut, ImfRgba *data, int nData, int stride) +{ + ((Imf::RgbaLut *)lut)->apply ((Imf::Rgba *)data, nData, stride); +} + + +const char * +ImfErrorMessage () +{ + return errorMessage; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCRgbaFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,467 @@ +/* + +Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +Digital Ltd. LLC + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Industrial Light & Magic nor the names of +its contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef INCLUDED_IMF_C_RGBA_FILE_H +#define INCLUDED_IMF_C_RGBA_FILE_H + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Interpreting unsigned shorts as 16-bit floating point numbers +*/ + +typedef unsigned short ImfHalf; + +void ImfFloatToHalf (float f, + ImfHalf *h); + +void ImfFloatToHalfArray (int n, + const float f[/*n*/], + ImfHalf h[/*n*/]); + +float ImfHalfToFloat (ImfHalf h); + +void ImfHalfToFloatArray (int n, + const ImfHalf h[/*n*/], + float f[/*n*/]); + +/* +** RGBA pixel; memory layout must be the same as struct Imf::Rgba. +*/ + +struct ImfRgba +{ + ImfHalf r; + ImfHalf g; + ImfHalf b; + ImfHalf a; +}; + +typedef struct ImfRgba ImfRgba; + +/* +** Magic number; this must be the same as Imf::MAGIC +*/ + +#define IMF_MAGIC 20000630 + +/* +** Version number; this must be the same as Imf::EXR_VERSION +*/ + +#define IMF_VERSION_NUMBER 2 + +/* +** Line order; values must the the same as in Imf::LineOrder. +*/ + +#define IMF_INCREASING_Y 0 +#define IMF_DECREASING_Y 1 +#define IMF_RAMDOM_Y 2 + + +/* +** Compression types; values must be the same as in Imf::Compression. +*/ + +#define IMF_NO_COMPRESSION 0 +#define IMF_RLE_COMPRESSION 1 +#define IMF_ZIPS_COMPRESSION 2 +#define IMF_ZIP_COMPRESSION 3 +#define IMF_PIZ_COMPRESSION 4 +#define IMF_PXR24_COMPRESSION 5 +#define IMF_B44_COMPRESSION 6 +#define IMF_B44A_COMPRESSION 7 + + +/* +** Channels; values must be the same as in Imf::RgbaChannels. +*/ + +#define IMF_WRITE_R 0x01 +#define IMF_WRITE_G 0x02 +#define IMF_WRITE_B 0x04 +#define IMF_WRITE_A 0x08 +#define IMF_WRITE_Y 0x10 +#define IMF_WRITE_C 0x20 +#define IMF_WRITE_RGB 0x07 +#define IMF_WRITE_RGBA 0x0f +#define IMF_WRITE_YC 0x30 +#define IMF_WRITE_YA 0x18 +#define IMF_WRITE_YCA 0x38 + + +/* +** Level modes; values must be the same as in Imf::LevelMode +*/ + +#define IMF_ONE_LEVEL 0 +#define IMF_MIPMAP_LEVELS 1 +#define IMF_RIPMAP_LEVELS 2 + + +/* +** Level rounding modes; values must be the same as in Imf::LevelRoundingMode +*/ + +#define IMF_ROUND_DOWN 0 +#define IMF_ROUND_UP 1 + + +/* +** RGBA file header +*/ + +struct ImfHeader; +typedef struct ImfHeader ImfHeader; + +ImfHeader * ImfNewHeader (void); + +void ImfDeleteHeader (ImfHeader *hdr); + +ImfHeader * ImfCopyHeader (const ImfHeader *hdr); + +void ImfHeaderSetDisplayWindow (ImfHeader *hdr, + int xMin, int yMin, + int xMax, int yMax); + +void ImfHeaderDisplayWindow (const ImfHeader *hdr, + int *xMin, int *yMin, + int *xMax, int *yMax); + +void ImfHeaderSetDataWindow (ImfHeader *hdr, + int xMin, int yMin, + int xMax, int yMax); + +void ImfHeaderDataWindow (const ImfHeader *hdr, + int *xMin, int *yMin, + int *xMax, int *yMax); + +void ImfHeaderSetPixelAspectRatio (ImfHeader *hdr, + float pixelAspectRatio); + +float ImfHeaderPixelAspectRatio (const ImfHeader *hdr); + +void ImfHeaderSetScreenWindowCenter (ImfHeader *hdr, + float x, float y); + +void ImfHeaderScreenWindowCenter (const ImfHeader *hdr, + float *x, float *y); + +void ImfHeaderSetScreenWindowWidth (ImfHeader *hdr, + float width); + +float ImfHeaderScreenWindowWidth (const ImfHeader *hdr); + +void ImfHeaderSetLineOrder (ImfHeader *hdr, + int lineOrder); + +int ImfHeaderLineOrder (const ImfHeader *hdr); + +void ImfHeaderSetCompression (ImfHeader *hdr, + int compression); + +int ImfHeaderCompression (const ImfHeader *hdr); + +int ImfHeaderSetIntAttribute (ImfHeader *hdr, + const char name[], + int value); + +int ImfHeaderIntAttribute (const ImfHeader *hdr, + const char name[], + int *value); + +int ImfHeaderSetFloatAttribute (ImfHeader *hdr, + const char name[], + float value); + +int ImfHeaderSetDoubleAttribute (ImfHeader *hdr, + const char name[], + double value); + +int ImfHeaderFloatAttribute (const ImfHeader *hdr, + const char name[], + float *value); + +int ImfHeaderDoubleAttribute (const ImfHeader *hdr, + const char name[], + double *value); + +int ImfHeaderSetStringAttribute (ImfHeader *hdr, + const char name[], + const char value[]); + +int ImfHeaderStringAttribute (const ImfHeader *hdr, + const char name[], + const char **value); + +int ImfHeaderSetBox2iAttribute (ImfHeader *hdr, + const char name[], + int xMin, int yMin, + int xMax, int yMax); + +int ImfHeaderBox2iAttribute (const ImfHeader *hdr, + const char name[], + int *xMin, int *yMin, + int *xMax, int *yMax); + +int ImfHeaderSetBox2fAttribute (ImfHeader *hdr, + const char name[], + float xMin, float yMin, + float xMax, float yMax); + +int ImfHeaderBox2fAttribute (const ImfHeader *hdr, + const char name[], + float *xMin, float *yMin, + float *xMax, float *yMax); + +int ImfHeaderSetV2iAttribute (ImfHeader *hdr, + const char name[], + int x, int y); + +int ImfHeaderV2iAttribute (const ImfHeader *hdr, + const char name[], + int *x, int *y); + +int ImfHeaderSetV2fAttribute (ImfHeader *hdr, + const char name[], + float x, float y); + +int ImfHeaderV2fAttribute (const ImfHeader *hdr, + const char name[], + float *x, float *y); + +int ImfHeaderSetV3iAttribute (ImfHeader *hdr, + const char name[], + int x, int y, int z); + +int ImfHeaderV3iAttribute (const ImfHeader *hdr, + const char name[], + int *x, int *y, int *z); + +int ImfHeaderSetV3fAttribute (ImfHeader *hdr, + const char name[], + float x, float y, float z); + +int ImfHeaderV3fAttribute (const ImfHeader *hdr, + const char name[], + float *x, float *y, float *z); + +int ImfHeaderSetM33fAttribute (ImfHeader *hdr, + const char name[], + const float m[3][3]); + +int ImfHeaderM33fAttribute (const ImfHeader *hdr, + const char name[], + float m[3][3]); + +int ImfHeaderSetM44fAttribute (ImfHeader *hdr, + const char name[], + const float m[4][4]); + +int ImfHeaderM44fAttribute (const ImfHeader *hdr, + const char name[], + float m[4][4]); + +/* +** RGBA output file +*/ + +struct ImfOutputFile; +typedef struct ImfOutputFile ImfOutputFile; + +ImfOutputFile * ImfOpenOutputFile (const char name[], + const ImfHeader *hdr, + int channels); + +int ImfCloseOutputFile (ImfOutputFile *out); + +int ImfOutputSetFrameBuffer (ImfOutputFile *out, + const ImfRgba *base, + size_t xStride, + size_t yStride); + +int ImfOutputWritePixels (ImfOutputFile *out, + int numScanLines); + +int ImfOutputCurrentScanLine (const ImfOutputFile *out); + +const ImfHeader * ImfOutputHeader (const ImfOutputFile *out); + +int ImfOutputChannels (const ImfOutputFile *out); + + +/* +** Tiled RGBA output file +*/ + +struct ImfTiledOutputFile; +typedef struct ImfTiledOutputFile ImfTiledOutputFile; + +ImfTiledOutputFile * ImfOpenTiledOutputFile (const char name[], + const ImfHeader *hdr, + int channels, + int xSize, int ySize, + int mode, int rmode); + +int ImfCloseTiledOutputFile (ImfTiledOutputFile *out); + +int ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out, + const ImfRgba *base, + size_t xStride, + size_t yStride); + +int ImfTiledOutputWriteTile (ImfTiledOutputFile *out, + int dx, int dy, + int lx, int ly); + +int ImfTiledOutputWriteTiles (ImfTiledOutputFile *out, + int dxMin, int dxMax, + int dyMin, int dyMax, + int lx, int ly); + +const ImfHeader * ImfTiledOutputHeader (const ImfTiledOutputFile *out); + +int ImfTiledOutputChannels (const ImfTiledOutputFile *out); + +int ImfTiledOutputTileXSize (const ImfTiledOutputFile *out); + +int ImfTiledOutputTileYSize (const ImfTiledOutputFile *out); + +int ImfTiledOutputLevelMode (const ImfTiledOutputFile *out); +int ImfTiledOutputLevelRoundingMode + (const ImfTiledOutputFile *out); + + +/* +** RGBA input file +*/ + +struct ImfInputFile; +typedef struct ImfInputFile ImfInputFile; + +ImfInputFile * ImfOpenInputFile (const char name[]); + +int ImfCloseInputFile (ImfInputFile *in); + +int ImfInputSetFrameBuffer (ImfInputFile *in, + ImfRgba *base, + size_t xStride, + size_t yStride); + +int ImfInputReadPixels (ImfInputFile *in, + int scanLine1, + int scanLine2); + +const ImfHeader * ImfInputHeader (const ImfInputFile *in); + +int ImfInputChannels (const ImfInputFile *in); + +const char * ImfInputFileName (const ImfInputFile *in); + + +/* +** Tiled RGBA input file +*/ + +struct ImfTiledInputFile; +typedef struct ImfTiledInputFile ImfTiledInputFile; + +ImfTiledInputFile * ImfOpenTiledInputFile (const char name[]); + +int ImfCloseTiledInputFile (ImfTiledInputFile *in); + +int ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in, + ImfRgba *base, + size_t xStride, + size_t yStride); + +int ImfTiledInputReadTile (ImfTiledInputFile *in, + int dx, int dy, + int lx, int ly); + +int ImfTiledInputReadTiles (ImfTiledInputFile *in, + int dxMin, int dxMax, + int dyMin, int dyMax, + int lx, int ly); + +const ImfHeader * ImfTiledInputHeader (const ImfTiledInputFile *in); + +int ImfTiledInputChannels (const ImfTiledInputFile *in); + +const char * ImfTiledInputFileName (const ImfTiledInputFile *in); + +int ImfTiledInputTileXSize (const ImfTiledInputFile *in); + +int ImfTiledInputTileYSize (const ImfTiledInputFile *in); + +int ImfTiledInputLevelMode (const ImfTiledInputFile *in); + +int ImfTiledInputLevelRoundingMode + (const ImfTiledInputFile *in); + +/* +** Lookup tables +*/ + +struct ImfLut; +typedef struct ImfLut ImfLut; + +ImfLut * ImfNewRound12logLut (int channels); + +ImfLut * ImfNewRoundNBitLut (unsigned int n, int channels); + +void ImfDeleteLut (ImfLut *lut); + +void ImfApplyLut (ImfLut *lut, + ImfRgba *data, + int nData, + int stride); +/* +** Most recent error message +*/ + +const char * ImfErrorMessage (void); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,321 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Channel +// class ChannelList +// +//----------------------------------------------------------------------------- + +#include +#include + + +using std::string; +using std::set; + +namespace Imf { + + +Channel::Channel (PixelType t, int xs, int ys, bool pl): + type (t), + xSampling (xs), + ySampling (ys), + pLinear (pl) +{ + // empty +} + + +bool +Channel::operator == (const Channel &other) const +{ + return type == other.type && + xSampling == other.xSampling && + ySampling == other.ySampling && + pLinear == other.pLinear; +} + + +void +ChannelList::insert (const char name[], const Channel &channel) +{ + if (name[0] == 0) + THROW (Iex::ArgExc, "Image channel name cannot be an empty string."); + + _map[name] = channel; +} + + +void +ChannelList::insert (const string &name, const Channel &channel) +{ + insert (name.c_str(), channel); +} + + +Channel & +ChannelList::operator [] (const char name[]) +{ + ChannelMap::iterator i = _map.find (name); + + if (i == _map.end()) + THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\"."); + + return i->second; +} + + +const Channel & +ChannelList::operator [] (const char name[]) const +{ + ChannelMap::const_iterator i = _map.find (name); + + if (i == _map.end()) + THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\"."); + + return i->second; +} + + +Channel & +ChannelList::operator [] (const string &name) +{ + return this->operator[] (name.c_str()); +} + + +const Channel & +ChannelList::operator [] (const string &name) const +{ + return this->operator[] (name.c_str()); +} + + +Channel * +ChannelList::findChannel (const char name[]) +{ + ChannelMap::iterator i = _map.find (name); + return (i == _map.end())? 0: &i->second; +} + + +const Channel * +ChannelList::findChannel (const char name[]) const +{ + ChannelMap::const_iterator i = _map.find (name); + return (i == _map.end())? 0: &i->second; +} + + +Channel * +ChannelList::findChannel (const string &name) +{ + return findChannel (name.c_str()); +} + + +const Channel * +ChannelList::findChannel (const string &name) const +{ + return findChannel (name.c_str()); +} + + +ChannelList::Iterator +ChannelList::begin () +{ + return _map.begin(); +} + + +ChannelList::ConstIterator +ChannelList::begin () const +{ + return _map.begin(); +} + + +ChannelList::Iterator +ChannelList::end () +{ + return _map.end(); +} + + +ChannelList::ConstIterator +ChannelList::end () const +{ + return _map.end(); +} + + +ChannelList::Iterator +ChannelList::find (const char name[]) +{ + return _map.find (name); +} + + +ChannelList::ConstIterator +ChannelList::find (const char name[]) const +{ + return _map.find (name); +} + + +ChannelList::Iterator +ChannelList::find (const string &name) +{ + return find (name.c_str()); +} + + +ChannelList::ConstIterator +ChannelList::find (const string &name) const +{ + return find (name.c_str()); +} + + +void +ChannelList::layers (set &layerNames) const +{ + layerNames.clear(); + + for (ConstIterator i = begin(); i != end(); ++i) + { + string layerName = i.name(); + size_t pos = layerName.rfind ('.'); + + if (pos != string::npos && pos != 0 && pos + 1 < layerName.size()) + { + layerName.erase (pos); + layerNames.insert (layerName); + } + } +} + + +void +ChannelList::channelsInLayer (const string &layerName, + Iterator &first, + Iterator &last) +{ + channelsWithPrefix (layerName + '.', first, last); +} + + +void +ChannelList::channelsInLayer (const string &layerName, + ConstIterator &first, + ConstIterator &last) const +{ + channelsWithPrefix (layerName + '.', first, last); +} + + +void +ChannelList::channelsWithPrefix (const char prefix[], + Iterator &first, + Iterator &last) +{ + first = last = _map.lower_bound (prefix); + int n = strlen (prefix); + + while (last != Iterator (_map.end()) && + strncmp (last.name(), prefix, n) <= 0) + { + ++last; + } +} + + +void +ChannelList::channelsWithPrefix (const char prefix[], + ConstIterator &first, + ConstIterator &last) const +{ + first = last = _map.lower_bound (prefix); + int n = strlen (prefix); + + while (last != ConstIterator (_map.end()) && + strncmp (last.name(), prefix, n) <= 0) + { + ++last; + } +} + + +void +ChannelList::channelsWithPrefix (const string &prefix, + Iterator &first, + Iterator &last) +{ + return channelsWithPrefix (prefix.c_str(), first, last); +} + + +void +ChannelList::channelsWithPrefix (const string &prefix, + ConstIterator &first, + ConstIterator &last) const +{ + return channelsWithPrefix (prefix.c_str(), first, last); +} + + +bool +ChannelList::operator == (const ChannelList &other) const +{ + ConstIterator i = begin(); + ConstIterator j = other.begin(); + + while (i != end() && j != other.end()) + { + if (!(i.channel() == j.channel())) + return false; + + ++i; + ++j; + } + + return i == end() && j == other.end(); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelList.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,433 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_CHANNEL_LIST_H +#define INCLUDED_IMF_CHANNEL_LIST_H + +//----------------------------------------------------------------------------- +// +// class Channel +// class ChannelList +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + + +namespace Imf { + + +struct Channel +{ + //------------------------------ + // Data type; see ImfPixelType.h + //------------------------------ + + PixelType type; + + + //-------------------------------------------- + // Subsampling: pixel (x, y) is present in the + // channel only if + // + // x % xSampling == 0 && y % ySampling == 0 + // + //-------------------------------------------- + + int xSampling; + int ySampling; + + + //-------------------------------------------------------------- + // Hint to lossy compression methods that indicates whether + // human perception of the quantity represented by this channel + // is closer to linear or closer to logarithmic. Compression + // methods may optimize image quality by adjusting pixel data + // quantization acording to this hint. + // For example, perception of red, green, blue and luminance is + // approximately logarithmic; the difference between 0.1 and 0.2 + // is perceived to be roughly the same as the difference between + // 1.0 and 2.0. Perception of chroma coordinates tends to be + // closer to linear than logarithmic; the difference between 0.1 + // and 0.2 is perceived to be roughly the same as the difference + // between 1.0 and 1.1. + //-------------------------------------------------------------- + + bool pLinear; + + + //------------ + // Constructor + //------------ + + Channel (PixelType type = HALF, + int xSampling = 1, + int ySampling = 1, + bool pLinear = false); + + + //------------ + // Operator == + //------------ + + bool operator == (const Channel &other) const; +}; + + +class ChannelList +{ + public: + + //-------------- + // Add a channel + //-------------- + + void insert (const char name[], + const Channel &channel); + + void insert (const std::string &name, + const Channel &channel); + + //------------------------------------------------------------------ + // Access to existing channels: + // + // [n] Returns a reference to the channel with name n. + // If no channel with name n exists, an Iex::ArgExc + // is thrown. + // + // findChannel(n) Returns a pointer to the channel with name n, + // or 0 if no channel with name n exists. + // + //------------------------------------------------------------------ + + Channel & operator [] (const char name[]); + const Channel & operator [] (const char name[]) const; + + Channel & operator [] (const std::string &name); + const Channel & operator [] (const std::string &name) const; + + Channel * findChannel (const char name[]); + const Channel * findChannel (const char name[]) const; + + Channel * findChannel (const std::string &name); + const Channel * findChannel (const std::string &name) const; + + + //------------------------------------------- + // Iterator-style access to existing channels + //------------------------------------------- + + typedef std::map ChannelMap; + + class Iterator; + class ConstIterator; + + Iterator begin (); + ConstIterator begin () const; + + Iterator end (); + ConstIterator end () const; + + Iterator find (const char name[]); + ConstIterator find (const char name[]) const; + + Iterator find (const std::string &name); + ConstIterator find (const std::string &name) const; + + + //----------------------------------------------------------------- + // Support for image layers: + // + // In an image file with many channels it is sometimes useful to + // group the channels into "layers", that is, into sets of channels + // that logically belong together. Grouping channels into layers + // is done using a naming convention: channel C in layer L is + // called "L.C". + // + // For example, a computer graphic image may contain separate + // R, G and B channels for light that originated at each of + // several different virtual light sources. The channels in + // this image might be called "light1.R", "light1.G", "light1.B", + // "light2.R", "light2.G", "light2.B", etc. + // + // Note that this naming convention allows layers to be nested; + // for example, "light1.specular.R" identifies the "R" channel + // in the "specular" sub-layer of layer "light1". + // + // Channel names that don't contain a "." or that contain a + // "." only at the beginning or at the end are not considered + // to be part of any layer. + // + // layers(lns) sorts the channels in this ChannelList + // into layers and stores the names of + // all layers, sorted alphabetically, + // into string set lns. + // + // channelsInLayer(ln,f,l) stores a pair of iterators in f and l + // such that the loop + // + // for (ConstIterator i = f; i != l; ++i) + // ... + // + // iterates over all channels in layer ln. + // channelsInLayer (ln, l, p) calls + // channelsWithPrefix (ln + ".", l, p). + // + //----------------------------------------------------------------- + + void layers (std::set &layerNames) const; + + void channelsInLayer (const std::string &layerName, + Iterator &first, + Iterator &last); + + void channelsInLayer (const std::string &layerName, + ConstIterator &first, + ConstIterator &last) const; + + + //------------------------------------------------------------------- + // Find all channels whose name begins with a given prefix: + // + // channelsWithPrefix(p,f,l) stores a pair of iterators in f and l + // such that the following loop iterates over all channels whose name + // begins with string p: + // + // for (ConstIterator i = f; i != l; ++i) + // ... + // + //------------------------------------------------------------------- + + void channelsWithPrefix (const char prefix[], + Iterator &first, + Iterator &last); + + void channelsWithPrefix (const char prefix[], + ConstIterator &first, + ConstIterator &last) const; + + void channelsWithPrefix (const std::string &prefix, + Iterator &first, + Iterator &last); + + void channelsWithPrefix (const std::string &prefix, + ConstIterator &first, + ConstIterator &last) const; + + //------------ + // Operator == + //------------ + + bool operator == (const ChannelList &other) const; + + private: + + ChannelMap _map; +}; + + +//---------- +// Iterators +//---------- + +class ChannelList::Iterator +{ + public: + + Iterator (); + Iterator (const ChannelList::ChannelMap::iterator &i); + + Iterator & operator ++ (); + Iterator operator ++ (int); + + const char * name () const; + Channel & channel () const; + + private: + + friend class ChannelList::ConstIterator; + + ChannelList::ChannelMap::iterator _i; +}; + + +class ChannelList::ConstIterator +{ + public: + + ConstIterator (); + ConstIterator (const ChannelList::ChannelMap::const_iterator &i); + ConstIterator (const ChannelList::Iterator &other); + + ConstIterator & operator ++ (); + ConstIterator operator ++ (int); + + const char * name () const; + const Channel & channel () const; + + private: + + friend bool operator == (const ConstIterator &, const ConstIterator &); + friend bool operator != (const ConstIterator &, const ConstIterator &); + + ChannelList::ChannelMap::const_iterator _i; +}; + + +//----------------- +// Inline Functions +//----------------- + +inline +ChannelList::Iterator::Iterator (): _i() +{ + // empty +} + + +inline +ChannelList::Iterator::Iterator (const ChannelList::ChannelMap::iterator &i): + _i (i) +{ + // empty +} + + +inline ChannelList::Iterator & +ChannelList::Iterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline ChannelList::Iterator +ChannelList::Iterator::operator ++ (int) +{ + Iterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +ChannelList::Iterator::name () const +{ + return *_i->first; +} + + +inline Channel & +ChannelList::Iterator::channel () const +{ + return _i->second; +} + + +inline +ChannelList::ConstIterator::ConstIterator (): _i() +{ + // empty +} + +inline +ChannelList::ConstIterator::ConstIterator + (const ChannelList::ChannelMap::const_iterator &i): _i (i) +{ + // empty +} + + +inline +ChannelList::ConstIterator::ConstIterator (const ChannelList::Iterator &other): + _i (other._i) +{ + // empty +} + +inline ChannelList::ConstIterator & +ChannelList::ConstIterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline ChannelList::ConstIterator +ChannelList::ConstIterator::operator ++ (int) +{ + ConstIterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +ChannelList::ConstIterator::name () const +{ + return *_i->first; +} + +inline const Channel & +ChannelList::ConstIterator::channel () const +{ + return _i->second; +} + + +inline bool +operator == (const ChannelList::ConstIterator &x, + const ChannelList::ConstIterator &y) +{ + return x._i == y._i; +} + + +inline bool +operator != (const ChannelList::ConstIterator &x, + const ChannelList::ConstIterator &y) +{ + return !(x == y); +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,145 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class ChannelListAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + +namespace { + +template +void checkIsNullTerminated (const char (&str)[N], const char *what) +{ + for (int i = 0; i < N; ++i) { + if (str[i] == '\0') + return; + } + std::stringstream s; + s << "Invalid " << what << ": it is more than " << (N - 1) + << " characters long."; + throw Iex::InputExc(s); +} + +} // namespace + +template <> +const char * +ChannelListAttribute::staticTypeName () +{ + return "chlist"; +} + + +template <> +void +ChannelListAttribute::writeValueTo (OStream &os, int) const +{ + for (ChannelList::ConstIterator i = _value.begin(); + i != _value.end(); + ++i) + { + // + // Write name + // + + Xdr::write (os, i.name()); + + // + // Write Channel struct + // + + Xdr::write (os, int (i.channel().type)); + Xdr::write (os, i.channel().pLinear); + Xdr::pad (os, 3); + Xdr::write (os, i.channel().xSampling); + Xdr::write (os, i.channel().ySampling); + } + + // + // Write end of list marker + // + + Xdr::write (os, ""); +} + + +template <> +void +ChannelListAttribute::readValueFrom (IStream &is, int, int) +{ + while (true) + { + // + // Read name; zero length name means end of channel list + // + + char name[Name::SIZE]; + Xdr::read (is, Name::MAX_LENGTH, name); + + if (name[0] == 0) + break; + + checkIsNullTerminated (name, "channel name"); + + // + // Read Channel struct + // + + int type; + bool pLinear; + int xSampling; + int ySampling; + + Xdr::read (is, type); + Xdr::read (is, pLinear); + Xdr::skip (is, 3); + Xdr::read (is, xSampling); + Xdr::read (is, ySampling); + + _value.insert + (name, Channel (PixelType (type), xSampling, ySampling, pLinear)); + } +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChannelListAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,67 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_CHANNEL_LIST_ATTRIBUTE_H +#define INCLUDED_IMF_CHANNEL_LIST_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class ChannelListAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute ChannelListAttribute; +template <> const char *ChannelListAttribute::staticTypeName (); +template <> void ChannelListAttribute::writeValueTo (OStream &, int) const; +template <> void ChannelListAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,161 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2009, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMF_CHECKED_ARITHMETIC_H +#define INCLUDED_IMF_CHECKED_ARITHMETIC_H + +//----------------------------------------------------------------------------- +// +// Integer arithmetic operations that throw exceptions +// on overflow, underflow or division by zero. +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { + +template struct StaticAssertionFailed; +template <> struct StaticAssertionFailed {}; + +#define IMF_STATIC_ASSERT(x) \ + do {StaticAssertionFailed staticAssertionFailed;} while (false) + + +template +T +uiMult (T a, T b) +{ + // + // Unsigned integer multiplication + // + + IMF_STATIC_ASSERT (!std::numeric_limits::is_signed && + std::numeric_limits::is_integer); + + if (a > 0 && b > std::numeric_limits::max() / a) + throw Iex::OverflowExc ("Integer multiplication overflow."); + + return a * b; +} + + +template +T +uiDiv (T a, T b) +{ + // + // Unsigned integer division + // + + IMF_STATIC_ASSERT (!std::numeric_limits::is_signed && + std::numeric_limits::is_integer); + + if (b == 0) + throw Iex::DivzeroExc ("Integer division by zero."); + + return a / b; +} + + +template +T +uiAdd (T a, T b) +{ + // + // Unsigned integer addition + // + + IMF_STATIC_ASSERT (!std::numeric_limits::is_signed && + std::numeric_limits::is_integer); + + if (a > std::numeric_limits::max() - b) + throw Iex::OverflowExc ("Integer addition overflow."); + + return a + b; +} + + +template +T +uiSub (T a, T b) +{ + // + // Unsigned integer subtraction + // + + IMF_STATIC_ASSERT (!std::numeric_limits::is_signed && + std::numeric_limits::is_integer); + + if (a < b) + throw Iex::UnderflowExc ("Integer subtraction underflow."); + + return a - b; +} + + +template +size_t +checkArraySize (T n, size_t s) +{ + // + // Verify that the size, in bytes, of an array with n elements + // of size s can be computed without overflowing: + // + // If computing + // + // size_t (n) * s + // + // would overflow, then throw an Iex::OverflowExc exception. + // Otherwise return + // + // size_t (n). + // + + IMF_STATIC_ASSERT (!std::numeric_limits::is_signed && + std::numeric_limits::is_integer); + + IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t)); + + if (size_t (n) > std::numeric_limits::max() / s) + throw Iex::OverflowExc ("Integer multiplication overflow."); + + return size_t (n); +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// CIE (x,y) chromaticities, and conversions between +// RGB tiples and CIE XYZ tristimulus values. +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +Chromaticities::Chromaticities (const Imath::V2f &red, + const Imath::V2f &green, + const Imath::V2f &blue, + const Imath::V2f &white) +: + red (red), + green (green), + blue (blue), + white (white) +{ + // empty +} + + +Imath::M44f +RGBtoXYZ (const Chromaticities chroma, float Y) +{ + // + // For an explanation of how the color conversion matrix is derived, + // see Roy Hall, "Illumination and Color in Computer Generated Imagery", + // Springer-Verlag, 1989, chapter 3, "Perceptual Response"; and + // Charles A. Poynton, "A Technical Introduction to Digital Video", + // John Wiley & Sons, 1996, chapter 7, "Color science for video". + // + + // + // X and Z values of RGB value (1, 1, 1), or "white" + // + + float X = chroma.white.x * Y / chroma.white.y; + float Z = (1 - chroma.white.x - chroma.white.y) * Y / chroma.white.y; + + // + // Scale factors for matrix rows + // + + float d = chroma.red.x * (chroma.blue.y - chroma.green.y) + + chroma.blue.x * (chroma.green.y - chroma.red.y) + + chroma.green.x * (chroma.red.y - chroma.blue.y); + + float Sr = (X * (chroma.blue.y - chroma.green.y) - + chroma.green.x * (Y * (chroma.blue.y - 1) + + chroma.blue.y * (X + Z)) + + chroma.blue.x * (Y * (chroma.green.y - 1) + + chroma.green.y * (X + Z))) / d; + + float Sg = (X * (chroma.red.y - chroma.blue.y) + + chroma.red.x * (Y * (chroma.blue.y - 1) + + chroma.blue.y * (X + Z)) - + chroma.blue.x * (Y * (chroma.red.y - 1) + + chroma.red.y * (X + Z))) / d; + + float Sb = (X * (chroma.green.y - chroma.red.y) - + chroma.red.x * (Y * (chroma.green.y - 1) + + chroma.green.y * (X + Z)) + + chroma.green.x * (Y * (chroma.red.y - 1) + + chroma.red.y * (X + Z))) / d; + + // + // Assemble the matrix + // + + Imath::M44f M; + + M[0][0] = Sr * chroma.red.x; + M[0][1] = Sr * chroma.red.y; + M[0][2] = Sr * (1 - chroma.red.x - chroma.red.y); + + M[1][0] = Sg * chroma.green.x; + M[1][1] = Sg * chroma.green.y; + M[1][2] = Sg * (1 - chroma.green.x - chroma.green.y); + + M[2][0] = Sb * chroma.blue.x; + M[2][1] = Sb * chroma.blue.y; + M[2][2] = Sb * (1 - chroma.blue.x - chroma.blue.y); + + return M; +} + + +Imath::M44f +XYZtoRGB (const Chromaticities chroma, float Y) +{ + return RGBtoXYZ (chroma, Y).inverse(); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticities.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_CHROMATICITIES_H +#define INCLUDED_IMF_CHROMATICITIES_H + +//----------------------------------------------------------------------------- +// +// CIE (x,y) chromaticities, and conversions between +// RGB tiples and CIE XYZ tristimulus values. +// +//----------------------------------------------------------------------------- + +#include "ImathVec.h" +#include "ImathMatrix.h" + +namespace Imf { + + +struct Chromaticities +{ + //----------------------------------------------- + // The CIE x and y coordinates of the RGB triples + // (1,0,0), (0,1,0), (0,0,1) and (1,1,1). + //----------------------------------------------- + + Imath::V2f red; + Imath::V2f green; + Imath::V2f blue; + Imath::V2f white; + + //-------------------------------------------- + // Default constructor produces chromaticities + // according to Rec. ITU-R BT.709-3 + //-------------------------------------------- + + Chromaticities (const Imath::V2f &red = Imath::V2f (0.6400f, 0.3300f), + const Imath::V2f &green = Imath::V2f (0.3000f, 0.6000f), + const Imath::V2f &blue = Imath::V2f (0.1500f, 0.0600f), + const Imath::V2f &white = Imath::V2f (0.3127f, 0.3290f)); +}; + + +// +// Conversions between RGB and CIE XYZ +// +// RGB to XYZ: +// +// Given a set of chromaticities, c, and the luminance, Y, of the RGB +// triple (1,1,1), or "white", RGBtoXYZ(c,Y) computes a matrix, M, so +// that multiplying an RGB value, v, with M produces an equivalent +// XYZ value, w. (w == v * M) +// +// If we define that +// +// (Xr, Yr, Zr) == (1, 0, 0) * M +// (Xg, Yg, Zg) == (0, 1, 0) * M +// (Xb, Yb, Zb) == (0, 0, 1) * M +// (Xw, Yw, Zw) == (1, 1, 1) * M, +// +// then the following statements are true: +// +// Xr / (Xr + Yr + Zr) == c.red.x +// Yr / (Xr + Yr + Zr) == c.red.y +// +// Xg / (Xg + Yg + Zg) == c.red.x +// Yg / (Xg + Yg + Zg) == c.red.y +// +// Xb / (Xb + Yb + Zb) == c.red.x +// Yb / (Xb + Yb + Zb) == c.red.y +// +// Xw / (Xw + Yw + Zw) == c.red.x +// Yw / (Xw + Yw + Zw) == c.red.y +// +// Yw == Y. +// +// XYZ to RGB: +// +// YYZtoRGB(c,Y) returns RGBtoXYZ(c,Y).inverse(). +// + +Imath::M44f RGBtoXYZ (const Chromaticities chroma, float Y); +Imath::M44f XYZtoRGB (const Chromaticities chroma, float Y); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class ChromaticitiesAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +ChromaticitiesAttribute::staticTypeName () +{ + return "chromaticities"; +} + + +template <> +void +ChromaticitiesAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.red.x); + Xdr::write (os, _value.red.y); + Xdr::write (os, _value.green.x); + Xdr::write (os, _value.green.y); + Xdr::write (os, _value.blue.x); + Xdr::write (os, _value.blue.y); + Xdr::write (os, _value.white.x); + Xdr::write (os, _value.white.y); +} + + +template <> +void +ChromaticitiesAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.red.x); + Xdr::read (is, _value.red.y); + Xdr::read (is, _value.green.x); + Xdr::read (is, _value.green.y); + Xdr::read (is, _value.blue.x); + Xdr::read (is, _value.blue.y); + Xdr::read (is, _value.white.x); + Xdr::read (is, _value.white.y); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,72 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_CHROMATICITIES_ATTRIBUTE_H +#define INCLUDED_IMF_CHROMATICITIES_ATTRIBUTE_H + + +//----------------------------------------------------------------------------- +// +// class ChromaticitiesAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute ChromaticitiesAttribute; + +template <> +const char *ChromaticitiesAttribute::staticTypeName (); + +template <> +void ChromaticitiesAttribute::writeValueTo (OStream &, int) const; + +template <> +void ChromaticitiesAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompression.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompression.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompression.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompression.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_COMPRESSION_H +#define INCLUDED_IMF_COMPRESSION_H + +//----------------------------------------------------------------------------- +// +// enum Compression +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +enum Compression +{ + NO_COMPRESSION = 0, // no compression + + RLE_COMPRESSION = 1, // run length encoding + + ZIPS_COMPRESSION = 2, // zlib compression, one scan line at a time + + ZIP_COMPRESSION = 3, // zlib compression, in blocks of 16 scan lines + + PIZ_COMPRESSION = 4, // piz-based wavelet compression + + PXR24_COMPRESSION = 5, // lossy 24-bit float compression + + B44_COMPRESSION = 6, // lossy 4-by-4 pixel block compression, + // fixed compression rate + + B44A_COMPRESSION = 7, // lossy 4-by-4 pixel block compression, + // flat fields are compressed more + + NUM_COMPRESSION_METHODS // number of different compression methods +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class CompressionAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +CompressionAttribute::staticTypeName () +{ + return "compression"; +} + + +template <> +void +CompressionAttribute::writeValueTo (OStream &os, int) const +{ + unsigned char tmp = _value; + Xdr::write (os, tmp); +} + + +template <> +void +CompressionAttribute::readValueFrom (IStream &is, int, int) +{ + unsigned char tmp; + Xdr::read (is, tmp); + _value = Compression (tmp); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_COMPRESSION_ATTRIBUTE_H +#define INCLUDED_IMF_COMPRESSION_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class CompressionAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute CompressionAttribute; +template <> const char *CompressionAttribute::staticTypeName (); +template <> void CompressionAttribute::writeValueTo (OStream &, int) const; +template <> void CompressionAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,192 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Compressor +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include + +namespace Imf { + +using Imath::Box2i; + + +Compressor::Compressor (const Header &hdr): _header (hdr) {} + + +Compressor::~Compressor () {} + + +Compressor::Format +Compressor::format () const +{ + return XDR; +} + + +int +Compressor::compressTile (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + return compress (inPtr, inSize, range.min.y, outPtr); +} + + +int +Compressor::uncompressTile (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + return uncompress (inPtr, inSize, range.min.y, outPtr); +} + + +bool +isValidCompression (Compression c) +{ + switch (c) + { + case NO_COMPRESSION: + case RLE_COMPRESSION: + case ZIPS_COMPRESSION: + case ZIP_COMPRESSION: + case PIZ_COMPRESSION: + case PXR24_COMPRESSION: + case B44_COMPRESSION: + case B44A_COMPRESSION: + + return true; + + default: + + return false; + } +} + + +Compressor * +newCompressor (Compression c, size_t maxScanLineSize, const Header &hdr) +{ + switch (c) + { + case RLE_COMPRESSION: + + return new RleCompressor (hdr, maxScanLineSize); + + case ZIPS_COMPRESSION: + + return new ZipCompressor (hdr, maxScanLineSize, 1); + + case ZIP_COMPRESSION: + + return new ZipCompressor (hdr, maxScanLineSize, 16); + + case PIZ_COMPRESSION: + + return new PizCompressor (hdr, maxScanLineSize, 32); + + case PXR24_COMPRESSION: + + return new Pxr24Compressor (hdr, maxScanLineSize, 16); + + case B44_COMPRESSION: + + return new B44Compressor (hdr, maxScanLineSize, 32, false); + + case B44A_COMPRESSION: + + return new B44Compressor (hdr, maxScanLineSize, 32, true); + + default: + + return 0; + } +} + + +Compressor * +newTileCompressor (Compression c, + size_t tileLineSize, + size_t numTileLines, + const Header &hdr) +{ + switch (c) + { + case RLE_COMPRESSION: + + return new RleCompressor (hdr, uiMult (tileLineSize, numTileLines)); + + case ZIPS_COMPRESSION: + case ZIP_COMPRESSION: + + return new ZipCompressor (hdr, tileLineSize, numTileLines); + + case PIZ_COMPRESSION: + + return new PizCompressor (hdr, tileLineSize, numTileLines); + + case PXR24_COMPRESSION: + + return new Pxr24Compressor (hdr, tileLineSize, numTileLines); + + case B44_COMPRESSION: + + return new B44Compressor (hdr, tileLineSize, numTileLines, false); + + case B44A_COMPRESSION: + + return new B44Compressor (hdr, tileLineSize, numTileLines, true); + + default: + + return 0; + } +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfCompressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,252 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_COMPRESSOR_H +#define INCLUDED_IMF_COMPRESSOR_H + +//----------------------------------------------------------------------------- +// +// class Compressor +// +//----------------------------------------------------------------------------- + +#include +#include "ImathBox.h" +#include + +namespace Imf { + +class Header; + + +class Compressor +{ + public: + + //--------------------------------------------- + // Constructor -- hdr is the header of the file + // that will be compressed or uncompressed + //--------------------------------------------- + + Compressor (const Header &hdr); + + + //----------- + // Destructor + //----------- + + virtual ~Compressor (); + + + //---------------------------------------------- + // Maximum number of scan lines processed by + // a single call to compress() and uncompress(). + //---------------------------------------------- + + virtual int numScanLines () const = 0; + + + //-------------------------------------------- + // Format of the pixel data read and written + // by the compress() and uncompress() methods. + // The default implementation of format() + // returns XDR. + //-------------------------------------------- + + enum Format + { + NATIVE, // the machine's native format + XDR // Xdr format + }; + + virtual Format format () const; + + + //---------------------------- + // Access to the file's header + //---------------------------- + + const Header & header () const {return _header;} + + + //------------------------------------------------------------------------- + // Compress an array of bytes that represents the contents of up to + // numScanLines() scan lines: + // + // inPtr Input buffer (uncompressed data). + // + // inSize Number of bytes in the input buffer + // + // minY Minimum y coordinate of the scan lines to + // be compressed + // + // outPtr Pointer to output buffer + // + // return value Size of compressed data in output buffer + // + // Arrangement of uncompressed pixel data in the input buffer: + // + // Before calling + // + // compress (buf, size, minY, ...); + // + // the InputFile::writePixels() method gathers pixel data from the + // frame buffer, fb, and places them in buffer buf, like this: + // + // char *endOfBuf = buf; + // + // for (int y = minY; + // y <= min (minY + numScanLines() - 1, header().dataWindow().max.y); + // ++y) + // { + // for (ChannelList::ConstIterator c = header().channels().begin(); + // c != header().channels().end(); + // ++c) + // { + // if (modp (y, c.channel().ySampling) != 0) + // continue; + // + // for (int x = header().dataWindow().min.x; + // x <= header().dataWindow().max.x; + // ++x) + // { + // if (modp (x, c.channel().xSampling) != 0) + // continue; + // + // Xdr::write (endOfBuf, fb.pixel (c, x, y)); + // } + // } + // } + // + // int size = endOfBuf - buf; + // + //------------------------------------------------------------------------- + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) = 0; + + virtual int compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + //------------------------------------------------------------------------- + // Uncompress an array of bytes that has been compressed by compress(): + // + // inPtr Input buffer (compressed data). + // + // inSize Number of bytes in the input buffer + // + // minY Minimum y coordinate of the scan lines to + // be uncompressed + // + // outPtr Pointer to output buffer + // + // return value Size of uncompressed data in output buffer + // + //------------------------------------------------------------------------- + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) = 0; + + virtual int uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + private: + + const Header & _header; +}; + + +//-------------------------------------- +// Test if c is a valid compression type +//-------------------------------------- + +bool isValidCompression (Compression c); + + +//----------------------------------------------------------------- +// Construct a Compressor for compression type c: +// +// maxScanLineSize Maximum number of bytes per uncompressed +// scan line. +// +// header Header of the input or output file whose +// pixels will be compressed or uncompressed. +// +// return value A pointer to a new Compressor object (it +// is the caller's responsibility to delete +// the object), or 0 (if c is NO_COMPRESSION). +// +//----------------------------------------------------------------- + +Compressor * newCompressor (Compression c, + size_t maxScanLineSize, + const Header &hdr); + + +//----------------------------------------------------------------- +// Construct a Compressor for compression type c for a tiled image: +// +// tileLineSize Maximum number of bytes per uncompressed +// line in a tile. +// +// numTileLines Maximum number of lines in a tile. +// +// header Header of the input or output file whose +// pixels will be compressed or uncompressed. +// +// return value A pointer to a new Compressor object (it +// is the caller's responsibility to delete +// the object), or 0 (if c is NO_COMPRESSION). +// +//----------------------------------------------------------------- + +Compressor * newTileCompressor (Compression c, + size_t tileLineSize, + size_t numTileLines, + const Header &hdr); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,139 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Routines for converting between pixel data types, +// with well-defined behavior for exceptional cases. +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { +namespace { + +inline bool +isNegative (float f) +{ + union {float f; int i;} u; + u.f = f; + return (u.i & 0x80000000) != 0; +} + + +inline bool +isNan (float f) +{ + union {float f; int i;} u; + u.f = f; + return (u.i & 0x7fffffff) > 0x7f800000; +} + + +inline bool +isInfinity (float f) +{ + union {float f; int i;} u; + u.f = f; + return (u.i & 0x7fffffff) == 0x7f800000; +} + + +inline bool +isFinite (float f) +{ + union {float f; int i;} u; + u.f = f; + return (u.i & 0x7f800000) != 0x7f800000; +} + +} // namespace + + +unsigned int +halfToUint (half h) +{ + if (h.isNegative() || h.isNan()) + return 0; + + if (h.isInfinity()) + return UINT_MAX; + + return (unsigned int) h; +} + + +unsigned int +floatToUint (float f) +{ + if (isNegative (f) || isNan (f)) + return 0; + + if (isInfinity (f) || f > UINT_MAX) + return UINT_MAX; + + return (unsigned int) f; +} + + +half +uintToHalf (unsigned int ui) +{ + if (ui > HALF_MAX) + return half::posInf(); + + return half (ui); +} + + +half +floatToHalf (float f) +{ + if (isFinite (f)) + { + if (f > HALF_MAX) + return half::posInf(); + + if (f < -HALF_MAX) + return half::negInf(); + } + + return half (f); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfConvert.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_CONVERT_H +#define INCLUDED_IMF_CONVERT_H + +//----------------------------------------------------------------------------- +// +// Routines for converting between pixel data types, +// with well-defined behavior for exceptional cases, +// without depending on how hardware and operating +// system handle integer overflows and floating-point +// exceptions. +// +//----------------------------------------------------------------------------- + +#include "half.h" + + +namespace Imf { + +//--------------------------------------------------------- +// Conversion from half or float to unsigned int: +// +// input result +// --------------------------------------------------- +// +// finite, >= 0 input, cast to unsigned int +// (rounds towards zero) +// +// finite, < 0 0 +// +// NaN 0 +// +// +infinity UINT_MAX +// +// -infinity 0 +// +//--------------------------------------------------------- + +unsigned int halfToUint (half h); +unsigned int floatToUint (float f); + + +//--------------------------------------------------------- +// Conversion from unsigned int or float to half: +// +// input result +// --------------------------------------------------- +// +// finite, closest possible half +// magnitude <= HALF_MAX +// +// finite, > HALF_MAX +infinity +// +// finite, < -HALF_MAX -infinity +// +// NaN NaN +// +// +infinity +infinity +// +// -infinity -infinity +// +//--------------------------------------------------------- + +half uintToHalf (unsigned int ui); +half floatToHalf (float f); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class DoubleAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +DoubleAttribute::staticTypeName () +{ + return "double"; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfDoubleAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_DOUBLE_ATTRIBUTE_H +#define INCLUDED_IMF_DOUBLE_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class DoubleAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +typedef TypedAttribute DoubleAttribute; +template <> const char *DoubleAttribute::staticTypeName (); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,328 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Environment maps +// +//----------------------------------------------------------------------------- + +#include +#include "ImathFun.h" +#include +#include + +using namespace std; +using namespace Imath; + +namespace Imf { +namespace LatLongMap { + +V2f +latLong (const V3f &dir) +{ + float r = sqrt (dir.z * dir.z + dir.x * dir.x); + + float latitude = (r < abs (dir.y))? + acos (r / dir.length()) * sign (dir.y): + asin (dir.y / dir.length()); + + float longitude = (dir.z == 0 && dir.x == 0)? 0: atan2 (dir.x, dir.z); + + return V2f (latitude, longitude); +} + + +V2f +latLong (const Box2i &dataWindow, const V2f &pixelPosition) +{ + float latitude, longitude; + + if (dataWindow.max.y > dataWindow.min.y) + { + latitude = -M_PI * + ((pixelPosition.y - dataWindow.min.y) / + (dataWindow.max.y - dataWindow.min.y) - 0.5f); + } + else + { + latitude = 0; + } + + if (dataWindow.max.x > dataWindow.min.x) + { + longitude = -2 * M_PI * + ((pixelPosition.x - dataWindow.min.x) / + (dataWindow.max.x - dataWindow.min.x) - 0.5f); + } + else + { + longitude = 0; + } + + return V2f (latitude, longitude); +} + + +V2f +pixelPosition (const Box2i &dataWindow, const V2f &latLong) +{ + float x = latLong.y / (-2 * M_PI) + 0.5f; + float y = latLong.x / -M_PI + 0.5f; + + return V2f (x * (dataWindow.max.x - dataWindow.min.x) + dataWindow.min.x, + y * (dataWindow.max.y - dataWindow.min.y) + dataWindow.min.y); +} + + +V2f +pixelPosition (const Box2i &dataWindow, const V3f &direction) +{ + return pixelPosition (dataWindow, latLong (direction)); +} + + +V3f +direction (const Box2i &dataWindow, const V2f &pixelPosition) +{ + V2f ll = latLong (dataWindow, pixelPosition); + + return V3f (sin (ll.y) * cos (ll.x), + sin (ll.x), + cos (ll.y) * cos (ll.x)); +} + +} // namespace LatLongMap + + +namespace CubeMap { + +int +sizeOfFace (const Box2i &dataWindow) +{ + return min ((dataWindow.max.x - dataWindow.min.x + 1), + (dataWindow.max.y - dataWindow.min.y + 1) / 6); +} + + +Box2i +dataWindowForFace (CubeMapFace face, const Box2i &dataWindow) +{ + int sof = sizeOfFace (dataWindow); + Box2i dwf; + + dwf.min.x = 0; + dwf.min.y = int (face) * sof; + + dwf.max.x = dwf.min.x + sof - 1; + dwf.max.y = dwf.min.y + sof - 1; + + return dwf; +} + + +V2f +pixelPosition (CubeMapFace face, const Box2i &dataWindow, V2f positionInFace) +{ + Box2i dwf = dataWindowForFace (face, dataWindow); + V2f pos (0, 0); + + switch (face) + { + case CUBEFACE_POS_X: + + pos.x = dwf.min.x + positionInFace.y; + pos.y = dwf.max.y - positionInFace.x; + break; + + case CUBEFACE_NEG_X: + + pos.x = dwf.max.x - positionInFace.y; + pos.y = dwf.max.y - positionInFace.x; + break; + + case CUBEFACE_POS_Y: + + pos.x = dwf.min.x + positionInFace.x; + pos.y = dwf.max.y - positionInFace.y; + break; + + case CUBEFACE_NEG_Y: + + pos.x = dwf.min.x + positionInFace.x; + pos.y = dwf.min.y + positionInFace.y; + break; + + case CUBEFACE_POS_Z: + + pos.x = dwf.max.x - positionInFace.x; + pos.y = dwf.max.y - positionInFace.y; + break; + + case CUBEFACE_NEG_Z: + + pos.x = dwf.min.x + positionInFace.x; + pos.y = dwf.max.y - positionInFace.y; + break; + } + + return pos; +} + + +void +faceAndPixelPosition (const V3f &direction, + const Box2i &dataWindow, + CubeMapFace &face, + V2f &pif) +{ + int sof = sizeOfFace (dataWindow); + float absx = abs (direction.x); + float absy = abs (direction.y); + float absz = abs (direction.z); + + if (absx >= absy && absx >= absz) + { + if (absx == 0) + { + // + // Special case - direction is (0, 0, 0) + // + + face = CUBEFACE_POS_X; + pif = V2f (0, 0); + return; + } + + pif.x = (direction.y / absx + 1) / 2 * (sof - 1); + pif.y = (direction.z / absx + 1) / 2 * (sof - 1); + + if (direction.x > 0) + face = CUBEFACE_POS_X; + else + face = CUBEFACE_NEG_X; + } + else if (absy >= absz) + { + pif.x = (direction.x / absy + 1) / 2 * (sof - 1); + pif.y = (direction.z / absy + 1) / 2 * (sof - 1); + + if (direction.y > 0) + face = CUBEFACE_POS_Y; + else + face = CUBEFACE_NEG_Y; + } + else + { + pif.x = (direction.x / absz + 1) / 2 * (sof - 1); + pif.y = (direction.y / absz + 1) / 2 * (sof - 1); + + if (direction.z > 0) + face = CUBEFACE_POS_Z; + else + face = CUBEFACE_NEG_Z; + } +} + + +V3f +direction (CubeMapFace face, const Box2i &dataWindow, const V2f &positionInFace) +{ + int sof = sizeOfFace (dataWindow); + + V2f pos; + + if (sof > 1) + { + pos = V2f (positionInFace.x / (sof - 1) * 2 - 1, + positionInFace.y / (sof - 1) * 2 - 1); + } + else + { + pos = V2f (0, 0); + } + + V3f dir (1, 0, 0); + + switch (face) + { + case CUBEFACE_POS_X: + + dir.x = 1; + dir.y = pos.x; + dir.z = pos.y; + break; + + case CUBEFACE_NEG_X: + + dir.x = -1; + dir.y = pos.x; + dir.z = pos.y; + break; + + case CUBEFACE_POS_Y: + + dir.x = pos.x; + dir.y = 1; + dir.z = pos.y; + break; + + case CUBEFACE_NEG_Y: + + dir.x = pos.x; + dir.y = -1; + dir.z = pos.y; + break; + + case CUBEFACE_POS_Z: + + dir.x = pos.x; + dir.y = pos.y; + dir.z = 1; + break; + + case CUBEFACE_NEG_Z: + + dir.x = pos.x; + dir.y = pos.y; + dir.z = -1; + break; + } + + return dir; +} + +} // namespace CubeMap +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmap.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,322 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_ENVMAP_H +#define INCLUDED_IMF_ENVMAP_H + +//----------------------------------------------------------------------------- +// +// Environment maps +// +// Environment maps define a mapping from 3D directions to 2D +// pixel space locations. Environment maps are typically used +// in 3D rendering, for effects such as quickly approximating +// how shiny surfaces reflect their environment. +// +// Environment maps can be stored in scanline-based or in tiled +// OpenEXR files. The fact that an image is an environment map +// is indicated by the presence of an EnvmapAttribute whose name +// is "envmap". (Convenience functions to access this attribute +// are defined in header file ImfStandardAttributes.h.) +// The attribute's value defines the mapping from 3D directions +// to 2D pixel space locations. +// +// This header file defines the set of possible EnvmapAttribute +// values. +// +// For each possible EnvmapAttribute value, this header file also +// defines a set of convienience functions to convert between 3D +// directions and 2D pixel locations. +// +// Most of the convenience functions defined below require a +// dataWindow parameter. For scanline-based images, and for +// tiled images with level mode ONE_LEVEL, the dataWindow +// parameter should be set to the image's data window, as +// defined in the image header. For tiled images with level +// mode MIPMAP_LEVELS or RIPMAP_LEVELS, the data window of the +// image level that is being accessed should be used instead. +// (See the dataWindowForLevel() methods in ImfTiledInputFile.h +// and ImfTiledOutputFile.h.) +// +//----------------------------------------------------------------------------- + +#include "ImathBox.h" + +namespace Imf { + +//-------------------------------- +// Supported environment map types +//-------------------------------- + +enum Envmap +{ + ENVMAP_LATLONG = 0, // Latitude-longitude environment map + ENVMAP_CUBE = 1, // Cube map + + NUM_ENVMAPTYPES // Number of different environment map types +}; + + +//------------------------------------------------------------------------- +// Latitude-Longitude Map: +// +// The environment is projected onto the image using polar coordinates +// (latitude and longitude). A pixel's x coordinate corresponds to +// its longitude, and the y coordinate corresponds to its latitude. +// Pixel (dataWindow.min.x, dataWindow.min.y) has latitude +pi/2 and +// longitude +pi; pixel (dataWindow.max.x, dataWindow.max.y) has +// latitude -pi/2 and longitude -pi. +// +// In 3D space, latitudes -pi/2 and +pi/2 correspond to the negative and +// positive y direction. Latitude 0, longitude 0 points into positive +// z direction; and latitude 0, longitude pi/2 points into positive x +// direction. +// +// The size of the data window should be 2*N by N pixels (width by height), +// where N can be any integer greater than 0. +//------------------------------------------------------------------------- + +namespace LatLongMap +{ + //---------------------------------------------------- + // Convert a 3D direction to a 2D vector whose x and y + // components represent the corresponding latitude + // and longitude. + //---------------------------------------------------- + + Imath::V2f latLong (const Imath::V3f &direction); + + + //-------------------------------------------------------- + // Convert the position of a pixel to a 2D vector whose + // x and y components represent the corresponding latitude + // and longitude. + //-------------------------------------------------------- + + Imath::V2f latLong (const Imath::Box2i &dataWindow, + const Imath::V2f &pixelPosition); + + + //------------------------------------------------------------- + // Convert a 2D vector, whose x and y components represent + // longitude and latitude, into a corresponding pixel position. + //------------------------------------------------------------- + + Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, + const Imath::V2f &latLong); + + + //----------------------------------------------------- + // Convert a 3D direction vector into a corresponding + // pixel position. pixelPosition(dw,dir) is equivalent + // to pixelPosition(dw,latLong(dw,dir)). + //----------------------------------------------------- + + Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, + const Imath::V3f &direction); + + + //-------------------------------------------------------- + // Convert the position of a pixel in a latitude-longitude + // map into a corresponding 3D direction. + //-------------------------------------------------------- + + Imath::V3f direction (const Imath::Box2i &dataWindow, + const Imath::V2f &pixelPosition); +} + + +//-------------------------------------------------------------- +// Cube Map: +// +// The environment is projected onto the six faces of an +// axis-aligned cube. The cube's faces are then arranged +// in a 2D image as shown below. +// +// 2-----------3 +// / /| +// / / | Y +// / / | | +// 6-----------7 | | +// | | | | +// | | | | +// | 0 | 1 *------- X +// | | / / +// | | / / +// | |/ / +// 4-----------5 Z +// +// dataWindow.min +// / +// / +// +-----------+ +// |3 Y 7| +// | | | +// | | | +// | ---+---Z | +X face +// | | | +// | | | +// |1 5| +// +-----------+ +// |6 Y 2| +// | | | +// | | | +// | Z---+--- | -X face +// | | | +// | | | +// |4 0| +// +-----------+ +// |6 Z 7| +// | | | +// | | | +// | ---+---X | +Y face +// | | | +// | | | +// |2 3| +// +-----------+ +// |0 1| +// | | | +// | | | +// | ---+---X | -Y face +// | | | +// | | | +// |4 Z 5| +// +-----------+ +// |7 Y 6| +// | | | +// | | | +// | X---+--- | +Z face +// | | | +// | | | +// |5 4| +// +-----------+ +// |2 Y 3| +// | | | +// | | | +// | ---+---X | -Z face +// | | | +// | | | +// |0 1| +// +-----------+ +// / +// / +// dataWindow.max +// +// The size of the data window should be N by 6*N pixels +// (width by height), where N can be any integer greater +// than 0. +// +//-------------------------------------------------------------- + +//------------------------------------ +// Names for the six faces of the cube +//------------------------------------ + +enum CubeMapFace +{ + CUBEFACE_POS_X, // +X face + CUBEFACE_NEG_X, // -X face + CUBEFACE_POS_Y, // +Y face + CUBEFACE_NEG_Y, // -Y face + CUBEFACE_POS_Z, // +Z face + CUBEFACE_NEG_Z // -Z face +}; + +namespace CubeMap +{ + //--------------------------------------------- + // Width and height of a cube's face, in pixels + //--------------------------------------------- + + int sizeOfFace (const Imath::Box2i &dataWindow); + + + //------------------------------------------ + // Compute the region in the environment map + // that is covered by the specified face. + //------------------------------------------ + + Imath::Box2i dataWindowForFace (CubeMapFace face, + const Imath::Box2i &dataWindow); + + + //---------------------------------------------------- + // Convert the coordinates of a pixel within a face + // [in the range from (0,0) to (s-1,s-1), where + // s == sizeOfFace(dataWindow)] to pixel coordinates + // in the environment map. + //---------------------------------------------------- + + Imath::V2f pixelPosition (CubeMapFace face, + const Imath::Box2i &dataWindow, + Imath::V2f positionInFace); + + + //-------------------------------------------------------------- + // Convert a 3D direction into a cube face, and a pixel position + // within that face. + // + // If you have a 3D direction, dir, the following code fragment + // finds the position, pos, of the corresponding pixel in an + // environment map with data window dw: + // + // CubeMapFace f; + // V2f pif, pos; + // + // faceAndPixelPosition (dir, dw, f, pif); + // pos = pixelPosition (f, dw, pif); + // + //-------------------------------------------------------------- + + void faceAndPixelPosition (const Imath::V3f &direction, + const Imath::Box2i &dataWindow, + CubeMapFace &face, + Imath::V2f &positionInFace); + + + // -------------------------------------------------------- + // Given a cube face and a pixel position within that face, + // compute the corresponding 3D direction. + // -------------------------------------------------------- + + Imath::V3f direction (CubeMapFace face, + const Imath::Box2i &dataWindow, + const Imath::V2f &positionInFace); +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class EnvmapAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +EnvmapAttribute::staticTypeName () +{ + return "envmap"; +} + + +template <> +void +EnvmapAttribute::writeValueTo (OStream &os, int) const +{ + unsigned char tmp = _value; + Xdr::write (os, tmp); +} + + +template <> +void +EnvmapAttribute::readValueFrom (IStream &is, int, int) +{ + unsigned char tmp; + Xdr::read (is, tmp); + _value = Envmap (tmp); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfEnvmapAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMF_ENVMAP_ATTRIBUTE_H +#define INCLUDED_IMF_ENVMAP_ATTRIBUTE_H + + +//----------------------------------------------------------------------------- +// +// class EnvmapAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute EnvmapAttribute; +template <> const char *EnvmapAttribute::staticTypeName (); +template <> void EnvmapAttribute::writeValueTo (OStream &, int) const; +template <> void EnvmapAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class FloatAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +FloatAttribute::staticTypeName () +{ + return "float"; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFloatAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_FLOAT_ATTRIBUTE_H +#define INCLUDED_IMF_FLOAT_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class FloatAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +typedef TypedAttribute FloatAttribute; +template <> const char *FloatAttribute::staticTypeName (); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,226 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Slice +// class FrameBuffer +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" + + +using namespace std; + +namespace Imf { + +Slice::Slice (PixelType t, + char *b, + size_t xst, + size_t yst, + int xsm, + int ysm, + double fv, + bool xtc, + bool ytc) +: + type (t), + base (b), + xStride (xst), + yStride (yst), + xSampling (xsm), + ySampling (ysm), + fillValue (fv), + xTileCoords (xtc), + yTileCoords (ytc) +{ + // empty +} + + +void +FrameBuffer::insert (const char name[], const Slice &slice) +{ + if (name[0] == 0) + { + THROW (Iex::ArgExc, + "Frame buffer slice name cannot be an empty string."); + } + + _map[name] = slice; +} + + +void +FrameBuffer::insert (const string &name, const Slice &slice) +{ + insert (name.c_str(), slice); +} + + +Slice & +FrameBuffer::operator [] (const char name[]) +{ + SliceMap::iterator i = _map.find (name); + + if (i == _map.end()) + { + THROW (Iex::ArgExc, + "Cannot find frame buffer slice \"" << name << "\"."); + } + + return i->second; +} + + +const Slice & +FrameBuffer::operator [] (const char name[]) const +{ + SliceMap::const_iterator i = _map.find (name); + + if (i == _map.end()) + { + THROW (Iex::ArgExc, + "Cannot find frame buffer slice \"" << name << "\"."); + } + + return i->second; +} + + +Slice & +FrameBuffer::operator [] (const string &name) +{ + return this->operator[] (name.c_str()); +} + + +const Slice & +FrameBuffer::operator [] (const string &name) const +{ + return this->operator[] (name.c_str()); +} + + +Slice * +FrameBuffer::findSlice (const char name[]) +{ + SliceMap::iterator i = _map.find (name); + return (i == _map.end())? 0: &i->second; +} + + +const Slice * +FrameBuffer::findSlice (const char name[]) const +{ + SliceMap::const_iterator i = _map.find (name); + return (i == _map.end())? 0: &i->second; +} + + +Slice * +FrameBuffer::findSlice (const string &name) +{ + return findSlice (name.c_str()); +} + + +const Slice * +FrameBuffer::findSlice (const string &name) const +{ + return findSlice (name.c_str()); +} + + +FrameBuffer::Iterator +FrameBuffer::begin () +{ + return _map.begin(); +} + + +FrameBuffer::ConstIterator +FrameBuffer::begin () const +{ + return _map.begin(); +} + + +FrameBuffer::Iterator +FrameBuffer::end () +{ + return _map.end(); +} + + +FrameBuffer::ConstIterator +FrameBuffer::end () const +{ + return _map.end(); +} + + +FrameBuffer::Iterator +FrameBuffer::find (const char name[]) +{ + return _map.find (name); +} + + +FrameBuffer::ConstIterator +FrameBuffer::find (const char name[]) const +{ + return _map.find (name); +} + + +FrameBuffer::Iterator +FrameBuffer::find (const string &name) +{ + return find (name.c_str()); +} + + +FrameBuffer::ConstIterator +FrameBuffer::find (const string &name) const +{ + return find (name.c_str()); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFrameBuffer.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,383 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_FRAME_BUFFER_H +#define INCLUDED_IMF_FRAME_BUFFER_H + +//----------------------------------------------------------------------------- +// +// class Slice +// class FrameBuffer +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include + + +namespace Imf { + + +//------------------------------------------------------- +// Description of a single slice of the frame buffer: +// +// Note -- terminology: as part of a file, a component of +// an image (e.g. red, green, blue, depth etc.) is called +// a "channel". As part of a frame buffer, an image +// component is called a "slice". +//------------------------------------------------------- + +struct Slice +{ + //------------------------------ + // Data type; see ImfPixelType.h + //------------------------------ + + PixelType type; + + + //--------------------------------------------------------------------- + // Memory layout: The address of pixel (x, y) is + // + // base + (xp / xSampling) * xStride + (yp / ySampling) * yStride + // + // where xp and yp are computed as follows: + // + // * If we are reading or writing a scanline-based file: + // + // xp = x + // yp = y + // + // * If we are reading a tile whose upper left coorner is at (xt, yt): + // + // if xTileCoords is true then xp = x - xt, else xp = x + // if yTileCoords is true then yp = y - yt, else yp = y + // + //--------------------------------------------------------------------- + + char * base; + size_t xStride; + size_t yStride; + + + //-------------------------------------------- + // Subsampling: pixel (x, y) is present in the + // slice only if + // + // x % xSampling == 0 && y % ySampling == 0 + // + //-------------------------------------------- + + int xSampling; + int ySampling; + + + //---------------------------------------------------------- + // Default value, used to fill the slice when a file without + // a channel that corresponds to this slice is read. + //---------------------------------------------------------- + + double fillValue; + + + //------------------------------------------------------- + // For tiled files, the xTileCoords and yTileCoords flags + // determine whether pixel addressing is performed using + // absolute coordinates or coordinates relative to a + // tile's upper left corner. (See the comment on base, + // xStride and yStride, above.) + // + // For scanline-based files these flags have no effect; + // pixel addressing is always done using absolute + // coordinates. + //------------------------------------------------------- + + bool xTileCoords; + bool yTileCoords; + + + //------------ + // Constructor + //------------ + + Slice (PixelType type = HALF, + char * base = 0, + size_t xStride = 0, + size_t yStride = 0, + int xSampling = 1, + int ySampling = 1, + double fillValue = 0.0, + bool xTileCoords = false, + bool yTileCoords = false); +}; + + +class FrameBuffer +{ + public: + + //------------ + // Add a slice + //------------ + + void insert (const char name[], + const Slice &slice); + + void insert (const std::string &name, + const Slice &slice); + + //---------------------------------------------------------------- + // Access to existing slices: + // + // [n] Returns a reference to the slice with name n. + // If no slice with name n exists, an Iex::ArgExc + // is thrown. + // + // findSlice(n) Returns a pointer to the slice with name n, + // or 0 if no slice with name n exists. + // + //---------------------------------------------------------------- + + Slice & operator [] (const char name[]); + const Slice & operator [] (const char name[]) const; + + Slice & operator [] (const std::string &name); + const Slice & operator [] (const std::string &name) const; + + Slice * findSlice (const char name[]); + const Slice * findSlice (const char name[]) const; + + Slice * findSlice (const std::string &name); + const Slice * findSlice (const std::string &name) const; + + + //----------------------------------------- + // Iterator-style access to existing slices + //----------------------------------------- + + typedef std::map SliceMap; + + class Iterator; + class ConstIterator; + + Iterator begin (); + ConstIterator begin () const; + + Iterator end (); + ConstIterator end () const; + + Iterator find (const char name[]); + ConstIterator find (const char name[]) const; + + Iterator find (const std::string &name); + ConstIterator find (const std::string &name) const; + + private: + + SliceMap _map; +}; + + +//---------- +// Iterators +//---------- + +class FrameBuffer::Iterator +{ + public: + + Iterator (); + Iterator (const FrameBuffer::SliceMap::iterator &i); + + Iterator & operator ++ (); + Iterator operator ++ (int); + + const char * name () const; + Slice & slice () const; + + private: + + friend class FrameBuffer::ConstIterator; + + FrameBuffer::SliceMap::iterator _i; +}; + + +class FrameBuffer::ConstIterator +{ + public: + + ConstIterator (); + ConstIterator (const FrameBuffer::SliceMap::const_iterator &i); + ConstIterator (const FrameBuffer::Iterator &other); + + ConstIterator & operator ++ (); + ConstIterator operator ++ (int); + + const char * name () const; + const Slice & slice () const; + + private: + + friend bool operator == (const ConstIterator &, const ConstIterator &); + friend bool operator != (const ConstIterator &, const ConstIterator &); + + FrameBuffer::SliceMap::const_iterator _i; +}; + + +//----------------- +// Inline Functions +//----------------- + +inline +FrameBuffer::Iterator::Iterator (): _i() +{ + // empty +} + + +inline +FrameBuffer::Iterator::Iterator (const FrameBuffer::SliceMap::iterator &i): + _i (i) +{ + // empty +} + + +inline FrameBuffer::Iterator & +FrameBuffer::Iterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline FrameBuffer::Iterator +FrameBuffer::Iterator::operator ++ (int) +{ + Iterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +FrameBuffer::Iterator::name () const +{ + return *_i->first; +} + + +inline Slice & +FrameBuffer::Iterator::slice () const +{ + return _i->second; +} + + +inline +FrameBuffer::ConstIterator::ConstIterator (): _i() +{ + // empty +} + +inline +FrameBuffer::ConstIterator::ConstIterator + (const FrameBuffer::SliceMap::const_iterator &i): _i (i) +{ + // empty +} + + +inline +FrameBuffer::ConstIterator::ConstIterator (const FrameBuffer::Iterator &other): + _i (other._i) +{ + // empty +} + +inline FrameBuffer::ConstIterator & +FrameBuffer::ConstIterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline FrameBuffer::ConstIterator +FrameBuffer::ConstIterator::operator ++ (int) +{ + ConstIterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +FrameBuffer::ConstIterator::name () const +{ + return *_i->first; +} + +inline const Slice & +FrameBuffer::ConstIterator::slice () const +{ + return _i->second; +} + + +inline bool +operator == (const FrameBuffer::ConstIterator &x, + const FrameBuffer::ConstIterator &y) +{ + return x._i == y._i; +} + + +inline bool +operator != (const FrameBuffer::ConstIterator &x, + const FrameBuffer::ConstIterator &y) +{ + return !(x == y); +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Convenience functions related to the framesPerSecond attribute +// +//----------------------------------------------------------------------------- + +#include +#include "ImathFun.h" + +using namespace Imath; + +namespace Imf { + +Rational +guessExactFps (double fps) +{ + return guessExactFps (Rational (fps)); +} + + +Rational +guessExactFps (const Rational &fps) +{ + const double e = 0.002; + + if (abs (double (fps) - double (fps_23_976())) < e) + return fps_23_976(); + + if (abs (double (fps) - double (fps_29_97())) < e) + return fps_29_97(); + + if (abs (double (fps) - double (fps_47_952())) < e) + return fps_47_952(); + + if (abs (double (fps) - double (fps_59_94())) < e) + return fps_59_94(); + + return fps; +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfFramesPerSecond.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,88 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_FRAMES_PER_SECOND_H +#define INCLUDED_IMF_FRAMES_PER_SECOND_H + +//----------------------------------------------------------------------------- +// +// Convenience functions related to the framesPerSecond attribute +// +// Functions that return the exact values for commonly used frame rates: +// +// name frames per second +// +// fps_23_976() 23.976023... +// fps_24() 24.0 35mm film frames +// fps_25() 25.0 PAL video frames +// fps_29_97() 29.970029... NTSC video frames +// fps_30() 30.0 60Hz HDTV frames +// fps_47_952() 47.952047... +// fps_48() 48.0 +// fps_50() 50.0 PAL video fields +// fps_59_94() 59.940059... NTSC video fields +// fps_60() 60.0 60Hz HDTV fields +// +// Functions that try to convert inexact frame rates into exact ones: +// +// Given a frame rate, fps, that is close to one of the pre-defined +// frame rates fps_23_976(), fps_29_97(), fps_47_952() or fps_59_94(), +// guessExactFps(fps) returns the corresponding pre-defined frame +// rate. If fps is not close to one of the pre-defined frame rates, +// then guessExactFps(fps) returns Rational(fps). +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + +inline Rational fps_23_976 () {return Rational (24000, 1001);} +inline Rational fps_24 () {return Rational (24, 1);} +inline Rational fps_25 () {return Rational (25, 1);} +inline Rational fps_29_97 () {return Rational (30000, 1001);} +inline Rational fps_30 () {return Rational (30, 1);} +inline Rational fps_47_952 () {return Rational (48000, 1001);} +inline Rational fps_48 () {return Rational (48, 1);} +inline Rational fps_50 () {return Rational (50, 1);} +inline Rational fps_59_94 () {return Rational (60000, 1001);} +inline Rational fps_60 () {return Rational (60, 1);} + +Rational guessExactFps (double fps); +Rational guessExactFps (const Rational &fps); + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1106 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class Header +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "IlmThreadMutex.h" +#include "Iex.h" +#include +#include +#include + + +namespace Imf { + +using namespace std; +using Imath::Box2i; +using Imath::V2i; +using Imath::V2f; +using IlmThread::Mutex; +using IlmThread::Lock; + + +namespace { + +int maxImageWidth = 0; +int maxImageHeight = 0; +int maxTileWidth = 0; +int maxTileHeight = 0; + + +void +initialize (Header &header, + const Box2i &displayWindow, + const Box2i &dataWindow, + float pixelAspectRatio, + const V2f &screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression) +{ + header.insert ("displayWindow", Box2iAttribute (displayWindow)); + header.insert ("dataWindow", Box2iAttribute (dataWindow)); + header.insert ("pixelAspectRatio", FloatAttribute (pixelAspectRatio)); + header.insert ("screenWindowCenter", V2fAttribute (screenWindowCenter)); + header.insert ("screenWindowWidth", FloatAttribute (screenWindowWidth)); + header.insert ("lineOrder", LineOrderAttribute (lineOrder)); + header.insert ("compression", CompressionAttribute (compression)); + header.insert ("channels", ChannelListAttribute ()); +} + + +bool +usesLongNames (const Header &header) +{ + // + // If an OpenEXR file contains any attribute names, attribute type names + // or channel names longer than 31 characters, then the file cannot be + // read by older versions of the IlmImf library (up to OpenEXR 1.6.1). + // Before writing the file header, we check if the header contains + // any names longer than 31 characters; if it does, then we set the + // LONG_NAMES_FLAG in the file version number. Older versions of the + // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG + // set. Without the flag, older versions of the library would mis- + // interpret the file as broken. + // + + for (Header::ConstIterator i = header.begin(); + i != header.end(); + ++i) + { + if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32) + return true; + } + + const ChannelList &channels = header.channels(); + + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + if (strlen (i.name()) >= 32) + return true; + } + + return false; +} + +template +void checkIsNullTerminated (const char (&str)[N], const char *what) +{ + for (int i = 0; i < N; ++i) { + if (str[i] == '\0') + return; + } + std::stringstream s; + s << "Invalid " << what << ": it is more than " << (N - 1) + << " characters long."; + throw Iex::InputExc(s); +} + +} // namespace + + +Header::Header (int width, + int height, + float pixelAspectRatio, + const V2f &screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression) +: + _map() +{ + staticInitialize(); + + Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1)); + + initialize (*this, + displayWindow, + displayWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); +} + + +Header::Header (int width, + int height, + const Box2i &dataWindow, + float pixelAspectRatio, + const V2f &screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression) +: + _map() +{ + staticInitialize(); + + Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1)); + + initialize (*this, + displayWindow, + dataWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); +} + + +Header::Header (const Box2i &displayWindow, + const Box2i &dataWindow, + float pixelAspectRatio, + const V2f &screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression) +: + _map() +{ + staticInitialize(); + + initialize (*this, + displayWindow, + dataWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); +} + + +Header::Header (const Header &other): _map() +{ + for (AttributeMap::const_iterator i = other._map.begin(); + i != other._map.end(); + ++i) + { + insert (*i->first, *i->second); + } +} + + +Header::~Header () +{ + for (AttributeMap::iterator i = _map.begin(); + i != _map.end(); + ++i) + { + delete i->second; + } +} + + +Header & +Header::operator = (const Header &other) +{ + if (this != &other) + { + for (AttributeMap::iterator i = _map.begin(); + i != _map.end(); + ++i) + { + delete i->second; + } + + _map.erase (_map.begin(), _map.end()); + + for (AttributeMap::const_iterator i = other._map.begin(); + i != other._map.end(); + ++i) + { + insert (*i->first, *i->second); + } + } + + return *this; +} + + +void +Header::insert (const char name[], const Attribute &attribute) +{ + if (name[0] == 0) + THROW (Iex::ArgExc, "Image attribute name cannot be an empty string."); + + AttributeMap::iterator i = _map.find (name); + + if (i == _map.end()) + { + Attribute *tmp = attribute.copy(); + + try + { + _map[name] = tmp; + } + catch (...) + { + delete tmp; + throw; + } + } + else + { + if (strcmp (i->second->typeName(), attribute.typeName())) + THROW (Iex::TypeExc, "Cannot assign a value of " + "type \"" << attribute.typeName() << "\" " + "to image attribute \"" << name << "\" of " + "type \"" << i->second->typeName() << "\"."); + + Attribute *tmp = attribute.copy(); + delete i->second; + i->second = tmp; + } +} + + +void +Header::insert (const string &name, const Attribute &attribute) +{ + insert (name.c_str(), attribute); +} + + +Attribute & +Header::operator [] (const char name[]) +{ + AttributeMap::iterator i = _map.find (name); + + if (i == _map.end()) + THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\"."); + + return *i->second; +} + + +const Attribute & +Header::operator [] (const char name[]) const +{ + AttributeMap::const_iterator i = _map.find (name); + + if (i == _map.end()) + THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\"."); + + return *i->second; +} + + +Attribute & +Header::operator [] (const string &name) +{ + return this->operator[] (name.c_str()); +} + + +const Attribute & +Header::operator [] (const string &name) const +{ + return this->operator[] (name.c_str()); +} + + +Header::Iterator +Header::begin () +{ + return _map.begin(); +} + + +Header::ConstIterator +Header::begin () const +{ + return _map.begin(); +} + + +Header::Iterator +Header::end () +{ + return _map.end(); +} + + +Header::ConstIterator +Header::end () const +{ + return _map.end(); +} + + +Header::Iterator +Header::find (const char name[]) +{ + return _map.find (name); +} + + +Header::ConstIterator +Header::find (const char name[]) const +{ + return _map.find (name); +} + + +Header::Iterator +Header::find (const string &name) +{ + return find (name.c_str()); +} + + +Header::ConstIterator +Header::find (const string &name) const +{ + return find (name.c_str()); +} + + +Imath::Box2i & +Header::displayWindow () +{ + return static_cast + ((*this)["displayWindow"]).value(); +} + + +const Imath::Box2i & +Header::displayWindow () const +{ + return static_cast + ((*this)["displayWindow"]).value(); +} + + +Imath::Box2i & +Header::dataWindow () +{ + return static_cast + ((*this)["dataWindow"]).value(); +} + + +const Imath::Box2i & +Header::dataWindow () const +{ + return static_cast + ((*this)["dataWindow"]).value(); +} + + +float & +Header::pixelAspectRatio () +{ + return static_cast + ((*this)["pixelAspectRatio"]).value(); +} + + +const float & +Header::pixelAspectRatio () const +{ + return static_cast + ((*this)["pixelAspectRatio"]).value(); +} + + +Imath::V2f & +Header::screenWindowCenter () +{ + return static_cast + ((*this)["screenWindowCenter"]).value(); +} + + +const Imath::V2f & +Header::screenWindowCenter () const +{ + return static_cast + ((*this)["screenWindowCenter"]).value(); +} + + +float & +Header::screenWindowWidth () +{ + return static_cast + ((*this)["screenWindowWidth"]).value(); +} + + +const float & +Header::screenWindowWidth () const +{ + return static_cast + ((*this)["screenWindowWidth"]).value(); +} + + +ChannelList & +Header::channels () +{ + return static_cast + ((*this)["channels"]).value(); +} + + +const ChannelList & +Header::channels () const +{ + return static_cast + ((*this)["channels"]).value(); +} + + +LineOrder & +Header::lineOrder () +{ + return static_cast + ((*this)["lineOrder"]).value(); +} + + +const LineOrder & +Header::lineOrder () const +{ + return static_cast + ((*this)["lineOrder"]).value(); +} + + +Compression & +Header::compression () +{ + return static_cast + ((*this)["compression"]).value(); +} + + +const Compression & +Header::compression () const +{ + return static_cast + ((*this)["compression"]).value(); +} + + +void +Header::setTileDescription(const TileDescription& td) +{ + insert ("tiles", TileDescriptionAttribute (td)); +} + + +bool +Header::hasTileDescription() const +{ + return findTypedAttribute ("tiles") != 0; +} + + +TileDescription & +Header::tileDescription () +{ + return typedAttribute ("tiles").value(); +} + + +const TileDescription & +Header::tileDescription () const +{ + return typedAttribute ("tiles").value(); +} + +void +Header::setPreviewImage (const PreviewImage &pi) +{ + insert ("preview", PreviewImageAttribute (pi)); +} + + +PreviewImage & +Header::previewImage () +{ + return typedAttribute ("preview").value(); +} + + +const PreviewImage & +Header::previewImage () const +{ + return typedAttribute ("preview").value(); +} + + +bool +Header::hasPreviewImage () const +{ + return findTypedAttribute ("preview") != 0; +} + + +void +Header::sanityCheck (bool isTiled) const +{ + // + // The display window and the data window must each + // contain at least one pixel. In addition, the + // coordinates of the window corners must be small + // enough to keep expressions like max-min+1 or + // max+min from overflowing. + // + + const Box2i &displayWindow = this->displayWindow(); + + if (displayWindow.min.x > displayWindow.max.x || + displayWindow.min.y > displayWindow.max.y || + displayWindow.min.x <= -(INT_MAX / 2) || + displayWindow.min.y <= -(INT_MAX / 2) || + displayWindow.max.x >= (INT_MAX / 2) || + displayWindow.max.y >= (INT_MAX / 2)) + { + throw Iex::ArgExc ("Invalid display window in image header."); + } + + const Box2i &dataWindow = this->dataWindow(); + + if (dataWindow.min.x > dataWindow.max.x || + dataWindow.min.y > dataWindow.max.y || + dataWindow.min.x <= -(INT_MAX / 2) || + dataWindow.min.y <= -(INT_MAX / 2) || + dataWindow.max.x >= (INT_MAX / 2) || + dataWindow.max.y >= (INT_MAX / 2)) + { + throw Iex::ArgExc ("Invalid data window in image header."); + } + + if (maxImageWidth > 0 && + maxImageWidth < dataWindow.max.x - dataWindow.min.x + 1) + { + THROW (Iex::ArgExc, "The width of the data window exceeds the " + "maximum width of " << maxImageWidth << "pixels."); + } + + if (maxImageHeight > 0 && + maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1) + { + THROW (Iex::ArgExc, "The width of the data window exceeds the " + "maximum width of " << maxImageHeight << "pixels."); + } + + // + // The pixel aspect ratio must be greater than 0. + // In applications, numbers like the the display or + // data window dimensions are likely to be multiplied + // or divided by the pixel aspect ratio; to avoid + // arithmetic exceptions, we limit the pixel aspect + // ratio to a range that is smaller than theoretically + // possible (real aspect ratios are likely to be close + // to 1.0 anyway). + // + + float pixelAspectRatio = this->pixelAspectRatio(); + + const float MIN_PIXEL_ASPECT_RATIO = 1e-6f; + const float MAX_PIXEL_ASPECT_RATIO = 1e+6f; + + if (pixelAspectRatio < MIN_PIXEL_ASPECT_RATIO || + pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO) + { + throw Iex::ArgExc ("Invalid pixel aspect ratio in image header."); + } + + // + // The screen window width must not be less than 0. + // The size of the screen window can vary over a wide + // range (fish-eye lens to astronomical telescope), + // so we can't limit the screen window width to a + // small range. + // + + float screenWindowWidth = this->screenWindowWidth(); + + if (screenWindowWidth < 0) + throw Iex::ArgExc ("Invalid screen window width in image header."); + + // + // If the file is tiled, verify that the tile description has resonable + // values and check to see if the lineOrder is one of the predefined 3. + // If the file is not tiled, then the lineOrder can only be INCREASING_Y + // or DECREASING_Y. + // + + LineOrder lineOrder = this->lineOrder(); + + if (isTiled) + { + if (!hasTileDescription()) + { + throw Iex::ArgExc ("Tiled image has no tile " + "description attribute."); + } + + const TileDescription &tileDesc = tileDescription(); + + if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0) + throw Iex::ArgExc ("Invalid tile size in image header."); + + if (maxTileWidth > 0 && + maxTileWidth < tileDesc.xSize) + { + THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum " + "width of " << maxTileWidth << "pixels."); + } + + if (maxTileHeight > 0 && + maxTileHeight < tileDesc.ySize) + { + THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum " + "width of " << maxTileHeight << "pixels."); + } + + if (tileDesc.mode != ONE_LEVEL && + tileDesc.mode != MIPMAP_LEVELS && + tileDesc.mode != RIPMAP_LEVELS) + throw Iex::ArgExc ("Invalid level mode in image header."); + + if (tileDesc.roundingMode != ROUND_UP && + tileDesc.roundingMode != ROUND_DOWN) + throw Iex::ArgExc ("Invalid level rounding mode in image header."); + + if (lineOrder != INCREASING_Y && + lineOrder != DECREASING_Y && + lineOrder != RANDOM_Y) + throw Iex::ArgExc ("Invalid line order in image header."); + } + else + { + if (lineOrder != INCREASING_Y && + lineOrder != DECREASING_Y) + throw Iex::ArgExc ("Invalid line order in image header."); + } + + // + // The compression method must be one of the predefined values. + // + + if (!isValidCompression (this->compression())) + throw Iex::ArgExc ("Unknown compression type in image header."); + + // + // Check the channel list: + // + // If the file is tiled then for each channel, the type must be one of the + // predefined values, and the x and y sampling must both be 1. + // + // If the file is not tiled then for each channel, the type must be one + // of the predefined values, the x and y coordinates of the data window's + // upper left corner must be divisible by the x and y subsampling factors, + // and the width and height of the data window must be divisible by the + // x and y subsampling factors. + // + + const ChannelList &channels = this->channels(); + + if (isTiled) + { + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + if (i.channel().type != UINT && + i.channel().type != HALF && + i.channel().type != FLOAT) + { + THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" " + "image channel is invalid."); + } + + if (i.channel().xSampling != 1) + { + THROW (Iex::ArgExc, "The x subsampling factor for the " + "\"" << i.name() << "\" channel " + "is not 1."); + } + + if (i.channel().ySampling != 1) + { + THROW (Iex::ArgExc, "The y subsampling factor for the " + "\"" << i.name() << "\" channel " + "is not 1."); + } + } + } + else + { + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + if (i.channel().type != UINT && + i.channel().type != HALF && + i.channel().type != FLOAT) + { + THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" " + "image channel is invalid."); + } + + if (i.channel().xSampling < 1) + { + THROW (Iex::ArgExc, "The x subsampling factor for the " + "\"" << i.name() << "\" channel " + "is invalid."); + } + + if (i.channel().ySampling < 1) + { + THROW (Iex::ArgExc, "The y subsampling factor for the " + "\"" << i.name() << "\" channel " + "is invalid."); + } + + if (dataWindow.min.x % i.channel().xSampling) + { + THROW (Iex::ArgExc, "The minimum x coordinate of the " + "image's data window is not a multiple " + "of the x subsampling factor of " + "the \"" << i.name() << "\" channel."); + } + + if (dataWindow.min.y % i.channel().ySampling) + { + THROW (Iex::ArgExc, "The minimum y coordinate of the " + "image's data window is not a multiple " + "of the y subsampling factor of " + "the \"" << i.name() << "\" channel."); + } + + if ((dataWindow.max.x - dataWindow.min.x + 1) % + i.channel().xSampling) + { + THROW (Iex::ArgExc, "Number of pixels per row in the " + "image's data window is not a multiple " + "of the x subsampling factor of " + "the \"" << i.name() << "\" channel."); + } + + if ((dataWindow.max.y - dataWindow.min.y + 1) % + i.channel().ySampling) + { + THROW (Iex::ArgExc, "Number of pixels per column in the " + "image's data window is not a multiple " + "of the y subsampling factor of " + "the \"" << i.name() << "\" channel."); + } + } + } +} + + +void +Header::setMaxImageSize (int maxWidth, int maxHeight) +{ + maxImageWidth = maxWidth; + maxImageHeight = maxHeight; +} + + +void +Header::setMaxTileSize (int maxWidth, int maxHeight) +{ + maxTileWidth = maxWidth; + maxTileHeight = maxHeight; +} + + +Int64 +Header::writeTo (OStream &os, bool isTiled) const +{ + // + // Write a "magic number" to identify the file as an image file. + // Write the current file format version number. + // + + Xdr::write (os, MAGIC); + + int version = EXR_VERSION; + + if (isTiled) + version |= TILED_FLAG; + + if (usesLongNames (*this)) + version |= LONG_NAMES_FLAG; + + Xdr::write (os, version); + + // + // Write all attributes. If we have a preview image attribute, + // keep track of its position in the file. + // + + Int64 previewPosition = 0; + + const Attribute *preview = + findTypedAttribute ("preview"); + + for (ConstIterator i = begin(); i != end(); ++i) + { + // + // Write the attribute's name and type. + // + + Xdr::write (os, i.name()); + Xdr::write (os, i.attribute().typeName()); + + // + // Write the size of the attribute value, + // and the value itself. + // + + StdOSStream oss; + i.attribute().writeValueTo (oss, version); + + std::string s = oss.str(); + Xdr::write (os, (int) s.length()); + + if (&i.attribute() == preview) + previewPosition = os.tellp(); + + os.write (s.data(), s.length()); + } + + // + // Write zero-length attribute name to mark the end of the header. + // + + Xdr::write (os, ""); + + return previewPosition; +} + + +void +Header::readFrom (IStream &is, int &version) +{ + // + // Read the magic number and the file format version number. + // Then check if we can read the rest of this file. + // + + int magic; + + Xdr::read (is, magic); + Xdr::read (is, version); + + if (magic != MAGIC) + { + throw Iex::InputExc ("File is not an image file."); + } + + if (getVersion (version) != EXR_VERSION) + { + THROW (Iex::InputExc, "Cannot read " + "version " << getVersion (version) << " " + "image files. Current file format version " + "is " << EXR_VERSION << "."); + } + + if (!supportsFlags (getFlags (version))) + { + THROW (Iex::InputExc, "The file format version number's flag field " + "contains unrecognized flags."); + } + + // + // Read all attributes. + // + + while (true) + { + // + // Read the name of the attribute. + // A zero-length attribute name indicates the end of the header. + // + + char name[Name::SIZE]; + Xdr::read (is, Name::MAX_LENGTH, name); + + if (name[0] == 0) + break; + + checkIsNullTerminated (name, "attribute name"); + + // + // Read the attribute type and the size of the attribute value. + // + + char typeName[Name::SIZE]; + int size; + + Xdr::read (is, Name::MAX_LENGTH, typeName); + checkIsNullTerminated (typeName, "attribute type name"); + Xdr::read (is, size); + + AttributeMap::iterator i = _map.find (name); + + if (i != _map.end()) + { + // + // The attribute already exists (for example, + // because it is a predefined attribute). + // Read the attribute's new value from the file. + // + + if (strncmp (i->second->typeName(), typeName, sizeof (typeName))) + THROW (Iex::InputExc, "Unexpected type for image attribute " + "\"" << name << "\"."); + + i->second->readValueFrom (is, size, version); + } + else + { + // + // The new attribute does not exist yet. + // If the attribute type is of a known type, + // read the attribute value. If the attribute + // is of an unknown type, read its value and + // store it as an OpaqueAttribute. + // + + Attribute *attr; + + if (Attribute::knownType (typeName)) + attr = Attribute::newAttribute (typeName); + else + attr = new OpaqueAttribute (typeName); + + try + { + attr->readValueFrom (is, size, version); + _map[name] = attr; + } + catch (...) + { + delete attr; + throw; + } + } + } +} + + +void +staticInitialize () +{ + static Mutex criticalSection; + Lock lock (criticalSection); + + static bool initialized = false; + + if (!initialized) + { + // + // One-time initialization -- register + // some predefined attribute types. + // + + Box2fAttribute::registerAttributeType(); + Box2iAttribute::registerAttributeType(); + ChannelListAttribute::registerAttributeType(); + CompressionAttribute::registerAttributeType(); + ChromaticitiesAttribute::registerAttributeType(); + DoubleAttribute::registerAttributeType(); + EnvmapAttribute::registerAttributeType(); + FloatAttribute::registerAttributeType(); + IntAttribute::registerAttributeType(); + KeyCodeAttribute::registerAttributeType(); + LineOrderAttribute::registerAttributeType(); + M33dAttribute::registerAttributeType(); + M33fAttribute::registerAttributeType(); + M44dAttribute::registerAttributeType(); + M44fAttribute::registerAttributeType(); + PreviewImageAttribute::registerAttributeType(); + RationalAttribute::registerAttributeType(); + StringAttribute::registerAttributeType(); + StringVectorAttribute::registerAttributeType(); + TileDescriptionAttribute::registerAttributeType(); + TimeCodeAttribute::registerAttributeType(); + V2dAttribute::registerAttributeType(); + V2fAttribute::registerAttributeType(); + V2iAttribute::registerAttributeType(); + V3dAttribute::registerAttributeType(); + V3fAttribute::registerAttributeType(); + V3iAttribute::registerAttributeType(); + + initialized = true; + } +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHeader.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,627 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_HEADER_H +#define INCLUDED_IMF_HEADER_H + +//----------------------------------------------------------------------------- +// +// class Header +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include "ImathVec.h" +#include "ImathBox.h" +#include "IexBaseExc.h" +#include +#include +#include + +namespace Imf { + + +class Attribute; +class ChannelList; +class IStream; +class OStream; +class PreviewImage; + + +class Header +{ + public: + + //---------------------------------------------------------------- + // Default constructor -- the display window and the data window + // are both set to Box2i (V2i (0, 0), V2i (width-1, height-1). + //---------------------------------------------------------------- + + Header (int width = 64, + int height = 64, + float pixelAspectRatio = 1, + const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression = ZIP_COMPRESSION); + + + //-------------------------------------------------------------------- + // Constructor -- the data window is specified explicitly; the display + // window is set to Box2i (V2i (0, 0), V2i (width-1, height-1). + //-------------------------------------------------------------------- + + Header (int width, + int height, + const Imath::Box2i &dataWindow, + float pixelAspectRatio = 1, + const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression = ZIP_COMPRESSION); + + + //---------------------------------------------------------- + // Constructor -- the display window and the data window are + // both specified explicitly. + //---------------------------------------------------------- + + Header (const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow, + float pixelAspectRatio = 1, + const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression = ZIP_COMPRESSION); + + + //----------------- + // Copy constructor + //----------------- + + Header (const Header &other); + + + //----------- + // Destructor + //----------- + + ~Header (); + + + //----------- + // Assignment + //----------- + + Header & operator = (const Header &other); + + + //--------------------------------------------------------------- + // Add an attribute: + // + // insert(n,attr) If no attribute with name n exists, a new + // attribute with name n, and the same type as + // attr, is added, and the value of attr is + // copied into the new attribute. + // + // If an attribute with name n exists, and its + // type is the same as attr, the value of attr + // is copied into this attribute. + // + // If an attribute with name n exists, and its + // type is different from attr, an Iex::TypeExc + // is thrown. + // + //--------------------------------------------------------------- + + void insert (const char name[], + const Attribute &attribute); + + void insert (const std::string &name, + const Attribute &attribute); + + //------------------------------------------------------------------ + // Access to existing attributes: + // + // [n] Returns a reference to the attribute + // with name n. If no attribute with + // name n exists, an Iex::ArgExc is thrown. + // + // typedAttribute(n) Returns a reference to the attribute + // with name n and type T. If no attribute + // with name n exists, an Iex::ArgExc is + // thrown. If an attribute with name n + // exists, but its type is not T, an + // Iex::TypeExc is thrown. + // + // findTypedAttribute(n) Returns a pointer to the attribute with + // name n and type T, or 0 if no attribute + // with name n and type T exists. + // + //------------------------------------------------------------------ + + Attribute & operator [] (const char name[]); + const Attribute & operator [] (const char name[]) const; + + Attribute & operator [] (const std::string &name); + const Attribute & operator [] (const std::string &name) const; + + template T& typedAttribute (const char name[]); + template const T& typedAttribute (const char name[]) const; + + template T& typedAttribute (const std::string &name); + template const T& typedAttribute (const std::string &name) const; + + template T* findTypedAttribute (const char name[]); + template const T* findTypedAttribute (const char name[]) const; + + template T* findTypedAttribute (const std::string &name); + template const T* findTypedAttribute (const std::string &name) + const; + + //--------------------------------------------- + // Iterator-style access to existing attributes + //--------------------------------------------- + + typedef std::map AttributeMap; + + class Iterator; + class ConstIterator; + + Iterator begin (); + ConstIterator begin () const; + + Iterator end (); + ConstIterator end () const; + + Iterator find (const char name[]); + ConstIterator find (const char name[]) const; + + Iterator find (const std::string &name); + ConstIterator find (const std::string &name) const; + + + //-------------------------------- + // Access to predefined attributes + //-------------------------------- + + Imath::Box2i & displayWindow (); + const Imath::Box2i & displayWindow () const; + + Imath::Box2i & dataWindow (); + const Imath::Box2i & dataWindow () const; + + float & pixelAspectRatio (); + const float & pixelAspectRatio () const; + + Imath::V2f & screenWindowCenter (); + const Imath::V2f & screenWindowCenter () const; + + float & screenWindowWidth (); + const float & screenWindowWidth () const; + + ChannelList & channels (); + const ChannelList & channels () const; + + LineOrder & lineOrder (); + const LineOrder & lineOrder () const; + + Compression & compression (); + const Compression & compression () const; + + + //---------------------------------------------------------------------- + // Tile Description: + // + // The tile description is a TileDescriptionAttribute whose name + // is "tiles". The "tiles" attribute must be present in any tiled + // image file. When present, it describes various properties of the + // tiles that make up the file. + // + // Convenience functions: + // + // setTileDescription(td) + // calls insert ("tiles", TileDescriptionAttribute (td)) + // + // tileDescription() + // returns typedAttribute("tiles").value() + // + // hasTileDescription() + // return findTypedAttribute("tiles") != 0 + // + //---------------------------------------------------------------------- + + void setTileDescription (const TileDescription & td); + + TileDescription & tileDescription (); + const TileDescription & tileDescription () const; + + bool hasTileDescription() const; + + + //---------------------------------------------------------------------- + // Preview image: + // + // The preview image is a PreviewImageAttribute whose name is "preview". + // This attribute is special -- while an image file is being written, + // the pixels of the preview image can be changed repeatedly by calling + // OutputFile::updatePreviewImage(). + // + // Convenience functions: + // + // setPreviewImage(p) + // calls insert ("preview", PreviewImageAttribute (p)) + // + // previewImage() + // returns typedAttribute("preview").value() + // + // hasPreviewImage() + // return findTypedAttribute("preview") != 0 + // + //---------------------------------------------------------------------- + + void setPreviewImage (const PreviewImage &p); + + PreviewImage & previewImage (); + const PreviewImage & previewImage () const; + + bool hasPreviewImage () const; + + + //------------------------------------------------------------- + // Sanity check -- examines the header, and throws an exception + // if it finds something wrong (empty display window, negative + // pixel aspect ratio, unknown compression sceme etc.) + // + // set isTiled to true if you are checking a tiled/multi-res + // header + //------------------------------------------------------------- + + void sanityCheck (bool isTiled = false) const; + + + //---------------------------------------------------------------- + // Maximum image size and maximim tile size: + // + // sanityCheck() will throw an exception if the width or height of + // the data window exceeds the maximum image width or height, or + // if the size of a tile exceeds the maximum tile width or height. + // + // At program startup the maximum image and tile width and height + // are set to zero, meaning that width and height are unlimited. + // + // Limiting image and tile width and height limits how much memory + // will be allocated when a file is opened. This can help protect + // applications from running out of memory while trying to read + // a damaged image file. + //---------------------------------------------------------------- + + static void setMaxImageSize (int maxWidth, int maxHeight); + static void setMaxTileSize (int maxWidth, int maxHeight); + + + //------------------------------------------------------------------ + // Input and output: + // + // If the header contains a preview image attribute, then writeTo() + // returns the position of that attribute in the output stream; this + // information is used by OutputFile::updatePreviewImage(). + // If the header contains no preview image attribute, then writeTo() + // returns 0. + //------------------------------------------------------------------ + + + Int64 writeTo (OStream &os, + bool isTiled = false) const; + + void readFrom (IStream &is, int &version); + + private: + + AttributeMap _map; +}; + + +//---------- +// Iterators +//---------- + +class Header::Iterator +{ + public: + + Iterator (); + Iterator (const Header::AttributeMap::iterator &i); + + Iterator & operator ++ (); + Iterator operator ++ (int); + + const char * name () const; + Attribute & attribute () const; + + private: + + friend class Header::ConstIterator; + + Header::AttributeMap::iterator _i; +}; + + +class Header::ConstIterator +{ + public: + + ConstIterator (); + ConstIterator (const Header::AttributeMap::const_iterator &i); + ConstIterator (const Header::Iterator &other); + + ConstIterator & operator ++ (); + ConstIterator operator ++ (int); + + const char * name () const; + const Attribute & attribute () const; + + private: + + friend bool operator == (const ConstIterator &, const ConstIterator &); + friend bool operator != (const ConstIterator &, const ConstIterator &); + + Header::AttributeMap::const_iterator _i; +}; + + +//------------------------------------------------------------------------ +// Library initialization: +// +// In a multithreaded program, staticInitialize() must be called once +// during startup, before the program accesses any other functions or +// classes in the IlmImf library. Calling staticInitialize() in this +// way avoids races during initialization of the library's global +// variables. +// +// Single-threaded programs are not required to call staticInitialize(); +// initialization of the library's global variables happens automatically. +// +//------------------------------------------------------------------------ + +void staticInitialize (); + + +//----------------- +// Inline Functions +//----------------- + + +inline +Header::Iterator::Iterator (): _i() +{ + // empty +} + + +inline +Header::Iterator::Iterator (const Header::AttributeMap::iterator &i): _i (i) +{ + // empty +} + + +inline Header::Iterator & +Header::Iterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline Header::Iterator +Header::Iterator::operator ++ (int) +{ + Iterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +Header::Iterator::name () const +{ + return *_i->first; +} + + +inline Attribute & +Header::Iterator::attribute () const +{ + return *_i->second; +} + + +inline +Header::ConstIterator::ConstIterator (): _i() +{ + // empty +} + +inline +Header::ConstIterator::ConstIterator + (const Header::AttributeMap::const_iterator &i): _i (i) +{ + // empty +} + + +inline +Header::ConstIterator::ConstIterator (const Header::Iterator &other): + _i (other._i) +{ + // empty +} + +inline Header::ConstIterator & +Header::ConstIterator::operator ++ () +{ + ++_i; + return *this; +} + + +inline Header::ConstIterator +Header::ConstIterator::operator ++ (int) +{ + ConstIterator tmp = *this; + ++_i; + return tmp; +} + + +inline const char * +Header::ConstIterator::name () const +{ + return *_i->first; +} + + +inline const Attribute & +Header::ConstIterator::attribute () const +{ + return *_i->second; +} + + +inline bool +operator == (const Header::ConstIterator &x, const Header::ConstIterator &y) +{ + return x._i == y._i; +} + + +inline bool +operator != (const Header::ConstIterator &x, const Header::ConstIterator &y) +{ + return !(x == y); +} + + +//--------------------- +// Template definitions +//--------------------- + +template +T & +Header::typedAttribute (const char name[]) +{ + Attribute *attr = &(*this)[name]; + T *tattr = dynamic_cast (attr); + + if (tattr == 0) + throw Iex::TypeExc ("Unexpected attribute type."); + + return *tattr; +} + + +template +const T & +Header::typedAttribute (const char name[]) const +{ + const Attribute *attr = &(*this)[name]; + const T *tattr = dynamic_cast (attr); + + if (tattr == 0) + throw Iex::TypeExc ("Unexpected attribute type."); + + return *tattr; +} + + +template +T & +Header::typedAttribute (const std::string &name) +{ + return typedAttribute (name.c_str()); +} + + +template +const T & +Header::typedAttribute (const std::string &name) const +{ + return typedAttribute (name.c_str()); +} + + +template +T * +Header::findTypedAttribute (const char name[]) +{ + AttributeMap::iterator i = _map.find (name); + return (i == _map.end())? 0: dynamic_cast (i->second); +} + + +template +const T * +Header::findTypedAttribute (const char name[]) const +{ + AttributeMap::const_iterator i = _map.find (name); + return (i == _map.end())? 0: dynamic_cast (i->second); +} + + +template +T * +Header::findTypedAttribute (const std::string &name) +{ + return findTypedAttribute (name.c_str()); +} + + +template +const T * +Header::findTypedAttribute (const std::string &name) const +{ + return findTypedAttribute (name.c_str()); +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1086 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + + +//----------------------------------------------------------------------------- +// +// 16-bit Huffman compression and decompression. +// +// The source code in this file is derived from the 8-bit +// Huffman compression and decompression routines written +// by Christian Rouet for his PIZ image file format. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "Iex.h" +#include +#include +#include + + +using namespace std; +using namespace Iex; + +namespace Imf { +namespace { + + +const int HUF_ENCBITS = 16; // literal (value) bit length +const int HUF_DECBITS = 14; // decoding bit size (>= 8) + +const int HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1; // encoding table size +const int HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size +const int HUF_DECMASK = HUF_DECSIZE - 1; + + +struct HufDec +{ // short code long code + //------------------------------- + int len:8; // code length 0 + int lit:24; // lit p size + int * p; // 0 lits +}; + + +void +invalidNBits () +{ + throw InputExc ("Error in header for Huffman-encoded data " + "(invalid number of bits)."); +} + + +void +tooMuchData () +{ + throw InputExc ("Error in Huffman-encoded data " + "(decoded data are longer than expected)."); +} + + +void +notEnoughData () +{ + throw InputExc ("Error in Huffman-encoded data " + "(decoded data are shorter than expected)."); +} + + +void +invalidCode () +{ + throw InputExc ("Error in Huffman-encoded data " + "(invalid code)."); +} + + +void +invalidTableSize () +{ + throw InputExc ("Error in Huffman-encoded data " + "(invalid code table size)."); +} + + +void +unexpectedEndOfTable () +{ + throw InputExc ("Error in Huffman-encoded data " + "(unexpected end of code table data)."); +} + + +void +tableTooLong () +{ + throw InputExc ("Error in Huffman-encoded data " + "(code table is longer than expected)."); +} + + +void +invalidTableEntry () +{ + throw InputExc ("Error in Huffman-encoded data " + "(invalid code table entry)."); +} + + +inline Int64 +hufLength (Int64 code) +{ + return code & 63; +} + + +inline Int64 +hufCode (Int64 code) +{ + return code >> 6; +} + + +inline void +outputBits (int nBits, Int64 bits, Int64 &c, int &lc, char *&out) +{ + c <<= nBits; + lc += nBits; + + c |= bits; + + while (lc >= 8) + *out++ = (c >> (lc -= 8)); +} + + +inline Int64 +getBits (int nBits, Int64 &c, int &lc, const char *&in) +{ + while (lc < nBits) + { + c = (c << 8) | *(unsigned char *)(in++); + lc += 8; + } + + lc -= nBits; + return (c >> lc) & ((1 << nBits) - 1); +} + + +// +// ENCODING TABLE BUILDING & (UN)PACKING +// + +// +// Build a "canonical" Huffman code table: +// - for each (uncompressed) symbol, hcode contains the length +// of the corresponding code (in the compressed data) +// - canonical codes are computed and stored in hcode +// - the rules for constructing canonical codes are as follows: +// * shorter codes (if filled with zeroes to the right) +// have a numerically higher value than longer codes +// * for codes with the same length, numerical values +// increase with numerical symbol values +// - because the canonical code table can be constructed from +// symbol lengths alone, the code table can be transmitted +// without sending the actual code values +// - see http://www.compressconsult.com/huffman/ +// + +void +hufCanonicalCodeTable (Int64 hcode[HUF_ENCSIZE]) +{ + Int64 n[59]; + + // + // For each i from 0 through 58, count the + // number of different codes of length i, and + // store the count in n[i]. + // + + for (int i = 0; i <= 58; ++i) + n[i] = 0; + + for (int i = 0; i < HUF_ENCSIZE; ++i) + n[hcode[i]] += 1; + + // + // For each i from 58 through 1, compute the + // numerically lowest code with length i, and + // store that code in n[i]. + // + + Int64 c = 0; + + for (int i = 58; i > 0; --i) + { + Int64 nc = ((c + n[i]) >> 1); + n[i] = c; + c = nc; + } + + // + // hcode[i] contains the length, l, of the + // code for symbol i. Assign the next available + // code of length l to the symbol and store both + // l and the code in hcode[i]. + // + + for (int i = 0; i < HUF_ENCSIZE; ++i) + { + int l = hcode[i]; + + if (l > 0) + hcode[i] = l | (n[l]++ << 6); + } +} + + +// +// Compute Huffman codes (based on frq input) and store them in frq: +// - code structure is : [63:lsb - 6:msb] | [5-0: bit length]; +// - max code length is 58 bits; +// - codes outside the range [im-iM] have a null length (unused values); +// - original frequencies are destroyed; +// - encoding tables are used by hufEncode() and hufBuildDecTable(); +// + + +struct FHeapCompare +{ + bool operator () (Int64 *a, Int64 *b) {return *a > *b;} +}; + + +void +hufBuildEncTable + (Int64* frq, // io: input frequencies [HUF_ENCSIZE], output table + int* im, // o: min frq index + int* iM) // o: max frq index +{ + // + // This function assumes that when it is called, array frq + // indicates the frequency of all possible symbols in the data + // that are to be Huffman-encoded. (frq[i] contains the number + // of occurrences of symbol i in the data.) + // + // The loop below does three things: + // + // 1) Finds the minimum and maximum indices that point + // to non-zero entries in frq: + // + // frq[im] != 0, and frq[i] == 0 for all i < im + // frq[iM] != 0, and frq[i] == 0 for all i > iM + // + // 2) Fills array fHeap with pointers to all non-zero + // entries in frq. + // + // 3) Initializes array hlink such that hlink[i] == i + // for all array entries. + // + + AutoArray hlink; + AutoArray fHeap; + + *im = 0; + + while (!frq[*im]) + (*im)++; + + int nf = 0; + + for (int i = *im; i < HUF_ENCSIZE; i++) + { + hlink[i] = i; + + if (frq[i]) + { + fHeap[nf] = &frq[i]; + nf++; + *iM = i; + } + } + + // + // Add a pseudo-symbol, with a frequency count of 1, to frq; + // adjust the fHeap and hlink array accordingly. Function + // hufEncode() uses the pseudo-symbol for run-length encoding. + // + + (*iM)++; + frq[*iM] = 1; + fHeap[nf] = &frq[*iM]; + nf++; + + // + // Build an array, scode, such that scode[i] contains the number + // of bits assigned to symbol i. Conceptually this is done by + // constructing a tree whose leaves are the symbols with non-zero + // frequency: + // + // Make a heap that contains all symbols with a non-zero frequency, + // with the least frequent symbol on top. + // + // Repeat until only one symbol is left on the heap: + // + // Take the two least frequent symbols off the top of the heap. + // Create a new node that has first two nodes as children, and + // whose frequency is the sum of the frequencies of the first + // two nodes. Put the new node back into the heap. + // + // The last node left on the heap is the root of the tree. For each + // leaf node, the distance between the root and the leaf is the length + // of the code for the corresponding symbol. + // + // The loop below doesn't actually build the tree; instead we compute + // the distances of the leaves from the root on the fly. When a new + // node is added to the heap, then that node's descendants are linked + // into a single linear list that starts at the new node, and the code + // lengths of the descendants (that is, their distance from the root + // of the tree) are incremented by one. + // + + make_heap (&fHeap[0], &fHeap[nf], FHeapCompare()); + + AutoArray scode; + memset (scode, 0, sizeof (Int64) * HUF_ENCSIZE); + + while (nf > 1) + { + // + // Find the indices, mm and m, of the two smallest non-zero frq + // values in fHeap, add the smallest frq to the second-smallest + // frq, and remove the smallest frq value from fHeap. + // + + int mm = fHeap[0] - frq; + pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare()); + --nf; + + int m = fHeap[0] - frq; + pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare()); + + frq[m ] += frq[mm]; + push_heap (&fHeap[0], &fHeap[nf], FHeapCompare()); + + // + // The entries in scode are linked into lists with the + // entries in hlink serving as "next" pointers and with + // the end of a list marked by hlink[j] == j. + // + // Traverse the lists that start at scode[m] and scode[mm]. + // For each element visited, increment the length of the + // corresponding code by one bit. (If we visit scode[j] + // during the traversal, then the code for symbol j becomes + // one bit longer.) + // + // Merge the lists that start at scode[m] and scode[mm] + // into a single list that starts at scode[m]. + // + + // + // Add a bit to all codes in the first list. + // + + for (int j = m; true; j = hlink[j]) + { + scode[j]++; + + assert (scode[j] <= 58); + + if (hlink[j] == j) + { + // + // Merge the two lists. + // + + hlink[j] = mm; + break; + } + } + + // + // Add a bit to all codes in the second list + // + + for (int j = mm; true; j = hlink[j]) + { + scode[j]++; + + assert (scode[j] <= 58); + + if (hlink[j] == j) + break; + } + } + + // + // Build a canonical Huffman code table, replacing the code + // lengths in scode with (code, code length) pairs. Copy the + // code table from scode into frq. + // + + hufCanonicalCodeTable (scode); + memcpy (frq, scode, sizeof (Int64) * HUF_ENCSIZE); +} + + +// +// Pack an encoding table: +// - only code lengths, not actual codes, are stored +// - runs of zeroes are compressed as follows: +// +// unpacked packed +// -------------------------------- +// 1 zero 0 (6 bits) +// 2 zeroes 59 +// 3 zeroes 60 +// 4 zeroes 61 +// 5 zeroes 62 +// n zeroes (6 or more) 63 n-6 (6 + 8 bits) +// + +const int SHORT_ZEROCODE_RUN = 59; +const int LONG_ZEROCODE_RUN = 63; +const int SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN; +const int LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN; + + +void +hufPackEncTable + (const Int64* hcode, // i : encoding table [HUF_ENCSIZE] + int im, // i : min hcode index + int iM, // i : max hcode index + char** pcode) // o: ptr to packed table (updated) +{ + char *p = *pcode; + Int64 c = 0; + int lc = 0; + + for (; im <= iM; im++) + { + int l = hufLength (hcode[im]); + + if (l == 0) + { + int zerun = 1; + + while ((im < iM) && (zerun < LONGEST_LONG_RUN)) + { + if (hufLength (hcode[im+1]) > 0 ) + break; + im++; + zerun++; + } + + if (zerun >= 2) + { + if (zerun >= SHORTEST_LONG_RUN) + { + outputBits (6, LONG_ZEROCODE_RUN, c, lc, p); + outputBits (8, zerun - SHORTEST_LONG_RUN, c, lc, p); + } + else + { + outputBits (6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p); + } + continue; + } + } + + outputBits (6, l, c, lc, p); + } + + if (lc > 0) + *p++ = (unsigned char) (c << (8 - lc)); + + *pcode = p; +} + + +// +// Unpack an encoding table packed by hufPackEncTable(): +// + +void +hufUnpackEncTable + (const char** pcode, // io: ptr to packed table (updated) + int ni, // i : input size (in bytes) + int im, // i : min hcode index + int iM, // i : max hcode index + Int64* hcode) // o: encoding table [HUF_ENCSIZE] +{ + memset (hcode, 0, sizeof (Int64) * HUF_ENCSIZE); + + const char *p = *pcode; + Int64 c = 0; + int lc = 0; + + for (; im <= iM; im++) + { + if (p - *pcode > ni) + unexpectedEndOfTable(); + + Int64 l = hcode[im] = getBits (6, c, lc, p); // code length + + if (l == (Int64) LONG_ZEROCODE_RUN) + { + if (p - *pcode > ni) + unexpectedEndOfTable(); + + int zerun = getBits (8, c, lc, p) + SHORTEST_LONG_RUN; + + if (im + zerun > iM + 1) + tableTooLong(); + + while (zerun--) + hcode[im++] = 0; + + im--; + } + else if (l >= (Int64) SHORT_ZEROCODE_RUN) + { + int zerun = l - SHORT_ZEROCODE_RUN + 2; + + if (im + zerun > iM + 1) + tableTooLong(); + + while (zerun--) + hcode[im++] = 0; + + im--; + } + } + + *pcode = (char *) p; + + hufCanonicalCodeTable (hcode); +} + + +// +// DECODING TABLE BUILDING +// + +// +// Clear a newly allocated decoding table so that it contains only zeroes. +// + +void +hufClearDecTable + (HufDec * hdecod) // io: (allocated by caller) + // decoding table [HUF_DECSIZE] +{ + memset (hdecod, 0, sizeof (HufDec) * HUF_DECSIZE); +} + + +// +// Build a decoding hash table based on the encoding table hcode: +// - short codes (<= HUF_DECBITS) are resolved with a single table access; +// - long code entry allocations are not optimized, because long codes are +// unfrequent; +// - decoding tables are used by hufDecode(); +// + +void +hufBuildDecTable + (const Int64* hcode, // i : encoding table + int im, // i : min index in hcode + int iM, // i : max index in hcode + HufDec * hdecod) // o: (allocated by caller) + // decoding table [HUF_DECSIZE] +{ + // + // Init hashtable & loop on all codes. + // Assumes that hufClearDecTable(hdecod) has already been called. + // + + for (; im <= iM; im++) + { + Int64 c = hufCode (hcode[im]); + int l = hufLength (hcode[im]); + + if (c >> l) + { + // + // Error: c is supposed to be an l-bit code, + // but c contains a value that is greater + // than the largest l-bit number. + // + + invalidTableEntry(); + } + + if (l > HUF_DECBITS) + { + // + // Long code: add a secondary entry + // + + HufDec *pl = hdecod + (c >> (l - HUF_DECBITS)); + + if (pl->len) + { + // + // Error: a short code has already + // been stored in table entry *pl. + // + + invalidTableEntry(); + } + + pl->lit++; + + if (pl->p) + { + int *p = pl->p; + pl->p = new int [pl->lit]; + + for (int i = 0; i < pl->lit - 1; ++i) + pl->p[i] = p[i]; + + delete [] p; + } + else + { + pl->p = new int [1]; + } + + pl->p[pl->lit - 1]= im; + } + else if (l) + { + // + // Short code: init all primary entries + // + + HufDec *pl = hdecod + (c << (HUF_DECBITS - l)); + + for (Int64 i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++) + { + if (pl->len || pl->p) + { + // + // Error: a short code or a long code has + // already been stored in table entry *pl. + // + + invalidTableEntry(); + } + + pl->len = l; + pl->lit = im; + } + } + } +} + + +// +// Free the long code entries of a decoding table built by hufBuildDecTable() +// + +void +hufFreeDecTable (HufDec *hdecod) // io: Decoding table +{ + for (int i = 0; i < HUF_DECSIZE; i++) + { + if (hdecod[i].p) + { + delete [] hdecod[i].p; + hdecod[i].p = 0; + } + } +} + + +// +// ENCODING +// + +inline void +outputCode (Int64 code, Int64 &c, int &lc, char *&out) +{ + outputBits (hufLength (code), hufCode (code), c, lc, out); +} + + +inline void +sendCode (Int64 sCode, int runCount, Int64 runCode, + Int64 &c, int &lc, char *&out) +{ + static const int RLMIN = 32; // min count to activate run-length coding + + if (runCount > RLMIN) + { + outputCode (sCode, c, lc, out); + outputCode (runCode, c, lc, out); + outputBits (8, runCount, c, lc, out); + } + else + { + while (runCount-- >= 0) + outputCode (sCode, c, lc, out); + } +} + + +// +// Encode (compress) ni values based on the Huffman encoding table hcode: +// + +int +hufEncode // return: output size (in bits) + (const Int64* hcode, // i : encoding table + const unsigned short* in, // i : uncompressed input buffer + const int ni, // i : input buffer size (in bytes) + int rlc, // i : rl code + char* out) // o: compressed output buffer +{ + char *outStart = out; + Int64 c = 0; // bits not yet written to out + int lc = 0; // number of valid bits in c (LSB) + int s = in[0]; + int cs = 0; + + // + // Loop on input values + // + + for (int i = 1; i < ni; i++) + { + // + // Count same values or send code + // + + if (s == in[i] && cs < 255) + { + cs++; + } + else + { + sendCode (hcode[s], cs, hcode[rlc], c, lc, out); + cs=0; + } + + s = in[i]; + } + + // + // Send remaining code + // + + sendCode (hcode[s], cs, hcode[rlc], c, lc, out); + + if (lc) + *out = (c << (8 - lc)) & 0xff; + + return (out - outStart) * 8 + lc; +} + + +// +// DECODING +// + +// +// In order to force the compiler to inline them, +// getChar() and getCode() are implemented as macros +// instead of "inline" functions. +// + +#define getChar(c, lc, in) \ +{ \ + c = (c << 8) | *(unsigned char *)(in++); \ + lc += 8; \ +} + + +#define getCode(po, rlc, c, lc, in, out, oe) \ +{ \ + if (po == rlc) \ + { \ + if (lc < 8) \ + getChar(c, lc, in); \ + \ + lc -= 8; \ + \ + unsigned char cs = (c >> lc); \ + \ + if (out + cs > oe) \ + tooMuchData(); \ + \ + unsigned short s = out[-1]; \ + \ + while (cs-- > 0) \ + *out++ = s; \ + } \ + else if (out < oe) \ + { \ + *out++ = po; \ + } \ + else \ + { \ + tooMuchData(); \ + } \ +} + + +// +// Decode (uncompress) ni bits based on encoding & decoding tables: +// + +void +hufDecode + (const Int64 * hcode, // i : encoding table + const HufDec * hdecod, // i : decoding table + const char* in, // i : compressed input buffer + int ni, // i : input size (in bits) + int rlc, // i : run-length code + int no, // i : expected output size (in bytes) + unsigned short* out) // o: uncompressed output buffer +{ + Int64 c = 0; + int lc = 0; + unsigned short * outb = out; + unsigned short * oe = out + no; + const char * ie = in + (ni + 7) / 8; // input byte size + + // + // Loop on input bytes + // + + while (in < ie) + { + getChar (c, lc, in); + + // + // Access decoding table + // + + while (lc >= HUF_DECBITS) + { + const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK]; + + if (pl.len) + { + // + // Get short code + // + + lc -= pl.len; + getCode (pl.lit, rlc, c, lc, in, out, oe); + } + else + { + if (!pl.p) + invalidCode(); // wrong code + + // + // Search long code + // + + int j; + + for (j = 0; j < pl.lit; j++) + { + int l = hufLength (hcode[pl.p[j]]); + + while (lc < l && in < ie) // get more bits + getChar (c, lc, in); + + if (lc >= l) + { + if (hufCode (hcode[pl.p[j]]) == + ((c >> (lc - l)) & ((Int64(1) << l) - 1))) + { + // + // Found : get long code + // + + lc -= l; + getCode (pl.p[j], rlc, c, lc, in, out, oe); + break; + } + } + } + + if (j == pl.lit) + invalidCode(); // Not found + } + } + } + + // + // Get remaining (short) codes + // + + int i = (8 - ni) & 7; + c >>= i; + lc -= i; + + while (lc > 0) + { + const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK]; + + if (pl.len) + { + lc -= pl.len; + getCode (pl.lit, rlc, c, lc, in, out, oe); + } + else + { + invalidCode(); // wrong (long) code + } + } + + if (out - outb != no) + notEnoughData (); +} + + +void +countFrequencies (Int64 freq[HUF_ENCSIZE], + const unsigned short data[/*n*/], + int n) +{ + for (int i = 0; i < HUF_ENCSIZE; ++i) + freq[i] = 0; + + for (int i = 0; i < n; ++i) + ++freq[data[i]]; +} + + +void +writeUInt (char buf[4], unsigned int i) +{ + unsigned char *b = (unsigned char *) buf; + + b[0] = i; + b[1] = i >> 8; + b[2] = i >> 16; + b[3] = i >> 24; +} + + +unsigned int +readUInt (const char buf[4]) +{ + const unsigned char *b = (const unsigned char *) buf; + + return ( b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + ((b[3] << 24) & 0xff000000); +} + +} // namespace + + +// +// EXTERNAL INTERFACE +// + + +int +hufCompress (const unsigned short raw[], + int nRaw, + char compressed[]) +{ + if (nRaw == 0) + return 0; + + AutoArray freq; + + countFrequencies (freq, raw, nRaw); + + int im, iM; + hufBuildEncTable (freq, &im, &iM); + + char *tableStart = compressed + 20; + char *tableEnd = tableStart; + hufPackEncTable (freq, im, iM, &tableEnd); + int tableLength = tableEnd - tableStart; + + char *dataStart = tableEnd; + int nBits = hufEncode (freq, raw, nRaw, iM, dataStart); + int dataLength = (nBits + 7) / 8; + + writeUInt (compressed, im); + writeUInt (compressed + 4, iM); + writeUInt (compressed + 8, tableLength); + writeUInt (compressed + 12, nBits); + writeUInt (compressed + 16, 0); // room for future extensions + + return dataStart + dataLength - compressed; +} + + +void +hufUncompress (const char compressed[], + int nCompressed, + unsigned short raw[], + int nRaw) +{ + if (nCompressed == 0) + { + if (nRaw != 0) + notEnoughData(); + + return; + } + + int im = readUInt (compressed); + int iM = readUInt (compressed + 4); + // int tableLength = readUInt (compressed + 8); + int nBits = readUInt (compressed + 12); + + if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) + invalidTableSize(); + + const char *ptr = compressed + 20; + + AutoArray freq; + AutoArray hdec; + + hufClearDecTable (hdec); + + hufUnpackEncTable (&ptr, nCompressed - (ptr - compressed), im, iM, freq); + + try + { + if (nBits > 8 * (nCompressed - (ptr - compressed))) + invalidNBits(); + + hufBuildDecTable (freq, im, iM, hdec); + hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw); + } + catch (...) + { + hufFreeDecTable (hdec); + throw; + } + + hufFreeDecTable (hdec); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfHuf.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_HUF_H +#define INCLUDED_IMF_HUF_H + + +//----------------------------------------------------------------------------- +// +// 16-bit Huffman compression and decompression: +// +// hufCompress (r, nr, c) +// +// Compresses the contents of array r (of length nr), +// stores the compressed data in array c, and returns +// the size of the compressed data (in bytes). +// +// To avoid buffer overflows, the size of array c should +// be at least 2 * nr + 65536. +// +// hufUncompress (c, nc, r, nr) +// +// Uncompresses the data in array c (with length nc), +// and stores the results in array r (with length nr). +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +int +hufCompress (const unsigned short raw[/*nRaw*/], + int nRaw, + char compressed[/*2 * nRaw + 65536*/]); + + +void +hufUncompress (const char compressed[/*nCompressed*/], + int nCompressed, + unsigned short raw[/*nRaw*/], + int nRaw); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,109 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Low-level file input and output for OpenEXR. +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" + +namespace Imf { + + +IStream::IStream (const char fileName[]): _fileName (fileName) +{ + // empty +} + + +IStream::~IStream () +{ + // empty +} + + +bool +IStream::isMemoryMapped () const +{ + return false; +} + + +char * +IStream::readMemoryMapped (int) +{ + throw Iex::InputExc ("Attempt to perform a memory-mapped read " + "on a file that is not memory mapped."); + return 0; +} + + +void +IStream::clear () +{ + // empty +} + + +const char * +IStream::fileName () const +{ + return _fileName.c_str(); +} + + +OStream::OStream (const char fileName[]): _fileName (fileName) +{ + // empty +} + + +OStream::~OStream () +{ + // empty +} + + +const char * +OStream::fileName () const +{ + return _fileName.c_str(); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIO.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,252 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_IO_H +#define INCLUDED_IMF_IO_H + +//----------------------------------------------------------------------------- +// +// Low-level file input and output for OpenEXR. +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { + +//----------------------------------------------------------- +// class IStream -- an abstract base class for input streams. +//----------------------------------------------------------- + +class IStream +{ + public: + + //----------- + // Destructor + //----------- + + virtual ~IStream (); + + + //------------------------------------------------- + // Does this input stream support memory-mapped IO? + // + // Memory-mapped streams can avoid an extra copy; + // memory-mapped read operations return a pointer + // to an internal buffer instead of copying data + // into a buffer supplied by the caller. + //------------------------------------------------- + + virtual bool isMemoryMapped () const; + + + //------------------------------------------------------ + // Read from the stream: + // + // read(c,n) reads n bytes from the stream, and stores + // them in array c. If the stream contains less than n + // bytes, or if an I/O error occurs, read(c,n) throws + // an exception. If read(c,n) reads the last byte from + // the file it returns false, otherwise it returns true. + //------------------------------------------------------ + + virtual bool read (char c[/*n*/], int n) = 0; + + + //--------------------------------------------------- + // Read from a memory-mapped stream: + // + // readMemoryMapped(n) reads n bytes from the stream + // and returns a pointer to the first byte. The + // returned pointer remains valid until the stream + // is closed. If there are less than n byte left to + // read in the stream or if the stream is not memory- + // mapped, readMemoryMapped(n) throws an exception. + //--------------------------------------------------- + + virtual char * readMemoryMapped (int n); + + + //-------------------------------------------------------- + // Get the current reading position, in bytes from the + // beginning of the file. If the next call to read() will + // read the first byte in the file, tellg() returns 0. + //-------------------------------------------------------- + + virtual Int64 tellg () = 0; + + + //------------------------------------------- + // Set the current reading position. + // After calling seekg(i), tellg() returns i. + //------------------------------------------- + + virtual void seekg (Int64 pos) = 0; + + + //------------------------------------------------------ + // Clear error conditions after an operation has failed. + //------------------------------------------------------ + + virtual void clear (); + + + //------------------------------------------------------ + // Get the name of the file associated with this stream. + //------------------------------------------------------ + + const char * fileName () const; + + protected: + + IStream (const char fileName[]); + + private: + + IStream (const IStream &); // not implemented + IStream & operator = (const IStream &); // not implemented + + std::string _fileName; +}; + + +//----------------------------------------------------------- +// class OStream -- an abstract base class for output streams +//----------------------------------------------------------- + +class OStream +{ + public: + + //----------- + // Destructor + //----------- + + virtual ~OStream (); + + + //---------------------------------------------------------- + // Write to the stream: + // + // write(c,n) takes n bytes from array c, and stores them + // in the stream. If an I/O error occurs, write(c,n) throws + // an exception. + //---------------------------------------------------------- + + virtual void write (const char c[/*n*/], int n) = 0; + + + //--------------------------------------------------------- + // Get the current writing position, in bytes from the + // beginning of the file. If the next call to write() will + // start writing at the beginning of the file, tellp() + // returns 0. + //--------------------------------------------------------- + + virtual Int64 tellp () = 0; + + + //------------------------------------------- + // Set the current writing position. + // After calling seekp(i), tellp() returns i. + //------------------------------------------- + + virtual void seekp (Int64 pos) = 0; + + + //------------------------------------------------------ + // Get the name of the file associated with this stream. + //------------------------------------------------------ + + const char * fileName () const; + + protected: + + OStream (const char fileName[]); + + private: + + OStream (const OStream &); // not implemented + OStream & operator = (const OStream &); // not implemented + + std::string _fileName; +}; + + +//----------------------- +// Helper classes for Xdr +//----------------------- + +struct StreamIO +{ + static void + writeChars (OStream &os, const char c[/*n*/], int n) + { + os.write (c, n); + } + + static bool + readChars (IStream &is, char c[/*n*/], int n) + { + return is.read (c, n); + } +}; + + +struct CharPtrIO +{ + static void + writeChars (char *&op, const char c[/*n*/], int n) + { + while (n--) + *op++ = *c++; + } + + static bool + readChars (const char *&ip, char c[/*n*/], int n) + { + while (n--) + *c++ = *ip++; + + return true; + } +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,648 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class InputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include "ImathFun.h" +#include "IlmThreadMutex.h" +#include "Iex.h" +#include "half.h" +#include +#include + + +namespace Imf { + + +using Imath::Box2i; +using Imath::divp; +using Imath::modp; +using IlmThread::Mutex; +using IlmThread::Lock; + + +// +// Struct InputFile::Data stores things that will be +// needed between calls to readPixels +// + +struct InputFile::Data: public Mutex +{ + Header header; + int version; + IStream * is; + bool deleteStream; + + TiledInputFile * tFile; + ScanLineInputFile * sFile; + + LineOrder lineOrder; // the file's lineorder + int minY; // data window's min y coord + int maxY; // data window's max x coord + + FrameBuffer tFileBuffer; + FrameBuffer * cachedBuffer; + + int cachedTileY; + int offset; + + int numThreads; + + Data (bool del, int numThreads); + ~Data (); + + void deleteCachedBuffer(); +}; + + +InputFile::Data::Data (bool del, int numThreads): + is (0), + deleteStream (del), + tFile (0), + sFile (0), + cachedBuffer (0), + cachedTileY (-1), + numThreads (numThreads) +{ + // empty +} + + +InputFile::Data::~Data () +{ + delete tFile; + delete sFile; + + if (deleteStream) + delete is; + + deleteCachedBuffer(); +} + + +void +InputFile::Data::deleteCachedBuffer() +{ + // + // Delete the cached frame buffer, and all memory + // allocated for the slices in the cached frameBuffer. + // + + if (cachedBuffer) + { + for (FrameBuffer::Iterator k = cachedBuffer->begin(); + k != cachedBuffer->end(); + ++k) + { + Slice &s = k.slice(); + + switch (s.type) + { + case UINT: + + delete [] (((unsigned int *)s.base) + offset); + break; + + case HALF: + + delete [] ((half *)s.base + offset); + break; + + case FLOAT: + + delete [] (((float *)s.base) + offset); + break; + } + } + + // + // delete the cached frame buffer + // + + delete cachedBuffer; + cachedBuffer = 0; + } +} + + +namespace { + +void +bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2) +{ + // + // bufferedReadPixels reads each row of tiles that intersect the + // scan-line range (scanLine1 to scanLine2). The previous row of + // tiles is cached in order to prevent redundent tile reads when + // accessing scanlines sequentially. + // + + int minY = std::min (scanLine1, scanLine2); + int maxY = std::max (scanLine1, scanLine2); + + if (minY < ifd->minY || maxY > ifd->maxY) + { + throw Iex::ArgExc ("Tried to read scan line outside " + "the image file's data window."); + } + + // + // The minimum and maximum y tile coordinates that intersect this + // scanline range + // + + int minDy = (minY - ifd->minY) / ifd->tFile->tileYSize(); + int maxDy = (maxY - ifd->minY) / ifd->tFile->tileYSize(); + + // + // Figure out which one is first in the file so we can read without seeking + // + + int yStart, yEnd, yStep; + + if (ifd->lineOrder == DECREASING_Y) + { + yStart = maxDy; + yEnd = minDy - 1; + yStep = -1; + } + else + { + yStart = minDy; + yEnd = maxDy + 1; + yStep = 1; + } + + // + // the number of pixels in a row of tiles + // + + Box2i levelRange = ifd->tFile->dataWindowForLevel(0); + + // + // Read the tiles into our temporary framebuffer and copy them into + // the user's buffer + // + + for (int j = yStart; j != yEnd; j += yStep) + { + Box2i tileRange = ifd->tFile->dataWindowForTile (0, j, 0); + + int minYThisRow = std::max (minY, tileRange.min.y); + int maxYThisRow = std::min (maxY, tileRange.max.y); + + if (j != ifd->cachedTileY) + { + // + // We don't have any valid buffered info, so we need to read in + // from the file. + // + + ifd->tFile->readTiles (0, ifd->tFile->numXTiles (0) - 1, j, j); + ifd->cachedTileY = j; + } + + // + // Copy the data from our cached framebuffer into the user's + // framebuffer. + // + + for (FrameBuffer::ConstIterator k = ifd->cachedBuffer->begin(); + k != ifd->cachedBuffer->end(); + ++k) + { + Slice fromSlice = k.slice(); // slice to write from + Slice toSlice = ifd->tFileBuffer[k.name()]; // slice to write to + + char *fromPtr, *toPtr; + int size = pixelTypeSize (toSlice.type); + + int xStart = levelRange.min.x; + int yStart = minYThisRow; + + while (modp (xStart, toSlice.xSampling) != 0) + ++xStart; + + while (modp (yStart, toSlice.ySampling) != 0) + ++yStart; + + for (int y = yStart; + y <= maxYThisRow; + y += toSlice.ySampling) + { + // + // Set the pointers to the start of the y scanline in + // this row of tiles + // + + fromPtr = fromSlice.base + + (y - tileRange.min.y) * fromSlice.yStride + + xStart * fromSlice.xStride; + + toPtr = toSlice.base + + divp (y, toSlice.ySampling) * toSlice.yStride + + divp (xStart, toSlice.xSampling) * toSlice.xStride; + + // + // Copy all pixels for the scanline in this row of tiles + // + + for (int x = xStart; + x <= levelRange.max.x; + x += toSlice.xSampling) + { + for (size_t i = 0; i < size; ++i) + toPtr[i] = fromPtr[i]; + + fromPtr += fromSlice.xStride * toSlice.xSampling; + toPtr += toSlice.xStride; + } + } + } + } +} + +} // namespace + + + +InputFile::InputFile (const char fileName[], int numThreads): + _data (new Data (true, numThreads)) +{ + try + { + _data->is = new StdIFStream (fileName); + initialize(); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot read image file " + "\"" << fileName << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +InputFile::InputFile (IStream &is, int numThreads): + _data (new Data (false, numThreads)) +{ + try + { + _data->is = &is; + initialize(); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot read image file " + "\"" << is.fileName() << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +void +InputFile::initialize () +{ + _data->header.readFrom (*_data->is, _data->version); + _data->header.sanityCheck (isTiled (_data->version)); + + if (isTiled (_data->version)) + { + _data->lineOrder = _data->header.lineOrder(); + + // + // Save the dataWindow information + // + + const Box2i &dataWindow = _data->header.dataWindow(); + _data->minY = dataWindow.min.y; + _data->maxY = dataWindow.max.y; + + _data->tFile = new TiledInputFile (_data->header, + _data->is, + _data->version, + _data->numThreads); + } + else + { + _data->sFile = new ScanLineInputFile (_data->header, + _data->is, + _data->numThreads); + } +} + + +InputFile::~InputFile () +{ + delete _data; +} + + +const char * +InputFile::fileName () const +{ + return _data->is->fileName(); +} + + +const Header & +InputFile::header () const +{ + return _data->header; +} + + +int +InputFile::version () const +{ + return _data->version; +} + + +void +InputFile::setFrameBuffer (const FrameBuffer &frameBuffer) +{ + if (isTiled (_data->version)) + { + Lock lock (*_data); + + // + // We must invalidate the cached buffer if the new frame + // buffer has a different set of channels than the old + // frame buffer, or if the type of a channel has changed. + // + + const FrameBuffer &oldFrameBuffer = _data->tFileBuffer; + + FrameBuffer::ConstIterator i = oldFrameBuffer.begin(); + FrameBuffer::ConstIterator j = frameBuffer.begin(); + + while (i != oldFrameBuffer.end() && j != frameBuffer.end()) + { + if (strcmp (i.name(), j.name()) || i.slice().type != j.slice().type) + break; + + ++i; + ++j; + } + + if (i != oldFrameBuffer.end() || j != frameBuffer.end()) + { + // + // Invalidate the cached buffer. + // + + _data->deleteCachedBuffer (); + _data->cachedTileY = -1; + + // + // Create new a cached frame buffer. It can hold a single + // row of tiles. The cached buffer can be reused for each + // row of tiles because we set the yTileCoords parameter of + // each Slice to true. + // + + const Box2i &dataWindow = _data->header.dataWindow(); + _data->cachedBuffer = new FrameBuffer(); + _data->offset = dataWindow.min.x; + + int tileRowSize = (dataWindow.max.x - dataWindow.min.x + 1) * + _data->tFile->tileYSize(); + + for (FrameBuffer::ConstIterator k = frameBuffer.begin(); + k != frameBuffer.end(); + ++k) + { + Slice s = k.slice(); + + switch (s.type) + { + case UINT: + + _data->cachedBuffer->insert + (k.name(), + Slice (UINT, + (char *)(new unsigned int[tileRowSize] - + _data->offset), + sizeof (unsigned int), + sizeof (unsigned int) * + _data->tFile->levelWidth(0), + 1, 1, + s.fillValue, + false, true)); + break; + + case HALF: + + _data->cachedBuffer->insert + (k.name(), + Slice (HALF, + (char *)(new half[tileRowSize] - + _data->offset), + sizeof (half), + sizeof (half) * + _data->tFile->levelWidth(0), + 1, 1, + s.fillValue, + false, true)); + break; + + case FLOAT: + + _data->cachedBuffer->insert + (k.name(), + Slice (FLOAT, + (char *)(new float[tileRowSize] - + _data->offset), + sizeof(float), + sizeof(float) * + _data->tFile->levelWidth(0), + 1, 1, + s.fillValue, + false, true)); + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } + + _data->tFile->setFrameBuffer (*_data->cachedBuffer); + } + + _data->tFileBuffer = frameBuffer; + } + else + { + _data->sFile->setFrameBuffer (frameBuffer); + } +} + + +const FrameBuffer & +InputFile::frameBuffer () const +{ + if (isTiled (_data->version)) + { + Lock lock (*_data); + return _data->tFileBuffer; + } + else + { + return _data->sFile->frameBuffer(); + } +} + + +bool +InputFile::isComplete () const +{ + if (isTiled (_data->version)) + return _data->tFile->isComplete(); + else + return _data->sFile->isComplete(); +} + + +void +InputFile::readPixels (int scanLine1, int scanLine2) +{ + if (isTiled (_data->version)) + { + Lock lock (*_data); + bufferedReadPixels (_data, scanLine1, scanLine2); + } + else + { + _data->sFile->readPixels (scanLine1, scanLine2); + } +} + + +void +InputFile::readPixels (int scanLine) +{ + readPixels (scanLine, scanLine); +} + + +void +InputFile::rawPixelData (int firstScanLine, + const char *&pixelData, + int &pixelDataSize) +{ + try + { + if (isTiled (_data->version)) + { + throw Iex::ArgExc ("Tried to read a raw scanline " + "from a tiled image."); + } + + _data->sFile->rawPixelData (firstScanLine, pixelData, pixelDataSize); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading pixel data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +InputFile::rawTileData (int &dx, int &dy, + int &lx, int &ly, + const char *&pixelData, + int &pixelDataSize) +{ + try + { + if (!isTiled (_data->version)) + { + throw Iex::ArgExc ("Tried to read a raw tile " + "from a scanline-based image."); + } + + _data->tFile->rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading tile data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +TiledInputFile* +InputFile::tFile() +{ + if (!isTiled (_data->version)) + { + throw Iex::ArgExc ("Cannot get a TiledInputFile pointer " + "from an InputFile that is not tiled."); + } + + return _data->tFile; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInputFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_INPUT_FILE_H +#define INCLUDED_IMF_INPUT_FILE_H + +//----------------------------------------------------------------------------- +// +// class InputFile -- a scanline-based interface that can be used +// to read both scanline-based and tiled OpenEXR image files. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include + +namespace Imf { + +class TiledInputFile; +class ScanLineInputFile; + + +class InputFile +{ + public: + + //----------------------------------------------------------- + // A constructor that opens the file with the specified name. + // Destroying the InputFile object will close the file. + // + // numThreads determines the number of threads that will be + // used to read the file (see ImfThreading.h). + //----------------------------------------------------------- + + InputFile (const char fileName[], int numThreads = globalThreadCount()); + + + //------------------------------------------------------------- + // A constructor that attaches the new InputFile object to a + // file that has already been opened. Destroying the InputFile + // object will not close the file. + // + // numThreads determines the number of threads that will be + // used to read the file (see ImfThreading.h). + //------------------------------------------------------------- + + InputFile (IStream &is, int numThreads = globalThreadCount()); + + + //----------- + // Destructor + //----------- + + virtual ~InputFile (); + + + //------------------------ + // Access to the file name + //------------------------ + + const char * fileName () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + + //----------------------------------------------------------- + // Set the current frame buffer -- copies the FrameBuffer + // object into the InputFile object. + // + // The current frame buffer is the destination for the pixel + // data read from the file. The current frame buffer must be + // set at least once before readPixels() is called. + // The current frame buffer can be changed after each call + // to readPixels(). + //----------------------------------------------------------- + + void setFrameBuffer (const FrameBuffer &frameBuffer); + + + //----------------------------------- + // Access to the current frame buffer + //----------------------------------- + + const FrameBuffer & frameBuffer () const; + + + //--------------------------------------------------------------- + // Check if the file is complete: + // + // isComplete() returns true if all pixels in the data window are + // present in the input file, or false if any pixels are missing. + // (Another program may still be busy writing the file, or file + // writing may have been aborted prematurely.) + //--------------------------------------------------------------- + + bool isComplete () const; + + + //--------------------------------------------------------------- + // Read pixel data: + // + // readPixels(s1,s2) reads all scan lines with y coordinates + // in the interval [min (s1, s2), max (s1, s2)] from the file, + // and stores them in the current frame buffer. + // + // Both s1 and s2 must be within the interval + // [header().dataWindow().min.y, header().dataWindow().max.y] + // + // The scan lines can be read from the file in random order, and + // individual scan lines may be skipped or read multiple times. + // For maximum efficiency, the scan lines should be read in the + // order in which they were written to the file. + // + // readPixels(s) calls readPixels(s,s). + // + //--------------------------------------------------------------- + + void readPixels (int scanLine1, int scanLine2); + void readPixels (int scanLine); + + + //---------------------------------------------- + // Read a block of raw pixel data from the file, + // without uncompressing it (this function is + // used to implement OutputFile::copyPixels()). + //---------------------------------------------- + + void rawPixelData (int firstScanLine, + const char *&pixelData, + int &pixelDataSize); + + //-------------------------------------------------- + // Read a tile of raw pixel data from the file, + // without uncompressing it (this function is + // used to implement TiledOutputFile::copyPixels()). + //-------------------------------------------------- + + void rawTileData (int &dx, int &dy, + int &lx, int &ly, + const char *&pixelData, + int &pixelDataSize); + + struct Data; + + private: + + InputFile (const InputFile &); // not implemented + InputFile & operator = (const InputFile &); // not implemented + + void initialize (); + TiledInputFile * tFile (); + + friend void TiledOutputFile::copyPixels (InputFile &); + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInt64.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInt64.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInt64.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfInt64.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMF_INT64_H +#define INCLUDED_IMF_INT64_H + +//---------------------------------------------------------------------------- +// +// Int64 -- unsigned 64-bit integers, imported from namespace Imath +// +//---------------------------------------------------------------------------- + +#include "ImathInt64.h" + +namespace Imf { + +using Imath::Int64; + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class IntAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +IntAttribute::staticTypeName () +{ + return "int"; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfIntAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_INT_ATTRIBUTE_H +#define INCLUDED_IMF_INT_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class IntAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +typedef TypedAttribute IntAttribute; +template <> const char *IntAttribute::staticTypeName (); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,216 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class KeyCode +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" + +namespace Imf { + + +KeyCode::KeyCode (int filmMfcCode, + int filmType, + int prefix, + int count, + int perfOffset, + int perfsPerFrame, + int perfsPerCount) +{ + setFilmMfcCode (filmMfcCode); + setFilmType (filmType); + setPrefix (prefix); + setCount (count); + setPerfOffset (perfOffset); + setPerfsPerFrame (perfsPerFrame); + setPerfsPerCount (perfsPerCount); +} + + +KeyCode::KeyCode (const KeyCode &other) +{ + _filmMfcCode = other._filmMfcCode; + _filmType = other._filmType; + _prefix = other._prefix; + _count = other._count; + _perfOffset = other._perfOffset; + _perfsPerFrame = other._perfsPerFrame; + _perfsPerCount = other._perfsPerCount; +} + + +KeyCode & +KeyCode::operator = (const KeyCode &other) +{ + _filmMfcCode = other._filmMfcCode; + _filmType = other._filmType; + _prefix = other._prefix; + _count = other._count; + _perfOffset = other._perfOffset; + _perfsPerFrame = other._perfsPerFrame; + _perfsPerCount = other._perfsPerCount; + + return *this; +} + + +int +KeyCode::filmMfcCode () const +{ + return _filmMfcCode; +} + + +void +KeyCode::setFilmMfcCode (int filmMfcCode) +{ + if (filmMfcCode < 0 || filmMfcCode > 99) + throw Iex::ArgExc ("Invalid key code film manufacturer code " + "(must be between 0 and 99)."); + + _filmMfcCode = filmMfcCode; +} + +int +KeyCode::filmType () const +{ + return _filmType; +} + + +void +KeyCode::setFilmType (int filmType) +{ + if (filmType < 0 || filmType > 99) + throw Iex::ArgExc ("Invalid key code film type " + "(must be between 0 and 99)."); + + _filmType = filmType; +} + +int +KeyCode::prefix () const +{ + return _prefix; +} + + +void +KeyCode::setPrefix (int prefix) +{ + if (prefix < 0 || prefix > 999999) + throw Iex::ArgExc ("Invalid key code prefix " + "(must be between 0 and 999999)."); + + _prefix = prefix; +} + + +int +KeyCode::count () const +{ + return _count; +} + + +void +KeyCode::setCount (int count) +{ + if (count < 0 || count > 9999) + throw Iex::ArgExc ("Invalid key code count " + "(must be between 0 and 9999)."); + + _count = count; +} + + +int +KeyCode::perfOffset () const +{ + return _perfOffset; +} + + +void +KeyCode::setPerfOffset (int perfOffset) +{ + if (perfOffset < 0 || perfOffset > 119) + throw Iex::ArgExc ("Invalid key code perforation offset " + "(must be between 0 and 119)."); + + _perfOffset = perfOffset; +} + + +int +KeyCode::perfsPerFrame () const +{ + return _perfsPerFrame; +} + + +void +KeyCode::setPerfsPerFrame (int perfsPerFrame) +{ + if (perfsPerFrame < 1 || perfsPerFrame > 15) + throw Iex::ArgExc ("Invalid key code number of perforations per frame " + "(must be between 1 and 15)."); + + _perfsPerFrame = perfsPerFrame; +} + + +int +KeyCode::perfsPerCount () const +{ + return _perfsPerCount; +} + + +void +KeyCode::setPerfsPerCount (int perfsPerCount) +{ + if (perfsPerCount < 20 || perfsPerCount > 120) + throw Iex::ArgExc ("Invalid key code number of perforations per count " + "(must be between 20 and 120)."); + + _perfsPerCount = perfsPerCount; +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCode.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,161 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_KEY_CODE_H +#define INCLUDED_IMF_KEY_CODE_H + +//----------------------------------------------------------------------------- +// +// class KeyCode +// +// A KeyCode object uniquely identifies a motion picture film frame. +// The following fields specifiy film manufacturer, film type, film +// roll and the frame's position within the roll: +// +// filmMfcCode film manufacturer code +// range: 0 - 99 +// +// filmType film type code +// range: 0 - 99 +// +// prefix prefix to identify film roll +// range: 0 - 999999 +// +// count count, increments once every perfsPerCount +// perforations (see below) +// range: 0 - 9999 +// +// perfOffset offset of frame, in perforations from +// zero-frame reference mark +// range: 0 - 119 +// +// perfsPerFrame number of perforations per frame +// range: 1 - 15 +// +// typical values: +// +// 1 for 16mm film +// 3, 4, or 8 for 35mm film +// 5, 8 or 15 for 65mm film +// +// perfsPerCount number of perforations per count +// range: 20 - 120 +// +// typical values: +// +// 20 for 16mm film +// 64 for 35mm film +// 80 or 120 for 65mm film +// +// For more information about the interpretation of those fields see +// the following standards and recommended practice publications: +// +// SMPTE 254 Motion-Picture Film (35-mm) - Manufacturer-Printed +// Latent Image Identification Information +// +// SMPTE 268M File Format for Digital Moving-Picture Exchange (DPX) +// (section 6.1) +// +// SMPTE 270 Motion-Picture Film (65-mm) - Manufacturer- Printed +// Latent Image Identification Information +// +// SMPTE 271 Motion-Picture Film (16-mm) - Manufacturer- Printed +// Latent Image Identification Information +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +class KeyCode +{ + public: + + //------------------------------------- + // Constructors and assignment operator + //------------------------------------- + + KeyCode (int filmMfcCode = 0, + int filmType = 0, + int prefix = 0, + int count = 0, + int perfOffset = 0, + int perfsPerFrame = 4, + int perfsPerCount = 64); + + KeyCode (const KeyCode &other); + KeyCode & operator = (const KeyCode &other); + + + //---------------------------- + // Access to individual fields + //---------------------------- + + int filmMfcCode () const; + void setFilmMfcCode (int filmMfcCode); + + int filmType () const; + void setFilmType (int filmType); + + int prefix () const; + void setPrefix (int prefix); + + int count () const; + void setCount (int count); + + int perfOffset () const; + void setPerfOffset (int perfOffset); + + int perfsPerFrame () const; + void setPerfsPerFrame (int perfsPerFrame); + + int perfsPerCount () const; + void setPerfsPerCount (int perfsPerCount); + + private: + + int _filmMfcCode; + int _filmType; + int _prefix; + int _count; + int _perfOffset; + int _perfsPerFrame; + int _perfsPerCount; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class KeyCodeAttribute +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +template <> +const char * +KeyCodeAttribute::staticTypeName () +{ + return "keycode"; +} + + +template <> +void +KeyCodeAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.filmMfcCode()); + Xdr::write (os, _value.filmType()); + Xdr::write (os, _value.prefix()); + Xdr::write (os, _value.count()); + Xdr::write (os, _value.perfOffset()); + Xdr::write (os, _value.perfsPerFrame()); + Xdr::write (os, _value.perfsPerCount()); +} + + +template <> +void +KeyCodeAttribute::readValueFrom (IStream &is, int, int) +{ + int tmp; + + Xdr::read (is, tmp); + _value.setFilmMfcCode (tmp); + + Xdr::read (is, tmp); + _value.setFilmType (tmp); + + Xdr::read (is, tmp); + _value.setPrefix (tmp); + + Xdr::read (is, tmp); + _value.setCount (tmp); + + Xdr::read (is, tmp); + _value.setPerfOffset (tmp); + + Xdr::read (is, tmp); + _value.setPerfsPerFrame (tmp); + + Xdr::read (is, tmp); + _value.setPerfsPerCount (tmp); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,72 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_KEY_CODE_ATTRIBUTE_H +#define INCLUDED_IMF_KEY_CODE_ATTRIBUTE_H + + +//----------------------------------------------------------------------------- +// +// class KeyCodeAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute KeyCodeAttribute; + +template <> +const char *KeyCodeAttribute::staticTypeName (); + +template <> +void KeyCodeAttribute::writeValueTo (OStream &, int) const; + +template <> +void KeyCodeAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrder.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrder.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrder.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrder.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,64 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_LINE_ORDER_H +#define INCLUDED_IMF_LINE_ORDER_H + +//----------------------------------------------------------------------------- +// +// enum LineOrder +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +enum LineOrder +{ + INCREASING_Y = 0, // first scan line has lowest y coordinate + + DECREASING_Y = 1, // first scan line has highest y coordinate + + RANDOM_Y = 2, // only for tiled files; tiles are written + // in random order + + NUM_LINEORDERS // number of different line orders +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,77 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + + +//----------------------------------------------------------------------------- +// +// class LineOrderAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +LineOrderAttribute::staticTypeName () +{ + return "lineOrder"; +} + + +template <> +void +LineOrderAttribute::writeValueTo (OStream &os, int) const +{ + unsigned char tmp = _value; + Xdr::write (os, tmp); +} + + +template <> +void +LineOrderAttribute::readValueFrom (IStream &is, int, int) +{ + unsigned char tmp; + Xdr::read (is, tmp); + _value = LineOrder (tmp); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLineOrderAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_LINE_ORDER_ATTRIBUTE_H +#define INCLUDED_IMF_LINE_ORDER_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class LineOrderAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute LineOrderAttribute; +template <> const char *LineOrderAttribute::staticTypeName (); +template <> void LineOrderAttribute::writeValueTo (OStream &, int) const; +template <> void LineOrderAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,176 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// Lookup tables for efficient application +// of half --> half functions to pixel data, +// and some commonly applied functions. +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + + +void +HalfLut::apply (half *data, int nData, int stride) const +{ + while (nData) + { + *data = _lut (*data); + data += stride; + nData -= 1; + } +} + + +void +HalfLut::apply (const Slice &data, const Imath::Box2i &dataWindow) const +{ + assert (data.type == HALF); + assert (dataWindow.min.x % data.xSampling == 0); + assert (dataWindow.min.y % data.ySampling == 0); + assert ((dataWindow.max.x - dataWindow.min.x + 1) % data.xSampling == 0); + assert ((dataWindow.max.y - dataWindow.min.y + 1) % data.ySampling == 0); + + char *base = data.base + data.yStride * + (dataWindow.min.y / data.ySampling); + + for (int y = dataWindow.min.y; + y <= dataWindow.max.y; + y += data.ySampling) + { + char *pixel = base + data.xStride * + (dataWindow.min.x / data.xSampling); + + for (int x = dataWindow.min.x; + x <= dataWindow.max.x; + x += data.xSampling) + { + *(half *)pixel = _lut (*(half *)pixel); + pixel += data.xStride; + } + + base += data.yStride; + } +} + + +void +RgbaLut::apply (Rgba *data, int nData, int stride) const +{ + while (nData) + { + if (_chn & WRITE_R) + data->r = _lut (data->r); + + if (_chn & WRITE_G) + data->g = _lut (data->g); + + if (_chn & WRITE_B) + data->b = _lut (data->b); + + if (_chn & WRITE_A) + data->a = _lut (data->a); + + data += stride; + nData -= 1; + } +} + + +void +RgbaLut::apply (Rgba *base, + int xStride, int yStride, + const Imath::Box2i &dataWindow) const +{ + base += dataWindow.min.y * yStride; + + for (int y = dataWindow.min.y; y <= dataWindow.max.y; ++y) + { + Rgba *pixel = base + dataWindow.min.x * xStride; + + for (int x = dataWindow.min.x; x <= dataWindow.max.x; ++x) + { + if (_chn & WRITE_R) + pixel->r = _lut (pixel->r); + + if (_chn & WRITE_G) + pixel->g = _lut (pixel->g); + + if (_chn & WRITE_B) + pixel->b = _lut (pixel->b); + + if (_chn & WRITE_A) + pixel->a = _lut (pixel->a); + + pixel += xStride; + } + + base += yStride; + } +} + + +half +round12log (half x) +{ + const float middleval = pow (2.0, -2.5); + int int12log; + + if (x <= 0) + { + return 0; + } + else + { + int12log = int (2000.5 + 200.0 * log (x / middleval) / log (2.0)); + + if (int12log > 4095) + int12log = 4095; + + if (int12log < 1) + int12log = 1; + } + + return middleval * pow (2.0, (int12log - 2000.0) / 200.0); +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfLut.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_LUT_H +#define INCLUDED_IMF_LUT_H + +//----------------------------------------------------------------------------- +// +// Lookup tables for efficient application +// of half --> half functions to pixel data, +// and some commonly applied functions. +// +//----------------------------------------------------------------------------- + +#include +#include +#include "ImathBox.h" +#include "halfFunction.h" + +namespace Imf { + +// +// Lookup table for individual half channels. +// + +class HalfLut +{ + public: + + //------------ + // Constructor + //------------ + + template + HalfLut (Function f); + + + //---------------------------------------------------------------------- + // Apply the table to data[0], data[stride] ... data[(nData-1) * stride] + //---------------------------------------------------------------------- + + void apply (half *data, + int nData, + int stride = 1) const; + + + //--------------------------------------------------------------- + // Apply the table to a frame buffer slice (see ImfFrameBuffer.h) + //--------------------------------------------------------------- + + void apply (const Slice &data, + const Imath::Box2i &dataWindow) const; + + private: + + halfFunction _lut; +}; + + +// +// Lookup table for combined RGBA data. +// + +class RgbaLut +{ + public: + + //------------ + // Constructor + //------------ + + template + RgbaLut (Function f, RgbaChannels chn = WRITE_RGB); + + + //---------------------------------------------------------------------- + // Apply the table to data[0], data[stride] ... data[(nData-1) * stride] + //---------------------------------------------------------------------- + + void apply (Rgba *data, + int nData, + int stride = 1) const; + + + //----------------------------------------------------------------------- + // Apply the table to a frame buffer (see RgbaOutpuFile.setFrameBuffer()) + //----------------------------------------------------------------------- + + void apply (Rgba *base, + int xStride, + int yStride, + const Imath::Box2i &dataWindow) const; + + private: + + halfFunction _lut; + RgbaChannels _chn; +}; + + +// +// 12bit log rounding reduces data to 20 stops with 200 steps per stop. +// That makes 4000 numbers. An extra 96 just come along for the ride. +// Zero explicitly remains zero. The first non-zero half will map to 1 +// in the 0-4095 12log space. A nice power of two number is placed at +// the center [2000] and that number is near 0.18. +// + +half round12log (half x); + + +// +// Round to n-bit precision (n should be between 0 and 10). +// After rounding, the significand's 10-n least significant +// bits will be zero. +// + +struct roundNBit +{ + roundNBit (int n): n(n) {} + half operator () (half x) {return x.round(n);} + int n; +}; + + +// +// Template definitions +// + + +template +HalfLut::HalfLut (Function f): + _lut(f, -HALF_MAX, HALF_MAX, half (0), + half::posInf(), half::negInf(), half::qNan()) +{ + // empty +} + + +template +RgbaLut::RgbaLut (Function f, RgbaChannels chn): + _lut(f, -HALF_MAX, HALF_MAX, half (0), + half::posInf(), half::negInf(), half::qNan()), + _chn(chn) +{ + // empty +} + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,260 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class M33fAttribute +// class M33dAttribute +// class M44fAttribute +// class M44dAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +M33fAttribute::staticTypeName () +{ + return "m33f"; +} + + +template <> +void +M33fAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value[0][0]); + Xdr::write (os, _value[0][1]); + Xdr::write (os, _value[0][2]); + + Xdr::write (os, _value[1][0]); + Xdr::write (os, _value[1][1]); + Xdr::write (os, _value[1][2]); + + Xdr::write (os, _value[2][0]); + Xdr::write (os, _value[2][1]); + Xdr::write (os, _value[2][2]); +} + + +template <> +void +M33fAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value[0][0]); + Xdr::read (is, _value[0][1]); + Xdr::read (is, _value[0][2]); + + Xdr::read (is, _value[1][0]); + Xdr::read (is, _value[1][1]); + Xdr::read (is, _value[1][2]); + + Xdr::read (is, _value[2][0]); + Xdr::read (is, _value[2][1]); + Xdr::read (is, _value[2][2]); +} + + +template <> +const char * +M33dAttribute::staticTypeName () +{ + return "m33d"; +} + + +template <> +void +M33dAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value[0][0]); + Xdr::write (os, _value[0][1]); + Xdr::write (os, _value[0][2]); + + Xdr::write (os, _value[1][0]); + Xdr::write (os, _value[1][1]); + Xdr::write (os, _value[1][2]); + + Xdr::write (os, _value[2][0]); + Xdr::write (os, _value[2][1]); + Xdr::write (os, _value[2][2]); +} + + +template <> +void +M33dAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value[0][0]); + Xdr::read (is, _value[0][1]); + Xdr::read (is, _value[0][2]); + + Xdr::read (is, _value[1][0]); + Xdr::read (is, _value[1][1]); + Xdr::read (is, _value[1][2]); + + Xdr::read (is, _value[2][0]); + Xdr::read (is, _value[2][1]); + Xdr::read (is, _value[2][2]); +} + + +template <> +const char * +M44fAttribute::staticTypeName () +{ + return "m44f"; +} + + +template <> +void +M44fAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value[0][0]); + Xdr::write (os, _value[0][1]); + Xdr::write (os, _value[0][2]); + Xdr::write (os, _value[0][3]); + + Xdr::write (os, _value[1][0]); + Xdr::write (os, _value[1][1]); + Xdr::write (os, _value[1][2]); + Xdr::write (os, _value[1][3]); + + Xdr::write (os, _value[2][0]); + Xdr::write (os, _value[2][1]); + Xdr::write (os, _value[2][2]); + Xdr::write (os, _value[2][3]); + + Xdr::write (os, _value[3][0]); + Xdr::write (os, _value[3][1]); + Xdr::write (os, _value[3][2]); + Xdr::write (os, _value[3][3]); +} + + +template <> +void +M44fAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value[0][0]); + Xdr::read (is, _value[0][1]); + Xdr::read (is, _value[0][2]); + Xdr::read (is, _value[0][3]); + + Xdr::read (is, _value[1][0]); + Xdr::read (is, _value[1][1]); + Xdr::read (is, _value[1][2]); + Xdr::read (is, _value[1][3]); + + Xdr::read (is, _value[2][0]); + Xdr::read (is, _value[2][1]); + Xdr::read (is, _value[2][2]); + Xdr::read (is, _value[2][3]); + + Xdr::read (is, _value[3][0]); + Xdr::read (is, _value[3][1]); + Xdr::read (is, _value[3][2]); + Xdr::read (is, _value[3][3]); +} + + +template <> +const char * +M44dAttribute::staticTypeName () +{ + return "m44d"; +} + + +template <> +void +M44dAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value[0][0]); + Xdr::write (os, _value[0][1]); + Xdr::write (os, _value[0][2]); + Xdr::write (os, _value[0][3]); + + Xdr::write (os, _value[1][0]); + Xdr::write (os, _value[1][1]); + Xdr::write (os, _value[1][2]); + Xdr::write (os, _value[1][3]); + + Xdr::write (os, _value[2][0]); + Xdr::write (os, _value[2][1]); + Xdr::write (os, _value[2][2]); + Xdr::write (os, _value[2][3]); + + Xdr::write (os, _value[3][0]); + Xdr::write (os, _value[3][1]); + Xdr::write (os, _value[3][2]); + Xdr::write (os, _value[3][3]); +} + + +template <> +void +M44dAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value[0][0]); + Xdr::read (is, _value[0][1]); + Xdr::read (is, _value[0][2]); + Xdr::read (is, _value[0][3]); + + Xdr::read (is, _value[1][0]); + Xdr::read (is, _value[1][1]); + Xdr::read (is, _value[1][2]); + Xdr::read (is, _value[1][3]); + + Xdr::read (is, _value[2][0]); + Xdr::read (is, _value[2][1]); + Xdr::read (is, _value[2][2]); + Xdr::read (is, _value[2][3]); + + Xdr::read (is, _value[3][0]); + Xdr::read (is, _value[3][1]); + Xdr::read (is, _value[3][2]); + Xdr::read (is, _value[3][3]); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMatrixAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_MATRIX_ATTRIBUTE_H +#define INCLUDED_IMF_MATRIX_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class M33fAttribute +// class M33dAttribute +// class M44fAttribute +// class M44dAttribute +// +//----------------------------------------------------------------------------- + +#include +#include "ImathMatrix.h" + + +namespace Imf { + + +typedef TypedAttribute M33fAttribute; +template <> const char *M33fAttribute::staticTypeName (); +template <> void M33fAttribute::writeValueTo (OStream &, int) const; +template <> void M33fAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute M33dAttribute; +template <> const char *M33dAttribute::staticTypeName (); +template <> void M33dAttribute::writeValueTo (OStream &, int) const; +template <> void M33dAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute M44fAttribute; +template <> const char *M44fAttribute::staticTypeName (); +template <> void M44fAttribute::writeValueTo (OStream &, int) const; +template <> void M44fAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute M44dAttribute; +template <> const char *M44dAttribute::staticTypeName (); +template <> void M44dAttribute::writeValueTo (OStream &, int) const; +template <> void M44dAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,787 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// Miscellaneous helper functions for OpenEXR image file I/O +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Imf { + +using Imath::Box2i; +using Imath::divp; +using Imath::modp; +using std::vector; + +int +pixelTypeSize (PixelType type) +{ + int size; + + switch (type) + { + case UINT: + + size = Xdr::size (); + break; + + case HALF: + + size = Xdr::size (); + break; + + case FLOAT: + + size = Xdr::size (); + break; + + default: + + throw Iex::ArgExc ("Unknown pixel type."); + } + + return size; +} + + +int +numSamples (int s, int a, int b) +{ + int a1 = divp (a, s); + int b1 = divp (b, s); + return b1 - a1 + ((a1 * s < a)? 0: 1); +} + + +size_t +bytesPerLineTable (const Header &header, + vector &bytesPerLine) +{ + const Box2i &dataWindow = header.dataWindow(); + const ChannelList &channels = header.channels(); + + bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1); + + for (ChannelList::ConstIterator c = channels.begin(); + c != channels.end(); + ++c) + { + int nBytes = pixelTypeSize (c.channel().type) * + (dataWindow.max.x - dataWindow.min.x + 1) / + c.channel().xSampling; + + for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) + if (modp (y, c.channel().ySampling) == 0) + bytesPerLine[i] += nBytes; + } + + size_t maxBytesPerLine = 0; + + for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) + if (maxBytesPerLine < bytesPerLine[i]) + maxBytesPerLine = bytesPerLine[i]; + + return maxBytesPerLine; +} + + +void +offsetInLineBufferTable (const vector &bytesPerLine, + int linesInLineBuffer, + vector &offsetInLineBuffer) +{ + offsetInLineBuffer.resize (bytesPerLine.size()); + + size_t offset = 0; + + for (int i = 0; i < bytesPerLine.size(); ++i) + { + if (i % linesInLineBuffer == 0) + offset = 0; + + offsetInLineBuffer[i] = offset; + offset += bytesPerLine[i]; + } +} + + +int +lineBufferMinY (int y, int minY, int linesInLineBuffer) +{ + return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY; +} + + +int +lineBufferMaxY (int y, int minY, int linesInLineBuffer) +{ + return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1; +} + + +Compressor::Format +defaultFormat (Compressor * compressor) +{ + return compressor? compressor->format(): Compressor::XDR; +} + + +int +numLinesInBuffer (Compressor * compressor) +{ + return compressor? compressor->numScanLines(): 1; +} + + +void +copyIntoFrameBuffer (const char *& readPtr, + char * writePtr, + char * endPtr, + size_t xStride, + bool fill, + double fillValue, + Compressor::Format format, + PixelType typeInFrameBuffer, + PixelType typeInFile) +{ + // + // Copy a horizontal row of pixels from an input + // file's line or tile buffer to a frame buffer. + // + + if (fill) + { + // + // The file contains no data for this channel. + // Store a default value in the frame buffer. + // + + switch (typeInFrameBuffer) + { + case UINT: + + { + unsigned int fillVal = (unsigned int) (fillValue); + + while (writePtr <= endPtr) + { + *(unsigned int *) writePtr = fillVal; + writePtr += xStride; + } + } + break; + + case HALF: + + { + half fillVal = half (fillValue); + + while (writePtr <= endPtr) + { + *(half *) writePtr = fillVal; + writePtr += xStride; + } + } + break; + + case FLOAT: + + { + float fillVal = float (fillValue); + + while (writePtr <= endPtr) + { + *(float *) writePtr = fillVal; + writePtr += xStride; + } + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } + else if (format == Compressor::XDR) + { + // + // The the line or tile buffer is in XDR format. + // + // Convert the pixels from the file's machine- + // independent representation, and store the + // results in the frame buffer. + // + + switch (typeInFrameBuffer) + { + case UINT: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + Xdr::read (readPtr, *(unsigned int *) writePtr); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + half h; + Xdr::read (readPtr, h); + *(unsigned int *) writePtr = halfToUint (h); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + float f; + Xdr::read (readPtr, f); + *(unsigned int *)writePtr = floatToUint (f); + writePtr += xStride; + } + break; + } + break; + + case HALF: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + unsigned int ui; + Xdr::read (readPtr, ui); + *(half *) writePtr = uintToHalf (ui); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + Xdr::read (readPtr, *(half *) writePtr); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + float f; + Xdr::read (readPtr, f); + *(half *) writePtr = floatToHalf (f); + writePtr += xStride; + } + break; + } + break; + + case FLOAT: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + unsigned int ui; + Xdr::read (readPtr, ui); + *(float *) writePtr = float (ui); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + half h; + Xdr::read (readPtr, h); + *(float *) writePtr = float (h); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + Xdr::read (readPtr, *(float *) writePtr); + writePtr += xStride; + } + break; + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } + else + { + // + // The the line or tile buffer is in NATIVE format. + // Copy the results into the frame buffer. + // + + switch (typeInFrameBuffer) + { + case UINT: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + for (size_t i = 0; i < sizeof (unsigned int); ++i) + writePtr[i] = readPtr[i]; + + readPtr += sizeof (unsigned int); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + half h = *(half *) readPtr; + *(unsigned int *) writePtr = halfToUint (h); + readPtr += sizeof (half); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + float f; + + for (size_t i = 0; i < sizeof (float); ++i) + ((char *)&f)[i] = readPtr[i]; + + *(unsigned int *)writePtr = floatToUint (f); + readPtr += sizeof (float); + writePtr += xStride; + } + break; + } + break; + + case HALF: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + unsigned int ui; + + for (size_t i = 0; i < sizeof (unsigned int); ++i) + ((char *)&ui)[i] = readPtr[i]; + + *(half *) writePtr = uintToHalf (ui); + readPtr += sizeof (unsigned int); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + *(half *) writePtr = *(half *)readPtr; + readPtr += sizeof (half); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + float f; + + for (size_t i = 0; i < sizeof (float); ++i) + ((char *)&f)[i] = readPtr[i]; + + *(half *) writePtr = floatToHalf (f); + readPtr += sizeof (float); + writePtr += xStride; + } + break; + } + break; + + case FLOAT: + + switch (typeInFile) + { + case UINT: + + while (writePtr <= endPtr) + { + unsigned int ui; + + for (size_t i = 0; i < sizeof (unsigned int); ++i) + ((char *)&ui)[i] = readPtr[i]; + + *(float *) writePtr = float (ui); + readPtr += sizeof (unsigned int); + writePtr += xStride; + } + break; + + case HALF: + + while (writePtr <= endPtr) + { + half h = *(half *) readPtr; + *(float *) writePtr = float (h); + readPtr += sizeof (half); + writePtr += xStride; + } + break; + + case FLOAT: + + while (writePtr <= endPtr) + { + for (size_t i = 0; i < sizeof (float); ++i) + writePtr[i] = readPtr[i]; + + readPtr += sizeof (float); + writePtr += xStride; + } + break; + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } +} + + +void +skipChannel (const char *& readPtr, + PixelType typeInFile, + size_t xSize) +{ + switch (typeInFile) + { + case UINT: + + Xdr::skip (readPtr, Xdr::size () * xSize); + break; + + case HALF: + + Xdr::skip (readPtr, Xdr::size () * xSize); + break; + + case FLOAT: + + Xdr::skip (readPtr, Xdr::size () * xSize); + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } +} + + +void +convertInPlace (char *& writePtr, + const char *& readPtr, + PixelType type, + size_t numPixels) +{ + switch (type) + { + case UINT: + + for (int j = 0; j < numPixels; ++j) + { + Xdr::write (writePtr, *(const unsigned int *) readPtr); + readPtr += sizeof(unsigned int); + } + break; + + case HALF: + + for (int j = 0; j < numPixels; ++j) + { + Xdr::write (writePtr, *(const half *) readPtr); + readPtr += sizeof(half); + } + break; + + case FLOAT: + + for (int j = 0; j < numPixels; ++j) + { + Xdr::write (writePtr, *(const float *) readPtr); + readPtr += sizeof(float); + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } +} + + +void +copyFromFrameBuffer (char *& writePtr, + const char *& readPtr, + const char * endPtr, + size_t xStride, + Compressor::Format format, + PixelType type) +{ + // + // Copy a horizontal row of pixels from a frame + // buffer to an output file's line or tile buffer. + // + + if (format == Compressor::XDR) + { + // + // The the line or tile buffer is in XDR format. + // + + switch (type) + { + case UINT: + + while (readPtr <= endPtr) + { + Xdr::write (writePtr, + *(const unsigned int *) readPtr); + readPtr += xStride; + } + break; + + case HALF: + + while (readPtr <= endPtr) + { + Xdr::write (writePtr, *(const half *) readPtr); + readPtr += xStride; + } + break; + + case FLOAT: + + while (readPtr <= endPtr) + { + Xdr::write (writePtr, *(const float *) readPtr); + readPtr += xStride; + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } + else + { + // + // The the line or tile buffer is in NATIVE format. + // + + switch (type) + { + case UINT: + + while (readPtr <= endPtr) + { + for (size_t i = 0; i < sizeof (unsigned int); ++i) + *writePtr++ = readPtr[i]; + + readPtr += xStride; + } + break; + + case HALF: + + while (readPtr <= endPtr) + { + *(half *) writePtr = *(const half *) readPtr; + writePtr += sizeof (half); + readPtr += xStride; + } + break; + + case FLOAT: + + while (readPtr <= endPtr) + { + for (size_t i = 0; i < sizeof (float); ++i) + *writePtr++ = readPtr[i]; + + readPtr += xStride; + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } +} + + +void +fillChannelWithZeroes (char *& writePtr, + Compressor::Format format, + PixelType type, + size_t xSize) +{ + if (format == Compressor::XDR) + { + // + // Fill with data in XDR format. + // + + switch (type) + { + case UINT: + + for (int j = 0; j < xSize; ++j) + Xdr::write (writePtr, (unsigned int) 0); + + break; + + case HALF: + + for (int j = 0; j < xSize; ++j) + Xdr::write (writePtr, (half) 0); + + break; + + case FLOAT: + + for (int j = 0; j < xSize; ++j) + Xdr::write (writePtr, (float) 0); + + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } + else + { + // + // Fill with data in NATIVE format. + // + + switch (type) + { + case UINT: + + for (int j = 0; j < xSize; ++j) + { + static const unsigned int ui = 0; + + for (size_t i = 0; i < sizeof (ui); ++i) + *writePtr++ = ((char *) &ui)[i]; + } + break; + + case HALF: + + for (int j = 0; j < xSize; ++j) + { + *(half *) writePtr = half (0); + writePtr += sizeof (half); + } + break; + + case FLOAT: + + for (int j = 0; j < xSize; ++j) + { + static const float f = 0; + + for (size_t i = 0; i < sizeof (f); ++i) + *writePtr++ = ((char *) &f)[i]; + } + break; + + default: + + throw Iex::ArgExc ("Unknown pixel data type."); + } + } +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMisc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,255 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_MISC_H +#define INCLUDED_IMF_MISC_H + +//----------------------------------------------------------------------------- +// +// Miscellaneous helper functions for OpenEXR image file I/O +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + +class Header; + +// +// Return the size of a single value of the indicated type, +// in the machine's native format. +// + +int pixelTypeSize (PixelType type); + + +// +// Return the number of samples a channel with subsampling rate +// s has in the interval [a, b]. For example, a channel with +// subsampling rate 2 (and samples at 0, 2, 4, 6, 8, etc.) has +// 2 samples in the interval [1, 5] and three samples in the +// interval [2, 6]. +// + +int numSamples (int s, int a, int b); + + +// +// Build a table that lists, for each scanline in a file's +// data window, how many bytes are required to store all +// pixels in all channels in that scanline (assuming that +// the pixel data are tightly packed). +// + +size_t bytesPerLineTable (const Header &header, + std::vector &bytesPerLine); + +// +// For scanline-based files, pixels are read or written in +// in multi-scanline blocks. Internally, class OutputFile +// and class ScanLineInputFile store a block of scan lines +// in a "line buffer". Function offsetInLineBufferTable() +// builds a table that lists, for each scan line in a file's +// data window, the location of the pixel data for the scanline +// relative to the beginning of the line buffer. +// + +void offsetInLineBufferTable (const std::vector &bytesPerLine, + int linesInLineBuffer, + std::vector &offsetInLineBuffer); + +// +// For a scanline-based file, compute the range of scanlines +// that occupy the same line buffer as a given scanline, y. +// (minY is the minimum y coordinate of the file's data window.) +// + +int lineBufferMinY (int y, int minY, int linesInLineBuffer); +int lineBufferMaxY (int y, int minY, int linesInLineBuffer); + + +// +// Return a compressor's data format (Compressor::NATIVE or Compressor::XDR). +// If compressor is 0, return Compressor::XDR. +// + +Compressor::Format defaultFormat (Compressor *compressor); + + +// +// Return the number of scan lines a compressor wants to compress +// or uncompress at once. If compressor is 0, return 1. +// + +int numLinesInBuffer (Compressor *compressor); + + +// +// Copy a single channel of a horizontal row of pixels from an +// input file's internal line buffer or tile buffer into a +// frame buffer slice. If necessary, perform on-the-fly data +// type conversion. +// +// readPtr initially points to the beginning of the +// data in the line or tile buffer. readPtr +// is advanced as the pixel data are copied; +// when copyIntoFrameBuffer() returns, +// readPtr points just past the end of the +// copied data. +// +// writePtr, endPtr point to the lefmost and rightmost pixels +// in the frame buffer slice +// +// xStride the xStride for the frame buffer slice +// +// format indicates if the line or tile buffer is +// in NATIVE or XDR format. +// +// typeInFrameBuffer the pixel data type of the frame buffer slice +// +// typeInFile the pixel data type in the input file's channel +// + +void copyIntoFrameBuffer (const char *&readPtr, + char *writePtr, + char *endPtr, + size_t xStride, + bool fill, + double fillValue, + Compressor::Format format, + PixelType typeInFrameBuffer, + PixelType typeInFile); + +// +// Given a pointer into a an input file's line buffer or tile buffer, +// skip over the data for xSize pixels of type typeInFile. +// readPtr initially points to the beginning of the data to be skipped; +// when skipChannel() returns, readPtr points just past the end of the +// skipped data. +// + +void skipChannel (const char *&readPtr, + PixelType typeInFile, + size_t xSize); + +// +// Convert an array of pixel data from the machine's native +// representation to XDR format. +// +// toPtr, fromPtr initially point to the beginning of the input +// and output pixel data arrays; when convertInPlace() +// returns, toPtr and fromPtr point just past the +// end of the input and output arrays. +// If the native representation of the data has the +// same size as the XDR data, then the conversion +// can take in place, without an intermediate +// temporary buffer (toPtr and fromPtr can point +// to the same location). +// +// type the pixel data type +// +// numPixels number of pixels in the input and output arrays +// + +void convertInPlace (char *&toPtr, + const char *&fromPtr, + PixelType type, + size_t numPixels); + +// +// Copy a single channel of a horizontal row of pixels from a +// a frame buffer into an output file's internal line buffer or +// tile buffer. +// +// writePtr initially points to the beginning of the +// data in the line or tile buffer. writePtr +// is advanced as the pixel data are copied; +// when copyFromFrameBuffer() returns, +// writePtr points just past the end of the +// copied data. +// +// readPtr, endPtr point to the lefmost and rightmost pixels +// in the frame buffer slice +// +// xStride the xStride for the frame buffer slice +// +// format indicates if the line or tile buffer is +// in NATIVE or XDR format. +// +// type the pixel data type in the frame buffer +// and in the output file's channel (function +// copyFromFrameBuffer() doesn't do on-the-fly +// data type conversion) +// + +void copyFromFrameBuffer (char *&writePtr, + const char *&readPtr, + const char *endPtr, + size_t xStride, + Compressor::Format format, + PixelType type); + +// +// Fill part of an output file's line buffer or tile buffer with +// zeroes. This routine is called when an output file contains +// a channel for which the frame buffer contains no corresponding +// slice. +// +// writePtr initially points to the beginning of the +// data in the line or tile buffer. When +// fillChannelWithZeroes() returns, writePtr +// points just past the end of the zeroed +// data. +// +// format indicates if the line or tile buffer is +// in NATIVE or XDR format. +// +// type the pixel data type in the line or frame buffer. +// +// xSize number of pixels to be filled with zeroes. +// + +void fillChannelWithZeroes (char *&writePtr, + Compressor::Format format, + PixelType type, + size_t xSize); + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,396 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Weta Digital Ltd +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Weta Digital nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Functions related to accessing channels +// and views in multi-view OpenEXR files. +// +//----------------------------------------------------------------------------- + +#include + +using namespace std; + +namespace Imf { +namespace { + +StringVector +parseString (string name, char c = '.') +{ + // + // Turn name into a list of strings, separating + // on char 'c' with whitespace stripped. + // + + StringVector r; + + while (name.size() > 0) + { + size_t s = name.find (c); + string sec = name.substr (0, s); + + // + // Strip spaces from beginning + // + + while (sec.size() > 0 && sec[0] == ' ') + sec.erase (0, 1); + + // + // Strip spaces from end + // + + while (sec.size() > 0 && sec[sec.size() - 1] == ' ') + sec.erase (sec.size() - 1); + + r.push_back (sec); + + // + // Strip off name including ending 'c' + // + + if (s == name.npos) + name = ""; + else + name = name.substr (s + 1); + } + + return r; +} + + +int +viewNum (const string &view, const StringVector &multiView) +{ + // + // returns which view number is called 'view' + // returns -1 if no member of multiView is 'view' + // (i.e. if viewNum() returns -1, 'view' isn't a view name + // if viewNum() returns 0, 'view' is the default view + // otherwise, it's some other (valid) view + // + + for (int i = 0; i < multiView.size(); ++i) + { + if (multiView[i] == view) + return i; + } + + return -1; +} + +} // namespace + + +string +defaultViewName (const StringVector &multiView) +{ + if (multiView.size() > 0) + return multiView[0]; + else + return ""; +} + + +string +viewFromChannelName (const string &channel, + const StringVector &multiView) +{ + // + // Given the name of a channel, return the name of the view to + // which it belongs. + // + + // + // View name is penultimate section of name separated by periods ('.'s) + // + + StringVector s = parseString (channel, '.'); + + if (s.size() == 0) + return ""; // nothing in, nothing out + + if (s.size() == 1) + { + // + // Return default view name. + // The rules say ALL channels with no periods + // in the name belong to the default view. + // + + return multiView[0]; + } + else + { + // + // size >= 2 - the last part is the channel name, + // the next-to-last part is the view name. + // Check if that part of the name really is + // a valid view and, if it is, return it. + // + + const string &viewName = s[s.size() - 2]; + + if (viewNum (viewName, multiView) >= 0) + return viewName; + else + return ""; // not associated with any particular view + } +} + + +ChannelList +channelsInView (const string & viewName, + const ChannelList & channelList, + const StringVector & multiView) +{ + // + // Return a list of all channels belonging to view viewName. + // + + ChannelList q; + + for (ChannelList::ConstIterator i = channelList.begin(); + i != channelList.end(); + ++i) + { + // + // Get view name for this channel + // + + string view = viewFromChannelName (i.name(), multiView); + + + // + // Insert channel into q if it's a member of view viewName + // + + if (view == viewName) + q.insert (i.name(), i.channel()); + } + + return q; +} + + +ChannelList +channelsInNoView (const ChannelList &channelList, + const StringVector &multiView) +{ + // + // Return a list of channels not associated with any named view. + // + + return channelsInView ("", channelList, multiView); +} + + + +bool +areCounterparts (const string &channel1, + const string &channel2, + const StringVector &multiView) +{ + // + // Given two channels, return true if they are the same + // channel in two different views. + // + + StringVector chan1 = parseString (channel1); + unsigned int size1 = chan1.size(); // number of SECTIONS in string + // name (not string length) + + StringVector chan2 = parseString (channel2); + unsigned int size2 = chan2.size(); + + if (size1 == 0 || size2 == 0) + return false; + + // + // channel1 and channel2 can't be counterparts + // if either channel is in no view. + // + + if (size1 > 1 && viewNum (chan1[size1 - 2], multiView) == -1) + return false; + + if (size2 > 1 && viewNum (chan2[size2 - 2], multiView) == -1) + return false; + + if (viewFromChannelName (channel1, multiView) == + viewFromChannelName (channel2, multiView)) + { + // + // channel1 and channel2 are not counterparts + // if they are in the same view. + // + + return false; + } + + if (size1 == 1) + { + // + // channel1 is a default channel - the channels will only be + // counterparts if channel2 is of the form . + // + + return size2 == 2 && chan1[0] == chan2[1]; + } + + if (size2 == 1) + { + // + // channel2 is a default channel - the channels will only be + // counterparts if channel1 is of the form . + // + + return size1 == 2 && chan2[0] == chan1[1]; + } + + // + // Neither channel is a default channel. To be counterparts both + // channel names must have the same number of components, and + // all components except the penultimate one must be the same. + // + + if (size1 != size2) + return false; + + for(int i = 0; i < size1; ++i) + { + if (i != size1 - 2 && chan1[i] != chan2[i]) + return false; + } + + return true; +} + + +ChannelList +channelInAllViews (const string &channelName, + const ChannelList &channelList, + const StringVector &multiView) +{ + // + // Given the name of a channel, return a + // list of the same channel in all views. + // + + ChannelList q; + + for (ChannelList::ConstIterator i=channelList.begin(); + i != channelList.end(); + ++i) + { + if (i.name() == channelName || + areCounterparts (i.name(), channelName, multiView)) + { + q.insert (i.name(), i.channel()); + } + } + + return q; +} + + +string +channelInOtherView (const string &channelName, + const ChannelList &channelList, + const StringVector &multiView, + const string &otherViewName) +{ + // + // Given the name of a channel in one view, return the + // corresponding channel name for view otherViewName. + // + + for (ChannelList::ConstIterator i=channelList.begin(); + i != channelList.end(); + ++i) + { + if (viewFromChannelName (i.name(), multiView) == otherViewName && + areCounterparts (i.name(), channelName, multiView)) + { + return i.name(); + } + } + + return ""; +} + + +string +insertViewName (const string &channel, + const StringVector &multiView, + int i) +{ + // + // Insert multiView[i] into the channel name if appropriate. + // + + StringVector s = parseString (channel, '.'); + + if (s.size() == 0) + return ""; // nothing in, nothing out + + if (s.size() == 1 && i == 0) + { + // + // Channel in the default view, with no periods in its name. + // Do not insert view name. + // + + return channel; + } + + // + // View name becomes penultimate section of new channel name. + // + + string newName; + + for (int j = 0; j < s.size(); ++j) + { + if (j < s.size() - 1) + newName += s[j] + "."; + else + newName += multiView[i] + "." + s[j]; + } + + return newName; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfMultiView.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,164 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Weta Digital Ltd +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Weta Digital nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_MULTIVIEW_H +#define INCLUDED_IMF_MULTIVIEW_H + +#include +#include + +//----------------------------------------------------------------------------- +// +// Functions related to accessing channels and views in multi-view +// OpenEXR files. +// +// A multi-view image file contains two or more views of the same +// scene, as seen from different viewpoints, for example, a left-eye +// and a right-eye view for stereo displays. Each view has its own +// set of image channels. A naming convention identifies the channels +// that belong to a given view. +// +// A "multiView" attribute in the file header lists the names of the +// views in an image (see ImfStandardAttributes.h), and channel names +// of the form +// +// layer.view.channel +// +// allow channels to be matched with views. +// +// For compatibility with singe-view images, the first view listed in +// the multiView attribute is the "default view", and channels that +// have no periods in their names are considered part of the default +// view. +// +// For example, if a file's multiView attribute lists the views +// "left" and "right", in that order, then "left" is the default +// view. Channels +// +// "R", "left.Z", "diffuse.left.R" +// +// are part of the "left" view; channels +// +// "right.R", "right.Z", "diffuse.right.R" +// +// are part of the "right" view; and channels +// +// "tmp.R", "right.diffuse.R", "diffuse.tmp.R" +// +// belong to no view at all. +// +//----------------------------------------------------------------------------- + +namespace Imf { + +// +// Return the name of the default view given a multi-view string vector, +// that is, return the first element of the string vector. If the string +// vector is empty, return "". +// + +std::string defaultViewName (const StringVector &multiView); + + +// +// Given the name of a channel, return the name of the view to +// which it belongs. Returns the empty string ("") if the channel +// is not a member of any named view. +// + +std::string viewFromChannelName (const std::string &channel, + const StringVector &multiView); + + +// +// Return whether channel1 and channel2 are the same channel but +// viewed in different views. (Return false if either channel +// belongs to no view or if both channels belong to the same view.) +// + +bool areCounterparts (const std::string &channel1, + const std::string &channel2, + const StringVector &multiView); + +// +// Return a list of all channels belonging to view viewName. +// + +ChannelList channelsInView (const std::string &viewName, + const ChannelList &channelList, + const StringVector &multiView); + +// +// Return a list of channels not associated with any view. +// + +ChannelList channelsInNoView (const ChannelList &channelList, + const StringVector &multiView); + +// +// Given the name of a channel, return a list of the same channel +// in all views (for example, given X.left.Y return X.left.Y, +// X.right.Y, X.centre.Y, etc.). +// + +ChannelList channelInAllViews (const std::string &channame, + const ChannelList &channelList, + const StringVector &multiView); + +// +// Given the name of a channel in one view, return the corresponding +// channel name for view otherViewName. Return "" if no corresponding +// channel exists in view otherViewName, or if view otherViewName doesn't +// exist. +// + +std::string channelInOtherView (const std::string &channel, + const ChannelList &channelList, + const StringVector &multiView, + const std::string &otherViewName); + +// +// Given a channel name that does not include a view name, insert +// multiView[i] into the channel name at the appropriate location. +// If i is zero and the channel name contains no periods, then do +// not insert the view name. +// + +std::string insertViewName (const std::string &channel, + const StringVector &multiView, + int i); + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfName.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfName.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfName.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfName.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,146 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_NAME_H +#define INCLUDED_IMF_NAME_H + +//----------------------------------------------------------------------------- +// +// class ImfName -- a zero-terminated string +// with a fixed, small maximum length +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +class Name +{ + public: + + //------------- + // Constructors + //------------- + + Name (); + Name (const char text[]); + + + //-------------------- + // Assignment operator + //-------------------- + + Name & operator = (const char text[]); + + + //--------------------- + // Access to the string + //--------------------- + + const char * text () const {return _text;} + const char * operator * () const {return _text;} + + //--------------- + // Maximum length + //--------------- + + static const int SIZE = 256; + static const int MAX_LENGTH = SIZE - 1; + + private: + + char _text[SIZE]; +}; + + +bool operator == (const Name &x, const Name &y); +bool operator != (const Name &x, const Name &y); +bool operator < (const Name &x, const Name &y); + + +//----------------- +// Inline functions +//----------------- + +inline Name & +Name::operator = (const char text[]) +{ + strncpy (_text, text, MAX_LENGTH); + return *this; +} + + +inline +Name::Name () +{ + _text[0] = 0; +} + + +inline +Name::Name (const char text[]) +{ + *this = text; + _text [MAX_LENGTH] = 0; +} + + +inline bool +operator == (const Name &x, const Name &y) +{ + return strcmp (*x, *y) == 0; +} + + +inline bool +operator != (const Name &x, const Name &y) +{ + return !(x == y); +} + + +inline bool +operator < (const Name &x, const Name &y) +{ + return strcmp (*x, *y) < 0; +} + + +} // namespace IMF + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class OpaqueAttribute +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" +#include + +namespace Imf { + + +OpaqueAttribute::OpaqueAttribute (const char typeName[]): + _typeName (strlen (typeName) + 1), + _dataSize (0) +{ + strcpy (_typeName, typeName); +} + + +OpaqueAttribute::OpaqueAttribute (const OpaqueAttribute &other): + _typeName (strlen (other._typeName) + 1), + _dataSize (other._dataSize), + _data (other._dataSize) +{ + strcpy (_typeName, other._typeName); + _data.resizeErase (other._dataSize); + memcpy ((char *) _data, (const char *) other._data, other._dataSize); +} + + +OpaqueAttribute::~OpaqueAttribute () +{ + // empty +} + + +const char * +OpaqueAttribute::typeName () const +{ + return _typeName; +} + + +Attribute * +OpaqueAttribute::copy () const +{ + return new OpaqueAttribute (*this); +} + + +void +OpaqueAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _data, _dataSize); +} + + +void +OpaqueAttribute::readValueFrom (IStream &is, int size, int) +{ + _data.resizeErase (size); + _dataSize = size; + Xdr::read (is, _data, size); +} + + +void +OpaqueAttribute::copyValueFrom (const Attribute &other) +{ + const OpaqueAttribute *oa = dynamic_cast (&other); + + if (oa == 0 || strcmp (_typeName, oa->_typeName)) + { + THROW (Iex::TypeExc, "Cannot copy the value of an " + "image file attribute of type " + "\"" << other.typeName() << "\" " + "to an attribute of type " + "\"" << _typeName << "\"."); + } + + _data.resizeErase (oa->_dataSize); + _dataSize = oa->_dataSize; + memcpy ((char *) _data, (const char *) oa->_data, oa->_dataSize); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOpaqueAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_OPAQUE_ATTRIBUTE_H +#define INCLUDED_IMF_OPAQUE_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class OpaqueAttribute +// +// When an image file is read, OpqaqueAttribute objects are used +// to hold the values of attributes whose types are not recognized +// by the reading program. OpaqueAttribute objects can be read +// from an image file, copied, and written back to to another image +// file, but their values are inaccessible. +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { + + +class OpaqueAttribute: public Attribute +{ + public: + + //---------------------------- + // Constructors and destructor + //---------------------------- + + OpaqueAttribute (const char typeName[]); + OpaqueAttribute (const OpaqueAttribute &other); + virtual ~OpaqueAttribute (); + + + //------------------------------- + // Get this attribute's type name + //------------------------------- + + virtual const char * typeName () const; + + + //------------------------------ + // Make a copy of this attribute + //------------------------------ + + virtual Attribute * copy () const; + + + //---------------- + // I/O and copying + //---------------- + + virtual void writeValueTo (OStream &os, + int version) const; + + virtual void readValueFrom (IStream &is, + int size, + int version); + + virtual void copyValueFrom (const Attribute &other); + + + private: + + Array _typeName; + long _dataSize; + Array _data; +}; + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1287 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class OutputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include "ImathBox.h" +#include "ImathFun.h" +#include +#include +#include +#include "IlmThreadPool.h" +#include "IlmThreadSemaphore.h" +#include "IlmThreadMutex.h" +#include "Iex.h" +#include +#include +#include +#include + + +namespace Imf { + +using Imath::Box2i; +using Imath::divp; +using Imath::modp; +using std::string; +using std::vector; +using std::ofstream; +using std::min; +using std::max; +using IlmThread::Mutex; +using IlmThread::Lock; +using IlmThread::Semaphore; +using IlmThread::Task; +using IlmThread::TaskGroup; +using IlmThread::ThreadPool; + +namespace { + + +struct OutSliceInfo +{ + PixelType type; + const char * base; + size_t xStride; + size_t yStride; + int xSampling; + int ySampling; + bool zero; + + OutSliceInfo (PixelType type = HALF, + const char *base = 0, + size_t xStride = 0, + size_t yStride = 0, + int xSampling = 1, + int ySampling = 1, + bool zero = false); +}; + + +OutSliceInfo::OutSliceInfo (PixelType t, + const char *b, + size_t xs, size_t ys, + int xsm, int ysm, + bool z) +: + type (t), + base (b), + xStride (xs), + yStride (ys), + xSampling (xsm), + ySampling (ysm), + zero (z) +{ + // empty +} + + +struct LineBuffer +{ + Array buffer; + const char * dataPtr; + int dataSize; + char * endOfLineBufferData; + int minY; + int maxY; + int scanLineMin; + int scanLineMax; + Compressor * compressor; + bool partiallyFull; // has incomplete data + bool hasException; + string exception; + + LineBuffer (Compressor *comp); + ~LineBuffer (); + + void wait () {_sem.wait();} + void post () {_sem.post();} + + private: + + Semaphore _sem; +}; + + +LineBuffer::LineBuffer (Compressor *comp) : + dataPtr (0), + dataSize (0), + compressor (comp), + partiallyFull (false), + hasException (false), + exception (), + _sem (1) +{ + // empty +} + + +LineBuffer::~LineBuffer () +{ + delete compressor; +} + +} // namespace + + +struct OutputFile::Data: public Mutex +{ + Header header; // the image header + int version; // file format version + Int64 previewPosition; // file position for preview + FrameBuffer frameBuffer; // framebuffer to write into + int currentScanLine; // next scanline to be written + int missingScanLines; // number of lines to write + LineOrder lineOrder; // the file's lineorder + int minX; // data window's min x coord + int maxX; // data window's max x coord + int minY; // data window's min y coord + int maxY; // data window's max x coord + vector lineOffsets; // stores offsets in file for + // each scanline + vector bytesPerLine; // combined size of a line over + // all channels + vector offsetInLineBuffer; // offset for each scanline in + // its linebuffer + Compressor::Format format; // compressor's data format + vector slices; // info about channels in file + OStream * os; // file stream to write to + bool deleteStream; + Int64 lineOffsetsPosition; // file position for line + // offset table + Int64 currentPosition; // current file position + + vector lineBuffers; // each holds one line buffer + int linesInBuffer; // number of scanlines each + // buffer holds + size_t lineBufferSize; // size of the line buffer + + Data (bool deleteStream, int numThreads); + ~Data (); + + + inline LineBuffer * getLineBuffer (int number); // hash function from line + // buffer indices into our + // vector of line buffers +}; + + +OutputFile::Data::Data (bool deleteStream, int numThreads): + os (0), + deleteStream (deleteStream), + lineOffsetsPosition (0) +{ + // + // We need at least one lineBuffer, but if threading is used, + // to keep n threads busy we need 2*n lineBuffers. + // + + lineBuffers.resize (max (1, 2 * numThreads)); +} + + +OutputFile::Data::~Data () +{ + if (deleteStream) + delete os; + + for (size_t i = 0; i < lineBuffers.size(); i++) + delete lineBuffers[i]; +} + + +LineBuffer* +OutputFile::Data::getLineBuffer (int number) +{ + return lineBuffers[number % lineBuffers.size()]; +} + + +namespace { + + +Int64 +writeLineOffsets (OStream &os, const vector &lineOffsets) +{ + Int64 pos = os.tellp(); + + if (pos == -1) + Iex::throwErrnoExc ("Cannot determine current file position (%T)."); + + for (unsigned int i = 0; i < lineOffsets.size(); i++) + Xdr::write (os, lineOffsets[i]); + + return pos; +} + + +void +writePixelData (OutputFile::Data *ofd, + int lineBufferMinY, + const char pixelData[], + int pixelDataSize) +{ + // + // Store a block of pixel data in the output file, and try + // to keep track of the current writing position the file + // without calling tellp() (tellp() can be fairly expensive). + // + + Int64 currentPosition = ofd->currentPosition; + ofd->currentPosition = 0; + + if (currentPosition == 0) + currentPosition = ofd->os->tellp(); + + ofd->lineOffsets[(ofd->currentScanLine - ofd->minY) / ofd->linesInBuffer] = + currentPosition; + + #ifdef DEBUG + + assert (ofd->os->tellp() == currentPosition); + + #endif + + Xdr::write (*ofd->os, lineBufferMinY); + Xdr::write (*ofd->os, pixelDataSize); + ofd->os->write (pixelData, pixelDataSize); + + ofd->currentPosition = currentPosition + + Xdr::size() + + Xdr::size() + + pixelDataSize; +} + + +inline void +writePixelData (OutputFile::Data *ofd, const LineBuffer *lineBuffer) +{ + writePixelData (ofd, + lineBuffer->minY, + lineBuffer->dataPtr, + lineBuffer->dataSize); +} + + +void +convertToXdr (OutputFile::Data *ofd, + Array &lineBuffer, + int lineBufferMinY, + int lineBufferMaxY, + int /*inSize*/) +{ + // + // Convert the contents of a lineBuffer from the machine's native + // representation to Xdr format. This function is called by + // CompressLineBuffer::execute(), below, if the compressor wanted + // its input pixel data in the machine's native format, but then + // failed to compress the data (most compressors will expand rather + // than compress random input data). + // + // Note that this routine assumes that the machine's native + // representation of the pixel data has the same size as the + // Xdr representation. This makes it possible to convert the + // pixel data in place, without an intermediate temporary buffer. + // + + int startY, endY; // The first and last scanlines in + // the file that are in the lineBuffer. + int step; + + if (ofd->lineOrder == INCREASING_Y) + { + startY = max (lineBufferMinY, ofd->minY); + endY = min (lineBufferMaxY, ofd->maxY) + 1; + step = 1; + } + else + { + startY = min (lineBufferMaxY, ofd->maxY); + endY = max (lineBufferMinY, ofd->minY) - 1; + step = -1; + } + + // + // Iterate over all scanlines in the lineBuffer to convert. + // + + for (int y = startY; y != endY; y += step) + { + // + // Set these to point to the start of line y. + // We will write to writePtr from readPtr. + // + + char *writePtr = lineBuffer + ofd->offsetInLineBuffer[y - ofd->minY]; + const char *readPtr = writePtr; + + // + // Iterate over all slices in the file. + // + + for (unsigned int i = 0; i < ofd->slices.size(); ++i) + { + // + // Test if scan line y of this channel is + // contains any data (the scan line contains + // data only if y % ySampling == 0). + // + + const OutSliceInfo &slice = ofd->slices[i]; + + if (modp (y, slice.ySampling) != 0) + continue; + + // + // Find the number of sampled pixels, dMaxX-dMinX+1, for + // slice i in scan line y (i.e. pixels within the data window + // for which x % xSampling == 0). + // + + int dMinX = divp (ofd->minX, slice.xSampling); + int dMaxX = divp (ofd->maxX, slice.xSampling); + + // + // Convert the samples in place. + // + + convertInPlace (writePtr, readPtr, slice.type, dMaxX - dMinX + 1); + } + } +} + + +// +// A LineBufferTask encapsulates the task of copying a set of scanlines +// from the user's frame buffer into a LineBuffer object, compressing +// the data if necessary. +// + +class LineBufferTask: public Task +{ + public: + + LineBufferTask (TaskGroup *group, + OutputFile::Data *ofd, + int number, + int scanLineMin, + int scanLineMax); + + virtual ~LineBufferTask (); + + virtual void execute (); + + private: + + OutputFile::Data * _ofd; + LineBuffer * _lineBuffer; +}; + + +LineBufferTask::LineBufferTask + (TaskGroup *group, + OutputFile::Data *ofd, + int number, + int scanLineMin, + int scanLineMax) +: + Task (group), + _ofd (ofd), + _lineBuffer (_ofd->getLineBuffer(number)) +{ + // + // Wait for the lineBuffer to become available + // + + _lineBuffer->wait (); + + // + // Initialize the lineBuffer data if necessary + // + + if (!_lineBuffer->partiallyFull) + { + _lineBuffer->endOfLineBufferData = _lineBuffer->buffer; + + _lineBuffer->minY = _ofd->minY + number * _ofd->linesInBuffer; + + _lineBuffer->maxY = min (_lineBuffer->minY + _ofd->linesInBuffer - 1, + _ofd->maxY); + + _lineBuffer->partiallyFull = true; + } + + _lineBuffer->scanLineMin = max (_lineBuffer->minY, scanLineMin); + _lineBuffer->scanLineMax = min (_lineBuffer->maxY, scanLineMax); +} + + +LineBufferTask::~LineBufferTask () +{ + // + // Signal that the line buffer is now free + // + + _lineBuffer->post (); +} + + +void +LineBufferTask::execute () +{ + try + { + // + // First copy the pixel data from the + // frame buffer into the line buffer + // + + int yStart, yStop, dy; + + if (_ofd->lineOrder == INCREASING_Y) + { + yStart = _lineBuffer->scanLineMin; + yStop = _lineBuffer->scanLineMax + 1; + dy = 1; + } + else + { + yStart = _lineBuffer->scanLineMax; + yStop = _lineBuffer->scanLineMin - 1; + dy = -1; + } + + int y; + + for (y = yStart; y != yStop; y += dy) + { + // + // Gather one scan line's worth of pixel data and store + // them in _ofd->lineBuffer. + // + + char *writePtr = _lineBuffer->buffer + + _ofd->offsetInLineBuffer[y - _ofd->minY]; + // + // Iterate over all image channels. + // + + for (unsigned int i = 0; i < _ofd->slices.size(); ++i) + { + // + // Test if scan line y of this channel contains any data + // (the scan line contains data only if y % ySampling == 0). + // + + const OutSliceInfo &slice = _ofd->slices[i]; + + if (modp (y, slice.ySampling) != 0) + continue; + + // + // Find the x coordinates of the leftmost and rightmost + // sampled pixels (i.e. pixels within the data window + // for which x % xSampling == 0). + // + + int dMinX = divp (_ofd->minX, slice.xSampling); + int dMaxX = divp (_ofd->maxX, slice.xSampling); + + // + // Fill the line buffer with with pixel data. + // + + if (slice.zero) + { + // + // The frame buffer contains no data for this channel. + // Store zeroes in _lineBuffer->buffer. + // + + fillChannelWithZeroes (writePtr, _ofd->format, slice.type, + dMaxX - dMinX + 1); + } + else + { + // + // If necessary, convert the pixel data to Xdr format. + // Then store the pixel data in _ofd->lineBuffer. + // + + const char *linePtr = slice.base + + divp (y, slice.ySampling) * + slice.yStride; + + const char *readPtr = linePtr + dMinX * slice.xStride; + const char *endPtr = linePtr + dMaxX * slice.xStride; + + copyFromFrameBuffer (writePtr, readPtr, endPtr, + slice.xStride, _ofd->format, + slice.type); + } + } + + if (_lineBuffer->endOfLineBufferData < writePtr) + _lineBuffer->endOfLineBufferData = writePtr; + + #ifdef DEBUG + + assert (writePtr - (_lineBuffer->buffer + + _ofd->offsetInLineBuffer[y - _ofd->minY]) == + (int) _ofd->bytesPerLine[y - _ofd->minY]); + + #endif + + } + + // + // If the next scanline isn't past the bounds of the lineBuffer + // then we are done, otherwise compress the linebuffer + // + + if (y >= _lineBuffer->minY && y <= _lineBuffer->maxY) + return; + + _lineBuffer->dataPtr = _lineBuffer->buffer; + + _lineBuffer->dataSize = _lineBuffer->endOfLineBufferData - + _lineBuffer->buffer; + + // + // Compress the data + // + + Compressor *compressor = _lineBuffer->compressor; + + if (compressor) + { + const char *compPtr; + + int compSize = compressor->compress (_lineBuffer->dataPtr, + _lineBuffer->dataSize, + _lineBuffer->minY, compPtr); + + if (compSize < _lineBuffer->dataSize) + { + _lineBuffer->dataSize = compSize; + _lineBuffer->dataPtr = compPtr; + } + else if (_ofd->format == Compressor::NATIVE) + { + // + // The data did not shrink during compression, but + // we cannot write to the file using the machine's + // native format, so we need to convert the lineBuffer + // to Xdr. + // + + convertToXdr (_ofd, _lineBuffer->buffer, _lineBuffer->minY, + _lineBuffer->maxY, _lineBuffer->dataSize); + } + } + + _lineBuffer->partiallyFull = false; + } + catch (std::exception &e) + { + if (!_lineBuffer->hasException) + { + _lineBuffer->exception = e.what (); + _lineBuffer->hasException = true; + } + } + catch (...) + { + if (!_lineBuffer->hasException) + { + _lineBuffer->exception = "unrecognized exception"; + _lineBuffer->hasException = true; + } + } +} + +} // namespace + + +OutputFile::OutputFile + (const char fileName[], + const Header &header, + int numThreads) +: + _data (new Data (true, numThreads)) +{ + try + { + header.sanityCheck(); + _data->os = new StdOFStream (fileName); + initialize (header); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << fileName << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +OutputFile::OutputFile + (OStream &os, + const Header &header, + int numThreads) +: + _data (new Data (false, numThreads)) +{ + try + { + header.sanityCheck(); + _data->os = &os; + initialize (header); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << os.fileName() << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +void +OutputFile::initialize (const Header &header) +{ + _data->header = header; + + const Box2i &dataWindow = header.dataWindow(); + + _data->currentScanLine = (header.lineOrder() == INCREASING_Y)? + dataWindow.min.y: dataWindow.max.y; + + _data->missingScanLines = dataWindow.max.y - dataWindow.min.y + 1; + _data->lineOrder = header.lineOrder(); + _data->minX = dataWindow.min.x; + _data->maxX = dataWindow.max.x; + _data->minY = dataWindow.min.y; + _data->maxY = dataWindow.max.y; + + size_t maxBytesPerLine = bytesPerLineTable (_data->header, + _data->bytesPerLine); + + for (size_t i = 0; i < _data->lineBuffers.size(); ++i) + { + _data->lineBuffers[i] = + new LineBuffer (newCompressor (_data->header.compression(), + maxBytesPerLine, + _data->header)); + } + + LineBuffer *lineBuffer = _data->lineBuffers[0]; + _data->format = defaultFormat (lineBuffer->compressor); + _data->linesInBuffer = numLinesInBuffer (lineBuffer->compressor); + _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer; + + for (size_t i = 0; i < _data->lineBuffers.size(); i++) + _data->lineBuffers[i]->buffer.resizeErase(_data->lineBufferSize); + + int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y + + _data->linesInBuffer) / _data->linesInBuffer; + + _data->lineOffsets.resize (lineOffsetSize); + + offsetInLineBufferTable (_data->bytesPerLine, + _data->linesInBuffer, + _data->offsetInLineBuffer); + + _data->previewPosition = + _data->header.writeTo (*_data->os); + + _data->lineOffsetsPosition = + writeLineOffsets (*_data->os, _data->lineOffsets); + + _data->currentPosition = _data->os->tellp(); +} + + +OutputFile::~OutputFile () +{ + if (_data) + { + { + if (_data->lineOffsetsPosition > 0) + { + try + { + _data->os->seekp (_data->lineOffsetsPosition); + writeLineOffsets (*_data->os, _data->lineOffsets); + } + catch (...) + { + // + // We cannot safely throw any exceptions from here. + // This destructor may have been called because the + // stack is currently being unwound for another + // exception. + // + } + } + } + + delete _data; + } +} + + +const char * +OutputFile::fileName () const +{ + return _data->os->fileName(); +} + + +const Header & +OutputFile::header () const +{ + return _data->header; +} + + +void +OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer) +{ + Lock lock (*_data); + + // + // Check if the new frame buffer descriptor + // is compatible with the image file header. + // + + const ChannelList &channels = _data->header.channels(); + + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); + + if (j == frameBuffer.end()) + continue; + + if (i.channel().type != j.slice().type) + { + THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel " + "of output file \"" << fileName() << "\" is " + "not compatible with the frame buffer's " + "pixel type."); + } + + if (i.channel().xSampling != j.slice().xSampling || + i.channel().ySampling != j.slice().ySampling) + { + THROW (Iex::ArgExc, "X and/or y subsampling factors " + "of \"" << i.name() << "\" channel " + "of output file \"" << fileName() << "\" are " + "not compatible with the frame buffer's " + "subsampling factors."); + } + } + + // + // Initialize slice table for writePixels(). + // + + vector slices; + + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); + + if (j == frameBuffer.end()) + { + // + // Channel i is not present in the frame buffer. + // In the file, channel i will contain only zeroes. + // + + slices.push_back (OutSliceInfo (i.channel().type, + 0, // base + 0, // xStride, + 0, // yStride, + i.channel().xSampling, + i.channel().ySampling, + true)); // zero + } + else + { + // + // Channel i is present in the frame buffer. + // + + slices.push_back (OutSliceInfo (j.slice().type, + j.slice().base, + j.slice().xStride, + j.slice().yStride, + j.slice().xSampling, + j.slice().ySampling, + false)); // zero + } + } + + // + // Store the new frame buffer. + // + + _data->frameBuffer = frameBuffer; + _data->slices = slices; +} + + +const FrameBuffer & +OutputFile::frameBuffer () const +{ + Lock lock (*_data); + return _data->frameBuffer; +} + + +void +OutputFile::writePixels (int numScanLines) +{ + try + { + Lock lock (*_data); + + if (_data->slices.size() == 0) + throw Iex::ArgExc ("No frame buffer specified " + "as pixel data source."); + + // + // Maintain two iterators: + // nextWriteBuffer: next linebuffer to be written to the file + // nextCompressBuffer: next linebuffer to compress + // + + int first = (_data->currentScanLine - _data->minY) / + _data->linesInBuffer; + + int nextWriteBuffer = first; + int nextCompressBuffer; + int stop; + int step; + int scanLineMin; + int scanLineMax; + + { + // + // Create a task group for all line buffer tasks. When the + // taskgroup goes out of scope, the destructor waits until + // all tasks are complete. + // + + TaskGroup taskGroup; + + // + // Determine the range of lineBuffers that intersect the scan + // line range. Then add the initial compression tasks to the + // thread pool. We always add in at least one task but the + // individual task might not do anything if numScanLines == 0. + // + + if (_data->lineOrder == INCREASING_Y) + { + int last = (_data->currentScanLine + (numScanLines - 1) - + _data->minY) / _data->linesInBuffer; + + scanLineMin = _data->currentScanLine; + scanLineMax = _data->currentScanLine + numScanLines - 1; + + int numTasks = max (min ((int)_data->lineBuffers.size(), + last - first + 1), + 1); + + for (int i = 0; i < numTasks; i++) + { + ThreadPool::addGlobalTask + (new LineBufferTask (&taskGroup, _data, first + i, + scanLineMin, scanLineMax)); + } + + nextCompressBuffer = first + numTasks; + stop = last + 1; + step = 1; + } + else + { + int last = (_data->currentScanLine - (numScanLines - 1) - + _data->minY) / _data->linesInBuffer; + + scanLineMax = _data->currentScanLine; + scanLineMin = _data->currentScanLine - numScanLines + 1; + + int numTasks = max (min ((int)_data->lineBuffers.size(), + first - last + 1), + 1); + + for (int i = 0; i < numTasks; i++) + { + ThreadPool::addGlobalTask + (new LineBufferTask (&taskGroup, _data, first - i, + scanLineMin, scanLineMax)); + } + + nextCompressBuffer = first - numTasks; + stop = last - 1; + step = -1; + } + + while (true) + { + if (_data->missingScanLines <= 0) + { + throw Iex::ArgExc ("Tried to write more scan lines " + "than specified by the data window."); + } + + // + // Wait until the next line buffer is ready to be written + // + + LineBuffer *writeBuffer = + _data->getLineBuffer (nextWriteBuffer); + + writeBuffer->wait(); + + int numLines = writeBuffer->scanLineMax - + writeBuffer->scanLineMin + 1; + + _data->missingScanLines -= numLines; + + // + // If the line buffer is only partially full, then it is + // not complete and we cannot write it to disk yet. + // + + if (writeBuffer->partiallyFull) + { + _data->currentScanLine = _data->currentScanLine + + step * numLines; + writeBuffer->post(); + + return; + } + + // + // Write the line buffer + // + + writePixelData (_data, writeBuffer); + nextWriteBuffer += step; + + _data->currentScanLine = _data->currentScanLine + + step * numLines; + + #ifdef DEBUG + + assert (_data->currentScanLine == + ((_data->lineOrder == INCREASING_Y) ? + writeBuffer->scanLineMax + 1: + writeBuffer->scanLineMin - 1)); + + #endif + + // + // Release the lock on the line buffer + // + + writeBuffer->post(); + + // + // If this was the last line buffer in the scanline range + // + + if (nextWriteBuffer == stop) + break; + + // + // If there are no more line buffers to compress, + // then only continue to write out remaining lineBuffers + // + + if (nextCompressBuffer == stop) + continue; + + // + // Add nextCompressBuffer as a compression task + // + + ThreadPool::addGlobalTask + (new LineBufferTask (&taskGroup, _data, nextCompressBuffer, + scanLineMin, scanLineMax)); + + // + // Update the next line buffer we need to compress + // + + nextCompressBuffer += step; + } + + // + // Finish all tasks + // + } + + // + // Exeption handling: + // + // LineBufferTask::execute() may have encountered exceptions, but + // those exceptions occurred in another thread, not in the thread + // that is executing this call to OutputFile::writePixels(). + // LineBufferTask::execute() has caught all exceptions and stored + // the exceptions' what() strings in the line buffers. + // Now we check if any line buffer contains a stored exception; if + // this is the case then we re-throw the exception in this thread. + // (It is possible that multiple line buffers contain stored + // exceptions. We re-throw the first exception we find and + // ignore all others.) + // + + const string *exception = 0; + + for (int i = 0; i < _data->lineBuffers.size(); ++i) + { + LineBuffer *lineBuffer = _data->lineBuffers[i]; + + if (lineBuffer->hasException && !exception) + exception = &lineBuffer->exception; + + lineBuffer->hasException = false; + } + + if (exception) + throw Iex::IoExc (*exception); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Failed to write pixel data to image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +int +OutputFile::currentScanLine () const +{ + Lock lock (*_data); + return _data->currentScanLine; +} + + +void +OutputFile::copyPixels (InputFile &in) +{ + Lock lock (*_data); + + // + // Check if this file's and and the InputFile's + // headers are compatible. + // + + const Header &hdr = _data->header; + const Header &inHdr = in.header(); + + if (inHdr.find("tiles") != inHdr.end()) + THROW (Iex::ArgExc, "Cannot copy pixels from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\". " + "The input file is tiled, but the output file is " + "not. Try using TiledOutputFile::copyPixels " + "instead."); + + if (!(hdr.dataWindow() == inHdr.dataWindow())) + THROW (Iex::ArgExc, "Cannot copy pixels from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\". " + "The files have different data windows."); + + if (!(hdr.lineOrder() == inHdr.lineOrder())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files have different line orders."); + + if (!(hdr.compression() == inHdr.compression())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files use different compression methods."); + + if (!(hdr.channels() == inHdr.channels())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files have different channel lists."); + + // + // Verify that no pixel data have been written to this file yet. + // + + const Box2i &dataWindow = hdr.dataWindow(); + + if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1) + THROW (Iex::LogicExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "\"" << fileName() << "\" already contains " + "pixel data."); + + // + // Copy the pixel data. + // + + while (_data->missingScanLines > 0) + { + const char *pixelData; + int pixelDataSize; + + in.rawPixelData (_data->currentScanLine, pixelData, pixelDataSize); + + writePixelData (_data, lineBufferMinY (_data->currentScanLine, + _data->minY, + _data->linesInBuffer), + pixelData, pixelDataSize); + + _data->currentScanLine += (_data->lineOrder == INCREASING_Y)? + _data->linesInBuffer: -_data->linesInBuffer; + + _data->missingScanLines -= _data->linesInBuffer; + } +} + + +void +OutputFile::updatePreviewImage (const PreviewRgba newPixels[]) +{ + Lock lock (*_data); + + if (_data->previewPosition <= 0) + THROW (Iex::LogicExc, "Cannot update preview image pixels. " + "File \"" << fileName() << "\" does not " + "contain a preview image."); + + // + // Store the new pixels in the header's preview image attribute. + // + + PreviewImageAttribute &pia = + _data->header.typedAttribute ("preview"); + + PreviewImage &pi = pia.value(); + PreviewRgba *pixels = pi.pixels(); + int numPixels = pi.width() * pi.height(); + + for (int i = 0; i < numPixels; ++i) + pixels[i] = newPixels[i]; + + // + // Save the current file position, jump to the position in + // the file where the preview image starts, store the new + // preview image, and jump back to the saved file position. + // + + Int64 savedPosition = _data->os->tellp(); + + try + { + _data->os->seekp (_data->previewPosition); + pia.writeValueTo (*_data->os, _data->version); + _data->os->seekp (savedPosition); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Cannot update preview image pixels for " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +OutputFile::breakScanLine (int y, int offset, int length, char c) +{ + Lock lock (*_data); + + Int64 position = + _data->lineOffsets[(y - _data->minY) / _data->linesInBuffer]; + + if (!position) + THROW (Iex::ArgExc, "Cannot overwrite scan line " << y << ". " + "The scan line has not yet been stored in " + "file \"" << fileName() << "\"."); + + _data->currentPosition = 0; + _data->os->seekp (position + offset); + + for (int i = 0; i < length; ++i) + _data->os->write (&c, 1); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfOutputFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,241 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_OUTPUT_FILE_H +#define INCLUDED_IMF_OUTPUT_FILE_H + +//----------------------------------------------------------------------------- +// +// class OutputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + +class InputFile; +struct PreviewRgba; + + +class OutputFile +{ + public: + + //----------------------------------------------------------- + // Constructor -- opens the file and writes the file header. + // The file header is also copied into the OutputFile object, + // and can later be accessed via the header() method. + // Destroying this OutputFile object automatically closes + // the file. + // + // numThreads determines the number of threads that will be + // used to write the file (see ImfThreading.h). + //----------------------------------------------------------- + + OutputFile (const char fileName[], const Header &header, + int numThreads = globalThreadCount()); + + + //------------------------------------------------------------ + // Constructor -- attaches the new OutputFile object to a file + // that has already been opened, and writes the file header. + // The file header is also copied into the OutputFile object, + // and can later be accessed via the header() method. + // Destroying this OutputFile object does not automatically + // close the file. + // + // numThreads determines the number of threads that will be + // used to write the file (see ImfThreading.h). + //------------------------------------------------------------ + + OutputFile (OStream &os, const Header &header, + int numThreads = globalThreadCount()); + + + //------------------------------------------------- + // Destructor + // + // Destroying the OutputFile object before writing + // all scan lines within the data window results in + // an incomplete file. + //------------------------------------------------- + + virtual ~OutputFile (); + + + //------------------------ + // Access to the file name + //------------------------ + + const char * fileName () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + + + //------------------------------------------------------- + // Set the current frame buffer -- copies the FrameBuffer + // object into the OutputFile object. + // + // The current frame buffer is the source of the pixel + // data written to the file. The current frame buffer + // must be set at least once before writePixels() is + // called. The current frame buffer can be changed + // after each call to writePixels. + //------------------------------------------------------- + + void setFrameBuffer (const FrameBuffer &frameBuffer); + + + //----------------------------------- + // Access to the current frame buffer + //----------------------------------- + + const FrameBuffer & frameBuffer () const; + + + //------------------------------------------------------------------- + // Write pixel data: + // + // writePixels(n) retrieves the next n scan lines worth of data from + // the current frame buffer, starting with the scan line indicated by + // currentScanLine(), and stores the data in the output file, and + // progressing in the direction indicated by header.lineOrder(). + // + // To produce a complete and correct file, exactly m scan lines must + // be written, where m is equal to + // header().dataWindow().max.y - header().dataWindow().min.y + 1. + //------------------------------------------------------------------- + + void writePixels (int numScanLines = 1); + + + //------------------------------------------------------------------ + // Access to the current scan line: + // + // currentScanLine() returns the y coordinate of the first scan line + // that will be read from the current frame buffer during the next + // call to writePixels(). + // + // If header.lineOrder() == INCREASING_Y: + // + // The current scan line before the first call to writePixels() + // is header().dataWindow().min.y. After writing each scan line, + // the current scan line is incremented by 1. + // + // If header.lineOrder() == DECREASING_Y: + // + // The current scan line before the first call to writePixels() + // is header().dataWindow().max.y. After writing each scan line, + // the current scan line is decremented by 1. + // + //------------------------------------------------------------------ + + int currentScanLine () const; + + + //-------------------------------------------------------------- + // Shortcut to copy all pixels from an InputFile into this file, + // without uncompressing and then recompressing the pixel data. + // This file's header must be compatible with the InputFile's + // header: The two header's "dataWindow", "compression", + // "lineOrder" and "channels" attributes must be the same. + //-------------------------------------------------------------- + + void copyPixels (InputFile &in); + + + //-------------------------------------------------------------- + // Updating the preview image: + // + // updatePreviewImage() supplies a new set of pixels for the + // preview image attribute in the file's header. If the header + // does not contain a preview image, updatePreviewImage() throws + // an Iex::LogicExc. + // + // Note: updatePreviewImage() is necessary because images are + // often stored in a file incrementally, a few scan lines at a + // time, while the image is being generated. Since the preview + // image is an attribute in the file's header, it gets stored in + // the file as soon as the file is opened, but we may not know + // what the preview image should look like until we have written + // the last scan line of the main image. + // + //-------------------------------------------------------------- + + void updatePreviewImage (const PreviewRgba newPixels[]); + + + //--------------------------------------------------------- + // Break a scan line -- for testing and debugging only: + // + // breakScanLine(y,p,n,c) introduces an error into the + // output file by writing n copies of character c, starting + // p bytes from the beginning of the pixel data block that + // contains scan line y. + // + // Warning: Calling this function usually results in a + // broken image file. The file or parts of it may not + // be readable, or the file may contain bad data. + // + //--------------------------------------------------------- + + void breakScanLine (int y, int offset, int length, char c); + + + struct Data; + + private: + + OutputFile (const OutputFile &); // not implemented + OutputFile & operator = (const OutputFile &); // not implemented + + void initialize (const Header &header); + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPixelType.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPixelType.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPixelType.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPixelType.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_PIXEL_TYPE_H +#define INCLUDED_IMF_PIXEL_TYPE_H + +//----------------------------------------------------------------------------- +// +// enum PixelType +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +enum PixelType +{ + UINT = 0, // unsigned int (32 bit) + HALF = 1, // half (16 bit floating point) + FLOAT = 2, // float (32 bit floating point) + + NUM_PIXELTYPES // number of different pixel types +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,666 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class PizCompressor +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Imf { + +using Imath::divp; +using Imath::modp; +using Imath::Box2i; +using Imath::V2i; +using Iex::InputExc; + +namespace { + +// +// Functions to compress the range of values in the pixel data +// + +const int USHORT_RANGE = (1 << 16); +const int BITMAP_SIZE = (USHORT_RANGE >> 3); + +void +bitmapFromData (const unsigned short data[/*nData*/], + int nData, + unsigned char bitmap[BITMAP_SIZE], + unsigned short &minNonZero, + unsigned short &maxNonZero) +{ + for (int i = 0; i < BITMAP_SIZE; ++i) + bitmap[i] = 0; + + for (int i = 0; i < nData; ++i) + bitmap[data[i] >> 3] |= (1 << (data[i] & 7)); + + bitmap[0] &= ~1; // zero is not explicitly stored in + // the bitmap; we assume that the + // data always contain zeroes + minNonZero = BITMAP_SIZE - 1; + maxNonZero = 0; + + for (int i = 0; i < BITMAP_SIZE; ++i) + { + if (bitmap[i]) + { + if (minNonZero > i) + minNonZero = i; + if (maxNonZero < i) + maxNonZero = i; + } + } +} + + +unsigned short +forwardLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE], + unsigned short lut[USHORT_RANGE]) +{ + int k = 0; + + for (int i = 0; i < USHORT_RANGE; ++i) + { + if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) + lut[i] = k++; + else + lut[i] = 0; + } + + return k - 1; // maximum value stored in lut[], +} // i.e. number of ones in bitmap minus 1 + + +unsigned short +reverseLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE], + unsigned short lut[USHORT_RANGE]) +{ + int k = 0; + + for (int i = 0; i < USHORT_RANGE; ++i) + { + if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) + lut[k++] = i; + } + + int n = k - 1; + + while (k < USHORT_RANGE) + lut[k++] = 0; + + return n; // maximum k where lut[k] is non-zero, +} // i.e. number of ones in bitmap minus 1 + + +void +applyLut (const unsigned short lut[USHORT_RANGE], + unsigned short data[/*nData*/], + int nData) +{ + for (int i = 0; i < nData; ++i) + data[i] = lut[data[i]]; +} + + +} // namespace + + +struct PizCompressor::ChannelData +{ + unsigned short * start; + unsigned short * end; + int nx; + int ny; + int ys; + int size; +}; + + +PizCompressor::PizCompressor + (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines) +: + Compressor (hdr), + _maxScanLineSize (maxScanLineSize), + _format (XDR), + _numScanLines (numScanLines), + _tmpBuffer (0), + _outBuffer (0), + _numChans (0), + _channels (hdr.channels()), + _channelData (0) +{ + size_t tmpBufferSize = + uiMult (maxScanLineSize, numScanLines) / 2; + + size_t outBufferSize = + uiAdd (uiMult (maxScanLineSize, numScanLines), + size_t (65536 + 8192)); + + _tmpBuffer = new unsigned short + [checkArraySize (tmpBufferSize, sizeof (unsigned short))]; + + _outBuffer = new char [outBufferSize]; + + const ChannelList &channels = header().channels(); + bool onlyHalfChannels = true; + + for (ChannelList::ConstIterator c = channels.begin(); + c != channels.end(); + ++c) + { + _numChans++; + + assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0); + + if (c.channel().type != HALF) + onlyHalfChannels = false; + } + + _channelData = new ChannelData[_numChans]; + + const Box2i &dataWindow = hdr.dataWindow(); + + _minX = dataWindow.min.x; + _maxX = dataWindow.max.x; + _maxY = dataWindow.max.y; + + // + // We can support uncompressed data in the machine's native format + // if all image channels are of type HALF, and if the Xdr and the + // native represenations of a half have the same size. + // + + if (onlyHalfChannels && (sizeof (half) == pixelTypeSize (HALF))) + _format = NATIVE; +} + + +PizCompressor::~PizCompressor () +{ + delete [] _tmpBuffer; + delete [] _outBuffer; + delete [] _channelData; +} + + +int +PizCompressor::numScanLines () const +{ + return _numScanLines; +} + + +Compressor::Format +PizCompressor::format () const +{ + return _format; +} + + +int +PizCompressor::compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return compress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + numScanLines() - 1)), + outPtr); +} + + +int +PizCompressor::compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + return compress (inPtr, inSize, range, outPtr); +} + + +int +PizCompressor::uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return uncompress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + numScanLines() - 1)), + outPtr); +} + + +int +PizCompressor::uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + return uncompress (inPtr, inSize, range, outPtr); +} + + +int +PizCompressor::compress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + // + // This is the compress function which is used by both the tiled and + // scanline compression routines. + // + + // + // Special case ­- empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Rearrange the pixel data so that the wavelet + // and Huffman encoders can process them easily. + // + // The wavelet and Huffman encoders both handle only + // 16-bit data, so 32-bit data must be split into smaller + // pieces. We treat each 32-bit channel (UINT, FLOAT) as + // two interleaved 16-bit channels. + // + + int minX = range.min.x; + int maxX = range.max.x; + int minY = range.min.y; + int maxY = range.max.y; + + if (maxY > _maxY) + maxY = _maxY; + + if (maxX > _maxX) + maxX = _maxX; + + unsigned short *tmpBufferEnd = _tmpBuffer; + int i = 0; + + for (ChannelList::ConstIterator c = _channels.begin(); + c != _channels.end(); + ++c, ++i) + { + ChannelData &cd = _channelData[i]; + + cd.start = tmpBufferEnd; + cd.end = cd.start; + + cd.nx = numSamples (c.channel().xSampling, minX, maxX); + cd.ny = numSamples (c.channel().ySampling, minY, maxY); + cd.ys = c.channel().ySampling; + + cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF); + + tmpBufferEnd += cd.nx * cd.ny * cd.size; + } + + if (_format == XDR) + { + // + // Machine-independent (Xdr) data format + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + for (int x = cd.nx * cd.size; x > 0; --x) + { + Xdr::read (inPtr, *cd.end); + ++cd.end; + } + } + } + } + else + { + // + // Native, machine-dependent data format + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + int n = cd.nx * cd.size; + memcpy (cd.end, inPtr, n * sizeof (unsigned short)); + inPtr += n * sizeof (unsigned short); + cd.end += n; + } + } + } + + #if defined (DEBUG) + + for (int i = 1; i < _numChans; ++i) + assert (_channelData[i-1].end == _channelData[i].start); + + assert (_channelData[_numChans-1].end == tmpBufferEnd); + + #endif + + // + // Compress the range of the pixel data + // + + AutoArray bitmap; + unsigned short minNonZero; + unsigned short maxNonZero; + + bitmapFromData (_tmpBuffer, + tmpBufferEnd - _tmpBuffer, + bitmap, + minNonZero, maxNonZero); + + AutoArray lut; + unsigned short maxValue = forwardLutFromBitmap (bitmap, lut); + applyLut (lut, _tmpBuffer, tmpBufferEnd - _tmpBuffer); + + // + // Store range compression info in _outBuffer + // + + char *buf = _outBuffer; + + Xdr::write (buf, minNonZero); + Xdr::write (buf, maxNonZero); + + if (minNonZero <= maxNonZero) + { + Xdr::write (buf, (char *) &bitmap[0] + minNonZero, + maxNonZero - minNonZero + 1); + } + + // + // Apply wavelet encoding + // + + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + for (int j = 0; j < cd.size; ++j) + { + wav2Encode (cd.start + j, + cd.nx, cd.size, + cd.ny, cd.nx * cd.size, + maxValue); + } + } + + // + // Apply Huffman encoding; append the result to _outBuffer + // + + char *lengthPtr = buf; + Xdr::write (buf, int(0)); + + int length = hufCompress (_tmpBuffer, tmpBufferEnd - _tmpBuffer, buf); + Xdr::write (lengthPtr, length); + + outPtr = _outBuffer; + return buf - _outBuffer + length; +} + + +int +PizCompressor::uncompress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr) +{ + // + // This is the cunompress function which is used by both the tiled and + // scanline decompression routines. + // + + // + // Special case - empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Determine the layout of the compressed pixel data + // + + int minX = range.min.x; + int maxX = range.max.x; + int minY = range.min.y; + int maxY = range.max.y; + + if (maxY > _maxY) + maxY = _maxY; + + if (maxX > _maxX) + maxX = _maxX; + + unsigned short *tmpBufferEnd = _tmpBuffer; + int i = 0; + + for (ChannelList::ConstIterator c = _channels.begin(); + c != _channels.end(); + ++c, ++i) + { + ChannelData &cd = _channelData[i]; + + cd.start = tmpBufferEnd; + cd.end = cd.start; + + cd.nx = numSamples (c.channel().xSampling, minX, maxX); + cd.ny = numSamples (c.channel().ySampling, minY, maxY); + cd.ys = c.channel().ySampling; + + cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF); + + tmpBufferEnd += cd.nx * cd.ny * cd.size; + } + + // + // Read range compression data + // + + unsigned short minNonZero; + unsigned short maxNonZero; + + AutoArray bitmap; + memset (bitmap, 0, sizeof (unsigned char) * BITMAP_SIZE); + + Xdr::read (inPtr, minNonZero); + Xdr::read (inPtr, maxNonZero); + + if (maxNonZero >= BITMAP_SIZE) + { + throw InputExc ("Error in header for PIZ-compressed data " + "(invalid bitmap size)."); + } + + if (minNonZero <= maxNonZero) + { + Xdr::read (inPtr, (char *) &bitmap[0] + minNonZero, + maxNonZero - minNonZero + 1); + } + + AutoArray lut; + unsigned short maxValue = reverseLutFromBitmap (bitmap, lut); + + // + // Huffman decoding + // + + int length; + Xdr::read (inPtr, length); + + hufUncompress (inPtr, length, _tmpBuffer, tmpBufferEnd - _tmpBuffer); + + // + // Wavelet decoding + // + + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + for (int j = 0; j < cd.size; ++j) + { + wav2Decode (cd.start + j, + cd.nx, cd.size, + cd.ny, cd.nx * cd.size, + maxValue); + } + } + + // + // Expand the pixel data to their original range + // + + applyLut (lut, _tmpBuffer, tmpBufferEnd - _tmpBuffer); + + // + // Rearrange the pixel data into the format expected by the caller. + // + + char *outEnd = _outBuffer; + + if (_format == XDR) + { + // + // Machine-independent (Xdr) data format + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + for (int x = cd.nx * cd.size; x > 0; --x) + { + Xdr::write (outEnd, *cd.end); + ++cd.end; + } + } + } + } + else + { + // + // Native, machine-dependent data format + // + + for (int y = minY; y <= maxY; ++y) + { + for (int i = 0; i < _numChans; ++i) + { + ChannelData &cd = _channelData[i]; + + if (modp (y, cd.ys) != 0) + continue; + + int n = cd.nx * cd.size; + memcpy (outEnd, cd.end, n * sizeof (unsigned short)); + outEnd += n * sizeof (unsigned short); + cd.end += n; + } + } + } + + #if defined (DEBUG) + + for (int i = 1; i < _numChans; ++i) + assert (_channelData[i-1].end == _channelData[i].start); + + assert (_channelData[_numChans-1].end == tmpBufferEnd); + + #endif + + outPtr = _outBuffer; + return outEnd - _outBuffer; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPizCompressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,115 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_PIZ_COMPRESSOR_H +#define INCLUDED_IMF_PIZ_COMPRESSOR_H + +//----------------------------------------------------------------------------- +// +// class PizCompressor -- uses Wavelet and Huffman encoding. +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + +class ChannelList; + + +class PizCompressor: public Compressor +{ + public: + + PizCompressor (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines); + + virtual ~PizCompressor (); + + virtual int numScanLines () const; + + virtual Format format () const; + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + private: + + struct ChannelData; + + int compress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int uncompress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int _maxScanLineSize; + Format _format; + int _numScanLines; + unsigned short * _tmpBuffer; + char * _outBuffer; + int _numChans; + const ChannelList & _channels; + ChannelData * _channelData; + int _minX; + int _maxX; + int _maxY; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class PreviewImage +// +//----------------------------------------------------------------------------- + +#include +#include +#include "Iex.h" + +namespace Imf { + + +PreviewImage::PreviewImage (unsigned int width, + unsigned int height, + const PreviewRgba pixels[]) +{ + _width = width; + _height = height; + _pixels = new PreviewRgba + [checkArraySize (uiMult (_width, _height), sizeof (PreviewRgba))]; + + if (pixels) + { + for (unsigned int i = 0; i < _width * _height; ++i) + _pixels[i] = pixels[i]; + } + else + { + for (unsigned int i = 0; i < _width * _height; ++i) + _pixels[i] = PreviewRgba(); + } +} + + +PreviewImage::PreviewImage (const PreviewImage &other): + _width (other._width), + _height (other._height), + _pixels (new PreviewRgba [other._width * other._height]) +{ + for (unsigned int i = 0; i < _width * _height; ++i) + _pixels[i] = other._pixels[i]; +} + + +PreviewImage::~PreviewImage () +{ + delete [] _pixels; +} + + +PreviewImage & +PreviewImage::operator = (const PreviewImage &other) +{ + delete [] _pixels; + + _width = other._width; + _height = other._height; + _pixels = new PreviewRgba [other._width * other._height]; + + for (unsigned int i = 0; i < _width * _height; ++i) + _pixels[i] = other._pixels[i]; + + return *this; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImage.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,131 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_PREVIEW_IMAGE_H +#define INCLUDED_IMF_PREVIEW_IMAGE_H + +//----------------------------------------------------------------------------- +// +// class PreviewImage -- a usually small, low-dynamic range image, +// that is intended to be stored in an image file's header. +// +// struct PreviewRgba -- holds the value of a PreviewImage pixel. +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +struct PreviewRgba +{ + unsigned char r; // Red, green and blue components of + unsigned char g; // the pixel's color; intensity is + unsigned char b; // proportional to pow (x/255, 2.2), + // where x is r, g, or b. + + unsigned char a; // The pixel's alpha; 0 == transparent, + // 255 == opaque. + + PreviewRgba (unsigned char r = 0, + unsigned char g = 0, + unsigned char b = 0, + unsigned char a = 255) + : r(r), g(g), b(b), a(a) {} +}; + + +class PreviewImage +{ + public: + + //-------------------------------------------------------------------- + // Constructor: + // + // PreviewImage(w,h,p) constructs a preview image with w by h pixels + // whose initial values are specified in pixel array p. The x and y + // coordinates of the pixels in p go from 0 to w-1, and from 0 to h-1. + // The pixel with coordinates (x, y) is at address p + y*w + x. + // Pixel (0, 0) is in the upper left corner of the preview image. + // If p is zero, the pixels in the preview image are initialized with + // (r = 0, b = 0, g = 0, a = 255). + // + //-------------------------------------------------------------------- + + PreviewImage (unsigned int width = 0, + unsigned int height = 0, + const PreviewRgba pixels[] = 0); + + //----------------------------------------------------- + // Copy constructor, destructor and assignment operator + //----------------------------------------------------- + + PreviewImage (const PreviewImage &other); + ~PreviewImage (); + + PreviewImage & operator = (const PreviewImage &other); + + + //----------------------------------------------- + // Access to width, height and to the pixel array + //----------------------------------------------- + + unsigned int width () const {return _width;} + unsigned int height () const {return _height;} + + PreviewRgba * pixels () {return _pixels;} + const PreviewRgba * pixels () const {return _pixels;} + + + //---------------------------- + // Access to individual pixels + //---------------------------- + + PreviewRgba & pixel (unsigned int x, unsigned int y) + {return _pixels[y * _width + x];} + + const PreviewRgba & pixel (unsigned int x, unsigned int y) const + {return _pixels[y * _width + x];} + + private: + + unsigned int _width; + unsigned int _height; + PreviewRgba * _pixels; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class PreviewImageAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +PreviewImageAttribute::staticTypeName () +{ + return "preview"; +} + + +template <> +void +PreviewImageAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.width()); + Xdr::write (os, _value.height()); + + int numPixels = _value.width() * _value.height(); + const PreviewRgba *pixels = _value.pixels(); + + for (int i = 0; i < numPixels; ++i) + { + Xdr::write (os, pixels[i].r); + Xdr::write (os, pixels[i].g); + Xdr::write (os, pixels[i].b); + Xdr::write (os, pixels[i].a); + } +} + + +template <> +void +PreviewImageAttribute::readValueFrom (IStream &is, int, int) +{ + int width, height; + + Xdr::read (is, width); + Xdr::read (is, height); + + PreviewImage p (width, height); + + int numPixels = p.width() * p.height(); + PreviewRgba *pixels = p.pixels(); + + for (int i = 0; i < numPixels; ++i) + { + Xdr::read (is, pixels[i].r); + Xdr::read (is, pixels[i].g); + Xdr::read (is, pixels[i].b); + Xdr::read (is, pixels[i].a); + } + + _value = p; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_PREVIEW_IMAGE_ATTRIBUTE_H +#define INCLUDED_IMF_PREVIEW_IMAGE_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class PreviewImageAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute PreviewImageAttribute; + +template <> +const char *PreviewImageAttribute::staticTypeName (); + +template <> +void PreviewImageAttribute::writeValueTo (OStream &, int) const; + +template <> +void PreviewImageAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,550 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Pixar Animation Studios +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Pixar Animation Studios nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Pxr24Compressor +// +// This compressor is based on source code that was contributed to +// OpenEXR by Pixar Animation Studios. The compression method was +// developed by Loren Carpenter. +// +// The compressor preprocesses the pixel data to reduce entropy, +// and then calls zlib. +// +// Compression of HALF and UINT channels is lossless, but compressing +// FLOAT channels is lossy: 32-bit floating-point numbers are converted +// to 24 bits by rounding the significand to 15 bits. +// +// When the compressor is invoked, the caller has already arranged +// the pixel data so that the values for each channel appear in a +// contiguous block of memory. The compressor converts the pixel +// values to unsigned integers: For UINT, this is a no-op. HALF +// values are simply re-interpreted as 16-bit integers. FLOAT +// values are converted to 24 bits, and the resulting bit patterns +// are interpreted as integers. The compressor then replaces each +// value with the difference between the value and its left neighbor. +// This turns flat fields in the image into zeroes, and ramps into +// strings of similar values. Next, each difference is split into +// 2, 3 or 4 bytes, and the bytes are transposed so that all the +// most significant bytes end up in a contiguous block, followed +// by the second most significant bytes, and so on. The resulting +// string of bytes is compressed with zlib. +// +//----------------------------------------------------------------------------- +//#define ZLIB_WINAPI + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Imath; + +namespace Imf { +namespace { + +// +// Conversion from 32-bit to 24-bit floating-point numbers. +// Conversion back to 32 bits is simply an 8-bit shift to the left. +// + +inline unsigned int +floatToFloat24 (float f) +{ + union + { + float f; + unsigned int i; + } u; + + u.f = f; + + // + // Disassemble the 32-bit floating point number, f, + // into sign, s, exponent, e, and significand, m. + // + + unsigned int s = u.i & 0x80000000; + unsigned int e = u.i & 0x7f800000; + unsigned int m = u.i & 0x007fffff; + unsigned int i; + + if (e == 0x7f800000) + { + if (m) + { + // + // F is a NAN; we preserve the sign bit and + // the 15 leftmost bits of the significand, + // with one exception: If the 15 leftmost + // bits are all zero, the NAN would turn + // into an infinity, so we have to set at + // least one bit in the significand. + // + + m >>= 8; + i = (e >> 8) | m | (m == 0); + } + else + { + // + // F is an infinity. + // + + i = e >> 8; + } + } + else + { + // + // F is finite, round the significand to 15 bits. + // + + i = ((e | m) + (m & 0x00000080)) >> 8; + + if (i >= 0x7f8000) + { + // + // F was close to FLT_MAX, and the significand was + // rounded up, resulting in an exponent overflow. + // Avoid the overflow by truncating the significand + // instead of rounding it. + // + + i = (e | m) >> 8; + } + } + + return (s >> 8) | i; +} + + +void +notEnoughData () +{ + throw Iex::InputExc ("Error decompressing data " + "(input data are shorter than expected)."); +} + + +void +tooMuchData () +{ + throw Iex::InputExc ("Error decompressing data " + "(input data are longer than expected)."); +} + +} // namespace + + +Pxr24Compressor::Pxr24Compressor (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines) +: + Compressor (hdr), + _maxScanLineSize (maxScanLineSize), + _numScanLines (numScanLines), + _tmpBuffer (0), + _outBuffer (0), + _channels (hdr.channels()) +{ + size_t maxInBytes = + uiMult (maxScanLineSize, numScanLines); + + size_t maxOutBytes = + uiAdd (uiAdd (maxInBytes, + size_t (ceil (maxInBytes * 0.01))), + size_t (100)); + + _tmpBuffer = new unsigned char [maxInBytes]; + _outBuffer = new char [maxOutBytes]; + + const Box2i &dataWindow = hdr.dataWindow(); + + _minX = dataWindow.min.x; + _maxX = dataWindow.max.x; + _maxY = dataWindow.max.y; +} + + +Pxr24Compressor::~Pxr24Compressor () +{ + delete [] _tmpBuffer; + delete [] _outBuffer; +} + + +int +Pxr24Compressor::numScanLines () const +{ + return _numScanLines; +} + + +Compressor::Format +Pxr24Compressor::format () const +{ + return NATIVE; +} + + +int +Pxr24Compressor::compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return compress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + _numScanLines - 1)), + outPtr); +} + + +int +Pxr24Compressor::compressTile (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + return compress (inPtr, inSize, range, outPtr); +} + + +int +Pxr24Compressor::uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr) +{ + return uncompress (inPtr, + inSize, + Box2i (V2i (_minX, minY), + V2i (_maxX, minY + _numScanLines - 1)), + outPtr); +} + + +int +Pxr24Compressor::uncompressTile (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + return uncompress (inPtr, inSize, range, outPtr); +} + + +int +Pxr24Compressor::compress (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + int minX = range.min.x; + int maxX = min (range.max.x, _maxX); + int minY = range.min.y; + int maxY = min (range.max.y, _maxY); + + unsigned char *tmpBufferEnd = _tmpBuffer; + + for (int y = minY; y <= maxY; ++y) + { + for (ChannelList::ConstIterator i = _channels.begin(); + i != _channels.end(); + ++i) + { + const Channel &c = i.channel(); + + if (modp (y, c.ySampling) != 0) + continue; + + int n = numSamples (c.xSampling, minX, maxX); + + unsigned char *ptr[4]; + unsigned int previousPixel = 0; + + switch (c.type) + { + case UINT: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + ptr[2] = ptr[1] + n; + ptr[3] = ptr[2] + n; + tmpBufferEnd = ptr[3] + n; + + for (int j = 0; j < n; ++j) + { + unsigned int pixel; + char *pPtr = (char *) &pixel; + + for (int k = 0; k < sizeof (pixel); ++k) + *pPtr++ = *inPtr++; + + unsigned int diff = pixel - previousPixel; + previousPixel = pixel; + + *(ptr[0]++) = diff >> 24; + *(ptr[1]++) = diff >> 16; + *(ptr[2]++) = diff >> 8; + *(ptr[3]++) = diff; + } + + break; + + case HALF: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + tmpBufferEnd = ptr[1] + n; + + for (int j = 0; j < n; ++j) + { + half pixel; + + pixel = *(const half *) inPtr; + inPtr += sizeof (half); + + unsigned int diff = pixel.bits() - previousPixel; + previousPixel = pixel.bits(); + + *(ptr[0]++) = diff >> 8; + *(ptr[1]++) = diff; + } + + break; + + case FLOAT: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + ptr[2] = ptr[1] + n; + tmpBufferEnd = ptr[2] + n; + + for (int j = 0; j < n; ++j) + { + float pixel; + char *pPtr = (char *) &pixel; + + for (int k = 0; k < sizeof (pixel); ++k) + *pPtr++ = *inPtr++; + + unsigned int pixel24 = floatToFloat24 (pixel); + unsigned int diff = pixel24 - previousPixel; + previousPixel = pixel24; + + *(ptr[0]++) = diff >> 16; + *(ptr[1]++) = diff >> 8; + *(ptr[2]++) = diff; + } + + break; + + default: + + assert (false); + } + } + } + + uLongf outSize = int (ceil ((tmpBufferEnd - _tmpBuffer) * 1.01)) + 100; + + if (Z_OK != ::compress ((Bytef *) _outBuffer, + &outSize, + (const Bytef *) _tmpBuffer, + tmpBufferEnd - _tmpBuffer)) + { + throw Iex::BaseExc ("Data compression (zlib) failed."); + } + + outPtr = _outBuffer; + return outSize; +} + + +int +Pxr24Compressor::uncompress (const char *inPtr, + int inSize, + Box2i range, + const char *&outPtr) +{ + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + uLongf tmpSize = _maxScanLineSize * _numScanLines; + + if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, + &tmpSize, + (const Bytef *) inPtr, + inSize)) + { + throw Iex::InputExc ("Data decompression (zlib) failed."); + } + + int minX = range.min.x; + int maxX = min (range.max.x, _maxX); + int minY = range.min.y; + int maxY = min (range.max.y, _maxY); + + const unsigned char *tmpBufferEnd = _tmpBuffer; + char *writePtr = _outBuffer; + + for (int y = minY; y <= maxY; ++y) + { + for (ChannelList::ConstIterator i = _channels.begin(); + i != _channels.end(); + ++i) + { + const Channel &c = i.channel(); + + if (modp (y, c.ySampling) != 0) + continue; + + int n = numSamples (c.xSampling, minX, maxX); + + const unsigned char *ptr[4]; + unsigned int pixel = 0; + + switch (c.type) + { + case UINT: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + ptr[2] = ptr[1] + n; + ptr[3] = ptr[2] + n; + tmpBufferEnd = ptr[3] + n; + + if (tmpBufferEnd - _tmpBuffer > tmpSize) + notEnoughData(); + + for (int j = 0; j < n; ++j) + { + unsigned int diff = (*(ptr[0]++) << 24) | + (*(ptr[1]++) << 16) | + (*(ptr[2]++) << 8) | + *(ptr[3]++); + + pixel += diff; + + char *pPtr = (char *) &pixel; + + for (int k = 0; k < sizeof (pixel); ++k) + *writePtr++ = *pPtr++; + } + + break; + + case HALF: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + tmpBufferEnd = ptr[1] + n; + + if (tmpBufferEnd - _tmpBuffer > tmpSize) + notEnoughData(); + + for (int j = 0; j < n; ++j) + { + unsigned int diff = (*(ptr[0]++) << 8) | + *(ptr[1]++); + + pixel += diff; + + half * hPtr = (half *) writePtr; + hPtr->setBits ((unsigned short) pixel); + writePtr += sizeof (half); + } + + break; + + case FLOAT: + + ptr[0] = tmpBufferEnd; + ptr[1] = ptr[0] + n; + ptr[2] = ptr[1] + n; + tmpBufferEnd = ptr[2] + n; + + if (tmpBufferEnd - _tmpBuffer > tmpSize) + notEnoughData(); + + for (int j = 0; j < n; ++j) + { + unsigned int diff = (*(ptr[0]++) << 24) | + (*(ptr[1]++) << 16) | + (*(ptr[2]++) << 8); + pixel += diff; + + char *pPtr = (char *) &pixel; + + for (int k = 0; k < sizeof (pixel); ++k) + *writePtr++ = *pPtr++; + } + + break; + + default: + + assert (false); + } + } + } + + if (tmpBufferEnd - _tmpBuffer < tmpSize) + tooMuchData(); + + outPtr = _outBuffer; + return writePtr - _outBuffer; +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfPxr24Compressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,108 @@ +#ifndef INCLUDED_IMF_PXR24_COMPRESSOR_H +#define INCLUDED_IMF_PXR24_COMPRESSOR_H + +///////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Pixar Animation Studios +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Pixar Animation Studios nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Pxr24Compressor -- Loren Carpenter's 24-bit float compressor +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + +class ChannelList; + + +class Pxr24Compressor: public Compressor +{ + public: + + Pxr24Compressor (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines); + + virtual ~Pxr24Compressor (); + + virtual int numScanLines () const; + + virtual Format format () const; + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int compressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int uncompressTile (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + private: + + int compress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int uncompress (const char *inPtr, + int inSize, + Imath::Box2i range, + const char *&outPtr); + + int _maxScanLineSize; + int _numScanLines; + unsigned char * _tmpBuffer; + char * _outBuffer; + const ChannelList & _channels; + int _minX; + int _maxX; + int _maxY; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Rational numbers +// +// The double-to-Rational conversion code below +// was contributed to OpenEXR by Greg Ward. +// +//----------------------------------------------------------------------------- + +#include +#include + +using namespace std; + +namespace Imf { +namespace { + +double +frac (double x, double e) +{ + return x - floor (x + e); +} + + +double +square (double x) +{ + return x * x; +} + + +double +denom (double x, double e) +{ + if (e > frac (x, e)) + { + return 1; + } + else + { + double r = frac (1 / x, e); + + if (e > r) + { + return floor (1 / x + e); + } + else + { + return denom (frac (1 / r, e), e / square (x * r)) + + floor (1 / x + e) * denom (frac (1 / x, e), e / square (x)); + } + } +} + +} // namespace + + +Rational::Rational (double x) +{ + int sign; + + if (x >= 0) + { + sign = 1; // positive + } + else if (x < 0) + { + sign = -1; // negative + x = -x; + } + else + { + n = 0; // NaN + d = 0; + return; + } + + if (x >= (1U << 31) - 0.5) + { + n = sign; // infinity + d = 0; + return; + } + + double e = (x < 1? 1: x) / (1U << 30); + d = (unsigned int) denom (x, e); + n = sign * (int) floor (x * d + 0.5); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRational.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_RATIONAL_H +#define INCLUDED_IMF_RATIONAL_H + +//----------------------------------------------------------------------------- +// +// Rational numbers +// +// A rational number is represented as pair of integers, n and d. +// The value of of the rational number is +// +// n/d for d > 0 +// positive infinity for n > 0, d == 0 +// negative infinity for n < 0, d == 0 +// not a number (NaN) for n == 0, d == 0 +// +//----------------------------------------------------------------------------- + +namespace Imf { + +class Rational +{ + public: + + int n; // numerator + unsigned int d; // denominator + + + //---------------------------------------- + // Default constructor, sets value to zero + //---------------------------------------- + + Rational (): n (0), d (1) {} + + + //------------------------------------- + // Constructor, explicitly sets n and d + //------------------------------------- + + Rational (int _n, int _d): n (_n), d (_d) {} + + + //---------------------------- + // Constructor, approximates x + //---------------------------- + + explicit Rational (double x); + + + //--------------------------------- + // Approximate conversion to double + //--------------------------------- + + operator double () const {return double (n) / double (d);} +}; + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class RationalAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +RationalAttribute::staticTypeName () +{ + return "rational"; +} + + +template <> +void +RationalAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.n); + Xdr::write (os, _value.d); +} + + +template <> +void +RationalAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.n); + Xdr::read (is, _value.d); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRationalAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMF_RATIONAL_ATTRIBUTE_H +#define INCLUDED_IMF_RATIONAL_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class RationalAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute RationalAttribute; + +template <> +const char *RationalAttribute::staticTypeName (); + +template <> +void RationalAttribute::writeValueTo (OStream &, int) const; + +template <> +void RationalAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgba.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgba.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgba.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgba.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_RGBA_H +#define INCLUDED_IMF_RGBA_H + +//----------------------------------------------------------------------------- +// +// class Rgba +// +//----------------------------------------------------------------------------- + +#include "half.h" + +namespace Imf { + + +// +// RGBA pixel +// + +struct Rgba +{ + half r; + half g; + half b; + half a; + + Rgba () {} + Rgba (half r, half g, half b, half a = 1.f): r (r), g (g), b (b), a (a) {} + + Rgba & operator = (const Rgba &other) + { + r = other.r; + g = other.g; + b = other.b; + a = other.a; + + return *this; + } +}; + + +// +// Channels in an RGBA file +// + +enum RgbaChannels +{ + WRITE_R = 0x01, // Red + WRITE_G = 0x02, // Green + WRITE_B = 0x04, // Blue + WRITE_A = 0x08, // Alpha + + WRITE_Y = 0x10, // Luminance, for black-and-white images, + // or in combination with chroma + + WRITE_C = 0x20, // Chroma (two subsampled channels, RY and BY, + // supported only for scanline-based files) + + WRITE_RGB = 0x07, // Red, green, blue + WRITE_RGBA = 0x0f, // Red, green, blue, alpha + + WRITE_YC = 0x30, // Luminance, chroma + WRITE_YA = 0x18, // Luminance, alpha + WRITE_YCA = 0x38 // Luminance, chroma, alpha +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1404 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class RgbaOutputFile +// class RgbaInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Imf { + +using namespace std; +using namespace Imath; +using namespace RgbaYca; +using namespace IlmThread; + +namespace { + +void +insertChannels (Header &header, RgbaChannels rgbaChannels) +{ + ChannelList ch; + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + { + if (rgbaChannels & WRITE_Y) + { + ch.insert ("Y", Channel (HALF, 1, 1)); + } + + if (rgbaChannels & WRITE_C) + { + ch.insert ("RY", Channel (HALF, 2, 2, true)); + ch.insert ("BY", Channel (HALF, 2, 2, true)); + } + } + else + { + if (rgbaChannels & WRITE_R) + ch.insert ("R", Channel (HALF, 1, 1)); + + if (rgbaChannels & WRITE_G) + ch.insert ("G", Channel (HALF, 1, 1)); + + if (rgbaChannels & WRITE_B) + ch.insert ("B", Channel (HALF, 1, 1)); + } + + if (rgbaChannels & WRITE_A) + ch.insert ("A", Channel (HALF, 1, 1)); + + header.channels() = ch; +} + + +RgbaChannels +rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "") +{ + int i = 0; + + if (ch.findChannel (channelNamePrefix + "R")) + i |= WRITE_R; + + if (ch.findChannel (channelNamePrefix + "G")) + i |= WRITE_G; + + if (ch.findChannel (channelNamePrefix + "B")) + i |= WRITE_B; + + if (ch.findChannel (channelNamePrefix + "A")) + i |= WRITE_A; + + if (ch.findChannel (channelNamePrefix + "Y")) + i |= WRITE_Y; + + if (ch.findChannel (channelNamePrefix + "RY") || + ch.findChannel (channelNamePrefix + "BY")) + i |= WRITE_C; + + return RgbaChannels (i); +} + + +string +prefixFromLayerName (const string &layerName, const Header &header) +{ + if (layerName.empty()) + return ""; + + if (hasMultiView (header) && multiView(header)[0] == layerName) + return ""; + + return layerName + "."; +} + + +V3f +ywFromHeader (const Header &header) +{ + Chromaticities cr; + + if (hasChromaticities (header)) + cr = chromaticities (header); + + return computeYw (cr); +} + + +ptrdiff_t +cachePadding (ptrdiff_t size) +{ + // + // Some of the buffers that are allocated by classes ToYca and + // FromYca, below, may need to be padded to avoid cache thrashing. + // If the difference between the buffer size and the nearest power + // of two is less than CACHE_LINE_SIZE, then we add an appropriate + // amount of padding. + // + // CACHE_LINE_SIZE must be a power of two, and it must be at + // least as big as the true size of a cache line on the machine + // we are running on. (It is ok if CACHE_LINE_SIZE is larger + // than a real cache line.) + // + + static int LOG2_CACHE_LINE_SIZE = 8; + static const ptrdiff_t CACHE_LINE_SIZE = (1 << LOG2_CACHE_LINE_SIZE); + + int i = LOG2_CACHE_LINE_SIZE + 2; + + while ((size >> i) > 1) + ++i; + + if (size > (1 << (i + 1)) - 64) + return 64 + ((1 << (i + 1)) - size); + + if (size < (1 << i) + 64) + return 64 + ((1 << i) - size); + + return 0; +} + +} // namespace + + +class RgbaOutputFile::ToYca: public Mutex +{ + public: + + ToYca (OutputFile &outputFile, RgbaChannels rgbaChannels); + ~ToYca (); + + void setYCRounding (unsigned int roundY, + unsigned int roundC); + + void setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride); + + void writePixels (int numScanLines); + int currentScanLine () const; + + private: + + void padTmpBuf (); + void rotateBuffers (); + void duplicateLastBuffer (); + void duplicateSecondToLastBuffer (); + void decimateChromaVertAndWriteScanLine (); + + OutputFile & _outputFile; + bool _writeY; + bool _writeC; + bool _writeA; + int _xMin; + int _width; + int _height; + int _linesConverted; + LineOrder _lineOrder; + int _currentScanLine; + V3f _yw; + Rgba * _bufBase; + Rgba * _buf[N]; + Rgba * _tmpBuf; + const Rgba * _fbBase; + size_t _fbXStride; + size_t _fbYStride; + int _roundY; + int _roundC; +}; + + +RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile, + RgbaChannels rgbaChannels) +: + _outputFile (outputFile) +{ + _writeY = (rgbaChannels & WRITE_Y)? true: false; + _writeC = (rgbaChannels & WRITE_C)? true: false; + _writeA = (rgbaChannels & WRITE_A)? true: false; + + const Box2i dw = _outputFile.header().dataWindow(); + + _xMin = dw.min.x; + _width = dw.max.x - dw.min.x + 1; + _height = dw.max.y - dw.min.y + 1; + + _linesConverted = 0; + _lineOrder = _outputFile.header().lineOrder(); + + if (_lineOrder == INCREASING_Y) + _currentScanLine = dw.min.y; + else + _currentScanLine = dw.max.y; + + _yw = ywFromHeader (_outputFile.header()); + + ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba); + + _bufBase = new Rgba[(_width + pad) * N]; + + for (int i = 0; i < N; ++i) + _buf[i] = _bufBase + (i * (_width + pad)); + + _tmpBuf = new Rgba[_width + N - 1]; + + _fbBase = 0; + _fbXStride = 0; + _fbYStride = 0; + + _roundY = 7; + _roundC = 5; +} + + +RgbaOutputFile::ToYca::~ToYca () +{ + delete [] _bufBase; + delete [] _tmpBuf; +} + + +void +RgbaOutputFile::ToYca::setYCRounding (unsigned int roundY, + unsigned int roundC) +{ + _roundY = roundY; + _roundC = roundC; +} + + +void +RgbaOutputFile::ToYca::setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride) +{ + if (_fbBase == 0) + { + FrameBuffer fb; + + if (_writeY) + { + fb.insert ("Y", + Slice (HALF, // type + (char *) &_tmpBuf[-_xMin].g, // base + sizeof (Rgba), // xStride + 0, // yStride + 1, // xSampling + 1)); // ySampling + } + + if (_writeC) + { + fb.insert ("RY", + Slice (HALF, // type + (char *) &_tmpBuf[-_xMin].r, // base + sizeof (Rgba) * 2, // xStride + 0, // yStride + 2, // xSampling + 2)); // ySampling + + fb.insert ("BY", + Slice (HALF, // type + (char *) &_tmpBuf[-_xMin].b, // base + sizeof (Rgba) * 2, // xStride + 0, // yStride + 2, // xSampling + 2)); // ySampling + } + + if (_writeA) + { + fb.insert ("A", + Slice (HALF, // type + (char *) &_tmpBuf[-_xMin].a, // base + sizeof (Rgba), // xStride + 0, // yStride + 1, // xSampling + 1)); // ySampling + } + + _outputFile.setFrameBuffer (fb); + } + + _fbBase = base; + _fbXStride = xStride; + _fbYStride = yStride; +} + + +void +RgbaOutputFile::ToYca::writePixels (int numScanLines) +{ + if (_fbBase == 0) + { + THROW (Iex::ArgExc, "No frame buffer was specified as the " + "pixel data source for image file " + "\"" << _outputFile.fileName() << "\"."); + } + + if (_writeY && !_writeC) + { + // + // We are writing only luminance; filtering + // and subsampling are not necessary. + // + + for (int i = 0; i < numScanLines; ++i) + { + // + // Copy the next scan line from the caller's + // frame buffer into _tmpBuf. + // + + for (int j = 0; j < _width; ++j) + { + _tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine + + _fbXStride * (j + _xMin)]; + } + + // + // Convert the scan line from RGB to luminance/chroma, + // and store the result in the output file. + // + + RGBAtoYCA (_yw, _width, _writeA, _tmpBuf, _tmpBuf); + _outputFile.writePixels (1); + + ++_linesConverted; + + if (_lineOrder == INCREASING_Y) + ++_currentScanLine; + else + --_currentScanLine; + } + } + else + { + // + // We are writing chroma; the pixels must be filtered and subsampled. + // + + for (int i = 0; i < numScanLines; ++i) + { + // + // Copy the next scan line from the caller's + // frame buffer into _tmpBuf. + // + + for (int j = 0; j < _width; ++j) + { + _tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine + + _fbXStride * (j + _xMin)]; + } + + // + // Convert the scan line from RGB to luminance/chroma. + // + + RGBAtoYCA (_yw, _width, _writeA, _tmpBuf + N2, _tmpBuf + N2); + + // + // Append N2 copies of the first and last pixel to the + // beginning and end of the scan line. + // + + padTmpBuf (); + + // + // Filter and subsample the scan line's chroma channels + // horizontally; store the result in _buf. + // + + rotateBuffers(); + decimateChromaHoriz (_width, _tmpBuf, _buf[N - 1]); + + // + // If this is the first scan line in the image, + // store N2 more copies of the scan line in _buf. + // + + if (_linesConverted == 0) + { + for (int j = 0; j < N2; ++j) + duplicateLastBuffer(); + } + + ++_linesConverted; + + // + // If we have have converted at least N2 scan lines from + // RGBA to luminance/chroma, then we can start to filter + // and subsample vertically, and store pixels in the + // output file. + // + + if (_linesConverted > N2) + decimateChromaVertAndWriteScanLine(); + + // + // If we have already converted the last scan line in + // the image to luminance/chroma, filter, subsample and + // store the remaining scan lines in _buf. + // + + if (_linesConverted >= _height) + { + for (int j = 0; j < N2 - _height; ++j) + duplicateLastBuffer(); + + duplicateSecondToLastBuffer(); + ++_linesConverted; + decimateChromaVertAndWriteScanLine(); + + for (int j = 1; j < min (_height, N2); ++j) + { + duplicateLastBuffer(); + ++_linesConverted; + decimateChromaVertAndWriteScanLine(); + } + } + + if (_lineOrder == INCREASING_Y) + ++_currentScanLine; + else + --_currentScanLine; + } + } +} + + +int +RgbaOutputFile::ToYca::currentScanLine () const +{ + return _currentScanLine; +} + + +void +RgbaOutputFile::ToYca::padTmpBuf () +{ + for (int i = 0; i < N2; ++i) + { + _tmpBuf[i] = _tmpBuf[N2]; + _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2]; + } +} + + +void +RgbaOutputFile::ToYca::rotateBuffers () +{ + Rgba *tmp = _buf[0]; + + for (int i = 0; i < N - 1; ++i) + _buf[i] = _buf[i + 1]; + + _buf[N - 1] = tmp; +} + + +void +RgbaOutputFile::ToYca::duplicateLastBuffer () +{ + rotateBuffers(); + memcpy (_buf[N - 1], _buf[N - 2], _width * sizeof (Rgba)); +} + + +void +RgbaOutputFile::ToYca::duplicateSecondToLastBuffer () +{ + rotateBuffers(); + memcpy (_buf[N - 1], _buf[N - 3], _width * sizeof (Rgba)); +} + + +void +RgbaOutputFile::ToYca::decimateChromaVertAndWriteScanLine () +{ + if (_linesConverted & 1) + memcpy (_tmpBuf, _buf[N2], _width * sizeof (Rgba)); + else + decimateChromaVert (_width, _buf, _tmpBuf); + + if (_writeY && _writeC) + roundYCA (_width, _roundY, _roundC, _tmpBuf, _tmpBuf); + + _outputFile.writePixels (1); +} + + +RgbaOutputFile::RgbaOutputFile (const char name[], + const Header &header, + RgbaChannels rgbaChannels, + int numThreads): + _outputFile (0), + _toYca (0) +{ + Header hd (header); + insertChannels (hd, rgbaChannels); + _outputFile = new OutputFile (name, hd, numThreads); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _toYca = new ToYca (*_outputFile, rgbaChannels); +} + + +RgbaOutputFile::RgbaOutputFile (OStream &os, + const Header &header, + RgbaChannels rgbaChannels, + int numThreads): + _outputFile (0), + _toYca (0) +{ + Header hd (header); + insertChannels (hd, rgbaChannels); + _outputFile = new OutputFile (os, hd, numThreads); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _toYca = new ToYca (*_outputFile, rgbaChannels); +} + + +RgbaOutputFile::RgbaOutputFile (const char name[], + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads): + _outputFile (0), + _toYca (0) +{ + Header hd (displayWindow, + dataWindow.isEmpty()? displayWindow: dataWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + insertChannels (hd, rgbaChannels); + _outputFile = new OutputFile (name, hd, numThreads); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _toYca = new ToYca (*_outputFile, rgbaChannels); +} + + +RgbaOutputFile::RgbaOutputFile (const char name[], + int width, + int height, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads): + _outputFile (0), + _toYca (0) +{ + Header hd (width, + height, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + insertChannels (hd, rgbaChannels); + _outputFile = new OutputFile (name, hd, numThreads); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _toYca = new ToYca (*_outputFile, rgbaChannels); +} + + +RgbaOutputFile::~RgbaOutputFile () +{ + delete _toYca; + delete _outputFile; +} + + +void +RgbaOutputFile::setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride) +{ + if (_toYca) + { + Lock lock (*_toYca); + _toYca->setFrameBuffer (base, xStride, yStride); + } + else + { + size_t xs = xStride * sizeof (Rgba); + size_t ys = yStride * sizeof (Rgba); + + FrameBuffer fb; + + fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys)); + fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys)); + fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys)); + fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys)); + + _outputFile->setFrameBuffer (fb); + } +} + + +void +RgbaOutputFile::writePixels (int numScanLines) +{ + if (_toYca) + { + Lock lock (*_toYca); + _toYca->writePixels (numScanLines); + } + else + { + _outputFile->writePixels (numScanLines); + } +} + + +int +RgbaOutputFile::currentScanLine () const +{ + if (_toYca) + { + Lock lock (*_toYca); + return _toYca->currentScanLine(); + } + else + { + return _outputFile->currentScanLine(); + } +} + + +const Header & +RgbaOutputFile::header () const +{ + return _outputFile->header(); +} + + +const FrameBuffer & +RgbaOutputFile::frameBuffer () const +{ + return _outputFile->frameBuffer(); +} + + +const Imath::Box2i & +RgbaOutputFile::displayWindow () const +{ + return _outputFile->header().displayWindow(); +} + + +const Imath::Box2i & +RgbaOutputFile::dataWindow () const +{ + return _outputFile->header().dataWindow(); +} + + +float +RgbaOutputFile::pixelAspectRatio () const +{ + return _outputFile->header().pixelAspectRatio(); +} + + +const Imath::V2f +RgbaOutputFile::screenWindowCenter () const +{ + return _outputFile->header().screenWindowCenter(); +} + + +float +RgbaOutputFile::screenWindowWidth () const +{ + return _outputFile->header().screenWindowWidth(); +} + + +LineOrder +RgbaOutputFile::lineOrder () const +{ + return _outputFile->header().lineOrder(); +} + + +Compression +RgbaOutputFile::compression () const +{ + return _outputFile->header().compression(); +} + + +RgbaChannels +RgbaOutputFile::channels () const +{ + return rgbaChannels (_outputFile->header().channels()); +} + + +void +RgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[]) +{ + _outputFile->updatePreviewImage (newPixels); +} + + +void +RgbaOutputFile::setYCRounding (unsigned int roundY, unsigned int roundC) +{ + if (_toYca) + { + Lock lock (*_toYca); + _toYca->setYCRounding (roundY, roundC); + } +} + + +void +RgbaOutputFile::breakScanLine (int y, int offset, int length, char c) +{ + _outputFile->breakScanLine (y, offset, length, c); +} + + +class RgbaInputFile::FromYca: public Mutex +{ + public: + + FromYca (InputFile &inputFile, RgbaChannels rgbaChannels); + ~FromYca (); + + void setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride, + const string &channelNamePrefix); + + void readPixels (int scanLine1, int scanLine2); + + private: + + void readPixels (int scanLine); + void rotateBuf1 (int d); + void rotateBuf2 (int d); + void readYCAScanLine (int y, Rgba buf[]); + void padTmpBuf (); + + InputFile & _inputFile; + bool _readC; + int _xMin; + int _yMin; + int _yMax; + int _width; + int _height; + int _currentScanLine; + LineOrder _lineOrder; + V3f _yw; + Rgba * _bufBase; + Rgba * _buf1[N + 2]; + Rgba * _buf2[3]; + Rgba * _tmpBuf; + Rgba * _fbBase; + size_t _fbXStride; + size_t _fbYStride; +}; + + +RgbaInputFile::FromYca::FromYca (InputFile &inputFile, + RgbaChannels rgbaChannels) +: + _inputFile (inputFile) +{ + _readC = (rgbaChannels & WRITE_C)? true: false; + + const Box2i dw = _inputFile.header().dataWindow(); + + _xMin = dw.min.x; + _yMin = dw.min.y; + _yMax = dw.max.y; + _width = dw.max.x - dw.min.x + 1; + _height = dw.max.y - dw.min.y + 1; + _currentScanLine = dw.min.y - N - 2; + _lineOrder = _inputFile.header().lineOrder(); + _yw = ywFromHeader (_inputFile.header()); + + ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba); + + _bufBase = new Rgba[(_width + pad) * (N + 2 + 3)]; + + for (int i = 0; i < N + 2; ++i) + _buf1[i] = _bufBase + (i * (_width + pad)); + + for (int i = 0; i < 3; ++i) + _buf2[i] = _bufBase + ((i + N + 2) * (_width + pad)); + + _tmpBuf = new Rgba[_width + N - 1]; + + _fbBase = 0; + _fbXStride = 0; + _fbYStride = 0; +} + + +RgbaInputFile::FromYca::~FromYca () +{ + delete [] _bufBase; + delete [] _tmpBuf; +} + + +void +RgbaInputFile::FromYca::setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride, + const string &channelNamePrefix) +{ + if (_fbBase == 0) + { + FrameBuffer fb; + + fb.insert (channelNamePrefix + "Y", + Slice (HALF, // type + (char *) &_tmpBuf[N2 - _xMin].g, // base + sizeof (Rgba), // xStride + 0, // yStride + 1, // xSampling + 1, // ySampling + 0.5)); // fillValue + + if (_readC) + { + fb.insert (channelNamePrefix + "RY", + Slice (HALF, // type + (char *) &_tmpBuf[N2 - _xMin].r, // base + sizeof (Rgba) * 2, // xStride + 0, // yStride + 2, // xSampling + 2, // ySampling + 0.0)); // fillValue + + fb.insert (channelNamePrefix + "BY", + Slice (HALF, // type + (char *) &_tmpBuf[N2 - _xMin].b, // base + sizeof (Rgba) * 2, // xStride + 0, // yStride + 2, // xSampling + 2, // ySampling + 0.0)); // fillValue + } + + fb.insert (channelNamePrefix + "A", + Slice (HALF, // type + (char *) &_tmpBuf[N2 - _xMin].a, // base + sizeof (Rgba), // xStride + 0, // yStride + 1, // xSampling + 1, // ySampling + 1.0)); // fillValue + + _inputFile.setFrameBuffer (fb); + } + + _fbBase = base; + _fbXStride = xStride; + _fbYStride = yStride; +} + + +void +RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2) +{ + int minY = min (scanLine1, scanLine2); + int maxY = max (scanLine1, scanLine2); + + if (_lineOrder == INCREASING_Y) + { + for (int y = minY; y <= maxY; ++y) + readPixels (y); + } + else + { + for (int y = maxY; y >= minY; --y) + readPixels (y); + } +} + + +void +RgbaInputFile::FromYca::readPixels (int scanLine) +{ + if (_fbBase == 0) + { + THROW (Iex::ArgExc, "No frame buffer was specified as the " + "pixel data destination for image file " + "\"" << _inputFile.fileName() << "\"."); + } + + // + // In order to convert one scan line to RGB format, we need that + // scan line plus N2+1 extra scan lines above and N2+1 scan lines + // below in luminance/chroma format. + // + // We allow random access to scan lines, but we buffer partially + // processed luminance/chroma data in order to make reading pixels + // in increasing y or decreasing y order reasonably efficient: + // + // _currentScanLine holds the y coordinate of the scan line + // that was most recently read. + // + // _buf1 contains scan lines _currentScanLine-N2-1 + // through _currentScanLine+N2+1 in + // luminance/chroma format. Odd-numbered + // lines contain no chroma data. Even-numbered + // lines have valid chroma data for all pixels. + // + // _buf2 contains scan lines _currentScanLine-1 + // through _currentScanLine+1, in RGB format. + // Super-saturated pixels (see ImfRgbaYca.h) + // have not yet been eliminated. + // + // If the scan line we are trying to read now is close enough to + // _currentScanLine, we don't have to recompute the contents of _buf1 + // and _buf2 from scratch. We can rotate _buf1 and _buf2, and fill + // in the missing data. + // + + int dy = scanLine - _currentScanLine; + + if (abs (dy) < N + 2) + rotateBuf1 (dy); + + if (abs (dy) < 3) + rotateBuf2 (dy); + + if (dy < 0) + { + { + int n = min (-dy, N + 2); + int yMin = scanLine - N2 - 1; + + for (int i = n - 1; i >= 0; --i) + readYCAScanLine (yMin + i, _buf1[i]); + } + + { + int n = min (-dy, 3); + + for (int i = 0; i < n; ++i) + { + if ((scanLine + i) & 1) + { + YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]); + } + else + { + reconstructChromaVert (_width, _buf1 + i, _buf2[i]); + YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]); + } + } + } + } + else + { + { + int n = min (dy, N + 2); + int yMax = scanLine + N2 + 1; + + for (int i = n - 1; i >= 0; --i) + readYCAScanLine (yMax - i, _buf1[N + 1 - i]); + } + + { + int n = min (dy, 3); + + for (int i = 2; i > 2 - n; --i) + { + if ((scanLine + i) & 1) + { + YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]); + } + else + { + reconstructChromaVert (_width, _buf1 + i, _buf2[i]); + YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]); + } + } + } + } + + fixSaturation (_yw, _width, _buf2, _tmpBuf); + + for (int i = 0; i < _width; ++i) + _fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i]; + + _currentScanLine = scanLine; +} + + +void +RgbaInputFile::FromYca::rotateBuf1 (int d) +{ + d = modp (d, N + 2); + + Rgba *tmp[N + 2]; + + for (int i = 0; i < N + 2; ++i) + tmp[i] = _buf1[i]; + + for (int i = 0; i < N + 2; ++i) + _buf1[i] = tmp[(i + d) % (N + 2)]; +} + + +void +RgbaInputFile::FromYca::rotateBuf2 (int d) +{ + d = modp (d, 3); + + Rgba *tmp[3]; + + for (int i = 0; i < 3; ++i) + tmp[i] = _buf2[i]; + + for (int i = 0; i < 3; ++i) + _buf2[i] = tmp[(i + d) % 3]; +} + + +void +RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf) +{ + // + // Clamp y. + // + + if (y < _yMin) + y = _yMin; + else if (y > _yMax) + y = _yMax - 1; + + // + // Read scan line y into _tmpBuf. + // + + _inputFile.readPixels (y); + + // + // Reconstruct missing chroma samples and copy + // the scan line into buf. + // + + if (!_readC) + { + for (int i = 0; i < _width; ++i) + { + _tmpBuf[i + N2].r = 0; + _tmpBuf[i + N2].b = 0; + } + } + + if (y & 1) + { + memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba)); + } + else + { + padTmpBuf(); + reconstructChromaHoriz (_width, _tmpBuf, buf); + } +} + + +void +RgbaInputFile::FromYca::padTmpBuf () +{ + for (int i = 0; i < N2; ++i) + { + _tmpBuf[i] = _tmpBuf[N2]; + _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2]; + } +} + + +RgbaInputFile::RgbaInputFile (const char name[], int numThreads): + _inputFile (new InputFile (name, numThreads)), + _fromYca (0), + _channelNamePrefix ("") +{ + RgbaChannels rgbaChannels = channels(); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _fromYca = new FromYca (*_inputFile, rgbaChannels); +} + + +RgbaInputFile::RgbaInputFile (IStream &is, int numThreads): + _inputFile (new InputFile (is, numThreads)), + _fromYca (0), + _channelNamePrefix ("") +{ + RgbaChannels rgbaChannels = channels(); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _fromYca = new FromYca (*_inputFile, rgbaChannels); +} + + +RgbaInputFile::RgbaInputFile (const char name[], + const string &layerName, + int numThreads) +: + _inputFile (new InputFile (name, numThreads)), + _fromYca (0), + _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header())) +{ + RgbaChannels rgbaChannels = channels(); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _fromYca = new FromYca (*_inputFile, rgbaChannels); +} + + +RgbaInputFile::RgbaInputFile (IStream &is, + const string &layerName, + int numThreads) +: + _inputFile (new InputFile (is, numThreads)), + _fromYca (0), + _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header())) +{ + RgbaChannels rgbaChannels = channels(); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _fromYca = new FromYca (*_inputFile, rgbaChannels); +} + + +RgbaInputFile::~RgbaInputFile () +{ + delete _inputFile; + delete _fromYca; +} + + +void +RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride) +{ + if (_fromYca) + { + Lock lock (*_fromYca); + _fromYca->setFrameBuffer (base, xStride, yStride, _channelNamePrefix); + } + else + { + size_t xs = xStride * sizeof (Rgba); + size_t ys = yStride * sizeof (Rgba); + + FrameBuffer fb; + + fb.insert (_channelNamePrefix + "R", + Slice (HALF, + (char *) &base[0].r, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "G", + Slice (HALF, + (char *) &base[0].g, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "B", + Slice (HALF, + (char *) &base[0].b, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "A", + Slice (HALF, + (char *) &base[0].a, + xs, ys, + 1, 1, // xSampling, ySampling + 1.0)); // fillValue + + _inputFile->setFrameBuffer (fb); + } +} + + +void +RgbaInputFile::setLayerName (const string &layerName) +{ + delete _fromYca; + _fromYca = 0; + + _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header()); + + RgbaChannels rgbaChannels = channels(); + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + _fromYca = new FromYca (*_inputFile, rgbaChannels); + + FrameBuffer fb; + _inputFile->setFrameBuffer (fb); +} + + +void +RgbaInputFile::readPixels (int scanLine1, int scanLine2) +{ + if (_fromYca) + { + Lock lock (*_fromYca); + _fromYca->readPixels (scanLine1, scanLine2); + } + else + { + _inputFile->readPixels (scanLine1, scanLine2); + } +} + + +void +RgbaInputFile::readPixels (int scanLine) +{ + readPixels (scanLine, scanLine); +} + + +bool +RgbaInputFile::isComplete () const +{ + return _inputFile->isComplete(); +} + + +const Header & +RgbaInputFile::header () const +{ + return _inputFile->header(); +} + + +const char * +RgbaInputFile::fileName () const +{ + return _inputFile->fileName(); +} + + +const FrameBuffer & +RgbaInputFile::frameBuffer () const +{ + return _inputFile->frameBuffer(); +} + + +const Imath::Box2i & +RgbaInputFile::displayWindow () const +{ + return _inputFile->header().displayWindow(); +} + + +const Imath::Box2i & +RgbaInputFile::dataWindow () const +{ + return _inputFile->header().dataWindow(); +} + + +float +RgbaInputFile::pixelAspectRatio () const +{ + return _inputFile->header().pixelAspectRatio(); +} + + +const Imath::V2f +RgbaInputFile::screenWindowCenter () const +{ + return _inputFile->header().screenWindowCenter(); +} + + +float +RgbaInputFile::screenWindowWidth () const +{ + return _inputFile->header().screenWindowWidth(); +} + + +LineOrder +RgbaInputFile::lineOrder () const +{ + return _inputFile->header().lineOrder(); +} + + +Compression +RgbaInputFile::compression () const +{ + return _inputFile->header().compression(); +} + + +RgbaChannels +RgbaInputFile::channels () const +{ + return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix); +} + + +int +RgbaInputFile::version () const +{ + return _inputFile->version(); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,344 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_RGBA_FILE_H +#define INCLUDED_IMF_RGBA_FILE_H + + +//----------------------------------------------------------------------------- +// +// Simplified RGBA image I/O +// +// class RgbaOutputFile +// class RgbaInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "ImathVec.h" +#include "ImathBox.h" +#include "half.h" +#include +#include + +namespace Imf { + + +class OutputFile; +class InputFile; +struct PreviewRgba; + +// +// RGBA output file. +// + +class RgbaOutputFile +{ + public: + + //--------------------------------------------------- + // Constructor -- header is constructed by the caller + //--------------------------------------------------- + + RgbaOutputFile (const char name[], + const Header &header, + RgbaChannels rgbaChannels = WRITE_RGBA, + int numThreads = globalThreadCount()); + + + //---------------------------------------------------- + // Constructor -- header is constructed by the caller, + // file is opened by the caller, destructor will not + // automatically close the file. + //---------------------------------------------------- + + RgbaOutputFile (OStream &os, + const Header &header, + RgbaChannels rgbaChannels = WRITE_RGBA, + int numThreads = globalThreadCount()); + + + //---------------------------------------------------------------- + // Constructor -- header data are explicitly specified as function + // call arguments (empty dataWindow means "same as displayWindow") + //---------------------------------------------------------------- + + RgbaOutputFile (const char name[], + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow = Imath::Box2i(), + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = PIZ_COMPRESSION, + int numThreads = globalThreadCount()); + + + //----------------------------------------------- + // Constructor -- like the previous one, but both + // the display window and the data window are + // Box2i (V2i (0, 0), V2i (width - 1, height -1)) + //----------------------------------------------- + + RgbaOutputFile (const char name[], + int width, + int height, + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = PIZ_COMPRESSION, + int numThreads = globalThreadCount()); + + + //----------- + // Destructor + //----------- + + virtual ~RgbaOutputFile (); + + + //------------------------------------------------ + // Define a frame buffer as the pixel data source: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //------------------------------------------------ + + void setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride); + + + //--------------------------------------------- + // Write pixel data (see class Imf::OutputFile) + //--------------------------------------------- + + void writePixels (int numScanLines = 1); + int currentScanLine () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const FrameBuffer & frameBuffer () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + + + // -------------------------------------------------------------------- + // Update the preview image (see Imf::OutputFile::updatePreviewImage()) + // -------------------------------------------------------------------- + + void updatePreviewImage (const PreviewRgba[]); + + + //----------------------------------------------------------------------- + // Rounding control for luminance/chroma images: + // + // If the output file contains luminance and chroma channels (WRITE_YC + // or WRITE_YCA), then the the significands of the luminance and + // chroma values are rounded to roundY and roundC bits respectively (see + // function half::round()). Rounding improves compression with minimal + // image degradation, usually much less than the degradation caused by + // chroma subsampling. By default, roundY is 7, and roundC is 5. + // + // If the output file contains RGB channels or a luminance channel, + // without chroma, then no rounding is performed. + //----------------------------------------------------------------------- + + void setYCRounding (unsigned int roundY, + unsigned int roundC); + + + //---------------------------------------------------- + // Break a scan line -- for testing and debugging only + // (see Imf::OutputFile::updatePreviewImage() + // + // Warning: Calling this function usually results in a + // broken image file. The file or parts of it may not + // be readable, or the file may contain bad data. + // + //---------------------------------------------------- + + void breakScanLine (int y, + int offset, + int length, + char c); + private: + + RgbaOutputFile (const RgbaOutputFile &); // not implemented + RgbaOutputFile & operator = (const RgbaOutputFile &); // not implemented + + class ToYca; + + OutputFile * _outputFile; + ToYca * _toYca; +}; + + +// +// RGBA input file +// + +class RgbaInputFile +{ + public: + + //------------------------------------------------------- + // Constructor -- opens the file with the specified name, + // destructor will automatically close the file. + //------------------------------------------------------- + + RgbaInputFile (const char name[], int numThreads = globalThreadCount()); + + + //----------------------------------------------------------- + // Constructor -- attaches the new RgbaInputFile object to a + // file that has already been opened by the caller. + // Destroying the RgbaInputFile object will not automatically + // close the file. + //----------------------------------------------------------- + + RgbaInputFile (IStream &is, int numThreads = globalThreadCount()); + + + //-------------------------------------------------------------- + // Constructors -- the same as the previous two, but the names + // of the red, green, blue, alpha, luminance and chroma channels + // are expected to be layerName.R, layerName.G, etc. + //-------------------------------------------------------------- + + RgbaInputFile (const char name[], + const std::string &layerName, + int numThreads = globalThreadCount()); + + RgbaInputFile (IStream &is, + const std::string &layerName, + int numThreads = globalThreadCount()); + + + //----------- + // Destructor + //----------- + + virtual ~RgbaInputFile (); + + + //----------------------------------------------------- + // Define a frame buffer as the pixel data destination: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //----------------------------------------------------- + + void setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride); + + + //---------------------------------------------------------------- + // Switch to a different layer -- subsequent calls to readPixels() + // will read channels layerName.R, layerName.G, etc. + // After each call to setLayerName(), setFrameBuffer() must be + // called at least once before the next call to readPixels(). + //---------------------------------------------------------------- + + void setLayerName (const std::string &layerName); + + + //------------------------------------------- + // Read pixel data (see class Imf::InputFile) + //------------------------------------------- + + void readPixels (int scanLine1, int scanLine2); + void readPixels (int scanLine); + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const FrameBuffer & frameBuffer () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + const char * fileName () const; + bool isComplete () const; + + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + private: + + RgbaInputFile (const RgbaInputFile &); // not implemented + RgbaInputFile & operator = (const RgbaInputFile &); // not implemented + + class FromYca; + + InputFile * _inputFile; + FromYca * _fromYca; + std::string _channelNamePrefix; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,495 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm +// Entertainment Company Ltd. Portions contributed and copyright held by +// others as indicated. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided with +// the distribution. +// +// * Neither the name of Industrial Light & Magic nor the names of +// any other contributors to this software may be used to endorse or +// promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Conversion between RGBA and YCA data. +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +using namespace Imath; +using namespace std; + +namespace Imf { +namespace RgbaYca { + + +V3f +computeYw (const Chromaticities &cr) +{ + M44f m = RGBtoXYZ (cr, 1); + return V3f (m[0][1], m[1][1], m[2][1]) / (m[0][1] + m[1][1] + m[2][1]); +} + + +void +RGBAtoYCA (const V3f &yw, + int n, + bool aIsValid, + const Rgba rgbaIn[/*n*/], + Rgba ycaOut[/*n*/]) +{ + for (int i = 0; i < n; ++i) + { + Rgba in = rgbaIn[i]; + Rgba &out = ycaOut[i]; + + // + // Conversion to YCA and subsequent chroma subsampling + // work only if R, G and B are finite and non-negative. + // + + if (!in.r.isFinite() || in.r < 0) + in.r = 0; + + if (!in.g.isFinite() || in.g < 0) + in.g = 0; + + if (!in.b.isFinite() || in.b < 0) + in.b = 0; + + if (in.r == in.g && in.g == in.b) + { + // + // Special case -- R, G and B are equal. To avoid rounding + // errors, we explicitly set the output luminance channel + // to G, and the chroma channels to 0. + // + // The special cases here and in YCAtoRGBA() ensure that + // converting black-and white images from RGBA to YCA and + // back is lossless. + // + + out.r = 0; + out.g = in.g; + out.b = 0; + } + else + { + out.g = in.r * yw.x + in.g * yw.y + in.b * yw.z; + + float Y = out.g; + + if (abs (in.r - Y) < HALF_MAX * Y) + out.r = (in.r - Y) / Y; + else + out.r = 0; + + if (abs (in.b - Y) < HALF_MAX * Y) + out.b = (in.b - Y) / Y; + else + out.b = 0; + } + + if (aIsValid) + out.a = in.a; + else + out.a = 1; + } +} + + +void +decimateChromaHoriz (int n, + const Rgba ycaIn[/*n+N-1*/], + Rgba ycaOut[/*n*/]) +{ + #ifdef DEBUG + assert (ycaIn != ycaOut); + #endif + + int begin = N2; + int end = begin + n; + + for (int i = begin, j = 0; i < end; ++i, ++j) + { + if ((j & 1) == 0) + { + ycaOut[j].r = ycaIn[i - 13].r * 0.001064f + + ycaIn[i - 11].r * -0.003771f + + ycaIn[i - 9].r * 0.009801f + + ycaIn[i - 7].r * -0.021586f + + ycaIn[i - 5].r * 0.043978f + + ycaIn[i - 3].r * -0.093067f + + ycaIn[i - 1].r * 0.313659f + + ycaIn[i ].r * 0.499846f + + ycaIn[i + 1].r * 0.313659f + + ycaIn[i + 3].r * -0.093067f + + ycaIn[i + 5].r * 0.043978f + + ycaIn[i + 7].r * -0.021586f + + ycaIn[i + 9].r * 0.009801f + + ycaIn[i + 11].r * -0.003771f + + ycaIn[i + 13].r * 0.001064f; + + ycaOut[j].b = ycaIn[i - 13].b * 0.001064f + + ycaIn[i - 11].b * -0.003771f + + ycaIn[i - 9].b * 0.009801f + + ycaIn[i - 7].b * -0.021586f + + ycaIn[i - 5].b * 0.043978f + + ycaIn[i - 3].b * -0.093067f + + ycaIn[i - 1].b * 0.313659f + + ycaIn[i ].b * 0.499846f + + ycaIn[i + 1].b * 0.313659f + + ycaIn[i + 3].b * -0.093067f + + ycaIn[i + 5].b * 0.043978f + + ycaIn[i + 7].b * -0.021586f + + ycaIn[i + 9].b * 0.009801f + + ycaIn[i + 11].b * -0.003771f + + ycaIn[i + 13].b * 0.001064f; + } + + ycaOut[j].g = ycaIn[i].g; + ycaOut[j].a = ycaIn[i].a; + } +} + + +void +decimateChromaVert (int n, + const Rgba * const ycaIn[N], + Rgba ycaOut[/*n*/]) +{ + for (int i = 0; i < n; ++i) + { + if ((i & 1) == 0) + { + ycaOut[i].r = ycaIn[ 0][i].r * 0.001064f + + ycaIn[ 2][i].r * -0.003771f + + ycaIn[ 4][i].r * 0.009801f + + ycaIn[ 6][i].r * -0.021586f + + ycaIn[ 8][i].r * 0.043978f + + ycaIn[10][i].r * -0.093067f + + ycaIn[12][i].r * 0.313659f + + ycaIn[13][i].r * 0.499846f + + ycaIn[14][i].r * 0.313659f + + ycaIn[16][i].r * -0.093067f + + ycaIn[18][i].r * 0.043978f + + ycaIn[20][i].r * -0.021586f + + ycaIn[22][i].r * 0.009801f + + ycaIn[24][i].r * -0.003771f + + ycaIn[26][i].r * 0.001064f; + + ycaOut[i].b = ycaIn[ 0][i].b * 0.001064f + + ycaIn[ 2][i].b * -0.003771f + + ycaIn[ 4][i].b * 0.009801f + + ycaIn[ 6][i].b * -0.021586f + + ycaIn[ 8][i].b * 0.043978f + + ycaIn[10][i].b * -0.093067f + + ycaIn[12][i].b * 0.313659f + + ycaIn[13][i].b * 0.499846f + + ycaIn[14][i].b * 0.313659f + + ycaIn[16][i].b * -0.093067f + + ycaIn[18][i].b * 0.043978f + + ycaIn[20][i].b * -0.021586f + + ycaIn[22][i].b * 0.009801f + + ycaIn[24][i].b * -0.003771f + + ycaIn[26][i].b * 0.001064f; + } + + ycaOut[i].g = ycaIn[13][i].g; + ycaOut[i].a = ycaIn[13][i].a; + } +} + + +void +roundYCA (int n, + unsigned int roundY, + unsigned int roundC, + const Rgba ycaIn[/*n*/], + Rgba ycaOut[/*n*/]) +{ + for (int i = 0; i < n; ++i) + { + ycaOut[i].g = ycaIn[i].g.round (roundY); + ycaOut[i].a = ycaIn[i].a; + + if ((i & 1) == 0) + { + ycaOut[i].r = ycaIn[i].r.round (roundC); + ycaOut[i].b = ycaIn[i].b.round (roundC); + } + } +} + + +void +reconstructChromaHoriz (int n, + const Rgba ycaIn[/*n+N-1*/], + Rgba ycaOut[/*n*/]) +{ + #ifdef DEBUG + assert (ycaIn != ycaOut); + #endif + + int begin = N2; + int end = begin + n; + + for (int i = begin, j = 0; i < end; ++i, ++j) + { + if (j & 1) + { + ycaOut[j].r = ycaIn[i - 13].r * 0.002128f + + ycaIn[i - 11].r * -0.007540f + + ycaIn[i - 9].r * 0.019597f + + ycaIn[i - 7].r * -0.043159f + + ycaIn[i - 5].r * 0.087929f + + ycaIn[i - 3].r * -0.186077f + + ycaIn[i - 1].r * 0.627123f + + ycaIn[i + 1].r * 0.627123f + + ycaIn[i + 3].r * -0.186077f + + ycaIn[i + 5].r * 0.087929f + + ycaIn[i + 7].r * -0.043159f + + ycaIn[i + 9].r * 0.019597f + + ycaIn[i + 11].r * -0.007540f + + ycaIn[i + 13].r * 0.002128f; + + ycaOut[j].b = ycaIn[i - 13].b * 0.002128f + + ycaIn[i - 11].b * -0.007540f + + ycaIn[i - 9].b * 0.019597f + + ycaIn[i - 7].b * -0.043159f + + ycaIn[i - 5].b * 0.087929f + + ycaIn[i - 3].b * -0.186077f + + ycaIn[i - 1].b * 0.627123f + + ycaIn[i + 1].b * 0.627123f + + ycaIn[i + 3].b * -0.186077f + + ycaIn[i + 5].b * 0.087929f + + ycaIn[i + 7].b * -0.043159f + + ycaIn[i + 9].b * 0.019597f + + ycaIn[i + 11].b * -0.007540f + + ycaIn[i + 13].b * 0.002128f; + } + else + { + ycaOut[j].r = ycaIn[i].r; + ycaOut[j].b = ycaIn[i].b; + } + + ycaOut[j].g = ycaIn[i].g; + ycaOut[j].a = ycaIn[i].a; + } +} + + +void +reconstructChromaVert (int n, + const Rgba * const ycaIn[N], + Rgba ycaOut[/*n*/]) +{ + for (int i = 0; i < n; ++i) + { + ycaOut[i].r = ycaIn[ 0][i].r * 0.002128f + + ycaIn[ 2][i].r * -0.007540f + + ycaIn[ 4][i].r * 0.019597f + + ycaIn[ 6][i].r * -0.043159f + + ycaIn[ 8][i].r * 0.087929f + + ycaIn[10][i].r * -0.186077f + + ycaIn[12][i].r * 0.627123f + + ycaIn[14][i].r * 0.627123f + + ycaIn[16][i].r * -0.186077f + + ycaIn[18][i].r * 0.087929f + + ycaIn[20][i].r * -0.043159f + + ycaIn[22][i].r * 0.019597f + + ycaIn[24][i].r * -0.007540f + + ycaIn[26][i].r * 0.002128f; + + ycaOut[i].b = ycaIn[ 0][i].b * 0.002128f + + ycaIn[ 2][i].b * -0.007540f + + ycaIn[ 4][i].b * 0.019597f + + ycaIn[ 6][i].b * -0.043159f + + ycaIn[ 8][i].b * 0.087929f + + ycaIn[10][i].b * -0.186077f + + ycaIn[12][i].b * 0.627123f + + ycaIn[14][i].b * 0.627123f + + ycaIn[16][i].b * -0.186077f + + ycaIn[18][i].b * 0.087929f + + ycaIn[20][i].b * -0.043159f + + ycaIn[22][i].b * 0.019597f + + ycaIn[24][i].b * -0.007540f + + ycaIn[26][i].b * 0.002128f; + + ycaOut[i].g = ycaIn[13][i].g; + ycaOut[i].a = ycaIn[13][i].a; + } +} + + +void +YCAtoRGBA (const Imath::V3f &yw, + int n, + const Rgba ycaIn[/*n*/], + Rgba rgbaOut[/*n*/]) +{ + for (int i = 0; i < n; ++i) + { + const Rgba &in = ycaIn[i]; + Rgba &out = rgbaOut[i]; + + if (in.r == 0 && in.b == 0) + { + // + // Special case -- both chroma channels are 0. To avoid + // rounding errors, we explicitly set the output R, G and B + // channels equal to the input luminance. + // + // The special cases here and in RGBAtoYCA() ensure that + // converting black-and white images from RGBA to YCA and + // back is lossless. + // + + out.r = in.g; + out.g = in.g; + out.b = in.g; + out.a = in.a; + } + else + { + float Y = in.g; + float r = (in.r + 1) * Y; + float b = (in.b + 1) * Y; + float g = (Y - r * yw.x - b * yw.z) / yw.y; + + out.r = r; + out.g = g; + out.b = b; + out.a = in.a; + } + } +} + + +namespace { + +inline float +saturation (const Rgba &in) +{ + float rgbMax = max (in.r, max (in.g, in.b)); + float rgbMin = min (in.r, min (in.g, in.b)); + + if (rgbMax > 0) + return 1 - rgbMin / rgbMax; + else + return 0; +} + + +void +desaturate (const Rgba &in, float f, const V3f &yw, Rgba &out) +{ + float rgbMax = max (in.r, max (in.g, in.b)); + + out.r = max (float (rgbMax - (rgbMax - in.r) * f), 0.0f); + out.g = max (float (rgbMax - (rgbMax - in.g) * f), 0.0f); + out.b = max (float (rgbMax - (rgbMax - in.b) * f), 0.0f); + out.a = in.a; + + float Yin = in.r * yw.x + in.g * yw.y + in.b * yw.z; + float Yout = out.r * yw.x + out.g * yw.y + out.b * yw.z; + + if (Yout > 0) + { + out.r *= Yin / Yout; + out.g *= Yin / Yout; + out.b *= Yin / Yout; + } +} + +} // namespace + + +void +fixSaturation (const Imath::V3f &yw, + int n, + const Rgba * const rgbaIn[3], + Rgba rgbaOut[/*n*/]) +{ + float neighborA2 = saturation (rgbaIn[0][0]); + float neighborA1 = neighborA2; + + float neighborB2 = saturation (rgbaIn[2][0]); + float neighborB1 = neighborB2; + + for (int i = 0; i < n; ++i) + { + float neighborA0 = neighborA1; + neighborA1 = neighborA2; + + float neighborB0 = neighborB1; + neighborB1 = neighborB2; + + if (i < n - 1) + { + neighborA2 = saturation (rgbaIn[0][i + 1]); + neighborB2 = saturation (rgbaIn[2][i + 1]); + } + + // + // A0 A1 A2 + // rgbaOut[i] + // B0 B1 B2 + // + + float sMean = min (1.0f, 0.25f * (neighborA0 + neighborA2 + + neighborB0 + neighborB2)); + + const Rgba &in = rgbaIn[1][i]; + Rgba &out = rgbaOut[i]; + + float s = saturation (in); + + if (s > sMean) + { + float sMax = min (1.0f, 1 - (1 - sMean) * 0.25f); + + if (s > sMax) + { + desaturate (in, sMax / s, yw, out); + continue; + } + } + + out = in; + } +} + +} // namespace RgbaYca +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRgbaYca.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,248 @@ +#ifndef INCLUDED_IMF_RGBA_YCA_H +#define INCLUDED_IMF_RGBA_YCA_H + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm +// Entertainment Company Ltd. Portions contributed and copyright held by +// others as indicated. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided with +// the distribution. +// +// * Neither the name of Industrial Light & Magic nor the names of +// any other contributors to this software may be used to endorse or +// promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Conversion between RGBA (red, green, blue alpha) +// and YCA (luminance, subsampled chroma, alpha) data: +// +// Luminance, Y, is computed as a weighted sum of R, G, and B: +// +// Y = yw.x * R + yw.y * G + yw.z * B +// +// Function computeYw() computes a set of RGB-to-Y weights, yw, +// from a set of primary and white point chromaticities. +// +// Chroma, C, consists of two components, RY and BY: +// +// RY = (R - Y) / Y +// BY = (B - Y) / Y +// +// For efficiency, the x and y subsampling rates for chroma are +// hardwired to 2, and the chroma subsampling and reconstruction +// filters are fixed 27-pixel wide windowed sinc functions. +// +// Starting with an image that has RGBA data for all pixels, +// +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// ... +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// RGBA RGBA RGBA RGBA ... RGBA RGBA +// +// function RGBAtoYCA() converts the pixels to YCA format: +// +// YCA YCA YCA YCA ... YCA YCA +// YCA YCA YCA YCA ... YCA YCA +// YCA YCA YCA YCA ... YCA YCA +// YCA YCA YCA YCA ... YCA YCA +// ... +// YCA YCA YCA YCA ... YCA YCA +// YCA YCA YCA YCA ... YCA YCA +// +// Next, decimateChomaHoriz() eliminates the chroma values from +// the odd-numbered pixels in every scan line: +// +// YCA YA YCA YA ... YCA YA +// YCA YA YCA YA ... YCA YA +// YCA YA YCA YA ... YCA YA +// YCA YA YCA YA ... YCA YA +// ... +// YCA YA YCA YA ... YCA YA +// YCA YA YCA YA ... YCA YA +// +// decimateChromaVert() eliminates all chroma values from the +// odd-numbered scan lines: +// +// YCA YA YCA YA ... YCA YA +// YA YA YA YA ... YA YA +// YCA YA YCA YA ... YCA YA +// YA YA YA YA ... YA YA +// ... +// YCA YA YCA YA ... YCA YA +// YA YA YA YA ... YA YA +// +// Finally, roundYCA() reduces the precision of the luminance +// and chroma values so that the pixel data shrink more when +// they are saved in a compressed file. +// +// The output of roundYCA() can be converted back to a set +// of RGBA pixel data that is visually very similar to the +// original RGBA image, by calling reconstructChromaHoriz(), +// reconstructChromaVert(), YCAtoRGBA(), and finally +// fixSaturation(). +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { +namespace RgbaYca { + + +// +// Width of the chroma subsampling and reconstruction filters +// + +static const int N = 27; +static const int N2 = N / 2; + + +// +// Convert a set of primary chromaticities into a set of weighting +// factors for computing a pixels's luminance, Y, from R, G and B +// + +Imath::V3f computeYw (const Chromaticities &cr); + + +// +// Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha): +// +// ycaOut[i].g = Y (rgbaIn[i]); +// ycaOut[i].r = RY (rgbaIn[i]); +// ycaOut[i].b = BY (rgbaIn[i]); +// ycaOut[i].a = aIsValid? rgbaIn[i].a: 1 +// +// yw is a set of RGB-to-Y weighting factors, as computed by computeYw(). +// + +void RGBAtoYCA (const Imath::V3f &yw, + int n, + bool aIsValid, + const Rgba rgbaIn[/*n*/], + Rgba ycaOut[/*n*/]); + +// +// Perform horizontal low-pass filtering and subsampling of +// the chroma channels of an array of n pixels. In order +// to avoid indexing off the ends of the input array during +// low-pass filtering, ycaIn must have N2 extra pixels at +// both ends. Before calling decimateChromaHoriz(), the extra +// pixels should be filled with copies of the first and last +// "real" input pixel. +// + +void decimateChromaHoriz (int n, + const Rgba ycaIn[/*n+N-1*/], + Rgba ycaOut[/*n*/]); + +// +// Perform vertical chroma channel low-pass filtering and subsampling. +// N scan lines of input pixels are combined into a single scan line +// of output pixels. +// + +void decimateChromaVert (int n, + const Rgba * const ycaIn[N], + Rgba ycaOut[/*n*/]); + +// +// Round the luminance and chroma channels of an array of YCA +// pixels that has already been filtered and subsampled. +// The signifcands of the pixels' luminance and chroma values +// are rounded to roundY and roundC bits respectively. +// + +void roundYCA (int n, + unsigned int roundY, + unsigned int roundC, + const Rgba ycaIn[/*n*/], + Rgba ycaOut[/*n*/]); + +// +// For a scan line that has valid chroma data only for every other pixel, +// reconstruct the missing chroma values. +// + +void reconstructChromaHoriz (int n, + const Rgba ycaIn[/*n+N-1*/], + Rgba ycaOut[/*n*/]); + +// +// For a scan line that has only luminance and no valid chroma data, +// reconstruct chroma from the surronding N scan lines. +// + +void reconstructChromaVert (int n, + const Rgba * const ycaIn[N], + Rgba ycaOut[/*n*/]); + +// +// Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA. +// This function is the inverse of RGBAtoYCA(). +// yw is a set of RGB-to-Y weighting factors, as computed by computeYw(). +// + +void YCAtoRGBA (const Imath::V3f &yw, + int n, + const Rgba ycaIn[/*n*/], + Rgba rgbaOut[/*n*/]); + +// +// Eliminate super-saturated pixels: +// +// Converting an image from RGBA to YCA, low-pass filtering chroma, +// and converting the result back to RGBA can produce pixels with +// super-saturated colors, where one or two of the RGB components +// become zero or negative. (The low-pass and reconstruction filters +// introduce some amount of ringing into the chroma components. +// This can lead to negative RGB values near high-contrast edges.) +// +// The fixSaturation() function finds super-saturated pixels and +// corrects them by desaturating their colors while maintaining +// their luminance. fixSaturation() takes three adjacent input +// scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the +// saturation of rgbaIn[1], and stores the result in rgbaOut. +// + +void fixSaturation (const Imath::V3f &yw, + int n, + const Rgba * const rgbaIn[3], + Rgba rgbaOut[/*n*/]); + +} // namespace RgbaYca +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,331 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class RleCompressor +// +//----------------------------------------------------------------------------- + +#include +#include +#include "Iex.h" + +namespace Imf { +namespace { + +const int MIN_RUN_LENGTH = 3; +const int MAX_RUN_LENGTH = 127; + + +// +// Compress an array of bytes, using run-length encoding, +// and return the length of the compressed data. +// + +int +rleCompress (int inLength, const char in[], signed char out[]) +{ + const char *inEnd = in + inLength; + const char *runStart = in; + const char *runEnd = in + 1; + signed char *outWrite = out; + + while (runStart < inEnd) + { + while (runEnd < inEnd && + *runStart == *runEnd && + runEnd - runStart - 1 < MAX_RUN_LENGTH) + { + ++runEnd; + } + + if (runEnd - runStart >= MIN_RUN_LENGTH) + { + // + // Compressable run + // + + *outWrite++ = (runEnd - runStart) - 1; + *outWrite++ = *(signed char *) runStart; + runStart = runEnd; + } + else + { + // + // Uncompressable run + // + + while (runEnd < inEnd && + ((runEnd + 1 >= inEnd || + *runEnd != *(runEnd + 1)) || + (runEnd + 2 >= inEnd || + *(runEnd + 1) != *(runEnd + 2))) && + runEnd - runStart < MAX_RUN_LENGTH) + { + ++runEnd; + } + + *outWrite++ = runStart - runEnd; + + while (runStart < runEnd) + { + *outWrite++ = *(signed char *) (runStart++); + } + } + + ++runEnd; + } + + return outWrite - out; +} + + +// +// Uncompress an array of bytes compressed with rleCompress(). +// Returns the length of the oncompressed data, or 0 if the +// length of the uncompressed data would be more than maxLength. +// + +int +rleUncompress (int inLength, int maxLength, const signed char in[], char out[]) +{ + char *outStart = out; + + while (inLength > 0) + { + if (*in < 0) + { + int count = -((int)*in++); + inLength -= count + 1; + + if (0 > (maxLength -= count)) + return 0; + + while (count-- > 0) + *out++ = *(char *) (in++); + } + else + { + int count = *in++; + inLength -= 2; + + if (0 > (maxLength -= count + 1)) + return 0; + + while (count-- >= 0) + *out++ = *(char *) in; + + in++; + } + } + + return out - outStart; +} + +} // namespace + + +RleCompressor::RleCompressor (const Header &hdr, size_t maxScanLineSize): + Compressor (hdr), + _maxScanLineSize (maxScanLineSize), + _tmpBuffer (0), + _outBuffer (0) +{ + _tmpBuffer = new char [maxScanLineSize]; + _outBuffer = new char [uiMult (maxScanLineSize, size_t (3)) / 2]; +} + + +RleCompressor::~RleCompressor () +{ + delete [] _tmpBuffer; + delete [] _outBuffer; +} + + +int +RleCompressor::numScanLines () const +{ + // + // This compressor compresses individual scan lines. + // + + return 1; +} + + +int +RleCompressor::compress (const char *inPtr, + int inSize, + int /*minY*/, + const char *&outPtr) +{ + // + // Special case ­- empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Reorder the pixel data. + // + + { + char *t1 = _tmpBuffer; + char *t2 = _tmpBuffer + (inSize + 1) / 2; + const char *stop = inPtr + inSize; + + while (true) + { + if (inPtr < stop) + *(t1++) = *(inPtr++); + else + break; + + if (inPtr < stop) + *(t2++) = *(inPtr++); + else + break; + } + } + + // + // Predictor. + // + + { + unsigned char *t = (unsigned char *) _tmpBuffer + 1; + unsigned char *stop = (unsigned char *) _tmpBuffer + inSize; + int p = t[-1]; + + while (t < stop) + { + int d = int (t[0]) - p + (128 + 256); + p = t[0]; + t[0] = d; + ++t; + } + } + + // + // Run-length encode the data. + // + + outPtr = _outBuffer; + return rleCompress (inSize, _tmpBuffer, (signed char *) _outBuffer); +} + + +int +RleCompressor::uncompress (const char *inPtr, + int inSize, + int /*minY*/, + const char *&outPtr) +{ + // + // Special case ­- empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Decode the run-length encoded data + // + + int outSize; + + if (0 == (outSize = rleUncompress (inSize, _maxScanLineSize, + (const signed char *) inPtr, + _tmpBuffer))) + { + throw Iex::InputExc ("Data decoding (rle) failed."); + } + + // + // Predictor. + // + + { + unsigned char *t = (unsigned char *) _tmpBuffer + 1; + unsigned char *stop = (unsigned char *) _tmpBuffer + outSize; + + while (t < stop) + { + int d = int (t[-1]) + int (t[0]) - 128; + t[0] = d; + ++t; + } + } + + // + // Reorder the pixel data. + // + + { + const char *t1 = _tmpBuffer; + const char *t2 = _tmpBuffer + (outSize + 1) / 2; + char *s = _outBuffer; + char *stop = s + outSize; + + while (true) + { + if (s < stop) + *(s++) = *(t1++); + else + break; + + if (s < stop) + *(s++) = *(t2++); + else + break; + } + } + + outPtr = _outBuffer; + return outSize; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_RLE_COMPRESSOR_H +#define INCLUDED_IMF_RLE_COMPRESSOR_H + +//----------------------------------------------------------------------------- +// +// class RleCompressor -- performs run-length encoding +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +class RleCompressor: public Compressor +{ + public: + + RleCompressor (const Header &hdr, size_t maxScanLineSize); + virtual ~RleCompressor (); + + virtual int numScanLines () const; + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + private: + + int _maxScanLineSize; + char * _tmpBuffer; + char * _outBuffer; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1021 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class ScanLineInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include "ImathBox.h" +#include "ImathFun.h" +#include +#include +#include +#include "IlmThreadPool.h" +#include "IlmThreadSemaphore.h" +#include "IlmThreadMutex.h" +#include "Iex.h" +#include +#include +#include + + +namespace Imf { + +using Imath::Box2i; +using Imath::divp; +using Imath::modp; +using std::string; +using std::vector; +using std::ifstream; +using std::min; +using std::max; +using IlmThread::Mutex; +using IlmThread::Lock; +using IlmThread::Semaphore; +using IlmThread::Task; +using IlmThread::TaskGroup; +using IlmThread::ThreadPool; + +namespace { + +struct InSliceInfo +{ + PixelType typeInFrameBuffer; + PixelType typeInFile; + char * base; + size_t xStride; + size_t yStride; + int xSampling; + int ySampling; + bool fill; + bool skip; + double fillValue; + + InSliceInfo (PixelType typeInFrameBuffer = HALF, + PixelType typeInFile = HALF, + char *base = 0, + size_t xStride = 0, + size_t yStride = 0, + int xSampling = 1, + int ySampling = 1, + bool fill = false, + bool skip = false, + double fillValue = 0.0); +}; + + +InSliceInfo::InSliceInfo (PixelType tifb, + PixelType tifl, + char *b, + size_t xs, size_t ys, + int xsm, int ysm, + bool f, bool s, + double fv) +: + typeInFrameBuffer (tifb), + typeInFile (tifl), + base (b), + xStride (xs), + yStride (ys), + xSampling (xsm), + ySampling (ysm), + fill (f), + skip (s), + fillValue (fv) +{ + // empty +} + + +struct LineBuffer +{ + const char * uncompressedData; + char * buffer; + int dataSize; + int minY; + int maxY; + Compressor * compressor; + Compressor::Format format; + int number; + bool hasException; + string exception; + + LineBuffer (Compressor * const comp); + ~LineBuffer (); + + inline void wait () {_sem.wait();} + inline void post () {_sem.post();} + + private: + + Semaphore _sem; +}; + + +LineBuffer::LineBuffer (Compressor *comp): + uncompressedData (0), + buffer (0), + dataSize (0), + compressor (comp), + format (defaultFormat(compressor)), + number (-1), + hasException (false), + exception (), + _sem (1) +{ + // empty +} + + +LineBuffer::~LineBuffer () +{ + delete compressor; +} + +} // namespace + + +struct ScanLineInputFile::Data: public Mutex +{ + Header header; // the image header + int version; // file's version + FrameBuffer frameBuffer; // framebuffer to write into + LineOrder lineOrder; // order of the scanlines in file + int minX; // data window's min x coord + int maxX; // data window's max x coord + int minY; // data window's min y coord + int maxY; // data window's max x coord + vector lineOffsets; // stores offsets in file for + // each line + bool fileIsComplete; // True if no scanlines are missing + // in the file + int nextLineBufferMinY; // minimum y of the next linebuffer + vector bytesPerLine; // combined size of a line over all + // channels + vector offsetInLineBuffer; // offset for each scanline in its + // linebuffer + vector slices; // info about channels in file + IStream * is; // file stream to read from + + vector lineBuffers; // each holds one line buffer + int linesInBuffer; // number of scanlines each buffer + // holds + size_t lineBufferSize; // size of the line buffer + + Data (IStream *is, int numThreads); + ~Data (); + + inline LineBuffer * getLineBuffer (int number); // hash function from line + // buffer indices into our + // vector of line buffers +}; + + +ScanLineInputFile::Data::Data (IStream *is, int numThreads): + is (is) +{ + // + // We need at least one lineBuffer, but if threading is used, + // to keep n threads busy we need 2*n lineBuffers + // + + lineBuffers.resize (max (1, 2 * numThreads)); +} + + +ScanLineInputFile::Data::~Data () +{ + for (size_t i = 0; i < lineBuffers.size(); i++) + delete lineBuffers[i]; +} + + +inline LineBuffer * +ScanLineInputFile::Data::getLineBuffer (int lineBufferNumber) +{ + return lineBuffers[lineBufferNumber % lineBuffers.size()]; +} + + +namespace { + + +void +reconstructLineOffsets (IStream &is, + LineOrder lineOrder, + vector &lineOffsets) +{ + Int64 position = is.tellg(); + + try + { + for (unsigned int i = 0; i < lineOffsets.size(); i++) + { + Int64 lineOffset = is.tellg(); + + int y; + Xdr::read (is, y); + + int dataSize; + Xdr::read (is, dataSize); + + Xdr::skip (is, dataSize); + + if (lineOrder == INCREASING_Y) + lineOffsets[i] = lineOffset; + else + lineOffsets[lineOffsets.size() - i - 1] = lineOffset; + } + } + catch (...) + { + // + // Suppress all exceptions. This functions is + // called only to reconstruct the line offset + // table for incomplete files, and exceptions + // are likely. + // + } + + is.clear(); + is.seekg (position); +} + + +void +readLineOffsets (IStream &is, + LineOrder lineOrder, + vector &lineOffsets, + bool &complete) +{ + for (unsigned int i = 0; i < lineOffsets.size(); i++) + { + Xdr::read (is, lineOffsets[i]); + } + + complete = true; + + for (unsigned int i = 0; i < lineOffsets.size(); i++) + { + if (lineOffsets[i] <= 0) + { + // + // Invalid data in the line offset table mean that + // the file is probably incomplete (the table is + // the last thing written to the file). Either + // some process is still busy writing the file, + // or writing the file was aborted. + // + // We should still be able to read the existing + // parts of the file. In order to do this, we + // have to make a sequential scan over the scan + // line data to reconstruct the line offset table. + // + + complete = false; + reconstructLineOffsets (is, lineOrder, lineOffsets); + break; + } + } +} + + +void +readPixelData (ScanLineInputFile::Data *ifd, + int minY, + char *&buffer, + int &dataSize) +{ + // + // Read a single line buffer from the input file. + // + // If the input file is not memory-mapped, we copy the pixel data into + // into the array pointed to by buffer. If the file is memory-mapped, + // then we change where buffer points to instead of writing into the + // array (hence buffer needs to be a reference to a char *). + // + + Int64 lineOffset = + ifd->lineOffsets[(minY - ifd->minY) / ifd->linesInBuffer]; + + if (lineOffset == 0) + THROW (Iex::InputExc, "Scan line " << minY << " is missing."); + + // + // Seek to the start of the scan line in the file, + // if necessary. + // + + if (ifd->nextLineBufferMinY != minY) + ifd->is->seekg (lineOffset); + + // + // Read the data block's header. + // + + int yInFile; + + Xdr::read (*ifd->is, yInFile); + Xdr::read (*ifd->is, dataSize); + + if (yInFile != minY) + throw Iex::InputExc ("Unexpected data block y coordinate."); + + if (dataSize > (int) ifd->lineBufferSize) + throw Iex::InputExc ("Unexpected data block length."); + + // + // Read the pixel data. + // + + if (ifd->is->isMemoryMapped ()) + buffer = ifd->is->readMemoryMapped (dataSize); + else + ifd->is->read (buffer, dataSize); + + // + // Keep track of which scan line is the next one in + // the file, so that we can avoid redundant seekg() + // operations (seekg() can be fairly expensive). + // + + if (ifd->lineOrder == INCREASING_Y) + ifd->nextLineBufferMinY = minY + ifd->linesInBuffer; + else + ifd->nextLineBufferMinY = minY - ifd->linesInBuffer; +} + + +// +// A LineBufferTask encapsulates the task uncompressing a set of +// scanlines (line buffer) and copying them into the frame buffer. +// + +class LineBufferTask : public Task +{ + public: + + LineBufferTask (TaskGroup *group, + ScanLineInputFile::Data *ifd, + LineBuffer *lineBuffer, + int scanLineMin, + int scanLineMax); + + virtual ~LineBufferTask (); + + virtual void execute (); + + private: + + ScanLineInputFile::Data * _ifd; + LineBuffer * _lineBuffer; + int _scanLineMin; + int _scanLineMax; +}; + + +LineBufferTask::LineBufferTask + (TaskGroup *group, + ScanLineInputFile::Data *ifd, + LineBuffer *lineBuffer, + int scanLineMin, + int scanLineMax) +: + Task (group), + _ifd (ifd), + _lineBuffer (lineBuffer), + _scanLineMin (scanLineMin), + _scanLineMax (scanLineMax) +{ + // empty +} + + +LineBufferTask::~LineBufferTask () +{ + // + // Signal that the line buffer is now free + // + + _lineBuffer->post (); +} + + +void +LineBufferTask::execute () +{ + try + { + // + // Uncompress the data, if necessary + // + + if (_lineBuffer->uncompressedData == 0) + { + int uncompressedSize = 0; + int maxY = min (_lineBuffer->maxY, _ifd->maxY); + + for (int i = _lineBuffer->minY - _ifd->minY; + i <= maxY - _ifd->minY; + ++i) + { + uncompressedSize += (int) _ifd->bytesPerLine[i]; + } + + if (_lineBuffer->compressor && + _lineBuffer->dataSize < uncompressedSize) + { + _lineBuffer->format = _lineBuffer->compressor->format(); + + _lineBuffer->dataSize = _lineBuffer->compressor->uncompress + (_lineBuffer->buffer, _lineBuffer->dataSize, + _lineBuffer->minY, _lineBuffer->uncompressedData); + } + else + { + // + // If the line is uncompressed, it's in XDR format, + // regardless of the compressor's output format. + // + + _lineBuffer->format = Compressor::XDR; + _lineBuffer->uncompressedData = _lineBuffer->buffer; + } + } + + int yStart, yStop, dy; + + if (_ifd->lineOrder == INCREASING_Y) + { + yStart = _scanLineMin; + yStop = _scanLineMax + 1; + dy = 1; + } + else + { + yStart = _scanLineMax; + yStop = _scanLineMin - 1; + dy = -1; + } + + for (int y = yStart; y != yStop; y += dy) + { + // + // Convert one scan line's worth of pixel data back + // from the machine-independent representation, and + // store the result in the frame buffer. + // + + const char *readPtr = _lineBuffer->uncompressedData + + _ifd->offsetInLineBuffer[y - _ifd->minY]; + + // + // Iterate over all image channels. + // + + for (unsigned int i = 0; i < _ifd->slices.size(); ++i) + { + // + // Test if scan line y of this channel contains any data + // (the scan line contains data only if y % ySampling == 0). + // + + const InSliceInfo &slice = _ifd->slices[i]; + + if (modp (y, slice.ySampling) != 0) + continue; + + // + // Find the x coordinates of the leftmost and rightmost + // sampled pixels (i.e. pixels within the data window + // for which x % xSampling == 0). + // + + int dMinX = divp (_ifd->minX, slice.xSampling); + int dMaxX = divp (_ifd->maxX, slice.xSampling); + + // + // Fill the frame buffer with pixel data. + // + + if (slice.skip) + { + // + // The file contains data for this channel, but + // the frame buffer contains no slice for this channel. + // + + skipChannel (readPtr, slice.typeInFile, dMaxX - dMinX + 1); + } + else + { + // + // The frame buffer contains a slice for this channel. + // + + char *linePtr = slice.base + + divp (y, slice.ySampling) * + slice.yStride; + + char *writePtr = linePtr + dMinX * slice.xStride; + char *endPtr = linePtr + dMaxX * slice.xStride; + + copyIntoFrameBuffer (readPtr, writePtr, endPtr, + slice.xStride, slice.fill, + slice.fillValue, _lineBuffer->format, + slice.typeInFrameBuffer, + slice.typeInFile); + } + } + } + } + catch (std::exception &e) + { + if (!_lineBuffer->hasException) + { + _lineBuffer->exception = e.what(); + _lineBuffer->hasException = true; + } + } + catch (...) + { + if (!_lineBuffer->hasException) + { + _lineBuffer->exception = "unrecognized exception"; + _lineBuffer->hasException = true; + } + } +} + + +LineBufferTask * +newLineBufferTask + (TaskGroup *group, + ScanLineInputFile::Data *ifd, + int number, + int scanLineMin, + int scanLineMax) +{ + // + // Wait for a line buffer to become available, fill the line + // buffer with raw data from the file if necessary, and create + // a new LineBufferTask whose execute() method will uncompress + // the contents of the buffer and copy the pixels into the + // frame buffer. + // + + LineBuffer *lineBuffer = ifd->getLineBuffer (number); + + try + { + lineBuffer->wait (); + + if (lineBuffer->number != number) + { + lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer; + lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1; + + lineBuffer->number = number; + lineBuffer->uncompressedData = 0; + + readPixelData (ifd, lineBuffer->minY, + lineBuffer->buffer, + lineBuffer->dataSize); + } + } + catch (std::exception &e) + { + if (!lineBuffer->hasException) + { + lineBuffer->exception = e.what(); + lineBuffer->hasException = true; + } + lineBuffer->number = -1; + lineBuffer->post();\ + throw; + } + catch (...) + { + // + // Reading from the file caused an exception. + // Signal that the line buffer is free, and + // re-throw the exception. + // + + lineBuffer->exception = "unrecognized exception"; + lineBuffer->hasException = true; + lineBuffer->number = -1; + lineBuffer->post(); + throw; + } + + scanLineMin = max (lineBuffer->minY, scanLineMin); + scanLineMax = min (lineBuffer->maxY, scanLineMax); + + return new LineBufferTask (group, ifd, lineBuffer, + scanLineMin, scanLineMax); +} + +} // namespace + + +ScanLineInputFile::ScanLineInputFile + (const Header &header, + IStream *is, + int numThreads) +: + _data (new Data (is, numThreads)) +{ + try + { + _data->header = header; + + _data->lineOrder = _data->header.lineOrder(); + + const Box2i &dataWindow = _data->header.dataWindow(); + + _data->minX = dataWindow.min.x; + _data->maxX = dataWindow.max.x; + _data->minY = dataWindow.min.y; + _data->maxY = dataWindow.max.y; + + size_t maxBytesPerLine = bytesPerLineTable (_data->header, + _data->bytesPerLine); + + for (size_t i = 0; i < _data->lineBuffers.size(); i++) + { + _data->lineBuffers[i] = new LineBuffer (newCompressor + (_data->header.compression(), + maxBytesPerLine, + _data->header)); + } + + _data->linesInBuffer = + numLinesInBuffer (_data->lineBuffers[0]->compressor); + + _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer; + + if (!_data->is->isMemoryMapped()) + for (size_t i = 0; i < _data->lineBuffers.size(); i++) + _data->lineBuffers[i]->buffer = new char[_data->lineBufferSize]; + + _data->nextLineBufferMinY = _data->minY - 1; + + offsetInLineBufferTable (_data->bytesPerLine, + _data->linesInBuffer, + _data->offsetInLineBuffer); + + int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y + + _data->linesInBuffer) / _data->linesInBuffer; + + _data->lineOffsets.resize (lineOffsetSize); + + readLineOffsets (*_data->is, + _data->lineOrder, + _data->lineOffsets, + _data->fileIsComplete); + } + catch (...) + { + delete _data; + throw; + } +} + + +ScanLineInputFile::~ScanLineInputFile () +{ + if (!_data->is->isMemoryMapped()) + for (size_t i = 0; i < _data->lineBuffers.size(); i++) + delete [] _data->lineBuffers[i]->buffer; + + delete _data; +} + + +const char * +ScanLineInputFile::fileName () const +{ + return _data->is->fileName(); +} + + +const Header & +ScanLineInputFile::header () const +{ + return _data->header; +} + + +int +ScanLineInputFile::version () const +{ + return _data->version; +} + + +void +ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer) +{ + Lock lock (*_data); + + // + // Check if the new frame buffer descriptor is + // compatible with the image file header. + // + + const ChannelList &channels = _data->header.channels(); + + for (FrameBuffer::ConstIterator j = frameBuffer.begin(); + j != frameBuffer.end(); + ++j) + { + ChannelList::ConstIterator i = channels.find (j.name()); + + if (i == channels.end()) + continue; + + if (i.channel().xSampling != j.slice().xSampling || + i.channel().ySampling != j.slice().ySampling) + THROW (Iex::ArgExc, "X and/or y subsampling factors " + "of \"" << i.name() << "\" channel " + "of input file \"" << fileName() << "\" are " + "not compatible with the frame buffer's " + "subsampling factors."); + } + + // + // Initialize the slice table for readPixels(). + // + + vector slices; + ChannelList::ConstIterator i = channels.begin(); + + for (FrameBuffer::ConstIterator j = frameBuffer.begin(); + j != frameBuffer.end(); + ++j) + { + while (i != channels.end() && strcmp (i.name(), j.name()) < 0) + { + // + // Channel i is present in the file but not + // in the frame buffer; data for channel i + // will be skipped during readPixels(). + // + + slices.push_back (InSliceInfo (i.channel().type, + i.channel().type, + 0, // base + 0, // xStride + 0, // yStride + i.channel().xSampling, + i.channel().ySampling, + false, // fill + true, // skip + 0.0)); // fillValue + ++i; + } + + bool fill = false; + + if (i == channels.end() || strcmp (i.name(), j.name()) > 0) + { + // + // Channel i is present in the frame buffer, but not in the file. + // In the frame buffer, slice j will be filled with a default value. + // + + fill = true; + } + + slices.push_back (InSliceInfo (j.slice().type, + fill? j.slice().type: + i.channel().type, + j.slice().base, + j.slice().xStride, + j.slice().yStride, + j.slice().xSampling, + j.slice().ySampling, + fill, + false, // skip + j.slice().fillValue)); + + if (i != channels.end() && !fill) + ++i; + } + + // + // Store the new frame buffer. + // + + _data->frameBuffer = frameBuffer; + _data->slices = slices; +} + + +const FrameBuffer & +ScanLineInputFile::frameBuffer () const +{ + Lock lock (*_data); + return _data->frameBuffer; +} + + +bool +ScanLineInputFile::isComplete () const +{ + return _data->fileIsComplete; +} + + +void +ScanLineInputFile::readPixels (int scanLine1, int scanLine2) +{ + try + { + Lock lock (*_data); + + if (_data->slices.size() == 0) + throw Iex::ArgExc ("No frame buffer specified " + "as pixel data destination."); + + int scanLineMin = min (scanLine1, scanLine2); + int scanLineMax = max (scanLine1, scanLine2); + + if (scanLineMin < _data->minY || scanLineMax > _data->maxY) + throw Iex::ArgExc ("Tried to read scan line outside " + "the image file's data window."); + + // + // We impose a numbering scheme on the lineBuffers where the first + // scanline is contained in lineBuffer 1. + // + // Determine the first and last lineBuffer numbers in this scanline + // range. We always attempt to read the scanlines in the order that + // they are stored in the file. + // + + int start, stop, dl; + + if (_data->lineOrder == INCREASING_Y) + { + start = (scanLineMin - _data->minY) / _data->linesInBuffer; + stop = (scanLineMax - _data->minY) / _data->linesInBuffer + 1; + dl = 1; + } + else + { + start = (scanLineMax - _data->minY) / _data->linesInBuffer; + stop = (scanLineMin - _data->minY) / _data->linesInBuffer - 1; + dl = -1; + } + + // + // Create a task group for all line buffer tasks. When the + // task group goes out of scope, the destructor waits until + // all tasks are complete. + // + + { + TaskGroup taskGroup; + + // + // Add the line buffer tasks. + // + // The tasks will execute in the order that they are created + // because we lock the line buffers during construction and the + // constructors are called by the main thread. Hence, in order + // for a successive task to execute the previous task which + // used that line buffer must have completed already. + // + + for (int l = start; l != stop; l += dl) + { + ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup, + _data, l, + scanLineMin, + scanLineMax)); + } + + // + // finish all tasks + // + } + + // + // Exeption handling: + // + // LineBufferTask::execute() may have encountered exceptions, but + // those exceptions occurred in another thread, not in the thread + // that is executing this call to ScanLineInputFile::readPixels(). + // LineBufferTask::execute() has caught all exceptions and stored + // the exceptions' what() strings in the line buffers. + // Now we check if any line buffer contains a stored exception; if + // this is the case then we re-throw the exception in this thread. + // (It is possible that multiple line buffers contain stored + // exceptions. We re-throw the first exception we find and + // ignore all others.) + // + + const string *exception = 0; + + for (int i = 0; i < _data->lineBuffers.size(); ++i) + { + LineBuffer *lineBuffer = _data->lineBuffers[i]; + + if (lineBuffer->hasException && !exception) + exception = &lineBuffer->exception; + + lineBuffer->hasException = false; + } + + if (exception) + throw Iex::IoExc (*exception); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading pixel data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +ScanLineInputFile::readPixels (int scanLine) +{ + readPixels (scanLine, scanLine); +} + + +void +ScanLineInputFile::rawPixelData (int firstScanLine, + const char *&pixelData, + int &pixelDataSize) +{ + try + { + Lock lock (*_data); + + if (firstScanLine < _data->minY || firstScanLine > _data->maxY) + { + throw Iex::ArgExc ("Tried to read scan line outside " + "the image file's data window."); + } + + int minY = lineBufferMinY + (firstScanLine, _data->minY, _data->linesInBuffer); + + readPixelData + (_data, minY, _data->lineBuffers[0]->buffer, pixelDataSize); + + pixelData = _data->lineBuffers[0]->buffer; + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading pixel data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfScanLineInputFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_SCAN_LINE_INPUT_FILE_H +#define INCLUDED_IMF_SCAN_LINE_INPUT_FILE_H + +//----------------------------------------------------------------------------- +// +// class ScanLineInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + + +class ScanLineInputFile +{ + public: + + //------------ + // Constructor + //------------ + + ScanLineInputFile (const Header &header, IStream *is, + int numThreads = globalThreadCount()); + + + //----------------------------------------- + // Destructor -- deallocates internal data + // structures, but does not close the file. + //----------------------------------------- + + virtual ~ScanLineInputFile (); + + + //------------------------ + // Access to the file name + //------------------------ + + const char * fileName () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + + //----------------------------------------------------------- + // Set the current frame buffer -- copies the FrameBuffer + // object into the InputFile object. + // + // The current frame buffer is the destination for the pixel + // data read from the file. The current frame buffer must be + // set at least once before readPixels() is called. + // The current frame buffer can be changed after each call + // to readPixels(). + //----------------------------------------------------------- + + void setFrameBuffer (const FrameBuffer &frameBuffer); + + + //----------------------------------- + // Access to the current frame buffer + //----------------------------------- + + const FrameBuffer & frameBuffer () const; + + + //--------------------------------------------------------------- + // Check if the file is complete: + // + // isComplete() returns true if all pixels in the data window are + // present in the input file, or false if any pixels are missing. + // (Another program may still be busy writing the file, or file + // writing may have been aborted prematurely.) + //--------------------------------------------------------------- + + bool isComplete () const; + + + //--------------------------------------------------------------- + // Read pixel data: + // + // readPixels(s1,s2) reads all scan lines with y coordinates + // in the interval [min (s1, s2), max (s1, s2)] from the file, + // and stores them in the current frame buffer. + // + // Both s1 and s2 must be within the interval + // [header().dataWindow().min.y, header.dataWindow().max.y] + // + // The scan lines can be read from the file in random order, and + // individual scan lines may be skipped or read multiple times. + // For maximum efficiency, the scan lines should be read in the + // order in which they were written to the file. + // + // readPixels(s) calls readPixels(s,s). + // + // If threading is enabled, readPixels (s1, s2) tries to perform + // decopmression of multiple scanlines in parallel. + // + //--------------------------------------------------------------- + + void readPixels (int scanLine1, int scanLine2); + void readPixels (int scanLine); + + + //---------------------------------------------- + // Read a block of raw pixel data from the file, + // without uncompressing it (this function is + // used to implement OutputFile::copyPixels()). + //---------------------------------------------- + + void rawPixelData (int firstScanLine, + const char *&pixelData, + int &pixelDataSize); + + struct Data; + + private: + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,118 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2003, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Optional Standard Attributes +// +//----------------------------------------------------------------------------- + +#include + + +#define IMF_STRING(name) #name + +#define IMF_STD_ATTRIBUTE_IMP(name,suffix,type) \ + \ + void \ + add##suffix (Header &header, const type &value) \ + { \ + header.insert (IMF_STRING (name), TypedAttribute (value)); \ + } \ + \ + bool \ + has##suffix (const Header &header) \ + { \ + return header.findTypedAttribute > \ + (IMF_STRING (name)) != 0; \ + } \ + \ + const TypedAttribute & \ + name##Attribute (const Header &header) \ + { \ + return header.typedAttribute > \ + (IMF_STRING (name)); \ + } \ + \ + TypedAttribute & \ + name##Attribute (Header &header) \ + { \ + return header.typedAttribute > \ + (IMF_STRING (name)); \ + } \ + \ + const type & \ + name (const Header &header) \ + { \ + return name##Attribute(header).value(); \ + } \ + \ + type & \ + name (Header &header) \ + { \ + return name##Attribute(header).value(); \ + } + + +namespace Imf { + + +IMF_STD_ATTRIBUTE_IMP (chromaticities, Chromaticities, Chromaticities) +IMF_STD_ATTRIBUTE_IMP (whiteLuminance, WhiteLuminance, float) +IMF_STD_ATTRIBUTE_IMP (adoptedNeutral, AdoptedNeutral, Imath::V2f) +IMF_STD_ATTRIBUTE_IMP (renderingTransform, RenderingTransform, std::string) +IMF_STD_ATTRIBUTE_IMP (lookModTransform, LookModTransform, std::string) +IMF_STD_ATTRIBUTE_IMP (xDensity, XDensity, float) +IMF_STD_ATTRIBUTE_IMP (owner, Owner, std::string) +IMF_STD_ATTRIBUTE_IMP (comments, Comments, std::string) +IMF_STD_ATTRIBUTE_IMP (capDate, CapDate, std::string) +IMF_STD_ATTRIBUTE_IMP (utcOffset, UtcOffset, float) +IMF_STD_ATTRIBUTE_IMP (longitude, Longitude, float) +IMF_STD_ATTRIBUTE_IMP (latitude, Latitude, float) +IMF_STD_ATTRIBUTE_IMP (altitude, Altitude, float) +IMF_STD_ATTRIBUTE_IMP (focus, Focus, float) +IMF_STD_ATTRIBUTE_IMP (expTime, ExpTime, float) +IMF_STD_ATTRIBUTE_IMP (aperture, Aperture, float) +IMF_STD_ATTRIBUTE_IMP (isoSpeed, IsoSpeed, float) +IMF_STD_ATTRIBUTE_IMP (envmap, Envmap, Envmap) +IMF_STD_ATTRIBUTE_IMP (keyCode, KeyCode, KeyCode) +IMF_STD_ATTRIBUTE_IMP (timeCode, TimeCode, TimeCode) +IMF_STD_ATTRIBUTE_IMP (wrapmodes, Wrapmodes, std::string) +IMF_STD_ATTRIBUTE_IMP (framesPerSecond, FramesPerSecond, Rational) +IMF_STD_ATTRIBUTE_IMP (multiView, MultiView, StringVector) +IMF_STD_ATTRIBUTE_IMP (worldToCamera, WorldToCamera, Imath::M44f) +IMF_STD_ATTRIBUTE_IMP (worldToNDC, WorldToNDC, Imath::M44f) + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStandardAttributes.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,343 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_STANDARD_ATTRIBUTES_H +#define INCLUDED_IMF_STANDARD_ATTRIBUTES_H + +//----------------------------------------------------------------------------- +// +// Optional Standard Attributes -- these attributes are "optional" +// because not every image file header has them, but they define a +// "standard" way to represent commonly used data in the file header. +// +// For each attribute, with name "foo", and type "T", the following +// functions are automatically generated via macros: +// +// void addFoo (Header &header, const T &value); +// bool hasFoo (const Header &header); +// const TypedAttribute & fooAttribute (const Header &header); +// TypedAttribute & fooAttribute (Header &header); +// const T & foo (const Header &Header); +// T & foo (Header &Header); +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMF_STD_ATTRIBUTE_DEF(name,suffix,type) \ + \ + void add##suffix (Header &header, const type &v); \ + bool has##suffix (const Header &header); \ + const TypedAttribute & name##Attribute (const Header &header); \ + TypedAttribute & name##Attribute (Header &header); \ + const type & name (const Header &header); \ + type & name (Header &header); + + +namespace Imf { + +// +// chromaticities -- for RGB images, specifies the CIE (x,y) +// chromaticities of the primaries and the white point +// + +IMF_STD_ATTRIBUTE_DEF (chromaticities, Chromaticities, Chromaticities) + + +// +// whiteLuminance -- for RGB images, defines the luminance, in Nits +// (candelas per square meter) of the RGB value (1.0, 1.0, 1.0). +// +// If the chromaticities and the whiteLuminance of an RGB image are +// known, then it is possible to convert the image's pixels from RGB +// to CIE XYZ tristimulus values (see function RGBtoXYZ() in header +// file ImfChromaticities.h). +// +// + +IMF_STD_ATTRIBUTE_DEF (whiteLuminance, WhiteLuminance, float) + + +// +// adoptedNeutral -- specifies the CIE (x,y) coordinates that should +// be considered neutral during color rendering. Pixels in the image +// file whose (x,y) coordinates match the adoptedNeutral value should +// be mapped to neutral values on the display. +// + +IMF_STD_ATTRIBUTE_DEF (adoptedNeutral, AdoptedNeutral, Imath::V2f) + + +// +// renderingTransform, lookModTransform -- specify the names of the +// CTL functions that implements the intended color rendering and look +// modification transforms for this image. +// + +IMF_STD_ATTRIBUTE_DEF (renderingTransform, RenderingTransform, std::string) +IMF_STD_ATTRIBUTE_DEF (lookModTransform, LookModTransform, std::string) + + +// +// xDensity -- horizontal output density, in pixels per inch. +// The image's vertical output density is xDensity * pixelAspectRatio. +// + +IMF_STD_ATTRIBUTE_DEF (xDensity, XDensity, float) + + +// +// owner -- name of the owner of the image +// + +IMF_STD_ATTRIBUTE_DEF (owner, Owner, std::string) + + +// +// comments -- additional image information in human-readable +// form, for example a verbal description of the image +// + +IMF_STD_ATTRIBUTE_DEF (comments, Comments, std::string) + + +// +// capDate -- the date when the image was created or captured, +// in local time, and formatted as +// +// YYYY:MM:DD hh:mm:ss +// +// where YYYY is the year (4 digits, e.g. 2003), MM is the month +// (2 digits, 01, 02, ... 12), DD is the day of the month (2 digits, +// 01, 02, ... 31), hh is the hour (2 digits, 00, 01, ... 23), mm +// is the minute, and ss is the second (2 digits, 00, 01, ... 59). +// +// + +IMF_STD_ATTRIBUTE_DEF (capDate, CapDate, std::string) + + +// +// utcOffset -- offset of local time at capDate from +// Universal Coordinated Time (UTC), in seconds: +// +// UTC == local time + utcOffset +// + +IMF_STD_ATTRIBUTE_DEF (utcOffset, UtcOffset, float) + + +// +// longitude, latitude, altitude -- for images of real objects, the +// location where the image was recorded. Longitude and latitude are +// in degrees east of Greenwich and north of the equator. Altitude +// is in meters above sea level. For example, Kathmandu, Nepal is +// at longitude 85.317, latitude 27.717, altitude 1305. +// + +IMF_STD_ATTRIBUTE_DEF (longitude, Longitude, float) +IMF_STD_ATTRIBUTE_DEF (latitude, Latitude, float) +IMF_STD_ATTRIBUTE_DEF (altitude, Altitude, float) + + +// +// focus -- the camera's focus distance, in meters +// + +IMF_STD_ATTRIBUTE_DEF (focus, Focus, float) + + +// +// exposure -- exposure time, in seconds +// + +IMF_STD_ATTRIBUTE_DEF (expTime, ExpTime, float) + + +// +// aperture -- the camera's lens aperture, in f-stops (focal length +// of the lens divided by the diameter of the iris opening) +// + +IMF_STD_ATTRIBUTE_DEF (aperture, Aperture, float) + + +// +// isoSpeed -- the ISO speed of the film or image sensor +// that was used to record the image +// + +IMF_STD_ATTRIBUTE_DEF (isoSpeed, IsoSpeed, float) + + +// +// envmap -- if this attribute is present, the image represents +// an environment map. The attribute's value defines how 3D +// directions are mapped to 2D pixel locations. For details +// see header file ImfEnvmap.h +// + +IMF_STD_ATTRIBUTE_DEF (envmap, Envmap, Envmap) + + +// +// keyCode -- for motion picture film frames. Identifies film +// manufacturer, film type, film roll and frame position within +// the roll. +// + +IMF_STD_ATTRIBUTE_DEF (keyCode, KeyCode, KeyCode) + + +// +// timeCode -- time and control code +// + +IMF_STD_ATTRIBUTE_DEF (timeCode, TimeCode, TimeCode) + + +// +// wrapmodes -- determines how texture map images are extrapolated. +// If an OpenEXR file is used as a texture map for 3D rendering, +// texture coordinates (0.0, 0.0) and (1.0, 1.0) correspond to +// the upper left and lower right corners of the data window. +// If the image is mapped onto a surface with texture coordinates +// outside the zero-to-one range, then the image must be extrapolated. +// This attribute tells the renderer how to do this extrapolation. +// The attribute contains either a pair of comma-separated keywords, +// to specify separate extrapolation modes for the horizontal and +// vertical directions; or a single keyword, to specify extrapolation +// in both directions (e.g. "clamp,periodic" or "clamp"). Extra white +// space surrounding the keywords is allowed, but should be ignored +// by the renderer ("clamp, black " is equivalent to "clamp,black"). +// The keywords listed below are predefined; some renderers may support +// additional extrapolation modes: +// +// black pixels outside the zero-to-one range are black +// +// clamp texture coordinates less than 0.0 and greater +// than 1.0 are clamped to 0.0 and 1.0 respectively +// +// periodic the texture image repeats periodically +// +// mirror the texture image repeats periodically, but +// every other instance is mirrored +// + +IMF_STD_ATTRIBUTE_DEF (wrapmodes, Wrapmodes, std::string) + + +// +// framesPerSecond -- defines the nominal playback frame rate for image +// sequences, in frames per second. Every image in a sequence should +// have a framesPerSecond attribute, and the attribute value should be +// the same for all images in the sequence. If an image sequence has +// no framesPerSecond attribute, playback software should assume that +// the frame rate for the sequence is 24 frames per second. +// +// In order to allow exact representation of NTSC frame and field rates, +// framesPerSecond is stored as a rational number. A rational number is +// a pair of integers, n and d, that represents the value n/d. +// +// For the exact values of commonly used frame rates, please see header +// file ImfFramesPerSecond.h. +// + +IMF_STD_ATTRIBUTE_DEF (framesPerSecond, FramesPerSecond, Rational) + + +// +// multiView -- defines the view names for multi-view image files. +// A multi-view image contains two or more views of the same scene, +// as seen from different viewpoints, for example a left-eye and +// a right-eye view for stereo displays. The multiView attribute +// lists the names of the views in an image, and a naming convention +// identifies the channels that belong to each view. +// +// For details, please see header file ImfMultiView.h +// + +IMF_STD_ATTRIBUTE_DEF (multiView , MultiView, StringVector) + + +// +// worldToCamera -- for images generated by 3D computer graphics rendering, +// a matrix that transforms 3D points from the world to the camera coordinate +// space of the renderer. +// +// The camera coordinate space is left-handed. Its origin indicates the +// location of the camera. The positive x and y axes correspond to the +// "right" and "up" directions in the rendered image. The positive z +// axis indicates the camera's viewing direction. (Objects in front of +// the camera have positive z coordinates.) +// +// Camera coordinate space in OpenEXR is the same as in Pixar's Renderman. +// + +IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, Imath::M44f) + + +// +// worldToNDC -- for images generated by 3D computer graphics rendering, a +// matrix that transforms 3D points from the world to the Normalized Device +// Coordinate (NDC) space of the renderer. +// +// NDC is a 2D coordinate space that corresponds to the image plane, with +// positive x and pointing to the right and y positive pointing down. The +// coordinates (0, 0) and (1, 1) correspond to the upper left and lower right +// corners of the OpenEXR display window. +// +// To transform a 3D point in word space into a 2D point in NDC space, +// multiply the 3D point by the worldToNDC matrix and discard the z +// coordinate. +// +// NDC space in OpenEXR is the same as in Pixar's Renderman. +// + +IMF_STD_ATTRIBUTE_DEF (worldToNDC, WorldToNDC, Imath::M44f) + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,240 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.67 +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Low-level file input and output for OpenEXR +// based on C++ standard iostreams. +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" +#include + +using namespace std; + +namespace Imf { +namespace { + +void +clearError () +{ + errno = 0; +} + + +bool +checkError (istream &is, streamsize expected = 0) +{ + if (!is) + { + if (errno) + Iex::throwErrnoExc(); + + if (is.gcount() < expected) + { + THROW (Iex::InputExc, "Early end of file: read " << is.gcount() + << " out of " << expected << " requested bytes."); + } + return false; + } + + return true; +} + + +void +checkError (ostream &os) +{ + if (!os) + { + if (errno) + Iex::throwErrnoExc(); + + throw Iex::ErrnoExc ("File output failed."); + } +} + +} // namespace + + +StdIFStream::StdIFStream (const char fileName[]): + IStream (fileName), + _is (new ifstream (fileName, ios_base::binary)), + _deleteStream (true) +{ + if (!*_is) + { + delete _is; + Iex::throwErrnoExc(); + } +} + + +StdIFStream::StdIFStream (ifstream &is, const char fileName[]): + IStream (fileName), + _is (&is), + _deleteStream (false) +{ + // empty +} + + +StdIFStream::~StdIFStream () +{ + if (_deleteStream) + delete _is; +} + + +bool +StdIFStream::read (char c[/*n*/], int n) +{ + if (!*_is) + throw Iex::InputExc ("Unexpected end of file."); + + clearError(); + _is->read (c, n); + return checkError (*_is, n); +} + + +Int64 +StdIFStream::tellg () +{ + return std::streamoff (_is->tellg()); +} + + +void +StdIFStream::seekg (Int64 pos) +{ + _is->seekg (pos); + checkError (*_is); +} + + +void +StdIFStream::clear () +{ + _is->clear(); +} + + +StdOFStream::StdOFStream (const char fileName[]): + OStream (fileName), + _os (new ofstream (fileName, ios_base::binary)), + _deleteStream (true) +{ + if (!*_os) + { + delete _os; + Iex::throwErrnoExc(); + } +} + + +StdOFStream::StdOFStream (ofstream &os, const char fileName[]): + OStream (fileName), + _os (&os), + _deleteStream (false) +{ + // empty +} + + +StdOFStream::~StdOFStream () +{ + if (_deleteStream) + delete _os; +} + + +void +StdOFStream::write (const char c[/*n*/], int n) +{ + clearError(); + _os->write (c, n); + checkError (*_os); +} + + +Int64 +StdOFStream::tellp () +{ + return std::streamoff (_os->tellp()); +} + + +void +StdOFStream::seekp (Int64 pos) +{ + _os->seekp (pos); + checkError (*_os); +} + + +StdOSStream::StdOSStream (): OStream ("(string)") +{ + // empty +} + + +void +StdOSStream::write (const char c[/*n*/], int n) +{ + clearError(); + _os.write (c, n); + checkError (_os); +} + + +Int64 +StdOSStream::tellp () +{ + return std::streamoff (_os.tellp()); +} + + +void +StdOSStream::seekp (Int64 pos) +{ + _os.seekp (pos); + checkError (_os); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStdIO.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_STD_IO_H +#define INCLUDED_IMF_STD_IO_H + +//----------------------------------------------------------------------------- +// +// Low-level file input and output for OpenEXR +// based on C++ standard iostreams. +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + +//------------------------------------------- +// class StdIFStream -- an implementation of +// class IStream based on class std::ifstream +//------------------------------------------- + +class StdIFStream: public IStream +{ + public: + + //------------------------------------------------------- + // A constructor that opens the file with the given name. + // The destructor will close the file. + //------------------------------------------------------- + + StdIFStream (const char fileName[]); + + + //--------------------------------------------------------- + // A constructor that uses a std::ifstream that has already + // been opened by the caller. The StdIFStream's destructor + // will not close the std::ifstream. + //--------------------------------------------------------- + + StdIFStream (std::ifstream &is, const char fileName[]); + + + virtual ~StdIFStream (); + + virtual bool read (char c[/*n*/], int n); + virtual Int64 tellg (); + virtual void seekg (Int64 pos); + virtual void clear (); + + private: + + std::ifstream * _is; + bool _deleteStream; +}; + + +//------------------------------------------- +// class StdOFStream -- an implementation of +// class OStream based on class std::ofstream +//------------------------------------------- + +class StdOFStream: public OStream +{ + public: + + //------------------------------------------------------- + // A constructor that opens the file with the given name. + // The destructor will close the file. + //------------------------------------------------------- + + StdOFStream (const char fileName[]); + + + //--------------------------------------------------------- + // A constructor that uses a std::ofstream that has already + // been opened by the caller. The StdOFStream's destructor + // will not close the std::ofstream. + //--------------------------------------------------------- + + StdOFStream (std::ofstream &os, const char fileName[]); + + + virtual ~StdOFStream (); + + virtual void write (const char c[/*n*/], int n); + virtual Int64 tellp (); + virtual void seekp (Int64 pos); + + private: + + std::ofstream * _os; + bool _deleteStream; +}; + + +//------------------------------------------------ +// class StdOSStream -- an implementation of class +// OStream, based on class std::ostringstream +//------------------------------------------------ + +class StdOSStream: public OStream +{ + public: + + StdOSStream (); + + virtual void write (const char c[/*n*/], int n); + virtual Int64 tellp (); + virtual void seekp (Int64 pos); + + std::string str () const {return _os.str();} + + private: + + std::ostringstream _os; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class StringAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +StringAttribute::staticTypeName () +{ + return "string"; +} + + +template <> +void +StringAttribute::writeValueTo (OStream &os, int) const +{ + int size = _value.size(); + + for (int i = 0; i < size; i++) + Xdr::write (os, _value[i]); +} + + +template <> +void +StringAttribute::readValueFrom (IStream &is, int size, int) +{ + _value.resize (size); + + for (int i = 0; i < size; i++) + Xdr::read (is, _value[i]); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_STRING_ATTRIBUTE_H +#define INCLUDED_IMF_STRING_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class StringAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute StringAttribute; +template <> const char *StringAttribute::staticTypeName (); +template <> void StringAttribute::writeValueTo (OStream &, int) const; +template <> void StringAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,94 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Weta Digital Ltd +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Weta Digital nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class StringAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +StringVectorAttribute::staticTypeName () +{ + return "stringvector"; +} + + +template <> +void +StringVectorAttribute::writeValueTo (OStream &os, int) const +{ + int size = _value.size(); + + for (int i = 0; i < size; i++) + { + int strSize = _value[i].size(); + Xdr::write (os, strSize); + Xdr::write (os, &_value[i][0], strSize); + } +} + + +template <> +void +StringVectorAttribute::readValueFrom (IStream &is, int size, int) +{ + int read = 0; + + while (read < size) + { + int strSize; + Xdr::read (is, strSize); + read += Xdr::size(); + + std::string str; + str.resize (strSize); + + Xdr::read (is, &str[0], strSize); + read += strSize; + + _value.push_back (str); + } +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfStringVectorAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007, Weta Digital Ltd +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Weta Digital nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_STRINGVECTOR_ATTRIBUTE_H +#define INCLUDED_IMF_STRINGVECTOR_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class StringVectorAttribute +// +//----------------------------------------------------------------------------- + +#include +#include +#include + + +namespace Imf { + +typedef std::vector StringVector; +typedef TypedAttribute StringVectorAttribute; +template <> const char *StringVectorAttribute::staticTypeName (); +template <> void StringVectorAttribute::writeValueTo (OStream &, int) const; +template <> void StringVectorAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Utility routines to test quickly if a given +// file is an OpenEXR file, and whether the +// file is scanline-based or tiled. +// +//----------------------------------------------------------------------------- + + +#include +#include +#include +#include + +namespace Imf { + + +bool +isOpenExrFile (const char fileName[], bool &tiled) +{ + try + { + StdIFStream is (fileName); + + int magic, version; + Xdr::read (is, magic); + Xdr::read (is, version); + + tiled = isTiled (version); + return magic == MAGIC; + } + catch (...) + { + tiled = false; + return false; + } +} + + +bool +isOpenExrFile (const char fileName[]) +{ + bool tiled; + return isOpenExrFile (fileName, tiled); +} + + +bool +isTiledOpenExrFile (const char fileName[]) +{ + bool exr, tiled; + exr = isOpenExrFile (fileName, tiled); + return exr && tiled; +} + + +bool +isOpenExrFile (IStream &is, bool &tiled) +{ + try + { + Int64 pos = is.tellg(); + + if (pos != 0) + is.seekg (0); + + int magic, version; + Xdr::read (is, magic); + Xdr::read (is, version); + + is.seekg (pos); + + tiled = isTiled (version); + return magic == MAGIC; + } + catch (...) + { + is.clear(); + tiled = false; + return false; + } +} + + +bool +isOpenExrFile (IStream &is) +{ + bool tiled; + return isOpenExrFile (is, tiled); +} + + +bool +isTiledOpenExrFile (IStream &is) +{ + bool exr, tiled; + exr = isOpenExrFile (is, tiled); + return exr && tiled; +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTestFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TEST_FILE_H +#define INCLUDED_IMF_TEST_FILE_H + +//----------------------------------------------------------------------------- +// +// Utility routines to test quickly if a given +// file is an OpenEXR file, and whether the +// file is scanline-based or tiled. +// +//----------------------------------------------------------------------------- + + +namespace Imf { + +class IStream; + + +bool isOpenExrFile (const char fileName[], bool &isTiled); +bool isOpenExrFile (const char fileName[]); +bool isTiledOpenExrFile (const char fileName[]); +bool isOpenExrFile (IStream &is, bool &isTiled); +bool isOpenExrFile (IStream &is); +bool isTiledOpenExrFile (IStream &is); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Threading support for the IlmImf library +// +//----------------------------------------------------------------------------- + +#include "IlmThreadPool.h" +#include "ImfThreading.h" + +namespace Imf { + + +int +globalThreadCount () +{ + return IlmThread::ThreadPool::globalThreadPool().numThreads(); +} + + +void +setGlobalThreadCount (int count) +{ + IlmThread::ThreadPool::globalThreadPool().setNumThreads (count); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfThreading.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,92 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMF_THREADING_H +#define INCLUDED_IMF_THREADING_H + +//----------------------------------------------------------------------------- +// +// Threading support for the IlmImf library +// +// The IlmImf library uses threads to perform reading and writing +// of OpenEXR files in parallel. The thread that calls the library +// always performs the actual file IO (this is usually the main +// application thread) whereas a several worker threads perform +// data compression and decompression. The number of worker +// threads can be any non-negative value (a value of zero reverts +// to single-threaded operation). As long as there is at least +// one worker thread, file IO and compression can potentially be +// done concurrently through pinelining. If there are two or more +// worker threads, then pipelining as well as concurrent compression +// of multiple blocks can be performed. +// +// Threading in the Imf library is controllable at two granularities: +// +// * The functions in this file query and control the total number +// of worker threads, which will be created globally for the whole +// library. Regardless of how many input or output files are +// opened simultaneously, the library will use at most this number +// of worker threads to perform all work. The default number of +// global worker threads is zero (i.e. single-threaded operation; +// everything happens in the thread that calls the library). +// +// * Furthermore, it is possible to set the number of threads that +// each input or output file should keep busy. This number can +// be explicitly set for each file. The default behavior is for +// each file to try to occupy all worker threads in the library's +// thread pool. +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +//----------------------------------------------------------------------------- +// Return the number of Imf-global worker threads used for parallel +// compression and decompression of OpenEXR files. +//----------------------------------------------------------------------------- + +int globalThreadCount (); + + +//----------------------------------------------------------------------------- +// Change the number of Imf-global worker threads +//----------------------------------------------------------------------------- + +void setGlobalThreadCount (int count); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescription.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescription.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescription.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescription.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILE_DESCRIPTION_H +#define INCLUDED_IMF_TILE_DESCRIPTION_H + +//----------------------------------------------------------------------------- +// +// class TileDescription and enum LevelMode +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +enum LevelMode +{ + ONE_LEVEL = 0, + MIPMAP_LEVELS = 1, + RIPMAP_LEVELS = 2, + + NUM_LEVELMODES // number of different level modes +}; + + +enum LevelRoundingMode +{ + ROUND_DOWN = 0, + ROUND_UP = 1, + + NUM_ROUNDINGMODES // number of different rounding modes +}; + + +class TileDescription +{ + public: + + unsigned int xSize; // size of a tile in the x dimension + unsigned int ySize; // size of a tile in the y dimension + LevelMode mode; + LevelRoundingMode roundingMode; + + TileDescription (unsigned int xs = 32, + unsigned int ys = 32, + LevelMode m = ONE_LEVEL, + LevelRoundingMode r = ROUND_DOWN) + : + xSize (xs), + ySize (ys), + mode (m), + roundingMode (r) + { + // empty + } + + bool + operator == (const TileDescription &other) const + { + return xSize == other.xSize && + ySize == other.ySize && + mode == other.mode && + roundingMode == other.roundingMode; + } +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class TileDescriptionAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +TileDescriptionAttribute::staticTypeName () +{ + return "tiledesc"; +} + + +template <> +void +TileDescriptionAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.xSize); + Xdr::write (os, _value.ySize); + + unsigned char tmp = _value.mode | (_value.roundingMode << 4); + Xdr::write (os, tmp); +} + + +template <> +void +TileDescriptionAttribute::readValueFrom (IStream &is, + int, + int) +{ + Xdr::read (is, _value.xSize); + Xdr::read (is, _value.ySize); + + unsigned char tmp; + Xdr::read (is, tmp); + _value.mode = LevelMode (tmp & 0x0f); + _value.roundingMode = LevelRoundingMode ((tmp >> 4) & 0x0f); + +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILE_DESCRIPTION_ATTRIBUTE_H +#define INCLUDED_IMF_TILE_DESCRIPTION_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class TileDescriptionAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imf { + + +typedef TypedAttribute TileDescriptionAttribute; + +template <> +const char * +TileDescriptionAttribute::staticTypeName (); + +template <> +void +TileDescriptionAttribute::writeValueTo (OStream &, int) const; + +template <> +void +TileDescriptionAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,385 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class TileOffsets +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "Iex.h" + +namespace Imf { + + +TileOffsets::TileOffsets (LevelMode mode, + int numXLevels, int numYLevels, + const int *numXTiles, const int *numYTiles) +: + _mode (mode), + _numXLevels (numXLevels), + _numYLevels (numYLevels) +{ + switch (_mode) + { + case ONE_LEVEL: + case MIPMAP_LEVELS: + + _offsets.resize (_numXLevels); + + for (unsigned int l = 0; l < _offsets.size(); ++l) + { + _offsets[l].resize (numYTiles[l]); + + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + { + _offsets[l][dy].resize (numXTiles[l]); + } + } + break; + + case RIPMAP_LEVELS: + + _offsets.resize (_numXLevels * _numYLevels); + + for (unsigned int ly = 0; ly < _numYLevels; ++ly) + { + for (unsigned int lx = 0; lx < _numXLevels; ++lx) + { + int l = ly * _numXLevels + lx; + _offsets[l].resize (numYTiles[ly]); + + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + { + _offsets[l][dy].resize (numXTiles[lx]); + } + } + } + break; + } +} + + +bool +TileOffsets::anyOffsetsAreInvalid () const +{ + for (unsigned int l = 0; l < _offsets.size(); ++l) + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx) + if (_offsets[l][dy][dx] <= 0) + return true; + + return false; +} + + +void +TileOffsets::findTiles (IStream &is) +{ + for (unsigned int l = 0; l < _offsets.size(); ++l) + { + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + { + for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx) + { + Int64 tileOffset = is.tellg(); + + int tileX; + Xdr::read (is, tileX); + + int tileY; + Xdr::read (is, tileY); + + int levelX; + Xdr::read (is, levelX); + + int levelY; + Xdr::read (is, levelY); + + int dataSize; + Xdr::read (is, dataSize); + + Xdr::skip (is, dataSize); + + if (!isValidTile(tileX, tileY, levelX, levelY)) + return; + + operator () (tileX, tileY, levelX, levelY) = tileOffset; + } + } + } +} + + +void +TileOffsets::reconstructFromFile (IStream &is) +{ + // + // Try to reconstruct a missing tile offset table by sequentially + // scanning through the file, and recording the offsets in the file + // of the tiles we find. + // + + Int64 position = is.tellg(); + + try + { + findTiles (is); + } + catch (...) + { + // + // Suppress all exceptions. This function is called only to + // reconstruct the tile offset table for incomplete files, + // and exceptions are likely. + // + } + + is.clear(); + is.seekg (position); +} + + +void +TileOffsets::readFrom (IStream &is, bool &complete) +{ + // + // Read in the tile offsets from the file's tile offset table + // + + for (unsigned int l = 0; l < _offsets.size(); ++l) + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx) + Xdr::read (is, _offsets[l][dy][dx]); + + // + // Check if any tile offsets are invalid. + // + // Invalid offsets mean that the file is probably incomplete + // (the offset table is the last thing written to the file). + // Either some process is still busy writing the file, or + // writing the file was aborted. + // + // We should still be able to read the existing parts of the + // file. In order to do this, we have to make a sequential + // scan over the scan tile to reconstruct the tile offset + // table. + // + + if (anyOffsetsAreInvalid()) + { + complete = false; + reconstructFromFile (is); + } + else + { + complete = true; + } + +} + + +Int64 +TileOffsets::writeTo (OStream &os) const +{ + // + // Write the tile offset table to the file, and + // return the position of the start of the table + // in the file. + // + + Int64 pos = os.tellp(); + + if (pos == -1) + Iex::throwErrnoExc ("Cannot determine current file position (%T)."); + + for (unsigned int l = 0; l < _offsets.size(); ++l) + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx) + Xdr::write (os, _offsets[l][dy][dx]); + + return pos; +} + + +bool +TileOffsets::isEmpty () const +{ + for (unsigned int l = 0; l < _offsets.size(); ++l) + for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy) + for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx) + if (_offsets[l][dy][dx] != 0) + return false; + return true; +} + + +bool +TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const +{ + switch (_mode) + { + case ONE_LEVEL: + + if (lx == 0 && + ly == 0 && + _offsets.size() > 0 && + _offsets[0].size() > dy && + _offsets[0][dy].size() > dx) + { + return true; + } + + break; + + case MIPMAP_LEVELS: + + if (lx < _numXLevels && + ly < _numYLevels && + _offsets.size() > lx && + _offsets[lx].size() > dy && + _offsets[lx][dy].size() > dx) + { + return true; + } + + break; + + case RIPMAP_LEVELS: + + if (lx < _numXLevels && + ly < _numYLevels && + _offsets.size() > lx + ly * _numXLevels && + _offsets[lx + ly * _numXLevels].size() > dy && + _offsets[lx + ly * _numXLevels][dy].size() > dx) + { + return true; + } + + break; + + default: + + return false; + } + + return false; +} + + +Int64 & +TileOffsets::operator () (int dx, int dy, int lx, int ly) +{ + // + // Looks up the value of the tile with tile coordinate (dx, dy) + // and level number (lx, ly) in the _offsets array, and returns + // the cooresponding offset. + // + + switch (_mode) + { + case ONE_LEVEL: + + return _offsets[0][dy][dx]; + break; + + case MIPMAP_LEVELS: + + return _offsets[lx][dy][dx]; + break; + + case RIPMAP_LEVELS: + + return _offsets[lx + ly * _numXLevels][dy][dx]; + break; + + default: + + throw Iex::ArgExc ("Unknown LevelMode format."); + } +} + + +Int64 & +TileOffsets::operator () (int dx, int dy, int l) +{ + return operator () (dx, dy, l, l); +} + + +const Int64 & +TileOffsets::operator () (int dx, int dy, int lx, int ly) const +{ + // + // Looks up the value of the tile with tile coordinate (dx, dy) + // and level number (lx, ly) in the _offsets array, and returns + // the cooresponding offset. + // + + switch (_mode) + { + case ONE_LEVEL: + + return _offsets[0][dy][dx]; + break; + + case MIPMAP_LEVELS: + + return _offsets[lx][dy][dx]; + break; + + case RIPMAP_LEVELS: + + return _offsets[lx + ly * _numXLevels][dy][dx]; + break; + + default: + + throw Iex::ArgExc ("Unknown LevelMode format."); + } +} + + +const Int64 & +TileOffsets::operator () (int dx, int dy, int l) const +{ + return operator () (dx, dy, l, l); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTileOffsets.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,107 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILE_OFFSETS_H +#define INCLUDED_IMF_TILE_OFFSETS_H + +//----------------------------------------------------------------------------- +// +// class TileOffsets +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +namespace Imf { + +class IStream; +class OStream; + + +class TileOffsets +{ + public: + + TileOffsets (LevelMode mode = ONE_LEVEL, + int numXLevels = 0, + int numYLevels = 0, + const int *numXTiles = 0, + const int *numYTiles = 0); + + // -------- + // File I/O + // -------- + + void readFrom (IStream &is, bool &complete); + Int64 writeTo (OStream &os) const; + + + //----------------------------------------------------------- + // Test if the tileOffsets array is empty (all entries are 0) + //----------------------------------------------------------- + + bool isEmpty () const; + + + //----------------------- + // Access to the elements + //----------------------- + + Int64 & operator () (int dx, int dy, int lx, int ly); + Int64 & operator () (int dx, int dy, int l); + const Int64 & operator () (int dx, int dy, int lx, int ly) const; + const Int64 & operator () (int dx, int dy, int l) const; + + private: + + void findTiles (IStream &is); + void reconstructFromFile (IStream &is); + bool readTile (IStream &is); + bool anyOffsetsAreInvalid () const; + bool isValidTile (int dx, int dy, int lx, int ly) const; + + LevelMode _mode; + int _numXLevels; + int _numYLevels; + + std::vector > > _offsets; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1302 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class TiledInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include "ImathBox.h" +#include +#include +#include +#include +#include +#include "IlmThreadPool.h" +#include "IlmThreadSemaphore.h" +#include "IlmThreadMutex.h" +#include "ImathVec.h" +#include "Iex.h" +#include +#include +#include +#include + + +namespace Imf { + +using Imath::Box2i; +using Imath::V2i; +using std::string; +using std::vector; +using std::min; +using std::max; +using IlmThread::Mutex; +using IlmThread::Lock; +using IlmThread::Semaphore; +using IlmThread::Task; +using IlmThread::TaskGroup; +using IlmThread::ThreadPool; + +namespace { + +struct TInSliceInfo +{ + PixelType typeInFrameBuffer; + PixelType typeInFile; + char * base; + size_t xStride; + size_t yStride; + bool fill; + bool skip; + double fillValue; + int xTileCoords; + int yTileCoords; + + TInSliceInfo (PixelType typeInFrameBuffer = HALF, + PixelType typeInFile = HALF, + char *base = 0, + size_t xStride = 0, + size_t yStride = 0, + bool fill = false, + bool skip = false, + double fillValue = 0.0, + int xTileCoords = 0, + int yTileCoords = 0); +}; + + +TInSliceInfo::TInSliceInfo (PixelType tifb, + PixelType tifl, + char *b, + size_t xs, size_t ys, + bool f, bool s, + double fv, + int xtc, + int ytc) +: + typeInFrameBuffer (tifb), + typeInFile (tifl), + base (b), + xStride (xs), + yStride (ys), + fill (f), + skip (s), + fillValue (fv), + xTileCoords (xtc), + yTileCoords (ytc) +{ + // empty +} + + +struct TileBuffer +{ + const char * uncompressedData; + char * buffer; + int dataSize; + Compressor * compressor; + Compressor::Format format; + int dx; + int dy; + int lx; + int ly; + bool hasException; + string exception; + + TileBuffer (Compressor * const comp); + ~TileBuffer (); + + inline void wait () {_sem.wait();} + inline void post () {_sem.post();} + + protected: + + Semaphore _sem; +}; + + +TileBuffer::TileBuffer (Compressor *comp): + uncompressedData (0), + dataSize (0), + compressor (comp), + format (defaultFormat (compressor)), + dx (-1), + dy (-1), + lx (-1), + ly (-1), + hasException (false), + exception (), + _sem (1) +{ + // empty +} + + +TileBuffer::~TileBuffer () +{ + delete compressor; +} + +} // namespace + + +// +// struct TiledInputFile::Data stores things that will be +// needed between calls to readTile() +// + +struct TiledInputFile::Data: public Mutex +{ + Header header; // the image header + TileDescription tileDesc; // describes the tile layout + int version; // file's version + FrameBuffer frameBuffer; // framebuffer to write into + LineOrder lineOrder; // the file's lineorder + int minX; // data window's min x coord + int maxX; // data window's max x coord + int minY; // data window's min y coord + int maxY; // data window's max x coord + + int numXLevels; // number of x levels + int numYLevels; // number of y levels + int * numXTiles; // number of x tiles at a level + int * numYTiles; // number of y tiles at a level + + TileOffsets tileOffsets; // stores offsets in file for + // each tile + + bool fileIsComplete; // True if no tiles are missing + // in the file + + Int64 currentPosition; // file offset for current tile, + // used to prevent unnecessary + // seeking + + vector slices; // info about channels in file + IStream * is; // file stream to read from + + bool deleteStream; // should we delete the stream + // ourselves? or does someone + // else do it? + + size_t bytesPerPixel; // size of an uncompressed pixel + + size_t maxBytesPerTileLine; // combined size of a line + // over all channels + + + vector tileBuffers; // each holds a single tile + size_t tileBufferSize; // size of the tile buffers + + Data (bool deleteStream, int numThreads); + ~Data (); + + inline TileBuffer * getTileBuffer (int number); + // hash function from tile indices + // into our vector of tile buffers +}; + + +TiledInputFile::Data::Data (bool del, int numThreads): + numXTiles (0), + numYTiles (0), + is (0), + deleteStream (del) +{ + // + // We need at least one tileBuffer, but if threading is used, + // to keep n threads busy we need 2*n tileBuffers + // + + tileBuffers.resize (max (1, 2 * numThreads)); +} + + +TiledInputFile::Data::~Data () +{ + delete [] numXTiles; + delete [] numYTiles; + + if (deleteStream) + delete is; + + for (size_t i = 0; i < tileBuffers.size(); i++) + delete tileBuffers[i]; +} + + +TileBuffer* +TiledInputFile::Data::getTileBuffer (int number) +{ + return tileBuffers[number % tileBuffers.size()]; +} + + +namespace { + +void +readTileData (TiledInputFile::Data *ifd, + int dx, int dy, + int lx, int ly, + char *&buffer, + int &dataSize) +{ + // + // Read a single tile block from the file and into the array pointed + // to by buffer. If the file is memory-mapped, then we change where + // buffer points instead of writing into the array (hence buffer needs + // to be a reference to a char *). + // + + // + // Look up the location for this tile in the Index and + // seek to that position if necessary + // + + Int64 tileOffset = ifd->tileOffsets (dx, dy, lx, ly); + + if (tileOffset == 0) + { + THROW (Iex::InputExc, "Tile (" << dx << ", " << dy << ", " << + lx << ", " << ly << ") is missing."); + } + + if (ifd->currentPosition != tileOffset) + ifd->is->seekg (tileOffset); + + // + // Read the first few bytes of the tile (the header). + // Verify that the tile coordinates and the level number + // are correct. + // + + int tileXCoord, tileYCoord, levelX, levelY; + + Xdr::read (*ifd->is, tileXCoord); + Xdr::read (*ifd->is, tileYCoord); + Xdr::read (*ifd->is, levelX); + Xdr::read (*ifd->is, levelY); + Xdr::read (*ifd->is, dataSize); + + if (tileXCoord != dx) + throw Iex::InputExc ("Unexpected tile x coordinate."); + + if (tileYCoord != dy) + throw Iex::InputExc ("Unexpected tile y coordinate."); + + if (levelX != lx) + throw Iex::InputExc ("Unexpected tile x level number coordinate."); + + if (levelY != ly) + throw Iex::InputExc ("Unexpected tile y level number coordinate."); + + if (dataSize > (int) ifd->tileBufferSize) + throw Iex::InputExc ("Unexpected tile block length."); + + // + // Read the pixel data. + // + + if (ifd->is->isMemoryMapped ()) + buffer = ifd->is->readMemoryMapped (dataSize); + else + ifd->is->read (buffer, dataSize); + + // + // Keep track of which tile is the next one in + // the file, so that we can avoid redundant seekg() + // operations (seekg() can be fairly expensive). + // + + ifd->currentPosition = tileOffset + 5 * Xdr::size() + dataSize; +} + + +void +readNextTileData (TiledInputFile::Data *ifd, + int &dx, int &dy, + int &lx, int &ly, + char * & buffer, + int &dataSize) +{ + // + // Read the next tile block from the file + // + + // + // Read the first few bytes of the tile (the header). + // + + Xdr::read (*ifd->is, dx); + Xdr::read (*ifd->is, dy); + Xdr::read (*ifd->is, lx); + Xdr::read (*ifd->is, ly); + Xdr::read (*ifd->is, dataSize); + + if (dataSize > (int) ifd->tileBufferSize) + throw Iex::InputExc ("Unexpected tile block length."); + + // + // Read the pixel data. + // + + ifd->is->read (buffer, dataSize); + + // + // Keep track of which tile is the next one in + // the file, so that we can avoid redundant seekg() + // operations (seekg() can be fairly expensive). + // + + ifd->currentPosition += 5 * Xdr::size() + dataSize; +} + + +// +// A TileBufferTask encapsulates the task of uncompressing +// a single tile and copying it into the frame buffer. +// + +class TileBufferTask : public Task +{ + public: + + TileBufferTask (TaskGroup *group, + TiledInputFile::Data *ifd, + TileBuffer *tileBuffer); + + virtual ~TileBufferTask (); + + virtual void execute (); + + private: + + TiledInputFile::Data * _ifd; + TileBuffer * _tileBuffer; +}; + + +TileBufferTask::TileBufferTask + (TaskGroup *group, + TiledInputFile::Data *ifd, + TileBuffer *tileBuffer) +: + Task (group), + _ifd (ifd), + _tileBuffer (tileBuffer) +{ + // empty +} + + +TileBufferTask::~TileBufferTask () +{ + // + // Signal that the tile buffer is now free + // + + _tileBuffer->post (); +} + + +void +TileBufferTask::execute () +{ + try + { + // + // Calculate information about the tile + // + + Box2i tileRange = Imf::dataWindowForTile (_ifd->tileDesc, + _ifd->minX, _ifd->maxX, + _ifd->minY, _ifd->maxY, + _tileBuffer->dx, + _tileBuffer->dy, + _tileBuffer->lx, + _tileBuffer->ly); + + int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1; + + int numPixelsInTile = numPixelsPerScanLine * + (tileRange.max.y - tileRange.min.y + 1); + + int sizeOfTile = _ifd->bytesPerPixel * numPixelsInTile; + + + // + // Uncompress the data, if necessary + // + + if (_tileBuffer->compressor && _tileBuffer->dataSize < sizeOfTile) + { + _tileBuffer->format = _tileBuffer->compressor->format(); + + _tileBuffer->dataSize = _tileBuffer->compressor->uncompressTile + (_tileBuffer->buffer, _tileBuffer->dataSize, + tileRange, _tileBuffer->uncompressedData); + } + else + { + // + // If the line is uncompressed, it's in XDR format, + // regardless of the compressor's output format. + // + + _tileBuffer->format = Compressor::XDR; + _tileBuffer->uncompressedData = _tileBuffer->buffer; + } + + // + // Convert the tile of pixel data back from the machine-independent + // representation, and store the result in the frame buffer. + // + + const char *readPtr = _tileBuffer->uncompressedData; + // points to where we + // read from in the + // tile block + + // + // Iterate over the scan lines in the tile. + // + + for (int y = tileRange.min.y; y <= tileRange.max.y; ++y) + { + // + // Iterate over all image channels. + // + + for (unsigned int i = 0; i < _ifd->slices.size(); ++i) + { + const TInSliceInfo &slice = _ifd->slices[i]; + + // + // These offsets are used to facilitate both + // absolute and tile-relative pixel coordinates. + // + + int xOffset = slice.xTileCoords * tileRange.min.x; + int yOffset = slice.yTileCoords * tileRange.min.y; + + // + // Fill the frame buffer with pixel data. + // + + if (slice.skip) + { + // + // The file contains data for this channel, but + // the frame buffer contains no slice for this channel. + // + + skipChannel (readPtr, slice.typeInFile, + numPixelsPerScanLine); + } + else + { + // + // The frame buffer contains a slice for this channel. + // + + char *writePtr = slice.base + + (y - yOffset) * slice.yStride + + (tileRange.min.x - xOffset) * + slice.xStride; + + char *endPtr = writePtr + + (numPixelsPerScanLine - 1) * slice.xStride; + + copyIntoFrameBuffer (readPtr, writePtr, endPtr, + slice.xStride, + slice.fill, slice.fillValue, + _tileBuffer->format, + slice.typeInFrameBuffer, + slice.typeInFile); + } + } + } + } + catch (std::exception &e) + { + if (!_tileBuffer->hasException) + { + _tileBuffer->exception = e.what (); + _tileBuffer->hasException = true; + } + } + catch (...) + { + if (!_tileBuffer->hasException) + { + _tileBuffer->exception = "unrecognized exception"; + _tileBuffer->hasException = true; + } + } +} + + +TileBufferTask * +newTileBufferTask + (TaskGroup *group, + TiledInputFile::Data *ifd, + int number, + int dx, int dy, + int lx, int ly) +{ + // + // Wait for a tile buffer to become available, + // fill the buffer with raw data from the file, + // and create a new TileBufferTask whose execute() + // method will uncompress the tile and copy the + // tile's pixels into the frame buffer. + // + + TileBuffer *tileBuffer = ifd->getTileBuffer (number); + + try + { + tileBuffer->wait(); + + tileBuffer->dx = dx; + tileBuffer->dy = dy; + tileBuffer->lx = lx; + tileBuffer->ly = ly; + + tileBuffer->uncompressedData = 0; + + readTileData (ifd, dx, dy, lx, ly, + tileBuffer->buffer, + tileBuffer->dataSize); + } + catch (...) + { + // + // Reading from the file caused an exception. + // Signal that the tile buffer is free, and + // re-throw the exception. + // + + tileBuffer->post(); + throw; + } + + return new TileBufferTask (group, ifd, tileBuffer); +} + + +} // namespace + + +TiledInputFile::TiledInputFile (const char fileName[], int numThreads): + _data (new Data (true, numThreads)) +{ + // + // This constructor is called when a user + // explicitly wants to read a tiled file. + // + + try + { + _data->is = new StdIFStream (fileName); + _data->header.readFrom (*_data->is, _data->version); + initialize(); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << fileName << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +TiledInputFile::TiledInputFile (IStream &is, int numThreads): + _data (new Data (false, numThreads)) +{ + // + // This constructor is called when a user + // explicitly wants to read a tiled file. + // + + try + { + _data->is = &is; + _data->header.readFrom (*_data->is, _data->version); + initialize(); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << is.fileName() << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +TiledInputFile::TiledInputFile + (const Header &header, + IStream *is, + int version, + int numThreads) +: + _data (new Data (false, numThreads)) +{ + // + // This constructor called by class Imf::InputFile + // when a user wants to just read an image file, and + // doesn't care or know if the file is tiled. + // + + _data->is = is; + _data->header = header; + _data->version = version; + initialize(); +} + + +void +TiledInputFile::initialize () +{ + if (!isTiled (_data->version)) + throw Iex::ArgExc ("Expected a tiled file but the file is not tiled."); + + _data->header.sanityCheck (true); + + _data->tileDesc = _data->header.tileDescription(); + _data->lineOrder = _data->header.lineOrder(); + + // + // Save the dataWindow information + // + + const Box2i &dataWindow = _data->header.dataWindow(); + _data->minX = dataWindow.min.x; + _data->maxX = dataWindow.max.x; + _data->minY = dataWindow.min.y; + _data->maxY = dataWindow.max.y; + + // + // Precompute level and tile information to speed up utility functions + // + + precalculateTileInfo (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + _data->numXTiles, _data->numYTiles, + _data->numXLevels, _data->numYLevels); + + _data->bytesPerPixel = calculateBytesPerPixel (_data->header); + + _data->maxBytesPerTileLine = _data->bytesPerPixel * _data->tileDesc.xSize; + + _data->tileBufferSize = _data->maxBytesPerTileLine * _data->tileDesc.ySize; + + // + // Create all the TileBuffers and allocate their internal buffers + // + + for (size_t i = 0; i < _data->tileBuffers.size(); i++) + { + _data->tileBuffers[i] = new TileBuffer (newTileCompressor + (_data->header.compression(), + _data->maxBytesPerTileLine, + _data->tileDesc.ySize, + _data->header)); + + if (!_data->is->isMemoryMapped ()) + _data->tileBuffers[i]->buffer = new char [_data->tileBufferSize]; + } + + _data->tileOffsets = TileOffsets (_data->tileDesc.mode, + _data->numXLevels, + _data->numYLevels, + _data->numXTiles, + _data->numYTiles); + + _data->tileOffsets.readFrom (*(_data->is), _data->fileIsComplete); + + _data->currentPosition = _data->is->tellg(); +} + + +TiledInputFile::~TiledInputFile () +{ + if (!_data->is->isMemoryMapped()) + for (size_t i = 0; i < _data->tileBuffers.size(); i++) + delete [] _data->tileBuffers[i]->buffer; + + delete _data; +} + + +const char * +TiledInputFile::fileName () const +{ + return _data->is->fileName(); +} + + +const Header & +TiledInputFile::header () const +{ + return _data->header; +} + + +int +TiledInputFile::version () const +{ + return _data->version; +} + + +void +TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer) +{ + Lock lock (*_data); + + // + // Set the frame buffer + // + + // + // Check if the new frame buffer descriptor is + // compatible with the image file header. + // + + const ChannelList &channels = _data->header.channels(); + + for (FrameBuffer::ConstIterator j = frameBuffer.begin(); + j != frameBuffer.end(); + ++j) + { + ChannelList::ConstIterator i = channels.find (j.name()); + + if (i == channels.end()) + continue; + + if (i.channel().xSampling != j.slice().xSampling || + i.channel().ySampling != j.slice().ySampling) + THROW (Iex::ArgExc, "X and/or y subsampling factors " + "of \"" << i.name() << "\" channel " + "of input file \"" << fileName() << "\" are " + "not compatible with the frame buffer's " + "subsampling factors."); + } + + // + // Initialize the slice table for readPixels(). + // + + vector slices; + ChannelList::ConstIterator i = channels.begin(); + + for (FrameBuffer::ConstIterator j = frameBuffer.begin(); + j != frameBuffer.end(); + ++j) + { + while (i != channels.end() && strcmp (i.name(), j.name()) < 0) + { + // + // Channel i is present in the file but not + // in the frame buffer; data for channel i + // will be skipped during readPixels(). + // + + slices.push_back (TInSliceInfo (i.channel().type, + i.channel().type, + 0, // base + 0, // xStride + 0, // yStride + false, // fill + true, // skip + 0.0)); // fillValue + ++i; + } + + bool fill = false; + + if (i == channels.end() || strcmp (i.name(), j.name()) > 0) + { + // + // Channel i is present in the frame buffer, but not in the file. + // In the frame buffer, slice j will be filled with a default value. + // + + fill = true; + } + + slices.push_back (TInSliceInfo (j.slice().type, + fill? j.slice().type: i.channel().type, + j.slice().base, + j.slice().xStride, + j.slice().yStride, + fill, + false, // skip + j.slice().fillValue, + (j.slice().xTileCoords)? 1: 0, + (j.slice().yTileCoords)? 1: 0)); + + if (i != channels.end() && !fill) + ++i; + } + + while (i != channels.end()) + { + // + // Channel i is present in the file but not + // in the frame buffer; data for channel i + // will be skipped during readPixels(). + // + + slices.push_back (TInSliceInfo (i.channel().type, + i.channel().type, + 0, // base + 0, // xStride + 0, // yStride + false, // fill + true, // skip + 0.0)); // fillValue + ++i; + } + + // + // Store the new frame buffer. + // + + _data->frameBuffer = frameBuffer; + _data->slices = slices; +} + + +const FrameBuffer & +TiledInputFile::frameBuffer () const +{ + Lock lock (*_data); + return _data->frameBuffer; +} + + +bool +TiledInputFile::isComplete () const +{ + return _data->fileIsComplete; +} + + +void +TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly) +{ + // + // Read a range of tiles from the file into the framebuffer + // + + try + { + Lock lock (*_data); + + if (_data->slices.size() == 0) + throw Iex::ArgExc ("No frame buffer specified " + "as pixel data destination."); + + // + // Determine the first and last tile coordinates in both dimensions. + // We always attempt to read the range of tiles in the order that + // they are stored in the file. + // + + if (dx1 > dx2) + std::swap (dx1, dx2); + + if (dy1 > dy2) + std::swap (dy1, dy2); + + int dyStart = dy1; + int dyStop = dy2 + 1; + int dY = 1; + + if (_data->lineOrder == DECREASING_Y) + { + dyStart = dy2; + dyStop = dy1 - 1; + dY = -1; + } + + // + // Create a task group for all tile buffer tasks. When the + // task group goes out of scope, the destructor waits until + // all tasks are complete. + // + + { + TaskGroup taskGroup; + int tileNumber = 0; + + for (int dy = dyStart; dy != dyStop; dy += dY) + { + for (int dx = dx1; dx <= dx2; dx++) + { + if (!isValidTile (dx, dy, lx, ly)) + THROW (Iex::ArgExc, + "Tile (" << dx << ", " << dy << ", " << + lx << "," << ly << ") is not a valid tile."); + + ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup, + _data, + tileNumber++, + dx, dy, + lx, ly)); + } + } + + // + // finish all tasks + // + } + + // + // Exeption handling: + // + // TileBufferTask::execute() may have encountered exceptions, but + // those exceptions occurred in another thread, not in the thread + // that is executing this call to TiledInputFile::readTiles(). + // TileBufferTask::execute() has caught all exceptions and stored + // the exceptions' what() strings in the tile buffers. + // Now we check if any tile buffer contains a stored exception; if + // this is the case then we re-throw the exception in this thread. + // (It is possible that multiple tile buffers contain stored + // exceptions. We re-throw the first exception we find and + // ignore all others.) + // + + const string *exception = 0; + + for (int i = 0; i < _data->tileBuffers.size(); ++i) + { + TileBuffer *tileBuffer = _data->tileBuffers[i]; + + if (tileBuffer->hasException && !exception) + exception = &tileBuffer->exception; + + tileBuffer->hasException = false; + } + + if (exception) + throw Iex::IoExc (*exception); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading pixel data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int l) +{ + readTiles (dx1, dx2, dy1, dy2, l, l); +} + + +void +TiledInputFile::readTile (int dx, int dy, int lx, int ly) +{ + readTiles (dx, dx, dy, dy, lx, ly); +} + + +void +TiledInputFile::readTile (int dx, int dy, int l) +{ + readTile (dx, dy, l, l); +} + + +void +TiledInputFile::rawTileData (int &dx, int &dy, + int &lx, int &ly, + const char *&pixelData, + int &pixelDataSize) +{ + try + { + Lock lock (*_data); + + if (!isValidTile (dx, dy, lx, ly)) + throw Iex::ArgExc ("Tried to read a tile outside " + "the image file's data window."); + + TileBuffer *tileBuffer = _data->getTileBuffer (0); + + readNextTileData (_data, dx, dy, lx, ly, + tileBuffer->buffer, + pixelDataSize); + + pixelData = tileBuffer->buffer; + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error reading pixel data from image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +unsigned int +TiledInputFile::tileXSize () const +{ + return _data->tileDesc.xSize; +} + + +unsigned int +TiledInputFile::tileYSize () const +{ + return _data->tileDesc.ySize; +} + + +LevelMode +TiledInputFile::levelMode () const +{ + return _data->tileDesc.mode; +} + + +LevelRoundingMode +TiledInputFile::levelRoundingMode () const +{ + return _data->tileDesc.roundingMode; +} + + +int +TiledInputFile::numLevels () const +{ + if (levelMode() == RIPMAP_LEVELS) + THROW (Iex::LogicExc, "Error calling numLevels() on image " + "file \"" << fileName() << "\" " + "(numLevels() is not defined for files " + "with RIPMAP level mode)."); + + return _data->numXLevels; +} + + +int +TiledInputFile::numXLevels () const +{ + return _data->numXLevels; +} + + +int +TiledInputFile::numYLevels () const +{ + return _data->numYLevels; +} + + +bool +TiledInputFile::isValidLevel (int lx, int ly) const +{ + if (lx < 0 || ly < 0) + return false; + + if (levelMode() == MIPMAP_LEVELS && lx != ly) + return false; + + if (lx >= numXLevels() || ly >= numYLevels()) + return false; + + return true; +} + + +int +TiledInputFile::levelWidth (int lx) const +{ + try + { + return levelSize (_data->minX, _data->maxX, lx, + _data->tileDesc.roundingMode); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling levelWidth() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +int +TiledInputFile::levelHeight (int ly) const +{ + try + { + return levelSize (_data->minY, _data->maxY, ly, + _data->tileDesc.roundingMode); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling levelHeight() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +int +TiledInputFile::numXTiles (int lx) const +{ + if (lx < 0 || lx >= _data->numXLevels) + { + THROW (Iex::ArgExc, "Error calling numXTiles() on image " + "file \"" << _data->is->fileName() << "\" " + "(Argument is not in valid range)."); + + } + + return _data->numXTiles[lx]; +} + + +int +TiledInputFile::numYTiles (int ly) const +{ + if (ly < 0 || ly >= _data->numYLevels) + { + THROW (Iex::ArgExc, "Error calling numYTiles() on image " + "file \"" << _data->is->fileName() << "\" " + "(Argument is not in valid range)."); + } + + return _data->numYTiles[ly]; +} + + +Box2i +TiledInputFile::dataWindowForLevel (int l) const +{ + return dataWindowForLevel (l, l); +} + + +Box2i +TiledInputFile::dataWindowForLevel (int lx, int ly) const +{ + try + { + return Imf::dataWindowForLevel (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + lx, ly); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling dataWindowForLevel() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +Box2i +TiledInputFile::dataWindowForTile (int dx, int dy, int l) const +{ + return dataWindowForTile (dx, dy, l, l); +} + + +Box2i +TiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const +{ + try + { + if (!isValidTile (dx, dy, lx, ly)) + throw Iex::ArgExc ("Arguments not in valid range."); + + return Imf::dataWindowForTile (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + dx, dy, lx, ly); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling dataWindowForTile() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +bool +TiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const +{ + return ((lx < _data->numXLevels && lx >= 0) && + (ly < _data->numYLevels && ly >= 0) && + (dx < _data->numXTiles[lx] && dx >= 0) && + (dy < _data->numYTiles[ly] && dy >= 0)); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledInputFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,381 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILED_INPUT_FILE_H +#define INCLUDED_IMF_TILED_INPUT_FILE_H + +//----------------------------------------------------------------------------- +// +// class TiledInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include "ImathBox.h" +#include +#include + +namespace Imf { + + +class TiledInputFile +{ + public: + + //-------------------------------------------------------------------- + // A constructor that opens the file with the specified name, and + // reads the file header. The constructor throws an Iex::ArgExc + // exception if the file is not tiled. + // The numThreads parameter specifies how many worker threads this + // file will try to keep busy when decompressing individual tiles. + // Destroying TiledInputFile objects constructed with this constructor + // automatically closes the corresponding files. + //-------------------------------------------------------------------- + + TiledInputFile (const char fileName[], + int numThreads = globalThreadCount ()); + + + // ---------------------------------------------------------- + // A constructor that attaches the new TiledInputFile object + // to a file that has already been opened. + // Destroying TiledInputFile objects constructed with this + // constructor does not automatically close the corresponding + // files. + // ---------------------------------------------------------- + + TiledInputFile (IStream &is, int numThreads = globalThreadCount ()); + + + //----------- + // Destructor + //----------- + + virtual ~TiledInputFile (); + + + //------------------------ + // Access to the file name + //------------------------ + + const char * fileName () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + + //----------------------------------------------------------- + // Set the current frame buffer -- copies the FrameBuffer + // object into the TiledInputFile object. + // + // The current frame buffer is the destination for the pixel + // data read from the file. The current frame buffer must be + // set at least once before readTile() is called. + // The current frame buffer can be changed after each call + // to readTile(). + //----------------------------------------------------------- + + void setFrameBuffer (const FrameBuffer &frameBuffer); + + + //----------------------------------- + // Access to the current frame buffer + //----------------------------------- + + const FrameBuffer & frameBuffer () const; + + + //------------------------------------------------------------ + // Check if the file is complete: + // + // isComplete() returns true if all pixels in the data window + // (in all levels) are present in the input file, or false if + // any pixels are missing. (Another program may still be busy + // writing the file, or file writing may have been aborted + // prematurely.) + //------------------------------------------------------------ + + bool isComplete () const; + + + //-------------------------------------------------- + // Utility functions: + //-------------------------------------------------- + + //--------------------------------------------------------- + // Multiresolution mode and tile size: + // The following functions return the xSize, ySize and mode + // fields of the file header's TileDescriptionAttribute. + //--------------------------------------------------------- + + unsigned int tileXSize () const; + unsigned int tileYSize () const; + LevelMode levelMode () const; + LevelRoundingMode levelRoundingMode () const; + + + //-------------------------------------------------------------------- + // Number of levels: + // + // numXLevels() returns the file's number of levels in x direction. + // + // if levelMode() == ONE_LEVEL: + // return value is: 1 + // + // if levelMode() == MIPMAP_LEVELS: + // return value is: rfunc (log (max (w, h)) / log (2)) + 1 + // + // if levelMode() == RIPMAP_LEVELS: + // return value is: rfunc (log (w) / log (2)) + 1 + // + // where + // w is the width of the image's data window, max.x - min.x + 1, + // y is the height of the image's data window, max.y - min.y + 1, + // and rfunc(x) is either floor(x), or ceil(x), depending on + // whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP. + // + // numYLevels() returns the file's number of levels in y direction. + // + // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS: + // return value is the same as for numXLevels() + // + // if levelMode() == RIPMAP_LEVELS: + // return value is: rfunc (log (h) / log (2)) + 1 + // + // + // numLevels() is a convenience function for use with + // MIPMAP_LEVELS files. + // + // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS: + // return value is the same as for numXLevels() + // + // if levelMode() == RIPMAP_LEVELS: + // an Iex::LogicExc exception is thrown + // + // isValidLevel(lx, ly) returns true if the file contains + // a level with level number (lx, ly), false if not. + // + //-------------------------------------------------------------------- + + int numLevels () const; + int numXLevels () const; + int numYLevels () const; + bool isValidLevel (int lx, int ly) const; + + + //---------------------------------------------------------- + // Dimensions of a level: + // + // levelWidth(lx) returns the width of a level with level + // number (lx, *), where * is any number. + // + // return value is: + // max (1, rfunc (w / pow (2, lx))) + // + // + // levelHeight(ly) returns the height of a level with level + // number (*, ly), where * is any number. + // + // return value is: + // max (1, rfunc (h / pow (2, ly))) + // + //---------------------------------------------------------- + + int levelWidth (int lx) const; + int levelHeight (int ly) const; + + + //-------------------------------------------------------------- + // Number of tiles: + // + // numXTiles(lx) returns the number of tiles in x direction + // that cover a level with level number (lx, *), where * is + // any number. + // + // return value is: + // (levelWidth(lx) + tileXSize() - 1) / tileXSize() + // + // + // numYTiles(ly) returns the number of tiles in y direction + // that cover a level with level number (*, ly), where * is + // any number. + // + // return value is: + // (levelHeight(ly) + tileXSize() - 1) / tileXSize() + // + //-------------------------------------------------------------- + + int numXTiles (int lx = 0) const; + int numYTiles (int ly = 0) const; + + + //--------------------------------------------------------------- + // Level pixel ranges: + // + // dataWindowForLevel(lx, ly) returns a 2-dimensional region of + // valid pixel coordinates for a level with level number (lx, ly) + // + // return value is a Box2i with min value: + // (dataWindow.min.x, dataWindow.min.y) + // + // and max value: + // (dataWindow.min.x + levelWidth(lx) - 1, + // dataWindow.min.y + levelHeight(ly) - 1) + // + // dataWindowForLevel(level) is a convenience function used + // for ONE_LEVEL and MIPMAP_LEVELS files. It returns + // dataWindowForLevel(level, level). + // + //--------------------------------------------------------------- + + Imath::Box2i dataWindowForLevel (int l = 0) const; + Imath::Box2i dataWindowForLevel (int lx, int ly) const; + + + //------------------------------------------------------------------- + // Tile pixel ranges: + // + // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional + // region of valid pixel coordinates for a tile with tile coordinates + // (dx,dy) and level number (lx, ly). + // + // return value is a Box2i with min value: + // (dataWindow.min.x + dx * tileXSize(), + // dataWindow.min.y + dy * tileYSize()) + // + // and max value: + // (dataWindow.min.x + (dx + 1) * tileXSize() - 1, + // dataWindow.min.y + (dy + 1) * tileYSize() - 1) + // + // dataWindowForTile(dx, dy, level) is a convenience function + // used for ONE_LEVEL and MIPMAP_LEVELS files. It returns + // dataWindowForTile(dx, dy, level, level). + // + //------------------------------------------------------------------- + + Imath::Box2i dataWindowForTile (int dx, int dy, int l = 0) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int lx, int ly) const; + + //------------------------------------------------------------ + // Read pixel data: + // + // readTile(dx, dy, lx, ly) reads the tile with tile + // coordinates (dx, dy), and level number (lx, ly), + // and stores it in the current frame buffer. + // + // dx must lie in the interval [0, numXTiles(lx)-1] + // dy must lie in the interval [0, numYTiles(ly)-1] + // + // lx must lie in the interval [0, numXLevels()-1] + // ly must lie in the inverval [0, numYLevels()-1] + // + // readTile(dx, dy, level) is a convenience function used + // for ONE_LEVEL and MIPMAP_LEVELS files. It calls + // readTile(dx, dy, level, level). + // + // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow + // reading multiple tiles at once. If multi-threading is used + // the multiple tiles are read concurrently. + // + // Pixels that are outside the pixel coordinate range for the + // tile's level, are never accessed by readTile(). + // + // Attempting to access a tile that is not present in the file + // throws an InputExc exception. + // + //------------------------------------------------------------ + + void readTile (int dx, int dy, int l = 0); + void readTile (int dx, int dy, int lx, int ly); + + void readTiles (int dx1, int dx2, int dy1, int dy2, + int lx, int ly); + + void readTiles (int dx1, int dx2, int dy1, int dy2, + int l = 0); + + + //-------------------------------------------------- + // Read a tile of raw pixel data from the file, + // without uncompressing it (this function is + // used to implement TiledOutputFile::copyPixels()). + //-------------------------------------------------- + + void rawTileData (int &dx, int &dy, + int &lx, int &ly, + const char *&pixelData, + int &pixelDataSize); + + struct Data; + + private: + + friend class InputFile; + + TiledInputFile (const TiledInputFile &); // not implemented + TiledInputFile & operator = (const TiledInputFile &); // not implemented + + TiledInputFile (const Header &header, IStream *is, int version, + int numThreads); + + void initialize (); + + bool isValidTile (int dx, int dy, + int lx, int ly) const; + + size_t bytesPerLineForTile (int dx, int dy, + int lx, int ly) const; + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,301 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Miscellaneous stuff related to tiled files +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" +#include +#include + + +namespace Imf { + +using Imath::Box2i; +using Imath::V2i; + + +int +levelSize (int min, int max, int l, LevelRoundingMode rmode) +{ + if (l < 0) + throw Iex::ArgExc ("Argument not in valid range."); + + int a = max - min + 1; + int b = (1 << l); + int size = a / b; + + if (rmode == ROUND_UP && size * b < a) + size += 1; + + return std::max (size, 1); +} + + +Box2i +dataWindowForLevel (const TileDescription &tileDesc, + int minX, int maxX, + int minY, int maxY, + int lx, int ly) +{ + V2i levelMin = V2i (minX, minY); + + V2i levelMax = levelMin + + V2i (levelSize (minX, maxX, lx, tileDesc.roundingMode) - 1, + levelSize (minY, maxY, ly, tileDesc.roundingMode) - 1); + + return Box2i(levelMin, levelMax); +} + + +Box2i +dataWindowForTile (const TileDescription &tileDesc, + int minX, int maxX, + int minY, int maxY, + int dx, int dy, + int lx, int ly) +{ + V2i tileMin = V2i (minX + dx * tileDesc.xSize, + minY + dy * tileDesc.ySize); + + V2i tileMax = tileMin + V2i (tileDesc.xSize - 1, tileDesc.ySize - 1); + + V2i levelMax = dataWindowForLevel + (tileDesc, minX, maxX, minY, maxY, lx, ly).max; + + tileMax = V2i (std::min (tileMax[0], levelMax[0]), + std::min (tileMax[1], levelMax[1])); + + return Box2i (tileMin, tileMax); +} + + +size_t +calculateBytesPerPixel (const Header &header) +{ + const ChannelList &channels = header.channels(); + + size_t bytesPerPixel = 0; + + for (ChannelList::ConstIterator c = channels.begin(); + c != channels.end(); + ++c) + { + bytesPerPixel += pixelTypeSize (c.channel().type); + } + + return bytesPerPixel; +} + + +namespace { + +int +floorLog2 (int x) +{ + // + // For x > 0, floorLog2(y) returns floor(log(x)/log(2)). + // + + int y = 0; + + while (x > 1) + { + y += 1; + x >>= 1; + } + + return y; +} + + +int +ceilLog2 (int x) +{ + // + // For x > 0, ceilLog2(y) returns ceil(log(x)/log(2)). + // + + int y = 0; + int r = 0; + + while (x > 1) + { + if (x & 1) + r = 1; + + y += 1; + x >>= 1; + } + + return y + r; +} + + +int +roundLog2 (int x, LevelRoundingMode rmode) +{ + return (rmode == ROUND_DOWN)? floorLog2 (x): ceilLog2 (x); +} + + +int +calculateNumXLevels (const TileDescription& tileDesc, + int minX, int maxX, + int minY, int maxY) +{ + int num = 0; + + switch (tileDesc.mode) + { + case ONE_LEVEL: + + num = 1; + break; + + case MIPMAP_LEVELS: + + { + int w = maxX - minX + 1; + int h = maxY - minY + 1; + num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1; + } + break; + + case RIPMAP_LEVELS: + + { + int w = maxX - minX + 1; + num = roundLog2 (w, tileDesc.roundingMode) + 1; + } + break; + + default: + + throw Iex::ArgExc ("Unknown LevelMode format."); + } + + return num; +} + + +int +calculateNumYLevels (const TileDescription& tileDesc, + int minX, int maxX, + int minY, int maxY) +{ + int num = 0; + + switch (tileDesc.mode) + { + case ONE_LEVEL: + + num = 1; + break; + + case MIPMAP_LEVELS: + + { + int w = maxX - minX + 1; + int h = maxY - minY + 1; + num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1; + } + break; + + case RIPMAP_LEVELS: + + { + int h = maxY - minY + 1; + num = roundLog2 (h, tileDesc.roundingMode) + 1; + } + break; + + default: + + throw Iex::ArgExc ("Unknown LevelMode format."); + } + + return num; +} + + +void +calculateNumTiles (int *numTiles, + int numLevels, + int min, int max, + int size, + LevelRoundingMode rmode) +{ + for (int i = 0; i < numLevels; i++) + { + numTiles[i] = (levelSize (min, max, i, rmode) + size - 1) / size; + } +} + +} // namespace + + +void +precalculateTileInfo (const TileDescription& tileDesc, + int minX, int maxX, + int minY, int maxY, + int *&numXTiles, int *&numYTiles, + int &numXLevels, int &numYLevels) +{ + numXLevels = calculateNumXLevels(tileDesc, minX, maxX, minY, maxY); + numYLevels = calculateNumYLevels(tileDesc, minX, maxX, minY, maxY); + + numXTiles = new int[numXLevels]; + numYTiles = new int[numYLevels]; + + calculateNumTiles (numXTiles, + numXLevels, + minX, maxX, + tileDesc.xSize, + tileDesc.roundingMode); + + calculateNumTiles (numYTiles, + numYLevels, + minY, maxY, + tileDesc.ySize, + tileDesc.roundingMode); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledMisc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILED_MISC_H +#define INCLUDED_IMF_TILED_MISC_H + +//----------------------------------------------------------------------------- +// +// Miscellaneous stuff related to tiled files +// +//----------------------------------------------------------------------------- + +#include "ImathBox.h" +#include +#include + +namespace Imf { + +int levelSize (int min, int max, int l, LevelRoundingMode rmode); + +Imath::Box2i dataWindowForLevel (const TileDescription &tileDesc, + int minX, int maxX, + int minY, int maxY, + int lx, int ly); + +Imath::Box2i dataWindowForTile (const TileDescription &tileDesc, + int minX, int maxX, + int minY, int maxY, + int dx, int dy, + int lx, int ly); + +size_t calculateBytesPerPixel (const Header &header); + +void precalculateTileInfo (const TileDescription& tileDesc, + int minX, int maxX, + int minY, int maxY, + int *&numXTiles, int *&numYTiles, + int &numXLevels, int &numYLevels); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1692 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class TiledOutputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ImathBox.h" +#include +#include +#include +#include +#include +#include "IlmThreadPool.h" +#include "IlmThreadSemaphore.h" +#include "IlmThreadMutex.h" +#include "Iex.h" +#include +#include +#include +#include +#include + + +namespace Imf { + +using Imath::Box2i; +using Imath::V2i; +using std::string; +using std::vector; +using std::ofstream; +using std::map; +using std::min; +using std::max; +using std::swap; +using IlmThread::Mutex; +using IlmThread::Lock; +using IlmThread::Semaphore; +using IlmThread::Task; +using IlmThread::TaskGroup; +using IlmThread::ThreadPool; + +namespace { + +struct TOutSliceInfo +{ + PixelType type; + const char * base; + size_t xStride; + size_t yStride; + bool zero; + int xTileCoords; + int yTileCoords; + + TOutSliceInfo (PixelType type = HALF, + const char *base = 0, + size_t xStride = 0, + size_t yStride = 0, + bool zero = false, + int xTileCoords = 0, + int yTileCoords = 0); +}; + + +TOutSliceInfo::TOutSliceInfo (PixelType t, + const char *b, + size_t xs, size_t ys, + bool z, + int xtc, + int ytc) +: + type (t), + base (b), + xStride (xs), + yStride (ys), + zero (z), + xTileCoords (xtc), + yTileCoords (ytc) +{ + // empty +} + + +struct TileCoord +{ + int dx; + int dy; + int lx; + int ly; + + + TileCoord (int xTile = 0, int yTile = 0, + int xLevel = 0, int yLevel = 0) + : + dx (xTile), dy (yTile), + lx (xLevel), ly (yLevel) + { + // empty + } + + + bool + operator < (const TileCoord &other) const + { + return (ly < other.ly) || + (ly == other.ly && lx < other.lx) || + ((ly == other.ly && lx == other.lx) && + ((dy < other.dy) || (dy == other.dy && dx < other.dx))); + } + + + bool + operator == (const TileCoord &other) const + { + return lx == other.lx && + ly == other.ly && + dx == other.dx && + dy == other.dy; + } +}; + + +struct BufferedTile +{ + char * pixelData; + int pixelDataSize; + + BufferedTile (const char *data, int size): + pixelData (0), + pixelDataSize(size) + { + pixelData = new char[pixelDataSize]; + memcpy (pixelData, data, pixelDataSize); + } + + ~BufferedTile() + { + delete [] pixelData; + } +}; + + +typedef map TileMap; + + +struct TileBuffer +{ + Array buffer; + const char * dataPtr; + int dataSize; + Compressor * compressor; + TileCoord tileCoord; + bool hasException; + string exception; + + TileBuffer (Compressor *comp); + ~TileBuffer (); + + inline void wait () {_sem.wait();} + inline void post () {_sem.post();} + + protected: + + Semaphore _sem; +}; + + +TileBuffer::TileBuffer (Compressor *comp): + dataPtr (0), + dataSize (0), + compressor (comp), + hasException (false), + exception (), + _sem (1) +{ + // empty +} + + +TileBuffer::~TileBuffer () +{ + delete compressor; +} + + +} // namespace + + +struct TiledOutputFile::Data: public Mutex +{ + Header header; // the image header + int version; // file format version + TileDescription tileDesc; // describes the tile layout + FrameBuffer frameBuffer; // framebuffer to write into + Int64 previewPosition; + LineOrder lineOrder; // the file's lineorder + int minX; // data window's min x coord + int maxX; // data window's max x coord + int minY; // data window's min y coord + int maxY; // data window's max x coord + + int numXLevels; // number of x levels + int numYLevels; // number of y levels + int * numXTiles; // number of x tiles at a level + int * numYTiles; // number of y tiles at a level + + TileOffsets tileOffsets; // stores offsets in file for + // each tile + + Compressor::Format format; // compressor's data format + vector slices; // info about channels in file + OStream * os; // file stream to write to + bool deleteStream; + + size_t maxBytesPerTileLine; // combined size of a tile line + // over all channels + + + vector tileBuffers; + size_t tileBufferSize; // size of a tile buffer + + Int64 tileOffsetsPosition; // position of the tile index + Int64 currentPosition; // current position in the file + + TileMap tileMap; + TileCoord nextTileToWrite; + + Data (bool del, int numThreads); + ~Data (); + + inline TileBuffer * getTileBuffer (int number); + // hash function from tile + // buffer coords into our + // vector of tile buffers + + TileCoord nextTileCoord (const TileCoord &a); +}; + + +TiledOutputFile::Data::Data (bool del, int numThreads): + numXTiles(0), + numYTiles(0), + os (0), + deleteStream (del), + tileOffsetsPosition (0) +{ + // + // We need at least one tileBuffer, but if threading is used, + // to keep n threads busy we need 2*n tileBuffers + // + + tileBuffers.resize (max (1, 2 * numThreads)); +} + + +TiledOutputFile::Data::~Data () +{ + delete [] numXTiles; + delete [] numYTiles; + + if (deleteStream) + delete os; + + // + // Delete all the tile buffers, if any still happen to exist + // + + for (TileMap::iterator i = tileMap.begin(); i != tileMap.end(); ++i) + delete i->second; + + for (size_t i = 0; i < tileBuffers.size(); i++) + delete tileBuffers[i]; +} + + +TileBuffer* +TiledOutputFile::Data::getTileBuffer (int number) +{ + return tileBuffers[number % tileBuffers.size()]; +} + + +TileCoord +TiledOutputFile::Data::nextTileCoord (const TileCoord &a) +{ + TileCoord b = a; + + if (lineOrder == INCREASING_Y) + { + b.dx++; + + if (b.dx >= numXTiles[b.lx]) + { + b.dx = 0; + b.dy++; + + if (b.dy >= numYTiles[b.ly]) + { + // + // the next tile is in the next level + // + + b.dy = 0; + + switch (tileDesc.mode) + { + case ONE_LEVEL: + case MIPMAP_LEVELS: + + b.lx++; + b.ly++; + break; + + case RIPMAP_LEVELS: + + b.lx++; + + if (b.lx >= numXLevels) + { + b.lx = 0; + b.ly++; + + #ifdef DEBUG + assert (b.ly <= numYLevels); + #endif + } + break; + } + } + } + } + else if (lineOrder == DECREASING_Y) + { + b.dx++; + + if (b.dx >= numXTiles[b.lx]) + { + b.dx = 0; + b.dy--; + + if (b.dy < 0) + { + // + // the next tile is in the next level + // + + switch (tileDesc.mode) + { + case ONE_LEVEL: + case MIPMAP_LEVELS: + + b.lx++; + b.ly++; + break; + + case RIPMAP_LEVELS: + + b.lx++; + + if (b.lx >= numXLevels) + { + b.lx = 0; + b.ly++; + + #ifdef DEBUG + assert (b.ly <= numYLevels); + #endif + } + break; + } + + if (b.ly < numYLevels) + b.dy = numYTiles[b.ly] - 1; + } + } + } + + return b; +} + + +namespace { + +void +writeTileData (TiledOutputFile::Data *ofd, + int dx, int dy, + int lx, int ly, + const char pixelData[], + int pixelDataSize) +{ + // + // Store a block of pixel data in the output file, and try + // to keep track of the current writing position the file, + // without calling tellp() (tellp() can be fairly expensive). + // + + Int64 currentPosition = ofd->currentPosition; + ofd->currentPosition = 0; + + if (currentPosition == 0) + currentPosition = ofd->os->tellp(); + + ofd->tileOffsets (dx, dy, lx, ly) = currentPosition; + + #ifdef DEBUG + assert (ofd->os->tellp() == currentPosition); + #endif + + // + // Write the tile header. + // + + Xdr::write (*ofd->os, dx); + Xdr::write (*ofd->os, dy); + Xdr::write (*ofd->os, lx); + Xdr::write (*ofd->os, ly); + Xdr::write (*ofd->os, pixelDataSize); + + ofd->os->write (pixelData, pixelDataSize); + + // + // Keep current position in the file so that we can avoid + // redundant seekg() operations (seekg() can be fairly expensive). + // + + ofd->currentPosition = currentPosition + + 5 * Xdr::size() + + pixelDataSize; +} + + + +void +bufferedTileWrite (TiledOutputFile::Data *ofd, + int dx, int dy, + int lx, int ly, + const char pixelData[], + int pixelDataSize) +{ + // + // Check if a tile with coordinates (dx,dy,lx,ly) has already been written. + // + + if (ofd->tileOffsets (dx, dy, lx, ly)) + { + THROW (Iex::ArgExc, + "Attempt to write tile " + "(" << dx << ", " << dy << ", " << lx << "," << ly << ") " + "more than once."); + } + + // + // If tiles can be written in random order, then don't buffer anything. + // + + if (ofd->lineOrder == RANDOM_Y) + { + writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize); + return; + } + + // + // If the tiles cannot be written in random order, then check if a + // tile with coordinates (dx,dy,lx,ly) has already been buffered. + // + + TileCoord currentTile = TileCoord(dx, dy, lx, ly); + + if (ofd->tileMap.find (currentTile) != ofd->tileMap.end()) + { + THROW (Iex::ArgExc, + "Attempt to write tile " + "(" << dx << ", " << dy << ", " << lx << "," << ly << ") " + "more than once."); + } + + // + // If all the tiles before this one have already been written to the file, + // then write this tile immediately and check if we have buffered tiles + // that can be written after this tile. + // + // Otherwise, buffer the tile so it can be written to file later. + // + + if (ofd->nextTileToWrite == currentTile) + { + writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize); + ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite); + + TileMap::iterator i = ofd->tileMap.find (ofd->nextTileToWrite); + + // + // Step through the tiles and write all successive buffered tiles after + // the current one. + // + + while(i != ofd->tileMap.end()) + { + // + // Write the tile, and then delete the tile's buffered data + // + + writeTileData (ofd, + i->first.dx, i->first.dy, + i->first.lx, i->first.ly, + i->second->pixelData, + i->second->pixelDataSize); + + delete i->second; + ofd->tileMap.erase (i); + + // + // Proceed to the next tile + // + + ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite); + i = ofd->tileMap.find (ofd->nextTileToWrite); + } + } + else + { + // + // Create a new BufferedTile, copy the pixelData into it, and + // insert it into the tileMap. + // + + ofd->tileMap[currentTile] = + new BufferedTile ((const char *)pixelData, pixelDataSize); + } +} + + +void +convertToXdr (TiledOutputFile::Data *ofd, + Array& tileBuffer, + int numScanLines, + int numPixelsPerScanLine) +{ + // + // Convert the contents of a TiledOutputFile's tileBuffer from the + // machine's native representation to Xdr format. This function is called + // by writeTile(), below, if the compressor wanted its input pixel data + // in the machine's native format, but then failed to compress the data + // (most compressors will expand rather than compress random input data). + // + // Note that this routine assumes that the machine's native representation + // of the pixel data has the same size as the Xdr representation. This + // makes it possible to convert the pixel data in place, without an + // intermediate temporary buffer. + // + + // + // Set these to point to the start of the tile. + // We will write to toPtr, and read from fromPtr. + // + + char *writePtr = tileBuffer; + const char *readPtr = writePtr; + + // + // Iterate over all scan lines in the tile. + // + + for (int y = 0; y < numScanLines; ++y) + { + // + // Iterate over all slices in the file. + // + + for (unsigned int i = 0; i < ofd->slices.size(); ++i) + { + const TOutSliceInfo &slice = ofd->slices[i]; + + // + // Convert the samples in place. + // + + convertInPlace (writePtr, readPtr, slice.type, + numPixelsPerScanLine); + } + } + + #ifdef DEBUG + + assert (writePtr == readPtr); + + #endif +} + + +// +// A TileBufferTask encapsulates the task of copying a tile from +// the user's framebuffer into a LineBuffer and compressing the data +// if necessary. +// + +class TileBufferTask: public Task +{ + public: + + TileBufferTask (TaskGroup *group, + TiledOutputFile::Data *ofd, + int number, + int dx, int dy, + int lx, int ly); + + virtual ~TileBufferTask (); + + virtual void execute (); + + private: + + TiledOutputFile::Data * _ofd; + TileBuffer * _tileBuffer; +}; + + +TileBufferTask::TileBufferTask + (TaskGroup *group, + TiledOutputFile::Data *ofd, + int number, + int dx, int dy, + int lx, int ly) +: + Task (group), + _ofd (ofd), + _tileBuffer (_ofd->getTileBuffer (number)) +{ + // + // Wait for the tileBuffer to become available + // + + _tileBuffer->wait (); + _tileBuffer->tileCoord = TileCoord (dx, dy, lx, ly); +} + + +TileBufferTask::~TileBufferTask () +{ + // + // Signal that the tile buffer is now free + // + + _tileBuffer->post (); +} + + +void +TileBufferTask::execute () +{ + try + { + // + // First copy the pixel data from the frame buffer + // into the tile buffer + // + // Convert one tile's worth of pixel data to + // a machine-independent representation, and store + // the result in _tileBuffer->buffer. + // + + char *writePtr = _tileBuffer->buffer; + + Box2i tileRange = Imf::dataWindowForTile (_ofd->tileDesc, + _ofd->minX, _ofd->maxX, + _ofd->minY, _ofd->maxY, + _tileBuffer->tileCoord.dx, + _tileBuffer->tileCoord.dy, + _tileBuffer->tileCoord.lx, + _tileBuffer->tileCoord.ly); + + int numScanLines = tileRange.max.y - tileRange.min.y + 1; + int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1; + + // + // Iterate over the scan lines in the tile. + // + + for (int y = tileRange.min.y; y <= tileRange.max.y; ++y) + { + // + // Iterate over all image channels. + // + + for (unsigned int i = 0; i < _ofd->slices.size(); ++i) + { + const TOutSliceInfo &slice = _ofd->slices[i]; + + // + // These offsets are used to facilitate both absolute + // and tile-relative pixel coordinates. + // + + int xOffset = slice.xTileCoords * tileRange.min.x; + int yOffset = slice.yTileCoords * tileRange.min.y; + + // + // Fill the tile buffer with pixel data. + // + + if (slice.zero) + { + // + // The frame buffer contains no data for this channel. + // Store zeroes in _data->tileBuffer. + // + + fillChannelWithZeroes (writePtr, _ofd->format, slice.type, + numPixelsPerScanLine); + } + else + { + // + // The frame buffer contains data for this channel. + // + + const char *readPtr = slice.base + + (y - yOffset) * slice.yStride + + (tileRange.min.x - xOffset) * + slice.xStride; + + const char *endPtr = readPtr + + (numPixelsPerScanLine - 1) * + slice.xStride; + + copyFromFrameBuffer (writePtr, readPtr, endPtr, + slice.xStride, _ofd->format, + slice.type); + } + } + } + + // + // Compress the contents of the tileBuffer, + // and store the compressed data in the output file. + // + + _tileBuffer->dataSize = writePtr - _tileBuffer->buffer; + _tileBuffer->dataPtr = _tileBuffer->buffer; + + if (_tileBuffer->compressor) + { + const char *compPtr; + + int compSize = _tileBuffer->compressor->compressTile + (_tileBuffer->dataPtr, + _tileBuffer->dataSize, + tileRange, compPtr); + + if (compSize < _tileBuffer->dataSize) + { + _tileBuffer->dataSize = compSize; + _tileBuffer->dataPtr = compPtr; + } + else if (_ofd->format == Compressor::NATIVE) + { + // + // The data did not shrink during compression, but + // we cannot write to the file using native format, + // so we need to convert the lineBuffer to Xdr. + // + + convertToXdr (_ofd, _tileBuffer->buffer, numScanLines, + numPixelsPerScanLine); + } + } + } + catch (std::exception &e) + { + if (!_tileBuffer->hasException) + { + _tileBuffer->exception = e.what (); + _tileBuffer->hasException = true; + } + } + catch (...) + { + if (!_tileBuffer->hasException) + { + _tileBuffer->exception = "unrecognized exception"; + _tileBuffer->hasException = true; + } + } +} + +} // namespace + + +TiledOutputFile::TiledOutputFile + (const char fileName[], + const Header &header, + int numThreads) +: + _data (new Data (true, numThreads)) +{ + try + { + header.sanityCheck (true); + _data->os = new StdOFStream (fileName); + initialize (header); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << fileName << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +TiledOutputFile::TiledOutputFile + (OStream &os, + const Header &header, + int numThreads) +: + _data (new Data (false, numThreads)) +{ + try + { + header.sanityCheck(true); + _data->os = &os; + initialize (header); + } + catch (Iex::BaseExc &e) + { + delete _data; + + REPLACE_EXC (e, "Cannot open image file " + "\"" << os.fileName() << "\". " << e); + throw; + } + catch (...) + { + delete _data; + throw; + } +} + + +void +TiledOutputFile::initialize (const Header &header) +{ + _data->header = header; + _data->lineOrder = _data->header.lineOrder(); + + // + // Check that the file is indeed tiled + // + + _data->tileDesc = _data->header.tileDescription(); + + // + // Save the dataWindow information + // + + const Box2i &dataWindow = _data->header.dataWindow(); + _data->minX = dataWindow.min.x; + _data->maxX = dataWindow.max.x; + _data->minY = dataWindow.min.y; + _data->maxY = dataWindow.max.y; + + // + // Precompute level and tile information to speed up utility functions + // + + precalculateTileInfo (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + _data->numXTiles, _data->numYTiles, + _data->numXLevels, _data->numYLevels); + + // + // Determine the first tile coordinate that we will be writing + // if the file is not RANDOM_Y. + // + + _data->nextTileToWrite = (_data->lineOrder == INCREASING_Y)? + TileCoord (0, 0, 0, 0): + TileCoord (0, _data->numYTiles[0] - 1, 0, 0); + + _data->maxBytesPerTileLine = + calculateBytesPerPixel (_data->header) * _data->tileDesc.xSize; + + _data->tileBufferSize = _data->maxBytesPerTileLine * _data->tileDesc.ySize; + + // + // Create all the TileBuffers and allocate their internal buffers + // + + for (size_t i = 0; i < _data->tileBuffers.size(); i++) + { + _data->tileBuffers[i] = new TileBuffer (newTileCompressor + (_data->header.compression(), + _data->maxBytesPerTileLine, + _data->tileDesc.ySize, + _data->header)); + + _data->tileBuffers[i]->buffer.resizeErase(_data->tileBufferSize); + } + + _data->format = defaultFormat (_data->tileBuffers[0]->compressor); + + _data->tileOffsets = TileOffsets (_data->tileDesc.mode, + _data->numXLevels, + _data->numYLevels, + _data->numXTiles, + _data->numYTiles); + + _data->previewPosition = _data->header.writeTo (*_data->os, true); + + _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->os); + _data->currentPosition = _data->os->tellp(); +} + + +TiledOutputFile::~TiledOutputFile () +{ + if (_data) + { + { + if (_data->tileOffsetsPosition > 0) + { + try + { + _data->os->seekp (_data->tileOffsetsPosition); + _data->tileOffsets.writeTo (*_data->os); + } + catch (...) + { + // + // We cannot safely throw any exceptions from here. + // This destructor may have been called because the + // stack is currently being unwound for another + // exception. + // + } + } + } + + delete _data; + } +} + + +const char * +TiledOutputFile::fileName () const +{ + return _data->os->fileName(); +} + + +const Header & +TiledOutputFile::header () const +{ + return _data->header; +} + + +void +TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer) +{ + Lock lock (*_data); + + // + // Check if the new frame buffer descriptor + // is compatible with the image file header. + // + + const ChannelList &channels = _data->header.channels(); + + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); + + if (j == frameBuffer.end()) + continue; + + if (i.channel().type != j.slice().type) + THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel " + "of output file \"" << fileName() << "\" is " + "not compatible with the frame buffer's " + "pixel type."); + + if (j.slice().xSampling != 1 || j.slice().ySampling != 1) + THROW (Iex::ArgExc, "All channels in a tiled file must have" + "sampling (1,1)."); + } + + // + // Initialize slice table for writePixels(). + // + + vector slices; + + for (ChannelList::ConstIterator i = channels.begin(); + i != channels.end(); + ++i) + { + FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); + + if (j == frameBuffer.end()) + { + // + // Channel i is not present in the frame buffer. + // In the file, channel i will contain only zeroes. + // + + slices.push_back (TOutSliceInfo (i.channel().type, + 0, // base + 0, // xStride, + 0, // yStride, + true)); // zero + } + else + { + // + // Channel i is present in the frame buffer. + // + + slices.push_back (TOutSliceInfo (j.slice().type, + j.slice().base, + j.slice().xStride, + j.slice().yStride, + false, // zero + (j.slice().xTileCoords)? 1: 0, + (j.slice().yTileCoords)? 1: 0)); + } + } + + // + // Store the new frame buffer. + // + + _data->frameBuffer = frameBuffer; + _data->slices = slices; +} + + +const FrameBuffer & +TiledOutputFile::frameBuffer () const +{ + Lock lock (*_data); + return _data->frameBuffer; +} + + +void +TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2, + int lx, int ly) +{ + try + { + Lock lock (*_data); + + if (_data->slices.size() == 0) + throw Iex::ArgExc ("No frame buffer specified " + "as pixel data source."); + + if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly)) + throw Iex::ArgExc ("Tile coordinates are invalid."); + + // + // Determine the first and last tile coordinates in both dimensions + // based on the file's lineOrder + // + + if (dx1 > dx2) + swap (dx1, dx2); + + if (dy1 > dy2) + swap (dy1, dy2); + + int dyStart = dy1; + int dyStop = dy2 + 1; + int dY = 1; + + if (_data->lineOrder == DECREASING_Y) + { + dyStart = dy2; + dyStop = dy1 - 1; + dY = -1; + } + + int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1); + int numTasks = min ((int)_data->tileBuffers.size(), numTiles); + + // + // Create a task group for all tile buffer tasks. When the + // task group goes out of scope, the destructor waits until + // all tasks are complete. + // + + { + TaskGroup taskGroup; + + // + // Add in the initial compression tasks to the thread pool + // + + int nextCompBuffer = 0; + int dxComp = dx1; + int dyComp = dyStart; + + while (nextCompBuffer < numTasks) + { + ThreadPool::addGlobalTask (new TileBufferTask (&taskGroup, + _data, + nextCompBuffer++, + dxComp, dyComp, + lx, ly)); + dxComp++; + + if (dxComp > dx2) + { + dxComp = dx1; + dyComp += dY; + } + } + + // + // Write the compressed buffers and add in more compression + // tasks until done + // + + int nextWriteBuffer = 0; + int dxWrite = dx1; + int dyWrite = dyStart; + + while (nextWriteBuffer < numTiles) + { + // + // Wait until the nextWriteBuffer is ready to be written + // + + TileBuffer* writeBuffer = + _data->getTileBuffer (nextWriteBuffer); + + writeBuffer->wait(); + + // + // Write the tilebuffer + // + + bufferedTileWrite (_data, dxWrite, dyWrite, lx, ly, + writeBuffer->dataPtr, + writeBuffer->dataSize); + + // + // Release the lock on nextWriteBuffer + // + + writeBuffer->post(); + + // + // If there are no more tileBuffers to compress, then + // only continue to write out remaining tileBuffers, + // otherwise keep adding compression tasks. + // + + if (nextCompBuffer < numTiles) + { + // + // add nextCompBuffer as a compression Task + // + + ThreadPool::addGlobalTask + (new TileBufferTask (&taskGroup, + _data, + nextCompBuffer, + dxComp, dyComp, + lx, ly)); + } + + nextWriteBuffer++; + dxWrite++; + + if (dxWrite > dx2) + { + dxWrite = dx1; + dyWrite += dY; + } + + nextCompBuffer++; + dxComp++; + + if (dxComp > dx2) + { + dxComp = dx1; + dyComp += dY; + } + } + + // + // finish all tasks + // + } + + // + // Exeption handling: + // + // TileBufferTask::execute() may have encountered exceptions, but + // those exceptions occurred in another thread, not in the thread + // that is executing this call to TiledOutputFile::writeTiles(). + // TileBufferTask::execute() has caught all exceptions and stored + // the exceptions' what() strings in the tile buffers. + // Now we check if any tile buffer contains a stored exception; if + // this is the case then we re-throw the exception in this thread. + // (It is possible that multiple tile buffers contain stored + // exceptions. We re-throw the first exception we find and + // ignore all others.) + // + + const string *exception = 0; + + for (int i = 0; i < _data->tileBuffers.size(); ++i) + { + TileBuffer *tileBuffer = _data->tileBuffers[i]; + + if (tileBuffer->hasException && !exception) + exception = &tileBuffer->exception; + + tileBuffer->hasException = false; + } + + if (exception) + throw Iex::IoExc (*exception); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Failed to write pixel data to image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +TiledOutputFile::writeTiles (int dx1, int dxMax, int dyMin, int dyMax, int l) +{ + writeTiles (dx1, dxMax, dyMin, dyMax, l, l); +} + + +void +TiledOutputFile::writeTile (int dx, int dy, int lx, int ly) +{ + writeTiles (dx, dx, dy, dy, lx, ly); +} + + +void +TiledOutputFile::writeTile (int dx, int dy, int l) +{ + writeTile(dx, dy, l, l); +} + + +void +TiledOutputFile::copyPixels (TiledInputFile &in) +{ + Lock lock (*_data); + + // + // Check if this file's and and the InputFile's + // headers are compatible. + // + + const Header &hdr = _data->header; + const Header &inHdr = in.header(); + + if (!hdr.hasTileDescription() || !inHdr.hasTileDescription()) + THROW (Iex::ArgExc, "Cannot perform a quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\". The " + "output file is tiled, but the input file is not. " + "Try using OutputFile::copyPixels() instead."); + + if (!(hdr.tileDescription() == inHdr.tileDescription())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files have different tile descriptions."); + + if (!(hdr.dataWindow() == inHdr.dataWindow())) + THROW (Iex::ArgExc, "Cannot copy pixels from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\". The " + "files have different data windows."); + + if (!(hdr.lineOrder() == inHdr.lineOrder())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files have different line orders."); + + if (!(hdr.compression() == inHdr.compression())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" failed. " + "The files use different compression methods."); + + if (!(hdr.channels() == inHdr.channels())) + THROW (Iex::ArgExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << fileName() << "\" " + "failed. The files have different channel " + "lists."); + + // + // Verify that no pixel data have been written to this file yet. + // + + if (!_data->tileOffsets.isEmpty()) + THROW (Iex::LogicExc, "Quick pixel copy from image " + "file \"" << in.fileName() << "\" to image " + "file \"" << _data->os->fileName() << "\" " + "failed. \"" << fileName() << "\" " + "already contains pixel data."); + + // + // Calculate the total number of tiles in the file + // + + int numAllTiles = 0; + + switch (levelMode ()) + { + case ONE_LEVEL: + case MIPMAP_LEVELS: + + for (size_t i_l = 0; i_l < numLevels (); ++i_l) + numAllTiles += numXTiles (i_l) * numYTiles (i_l); + + break; + + case RIPMAP_LEVELS: + + for (size_t i_ly = 0; i_ly < numYLevels (); ++i_ly) + for (size_t i_lx = 0; i_lx < numXLevels (); ++i_lx) + numAllTiles += numXTiles (i_lx) * numYTiles (i_ly); + + break; + + default: + + throw Iex::ArgExc ("Unknown LevelMode format."); + } + + for (int i = 0; i < numAllTiles; ++i) + { + const char *pixelData; + int pixelDataSize; + + int dx = _data->nextTileToWrite.dx; + int dy = _data->nextTileToWrite.dy; + int lx = _data->nextTileToWrite.lx; + int ly = _data->nextTileToWrite.ly; + + in.rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize); + writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize); + } +} + + +void +TiledOutputFile::copyPixels (InputFile &in) +{ + copyPixels (*in.tFile()); +} + + +unsigned int +TiledOutputFile::tileXSize () const +{ + return _data->tileDesc.xSize; +} + + +unsigned int +TiledOutputFile::tileYSize () const +{ + return _data->tileDesc.ySize; +} + + +LevelMode +TiledOutputFile::levelMode () const +{ + return _data->tileDesc.mode; +} + + +LevelRoundingMode +TiledOutputFile::levelRoundingMode () const +{ + return _data->tileDesc.roundingMode; +} + + +int +TiledOutputFile::numLevels () const +{ + if (levelMode() == RIPMAP_LEVELS) + THROW (Iex::LogicExc, "Error calling numLevels() on image " + "file \"" << fileName() << "\" " + "(numLevels() is not defined for RIPMAPs)."); + return _data->numXLevels; +} + + +int +TiledOutputFile::numXLevels () const +{ + return _data->numXLevels; +} + + +int +TiledOutputFile::numYLevels () const +{ + return _data->numYLevels; +} + + +bool +TiledOutputFile::isValidLevel (int lx, int ly) const +{ + if (lx < 0 || ly < 0) + return false; + + if (levelMode() == MIPMAP_LEVELS && lx != ly) + return false; + + if (lx >= numXLevels() || ly >= numYLevels()) + return false; + + return true; +} + + +int +TiledOutputFile::levelWidth (int lx) const +{ + try + { + int retVal = levelSize (_data->minX, _data->maxX, lx, + _data->tileDesc.roundingMode); + + return retVal; + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling levelWidth() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +int +TiledOutputFile::levelHeight (int ly) const +{ + try + { + return levelSize (_data->minY, _data->maxY, ly, + _data->tileDesc.roundingMode); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling levelHeight() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +int +TiledOutputFile::numXTiles (int lx) const +{ + if (lx < 0 || lx >= _data->numXLevels) + THROW (Iex::LogicExc, "Error calling numXTiles() on image " + "file \"" << _data->os->fileName() << "\" " + "(Argument is not in valid range)."); + + return _data->numXTiles[lx]; +} + + +int +TiledOutputFile::numYTiles (int ly) const +{ + if (ly < 0 || ly >= _data->numYLevels) + THROW (Iex::LogicExc, "Error calling numXTiles() on image " + "file \"" << _data->os->fileName() << "\" " + "(Argument is not in valid range)."); + + return _data->numYTiles[ly]; +} + + +Box2i +TiledOutputFile::dataWindowForLevel (int l) const +{ + return dataWindowForLevel (l, l); +} + + +Box2i +TiledOutputFile::dataWindowForLevel (int lx, int ly) const +{ + try + { + return Imf::dataWindowForLevel (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + lx, ly); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling dataWindowForLevel() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +Box2i +TiledOutputFile::dataWindowForTile (int dx, int dy, int l) const +{ + return dataWindowForTile (dx, dy, l, l); +} + + +Box2i +TiledOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const +{ + try + { + if (!isValidTile (dx, dy, lx, ly)) + throw Iex::ArgExc ("Arguments not in valid range."); + + return Imf::dataWindowForTile (_data->tileDesc, + _data->minX, _data->maxX, + _data->minY, _data->maxY, + dx, dy, + lx, ly); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Error calling dataWindowForTile() on image " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +bool +TiledOutputFile::isValidTile (int dx, int dy, int lx, int ly) const +{ + return ((lx < _data->numXLevels && lx >= 0) && + (ly < _data->numYLevels && ly >= 0) && + (dx < _data->numXTiles[lx] && dx >= 0) && + (dy < _data->numYTiles[ly] && dy >= 0)); +} + + +void +TiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[]) +{ + Lock lock (*_data); + + if (_data->previewPosition <= 0) + THROW (Iex::LogicExc, "Cannot update preview image pixels. " + "File \"" << fileName() << "\" does not " + "contain a preview image."); + + // + // Store the new pixels in the header's preview image attribute. + // + + PreviewImageAttribute &pia = + _data->header.typedAttribute ("preview"); + + PreviewImage &pi = pia.value(); + PreviewRgba *pixels = pi.pixels(); + int numPixels = pi.width() * pi.height(); + + for (int i = 0; i < numPixels; ++i) + pixels[i] = newPixels[i]; + + // + // Save the current file position, jump to the position in + // the file where the preview image starts, store the new + // preview image, and jump back to the saved file position. + // + + Int64 savedPosition = _data->os->tellp(); + + try + { + _data->os->seekp (_data->previewPosition); + pia.writeValueTo (*_data->os, _data->version); + _data->os->seekp (savedPosition); + } + catch (Iex::BaseExc &e) + { + REPLACE_EXC (e, "Cannot update preview image pixels for " + "file \"" << fileName() << "\". " << e); + throw; + } +} + + +void +TiledOutputFile::breakTile + (int dx, int dy, + int lx, int ly, + int offset, + int length, + char c) +{ + Lock lock (*_data); + + Int64 position = _data->tileOffsets (dx, dy, lx, ly); + + if (!position) + THROW (Iex::ArgExc, + "Cannot overwrite tile " + "(" << dx << ", " << dy << ", " << lx << "," << ly << "). " + "The tile has not yet been stored in " + "file \"" << fileName() << "\"."); + + _data->currentPosition = 0; + _data->os->seekp (position + offset); + + for (int i = 0; i < length; ++i) + _data->os->write (&c, 1); +} + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledOutputFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,475 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILED_OUTPUT_FILE_H +#define INCLUDED_IMF_TILED_OUTPUT_FILE_H + +//----------------------------------------------------------------------------- +// +// class TiledOutputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include "ImathBox.h" +#include +#include + +namespace Imf { + +class TiledInputFile; +class InputFile; +struct PreviewRgba; + + +class TiledOutputFile +{ + public: + + //------------------------------------------------------------------- + // A constructor that opens the file with the specified name, and + // writes the file header. The file header is also copied into the + // TiledOutputFile object, and can later be accessed via the header() + // method. + // + // Destroying TiledOutputFile constructed with this constructor + // automatically closes the corresponding files. + // + // The header must contain a TileDescriptionAttribute called "tiles". + // + // The x and y subsampling factors for all image channels must be 1; + // subsampling is not supported. + // + // Tiles can be written to the file in arbitrary order. The line + // order attribute can be used to cause the tiles to be sorted in + // the file. When the file is read later, reading the tiles in the + // same order as they are in the file tends to be significantly + // faster than reading the tiles in random order (see writeTile, + // below). + //------------------------------------------------------------------- + + TiledOutputFile (const char fileName[], + const Header &header, + int numThreads = globalThreadCount ()); + + + // ---------------------------------------------------------------- + // A constructor that attaches the new TiledOutputFile object to + // a file that has already been opened. Destroying TiledOutputFile + // objects constructed with this constructor does not automatically + // close the corresponding files. + // ---------------------------------------------------------------- + + TiledOutputFile (OStream &os, + const Header &header, + int numThreads = globalThreadCount ()); + + + //----------------------------------------------------- + // Destructor + // + // Destroying a TiledOutputFile object before all tiles + // have been written results in an incomplete file. + //----------------------------------------------------- + + virtual ~TiledOutputFile (); + + + //------------------------ + // Access to the file name + //------------------------ + + const char * fileName () const; + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + + + //------------------------------------------------------- + // Set the current frame buffer -- copies the FrameBuffer + // object into the TiledOutputFile object. + // + // The current frame buffer is the source of the pixel + // data written to the file. The current frame buffer + // must be set at least once before writeTile() is + // called. The current frame buffer can be changed + // after each call to writeTile(). + //------------------------------------------------------- + + void setFrameBuffer (const FrameBuffer &frameBuffer); + + + //----------------------------------- + // Access to the current frame buffer + //----------------------------------- + + const FrameBuffer & frameBuffer () const; + + + //------------------- + // Utility functions: + //------------------- + + //--------------------------------------------------------- + // Multiresolution mode and tile size: + // The following functions return the xSize, ySize and mode + // fields of the file header's TileDescriptionAttribute. + //--------------------------------------------------------- + + unsigned int tileXSize () const; + unsigned int tileYSize () const; + LevelMode levelMode () const; + LevelRoundingMode levelRoundingMode () const; + + + //-------------------------------------------------------------------- + // Number of levels: + // + // numXLevels() returns the file's number of levels in x direction. + // + // if levelMode() == ONE_LEVEL: + // return value is: 1 + // + // if levelMode() == MIPMAP_LEVELS: + // return value is: rfunc (log (max (w, h)) / log (2)) + 1 + // + // if levelMode() == RIPMAP_LEVELS: + // return value is: rfunc (log (w) / log (2)) + 1 + // + // where + // w is the width of the image's data window, max.x - min.x + 1, + // y is the height of the image's data window, max.y - min.y + 1, + // and rfunc(x) is either floor(x), or ceil(x), depending on + // whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP. + // + // numYLevels() returns the file's number of levels in y direction. + // + // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS: + // return value is the same as for numXLevels() + // + // if levelMode() == RIPMAP_LEVELS: + // return value is: rfunc (log (h) / log (2)) + 1 + // + // + // numLevels() is a convenience function for use with MIPMAP_LEVELS + // files. + // + // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS: + // return value is the same as for numXLevels() + // + // if levelMode() == RIPMAP_LEVELS: + // an Iex::LogicExc exception is thrown + // + // isValidLevel(lx, ly) returns true if the file contains + // a level with level number (lx, ly), false if not. + // + //-------------------------------------------------------------------- + + int numLevels () const; + int numXLevels () const; + int numYLevels () const; + bool isValidLevel (int lx, int ly) const; + + + //--------------------------------------------------------- + // Dimensions of a level: + // + // levelWidth(lx) returns the width of a level with level + // number (lx, *), where * is any number. + // + // return value is: + // max (1, rfunc (w / pow (2, lx))) + // + // + // levelHeight(ly) returns the height of a level with level + // number (*, ly), where * is any number. + // + // return value is: + // max (1, rfunc (h / pow (2, ly))) + // + //--------------------------------------------------------- + + int levelWidth (int lx) const; + int levelHeight (int ly) const; + + + //---------------------------------------------------------- + // Number of tiles: + // + // numXTiles(lx) returns the number of tiles in x direction + // that cover a level with level number (lx, *), where * is + // any number. + // + // return value is: + // (levelWidth(lx) + tileXSize() - 1) / tileXSize() + // + // + // numYTiles(ly) returns the number of tiles in y direction + // that cover a level with level number (*, ly), where * is + // any number. + // + // return value is: + // (levelHeight(ly) + tileXSize() - 1) / tileXSize() + // + //---------------------------------------------------------- + + int numXTiles (int lx = 0) const; + int numYTiles (int ly = 0) const; + + + //--------------------------------------------------------- + // Level pixel ranges: + // + // dataWindowForLevel(lx, ly) returns a 2-dimensional + // region of valid pixel coordinates for a level with + // level number (lx, ly) + // + // return value is a Box2i with min value: + // (dataWindow.min.x, dataWindow.min.y) + // + // and max value: + // (dataWindow.min.x + levelWidth(lx) - 1, + // dataWindow.min.y + levelHeight(ly) - 1) + // + // dataWindowForLevel(level) is a convenience function used + // for ONE_LEVEL and MIPMAP_LEVELS files. It returns + // dataWindowForLevel(level, level). + // + //--------------------------------------------------------- + + Imath::Box2i dataWindowForLevel (int l = 0) const; + Imath::Box2i dataWindowForLevel (int lx, int ly) const; + + + //------------------------------------------------------------------- + // Tile pixel ranges: + // + // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional + // region of valid pixel coordinates for a tile with tile coordinates + // (dx,dy) and level number (lx, ly). + // + // return value is a Box2i with min value: + // (dataWindow.min.x + dx * tileXSize(), + // dataWindow.min.y + dy * tileYSize()) + // + // and max value: + // (dataWindow.min.x + (dx + 1) * tileXSize() - 1, + // dataWindow.min.y + (dy + 1) * tileYSize() - 1) + // + // dataWindowForTile(dx, dy, level) is a convenience function + // used for ONE_LEVEL and MIPMAP_LEVELS files. It returns + // dataWindowForTile(dx, dy, level, level). + // + //------------------------------------------------------------------- + + Imath::Box2i dataWindowForTile (int dx, int dy, + int l = 0) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int lx, int ly) const; + + //------------------------------------------------------------------ + // Write pixel data: + // + // writeTile(dx, dy, lx, ly) writes the tile with tile + // coordinates (dx, dy), and level number (lx, ly) to + // the file. + // + // dx must lie in the interval [0, numXTiles(lx) - 1] + // dy must lie in the interval [0, numYTiles(ly) - 1] + // + // lx must lie in the interval [0, numXLevels() - 1] + // ly must lie in the inverval [0, numYLevels() - 1] + // + // writeTile(dx, dy, level) is a convenience function + // used for ONE_LEVEL and MIPMAP_LEVEL files. It calls + // writeTile(dx, dy, level, level). + // + // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow + // writing multiple tiles at once. If multi-threading is used + // multiple tiles are written concurrently. The tile coordinates, + // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile + // coordinates. It is valid for dx1 < dx2 or dy1 < dy2; the + // tiles are always written in the order specified by the line + // order attribute. Hence, it is not possible to specify an + // "invalid" or empty tile range. + // + // Pixels that are outside the pixel coordinate range for the tile's + // level, are never accessed by writeTile(). + // + // Each tile in the file must be written exactly once. + // + // The file's line order attribute determines the order of the tiles + // in the file: + // + // INCREASING_Y In the file, the tiles for each level are stored + // in a contiguous block. The levels are ordered + // like this: + // + // (0, 0) (1, 0) ... (nx-1, 0) + // (0, 1) (1, 1) ... (nx-1, 1) + // ... + // (0,ny-1) (1,ny-1) ... (nx-1,ny-1) + // + // where nx = numXLevels(), and ny = numYLevels(). + // In an individual level, (lx, ly), the tiles + // are stored in the following order: + // + // (0, 0) (1, 0) ... (tx-1, 0) + // (0, 1) (1, 1) ... (tx-1, 1) + // ... + // (0,ty-1) (1,ty-1) ... (tx-1,ty-1) + // + // where tx = numXTiles(lx), + // and ty = numYTiles(ly). + // + // DECREASING_Y As for INCREASING_Y, the tiles for each level + // are stored in a contiguous block. The levels + // are ordered the same way as for INCREASING_Y, + // but within an individual level, the tiles + // are stored in this order: + // + // (0,ty-1) (1,ty-1) ... (tx-1,ty-1) + // ... + // (0, 1) (1, 1) ... (tx-1, 1) + // (0, 0) (1, 0) ... (tx-1, 0) + // + // + // RANDOM_Y The order of the calls to writeTile() determines + // the order of the tiles in the file. + // + //------------------------------------------------------------------ + + void writeTile (int dx, int dy, int l = 0); + void writeTile (int dx, int dy, int lx, int ly); + + void writeTiles (int dx1, int dx2, int dy1, int dy2, + int lx, int ly); + + void writeTiles (int dx1, int dx2, int dy1, int dy2, + int l = 0); + + + //------------------------------------------------------------------ + // Shortcut to copy all pixels from a TiledInputFile into this file, + // without uncompressing and then recompressing the pixel data. + // This file's header must be compatible with the TiledInputFile's + // header: The two header's "dataWindow", "compression", + // "lineOrder", "channels", and "tiles" attributes must be the same. + //------------------------------------------------------------------ + + void copyPixels (TiledInputFile &in); + + + //------------------------------------------------------------------ + // Shortcut to copy all pixels from an InputFile into this file, + // without uncompressing and then recompressing the pixel data. + // This file's header must be compatible with the InputFile's + // header: The two header's "dataWindow", "compression", + // "lineOrder", "channels", and "tiles" attributes must be the same. + // + // To use this function, the InputFile must be tiled. + //------------------------------------------------------------------ + + void copyPixels (InputFile &in); + + + //-------------------------------------------------------------- + // Updating the preview image: + // + // updatePreviewImage() supplies a new set of pixels for the + // preview image attribute in the file's header. If the header + // does not contain a preview image, updatePreviewImage() throws + // an Iex::LogicExc. + // + // Note: updatePreviewImage() is necessary because images are + // often stored in a file incrementally, a few tiles at a time, + // while the image is being generated. Since the preview image + // is an attribute in the file's header, it gets stored in the + // file as soon as the file is opened, but we may not know what + // the preview image should look like until we have written the + // last tile of the main image. + // + //-------------------------------------------------------------- + + void updatePreviewImage (const PreviewRgba newPixels[]); + + + //------------------------------------------------------------- + // Break a tile -- for testing and debugging only: + // + // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the + // output file by writing n copies of character c, starting + // p bytes from the beginning of the tile with tile coordinates + // (dx, dy) and level number (lx, ly). + // + // Warning: Calling this function usually results in a broken + // image file. The file or parts of it may not be readable, + // or the file may contain bad data. + // + //------------------------------------------------------------- + + void breakTile (int dx, int dy, + int lx, int ly, + int offset, + int length, + char c); + struct Data; + + private: + + TiledOutputFile (const TiledOutputFile &); // not implemented + TiledOutputFile & operator = (const TiledOutputFile &); // not implemented + + void initialize (const Header &header); + + bool isValidTile (int dx, int dy, + int lx, int ly) const; + + size_t bytesPerLineForTile (int dx, int dy, + int lx, int ly) const; + + Data * _data; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1162 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class TiledRgbaOutputFile +// class TiledRgbaInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "IlmThreadMutex.h" +#include "Iex.h" + + +namespace Imf { + +using namespace std; +using namespace Imath; +using namespace RgbaYca; +using namespace IlmThread; + +namespace { + +void +insertChannels (Header &header, + RgbaChannels rgbaChannels, + const char fileName[]) +{ + ChannelList ch; + + if (rgbaChannels & (WRITE_Y | WRITE_C)) + { + if (rgbaChannels & WRITE_Y) + { + ch.insert ("Y", Channel (HALF, 1, 1)); + } + + if (rgbaChannels & WRITE_C) + { + THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" " + "for writing. Tiled image files do not " + "support subsampled chroma channels."); + } + } + else + { + if (rgbaChannels & WRITE_R) + ch.insert ("R", Channel (HALF, 1, 1)); + + if (rgbaChannels & WRITE_G) + ch.insert ("G", Channel (HALF, 1, 1)); + + if (rgbaChannels & WRITE_B) + ch.insert ("B", Channel (HALF, 1, 1)); + } + + if (rgbaChannels & WRITE_A) + ch.insert ("A", Channel (HALF, 1, 1)); + + header.channels() = ch; +} + + +RgbaChannels +rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "") +{ + int i = 0; + + if (ch.findChannel (channelNamePrefix + "R")) + i |= WRITE_R; + + if (ch.findChannel (channelNamePrefix + "G")) + i |= WRITE_G; + + if (ch.findChannel (channelNamePrefix + "B")) + i |= WRITE_B; + + if (ch.findChannel (channelNamePrefix + "A")) + i |= WRITE_A; + + if (ch.findChannel (channelNamePrefix + "Y")) + i |= WRITE_Y; + + return RgbaChannels (i); +} + + +string +prefixFromLayerName (const string &layerName, const Header &header) +{ + if (layerName.empty()) + return ""; + + if (hasMultiView (header) && multiView(header)[0] == layerName) + return ""; + + return layerName + "."; +} + + +V3f +ywFromHeader (const Header &header) +{ + Chromaticities cr; + + if (hasChromaticities (header)) + cr = chromaticities (header); + + return computeYw (cr); +} + +} // namespace + + +class TiledRgbaOutputFile::ToYa: public Mutex +{ + public: + + ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels); + + void setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride); + + void writeTile (int dx, int dy, int lx, int ly); + + private: + + TiledOutputFile & _outputFile; + bool _writeA; + unsigned int _tileXSize; + unsigned int _tileYSize; + V3f _yw; + Array2D _buf; + const Rgba * _fbBase; + size_t _fbXStride; + size_t _fbYStride; +}; + + +TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile, + RgbaChannels rgbaChannels) +: + _outputFile (outputFile) +{ + _writeA = (rgbaChannels & WRITE_A)? true: false; + + const TileDescription &td = outputFile.header().tileDescription(); + + _tileXSize = td.xSize; + _tileYSize = td.ySize; + _yw = ywFromHeader (_outputFile.header()); + _buf.resizeErase (_tileYSize, _tileXSize); + _fbBase = 0; + _fbXStride = 0; + _fbYStride = 0; +} + + +void +TiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride) +{ + _fbBase = base; + _fbXStride = xStride; + _fbYStride = yStride; +} + + +void +TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly) +{ + if (_fbBase == 0) + { + THROW (Iex::ArgExc, "No frame buffer was specified as the " + "pixel data source for image file " + "\"" << _outputFile.fileName() << "\"."); + } + + // + // Copy the tile's RGBA pixels into _buf and convert + // them to luminance/alpha format + // + + Box2i dw = _outputFile.dataWindowForTile (dx, dy, lx, ly); + int width = dw.max.x - dw.min.x + 1; + + for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1) + { + for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) + _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride]; + + RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]); + } + + // + // Store the contents of _buf in the output file + // + + FrameBuffer fb; + + fb.insert ("Y", Slice (HALF, // type + (char *) &_buf[-dw.min.y][-dw.min.x].g, // base + sizeof (Rgba), // xStride + sizeof (Rgba) * _tileXSize)); // yStride + + fb.insert ("A", Slice (HALF, // type + (char *) &_buf[-dw.min.y][-dw.min.x].a, // base + sizeof (Rgba), // xStride + sizeof (Rgba) * _tileXSize)); // yStride + + _outputFile.setFrameBuffer (fb); + _outputFile.writeTile (dx, dy, lx, ly); +} + + +TiledRgbaOutputFile::TiledRgbaOutputFile + (const char name[], + const Header &header, + RgbaChannels rgbaChannels, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode, + int numThreads) +: + _outputFile (0), + _toYa (0) +{ + Header hd (header); + insertChannels (hd, rgbaChannels, name); + hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); + _outputFile = new TiledOutputFile (name, hd, numThreads); + + if (rgbaChannels & WRITE_Y) + _toYa = new ToYa (*_outputFile, rgbaChannels); +} + + + +TiledRgbaOutputFile::TiledRgbaOutputFile + (OStream &os, + const Header &header, + RgbaChannels rgbaChannels, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode, + int numThreads) +: + _outputFile (0), + _toYa (0) +{ + Header hd (header); + insertChannels (hd, rgbaChannels, os.fileName()); + hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); + _outputFile = new TiledOutputFile (os, hd, numThreads); + + if (rgbaChannels & WRITE_Y) + _toYa = new ToYa (*_outputFile, rgbaChannels); +} + + + +TiledRgbaOutputFile::TiledRgbaOutputFile + (const char name[], + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode, + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads) +: + _outputFile (0), + _toYa (0) +{ + Header hd (displayWindow, + dataWindow.isEmpty()? displayWindow: dataWindow, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + insertChannels (hd, rgbaChannels, name); + hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); + _outputFile = new TiledOutputFile (name, hd, numThreads); + + if (rgbaChannels & WRITE_Y) + _toYa = new ToYa (*_outputFile, rgbaChannels); +} + + +TiledRgbaOutputFile::TiledRgbaOutputFile + (const char name[], + int width, + int height, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode, + RgbaChannels rgbaChannels, + float pixelAspectRatio, + const Imath::V2f screenWindowCenter, + float screenWindowWidth, + LineOrder lineOrder, + Compression compression, + int numThreads) +: + _outputFile (0), + _toYa (0) +{ + Header hd (width, + height, + pixelAspectRatio, + screenWindowCenter, + screenWindowWidth, + lineOrder, + compression); + + insertChannels (hd, rgbaChannels, name); + hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); + _outputFile = new TiledOutputFile (name, hd, numThreads); + + if (rgbaChannels & WRITE_Y) + _toYa = new ToYa (*_outputFile, rgbaChannels); +} + + +TiledRgbaOutputFile::~TiledRgbaOutputFile () +{ + delete _outputFile; + delete _toYa; +} + + +void +TiledRgbaOutputFile::setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride) +{ + if (_toYa) + { + Lock lock (*_toYa); + _toYa->setFrameBuffer (base, xStride, yStride); + } + else + { + size_t xs = xStride * sizeof (Rgba); + size_t ys = yStride * sizeof (Rgba); + + FrameBuffer fb; + + fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys)); + fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys)); + fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys)); + fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys)); + + _outputFile->setFrameBuffer (fb); + } +} + + +const Header & +TiledRgbaOutputFile::header () const +{ + return _outputFile->header(); +} + + +const FrameBuffer & +TiledRgbaOutputFile::frameBuffer () const +{ + return _outputFile->frameBuffer(); +} + + +const Imath::Box2i & +TiledRgbaOutputFile::displayWindow () const +{ + return _outputFile->header().displayWindow(); +} + + +const Imath::Box2i & +TiledRgbaOutputFile::dataWindow () const +{ + return _outputFile->header().dataWindow(); +} + + +float +TiledRgbaOutputFile::pixelAspectRatio () const +{ + return _outputFile->header().pixelAspectRatio(); +} + + +const Imath::V2f +TiledRgbaOutputFile::screenWindowCenter () const +{ + return _outputFile->header().screenWindowCenter(); +} + + +float +TiledRgbaOutputFile::screenWindowWidth () const +{ + return _outputFile->header().screenWindowWidth(); +} + + +LineOrder +TiledRgbaOutputFile::lineOrder () const +{ + return _outputFile->header().lineOrder(); +} + + +Compression +TiledRgbaOutputFile::compression () const +{ + return _outputFile->header().compression(); +} + + +RgbaChannels +TiledRgbaOutputFile::channels () const +{ + return rgbaChannels (_outputFile->header().channels()); +} + + +unsigned int +TiledRgbaOutputFile::tileXSize () const +{ + return _outputFile->tileXSize(); +} + + +unsigned int +TiledRgbaOutputFile::tileYSize () const +{ + return _outputFile->tileYSize(); +} + + +LevelMode +TiledRgbaOutputFile::levelMode () const +{ + return _outputFile->levelMode(); +} + + +LevelRoundingMode +TiledRgbaOutputFile::levelRoundingMode () const +{ + return _outputFile->levelRoundingMode(); +} + + +int +TiledRgbaOutputFile::numLevels () const +{ + return _outputFile->numLevels(); +} + + +int +TiledRgbaOutputFile::numXLevels () const +{ + return _outputFile->numXLevels(); +} + + +int +TiledRgbaOutputFile::numYLevels () const +{ + return _outputFile->numYLevels(); +} + + +bool +TiledRgbaOutputFile::isValidLevel (int lx, int ly) const +{ + return _outputFile->isValidLevel (lx, ly); +} + + +int +TiledRgbaOutputFile::levelWidth (int lx) const +{ + return _outputFile->levelWidth (lx); +} + + +int +TiledRgbaOutputFile::levelHeight (int ly) const +{ + return _outputFile->levelHeight (ly); +} + + +int +TiledRgbaOutputFile::numXTiles (int lx) const +{ + return _outputFile->numXTiles (lx); +} + + +int +TiledRgbaOutputFile::numYTiles (int ly) const +{ + return _outputFile->numYTiles (ly); +} + + +Imath::Box2i +TiledRgbaOutputFile::dataWindowForLevel (int l) const +{ + return _outputFile->dataWindowForLevel (l); +} + + +Imath::Box2i +TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const +{ + return _outputFile->dataWindowForLevel (lx, ly); +} + + +Imath::Box2i +TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const +{ + return _outputFile->dataWindowForTile (dx, dy, l); +} + + +Imath::Box2i +TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const +{ + return _outputFile->dataWindowForTile (dx, dy, lx, ly); +} + + +void +TiledRgbaOutputFile::writeTile (int dx, int dy, int l) +{ + if (_toYa) + { + Lock lock (*_toYa); + _toYa->writeTile (dx, dy, l, l); + } + else + { + _outputFile->writeTile (dx, dy, l); + } +} + + +void +TiledRgbaOutputFile::writeTile (int dx, int dy, int lx, int ly) +{ + if (_toYa) + { + Lock lock (*_toYa); + _toYa->writeTile (dx, dy, lx, ly); + } + else + { + _outputFile->writeTile (dx, dy, lx, ly); + } +} + + +void +TiledRgbaOutputFile::writeTiles + (int dxMin, int dxMax, int dyMin, int dyMax, int lx, int ly) +{ + if (_toYa) + { + Lock lock (*_toYa); + + for (int dy = dyMin; dy <= dyMax; dy++) + for (int dx = dxMin; dx <= dxMax; dx++) + _toYa->writeTile (dx, dy, lx, ly); + } + else + { + _outputFile->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); + } +} + +void +TiledRgbaOutputFile::writeTiles + (int dxMin, int dxMax, int dyMin, int dyMax, int l) +{ + writeTiles (dxMin, dxMax, dyMin, dyMax, l, l); +} + + +class TiledRgbaInputFile::FromYa: public Mutex +{ + public: + + FromYa (TiledInputFile &inputFile); + + void setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride, + const string &channelNamePrefix); + + void readTile (int dx, int dy, int lx, int ly); + + private: + + TiledInputFile & _inputFile; + unsigned int _tileXSize; + unsigned int _tileYSize; + V3f _yw; + Array2D _buf; + Rgba * _fbBase; + size_t _fbXStride; + size_t _fbYStride; +}; + + +TiledRgbaInputFile::FromYa::FromYa (TiledInputFile &inputFile) +: + _inputFile (inputFile) +{ + const TileDescription &td = inputFile.header().tileDescription(); + + _tileXSize = td.xSize; + _tileYSize = td.ySize; + _yw = ywFromHeader (_inputFile.header()); + _buf.resizeErase (_tileYSize, _tileXSize); + _fbBase = 0; + _fbXStride = 0; + _fbYStride = 0; +} + + +void +TiledRgbaInputFile::FromYa::setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride, + const string &channelNamePrefix) +{ + if (_fbBase == 0) +{ + FrameBuffer fb; + + fb.insert (channelNamePrefix + "Y", + Slice (HALF, // type + (char *) &_buf[0][0].g, // base + sizeof (Rgba), // xStride + sizeof (Rgba) * _tileXSize, // yStride + 1, 1, // sampling + 0.0, // fillValue + true, true)); // tileCoordinates + + fb.insert (channelNamePrefix + "A", + Slice (HALF, // type + (char *) &_buf[0][0].a, // base + sizeof (Rgba), // xStride + sizeof (Rgba) * _tileXSize, // yStride + 1, 1, // sampling + 1.0, // fillValue + true, true)); // tileCoordinates + + _inputFile.setFrameBuffer (fb); + } + + _fbBase = base; + _fbXStride = xStride; + _fbYStride = yStride; +} + + +void +TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly) +{ + if (_fbBase == 0) + { + THROW (Iex::ArgExc, "No frame buffer was specified as the " + "pixel data destination for image file " + "\"" << _inputFile.fileName() << "\"."); + } + + // + // Read the tile requested by the caller into _buf. + // + + _inputFile.readTile (dx, dy, lx, ly); + + // + // Convert the luminance/alpha pixels to RGBA + // and copy them into the caller's frame buffer. + // + + Box2i dw = _inputFile.dataWindowForTile (dx, dy, lx, ly); + int width = dw.max.x - dw.min.x + 1; + + for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1) + { + for (int x1 = 0; x1 < width; ++x1) + { + _buf[y1][x1].r = 0; + _buf[y1][x1].b = 0; + } + + YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]); + + for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) + { + _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1]; + } + } +} + + +TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads): + _inputFile (new TiledInputFile (name, numThreads)), + _fromYa (0), + _channelNamePrefix ("") +{ + if (channels() & WRITE_Y) + _fromYa = new FromYa (*_inputFile); +} + + +TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads): + _inputFile (new TiledInputFile (is, numThreads)), + _fromYa (0), + _channelNamePrefix ("") +{ + if (channels() & WRITE_Y) + _fromYa = new FromYa (*_inputFile); +} + + +TiledRgbaInputFile::TiledRgbaInputFile (const char name[], + const string &layerName, + int numThreads) +: + _inputFile (new TiledInputFile (name, numThreads)), + _fromYa (0), + _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header())) +{ + if (channels() & WRITE_Y) + _fromYa = new FromYa (*_inputFile); +} + + +TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, + const string &layerName, + int numThreads) +: + _inputFile (new TiledInputFile (is, numThreads)), + _fromYa (0), + _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header())) +{ + if (channels() & WRITE_Y) + _fromYa = new FromYa (*_inputFile); +} + + +TiledRgbaInputFile::~TiledRgbaInputFile () +{ + delete _inputFile; + delete _fromYa; +} + + +void +TiledRgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride) +{ + if (_fromYa) + { + Lock lock (*_fromYa); + _fromYa->setFrameBuffer (base, xStride, yStride, _channelNamePrefix); + } + else + { + size_t xs = xStride * sizeof (Rgba); + size_t ys = yStride * sizeof (Rgba); + + FrameBuffer fb; + + fb.insert (_channelNamePrefix + "R", + Slice (HALF, + (char *) &base[0].r, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "G", + Slice (HALF, + (char *) &base[0].g, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "B", + Slice (HALF, + (char *) &base[0].b, + xs, ys, + 1, 1, // xSampling, ySampling + 0.0)); // fillValue + + fb.insert (_channelNamePrefix + "A", + Slice (HALF, + (char *) &base[0].a, + xs, ys, + 1, 1, // xSampling, ySampling + 1.0)); // fillValue + + _inputFile->setFrameBuffer (fb); + } +} + + +void +TiledRgbaInputFile::setLayerName (const std::string &layerName) +{ + delete _fromYa; + _fromYa = 0; + + _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header()); + + if (channels() & WRITE_Y) + _fromYa = new FromYa (*_inputFile); + + FrameBuffer fb; + _inputFile->setFrameBuffer (fb); +} + + +const Header & +TiledRgbaInputFile::header () const +{ + return _inputFile->header(); +} + + +const char * +TiledRgbaInputFile::fileName () const +{ + return _inputFile->fileName(); +} + + +const FrameBuffer & +TiledRgbaInputFile::frameBuffer () const +{ + return _inputFile->frameBuffer(); +} + + +const Imath::Box2i & +TiledRgbaInputFile::displayWindow () const +{ + return _inputFile->header().displayWindow(); +} + + +const Imath::Box2i & +TiledRgbaInputFile::dataWindow () const +{ + return _inputFile->header().dataWindow(); +} + + +float +TiledRgbaInputFile::pixelAspectRatio () const +{ + return _inputFile->header().pixelAspectRatio(); +} + + +const Imath::V2f +TiledRgbaInputFile::screenWindowCenter () const +{ + return _inputFile->header().screenWindowCenter(); +} + + +float +TiledRgbaInputFile::screenWindowWidth () const +{ + return _inputFile->header().screenWindowWidth(); +} + + +LineOrder +TiledRgbaInputFile::lineOrder () const +{ + return _inputFile->header().lineOrder(); +} + + +Compression +TiledRgbaInputFile::compression () const +{ + return _inputFile->header().compression(); +} + + +RgbaChannels +TiledRgbaInputFile::channels () const +{ + return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix); +} + + +int +TiledRgbaInputFile::version () const +{ + return _inputFile->version(); +} + + +bool +TiledRgbaInputFile::isComplete () const +{ + return _inputFile->isComplete(); +} + + +unsigned int +TiledRgbaInputFile::tileXSize () const +{ + return _inputFile->tileXSize(); +} + + +unsigned int +TiledRgbaInputFile::tileYSize () const +{ + return _inputFile->tileYSize(); +} + + +LevelMode +TiledRgbaInputFile::levelMode () const +{ + return _inputFile->levelMode(); +} + + +LevelRoundingMode +TiledRgbaInputFile::levelRoundingMode () const +{ + return _inputFile->levelRoundingMode(); +} + + +int +TiledRgbaInputFile::numLevels () const +{ + return _inputFile->numLevels(); +} + + +int +TiledRgbaInputFile::numXLevels () const +{ + return _inputFile->numXLevels(); +} + + +int +TiledRgbaInputFile::numYLevels () const +{ + return _inputFile->numYLevels(); +} + + +bool +TiledRgbaInputFile::isValidLevel (int lx, int ly) const +{ + return _inputFile->isValidLevel (lx, ly); +} + + +int +TiledRgbaInputFile::levelWidth (int lx) const +{ + return _inputFile->levelWidth (lx); +} + + +int +TiledRgbaInputFile::levelHeight (int ly) const +{ + return _inputFile->levelHeight (ly); +} + + +int +TiledRgbaInputFile::numXTiles (int lx) const +{ + return _inputFile->numXTiles(lx); +} + + +int +TiledRgbaInputFile::numYTiles (int ly) const +{ + return _inputFile->numYTiles(ly); +} + + +Imath::Box2i +TiledRgbaInputFile::dataWindowForLevel (int l) const +{ + return _inputFile->dataWindowForLevel (l); +} + + +Imath::Box2i +TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const +{ + return _inputFile->dataWindowForLevel (lx, ly); +} + + +Imath::Box2i +TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const +{ + return _inputFile->dataWindowForTile (dx, dy, l); +} + + +Imath::Box2i +TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const +{ + return _inputFile->dataWindowForTile (dx, dy, lx, ly); +} + + +void +TiledRgbaInputFile::readTile (int dx, int dy, int l) +{ + if (_fromYa) + { + Lock lock (*_fromYa); + _fromYa->readTile (dx, dy, l, l); + } + else + { + _inputFile->readTile (dx, dy, l); + } +} + + +void +TiledRgbaInputFile::readTile (int dx, int dy, int lx, int ly) +{ + if (_fromYa) + { + Lock lock (*_fromYa); + _fromYa->readTile (dx, dy, lx, ly); + } + else + { + _inputFile->readTile (dx, dy, lx, ly); + } +} + + +void +TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax, + int lx, int ly) +{ + if (_fromYa) + { + Lock lock (*_fromYa); + + for (int dy = dyMin; dy <= dyMax; dy++) + for (int dx = dxMin; dx <= dxMax; dx++) + _fromYa->readTile (dx, dy, lx, ly); + } + else + { + _inputFile->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); + } +} + +void +TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax, + int l) +{ + readTiles (dxMin, dxMax, dyMin, dyMax, l, l); +} + + +void +TiledRgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[]) +{ + _outputFile->updatePreviewImage (newPixels); +} + + +void +TiledRgbaOutputFile::breakTile (int dx, int dy, int lx, int ly, + int offset, int length, char c) +{ + _outputFile->breakTile (dx, dy, lx, ly, offset, length, c); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,479 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TILED_RGBA_FILE_H +#define INCLUDED_IMF_TILED_RGBA_FILE_H + +//----------------------------------------------------------------------------- +// +// Simplified RGBA image I/O for tiled files +// +// class TiledRgbaOutputFile +// class TiledRgbaInputFile +// +//----------------------------------------------------------------------------- + +#include +#include +#include "ImathVec.h" +#include "ImathBox.h" +#include "half.h" +#include +#include +#include +#include + +namespace Imf { + +class TiledOutputFile; +class TiledInputFile; +struct PreviewRgba; + + +// +// Tiled RGBA output file. +// + +class TiledRgbaOutputFile +{ + public: + + //--------------------------------------------------- + // Constructor -- rgbaChannels, tileXSize, tileYSize, + // levelMode, and levelRoundingMode overwrite the + // channel list and tile description attribute in the + // header that is passed as an argument to the + // constructor. + //--------------------------------------------------- + + TiledRgbaOutputFile (const char name[], + const Header &header, + RgbaChannels rgbaChannels, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode = ROUND_DOWN, + int numThreads = globalThreadCount ()); + + + //--------------------------------------------------- + // Constructor -- like the previous one, but the new + // TiledRgbaOutputFile is attached to a file that has + // already been opened by the caller. Destroying + // TiledRgbaOutputFileObjects constructed with this + // constructor does not automatically close the + // corresponding files. + //--------------------------------------------------- + + TiledRgbaOutputFile (OStream &os, + const Header &header, + RgbaChannels rgbaChannels, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode = ROUND_DOWN, + int numThreads = globalThreadCount ()); + + + //------------------------------------------------------ + // Constructor -- header data are explicitly specified + // as function call arguments (an empty dataWindow means + // "same as displayWindow") + //------------------------------------------------------ + + TiledRgbaOutputFile (const char name[], + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode, + const Imath::Box2i &displayWindow, + const Imath::Box2i &dataWindow = Imath::Box2i(), + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = + Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = ZIP_COMPRESSION, + int numThreads = globalThreadCount ()); + + + //----------------------------------------------- + // Constructor -- like the previous one, but both + // the display window and the data window are + // Box2i (V2i (0, 0), V2i (width - 1, height -1)) + //----------------------------------------------- + + TiledRgbaOutputFile (const char name[], + int width, + int height, + int tileXSize, + int tileYSize, + LevelMode mode, + LevelRoundingMode rmode = ROUND_DOWN, + RgbaChannels rgbaChannels = WRITE_RGBA, + float pixelAspectRatio = 1, + const Imath::V2f screenWindowCenter = + Imath::V2f (0, 0), + float screenWindowWidth = 1, + LineOrder lineOrder = INCREASING_Y, + Compression compression = ZIP_COMPRESSION, + int numThreads = globalThreadCount ()); + + + virtual ~TiledRgbaOutputFile (); + + + //------------------------------------------------ + // Define a frame buffer as the pixel data source: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //------------------------------------------------ + + void setFrameBuffer (const Rgba *base, + size_t xStride, + size_t yStride); + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const FrameBuffer & frameBuffer () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + + + //---------------------------------------------------- + // Utility functions (same as in Imf::TiledOutputFile) + //---------------------------------------------------- + + unsigned int tileXSize () const; + unsigned int tileYSize () const; + LevelMode levelMode () const; + LevelRoundingMode levelRoundingMode () const; + + int numLevels () const; + int numXLevels () const; + int numYLevels () const; + bool isValidLevel (int lx, int ly) const; + + int levelWidth (int lx) const; + int levelHeight (int ly) const; + + int numXTiles (int lx = 0) const; + int numYTiles (int ly = 0) const; + + Imath::Box2i dataWindowForLevel (int l = 0) const; + Imath::Box2i dataWindowForLevel (int lx, int ly) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int l = 0) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int lx, int ly) const; + + //------------------------------------------------------------------ + // Write pixel data: + // + // writeTile(dx, dy, lx, ly) writes the tile with tile + // coordinates (dx, dy), and level number (lx, ly) to + // the file. + // + // dx must lie in the interval [0, numXTiles(lx)-1] + // dy must lie in the interval [0, numYTiles(ly)-1] + // + // lx must lie in the interval [0, numXLevels()-1] + // ly must lie in the inverval [0, numYLevels()-1] + // + // writeTile(dx, dy, level) is a convenience function + // used for ONE_LEVEL and MIPMAP_LEVEL files. It calls + // writeTile(dx, dy, level, level). + // + // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow + // writing multiple tiles at once. If multi-threading is used + // multiple tiles are written concurrently. + // + // Pixels that are outside the pixel coordinate range for the tile's + // level, are never accessed by writeTile(). + // + // Each tile in the file must be written exactly once. + // + //------------------------------------------------------------------ + + void writeTile (int dx, int dy, int l = 0); + void writeTile (int dx, int dy, int lx, int ly); + + void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, + int lx, int ly); + + void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, + int l = 0); + + + // ------------------------------------------------------------------------- + // Update the preview image (see Imf::TiledOutputFile::updatePreviewImage()) + // ------------------------------------------------------------------------- + + void updatePreviewImage (const PreviewRgba[]); + + + //------------------------------------------------ + // Break a tile -- for testing and debugging only + // (see Imf::TiledOutputFile::breakTile()) + // + // Warning: Calling this function usually results + // in a broken image file. The file or parts of + // it may not be readable, or the file may contain + // bad data. + // + //------------------------------------------------ + + void breakTile (int dx, int dy, + int lx, int ly, + int offset, + int length, + char c); + private: + + // + // Copy constructor and assignment are not implemented + // + + TiledRgbaOutputFile (const TiledRgbaOutputFile &); + TiledRgbaOutputFile & operator = (const TiledRgbaOutputFile &); + + class ToYa; + + TiledOutputFile * _outputFile; + ToYa * _toYa; +}; + + + +// +// Tiled RGBA input file +// + +class TiledRgbaInputFile +{ + public: + + //-------------------------------------------------------- + // Constructor -- opens the file with the specified name. + // Destroying TiledRgbaInputFile objects constructed with + // this constructor automatically closes the corresponding + // files. + //-------------------------------------------------------- + + TiledRgbaInputFile (const char name[], + int numThreads = globalThreadCount ()); + + + //------------------------------------------------------- + // Constructor -- attaches the new TiledRgbaInputFile + // object to a file that has already been opened by the + // caller. + // Destroying TiledRgbaInputFile objects constructed with + // this constructor does not automatically close the + // corresponding files. + //------------------------------------------------------- + + TiledRgbaInputFile (IStream &is, int numThreads = globalThreadCount ()); + + + //------------------------------------------------------------ + // Constructors -- the same as the previous two, but the names + // of the red, green, blue, alpha, and luminance channels are + // expected to be layerName.R, layerName.G, etc. + //------------------------------------------------------------ + + TiledRgbaInputFile (const char name[], + const std::string &layerName, + int numThreads = globalThreadCount()); + + TiledRgbaInputFile (IStream &is, + const std::string &layerName, + int numThreads = globalThreadCount()); + + //----------- + // Destructor + //----------- + + virtual ~TiledRgbaInputFile (); + + + //----------------------------------------------------- + // Define a frame buffer as the pixel data destination: + // Pixel (x, y) is at address + // + // base + x * xStride + y * yStride + // + //----------------------------------------------------- + + void setFrameBuffer (Rgba *base, + size_t xStride, + size_t yStride); + + //------------------------------------------------------------------- + // Switch to a different layer -- subsequent calls to readTile() + // and readTiles() will read channels layerName.R, layerName.G, etc. + // After each call to setLayerName(), setFrameBuffer() must be called + // at least once before the next call to readTile() or readTiles(). + //------------------------------------------------------------------- + + void setLayerName (const std::string &layerName); + + + //-------------------------- + // Access to the file header + //-------------------------- + + const Header & header () const; + const FrameBuffer & frameBuffer () const; + const Imath::Box2i & displayWindow () const; + const Imath::Box2i & dataWindow () const; + float pixelAspectRatio () const; + const Imath::V2f screenWindowCenter () const; + float screenWindowWidth () const; + LineOrder lineOrder () const; + Compression compression () const; + RgbaChannels channels () const; + const char * fileName () const; + bool isComplete () const; + + //---------------------------------- + // Access to the file format version + //---------------------------------- + + int version () const; + + + //--------------------------------------------------- + // Utility functions (same as in Imf::TiledInputFile) + //--------------------------------------------------- + + unsigned int tileXSize () const; + unsigned int tileYSize () const; + LevelMode levelMode () const; + LevelRoundingMode levelRoundingMode () const; + + int numLevels () const; + int numXLevels () const; + int numYLevels () const; + bool isValidLevel (int lx, int ly) const; + + int levelWidth (int lx) const; + int levelHeight (int ly) const; + + int numXTiles (int lx = 0) const; + int numYTiles (int ly = 0) const; + + Imath::Box2i dataWindowForLevel (int l = 0) const; + Imath::Box2i dataWindowForLevel (int lx, int ly) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int l = 0) const; + + Imath::Box2i dataWindowForTile (int dx, int dy, + int lx, int ly) const; + + + //---------------------------------------------------------------- + // Read pixel data: + // + // readTile(dx, dy, lx, ly) reads the tile with tile + // coordinates (dx, dy), and level number (lx, ly), + // and stores it in the current frame buffer. + // + // dx must lie in the interval [0, numXTiles(lx)-1] + // dy must lie in the interval [0, numYTiles(ly)-1] + // + // lx must lie in the interval [0, numXLevels()-1] + // ly must lie in the inverval [0, numYLevels()-1] + // + // readTile(dx, dy, level) is a convenience function used + // for ONE_LEVEL and MIPMAP_LEVELS files. It calls + // readTile(dx, dy, level, level). + // + // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow + // reading multiple tiles at once. If multi-threading is used + // multiple tiles are read concurrently. + // + // Pixels that are outside the pixel coordinate range for the + // tile's level, are never accessed by readTile(). + // + // Attempting to access a tile that is not present in the file + // throws an InputExc exception. + // + //---------------------------------------------------------------- + + void readTile (int dx, int dy, int l = 0); + void readTile (int dx, int dy, int lx, int ly); + + void readTiles (int dxMin, int dxMax, + int dyMin, int dyMax, int lx, int ly); + + void readTiles (int dxMin, int dxMax, + int dyMin, int dyMax, int l = 0); + + private: + + // + // Copy constructor and assignment are not implemented + // + + TiledRgbaInputFile (const TiledRgbaInputFile &); + TiledRgbaInputFile & operator = (const TiledRgbaInputFile &); + + class FromYa; + + TiledInputFile * _inputFile; + FromYa * _fromYa; + std::string _channelNamePrefix; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,415 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class TimeCode +// +//----------------------------------------------------------------------------- + +#include +#include "Iex.h" + +namespace Imf { + + +TimeCode::TimeCode () +{ + _time = 0; + _user = 0; +} + + +TimeCode::TimeCode + (int hours, + int minutes, + int seconds, + int frame, + bool dropFrame, + bool colorFrame, + bool fieldPhase, + bool bgf0, + bool bgf1, + bool bgf2, + int binaryGroup1, + int binaryGroup2, + int binaryGroup3, + int binaryGroup4, + int binaryGroup5, + int binaryGroup6, + int binaryGroup7, + int binaryGroup8) +{ + setHours (hours); + setMinutes (minutes); + setSeconds (seconds); + setFrame (frame); + setDropFrame (dropFrame); + setColorFrame (colorFrame); + setFieldPhase (fieldPhase); + setBgf0 (bgf0); + setBgf1 (bgf1); + setBgf2 (bgf2); + setBinaryGroup (1, binaryGroup1); + setBinaryGroup (2, binaryGroup2); + setBinaryGroup (3, binaryGroup3); + setBinaryGroup (4, binaryGroup4); + setBinaryGroup (5, binaryGroup5); + setBinaryGroup (6, binaryGroup6); + setBinaryGroup (7, binaryGroup7); + setBinaryGroup (8, binaryGroup8); +} + + +TimeCode::TimeCode + (unsigned int timeAndFlags, + unsigned int userData, + Packing packing) +{ + setTimeAndFlags (timeAndFlags, packing); + setUserData (userData); +} + + +TimeCode::TimeCode (const TimeCode &other) +{ + _time = other._time; + _user = other._user; +} + + +TimeCode & +TimeCode::operator = (const TimeCode &other) +{ + _time = other._time; + _user = other._user; + return *this; +} + + +namespace { + +unsigned int +bitField (unsigned int value, int minBit, int maxBit) +{ + int shift = minBit; + unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit); + return (value & mask) >> shift; +} + + +void +setBitField (unsigned int &value, int minBit, int maxBit, unsigned int field) +{ + int shift = minBit; + unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit); + value = ((value & ~mask) | ((field << shift) & mask)); +} + + +int +bcdToBinary (unsigned int bcd) +{ + return int ((bcd & 0x0f) + 10 * ((bcd >> 4) & 0x0f)); +} + + +unsigned int +binaryToBcd (int binary) +{ + int units = binary % 10; + int tens = (binary / 10) % 10; + return (unsigned int) (units | (tens << 4)); +} + + +} // namespace + + +int +TimeCode::hours () const +{ + return bcdToBinary (bitField (_time, 24, 29)); +} + + +void +TimeCode::setHours (int value) +{ + if (value < 0 || value > 23) + throw Iex::ArgExc ("Cannot set hours field in time code. " + "New value is out of range."); + + setBitField (_time, 24, 29, binaryToBcd (value)); +} + + +int +TimeCode::minutes () const +{ + return bcdToBinary (bitField (_time, 16, 22)); +} + + +void +TimeCode::setMinutes (int value) +{ + if (value < 0 || value > 59) + throw Iex::ArgExc ("Cannot set minutes field in time code. " + "New value is out of range."); + + setBitField (_time, 16, 22, binaryToBcd (value)); +} + + +int +TimeCode::seconds () const +{ + return bcdToBinary (bitField (_time, 8, 14)); +} + + +void +TimeCode::setSeconds (int value) +{ + if (value < 0 || value > 59) + throw Iex::ArgExc ("Cannot set seconds field in time code. " + "New value is out of range."); + + setBitField (_time, 8, 14, binaryToBcd (value)); +} + + +int +TimeCode::frame () const +{ + return bcdToBinary (bitField (_time, 0, 5)); +} + + +void +TimeCode::setFrame (int value) +{ + if (value < 0 || value > 59) + throw Iex::ArgExc ("Cannot set frame field in time code. " + "New value is out of range."); + + setBitField (_time, 0, 5, binaryToBcd (value)); +} + + +bool +TimeCode::dropFrame () const +{ + return bool (bitField (_time, 6, 6)); +} + + +void +TimeCode::setDropFrame (bool value) +{ + setBitField (_time, 6, 6, (unsigned int) !!value); +} + + +bool +TimeCode::colorFrame () const +{ + return bool (bitField (_time, 7, 7)); +} + + +void +TimeCode::setColorFrame (bool value) +{ + setBitField (_time, 7, 7, (unsigned int) !!value); +} + + +bool +TimeCode::fieldPhase () const +{ + return bool (bitField (_time, 15, 15)); +} + + +void +TimeCode::setFieldPhase (bool value) +{ + setBitField (_time, 15, 15, (unsigned int) !!value); +} + + +bool +TimeCode::bgf0 () const +{ + return bool (bitField (_time, 23, 23)); +} + + +void +TimeCode::setBgf0 (bool value) +{ + setBitField (_time, 23, 23, (unsigned int) !!value); +} + + +bool +TimeCode::bgf1 () const +{ + return bool (bitField (_time, 30, 30)); +} + + +void +TimeCode::setBgf1 (bool value) +{ + setBitField (_time, 30, 30, (unsigned int) !!value); +} + + +bool +TimeCode::bgf2 () const +{ + return bool (bitField (_time, 31, 31)); +} + + +void +TimeCode::setBgf2 (bool value) +{ + setBitField (_time, 31, 31, (unsigned int) !!value); +} + + +int +TimeCode::binaryGroup (int group) const +{ + if (group < 1 || group > 8) + throw Iex::ArgExc ("Cannot extract binary group from time code " + "user data. Group number is out of range."); + + int minBit = 4 * (group - 1); + int maxBit = minBit + 3; + return int (bitField (_user, minBit, maxBit)); +} + + +void +TimeCode::setBinaryGroup (int group, int value) +{ + if (group < 1 || group > 8) + throw Iex::ArgExc ("Cannot extract binary group from time code " + "user data. Group number is out of range."); + + int minBit = 4 * (group - 1); + int maxBit = minBit + 3; + setBitField (_user, minBit, maxBit, (unsigned int) value); +} + + +unsigned int +TimeCode::timeAndFlags (Packing packing) const +{ + if (packing == TV50_PACKING) + { + unsigned int t = _time; + + t &= ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31)); + + t |= ((unsigned int) bgf0() << 15); + t |= ((unsigned int) bgf2() << 23); + t |= ((unsigned int) bgf1() << 30); + t |= ((unsigned int) fieldPhase() << 31); + + return t; + } + if (packing == FILM24_PACKING) + { + return _time & ~((1 << 6) | (1 << 7)); + } + else // packing == TV60_PACKING + { + return _time; + } +} + + +void +TimeCode::setTimeAndFlags (unsigned int value, Packing packing) +{ + if (packing == TV50_PACKING) + { + _time = value & + ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31)); + + if (value & (1 << 15)) + setBgf0 (true); + + if (value & (1 << 23)) + setBgf2 (true); + + if (value & (1 << 30)) + setBgf1 (true); + + if (value & (1 << 31)) + setFieldPhase (true); + } + else if (packing == FILM24_PACKING) + { + _time = value & ~((1 << 6) | (1 << 7)); + } + else // packing == TV60_PACKING + { + _time = value; + } +} + + +unsigned int +TimeCode::userData () const +{ + return _user; +} + + +void +TimeCode::setUserData (unsigned int value) +{ + _user = value; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCode.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,226 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TIME_CODE_H +#define INCLUDED_IMF_TIME_CODE_H + +//----------------------------------------------------------------------------- +// +// class TimeCode +// +// A TimeCode object stores time and control codes as described +// in SMPTE standard 12M-1999. A TimeCode object contains the +// following fields: +// +// Time Address: +// +// hours integer, range 0 - 23 +// minutes integer, range 0 - 59 +// seconds integer, range 0 - 59 +// frame integer, range 0 - 29 +// +// Flags: +// +// drop frame flag boolean +// color frame flag boolean +// field/phase flag boolean +// bgf0 boolean +// bgf1 boolean +// bgf2 boolean +// +// Binary groups for user-defined data and control codes: +// +// binary group 1 integer, range 0 - 15 +// binary group 2 integer, range 0 - 15 +// ... +// binary group 8 integer, range 0 - 15 +// +// Class TimeCode contains methods to convert between the fields +// listed above and a more compact representation where the fields +// are packed into two unsigned 32-bit integers. In the packed +// integer representations, bit 0 is the least significant bit, +// and bit 31 is the most significant bit of the integer value. +// +// The time address and flags fields can be packed in three +// different ways: +// +// bits packing for packing for packing for +// 24-frame 60-field 50-field +// film television television +// +// 0 - 3 frame units frame units frame units +// 4 - 5 frame tens frame tens frame tens +// 6 unused, set to 0 drop frame flag unused, set to 0 +// 7 unused, set to 0 color frame flag color frame flag +// 8 - 11 seconds units seconds units seconds units +// 12 - 14 seconds tens seconds tens seconds tens +// 15 phase flag field/phase flag bgf0 +// 16 - 19 minutes units minutes units minutes units +// 20 - 22 minutes tens minutes tens minutes tens +// 23 bgf0 bgf0 bgf2 +// 24 - 27 hours units hours units hours units +// 28 - 29 hours tens hours tens hours tens +// 30 bgf1 bgf1 bgf1 +// 31 bgf2 bgf2 field/phase flag +// +// User-defined data and control codes are packed as follows: +// +// bits field +// +// 0 - 3 binary group 1 +// 4 - 7 binary group 2 +// 8 - 11 binary group 3 +// 12 - 15 binary group 4 +// 16 - 19 binary group 5 +// 20 - 23 binary group 6 +// 24 - 27 binary group 7 +// 28 - 31 binary group 8 +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +class TimeCode +{ + public: + + //--------------------- + // Bit packing variants + //--------------------- + + enum Packing + { + TV60_PACKING, // packing for 60-field television + TV50_PACKING, // packing for 50-field television + FILM24_PACKING // packing for 24-frame film + }; + + + //------------------------------------- + // Constructors and assignment operator + //------------------------------------- + + TimeCode (); // all fields set to 0 or false + + TimeCode (int hours, + int minutes, + int seconds, + int frame, + bool dropFrame = false, + bool colorFrame = false, + bool fieldPhase = false, + bool bgf0 = false, + bool bgf1 = false, + bool bgf2 = false, + int binaryGroup1 = 0, + int binaryGroup2 = 0, + int binaryGroup3 = 0, + int binaryGroup4 = 0, + int binaryGroup5 = 0, + int binaryGroup6 = 0, + int binaryGroup7 = 0, + int binaryGroup8 = 0); + + TimeCode (unsigned int timeAndFlags, + unsigned int userData = 0, + Packing packing = TV60_PACKING); + + TimeCode (const TimeCode &other); + + TimeCode & operator = (const TimeCode &other); + + + //---------------------------- + // Access to individual fields + //---------------------------- + + int hours () const; + void setHours (int value); + + int minutes () const; + void setMinutes (int value); + + int seconds () const; + void setSeconds (int value); + + int frame () const; + void setFrame (int value); + + bool dropFrame () const; + void setDropFrame (bool value); + + bool colorFrame () const; + void setColorFrame (bool value); + + bool fieldPhase () const; + void setFieldPhase (bool value); + + bool bgf0 () const; + void setBgf0 (bool value); + + bool bgf1 () const; + void setBgf1 (bool value); + + bool bgf2 () const; + void setBgf2 (bool value); + + int binaryGroup (int group) const; // group must be between 1 and 8 + void setBinaryGroup (int group, int value); + + + //--------------------------------- + // Access to packed representations + //--------------------------------- + + unsigned int timeAndFlags (Packing packing = TV60_PACKING) const; + + void setTimeAndFlags (unsigned int value, + Packing packing = TV60_PACKING); + + unsigned int userData () const; + + void setUserData (unsigned int value); + + private: + + unsigned int _time; + unsigned int _user; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// class TimeCodeAttribute +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +template <> +const char * +TimeCodeAttribute::staticTypeName () +{ + return "timecode"; +} + + +template <> +void +TimeCodeAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.timeAndFlags()); + Xdr::write (os, _value.userData()); +} + + +template <> +void +TimeCodeAttribute::readValueFrom (IStream &is, int, int) +{ + unsigned int tmp; + + Xdr::read (is, tmp); + _value.setTimeAndFlags (tmp); + + Xdr::read (is, tmp); + _value.setUserData (tmp); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,72 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_TIME_CODE_ATTRIBUTE_H +#define INCLUDED_IMF_TIME_CODE_ATTRIBUTE_H + + +//----------------------------------------------------------------------------- +// +// class TimeCodeAttribute +// +//----------------------------------------------------------------------------- + +#include +#include + + +namespace Imf { + + +typedef TypedAttribute TimeCodeAttribute; + +template <> +const char *TimeCodeAttribute::staticTypeName (); + +template <> +void TimeCodeAttribute::writeValueTo (OStream &, int) const; + +template <> +void TimeCodeAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,216 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class V2iAttribute +// class V2fAttribute +// class V2dAttribute +// class V3iAttribute +// class V3fAttribute +// class V3dAttribute +// +//----------------------------------------------------------------------------- + +#include + + +namespace Imf { + + +template <> +const char * +V2iAttribute::staticTypeName () +{ + return "v2i"; +} + + +template <> +void +V2iAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); +} + + +template <> +void +V2iAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); +} + + +template <> +const char * +V2fAttribute::staticTypeName () +{ + return "v2f"; +} + + +template <> +void +V2fAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); +} + + +template <> +void +V2fAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); +} + + +template <> +const char * +V2dAttribute::staticTypeName () +{ + return "v2d"; +} + + +template <> +void +V2dAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); +} + + +template <> +void +V2dAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); +} + + +template <> +const char * +V3iAttribute::staticTypeName () +{ + return "v3i"; +} + + +template <> +void +V3iAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); + Xdr::write (os, _value.z); +} + + +template <> +void +V3iAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); + Xdr::read (is, _value.z); +} + + +template <> +const char * +V3fAttribute::staticTypeName () +{ + return "v3f"; +} + + +template <> +void +V3fAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); + Xdr::write (os, _value.z); +} + + +template <> +void +V3fAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); + Xdr::read (is, _value.z); +} + + +template <> +const char * +V3dAttribute::staticTypeName () +{ + return "v3d"; +} + + +template <> +void +V3dAttribute::writeValueTo (OStream &os, int) const +{ + Xdr::write (os, _value.x); + Xdr::write (os, _value.y); + Xdr::write (os, _value.z); +} + + +template <> +void +V3dAttribute::readValueFrom (IStream &is, int, int) +{ + Xdr::read (is, _value.x); + Xdr::read (is, _value.y); + Xdr::read (is, _value.z); +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVecAttribute.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_VEC_ATTRIBUTE_H +#define INCLUDED_IMF_VEC_ATTRIBUTE_H + +//----------------------------------------------------------------------------- +// +// class V2iAttribute +// class V2fAttribute +// class V2dAttribute +// class V3iAttribute +// class V3fAttribute +// class V3dAttribute +// +//----------------------------------------------------------------------------- + +#include +#include "ImathVec.h" + + +namespace Imf { + + +typedef TypedAttribute V2iAttribute; +template <> const char *V2iAttribute::staticTypeName (); +template <> void V2iAttribute::writeValueTo (OStream &, int) const; +template <> void V2iAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute V2fAttribute; +template <> const char *V2fAttribute::staticTypeName (); +template <> void V2fAttribute::writeValueTo (OStream &, int) const; +template <> void V2fAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute V2dAttribute; +template <> const char *V2dAttribute::staticTypeName (); +template <> void V2dAttribute::writeValueTo (OStream &, int) const; +template <> void V2dAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute V3iAttribute; +template <> const char *V3iAttribute::staticTypeName (); +template <> void V3iAttribute::writeValueTo (OStream &, int) const; +template <> void V3iAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute V3fAttribute; +template <> const char *V3fAttribute::staticTypeName (); +template <> void V3fAttribute::writeValueTo (OStream &, int) const; +template <> void V3fAttribute::readValueFrom (IStream &, int, int); + + +typedef TypedAttribute V3dAttribute; +template <> const char *V3dAttribute::staticTypeName (); +template <> void V3dAttribute::writeValueTo (OStream &, int) const; +template <> void V3dAttribute::readValueFrom (IStream &, int, int); + + +} // namespace Imf + +// Metrowerks compiler wants the .cpp file inlined, too +#ifdef __MWERKS__ +#include +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,59 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//----------------------------------------------------------------------------- +// +// Magic and version number. +// +//----------------------------------------------------------------------------- + + +#include + +namespace Imf { + + +bool +isImfMagic (const char bytes[4]) +{ + return bytes[0] == ((MAGIC >> 0) & 0x00ff) && + bytes[1] == ((MAGIC >> 8) & 0x00ff) && + bytes[2] == ((MAGIC >> 16) & 0x00ff) && + bytes[3] == ((MAGIC >> 24) & 0x00ff); +} + + +} // namespace Imf + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfVersion.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_VERSION_H +#define INCLUDED_IMF_VERSION_H + +//----------------------------------------------------------------------------- +// +// Magic and version number. +// +//----------------------------------------------------------------------------- + + +namespace Imf { + + +// +// The MAGIC number is stored in the first four bytes of every +// OpenEXR image file. This can be used to quickly test whether +// a given file is an OpenEXR image file (see isImfMagic(), below). +// + +const int MAGIC = 20000630; + + +// +// The second item in each OpenEXR image file, right after the +// magic number, is a four-byte file version identifier. Depending +// on a file's version identifier, a file reader can enable various +// backwards-compatibility switches, or it can quickly reject files +// that it cannot read. +// +// The version identifier is split into an 8-bit version number, +// and a 24-bit flags field. +// + +const int VERSION_NUMBER_FIELD = 0x000000ff; +const int VERSION_FLAGS_FIELD = 0xffffff00; + + +// +// Value that goes into VERSION_NUMBER_FIELD. +// + +const int EXR_VERSION = 2; + + +// +// Flags that can go into VERSION_FLAGS_FIELD. +// Flags can only occupy the 1 bits in VERSION_FLAGS_FIELD. +// + +const int TILED_FLAG = 0x00000200; // File is tiled + +const int LONG_NAMES_FLAG = 0x00000400; // File contains long + // attribute or channel + // names + +// +// Bitwise OR of all known flags. +// + +const int ALL_FLAGS = TILED_FLAG | LONG_NAMES_FLAG; + + +// +// Utility functions +// + +inline bool isTiled (int version) {return !!(version & TILED_FLAG);} +inline int makeTiled (int version) {return version | TILED_FLAG;} +inline int makeNotTiled (int version) {return version & ~TILED_FLAG;} +inline int getVersion (int version) {return version & VERSION_NUMBER_FIELD;} +inline int getFlags (int version) {return version & VERSION_FLAGS_FIELD;} +inline bool supportsFlags (int flags) {return !(flags & ~ALL_FLAGS);} + + +// +// Given the first four bytes of a file, returns true if the +// file is probably an OpenEXR image file, false if not. +// + +bool isImfMagic (const char bytes[4]); + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,390 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// 16-bit Haar Wavelet encoding and decoding +// +// The source code in this file is derived from the encoding +// and decoding routines written by Christian Rouet for his +// PIZ image file format. +// +//----------------------------------------------------------------------------- + + +#include + +namespace Imf { +namespace { + + +// +// Wavelet basis functions without modulo arithmetic; they produce +// the best compression ratios when the wavelet-transformed data are +// Huffman-encoded, but the wavelet transform works only for 14-bit +// data (untransformed data values must be less than (1 << 14)). +// + +inline void +wenc14 (unsigned short a, unsigned short b, + unsigned short &l, unsigned short &h) +{ + short as = a; + short bs = b; + + short ms = (as + bs) >> 1; + short ds = as - bs; + + l = ms; + h = ds; +} + + +inline void +wdec14 (unsigned short l, unsigned short h, + unsigned short &a, unsigned short &b) +{ + short ls = l; + short hs = h; + + int hi = hs; + int ai = ls + (hi & 1) + (hi >> 1); + + short as = ai; + short bs = ai - hi; + + a = as; + b = bs; +} + + +// +// Wavelet basis functions with modulo arithmetic; they work with full +// 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't +// compress the data quite as well. +// + +const int NBITS = 16; +const int A_OFFSET = 1 << (NBITS - 1); +const int M_OFFSET = 1 << (NBITS - 1); +const int MOD_MASK = (1 << NBITS) - 1; + + +inline void +wenc16 (unsigned short a, unsigned short b, + unsigned short &l, unsigned short &h) +{ + int ao = (a + A_OFFSET) & MOD_MASK; + int m = ((ao + b) >> 1); + int d = ao - b; + + if (d < 0) + m = (m + M_OFFSET) & MOD_MASK; + + d &= MOD_MASK; + + l = m; + h = d; +} + + +inline void +wdec16 (unsigned short l, unsigned short h, + unsigned short &a, unsigned short &b) +{ + int m = l; + int d = h; + int bb = (m - (d >> 1)) & MOD_MASK; + int aa = (d + bb - A_OFFSET) & MOD_MASK; + b = bb; + a = aa; +} + +} // namespace + + +// +// 2D Wavelet encoding: +// + +void +wav2Encode + (unsigned short* in, // io: values are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx) // i : maximum in[x][y] value +{ + bool w14 = (mx < (1 << 14)); + int n = (nx > ny)? ny: nx; + int p = 1; // == 1 << level + int p2 = 2; // == 1 << (level+1) + + // + // Hierachical loop on smaller dimension n + // + + while (p2 <= n) + { + unsigned short *py = in; + unsigned short *ey = in + oy * (ny - p2); + int oy1 = oy * p; + int oy2 = oy * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + unsigned short i00,i01,i10,i11; + + // + // Y loop + // + + for (; py <= ey; py += oy2) + { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + // + // X loop + // + + for (; px <= ex; px += ox2) + { + unsigned short *p01 = px + ox1; + unsigned short *p10 = px + oy1; + unsigned short *p11 = p10 + ox1; + + // + // 2D wavelet encoding + // + + if (w14) + { + wenc14 (*px, *p01, i00, i01); + wenc14 (*p10, *p11, i10, i11); + wenc14 (i00, i10, *px, *p10); + wenc14 (i01, i11, *p01, *p11); + } + else + { + wenc16 (*px, *p01, i00, i01); + wenc16 (*p10, *p11, i10, i11); + wenc16 (i00, i10, *px, *p10); + wenc16 (i01, i11, *p01, *p11); + } + } + + // + // Encode (1D) odd column (still in Y loop) + // + + if (nx & p) + { + unsigned short *p10 = px + oy1; + + if (w14) + wenc14 (*px, *p10, i00, *p10); + else + wenc16 (*px, *p10, i00, *p10); + + *px= i00; + } + } + + // + // Encode (1D) odd line (must loop in X) + // + + if (ny & p) + { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) + { + unsigned short *p01 = px + ox1; + + if (w14) + wenc14 (*px, *p01, i00, *p01); + else + wenc16 (*px, *p01, i00, *p01); + + *px= i00; + } + } + + // + // Next level + // + + p = p2; + p2 <<= 1; + } +} + + +// +// 2D Wavelet decoding: +// + +void +wav2Decode + (unsigned short* in, // io: values are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx) // i : maximum in[x][y] value +{ + bool w14 = (mx < (1 << 14)); + int n = (nx > ny)? ny: nx; + int p = 1; + int p2; + + // + // Search max level + // + + while (p <= n) + p <<= 1; + + p >>= 1; + p2 = p; + p >>= 1; + + // + // Hierarchical loop on smaller dimension n + // + + while (p >= 1) + { + unsigned short *py = in; + unsigned short *ey = in + oy * (ny - p2); + int oy1 = oy * p; + int oy2 = oy * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + unsigned short i00,i01,i10,i11; + + // + // Y loop + // + + for (; py <= ey; py += oy2) + { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + // + // X loop + // + + for (; px <= ex; px += ox2) + { + unsigned short *p01 = px + ox1; + unsigned short *p10 = px + oy1; + unsigned short *p11 = p10 + ox1; + + // + // 2D wavelet decoding + // + + if (w14) + { + wdec14 (*px, *p10, i00, i10); + wdec14 (*p01, *p11, i01, i11); + wdec14 (i00, i01, *px, *p01); + wdec14 (i10, i11, *p10, *p11); + } + else + { + wdec16 (*px, *p10, i00, i10); + wdec16 (*p01, *p11, i01, i11); + wdec16 (i00, i01, *px, *p01); + wdec16 (i10, i11, *p10, *p11); + } + } + + // + // Decode (1D) odd column (still in Y loop) + // + + if (nx & p) + { + unsigned short *p10 = px + oy1; + + if (w14) + wdec14 (*px, *p10, i00, *p10); + else + wdec16 (*px, *p10, i00, *p10); + + *px= i00; + } + } + + // + // Decode (1D) odd line (must loop in X) + // + + if (ny & p) + { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) + { + unsigned short *p01 = px + ox1; + + if (w14) + wdec14 (*px, *p01, i00, *p01); + else + wdec16 (*px, *p01, i00, *p01); + + *px= i00; + } + } + + // + // Next level + // + + p2 = p; + p >>= 1; + } +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfWav.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_WAV_H +#define INCLUDED_IMF_WAV_H + +//----------------------------------------------------------------------------- +// +// 16-bit Haar Wavelet encoding and decoding +// +//----------------------------------------------------------------------------- + +namespace Imf { + + +void +wav2Encode + (unsigned short *in, // io: values in[y][x] are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx); // i : maximum in[x][y] value + +void +wav2Decode + (unsigned short *in, // io: values in[y][x] are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx); // i : maximum in[x][y] value + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfXdr.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfXdr.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfXdr.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfXdr.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,916 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMF_XDR_H +#define INCLUDED_IMF_XDR_H + +//---------------------------------------------------------------------------- +// +// Xdr -- routines to convert data between the machine's native +// format and a machine-independent external data representation: +// +// write (T &o, S v); converts a value, v, of type S +// into a machine-independent +// representation and stores the +// result in an output buffer, o. +// +// read (T &i, S &v); reads the machine-independent +// representation of a value of type +// S from input buffer i, converts +// the value into the machine's native +// representation, and stores the result +// in v. +// +// size(); returns the size, in bytes, of the +// machine-independent representation +// of an object of type S. +// +// The write() and read() routines are templates; data can be written +// to and read from any output or input buffer type T for which a helper +// class, R, exits. Class R must define a method to store a char array +// in a T, and a method to read a char array from a T: +// +// struct R +// { +// static void +// writeChars (T &o, const char c[/*n*/], int n) +// { +// ... // Write c[0], c[1] ... c[n-1] to output buffer o. +// } +// +// static void +// readChars (T &i, char c[/*n*/], int n) +// { +// ... // Read n characters from input buffer i +// // and copy them to c[0], c[1] ... c[n-1]. +// } +// }; +// +// Example - writing to and reading from iostreams: +// +// struct CharStreamIO +// { +// static void +// writeChars (ostream &os, const char c[], int n) +// { +// os.write (c, n); +// } +// +// static void +// readChars (istream &is, char c[], int n) +// { +// is.read (c, n); +// } +// }; +// +// ... +// +// Xdr::write (os, 3); +// Xdr::write (os, 5.0); +// +//---------------------------------------------------------------------------- + +#include +#include "IexMathExc.h" +#include "half.h" +#include + +namespace Imf { +namespace Xdr { + + +//------------------------------- +// Write data to an output stream +//------------------------------- + +template +void +write (T &out, bool v); + +template +void +write (T &out, char v); + +template +void +write (T &out, signed char v); + +template +void +write (T &out, unsigned char v); + +template +void +write (T &out, signed short v); + +template +void +write (T &out, unsigned short v); + +template +void +write (T &out, signed int v); + +template +void +write (T &out, unsigned int v); + +template +void +write (T &out, signed long v); + +template +void +write (T &out, unsigned long v); + +#if ULONG_MAX != 18446744073709551615LU + + template + void + write (T &out, Int64 v); + +#endif + +template +void +write (T &out, float v); + +template +void +write (T &out, double v); + +template +void +write (T &out, half v); + +template +void +write (T &out, const char v[/*n*/], int n); // fixed-size char array + +template +void +write (T &out, const char v[]); // zero-terminated string + + +//----------------------------------------- +// Append padding bytes to an output stream +//----------------------------------------- + +template +void +pad (T &out, int n); // write n padding bytes + + + +//------------------------------- +// Read data from an input stream +//------------------------------- + +template +void +read (T &in, bool &v); + +template +void +read (T &in, char &v); + +template +void +read (T &in, signed char &v); + +template +void +read (T &in, unsigned char &v); + +template +void +read (T &in, signed short &v); + +template +void +read (T &in, unsigned short &v); + +template +void +read (T &in, signed int &v); + +template +void +read (T &in, unsigned int &v); + +template +void +read (T &in, signed long &v); + +template +void +read (T &in, unsigned long &v); + +#if ULONG_MAX != 18446744073709551615LU + + template + void + read (T &in, Int64 &v); + +#endif + +template +void +read (T &in, float &v); + +template +void +read (T &in, double &v); + +template +void +read (T &in, half &v); + +template +void +read (T &in, char v[/*n*/], int n); // fixed-size char array + +template +void +read (T &in, int n, char v[/*n*/]); // zero-terminated string + + +//------------------------------------------- +// Skip over padding bytes in an input stream +//------------------------------------------- + +template +void +skip (T &in, int n); // skip n padding bytes + + + +//-------------------------------------- +// Size of the machine-independent +// representation of an object of type S +//-------------------------------------- + +template +int +size (); + + +//--------------- +// Implementation +//--------------- + +template +inline void +writeSignedChars (T &out, const signed char c[], int n) +{ + S::writeChars (out, (const char *) c, n); +} + + +template +inline void +writeUnsignedChars (T &out, const unsigned char c[], int n) +{ + S::writeChars (out, (const char *) c, n); +} + + +template +inline void +readSignedChars (T &in, signed char c[], int n) +{ + S::readChars (in, (char *) c, n); +} + + +template +inline void +readUnsignedChars (T &in, unsigned char c[], int n) +{ + S::readChars (in, (char *) c, n); +} + + +template +inline void +write (T &out, bool v) +{ + char c = !!v; + S::writeChars (out, &c, 1); +} + + +template +inline void +write (T &out, char v) +{ + S::writeChars (out, &v, 1); +} + + +template +inline void +write (T &out, signed char v) +{ + writeSignedChars (out, &v, 1); +} + + +template +inline void +write (T &out, unsigned char v) +{ + writeUnsignedChars (out, &v, 1); +} + + +template +void +write (T &out, signed short v) +{ + signed char b[2]; + + b[0] = (signed char) (v); + b[1] = (signed char) (v >> 8); + + writeSignedChars (out, b, 2); +} + + +template +void +write (T &out, unsigned short v) +{ + unsigned char b[2]; + + b[0] = (unsigned char) (v); + b[1] = (unsigned char) (v >> 8); + + writeUnsignedChars (out, b, 2); +} + + +template +void +write (T &out, signed int v) +{ + signed char b[4]; + + b[0] = (signed char) (v); + b[1] = (signed char) (v >> 8); + b[2] = (signed char) (v >> 16); + b[3] = (signed char) (v >> 24); + + writeSignedChars (out, b, 4); +} + + +template +void +write (T &out, unsigned int v) +{ + unsigned char b[4]; + + b[0] = (unsigned char) (v); + b[1] = (unsigned char) (v >> 8); + b[2] = (unsigned char) (v >> 16); + b[3] = (unsigned char) (v >> 24); + + writeUnsignedChars (out, b, 4); +} + + +template +void +write (T &out, signed long v) +{ + signed char b[8]; + + b[0] = (signed char) (v); + b[1] = (signed char) (v >> 8); + b[2] = (signed char) (v >> 16); + b[3] = (signed char) (v >> 24); + + #if LONG_MAX == 2147483647 + + if (v >= 0) + { + b[4] = 0; + b[5] = 0; + b[6] = 0; + b[7] = 0; + } + else + { + b[4] = ~0; + b[5] = ~0; + b[6] = ~0; + b[7] = ~0; + } + + #elif LONG_MAX == 9223372036854775807L + + b[4] = (signed char) (v >> 32); + b[5] = (signed char) (v >> 40); + b[6] = (signed char) (v >> 48); + b[7] = (signed char) (v >> 56); + + #else + + #error write (T &out, signed long v) not implemented + + #endif + + writeSignedChars (out, b, 8); +} + + +template +void +write (T &out, unsigned long v) +{ + unsigned char b[8]; + + b[0] = (unsigned char) (v); + b[1] = (unsigned char) (v >> 8); + b[2] = (unsigned char) (v >> 16); + b[3] = (unsigned char) (v >> 24); + + #if ULONG_MAX == 4294967295U + + b[4] = 0; + b[5] = 0; + b[6] = 0; + b[7] = 0; + + #elif ULONG_MAX == 18446744073709551615LU + + b[4] = (unsigned char) (v >> 32); + b[5] = (unsigned char) (v >> 40); + b[6] = (unsigned char) (v >> 48); + b[7] = (unsigned char) (v >> 56); + + #else + + #error write (T &out, unsigned long v) not implemented + + #endif + + writeUnsignedChars (out, b, 8); +} + + +#if ULONG_MAX != 18446744073709551615LU + + template + void + write (T &out, Int64 v) + { + unsigned char b[8]; + + b[0] = (unsigned char) (v); + b[1] = (unsigned char) (v >> 8); + b[2] = (unsigned char) (v >> 16); + b[3] = (unsigned char) (v >> 24); + b[4] = (unsigned char) (v >> 32); + b[5] = (unsigned char) (v >> 40); + b[6] = (unsigned char) (v >> 48); + b[7] = (unsigned char) (v >> 56); + + writeUnsignedChars (out, b, 8); + } + +#endif + + +template +void +write (T &out, float v) +{ + union {unsigned int i; float f;} u; + u.f = v; + + unsigned char b[4]; + + b[0] = (unsigned char) (u.i); + b[1] = (unsigned char) (u.i >> 8); + b[2] = (unsigned char) (u.i >> 16); + b[3] = (unsigned char) (u.i >> 24); + + writeUnsignedChars (out, b, 4); +} + + +template +void +write (T &out, double v) +{ + union {Int64 i; double d;} u; + u.d = v; + + unsigned char b[8]; + + b[0] = (unsigned char) (u.i); + b[1] = (unsigned char) (u.i >> 8); + b[2] = (unsigned char) (u.i >> 16); + b[3] = (unsigned char) (u.i >> 24); + b[4] = (unsigned char) (u.i >> 32); + b[5] = (unsigned char) (u.i >> 40); + b[6] = (unsigned char) (u.i >> 48); + b[7] = (unsigned char) (u.i >> 56); + + writeUnsignedChars (out, b, 8); +} + + +template +inline void +write (T &out, half v) +{ + unsigned char b[2]; + + b[0] = (unsigned char) (v.bits()); + b[1] = (unsigned char) (v.bits() >> 8); + + writeUnsignedChars (out, b, 2); +} + + +template +inline void +write (T &out, const char v[], int n) // fixed-size char array +{ + S::writeChars (out, v, n); +} + + +template +void +write (T &out, const char v[]) // zero-terminated string +{ + while (*v) + { + S::writeChars (out, v, 1); + ++v; + } + + S::writeChars (out, v, 1); +} + + +template +void +pad (T &out, int n) // add n padding bytes +{ + for (int i = 0; i < n; i++) + { + const char c = 0; + S::writeChars (out, &c, 1); + } +} + + +template +inline void +read (T &in, bool &v) +{ + char c; + + S::readChars (in, &c, 1); + v = !!c; +} + + +template +inline void +read (T &in, char &v) +{ + S::readChars (in, &v, 1); +} + + +template +inline void +read (T &in, signed char &v) +{ + readSignedChars (in, &v, 1); +} + + +template +inline void +read (T &in, unsigned char &v) +{ + readUnsignedChars (in, &v, 1); +} + + +template +void +read (T &in, signed short &v) +{ + signed char b[2]; + + readSignedChars (in, b, 2); + + v = (b[0] & 0x00ff) | + (b[1] << 8); +} + + +template +void +read (T &in, unsigned short &v) +{ + unsigned char b[2]; + + readUnsignedChars (in, b, 2); + + v = (b[0] & 0x00ff) | + (b[1] << 8); +} + + +template +void +read (T &in, signed int &v) +{ + signed char b[4]; + + readSignedChars (in, b, 4); + + v = (b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + (b[3] << 24); +} + + +template +void +read (T &in, unsigned int &v) +{ + unsigned char b[4]; + + readUnsignedChars (in, b, 4); + + v = (b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + (b[3] << 24); +} + + +template +void +read (T &in, signed long &v) +{ + signed char b[8]; + + readSignedChars (in, b, 8); + + #if LONG_MAX == 2147483647 + + v = (b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + (b[3] << 24); + + if (( b[4] || b[5] || b[6] || b[7]) && + (~b[4] || ~b[5] || ~b[6] || ~b[7])) + { + throw Iex::OverflowExc ("Long int overflow - read a large " + "64-bit integer in a 32-bit process."); + } + + #elif LONG_MAX == 9223372036854775807L + + v = ((long) b[0] & 0x00000000000000ff) | + (((long) b[1] << 8) & 0x000000000000ff00) | + (((long) b[2] << 16) & 0x0000000000ff0000) | + (((long) b[3] << 24) & 0x00000000ff000000) | + (((long) b[4] << 32) & 0x000000ff00000000) | + (((long) b[5] << 40) & 0x0000ff0000000000) | + (((long) b[6] << 48) & 0x00ff000000000000) | + ((long) b[7] << 56); + + #else + + #error read (T &in, signed long &v) not implemented + + #endif +} + + +template +void +read (T &in, unsigned long &v) +{ + unsigned char b[8]; + + readUnsignedChars (in, b, 8); + + #if ULONG_MAX == 4294967295U + + v = (b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + (b[3] << 24); + + if (b[4] || b[5] || b[6] || b[7]) + { + throw Iex::OverflowExc ("Long int overflow - read a large " + "64-bit integer in a 32-bit process."); + } + + #elif ULONG_MAX == 18446744073709551615LU + + v = ((unsigned long) b[0] & 0x00000000000000ff) | + (((unsigned long) b[1] << 8) & 0x000000000000ff00) | + (((unsigned long) b[2] << 16) & 0x0000000000ff0000) | + (((unsigned long) b[3] << 24) & 0x00000000ff000000) | + (((unsigned long) b[4] << 32) & 0x000000ff00000000) | + (((unsigned long) b[5] << 40) & 0x0000ff0000000000) | + (((unsigned long) b[6] << 48) & 0x00ff000000000000) | + ((unsigned long) b[7] << 56); + + #else + + #error read (T &in, unsigned long &v) not implemented + + #endif +} + + +#if ULONG_MAX != 18446744073709551615LU + + template + void + read (T &in, Int64 &v) + { + unsigned char b[8]; + + readUnsignedChars (in, b, 8); + + v = ((Int64) b[0] & 0x00000000000000ffLL) | + (((Int64) b[1] << 8) & 0x000000000000ff00LL) | + (((Int64) b[2] << 16) & 0x0000000000ff0000LL) | + (((Int64) b[3] << 24) & 0x00000000ff000000LL) | + (((Int64) b[4] << 32) & 0x000000ff00000000LL) | + (((Int64) b[5] << 40) & 0x0000ff0000000000LL) | + (((Int64) b[6] << 48) & 0x00ff000000000000LL) | + ((Int64) b[7] << 56); + } + +#endif + + +template +void +read (T &in, float &v) +{ + unsigned char b[4]; + + readUnsignedChars (in, b, 4); + + union {unsigned int i; float f;} u; + + u.i = (b[0] & 0x000000ff) | + ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | + (b[3] << 24); + + v = u.f; +} + + +template +void +read (T &in, double &v) +{ + unsigned char b[8]; + + readUnsignedChars (in, b, 8); + + union {Int64 i; double d;} u; + + u.i = ((Int64) b[0] & 0x00000000000000ffULL) | + (((Int64) b[1] << 8) & 0x000000000000ff00ULL) | + (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) | + (((Int64) b[3] << 24) & 0x00000000ff000000ULL) | + (((Int64) b[4] << 32) & 0x000000ff00000000ULL) | + (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) | + (((Int64) b[6] << 48) & 0x00ff000000000000ULL) | + ((Int64) b[7] << 56); + + v = u.d; +} + + +template +inline void +read (T &in, half &v) +{ + unsigned char b[2]; + + readUnsignedChars (in, b, 2); + + v.setBits ((b[0] & 0x00ff) | (b[1] << 8)); +} + + +template +inline void +read (T &in, char v[], int n) // fixed-size char array +{ + S::readChars (in, v, n); +} + + +template +void +read (T &in, int n, char v[]) // zero-terminated string +{ + while (n >= 0) + { + S::readChars (in, v, 1); + + if (*v == 0) + break; + + --n; + ++v; + } +} + + +template +void +skip (T &in, int n) // skip n padding bytes +{ + char c[1024]; + + while (n >= (int) sizeof (c)) + { + if (!S::readChars (in, c, sizeof (c))) + return; + + n -= sizeof (c); + } + + if (n >= 1) + S::readChars (in, c, n); +} + + +template <> inline int size () {return 1;} +template <> inline int size () {return 1;} +template <> inline int size () {return 1;} +template <> inline int size () {return 1;} +template <> inline int size () {return 2;} +template <> inline int size () {return 2;} +template <> inline int size () {return 4;} +template <> inline int size () {return 4;} +template <> inline int size () {return 8;} +template <> inline int size () {return 8;} +template <> inline int size () {return 4;} +template <> inline int size () {return 8;} +template <> inline int size () {return 2;} + + +} // namespace Xdr +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,240 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//----------------------------------------------------------------------------- +// +// class ZipCompressor +// +//----------------------------------------------------------------------------- +//#define ZLIB_WINAPI + +#include +#include +#include "Iex.h" +#include + +namespace Imf { + + +ZipCompressor::ZipCompressor + (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines) +: + Compressor (hdr), + _maxScanLineSize (maxScanLineSize), + _numScanLines (numScanLines), + _tmpBuffer (0), + _outBuffer (0) +{ + size_t maxInBytes = + uiMult (maxScanLineSize, numScanLines); + + size_t maxOutBytes = + uiAdd (uiAdd (maxInBytes, + size_t (ceil (maxInBytes * 0.01))), + size_t (100)); + + _tmpBuffer = + new char [maxInBytes]; + + _outBuffer = + new char [maxOutBytes]; +} + + +ZipCompressor::~ZipCompressor () +{ + delete [] _tmpBuffer; + delete [] _outBuffer; +} + + +int +ZipCompressor::numScanLines () const +{ + return _numScanLines; +} + + +int +ZipCompressor::compress (const char *inPtr, + int inSize, + int /*minY*/, + const char *&outPtr) +{ + // + // Special case ­- empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Reorder the pixel data. + // + + { + char *t1 = _tmpBuffer; + char *t2 = _tmpBuffer + (inSize + 1) / 2; + const char *stop = inPtr + inSize; + + while (true) + { + if (inPtr < stop) + *(t1++) = *(inPtr++); + else + break; + + if (inPtr < stop) + *(t2++) = *(inPtr++); + else + break; + } + } + + // + // Predictor. + // + + { + unsigned char *t = (unsigned char *) _tmpBuffer + 1; + unsigned char *stop = (unsigned char *) _tmpBuffer + inSize; + int p = t[-1]; + + while (t < stop) + { + int d = int (t[0]) - p + (128 + 256); + p = t[0]; + t[0] = d; + ++t; + } + } + + // + // Compress the data using zlib + // + + uLongf outSize = int(ceil(inSize * 1.01)) + 100; + + if (Z_OK != ::compress ((Bytef *)_outBuffer, &outSize, + (const Bytef *) _tmpBuffer, inSize)) + { + throw Iex::BaseExc ("Data compression (zlib) failed."); + } + + outPtr = _outBuffer; + return outSize; +} + + +int +ZipCompressor::uncompress (const char *inPtr, + int inSize, + int /*minY*/, + const char *&outPtr) +{ + // + // Special case ­- empty input buffer + // + + if (inSize == 0) + { + outPtr = _outBuffer; + return 0; + } + + // + // Decompress the data using zlib + // + + uLongf outSize = _maxScanLineSize * _numScanLines; + + if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize, + (const Bytef *) inPtr, inSize)) + { + throw Iex::InputExc ("Data decompression (zlib) failed."); + } + + // + // Predictor. + // + + { + unsigned char *t = (unsigned char *) _tmpBuffer + 1; + unsigned char *stop = (unsigned char *) _tmpBuffer + outSize; + + while (t < stop) + { + int d = int (t[-1]) + int (t[0]) - 128; + t[0] = d; + ++t; + } + } + + // + // Reorder the pixel data. + // + + { + const char *t1 = _tmpBuffer; + const char *t2 = _tmpBuffer + (outSize + 1) / 2; + char *s = _outBuffer; + char *stop = s + outSize; + + while (true) + { + if (s < stop) + *(s++) = *(t1++); + else + break; + + if (s < stop) + *(s++) = *(t2++); + else + break; + } + } + + outPtr = _outBuffer; + return outSize; +} + + +} // namespace Imf diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/ImfZipCompressor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMF_ZIP_COMPRESSOR_H +#define INCLUDED_IMF_ZIP_COMPRESSOR_H + +//----------------------------------------------------------------------------- +// +// class ZipCompressor -- performs zlib-style compression +// +//----------------------------------------------------------------------------- + +#include + +namespace Imf { + + +class ZipCompressor: public Compressor +{ + public: + + ZipCompressor (const Header &hdr, + size_t maxScanLineSize, + size_t numScanLines); + + virtual ~ZipCompressor (); + + virtual int numScanLines () const; + + virtual int compress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + + virtual int uncompress (const char *inPtr, + int inSize, + int minY, + const char *&outPtr); + private: + + int _maxScanLineSize; + int _numScanLines; + char * _tmpBuffer; + char * _outBuffer; +}; + + +} // namespace Imf + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,136 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//--------------------------------------------------------------------------- +// +// b44ExpLogTable +// +// A program to generate lookup tables for +// +// y = exp (x / 8) +// +// and +// x = 8 * log (x); +// +// where x and y are 16-bit floating-point numbers +// +// The tables are used by class B44Compressor. +// +//--------------------------------------------------------------------------- + +#include +#include +#include +#include + +using namespace std; + +//--------------------------------------------- +// Main - prints the half-to-float lookup table +//--------------------------------------------- + +int +main () +{ +#ifndef HAVE_IOS_BASE + cout.setf (ios::hex, ios::basefield); +#else + cout.setf (ios_base::hex, ios_base::basefield); +#endif + + cout << "//\n" + "// This is an automatically generated file.\n" + "// Do not edit.\n" + "//\n\n"; + + const int iMax = (1 << 16); + + cout << "const unsigned short expTable[] =\n" + "{\n" + " "; + + for (int i = 0; i < iMax; i++) + { + half h; + h.setBits (i); + + if (!h.isFinite()) + h = 0; + else if (h >= 8 * log (HALF_MAX)) + h = HALF_MAX; + else + h = exp (h / 8); + + cout << "0x" << setfill ('0') << setw (4) << h.bits() << ", "; + + if (i % 8 == 7) + { + cout << "\n"; + + if (i < iMax - 1) + cout << " "; + } + } + + cout << "};\n\n"; + + cout << "const unsigned short logTable[] =\n" + "{\n" + " "; + + for (int i = 0; i < iMax; i++) + { + half h; + h.setBits (i); + + if (!h.isFinite() || h < 0) + h = 0; + else + h = 8 * log (h); + + cout << "0x" << setfill ('0') << setw (4) << h.bits() << ", "; + + if (i % 8 == 7) + { + cout << "\n"; + + if (i < iMax - 1) + cout << " "; + } + } + + cout << "};\n"; + + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmImf/b44ExpLogTable.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,16396 @@ +// +// This is an automatically generated file. +// Do not edit. +// + +const unsigned short expTable[] = +{ + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, + 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c01, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, + 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c02, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, + 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c03, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, + 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c04, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, + 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c05, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, 0x3c06, + 0x3c06, 0x3c06, 0x3c06, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, 0x3c07, + 0x3c07, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c08, + 0x3c08, 0x3c08, 0x3c08, 0x3c08, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, 0x3c09, + 0x3c09, 0x3c09, 0x3c09, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, 0x3c0a, + 0x3c0a, 0x3c0a, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, 0x3c0b, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, + 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0c, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, + 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0e, + 0x3c0e, 0x3c0e, 0x3c0e, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3c0f, 0x3c0f, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, 0x3c10, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, + 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c11, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, + 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c12, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, + 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c13, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c14, + 0x3c14, 0x3c14, 0x3c14, 0x3c14, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, 0x3c15, + 0x3c15, 0x3c15, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, 0x3c16, + 0x3c16, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, + 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c17, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, + 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c18, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, + 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c19, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1a, + 0x3c1a, 0x3c1a, 0x3c1a, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1b, + 0x3c1b, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, 0x3c1c, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, + 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, + 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1e, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, 0x3c1f, + 0x3c1f, 0x3c1f, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, 0x3c20, + 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, + 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, + 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, + 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c21, 0x3c22, + 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, + 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, + 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, + 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c22, 0x3c23, 0x3c23, + 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, + 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, + 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, + 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c23, 0x3c24, 0x3c24, 0x3c24, + 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, + 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, + 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c24, + 0x3c24, 0x3c24, 0x3c24, 0x3c24, 0x3c25, 0x3c25, 0x3c25, 0x3c25, + 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, + 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, + 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, 0x3c25, + 0x3c25, 0x3c25, 0x3c25, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, + 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, + 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, + 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, 0x3c26, + 0x3c26, 0x3c26, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, + 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, + 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, + 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, 0x3c27, + 0x3c27, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, + 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, + 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, + 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, 0x3c28, + 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, + 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, + 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, + 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c29, 0x3c2a, 0x3c2a, + 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, + 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, + 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, + 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2a, 0x3c2b, 0x3c2b, 0x3c2b, + 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, + 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, + 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, + 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, + 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, + 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, + 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, 0x3c2c, + 0x3c2c, 0x3c2c, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, + 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, + 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, + 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, 0x3c2d, + 0x3c2d, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, + 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, + 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, + 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, 0x3c2e, + 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, + 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, + 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, + 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c30, 0x3c30, + 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, + 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, + 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, + 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c30, 0x3c31, 0x3c31, 0x3c31, + 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, + 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, + 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, 0x3c31, + 0x3c31, 0x3c31, 0x3c31, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, + 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, + 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, + 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, 0x3c32, + 0x3c32, 0x3c32, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, + 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, + 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, + 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, 0x3c33, + 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, + 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, + 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, + 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c34, 0x3c35, + 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, + 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, + 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, + 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c35, 0x3c36, 0x3c36, 0x3c36, + 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, + 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, + 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c36, + 0x3c36, 0x3c36, 0x3c36, 0x3c36, 0x3c37, 0x3c37, 0x3c37, 0x3c37, + 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, + 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, + 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, 0x3c37, + 0x3c37, 0x3c37, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, + 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, + 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, + 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, 0x3c38, + 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, + 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, + 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, + 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c39, 0x3c3a, + 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, + 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, + 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, + 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3a, 0x3c3b, 0x3c3b, 0x3c3b, + 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, + 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, + 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3b, + 0x3c3b, 0x3c3b, 0x3c3b, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3c, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, + 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, + 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, + 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, 0x3c3d, + 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, + 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, + 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, + 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3f, 0x3c3f, + 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, + 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, + 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, + 0x3c3f, 0x3c3f, 0x3c3f, 0x3c3f, 0x3c40, 0x3c40, 0x3c40, 0x3c40, + 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, + 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, + 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, 0x3c40, + 0x3c40, 0x3c40, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, + 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, + 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, + 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, 0x3c41, + 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, + 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, + 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c42, 0x3c43, + 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, + 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c43, 0x3c44, 0x3c44, + 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c44, + 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c44, 0x3c45, 0x3c45, 0x3c45, + 0x3c45, 0x3c45, 0x3c45, 0x3c45, 0x3c45, 0x3c45, 0x3c45, 0x3c45, + 0x3c45, 0x3c45, 0x3c45, 0x3c45, 0x3c46, 0x3c46, 0x3c46, 0x3c46, + 0x3c46, 0x3c46, 0x3c46, 0x3c46, 0x3c46, 0x3c46, 0x3c46, 0x3c46, + 0x3c46, 0x3c46, 0x3c46, 0x3c47, 0x3c47, 0x3c47, 0x3c47, 0x3c47, + 0x3c47, 0x3c47, 0x3c47, 0x3c47, 0x3c47, 0x3c47, 0x3c47, 0x3c47, + 0x3c47, 0x3c47, 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, + 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, 0x3c48, + 0x3c48, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, + 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, 0x3c49, + 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, + 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4a, 0x3c4b, + 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, + 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4c, 0x3c4c, + 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, + 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4c, 0x3c4d, 0x3c4d, 0x3c4d, + 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, + 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4d, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, + 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, + 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, + 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, 0x3c4f, + 0x3c4f, 0x3c4f, 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, + 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, 0x3c50, + 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, + 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c51, 0x3c52, + 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, + 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c52, 0x3c53, 0x3c53, + 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c53, + 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c53, 0x3c54, 0x3c54, 0x3c54, + 0x3c54, 0x3c54, 0x3c54, 0x3c54, 0x3c54, 0x3c54, 0x3c54, 0x3c54, + 0x3c54, 0x3c54, 0x3c54, 0x3c54, 0x3c55, 0x3c55, 0x3c55, 0x3c55, + 0x3c55, 0x3c55, 0x3c55, 0x3c55, 0x3c55, 0x3c55, 0x3c55, 0x3c55, + 0x3c55, 0x3c55, 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, + 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, 0x3c56, + 0x3c56, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, + 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, 0x3c57, + 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, + 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c58, 0x3c59, + 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c59, + 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c59, 0x3c5a, 0x3c5a, 0x3c5a, + 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, + 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5a, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, + 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5b, + 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, + 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, 0x3c5c, + 0x3c5c, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, + 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, 0x3c5d, + 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, + 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5f, + 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, + 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c5f, 0x3c60, 0x3c60, 0x3c60, + 0x3c60, 0x3c60, 0x3c60, 0x3c60, 0x3c60, 0x3c60, 0x3c60, 0x3c60, + 0x3c60, 0x3c60, 0x3c60, 0x3c60, 0x3c61, 0x3c61, 0x3c61, 0x3c61, + 0x3c61, 0x3c61, 0x3c61, 0x3c61, 0x3c61, 0x3c61, 0x3c61, 0x3c61, + 0x3c61, 0x3c61, 0x3c61, 0x3c62, 0x3c62, 0x3c62, 0x3c62, 0x3c62, + 0x3c62, 0x3c62, 0x3c62, 0x3c62, 0x3c62, 0x3c62, 0x3c62, 0x3c62, + 0x3c62, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, + 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, 0x3c63, + 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, + 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c64, 0x3c65, 0x3c65, + 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c65, + 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c65, 0x3c66, 0x3c66, 0x3c66, + 0x3c66, 0x3c66, 0x3c66, 0x3c66, 0x3c66, 0x3c66, 0x3c66, 0x3c66, + 0x3c66, 0x3c66, 0x3c66, 0x3c66, 0x3c67, 0x3c67, 0x3c67, 0x3c67, + 0x3c67, 0x3c67, 0x3c67, 0x3c67, 0x3c67, 0x3c67, 0x3c67, 0x3c67, + 0x3c67, 0x3c67, 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, + 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, 0x3c68, + 0x3c68, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, + 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c69, 0x3c6a, + 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, + 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6a, 0x3c6b, 0x3c6b, + 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, + 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6b, 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, + 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6c, + 0x3c6c, 0x3c6c, 0x3c6c, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, + 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, 0x3c6d, + 0x3c6d, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, + 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6e, 0x3c6f, + 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, + 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c70, 0x3c70, + 0x3c70, 0x3c70, 0x3c70, 0x3c70, 0x3c70, 0x3c70, 0x3c70, 0x3c70, + 0x3c70, 0x3c70, 0x3c70, 0x3c70, 0x3c71, 0x3c71, 0x3c71, 0x3c71, + 0x3c71, 0x3c71, 0x3c71, 0x3c71, 0x3c71, 0x3c71, 0x3c71, 0x3c71, + 0x3c71, 0x3c71, 0x3c71, 0x3c72, 0x3c72, 0x3c72, 0x3c72, 0x3c72, + 0x3c72, 0x3c72, 0x3c72, 0x3c72, 0x3c72, 0x3c72, 0x3c72, 0x3c72, + 0x3c72, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, + 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, 0x3c73, + 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, + 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c74, 0x3c75, 0x3c75, + 0x3c75, 0x3c75, 0x3c75, 0x3c75, 0x3c75, 0x3c75, 0x3c75, 0x3c75, + 0x3c75, 0x3c75, 0x3c75, 0x3c75, 0x3c76, 0x3c76, 0x3c76, 0x3c76, + 0x3c76, 0x3c76, 0x3c76, 0x3c76, 0x3c76, 0x3c76, 0x3c76, 0x3c76, + 0x3c76, 0x3c76, 0x3c76, 0x3c77, 0x3c77, 0x3c77, 0x3c77, 0x3c77, + 0x3c77, 0x3c77, 0x3c77, 0x3c77, 0x3c77, 0x3c77, 0x3c77, 0x3c77, + 0x3c77, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, + 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c78, 0x3c79, + 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, + 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c79, 0x3c7a, 0x3c7a, + 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, + 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, + 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, 0x3c7b, + 0x3c7b, 0x3c7b, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, + 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, 0x3c7c, + 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, + 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7d, 0x3c7e, + 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, + 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7e, 0x3c7f, 0x3c7f, 0x3c7f, + 0x3c7f, 0x3c7f, 0x3c7f, 0x3c7f, 0x3c7f, 0x3c7f, 0x3c7f, 0x3c7f, + 0x3c7f, 0x3c7f, 0x3c7f, 0x3c80, 0x3c80, 0x3c80, 0x3c80, 0x3c80, + 0x3c80, 0x3c80, 0x3c80, 0x3c80, 0x3c80, 0x3c80, 0x3c80, 0x3c80, + 0x3c80, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, + 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, 0x3c81, + 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, + 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c82, 0x3c83, 0x3c83, + 0x3c83, 0x3c83, 0x3c83, 0x3c83, 0x3c83, 0x3c83, 0x3c83, 0x3c83, + 0x3c83, 0x3c83, 0x3c83, 0x3c83, 0x3c84, 0x3c84, 0x3c84, 0x3c84, + 0x3c84, 0x3c84, 0x3c84, 0x3c84, 0x3c84, 0x3c84, 0x3c84, 0x3c84, + 0x3c84, 0x3c84, 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, + 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, 0x3c85, + 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, + 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c86, 0x3c87, 0x3c87, + 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c87, + 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c87, 0x3c88, 0x3c88, 0x3c88, + 0x3c88, 0x3c88, 0x3c88, 0x3c88, 0x3c88, 0x3c88, 0x3c88, 0x3c88, + 0x3c88, 0x3c88, 0x3c89, 0x3c89, 0x3c89, 0x3c89, 0x3c89, 0x3c89, + 0x3c89, 0x3c8a, 0x3c8a, 0x3c8a, 0x3c8a, 0x3c8a, 0x3c8a, 0x3c8a, + 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8c, + 0x3c8c, 0x3c8c, 0x3c8c, 0x3c8c, 0x3c8c, 0x3c8c, 0x3c8d, 0x3c8d, + 0x3c8d, 0x3c8d, 0x3c8d, 0x3c8d, 0x3c8d, 0x3c8e, 0x3c8e, 0x3c8e, + 0x3c8e, 0x3c8e, 0x3c8e, 0x3c8e, 0x3c8f, 0x3c8f, 0x3c8f, 0x3c8f, + 0x3c8f, 0x3c8f, 0x3c8f, 0x3c90, 0x3c90, 0x3c90, 0x3c90, 0x3c90, + 0x3c90, 0x3c90, 0x3c91, 0x3c91, 0x3c91, 0x3c91, 0x3c91, 0x3c91, + 0x3c91, 0x3c92, 0x3c92, 0x3c92, 0x3c92, 0x3c92, 0x3c92, 0x3c92, + 0x3c93, 0x3c93, 0x3c93, 0x3c93, 0x3c93, 0x3c93, 0x3c93, 0x3c94, + 0x3c94, 0x3c94, 0x3c94, 0x3c94, 0x3c94, 0x3c94, 0x3c95, 0x3c95, + 0x3c95, 0x3c95, 0x3c95, 0x3c95, 0x3c95, 0x3c96, 0x3c96, 0x3c96, + 0x3c96, 0x3c96, 0x3c96, 0x3c96, 0x3c97, 0x3c97, 0x3c97, 0x3c97, + 0x3c97, 0x3c97, 0x3c97, 0x3c98, 0x3c98, 0x3c98, 0x3c98, 0x3c98, + 0x3c98, 0x3c98, 0x3c99, 0x3c99, 0x3c99, 0x3c99, 0x3c99, 0x3c99, + 0x3c99, 0x3c9a, 0x3c9a, 0x3c9a, 0x3c9a, 0x3c9a, 0x3c9a, 0x3c9a, + 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9c, + 0x3c9c, 0x3c9c, 0x3c9c, 0x3c9c, 0x3c9c, 0x3c9c, 0x3c9d, 0x3c9d, + 0x3c9d, 0x3c9d, 0x3c9d, 0x3c9d, 0x3c9d, 0x3c9e, 0x3c9e, 0x3c9e, + 0x3c9e, 0x3c9e, 0x3c9e, 0x3c9f, 0x3c9f, 0x3c9f, 0x3c9f, 0x3c9f, + 0x3c9f, 0x3c9f, 0x3ca0, 0x3ca0, 0x3ca0, 0x3ca0, 0x3ca0, 0x3ca0, + 0x3ca0, 0x3ca1, 0x3ca1, 0x3ca1, 0x3ca1, 0x3ca1, 0x3ca1, 0x3ca1, + 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca3, + 0x3ca3, 0x3ca3, 0x3ca3, 0x3ca3, 0x3ca3, 0x3ca3, 0x3ca4, 0x3ca4, + 0x3ca4, 0x3ca4, 0x3ca4, 0x3ca4, 0x3ca4, 0x3ca5, 0x3ca5, 0x3ca5, + 0x3ca5, 0x3ca5, 0x3ca5, 0x3ca5, 0x3ca6, 0x3ca6, 0x3ca6, 0x3ca6, + 0x3ca6, 0x3ca6, 0x3ca6, 0x3ca7, 0x3ca7, 0x3ca7, 0x3ca7, 0x3ca7, + 0x3ca7, 0x3ca7, 0x3ca8, 0x3ca8, 0x3ca8, 0x3ca8, 0x3ca8, 0x3ca8, + 0x3ca9, 0x3ca9, 0x3ca9, 0x3ca9, 0x3ca9, 0x3ca9, 0x3ca9, 0x3caa, + 0x3caa, 0x3caa, 0x3caa, 0x3caa, 0x3caa, 0x3caa, 0x3cab, 0x3cab, + 0x3cab, 0x3cab, 0x3cab, 0x3cab, 0x3cab, 0x3cac, 0x3cac, 0x3cac, + 0x3cac, 0x3cac, 0x3cac, 0x3cac, 0x3cad, 0x3cad, 0x3cad, 0x3cad, + 0x3cad, 0x3cad, 0x3cad, 0x3cae, 0x3cae, 0x3cae, 0x3cae, 0x3cae, + 0x3cae, 0x3cae, 0x3caf, 0x3caf, 0x3caf, 0x3caf, 0x3caf, 0x3caf, + 0x3cb0, 0x3cb0, 0x3cb0, 0x3cb0, 0x3cb0, 0x3cb0, 0x3cb0, 0x3cb1, + 0x3cb1, 0x3cb1, 0x3cb1, 0x3cb1, 0x3cb1, 0x3cb1, 0x3cb2, 0x3cb2, + 0x3cb2, 0x3cb2, 0x3cb2, 0x3cb2, 0x3cb2, 0x3cb3, 0x3cb3, 0x3cb3, + 0x3cb3, 0x3cb3, 0x3cb3, 0x3cb3, 0x3cb4, 0x3cb4, 0x3cb4, 0x3cb4, + 0x3cb4, 0x3cb4, 0x3cb5, 0x3cb5, 0x3cb5, 0x3cb5, 0x3cb5, 0x3cb5, + 0x3cb5, 0x3cb6, 0x3cb6, 0x3cb6, 0x3cb6, 0x3cb6, 0x3cb6, 0x3cb6, + 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb8, + 0x3cb8, 0x3cb8, 0x3cb8, 0x3cb8, 0x3cb8, 0x3cb8, 0x3cb9, 0x3cb9, + 0x3cb9, 0x3cb9, 0x3cb9, 0x3cb9, 0x3cba, 0x3cba, 0x3cba, 0x3cba, + 0x3cba, 0x3cba, 0x3cba, 0x3cbb, 0x3cbb, 0x3cbb, 0x3cbb, 0x3cbb, + 0x3cbb, 0x3cbb, 0x3cbc, 0x3cbc, 0x3cbc, 0x3cbc, 0x3cbc, 0x3cbc, + 0x3cbc, 0x3cbd, 0x3cbd, 0x3cbd, 0x3cbd, 0x3cbd, 0x3cbd, 0x3cbe, + 0x3cbe, 0x3cbe, 0x3cbe, 0x3cbe, 0x3cbe, 0x3cbe, 0x3cbf, 0x3cbf, + 0x3cbf, 0x3cbf, 0x3cbf, 0x3cbf, 0x3cbf, 0x3cc0, 0x3cc0, 0x3cc0, + 0x3cc0, 0x3cc0, 0x3cc0, 0x3cc0, 0x3cc1, 0x3cc1, 0x3cc1, 0x3cc1, + 0x3cc1, 0x3cc1, 0x3cc2, 0x3cc2, 0x3cc2, 0x3cc2, 0x3cc2, 0x3cc2, + 0x3cc2, 0x3cc3, 0x3cc3, 0x3cc3, 0x3cc3, 0x3cc3, 0x3cc3, 0x3cc3, + 0x3cc4, 0x3cc4, 0x3cc4, 0x3cc4, 0x3cc4, 0x3cc4, 0x3cc4, 0x3cc5, + 0x3cc5, 0x3cc5, 0x3cc5, 0x3cc5, 0x3cc5, 0x3cc6, 0x3cc6, 0x3cc6, + 0x3cc6, 0x3cc6, 0x3cc6, 0x3cc6, 0x3cc7, 0x3cc7, 0x3cc7, 0x3cc7, + 0x3cc7, 0x3cc7, 0x3cc7, 0x3cc8, 0x3cc8, 0x3cc8, 0x3cc8, 0x3cc8, + 0x3cc8, 0x3cc9, 0x3cc9, 0x3cc9, 0x3cc9, 0x3cc9, 0x3cc9, 0x3cc9, + 0x3cca, 0x3cca, 0x3cca, 0x3cca, 0x3cca, 0x3cca, 0x3cca, 0x3ccb, + 0x3ccb, 0x3ccb, 0x3ccb, 0x3ccb, 0x3ccb, 0x3ccc, 0x3ccc, 0x3ccc, + 0x3ccc, 0x3ccc, 0x3ccc, 0x3ccc, 0x3ccd, 0x3ccd, 0x3ccd, 0x3ccd, + 0x3ccd, 0x3ccd, 0x3ccd, 0x3cce, 0x3cce, 0x3cce, 0x3cce, 0x3cce, + 0x3cce, 0x3ccf, 0x3ccf, 0x3ccf, 0x3ccf, 0x3ccf, 0x3ccf, 0x3ccf, + 0x3cd0, 0x3cd0, 0x3cd0, 0x3cd0, 0x3cd0, 0x3cd0, 0x3cd0, 0x3cd1, + 0x3cd1, 0x3cd1, 0x3cd1, 0x3cd1, 0x3cd1, 0x3cd2, 0x3cd2, 0x3cd2, + 0x3cd2, 0x3cd2, 0x3cd2, 0x3cd2, 0x3cd3, 0x3cd3, 0x3cd3, 0x3cd3, + 0x3cd3, 0x3cd3, 0x3cd3, 0x3cd4, 0x3cd4, 0x3cd4, 0x3cd4, 0x3cd4, + 0x3cd4, 0x3cd5, 0x3cd5, 0x3cd5, 0x3cd5, 0x3cd5, 0x3cd5, 0x3cd5, + 0x3cd6, 0x3cd6, 0x3cd6, 0x3cd6, 0x3cd6, 0x3cd6, 0x3cd7, 0x3cd7, + 0x3cd7, 0x3cd7, 0x3cd7, 0x3cd7, 0x3cd7, 0x3cd8, 0x3cd8, 0x3cd8, + 0x3cd8, 0x3cd8, 0x3cd8, 0x3cd8, 0x3cd9, 0x3cd9, 0x3cd9, 0x3cd9, + 0x3cd9, 0x3cd9, 0x3cda, 0x3cda, 0x3cda, 0x3cda, 0x3cda, 0x3cda, + 0x3cda, 0x3cdb, 0x3cdb, 0x3cdb, 0x3cdb, 0x3cdb, 0x3cdb, 0x3cdc, + 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdd, 0x3cdd, + 0x3cdd, 0x3cdd, 0x3cdd, 0x3cdd, 0x3cdd, 0x3cde, 0x3cde, 0x3cde, + 0x3cde, 0x3cde, 0x3cde, 0x3cdf, 0x3cdf, 0x3cdf, 0x3cdf, 0x3cdf, + 0x3cdf, 0x3cdf, 0x3ce0, 0x3ce0, 0x3ce0, 0x3ce0, 0x3ce0, 0x3ce0, + 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce2, + 0x3ce2, 0x3ce2, 0x3ce2, 0x3ce2, 0x3ce2, 0x3ce3, 0x3ce3, 0x3ce3, + 0x3ce3, 0x3ce3, 0x3ce3, 0x3ce3, 0x3ce4, 0x3ce4, 0x3ce4, 0x3ce4, + 0x3ce4, 0x3ce4, 0x3ce4, 0x3ce5, 0x3ce5, 0x3ce5, 0x3ce5, 0x3ce5, + 0x3ce5, 0x3ce6, 0x3ce6, 0x3ce6, 0x3ce6, 0x3ce6, 0x3ce6, 0x3ce6, + 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce8, 0x3ce8, + 0x3ce8, 0x3ce8, 0x3ce8, 0x3ce8, 0x3ce8, 0x3ce9, 0x3ce9, 0x3ce9, + 0x3ce9, 0x3ce9, 0x3ce9, 0x3cea, 0x3cea, 0x3cea, 0x3cea, 0x3cea, + 0x3cea, 0x3cea, 0x3ceb, 0x3ceb, 0x3ceb, 0x3ceb, 0x3ceb, 0x3ceb, + 0x3cec, 0x3cec, 0x3cec, 0x3cec, 0x3cec, 0x3cec, 0x3cec, 0x3ced, + 0x3ced, 0x3ced, 0x3ced, 0x3ced, 0x3ced, 0x3cee, 0x3cee, 0x3cee, + 0x3cee, 0x3cee, 0x3cee, 0x3cee, 0x3cef, 0x3cef, 0x3cef, 0x3cef, + 0x3cef, 0x3cef, 0x3cf0, 0x3cf0, 0x3cf0, 0x3cf0, 0x3cf0, 0x3cf0, + 0x3cf0, 0x3cf1, 0x3cf1, 0x3cf1, 0x3cf1, 0x3cf1, 0x3cf1, 0x3cf2, + 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf3, 0x3cf3, + 0x3cf3, 0x3cf3, 0x3cf3, 0x3cf3, 0x3cf4, 0x3cf4, 0x3cf4, 0x3cf4, + 0x3cf4, 0x3cf4, 0x3cf4, 0x3cf5, 0x3cf5, 0x3cf5, 0x3cf5, 0x3cf5, + 0x3cf5, 0x3cf6, 0x3cf6, 0x3cf6, 0x3cf6, 0x3cf6, 0x3cf6, 0x3cf7, + 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf8, 0x3cf8, + 0x3cf8, 0x3cf8, 0x3cf8, 0x3cf8, 0x3cf9, 0x3cf9, 0x3cf9, 0x3cf9, + 0x3cf9, 0x3cf9, 0x3cf9, 0x3cfa, 0x3cfa, 0x3cfa, 0x3cfa, 0x3cfa, + 0x3cfa, 0x3cfb, 0x3cfb, 0x3cfb, 0x3cfb, 0x3cfb, 0x3cfb, 0x3cfb, + 0x3cfc, 0x3cfc, 0x3cfc, 0x3cfc, 0x3cfc, 0x3cfc, 0x3cfd, 0x3cfd, + 0x3cfd, 0x3cfd, 0x3cfd, 0x3cfd, 0x3cfe, 0x3cfe, 0x3cfe, 0x3cfe, + 0x3cfe, 0x3cfe, 0x3cfe, 0x3cff, 0x3cff, 0x3cff, 0x3cff, 0x3cff, + 0x3cff, 0x3d00, 0x3d00, 0x3d00, 0x3d00, 0x3d00, 0x3d00, 0x3d00, + 0x3d01, 0x3d01, 0x3d01, 0x3d01, 0x3d01, 0x3d01, 0x3d02, 0x3d02, + 0x3d02, 0x3d02, 0x3d02, 0x3d02, 0x3d03, 0x3d03, 0x3d03, 0x3d03, + 0x3d03, 0x3d03, 0x3d03, 0x3d04, 0x3d04, 0x3d04, 0x3d04, 0x3d04, + 0x3d04, 0x3d05, 0x3d05, 0x3d05, 0x3d05, 0x3d05, 0x3d05, 0x3d05, + 0x3d06, 0x3d06, 0x3d06, 0x3d06, 0x3d06, 0x3d06, 0x3d07, 0x3d07, + 0x3d07, 0x3d07, 0x3d07, 0x3d07, 0x3d08, 0x3d08, 0x3d08, 0x3d08, + 0x3d08, 0x3d08, 0x3d08, 0x3d09, 0x3d09, 0x3d09, 0x3d09, 0x3d09, + 0x3d09, 0x3d0a, 0x3d0a, 0x3d0a, 0x3d0a, 0x3d0a, 0x3d0a, 0x3d0b, + 0x3d0b, 0x3d0b, 0x3d0b, 0x3d0b, 0x3d0b, 0x3d0b, 0x3d0c, 0x3d0c, + 0x3d0c, 0x3d0c, 0x3d0c, 0x3d0c, 0x3d0d, 0x3d0d, 0x3d0d, 0x3d0d, + 0x3d0d, 0x3d0d, 0x3d0e, 0x3d0e, 0x3d0e, 0x3d0e, 0x3d0e, 0x3d0e, + 0x3d0e, 0x3d0f, 0x3d0f, 0x3d0f, 0x3d0f, 0x3d0f, 0x3d0f, 0x3d10, + 0x3d10, 0x3d10, 0x3d10, 0x3d10, 0x3d10, 0x3d11, 0x3d11, 0x3d11, + 0x3d11, 0x3d11, 0x3d11, 0x3d11, 0x3d12, 0x3d12, 0x3d12, 0x3d12, + 0x3d12, 0x3d12, 0x3d13, 0x3d13, 0x3d13, 0x3d13, 0x3d13, 0x3d13, + 0x3d14, 0x3d14, 0x3d14, 0x3d14, 0x3d14, 0x3d14, 0x3d14, 0x3d15, + 0x3d15, 0x3d15, 0x3d15, 0x3d15, 0x3d15, 0x3d16, 0x3d16, 0x3d16, + 0x3d16, 0x3d16, 0x3d16, 0x3d17, 0x3d17, 0x3d17, 0x3d17, 0x3d17, + 0x3d17, 0x3d17, 0x3d18, 0x3d18, 0x3d18, 0x3d18, 0x3d18, 0x3d18, + 0x3d19, 0x3d19, 0x3d19, 0x3d19, 0x3d19, 0x3d19, 0x3d1a, 0x3d1a, + 0x3d1a, 0x3d1a, 0x3d1a, 0x3d1a, 0x3d1b, 0x3d1b, 0x3d1b, 0x3d1b, + 0x3d1b, 0x3d1b, 0x3d1b, 0x3d1c, 0x3d1c, 0x3d1c, 0x3d1c, 0x3d1c, + 0x3d1c, 0x3d1d, 0x3d1d, 0x3d1d, 0x3d1d, 0x3d1d, 0x3d1d, 0x3d1e, + 0x3d1e, 0x3d1e, 0x3d1e, 0x3d1e, 0x3d1e, 0x3d1f, 0x3d1f, 0x3d1f, + 0x3d1f, 0x3d1f, 0x3d1f, 0x3d1f, 0x3d20, 0x3d20, 0x3d20, 0x3d20, + 0x3d20, 0x3d20, 0x3d21, 0x3d21, 0x3d21, 0x3d21, 0x3d21, 0x3d21, + 0x3d22, 0x3d22, 0x3d22, 0x3d22, 0x3d22, 0x3d22, 0x3d23, 0x3d23, + 0x3d23, 0x3d23, 0x3d23, 0x3d24, 0x3d24, 0x3d24, 0x3d25, 0x3d25, + 0x3d25, 0x3d26, 0x3d26, 0x3d26, 0x3d27, 0x3d27, 0x3d27, 0x3d28, + 0x3d28, 0x3d28, 0x3d29, 0x3d29, 0x3d29, 0x3d2a, 0x3d2a, 0x3d2a, + 0x3d2b, 0x3d2b, 0x3d2b, 0x3d2c, 0x3d2c, 0x3d2c, 0x3d2d, 0x3d2d, + 0x3d2d, 0x3d2d, 0x3d2e, 0x3d2e, 0x3d2e, 0x3d2f, 0x3d2f, 0x3d2f, + 0x3d30, 0x3d30, 0x3d30, 0x3d31, 0x3d31, 0x3d31, 0x3d32, 0x3d32, + 0x3d32, 0x3d33, 0x3d33, 0x3d33, 0x3d34, 0x3d34, 0x3d34, 0x3d35, + 0x3d35, 0x3d35, 0x3d36, 0x3d36, 0x3d36, 0x3d37, 0x3d37, 0x3d37, + 0x3d38, 0x3d38, 0x3d38, 0x3d39, 0x3d39, 0x3d39, 0x3d3a, 0x3d3a, + 0x3d3a, 0x3d3a, 0x3d3b, 0x3d3b, 0x3d3b, 0x3d3c, 0x3d3c, 0x3d3c, + 0x3d3d, 0x3d3d, 0x3d3d, 0x3d3e, 0x3d3e, 0x3d3e, 0x3d3f, 0x3d3f, + 0x3d3f, 0x3d40, 0x3d40, 0x3d40, 0x3d41, 0x3d41, 0x3d41, 0x3d42, + 0x3d42, 0x3d42, 0x3d43, 0x3d43, 0x3d43, 0x3d44, 0x3d44, 0x3d44, + 0x3d45, 0x3d45, 0x3d45, 0x3d46, 0x3d46, 0x3d46, 0x3d47, 0x3d47, + 0x3d47, 0x3d48, 0x3d48, 0x3d48, 0x3d49, 0x3d49, 0x3d49, 0x3d4a, + 0x3d4a, 0x3d4a, 0x3d4b, 0x3d4b, 0x3d4b, 0x3d4c, 0x3d4c, 0x3d4c, + 0x3d4d, 0x3d4d, 0x3d4d, 0x3d4e, 0x3d4e, 0x3d4e, 0x3d4f, 0x3d4f, + 0x3d4f, 0x3d50, 0x3d50, 0x3d50, 0x3d51, 0x3d51, 0x3d51, 0x3d52, + 0x3d52, 0x3d52, 0x3d53, 0x3d53, 0x3d53, 0x3d54, 0x3d54, 0x3d54, + 0x3d55, 0x3d55, 0x3d55, 0x3d56, 0x3d56, 0x3d56, 0x3d57, 0x3d57, + 0x3d57, 0x3d58, 0x3d58, 0x3d58, 0x3d59, 0x3d59, 0x3d59, 0x3d5a, + 0x3d5a, 0x3d5a, 0x3d5b, 0x3d5b, 0x3d5b, 0x3d5c, 0x3d5c, 0x3d5c, + 0x3d5d, 0x3d5d, 0x3d5d, 0x3d5e, 0x3d5e, 0x3d5e, 0x3d5f, 0x3d5f, + 0x3d5f, 0x3d60, 0x3d60, 0x3d60, 0x3d61, 0x3d61, 0x3d61, 0x3d62, + 0x3d62, 0x3d62, 0x3d63, 0x3d63, 0x3d63, 0x3d64, 0x3d64, 0x3d64, + 0x3d65, 0x3d65, 0x3d65, 0x3d66, 0x3d66, 0x3d66, 0x3d67, 0x3d67, + 0x3d67, 0x3d68, 0x3d68, 0x3d68, 0x3d69, 0x3d69, 0x3d69, 0x3d6a, + 0x3d6a, 0x3d6a, 0x3d6b, 0x3d6b, 0x3d6b, 0x3d6c, 0x3d6c, 0x3d6c, + 0x3d6d, 0x3d6d, 0x3d6d, 0x3d6e, 0x3d6e, 0x3d6e, 0x3d6f, 0x3d6f, + 0x3d6f, 0x3d70, 0x3d70, 0x3d70, 0x3d71, 0x3d71, 0x3d72, 0x3d72, + 0x3d72, 0x3d73, 0x3d73, 0x3d73, 0x3d74, 0x3d74, 0x3d74, 0x3d75, + 0x3d75, 0x3d75, 0x3d76, 0x3d76, 0x3d76, 0x3d77, 0x3d77, 0x3d77, + 0x3d78, 0x3d78, 0x3d78, 0x3d79, 0x3d79, 0x3d79, 0x3d7a, 0x3d7a, + 0x3d7a, 0x3d7b, 0x3d7b, 0x3d7b, 0x3d7c, 0x3d7c, 0x3d7c, 0x3d7d, + 0x3d7d, 0x3d7d, 0x3d7e, 0x3d7e, 0x3d7e, 0x3d7f, 0x3d7f, 0x3d80, + 0x3d80, 0x3d80, 0x3d81, 0x3d81, 0x3d81, 0x3d82, 0x3d82, 0x3d82, + 0x3d83, 0x3d83, 0x3d83, 0x3d84, 0x3d84, 0x3d84, 0x3d85, 0x3d85, + 0x3d85, 0x3d86, 0x3d86, 0x3d86, 0x3d87, 0x3d87, 0x3d87, 0x3d88, + 0x3d88, 0x3d88, 0x3d89, 0x3d89, 0x3d8a, 0x3d8a, 0x3d8a, 0x3d8b, + 0x3d8b, 0x3d8b, 0x3d8c, 0x3d8c, 0x3d8c, 0x3d8d, 0x3d8d, 0x3d8d, + 0x3d8e, 0x3d8e, 0x3d8e, 0x3d8f, 0x3d8f, 0x3d8f, 0x3d90, 0x3d90, + 0x3d90, 0x3d91, 0x3d91, 0x3d92, 0x3d92, 0x3d92, 0x3d93, 0x3d93, + 0x3d93, 0x3d94, 0x3d94, 0x3d94, 0x3d95, 0x3d95, 0x3d95, 0x3d96, + 0x3d96, 0x3d96, 0x3d97, 0x3d97, 0x3d97, 0x3d98, 0x3d98, 0x3d98, + 0x3d99, 0x3d99, 0x3d9a, 0x3d9a, 0x3d9a, 0x3d9b, 0x3d9b, 0x3d9b, + 0x3d9c, 0x3d9c, 0x3d9c, 0x3d9d, 0x3d9d, 0x3d9d, 0x3d9e, 0x3d9e, + 0x3d9e, 0x3d9f, 0x3d9f, 0x3d9f, 0x3da0, 0x3da0, 0x3da1, 0x3da1, + 0x3da1, 0x3da2, 0x3da2, 0x3da2, 0x3da3, 0x3da3, 0x3da3, 0x3da4, + 0x3da4, 0x3da4, 0x3da5, 0x3da5, 0x3da5, 0x3da6, 0x3da6, 0x3da7, + 0x3da7, 0x3da7, 0x3da8, 0x3da8, 0x3da8, 0x3da9, 0x3da9, 0x3da9, + 0x3daa, 0x3daa, 0x3daa, 0x3dab, 0x3dab, 0x3dab, 0x3dac, 0x3dac, + 0x3dad, 0x3dad, 0x3dad, 0x3dae, 0x3dae, 0x3dae, 0x3daf, 0x3daf, + 0x3daf, 0x3db0, 0x3db0, 0x3db0, 0x3db1, 0x3db1, 0x3db2, 0x3db2, + 0x3db2, 0x3db3, 0x3db3, 0x3db3, 0x3db4, 0x3db4, 0x3db4, 0x3db5, + 0x3db5, 0x3db5, 0x3db6, 0x3db6, 0x3db7, 0x3db7, 0x3db7, 0x3db8, + 0x3db8, 0x3db8, 0x3db9, 0x3db9, 0x3db9, 0x3dba, 0x3dba, 0x3dba, + 0x3dbb, 0x3dbb, 0x3dbc, 0x3dbc, 0x3dbc, 0x3dbd, 0x3dbd, 0x3dbd, + 0x3dbe, 0x3dbe, 0x3dbe, 0x3dbf, 0x3dbf, 0x3dbf, 0x3dc0, 0x3dc0, + 0x3dc1, 0x3dc1, 0x3dc1, 0x3dc2, 0x3dc2, 0x3dc2, 0x3dc3, 0x3dc3, + 0x3dc3, 0x3dc4, 0x3dc4, 0x3dc5, 0x3dc5, 0x3dc5, 0x3dc6, 0x3dc6, + 0x3dc6, 0x3dc7, 0x3dc7, 0x3dc7, 0x3dc8, 0x3dc8, 0x3dc8, 0x3dc9, + 0x3dc9, 0x3dca, 0x3dca, 0x3dca, 0x3dcb, 0x3dcb, 0x3dcb, 0x3dcc, + 0x3dcc, 0x3dcc, 0x3dcd, 0x3dcd, 0x3dce, 0x3dce, 0x3dce, 0x3dcf, + 0x3dcf, 0x3dcf, 0x3dd0, 0x3dd0, 0x3dd0, 0x3dd1, 0x3dd1, 0x3dd2, + 0x3dd2, 0x3dd2, 0x3dd3, 0x3dd3, 0x3dd3, 0x3dd4, 0x3dd4, 0x3dd4, + 0x3dd5, 0x3dd5, 0x3dd6, 0x3dd6, 0x3dd6, 0x3dd7, 0x3dd7, 0x3dd7, + 0x3dd8, 0x3dd8, 0x3dd8, 0x3dd9, 0x3dd9, 0x3dda, 0x3dda, 0x3dda, + 0x3ddb, 0x3ddb, 0x3ddb, 0x3ddc, 0x3ddc, 0x3ddc, 0x3ddd, 0x3ddd, + 0x3dde, 0x3dde, 0x3dde, 0x3ddf, 0x3ddf, 0x3ddf, 0x3de0, 0x3de0, + 0x3de1, 0x3de1, 0x3de1, 0x3de2, 0x3de2, 0x3de2, 0x3de3, 0x3de3, + 0x3de3, 0x3de4, 0x3de4, 0x3de5, 0x3de5, 0x3de5, 0x3de6, 0x3de6, + 0x3de6, 0x3de7, 0x3de7, 0x3de8, 0x3de8, 0x3de8, 0x3de9, 0x3de9, + 0x3de9, 0x3dea, 0x3dea, 0x3dea, 0x3deb, 0x3deb, 0x3dec, 0x3dec, + 0x3dec, 0x3ded, 0x3ded, 0x3ded, 0x3dee, 0x3dee, 0x3def, 0x3def, + 0x3def, 0x3df0, 0x3df0, 0x3df0, 0x3df1, 0x3df1, 0x3df2, 0x3df2, + 0x3df2, 0x3df3, 0x3df3, 0x3df3, 0x3df4, 0x3df4, 0x3df4, 0x3df5, + 0x3df5, 0x3df6, 0x3df6, 0x3df6, 0x3df7, 0x3df7, 0x3df7, 0x3df8, + 0x3df8, 0x3df9, 0x3df9, 0x3df9, 0x3dfa, 0x3dfa, 0x3dfa, 0x3dfb, + 0x3dfb, 0x3dfc, 0x3dfc, 0x3dfc, 0x3dfd, 0x3dfd, 0x3dfd, 0x3dfe, + 0x3dfe, 0x3dff, 0x3dff, 0x3dff, 0x3e00, 0x3e00, 0x3e00, 0x3e01, + 0x3e01, 0x3e02, 0x3e02, 0x3e02, 0x3e03, 0x3e03, 0x3e03, 0x3e04, + 0x3e04, 0x3e05, 0x3e05, 0x3e05, 0x3e06, 0x3e06, 0x3e06, 0x3e07, + 0x3e07, 0x3e08, 0x3e08, 0x3e08, 0x3e09, 0x3e09, 0x3e09, 0x3e0a, + 0x3e0a, 0x3e0b, 0x3e0b, 0x3e0b, 0x3e0c, 0x3e0c, 0x3e0d, 0x3e0d, + 0x3e0d, 0x3e0e, 0x3e0e, 0x3e0e, 0x3e0f, 0x3e0f, 0x3e10, 0x3e10, + 0x3e10, 0x3e11, 0x3e11, 0x3e11, 0x3e12, 0x3e12, 0x3e13, 0x3e13, + 0x3e13, 0x3e14, 0x3e14, 0x3e14, 0x3e15, 0x3e15, 0x3e16, 0x3e16, + 0x3e16, 0x3e17, 0x3e17, 0x3e18, 0x3e18, 0x3e18, 0x3e19, 0x3e19, + 0x3e19, 0x3e1a, 0x3e1a, 0x3e1b, 0x3e1b, 0x3e1b, 0x3e1c, 0x3e1c, + 0x3e1c, 0x3e1d, 0x3e1d, 0x3e1e, 0x3e1e, 0x3e1e, 0x3e1f, 0x3e1f, + 0x3e20, 0x3e20, 0x3e20, 0x3e21, 0x3e21, 0x3e21, 0x3e22, 0x3e22, + 0x3e23, 0x3e23, 0x3e23, 0x3e24, 0x3e24, 0x3e25, 0x3e25, 0x3e25, + 0x3e26, 0x3e26, 0x3e26, 0x3e27, 0x3e27, 0x3e28, 0x3e28, 0x3e28, + 0x3e29, 0x3e29, 0x3e2a, 0x3e2a, 0x3e2a, 0x3e2b, 0x3e2b, 0x3e2b, + 0x3e2c, 0x3e2c, 0x3e2d, 0x3e2d, 0x3e2d, 0x3e2e, 0x3e2e, 0x3e2f, + 0x3e2f, 0x3e2f, 0x3e30, 0x3e30, 0x3e30, 0x3e31, 0x3e31, 0x3e32, + 0x3e32, 0x3e32, 0x3e33, 0x3e33, 0x3e34, 0x3e34, 0x3e34, 0x3e35, + 0x3e35, 0x3e35, 0x3e36, 0x3e36, 0x3e37, 0x3e37, 0x3e37, 0x3e38, + 0x3e38, 0x3e39, 0x3e39, 0x3e39, 0x3e3a, 0x3e3a, 0x3e3b, 0x3e3b, + 0x3e3b, 0x3e3c, 0x3e3c, 0x3e3c, 0x3e3d, 0x3e3d, 0x3e3e, 0x3e3e, + 0x3e3e, 0x3e3f, 0x3e3f, 0x3e40, 0x3e40, 0x3e40, 0x3e41, 0x3e41, + 0x3e42, 0x3e42, 0x3e42, 0x3e43, 0x3e43, 0x3e44, 0x3e44, 0x3e44, + 0x3e45, 0x3e45, 0x3e45, 0x3e46, 0x3e46, 0x3e47, 0x3e47, 0x3e47, + 0x3e48, 0x3e48, 0x3e49, 0x3e49, 0x3e49, 0x3e4a, 0x3e4a, 0x3e4b, + 0x3e4b, 0x3e4b, 0x3e4c, 0x3e4c, 0x3e4d, 0x3e4d, 0x3e4d, 0x3e4e, + 0x3e4e, 0x3e4f, 0x3e4f, 0x3e4f, 0x3e50, 0x3e50, 0x3e50, 0x3e51, + 0x3e51, 0x3e52, 0x3e52, 0x3e52, 0x3e53, 0x3e53, 0x3e54, 0x3e54, + 0x3e54, 0x3e55, 0x3e55, 0x3e56, 0x3e56, 0x3e56, 0x3e57, 0x3e57, + 0x3e58, 0x3e58, 0x3e58, 0x3e59, 0x3e59, 0x3e5a, 0x3e5a, 0x3e5a, + 0x3e5b, 0x3e5b, 0x3e5c, 0x3e5c, 0x3e5c, 0x3e5d, 0x3e5d, 0x3e5e, + 0x3e5e, 0x3e5e, 0x3e5f, 0x3e5f, 0x3e60, 0x3e60, 0x3e60, 0x3e61, + 0x3e61, 0x3e62, 0x3e62, 0x3e62, 0x3e63, 0x3e63, 0x3e64, 0x3e64, + 0x3e64, 0x3e65, 0x3e65, 0x3e66, 0x3e66, 0x3e66, 0x3e67, 0x3e67, + 0x3e68, 0x3e68, 0x3e68, 0x3e69, 0x3e69, 0x3e6a, 0x3e6a, 0x3e6a, + 0x3e6b, 0x3e6b, 0x3e6c, 0x3e6c, 0x3e6c, 0x3e6d, 0x3e6d, 0x3e6e, + 0x3e6e, 0x3e6e, 0x3e6f, 0x3e6f, 0x3e70, 0x3e70, 0x3e70, 0x3e71, + 0x3e71, 0x3e72, 0x3e72, 0x3e72, 0x3e73, 0x3e73, 0x3e74, 0x3e74, + 0x3e74, 0x3e75, 0x3e75, 0x3e76, 0x3e76, 0x3e76, 0x3e77, 0x3e77, + 0x3e78, 0x3e78, 0x3e78, 0x3e79, 0x3e79, 0x3e7a, 0x3e7a, 0x3e7a, + 0x3e7b, 0x3e7b, 0x3e7c, 0x3e7c, 0x3e7c, 0x3e7d, 0x3e7d, 0x3e7e, + 0x3e7e, 0x3e7f, 0x3e7f, 0x3e7f, 0x3e80, 0x3e80, 0x3e81, 0x3e81, + 0x3e81, 0x3e82, 0x3e82, 0x3e83, 0x3e83, 0x3e83, 0x3e84, 0x3e84, + 0x3e85, 0x3e85, 0x3e85, 0x3e86, 0x3e86, 0x3e87, 0x3e87, 0x3e87, + 0x3e88, 0x3e88, 0x3e89, 0x3e89, 0x3e8a, 0x3e8a, 0x3e8a, 0x3e8b, + 0x3e8b, 0x3e8c, 0x3e8c, 0x3e8c, 0x3e8d, 0x3e8d, 0x3e8e, 0x3e8e, + 0x3e8e, 0x3e8f, 0x3e8f, 0x3e90, 0x3e90, 0x3e90, 0x3e91, 0x3e91, + 0x3e92, 0x3e92, 0x3e93, 0x3e93, 0x3e93, 0x3e94, 0x3e94, 0x3e95, + 0x3e95, 0x3e95, 0x3e96, 0x3e96, 0x3e97, 0x3e97, 0x3e97, 0x3e98, + 0x3e98, 0x3e99, 0x3e9a, 0x3e9b, 0x3e9c, 0x3e9c, 0x3e9d, 0x3e9e, + 0x3e9f, 0x3ea0, 0x3ea1, 0x3ea1, 0x3ea2, 0x3ea3, 0x3ea4, 0x3ea5, + 0x3ea6, 0x3ea6, 0x3ea7, 0x3ea8, 0x3ea9, 0x3eaa, 0x3eab, 0x3eab, + 0x3eac, 0x3ead, 0x3eae, 0x3eaf, 0x3eb0, 0x3eb0, 0x3eb1, 0x3eb2, + 0x3eb3, 0x3eb4, 0x3eb5, 0x3eb5, 0x3eb6, 0x3eb7, 0x3eb8, 0x3eb9, + 0x3eba, 0x3eba, 0x3ebb, 0x3ebc, 0x3ebd, 0x3ebe, 0x3ebf, 0x3ebf, + 0x3ec0, 0x3ec1, 0x3ec2, 0x3ec3, 0x3ec4, 0x3ec5, 0x3ec5, 0x3ec6, + 0x3ec7, 0x3ec8, 0x3ec9, 0x3eca, 0x3eca, 0x3ecb, 0x3ecc, 0x3ecd, + 0x3ece, 0x3ecf, 0x3ed0, 0x3ed0, 0x3ed1, 0x3ed2, 0x3ed3, 0x3ed4, + 0x3ed5, 0x3ed6, 0x3ed6, 0x3ed7, 0x3ed8, 0x3ed9, 0x3eda, 0x3edb, + 0x3edc, 0x3edc, 0x3edd, 0x3ede, 0x3edf, 0x3ee0, 0x3ee1, 0x3ee2, + 0x3ee2, 0x3ee3, 0x3ee4, 0x3ee5, 0x3ee6, 0x3ee7, 0x3ee8, 0x3ee8, + 0x3ee9, 0x3eea, 0x3eeb, 0x3eec, 0x3eed, 0x3eee, 0x3eef, 0x3eef, + 0x3ef0, 0x3ef1, 0x3ef2, 0x3ef3, 0x3ef4, 0x3ef5, 0x3ef5, 0x3ef6, + 0x3ef7, 0x3ef8, 0x3ef9, 0x3efa, 0x3efb, 0x3efc, 0x3efc, 0x3efd, + 0x3efe, 0x3eff, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f03, 0x3f04, + 0x3f05, 0x3f06, 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0a, 0x3f0b, + 0x3f0c, 0x3f0d, 0x3f0e, 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f12, + 0x3f13, 0x3f14, 0x3f15, 0x3f16, 0x3f17, 0x3f18, 0x3f19, 0x3f19, + 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e, 0x3f1f, 0x3f20, 0x3f21, + 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, 0x3f27, 0x3f28, + 0x3f29, 0x3f2a, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, 0x3f2f, + 0x3f30, 0x3f31, 0x3f32, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, + 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3c, 0x3f3d, + 0x3f3e, 0x3f3f, 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, + 0x3f45, 0x3f46, 0x3f47, 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, + 0x3f4d, 0x3f4e, 0x3f4f, 0x3f50, 0x3f50, 0x3f51, 0x3f52, 0x3f53, + 0x3f54, 0x3f55, 0x3f56, 0x3f57, 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, + 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, 0x3f60, 0x3f61, 0x3f62, + 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f66, 0x3f67, 0x3f68, 0x3f69, + 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, 0x3f70, 0x3f71, + 0x3f72, 0x3f73, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, 0x3f78, + 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f, 0x3f80, + 0x3f81, 0x3f82, 0x3f82, 0x3f83, 0x3f84, 0x3f85, 0x3f86, 0x3f87, + 0x3f88, 0x3f89, 0x3f8a, 0x3f8b, 0x3f8c, 0x3f8d, 0x3f8e, 0x3f8f, + 0x3f90, 0x3f91, 0x3f92, 0x3f92, 0x3f93, 0x3f94, 0x3f95, 0x3f96, + 0x3f97, 0x3f98, 0x3f99, 0x3f9a, 0x3f9b, 0x3f9c, 0x3f9d, 0x3f9e, + 0x3f9f, 0x3fa0, 0x3fa1, 0x3fa2, 0x3fa3, 0x3fa4, 0x3fa5, 0x3fa5, + 0x3fa6, 0x3fa7, 0x3fa8, 0x3fa9, 0x3faa, 0x3fab, 0x3fac, 0x3fad, + 0x3fae, 0x3faf, 0x3fb0, 0x3fb1, 0x3fb2, 0x3fb3, 0x3fb4, 0x3fb5, + 0x3fb6, 0x3fb7, 0x3fb8, 0x3fb9, 0x3fba, 0x3fbb, 0x3fbc, 0x3fbd, + 0x3fbe, 0x3fbf, 0x3fbf, 0x3fc0, 0x3fc1, 0x3fc2, 0x3fc3, 0x3fc4, + 0x3fc5, 0x3fc6, 0x3fc7, 0x3fc8, 0x3fc9, 0x3fca, 0x3fcb, 0x3fcc, + 0x3fcd, 0x3fce, 0x3fcf, 0x3fd0, 0x3fd1, 0x3fd2, 0x3fd3, 0x3fd4, + 0x3fd5, 0x3fd6, 0x3fd7, 0x3fd8, 0x3fd9, 0x3fda, 0x3fdb, 0x3fdc, + 0x3fdd, 0x3fde, 0x3fdf, 0x3fe0, 0x3fe1, 0x3fe2, 0x3fe3, 0x3fe4, + 0x3fe5, 0x3fe6, 0x3fe7, 0x3fe8, 0x3fe9, 0x3fea, 0x3feb, 0x3fec, + 0x3fed, 0x3fee, 0x3fef, 0x3ff0, 0x3ff0, 0x3ff1, 0x3ff2, 0x3ff3, + 0x3ff4, 0x3ff5, 0x3ff6, 0x3ff7, 0x3ff8, 0x3ff9, 0x3ffa, 0x3ffb, + 0x3ffc, 0x3ffd, 0x3ffe, 0x3fff, 0x4000, 0x4001, 0x4001, 0x4002, + 0x4002, 0x4003, 0x4003, 0x4004, 0x4004, 0x4005, 0x4005, 0x4006, + 0x4006, 0x4007, 0x4007, 0x4008, 0x4008, 0x4009, 0x4009, 0x400a, + 0x400a, 0x400b, 0x400b, 0x400c, 0x400c, 0x400d, 0x400d, 0x400e, + 0x400e, 0x400f, 0x400f, 0x4010, 0x4010, 0x4011, 0x4011, 0x4012, + 0x4012, 0x4013, 0x4013, 0x4014, 0x4014, 0x4015, 0x4015, 0x4016, + 0x4016, 0x4017, 0x4017, 0x4018, 0x4019, 0x4019, 0x401a, 0x401a, + 0x401b, 0x401b, 0x401c, 0x401c, 0x401d, 0x401d, 0x401e, 0x401e, + 0x401f, 0x401f, 0x4020, 0x4020, 0x4021, 0x4021, 0x4022, 0x4022, + 0x4023, 0x4023, 0x4024, 0x4024, 0x4025, 0x4025, 0x4026, 0x4026, + 0x4027, 0x4027, 0x4028, 0x4028, 0x4029, 0x402a, 0x402a, 0x402b, + 0x402b, 0x402c, 0x402c, 0x402d, 0x402d, 0x402e, 0x402e, 0x402f, + 0x402f, 0x4030, 0x4030, 0x4031, 0x4031, 0x4032, 0x4032, 0x4033, + 0x4033, 0x4034, 0x4035, 0x4035, 0x4036, 0x4036, 0x4037, 0x4037, + 0x4038, 0x4038, 0x4039, 0x4039, 0x403a, 0x403a, 0x403b, 0x403b, + 0x403c, 0x403c, 0x403d, 0x403d, 0x403e, 0x403f, 0x403f, 0x4040, + 0x4040, 0x4041, 0x4041, 0x4042, 0x4042, 0x4043, 0x4043, 0x4044, + 0x4044, 0x4045, 0x4045, 0x4046, 0x4047, 0x4047, 0x4048, 0x4048, + 0x4049, 0x4049, 0x404a, 0x404a, 0x404b, 0x404b, 0x404c, 0x404c, + 0x404d, 0x404e, 0x404e, 0x404f, 0x404f, 0x4050, 0x4050, 0x4051, + 0x4051, 0x4052, 0x4052, 0x4053, 0x4053, 0x4054, 0x4055, 0x4055, + 0x4056, 0x4056, 0x4057, 0x4057, 0x4058, 0x4058, 0x4059, 0x4059, + 0x405a, 0x405a, 0x405b, 0x405c, 0x405c, 0x405d, 0x405d, 0x405e, + 0x405e, 0x405f, 0x405f, 0x4060, 0x4060, 0x4061, 0x4062, 0x4062, + 0x4063, 0x4063, 0x4064, 0x4064, 0x4065, 0x4065, 0x4066, 0x4067, + 0x4067, 0x4068, 0x4068, 0x4069, 0x4069, 0x406a, 0x406a, 0x406b, + 0x406b, 0x406c, 0x406d, 0x406d, 0x406e, 0x406e, 0x406f, 0x406f, + 0x4070, 0x4070, 0x4071, 0x4072, 0x4072, 0x4073, 0x4073, 0x4074, + 0x4074, 0x4075, 0x4075, 0x4076, 0x4077, 0x4077, 0x4078, 0x4078, + 0x4079, 0x4079, 0x407a, 0x407b, 0x407b, 0x407c, 0x407c, 0x407d, + 0x407d, 0x407e, 0x407e, 0x407f, 0x4080, 0x4080, 0x4081, 0x4081, + 0x4082, 0x4082, 0x4083, 0x4084, 0x4084, 0x4085, 0x4085, 0x4086, + 0x4086, 0x4087, 0x4087, 0x4088, 0x4089, 0x4089, 0x408a, 0x408a, + 0x408b, 0x408b, 0x408c, 0x408d, 0x408d, 0x408e, 0x408e, 0x408f, + 0x408f, 0x4090, 0x4091, 0x4091, 0x4092, 0x4092, 0x4093, 0x4093, + 0x4094, 0x4095, 0x4095, 0x4096, 0x4096, 0x4097, 0x4097, 0x4098, + 0x4099, 0x4099, 0x409a, 0x409a, 0x409b, 0x409b, 0x409c, 0x409d, + 0x409d, 0x409e, 0x409e, 0x409f, 0x409f, 0x40a0, 0x40a1, 0x40a1, + 0x40a2, 0x40a2, 0x40a3, 0x40a4, 0x40a4, 0x40a5, 0x40a5, 0x40a6, + 0x40a6, 0x40a7, 0x40a8, 0x40a8, 0x40a9, 0x40a9, 0x40aa, 0x40ab, + 0x40ab, 0x40ac, 0x40ac, 0x40ad, 0x40ad, 0x40ae, 0x40af, 0x40af, + 0x40b0, 0x40b0, 0x40b1, 0x40b2, 0x40b2, 0x40b3, 0x40b3, 0x40b4, + 0x40b4, 0x40b5, 0x40b6, 0x40b6, 0x40b7, 0x40b7, 0x40b8, 0x40b9, + 0x40b9, 0x40ba, 0x40ba, 0x40bb, 0x40bc, 0x40bc, 0x40bd, 0x40bd, + 0x40be, 0x40bf, 0x40bf, 0x40c0, 0x40c0, 0x40c1, 0x40c1, 0x40c2, + 0x40c3, 0x40c3, 0x40c4, 0x40c4, 0x40c5, 0x40c6, 0x40c6, 0x40c7, + 0x40c7, 0x40c8, 0x40c9, 0x40c9, 0x40ca, 0x40ca, 0x40cb, 0x40cc, + 0x40cc, 0x40cd, 0x40cd, 0x40ce, 0x40cf, 0x40cf, 0x40d0, 0x40d0, + 0x40d1, 0x40d2, 0x40d2, 0x40d3, 0x40d3, 0x40d4, 0x40d5, 0x40d5, + 0x40d6, 0x40d6, 0x40d7, 0x40d8, 0x40d8, 0x40d9, 0x40d9, 0x40da, + 0x40db, 0x40db, 0x40dc, 0x40dd, 0x40dd, 0x40de, 0x40de, 0x40df, + 0x40e0, 0x40e0, 0x40e1, 0x40e1, 0x40e2, 0x40e3, 0x40e3, 0x40e4, + 0x40e4, 0x40e5, 0x40e6, 0x40e6, 0x40e7, 0x40e8, 0x40e8, 0x40e9, + 0x40e9, 0x40ea, 0x40eb, 0x40eb, 0x40ec, 0x40ec, 0x40ed, 0x40ee, + 0x40ee, 0x40ef, 0x40f0, 0x40f0, 0x40f1, 0x40f1, 0x40f2, 0x40f3, + 0x40f3, 0x40f4, 0x40f4, 0x40f5, 0x40f6, 0x40f6, 0x40f7, 0x40f8, + 0x40f8, 0x40f9, 0x40f9, 0x40fa, 0x40fb, 0x40fb, 0x40fc, 0x40fd, + 0x40fd, 0x40fe, 0x40fe, 0x40ff, 0x4100, 0x4100, 0x4101, 0x4102, + 0x4102, 0x4103, 0x4103, 0x4104, 0x4105, 0x4105, 0x4106, 0x4107, + 0x4107, 0x4108, 0x4108, 0x4109, 0x410a, 0x410a, 0x410b, 0x410c, + 0x410c, 0x410d, 0x410d, 0x410e, 0x410f, 0x410f, 0x4110, 0x4111, + 0x4111, 0x4112, 0x4113, 0x4113, 0x4114, 0x4114, 0x4115, 0x4116, + 0x4116, 0x4117, 0x4118, 0x4118, 0x4119, 0x411a, 0x411a, 0x411b, + 0x411b, 0x411c, 0x411d, 0x411d, 0x411e, 0x411f, 0x411f, 0x4120, + 0x4121, 0x4121, 0x4122, 0x4122, 0x4123, 0x4124, 0x4124, 0x4125, + 0x4126, 0x4126, 0x4127, 0x4128, 0x4128, 0x4129, 0x412a, 0x412a, + 0x412b, 0x412b, 0x412c, 0x412d, 0x412d, 0x412e, 0x412f, 0x412f, + 0x4130, 0x4131, 0x4131, 0x4132, 0x4133, 0x4133, 0x4134, 0x4135, + 0x4135, 0x4136, 0x4137, 0x4137, 0x4138, 0x4138, 0x4139, 0x413a, + 0x413a, 0x413b, 0x413c, 0x413c, 0x413d, 0x413e, 0x413e, 0x413f, + 0x4140, 0x4140, 0x4141, 0x4142, 0x4142, 0x4143, 0x4144, 0x4144, + 0x4145, 0x4146, 0x4146, 0x4147, 0x4148, 0x4148, 0x4149, 0x414a, + 0x414a, 0x414b, 0x414c, 0x414c, 0x414d, 0x414e, 0x414e, 0x414f, + 0x4150, 0x4150, 0x4151, 0x4152, 0x4152, 0x4153, 0x4154, 0x4154, + 0x4155, 0x4156, 0x4156, 0x4157, 0x4158, 0x4158, 0x4159, 0x415a, + 0x415a, 0x415b, 0x415c, 0x415c, 0x415d, 0x415e, 0x415e, 0x415f, + 0x4160, 0x4160, 0x4161, 0x4162, 0x4162, 0x4163, 0x4164, 0x4164, + 0x4165, 0x4166, 0x4166, 0x4167, 0x4168, 0x4168, 0x4169, 0x416a, + 0x416a, 0x416b, 0x416c, 0x416c, 0x416d, 0x416e, 0x416e, 0x416f, + 0x4170, 0x4171, 0x4172, 0x4174, 0x4175, 0x4177, 0x4178, 0x4179, + 0x417b, 0x417c, 0x417d, 0x417f, 0x4180, 0x4182, 0x4183, 0x4184, + 0x4186, 0x4187, 0x4188, 0x418a, 0x418b, 0x418d, 0x418e, 0x418f, + 0x4191, 0x4192, 0x4194, 0x4195, 0x4196, 0x4198, 0x4199, 0x419b, + 0x419c, 0x419d, 0x419f, 0x41a0, 0x41a2, 0x41a3, 0x41a4, 0x41a6, + 0x41a7, 0x41a9, 0x41aa, 0x41ab, 0x41ad, 0x41ae, 0x41b0, 0x41b1, + 0x41b3, 0x41b4, 0x41b5, 0x41b7, 0x41b8, 0x41ba, 0x41bb, 0x41bd, + 0x41be, 0x41bf, 0x41c1, 0x41c2, 0x41c4, 0x41c5, 0x41c7, 0x41c8, + 0x41ca, 0x41cb, 0x41cc, 0x41ce, 0x41cf, 0x41d1, 0x41d2, 0x41d4, + 0x41d5, 0x41d7, 0x41d8, 0x41da, 0x41db, 0x41dc, 0x41de, 0x41df, + 0x41e1, 0x41e2, 0x41e4, 0x41e5, 0x41e7, 0x41e8, 0x41ea, 0x41eb, + 0x41ed, 0x41ee, 0x41f0, 0x41f1, 0x41f3, 0x41f4, 0x41f6, 0x41f7, + 0x41f9, 0x41fa, 0x41fc, 0x41fd, 0x41ff, 0x4200, 0x4202, 0x4203, + 0x4205, 0x4206, 0x4208, 0x4209, 0x420b, 0x420c, 0x420e, 0x420f, + 0x4211, 0x4212, 0x4214, 0x4215, 0x4217, 0x4218, 0x421a, 0x421b, + 0x421d, 0x421e, 0x4220, 0x4221, 0x4223, 0x4224, 0x4226, 0x4228, + 0x4229, 0x422b, 0x422c, 0x422e, 0x422f, 0x4231, 0x4232, 0x4234, + 0x4235, 0x4237, 0x4239, 0x423a, 0x423c, 0x423d, 0x423f, 0x4240, + 0x4242, 0x4243, 0x4245, 0x4247, 0x4248, 0x424a, 0x424b, 0x424d, + 0x424e, 0x4250, 0x4252, 0x4253, 0x4255, 0x4256, 0x4258, 0x425a, + 0x425b, 0x425d, 0x425e, 0x4260, 0x4262, 0x4263, 0x4265, 0x4266, + 0x4268, 0x4269, 0x426b, 0x426d, 0x426e, 0x4270, 0x4272, 0x4273, + 0x4275, 0x4276, 0x4278, 0x427a, 0x427b, 0x427d, 0x427e, 0x4280, + 0x4282, 0x4283, 0x4285, 0x4287, 0x4288, 0x428a, 0x428c, 0x428d, + 0x428f, 0x4290, 0x4292, 0x4294, 0x4295, 0x4297, 0x4299, 0x429a, + 0x429c, 0x429e, 0x429f, 0x42a1, 0x42a3, 0x42a4, 0x42a6, 0x42a8, + 0x42a9, 0x42ab, 0x42ad, 0x42ae, 0x42b0, 0x42b2, 0x42b3, 0x42b5, + 0x42b7, 0x42b8, 0x42ba, 0x42bc, 0x42bd, 0x42bf, 0x42c1, 0x42c2, + 0x42c4, 0x42c6, 0x42c7, 0x42c9, 0x42cb, 0x42cd, 0x42ce, 0x42d0, + 0x42d2, 0x42d3, 0x42d5, 0x42d7, 0x42d8, 0x42da, 0x42dc, 0x42de, + 0x42df, 0x42e1, 0x42e3, 0x42e5, 0x42e6, 0x42e8, 0x42ea, 0x42eb, + 0x42ed, 0x42ef, 0x42f1, 0x42f2, 0x42f4, 0x42f6, 0x42f8, 0x42f9, + 0x42fb, 0x42fd, 0x42ff, 0x4300, 0x4302, 0x4304, 0x4306, 0x4307, + 0x4309, 0x430b, 0x430d, 0x430e, 0x4310, 0x4312, 0x4314, 0x4315, + 0x4317, 0x4319, 0x431b, 0x431d, 0x431e, 0x4320, 0x4322, 0x4324, + 0x4325, 0x4327, 0x4329, 0x432b, 0x432d, 0x432e, 0x4330, 0x4332, + 0x4334, 0x4336, 0x4337, 0x4339, 0x433b, 0x433d, 0x433f, 0x4340, + 0x4342, 0x4344, 0x4346, 0x4348, 0x434a, 0x434b, 0x434d, 0x434f, + 0x4351, 0x4353, 0x4354, 0x4356, 0x4358, 0x435a, 0x435c, 0x435e, + 0x4360, 0x4361, 0x4363, 0x4365, 0x4367, 0x4369, 0x436b, 0x436c, + 0x436e, 0x4370, 0x4372, 0x4374, 0x4376, 0x4378, 0x4379, 0x437b, + 0x437d, 0x437f, 0x4381, 0x4383, 0x4385, 0x4387, 0x4388, 0x438a, + 0x438c, 0x438e, 0x4390, 0x4392, 0x4394, 0x4396, 0x4398, 0x439a, + 0x439b, 0x439d, 0x439f, 0x43a1, 0x43a3, 0x43a5, 0x43a7, 0x43a9, + 0x43ab, 0x43ad, 0x43af, 0x43b0, 0x43b2, 0x43b4, 0x43b6, 0x43b8, + 0x43ba, 0x43bc, 0x43be, 0x43c0, 0x43c2, 0x43c4, 0x43c6, 0x43c8, + 0x43ca, 0x43cc, 0x43ce, 0x43cf, 0x43d1, 0x43d3, 0x43d5, 0x43d7, + 0x43d9, 0x43db, 0x43dd, 0x43df, 0x43e1, 0x43e3, 0x43e5, 0x43e7, + 0x43e9, 0x43eb, 0x43ed, 0x43ef, 0x43f1, 0x43f3, 0x43f5, 0x43f7, + 0x43f9, 0x43fb, 0x43fd, 0x43ff, 0x4400, 0x4401, 0x4402, 0x4403, + 0x4404, 0x4405, 0x4406, 0x4407, 0x4408, 0x4409, 0x440a, 0x440b, + 0x440d, 0x440e, 0x440f, 0x4410, 0x4411, 0x4412, 0x4413, 0x4414, + 0x4415, 0x4416, 0x4417, 0x4418, 0x4419, 0x441a, 0x441b, 0x441c, + 0x441d, 0x441e, 0x441f, 0x4420, 0x4421, 0x4422, 0x4423, 0x4424, + 0x4425, 0x4426, 0x4427, 0x4428, 0x4429, 0x442a, 0x442b, 0x442c, + 0x442d, 0x442e, 0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4435, + 0x4436, 0x4437, 0x4438, 0x4439, 0x443a, 0x443b, 0x443c, 0x443d, + 0x443e, 0x443f, 0x4440, 0x4441, 0x4443, 0x4444, 0x4445, 0x4446, + 0x4447, 0x4448, 0x4449, 0x444a, 0x444b, 0x444c, 0x444d, 0x444e, + 0x444f, 0x4450, 0x4452, 0x4453, 0x4454, 0x4455, 0x4456, 0x4457, + 0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, 0x445f, 0x4460, + 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4466, 0x4467, 0x4468, + 0x446a, 0x446b, 0x446c, 0x446d, 0x446e, 0x446f, 0x4470, 0x4471, + 0x4472, 0x4473, 0x4475, 0x4476, 0x4477, 0x4478, 0x4479, 0x447a, + 0x447b, 0x447c, 0x447e, 0x447f, 0x4480, 0x4481, 0x4482, 0x4483, + 0x4484, 0x4485, 0x4487, 0x4488, 0x4489, 0x448a, 0x448b, 0x448c, + 0x448d, 0x448f, 0x4490, 0x4491, 0x4492, 0x4493, 0x4494, 0x4495, + 0x4497, 0x4498, 0x4499, 0x449a, 0x449b, 0x449c, 0x449d, 0x449f, + 0x44a0, 0x44a1, 0x44a2, 0x44a3, 0x44a4, 0x44a6, 0x44a7, 0x44a8, + 0x44a9, 0x44aa, 0x44ab, 0x44ad, 0x44ae, 0x44af, 0x44b0, 0x44b1, + 0x44b2, 0x44b4, 0x44b5, 0x44b6, 0x44b7, 0x44b8, 0x44b9, 0x44bb, + 0x44bc, 0x44bd, 0x44be, 0x44bf, 0x44c1, 0x44c2, 0x44c3, 0x44c4, + 0x44c5, 0x44c7, 0x44c8, 0x44c9, 0x44ca, 0x44cb, 0x44cc, 0x44ce, + 0x44cf, 0x44d0, 0x44d1, 0x44d2, 0x44d4, 0x44d5, 0x44d6, 0x44d7, + 0x44d9, 0x44da, 0x44db, 0x44dc, 0x44dd, 0x44df, 0x44e0, 0x44e1, + 0x44e2, 0x44e3, 0x44e5, 0x44e6, 0x44e7, 0x44e8, 0x44ea, 0x44eb, + 0x44ec, 0x44ed, 0x44ef, 0x44f0, 0x44f1, 0x44f2, 0x44f3, 0x44f5, + 0x44f6, 0x44f7, 0x44f8, 0x44fa, 0x44fb, 0x44fc, 0x44fd, 0x44ff, + 0x4500, 0x4501, 0x4502, 0x4504, 0x4505, 0x4506, 0x4507, 0x4509, + 0x450a, 0x450b, 0x450c, 0x450e, 0x450f, 0x4510, 0x4512, 0x4513, + 0x4514, 0x4515, 0x4517, 0x4518, 0x4519, 0x451a, 0x451c, 0x451d, + 0x451e, 0x4520, 0x4521, 0x4522, 0x4523, 0x4525, 0x4526, 0x4527, + 0x4529, 0x452a, 0x452b, 0x452c, 0x452e, 0x452f, 0x4530, 0x4532, + 0x4533, 0x4534, 0x4536, 0x4537, 0x4538, 0x4539, 0x453b, 0x453c, + 0x453d, 0x453f, 0x4540, 0x4541, 0x4543, 0x4544, 0x4545, 0x4547, + 0x4548, 0x4549, 0x454b, 0x454c, 0x454d, 0x454e, 0x4550, 0x4551, + 0x4552, 0x4554, 0x4555, 0x4556, 0x4558, 0x4559, 0x455a, 0x455c, + 0x455d, 0x455e, 0x4560, 0x4561, 0x4563, 0x4564, 0x4565, 0x4567, + 0x4568, 0x4569, 0x456b, 0x456c, 0x456d, 0x456f, 0x4570, 0x4571, + 0x4573, 0x4574, 0x4576, 0x4577, 0x4578, 0x457a, 0x457b, 0x457c, + 0x457e, 0x457f, 0x4580, 0x4582, 0x4583, 0x4585, 0x4586, 0x4587, + 0x4589, 0x458a, 0x458c, 0x458d, 0x458e, 0x4590, 0x4591, 0x4592, + 0x4594, 0x4595, 0x4597, 0x4598, 0x4599, 0x459b, 0x459c, 0x459e, + 0x459f, 0x45a0, 0x45a2, 0x45a3, 0x45a5, 0x45a6, 0x45a8, 0x45a9, + 0x45aa, 0x45ac, 0x45ad, 0x45af, 0x45b0, 0x45b1, 0x45b3, 0x45b4, + 0x45b6, 0x45b7, 0x45b9, 0x45ba, 0x45bb, 0x45bd, 0x45be, 0x45c0, + 0x45c1, 0x45c3, 0x45c4, 0x45c6, 0x45c7, 0x45c8, 0x45ca, 0x45cb, + 0x45cd, 0x45ce, 0x45d0, 0x45d1, 0x45d3, 0x45d4, 0x45d5, 0x45d7, + 0x45d8, 0x45da, 0x45db, 0x45dd, 0x45de, 0x45e0, 0x45e1, 0x45e3, + 0x45e4, 0x45e6, 0x45e7, 0x45e9, 0x45ea, 0x45eb, 0x45ed, 0x45ee, + 0x45f0, 0x45f1, 0x45f3, 0x45f4, 0x45f6, 0x45f7, 0x45f9, 0x45fa, + 0x45fc, 0x45fd, 0x45ff, 0x4600, 0x4602, 0x4603, 0x4605, 0x4606, + 0x4608, 0x4609, 0x460b, 0x460c, 0x460e, 0x460f, 0x4611, 0x4612, + 0x4614, 0x4616, 0x4617, 0x4619, 0x461a, 0x461c, 0x461d, 0x461f, + 0x4620, 0x4622, 0x4623, 0x4625, 0x4626, 0x4628, 0x4629, 0x462b, + 0x462c, 0x462e, 0x4630, 0x4631, 0x4633, 0x4634, 0x4636, 0x4637, + 0x4639, 0x463a, 0x463c, 0x463e, 0x463f, 0x4641, 0x4642, 0x4644, + 0x4645, 0x4647, 0x4649, 0x464a, 0x464c, 0x464d, 0x464f, 0x4650, + 0x4652, 0x4654, 0x4655, 0x4657, 0x4658, 0x465a, 0x465b, 0x465d, + 0x465f, 0x4660, 0x4662, 0x4663, 0x4665, 0x4667, 0x4668, 0x466a, + 0x466b, 0x466d, 0x466f, 0x4670, 0x4672, 0x4673, 0x4675, 0x4677, + 0x4678, 0x467a, 0x467c, 0x467d, 0x467f, 0x4680, 0x4682, 0x4684, + 0x4685, 0x4687, 0x4689, 0x468a, 0x468c, 0x468e, 0x468f, 0x4691, + 0x4692, 0x4694, 0x4696, 0x4697, 0x4699, 0x469b, 0x469c, 0x469e, + 0x46a0, 0x46a1, 0x46a3, 0x46a5, 0x46a6, 0x46a8, 0x46aa, 0x46ab, + 0x46ad, 0x46af, 0x46b0, 0x46b2, 0x46b4, 0x46b5, 0x46b7, 0x46b9, + 0x46ba, 0x46bc, 0x46be, 0x46bf, 0x46c1, 0x46c3, 0x46c4, 0x46c6, + 0x46c8, 0x46ca, 0x46cb, 0x46cd, 0x46cf, 0x46d0, 0x46d2, 0x46d4, + 0x46d5, 0x46d7, 0x46d9, 0x46db, 0x46dc, 0x46de, 0x46e0, 0x46e1, + 0x46e3, 0x46e5, 0x46e7, 0x46e8, 0x46ea, 0x46ec, 0x46ee, 0x46ef, + 0x46f1, 0x46f3, 0x46f4, 0x46f6, 0x46f8, 0x46fa, 0x46fb, 0x46fd, + 0x46ff, 0x4701, 0x4702, 0x4704, 0x4706, 0x4708, 0x4709, 0x470b, + 0x470d, 0x470f, 0x4711, 0x4712, 0x4714, 0x4716, 0x4718, 0x4719, + 0x471b, 0x471d, 0x471f, 0x4720, 0x4722, 0x4724, 0x4726, 0x4728, + 0x4729, 0x472b, 0x472d, 0x472f, 0x4731, 0x4732, 0x4734, 0x4736, + 0x4738, 0x473a, 0x473b, 0x473d, 0x473f, 0x4741, 0x4743, 0x4744, + 0x4746, 0x4748, 0x474a, 0x474c, 0x474e, 0x474f, 0x4751, 0x4753, + 0x4755, 0x4757, 0x4759, 0x475a, 0x475c, 0x475e, 0x4760, 0x4762, + 0x4764, 0x4767, 0x476b, 0x476f, 0x4772, 0x4776, 0x477a, 0x477e, + 0x4781, 0x4785, 0x4789, 0x478d, 0x4790, 0x4794, 0x4798, 0x479c, + 0x47a0, 0x47a3, 0x47a7, 0x47ab, 0x47af, 0x47b3, 0x47b7, 0x47bb, + 0x47be, 0x47c2, 0x47c6, 0x47ca, 0x47ce, 0x47d2, 0x47d6, 0x47da, + 0x47de, 0x47e2, 0x47e5, 0x47e9, 0x47ed, 0x47f1, 0x47f5, 0x47f9, + 0x47fd, 0x4801, 0x4803, 0x4805, 0x4807, 0x4809, 0x480b, 0x480d, + 0x480f, 0x4811, 0x4813, 0x4815, 0x4817, 0x4819, 0x481b, 0x481d, + 0x481f, 0x4821, 0x4823, 0x4825, 0x4827, 0x4829, 0x482c, 0x482e, + 0x4830, 0x4832, 0x4834, 0x4836, 0x4838, 0x483a, 0x483c, 0x483e, + 0x4841, 0x4843, 0x4845, 0x4847, 0x4849, 0x484b, 0x484d, 0x4850, + 0x4852, 0x4854, 0x4856, 0x4858, 0x485a, 0x485d, 0x485f, 0x4861, + 0x4863, 0x4865, 0x4868, 0x486a, 0x486c, 0x486e, 0x4870, 0x4873, + 0x4875, 0x4877, 0x4879, 0x487c, 0x487e, 0x4880, 0x4882, 0x4885, + 0x4887, 0x4889, 0x488b, 0x488e, 0x4890, 0x4892, 0x4894, 0x4897, + 0x4899, 0x489b, 0x489e, 0x48a0, 0x48a2, 0x48a5, 0x48a7, 0x48a9, + 0x48ac, 0x48ae, 0x48b0, 0x48b3, 0x48b5, 0x48b7, 0x48ba, 0x48bc, + 0x48be, 0x48c1, 0x48c3, 0x48c6, 0x48c8, 0x48ca, 0x48cd, 0x48cf, + 0x48d2, 0x48d4, 0x48d6, 0x48d9, 0x48db, 0x48de, 0x48e0, 0x48e3, + 0x48e5, 0x48e7, 0x48ea, 0x48ec, 0x48ef, 0x48f1, 0x48f4, 0x48f6, + 0x48f9, 0x48fb, 0x48fe, 0x4900, 0x4903, 0x4905, 0x4908, 0x490a, + 0x490d, 0x490f, 0x4912, 0x4914, 0x4917, 0x4919, 0x491c, 0x491f, + 0x4921, 0x4924, 0x4926, 0x4929, 0x492b, 0x492e, 0x4931, 0x4933, + 0x4936, 0x4938, 0x493b, 0x493e, 0x4940, 0x4943, 0x4946, 0x4948, + 0x494b, 0x494d, 0x4950, 0x4953, 0x4955, 0x4958, 0x495b, 0x495d, + 0x4960, 0x4963, 0x4966, 0x4968, 0x496b, 0x496e, 0x4970, 0x4973, + 0x4976, 0x4979, 0x497b, 0x497e, 0x4981, 0x4984, 0x4986, 0x4989, + 0x498c, 0x498f, 0x4991, 0x4994, 0x4997, 0x499a, 0x499d, 0x499f, + 0x49a2, 0x49a5, 0x49a8, 0x49ab, 0x49ad, 0x49b0, 0x49b3, 0x49b6, + 0x49b9, 0x49bc, 0x49bf, 0x49c1, 0x49c4, 0x49c7, 0x49ca, 0x49cd, + 0x49d0, 0x49d3, 0x49d6, 0x49d9, 0x49dc, 0x49df, 0x49e1, 0x49e4, + 0x49e7, 0x49ea, 0x49ed, 0x49f0, 0x49f3, 0x49f6, 0x49f9, 0x49fc, + 0x49ff, 0x4a02, 0x4a05, 0x4a08, 0x4a0b, 0x4a0e, 0x4a11, 0x4a14, + 0x4a17, 0x4a1a, 0x4a1d, 0x4a21, 0x4a24, 0x4a27, 0x4a2a, 0x4a2d, + 0x4a30, 0x4a33, 0x4a36, 0x4a39, 0x4a3c, 0x4a3f, 0x4a43, 0x4a46, + 0x4a49, 0x4a4c, 0x4a4f, 0x4a52, 0x4a55, 0x4a59, 0x4a5c, 0x4a5f, + 0x4a62, 0x4a65, 0x4a69, 0x4a6c, 0x4a6f, 0x4a72, 0x4a75, 0x4a79, + 0x4a7c, 0x4a7f, 0x4a82, 0x4a86, 0x4a89, 0x4a8c, 0x4a8f, 0x4a93, + 0x4a96, 0x4a99, 0x4a9d, 0x4aa0, 0x4aa3, 0x4aa7, 0x4aaa, 0x4aad, + 0x4ab1, 0x4ab4, 0x4ab7, 0x4abb, 0x4abe, 0x4ac1, 0x4ac5, 0x4ac8, + 0x4acc, 0x4acf, 0x4ad2, 0x4ad6, 0x4ad9, 0x4add, 0x4ae0, 0x4ae4, + 0x4ae7, 0x4aea, 0x4aee, 0x4af1, 0x4af5, 0x4af8, 0x4afc, 0x4aff, + 0x4b03, 0x4b06, 0x4b0a, 0x4b0d, 0x4b11, 0x4b14, 0x4b18, 0x4b1c, + 0x4b1f, 0x4b23, 0x4b26, 0x4b2a, 0x4b2d, 0x4b31, 0x4b35, 0x4b38, + 0x4b3c, 0x4b3f, 0x4b43, 0x4b47, 0x4b4a, 0x4b4e, 0x4b52, 0x4b55, + 0x4b59, 0x4b5d, 0x4b60, 0x4b64, 0x4b68, 0x4b6b, 0x4b6f, 0x4b73, + 0x4b77, 0x4b7a, 0x4b7e, 0x4b82, 0x4b86, 0x4b89, 0x4b8d, 0x4b91, + 0x4b95, 0x4b98, 0x4b9c, 0x4ba0, 0x4ba4, 0x4ba8, 0x4bac, 0x4baf, + 0x4bb3, 0x4bb7, 0x4bbb, 0x4bbf, 0x4bc3, 0x4bc7, 0x4bca, 0x4bce, + 0x4bd2, 0x4bd6, 0x4bda, 0x4bde, 0x4be2, 0x4be6, 0x4bea, 0x4bee, + 0x4bf2, 0x4bf6, 0x4bfa, 0x4bfe, 0x4c01, 0x4c03, 0x4c05, 0x4c07, + 0x4c09, 0x4c0b, 0x4c0d, 0x4c0f, 0x4c11, 0x4c13, 0x4c15, 0x4c17, + 0x4c19, 0x4c1b, 0x4c1d, 0x4c1f, 0x4c21, 0x4c23, 0x4c26, 0x4c28, + 0x4c2a, 0x4c2c, 0x4c2e, 0x4c30, 0x4c32, 0x4c34, 0x4c36, 0x4c38, + 0x4c3a, 0x4c3d, 0x4c3f, 0x4c41, 0x4c43, 0x4c45, 0x4c47, 0x4c49, + 0x4c4c, 0x4c4e, 0x4c50, 0x4c52, 0x4c54, 0x4c56, 0x4c58, 0x4c5b, + 0x4c5d, 0x4c5f, 0x4c61, 0x4c63, 0x4c66, 0x4c68, 0x4c6a, 0x4c6c, + 0x4c6e, 0x4c71, 0x4c73, 0x4c75, 0x4c77, 0x4c7a, 0x4c7c, 0x4c7e, + 0x4c80, 0x4c83, 0x4c85, 0x4c87, 0x4c89, 0x4c8c, 0x4c8e, 0x4c90, + 0x4c92, 0x4c95, 0x4c97, 0x4c99, 0x4c9c, 0x4c9e, 0x4ca0, 0x4ca3, + 0x4ca5, 0x4ca7, 0x4caa, 0x4cac, 0x4cae, 0x4cb1, 0x4cb3, 0x4cb5, + 0x4cb8, 0x4cba, 0x4cbc, 0x4cbf, 0x4cc1, 0x4cc3, 0x4cc6, 0x4cc8, + 0x4ccb, 0x4ccd, 0x4ccf, 0x4cd2, 0x4cd4, 0x4cd7, 0x4cd9, 0x4cdb, + 0x4cde, 0x4ce0, 0x4ce3, 0x4ce5, 0x4ce8, 0x4cea, 0x4ced, 0x4cef, + 0x4cf2, 0x4cf4, 0x4cf6, 0x4cf9, 0x4cfb, 0x4cfe, 0x4d00, 0x4d03, + 0x4d05, 0x4d08, 0x4d0b, 0x4d0d, 0x4d10, 0x4d12, 0x4d15, 0x4d17, + 0x4d1a, 0x4d1c, 0x4d1f, 0x4d21, 0x4d24, 0x4d27, 0x4d29, 0x4d2c, + 0x4d2e, 0x4d31, 0x4d33, 0x4d36, 0x4d39, 0x4d3b, 0x4d3e, 0x4d41, + 0x4d43, 0x4d46, 0x4d48, 0x4d4b, 0x4d4e, 0x4d50, 0x4d53, 0x4d56, + 0x4d58, 0x4d5b, 0x4d5e, 0x4d60, 0x4d63, 0x4d66, 0x4d69, 0x4d6b, + 0x4d6e, 0x4d71, 0x4d73, 0x4d76, 0x4d79, 0x4d7c, 0x4d7e, 0x4d81, + 0x4d84, 0x4d87, 0x4d89, 0x4d8c, 0x4d8f, 0x4d92, 0x4d94, 0x4d97, + 0x4d9a, 0x4d9d, 0x4da0, 0x4da2, 0x4da5, 0x4da8, 0x4dab, 0x4dae, + 0x4db1, 0x4db3, 0x4db6, 0x4db9, 0x4dbc, 0x4dbf, 0x4dc2, 0x4dc5, + 0x4dc8, 0x4dca, 0x4dcd, 0x4dd0, 0x4dd3, 0x4dd6, 0x4dd9, 0x4ddc, + 0x4ddf, 0x4de2, 0x4de5, 0x4de8, 0x4deb, 0x4dee, 0x4df1, 0x4df4, + 0x4df7, 0x4dfa, 0x4dfd, 0x4e00, 0x4e03, 0x4e06, 0x4e09, 0x4e0c, + 0x4e0f, 0x4e12, 0x4e15, 0x4e18, 0x4e1b, 0x4e1e, 0x4e21, 0x4e24, + 0x4e27, 0x4e2a, 0x4e2d, 0x4e30, 0x4e33, 0x4e36, 0x4e3a, 0x4e3d, + 0x4e40, 0x4e43, 0x4e46, 0x4e49, 0x4e4c, 0x4e4f, 0x4e53, 0x4e56, + 0x4e59, 0x4e5c, 0x4e5f, 0x4e63, 0x4e66, 0x4e69, 0x4e6c, 0x4e6f, + 0x4e73, 0x4e76, 0x4e79, 0x4e7c, 0x4e80, 0x4e83, 0x4e86, 0x4e89, + 0x4e8d, 0x4e90, 0x4e93, 0x4e96, 0x4e9a, 0x4e9d, 0x4ea0, 0x4ea4, + 0x4ea7, 0x4eaa, 0x4eae, 0x4eb1, 0x4eb4, 0x4eb8, 0x4ebb, 0x4ebe, + 0x4ec2, 0x4ec5, 0x4ec9, 0x4ecc, 0x4ecf, 0x4ed3, 0x4ed6, 0x4eda, + 0x4edd, 0x4ee0, 0x4ee4, 0x4ee7, 0x4eeb, 0x4eee, 0x4ef2, 0x4ef5, + 0x4ef9, 0x4efc, 0x4f00, 0x4f03, 0x4f07, 0x4f0a, 0x4f0e, 0x4f11, + 0x4f15, 0x4f18, 0x4f1c, 0x4f1f, 0x4f23, 0x4f27, 0x4f2a, 0x4f2e, + 0x4f31, 0x4f35, 0x4f39, 0x4f3c, 0x4f40, 0x4f43, 0x4f47, 0x4f4b, + 0x4f4e, 0x4f52, 0x4f56, 0x4f59, 0x4f5d, 0x4f61, 0x4f64, 0x4f68, + 0x4f6c, 0x4f70, 0x4f73, 0x4f77, 0x4f7b, 0x4f7e, 0x4f82, 0x4f86, + 0x4f8a, 0x4f8d, 0x4f91, 0x4f95, 0x4f99, 0x4f9d, 0x4fa0, 0x4fa4, + 0x4fa8, 0x4fac, 0x4fb0, 0x4fb4, 0x4fb7, 0x4fbb, 0x4fbf, 0x4fc3, + 0x4fc7, 0x4fcb, 0x4fcf, 0x4fd3, 0x4fd7, 0x4fdb, 0x4fde, 0x4fe2, + 0x4fe6, 0x4fea, 0x4fee, 0x4ff2, 0x4ff6, 0x4ffa, 0x4ffe, 0x5001, + 0x5003, 0x5005, 0x5007, 0x5009, 0x500b, 0x500d, 0x500f, 0x5011, + 0x5013, 0x5015, 0x5017, 0x5019, 0x501b, 0x501e, 0x5020, 0x5022, + 0x5024, 0x5026, 0x5028, 0x502a, 0x502c, 0x502e, 0x5030, 0x5032, + 0x5034, 0x5036, 0x5039, 0x503b, 0x503d, 0x503f, 0x5041, 0x5043, + 0x5045, 0x5047, 0x504a, 0x504c, 0x504e, 0x5050, 0x5052, 0x5054, + 0x5057, 0x5059, 0x505b, 0x505d, 0x505f, 0x5061, 0x5064, 0x5066, + 0x5068, 0x506a, 0x506c, 0x506f, 0x5071, 0x5073, 0x5075, 0x5078, + 0x507a, 0x507c, 0x507e, 0x5081, 0x5083, 0x5085, 0x5087, 0x508a, + 0x508c, 0x508e, 0x5090, 0x5093, 0x5095, 0x5097, 0x509a, 0x509c, + 0x509e, 0x50a0, 0x50a3, 0x50a5, 0x50a7, 0x50aa, 0x50ac, 0x50ae, + 0x50b1, 0x50b3, 0x50b5, 0x50b8, 0x50ba, 0x50bd, 0x50bf, 0x50c1, + 0x50c4, 0x50c6, 0x50c8, 0x50cb, 0x50cd, 0x50d0, 0x50d2, 0x50d4, + 0x50d7, 0x50d9, 0x50dc, 0x50de, 0x50e1, 0x50e3, 0x50e6, 0x50e8, + 0x50ea, 0x50ed, 0x50ef, 0x50f2, 0x50f4, 0x50f7, 0x50f9, 0x50fc, + 0x50fe, 0x5101, 0x5103, 0x5106, 0x5108, 0x510b, 0x510d, 0x5110, + 0x5112, 0x5115, 0x5117, 0x511a, 0x511d, 0x511f, 0x5122, 0x5124, + 0x5127, 0x5129, 0x512c, 0x512f, 0x5131, 0x5134, 0x5136, 0x5139, + 0x513c, 0x513e, 0x5141, 0x5143, 0x5146, 0x5149, 0x514b, 0x514e, + 0x5151, 0x5153, 0x5156, 0x5159, 0x515b, 0x515e, 0x5161, 0x5163, + 0x5166, 0x5169, 0x516c, 0x516e, 0x5171, 0x5174, 0x5176, 0x5179, + 0x517c, 0x517f, 0x5181, 0x5184, 0x5187, 0x518a, 0x518c, 0x518f, + 0x5192, 0x5195, 0x5198, 0x519a, 0x519d, 0x51a0, 0x51a3, 0x51a6, + 0x51a8, 0x51ab, 0x51ae, 0x51b1, 0x51b4, 0x51b7, 0x51ba, 0x51bc, + 0x51bf, 0x51c2, 0x51c5, 0x51c8, 0x51cb, 0x51ce, 0x51d1, 0x51d3, + 0x51d6, 0x51d9, 0x51dc, 0x51df, 0x51e2, 0x51e5, 0x51e8, 0x51eb, + 0x51ee, 0x51f1, 0x51f4, 0x51f7, 0x51fa, 0x51fd, 0x5200, 0x5203, + 0x5206, 0x5209, 0x520c, 0x520f, 0x5212, 0x5215, 0x5218, 0x521b, + 0x521e, 0x5221, 0x5224, 0x5227, 0x522a, 0x522d, 0x5231, 0x5234, + 0x5237, 0x523a, 0x523d, 0x5240, 0x5243, 0x5246, 0x524a, 0x524d, + 0x5250, 0x5253, 0x5256, 0x5259, 0x525d, 0x5260, 0x5263, 0x5266, + 0x5269, 0x526c, 0x5270, 0x5273, 0x5276, 0x5279, 0x527d, 0x5280, + 0x5283, 0x5286, 0x528a, 0x528d, 0x5290, 0x5293, 0x5297, 0x529a, + 0x529d, 0x52a1, 0x52a4, 0x52a7, 0x52ab, 0x52ae, 0x52b1, 0x52b5, + 0x52b8, 0x52bb, 0x52bf, 0x52c2, 0x52c6, 0x52c9, 0x52cc, 0x52d0, + 0x52d3, 0x52da, 0x52e1, 0x52e8, 0x52ef, 0x52f6, 0x52fd, 0x5304, + 0x530b, 0x5312, 0x5319, 0x5320, 0x5327, 0x532e, 0x5335, 0x533d, + 0x5344, 0x534b, 0x5352, 0x535a, 0x5361, 0x5369, 0x5370, 0x5377, + 0x537f, 0x5386, 0x538e, 0x5395, 0x539d, 0x53a5, 0x53ac, 0x53b4, + 0x53bc, 0x53c4, 0x53cb, 0x53d3, 0x53db, 0x53e3, 0x53eb, 0x53f3, + 0x53fb, 0x5401, 0x5405, 0x5409, 0x540d, 0x5411, 0x5416, 0x541a, + 0x541e, 0x5422, 0x5426, 0x542a, 0x542e, 0x5433, 0x5437, 0x543b, + 0x543f, 0x5443, 0x5448, 0x544c, 0x5450, 0x5455, 0x5459, 0x545d, + 0x5462, 0x5466, 0x546a, 0x546f, 0x5473, 0x5478, 0x547c, 0x5481, + 0x5485, 0x548a, 0x548e, 0x5493, 0x5498, 0x549c, 0x54a1, 0x54a5, + 0x54aa, 0x54af, 0x54b3, 0x54b8, 0x54bd, 0x54c2, 0x54c6, 0x54cb, + 0x54d0, 0x54d5, 0x54da, 0x54de, 0x54e3, 0x54e8, 0x54ed, 0x54f2, + 0x54f7, 0x54fc, 0x5501, 0x5506, 0x550b, 0x5510, 0x5515, 0x551a, + 0x551f, 0x5525, 0x552a, 0x552f, 0x5534, 0x5539, 0x553e, 0x5544, + 0x5549, 0x554e, 0x5554, 0x5559, 0x555e, 0x5564, 0x5569, 0x556f, + 0x5574, 0x5579, 0x557f, 0x5584, 0x558a, 0x558f, 0x5595, 0x559b, + 0x55a0, 0x55a6, 0x55ac, 0x55b1, 0x55b7, 0x55bd, 0x55c2, 0x55c8, + 0x55ce, 0x55d4, 0x55da, 0x55e0, 0x55e5, 0x55eb, 0x55f1, 0x55f7, + 0x55fd, 0x5603, 0x5609, 0x560f, 0x5615, 0x561b, 0x5622, 0x5628, + 0x562e, 0x5634, 0x563a, 0x5640, 0x5647, 0x564d, 0x5653, 0x565a, + 0x5660, 0x5666, 0x566d, 0x5673, 0x567a, 0x5680, 0x5687, 0x568d, + 0x5694, 0x569a, 0x56a1, 0x56a8, 0x56ae, 0x56b5, 0x56bc, 0x56c3, + 0x56c9, 0x56d0, 0x56d7, 0x56de, 0x56e5, 0x56ec, 0x56f3, 0x56f9, + 0x5700, 0x5707, 0x570f, 0x5716, 0x571d, 0x5724, 0x572b, 0x5732, + 0x5739, 0x5741, 0x5748, 0x574f, 0x5756, 0x575e, 0x5765, 0x576d, + 0x5774, 0x577c, 0x5783, 0x578b, 0x5792, 0x579a, 0x57a1, 0x57a9, + 0x57b1, 0x57b8, 0x57c0, 0x57c8, 0x57d0, 0x57d7, 0x57df, 0x57e7, + 0x57ef, 0x57f7, 0x57ff, 0x5804, 0x5808, 0x580c, 0x5810, 0x5814, + 0x5818, 0x581c, 0x5820, 0x5824, 0x5828, 0x582c, 0x5831, 0x5835, + 0x5839, 0x583d, 0x5842, 0x5846, 0x584a, 0x584e, 0x5853, 0x5857, + 0x585b, 0x5860, 0x5864, 0x5869, 0x586d, 0x5871, 0x5876, 0x587a, + 0x587f, 0x5883, 0x5888, 0x588c, 0x5891, 0x5895, 0x589a, 0x589f, + 0x58a3, 0x58a8, 0x58ad, 0x58b1, 0x58b6, 0x58bb, 0x58bf, 0x58c4, + 0x58c9, 0x58ce, 0x58d3, 0x58d7, 0x58dc, 0x58e1, 0x58e6, 0x58eb, + 0x58f0, 0x58f5, 0x58fa, 0x58ff, 0x5904, 0x5909, 0x590e, 0x5913, + 0x5918, 0x591d, 0x5922, 0x5927, 0x592d, 0x5932, 0x5937, 0x593c, + 0x5941, 0x5947, 0x594c, 0x5951, 0x5957, 0x595c, 0x5961, 0x5967, + 0x596c, 0x5972, 0x5977, 0x597c, 0x5982, 0x5987, 0x598d, 0x5993, + 0x5998, 0x599e, 0x59a3, 0x59a9, 0x59af, 0x59b4, 0x59ba, 0x59c0, + 0x59c6, 0x59cb, 0x59d1, 0x59d7, 0x59dd, 0x59e3, 0x59e9, 0x59ef, + 0x59f5, 0x59fa, 0x5a00, 0x5a07, 0x5a0d, 0x5a13, 0x5a19, 0x5a1f, + 0x5a25, 0x5a2b, 0x5a31, 0x5a37, 0x5a3e, 0x5a44, 0x5a4a, 0x5a51, + 0x5a57, 0x5a5d, 0x5a64, 0x5a6a, 0x5a70, 0x5a77, 0x5a7d, 0x5a84, + 0x5a8a, 0x5a91, 0x5a98, 0x5a9e, 0x5aa5, 0x5aab, 0x5ab2, 0x5ab9, + 0x5ac0, 0x5ac6, 0x5acd, 0x5ad4, 0x5adb, 0x5ae2, 0x5ae8, 0x5aef, + 0x5af6, 0x5afd, 0x5b04, 0x5b0b, 0x5b12, 0x5b1a, 0x5b21, 0x5b28, + 0x5b2f, 0x5b36, 0x5b3d, 0x5b45, 0x5b4c, 0x5b53, 0x5b5b, 0x5b62, + 0x5b69, 0x5b71, 0x5b78, 0x5b80, 0x5b87, 0x5b8f, 0x5b96, 0x5b9e, + 0x5ba6, 0x5bad, 0x5bb5, 0x5bbd, 0x5bc4, 0x5bcc, 0x5bd4, 0x5bdc, + 0x5be4, 0x5bec, 0x5bf4, 0x5bfb, 0x5c02, 0x5c06, 0x5c0a, 0x5c0e, + 0x5c12, 0x5c16, 0x5c1a, 0x5c1e, 0x5c22, 0x5c26, 0x5c2b, 0x5c2f, + 0x5c33, 0x5c37, 0x5c3b, 0x5c40, 0x5c44, 0x5c48, 0x5c4c, 0x5c51, + 0x5c55, 0x5c59, 0x5c5e, 0x5c62, 0x5c67, 0x5c6b, 0x5c6f, 0x5c74, + 0x5c78, 0x5c7d, 0x5c81, 0x5c86, 0x5c8a, 0x5c8f, 0x5c93, 0x5c98, + 0x5c9d, 0x5ca1, 0x5ca6, 0x5cab, 0x5caf, 0x5cb4, 0x5cb9, 0x5cbd, + 0x5cc2, 0x5cc7, 0x5ccc, 0x5cd0, 0x5cd5, 0x5cda, 0x5cdf, 0x5ce4, + 0x5ce9, 0x5cee, 0x5cf3, 0x5cf8, 0x5cfd, 0x5d02, 0x5d07, 0x5d0c, + 0x5d11, 0x5d16, 0x5d1b, 0x5d20, 0x5d25, 0x5d2a, 0x5d2f, 0x5d35, + 0x5d3a, 0x5d3f, 0x5d44, 0x5d4a, 0x5d4f, 0x5d54, 0x5d5a, 0x5d5f, + 0x5d64, 0x5d6a, 0x5d6f, 0x5d75, 0x5d7a, 0x5d80, 0x5d85, 0x5d8b, + 0x5d90, 0x5d96, 0x5d9b, 0x5da1, 0x5da7, 0x5dac, 0x5db2, 0x5db8, + 0x5dbd, 0x5dc3, 0x5dc9, 0x5dcf, 0x5dd4, 0x5dda, 0x5de0, 0x5de6, + 0x5dec, 0x5df2, 0x5df8, 0x5dfe, 0x5e04, 0x5e0a, 0x5e10, 0x5e16, + 0x5e1c, 0x5e22, 0x5e28, 0x5e2f, 0x5e35, 0x5e3b, 0x5e41, 0x5e47, + 0x5e4e, 0x5e54, 0x5e5a, 0x5e61, 0x5e67, 0x5e6e, 0x5e74, 0x5e7a, + 0x5e81, 0x5e87, 0x5e8e, 0x5e95, 0x5e9b, 0x5ea2, 0x5ea8, 0x5eaf, + 0x5eb6, 0x5ebd, 0x5ec3, 0x5eca, 0x5ed1, 0x5ed8, 0x5edf, 0x5ee5, + 0x5eec, 0x5ef3, 0x5efa, 0x5f01, 0x5f08, 0x5f0f, 0x5f16, 0x5f1d, + 0x5f25, 0x5f2c, 0x5f33, 0x5f3a, 0x5f41, 0x5f49, 0x5f50, 0x5f57, + 0x5f5f, 0x5f66, 0x5f6d, 0x5f75, 0x5f7c, 0x5f84, 0x5f8b, 0x5f93, + 0x5f9b, 0x5fa2, 0x5faa, 0x5fb1, 0x5fb9, 0x5fc1, 0x5fc9, 0x5fd0, + 0x5fd8, 0x5fe0, 0x5fe8, 0x5ff0, 0x5ff8, 0x6000, 0x6004, 0x6008, + 0x600c, 0x6010, 0x6014, 0x6018, 0x601c, 0x6020, 0x6025, 0x6029, + 0x602d, 0x6031, 0x6035, 0x603a, 0x603e, 0x6042, 0x6046, 0x604b, + 0x604f, 0x6053, 0x6057, 0x605c, 0x6060, 0x6065, 0x6069, 0x606d, + 0x6072, 0x6076, 0x607b, 0x607f, 0x6084, 0x6088, 0x608d, 0x6091, + 0x6096, 0x609b, 0x609f, 0x60a4, 0x60a8, 0x60ad, 0x60b2, 0x60b7, + 0x60bb, 0x60c0, 0x60c5, 0x60ca, 0x60ce, 0x60d3, 0x60d8, 0x60dd, + 0x60e2, 0x60e7, 0x60eb, 0x60f0, 0x60f5, 0x60fa, 0x60ff, 0x6104, + 0x6109, 0x610e, 0x6113, 0x6119, 0x611e, 0x6123, 0x6128, 0x612d, + 0x6132, 0x6137, 0x613d, 0x6142, 0x6147, 0x614d, 0x6152, 0x6157, + 0x615d, 0x6162, 0x6167, 0x616d, 0x6172, 0x6178, 0x617d, 0x6183, + 0x6188, 0x618e, 0x6193, 0x6199, 0x619e, 0x61a4, 0x61aa, 0x61af, + 0x61b5, 0x61bb, 0x61c0, 0x61c6, 0x61cc, 0x61d2, 0x61d8, 0x61de, + 0x61e3, 0x61e9, 0x61ef, 0x61f5, 0x61fb, 0x6201, 0x6207, 0x620d, + 0x6213, 0x6219, 0x621f, 0x6226, 0x622c, 0x6232, 0x6238, 0x623e, + 0x6245, 0x624b, 0x6251, 0x6258, 0x625e, 0x6264, 0x626b, 0x6271, + 0x6278, 0x627e, 0x6285, 0x628b, 0x6292, 0x6298, 0x629f, 0x62a5, + 0x62ac, 0x62b3, 0x62ba, 0x62c0, 0x62c7, 0x62ce, 0x62d5, 0x62db, + 0x62e2, 0x62e9, 0x62f0, 0x62f7, 0x62fe, 0x6305, 0x630c, 0x6313, + 0x631a, 0x6321, 0x6329, 0x6330, 0x6337, 0x633e, 0x6345, 0x634d, + 0x6354, 0x635b, 0x6363, 0x636a, 0x6372, 0x6379, 0x6380, 0x6388, + 0x6390, 0x6397, 0x639f, 0x63a6, 0x63ae, 0x63b6, 0x63bd, 0x63c5, + 0x63cd, 0x63d5, 0x63dd, 0x63e5, 0x63ec, 0x63f4, 0x63fc, 0x6402, + 0x6406, 0x640a, 0x640e, 0x6412, 0x6416, 0x641b, 0x641f, 0x6423, + 0x6427, 0x642b, 0x642f, 0x6433, 0x6438, 0x643c, 0x6440, 0x6444, + 0x6449, 0x644d, 0x6451, 0x6456, 0x645a, 0x645e, 0x6463, 0x6467, + 0x646b, 0x6470, 0x6474, 0x6479, 0x647d, 0x6482, 0x6486, 0x648b, + 0x648f, 0x6494, 0x6499, 0x649d, 0x64a2, 0x64a6, 0x64ab, 0x64b0, + 0x64b4, 0x64b9, 0x64be, 0x64c3, 0x64c7, 0x64cc, 0x64d1, 0x64d6, + 0x64db, 0x64e0, 0x64e4, 0x64e9, 0x64ee, 0x64f3, 0x64f8, 0x64fd, + 0x6502, 0x6507, 0x650c, 0x6511, 0x6516, 0x651b, 0x6520, 0x6526, + 0x652b, 0x6530, 0x6535, 0x653a, 0x6540, 0x6545, 0x654a, 0x654f, + 0x6555, 0x655a, 0x655f, 0x6565, 0x656a, 0x6570, 0x6575, 0x657b, + 0x6580, 0x6586, 0x658b, 0x6591, 0x6596, 0x659c, 0x65a1, 0x65a7, + 0x65ad, 0x65b2, 0x65b8, 0x65be, 0x65c4, 0x65c9, 0x65cf, 0x65d5, + 0x65db, 0x65e1, 0x65e7, 0x65ed, 0x65f3, 0x65f8, 0x65fe, 0x6604, + 0x660b, 0x6611, 0x6617, 0x661d, 0x6623, 0x6629, 0x662f, 0x6635, + 0x663c, 0x6642, 0x6648, 0x664e, 0x6655, 0x665b, 0x6661, 0x6668, + 0x666e, 0x6675, 0x667b, 0x6682, 0x6688, 0x668f, 0x6695, 0x669c, + 0x66a2, 0x66a9, 0x66b0, 0x66b7, 0x66bd, 0x66c4, 0x66cb, 0x66d2, + 0x66d8, 0x66df, 0x66e6, 0x66ed, 0x66f4, 0x66fb, 0x6702, 0x6709, + 0x6710, 0x6717, 0x671e, 0x6725, 0x672d, 0x6734, 0x673b, 0x6742, + 0x6749, 0x6751, 0x6758, 0x675f, 0x6767, 0x676e, 0x6776, 0x677d, + 0x6785, 0x678c, 0x6794, 0x679b, 0x67a3, 0x67ab, 0x67b2, 0x67ba, + 0x67c2, 0x67ca, 0x67d1, 0x67d9, 0x67e1, 0x67e9, 0x67f1, 0x67f9, + 0x6800, 0x6804, 0x6808, 0x680c, 0x6811, 0x6815, 0x6819, 0x681d, + 0x6821, 0x6825, 0x6829, 0x682d, 0x6832, 0x6836, 0x683a, 0x683e, + 0x6842, 0x6847, 0x684b, 0x684f, 0x6854, 0x6858, 0x685c, 0x6861, + 0x6865, 0x6869, 0x686e, 0x6872, 0x6877, 0x687b, 0x6880, 0x6884, + 0x6889, 0x688d, 0x6892, 0x6896, 0x689b, 0x68a0, 0x68a4, 0x68a9, + 0x68ae, 0x68b2, 0x68b7, 0x68bc, 0x68c0, 0x68c5, 0x68ca, 0x68cf, + 0x68d4, 0x68d8, 0x68dd, 0x68e2, 0x68e7, 0x68ec, 0x68f1, 0x68f6, + 0x68fb, 0x6900, 0x6905, 0x690a, 0x690f, 0x6914, 0x6919, 0x691e, + 0x6923, 0x6928, 0x692e, 0x6933, 0x6938, 0x693d, 0x6943, 0x6948, + 0x694d, 0x6952, 0x6958, 0x695d, 0x6962, 0x6968, 0x696d, 0x6973, + 0x6978, 0x697e, 0x6983, 0x6989, 0x698e, 0x6994, 0x6999, 0x699f, + 0x69a5, 0x69aa, 0x69b0, 0x69b6, 0x69bb, 0x69c1, 0x69c7, 0x69cd, + 0x69d2, 0x69de, 0x69ea, 0x69f6, 0x6a02, 0x6a0e, 0x6a1a, 0x6a26, + 0x6a33, 0x6a3f, 0x6a4c, 0x6a58, 0x6a65, 0x6a72, 0x6a7f, 0x6a8c, + 0x6a99, 0x6aa6, 0x6ab4, 0x6ac1, 0x6acf, 0x6adc, 0x6aea, 0x6af8, + 0x6b06, 0x6b14, 0x6b22, 0x6b30, 0x6b3f, 0x6b4d, 0x6b5c, 0x6b6b, + 0x6b7a, 0x6b89, 0x6b98, 0x6ba7, 0x6bb7, 0x6bc6, 0x6bd6, 0x6be5, + 0x6bf5, 0x6c03, 0x6c0b, 0x6c13, 0x6c1b, 0x6c23, 0x6c2c, 0x6c34, + 0x6c3c, 0x6c45, 0x6c4d, 0x6c56, 0x6c5f, 0x6c68, 0x6c70, 0x6c79, + 0x6c82, 0x6c8b, 0x6c94, 0x6c9e, 0x6ca7, 0x6cb0, 0x6cba, 0x6cc3, + 0x6ccd, 0x6cd6, 0x6ce0, 0x6cea, 0x6cf4, 0x6cfe, 0x6d08, 0x6d12, + 0x6d1c, 0x6d26, 0x6d31, 0x6d3b, 0x6d45, 0x6d50, 0x6d5b, 0x6d65, + 0x6d70, 0x6d7b, 0x6d86, 0x6d91, 0x6d9c, 0x6da8, 0x6db3, 0x6dbf, + 0x6dca, 0x6dd6, 0x6de1, 0x6ded, 0x6df9, 0x6e05, 0x6e11, 0x6e1d, + 0x6e2a, 0x6e36, 0x6e43, 0x6e4f, 0x6e5c, 0x6e69, 0x6e75, 0x6e82, + 0x6e8f, 0x6e9d, 0x6eaa, 0x6eb7, 0x6ec5, 0x6ed2, 0x6ee0, 0x6eee, + 0x6efc, 0x6f0a, 0x6f18, 0x6f26, 0x6f34, 0x6f43, 0x6f52, 0x6f60, + 0x6f6f, 0x6f7e, 0x6f8d, 0x6f9c, 0x6fab, 0x6fbb, 0x6fca, 0x6fda, + 0x6fea, 0x6ffa, 0x7005, 0x700d, 0x7015, 0x701d, 0x7025, 0x702e, + 0x7036, 0x703f, 0x7047, 0x7050, 0x7058, 0x7061, 0x706a, 0x7073, + 0x707c, 0x7085, 0x708e, 0x7097, 0x70a0, 0x70a9, 0x70b3, 0x70bc, + 0x70c6, 0x70cf, 0x70d9, 0x70e3, 0x70ed, 0x70f6, 0x7100, 0x710a, + 0x7115, 0x711f, 0x7129, 0x7133, 0x713e, 0x7148, 0x7153, 0x715e, + 0x7168, 0x7173, 0x717e, 0x7189, 0x7194, 0x71a0, 0x71ab, 0x71b6, + 0x71c2, 0x71cd, 0x71d9, 0x71e5, 0x71f1, 0x71fc, 0x7208, 0x7215, + 0x7221, 0x722d, 0x7239, 0x7246, 0x7253, 0x725f, 0x726c, 0x7279, + 0x7286, 0x7293, 0x72a0, 0x72ae, 0x72bb, 0x72c8, 0x72d6, 0x72e4, + 0x72f2, 0x7300, 0x730e, 0x731c, 0x732a, 0x7338, 0x7347, 0x7356, + 0x7364, 0x7373, 0x7382, 0x7391, 0x73a0, 0x73b0, 0x73bf, 0x73cf, + 0x73de, 0x73ee, 0x73fe, 0x7407, 0x740f, 0x7417, 0x7420, 0x7428, + 0x7430, 0x7439, 0x7441, 0x744a, 0x7452, 0x745b, 0x7464, 0x746c, + 0x7475, 0x747e, 0x7487, 0x7490, 0x749a, 0x74a3, 0x74ac, 0x74b5, + 0x74bf, 0x74c8, 0x74d2, 0x74dc, 0x74e5, 0x74ef, 0x74f9, 0x7503, + 0x750d, 0x7517, 0x7522, 0x752c, 0x7536, 0x7541, 0x754b, 0x7556, + 0x7561, 0x756b, 0x7576, 0x7581, 0x758c, 0x7597, 0x75a3, 0x75ae, + 0x75b9, 0x75c5, 0x75d1, 0x75dc, 0x75e8, 0x75f4, 0x7600, 0x760c, + 0x7618, 0x7624, 0x7631, 0x763d, 0x7649, 0x7656, 0x7663, 0x7670, + 0x767d, 0x768a, 0x7697, 0x76a4, 0x76b1, 0x76bf, 0x76cc, 0x76da, + 0x76e8, 0x76f6, 0x7703, 0x7712, 0x7720, 0x772e, 0x773c, 0x774b, + 0x775a, 0x7768, 0x7777, 0x7786, 0x7795, 0x77a5, 0x77b4, 0x77c3, + 0x77d3, 0x77e3, 0x77f3, 0x7801, 0x7809, 0x7811, 0x781a, 0x7822, + 0x782a, 0x7832, 0x783b, 0x7843, 0x784c, 0x7855, 0x785d, 0x7866, + 0x786f, 0x7878, 0x7881, 0x788a, 0x7893, 0x789c, 0x78a5, 0x78af, + 0x78b8, 0x78c2, 0x78cb, 0x78d5, 0x78de, 0x78e8, 0x78f2, 0x78fc, + 0x7906, 0x7910, 0x791a, 0x7924, 0x792f, 0x7939, 0x7944, 0x794e, + 0x7959, 0x7964, 0x796e, 0x7979, 0x7984, 0x798f, 0x799b, 0x79a6, + 0x79b1, 0x79bd, 0x79c8, 0x79d4, 0x79df, 0x79eb, 0x79f7, 0x7a03, + 0x7a0f, 0x7a1b, 0x7a28, 0x7a34, 0x7a40, 0x7a4d, 0x7a5a, 0x7a66, + 0x7a73, 0x7a80, 0x7a8d, 0x7a9a, 0x7aa8, 0x7ab5, 0x7ac2, 0x7ad0, + 0x7ade, 0x7aeb, 0x7af9, 0x7b07, 0x7b16, 0x7b24, 0x7b32, 0x7b41, + 0x7b4f, 0x7b5e, 0x7b6d, 0x7b7b, 0x7b8a, 0x7b9a, 0x7ba9, 0x7bb8, + 0x7bc8, 0x7bd7, 0x7be7, 0x7bf7, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, + 0x3c00, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, 0x3bff, + 0x3bff, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, 0x3bfe, + 0x3bfe, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, + 0x3bfc, 0x3bfc, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, + 0x3bfb, 0x3bfb, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, + 0x3bfa, 0x3bfa, 0x3bfa, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, + 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, + 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf7, + 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, + 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, + 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, + 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf4, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, + 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf3, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, + 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf2, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, 0x3bf1, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, + 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, + 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bef, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, + 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bee, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, + 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bed, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, + 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3bec, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, 0x3beb, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, 0x3bea, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, 0x3be9, + 0x3be9, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, 0x3be8, + 0x3be8, 0x3be8, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, 0x3be7, + 0x3be7, 0x3be7, 0x3be7, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be6, + 0x3be6, 0x3be6, 0x3be6, 0x3be6, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be5, + 0x3be5, 0x3be5, 0x3be5, 0x3be5, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, + 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be4, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, + 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be3, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, + 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be2, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, 0x3be1, + 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, + 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, + 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, + 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, + 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, 0x3be0, + 0x3be0, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, + 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, + 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, + 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, 0x3bdf, + 0x3bdf, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, + 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, + 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, + 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, 0x3bde, + 0x3bde, 0x3bde, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, + 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, + 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, + 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, 0x3bdd, + 0x3bdd, 0x3bdd, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, + 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, + 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, + 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdc, + 0x3bdc, 0x3bdc, 0x3bdc, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, + 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, + 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, + 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, + 0x3bdb, 0x3bdb, 0x3bdb, 0x3bdb, 0x3bda, 0x3bda, 0x3bda, 0x3bda, + 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, + 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, + 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bda, + 0x3bda, 0x3bda, 0x3bda, 0x3bda, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, + 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, + 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, + 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, + 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd9, 0x3bd8, 0x3bd8, 0x3bd8, + 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, + 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, + 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, + 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd8, 0x3bd7, 0x3bd7, 0x3bd7, + 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, + 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, + 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, + 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd7, 0x3bd6, 0x3bd6, + 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, + 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, + 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, + 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd6, 0x3bd5, + 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, + 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, + 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, + 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd5, 0x3bd4, + 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, + 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, + 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, + 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, 0x3bd4, + 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, + 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, + 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, + 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, 0x3bd3, + 0x3bd3, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, + 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, + 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, + 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, 0x3bd2, + 0x3bd2, 0x3bd2, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, + 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, + 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, + 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd1, + 0x3bd1, 0x3bd1, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, + 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, + 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, + 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, 0x3bd0, + 0x3bd0, 0x3bd0, 0x3bd0, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, + 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, + 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, + 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, + 0x3bcf, 0x3bcf, 0x3bcf, 0x3bcf, 0x3bce, 0x3bce, 0x3bce, 0x3bce, + 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, + 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, + 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, + 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bce, 0x3bcd, 0x3bcd, 0x3bcd, + 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, + 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, + 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, + 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcd, 0x3bcc, 0x3bcc, + 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, + 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, + 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, + 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcc, 0x3bcb, 0x3bcb, + 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, + 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, + 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, + 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bcb, 0x3bca, + 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, + 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, + 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, + 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, 0x3bca, + 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, + 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, + 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, + 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, 0x3bc9, + 0x3bc9, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, + 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, + 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, + 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, + 0x3bc8, 0x3bc8, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, + 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, + 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, + 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc7, + 0x3bc7, 0x3bc7, 0x3bc7, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, + 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, + 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, + 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, + 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc6, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, + 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, + 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, + 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, + 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc5, 0x3bc4, 0x3bc4, 0x3bc4, + 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, + 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, + 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, + 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc4, 0x3bc3, 0x3bc3, + 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, + 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, + 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, + 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc3, 0x3bc2, + 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, + 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, + 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, + 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, 0x3bc2, + 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, + 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, + 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, 0x3bc1, + 0x3bc1, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, + 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, 0x3bc0, + 0x3bc0, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, + 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, 0x3bbf, + 0x3bbf, 0x3bbf, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, + 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, 0x3bbe, + 0x3bbe, 0x3bbe, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, + 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbd, + 0x3bbd, 0x3bbd, 0x3bbd, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, + 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbc, + 0x3bbc, 0x3bbc, 0x3bbc, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, + 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, + 0x3bbb, 0x3bbb, 0x3bbb, 0x3bbb, 0x3bba, 0x3bba, 0x3bba, 0x3bba, + 0x3bba, 0x3bba, 0x3bba, 0x3bba, 0x3bba, 0x3bba, 0x3bba, 0x3bba, + 0x3bba, 0x3bba, 0x3bba, 0x3bba, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, + 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, + 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb9, 0x3bb8, 0x3bb8, 0x3bb8, + 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, + 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb8, 0x3bb7, 0x3bb7, + 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, + 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb7, 0x3bb6, 0x3bb6, + 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, + 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb6, 0x3bb5, + 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, + 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb5, 0x3bb4, + 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, + 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, 0x3bb4, + 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, + 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, 0x3bb3, + 0x3bb3, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, + 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, 0x3bb2, + 0x3bb2, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, + 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, 0x3bb1, + 0x3bb1, 0x3bb1, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, + 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, 0x3bb0, + 0x3bb0, 0x3bb0, 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, + 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, 0x3baf, + 0x3baf, 0x3baf, 0x3baf, 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bae, + 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bae, + 0x3bae, 0x3bae, 0x3bae, 0x3bae, 0x3bad, 0x3bad, 0x3bad, 0x3bad, + 0x3bad, 0x3bad, 0x3bad, 0x3bad, 0x3bad, 0x3bad, 0x3bad, 0x3bad, + 0x3bad, 0x3bad, 0x3bad, 0x3bad, 0x3bac, 0x3bac, 0x3bac, 0x3bac, + 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bac, + 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bac, 0x3bab, 0x3bab, 0x3bab, + 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, + 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3bab, 0x3baa, 0x3baa, + 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, + 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3baa, 0x3ba9, + 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, + 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba9, 0x3ba8, + 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, + 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, 0x3ba8, + 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, + 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, 0x3ba7, + 0x3ba7, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, + 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, 0x3ba6, + 0x3ba6, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, + 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, 0x3ba5, + 0x3ba5, 0x3ba5, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, + 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba4, + 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, + 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, + 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba3, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, + 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, + 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, + 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, + 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba1, 0x3ba0, 0x3ba0, 0x3ba0, + 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, + 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3ba0, 0x3b9f, 0x3b9f, + 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, + 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9f, 0x3b9e, + 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, + 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, 0x3b9e, + 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, + 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, 0x3b9d, + 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, + 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, 0x3b9c, + 0x3b9c, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, + 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, 0x3b9b, + 0x3b9b, 0x3b9b, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, + 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, 0x3b9a, + 0x3b9a, 0x3b9a, 0x3b9a, 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b99, + 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b99, + 0x3b99, 0x3b99, 0x3b99, 0x3b99, 0x3b98, 0x3b98, 0x3b98, 0x3b98, + 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b98, + 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b98, 0x3b97, 0x3b97, 0x3b97, + 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, + 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b97, 0x3b96, 0x3b96, + 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, + 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b96, 0x3b95, 0x3b95, + 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, + 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b95, 0x3b94, + 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, + 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, 0x3b94, + 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, + 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, 0x3b93, + 0x3b93, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, + 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, 0x3b92, + 0x3b92, 0x3b92, 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, + 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, 0x3b91, + 0x3b91, 0x3b91, 0x3b91, 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b90, + 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b90, + 0x3b90, 0x3b90, 0x3b90, 0x3b90, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, + 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, + 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8f, 0x3b8e, 0x3b8e, 0x3b8e, + 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, + 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8d, 0x3b8d, + 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, + 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8d, 0x3b8c, + 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, + 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, 0x3b8c, + 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, + 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, 0x3b8b, + 0x3b8b, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, + 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, 0x3b8a, + 0x3b8a, 0x3b8a, 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, + 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, 0x3b89, + 0x3b89, 0x3b89, 0x3b89, 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b88, + 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b88, + 0x3b88, 0x3b88, 0x3b88, 0x3b88, 0x3b87, 0x3b87, 0x3b87, 0x3b87, + 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b87, + 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b87, 0x3b86, 0x3b86, 0x3b86, + 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, + 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b86, 0x3b85, 0x3b85, + 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, + 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b85, 0x3b84, + 0x3b84, 0x3b84, 0x3b84, 0x3b84, 0x3b84, 0x3b84, 0x3b84, 0x3b84, + 0x3b84, 0x3b84, 0x3b84, 0x3b84, 0x3b83, 0x3b83, 0x3b83, 0x3b83, + 0x3b83, 0x3b83, 0x3b83, 0x3b83, 0x3b83, 0x3b82, 0x3b82, 0x3b82, + 0x3b82, 0x3b82, 0x3b82, 0x3b82, 0x3b82, 0x3b81, 0x3b81, 0x3b81, + 0x3b81, 0x3b81, 0x3b81, 0x3b81, 0x3b81, 0x3b81, 0x3b80, 0x3b80, + 0x3b80, 0x3b80, 0x3b80, 0x3b80, 0x3b80, 0x3b80, 0x3b7f, 0x3b7f, + 0x3b7f, 0x3b7f, 0x3b7f, 0x3b7f, 0x3b7f, 0x3b7f, 0x3b7f, 0x3b7e, + 0x3b7e, 0x3b7e, 0x3b7e, 0x3b7e, 0x3b7e, 0x3b7e, 0x3b7e, 0x3b7d, + 0x3b7d, 0x3b7d, 0x3b7d, 0x3b7d, 0x3b7d, 0x3b7d, 0x3b7d, 0x3b7d, + 0x3b7c, 0x3b7c, 0x3b7c, 0x3b7c, 0x3b7c, 0x3b7c, 0x3b7c, 0x3b7c, + 0x3b7b, 0x3b7b, 0x3b7b, 0x3b7b, 0x3b7b, 0x3b7b, 0x3b7b, 0x3b7b, + 0x3b7b, 0x3b7a, 0x3b7a, 0x3b7a, 0x3b7a, 0x3b7a, 0x3b7a, 0x3b7a, + 0x3b7a, 0x3b79, 0x3b79, 0x3b79, 0x3b79, 0x3b79, 0x3b79, 0x3b79, + 0x3b79, 0x3b79, 0x3b78, 0x3b78, 0x3b78, 0x3b78, 0x3b78, 0x3b78, + 0x3b78, 0x3b78, 0x3b78, 0x3b77, 0x3b77, 0x3b77, 0x3b77, 0x3b77, + 0x3b77, 0x3b77, 0x3b77, 0x3b76, 0x3b76, 0x3b76, 0x3b76, 0x3b76, + 0x3b76, 0x3b76, 0x3b76, 0x3b76, 0x3b75, 0x3b75, 0x3b75, 0x3b75, + 0x3b75, 0x3b75, 0x3b75, 0x3b75, 0x3b74, 0x3b74, 0x3b74, 0x3b74, + 0x3b74, 0x3b74, 0x3b74, 0x3b74, 0x3b74, 0x3b73, 0x3b73, 0x3b73, + 0x3b73, 0x3b73, 0x3b73, 0x3b73, 0x3b73, 0x3b73, 0x3b72, 0x3b72, + 0x3b72, 0x3b72, 0x3b72, 0x3b72, 0x3b72, 0x3b72, 0x3b71, 0x3b71, + 0x3b71, 0x3b71, 0x3b71, 0x3b71, 0x3b71, 0x3b71, 0x3b71, 0x3b70, + 0x3b70, 0x3b70, 0x3b70, 0x3b70, 0x3b70, 0x3b70, 0x3b70, 0x3b6f, + 0x3b6f, 0x3b6f, 0x3b6f, 0x3b6f, 0x3b6f, 0x3b6f, 0x3b6f, 0x3b6f, + 0x3b6e, 0x3b6e, 0x3b6e, 0x3b6e, 0x3b6e, 0x3b6e, 0x3b6e, 0x3b6e, + 0x3b6e, 0x3b6d, 0x3b6d, 0x3b6d, 0x3b6d, 0x3b6d, 0x3b6d, 0x3b6d, + 0x3b6d, 0x3b6c, 0x3b6c, 0x3b6c, 0x3b6c, 0x3b6c, 0x3b6c, 0x3b6c, + 0x3b6c, 0x3b6c, 0x3b6b, 0x3b6b, 0x3b6b, 0x3b6b, 0x3b6b, 0x3b6b, + 0x3b6b, 0x3b6b, 0x3b6a, 0x3b6a, 0x3b6a, 0x3b6a, 0x3b6a, 0x3b6a, + 0x3b6a, 0x3b6a, 0x3b6a, 0x3b69, 0x3b69, 0x3b69, 0x3b69, 0x3b69, + 0x3b69, 0x3b69, 0x3b69, 0x3b69, 0x3b68, 0x3b68, 0x3b68, 0x3b68, + 0x3b68, 0x3b68, 0x3b68, 0x3b68, 0x3b67, 0x3b67, 0x3b67, 0x3b67, + 0x3b67, 0x3b67, 0x3b67, 0x3b67, 0x3b67, 0x3b66, 0x3b66, 0x3b66, + 0x3b66, 0x3b66, 0x3b66, 0x3b66, 0x3b66, 0x3b66, 0x3b65, 0x3b65, + 0x3b65, 0x3b65, 0x3b65, 0x3b65, 0x3b65, 0x3b65, 0x3b64, 0x3b64, + 0x3b64, 0x3b64, 0x3b64, 0x3b64, 0x3b64, 0x3b64, 0x3b64, 0x3b63, + 0x3b63, 0x3b63, 0x3b63, 0x3b63, 0x3b63, 0x3b63, 0x3b63, 0x3b63, + 0x3b62, 0x3b62, 0x3b62, 0x3b62, 0x3b62, 0x3b62, 0x3b62, 0x3b62, + 0x3b61, 0x3b61, 0x3b61, 0x3b61, 0x3b61, 0x3b61, 0x3b61, 0x3b61, + 0x3b61, 0x3b60, 0x3b60, 0x3b60, 0x3b60, 0x3b60, 0x3b60, 0x3b60, + 0x3b60, 0x3b60, 0x3b5f, 0x3b5f, 0x3b5f, 0x3b5f, 0x3b5f, 0x3b5f, + 0x3b5f, 0x3b5f, 0x3b5e, 0x3b5e, 0x3b5e, 0x3b5e, 0x3b5e, 0x3b5e, + 0x3b5e, 0x3b5e, 0x3b5e, 0x3b5d, 0x3b5d, 0x3b5d, 0x3b5d, 0x3b5d, + 0x3b5d, 0x3b5d, 0x3b5d, 0x3b5d, 0x3b5c, 0x3b5c, 0x3b5c, 0x3b5c, + 0x3b5c, 0x3b5c, 0x3b5c, 0x3b5c, 0x3b5b, 0x3b5b, 0x3b5b, 0x3b5b, + 0x3b5b, 0x3b5b, 0x3b5b, 0x3b5b, 0x3b5b, 0x3b5a, 0x3b5a, 0x3b5a, + 0x3b5a, 0x3b5a, 0x3b5a, 0x3b5a, 0x3b5a, 0x3b5a, 0x3b59, 0x3b59, + 0x3b59, 0x3b59, 0x3b59, 0x3b59, 0x3b59, 0x3b59, 0x3b58, 0x3b58, + 0x3b58, 0x3b58, 0x3b58, 0x3b58, 0x3b58, 0x3b58, 0x3b58, 0x3b57, + 0x3b57, 0x3b57, 0x3b57, 0x3b57, 0x3b57, 0x3b57, 0x3b57, 0x3b57, + 0x3b56, 0x3b56, 0x3b56, 0x3b56, 0x3b56, 0x3b56, 0x3b56, 0x3b56, + 0x3b56, 0x3b55, 0x3b55, 0x3b55, 0x3b55, 0x3b55, 0x3b55, 0x3b55, + 0x3b55, 0x3b54, 0x3b54, 0x3b54, 0x3b54, 0x3b54, 0x3b54, 0x3b54, + 0x3b54, 0x3b54, 0x3b53, 0x3b53, 0x3b53, 0x3b53, 0x3b53, 0x3b53, + 0x3b53, 0x3b53, 0x3b53, 0x3b52, 0x3b52, 0x3b52, 0x3b52, 0x3b52, + 0x3b52, 0x3b52, 0x3b52, 0x3b52, 0x3b51, 0x3b51, 0x3b51, 0x3b51, + 0x3b51, 0x3b51, 0x3b51, 0x3b51, 0x3b50, 0x3b50, 0x3b50, 0x3b50, + 0x3b50, 0x3b50, 0x3b50, 0x3b50, 0x3b50, 0x3b4f, 0x3b4f, 0x3b4f, + 0x3b4f, 0x3b4f, 0x3b4f, 0x3b4f, 0x3b4f, 0x3b4f, 0x3b4e, 0x3b4e, + 0x3b4e, 0x3b4e, 0x3b4e, 0x3b4e, 0x3b4e, 0x3b4e, 0x3b4e, 0x3b4d, + 0x3b4d, 0x3b4d, 0x3b4d, 0x3b4d, 0x3b4d, 0x3b4d, 0x3b4d, 0x3b4c, + 0x3b4c, 0x3b4c, 0x3b4c, 0x3b4c, 0x3b4c, 0x3b4c, 0x3b4c, 0x3b4c, + 0x3b4b, 0x3b4b, 0x3b4b, 0x3b4b, 0x3b4b, 0x3b4b, 0x3b4b, 0x3b4b, + 0x3b4b, 0x3b4a, 0x3b4a, 0x3b4a, 0x3b4a, 0x3b4a, 0x3b4a, 0x3b4a, + 0x3b4a, 0x3b4a, 0x3b49, 0x3b49, 0x3b49, 0x3b49, 0x3b49, 0x3b49, + 0x3b49, 0x3b49, 0x3b48, 0x3b48, 0x3b48, 0x3b48, 0x3b48, 0x3b48, + 0x3b48, 0x3b48, 0x3b48, 0x3b47, 0x3b47, 0x3b47, 0x3b47, 0x3b47, + 0x3b47, 0x3b47, 0x3b47, 0x3b47, 0x3b46, 0x3b46, 0x3b46, 0x3b46, + 0x3b46, 0x3b46, 0x3b46, 0x3b46, 0x3b46, 0x3b45, 0x3b45, 0x3b45, + 0x3b45, 0x3b45, 0x3b45, 0x3b45, 0x3b45, 0x3b45, 0x3b44, 0x3b44, + 0x3b44, 0x3b44, 0x3b44, 0x3b44, 0x3b44, 0x3b44, 0x3b43, 0x3b43, + 0x3b43, 0x3b43, 0x3b43, 0x3b43, 0x3b43, 0x3b43, 0x3b43, 0x3b42, + 0x3b42, 0x3b42, 0x3b42, 0x3b42, 0x3b42, 0x3b42, 0x3b42, 0x3b42, + 0x3b41, 0x3b41, 0x3b41, 0x3b41, 0x3b41, 0x3b41, 0x3b41, 0x3b41, + 0x3b41, 0x3b40, 0x3b40, 0x3b40, 0x3b40, 0x3b40, 0x3b40, 0x3b40, + 0x3b40, 0x3b40, 0x3b3f, 0x3b3f, 0x3b3f, 0x3b3f, 0x3b3f, 0x3b3f, + 0x3b3f, 0x3b3f, 0x3b3f, 0x3b3e, 0x3b3e, 0x3b3e, 0x3b3e, 0x3b3e, + 0x3b3e, 0x3b3e, 0x3b3e, 0x3b3d, 0x3b3d, 0x3b3d, 0x3b3d, 0x3b3d, + 0x3b3d, 0x3b3d, 0x3b3d, 0x3b3d, 0x3b3c, 0x3b3c, 0x3b3c, 0x3b3c, + 0x3b3c, 0x3b3c, 0x3b3c, 0x3b3c, 0x3b3c, 0x3b3b, 0x3b3b, 0x3b3b, + 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3a, 0x3b3a, + 0x3b3a, 0x3b3a, 0x3b3a, 0x3b3a, 0x3b3a, 0x3b3a, 0x3b3a, 0x3b39, + 0x3b39, 0x3b39, 0x3b39, 0x3b39, 0x3b39, 0x3b39, 0x3b39, 0x3b39, + 0x3b38, 0x3b38, 0x3b38, 0x3b38, 0x3b38, 0x3b38, 0x3b38, 0x3b38, + 0x3b38, 0x3b37, 0x3b37, 0x3b37, 0x3b37, 0x3b37, 0x3b37, 0x3b37, + 0x3b37, 0x3b36, 0x3b36, 0x3b36, 0x3b36, 0x3b36, 0x3b36, 0x3b36, + 0x3b36, 0x3b36, 0x3b35, 0x3b35, 0x3b35, 0x3b35, 0x3b35, 0x3b35, + 0x3b35, 0x3b35, 0x3b35, 0x3b34, 0x3b34, 0x3b34, 0x3b34, 0x3b34, + 0x3b34, 0x3b34, 0x3b34, 0x3b34, 0x3b33, 0x3b33, 0x3b33, 0x3b33, + 0x3b33, 0x3b33, 0x3b33, 0x3b33, 0x3b33, 0x3b32, 0x3b32, 0x3b32, + 0x3b32, 0x3b32, 0x3b32, 0x3b32, 0x3b32, 0x3b32, 0x3b31, 0x3b31, + 0x3b31, 0x3b31, 0x3b31, 0x3b31, 0x3b31, 0x3b31, 0x3b31, 0x3b30, + 0x3b30, 0x3b30, 0x3b30, 0x3b30, 0x3b30, 0x3b30, 0x3b30, 0x3b30, + 0x3b2f, 0x3b2f, 0x3b2f, 0x3b2f, 0x3b2f, 0x3b2f, 0x3b2f, 0x3b2f, + 0x3b2f, 0x3b2e, 0x3b2e, 0x3b2e, 0x3b2e, 0x3b2e, 0x3b2e, 0x3b2e, + 0x3b2e, 0x3b2d, 0x3b2d, 0x3b2d, 0x3b2d, 0x3b2d, 0x3b2d, 0x3b2d, + 0x3b2d, 0x3b2d, 0x3b2c, 0x3b2c, 0x3b2c, 0x3b2c, 0x3b2c, 0x3b2c, + 0x3b2c, 0x3b2c, 0x3b2c, 0x3b2b, 0x3b2b, 0x3b2b, 0x3b2b, 0x3b2b, + 0x3b2b, 0x3b2b, 0x3b2b, 0x3b2b, 0x3b2a, 0x3b2a, 0x3b2a, 0x3b2a, + 0x3b2a, 0x3b2a, 0x3b2a, 0x3b2a, 0x3b2a, 0x3b29, 0x3b29, 0x3b29, + 0x3b29, 0x3b29, 0x3b29, 0x3b29, 0x3b29, 0x3b29, 0x3b28, 0x3b28, + 0x3b28, 0x3b28, 0x3b28, 0x3b28, 0x3b28, 0x3b28, 0x3b28, 0x3b27, + 0x3b27, 0x3b27, 0x3b27, 0x3b27, 0x3b27, 0x3b27, 0x3b27, 0x3b27, + 0x3b26, 0x3b26, 0x3b26, 0x3b26, 0x3b26, 0x3b26, 0x3b26, 0x3b26, + 0x3b26, 0x3b25, 0x3b25, 0x3b25, 0x3b25, 0x3b25, 0x3b25, 0x3b25, + 0x3b25, 0x3b25, 0x3b24, 0x3b24, 0x3b24, 0x3b24, 0x3b24, 0x3b24, + 0x3b24, 0x3b24, 0x3b24, 0x3b23, 0x3b23, 0x3b23, 0x3b23, 0x3b23, + 0x3b23, 0x3b23, 0x3b23, 0x3b23, 0x3b22, 0x3b22, 0x3b22, 0x3b22, + 0x3b22, 0x3b22, 0x3b22, 0x3b22, 0x3b22, 0x3b21, 0x3b21, 0x3b21, + 0x3b21, 0x3b21, 0x3b21, 0x3b21, 0x3b21, 0x3b21, 0x3b20, 0x3b20, + 0x3b20, 0x3b20, 0x3b20, 0x3b20, 0x3b20, 0x3b20, 0x3b20, 0x3b1f, + 0x3b1f, 0x3b1f, 0x3b1f, 0x3b1f, 0x3b1f, 0x3b1f, 0x3b1f, 0x3b1f, + 0x3b1e, 0x3b1e, 0x3b1e, 0x3b1e, 0x3b1e, 0x3b1e, 0x3b1e, 0x3b1e, + 0x3b1e, 0x3b1d, 0x3b1d, 0x3b1d, 0x3b1d, 0x3b1d, 0x3b1d, 0x3b1d, + 0x3b1d, 0x3b1d, 0x3b1c, 0x3b1c, 0x3b1c, 0x3b1c, 0x3b1c, 0x3b1c, + 0x3b1c, 0x3b1c, 0x3b1c, 0x3b1b, 0x3b1b, 0x3b1b, 0x3b1b, 0x3b1b, + 0x3b1b, 0x3b1b, 0x3b1b, 0x3b1b, 0x3b1a, 0x3b1a, 0x3b1a, 0x3b1a, + 0x3b1a, 0x3b1a, 0x3b1a, 0x3b1a, 0x3b1a, 0x3b19, 0x3b19, 0x3b19, + 0x3b19, 0x3b19, 0x3b19, 0x3b19, 0x3b19, 0x3b19, 0x3b18, 0x3b18, + 0x3b18, 0x3b18, 0x3b18, 0x3b18, 0x3b18, 0x3b18, 0x3b18, 0x3b17, + 0x3b17, 0x3b17, 0x3b17, 0x3b17, 0x3b17, 0x3b17, 0x3b17, 0x3b17, + 0x3b16, 0x3b16, 0x3b16, 0x3b16, 0x3b16, 0x3b16, 0x3b16, 0x3b16, + 0x3b16, 0x3b15, 0x3b15, 0x3b15, 0x3b15, 0x3b15, 0x3b15, 0x3b15, + 0x3b15, 0x3b15, 0x3b14, 0x3b14, 0x3b14, 0x3b14, 0x3b14, 0x3b14, + 0x3b14, 0x3b14, 0x3b14, 0x3b13, 0x3b13, 0x3b13, 0x3b13, 0x3b13, + 0x3b13, 0x3b13, 0x3b13, 0x3b13, 0x3b12, 0x3b12, 0x3b12, 0x3b12, + 0x3b12, 0x3b12, 0x3b12, 0x3b12, 0x3b12, 0x3b11, 0x3b11, 0x3b11, + 0x3b11, 0x3b11, 0x3b11, 0x3b11, 0x3b11, 0x3b11, 0x3b10, 0x3b10, + 0x3b10, 0x3b10, 0x3b10, 0x3b10, 0x3b10, 0x3b10, 0x3b10, 0x3b0f, + 0x3b0f, 0x3b0f, 0x3b0f, 0x3b0f, 0x3b0e, 0x3b0e, 0x3b0e, 0x3b0e, + 0x3b0e, 0x3b0d, 0x3b0d, 0x3b0d, 0x3b0d, 0x3b0c, 0x3b0c, 0x3b0c, + 0x3b0c, 0x3b0c, 0x3b0b, 0x3b0b, 0x3b0b, 0x3b0b, 0x3b0b, 0x3b0a, + 0x3b0a, 0x3b0a, 0x3b0a, 0x3b09, 0x3b09, 0x3b09, 0x3b09, 0x3b09, + 0x3b08, 0x3b08, 0x3b08, 0x3b08, 0x3b07, 0x3b07, 0x3b07, 0x3b07, + 0x3b07, 0x3b06, 0x3b06, 0x3b06, 0x3b06, 0x3b05, 0x3b05, 0x3b05, + 0x3b05, 0x3b05, 0x3b04, 0x3b04, 0x3b04, 0x3b04, 0x3b03, 0x3b03, + 0x3b03, 0x3b03, 0x3b03, 0x3b02, 0x3b02, 0x3b02, 0x3b02, 0x3b02, + 0x3b01, 0x3b01, 0x3b01, 0x3b01, 0x3b00, 0x3b00, 0x3b00, 0x3b00, + 0x3b00, 0x3aff, 0x3aff, 0x3aff, 0x3aff, 0x3afe, 0x3afe, 0x3afe, + 0x3afe, 0x3afe, 0x3afd, 0x3afd, 0x3afd, 0x3afd, 0x3afc, 0x3afc, + 0x3afc, 0x3afc, 0x3afc, 0x3afb, 0x3afb, 0x3afb, 0x3afb, 0x3afb, + 0x3afa, 0x3afa, 0x3afa, 0x3afa, 0x3af9, 0x3af9, 0x3af9, 0x3af9, + 0x3af9, 0x3af8, 0x3af8, 0x3af8, 0x3af8, 0x3af7, 0x3af7, 0x3af7, + 0x3af7, 0x3af7, 0x3af6, 0x3af6, 0x3af6, 0x3af6, 0x3af6, 0x3af5, + 0x3af5, 0x3af5, 0x3af5, 0x3af4, 0x3af4, 0x3af4, 0x3af4, 0x3af4, + 0x3af3, 0x3af3, 0x3af3, 0x3af3, 0x3af2, 0x3af2, 0x3af2, 0x3af2, + 0x3af2, 0x3af1, 0x3af1, 0x3af1, 0x3af1, 0x3af1, 0x3af0, 0x3af0, + 0x3af0, 0x3af0, 0x3aef, 0x3aef, 0x3aef, 0x3aef, 0x3aef, 0x3aee, + 0x3aee, 0x3aee, 0x3aee, 0x3aed, 0x3aed, 0x3aed, 0x3aed, 0x3aed, + 0x3aec, 0x3aec, 0x3aec, 0x3aec, 0x3aec, 0x3aeb, 0x3aeb, 0x3aeb, + 0x3aeb, 0x3aea, 0x3aea, 0x3aea, 0x3aea, 0x3aea, 0x3ae9, 0x3ae9, + 0x3ae9, 0x3ae9, 0x3ae9, 0x3ae8, 0x3ae8, 0x3ae8, 0x3ae8, 0x3ae7, + 0x3ae7, 0x3ae7, 0x3ae7, 0x3ae7, 0x3ae6, 0x3ae6, 0x3ae6, 0x3ae6, + 0x3ae5, 0x3ae5, 0x3ae5, 0x3ae5, 0x3ae5, 0x3ae4, 0x3ae4, 0x3ae4, + 0x3ae4, 0x3ae4, 0x3ae3, 0x3ae3, 0x3ae3, 0x3ae3, 0x3ae2, 0x3ae2, + 0x3ae2, 0x3ae2, 0x3ae2, 0x3ae1, 0x3ae1, 0x3ae1, 0x3ae1, 0x3ae1, + 0x3ae0, 0x3ae0, 0x3ae0, 0x3ae0, 0x3adf, 0x3adf, 0x3adf, 0x3adf, + 0x3adf, 0x3ade, 0x3ade, 0x3ade, 0x3ade, 0x3ade, 0x3add, 0x3add, + 0x3add, 0x3add, 0x3adc, 0x3adc, 0x3adc, 0x3adc, 0x3adc, 0x3adb, + 0x3adb, 0x3adb, 0x3adb, 0x3adb, 0x3ada, 0x3ada, 0x3ada, 0x3ada, + 0x3ad9, 0x3ad9, 0x3ad9, 0x3ad9, 0x3ad9, 0x3ad8, 0x3ad8, 0x3ad8, + 0x3ad8, 0x3ad8, 0x3ad7, 0x3ad7, 0x3ad7, 0x3ad7, 0x3ad6, 0x3ad6, + 0x3ad6, 0x3ad6, 0x3ad6, 0x3ad5, 0x3ad5, 0x3ad5, 0x3ad5, 0x3ad5, + 0x3ad4, 0x3ad4, 0x3ad4, 0x3ad4, 0x3ad3, 0x3ad3, 0x3ad3, 0x3ad3, + 0x3ad3, 0x3ad2, 0x3ad2, 0x3ad2, 0x3ad2, 0x3ad2, 0x3ad1, 0x3ad1, + 0x3ad1, 0x3ad1, 0x3ad0, 0x3ad0, 0x3ad0, 0x3ad0, 0x3ad0, 0x3acf, + 0x3acf, 0x3acf, 0x3acf, 0x3acf, 0x3ace, 0x3ace, 0x3ace, 0x3ace, + 0x3ace, 0x3acd, 0x3acd, 0x3acd, 0x3acd, 0x3acc, 0x3acc, 0x3acc, + 0x3acc, 0x3acc, 0x3acb, 0x3acb, 0x3acb, 0x3acb, 0x3acb, 0x3aca, + 0x3aca, 0x3aca, 0x3aca, 0x3ac9, 0x3ac9, 0x3ac9, 0x3ac9, 0x3ac9, + 0x3ac8, 0x3ac8, 0x3ac8, 0x3ac8, 0x3ac8, 0x3ac7, 0x3ac7, 0x3ac7, + 0x3ac7, 0x3ac7, 0x3ac6, 0x3ac6, 0x3ac6, 0x3ac6, 0x3ac5, 0x3ac5, + 0x3ac5, 0x3ac5, 0x3ac5, 0x3ac4, 0x3ac4, 0x3ac4, 0x3ac4, 0x3ac4, + 0x3ac3, 0x3ac3, 0x3ac3, 0x3ac3, 0x3ac2, 0x3ac2, 0x3ac2, 0x3ac2, + 0x3ac2, 0x3ac1, 0x3ac1, 0x3ac1, 0x3ac1, 0x3ac1, 0x3ac0, 0x3ac0, + 0x3ac0, 0x3ac0, 0x3ac0, 0x3abf, 0x3abf, 0x3abf, 0x3abf, 0x3abe, + 0x3abe, 0x3abe, 0x3abe, 0x3abe, 0x3abd, 0x3abd, 0x3abd, 0x3abd, + 0x3abd, 0x3abc, 0x3abc, 0x3abc, 0x3abc, 0x3abc, 0x3abb, 0x3abb, + 0x3abb, 0x3abb, 0x3aba, 0x3aba, 0x3aba, 0x3aba, 0x3aba, 0x3ab9, + 0x3ab9, 0x3ab9, 0x3ab9, 0x3ab9, 0x3ab8, 0x3ab8, 0x3ab8, 0x3ab8, + 0x3ab8, 0x3ab7, 0x3ab7, 0x3ab7, 0x3ab7, 0x3ab6, 0x3ab6, 0x3ab6, + 0x3ab6, 0x3ab6, 0x3ab5, 0x3ab5, 0x3ab5, 0x3ab5, 0x3ab5, 0x3ab4, + 0x3ab4, 0x3ab4, 0x3ab4, 0x3ab4, 0x3ab3, 0x3ab3, 0x3ab3, 0x3ab3, + 0x3ab3, 0x3ab2, 0x3ab2, 0x3ab2, 0x3ab2, 0x3ab1, 0x3ab1, 0x3ab1, + 0x3ab1, 0x3ab1, 0x3ab0, 0x3ab0, 0x3ab0, 0x3ab0, 0x3ab0, 0x3aaf, + 0x3aaf, 0x3aaf, 0x3aaf, 0x3aaf, 0x3aae, 0x3aae, 0x3aae, 0x3aae, + 0x3aad, 0x3aad, 0x3aad, 0x3aad, 0x3aad, 0x3aac, 0x3aac, 0x3aac, + 0x3aac, 0x3aac, 0x3aab, 0x3aab, 0x3aab, 0x3aab, 0x3aab, 0x3aaa, + 0x3aaa, 0x3aaa, 0x3aaa, 0x3aaa, 0x3aa9, 0x3aa9, 0x3aa9, 0x3aa9, + 0x3aa8, 0x3aa8, 0x3aa8, 0x3aa8, 0x3aa8, 0x3aa7, 0x3aa7, 0x3aa7, + 0x3aa7, 0x3aa7, 0x3aa6, 0x3aa6, 0x3aa6, 0x3aa6, 0x3aa6, 0x3aa5, + 0x3aa5, 0x3aa5, 0x3aa5, 0x3aa5, 0x3aa4, 0x3aa4, 0x3aa4, 0x3aa4, + 0x3aa4, 0x3aa3, 0x3aa3, 0x3aa3, 0x3aa3, 0x3aa2, 0x3aa2, 0x3aa2, + 0x3aa2, 0x3aa2, 0x3aa1, 0x3aa1, 0x3aa1, 0x3aa1, 0x3aa1, 0x3aa0, + 0x3aa0, 0x3aa0, 0x3aa0, 0x3aa0, 0x3a9f, 0x3a9f, 0x3a9f, 0x3a9f, + 0x3a9f, 0x3a9e, 0x3a9e, 0x3a9e, 0x3a9e, 0x3a9e, 0x3a9d, 0x3a9d, + 0x3a9d, 0x3a9d, 0x3a9c, 0x3a9c, 0x3a9c, 0x3a9c, 0x3a9c, 0x3a9b, + 0x3a9b, 0x3a9b, 0x3a9b, 0x3a9b, 0x3a9a, 0x3a9a, 0x3a9a, 0x3a9a, + 0x3a9a, 0x3a99, 0x3a99, 0x3a99, 0x3a99, 0x3a99, 0x3a98, 0x3a98, + 0x3a98, 0x3a98, 0x3a98, 0x3a97, 0x3a97, 0x3a97, 0x3a97, 0x3a96, + 0x3a96, 0x3a96, 0x3a96, 0x3a96, 0x3a95, 0x3a95, 0x3a95, 0x3a95, + 0x3a95, 0x3a94, 0x3a94, 0x3a94, 0x3a94, 0x3a94, 0x3a93, 0x3a93, + 0x3a93, 0x3a93, 0x3a93, 0x3a92, 0x3a92, 0x3a92, 0x3a92, 0x3a92, + 0x3a91, 0x3a91, 0x3a91, 0x3a91, 0x3a91, 0x3a90, 0x3a90, 0x3a90, + 0x3a90, 0x3a90, 0x3a8f, 0x3a8f, 0x3a8f, 0x3a8f, 0x3a8e, 0x3a8e, + 0x3a8e, 0x3a8e, 0x3a8e, 0x3a8d, 0x3a8d, 0x3a8d, 0x3a8d, 0x3a8d, + 0x3a8c, 0x3a8c, 0x3a8c, 0x3a8c, 0x3a8c, 0x3a8b, 0x3a8b, 0x3a8b, + 0x3a8b, 0x3a8b, 0x3a8a, 0x3a8a, 0x3a8a, 0x3a8a, 0x3a8a, 0x3a89, + 0x3a89, 0x3a89, 0x3a89, 0x3a89, 0x3a88, 0x3a88, 0x3a88, 0x3a88, + 0x3a88, 0x3a87, 0x3a87, 0x3a87, 0x3a87, 0x3a87, 0x3a86, 0x3a86, + 0x3a86, 0x3a86, 0x3a85, 0x3a85, 0x3a85, 0x3a85, 0x3a85, 0x3a84, + 0x3a84, 0x3a84, 0x3a84, 0x3a84, 0x3a83, 0x3a83, 0x3a83, 0x3a83, + 0x3a83, 0x3a82, 0x3a82, 0x3a82, 0x3a82, 0x3a82, 0x3a81, 0x3a81, + 0x3a81, 0x3a81, 0x3a81, 0x3a80, 0x3a80, 0x3a80, 0x3a80, 0x3a80, + 0x3a7f, 0x3a7f, 0x3a7f, 0x3a7f, 0x3a7f, 0x3a7e, 0x3a7e, 0x3a7e, + 0x3a7e, 0x3a7e, 0x3a7d, 0x3a7d, 0x3a7d, 0x3a7d, 0x3a7d, 0x3a7c, + 0x3a7c, 0x3a7c, 0x3a7c, 0x3a7c, 0x3a7b, 0x3a7b, 0x3a7b, 0x3a7b, + 0x3a7b, 0x3a7a, 0x3a7a, 0x3a7a, 0x3a7a, 0x3a7a, 0x3a79, 0x3a79, + 0x3a79, 0x3a79, 0x3a78, 0x3a78, 0x3a78, 0x3a78, 0x3a78, 0x3a77, + 0x3a77, 0x3a77, 0x3a77, 0x3a77, 0x3a76, 0x3a76, 0x3a76, 0x3a76, + 0x3a76, 0x3a75, 0x3a75, 0x3a75, 0x3a75, 0x3a75, 0x3a74, 0x3a74, + 0x3a74, 0x3a74, 0x3a74, 0x3a73, 0x3a73, 0x3a73, 0x3a73, 0x3a73, + 0x3a72, 0x3a72, 0x3a72, 0x3a72, 0x3a72, 0x3a71, 0x3a71, 0x3a71, + 0x3a71, 0x3a71, 0x3a70, 0x3a70, 0x3a70, 0x3a70, 0x3a70, 0x3a6f, + 0x3a6f, 0x3a6f, 0x3a6f, 0x3a6f, 0x3a6e, 0x3a6e, 0x3a6e, 0x3a6e, + 0x3a6e, 0x3a6d, 0x3a6d, 0x3a6d, 0x3a6d, 0x3a6d, 0x3a6c, 0x3a6c, + 0x3a6c, 0x3a6c, 0x3a6c, 0x3a6b, 0x3a6b, 0x3a6b, 0x3a6b, 0x3a6b, + 0x3a6a, 0x3a6a, 0x3a6a, 0x3a6a, 0x3a6a, 0x3a69, 0x3a69, 0x3a69, + 0x3a69, 0x3a69, 0x3a68, 0x3a68, 0x3a68, 0x3a68, 0x3a68, 0x3a67, + 0x3a67, 0x3a67, 0x3a67, 0x3a67, 0x3a66, 0x3a66, 0x3a66, 0x3a66, + 0x3a66, 0x3a65, 0x3a65, 0x3a65, 0x3a65, 0x3a65, 0x3a64, 0x3a64, + 0x3a64, 0x3a64, 0x3a64, 0x3a63, 0x3a63, 0x3a63, 0x3a63, 0x3a63, + 0x3a62, 0x3a62, 0x3a62, 0x3a62, 0x3a62, 0x3a61, 0x3a61, 0x3a61, + 0x3a61, 0x3a61, 0x3a60, 0x3a60, 0x3a60, 0x3a60, 0x3a60, 0x3a5f, + 0x3a5f, 0x3a5f, 0x3a5f, 0x3a5f, 0x3a5e, 0x3a5e, 0x3a5e, 0x3a5e, + 0x3a5e, 0x3a5d, 0x3a5d, 0x3a5d, 0x3a5d, 0x3a5d, 0x3a5c, 0x3a5c, + 0x3a5c, 0x3a5c, 0x3a5c, 0x3a5b, 0x3a5b, 0x3a5b, 0x3a5b, 0x3a5b, + 0x3a5a, 0x3a5a, 0x3a5a, 0x3a5a, 0x3a5a, 0x3a59, 0x3a59, 0x3a59, + 0x3a59, 0x3a59, 0x3a58, 0x3a58, 0x3a58, 0x3a58, 0x3a58, 0x3a57, + 0x3a57, 0x3a57, 0x3a57, 0x3a57, 0x3a56, 0x3a56, 0x3a56, 0x3a56, + 0x3a56, 0x3a55, 0x3a55, 0x3a55, 0x3a55, 0x3a55, 0x3a54, 0x3a54, + 0x3a54, 0x3a54, 0x3a54, 0x3a54, 0x3a53, 0x3a53, 0x3a53, 0x3a53, + 0x3a53, 0x3a52, 0x3a52, 0x3a52, 0x3a52, 0x3a52, 0x3a51, 0x3a51, + 0x3a51, 0x3a51, 0x3a51, 0x3a50, 0x3a50, 0x3a50, 0x3a50, 0x3a50, + 0x3a4f, 0x3a4f, 0x3a4f, 0x3a4f, 0x3a4f, 0x3a4e, 0x3a4e, 0x3a4e, + 0x3a4e, 0x3a4e, 0x3a4d, 0x3a4d, 0x3a4d, 0x3a4d, 0x3a4d, 0x3a4c, + 0x3a4c, 0x3a4c, 0x3a4c, 0x3a4c, 0x3a4b, 0x3a4b, 0x3a4b, 0x3a4b, + 0x3a4b, 0x3a4a, 0x3a4a, 0x3a4a, 0x3a4a, 0x3a4a, 0x3a49, 0x3a49, + 0x3a49, 0x3a49, 0x3a49, 0x3a48, 0x3a48, 0x3a48, 0x3a48, 0x3a48, + 0x3a47, 0x3a47, 0x3a47, 0x3a47, 0x3a47, 0x3a47, 0x3a46, 0x3a46, + 0x3a46, 0x3a46, 0x3a46, 0x3a45, 0x3a45, 0x3a45, 0x3a45, 0x3a45, + 0x3a44, 0x3a44, 0x3a44, 0x3a44, 0x3a44, 0x3a43, 0x3a43, 0x3a43, + 0x3a43, 0x3a43, 0x3a42, 0x3a42, 0x3a42, 0x3a42, 0x3a42, 0x3a41, + 0x3a41, 0x3a41, 0x3a41, 0x3a41, 0x3a40, 0x3a40, 0x3a40, 0x3a40, + 0x3a40, 0x3a3f, 0x3a3f, 0x3a3f, 0x3a3f, 0x3a3f, 0x3a3e, 0x3a3e, + 0x3a3e, 0x3a3e, 0x3a3e, 0x3a3e, 0x3a3d, 0x3a3d, 0x3a3d, 0x3a3d, + 0x3a3d, 0x3a3c, 0x3a3c, 0x3a3c, 0x3a3c, 0x3a3c, 0x3a3b, 0x3a3b, + 0x3a3b, 0x3a3b, 0x3a3a, 0x3a3a, 0x3a39, 0x3a39, 0x3a39, 0x3a38, + 0x3a38, 0x3a37, 0x3a37, 0x3a37, 0x3a36, 0x3a36, 0x3a36, 0x3a35, + 0x3a35, 0x3a34, 0x3a34, 0x3a34, 0x3a33, 0x3a33, 0x3a32, 0x3a32, + 0x3a32, 0x3a31, 0x3a31, 0x3a31, 0x3a30, 0x3a30, 0x3a2f, 0x3a2f, + 0x3a2f, 0x3a2e, 0x3a2e, 0x3a2d, 0x3a2d, 0x3a2d, 0x3a2c, 0x3a2c, + 0x3a2b, 0x3a2b, 0x3a2b, 0x3a2a, 0x3a2a, 0x3a2a, 0x3a29, 0x3a29, + 0x3a28, 0x3a28, 0x3a28, 0x3a27, 0x3a27, 0x3a26, 0x3a26, 0x3a26, + 0x3a25, 0x3a25, 0x3a25, 0x3a24, 0x3a24, 0x3a23, 0x3a23, 0x3a23, + 0x3a22, 0x3a22, 0x3a21, 0x3a21, 0x3a21, 0x3a20, 0x3a20, 0x3a20, + 0x3a1f, 0x3a1f, 0x3a1e, 0x3a1e, 0x3a1e, 0x3a1d, 0x3a1d, 0x3a1d, + 0x3a1c, 0x3a1c, 0x3a1b, 0x3a1b, 0x3a1b, 0x3a1a, 0x3a1a, 0x3a19, + 0x3a19, 0x3a19, 0x3a18, 0x3a18, 0x3a18, 0x3a17, 0x3a17, 0x3a16, + 0x3a16, 0x3a16, 0x3a15, 0x3a15, 0x3a15, 0x3a14, 0x3a14, 0x3a13, + 0x3a13, 0x3a13, 0x3a12, 0x3a12, 0x3a11, 0x3a11, 0x3a11, 0x3a10, + 0x3a10, 0x3a10, 0x3a0f, 0x3a0f, 0x3a0e, 0x3a0e, 0x3a0e, 0x3a0d, + 0x3a0d, 0x3a0d, 0x3a0c, 0x3a0c, 0x3a0b, 0x3a0b, 0x3a0b, 0x3a0a, + 0x3a0a, 0x3a0a, 0x3a09, 0x3a09, 0x3a08, 0x3a08, 0x3a08, 0x3a07, + 0x3a07, 0x3a07, 0x3a06, 0x3a06, 0x3a05, 0x3a05, 0x3a05, 0x3a04, + 0x3a04, 0x3a04, 0x3a03, 0x3a03, 0x3a02, 0x3a02, 0x3a02, 0x3a01, + 0x3a01, 0x3a01, 0x3a00, 0x3a00, 0x39ff, 0x39ff, 0x39ff, 0x39fe, + 0x39fe, 0x39fe, 0x39fd, 0x39fd, 0x39fc, 0x39fc, 0x39fc, 0x39fb, + 0x39fb, 0x39fb, 0x39fa, 0x39fa, 0x39f9, 0x39f9, 0x39f9, 0x39f8, + 0x39f8, 0x39f8, 0x39f7, 0x39f7, 0x39f6, 0x39f6, 0x39f6, 0x39f5, + 0x39f5, 0x39f5, 0x39f4, 0x39f4, 0x39f3, 0x39f3, 0x39f3, 0x39f2, + 0x39f2, 0x39f2, 0x39f1, 0x39f1, 0x39f0, 0x39f0, 0x39f0, 0x39ef, + 0x39ef, 0x39ef, 0x39ee, 0x39ee, 0x39ed, 0x39ed, 0x39ed, 0x39ec, + 0x39ec, 0x39ec, 0x39eb, 0x39eb, 0x39eb, 0x39ea, 0x39ea, 0x39e9, + 0x39e9, 0x39e9, 0x39e8, 0x39e8, 0x39e8, 0x39e7, 0x39e7, 0x39e6, + 0x39e6, 0x39e6, 0x39e5, 0x39e5, 0x39e5, 0x39e4, 0x39e4, 0x39e4, + 0x39e3, 0x39e3, 0x39e2, 0x39e2, 0x39e2, 0x39e1, 0x39e1, 0x39e1, + 0x39e0, 0x39e0, 0x39df, 0x39df, 0x39df, 0x39de, 0x39de, 0x39de, + 0x39dd, 0x39dd, 0x39dd, 0x39dc, 0x39dc, 0x39db, 0x39db, 0x39db, + 0x39da, 0x39da, 0x39da, 0x39d9, 0x39d9, 0x39d9, 0x39d8, 0x39d8, + 0x39d7, 0x39d7, 0x39d7, 0x39d6, 0x39d6, 0x39d6, 0x39d5, 0x39d5, + 0x39d5, 0x39d4, 0x39d4, 0x39d3, 0x39d3, 0x39d3, 0x39d2, 0x39d2, + 0x39d2, 0x39d1, 0x39d1, 0x39d1, 0x39d0, 0x39d0, 0x39cf, 0x39cf, + 0x39cf, 0x39ce, 0x39ce, 0x39ce, 0x39cd, 0x39cd, 0x39cd, 0x39cc, + 0x39cc, 0x39cb, 0x39cb, 0x39cb, 0x39ca, 0x39ca, 0x39ca, 0x39c9, + 0x39c9, 0x39c9, 0x39c8, 0x39c8, 0x39c7, 0x39c7, 0x39c7, 0x39c6, + 0x39c6, 0x39c6, 0x39c5, 0x39c5, 0x39c5, 0x39c4, 0x39c4, 0x39c3, + 0x39c3, 0x39c3, 0x39c2, 0x39c2, 0x39c2, 0x39c1, 0x39c1, 0x39c1, + 0x39c0, 0x39c0, 0x39c0, 0x39bf, 0x39bf, 0x39be, 0x39be, 0x39be, + 0x39bd, 0x39bd, 0x39bd, 0x39bc, 0x39bc, 0x39bc, 0x39bb, 0x39bb, + 0x39bb, 0x39ba, 0x39ba, 0x39b9, 0x39b9, 0x39b9, 0x39b8, 0x39b8, + 0x39b8, 0x39b7, 0x39b7, 0x39b7, 0x39b6, 0x39b6, 0x39b5, 0x39b5, + 0x39b5, 0x39b4, 0x39b4, 0x39b4, 0x39b3, 0x39b3, 0x39b3, 0x39b2, + 0x39b2, 0x39b2, 0x39b1, 0x39b1, 0x39b1, 0x39b0, 0x39b0, 0x39af, + 0x39af, 0x39af, 0x39ae, 0x39ae, 0x39ae, 0x39ad, 0x39ad, 0x39ad, + 0x39ac, 0x39ac, 0x39ac, 0x39ab, 0x39ab, 0x39aa, 0x39aa, 0x39aa, + 0x39a9, 0x39a9, 0x39a9, 0x39a8, 0x39a8, 0x39a8, 0x39a7, 0x39a7, + 0x39a7, 0x39a6, 0x39a6, 0x39a6, 0x39a5, 0x39a5, 0x39a4, 0x39a4, + 0x39a4, 0x39a3, 0x39a3, 0x39a3, 0x39a2, 0x39a2, 0x39a2, 0x39a1, + 0x39a1, 0x39a1, 0x39a0, 0x39a0, 0x39a0, 0x399f, 0x399f, 0x399e, + 0x399e, 0x399e, 0x399d, 0x399d, 0x399d, 0x399c, 0x399c, 0x399c, + 0x399b, 0x399b, 0x399b, 0x399a, 0x399a, 0x399a, 0x3999, 0x3999, + 0x3999, 0x3998, 0x3998, 0x3997, 0x3997, 0x3997, 0x3996, 0x3996, + 0x3996, 0x3995, 0x3995, 0x3995, 0x3994, 0x3994, 0x3994, 0x3993, + 0x3993, 0x3993, 0x3992, 0x3992, 0x3992, 0x3991, 0x3991, 0x3991, + 0x3990, 0x3990, 0x398f, 0x398f, 0x398f, 0x398e, 0x398e, 0x398e, + 0x398d, 0x398d, 0x398d, 0x398c, 0x398c, 0x398c, 0x398b, 0x398b, + 0x398b, 0x398a, 0x398a, 0x398a, 0x3989, 0x3989, 0x3989, 0x3988, + 0x3988, 0x3987, 0x3987, 0x3987, 0x3986, 0x3986, 0x3986, 0x3985, + 0x3985, 0x3985, 0x3984, 0x3984, 0x3984, 0x3983, 0x3983, 0x3983, + 0x3982, 0x3982, 0x3982, 0x3981, 0x3981, 0x3981, 0x3980, 0x3980, + 0x3980, 0x397f, 0x397f, 0x397f, 0x397e, 0x397e, 0x397e, 0x397d, + 0x397d, 0x397c, 0x397c, 0x397c, 0x397b, 0x397b, 0x397b, 0x397a, + 0x397a, 0x397a, 0x3979, 0x3979, 0x3979, 0x3978, 0x3978, 0x3978, + 0x3977, 0x3977, 0x3977, 0x3976, 0x3976, 0x3976, 0x3975, 0x3975, + 0x3975, 0x3974, 0x3974, 0x3974, 0x3973, 0x3973, 0x3973, 0x3972, + 0x3972, 0x3972, 0x3971, 0x3971, 0x3971, 0x3970, 0x3970, 0x3970, + 0x396f, 0x396f, 0x396e, 0x396e, 0x396e, 0x396d, 0x396d, 0x396d, + 0x396c, 0x396c, 0x396c, 0x396b, 0x396b, 0x396b, 0x396a, 0x396a, + 0x396a, 0x3969, 0x3969, 0x3969, 0x3968, 0x3968, 0x3968, 0x3967, + 0x3967, 0x3967, 0x3966, 0x3966, 0x3966, 0x3965, 0x3965, 0x3965, + 0x3964, 0x3964, 0x3964, 0x3963, 0x3963, 0x3963, 0x3962, 0x3962, + 0x3962, 0x3961, 0x3961, 0x3961, 0x3960, 0x3960, 0x3960, 0x395f, + 0x395f, 0x395f, 0x395e, 0x395e, 0x395e, 0x395d, 0x395d, 0x395d, + 0x395c, 0x395c, 0x395c, 0x395b, 0x395b, 0x395b, 0x395a, 0x395a, + 0x395a, 0x3959, 0x3959, 0x3959, 0x3958, 0x3958, 0x3958, 0x3957, + 0x3957, 0x3957, 0x3956, 0x3956, 0x3956, 0x3955, 0x3955, 0x3955, + 0x3954, 0x3954, 0x3954, 0x3953, 0x3953, 0x3953, 0x3952, 0x3952, + 0x3952, 0x3951, 0x3951, 0x3951, 0x3950, 0x3950, 0x3950, 0x394f, + 0x394f, 0x394f, 0x394e, 0x394e, 0x394e, 0x394d, 0x394d, 0x394d, + 0x394c, 0x394c, 0x394c, 0x394b, 0x394b, 0x394b, 0x394a, 0x394a, + 0x394a, 0x3949, 0x3949, 0x3949, 0x3948, 0x3948, 0x3948, 0x3947, + 0x3947, 0x3947, 0x3946, 0x3946, 0x3946, 0x3945, 0x3945, 0x3945, + 0x3944, 0x3944, 0x3944, 0x3943, 0x3943, 0x3943, 0x3942, 0x3942, + 0x3942, 0x3941, 0x3941, 0x3941, 0x3940, 0x3940, 0x3940, 0x393f, + 0x393f, 0x393f, 0x393e, 0x393e, 0x393e, 0x393d, 0x393d, 0x393d, + 0x393c, 0x393c, 0x393c, 0x393c, 0x393b, 0x393b, 0x393b, 0x393a, + 0x393a, 0x393a, 0x3939, 0x3939, 0x3939, 0x3938, 0x3938, 0x3938, + 0x3937, 0x3937, 0x3937, 0x3936, 0x3936, 0x3936, 0x3935, 0x3935, + 0x3935, 0x3934, 0x3934, 0x3934, 0x3933, 0x3933, 0x3933, 0x3932, + 0x3932, 0x3932, 0x3931, 0x3931, 0x3931, 0x3930, 0x3930, 0x3930, + 0x392f, 0x392f, 0x392f, 0x392e, 0x392e, 0x392e, 0x392e, 0x392d, + 0x392d, 0x392d, 0x392c, 0x392c, 0x392c, 0x392b, 0x392b, 0x392b, + 0x392a, 0x392a, 0x392a, 0x3929, 0x3929, 0x3929, 0x3928, 0x3928, + 0x3928, 0x3927, 0x3927, 0x3927, 0x3926, 0x3926, 0x3926, 0x3925, + 0x3925, 0x3925, 0x3924, 0x3924, 0x3924, 0x3924, 0x3923, 0x3923, + 0x3923, 0x3922, 0x3922, 0x3922, 0x3921, 0x3921, 0x3921, 0x3920, + 0x3920, 0x3920, 0x391f, 0x391f, 0x391f, 0x391e, 0x391e, 0x391e, + 0x391d, 0x391d, 0x391d, 0x391c, 0x391c, 0x391c, 0x391c, 0x391b, + 0x391b, 0x391b, 0x391a, 0x391a, 0x391a, 0x3919, 0x3919, 0x3919, + 0x3918, 0x3918, 0x3918, 0x3917, 0x3917, 0x3917, 0x3916, 0x3916, + 0x3916, 0x3915, 0x3915, 0x3915, 0x3915, 0x3914, 0x3914, 0x3914, + 0x3913, 0x3913, 0x3913, 0x3912, 0x3912, 0x3912, 0x3911, 0x3911, + 0x3911, 0x3910, 0x3910, 0x3910, 0x390f, 0x390f, 0x390f, 0x390e, + 0x390e, 0x390e, 0x390e, 0x390d, 0x390d, 0x390d, 0x390c, 0x390c, + 0x390c, 0x390b, 0x390b, 0x390b, 0x390a, 0x390a, 0x390a, 0x3909, + 0x3909, 0x3909, 0x3909, 0x3908, 0x3908, 0x3908, 0x3907, 0x3907, + 0x3907, 0x3906, 0x3906, 0x3906, 0x3905, 0x3905, 0x3905, 0x3904, + 0x3904, 0x3904, 0x3903, 0x3903, 0x3903, 0x3903, 0x3902, 0x3902, + 0x3902, 0x3901, 0x3901, 0x3901, 0x3900, 0x3900, 0x3900, 0x38ff, + 0x38ff, 0x38ff, 0x38fe, 0x38fe, 0x38fe, 0x38fe, 0x38fd, 0x38fd, + 0x38fd, 0x38fc, 0x38fc, 0x38fc, 0x38fb, 0x38fb, 0x38fb, 0x38fa, + 0x38fa, 0x38fa, 0x38f9, 0x38f9, 0x38f9, 0x38f9, 0x38f8, 0x38f8, + 0x38f8, 0x38f7, 0x38f7, 0x38f7, 0x38f6, 0x38f6, 0x38f6, 0x38f5, + 0x38f5, 0x38f5, 0x38f5, 0x38f4, 0x38f4, 0x38f4, 0x38f3, 0x38f3, + 0x38f3, 0x38f2, 0x38f2, 0x38f2, 0x38f1, 0x38f1, 0x38f1, 0x38f1, + 0x38f0, 0x38f0, 0x38f0, 0x38ef, 0x38ef, 0x38ef, 0x38ee, 0x38ee, + 0x38ee, 0x38ed, 0x38ed, 0x38ed, 0x38ed, 0x38ec, 0x38ec, 0x38ec, + 0x38eb, 0x38eb, 0x38eb, 0x38ea, 0x38ea, 0x38ea, 0x38e9, 0x38e9, + 0x38e9, 0x38e9, 0x38e8, 0x38e8, 0x38e8, 0x38e7, 0x38e7, 0x38e7, + 0x38e6, 0x38e6, 0x38e6, 0x38e5, 0x38e5, 0x38e5, 0x38e5, 0x38e4, + 0x38e4, 0x38e4, 0x38e3, 0x38e3, 0x38e3, 0x38e2, 0x38e2, 0x38e2, + 0x38e1, 0x38e1, 0x38e1, 0x38e1, 0x38e0, 0x38e0, 0x38e0, 0x38df, + 0x38df, 0x38df, 0x38de, 0x38de, 0x38de, 0x38de, 0x38dd, 0x38dd, + 0x38dd, 0x38dc, 0x38dc, 0x38dc, 0x38db, 0x38db, 0x38db, 0x38da, + 0x38da, 0x38da, 0x38d9, 0x38d8, 0x38d8, 0x38d7, 0x38d7, 0x38d6, + 0x38d5, 0x38d5, 0x38d4, 0x38d4, 0x38d3, 0x38d2, 0x38d2, 0x38d1, + 0x38d1, 0x38d0, 0x38cf, 0x38cf, 0x38ce, 0x38ce, 0x38cd, 0x38cc, + 0x38cc, 0x38cb, 0x38cb, 0x38ca, 0x38c9, 0x38c9, 0x38c8, 0x38c8, + 0x38c7, 0x38c6, 0x38c6, 0x38c5, 0x38c5, 0x38c4, 0x38c3, 0x38c3, + 0x38c2, 0x38c2, 0x38c1, 0x38c0, 0x38c0, 0x38bf, 0x38bf, 0x38be, + 0x38bd, 0x38bd, 0x38bc, 0x38bc, 0x38bb, 0x38ba, 0x38ba, 0x38b9, + 0x38b9, 0x38b8, 0x38b7, 0x38b7, 0x38b6, 0x38b6, 0x38b5, 0x38b5, + 0x38b4, 0x38b3, 0x38b3, 0x38b2, 0x38b2, 0x38b1, 0x38b0, 0x38b0, + 0x38af, 0x38af, 0x38ae, 0x38ae, 0x38ad, 0x38ac, 0x38ac, 0x38ab, + 0x38ab, 0x38aa, 0x38a9, 0x38a9, 0x38a8, 0x38a8, 0x38a7, 0x38a7, + 0x38a6, 0x38a5, 0x38a5, 0x38a4, 0x38a4, 0x38a3, 0x38a2, 0x38a2, + 0x38a1, 0x38a1, 0x38a0, 0x38a0, 0x389f, 0x389e, 0x389e, 0x389d, + 0x389d, 0x389c, 0x389c, 0x389b, 0x389a, 0x389a, 0x3899, 0x3899, + 0x3898, 0x3897, 0x3897, 0x3896, 0x3896, 0x3895, 0x3895, 0x3894, + 0x3893, 0x3893, 0x3892, 0x3892, 0x3891, 0x3891, 0x3890, 0x388f, + 0x388f, 0x388e, 0x388e, 0x388d, 0x388d, 0x388c, 0x388c, 0x388b, + 0x388a, 0x388a, 0x3889, 0x3889, 0x3888, 0x3888, 0x3887, 0x3886, + 0x3886, 0x3885, 0x3885, 0x3884, 0x3884, 0x3883, 0x3882, 0x3882, + 0x3881, 0x3881, 0x3880, 0x3880, 0x387f, 0x387f, 0x387e, 0x387d, + 0x387d, 0x387c, 0x387c, 0x387b, 0x387b, 0x387a, 0x3879, 0x3879, + 0x3878, 0x3878, 0x3877, 0x3877, 0x3876, 0x3876, 0x3875, 0x3874, + 0x3874, 0x3873, 0x3873, 0x3872, 0x3872, 0x3871, 0x3871, 0x3870, + 0x386f, 0x386f, 0x386e, 0x386e, 0x386d, 0x386d, 0x386c, 0x386c, + 0x386b, 0x386a, 0x386a, 0x3869, 0x3869, 0x3868, 0x3868, 0x3867, + 0x3867, 0x3866, 0x3866, 0x3865, 0x3864, 0x3864, 0x3863, 0x3863, + 0x3862, 0x3862, 0x3861, 0x3861, 0x3860, 0x385f, 0x385f, 0x385e, + 0x385e, 0x385d, 0x385d, 0x385c, 0x385c, 0x385b, 0x385b, 0x385a, + 0x3859, 0x3859, 0x3858, 0x3858, 0x3857, 0x3857, 0x3856, 0x3856, + 0x3855, 0x3855, 0x3854, 0x3854, 0x3853, 0x3852, 0x3852, 0x3851, + 0x3851, 0x3850, 0x3850, 0x384f, 0x384f, 0x384e, 0x384e, 0x384d, + 0x384d, 0x384c, 0x384b, 0x384b, 0x384a, 0x384a, 0x3849, 0x3849, + 0x3848, 0x3848, 0x3847, 0x3847, 0x3846, 0x3846, 0x3845, 0x3844, + 0x3844, 0x3843, 0x3843, 0x3842, 0x3842, 0x3841, 0x3841, 0x3840, + 0x3840, 0x383f, 0x383f, 0x383e, 0x383e, 0x383d, 0x383d, 0x383c, + 0x383b, 0x383b, 0x383a, 0x383a, 0x3839, 0x3839, 0x3838, 0x3838, + 0x3837, 0x3837, 0x3836, 0x3836, 0x3835, 0x3835, 0x3834, 0x3834, + 0x3833, 0x3832, 0x3832, 0x3831, 0x3831, 0x3830, 0x3830, 0x382f, + 0x382f, 0x382e, 0x382e, 0x382d, 0x382d, 0x382c, 0x382c, 0x382b, + 0x382b, 0x382a, 0x382a, 0x3829, 0x3829, 0x3828, 0x3828, 0x3827, + 0x3826, 0x3826, 0x3825, 0x3825, 0x3824, 0x3824, 0x3823, 0x3823, + 0x3822, 0x3822, 0x3821, 0x3821, 0x3820, 0x3820, 0x381f, 0x381f, + 0x381e, 0x381e, 0x381d, 0x381d, 0x381c, 0x381c, 0x381b, 0x381b, + 0x381a, 0x381a, 0x3819, 0x3819, 0x3818, 0x3818, 0x3817, 0x3817, + 0x3816, 0x3816, 0x3815, 0x3814, 0x3814, 0x3813, 0x3813, 0x3812, + 0x3812, 0x3811, 0x3811, 0x3810, 0x3810, 0x380f, 0x380f, 0x380e, + 0x380e, 0x380d, 0x380d, 0x380c, 0x380c, 0x380b, 0x380b, 0x380a, + 0x380a, 0x3809, 0x3809, 0x3808, 0x3808, 0x3807, 0x3807, 0x3806, + 0x3806, 0x3805, 0x3805, 0x3804, 0x3804, 0x3803, 0x3803, 0x3802, + 0x3802, 0x3801, 0x3801, 0x3800, 0x3800, 0x37ff, 0x37fe, 0x37fd, + 0x37fc, 0x37fb, 0x37fa, 0x37f9, 0x37f8, 0x37f7, 0x37f6, 0x37f5, + 0x37f4, 0x37f3, 0x37f2, 0x37f1, 0x37f0, 0x37ef, 0x37ee, 0x37ed, + 0x37ec, 0x37eb, 0x37ea, 0x37e9, 0x37e8, 0x37e7, 0x37e6, 0x37e5, + 0x37e4, 0x37e3, 0x37e2, 0x37e1, 0x37e0, 0x37df, 0x37de, 0x37dd, + 0x37dc, 0x37db, 0x37da, 0x37d9, 0x37d8, 0x37d7, 0x37d6, 0x37d5, + 0x37d4, 0x37d3, 0x37d2, 0x37d1, 0x37d0, 0x37cf, 0x37ce, 0x37cd, + 0x37cc, 0x37cb, 0x37ca, 0x37c9, 0x37c8, 0x37c7, 0x37c6, 0x37c5, + 0x37c4, 0x37c3, 0x37c3, 0x37c2, 0x37c1, 0x37c0, 0x37bf, 0x37be, + 0x37bd, 0x37bc, 0x37bb, 0x37ba, 0x37b9, 0x37b8, 0x37b7, 0x37b6, + 0x37b5, 0x37b4, 0x37b3, 0x37b2, 0x37b1, 0x37b0, 0x37af, 0x37ae, + 0x37ad, 0x37ac, 0x37ab, 0x37aa, 0x37a9, 0x37a8, 0x37a8, 0x37a7, + 0x37a6, 0x37a5, 0x37a4, 0x37a3, 0x37a2, 0x37a1, 0x37a0, 0x379f, + 0x379e, 0x379d, 0x379c, 0x379b, 0x379a, 0x3799, 0x3798, 0x3797, + 0x3796, 0x3795, 0x3794, 0x3794, 0x3793, 0x3792, 0x3791, 0x3790, + 0x378f, 0x378e, 0x378d, 0x378c, 0x378b, 0x378a, 0x3789, 0x3788, + 0x3787, 0x3786, 0x3785, 0x3784, 0x3784, 0x3783, 0x3782, 0x3781, + 0x3780, 0x377f, 0x377e, 0x377d, 0x377c, 0x377b, 0x377a, 0x3779, + 0x3778, 0x3777, 0x3776, 0x3775, 0x3775, 0x3774, 0x3773, 0x3772, + 0x3771, 0x3770, 0x376f, 0x376e, 0x376d, 0x376c, 0x376b, 0x376a, + 0x3769, 0x3768, 0x3768, 0x3767, 0x3766, 0x3765, 0x3764, 0x3763, + 0x3762, 0x3761, 0x3760, 0x375f, 0x375e, 0x375d, 0x375c, 0x375c, + 0x375b, 0x375a, 0x3759, 0x3758, 0x3757, 0x3756, 0x3755, 0x3754, + 0x3753, 0x3752, 0x3751, 0x3751, 0x3750, 0x374f, 0x374e, 0x374d, + 0x374c, 0x374b, 0x374a, 0x3749, 0x3748, 0x3747, 0x3747, 0x3746, + 0x3745, 0x3744, 0x3743, 0x3742, 0x3741, 0x3740, 0x373f, 0x373e, + 0x373d, 0x373d, 0x373c, 0x373b, 0x373a, 0x3739, 0x3738, 0x3737, + 0x3736, 0x3735, 0x3734, 0x3734, 0x3733, 0x3732, 0x3731, 0x3730, + 0x372f, 0x372e, 0x372d, 0x372c, 0x372b, 0x372b, 0x372a, 0x3729, + 0x3728, 0x3727, 0x3726, 0x3725, 0x3724, 0x3723, 0x3722, 0x3722, + 0x3721, 0x3720, 0x371f, 0x371e, 0x371d, 0x371c, 0x371b, 0x371a, + 0x371a, 0x3719, 0x3718, 0x3717, 0x3716, 0x3715, 0x3714, 0x3713, + 0x3713, 0x3712, 0x3711, 0x3710, 0x370f, 0x370e, 0x370d, 0x370c, + 0x370b, 0x370b, 0x370a, 0x3709, 0x3708, 0x3707, 0x3706, 0x3705, + 0x3704, 0x3704, 0x3703, 0x3702, 0x3701, 0x3700, 0x36ff, 0x36fe, + 0x36fd, 0x36fd, 0x36fc, 0x36fb, 0x36fa, 0x36f9, 0x36f8, 0x36f7, + 0x36f6, 0x36f6, 0x36f5, 0x36f4, 0x36f3, 0x36f2, 0x36f1, 0x36f0, + 0x36ef, 0x36ef, 0x36ee, 0x36ed, 0x36ec, 0x36eb, 0x36ea, 0x36e9, + 0x36e9, 0x36e8, 0x36e7, 0x36e6, 0x36e5, 0x36e4, 0x36e3, 0x36e3, + 0x36e2, 0x36e1, 0x36e0, 0x36df, 0x36de, 0x36dd, 0x36dd, 0x36dc, + 0x36db, 0x36da, 0x36d9, 0x36d8, 0x36d7, 0x36d7, 0x36d6, 0x36d5, + 0x36d4, 0x36d3, 0x36d2, 0x36d1, 0x36d1, 0x36d0, 0x36cf, 0x36ce, + 0x36cd, 0x36cc, 0x36cb, 0x36cb, 0x36ca, 0x36c9, 0x36c8, 0x36c7, + 0x36c6, 0x36c6, 0x36c5, 0x36c4, 0x36c3, 0x36c2, 0x36c1, 0x36c0, + 0x36c0, 0x36bf, 0x36be, 0x36bd, 0x36bc, 0x36bb, 0x36bb, 0x36ba, + 0x36b9, 0x36b8, 0x36b7, 0x36b6, 0x36b6, 0x36b5, 0x36b4, 0x36b3, + 0x36b2, 0x36b1, 0x36b0, 0x36b0, 0x36af, 0x36ae, 0x36ad, 0x36ac, + 0x36ab, 0x36ab, 0x36aa, 0x36a9, 0x36a8, 0x36a7, 0x36a6, 0x36a6, + 0x36a5, 0x36a4, 0x36a3, 0x36a2, 0x36a1, 0x36a1, 0x36a0, 0x369f, + 0x369e, 0x369d, 0x369d, 0x369c, 0x369b, 0x369a, 0x3699, 0x3698, + 0x3698, 0x3697, 0x3696, 0x3695, 0x3694, 0x3693, 0x3693, 0x3692, + 0x3691, 0x3690, 0x368f, 0x368f, 0x368e, 0x368d, 0x368c, 0x368b, + 0x368a, 0x368a, 0x3689, 0x3688, 0x3687, 0x3686, 0x3686, 0x3685, + 0x3684, 0x3683, 0x3682, 0x3681, 0x3681, 0x3680, 0x367f, 0x367e, + 0x367d, 0x367d, 0x367c, 0x367b, 0x367a, 0x3679, 0x3679, 0x3678, + 0x3677, 0x3676, 0x3675, 0x3675, 0x3674, 0x3673, 0x3672, 0x3671, + 0x3670, 0x3670, 0x366f, 0x366e, 0x366d, 0x366c, 0x366c, 0x366b, + 0x366a, 0x3669, 0x3668, 0x3668, 0x3667, 0x3666, 0x3665, 0x3664, + 0x3664, 0x3663, 0x3662, 0x3661, 0x3660, 0x3660, 0x365f, 0x365e, + 0x365d, 0x365c, 0x365c, 0x365b, 0x365a, 0x3659, 0x3659, 0x3658, + 0x3657, 0x3656, 0x3655, 0x3655, 0x3654, 0x3653, 0x3652, 0x3651, + 0x3651, 0x3650, 0x364f, 0x364e, 0x364d, 0x364d, 0x364c, 0x364b, + 0x364a, 0x364a, 0x3649, 0x3648, 0x3647, 0x3646, 0x3646, 0x3645, + 0x3644, 0x3643, 0x3642, 0x3642, 0x3641, 0x3640, 0x363f, 0x363f, + 0x363e, 0x363d, 0x363c, 0x363b, 0x363b, 0x363a, 0x3639, 0x3638, + 0x3638, 0x3637, 0x3636, 0x3635, 0x3634, 0x3634, 0x3633, 0x3632, + 0x3631, 0x3631, 0x3630, 0x362f, 0x362e, 0x362d, 0x362d, 0x362c, + 0x362b, 0x362a, 0x362a, 0x3629, 0x3628, 0x3627, 0x3627, 0x3626, + 0x3625, 0x3624, 0x3623, 0x3623, 0x3622, 0x3621, 0x3620, 0x3620, + 0x361f, 0x361e, 0x361d, 0x361d, 0x361c, 0x361b, 0x361a, 0x361a, + 0x3619, 0x3618, 0x3617, 0x3616, 0x3616, 0x3615, 0x3614, 0x3613, + 0x3613, 0x3612, 0x3611, 0x3610, 0x3610, 0x360f, 0x360e, 0x360d, + 0x360d, 0x360c, 0x360b, 0x360a, 0x360a, 0x3609, 0x3608, 0x3607, + 0x3607, 0x3606, 0x3605, 0x3604, 0x3604, 0x3603, 0x3602, 0x3601, + 0x3601, 0x3600, 0x35ff, 0x35fe, 0x35fe, 0x35fd, 0x35fc, 0x35fb, + 0x35fb, 0x35fa, 0x35f9, 0x35f8, 0x35f8, 0x35f7, 0x35f6, 0x35f5, + 0x35f5, 0x35f4, 0x35f3, 0x35f2, 0x35f2, 0x35f1, 0x35f0, 0x35ef, + 0x35ef, 0x35ee, 0x35ed, 0x35ec, 0x35ec, 0x35eb, 0x35ea, 0x35e9, + 0x35e9, 0x35e8, 0x35e7, 0x35e7, 0x35e6, 0x35e5, 0x35e4, 0x35e4, + 0x35e3, 0x35e1, 0x35e0, 0x35de, 0x35dd, 0x35db, 0x35da, 0x35d9, + 0x35d7, 0x35d6, 0x35d4, 0x35d3, 0x35d1, 0x35d0, 0x35ce, 0x35cd, + 0x35cb, 0x35ca, 0x35c9, 0x35c7, 0x35c6, 0x35c4, 0x35c3, 0x35c1, + 0x35c0, 0x35be, 0x35bd, 0x35bc, 0x35ba, 0x35b9, 0x35b7, 0x35b6, + 0x35b4, 0x35b3, 0x35b2, 0x35b0, 0x35af, 0x35ad, 0x35ac, 0x35ab, + 0x35a9, 0x35a8, 0x35a6, 0x35a5, 0x35a3, 0x35a2, 0x35a1, 0x359f, + 0x359e, 0x359c, 0x359b, 0x359a, 0x3598, 0x3597, 0x3595, 0x3594, + 0x3593, 0x3591, 0x3590, 0x358e, 0x358d, 0x358c, 0x358a, 0x3589, + 0x3588, 0x3586, 0x3585, 0x3583, 0x3582, 0x3581, 0x357f, 0x357e, + 0x357d, 0x357b, 0x357a, 0x3578, 0x3577, 0x3576, 0x3574, 0x3573, + 0x3572, 0x3570, 0x356f, 0x356e, 0x356c, 0x356b, 0x3569, 0x3568, + 0x3567, 0x3565, 0x3564, 0x3563, 0x3561, 0x3560, 0x355f, 0x355d, + 0x355c, 0x355b, 0x3559, 0x3558, 0x3557, 0x3555, 0x3554, 0x3553, + 0x3551, 0x3550, 0x354f, 0x354d, 0x354c, 0x354b, 0x3549, 0x3548, + 0x3547, 0x3545, 0x3544, 0x3543, 0x3541, 0x3540, 0x353f, 0x353e, + 0x353c, 0x353b, 0x353a, 0x3538, 0x3537, 0x3536, 0x3534, 0x3533, + 0x3532, 0x3530, 0x352f, 0x352e, 0x352d, 0x352b, 0x352a, 0x3529, + 0x3527, 0x3526, 0x3525, 0x3524, 0x3522, 0x3521, 0x3520, 0x351e, + 0x351d, 0x351c, 0x351b, 0x3519, 0x3518, 0x3517, 0x3516, 0x3514, + 0x3513, 0x3512, 0x3510, 0x350f, 0x350e, 0x350d, 0x350b, 0x350a, + 0x3509, 0x3508, 0x3506, 0x3505, 0x3504, 0x3503, 0x3501, 0x3500, + 0x34ff, 0x34fe, 0x34fc, 0x34fb, 0x34fa, 0x34f9, 0x34f7, 0x34f6, + 0x34f5, 0x34f4, 0x34f2, 0x34f1, 0x34f0, 0x34ef, 0x34ed, 0x34ec, + 0x34eb, 0x34ea, 0x34e9, 0x34e7, 0x34e6, 0x34e5, 0x34e4, 0x34e2, + 0x34e1, 0x34e0, 0x34df, 0x34de, 0x34dc, 0x34db, 0x34da, 0x34d9, + 0x34d7, 0x34d6, 0x34d5, 0x34d4, 0x34d3, 0x34d1, 0x34d0, 0x34cf, + 0x34ce, 0x34cd, 0x34cb, 0x34ca, 0x34c9, 0x34c8, 0x34c7, 0x34c5, + 0x34c4, 0x34c3, 0x34c2, 0x34c1, 0x34c0, 0x34be, 0x34bd, 0x34bc, + 0x34bb, 0x34ba, 0x34b8, 0x34b7, 0x34b6, 0x34b5, 0x34b4, 0x34b3, + 0x34b1, 0x34b0, 0x34af, 0x34ae, 0x34ad, 0x34ac, 0x34aa, 0x34a9, + 0x34a8, 0x34a7, 0x34a6, 0x34a5, 0x34a3, 0x34a2, 0x34a1, 0x34a0, + 0x349f, 0x349e, 0x349c, 0x349b, 0x349a, 0x3499, 0x3498, 0x3497, + 0x3496, 0x3494, 0x3493, 0x3492, 0x3491, 0x3490, 0x348f, 0x348e, + 0x348c, 0x348b, 0x348a, 0x3489, 0x3488, 0x3487, 0x3486, 0x3484, + 0x3483, 0x3482, 0x3481, 0x3480, 0x347f, 0x347e, 0x347d, 0x347b, + 0x347a, 0x3479, 0x3478, 0x3477, 0x3476, 0x3475, 0x3474, 0x3473, + 0x3471, 0x3470, 0x346f, 0x346e, 0x346d, 0x346c, 0x346b, 0x346a, + 0x3469, 0x3467, 0x3466, 0x3465, 0x3464, 0x3463, 0x3462, 0x3461, + 0x3460, 0x345f, 0x345e, 0x345d, 0x345b, 0x345a, 0x3459, 0x3458, + 0x3457, 0x3456, 0x3455, 0x3454, 0x3453, 0x3452, 0x3451, 0x3450, + 0x344e, 0x344d, 0x344c, 0x344b, 0x344a, 0x3449, 0x3448, 0x3447, + 0x3446, 0x3445, 0x3444, 0x3443, 0x3442, 0x3441, 0x343f, 0x343e, + 0x343d, 0x343c, 0x343b, 0x343a, 0x3439, 0x3438, 0x3437, 0x3436, + 0x3435, 0x3434, 0x3433, 0x3432, 0x3431, 0x3430, 0x342f, 0x342e, + 0x342d, 0x342b, 0x342a, 0x3429, 0x3428, 0x3427, 0x3426, 0x3425, + 0x3424, 0x3423, 0x3422, 0x3421, 0x3420, 0x341f, 0x341e, 0x341d, + 0x341c, 0x341b, 0x341a, 0x3419, 0x3418, 0x3417, 0x3416, 0x3415, + 0x3414, 0x3413, 0x3412, 0x3411, 0x3410, 0x340f, 0x340e, 0x340d, + 0x340c, 0x340b, 0x340a, 0x3409, 0x3408, 0x3407, 0x3406, 0x3405, + 0x3404, 0x3403, 0x3402, 0x3401, 0x33ff, 0x33fd, 0x33fb, 0x33f9, + 0x33f7, 0x33f5, 0x33f3, 0x33f1, 0x33ef, 0x33ed, 0x33eb, 0x33e9, + 0x33e7, 0x33e5, 0x33e3, 0x33e1, 0x33df, 0x33dd, 0x33db, 0x33d9, + 0x33d8, 0x33d6, 0x33d4, 0x33d2, 0x33d0, 0x33ce, 0x33cc, 0x33ca, + 0x33c8, 0x33c6, 0x33c4, 0x33c2, 0x33c0, 0x33be, 0x33bc, 0x33ba, + 0x33b8, 0x33b6, 0x33b5, 0x33b3, 0x33b1, 0x33af, 0x33ad, 0x33ab, + 0x33a9, 0x33a7, 0x33a5, 0x33a3, 0x33a1, 0x339f, 0x339e, 0x339c, + 0x339a, 0x3398, 0x3396, 0x3394, 0x3392, 0x3390, 0x338e, 0x338d, + 0x338b, 0x3389, 0x3387, 0x3385, 0x3383, 0x3381, 0x337f, 0x337d, + 0x337c, 0x337a, 0x3378, 0x3376, 0x3374, 0x3372, 0x3370, 0x336f, + 0x336d, 0x336b, 0x3369, 0x3367, 0x3365, 0x3363, 0x3362, 0x3360, + 0x335e, 0x335c, 0x335a, 0x3358, 0x3357, 0x3355, 0x3353, 0x3351, + 0x334f, 0x334d, 0x334c, 0x334a, 0x3348, 0x3346, 0x3344, 0x3342, + 0x3341, 0x333f, 0x333d, 0x333b, 0x3339, 0x3338, 0x3336, 0x3334, + 0x3332, 0x3330, 0x332f, 0x332d, 0x332b, 0x3329, 0x3327, 0x3326, + 0x3324, 0x3322, 0x3320, 0x331f, 0x331d, 0x331b, 0x3319, 0x3317, + 0x3316, 0x3314, 0x3312, 0x3310, 0x330f, 0x330d, 0x330b, 0x3309, + 0x3308, 0x3306, 0x3304, 0x3302, 0x3301, 0x32ff, 0x32fd, 0x32fb, + 0x32fa, 0x32f8, 0x32f6, 0x32f4, 0x32f3, 0x32f1, 0x32ef, 0x32ed, + 0x32ec, 0x32ea, 0x32e8, 0x32e6, 0x32e5, 0x32e3, 0x32e1, 0x32e0, + 0x32de, 0x32dc, 0x32da, 0x32d9, 0x32d7, 0x32d5, 0x32d4, 0x32d2, + 0x32d0, 0x32ce, 0x32cd, 0x32cb, 0x32c9, 0x32c8, 0x32c6, 0x32c4, + 0x32c3, 0x32c1, 0x32bf, 0x32be, 0x32bc, 0x32ba, 0x32b8, 0x32b7, + 0x32b5, 0x32b3, 0x32b2, 0x32b0, 0x32ae, 0x32ad, 0x32ab, 0x32a9, + 0x32a8, 0x32a6, 0x32a4, 0x32a3, 0x32a1, 0x329f, 0x329e, 0x329c, + 0x329b, 0x3299, 0x3297, 0x3296, 0x3294, 0x3292, 0x3291, 0x328f, + 0x328d, 0x328c, 0x328a, 0x3288, 0x3287, 0x3285, 0x3284, 0x3282, + 0x3280, 0x327f, 0x327d, 0x327b, 0x327a, 0x3278, 0x3277, 0x3275, + 0x3273, 0x3272, 0x3270, 0x326f, 0x326d, 0x326b, 0x326a, 0x3268, + 0x3267, 0x3265, 0x3263, 0x3262, 0x3260, 0x325f, 0x325d, 0x325b, + 0x325a, 0x3258, 0x3257, 0x3255, 0x3253, 0x3252, 0x3250, 0x324f, + 0x324d, 0x324c, 0x324a, 0x3248, 0x3247, 0x3245, 0x3244, 0x3242, + 0x3241, 0x323f, 0x323d, 0x323c, 0x323a, 0x3239, 0x3237, 0x3236, + 0x3234, 0x3233, 0x3231, 0x322f, 0x322e, 0x322c, 0x322b, 0x3229, + 0x3228, 0x3226, 0x3225, 0x3223, 0x3222, 0x3220, 0x321f, 0x321d, + 0x321b, 0x321a, 0x3218, 0x3217, 0x3215, 0x3214, 0x3212, 0x3211, + 0x320f, 0x320e, 0x320c, 0x320b, 0x3209, 0x3208, 0x3206, 0x3205, + 0x3203, 0x3202, 0x3200, 0x31ff, 0x31fd, 0x31fc, 0x31fa, 0x31f9, + 0x31f7, 0x31f6, 0x31f4, 0x31f3, 0x31f1, 0x31f0, 0x31ee, 0x31ed, + 0x31eb, 0x31ea, 0x31e8, 0x31e7, 0x31e5, 0x31e4, 0x31e3, 0x31e1, + 0x31e0, 0x31de, 0x31dd, 0x31db, 0x31da, 0x31d8, 0x31d7, 0x31d5, + 0x31d4, 0x31d2, 0x31d1, 0x31d0, 0x31ce, 0x31cd, 0x31cb, 0x31ca, + 0x31c8, 0x31c7, 0x31c5, 0x31c4, 0x31c2, 0x31c1, 0x31c0, 0x31be, + 0x31bd, 0x31bb, 0x31ba, 0x31b8, 0x31b7, 0x31b6, 0x31b4, 0x31b3, + 0x31b1, 0x31b0, 0x31ae, 0x31ad, 0x31ac, 0x31aa, 0x31a9, 0x31a7, + 0x31a6, 0x31a5, 0x31a3, 0x31a2, 0x31a0, 0x319f, 0x319e, 0x319c, + 0x319b, 0x3199, 0x3198, 0x3197, 0x3195, 0x3194, 0x3192, 0x3191, + 0x3190, 0x318e, 0x318d, 0x318b, 0x318a, 0x3189, 0x3187, 0x3186, + 0x3184, 0x3183, 0x3182, 0x3180, 0x317f, 0x317e, 0x317c, 0x317b, + 0x3179, 0x3178, 0x3177, 0x3175, 0x3174, 0x3173, 0x3171, 0x3170, + 0x316f, 0x316d, 0x316c, 0x316b, 0x3169, 0x3168, 0x3166, 0x3165, + 0x3164, 0x3162, 0x3161, 0x3160, 0x315e, 0x315d, 0x315c, 0x315a, + 0x3159, 0x3158, 0x3156, 0x3155, 0x3154, 0x3152, 0x3151, 0x3150, + 0x314e, 0x314d, 0x314c, 0x314a, 0x3149, 0x3148, 0x3146, 0x3145, + 0x3144, 0x3142, 0x3141, 0x3140, 0x313f, 0x313d, 0x313c, 0x313b, + 0x3139, 0x3138, 0x3137, 0x3135, 0x3134, 0x3133, 0x3131, 0x3130, + 0x312f, 0x312e, 0x312c, 0x312b, 0x312a, 0x3128, 0x3127, 0x3126, + 0x3125, 0x3123, 0x3122, 0x3121, 0x311f, 0x311e, 0x311d, 0x311c, + 0x311a, 0x3119, 0x3118, 0x3117, 0x3115, 0x3114, 0x3113, 0x3111, + 0x3110, 0x310f, 0x310e, 0x310c, 0x310b, 0x310a, 0x3109, 0x3107, + 0x3106, 0x3105, 0x3104, 0x3102, 0x3101, 0x3100, 0x30ff, 0x30fd, + 0x30fc, 0x30fb, 0x30fa, 0x30f8, 0x30f7, 0x30f6, 0x30f5, 0x30f3, + 0x30f2, 0x30f1, 0x30f0, 0x30ee, 0x30ed, 0x30ec, 0x30eb, 0x30ea, + 0x30e8, 0x30e7, 0x30e6, 0x30e5, 0x30e3, 0x30e2, 0x30e1, 0x30e0, + 0x30df, 0x30dd, 0x30dc, 0x30db, 0x30da, 0x30d8, 0x30d7, 0x30d6, + 0x30d5, 0x30d4, 0x30d2, 0x30d1, 0x30d0, 0x30cf, 0x30ce, 0x30cc, + 0x30cb, 0x30ca, 0x30c9, 0x30c8, 0x30c6, 0x30c5, 0x30c4, 0x30c3, + 0x30c2, 0x30c0, 0x30bf, 0x30be, 0x30bd, 0x30bc, 0x30bb, 0x30b9, + 0x30b8, 0x30b7, 0x30b6, 0x30b5, 0x30b3, 0x30b2, 0x30b1, 0x30b0, + 0x30af, 0x30ae, 0x30ac, 0x30ab, 0x30aa, 0x30a9, 0x30a8, 0x30a7, + 0x30a5, 0x30a4, 0x30a3, 0x30a2, 0x30a1, 0x30a0, 0x309e, 0x309d, + 0x309c, 0x309b, 0x309a, 0x3099, 0x3098, 0x3096, 0x3095, 0x3094, + 0x3093, 0x3092, 0x3091, 0x3090, 0x308e, 0x308d, 0x308c, 0x308b, + 0x308a, 0x3089, 0x3088, 0x3086, 0x3085, 0x3084, 0x3083, 0x3082, + 0x3081, 0x3080, 0x307f, 0x307d, 0x307c, 0x307b, 0x307a, 0x3079, + 0x3078, 0x3077, 0x3076, 0x3075, 0x3073, 0x3072, 0x3071, 0x3070, + 0x306f, 0x306e, 0x306d, 0x306c, 0x306b, 0x3069, 0x3068, 0x3067, + 0x3066, 0x3065, 0x3064, 0x3063, 0x3062, 0x3061, 0x3060, 0x305e, + 0x305d, 0x305c, 0x305b, 0x305a, 0x3059, 0x3058, 0x3057, 0x3056, + 0x3055, 0x3053, 0x3050, 0x304e, 0x304c, 0x304a, 0x3048, 0x3046, + 0x3043, 0x3041, 0x303f, 0x303d, 0x303b, 0x3039, 0x3037, 0x3035, + 0x3033, 0x3030, 0x302e, 0x302c, 0x302a, 0x3028, 0x3026, 0x3024, + 0x3022, 0x3020, 0x301e, 0x301c, 0x301a, 0x3018, 0x3016, 0x3014, + 0x3011, 0x300f, 0x300d, 0x300b, 0x3009, 0x3007, 0x3005, 0x3003, + 0x3001, 0x2fff, 0x2ffb, 0x2ff7, 0x2ff3, 0x2fef, 0x2feb, 0x2fe7, + 0x2fe3, 0x2fdf, 0x2fdb, 0x2fd7, 0x2fd3, 0x2fcf, 0x2fcb, 0x2fc7, + 0x2fc4, 0x2fc0, 0x2fbc, 0x2fb8, 0x2fb4, 0x2fb0, 0x2fac, 0x2fa9, + 0x2fa5, 0x2fa1, 0x2f9d, 0x2f99, 0x2f96, 0x2f92, 0x2f8e, 0x2f8a, + 0x2f86, 0x2f83, 0x2f7f, 0x2f7b, 0x2f77, 0x2f74, 0x2f70, 0x2f6c, + 0x2f69, 0x2f65, 0x2f61, 0x2f5e, 0x2f5a, 0x2f56, 0x2f52, 0x2f4f, + 0x2f4b, 0x2f48, 0x2f44, 0x2f40, 0x2f3d, 0x2f39, 0x2f35, 0x2f32, + 0x2f2e, 0x2f2b, 0x2f27, 0x2f23, 0x2f20, 0x2f1c, 0x2f19, 0x2f15, + 0x2f12, 0x2f0e, 0x2f0b, 0x2f07, 0x2f04, 0x2f00, 0x2efd, 0x2ef9, + 0x2ef6, 0x2ef2, 0x2eef, 0x2eeb, 0x2ee8, 0x2ee4, 0x2ee1, 0x2edd, + 0x2eda, 0x2ed7, 0x2ed3, 0x2ed0, 0x2ecc, 0x2ec9, 0x2ec6, 0x2ec2, + 0x2ebf, 0x2ebb, 0x2eb8, 0x2eb5, 0x2eb1, 0x2eae, 0x2eab, 0x2ea7, + 0x2ea4, 0x2ea1, 0x2e9d, 0x2e9a, 0x2e97, 0x2e94, 0x2e90, 0x2e8d, + 0x2e8a, 0x2e86, 0x2e83, 0x2e80, 0x2e7d, 0x2e79, 0x2e76, 0x2e73, + 0x2e70, 0x2e6d, 0x2e69, 0x2e66, 0x2e63, 0x2e60, 0x2e5d, 0x2e59, + 0x2e56, 0x2e53, 0x2e50, 0x2e4d, 0x2e4a, 0x2e46, 0x2e43, 0x2e40, + 0x2e3d, 0x2e3a, 0x2e37, 0x2e34, 0x2e31, 0x2e2e, 0x2e2a, 0x2e27, + 0x2e24, 0x2e21, 0x2e1e, 0x2e1b, 0x2e18, 0x2e15, 0x2e12, 0x2e0f, + 0x2e0c, 0x2e09, 0x2e06, 0x2e03, 0x2e00, 0x2dfd, 0x2dfa, 0x2df7, + 0x2df4, 0x2df1, 0x2dee, 0x2deb, 0x2de8, 0x2de5, 0x2de2, 0x2ddf, + 0x2ddc, 0x2dd9, 0x2dd6, 0x2dd4, 0x2dd1, 0x2dce, 0x2dcb, 0x2dc8, + 0x2dc5, 0x2dc2, 0x2dbf, 0x2dbc, 0x2dba, 0x2db7, 0x2db4, 0x2db1, + 0x2dae, 0x2dab, 0x2da8, 0x2da6, 0x2da3, 0x2da0, 0x2d9d, 0x2d9a, + 0x2d98, 0x2d95, 0x2d92, 0x2d8f, 0x2d8c, 0x2d8a, 0x2d87, 0x2d84, + 0x2d81, 0x2d7f, 0x2d7c, 0x2d79, 0x2d76, 0x2d74, 0x2d71, 0x2d6e, + 0x2d6c, 0x2d69, 0x2d66, 0x2d63, 0x2d61, 0x2d5e, 0x2d5b, 0x2d59, + 0x2d56, 0x2d53, 0x2d51, 0x2d4e, 0x2d4b, 0x2d49, 0x2d46, 0x2d44, + 0x2d41, 0x2d3e, 0x2d3c, 0x2d39, 0x2d36, 0x2d34, 0x2d31, 0x2d2f, + 0x2d2c, 0x2d29, 0x2d27, 0x2d24, 0x2d22, 0x2d1f, 0x2d1d, 0x2d1a, + 0x2d18, 0x2d15, 0x2d12, 0x2d10, 0x2d0d, 0x2d0b, 0x2d08, 0x2d06, + 0x2d03, 0x2d01, 0x2cfe, 0x2cfc, 0x2cf9, 0x2cf7, 0x2cf4, 0x2cf2, + 0x2cef, 0x2ced, 0x2cea, 0x2ce8, 0x2ce6, 0x2ce3, 0x2ce1, 0x2cde, + 0x2cdc, 0x2cd9, 0x2cd7, 0x2cd5, 0x2cd2, 0x2cd0, 0x2ccd, 0x2ccb, + 0x2cc9, 0x2cc6, 0x2cc4, 0x2cc1, 0x2cbf, 0x2cbd, 0x2cba, 0x2cb8, + 0x2cb6, 0x2cb3, 0x2cb1, 0x2caf, 0x2cac, 0x2caa, 0x2ca7, 0x2ca5, + 0x2ca3, 0x2ca1, 0x2c9e, 0x2c9c, 0x2c9a, 0x2c97, 0x2c95, 0x2c93, + 0x2c90, 0x2c8e, 0x2c8c, 0x2c8a, 0x2c87, 0x2c85, 0x2c83, 0x2c81, + 0x2c7e, 0x2c7c, 0x2c7a, 0x2c78, 0x2c75, 0x2c73, 0x2c71, 0x2c6f, + 0x2c6d, 0x2c6a, 0x2c68, 0x2c66, 0x2c64, 0x2c61, 0x2c5f, 0x2c5d, + 0x2c5b, 0x2c59, 0x2c57, 0x2c54, 0x2c52, 0x2c50, 0x2c4e, 0x2c4c, + 0x2c4a, 0x2c48, 0x2c45, 0x2c43, 0x2c41, 0x2c3f, 0x2c3d, 0x2c3b, + 0x2c39, 0x2c37, 0x2c34, 0x2c32, 0x2c30, 0x2c2e, 0x2c2c, 0x2c2a, + 0x2c28, 0x2c26, 0x2c24, 0x2c22, 0x2c20, 0x2c1e, 0x2c1b, 0x2c19, + 0x2c17, 0x2c15, 0x2c13, 0x2c11, 0x2c0f, 0x2c0d, 0x2c0b, 0x2c09, + 0x2c07, 0x2c05, 0x2c03, 0x2c01, 0x2bfe, 0x2bfa, 0x2bf6, 0x2bf2, + 0x2bee, 0x2bea, 0x2be6, 0x2be2, 0x2bdf, 0x2bdb, 0x2bd7, 0x2bd3, + 0x2bcf, 0x2bcb, 0x2bc7, 0x2bc3, 0x2bbf, 0x2bbb, 0x2bb8, 0x2bb4, + 0x2bb0, 0x2bac, 0x2ba8, 0x2ba4, 0x2ba1, 0x2b9d, 0x2b99, 0x2b95, + 0x2b91, 0x2b8e, 0x2b8a, 0x2b86, 0x2b82, 0x2b7f, 0x2b7b, 0x2b77, + 0x2b73, 0x2b70, 0x2b6c, 0x2b68, 0x2b64, 0x2b61, 0x2b5d, 0x2b59, + 0x2b56, 0x2b52, 0x2b4e, 0x2b4b, 0x2b47, 0x2b44, 0x2b40, 0x2b3c, + 0x2b39, 0x2b35, 0x2b31, 0x2b2e, 0x2b2a, 0x2b27, 0x2b23, 0x2b20, + 0x2b1c, 0x2b18, 0x2b15, 0x2b11, 0x2b0e, 0x2b0a, 0x2b07, 0x2b03, + 0x2b00, 0x2afc, 0x2af9, 0x2af5, 0x2af2, 0x2aee, 0x2aeb, 0x2ae7, + 0x2ae4, 0x2ae1, 0x2add, 0x2ada, 0x2ad6, 0x2ad3, 0x2acf, 0x2acc, + 0x2ac9, 0x2ac5, 0x2ac2, 0x2abe, 0x2abb, 0x2ab8, 0x2ab4, 0x2ab1, + 0x2aae, 0x2aaa, 0x2aa7, 0x2aa4, 0x2aa0, 0x2a9d, 0x2a9a, 0x2a97, + 0x2a93, 0x2a90, 0x2a8d, 0x2a89, 0x2a86, 0x2a83, 0x2a80, 0x2a7c, + 0x2a79, 0x2a76, 0x2a73, 0x2a6f, 0x2a6c, 0x2a69, 0x2a66, 0x2a63, + 0x2a5f, 0x2a5c, 0x2a59, 0x2a56, 0x2a53, 0x2a50, 0x2a4c, 0x2a49, + 0x2a46, 0x2a43, 0x2a40, 0x2a3d, 0x2a3a, 0x2a37, 0x2a33, 0x2a30, + 0x2a2d, 0x2a2a, 0x2a27, 0x2a24, 0x2a21, 0x2a1e, 0x2a1b, 0x2a18, + 0x2a15, 0x2a12, 0x2a0f, 0x2a0c, 0x2a09, 0x2a06, 0x2a03, 0x2a00, + 0x29fd, 0x29fa, 0x29f7, 0x29f4, 0x29f1, 0x29ee, 0x29eb, 0x29e8, + 0x29e5, 0x29e2, 0x29df, 0x29dc, 0x29d9, 0x29d6, 0x29d3, 0x29d0, + 0x29cd, 0x29cb, 0x29c8, 0x29c5, 0x29c2, 0x29bf, 0x29bc, 0x29b9, + 0x29b6, 0x29b4, 0x29b1, 0x29ae, 0x29ab, 0x29a8, 0x29a5, 0x29a3, + 0x29a0, 0x299d, 0x299a, 0x2997, 0x2995, 0x2992, 0x298f, 0x298c, + 0x2989, 0x2987, 0x2984, 0x2981, 0x297e, 0x297c, 0x2979, 0x2976, + 0x2973, 0x2971, 0x296e, 0x296b, 0x2969, 0x2966, 0x2963, 0x2960, + 0x295e, 0x295b, 0x2958, 0x2956, 0x2953, 0x2950, 0x294e, 0x294b, + 0x2948, 0x2946, 0x2943, 0x2941, 0x293e, 0x293b, 0x2939, 0x2936, + 0x2934, 0x2931, 0x292e, 0x292c, 0x2929, 0x2927, 0x2924, 0x2921, + 0x291f, 0x291c, 0x291a, 0x2917, 0x2915, 0x2912, 0x2910, 0x290d, + 0x290b, 0x2908, 0x2906, 0x2903, 0x2901, 0x28fe, 0x28fc, 0x28f9, + 0x28f7, 0x28f4, 0x28f2, 0x28ef, 0x28ed, 0x28ea, 0x28e8, 0x28e5, + 0x28e3, 0x28e0, 0x28de, 0x28dc, 0x28d9, 0x28d7, 0x28d4, 0x28d2, + 0x28cf, 0x28cd, 0x28cb, 0x28c8, 0x28c6, 0x28c3, 0x28c1, 0x28bf, + 0x28bc, 0x28ba, 0x28b8, 0x28b5, 0x28b3, 0x28b1, 0x28ae, 0x28ac, + 0x28aa, 0x28a7, 0x28a5, 0x28a3, 0x28a0, 0x289e, 0x289c, 0x2899, + 0x2897, 0x2895, 0x2892, 0x2890, 0x288e, 0x288c, 0x2889, 0x2887, + 0x2885, 0x2883, 0x2880, 0x287e, 0x287c, 0x287a, 0x2877, 0x2875, + 0x2873, 0x2871, 0x286e, 0x286c, 0x286a, 0x2868, 0x2866, 0x2863, + 0x2861, 0x285f, 0x285d, 0x285b, 0x2859, 0x2856, 0x2854, 0x2852, + 0x2850, 0x284e, 0x284c, 0x2849, 0x2847, 0x2845, 0x2843, 0x2841, + 0x283f, 0x283d, 0x283b, 0x2838, 0x2836, 0x2834, 0x2832, 0x2830, + 0x282e, 0x282c, 0x282a, 0x2828, 0x2826, 0x2824, 0x2821, 0x281f, + 0x281d, 0x281b, 0x2819, 0x2817, 0x2815, 0x2813, 0x2811, 0x280f, + 0x280d, 0x280b, 0x2809, 0x2807, 0x2805, 0x2803, 0x2801, 0x27fe, + 0x27fa, 0x27f6, 0x27f2, 0x27ee, 0x27ea, 0x27e6, 0x27e2, 0x27de, + 0x27da, 0x27d6, 0x27d2, 0x27ce, 0x27cb, 0x27c7, 0x27c3, 0x27bf, + 0x27bb, 0x27b7, 0x27b3, 0x27af, 0x27ac, 0x27a8, 0x27a4, 0x27a0, + 0x279c, 0x2799, 0x2795, 0x2791, 0x278d, 0x2789, 0x2786, 0x2782, + 0x277e, 0x277a, 0x2777, 0x2773, 0x276f, 0x276b, 0x2768, 0x2764, + 0x2760, 0x275d, 0x2759, 0x2755, 0x2752, 0x274e, 0x274a, 0x2747, + 0x2743, 0x273f, 0x273c, 0x2738, 0x2735, 0x2731, 0x272d, 0x272a, + 0x2726, 0x2723, 0x271f, 0x271c, 0x2718, 0x2715, 0x2711, 0x270d, + 0x270a, 0x2706, 0x2703, 0x26ff, 0x26fc, 0x26f8, 0x26f5, 0x26f1, + 0x26ee, 0x26eb, 0x26e7, 0x26e4, 0x26e0, 0x26dd, 0x26d9, 0x26d6, + 0x26d2, 0x26cf, 0x26cc, 0x26c8, 0x26c5, 0x26c2, 0x26be, 0x26bb, + 0x26b7, 0x26b4, 0x26b1, 0x26ad, 0x26aa, 0x26a7, 0x26a3, 0x26a0, + 0x269d, 0x2699, 0x2696, 0x2693, 0x2690, 0x268c, 0x2689, 0x2686, + 0x2682, 0x267f, 0x267c, 0x2679, 0x2676, 0x2672, 0x266f, 0x266c, + 0x2669, 0x2665, 0x2662, 0x265f, 0x265c, 0x2659, 0x2656, 0x2652, + 0x264f, 0x264c, 0x2649, 0x2646, 0x2643, 0x2640, 0x263c, 0x2639, + 0x2636, 0x2633, 0x2630, 0x262d, 0x262a, 0x2627, 0x2624, 0x2621, + 0x261e, 0x261a, 0x2617, 0x2614, 0x2611, 0x260e, 0x260b, 0x2608, + 0x2605, 0x2602, 0x25ff, 0x25fc, 0x25f9, 0x25f6, 0x25f3, 0x25f0, + 0x25ed, 0x25ea, 0x25e7, 0x25e4, 0x25e2, 0x25df, 0x25dc, 0x25d9, + 0x25d6, 0x25d3, 0x25d0, 0x25cd, 0x25ca, 0x25c7, 0x25c4, 0x25c2, + 0x25bf, 0x25bc, 0x25b9, 0x25b6, 0x25b3, 0x25b0, 0x25ae, 0x25ab, + 0x25a8, 0x25a5, 0x25a2, 0x259f, 0x259d, 0x259a, 0x2597, 0x2594, + 0x2591, 0x258f, 0x258c, 0x2589, 0x2586, 0x2584, 0x2581, 0x257e, + 0x257b, 0x2579, 0x2576, 0x2573, 0x2570, 0x256e, 0x256b, 0x2568, + 0x2566, 0x2563, 0x2560, 0x255e, 0x255b, 0x2558, 0x2555, 0x2553, + 0x2550, 0x254e, 0x254b, 0x2548, 0x2546, 0x2543, 0x2540, 0x253e, + 0x253b, 0x2538, 0x2536, 0x2533, 0x2531, 0x252e, 0x252b, 0x2529, + 0x2526, 0x2524, 0x2521, 0x251f, 0x251c, 0x2519, 0x2517, 0x2514, + 0x2512, 0x250f, 0x250d, 0x250a, 0x2508, 0x2505, 0x2503, 0x2500, + 0x24fe, 0x24fb, 0x24f9, 0x24f6, 0x24f4, 0x24f1, 0x24ef, 0x24ec, + 0x24ea, 0x24e7, 0x24e5, 0x24e3, 0x24e0, 0x24de, 0x24db, 0x24d9, + 0x24d6, 0x24d4, 0x24d2, 0x24cf, 0x24cd, 0x24ca, 0x24c8, 0x24c6, + 0x24c3, 0x24c1, 0x24be, 0x24bc, 0x24ba, 0x24b7, 0x24b5, 0x24b3, + 0x24b0, 0x24ac, 0x24a7, 0x24a2, 0x249e, 0x2499, 0x2495, 0x2490, + 0x248b, 0x2487, 0x2482, 0x247e, 0x2479, 0x2475, 0x2470, 0x246c, + 0x2468, 0x2463, 0x245f, 0x245a, 0x2456, 0x2452, 0x244d, 0x2449, + 0x2445, 0x2441, 0x243c, 0x2438, 0x2434, 0x2430, 0x242c, 0x2427, + 0x2423, 0x241f, 0x241b, 0x2417, 0x2413, 0x240f, 0x240b, 0x2407, + 0x2403, 0x23fd, 0x23f5, 0x23ed, 0x23e6, 0x23de, 0x23d6, 0x23ce, + 0x23c6, 0x23be, 0x23b7, 0x23af, 0x23a7, 0x23a0, 0x2398, 0x2391, + 0x2389, 0x2381, 0x237a, 0x2373, 0x236b, 0x2364, 0x235c, 0x2355, + 0x234e, 0x2346, 0x233f, 0x2338, 0x2331, 0x2329, 0x2322, 0x231b, + 0x2314, 0x230d, 0x2306, 0x22ff, 0x22f8, 0x22f1, 0x22ea, 0x22e3, + 0x22dc, 0x22d6, 0x22cf, 0x22c8, 0x22c1, 0x22ba, 0x22b4, 0x22ad, + 0x22a6, 0x22a0, 0x2299, 0x2292, 0x228c, 0x2285, 0x227f, 0x2278, + 0x2272, 0x226c, 0x2265, 0x225f, 0x2258, 0x2252, 0x224c, 0x2245, + 0x223f, 0x2239, 0x2233, 0x222d, 0x2226, 0x2220, 0x221a, 0x2214, + 0x220e, 0x2208, 0x2202, 0x21fc, 0x21f6, 0x21f0, 0x21ea, 0x21e4, + 0x21de, 0x21d8, 0x21d3, 0x21cd, 0x21c7, 0x21c1, 0x21bb, 0x21b6, + 0x21b0, 0x21aa, 0x21a5, 0x219f, 0x219a, 0x2194, 0x218e, 0x2189, + 0x2183, 0x217e, 0x2178, 0x2173, 0x216d, 0x2168, 0x2163, 0x215d, + 0x2158, 0x2153, 0x214d, 0x2148, 0x2143, 0x213d, 0x2138, 0x2133, + 0x212e, 0x2129, 0x2123, 0x211e, 0x2119, 0x2114, 0x210f, 0x210a, + 0x2105, 0x2100, 0x20fb, 0x20f6, 0x20f1, 0x20ec, 0x20e7, 0x20e2, + 0x20dd, 0x20d9, 0x20d4, 0x20cf, 0x20ca, 0x20c5, 0x20c1, 0x20bc, + 0x20b7, 0x20b2, 0x20ae, 0x20a9, 0x20a4, 0x20a0, 0x209b, 0x2097, + 0x2092, 0x208d, 0x2089, 0x2084, 0x2080, 0x207b, 0x2077, 0x2072, + 0x206e, 0x206a, 0x2065, 0x2061, 0x205c, 0x2058, 0x2054, 0x204f, + 0x204b, 0x2047, 0x2043, 0x203e, 0x203a, 0x2036, 0x2032, 0x202d, + 0x2029, 0x2025, 0x2021, 0x201d, 0x2019, 0x2015, 0x2011, 0x200d, + 0x2009, 0x2004, 0x2000, 0x1ff9, 0x1ff1, 0x1fe9, 0x1fe1, 0x1fd9, + 0x1fd1, 0x1fca, 0x1fc2, 0x1fba, 0x1fb2, 0x1fab, 0x1fa3, 0x1f9c, + 0x1f94, 0x1f8c, 0x1f85, 0x1f7d, 0x1f76, 0x1f6e, 0x1f67, 0x1f60, + 0x1f58, 0x1f51, 0x1f4a, 0x1f42, 0x1f3b, 0x1f34, 0x1f2d, 0x1f26, + 0x1f1e, 0x1f17, 0x1f10, 0x1f09, 0x1f02, 0x1efb, 0x1ef4, 0x1eed, + 0x1ee6, 0x1edf, 0x1ed9, 0x1ed2, 0x1ecb, 0x1ec4, 0x1ebd, 0x1eb7, + 0x1eb0, 0x1ea9, 0x1ea3, 0x1e9c, 0x1e95, 0x1e8f, 0x1e88, 0x1e82, + 0x1e7b, 0x1e75, 0x1e6e, 0x1e68, 0x1e62, 0x1e5b, 0x1e55, 0x1e4f, + 0x1e48, 0x1e42, 0x1e3c, 0x1e36, 0x1e2f, 0x1e29, 0x1e23, 0x1e1d, + 0x1e17, 0x1e11, 0x1e0b, 0x1e05, 0x1dff, 0x1df9, 0x1df3, 0x1ded, + 0x1de7, 0x1de1, 0x1ddb, 0x1dd5, 0x1dcf, 0x1dca, 0x1dc4, 0x1dbe, + 0x1db8, 0x1db3, 0x1dad, 0x1da7, 0x1da2, 0x1d9c, 0x1d96, 0x1d91, + 0x1d8b, 0x1d86, 0x1d80, 0x1d7b, 0x1d75, 0x1d70, 0x1d6a, 0x1d65, + 0x1d60, 0x1d5a, 0x1d55, 0x1d50, 0x1d4a, 0x1d45, 0x1d40, 0x1d3b, + 0x1d35, 0x1d30, 0x1d2b, 0x1d26, 0x1d21, 0x1d1b, 0x1d16, 0x1d11, + 0x1d0c, 0x1d07, 0x1d02, 0x1cfd, 0x1cf8, 0x1cf3, 0x1cee, 0x1ce9, + 0x1ce5, 0x1ce0, 0x1cdb, 0x1cd6, 0x1cd1, 0x1ccc, 0x1cc7, 0x1cc3, + 0x1cbe, 0x1cb9, 0x1cb5, 0x1cb0, 0x1cab, 0x1ca6, 0x1ca2, 0x1c9d, + 0x1c99, 0x1c94, 0x1c8f, 0x1c8b, 0x1c86, 0x1c82, 0x1c7d, 0x1c79, + 0x1c74, 0x1c70, 0x1c6c, 0x1c67, 0x1c63, 0x1c5e, 0x1c5a, 0x1c56, + 0x1c51, 0x1c4d, 0x1c49, 0x1c44, 0x1c40, 0x1c3c, 0x1c38, 0x1c34, + 0x1c2f, 0x1c2b, 0x1c27, 0x1c23, 0x1c1f, 0x1c1b, 0x1c17, 0x1c12, + 0x1c0e, 0x1c0a, 0x1c06, 0x1c02, 0x1bfd, 0x1bf5, 0x1bed, 0x1be5, + 0x1bdd, 0x1bd5, 0x1bcd, 0x1bc5, 0x1bbe, 0x1bb6, 0x1bae, 0x1ba7, + 0x1b9f, 0x1b97, 0x1b90, 0x1b88, 0x1b81, 0x1b79, 0x1b72, 0x1b6a, + 0x1b63, 0x1b5c, 0x1b54, 0x1b4d, 0x1b46, 0x1b3e, 0x1b37, 0x1b30, + 0x1b29, 0x1b22, 0x1b1a, 0x1b13, 0x1b0c, 0x1b05, 0x1afe, 0x1af7, + 0x1af0, 0x1ae9, 0x1ae2, 0x1adc, 0x1ad5, 0x1ace, 0x1ac7, 0x1ac0, + 0x1aba, 0x1ab3, 0x1aac, 0x1aa6, 0x1a9f, 0x1a98, 0x1a92, 0x1a8b, + 0x1a85, 0x1a7e, 0x1a78, 0x1a71, 0x1a6b, 0x1a64, 0x1a5e, 0x1a58, + 0x1a51, 0x1a4b, 0x1a45, 0x1a3f, 0x1a38, 0x1a32, 0x1a2c, 0x1a26, + 0x1a20, 0x1a19, 0x1a13, 0x1a0d, 0x1a07, 0x1a01, 0x19fb, 0x19f5, + 0x19ef, 0x19e9, 0x19e4, 0x19de, 0x19d8, 0x19d2, 0x19cc, 0x19c6, + 0x19c1, 0x19bb, 0x19b5, 0x19af, 0x19aa, 0x19a4, 0x199f, 0x1999, + 0x1993, 0x198e, 0x1988, 0x1983, 0x197d, 0x1978, 0x1972, 0x196d, + 0x1967, 0x1962, 0x195d, 0x1957, 0x1952, 0x194d, 0x1947, 0x1942, + 0x193d, 0x1938, 0x1932, 0x192d, 0x1928, 0x1923, 0x191e, 0x1919, + 0x1914, 0x190f, 0x1909, 0x1904, 0x18ff, 0x18fa, 0x18f5, 0x18f1, + 0x18ec, 0x18e7, 0x18e2, 0x18dd, 0x18d8, 0x18d3, 0x18ce, 0x18ca, + 0x18c5, 0x18c0, 0x18bb, 0x18b7, 0x18b2, 0x18ad, 0x18a9, 0x18a4, + 0x189f, 0x189b, 0x1896, 0x1891, 0x188d, 0x1888, 0x1884, 0x187f, + 0x187b, 0x1876, 0x1872, 0x186e, 0x1869, 0x1865, 0x1860, 0x185c, + 0x1858, 0x1853, 0x184f, 0x184b, 0x1846, 0x1842, 0x183e, 0x183a, + 0x1835, 0x1831, 0x182d, 0x1829, 0x1825, 0x1821, 0x181c, 0x1818, + 0x1814, 0x1810, 0x180c, 0x1808, 0x1804, 0x1800, 0x17f8, 0x17f0, + 0x17e8, 0x17e0, 0x17d8, 0x17d1, 0x17c9, 0x17c1, 0x17b9, 0x17b2, + 0x17aa, 0x17a2, 0x179b, 0x1793, 0x178c, 0x1784, 0x177d, 0x1775, + 0x176e, 0x1766, 0x175f, 0x1757, 0x1750, 0x1749, 0x1742, 0x173a, + 0x1733, 0x172c, 0x1725, 0x171e, 0x1717, 0x170f, 0x1708, 0x1701, + 0x16fa, 0x16f3, 0x16ec, 0x16e6, 0x16df, 0x16d8, 0x16d1, 0x16ca, + 0x16c3, 0x16bd, 0x16b6, 0x16af, 0x16a9, 0x16a2, 0x169b, 0x1695, + 0x168e, 0x1688, 0x1681, 0x167b, 0x1674, 0x166e, 0x1667, 0x1661, + 0x165b, 0x1654, 0x164e, 0x1648, 0x1641, 0x163b, 0x1635, 0x162f, + 0x1628, 0x1622, 0x161c, 0x1616, 0x1610, 0x160a, 0x1604, 0x15fe, + 0x15f8, 0x15f2, 0x15ec, 0x15e6, 0x15e0, 0x15da, 0x15d5, 0x15cf, + 0x15c9, 0x15c3, 0x15bd, 0x15b8, 0x15b2, 0x15ac, 0x15a7, 0x15a1, + 0x159b, 0x1596, 0x1590, 0x158b, 0x1585, 0x1580, 0x157a, 0x1575, + 0x156f, 0x156a, 0x1564, 0x155f, 0x155a, 0x1554, 0x154f, 0x154a, + 0x1544, 0x153f, 0x153a, 0x1535, 0x1530, 0x152a, 0x1525, 0x1520, + 0x151b, 0x1516, 0x1511, 0x150c, 0x1507, 0x1502, 0x14fd, 0x14f8, + 0x14f3, 0x14ee, 0x14e9, 0x14e4, 0x14df, 0x14da, 0x14d5, 0x14d1, + 0x14cc, 0x14c7, 0x14c2, 0x14bd, 0x14b9, 0x14b4, 0x14af, 0x14ab, + 0x14a6, 0x14a1, 0x149d, 0x1498, 0x1494, 0x148f, 0x148a, 0x1486, + 0x1481, 0x147d, 0x1478, 0x1474, 0x146f, 0x146b, 0x1467, 0x1462, + 0x145e, 0x145a, 0x1455, 0x1451, 0x144d, 0x1448, 0x1444, 0x1440, + 0x143b, 0x1437, 0x1433, 0x142f, 0x142b, 0x1427, 0x1422, 0x141e, + 0x141a, 0x1416, 0x1412, 0x140e, 0x140a, 0x1406, 0x1402, 0x13fc, + 0x13f4, 0x13ec, 0x13e4, 0x13dc, 0x13d4, 0x13cc, 0x13c5, 0x13bd, + 0x13b5, 0x13ad, 0x13a6, 0x139e, 0x1396, 0x138f, 0x1387, 0x1380, + 0x1378, 0x1371, 0x1369, 0x1362, 0x135b, 0x1353, 0x134c, 0x1345, + 0x133e, 0x1336, 0x132f, 0x1328, 0x1321, 0x131a, 0x1313, 0x130c, + 0x1304, 0x12fd, 0x12f7, 0x12f0, 0x12e9, 0x12e2, 0x12db, 0x12d4, + 0x12cd, 0x12c6, 0x12c0, 0x12b9, 0x12b2, 0x12ac, 0x12a5, 0x129e, + 0x1298, 0x1291, 0x128b, 0x1284, 0x127d, 0x1277, 0x1271, 0x126a, + 0x1264, 0x125d, 0x1257, 0x1251, 0x124a, 0x1244, 0x123e, 0x1238, + 0x1231, 0x122b, 0x1225, 0x121f, 0x1219, 0x1213, 0x120d, 0x1207, + 0x1201, 0x11fb, 0x11f5, 0x11ef, 0x11e9, 0x11e3, 0x11dd, 0x11d7, + 0x11d1, 0x11cc, 0x11c6, 0x11c0, 0x11ba, 0x11b5, 0x11af, 0x11a9, + 0x11a4, 0x119e, 0x1198, 0x1193, 0x118d, 0x1188, 0x1182, 0x117d, + 0x1177, 0x1172, 0x116c, 0x1167, 0x1161, 0x115c, 0x1157, 0x1151, + 0x114c, 0x1147, 0x1142, 0x113c, 0x1137, 0x1132, 0x112d, 0x1127, + 0x1122, 0x111d, 0x1118, 0x1113, 0x110e, 0x1109, 0x1104, 0x10ff, + 0x10fa, 0x10f5, 0x10f0, 0x10eb, 0x10e6, 0x10e1, 0x10dc, 0x10d8, + 0x10d3, 0x10ce, 0x10c9, 0x10c4, 0x10c0, 0x10bb, 0x10b6, 0x10b1, + 0x10ad, 0x10a8, 0x10a3, 0x109f, 0x109a, 0x1096, 0x1091, 0x108c, + 0x1088, 0x1083, 0x107f, 0x107a, 0x1076, 0x1071, 0x106d, 0x1069, + 0x1064, 0x1060, 0x105b, 0x1057, 0x1053, 0x104e, 0x104a, 0x1046, + 0x1042, 0x103d, 0x1039, 0x1035, 0x1031, 0x102d, 0x1028, 0x1024, + 0x1020, 0x101c, 0x1018, 0x1014, 0x1010, 0x100c, 0x1008, 0x1004, + 0x0fff, 0x0ff7, 0x0fef, 0x0fe7, 0x0fdf, 0x0fd8, 0x0fd0, 0x0fc8, + 0x0fc0, 0x0fb8, 0x0fb1, 0x0fa9, 0x0fa1, 0x0f9a, 0x0f92, 0x0f8b, + 0x0f83, 0x0f7c, 0x0f74, 0x0f6d, 0x0f65, 0x0f5e, 0x0f57, 0x0f4f, + 0x0f48, 0x0f41, 0x0f3a, 0x0f32, 0x0f2b, 0x0f24, 0x0f1d, 0x0f16, + 0x0f0f, 0x0f08, 0x0f01, 0x0efa, 0x0ef3, 0x0eec, 0x0ee5, 0x0ede, + 0x0ed7, 0x0ed0, 0x0ec9, 0x0ec3, 0x0ebc, 0x0eb5, 0x0eaf, 0x0ea8, + 0x0ea1, 0x0e9b, 0x0e94, 0x0e8d, 0x0e87, 0x0e80, 0x0e7a, 0x0e73, + 0x0e6d, 0x0e67, 0x0e60, 0x0e5a, 0x0e53, 0x0e4d, 0x0e47, 0x0e41, + 0x0e3a, 0x0e34, 0x0e2e, 0x0e28, 0x0e22, 0x0e1c, 0x0e15, 0x0e0f, + 0x0e09, 0x0e03, 0x0dfd, 0x0df7, 0x0df1, 0x0deb, 0x0de6, 0x0de0, + 0x0dda, 0x0dd4, 0x0dce, 0x0dc8, 0x0dc3, 0x0dbd, 0x0db7, 0x0db1, + 0x0dac, 0x0da6, 0x0da0, 0x0d9b, 0x0d95, 0x0d90, 0x0d8a, 0x0d85, + 0x0d7f, 0x0d74, 0x0d69, 0x0d5e, 0x0d54, 0x0d49, 0x0d3f, 0x0d34, + 0x0d2a, 0x0d1f, 0x0d15, 0x0d0b, 0x0d01, 0x0cf7, 0x0ced, 0x0ce3, + 0x0cda, 0x0cd0, 0x0cc6, 0x0cbd, 0x0cb3, 0x0caa, 0x0ca1, 0x0c98, + 0x0c8e, 0x0c85, 0x0c7c, 0x0c73, 0x0c6b, 0x0c62, 0x0c59, 0x0c50, + 0x0c48, 0x0c3f, 0x0c37, 0x0c2e, 0x0c26, 0x0c1e, 0x0c16, 0x0c0d, + 0x0c05, 0x0bfb, 0x0beb, 0x0bdb, 0x0bcb, 0x0bbc, 0x0bad, 0x0b9d, + 0x0b8e, 0x0b7f, 0x0b70, 0x0b61, 0x0b53, 0x0b44, 0x0b36, 0x0b27, + 0x0b19, 0x0b0b, 0x0afd, 0x0aef, 0x0ae1, 0x0ad3, 0x0ac6, 0x0ab8, + 0x0aab, 0x0a9e, 0x0a90, 0x0a83, 0x0a76, 0x0a69, 0x0a5d, 0x0a50, + 0x0a43, 0x0a37, 0x0a2b, 0x0a1e, 0x0a12, 0x0a06, 0x09fa, 0x09ee, + 0x09e2, 0x09d7, 0x09cb, 0x09bf, 0x09b4, 0x09a9, 0x099d, 0x0992, + 0x0987, 0x097c, 0x0971, 0x0966, 0x095b, 0x0951, 0x0946, 0x093c, + 0x0931, 0x0927, 0x091d, 0x0912, 0x0908, 0x08fe, 0x08f4, 0x08eb, + 0x08e1, 0x08d7, 0x08cd, 0x08c4, 0x08ba, 0x08b1, 0x08a8, 0x089e, + 0x0895, 0x088c, 0x0883, 0x087a, 0x0871, 0x0868, 0x085f, 0x0857, + 0x084e, 0x0845, 0x083d, 0x0834, 0x082c, 0x0824, 0x081c, 0x0813, + 0x080b, 0x0803, 0x07f6, 0x07e7, 0x07d7, 0x07c7, 0x07b8, 0x07a8, + 0x0799, 0x078a, 0x077b, 0x076c, 0x075d, 0x074f, 0x0740, 0x0732, + 0x0723, 0x0715, 0x0707, 0x06f9, 0x06eb, 0x06dd, 0x06d0, 0x06c2, + 0x06b4, 0x06a7, 0x069a, 0x068d, 0x0680, 0x0673, 0x0666, 0x0659, + 0x064c, 0x0640, 0x0633, 0x0627, 0x061b, 0x060f, 0x0603, 0x05f7, + 0x05eb, 0x05df, 0x05d3, 0x05c8, 0x05bc, 0x05b1, 0x05a5, 0x059a, + 0x058f, 0x0584, 0x0579, 0x056e, 0x0563, 0x0558, 0x054e, 0x0543, + 0x0539, 0x052e, 0x0524, 0x051a, 0x0510, 0x0506, 0x04fc, 0x04f2, + 0x04e8, 0x04de, 0x04d4, 0x04cb, 0x04c1, 0x04b8, 0x04ae, 0x04a5, + 0x049c, 0x0493, 0x0489, 0x0480, 0x0477, 0x046f, 0x0466, 0x045d, + 0x0454, 0x044c, 0x0443, 0x043b, 0x0432, 0x042a, 0x0421, 0x0419, + 0x0411, 0x0409, 0x0401, 0x03f9, 0x03f1, 0x03e9, 0x03e1, 0x03da, + 0x03d2, 0x03ca, 0x03c3, 0x03bb, 0x03b4, 0x03ad, 0x03a5, 0x039e, + 0x0397, 0x0390, 0x0389, 0x0381, 0x037a, 0x0374, 0x036d, 0x0366, + 0x035f, 0x0358, 0x0352, 0x034b, 0x0345, 0x033e, 0x0338, 0x0331, + 0x032b, 0x0324, 0x031e, 0x0318, 0x0312, 0x030c, 0x0306, 0x0300, + 0x02fa, 0x02f4, 0x02ee, 0x02e8, 0x02e2, 0x02dd, 0x02d7, 0x02d1, + 0x02cc, 0x02c6, 0x02c0, 0x02bb, 0x02b6, 0x02b0, 0x02ab, 0x02a5, + 0x02a0, 0x029b, 0x0296, 0x0291, 0x028c, 0x0286, 0x0281, 0x027c, + 0x0277, 0x0273, 0x026e, 0x0269, 0x0264, 0x025f, 0x025b, 0x0256, + 0x0251, 0x024d, 0x0248, 0x0243, 0x023f, 0x023a, 0x0236, 0x0232, + 0x022d, 0x0229, 0x0225, 0x0220, 0x021c, 0x0218, 0x0214, 0x0210, + 0x020b, 0x0207, 0x0203, 0x01ff, 0x01fb, 0x01f7, 0x01f4, 0x01f0, + 0x01ec, 0x01e8, 0x01e4, 0x01e0, 0x01dd, 0x01d9, 0x01d5, 0x01d2, + 0x01ce, 0x01ca, 0x01c7, 0x01c3, 0x01c0, 0x01bc, 0x01b9, 0x01b5, + 0x01b2, 0x01af, 0x01ab, 0x01a8, 0x01a5, 0x01a1, 0x019e, 0x019b, + 0x0198, 0x0195, 0x0191, 0x018e, 0x018b, 0x0188, 0x0185, 0x0182, + 0x017f, 0x017c, 0x0179, 0x0176, 0x0173, 0x0170, 0x016d, 0x016b, + 0x0168, 0x0165, 0x0162, 0x015f, 0x015d, 0x015a, 0x0157, 0x0155, + 0x0152, 0x014f, 0x014d, 0x014a, 0x0148, 0x0145, 0x0143, 0x0140, + 0x013e, 0x013b, 0x0139, 0x0136, 0x0134, 0x0131, 0x012f, 0x012d, + 0x012a, 0x0128, 0x0126, 0x0123, 0x0121, 0x011f, 0x011d, 0x011a, + 0x0118, 0x0116, 0x0114, 0x0112, 0x0110, 0x010d, 0x010b, 0x0109, + 0x0107, 0x0105, 0x0103, 0x0101, 0x00ff, 0x00fd, 0x00fb, 0x00f9, + 0x00f7, 0x00f5, 0x00f3, 0x00f2, 0x00f0, 0x00ee, 0x00ec, 0x00ea, + 0x00e8, 0x00e6, 0x00e5, 0x00e3, 0x00e1, 0x00df, 0x00de, 0x00dc, + 0x00da, 0x00d9, 0x00d7, 0x00d5, 0x00d4, 0x00d2, 0x00d0, 0x00cf, + 0x00cd, 0x00cb, 0x00ca, 0x00c8, 0x00c7, 0x00c5, 0x00c4, 0x00c2, + 0x00c1, 0x00bf, 0x00be, 0x00bc, 0x00bb, 0x00b9, 0x00b8, 0x00b6, + 0x00b5, 0x00b4, 0x00b2, 0x00b1, 0x00af, 0x00ae, 0x00ad, 0x00ab, + 0x00aa, 0x00a9, 0x00a7, 0x00a6, 0x00a5, 0x00a3, 0x00a2, 0x00a1, + 0x00a0, 0x009e, 0x009d, 0x009c, 0x009b, 0x009a, 0x0098, 0x0097, + 0x0096, 0x0095, 0x0094, 0x0093, 0x0091, 0x0090, 0x008f, 0x008e, + 0x008d, 0x008c, 0x008b, 0x008a, 0x0089, 0x0087, 0x0086, 0x0085, + 0x0084, 0x0083, 0x0082, 0x0081, 0x0080, 0x007f, 0x007e, 0x007d, + 0x007c, 0x007b, 0x007a, 0x0079, 0x0079, 0x0078, 0x0077, 0x0076, + 0x0075, 0x0074, 0x0073, 0x0072, 0x0071, 0x0070, 0x006f, 0x006f, + 0x006e, 0x006d, 0x006c, 0x006b, 0x006a, 0x006a, 0x0069, 0x0068, + 0x0067, 0x0066, 0x0065, 0x0065, 0x0064, 0x0063, 0x0062, 0x0062, + 0x0061, 0x0060, 0x005f, 0x005f, 0x005e, 0x005d, 0x005c, 0x005c, + 0x005b, 0x005a, 0x005a, 0x0059, 0x0058, 0x0057, 0x0057, 0x0056, + 0x0055, 0x0055, 0x0054, 0x0053, 0x0053, 0x0052, 0x0052, 0x0051, + 0x0050, 0x0050, 0x004f, 0x004e, 0x004e, 0x004d, 0x004d, 0x004c, + 0x004b, 0x004b, 0x004a, 0x004a, 0x0049, 0x0049, 0x0048, 0x0047, + 0x0047, 0x0046, 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, + 0x0043, 0x0042, 0x0042, 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, + 0x003f, 0x003e, 0x003e, 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, + 0x003b, 0x003a, 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, + 0x0037, 0x0037, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, + 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0031, 0x0031, + 0x0031, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, 0x002e, 0x002e, + 0x002e, 0x002d, 0x002d, 0x002d, 0x002c, 0x002c, 0x002c, 0x002b, + 0x002b, 0x002b, 0x002a, 0x002a, 0x002a, 0x0029, 0x0029, 0x0029, + 0x0028, 0x0028, 0x0028, 0x0027, 0x0027, 0x0027, 0x0027, 0x0026, + 0x0026, 0x0026, 0x0025, 0x0025, 0x0025, 0x0024, 0x0024, 0x0024, + 0x0024, 0x0023, 0x0023, 0x0023, 0x0023, 0x0022, 0x0022, 0x0022, + 0x0021, 0x0021, 0x0021, 0x0021, 0x0020, 0x0020, 0x0020, 0x0020, + 0x001f, 0x001f, 0x001f, 0x001f, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001d, 0x001d, 0x001d, 0x001d, 0x001c, 0x001c, 0x001c, + 0x001c, 0x001c, 0x001b, 0x001b, 0x001b, 0x001b, 0x001a, 0x001a, + 0x001a, 0x001a, 0x001a, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, + 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0017, 0x0017, + 0x0017, 0x0017, 0x0017, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, + 0x0016, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0014, + 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0013, 0x0013, + 0x0013, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012, 0x0012, + 0x0012, 0x0012, 0x0012, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, + 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0010, 0x0010, 0x0010, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, + 0x000f, 0x000f, 0x000f, 0x000f, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, + 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000c, + 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, + 0x000c, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, + 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; + +const unsigned short logTable[] = +{ + 0xfc00, 0xd829, 0xd7f9, 0xd7c5, 0xd7a0, 0xd783, 0xd76c, 0xd758, + 0xd747, 0xd738, 0xd72b, 0xd71e, 0xd713, 0xd709, 0xd700, 0xd6f7, + 0xd6ee, 0xd6e7, 0xd6df, 0xd6d8, 0xd6d2, 0xd6cc, 0xd6c6, 0xd6c0, + 0xd6bb, 0xd6b5, 0xd6b0, 0xd6ab, 0xd6a7, 0xd6a2, 0xd69e, 0xd69a, + 0xd696, 0xd692, 0xd68e, 0xd68a, 0xd687, 0xd683, 0xd680, 0xd67c, + 0xd679, 0xd676, 0xd673, 0xd670, 0xd66d, 0xd66a, 0xd667, 0xd665, + 0xd662, 0xd65f, 0xd65d, 0xd65a, 0xd658, 0xd655, 0xd653, 0xd650, + 0xd64e, 0xd64c, 0xd64a, 0xd647, 0xd645, 0xd643, 0xd641, 0xd63f, + 0xd63d, 0xd63b, 0xd639, 0xd637, 0xd635, 0xd633, 0xd632, 0xd630, + 0xd62e, 0xd62c, 0xd62a, 0xd629, 0xd627, 0xd625, 0xd624, 0xd622, + 0xd620, 0xd61f, 0xd61d, 0xd61c, 0xd61a, 0xd619, 0xd617, 0xd616, + 0xd614, 0xd613, 0xd611, 0xd610, 0xd60f, 0xd60d, 0xd60c, 0xd60a, + 0xd609, 0xd608, 0xd606, 0xd605, 0xd604, 0xd603, 0xd601, 0xd600, + 0xd5ff, 0xd5fe, 0xd5fc, 0xd5fb, 0xd5fa, 0xd5f9, 0xd5f8, 0xd5f7, + 0xd5f5, 0xd5f4, 0xd5f3, 0xd5f2, 0xd5f1, 0xd5f0, 0xd5ef, 0xd5ee, + 0xd5ed, 0xd5eb, 0xd5ea, 0xd5e9, 0xd5e8, 0xd5e7, 0xd5e6, 0xd5e5, + 0xd5e4, 0xd5e3, 0xd5e2, 0xd5e1, 0xd5e0, 0xd5df, 0xd5de, 0xd5dd, + 0xd5dd, 0xd5dc, 0xd5db, 0xd5da, 0xd5d9, 0xd5d8, 0xd5d7, 0xd5d6, + 0xd5d5, 0xd5d4, 0xd5d3, 0xd5d3, 0xd5d2, 0xd5d1, 0xd5d0, 0xd5cf, + 0xd5ce, 0xd5cd, 0xd5cd, 0xd5cc, 0xd5cb, 0xd5ca, 0xd5c9, 0xd5c9, + 0xd5c8, 0xd5c7, 0xd5c6, 0xd5c5, 0xd5c5, 0xd5c4, 0xd5c3, 0xd5c2, + 0xd5c1, 0xd5c1, 0xd5c0, 0xd5bf, 0xd5be, 0xd5be, 0xd5bd, 0xd5bc, + 0xd5bc, 0xd5bb, 0xd5ba, 0xd5b9, 0xd5b9, 0xd5b8, 0xd5b7, 0xd5b7, + 0xd5b6, 0xd5b5, 0xd5b4, 0xd5b4, 0xd5b3, 0xd5b2, 0xd5b2, 0xd5b1, + 0xd5b0, 0xd5b0, 0xd5af, 0xd5ae, 0xd5ae, 0xd5ad, 0xd5ac, 0xd5ac, + 0xd5ab, 0xd5ab, 0xd5aa, 0xd5a9, 0xd5a9, 0xd5a8, 0xd5a7, 0xd5a7, + 0xd5a6, 0xd5a6, 0xd5a5, 0xd5a4, 0xd5a4, 0xd5a3, 0xd5a3, 0xd5a2, + 0xd5a1, 0xd5a1, 0xd5a0, 0xd5a0, 0xd59f, 0xd59e, 0xd59e, 0xd59d, + 0xd59d, 0xd59c, 0xd59c, 0xd59b, 0xd59a, 0xd59a, 0xd599, 0xd599, + 0xd598, 0xd598, 0xd597, 0xd597, 0xd596, 0xd595, 0xd595, 0xd594, + 0xd594, 0xd593, 0xd593, 0xd592, 0xd592, 0xd591, 0xd591, 0xd590, + 0xd590, 0xd58f, 0xd58f, 0xd58e, 0xd58e, 0xd58d, 0xd58d, 0xd58c, + 0xd58c, 0xd58b, 0xd58b, 0xd58a, 0xd58a, 0xd589, 0xd589, 0xd588, + 0xd588, 0xd587, 0xd587, 0xd586, 0xd586, 0xd585, 0xd585, 0xd584, + 0xd584, 0xd583, 0xd583, 0xd582, 0xd582, 0xd581, 0xd581, 0xd581, + 0xd580, 0xd580, 0xd57f, 0xd57f, 0xd57e, 0xd57e, 0xd57d, 0xd57d, + 0xd57c, 0xd57c, 0xd57c, 0xd57b, 0xd57b, 0xd57a, 0xd57a, 0xd579, + 0xd579, 0xd579, 0xd578, 0xd578, 0xd577, 0xd577, 0xd576, 0xd576, + 0xd576, 0xd575, 0xd575, 0xd574, 0xd574, 0xd573, 0xd573, 0xd573, + 0xd572, 0xd572, 0xd571, 0xd571, 0xd571, 0xd570, 0xd570, 0xd56f, + 0xd56f, 0xd56f, 0xd56e, 0xd56e, 0xd56d, 0xd56d, 0xd56d, 0xd56c, + 0xd56c, 0xd56b, 0xd56b, 0xd56b, 0xd56a, 0xd56a, 0xd56a, 0xd569, + 0xd569, 0xd568, 0xd568, 0xd568, 0xd567, 0xd567, 0xd566, 0xd566, + 0xd566, 0xd565, 0xd565, 0xd565, 0xd564, 0xd564, 0xd564, 0xd563, + 0xd563, 0xd562, 0xd562, 0xd562, 0xd561, 0xd561, 0xd561, 0xd560, + 0xd560, 0xd560, 0xd55f, 0xd55f, 0xd55f, 0xd55e, 0xd55e, 0xd55d, + 0xd55d, 0xd55d, 0xd55c, 0xd55c, 0xd55c, 0xd55b, 0xd55b, 0xd55b, + 0xd55a, 0xd55a, 0xd55a, 0xd559, 0xd559, 0xd559, 0xd558, 0xd558, + 0xd558, 0xd557, 0xd557, 0xd557, 0xd556, 0xd556, 0xd556, 0xd555, + 0xd555, 0xd555, 0xd554, 0xd554, 0xd554, 0xd553, 0xd553, 0xd553, + 0xd552, 0xd552, 0xd552, 0xd551, 0xd551, 0xd551, 0xd551, 0xd550, + 0xd550, 0xd550, 0xd54f, 0xd54f, 0xd54f, 0xd54e, 0xd54e, 0xd54e, + 0xd54d, 0xd54d, 0xd54d, 0xd54d, 0xd54c, 0xd54c, 0xd54c, 0xd54b, + 0xd54b, 0xd54b, 0xd54a, 0xd54a, 0xd54a, 0xd549, 0xd549, 0xd549, + 0xd549, 0xd548, 0xd548, 0xd548, 0xd547, 0xd547, 0xd547, 0xd547, + 0xd546, 0xd546, 0xd546, 0xd545, 0xd545, 0xd545, 0xd545, 0xd544, + 0xd544, 0xd544, 0xd543, 0xd543, 0xd543, 0xd543, 0xd542, 0xd542, + 0xd542, 0xd541, 0xd541, 0xd541, 0xd541, 0xd540, 0xd540, 0xd540, + 0xd53f, 0xd53f, 0xd53f, 0xd53f, 0xd53e, 0xd53e, 0xd53e, 0xd53e, + 0xd53d, 0xd53d, 0xd53d, 0xd53c, 0xd53c, 0xd53c, 0xd53c, 0xd53b, + 0xd53b, 0xd53b, 0xd53b, 0xd53a, 0xd53a, 0xd53a, 0xd53a, 0xd539, + 0xd539, 0xd539, 0xd538, 0xd538, 0xd538, 0xd538, 0xd537, 0xd537, + 0xd537, 0xd537, 0xd536, 0xd536, 0xd536, 0xd536, 0xd535, 0xd535, + 0xd535, 0xd535, 0xd534, 0xd534, 0xd534, 0xd534, 0xd533, 0xd533, + 0xd533, 0xd533, 0xd532, 0xd532, 0xd532, 0xd532, 0xd531, 0xd531, + 0xd531, 0xd531, 0xd530, 0xd530, 0xd530, 0xd530, 0xd52f, 0xd52f, + 0xd52f, 0xd52f, 0xd52e, 0xd52e, 0xd52e, 0xd52e, 0xd52d, 0xd52d, + 0xd52d, 0xd52d, 0xd52d, 0xd52c, 0xd52c, 0xd52c, 0xd52c, 0xd52b, + 0xd52b, 0xd52b, 0xd52b, 0xd52a, 0xd52a, 0xd52a, 0xd52a, 0xd529, + 0xd529, 0xd529, 0xd529, 0xd529, 0xd528, 0xd528, 0xd528, 0xd528, + 0xd527, 0xd527, 0xd527, 0xd527, 0xd526, 0xd526, 0xd526, 0xd526, + 0xd526, 0xd525, 0xd525, 0xd525, 0xd525, 0xd524, 0xd524, 0xd524, + 0xd524, 0xd524, 0xd523, 0xd523, 0xd523, 0xd523, 0xd522, 0xd522, + 0xd522, 0xd522, 0xd522, 0xd521, 0xd521, 0xd521, 0xd521, 0xd520, + 0xd520, 0xd520, 0xd520, 0xd520, 0xd51f, 0xd51f, 0xd51f, 0xd51f, + 0xd51f, 0xd51e, 0xd51e, 0xd51e, 0xd51e, 0xd51d, 0xd51d, 0xd51d, + 0xd51d, 0xd51d, 0xd51c, 0xd51c, 0xd51c, 0xd51c, 0xd51c, 0xd51b, + 0xd51b, 0xd51b, 0xd51b, 0xd51b, 0xd51a, 0xd51a, 0xd51a, 0xd51a, + 0xd51a, 0xd519, 0xd519, 0xd519, 0xd519, 0xd518, 0xd518, 0xd518, + 0xd518, 0xd518, 0xd517, 0xd517, 0xd517, 0xd517, 0xd517, 0xd516, + 0xd516, 0xd516, 0xd516, 0xd516, 0xd515, 0xd515, 0xd515, 0xd515, + 0xd515, 0xd514, 0xd514, 0xd514, 0xd514, 0xd514, 0xd514, 0xd513, + 0xd513, 0xd513, 0xd513, 0xd513, 0xd512, 0xd512, 0xd512, 0xd512, + 0xd512, 0xd511, 0xd511, 0xd511, 0xd511, 0xd511, 0xd510, 0xd510, + 0xd510, 0xd510, 0xd510, 0xd50f, 0xd50f, 0xd50f, 0xd50f, 0xd50f, + 0xd50f, 0xd50e, 0xd50e, 0xd50e, 0xd50e, 0xd50e, 0xd50d, 0xd50d, + 0xd50d, 0xd50d, 0xd50d, 0xd50c, 0xd50c, 0xd50c, 0xd50c, 0xd50c, + 0xd50c, 0xd50b, 0xd50b, 0xd50b, 0xd50b, 0xd50b, 0xd50a, 0xd50a, + 0xd50a, 0xd50a, 0xd50a, 0xd50a, 0xd509, 0xd509, 0xd509, 0xd509, + 0xd509, 0xd508, 0xd508, 0xd508, 0xd508, 0xd508, 0xd508, 0xd507, + 0xd507, 0xd507, 0xd507, 0xd507, 0xd506, 0xd506, 0xd506, 0xd506, + 0xd506, 0xd506, 0xd505, 0xd505, 0xd505, 0xd505, 0xd505, 0xd505, + 0xd504, 0xd504, 0xd504, 0xd504, 0xd504, 0xd504, 0xd503, 0xd503, + 0xd503, 0xd503, 0xd503, 0xd502, 0xd502, 0xd502, 0xd502, 0xd502, + 0xd502, 0xd501, 0xd501, 0xd501, 0xd501, 0xd501, 0xd501, 0xd500, + 0xd500, 0xd500, 0xd500, 0xd500, 0xd500, 0xd4ff, 0xd4ff, 0xd4ff, + 0xd4ff, 0xd4ff, 0xd4ff, 0xd4fe, 0xd4fe, 0xd4fe, 0xd4fe, 0xd4fe, + 0xd4fe, 0xd4fd, 0xd4fd, 0xd4fd, 0xd4fd, 0xd4fd, 0xd4fd, 0xd4fc, + 0xd4fc, 0xd4fc, 0xd4fc, 0xd4fc, 0xd4fc, 0xd4fb, 0xd4fb, 0xd4fb, + 0xd4fb, 0xd4fb, 0xd4fb, 0xd4fb, 0xd4fa, 0xd4fa, 0xd4fa, 0xd4fa, + 0xd4fa, 0xd4fa, 0xd4f9, 0xd4f9, 0xd4f9, 0xd4f9, 0xd4f9, 0xd4f9, + 0xd4f8, 0xd4f8, 0xd4f8, 0xd4f8, 0xd4f8, 0xd4f8, 0xd4f7, 0xd4f7, + 0xd4f7, 0xd4f7, 0xd4f7, 0xd4f7, 0xd4f7, 0xd4f6, 0xd4f6, 0xd4f6, + 0xd4f6, 0xd4f6, 0xd4f6, 0xd4f5, 0xd4f5, 0xd4f5, 0xd4f5, 0xd4f5, + 0xd4f5, 0xd4f5, 0xd4f4, 0xd4f4, 0xd4f4, 0xd4f4, 0xd4f4, 0xd4f4, + 0xd4f3, 0xd4f3, 0xd4f3, 0xd4f3, 0xd4f3, 0xd4f3, 0xd4f3, 0xd4f2, + 0xd4f2, 0xd4f2, 0xd4f2, 0xd4f2, 0xd4f2, 0xd4f2, 0xd4f1, 0xd4f1, + 0xd4f1, 0xd4f1, 0xd4f1, 0xd4f1, 0xd4f0, 0xd4f0, 0xd4f0, 0xd4f0, + 0xd4f0, 0xd4f0, 0xd4f0, 0xd4ef, 0xd4ef, 0xd4ef, 0xd4ef, 0xd4ef, + 0xd4ef, 0xd4ef, 0xd4ee, 0xd4ee, 0xd4ee, 0xd4ee, 0xd4ee, 0xd4ee, + 0xd4ee, 0xd4ed, 0xd4ed, 0xd4ed, 0xd4ed, 0xd4ed, 0xd4ed, 0xd4ed, + 0xd4ec, 0xd4ec, 0xd4ec, 0xd4ec, 0xd4ec, 0xd4ec, 0xd4eb, 0xd4eb, + 0xd4eb, 0xd4eb, 0xd4eb, 0xd4eb, 0xd4eb, 0xd4ea, 0xd4ea, 0xd4ea, + 0xd4ea, 0xd4ea, 0xd4ea, 0xd4ea, 0xd4ea, 0xd4e9, 0xd4e9, 0xd4e9, + 0xd4e9, 0xd4e9, 0xd4e9, 0xd4e9, 0xd4e8, 0xd4e8, 0xd4e8, 0xd4e8, + 0xd4e8, 0xd4e8, 0xd4e8, 0xd4e7, 0xd4e7, 0xd4e7, 0xd4e7, 0xd4e7, + 0xd4e7, 0xd4e7, 0xd4e6, 0xd4e6, 0xd4e6, 0xd4e6, 0xd4e6, 0xd4e6, + 0xd4e6, 0xd4e5, 0xd4e5, 0xd4e5, 0xd4e5, 0xd4e5, 0xd4e5, 0xd4e5, + 0xd4e5, 0xd4e4, 0xd4e4, 0xd4e4, 0xd4e4, 0xd4e4, 0xd4e4, 0xd4e4, + 0xd4e3, 0xd4e3, 0xd4e3, 0xd4e3, 0xd4e3, 0xd4e3, 0xd4e3, 0xd4e3, + 0xd4e2, 0xd4e2, 0xd4e2, 0xd4e2, 0xd4e2, 0xd4e2, 0xd4e2, 0xd4e1, + 0xd4e1, 0xd4e1, 0xd4e1, 0xd4e1, 0xd4e1, 0xd4e1, 0xd4e1, 0xd4e0, + 0xd4e0, 0xd4e0, 0xd4e0, 0xd4e0, 0xd4e0, 0xd4e0, 0xd4df, 0xd4df, + 0xd4df, 0xd4df, 0xd4df, 0xd4df, 0xd4df, 0xd4df, 0xd4de, 0xd4de, + 0xd4de, 0xd4de, 0xd4de, 0xd4de, 0xd4de, 0xd4de, 0xd4dd, 0xd4dd, + 0xd4dd, 0xd4dd, 0xd4dd, 0xd4dd, 0xd4dd, 0xd4dd, 0xd4dc, 0xd4dc, + 0xd4dc, 0xd4dc, 0xd4dc, 0xd4dc, 0xd4dc, 0xd4dc, 0xd4db, 0xd4db, + 0xd4db, 0xd4db, 0xd4db, 0xd4db, 0xd4db, 0xd4da, 0xd4da, 0xd4da, + 0xd4da, 0xd4da, 0xd4da, 0xd4da, 0xd4da, 0xd4d9, 0xd4d9, 0xd4d9, + 0xd4d9, 0xd4d9, 0xd4d9, 0xd4d9, 0xd4d9, 0xd4d9, 0xd4d8, 0xd4d8, + 0xd4d8, 0xd4d8, 0xd4d8, 0xd4d8, 0xd4d8, 0xd4d8, 0xd4d7, 0xd4d7, + 0xd4d7, 0xd4d7, 0xd4d7, 0xd4d7, 0xd4d7, 0xd4d7, 0xd4d6, 0xd4d6, + 0xd4d6, 0xd4d6, 0xd4d6, 0xd4d6, 0xd4d6, 0xd4d6, 0xd4d5, 0xd4d5, + 0xd4d5, 0xd4d5, 0xd4d5, 0xd4d5, 0xd4d5, 0xd4d5, 0xd4d4, 0xd4d4, + 0xd4d4, 0xd4d4, 0xd4d4, 0xd4d4, 0xd4d4, 0xd4d4, 0xd4d4, 0xd4d3, + 0xd4d3, 0xd4d3, 0xd4d3, 0xd4d3, 0xd4d3, 0xd4d3, 0xd4d3, 0xd4d2, + 0xd4d2, 0xd4d2, 0xd4d2, 0xd4d2, 0xd4d2, 0xd4d2, 0xd4d2, 0xd4d2, + 0xd4d1, 0xd4d1, 0xd4d1, 0xd4d1, 0xd4d1, 0xd4d1, 0xd4d1, 0xd4d1, + 0xd4d0, 0xd4d0, 0xd4d0, 0xd4d0, 0xd4d0, 0xd4d0, 0xd4d0, 0xd4d0, + 0xd4d0, 0xd4cf, 0xd4cf, 0xd4cf, 0xd4cf, 0xd4cf, 0xd4cf, 0xd4cf, + 0xd4cf, 0xd4cf, 0xd4ce, 0xd4ce, 0xd4ce, 0xd4ce, 0xd4ce, 0xd4ce, + 0xd4ce, 0xd4ce, 0xd4ce, 0xd4cd, 0xd4cd, 0xd4cd, 0xd4cd, 0xd4cd, + 0xd4cd, 0xd4cd, 0xd4cd, 0xd4cc, 0xd4cc, 0xd4cc, 0xd4cc, 0xd4cc, + 0xd4cc, 0xd4cc, 0xd4cc, 0xd4cc, 0xd4cb, 0xd4cb, 0xd4cb, 0xd4cb, + 0xd4cb, 0xd4cb, 0xd4cb, 0xd4cb, 0xd4cb, 0xd4ca, 0xd4ca, 0xd4ca, + 0xd4ca, 0xd4ca, 0xd4ca, 0xd4ca, 0xd4ca, 0xd4ca, 0xd4c9, 0xd4c9, + 0xd4c9, 0xd4c9, 0xd4c9, 0xd4c9, 0xd4c9, 0xd4c9, 0xd4c9, 0xd4c9, + 0xd4c8, 0xd4c8, 0xd4c8, 0xd4c8, 0xd4c8, 0xd4c8, 0xd4c8, 0xd4c8, + 0xd4c8, 0xd4c7, 0xd4c7, 0xd4c7, 0xd4c7, 0xd4c7, 0xd4c7, 0xd4c7, + 0xd4c7, 0xd4c7, 0xd4c6, 0xd4c6, 0xd4c6, 0xd4c6, 0xd4c6, 0xd4c6, + 0xd4c6, 0xd4c6, 0xd4c6, 0xd4c5, 0xd4c5, 0xd4c5, 0xd4c5, 0xd4c5, + 0xd4c5, 0xd4c5, 0xd4c5, 0xd4c5, 0xd4c5, 0xd4c4, 0xd4c4, 0xd4c4, + 0xd4c4, 0xd4c4, 0xd4c4, 0xd4c4, 0xd4c4, 0xd4c4, 0xd4c3, 0xd4c3, + 0xd4c3, 0xd4c3, 0xd4c3, 0xd4c3, 0xd4c3, 0xd4c3, 0xd4c3, 0xd4c3, + 0xd4c2, 0xd4c2, 0xd4c2, 0xd4c2, 0xd4c2, 0xd4c2, 0xd4c2, 0xd4c2, + 0xd4c2, 0xd4c2, 0xd4c1, 0xd4c1, 0xd4c1, 0xd4c1, 0xd4c1, 0xd4c1, + 0xd4c1, 0xd4c1, 0xd4c1, 0xd4c0, 0xd4c0, 0xd4c0, 0xd4c0, 0xd4c0, + 0xd4c0, 0xd4c0, 0xd4c0, 0xd4c0, 0xd4c0, 0xd4bf, 0xd4bf, 0xd4bf, + 0xd4bf, 0xd4bf, 0xd4bf, 0xd4bf, 0xd4bf, 0xd4bf, 0xd4bf, 0xd4be, + 0xd4be, 0xd4be, 0xd4be, 0xd4be, 0xd4be, 0xd4be, 0xd4be, 0xd4be, + 0xd4be, 0xd4bd, 0xd4bd, 0xd4bd, 0xd4bd, 0xd4bd, 0xd4bd, 0xd4bd, + 0xd4bd, 0xd4bd, 0xd4bd, 0xd4bc, 0xd4bc, 0xd4bc, 0xd4bc, 0xd4bc, + 0xd4bc, 0xd4bc, 0xd4bc, 0xd4bc, 0xd4bc, 0xd4bb, 0xd4bb, 0xd4bb, + 0xd4bb, 0xd4bb, 0xd4bb, 0xd4bb, 0xd4bb, 0xd4bb, 0xd4bb, 0xd4ba, + 0xd4ba, 0xd4ba, 0xd4ba, 0xd4ba, 0xd4ba, 0xd4ba, 0xd4ba, 0xd4ba, + 0xd4ba, 0xd4ba, 0xd4b9, 0xd4b9, 0xd4b9, 0xd4b9, 0xd4b9, 0xd4b9, + 0xd4b9, 0xd4b9, 0xd4b9, 0xd4b9, 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b8, + 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b8, 0xd4b7, + 0xd4b7, 0xd4b7, 0xd4b7, 0xd4b7, 0xd4b7, 0xd4b7, 0xd4b7, 0xd4b7, + 0xd4b7, 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b6, + 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b6, 0xd4b5, 0xd4b5, 0xd4b5, 0xd4b5, + 0xd4b5, 0xd4b5, 0xd4b5, 0xd4b5, 0xd4b5, 0xd4b5, 0xd4b4, 0xd4b4, + 0xd4b4, 0xd4b4, 0xd4b4, 0xd4b4, 0xd4b4, 0xd4b4, 0xd4b4, 0xd4b4, + 0xd4b4, 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b3, + 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b3, 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b2, + 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b2, 0xd4b1, + 0xd4b1, 0xd4b1, 0xd4b1, 0xd4b1, 0xd4b1, 0xd4b1, 0xd4b1, 0xd4b1, + 0xd4b1, 0xd4b1, 0xd4b0, 0xd4b0, 0xd4b0, 0xd4b0, 0xd4b0, 0xd4b0, + 0xd4b0, 0xd4b0, 0xd4b0, 0xd4b0, 0xd4b0, 0xd4af, 0xd4af, 0xd4af, + 0xd4af, 0xd4af, 0xd4af, 0xd4af, 0xd4af, 0xd4af, 0xd4af, 0xd4af, + 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, + 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ae, 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ad, + 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ad, 0xd4ac, + 0xd4ac, 0xd4ac, 0xd4ac, 0xd4ac, 0xd4ac, 0xd4ac, 0xd4ac, 0xd4ac, + 0xd4ac, 0xd4ac, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, + 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4ab, 0xd4aa, 0xd4aa, + 0xd4aa, 0xd4aa, 0xd4aa, 0xd4aa, 0xd4aa, 0xd4aa, 0xd4aa, 0xd4aa, + 0xd4aa, 0xd4aa, 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a9, + 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a9, 0xd4a8, 0xd4a8, 0xd4a8, + 0xd4a8, 0xd4a8, 0xd4a8, 0xd4a8, 0xd4a8, 0xd4a8, 0xd4a8, 0xd4a8, + 0xd4a8, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, + 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a7, 0xd4a6, 0xd4a6, 0xd4a6, + 0xd4a6, 0xd4a6, 0xd4a6, 0xd4a6, 0xd4a6, 0xd4a6, 0xd4a6, 0xd4a6, + 0xd4a6, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, + 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a5, 0xd4a4, 0xd4a4, 0xd4a4, + 0xd4a4, 0xd4a4, 0xd4a4, 0xd4a4, 0xd4a4, 0xd4a4, 0xd4a4, 0xd4a4, + 0xd4a4, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, + 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a3, 0xd4a2, 0xd4a2, + 0xd4a2, 0xd4a2, 0xd4a2, 0xd4a2, 0xd4a2, 0xd4a2, 0xd4a2, 0xd4a2, + 0xd4a2, 0xd4a2, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, + 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a1, 0xd4a0, + 0xd4a0, 0xd4a0, 0xd4a0, 0xd4a0, 0xd4a0, 0xd4a0, 0xd4a0, 0xd4a0, + 0xd4a0, 0xd4a0, 0xd4a0, 0xd49f, 0xd49f, 0xd49f, 0xd49f, 0xd49f, + 0xd49f, 0xd49f, 0xd49f, 0xd49f, 0xd49f, 0xd49f, 0xd49f, 0xd49f, + 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49e, + 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49e, 0xd49d, 0xd49d, 0xd49d, + 0xd49d, 0xd49d, 0xd49d, 0xd49d, 0xd49d, 0xd49d, 0xd49d, 0xd49d, + 0xd49d, 0xd49d, 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49c, + 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49c, 0xd49b, + 0xd49b, 0xd49b, 0xd49b, 0xd49b, 0xd49b, 0xd49b, 0xd49b, 0xd49b, + 0xd49b, 0xd49b, 0xd49b, 0xd49b, 0xd49a, 0xd49a, 0xd49a, 0xd49a, + 0xd49a, 0xd49a, 0xd49a, 0xd49a, 0xd49a, 0xd49a, 0xd49a, 0xd49a, + 0xd49a, 0xd499, 0xd499, 0xd499, 0xd499, 0xd499, 0xd499, 0xd499, + 0xd499, 0xd499, 0xd499, 0xd499, 0xd499, 0xd499, 0xd498, 0xd498, + 0xd498, 0xd498, 0xd498, 0xd498, 0xd498, 0xd498, 0xd498, 0xd498, + 0xd498, 0xd498, 0xd498, 0xd498, 0xd497, 0xd497, 0xd497, 0xd497, + 0xd497, 0xd497, 0xd497, 0xd497, 0xd497, 0xd497, 0xd497, 0xd497, + 0xd497, 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, + 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, 0xd496, 0xd495, + 0xd495, 0xd495, 0xd495, 0xd495, 0xd495, 0xd495, 0xd495, 0xd495, + 0xd495, 0xd495, 0xd495, 0xd495, 0xd495, 0xd494, 0xd494, 0xd494, + 0xd494, 0xd494, 0xd494, 0xd494, 0xd494, 0xd494, 0xd494, 0xd494, + 0xd494, 0xd494, 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, + 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, 0xd493, + 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, + 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, 0xd492, 0xd491, 0xd491, + 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, + 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, 0xd490, 0xd490, 0xd490, + 0xd490, 0xd490, 0xd490, 0xd490, 0xd490, 0xd490, 0xd490, 0xd490, + 0xd490, 0xd490, 0xd490, 0xd48f, 0xd48f, 0xd48f, 0xd48f, 0xd48f, + 0xd48f, 0xd48f, 0xd48f, 0xd48f, 0xd48f, 0xd48f, 0xd48f, 0xd48f, + 0xd48f, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, + 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, 0xd48e, + 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, + 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48d, 0xd48c, 0xd48c, + 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48c, + 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48c, 0xd48b, 0xd48b, 0xd48b, + 0xd48b, 0xd48b, 0xd48b, 0xd48b, 0xd48b, 0xd48b, 0xd48b, 0xd48b, + 0xd48b, 0xd48b, 0xd48b, 0xd48b, 0xd48a, 0xd48a, 0xd48a, 0xd48a, + 0xd48a, 0xd48a, 0xd48a, 0xd48a, 0xd48a, 0xd48a, 0xd48a, 0xd48a, + 0xd48a, 0xd48a, 0xd48a, 0xd489, 0xd489, 0xd489, 0xd489, 0xd489, + 0xd489, 0xd489, 0xd489, 0xd489, 0xd489, 0xd489, 0xd489, 0xd489, + 0xd489, 0xd489, 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, + 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, 0xd488, + 0xd488, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, + 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, 0xd487, + 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, + 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, 0xd486, + 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, + 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd485, 0xd484, + 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, + 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd484, 0xd483, + 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, + 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd483, 0xd482, + 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, + 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd482, 0xd481, + 0xd481, 0xd481, 0xd481, 0xd481, 0xd481, 0xd481, 0xd481, 0xd481, + 0xd480, 0xd480, 0xd480, 0xd480, 0xd480, 0xd480, 0xd480, 0xd480, + 0xd47f, 0xd47f, 0xd47f, 0xd47f, 0xd47f, 0xd47f, 0xd47f, 0xd47f, + 0xd47e, 0xd47e, 0xd47e, 0xd47e, 0xd47e, 0xd47e, 0xd47e, 0xd47e, + 0xd47d, 0xd47d, 0xd47d, 0xd47d, 0xd47d, 0xd47d, 0xd47d, 0xd47d, + 0xd47c, 0xd47c, 0xd47c, 0xd47c, 0xd47c, 0xd47c, 0xd47c, 0xd47c, + 0xd47c, 0xd47b, 0xd47b, 0xd47b, 0xd47b, 0xd47b, 0xd47b, 0xd47b, + 0xd47b, 0xd47a, 0xd47a, 0xd47a, 0xd47a, 0xd47a, 0xd47a, 0xd47a, + 0xd47a, 0xd47a, 0xd479, 0xd479, 0xd479, 0xd479, 0xd479, 0xd479, + 0xd479, 0xd479, 0xd478, 0xd478, 0xd478, 0xd478, 0xd478, 0xd478, + 0xd478, 0xd478, 0xd478, 0xd477, 0xd477, 0xd477, 0xd477, 0xd477, + 0xd477, 0xd477, 0xd477, 0xd476, 0xd476, 0xd476, 0xd476, 0xd476, + 0xd476, 0xd476, 0xd476, 0xd476, 0xd475, 0xd475, 0xd475, 0xd475, + 0xd475, 0xd475, 0xd475, 0xd475, 0xd475, 0xd474, 0xd474, 0xd474, + 0xd474, 0xd474, 0xd474, 0xd474, 0xd474, 0xd474, 0xd473, 0xd473, + 0xd473, 0xd473, 0xd473, 0xd473, 0xd473, 0xd473, 0xd473, 0xd472, + 0xd472, 0xd472, 0xd472, 0xd472, 0xd472, 0xd472, 0xd472, 0xd472, + 0xd471, 0xd471, 0xd471, 0xd471, 0xd471, 0xd471, 0xd471, 0xd471, + 0xd471, 0xd470, 0xd470, 0xd470, 0xd470, 0xd470, 0xd470, 0xd470, + 0xd470, 0xd470, 0xd46f, 0xd46f, 0xd46f, 0xd46f, 0xd46f, 0xd46f, + 0xd46f, 0xd46f, 0xd46f, 0xd46e, 0xd46e, 0xd46e, 0xd46e, 0xd46e, + 0xd46e, 0xd46e, 0xd46e, 0xd46e, 0xd46e, 0xd46d, 0xd46d, 0xd46d, + 0xd46d, 0xd46d, 0xd46d, 0xd46d, 0xd46d, 0xd46d, 0xd46c, 0xd46c, + 0xd46c, 0xd46c, 0xd46c, 0xd46c, 0xd46c, 0xd46c, 0xd46c, 0xd46c, + 0xd46b, 0xd46b, 0xd46b, 0xd46b, 0xd46b, 0xd46b, 0xd46b, 0xd46b, + 0xd46b, 0xd46a, 0xd46a, 0xd46a, 0xd46a, 0xd46a, 0xd46a, 0xd46a, + 0xd46a, 0xd46a, 0xd46a, 0xd469, 0xd469, 0xd469, 0xd469, 0xd469, + 0xd469, 0xd469, 0xd469, 0xd469, 0xd468, 0xd468, 0xd468, 0xd468, + 0xd468, 0xd468, 0xd468, 0xd468, 0xd468, 0xd468, 0xd467, 0xd467, + 0xd467, 0xd467, 0xd467, 0xd467, 0xd467, 0xd467, 0xd467, 0xd467, + 0xd466, 0xd466, 0xd466, 0xd466, 0xd466, 0xd466, 0xd466, 0xd466, + 0xd466, 0xd466, 0xd465, 0xd465, 0xd465, 0xd465, 0xd465, 0xd465, + 0xd465, 0xd465, 0xd465, 0xd465, 0xd464, 0xd464, 0xd464, 0xd464, + 0xd464, 0xd464, 0xd464, 0xd464, 0xd464, 0xd464, 0xd463, 0xd463, + 0xd463, 0xd463, 0xd463, 0xd463, 0xd463, 0xd463, 0xd463, 0xd463, + 0xd462, 0xd462, 0xd462, 0xd462, 0xd462, 0xd462, 0xd462, 0xd462, + 0xd462, 0xd462, 0xd461, 0xd461, 0xd461, 0xd461, 0xd461, 0xd461, + 0xd461, 0xd461, 0xd461, 0xd461, 0xd461, 0xd460, 0xd460, 0xd460, + 0xd460, 0xd460, 0xd460, 0xd460, 0xd460, 0xd460, 0xd460, 0xd45f, + 0xd45f, 0xd45f, 0xd45f, 0xd45f, 0xd45f, 0xd45f, 0xd45f, 0xd45f, + 0xd45f, 0xd45e, 0xd45e, 0xd45e, 0xd45e, 0xd45e, 0xd45e, 0xd45e, + 0xd45e, 0xd45e, 0xd45e, 0xd45e, 0xd45d, 0xd45d, 0xd45d, 0xd45d, + 0xd45d, 0xd45d, 0xd45d, 0xd45d, 0xd45d, 0xd45d, 0xd45d, 0xd45c, + 0xd45c, 0xd45c, 0xd45c, 0xd45c, 0xd45c, 0xd45c, 0xd45c, 0xd45c, + 0xd45c, 0xd45b, 0xd45b, 0xd45b, 0xd45b, 0xd45b, 0xd45b, 0xd45b, + 0xd45b, 0xd45b, 0xd45b, 0xd45b, 0xd45a, 0xd45a, 0xd45a, 0xd45a, + 0xd45a, 0xd45a, 0xd45a, 0xd45a, 0xd45a, 0xd45a, 0xd45a, 0xd459, + 0xd459, 0xd459, 0xd459, 0xd459, 0xd459, 0xd459, 0xd459, 0xd459, + 0xd459, 0xd459, 0xd458, 0xd458, 0xd458, 0xd458, 0xd458, 0xd458, + 0xd458, 0xd458, 0xd458, 0xd458, 0xd458, 0xd457, 0xd457, 0xd457, + 0xd457, 0xd457, 0xd457, 0xd457, 0xd457, 0xd457, 0xd457, 0xd457, + 0xd456, 0xd456, 0xd456, 0xd456, 0xd456, 0xd456, 0xd456, 0xd456, + 0xd456, 0xd456, 0xd456, 0xd455, 0xd455, 0xd455, 0xd455, 0xd455, + 0xd455, 0xd455, 0xd455, 0xd455, 0xd455, 0xd455, 0xd455, 0xd454, + 0xd454, 0xd454, 0xd454, 0xd454, 0xd454, 0xd454, 0xd454, 0xd454, + 0xd454, 0xd454, 0xd453, 0xd453, 0xd453, 0xd453, 0xd453, 0xd453, + 0xd453, 0xd453, 0xd453, 0xd453, 0xd453, 0xd453, 0xd452, 0xd452, + 0xd452, 0xd452, 0xd452, 0xd452, 0xd452, 0xd452, 0xd452, 0xd452, + 0xd452, 0xd451, 0xd451, 0xd451, 0xd451, 0xd451, 0xd451, 0xd451, + 0xd451, 0xd451, 0xd451, 0xd451, 0xd451, 0xd450, 0xd450, 0xd450, + 0xd450, 0xd450, 0xd450, 0xd450, 0xd450, 0xd450, 0xd450, 0xd450, + 0xd450, 0xd44f, 0xd44f, 0xd44f, 0xd44f, 0xd44f, 0xd44f, 0xd44f, + 0xd44f, 0xd44f, 0xd44f, 0xd44f, 0xd44f, 0xd44e, 0xd44e, 0xd44e, + 0xd44e, 0xd44e, 0xd44e, 0xd44e, 0xd44e, 0xd44e, 0xd44e, 0xd44e, + 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44d, + 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44d, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44b, 0xd44b, 0xd44b, 0xd44b, 0xd44b, 0xd44b, 0xd44b, + 0xd44b, 0xd44b, 0xd44b, 0xd44b, 0xd44b, 0xd44a, 0xd44a, 0xd44a, + 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, + 0xd44a, 0xd449, 0xd449, 0xd449, 0xd449, 0xd449, 0xd449, 0xd449, + 0xd449, 0xd449, 0xd449, 0xd449, 0xd449, 0xd449, 0xd448, 0xd448, + 0xd448, 0xd448, 0xd448, 0xd448, 0xd448, 0xd448, 0xd448, 0xd448, + 0xd448, 0xd448, 0xd447, 0xd447, 0xd447, 0xd447, 0xd447, 0xd447, + 0xd447, 0xd447, 0xd447, 0xd447, 0xd447, 0xd447, 0xd447, 0xd446, + 0xd446, 0xd446, 0xd446, 0xd446, 0xd446, 0xd446, 0xd446, 0xd446, + 0xd446, 0xd446, 0xd446, 0xd446, 0xd445, 0xd445, 0xd445, 0xd445, + 0xd445, 0xd445, 0xd445, 0xd445, 0xd445, 0xd445, 0xd445, 0xd445, + 0xd444, 0xd444, 0xd444, 0xd444, 0xd444, 0xd444, 0xd444, 0xd444, + 0xd444, 0xd444, 0xd444, 0xd444, 0xd444, 0xd443, 0xd443, 0xd443, + 0xd443, 0xd443, 0xd443, 0xd443, 0xd443, 0xd443, 0xd443, 0xd443, + 0xd443, 0xd443, 0xd442, 0xd442, 0xd442, 0xd442, 0xd442, 0xd442, + 0xd442, 0xd442, 0xd442, 0xd442, 0xd442, 0xd442, 0xd442, 0xd441, + 0xd441, 0xd441, 0xd441, 0xd441, 0xd441, 0xd441, 0xd441, 0xd441, + 0xd441, 0xd441, 0xd441, 0xd441, 0xd441, 0xd440, 0xd440, 0xd440, + 0xd440, 0xd440, 0xd440, 0xd440, 0xd440, 0xd440, 0xd440, 0xd440, + 0xd440, 0xd440, 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43f, + 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43f, 0xd43e, + 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43e, + 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43e, 0xd43d, 0xd43d, 0xd43d, + 0xd43d, 0xd43d, 0xd43d, 0xd43d, 0xd43d, 0xd43d, 0xd43d, 0xd43d, + 0xd43d, 0xd43d, 0xd43d, 0xd43c, 0xd43c, 0xd43c, 0xd43c, 0xd43c, + 0xd43c, 0xd43c, 0xd43c, 0xd43c, 0xd43c, 0xd43c, 0xd43c, 0xd43c, + 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, + 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43b, 0xd43a, 0xd43a, + 0xd43a, 0xd43a, 0xd43a, 0xd43a, 0xd43a, 0xd43a, 0xd43a, 0xd43a, + 0xd43a, 0xd43a, 0xd43a, 0xd43a, 0xd439, 0xd439, 0xd439, 0xd439, + 0xd439, 0xd439, 0xd439, 0xd439, 0xd439, 0xd439, 0xd439, 0xd439, + 0xd439, 0xd439, 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, + 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, 0xd438, + 0xd438, 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, + 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, 0xd437, 0xd436, + 0xd436, 0xd436, 0xd436, 0xd436, 0xd436, 0xd436, 0xd436, 0xd436, + 0xd436, 0xd436, 0xd436, 0xd436, 0xd436, 0xd435, 0xd435, 0xd435, + 0xd435, 0xd435, 0xd435, 0xd435, 0xd435, 0xd435, 0xd435, 0xd435, + 0xd435, 0xd435, 0xd435, 0xd435, 0xd434, 0xd434, 0xd434, 0xd434, + 0xd434, 0xd434, 0xd434, 0xd434, 0xd434, 0xd434, 0xd434, 0xd434, + 0xd434, 0xd434, 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, + 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, 0xd433, + 0xd433, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, + 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, 0xd432, + 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, + 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd431, 0xd430, + 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, + 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, 0xd430, 0xd42f, 0xd42f, + 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42f, + 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42f, 0xd42e, 0xd42e, 0xd42e, + 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42e, + 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42e, 0xd42d, 0xd42d, 0xd42d, + 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, + 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42c, 0xd42c, 0xd42c, 0xd42c, + 0xd42c, 0xd42c, 0xd42c, 0xd42c, 0xd42c, 0xd42c, 0xd42c, 0xd42c, + 0xd42c, 0xd42c, 0xd42c, 0xd42c, 0xd42b, 0xd42b, 0xd42b, 0xd42b, + 0xd42b, 0xd42b, 0xd42b, 0xd42b, 0xd42b, 0xd42b, 0xd42b, 0xd42b, + 0xd42b, 0xd42b, 0xd42b, 0xd42a, 0xd42a, 0xd42a, 0xd42a, 0xd42a, + 0xd42a, 0xd42a, 0xd42a, 0xd42a, 0xd42a, 0xd42a, 0xd42a, 0xd42a, + 0xd42a, 0xd42a, 0xd42a, 0xd429, 0xd429, 0xd429, 0xd429, 0xd429, + 0xd429, 0xd429, 0xd429, 0xd429, 0xd429, 0xd429, 0xd429, 0xd429, + 0xd429, 0xd429, 0xd428, 0xd428, 0xd428, 0xd428, 0xd428, 0xd428, + 0xd428, 0xd428, 0xd427, 0xd427, 0xd427, 0xd427, 0xd427, 0xd427, + 0xd427, 0xd427, 0xd426, 0xd426, 0xd426, 0xd426, 0xd426, 0xd426, + 0xd426, 0xd426, 0xd425, 0xd425, 0xd425, 0xd425, 0xd425, 0xd425, + 0xd425, 0xd425, 0xd424, 0xd424, 0xd424, 0xd424, 0xd424, 0xd424, + 0xd424, 0xd424, 0xd424, 0xd423, 0xd423, 0xd423, 0xd423, 0xd423, + 0xd423, 0xd423, 0xd423, 0xd422, 0xd422, 0xd422, 0xd422, 0xd422, + 0xd422, 0xd422, 0xd422, 0xd422, 0xd421, 0xd421, 0xd421, 0xd421, + 0xd421, 0xd421, 0xd421, 0xd421, 0xd420, 0xd420, 0xd420, 0xd420, + 0xd420, 0xd420, 0xd420, 0xd420, 0xd420, 0xd41f, 0xd41f, 0xd41f, + 0xd41f, 0xd41f, 0xd41f, 0xd41f, 0xd41f, 0xd41e, 0xd41e, 0xd41e, + 0xd41e, 0xd41e, 0xd41e, 0xd41e, 0xd41e, 0xd41e, 0xd41d, 0xd41d, + 0xd41d, 0xd41d, 0xd41d, 0xd41d, 0xd41d, 0xd41d, 0xd41d, 0xd41c, + 0xd41c, 0xd41c, 0xd41c, 0xd41c, 0xd41c, 0xd41c, 0xd41c, 0xd41c, + 0xd41b, 0xd41b, 0xd41b, 0xd41b, 0xd41b, 0xd41b, 0xd41b, 0xd41b, + 0xd41a, 0xd41a, 0xd41a, 0xd41a, 0xd41a, 0xd41a, 0xd41a, 0xd41a, + 0xd41a, 0xd419, 0xd419, 0xd419, 0xd419, 0xd419, 0xd419, 0xd419, + 0xd419, 0xd419, 0xd418, 0xd418, 0xd418, 0xd418, 0xd418, 0xd418, + 0xd418, 0xd418, 0xd418, 0xd418, 0xd417, 0xd417, 0xd417, 0xd417, + 0xd417, 0xd417, 0xd417, 0xd417, 0xd417, 0xd416, 0xd416, 0xd416, + 0xd416, 0xd416, 0xd416, 0xd416, 0xd416, 0xd416, 0xd415, 0xd415, + 0xd415, 0xd415, 0xd415, 0xd415, 0xd415, 0xd415, 0xd415, 0xd414, + 0xd414, 0xd414, 0xd414, 0xd414, 0xd414, 0xd414, 0xd414, 0xd414, + 0xd414, 0xd413, 0xd413, 0xd413, 0xd413, 0xd413, 0xd413, 0xd413, + 0xd413, 0xd413, 0xd412, 0xd412, 0xd412, 0xd412, 0xd412, 0xd412, + 0xd412, 0xd412, 0xd412, 0xd412, 0xd411, 0xd411, 0xd411, 0xd411, + 0xd411, 0xd411, 0xd411, 0xd411, 0xd411, 0xd410, 0xd410, 0xd410, + 0xd410, 0xd410, 0xd410, 0xd410, 0xd410, 0xd410, 0xd410, 0xd40f, + 0xd40f, 0xd40f, 0xd40f, 0xd40f, 0xd40f, 0xd40f, 0xd40f, 0xd40f, + 0xd40f, 0xd40e, 0xd40e, 0xd40e, 0xd40e, 0xd40e, 0xd40e, 0xd40e, + 0xd40e, 0xd40e, 0xd40e, 0xd40d, 0xd40d, 0xd40d, 0xd40d, 0xd40d, + 0xd40d, 0xd40d, 0xd40d, 0xd40d, 0xd40d, 0xd40c, 0xd40c, 0xd40c, + 0xd40c, 0xd40c, 0xd40c, 0xd40c, 0xd40c, 0xd40c, 0xd40c, 0xd40b, + 0xd40b, 0xd40b, 0xd40b, 0xd40b, 0xd40b, 0xd40b, 0xd40b, 0xd40b, + 0xd40b, 0xd40a, 0xd40a, 0xd40a, 0xd40a, 0xd40a, 0xd40a, 0xd40a, + 0xd40a, 0xd40a, 0xd40a, 0xd409, 0xd409, 0xd409, 0xd409, 0xd409, + 0xd409, 0xd409, 0xd409, 0xd409, 0xd409, 0xd408, 0xd408, 0xd408, + 0xd408, 0xd408, 0xd408, 0xd408, 0xd408, 0xd408, 0xd408, 0xd407, + 0xd407, 0xd407, 0xd407, 0xd407, 0xd407, 0xd407, 0xd407, 0xd407, + 0xd407, 0xd407, 0xd406, 0xd406, 0xd406, 0xd406, 0xd406, 0xd406, + 0xd406, 0xd406, 0xd406, 0xd406, 0xd405, 0xd405, 0xd405, 0xd405, + 0xd405, 0xd405, 0xd405, 0xd405, 0xd405, 0xd405, 0xd405, 0xd404, + 0xd404, 0xd404, 0xd404, 0xd404, 0xd404, 0xd404, 0xd404, 0xd404, + 0xd404, 0xd404, 0xd403, 0xd403, 0xd403, 0xd403, 0xd403, 0xd403, + 0xd403, 0xd403, 0xd403, 0xd403, 0xd402, 0xd402, 0xd402, 0xd402, + 0xd402, 0xd402, 0xd402, 0xd402, 0xd402, 0xd402, 0xd402, 0xd401, + 0xd401, 0xd401, 0xd401, 0xd401, 0xd401, 0xd401, 0xd401, 0xd401, + 0xd401, 0xd401, 0xd400, 0xd400, 0xd400, 0xd400, 0xd400, 0xd400, + 0xd400, 0xd400, 0xd3ff, 0xd3ff, 0xd3ff, 0xd3ff, 0xd3ff, 0xd3ff, + 0xd3fe, 0xd3fe, 0xd3fe, 0xd3fe, 0xd3fe, 0xd3fd, 0xd3fd, 0xd3fd, + 0xd3fd, 0xd3fd, 0xd3fd, 0xd3fc, 0xd3fc, 0xd3fc, 0xd3fc, 0xd3fc, + 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fa, 0xd3fa, + 0xd3fa, 0xd3fa, 0xd3fa, 0xd3fa, 0xd3f9, 0xd3f9, 0xd3f9, 0xd3f9, + 0xd3f9, 0xd3f8, 0xd3f8, 0xd3f8, 0xd3f8, 0xd3f8, 0xd3f8, 0xd3f7, + 0xd3f7, 0xd3f7, 0xd3f7, 0xd3f7, 0xd3f7, 0xd3f6, 0xd3f6, 0xd3f6, + 0xd3f6, 0xd3f6, 0xd3f5, 0xd3f5, 0xd3f5, 0xd3f5, 0xd3f5, 0xd3f5, + 0xd3f4, 0xd3f4, 0xd3f4, 0xd3f4, 0xd3f4, 0xd3f4, 0xd3f3, 0xd3f3, + 0xd3f3, 0xd3f3, 0xd3f3, 0xd3f3, 0xd3f2, 0xd3f2, 0xd3f2, 0xd3f2, + 0xd3f2, 0xd3f2, 0xd3f1, 0xd3f1, 0xd3f1, 0xd3f1, 0xd3f1, 0xd3f0, + 0xd3f0, 0xd3f0, 0xd3f0, 0xd3f0, 0xd3f0, 0xd3ef, 0xd3ef, 0xd3ef, + 0xd3ef, 0xd3ef, 0xd3ef, 0xd3ee, 0xd3ee, 0xd3ee, 0xd3ee, 0xd3ee, + 0xd3ee, 0xd3ed, 0xd3ed, 0xd3ed, 0xd3ed, 0xd3ed, 0xd3ed, 0xd3ec, + 0xd3ec, 0xd3ec, 0xd3ec, 0xd3ec, 0xd3ec, 0xd3eb, 0xd3eb, 0xd3eb, + 0xd3eb, 0xd3eb, 0xd3eb, 0xd3ea, 0xd3ea, 0xd3ea, 0xd3ea, 0xd3ea, + 0xd3ea, 0xd3e9, 0xd3e9, 0xd3e9, 0xd3e9, 0xd3e9, 0xd3e9, 0xd3e8, + 0xd3e8, 0xd3e8, 0xd3e8, 0xd3e8, 0xd3e8, 0xd3e7, 0xd3e7, 0xd3e7, + 0xd3e7, 0xd3e7, 0xd3e7, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, + 0xd3e6, 0xd3e5, 0xd3e5, 0xd3e5, 0xd3e5, 0xd3e5, 0xd3e5, 0xd3e4, + 0xd3e4, 0xd3e4, 0xd3e4, 0xd3e4, 0xd3e4, 0xd3e3, 0xd3e3, 0xd3e3, + 0xd3e3, 0xd3e3, 0xd3e3, 0xd3e2, 0xd3e2, 0xd3e2, 0xd3e2, 0xd3e2, + 0xd3e2, 0xd3e2, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1, + 0xd3e0, 0xd3e0, 0xd3e0, 0xd3e0, 0xd3e0, 0xd3e0, 0xd3df, 0xd3df, + 0xd3df, 0xd3df, 0xd3df, 0xd3df, 0xd3de, 0xd3de, 0xd3de, 0xd3de, + 0xd3de, 0xd3de, 0xd3de, 0xd3dd, 0xd3dd, 0xd3dd, 0xd3dd, 0xd3dd, + 0xd3dd, 0xd3dc, 0xd3dc, 0xd3dc, 0xd3dc, 0xd3dc, 0xd3dc, 0xd3db, + 0xd3db, 0xd3db, 0xd3db, 0xd3db, 0xd3db, 0xd3db, 0xd3da, 0xd3da, + 0xd3da, 0xd3da, 0xd3da, 0xd3da, 0xd3d9, 0xd3d9, 0xd3d9, 0xd3d9, + 0xd3d9, 0xd3d9, 0xd3d8, 0xd3d8, 0xd3d8, 0xd3d8, 0xd3d8, 0xd3d8, + 0xd3d8, 0xd3d7, 0xd3d7, 0xd3d7, 0xd3d7, 0xd3d7, 0xd3d7, 0xd3d6, + 0xd3d6, 0xd3d6, 0xd3d6, 0xd3d6, 0xd3d6, 0xd3d6, 0xd3d5, 0xd3d5, + 0xd3d5, 0xd3d5, 0xd3d5, 0xd3d5, 0xd3d4, 0xd3d4, 0xd3d4, 0xd3d4, + 0xd3d4, 0xd3d4, 0xd3d4, 0xd3d3, 0xd3d3, 0xd3d3, 0xd3d3, 0xd3d3, + 0xd3d3, 0xd3d2, 0xd3d2, 0xd3d2, 0xd3d2, 0xd3d2, 0xd3d2, 0xd3d2, + 0xd3d1, 0xd3d1, 0xd3d1, 0xd3d1, 0xd3d1, 0xd3d1, 0xd3d0, 0xd3d0, + 0xd3d0, 0xd3d0, 0xd3d0, 0xd3d0, 0xd3d0, 0xd3cf, 0xd3cf, 0xd3cf, + 0xd3cf, 0xd3cf, 0xd3cf, 0xd3cf, 0xd3ce, 0xd3ce, 0xd3ce, 0xd3ce, + 0xd3ce, 0xd3ce, 0xd3cd, 0xd3cd, 0xd3cd, 0xd3cd, 0xd3cd, 0xd3cd, + 0xd3cd, 0xd3cc, 0xd3cc, 0xd3cc, 0xd3cc, 0xd3cc, 0xd3cc, 0xd3cc, + 0xd3cb, 0xd3cb, 0xd3cb, 0xd3cb, 0xd3cb, 0xd3cb, 0xd3cb, 0xd3ca, + 0xd3ca, 0xd3ca, 0xd3ca, 0xd3ca, 0xd3ca, 0xd3c9, 0xd3c9, 0xd3c9, + 0xd3c9, 0xd3c9, 0xd3c9, 0xd3c9, 0xd3c8, 0xd3c8, 0xd3c8, 0xd3c8, + 0xd3c8, 0xd3c8, 0xd3c8, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, + 0xd3c7, 0xd3c7, 0xd3c6, 0xd3c6, 0xd3c6, 0xd3c6, 0xd3c6, 0xd3c6, + 0xd3c6, 0xd3c5, 0xd3c5, 0xd3c5, 0xd3c5, 0xd3c5, 0xd3c5, 0xd3c5, + 0xd3c4, 0xd3c4, 0xd3c4, 0xd3c4, 0xd3c4, 0xd3c4, 0xd3c4, 0xd3c3, + 0xd3c3, 0xd3c3, 0xd3c3, 0xd3c3, 0xd3c3, 0xd3c3, 0xd3c2, 0xd3c2, + 0xd3c2, 0xd3c2, 0xd3c2, 0xd3c2, 0xd3c2, 0xd3c1, 0xd3c1, 0xd3c1, + 0xd3c1, 0xd3c1, 0xd3c1, 0xd3c1, 0xd3c0, 0xd3c0, 0xd3c0, 0xd3c0, + 0xd3c0, 0xd3c0, 0xd3c0, 0xd3bf, 0xd3bf, 0xd3bf, 0xd3bf, 0xd3bf, + 0xd3bf, 0xd3bf, 0xd3be, 0xd3be, 0xd3be, 0xd3be, 0xd3be, 0xd3be, + 0xd3be, 0xd3bd, 0xd3bd, 0xd3bd, 0xd3bd, 0xd3bd, 0xd3bd, 0xd3bd, + 0xd3bc, 0xd3bc, 0xd3bc, 0xd3bc, 0xd3bc, 0xd3bc, 0xd3bc, 0xd3bb, + 0xd3bb, 0xd3bb, 0xd3bb, 0xd3bb, 0xd3bb, 0xd3bb, 0xd3ba, 0xd3ba, + 0xd3ba, 0xd3ba, 0xd3ba, 0xd3ba, 0xd3ba, 0xd3ba, 0xd3b9, 0xd3b9, + 0xd3b9, 0xd3b9, 0xd3b9, 0xd3b9, 0xd3b9, 0xd3b8, 0xd3b8, 0xd3b8, + 0xd3b8, 0xd3b8, 0xd3b8, 0xd3b8, 0xd3b7, 0xd3b7, 0xd3b7, 0xd3b7, + 0xd3b7, 0xd3b7, 0xd3b7, 0xd3b6, 0xd3b6, 0xd3b6, 0xd3b6, 0xd3b6, + 0xd3b6, 0xd3b6, 0xd3b6, 0xd3b5, 0xd3b5, 0xd3b5, 0xd3b5, 0xd3b5, + 0xd3b5, 0xd3b5, 0xd3b4, 0xd3b4, 0xd3b4, 0xd3b4, 0xd3b4, 0xd3b4, + 0xd3b4, 0xd3b4, 0xd3b3, 0xd3b3, 0xd3b3, 0xd3b3, 0xd3b3, 0xd3b3, + 0xd3b3, 0xd3b2, 0xd3b2, 0xd3b2, 0xd3b2, 0xd3b2, 0xd3b2, 0xd3b2, + 0xd3b1, 0xd3b1, 0xd3b1, 0xd3b1, 0xd3b1, 0xd3b1, 0xd3b1, 0xd3b1, + 0xd3b0, 0xd3b0, 0xd3b0, 0xd3b0, 0xd3b0, 0xd3b0, 0xd3b0, 0xd3af, + 0xd3af, 0xd3af, 0xd3af, 0xd3af, 0xd3af, 0xd3af, 0xd3af, 0xd3ae, + 0xd3ae, 0xd3ae, 0xd3ae, 0xd3ae, 0xd3ae, 0xd3ae, 0xd3ae, 0xd3ad, + 0xd3ad, 0xd3ad, 0xd3ad, 0xd3ad, 0xd3ad, 0xd3ad, 0xd3ac, 0xd3ac, + 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ab, 0xd3ab, + 0xd3ab, 0xd3ab, 0xd3ab, 0xd3ab, 0xd3ab, 0xd3aa, 0xd3aa, 0xd3aa, + 0xd3aa, 0xd3aa, 0xd3aa, 0xd3aa, 0xd3aa, 0xd3a9, 0xd3a9, 0xd3a9, + 0xd3a9, 0xd3a9, 0xd3a9, 0xd3a9, 0xd3a9, 0xd3a8, 0xd3a8, 0xd3a8, + 0xd3a8, 0xd3a8, 0xd3a8, 0xd3a8, 0xd3a8, 0xd3a7, 0xd3a7, 0xd3a7, + 0xd3a7, 0xd3a7, 0xd3a7, 0xd3a7, 0xd3a6, 0xd3a6, 0xd3a6, 0xd3a6, + 0xd3a6, 0xd3a6, 0xd3a6, 0xd3a6, 0xd3a5, 0xd3a5, 0xd3a5, 0xd3a5, + 0xd3a5, 0xd3a5, 0xd3a5, 0xd3a5, 0xd3a4, 0xd3a4, 0xd3a4, 0xd3a4, + 0xd3a4, 0xd3a4, 0xd3a4, 0xd3a4, 0xd3a3, 0xd3a3, 0xd3a3, 0xd3a3, + 0xd3a3, 0xd3a3, 0xd3a3, 0xd3a3, 0xd3a2, 0xd3a2, 0xd3a2, 0xd3a2, + 0xd3a2, 0xd3a2, 0xd3a2, 0xd3a2, 0xd3a1, 0xd3a1, 0xd3a1, 0xd3a1, + 0xd3a1, 0xd3a1, 0xd3a1, 0xd3a1, 0xd3a0, 0xd3a0, 0xd3a0, 0xd3a0, + 0xd3a0, 0xd3a0, 0xd39f, 0xd39f, 0xd39f, 0xd39f, 0xd39e, 0xd39e, + 0xd39e, 0xd39e, 0xd39d, 0xd39d, 0xd39d, 0xd39d, 0xd39c, 0xd39c, + 0xd39c, 0xd39c, 0xd39b, 0xd39b, 0xd39b, 0xd39b, 0xd39a, 0xd39a, + 0xd39a, 0xd39a, 0xd399, 0xd399, 0xd399, 0xd399, 0xd399, 0xd398, + 0xd398, 0xd398, 0xd398, 0xd397, 0xd397, 0xd397, 0xd397, 0xd396, + 0xd396, 0xd396, 0xd396, 0xd395, 0xd395, 0xd395, 0xd395, 0xd394, + 0xd394, 0xd394, 0xd394, 0xd393, 0xd393, 0xd393, 0xd393, 0xd393, + 0xd392, 0xd392, 0xd392, 0xd392, 0xd391, 0xd391, 0xd391, 0xd391, + 0xd390, 0xd390, 0xd390, 0xd390, 0xd38f, 0xd38f, 0xd38f, 0xd38f, + 0xd38f, 0xd38e, 0xd38e, 0xd38e, 0xd38e, 0xd38d, 0xd38d, 0xd38d, + 0xd38d, 0xd38c, 0xd38c, 0xd38c, 0xd38c, 0xd38b, 0xd38b, 0xd38b, + 0xd38b, 0xd38b, 0xd38a, 0xd38a, 0xd38a, 0xd38a, 0xd389, 0xd389, + 0xd389, 0xd389, 0xd389, 0xd388, 0xd388, 0xd388, 0xd388, 0xd387, + 0xd387, 0xd387, 0xd387, 0xd386, 0xd386, 0xd386, 0xd386, 0xd386, + 0xd385, 0xd385, 0xd385, 0xd385, 0xd384, 0xd384, 0xd384, 0xd384, + 0xd384, 0xd383, 0xd383, 0xd383, 0xd383, 0xd382, 0xd382, 0xd382, + 0xd382, 0xd382, 0xd381, 0xd381, 0xd381, 0xd381, 0xd380, 0xd380, + 0xd380, 0xd380, 0xd380, 0xd37f, 0xd37f, 0xd37f, 0xd37f, 0xd37e, + 0xd37e, 0xd37e, 0xd37e, 0xd37e, 0xd37d, 0xd37d, 0xd37d, 0xd37d, + 0xd37c, 0xd37c, 0xd37c, 0xd37c, 0xd37c, 0xd37b, 0xd37b, 0xd37b, + 0xd37b, 0xd37b, 0xd37a, 0xd37a, 0xd37a, 0xd37a, 0xd379, 0xd379, + 0xd379, 0xd379, 0xd379, 0xd378, 0xd378, 0xd378, 0xd378, 0xd378, + 0xd377, 0xd377, 0xd377, 0xd377, 0xd376, 0xd376, 0xd376, 0xd376, + 0xd376, 0xd375, 0xd375, 0xd375, 0xd375, 0xd375, 0xd374, 0xd374, + 0xd374, 0xd374, 0xd373, 0xd373, 0xd373, 0xd373, 0xd373, 0xd372, + 0xd372, 0xd372, 0xd372, 0xd372, 0xd371, 0xd371, 0xd371, 0xd371, + 0xd371, 0xd370, 0xd370, 0xd370, 0xd370, 0xd370, 0xd36f, 0xd36f, + 0xd36f, 0xd36f, 0xd36e, 0xd36e, 0xd36e, 0xd36e, 0xd36e, 0xd36d, + 0xd36d, 0xd36d, 0xd36d, 0xd36d, 0xd36c, 0xd36c, 0xd36c, 0xd36c, + 0xd36c, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36a, 0xd36a, + 0xd36a, 0xd36a, 0xd36a, 0xd369, 0xd369, 0xd369, 0xd369, 0xd369, + 0xd368, 0xd368, 0xd368, 0xd368, 0xd368, 0xd367, 0xd367, 0xd367, + 0xd367, 0xd367, 0xd366, 0xd366, 0xd366, 0xd366, 0xd366, 0xd365, + 0xd365, 0xd365, 0xd365, 0xd365, 0xd364, 0xd364, 0xd364, 0xd364, + 0xd364, 0xd363, 0xd363, 0xd363, 0xd363, 0xd363, 0xd362, 0xd362, + 0xd362, 0xd362, 0xd362, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, + 0xd360, 0xd360, 0xd360, 0xd360, 0xd360, 0xd35f, 0xd35f, 0xd35f, + 0xd35f, 0xd35f, 0xd35f, 0xd35e, 0xd35e, 0xd35e, 0xd35e, 0xd35e, + 0xd35d, 0xd35d, 0xd35d, 0xd35d, 0xd35d, 0xd35c, 0xd35c, 0xd35c, + 0xd35c, 0xd35c, 0xd35b, 0xd35b, 0xd35b, 0xd35b, 0xd35b, 0xd35a, + 0xd35a, 0xd35a, 0xd35a, 0xd35a, 0xd35a, 0xd359, 0xd359, 0xd359, + 0xd359, 0xd359, 0xd358, 0xd358, 0xd358, 0xd358, 0xd358, 0xd357, + 0xd357, 0xd357, 0xd357, 0xd357, 0xd357, 0xd356, 0xd356, 0xd356, + 0xd356, 0xd356, 0xd355, 0xd355, 0xd355, 0xd355, 0xd355, 0xd354, + 0xd354, 0xd354, 0xd354, 0xd354, 0xd354, 0xd353, 0xd353, 0xd353, + 0xd353, 0xd353, 0xd352, 0xd352, 0xd352, 0xd352, 0xd352, 0xd351, + 0xd351, 0xd351, 0xd351, 0xd351, 0xd351, 0xd350, 0xd350, 0xd350, + 0xd350, 0xd350, 0xd34f, 0xd34f, 0xd34f, 0xd34f, 0xd34f, 0xd34f, + 0xd34e, 0xd34e, 0xd34e, 0xd34e, 0xd34e, 0xd34d, 0xd34d, 0xd34d, + 0xd34d, 0xd34d, 0xd34d, 0xd34c, 0xd34c, 0xd34c, 0xd34c, 0xd34c, + 0xd34b, 0xd34b, 0xd34b, 0xd34b, 0xd34b, 0xd34b, 0xd34a, 0xd34a, + 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd349, 0xd349, 0xd349, 0xd349, + 0xd349, 0xd348, 0xd348, 0xd348, 0xd348, 0xd348, 0xd348, 0xd347, + 0xd347, 0xd347, 0xd347, 0xd347, 0xd347, 0xd346, 0xd346, 0xd346, + 0xd346, 0xd346, 0xd345, 0xd345, 0xd345, 0xd345, 0xd345, 0xd345, + 0xd344, 0xd344, 0xd344, 0xd344, 0xd344, 0xd344, 0xd343, 0xd343, + 0xd343, 0xd343, 0xd343, 0xd342, 0xd342, 0xd342, 0xd342, 0xd342, + 0xd342, 0xd341, 0xd341, 0xd341, 0xd341, 0xd341, 0xd341, 0xd340, + 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd33f, 0xd33f, 0xd33f, + 0xd33f, 0xd33f, 0xd33f, 0xd33e, 0xd33e, 0xd33e, 0xd33e, 0xd33e, + 0xd33d, 0xd33d, 0xd33d, 0xd33d, 0xd33d, 0xd33d, 0xd33c, 0xd33c, + 0xd33c, 0xd33c, 0xd33c, 0xd33c, 0xd33b, 0xd33b, 0xd33b, 0xd33b, + 0xd33b, 0xd33b, 0xd33a, 0xd33a, 0xd33a, 0xd33a, 0xd33a, 0xd33a, + 0xd339, 0xd339, 0xd339, 0xd339, 0xd339, 0xd339, 0xd338, 0xd338, + 0xd338, 0xd338, 0xd338, 0xd338, 0xd337, 0xd337, 0xd337, 0xd337, + 0xd337, 0xd337, 0xd336, 0xd336, 0xd336, 0xd336, 0xd336, 0xd336, + 0xd335, 0xd335, 0xd335, 0xd335, 0xd335, 0xd335, 0xd334, 0xd334, + 0xd334, 0xd334, 0xd334, 0xd334, 0xd333, 0xd333, 0xd333, 0xd333, + 0xd333, 0xd333, 0xd332, 0xd332, 0xd332, 0xd332, 0xd332, 0xd332, + 0xd332, 0xd331, 0xd331, 0xd331, 0xd331, 0xd331, 0xd331, 0xd330, + 0xd330, 0xd330, 0xd330, 0xd330, 0xd330, 0xd32f, 0xd32f, 0xd32f, + 0xd32f, 0xd32f, 0xd32f, 0xd32e, 0xd32e, 0xd32e, 0xd32e, 0xd32e, + 0xd32e, 0xd32d, 0xd32d, 0xd32d, 0xd32d, 0xd32d, 0xd32d, 0xd32d, + 0xd32c, 0xd32c, 0xd32c, 0xd32c, 0xd32c, 0xd32c, 0xd32b, 0xd32b, + 0xd32b, 0xd32b, 0xd32b, 0xd32b, 0xd32a, 0xd32a, 0xd32a, 0xd32a, + 0xd32a, 0xd32a, 0xd32a, 0xd329, 0xd329, 0xd329, 0xd329, 0xd329, + 0xd329, 0xd328, 0xd328, 0xd328, 0xd328, 0xd328, 0xd328, 0xd327, + 0xd327, 0xd327, 0xd327, 0xd327, 0xd327, 0xd327, 0xd326, 0xd326, + 0xd326, 0xd326, 0xd326, 0xd326, 0xd325, 0xd325, 0xd325, 0xd325, + 0xd325, 0xd325, 0xd325, 0xd324, 0xd324, 0xd324, 0xd324, 0xd324, + 0xd324, 0xd323, 0xd323, 0xd323, 0xd323, 0xd323, 0xd323, 0xd323, + 0xd322, 0xd322, 0xd322, 0xd322, 0xd322, 0xd322, 0xd321, 0xd321, + 0xd321, 0xd321, 0xd321, 0xd321, 0xd321, 0xd320, 0xd320, 0xd320, + 0xd320, 0xd320, 0xd320, 0xd31f, 0xd31f, 0xd31f, 0xd31f, 0xd31f, + 0xd31f, 0xd31f, 0xd31e, 0xd31e, 0xd31e, 0xd31e, 0xd31e, 0xd31e, + 0xd31e, 0xd31d, 0xd31d, 0xd31d, 0xd31d, 0xd31d, 0xd31d, 0xd31c, + 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31b, 0xd31b, + 0xd31b, 0xd31b, 0xd31b, 0xd31b, 0xd31b, 0xd31a, 0xd31a, 0xd31a, + 0xd31a, 0xd31a, 0xd31a, 0xd31a, 0xd319, 0xd319, 0xd319, 0xd319, + 0xd319, 0xd319, 0xd318, 0xd318, 0xd318, 0xd318, 0xd318, 0xd318, + 0xd318, 0xd317, 0xd317, 0xd317, 0xd317, 0xd317, 0xd317, 0xd317, + 0xd316, 0xd316, 0xd316, 0xd316, 0xd316, 0xd316, 0xd316, 0xd315, + 0xd315, 0xd315, 0xd315, 0xd315, 0xd315, 0xd315, 0xd314, 0xd314, + 0xd314, 0xd314, 0xd314, 0xd314, 0xd314, 0xd313, 0xd313, 0xd313, + 0xd313, 0xd313, 0xd313, 0xd313, 0xd312, 0xd312, 0xd312, 0xd312, + 0xd312, 0xd312, 0xd311, 0xd311, 0xd311, 0xd311, 0xd311, 0xd311, + 0xd311, 0xd310, 0xd310, 0xd310, 0xd310, 0xd310, 0xd310, 0xd310, + 0xd310, 0xd30f, 0xd30f, 0xd30f, 0xd30f, 0xd30f, 0xd30f, 0xd30f, + 0xd30e, 0xd30e, 0xd30e, 0xd30e, 0xd30e, 0xd30e, 0xd30e, 0xd30d, + 0xd30d, 0xd30d, 0xd30d, 0xd30d, 0xd30d, 0xd30d, 0xd30c, 0xd30c, + 0xd30c, 0xd30c, 0xd30c, 0xd30c, 0xd30c, 0xd30b, 0xd30b, 0xd30b, + 0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30a, 0xd30a, 0xd30a, 0xd30a, + 0xd30a, 0xd30a, 0xd30a, 0xd309, 0xd309, 0xd309, 0xd309, 0xd309, + 0xd309, 0xd309, 0xd308, 0xd308, 0xd308, 0xd308, 0xd308, 0xd308, + 0xd308, 0xd308, 0xd307, 0xd307, 0xd307, 0xd307, 0xd307, 0xd307, + 0xd307, 0xd306, 0xd306, 0xd306, 0xd306, 0xd306, 0xd306, 0xd306, + 0xd305, 0xd305, 0xd305, 0xd305, 0xd305, 0xd305, 0xd305, 0xd305, + 0xd304, 0xd304, 0xd304, 0xd304, 0xd304, 0xd304, 0xd304, 0xd303, + 0xd303, 0xd303, 0xd303, 0xd303, 0xd303, 0xd303, 0xd302, 0xd302, + 0xd302, 0xd302, 0xd302, 0xd302, 0xd302, 0xd302, 0xd301, 0xd301, + 0xd301, 0xd301, 0xd301, 0xd301, 0xd301, 0xd300, 0xd300, 0xd300, + 0xd300, 0xd300, 0xd300, 0xd300, 0xd300, 0xd2ff, 0xd2ff, 0xd2ff, + 0xd2ff, 0xd2ff, 0xd2ff, 0xd2ff, 0xd2fe, 0xd2fe, 0xd2fe, 0xd2fe, + 0xd2fe, 0xd2fe, 0xd2fe, 0xd2fe, 0xd2fd, 0xd2fd, 0xd2fd, 0xd2fd, + 0xd2fd, 0xd2fd, 0xd2fd, 0xd2fc, 0xd2fc, 0xd2fc, 0xd2fc, 0xd2fc, + 0xd2fc, 0xd2fc, 0xd2fc, 0xd2fb, 0xd2fb, 0xd2fb, 0xd2fb, 0xd2fb, + 0xd2fb, 0xd2fb, 0xd2fa, 0xd2fa, 0xd2fa, 0xd2fa, 0xd2fa, 0xd2fa, + 0xd2fa, 0xd2fa, 0xd2f9, 0xd2f9, 0xd2f9, 0xd2f9, 0xd2f9, 0xd2f9, + 0xd2f9, 0xd2f9, 0xd2f8, 0xd2f8, 0xd2f8, 0xd2f8, 0xd2f8, 0xd2f8, + 0xd2f8, 0xd2f7, 0xd2f7, 0xd2f7, 0xd2f7, 0xd2f7, 0xd2f7, 0xd2f7, + 0xd2f7, 0xd2f6, 0xd2f6, 0xd2f6, 0xd2f6, 0xd2f6, 0xd2f6, 0xd2f6, + 0xd2f6, 0xd2f5, 0xd2f5, 0xd2f5, 0xd2f5, 0xd2f5, 0xd2f5, 0xd2f5, + 0xd2f5, 0xd2f4, 0xd2f4, 0xd2f4, 0xd2f4, 0xd2f4, 0xd2f4, 0xd2f4, + 0xd2f4, 0xd2f3, 0xd2f3, 0xd2f3, 0xd2f3, 0xd2f3, 0xd2f3, 0xd2f3, + 0xd2f2, 0xd2f2, 0xd2f2, 0xd2f2, 0xd2f2, 0xd2f2, 0xd2f2, 0xd2f2, + 0xd2f1, 0xd2f1, 0xd2f1, 0xd2f1, 0xd2f1, 0xd2f1, 0xd2f1, 0xd2f1, + 0xd2f0, 0xd2f0, 0xd2f0, 0xd2f0, 0xd2f0, 0xd2f0, 0xd2f0, 0xd2f0, + 0xd2ef, 0xd2ef, 0xd2ef, 0xd2ef, 0xd2ef, 0xd2ef, 0xd2ef, 0xd2ef, + 0xd2ee, 0xd2ee, 0xd2ee, 0xd2ee, 0xd2ed, 0xd2ed, 0xd2ed, 0xd2ed, + 0xd2ec, 0xd2ec, 0xd2ec, 0xd2ec, 0xd2eb, 0xd2eb, 0xd2eb, 0xd2eb, + 0xd2ea, 0xd2ea, 0xd2ea, 0xd2ea, 0xd2ea, 0xd2e9, 0xd2e9, 0xd2e9, + 0xd2e9, 0xd2e8, 0xd2e8, 0xd2e8, 0xd2e8, 0xd2e7, 0xd2e7, 0xd2e7, + 0xd2e7, 0xd2e6, 0xd2e6, 0xd2e6, 0xd2e6, 0xd2e5, 0xd2e5, 0xd2e5, + 0xd2e5, 0xd2e4, 0xd2e4, 0xd2e4, 0xd2e4, 0xd2e3, 0xd2e3, 0xd2e3, + 0xd2e3, 0xd2e2, 0xd2e2, 0xd2e2, 0xd2e2, 0xd2e2, 0xd2e1, 0xd2e1, + 0xd2e1, 0xd2e1, 0xd2e0, 0xd2e0, 0xd2e0, 0xd2e0, 0xd2df, 0xd2df, + 0xd2df, 0xd2df, 0xd2de, 0xd2de, 0xd2de, 0xd2de, 0xd2de, 0xd2dd, + 0xd2dd, 0xd2dd, 0xd2dd, 0xd2dc, 0xd2dc, 0xd2dc, 0xd2dc, 0xd2db, + 0xd2db, 0xd2db, 0xd2db, 0xd2db, 0xd2da, 0xd2da, 0xd2da, 0xd2da, + 0xd2d9, 0xd2d9, 0xd2d9, 0xd2d9, 0xd2d8, 0xd2d8, 0xd2d8, 0xd2d8, + 0xd2d8, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d6, 0xd2d6, 0xd2d6, + 0xd2d6, 0xd2d5, 0xd2d5, 0xd2d5, 0xd2d5, 0xd2d5, 0xd2d4, 0xd2d4, + 0xd2d4, 0xd2d4, 0xd2d3, 0xd2d3, 0xd2d3, 0xd2d3, 0xd2d3, 0xd2d2, + 0xd2d2, 0xd2d2, 0xd2d2, 0xd2d1, 0xd2d1, 0xd2d1, 0xd2d1, 0xd2d1, + 0xd2d0, 0xd2d0, 0xd2d0, 0xd2d0, 0xd2cf, 0xd2cf, 0xd2cf, 0xd2cf, + 0xd2cf, 0xd2ce, 0xd2ce, 0xd2ce, 0xd2ce, 0xd2cd, 0xd2cd, 0xd2cd, + 0xd2cd, 0xd2cd, 0xd2cc, 0xd2cc, 0xd2cc, 0xd2cc, 0xd2cb, 0xd2cb, + 0xd2cb, 0xd2cb, 0xd2cb, 0xd2ca, 0xd2ca, 0xd2ca, 0xd2ca, 0xd2ca, + 0xd2c9, 0xd2c9, 0xd2c9, 0xd2c9, 0xd2c8, 0xd2c8, 0xd2c8, 0xd2c8, + 0xd2c8, 0xd2c7, 0xd2c7, 0xd2c7, 0xd2c7, 0xd2c6, 0xd2c6, 0xd2c6, + 0xd2c6, 0xd2c6, 0xd2c5, 0xd2c5, 0xd2c5, 0xd2c5, 0xd2c5, 0xd2c4, + 0xd2c4, 0xd2c4, 0xd2c4, 0xd2c4, 0xd2c3, 0xd2c3, 0xd2c3, 0xd2c3, + 0xd2c2, 0xd2c2, 0xd2c2, 0xd2c2, 0xd2c2, 0xd2c1, 0xd2c1, 0xd2c1, + 0xd2c1, 0xd2c1, 0xd2c0, 0xd2c0, 0xd2c0, 0xd2c0, 0xd2c0, 0xd2bf, + 0xd2bf, 0xd2bf, 0xd2bf, 0xd2be, 0xd2be, 0xd2be, 0xd2be, 0xd2be, + 0xd2bd, 0xd2bd, 0xd2bd, 0xd2bd, 0xd2bd, 0xd2bc, 0xd2bc, 0xd2bc, + 0xd2bc, 0xd2bc, 0xd2bb, 0xd2bb, 0xd2bb, 0xd2bb, 0xd2bb, 0xd2ba, + 0xd2ba, 0xd2ba, 0xd2ba, 0xd2ba, 0xd2b9, 0xd2b9, 0xd2b9, 0xd2b9, + 0xd2b9, 0xd2b8, 0xd2b8, 0xd2b8, 0xd2b8, 0xd2b8, 0xd2b7, 0xd2b7, + 0xd2b7, 0xd2b7, 0xd2b7, 0xd2b6, 0xd2b6, 0xd2b6, 0xd2b6, 0xd2b6, + 0xd2b5, 0xd2b5, 0xd2b5, 0xd2b5, 0xd2b5, 0xd2b4, 0xd2b4, 0xd2b4, + 0xd2b4, 0xd2b4, 0xd2b3, 0xd2b3, 0xd2b3, 0xd2b3, 0xd2b3, 0xd2b2, + 0xd2b2, 0xd2b2, 0xd2b2, 0xd2b2, 0xd2b1, 0xd2b1, 0xd2b1, 0xd2b1, + 0xd2b1, 0xd2b0, 0xd2b0, 0xd2b0, 0xd2b0, 0xd2b0, 0xd2af, 0xd2af, + 0xd2af, 0xd2af, 0xd2af, 0xd2ae, 0xd2ae, 0xd2ae, 0xd2ae, 0xd2ae, + 0xd2ad, 0xd2ad, 0xd2ad, 0xd2ad, 0xd2ad, 0xd2ac, 0xd2ac, 0xd2ac, + 0xd2ac, 0xd2ac, 0xd2ac, 0xd2ab, 0xd2ab, 0xd2ab, 0xd2ab, 0xd2ab, + 0xd2aa, 0xd2aa, 0xd2aa, 0xd2aa, 0xd2aa, 0xd2a9, 0xd2a9, 0xd2a9, + 0xd2a9, 0xd2a9, 0xd2a8, 0xd2a8, 0xd2a8, 0xd2a8, 0xd2a8, 0xd2a8, + 0xd2a7, 0xd2a7, 0xd2a7, 0xd2a7, 0xd2a7, 0xd2a6, 0xd2a6, 0xd2a6, + 0xd2a6, 0xd2a6, 0xd2a5, 0xd2a5, 0xd2a5, 0xd2a5, 0xd2a5, 0xd2a4, + 0xd2a4, 0xd2a4, 0xd2a4, 0xd2a4, 0xd2a4, 0xd2a3, 0xd2a3, 0xd2a3, + 0xd2a3, 0xd2a3, 0xd2a2, 0xd2a2, 0xd2a2, 0xd2a2, 0xd2a2, 0xd2a2, + 0xd2a1, 0xd2a1, 0xd2a1, 0xd2a1, 0xd2a1, 0xd2a0, 0xd2a0, 0xd2a0, + 0xd2a0, 0xd2a0, 0xd29f, 0xd29f, 0xd29f, 0xd29f, 0xd29f, 0xd29f, + 0xd29e, 0xd29e, 0xd29e, 0xd29e, 0xd29e, 0xd29d, 0xd29d, 0xd29d, + 0xd29d, 0xd29d, 0xd29d, 0xd29c, 0xd29c, 0xd29c, 0xd29c, 0xd29c, + 0xd29b, 0xd29b, 0xd29b, 0xd29b, 0xd29b, 0xd29b, 0xd29a, 0xd29a, + 0xd29a, 0xd29a, 0xd29a, 0xd29a, 0xd299, 0xd299, 0xd299, 0xd299, + 0xd299, 0xd298, 0xd298, 0xd298, 0xd298, 0xd298, 0xd298, 0xd297, + 0xd297, 0xd297, 0xd297, 0xd297, 0xd296, 0xd296, 0xd296, 0xd296, + 0xd296, 0xd296, 0xd295, 0xd295, 0xd295, 0xd295, 0xd295, 0xd295, + 0xd294, 0xd294, 0xd294, 0xd294, 0xd294, 0xd293, 0xd293, 0xd293, + 0xd293, 0xd293, 0xd293, 0xd292, 0xd292, 0xd292, 0xd292, 0xd292, + 0xd292, 0xd291, 0xd291, 0xd291, 0xd291, 0xd291, 0xd291, 0xd290, + 0xd290, 0xd290, 0xd290, 0xd290, 0xd28f, 0xd28f, 0xd28f, 0xd28f, + 0xd28f, 0xd28f, 0xd28e, 0xd28e, 0xd28e, 0xd28e, 0xd28e, 0xd28e, + 0xd28d, 0xd28d, 0xd28d, 0xd28d, 0xd28d, 0xd28d, 0xd28c, 0xd28c, + 0xd28c, 0xd28c, 0xd28c, 0xd28c, 0xd28b, 0xd28b, 0xd28b, 0xd28b, + 0xd28b, 0xd28b, 0xd28a, 0xd28a, 0xd28a, 0xd28a, 0xd28a, 0xd28a, + 0xd289, 0xd289, 0xd289, 0xd289, 0xd289, 0xd288, 0xd288, 0xd288, + 0xd288, 0xd288, 0xd288, 0xd287, 0xd287, 0xd287, 0xd287, 0xd287, + 0xd287, 0xd286, 0xd286, 0xd286, 0xd286, 0xd286, 0xd286, 0xd285, + 0xd285, 0xd285, 0xd285, 0xd285, 0xd285, 0xd285, 0xd284, 0xd284, + 0xd284, 0xd284, 0xd284, 0xd284, 0xd283, 0xd283, 0xd283, 0xd283, + 0xd283, 0xd283, 0xd282, 0xd282, 0xd282, 0xd282, 0xd282, 0xd282, + 0xd281, 0xd281, 0xd281, 0xd281, 0xd281, 0xd281, 0xd280, 0xd280, + 0xd280, 0xd280, 0xd280, 0xd280, 0xd27f, 0xd27f, 0xd27f, 0xd27f, + 0xd27f, 0xd27f, 0xd27e, 0xd27e, 0xd27e, 0xd27e, 0xd27e, 0xd27e, + 0xd27d, 0xd27d, 0xd27d, 0xd27d, 0xd27d, 0xd27d, 0xd27d, 0xd27c, + 0xd27c, 0xd27c, 0xd27c, 0xd27c, 0xd27c, 0xd27b, 0xd27b, 0xd27b, + 0xd27b, 0xd27b, 0xd27b, 0xd27a, 0xd27a, 0xd27a, 0xd27a, 0xd27a, + 0xd27a, 0xd27a, 0xd279, 0xd279, 0xd279, 0xd279, 0xd279, 0xd279, + 0xd278, 0xd278, 0xd278, 0xd278, 0xd278, 0xd278, 0xd277, 0xd277, + 0xd277, 0xd277, 0xd277, 0xd277, 0xd277, 0xd276, 0xd276, 0xd276, + 0xd276, 0xd276, 0xd276, 0xd275, 0xd275, 0xd275, 0xd275, 0xd275, + 0xd275, 0xd274, 0xd274, 0xd274, 0xd274, 0xd274, 0xd274, 0xd274, + 0xd273, 0xd273, 0xd273, 0xd273, 0xd273, 0xd273, 0xd272, 0xd272, + 0xd272, 0xd272, 0xd272, 0xd272, 0xd272, 0xd271, 0xd271, 0xd271, + 0xd271, 0xd271, 0xd271, 0xd270, 0xd270, 0xd270, 0xd270, 0xd270, + 0xd270, 0xd270, 0xd26f, 0xd26f, 0xd26f, 0xd26f, 0xd26f, 0xd26f, + 0xd26f, 0xd26e, 0xd26e, 0xd26e, 0xd26e, 0xd26e, 0xd26e, 0xd26d, + 0xd26d, 0xd26d, 0xd26d, 0xd26d, 0xd26d, 0xd26d, 0xd26c, 0xd26c, + 0xd26c, 0xd26c, 0xd26c, 0xd26c, 0xd26b, 0xd26b, 0xd26b, 0xd26b, + 0xd26b, 0xd26b, 0xd26b, 0xd26a, 0xd26a, 0xd26a, 0xd26a, 0xd26a, + 0xd26a, 0xd26a, 0xd269, 0xd269, 0xd269, 0xd269, 0xd269, 0xd269, + 0xd269, 0xd268, 0xd268, 0xd268, 0xd268, 0xd268, 0xd268, 0xd267, + 0xd267, 0xd267, 0xd267, 0xd267, 0xd267, 0xd267, 0xd266, 0xd266, + 0xd266, 0xd266, 0xd266, 0xd266, 0xd266, 0xd265, 0xd265, 0xd265, + 0xd265, 0xd265, 0xd265, 0xd265, 0xd264, 0xd264, 0xd264, 0xd264, + 0xd264, 0xd264, 0xd264, 0xd263, 0xd263, 0xd263, 0xd263, 0xd263, + 0xd263, 0xd263, 0xd262, 0xd262, 0xd262, 0xd262, 0xd262, 0xd262, + 0xd261, 0xd261, 0xd261, 0xd261, 0xd261, 0xd261, 0xd261, 0xd260, + 0xd260, 0xd260, 0xd260, 0xd260, 0xd260, 0xd260, 0xd25f, 0xd25f, + 0xd25f, 0xd25f, 0xd25f, 0xd25f, 0xd25f, 0xd25e, 0xd25e, 0xd25e, + 0xd25e, 0xd25e, 0xd25e, 0xd25e, 0xd25d, 0xd25d, 0xd25d, 0xd25d, + 0xd25d, 0xd25d, 0xd25d, 0xd25c, 0xd25c, 0xd25c, 0xd25c, 0xd25c, + 0xd25c, 0xd25c, 0xd25c, 0xd25b, 0xd25b, 0xd25b, 0xd25b, 0xd25b, + 0xd25b, 0xd25b, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, + 0xd25a, 0xd259, 0xd259, 0xd259, 0xd259, 0xd259, 0xd259, 0xd259, + 0xd258, 0xd258, 0xd258, 0xd258, 0xd258, 0xd258, 0xd258, 0xd257, + 0xd257, 0xd257, 0xd257, 0xd257, 0xd257, 0xd257, 0xd256, 0xd256, + 0xd256, 0xd256, 0xd256, 0xd256, 0xd256, 0xd256, 0xd255, 0xd255, + 0xd255, 0xd255, 0xd255, 0xd255, 0xd255, 0xd254, 0xd254, 0xd254, + 0xd254, 0xd254, 0xd254, 0xd254, 0xd253, 0xd253, 0xd253, 0xd253, + 0xd253, 0xd253, 0xd253, 0xd253, 0xd252, 0xd252, 0xd252, 0xd252, + 0xd252, 0xd252, 0xd252, 0xd251, 0xd251, 0xd251, 0xd251, 0xd251, + 0xd251, 0xd251, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, + 0xd250, 0xd250, 0xd24f, 0xd24f, 0xd24f, 0xd24f, 0xd24f, 0xd24f, + 0xd24f, 0xd24e, 0xd24e, 0xd24e, 0xd24e, 0xd24e, 0xd24e, 0xd24e, + 0xd24e, 0xd24d, 0xd24d, 0xd24d, 0xd24d, 0xd24d, 0xd24d, 0xd24d, + 0xd24c, 0xd24c, 0xd24c, 0xd24c, 0xd24c, 0xd24c, 0xd24c, 0xd24c, + 0xd24b, 0xd24b, 0xd24b, 0xd24b, 0xd24b, 0xd24b, 0xd24b, 0xd24a, + 0xd24a, 0xd24a, 0xd24a, 0xd24a, 0xd24a, 0xd24a, 0xd24a, 0xd249, + 0xd249, 0xd249, 0xd249, 0xd249, 0xd249, 0xd249, 0xd249, 0xd248, + 0xd248, 0xd248, 0xd248, 0xd248, 0xd248, 0xd248, 0xd247, 0xd247, + 0xd247, 0xd247, 0xd247, 0xd247, 0xd247, 0xd247, 0xd246, 0xd246, + 0xd246, 0xd246, 0xd246, 0xd246, 0xd246, 0xd246, 0xd245, 0xd245, + 0xd245, 0xd245, 0xd245, 0xd245, 0xd245, 0xd244, 0xd244, 0xd244, + 0xd244, 0xd244, 0xd244, 0xd244, 0xd244, 0xd243, 0xd243, 0xd243, + 0xd243, 0xd243, 0xd243, 0xd243, 0xd243, 0xd242, 0xd242, 0xd242, + 0xd242, 0xd242, 0xd242, 0xd242, 0xd242, 0xd241, 0xd241, 0xd241, + 0xd241, 0xd241, 0xd241, 0xd241, 0xd241, 0xd240, 0xd240, 0xd240, + 0xd240, 0xd240, 0xd240, 0xd240, 0xd240, 0xd23f, 0xd23f, 0xd23f, + 0xd23f, 0xd23f, 0xd23f, 0xd23f, 0xd23f, 0xd23e, 0xd23e, 0xd23e, + 0xd23e, 0xd23e, 0xd23e, 0xd23e, 0xd23e, 0xd23d, 0xd23d, 0xd23d, + 0xd23d, 0xd23d, 0xd23d, 0xd23c, 0xd23c, 0xd23c, 0xd23c, 0xd23b, + 0xd23b, 0xd23b, 0xd23b, 0xd23a, 0xd23a, 0xd23a, 0xd23a, 0xd239, + 0xd239, 0xd239, 0xd239, 0xd238, 0xd238, 0xd238, 0xd238, 0xd237, + 0xd237, 0xd237, 0xd237, 0xd236, 0xd236, 0xd236, 0xd236, 0xd235, + 0xd235, 0xd235, 0xd235, 0xd234, 0xd234, 0xd234, 0xd234, 0xd233, + 0xd233, 0xd233, 0xd233, 0xd232, 0xd232, 0xd232, 0xd232, 0xd232, + 0xd231, 0xd231, 0xd231, 0xd231, 0xd230, 0xd230, 0xd230, 0xd230, + 0xd22f, 0xd22f, 0xd22f, 0xd22f, 0xd22e, 0xd22e, 0xd22e, 0xd22e, + 0xd22d, 0xd22d, 0xd22d, 0xd22d, 0xd22d, 0xd22c, 0xd22c, 0xd22c, + 0xd22c, 0xd22b, 0xd22b, 0xd22b, 0xd22b, 0xd22a, 0xd22a, 0xd22a, + 0xd22a, 0xd22a, 0xd229, 0xd229, 0xd229, 0xd229, 0xd228, 0xd228, + 0xd228, 0xd228, 0xd227, 0xd227, 0xd227, 0xd227, 0xd227, 0xd226, + 0xd226, 0xd226, 0xd226, 0xd225, 0xd225, 0xd225, 0xd225, 0xd224, + 0xd224, 0xd224, 0xd224, 0xd224, 0xd223, 0xd223, 0xd223, 0xd223, + 0xd222, 0xd222, 0xd222, 0xd222, 0xd222, 0xd221, 0xd221, 0xd221, + 0xd221, 0xd220, 0xd220, 0xd220, 0xd220, 0xd220, 0xd21f, 0xd21f, + 0xd21f, 0xd21f, 0xd21e, 0xd21e, 0xd21e, 0xd21e, 0xd21e, 0xd21d, + 0xd21d, 0xd21d, 0xd21d, 0xd21c, 0xd21c, 0xd21c, 0xd21c, 0xd21c, + 0xd21b, 0xd21b, 0xd21b, 0xd21b, 0xd21a, 0xd21a, 0xd21a, 0xd21a, + 0xd21a, 0xd219, 0xd219, 0xd219, 0xd219, 0xd218, 0xd218, 0xd218, + 0xd218, 0xd218, 0xd217, 0xd217, 0xd217, 0xd217, 0xd217, 0xd216, + 0xd216, 0xd216, 0xd216, 0xd215, 0xd215, 0xd215, 0xd215, 0xd215, + 0xd214, 0xd214, 0xd214, 0xd214, 0xd214, 0xd213, 0xd213, 0xd213, + 0xd213, 0xd212, 0xd212, 0xd212, 0xd212, 0xd212, 0xd211, 0xd211, + 0xd211, 0xd211, 0xd211, 0xd210, 0xd210, 0xd210, 0xd210, 0xd210, + 0xd20f, 0xd20f, 0xd20f, 0xd20f, 0xd20f, 0xd20e, 0xd20e, 0xd20e, + 0xd20e, 0xd20d, 0xd20d, 0xd20d, 0xd20d, 0xd20d, 0xd20c, 0xd20c, + 0xd20c, 0xd20c, 0xd20c, 0xd20b, 0xd20b, 0xd20b, 0xd20b, 0xd20b, + 0xd20a, 0xd20a, 0xd20a, 0xd20a, 0xd20a, 0xd209, 0xd209, 0xd209, + 0xd209, 0xd209, 0xd208, 0xd208, 0xd208, 0xd208, 0xd208, 0xd207, + 0xd207, 0xd207, 0xd207, 0xd206, 0xd206, 0xd206, 0xd206, 0xd206, + 0xd205, 0xd205, 0xd205, 0xd205, 0xd205, 0xd204, 0xd204, 0xd204, + 0xd204, 0xd204, 0xd203, 0xd203, 0xd203, 0xd203, 0xd203, 0xd202, + 0xd202, 0xd202, 0xd202, 0xd202, 0xd201, 0xd201, 0xd201, 0xd201, + 0xd201, 0xd201, 0xd200, 0xd200, 0xd200, 0xd200, 0xd200, 0xd1ff, + 0xd1ff, 0xd1ff, 0xd1ff, 0xd1ff, 0xd1fe, 0xd1fe, 0xd1fe, 0xd1fe, + 0xd1fe, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fc, 0xd1fc, + 0xd1fc, 0xd1fc, 0xd1fc, 0xd1fb, 0xd1fb, 0xd1fb, 0xd1fb, 0xd1fb, + 0xd1fa, 0xd1fa, 0xd1fa, 0xd1fa, 0xd1fa, 0xd1f9, 0xd1f9, 0xd1f9, + 0xd1f9, 0xd1f9, 0xd1f9, 0xd1f8, 0xd1f8, 0xd1f8, 0xd1f8, 0xd1f8, + 0xd1f7, 0xd1f7, 0xd1f7, 0xd1f7, 0xd1f7, 0xd1f6, 0xd1f6, 0xd1f6, + 0xd1f6, 0xd1f6, 0xd1f5, 0xd1f5, 0xd1f5, 0xd1f5, 0xd1f5, 0xd1f5, + 0xd1f4, 0xd1f4, 0xd1f4, 0xd1f4, 0xd1f4, 0xd1f3, 0xd1f3, 0xd1f3, + 0xd1f3, 0xd1f3, 0xd1f2, 0xd1f2, 0xd1f2, 0xd1f2, 0xd1f2, 0xd1f2, + 0xd1f1, 0xd1f1, 0xd1f1, 0xd1f1, 0xd1f1, 0xd1f0, 0xd1f0, 0xd1f0, + 0xd1f0, 0xd1f0, 0xd1f0, 0xd1ef, 0xd1ef, 0xd1ef, 0xd1ef, 0xd1ef, + 0xd1ee, 0xd1ee, 0xd1ee, 0xd1ee, 0xd1ee, 0xd1ed, 0xd1ed, 0xd1ed, + 0xd1ed, 0xd1ed, 0xd1ed, 0xd1ec, 0xd1ec, 0xd1ec, 0xd1ec, 0xd1ec, + 0xd1eb, 0xd1eb, 0xd1eb, 0xd1eb, 0xd1eb, 0xd1eb, 0xd1ea, 0xd1ea, + 0xd1ea, 0xd1ea, 0xd1ea, 0xd1e9, 0xd1e9, 0xd1e9, 0xd1e9, 0xd1e9, + 0xd1e9, 0xd1e8, 0xd1e8, 0xd1e8, 0xd1e8, 0xd1e8, 0xd1e8, 0xd1e7, + 0xd1e7, 0xd1e7, 0xd1e7, 0xd1e7, 0xd1e6, 0xd1e6, 0xd1e6, 0xd1e6, + 0xd1e6, 0xd1e6, 0xd1e5, 0xd1e5, 0xd1e5, 0xd1e5, 0xd1e5, 0xd1e4, + 0xd1e4, 0xd1e4, 0xd1e4, 0xd1e4, 0xd1e4, 0xd1e3, 0xd1e3, 0xd1e3, + 0xd1e3, 0xd1e3, 0xd1e3, 0xd1e2, 0xd1e2, 0xd1e2, 0xd1e2, 0xd1e2, + 0xd1e2, 0xd1e1, 0xd1e1, 0xd1e1, 0xd1e1, 0xd1e1, 0xd1e0, 0xd1e0, + 0xd1e0, 0xd1e0, 0xd1e0, 0xd1e0, 0xd1df, 0xd1df, 0xd1df, 0xd1df, + 0xd1df, 0xd1df, 0xd1de, 0xd1de, 0xd1de, 0xd1de, 0xd1de, 0xd1de, + 0xd1dd, 0xd1dd, 0xd1dd, 0xd1dd, 0xd1dd, 0xd1dc, 0xd1dc, 0xd1dc, + 0xd1dc, 0xd1dc, 0xd1dc, 0xd1db, 0xd1db, 0xd1db, 0xd1db, 0xd1db, + 0xd1db, 0xd1da, 0xd1da, 0xd1da, 0xd1da, 0xd1da, 0xd1da, 0xd1d9, + 0xd1d9, 0xd1d9, 0xd1d9, 0xd1d9, 0xd1d9, 0xd1d8, 0xd1d8, 0xd1d8, + 0xd1d8, 0xd1d8, 0xd1d8, 0xd1d7, 0xd1d7, 0xd1d7, 0xd1d7, 0xd1d7, + 0xd1d7, 0xd1d6, 0xd1d6, 0xd1d6, 0xd1d6, 0xd1d6, 0xd1d6, 0xd1d5, + 0xd1d5, 0xd1d5, 0xd1d5, 0xd1d5, 0xd1d5, 0xd1d4, 0xd1d4, 0xd1d4, + 0xd1d4, 0xd1d4, 0xd1d4, 0xd1d3, 0xd1d3, 0xd1d3, 0xd1d3, 0xd1d3, + 0xd1d3, 0xd1d2, 0xd1d2, 0xd1d2, 0xd1d2, 0xd1d2, 0xd1d2, 0xd1d1, + 0xd1d1, 0xd1d1, 0xd1d1, 0xd1d1, 0xd1d1, 0xd1d0, 0xd1d0, 0xd1d0, + 0xd1d0, 0xd1d0, 0xd1d0, 0xd1cf, 0xd1cf, 0xd1cf, 0xd1cf, 0xd1cf, + 0xd1cf, 0xd1ce, 0xd1ce, 0xd1ce, 0xd1ce, 0xd1ce, 0xd1ce, 0xd1cd, + 0xd1cd, 0xd1cd, 0xd1cd, 0xd1cd, 0xd1cd, 0xd1cd, 0xd1cc, 0xd1cc, + 0xd1cc, 0xd1cc, 0xd1cc, 0xd1cc, 0xd1cb, 0xd1cb, 0xd1cb, 0xd1cb, + 0xd1cb, 0xd1cb, 0xd1ca, 0xd1ca, 0xd1ca, 0xd1ca, 0xd1ca, 0xd1ca, + 0xd1c9, 0xd1c9, 0xd1c9, 0xd1c9, 0xd1c9, 0xd1c9, 0xd1c9, 0xd1c8, + 0xd1c8, 0xd1c8, 0xd1c8, 0xd1c8, 0xd1c8, 0xd1c7, 0xd1c7, 0xd1c7, + 0xd1c7, 0xd1c7, 0xd1c7, 0xd1c6, 0xd1c6, 0xd1c6, 0xd1c6, 0xd1c6, + 0xd1c6, 0xd1c6, 0xd1c5, 0xd1c5, 0xd1c5, 0xd1c5, 0xd1c5, 0xd1c5, + 0xd1c4, 0xd1c4, 0xd1c4, 0xd1c4, 0xd1c4, 0xd1c4, 0xd1c4, 0xd1c3, + 0xd1c3, 0xd1c3, 0xd1c3, 0xd1c3, 0xd1c3, 0xd1c2, 0xd1c2, 0xd1c2, + 0xd1c2, 0xd1c2, 0xd1c2, 0xd1c1, 0xd1c1, 0xd1c1, 0xd1c1, 0xd1c1, + 0xd1c1, 0xd1c1, 0xd1c0, 0xd1c0, 0xd1c0, 0xd1c0, 0xd1c0, 0xd1c0, + 0xd1bf, 0xd1bf, 0xd1bf, 0xd1bf, 0xd1bf, 0xd1bf, 0xd1bf, 0xd1be, + 0xd1be, 0xd1be, 0xd1be, 0xd1be, 0xd1be, 0xd1be, 0xd1bd, 0xd1bd, + 0xd1bd, 0xd1bd, 0xd1bd, 0xd1bd, 0xd1bc, 0xd1bc, 0xd1bc, 0xd1bc, + 0xd1bc, 0xd1bc, 0xd1bc, 0xd1bb, 0xd1bb, 0xd1bb, 0xd1bb, 0xd1bb, + 0xd1bb, 0xd1ba, 0xd1ba, 0xd1ba, 0xd1ba, 0xd1ba, 0xd1ba, 0xd1ba, + 0xd1b9, 0xd1b9, 0xd1b9, 0xd1b9, 0xd1b9, 0xd1b9, 0xd1b9, 0xd1b8, + 0xd1b8, 0xd1b8, 0xd1b8, 0xd1b8, 0xd1b8, 0xd1b8, 0xd1b7, 0xd1b7, + 0xd1b7, 0xd1b7, 0xd1b7, 0xd1b7, 0xd1b6, 0xd1b6, 0xd1b6, 0xd1b6, + 0xd1b6, 0xd1b6, 0xd1b6, 0xd1b5, 0xd1b5, 0xd1b5, 0xd1b5, 0xd1b5, + 0xd1b5, 0xd1b5, 0xd1b4, 0xd1b4, 0xd1b4, 0xd1b4, 0xd1b4, 0xd1b4, + 0xd1b4, 0xd1b3, 0xd1b3, 0xd1b3, 0xd1b3, 0xd1b3, 0xd1b3, 0xd1b3, + 0xd1b2, 0xd1b2, 0xd1b2, 0xd1b2, 0xd1b2, 0xd1b2, 0xd1b1, 0xd1b1, + 0xd1b1, 0xd1b1, 0xd1b1, 0xd1b1, 0xd1b1, 0xd1b0, 0xd1b0, 0xd1b0, + 0xd1b0, 0xd1b0, 0xd1b0, 0xd1b0, 0xd1af, 0xd1af, 0xd1af, 0xd1af, + 0xd1af, 0xd1af, 0xd1af, 0xd1ae, 0xd1ae, 0xd1ae, 0xd1ae, 0xd1ae, + 0xd1ae, 0xd1ae, 0xd1ad, 0xd1ad, 0xd1ad, 0xd1ad, 0xd1ad, 0xd1ad, + 0xd1ad, 0xd1ac, 0xd1ac, 0xd1ac, 0xd1ac, 0xd1ac, 0xd1ac, 0xd1ac, + 0xd1ab, 0xd1ab, 0xd1ab, 0xd1ab, 0xd1ab, 0xd1ab, 0xd1ab, 0xd1aa, + 0xd1aa, 0xd1aa, 0xd1aa, 0xd1aa, 0xd1aa, 0xd1aa, 0xd1a9, 0xd1a9, + 0xd1a9, 0xd1a9, 0xd1a9, 0xd1a9, 0xd1a9, 0xd1a9, 0xd1a8, 0xd1a8, + 0xd1a8, 0xd1a8, 0xd1a8, 0xd1a8, 0xd1a8, 0xd1a7, 0xd1a7, 0xd1a7, + 0xd1a7, 0xd1a7, 0xd1a7, 0xd1a7, 0xd1a6, 0xd1a6, 0xd1a6, 0xd1a6, + 0xd1a6, 0xd1a6, 0xd1a6, 0xd1a5, 0xd1a5, 0xd1a5, 0xd1a5, 0xd1a5, + 0xd1a5, 0xd1a5, 0xd1a4, 0xd1a4, 0xd1a4, 0xd1a4, 0xd1a4, 0xd1a4, + 0xd1a4, 0xd1a4, 0xd1a3, 0xd1a3, 0xd1a3, 0xd1a3, 0xd1a3, 0xd1a3, + 0xd1a3, 0xd1a2, 0xd1a2, 0xd1a2, 0xd1a2, 0xd1a2, 0xd1a2, 0xd1a2, + 0xd1a1, 0xd1a1, 0xd1a1, 0xd1a1, 0xd1a1, 0xd1a1, 0xd1a1, 0xd1a1, + 0xd1a0, 0xd1a0, 0xd1a0, 0xd1a0, 0xd1a0, 0xd1a0, 0xd1a0, 0xd19f, + 0xd19f, 0xd19f, 0xd19f, 0xd19f, 0xd19f, 0xd19f, 0xd19e, 0xd19e, + 0xd19e, 0xd19e, 0xd19e, 0xd19e, 0xd19e, 0xd19e, 0xd19d, 0xd19d, + 0xd19d, 0xd19d, 0xd19d, 0xd19d, 0xd19d, 0xd19c, 0xd19c, 0xd19c, + 0xd19c, 0xd19c, 0xd19c, 0xd19c, 0xd19c, 0xd19b, 0xd19b, 0xd19b, + 0xd19b, 0xd19b, 0xd19b, 0xd19b, 0xd19a, 0xd19a, 0xd19a, 0xd19a, + 0xd19a, 0xd19a, 0xd19a, 0xd19a, 0xd199, 0xd199, 0xd199, 0xd199, + 0xd199, 0xd199, 0xd199, 0xd199, 0xd198, 0xd198, 0xd198, 0xd198, + 0xd198, 0xd198, 0xd198, 0xd197, 0xd197, 0xd197, 0xd197, 0xd197, + 0xd197, 0xd197, 0xd197, 0xd196, 0xd196, 0xd196, 0xd196, 0xd196, + 0xd196, 0xd196, 0xd196, 0xd195, 0xd195, 0xd195, 0xd195, 0xd195, + 0xd195, 0xd195, 0xd194, 0xd194, 0xd194, 0xd194, 0xd194, 0xd194, + 0xd194, 0xd194, 0xd193, 0xd193, 0xd193, 0xd193, 0xd193, 0xd193, + 0xd193, 0xd193, 0xd192, 0xd192, 0xd192, 0xd192, 0xd192, 0xd192, + 0xd192, 0xd192, 0xd191, 0xd191, 0xd191, 0xd191, 0xd191, 0xd191, + 0xd191, 0xd190, 0xd190, 0xd190, 0xd190, 0xd190, 0xd190, 0xd190, + 0xd190, 0xd18f, 0xd18f, 0xd18f, 0xd18f, 0xd18f, 0xd18f, 0xd18f, + 0xd18f, 0xd18e, 0xd18e, 0xd18e, 0xd18e, 0xd18e, 0xd18e, 0xd18e, + 0xd18e, 0xd18d, 0xd18d, 0xd18d, 0xd18d, 0xd18d, 0xd18d, 0xd18d, + 0xd18d, 0xd18c, 0xd18c, 0xd18c, 0xd18c, 0xd18c, 0xd18c, 0xd18c, + 0xd18c, 0xd18b, 0xd18b, 0xd18b, 0xd18b, 0xd18a, 0xd18a, 0xd18a, + 0xd18a, 0xd189, 0xd189, 0xd189, 0xd189, 0xd188, 0xd188, 0xd188, + 0xd188, 0xd187, 0xd187, 0xd187, 0xd187, 0xd186, 0xd186, 0xd186, + 0xd186, 0xd185, 0xd185, 0xd185, 0xd185, 0xd184, 0xd184, 0xd184, + 0xd184, 0xd183, 0xd183, 0xd183, 0xd183, 0xd182, 0xd182, 0xd182, + 0xd182, 0xd182, 0xd181, 0xd181, 0xd181, 0xd181, 0xd180, 0xd180, + 0xd180, 0xd180, 0xd17f, 0xd17f, 0xd17f, 0xd17f, 0xd17e, 0xd17e, + 0xd17e, 0xd17e, 0xd17d, 0xd17d, 0xd17d, 0xd17d, 0xd17d, 0xd17c, + 0xd17c, 0xd17c, 0xd17c, 0xd17b, 0xd17b, 0xd17b, 0xd17b, 0xd17a, + 0xd17a, 0xd17a, 0xd17a, 0xd179, 0xd179, 0xd179, 0xd179, 0xd179, + 0xd178, 0xd178, 0xd178, 0xd178, 0xd177, 0xd177, 0xd177, 0xd177, + 0xd176, 0xd176, 0xd176, 0xd176, 0xd176, 0xd175, 0xd175, 0xd175, + 0xd175, 0xd174, 0xd174, 0xd174, 0xd174, 0xd173, 0xd173, 0xd173, + 0xd173, 0xd173, 0xd172, 0xd172, 0xd172, 0xd172, 0xd171, 0xd171, + 0xd171, 0xd171, 0xd171, 0xd170, 0xd170, 0xd170, 0xd170, 0xd16f, + 0xd16f, 0xd16f, 0xd16f, 0xd16f, 0xd16e, 0xd16e, 0xd16e, 0xd16e, + 0xd16d, 0xd16d, 0xd16d, 0xd16d, 0xd16d, 0xd16c, 0xd16c, 0xd16c, + 0xd16c, 0xd16b, 0xd16b, 0xd16b, 0xd16b, 0xd16b, 0xd16a, 0xd16a, + 0xd16a, 0xd16a, 0xd169, 0xd169, 0xd169, 0xd169, 0xd169, 0xd168, + 0xd168, 0xd168, 0xd168, 0xd167, 0xd167, 0xd167, 0xd167, 0xd167, + 0xd166, 0xd166, 0xd166, 0xd166, 0xd166, 0xd165, 0xd165, 0xd165, + 0xd165, 0xd164, 0xd164, 0xd164, 0xd164, 0xd164, 0xd163, 0xd163, + 0xd163, 0xd163, 0xd163, 0xd162, 0xd162, 0xd162, 0xd162, 0xd161, + 0xd161, 0xd161, 0xd161, 0xd161, 0xd160, 0xd160, 0xd160, 0xd160, + 0xd160, 0xd15f, 0xd15f, 0xd15f, 0xd15f, 0xd15f, 0xd15e, 0xd15e, + 0xd15e, 0xd15e, 0xd15d, 0xd15d, 0xd15d, 0xd15d, 0xd15d, 0xd15c, + 0xd15c, 0xd15c, 0xd15c, 0xd15c, 0xd15b, 0xd15b, 0xd15b, 0xd15b, + 0xd15b, 0xd15a, 0xd15a, 0xd15a, 0xd15a, 0xd15a, 0xd159, 0xd159, + 0xd159, 0xd159, 0xd159, 0xd158, 0xd158, 0xd158, 0xd158, 0xd157, + 0xd157, 0xd157, 0xd157, 0xd157, 0xd156, 0xd156, 0xd156, 0xd156, + 0xd156, 0xd155, 0xd155, 0xd155, 0xd155, 0xd155, 0xd154, 0xd154, + 0xd154, 0xd154, 0xd154, 0xd153, 0xd153, 0xd153, 0xd153, 0xd153, + 0xd152, 0xd152, 0xd152, 0xd152, 0xd152, 0xd151, 0xd151, 0xd151, + 0xd151, 0xd151, 0xd150, 0xd150, 0xd150, 0xd150, 0xd150, 0xd14f, + 0xd14f, 0xd14f, 0xd14f, 0xd14f, 0xd14e, 0xd14e, 0xd14e, 0xd14e, + 0xd14e, 0xd14d, 0xd14d, 0xd14d, 0xd14d, 0xd14d, 0xd14d, 0xd14c, + 0xd14c, 0xd14c, 0xd14c, 0xd14c, 0xd14b, 0xd14b, 0xd14b, 0xd14b, + 0xd14b, 0xd14a, 0xd14a, 0xd14a, 0xd14a, 0xd14a, 0xd149, 0xd149, + 0xd149, 0xd149, 0xd149, 0xd148, 0xd148, 0xd148, 0xd148, 0xd148, + 0xd147, 0xd147, 0xd147, 0xd147, 0xd147, 0xd147, 0xd146, 0xd146, + 0xd146, 0xd146, 0xd146, 0xd145, 0xd145, 0xd145, 0xd145, 0xd145, + 0xd144, 0xd144, 0xd144, 0xd144, 0xd144, 0xd143, 0xd143, 0xd143, + 0xd143, 0xd143, 0xd143, 0xd142, 0xd142, 0xd142, 0xd142, 0xd142, + 0xd141, 0xd141, 0xd141, 0xd141, 0xd141, 0xd140, 0xd140, 0xd140, + 0xd140, 0xd140, 0xd140, 0xd13f, 0xd13f, 0xd13f, 0xd13f, 0xd13f, + 0xd13e, 0xd13e, 0xd13e, 0xd13e, 0xd13e, 0xd13e, 0xd13d, 0xd13d, + 0xd13d, 0xd13d, 0xd13d, 0xd13c, 0xd13c, 0xd13c, 0xd13c, 0xd13c, + 0xd13c, 0xd13b, 0xd13b, 0xd13b, 0xd13b, 0xd13b, 0xd13a, 0xd13a, + 0xd13a, 0xd13a, 0xd13a, 0xd139, 0xd139, 0xd139, 0xd139, 0xd139, + 0xd139, 0xd138, 0xd138, 0xd138, 0xd138, 0xd138, 0xd138, 0xd137, + 0xd137, 0xd137, 0xd137, 0xd137, 0xd136, 0xd136, 0xd136, 0xd136, + 0xd136, 0xd136, 0xd135, 0xd135, 0xd135, 0xd135, 0xd135, 0xd134, + 0xd134, 0xd134, 0xd134, 0xd134, 0xd134, 0xd133, 0xd133, 0xd133, + 0xd133, 0xd133, 0xd133, 0xd132, 0xd132, 0xd132, 0xd132, 0xd132, + 0xd131, 0xd131, 0xd131, 0xd131, 0xd131, 0xd131, 0xd130, 0xd130, + 0xd130, 0xd130, 0xd130, 0xd130, 0xd12f, 0xd12f, 0xd12f, 0xd12f, + 0xd12f, 0xd12e, 0xd12e, 0xd12e, 0xd12e, 0xd12e, 0xd12e, 0xd12d, + 0xd12d, 0xd12d, 0xd12d, 0xd12d, 0xd12d, 0xd12c, 0xd12c, 0xd12c, + 0xd12c, 0xd12c, 0xd12c, 0xd12b, 0xd12b, 0xd12b, 0xd12b, 0xd12b, + 0xd12b, 0xd12a, 0xd12a, 0xd12a, 0xd12a, 0xd12a, 0xd129, 0xd129, + 0xd129, 0xd129, 0xd129, 0xd129, 0xd128, 0xd128, 0xd128, 0xd128, + 0xd128, 0xd128, 0xd127, 0xd127, 0xd127, 0xd127, 0xd127, 0xd127, + 0xd126, 0xd126, 0xd126, 0xd126, 0xd126, 0xd126, 0xd125, 0xd125, + 0xd125, 0xd125, 0xd125, 0xd125, 0xd124, 0xd124, 0xd124, 0xd124, + 0xd124, 0xd124, 0xd123, 0xd123, 0xd123, 0xd123, 0xd123, 0xd123, + 0xd122, 0xd122, 0xd122, 0xd122, 0xd122, 0xd122, 0xd121, 0xd121, + 0xd121, 0xd121, 0xd121, 0xd121, 0xd120, 0xd120, 0xd120, 0xd120, + 0xd120, 0xd120, 0xd11f, 0xd11f, 0xd11f, 0xd11f, 0xd11f, 0xd11f, + 0xd11e, 0xd11e, 0xd11e, 0xd11e, 0xd11e, 0xd11e, 0xd11e, 0xd11d, + 0xd11d, 0xd11d, 0xd11d, 0xd11d, 0xd11d, 0xd11c, 0xd11c, 0xd11c, + 0xd11c, 0xd11c, 0xd11c, 0xd11b, 0xd11b, 0xd11b, 0xd11b, 0xd11b, + 0xd11b, 0xd11a, 0xd11a, 0xd11a, 0xd11a, 0xd11a, 0xd11a, 0xd119, + 0xd119, 0xd119, 0xd119, 0xd119, 0xd119, 0xd119, 0xd118, 0xd118, + 0xd118, 0xd118, 0xd118, 0xd118, 0xd117, 0xd117, 0xd117, 0xd117, + 0xd117, 0xd117, 0xd116, 0xd116, 0xd116, 0xd116, 0xd116, 0xd116, + 0xd116, 0xd115, 0xd115, 0xd115, 0xd115, 0xd115, 0xd115, 0xd114, + 0xd114, 0xd114, 0xd114, 0xd114, 0xd114, 0xd113, 0xd113, 0xd113, + 0xd113, 0xd113, 0xd113, 0xd113, 0xd112, 0xd112, 0xd112, 0xd112, + 0xd112, 0xd112, 0xd111, 0xd111, 0xd111, 0xd111, 0xd111, 0xd111, + 0xd111, 0xd110, 0xd110, 0xd110, 0xd110, 0xd110, 0xd110, 0xd10f, + 0xd10f, 0xd10f, 0xd10f, 0xd10f, 0xd10f, 0xd10f, 0xd10e, 0xd10e, + 0xd10e, 0xd10e, 0xd10e, 0xd10e, 0xd10d, 0xd10d, 0xd10d, 0xd10d, + 0xd10d, 0xd10d, 0xd10d, 0xd10c, 0xd10c, 0xd10c, 0xd10c, 0xd10c, + 0xd10c, 0xd10b, 0xd10b, 0xd10b, 0xd10b, 0xd10b, 0xd10b, 0xd10b, + 0xd10a, 0xd10a, 0xd10a, 0xd10a, 0xd10a, 0xd10a, 0xd109, 0xd109, + 0xd109, 0xd109, 0xd109, 0xd109, 0xd109, 0xd108, 0xd108, 0xd108, + 0xd108, 0xd108, 0xd108, 0xd108, 0xd107, 0xd107, 0xd107, 0xd107, + 0xd107, 0xd107, 0xd107, 0xd106, 0xd106, 0xd106, 0xd106, 0xd106, + 0xd106, 0xd105, 0xd105, 0xd105, 0xd105, 0xd105, 0xd105, 0xd105, + 0xd104, 0xd104, 0xd104, 0xd104, 0xd104, 0xd104, 0xd104, 0xd103, + 0xd103, 0xd103, 0xd103, 0xd103, 0xd103, 0xd103, 0xd102, 0xd102, + 0xd102, 0xd102, 0xd102, 0xd102, 0xd101, 0xd101, 0xd101, 0xd101, + 0xd101, 0xd101, 0xd101, 0xd100, 0xd100, 0xd100, 0xd100, 0xd100, + 0xd100, 0xd100, 0xd0ff, 0xd0ff, 0xd0ff, 0xd0ff, 0xd0ff, 0xd0ff, + 0xd0ff, 0xd0fe, 0xd0fe, 0xd0fe, 0xd0fe, 0xd0fe, 0xd0fe, 0xd0fe, + 0xd0fd, 0xd0fd, 0xd0fd, 0xd0fd, 0xd0fd, 0xd0fd, 0xd0fd, 0xd0fc, + 0xd0fc, 0xd0fc, 0xd0fc, 0xd0fc, 0xd0fc, 0xd0fc, 0xd0fb, 0xd0fb, + 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fa, 0xd0fa, 0xd0fa, + 0xd0fa, 0xd0fa, 0xd0fa, 0xd0fa, 0xd0f9, 0xd0f9, 0xd0f9, 0xd0f9, + 0xd0f9, 0xd0f9, 0xd0f9, 0xd0f8, 0xd0f8, 0xd0f8, 0xd0f8, 0xd0f8, + 0xd0f8, 0xd0f8, 0xd0f7, 0xd0f7, 0xd0f7, 0xd0f7, 0xd0f7, 0xd0f7, + 0xd0f7, 0xd0f7, 0xd0f6, 0xd0f6, 0xd0f6, 0xd0f6, 0xd0f6, 0xd0f6, + 0xd0f6, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, + 0xd0f4, 0xd0f4, 0xd0f4, 0xd0f4, 0xd0f4, 0xd0f4, 0xd0f4, 0xd0f3, + 0xd0f3, 0xd0f3, 0xd0f3, 0xd0f3, 0xd0f3, 0xd0f3, 0xd0f2, 0xd0f2, + 0xd0f2, 0xd0f2, 0xd0f2, 0xd0f2, 0xd0f2, 0xd0f2, 0xd0f1, 0xd0f1, + 0xd0f1, 0xd0f1, 0xd0f1, 0xd0f1, 0xd0f1, 0xd0f0, 0xd0f0, 0xd0f0, + 0xd0f0, 0xd0f0, 0xd0f0, 0xd0f0, 0xd0ef, 0xd0ef, 0xd0ef, 0xd0ef, + 0xd0ef, 0xd0ef, 0xd0ef, 0xd0ef, 0xd0ee, 0xd0ee, 0xd0ee, 0xd0ee, + 0xd0ee, 0xd0ee, 0xd0ee, 0xd0ed, 0xd0ed, 0xd0ed, 0xd0ed, 0xd0ed, + 0xd0ed, 0xd0ed, 0xd0ed, 0xd0ec, 0xd0ec, 0xd0ec, 0xd0ec, 0xd0ec, + 0xd0ec, 0xd0ec, 0xd0eb, 0xd0eb, 0xd0eb, 0xd0eb, 0xd0eb, 0xd0eb, + 0xd0eb, 0xd0eb, 0xd0ea, 0xd0ea, 0xd0ea, 0xd0ea, 0xd0ea, 0xd0ea, + 0xd0ea, 0xd0e9, 0xd0e9, 0xd0e9, 0xd0e9, 0xd0e9, 0xd0e9, 0xd0e9, + 0xd0e9, 0xd0e8, 0xd0e8, 0xd0e8, 0xd0e8, 0xd0e8, 0xd0e8, 0xd0e8, + 0xd0e7, 0xd0e7, 0xd0e7, 0xd0e7, 0xd0e7, 0xd0e7, 0xd0e7, 0xd0e7, + 0xd0e6, 0xd0e6, 0xd0e6, 0xd0e6, 0xd0e6, 0xd0e6, 0xd0e6, 0xd0e5, + 0xd0e5, 0xd0e5, 0xd0e5, 0xd0e5, 0xd0e5, 0xd0e5, 0xd0e5, 0xd0e4, + 0xd0e4, 0xd0e4, 0xd0e4, 0xd0e4, 0xd0e4, 0xd0e4, 0xd0e4, 0xd0e3, + 0xd0e3, 0xd0e3, 0xd0e3, 0xd0e3, 0xd0e3, 0xd0e3, 0xd0e3, 0xd0e2, + 0xd0e2, 0xd0e2, 0xd0e2, 0xd0e2, 0xd0e2, 0xd0e2, 0xd0e1, 0xd0e1, + 0xd0e1, 0xd0e1, 0xd0e1, 0xd0e1, 0xd0e1, 0xd0e1, 0xd0e0, 0xd0e0, + 0xd0e0, 0xd0e0, 0xd0e0, 0xd0e0, 0xd0e0, 0xd0e0, 0xd0df, 0xd0df, + 0xd0df, 0xd0df, 0xd0df, 0xd0df, 0xd0df, 0xd0df, 0xd0de, 0xd0de, + 0xd0de, 0xd0de, 0xd0de, 0xd0de, 0xd0de, 0xd0de, 0xd0dd, 0xd0dd, + 0xd0dd, 0xd0dd, 0xd0dd, 0xd0dd, 0xd0dd, 0xd0dd, 0xd0dc, 0xd0dc, + 0xd0dc, 0xd0dc, 0xd0dc, 0xd0dc, 0xd0dc, 0xd0db, 0xd0db, 0xd0db, + 0xd0db, 0xd0db, 0xd0db, 0xd0db, 0xd0db, 0xd0da, 0xd0da, 0xd0da, + 0xd0da, 0xd0da, 0xd0da, 0xd0d9, 0xd0d9, 0xd0d9, 0xd0d9, 0xd0d8, + 0xd0d8, 0xd0d8, 0xd0d8, 0xd0d7, 0xd0d7, 0xd0d7, 0xd0d7, 0xd0d6, + 0xd0d6, 0xd0d6, 0xd0d6, 0xd0d5, 0xd0d5, 0xd0d5, 0xd0d5, 0xd0d4, + 0xd0d4, 0xd0d4, 0xd0d4, 0xd0d3, 0xd0d3, 0xd0d3, 0xd0d3, 0xd0d2, + 0xd0d2, 0xd0d2, 0xd0d2, 0xd0d2, 0xd0d1, 0xd0d1, 0xd0d1, 0xd0d1, + 0xd0d0, 0xd0d0, 0xd0d0, 0xd0d0, 0xd0cf, 0xd0cf, 0xd0cf, 0xd0cf, + 0xd0ce, 0xd0ce, 0xd0ce, 0xd0ce, 0xd0cd, 0xd0cd, 0xd0cd, 0xd0cd, + 0xd0cc, 0xd0cc, 0xd0cc, 0xd0cc, 0xd0cc, 0xd0cb, 0xd0cb, 0xd0cb, + 0xd0cb, 0xd0ca, 0xd0ca, 0xd0ca, 0xd0ca, 0xd0c9, 0xd0c9, 0xd0c9, + 0xd0c9, 0xd0c8, 0xd0c8, 0xd0c8, 0xd0c8, 0xd0c8, 0xd0c7, 0xd0c7, + 0xd0c7, 0xd0c7, 0xd0c6, 0xd0c6, 0xd0c6, 0xd0c6, 0xd0c5, 0xd0c5, + 0xd0c5, 0xd0c5, 0xd0c5, 0xd0c4, 0xd0c4, 0xd0c4, 0xd0c4, 0xd0c3, + 0xd0c3, 0xd0c3, 0xd0c3, 0xd0c2, 0xd0c2, 0xd0c2, 0xd0c2, 0xd0c2, + 0xd0c1, 0xd0c1, 0xd0c1, 0xd0c1, 0xd0c0, 0xd0c0, 0xd0c0, 0xd0c0, + 0xd0c0, 0xd0bf, 0xd0bf, 0xd0bf, 0xd0bf, 0xd0be, 0xd0be, 0xd0be, + 0xd0be, 0xd0be, 0xd0bd, 0xd0bd, 0xd0bd, 0xd0bd, 0xd0bc, 0xd0bc, + 0xd0bc, 0xd0bc, 0xd0bc, 0xd0bb, 0xd0bb, 0xd0bb, 0xd0bb, 0xd0ba, + 0xd0ba, 0xd0ba, 0xd0ba, 0xd0ba, 0xd0b9, 0xd0b9, 0xd0b9, 0xd0b9, + 0xd0b8, 0xd0b8, 0xd0b8, 0xd0b8, 0xd0b8, 0xd0b7, 0xd0b7, 0xd0b7, + 0xd0b7, 0xd0b6, 0xd0b6, 0xd0b6, 0xd0b6, 0xd0b6, 0xd0b5, 0xd0b5, + 0xd0b5, 0xd0b5, 0xd0b5, 0xd0b4, 0xd0b4, 0xd0b4, 0xd0b4, 0xd0b3, + 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, + 0xd0b2, 0xd0b1, 0xd0b1, 0xd0b1, 0xd0b1, 0xd0b0, 0xd0b0, 0xd0b0, + 0xd0b0, 0xd0b0, 0xd0af, 0xd0af, 0xd0af, 0xd0af, 0xd0af, 0xd0ae, + 0xd0ae, 0xd0ae, 0xd0ae, 0xd0ad, 0xd0ad, 0xd0ad, 0xd0ad, 0xd0ad, + 0xd0ac, 0xd0ac, 0xd0ac, 0xd0ac, 0xd0ac, 0xd0ab, 0xd0ab, 0xd0ab, + 0xd0ab, 0xd0ab, 0xd0aa, 0xd0aa, 0xd0aa, 0xd0aa, 0xd0aa, 0xd0a9, + 0xd0a9, 0xd0a9, 0xd0a9, 0xd0a9, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, + 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a6, 0xd0a6, 0xd0a6, + 0xd0a6, 0xd0a6, 0xd0a5, 0xd0a5, 0xd0a5, 0xd0a5, 0xd0a5, 0xd0a4, + 0xd0a4, 0xd0a4, 0xd0a4, 0xd0a4, 0xd0a3, 0xd0a3, 0xd0a3, 0xd0a3, + 0xd0a3, 0xd0a2, 0xd0a2, 0xd0a2, 0xd0a2, 0xd0a2, 0xd0a1, 0xd0a1, + 0xd0a1, 0xd0a1, 0xd0a1, 0xd0a0, 0xd0a0, 0xd0a0, 0xd0a0, 0xd0a0, + 0xd09f, 0xd09f, 0xd09f, 0xd09f, 0xd09f, 0xd09e, 0xd09e, 0xd09e, + 0xd09e, 0xd09e, 0xd09d, 0xd09d, 0xd09d, 0xd09d, 0xd09d, 0xd09c, + 0xd09c, 0xd09c, 0xd09c, 0xd09c, 0xd09b, 0xd09b, 0xd09b, 0xd09b, + 0xd09b, 0xd09a, 0xd09a, 0xd09a, 0xd09a, 0xd09a, 0xd09a, 0xd099, + 0xd099, 0xd099, 0xd099, 0xd099, 0xd098, 0xd098, 0xd098, 0xd098, + 0xd098, 0xd097, 0xd097, 0xd097, 0xd097, 0xd097, 0xd096, 0xd096, + 0xd096, 0xd096, 0xd096, 0xd095, 0xd095, 0xd095, 0xd095, 0xd095, + 0xd095, 0xd094, 0xd094, 0xd094, 0xd094, 0xd094, 0xd093, 0xd093, + 0xd093, 0xd093, 0xd093, 0xd092, 0xd092, 0xd092, 0xd092, 0xd092, + 0xd091, 0xd091, 0xd091, 0xd091, 0xd091, 0xd091, 0xd090, 0xd090, + 0xd090, 0xd090, 0xd090, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, + 0xd08e, 0xd08e, 0xd08e, 0xd08e, 0xd08e, 0xd08e, 0xd08d, 0xd08d, + 0xd08d, 0xd08d, 0xd08d, 0xd08c, 0xd08c, 0xd08c, 0xd08c, 0xd08c, + 0xd08c, 0xd08b, 0xd08b, 0xd08b, 0xd08b, 0xd08b, 0xd08a, 0xd08a, + 0xd08a, 0xd08a, 0xd08a, 0xd08a, 0xd089, 0xd089, 0xd089, 0xd089, + 0xd089, 0xd088, 0xd088, 0xd088, 0xd088, 0xd088, 0xd088, 0xd087, + 0xd087, 0xd087, 0xd087, 0xd087, 0xd086, 0xd086, 0xd086, 0xd086, + 0xd086, 0xd086, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd084, + 0xd084, 0xd084, 0xd084, 0xd084, 0xd084, 0xd083, 0xd083, 0xd083, + 0xd083, 0xd083, 0xd082, 0xd082, 0xd082, 0xd082, 0xd082, 0xd082, + 0xd081, 0xd081, 0xd081, 0xd081, 0xd081, 0xd081, 0xd080, 0xd080, + 0xd080, 0xd080, 0xd080, 0xd07f, 0xd07f, 0xd07f, 0xd07f, 0xd07f, + 0xd07f, 0xd07e, 0xd07e, 0xd07e, 0xd07e, 0xd07e, 0xd07e, 0xd07d, + 0xd07d, 0xd07d, 0xd07d, 0xd07d, 0xd07d, 0xd07c, 0xd07c, 0xd07c, + 0xd07c, 0xd07c, 0xd07b, 0xd07b, 0xd07b, 0xd07b, 0xd07b, 0xd07b, + 0xd07a, 0xd07a, 0xd07a, 0xd07a, 0xd07a, 0xd07a, 0xd079, 0xd079, + 0xd079, 0xd079, 0xd079, 0xd079, 0xd078, 0xd078, 0xd078, 0xd078, + 0xd078, 0xd078, 0xd077, 0xd077, 0xd077, 0xd077, 0xd077, 0xd077, + 0xd076, 0xd076, 0xd076, 0xd076, 0xd076, 0xd076, 0xd075, 0xd075, + 0xd075, 0xd075, 0xd075, 0xd074, 0xd074, 0xd074, 0xd074, 0xd074, + 0xd074, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd072, + 0xd072, 0xd072, 0xd072, 0xd072, 0xd072, 0xd071, 0xd071, 0xd071, + 0xd071, 0xd071, 0xd071, 0xd070, 0xd070, 0xd070, 0xd070, 0xd070, + 0xd070, 0xd070, 0xd06f, 0xd06f, 0xd06f, 0xd06f, 0xd06f, 0xd06f, + 0xd06e, 0xd06e, 0xd06e, 0xd06e, 0xd06e, 0xd06e, 0xd06d, 0xd06d, + 0xd06d, 0xd06d, 0xd06d, 0xd06d, 0xd06c, 0xd06c, 0xd06c, 0xd06c, + 0xd06c, 0xd06c, 0xd06b, 0xd06b, 0xd06b, 0xd06b, 0xd06b, 0xd06b, + 0xd06a, 0xd06a, 0xd06a, 0xd06a, 0xd06a, 0xd06a, 0xd069, 0xd069, + 0xd069, 0xd069, 0xd069, 0xd069, 0xd069, 0xd068, 0xd068, 0xd068, + 0xd068, 0xd068, 0xd068, 0xd067, 0xd067, 0xd067, 0xd067, 0xd067, + 0xd067, 0xd066, 0xd066, 0xd066, 0xd066, 0xd066, 0xd066, 0xd065, + 0xd065, 0xd065, 0xd065, 0xd065, 0xd065, 0xd065, 0xd064, 0xd064, + 0xd064, 0xd064, 0xd064, 0xd064, 0xd063, 0xd063, 0xd063, 0xd063, + 0xd063, 0xd063, 0xd062, 0xd062, 0xd062, 0xd062, 0xd062, 0xd062, + 0xd062, 0xd061, 0xd061, 0xd061, 0xd061, 0xd061, 0xd061, 0xd060, + 0xd060, 0xd060, 0xd060, 0xd060, 0xd060, 0xd060, 0xd05f, 0xd05f, + 0xd05f, 0xd05f, 0xd05f, 0xd05f, 0xd05e, 0xd05e, 0xd05e, 0xd05e, + 0xd05e, 0xd05e, 0xd05e, 0xd05d, 0xd05d, 0xd05d, 0xd05d, 0xd05d, + 0xd05d, 0xd05c, 0xd05c, 0xd05c, 0xd05c, 0xd05c, 0xd05c, 0xd05c, + 0xd05b, 0xd05b, 0xd05b, 0xd05b, 0xd05b, 0xd05b, 0xd05a, 0xd05a, + 0xd05a, 0xd05a, 0xd05a, 0xd05a, 0xd05a, 0xd059, 0xd059, 0xd059, + 0xd059, 0xd059, 0xd059, 0xd059, 0xd058, 0xd058, 0xd058, 0xd058, + 0xd058, 0xd058, 0xd057, 0xd057, 0xd057, 0xd057, 0xd057, 0xd057, + 0xd057, 0xd056, 0xd056, 0xd056, 0xd056, 0xd056, 0xd056, 0xd056, + 0xd055, 0xd055, 0xd055, 0xd055, 0xd055, 0xd055, 0xd054, 0xd054, + 0xd054, 0xd054, 0xd054, 0xd054, 0xd054, 0xd053, 0xd053, 0xd053, + 0xd053, 0xd053, 0xd053, 0xd053, 0xd052, 0xd052, 0xd052, 0xd052, + 0xd052, 0xd052, 0xd052, 0xd051, 0xd051, 0xd051, 0xd051, 0xd051, + 0xd051, 0xd050, 0xd050, 0xd050, 0xd050, 0xd050, 0xd050, 0xd050, + 0xd04f, 0xd04f, 0xd04f, 0xd04f, 0xd04f, 0xd04f, 0xd04f, 0xd04e, + 0xd04e, 0xd04e, 0xd04e, 0xd04e, 0xd04e, 0xd04e, 0xd04d, 0xd04d, + 0xd04d, 0xd04d, 0xd04d, 0xd04d, 0xd04d, 0xd04c, 0xd04c, 0xd04c, + 0xd04c, 0xd04c, 0xd04c, 0xd04c, 0xd04b, 0xd04b, 0xd04b, 0xd04b, + 0xd04b, 0xd04b, 0xd04b, 0xd04a, 0xd04a, 0xd04a, 0xd04a, 0xd04a, + 0xd04a, 0xd04a, 0xd049, 0xd049, 0xd049, 0xd049, 0xd049, 0xd049, + 0xd049, 0xd048, 0xd048, 0xd048, 0xd048, 0xd048, 0xd048, 0xd048, + 0xd047, 0xd047, 0xd047, 0xd047, 0xd047, 0xd047, 0xd047, 0xd046, + 0xd046, 0xd046, 0xd046, 0xd046, 0xd046, 0xd046, 0xd045, 0xd045, + 0xd045, 0xd045, 0xd045, 0xd045, 0xd045, 0xd045, 0xd044, 0xd044, + 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd043, 0xd043, 0xd043, + 0xd043, 0xd043, 0xd043, 0xd043, 0xd042, 0xd042, 0xd042, 0xd042, + 0xd042, 0xd042, 0xd042, 0xd041, 0xd041, 0xd041, 0xd041, 0xd041, + 0xd041, 0xd041, 0xd040, 0xd040, 0xd040, 0xd040, 0xd040, 0xd040, + 0xd040, 0xd040, 0xd03f, 0xd03f, 0xd03f, 0xd03f, 0xd03f, 0xd03f, + 0xd03f, 0xd03e, 0xd03e, 0xd03e, 0xd03e, 0xd03e, 0xd03e, 0xd03e, + 0xd03d, 0xd03d, 0xd03d, 0xd03d, 0xd03d, 0xd03d, 0xd03d, 0xd03d, + 0xd03c, 0xd03c, 0xd03c, 0xd03c, 0xd03c, 0xd03c, 0xd03c, 0xd03b, + 0xd03b, 0xd03b, 0xd03b, 0xd03b, 0xd03b, 0xd03b, 0xd03b, 0xd03a, + 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd039, 0xd039, + 0xd039, 0xd039, 0xd039, 0xd039, 0xd039, 0xd039, 0xd038, 0xd038, + 0xd038, 0xd038, 0xd038, 0xd038, 0xd038, 0xd037, 0xd037, 0xd037, + 0xd037, 0xd037, 0xd037, 0xd037, 0xd037, 0xd036, 0xd036, 0xd036, + 0xd036, 0xd036, 0xd036, 0xd036, 0xd035, 0xd035, 0xd035, 0xd035, + 0xd035, 0xd035, 0xd035, 0xd035, 0xd034, 0xd034, 0xd034, 0xd034, + 0xd034, 0xd034, 0xd034, 0xd034, 0xd033, 0xd033, 0xd033, 0xd033, + 0xd033, 0xd033, 0xd033, 0xd032, 0xd032, 0xd032, 0xd032, 0xd032, + 0xd032, 0xd032, 0xd032, 0xd031, 0xd031, 0xd031, 0xd031, 0xd031, + 0xd031, 0xd031, 0xd031, 0xd030, 0xd030, 0xd030, 0xd030, 0xd030, + 0xd030, 0xd030, 0xd030, 0xd02f, 0xd02f, 0xd02f, 0xd02f, 0xd02f, + 0xd02f, 0xd02f, 0xd02e, 0xd02e, 0xd02e, 0xd02e, 0xd02e, 0xd02e, + 0xd02e, 0xd02e, 0xd02d, 0xd02d, 0xd02d, 0xd02d, 0xd02d, 0xd02d, + 0xd02d, 0xd02d, 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xd02c, + 0xd02c, 0xd02c, 0xd02b, 0xd02b, 0xd02b, 0xd02b, 0xd02b, 0xd02b, + 0xd02b, 0xd02b, 0xd02a, 0xd02a, 0xd02a, 0xd02a, 0xd02a, 0xd02a, + 0xd02a, 0xd02a, 0xd029, 0xd029, 0xd029, 0xd029, 0xd029, 0xd029, + 0xd029, 0xd028, 0xd028, 0xd028, 0xd028, 0xd027, 0xd027, 0xd027, + 0xd027, 0xd026, 0xd026, 0xd026, 0xd026, 0xd025, 0xd025, 0xd025, + 0xd025, 0xd024, 0xd024, 0xd024, 0xd024, 0xd023, 0xd023, 0xd023, + 0xd023, 0xd022, 0xd022, 0xd022, 0xd022, 0xd022, 0xd021, 0xd021, + 0xd021, 0xd021, 0xd020, 0xd020, 0xd020, 0xd020, 0xd01f, 0xd01f, + 0xd01f, 0xd01f, 0xd01e, 0xd01e, 0xd01e, 0xd01e, 0xd01d, 0xd01d, + 0xd01d, 0xd01d, 0xd01c, 0xd01c, 0xd01c, 0xd01c, 0xd01c, 0xd01b, + 0xd01b, 0xd01b, 0xd01b, 0xd01a, 0xd01a, 0xd01a, 0xd01a, 0xd019, + 0xd019, 0xd019, 0xd019, 0xd018, 0xd018, 0xd018, 0xd018, 0xd018, + 0xd017, 0xd017, 0xd017, 0xd017, 0xd016, 0xd016, 0xd016, 0xd016, + 0xd015, 0xd015, 0xd015, 0xd015, 0xd014, 0xd014, 0xd014, 0xd014, + 0xd014, 0xd013, 0xd013, 0xd013, 0xd013, 0xd012, 0xd012, 0xd012, + 0xd012, 0xd012, 0xd011, 0xd011, 0xd011, 0xd011, 0xd010, 0xd010, + 0xd010, 0xd010, 0xd00f, 0xd00f, 0xd00f, 0xd00f, 0xd00f, 0xd00e, + 0xd00e, 0xd00e, 0xd00e, 0xd00d, 0xd00d, 0xd00d, 0xd00d, 0xd00d, + 0xd00c, 0xd00c, 0xd00c, 0xd00c, 0xd00b, 0xd00b, 0xd00b, 0xd00b, + 0xd00b, 0xd00a, 0xd00a, 0xd00a, 0xd00a, 0xd009, 0xd009, 0xd009, + 0xd009, 0xd009, 0xd008, 0xd008, 0xd008, 0xd008, 0xd007, 0xd007, + 0xd007, 0xd007, 0xd007, 0xd006, 0xd006, 0xd006, 0xd006, 0xd005, + 0xd005, 0xd005, 0xd005, 0xd005, 0xd004, 0xd004, 0xd004, 0xd004, + 0xd004, 0xd003, 0xd003, 0xd003, 0xd003, 0xd002, 0xd002, 0xd002, + 0xd002, 0xd002, 0xd001, 0xd001, 0xd001, 0xd001, 0xd000, 0xd000, + 0xd000, 0xd000, 0xcfff, 0xcfff, 0xcffe, 0xcffe, 0xcffe, 0xcffd, + 0xcffd, 0xcffc, 0xcffc, 0xcffb, 0xcffb, 0xcffb, 0xcffa, 0xcffa, + 0xcff9, 0xcff9, 0xcff9, 0xcff8, 0xcff8, 0xcff7, 0xcff7, 0xcff6, + 0xcff6, 0xcff6, 0xcff5, 0xcff5, 0xcff4, 0xcff4, 0xcff3, 0xcff3, + 0xcff3, 0xcff2, 0xcff2, 0xcff1, 0xcff1, 0xcff1, 0xcff0, 0xcff0, + 0xcfef, 0xcfef, 0xcfef, 0xcfee, 0xcfee, 0xcfed, 0xcfed, 0xcfec, + 0xcfec, 0xcfec, 0xcfeb, 0xcfeb, 0xcfea, 0xcfea, 0xcfea, 0xcfe9, + 0xcfe9, 0xcfe8, 0xcfe8, 0xcfe8, 0xcfe7, 0xcfe7, 0xcfe6, 0xcfe6, + 0xcfe6, 0xcfe5, 0xcfe5, 0xcfe4, 0xcfe4, 0xcfe4, 0xcfe3, 0xcfe3, + 0xcfe2, 0xcfe2, 0xcfe2, 0xcfe1, 0xcfe1, 0xcfe0, 0xcfe0, 0xcfdf, + 0xcfdf, 0xcfdf, 0xcfde, 0xcfde, 0xcfde, 0xcfdd, 0xcfdd, 0xcfdc, + 0xcfdc, 0xcfdc, 0xcfdb, 0xcfdb, 0xcfda, 0xcfda, 0xcfda, 0xcfd9, + 0xcfd9, 0xcfd8, 0xcfd8, 0xcfd8, 0xcfd7, 0xcfd7, 0xcfd6, 0xcfd6, + 0xcfd6, 0xcfd5, 0xcfd5, 0xcfd4, 0xcfd4, 0xcfd4, 0xcfd3, 0xcfd3, + 0xcfd2, 0xcfd2, 0xcfd2, 0xcfd1, 0xcfd1, 0xcfd1, 0xcfd0, 0xcfd0, + 0xcfcf, 0xcfcf, 0xcfcf, 0xcfce, 0xcfce, 0xcfcd, 0xcfcd, 0xcfcd, + 0xcfcc, 0xcfcc, 0xcfcb, 0xcfcb, 0xcfcb, 0xcfca, 0xcfca, 0xcfca, + 0xcfc9, 0xcfc9, 0xcfc8, 0xcfc8, 0xcfc8, 0xcfc7, 0xcfc7, 0xcfc6, + 0xcfc6, 0xcfc6, 0xcfc5, 0xcfc5, 0xcfc5, 0xcfc4, 0xcfc4, 0xcfc3, + 0xcfc3, 0xcfc3, 0xcfc2, 0xcfc2, 0xcfc2, 0xcfc1, 0xcfc1, 0xcfc0, + 0xcfc0, 0xcfc0, 0xcfbf, 0xcfbf, 0xcfbf, 0xcfbe, 0xcfbe, 0xcfbd, + 0xcfbd, 0xcfbd, 0xcfbc, 0xcfbc, 0xcfbc, 0xcfbb, 0xcfbb, 0xcfba, + 0xcfba, 0xcfba, 0xcfb9, 0xcfb9, 0xcfb9, 0xcfb8, 0xcfb8, 0xcfb7, + 0xcfb7, 0xcfb7, 0xcfb6, 0xcfb6, 0xcfb6, 0xcfb5, 0xcfb5, 0xcfb5, + 0xcfb4, 0xcfb4, 0xcfb3, 0xcfb3, 0xcfb3, 0xcfb2, 0xcfb2, 0xcfb2, + 0xcfb1, 0xcfb1, 0xcfb0, 0xcfb0, 0xcfb0, 0xcfaf, 0xcfaf, 0xcfaf, + 0xcfae, 0xcfae, 0xcfae, 0xcfad, 0xcfad, 0xcfac, 0xcfac, 0xcfac, + 0xcfab, 0xcfab, 0xcfab, 0xcfaa, 0xcfaa, 0xcfaa, 0xcfa9, 0xcfa9, + 0xcfa9, 0xcfa8, 0xcfa8, 0xcfa7, 0xcfa7, 0xcfa7, 0xcfa6, 0xcfa6, + 0xcfa6, 0xcfa5, 0xcfa5, 0xcfa5, 0xcfa4, 0xcfa4, 0xcfa4, 0xcfa3, + 0xcfa3, 0xcfa2, 0xcfa2, 0xcfa2, 0xcfa1, 0xcfa1, 0xcfa1, 0xcfa0, + 0xcfa0, 0xcfa0, 0xcf9f, 0xcf9f, 0xcf9f, 0xcf9e, 0xcf9e, 0xcf9d, + 0xcf9d, 0xcf9d, 0xcf9c, 0xcf9c, 0xcf9c, 0xcf9b, 0xcf9b, 0xcf9b, + 0xcf9a, 0xcf9a, 0xcf9a, 0xcf99, 0xcf99, 0xcf99, 0xcf98, 0xcf98, + 0xcf98, 0xcf97, 0xcf97, 0xcf96, 0xcf96, 0xcf96, 0xcf95, 0xcf95, + 0xcf95, 0xcf94, 0xcf94, 0xcf94, 0xcf93, 0xcf93, 0xcf93, 0xcf92, + 0xcf92, 0xcf92, 0xcf91, 0xcf91, 0xcf91, 0xcf90, 0xcf90, 0xcf90, + 0xcf8f, 0xcf8f, 0xcf8f, 0xcf8e, 0xcf8e, 0xcf8e, 0xcf8d, 0xcf8d, + 0xcf8d, 0xcf8c, 0xcf8c, 0xcf8c, 0xcf8b, 0xcf8b, 0xcf8a, 0xcf8a, + 0xcf8a, 0xcf89, 0xcf89, 0xcf89, 0xcf88, 0xcf88, 0xcf88, 0xcf87, + 0xcf87, 0xcf87, 0xcf86, 0xcf86, 0xcf86, 0xcf85, 0xcf85, 0xcf85, + 0xcf84, 0xcf84, 0xcf84, 0xcf83, 0xcf83, 0xcf83, 0xcf82, 0xcf82, + 0xcf82, 0xcf81, 0xcf81, 0xcf81, 0xcf80, 0xcf80, 0xcf80, 0xcf7f, + 0xcf7f, 0xcf7f, 0xcf7e, 0xcf7e, 0xcf7e, 0xcf7d, 0xcf7d, 0xcf7d, + 0xcf7c, 0xcf7c, 0xcf7c, 0xcf7b, 0xcf7b, 0xcf7b, 0xcf7a, 0xcf7a, + 0xcf7a, 0xcf79, 0xcf79, 0xcf79, 0xcf79, 0xcf78, 0xcf78, 0xcf78, + 0xcf77, 0xcf77, 0xcf77, 0xcf76, 0xcf76, 0xcf76, 0xcf75, 0xcf75, + 0xcf75, 0xcf74, 0xcf74, 0xcf74, 0xcf73, 0xcf73, 0xcf73, 0xcf72, + 0xcf72, 0xcf72, 0xcf71, 0xcf71, 0xcf71, 0xcf70, 0xcf70, 0xcf70, + 0xcf6f, 0xcf6f, 0xcf6f, 0xcf6e, 0xcf6e, 0xcf6e, 0xcf6d, 0xcf6d, + 0xcf6d, 0xcf6d, 0xcf6c, 0xcf6c, 0xcf6c, 0xcf6b, 0xcf6b, 0xcf6b, + 0xcf6a, 0xcf6a, 0xcf6a, 0xcf69, 0xcf69, 0xcf69, 0xcf68, 0xcf68, + 0xcf68, 0xcf67, 0xcf67, 0xcf67, 0xcf66, 0xcf66, 0xcf66, 0xcf66, + 0xcf65, 0xcf65, 0xcf65, 0xcf64, 0xcf64, 0xcf64, 0xcf63, 0xcf63, + 0xcf63, 0xcf62, 0xcf62, 0xcf62, 0xcf61, 0xcf61, 0xcf61, 0xcf61, + 0xcf60, 0xcf60, 0xcf60, 0xcf5f, 0xcf5f, 0xcf5f, 0xcf5e, 0xcf5e, + 0xcf5e, 0xcf5d, 0xcf5d, 0xcf5d, 0xcf5c, 0xcf5c, 0xcf5c, 0xcf5c, + 0xcf5b, 0xcf5b, 0xcf5b, 0xcf5a, 0xcf5a, 0xcf5a, 0xcf59, 0xcf59, + 0xcf59, 0xcf58, 0xcf58, 0xcf58, 0xcf58, 0xcf57, 0xcf57, 0xcf57, + 0xcf56, 0xcf56, 0xcf56, 0xcf55, 0xcf55, 0xcf55, 0xcf54, 0xcf54, + 0xcf54, 0xcf54, 0xcf53, 0xcf53, 0xcf53, 0xcf52, 0xcf52, 0xcf52, + 0xcf51, 0xcf51, 0xcf51, 0xcf51, 0xcf50, 0xcf50, 0xcf50, 0xcf4f, + 0xcf4f, 0xcf4f, 0xcf4e, 0xcf4e, 0xcf4e, 0xcf4e, 0xcf4d, 0xcf4d, + 0xcf4d, 0xcf4c, 0xcf4c, 0xcf4c, 0xcf4b, 0xcf4b, 0xcf4b, 0xcf4b, + 0xcf4a, 0xcf4a, 0xcf4a, 0xcf49, 0xcf49, 0xcf49, 0xcf48, 0xcf48, + 0xcf48, 0xcf48, 0xcf47, 0xcf47, 0xcf47, 0xcf46, 0xcf46, 0xcf46, + 0xcf45, 0xcf45, 0xcf45, 0xcf45, 0xcf44, 0xcf44, 0xcf44, 0xcf43, + 0xcf43, 0xcf43, 0xcf42, 0xcf42, 0xcf42, 0xcf42, 0xcf41, 0xcf41, + 0xcf41, 0xcf40, 0xcf40, 0xcf40, 0xcf40, 0xcf3f, 0xcf3f, 0xcf3f, + 0xcf3e, 0xcf3e, 0xcf3e, 0xcf3e, 0xcf3d, 0xcf3d, 0xcf3d, 0xcf3c, + 0xcf3c, 0xcf3c, 0xcf3b, 0xcf3b, 0xcf3b, 0xcf3b, 0xcf3a, 0xcf3a, + 0xcf3a, 0xcf39, 0xcf39, 0xcf39, 0xcf39, 0xcf38, 0xcf38, 0xcf38, + 0xcf37, 0xcf37, 0xcf37, 0xcf37, 0xcf36, 0xcf36, 0xcf36, 0xcf35, + 0xcf35, 0xcf35, 0xcf35, 0xcf34, 0xcf34, 0xcf34, 0xcf33, 0xcf33, + 0xcf33, 0xcf33, 0xcf32, 0xcf32, 0xcf32, 0xcf31, 0xcf31, 0xcf31, + 0xcf31, 0xcf30, 0xcf30, 0xcf30, 0xcf2f, 0xcf2f, 0xcf2f, 0xcf2f, + 0xcf2e, 0xcf2e, 0xcf2e, 0xcf2d, 0xcf2d, 0xcf2d, 0xcf2d, 0xcf2c, + 0xcf2c, 0xcf2c, 0xcf2b, 0xcf2b, 0xcf2b, 0xcf2b, 0xcf2a, 0xcf2a, + 0xcf2a, 0xcf29, 0xcf29, 0xcf29, 0xcf29, 0xcf28, 0xcf28, 0xcf28, + 0xcf28, 0xcf27, 0xcf27, 0xcf27, 0xcf26, 0xcf26, 0xcf26, 0xcf26, + 0xcf25, 0xcf25, 0xcf25, 0xcf24, 0xcf24, 0xcf24, 0xcf24, 0xcf23, + 0xcf23, 0xcf23, 0xcf23, 0xcf22, 0xcf22, 0xcf22, 0xcf21, 0xcf21, + 0xcf21, 0xcf21, 0xcf20, 0xcf20, 0xcf20, 0xcf1f, 0xcf1f, 0xcf1f, + 0xcf1f, 0xcf1e, 0xcf1e, 0xcf1e, 0xcf1e, 0xcf1d, 0xcf1d, 0xcf1d, + 0xcf1c, 0xcf1c, 0xcf1c, 0xcf1c, 0xcf1b, 0xcf1b, 0xcf1b, 0xcf1b, + 0xcf1a, 0xcf1a, 0xcf1a, 0xcf19, 0xcf19, 0xcf19, 0xcf19, 0xcf18, + 0xcf18, 0xcf18, 0xcf18, 0xcf17, 0xcf17, 0xcf17, 0xcf16, 0xcf16, + 0xcf16, 0xcf16, 0xcf15, 0xcf15, 0xcf15, 0xcf15, 0xcf14, 0xcf14, + 0xcf14, 0xcf14, 0xcf13, 0xcf13, 0xcf13, 0xcf12, 0xcf12, 0xcf12, + 0xcf12, 0xcf11, 0xcf11, 0xcf11, 0xcf11, 0xcf10, 0xcf10, 0xcf10, + 0xcf10, 0xcf0f, 0xcf0f, 0xcf0f, 0xcf0e, 0xcf0e, 0xcf0e, 0xcf0e, + 0xcf0d, 0xcf0d, 0xcf0d, 0xcf0d, 0xcf0c, 0xcf0c, 0xcf0c, 0xcf0c, + 0xcf0b, 0xcf0b, 0xcf0b, 0xcf0a, 0xcf0a, 0xcf0a, 0xcf0a, 0xcf09, + 0xcf09, 0xcf09, 0xcf09, 0xcf08, 0xcf08, 0xcf08, 0xcf08, 0xcf07, + 0xcf07, 0xcf07, 0xcf07, 0xcf06, 0xcf06, 0xcf06, 0xcf05, 0xcf05, + 0xcf05, 0xcf05, 0xcf04, 0xcf04, 0xcf04, 0xcf04, 0xcf03, 0xcf03, + 0xcf03, 0xcf03, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf01, 0xcf01, + 0xcf01, 0xcf01, 0xcf00, 0xcf00, 0xcf00, 0xceff, 0xceff, 0xceff, + 0xceff, 0xcefe, 0xcefe, 0xcefe, 0xcefe, 0xcefd, 0xcefd, 0xcefd, + 0xcefd, 0xcefc, 0xcefc, 0xcefc, 0xcefc, 0xcefb, 0xcefb, 0xcefb, + 0xcefb, 0xcefa, 0xcefa, 0xcefa, 0xcefa, 0xcef9, 0xcef9, 0xcef9, + 0xcef9, 0xcef8, 0xcef8, 0xcef8, 0xcef8, 0xcef7, 0xcef7, 0xcef7, + 0xcef7, 0xcef6, 0xcef6, 0xcef6, 0xcef6, 0xcef5, 0xcef5, 0xcef5, + 0xcef4, 0xcef4, 0xcef4, 0xcef4, 0xcef3, 0xcef3, 0xcef3, 0xcef3, + 0xcef2, 0xcef2, 0xcef2, 0xcef2, 0xcef1, 0xcef1, 0xcef1, 0xcef1, + 0xcef0, 0xcef0, 0xcef0, 0xcef0, 0xceef, 0xceef, 0xceef, 0xceef, + 0xceee, 0xceee, 0xceed, 0xceed, 0xceec, 0xceec, 0xceeb, 0xceeb, + 0xceea, 0xceea, 0xcee9, 0xcee9, 0xcee8, 0xcee8, 0xcee8, 0xcee7, + 0xcee7, 0xcee6, 0xcee6, 0xcee5, 0xcee5, 0xcee4, 0xcee4, 0xcee3, + 0xcee3, 0xcee2, 0xcee2, 0xcee1, 0xcee1, 0xcee0, 0xcee0, 0xcedf, + 0xcedf, 0xcede, 0xcede, 0xcedd, 0xcedd, 0xcedc, 0xcedc, 0xcedb, + 0xcedb, 0xceda, 0xceda, 0xced9, 0xced9, 0xced8, 0xced8, 0xced7, + 0xced7, 0xced7, 0xced6, 0xced6, 0xced5, 0xced5, 0xced4, 0xced4, + 0xced3, 0xced3, 0xced2, 0xced2, 0xced1, 0xced1, 0xced0, 0xced0, + 0xcecf, 0xcecf, 0xcece, 0xcece, 0xcece, 0xcecd, 0xcecd, 0xcecc, + 0xcecc, 0xcecb, 0xcecb, 0xceca, 0xceca, 0xcec9, 0xcec9, 0xcec8, + 0xcec8, 0xcec7, 0xcec7, 0xcec7, 0xcec6, 0xcec6, 0xcec5, 0xcec5, + 0xcec4, 0xcec4, 0xcec3, 0xcec3, 0xcec2, 0xcec2, 0xcec1, 0xcec1, + 0xcec1, 0xcec0, 0xcec0, 0xcebf, 0xcebf, 0xcebe, 0xcebe, 0xcebd, + 0xcebd, 0xcebc, 0xcebc, 0xcebc, 0xcebb, 0xcebb, 0xceba, 0xceba, + 0xceb9, 0xceb9, 0xceb8, 0xceb8, 0xceb8, 0xceb7, 0xceb7, 0xceb6, + 0xceb6, 0xceb5, 0xceb5, 0xceb4, 0xceb4, 0xceb3, 0xceb3, 0xceb3, + 0xceb2, 0xceb2, 0xceb1, 0xceb1, 0xceb0, 0xceb0, 0xceaf, 0xceaf, + 0xceaf, 0xceae, 0xceae, 0xcead, 0xcead, 0xceac, 0xceac, 0xceac, + 0xceab, 0xceab, 0xceaa, 0xceaa, 0xcea9, 0xcea9, 0xcea8, 0xcea8, + 0xcea8, 0xcea7, 0xcea7, 0xcea6, 0xcea6, 0xcea5, 0xcea5, 0xcea5, + 0xcea4, 0xcea4, 0xcea3, 0xcea3, 0xcea2, 0xcea2, 0xcea2, 0xcea1, + 0xcea1, 0xcea0, 0xcea0, 0xce9f, 0xce9f, 0xce9f, 0xce9e, 0xce9e, + 0xce9d, 0xce9d, 0xce9c, 0xce9c, 0xce9c, 0xce9b, 0xce9b, 0xce9a, + 0xce9a, 0xce99, 0xce99, 0xce99, 0xce98, 0xce98, 0xce97, 0xce97, + 0xce96, 0xce96, 0xce96, 0xce95, 0xce95, 0xce94, 0xce94, 0xce94, + 0xce93, 0xce93, 0xce92, 0xce92, 0xce91, 0xce91, 0xce91, 0xce90, + 0xce90, 0xce8f, 0xce8f, 0xce8f, 0xce8e, 0xce8e, 0xce8d, 0xce8d, + 0xce8c, 0xce8c, 0xce8c, 0xce8b, 0xce8b, 0xce8a, 0xce8a, 0xce8a, + 0xce89, 0xce89, 0xce88, 0xce88, 0xce88, 0xce87, 0xce87, 0xce86, + 0xce86, 0xce85, 0xce85, 0xce85, 0xce84, 0xce84, 0xce83, 0xce83, + 0xce83, 0xce82, 0xce82, 0xce81, 0xce81, 0xce81, 0xce80, 0xce80, + 0xce7f, 0xce7f, 0xce7f, 0xce7e, 0xce7e, 0xce7d, 0xce7d, 0xce7d, + 0xce7c, 0xce7c, 0xce7b, 0xce7b, 0xce7b, 0xce7a, 0xce7a, 0xce79, + 0xce79, 0xce79, 0xce78, 0xce78, 0xce77, 0xce77, 0xce77, 0xce76, + 0xce76, 0xce75, 0xce75, 0xce75, 0xce74, 0xce74, 0xce73, 0xce73, + 0xce73, 0xce72, 0xce72, 0xce72, 0xce71, 0xce71, 0xce70, 0xce70, + 0xce70, 0xce6f, 0xce6f, 0xce6e, 0xce6e, 0xce6e, 0xce6d, 0xce6d, + 0xce6c, 0xce6c, 0xce6c, 0xce6b, 0xce6b, 0xce6b, 0xce6a, 0xce6a, + 0xce69, 0xce69, 0xce69, 0xce68, 0xce68, 0xce67, 0xce67, 0xce67, + 0xce66, 0xce66, 0xce66, 0xce65, 0xce65, 0xce64, 0xce64, 0xce64, + 0xce63, 0xce63, 0xce62, 0xce62, 0xce62, 0xce61, 0xce61, 0xce61, + 0xce60, 0xce60, 0xce5f, 0xce5f, 0xce5f, 0xce5e, 0xce5e, 0xce5e, + 0xce5d, 0xce5d, 0xce5c, 0xce5c, 0xce5c, 0xce5b, 0xce5b, 0xce5b, + 0xce5a, 0xce5a, 0xce59, 0xce59, 0xce59, 0xce58, 0xce58, 0xce58, + 0xce57, 0xce57, 0xce56, 0xce56, 0xce56, 0xce55, 0xce55, 0xce55, + 0xce54, 0xce54, 0xce53, 0xce53, 0xce53, 0xce52, 0xce52, 0xce52, + 0xce51, 0xce51, 0xce51, 0xce50, 0xce50, 0xce4f, 0xce4f, 0xce4f, + 0xce4e, 0xce4e, 0xce4e, 0xce4d, 0xce4d, 0xce4d, 0xce4c, 0xce4c, + 0xce4b, 0xce4b, 0xce4b, 0xce4a, 0xce4a, 0xce4a, 0xce49, 0xce49, + 0xce49, 0xce48, 0xce48, 0xce47, 0xce47, 0xce47, 0xce46, 0xce46, + 0xce46, 0xce45, 0xce45, 0xce45, 0xce44, 0xce44, 0xce43, 0xce43, + 0xce43, 0xce42, 0xce42, 0xce42, 0xce41, 0xce41, 0xce41, 0xce40, + 0xce40, 0xce40, 0xce3f, 0xce3f, 0xce3e, 0xce3e, 0xce3e, 0xce3d, + 0xce3d, 0xce3d, 0xce3c, 0xce3c, 0xce3c, 0xce3b, 0xce3b, 0xce3b, + 0xce3a, 0xce3a, 0xce3a, 0xce39, 0xce39, 0xce38, 0xce38, 0xce38, + 0xce37, 0xce37, 0xce37, 0xce36, 0xce36, 0xce36, 0xce35, 0xce35, + 0xce35, 0xce34, 0xce34, 0xce34, 0xce33, 0xce33, 0xce33, 0xce32, + 0xce32, 0xce32, 0xce31, 0xce31, 0xce30, 0xce30, 0xce30, 0xce2f, + 0xce2f, 0xce2f, 0xce2e, 0xce2e, 0xce2e, 0xce2d, 0xce2d, 0xce2d, + 0xce2c, 0xce2c, 0xce2c, 0xce2b, 0xce2b, 0xce2b, 0xce2a, 0xce2a, + 0xce2a, 0xce29, 0xce29, 0xce29, 0xce28, 0xce28, 0xce28, 0xce27, + 0xce27, 0xce27, 0xce26, 0xce26, 0xce26, 0xce25, 0xce25, 0xce25, + 0xce24, 0xce24, 0xce24, 0xce23, 0xce23, 0xce23, 0xce22, 0xce22, + 0xce22, 0xce21, 0xce21, 0xce21, 0xce20, 0xce20, 0xce20, 0xce1f, + 0xce1f, 0xce1f, 0xce1e, 0xce1e, 0xce1e, 0xce1d, 0xce1d, 0xce1d, + 0xce1c, 0xce1c, 0xce1c, 0xce1b, 0xce1b, 0xce1b, 0xce1a, 0xce1a, + 0xce1a, 0xce19, 0xce19, 0xce19, 0xce18, 0xce18, 0xce18, 0xce17, + 0xce17, 0xce17, 0xce16, 0xce16, 0xce16, 0xce15, 0xce15, 0xce15, + 0xce14, 0xce14, 0xce14, 0xce13, 0xce13, 0xce13, 0xce12, 0xce12, + 0xce12, 0xce11, 0xce11, 0xce11, 0xce10, 0xce10, 0xce10, 0xce0f, + 0xce0f, 0xce0f, 0xce0e, 0xce0e, 0xce0e, 0xce0d, 0xce0d, 0xce0d, + 0xce0d, 0xce0c, 0xce0c, 0xce0c, 0xce0b, 0xce0b, 0xce0b, 0xce0a, + 0xce0a, 0xce0a, 0xce09, 0xce09, 0xce09, 0xce08, 0xce08, 0xce08, + 0xce07, 0xce07, 0xce07, 0xce06, 0xce06, 0xce06, 0xce05, 0xce05, + 0xce05, 0xce05, 0xce04, 0xce04, 0xce04, 0xce03, 0xce03, 0xce03, + 0xce02, 0xce02, 0xce02, 0xce01, 0xce01, 0xce01, 0xce00, 0xce00, + 0xce00, 0xce00, 0xcdff, 0xcdff, 0xcdff, 0xcdfe, 0xcdfe, 0xcdfe, + 0xcdfd, 0xcdfd, 0xcdfd, 0xcdfc, 0xcdfc, 0xcdfc, 0xcdfb, 0xcdfb, + 0xcdfb, 0xcdfb, 0xcdfa, 0xcdfa, 0xcdfa, 0xcdf9, 0xcdf9, 0xcdf9, + 0xcdf8, 0xcdf8, 0xcdf8, 0xcdf7, 0xcdf7, 0xcdf7, 0xcdf6, 0xcdf6, + 0xcdf6, 0xcdf6, 0xcdf5, 0xcdf5, 0xcdf5, 0xcdf4, 0xcdf4, 0xcdf4, + 0xcdf3, 0xcdf3, 0xcdf3, 0xcdf3, 0xcdf2, 0xcdf2, 0xcdf2, 0xcdf1, + 0xcdf1, 0xcdf1, 0xcdf0, 0xcdf0, 0xcdf0, 0xcdef, 0xcdef, 0xcdef, + 0xcdef, 0xcdee, 0xcdee, 0xcdee, 0xcded, 0xcded, 0xcded, 0xcdec, + 0xcdec, 0xcdec, 0xcdec, 0xcdeb, 0xcdeb, 0xcdeb, 0xcdea, 0xcdea, + 0xcdea, 0xcde9, 0xcde9, 0xcde9, 0xcde9, 0xcde8, 0xcde8, 0xcde8, + 0xcde7, 0xcde7, 0xcde7, 0xcde6, 0xcde6, 0xcde6, 0xcde6, 0xcde5, + 0xcde5, 0xcde5, 0xcde4, 0xcde4, 0xcde4, 0xcde3, 0xcde3, 0xcde3, + 0xcde3, 0xcde2, 0xcde2, 0xcde2, 0xcde1, 0xcde1, 0xcde1, 0xcde0, + 0xcde0, 0xcde0, 0xcde0, 0xcddf, 0xcddf, 0xcddf, 0xcdde, 0xcdde, + 0xcdde, 0xcdde, 0xcddd, 0xcddd, 0xcddd, 0xcddc, 0xcddc, 0xcddc, + 0xcddb, 0xcddb, 0xcddb, 0xcddb, 0xcdda, 0xcdda, 0xcdda, 0xcdd9, + 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd8, 0xcdd8, 0xcdd8, 0xcdd7, 0xcdd7, + 0xcdd7, 0xcdd7, 0xcdd6, 0xcdd6, 0xcdd6, 0xcdd5, 0xcdd5, 0xcdd5, + 0xcdd5, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd3, 0xcdd3, 0xcdd3, 0xcdd3, + 0xcdd2, 0xcdd2, 0xcdd2, 0xcdd1, 0xcdd1, 0xcdd1, 0xcdd1, 0xcdd0, + 0xcdd0, 0xcdd0, 0xcdcf, 0xcdcf, 0xcdcf, 0xcdcf, 0xcdce, 0xcdce, + 0xcdce, 0xcdcd, 0xcdcd, 0xcdcd, 0xcdcd, 0xcdcc, 0xcdcc, 0xcdcc, + 0xcdcb, 0xcdcb, 0xcdcb, 0xcdcb, 0xcdca, 0xcdca, 0xcdca, 0xcdc9, + 0xcdc9, 0xcdc9, 0xcdc9, 0xcdc8, 0xcdc8, 0xcdc8, 0xcdc7, 0xcdc7, + 0xcdc7, 0xcdc7, 0xcdc6, 0xcdc6, 0xcdc6, 0xcdc5, 0xcdc5, 0xcdc5, + 0xcdc5, 0xcdc4, 0xcdc4, 0xcdc4, 0xcdc4, 0xcdc3, 0xcdc3, 0xcdc3, + 0xcdc2, 0xcdc2, 0xcdc2, 0xcdc2, 0xcdc1, 0xcdc1, 0xcdc1, 0xcdc0, + 0xcdc0, 0xcdc0, 0xcdc0, 0xcdbf, 0xcdbf, 0xcdbf, 0xcdbf, 0xcdbe, + 0xcdbe, 0xcdbe, 0xcdbd, 0xcdbd, 0xcdbd, 0xcdbd, 0xcdbc, 0xcdbc, + 0xcdbc, 0xcdbb, 0xcdbb, 0xcdbb, 0xcdbb, 0xcdba, 0xcdba, 0xcdba, + 0xcdba, 0xcdb9, 0xcdb9, 0xcdb9, 0xcdb8, 0xcdb8, 0xcdb8, 0xcdb8, + 0xcdb7, 0xcdb7, 0xcdb7, 0xcdb7, 0xcdb6, 0xcdb6, 0xcdb6, 0xcdb5, + 0xcdb5, 0xcdb5, 0xcdb5, 0xcdb4, 0xcdb4, 0xcdb4, 0xcdb4, 0xcdb3, + 0xcdb3, 0xcdb3, 0xcdb3, 0xcdb2, 0xcdb2, 0xcdb2, 0xcdb1, 0xcdb1, + 0xcdb1, 0xcdb1, 0xcdb0, 0xcdb0, 0xcdb0, 0xcdb0, 0xcdaf, 0xcdaf, + 0xcdaf, 0xcdae, 0xcdae, 0xcdae, 0xcdae, 0xcdad, 0xcdad, 0xcdad, + 0xcdad, 0xcdac, 0xcdac, 0xcdac, 0xcdac, 0xcdab, 0xcdab, 0xcdab, + 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcda9, 0xcda9, 0xcda9, 0xcda9, + 0xcda8, 0xcda8, 0xcda8, 0xcda8, 0xcda7, 0xcda7, 0xcda7, 0xcda7, + 0xcda6, 0xcda6, 0xcda6, 0xcda5, 0xcda5, 0xcda5, 0xcda5, 0xcda4, + 0xcda4, 0xcda4, 0xcda4, 0xcda3, 0xcda3, 0xcda3, 0xcda3, 0xcda2, + 0xcda2, 0xcda2, 0xcda2, 0xcda1, 0xcda1, 0xcda1, 0xcda0, 0xcda0, + 0xcda0, 0xcda0, 0xcd9f, 0xcd9f, 0xcd9f, 0xcd9f, 0xcd9e, 0xcd9e, + 0xcd9e, 0xcd9e, 0xcd9d, 0xcd9d, 0xcd9d, 0xcd9d, 0xcd9c, 0xcd9c, + 0xcd9c, 0xcd9c, 0xcd9b, 0xcd9b, 0xcd9b, 0xcd9b, 0xcd9a, 0xcd9a, + 0xcd9a, 0xcd9a, 0xcd99, 0xcd99, 0xcd99, 0xcd98, 0xcd98, 0xcd98, + 0xcd98, 0xcd97, 0xcd97, 0xcd97, 0xcd97, 0xcd96, 0xcd96, 0xcd96, + 0xcd96, 0xcd95, 0xcd95, 0xcd95, 0xcd95, 0xcd94, 0xcd94, 0xcd94, + 0xcd94, 0xcd93, 0xcd93, 0xcd93, 0xcd93, 0xcd92, 0xcd92, 0xcd92, + 0xcd92, 0xcd91, 0xcd91, 0xcd91, 0xcd91, 0xcd90, 0xcd90, 0xcd90, + 0xcd90, 0xcd8f, 0xcd8f, 0xcd8f, 0xcd8f, 0xcd8e, 0xcd8e, 0xcd8e, + 0xcd8e, 0xcd8d, 0xcd8d, 0xcd8d, 0xcd8d, 0xcd8c, 0xcd8c, 0xcd8c, + 0xcd8c, 0xcd8b, 0xcd8b, 0xcd8a, 0xcd8a, 0xcd89, 0xcd89, 0xcd88, + 0xcd88, 0xcd87, 0xcd87, 0xcd86, 0xcd86, 0xcd85, 0xcd85, 0xcd84, + 0xcd84, 0xcd83, 0xcd83, 0xcd82, 0xcd82, 0xcd81, 0xcd81, 0xcd80, + 0xcd80, 0xcd7f, 0xcd7f, 0xcd7e, 0xcd7e, 0xcd7d, 0xcd7d, 0xcd7c, + 0xcd7c, 0xcd7b, 0xcd7b, 0xcd7a, 0xcd7a, 0xcd79, 0xcd79, 0xcd78, + 0xcd78, 0xcd77, 0xcd77, 0xcd77, 0xcd76, 0xcd76, 0xcd75, 0xcd75, + 0xcd74, 0xcd74, 0xcd73, 0xcd73, 0xcd72, 0xcd72, 0xcd71, 0xcd71, + 0xcd70, 0xcd70, 0xcd6f, 0xcd6f, 0xcd6e, 0xcd6e, 0xcd6d, 0xcd6d, + 0xcd6d, 0xcd6c, 0xcd6c, 0xcd6b, 0xcd6b, 0xcd6a, 0xcd6a, 0xcd69, + 0xcd69, 0xcd68, 0xcd68, 0xcd67, 0xcd67, 0xcd66, 0xcd66, 0xcd66, + 0xcd65, 0xcd65, 0xcd64, 0xcd64, 0xcd63, 0xcd63, 0xcd62, 0xcd62, + 0xcd61, 0xcd61, 0xcd60, 0xcd60, 0xcd60, 0xcd5f, 0xcd5f, 0xcd5e, + 0xcd5e, 0xcd5d, 0xcd5d, 0xcd5c, 0xcd5c, 0xcd5b, 0xcd5b, 0xcd5a, + 0xcd5a, 0xcd5a, 0xcd59, 0xcd59, 0xcd58, 0xcd58, 0xcd57, 0xcd57, + 0xcd56, 0xcd56, 0xcd56, 0xcd55, 0xcd55, 0xcd54, 0xcd54, 0xcd53, + 0xcd53, 0xcd52, 0xcd52, 0xcd51, 0xcd51, 0xcd51, 0xcd50, 0xcd50, + 0xcd4f, 0xcd4f, 0xcd4e, 0xcd4e, 0xcd4d, 0xcd4d, 0xcd4d, 0xcd4c, + 0xcd4c, 0xcd4b, 0xcd4b, 0xcd4a, 0xcd4a, 0xcd4a, 0xcd49, 0xcd49, + 0xcd48, 0xcd48, 0xcd47, 0xcd47, 0xcd46, 0xcd46, 0xcd46, 0xcd45, + 0xcd45, 0xcd44, 0xcd44, 0xcd43, 0xcd43, 0xcd43, 0xcd42, 0xcd42, + 0xcd41, 0xcd41, 0xcd40, 0xcd40, 0xcd40, 0xcd3f, 0xcd3f, 0xcd3e, + 0xcd3e, 0xcd3d, 0xcd3d, 0xcd3c, 0xcd3c, 0xcd3c, 0xcd3b, 0xcd3b, + 0xcd3a, 0xcd3a, 0xcd3a, 0xcd39, 0xcd39, 0xcd38, 0xcd38, 0xcd37, + 0xcd37, 0xcd37, 0xcd36, 0xcd36, 0xcd35, 0xcd35, 0xcd34, 0xcd34, + 0xcd34, 0xcd33, 0xcd33, 0xcd32, 0xcd32, 0xcd31, 0xcd31, 0xcd31, + 0xcd30, 0xcd30, 0xcd2f, 0xcd2f, 0xcd2f, 0xcd2e, 0xcd2e, 0xcd2d, + 0xcd2d, 0xcd2c, 0xcd2c, 0xcd2c, 0xcd2b, 0xcd2b, 0xcd2a, 0xcd2a, + 0xcd2a, 0xcd29, 0xcd29, 0xcd28, 0xcd28, 0xcd28, 0xcd27, 0xcd27, + 0xcd26, 0xcd26, 0xcd25, 0xcd25, 0xcd25, 0xcd24, 0xcd24, 0xcd23, + 0xcd23, 0xcd23, 0xcd22, 0xcd22, 0xcd21, 0xcd21, 0xcd21, 0xcd20, + 0xcd20, 0xcd1f, 0xcd1f, 0xcd1f, 0xcd1e, 0xcd1e, 0xcd1d, 0xcd1d, + 0xcd1d, 0xcd1c, 0xcd1c, 0xcd1b, 0xcd1b, 0xcd1b, 0xcd1a, 0xcd1a, + 0xcd19, 0xcd19, 0xcd19, 0xcd18, 0xcd18, 0xcd17, 0xcd17, 0xcd17, + 0xcd16, 0xcd16, 0xcd15, 0xcd15, 0xcd15, 0xcd14, 0xcd14, 0xcd13, + 0xcd13, 0xcd13, 0xcd12, 0xcd12, 0xcd11, 0xcd11, 0xcd11, 0xcd10, + 0xcd10, 0xcd0f, 0xcd0f, 0xcd0f, 0xcd0e, 0xcd0e, 0xcd0d, 0xcd0d, + 0xcd0d, 0xcd0c, 0xcd0c, 0xcd0c, 0xcd0b, 0xcd0b, 0xcd0a, 0xcd0a, + 0xcd0a, 0xcd09, 0xcd09, 0xcd08, 0xcd08, 0xcd08, 0xcd07, 0xcd07, + 0xcd06, 0xcd06, 0xcd06, 0xcd05, 0xcd05, 0xcd05, 0xcd04, 0xcd04, + 0xcd03, 0xcd03, 0xcd03, 0xcd02, 0xcd02, 0xcd01, 0xcd01, 0xcd01, + 0xcd00, 0xcd00, 0xcd00, 0xccff, 0xccff, 0xccfe, 0xccfe, 0xccfe, + 0xccfd, 0xccfd, 0xccfd, 0xccfc, 0xccfc, 0xccfb, 0xccfb, 0xccfb, + 0xccfa, 0xccfa, 0xccfa, 0xccf9, 0xccf9, 0xccf8, 0xccf8, 0xccf8, + 0xccf7, 0xccf7, 0xccf7, 0xccf6, 0xccf6, 0xccf5, 0xccf5, 0xccf5, + 0xccf4, 0xccf4, 0xccf4, 0xccf3, 0xccf3, 0xccf2, 0xccf2, 0xccf2, + 0xccf1, 0xccf1, 0xccf1, 0xccf0, 0xccf0, 0xccef, 0xccef, 0xccef, + 0xccee, 0xccee, 0xccee, 0xcced, 0xcced, 0xcced, 0xccec, 0xccec, + 0xcceb, 0xcceb, 0xcceb, 0xccea, 0xccea, 0xccea, 0xcce9, 0xcce9, + 0xcce9, 0xcce8, 0xcce8, 0xcce7, 0xcce7, 0xcce7, 0xcce6, 0xcce6, + 0xcce6, 0xcce5, 0xcce5, 0xcce5, 0xcce4, 0xcce4, 0xcce3, 0xcce3, + 0xcce3, 0xcce2, 0xcce2, 0xcce2, 0xcce1, 0xcce1, 0xcce1, 0xcce0, + 0xcce0, 0xcce0, 0xccdf, 0xccdf, 0xccde, 0xccde, 0xccde, 0xccdd, + 0xccdd, 0xccdd, 0xccdc, 0xccdc, 0xccdc, 0xccdb, 0xccdb, 0xccdb, + 0xccda, 0xccda, 0xccd9, 0xccd9, 0xccd9, 0xccd8, 0xccd8, 0xccd8, + 0xccd7, 0xccd7, 0xccd7, 0xccd6, 0xccd6, 0xccd6, 0xccd5, 0xccd5, + 0xccd5, 0xccd4, 0xccd4, 0xccd3, 0xccd3, 0xccd3, 0xccd2, 0xccd2, + 0xccd2, 0xccd1, 0xccd1, 0xccd1, 0xccd0, 0xccd0, 0xccd0, 0xcccf, + 0xcccf, 0xcccf, 0xccce, 0xccce, 0xccce, 0xcccd, 0xcccd, 0xcccd, + 0xcccc, 0xcccc, 0xcccc, 0xcccb, 0xcccb, 0xcccb, 0xccca, 0xccca, + 0xccc9, 0xccc9, 0xccc9, 0xccc8, 0xccc8, 0xccc8, 0xccc7, 0xccc7, + 0xccc7, 0xccc6, 0xccc6, 0xccc6, 0xccc5, 0xccc5, 0xccc5, 0xccc4, + 0xccc4, 0xccc4, 0xccc3, 0xccc3, 0xccc3, 0xccc2, 0xccc2, 0xccc2, + 0xccc1, 0xccc1, 0xccc1, 0xccc0, 0xccc0, 0xccc0, 0xccbf, 0xccbf, + 0xccbf, 0xccbe, 0xccbe, 0xccbe, 0xccbd, 0xccbd, 0xccbd, 0xccbc, + 0xccbc, 0xccbc, 0xccbb, 0xccbb, 0xccbb, 0xccba, 0xccba, 0xccba, + 0xccb9, 0xccb9, 0xccb9, 0xccb8, 0xccb8, 0xccb8, 0xccb7, 0xccb7, + 0xccb7, 0xccb6, 0xccb6, 0xccb6, 0xccb5, 0xccb5, 0xccb5, 0xccb4, + 0xccb4, 0xccb4, 0xccb3, 0xccb3, 0xccb3, 0xccb2, 0xccb2, 0xccb2, + 0xccb1, 0xccb1, 0xccb1, 0xccb0, 0xccb0, 0xccb0, 0xccaf, 0xccaf, + 0xccaf, 0xccae, 0xccae, 0xccae, 0xccae, 0xccad, 0xccad, 0xccad, + 0xccac, 0xccac, 0xccac, 0xccab, 0xccab, 0xccab, 0xccaa, 0xccaa, + 0xccaa, 0xcca9, 0xcca9, 0xcca9, 0xcca8, 0xcca8, 0xcca8, 0xcca7, + 0xcca7, 0xcca7, 0xcca6, 0xcca6, 0xcca6, 0xcca5, 0xcca5, 0xcca5, + 0xcca5, 0xcca4, 0xcca4, 0xcca4, 0xcca3, 0xcca3, 0xcca3, 0xcca2, + 0xcca2, 0xcca2, 0xcca1, 0xcca1, 0xcca1, 0xcca0, 0xcca0, 0xcca0, + 0xcc9f, 0xcc9f, 0xcc9f, 0xcc9e, 0xcc9e, 0xcc9e, 0xcc9e, 0xcc9d, + 0xcc9d, 0xcc9d, 0xcc9c, 0xcc9c, 0xcc9c, 0xcc9b, 0xcc9b, 0xcc9b, + 0xcc9a, 0xcc9a, 0xcc9a, 0xcc99, 0xcc99, 0xcc99, 0xcc99, 0xcc98, + 0xcc98, 0xcc98, 0xcc97, 0xcc97, 0xcc97, 0xcc96, 0xcc96, 0xcc96, + 0xcc95, 0xcc95, 0xcc95, 0xcc95, 0xcc94, 0xcc94, 0xcc94, 0xcc93, + 0xcc93, 0xcc93, 0xcc92, 0xcc92, 0xcc92, 0xcc91, 0xcc91, 0xcc91, + 0xcc91, 0xcc90, 0xcc90, 0xcc90, 0xcc8f, 0xcc8f, 0xcc8f, 0xcc8e, + 0xcc8e, 0xcc8e, 0xcc8d, 0xcc8d, 0xcc8d, 0xcc8d, 0xcc8c, 0xcc8c, + 0xcc8c, 0xcc8b, 0xcc8b, 0xcc8b, 0xcc8a, 0xcc8a, 0xcc8a, 0xcc8a, + 0xcc89, 0xcc89, 0xcc89, 0xcc88, 0xcc88, 0xcc88, 0xcc87, 0xcc87, + 0xcc87, 0xcc87, 0xcc86, 0xcc86, 0xcc86, 0xcc85, 0xcc85, 0xcc85, + 0xcc84, 0xcc84, 0xcc84, 0xcc84, 0xcc83, 0xcc83, 0xcc83, 0xcc82, + 0xcc82, 0xcc82, 0xcc81, 0xcc81, 0xcc81, 0xcc81, 0xcc80, 0xcc80, + 0xcc80, 0xcc7f, 0xcc7f, 0xcc7f, 0xcc7e, 0xcc7e, 0xcc7e, 0xcc7e, + 0xcc7d, 0xcc7d, 0xcc7d, 0xcc7c, 0xcc7c, 0xcc7c, 0xcc7c, 0xcc7b, + 0xcc7b, 0xcc7b, 0xcc7a, 0xcc7a, 0xcc7a, 0xcc79, 0xcc79, 0xcc79, + 0xcc79, 0xcc78, 0xcc78, 0xcc78, 0xcc77, 0xcc77, 0xcc77, 0xcc77, + 0xcc76, 0xcc76, 0xcc76, 0xcc75, 0xcc75, 0xcc75, 0xcc75, 0xcc74, + 0xcc74, 0xcc74, 0xcc73, 0xcc73, 0xcc73, 0xcc72, 0xcc72, 0xcc72, + 0xcc72, 0xcc71, 0xcc71, 0xcc71, 0xcc70, 0xcc70, 0xcc70, 0xcc70, + 0xcc6f, 0xcc6f, 0xcc6f, 0xcc6e, 0xcc6e, 0xcc6e, 0xcc6e, 0xcc6d, + 0xcc6d, 0xcc6d, 0xcc6c, 0xcc6c, 0xcc6c, 0xcc6c, 0xcc6b, 0xcc6b, + 0xcc6b, 0xcc6a, 0xcc6a, 0xcc6a, 0xcc6a, 0xcc69, 0xcc69, 0xcc69, + 0xcc68, 0xcc68, 0xcc68, 0xcc68, 0xcc67, 0xcc67, 0xcc67, 0xcc67, + 0xcc66, 0xcc66, 0xcc66, 0xcc65, 0xcc65, 0xcc65, 0xcc65, 0xcc64, + 0xcc64, 0xcc64, 0xcc63, 0xcc63, 0xcc63, 0xcc63, 0xcc62, 0xcc62, + 0xcc62, 0xcc61, 0xcc61, 0xcc61, 0xcc61, 0xcc60, 0xcc60, 0xcc60, + 0xcc60, 0xcc5f, 0xcc5f, 0xcc5f, 0xcc5e, 0xcc5e, 0xcc5e, 0xcc5e, + 0xcc5d, 0xcc5d, 0xcc5d, 0xcc5c, 0xcc5c, 0xcc5c, 0xcc5c, 0xcc5b, + 0xcc5b, 0xcc5b, 0xcc5b, 0xcc5a, 0xcc5a, 0xcc5a, 0xcc59, 0xcc59, + 0xcc59, 0xcc59, 0xcc58, 0xcc58, 0xcc58, 0xcc58, 0xcc57, 0xcc57, + 0xcc57, 0xcc56, 0xcc56, 0xcc56, 0xcc56, 0xcc55, 0xcc55, 0xcc55, + 0xcc54, 0xcc54, 0xcc54, 0xcc54, 0xcc53, 0xcc53, 0xcc53, 0xcc53, + 0xcc52, 0xcc52, 0xcc52, 0xcc52, 0xcc51, 0xcc51, 0xcc51, 0xcc50, + 0xcc50, 0xcc50, 0xcc50, 0xcc4f, 0xcc4f, 0xcc4f, 0xcc4f, 0xcc4e, + 0xcc4e, 0xcc4e, 0xcc4d, 0xcc4d, 0xcc4d, 0xcc4d, 0xcc4c, 0xcc4c, + 0xcc4c, 0xcc4c, 0xcc4b, 0xcc4b, 0xcc4b, 0xcc4b, 0xcc4a, 0xcc4a, + 0xcc4a, 0xcc49, 0xcc49, 0xcc49, 0xcc49, 0xcc48, 0xcc48, 0xcc48, + 0xcc48, 0xcc47, 0xcc47, 0xcc47, 0xcc47, 0xcc46, 0xcc46, 0xcc46, + 0xcc45, 0xcc45, 0xcc45, 0xcc45, 0xcc44, 0xcc44, 0xcc44, 0xcc44, + 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc42, 0xcc42, 0xcc42, 0xcc42, + 0xcc41, 0xcc41, 0xcc41, 0xcc40, 0xcc40, 0xcc40, 0xcc40, 0xcc3f, + 0xcc3f, 0xcc3f, 0xcc3f, 0xcc3e, 0xcc3e, 0xcc3e, 0xcc3e, 0xcc3d, + 0xcc3d, 0xcc3d, 0xcc3d, 0xcc3c, 0xcc3c, 0xcc3c, 0xcc3c, 0xcc3b, + 0xcc3b, 0xcc3b, 0xcc3a, 0xcc3a, 0xcc3a, 0xcc3a, 0xcc39, 0xcc39, + 0xcc39, 0xcc39, 0xcc38, 0xcc38, 0xcc38, 0xcc38, 0xcc37, 0xcc37, + 0xcc37, 0xcc37, 0xcc36, 0xcc36, 0xcc36, 0xcc36, 0xcc35, 0xcc35, + 0xcc35, 0xcc35, 0xcc34, 0xcc34, 0xcc34, 0xcc34, 0xcc33, 0xcc33, + 0xcc33, 0xcc33, 0xcc32, 0xcc32, 0xcc32, 0xcc31, 0xcc31, 0xcc31, + 0xcc31, 0xcc30, 0xcc30, 0xcc30, 0xcc30, 0xcc2f, 0xcc2f, 0xcc2f, + 0xcc2f, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2d, 0xcc2d, 0xcc2d, + 0xcc2d, 0xcc2c, 0xcc2c, 0xcc2c, 0xcc2c, 0xcc2b, 0xcc2b, 0xcc2b, + 0xcc2b, 0xcc2a, 0xcc2a, 0xcc2a, 0xcc2a, 0xcc29, 0xcc29, 0xcc29, + 0xcc29, 0xcc28, 0xcc28, 0xcc27, 0xcc27, 0xcc26, 0xcc26, 0xcc25, + 0xcc25, 0xcc24, 0xcc24, 0xcc23, 0xcc23, 0xcc22, 0xcc22, 0xcc21, + 0xcc21, 0xcc20, 0xcc20, 0xcc1f, 0xcc1f, 0xcc1e, 0xcc1e, 0xcc1d, + 0xcc1d, 0xcc1c, 0xcc1c, 0xcc1b, 0xcc1b, 0xcc1a, 0xcc1a, 0xcc19, + 0xcc19, 0xcc18, 0xcc18, 0xcc17, 0xcc17, 0xcc17, 0xcc16, 0xcc16, + 0xcc15, 0xcc15, 0xcc14, 0xcc14, 0xcc13, 0xcc13, 0xcc12, 0xcc12, + 0xcc11, 0xcc11, 0xcc10, 0xcc10, 0xcc0f, 0xcc0f, 0xcc0e, 0xcc0e, + 0xcc0d, 0xcc0d, 0xcc0c, 0xcc0c, 0xcc0c, 0xcc0b, 0xcc0b, 0xcc0a, + 0xcc0a, 0xcc09, 0xcc09, 0xcc08, 0xcc08, 0xcc07, 0xcc07, 0xcc06, + 0xcc06, 0xcc05, 0xcc05, 0xcc04, 0xcc04, 0xcc04, 0xcc03, 0xcc03, + 0xcc02, 0xcc02, 0xcc01, 0xcc01, 0xcc00, 0xcc00, 0xcbff, 0xcbfe, + 0xcbfd, 0xcbfc, 0xcbfb, 0xcbfa, 0xcbf9, 0xcbf8, 0xcbf7, 0xcbf6, + 0xcbf6, 0xcbf5, 0xcbf4, 0xcbf3, 0xcbf2, 0xcbf1, 0xcbf0, 0xcbef, + 0xcbee, 0xcbed, 0xcbec, 0xcbec, 0xcbeb, 0xcbea, 0xcbe9, 0xcbe8, + 0xcbe7, 0xcbe6, 0xcbe5, 0xcbe4, 0xcbe3, 0xcbe3, 0xcbe2, 0xcbe1, + 0xcbe0, 0xcbdf, 0xcbde, 0xcbdd, 0xcbdc, 0xcbdb, 0xcbdb, 0xcbda, + 0xcbd9, 0xcbd8, 0xcbd7, 0xcbd6, 0xcbd5, 0xcbd4, 0xcbd3, 0xcbd3, + 0xcbd2, 0xcbd1, 0xcbd0, 0xcbcf, 0xcbce, 0xcbcd, 0xcbcc, 0xcbcb, + 0xcbcb, 0xcbca, 0xcbc9, 0xcbc8, 0xcbc7, 0xcbc6, 0xcbc5, 0xcbc4, + 0xcbc4, 0xcbc3, 0xcbc2, 0xcbc1, 0xcbc0, 0xcbbf, 0xcbbe, 0xcbbe, + 0xcbbd, 0xcbbc, 0xcbbb, 0xcbba, 0xcbb9, 0xcbb8, 0xcbb8, 0xcbb7, + 0xcbb6, 0xcbb5, 0xcbb4, 0xcbb3, 0xcbb2, 0xcbb1, 0xcbb1, 0xcbb0, + 0xcbaf, 0xcbae, 0xcbad, 0xcbac, 0xcbac, 0xcbab, 0xcbaa, 0xcba9, + 0xcba8, 0xcba7, 0xcba6, 0xcba6, 0xcba5, 0xcba4, 0xcba3, 0xcba2, + 0xcba1, 0xcba1, 0xcba0, 0xcb9f, 0xcb9e, 0xcb9d, 0xcb9c, 0xcb9b, + 0xcb9b, 0xcb9a, 0xcb99, 0xcb98, 0xcb97, 0xcb96, 0xcb96, 0xcb95, + 0xcb94, 0xcb93, 0xcb92, 0xcb91, 0xcb91, 0xcb90, 0xcb8f, 0xcb8e, + 0xcb8d, 0xcb8d, 0xcb8c, 0xcb8b, 0xcb8a, 0xcb89, 0xcb88, 0xcb88, + 0xcb87, 0xcb86, 0xcb85, 0xcb84, 0xcb83, 0xcb83, 0xcb82, 0xcb81, + 0xcb80, 0xcb7f, 0xcb7f, 0xcb7e, 0xcb7d, 0xcb7c, 0xcb7b, 0xcb7b, + 0xcb7a, 0xcb79, 0xcb78, 0xcb77, 0xcb76, 0xcb76, 0xcb75, 0xcb74, + 0xcb73, 0xcb72, 0xcb72, 0xcb71, 0xcb70, 0xcb6f, 0xcb6e, 0xcb6e, + 0xcb6d, 0xcb6c, 0xcb6b, 0xcb6a, 0xcb6a, 0xcb69, 0xcb68, 0xcb67, + 0xcb66, 0xcb66, 0xcb65, 0xcb64, 0xcb63, 0xcb63, 0xcb62, 0xcb61, + 0xcb60, 0xcb5f, 0xcb5f, 0xcb5e, 0xcb5d, 0xcb5c, 0xcb5b, 0xcb5b, + 0xcb5a, 0xcb59, 0xcb58, 0xcb57, 0xcb57, 0xcb56, 0xcb55, 0xcb54, + 0xcb54, 0xcb53, 0xcb52, 0xcb51, 0xcb50, 0xcb50, 0xcb4f, 0xcb4e, + 0xcb4d, 0xcb4d, 0xcb4c, 0xcb4b, 0xcb4a, 0xcb49, 0xcb49, 0xcb48, + 0xcb47, 0xcb46, 0xcb46, 0xcb45, 0xcb44, 0xcb43, 0xcb43, 0xcb42, + 0xcb41, 0xcb40, 0xcb3f, 0xcb3f, 0xcb3e, 0xcb3d, 0xcb3c, 0xcb3c, + 0xcb3b, 0xcb3a, 0xcb39, 0xcb39, 0xcb38, 0xcb37, 0xcb36, 0xcb36, + 0xcb35, 0xcb34, 0xcb33, 0xcb33, 0xcb32, 0xcb31, 0xcb30, 0xcb30, + 0xcb2f, 0xcb2e, 0xcb2d, 0xcb2d, 0xcb2c, 0xcb2b, 0xcb2a, 0xcb2a, + 0xcb29, 0xcb28, 0xcb27, 0xcb27, 0xcb26, 0xcb25, 0xcb24, 0xcb24, + 0xcb23, 0xcb22, 0xcb21, 0xcb21, 0xcb20, 0xcb1f, 0xcb1e, 0xcb1e, + 0xcb1d, 0xcb1c, 0xcb1b, 0xcb1b, 0xcb1a, 0xcb19, 0xcb18, 0xcb18, + 0xcb17, 0xcb16, 0xcb15, 0xcb15, 0xcb14, 0xcb13, 0xcb13, 0xcb12, + 0xcb11, 0xcb10, 0xcb10, 0xcb0f, 0xcb0e, 0xcb0d, 0xcb0d, 0xcb0c, + 0xcb0b, 0xcb0b, 0xcb0a, 0xcb09, 0xcb08, 0xcb08, 0xcb07, 0xcb06, + 0xcb05, 0xcb05, 0xcb04, 0xcb03, 0xcb03, 0xcb02, 0xcb01, 0xcb00, + 0xcb00, 0xcaff, 0xcafe, 0xcafe, 0xcafd, 0xcafc, 0xcafb, 0xcafb, + 0xcafa, 0xcaf9, 0xcaf9, 0xcaf8, 0xcaf7, 0xcaf6, 0xcaf6, 0xcaf5, + 0xcaf4, 0xcaf4, 0xcaf3, 0xcaf2, 0xcaf1, 0xcaf1, 0xcaf0, 0xcaef, + 0xcaef, 0xcaee, 0xcaed, 0xcaec, 0xcaec, 0xcaeb, 0xcaea, 0xcaea, + 0xcae9, 0xcae8, 0xcae8, 0xcae7, 0xcae6, 0xcae5, 0xcae5, 0xcae4, + 0xcae3, 0xcae3, 0xcae2, 0xcae1, 0xcae1, 0xcae0, 0xcadf, 0xcade, + 0xcade, 0xcadd, 0xcadc, 0xcadc, 0xcadb, 0xcada, 0xcada, 0xcad9, + 0xcad8, 0xcad7, 0xcad7, 0xcad6, 0xcad5, 0xcad5, 0xcad4, 0xcad3, + 0xcad3, 0xcad2, 0xcad1, 0xcad1, 0xcad0, 0xcacf, 0xcacf, 0xcace, + 0xcacd, 0xcacc, 0xcacc, 0xcacb, 0xcaca, 0xcaca, 0xcac9, 0xcac8, + 0xcac8, 0xcac7, 0xcac6, 0xcac6, 0xcac5, 0xcac4, 0xcac4, 0xcac3, + 0xcac2, 0xcac2, 0xcac1, 0xcac0, 0xcac0, 0xcabf, 0xcabe, 0xcabe, + 0xcabd, 0xcabc, 0xcabc, 0xcabb, 0xcaba, 0xcaba, 0xcab9, 0xcab8, + 0xcab7, 0xcab7, 0xcab6, 0xcab5, 0xcab5, 0xcab4, 0xcab3, 0xcab3, + 0xcab2, 0xcab1, 0xcab1, 0xcab0, 0xcaaf, 0xcaaf, 0xcaae, 0xcaad, + 0xcaad, 0xcaac, 0xcaac, 0xcaab, 0xcaaa, 0xcaaa, 0xcaa9, 0xcaa8, + 0xcaa8, 0xcaa7, 0xcaa6, 0xcaa6, 0xcaa5, 0xcaa4, 0xcaa4, 0xcaa3, + 0xcaa2, 0xcaa2, 0xcaa1, 0xcaa0, 0xcaa0, 0xca9f, 0xca9e, 0xca9e, + 0xca9d, 0xca9c, 0xca9c, 0xca9b, 0xca9a, 0xca9a, 0xca99, 0xca98, + 0xca98, 0xca97, 0xca97, 0xca96, 0xca95, 0xca95, 0xca94, 0xca93, + 0xca93, 0xca92, 0xca91, 0xca91, 0xca90, 0xca8f, 0xca8f, 0xca8e, + 0xca8d, 0xca8d, 0xca8c, 0xca8c, 0xca8b, 0xca8a, 0xca8a, 0xca89, + 0xca88, 0xca88, 0xca87, 0xca86, 0xca86, 0xca85, 0xca85, 0xca84, + 0xca83, 0xca83, 0xca82, 0xca81, 0xca81, 0xca80, 0xca7f, 0xca7f, + 0xca7e, 0xca7e, 0xca7d, 0xca7c, 0xca7c, 0xca7b, 0xca7a, 0xca7a, + 0xca79, 0xca78, 0xca78, 0xca77, 0xca77, 0xca76, 0xca75, 0xca75, + 0xca74, 0xca73, 0xca73, 0xca72, 0xca72, 0xca71, 0xca70, 0xca70, + 0xca6f, 0xca6e, 0xca6e, 0xca6d, 0xca6d, 0xca6c, 0xca6b, 0xca6b, + 0xca6a, 0xca69, 0xca69, 0xca68, 0xca68, 0xca67, 0xca66, 0xca66, + 0xca65, 0xca65, 0xca64, 0xca63, 0xca63, 0xca62, 0xca61, 0xca61, + 0xca60, 0xca60, 0xca5f, 0xca5e, 0xca5e, 0xca5d, 0xca5d, 0xca5c, + 0xca5b, 0xca5b, 0xca5a, 0xca59, 0xca59, 0xca58, 0xca58, 0xca57, + 0xca56, 0xca56, 0xca55, 0xca55, 0xca54, 0xca53, 0xca53, 0xca52, + 0xca52, 0xca51, 0xca50, 0xca50, 0xca4f, 0xca4e, 0xca4e, 0xca4d, + 0xca4d, 0xca4c, 0xca4b, 0xca4b, 0xca4a, 0xca4a, 0xca49, 0xca48, + 0xca48, 0xca47, 0xca47, 0xca46, 0xca45, 0xca45, 0xca44, 0xca44, + 0xca43, 0xca42, 0xca42, 0xca41, 0xca41, 0xca40, 0xca3f, 0xca3f, + 0xca3e, 0xca3e, 0xca3d, 0xca3d, 0xca3c, 0xca3b, 0xca3b, 0xca3a, + 0xca3a, 0xca39, 0xca38, 0xca38, 0xca37, 0xca37, 0xca36, 0xca35, + 0xca35, 0xca34, 0xca34, 0xca33, 0xca32, 0xca32, 0xca31, 0xca31, + 0xca30, 0xca30, 0xca2f, 0xca2e, 0xca2e, 0xca2d, 0xca2d, 0xca2c, + 0xca2b, 0xca2b, 0xca2a, 0xca2a, 0xca29, 0xca28, 0xca28, 0xca27, + 0xca27, 0xca26, 0xca26, 0xca25, 0xca24, 0xca24, 0xca23, 0xca23, + 0xca22, 0xca22, 0xca21, 0xca20, 0xca20, 0xca1f, 0xca1f, 0xca1e, + 0xca1d, 0xca1d, 0xca1c, 0xca1c, 0xca1b, 0xca1b, 0xca1a, 0xca19, + 0xca19, 0xca18, 0xca18, 0xca17, 0xca17, 0xca16, 0xca15, 0xca15, + 0xca14, 0xca14, 0xca13, 0xca13, 0xca12, 0xca11, 0xca11, 0xca10, + 0xca10, 0xca0f, 0xca0f, 0xca0e, 0xca0d, 0xca0d, 0xca0c, 0xca0c, + 0xca0b, 0xca0b, 0xca0a, 0xca0a, 0xca09, 0xca08, 0xca08, 0xca07, + 0xca07, 0xca06, 0xca06, 0xca05, 0xca04, 0xca04, 0xca03, 0xca03, + 0xca02, 0xca02, 0xca01, 0xca00, 0xca00, 0xc9ff, 0xc9ff, 0xc9fe, + 0xc9fe, 0xc9fd, 0xc9fd, 0xc9fc, 0xc9fb, 0xc9fb, 0xc9fa, 0xc9fa, + 0xc9f9, 0xc9f9, 0xc9f8, 0xc9f8, 0xc9f7, 0xc9f6, 0xc9f6, 0xc9f5, + 0xc9f5, 0xc9f4, 0xc9f4, 0xc9f3, 0xc9f3, 0xc9f2, 0xc9f1, 0xc9f1, + 0xc9f0, 0xc9f0, 0xc9ef, 0xc9ef, 0xc9ee, 0xc9ee, 0xc9ed, 0xc9ed, + 0xc9ec, 0xc9eb, 0xc9eb, 0xc9ea, 0xc9ea, 0xc9e9, 0xc9e9, 0xc9e8, + 0xc9e8, 0xc9e7, 0xc9e6, 0xc9e6, 0xc9e5, 0xc9e5, 0xc9e4, 0xc9e4, + 0xc9e3, 0xc9e3, 0xc9e2, 0xc9e2, 0xc9e1, 0xc9e0, 0xc9e0, 0xc9df, + 0xc9df, 0xc9de, 0xc9de, 0xc9dd, 0xc9dd, 0xc9dc, 0xc9dc, 0xc9db, + 0xc9db, 0xc9da, 0xc9d9, 0xc9d9, 0xc9d8, 0xc9d8, 0xc9d7, 0xc9d7, + 0xc9d6, 0xc9d6, 0xc9d5, 0xc9d5, 0xc9d4, 0xc9d4, 0xc9d3, 0xc9d2, + 0xc9d2, 0xc9d1, 0xc9d1, 0xc9d0, 0xc9d0, 0xc9cf, 0xc9cf, 0xc9ce, + 0xc9ce, 0xc9cd, 0xc9cd, 0xc9cc, 0xc9cc, 0xc9cb, 0xc9ca, 0xc9ca, + 0xc9c9, 0xc9c9, 0xc9c8, 0xc9c8, 0xc9c7, 0xc9c7, 0xc9c6, 0xc9c6, + 0xc9c5, 0xc9c5, 0xc9c4, 0xc9c4, 0xc9c3, 0xc9c3, 0xc9c2, 0xc9c1, + 0xc9c1, 0xc9c0, 0xc9c0, 0xc9bf, 0xc9bf, 0xc9be, 0xc9be, 0xc9bd, + 0xc9bd, 0xc9bc, 0xc9bc, 0xc9bb, 0xc9bb, 0xc9ba, 0xc9ba, 0xc9b9, + 0xc9b9, 0xc9b8, 0xc9b7, 0xc9b7, 0xc9b6, 0xc9b6, 0xc9b5, 0xc9b5, + 0xc9b4, 0xc9b4, 0xc9b3, 0xc9b3, 0xc9b2, 0xc9b2, 0xc9b1, 0xc9b1, + 0xc9b0, 0xc9b0, 0xc9af, 0xc9af, 0xc9ae, 0xc9ae, 0xc9ad, 0xc9ad, + 0xc9ac, 0xc9ac, 0xc9ab, 0xc9ab, 0xc9aa, 0xc9a9, 0xc9a9, 0xc9a8, + 0xc9a8, 0xc9a7, 0xc9a7, 0xc9a6, 0xc9a6, 0xc9a5, 0xc9a5, 0xc9a4, + 0xc9a4, 0xc9a3, 0xc9a3, 0xc9a2, 0xc9a2, 0xc9a1, 0xc9a1, 0xc9a0, + 0xc9a0, 0xc99f, 0xc99f, 0xc99e, 0xc99e, 0xc99d, 0xc99d, 0xc99c, + 0xc99c, 0xc99b, 0xc99b, 0xc99a, 0xc99a, 0xc999, 0xc999, 0xc998, + 0xc998, 0xc997, 0xc997, 0xc996, 0xc996, 0xc995, 0xc995, 0xc994, + 0xc994, 0xc993, 0xc993, 0xc992, 0xc992, 0xc991, 0xc991, 0xc990, + 0xc990, 0xc98f, 0xc98f, 0xc98e, 0xc98e, 0xc98d, 0xc98d, 0xc98c, + 0xc98c, 0xc98b, 0xc98a, 0xc989, 0xc988, 0xc987, 0xc986, 0xc985, + 0xc984, 0xc983, 0xc982, 0xc981, 0xc980, 0xc97f, 0xc97e, 0xc97d, + 0xc97c, 0xc97b, 0xc97a, 0xc979, 0xc978, 0xc977, 0xc976, 0xc975, + 0xc974, 0xc973, 0xc972, 0xc971, 0xc970, 0xc96f, 0xc96e, 0xc96d, + 0xc96c, 0xc96b, 0xc96a, 0xc969, 0xc968, 0xc967, 0xc966, 0xc965, + 0xc964, 0xc963, 0xc962, 0xc961, 0xc960, 0xc960, 0xc95f, 0xc95e, + 0xc95d, 0xc95c, 0xc95b, 0xc95a, 0xc959, 0xc958, 0xc957, 0xc956, + 0xc955, 0xc954, 0xc953, 0xc952, 0xc951, 0xc950, 0xc94f, 0xc94e, + 0xc94d, 0xc94d, 0xc94c, 0xc94b, 0xc94a, 0xc949, 0xc948, 0xc947, + 0xc946, 0xc945, 0xc944, 0xc943, 0xc942, 0xc941, 0xc940, 0xc93f, + 0xc93f, 0xc93e, 0xc93d, 0xc93c, 0xc93b, 0xc93a, 0xc939, 0xc938, + 0xc937, 0xc936, 0xc935, 0xc934, 0xc933, 0xc933, 0xc932, 0xc931, + 0xc930, 0xc92f, 0xc92e, 0xc92d, 0xc92c, 0xc92b, 0xc92a, 0xc929, + 0xc929, 0xc928, 0xc927, 0xc926, 0xc925, 0xc924, 0xc923, 0xc922, + 0xc921, 0xc920, 0xc91f, 0xc91f, 0xc91e, 0xc91d, 0xc91c, 0xc91b, + 0xc91a, 0xc919, 0xc918, 0xc917, 0xc917, 0xc916, 0xc915, 0xc914, + 0xc913, 0xc912, 0xc911, 0xc910, 0xc90f, 0xc90f, 0xc90e, 0xc90d, + 0xc90c, 0xc90b, 0xc90a, 0xc909, 0xc908, 0xc907, 0xc907, 0xc906, + 0xc905, 0xc904, 0xc903, 0xc902, 0xc901, 0xc900, 0xc900, 0xc8ff, + 0xc8fe, 0xc8fd, 0xc8fc, 0xc8fb, 0xc8fa, 0xc8f9, 0xc8f9, 0xc8f8, + 0xc8f7, 0xc8f6, 0xc8f5, 0xc8f4, 0xc8f3, 0xc8f3, 0xc8f2, 0xc8f1, + 0xc8f0, 0xc8ef, 0xc8ee, 0xc8ed, 0xc8ed, 0xc8ec, 0xc8eb, 0xc8ea, + 0xc8e9, 0xc8e8, 0xc8e7, 0xc8e7, 0xc8e6, 0xc8e5, 0xc8e4, 0xc8e3, + 0xc8e2, 0xc8e2, 0xc8e1, 0xc8e0, 0xc8df, 0xc8de, 0xc8dd, 0xc8dc, + 0xc8dc, 0xc8db, 0xc8da, 0xc8d9, 0xc8d8, 0xc8d7, 0xc8d7, 0xc8d6, + 0xc8d5, 0xc8d4, 0xc8d3, 0xc8d2, 0xc8d2, 0xc8d1, 0xc8d0, 0xc8cf, + 0xc8ce, 0xc8cd, 0xc8cd, 0xc8cc, 0xc8cb, 0xc8ca, 0xc8c9, 0xc8c8, + 0xc8c8, 0xc8c7, 0xc8c6, 0xc8c5, 0xc8c4, 0xc8c3, 0xc8c3, 0xc8c2, + 0xc8c1, 0xc8c0, 0xc8bf, 0xc8bf, 0xc8be, 0xc8bd, 0xc8bc, 0xc8bb, + 0xc8ba, 0xc8ba, 0xc8b9, 0xc8b8, 0xc8b7, 0xc8b6, 0xc8b6, 0xc8b5, + 0xc8b4, 0xc8b3, 0xc8b2, 0xc8b2, 0xc8b1, 0xc8b0, 0xc8af, 0xc8ae, + 0xc8ad, 0xc8ad, 0xc8ac, 0xc8ab, 0xc8aa, 0xc8a9, 0xc8a9, 0xc8a8, + 0xc8a7, 0xc8a6, 0xc8a5, 0xc8a5, 0xc8a4, 0xc8a3, 0xc8a2, 0xc8a1, + 0xc8a1, 0xc8a0, 0xc89f, 0xc89e, 0xc89e, 0xc89d, 0xc89c, 0xc89b, + 0xc89a, 0xc89a, 0xc899, 0xc898, 0xc897, 0xc896, 0xc896, 0xc895, + 0xc894, 0xc893, 0xc892, 0xc892, 0xc891, 0xc890, 0xc88f, 0xc88f, + 0xc88e, 0xc88d, 0xc88c, 0xc88b, 0xc88b, 0xc88a, 0xc889, 0xc888, + 0xc888, 0xc887, 0xc886, 0xc885, 0xc884, 0xc884, 0xc883, 0xc882, + 0xc881, 0xc881, 0xc880, 0xc87f, 0xc87e, 0xc87e, 0xc87d, 0xc87c, + 0xc87b, 0xc87a, 0xc87a, 0xc879, 0xc878, 0xc877, 0xc877, 0xc876, + 0xc875, 0xc874, 0xc874, 0xc873, 0xc872, 0xc871, 0xc871, 0xc870, + 0xc86f, 0xc86e, 0xc86e, 0xc86d, 0xc86c, 0xc86b, 0xc86a, 0xc86a, + 0xc869, 0xc868, 0xc867, 0xc867, 0xc866, 0xc865, 0xc864, 0xc864, + 0xc863, 0xc862, 0xc861, 0xc861, 0xc860, 0xc85f, 0xc85e, 0xc85e, + 0xc85d, 0xc85c, 0xc85c, 0xc85b, 0xc85a, 0xc859, 0xc859, 0xc858, + 0xc857, 0xc856, 0xc856, 0xc855, 0xc854, 0xc853, 0xc853, 0xc852, + 0xc851, 0xc850, 0xc850, 0xc84f, 0xc84e, 0xc84e, 0xc84d, 0xc84c, + 0xc84b, 0xc84b, 0xc84a, 0xc849, 0xc848, 0xc848, 0xc847, 0xc846, + 0xc845, 0xc845, 0xc844, 0xc843, 0xc843, 0xc842, 0xc841, 0xc840, + 0xc840, 0xc83f, 0xc83e, 0xc83d, 0xc83d, 0xc83c, 0xc83b, 0xc83b, + 0xc83a, 0xc839, 0xc838, 0xc838, 0xc837, 0xc836, 0xc836, 0xc835, + 0xc834, 0xc833, 0xc833, 0xc832, 0xc831, 0xc831, 0xc830, 0xc82f, + 0xc82e, 0xc82e, 0xc82d, 0xc82c, 0xc82c, 0xc82b, 0xc82a, 0xc829, + 0xc829, 0xc828, 0xc827, 0xc827, 0xc826, 0xc825, 0xc825, 0xc824, + 0xc823, 0xc822, 0xc822, 0xc821, 0xc820, 0xc820, 0xc81f, 0xc81e, + 0xc81e, 0xc81d, 0xc81c, 0xc81b, 0xc81b, 0xc81a, 0xc819, 0xc819, + 0xc818, 0xc817, 0xc817, 0xc816, 0xc815, 0xc814, 0xc814, 0xc813, + 0xc812, 0xc812, 0xc811, 0xc810, 0xc810, 0xc80f, 0xc80e, 0xc80e, + 0xc80d, 0xc80c, 0xc80c, 0xc80b, 0xc80a, 0xc809, 0xc809, 0xc808, + 0xc807, 0xc807, 0xc806, 0xc805, 0xc805, 0xc804, 0xc803, 0xc803, + 0xc802, 0xc801, 0xc801, 0xc800, 0xc7fe, 0xc7fd, 0xc7fc, 0xc7fa, + 0xc7f9, 0xc7f8, 0xc7f6, 0xc7f5, 0xc7f4, 0xc7f2, 0xc7f1, 0xc7f0, + 0xc7ee, 0xc7ed, 0xc7eb, 0xc7ea, 0xc7e9, 0xc7e7, 0xc7e6, 0xc7e5, + 0xc7e3, 0xc7e2, 0xc7e1, 0xc7df, 0xc7de, 0xc7dd, 0xc7db, 0xc7da, + 0xc7d9, 0xc7d7, 0xc7d6, 0xc7d5, 0xc7d3, 0xc7d2, 0xc7d1, 0xc7cf, + 0xc7ce, 0xc7cd, 0xc7cb, 0xc7ca, 0xc7c9, 0xc7c7, 0xc7c6, 0xc7c5, + 0xc7c4, 0xc7c2, 0xc7c1, 0xc7c0, 0xc7be, 0xc7bd, 0xc7bc, 0xc7ba, + 0xc7b9, 0xc7b8, 0xc7b6, 0xc7b5, 0xc7b4, 0xc7b2, 0xc7b1, 0xc7b0, + 0xc7af, 0xc7ad, 0xc7ac, 0xc7ab, 0xc7a9, 0xc7a8, 0xc7a7, 0xc7a5, + 0xc7a4, 0xc7a3, 0xc7a1, 0xc7a0, 0xc79f, 0xc79e, 0xc79c, 0xc79b, + 0xc79a, 0xc798, 0xc797, 0xc796, 0xc795, 0xc793, 0xc792, 0xc791, + 0xc78f, 0xc78e, 0xc78d, 0xc78c, 0xc78a, 0xc789, 0xc788, 0xc786, + 0xc785, 0xc784, 0xc783, 0xc781, 0xc780, 0xc77f, 0xc77d, 0xc77c, + 0xc77b, 0xc77a, 0xc778, 0xc777, 0xc776, 0xc775, 0xc773, 0xc772, + 0xc771, 0xc76f, 0xc76e, 0xc76d, 0xc76c, 0xc76a, 0xc769, 0xc768, + 0xc767, 0xc765, 0xc764, 0xc763, 0xc762, 0xc760, 0xc75f, 0xc75e, + 0xc75d, 0xc75b, 0xc75a, 0xc759, 0xc758, 0xc756, 0xc755, 0xc754, + 0xc753, 0xc751, 0xc750, 0xc74f, 0xc74e, 0xc74c, 0xc74b, 0xc74a, + 0xc749, 0xc747, 0xc746, 0xc745, 0xc744, 0xc742, 0xc741, 0xc740, + 0xc73f, 0xc73d, 0xc73c, 0xc73b, 0xc73a, 0xc739, 0xc737, 0xc736, + 0xc735, 0xc734, 0xc732, 0xc731, 0xc730, 0xc72f, 0xc72d, 0xc72c, + 0xc72b, 0xc72a, 0xc729, 0xc727, 0xc726, 0xc725, 0xc724, 0xc722, + 0xc721, 0xc720, 0xc71f, 0xc71e, 0xc71c, 0xc71b, 0xc71a, 0xc719, + 0xc717, 0xc716, 0xc715, 0xc714, 0xc713, 0xc711, 0xc710, 0xc70f, + 0xc70e, 0xc70d, 0xc70b, 0xc70a, 0xc709, 0xc708, 0xc707, 0xc705, + 0xc704, 0xc703, 0xc702, 0xc701, 0xc6ff, 0xc6fe, 0xc6fd, 0xc6fc, + 0xc6fb, 0xc6f9, 0xc6f8, 0xc6f7, 0xc6f6, 0xc6f5, 0xc6f3, 0xc6f2, + 0xc6f1, 0xc6f0, 0xc6ef, 0xc6ed, 0xc6ec, 0xc6eb, 0xc6ea, 0xc6e9, + 0xc6e8, 0xc6e6, 0xc6e5, 0xc6e4, 0xc6e3, 0xc6e2, 0xc6e0, 0xc6df, + 0xc6de, 0xc6dd, 0xc6dc, 0xc6db, 0xc6d9, 0xc6d8, 0xc6d7, 0xc6d6, + 0xc6d5, 0xc6d3, 0xc6d2, 0xc6d1, 0xc6d0, 0xc6cf, 0xc6ce, 0xc6cc, + 0xc6cb, 0xc6ca, 0xc6c9, 0xc6c8, 0xc6c7, 0xc6c5, 0xc6c4, 0xc6c3, + 0xc6c2, 0xc6c1, 0xc6c0, 0xc6be, 0xc6bd, 0xc6bc, 0xc6bb, 0xc6ba, + 0xc6b9, 0xc6b7, 0xc6b6, 0xc6b5, 0xc6b4, 0xc6b3, 0xc6b2, 0xc6b1, + 0xc6af, 0xc6ae, 0xc6ad, 0xc6ac, 0xc6ab, 0xc6aa, 0xc6a8, 0xc6a7, + 0xc6a6, 0xc6a5, 0xc6a4, 0xc6a3, 0xc6a2, 0xc6a0, 0xc69f, 0xc69e, + 0xc69d, 0xc69c, 0xc69b, 0xc69a, 0xc698, 0xc697, 0xc696, 0xc695, + 0xc694, 0xc693, 0xc692, 0xc691, 0xc68f, 0xc68e, 0xc68d, 0xc68c, + 0xc68b, 0xc68a, 0xc689, 0xc687, 0xc686, 0xc685, 0xc684, 0xc683, + 0xc682, 0xc681, 0xc680, 0xc67e, 0xc67d, 0xc67c, 0xc67b, 0xc67a, + 0xc679, 0xc678, 0xc677, 0xc675, 0xc674, 0xc673, 0xc672, 0xc671, + 0xc670, 0xc66f, 0xc66e, 0xc66c, 0xc66b, 0xc66a, 0xc669, 0xc668, + 0xc667, 0xc666, 0xc665, 0xc664, 0xc662, 0xc661, 0xc660, 0xc65f, + 0xc65e, 0xc65d, 0xc65c, 0xc65b, 0xc65a, 0xc658, 0xc657, 0xc656, + 0xc655, 0xc654, 0xc653, 0xc652, 0xc651, 0xc650, 0xc64f, 0xc64d, + 0xc64c, 0xc64b, 0xc64a, 0xc649, 0xc648, 0xc647, 0xc646, 0xc645, + 0xc644, 0xc642, 0xc641, 0xc640, 0xc63f, 0xc63e, 0xc63d, 0xc63c, + 0xc63b, 0xc63a, 0xc639, 0xc638, 0xc637, 0xc635, 0xc634, 0xc633, + 0xc632, 0xc631, 0xc630, 0xc62f, 0xc62e, 0xc62d, 0xc62c, 0xc62b, + 0xc62a, 0xc628, 0xc627, 0xc626, 0xc625, 0xc624, 0xc623, 0xc622, + 0xc621, 0xc620, 0xc61f, 0xc61e, 0xc61d, 0xc61c, 0xc61a, 0xc619, + 0xc618, 0xc617, 0xc616, 0xc615, 0xc614, 0xc613, 0xc612, 0xc611, + 0xc610, 0xc60f, 0xc60e, 0xc60d, 0xc60b, 0xc60a, 0xc609, 0xc608, + 0xc607, 0xc606, 0xc605, 0xc604, 0xc603, 0xc602, 0xc601, 0xc600, + 0xc5ff, 0xc5fe, 0xc5fd, 0xc5fc, 0xc5fb, 0xc5f9, 0xc5f8, 0xc5f7, + 0xc5f6, 0xc5f5, 0xc5f4, 0xc5f3, 0xc5f2, 0xc5f1, 0xc5f0, 0xc5ef, + 0xc5ee, 0xc5ed, 0xc5ec, 0xc5eb, 0xc5ea, 0xc5e9, 0xc5e8, 0xc5e7, + 0xc5e6, 0xc5e4, 0xc5e3, 0xc5e2, 0xc5e1, 0xc5e0, 0xc5df, 0xc5de, + 0xc5dd, 0xc5dc, 0xc5db, 0xc5da, 0xc5d9, 0xc5d8, 0xc5d7, 0xc5d6, + 0xc5d5, 0xc5d4, 0xc5d3, 0xc5d2, 0xc5d1, 0xc5d0, 0xc5cf, 0xc5ce, + 0xc5cd, 0xc5cc, 0xc5cb, 0xc5c9, 0xc5c8, 0xc5c7, 0xc5c6, 0xc5c5, + 0xc5c4, 0xc5c3, 0xc5c2, 0xc5c1, 0xc5c0, 0xc5bf, 0xc5be, 0xc5bd, + 0xc5bc, 0xc5bb, 0xc5ba, 0xc5b9, 0xc5b8, 0xc5b7, 0xc5b6, 0xc5b5, + 0xc5b4, 0xc5b3, 0xc5b2, 0xc5b1, 0xc5b0, 0xc5af, 0xc5ae, 0xc5ad, + 0xc5ac, 0xc5ab, 0xc5aa, 0xc5a9, 0xc5a8, 0xc5a7, 0xc5a6, 0xc5a5, + 0xc5a4, 0xc5a3, 0xc5a2, 0xc5a1, 0xc5a0, 0xc59f, 0xc59e, 0xc59d, + 0xc59c, 0xc59b, 0xc59a, 0xc599, 0xc598, 0xc597, 0xc596, 0xc595, + 0xc594, 0xc593, 0xc592, 0xc591, 0xc590, 0xc58f, 0xc58e, 0xc58d, + 0xc58c, 0xc58a, 0xc588, 0xc586, 0xc584, 0xc582, 0xc580, 0xc57e, + 0xc57c, 0xc57a, 0xc578, 0xc576, 0xc574, 0xc572, 0xc570, 0xc56e, + 0xc56c, 0xc56a, 0xc568, 0xc566, 0xc564, 0xc562, 0xc560, 0xc55e, + 0xc55c, 0xc55a, 0xc558, 0xc556, 0xc554, 0xc552, 0xc550, 0xc54e, + 0xc54d, 0xc54b, 0xc549, 0xc547, 0xc545, 0xc543, 0xc541, 0xc53f, + 0xc53d, 0xc53b, 0xc539, 0xc537, 0xc535, 0xc533, 0xc532, 0xc530, + 0xc52e, 0xc52c, 0xc52a, 0xc528, 0xc526, 0xc524, 0xc522, 0xc520, + 0xc51f, 0xc51d, 0xc51b, 0xc519, 0xc517, 0xc515, 0xc513, 0xc511, + 0xc50f, 0xc50e, 0xc50c, 0xc50a, 0xc508, 0xc506, 0xc504, 0xc502, + 0xc500, 0xc4ff, 0xc4fd, 0xc4fb, 0xc4f9, 0xc4f7, 0xc4f5, 0xc4f3, + 0xc4f2, 0xc4f0, 0xc4ee, 0xc4ec, 0xc4ea, 0xc4e8, 0xc4e6, 0xc4e5, + 0xc4e3, 0xc4e1, 0xc4df, 0xc4dd, 0xc4db, 0xc4da, 0xc4d8, 0xc4d6, + 0xc4d4, 0xc4d2, 0xc4d0, 0xc4cf, 0xc4cd, 0xc4cb, 0xc4c9, 0xc4c7, + 0xc4c5, 0xc4c4, 0xc4c2, 0xc4c0, 0xc4be, 0xc4bc, 0xc4bb, 0xc4b9, + 0xc4b7, 0xc4b5, 0xc4b3, 0xc4b2, 0xc4b0, 0xc4ae, 0xc4ac, 0xc4aa, + 0xc4a9, 0xc4a7, 0xc4a5, 0xc4a3, 0xc4a1, 0xc4a0, 0xc49e, 0xc49c, + 0xc49a, 0xc499, 0xc497, 0xc495, 0xc493, 0xc491, 0xc490, 0xc48e, + 0xc48c, 0xc48a, 0xc489, 0xc487, 0xc485, 0xc483, 0xc482, 0xc480, + 0xc47e, 0xc47c, 0xc47b, 0xc479, 0xc477, 0xc475, 0xc474, 0xc472, + 0xc470, 0xc46e, 0xc46d, 0xc46b, 0xc469, 0xc467, 0xc466, 0xc464, + 0xc462, 0xc461, 0xc45f, 0xc45d, 0xc45b, 0xc45a, 0xc458, 0xc456, + 0xc454, 0xc453, 0xc451, 0xc44f, 0xc44e, 0xc44c, 0xc44a, 0xc448, + 0xc447, 0xc445, 0xc443, 0xc442, 0xc440, 0xc43e, 0xc43d, 0xc43b, + 0xc439, 0xc437, 0xc436, 0xc434, 0xc432, 0xc431, 0xc42f, 0xc42d, + 0xc42c, 0xc42a, 0xc428, 0xc427, 0xc425, 0xc423, 0xc422, 0xc420, + 0xc41e, 0xc41d, 0xc41b, 0xc419, 0xc418, 0xc416, 0xc414, 0xc413, + 0xc411, 0xc40f, 0xc40e, 0xc40c, 0xc40a, 0xc409, 0xc407, 0xc405, + 0xc404, 0xc402, 0xc400, 0xc3fd, 0xc3fa, 0xc3f7, 0xc3f3, 0xc3f0, + 0xc3ed, 0xc3ea, 0xc3e6, 0xc3e3, 0xc3e0, 0xc3dc, 0xc3d9, 0xc3d6, + 0xc3d3, 0xc3cf, 0xc3cc, 0xc3c9, 0xc3c6, 0xc3c2, 0xc3bf, 0xc3bc, + 0xc3b9, 0xc3b5, 0xc3b2, 0xc3af, 0xc3ac, 0xc3a8, 0xc3a5, 0xc3a2, + 0xc39f, 0xc39c, 0xc398, 0xc395, 0xc392, 0xc38f, 0xc38c, 0xc388, + 0xc385, 0xc382, 0xc37f, 0xc37c, 0xc378, 0xc375, 0xc372, 0xc36f, + 0xc36c, 0xc368, 0xc365, 0xc362, 0xc35f, 0xc35c, 0xc359, 0xc355, + 0xc352, 0xc34f, 0xc34c, 0xc349, 0xc346, 0xc342, 0xc33f, 0xc33c, + 0xc339, 0xc336, 0xc333, 0xc330, 0xc32d, 0xc329, 0xc326, 0xc323, + 0xc320, 0xc31d, 0xc31a, 0xc317, 0xc314, 0xc310, 0xc30d, 0xc30a, + 0xc307, 0xc304, 0xc301, 0xc2fe, 0xc2fb, 0xc2f8, 0xc2f5, 0xc2f1, + 0xc2ee, 0xc2eb, 0xc2e8, 0xc2e5, 0xc2e2, 0xc2df, 0xc2dc, 0xc2d9, + 0xc2d6, 0xc2d3, 0xc2d0, 0xc2cd, 0xc2c9, 0xc2c6, 0xc2c3, 0xc2c0, + 0xc2bd, 0xc2ba, 0xc2b7, 0xc2b4, 0xc2b1, 0xc2ae, 0xc2ab, 0xc2a8, + 0xc2a5, 0xc2a2, 0xc29f, 0xc29c, 0xc299, 0xc296, 0xc293, 0xc290, + 0xc28d, 0xc28a, 0xc287, 0xc284, 0xc281, 0xc27e, 0xc27b, 0xc278, + 0xc275, 0xc272, 0xc26f, 0xc26c, 0xc269, 0xc266, 0xc263, 0xc260, + 0xc25d, 0xc25a, 0xc257, 0xc254, 0xc251, 0xc24e, 0xc24b, 0xc248, + 0xc245, 0xc242, 0xc23f, 0xc23c, 0xc239, 0xc236, 0xc233, 0xc230, + 0xc22e, 0xc22b, 0xc228, 0xc225, 0xc222, 0xc21f, 0xc21c, 0xc219, + 0xc216, 0xc213, 0xc210, 0xc20d, 0xc20a, 0xc207, 0xc205, 0xc202, + 0xc1ff, 0xc1fc, 0xc1f9, 0xc1f6, 0xc1f3, 0xc1f0, 0xc1ed, 0xc1ea, + 0xc1e8, 0xc1e5, 0xc1e2, 0xc1df, 0xc1dc, 0xc1d9, 0xc1d6, 0xc1d3, + 0xc1d0, 0xc1ce, 0xc1cb, 0xc1c8, 0xc1c5, 0xc1c2, 0xc1bf, 0xc1bc, + 0xc1ba, 0xc1b7, 0xc1b4, 0xc1b1, 0xc1ae, 0xc1ab, 0xc1a8, 0xc1a6, + 0xc1a3, 0xc1a0, 0xc19d, 0xc19a, 0xc197, 0xc194, 0xc192, 0xc18f, + 0xc18c, 0xc189, 0xc186, 0xc184, 0xc181, 0xc17e, 0xc17b, 0xc178, + 0xc175, 0xc173, 0xc170, 0xc16d, 0xc16a, 0xc167, 0xc165, 0xc162, + 0xc15f, 0xc15c, 0xc159, 0xc157, 0xc154, 0xc151, 0xc14e, 0xc14b, + 0xc149, 0xc146, 0xc143, 0xc140, 0xc13e, 0xc13b, 0xc138, 0xc135, + 0xc132, 0xc130, 0xc12d, 0xc12a, 0xc127, 0xc125, 0xc122, 0xc11f, + 0xc11c, 0xc11a, 0xc117, 0xc114, 0xc111, 0xc10f, 0xc10c, 0xc109, + 0xc106, 0xc104, 0xc101, 0xc0fe, 0xc0fb, 0xc0f9, 0xc0f6, 0xc0f3, + 0xc0f1, 0xc0ee, 0xc0eb, 0xc0e8, 0xc0e6, 0xc0e3, 0xc0e0, 0xc0de, + 0xc0db, 0xc0d8, 0xc0d5, 0xc0d3, 0xc0d0, 0xc0cd, 0xc0cb, 0xc0c8, + 0xc0c5, 0xc0c3, 0xc0c0, 0xc0bd, 0xc0ba, 0xc0b8, 0xc0b5, 0xc0b2, + 0xc0b0, 0xc0ad, 0xc0aa, 0xc0a8, 0xc0a5, 0xc0a2, 0xc0a0, 0xc09d, + 0xc09a, 0xc098, 0xc095, 0xc092, 0xc090, 0xc08d, 0xc08a, 0xc088, + 0xc085, 0xc082, 0xc080, 0xc07d, 0xc07a, 0xc078, 0xc075, 0xc073, + 0xc070, 0xc06d, 0xc06b, 0xc068, 0xc065, 0xc063, 0xc060, 0xc05d, + 0xc05b, 0xc058, 0xc056, 0xc053, 0xc050, 0xc04e, 0xc04b, 0xc049, + 0xc046, 0xc043, 0xc041, 0xc03e, 0xc03b, 0xc039, 0xc036, 0xc034, + 0xc031, 0xc02e, 0xc02c, 0xc029, 0xc027, 0xc024, 0xc021, 0xc01f, + 0xc01c, 0xc01a, 0xc017, 0xc015, 0xc012, 0xc00f, 0xc00d, 0xc00a, + 0xc008, 0xc005, 0xc003, 0xc000, 0xbffb, 0xbff6, 0xbff1, 0xbfeb, + 0xbfe6, 0xbfe1, 0xbfdc, 0xbfd7, 0xbfd2, 0xbfcd, 0xbfc8, 0xbfc3, + 0xbfbd, 0xbfb8, 0xbfb3, 0xbfae, 0xbfa9, 0xbfa4, 0xbf9f, 0xbf9a, + 0xbf95, 0xbf90, 0xbf8b, 0xbf86, 0xbf81, 0xbf7b, 0xbf76, 0xbf71, + 0xbf6c, 0xbf67, 0xbf62, 0xbf5d, 0xbf58, 0xbf53, 0xbf4e, 0xbf49, + 0xbf44, 0xbf3f, 0xbf3a, 0xbf35, 0xbf30, 0xbf2b, 0xbf26, 0xbf21, + 0xbf1c, 0xbf17, 0xbf12, 0xbf0d, 0xbf08, 0xbf03, 0xbefe, 0xbef9, + 0xbef4, 0xbeef, 0xbeea, 0xbee5, 0xbee0, 0xbedb, 0xbed6, 0xbed1, + 0xbecc, 0xbec8, 0xbec3, 0xbebe, 0xbeb9, 0xbeb4, 0xbeaf, 0xbeaa, + 0xbea5, 0xbea0, 0xbe9b, 0xbe96, 0xbe91, 0xbe8c, 0xbe87, 0xbe83, + 0xbe7e, 0xbe79, 0xbe74, 0xbe6f, 0xbe6a, 0xbe65, 0xbe60, 0xbe5b, + 0xbe57, 0xbe52, 0xbe4d, 0xbe48, 0xbe43, 0xbe3e, 0xbe39, 0xbe35, + 0xbe30, 0xbe2b, 0xbe26, 0xbe21, 0xbe1c, 0xbe17, 0xbe13, 0xbe0e, + 0xbe09, 0xbe04, 0xbdff, 0xbdfa, 0xbdf6, 0xbdf1, 0xbdec, 0xbde7, + 0xbde2, 0xbdde, 0xbdd9, 0xbdd4, 0xbdcf, 0xbdca, 0xbdc6, 0xbdc1, + 0xbdbc, 0xbdb7, 0xbdb2, 0xbdae, 0xbda9, 0xbda4, 0xbd9f, 0xbd9b, + 0xbd96, 0xbd91, 0xbd8c, 0xbd88, 0xbd83, 0xbd7e, 0xbd79, 0xbd75, + 0xbd70, 0xbd6b, 0xbd66, 0xbd62, 0xbd5d, 0xbd58, 0xbd53, 0xbd4f, + 0xbd4a, 0xbd45, 0xbd41, 0xbd3c, 0xbd37, 0xbd32, 0xbd2e, 0xbd29, + 0xbd24, 0xbd20, 0xbd1b, 0xbd16, 0xbd12, 0xbd0d, 0xbd08, 0xbd03, + 0xbcff, 0xbcfa, 0xbcf5, 0xbcf1, 0xbcec, 0xbce7, 0xbce3, 0xbcde, + 0xbcd9, 0xbcd5, 0xbcd0, 0xbccc, 0xbcc7, 0xbcc2, 0xbcbe, 0xbcb9, + 0xbcb4, 0xbcb0, 0xbcab, 0xbca6, 0xbca2, 0xbc9d, 0xbc99, 0xbc94, + 0xbc8f, 0xbc8b, 0xbc86, 0xbc82, 0xbc7d, 0xbc78, 0xbc74, 0xbc6f, + 0xbc6b, 0xbc66, 0xbc61, 0xbc5d, 0xbc58, 0xbc54, 0xbc4f, 0xbc4a, + 0xbc46, 0xbc41, 0xbc3d, 0xbc38, 0xbc34, 0xbc2f, 0xbc2b, 0xbc26, + 0xbc21, 0xbc1d, 0xbc18, 0xbc14, 0xbc0f, 0xbc0b, 0xbc06, 0xbc02, + 0xbbfa, 0xbbf1, 0xbbe8, 0xbbdf, 0xbbd6, 0xbbcd, 0xbbc4, 0xbbbb, + 0xbbb2, 0xbba9, 0xbba0, 0xbb97, 0xbb8e, 0xbb85, 0xbb7c, 0xbb73, + 0xbb6a, 0xbb61, 0xbb58, 0xbb4f, 0xbb46, 0xbb3d, 0xbb34, 0xbb2b, + 0xbb22, 0xbb19, 0xbb10, 0xbb07, 0xbafe, 0xbaf5, 0xbaed, 0xbae4, + 0xbadb, 0xbad2, 0xbac9, 0xbac0, 0xbab7, 0xbaae, 0xbaa5, 0xba9c, + 0xba94, 0xba8b, 0xba82, 0xba79, 0xba70, 0xba67, 0xba5f, 0xba56, + 0xba4d, 0xba44, 0xba3b, 0xba32, 0xba2a, 0xba21, 0xba18, 0xba0f, + 0xba06, 0xb9fe, 0xb9f5, 0xb9ec, 0xb9e3, 0xb9da, 0xb9d2, 0xb9c9, + 0xb9c0, 0xb9b7, 0xb9af, 0xb9a6, 0xb99d, 0xb995, 0xb98c, 0xb983, + 0xb97a, 0xb972, 0xb969, 0xb960, 0xb958, 0xb94f, 0xb946, 0xb93d, + 0xb935, 0xb92c, 0xb923, 0xb91b, 0xb912, 0xb909, 0xb901, 0xb8f8, + 0xb8ef, 0xb8e7, 0xb8de, 0xb8d6, 0xb8cd, 0xb8c4, 0xb8bc, 0xb8b3, + 0xb8ab, 0xb8a2, 0xb899, 0xb891, 0xb888, 0xb880, 0xb877, 0xb86e, + 0xb866, 0xb85d, 0xb855, 0xb84c, 0xb844, 0xb83b, 0xb832, 0xb82a, + 0xb821, 0xb819, 0xb810, 0xb808, 0xb7ff, 0xb7ee, 0xb7dd, 0xb7cc, + 0xb7bb, 0xb7aa, 0xb799, 0xb788, 0xb777, 0xb766, 0xb755, 0xb744, + 0xb733, 0xb722, 0xb711, 0xb700, 0xb6ef, 0xb6de, 0xb6cd, 0xb6bd, + 0xb6ac, 0xb69b, 0xb68a, 0xb679, 0xb668, 0xb658, 0xb647, 0xb636, + 0xb625, 0xb614, 0xb604, 0xb5f3, 0xb5e2, 0xb5d1, 0xb5c1, 0xb5b0, + 0xb59f, 0xb58e, 0xb57e, 0xb56d, 0xb55c, 0xb54c, 0xb53b, 0xb52a, + 0xb51a, 0xb509, 0xb4f8, 0xb4e8, 0xb4d7, 0xb4c7, 0xb4b6, 0xb4a5, + 0xb495, 0xb484, 0xb474, 0xb463, 0xb452, 0xb442, 0xb431, 0xb421, + 0xb410, 0xb400, 0xb3df, 0xb3be, 0xb39d, 0xb37c, 0xb35b, 0xb33a, + 0xb319, 0xb2f8, 0xb2d7, 0xb2b6, 0xb295, 0xb275, 0xb254, 0xb233, + 0xb212, 0xb1f2, 0xb1d1, 0xb1b0, 0xb18f, 0xb16f, 0xb14e, 0xb12d, + 0xb10d, 0xb0ec, 0xb0cb, 0xb0ab, 0xb08a, 0xb06a, 0xb049, 0xb029, + 0xb008, 0xafcf, 0xaf8e, 0xaf4d, 0xaf0c, 0xaecb, 0xae8b, 0xae4a, + 0xae09, 0xadc8, 0xad88, 0xad47, 0xad06, 0xacc6, 0xac85, 0xac45, + 0xac04, 0xab87, 0xab06, 0xaa85, 0xaa05, 0xa984, 0xa903, 0xa883, + 0xa802, 0xa703, 0xa602, 0xa502, 0xa401, 0xa201, 0xa001, 0x9c00, + 0x0000, 0x1fff, 0x23fe, 0x25fe, 0x27fc, 0x28fd, 0x29fc, 0x2afa, + 0x2bf8, 0x2c7b, 0x2cfa, 0x2d78, 0x2df7, 0x2e76, 0x2ef4, 0x2f72, + 0x2ff0, 0x3037, 0x3076, 0x30b5, 0x30f4, 0x3132, 0x3171, 0x31b0, + 0x31ee, 0x322d, 0x326b, 0x32aa, 0x32e8, 0x3326, 0x3364, 0x33a3, + 0x33e1, 0x340f, 0x342e, 0x344d, 0x346c, 0x348b, 0x34aa, 0x34c9, + 0x34e8, 0x3506, 0x3525, 0x3544, 0x3563, 0x3581, 0x35a0, 0x35bf, + 0x35dd, 0x35fc, 0x361a, 0x3639, 0x3657, 0x3676, 0x3694, 0x36b2, + 0x36d1, 0x36ef, 0x370d, 0x372c, 0x374a, 0x3768, 0x3786, 0x37a4, + 0x37c3, 0x37e1, 0x37ff, 0x380e, 0x381d, 0x382c, 0x383b, 0x384a, + 0x3859, 0x3868, 0x3877, 0x3886, 0x3895, 0x38a4, 0x38b3, 0x38c2, + 0x38d0, 0x38df, 0x38ee, 0x38fd, 0x390c, 0x391a, 0x3929, 0x3938, + 0x3947, 0x3955, 0x3964, 0x3973, 0x3982, 0x3990, 0x399f, 0x39ae, + 0x39bc, 0x39cb, 0x39d9, 0x39e8, 0x39f7, 0x3a05, 0x3a14, 0x3a22, + 0x3a31, 0x3a3f, 0x3a4e, 0x3a5c, 0x3a6b, 0x3a79, 0x3a88, 0x3a96, + 0x3aa5, 0x3ab3, 0x3ac1, 0x3ad0, 0x3ade, 0x3aed, 0x3afb, 0x3b09, + 0x3b18, 0x3b26, 0x3b34, 0x3b42, 0x3b51, 0x3b5f, 0x3b6d, 0x3b7c, + 0x3b8a, 0x3b98, 0x3ba6, 0x3bb4, 0x3bc3, 0x3bd1, 0x3bdf, 0x3bed, + 0x3bfb, 0x3c05, 0x3c0c, 0x3c13, 0x3c1a, 0x3c21, 0x3c28, 0x3c2f, + 0x3c36, 0x3c3d, 0x3c44, 0x3c4b, 0x3c52, 0x3c59, 0x3c60, 0x3c67, + 0x3c6e, 0x3c75, 0x3c7c, 0x3c83, 0x3c8a, 0x3c91, 0x3c97, 0x3c9e, + 0x3ca5, 0x3cac, 0x3cb3, 0x3cba, 0x3cc1, 0x3cc8, 0x3ccf, 0x3cd6, + 0x3cdc, 0x3ce3, 0x3cea, 0x3cf1, 0x3cf8, 0x3cff, 0x3d06, 0x3d0c, + 0x3d13, 0x3d1a, 0x3d21, 0x3d28, 0x3d2f, 0x3d35, 0x3d3c, 0x3d43, + 0x3d4a, 0x3d51, 0x3d57, 0x3d5e, 0x3d65, 0x3d6c, 0x3d72, 0x3d79, + 0x3d80, 0x3d87, 0x3d8d, 0x3d94, 0x3d9b, 0x3da1, 0x3da8, 0x3daf, + 0x3db6, 0x3dbc, 0x3dc3, 0x3dca, 0x3dd0, 0x3dd7, 0x3dde, 0x3de4, + 0x3deb, 0x3df2, 0x3df8, 0x3dff, 0x3e05, 0x3e0c, 0x3e13, 0x3e19, + 0x3e20, 0x3e27, 0x3e2d, 0x3e34, 0x3e3a, 0x3e41, 0x3e47, 0x3e4e, + 0x3e55, 0x3e5b, 0x3e62, 0x3e68, 0x3e6f, 0x3e75, 0x3e7c, 0x3e82, + 0x3e89, 0x3e8f, 0x3e96, 0x3e9c, 0x3ea3, 0x3ea9, 0x3eb0, 0x3eb6, + 0x3ebd, 0x3ec3, 0x3eca, 0x3ed0, 0x3ed7, 0x3edd, 0x3ee4, 0x3eea, + 0x3ef1, 0x3ef7, 0x3efe, 0x3f04, 0x3f0a, 0x3f11, 0x3f17, 0x3f1e, + 0x3f24, 0x3f2a, 0x3f31, 0x3f37, 0x3f3e, 0x3f44, 0x3f4a, 0x3f51, + 0x3f57, 0x3f5d, 0x3f64, 0x3f6a, 0x3f70, 0x3f77, 0x3f7d, 0x3f83, + 0x3f8a, 0x3f90, 0x3f96, 0x3f9d, 0x3fa3, 0x3fa9, 0x3fb0, 0x3fb6, + 0x3fbc, 0x3fc2, 0x3fc9, 0x3fcf, 0x3fd5, 0x3fdc, 0x3fe2, 0x3fe8, + 0x3fee, 0x3ff5, 0x3ffb, 0x4000, 0x4004, 0x4007, 0x400a, 0x400d, + 0x4010, 0x4013, 0x4016, 0x4019, 0x401c, 0x4020, 0x4023, 0x4026, + 0x4029, 0x402c, 0x402f, 0x4032, 0x4035, 0x4038, 0x403b, 0x403e, + 0x4041, 0x4044, 0x4048, 0x404b, 0x404e, 0x4051, 0x4054, 0x4057, + 0x405a, 0x405d, 0x4060, 0x4063, 0x4066, 0x4069, 0x406c, 0x406f, + 0x4072, 0x4075, 0x4078, 0x407b, 0x407e, 0x4081, 0x4084, 0x4087, + 0x408a, 0x408d, 0x4090, 0x4093, 0x4096, 0x4099, 0x409c, 0x409f, + 0x40a2, 0x40a5, 0x40a8, 0x40ab, 0x40ae, 0x40b1, 0x40b4, 0x40b7, + 0x40ba, 0x40bd, 0x40c0, 0x40c3, 0x40c6, 0x40c9, 0x40cc, 0x40cf, + 0x40d2, 0x40d5, 0x40d8, 0x40db, 0x40de, 0x40e1, 0x40e4, 0x40e7, + 0x40ea, 0x40ed, 0x40ef, 0x40f2, 0x40f5, 0x40f8, 0x40fb, 0x40fe, + 0x4101, 0x4104, 0x4107, 0x410a, 0x410d, 0x4110, 0x4113, 0x4115, + 0x4118, 0x411b, 0x411e, 0x4121, 0x4124, 0x4127, 0x412a, 0x412d, + 0x4130, 0x4132, 0x4135, 0x4138, 0x413b, 0x413e, 0x4141, 0x4144, + 0x4147, 0x414a, 0x414c, 0x414f, 0x4152, 0x4155, 0x4158, 0x415b, + 0x415e, 0x4160, 0x4163, 0x4166, 0x4169, 0x416c, 0x416f, 0x4172, + 0x4174, 0x4177, 0x417a, 0x417d, 0x4180, 0x4183, 0x4185, 0x4188, + 0x418b, 0x418e, 0x4191, 0x4194, 0x4196, 0x4199, 0x419c, 0x419f, + 0x41a2, 0x41a5, 0x41a7, 0x41aa, 0x41ad, 0x41b0, 0x41b3, 0x41b5, + 0x41b8, 0x41bb, 0x41be, 0x41c1, 0x41c3, 0x41c6, 0x41c9, 0x41cc, + 0x41ce, 0x41d1, 0x41d4, 0x41d7, 0x41da, 0x41dc, 0x41df, 0x41e2, + 0x41e5, 0x41e7, 0x41ea, 0x41ed, 0x41f0, 0x41f2, 0x41f5, 0x41f8, + 0x41fb, 0x41fd, 0x4200, 0x4203, 0x4206, 0x4208, 0x420b, 0x420e, + 0x4211, 0x4213, 0x4216, 0x4219, 0x421c, 0x421e, 0x4221, 0x4224, + 0x4227, 0x4229, 0x422c, 0x422f, 0x4231, 0x4234, 0x4237, 0x423a, + 0x423c, 0x423f, 0x4242, 0x4244, 0x4247, 0x424a, 0x424d, 0x424f, + 0x4252, 0x4255, 0x4257, 0x425a, 0x425d, 0x425f, 0x4262, 0x4265, + 0x4267, 0x426a, 0x426d, 0x426f, 0x4272, 0x4275, 0x4277, 0x427a, + 0x427d, 0x427f, 0x4282, 0x4285, 0x4287, 0x428a, 0x428d, 0x428f, + 0x4292, 0x4295, 0x4297, 0x429a, 0x429d, 0x429f, 0x42a2, 0x42a5, + 0x42a7, 0x42aa, 0x42ad, 0x42af, 0x42b2, 0x42b4, 0x42b7, 0x42ba, + 0x42bc, 0x42bf, 0x42c2, 0x42c4, 0x42c7, 0x42c9, 0x42cc, 0x42cf, + 0x42d1, 0x42d4, 0x42d6, 0x42d9, 0x42dc, 0x42de, 0x42e1, 0x42e3, + 0x42e6, 0x42e9, 0x42eb, 0x42ee, 0x42f0, 0x42f3, 0x42f6, 0x42f8, + 0x42fb, 0x42fd, 0x4300, 0x4303, 0x4305, 0x4308, 0x430a, 0x430d, + 0x430f, 0x4312, 0x4315, 0x4317, 0x431a, 0x431c, 0x431f, 0x4321, + 0x4324, 0x4327, 0x4329, 0x432c, 0x432e, 0x4331, 0x4333, 0x4336, + 0x4338, 0x433b, 0x433e, 0x4340, 0x4343, 0x4345, 0x4348, 0x434a, + 0x434d, 0x434f, 0x4352, 0x4354, 0x4357, 0x4359, 0x435c, 0x435e, + 0x4361, 0x4363, 0x4366, 0x4369, 0x436b, 0x436e, 0x4370, 0x4373, + 0x4375, 0x4378, 0x437a, 0x437d, 0x437f, 0x4382, 0x4384, 0x4387, + 0x4389, 0x438c, 0x438e, 0x4391, 0x4393, 0x4396, 0x4398, 0x439b, + 0x439d, 0x43a0, 0x43a2, 0x43a5, 0x43a7, 0x43a9, 0x43ac, 0x43ae, + 0x43b1, 0x43b3, 0x43b6, 0x43b8, 0x43bb, 0x43bd, 0x43c0, 0x43c2, + 0x43c5, 0x43c7, 0x43ca, 0x43cc, 0x43ce, 0x43d1, 0x43d3, 0x43d6, + 0x43d8, 0x43db, 0x43dd, 0x43e0, 0x43e2, 0x43e5, 0x43e7, 0x43e9, + 0x43ec, 0x43ee, 0x43f1, 0x43f3, 0x43f6, 0x43f8, 0x43fa, 0x43fd, + 0x43ff, 0x4401, 0x4402, 0x4403, 0x4404, 0x4406, 0x4407, 0x4408, + 0x4409, 0x440b, 0x440c, 0x440d, 0x440e, 0x440f, 0x4411, 0x4412, + 0x4413, 0x4414, 0x4415, 0x4417, 0x4418, 0x4419, 0x441a, 0x441b, + 0x441d, 0x441e, 0x441f, 0x4420, 0x4421, 0x4423, 0x4424, 0x4425, + 0x4426, 0x4427, 0x4428, 0x442a, 0x442b, 0x442c, 0x442d, 0x442e, + 0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4436, 0x4437, 0x4438, + 0x4439, 0x443a, 0x443b, 0x443d, 0x443e, 0x443f, 0x4440, 0x4441, + 0x4442, 0x4444, 0x4445, 0x4446, 0x4447, 0x4448, 0x444a, 0x444b, + 0x444c, 0x444d, 0x444e, 0x444f, 0x4451, 0x4452, 0x4453, 0x4454, + 0x4455, 0x4456, 0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, + 0x445e, 0x4460, 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4467, + 0x4468, 0x4469, 0x446a, 0x446b, 0x446c, 0x446d, 0x446f, 0x4470, + 0x4471, 0x4472, 0x4473, 0x4474, 0x4476, 0x4477, 0x4478, 0x4479, + 0x447a, 0x447b, 0x447c, 0x447e, 0x447f, 0x4480, 0x4481, 0x4482, + 0x4483, 0x4484, 0x4485, 0x4487, 0x4488, 0x4489, 0x448a, 0x448b, + 0x448c, 0x448d, 0x448f, 0x4490, 0x4491, 0x4492, 0x4493, 0x4494, + 0x4495, 0x4496, 0x4498, 0x4499, 0x449a, 0x449b, 0x449c, 0x449d, + 0x449e, 0x449f, 0x44a1, 0x44a2, 0x44a3, 0x44a4, 0x44a5, 0x44a6, + 0x44a7, 0x44a8, 0x44aa, 0x44ab, 0x44ac, 0x44ad, 0x44ae, 0x44af, + 0x44b0, 0x44b1, 0x44b2, 0x44b4, 0x44b5, 0x44b6, 0x44b7, 0x44b8, + 0x44b9, 0x44ba, 0x44bb, 0x44bc, 0x44be, 0x44bf, 0x44c0, 0x44c1, + 0x44c2, 0x44c3, 0x44c4, 0x44c5, 0x44c6, 0x44c7, 0x44c9, 0x44ca, + 0x44cb, 0x44cc, 0x44cd, 0x44ce, 0x44cf, 0x44d0, 0x44d1, 0x44d2, + 0x44d4, 0x44d5, 0x44d6, 0x44d7, 0x44d8, 0x44d9, 0x44da, 0x44db, + 0x44dc, 0x44dd, 0x44de, 0x44e0, 0x44e1, 0x44e2, 0x44e3, 0x44e4, + 0x44e5, 0x44e6, 0x44e7, 0x44e8, 0x44e9, 0x44ea, 0x44eb, 0x44ed, + 0x44ee, 0x44ef, 0x44f0, 0x44f1, 0x44f2, 0x44f3, 0x44f4, 0x44f5, + 0x44f6, 0x44f7, 0x44f8, 0x44f9, 0x44fb, 0x44fc, 0x44fd, 0x44fe, + 0x44ff, 0x4500, 0x4501, 0x4502, 0x4503, 0x4504, 0x4505, 0x4506, + 0x4507, 0x4508, 0x450a, 0x450b, 0x450c, 0x450d, 0x450e, 0x450f, + 0x4510, 0x4511, 0x4512, 0x4513, 0x4514, 0x4515, 0x4516, 0x4517, + 0x4518, 0x4519, 0x451b, 0x451c, 0x451d, 0x451e, 0x451f, 0x4520, + 0x4521, 0x4522, 0x4523, 0x4524, 0x4525, 0x4526, 0x4527, 0x4528, + 0x4529, 0x452a, 0x452b, 0x452c, 0x452d, 0x452e, 0x4530, 0x4531, + 0x4532, 0x4533, 0x4534, 0x4535, 0x4536, 0x4537, 0x4538, 0x4539, + 0x453a, 0x453b, 0x453c, 0x453d, 0x453e, 0x453f, 0x4540, 0x4541, + 0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548, 0x454a, + 0x454b, 0x454c, 0x454d, 0x454e, 0x454f, 0x4550, 0x4551, 0x4552, + 0x4553, 0x4554, 0x4555, 0x4556, 0x4557, 0x4558, 0x4559, 0x455a, + 0x455b, 0x455c, 0x455d, 0x455e, 0x455f, 0x4560, 0x4561, 0x4562, + 0x4563, 0x4564, 0x4565, 0x4566, 0x4567, 0x4568, 0x4569, 0x456a, + 0x456b, 0x456c, 0x456d, 0x456e, 0x456f, 0x4570, 0x4571, 0x4572, + 0x4573, 0x4574, 0x4575, 0x4576, 0x4577, 0x4578, 0x4579, 0x457a, + 0x457c, 0x457d, 0x457e, 0x457f, 0x4580, 0x4581, 0x4582, 0x4583, + 0x4584, 0x4585, 0x4586, 0x4587, 0x4588, 0x4589, 0x458a, 0x458b, + 0x458c, 0x458e, 0x4590, 0x4592, 0x4594, 0x4596, 0x4598, 0x459a, + 0x459c, 0x459d, 0x459f, 0x45a1, 0x45a3, 0x45a5, 0x45a7, 0x45a9, + 0x45ab, 0x45ad, 0x45af, 0x45b1, 0x45b3, 0x45b5, 0x45b7, 0x45b9, + 0x45bb, 0x45bd, 0x45bf, 0x45c1, 0x45c3, 0x45c5, 0x45c7, 0x45c9, + 0x45cb, 0x45cd, 0x45ce, 0x45d0, 0x45d2, 0x45d4, 0x45d6, 0x45d8, + 0x45da, 0x45dc, 0x45de, 0x45e0, 0x45e2, 0x45e4, 0x45e6, 0x45e7, + 0x45e9, 0x45eb, 0x45ed, 0x45ef, 0x45f1, 0x45f3, 0x45f5, 0x45f7, + 0x45f9, 0x45fb, 0x45fc, 0x45fe, 0x4600, 0x4602, 0x4604, 0x4606, + 0x4608, 0x460a, 0x460b, 0x460d, 0x460f, 0x4611, 0x4613, 0x4615, + 0x4617, 0x4619, 0x461a, 0x461c, 0x461e, 0x4620, 0x4622, 0x4624, + 0x4626, 0x4627, 0x4629, 0x462b, 0x462d, 0x462f, 0x4631, 0x4633, + 0x4634, 0x4636, 0x4638, 0x463a, 0x463c, 0x463e, 0x463f, 0x4641, + 0x4643, 0x4645, 0x4647, 0x4649, 0x464a, 0x464c, 0x464e, 0x4650, + 0x4652, 0x4653, 0x4655, 0x4657, 0x4659, 0x465b, 0x465d, 0x465e, + 0x4660, 0x4662, 0x4664, 0x4666, 0x4667, 0x4669, 0x466b, 0x466d, + 0x466f, 0x4670, 0x4672, 0x4674, 0x4676, 0x4677, 0x4679, 0x467b, + 0x467d, 0x467f, 0x4680, 0x4682, 0x4684, 0x4686, 0x4687, 0x4689, + 0x468b, 0x468d, 0x468e, 0x4690, 0x4692, 0x4694, 0x4696, 0x4697, + 0x4699, 0x469b, 0x469d, 0x469e, 0x46a0, 0x46a2, 0x46a4, 0x46a5, + 0x46a7, 0x46a9, 0x46aa, 0x46ac, 0x46ae, 0x46b0, 0x46b1, 0x46b3, + 0x46b5, 0x46b7, 0x46b8, 0x46ba, 0x46bc, 0x46be, 0x46bf, 0x46c1, + 0x46c3, 0x46c4, 0x46c6, 0x46c8, 0x46ca, 0x46cb, 0x46cd, 0x46cf, + 0x46d0, 0x46d2, 0x46d4, 0x46d6, 0x46d7, 0x46d9, 0x46db, 0x46dc, + 0x46de, 0x46e0, 0x46e1, 0x46e3, 0x46e5, 0x46e6, 0x46e8, 0x46ea, + 0x46ec, 0x46ed, 0x46ef, 0x46f1, 0x46f2, 0x46f4, 0x46f6, 0x46f7, + 0x46f9, 0x46fb, 0x46fc, 0x46fe, 0x4700, 0x4701, 0x4703, 0x4705, + 0x4706, 0x4708, 0x470a, 0x470b, 0x470d, 0x470f, 0x4710, 0x4712, + 0x4714, 0x4715, 0x4717, 0x4718, 0x471a, 0x471c, 0x471d, 0x471f, + 0x4721, 0x4722, 0x4724, 0x4726, 0x4727, 0x4729, 0x472b, 0x472c, + 0x472e, 0x472f, 0x4731, 0x4733, 0x4734, 0x4736, 0x4738, 0x4739, + 0x473b, 0x473c, 0x473e, 0x4740, 0x4741, 0x4743, 0x4745, 0x4746, + 0x4748, 0x4749, 0x474b, 0x474d, 0x474e, 0x4750, 0x4751, 0x4753, + 0x4755, 0x4756, 0x4758, 0x4759, 0x475b, 0x475d, 0x475e, 0x4760, + 0x4761, 0x4763, 0x4765, 0x4766, 0x4768, 0x4769, 0x476b, 0x476c, + 0x476e, 0x4770, 0x4771, 0x4773, 0x4774, 0x4776, 0x4777, 0x4779, + 0x477b, 0x477c, 0x477e, 0x477f, 0x4781, 0x4782, 0x4784, 0x4786, + 0x4787, 0x4789, 0x478a, 0x478c, 0x478d, 0x478f, 0x4790, 0x4792, + 0x4794, 0x4795, 0x4797, 0x4798, 0x479a, 0x479b, 0x479d, 0x479e, + 0x47a0, 0x47a2, 0x47a3, 0x47a5, 0x47a6, 0x47a8, 0x47a9, 0x47ab, + 0x47ac, 0x47ae, 0x47af, 0x47b1, 0x47b2, 0x47b4, 0x47b5, 0x47b7, + 0x47b8, 0x47ba, 0x47bc, 0x47bd, 0x47bf, 0x47c0, 0x47c2, 0x47c3, + 0x47c5, 0x47c6, 0x47c8, 0x47c9, 0x47cb, 0x47cc, 0x47ce, 0x47cf, + 0x47d1, 0x47d2, 0x47d4, 0x47d5, 0x47d7, 0x47d8, 0x47da, 0x47db, + 0x47dd, 0x47de, 0x47e0, 0x47e1, 0x47e3, 0x47e4, 0x47e6, 0x47e7, + 0x47e9, 0x47ea, 0x47ec, 0x47ed, 0x47ef, 0x47f0, 0x47f2, 0x47f3, + 0x47f5, 0x47f6, 0x47f8, 0x47f9, 0x47fa, 0x47fc, 0x47fd, 0x47ff, + 0x4800, 0x4801, 0x4802, 0x4802, 0x4803, 0x4804, 0x4805, 0x4805, + 0x4806, 0x4807, 0x4808, 0x4808, 0x4809, 0x480a, 0x480a, 0x480b, + 0x480c, 0x480d, 0x480d, 0x480e, 0x480f, 0x4810, 0x4810, 0x4811, + 0x4812, 0x4812, 0x4813, 0x4814, 0x4815, 0x4815, 0x4816, 0x4817, + 0x4817, 0x4818, 0x4819, 0x481a, 0x481a, 0x481b, 0x481c, 0x481c, + 0x481d, 0x481e, 0x481f, 0x481f, 0x4820, 0x4821, 0x4821, 0x4822, + 0x4823, 0x4824, 0x4824, 0x4825, 0x4826, 0x4826, 0x4827, 0x4828, + 0x4829, 0x4829, 0x482a, 0x482b, 0x482b, 0x482c, 0x482d, 0x482e, + 0x482e, 0x482f, 0x4830, 0x4830, 0x4831, 0x4832, 0x4832, 0x4833, + 0x4834, 0x4835, 0x4835, 0x4836, 0x4837, 0x4837, 0x4838, 0x4839, + 0x4839, 0x483a, 0x483b, 0x483b, 0x483c, 0x483d, 0x483e, 0x483e, + 0x483f, 0x4840, 0x4840, 0x4841, 0x4842, 0x4842, 0x4843, 0x4844, + 0x4844, 0x4845, 0x4846, 0x4847, 0x4847, 0x4848, 0x4849, 0x4849, + 0x484a, 0x484b, 0x484b, 0x484c, 0x484d, 0x484d, 0x484e, 0x484f, + 0x484f, 0x4850, 0x4851, 0x4851, 0x4852, 0x4853, 0x4853, 0x4854, + 0x4855, 0x4856, 0x4856, 0x4857, 0x4858, 0x4858, 0x4859, 0x485a, + 0x485a, 0x485b, 0x485c, 0x485c, 0x485d, 0x485e, 0x485e, 0x485f, + 0x4860, 0x4860, 0x4861, 0x4862, 0x4862, 0x4863, 0x4864, 0x4864, + 0x4865, 0x4866, 0x4866, 0x4867, 0x4868, 0x4868, 0x4869, 0x486a, + 0x486a, 0x486b, 0x486c, 0x486c, 0x486d, 0x486e, 0x486e, 0x486f, + 0x4870, 0x4870, 0x4871, 0x4872, 0x4872, 0x4873, 0x4874, 0x4874, + 0x4875, 0x4876, 0x4876, 0x4877, 0x4877, 0x4878, 0x4879, 0x4879, + 0x487a, 0x487b, 0x487b, 0x487c, 0x487d, 0x487d, 0x487e, 0x487f, + 0x487f, 0x4880, 0x4881, 0x4881, 0x4882, 0x4883, 0x4883, 0x4884, + 0x4884, 0x4885, 0x4886, 0x4886, 0x4887, 0x4888, 0x4888, 0x4889, + 0x488a, 0x488a, 0x488b, 0x488c, 0x488c, 0x488d, 0x488d, 0x488e, + 0x488f, 0x488f, 0x4890, 0x4891, 0x4891, 0x4892, 0x4893, 0x4893, + 0x4894, 0x4895, 0x4895, 0x4896, 0x4896, 0x4897, 0x4898, 0x4898, + 0x4899, 0x489a, 0x489a, 0x489b, 0x489c, 0x489c, 0x489d, 0x489d, + 0x489e, 0x489f, 0x489f, 0x48a0, 0x48a1, 0x48a1, 0x48a2, 0x48a2, + 0x48a3, 0x48a4, 0x48a4, 0x48a5, 0x48a6, 0x48a6, 0x48a7, 0x48a7, + 0x48a8, 0x48a9, 0x48a9, 0x48aa, 0x48ab, 0x48ab, 0x48ac, 0x48ac, + 0x48ad, 0x48ae, 0x48ae, 0x48af, 0x48b0, 0x48b0, 0x48b1, 0x48b1, + 0x48b2, 0x48b3, 0x48b3, 0x48b4, 0x48b4, 0x48b5, 0x48b6, 0x48b6, + 0x48b7, 0x48b8, 0x48b8, 0x48b9, 0x48b9, 0x48ba, 0x48bb, 0x48bb, + 0x48bc, 0x48bc, 0x48bd, 0x48be, 0x48be, 0x48bf, 0x48c0, 0x48c0, + 0x48c1, 0x48c1, 0x48c2, 0x48c3, 0x48c3, 0x48c4, 0x48c4, 0x48c5, + 0x48c6, 0x48c6, 0x48c7, 0x48c7, 0x48c8, 0x48c9, 0x48c9, 0x48ca, + 0x48ca, 0x48cb, 0x48cc, 0x48cc, 0x48cd, 0x48cd, 0x48ce, 0x48cf, + 0x48cf, 0x48d0, 0x48d0, 0x48d1, 0x48d2, 0x48d2, 0x48d3, 0x48d3, + 0x48d4, 0x48d5, 0x48d5, 0x48d6, 0x48d6, 0x48d7, 0x48d8, 0x48d8, + 0x48d9, 0x48d9, 0x48da, 0x48db, 0x48db, 0x48dc, 0x48dc, 0x48dd, + 0x48de, 0x48de, 0x48df, 0x48df, 0x48e0, 0x48e1, 0x48e1, 0x48e2, + 0x48e2, 0x48e3, 0x48e3, 0x48e4, 0x48e5, 0x48e5, 0x48e6, 0x48e6, + 0x48e7, 0x48e8, 0x48e8, 0x48e9, 0x48e9, 0x48ea, 0x48eb, 0x48eb, + 0x48ec, 0x48ec, 0x48ed, 0x48ed, 0x48ee, 0x48ef, 0x48ef, 0x48f0, + 0x48f0, 0x48f1, 0x48f2, 0x48f2, 0x48f3, 0x48f3, 0x48f4, 0x48f4, + 0x48f5, 0x48f6, 0x48f6, 0x48f7, 0x48f7, 0x48f8, 0x48f8, 0x48f9, + 0x48fa, 0x48fa, 0x48fb, 0x48fb, 0x48fc, 0x48fd, 0x48fd, 0x48fe, + 0x48fe, 0x48ff, 0x48ff, 0x4900, 0x4901, 0x4901, 0x4902, 0x4902, + 0x4903, 0x4903, 0x4904, 0x4905, 0x4905, 0x4906, 0x4906, 0x4907, + 0x4907, 0x4908, 0x4909, 0x4909, 0x490a, 0x490a, 0x490b, 0x490b, + 0x490c, 0x490c, 0x490d, 0x490e, 0x490e, 0x490f, 0x490f, 0x4910, + 0x4910, 0x4911, 0x4912, 0x4912, 0x4913, 0x4913, 0x4914, 0x4914, + 0x4915, 0x4916, 0x4916, 0x4917, 0x4917, 0x4918, 0x4918, 0x4919, + 0x4919, 0x491a, 0x491b, 0x491b, 0x491c, 0x491c, 0x491d, 0x491d, + 0x491e, 0x491e, 0x491f, 0x4920, 0x4920, 0x4921, 0x4921, 0x4922, + 0x4922, 0x4923, 0x4923, 0x4924, 0x4925, 0x4925, 0x4926, 0x4926, + 0x4927, 0x4927, 0x4928, 0x4928, 0x4929, 0x492a, 0x492a, 0x492b, + 0x492b, 0x492c, 0x492c, 0x492d, 0x492d, 0x492e, 0x492e, 0x492f, + 0x4930, 0x4930, 0x4931, 0x4931, 0x4932, 0x4932, 0x4933, 0x4933, + 0x4934, 0x4934, 0x4935, 0x4936, 0x4936, 0x4937, 0x4937, 0x4938, + 0x4938, 0x4939, 0x4939, 0x493a, 0x493a, 0x493b, 0x493c, 0x493c, + 0x493d, 0x493d, 0x493e, 0x493e, 0x493f, 0x493f, 0x4940, 0x4940, + 0x4941, 0x4941, 0x4942, 0x4943, 0x4943, 0x4944, 0x4944, 0x4945, + 0x4945, 0x4946, 0x4946, 0x4947, 0x4947, 0x4948, 0x4948, 0x4949, + 0x4949, 0x494a, 0x494b, 0x494b, 0x494c, 0x494c, 0x494d, 0x494d, + 0x494e, 0x494e, 0x494f, 0x494f, 0x4950, 0x4950, 0x4951, 0x4951, + 0x4952, 0x4953, 0x4953, 0x4954, 0x4954, 0x4955, 0x4955, 0x4956, + 0x4956, 0x4957, 0x4957, 0x4958, 0x4958, 0x4959, 0x4959, 0x495a, + 0x495a, 0x495b, 0x495b, 0x495c, 0x495d, 0x495d, 0x495e, 0x495e, + 0x495f, 0x495f, 0x4960, 0x4960, 0x4961, 0x4961, 0x4962, 0x4962, + 0x4963, 0x4963, 0x4964, 0x4964, 0x4965, 0x4965, 0x4966, 0x4966, + 0x4967, 0x4967, 0x4968, 0x4968, 0x4969, 0x496a, 0x496a, 0x496b, + 0x496b, 0x496c, 0x496c, 0x496d, 0x496d, 0x496e, 0x496e, 0x496f, + 0x496f, 0x4970, 0x4970, 0x4971, 0x4971, 0x4972, 0x4972, 0x4973, + 0x4973, 0x4974, 0x4974, 0x4975, 0x4975, 0x4976, 0x4976, 0x4977, + 0x4977, 0x4978, 0x4978, 0x4979, 0x4979, 0x497a, 0x497a, 0x497b, + 0x497b, 0x497c, 0x497c, 0x497d, 0x497d, 0x497e, 0x497e, 0x497f, + 0x497f, 0x4980, 0x4981, 0x4981, 0x4982, 0x4982, 0x4983, 0x4983, + 0x4984, 0x4984, 0x4985, 0x4985, 0x4986, 0x4986, 0x4987, 0x4987, + 0x4988, 0x4988, 0x4989, 0x4989, 0x498a, 0x498a, 0x498b, 0x498b, + 0x498c, 0x498d, 0x498e, 0x498f, 0x4990, 0x4991, 0x4992, 0x4993, + 0x4994, 0x4995, 0x4996, 0x4997, 0x4997, 0x4998, 0x4999, 0x499a, + 0x499b, 0x499c, 0x499d, 0x499e, 0x499f, 0x49a0, 0x49a1, 0x49a2, + 0x49a3, 0x49a4, 0x49a5, 0x49a6, 0x49a7, 0x49a8, 0x49a9, 0x49aa, + 0x49ab, 0x49ac, 0x49ad, 0x49ae, 0x49af, 0x49b0, 0x49b1, 0x49b2, + 0x49b3, 0x49b4, 0x49b5, 0x49b6, 0x49b7, 0x49b8, 0x49b9, 0x49ba, + 0x49ba, 0x49bb, 0x49bc, 0x49bd, 0x49be, 0x49bf, 0x49c0, 0x49c1, + 0x49c2, 0x49c3, 0x49c4, 0x49c5, 0x49c6, 0x49c7, 0x49c8, 0x49c9, + 0x49ca, 0x49cb, 0x49cc, 0x49cc, 0x49cd, 0x49ce, 0x49cf, 0x49d0, + 0x49d1, 0x49d2, 0x49d3, 0x49d4, 0x49d5, 0x49d6, 0x49d7, 0x49d8, + 0x49d9, 0x49da, 0x49da, 0x49db, 0x49dc, 0x49dd, 0x49de, 0x49df, + 0x49e0, 0x49e1, 0x49e2, 0x49e3, 0x49e4, 0x49e5, 0x49e5, 0x49e6, + 0x49e7, 0x49e8, 0x49e9, 0x49ea, 0x49eb, 0x49ec, 0x49ed, 0x49ee, + 0x49ef, 0x49f0, 0x49f0, 0x49f1, 0x49f2, 0x49f3, 0x49f4, 0x49f5, + 0x49f6, 0x49f7, 0x49f8, 0x49f9, 0x49f9, 0x49fa, 0x49fb, 0x49fc, + 0x49fd, 0x49fe, 0x49ff, 0x4a00, 0x4a01, 0x4a02, 0x4a02, 0x4a03, + 0x4a04, 0x4a05, 0x4a06, 0x4a07, 0x4a08, 0x4a09, 0x4a09, 0x4a0a, + 0x4a0b, 0x4a0c, 0x4a0d, 0x4a0e, 0x4a0f, 0x4a10, 0x4a11, 0x4a11, + 0x4a12, 0x4a13, 0x4a14, 0x4a15, 0x4a16, 0x4a17, 0x4a18, 0x4a18, + 0x4a19, 0x4a1a, 0x4a1b, 0x4a1c, 0x4a1d, 0x4a1e, 0x4a1f, 0x4a1f, + 0x4a20, 0x4a21, 0x4a22, 0x4a23, 0x4a24, 0x4a25, 0x4a25, 0x4a26, + 0x4a27, 0x4a28, 0x4a29, 0x4a2a, 0x4a2b, 0x4a2b, 0x4a2c, 0x4a2d, + 0x4a2e, 0x4a2f, 0x4a30, 0x4a31, 0x4a31, 0x4a32, 0x4a33, 0x4a34, + 0x4a35, 0x4a36, 0x4a36, 0x4a37, 0x4a38, 0x4a39, 0x4a3a, 0x4a3b, + 0x4a3c, 0x4a3c, 0x4a3d, 0x4a3e, 0x4a3f, 0x4a40, 0x4a41, 0x4a41, + 0x4a42, 0x4a43, 0x4a44, 0x4a45, 0x4a46, 0x4a46, 0x4a47, 0x4a48, + 0x4a49, 0x4a4a, 0x4a4b, 0x4a4b, 0x4a4c, 0x4a4d, 0x4a4e, 0x4a4f, + 0x4a50, 0x4a50, 0x4a51, 0x4a52, 0x4a53, 0x4a54, 0x4a54, 0x4a55, + 0x4a56, 0x4a57, 0x4a58, 0x4a59, 0x4a59, 0x4a5a, 0x4a5b, 0x4a5c, + 0x4a5d, 0x4a5d, 0x4a5e, 0x4a5f, 0x4a60, 0x4a61, 0x4a62, 0x4a62, + 0x4a63, 0x4a64, 0x4a65, 0x4a66, 0x4a66, 0x4a67, 0x4a68, 0x4a69, + 0x4a6a, 0x4a6a, 0x4a6b, 0x4a6c, 0x4a6d, 0x4a6e, 0x4a6e, 0x4a6f, + 0x4a70, 0x4a71, 0x4a72, 0x4a72, 0x4a73, 0x4a74, 0x4a75, 0x4a76, + 0x4a76, 0x4a77, 0x4a78, 0x4a79, 0x4a7a, 0x4a7a, 0x4a7b, 0x4a7c, + 0x4a7d, 0x4a7e, 0x4a7e, 0x4a7f, 0x4a80, 0x4a81, 0x4a82, 0x4a82, + 0x4a83, 0x4a84, 0x4a85, 0x4a85, 0x4a86, 0x4a87, 0x4a88, 0x4a89, + 0x4a89, 0x4a8a, 0x4a8b, 0x4a8c, 0x4a8c, 0x4a8d, 0x4a8e, 0x4a8f, + 0x4a90, 0x4a90, 0x4a91, 0x4a92, 0x4a93, 0x4a93, 0x4a94, 0x4a95, + 0x4a96, 0x4a97, 0x4a97, 0x4a98, 0x4a99, 0x4a9a, 0x4a9a, 0x4a9b, + 0x4a9c, 0x4a9d, 0x4a9d, 0x4a9e, 0x4a9f, 0x4aa0, 0x4aa1, 0x4aa1, + 0x4aa2, 0x4aa3, 0x4aa4, 0x4aa4, 0x4aa5, 0x4aa6, 0x4aa7, 0x4aa7, + 0x4aa8, 0x4aa9, 0x4aaa, 0x4aaa, 0x4aab, 0x4aac, 0x4aad, 0x4aad, + 0x4aae, 0x4aaf, 0x4ab0, 0x4ab0, 0x4ab1, 0x4ab2, 0x4ab3, 0x4ab3, + 0x4ab4, 0x4ab5, 0x4ab6, 0x4ab6, 0x4ab7, 0x4ab8, 0x4ab9, 0x4ab9, + 0x4aba, 0x4abb, 0x4abc, 0x4abc, 0x4abd, 0x4abe, 0x4abf, 0x4abf, + 0x4ac0, 0x4ac1, 0x4ac2, 0x4ac2, 0x4ac3, 0x4ac4, 0x4ac4, 0x4ac5, + 0x4ac6, 0x4ac7, 0x4ac7, 0x4ac8, 0x4ac9, 0x4aca, 0x4aca, 0x4acb, + 0x4acc, 0x4acd, 0x4acd, 0x4ace, 0x4acf, 0x4acf, 0x4ad0, 0x4ad1, + 0x4ad2, 0x4ad2, 0x4ad3, 0x4ad4, 0x4ad5, 0x4ad5, 0x4ad6, 0x4ad7, + 0x4ad7, 0x4ad8, 0x4ad9, 0x4ada, 0x4ada, 0x4adb, 0x4adc, 0x4add, + 0x4add, 0x4ade, 0x4adf, 0x4adf, 0x4ae0, 0x4ae1, 0x4ae2, 0x4ae2, + 0x4ae3, 0x4ae4, 0x4ae4, 0x4ae5, 0x4ae6, 0x4ae7, 0x4ae7, 0x4ae8, + 0x4ae9, 0x4ae9, 0x4aea, 0x4aeb, 0x4aec, 0x4aec, 0x4aed, 0x4aee, + 0x4aee, 0x4aef, 0x4af0, 0x4af0, 0x4af1, 0x4af2, 0x4af3, 0x4af3, + 0x4af4, 0x4af5, 0x4af5, 0x4af6, 0x4af7, 0x4af7, 0x4af8, 0x4af9, + 0x4afa, 0x4afa, 0x4afb, 0x4afc, 0x4afc, 0x4afd, 0x4afe, 0x4afe, + 0x4aff, 0x4b00, 0x4b01, 0x4b01, 0x4b02, 0x4b03, 0x4b03, 0x4b04, + 0x4b05, 0x4b05, 0x4b06, 0x4b07, 0x4b07, 0x4b08, 0x4b09, 0x4b0a, + 0x4b0a, 0x4b0b, 0x4b0c, 0x4b0c, 0x4b0d, 0x4b0e, 0x4b0e, 0x4b0f, + 0x4b10, 0x4b10, 0x4b11, 0x4b12, 0x4b12, 0x4b13, 0x4b14, 0x4b15, + 0x4b15, 0x4b16, 0x4b17, 0x4b17, 0x4b18, 0x4b19, 0x4b19, 0x4b1a, + 0x4b1b, 0x4b1b, 0x4b1c, 0x4b1d, 0x4b1d, 0x4b1e, 0x4b1f, 0x4b1f, + 0x4b20, 0x4b21, 0x4b21, 0x4b22, 0x4b23, 0x4b23, 0x4b24, 0x4b25, + 0x4b25, 0x4b26, 0x4b27, 0x4b27, 0x4b28, 0x4b29, 0x4b29, 0x4b2a, + 0x4b2b, 0x4b2b, 0x4b2c, 0x4b2d, 0x4b2d, 0x4b2e, 0x4b2f, 0x4b2f, + 0x4b30, 0x4b31, 0x4b31, 0x4b32, 0x4b33, 0x4b33, 0x4b34, 0x4b35, + 0x4b35, 0x4b36, 0x4b37, 0x4b37, 0x4b38, 0x4b39, 0x4b39, 0x4b3a, + 0x4b3b, 0x4b3b, 0x4b3c, 0x4b3d, 0x4b3d, 0x4b3e, 0x4b3f, 0x4b3f, + 0x4b40, 0x4b41, 0x4b41, 0x4b42, 0x4b42, 0x4b43, 0x4b44, 0x4b44, + 0x4b45, 0x4b46, 0x4b46, 0x4b47, 0x4b48, 0x4b48, 0x4b49, 0x4b4a, + 0x4b4a, 0x4b4b, 0x4b4c, 0x4b4c, 0x4b4d, 0x4b4d, 0x4b4e, 0x4b4f, + 0x4b4f, 0x4b50, 0x4b51, 0x4b51, 0x4b52, 0x4b53, 0x4b53, 0x4b54, + 0x4b55, 0x4b55, 0x4b56, 0x4b56, 0x4b57, 0x4b58, 0x4b58, 0x4b59, + 0x4b5a, 0x4b5a, 0x4b5b, 0x4b5c, 0x4b5c, 0x4b5d, 0x4b5d, 0x4b5e, + 0x4b5f, 0x4b5f, 0x4b60, 0x4b61, 0x4b61, 0x4b62, 0x4b63, 0x4b63, + 0x4b64, 0x4b64, 0x4b65, 0x4b66, 0x4b66, 0x4b67, 0x4b68, 0x4b68, + 0x4b69, 0x4b69, 0x4b6a, 0x4b6b, 0x4b6b, 0x4b6c, 0x4b6d, 0x4b6d, + 0x4b6e, 0x4b6e, 0x4b6f, 0x4b70, 0x4b70, 0x4b71, 0x4b72, 0x4b72, + 0x4b73, 0x4b73, 0x4b74, 0x4b75, 0x4b75, 0x4b76, 0x4b77, 0x4b77, + 0x4b78, 0x4b78, 0x4b79, 0x4b7a, 0x4b7a, 0x4b7b, 0x4b7b, 0x4b7c, + 0x4b7d, 0x4b7d, 0x4b7e, 0x4b7f, 0x4b7f, 0x4b80, 0x4b80, 0x4b81, + 0x4b82, 0x4b82, 0x4b83, 0x4b83, 0x4b84, 0x4b85, 0x4b85, 0x4b86, + 0x4b87, 0x4b87, 0x4b88, 0x4b88, 0x4b89, 0x4b8a, 0x4b8a, 0x4b8b, + 0x4b8b, 0x4b8c, 0x4b8d, 0x4b8d, 0x4b8e, 0x4b8e, 0x4b8f, 0x4b90, + 0x4b90, 0x4b91, 0x4b91, 0x4b92, 0x4b93, 0x4b93, 0x4b94, 0x4b94, + 0x4b95, 0x4b96, 0x4b96, 0x4b97, 0x4b97, 0x4b98, 0x4b99, 0x4b99, + 0x4b9a, 0x4b9a, 0x4b9b, 0x4b9c, 0x4b9c, 0x4b9d, 0x4b9d, 0x4b9e, + 0x4b9f, 0x4b9f, 0x4ba0, 0x4ba0, 0x4ba1, 0x4ba2, 0x4ba2, 0x4ba3, + 0x4ba3, 0x4ba4, 0x4ba5, 0x4ba5, 0x4ba6, 0x4ba6, 0x4ba7, 0x4ba8, + 0x4ba8, 0x4ba9, 0x4ba9, 0x4baa, 0x4baa, 0x4bab, 0x4bac, 0x4bac, + 0x4bad, 0x4bad, 0x4bae, 0x4baf, 0x4baf, 0x4bb0, 0x4bb0, 0x4bb1, + 0x4bb1, 0x4bb2, 0x4bb3, 0x4bb3, 0x4bb4, 0x4bb4, 0x4bb5, 0x4bb6, + 0x4bb6, 0x4bb7, 0x4bb7, 0x4bb8, 0x4bb8, 0x4bb9, 0x4bba, 0x4bba, + 0x4bbb, 0x4bbb, 0x4bbc, 0x4bbd, 0x4bbd, 0x4bbe, 0x4bbe, 0x4bbf, + 0x4bbf, 0x4bc0, 0x4bc1, 0x4bc1, 0x4bc2, 0x4bc2, 0x4bc3, 0x4bc3, + 0x4bc4, 0x4bc5, 0x4bc5, 0x4bc6, 0x4bc6, 0x4bc7, 0x4bc7, 0x4bc8, + 0x4bc9, 0x4bc9, 0x4bca, 0x4bca, 0x4bcb, 0x4bcb, 0x4bcc, 0x4bcd, + 0x4bcd, 0x4bce, 0x4bce, 0x4bcf, 0x4bcf, 0x4bd0, 0x4bd1, 0x4bd1, + 0x4bd2, 0x4bd2, 0x4bd3, 0x4bd3, 0x4bd4, 0x4bd5, 0x4bd5, 0x4bd6, + 0x4bd6, 0x4bd7, 0x4bd7, 0x4bd8, 0x4bd8, 0x4bd9, 0x4bda, 0x4bda, + 0x4bdb, 0x4bdb, 0x4bdc, 0x4bdc, 0x4bdd, 0x4bde, 0x4bde, 0x4bdf, + 0x4bdf, 0x4be0, 0x4be0, 0x4be1, 0x4be1, 0x4be2, 0x4be3, 0x4be3, + 0x4be4, 0x4be4, 0x4be5, 0x4be5, 0x4be6, 0x4be6, 0x4be7, 0x4be8, + 0x4be8, 0x4be9, 0x4be9, 0x4bea, 0x4bea, 0x4beb, 0x4beb, 0x4bec, + 0x4bed, 0x4bed, 0x4bee, 0x4bee, 0x4bef, 0x4bef, 0x4bf0, 0x4bf0, + 0x4bf1, 0x4bf1, 0x4bf2, 0x4bf3, 0x4bf3, 0x4bf4, 0x4bf4, 0x4bf5, + 0x4bf5, 0x4bf6, 0x4bf6, 0x4bf7, 0x4bf8, 0x4bf8, 0x4bf9, 0x4bf9, + 0x4bfa, 0x4bfa, 0x4bfb, 0x4bfb, 0x4bfc, 0x4bfc, 0x4bfd, 0x4bfe, + 0x4bfe, 0x4bff, 0x4bff, 0x4c00, 0x4c00, 0x4c00, 0x4c01, 0x4c01, + 0x4c01, 0x4c01, 0x4c02, 0x4c02, 0x4c02, 0x4c03, 0x4c03, 0x4c03, + 0x4c03, 0x4c04, 0x4c04, 0x4c04, 0x4c04, 0x4c05, 0x4c05, 0x4c05, + 0x4c05, 0x4c06, 0x4c06, 0x4c06, 0x4c07, 0x4c07, 0x4c07, 0x4c07, + 0x4c08, 0x4c08, 0x4c08, 0x4c08, 0x4c09, 0x4c09, 0x4c09, 0x4c09, + 0x4c0a, 0x4c0a, 0x4c0a, 0x4c0b, 0x4c0b, 0x4c0b, 0x4c0b, 0x4c0c, + 0x4c0c, 0x4c0c, 0x4c0c, 0x4c0d, 0x4c0d, 0x4c0d, 0x4c0d, 0x4c0e, + 0x4c0e, 0x4c0e, 0x4c0f, 0x4c0f, 0x4c0f, 0x4c0f, 0x4c10, 0x4c10, + 0x4c10, 0x4c10, 0x4c11, 0x4c11, 0x4c11, 0x4c11, 0x4c12, 0x4c12, + 0x4c12, 0x4c12, 0x4c13, 0x4c13, 0x4c13, 0x4c13, 0x4c14, 0x4c14, + 0x4c14, 0x4c15, 0x4c15, 0x4c15, 0x4c15, 0x4c16, 0x4c16, 0x4c16, + 0x4c16, 0x4c17, 0x4c17, 0x4c17, 0x4c17, 0x4c18, 0x4c18, 0x4c18, + 0x4c18, 0x4c19, 0x4c19, 0x4c19, 0x4c19, 0x4c1a, 0x4c1a, 0x4c1a, + 0x4c1a, 0x4c1b, 0x4c1b, 0x4c1b, 0x4c1c, 0x4c1c, 0x4c1c, 0x4c1c, + 0x4c1d, 0x4c1d, 0x4c1d, 0x4c1d, 0x4c1e, 0x4c1e, 0x4c1e, 0x4c1e, + 0x4c1f, 0x4c1f, 0x4c1f, 0x4c1f, 0x4c20, 0x4c20, 0x4c20, 0x4c20, + 0x4c21, 0x4c21, 0x4c21, 0x4c21, 0x4c22, 0x4c22, 0x4c22, 0x4c22, + 0x4c23, 0x4c23, 0x4c23, 0x4c23, 0x4c24, 0x4c24, 0x4c24, 0x4c24, + 0x4c25, 0x4c25, 0x4c25, 0x4c25, 0x4c26, 0x4c26, 0x4c26, 0x4c26, + 0x4c27, 0x4c27, 0x4c27, 0x4c27, 0x4c28, 0x4c28, 0x4c28, 0x4c28, + 0x4c29, 0x4c29, 0x4c2a, 0x4c2a, 0x4c2b, 0x4c2b, 0x4c2c, 0x4c2c, + 0x4c2d, 0x4c2d, 0x4c2e, 0x4c2e, 0x4c2f, 0x4c2f, 0x4c30, 0x4c30, + 0x4c31, 0x4c31, 0x4c32, 0x4c32, 0x4c33, 0x4c33, 0x4c34, 0x4c34, + 0x4c35, 0x4c35, 0x4c36, 0x4c36, 0x4c36, 0x4c37, 0x4c37, 0x4c38, + 0x4c38, 0x4c39, 0x4c39, 0x4c3a, 0x4c3a, 0x4c3b, 0x4c3b, 0x4c3c, + 0x4c3c, 0x4c3d, 0x4c3d, 0x4c3e, 0x4c3e, 0x4c3f, 0x4c3f, 0x4c40, + 0x4c40, 0x4c41, 0x4c41, 0x4c42, 0x4c42, 0x4c43, 0x4c43, 0x4c43, + 0x4c44, 0x4c44, 0x4c45, 0x4c45, 0x4c46, 0x4c46, 0x4c47, 0x4c47, + 0x4c48, 0x4c48, 0x4c49, 0x4c49, 0x4c4a, 0x4c4a, 0x4c4b, 0x4c4b, + 0x4c4b, 0x4c4c, 0x4c4c, 0x4c4d, 0x4c4d, 0x4c4e, 0x4c4e, 0x4c4f, + 0x4c4f, 0x4c50, 0x4c50, 0x4c51, 0x4c51, 0x4c52, 0x4c52, 0x4c52, + 0x4c53, 0x4c53, 0x4c54, 0x4c54, 0x4c55, 0x4c55, 0x4c56, 0x4c56, + 0x4c57, 0x4c57, 0x4c57, 0x4c58, 0x4c58, 0x4c59, 0x4c59, 0x4c5a, + 0x4c5a, 0x4c5b, 0x4c5b, 0x4c5c, 0x4c5c, 0x4c5c, 0x4c5d, 0x4c5d, + 0x4c5e, 0x4c5e, 0x4c5f, 0x4c5f, 0x4c60, 0x4c60, 0x4c61, 0x4c61, + 0x4c61, 0x4c62, 0x4c62, 0x4c63, 0x4c63, 0x4c64, 0x4c64, 0x4c65, + 0x4c65, 0x4c65, 0x4c66, 0x4c66, 0x4c67, 0x4c67, 0x4c68, 0x4c68, + 0x4c69, 0x4c69, 0x4c69, 0x4c6a, 0x4c6a, 0x4c6b, 0x4c6b, 0x4c6c, + 0x4c6c, 0x4c6c, 0x4c6d, 0x4c6d, 0x4c6e, 0x4c6e, 0x4c6f, 0x4c6f, + 0x4c70, 0x4c70, 0x4c70, 0x4c71, 0x4c71, 0x4c72, 0x4c72, 0x4c73, + 0x4c73, 0x4c73, 0x4c74, 0x4c74, 0x4c75, 0x4c75, 0x4c76, 0x4c76, + 0x4c76, 0x4c77, 0x4c77, 0x4c78, 0x4c78, 0x4c79, 0x4c79, 0x4c79, + 0x4c7a, 0x4c7a, 0x4c7b, 0x4c7b, 0x4c7c, 0x4c7c, 0x4c7c, 0x4c7d, + 0x4c7d, 0x4c7e, 0x4c7e, 0x4c7f, 0x4c7f, 0x4c7f, 0x4c80, 0x4c80, + 0x4c81, 0x4c81, 0x4c82, 0x4c82, 0x4c82, 0x4c83, 0x4c83, 0x4c84, + 0x4c84, 0x4c84, 0x4c85, 0x4c85, 0x4c86, 0x4c86, 0x4c87, 0x4c87, + 0x4c87, 0x4c88, 0x4c88, 0x4c89, 0x4c89, 0x4c89, 0x4c8a, 0x4c8a, + 0x4c8b, 0x4c8b, 0x4c8b, 0x4c8c, 0x4c8c, 0x4c8d, 0x4c8d, 0x4c8e, + 0x4c8e, 0x4c8e, 0x4c8f, 0x4c8f, 0x4c90, 0x4c90, 0x4c90, 0x4c91, + 0x4c91, 0x4c92, 0x4c92, 0x4c92, 0x4c93, 0x4c93, 0x4c94, 0x4c94, + 0x4c94, 0x4c95, 0x4c95, 0x4c96, 0x4c96, 0x4c97, 0x4c97, 0x4c97, + 0x4c98, 0x4c98, 0x4c99, 0x4c99, 0x4c99, 0x4c9a, 0x4c9a, 0x4c9b, + 0x4c9b, 0x4c9b, 0x4c9c, 0x4c9c, 0x4c9d, 0x4c9d, 0x4c9d, 0x4c9e, + 0x4c9e, 0x4c9f, 0x4c9f, 0x4c9f, 0x4ca0, 0x4ca0, 0x4ca0, 0x4ca1, + 0x4ca1, 0x4ca2, 0x4ca2, 0x4ca2, 0x4ca3, 0x4ca3, 0x4ca4, 0x4ca4, + 0x4ca4, 0x4ca5, 0x4ca5, 0x4ca6, 0x4ca6, 0x4ca6, 0x4ca7, 0x4ca7, + 0x4ca8, 0x4ca8, 0x4ca8, 0x4ca9, 0x4ca9, 0x4caa, 0x4caa, 0x4caa, + 0x4cab, 0x4cab, 0x4cab, 0x4cac, 0x4cac, 0x4cad, 0x4cad, 0x4cad, + 0x4cae, 0x4cae, 0x4caf, 0x4caf, 0x4caf, 0x4cb0, 0x4cb0, 0x4cb0, + 0x4cb1, 0x4cb1, 0x4cb2, 0x4cb2, 0x4cb2, 0x4cb3, 0x4cb3, 0x4cb4, + 0x4cb4, 0x4cb4, 0x4cb5, 0x4cb5, 0x4cb5, 0x4cb6, 0x4cb6, 0x4cb7, + 0x4cb7, 0x4cb7, 0x4cb8, 0x4cb8, 0x4cb8, 0x4cb9, 0x4cb9, 0x4cba, + 0x4cba, 0x4cba, 0x4cbb, 0x4cbb, 0x4cbb, 0x4cbc, 0x4cbc, 0x4cbd, + 0x4cbd, 0x4cbd, 0x4cbe, 0x4cbe, 0x4cbe, 0x4cbf, 0x4cbf, 0x4cc0, + 0x4cc0, 0x4cc0, 0x4cc1, 0x4cc1, 0x4cc1, 0x4cc2, 0x4cc2, 0x4cc3, + 0x4cc3, 0x4cc3, 0x4cc4, 0x4cc4, 0x4cc4, 0x4cc5, 0x4cc5, 0x4cc6, + 0x4cc6, 0x4cc6, 0x4cc7, 0x4cc7, 0x4cc7, 0x4cc8, 0x4cc8, 0x4cc8, + 0x4cc9, 0x4cc9, 0x4cca, 0x4cca, 0x4cca, 0x4ccb, 0x4ccb, 0x4ccb, + 0x4ccc, 0x4ccc, 0x4ccc, 0x4ccd, 0x4ccd, 0x4cce, 0x4cce, 0x4cce, + 0x4ccf, 0x4ccf, 0x4ccf, 0x4cd0, 0x4cd0, 0x4cd0, 0x4cd1, 0x4cd1, + 0x4cd2, 0x4cd2, 0x4cd2, 0x4cd3, 0x4cd3, 0x4cd3, 0x4cd4, 0x4cd4, + 0x4cd4, 0x4cd5, 0x4cd5, 0x4cd5, 0x4cd6, 0x4cd6, 0x4cd7, 0x4cd7, + 0x4cd7, 0x4cd8, 0x4cd8, 0x4cd8, 0x4cd9, 0x4cd9, 0x4cd9, 0x4cda, + 0x4cda, 0x4cda, 0x4cdb, 0x4cdb, 0x4cdb, 0x4cdc, 0x4cdc, 0x4cdd, + 0x4cdd, 0x4cdd, 0x4cde, 0x4cde, 0x4cde, 0x4cdf, 0x4cdf, 0x4cdf, + 0x4ce0, 0x4ce0, 0x4ce0, 0x4ce1, 0x4ce1, 0x4ce1, 0x4ce2, 0x4ce2, + 0x4ce2, 0x4ce3, 0x4ce3, 0x4ce4, 0x4ce4, 0x4ce4, 0x4ce5, 0x4ce5, + 0x4ce5, 0x4ce6, 0x4ce6, 0x4ce6, 0x4ce7, 0x4ce7, 0x4ce7, 0x4ce8, + 0x4ce8, 0x4ce8, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cea, 0x4cea, 0x4cea, + 0x4ceb, 0x4ceb, 0x4ceb, 0x4cec, 0x4cec, 0x4cec, 0x4ced, 0x4ced, + 0x4ced, 0x4cee, 0x4cee, 0x4cef, 0x4cef, 0x4cef, 0x4cf0, 0x4cf0, + 0x4cf0, 0x4cf1, 0x4cf1, 0x4cf1, 0x4cf2, 0x4cf2, 0x4cf2, 0x4cf3, + 0x4cf3, 0x4cf3, 0x4cf4, 0x4cf4, 0x4cf4, 0x4cf5, 0x4cf5, 0x4cf5, + 0x4cf6, 0x4cf6, 0x4cf6, 0x4cf7, 0x4cf7, 0x4cf7, 0x4cf8, 0x4cf8, + 0x4cf8, 0x4cf9, 0x4cf9, 0x4cf9, 0x4cfa, 0x4cfa, 0x4cfa, 0x4cfb, + 0x4cfb, 0x4cfb, 0x4cfc, 0x4cfc, 0x4cfc, 0x4cfd, 0x4cfd, 0x4cfd, + 0x4cfe, 0x4cfe, 0x4cfe, 0x4cff, 0x4cff, 0x4cff, 0x4d00, 0x4d00, + 0x4d00, 0x4d01, 0x4d01, 0x4d01, 0x4d02, 0x4d02, 0x4d02, 0x4d03, + 0x4d03, 0x4d03, 0x4d03, 0x4d04, 0x4d04, 0x4d04, 0x4d05, 0x4d05, + 0x4d05, 0x4d06, 0x4d06, 0x4d06, 0x4d07, 0x4d07, 0x4d07, 0x4d08, + 0x4d08, 0x4d08, 0x4d09, 0x4d09, 0x4d09, 0x4d0a, 0x4d0a, 0x4d0a, + 0x4d0b, 0x4d0b, 0x4d0b, 0x4d0c, 0x4d0c, 0x4d0c, 0x4d0d, 0x4d0d, + 0x4d0d, 0x4d0d, 0x4d0e, 0x4d0e, 0x4d0e, 0x4d0f, 0x4d0f, 0x4d0f, + 0x4d10, 0x4d10, 0x4d10, 0x4d11, 0x4d11, 0x4d11, 0x4d12, 0x4d12, + 0x4d12, 0x4d13, 0x4d13, 0x4d13, 0x4d14, 0x4d14, 0x4d14, 0x4d14, + 0x4d15, 0x4d15, 0x4d15, 0x4d16, 0x4d16, 0x4d16, 0x4d17, 0x4d17, + 0x4d17, 0x4d18, 0x4d18, 0x4d18, 0x4d19, 0x4d19, 0x4d19, 0x4d1a, + 0x4d1a, 0x4d1a, 0x4d1a, 0x4d1b, 0x4d1b, 0x4d1b, 0x4d1c, 0x4d1c, + 0x4d1c, 0x4d1d, 0x4d1d, 0x4d1d, 0x4d1e, 0x4d1e, 0x4d1e, 0x4d1e, + 0x4d1f, 0x4d1f, 0x4d1f, 0x4d20, 0x4d20, 0x4d20, 0x4d21, 0x4d21, + 0x4d21, 0x4d22, 0x4d22, 0x4d22, 0x4d22, 0x4d23, 0x4d23, 0x4d23, + 0x4d24, 0x4d24, 0x4d24, 0x4d25, 0x4d25, 0x4d25, 0x4d26, 0x4d26, + 0x4d26, 0x4d26, 0x4d27, 0x4d27, 0x4d27, 0x4d28, 0x4d28, 0x4d28, + 0x4d29, 0x4d29, 0x4d29, 0x4d29, 0x4d2a, 0x4d2a, 0x4d2a, 0x4d2b, + 0x4d2b, 0x4d2b, 0x4d2c, 0x4d2c, 0x4d2c, 0x4d2d, 0x4d2d, 0x4d2d, + 0x4d2d, 0x4d2e, 0x4d2e, 0x4d2e, 0x4d2f, 0x4d2f, 0x4d2f, 0x4d30, + 0x4d30, 0x4d30, 0x4d30, 0x4d31, 0x4d31, 0x4d31, 0x4d32, 0x4d32, + 0x4d32, 0x4d32, 0x4d33, 0x4d33, 0x4d33, 0x4d34, 0x4d34, 0x4d34, + 0x4d35, 0x4d35, 0x4d35, 0x4d35, 0x4d36, 0x4d36, 0x4d36, 0x4d37, + 0x4d37, 0x4d37, 0x4d38, 0x4d38, 0x4d38, 0x4d38, 0x4d39, 0x4d39, + 0x4d39, 0x4d3a, 0x4d3a, 0x4d3a, 0x4d3a, 0x4d3b, 0x4d3b, 0x4d3b, + 0x4d3c, 0x4d3c, 0x4d3c, 0x4d3d, 0x4d3d, 0x4d3d, 0x4d3d, 0x4d3e, + 0x4d3e, 0x4d3e, 0x4d3f, 0x4d3f, 0x4d3f, 0x4d3f, 0x4d40, 0x4d40, + 0x4d40, 0x4d41, 0x4d41, 0x4d41, 0x4d41, 0x4d42, 0x4d42, 0x4d42, + 0x4d43, 0x4d43, 0x4d43, 0x4d43, 0x4d44, 0x4d44, 0x4d44, 0x4d45, + 0x4d45, 0x4d45, 0x4d45, 0x4d46, 0x4d46, 0x4d46, 0x4d47, 0x4d47, + 0x4d47, 0x4d47, 0x4d48, 0x4d48, 0x4d48, 0x4d49, 0x4d49, 0x4d49, + 0x4d49, 0x4d4a, 0x4d4a, 0x4d4a, 0x4d4b, 0x4d4b, 0x4d4b, 0x4d4b, + 0x4d4c, 0x4d4c, 0x4d4c, 0x4d4d, 0x4d4d, 0x4d4d, 0x4d4d, 0x4d4e, + 0x4d4e, 0x4d4e, 0x4d4f, 0x4d4f, 0x4d4f, 0x4d4f, 0x4d50, 0x4d50, + 0x4d50, 0x4d51, 0x4d51, 0x4d51, 0x4d51, 0x4d52, 0x4d52, 0x4d52, + 0x4d53, 0x4d53, 0x4d53, 0x4d53, 0x4d54, 0x4d54, 0x4d54, 0x4d54, + 0x4d55, 0x4d55, 0x4d55, 0x4d56, 0x4d56, 0x4d56, 0x4d56, 0x4d57, + 0x4d57, 0x4d57, 0x4d58, 0x4d58, 0x4d58, 0x4d58, 0x4d59, 0x4d59, + 0x4d59, 0x4d59, 0x4d5a, 0x4d5a, 0x4d5a, 0x4d5b, 0x4d5b, 0x4d5b, + 0x4d5b, 0x4d5c, 0x4d5c, 0x4d5c, 0x4d5c, 0x4d5d, 0x4d5d, 0x4d5d, + 0x4d5e, 0x4d5e, 0x4d5e, 0x4d5e, 0x4d5f, 0x4d5f, 0x4d5f, 0x4d5f, + 0x4d60, 0x4d60, 0x4d60, 0x4d61, 0x4d61, 0x4d61, 0x4d61, 0x4d62, + 0x4d62, 0x4d62, 0x4d62, 0x4d63, 0x4d63, 0x4d63, 0x4d64, 0x4d64, + 0x4d64, 0x4d64, 0x4d65, 0x4d65, 0x4d65, 0x4d65, 0x4d66, 0x4d66, + 0x4d66, 0x4d67, 0x4d67, 0x4d67, 0x4d67, 0x4d68, 0x4d68, 0x4d68, + 0x4d68, 0x4d69, 0x4d69, 0x4d69, 0x4d69, 0x4d6a, 0x4d6a, 0x4d6a, + 0x4d6b, 0x4d6b, 0x4d6b, 0x4d6b, 0x4d6c, 0x4d6c, 0x4d6c, 0x4d6c, + 0x4d6d, 0x4d6d, 0x4d6d, 0x4d6d, 0x4d6e, 0x4d6e, 0x4d6e, 0x4d6f, + 0x4d6f, 0x4d6f, 0x4d6f, 0x4d70, 0x4d70, 0x4d70, 0x4d70, 0x4d71, + 0x4d71, 0x4d71, 0x4d71, 0x4d72, 0x4d72, 0x4d72, 0x4d72, 0x4d73, + 0x4d73, 0x4d73, 0x4d74, 0x4d74, 0x4d74, 0x4d74, 0x4d75, 0x4d75, + 0x4d75, 0x4d75, 0x4d76, 0x4d76, 0x4d76, 0x4d76, 0x4d77, 0x4d77, + 0x4d77, 0x4d77, 0x4d78, 0x4d78, 0x4d78, 0x4d78, 0x4d79, 0x4d79, + 0x4d79, 0x4d7a, 0x4d7a, 0x4d7a, 0x4d7a, 0x4d7b, 0x4d7b, 0x4d7b, + 0x4d7b, 0x4d7c, 0x4d7c, 0x4d7c, 0x4d7c, 0x4d7d, 0x4d7d, 0x4d7d, + 0x4d7d, 0x4d7e, 0x4d7e, 0x4d7e, 0x4d7e, 0x4d7f, 0x4d7f, 0x4d7f, + 0x4d7f, 0x4d80, 0x4d80, 0x4d80, 0x4d80, 0x4d81, 0x4d81, 0x4d81, + 0x4d81, 0x4d82, 0x4d82, 0x4d82, 0x4d82, 0x4d83, 0x4d83, 0x4d83, + 0x4d84, 0x4d84, 0x4d84, 0x4d84, 0x4d85, 0x4d85, 0x4d85, 0x4d85, + 0x4d86, 0x4d86, 0x4d86, 0x4d86, 0x4d87, 0x4d87, 0x4d87, 0x4d87, + 0x4d88, 0x4d88, 0x4d88, 0x4d88, 0x4d89, 0x4d89, 0x4d89, 0x4d89, + 0x4d8a, 0x4d8a, 0x4d8a, 0x4d8a, 0x4d8b, 0x4d8b, 0x4d8b, 0x4d8b, + 0x4d8c, 0x4d8c, 0x4d8d, 0x4d8d, 0x4d8e, 0x4d8e, 0x4d8f, 0x4d8f, + 0x4d90, 0x4d90, 0x4d91, 0x4d91, 0x4d92, 0x4d92, 0x4d93, 0x4d93, + 0x4d94, 0x4d94, 0x4d94, 0x4d95, 0x4d95, 0x4d96, 0x4d96, 0x4d97, + 0x4d97, 0x4d98, 0x4d98, 0x4d99, 0x4d99, 0x4d9a, 0x4d9a, 0x4d9b, + 0x4d9b, 0x4d9c, 0x4d9c, 0x4d9d, 0x4d9d, 0x4d9e, 0x4d9e, 0x4d9f, + 0x4d9f, 0x4da0, 0x4da0, 0x4da1, 0x4da1, 0x4da2, 0x4da2, 0x4da3, + 0x4da3, 0x4da3, 0x4da4, 0x4da4, 0x4da5, 0x4da5, 0x4da6, 0x4da6, + 0x4da7, 0x4da7, 0x4da8, 0x4da8, 0x4da9, 0x4da9, 0x4daa, 0x4daa, + 0x4dab, 0x4dab, 0x4dac, 0x4dac, 0x4dac, 0x4dad, 0x4dad, 0x4dae, + 0x4dae, 0x4daf, 0x4daf, 0x4db0, 0x4db0, 0x4db1, 0x4db1, 0x4db2, + 0x4db2, 0x4db3, 0x4db3, 0x4db3, 0x4db4, 0x4db4, 0x4db5, 0x4db5, + 0x4db6, 0x4db6, 0x4db7, 0x4db7, 0x4db8, 0x4db8, 0x4db9, 0x4db9, + 0x4db9, 0x4dba, 0x4dba, 0x4dbb, 0x4dbb, 0x4dbc, 0x4dbc, 0x4dbd, + 0x4dbd, 0x4dbe, 0x4dbe, 0x4dbe, 0x4dbf, 0x4dbf, 0x4dc0, 0x4dc0, + 0x4dc1, 0x4dc1, 0x4dc2, 0x4dc2, 0x4dc3, 0x4dc3, 0x4dc3, 0x4dc4, + 0x4dc4, 0x4dc5, 0x4dc5, 0x4dc6, 0x4dc6, 0x4dc7, 0x4dc7, 0x4dc7, + 0x4dc8, 0x4dc8, 0x4dc9, 0x4dc9, 0x4dca, 0x4dca, 0x4dcb, 0x4dcb, + 0x4dcb, 0x4dcc, 0x4dcc, 0x4dcd, 0x4dcd, 0x4dce, 0x4dce, 0x4dce, + 0x4dcf, 0x4dcf, 0x4dd0, 0x4dd0, 0x4dd1, 0x4dd1, 0x4dd2, 0x4dd2, + 0x4dd2, 0x4dd3, 0x4dd3, 0x4dd4, 0x4dd4, 0x4dd5, 0x4dd5, 0x4dd5, + 0x4dd6, 0x4dd6, 0x4dd7, 0x4dd7, 0x4dd8, 0x4dd8, 0x4dd8, 0x4dd9, + 0x4dd9, 0x4dda, 0x4dda, 0x4ddb, 0x4ddb, 0x4ddb, 0x4ddc, 0x4ddc, + 0x4ddd, 0x4ddd, 0x4dde, 0x4dde, 0x4dde, 0x4ddf, 0x4ddf, 0x4de0, + 0x4de0, 0x4de1, 0x4de1, 0x4de1, 0x4de2, 0x4de2, 0x4de3, 0x4de3, + 0x4de4, 0x4de4, 0x4de4, 0x4de5, 0x4de5, 0x4de6, 0x4de6, 0x4de6, + 0x4de7, 0x4de7, 0x4de8, 0x4de8, 0x4de9, 0x4de9, 0x4de9, 0x4dea, + 0x4dea, 0x4deb, 0x4deb, 0x4deb, 0x4dec, 0x4dec, 0x4ded, 0x4ded, + 0x4dee, 0x4dee, 0x4dee, 0x4def, 0x4def, 0x4df0, 0x4df0, 0x4df0, + 0x4df1, 0x4df1, 0x4df2, 0x4df2, 0x4df2, 0x4df3, 0x4df3, 0x4df4, + 0x4df4, 0x4df5, 0x4df5, 0x4df5, 0x4df6, 0x4df6, 0x4df7, 0x4df7, + 0x4df7, 0x4df8, 0x4df8, 0x4df9, 0x4df9, 0x4df9, 0x4dfa, 0x4dfa, + 0x4dfb, 0x4dfb, 0x4dfb, 0x4dfc, 0x4dfc, 0x4dfd, 0x4dfd, 0x4dfd, + 0x4dfe, 0x4dfe, 0x4dff, 0x4dff, 0x4dff, 0x4e00, 0x4e00, 0x4e01, + 0x4e01, 0x4e01, 0x4e02, 0x4e02, 0x4e03, 0x4e03, 0x4e03, 0x4e04, + 0x4e04, 0x4e05, 0x4e05, 0x4e05, 0x4e06, 0x4e06, 0x4e07, 0x4e07, + 0x4e07, 0x4e08, 0x4e08, 0x4e09, 0x4e09, 0x4e09, 0x4e0a, 0x4e0a, + 0x4e0a, 0x4e0b, 0x4e0b, 0x4e0c, 0x4e0c, 0x4e0c, 0x4e0d, 0x4e0d, + 0x4e0e, 0x4e0e, 0x4e0e, 0x4e0f, 0x4e0f, 0x4e10, 0x4e10, 0x4e10, + 0x4e11, 0x4e11, 0x4e11, 0x4e12, 0x4e12, 0x4e13, 0x4e13, 0x4e13, + 0x4e14, 0x4e14, 0x4e15, 0x4e15, 0x4e15, 0x4e16, 0x4e16, 0x4e16, + 0x4e17, 0x4e17, 0x4e18, 0x4e18, 0x4e18, 0x4e19, 0x4e19, 0x4e19, + 0x4e1a, 0x4e1a, 0x4e1b, 0x4e1b, 0x4e1b, 0x4e1c, 0x4e1c, 0x4e1c, + 0x4e1d, 0x4e1d, 0x4e1e, 0x4e1e, 0x4e1e, 0x4e1f, 0x4e1f, 0x4e1f, + 0x4e20, 0x4e20, 0x4e21, 0x4e21, 0x4e21, 0x4e22, 0x4e22, 0x4e22, + 0x4e23, 0x4e23, 0x4e24, 0x4e24, 0x4e24, 0x4e25, 0x4e25, 0x4e25, + 0x4e26, 0x4e26, 0x4e27, 0x4e27, 0x4e27, 0x4e28, 0x4e28, 0x4e28, + 0x4e29, 0x4e29, 0x4e29, 0x4e2a, 0x4e2a, 0x4e2b, 0x4e2b, 0x4e2b, + 0x4e2c, 0x4e2c, 0x4e2c, 0x4e2d, 0x4e2d, 0x4e2e, 0x4e2e, 0x4e2e, + 0x4e2f, 0x4e2f, 0x4e2f, 0x4e30, 0x4e30, 0x4e30, 0x4e31, 0x4e31, + 0x4e32, 0x4e32, 0x4e32, 0x4e33, 0x4e33, 0x4e33, 0x4e34, 0x4e34, + 0x4e34, 0x4e35, 0x4e35, 0x4e35, 0x4e36, 0x4e36, 0x4e37, 0x4e37, + 0x4e37, 0x4e38, 0x4e38, 0x4e38, 0x4e39, 0x4e39, 0x4e39, 0x4e3a, + 0x4e3a, 0x4e3a, 0x4e3b, 0x4e3b, 0x4e3c, 0x4e3c, 0x4e3c, 0x4e3d, + 0x4e3d, 0x4e3d, 0x4e3e, 0x4e3e, 0x4e3e, 0x4e3f, 0x4e3f, 0x4e3f, + 0x4e40, 0x4e40, 0x4e40, 0x4e41, 0x4e41, 0x4e42, 0x4e42, 0x4e42, + 0x4e43, 0x4e43, 0x4e43, 0x4e44, 0x4e44, 0x4e44, 0x4e45, 0x4e45, + 0x4e45, 0x4e46, 0x4e46, 0x4e46, 0x4e47, 0x4e47, 0x4e47, 0x4e48, + 0x4e48, 0x4e48, 0x4e49, 0x4e49, 0x4e4a, 0x4e4a, 0x4e4a, 0x4e4b, + 0x4e4b, 0x4e4b, 0x4e4c, 0x4e4c, 0x4e4c, 0x4e4d, 0x4e4d, 0x4e4d, + 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4f, 0x4e4f, 0x4e4f, 0x4e50, 0x4e50, + 0x4e50, 0x4e51, 0x4e51, 0x4e51, 0x4e52, 0x4e52, 0x4e52, 0x4e53, + 0x4e53, 0x4e53, 0x4e54, 0x4e54, 0x4e54, 0x4e55, 0x4e55, 0x4e55, + 0x4e56, 0x4e56, 0x4e56, 0x4e57, 0x4e57, 0x4e57, 0x4e58, 0x4e58, + 0x4e58, 0x4e59, 0x4e59, 0x4e59, 0x4e5a, 0x4e5a, 0x4e5a, 0x4e5b, + 0x4e5b, 0x4e5b, 0x4e5c, 0x4e5c, 0x4e5c, 0x4e5d, 0x4e5d, 0x4e5d, + 0x4e5e, 0x4e5e, 0x4e5e, 0x4e5f, 0x4e5f, 0x4e5f, 0x4e60, 0x4e60, + 0x4e60, 0x4e61, 0x4e61, 0x4e61, 0x4e62, 0x4e62, 0x4e62, 0x4e63, + 0x4e63, 0x4e63, 0x4e64, 0x4e64, 0x4e64, 0x4e65, 0x4e65, 0x4e65, + 0x4e66, 0x4e66, 0x4e66, 0x4e67, 0x4e67, 0x4e67, 0x4e68, 0x4e68, + 0x4e68, 0x4e69, 0x4e69, 0x4e69, 0x4e6a, 0x4e6a, 0x4e6a, 0x4e6b, + 0x4e6b, 0x4e6b, 0x4e6c, 0x4e6c, 0x4e6c, 0x4e6d, 0x4e6d, 0x4e6d, + 0x4e6d, 0x4e6e, 0x4e6e, 0x4e6e, 0x4e6f, 0x4e6f, 0x4e6f, 0x4e70, + 0x4e70, 0x4e70, 0x4e71, 0x4e71, 0x4e71, 0x4e72, 0x4e72, 0x4e72, + 0x4e73, 0x4e73, 0x4e73, 0x4e74, 0x4e74, 0x4e74, 0x4e75, 0x4e75, + 0x4e75, 0x4e75, 0x4e76, 0x4e76, 0x4e76, 0x4e77, 0x4e77, 0x4e77, + 0x4e78, 0x4e78, 0x4e78, 0x4e79, 0x4e79, 0x4e79, 0x4e7a, 0x4e7a, + 0x4e7a, 0x4e7b, 0x4e7b, 0x4e7b, 0x4e7b, 0x4e7c, 0x4e7c, 0x4e7c, + 0x4e7d, 0x4e7d, 0x4e7d, 0x4e7e, 0x4e7e, 0x4e7e, 0x4e7f, 0x4e7f, + 0x4e7f, 0x4e80, 0x4e80, 0x4e80, 0x4e80, 0x4e81, 0x4e81, 0x4e81, + 0x4e82, 0x4e82, 0x4e82, 0x4e83, 0x4e83, 0x4e83, 0x4e84, 0x4e84, + 0x4e84, 0x4e84, 0x4e85, 0x4e85, 0x4e85, 0x4e86, 0x4e86, 0x4e86, + 0x4e87, 0x4e87, 0x4e87, 0x4e88, 0x4e88, 0x4e88, 0x4e88, 0x4e89, + 0x4e89, 0x4e89, 0x4e8a, 0x4e8a, 0x4e8a, 0x4e8b, 0x4e8b, 0x4e8b, + 0x4e8b, 0x4e8c, 0x4e8c, 0x4e8c, 0x4e8d, 0x4e8d, 0x4e8d, 0x4e8e, + 0x4e8e, 0x4e8e, 0x4e8f, 0x4e8f, 0x4e8f, 0x4e8f, 0x4e90, 0x4e90, + 0x4e90, 0x4e91, 0x4e91, 0x4e91, 0x4e92, 0x4e92, 0x4e92, 0x4e92, + 0x4e93, 0x4e93, 0x4e93, 0x4e94, 0x4e94, 0x4e94, 0x4e94, 0x4e95, + 0x4e95, 0x4e95, 0x4e96, 0x4e96, 0x4e96, 0x4e97, 0x4e97, 0x4e97, + 0x4e97, 0x4e98, 0x4e98, 0x4e98, 0x4e99, 0x4e99, 0x4e99, 0x4e9a, + 0x4e9a, 0x4e9a, 0x4e9a, 0x4e9b, 0x4e9b, 0x4e9b, 0x4e9c, 0x4e9c, + 0x4e9c, 0x4e9c, 0x4e9d, 0x4e9d, 0x4e9d, 0x4e9e, 0x4e9e, 0x4e9e, + 0x4e9f, 0x4e9f, 0x4e9f, 0x4e9f, 0x4ea0, 0x4ea0, 0x4ea0, 0x4ea1, + 0x4ea1, 0x4ea1, 0x4ea1, 0x4ea2, 0x4ea2, 0x4ea2, 0x4ea3, 0x4ea3, + 0x4ea3, 0x4ea3, 0x4ea4, 0x4ea4, 0x4ea4, 0x4ea5, 0x4ea5, 0x4ea5, + 0x4ea5, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea7, 0x4ea7, 0x4ea7, 0x4ea8, + 0x4ea8, 0x4ea8, 0x4ea8, 0x4ea9, 0x4ea9, 0x4ea9, 0x4eaa, 0x4eaa, + 0x4eaa, 0x4eaa, 0x4eab, 0x4eab, 0x4eab, 0x4eac, 0x4eac, 0x4eac, + 0x4eac, 0x4ead, 0x4ead, 0x4ead, 0x4eae, 0x4eae, 0x4eae, 0x4eae, + 0x4eaf, 0x4eaf, 0x4eaf, 0x4eaf, 0x4eb0, 0x4eb0, 0x4eb0, 0x4eb1, + 0x4eb1, 0x4eb1, 0x4eb1, 0x4eb2, 0x4eb2, 0x4eb2, 0x4eb3, 0x4eb3, + 0x4eb3, 0x4eb3, 0x4eb4, 0x4eb4, 0x4eb4, 0x4eb5, 0x4eb5, 0x4eb5, + 0x4eb5, 0x4eb6, 0x4eb6, 0x4eb6, 0x4eb7, 0x4eb7, 0x4eb7, 0x4eb7, + 0x4eb8, 0x4eb8, 0x4eb8, 0x4eb8, 0x4eb9, 0x4eb9, 0x4eb9, 0x4eba, + 0x4eba, 0x4eba, 0x4eba, 0x4ebb, 0x4ebb, 0x4ebb, 0x4ebc, 0x4ebc, + 0x4ebc, 0x4ebc, 0x4ebd, 0x4ebd, 0x4ebd, 0x4ebd, 0x4ebe, 0x4ebe, + 0x4ebe, 0x4ebf, 0x4ebf, 0x4ebf, 0x4ebf, 0x4ec0, 0x4ec0, 0x4ec0, + 0x4ec0, 0x4ec1, 0x4ec1, 0x4ec1, 0x4ec2, 0x4ec2, 0x4ec2, 0x4ec2, + 0x4ec3, 0x4ec3, 0x4ec3, 0x4ec3, 0x4ec4, 0x4ec4, 0x4ec4, 0x4ec5, + 0x4ec5, 0x4ec5, 0x4ec5, 0x4ec6, 0x4ec6, 0x4ec6, 0x4ec6, 0x4ec7, + 0x4ec7, 0x4ec7, 0x4ec8, 0x4ec8, 0x4ec8, 0x4ec8, 0x4ec9, 0x4ec9, + 0x4ec9, 0x4ec9, 0x4eca, 0x4eca, 0x4eca, 0x4eca, 0x4ecb, 0x4ecb, + 0x4ecb, 0x4ecc, 0x4ecc, 0x4ecc, 0x4ecc, 0x4ecd, 0x4ecd, 0x4ecd, + 0x4ecd, 0x4ece, 0x4ece, 0x4ece, 0x4ece, 0x4ecf, 0x4ecf, 0x4ecf, + 0x4ed0, 0x4ed0, 0x4ed0, 0x4ed0, 0x4ed1, 0x4ed1, 0x4ed1, 0x4ed1, + 0x4ed2, 0x4ed2, 0x4ed2, 0x4ed2, 0x4ed3, 0x4ed3, 0x4ed3, 0x4ed4, + 0x4ed4, 0x4ed4, 0x4ed4, 0x4ed5, 0x4ed5, 0x4ed5, 0x4ed5, 0x4ed6, + 0x4ed6, 0x4ed6, 0x4ed6, 0x4ed7, 0x4ed7, 0x4ed7, 0x4ed7, 0x4ed8, + 0x4ed8, 0x4ed8, 0x4ed8, 0x4ed9, 0x4ed9, 0x4ed9, 0x4eda, 0x4eda, + 0x4eda, 0x4eda, 0x4edb, 0x4edb, 0x4edb, 0x4edb, 0x4edc, 0x4edc, + 0x4edc, 0x4edc, 0x4edd, 0x4edd, 0x4edd, 0x4edd, 0x4ede, 0x4ede, + 0x4ede, 0x4ede, 0x4edf, 0x4edf, 0x4edf, 0x4edf, 0x4ee0, 0x4ee0, + 0x4ee0, 0x4ee1, 0x4ee1, 0x4ee1, 0x4ee1, 0x4ee2, 0x4ee2, 0x4ee2, + 0x4ee2, 0x4ee3, 0x4ee3, 0x4ee3, 0x4ee3, 0x4ee4, 0x4ee4, 0x4ee4, + 0x4ee4, 0x4ee5, 0x4ee5, 0x4ee5, 0x4ee5, 0x4ee6, 0x4ee6, 0x4ee6, + 0x4ee6, 0x4ee7, 0x4ee7, 0x4ee7, 0x4ee7, 0x4ee8, 0x4ee8, 0x4ee8, + 0x4ee8, 0x4ee9, 0x4ee9, 0x4ee9, 0x4ee9, 0x4eea, 0x4eea, 0x4eea, + 0x4eea, 0x4eeb, 0x4eeb, 0x4eeb, 0x4eeb, 0x4eec, 0x4eec, 0x4eec, + 0x4eec, 0x4eed, 0x4eed, 0x4eed, 0x4eed, 0x4eee, 0x4eee, 0x4eee, + 0x4eee, 0x4eef, 0x4eef, 0x4ef0, 0x4ef0, 0x4ef1, 0x4ef1, 0x4ef2, + 0x4ef2, 0x4ef3, 0x4ef3, 0x4ef4, 0x4ef4, 0x4ef5, 0x4ef5, 0x4ef6, + 0x4ef6, 0x4ef7, 0x4ef7, 0x4ef8, 0x4ef8, 0x4ef9, 0x4ef9, 0x4efa, + 0x4efa, 0x4efb, 0x4efb, 0x4efc, 0x4efc, 0x4efd, 0x4efd, 0x4efe, + 0x4efe, 0x4eff, 0x4eff, 0x4f00, 0x4f00, 0x4f01, 0x4f01, 0x4f02, + 0x4f02, 0x4f03, 0x4f03, 0x4f04, 0x4f04, 0x4f04, 0x4f05, 0x4f05, + 0x4f06, 0x4f06, 0x4f07, 0x4f07, 0x4f08, 0x4f08, 0x4f09, 0x4f09, + 0x4f0a, 0x4f0a, 0x4f0b, 0x4f0b, 0x4f0c, 0x4f0c, 0x4f0d, 0x4f0d, + 0x4f0d, 0x4f0e, 0x4f0e, 0x4f0f, 0x4f0f, 0x4f10, 0x4f10, 0x4f11, + 0x4f11, 0x4f12, 0x4f12, 0x4f13, 0x4f13, 0x4f14, 0x4f14, 0x4f15, + 0x4f15, 0x4f15, 0x4f16, 0x4f16, 0x4f17, 0x4f17, 0x4f18, 0x4f18, + 0x4f19, 0x4f19, 0x4f1a, 0x4f1a, 0x4f1b, 0x4f1b, 0x4f1b, 0x4f1c, + 0x4f1c, 0x4f1d, 0x4f1d, 0x4f1e, 0x4f1e, 0x4f1f, 0x4f1f, 0x4f20, + 0x4f20, 0x4f20, 0x4f21, 0x4f21, 0x4f22, 0x4f22, 0x4f23, 0x4f23, + 0x4f24, 0x4f24, 0x4f25, 0x4f25, 0x4f25, 0x4f26, 0x4f26, 0x4f27, + 0x4f27, 0x4f28, 0x4f28, 0x4f29, 0x4f29, 0x4f29, 0x4f2a, 0x4f2a, + 0x4f2b, 0x4f2b, 0x4f2c, 0x4f2c, 0x4f2d, 0x4f2d, 0x4f2d, 0x4f2e, + 0x4f2e, 0x4f2f, 0x4f2f, 0x4f30, 0x4f30, 0x4f31, 0x4f31, 0x4f31, + 0x4f32, 0x4f32, 0x4f33, 0x4f33, 0x4f34, 0x4f34, 0x4f34, 0x4f35, + 0x4f35, 0x4f36, 0x4f36, 0x4f37, 0x4f37, 0x4f37, 0x4f38, 0x4f38, + 0x4f39, 0x4f39, 0x4f3a, 0x4f3a, 0x4f3b, 0x4f3b, 0x4f3b, 0x4f3c, + 0x4f3c, 0x4f3d, 0x4f3d, 0x4f3e, 0x4f3e, 0x4f3e, 0x4f3f, 0x4f3f, + 0x4f40, 0x4f40, 0x4f41, 0x4f41, 0x4f41, 0x4f42, 0x4f42, 0x4f43, + 0x4f43, 0x4f43, 0x4f44, 0x4f44, 0x4f45, 0x4f45, 0x4f46, 0x4f46, + 0x4f46, 0x4f47, 0x4f47, 0x4f48, 0x4f48, 0x4f49, 0x4f49, 0x4f49, + 0x4f4a, 0x4f4a, 0x4f4b, 0x4f4b, 0x4f4b, 0x4f4c, 0x4f4c, 0x4f4d, + 0x4f4d, 0x4f4e, 0x4f4e, 0x4f4e, 0x4f4f, 0x4f4f, 0x4f50, 0x4f50, + 0x4f50, 0x4f51, 0x4f51, 0x4f52, 0x4f52, 0x4f53, 0x4f53, 0x4f53, + 0x4f54, 0x4f54, 0x4f55, 0x4f55, 0x4f55, 0x4f56, 0x4f56, 0x4f57, + 0x4f57, 0x4f57, 0x4f58, 0x4f58, 0x4f59, 0x4f59, 0x4f59, 0x4f5a, + 0x4f5a, 0x4f5b, 0x4f5b, 0x4f5b, 0x4f5c, 0x4f5c, 0x4f5d, 0x4f5d, + 0x4f5d, 0x4f5e, 0x4f5e, 0x4f5f, 0x4f5f, 0x4f60, 0x4f60, 0x4f60, + 0x4f61, 0x4f61, 0x4f62, 0x4f62, 0x4f62, 0x4f63, 0x4f63, 0x4f63, + 0x4f64, 0x4f64, 0x4f65, 0x4f65, 0x4f65, 0x4f66, 0x4f66, 0x4f67, + 0x4f67, 0x4f67, 0x4f68, 0x4f68, 0x4f69, 0x4f69, 0x4f69, 0x4f6a, + 0x4f6a, 0x4f6b, 0x4f6b, 0x4f6b, 0x4f6c, 0x4f6c, 0x4f6d, 0x4f6d, + 0x4f6d, 0x4f6e, 0x4f6e, 0x4f6f, 0x4f6f, 0x4f6f, 0x4f70, 0x4f70, + 0x4f70, 0x4f71, 0x4f71, 0x4f72, 0x4f72, 0x4f72, 0x4f73, 0x4f73, + 0x4f74, 0x4f74, 0x4f74, 0x4f75, 0x4f75, 0x4f75, 0x4f76, 0x4f76, + 0x4f77, 0x4f77, 0x4f77, 0x4f78, 0x4f78, 0x4f79, 0x4f79, 0x4f79, + 0x4f7a, 0x4f7a, 0x4f7a, 0x4f7b, 0x4f7b, 0x4f7c, 0x4f7c, 0x4f7c, + 0x4f7d, 0x4f7d, 0x4f7d, 0x4f7e, 0x4f7e, 0x4f7f, 0x4f7f, 0x4f7f, + 0x4f80, 0x4f80, 0x4f80, 0x4f81, 0x4f81, 0x4f82, 0x4f82, 0x4f82, + 0x4f83, 0x4f83, 0x4f83, 0x4f84, 0x4f84, 0x4f85, 0x4f85, 0x4f85, + 0x4f86, 0x4f86, 0x4f86, 0x4f87, 0x4f87, 0x4f88, 0x4f88, 0x4f88, + 0x4f89, 0x4f89, 0x4f89, 0x4f8a, 0x4f8a, 0x4f8b, 0x4f8b, 0x4f8b, + 0x4f8c, 0x4f8c, 0x4f8c, 0x4f8d, 0x4f8d, 0x4f8d, 0x4f8e, 0x4f8e, + 0x4f8f, 0x4f8f, 0x4f8f, 0x4f90, 0x4f90, 0x4f90, 0x4f91, 0x4f91, + 0x4f92, 0x4f92, 0x4f92, 0x4f93, 0x4f93, 0x4f93, 0x4f94, 0x4f94, + 0x4f94, 0x4f95, 0x4f95, 0x4f95, 0x4f96, 0x4f96, 0x4f97, 0x4f97, + 0x4f97, 0x4f98, 0x4f98, 0x4f98, 0x4f99, 0x4f99, 0x4f99, 0x4f9a, + 0x4f9a, 0x4f9b, 0x4f9b, 0x4f9b, 0x4f9c, 0x4f9c, 0x4f9c, 0x4f9d, + 0x4f9d, 0x4f9d, 0x4f9e, 0x4f9e, 0x4f9e, 0x4f9f, 0x4f9f, 0x4f9f, + 0x4fa0, 0x4fa0, 0x4fa1, 0x4fa1, 0x4fa1, 0x4fa2, 0x4fa2, 0x4fa2, + 0x4fa3, 0x4fa3, 0x4fa3, 0x4fa4, 0x4fa4, 0x4fa4, 0x4fa5, 0x4fa5, + 0x4fa5, 0x4fa6, 0x4fa6, 0x4fa7, 0x4fa7, 0x4fa7, 0x4fa8, 0x4fa8, + 0x4fa8, 0x4fa9, 0x4fa9, 0x4fa9, 0x4faa, 0x4faa, 0x4faa, 0x4fab, + 0x4fab, 0x4fab, 0x4fac, 0x4fac, 0x4fac, 0x4fad, 0x4fad, 0x4fad, + 0x4fae, 0x4fae, 0x4fae, 0x4faf, 0x4faf, 0x4fb0, 0x4fb0, 0x4fb0, + 0x4fb1, 0x4fb1, 0x4fb1, 0x4fb2, 0x4fb2, 0x4fb2, 0x4fb3, 0x4fb3, + 0x4fb3, 0x4fb4, 0x4fb4, 0x4fb4, 0x4fb5, 0x4fb5, 0x4fb5, 0x4fb6, + 0x4fb6, 0x4fb6, 0x4fb7, 0x4fb7, 0x4fb7, 0x4fb8, 0x4fb8, 0x4fb8, + 0x4fb9, 0x4fb9, 0x4fb9, 0x4fba, 0x4fba, 0x4fba, 0x4fbb, 0x4fbb, + 0x4fbb, 0x4fbc, 0x4fbc, 0x4fbc, 0x4fbd, 0x4fbd, 0x4fbd, 0x4fbe, + 0x4fbe, 0x4fbe, 0x4fbf, 0x4fbf, 0x4fbf, 0x4fc0, 0x4fc0, 0x4fc0, + 0x4fc1, 0x4fc1, 0x4fc1, 0x4fc2, 0x4fc2, 0x4fc2, 0x4fc3, 0x4fc3, + 0x4fc3, 0x4fc4, 0x4fc4, 0x4fc4, 0x4fc5, 0x4fc5, 0x4fc5, 0x4fc6, + 0x4fc6, 0x4fc6, 0x4fc7, 0x4fc7, 0x4fc7, 0x4fc8, 0x4fc8, 0x4fc8, + 0x4fc9, 0x4fc9, 0x4fc9, 0x4fca, 0x4fca, 0x4fca, 0x4fcb, 0x4fcb, + 0x4fcb, 0x4fcc, 0x4fcc, 0x4fcc, 0x4fcd, 0x4fcd, 0x4fcd, 0x4fcd, + 0x4fce, 0x4fce, 0x4fce, 0x4fcf, 0x4fcf, 0x4fcf, 0x4fd0, 0x4fd0, + 0x4fd0, 0x4fd1, 0x4fd1, 0x4fd1, 0x4fd2, 0x4fd2, 0x4fd2, 0x4fd3, + 0x4fd3, 0x4fd3, 0x4fd4, 0x4fd4, 0x4fd4, 0x4fd5, 0x4fd5, 0x4fd5, + 0x4fd6, 0x4fd6, 0x4fd6, 0x4fd6, 0x4fd7, 0x4fd7, 0x4fd7, 0x4fd8, + 0x4fd8, 0x4fd8, 0x4fd9, 0x4fd9, 0x4fd9, 0x4fda, 0x4fda, 0x4fda, + 0x4fdb, 0x4fdb, 0x4fdb, 0x4fdc, 0x4fdc, 0x4fdc, 0x4fdc, 0x4fdd, + 0x4fdd, 0x4fdd, 0x4fde, 0x4fde, 0x4fde, 0x4fdf, 0x4fdf, 0x4fdf, + 0x4fe0, 0x4fe0, 0x4fe0, 0x4fe1, 0x4fe1, 0x4fe1, 0x4fe1, 0x4fe2, + 0x4fe2, 0x4fe2, 0x4fe3, 0x4fe3, 0x4fe3, 0x4fe4, 0x4fe4, 0x4fe4, + 0x4fe5, 0x4fe5, 0x4fe5, 0x4fe5, 0x4fe6, 0x4fe6, 0x4fe6, 0x4fe7, + 0x4fe7, 0x4fe7, 0x4fe8, 0x4fe8, 0x4fe8, 0x4fe9, 0x4fe9, 0x4fe9, + 0x4fe9, 0x4fea, 0x4fea, 0x4fea, 0x4feb, 0x4feb, 0x4feb, 0x4fec, + 0x4fec, 0x4fec, 0x4fed, 0x4fed, 0x4fed, 0x4fed, 0x4fee, 0x4fee, + 0x4fee, 0x4fef, 0x4fef, 0x4fef, 0x4ff0, 0x4ff0, 0x4ff0, 0x4ff0, + 0x4ff1, 0x4ff1, 0x4ff1, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff3, 0x4ff3, + 0x4ff3, 0x4ff3, 0x4ff4, 0x4ff4, 0x4ff4, 0x4ff5, 0x4ff5, 0x4ff5, + 0x4ff6, 0x4ff6, 0x4ff6, 0x4ff6, 0x4ff7, 0x4ff7, 0x4ff7, 0x4ff8, + 0x4ff8, 0x4ff8, 0x4ff9, 0x4ff9, 0x4ff9, 0x4ff9, 0x4ffa, 0x4ffa, + 0x4ffa, 0x4ffb, 0x4ffb, 0x4ffb, 0x4ffc, 0x4ffc, 0x4ffc, 0x4ffc, + 0x4ffd, 0x4ffd, 0x4ffd, 0x4ffe, 0x4ffe, 0x4ffe, 0x4ffe, 0x4fff, + 0x4fff, 0x4fff, 0x5000, 0x5000, 0x5000, 0x5000, 0x5000, 0x5001, + 0x5001, 0x5001, 0x5001, 0x5001, 0x5001, 0x5001, 0x5002, 0x5002, + 0x5002, 0x5002, 0x5002, 0x5002, 0x5002, 0x5003, 0x5003, 0x5003, + 0x5003, 0x5003, 0x5003, 0x5003, 0x5004, 0x5004, 0x5004, 0x5004, + 0x5004, 0x5004, 0x5004, 0x5005, 0x5005, 0x5005, 0x5005, 0x5005, + 0x5005, 0x5005, 0x5006, 0x5006, 0x5006, 0x5006, 0x5006, 0x5006, + 0x5006, 0x5007, 0x5007, 0x5007, 0x5007, 0x5007, 0x5007, 0x5007, + 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5009, + 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x500a, 0x500a, + 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, + 0x500b, 0x500b, 0x500b, 0x500b, 0x500c, 0x500c, 0x500c, 0x500c, + 0x500c, 0x500c, 0x500c, 0x500d, 0x500d, 0x500d, 0x500d, 0x500d, + 0x500d, 0x500d, 0x500e, 0x500e, 0x500e, 0x500e, 0x500e, 0x500e, + 0x500e, 0x500f, 0x500f, 0x500f, 0x500f, 0x500f, 0x500f, 0x500f, + 0x500f, 0x5010, 0x5010, 0x5010, 0x5010, 0x5010, 0x5010, 0x5010, + 0x5011, 0x5011, 0x5011, 0x5011, 0x5011, 0x5011, 0x5011, 0x5012, + 0x5012, 0x5012, 0x5012, 0x5012, 0x5012, 0x5012, 0x5012, 0x5013, + 0x5013, 0x5013, 0x5013, 0x5013, 0x5013, 0x5013, 0x5014, 0x5014, + 0x5014, 0x5014, 0x5014, 0x5014, 0x5014, 0x5015, 0x5015, 0x5015, + 0x5015, 0x5015, 0x5015, 0x5015, 0x5015, 0x5016, 0x5016, 0x5016, + 0x5016, 0x5016, 0x5016, 0x5016, 0x5017, 0x5017, 0x5017, 0x5017, + 0x5017, 0x5017, 0x5017, 0x5017, 0x5018, 0x5018, 0x5018, 0x5018, + 0x5018, 0x5018, 0x5018, 0x5019, 0x5019, 0x5019, 0x5019, 0x5019, + 0x5019, 0x5019, 0x5019, 0x501a, 0x501a, 0x501a, 0x501a, 0x501a, + 0x501a, 0x501a, 0x501b, 0x501b, 0x501b, 0x501b, 0x501b, 0x501b, + 0x501b, 0x501b, 0x501c, 0x501c, 0x501c, 0x501c, 0x501c, 0x501c, + 0x501c, 0x501d, 0x501d, 0x501d, 0x501d, 0x501d, 0x501d, 0x501d, + 0x501d, 0x501e, 0x501e, 0x501e, 0x501e, 0x501e, 0x501e, 0x501e, + 0x501e, 0x501f, 0x501f, 0x501f, 0x501f, 0x501f, 0x501f, 0x501f, + 0x5020, 0x5020, 0x5020, 0x5020, 0x5020, 0x5020, 0x5020, 0x5020, + 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, + 0x5022, 0x5022, 0x5022, 0x5022, 0x5022, 0x5022, 0x5022, 0x5022, + 0x5023, 0x5023, 0x5023, 0x5023, 0x5023, 0x5023, 0x5023, 0x5023, + 0x5024, 0x5024, 0x5024, 0x5024, 0x5024, 0x5024, 0x5024, 0x5025, + 0x5025, 0x5025, 0x5025, 0x5025, 0x5025, 0x5025, 0x5025, 0x5026, + 0x5026, 0x5026, 0x5026, 0x5026, 0x5026, 0x5026, 0x5026, 0x5027, + 0x5027, 0x5027, 0x5027, 0x5027, 0x5027, 0x5027, 0x5027, 0x5028, + 0x5028, 0x5028, 0x5028, 0x5028, 0x5028, 0x5028, 0x5028, 0x5029, + 0x5029, 0x5029, 0x5029, 0x5029, 0x502a, 0x502a, 0x502a, 0x502a, + 0x502b, 0x502b, 0x502b, 0x502b, 0x502c, 0x502c, 0x502c, 0x502c, + 0x502d, 0x502d, 0x502d, 0x502d, 0x502e, 0x502e, 0x502e, 0x502e, + 0x502f, 0x502f, 0x502f, 0x502f, 0x5030, 0x5030, 0x5030, 0x5030, + 0x5031, 0x5031, 0x5031, 0x5031, 0x5032, 0x5032, 0x5032, 0x5032, + 0x5032, 0x5033, 0x5033, 0x5033, 0x5033, 0x5034, 0x5034, 0x5034, + 0x5034, 0x5035, 0x5035, 0x5035, 0x5035, 0x5036, 0x5036, 0x5036, + 0x5036, 0x5037, 0x5037, 0x5037, 0x5037, 0x5037, 0x5038, 0x5038, + 0x5038, 0x5038, 0x5039, 0x5039, 0x5039, 0x5039, 0x503a, 0x503a, + 0x503a, 0x503a, 0x503b, 0x503b, 0x503b, 0x503b, 0x503b, 0x503c, + 0x503c, 0x503c, 0x503c, 0x503d, 0x503d, 0x503d, 0x503d, 0x503e, + 0x503e, 0x503e, 0x503e, 0x503e, 0x503f, 0x503f, 0x503f, 0x503f, + 0x5040, 0x5040, 0x5040, 0x5040, 0x5041, 0x5041, 0x5041, 0x5041, + 0x5041, 0x5042, 0x5042, 0x5042, 0x5042, 0x5043, 0x5043, 0x5043, + 0x5043, 0x5043, 0x5044, 0x5044, 0x5044, 0x5044, 0x5045, 0x5045, + 0x5045, 0x5045, 0x5045, 0x5046, 0x5046, 0x5046, 0x5046, 0x5047, + 0x5047, 0x5047, 0x5047, 0x5047, 0x5048, 0x5048, 0x5048, 0x5048, + 0x5049, 0x5049, 0x5049, 0x5049, 0x5049, 0x504a, 0x504a, 0x504a, + 0x504a, 0x504b, 0x504b, 0x504b, 0x504b, 0x504b, 0x504c, 0x504c, + 0x504c, 0x504c, 0x504d, 0x504d, 0x504d, 0x504d, 0x504d, 0x504e, + 0x504e, 0x504e, 0x504e, 0x504e, 0x504f, 0x504f, 0x504f, 0x504f, + 0x5050, 0x5050, 0x5050, 0x5050, 0x5050, 0x5051, 0x5051, 0x5051, + 0x5051, 0x5051, 0x5052, 0x5052, 0x5052, 0x5052, 0x5053, 0x5053, + 0x5053, 0x5053, 0x5053, 0x5054, 0x5054, 0x5054, 0x5054, 0x5054, + 0x5055, 0x5055, 0x5055, 0x5055, 0x5056, 0x5056, 0x5056, 0x5056, + 0x5056, 0x5057, 0x5057, 0x5057, 0x5057, 0x5057, 0x5058, 0x5058, + 0x5058, 0x5058, 0x5058, 0x5059, 0x5059, 0x5059, 0x5059, 0x5059, + 0x505a, 0x505a, 0x505a, 0x505a, 0x505a, 0x505b, 0x505b, 0x505b, + 0x505b, 0x505c, 0x505c, 0x505c, 0x505c, 0x505c, 0x505d, 0x505d, + 0x505d, 0x505d, 0x505d, 0x505e, 0x505e, 0x505e, 0x505e, 0x505e, + 0x505f, 0x505f, 0x505f, 0x505f, 0x505f, 0x5060, 0x5060, 0x5060, + 0x5060, 0x5060, 0x5061, 0x5061, 0x5061, 0x5061, 0x5061, 0x5062, + 0x5062, 0x5062, 0x5062, 0x5062, 0x5063, 0x5063, 0x5063, 0x5063, + 0x5063, 0x5064, 0x5064, 0x5064, 0x5064, 0x5064, 0x5065, 0x5065, + 0x5065, 0x5065, 0x5065, 0x5066, 0x5066, 0x5066, 0x5066, 0x5066, + 0x5067, 0x5067, 0x5067, 0x5067, 0x5067, 0x5068, 0x5068, 0x5068, + 0x5068, 0x5068, 0x5069, 0x5069, 0x5069, 0x5069, 0x5069, 0x5069, + 0x506a, 0x506a, 0x506a, 0x506a, 0x506a, 0x506b, 0x506b, 0x506b, + 0x506b, 0x506b, 0x506c, 0x506c, 0x506c, 0x506c, 0x506c, 0x506d, + 0x506d, 0x506d, 0x506d, 0x506d, 0x506e, 0x506e, 0x506e, 0x506e, + 0x506e, 0x506e, 0x506f, 0x506f, 0x506f, 0x506f, 0x506f, 0x5070, + 0x5070, 0x5070, 0x5070, 0x5070, 0x5071, 0x5071, 0x5071, 0x5071, + 0x5071, 0x5072, 0x5072, 0x5072, 0x5072, 0x5072, 0x5072, 0x5073, + 0x5073, 0x5073, 0x5073, 0x5073, 0x5074, 0x5074, 0x5074, 0x5074, + 0x5074, 0x5074, 0x5075, 0x5075, 0x5075, 0x5075, 0x5075, 0x5076, + 0x5076, 0x5076, 0x5076, 0x5076, 0x5077, 0x5077, 0x5077, 0x5077, + 0x5077, 0x5077, 0x5078, 0x5078, 0x5078, 0x5078, 0x5078, 0x5079, + 0x5079, 0x5079, 0x5079, 0x5079, 0x5079, 0x507a, 0x507a, 0x507a, + 0x507a, 0x507a, 0x507b, 0x507b, 0x507b, 0x507b, 0x507b, 0x507b, + 0x507c, 0x507c, 0x507c, 0x507c, 0x507c, 0x507d, 0x507d, 0x507d, + 0x507d, 0x507d, 0x507d, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, + 0x507f, 0x507f, 0x507f, 0x507f, 0x507f, 0x507f, 0x5080, 0x5080, + 0x5080, 0x5080, 0x5080, 0x5080, 0x5081, 0x5081, 0x5081, 0x5081, + 0x5081, 0x5082, 0x5082, 0x5082, 0x5082, 0x5082, 0x5082, 0x5083, + 0x5083, 0x5083, 0x5083, 0x5083, 0x5083, 0x5084, 0x5084, 0x5084, + 0x5084, 0x5084, 0x5085, 0x5085, 0x5085, 0x5085, 0x5085, 0x5085, + 0x5086, 0x5086, 0x5086, 0x5086, 0x5086, 0x5086, 0x5087, 0x5087, + 0x5087, 0x5087, 0x5087, 0x5087, 0x5088, 0x5088, 0x5088, 0x5088, + 0x5088, 0x5089, 0x5089, 0x5089, 0x5089, 0x5089, 0x5089, 0x508a, + 0x508a, 0x508a, 0x508a, 0x508a, 0x508a, 0x508b, 0x508b, 0x508b, + 0x508b, 0x508b, 0x508b, 0x508c, 0x508c, 0x508c, 0x508c, 0x508c, + 0x508c, 0x508d, 0x508d, 0x508d, 0x508d, 0x508d, 0x508d, 0x508e, + 0x508e, 0x508e, 0x508e, 0x508e, 0x508e, 0x508f, 0x508f, 0x508f, + 0x508f, 0x508f, 0x508f, 0x5090, 0x5090, 0x5090, 0x5090, 0x5090, + 0x5090, 0x5091, 0x5091, 0x5091, 0x5091, 0x5091, 0x5091, 0x5092, + 0x5092, 0x5092, 0x5092, 0x5092, 0x5092, 0x5093, 0x5093, 0x5093, + 0x5093, 0x5093, 0x5093, 0x5094, 0x5094, 0x5094, 0x5094, 0x5094, + 0x5094, 0x5095, 0x5095, 0x5095, 0x5095, 0x5095, 0x5095, 0x5096, + 0x5096, 0x5096, 0x5096, 0x5096, 0x5096, 0x5097, 0x5097, 0x5097, + 0x5097, 0x5097, 0x5097, 0x5098, 0x5098, 0x5098, 0x5098, 0x5098, + 0x5098, 0x5099, 0x5099, 0x5099, 0x5099, 0x5099, 0x5099, 0x5099, + 0x509a, 0x509a, 0x509a, 0x509a, 0x509a, 0x509a, 0x509b, 0x509b, + 0x509b, 0x509b, 0x509b, 0x509b, 0x509c, 0x509c, 0x509c, 0x509c, + 0x509c, 0x509c, 0x509d, 0x509d, 0x509d, 0x509d, 0x509d, 0x509d, + 0x509d, 0x509e, 0x509e, 0x509e, 0x509e, 0x509e, 0x509e, 0x509f, + 0x509f, 0x509f, 0x509f, 0x509f, 0x509f, 0x50a0, 0x50a0, 0x50a0, + 0x50a0, 0x50a0, 0x50a0, 0x50a0, 0x50a1, 0x50a1, 0x50a1, 0x50a1, + 0x50a1, 0x50a1, 0x50a2, 0x50a2, 0x50a2, 0x50a2, 0x50a2, 0x50a2, + 0x50a2, 0x50a3, 0x50a3, 0x50a3, 0x50a3, 0x50a3, 0x50a3, 0x50a4, + 0x50a4, 0x50a4, 0x50a4, 0x50a4, 0x50a4, 0x50a5, 0x50a5, 0x50a5, + 0x50a5, 0x50a5, 0x50a5, 0x50a5, 0x50a6, 0x50a6, 0x50a6, 0x50a6, + 0x50a6, 0x50a6, 0x50a6, 0x50a7, 0x50a7, 0x50a7, 0x50a7, 0x50a7, + 0x50a7, 0x50a8, 0x50a8, 0x50a8, 0x50a8, 0x50a8, 0x50a8, 0x50a8, + 0x50a9, 0x50a9, 0x50a9, 0x50a9, 0x50a9, 0x50a9, 0x50aa, 0x50aa, + 0x50aa, 0x50aa, 0x50aa, 0x50aa, 0x50aa, 0x50ab, 0x50ab, 0x50ab, + 0x50ab, 0x50ab, 0x50ab, 0x50ab, 0x50ac, 0x50ac, 0x50ac, 0x50ac, + 0x50ac, 0x50ac, 0x50ad, 0x50ad, 0x50ad, 0x50ad, 0x50ad, 0x50ad, + 0x50ad, 0x50ae, 0x50ae, 0x50ae, 0x50ae, 0x50ae, 0x50ae, 0x50ae, + 0x50af, 0x50af, 0x50af, 0x50af, 0x50af, 0x50af, 0x50b0, 0x50b0, + 0x50b0, 0x50b0, 0x50b0, 0x50b0, 0x50b0, 0x50b1, 0x50b1, 0x50b1, + 0x50b1, 0x50b1, 0x50b1, 0x50b1, 0x50b2, 0x50b2, 0x50b2, 0x50b2, + 0x50b2, 0x50b2, 0x50b2, 0x50b3, 0x50b3, 0x50b3, 0x50b3, 0x50b3, + 0x50b3, 0x50b3, 0x50b4, 0x50b4, 0x50b4, 0x50b4, 0x50b4, 0x50b4, + 0x50b4, 0x50b5, 0x50b5, 0x50b5, 0x50b5, 0x50b5, 0x50b5, 0x50b5, + 0x50b6, 0x50b6, 0x50b6, 0x50b6, 0x50b6, 0x50b6, 0x50b7, 0x50b7, + 0x50b7, 0x50b7, 0x50b7, 0x50b7, 0x50b7, 0x50b8, 0x50b8, 0x50b8, + 0x50b8, 0x50b8, 0x50b8, 0x50b8, 0x50b9, 0x50b9, 0x50b9, 0x50b9, + 0x50b9, 0x50b9, 0x50b9, 0x50ba, 0x50ba, 0x50ba, 0x50ba, 0x50ba, + 0x50ba, 0x50ba, 0x50ba, 0x50bb, 0x50bb, 0x50bb, 0x50bb, 0x50bb, + 0x50bb, 0x50bb, 0x50bc, 0x50bc, 0x50bc, 0x50bc, 0x50bc, 0x50bc, + 0x50bc, 0x50bd, 0x50bd, 0x50bd, 0x50bd, 0x50bd, 0x50bd, 0x50bd, + 0x50be, 0x50be, 0x50be, 0x50be, 0x50be, 0x50be, 0x50be, 0x50bf, + 0x50bf, 0x50bf, 0x50bf, 0x50bf, 0x50bf, 0x50bf, 0x50c0, 0x50c0, + 0x50c0, 0x50c0, 0x50c0, 0x50c0, 0x50c0, 0x50c1, 0x50c1, 0x50c1, + 0x50c1, 0x50c1, 0x50c1, 0x50c1, 0x50c1, 0x50c2, 0x50c2, 0x50c2, + 0x50c2, 0x50c2, 0x50c2, 0x50c2, 0x50c3, 0x50c3, 0x50c3, 0x50c3, + 0x50c3, 0x50c3, 0x50c3, 0x50c4, 0x50c4, 0x50c4, 0x50c4, 0x50c4, + 0x50c4, 0x50c4, 0x50c4, 0x50c5, 0x50c5, 0x50c5, 0x50c5, 0x50c5, + 0x50c5, 0x50c5, 0x50c6, 0x50c6, 0x50c6, 0x50c6, 0x50c6, 0x50c6, + 0x50c6, 0x50c7, 0x50c7, 0x50c7, 0x50c7, 0x50c7, 0x50c7, 0x50c7, + 0x50c7, 0x50c8, 0x50c8, 0x50c8, 0x50c8, 0x50c8, 0x50c8, 0x50c8, + 0x50c9, 0x50c9, 0x50c9, 0x50c9, 0x50c9, 0x50c9, 0x50c9, 0x50c9, + 0x50ca, 0x50ca, 0x50ca, 0x50ca, 0x50ca, 0x50ca, 0x50ca, 0x50cb, + 0x50cb, 0x50cb, 0x50cb, 0x50cb, 0x50cb, 0x50cb, 0x50cb, 0x50cc, + 0x50cc, 0x50cc, 0x50cc, 0x50cc, 0x50cc, 0x50cc, 0x50cd, 0x50cd, + 0x50cd, 0x50cd, 0x50cd, 0x50cd, 0x50cd, 0x50cd, 0x50ce, 0x50ce, + 0x50ce, 0x50ce, 0x50ce, 0x50ce, 0x50ce, 0x50ce, 0x50cf, 0x50cf, + 0x50cf, 0x50cf, 0x50cf, 0x50cf, 0x50cf, 0x50d0, 0x50d0, 0x50d0, + 0x50d0, 0x50d0, 0x50d0, 0x50d0, 0x50d0, 0x50d1, 0x50d1, 0x50d1, + 0x50d1, 0x50d1, 0x50d1, 0x50d1, 0x50d1, 0x50d2, 0x50d2, 0x50d2, + 0x50d2, 0x50d2, 0x50d2, 0x50d2, 0x50d3, 0x50d3, 0x50d3, 0x50d3, + 0x50d3, 0x50d3, 0x50d3, 0x50d3, 0x50d4, 0x50d4, 0x50d4, 0x50d4, + 0x50d4, 0x50d4, 0x50d4, 0x50d4, 0x50d5, 0x50d5, 0x50d5, 0x50d5, + 0x50d5, 0x50d5, 0x50d5, 0x50d5, 0x50d6, 0x50d6, 0x50d6, 0x50d6, + 0x50d6, 0x50d6, 0x50d6, 0x50d6, 0x50d7, 0x50d7, 0x50d7, 0x50d7, + 0x50d7, 0x50d7, 0x50d7, 0x50d7, 0x50d8, 0x50d8, 0x50d8, 0x50d8, + 0x50d8, 0x50d8, 0x50d8, 0x50d8, 0x50d9, 0x50d9, 0x50d9, 0x50d9, + 0x50d9, 0x50d9, 0x50d9, 0x50d9, 0x50da, 0x50da, 0x50da, 0x50da, + 0x50da, 0x50da, 0x50db, 0x50db, 0x50db, 0x50db, 0x50dc, 0x50dc, + 0x50dc, 0x50dc, 0x50dd, 0x50dd, 0x50dd, 0x50dd, 0x50de, 0x50de, + 0x50de, 0x50de, 0x50df, 0x50df, 0x50df, 0x50df, 0x50e0, 0x50e0, + 0x50e0, 0x50e0, 0x50e1, 0x50e1, 0x50e1, 0x50e1, 0x50e2, 0x50e2, + 0x50e2, 0x50e2, 0x50e2, 0x50e3, 0x50e3, 0x50e3, 0x50e3, 0x50e4, + 0x50e4, 0x50e4, 0x50e4, 0x50e5, 0x50e5, 0x50e5, 0x50e5, 0x50e6, + 0x50e6, 0x50e6, 0x50e6, 0x50e7, 0x50e7, 0x50e7, 0x50e7, 0x50e8, + 0x50e8, 0x50e8, 0x50e8, 0x50e8, 0x50e9, 0x50e9, 0x50e9, 0x50e9, + 0x50ea, 0x50ea, 0x50ea, 0x50ea, 0x50eb, 0x50eb, 0x50eb, 0x50eb, + 0x50ec, 0x50ec, 0x50ec, 0x50ec, 0x50ec, 0x50ed, 0x50ed, 0x50ed, + 0x50ed, 0x50ee, 0x50ee, 0x50ee, 0x50ee, 0x50ef, 0x50ef, 0x50ef, + 0x50ef, 0x50ef, 0x50f0, 0x50f0, 0x50f0, 0x50f0, 0x50f1, 0x50f1, + 0x50f1, 0x50f1, 0x50f2, 0x50f2, 0x50f2, 0x50f2, 0x50f2, 0x50f3, + 0x50f3, 0x50f3, 0x50f3, 0x50f4, 0x50f4, 0x50f4, 0x50f4, 0x50f4, + 0x50f5, 0x50f5, 0x50f5, 0x50f5, 0x50f6, 0x50f6, 0x50f6, 0x50f6, + 0x50f6, 0x50f7, 0x50f7, 0x50f7, 0x50f7, 0x50f8, 0x50f8, 0x50f8, + 0x50f8, 0x50f8, 0x50f9, 0x50f9, 0x50f9, 0x50f9, 0x50fa, 0x50fa, + 0x50fa, 0x50fa, 0x50fa, 0x50fb, 0x50fb, 0x50fb, 0x50fb, 0x50fc, + 0x50fc, 0x50fc, 0x50fc, 0x50fc, 0x50fd, 0x50fd, 0x50fd, 0x50fd, + 0x50fe, 0x50fe, 0x50fe, 0x50fe, 0x50fe, 0x50ff, 0x50ff, 0x50ff, + 0x50ff, 0x5100, 0x5100, 0x5100, 0x5100, 0x5100, 0x5101, 0x5101, + 0x5101, 0x5101, 0x5101, 0x5102, 0x5102, 0x5102, 0x5102, 0x5103, + 0x5103, 0x5103, 0x5103, 0x5103, 0x5104, 0x5104, 0x5104, 0x5104, + 0x5104, 0x5105, 0x5105, 0x5105, 0x5105, 0x5105, 0x5106, 0x5106, + 0x5106, 0x5106, 0x5107, 0x5107, 0x5107, 0x5107, 0x5107, 0x5108, + 0x5108, 0x5108, 0x5108, 0x5108, 0x5109, 0x5109, 0x5109, 0x5109, + 0x5109, 0x510a, 0x510a, 0x510a, 0x510a, 0x510a, 0x510b, 0x510b, + 0x510b, 0x510b, 0x510c, 0x510c, 0x510c, 0x510c, 0x510c, 0x510d, + 0x510d, 0x510d, 0x510d, 0x510d, 0x510e, 0x510e, 0x510e, 0x510e, + 0x510e, 0x510f, 0x510f, 0x510f, 0x510f, 0x510f, 0x5110, 0x5110, + 0x5110, 0x5110, 0x5110, 0x5111, 0x5111, 0x5111, 0x5111, 0x5111, + 0x5112, 0x5112, 0x5112, 0x5112, 0x5112, 0x5113, 0x5113, 0x5113, + 0x5113, 0x5113, 0x5114, 0x5114, 0x5114, 0x5114, 0x5114, 0x5115, + 0x5115, 0x5115, 0x5115, 0x5115, 0x5116, 0x5116, 0x5116, 0x5116, + 0x5116, 0x5117, 0x5117, 0x5117, 0x5117, 0x5117, 0x5118, 0x5118, + 0x5118, 0x5118, 0x5118, 0x5119, 0x5119, 0x5119, 0x5119, 0x5119, + 0x511a, 0x511a, 0x511a, 0x511a, 0x511a, 0x511b, 0x511b, 0x511b, + 0x511b, 0x511b, 0x511c, 0x511c, 0x511c, 0x511c, 0x511c, 0x511c, + 0x511d, 0x511d, 0x511d, 0x511d, 0x511d, 0x511e, 0x511e, 0x511e, + 0x511e, 0x511e, 0x511f, 0x511f, 0x511f, 0x511f, 0x511f, 0x5120, + 0x5120, 0x5120, 0x5120, 0x5120, 0x5120, 0x5121, 0x5121, 0x5121, + 0x5121, 0x5121, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5123, + 0x5123, 0x5123, 0x5123, 0x5123, 0x5124, 0x5124, 0x5124, 0x5124, + 0x5124, 0x5124, 0x5125, 0x5125, 0x5125, 0x5125, 0x5125, 0x5126, + 0x5126, 0x5126, 0x5126, 0x5126, 0x5127, 0x5127, 0x5127, 0x5127, + 0x5127, 0x5127, 0x5128, 0x5128, 0x5128, 0x5128, 0x5128, 0x5129, + 0x5129, 0x5129, 0x5129, 0x5129, 0x5129, 0x512a, 0x512a, 0x512a, + 0x512a, 0x512a, 0x512b, 0x512b, 0x512b, 0x512b, 0x512b, 0x512b, + 0x512c, 0x512c, 0x512c, 0x512c, 0x512c, 0x512d, 0x512d, 0x512d, + 0x512d, 0x512d, 0x512d, 0x512e, 0x512e, 0x512e, 0x512e, 0x512e, + 0x512f, 0x512f, 0x512f, 0x512f, 0x512f, 0x512f, 0x5130, 0x5130, + 0x5130, 0x5130, 0x5130, 0x5131, 0x5131, 0x5131, 0x5131, 0x5131, + 0x5131, 0x5132, 0x5132, 0x5132, 0x5132, 0x5132, 0x5132, 0x5133, + 0x5133, 0x5133, 0x5133, 0x5133, 0x5134, 0x5134, 0x5134, 0x5134, + 0x5134, 0x5134, 0x5135, 0x5135, 0x5135, 0x5135, 0x5135, 0x5135, + 0x5136, 0x5136, 0x5136, 0x5136, 0x5136, 0x5137, 0x5137, 0x5137, + 0x5137, 0x5137, 0x5137, 0x5138, 0x5138, 0x5138, 0x5138, 0x5138, + 0x5138, 0x5139, 0x5139, 0x5139, 0x5139, 0x5139, 0x5139, 0x513a, + 0x513a, 0x513a, 0x513a, 0x513a, 0x513a, 0x513b, 0x513b, 0x513b, + 0x513b, 0x513b, 0x513c, 0x513c, 0x513c, 0x513c, 0x513c, 0x513c, + 0x513d, 0x513d, 0x513d, 0x513d, 0x513d, 0x513d, 0x513e, 0x513e, + 0x513e, 0x513e, 0x513e, 0x513e, 0x513f, 0x513f, 0x513f, 0x513f, + 0x513f, 0x513f, 0x5140, 0x5140, 0x5140, 0x5140, 0x5140, 0x5140, + 0x5141, 0x5141, 0x5141, 0x5141, 0x5141, 0x5141, 0x5142, 0x5142, + 0x5142, 0x5142, 0x5142, 0x5142, 0x5143, 0x5143, 0x5143, 0x5143, + 0x5143, 0x5143, 0x5144, 0x5144, 0x5144, 0x5144, 0x5144, 0x5144, + 0x5145, 0x5145, 0x5145, 0x5145, 0x5145, 0x5145, 0x5146, 0x5146, + 0x5146, 0x5146, 0x5146, 0x5146, 0x5147, 0x5147, 0x5147, 0x5147, + 0x5147, 0x5147, 0x5148, 0x5148, 0x5148, 0x5148, 0x5148, 0x5148, + 0x5149, 0x5149, 0x5149, 0x5149, 0x5149, 0x5149, 0x5149, 0x514a, + 0x514a, 0x514a, 0x514a, 0x514a, 0x514a, 0x514b, 0x514b, 0x514b, + 0x514b, 0x514b, 0x514b, 0x514c, 0x514c, 0x514c, 0x514c, 0x514c, + 0x514c, 0x514d, 0x514d, 0x514d, 0x514d, 0x514d, 0x514d, 0x514d, + 0x514e, 0x514e, 0x514e, 0x514e, 0x514e, 0x514e, 0x514f, 0x514f, + 0x514f, 0x514f, 0x514f, 0x514f, 0x5150, 0x5150, 0x5150, 0x5150, + 0x5150, 0x5150, 0x5150, 0x5151, 0x5151, 0x5151, 0x5151, 0x5151, + 0x5151, 0x5152, 0x5152, 0x5152, 0x5152, 0x5152, 0x5152, 0x5153, + 0x5153, 0x5153, 0x5153, 0x5153, 0x5153, 0x5153, 0x5154, 0x5154, + 0x5154, 0x5154, 0x5154, 0x5154, 0x5155, 0x5155, 0x5155, 0x5155, + 0x5155, 0x5155, 0x5155, 0x5156, 0x5156, 0x5156, 0x5156, 0x5156, + 0x5156, 0x5157, 0x5157, 0x5157, 0x5157, 0x5157, 0x5157, 0x5157, + 0x5158, 0x5158, 0x5158, 0x5158, 0x5158, 0x5158, 0x5159, 0x5159, + 0x5159, 0x5159, 0x5159, 0x5159, 0x5159, 0x515a, 0x515a, 0x515a, + 0x515a, 0x515a, 0x515a, 0x515b, 0x515b, 0x515b, 0x515b, 0x515b, + 0x515b, 0x515b, 0x515c, 0x515c, 0x515c, 0x515c, 0x515c, 0x515c, + 0x515c, 0x515d, 0x515d, 0x515d, 0x515d, 0x515d, 0x515d, 0x515e, + 0x515e, 0x515e, 0x515e, 0x515e, 0x515e, 0x515e, 0x515f, 0x515f, + 0x515f, 0x515f, 0x515f, 0x515f, 0x515f, 0x5160, 0x5160, 0x5160, + 0x5160, 0x5160, 0x5160, 0x5161, 0x5161, 0x5161, 0x5161, 0x5161, + 0x5161, 0x5161, 0x5162, 0x5162, 0x5162, 0x5162, 0x5162, 0x5162, + 0x5162, 0x5163, 0x5163, 0x5163, 0x5163, 0x5163, 0x5163, 0x5163, + 0x5164, 0x5164, 0x5164, 0x5164, 0x5164, 0x5164, 0x5164, 0x5165, + 0x5165, 0x5165, 0x5165, 0x5165, 0x5165, 0x5165, 0x5166, 0x5166, + 0x5166, 0x5166, 0x5166, 0x5166, 0x5167, 0x5167, 0x5167, 0x5167, + 0x5167, 0x5167, 0x5167, 0x5168, 0x5168, 0x5168, 0x5168, 0x5168, + 0x5168, 0x5168, 0x5169, 0x5169, 0x5169, 0x5169, 0x5169, 0x5169, + 0x5169, 0x516a, 0x516a, 0x516a, 0x516a, 0x516a, 0x516a, 0x516a, + 0x516b, 0x516b, 0x516b, 0x516b, 0x516b, 0x516b, 0x516b, 0x516c, + 0x516c, 0x516c, 0x516c, 0x516c, 0x516c, 0x516c, 0x516d, 0x516d, + 0x516d, 0x516d, 0x516d, 0x516d, 0x516d, 0x516d, 0x516e, 0x516e, + 0x516e, 0x516e, 0x516e, 0x516e, 0x516e, 0x516f, 0x516f, 0x516f, + 0x516f, 0x516f, 0x516f, 0x516f, 0x5170, 0x5170, 0x5170, 0x5170, + 0x5170, 0x5170, 0x5170, 0x5171, 0x5171, 0x5171, 0x5171, 0x5171, + 0x5171, 0x5171, 0x5172, 0x5172, 0x5172, 0x5172, 0x5172, 0x5172, + 0x5172, 0x5173, 0x5173, 0x5173, 0x5173, 0x5173, 0x5173, 0x5173, + 0x5173, 0x5174, 0x5174, 0x5174, 0x5174, 0x5174, 0x5174, 0x5174, + 0x5175, 0x5175, 0x5175, 0x5175, 0x5175, 0x5175, 0x5175, 0x5176, + 0x5176, 0x5176, 0x5176, 0x5176, 0x5176, 0x5176, 0x5176, 0x5177, + 0x5177, 0x5177, 0x5177, 0x5177, 0x5177, 0x5177, 0x5178, 0x5178, + 0x5178, 0x5178, 0x5178, 0x5178, 0x5178, 0x5178, 0x5179, 0x5179, + 0x5179, 0x5179, 0x5179, 0x5179, 0x5179, 0x517a, 0x517a, 0x517a, + 0x517a, 0x517a, 0x517a, 0x517a, 0x517b, 0x517b, 0x517b, 0x517b, + 0x517b, 0x517b, 0x517b, 0x517b, 0x517c, 0x517c, 0x517c, 0x517c, + 0x517c, 0x517c, 0x517c, 0x517d, 0x517d, 0x517d, 0x517d, 0x517d, + 0x517d, 0x517d, 0x517d, 0x517e, 0x517e, 0x517e, 0x517e, 0x517e, + 0x517e, 0x517e, 0x517e, 0x517f, 0x517f, 0x517f, 0x517f, 0x517f, + 0x517f, 0x517f, 0x5180, 0x5180, 0x5180, 0x5180, 0x5180, 0x5180, + 0x5180, 0x5180, 0x5181, 0x5181, 0x5181, 0x5181, 0x5181, 0x5181, + 0x5181, 0x5181, 0x5182, 0x5182, 0x5182, 0x5182, 0x5182, 0x5182, + 0x5182, 0x5183, 0x5183, 0x5183, 0x5183, 0x5183, 0x5183, 0x5183, + 0x5183, 0x5184, 0x5184, 0x5184, 0x5184, 0x5184, 0x5184, 0x5184, + 0x5184, 0x5185, 0x5185, 0x5185, 0x5185, 0x5185, 0x5185, 0x5185, + 0x5185, 0x5186, 0x5186, 0x5186, 0x5186, 0x5186, 0x5186, 0x5186, + 0x5187, 0x5187, 0x5187, 0x5187, 0x5187, 0x5187, 0x5187, 0x5187, + 0x5188, 0x5188, 0x5188, 0x5188, 0x5188, 0x5188, 0x5188, 0x5188, + 0x5189, 0x5189, 0x5189, 0x5189, 0x5189, 0x5189, 0x5189, 0x5189, + 0x518a, 0x518a, 0x518a, 0x518a, 0x518a, 0x518a, 0x518a, 0x518a, + 0x518b, 0x518b, 0x518b, 0x518b, 0x518b, 0x518b, 0x518b, 0x518b, + 0x518c, 0x518c, 0x518c, 0x518c, 0x518d, 0x518d, 0x518d, 0x518d, + 0x518e, 0x518e, 0x518e, 0x518e, 0x518f, 0x518f, 0x518f, 0x518f, + 0x5190, 0x5190, 0x5190, 0x5190, 0x5191, 0x5191, 0x5191, 0x5191, + 0x5191, 0x5192, 0x5192, 0x5192, 0x5192, 0x5193, 0x5193, 0x5193, + 0x5193, 0x5194, 0x5194, 0x5194, 0x5194, 0x5195, 0x5195, 0x5195, + 0x5195, 0x5196, 0x5196, 0x5196, 0x5196, 0x5197, 0x5197, 0x5197, + 0x5197, 0x5198, 0x5198, 0x5198, 0x5198, 0x5198, 0x5199, 0x5199, + 0x5199, 0x5199, 0x519a, 0x519a, 0x519a, 0x519a, 0x519b, 0x519b, + 0x519b, 0x519b, 0x519c, 0x519c, 0x519c, 0x519c, 0x519c, 0x519d, + 0x519d, 0x519d, 0x519d, 0x519e, 0x519e, 0x519e, 0x519e, 0x519f, + 0x519f, 0x519f, 0x519f, 0x51a0, 0x51a0, 0x51a0, 0x51a0, 0x51a0, + 0x51a1, 0x51a1, 0x51a1, 0x51a1, 0x51a2, 0x51a2, 0x51a2, 0x51a2, + 0x51a3, 0x51a3, 0x51a3, 0x51a3, 0x51a3, 0x51a4, 0x51a4, 0x51a4, + 0x51a4, 0x51a5, 0x51a5, 0x51a5, 0x51a5, 0x51a5, 0x51a6, 0x51a6, + 0x51a6, 0x51a6, 0x51a7, 0x51a7, 0x51a7, 0x51a7, 0x51a7, 0x51a8, + 0x51a8, 0x51a8, 0x51a8, 0x51a9, 0x51a9, 0x51a9, 0x51a9, 0x51a9, + 0x51aa, 0x51aa, 0x51aa, 0x51aa, 0x51ab, 0x51ab, 0x51ab, 0x51ab, + 0x51ab, 0x51ac, 0x51ac, 0x51ac, 0x51ac, 0x51ad, 0x51ad, 0x51ad, + 0x51ad, 0x51ad, 0x51ae, 0x51ae, 0x51ae, 0x51ae, 0x51af, 0x51af, + 0x51af, 0x51af, 0x51af, 0x51b0, 0x51b0, 0x51b0, 0x51b0, 0x51b1, + 0x51b1, 0x51b1, 0x51b1, 0x51b1, 0x51b2, 0x51b2, 0x51b2, 0x51b2, + 0x51b2, 0x51b3, 0x51b3, 0x51b3, 0x51b3, 0x51b4, 0x51b4, 0x51b4, + 0x51b4, 0x51b4, 0x51b5, 0x51b5, 0x51b5, 0x51b5, 0x51b5, 0x51b6, + 0x51b6, 0x51b6, 0x51b6, 0x51b7, 0x51b7, 0x51b7, 0x51b7, 0x51b7, + 0x51b8, 0x51b8, 0x51b8, 0x51b8, 0x51b8, 0x51b9, 0x51b9, 0x51b9, + 0x51b9, 0x51b9, 0x51ba, 0x51ba, 0x51ba, 0x51ba, 0x51ba, 0x51bb, + 0x51bb, 0x51bb, 0x51bb, 0x51bc, 0x51bc, 0x51bc, 0x51bc, 0x51bc, + 0x51bd, 0x51bd, 0x51bd, 0x51bd, 0x51bd, 0x51be, 0x51be, 0x51be, + 0x51be, 0x51be, 0x51bf, 0x51bf, 0x51bf, 0x51bf, 0x51bf, 0x51c0, + 0x51c0, 0x51c0, 0x51c0, 0x51c0, 0x51c1, 0x51c1, 0x51c1, 0x51c1, + 0x51c1, 0x51c2, 0x51c2, 0x51c2, 0x51c2, 0x51c2, 0x51c3, 0x51c3, + 0x51c3, 0x51c3, 0x51c3, 0x51c4, 0x51c4, 0x51c4, 0x51c4, 0x51c4, + 0x51c5, 0x51c5, 0x51c5, 0x51c5, 0x51c5, 0x51c6, 0x51c6, 0x51c6, + 0x51c6, 0x51c6, 0x51c7, 0x51c7, 0x51c7, 0x51c7, 0x51c7, 0x51c8, + 0x51c8, 0x51c8, 0x51c8, 0x51c8, 0x51c9, 0x51c9, 0x51c9, 0x51c9, + 0x51c9, 0x51ca, 0x51ca, 0x51ca, 0x51ca, 0x51ca, 0x51cb, 0x51cb, + 0x51cb, 0x51cb, 0x51cb, 0x51cc, 0x51cc, 0x51cc, 0x51cc, 0x51cc, + 0x51cd, 0x51cd, 0x51cd, 0x51cd, 0x51cd, 0x51ce, 0x51ce, 0x51ce, + 0x51ce, 0x51ce, 0x51ce, 0x51cf, 0x51cf, 0x51cf, 0x51cf, 0x51cf, + 0x51d0, 0x51d0, 0x51d0, 0x51d0, 0x51d0, 0x51d1, 0x51d1, 0x51d1, + 0x51d1, 0x51d1, 0x51d2, 0x51d2, 0x51d2, 0x51d2, 0x51d2, 0x51d3, + 0x51d3, 0x51d3, 0x51d3, 0x51d3, 0x51d3, 0x51d4, 0x51d4, 0x51d4, + 0x51d4, 0x51d4, 0x51d5, 0x51d5, 0x51d5, 0x51d5, 0x51d5, 0x51d6, + 0x51d6, 0x51d6, 0x51d6, 0x51d6, 0x51d6, 0x51d7, 0x51d7, 0x51d7, + 0x51d7, 0x51d7, 0x51d8, 0x51d8, 0x51d8, 0x51d8, 0x51d8, 0x51d9, + 0x51d9, 0x51d9, 0x51d9, 0x51d9, 0x51d9, 0x51da, 0x51da, 0x51da, + 0x51da, 0x51da, 0x51db, 0x51db, 0x51db, 0x51db, 0x51db, 0x51db, + 0x51dc, 0x51dc, 0x51dc, 0x51dc, 0x51dc, 0x51dd, 0x51dd, 0x51dd, + 0x51dd, 0x51dd, 0x51dd, 0x51de, 0x51de, 0x51de, 0x51de, 0x51de, + 0x51df, 0x51df, 0x51df, 0x51df, 0x51df, 0x51df, 0x51e0, 0x51e0, + 0x51e0, 0x51e0, 0x51e0, 0x51e1, 0x51e1, 0x51e1, 0x51e1, 0x51e1, + 0x51e1, 0x51e2, 0x51e2, 0x51e2, 0x51e2, 0x51e2, 0x51e2, 0x51e3, + 0x51e3, 0x51e3, 0x51e3, 0x51e3, 0x51e4, 0x51e4, 0x51e4, 0x51e4, + 0x51e4, 0x51e4, 0x51e5, 0x51e5, 0x51e5, 0x51e5, 0x51e5, 0x51e5, + 0x51e6, 0x51e6, 0x51e6, 0x51e6, 0x51e6, 0x51e7, 0x51e7, 0x51e7, + 0x51e7, 0x51e7, 0x51e7, 0x51e8, 0x51e8, 0x51e8, 0x51e8, 0x51e8, + 0x51e8, 0x51e9, 0x51e9, 0x51e9, 0x51e9, 0x51e9, 0x51ea, 0x51ea, + 0x51ea, 0x51ea, 0x51ea, 0x51ea, 0x51eb, 0x51eb, 0x51eb, 0x51eb, + 0x51eb, 0x51eb, 0x51ec, 0x51ec, 0x51ec, 0x51ec, 0x51ec, 0x51ec, + 0x51ed, 0x51ed, 0x51ed, 0x51ed, 0x51ed, 0x51ed, 0x51ee, 0x51ee, + 0x51ee, 0x51ee, 0x51ee, 0x51ee, 0x51ef, 0x51ef, 0x51ef, 0x51ef, + 0x51ef, 0x51f0, 0x51f0, 0x51f0, 0x51f0, 0x51f0, 0x51f0, 0x51f1, + 0x51f1, 0x51f1, 0x51f1, 0x51f1, 0x51f1, 0x51f2, 0x51f2, 0x51f2, + 0x51f2, 0x51f2, 0x51f2, 0x51f3, 0x51f3, 0x51f3, 0x51f3, 0x51f3, + 0x51f3, 0x51f4, 0x51f4, 0x51f4, 0x51f4, 0x51f4, 0x51f4, 0x51f5, + 0x51f5, 0x51f5, 0x51f5, 0x51f5, 0x51f5, 0x51f6, 0x51f6, 0x51f6, + 0x51f6, 0x51f6, 0x51f6, 0x51f7, 0x51f7, 0x51f7, 0x51f7, 0x51f7, + 0x51f7, 0x51f7, 0x51f8, 0x51f8, 0x51f8, 0x51f8, 0x51f8, 0x51f8, + 0x51f9, 0x51f9, 0x51f9, 0x51f9, 0x51f9, 0x51f9, 0x51fa, 0x51fa, + 0x51fa, 0x51fa, 0x51fa, 0x51fa, 0x51fb, 0x51fb, 0x51fb, 0x51fb, + 0x51fb, 0x51fb, 0x51fc, 0x51fc, 0x51fc, 0x51fc, 0x51fc, 0x51fc, + 0x51fd, 0x51fd, 0x51fd, 0x51fd, 0x51fd, 0x51fd, 0x51fd, 0x51fe, + 0x51fe, 0x51fe, 0x51fe, 0x51fe, 0x51fe, 0x51ff, 0x51ff, 0x51ff, + 0x51ff, 0x51ff, 0x51ff, 0x5200, 0x5200, 0x5200, 0x5200, 0x5200, + 0x5200, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, + 0x5202, 0x5202, 0x5202, 0x5202, 0x5202, 0x5202, 0x5203, 0x5203, + 0x5203, 0x5203, 0x5203, 0x5203, 0x5204, 0x5204, 0x5204, 0x5204, + 0x5204, 0x5204, 0x5204, 0x5205, 0x5205, 0x5205, 0x5205, 0x5205, + 0x5205, 0x5206, 0x5206, 0x5206, 0x5206, 0x5206, 0x5206, 0x5206, + 0x5207, 0x5207, 0x5207, 0x5207, 0x5207, 0x5207, 0x5208, 0x5208, + 0x5208, 0x5208, 0x5208, 0x5208, 0x5208, 0x5209, 0x5209, 0x5209, + 0x5209, 0x5209, 0x5209, 0x520a, 0x520a, 0x520a, 0x520a, 0x520a, + 0x520a, 0x520a, 0x520b, 0x520b, 0x520b, 0x520b, 0x520b, 0x520b, + 0x520c, 0x520c, 0x520c, 0x520c, 0x520c, 0x520c, 0x520c, 0x520d, + 0x520d, 0x520d, 0x520d, 0x520d, 0x520d, 0x520d, 0x520e, 0x520e, + 0x520e, 0x520e, 0x520e, 0x520e, 0x520f, 0x520f, 0x520f, 0x520f, + 0x520f, 0x520f, 0x520f, 0x5210, 0x5210, 0x5210, 0x5210, 0x5210, + 0x5210, 0x5210, 0x5211, 0x5211, 0x5211, 0x5211, 0x5211, 0x5211, + 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5213, + 0x5213, 0x5213, 0x5213, 0x5213, 0x5213, 0x5213, 0x5214, 0x5214, + 0x5214, 0x5214, 0x5214, 0x5214, 0x5214, 0x5215, 0x5215, 0x5215, + 0x5215, 0x5215, 0x5215, 0x5215, 0x5216, 0x5216, 0x5216, 0x5216, + 0x5216, 0x5216, 0x5217, 0x5217, 0x5217, 0x5217, 0x5217, 0x5217, + 0x5217, 0x5218, 0x5218, 0x5218, 0x5218, 0x5218, 0x5218, 0x5218, + 0x5219, 0x5219, 0x5219, 0x5219, 0x5219, 0x5219, 0x5219, 0x521a, + 0x521a, 0x521a, 0x521a, 0x521a, 0x521a, 0x521a, 0x521b, 0x521b, + 0x521b, 0x521b, 0x521b, 0x521b, 0x521b, 0x521c, 0x521c, 0x521c, + 0x521c, 0x521c, 0x521c, 0x521c, 0x521d, 0x521d, 0x521d, 0x521d, + 0x521d, 0x521d, 0x521d, 0x521e, 0x521e, 0x521e, 0x521e, 0x521e, + 0x521e, 0x521e, 0x521f, 0x521f, 0x521f, 0x521f, 0x521f, 0x521f, + 0x521f, 0x521f, 0x5220, 0x5220, 0x5220, 0x5220, 0x5220, 0x5220, + 0x5220, 0x5221, 0x5221, 0x5221, 0x5221, 0x5221, 0x5221, 0x5221, + 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5223, + 0x5223, 0x5223, 0x5223, 0x5223, 0x5223, 0x5223, 0x5224, 0x5224, + 0x5224, 0x5224, 0x5224, 0x5224, 0x5224, 0x5224, 0x5225, 0x5225, + 0x5225, 0x5225, 0x5225, 0x5225, 0x5225, 0x5226, 0x5226, 0x5226, + 0x5226, 0x5226, 0x5226, 0x5226, 0x5227, 0x5227, 0x5227, 0x5227, + 0x5227, 0x5227, 0x5227, 0x5228, 0x5228, 0x5228, 0x5228, 0x5228, + 0x5228, 0x5228, 0x5228, 0x5229, 0x5229, 0x5229, 0x5229, 0x5229, + 0x5229, 0x5229, 0x522a, 0x522a, 0x522a, 0x522a, 0x522a, 0x522a, + 0x522a, 0x522a, 0x522b, 0x522b, 0x522b, 0x522b, 0x522b, 0x522b, + 0x522b, 0x522c, 0x522c, 0x522c, 0x522c, 0x522c, 0x522c, 0x522c, + 0x522c, 0x522d, 0x522d, 0x522d, 0x522d, 0x522d, 0x522d, 0x522d, + 0x522e, 0x522e, 0x522e, 0x522e, 0x522e, 0x522e, 0x522e, 0x522e, + 0x522f, 0x522f, 0x522f, 0x522f, 0x522f, 0x522f, 0x522f, 0x5230, + 0x5230, 0x5230, 0x5230, 0x5230, 0x5230, 0x5230, 0x5230, 0x5231, + 0x5231, 0x5231, 0x5231, 0x5231, 0x5231, 0x5231, 0x5232, 0x5232, + 0x5232, 0x5232, 0x5232, 0x5232, 0x5232, 0x5232, 0x5233, 0x5233, + 0x5233, 0x5233, 0x5233, 0x5233, 0x5233, 0x5233, 0x5234, 0x5234, + 0x5234, 0x5234, 0x5234, 0x5234, 0x5234, 0x5234, 0x5235, 0x5235, + 0x5235, 0x5235, 0x5235, 0x5235, 0x5235, 0x5236, 0x5236, 0x5236, + 0x5236, 0x5236, 0x5236, 0x5236, 0x5236, 0x5237, 0x5237, 0x5237, + 0x5237, 0x5237, 0x5237, 0x5237, 0x5237, 0x5238, 0x5238, 0x5238, + 0x5238, 0x5238, 0x5238, 0x5238, 0x5238, 0x5239, 0x5239, 0x5239, + 0x5239, 0x5239, 0x5239, 0x5239, 0x5239, 0x523a, 0x523a, 0x523a, + 0x523a, 0x523a, 0x523a, 0x523a, 0x523a, 0x523b, 0x523b, 0x523b, + 0x523b, 0x523b, 0x523b, 0x523b, 0x523c, 0x523c, 0x523c, 0x523c, + 0x523c, 0x523c, 0x523c, 0x523c, 0x523d, 0x523d, 0x523d, 0x523d, + 0x523d, 0x523d, 0x523e, 0x523e, 0x523e, 0x523e, 0x523f, 0x523f, + 0x523f, 0x523f, 0x523f, 0x5240, 0x5240, 0x5240, 0x5240, 0x5241, + 0x5241, 0x5241, 0x5241, 0x5242, 0x5242, 0x5242, 0x5242, 0x5243, + 0x5243, 0x5243, 0x5243, 0x5244, 0x5244, 0x5244, 0x5244, 0x5245, + 0x5245, 0x5245, 0x5245, 0x5246, 0x5246, 0x5246, 0x5246, 0x5247, + 0x5247, 0x5247, 0x5247, 0x5248, 0x5248, 0x5248, 0x5248, 0x5248, + 0x5249, 0x5249, 0x5249, 0x5249, 0x524a, 0x524a, 0x524a, 0x524a, + 0x524b, 0x524b, 0x524b, 0x524b, 0x524c, 0x524c, 0x524c, 0x524c, + 0x524d, 0x524d, 0x524d, 0x524d, 0x524d, 0x524e, 0x524e, 0x524e, + 0x524e, 0x524f, 0x524f, 0x524f, 0x524f, 0x5250, 0x5250, 0x5250, + 0x5250, 0x5251, 0x5251, 0x5251, 0x5251, 0x5251, 0x5252, 0x5252, + 0x5252, 0x5252, 0x5253, 0x5253, 0x5253, 0x5253, 0x5253, 0x5254, + 0x5254, 0x5254, 0x5254, 0x5255, 0x5255, 0x5255, 0x5255, 0x5256, + 0x5256, 0x5256, 0x5256, 0x5256, 0x5257, 0x5257, 0x5257, 0x5257, + 0x5258, 0x5258, 0x5258, 0x5258, 0x5258, 0x5259, 0x5259, 0x5259, + 0x5259, 0x525a, 0x525a, 0x525a, 0x525a, 0x525a, 0x525b, 0x525b, + 0x525b, 0x525b, 0x525c, 0x525c, 0x525c, 0x525c, 0x525c, 0x525d, + 0x525d, 0x525d, 0x525d, 0x525e, 0x525e, 0x525e, 0x525e, 0x525e, + 0x525f, 0x525f, 0x525f, 0x525f, 0x5260, 0x5260, 0x5260, 0x5260, + 0x5260, 0x5261, 0x5261, 0x5261, 0x5261, 0x5262, 0x5262, 0x5262, + 0x5262, 0x5262, 0x5263, 0x5263, 0x5263, 0x5263, 0x5263, 0x5264, + 0x5264, 0x5264, 0x5264, 0x5265, 0x5265, 0x5265, 0x5265, 0x5265, + 0x5266, 0x5266, 0x5266, 0x5266, 0x5266, 0x5267, 0x5267, 0x5267, + 0x5267, 0x5268, 0x5268, 0x5268, 0x5268, 0x5268, 0x5269, 0x5269, + 0x5269, 0x5269, 0x5269, 0x526a, 0x526a, 0x526a, 0x526a, 0x526a, + 0x526b, 0x526b, 0x526b, 0x526b, 0x526c, 0x526c, 0x526c, 0x526c, + 0x526c, 0x526d, 0x526d, 0x526d, 0x526d, 0x526d, 0x526e, 0x526e, + 0x526e, 0x526e, 0x526e, 0x526f, 0x526f, 0x526f, 0x526f, 0x526f, + 0x5270, 0x5270, 0x5270, 0x5270, 0x5270, 0x5271, 0x5271, 0x5271, + 0x5271, 0x5271, 0x5272, 0x5272, 0x5272, 0x5272, 0x5273, 0x5273, + 0x5273, 0x5273, 0x5273, 0x5274, 0x5274, 0x5274, 0x5274, 0x5274, + 0x5275, 0x5275, 0x5275, 0x5275, 0x5275, 0x5276, 0x5276, 0x5276, + 0x5276, 0x5276, 0x5277, 0x5277, 0x5277, 0x5277, 0x5277, 0x5278, + 0x5278, 0x5278, 0x5278, 0x5278, 0x5279, 0x5279, 0x5279, 0x5279, + 0x5279, 0x527a, 0x527a, 0x527a, 0x527a, 0x527a, 0x527a, 0x527b, + 0x527b, 0x527b, 0x527b, 0x527b, 0x527c, 0x527c, 0x527c, 0x527c, + 0x527c, 0x527d, 0x527d, 0x527d, 0x527d, 0x527d, 0x527e, 0x527e, + 0x527e, 0x527e, 0x527e, 0x527f, 0x527f, 0x527f, 0x527f, 0x527f, + 0x5280, 0x5280, 0x5280, 0x5280, 0x5280, 0x5281, 0x5281, 0x5281, + 0x5281, 0x5281, 0x5281, 0x5282, 0x5282, 0x5282, 0x5282, 0x5282, + 0x5283, 0x5283, 0x5283, 0x5283, 0x5283, 0x5284, 0x5284, 0x5284, + 0x5284, 0x5284, 0x5285, 0x5285, 0x5285, 0x5285, 0x5285, 0x5285, + 0x5286, 0x5286, 0x5286, 0x5286, 0x5286, 0x5287, 0x5287, 0x5287, + 0x5287, 0x5287, 0x5288, 0x5288, 0x5288, 0x5288, 0x5288, 0x5288, + 0x5289, 0x5289, 0x5289, 0x5289, 0x5289, 0x528a, 0x528a, 0x528a, + 0x528a, 0x528a, 0x528b, 0x528b, 0x528b, 0x528b, 0x528b, 0x528b, + 0x528c, 0x528c, 0x528c, 0x528c, 0x528c, 0x528d, 0x528d, 0x528d, + 0x528d, 0x528d, 0x528d, 0x528e, 0x528e, 0x528e, 0x528e, 0x528e, + 0x528f, 0x528f, 0x528f, 0x528f, 0x528f, 0x528f, 0x5290, 0x5290, + 0x5290, 0x5290, 0x5290, 0x5291, 0x5291, 0x5291, 0x5291, 0x5291, + 0x5291, 0x5292, 0x5292, 0x5292, 0x5292, 0x5292, 0x5293, 0x5293, + 0x5293, 0x5293, 0x5293, 0x5293, 0x5294, 0x5294, 0x5294, 0x5294, + 0x5294, 0x5294, 0x5295, 0x5295, 0x5295, 0x5295, 0x5295, 0x5296, + 0x5296, 0x5296, 0x5296, 0x5296, 0x5296, 0x5297, 0x5297, 0x5297, + 0x5297, 0x5297, 0x5297, 0x5298, 0x5298, 0x5298, 0x5298, 0x5298, + 0x5299, 0x5299, 0x5299, 0x5299, 0x5299, 0x5299, 0x529a, 0x529a, + 0x529a, 0x529a, 0x529a, 0x529a, 0x529b, 0x529b, 0x529b, 0x529b, + 0x529b, 0x529b, 0x529c, 0x529c, 0x529c, 0x529c, 0x529c, 0x529d, + 0x529d, 0x529d, 0x529d, 0x529d, 0x529d, 0x529e, 0x529e, 0x529e, + 0x529e, 0x529e, 0x529e, 0x529f, 0x529f, 0x529f, 0x529f, 0x529f, + 0x529f, 0x52a0, 0x52a0, 0x52a0, 0x52a0, 0x52a0, 0x52a0, 0x52a1, + 0x52a1, 0x52a1, 0x52a1, 0x52a1, 0x52a1, 0x52a2, 0x52a2, 0x52a2, + 0x52a2, 0x52a2, 0x52a2, 0x52a3, 0x52a3, 0x52a3, 0x52a3, 0x52a3, + 0x52a3, 0x52a4, 0x52a4, 0x52a4, 0x52a4, 0x52a4, 0x52a4, 0x52a5, + 0x52a5, 0x52a5, 0x52a5, 0x52a5, 0x52a5, 0x52a6, 0x52a6, 0x52a6, + 0x52a6, 0x52a6, 0x52a6, 0x52a7, 0x52a7, 0x52a7, 0x52a7, 0x52a7, + 0x52a7, 0x52a8, 0x52a8, 0x52a8, 0x52a8, 0x52a8, 0x52a8, 0x52a9, + 0x52a9, 0x52a9, 0x52a9, 0x52a9, 0x52a9, 0x52aa, 0x52aa, 0x52aa, + 0x52aa, 0x52aa, 0x52aa, 0x52ab, 0x52ab, 0x52ab, 0x52ab, 0x52ab, + 0x52ab, 0x52ac, 0x52ac, 0x52ac, 0x52ac, 0x52ac, 0x52ac, 0x52ad, + 0x52ad, 0x52ad, 0x52ad, 0x52ad, 0x52ad, 0x52ad, 0x52ae, 0x52ae, + 0x52ae, 0x52ae, 0x52ae, 0x52ae, 0x52af, 0x52af, 0x52af, 0x52af, + 0x52af, 0x52af, 0x52b0, 0x52b0, 0x52b0, 0x52b0, 0x52b0, 0x52b0, + 0x52b1, 0x52b1, 0x52b1, 0x52b1, 0x52b1, 0x52b1, 0x52b1, 0x52b2, + 0x52b2, 0x52b2, 0x52b2, 0x52b2, 0x52b2, 0x52b3, 0x52b3, 0x52b3, + 0x52b3, 0x52b3, 0x52b3, 0x52b4, 0x52b4, 0x52b4, 0x52b4, 0x52b4, + 0x52b4, 0x52b4, 0x52b5, 0x52b5, 0x52b5, 0x52b5, 0x52b5, 0x52b5, + 0x52b6, 0x52b6, 0x52b6, 0x52b6, 0x52b6, 0x52b6, 0x52b7, 0x52b7, + 0x52b7, 0x52b7, 0x52b7, 0x52b7, 0x52b7, 0x52b8, 0x52b8, 0x52b8, + 0x52b8, 0x52b8, 0x52b8, 0x52b9, 0x52b9, 0x52b9, 0x52b9, 0x52b9, + 0x52b9, 0x52b9, 0x52ba, 0x52ba, 0x52ba, 0x52ba, 0x52ba, 0x52ba, + 0x52bb, 0x52bb, 0x52bb, 0x52bb, 0x52bb, 0x52bb, 0x52bb, 0x52bc, + 0x52bc, 0x52bc, 0x52bc, 0x52bc, 0x52bc, 0x52bd, 0x52bd, 0x52bd, + 0x52bd, 0x52bd, 0x52bd, 0x52bd, 0x52be, 0x52be, 0x52be, 0x52be, + 0x52be, 0x52be, 0x52be, 0x52bf, 0x52bf, 0x52bf, 0x52bf, 0x52bf, + 0x52bf, 0x52c0, 0x52c0, 0x52c0, 0x52c0, 0x52c0, 0x52c0, 0x52c0, + 0x52c1, 0x52c1, 0x52c1, 0x52c1, 0x52c1, 0x52c1, 0x52c1, 0x52c2, + 0x52c2, 0x52c2, 0x52c2, 0x52c2, 0x52c2, 0x52c3, 0x52c3, 0x52c3, + 0x52c3, 0x52c3, 0x52c3, 0x52c3, 0x52c4, 0x52c4, 0x52c4, 0x52c4, + 0x52c4, 0x52c4, 0x52c4, 0x52c5, 0x52c5, 0x52c5, 0x52c5, 0x52c5, + 0x52c5, 0x52c5, 0x52c6, 0x52c6, 0x52c6, 0x52c6, 0x52c6, 0x52c6, + 0x52c6, 0x52c7, 0x52c7, 0x52c7, 0x52c7, 0x52c7, 0x52c7, 0x52c8, + 0x52c8, 0x52c8, 0x52c8, 0x52c8, 0x52c8, 0x52c8, 0x52c9, 0x52c9, + 0x52c9, 0x52c9, 0x52c9, 0x52c9, 0x52c9, 0x52ca, 0x52ca, 0x52ca, + 0x52ca, 0x52ca, 0x52ca, 0x52ca, 0x52cb, 0x52cb, 0x52cb, 0x52cb, + 0x52cb, 0x52cb, 0x52cb, 0x52cc, 0x52cc, 0x52cc, 0x52cc, 0x52cc, + 0x52cc, 0x52cc, 0x52cd, 0x52cd, 0x52cd, 0x52cd, 0x52cd, 0x52cd, + 0x52cd, 0x52ce, 0x52ce, 0x52ce, 0x52ce, 0x52ce, 0x52ce, 0x52ce, + 0x52cf, 0x52cf, 0x52cf, 0x52cf, 0x52cf, 0x52cf, 0x52cf, 0x52d0, + 0x52d0, 0x52d0, 0x52d0, 0x52d0, 0x52d0, 0x52d0, 0x52d1, 0x52d1, + 0x52d1, 0x52d1, 0x52d1, 0x52d1, 0x52d1, 0x52d2, 0x52d2, 0x52d2, + 0x52d2, 0x52d2, 0x52d2, 0x52d2, 0x52d2, 0x52d3, 0x52d3, 0x52d3, + 0x52d3, 0x52d3, 0x52d3, 0x52d3, 0x52d4, 0x52d4, 0x52d4, 0x52d4, + 0x52d4, 0x52d4, 0x52d4, 0x52d5, 0x52d5, 0x52d5, 0x52d5, 0x52d5, + 0x52d5, 0x52d5, 0x52d6, 0x52d6, 0x52d6, 0x52d6, 0x52d6, 0x52d6, + 0x52d6, 0x52d6, 0x52d7, 0x52d7, 0x52d7, 0x52d7, 0x52d7, 0x52d7, + 0x52d7, 0x52d8, 0x52d8, 0x52d8, 0x52d8, 0x52d8, 0x52d8, 0x52d8, + 0x52d9, 0x52d9, 0x52d9, 0x52d9, 0x52d9, 0x52d9, 0x52d9, 0x52d9, + 0x52da, 0x52da, 0x52da, 0x52da, 0x52da, 0x52da, 0x52da, 0x52db, + 0x52db, 0x52db, 0x52db, 0x52db, 0x52db, 0x52db, 0x52dc, 0x52dc, + 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dd, 0x52dd, + 0x52dd, 0x52dd, 0x52dd, 0x52dd, 0x52dd, 0x52de, 0x52de, 0x52de, + 0x52de, 0x52de, 0x52de, 0x52de, 0x52de, 0x52df, 0x52df, 0x52df, + 0x52df, 0x52df, 0x52df, 0x52df, 0x52e0, 0x52e0, 0x52e0, 0x52e0, + 0x52e0, 0x52e0, 0x52e0, 0x52e0, 0x52e1, 0x52e1, 0x52e1, 0x52e1, + 0x52e1, 0x52e1, 0x52e1, 0x52e2, 0x52e2, 0x52e2, 0x52e2, 0x52e2, + 0x52e2, 0x52e2, 0x52e2, 0x52e3, 0x52e3, 0x52e3, 0x52e3, 0x52e3, + 0x52e3, 0x52e3, 0x52e3, 0x52e4, 0x52e4, 0x52e4, 0x52e4, 0x52e4, + 0x52e4, 0x52e4, 0x52e5, 0x52e5, 0x52e5, 0x52e5, 0x52e5, 0x52e5, + 0x52e5, 0x52e5, 0x52e6, 0x52e6, 0x52e6, 0x52e6, 0x52e6, 0x52e6, + 0x52e6, 0x52e6, 0x52e7, 0x52e7, 0x52e7, 0x52e7, 0x52e7, 0x52e7, + 0x52e7, 0x52e7, 0x52e8, 0x52e8, 0x52e8, 0x52e8, 0x52e8, 0x52e8, + 0x52e8, 0x52e9, 0x52e9, 0x52e9, 0x52e9, 0x52e9, 0x52e9, 0x52e9, + 0x52e9, 0x52ea, 0x52ea, 0x52ea, 0x52ea, 0x52ea, 0x52ea, 0x52ea, + 0x52ea, 0x52eb, 0x52eb, 0x52eb, 0x52eb, 0x52eb, 0x52eb, 0x52eb, + 0x52eb, 0x52ec, 0x52ec, 0x52ec, 0x52ec, 0x52ec, 0x52ec, 0x52ec, + 0x52ec, 0x52ed, 0x52ed, 0x52ed, 0x52ed, 0x52ed, 0x52ed, 0x52ed, + 0x52ed, 0x52ee, 0x52ee, 0x52ee, 0x52ee, 0x52ee, 0x52ee, 0x52ee, + 0x52ee, 0x52ef, 0x52ef, 0x52ef, 0x52ef, 0x52f0, 0x52f0, 0x52f0, + 0x52f0, 0x52f1, 0x52f1, 0x52f1, 0x52f1, 0x52f2, 0x52f2, 0x52f2, + 0x52f2, 0x52f3, 0x52f3, 0x52f3, 0x52f3, 0x52f4, 0x52f4, 0x52f4, + 0x52f4, 0x52f5, 0x52f5, 0x52f5, 0x52f5, 0x52f6, 0x52f6, 0x52f6, + 0x52f6, 0x52f7, 0x52f7, 0x52f7, 0x52f7, 0x52f8, 0x52f8, 0x52f8, + 0x52f8, 0x52f9, 0x52f9, 0x52f9, 0x52f9, 0x52f9, 0x52fa, 0x52fa, + 0x52fa, 0x52fa, 0x52fb, 0x52fb, 0x52fb, 0x52fb, 0x52fc, 0x52fc, + 0x52fc, 0x52fc, 0x52fd, 0x52fd, 0x52fd, 0x52fd, 0x52fe, 0x52fe, + 0x52fe, 0x52fe, 0x52fe, 0x52ff, 0x52ff, 0x52ff, 0x52ff, 0x5300, + 0x5300, 0x5300, 0x5300, 0x5301, 0x5301, 0x5301, 0x5301, 0x5301, + 0x5302, 0x5302, 0x5302, 0x5302, 0x5303, 0x5303, 0x5303, 0x5303, + 0x5304, 0x5304, 0x5304, 0x5304, 0x5304, 0x5305, 0x5305, 0x5305, + 0x5305, 0x5306, 0x5306, 0x5306, 0x5306, 0x5307, 0x5307, 0x5307, + 0x5307, 0x5307, 0x5308, 0x5308, 0x5308, 0x5308, 0x5309, 0x5309, + 0x5309, 0x5309, 0x5309, 0x530a, 0x530a, 0x530a, 0x530a, 0x530b, + 0x530b, 0x530b, 0x530b, 0x530b, 0x530c, 0x530c, 0x530c, 0x530c, + 0x530d, 0x530d, 0x530d, 0x530d, 0x530d, 0x530e, 0x530e, 0x530e, + 0x530e, 0x530f, 0x530f, 0x530f, 0x530f, 0x530f, 0x5310, 0x5310, + 0x5310, 0x5310, 0x5311, 0x5311, 0x5311, 0x5311, 0x5311, 0x5312, + 0x5312, 0x5312, 0x5312, 0x5313, 0x5313, 0x5313, 0x5313, 0x5313, + 0x5314, 0x5314, 0x5314, 0x5314, 0x5314, 0x5315, 0x5315, 0x5315, + 0x5315, 0x5316, 0x5316, 0x5316, 0x5316, 0x5316, 0x5317, 0x5317, + 0x5317, 0x5317, 0x5317, 0x5318, 0x5318, 0x5318, 0x5318, 0x5319, + 0x5319, 0x5319, 0x5319, 0x5319, 0x531a, 0x531a, 0x531a, 0x531a, + 0x531a, 0x531b, 0x531b, 0x531b, 0x531b, 0x531c, 0x531c, 0x531c, + 0x531c, 0x531c, 0x531d, 0x531d, 0x531d, 0x531d, 0x531d, 0x531e, + 0x531e, 0x531e, 0x531e, 0x531e, 0x531f, 0x531f, 0x531f, 0x531f, + 0x531f, 0x5320, 0x5320, 0x5320, 0x5320, 0x5320, 0x5321, 0x5321, + 0x5321, 0x5321, 0x5322, 0x5322, 0x5322, 0x5322, 0x5322, 0x5323, + 0x5323, 0x5323, 0x5323, 0x5323, 0x5324, 0x5324, 0x5324, 0x5324, + 0x5324, 0x5325, 0x5325, 0x5325, 0x5325, 0x5325, 0x5326, 0x5326, + 0x5326, 0x5326, 0x5326, 0x5327, 0x5327, 0x5327, 0x5327, 0x5327, + 0x5328, 0x5328, 0x5328, 0x5328, 0x5328, 0x5329, 0x5329, 0x5329, + 0x5329, 0x5329, 0x532a, 0x532a, 0x532a, 0x532a, 0x532a, 0x532b, + 0x532b, 0x532b, 0x532b, 0x532b, 0x532c, 0x532c, 0x532c, 0x532c, + 0x532c, 0x532d, 0x532d, 0x532d, 0x532d, 0x532d, 0x532e, 0x532e, + 0x532e, 0x532e, 0x532e, 0x532e, 0x532f, 0x532f, 0x532f, 0x532f, + 0x532f, 0x5330, 0x5330, 0x5330, 0x5330, 0x5330, 0x5331, 0x5331, + 0x5331, 0x5331, 0x5331, 0x5332, 0x5332, 0x5332, 0x5332, 0x5332, + 0x5333, 0x5333, 0x5333, 0x5333, 0x5333, 0x5333, 0x5334, 0x5334, + 0x5334, 0x5334, 0x5334, 0x5335, 0x5335, 0x5335, 0x5335, 0x5335, + 0x5336, 0x5336, 0x5336, 0x5336, 0x5336, 0x5337, 0x5337, 0x5337, + 0x5337, 0x5337, 0x5337, 0x5338, 0x5338, 0x5338, 0x5338, 0x5338, + 0x5339, 0x5339, 0x5339, 0x5339, 0x5339, 0x533a, 0x533a, 0x533a, + 0x533a, 0x533a, 0x533a, 0x533b, 0x533b, 0x533b, 0x533b, 0x533b, + 0x533c, 0x533c, 0x533c, 0x533c, 0x533c, 0x533d, 0x533d, 0x533d, + 0x533d, 0x533d, 0x533d, 0x533e, 0x533e, 0x533e, 0x533e, 0x533e, + 0x533f, 0x533f, 0x533f, 0x533f, 0x533f, 0x533f, 0x5340, 0x5340, + 0x5340, 0x5340, 0x5340, 0x5341, 0x5341, 0x5341, 0x5341, 0x5341, + 0x5341, 0x5342, 0x5342, 0x5342, 0x5342, 0x5342, 0x5343, 0x5343, + 0x5343, 0x5343, 0x5343, 0x5343, 0x5344, 0x5344, 0x5344, 0x5344, + 0x5344, 0x5344, 0x5345, 0x5345, 0x5345, 0x5345, 0x5345, 0x5346, + 0x5346, 0x5346, 0x5346, 0x5346, 0x5346, 0x5347, 0x5347, 0x5347, + 0x5347, 0x5347, 0x5348, 0x5348, 0x5348, 0x5348, 0x5348, 0x5348, + 0x5349, 0x5349, 0x5349, 0x5349, 0x5349, 0x5349, 0x534a, 0x534a, + 0x534a, 0x534a, 0x534a, 0x534a, 0x534b, 0x534b, 0x534b, 0x534b, + 0x534b, 0x534c, 0x534c, 0x534c, 0x534c, 0x534c, 0x534c, 0x534d, + 0x534d, 0x534d, 0x534d, 0x534d, 0x534d, 0x534e, 0x534e, 0x534e, + 0x534e, 0x534e, 0x534e, 0x534f, 0x534f, 0x534f, 0x534f, 0x534f, + 0x5350, 0x5350, 0x5350, 0x5350, 0x5350, 0x5350, 0x5351, 0x5351, + 0x5351, 0x5351, 0x5351, 0x5351, 0x5352, 0x5352, 0x5352, 0x5352, + 0x5352, 0x5352, 0x5353, 0x5353, 0x5353, 0x5353, 0x5353, 0x5353, + 0x5354, 0x5354, 0x5354, 0x5354, 0x5354, 0x5354, 0x5355, 0x5355, + 0x5355, 0x5355, 0x5355, 0x5355, 0x5356, 0x5356, 0x5356, 0x5356, + 0x5356, 0x5356, 0x5357, 0x5357, 0x5357, 0x5357, 0x5357, 0x5357, + 0x5358, 0x5358, 0x5358, 0x5358, 0x5358, 0x5358, 0x5359, 0x5359, + 0x5359, 0x5359, 0x5359, 0x5359, 0x535a, 0x535a, 0x535a, 0x535a, + 0x535a, 0x535a, 0x535b, 0x535b, 0x535b, 0x535b, 0x535b, 0x535b, + 0x535c, 0x535c, 0x535c, 0x535c, 0x535c, 0x535c, 0x535d, 0x535d, + 0x535d, 0x535d, 0x535d, 0x535d, 0x535d, 0x535e, 0x535e, 0x535e, + 0x535e, 0x535e, 0x535e, 0x535f, 0x535f, 0x535f, 0x535f, 0x535f, + 0x535f, 0x5360, 0x5360, 0x5360, 0x5360, 0x5360, 0x5360, 0x5361, + 0x5361, 0x5361, 0x5361, 0x5361, 0x5361, 0x5362, 0x5362, 0x5362, + 0x5362, 0x5362, 0x5362, 0x5362, 0x5363, 0x5363, 0x5363, 0x5363, + 0x5363, 0x5363, 0x5364, 0x5364, 0x5364, 0x5364, 0x5364, 0x5364, + 0x5365, 0x5365, 0x5365, 0x5365, 0x5365, 0x5365, 0x5365, 0x5366, + 0x5366, 0x5366, 0x5366, 0x5366, 0x5366, 0x5367, 0x5367, 0x5367, + 0x5367, 0x5367, 0x5367, 0x5367, 0x5368, 0x5368, 0x5368, 0x5368, + 0x5368, 0x5368, 0x5369, 0x5369, 0x5369, 0x5369, 0x5369, 0x5369, + 0x536a, 0x536a, 0x536a, 0x536a, 0x536a, 0x536a, 0x536a, 0x536b, + 0x536b, 0x536b, 0x536b, 0x536b, 0x536b, 0x536c, 0x536c, 0x536c, + 0x536c, 0x536c, 0x536c, 0x536c, 0x536d, 0x536d, 0x536d, 0x536d, + 0x536d, 0x536d, 0x536e, 0x536e, 0x536e, 0x536e, 0x536e, 0x536e, + 0x536e, 0x536f, 0x536f, 0x536f, 0x536f, 0x536f, 0x536f, 0x536f, + 0x5370, 0x5370, 0x5370, 0x5370, 0x5370, 0x5370, 0x5371, 0x5371, + 0x5371, 0x5371, 0x5371, 0x5371, 0x5371, 0x5372, 0x5372, 0x5372, + 0x5372, 0x5372, 0x5372, 0x5372, 0x5373, 0x5373, 0x5373, 0x5373, + 0x5373, 0x5373, 0x5374, 0x5374, 0x5374, 0x5374, 0x5374, 0x5374, + 0x5374, 0x5375, 0x5375, 0x5375, 0x5375, 0x5375, 0x5375, 0x5375, + 0x5376, 0x5376, 0x5376, 0x5376, 0x5376, 0x5376, 0x5376, 0x5377, + 0x5377, 0x5377, 0x5377, 0x5377, 0x5377, 0x5378, 0x5378, 0x5378, + 0x5378, 0x5378, 0x5378, 0x5378, 0x5379, 0x5379, 0x5379, 0x5379, + 0x5379, 0x5379, 0x5379, 0x537a, 0x537a, 0x537a, 0x537a, 0x537a, + 0x537a, 0x537a, 0x537b, 0x537b, 0x537b, 0x537b, 0x537b, 0x537b, + 0x537b, 0x537c, 0x537c, 0x537c, 0x537c, 0x537c, 0x537c, 0x537c, + 0x537d, 0x537d, 0x537d, 0x537d, 0x537d, 0x537d, 0x537d, 0x537e, + 0x537e, 0x537e, 0x537e, 0x537e, 0x537e, 0x537e, 0x537f, 0x537f, + 0x537f, 0x537f, 0x537f, 0x537f, 0x537f, 0x5380, 0x5380, 0x5380, + 0x5380, 0x5380, 0x5380, 0x5380, 0x5381, 0x5381, 0x5381, 0x5381, + 0x5381, 0x5381, 0x5381, 0x5382, 0x5382, 0x5382, 0x5382, 0x5382, + 0x5382, 0x5382, 0x5383, 0x5383, 0x5383, 0x5383, 0x5383, 0x5383, + 0x5383, 0x5384, 0x5384, 0x5384, 0x5384, 0x5384, 0x5384, 0x5384, + 0x5384, 0x5385, 0x5385, 0x5385, 0x5385, 0x5385, 0x5385, 0x5385, + 0x5386, 0x5386, 0x5386, 0x5386, 0x5386, 0x5386, 0x5386, 0x5387, + 0x5387, 0x5387, 0x5387, 0x5387, 0x5387, 0x5387, 0x5388, 0x5388, + 0x5388, 0x5388, 0x5388, 0x5388, 0x5388, 0x5388, 0x5389, 0x5389, + 0x5389, 0x5389, 0x5389, 0x5389, 0x5389, 0x538a, 0x538a, 0x538a, + 0x538a, 0x538a, 0x538a, 0x538a, 0x538b, 0x538b, 0x538b, 0x538b, + 0x538b, 0x538b, 0x538b, 0x538b, 0x538c, 0x538c, 0x538c, 0x538c, + 0x538c, 0x538c, 0x538c, 0x538d, 0x538d, 0x538d, 0x538d, 0x538d, + 0x538d, 0x538d, 0x538e, 0x538e, 0x538e, 0x538e, 0x538e, 0x538e, + 0x538e, 0x538e, 0x538f, 0x538f, 0x538f, 0x538f, 0x538f, 0x538f, + 0x538f, 0x5390, 0x5390, 0x5390, 0x5390, 0x5390, 0x5390, 0x5390, + 0x5390, 0x5391, 0x5391, 0x5391, 0x5391, 0x5391, 0x5391, 0x5391, + 0x5392, 0x5392, 0x5392, 0x5392, 0x5392, 0x5392, 0x5392, 0x5392, + 0x5393, 0x5393, 0x5393, 0x5393, 0x5393, 0x5393, 0x5393, 0x5393, + 0x5394, 0x5394, 0x5394, 0x5394, 0x5394, 0x5394, 0x5394, 0x5395, + 0x5395, 0x5395, 0x5395, 0x5395, 0x5395, 0x5395, 0x5395, 0x5396, + 0x5396, 0x5396, 0x5396, 0x5396, 0x5396, 0x5396, 0x5396, 0x5397, + 0x5397, 0x5397, 0x5397, 0x5397, 0x5397, 0x5397, 0x5398, 0x5398, + 0x5398, 0x5398, 0x5398, 0x5398, 0x5398, 0x5398, 0x5399, 0x5399, + 0x5399, 0x5399, 0x5399, 0x5399, 0x5399, 0x5399, 0x539a, 0x539a, + 0x539a, 0x539a, 0x539a, 0x539a, 0x539a, 0x539a, 0x539b, 0x539b, + 0x539b, 0x539b, 0x539b, 0x539b, 0x539b, 0x539b, 0x539c, 0x539c, + 0x539c, 0x539c, 0x539c, 0x539c, 0x539c, 0x539d, 0x539d, 0x539d, + 0x539d, 0x539d, 0x539d, 0x539d, 0x539d, 0x539e, 0x539e, 0x539e, + 0x539e, 0x539e, 0x539e, 0x539e, 0x539e, 0x539f, 0x539f, 0x539f, + 0x539f, 0x539f, 0x539f, 0x539f, 0x539f, 0x53a0, 0x53a0, 0x53a0, + 0x53a0, 0x53a0, 0x53a0, 0x53a1, 0x53a1, 0x53a1, 0x53a1, 0x53a2, + 0x53a2, 0x53a2, 0x53a2, 0x53a3, 0x53a3, 0x53a3, 0x53a3, 0x53a4, + 0x53a4, 0x53a4, 0x53a4, 0x53a5, 0x53a5, 0x53a5, 0x53a5, 0x53a6, + 0x53a6, 0x53a6, 0x53a6, 0x53a7, 0x53a7, 0x53a7, 0x53a7, 0x53a8, + 0x53a8, 0x53a8, 0x53a8, 0x53a9, 0x53a9, 0x53a9, 0x53a9, 0x53a9, + 0x53aa, 0x53aa, 0x53aa, 0x53aa, 0x53ab, 0x53ab, 0x53ab, 0x53ab, + 0x53ac, 0x53ac, 0x53ac, 0x53ac, 0x53ad, 0x53ad, 0x53ad, 0x53ad, + 0x53ae, 0x53ae, 0x53ae, 0x53ae, 0x53ae, 0x53af, 0x53af, 0x53af, + 0x53af, 0x53b0, 0x53b0, 0x53b0, 0x53b0, 0x53b1, 0x53b1, 0x53b1, + 0x53b1, 0x53b2, 0x53b2, 0x53b2, 0x53b2, 0x53b2, 0x53b3, 0x53b3, + 0x53b3, 0x53b3, 0x53b4, 0x53b4, 0x53b4, 0x53b4, 0x53b5, 0x53b5, + 0x53b5, 0x53b5, 0x53b5, 0x53b6, 0x53b6, 0x53b6, 0x53b6, 0x53b7, + 0x53b7, 0x53b7, 0x53b7, 0x53b8, 0x53b8, 0x53b8, 0x53b8, 0x53b8, + 0x53b9, 0x53b9, 0x53b9, 0x53b9, 0x53ba, 0x53ba, 0x53ba, 0x53ba, + 0x53ba, 0x53bb, 0x53bb, 0x53bb, 0x53bb, 0x53bc, 0x53bc, 0x53bc, + 0x53bc, 0x53bc, 0x53bd, 0x53bd, 0x53bd, 0x53bd, 0x53be, 0x53be, + 0x53be, 0x53be, 0x53be, 0x53bf, 0x53bf, 0x53bf, 0x53bf, 0x53c0, + 0x53c0, 0x53c0, 0x53c0, 0x53c0, 0x53c1, 0x53c1, 0x53c1, 0x53c1, + 0x53c2, 0x53c2, 0x53c2, 0x53c2, 0x53c2, 0x53c3, 0x53c3, 0x53c3, + 0x53c3, 0x53c4, 0x53c4, 0x53c4, 0x53c4, 0x53c4, 0x53c5, 0x53c5, + 0x53c5, 0x53c5, 0x53c6, 0x53c6, 0x53c6, 0x53c6, 0x53c6, 0x53c7, + 0x53c7, 0x53c7, 0x53c7, 0x53c7, 0x53c8, 0x53c8, 0x53c8, 0x53c8, + 0x53c9, 0x53c9, 0x53c9, 0x53c9, 0x53c9, 0x53ca, 0x53ca, 0x53ca, + 0x53ca, 0x53ca, 0x53cb, 0x53cb, 0x53cb, 0x53cb, 0x53cb, 0x53cc, + 0x53cc, 0x53cc, 0x53cc, 0x53cd, 0x53cd, 0x53cd, 0x53cd, 0x53cd, + 0x53ce, 0x53ce, 0x53ce, 0x53ce, 0x53ce, 0x53cf, 0x53cf, 0x53cf, + 0x53cf, 0x53cf, 0x53d0, 0x53d0, 0x53d0, 0x53d0, 0x53d0, 0x53d1, + 0x53d1, 0x53d1, 0x53d1, 0x53d2, 0x53d2, 0x53d2, 0x53d2, 0x53d2, + 0x53d3, 0x53d3, 0x53d3, 0x53d3, 0x53d3, 0x53d4, 0x53d4, 0x53d4, + 0x53d4, 0x53d4, 0x53d5, 0x53d5, 0x53d5, 0x53d5, 0x53d5, 0x53d6, + 0x53d6, 0x53d6, 0x53d6, 0x53d6, 0x53d7, 0x53d7, 0x53d7, 0x53d7, + 0x53d7, 0x53d8, 0x53d8, 0x53d8, 0x53d8, 0x53d8, 0x53d9, 0x53d9, + 0x53d9, 0x53d9, 0x53d9, 0x53da, 0x53da, 0x53da, 0x53da, 0x53da, + 0x53db, 0x53db, 0x53db, 0x53db, 0x53db, 0x53dc, 0x53dc, 0x53dc, + 0x53dc, 0x53dc, 0x53dd, 0x53dd, 0x53dd, 0x53dd, 0x53dd, 0x53de, + 0x53de, 0x53de, 0x53de, 0x53de, 0x53df, 0x53df, 0x53df, 0x53df, + 0x53df, 0x53e0, 0x53e0, 0x53e0, 0x53e0, 0x53e0, 0x53e1, 0x53e1, + 0x53e1, 0x53e1, 0x53e1, 0x53e1, 0x53e2, 0x53e2, 0x53e2, 0x53e2, + 0x53e2, 0x53e3, 0x53e3, 0x53e3, 0x53e3, 0x53e3, 0x53e4, 0x53e4, + 0x53e4, 0x53e4, 0x53e4, 0x53e5, 0x53e5, 0x53e5, 0x53e5, 0x53e5, + 0x53e6, 0x53e6, 0x53e6, 0x53e6, 0x53e6, 0x53e6, 0x53e7, 0x53e7, + 0x53e7, 0x53e7, 0x53e7, 0x53e8, 0x53e8, 0x53e8, 0x53e8, 0x53e8, + 0x53e9, 0x53e9, 0x53e9, 0x53e9, 0x53e9, 0x53e9, 0x53ea, 0x53ea, + 0x53ea, 0x53ea, 0x53ea, 0x53eb, 0x53eb, 0x53eb, 0x53eb, 0x53eb, + 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ed, 0x53ed, + 0x53ed, 0x53ed, 0x53ed, 0x53ee, 0x53ee, 0x53ee, 0x53ee, 0x53ee, + 0x53ef, 0x53ef, 0x53ef, 0x53ef, 0x53ef, 0x53ef, 0x53f0, 0x53f0, + 0x53f0, 0x53f0, 0x53f0, 0x53f1, 0x53f1, 0x53f1, 0x53f1, 0x53f1, + 0x53f1, 0x53f2, 0x53f2, 0x53f2, 0x53f2, 0x53f2, 0x53f3, 0x53f3, + 0x53f3, 0x53f3, 0x53f3, 0x53f3, 0x53f4, 0x53f4, 0x53f4, 0x53f4, + 0x53f4, 0x53f4, 0x53f5, 0x53f5, 0x53f5, 0x53f5, 0x53f5, 0x53f6, + 0x53f6, 0x53f6, 0x53f6, 0x53f6, 0x53f6, 0x53f7, 0x53f7, 0x53f7, + 0x53f7, 0x53f7, 0x53f8, 0x53f8, 0x53f8, 0x53f8, 0x53f8, 0x53f8, + 0x53f9, 0x53f9, 0x53f9, 0x53f9, 0x53f9, 0x53f9, 0x53fa, 0x53fa, + 0x53fa, 0x53fa, 0x53fa, 0x53fb, 0x53fb, 0x53fb, 0x53fb, 0x53fb, + 0x53fb, 0x53fc, 0x53fc, 0x53fc, 0x53fc, 0x53fc, 0x53fc, 0x53fd, + 0x53fd, 0x53fd, 0x53fd, 0x53fd, 0x53fe, 0x53fe, 0x53fe, 0x53fe, + 0x53fe, 0x53fe, 0x53ff, 0x53ff, 0x53ff, 0x53ff, 0x53ff, 0x53ff, + 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, + 0x5400, 0x5401, 0x5401, 0x5401, 0x5401, 0x5401, 0x5401, 0x5401, + 0x5401, 0x5401, 0x5401, 0x5401, 0x5401, 0x5402, 0x5402, 0x5402, + 0x5402, 0x5402, 0x5402, 0x5402, 0x5402, 0x5402, 0x5402, 0x5402, + 0x5403, 0x5403, 0x5403, 0x5403, 0x5403, 0x5403, 0x5403, 0x5403, + 0x5403, 0x5403, 0x5403, 0x5403, 0x5404, 0x5404, 0x5404, 0x5404, + 0x5404, 0x5404, 0x5404, 0x5404, 0x5404, 0x5404, 0x5404, 0x5404, + 0x5405, 0x5405, 0x5405, 0x5405, 0x5405, 0x5405, 0x5405, 0x5405, + 0x5405, 0x5405, 0x5405, 0x5405, 0x5406, 0x5406, 0x5406, 0x5406, + 0x5406, 0x5406, 0x5406, 0x5406, 0x5406, 0x5406, 0x5406, 0x5406, + 0x5406, 0x5407, 0x5407, 0x5407, 0x5407, 0x5407, 0x5407, 0x5407, + 0x5407, 0x5407, 0x5407, 0x5407, 0x5407, 0x5408, 0x5408, 0x5408, + 0x5408, 0x5408, 0x5408, 0x5408, 0x5408, 0x5408, 0x5408, 0x5408, + 0x5408, 0x5409, 0x5409, 0x5409, 0x5409, 0x5409, 0x5409, 0x5409, + 0x5409, 0x5409, 0x5409, 0x5409, 0x5409, 0x5409, 0x540a, 0x540a, + 0x540a, 0x540a, 0x540a, 0x540a, 0x540a, 0x540a, 0x540a, 0x540a, + 0x540a, 0x540a, 0x540b, 0x540b, 0x540b, 0x540b, 0x540b, 0x540b, + 0x540b, 0x540b, 0x540b, 0x540b, 0x540b, 0x540b, 0x540b, 0x540c, + 0x540c, 0x540c, 0x540c, 0x540c, 0x540c, 0x540c, 0x540c, 0x540c, + 0x540c, 0x540c, 0x540c, 0x540c, 0x540d, 0x540d, 0x540d, 0x540d, + 0x540d, 0x540d, 0x540d, 0x540d, 0x540d, 0x540d, 0x540d, 0x540d, + 0x540d, 0x540e, 0x540e, 0x540e, 0x540e, 0x540e, 0x540e, 0x540e, + 0x540e, 0x540e, 0x540e, 0x540e, 0x540e, 0x540e, 0x540f, 0x540f, + 0x540f, 0x540f, 0x540f, 0x540f, 0x540f, 0x540f, 0x540f, 0x540f, + 0x540f, 0x540f, 0x540f, 0x5410, 0x5410, 0x5410, 0x5410, 0x5410, + 0x5410, 0x5410, 0x5410, 0x5410, 0x5410, 0x5410, 0x5410, 0x5410, + 0x5411, 0x5411, 0x5411, 0x5411, 0x5411, 0x5411, 0x5411, 0x5411, + 0x5411, 0x5411, 0x5411, 0x5411, 0x5411, 0x5412, 0x5412, 0x5412, + 0x5412, 0x5412, 0x5412, 0x5412, 0x5412, 0x5412, 0x5412, 0x5412, + 0x5412, 0x5412, 0x5412, 0x5413, 0x5413, 0x5413, 0x5413, 0x5413, + 0x5413, 0x5413, 0x5413, 0x5413, 0x5413, 0x5413, 0x5413, 0x5413, + 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, + 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, 0x5414, 0x5415, 0x5415, + 0x5415, 0x5415, 0x5415, 0x5415, 0x5415, 0x5415, 0x5415, 0x5415, + 0x5415, 0x5415, 0x5415, 0x5415, 0x5416, 0x5416, 0x5416, 0x5416, + 0x5416, 0x5416, 0x5416, 0x5416, 0x5416, 0x5416, 0x5416, 0x5416, + 0x5416, 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, + 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, 0x5417, 0x5418, + 0x5418, 0x5418, 0x5418, 0x5418, 0x5418, 0x5418, 0x5418, 0x5418, + 0x5418, 0x5418, 0x5418, 0x5418, 0x5418, 0x5419, 0x5419, 0x5419, + 0x5419, 0x5419, 0x5419, 0x5419, 0x5419, 0x5419, 0x5419, 0x5419, + 0x5419, 0x5419, 0x5419, 0x5419, 0x541a, 0x541a, 0x541a, 0x541a, + 0x541a, 0x541a, 0x541a, 0x541a, 0x541a, 0x541a, 0x541a, 0x541a, + 0x541a, 0x541a, 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, + 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, 0x541b, + 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, + 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541c, 0x541d, + 0x541d, 0x541d, 0x541d, 0x541d, 0x541d, 0x541d, 0x541d, 0x541d, + 0x541d, 0x541d, 0x541d, 0x541d, 0x541d, 0x541e, 0x541e, 0x541e, + 0x541e, 0x541e, 0x541e, 0x541e, 0x541e, 0x541e, 0x541e, 0x541e, + 0x541e, 0x541e, 0x541e, 0x541e, 0x541f, 0x541f, 0x541f, 0x541f, + 0x541f, 0x541f, 0x541f, 0x541f, 0x541f, 0x541f, 0x541f, 0x541f, + 0x541f, 0x541f, 0x541f, 0x5420, 0x5420, 0x5420, 0x5420, 0x5420, + 0x5420, 0x5420, 0x5420, 0x5420, 0x5420, 0x5420, 0x5420, 0x5420, + 0x5420, 0x5420, 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, + 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, 0x5421, + 0x5421, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, + 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, 0x5422, + 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, + 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5423, 0x5424, + 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, + 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5424, 0x5425, + 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, + 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, 0x5425, 0x5426, 0x5426, + 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, + 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, 0x5426, 0x5427, 0x5427, + 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, + 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, 0x5427, 0x5428, 0x5428, + 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, + 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, 0x5428, 0x5429, 0x5429, + 0x5429, 0x5429, 0x5429, 0x5429, 0x5429, 0x5429, 0x5429, 0x542a, + 0x542a, 0x542a, 0x542a, 0x542a, 0x542a, 0x542a, 0x542a, 0x542b, + 0x542b, 0x542b, 0x542b, 0x542b, 0x542b, 0x542b, 0x542b, 0x542c, + 0x542c, 0x542c, 0x542c, 0x542c, 0x542c, 0x542c, 0x542c, 0x542c, + 0x542d, 0x542d, 0x542d, 0x542d, 0x542d, 0x542d, 0x542d, 0x542d, + 0x542e, 0x542e, 0x542e, 0x542e, 0x542e, 0x542e, 0x542e, 0x542e, + 0x542f, 0x542f, 0x542f, 0x542f, 0x542f, 0x542f, 0x542f, 0x542f, + 0x542f, 0x5430, 0x5430, 0x5430, 0x5430, 0x5430, 0x5430, 0x5430, + 0x5430, 0x5431, 0x5431, 0x5431, 0x5431, 0x5431, 0x5431, 0x5431, + 0x5431, 0x5431, 0x5432, 0x5432, 0x5432, 0x5432, 0x5432, 0x5432, + 0x5432, 0x5432, 0x5433, 0x5433, 0x5433, 0x5433, 0x5433, 0x5433, + 0x5433, 0x5433, 0x5433, 0x5434, 0x5434, 0x5434, 0x5434, 0x5434, + 0x5434, 0x5434, 0x5434, 0x5434, 0x5435, 0x5435, 0x5435, 0x5435, + 0x5435, 0x5435, 0x5435, 0x5435, 0x5436, 0x5436, 0x5436, 0x5436, + 0x5436, 0x5436, 0x5436, 0x5436, 0x5436, 0x5437, 0x5437, 0x5437, + 0x5437, 0x5437, 0x5437, 0x5437, 0x5437, 0x5437, 0x5438, 0x5438, + 0x5438, 0x5438, 0x5438, 0x5438, 0x5438, 0x5438, 0x5438, 0x5439, + 0x5439, 0x5439, 0x5439, 0x5439, 0x5439, 0x5439, 0x5439, 0x5439, + 0x543a, 0x543a, 0x543a, 0x543a, 0x543a, 0x543a, 0x543a, 0x543a, + 0x543a, 0x543a, 0x543b, 0x543b, 0x543b, 0x543b, 0x543b, 0x543b, + 0x543b, 0x543b, 0x543b, 0x543c, 0x543c, 0x543c, 0x543c, 0x543c, + 0x543c, 0x543c, 0x543c, 0x543c, 0x543d, 0x543d, 0x543d, 0x543d, + 0x543d, 0x543d, 0x543d, 0x543d, 0x543d, 0x543e, 0x543e, 0x543e, + 0x543e, 0x543e, 0x543e, 0x543e, 0x543e, 0x543e, 0x543e, 0x543f, + 0x543f, 0x543f, 0x543f, 0x543f, 0x543f, 0x543f, 0x543f, 0x543f, + 0x5440, 0x5440, 0x5440, 0x5440, 0x5440, 0x5440, 0x5440, 0x5440, + 0x5440, 0x5440, 0x5441, 0x5441, 0x5441, 0x5441, 0x5441, 0x5441, + 0x5441, 0x5441, 0x5441, 0x5441, 0x5442, 0x5442, 0x5442, 0x5442, + 0x5442, 0x5442, 0x5442, 0x5442, 0x5442, 0x5443, 0x5443, 0x5443, + 0x5443, 0x5443, 0x5443, 0x5443, 0x5443, 0x5443, 0x5443, 0x5444, + 0x5444, 0x5444, 0x5444, 0x5444, 0x5444, 0x5444, 0x5444, 0x5444, + 0x5444, 0x5445, 0x5445, 0x5445, 0x5445, 0x5445, 0x5445, 0x5445, + 0x5445, 0x5445, 0x5445, 0x5446, 0x5446, 0x5446, 0x5446, 0x5446, + 0x5446, 0x5446, 0x5446, 0x5446, 0x5446, 0x5447, 0x5447, 0x5447, + 0x5447, 0x5447, 0x5447, 0x5447, 0x5447, 0x5447, 0x5447, 0x5448, + 0x5448, 0x5448, 0x5448, 0x5448, 0x5448, 0x5448, 0x5448, 0x5448, + 0x5448, 0x5448, 0x5449, 0x5449, 0x5449, 0x5449, 0x5449, 0x5449, + 0x5449, 0x5449, 0x5449, 0x5449, 0x544a, 0x544a, 0x544a, 0x544a, + 0x544a, 0x544a, 0x544a, 0x544a, 0x544a, 0x544a, 0x544b, 0x544b, + 0x544b, 0x544b, 0x544b, 0x544b, 0x544b, 0x544b, 0x544b, 0x544b, + 0x544b, 0x544c, 0x544c, 0x544c, 0x544c, 0x544c, 0x544c, 0x544c, + 0x544c, 0x544c, 0x544c, 0x544d, 0x544d, 0x544d, 0x544d, 0x544d, + 0x544d, 0x544d, 0x544d, 0x544d, 0x544d, 0x544d, 0x544e, 0x544e, + 0x544e, 0x544e, 0x544e, 0x544e, 0x544e, 0x544e, 0x544e, 0x544e, + 0x544e, 0x544f, 0x544f, 0x544f, 0x544f, 0x544f, 0x544f, 0x544f, + 0x544f, 0x544f, 0x544f, 0x5450, 0x5450, 0x5450, 0x5450, 0x5450, + 0x5450, 0x5450, 0x5450, 0x5450, 0x5450, 0x5450, 0x5451, 0x5451, + 0x5451, 0x5451, 0x5451, 0x5451, 0x5451, 0x5451, 0x5451, 0x5451, + 0x5451, 0x5452, 0x5452, 0x5452, 0x5452, 0x5452, 0x5452, 0x5452, + 0x5452, 0x5452, 0x5452, 0x5452, 0x5453, 0x5453, 0x5453, 0x5453, + 0x5453, 0x5453, 0x5453, 0x5453, 0x5453, 0x5453, 0x5453, 0x5454, + 0x5454, 0x5454, 0x5454, 0x5454, 0x5454, 0x5454, 0x5454, 0x5454, + 0x5454, 0x5454, 0x5454, 0x5455, 0x5455, 0x5455, 0x5455, 0x5455, + 0x5455, 0x5455, 0x5455, 0x5455, 0x5455, 0x5455, 0x5456, 0x5456, + 0x5456, 0x5456, 0x5456, 0x5456, 0x5456, 0x5456, 0x5456, 0x5456, + 0x5456, 0x5457, 0x5457, 0x5457, 0x5457, 0x5457, 0x5457, 0x5457, + 0x5457, 0x5457, 0x5457, 0x5457, 0x5457, 0x5458, 0x5458, 0x5458, + 0x5458, 0x5458, 0x5458, 0x5458, 0x5458, 0x5458, 0x5458, 0x5458, + 0x5459, 0x5459, 0x5459, 0x5459, 0x5459, 0x5459, 0x5459, 0x5459, + 0x5459, 0x5459, 0x5459, 0x5459, 0x545a, 0x545a, 0x545a, 0x545a, + 0x545a, 0x545a, 0x545a, 0x545a, 0x545a, 0x545a, 0x545a, 0x545a, + 0x545b, 0x545b, 0x545b, 0x545b, 0x545b, 0x545b, 0x545b, 0x545b, + 0x545b, 0x545b, 0x545b, 0x545b, 0x545c, 0x545c, 0x545c, 0x545c, + 0x545c, 0x545c, 0x545c, 0x545c, 0x545c, 0x545c, 0x545c, 0x545c, + 0x545d, 0x545d, 0x545d, 0x545d, 0x545d, 0x545d, 0x545d, 0x545d, + 0x545d, 0x545d, 0x545d, 0x545d, 0x545e, 0x545e, 0x545e, 0x545e, + 0x545e, 0x545e, 0x545e, 0x545e, 0x545e, 0x545e, 0x545e, 0x545e, + 0x545f, 0x545f, 0x545f, 0x545f, 0x545f, 0x545f, 0x545f, 0x545f, + 0x545f, 0x545f, 0x545f, 0x545f, 0x5460, 0x5460, 0x5460, 0x5460, + 0x5460, 0x5460, 0x5460, 0x5460, 0x5460, 0x5460, 0x5460, 0x5460, + 0x5461, 0x5461, 0x5461, 0x5461, 0x5461, 0x5461, 0x5461, 0x5461, + 0x5461, 0x5461, 0x5461, 0x5461, 0x5461, 0x5462, 0x5462, 0x5462, + 0x5462, 0x5462, 0x5462, 0x5462, 0x5462, 0x5462, 0x5462, 0x5462, + 0x5462, 0x5463, 0x5463, 0x5463, 0x5463, 0x5463, 0x5463, 0x5463, + 0x5463, 0x5463, 0x5463, 0x5463, 0x5463, 0x5463, 0x5464, 0x5464, + 0x5464, 0x5464, 0x5464, 0x5464, 0x5464, 0x5464, 0x5464, 0x5464, + 0x5464, 0x5464, 0x5464, 0x5465, 0x5465, 0x5465, 0x5465, 0x5465, + 0x5465, 0x5465, 0x5465, 0x5465, 0x5465, 0x5465, 0x5465, 0x5466, + 0x5466, 0x5466, 0x5466, 0x5466, 0x5466, 0x5466, 0x5466, 0x5466, + 0x5466, 0x5466, 0x5466, 0x5466, 0x5467, 0x5467, 0x5467, 0x5467, + 0x5467, 0x5467, 0x5467, 0x5467, 0x5467, 0x5467, 0x5467, 0x5467, + 0x5467, 0x5468, 0x5468, 0x5468, 0x5468, 0x5468, 0x5468, 0x5468, + 0x5468, 0x5468, 0x5468, 0x5468, 0x5468, 0x5468, 0x5469, 0x5469, + 0x5469, 0x5469, 0x5469, 0x5469, 0x5469, 0x5469, 0x5469, 0x5469, + 0x5469, 0x5469, 0x5469, 0x5469, 0x546a, 0x546a, 0x546a, 0x546a, + 0x546a, 0x546a, 0x546a, 0x546a, 0x546a, 0x546a, 0x546a, 0x546a, + 0x546a, 0x546b, 0x546b, 0x546b, 0x546b, 0x546b, 0x546b, 0x546b, + 0x546b, 0x546b, 0x546b, 0x546b, 0x546b, 0x546b, 0x546c, 0x546c, + 0x546c, 0x546c, 0x546c, 0x546c, 0x546c, 0x546c, 0x546c, 0x546c, + 0x546c, 0x546c, 0x546c, 0x546c, 0x546d, 0x546d, 0x546d, 0x546d, + 0x546d, 0x546d, 0x546d, 0x546d, 0x546d, 0x546d, 0x546d, 0x546d, + 0x546d, 0x546d, 0x546e, 0x546e, 0x546e, 0x546e, 0x546e, 0x546e, + 0x546e, 0x546e, 0x546e, 0x546e, 0x546e, 0x546e, 0x546e, 0x546f, + 0x546f, 0x546f, 0x546f, 0x546f, 0x546f, 0x546f, 0x546f, 0x546f, + 0x546f, 0x546f, 0x546f, 0x546f, 0x546f, 0x5470, 0x5470, 0x5470, + 0x5470, 0x5470, 0x5470, 0x5470, 0x5470, 0x5470, 0x5470, 0x5470, + 0x5470, 0x5470, 0x5470, 0x5471, 0x5471, 0x5471, 0x5471, 0x5471, + 0x5471, 0x5471, 0x5471, 0x5471, 0x5471, 0x5471, 0x5471, 0x5471, + 0x5471, 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, + 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, 0x5472, 0x5473, + 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, + 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, 0x5473, 0x5474, 0x5474, + 0x5474, 0x5474, 0x5474, 0x5474, 0x5474, 0x5474, 0x5474, 0x5474, + 0x5474, 0x5474, 0x5474, 0x5474, 0x5475, 0x5475, 0x5475, 0x5475, + 0x5475, 0x5475, 0x5475, 0x5475, 0x5475, 0x5475, 0x5475, 0x5475, + 0x5475, 0x5475, 0x5475, 0x5476, 0x5476, 0x5476, 0x5476, 0x5476, + 0x5476, 0x5476, 0x5476, 0x5476, 0x5476, 0x5476, 0x5476, 0x5476, + 0x5476, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, + 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, 0x5477, + 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, + 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5478, 0x5479, + 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, + 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, 0x5479, 0x547a, 0x547a, + 0x547a, 0x547a, 0x547a, 0x547a, 0x547a, 0x547a, 0x547a, 0x547a, + 0x547a, 0x547a, 0x547a, 0x547a, 0x547a, 0x547b, 0x547b, 0x547b, + 0x547b, 0x547b, 0x547b, 0x547b, 0x547b, 0x547b, 0x547b, 0x547b, + 0x547b, 0x547b, 0x547b, 0x547b, 0x547c, 0x547c, 0x547c, 0x547c, + 0x547c, 0x547c, 0x547c, 0x547c, 0x547c, 0x547c, 0x547c, 0x547c, + 0x547c, 0x547c, 0x547c, 0x547c, 0x547d, 0x547d, 0x547d, 0x547d, + 0x547d, 0x547d, 0x547d, 0x547d, 0x547d, 0x547d, 0x547d, 0x547d, + 0x547d, 0x547d, 0x547d, 0x547e, 0x547e, 0x547e, 0x547e, 0x547e, + 0x547e, 0x547e, 0x547e, 0x547e, 0x547e, 0x547e, 0x547e, 0x547e, + 0x547e, 0x547e, 0x547e, 0x547f, 0x547f, 0x547f, 0x547f, 0x547f, + 0x547f, 0x547f, 0x547f, 0x547f, 0x547f, 0x547f, 0x547f, 0x547f, + 0x547f, 0x547f, 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, + 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, 0x5480, + 0x5480, 0x5480, 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, + 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, 0x5481, + 0x5481, 0x5482, 0x5482, 0x5482, 0x5482, 0x5482, 0x5482, 0x5482, + 0x5482, 0x5483, 0x5483, 0x5483, 0x5483, 0x5483, 0x5483, 0x5483, + 0x5483, 0x5484, 0x5484, 0x5484, 0x5484, 0x5484, 0x5484, 0x5484, + 0x5484, 0x5484, 0x5485, 0x5485, 0x5485, 0x5485, 0x5485, 0x5485, + 0x5485, 0x5485, 0x5486, 0x5486, 0x5486, 0x5486, 0x5486, 0x5486, + 0x5486, 0x5486, 0x5487, 0x5487, 0x5487, 0x5487, 0x5487, 0x5487, + 0x5487, 0x5487, 0x5487, 0x5488, 0x5488, 0x5488, 0x5488, 0x5488, + 0x5488, 0x5488, 0x5488, 0x5489, 0x5489, 0x5489, 0x5489, 0x5489, + 0x5489, 0x5489, 0x5489, 0x548a, 0x548a, 0x548a, 0x548a, 0x548a, + 0x548a, 0x548a, 0x548a, 0x548a, 0x548b, 0x548b, 0x548b, 0x548b, + 0x548b, 0x548b, 0x548b, 0x548b, 0x548b, 0x548c, 0x548c, 0x548c, + 0x548c, 0x548c, 0x548c, 0x548c, 0x548c, 0x548d, 0x548d, 0x548d, + 0x548d, 0x548d, 0x548d, 0x548d, 0x548d, 0x548d, 0x548e, 0x548e, + 0x548e, 0x548e, 0x548e, 0x548e, 0x548e, 0x548e, 0x548e, 0x548f, + 0x548f, 0x548f, 0x548f, 0x548f, 0x548f, 0x548f, 0x548f, 0x548f, + 0x5490, 0x5490, 0x5490, 0x5490, 0x5490, 0x5490, 0x5490, 0x5490, + 0x5490, 0x5491, 0x5491, 0x5491, 0x5491, 0x5491, 0x5491, 0x5491, + 0x5491, 0x5491, 0x5492, 0x5492, 0x5492, 0x5492, 0x5492, 0x5492, + 0x5492, 0x5492, 0x5492, 0x5493, 0x5493, 0x5493, 0x5493, 0x5493, + 0x5493, 0x5493, 0x5493, 0x5493, 0x5494, 0x5494, 0x5494, 0x5494, + 0x5494, 0x5494, 0x5494, 0x5494, 0x5494, 0x5495, 0x5495, 0x5495, + 0x5495, 0x5495, 0x5495, 0x5495, 0x5495, 0x5495, 0x5495, 0x5496, + 0x5496, 0x5496, 0x5496, 0x5496, 0x5496, 0x5496, 0x5496, 0x5496, + 0x5497, 0x5497, 0x5497, 0x5497, 0x5497, 0x5497, 0x5497, 0x5497, + 0x5497, 0x5497, 0x5498, 0x5498, 0x5498, 0x5498, 0x5498, 0x5498, + 0x5498, 0x5498, 0x5498, 0x5499, 0x5499, 0x5499, 0x5499, 0x5499, + 0x5499, 0x5499, 0x5499, 0x5499, 0x5499, 0x549a, 0x549a, 0x549a, + 0x549a, 0x549a, 0x549a, 0x549a, 0x549a, 0x549a, 0x549b, 0x549b, + 0x549b, 0x549b, 0x549b, 0x549b, 0x549b, 0x549b, 0x549b, 0x549b, + 0x549c, 0x549c, 0x549c, 0x549c, 0x549c, 0x549c, 0x549c, 0x549c, + 0x549c, 0x549c, 0x549d, 0x549d, 0x549d, 0x549d, 0x549d, 0x549d, + 0x549d, 0x549d, 0x549d, 0x549d, 0x549e, 0x549e, 0x549e, 0x549e, + 0x549e, 0x549e, 0x549e, 0x549e, 0x549e, 0x549e, 0x549f, 0x549f, + 0x549f, 0x549f, 0x549f, 0x549f, 0x549f, 0x549f, 0x549f, 0x549f, + 0x54a0, 0x54a0, 0x54a0, 0x54a0, 0x54a0, 0x54a0, 0x54a0, 0x54a0, + 0x54a0, 0x54a0, 0x54a1, 0x54a1, 0x54a1, 0x54a1, 0x54a1, 0x54a1, + 0x54a1, 0x54a1, 0x54a1, 0x54a1, 0x54a2, 0x54a2, 0x54a2, 0x54a2, + 0x54a2, 0x54a2, 0x54a2, 0x54a2, 0x54a2, 0x54a2, 0x54a2, 0x54a3, + 0x54a3, 0x54a3, 0x54a3, 0x54a3, 0x54a3, 0x54a3, 0x54a3, 0x54a3, + 0x54a3, 0x54a4, 0x54a4, 0x54a4, 0x54a4, 0x54a4, 0x54a4, 0x54a4, + 0x54a4, 0x54a4, 0x54a4, 0x54a4, 0x54a5, 0x54a5, 0x54a5, 0x54a5, + 0x54a5, 0x54a5, 0x54a5, 0x54a5, 0x54a5, 0x54a5, 0x54a6, 0x54a6, + 0x54a6, 0x54a6, 0x54a6, 0x54a6, 0x54a6, 0x54a6, 0x54a6, 0x54a6, + 0x54a6, 0x54a7, 0x54a7, 0x54a7, 0x54a7, 0x54a7, 0x54a7, 0x54a7, + 0x54a7, 0x54a7, 0x54a7, 0x54a7, 0x54a8, 0x54a8, 0x54a8, 0x54a8, + 0x54a8, 0x54a8, 0x54a8, 0x54a8, 0x54a8, 0x54a8, 0x54a9, 0x54a9, + 0x54a9, 0x54a9, 0x54a9, 0x54a9, 0x54a9, 0x54a9, 0x54a9, 0x54a9, + 0x54a9, 0x54aa, 0x54aa, 0x54aa, 0x54aa, 0x54aa, 0x54aa, 0x54aa, + 0x54aa, 0x54aa, 0x54aa, 0x54aa, 0x54ab, 0x54ab, 0x54ab, 0x54ab, + 0x54ab, 0x54ab, 0x54ab, 0x54ab, 0x54ab, 0x54ab, 0x54ab, 0x54ac, + 0x54ac, 0x54ac, 0x54ac, 0x54ac, 0x54ac, 0x54ac, 0x54ac, 0x54ac, + 0x54ac, 0x54ac, 0x54ad, 0x54ad, 0x54ad, 0x54ad, 0x54ad, 0x54ad, + 0x54ad, 0x54ad, 0x54ad, 0x54ad, 0x54ad, 0x54ad, 0x54ae, 0x54ae, + 0x54ae, 0x54ae, 0x54ae, 0x54ae, 0x54ae, 0x54ae, 0x54ae, 0x54ae, + 0x54ae, 0x54af, 0x54af, 0x54af, 0x54af, 0x54af, 0x54af, 0x54af, + 0x54af, 0x54af, 0x54af, 0x54af, 0x54b0, 0x54b0, 0x54b0, 0x54b0, + 0x54b0, 0x54b0, 0x54b0, 0x54b0, 0x54b0, 0x54b0, 0x54b0, 0x54b0, + 0x54b1, 0x54b1, 0x54b1, 0x54b1, 0x54b1, 0x54b1, 0x54b1, 0x54b1, + 0x54b1, 0x54b1, 0x54b1, 0x54b1, 0x54b2, 0x54b2, 0x54b2, 0x54b2, + 0x54b2, 0x54b2, 0x54b2, 0x54b2, 0x54b2, 0x54b2, 0x54b2, 0x54b3, + 0x54b3, 0x54b3, 0x54b3, 0x54b3, 0x54b3, 0x54b3, 0x54b3, 0x54b3, + 0x54b3, 0x54b3, 0x54b3, 0x54b4, 0x54b4, 0x54b4, 0x54b4, 0x54b4, + 0x54b4, 0x54b4, 0x54b4, 0x54b4, 0x54b4, 0x54b4, 0x54b4, 0x54b5, + 0x54b5, 0x54b5, 0x54b5, 0x54b5, 0x54b5, 0x54b5, 0x54b5, 0x54b5, + 0x54b5, 0x54b5, 0x54b5, 0x54b6, 0x54b6, 0x54b6, 0x54b6, 0x54b6, + 0x54b6, 0x54b6, 0x54b6, 0x54b6, 0x54b6, 0x54b6, 0x54b6, 0x54b7, + 0x54b7, 0x54b7, 0x54b7, 0x54b7, 0x54b7, 0x54b7, 0x54b7, 0x54b7, + 0x54b7, 0x54b7, 0x54b7, 0x54b8, 0x54b8, 0x54b8, 0x54b8, 0x54b8, + 0x54b8, 0x54b8, 0x54b8, 0x54b8, 0x54b8, 0x54b8, 0x54b8, 0x54b9, + 0x54b9, 0x54b9, 0x54b9, 0x54b9, 0x54b9, 0x54b9, 0x54b9, 0x54b9, + 0x54b9, 0x54b9, 0x54b9, 0x54b9, 0x54ba, 0x54ba, 0x54ba, 0x54ba, + 0x54ba, 0x54ba, 0x54ba, 0x54ba, 0x54ba, 0x54ba, 0x54ba, 0x54ba, + 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bb, + 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bb, 0x54bc, 0x54bc, 0x54bc, + 0x54bc, 0x54bc, 0x54bc, 0x54bc, 0x54bc, 0x54bc, 0x54bc, 0x54bc, + 0x54bc, 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54bd, + 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54bd, 0x54be, 0x54be, + 0x54be, 0x54be, 0x54be, 0x54be, 0x54be, 0x54be, 0x54be, 0x54be, + 0x54be, 0x54be, 0x54be, 0x54bf, 0x54bf, 0x54bf, 0x54bf, 0x54bf, + 0x54bf, 0x54bf, 0x54bf, 0x54bf, 0x54bf, 0x54bf, 0x54bf, 0x54bf, + 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c0, + 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c0, 0x54c1, 0x54c1, 0x54c1, + 0x54c1, 0x54c1, 0x54c1, 0x54c1, 0x54c1, 0x54c1, 0x54c1, 0x54c1, + 0x54c1, 0x54c1, 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c2, + 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c2, 0x54c3, + 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c3, + 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c3, 0x54c4, 0x54c4, 0x54c4, + 0x54c4, 0x54c4, 0x54c4, 0x54c4, 0x54c4, 0x54c4, 0x54c4, 0x54c4, + 0x54c4, 0x54c4, 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, + 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, 0x54c5, + 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c6, + 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c6, 0x54c7, 0x54c7, 0x54c7, + 0x54c7, 0x54c7, 0x54c7, 0x54c7, 0x54c7, 0x54c7, 0x54c7, 0x54c7, + 0x54c7, 0x54c7, 0x54c7, 0x54c8, 0x54c8, 0x54c8, 0x54c8, 0x54c8, + 0x54c8, 0x54c8, 0x54c8, 0x54c8, 0x54c8, 0x54c8, 0x54c8, 0x54c8, + 0x54c8, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, + 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54c9, 0x54ca, + 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54ca, + 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54ca, 0x54cb, 0x54cb, 0x54cb, + 0x54cb, 0x54cb, 0x54cb, 0x54cb, 0x54cb, 0x54cb, 0x54cb, 0x54cb, + 0x54cb, 0x54cb, 0x54cb, 0x54cc, 0x54cc, 0x54cc, 0x54cc, 0x54cc, + 0x54cc, 0x54cc, 0x54cc, 0x54cc, 0x54cc, 0x54cc, 0x54cc, 0x54cc, + 0x54cc, 0x54cc, 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, + 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, 0x54cd, + 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, + 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54ce, 0x54cf, + 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54cf, + 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54cf, 0x54d0, 0x54d0, 0x54d0, + 0x54d0, 0x54d0, 0x54d0, 0x54d0, 0x54d0, 0x54d0, 0x54d0, 0x54d0, + 0x54d0, 0x54d0, 0x54d0, 0x54d0, 0x54d1, 0x54d1, 0x54d1, 0x54d1, + 0x54d1, 0x54d1, 0x54d1, 0x54d1, 0x54d1, 0x54d1, 0x54d1, 0x54d1, + 0x54d1, 0x54d1, 0x54d1, 0x54d2, 0x54d2, 0x54d2, 0x54d2, 0x54d2, + 0x54d2, 0x54d2, 0x54d2, 0x54d2, 0x54d2, 0x54d2, 0x54d2, 0x54d2, + 0x54d2, 0x54d2, 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, + 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, 0x54d3, + 0x54d3, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, + 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, 0x54d4, + 0x54d4, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, + 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, 0x54d5, + 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, + 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d6, 0x54d7, + 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, + 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d7, 0x54d8, + 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, + 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d8, 0x54d9, + 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, + 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54d9, 0x54da, + 0x54da, 0x54da, 0x54da, 0x54da, 0x54da, 0x54da, 0x54da, 0x54da, + 0x54da, 0x54da, 0x54da, 0x54da, 0x54db, 0x54db, 0x54db, 0x54db, + 0x54db, 0x54db, 0x54db, 0x54db, 0x54dc, 0x54dc, 0x54dc, 0x54dc, + 0x54dc, 0x54dc, 0x54dc, 0x54dc, 0x54dd, 0x54dd, 0x54dd, 0x54dd, + 0x54dd, 0x54dd, 0x54dd, 0x54dd, 0x54de, 0x54de, 0x54de, 0x54de, + 0x54de, 0x54de, 0x54de, 0x54de, 0x54df, 0x54df, 0x54df, 0x54df, + 0x54df, 0x54df, 0x54df, 0x54df, 0x54e0, 0x54e0, 0x54e0, 0x54e0, + 0x54e0, 0x54e0, 0x54e0, 0x54e0, 0x54e0, 0x54e1, 0x54e1, 0x54e1, + 0x54e1, 0x54e1, 0x54e1, 0x54e1, 0x54e1, 0x54e2, 0x54e2, 0x54e2, + 0x54e2, 0x54e2, 0x54e2, 0x54e2, 0x54e2, 0x54e2, 0x54e3, 0x54e3, + 0x54e3, 0x54e3, 0x54e3, 0x54e3, 0x54e3, 0x54e3, 0x54e4, 0x54e4, + 0x54e4, 0x54e4, 0x54e4, 0x54e4, 0x54e4, 0x54e4, 0x54e4, 0x54e5, + 0x54e5, 0x54e5, 0x54e5, 0x54e5, 0x54e5, 0x54e5, 0x54e5, 0x54e5, + 0x54e6, 0x54e6, 0x54e6, 0x54e6, 0x54e6, 0x54e6, 0x54e6, 0x54e6, + 0x54e7, 0x54e7, 0x54e7, 0x54e7, 0x54e7, 0x54e7, 0x54e7, 0x54e7, + 0x54e7, 0x54e8, 0x54e8, 0x54e8, 0x54e8, 0x54e8, 0x54e8, 0x54e8, + 0x54e8, 0x54e8, 0x54e9, 0x54e9, 0x54e9, 0x54e9, 0x54e9, 0x54e9, + 0x54e9, 0x54e9, 0x54e9, 0x54ea, 0x54ea, 0x54ea, 0x54ea, 0x54ea, + 0x54ea, 0x54ea, 0x54ea, 0x54ea, 0x54eb, 0x54eb, 0x54eb, 0x54eb, + 0x54eb, 0x54eb, 0x54eb, 0x54eb, 0x54eb, 0x54ec, 0x54ec, 0x54ec, + 0x54ec, 0x54ec, 0x54ec, 0x54ec, 0x54ec, 0x54ec, 0x54ec, 0x54ed, + 0x54ed, 0x54ed, 0x54ed, 0x54ed, 0x54ed, 0x54ed, 0x54ed, 0x54ed, + 0x54ee, 0x54ee, 0x54ee, 0x54ee, 0x54ee, 0x54ee, 0x54ee, 0x54ee, + 0x54ee, 0x54ef, 0x54ef, 0x54ef, 0x54ef, 0x54ef, 0x54ef, 0x54ef, + 0x54ef, 0x54ef, 0x54ef, 0x54f0, 0x54f0, 0x54f0, 0x54f0, 0x54f0, + 0x54f0, 0x54f0, 0x54f0, 0x54f0, 0x54f1, 0x54f1, 0x54f1, 0x54f1, + 0x54f1, 0x54f1, 0x54f1, 0x54f1, 0x54f1, 0x54f1, 0x54f2, 0x54f2, + 0x54f2, 0x54f2, 0x54f2, 0x54f2, 0x54f2, 0x54f2, 0x54f2, 0x54f3, + 0x54f3, 0x54f3, 0x54f3, 0x54f3, 0x54f3, 0x54f3, 0x54f3, 0x54f3, + 0x54f3, 0x54f4, 0x54f4, 0x54f4, 0x54f4, 0x54f4, 0x54f4, 0x54f4, + 0x54f4, 0x54f4, 0x54f4, 0x54f5, 0x54f5, 0x54f5, 0x54f5, 0x54f5, + 0x54f5, 0x54f5, 0x54f5, 0x54f5, 0x54f5, 0x54f6, 0x54f6, 0x54f6, + 0x54f6, 0x54f6, 0x54f6, 0x54f6, 0x54f6, 0x54f6, 0x54f6, 0x54f7, + 0x54f7, 0x54f7, 0x54f7, 0x54f7, 0x54f7, 0x54f7, 0x54f7, 0x54f7, + 0x54f7, 0x54f8, 0x54f8, 0x54f8, 0x54f8, 0x54f8, 0x54f8, 0x54f8, + 0x54f8, 0x54f8, 0x54f8, 0x54f9, 0x54f9, 0x54f9, 0x54f9, 0x54f9, + 0x54f9, 0x54f9, 0x54f9, 0x54f9, 0x54f9, 0x54fa, 0x54fa, 0x54fa, + 0x54fa, 0x54fa, 0x54fa, 0x54fa, 0x54fa, 0x54fa, 0x54fa, 0x54fb, + 0x54fb, 0x54fb, 0x54fb, 0x54fb, 0x54fb, 0x54fb, 0x54fb, 0x54fb, + 0x54fb, 0x54fb, 0x54fc, 0x54fc, 0x54fc, 0x54fc, 0x54fc, 0x54fc, + 0x54fc, 0x54fc, 0x54fc, 0x54fc, 0x54fd, 0x54fd, 0x54fd, 0x54fd, + 0x54fd, 0x54fd, 0x54fd, 0x54fd, 0x54fd, 0x54fd, 0x54fd, 0x54fe, + 0x54fe, 0x54fe, 0x54fe, 0x54fe, 0x54fe, 0x54fe, 0x54fe, 0x54fe, + 0x54fe, 0x54ff, 0x54ff, 0x54ff, 0x54ff, 0x54ff, 0x54ff, 0x54ff, + 0x54ff, 0x54ff, 0x54ff, 0x54ff, 0x5500, 0x5500, 0x5500, 0x5500, + 0x5500, 0x5500, 0x5500, 0x5500, 0x5500, 0x5500, 0x5500, 0x5501, + 0x5501, 0x5501, 0x5501, 0x5501, 0x5501, 0x5501, 0x5501, 0x5501, + 0x5501, 0x5502, 0x5502, 0x5502, 0x5502, 0x5502, 0x5502, 0x5502, + 0x5502, 0x5502, 0x5502, 0x5502, 0x5503, 0x5503, 0x5503, 0x5503, + 0x5503, 0x5503, 0x5503, 0x5503, 0x5503, 0x5503, 0x5503, 0x5504, + 0x5504, 0x5504, 0x5504, 0x5504, 0x5504, 0x5504, 0x5504, 0x5504, + 0x5504, 0x5504, 0x5505, 0x5505, 0x5505, 0x5505, 0x5505, 0x5505, + 0x5505, 0x5505, 0x5505, 0x5505, 0x5505, 0x5505, 0x5506, 0x5506, + 0x5506, 0x5506, 0x5506, 0x5506, 0x5506, 0x5506, 0x5506, 0x5506, + 0x5506, 0x5507, 0x5507, 0x5507, 0x5507, 0x5507, 0x5507, 0x5507, + 0x5507, 0x5507, 0x5507, 0x5507, 0x5508, 0x5508, 0x5508, 0x5508, + 0x5508, 0x5508, 0x5508, 0x5508, 0x5508, 0x5508, 0x5508, 0x5508, + 0x5509, 0x5509, 0x5509, 0x5509, 0x5509, 0x5509, 0x5509, 0x5509, + 0x5509, 0x5509, 0x5509, 0x550a, 0x550a, 0x550a, 0x550a, 0x550a, + 0x550a, 0x550a, 0x550a, 0x550a, 0x550a, 0x550a, 0x550a, 0x550b, + 0x550b, 0x550b, 0x550b, 0x550b, 0x550b, 0x550b, 0x550b, 0x550b, + 0x550b, 0x550b, 0x550b, 0x550c, 0x550c, 0x550c, 0x550c, 0x550c, + 0x550c, 0x550c, 0x550c, 0x550c, 0x550c, 0x550c, 0x550d, 0x550d, + 0x550d, 0x550d, 0x550d, 0x550d, 0x550d, 0x550d, 0x550d, 0x550d, + 0x550d, 0x550d, 0x550e, 0x550e, 0x550e, 0x550e, 0x550e, 0x550e, + 0x550e, 0x550e, 0x550e, 0x550e, 0x550e, 0x550e, 0x550f, 0x550f, + 0x550f, 0x550f, 0x550f, 0x550f, 0x550f, 0x550f, 0x550f, 0x550f, + 0x550f, 0x550f, 0x5510, 0x5510, 0x5510, 0x5510, 0x5510, 0x5510, + 0x5510, 0x5510, 0x5510, 0x5510, 0x5510, 0x5510, 0x5510, 0x5511, + 0x5511, 0x5511, 0x5511, 0x5511, 0x5511, 0x5511, 0x5511, 0x5511, + 0x5511, 0x5511, 0x5511, 0x5512, 0x5512, 0x5512, 0x5512, 0x5512, + 0x5512, 0x5512, 0x5512, 0x5512, 0x5512, 0x5512, 0x5512, 0x5513, + 0x5513, 0x5513, 0x5513, 0x5513, 0x5513, 0x5513, 0x5513, 0x5513, + 0x5513, 0x5513, 0x5513, 0x5513, 0x5514, 0x5514, 0x5514, 0x5514, + 0x5514, 0x5514, 0x5514, 0x5514, 0x5514, 0x5514, 0x5514, 0x5514, + 0x5515, 0x5515, 0x5515, 0x5515, 0x5515, 0x5515, 0x5515, 0x5515, + 0x5515, 0x5515, 0x5515, 0x5515, 0x5515, 0x5516, 0x5516, 0x5516, + 0x5516, 0x5516, 0x5516, 0x5516, 0x5516, 0x5516, 0x5516, 0x5516, + 0x5516, 0x5516, 0x5517, 0x5517, 0x5517, 0x5517, 0x5517, 0x5517, + 0x5517, 0x5517, 0x5517, 0x5517, 0x5517, 0x5517, 0x5517, 0x5518, + 0x5518, 0x5518, 0x5518, 0x5518, 0x5518, 0x5518, 0x5518, 0x5518, + 0x5518, 0x5518, 0x5518, 0x5518, 0x5519, 0x5519, 0x5519, 0x5519, + 0x5519, 0x5519, 0x5519, 0x5519, 0x5519, 0x5519, 0x5519, 0x5519, + 0x5519, 0x551a, 0x551a, 0x551a, 0x551a, 0x551a, 0x551a, 0x551a, + 0x551a, 0x551a, 0x551a, 0x551a, 0x551a, 0x551a, 0x551b, 0x551b, + 0x551b, 0x551b, 0x551b, 0x551b, 0x551b, 0x551b, 0x551b, 0x551b, + 0x551b, 0x551b, 0x551b, 0x551c, 0x551c, 0x551c, 0x551c, 0x551c, + 0x551c, 0x551c, 0x551c, 0x551c, 0x551c, 0x551c, 0x551c, 0x551c, + 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, + 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, 0x551d, 0x551e, 0x551e, + 0x551e, 0x551e, 0x551e, 0x551e, 0x551e, 0x551e, 0x551e, 0x551e, + 0x551e, 0x551e, 0x551e, 0x551e, 0x551f, 0x551f, 0x551f, 0x551f, + 0x551f, 0x551f, 0x551f, 0x551f, 0x551f, 0x551f, 0x551f, 0x551f, + 0x551f, 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, + 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, 0x5520, 0x5521, + 0x5521, 0x5521, 0x5521, 0x5521, 0x5521, 0x5521, 0x5521, 0x5521, + 0x5521, 0x5521, 0x5521, 0x5521, 0x5521, 0x5522, 0x5522, 0x5522, + 0x5522, 0x5522, 0x5522, 0x5522, 0x5522, 0x5522, 0x5522, 0x5522, + 0x5522, 0x5522, 0x5522, 0x5523, 0x5523, 0x5523, 0x5523, 0x5523, + 0x5523, 0x5523, 0x5523, 0x5523, 0x5523, 0x5523, 0x5523, 0x5523, + 0x5523, 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, + 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, 0x5524, 0x5525, + 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, + 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, 0x5525, 0x5526, 0x5526, + 0x5526, 0x5526, 0x5526, 0x5526, 0x5526, 0x5526, 0x5526, 0x5526, + 0x5526, 0x5526, 0x5526, 0x5526, 0x5527, 0x5527, 0x5527, 0x5527, + 0x5527, 0x5527, 0x5527, 0x5527, 0x5527, 0x5527, 0x5527, 0x5527, + 0x5527, 0x5527, 0x5527, 0x5528, 0x5528, 0x5528, 0x5528, 0x5528, + 0x5528, 0x5528, 0x5528, 0x5528, 0x5528, 0x5528, 0x5528, 0x5528, + 0x5528, 0x5528, 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, + 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, 0x5529, + 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, + 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552a, 0x552b, + 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, + 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, 0x552b, 0x552c, 0x552c, + 0x552c, 0x552c, 0x552c, 0x552c, 0x552c, 0x552c, 0x552c, 0x552c, + 0x552c, 0x552c, 0x552c, 0x552c, 0x552c, 0x552d, 0x552d, 0x552d, + 0x552d, 0x552d, 0x552d, 0x552d, 0x552d, 0x552d, 0x552d, 0x552d, + 0x552d, 0x552d, 0x552d, 0x552d, 0x552d, 0x552e, 0x552e, 0x552e, + 0x552e, 0x552e, 0x552e, 0x552e, 0x552e, 0x552e, 0x552e, 0x552e, + 0x552e, 0x552e, 0x552e, 0x552e, 0x552f, 0x552f, 0x552f, 0x552f, + 0x552f, 0x552f, 0x552f, 0x552f, 0x552f, 0x552f, 0x552f, 0x552f, + 0x552f, 0x552f, 0x552f, 0x552f, 0x5530, 0x5530, 0x5530, 0x5530, + 0x5530, 0x5530, 0x5530, 0x5530, 0x5530, 0x5530, 0x5530, 0x5530, + 0x5530, 0x5530, 0x5530, 0x5531, 0x5531, 0x5531, 0x5531, 0x5531, + 0x5531, 0x5531, 0x5531, 0x5531, 0x5531, 0x5531, 0x5531, 0x5531, + 0x5531, 0x5531, 0x5531, 0x5532, 0x5532, 0x5532, 0x5532, 0x5532, + 0x5532, 0x5532, 0x5532, 0x5532, 0x5532, 0x5532, 0x5532, 0x5532, + 0x5532, 0x5532, 0x5532, 0x5533, 0x5533, 0x5533, 0x5533, 0x5533, + 0x5533, 0x5533, 0x5533, 0x5533, 0x5533, 0x5533, 0x5534, 0x5534, + 0x5534, 0x5534, 0x5534, 0x5534, 0x5534, 0x5534, 0x5535, 0x5535, + 0x5535, 0x5535, 0x5535, 0x5535, 0x5535, 0x5535, 0x5536, 0x5536, + 0x5536, 0x5536, 0x5536, 0x5536, 0x5536, 0x5536, 0x5537, 0x5537, + 0x5537, 0x5537, 0x5537, 0x5537, 0x5537, 0x5537, 0x5538, 0x5538, + 0x5538, 0x5538, 0x5538, 0x5538, 0x5538, 0x5538, 0x5538, 0x5539, + 0x5539, 0x5539, 0x5539, 0x5539, 0x5539, 0x5539, 0x5539, 0x553a, + 0x553a, 0x553a, 0x553a, 0x553a, 0x553a, 0x553a, 0x553a, 0x553a, + 0x553b, 0x553b, 0x553b, 0x553b, 0x553b, 0x553b, 0x553b, 0x553b, + 0x553c, 0x553c, 0x553c, 0x553c, 0x553c, 0x553c, 0x553c, 0x553c, + 0x553c, 0x553d, 0x553d, 0x553d, 0x553d, 0x553d, 0x553d, 0x553d, + 0x553d, 0x553e, 0x553e, 0x553e, 0x553e, 0x553e, 0x553e, 0x553e, + 0x553e, 0x553e, 0x553f, 0x553f, 0x553f, 0x553f, 0x553f, 0x553f, + 0x553f, 0x553f, 0x553f, 0x5540, 0x5540, 0x5540, 0x5540, 0x5540, + 0x5540, 0x5540, 0x5540, 0x5540, 0x5541, 0x5541, 0x5541, 0x5541, + 0x5541, 0x5541, 0x5541, 0x5541, 0x5541, 0x5542, 0x5542, 0x5542, + 0x5542, 0x5542, 0x5542, 0x5542, 0x5542, 0x5542, 0x5543, 0x5543, + 0x5543, 0x5543, 0x5543, 0x5543, 0x5543, 0x5543, 0x5543, 0x5544, + 0x5544, 0x5544, 0x5544, 0x5544, 0x5544, 0x5544, 0x5544, 0x5544, + 0x5545, 0x5545, 0x5545, 0x5545, 0x5545, 0x5545, 0x5545, 0x5545, + 0x5545, 0x5546, 0x5546, 0x5546, 0x5546, 0x5546, 0x5546, 0x5546, + 0x5546, 0x5546, 0x5547, 0x5547, 0x5547, 0x5547, 0x5547, 0x5547, + 0x5547, 0x5547, 0x5547, 0x5547, 0x5548, 0x5548, 0x5548, 0x5548, + 0x5548, 0x5548, 0x5548, 0x5548, 0x5548, 0x5549, 0x5549, 0x5549, + 0x5549, 0x5549, 0x5549, 0x5549, 0x5549, 0x5549, 0x5549, 0x554a, + 0x554a, 0x554a, 0x554a, 0x554a, 0x554a, 0x554a, 0x554a, 0x554a, + 0x554b, 0x554b, 0x554b, 0x554b, 0x554b, 0x554b, 0x554b, 0x554b, + 0x554b, 0x554b, 0x554c, 0x554c, 0x554c, 0x554c, 0x554c, 0x554c, + 0x554c, 0x554c, 0x554c, 0x554c, 0x554d, 0x554d, 0x554d, 0x554d, + 0x554d, 0x554d, 0x554d, 0x554d, 0x554d, 0x554d, 0x554e, 0x554e, + 0x554e, 0x554e, 0x554e, 0x554e, 0x554e, 0x554e, 0x554e, 0x554f, + 0x554f, 0x554f, 0x554f, 0x554f, 0x554f, 0x554f, 0x554f, 0x554f, + 0x554f, 0x5550, 0x5550, 0x5550, 0x5550, 0x5550, 0x5550, 0x5550, + 0x5550, 0x5550, 0x5550, 0x5551, 0x5551, 0x5551, 0x5551, 0x5551, + 0x5551, 0x5551, 0x5551, 0x5551, 0x5551, 0x5551, 0x5552, 0x5552, + 0x5552, 0x5552, 0x5552, 0x5552, 0x5552, 0x5552, 0x5552, 0x5552, + 0x5553, 0x5553, 0x5553, 0x5553, 0x5553, 0x5553, 0x5553, 0x5553, + 0x5553, 0x5553, 0x5554, 0x5554, 0x5554, 0x5554, 0x5554, 0x5554, + 0x5554, 0x5554, 0x5554, 0x5554, 0x5555, 0x5555, 0x5555, 0x5555, + 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5556, + 0x5556, 0x5556, 0x5556, 0x5556, 0x5556, 0x5556, 0x5556, 0x5556, + 0x5556, 0x5557, 0x5557, 0x5557, 0x5557, 0x5557, 0x5557, 0x5557, + 0x5557, 0x5557, 0x5557, 0x5557, 0x5558, 0x5558, 0x5558, 0x5558, + 0x5558, 0x5558, 0x5558, 0x5558, 0x5558, 0x5558, 0x5558, 0x5559, + 0x5559, 0x5559, 0x5559, 0x5559, 0x5559, 0x5559, 0x5559, 0x5559, + 0x5559, 0x5559, 0x555a, 0x555a, 0x555a, 0x555a, 0x555a, 0x555a, + 0x555a, 0x555a, 0x555a, 0x555a, 0x555b, 0x555b, 0x555b, 0x555b, + 0x555b, 0x555b, 0x555b, 0x555b, 0x555b, 0x555b, 0x555b, 0x555c, + 0x555c, 0x555c, 0x555c, 0x555c, 0x555c, 0x555c, 0x555c, 0x555c, + 0x555c, 0x555c, 0x555d, 0x555d, 0x555d, 0x555d, 0x555d, 0x555d, + 0x555d, 0x555d, 0x555d, 0x555d, 0x555d, 0x555d, 0x555e, 0x555e, + 0x555e, 0x555e, 0x555e, 0x555e, 0x555e, 0x555e, 0x555e, 0x555e, + 0x555e, 0x555f, 0x555f, 0x555f, 0x555f, 0x555f, 0x555f, 0x555f, + 0x555f, 0x555f, 0x555f, 0x555f, 0x5560, 0x5560, 0x5560, 0x5560, + 0x5560, 0x5560, 0x5560, 0x5560, 0x5560, 0x5560, 0x5560, 0x5561, + 0x5561, 0x5561, 0x5561, 0x5561, 0x5561, 0x5561, 0x5561, 0x5561, + 0x5561, 0x5561, 0x5561, 0x5562, 0x5562, 0x5562, 0x5562, 0x5562, + 0x5562, 0x5562, 0x5562, 0x5562, 0x5562, 0x5562, 0x5563, 0x5563, + 0x5563, 0x5563, 0x5563, 0x5563, 0x5563, 0x5563, 0x5563, 0x5563, + 0x5563, 0x5563, 0x5564, 0x5564, 0x5564, 0x5564, 0x5564, 0x5564, + 0x5564, 0x5564, 0x5564, 0x5564, 0x5564, 0x5564, 0x5565, 0x5565, + 0x5565, 0x5565, 0x5565, 0x5565, 0x5565, 0x5565, 0x5565, 0x5565, + 0x5565, 0x5565, 0x5566, 0x5566, 0x5566, 0x5566, 0x5566, 0x5566, + 0x5566, 0x5566, 0x5566, 0x5566, 0x5566, 0x5566, 0x5567, 0x5567, + 0x5567, 0x5567, 0x5567, 0x5567, 0x5567, 0x5567, 0x5567, 0x5567, + 0x5567, 0x5567, 0x5568, 0x5568, 0x5568, 0x5568, 0x5568, 0x5568, + 0x5568, 0x5568, 0x5568, 0x5568, 0x5568, 0x5568, 0x5569, 0x5569, + 0x5569, 0x5569, 0x5569, 0x5569, 0x5569, 0x5569, 0x5569, 0x5569, + 0x5569, 0x5569, 0x556a, 0x556a, 0x556a, 0x556a, 0x556a, 0x556a, + 0x556a, 0x556a, 0x556a, 0x556a, 0x556a, 0x556a, 0x556b, 0x556b, + 0x556b, 0x556b, 0x556b, 0x556b, 0x556b, 0x556b, 0x556b, 0x556b, + 0x556b, 0x556b, 0x556b, 0x556c, 0x556c, 0x556c, 0x556c, 0x556c, + 0x556c, 0x556c, 0x556c, 0x556c, 0x556c, 0x556c, 0x556c, 0x556d, + 0x556d, 0x556d, 0x556d, 0x556d, 0x556d, 0x556d, 0x556d, 0x556d, + 0x556d, 0x556d, 0x556d, 0x556d, 0x556e, 0x556e, 0x556e, 0x556e, + 0x556e, 0x556e, 0x556e, 0x556e, 0x556e, 0x556e, 0x556e, 0x556e, + 0x556f, 0x556f, 0x556f, 0x556f, 0x556f, 0x556f, 0x556f, 0x556f, + 0x556f, 0x556f, 0x556f, 0x556f, 0x556f, 0x5570, 0x5570, 0x5570, + 0x5570, 0x5570, 0x5570, 0x5570, 0x5570, 0x5570, 0x5570, 0x5570, + 0x5570, 0x5570, 0x5571, 0x5571, 0x5571, 0x5571, 0x5571, 0x5571, + 0x5571, 0x5571, 0x5571, 0x5571, 0x5571, 0x5571, 0x5571, 0x5572, + 0x5572, 0x5572, 0x5572, 0x5572, 0x5572, 0x5572, 0x5572, 0x5572, + 0x5572, 0x5572, 0x5572, 0x5572, 0x5573, 0x5573, 0x5573, 0x5573, + 0x5573, 0x5573, 0x5573, 0x5573, 0x5573, 0x5573, 0x5573, 0x5573, + 0x5573, 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, + 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, 0x5574, 0x5575, + 0x5575, 0x5575, 0x5575, 0x5575, 0x5575, 0x5575, 0x5575, 0x5575, + 0x5575, 0x5575, 0x5575, 0x5575, 0x5576, 0x5576, 0x5576, 0x5576, + 0x5576, 0x5576, 0x5576, 0x5576, 0x5576, 0x5576, 0x5576, 0x5576, + 0x5576, 0x5576, 0x5577, 0x5577, 0x5577, 0x5577, 0x5577, 0x5577, + 0x5577, 0x5577, 0x5577, 0x5577, 0x5577, 0x5577, 0x5577, 0x5578, + 0x5578, 0x5578, 0x5578, 0x5578, 0x5578, 0x5578, 0x5578, 0x5578, + 0x5578, 0x5578, 0x5578, 0x5578, 0x5578, 0x5579, 0x5579, 0x5579, + 0x5579, 0x5579, 0x5579, 0x5579, 0x5579, 0x5579, 0x5579, 0x5579, + 0x5579, 0x5579, 0x5579, 0x557a, 0x557a, 0x557a, 0x557a, 0x557a, + 0x557a, 0x557a, 0x557a, 0x557a, 0x557a, 0x557a, 0x557a, 0x557a, + 0x557a, 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, + 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, 0x557b, 0x557c, + 0x557c, 0x557c, 0x557c, 0x557c, 0x557c, 0x557c, 0x557c, 0x557c, + 0x557c, 0x557c, 0x557c, 0x557c, 0x557c, 0x557d, 0x557d, 0x557d, + 0x557d, 0x557d, 0x557d, 0x557d, 0x557d, 0x557d, 0x557d, 0x557d, + 0x557d, 0x557d, 0x557d, 0x557e, 0x557e, 0x557e, 0x557e, 0x557e, + 0x557e, 0x557e, 0x557e, 0x557e, 0x557e, 0x557e, 0x557e, 0x557e, + 0x557e, 0x557e, 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, + 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, 0x557f, + 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, + 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5580, 0x5581, + 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, + 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, 0x5581, 0x5582, 0x5582, + 0x5582, 0x5582, 0x5582, 0x5582, 0x5582, 0x5582, 0x5582, 0x5582, + 0x5582, 0x5582, 0x5582, 0x5582, 0x5583, 0x5583, 0x5583, 0x5583, + 0x5583, 0x5583, 0x5583, 0x5583, 0x5583, 0x5583, 0x5583, 0x5583, + 0x5583, 0x5583, 0x5583, 0x5584, 0x5584, 0x5584, 0x5584, 0x5584, + 0x5584, 0x5584, 0x5584, 0x5584, 0x5584, 0x5584, 0x5584, 0x5584, + 0x5584, 0x5584, 0x5584, 0x5585, 0x5585, 0x5585, 0x5585, 0x5585, + 0x5585, 0x5585, 0x5585, 0x5585, 0x5585, 0x5585, 0x5585, 0x5585, + 0x5585, 0x5585, 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, + 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, 0x5586, + 0x5586, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, + 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, 0x5587, + 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, + 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, 0x5588, + 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, + 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, 0x5589, + 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, + 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, 0x558a, + 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, + 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558b, 0x558c, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xfc00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,80 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Thread -- dummy implementation for +// platforms that do not support threading +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if !defined (_WIN32) && !defined(_WIN64) && !(HAVE_PTHREAD) + +#include "IlmThread.h" +#include "Iex.h" + +namespace IlmThread { + + +bool +supportsThreads () +{ + return false; +} + + +Thread::Thread () +{ + throw Iex::NoImplExc ("Threads not supported on this platform."); +} + + +Thread::~Thread () +{ + throw Iex::NoImplExc ("Threads not supported on this platform."); +} + + +void +Thread::start () +{ + throw Iex::NoImplExc ("Threads not supported on this platform."); +} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThread.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_ILM_THREAD_H +#define INCLUDED_ILM_THREAD_H + +//----------------------------------------------------------------------------- +// +// class Thread +// +// Class Thread is a portable interface to a system-dependent thread +// primitive. In order to make a thread actually do something useful, +// you must derive a subclass from class Thread and implement the +// run() function. If the operating system supports threading then +// the run() function will be executed int a new thread. +// +// The actual creation of the thread is done by the start() routine +// which then calls the run() function. In general the start() +// routine should be called from the constructor of the derived class. +// +// The base-class thread destructor will join/destroy the thread. +// +// IMPORTANT: Due to the mechanisms that encapsulate the low-level +// threading primitives in a C++ class there is a race condition +// with code resembling the following: +// +// { +// WorkerThread myThread; +// } // myThread goes out of scope, is destroyed +// // and the thread is joined +// +// The race is between the parent thread joining the child thread +// in the destructor of myThread, and the run() function in the +// child thread. If the destructor gets executed first then run() +// will be called with an invalid "this" pointer. +// +// This issue can be fixed by using a Semaphore to keep track of +// whether the run() function has already been called. You can +// include a Semaphore member variable within your derived class +// which you post() on in the run() function, and wait() on in the +// destructor before the thread is joined. Alternatively you could +// do something like this: +// +// Semaphore runStarted; +// +// void WorkerThread::run () +// { +// runStarted.post() +// // do some work +// ... +// } +// +// { +// WorkerThread myThread; +// runStarted.wait (); // ensure that we have started +// // the run function +// } // myThread goes out of scope, is destroyed +// // and the thread is joined +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if defined _WIN32 || defined _WIN64 + #ifdef NOMINMAX + #undef NOMINMAX + #endif + #define NOMINMAX + #include + #include +#elif HAVE_PTHREAD + #include +#endif + +#if defined(OPENEXR_DLL) && !defined(ZENO_STATIC) + #ifdef ILMTHREAD_EXPORTS + #define ILMTHREAD_EXPORT __declspec(dllexport) + #else + #define ILMTHREAD_EXPORT __declspec(dllimport) + #endif +#else + #define ILMTHREAD_EXPORT +#endif + +namespace IlmThread { + +// +// Query function to determine if the current platform supports +// threads AND this library was compiled with threading enabled. +// + +ILMTHREAD_EXPORT bool supportsThreads (); + + +class ILMTHREAD_EXPORT Thread +{ + public: + + Thread (); + virtual ~Thread (); + + void start (); + virtual void run () = 0; + + private: + + #if defined _WIN32 || defined _WIN64 + HANDLE _thread; + #elif HAVE_PTHREAD + pthread_t _thread; + #endif + + void operator = (const Thread& t); // not implemented + Thread (const Thread& t); // not implemented +}; + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,59 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Mutex, class Lock -- dummy implementation +// for platforms that do not support threading +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD) + +#include "IlmThreadMutex.h" + +namespace IlmThread { + + +Mutex::Mutex () {} +Mutex::~Mutex () {} +void Mutex::lock () const {} +void Mutex::unlock () const {} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutex.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,158 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_ILM_THREAD_MUTEX_H +#define INCLUDED_ILM_THREAD_MUTEX_H + +//----------------------------------------------------------------------------- +// +// class Mutex, class Lock +// +// Class Mutex is a wrapper for a system-dependent mutual exclusion +// mechanism. Actual locking and unlocking of a Mutex object must +// be performed using an instance of a Lock (defined below). +// +// Class lock provides safe locking and unlocking of mutexes even in +// the presence of C++ exceptions. Constructing a Lock object locks +// the mutex; destroying the Lock unlocks the mutex. +// +// Lock objects are not themselves thread-safe. You should never +// share a Lock object among multiple threads. +// +// Typical usage: +// +// Mutex mtx; // Create a Mutex object that is visible +// //to multiple threads +// +// ... // create some threads +// +// // Then, within each thread, construct a critical section like so: +// +// { +// Lock lock (mtx); // Lock constructor locks the mutex +// ... // do some computation on shared data +// } // leaving the block unlocks the mutex +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if defined _WIN32 || defined _WIN64 + #ifdef NOMINMAX + #undef NOMINMAX + #endif + #define NOMINMAX + #include +#elif HAVE_PTHREAD + #include +#endif + +namespace IlmThread { + +class Lock; + + +class Mutex +{ + public: + + Mutex (); + virtual ~Mutex (); + + private: + + void lock () const; + void unlock () const; + + #if defined _WIN32 || defined _WIN64 + mutable CRITICAL_SECTION _mutex; + #elif HAVE_PTHREAD + mutable pthread_mutex_t _mutex; + #endif + + void operator = (const Mutex& M); // not implemented + Mutex (const Mutex& M); // not implemented + + friend class Lock; +}; + + +class Lock +{ + public: + + Lock (const Mutex& m, bool autoLock = true): + _mutex (m), + _locked (false) + { + if (autoLock) + { + _mutex.lock(); + _locked = true; + } + } + + ~Lock () + { + if (_locked) + _mutex.unlock(); + } + + void acquire () + { + _mutex.lock(); + _locked = true; + } + + void release () + { + _mutex.unlock(); + _locked = false; + } + + bool locked () + { + return _locked; + } + + private: + + const Mutex & _mutex; + bool _locked; +}; + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexPosix.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexPosix.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexPosix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexPosix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Mutex -- implementation for +// platforms that support Posix threads +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if HAVE_PTHREAD + +#include "IlmThreadMutex.h" +#include "Iex.h" +#include + +namespace IlmThread { + + +Mutex::Mutex () +{ + if (int error = ::pthread_mutex_init (&_mutex, 0)) + Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error); +} + + +Mutex::~Mutex () +{ + int error = ::pthread_mutex_destroy (&_mutex); + assert (error == 0); +} + + +void +Mutex::lock () const +{ + if (int error = ::pthread_mutex_lock (&_mutex)) + Iex::throwErrnoExc ("Cannot lock mutex (%T).", error); +} + + +void +Mutex::unlock () const +{ + if (int error = ::pthread_mutex_unlock (&_mutex)) + Iex::throwErrnoExc ("Cannot unlock mutex (%T).", error); +} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexWin32.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexWin32.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexWin32.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadMutexWin32.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Mutex -- implementation for Windows +// +//----------------------------------------------------------------------------- + +#ifdef WIN32 // XBEE + +#include "IlmThreadMutex.h" +#include "Iex.h" + +namespace IlmThread { + + +Mutex::Mutex () +{ + ::InitializeCriticalSection (&_mutex); +} + + +Mutex::~Mutex () +{ + ::DeleteCriticalSection (&_mutex); +} + + +void +Mutex::lock () const +{ + ::EnterCriticalSection (&_mutex); +} + + +void +Mutex::unlock () const +{ + ::LeaveCriticalSection (&_mutex); +} + + +} // namespace IlmThread + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,456 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Task, class ThreadPool, class TaskGroup +// +//----------------------------------------------------------------------------- + +#include "IlmThread.h" +#include "IlmThreadMutex.h" +#include "IlmThreadSemaphore.h" +#include "IlmThreadPool.h" +#include "Iex.h" +#include + +using namespace std; + +namespace IlmThread { +namespace { + +class WorkerThread: public Thread +{ + public: + + WorkerThread (ThreadPool::Data* data); + + virtual void run (); + + private: + + ThreadPool::Data * _data; +}; + +} //namespace + + +struct TaskGroup::Data +{ + Data (); + ~Data (); + + void addTask () ; + void removeTask (); + + Semaphore isEmpty; // used to signal that the taskgroup is empty + int numPending; // number of pending tasks to still execute +}; + + +struct ThreadPool::Data +{ + Data (); + ~Data(); + + void finish (); + bool stopped () const; + void stop (); + + Semaphore taskSemaphore; // threads wait on this for ready tasks + Mutex taskMutex; // mutual exclusion for the tasks list + list tasks; // the list of tasks to execute + size_t numTasks; // fast access to list size + // (list::size() can be O(n)) + + Semaphore threadSemaphore; // signaled when a thread starts executing + Mutex threadMutex; // mutual exclusion for threads list + list threads; // the list of all threads + size_t numThreads; // fast access to list size + + bool stopping; // flag indicating whether to stop threads + Mutex stopMutex; // mutual exclusion for stopping flag +}; + + + +// +// class WorkerThread +// + +WorkerThread::WorkerThread (ThreadPool::Data* data): + _data (data) +{ + start(); +} + + +void +WorkerThread::run () +{ + // + // Signal that the thread has started executing + // + + _data->threadSemaphore.post(); + + while (true) + { + // + // Wait for a task to become available + // + + _data->taskSemaphore.wait(); + + { + Lock taskLock (_data->taskMutex); + + // + // If there is a task pending, pop off the next task in the FIFO + // + + if (_data->numTasks > 0) + { + Task* task = _data->tasks.front(); + TaskGroup* taskGroup = task->group(); + _data->tasks.pop_front(); + _data->numTasks--; + + taskLock.release(); + task->execute(); + taskLock.acquire(); + + delete task; + taskGroup->_data->removeTask(); + } + else if (_data->stopped()) + { + break; + } + } + } +} + + +// +// struct TaskGroup::Data +// + +TaskGroup::Data::Data (): isEmpty (1), numPending (0) +{ + // empty +} + + +TaskGroup::Data::~Data () +{ + // + // A TaskGroup acts like an "inverted" semaphore: if the count + // is above 0 then waiting on the taskgroup will block. This + // destructor waits until the taskgroup is empty before returning. + // + + isEmpty.wait (); +} + + +void +TaskGroup::Data::addTask () +{ + // + // Any access to the taskgroup is protected by a mutex that is + // held by the threadpool. Therefore it is safe to access + // numPending before we wait on the semaphore. + // + + if (numPending++ == 0) + isEmpty.wait (); +} + + +void +TaskGroup::Data::removeTask () +{ + if (--numPending == 0) + isEmpty.post (); +} + + +// +// struct ThreadPool::Data +// + +ThreadPool::Data::Data (): numTasks (0), numThreads (0), stopping (false) +{ + // empty +} + + +ThreadPool::Data::~Data() +{ + Lock lock (threadMutex); + finish (); +} + + +void +ThreadPool::Data::finish () +{ + stop(); + + // + // Signal enough times to allow all threads to stop. + // + // Wait until all threads have started their run functions. + // If we do not wait before we destroy the threads then it's + // possible that the threads have not yet called their run + // functions. + // If this happens then the run function will be called off + // of an invalid object and we will crash, most likely with + // an error like: "pure virtual method called" + // + + for (size_t i = 0; i < numThreads; i++) + { + taskSemaphore.post(); + threadSemaphore.wait(); + } + + // + // Join all the threads + // + + for (list::iterator i = threads.begin(); + i != threads.end(); + ++i) + { + delete (*i); + } + + Lock lock1 (taskMutex); + Lock lock2 (stopMutex); + threads.clear(); + tasks.clear(); + numThreads = 0; + numTasks = 0; + stopping = false; +} + + +bool +ThreadPool::Data::stopped () const +{ + Lock lock (stopMutex); + return stopping; +} + + +void +ThreadPool::Data::stop () +{ + Lock lock (stopMutex); + stopping = true; +} + + +// +// class Task +// + +Task::Task (TaskGroup* g): _group(g) +{ + // empty +} + + +Task::~Task() +{ + // empty +} + + +TaskGroup* +Task::group () +{ + return _group; +} + + +TaskGroup::TaskGroup (): + _data (new Data()) +{ + // empty +} + + +TaskGroup::~TaskGroup () +{ + delete _data; +} + + +// +// class ThreadPool +// + +ThreadPool::ThreadPool (unsigned nthreads): + _data (new Data()) +{ + setNumThreads (nthreads); +} + + +ThreadPool::~ThreadPool () +{ + delete _data; +} + + +int +ThreadPool::numThreads () const +{ + Lock lock (_data->threadMutex); + return _data->numThreads; +} + + +void +ThreadPool::setNumThreads (int count) +{ + if (count < 0) + throw Iex::ArgExc ("Attempt to set the number of threads " + "in a thread pool to a negative value."); + + // + // Lock access to thread list and size + // + + Lock lock (_data->threadMutex); + + if ((size_t)count > _data->numThreads) + { + // + // Add more threads + // + + while (_data->numThreads < (size_t)count) + { + _data->threads.push_back (new WorkerThread (_data)); + _data->numThreads++; + } + } + else if ((size_t)count < _data->numThreads) + { + // + // Wait until all existing threads are finished processing, + // then delete all threads. + // + + _data->finish (); + + // + // Add in new threads + // + + while (_data->numThreads < (size_t)count) + { + _data->threads.push_back (new WorkerThread (_data)); + _data->numThreads++; + } + } +} + + +void +ThreadPool::addTask (Task* task) +{ + // + // Lock the threads, needed to access numThreads + // + + Lock lock (_data->threadMutex); + + if (_data->numThreads == 0) + { + task->execute (); + delete task; + } + else + { + // + // Get exclusive access to the tasks queue + // + + { + Lock taskLock (_data->taskMutex); + + // + // Push the new task into the FIFO + // + + _data->tasks.push_back (task); + _data->numTasks++; + task->group()->_data->addTask(); + } + + // + // Signal that we have a new task to process + // + + _data->taskSemaphore.post (); + } +} + + +ThreadPool& +ThreadPool::globalThreadPool () +{ + // + // The global thread pool + // + + static ThreadPool gThreadPool (0); + + return gThreadPool; +} + + +void +ThreadPool::addGlobalTask (Task* task) +{ + globalThreadPool().addTask (task); +} + + +} // namespace IlmThread diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPool.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_ILM_THREAD_POOL_H +#define INCLUDED_ILM_THREAD_POOL_H + +//----------------------------------------------------------------------------- +// +// class Task, class ThreadPool, class TaskGroup +// +// Class ThreadPool manages a set of worker threads and accepts +// tasks for processing. Tasks added to the thread pool are +// executed concurrently by the worker threads. +// +// Class Thread provides an abstract interface for a task which +// a ThreadPool works on. Derived classes need to implement the +// execute() function which performs the actual task. +// +// Class TaskTroup allows synchronization on the completion of a set +// of tasks. Every task that is added to a ThreadPool belongs to a +// single TaskGroup. The destructor of the TaskGroup waits for all +// tasks in the group to finish. +// +// Note: if you plan to use the ThreadPool interface in your own +// applications note that the implementation of the ThreadPool calls +// operator delete on tasks as they complete. If you define a custom +// operator new for your tasks, for instance to use a custom heap, +// then you must also write an appropriate operator delete. +// +//----------------------------------------------------------------------------- + +namespace IlmThread { + +class TaskGroup; +class Task; + + +class ThreadPool +{ + public: + + //------------------------------------------------------- + // Constructor -- creates numThreads worker threads which + // wait until a task is available. + //------------------------------------------------------- + + ThreadPool (unsigned numThreads = 0); + + + //----------------------------------------------------------- + // Destructor -- waits for all tasks to complete, joins all + // the threads to the calling thread, and then destroys them. + //----------------------------------------------------------- + + virtual ~ThreadPool (); + + + //-------------------------------------------------------- + // Query and set the number of worker threads in the pool. + // + // Warning: never call setNumThreads from within a worker + // thread as this will almost certainly cause a deadlock + // or crash. + //-------------------------------------------------------- + + int numThreads () const; + void setNumThreads (int count); + + + //------------------------------------------------------------ + // Add a task for processing. The ThreadPool can handle any + // number of tasks regardless of the number of worker threads. + // The tasks are first added onto a queue, and are executed + // by threads as they become available, in FIFO order. + //------------------------------------------------------------ + + void addTask (Task* task); + + + //------------------------------------------- + // Access functions for the global threadpool + //------------------------------------------- + + static ThreadPool& globalThreadPool (); + static void addGlobalTask (Task* task); + + struct Data; + + protected: + + Data * _data; +}; + + +class Task +{ + public: + + Task (TaskGroup* g); + virtual ~Task (); + + virtual void execute () = 0; + TaskGroup * group(); + + protected: + + TaskGroup * _group; +}; + + +class TaskGroup +{ + public: + + TaskGroup(); + ~TaskGroup(); + + struct Data; + Data* const _data; +}; + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPosix.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPosix.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPosix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadPosix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Thread -- implementation for +// platforms that support Posix threads +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if HAVE_PTHREAD + +#include "IlmThread.h" +#include "Iex.h" +#include + +extern "C" +{ + typedef void * (* Start) (void *); +} + +namespace IlmThread { + + +bool +supportsThreads () +{ + return true; +} + +namespace { + +void +threadLoop (void * t) +{ + return (reinterpret_cast(t))->run(); +} + +} // namespace + + +Thread::Thread () +{ + // empty +} + + +Thread::~Thread () +{ + int error = ::pthread_join (_thread, 0); + assert (error == 0); +} + + +void +Thread::start () +{ + if (int error = ::pthread_create (&_thread, 0, Start (threadLoop), this)) + Iex::throwErrnoExc ("Cannot create new thread (%T).", error); +} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Semaphore -- dummy implementation for +// for platforms that do not support threading +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD) +#include "IlmThreadSemaphore.h" + +namespace IlmThread { + + +Semaphore::Semaphore (unsigned int value) {} +Semaphore::~Semaphore () {} +void Semaphore::wait () {} +bool Semaphore::tryWait () {return true;} +void Semaphore::post () {} +int Semaphore::value () const {return 0;} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphore.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,110 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_ILM_THREAD_SEMAPHORE_H +#define INCLUDED_ILM_THREAD_SEMAPHORE_H + +//----------------------------------------------------------------------------- +// +// class Semaphore -- a wrapper class for +// system-dependent counting semaphores +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if defined _WIN32 || defined _WIN64 + #ifdef NOMINMAX + #undef NOMINMAX + #endif + #define NOMINMAX + #include +#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES + #include +#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES + #include +#endif + +namespace IlmThread { + + +class Semaphore +{ + public: + + Semaphore (unsigned int value = 0); + virtual ~Semaphore(); + + void wait(); + bool tryWait(); + void post(); + int value() const; + + private: + + #if defined _WIN32 || defined _WIN64 + + mutable HANDLE _semaphore; + + #elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES + + // + // If the platform has Posix threads but no semapohores, + // then we implement them ourselves using condition variables + // + + struct sema_t + { + unsigned int count; + unsigned long numWaiting; + pthread_mutex_t mutex; + pthread_cond_t nonZero; + }; + + mutable sema_t _semaphore; + + #elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES + + mutable sem_t _semaphore; + + #endif + + void operator = (const Semaphore& s); // not implemented + Semaphore (const Semaphore& s); // not implemented +}; + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosix.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosix.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Semaphore -- implementation for platforms +// that support Posix threads and Posix semaphores +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES + +#include "IlmThreadSemaphore.h" +#include "Iex.h" +#include + +namespace IlmThread { + + +Semaphore::Semaphore (unsigned int value) +{ + if (::sem_init (&_semaphore, 0, value)) + Iex::throwErrnoExc ("Cannot initialize semaphore (%T)."); +} + + +Semaphore::~Semaphore () +{ + int error = ::sem_destroy (&_semaphore); + assert (error == 0); +} + + +void +Semaphore::wait () +{ + ::sem_wait (&_semaphore); +} + + +bool +Semaphore::tryWait () +{ + return sem_trywait (&_semaphore) == 0; +} + + +void +Semaphore::post () +{ + if (::sem_post (&_semaphore)) + Iex::throwErrnoExc ("Post operation on semaphore failed (%T)."); +} + + +int +Semaphore::value () const +{ + int value; + + if (::sem_getvalue (&_semaphore, &value)) + Iex::throwErrnoExc ("Cannot read semaphore value (%T)."); + + return value; +} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosixCompat.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosixCompat.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosixCompat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphorePosixCompat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,155 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Semaphore -- implementation for for platforms that do +// support Posix threads but do not support Posix semaphores, +// for example, OS X +// +//----------------------------------------------------------------------------- + +#include "IlmBaseConfig.h" + +#if HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES + +#include "IlmThreadSemaphore.h" +#include "Iex.h" +#include + +namespace IlmThread { + + +Semaphore::Semaphore (unsigned int value) +{ + if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0)) + Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error); + + if (int error = ::pthread_cond_init (&_semaphore.nonZero, 0)) + Iex::throwErrnoExc ("Cannot initialize condition variable (%T).", + error); + + _semaphore.count = value; + _semaphore.numWaiting = 0; +} + + +Semaphore::~Semaphore () +{ + int error = ::pthread_cond_destroy (&_semaphore.nonZero); + assert (error == 0); + error = ::pthread_mutex_destroy (&_semaphore.mutex); + assert (error == 0); +} + + +void +Semaphore::wait () +{ + ::pthread_mutex_lock (&_semaphore.mutex); + + _semaphore.numWaiting++; + + while (_semaphore.count == 0) + { + if (int error = ::pthread_cond_wait (&_semaphore.nonZero, + &_semaphore.mutex)) + { + ::pthread_mutex_unlock (&_semaphore.mutex); + + Iex::throwErrnoExc ("Cannot wait on condition variable (%T).", + error); + } + } + + _semaphore.numWaiting--; + _semaphore.count--; + + ::pthread_mutex_unlock (&_semaphore.mutex); +} + + +bool +Semaphore::tryWait () +{ + ::pthread_mutex_lock (&_semaphore.mutex); + + if (_semaphore.count == 0) + { + ::pthread_mutex_unlock (&_semaphore.mutex); + return false; + } + else + { + _semaphore.count--; + ::pthread_mutex_unlock (&_semaphore.mutex); + return true; + } +} + + +void +Semaphore::post () +{ + ::pthread_mutex_lock (&_semaphore.mutex); + + if (_semaphore.numWaiting > 0) + { + if (int error = ::pthread_cond_signal (&_semaphore.nonZero)) + { + ::pthread_mutex_unlock (&_semaphore.mutex); + + Iex::throwErrnoExc ("Cannot signal condition variable (%T).", + error); + } + } + + _semaphore.count++; + ::pthread_mutex_unlock (&_semaphore.mutex); +} + + +int +Semaphore::value () const +{ + ::pthread_mutex_lock (&_semaphore.mutex); + int value = _semaphore.count; + ::pthread_mutex_unlock (&_semaphore.mutex); + return value; +} + + +} // namespace IlmThread + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphoreWin32.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphoreWin32.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphoreWin32.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadSemaphoreWin32.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,150 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Semaphore -- implementation for Windows +// +//----------------------------------------------------------------------------- + +#ifdef WIN32 // XBEE + +#include "IlmThreadSemaphore.h" +#include "Iex.h" +#include +#include +#include + +namespace IlmThread { + +using namespace Iex; + +namespace { + +std::string +errorString () +{ + LPSTR messageBuffer; + DWORD bufferLength; + std::string message; + + // + // Call FormatMessage() to allow for message + // text to be acquired from the system. + // + + if (bufferLength = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + 0, + GetLastError (), + MAKELANGID (LANG_NEUTRAL, + SUBLANG_DEFAULT), + (LPSTR) &messageBuffer, + 0, + NULL)) + { + message = messageBuffer; + LocalFree (messageBuffer); + } + + return message; +} + +} // namespace + + +Semaphore::Semaphore (unsigned int value) +{ + if ((_semaphore = ::CreateSemaphore (0, value, 0x7fffffff, 0)) == 0) + { + THROW (LogicExc, "Could not create semaphore " + "(" << errorString() << ")."); + } +} + + +Semaphore::~Semaphore() +{ + bool ok = ::CloseHandle (_semaphore) != FALSE; + assert (ok); +} + + +void +Semaphore::wait() +{ + if (::WaitForSingleObject (_semaphore, INFINITE) != WAIT_OBJECT_0) + { + THROW (LogicExc, "Could not wait on semaphore " + "(" << errorString() << ")."); + } +} + + +bool +Semaphore::tryWait() +{ + return ::WaitForSingleObject (_semaphore, 0) == WAIT_OBJECT_0; +} + + +void +Semaphore::post() +{ + if (!::ReleaseSemaphore (_semaphore, 1, 0)) + { + THROW (LogicExc, "Could not post on semaphore " + "(" << errorString() << ")."); + } +} + + +int +Semaphore::value() const +{ + LONG v = -1; + + if (!::ReleaseSemaphore (_semaphore, 0, &v) || v < 0) + { + THROW (LogicExc, "Could not get value of semaphore " + "(" << errorString () << ")."); + } + + return v; +} + +} // namespace IlmThread + +#endif // WIN32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadWin32.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadWin32.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadWin32.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/IlmThread/IlmThreadWin32.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// class Thread -- implementation for Windows +// +//----------------------------------------------------------------------------- + +#ifdef WIN32 // XBEE + +#include "IlmThread.h" +#include "Iex.h" +#include +#include + +namespace IlmThread { + + +bool +supportsThreads () +{ + return true; +} + +namespace { + +unsigned __stdcall +threadLoop (void * t) +{ + reinterpret_cast(t)->run(); + _endthreadex (0); + return 0; +} + +} // namespace + + +Thread::Thread () +{ + // empty +} + + +Thread::~Thread () +{ + DWORD status = ::WaitForSingleObject (_thread, INFINITE); + assert (status == WAIT_OBJECT_0); + bool ok = ::CloseHandle (_thread) != FALSE; + assert (ok); +} + + +void +Thread::start () +{ + unsigned id; + _thread = (HANDLE)::_beginthreadex (0, 0, &threadLoop, this, 0, &id); + + if (_thread == 0) + Iex::throwErrnoExc ("Cannot create new thread (%T)."); +} + + +} // namespace IlmThread + +#endif // WIN32 \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBox.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBox.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBox.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBox.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,850 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATHBOX_H +#define INCLUDED_IMATHBOX_H + +//------------------------------------------------------------------- +// +// class Imath::Box +// -------------------------------- +// +// This class imposes the following requirements on its +// parameter class: +// +// 1) The class T must implement these operators: +// + - < > <= >= = +// with the signature (T,T) and the expected +// return values for a numeric type. +// +// 2) The class T must implement operator= +// with the signature (T,float and/or double) +// +// 3) The class T must have a constructor which takes +// a float (and/or double) for use in initializing the box. +// +// 4) The class T must have a function T::dimensions() +// which returns the number of dimensions in the class +// (since its assumed its a vector) -- preferably, this +// returns a constant expression. +// +//------------------------------------------------------------------- + +#include "ImathVec.h" + +namespace Imath { + + +template +class Box +{ + public: + + //------------------------- + // Data Members are public + //------------------------- + + T min; + T max; + + //----------------------------------------------------- + // Constructors - an "empty" box is created by default + //----------------------------------------------------- + + Box (); + Box (const T &point); + Box (const T &minT, const T &maxT); + + //-------------------- + // Operators: ==, != + //-------------------- + + bool operator == (const Box &src) const; + bool operator != (const Box &src) const; + + //------------------ + // Box manipulation + //------------------ + + void makeEmpty (); + void extendBy (const T &point); + void extendBy (const Box &box); + void makeInfinite (); + + //--------------------------------------------------- + // Query functions - these compute results each time + //--------------------------------------------------- + + T size () const; + T center () const; + bool intersects (const T &point) const; + bool intersects (const Box &box) const; + + unsigned int majorAxis () const; + + //---------------- + // Classification + //---------------- + + bool isEmpty () const; + bool hasVolume () const; + bool isInfinite () const; +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Box Box2s; +typedef Box Box2i; +typedef Box Box2f; +typedef Box Box2d; +typedef Box Box3s; +typedef Box Box3i; +typedef Box Box3f; +typedef Box Box3d; + + +//---------------- +// Implementation + + +template +inline Box::Box() +{ + makeEmpty(); +} + + +template +inline Box::Box (const T &point) +{ + min = point; + max = point; +} + + +template +inline Box::Box (const T &minT, const T &maxT) +{ + min = minT; + max = maxT; +} + + +template +inline bool +Box::operator == (const Box &src) const +{ + return (min == src.min && max == src.max); +} + + +template +inline bool +Box::operator != (const Box &src) const +{ + return (min != src.min || max != src.max); +} + + +template +inline void Box::makeEmpty() +{ + min = T(T::baseTypeMax()); + max = T(T::baseTypeMin()); +} + +template +inline void Box::makeInfinite() +{ + min = T(T::baseTypeMin()); + max = T(T::baseTypeMax()); +} + + +template +inline void +Box::extendBy(const T &point) +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (point[i] < min[i]) + min[i] = point[i]; + + if (point[i] > max[i]) + max[i] = point[i]; + } +} + + +template +inline void +Box::extendBy(const Box &box) +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (box.min[i] < min[i]) + min[i] = box.min[i]; + + if (box.max[i] > max[i]) + max[i] = box.max[i]; + } +} + + +template +inline bool +Box::intersects(const T &point) const +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (point[i] < min[i] || point[i] > max[i]) + return false; + } + + return true; +} + + +template +inline bool +Box::intersects(const Box &box) const +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (box.max[i] < min[i] || box.min[i] > max[i]) + return false; + } + + return true; +} + + +template +inline T +Box::size() const +{ + if (isEmpty()) + return T (0); + + return max - min; +} + + +template +inline T +Box::center() const +{ + return (max + min) / 2; +} + + +template +inline bool +Box::isEmpty() const +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (max[i] < min[i]) + return true; + } + + return false; +} + +template +inline bool +Box::isInfinite() const +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax()) + return false; + } + + return true; +} + + +template +inline bool +Box::hasVolume() const +{ + for (unsigned int i = 0; i < min.dimensions(); i++) + { + if (max[i] <= min[i]) + return false; + } + + return true; +} + + +template +inline unsigned int +Box::majorAxis() const +{ + unsigned int major = 0; + T s = size(); + + for (unsigned int i = 1; i < min.dimensions(); i++) + { + if (s[i] > s[major]) + major = i; + } + + return major; +} + +//------------------------------------------------------------------- +// +// Partial class specializations for Imath::Vec2 and Imath::Vec3 +// +//------------------------------------------------------------------- + +template class Box; + +template +class Box > +{ + public: + + //------------------------- + // Data Members are public + //------------------------- + + Vec2 min; + Vec2 max; + + //----------------------------------------------------- + // Constructors - an "empty" box is created by default + //----------------------------------------------------- + + Box(); + Box (const Vec2 &point); + Box (const Vec2 &minT, const Vec2 &maxT); + + //-------------------- + // Operators: ==, != + //-------------------- + + bool operator == (const Box > &src) const; + bool operator != (const Box > &src) const; + + //------------------ + // Box manipulation + //------------------ + + void makeEmpty(); + void extendBy (const Vec2 &point); + void extendBy (const Box > &box); + void makeInfinite(); + + //--------------------------------------------------- + // Query functions - these compute results each time + //--------------------------------------------------- + + Vec2 size() const; + Vec2 center() const; + bool intersects (const Vec2 &point) const; + bool intersects (const Box > &box) const; + + unsigned int majorAxis() const; + + //---------------- + // Classification + //---------------- + + bool isEmpty() const; + bool hasVolume() const; + bool isInfinite() const; +}; + + +//---------------- +// Implementation + +template +inline Box >::Box() +{ + makeEmpty(); +} + + +template +inline Box >::Box (const Vec2 &point) +{ + min = point; + max = point; +} + + +template +inline Box >::Box (const Vec2 &minT, const Vec2 &maxT) +{ + min = minT; + max = maxT; +} + + +template +inline bool +Box >::operator == (const Box > &src) const +{ + return (min == src.min && max == src.max); +} + + +template +inline bool +Box >::operator != (const Box > &src) const +{ + return (min != src.min || max != src.max); +} + + +template +inline void Box >::makeEmpty() +{ + min = Vec2(Vec2::baseTypeMax()); + max = Vec2(Vec2::baseTypeMin()); +} + +template +inline void Box >::makeInfinite() +{ + min = Vec2(Vec2::baseTypeMin()); + max = Vec2(Vec2::baseTypeMax()); +} + + +template +inline void +Box >::extendBy (const Vec2 &point) +{ + if (point[0] < min[0]) + min[0] = point[0]; + + if (point[0] > max[0]) + max[0] = point[0]; + + if (point[1] < min[1]) + min[1] = point[1]; + + if (point[1] > max[1]) + max[1] = point[1]; +} + + +template +inline void +Box >::extendBy (const Box > &box) +{ + if (box.min[0] < min[0]) + min[0] = box.min[0]; + + if (box.max[0] > max[0]) + max[0] = box.max[0]; + + if (box.min[1] < min[1]) + min[1] = box.min[1]; + + if (box.max[1] > max[1]) + max[1] = box.max[1]; +} + + +template +inline bool +Box >::intersects (const Vec2 &point) const +{ + if (point[0] < min[0] || point[0] > max[0] || + point[1] < min[1] || point[1] > max[1]) + return false; + + return true; +} + + +template +inline bool +Box >::intersects (const Box > &box) const +{ + if (box.max[0] < min[0] || box.min[0] > max[0] || + box.max[1] < min[1] || box.min[1] > max[1]) + return false; + + return true; +} + + +template +inline Vec2 +Box >::size() const +{ + if (isEmpty()) + return Vec2 (0); + + return max - min; +} + + +template +inline Vec2 +Box >::center() const +{ + return (max + min) / 2; +} + + +template +inline bool +Box >::isEmpty() const +{ + if (max[0] < min[0] || + max[1] < min[1]) + return true; + + return false; +} + +template +inline bool +Box > ::isInfinite() const +{ + if (min[0] != limits::min() || max[0] != limits::max() || + min[1] != limits::min() || max[1] != limits::max()) + return false; + + return true; +} + + +template +inline bool +Box >::hasVolume() const +{ + if (max[0] <= min[0] || + max[1] <= min[1]) + return false; + + return true; +} + + +template +inline unsigned int +Box >::majorAxis() const +{ + unsigned int major = 0; + Vec2 s = size(); + + if (s[1] > s[major]) + major = 1; + + return major; +} + + +template +class Box > +{ + public: + + //------------------------- + // Data Members are public + //------------------------- + + Vec3 min; + Vec3 max; + + //----------------------------------------------------- + // Constructors - an "empty" box is created by default + //----------------------------------------------------- + + Box(); + Box (const Vec3 &point); + Box (const Vec3 &minT, const Vec3 &maxT); + + //-------------------- + // Operators: ==, != + //-------------------- + + bool operator == (const Box > &src) const; + bool operator != (const Box > &src) const; + + //------------------ + // Box manipulation + //------------------ + + void makeEmpty(); + void extendBy (const Vec3 &point); + void extendBy (const Box > &box); + void makeInfinite (); + + //--------------------------------------------------- + // Query functions - these compute results each time + //--------------------------------------------------- + + Vec3 size() const; + Vec3 center() const; + bool intersects (const Vec3 &point) const; + bool intersects (const Box > &box) const; + + unsigned int majorAxis() const; + + //---------------- + // Classification + //---------------- + + bool isEmpty() const; + bool hasVolume() const; + bool isInfinite() const; +}; + + +//---------------- +// Implementation + + +template +inline Box >::Box() +{ + makeEmpty(); +} + + +template +inline Box >::Box (const Vec3 &point) +{ + min = point; + max = point; +} + + +template +inline Box >::Box (const Vec3 &minT, const Vec3 &maxT) +{ + min = minT; + max = maxT; +} + + +template +inline bool +Box >::operator == (const Box > &src) const +{ + return (min == src.min && max == src.max); +} + + +template +inline bool +Box >::operator != (const Box > &src) const +{ + return (min != src.min || max != src.max); +} + + +template +inline void Box >::makeEmpty() +{ + min = Vec3(Vec3::baseTypeMax()); + max = Vec3(Vec3::baseTypeMin()); +} + +template +inline void Box >::makeInfinite() +{ + min = Vec3(Vec3::baseTypeMin()); + max = Vec3(Vec3::baseTypeMax()); +} + + +template +inline void +Box >::extendBy (const Vec3 &point) +{ + if (point[0] < min[0]) + min[0] = point[0]; + + if (point[0] > max[0]) + max[0] = point[0]; + + if (point[1] < min[1]) + min[1] = point[1]; + + if (point[1] > max[1]) + max[1] = point[1]; + + if (point[2] < min[2]) + min[2] = point[2]; + + if (point[2] > max[2]) + max[2] = point[2]; +} + + +template +inline void +Box >::extendBy (const Box > &box) +{ + if (box.min[0] < min[0]) + min[0] = box.min[0]; + + if (box.max[0] > max[0]) + max[0] = box.max[0]; + + if (box.min[1] < min[1]) + min[1] = box.min[1]; + + if (box.max[1] > max[1]) + max[1] = box.max[1]; + + if (box.min[2] < min[2]) + min[2] = box.min[2]; + + if (box.max[2] > max[2]) + max[2] = box.max[2]; +} + + +template +inline bool +Box >::intersects (const Vec3 &point) const +{ + if (point[0] < min[0] || point[0] > max[0] || + point[1] < min[1] || point[1] > max[1] || + point[2] < min[2] || point[2] > max[2]) + return false; + + return true; +} + + +template +inline bool +Box >::intersects (const Box > &box) const +{ + if (box.max[0] < min[0] || box.min[0] > max[0] || + box.max[1] < min[1] || box.min[1] > max[1] || + box.max[2] < min[2] || box.min[2] > max[2]) + return false; + + return true; +} + + +template +inline Vec3 +Box >::size() const +{ + if (isEmpty()) + return Vec3 (0); + + return max - min; +} + + +template +inline Vec3 +Box >::center() const +{ + return (max + min) / 2; +} + + +template +inline bool +Box >::isEmpty() const +{ + if (max[0] < min[0] || + max[1] < min[1] || + max[2] < min[2]) + return true; + + return false; +} + +template +inline bool +Box >::isInfinite() const +{ + if (min[0] != limits::min() || max[0] != limits::max() || + min[1] != limits::min() || max[1] != limits::max() || + min[2] != limits::min() || max[2] != limits::max()) + return false; + + return true; +} + + +template +inline bool +Box >::hasVolume() const +{ + if (max[0] <= min[0] || + max[1] <= min[1] || + max[2] <= min[2]) + return false; + + return true; +} + + +template +inline unsigned int +Box >::majorAxis() const +{ + unsigned int major = 0; + Vec3 s = size(); + + if (s[1] > s[major]) + major = 1; + + if (s[2] > s[major]) + major = 2; + + return major; +} + + + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBoxAlgo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBoxAlgo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBoxAlgo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathBoxAlgo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1015 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002-2010, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHBOXALGO_H +#define INCLUDED_IMATHBOXALGO_H + + +//--------------------------------------------------------------------------- +// +// This file contains algorithms applied to or in conjunction +// with bounding boxes (Imath::Box). These algorithms require +// more headers to compile. The assumption made is that these +// functions are called much less often than the basic box +// functions or these functions require more support classes. +// +// Contains: +// +// T clip(const T& in, const Box& box) +// +// Vec3 closestPointOnBox(const Vec3&, const Box>& ) +// +// Vec3 closestPointInBox(const Vec3&, const Box>& ) +// +// Box< Vec3 > transform(const Box>&, const Matrix44&) +// Box< Vec3 > affineTransform(const Box>&, const Matrix44&) +// +// void transform(const Box>&, const Matrix44&, Box>&) +// void affineTransform(const Box>&, +// const Matrix44&, +// Box>&) +// +// bool findEntryAndExitPoints(const Line &line, +// const Box< Vec3 > &box, +// Vec3 &enterPoint, +// Vec3 &exitPoint) +// +// bool intersects(const Box> &box, +// const Line3 &ray, +// Vec3 intersectionPoint) +// +// bool intersects(const Box> &box, const Line3 &ray) +// +//--------------------------------------------------------------------------- + +#include "ImathBox.h" +#include "ImathMatrix.h" +#include "ImathLineAlgo.h" +#include "ImathPlane.h" + +namespace Imath { + + +template +inline T +clip (const T &p, const Box &box) +{ + // + // Clip the coordinates of a point, p, against a box. + // The result, q, is the closest point to p that is inside the box. + // + + T q; + + for (int i = 0; i < int (box.min.dimensions()); i++) + { + if (p[i] < box.min[i]) + q[i] = box.min[i]; + else if (p[i] > box.max[i]) + q[i] = box.max[i]; + else + q[i] = p[i]; + } + + return q; +} + + +template +inline T +closestPointInBox (const T &p, const Box &box) +{ + return clip (p, box); +} + + +template +Vec3 +closestPointOnBox (const Vec3 &p, const Box< Vec3 > &box) +{ + // + // Find the point, q, on the surface of + // the box, that is closest to point p. + // + // If the box is empty, return p. + // + + if (box.isEmpty()) + return p; + + Vec3 q = closestPointInBox (p, box); + + if (q == p) + { + Vec3 d1 = p - box.min; + Vec3 d2 = box.max - p; + + Vec3 d ((d1.x < d2.x)? d1.x: d2.x, + (d1.y < d2.y)? d1.y: d2.y, + (d1.z < d2.z)? d1.z: d2.z); + + if (d.x < d.y && d.x < d.z) + { + q.x = (d1.x < d2.x)? box.min.x: box.max.x; + } + else if (d.y < d.z) + { + q.y = (d1.y < d2.y)? box.min.y: box.max.y; + } + else + { + q.z = (d1.z < d2.z)? box.min.z: box.max.z; + } + } + + return q; +} + + +template +Box< Vec3 > +transform (const Box< Vec3 > &box, const Matrix44 &m) +{ + // + // Transform a 3D box by a matrix, and compute a new box that + // tightly encloses the transformed box. + // + // If m is an affine transform, then we use James Arvo's fast + // method as described in "Graphics Gems", Academic Press, 1990, + // pp. 548-550. + // + + // + // A transformed empty box is still empty, and a transformed infinite box + // is still infinite + // + + if (box.isEmpty() || box.isInfinite()) + return box; + + // + // If the last column of m is (0 0 0 1) then m is an affine + // transform, and we use the fast Graphics Gems trick. + // + + if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1) + { + Box< Vec3 > newBox; + + for (int i = 0; i < 3; i++) + { + newBox.min[i] = newBox.max[i] = (S) m[3][i]; + + for (int j = 0; j < 3; j++) + { + S a, b; + + a = (S) m[j][i] * box.min[j]; + b = (S) m[j][i] * box.max[j]; + + if (a < b) + { + newBox.min[i] += a; + newBox.max[i] += b; + } + else + { + newBox.min[i] += b; + newBox.max[i] += a; + } + } + } + + return newBox; + } + + // + // M is a projection matrix. Do things the naive way: + // Transform the eight corners of the box, and find an + // axis-parallel box that encloses the transformed corners. + // + + Vec3 points[8]; + + points[0][0] = points[1][0] = points[2][0] = points[3][0] = box.min[0]; + points[4][0] = points[5][0] = points[6][0] = points[7][0] = box.max[0]; + + points[0][1] = points[1][1] = points[4][1] = points[5][1] = box.min[1]; + points[2][1] = points[3][1] = points[6][1] = points[7][1] = box.max[1]; + + points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2]; + points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2]; + + Box< Vec3 > newBox; + + for (int i = 0; i < 8; i++) + newBox.extendBy (points[i] * m); + + return newBox; +} + +template +void +transform (const Box< Vec3 > &box, + const Matrix44 &m, + Box< Vec3 > &result) +{ + // + // Transform a 3D box by a matrix, and compute a new box that + // tightly encloses the transformed box. + // + // If m is an affine transform, then we use James Arvo's fast + // method as described in "Graphics Gems", Academic Press, 1990, + // pp. 548-550. + // + + // + // A transformed empty box is still empty, and a transformed infinite + // box is still infinite + // + + if (box.isEmpty() || box.isInfinite()) + { + return; + } + + // + // If the last column of m is (0 0 0 1) then m is an affine + // transform, and we use the fast Graphics Gems trick. + // + + if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1) + { + for (int i = 0; i < 3; i++) + { + result.min[i] = result.max[i] = (S) m[3][i]; + + for (int j = 0; j < 3; j++) + { + S a, b; + + a = (S) m[j][i] * box.min[j]; + b = (S) m[j][i] * box.max[j]; + + if (a < b) + { + result.min[i] += a; + result.max[i] += b; + } + else + { + result.min[i] += b; + result.max[i] += a; + } + } + } + + return; + } + + // + // M is a projection matrix. Do things the naive way: + // Transform the eight corners of the box, and find an + // axis-parallel box that encloses the transformed corners. + // + + Vec3 points[8]; + + points[0][0] = points[1][0] = points[2][0] = points[3][0] = box.min[0]; + points[4][0] = points[5][0] = points[6][0] = points[7][0] = box.max[0]; + + points[0][1] = points[1][1] = points[4][1] = points[5][1] = box.min[1]; + points[2][1] = points[3][1] = points[6][1] = points[7][1] = box.max[1]; + + points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2]; + points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2]; + + for (int i = 0; i < 8; i++) + result.extendBy (points[i] * m); +} + + +template +Box< Vec3 > +affineTransform (const Box< Vec3 > &box, const Matrix44 &m) +{ + // + // Transform a 3D box by a matrix whose rightmost column + // is (0 0 0 1), and compute a new box that tightly encloses + // the transformed box. + // + // As in the transform() function, above, we use James Arvo's + // fast method. + // + + if (box.isEmpty() || box.isInfinite()) + { + // + // A transformed empty or infinite box is still empty or infinite + // + + return box; + } + + Box< Vec3 > newBox; + + for (int i = 0; i < 3; i++) + { + newBox.min[i] = newBox.max[i] = (S) m[3][i]; + + for (int j = 0; j < 3; j++) + { + S a, b; + + a = (S) m[j][i] * box.min[j]; + b = (S) m[j][i] * box.max[j]; + + if (a < b) + { + newBox.min[i] += a; + newBox.max[i] += b; + } + else + { + newBox.min[i] += b; + newBox.max[i] += a; + } + } + } + + return newBox; +} + +template +void +affineTransform (const Box< Vec3 > &box, + const Matrix44 &m, + Box > &result) +{ + // + // Transform a 3D box by a matrix whose rightmost column + // is (0 0 0 1), and compute a new box that tightly encloses + // the transformed box. + // + // As in the transform() function, above, we use James Arvo's + // fast method. + // + + if (box.isEmpty()) + { + // + // A transformed empty box is still empty + // + result.makeEmpty(); + return; + } + + if (box.isInfinite()) + { + // + // A transformed infinite box is still infinite + // + result.makeInfinite(); + return; + } + + for (int i = 0; i < 3; i++) + { + result.min[i] = result.max[i] = (S) m[3][i]; + + for (int j = 0; j < 3; j++) + { + S a, b; + + a = (S) m[j][i] * box.min[j]; + b = (S) m[j][i] * box.max[j]; + + if (a < b) + { + result.min[i] += a; + result.max[i] += b; + } + else + { + result.min[i] += b; + result.max[i] += a; + } + } + } +} + + +template +bool +findEntryAndExitPoints (const Line3 &r, + const Box > &b, + Vec3 &entry, + Vec3 &exit) +{ + // + // Compute the points where a ray, r, enters and exits a box, b: + // + // findEntryAndExitPoints() returns + // + // - true if the ray starts inside the box or if the + // ray starts outside and intersects the box + // + // - false otherwise (that is, if the ray does not + // intersect the box) + // + // The entry and exit points are + // + // - points on two of the faces of the box when + // findEntryAndExitPoints() returns true + // (The entry end exit points may be on either + // side of the ray's origin) + // + // - undefined when findEntryAndExitPoints() + // returns false + // + + if (b.isEmpty()) + { + // + // No ray intersects an empty box + // + + return false; + } + + // + // The following description assumes that the ray's origin is outside + // the box, but the code below works even if the origin is inside the + // box: + // + // Between one and three "frontfacing" sides of the box are oriented + // towards the ray's origin, and between one and three "backfacing" + // sides are oriented away from the ray's origin. + // We intersect the ray with the planes that contain the sides of the + // box, and compare the distances between the ray's origin and the + // ray-plane intersections. The ray intersects the box if the most + // distant frontfacing intersection is nearer than the nearest + // backfacing intersection. If the ray does intersect the box, then + // the most distant frontfacing ray-plane intersection is the entry + // point and the nearest backfacing ray-plane intersection is the + // exit point. + // + + const T TMAX = limits::max(); + + T tFrontMax = -TMAX; + T tBackMin = TMAX; + + // + // Minimum and maximum X sides. + // + + if (r.dir.x >= 0) + { + T d1 = b.max.x - r.pos.x; + T d2 = b.min.x - r.pos.x; + + if (r.dir.x > 1 || + (abs (d1) < TMAX * r.dir.x && + abs (d2) < TMAX * r.dir.x)) + { + T t1 = d1 / r.dir.x; + T t2 = d2 / r.dir.x; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = b.max.x; + exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y); + exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z); + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = b.min.x; + entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y); + entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z); + } + } + else if (r.pos.x < b.min.x || r.pos.x > b.max.x) + { + return false; + } + } + else // r.dir.x < 0 + { + T d1 = b.min.x - r.pos.x; + T d2 = b.max.x - r.pos.x; + + if (r.dir.x < -1 || + (abs (d1) < -TMAX * r.dir.x && + abs (d2) < -TMAX * r.dir.x)) + { + T t1 = d1 / r.dir.x; + T t2 = d2 / r.dir.x; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = b.min.x; + exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y); + exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z); + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = b.max.x; + entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y); + entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z); + } + } + else if (r.pos.x < b.min.x || r.pos.x > b.max.x) + { + return false; + } + } + + // + // Minimum and maximum Y sides. + // + + if (r.dir.y >= 0) + { + T d1 = b.max.y - r.pos.y; + T d2 = b.min.y - r.pos.y; + + if (r.dir.y > 1 || + (abs (d1) < TMAX * r.dir.y && + abs (d2) < TMAX * r.dir.y)) + { + T t1 = d1 / r.dir.y; + T t2 = d2 / r.dir.y; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x); + exit.y = b.max.y; + exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z); + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x); + entry.y = b.min.y; + entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z); + } + } + else if (r.pos.y < b.min.y || r.pos.y > b.max.y) + { + return false; + } + } + else // r.dir.y < 0 + { + T d1 = b.min.y - r.pos.y; + T d2 = b.max.y - r.pos.y; + + if (r.dir.y < -1 || + (abs (d1) < -TMAX * r.dir.y && + abs (d2) < -TMAX * r.dir.y)) + { + T t1 = d1 / r.dir.y; + T t2 = d2 / r.dir.y; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x); + exit.y = b.min.y; + exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z); + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x); + entry.y = b.max.y; + entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z); + } + } + else if (r.pos.y < b.min.y || r.pos.y > b.max.y) + { + return false; + } + } + + // + // Minimum and maximum Z sides. + // + + if (r.dir.z >= 0) + { + T d1 = b.max.z - r.pos.z; + T d2 = b.min.z - r.pos.z; + + if (r.dir.z > 1 || + (abs (d1) < TMAX * r.dir.z && + abs (d2) < TMAX * r.dir.z)) + { + T t1 = d1 / r.dir.z; + T t2 = d2 / r.dir.z; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x); + exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y); + exit.z = b.max.z; + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x); + entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y); + entry.z = b.min.z; + } + } + else if (r.pos.z < b.min.z || r.pos.z > b.max.z) + { + return false; + } + } + else // r.dir.z < 0 + { + T d1 = b.min.z - r.pos.z; + T d2 = b.max.z - r.pos.z; + + if (r.dir.z < -1 || + (abs (d1) < -TMAX * r.dir.z && + abs (d2) < -TMAX * r.dir.z)) + { + T t1 = d1 / r.dir.z; + T t2 = d2 / r.dir.z; + + if (tBackMin > t1) + { + tBackMin = t1; + + exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x); + exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y); + exit.z = b.min.z; + } + + if (tFrontMax < t2) + { + tFrontMax = t2; + + entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x); + entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y); + entry.z = b.max.z; + } + } + else if (r.pos.z < b.min.z || r.pos.z > b.max.z) + { + return false; + } + } + + return tFrontMax <= tBackMin; +} + + +template +bool +intersects (const Box< Vec3 > &b, const Line3 &r, Vec3 &ip) +{ + // + // Intersect a ray, r, with a box, b, and compute the intersection + // point, ip: + // + // intersect() returns + // + // - true if the ray starts inside the box or if the + // ray starts outside and intersects the box + // + // - false if the ray starts outside the box and intersects it, + // but the intersection is behind the ray's origin. + // + // - false if the ray starts outside and does not intersect it + // + // The intersection point is + // + // - the ray's origin if the ray starts inside the box + // + // - a point on one of the faces of the box if the ray + // starts outside the box + // + // - undefined when intersect() returns false + // + + if (b.isEmpty()) + { + // + // No ray intersects an empty box + // + + return false; + } + + if (b.intersects (r.pos)) + { + // + // The ray starts inside the box + // + + ip = r.pos; + return true; + } + + // + // The ray starts outside the box. Between one and three "frontfacing" + // sides of the box are oriented towards the ray, and between one and + // three "backfacing" sides are oriented away from the ray. + // We intersect the ray with the planes that contain the sides of the + // box, and compare the distances between ray's origin and the ray-plane + // intersections. + // The ray intersects the box if the most distant frontfacing intersection + // is nearer than the nearest backfacing intersection. If the ray does + // intersect the box, then the most distant frontfacing ray-plane + // intersection is the ray-box intersection. + // + + const T TMAX = limits::max(); + + T tFrontMax = -1; + T tBackMin = TMAX; + + // + // Minimum and maximum X sides. + // + + if (r.dir.x > 0) + { + if (r.pos.x > b.max.x) + return false; + + T d = b.max.x - r.pos.x; + + if (r.dir.x > 1 || d < TMAX * r.dir.x) + { + T t = d / r.dir.x; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.x <= b.min.x) + { + T d = b.min.x - r.pos.x; + T t = (r.dir.x > 1 || d < TMAX * r.dir.x)? d / r.dir.x: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = b.min.x; + ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y); + ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z); + } + } + } + else if (r.dir.x < 0) + { + if (r.pos.x < b.min.x) + return false; + + T d = b.min.x - r.pos.x; + + if (r.dir.x < -1 || d > TMAX * r.dir.x) + { + T t = d / r.dir.x; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.x >= b.max.x) + { + T d = b.max.x - r.pos.x; + T t = (r.dir.x < -1 || d > TMAX * r.dir.x)? d / r.dir.x: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = b.max.x; + ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y); + ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z); + } + } + } + else // r.dir.x == 0 + { + if (r.pos.x < b.min.x || r.pos.x > b.max.x) + return false; + } + + // + // Minimum and maximum Y sides. + // + + if (r.dir.y > 0) + { + if (r.pos.y > b.max.y) + return false; + + T d = b.max.y - r.pos.y; + + if (r.dir.y > 1 || d < TMAX * r.dir.y) + { + T t = d / r.dir.y; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.y <= b.min.y) + { + T d = b.min.y - r.pos.y; + T t = (r.dir.y > 1 || d < TMAX * r.dir.y)? d / r.dir.y: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x); + ip.y = b.min.y; + ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z); + } + } + } + else if (r.dir.y < 0) + { + if (r.pos.y < b.min.y) + return false; + + T d = b.min.y - r.pos.y; + + if (r.dir.y < -1 || d > TMAX * r.dir.y) + { + T t = d / r.dir.y; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.y >= b.max.y) + { + T d = b.max.y - r.pos.y; + T t = (r.dir.y < -1 || d > TMAX * r.dir.y)? d / r.dir.y: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x); + ip.y = b.max.y; + ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z); + } + } + } + else // r.dir.y == 0 + { + if (r.pos.y < b.min.y || r.pos.y > b.max.y) + return false; + } + + // + // Minimum and maximum Z sides. + // + + if (r.dir.z > 0) + { + if (r.pos.z > b.max.z) + return false; + + T d = b.max.z - r.pos.z; + + if (r.dir.z > 1 || d < TMAX * r.dir.z) + { + T t = d / r.dir.z; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.z <= b.min.z) + { + T d = b.min.z - r.pos.z; + T t = (r.dir.z > 1 || d < TMAX * r.dir.z)? d / r.dir.z: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x); + ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y); + ip.z = b.min.z; + } + } + } + else if (r.dir.z < 0) + { + if (r.pos.z < b.min.z) + return false; + + T d = b.min.z - r.pos.z; + + if (r.dir.z < -1 || d > TMAX * r.dir.z) + { + T t = d / r.dir.z; + + if (tBackMin > t) + tBackMin = t; + } + + if (r.pos.z >= b.max.z) + { + T d = b.max.z - r.pos.z; + T t = (r.dir.z < -1 || d > TMAX * r.dir.z)? d / r.dir.z: TMAX; + + if (tFrontMax < t) + { + tFrontMax = t; + + ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x); + ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y); + ip.z = b.max.z; + } + } + } + else // r.dir.z == 0 + { + if (r.pos.z < b.min.z || r.pos.z > b.max.z) + return false; + } + + return tFrontMax <= tBackMin; +} + + +template +bool +intersects (const Box< Vec3 > &box, const Line3 &ray) +{ + Vec3 ignored; + return intersects (box, ray, ignored); +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColor.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColor.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColor.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColor.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,734 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHCOLOR_H +#define INCLUDED_IMATHCOLOR_H + +//---------------------------------------------------- +// +// A three and four component color class template. +// +//---------------------------------------------------- + +#include "ImathVec.h" +#include "half.h" + +namespace Imath { + + +template +class Color3: public Vec3 +{ + public: + + //------------- + // Constructors + //------------- + + Color3 (); // no initialization + explicit Color3 (T a); // (a a a) + Color3 (T a, T b, T c); // (a b c) + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Color3 (const Color3 &c); + template Color3 (const Vec3 &v); + + const Color3 & operator = (const Color3 &c); + + + //------------------------ + // Component-wise addition + //------------------------ + + const Color3 & operator += (const Color3 &c); + Color3 operator + (const Color3 &c) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Color3 & operator -= (const Color3 &c); + Color3 operator - (const Color3 &c) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Color3 operator - () const; + const Color3 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Color3 & operator *= (const Color3 &c); + const Color3 & operator *= (T a); + Color3 operator * (const Color3 &c) const; + Color3 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Color3 & operator /= (const Color3 &c); + const Color3 & operator /= (T a); + Color3 operator / (const Color3 &c) const; + Color3 operator / (T a) const; +}; + +template class Color4 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T r, g, b, a; + + T & operator [] (int i); + const T & operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Color4 (); // no initialization + explicit Color4 (T a); // (a a a a) + Color4 (T a, T b, T c, T d); // (a b c d) + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Color4 (const Color4 &v); + template Color4 (const Color4 &v); + + const Color4 & operator = (const Color4 &v); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + template + void setValue (S a, S b, S c, S d); + + template + void setValue (const Color4 &v); + + template + void getValue (S &a, S &b, S &c, S &d) const; + + template + void getValue (Color4 &v) const; + + T * getValue(); + const T * getValue() const; + + + //--------- + // Equality + //--------- + + template + bool operator == (const Color4 &v) const; + + template + bool operator != (const Color4 &v) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Color4 & operator += (const Color4 &v); + Color4 operator + (const Color4 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Color4 & operator -= (const Color4 &v); + Color4 operator - (const Color4 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Color4 operator - () const; + const Color4 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Color4 & operator *= (const Color4 &v); + const Color4 & operator *= (T a); + Color4 operator * (const Color4 &v) const; + Color4 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Color4 & operator /= (const Color4 &v); + const Color4 & operator /= (T a); + Color4 operator / (const Color4 &v) const; + Color4 operator / (T a) const; + + + //---------------------------------------------------------- + // Number of dimensions, i.e. number of elements in a Color4 + //---------------------------------------------------------- + + static unsigned int dimensions() {return 4;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + + //-------------------------------------------------------------- + // Base type -- in templates, which accept a parameter, V, which + // could be a Color4, you can refer to T as + // V::BaseType + //-------------------------------------------------------------- + + typedef T BaseType; +}; + +//-------------- +// Stream output +//-------------- + +template +std::ostream & operator << (std::ostream &s, const Color4 &v); + +//---------------------------------------------------- +// Reverse multiplication: S * Color4 +//---------------------------------------------------- + +template Color4 operator * (S a, const Color4 &v); + +//------------------------- +// Typedefs for convenience +//------------------------- + +typedef Color3 Color3f; +typedef Color3 Color3h; +typedef Color3 Color3c; +typedef Color3 C3h; +typedef Color3 C3f; +typedef Color3 C3c; +typedef Color4 Color4f; +typedef Color4 Color4h; +typedef Color4 Color4c; +typedef Color4 C4f; +typedef Color4 C4h; +typedef Color4 C4c; +typedef unsigned int PackedColor; + + +//------------------------- +// Implementation of Color3 +//------------------------- + +template +inline +Color3::Color3 (): Vec3 () +{ + // empty +} + +template +inline +Color3::Color3 (T a): Vec3 (a) +{ + // empty +} + +template +inline +Color3::Color3 (T a, T b, T c): Vec3 (a, b, c) +{ + // empty +} + +template +inline +Color3::Color3 (const Color3 &c): Vec3 (c) +{ + // empty +} + +template +template +inline +Color3::Color3 (const Vec3 &v): Vec3 (v) +{ + //empty +} + +template +inline const Color3 & +Color3::operator = (const Color3 &c) +{ + *((Vec3 *) this) = c; + return *this; +} + +template +inline const Color3 & +Color3::operator += (const Color3 &c) +{ + *((Vec3 *) this) += c; + return *this; +} + +template +inline Color3 +Color3::operator + (const Color3 &c) const +{ + return Color3 (*(Vec3 *)this + (const Vec3 &)c); +} + +template +inline const Color3 & +Color3::operator -= (const Color3 &c) +{ + *((Vec3 *) this) -= c; + return *this; +} + +template +inline Color3 +Color3::operator - (const Color3 &c) const +{ + return Color3 (*(Vec3 *)this - (const Vec3 &)c); +} + +template +inline Color3 +Color3::operator - () const +{ + return Color3 (-(*(Vec3 *)this)); +} + +template +inline const Color3 & +Color3::negate () +{ + ((Vec3 *) this)->negate(); + return *this; +} + +template +inline const Color3 & +Color3::operator *= (const Color3 &c) +{ + *((Vec3 *) this) *= c; + return *this; +} + +template +inline const Color3 & +Color3::operator *= (T a) +{ + *((Vec3 *) this) *= a; + return *this; +} + +template +inline Color3 +Color3::operator * (const Color3 &c) const +{ + return Color3 (*(Vec3 *)this * (const Vec3 &)c); +} + +template +inline Color3 +Color3::operator * (T a) const +{ + return Color3 (*(Vec3 *)this * a); +} + +template +inline const Color3 & +Color3::operator /= (const Color3 &c) +{ + *((Vec3 *) this) /= c; + return *this; +} + +template +inline const Color3 & +Color3::operator /= (T a) +{ + *((Vec3 *) this) /= a; + return *this; +} + +template +inline Color3 +Color3::operator / (const Color3 &c) const +{ + return Color3 (*(Vec3 *)this / (const Vec3 &)c); +} + +template +inline Color3 +Color3::operator / (T a) const +{ + return Color3 (*(Vec3 *)this / a); +} + +//----------------------- +// Implementation of Color4 +//----------------------- + +template +inline T & +Color4::operator [] (int i) +{ + return (&r)[i]; +} + +template +inline const T & +Color4::operator [] (int i) const +{ + return (&r)[i]; +} + +template +inline +Color4::Color4 () +{ + // empty +} + +template +inline +Color4::Color4 (T x) +{ + r = g = b = a = x; +} + +template +inline +Color4::Color4 (T x, T y, T z, T w) +{ + r = x; + g = y; + b = z; + a = w; +} + +template +inline +Color4::Color4 (const Color4 &v) +{ + r = v.r; + g = v.g; + b = v.b; + a = v.a; +} + +template +template +inline +Color4::Color4 (const Color4 &v) +{ + r = T (v.r); + g = T (v.g); + b = T (v.b); + a = T (v.a); +} + +template +inline const Color4 & +Color4::operator = (const Color4 &v) +{ + r = v.r; + g = v.g; + b = v.b; + a = v.a; + return *this; +} + +template +template +inline void +Color4::setValue (S x, S y, S z, S w) +{ + r = T (x); + g = T (y); + b = T (z); + a = T (w); +} + +template +template +inline void +Color4::setValue (const Color4 &v) +{ + r = T (v.r); + g = T (v.g); + b = T (v.b); + a = T (v.a); +} + +template +template +inline void +Color4::getValue (S &x, S &y, S &z, S &w) const +{ + x = S (r); + y = S (g); + z = S (b); + w = S (a); +} + +template +template +inline void +Color4::getValue (Color4 &v) const +{ + v.r = S (r); + v.g = S (g); + v.b = S (b); + v.a = S (a); +} + +template +inline T * +Color4::getValue() +{ + return (T *) &r; +} + +template +inline const T * +Color4::getValue() const +{ + return (const T *) &r; +} + +template +template +inline bool +Color4::operator == (const Color4 &v) const +{ + return r == v.r && g == v.g && b == v.b && a == v.a; +} + +template +template +inline bool +Color4::operator != (const Color4 &v) const +{ + return r != v.r || g != v.g || b != v.b || a != v.a; +} + +template +inline const Color4 & +Color4::operator += (const Color4 &v) +{ + r += v.r; + g += v.g; + b += v.b; + a += v.a; + return *this; +} + +template +inline Color4 +Color4::operator + (const Color4 &v) const +{ + return Color4 (r + v.r, g + v.g, b + v.b, a + v.a); +} + +template +inline const Color4 & +Color4::operator -= (const Color4 &v) +{ + r -= v.r; + g -= v.g; + b -= v.b; + a -= v.a; + return *this; +} + +template +inline Color4 +Color4::operator - (const Color4 &v) const +{ + return Color4 (r - v.r, g - v.g, b - v.b, a - v.a); +} + +template +inline Color4 +Color4::operator - () const +{ + return Color4 (-r, -g, -b, -a); +} + +template +inline const Color4 & +Color4::negate () +{ + r = -r; + g = -g; + b = -b; + a = -a; + return *this; +} + +template +inline const Color4 & +Color4::operator *= (const Color4 &v) +{ + r *= v.r; + g *= v.g; + b *= v.b; + a *= v.a; + return *this; +} + +template +inline const Color4 & +Color4::operator *= (T x) +{ + r *= x; + g *= x; + b *= x; + a *= x; + return *this; +} + +template +inline Color4 +Color4::operator * (const Color4 &v) const +{ + return Color4 (r * v.r, g * v.g, b * v.b, a * v.a); +} + +template +inline Color4 +Color4::operator * (T x) const +{ + return Color4 (r * x, g * x, b * x, a * x); +} + +template +inline const Color4 & +Color4::operator /= (const Color4 &v) +{ + r /= v.r; + g /= v.g; + b /= v.b; + a /= v.a; + return *this; +} + +template +inline const Color4 & +Color4::operator /= (T x) +{ + r /= x; + g /= x; + b /= x; + a /= x; + return *this; +} + +template +inline Color4 +Color4::operator / (const Color4 &v) const +{ + return Color4 (r / v.r, g / v.g, b / v.b, a / v.a); +} + +template +inline Color4 +Color4::operator / (T x) const +{ + return Color4 (r / x, g / x, b / x, a / x); +} + + +template +std::ostream & +operator << (std::ostream &s, const Color4 &v) +{ + return s << '(' << v.r << ' ' << v.g << ' ' << v.b << ' ' << v.a << ')'; +} + +//----------------------------------------- +// Implementation of reverse multiplication +//----------------------------------------- + +template +inline Color4 +operator * (S x, const Color4 &v) +{ + return Color4 (x * v.r, x * v.g, x * v.b, x * v.a); +} + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,178 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------- +// +// Implementation of non-template items declared in ImathColorAlgo.h +// +//---------------------------------------------------------------------------- + +#include "ImathColorAlgo.h" + +namespace Imath { + + +Vec3 +hsv2rgb_d(const Vec3 &hsv) +{ + double hue = hsv.x; + double sat = hsv.y; + double val = hsv.z; + + double x = 0.0, y = 0.0, z = 0.0; + + if (hue == 1) hue = 0; + else hue *= 6; + + int i = int(Math::floor(hue)); + double f = hue-i; + double p = val*(1-sat); + double q = val*(1-(sat*f)); + double t = val*(1-(sat*(1-f))); + + switch (i) + { + case 0: x = val; y = t; z = p; break; + case 1: x = q; y = val; z = p; break; + case 2: x = p; y = val; z = t; break; + case 3: x = p; y = q; z = val; break; + case 4: x = t; y = p; z = val; break; + case 5: x = val; y = p; z = q; break; + } + + return Vec3(x,y,z); +} + + +Color4 +hsv2rgb_d(const Color4 &hsv) +{ + double hue = hsv.r; + double sat = hsv.g; + double val = hsv.b; + + double r = 0.0, g = 0.0, b = 0.0; + + if (hue == 1) hue = 0; + else hue *= 6; + + int i = int(Math::floor(hue)); + double f = hue-i; + double p = val*(1-sat); + double q = val*(1-(sat*f)); + double t = val*(1-(sat*(1-f))); + + switch (i) + { + case 0: r = val; g = t; b = p; break; + case 1: r = q; g = val; b = p; break; + case 2: r = p; g = val; b = t; break; + case 3: r = p; g = q; b = val; break; + case 4: r = t; g = p; b = val; break; + case 5: r = val; g = p; b = q; break; + } + + return Color4(r,g,b,hsv.a); +} + + + +Vec3 +rgb2hsv_d(const Vec3 &c) +{ + const double &x = c.x; + const double &y = c.y; + const double &z = c.z; + + double max = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z); + double min = (x < y) ? ((x < z) ? x : z) : ((y < z) ? y : z); + double range = max - min; + double val = max; + double sat = 0; + double hue = 0; + + if (max != 0) sat = range/max; + + if (sat != 0) + { + double h; + + if (x == max) h = (y - z) / range; + else if (y == max) h = 2 + (z - x) / range; + else h = 4 + (x - y) / range; + + hue = h/6.; + + if (hue < 0.) + hue += 1.0; + } + return Vec3(hue,sat,val); +} + + +Color4 +rgb2hsv_d(const Color4 &c) +{ + const double &r = c.r; + const double &g = c.g; + const double &b = c.b; + + double max = (r > g) ? ((r > b) ? r : b) : ((g > b) ? g : b); + double min = (r < g) ? ((r < b) ? r : b) : ((g < b) ? g : b); + double range = max - min; + double val = max; + double sat = 0; + double hue = 0; + + if (max != 0) sat = range/max; + + if (sat != 0) + { + double h; + + if (r == max) h = (g - b) / range; + else if (g == max) h = 2 + (b - r) / range; + else h = 4 + (r - g) / range; + + hue = h/6.; + + if (hue < 0.) + hue += 1.0; + } + return Color4(hue,sat,val,c.a); +} + + +} // namespace Imath diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathColorAlgo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,256 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHCOLORALGO_H +#define INCLUDED_IMATHCOLORALGO_H + + +#include "ImathColor.h" +#include "ImathMath.h" +#include "ImathLimits.h" + +namespace Imath { + + +// +// Non-templated helper routines for color conversion. +// These routines eliminate type warnings under g++. +// + +Vec3 hsv2rgb_d(const Vec3 &hsv); + +Color4 hsv2rgb_d(const Color4 &hsv); + + +Vec3 rgb2hsv_d(const Vec3 &rgb); + +Color4 rgb2hsv_d(const Color4 &rgb); + + +// +// Color conversion functions and general color algorithms +// +// hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb() +// see each funtion definition for details. +// + +template +Vec3 +hsv2rgb(const Vec3 &hsv) +{ + if ( limits::isIntegral() ) + { + Vec3 v = Vec3(hsv.x / double(limits::max()), + hsv.y / double(limits::max()), + hsv.z / double(limits::max())); + Vec3 c = hsv2rgb_d(v); + return Vec3((T) (c.x * limits::max()), + (T) (c.y * limits::max()), + (T) (c.z * limits::max())); + } + else + { + Vec3 v = Vec3(hsv.x, hsv.y, hsv.z); + Vec3 c = hsv2rgb_d(v); + return Vec3((T) c.x, (T) c.y, (T) c.z); + } +} + + +template +Color4 +hsv2rgb(const Color4 &hsv) +{ + if ( limits::isIntegral() ) + { + Color4 v = Color4(hsv.r / float(limits::max()), + hsv.g / float(limits::max()), + hsv.b / float(limits::max()), + hsv.a / float(limits::max())); + Color4 c = hsv2rgb_d(v); + return Color4((T) (c.r * limits::max()), + (T) (c.g * limits::max()), + (T) (c.b * limits::max()), + (T) (c.a * limits::max())); + } + else + { + Color4 v = Color4(hsv.r, hsv.g, hsv.b, hsv.a); + Color4 c = hsv2rgb_d(v); + return Color4((T) c.r, (T) c.g, (T) c.b, (T) c.a); + } +} + + +template +Vec3 +rgb2hsv(const Vec3 &rgb) +{ + if ( limits::isIntegral() ) + { + Vec3 v = Vec3(rgb.x / double(limits::max()), + rgb.y / double(limits::max()), + rgb.z / double(limits::max())); + Vec3 c = rgb2hsv_d(v); + return Vec3((T) (c.x * limits::max()), + (T) (c.y * limits::max()), + (T) (c.z * limits::max())); + } + else + { + Vec3 v = Vec3(rgb.x, rgb.y, rgb.z); + Vec3 c = rgb2hsv_d(v); + return Vec3((T) c.x, (T) c.y, (T) c.z); + } +} + + +template +Color4 +rgb2hsv(const Color4 &rgb) +{ + if ( limits::isIntegral() ) + { + Color4 v = Color4(rgb.r / float(limits::max()), + rgb.g / float(limits::max()), + rgb.b / float(limits::max()), + rgb.a / float(limits::max())); + Color4 c = rgb2hsv_d(v); + return Color4((T) (c.r * limits::max()), + (T) (c.g * limits::max()), + (T) (c.b * limits::max()), + (T) (c.a * limits::max())); + } + else + { + Color4 v = Color4(rgb.r, rgb.g, rgb.b, rgb.a); + Color4 c = rgb2hsv_d(v); + return Color4((T) c.r, (T) c.g, (T) c.b, (T) c.a); + } +} + +template +PackedColor +rgb2packed(const Vec3 &c) +{ + if ( limits::isIntegral() ) + { + float x = c.x / float(limits::max()); + float y = c.y / float(limits::max()); + float z = c.z / float(limits::max()); + return rgb2packed( V3f(x,y,z) ); + } + else + { + return ( (PackedColor) (c.x * 255) | + (((PackedColor) (c.y * 255)) << 8) | + (((PackedColor) (c.z * 255)) << 16) | 0xFF000000 ); + } +} + +template +PackedColor +rgb2packed(const Color4 &c) +{ + if ( limits::isIntegral() ) + { + float r = c.r / float(limits::max()); + float g = c.g / float(limits::max()); + float b = c.b / float(limits::max()); + float a = c.a / float(limits::max()); + return rgb2packed( C4f(r,g,b,a) ); + } + else + { + return ( (PackedColor) (c.r * 255) | + (((PackedColor) (c.g * 255)) << 8) | + (((PackedColor) (c.b * 255)) << 16) | + (((PackedColor) (c.a * 255)) << 24)); + } +} + +// +// This guy can't return the result because the template +// parameter would not be in the function signiture. So instead, +// its passed in as an argument. +// + +template +void +packed2rgb(PackedColor packed, Vec3 &out) +{ + if ( limits::isIntegral() ) + { + T f = limits::max() / ((PackedColor)0xFF); + out.x = (packed & 0xFF) * f; + out.y = ((packed & 0xFF00) >> 8) * f; + out.z = ((packed & 0xFF0000) >> 16) * f; + } + else + { + T f = T(1) / T(255); + out.x = (packed & 0xFF) * f; + out.y = ((packed & 0xFF00) >> 8) * f; + out.z = ((packed & 0xFF0000) >> 16) * f; + } +} + +template +void +packed2rgb(PackedColor packed, Color4 &out) +{ + if ( limits::isIntegral() ) + { + T f = limits::max() / ((PackedColor)0xFF); + out.r = (packed & 0xFF) * f; + out.g = ((packed & 0xFF00) >> 8) * f; + out.b = ((packed & 0xFF0000) >> 16) * f; + out.a = ((packed & 0xFF000000) >> 24) * f; + } + else + { + T f = T(1) / T(255); + out.r = (packed & 0xFF) * f; + out.g = ((packed & 0xFF00) >> 8) * f; + out.b = ((packed & 0xFF0000) >> 16) * f; + out.a = ((packed & 0xFF000000) >> 24) * f; + } +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathEuler.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathEuler.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathEuler.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathEuler.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,924 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHEULER_H +#define INCLUDED_IMATHEULER_H + +//---------------------------------------------------------------------- +// +// template class Euler +// +// This class represents euler angle orientations. The class +// inherits from Vec3 to it can be freely cast. The additional +// information is the euler priorities rep. This class is +// essentially a rip off of Ken Shoemake's GemsIV code. It has +// been modified minimally to make it more understandable, but +// hardly enough to make it easy to grok completely. +// +// There are 24 possible combonations of Euler angle +// representations of which 12 are common in CG and you will +// probably only use 6 of these which in this scheme are the +// non-relative-non-repeating types. +// +// The representations can be partitioned according to two +// criteria: +// +// 1) Are the angles measured relative to a set of fixed axis +// or relative to each other (the latter being what happens +// when rotation matrices are multiplied together and is +// almost ubiquitous in the cg community) +// +// 2) Is one of the rotations repeated (ala XYX rotation) +// +// When you construct a given representation from scratch you +// must order the angles according to their priorities. So, the +// easiest is a softimage or aerospace (yaw/pitch/roll) ordering +// of ZYX. +// +// float x_rot = 1; +// float y_rot = 2; +// float z_rot = 3; +// +// Eulerf angles(z_rot, y_rot, x_rot, Eulerf::ZYX); +// -or- +// Eulerf angles( V3f(z_rot,y_rot,z_rot), Eulerf::ZYX ); +// +// If instead, the order was YXZ for instance you would have to +// do this: +// +// float x_rot = 1; +// float y_rot = 2; +// float z_rot = 3; +// +// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); +// -or- +// Eulerf angles( V3f(y_rot,x_rot,z_rot), Eulerf::YXZ ); +// +// Notice how the order you put the angles into the three slots +// should correspond to the enum (YXZ) ordering. The input angle +// vector is called the "ijk" vector -- not an "xyz" vector. The +// ijk vector order is the same as the enum. If you treat the +// Euler<> as a Vec<> (which it inherts from) you will find the +// angles are ordered in the same way, i.e.: +// +// V3f v = angles; +// // v.x == y_rot, v.y == x_rot, v.z == z_rot +// +// If you just want the x, y, and z angles stored in a vector in +// that order, you can do this: +// +// V3f v = angles.toXYZVector() +// // v.x == x_rot, v.y == y_rot, v.z == z_rot +// +// If you want to set the Euler with an XYZVector use the +// optional layout argument: +// +// Eulerf angles(x_rot, y_rot, z_rot, +// Eulerf::YXZ, +// Eulerf::XYZLayout); +// +// This is the same as: +// +// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); +// +// Note that this won't do anything intelligent if you have a +// repeated axis in the euler angles (e.g. XYX) +// +// If you need to use the "relative" versions of these, you will +// need to use the "r" enums. +// +// The units of the rotation angles are assumed to be radians. +// +//---------------------------------------------------------------------- + + +#include "ImathMath.h" +#include "ImathVec.h" +#include "ImathQuat.h" +#include "ImathMatrix.h" +#include "ImathLimits.h" +#include + +namespace Imath { + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// Disable MS VC++ warnings about conversion from double to float +#pragma warning(disable:4244) +#endif + +template +class Euler : public Vec3 +{ + public: + + using Vec3::x; + using Vec3::y; + using Vec3::z; + + enum Order + { + // + // All 24 possible orderings + // + + XYZ = 0x0101, // "usual" orderings + XZY = 0x0001, + YZX = 0x1101, + YXZ = 0x1001, + ZXY = 0x2101, + ZYX = 0x2001, + + XZX = 0x0011, // first axis repeated + XYX = 0x0111, + YXY = 0x1011, + YZY = 0x1111, + ZYZ = 0x2011, + ZXZ = 0x2111, + + XYZr = 0x2000, // relative orderings -- not common + XZYr = 0x2100, + YZXr = 0x1000, + YXZr = 0x1100, + ZXYr = 0x0000, + ZYXr = 0x0100, + + XZXr = 0x2110, // relative first axis repeated + XYXr = 0x2010, + YXYr = 0x1110, + YZYr = 0x1010, + ZYZr = 0x0110, + ZXZr = 0x0010, + // |||| + // VVVV + // Legend: ABCD + // A -> Initial Axis (0==x, 1==y, 2==z) + // B -> Parity Even (1==true) + // C -> Initial Repeated (1==true) + // D -> Frame Static (1==true) + // + + Legal = XYZ | XZY | YZX | YXZ | ZXY | ZYX | + XZX | XYX | YXY | YZY | ZYZ | ZXZ | + XYZr| XZYr| YZXr| YXZr| ZXYr| ZYXr| + XZXr| XYXr| YXYr| YZYr| ZYZr| ZXZr, + + Min = 0x0000, + Max = 0x2111, + Default = XYZ + }; + + enum Axis { X = 0, Y = 1, Z = 2 }; + + enum InputLayout { XYZLayout, IJKLayout }; + + //-------------------------------------------------------------------- + // Constructors -- all default to ZYX non-relative ala softimage + // (where there is no argument to specify it) + // + // The Euler-from-matrix constructors assume that the matrix does + // not include shear or non-uniform scaling, but the constructors + // do not examine the matrix to verify this assumption. If necessary, + // you can adjust the matrix by calling the removeScalingAndShear() + // function, defined in ImathMatrixAlgo.h. + //-------------------------------------------------------------------- + + Euler(); + Euler(const Euler&); + Euler(Order p); + Euler(const Vec3 &v, Order o = Default, InputLayout l = IJKLayout); + Euler(T i, T j, T k, Order o = Default, InputLayout l = IJKLayout); + Euler(const Euler &euler, Order newp); + Euler(const Matrix33 &, Order o = Default); + Euler(const Matrix44 &, Order o = Default); + + //--------------------------------- + // Algebraic functions/ Operators + //--------------------------------- + + const Euler& operator= (const Euler&); + const Euler& operator= (const Vec3&); + + //-------------------------------------------------------- + // Set the euler value + // This does NOT convert the angles, but setXYZVector() + // does reorder the input vector. + //-------------------------------------------------------- + + static bool legal(Order); + + void setXYZVector(const Vec3 &); + + Order order() const; + void setOrder(Order); + + void set(Axis initial, + bool relative, + bool parityEven, + bool firstRepeats); + + //------------------------------------------------------------ + // Conversions, toXYZVector() reorders the angles so that + // the X rotation comes first, followed by the Y and Z + // in cases like XYX ordering, the repeated angle will be + // in the "z" component + // + // The Euler-from-matrix extract() functions assume that the + // matrix does not include shear or non-uniform scaling, but + // the extract() functions do not examine the matrix to verify + // this assumption. If necessary, you can adjust the matrix + // by calling the removeScalingAndShear() function, defined + // in ImathMatrixAlgo.h. + //------------------------------------------------------------ + + void extract(const Matrix33&); + void extract(const Matrix44&); + void extract(const Quat&); + + Matrix33 toMatrix33() const; + Matrix44 toMatrix44() const; + Quat toQuat() const; + Vec3 toXYZVector() const; + + //--------------------------------------------------- + // Use this function to unpack angles from ijk form + //--------------------------------------------------- + + void angleOrder(int &i, int &j, int &k) const; + + //--------------------------------------------------- + // Use this function to determine mapping from xyz to ijk + // - reshuffles the xyz to match the order + //--------------------------------------------------- + + void angleMapping(int &i, int &j, int &k) const; + + //---------------------------------------------------------------------- + // + // Utility methods for getting continuous rotations. None of these + // methods change the orientation given by its inputs (or at least + // that is the intent). + // + // angleMod() converts an angle to its equivalent in [-PI, PI] + // + // simpleXYZRotation() adjusts xyzRot so that its components differ + // from targetXyzRot by no more than +-PI + // + // nearestRotation() adjusts xyzRot so that its components differ + // from targetXyzRot by as little as possible. + // Note that xyz here really means ijk, because + // the order must be provided. + // + // makeNear() adjusts "this" Euler so that its components differ + // from target by as little as possible. This method + // might not make sense for Eulers with different order + // and it probably doesn't work for repeated axis and + // relative orderings (TODO). + // + //----------------------------------------------------------------------- + + static float angleMod (T angle); + static void simpleXYZRotation (Vec3 &xyzRot, + const Vec3 &targetXyzRot); + static void nearestRotation (Vec3 &xyzRot, + const Vec3 &targetXyzRot, + Order order = XYZ); + + void makeNear (const Euler &target); + + bool frameStatic() const { return _frameStatic; } + bool initialRepeated() const { return _initialRepeated; } + bool parityEven() const { return _parityEven; } + Axis initialAxis() const { return _initialAxis; } + + protected: + + bool _frameStatic : 1; // relative or static rotations + bool _initialRepeated : 1; // init axis repeated as last + bool _parityEven : 1; // "parity of axis permutation" +#if defined _WIN32 || defined _WIN64 + Axis _initialAxis ; // First axis of rotation +#else + Axis _initialAxis : 2; // First axis of rotation +#endif +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Euler Eulerf; +typedef Euler Eulerd; + + +//--------------- +// Implementation +//--------------- + +template +inline void + Euler::angleOrder(int &i, int &j, int &k) const +{ + i = _initialAxis; + j = _parityEven ? (i+1)%3 : (i > 0 ? i-1 : 2); + k = _parityEven ? (i > 0 ? i-1 : 2) : (i+1)%3; +} + +template +inline void + Euler::angleMapping(int &i, int &j, int &k) const +{ + int m[3]; + + m[_initialAxis] = 0; + m[(_initialAxis+1) % 3] = _parityEven ? 1 : 2; + m[(_initialAxis+2) % 3] = _parityEven ? 2 : 1; + i = m[0]; + j = m[1]; + k = m[2]; +} + +template +inline void +Euler::setXYZVector(const Vec3 &v) +{ + int i,j,k; + angleMapping(i,j,k); + (*this)[i] = v.x; + (*this)[j] = v.y; + (*this)[k] = v.z; +} + +template +inline Vec3 +Euler::toXYZVector() const +{ + int i,j,k; + angleMapping(i,j,k); + return Vec3((*this)[i],(*this)[j],(*this)[k]); +} + + +template +Euler::Euler() : + Vec3(0,0,0), + _frameStatic(true), + _initialRepeated(false), + _parityEven(true), + _initialAxis(X) +{} + +template +Euler::Euler(typename Euler::Order p) : + Vec3(0,0,0), + _frameStatic(true), + _initialRepeated(false), + _parityEven(true), + _initialAxis(X) +{ + setOrder(p); +} + +template +inline Euler::Euler( const Vec3 &v, + typename Euler::Order p, + typename Euler::InputLayout l ) +{ + setOrder(p); + if ( l == XYZLayout ) setXYZVector(v); + else { x = v.x; y = v.y; z = v.z; } +} + +template +inline Euler::Euler(const Euler &euler) +{ + operator=(euler); +} + +template +inline Euler::Euler(const Euler &euler,Order p) +{ + setOrder(p); + Matrix33 M = euler.toMatrix33(); + extract(M); +} + +template +inline Euler::Euler( T xi, T yi, T zi, + typename Euler::Order p, + typename Euler::InputLayout l) +{ + setOrder(p); + if ( l == XYZLayout ) setXYZVector(Vec3(xi,yi,zi)); + else { x = xi; y = yi; z = zi; } +} + +template +inline Euler::Euler( const Matrix33 &M, typename Euler::Order p ) +{ + setOrder(p); + extract(M); +} + +template +inline Euler::Euler( const Matrix44 &M, typename Euler::Order p ) +{ + setOrder(p); + extract(M); +} + +template +inline void Euler::extract(const Quat &q) +{ + extract(q.toMatrix33()); +} + +template +void Euler::extract(const Matrix33 &M) +{ + int i,j,k; + angleOrder(i,j,k); + + if (_initialRepeated) + { + // + // Extract the first angle, x. + // + + x = Math::atan2 (M[j][i], M[k][i]); + + // + // Remove the x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Vec3 r (0, 0, 0); + r[i] = (_parityEven? -x: x); + + Matrix44 N; + N.rotate (r); + + N = N * Matrix44 (M[0][0], M[0][1], M[0][2], 0, + M[1][0], M[1][1], M[1][2], 0, + M[2][0], M[2][1], M[2][2], 0, + 0, 0, 0, 1); + // + // Extract the other two angles, y and z, from N. + // + + T sy = Math::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]); + y = Math::atan2 (sy, N[i][i]); + z = Math::atan2 (N[j][k], N[j][j]); + } + else + { + // + // Extract the first angle, x. + // + + x = Math::atan2 (M[j][k], M[k][k]); + + // + // Remove the x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Vec3 r (0, 0, 0); + r[i] = (_parityEven? -x: x); + + Matrix44 N; + N.rotate (r); + + N = N * Matrix44 (M[0][0], M[0][1], M[0][2], 0, + M[1][0], M[1][1], M[1][2], 0, + M[2][0], M[2][1], M[2][2], 0, + 0, 0, 0, 1); + // + // Extract the other two angles, y and z, from N. + // + + T cy = Math::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]); + y = Math::atan2 (-N[i][k], cy); + z = Math::atan2 (-N[j][i], N[j][j]); + } + + if (!_parityEven) + *this *= -1; + + if (!_frameStatic) + { + T t = x; + x = z; + z = t; + } +} + +template +void Euler::extract(const Matrix44 &M) +{ + int i,j,k; + angleOrder(i,j,k); + + if (_initialRepeated) + { + // + // Extract the first angle, x. + // + + x = Math::atan2 (M[j][i], M[k][i]); + + // + // Remove the x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Vec3 r (0, 0, 0); + r[i] = (_parityEven? -x: x); + + Matrix44 N; + N.rotate (r); + N = N * M; + + // + // Extract the other two angles, y and z, from N. + // + + T sy = Math::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]); + y = Math::atan2 (sy, N[i][i]); + z = Math::atan2 (N[j][k], N[j][j]); + } + else + { + // + // Extract the first angle, x. + // + + x = Math::atan2 (M[j][k], M[k][k]); + + // + // Remove the x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Vec3 r (0, 0, 0); + r[i] = (_parityEven? -x: x); + + Matrix44 N; + N.rotate (r); + N = N * M; + + // + // Extract the other two angles, y and z, from N. + // + + T cy = Math::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]); + y = Math::atan2 (-N[i][k], cy); + z = Math::atan2 (-N[j][i], N[j][j]); + } + + if (!_parityEven) + *this *= -1; + + if (!_frameStatic) + { + T t = x; + x = z; + z = t; + } +} + +template +Matrix33 Euler::toMatrix33() const +{ + int i,j,k; + angleOrder(i,j,k); + + Vec3 angles; + + if ( _frameStatic ) angles = (*this); + else angles = Vec3(z,y,x); + + if ( !_parityEven ) angles *= -1.0; + + T ci = Math::cos(angles.x); + T cj = Math::cos(angles.y); + T ch = Math::cos(angles.z); + T si = Math::sin(angles.x); + T sj = Math::sin(angles.y); + T sh = Math::sin(angles.z); + + T cc = ci*ch; + T cs = ci*sh; + T sc = si*ch; + T ss = si*sh; + + Matrix33 M; + + if ( _initialRepeated ) + { + M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci; + M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc; + M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss; + } + else + { + M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss; + M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc; + M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci; + } + + return M; +} + +template +Matrix44 Euler::toMatrix44() const +{ + int i,j,k; + angleOrder(i,j,k); + + Vec3 angles; + + if ( _frameStatic ) angles = (*this); + else angles = Vec3(z,y,x); + + if ( !_parityEven ) angles *= -1.0; + + T ci = Math::cos(angles.x); + T cj = Math::cos(angles.y); + T ch = Math::cos(angles.z); + T si = Math::sin(angles.x); + T sj = Math::sin(angles.y); + T sh = Math::sin(angles.z); + + T cc = ci*ch; + T cs = ci*sh; + T sc = si*ch; + T ss = si*sh; + + Matrix44 M; + + if ( _initialRepeated ) + { + M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci; + M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc; + M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss; + } + else + { + M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss; + M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc; + M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci; + } + + return M; +} + +template +Quat Euler::toQuat() const +{ + Vec3 angles; + int i,j,k; + angleOrder(i,j,k); + + if ( _frameStatic ) angles = (*this); + else angles = Vec3(z,y,x); + + if ( !_parityEven ) angles.y = -angles.y; + + T ti = angles.x*0.5; + T tj = angles.y*0.5; + T th = angles.z*0.5; + T ci = Math::cos(ti); + T cj = Math::cos(tj); + T ch = Math::cos(th); + T si = Math::sin(ti); + T sj = Math::sin(tj); + T sh = Math::sin(th); + T cc = ci*ch; + T cs = ci*sh; + T sc = si*ch; + T ss = si*sh; + + T parity = _parityEven ? 1.0 : -1.0; + + Quat q; + Vec3 a; + + if ( _initialRepeated ) + { + a[i] = cj*(cs + sc); + a[j] = sj*(cc + ss) * parity, + a[k] = sj*(cs - sc); + q.r = cj*(cc - ss); + } + else + { + a[i] = cj*sc - sj*cs, + a[j] = (cj*ss + sj*cc) * parity, + a[k] = cj*cs - sj*sc; + q.r = cj*cc + sj*ss; + } + + q.v = a; + + return q; +} + +template +inline bool +Euler::legal(typename Euler::Order order) +{ + return (order & ~Legal) ? false : true; +} + +template +typename Euler::Order +Euler::order() const +{ + int foo = (_initialAxis == Z ? 0x2000 : (_initialAxis == Y ? 0x1000 : 0)); + + if (_parityEven) foo |= 0x0100; + if (_initialRepeated) foo |= 0x0010; + if (_frameStatic) foo++; + + return (Order)foo; +} + +template +inline void Euler::setOrder(typename Euler::Order p) +{ + set( p & 0x2000 ? Z : (p & 0x1000 ? Y : X), // initial axis + !(p & 0x1), // static? + !!(p & 0x100), // permutation even? + !!(p & 0x10)); // initial repeats? +} + +template +void Euler::set(typename Euler::Axis axis, + bool relative, + bool parityEven, + bool firstRepeats) +{ + _initialAxis = axis; + _frameStatic = !relative; + _parityEven = parityEven; + _initialRepeated = firstRepeats; +} + +template +const Euler& Euler::operator= (const Euler &euler) +{ + x = euler.x; + y = euler.y; + z = euler.z; + _initialAxis = euler._initialAxis; + _frameStatic = euler._frameStatic; + _parityEven = euler._parityEven; + _initialRepeated = euler._initialRepeated; + return *this; +} + +template +const Euler& Euler::operator= (const Vec3 &v) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + +template +std::ostream& operator << (std::ostream &o, const Euler &euler) +{ + char a[3] = { 'X', 'Y', 'Z' }; + + const char* r = euler.frameStatic() ? "" : "r"; + int i,j,k; + euler.angleOrder(i,j,k); + + if ( euler.initialRepeated() ) k = i; + + return o << "(" + << euler.x << " " + << euler.y << " " + << euler.z << " " + << a[i] << a[j] << a[k] << r << ")"; +} + +template +float +Euler::angleMod (T angle) +{ + angle = fmod(T (angle), T (2 * M_PI)); + + if (angle < -M_PI) angle += 2 * M_PI; + if (angle > +M_PI) angle -= 2 * M_PI; + + return angle; +} + +template +void +Euler::simpleXYZRotation (Vec3 &xyzRot, const Vec3 &targetXyzRot) +{ + Vec3 d = xyzRot - targetXyzRot; + xyzRot[0] = targetXyzRot[0] + angleMod(d[0]); + xyzRot[1] = targetXyzRot[1] + angleMod(d[1]); + xyzRot[2] = targetXyzRot[2] + angleMod(d[2]); +} + +template +void +Euler::nearestRotation (Vec3 &xyzRot, const Vec3 &targetXyzRot, + Order order) +{ + int i,j,k; + Euler e (0,0,0, order); + e.angleOrder(i,j,k); + + simpleXYZRotation(xyzRot, targetXyzRot); + + Vec3 otherXyzRot; + otherXyzRot[i] = M_PI+xyzRot[i]; + otherXyzRot[j] = M_PI-xyzRot[j]; + otherXyzRot[k] = M_PI+xyzRot[k]; + + simpleXYZRotation(otherXyzRot, targetXyzRot); + + Vec3 d = xyzRot - targetXyzRot; + Vec3 od = otherXyzRot - targetXyzRot; + T dMag = d.dot(d); + T odMag = od.dot(od); + + if (odMag < dMag) + { + xyzRot = otherXyzRot; + } +} + +template +void +Euler::makeNear (const Euler &target) +{ + Vec3 xyzRot = toXYZVector(); + Vec3 targetXyz; + if (order() != target.order()) + { + Euler targetSameOrder = Euler(target, order()); + targetXyz = targetSameOrder.toXYZVector(); + } + else + { + targetXyz = target.toXYZVector(); + } + + nearestRotation(xyzRot, targetXyz, order()); + + setXYZVector(xyzRot); +} + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +#pragma warning(default:4244) +#endif + +} // namespace Imath + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathExc.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathExc.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathExc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathExc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHEXC_H +#define INCLUDED_IMATHEXC_H + + +//----------------------------------------------- +// +// Imath library-specific exceptions +// +//----------------------------------------------- + +#include "IexBaseExc.h" + +namespace Imath { + + +DEFINE_EXC (NullVecExc, ::Iex::MathExc) // Attempt to normalize + // null vector + +DEFINE_EXC (InfPointExc, ::Iex::MathExc) // Attempt to normalize + // a point at infinity + +DEFINE_EXC (NullQuatExc, ::Iex::MathExc) // Attempt to normalize + // null quaternion + +DEFINE_EXC (SingMatrixExc, ::Iex::MathExc) // Attempt to invert + // singular matrix + +DEFINE_EXC (ZeroScaleExc, ::Iex::MathExc) // Attempt to remove zero + // scaling from matrix + +DEFINE_EXC (IntVecNormalizeExc, ::Iex::MathExc) // Attempt to normalize + // a vector of whose elements + // are an integer type + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrame.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrame.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrame.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrame.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,190 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHFRAME_H +#define INCLUDED_IMATHFRAME_H + +namespace Imath { + +template class Vec3; +template class Matrix44; + +// +// These methods compute a set of reference frames, defined by their +// transformation matrix, along a curve. It is designed so that the +// array of points and the array of matrices used to fetch these routines +// don't need to be ordered as the curve. +// +// A typical usage would be : +// +// m[0] = Imath::firstFrame( p[0], p[1], p[2] ); +// for( int i = 1; i < n - 1; i++ ) +// { +// m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] ); +// } +// m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] ); +// +// See Graphics Gems I for the underlying algorithm. +// + +template Matrix44 firstFrame( const Vec3&, // First point + const Vec3&, // Second point + const Vec3& ); // Third point + +template Matrix44 nextFrame( const Matrix44&, // Previous matrix + const Vec3&, // Previous point + const Vec3&, // Current point + Vec3&, // Previous tangent + Vec3& ); // Current tangent + +template Matrix44 lastFrame( const Matrix44&, // Previous matrix + const Vec3&, // Previous point + const Vec3& ); // Last point + +// +// firstFrame - Compute the first reference frame along a curve. +// +// This function returns the transformation matrix to the reference frame +// defined by the three points 'pi', 'pj' and 'pk'. Note that if the two +// vectors and are colinears, an arbitrary twist value will +// be choosen. +// +// Throw 'NullVecExc' if 'pi' and 'pj' are equals. +// + +template Matrix44 firstFrame +( + const Vec3& pi, // First point + const Vec3& pj, // Second point + const Vec3& pk ) // Third point +{ + Vec3 t = pj - pi; t.normalizeExc(); + + Vec3 n = t.cross( pk - pi ); n.normalize(); + if( n.length() == 0.0f ) + { + int i = fabs( t[0] ) < fabs( t[1] ) ? 0 : 1; + if( fabs( t[2] ) < fabs( t[i] )) i = 2; + + Vec3 v( 0.0, 0.0, 0.0 ); v[i] = 1.0; + n = t.cross( v ); n.normalize(); + } + + Vec3 b = t.cross( n ); + + Matrix44 M; + + M[0][0] = t[0]; M[0][1] = t[1]; M[0][2] = t[2]; M[0][3] = 0.0, + M[1][0] = n[0]; M[1][1] = n[1]; M[1][2] = n[2]; M[1][3] = 0.0, + M[2][0] = b[0]; M[2][1] = b[1]; M[2][2] = b[2]; M[2][3] = 0.0, + M[3][0] = pi[0]; M[3][1] = pi[1]; M[3][2] = pi[2]; M[3][3] = 1.0; + + return M; +} + +// +// nextFrame - Compute the next reference frame along a curve. +// +// This function returns the transformation matrix to the next reference +// frame defined by the previously computed transformation matrix and the +// new point and tangent vector along the curve. +// + +template Matrix44 nextFrame +( + const Matrix44& Mi, // Previous matrix + const Vec3& pi, // Previous point + const Vec3& pj, // Current point + Vec3& ti, // Previous tangent vector + Vec3& tj ) // Current tangent vector +{ + Vec3 a(0.0, 0.0, 0.0); // Rotation axis. + T r = 0.0; // Rotation angle. + + if( ti.length() != 0.0 && tj.length() != 0.0 ) + { + ti.normalize(); tj.normalize(); + T dot = ti.dot( tj ); + + // + // This is *really* necessary : + // + + if( dot > 1.0 ) dot = 1.0; + else if( dot < -1.0 ) dot = -1.0; + + r = acosf( dot ); + a = ti.cross( tj ); + } + + if( a.length() != 0.0 && r != 0.0 ) + { + Matrix44 R; R.setAxisAngle( a, r ); + Matrix44 Tj; Tj.translate( pj ); + Matrix44 Ti; Ti.translate( -pi ); + + return Mi * Ti * R * Tj; + } + else + { + Matrix44 Tr; Tr.translate( pj - pi ); + + return Mi * Tr; + } +} + +// +// lastFrame - Compute the last reference frame along a curve. +// +// This function returns the transformation matrix to the last reference +// frame defined by the previously computed transformation matrix and the +// last point along the curve. +// + +template Matrix44 lastFrame +( + const Matrix44& Mi, // Previous matrix + const Vec3& pi, // Previous point + const Vec3& pj ) // Last point +{ + Matrix44 Tr; Tr.translate( pj - pi ); + + return Mi * Tr; +} + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustum.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustum.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustum.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustum.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,739 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHFRUSTUM_H +#define INCLUDED_IMATHFRUSTUM_H + + +#include "ImathVec.h" +#include "ImathPlane.h" +#include "ImathLine.h" +#include "ImathMatrix.h" +#include "ImathLimits.h" +#include "ImathFun.h" +#include "IexMathExc.h" + +namespace Imath { + +// +// template class Frustum +// +// The frustum is always located with the eye point at the +// origin facing down -Z. This makes the Frustum class +// compatable with OpenGL (or anything that assumes a camera +// looks down -Z, hence with a right-handed coordinate system) +// but not with RenderMan which assumes the camera looks down +// +Z. Additional functions are provided for conversion from +// and from various camera coordinate spaces. +// +// nearPlane/farPlane: near/far are keywords used by Microsoft's +// compiler, so we use nearPlane/farPlane instead to avoid +// issues. + + +template +class Frustum +{ + public: + Frustum(); + Frustum(const Frustum &); + Frustum(T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho=false); + Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect); + virtual ~Frustum(); + + //-------------------- + // Assignment operator + //-------------------- + + const Frustum &operator = (const Frustum &); + + //-------------------- + // Operators: ==, != + //-------------------- + + bool operator == (const Frustum &src) const; + bool operator != (const Frustum &src) const; + + //-------------------------------------------------------- + // Set functions change the entire state of the Frustum + //-------------------------------------------------------- + + void set(T nearPlane, T farPlane, + T left, T right, + T top, T bottom, + bool ortho=false); + + void set(T nearPlane, T farPlane, T fovx, T fovy, T aspect); + + //------------------------------------------------------ + // These functions modify an already valid frustum state + //------------------------------------------------------ + + void modifyNearAndFar(T nearPlane, T farPlane); + void setOrthographic(bool); + + //-------------- + // Access + //-------------- + + bool orthographic() const { return _orthographic; } + T nearPlane() const { return _nearPlane; } + T hither() const { return _nearPlane; } + T farPlane() const { return _farPlane; } + T yon() const { return _farPlane; } + T left() const { return _left; } + T right() const { return _right; } + T bottom() const { return _bottom; } + T top() const { return _top; } + + //----------------------------------------------------------------------- + // Sets the planes in p to be the six bounding planes of the frustum, in + // the following order: top, right, bottom, left, near, far. + // Note that the planes have normals that point out of the frustum. + // The version of this routine that takes a matrix applies that matrix + // to transform the frustum before setting the planes. + //----------------------------------------------------------------------- + + void planes(Plane3 p[6]); + void planes(Plane3 p[6], const Matrix44 &M); + + //---------------------- + // Derived Quantities + //---------------------- + + T fovx() const; + T fovy() const; + T aspect() const; + Matrix44 projectionMatrix() const; + bool degenerate() const; + + //----------------------------------------------------------------------- + // Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1 + // and -1 <= bottom <= top <= 1) of this Frustum, and returns a new + // Frustum whose near clipping-plane window is that rectangle in local + // space. + //----------------------------------------------------------------------- + + Frustum window(T left, T right, T top, T bottom) const; + + //---------------------------------------------------------- + // Projection is in screen space / Conversion from Z-Buffer + //---------------------------------------------------------- + + Line3 projectScreenToRay( const Vec2 & ) const; + Vec2 projectPointToScreen( const Vec3 & ) const; + + T ZToDepth(long zval, long min, long max) const; + T normalizedZToDepth(T zval) const; + long DepthToZ(T depth, long zmin, long zmax) const; + + T worldRadius(const Vec3 &p, T radius) const; + T screenRadius(const Vec3 &p, T radius) const; + + + protected: + + Vec2 screenToLocal( const Vec2 & ) const; + Vec2 localToScreen( const Vec2 & ) const; + + protected: + T _nearPlane; + T _farPlane; + T _left; + T _right; + T _top; + T _bottom; + bool _orthographic; +}; + + +template +inline Frustum::Frustum() +{ + set(T (0.1), + T (1000.0), + T (-1.0), + T (1.0), + T (1.0), + T (-1.0), + false); +} + +template +inline Frustum::Frustum(const Frustum &f) +{ + *this = f; +} + +template +inline Frustum::Frustum(T n, T f, T l, T r, T t, T b, bool o) +{ + set(n,f,l,r,t,b,o); +} + +template +inline Frustum::Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect) +{ + set(nearPlane,farPlane,fovx,fovy,aspect); +} + +template +Frustum::~Frustum() +{ +} + +template +const Frustum & +Frustum::operator = (const Frustum &f) +{ + _nearPlane = f._nearPlane; + _farPlane = f._farPlane; + _left = f._left; + _right = f._right; + _top = f._top; + _bottom = f._bottom; + _orthographic = f._orthographic; + + return *this; +} + +template +bool +Frustum::operator == (const Frustum &src) const +{ + return + _nearPlane == src._nearPlane && + _farPlane == src._farPlane && + _left == src._left && + _right == src._right && + _top == src._top && + _bottom == src._bottom && + _orthographic == src._orthographic; +} + +template +inline bool +Frustum::operator != (const Frustum &src) const +{ + return !operator== (src); +} + +template +void Frustum::set(T n, T f, T l, T r, T t, T b, bool o) +{ + _nearPlane = n; + _farPlane = f; + _left = l; + _right = r; + _bottom = b; + _top = t; + _orthographic = o; +} + +template +void Frustum::modifyNearAndFar(T n, T f) +{ + if ( _orthographic ) + { + _nearPlane = n; + } + else + { + Line3 lowerLeft( Vec3(0,0,0), Vec3(_left,_bottom,-_nearPlane) ); + Line3 upperRight( Vec3(0,0,0), Vec3(_right,_top,-_nearPlane) ); + Plane3 nearPlane( Vec3(0,0,-1), n ); + + Vec3 ll,ur; + nearPlane.intersect(lowerLeft,ll); + nearPlane.intersect(upperRight,ur); + + _left = ll.x; + _right = ur.x; + _top = ur.y; + _bottom = ll.y; + _nearPlane = n; + _farPlane = f; + } + + _farPlane = f; +} + +template +void Frustum::setOrthographic(bool ortho) +{ + _orthographic = ortho; +} + +template +void Frustum::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect) +{ + if (fovx != 0 && fovy != 0) + throw Iex::ArgExc ("fovx and fovy cannot both be non-zero."); + + const T two = static_cast(2); + + if (fovx != 0) + { + _right = nearPlane * Math::tan(fovx / two); + _left = -_right; + _top = ((_right - _left) / aspect) / two; + _bottom = -_top; + } + else + { + _top = nearPlane * Math::tan(fovy / two); + _bottom = -_top; + _right = (_top - _bottom) * aspect / two; + _left = -_right; + } + _nearPlane = nearPlane; + _farPlane = farPlane; + _orthographic = false; +} + +template +T Frustum::fovx() const +{ + return Math::atan2(_right,_nearPlane) - Math::atan2(_left,_nearPlane); +} + +template +T Frustum::fovy() const +{ + return Math::atan2(_top,_nearPlane) - Math::atan2(_bottom,_nearPlane); +} + +template +T Frustum::aspect() const +{ + T rightMinusLeft = _right-_left; + T topMinusBottom = _top-_bottom; + + if (abs(topMinusBottom) < 1 && + abs(rightMinusLeft) > limits::max() * abs(topMinusBottom)) + { + throw Iex::DivzeroExc ("Bad viewing frustum: " + "aspect ratio cannot be computed."); + } + + return rightMinusLeft / topMinusBottom; +} + +template +Matrix44 Frustum::projectionMatrix() const +{ + T rightPlusLeft = _right+_left; + T rightMinusLeft = _right-_left; + + T topPlusBottom = _top+_bottom; + T topMinusBottom = _top-_bottom; + + T farPlusNear = _farPlane+_nearPlane; + T farMinusNear = _farPlane-_nearPlane; + + if ((abs(rightMinusLeft) < 1 && + abs(rightPlusLeft) > limits::max() * abs(rightMinusLeft)) || + (abs(topMinusBottom) < 1 && + abs(topPlusBottom) > limits::max() * abs(topMinusBottom)) || + (abs(farMinusNear) < 1 && + abs(farPlusNear) > limits::max() * abs(farMinusNear))) + { + throw Iex::DivzeroExc ("Bad viewing frustum: " + "projection matrix cannot be computed."); + } + + if ( _orthographic ) + { + T tx = -rightPlusLeft / rightMinusLeft; + T ty = -topPlusBottom / topMinusBottom; + T tz = -farPlusNear / farMinusNear; + + if ((abs(rightMinusLeft) < 1 && + 2 > limits::max() * abs(rightMinusLeft)) || + (abs(topMinusBottom) < 1 && + 2 > limits::max() * abs(topMinusBottom)) || + (abs(farMinusNear) < 1 && + 2 > limits::max() * abs(farMinusNear))) + { + throw Iex::DivzeroExc ("Bad viewing frustum: " + "projection matrix cannot be computed."); + } + + T A = 2 / rightMinusLeft; + T B = 2 / topMinusBottom; + T C = -2 / farMinusNear; + + return Matrix44( A, 0, 0, 0, + 0, B, 0, 0, + 0, 0, C, 0, + tx, ty, tz, 1.f ); + } + else + { + T A = rightPlusLeft / rightMinusLeft; + T B = topPlusBottom / topMinusBottom; + T C = -farPlusNear / farMinusNear; + + T farTimesNear = -2 * _farPlane * _nearPlane; + if (abs(farMinusNear) < 1 && + abs(farTimesNear) > limits::max() * abs(farMinusNear)) + { + throw Iex::DivzeroExc ("Bad viewing frustum: " + "projection matrix cannot be computed."); + } + + T D = farTimesNear / farMinusNear; + + T twoTimesNear = 2 * _nearPlane; + + if ((abs(rightMinusLeft) < 1 && + abs(twoTimesNear) > limits::max() * abs(rightMinusLeft)) || + (abs(topMinusBottom) < 1 && + abs(twoTimesNear) > limits::max() * abs(topMinusBottom))) + { + throw Iex::DivzeroExc ("Bad viewing frustum: " + "projection matrix cannot be computed."); + } + + T E = twoTimesNear / rightMinusLeft; + T F = twoTimesNear / topMinusBottom; + + return Matrix44( E, 0, 0, 0, + 0, F, 0, 0, + A, B, C, -1, + 0, 0, D, 0 ); + } +} + +template +bool Frustum::degenerate() const +{ + return (_nearPlane == _farPlane) || + (_left == _right) || + (_top == _bottom); +} + +template +Frustum Frustum::window(T l, T r, T t, T b) const +{ + // move it to 0->1 space + + Vec2 bl = screenToLocal( Vec2(l,b) ); + Vec2 tr = screenToLocal( Vec2(r,t) ); + + return Frustum(_nearPlane, _farPlane, bl.x, tr.x, tr.y, bl.y, _orthographic); +} + + +template +Vec2 Frustum::screenToLocal(const Vec2 &s) const +{ + return Vec2( _left + (_right-_left) * (1.f+s.x) / 2.f, + _bottom + (_top-_bottom) * (1.f+s.y) / 2.f ); +} + +template +Vec2 Frustum::localToScreen(const Vec2 &p) const +{ + T leftPlusRight = _left - T (2) * p.x + _right; + T leftMinusRight = _left-_right; + T bottomPlusTop = _bottom - T (2) * p.y + _top; + T bottomMinusTop = _bottom-_top; + + if ((abs(leftMinusRight) < T (1) && + abs(leftPlusRight) > limits::max() * abs(leftMinusRight)) || + (abs(bottomMinusTop) < T (1) && + abs(bottomPlusTop) > limits::max() * abs(bottomMinusTop))) + { + throw Iex::DivzeroExc + ("Bad viewing frustum: " + "local-to-screen transformation cannot be computed"); + } + + return Vec2( leftPlusRight / leftMinusRight, + bottomPlusTop / bottomMinusTop ); +} + +template +Line3 Frustum::projectScreenToRay(const Vec2 &p) const +{ + Vec2 point = screenToLocal(p); + if (orthographic()) + return Line3( Vec3(point.x,point.y, 0.0), + Vec3(point.x,point.y,-_nearPlane)); + else + return Line3( Vec3(0, 0, 0), Vec3(point.x,point.y,-_nearPlane)); +} + +template +Vec2 Frustum::projectPointToScreen(const Vec3 &point) const +{ + if (orthographic() || point.z == T (0)) + return localToScreen( Vec2( point.x, point.y ) ); + else + return localToScreen( Vec2( point.x * _nearPlane / -point.z, + point.y * _nearPlane / -point.z ) ); +} + +template +T Frustum::ZToDepth(long zval,long zmin,long zmax) const +{ + int zdiff = zmax - zmin; + + if (zdiff == 0) + { + throw Iex::DivzeroExc + ("Bad call to Frustum::ZToDepth: zmax == zmin"); + } + + if ( zval > zmax+1 ) zval -= zdiff; + + T fzval = (T(zval) - T(zmin)) / T(zdiff); + return normalizedZToDepth(fzval); +} + +template +T Frustum::normalizedZToDepth(T zval) const +{ + T Zp = zval * 2.0 - 1; + + if ( _orthographic ) + { + return -(Zp*(_farPlane-_nearPlane) + (_farPlane+_nearPlane))/2; + } + else + { + T farTimesNear = 2 * _farPlane * _nearPlane; + T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane; + + if (abs(farMinusNear) < 1 && + abs(farTimesNear) > limits::max() * abs(farMinusNear)) + { + throw Iex::DivzeroExc + ("Frustum::normalizedZToDepth cannot be computed. The " + "near and far clipping planes of the viewing frustum " + "may be too close to each other"); + } + + return farTimesNear / farMinusNear; + } +} + +template +long Frustum::DepthToZ(T depth,long zmin,long zmax) const +{ + long zdiff = zmax - zmin; + T farMinusNear = _farPlane-_nearPlane; + + if ( _orthographic ) + { + T farPlusNear = 2*depth + _farPlane + _nearPlane; + + if (abs(farMinusNear) < 1 && + abs(farPlusNear) > limits::max() * abs(farMinusNear)) + { + throw Iex::DivzeroExc + ("Bad viewing frustum: near and far clipping planes " + "are too close to each other"); + } + + T Zp = -farPlusNear/farMinusNear; + return long(0.5*(Zp+1)*zdiff) + zmin; + } + else + { + // Perspective + + T farTimesNear = 2*_farPlane*_nearPlane; + if (abs(depth) < 1 && + abs(farTimesNear) > limits::max() * abs(depth)) + { + throw Iex::DivzeroExc + ("Bad call to DepthToZ function: value of `depth' " + "is too small"); + } + + T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane; + if (abs(farMinusNear) < 1 && + abs(farPlusNear) > limits::max() * abs(farMinusNear)) + { + throw Iex::DivzeroExc + ("Bad viewing frustum: near and far clipping planes " + "are too close to each other"); + } + + T Zp = farPlusNear/farMinusNear; + return long(0.5*(Zp+1)*zdiff) + zmin; + } +} + +template +T Frustum::screenRadius(const Vec3 &p, T radius) const +{ + // Derivation: + // Consider X-Z plane. + // X coord of projection of p = xp = p.x * (-_nearPlane / p.z) + // Let q be p + (radius, 0, 0). + // X coord of projection of q = xq = (p.x - radius) * (-_nearPlane / p.z) + // X coord of projection of segment from p to q = r = xp - xq + // = radius * (-_nearPlane / p.z) + // A similar analysis holds in the Y-Z plane. + // So r is the quantity we want to return. + + if (abs(p.z) > 1 || abs(-_nearPlane) < limits::max() * abs(p.z)) + { + return radius * (-_nearPlane / p.z); + } + else + { + throw Iex::DivzeroExc + ("Bad call to Frustum::screenRadius: the magnitude of `p' " + "is too small"); + } + + return radius * (-_nearPlane / p.z); +} + +template +T Frustum::worldRadius(const Vec3 &p, T radius) const +{ + if (abs(-_nearPlane) > 1 || abs(p.z) < limits::max() * abs(-_nearPlane)) + { + return radius * (p.z / -_nearPlane); + } + else + { + throw Iex::DivzeroExc + ("Bad viewing frustum: the near clipping plane is too " + "close to zero"); + } +} + +template +void Frustum::planes(Plane3 p[6]) +{ + // + // Plane order: Top, Right, Bottom, Left, Near, Far. + // Normals point outwards. + // + + if (! _orthographic) + { + Vec3 a( _left, _bottom, -_nearPlane); + Vec3 b( _left, _top, -_nearPlane); + Vec3 c( _right, _top, -_nearPlane); + Vec3 d( _right, _bottom, -_nearPlane); + Vec3 o(0,0,0); + + p[0].set( o, c, b ); + p[1].set( o, d, c ); + p[2].set( o, a, d ); + p[3].set( o, b, a ); + } + else + { + p[0].set( Vec3( 0, 1, 0), _top ); + p[1].set( Vec3( 1, 0, 0), _right ); + p[2].set( Vec3( 0,-1, 0),-_bottom ); + p[3].set( Vec3(-1, 0, 0),-_left ); + } + p[4].set( Vec3(0, 0, 1), -_nearPlane ); + p[5].set( Vec3(0, 0,-1), _farPlane ); +} + + +template +void Frustum::planes(Plane3 p[6], const Matrix44 &M) +{ + // + // Plane order: Top, Right, Bottom, Left, Near, Far. + // Normals point outwards. + // + + Vec3 a = Vec3( _left, _bottom, -_nearPlane) * M; + Vec3 b = Vec3( _left, _top, -_nearPlane) * M; + Vec3 c = Vec3( _right, _top, -_nearPlane) * M; + Vec3 d = Vec3( _right, _bottom, -_nearPlane) * M; + if (! _orthographic) + { + double s = _farPlane / double(_nearPlane); + T farLeft = (T) (s * _left); + T farRight = (T) (s * _right); + T farTop = (T) (s * _top); + T farBottom = (T) (s * _bottom); + Vec3 e = Vec3( farLeft, farBottom, -_farPlane) * M; + Vec3 f = Vec3( farLeft, farTop, -_farPlane) * M; + Vec3 g = Vec3( farRight, farTop, -_farPlane) * M; + Vec3 o = Vec3(0,0,0) * M; + p[0].set( o, c, b ); + p[1].set( o, d, c ); + p[2].set( o, a, d ); + p[3].set( o, b, a ); + p[4].set( a, d, c ); + p[5].set( e, f, g ); + } + else + { + Vec3 e = Vec3( _left, _bottom, -_farPlane) * M; + Vec3 f = Vec3( _left, _top, -_farPlane) * M; + Vec3 g = Vec3( _right, _top, -_farPlane) * M; + Vec3 h = Vec3( _right, _bottom, -_farPlane) * M; + p[0].set( c, g, f ); + p[1].set( d, h, g ); + p[2].set( a, e, h ); + p[3].set( b, f, e ); + p[4].set( a, d, c ); + p[5].set( e, f, g ); + } +} + +typedef Frustum Frustumf; +typedef Frustum Frustumd; + + +} // namespace Imath + + +#if defined _WIN32 || defined _WIN64 + #ifdef _redef_near + #define near + #endif + #ifdef _redef_far + #define far + #endif +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustumTest.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustumTest.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustumTest.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFrustumTest.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,410 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATHFRUSTUMTEST_H +#define INCLUDED_IMATHFRUSTUMTEST_H + +//------------------------------------------------------------------------- +// +// This file contains algorithms applied to or in conjunction with +// Frustum visibility testing (Imath::Frustum). +// +// Methods for frustum-based rejection of primitives are contained here. +// +//------------------------------------------------------------------------- + +#include "ImathFrustum.h" +#include "ImathBox.h" +#include "ImathSphere.h" +#include "ImathMatrix.h" +#include "ImathVec.h" + +namespace Imath { + +///////////////////////////////////////////////////////////////// +// FrustumTest +// +// template class FrustumTest +// +// This is a helper class, designed to accelerate the case +// where many tests are made against the same frustum. +// That's a really common case. +// +// The acceleration is achieved by pre-computing the planes of +// the frustum, along with the ablsolute values of the plane normals. +// + + + +////////////////////////////////////////////////////////////////// +// How to use this +// +// Given that you already have: +// Imath::Frustum myFrustum +// IMath::Matrix44 myCameraWorldMatrix +// +// First, make a frustum test object: +// FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix) +// +// Whenever the camera or frustum changes, call: +// myFrustumTest.setFrustum(myFrustum, myCameraWorldMatrix) +// +// For each object you want to test for visibility, call: +// myFrustumTest.isVisible(myBox) +// myFrustumTest.isVisible(mySphere) +// myFrustumTest.isVisible(myVec3) +// myFrustumTest.completelyContains(myBox) +// myFrustumTest.completelyContains(mySphere) +// + + + + +////////////////////////////////////////////////////////////////// +// Explanation of how it works +// +// +// We store six world-space Frustum planes (nx, ny, nz, offset) +// +// Points: To test a Vec3 for visibility, test it against each plane +// using the normal (v dot n - offset) method. (the result is exact) +// +// BBoxes: To test an axis-aligned bbox, test the center against each plane +// using the normal (v dot n - offset) method, but offset by the +// box extents dot the abs of the plane normal. (the result is NOT +// exact, but will not return false-negatives.) +// +// Spheres: To test a sphere, test the center against each plane +// using the normal (v dot n - offset) method, but offset by the +// sphere's radius. (the result is NOT exact, but will not return +// false-negatives.) +// +// +// SPECIAL NOTE: "Where are the dot products?" +// Actual dot products are currently slow for most SIMD architectures. +// In order to keep this code optimization-ready, the dot products +// are all performed using vector adds and multipies. +// +// In order to do this, the plane equations are stored in "transpose" +// form, with the X components grouped into an X vector, etc. +// + + +template +class FrustumTest +{ +public: + FrustumTest() + { + Frustum frust; + Matrix44 cameraMat; + cameraMat.makeIdentity(); + setFrustum(frust, cameraMat); + } + FrustumTest(Frustum &frustum, const Matrix44 &cameraMat) + { + setFrustum(frustum, cameraMat); + } + + //////////////////////////////////////////////////////////////////// + // setFrustum() + // This updates the frustum test with a new frustum and matrix. + // This should usually be called just once per frame. + void setFrustum(Frustum &frustum, const Matrix44 &cameraMat); + + //////////////////////////////////////////////////////////////////// + // isVisible() + // Check to see if shapes are visible. + bool isVisible(const Sphere3 &sphere) const; + bool isVisible(const Box > &box) const; + bool isVisible(const Vec3 &vec) const; + + //////////////////////////////////////////////////////////////////// + // completelyContains() + // Check to see if shapes are entirely contained. + bool completelyContains(const Sphere3 &sphere) const; + bool completelyContains(const Box > &box) const; + + // These next items are kept primarily for debugging tools. + // It's useful for drawing the culling environment, and also + // for getting an "outside view" of the culling frustum. + Imath::Matrix44 cameraMat() const {return cameraMatrix;} + Imath::Frustum currentFrustum() const {return currFrustum;} + +protected: + // To understand why the planes are stored this way, see + // the SPECIAL NOTE above. + Vec3 planeNormX[2]; // The X compunents from 6 plane equations + Vec3 planeNormY[2]; // The Y compunents from 6 plane equations + Vec3 planeNormZ[2]; // The Z compunents from 6 plane equations + + Vec3 planeOffsetVec[2]; // The distance offsets from 6 plane equations + + // The absolute values are stored to assist with bounding box tests. + Vec3 planeNormAbsX[2]; // The abs(X) compunents from 6 plane equations + Vec3 planeNormAbsY[2]; // The abs(X) compunents from 6 plane equations + Vec3 planeNormAbsZ[2]; // The abs(X) compunents from 6 plane equations + + // These are kept primarily for debugging tools. + Frustum currFrustum; + Matrix44 cameraMatrix; +}; + + +//////////////////////////////////////////////////////////////////// +// setFrustum() +// This should usually only be called once per frame, or however +// often the camera moves. +template +void FrustumTest::setFrustum(Frustum &frustum, + const Matrix44 &cameraMat) +{ + Plane3 frustumPlanes[6]; + frustum.planes(frustumPlanes, cameraMat); + + // Here's where we effectively transpose the plane equations. + // We stuff all six X's into the two planeNormX vectors, etc. + for (int i = 0; i < 2; ++i) + { + int index = i * 3; + + planeNormX[i] = Vec3(frustumPlanes[index + 0].normal.x, + frustumPlanes[index + 1].normal.x, + frustumPlanes[index + 2].normal.x); + planeNormY[i] = Vec3(frustumPlanes[index + 0].normal.y, + frustumPlanes[index + 1].normal.y, + frustumPlanes[index + 2].normal.y); + planeNormZ[i] = Vec3(frustumPlanes[index + 0].normal.z, + frustumPlanes[index + 1].normal.z, + frustumPlanes[index + 2].normal.z); + + planeNormAbsX[i] = Vec3(Imath::abs(planeNormX[i].x), + Imath::abs(planeNormX[i].y), + Imath::abs(planeNormX[i].z)); + planeNormAbsY[i] = Vec3(Imath::abs(planeNormY[i].x), + Imath::abs(planeNormY[i].y), + Imath::abs(planeNormY[i].z)); + planeNormAbsZ[i] = Vec3(Imath::abs(planeNormZ[i].x), + Imath::abs(planeNormZ[i].y), + Imath::abs(planeNormZ[i].z)); + + planeOffsetVec[i] = Vec3(frustumPlanes[index + 0].distance, + frustumPlanes[index + 1].distance, + frustumPlanes[index + 2].distance); + } + currFrustum = frustum; + cameraMatrix = cameraMat; +} + + +//////////////////////////////////////////////////////////////////// +// isVisible(Sphere) +// Returns true if any part of the sphere is inside +// the frustum. +// The result MAY return close false-positives, but not false-negatives. +// +template +bool FrustumTest::isVisible(const Sphere3 &sphere) const +{ + Vec3 center = sphere.center; + Vec3 radiusVec = Vec3(sphere.radius, sphere.radius, sphere.radius); + + // This is a vertical dot-product on three vectors at once. + Vec3 d0 = planeNormX[0] * center.x + + planeNormY[0] * center.y + + planeNormZ[0] * center.z + - radiusVec + - planeOffsetVec[0]; + + if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0) + return false; + + Vec3 d1 = planeNormX[1] * center.x + + planeNormY[1] * center.y + + planeNormZ[1] * center.z + - radiusVec + - planeOffsetVec[1]; + + if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////// +// completelyContains(Sphere) +// Returns true if every part of the sphere is inside +// the frustum. +// The result MAY return close false-negatives, but not false-positives. +// +template +bool FrustumTest::completelyContains(const Sphere3 &sphere) const +{ + Vec3 center = sphere.center; + Vec3 radiusVec = Vec3(sphere.radius, sphere.radius, sphere.radius); + + // This is a vertical dot-product on three vectors at once. + Vec3 d0 = planeNormX[0] * center.x + + planeNormY[0] * center.y + + planeNormZ[0] * center.z + + radiusVec + - planeOffsetVec[0]; + + if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0) + return false; + + Vec3 d1 = planeNormX[1] * center.x + + planeNormY[1] * center.y + + planeNormZ[1] * center.z + + radiusVec + - planeOffsetVec[1]; + + if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////// +// isVisible(Box) +// Returns true if any part of the axis-aligned box +// is inside the frustum. +// The result MAY return close false-positives, but not false-negatives. +// +template +bool FrustumTest::isVisible(const Box > &box) const +{ + Vec3 center = (box.min + box.max) / 2; + Vec3 extent = (box.max - center); + + // This is a vertical dot-product on three vectors at once. + Vec3 d0 = planeNormX[0] * center.x + + planeNormY[0] * center.y + + planeNormZ[0] * center.z + - planeNormAbsX[0] * extent.x + - planeNormAbsY[0] * extent.y + - planeNormAbsZ[0] * extent.z + - planeOffsetVec[0]; + + if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0) + return false; + + Vec3 d1 = planeNormX[1] * center.x + + planeNormY[1] * center.y + + planeNormZ[1] * center.z + - planeNormAbsX[1] * extent.x + - planeNormAbsY[1] * extent.y + - planeNormAbsZ[1] * extent.z + - planeOffsetVec[1]; + + if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////// +// completelyContains(Box) +// Returns true if every part of the axis-aligned box +// is inside the frustum. +// The result MAY return close false-negatives, but not false-positives. +// +template +bool FrustumTest::completelyContains(const Box > &box) const +{ + Vec3 center = (box.min + box.max) / 2; + Vec3 extent = (box.max - center); + + // This is a vertical dot-product on three vectors at once. + Vec3 d0 = planeNormX[0] * center.x + + planeNormY[0] * center.y + + planeNormZ[0] * center.z + + planeNormAbsX[0] * extent.x + + planeNormAbsY[0] * extent.y + + planeNormAbsZ[0] * extent.z + - planeOffsetVec[0]; + + if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0) + return false; + + Vec3 d1 = planeNormX[1] * center.x + + planeNormY[1] * center.y + + planeNormZ[1] * center.z + + planeNormAbsX[1] * extent.x + + planeNormAbsY[1] * extent.y + + planeNormAbsZ[1] * extent.z + - planeOffsetVec[1]; + + if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0) + return false; + + return true; +} + + +//////////////////////////////////////////////////////////////////// +// isVisible(Vec3) +// Returns true if the point is inside the frustum. +// +template +bool FrustumTest::isVisible(const Vec3 &vec) const +{ + // This is a vertical dot-product on three vectors at once. + Vec3 d0 = (planeNormX[0] * vec.x) + + (planeNormY[0] * vec.y) + + (planeNormZ[0] * vec.z) + - planeOffsetVec[0]; + + if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0) + return false; + + Vec3 d1 = (planeNormX[1] * vec.x) + + (planeNormY[1] * vec.y) + + (planeNormZ[1] * vec.z) + - planeOffsetVec[1]; + + if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0) + return false; + + return true; +} + + +typedef FrustumTest FrustumTestf; +typedef FrustumTest FrustumTestd; + +} //namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,181 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#include "ImathFun.h" + +namespace Imath { + + +float +succf (float f) +{ + union {float f; int i;} u; + u.f = f; + + if ((u.i & 0x7f800000) == 0x7f800000) + { + // Nan or infinity; don't change value. + } + else if (u.i == 0x00000000 || u.i == 0x80000000) + { + // Plus or minus zero. + + u.i = 0x00000001; + } + else if (u.i > 0) + { + // Positive float, normalized or denormalized. + // Incrementing the largest positive float + // produces +infinity. + + ++u.i; + } + else + { + // Negative normalized or denormalized float. + + --u.i; + } + + return u.f; +} + + +float +predf (float f) +{ + union {float f; int i;} u; + u.f = f; + + if ((u.i & 0x7f800000) == 0x7f800000) + { + // Nan or infinity; don't change value. + } + else if (u.i == 0x00000000 || u.i == 0x80000000) + { + // Plus or minus zero. + + u.i = 0x80000001; + } + else if (u.i > 0) + { + // Positive float, normalized or denormalized. + + --u.i; + } + else + { + // Negative normalized or denormalized float. + // Decrementing the largest negative float + // produces -infinity. + + ++u.i; + } + + return u.f; +} + + +double +succd (double d) +{ + union {double d; Int64 i;} u; + u.d = d; + + if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) + { + // Nan or infinity; don't change value. + } + else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL) + { + // Plus or minus zero. + + u.i = 0x0000000000000001LL; + } + else if (u.i > 0) + { + // Positive double, normalized or denormalized. + // Incrementing the largest positive double + // produces +infinity. + + ++u.i; + } + else + { + // Negative normalized or denormalized double. + + --u.i; + } + + return u.d; +} + + +double +predd (double d) +{ + union {double d; Int64 i;} u; + u.d = d; + + if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) + { + // Nan or infinity; don't change value. + } + else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL) + { + // Plus or minus zero. + + u.i = 0x8000000000000001LL; + } + else if (u.i > 0) + { + // Positive double, normalized or denormalized. + + --u.i; + } + else + { + // Negative normalized or denormalized double. + // Decrementing the largest negative double + // produces -infinity. + + ++u.i; + } + + return u.d; +} + + +} // namespace Imath diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathFun.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,267 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHFUN_H +#define INCLUDED_IMATHFUN_H + +//----------------------------------------------------------------------------- +// +// Miscellaneous utility functions +// +//----------------------------------------------------------------------------- + +#include "ImathLimits.h" +#include "ImathInt64.h" + +namespace Imath { + +template +inline T +abs (T a) +{ + return (a > T(0)) ? a : -a; +} + + +template +inline int +sign (T a) +{ + return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0); +} + + +template +inline T +lerp (T a, T b, Q t) +{ + return (T) (a * (1 - t) + b * t); +} + + +template +inline T +ulerp (T a, T b, Q t) +{ + return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t)); +} + + +template +inline T +lerpfactor(T m, T a, T b) +{ + // + // Return how far m is between a and b, that is return t such that + // if: + // t = lerpfactor(m, a, b); + // then: + // m = lerp(a, b, t); + // + // If a==b, return 0. + // + + T d = b - a; + T n = m - a; + + if (abs(d) > T(1) || abs(n) < limits::max() * abs(d)) + return n / d; + + return T(0); +} + + +template +inline T +clamp (T a, T l, T h) +{ + return (a < l)? l : ((a > h)? h : a); +} + + +template +inline int +cmp (T a, T b) +{ + return Imath::sign (a - b); +} + + +template +inline int +cmpt (T a, T b, T t) +{ + return (Imath::abs (a - b) <= t)? 0 : cmp (a, b); +} + + +template +inline bool +iszero (T a, T t) +{ + return (Imath::abs (a) <= t) ? 1 : 0; +} + + +template +inline bool +equal (T1 a, T2 b, T3 t) +{ + return Imath::abs (a - b) <= t; +} + +template +inline int +floor (T x) +{ + return (x >= 0)? int (x): -(int (-x) + (-x > int (-x))); +} + + +template +inline int +ceil (T x) +{ + return -floor (-x); +} + +template +inline int +trunc (T x) +{ + return (x >= 0) ? int(x) : -int(-x); +} + + +// +// Integer division and remainder where the +// remainder of x/y has the same sign as x: +// +// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y)) +// mods(x,y) == x - y * divs(x,y) +// + +inline int +divs (int x, int y) +{ + return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): + ((y >= 0)? -(-x / y): (-x / -y)); +} + + +inline int +mods (int x, int y) +{ + return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)): + ((y >= 0)? -(-x % y): -(-x % -y)); +} + + +// +// Integer division and remainder where the +// remainder of x/y is always positive: +// +// divp(x,y) == floor (double(x) / double (y)) +// modp(x,y) == x - y * divp(x,y) +// + +inline int +divp (int x, int y) +{ + return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): + ((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y)); +} + + +inline int +modp (int x, int y) +{ + return x - y * divp (x, y); +} + +//---------------------------------------------------------- +// Successor and predecessor for floating-point numbers: +// +// succf(f) returns float(f+e), where e is the smallest +// positive number such that float(f+e) != f. +// +// predf(f) returns float(f-e), where e is the smallest +// positive number such that float(f-e) != f. +// +// succd(d) returns double(d+e), where e is the smallest +// positive number such that double(d+e) != d. +// +// predd(d) returns double(d-e), where e is the smallest +// positive number such that double(d-e) != d. +// +// Exceptions: If the input value is an infinity or a nan, +// succf(), predf(), succd(), and predd() all +// return the input value without changing it. +// +//---------------------------------------------------------- + +float succf (float f); +float predf (float f); + +double succd (double d); +double predd (double d); + +// +// Return true if the number is not a NaN or Infinity. +// + +inline bool +finitef (float f) +{ + union {float f; int i;} u; + u.f = f; + + return (u.i & 0x7f800000) != 0x7f800000; +} + +inline bool +finited (double d) +{ + union {double d; Int64 i;} u; + u.d = d; + + return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL; +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGL.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGL.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGL.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGL.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,159 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATHGL_H +#define INCLUDED_IMATHGL_H + +#include + +#include "ImathVec.h" +#include "ImathMatrix.h" +#include "IexMathExc.h" +#include "ImathFun.h" + +inline void glVertex ( const Imath::V3f &v ) { glVertex3f(v.x,v.y,v.z); } +inline void glVertex ( const Imath::V2f &v ) { glVertex2f(v.x,v.y); } +inline void glNormal ( const Imath::V3f &n ) { glNormal3f(n.x,n.y,n.z); } +inline void glColor ( const Imath::V3f &c ) { glColor3f(c.x,c.y,c.z); } +inline void glTranslate ( const Imath::V3f &t ) { glTranslatef(t.x,t.y,t.z); } + +inline void glTexCoord( const Imath::V2f &t ) +{ + glTexCoord2f(t.x,t.y); +} + +inline void glDisableTexture() +{ + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + glActiveTexture(GL_TEXTURE0); +} + +namespace { + +const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX) + +inline bool +badFloat (float f) +{ + return !Imath::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX; +} + +} // namespace + +inline void +throwBadMatrix (const Imath::M44f& m) +{ + if (badFloat (m[0][0]) || + badFloat (m[0][1]) || + badFloat (m[0][2]) || + badFloat (m[0][3]) || + badFloat (m[1][0]) || + badFloat (m[1][1]) || + badFloat (m[1][2]) || + badFloat (m[1][3]) || + badFloat (m[2][0]) || + badFloat (m[2][1]) || + badFloat (m[2][2]) || + badFloat (m[2][3]) || + badFloat (m[3][0]) || + badFloat (m[3][1]) || + badFloat (m[3][2]) || + badFloat (m[3][3])) + throw Iex::OverflowExc ("GL matrix overflow"); +} + +inline void +glMultMatrix( const Imath::M44f& m ) +{ + throwBadMatrix (m); + glMultMatrixf( (GLfloat*)m[0] ); +} + +inline void +glMultMatrix( const Imath::M44f* m ) +{ + throwBadMatrix (*m); + glMultMatrixf( (GLfloat*)(*m)[0] ); +} + +inline void +glLoadMatrix( const Imath::M44f& m ) +{ + throwBadMatrix (m); + glLoadMatrixf( (GLfloat*)m[0] ); +} + +inline void +glLoadMatrix( const Imath::M44f* m ) +{ + throwBadMatrix (*m); + glLoadMatrixf( (GLfloat*)(*m)[0] ); +} + + +namespace Imath { + +// +// Class objects that push/pop the GL state. These objects assist with +// proper cleanup of the state when exceptions are thrown. +// + +class GLPushMatrix { + public: + + GLPushMatrix () { glPushMatrix(); } + ~GLPushMatrix() { glPopMatrix(); } +}; + +class GLPushAttrib { + public: + + GLPushAttrib (GLbitfield mask) { glPushAttrib (mask); } + ~GLPushAttrib() { glPopAttrib(); } +}; + +class GLBegin { + public: + + GLBegin (GLenum mode) { glBegin (mode); } + ~GLBegin() { glEnd(); } +}; + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGLU.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGLU.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGLU.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathGLU.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHGLU_H +#define INCLUDED_IMATHGLU_H + +#include +#include + +#include "ImathVec.h" + +inline +void +gluLookAt(const Imath::V3f &pos, const Imath::V3f &interest, const Imath::V3f &up) +{ + gluLookAt(pos.x, pos.y, pos.z, + interest.x, interest.y, interest.z, + up.x, up.y, up.z); +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathHalfLimits.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathHalfLimits.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathHalfLimits.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathHalfLimits.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHHALFLIMITS_H +#define INCLUDED_IMATHHALFLIMITS_H + +//-------------------------------------------------- +// +// Imath-style limits for class half. +// +//-------------------------------------------------- + +#include "ImathLimits.h" +#include "half.h" + +namespace Imath { + + +template <> +struct limits +{ + static float min() {return -HALF_MAX;} + static float max() {return HALF_MAX;} + static float smallest() {return HALF_MIN;} + static float epsilon() {return HALF_EPSILON;} + static bool isIntegral() {return false;} + static bool isSigned() {return true;} +}; + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInt64.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInt64.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInt64.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInt64.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATH_INT64_H +#define INCLUDED_IMATH_INT64_H + +//---------------------------------------------------------------------------- +// +// Int64 -- unsigned 64-bit integers +// +//---------------------------------------------------------------------------- + +#include + +namespace Imath { + + +#if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300 + typedef unsigned __int64 Int64; +#elif ULONG_MAX == 18446744073709551615LU + typedef long unsigned int Int64; +#else + typedef long long unsigned int Int64; +#endif + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInterval.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInterval.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInterval.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathInterval.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,224 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHINTERVAL_H +#define INCLUDED_IMATHINTERVAL_H + + +//------------------------------------------------------------------- +// +// class Imath::Interval +// -------------------------------- +// +// An Interval has a min and a max and some miscellaneous +// functions. It is basically a Box that allows T to be +// a scalar. +// +//------------------------------------------------------------------- + +#include "ImathVec.h" + +namespace Imath { + + +template +class Interval +{ + public: + + //------------------------- + // Data Members are public + //------------------------- + + T min; + T max; + + //----------------------------------------------------- + // Constructors - an "empty" Interval is created by default + //----------------------------------------------------- + + Interval(); + Interval(const T& point); + Interval(const T& minT, const T& maxT); + + //-------------------------------- + // Operators: we get != from STL + //-------------------------------- + + bool operator == (const Interval &src) const; + + //------------------ + // Interval manipulation + //------------------ + + void makeEmpty(); + void extendBy(const T& point); + void extendBy(const Interval& interval); + + //--------------------------------------------------- + // Query functions - these compute results each time + //--------------------------------------------------- + + T size() const; + T center() const; + bool intersects(const T &point) const; + bool intersects(const Interval &interval) const; + + //---------------- + // Classification + //---------------- + + bool hasVolume() const; + bool isEmpty() const; +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + + +typedef Interval Intervalf; +typedef Interval Intervald; +typedef Interval Intervals; +typedef Interval Intervali; + +//---------------- +// Implementation +//---------------- + + +template +inline Interval::Interval() +{ + makeEmpty(); +} + +template +inline Interval::Interval(const T& point) +{ + min = point; + max = point; +} + +template +inline Interval::Interval(const T& minV, const T& maxV) +{ + min = minV; + max = maxV; +} + +template +inline bool +Interval::operator == (const Interval &src) const +{ + return (min == src.min && max == src.max); +} + +template +inline void +Interval::makeEmpty() +{ + min = limits::max(); + max = limits::min(); +} + +template +inline void +Interval::extendBy(const T& point) +{ + if ( point < min ) + min = point; + + if ( point > max ) + max = point; +} + +template +inline void +Interval::extendBy(const Interval& interval) +{ + if ( interval.min < min ) + min = interval.min; + + if ( interval.max > max ) + max = interval.max; +} + +template +inline bool +Interval::intersects(const T& point) const +{ + return point >= min && point <= max; +} + +template +inline bool +Interval::intersects(const Interval& interval) const +{ + return interval.max >= min && interval.min <= max; +} + +template +inline T +Interval::size() const +{ + return max-min; +} + +template +inline T +Interval::center() const +{ + return (max+min)/2; +} + +template +inline bool +Interval::isEmpty() const +{ + return max < min; +} + +template +inline bool Interval::hasVolume() const +{ + return max > min; +} + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLimits.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLimits.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLimits.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLimits.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,267 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHLIMITS_H +#define INCLUDED_IMATHLIMITS_H + +//---------------------------------------------------------------- +// +// Limitations of the basic C++ numerical data types +// +//---------------------------------------------------------------- + +#include +#include + +//------------------------------------------ +// In Windows, min and max are macros. Yay. +//------------------------------------------ + +#if defined _WIN32 || defined _WIN64 + #ifdef min + #undef min + #endif + #ifdef max + #undef max + #endif +#endif + +namespace Imath { + + +//----------------------------------------------------------------- +// +// Template class limits returns information about the limits +// of numerical data type T: +// +// min() largest possible negative value of type T +// +// max() largest possible positive value of type T +// +// smallest() smallest possible positive value of type T +// (for float and double: smallest normalized +// positive value) +// +// epsilon() smallest possible e of type T, for which +// 1 + e != 1 +// +// isIntegral() returns true if T is an integral type +// +// isSigned() returns true if T is signed +// +// Class limits is useful to implement template classes or +// functions which depend on the limits of a numerical type +// which is not known in advance; for example: +// +// template max (T x[], int n) +// { +// T m = limits::min(); +// +// for (int i = 0; i < n; i++) +// if (m < x[i]) +// m = x[i]; +// +// return m; +// } +// +// Class limits has been implemented for the following types: +// +// char, signed char, unsigned char +// short, unsigned short +// int, unsigned int +// long, unsigned long +// float +// double +// long double +// +// Class limits has only static member functions, all of which +// are implemented as inlines. No objects of type limits are +// ever created. +// +//----------------------------------------------------------------- + + +template struct limits +{ + static T min(); + static T max(); + static T smallest(); + static T epsilon(); + static bool isIntegral(); + static bool isSigned(); +}; + + +//--------------- +// Implementation +//--------------- + +template <> +struct limits +{ + static char min() {return CHAR_MIN;} + static char max() {return CHAR_MAX;} + static char smallest() {return 1;} + static char epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return (char) ~0 < 0;} +}; + +template <> +struct limits +{ + static signed char min() {return SCHAR_MIN;} + static signed char max() {return SCHAR_MAX;} + static signed char smallest() {return 1;} + static signed char epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static unsigned char min() {return 0;} + static unsigned char max() {return UCHAR_MAX;} + static unsigned char smallest() {return 1;} + static unsigned char epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return false;} +}; + +template <> +struct limits +{ + static short min() {return SHRT_MIN;} + static short max() {return SHRT_MAX;} + static short smallest() {return 1;} + static short epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static unsigned short min() {return 0;} + static unsigned short max() {return USHRT_MAX;} + static unsigned short smallest() {return 1;} + static unsigned short epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return false;} +}; + +template <> +struct limits +{ + static int min() {return INT_MIN;} + static int max() {return INT_MAX;} + static int smallest() {return 1;} + static int epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static unsigned int min() {return 0;} + static unsigned int max() {return UINT_MAX;} + static unsigned int smallest() {return 1;} + static unsigned int epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return false;} +}; + +template <> +struct limits +{ + static long min() {return LONG_MIN;} + static long max() {return LONG_MAX;} + static long smallest() {return 1;} + static long epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static unsigned long min() {return 0;} + static unsigned long max() {return ULONG_MAX;} + static unsigned long smallest() {return 1;} + static unsigned long epsilon() {return 1;} + static bool isIntegral() {return true;} + static bool isSigned() {return false;} +}; + +template <> +struct limits +{ + static float min() {return -FLT_MAX;} + static float max() {return FLT_MAX;} + static float smallest() {return FLT_MIN;} + static float epsilon() {return FLT_EPSILON;} + static bool isIntegral() {return false;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static double min() {return -DBL_MAX;} + static double max() {return DBL_MAX;} + static double smallest() {return DBL_MIN;} + static double epsilon() {return DBL_EPSILON;} + static bool isIntegral() {return false;} + static bool isSigned() {return true;} +}; + +template <> +struct limits +{ + static long double min() {return -LDBL_MAX;} + static long double max() {return LDBL_MAX;} + static long double smallest() {return LDBL_MIN;} + static long double epsilon() {return LDBL_EPSILON;} + static bool isIntegral() {return false;} + static bool isSigned() {return true;} +}; + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLine.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLine.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLine.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLine.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,184 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHLINE_H +#define INCLUDED_IMATHLINE_H + +//------------------------------------- +// +// A 3D line class template +// +//------------------------------------- + +#include "ImathVec.h" +#include "ImathLimits.h" +#include "ImathMatrix.h" + +namespace Imath { + + +template +class Line3 +{ + public: + + Vec3 pos; + Vec3 dir; + + //------------------------------------------------------------- + // Constructors - default is normalized units along direction + //------------------------------------------------------------- + + Line3() {} + Line3(const Vec3& point1, const Vec3& point2); + + //------------------ + // State Query/Set + //------------------ + + void set(const Vec3& point1, + const Vec3& point2); + + //------- + // F(t) + //------- + + Vec3 operator() (T parameter) const; + + //--------- + // Query + //--------- + + T distanceTo(const Vec3& point) const; + T distanceTo(const Line3& line) const; + Vec3 closestPointTo(const Vec3& point) const; + Vec3 closestPointTo(const Line3& line) const; +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Line3 Line3f; +typedef Line3 Line3d; + + +//--------------- +// Implementation +//--------------- + +template +inline Line3::Line3(const Vec3 &p0, const Vec3 &p1) +{ + set(p0,p1); +} + +template +inline void Line3::set(const Vec3 &p0, const Vec3 &p1) +{ + pos = p0; dir = p1-p0; + dir.normalize(); +} + +template +inline Vec3 Line3::operator()(T parameter) const +{ + return pos + dir * parameter; +} + +template +inline T Line3::distanceTo(const Vec3& point) const +{ + return (closestPointTo(point)-point).length(); +} + +template +inline Vec3 Line3::closestPointTo(const Vec3& point) const +{ + return ((point - pos) ^ dir) * dir + pos; +} + +template +inline T Line3::distanceTo(const Line3& line) const +{ + T d = (dir % line.dir) ^ (line.pos - pos); + return (d >= 0)? d: -d; +} + +template +inline Vec3 +Line3::closestPointTo(const Line3& line) const +{ + // Assumes the lines are normalized + + Vec3 posLpos = pos - line.pos ; + T c = dir ^ posLpos; + T a = line.dir ^ dir; + T f = line.dir ^ posLpos ; + T num = c - a * f; + + T denom = a*a - 1; + + T absDenom = ((denom >= 0)? denom: -denom); + + if (absDenom < 1) + { + T absNum = ((num >= 0)? num: -num); + + if (absNum >= absDenom * limits::max()) + return pos; + } + + return pos + dir * (num / denom); +} + +template +std::ostream& operator<< (std::ostream &o, const Line3 &line) +{ + return o << "(" << line.pos << ", " << line.dir << ")"; +} + +template +inline Line3 operator * (const Line3 &line, const Matrix44 &M) +{ + return Line3( line.pos * M, (line.pos + line.dir) * M ); +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLineAlgo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLineAlgo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLineAlgo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathLineAlgo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,287 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHLINEALGO_H +#define INCLUDED_IMATHLINEALGO_H + +//------------------------------------------------------------------ +// +// This file contains algorithms applied to or in conjunction +// with lines (Imath::Line). These algorithms may require +// more headers to compile. The assumption made is that these +// functions are called much less often than the basic line +// functions or these functions require more support classes +// +// Contains: +// +// bool closestPoints(const Line& line1, +// const Line& line2, +// Vec3& point1, +// Vec3& point2) +// +// bool intersect( const Line3 &line, +// const Vec3 &v0, +// const Vec3 &v1, +// const Vec3 &v2, +// Vec3 &pt, +// Vec3 &barycentric, +// bool &front) +// +// V3f +// closestVertex(const Vec3 &v0, +// const Vec3 &v1, +// const Vec3 &v2, +// const Line3 &l) +// +// V3f +// rotatePoint(const Vec3 p, Line3 l, float angle) +// +//------------------------------------------------------------------ + +#include "ImathLine.h" +#include "ImathVecAlgo.h" +#include "ImathFun.h" + +namespace Imath { + + +template +bool +closestPoints + (const Line3& line1, + const Line3& line2, + Vec3& point1, + Vec3& point2) +{ + // + // Compute point1 and point2 such that point1 is on line1, point2 + // is on line2 and the distance between point1 and point2 is minimal. + // This function returns true if point1 and point2 can be computed, + // or false if line1 and line2 are parallel or nearly parallel. + // This function assumes that line1.dir and line2.dir are normalized. + // + + Vec3 w = line1.pos - line2.pos; + T d1w = line1.dir ^ w; + T d2w = line2.dir ^ w; + T d1d2 = line1.dir ^ line2.dir; + T n1 = d1d2 * d2w - d1w; + T n2 = d2w - d1d2 * d1w; + T d = 1 - d1d2 * d1d2; + T absD = abs (d); + + if ((absD > 1) || + (abs (n1) < limits::max() * absD && + abs (n2) < limits::max() * absD)) + { + point1 = line1 (n1 / d); + point2 = line2 (n2 / d); + return true; + } + else + { + return false; + } +} + + +template +bool +intersect + (const Line3 &line, + const Vec3 &v0, + const Vec3 &v1, + const Vec3 &v2, + Vec3 &pt, + Vec3 &barycentric, + bool &front) +{ + // + // Given a line and a triangle (v0, v1, v2), the intersect() function + // finds the intersection of the line and the plane that contains the + // triangle. + // + // If the intersection point cannot be computed, either because the + // line and the triangle's plane are nearly parallel or because the + // triangle's area is very small, intersect() returns false. + // + // If the intersection point is outside the triangle, intersect + // returns false. + // + // If the intersection point, pt, is inside the triangle, intersect() + // computes a front-facing flag and the barycentric coordinates of + // the intersection point, and returns true. + // + // The front-facing flag is true if the dot product of the triangle's + // normal, (v2-v1)%(v1-v0), and the line's direction is negative. + // + // The barycentric coordinates have the following property: + // + // pt = v0 * barycentric.x + v1 * barycentric.y + v2 * barycentric.z + // + + Vec3 edge0 = v1 - v0; + Vec3 edge1 = v2 - v1; + Vec3 normal = edge1 % edge0; + + T l = normal.length(); + + if (l != 0) + normal /= l; + else + return false; // zero-area triangle + + // + // d is the distance of line.pos from the plane that contains the triangle. + // The intersection point is at line.pos + (d/nd) * line.dir. + // + + T d = normal ^ (v0 - line.pos); + T nd = normal ^ line.dir; + + if (abs (nd) > 1 || abs (d) < limits::max() * abs (nd)) + pt = line (d / nd); + else + return false; // line and plane are nearly parallel + + // + // Compute the barycentric coordinates of the intersection point. + // The intersection is inside the triangle if all three barycentric + // coordinates are between zero and one. + // + + { + Vec3 en = edge0.normalized(); + Vec3 a = pt - v0; + Vec3 b = v2 - v0; + Vec3 c = (a - en * (en ^ a)); + Vec3 d = (b - en * (en ^ b)); + T e = c ^ d; + T f = d ^ d; + + if (e >= 0 && e <= f) + barycentric.z = e / f; + else + return false; // outside + } + + { + Vec3 en = edge1.normalized(); + Vec3 a = pt - v1; + Vec3 b = v0 - v1; + Vec3 c = (a - en * (en ^ a)); + Vec3 d = (b - en * (en ^ b)); + T e = c ^ d; + T f = d ^ d; + + if (e >= 0 && e <= f) + barycentric.x = e / f; + else + return false; // outside + } + + barycentric.y = 1 - barycentric.x - barycentric.z; + + if (barycentric.y < 0) + return false; // outside + + front = ((line.dir ^ normal) < 0); + return true; +} + + +template +Vec3 +closestVertex + (const Vec3 &v0, + const Vec3 &v1, + const Vec3 &v2, + const Line3 &l) +{ + Vec3 nearest = v0; + T neardot = (v0 - l.closestPointTo(v0)).length2(); + + T tmp = (v1 - l.closestPointTo(v1)).length2(); + + if (tmp < neardot) + { + neardot = tmp; + nearest = v1; + } + + tmp = (v2 - l.closestPointTo(v2)).length2(); + if (tmp < neardot) + { + neardot = tmp; + nearest = v2; + } + + return nearest; +} + + +template +Vec3 +rotatePoint (const Vec3 p, Line3 l, T angle) +{ + // + // Rotate the point p around the line l by the given angle. + // + + // + // Form a coordinate frame with . The rotation is the in xy + // plane. + // + + Vec3 q = l.closestPointTo(p); + Vec3 x = p - q; + T radius = x.length(); + + x.normalize(); + Vec3 y = (x % l.dir).normalize(); + + T cosangle = Math::cos(angle); + T sinangle = Math::sin(angle); + + Vec3 r = q + x * radius * cosangle + y * radius * sinangle; + + return r; +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMath.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMath.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMath.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMath.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,208 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHMATH_H +#define INCLUDED_IMATHMATH_H + +//---------------------------------------------------------------------------- +// +// ImathMath.h +// +// This file contains template functions which call the double- +// precision math functions defined in math.h (sin(), sqrt(), +// exp() etc.), with specializations that call the faster +// single-precision versions (sinf(), sqrtf(), expf() etc.) +// when appropriate. +// +// Example: +// +// double x = Math::sqrt (3); // calls ::sqrt(double); +// float y = Math::sqrt (3); // calls ::sqrtf(float); +// +// When would I want to use this? +// +// You may be writing a template which needs to call some function +// defined in math.h, for example to extract a square root, but you +// don't know whether to call the single- or the double-precision +// version of this function (sqrt() or sqrtf()): +// +// template +// T +// glorp (T x) +// { +// return sqrt (x + 1); // should call ::sqrtf(float) +// } // if x is a float, but we +// // don't know if it is +// +// Using the templates in this file, you can make sure that +// the appropriate version of the math function is called: +// +// template +// T +// glorp (T x, T y) +// { +// return Math::sqrt (x + 1); // calls ::sqrtf(float) if x +// } // is a float, ::sqrt(double) +// // otherwise +// +//---------------------------------------------------------------------------- + +#include "ImathPlatform.h" +#include "ImathLimits.h" +#include + +namespace Imath { + + +template +struct Math +{ + static T acos (T x) {return ::acos (double(x));} + static T asin (T x) {return ::asin (double(x));} + static T atan (T x) {return ::atan (double(x));} + static T atan2 (T x, T y) {return ::atan2 (double(x), double(y));} + static T cos (T x) {return ::cos (double(x));} + static T sin (T x) {return ::sin (double(x));} + static T tan (T x) {return ::tan (double(x));} + static T cosh (T x) {return ::cosh (double(x));} + static T sinh (T x) {return ::sinh (double(x));} + static T tanh (T x) {return ::tanh (double(x));} + static T exp (T x) {return ::exp (double(x));} + static T log (T x) {return ::log (double(x));} + static T log10 (T x) {return ::log10 (double(x));} + static T modf (T x, T *iptr) + { + double ival; + T rval( ::modf (double(x),&ival)); + *iptr = ival; + return rval; + } + static T pow (T x, T y) {return ::pow (double(x), double(y));} + static T sqrt (T x) {return ::sqrt (double(x));} + static T ceil (T x) {return ::ceil (double(x));} + static T fabs (T x) {return ::fabs (double(x));} + static T floor (T x) {return ::floor (double(x));} + static T fmod (T x, T y) {return ::fmod (double(x), double(y));} + static T hypot (T x, T y) {return ::hypot (double(x), double(y));} +}; + + +template <> +struct Math +{ + static float acos (float x) {return ::acosf (x);} + static float asin (float x) {return ::asinf (x);} + static float atan (float x) {return ::atanf (x);} + static float atan2 (float x, float y) {return ::atan2f (x, y);} + static float cos (float x) {return ::cosf (x);} + static float sin (float x) {return ::sinf (x);} + static float tan (float x) {return ::tanf (x);} + static float cosh (float x) {return ::coshf (x);} + static float sinh (float x) {return ::sinhf (x);} + static float tanh (float x) {return ::tanhf (x);} + static float exp (float x) {return ::expf (x);} + static float log (float x) {return ::logf (x);} + static float log10 (float x) {return ::log10f (x);} + static float modf (float x, float *y) {return ::modff (x, y);} + static float pow (float x, float y) {return ::powf (x, y);} + static float sqrt (float x) {return ::sqrtf (x);} + static float ceil (float x) {return ::ceilf (x);} + static float fabs (float x) {return ::fabsf (x);} + static float floor (float x) {return ::floorf (x);} + static float fmod (float x, float y) {return ::fmodf (x, y);} +#if !defined(_MSC_VER) + static float hypot (float x, float y) {return ::hypotf (x, y);} +#else + static float hypot (float x, float y) {return ::sqrtf(x*x + y*y);} +#endif +}; + + +//-------------------------------------------------------------------------- +// Don Hatch's version of sin(x)/x, which is accurate for very small x. +// Returns 1 for x == 0. +//-------------------------------------------------------------------------- + +template +inline T +sinx_over_x (T x) +{ + if (x * x < limits::epsilon()) + return T (1); + else + return Math::sin (x) / x; +} + + +//-------------------------------------------------------------------------- +// Compare two numbers and test if they are "approximately equal": +// +// equalWithAbsError (x1, x2, e) +// +// Returns true if x1 is the same as x2 with an absolute error of +// no more than e, +// +// abs (x1 - x2) <= e +// +// equalWithRelError (x1, x2, e) +// +// Returns true if x1 is the same as x2 with an relative error of +// no more than e, +// +// abs (x1 - x2) <= e * x1 +// +//-------------------------------------------------------------------------- + +template +inline bool +equalWithAbsError (T x1, T x2, T e) +{ + return ((x1 > x2)? x1 - x2: x2 - x1) <= e; +} + + +template +inline bool +equalWithRelError (T x1, T x2, T e) +{ + return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1); +} + + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrix.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrix.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrix.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrix.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3442 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHMATRIX_H +#define INCLUDED_IMATHMATRIX_H + +//---------------------------------------------------------------- +// +// 2D (3x3) and 3D (4x4) transformation matrix templates. +// +//---------------------------------------------------------------- + +#include "ImathPlatform.h" +#include "ImathFun.h" +#include "ImathExc.h" +#include "ImathVec.h" +#include "ImathShear.h" + +#include +#include +#include +#include + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// suppress exception specification warnings +#pragma warning(disable:4290) +#endif + + +namespace Imath { + +enum Uninitialized {UNINITIALIZED}; + + +template class Matrix33 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T x[3][3]; + + T * operator [] (int i); + const T * operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Matrix33 (Uninitialized) {} + + Matrix33 (); + // 1 0 0 + // 0 1 0 + // 0 0 1 + + Matrix33 (T a); + // a a a + // a a a + // a a a + + Matrix33 (const T a[3][3]); + // a[0][0] a[0][1] a[0][2] + // a[1][0] a[1][1] a[1][2] + // a[2][0] a[2][1] a[2][2] + + Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i); + + // a b c + // d e f + // g h i + + + //-------------------------------- + // Copy constructor and assignment + //-------------------------------- + + Matrix33 (const Matrix33 &v); + template explicit Matrix33 (const Matrix33 &v); + + const Matrix33 & operator = (const Matrix33 &v); + const Matrix33 & operator = (T a); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + T * getValue (); + const T * getValue () const; + + template + void getValue (Matrix33 &v) const; + template + Matrix33 & setValue (const Matrix33 &v); + + template + Matrix33 & setTheMatrix (const Matrix33 &v); + + + //--------- + // Identity + //--------- + + void makeIdentity(); + + + //--------- + // Equality + //--------- + + bool operator == (const Matrix33 &v) const; + bool operator != (const Matrix33 &v) const; + + //----------------------------------------------------------------------- + // Compare two matrices and test if they are "approximately equal": + // + // equalWithAbsError (m, e) + // + // Returns true if the coefficients of this and m are the same with + // an absolute error of no more than e, i.e., for all i, j + // + // abs (this[i][j] - m[i][j]) <= e + // + // equalWithRelError (m, e) + // + // Returns true if the coefficients of this and m are the same with + // a relative error of no more than e, i.e., for all i, j + // + // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Matrix33 &v, T e) const; + bool equalWithRelError (const Matrix33 &v, T e) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Matrix33 & operator += (const Matrix33 &v); + const Matrix33 & operator += (T a); + Matrix33 operator + (const Matrix33 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Matrix33 & operator -= (const Matrix33 &v); + const Matrix33 & operator -= (T a); + Matrix33 operator - (const Matrix33 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Matrix33 operator - () const; + const Matrix33 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Matrix33 & operator *= (T a); + Matrix33 operator * (T a) const; + + + //----------------------------------- + // Matrix-times-matrix multiplication + //----------------------------------- + + const Matrix33 & operator *= (const Matrix33 &v); + Matrix33 operator * (const Matrix33 &v) const; + + + //----------------------------------------------------------------- + // Vector-times-matrix multiplication; see also the "operator *" + // functions defined below. + // + // m.multVecMatrix(src,dst) implements a homogeneous transformation + // by computing Vec3 (src.x, src.y, 1) * m and dividing by the + // result's third element. + // + // m.multDirMatrix(src,dst) multiplies src by the upper left 2x2 + // submatrix, ignoring the rest of matrix m. + //----------------------------------------------------------------- + + template + void multVecMatrix(const Vec2 &src, Vec2 &dst) const; + + template + void multDirMatrix(const Vec2 &src, Vec2 &dst) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Matrix33 & operator /= (T a); + Matrix33 operator / (T a) const; + + + //------------------ + // Transposed matrix + //------------------ + + const Matrix33 & transpose (); + Matrix33 transposed () const; + + + //------------------------------------------------------------ + // Inverse matrix: If singExc is false, inverting a singular + // matrix produces an identity matrix. If singExc is true, + // inverting a singular matrix throws a SingMatrixExc. + // + // inverse() and invert() invert matrices using determinants; + // gjInverse() and gjInvert() use the Gauss-Jordan method. + // + // inverse() and invert() are significantly faster than + // gjInverse() and gjInvert(), but the results may be slightly + // less accurate. + // + //------------------------------------------------------------ + + const Matrix33 & invert (bool singExc = false) + throw (Iex::MathExc); + + Matrix33 inverse (bool singExc = false) const + throw (Iex::MathExc); + + const Matrix33 & gjInvert (bool singExc = false) + throw (Iex::MathExc); + + Matrix33 gjInverse (bool singExc = false) const + throw (Iex::MathExc); + + + //------------------------------------------------ + // Calculate the matrix minor of the (r,c) element + //------------------------------------------------ + + T minorOf (const int r, const int c) const; + + //--------------------------------------------------- + // Build a minor using the specified rows and columns + //--------------------------------------------------- + + T fastMinor (const int r0, const int r1, + const int c0, const int c1) const; + + //------------ + // Determinant + //------------ + + T determinant() const; + + //----------------------------------------- + // Set matrix to rotation by r (in radians) + //----------------------------------------- + + template + const Matrix33 & setRotation (S r); + + + //----------------------------- + // Rotate the given matrix by r + //----------------------------- + + template + const Matrix33 & rotate (S r); + + + //-------------------------------------------- + // Set matrix to scale by given uniform factor + //-------------------------------------------- + + const Matrix33 & setScale (T s); + + + //------------------------------------ + // Set matrix to scale by given vector + //------------------------------------ + + template + const Matrix33 & setScale (const Vec2 &s); + + + //---------------------- + // Scale the matrix by s + //---------------------- + + template + const Matrix33 & scale (const Vec2 &s); + + + //------------------------------------------ + // Set matrix to translation by given vector + //------------------------------------------ + + template + const Matrix33 & setTranslation (const Vec2 &t); + + + //----------------------------- + // Return translation component + //----------------------------- + + Vec2 translation () const; + + + //-------------------------- + // Translate the matrix by t + //-------------------------- + + template + const Matrix33 & translate (const Vec2 &t); + + + //----------------------------------------------------------- + // Set matrix to shear x for each y coord. by given factor xy + //----------------------------------------------------------- + + template + const Matrix33 & setShear (const S &h); + + + //------------------------------------------------------------- + // Set matrix to shear x for each y coord. by given factor h[0] + // and to shear y for each x coord. by given factor h[1] + //------------------------------------------------------------- + + template + const Matrix33 & setShear (const Vec2 &h); + + + //----------------------------------------------------------- + // Shear the matrix in x for each y coord. by given factor xy + //----------------------------------------------------------- + + template + const Matrix33 & shear (const S &xy); + + + //----------------------------------------------------------- + // Shear the matrix in x for each y coord. by given factor xy + // and shear y for each x coord. by given factor yx + //----------------------------------------------------------- + + template + const Matrix33 & shear (const Vec2 &h); + + + //-------------------------------------------------------- + // Number of the row and column dimensions, since + // Matrix33 is a square matrix. + //-------------------------------------------------------- + + static unsigned int dimensions() {return 3;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + typedef T BaseType; + typedef Vec3 BaseVecType; + + private: + + template + struct isSameType + { + enum {value = 0}; + }; + + template + struct isSameType + { + enum {value = 1}; + }; +}; + + +template class Matrix44 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T x[4][4]; + + T * operator [] (int i); + const T * operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Matrix44 (Uninitialized) {} + + Matrix44 (); + // 1 0 0 0 + // 0 1 0 0 + // 0 0 1 0 + // 0 0 0 1 + + Matrix44 (T a); + // a a a a + // a a a a + // a a a a + // a a a a + + Matrix44 (const T a[4][4]) ; + // a[0][0] a[0][1] a[0][2] a[0][3] + // a[1][0] a[1][1] a[1][2] a[1][3] + // a[2][0] a[2][1] a[2][2] a[2][3] + // a[3][0] a[3][1] a[3][2] a[3][3] + + Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, + T i, T j, T k, T l, T m, T n, T o, T p); + + // a b c d + // e f g h + // i j k l + // m n o p + + Matrix44 (Matrix33 r, Vec3 t); + // r r r 0 + // r r r 0 + // r r r 0 + // t t t 1 + + + //-------------------------------- + // Copy constructor and assignment + //-------------------------------- + + Matrix44 (const Matrix44 &v); + template explicit Matrix44 (const Matrix44 &v); + + const Matrix44 & operator = (const Matrix44 &v); + const Matrix44 & operator = (T a); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + T * getValue (); + const T * getValue () const; + + template + void getValue (Matrix44 &v) const; + template + Matrix44 & setValue (const Matrix44 &v); + + template + Matrix44 & setTheMatrix (const Matrix44 &v); + + //--------- + // Identity + //--------- + + void makeIdentity(); + + + //--------- + // Equality + //--------- + + bool operator == (const Matrix44 &v) const; + bool operator != (const Matrix44 &v) const; + + //----------------------------------------------------------------------- + // Compare two matrices and test if they are "approximately equal": + // + // equalWithAbsError (m, e) + // + // Returns true if the coefficients of this and m are the same with + // an absolute error of no more than e, i.e., for all i, j + // + // abs (this[i][j] - m[i][j]) <= e + // + // equalWithRelError (m, e) + // + // Returns true if the coefficients of this and m are the same with + // a relative error of no more than e, i.e., for all i, j + // + // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Matrix44 &v, T e) const; + bool equalWithRelError (const Matrix44 &v, T e) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Matrix44 & operator += (const Matrix44 &v); + const Matrix44 & operator += (T a); + Matrix44 operator + (const Matrix44 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Matrix44 & operator -= (const Matrix44 &v); + const Matrix44 & operator -= (T a); + Matrix44 operator - (const Matrix44 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Matrix44 operator - () const; + const Matrix44 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Matrix44 & operator *= (T a); + Matrix44 operator * (T a) const; + + + //----------------------------------- + // Matrix-times-matrix multiplication + //----------------------------------- + + const Matrix44 & operator *= (const Matrix44 &v); + Matrix44 operator * (const Matrix44 &v) const; + + static void multiply (const Matrix44 &a, // assumes that + const Matrix44 &b, // &a != &c and + Matrix44 &c); // &b != &c. + + + //----------------------------------------------------------------- + // Vector-times-matrix multiplication; see also the "operator *" + // functions defined below. + // + // m.multVecMatrix(src,dst) implements a homogeneous transformation + // by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by + // the result's third element. + // + // m.multDirMatrix(src,dst) multiplies src by the upper left 3x3 + // submatrix, ignoring the rest of matrix m. + //----------------------------------------------------------------- + + template + void multVecMatrix(const Vec3 &src, Vec3 &dst) const; + + template + void multDirMatrix(const Vec3 &src, Vec3 &dst) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Matrix44 & operator /= (T a); + Matrix44 operator / (T a) const; + + + //------------------ + // Transposed matrix + //------------------ + + const Matrix44 & transpose (); + Matrix44 transposed () const; + + + //------------------------------------------------------------ + // Inverse matrix: If singExc is false, inverting a singular + // matrix produces an identity matrix. If singExc is true, + // inverting a singular matrix throws a SingMatrixExc. + // + // inverse() and invert() invert matrices using determinants; + // gjInverse() and gjInvert() use the Gauss-Jordan method. + // + // inverse() and invert() are significantly faster than + // gjInverse() and gjInvert(), but the results may be slightly + // less accurate. + // + //------------------------------------------------------------ + + const Matrix44 & invert (bool singExc = false) + throw (Iex::MathExc); + + Matrix44 inverse (bool singExc = false) const + throw (Iex::MathExc); + + const Matrix44 & gjInvert (bool singExc = false) + throw (Iex::MathExc); + + Matrix44 gjInverse (bool singExc = false) const + throw (Iex::MathExc); + + + //------------------------------------------------ + // Calculate the matrix minor of the (r,c) element + //------------------------------------------------ + + T minorOf (const int r, const int c) const; + + //--------------------------------------------------- + // Build a minor using the specified rows and columns + //--------------------------------------------------- + + T fastMinor (const int r0, const int r1, const int r2, + const int c0, const int c1, const int c2) const; + + //------------ + // Determinant + //------------ + + T determinant() const; + + //-------------------------------------------------------- + // Set matrix to rotation by XYZ euler angles (in radians) + //-------------------------------------------------------- + + template + const Matrix44 & setEulerAngles (const Vec3& r); + + + //-------------------------------------------------------- + // Set matrix to rotation around given axis by given angle + //-------------------------------------------------------- + + template + const Matrix44 & setAxisAngle (const Vec3& ax, S ang); + + + //------------------------------------------- + // Rotate the matrix by XYZ euler angles in r + //------------------------------------------- + + template + const Matrix44 & rotate (const Vec3 &r); + + + //-------------------------------------------- + // Set matrix to scale by given uniform factor + //-------------------------------------------- + + const Matrix44 & setScale (T s); + + + //------------------------------------ + // Set matrix to scale by given vector + //------------------------------------ + + template + const Matrix44 & setScale (const Vec3 &s); + + + //---------------------- + // Scale the matrix by s + //---------------------- + + template + const Matrix44 & scale (const Vec3 &s); + + + //------------------------------------------ + // Set matrix to translation by given vector + //------------------------------------------ + + template + const Matrix44 & setTranslation (const Vec3 &t); + + + //----------------------------- + // Return translation component + //----------------------------- + + const Vec3 translation () const; + + + //-------------------------- + // Translate the matrix by t + //-------------------------- + + template + const Matrix44 & translate (const Vec3 &t); + + + //------------------------------------------------------------- + // Set matrix to shear by given vector h. The resulting matrix + // will shear x for each y coord. by a factor of h[0] ; + // will shear x for each z coord. by a factor of h[1] ; + // will shear y for each z coord. by a factor of h[2] . + //------------------------------------------------------------- + + template + const Matrix44 & setShear (const Vec3 &h); + + + //------------------------------------------------------------ + // Set matrix to shear by given factors. The resulting matrix + // will shear x for each y coord. by a factor of h.xy ; + // will shear x for each z coord. by a factor of h.xz ; + // will shear y for each z coord. by a factor of h.yz ; + // will shear y for each x coord. by a factor of h.yx ; + // will shear z for each x coord. by a factor of h.zx ; + // will shear z for each y coord. by a factor of h.zy . + //------------------------------------------------------------ + + template + const Matrix44 & setShear (const Shear6 &h); + + + //-------------------------------------------------------- + // Shear the matrix by given vector. The composed matrix + // will be * , where the shear matrix ... + // will shear x for each y coord. by a factor of h[0] ; + // will shear x for each z coord. by a factor of h[1] ; + // will shear y for each z coord. by a factor of h[2] . + //-------------------------------------------------------- + + template + const Matrix44 & shear (const Vec3 &h); + + //-------------------------------------------------------- + // Number of the row and column dimensions, since + // Matrix44 is a square matrix. + //-------------------------------------------------------- + + static unsigned int dimensions() {return 4;} + + + //------------------------------------------------------------ + // Shear the matrix by the given factors. The composed matrix + // will be * , where the shear matrix ... + // will shear x for each y coord. by a factor of h.xy ; + // will shear x for each z coord. by a factor of h.xz ; + // will shear y for each z coord. by a factor of h.yz ; + // will shear y for each x coord. by a factor of h.yx ; + // will shear z for each x coord. by a factor of h.zx ; + // will shear z for each y coord. by a factor of h.zy . + //------------------------------------------------------------ + + template + const Matrix44 & shear (const Shear6 &h); + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + typedef T BaseType; + typedef Vec4 BaseVecType; + + private: + + template + struct isSameType + { + enum {value = 0}; + }; + + template + struct isSameType + { + enum {value = 1}; + }; +}; + + +//-------------- +// Stream output +//-------------- + +template +std::ostream & operator << (std::ostream & s, const Matrix33 &m); + +template +std::ostream & operator << (std::ostream & s, const Matrix44 &m); + + +//--------------------------------------------- +// Vector-times-matrix multiplication operators +//--------------------------------------------- + +template +const Vec2 & operator *= (Vec2 &v, const Matrix33 &m); + +template +Vec2 operator * (const Vec2 &v, const Matrix33 &m); + +template +const Vec3 & operator *= (Vec3 &v, const Matrix33 &m); + +template +Vec3 operator * (const Vec3 &v, const Matrix33 &m); + +template +const Vec3 & operator *= (Vec3 &v, const Matrix44 &m); + +template +Vec3 operator * (const Vec3 &v, const Matrix44 &m); + +template +const Vec4 & operator *= (Vec4 &v, const Matrix44 &m); + +template +Vec4 operator * (const Vec4 &v, const Matrix44 &m); + +//------------------------- +// Typedefs for convenience +//------------------------- + +typedef Matrix33 M33f; +typedef Matrix33 M33d; +typedef Matrix44 M44f; +typedef Matrix44 M44d; + + +//--------------------------- +// Implementation of Matrix33 +//--------------------------- + +template +inline T * +Matrix33::operator [] (int i) +{ + return x[i]; +} + +template +inline const T * +Matrix33::operator [] (int i) const +{ + return x[i]; +} + +template +inline +Matrix33::Matrix33 () +{ + memset (x, 0, sizeof (x)); + x[0][0] = 1; + x[1][1] = 1; + x[2][2] = 1; +} + +template +inline +Matrix33::Matrix33 (T a) +{ + x[0][0] = a; + x[0][1] = a; + x[0][2] = a; + x[1][0] = a; + x[1][1] = a; + x[1][2] = a; + x[2][0] = a; + x[2][1] = a; + x[2][2] = a; +} + +template +inline +Matrix33::Matrix33 (const T a[3][3]) +{ + memcpy (x, a, sizeof (x)); +} + +template +inline +Matrix33::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) +{ + x[0][0] = a; + x[0][1] = b; + x[0][2] = c; + x[1][0] = d; + x[1][1] = e; + x[1][2] = f; + x[2][0] = g; + x[2][1] = h; + x[2][2] = i; +} + +template +inline +Matrix33::Matrix33 (const Matrix33 &v) +{ + memcpy (x, v.x, sizeof (x)); +} + +template +template +inline +Matrix33::Matrix33 (const Matrix33 &v) +{ + x[0][0] = T (v.x[0][0]); + x[0][1] = T (v.x[0][1]); + x[0][2] = T (v.x[0][2]); + x[1][0] = T (v.x[1][0]); + x[1][1] = T (v.x[1][1]); + x[1][2] = T (v.x[1][2]); + x[2][0] = T (v.x[2][0]); + x[2][1] = T (v.x[2][1]); + x[2][2] = T (v.x[2][2]); +} + +template +inline const Matrix33 & +Matrix33::operator = (const Matrix33 &v) +{ + memcpy (x, v.x, sizeof (x)); + return *this; +} + +template +inline const Matrix33 & +Matrix33::operator = (T a) +{ + x[0][0] = a; + x[0][1] = a; + x[0][2] = a; + x[1][0] = a; + x[1][1] = a; + x[1][2] = a; + x[2][0] = a; + x[2][1] = a; + x[2][2] = a; + return *this; +} + +template +inline T * +Matrix33::getValue () +{ + return (T *) &x[0][0]; +} + +template +inline const T * +Matrix33::getValue () const +{ + return (const T *) &x[0][0]; +} + +template +template +inline void +Matrix33::getValue (Matrix33 &v) const +{ + if (isSameType::value) + { + memcpy (v.x, x, sizeof (x)); + } + else + { + v.x[0][0] = x[0][0]; + v.x[0][1] = x[0][1]; + v.x[0][2] = x[0][2]; + v.x[1][0] = x[1][0]; + v.x[1][1] = x[1][1]; + v.x[1][2] = x[1][2]; + v.x[2][0] = x[2][0]; + v.x[2][1] = x[2][1]; + v.x[2][2] = x[2][2]; + } +} + +template +template +inline Matrix33 & +Matrix33::setValue (const Matrix33 &v) +{ + if (isSameType::value) + { + memcpy (x, v.x, sizeof (x)); + } + else + { + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + } + + return *this; +} + +template +template +inline Matrix33 & +Matrix33::setTheMatrix (const Matrix33 &v) +{ + if (isSameType::value) + { + memcpy (x, v.x, sizeof (x)); + } + else + { + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + } + + return *this; +} + +template +inline void +Matrix33::makeIdentity() +{ + memset (x, 0, sizeof (x)); + x[0][0] = 1; + x[1][1] = 1; + x[2][2] = 1; +} + +template +bool +Matrix33::operator == (const Matrix33 &v) const +{ + return x[0][0] == v.x[0][0] && + x[0][1] == v.x[0][1] && + x[0][2] == v.x[0][2] && + x[1][0] == v.x[1][0] && + x[1][1] == v.x[1][1] && + x[1][2] == v.x[1][2] && + x[2][0] == v.x[2][0] && + x[2][1] == v.x[2][1] && + x[2][2] == v.x[2][2]; +} + +template +bool +Matrix33::operator != (const Matrix33 &v) const +{ + return x[0][0] != v.x[0][0] || + x[0][1] != v.x[0][1] || + x[0][2] != v.x[0][2] || + x[1][0] != v.x[1][0] || + x[1][1] != v.x[1][1] || + x[1][2] != v.x[1][2] || + x[2][0] != v.x[2][0] || + x[2][1] != v.x[2][1] || + x[2][2] != v.x[2][2]; +} + +template +bool +Matrix33::equalWithAbsError (const Matrix33 &m, T e) const +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e)) + return false; + + return true; +} + +template +bool +Matrix33::equalWithRelError (const Matrix33 &m, T e) const +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e)) + return false; + + return true; +} + +template +const Matrix33 & +Matrix33::operator += (const Matrix33 &v) +{ + x[0][0] += v.x[0][0]; + x[0][1] += v.x[0][1]; + x[0][2] += v.x[0][2]; + x[1][0] += v.x[1][0]; + x[1][1] += v.x[1][1]; + x[1][2] += v.x[1][2]; + x[2][0] += v.x[2][0]; + x[2][1] += v.x[2][1]; + x[2][2] += v.x[2][2]; + + return *this; +} + +template +const Matrix33 & +Matrix33::operator += (T a) +{ + x[0][0] += a; + x[0][1] += a; + x[0][2] += a; + x[1][0] += a; + x[1][1] += a; + x[1][2] += a; + x[2][0] += a; + x[2][1] += a; + x[2][2] += a; + + return *this; +} + +template +Matrix33 +Matrix33::operator + (const Matrix33 &v) const +{ + return Matrix33 (x[0][0] + v.x[0][0], + x[0][1] + v.x[0][1], + x[0][2] + v.x[0][2], + x[1][0] + v.x[1][0], + x[1][1] + v.x[1][1], + x[1][2] + v.x[1][2], + x[2][0] + v.x[2][0], + x[2][1] + v.x[2][1], + x[2][2] + v.x[2][2]); +} + +template +const Matrix33 & +Matrix33::operator -= (const Matrix33 &v) +{ + x[0][0] -= v.x[0][0]; + x[0][1] -= v.x[0][1]; + x[0][2] -= v.x[0][2]; + x[1][0] -= v.x[1][0]; + x[1][1] -= v.x[1][1]; + x[1][2] -= v.x[1][2]; + x[2][0] -= v.x[2][0]; + x[2][1] -= v.x[2][1]; + x[2][2] -= v.x[2][2]; + + return *this; +} + +template +const Matrix33 & +Matrix33::operator -= (T a) +{ + x[0][0] -= a; + x[0][1] -= a; + x[0][2] -= a; + x[1][0] -= a; + x[1][1] -= a; + x[1][2] -= a; + x[2][0] -= a; + x[2][1] -= a; + x[2][2] -= a; + + return *this; +} + +template +Matrix33 +Matrix33::operator - (const Matrix33 &v) const +{ + return Matrix33 (x[0][0] - v.x[0][0], + x[0][1] - v.x[0][1], + x[0][2] - v.x[0][2], + x[1][0] - v.x[1][0], + x[1][1] - v.x[1][1], + x[1][2] - v.x[1][2], + x[2][0] - v.x[2][0], + x[2][1] - v.x[2][1], + x[2][2] - v.x[2][2]); +} + +template +Matrix33 +Matrix33::operator - () const +{ + return Matrix33 (-x[0][0], + -x[0][1], + -x[0][2], + -x[1][0], + -x[1][1], + -x[1][2], + -x[2][0], + -x[2][1], + -x[2][2]); +} + +template +const Matrix33 & +Matrix33::negate () +{ + x[0][0] = -x[0][0]; + x[0][1] = -x[0][1]; + x[0][2] = -x[0][2]; + x[1][0] = -x[1][0]; + x[1][1] = -x[1][1]; + x[1][2] = -x[1][2]; + x[2][0] = -x[2][0]; + x[2][1] = -x[2][1]; + x[2][2] = -x[2][2]; + + return *this; +} + +template +const Matrix33 & +Matrix33::operator *= (T a) +{ + x[0][0] *= a; + x[0][1] *= a; + x[0][2] *= a; + x[1][0] *= a; + x[1][1] *= a; + x[1][2] *= a; + x[2][0] *= a; + x[2][1] *= a; + x[2][2] *= a; + + return *this; +} + +template +Matrix33 +Matrix33::operator * (T a) const +{ + return Matrix33 (x[0][0] * a, + x[0][1] * a, + x[0][2] * a, + x[1][0] * a, + x[1][1] * a, + x[1][2] * a, + x[2][0] * a, + x[2][1] * a, + x[2][2] * a); +} + +template +inline Matrix33 +operator * (T a, const Matrix33 &v) +{ + return v * a; +} + +template +const Matrix33 & +Matrix33::operator *= (const Matrix33 &v) +{ + Matrix33 tmp (T (0)); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + tmp.x[i][j] += x[i][k] * v.x[k][j]; + + *this = tmp; + return *this; +} + +template +Matrix33 +Matrix33::operator * (const Matrix33 &v) const +{ + Matrix33 tmp (T (0)); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + tmp.x[i][j] += x[i][k] * v.x[k][j]; + + return tmp; +} + +template +template +void +Matrix33::multVecMatrix(const Vec2 &src, Vec2 &dst) const +{ + S a, b, w; + + a = src[0] * x[0][0] + src[1] * x[1][0] + x[2][0]; + b = src[0] * x[0][1] + src[1] * x[1][1] + x[2][1]; + w = src[0] * x[0][2] + src[1] * x[1][2] + x[2][2]; + + dst.x = a / w; + dst.y = b / w; +} + +template +template +void +Matrix33::multDirMatrix(const Vec2 &src, Vec2 &dst) const +{ + S a, b; + + a = src[0] * x[0][0] + src[1] * x[1][0]; + b = src[0] * x[0][1] + src[1] * x[1][1]; + + dst.x = a; + dst.y = b; +} + +template +const Matrix33 & +Matrix33::operator /= (T a) +{ + x[0][0] /= a; + x[0][1] /= a; + x[0][2] /= a; + x[1][0] /= a; + x[1][1] /= a; + x[1][2] /= a; + x[2][0] /= a; + x[2][1] /= a; + x[2][2] /= a; + + return *this; +} + +template +Matrix33 +Matrix33::operator / (T a) const +{ + return Matrix33 (x[0][0] / a, + x[0][1] / a, + x[0][2] / a, + x[1][0] / a, + x[1][1] / a, + x[1][2] / a, + x[2][0] / a, + x[2][1] / a, + x[2][2] / a); +} + +template +const Matrix33 & +Matrix33::transpose () +{ + Matrix33 tmp (x[0][0], + x[1][0], + x[2][0], + x[0][1], + x[1][1], + x[2][1], + x[0][2], + x[1][2], + x[2][2]); + *this = tmp; + return *this; +} + +template +Matrix33 +Matrix33::transposed () const +{ + return Matrix33 (x[0][0], + x[1][0], + x[2][0], + x[0][1], + x[1][1], + x[2][1], + x[0][2], + x[1][2], + x[2][2]); +} + +template +const Matrix33 & +Matrix33::gjInvert (bool singExc) throw (Iex::MathExc) +{ + *this = gjInverse (singExc); + return *this; +} + +template +Matrix33 +Matrix33::gjInverse (bool singExc) const throw (Iex::MathExc) +{ + int i, j, k; + Matrix33 s; + Matrix33 t (*this); + + // Forward elimination + + for (i = 0; i < 2 ; i++) + { + int pivot = i; + + T pivotsize = t[i][i]; + + if (pivotsize < 0) + pivotsize = -pivotsize; + + for (j = i + 1; j < 3; j++) + { + T tmp = t[j][i]; + + if (tmp < 0) + tmp = -tmp; + + if (tmp > pivotsize) + { + pivot = j; + pivotsize = tmp; + } + } + + if (pivotsize == 0) + { + if (singExc) + throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); + + return Matrix33(); + } + + if (pivot != i) + { + for (j = 0; j < 3; j++) + { + T tmp; + + tmp = t[i][j]; + t[i][j] = t[pivot][j]; + t[pivot][j] = tmp; + + tmp = s[i][j]; + s[i][j] = s[pivot][j]; + s[pivot][j] = tmp; + } + } + + for (j = i + 1; j < 3; j++) + { + T f = t[j][i] / t[i][i]; + + for (k = 0; k < 3; k++) + { + t[j][k] -= f * t[i][k]; + s[j][k] -= f * s[i][k]; + } + } + } + + // Backward substitution + + for (i = 2; i >= 0; --i) + { + T f; + + if ((f = t[i][i]) == 0) + { + if (singExc) + throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); + + return Matrix33(); + } + + for (j = 0; j < 3; j++) + { + t[i][j] /= f; + s[i][j] /= f; + } + + for (j = 0; j < i; j++) + { + f = t[j][i]; + + for (k = 0; k < 3; k++) + { + t[j][k] -= f * t[i][k]; + s[j][k] -= f * s[i][k]; + } + } + } + + return s; +} + +template +const Matrix33 & +Matrix33::invert (bool singExc) throw (Iex::MathExc) +{ + *this = inverse (singExc); + return *this; +} + +template +Matrix33 +Matrix33::inverse (bool singExc) const throw (Iex::MathExc) +{ + if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1) + { + Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2], + x[2][1] * x[0][2] - x[0][1] * x[2][2], + x[0][1] * x[1][2] - x[1][1] * x[0][2], + + x[2][0] * x[1][2] - x[1][0] * x[2][2], + x[0][0] * x[2][2] - x[2][0] * x[0][2], + x[1][0] * x[0][2] - x[0][0] * x[1][2], + + x[1][0] * x[2][1] - x[2][0] * x[1][1], + x[2][0] * x[0][1] - x[0][0] * x[2][1], + x[0][0] * x[1][1] - x[1][0] * x[0][1]); + + T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0]; + + if (Imath::abs (r) >= 1) + { + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + s[i][j] /= r; + } + } + } + else + { + T mr = Imath::abs (r) / limits::smallest(); + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + if (mr > Imath::abs (s[i][j])) + { + s[i][j] /= r; + } + else + { + if (singExc) + throw SingMatrixExc ("Cannot invert " + "singular matrix."); + return Matrix33(); + } + } + } + } + + return s; + } + else + { + Matrix33 s ( x[1][1], + -x[0][1], + 0, + + -x[1][0], + x[0][0], + 0, + + 0, + 0, + 1); + + T r = x[0][0] * x[1][1] - x[1][0] * x[0][1]; + + if (Imath::abs (r) >= 1) + { + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < 2; ++j) + { + s[i][j] /= r; + } + } + } + else + { + T mr = Imath::abs (r) / limits::smallest(); + + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < 2; ++j) + { + if (mr > Imath::abs (s[i][j])) + { + s[i][j] /= r; + } + else + { + if (singExc) + throw SingMatrixExc ("Cannot invert " + "singular matrix."); + return Matrix33(); + } + } + } + } + + s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0]; + s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1]; + + return s; + } +} + +template +inline T +Matrix33::minorOf (const int r, const int c) const +{ + int r0 = 0 + (r < 1 ? 1 : 0); + int r1 = 1 + (r < 2 ? 1 : 0); + int c0 = 0 + (c < 1 ? 1 : 0); + int c1 = 1 + (c < 2 ? 1 : 0); + + return x[r0][c0]*x[r1][c1] - x[r1][c0]*x[r0][c1]; +} + +template +inline T +Matrix33::fastMinor( const int r0, const int r1, + const int c0, const int c1) const +{ + return x[r0][c0]*x[r1][c1] - x[r0][c1]*x[r1][c0]; +} + +template +inline T +Matrix33::determinant () const +{ + return x[0][0]*(x[1][1]*x[2][2] - x[1][2]*x[2][1]) + + x[0][1]*(x[1][2]*x[2][0] - x[1][0]*x[2][2]) + + x[0][2]*(x[1][0]*x[2][1] - x[1][1]*x[2][0]); +} + +template +template +const Matrix33 & +Matrix33::setRotation (S r) +{ + S cos_r, sin_r; + + cos_r = Math::cos (r); + sin_r = Math::sin (r); + + x[0][0] = cos_r; + x[0][1] = sin_r; + x[0][2] = 0; + + x[1][0] = -sin_r; + x[1][1] = cos_r; + x[1][2] = 0; + + x[2][0] = 0; + x[2][1] = 0; + x[2][2] = 1; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::rotate (S r) +{ + *this *= Matrix33().setRotation (r); + return *this; +} + +template +const Matrix33 & +Matrix33::setScale (T s) +{ + memset (x, 0, sizeof (x)); + x[0][0] = s; + x[1][1] = s; + x[2][2] = 1; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::setScale (const Vec2 &s) +{ + memset (x, 0, sizeof (x)); + x[0][0] = s[0]; + x[1][1] = s[1]; + x[2][2] = 1; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::scale (const Vec2 &s) +{ + x[0][0] *= s[0]; + x[0][1] *= s[0]; + x[0][2] *= s[0]; + + x[1][0] *= s[1]; + x[1][1] *= s[1]; + x[1][2] *= s[1]; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::setTranslation (const Vec2 &t) +{ + x[0][0] = 1; + x[0][1] = 0; + x[0][2] = 0; + + x[1][0] = 0; + x[1][1] = 1; + x[1][2] = 0; + + x[2][0] = t[0]; + x[2][1] = t[1]; + x[2][2] = 1; + + return *this; +} + +template +inline Vec2 +Matrix33::translation () const +{ + return Vec2 (x[2][0], x[2][1]); +} + +template +template +const Matrix33 & +Matrix33::translate (const Vec2 &t) +{ + x[2][0] += t[0] * x[0][0] + t[1] * x[1][0]; + x[2][1] += t[0] * x[0][1] + t[1] * x[1][1]; + x[2][2] += t[0] * x[0][2] + t[1] * x[1][2]; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::setShear (const S &xy) +{ + x[0][0] = 1; + x[0][1] = 0; + x[0][2] = 0; + + x[1][0] = xy; + x[1][1] = 1; + x[1][2] = 0; + + x[2][0] = 0; + x[2][1] = 0; + x[2][2] = 1; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::setShear (const Vec2 &h) +{ + x[0][0] = 1; + x[0][1] = h[1]; + x[0][2] = 0; + + x[1][0] = h[0]; + x[1][1] = 1; + x[1][2] = 0; + + x[2][0] = 0; + x[2][1] = 0; + x[2][2] = 1; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::shear (const S &xy) +{ + // + // In this case, we don't need a temp. copy of the matrix + // because we never use a value on the RHS after we've + // changed it on the LHS. + // + + x[1][0] += xy * x[0][0]; + x[1][1] += xy * x[0][1]; + x[1][2] += xy * x[0][2]; + + return *this; +} + +template +template +const Matrix33 & +Matrix33::shear (const Vec2 &h) +{ + Matrix33 P (*this); + + x[0][0] = P[0][0] + h[1] * P[1][0]; + x[0][1] = P[0][1] + h[1] * P[1][1]; + x[0][2] = P[0][2] + h[1] * P[1][2]; + + x[1][0] = P[1][0] + h[0] * P[0][0]; + x[1][1] = P[1][1] + h[0] * P[0][1]; + x[1][2] = P[1][2] + h[0] * P[0][2]; + + return *this; +} + + +//--------------------------- +// Implementation of Matrix44 +//--------------------------- + +template +inline T * +Matrix44::operator [] (int i) +{ + return x[i]; +} + +template +inline const T * +Matrix44::operator [] (int i) const +{ + return x[i]; +} + +template +inline +Matrix44::Matrix44 () +{ + memset (x, 0, sizeof (x)); + x[0][0] = 1; + x[1][1] = 1; + x[2][2] = 1; + x[3][3] = 1; +} + +template +inline +Matrix44::Matrix44 (T a) +{ + x[0][0] = a; + x[0][1] = a; + x[0][2] = a; + x[0][3] = a; + x[1][0] = a; + x[1][1] = a; + x[1][2] = a; + x[1][3] = a; + x[2][0] = a; + x[2][1] = a; + x[2][2] = a; + x[2][3] = a; + x[3][0] = a; + x[3][1] = a; + x[3][2] = a; + x[3][3] = a; +} + +template +inline +Matrix44::Matrix44 (const T a[4][4]) +{ + memcpy (x, a, sizeof (x)); +} + +template +inline +Matrix44::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, + T i, T j, T k, T l, T m, T n, T o, T p) +{ + x[0][0] = a; + x[0][1] = b; + x[0][2] = c; + x[0][3] = d; + x[1][0] = e; + x[1][1] = f; + x[1][2] = g; + x[1][3] = h; + x[2][0] = i; + x[2][1] = j; + x[2][2] = k; + x[2][3] = l; + x[3][0] = m; + x[3][1] = n; + x[3][2] = o; + x[3][3] = p; +} + + +template +inline +Matrix44::Matrix44 (Matrix33 r, Vec3 t) +{ + x[0][0] = r[0][0]; + x[0][1] = r[0][1]; + x[0][2] = r[0][2]; + x[0][3] = 0; + x[1][0] = r[1][0]; + x[1][1] = r[1][1]; + x[1][2] = r[1][2]; + x[1][3] = 0; + x[2][0] = r[2][0]; + x[2][1] = r[2][1]; + x[2][2] = r[2][2]; + x[2][3] = 0; + x[3][0] = t[0]; + x[3][1] = t[1]; + x[3][2] = t[2]; + x[3][3] = 1; +} + +template +inline +Matrix44::Matrix44 (const Matrix44 &v) +{ + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[0][3] = v.x[0][3]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[1][3] = v.x[1][3]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + x[2][3] = v.x[2][3]; + x[3][0] = v.x[3][0]; + x[3][1] = v.x[3][1]; + x[3][2] = v.x[3][2]; + x[3][3] = v.x[3][3]; +} + +template +template +inline +Matrix44::Matrix44 (const Matrix44 &v) +{ + x[0][0] = T (v.x[0][0]); + x[0][1] = T (v.x[0][1]); + x[0][2] = T (v.x[0][2]); + x[0][3] = T (v.x[0][3]); + x[1][0] = T (v.x[1][0]); + x[1][1] = T (v.x[1][1]); + x[1][2] = T (v.x[1][2]); + x[1][3] = T (v.x[1][3]); + x[2][0] = T (v.x[2][0]); + x[2][1] = T (v.x[2][1]); + x[2][2] = T (v.x[2][2]); + x[2][3] = T (v.x[2][3]); + x[3][0] = T (v.x[3][0]); + x[3][1] = T (v.x[3][1]); + x[3][2] = T (v.x[3][2]); + x[3][3] = T (v.x[3][3]); +} + +template +inline const Matrix44 & +Matrix44::operator = (const Matrix44 &v) +{ + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[0][3] = v.x[0][3]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[1][3] = v.x[1][3]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + x[2][3] = v.x[2][3]; + x[3][0] = v.x[3][0]; + x[3][1] = v.x[3][1]; + x[3][2] = v.x[3][2]; + x[3][3] = v.x[3][3]; + return *this; +} + +template +inline const Matrix44 & +Matrix44::operator = (T a) +{ + x[0][0] = a; + x[0][1] = a; + x[0][2] = a; + x[0][3] = a; + x[1][0] = a; + x[1][1] = a; + x[1][2] = a; + x[1][3] = a; + x[2][0] = a; + x[2][1] = a; + x[2][2] = a; + x[2][3] = a; + x[3][0] = a; + x[3][1] = a; + x[3][2] = a; + x[3][3] = a; + return *this; +} + +template +inline T * +Matrix44::getValue () +{ + return (T *) &x[0][0]; +} + +template +inline const T * +Matrix44::getValue () const +{ + return (const T *) &x[0][0]; +} + +template +template +inline void +Matrix44::getValue (Matrix44 &v) const +{ + if (isSameType::value) + { + memcpy (v.x, x, sizeof (x)); + } + else + { + v.x[0][0] = x[0][0]; + v.x[0][1] = x[0][1]; + v.x[0][2] = x[0][2]; + v.x[0][3] = x[0][3]; + v.x[1][0] = x[1][0]; + v.x[1][1] = x[1][1]; + v.x[1][2] = x[1][2]; + v.x[1][3] = x[1][3]; + v.x[2][0] = x[2][0]; + v.x[2][1] = x[2][1]; + v.x[2][2] = x[2][2]; + v.x[2][3] = x[2][3]; + v.x[3][0] = x[3][0]; + v.x[3][1] = x[3][1]; + v.x[3][2] = x[3][2]; + v.x[3][3] = x[3][3]; + } +} + +template +template +inline Matrix44 & +Matrix44::setValue (const Matrix44 &v) +{ + if (isSameType::value) + { + memcpy (x, v.x, sizeof (x)); + } + else + { + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[0][3] = v.x[0][3]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[1][3] = v.x[1][3]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + x[2][3] = v.x[2][3]; + x[3][0] = v.x[3][0]; + x[3][1] = v.x[3][1]; + x[3][2] = v.x[3][2]; + x[3][3] = v.x[3][3]; + } + + return *this; +} + +template +template +inline Matrix44 & +Matrix44::setTheMatrix (const Matrix44 &v) +{ + if (isSameType::value) + { + memcpy (x, v.x, sizeof (x)); + } + else + { + x[0][0] = v.x[0][0]; + x[0][1] = v.x[0][1]; + x[0][2] = v.x[0][2]; + x[0][3] = v.x[0][3]; + x[1][0] = v.x[1][0]; + x[1][1] = v.x[1][1]; + x[1][2] = v.x[1][2]; + x[1][3] = v.x[1][3]; + x[2][0] = v.x[2][0]; + x[2][1] = v.x[2][1]; + x[2][2] = v.x[2][2]; + x[2][3] = v.x[2][3]; + x[3][0] = v.x[3][0]; + x[3][1] = v.x[3][1]; + x[3][2] = v.x[3][2]; + x[3][3] = v.x[3][3]; + } + + return *this; +} + +template +inline void +Matrix44::makeIdentity() +{ + memset (x, 0, sizeof (x)); + x[0][0] = 1; + x[1][1] = 1; + x[2][2] = 1; + x[3][3] = 1; +} + +template +bool +Matrix44::operator == (const Matrix44 &v) const +{ + return x[0][0] == v.x[0][0] && + x[0][1] == v.x[0][1] && + x[0][2] == v.x[0][2] && + x[0][3] == v.x[0][3] && + x[1][0] == v.x[1][0] && + x[1][1] == v.x[1][1] && + x[1][2] == v.x[1][2] && + x[1][3] == v.x[1][3] && + x[2][0] == v.x[2][0] && + x[2][1] == v.x[2][1] && + x[2][2] == v.x[2][2] && + x[2][3] == v.x[2][3] && + x[3][0] == v.x[3][0] && + x[3][1] == v.x[3][1] && + x[3][2] == v.x[3][2] && + x[3][3] == v.x[3][3]; +} + +template +bool +Matrix44::operator != (const Matrix44 &v) const +{ + return x[0][0] != v.x[0][0] || + x[0][1] != v.x[0][1] || + x[0][2] != v.x[0][2] || + x[0][3] != v.x[0][3] || + x[1][0] != v.x[1][0] || + x[1][1] != v.x[1][1] || + x[1][2] != v.x[1][2] || + x[1][3] != v.x[1][3] || + x[2][0] != v.x[2][0] || + x[2][1] != v.x[2][1] || + x[2][2] != v.x[2][2] || + x[2][3] != v.x[2][3] || + x[3][0] != v.x[3][0] || + x[3][1] != v.x[3][1] || + x[3][2] != v.x[3][2] || + x[3][3] != v.x[3][3]; +} + +template +bool +Matrix44::equalWithAbsError (const Matrix44 &m, T e) const +{ + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e)) + return false; + + return true; +} + +template +bool +Matrix44::equalWithRelError (const Matrix44 &m, T e) const +{ + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e)) + return false; + + return true; +} + +template +const Matrix44 & +Matrix44::operator += (const Matrix44 &v) +{ + x[0][0] += v.x[0][0]; + x[0][1] += v.x[0][1]; + x[0][2] += v.x[0][2]; + x[0][3] += v.x[0][3]; + x[1][0] += v.x[1][0]; + x[1][1] += v.x[1][1]; + x[1][2] += v.x[1][2]; + x[1][3] += v.x[1][3]; + x[2][0] += v.x[2][0]; + x[2][1] += v.x[2][1]; + x[2][2] += v.x[2][2]; + x[2][3] += v.x[2][3]; + x[3][0] += v.x[3][0]; + x[3][1] += v.x[3][1]; + x[3][2] += v.x[3][2]; + x[3][3] += v.x[3][3]; + + return *this; +} + +template +const Matrix44 & +Matrix44::operator += (T a) +{ + x[0][0] += a; + x[0][1] += a; + x[0][2] += a; + x[0][3] += a; + x[1][0] += a; + x[1][1] += a; + x[1][2] += a; + x[1][3] += a; + x[2][0] += a; + x[2][1] += a; + x[2][2] += a; + x[2][3] += a; + x[3][0] += a; + x[3][1] += a; + x[3][2] += a; + x[3][3] += a; + + return *this; +} + +template +Matrix44 +Matrix44::operator + (const Matrix44 &v) const +{ + return Matrix44 (x[0][0] + v.x[0][0], + x[0][1] + v.x[0][1], + x[0][2] + v.x[0][2], + x[0][3] + v.x[0][3], + x[1][0] + v.x[1][0], + x[1][1] + v.x[1][1], + x[1][2] + v.x[1][2], + x[1][3] + v.x[1][3], + x[2][0] + v.x[2][0], + x[2][1] + v.x[2][1], + x[2][2] + v.x[2][2], + x[2][3] + v.x[2][3], + x[3][0] + v.x[3][0], + x[3][1] + v.x[3][1], + x[3][2] + v.x[3][2], + x[3][3] + v.x[3][3]); +} + +template +const Matrix44 & +Matrix44::operator -= (const Matrix44 &v) +{ + x[0][0] -= v.x[0][0]; + x[0][1] -= v.x[0][1]; + x[0][2] -= v.x[0][2]; + x[0][3] -= v.x[0][3]; + x[1][0] -= v.x[1][0]; + x[1][1] -= v.x[1][1]; + x[1][2] -= v.x[1][2]; + x[1][3] -= v.x[1][3]; + x[2][0] -= v.x[2][0]; + x[2][1] -= v.x[2][1]; + x[2][2] -= v.x[2][2]; + x[2][3] -= v.x[2][3]; + x[3][0] -= v.x[3][0]; + x[3][1] -= v.x[3][1]; + x[3][2] -= v.x[3][2]; + x[3][3] -= v.x[3][3]; + + return *this; +} + +template +const Matrix44 & +Matrix44::operator -= (T a) +{ + x[0][0] -= a; + x[0][1] -= a; + x[0][2] -= a; + x[0][3] -= a; + x[1][0] -= a; + x[1][1] -= a; + x[1][2] -= a; + x[1][3] -= a; + x[2][0] -= a; + x[2][1] -= a; + x[2][2] -= a; + x[2][3] -= a; + x[3][0] -= a; + x[3][1] -= a; + x[3][2] -= a; + x[3][3] -= a; + + return *this; +} + +template +Matrix44 +Matrix44::operator - (const Matrix44 &v) const +{ + return Matrix44 (x[0][0] - v.x[0][0], + x[0][1] - v.x[0][1], + x[0][2] - v.x[0][2], + x[0][3] - v.x[0][3], + x[1][0] - v.x[1][0], + x[1][1] - v.x[1][1], + x[1][2] - v.x[1][2], + x[1][3] - v.x[1][3], + x[2][0] - v.x[2][0], + x[2][1] - v.x[2][1], + x[2][2] - v.x[2][2], + x[2][3] - v.x[2][3], + x[3][0] - v.x[3][0], + x[3][1] - v.x[3][1], + x[3][2] - v.x[3][2], + x[3][3] - v.x[3][3]); +} + +template +Matrix44 +Matrix44::operator - () const +{ + return Matrix44 (-x[0][0], + -x[0][1], + -x[0][2], + -x[0][3], + -x[1][0], + -x[1][1], + -x[1][2], + -x[1][3], + -x[2][0], + -x[2][1], + -x[2][2], + -x[2][3], + -x[3][0], + -x[3][1], + -x[3][2], + -x[3][3]); +} + +template +const Matrix44 & +Matrix44::negate () +{ + x[0][0] = -x[0][0]; + x[0][1] = -x[0][1]; + x[0][2] = -x[0][2]; + x[0][3] = -x[0][3]; + x[1][0] = -x[1][0]; + x[1][1] = -x[1][1]; + x[1][2] = -x[1][2]; + x[1][3] = -x[1][3]; + x[2][0] = -x[2][0]; + x[2][1] = -x[2][1]; + x[2][2] = -x[2][2]; + x[2][3] = -x[2][3]; + x[3][0] = -x[3][0]; + x[3][1] = -x[3][1]; + x[3][2] = -x[3][2]; + x[3][3] = -x[3][3]; + + return *this; +} + +template +const Matrix44 & +Matrix44::operator *= (T a) +{ + x[0][0] *= a; + x[0][1] *= a; + x[0][2] *= a; + x[0][3] *= a; + x[1][0] *= a; + x[1][1] *= a; + x[1][2] *= a; + x[1][3] *= a; + x[2][0] *= a; + x[2][1] *= a; + x[2][2] *= a; + x[2][3] *= a; + x[3][0] *= a; + x[3][1] *= a; + x[3][2] *= a; + x[3][3] *= a; + + return *this; +} + +template +Matrix44 +Matrix44::operator * (T a) const +{ + return Matrix44 (x[0][0] * a, + x[0][1] * a, + x[0][2] * a, + x[0][3] * a, + x[1][0] * a, + x[1][1] * a, + x[1][2] * a, + x[1][3] * a, + x[2][0] * a, + x[2][1] * a, + x[2][2] * a, + x[2][3] * a, + x[3][0] * a, + x[3][1] * a, + x[3][2] * a, + x[3][3] * a); +} + +template +inline Matrix44 +operator * (T a, const Matrix44 &v) +{ + return v * a; +} + +template +inline const Matrix44 & +Matrix44::operator *= (const Matrix44 &v) +{ + Matrix44 tmp (T (0)); + + multiply (*this, v, tmp); + *this = tmp; + return *this; +} + +template +inline Matrix44 +Matrix44::operator * (const Matrix44 &v) const +{ + Matrix44 tmp (T (0)); + + multiply (*this, v, tmp); + return tmp; +} + +template +void +Matrix44::multiply (const Matrix44 &a, + const Matrix44 &b, + Matrix44 &c) +{ + register const T * IMATH_RESTRICT ap = &a.x[0][0]; + register const T * IMATH_RESTRICT bp = &b.x[0][0]; + register T * IMATH_RESTRICT cp = &c.x[0][0]; + + register T a0, a1, a2, a3; + + a0 = ap[0]; + a1 = ap[1]; + a2 = ap[2]; + a3 = ap[3]; + + cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; + cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; + cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; + cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; + + a0 = ap[4]; + a1 = ap[5]; + a2 = ap[6]; + a3 = ap[7]; + + cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; + cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; + cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; + cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; + + a0 = ap[8]; + a1 = ap[9]; + a2 = ap[10]; + a3 = ap[11]; + + cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; + cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; + cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; + cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; + + a0 = ap[12]; + a1 = ap[13]; + a2 = ap[14]; + a3 = ap[15]; + + cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; + cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; + cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; + cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; +} + +template template +void +Matrix44::multVecMatrix(const Vec3 &src, Vec3 &dst) const +{ + S a, b, c, w; + + a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0] + x[3][0]; + b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1] + x[3][1]; + c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2] + x[3][2]; + w = src[0] * x[0][3] + src[1] * x[1][3] + src[2] * x[2][3] + x[3][3]; + + dst.x = a / w; + dst.y = b / w; + dst.z = c / w; +} + +template template +void +Matrix44::multDirMatrix(const Vec3 &src, Vec3 &dst) const +{ + S a, b, c; + + a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0]; + b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1]; + c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2]; + + dst.x = a; + dst.y = b; + dst.z = c; +} + +template +const Matrix44 & +Matrix44::operator /= (T a) +{ + x[0][0] /= a; + x[0][1] /= a; + x[0][2] /= a; + x[0][3] /= a; + x[1][0] /= a; + x[1][1] /= a; + x[1][2] /= a; + x[1][3] /= a; + x[2][0] /= a; + x[2][1] /= a; + x[2][2] /= a; + x[2][3] /= a; + x[3][0] /= a; + x[3][1] /= a; + x[3][2] /= a; + x[3][3] /= a; + + return *this; +} + +template +Matrix44 +Matrix44::operator / (T a) const +{ + return Matrix44 (x[0][0] / a, + x[0][1] / a, + x[0][2] / a, + x[0][3] / a, + x[1][0] / a, + x[1][1] / a, + x[1][2] / a, + x[1][3] / a, + x[2][0] / a, + x[2][1] / a, + x[2][2] / a, + x[2][3] / a, + x[3][0] / a, + x[3][1] / a, + x[3][2] / a, + x[3][3] / a); +} + +template +const Matrix44 & +Matrix44::transpose () +{ + Matrix44 tmp (x[0][0], + x[1][0], + x[2][0], + x[3][0], + x[0][1], + x[1][1], + x[2][1], + x[3][1], + x[0][2], + x[1][2], + x[2][2], + x[3][2], + x[0][3], + x[1][3], + x[2][3], + x[3][3]); + *this = tmp; + return *this; +} + +template +Matrix44 +Matrix44::transposed () const +{ + return Matrix44 (x[0][0], + x[1][0], + x[2][0], + x[3][0], + x[0][1], + x[1][1], + x[2][1], + x[3][1], + x[0][2], + x[1][2], + x[2][2], + x[3][2], + x[0][3], + x[1][3], + x[2][3], + x[3][3]); +} + +template +const Matrix44 & +Matrix44::gjInvert (bool singExc) throw (Iex::MathExc) +{ + *this = gjInverse (singExc); + return *this; +} + +template +Matrix44 +Matrix44::gjInverse (bool singExc) const throw (Iex::MathExc) +{ + int i, j, k; + Matrix44 s; + Matrix44 t (*this); + + // Forward elimination + + for (i = 0; i < 3 ; i++) + { + int pivot = i; + + T pivotsize = t[i][i]; + + if (pivotsize < 0) + pivotsize = -pivotsize; + + for (j = i + 1; j < 4; j++) + { + T tmp = t[j][i]; + + if (tmp < 0) + tmp = -tmp; + + if (tmp > pivotsize) + { + pivot = j; + pivotsize = tmp; + } + } + + if (pivotsize == 0) + { + if (singExc) + throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); + + return Matrix44(); + } + + if (pivot != i) + { + for (j = 0; j < 4; j++) + { + T tmp; + + tmp = t[i][j]; + t[i][j] = t[pivot][j]; + t[pivot][j] = tmp; + + tmp = s[i][j]; + s[i][j] = s[pivot][j]; + s[pivot][j] = tmp; + } + } + + for (j = i + 1; j < 4; j++) + { + T f = t[j][i] / t[i][i]; + + for (k = 0; k < 4; k++) + { + t[j][k] -= f * t[i][k]; + s[j][k] -= f * s[i][k]; + } + } + } + + // Backward substitution + + for (i = 3; i >= 0; --i) + { + T f; + + if ((f = t[i][i]) == 0) + { + if (singExc) + throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); + + return Matrix44(); + } + + for (j = 0; j < 4; j++) + { + t[i][j] /= f; + s[i][j] /= f; + } + + for (j = 0; j < i; j++) + { + f = t[j][i]; + + for (k = 0; k < 4; k++) + { + t[j][k] -= f * t[i][k]; + s[j][k] -= f * s[i][k]; + } + } + } + + return s; +} + +template +const Matrix44 & +Matrix44::invert (bool singExc) throw (Iex::MathExc) +{ + *this = inverse (singExc); + return *this; +} + +template +Matrix44 +Matrix44::inverse (bool singExc) const throw (Iex::MathExc) +{ + if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1) + return gjInverse(singExc); + + Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2], + x[2][1] * x[0][2] - x[0][1] * x[2][2], + x[0][1] * x[1][2] - x[1][1] * x[0][2], + 0, + + x[2][0] * x[1][2] - x[1][0] * x[2][2], + x[0][0] * x[2][2] - x[2][0] * x[0][2], + x[1][0] * x[0][2] - x[0][0] * x[1][2], + 0, + + x[1][0] * x[2][1] - x[2][0] * x[1][1], + x[2][0] * x[0][1] - x[0][0] * x[2][1], + x[0][0] * x[1][1] - x[1][0] * x[0][1], + 0, + + 0, + 0, + 0, + 1); + + T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0]; + + if (Imath::abs (r) >= 1) + { + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + s[i][j] /= r; + } + } + } + else + { + T mr = Imath::abs (r) / limits::smallest(); + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + if (mr > Imath::abs (s[i][j])) + { + s[i][j] /= r; + } + else + { + if (singExc) + throw SingMatrixExc ("Cannot invert singular matrix."); + + return Matrix44(); + } + } + } + } + + s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0]; + s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1]; + s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2]; + + return s; +} + +template +inline T +Matrix44::fastMinor( const int r0, const int r1, const int r2, + const int c0, const int c1, const int c2) const +{ + return x[r0][c0] * (x[r1][c1]*x[r2][c2] - x[r1][c2]*x[r2][c1]) + + x[r0][c1] * (x[r1][c2]*x[r2][c0] - x[r1][c0]*x[r2][c2]) + + x[r0][c2] * (x[r1][c0]*x[r2][c1] - x[r1][c1]*x[r2][c0]); +} + +template +inline T +Matrix44::minorOf (const int r, const int c) const +{ + int r0 = 0 + (r < 1 ? 1 : 0); + int r1 = 1 + (r < 2 ? 1 : 0); + int r2 = 2 + (r < 3 ? 1 : 0); + int c0 = 0 + (c < 1 ? 1 : 0); + int c1 = 1 + (c < 2 ? 1 : 0); + int c2 = 2 + (c < 3 ? 1 : 0); + + Matrix33 working (x[r0][c0],x[r1][c0],x[r2][c0], + x[r0][c1],x[r1][c1],x[r2][c1], + x[r0][c2],x[r1][c2],x[r2][c2]); + + return working.determinant(); +} + +template +inline T +Matrix44::determinant () const +{ + T sum = (T)0; + + if (x[0][3] != 0.) sum -= x[0][3] * fastMinor(1,2,3,0,1,2); + if (x[1][3] != 0.) sum += x[1][3] * fastMinor(0,2,3,0,1,2); + if (x[2][3] != 0.) sum -= x[2][3] * fastMinor(0,1,3,0,1,2); + if (x[3][3] != 0.) sum += x[3][3] * fastMinor(0,1,2,0,1,2); + + return sum; +} + +template +template +const Matrix44 & +Matrix44::setEulerAngles (const Vec3& r) +{ + S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx; + + cos_rz = Math::cos (r[2]); + cos_ry = Math::cos (r[1]); + cos_rx = Math::cos (r[0]); + + sin_rz = Math::sin (r[2]); + sin_ry = Math::sin (r[1]); + sin_rx = Math::sin (r[0]); + + x[0][0] = cos_rz * cos_ry; + x[0][1] = sin_rz * cos_ry; + x[0][2] = -sin_ry; + x[0][3] = 0; + + x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx; + x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx; + x[1][2] = cos_ry * sin_rx; + x[1][3] = 0; + + x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx; + x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx; + x[2][2] = cos_ry * cos_rx; + x[2][3] = 0; + + x[3][0] = 0; + x[3][1] = 0; + x[3][2] = 0; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::setAxisAngle (const Vec3& axis, S angle) +{ + Vec3 unit (axis.normalized()); + S sine = Math::sin (angle); + S cosine = Math::cos (angle); + + x[0][0] = unit[0] * unit[0] * (1 - cosine) + cosine; + x[0][1] = unit[0] * unit[1] * (1 - cosine) + unit[2] * sine; + x[0][2] = unit[0] * unit[2] * (1 - cosine) - unit[1] * sine; + x[0][3] = 0; + + x[1][0] = unit[0] * unit[1] * (1 - cosine) - unit[2] * sine; + x[1][1] = unit[1] * unit[1] * (1 - cosine) + cosine; + x[1][2] = unit[1] * unit[2] * (1 - cosine) + unit[0] * sine; + x[1][3] = 0; + + x[2][0] = unit[0] * unit[2] * (1 - cosine) + unit[1] * sine; + x[2][1] = unit[1] * unit[2] * (1 - cosine) - unit[0] * sine; + x[2][2] = unit[2] * unit[2] * (1 - cosine) + cosine; + x[2][3] = 0; + + x[3][0] = 0; + x[3][1] = 0; + x[3][2] = 0; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::rotate (const Vec3 &r) +{ + S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx; + S m00, m01, m02; + S m10, m11, m12; + S m20, m21, m22; + + cos_rz = Math::cos (r[2]); + cos_ry = Math::cos (r[1]); + cos_rx = Math::cos (r[0]); + + sin_rz = Math::sin (r[2]); + sin_ry = Math::sin (r[1]); + sin_rx = Math::sin (r[0]); + + m00 = cos_rz * cos_ry; + m01 = sin_rz * cos_ry; + m02 = -sin_ry; + m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx; + m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx; + m12 = cos_ry * sin_rx; + m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx; + m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx; + m22 = cos_ry * cos_rx; + + Matrix44 P (*this); + + x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02; + x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02; + x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02; + x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02; + + x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12; + x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12; + x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12; + x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12; + + x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22; + x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22; + x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22; + x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22; + + return *this; +} + +template +const Matrix44 & +Matrix44::setScale (T s) +{ + memset (x, 0, sizeof (x)); + x[0][0] = s; + x[1][1] = s; + x[2][2] = s; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::setScale (const Vec3 &s) +{ + memset (x, 0, sizeof (x)); + x[0][0] = s[0]; + x[1][1] = s[1]; + x[2][2] = s[2]; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::scale (const Vec3 &s) +{ + x[0][0] *= s[0]; + x[0][1] *= s[0]; + x[0][2] *= s[0]; + x[0][3] *= s[0]; + + x[1][0] *= s[1]; + x[1][1] *= s[1]; + x[1][2] *= s[1]; + x[1][3] *= s[1]; + + x[2][0] *= s[2]; + x[2][1] *= s[2]; + x[2][2] *= s[2]; + x[2][3] *= s[2]; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::setTranslation (const Vec3 &t) +{ + x[0][0] = 1; + x[0][1] = 0; + x[0][2] = 0; + x[0][3] = 0; + + x[1][0] = 0; + x[1][1] = 1; + x[1][2] = 0; + x[1][3] = 0; + + x[2][0] = 0; + x[2][1] = 0; + x[2][2] = 1; + x[2][3] = 0; + + x[3][0] = t[0]; + x[3][1] = t[1]; + x[3][2] = t[2]; + x[3][3] = 1; + + return *this; +} + +template +inline const Vec3 +Matrix44::translation () const +{ + return Vec3 (x[3][0], x[3][1], x[3][2]); +} + +template +template +const Matrix44 & +Matrix44::translate (const Vec3 &t) +{ + x[3][0] += t[0] * x[0][0] + t[1] * x[1][0] + t[2] * x[2][0]; + x[3][1] += t[0] * x[0][1] + t[1] * x[1][1] + t[2] * x[2][1]; + x[3][2] += t[0] * x[0][2] + t[1] * x[1][2] + t[2] * x[2][2]; + x[3][3] += t[0] * x[0][3] + t[1] * x[1][3] + t[2] * x[2][3]; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::setShear (const Vec3 &h) +{ + x[0][0] = 1; + x[0][1] = 0; + x[0][2] = 0; + x[0][3] = 0; + + x[1][0] = h[0]; + x[1][1] = 1; + x[1][2] = 0; + x[1][3] = 0; + + x[2][0] = h[1]; + x[2][1] = h[2]; + x[2][2] = 1; + x[2][3] = 0; + + x[3][0] = 0; + x[3][1] = 0; + x[3][2] = 0; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::setShear (const Shear6 &h) +{ + x[0][0] = 1; + x[0][1] = h.yx; + x[0][2] = h.zx; + x[0][3] = 0; + + x[1][0] = h.xy; + x[1][1] = 1; + x[1][2] = h.zy; + x[1][3] = 0; + + x[2][0] = h.xz; + x[2][1] = h.yz; + x[2][2] = 1; + x[2][3] = 0; + + x[3][0] = 0; + x[3][1] = 0; + x[3][2] = 0; + x[3][3] = 1; + + return *this; +} + +template +template +const Matrix44 & +Matrix44::shear (const Vec3 &h) +{ + // + // In this case, we don't need a temp. copy of the matrix + // because we never use a value on the RHS after we've + // changed it on the LHS. + // + + for (int i=0; i < 4; i++) + { + x[2][i] += h[1] * x[0][i] + h[2] * x[1][i]; + x[1][i] += h[0] * x[0][i]; + } + + return *this; +} + +template +template +const Matrix44 & +Matrix44::shear (const Shear6 &h) +{ + Matrix44 P (*this); + + for (int i=0; i < 4; i++) + { + x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i]; + x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i]; + x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i]; + } + + return *this; +} + + +//-------------------------------- +// Implementation of stream output +//-------------------------------- + +template +std::ostream & +operator << (std::ostream &s, const Matrix33 &m) +{ + std::ios_base::fmtflags oldFlags = s.flags(); + int width; + + if (s.flags() & std::ios_base::fixed) + { + s.setf (std::ios_base::showpoint); + width = s.precision() + 5; + } + else + { + s.setf (std::ios_base::scientific); + s.setf (std::ios_base::showpoint); + width = s.precision() + 8; + } + + s << "(" << std::setw (width) << m[0][0] << + " " << std::setw (width) << m[0][1] << + " " << std::setw (width) << m[0][2] << "\n" << + + " " << std::setw (width) << m[1][0] << + " " << std::setw (width) << m[1][1] << + " " << std::setw (width) << m[1][2] << "\n" << + + " " << std::setw (width) << m[2][0] << + " " << std::setw (width) << m[2][1] << + " " << std::setw (width) << m[2][2] << ")\n"; + + s.flags (oldFlags); + return s; +} + +template +std::ostream & +operator << (std::ostream &s, const Matrix44 &m) +{ + std::ios_base::fmtflags oldFlags = s.flags(); + int width; + + if (s.flags() & std::ios_base::fixed) + { + s.setf (std::ios_base::showpoint); + width = s.precision() + 5; + } + else + { + s.setf (std::ios_base::scientific); + s.setf (std::ios_base::showpoint); + width = s.precision() + 8; + } + + s << "(" << std::setw (width) << m[0][0] << + " " << std::setw (width) << m[0][1] << + " " << std::setw (width) << m[0][2] << + " " << std::setw (width) << m[0][3] << "\n" << + + " " << std::setw (width) << m[1][0] << + " " << std::setw (width) << m[1][1] << + " " << std::setw (width) << m[1][2] << + " " << std::setw (width) << m[1][3] << "\n" << + + " " << std::setw (width) << m[2][0] << + " " << std::setw (width) << m[2][1] << + " " << std::setw (width) << m[2][2] << + " " << std::setw (width) << m[2][3] << "\n" << + + " " << std::setw (width) << m[3][0] << + " " << std::setw (width) << m[3][1] << + " " << std::setw (width) << m[3][2] << + " " << std::setw (width) << m[3][3] << ")\n"; + + s.flags (oldFlags); + return s; +} + + +//--------------------------------------------------------------- +// Implementation of vector-times-matrix multiplication operators +//--------------------------------------------------------------- + +template +inline const Vec2 & +operator *= (Vec2 &v, const Matrix33 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]); + S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]); + + v.x = x / w; + v.y = y / w; + + return v; +} + +template +inline Vec2 +operator * (const Vec2 &v, const Matrix33 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]); + S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]); + + return Vec2 (x / w, y / w); +} + + +template +inline const Vec3 & +operator *= (Vec3 &v, const Matrix33 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]); + + v.x = x; + v.y = y; + v.z = z; + + return v; +} + +template +inline Vec3 +operator * (const Vec3 &v, const Matrix33 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]); + + return Vec3 (x, y, z); +} + + +template +inline const Vec3 & +operator *= (Vec3 &v, const Matrix44 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]); + S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]); + + v.x = x / w; + v.y = y / w; + v.z = z / w; + + return v; +} + +template +inline Vec3 +operator * (const Vec3 &v, const Matrix44 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]); + S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]); + + return Vec3 (x / w, y / w, z / w); +} + + +template +inline const Vec4 & +operator *= (Vec4 &v, const Matrix44 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]); + S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]); + + v.x = x; + v.y = y; + v.z = z; + v.w = w; + + return v; +} + +template +inline Vec4 +operator * (const Vec4 &v, const Matrix44 &m) +{ + S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]); + S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]); + S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]); + S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]); + + return Vec4 (x, y, z, w); +} + +} // namespace Imath + + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1251 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + + + +//---------------------------------------------------------------------------- +// +// Implementation of non-template items declared in ImathMatrixAlgo.h +// +//---------------------------------------------------------------------------- + +#include "ImathMatrixAlgo.h" +#include + +#if defined(OPENEXR_DLL) + #define EXPORT_CONST __declspec(dllexport) +#else + #define EXPORT_CONST const +#endif + +namespace Imath { + +EXPORT_CONST M33f identity33f ( 1, 0, 0, + 0, 1, 0, + 0, 0, 1); + +EXPORT_CONST M33d identity33d ( 1, 0, 0, + 0, 1, 0, + 0, 0, 1); + +EXPORT_CONST M44f identity44f ( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + +EXPORT_CONST M44d identity44d ( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + +namespace +{ + +class KahanSum +{ +public: + KahanSum() : _total(0), _correction(0) {} + + void + operator+= (const double val) + { + const double y = val - _correction; + const double t = _total + y; + _correction = (t - _total) - y; + _total = t; + } + + double get() const + { + return _total; + } + +private: + double _total; + double _correction; +}; + +} + +template +M44d +procrustesRotationAndTranslation (const Vec3* A, const Vec3* B, const T* weights, const size_t numPoints, const bool doScale) +{ + if (numPoints == 0) + return M44d(); + + // Always do the accumulation in double precision: + V3d Acenter (0.0); + V3d Bcenter (0.0); + double weightsSum = 0.0; + + if (weights == 0) + { + for (int i = 0; i < numPoints; ++i) + { + Acenter += (V3d) A[i]; + Bcenter += (V3d) B[i]; + } + weightsSum = (double) numPoints; + } + else + { + for (int i = 0; i < numPoints; ++i) + { + const double w = weights[i]; + weightsSum += w; + + Acenter += w * (V3d) A[i]; + Bcenter += w * (V3d) B[i]; + } + } + + if (weightsSum == 0) + return M44d(); + + Acenter /= weightsSum; + Bcenter /= weightsSum; + + // + // Find Q such that |Q*A - B| (actually A-Acenter and B-Bcenter, weighted) + // is minimized in the least squares sense. + // From Golub/Van Loan, p.601 + // + // A,B are 3xn + // Let C = B A^T (where A is 3xn and B^T is nx3, so C is 3x3) + // Compute the SVD: C = U D V^T (U,V rotations, D diagonal). + // Throw away the D part, and return Q = U V^T + M33d C (0.0); + if (weights == 0) + { + for (int i = 0; i < numPoints; ++i) + C += outerProduct ((V3d) B[i] - Bcenter, (V3d) A[i] - Acenter); + } + else + { + for (int i = 0; i < numPoints; ++i) + { + const double w = weights[i]; + C += outerProduct (w * ((V3d) B[i] - Bcenter), (V3d) A[i] - Acenter); + } + } + + M33d U, V; + V3d S; + jacobiSVD (C, U, S, V, Imath::limits::epsilon(), true); + + // We want Q.transposed() here since we are going to be using it in the + // Imath style (multiplying vectors on the right, v' = v*A^T): + const M33d Qt = V * U.transposed(); + + double s = 1.0; + if (doScale && numPoints > 1) + { + // Finding a uniform scale: let us assume the Q is completely fixed + // at this point (solving for both simultaneously seems much harder). + // We are trying to compute (again, per Golub and van Loan) + // min || s*A*Q - B ||_F + // Notice that we've jammed a uniform scale in front of the Q. + // Now, the Frobenius norm (the least squares norm over matrices) + // has the neat property that it is equivalent to minimizing the trace + // of M^T*M (see your friendly neighborhood linear algebra text for a + // derivation). Thus, we can expand this out as + // min tr (s*A*Q - B)^T*(s*A*Q - B) + // = min tr(Q^T*A^T*s*s*A*Q) + tr(B^T*B) - 2*tr(Q^T*A^T*s*B) by linearity of the trace + // = min s^2 tr(A^T*A) + tr(B^T*B) - 2*s*tr(Q^T*A^T*B) using the fact that the trace is invariant + // under similarity transforms Q*M*Q^T + // If we differentiate w.r.t. s and set this to 0, we get + // 0 = 2*s*tr(A^T*A) - 2*tr(Q^T*A^T*B) + // so + // 2*s*tr(A^T*A) = 2*s*tr(Q^T*A^T*B) + // s = tr(Q^T*A^T*B) / tr(A^T*A) + + KahanSum traceATA; + if (weights == 0) + { + for (int i = 0; i < numPoints; ++i) + traceATA += ((V3d) A[i] - Acenter).length2(); + } + else + { + for (int i = 0; i < numPoints; ++i) + traceATA += ((double) weights[i]) * ((V3d) A[i] - Acenter).length2(); + } + + KahanSum traceBATQ; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + traceBATQ += Qt[j][i] * C[i][j]; + + s = traceBATQ.get() / traceATA.get(); + } + + // Q is the rotation part of what we want to return. + // The entire transform is: + // (translate origin to Bcenter) * Q * (translate Acenter to origin) + // last first + // The effect of this on a point is: + // (translate origin to Bcenter) * Q * (translate Acenter to origin) * point + // = (translate origin to Bcenter) * Q * (-Acenter + point) + // = (translate origin to Bcenter) * (-Q*Acenter + Q*point) + // = (translate origin to Bcenter) * (translate Q*Acenter to origin) * Q*point + // = (translate Q*Acenter to Bcenter) * Q*point + // So what we want to return is: + // (translate Q*Acenter to Bcenter) * Q + // + // In block form, this is: + // [ 1 0 0 | ] [ 0 ] [ 1 0 0 | ] [ 1 0 0 | ] [ | ] [ ] + // [ 0 1 0 tb ] [ s*Q 0 ] [ 0 1 0 -ta ] = [ 0 1 0 tb ] [ s*Q -s*Q*ta ] = [ Q tb-s*Q*ta ] + // [ 0 0 1 | ] [ 0 ] [ 0 0 1 | ] [ 0 0 1 | ] [ | ] [ ] + // [ 0 0 0 1 ] [ 0 0 0 1 ] [ 0 0 0 1 ] [ 0 0 0 1 ] [ 0 0 0 1 ] [ 0 0 0 1 ] + // (ofc the whole thing is transposed for Imath). + const V3d translate = Bcenter - s*Acenter*Qt; + + return M44d (s*Qt.x[0][0], s*Qt.x[0][1], s*Qt.x[0][2], T(0), + s*Qt.x[1][0], s*Qt.x[1][1], s*Qt.x[1][2], T(0), + s*Qt.x[2][0], s*Qt.x[2][1], s*Qt.x[2][2], T(0), + translate.x, translate.y, translate.z, T(1)); +} // procrustesRotationAndTranslation + +template +M44d +procrustesRotationAndTranslation (const Vec3* A, const Vec3* B, const size_t numPoints, const bool doScale) +{ + return procrustesRotationAndTranslation (A, B, (const T*) 0, numPoints, doScale); +} // procrustesRotationAndTranslation + + +template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale); +template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale); +template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale); +template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, const size_t numPoints, const bool doScale); + + +namespace +{ + +// Applies the 2x2 Jacobi rotation +// [ c s 0 ] [ 1 0 0 ] [ c 0 s ] +// [ -s c 0 ] or [ 0 c s ] or [ 0 1 0 ] +// [ 0 0 1 ] [ 0 -s c ] [ -s 0 c ] +// from the right; that is, computes +// J * A +// for the Jacobi rotation J and the matrix A. This is efficient because we +// only need to touch exactly the 2 columns that are affected, so we never +// need to explicitly construct the J matrix. +template +void +jacobiRotateRight (Imath::Matrix33& A, + const T c, + const T s) +{ + for (int i = 0; i < 3; ++i) + { + const T tau1 = A[i][j]; + const T tau2 = A[i][k]; + A[i][j] = c * tau1 - s * tau2; + A[i][k] = s * tau1 + c * tau2; + } +} + +template +void +jacobiRotateRight (Imath::Matrix44& A, + const int j, + const int k, + const T c, + const T s) +{ + for (int i = 0; i < 4; ++i) + { + const T tau1 = A[i][j]; + const T tau2 = A[i][k]; + A[i][j] = c * tau1 - s * tau2; + A[i][k] = s * tau1 + c * tau2; + } +} + +// This routine solves the 2x2 SVD: +// [ c1 s1 ] [ w x ] [ c2 s2 ] [ d1 0 ] +// [ ] [ ] [ ] = [ ] +// [ -s1 c1 ] [ y z ] [ -s2 c2 ] [ 0 d2 ] +// where +// [ w x ] +// A = [ ] +// [ y z ] +// is the subset of A consisting of the [j,k] entries, A([j k], [j k]) in +// Matlab parlance. The method is the 'USVD' algorithm described in the +// following paper: +// 'Computation of the Singular Value Decomposition using Mesh-Connected Processors' +// by Richard P. Brent, Franklin T. Luk, and Charles Van Loan +// It breaks the computation into two steps: the first symmetrizes the matrix, +// and the second diagonalizes the symmetric matrix. +template +bool +twoSidedJacobiRotation (Imath::Matrix33& A, + Imath::Matrix33& U, + Imath::Matrix33& V, + const T tol) +{ + // Load everything into local variables to make things easier on the + // optimizer: + const T w = A[j][j]; + const T x = A[j][k]; + const T y = A[k][j]; + const T z = A[k][k]; + + // We will keep track of whether we're actually performing any rotations, + // since if the matrix is already diagonal we'll end up with the identity + // as our Jacobi rotation and we can short-circuit. + bool changed = false; + + // The first step is to symmetrize the 2x2 matrix, + // [ c s ]^T [ w x ] = [ p q ] + // [ -s c ] [ y z ] [ q r ] + T mu_1 = w + z; + T mu_2 = x - y; + + T c, s; + if (std::abs(mu_2) <= tol*std::abs(mu_1)) // Already symmetric (to tolerance) + { // Note that the <= is important here + c = T(1); // because we want to bypass the computation + s = T(0); // of rho if mu_1 = mu_2 = 0. + + const T p = w; + const T r = z; + mu_1 = r - p; + mu_2 = x + y; + } + else + { + const T rho = mu_1 / mu_2; + s = T(1) / std::sqrt (T(1) + rho*rho); // TODO is there a native inverse square root function? + if (rho < 0) + s = -s; + c = s * rho; + + mu_1 = s * (x + y) + c * (z - w); // = r - p + mu_2 = T(2) * (c * x - s * z); // = 2*q + + changed = true; + } + + // The second stage diagonalizes, + // [ c2 s2 ]^T [ p q ] [ c2 s2 ] = [ d1 0 ] + // [ -s2 c2 ] [ q r ] [ -s2 c2 ] [ 0 d2 ] + T c_2, s_2; + if (std::abs(mu_2) <= tol*std::abs(mu_1)) + { + c_2 = T(1); + s_2 = T(0); + } + else + { + const T rho_2 = mu_1 / mu_2; + T t_2 = T(1) / (std::abs(rho_2) + std::sqrt(1 + rho_2*rho_2)); + if (rho_2 < 0) + t_2 = -t_2; + c_2 = T(1) / std::sqrt (T(1) + t_2*t_2); + s_2 = c_2 * t_2; + + changed = true; + } + + const T c_1 = c_2 * c - s_2 * s; + const T s_1 = s_2 * c + c_2 * s; + + if (!changed) + { + // We've decided that the off-diagonal entries are already small + // enough, so we'll set them to zero. This actually appears to result + // in smaller errors than leaving them be, possibly because it prevents + // us from trying to do extra rotations later that we don't need. + A[k][j] = 0; + A[j][k] = 0; + return false; + } + + const T d_1 = c_1*(w*c_2 - x*s_2) - s_1*(y*c_2 - z*s_2); + const T d_2 = s_1*(w*s_2 + x*c_2) + c_1*(y*s_2 + z*c_2); + + // For the entries we just zeroed out, we'll just set them to 0, since + // they should be 0 up to machine precision. + A[j][j] = d_1; + A[k][k] = d_2; + A[k][j] = 0; + A[j][k] = 0; + + // Rotate the entries that _weren't_ involved in the 2x2 SVD: + { + // Rotate on the left by + // [ c1 s1 0 ]^T [ c1 0 s1 ]^T [ 1 0 0 ]^T + // [ -s1 c1 0 ] or [ 0 1 0 ] or [ 0 c1 s1 ] + // [ 0 0 1 ] [ -s1 0 c1 ] [ 0 -s1 c1 ] + // This has the effect of adding the (weighted) ith and jth _rows_ to + // each other. + const T tau1 = A[j][l]; + const T tau2 = A[k][l]; + A[j][l] = c_1 * tau1 - s_1 * tau2; + A[k][l] = s_1 * tau1 + c_1 * tau2; + } + + { + // Rotate on the right by + // [ c2 s2 0 ] [ c2 0 s2 ] [ 1 0 0 ] + // [ -s2 c2 0 ] or [ 0 1 0 ] or [ 0 c2 s2 ] + // [ 0 0 1 ] [ -s2 0 c2 ] [ 0 -s2 c2 ] + // This has the effect of adding the (weighted) ith and jth _columns_ to + // each other. + const T tau1 = A[l][j]; + const T tau2 = A[l][k]; + A[l][j] = c_2 * tau1 - s_2 * tau2; + A[l][k] = s_2 * tau1 + c_2 * tau2; + } + + // Now apply the rotations to U and V: + // Remember that we have + // R1^T * A * R2 = D + // This is in the 2x2 case, but after doing a bunch of these + // we will get something like this for the 3x3 case: + // ... R1b^T * R1a^T * A * R2a * R2b * ... = D + // ----------------- --------------- + // = U^T = V + // So, + // U = R1a * R1b * ... + // V = R2a * R2b * ... + jacobiRotateRight (U, c_1, s_1); + jacobiRotateRight (V, c_2, s_2); + + return true; +} + +template +bool +twoSidedJacobiRotation (Imath::Matrix44& A, + int j, + int k, + Imath::Matrix44& U, + Imath::Matrix44& V, + const T tol) +{ + // Load everything into local variables to make things easier on the + // optimizer: + const T w = A[j][j]; + const T x = A[j][k]; + const T y = A[k][j]; + const T z = A[k][k]; + + // We will keep track of whether we're actually performing any rotations, + // since if the matrix is already diagonal we'll end up with the identity + // as our Jacobi rotation and we can short-circuit. + bool changed = false; + + // The first step is to symmetrize the 2x2 matrix, + // [ c s ]^T [ w x ] = [ p q ] + // [ -s c ] [ y z ] [ q r ] + T mu_1 = w + z; + T mu_2 = x - y; + + T c, s; + if (std::abs(mu_2) <= tol*std::abs(mu_1)) // Already symmetric (to tolerance) + { // Note that the <= is important here + c = T(1); // because we want to bypass the computation + s = T(0); // of rho if mu_1 = mu_2 = 0. + + const T p = w; + const T r = z; + mu_1 = r - p; + mu_2 = x + y; + } + else + { + const T rho = mu_1 / mu_2; + s = T(1) / std::sqrt (T(1) + rho*rho); // TODO is there a native inverse square root function? + if (rho < 0) + s = -s; + c = s * rho; + + mu_1 = s * (x + y) + c * (z - w); // = r - p + mu_2 = T(2) * (c * x - s * z); // = 2*q + + changed = true; + } + + // The second stage diagonalizes, + // [ c2 s2 ]^T [ p q ] [ c2 s2 ] = [ d1 0 ] + // [ -s2 c2 ] [ q r ] [ -s2 c2 ] [ 0 d2 ] + T c_2, s_2; + if (std::abs(mu_2) <= tol*std::abs(mu_1)) + { + c_2 = T(1); + s_2 = T(0); + } + else + { + const T rho_2 = mu_1 / mu_2; + T t_2 = T(1) / (std::abs(rho_2) + std::sqrt(1 + rho_2*rho_2)); + if (rho_2 < 0) + t_2 = -t_2; + c_2 = T(1) / std::sqrt (T(1) + t_2*t_2); + s_2 = c_2 * t_2; + + changed = true; + } + + const T c_1 = c_2 * c - s_2 * s; + const T s_1 = s_2 * c + c_2 * s; + + if (!changed) + { + // We've decided that the off-diagonal entries are already small + // enough, so we'll set them to zero. This actually appears to result + // in smaller errors than leaving them be, possibly because it prevents + // us from trying to do extra rotations later that we don't need. + A[k][j] = 0; + A[j][k] = 0; + return false; + } + + const T d_1 = c_1*(w*c_2 - x*s_2) - s_1*(y*c_2 - z*s_2); + const T d_2 = s_1*(w*s_2 + x*c_2) + c_1*(y*s_2 + z*c_2); + + // For the entries we just zeroed out, we'll just set them to 0, since + // they should be 0 up to machine precision. + A[j][j] = d_1; + A[k][k] = d_2; + A[k][j] = 0; + A[j][k] = 0; + + // Rotate the entries that _weren't_ involved in the 2x2 SVD: + for (int l = 0; l < 4; ++l) + { + if (l == j || l == k) + continue; + + // Rotate on the left by + // [ 1 ] + // [ . ] + // [ c2 s2 ] j + // [ 1 ] + // [ -s2 c2 ] k + // [ . ] + // [ 1 ] + // j k + // + // This has the effect of adding the (weighted) ith and jth _rows_ to + // each other. + const T tau1 = A[j][l]; + const T tau2 = A[k][l]; + A[j][l] = c_1 * tau1 - s_1 * tau2; + A[k][l] = s_1 * tau1 + c_1 * tau2; + } + + for (int l = 0; l < 4; ++l) + { + // We set the A[j/k][j/k] entries already + if (l == j || l == k) + continue; + + // Rotate on the right by + // [ 1 ] + // [ . ] + // [ c2 s2 ] j + // [ 1 ] + // [ -s2 c2 ] k + // [ . ] + // [ 1 ] + // j k + // + // This has the effect of adding the (weighted) ith and jth _columns_ to + // each other. + const T tau1 = A[l][j]; + const T tau2 = A[l][k]; + A[l][j] = c_2 * tau1 - s_2 * tau2; + A[l][k] = s_2 * tau1 + c_2 * tau2; + } + + // Now apply the rotations to U and V: + // Remember that we have + // R1^T * A * R2 = D + // This is in the 2x2 case, but after doing a bunch of these + // we will get something like this for the 3x3 case: + // ... R1b^T * R1a^T * A * R2a * R2b * ... = D + // ----------------- --------------- + // = U^T = V + // So, + // U = R1a * R1b * ... + // V = R2a * R2b * ... + jacobiRotateRight (U, j, k, c_1, s_1); + jacobiRotateRight (V, j, k, c_2, s_2); + + return true; +} + +template +void +swapColumns (Imath::Matrix33& A, int j, int k) +{ + for (int i = 0; i < 3; ++i) + std::swap (A[i][j], A[i][k]); +} + +template +T +maxOffDiag (const Imath::Matrix33& A) +{ + T result = 0; + result = std::max (result, std::abs (A[0][1])); + result = std::max (result, std::abs (A[0][2])); + result = std::max (result, std::abs (A[1][0])); + result = std::max (result, std::abs (A[1][2])); + result = std::max (result, std::abs (A[2][0])); + result = std::max (result, std::abs (A[2][1])); + return result; +} + +template +T +maxOffDiag (const Imath::Matrix44& A) +{ + T result = 0; + for (int i = 0; i < 4; ++i) + { + for (int j = 0; j < 4; ++j) + { + if (i != j) + result = std::max (result, std::abs (A[i][j])); + } + } + + return result; +} + +template +void +twoSidedJacobiSVD (Imath::Matrix33 A, + Imath::Matrix33& U, + Imath::Vec3& S, + Imath::Matrix33& V, + const T tol, + const bool forcePositiveDeterminant) +{ + // The two-sided Jacobi SVD works by repeatedly zeroing out + // off-diagonal entries of the matrix, 2 at a time. Basically, + // we can take our 3x3 matrix, + // [* * *] + // [* * *] + // [* * *] + // and use a pair of orthogonal transforms to zero out, say, the + // pair of entries (0, 1) and (1, 0): + // [ c1 s1 ] [* * *] [ c2 s2 ] [* *] + // [-s1 c1 ] [* * *] [-s2 c2 ] = [ * *] + // [ 1] [* * *] [ 1] [* * *] + // When we go to zero out the next pair of entries (say, (0, 2) and (2, 0)) + // then we don't expect those entries to stay 0: + // [ c1 s1 ] [* *] [ c2 s2 ] [* * ] + // [-s1 c1 ] [ * *] [-s2 c2 ] = [* * *] + // [ 1] [* * *] [ 1] [ * *] + // However, if we keep doing this, we'll find that the off-diagonal entries + // converge to 0 fairly quickly (convergence should be roughly cubic). The + // result is a diagonal A matrix and a bunch of orthogonal transforms: + // [* * *] [* ] + // L1 L2 ... Ln [* * *] Rn ... R2 R1 = [ * ] + // [* * *] [ *] + // ------------ ------- ------------ ------- + // U^T A V S + // This turns out to be highly accurate because (1) orthogonal transforms + // are extremely stable to compute and apply (this is why QR factorization + // works so well, FWIW) and because (2) by applying everything to the original + // matrix A instead of computing (A^T * A) we avoid any precision loss that + // would result from that. + U.makeIdentity(); + V.makeIdentity(); + + const int maxIter = 20; // In case we get really unlucky, prevents infinite loops + const T absTol = tol * maxOffDiag (A); // Tolerance is in terms of the maximum + if (absTol != 0) // _off-diagonal_ entry. + { + int numIter = 0; + do + { + ++numIter; + bool changed = twoSidedJacobiRotation (A, U, V, tol); + changed = twoSidedJacobiRotation (A, U, V, tol) || changed; + changed = twoSidedJacobiRotation (A, U, V, tol) || changed; + if (!changed) + break; + } while (maxOffDiag(A) > absTol && numIter < maxIter); + } + + // The off-diagonal entries are (effectively) 0, so whatever's left on the + // diagonal are the singular values: + S.x = A[0][0]; + S.y = A[1][1]; + S.z = A[2][2]; + + // Nothing thus far has guaranteed that the singular values are positive, + // so let's go back through and flip them if not (since by contract we are + // supposed to return all positive SVs): + for (int i = 0; i < 3; ++i) + { + if (S[i] < 0) + { + // If we flip S[i], we need to flip the corresponding column of U + // (we could also pick V if we wanted; it doesn't really matter): + S[i] = -S[i]; + for (int j = 0; j < 3; ++j) + U[j][i] = -U[j][i]; + } + } + + // Order the singular values from largest to smallest; this requires + // exactly two passes through the data using bubble sort: + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < (2 - i); ++j) + { + // No absolute values necessary since we already ensured that + // they're positive: + if (S[j] < S[j+1]) + { + // If we swap singular values we also have to swap + // corresponding columns in U and V: + std::swap (S[j], S[j+1]); + swapColumns (U, j, j+1); + swapColumns (V, j, j+1); + } + } + } + + if (forcePositiveDeterminant) + { + // We want to guarantee that the returned matrices always have positive + // determinant. We can do this by adding the appropriate number of + // matrices of the form: + // [ 1 ] + // L = [ 1 ] + // [ -1 ] + // Note that L' = L and L*L = Identity. Thus we can add: + // U*L*L*S*V = (U*L)*(L*S)*V + // if U has a negative determinant, and + // U*S*L*L*V = U*(S*L)*(L*V) + // if V has a neg. determinant. + if (U.determinant() < 0) + { + for (int i = 0; i < 3; ++i) + U[i][2] = -U[i][2]; + S.z = -S.z; + } + + if (V.determinant() < 0) + { + for (int i = 0; i < 3; ++i) + V[i][2] = -V[i][2]; + S.z = -S.z; + } + } +} + +template +void +twoSidedJacobiSVD (Imath::Matrix44 A, + Imath::Matrix44& U, + Imath::Vec4& S, + Imath::Matrix44& V, + const T tol, + const bool forcePositiveDeterminant) +{ + // Please see the Matrix33 version for a detailed description of the algorithm. + U.makeIdentity(); + V.makeIdentity(); + + const int maxIter = 20; // In case we get really unlucky, prevents infinite loops + const T absTol = tol * maxOffDiag (A); // Tolerance is in terms of the maximum + if (absTol != 0) // _off-diagonal_ entry. + { + int numIter = 0; + do + { + ++numIter; + bool changed = twoSidedJacobiRotation (A, 0, 1, U, V, tol); + changed = twoSidedJacobiRotation (A, 0, 2, U, V, tol) || changed; + changed = twoSidedJacobiRotation (A, 0, 3, U, V, tol) || changed; + changed = twoSidedJacobiRotation (A, 1, 2, U, V, tol) || changed; + changed = twoSidedJacobiRotation (A, 1, 3, U, V, tol) || changed; + changed = twoSidedJacobiRotation (A, 2, 3, U, V, tol) || changed; + if (!changed) + break; + } while (maxOffDiag(A) > absTol && numIter < maxIter); + } + + // The off-diagonal entries are (effectively) 0, so whatever's left on the + // diagonal are the singular values: + S[0] = A[0][0]; + S[1] = A[1][1]; + S[2] = A[2][2]; + S[3] = A[3][3]; + + // Nothing thus far has guaranteed that the singular values are positive, + // so let's go back through and flip them if not (since by contract we are + // supposed to return all positive SVs): + for (int i = 0; i < 4; ++i) + { + if (S[i] < 0) + { + // If we flip S[i], we need to flip the corresponding column of U + // (we could also pick V if we wanted; it doesn't really matter): + S[i] = -S[i]; + for (int j = 0; j < 4; ++j) + U[j][i] = -U[j][i]; + } + } + + // Order the singular values from largest to smallest using insertion sort: + for (int i = 1; i < 4; ++i) + { + const Imath::Vec4 uCol (U[0][i], U[1][i], U[2][i], U[3][i]); + const Imath::Vec4 vCol (V[0][i], V[1][i], V[2][i], V[3][i]); + const T sVal = S[i]; + + int j = i - 1; + while (std::abs (S[j]) < std::abs (sVal)) + { + for (int k = 0; k < 4; ++k) + U[k][j+1] = U[k][j]; + for (int k = 0; k < 4; ++k) + V[k][j+1] = V[k][j]; + S[j+1] = S[j]; + + --j; + if (j < 0) + break; + } + + for (int k = 0; k < 4; ++k) + U[k][j+1] = uCol[k]; + for (int k = 0; k < 4; ++k) + V[k][j+1] = vCol[k]; + S[j+1] = sVal; + } + + if (forcePositiveDeterminant) + { + // We want to guarantee that the returned matrices always have positive + // determinant. We can do this by adding the appropriate number of + // matrices of the form: + // [ 1 ] + // L = [ 1 ] + // [ 1 ] + // [ -1 ] + // Note that L' = L and L*L = Identity. Thus we can add: + // U*L*L*S*V = (U*L)*(L*S)*V + // if U has a negative determinant, and + // U*S*L*L*V = U*(S*L)*(L*V) + // if V has a neg. determinant. + if (U.determinant() < 0) + { + for (int i = 0; i < 4; ++i) + U[i][3] = -U[i][3]; + S[3] = -S[3]; + } + + if (V.determinant() < 0) + { + for (int i = 0; i < 4; ++i) + V[i][3] = -V[i][3]; + S[3] = -S[3]; + } + } +} + +} + +template +void +jacobiSVD (const Imath::Matrix33& A, + Imath::Matrix33& U, + Imath::Vec3& S, + Imath::Matrix33& V, + const T tol, + const bool forcePositiveDeterminant) +{ + twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant); +} + +template +void +jacobiSVD (const Imath::Matrix44& A, + Imath::Matrix44& U, + Imath::Vec4& S, + Imath::Matrix44& V, + const T tol, + const bool forcePositiveDeterminant) +{ + twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant); +} + +template void jacobiSVD (const Imath::Matrix33& A, + Imath::Matrix33& U, + Imath::Vec3& S, + Imath::Matrix33& V, + const float tol, + const bool forcePositiveDeterminant); +template void jacobiSVD (const Imath::Matrix33& A, + Imath::Matrix33& U, + Imath::Vec3& S, + Imath::Matrix33& V, + const double tol, + const bool forcePositiveDeterminant); +template void jacobiSVD (const Imath::Matrix44& A, + Imath::Matrix44& U, + Imath::Vec4& S, + Imath::Matrix44& V, + const float tol, + const bool forcePositiveDeterminant); +template void jacobiSVD (const Imath::Matrix44& A, + Imath::Matrix44& U, + Imath::Vec4& S, + Imath::Matrix44& V, + const double tol, + const bool forcePositiveDeterminant); + +namespace +{ + +template +inline +void +jacobiRotateRight (TM& A, + const typename TM::BaseType s, + const typename TM::BaseType tau) +{ + typedef typename TM::BaseType T; + + for (unsigned int i = 0; i < TM::dimensions(); ++i) + { + const T nu1 = A[i][j]; + const T nu2 = A[i][k]; + A[i][j] -= s * (nu2 + tau * nu1); + A[i][k] += s * (nu1 - tau * nu2); + } +} + +template +bool +jacobiRotation (Matrix33& A, + Matrix33& V, + Vec3& Z, + const T tol) +{ + // Load everything into local variables to make things easier on the + // optimizer: + const T x = A[j][j]; + const T y = A[j][k]; + const T z = A[k][k]; + + // The first stage diagonalizes, + // [ c s ]^T [ x y ] [ c -s ] = [ d1 0 ] + // [ -s c ] [ y z ] [ s c ] [ 0 d2 ] + const T mu1 = z - x; + const T mu2 = 2 * y; + + if (std::abs(mu2) <= tol*std::abs(mu1)) + { + // We've decided that the off-diagonal entries are already small + // enough, so we'll set them to zero. This actually appears to result + // in smaller errors than leaving them be, possibly because it prevents + // us from trying to do extra rotations later that we don't need. + A[j][k] = 0; + return false; + } + const T rho = mu1 / mu2; + const T t = (rho < 0 ? T(-1) : T(1)) / (std::abs(rho) + std::sqrt(1 + rho*rho)); + const T c = T(1) / std::sqrt (T(1) + t*t); + const T s = t * c; + const T tau = s / (T(1) + c); + const T h = t * y; + + // Update diagonal elements. + Z[j] -= h; + Z[k] += h; + A[j][j] -= h; + A[k][k] += h; + + // For the entries we just zeroed out, we'll just set them to 0, since + // they should be 0 up to machine precision. + A[j][k] = 0; + + // We only update upper triagnular elements of A, since + // A is supposed to be symmetric. + T& offd1 = l < j ? A[l][j] : A[j][l]; + T& offd2 = l < k ? A[l][k] : A[k][l]; + const T nu1 = offd1; + const T nu2 = offd2; + offd1 = nu1 - s * (nu2 + tau * nu1); + offd2 = nu2 + s * (nu1 - tau * nu2); + + // Apply rotation to V + jacobiRotateRight (V, s, tau); + + return true; +} + +template +bool +jacobiRotation (Matrix44& A, + Matrix44& V, + Vec4& Z, + const T tol) +{ + const T x = A[j][j]; + const T y = A[j][k]; + const T z = A[k][k]; + + const T mu1 = z - x; + const T mu2 = T(2) * y; + + // Let's see if rho^(-1) = mu2 / mu1 is less than tol + // This test also checks if rho^2 will overflow + // when tol^(-1) < sqrt(limits::max()). + if (std::abs(mu2) <= tol*std::abs(mu1)) + { + A[j][k] = 0; + return true; + } + + const T rho = mu1 / mu2; + const T t = (rho < 0 ? T(-1) : T(1)) / (std::abs(rho) + std::sqrt(1 + rho*rho)); + const T c = T(1) / std::sqrt (T(1) + t*t); + const T s = c * t; + const T tau = s / (T(1) + c); + const T h = t * y; + + Z[j] -= h; + Z[k] += h; + A[j][j] -= h; + A[k][k] += h; + A[j][k] = 0; + + { + T& offd1 = l1 < j ? A[l1][j] : A[j][l1]; + T& offd2 = l1 < k ? A[l1][k] : A[k][l1]; + const T nu1 = offd1; + const T nu2 = offd2; + offd1 -= s * (nu2 + tau * nu1); + offd2 += s * (nu1 - tau * nu2); + } + + { + T& offd1 = l2 < j ? A[l2][j] : A[j][l2]; + T& offd2 = l2 < k ? A[l2][k] : A[k][l2]; + const T nu1 = offd1; + const T nu2 = offd2; + offd1 -= s * (nu2 + tau * nu1); + offd2 += s * (nu1 - tau * nu2); + } + + jacobiRotateRight (V, s, tau); + + return true; +} + +template +inline +typename TM::BaseType +maxOffDiagSymm (const TM& A) +{ + typedef typename TM::BaseType T; + T result = 0; + for (unsigned int i = 0; i < TM::dimensions(); ++i) + for (unsigned int j = i+1; j < TM::dimensions(); ++j) + result = std::max (result, std::abs (A[i][j])); + + return result; +} + +} // namespace + +template +void +jacobiEigenSolver (Matrix33& A, + Vec3& S, + Matrix33& V, + const T tol) +{ + V.makeIdentity(); + for(int i = 0; i < 3; ++i) { + S[i] = A[i][i]; + } + + const int maxIter = 20; // In case we get really unlucky, prevents infinite loops + const T absTol = tol * maxOffDiagSymm (A); // Tolerance is in terms of the maximum + if (absTol != 0) // _off-diagonal_ entry. + { + int numIter = 0; + do + { + // Z is for accumulating small changes (h) to diagonal entries + // of A for one sweep. Adding h's directly to A might cause + // a cancellation effect when h is relatively very small to + // the corresponding diagonal entry of A and + // this will increase numerical errors + Vec3 Z(0, 0, 0); + ++numIter; + bool changed = jacobiRotation<0, 1, 2> (A, V, Z, tol); + changed = jacobiRotation<0, 2, 1> (A, V, Z, tol) || changed; + changed = jacobiRotation<1, 2, 0> (A, V, Z, tol) || changed; + // One sweep passed. Add accumulated changes (Z) to singular values (S) + // Update diagonal elements of A for better accuracy as well. + for(int i = 0; i < 3; ++i) { + A[i][i] = S[i] += Z[i]; + } + if (!changed) + break; + } while (maxOffDiagSymm(A) > absTol && numIter < maxIter); + } +} + +template +void +jacobiEigenSolver (Matrix44& A, + Vec4& S, + Matrix44& V, + const T tol) +{ + V.makeIdentity(); + + for(int i = 0; i < 4; ++i) { + S[i] = A[i][i]; + } + + const int maxIter = 20; // In case we get really unlucky, prevents infinite loops + const T absTol = tol * maxOffDiagSymm (A); // Tolerance is in terms of the maximum + if (absTol != 0) // _off-diagonal_ entry. + { + int numIter = 0; + do + { + ++numIter; + Vec4 Z(0, 0, 0, 0); + bool changed = jacobiRotation<0, 1, 2, 3> (A, V, Z, tol); + changed = jacobiRotation<0, 2, 1, 3> (A, V, Z, tol) || changed; + changed = jacobiRotation<0, 3, 1, 2> (A, V, Z, tol) || changed; + changed = jacobiRotation<1, 2, 0, 3> (A, V, Z, tol) || changed; + changed = jacobiRotation<1, 3, 0, 2> (A, V, Z, tol) || changed; + changed = jacobiRotation<2, 3, 0, 1> (A, V, Z, tol) || changed; + for(int i = 0; i < 4; ++i) { + A[i][i] = S[i] += Z[i]; + } + if (!changed) + break; + } while (maxOffDiagSymm(A) > absTol && numIter < maxIter); + } +} + +template +void +maxEigenVector (TM& A, TV& V) +{ + TV S; + TM MV; + jacobiEigenSolver(A, S, MV); + + int maxIdx(0); + for(unsigned int i = 1; i < TV::dimensions(); ++i) + { + if(std::abs(S[i]) > std::abs(S[maxIdx])) + maxIdx = i; + } + + for(unsigned int i = 0; i < TV::dimensions(); ++i) + V[i] = MV[i][maxIdx]; +} + +template +void +minEigenVector (TM& A, TV& V) +{ + TV S; + TM MV; + jacobiEigenSolver(A, S, MV); + + int minIdx(0); + for(unsigned int i = 1; i < TV::dimensions(); ++i) + { + if(std::abs(S[i]) < std::abs(S[minIdx])) + minIdx = i; + } + + for(unsigned int i = 0; i < TV::dimensions(); ++i) + V[i] = MV[i][minIdx]; +} + +template void jacobiEigenSolver (Matrix33& A, + Vec3& S, + Matrix33& V, + const float tol); +template void jacobiEigenSolver (Matrix33& A, + Vec3& S, + Matrix33& V, + const double tol); +template void jacobiEigenSolver (Matrix44& A, + Vec4& S, + Matrix44& V, + const float tol); +template void jacobiEigenSolver (Matrix44& A, + Vec4& S, + Matrix44& V, + const double tol); + +template void maxEigenVector (Matrix33& A, + Vec3& S); +template void maxEigenVector (Matrix44& A, + Vec4& S); +template void maxEigenVector (Matrix33& A, + Vec3& S); +template void maxEigenVector (Matrix44& A, + Vec4& S); + +template void minEigenVector (Matrix33& A, + Vec3& S); +template void minEigenVector (Matrix44& A, + Vec4& S); +template void minEigenVector (Matrix33& A, + Vec3& S); +template void minEigenVector (Matrix44& A, + Vec4& S); + +} // namespace Imath diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathMatrixAlgo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1435 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATHMATRIXALGO_H +#define INCLUDED_IMATHMATRIXALGO_H + +//------------------------------------------------------------------------- +// +// This file contains algorithms applied to or in conjunction with +// transformation matrices (Imath::Matrix33 and Imath::Matrix44). +// The assumption made is that these functions are called much less +// often than the basic point functions or these functions require +// more support classes. +// +// This file also defines a few predefined constant matrices. +// +//------------------------------------------------------------------------- + +#include "ImathMatrix.h" +#include "ImathQuat.h" +#include "ImathEuler.h" +#include "ImathExc.h" +#include "ImathVec.h" +#include "ImathLimits.h" +#include + + +#ifdef OPENEXR_DLL + #ifdef IMATH_EXPORTS + #define IMATH_EXPORT_CONST extern __declspec(dllexport) + #else + #define IMATH_EXPORT_CONST extern __declspec(dllimport) + #endif +#else + #define IMATH_EXPORT_CONST extern const +#endif + + +namespace Imath { + +//------------------ +// Identity matrices +//------------------ + +IMATH_EXPORT_CONST M33f identity33f; +IMATH_EXPORT_CONST M44f identity44f; +IMATH_EXPORT_CONST M33d identity33d; +IMATH_EXPORT_CONST M44d identity44d; + +//---------------------------------------------------------------------- +// Extract scale, shear, rotation, and translation values from a matrix: +// +// Notes: +// +// This implementation follows the technique described in the paper by +// Spencer W. Thomas in the Graphics Gems II article: "Decomposing a +// Matrix into Simple Transformations", p. 320. +// +// - Some of the functions below have an optional exc parameter +// that determines the functions' behavior when the matrix' +// scaling is very close to zero: +// +// If exc is true, the functions throw an Imath::ZeroScale exception. +// +// If exc is false: +// +// extractScaling (m, s) returns false, s is invalid +// sansScaling (m) returns m +// removeScaling (m) returns false, m is unchanged +// sansScalingAndShear (m) returns m +// removeScalingAndShear (m) returns false, m is unchanged +// extractAndRemoveScalingAndShear (m, s, h) +// returns false, m is unchanged, +// (sh) are invalid +// checkForZeroScaleInRow () returns false +// extractSHRT (m, s, h, r, t) returns false, (shrt) are invalid +// +// - Functions extractEuler(), extractEulerXYZ() and extractEulerZYX() +// assume that the matrix does not include shear or non-uniform scaling, +// but they do not examine the matrix to verify this assumption. +// Matrices with shear or non-uniform scaling are likely to produce +// meaningless results. Therefore, you should use the +// removeScalingAndShear() routine, if necessary, prior to calling +// extractEuler...() . +// +// - All functions assume that the matrix does not include perspective +// transformation(s), but they do not examine the matrix to verify +// this assumption. Matrices with perspective transformations are +// likely to produce meaningless results. +// +//---------------------------------------------------------------------- + + +// +// Declarations for 4x4 matrix. +// + +template bool extractScaling + (const Matrix44 &mat, + Vec3 &scl, + bool exc = true); + +template Matrix44 sansScaling (const Matrix44 &mat, + bool exc = true); + +template bool removeScaling + (Matrix44 &mat, + bool exc = true); + +template bool extractScalingAndShear + (const Matrix44 &mat, + Vec3 &scl, + Vec3 &shr, + bool exc = true); + +template Matrix44 sansScalingAndShear + (const Matrix44 &mat, + bool exc = true); + +template void sansScalingAndShear + (Matrix44 &result, + const Matrix44 &mat, + bool exc = true); + +template bool removeScalingAndShear + (Matrix44 &mat, + bool exc = true); + +template bool extractAndRemoveScalingAndShear + (Matrix44 &mat, + Vec3 &scl, + Vec3 &shr, + bool exc = true); + +template void extractEulerXYZ + (const Matrix44 &mat, + Vec3 &rot); + +template void extractEulerZYX + (const Matrix44 &mat, + Vec3 &rot); + +template Quat extractQuat (const Matrix44 &mat); + +template bool extractSHRT + (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Vec3 &r, + Vec3 &t, + bool exc /*= true*/, + typename Euler::Order rOrder); + +template bool extractSHRT + (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Vec3 &r, + Vec3 &t, + bool exc = true); + +template bool extractSHRT + (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Euler &r, + Vec3 &t, + bool exc = true); + +// +// Internal utility function. +// + +template bool checkForZeroScaleInRow + (const T &scl, + const Vec3 &row, + bool exc = true); + +template Matrix44 outerProduct + ( const Vec4 &a, + const Vec4 &b); + + +// +// Returns a matrix that rotates "fromDirection" vector to "toDirection" +// vector. +// + +template Matrix44 rotationMatrix (const Vec3 &fromDirection, + const Vec3 &toDirection); + + + +// +// Returns a matrix that rotates the "fromDir" vector +// so that it points towards "toDir". You may also +// specify that you want the up vector to be pointing +// in a certain direction "upDir". +// + +template Matrix44 rotationMatrixWithUpDir + (const Vec3 &fromDir, + const Vec3 &toDir, + const Vec3 &upDir); + + +// +// Constructs a matrix that rotates the z-axis so that it +// points towards "targetDir". You must also specify +// that you want the up vector to be pointing in a +// certain direction "upDir". +// +// Notes: The following degenerate cases are handled: +// (a) when the directions given by "toDir" and "upDir" +// are parallel or opposite; +// (the direction vectors must have a non-zero cross product) +// (b) when any of the given direction vectors have zero length +// + +template void alignZAxisWithTargetDir + (Matrix44 &result, + Vec3 targetDir, + Vec3 upDir); + + +// Compute an orthonormal direct frame from : a position, an x axis direction and a normal to the y axis +// If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis. +// Inputs are : +// -the position of the frame +// -the x axis direction of the frame +// -a normal to the y axis of the frame +// Return is the orthonormal frame +template Matrix44 computeLocalFrame( const Vec3& p, + const Vec3& xDir, + const Vec3& normal); + +// Add a translate/rotate/scale offset to an input frame +// and put it in another frame of reference +// Inputs are : +// - input frame +// - translate offset +// - rotate offset in degrees +// - scale offset +// - frame of reference +// Output is the offsetted frame +template Matrix44 addOffset( const Matrix44& inMat, + const Vec3& tOffset, + const Vec3& rOffset, + const Vec3& sOffset, + const Vec3& ref); + +// Compute Translate/Rotate/Scale matrix from matrix A with the Rotate/Scale of Matrix B +// Inputs are : +// -keepRotateA : if true keep rotate from matrix A, use B otherwise +// -keepScaleA : if true keep scale from matrix A, use B otherwise +// -Matrix A +// -Matrix B +// Return Matrix A with tweaked rotation/scale +template Matrix44 computeRSMatrix( bool keepRotateA, + bool keepScaleA, + const Matrix44& A, + const Matrix44& B); + + +//---------------------------------------------------------------------- + + +// +// Declarations for 3x3 matrix. +// + + +template bool extractScaling + (const Matrix33 &mat, + Vec2 &scl, + bool exc = true); + +template Matrix33 sansScaling (const Matrix33 &mat, + bool exc = true); + +template bool removeScaling + (Matrix33 &mat, + bool exc = true); + +template bool extractScalingAndShear + (const Matrix33 &mat, + Vec2 &scl, + T &h, + bool exc = true); + +template Matrix33 sansScalingAndShear + (const Matrix33 &mat, + bool exc = true); + +template bool removeScalingAndShear + (Matrix33 &mat, + bool exc = true); + +template bool extractAndRemoveScalingAndShear + (Matrix33 &mat, + Vec2 &scl, + T &shr, + bool exc = true); + +template void extractEuler + (const Matrix33 &mat, + T &rot); + +template bool extractSHRT (const Matrix33 &mat, + Vec2 &s, + T &h, + T &r, + Vec2 &t, + bool exc = true); + +template bool checkForZeroScaleInRow + (const T &scl, + const Vec2 &row, + bool exc = true); + +template Matrix33 outerProduct + ( const Vec3 &a, + const Vec3 &b); + + +//----------------------------------------------------------------------------- +// Implementation for 4x4 Matrix +//------------------------------ + + +template +bool +extractScaling (const Matrix44 &mat, Vec3 &scl, bool exc) +{ + Vec3 shr; + Matrix44 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return false; + + return true; +} + + +template +Matrix44 +sansScaling (const Matrix44 &mat, bool exc) +{ + Vec3 scl; + Vec3 shr; + Vec3 rot; + Vec3 tran; + + if (! extractSHRT (mat, scl, shr, rot, tran, exc)) + return mat; + + Matrix44 M; + + M.translate (tran); + M.rotate (rot); + M.shear (shr); + + return M; +} + + +template +bool +removeScaling (Matrix44 &mat, bool exc) +{ + Vec3 scl; + Vec3 shr; + Vec3 rot; + Vec3 tran; + + if (! extractSHRT (mat, scl, shr, rot, tran, exc)) + return false; + + mat.makeIdentity (); + mat.translate (tran); + mat.rotate (rot); + mat.shear (shr); + + return true; +} + + +template +bool +extractScalingAndShear (const Matrix44 &mat, + Vec3 &scl, Vec3 &shr, bool exc) +{ + Matrix44 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return false; + + return true; +} + + +template +Matrix44 +sansScalingAndShear (const Matrix44 &mat, bool exc) +{ + Vec3 scl; + Vec3 shr; + Matrix44 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return mat; + + return M; +} + + +template +void +sansScalingAndShear (Matrix44 &result, const Matrix44 &mat, bool exc) +{ + Vec3 scl; + Vec3 shr; + + if (! extractAndRemoveScalingAndShear (result, scl, shr, exc)) + result = mat; +} + + +template +bool +removeScalingAndShear (Matrix44 &mat, bool exc) +{ + Vec3 scl; + Vec3 shr; + + if (! extractAndRemoveScalingAndShear (mat, scl, shr, exc)) + return false; + + return true; +} + + +template +bool +extractAndRemoveScalingAndShear (Matrix44 &mat, + Vec3 &scl, Vec3 &shr, bool exc) +{ + // + // This implementation follows the technique described in the paper by + // Spencer W. Thomas in the Graphics Gems II article: "Decomposing a + // Matrix into Simple Transformations", p. 320. + // + + Vec3 row[3]; + + row[0] = Vec3 (mat[0][0], mat[0][1], mat[0][2]); + row[1] = Vec3 (mat[1][0], mat[1][1], mat[1][2]); + row[2] = Vec3 (mat[2][0], mat[2][1], mat[2][2]); + + T maxVal = 0; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + if (Imath::abs (row[i][j]) > maxVal) + maxVal = Imath::abs (row[i][j]); + + // + // We normalize the 3x3 matrix here. + // It was noticed that this can improve numerical stability significantly, + // especially when many of the upper 3x3 matrix's coefficients are very + // close to zero; we correct for this step at the end by multiplying the + // scaling factors by maxVal at the end (shear and rotation are not + // affected by the normalization). + + if (maxVal != 0) + { + for (int i=0; i < 3; i++) + if (! checkForZeroScaleInRow (maxVal, row[i], exc)) + return false; + else + row[i] /= maxVal; + } + + // Compute X scale factor. + scl.x = row[0].length (); + if (! checkForZeroScaleInRow (scl.x, row[0], exc)) + return false; + + // Normalize first row. + row[0] /= scl.x; + + // An XY shear factor will shear the X coord. as the Y coord. changes. + // There are 6 combinations (XY, XZ, YZ, YX, ZX, ZY), although we only + // extract the first 3 because we can effect the last 3 by shearing in + // XY, XZ, YZ combined rotations and scales. + // + // shear matrix < 1, YX, ZX, 0, + // XY, 1, ZY, 0, + // XZ, YZ, 1, 0, + // 0, 0, 0, 1 > + + // Compute XY shear factor and make 2nd row orthogonal to 1st. + shr[0] = row[0].dot (row[1]); + row[1] -= shr[0] * row[0]; + + // Now, compute Y scale. + scl.y = row[1].length (); + if (! checkForZeroScaleInRow (scl.y, row[1], exc)) + return false; + + // Normalize 2nd row and correct the XY shear factor for Y scaling. + row[1] /= scl.y; + shr[0] /= scl.y; + + // Compute XZ and YZ shears, orthogonalize 3rd row. + shr[1] = row[0].dot (row[2]); + row[2] -= shr[1] * row[0]; + shr[2] = row[1].dot (row[2]); + row[2] -= shr[2] * row[1]; + + // Next, get Z scale. + scl.z = row[2].length (); + if (! checkForZeroScaleInRow (scl.z, row[2], exc)) + return false; + + // Normalize 3rd row and correct the XZ and YZ shear factors for Z scaling. + row[2] /= scl.z; + shr[1] /= scl.z; + shr[2] /= scl.z; + + // At this point, the upper 3x3 matrix in mat is orthonormal. + // Check for a coordinate system flip. If the determinant + // is less than zero, then negate the matrix and the scaling factors. + if (row[0].dot (row[1].cross (row[2])) < 0) + for (int i=0; i < 3; i++) + { + scl[i] *= -1; + row[i] *= -1; + } + + // Copy over the orthonormal rows into the returned matrix. + // The upper 3x3 matrix in mat is now a rotation matrix. + for (int i=0; i < 3; i++) + { + mat[i][0] = row[i][0]; + mat[i][1] = row[i][1]; + mat[i][2] = row[i][2]; + } + + // Correct the scaling factors for the normalization step that we + // performed above; shear and rotation are not affected by the + // normalization. + scl *= maxVal; + + return true; +} + + +template +void +extractEulerXYZ (const Matrix44 &mat, Vec3 &rot) +{ + // + // Normalize the local x, y and z axes to remove scaling. + // + + Vec3 i (mat[0][0], mat[0][1], mat[0][2]); + Vec3 j (mat[1][0], mat[1][1], mat[1][2]); + Vec3 k (mat[2][0], mat[2][1], mat[2][2]); + + i.normalize(); + j.normalize(); + k.normalize(); + + Matrix44 M (i[0], i[1], i[2], 0, + j[0], j[1], j[2], 0, + k[0], k[1], k[2], 0, + 0, 0, 0, 1); + + // + // Extract the first angle, rot.x. + // + + rot.x = Math::atan2 (M[1][2], M[2][2]); + + // + // Remove the rot.x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Matrix44 N; + N.rotate (Vec3 (-rot.x, 0, 0)); + N = N * M; + + // + // Extract the other two angles, rot.y and rot.z, from N. + // + + T cy = Math::sqrt (N[0][0]*N[0][0] + N[0][1]*N[0][1]); + rot.y = Math::atan2 (-N[0][2], cy); + rot.z = Math::atan2 (-N[1][0], N[1][1]); +} + + +template +void +extractEulerZYX (const Matrix44 &mat, Vec3 &rot) +{ + // + // Normalize the local x, y and z axes to remove scaling. + // + + Vec3 i (mat[0][0], mat[0][1], mat[0][2]); + Vec3 j (mat[1][0], mat[1][1], mat[1][2]); + Vec3 k (mat[2][0], mat[2][1], mat[2][2]); + + i.normalize(); + j.normalize(); + k.normalize(); + + Matrix44 M (i[0], i[1], i[2], 0, + j[0], j[1], j[2], 0, + k[0], k[1], k[2], 0, + 0, 0, 0, 1); + + // + // Extract the first angle, rot.x. + // + + rot.x = -Math::atan2 (M[1][0], M[0][0]); + + // + // Remove the x rotation from M, so that the remaining + // rotation, N, is only around two axes, and gimbal lock + // cannot occur. + // + + Matrix44 N; + N.rotate (Vec3 (0, 0, -rot.x)); + N = N * M; + + // + // Extract the other two angles, rot.y and rot.z, from N. + // + + T cy = Math::sqrt (N[2][2]*N[2][2] + N[2][1]*N[2][1]); + rot.y = -Math::atan2 (-N[2][0], cy); + rot.z = -Math::atan2 (-N[1][2], N[1][1]); +} + + +template +Quat +extractQuat (const Matrix44 &mat) +{ + Matrix44 rot; + + T tr, s; + T q[4]; + int i, j, k; + Quat quat; + + int nxt[3] = {1, 2, 0}; + tr = mat[0][0] + mat[1][1] + mat[2][2]; + + // check the diagonal + if (tr > 0.0) { + s = Math::sqrt (tr + T(1.0)); + quat.r = s / T(2.0); + s = T(0.5) / s; + + quat.v.x = (mat[1][2] - mat[2][1]) * s; + quat.v.y = (mat[2][0] - mat[0][2]) * s; + quat.v.z = (mat[0][1] - mat[1][0]) * s; + } + else { + // diagonal is negative + i = 0; + if (mat[1][1] > mat[0][0]) + i=1; + if (mat[2][2] > mat[i][i]) + i=2; + + j = nxt[i]; + k = nxt[j]; + s = Math::sqrt ((mat[i][i] - (mat[j][j] + mat[k][k])) + T(1.0)); + + q[i] = s * T(0.5); + if (s != T(0.0)) + s = T(0.5) / s; + + q[3] = (mat[j][k] - mat[k][j]) * s; + q[j] = (mat[i][j] + mat[j][i]) * s; + q[k] = (mat[i][k] + mat[k][i]) * s; + + quat.v.x = q[0]; + quat.v.y = q[1]; + quat.v.z = q[2]; + quat.r = q[3]; + } + + return quat; +} + +template +bool +extractSHRT (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Vec3 &r, + Vec3 &t, + bool exc /* = true */ , + typename Euler::Order rOrder /* = Euler::XYZ */ ) +{ + Matrix44 rot; + + rot = mat; + if (! extractAndRemoveScalingAndShear (rot, s, h, exc)) + return false; + + extractEulerXYZ (rot, r); + + t.x = mat[3][0]; + t.y = mat[3][1]; + t.z = mat[3][2]; + + if (rOrder != Euler::XYZ) + { + Imath::Euler eXYZ (r, Imath::Euler::XYZ); + Imath::Euler e (eXYZ, rOrder); + r = e.toXYZVector (); + } + + return true; +} + +template +bool +extractSHRT (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Vec3 &r, + Vec3 &t, + bool exc) +{ + return extractSHRT(mat, s, h, r, t, exc, Imath::Euler::XYZ); +} + +template +bool +extractSHRT (const Matrix44 &mat, + Vec3 &s, + Vec3 &h, + Euler &r, + Vec3 &t, + bool exc /* = true */) +{ + return extractSHRT (mat, s, h, r, t, exc, r.order ()); +} + + +template +bool +checkForZeroScaleInRow (const T& scl, + const Vec3 &row, + bool exc /* = true */ ) +{ + for (int i = 0; i < 3; i++) + { + if ((abs (scl) < 1 && abs (row[i]) >= limits::max() * abs (scl))) + { + if (exc) + throw Imath::ZeroScaleExc ("Cannot remove zero scaling " + "from matrix."); + else + return false; + } + } + + return true; +} + +template +Matrix44 +outerProduct (const Vec4 &a, const Vec4 &b ) +{ + return Matrix44 (a.x*b.x, a.x*b.y, a.x*b.z, a.x*b.w, + a.y*b.x, a.y*b.y, a.y*b.z, a.x*b.w, + a.z*b.x, a.z*b.y, a.z*b.z, a.x*b.w, + a.w*b.x, a.w*b.y, a.w*b.z, a.w*b.w); +} + +template +Matrix44 +rotationMatrix (const Vec3 &from, const Vec3 &to) +{ + Quat q; + q.setRotation(from, to); + return q.toMatrix44(); +} + + +template +Matrix44 +rotationMatrixWithUpDir (const Vec3 &fromDir, + const Vec3 &toDir, + const Vec3 &upDir) +{ + // + // The goal is to obtain a rotation matrix that takes + // "fromDir" to "toDir". We do this in two steps and + // compose the resulting rotation matrices; + // (a) rotate "fromDir" into the z-axis + // (b) rotate the z-axis into "toDir" + // + + // The from direction must be non-zero; but we allow zero to and up dirs. + if (fromDir.length () == 0) + return Matrix44 (); + + else + { + Matrix44 zAxis2FromDir( Imath::UNINITIALIZED ); + alignZAxisWithTargetDir (zAxis2FromDir, fromDir, Vec3 (0, 1, 0)); + + Matrix44 fromDir2zAxis = zAxis2FromDir.transposed (); + + Matrix44 zAxis2ToDir( Imath::UNINITIALIZED ); + alignZAxisWithTargetDir (zAxis2ToDir, toDir, upDir); + + return fromDir2zAxis * zAxis2ToDir; + } +} + + +template +void +alignZAxisWithTargetDir (Matrix44 &result, Vec3 targetDir, Vec3 upDir) +{ + // + // Ensure that the target direction is non-zero. + // + + if ( targetDir.length () == 0 ) + targetDir = Vec3 (0, 0, 1); + + // + // Ensure that the up direction is non-zero. + // + + if ( upDir.length () == 0 ) + upDir = Vec3 (0, 1, 0); + + // + // Check for degeneracies. If the upDir and targetDir are parallel + // or opposite, then compute a new, arbitrary up direction that is + // not parallel or opposite to the targetDir. + // + + if (upDir.cross (targetDir).length () == 0) + { + upDir = targetDir.cross (Vec3 (1, 0, 0)); + if (upDir.length() == 0) + upDir = targetDir.cross(Vec3 (0, 0, 1)); + } + + // + // Compute the x-, y-, and z-axis vectors of the new coordinate system. + // + + Vec3 targetPerpDir = upDir.cross (targetDir); + Vec3 targetUpDir = targetDir.cross (targetPerpDir); + + // + // Rotate the x-axis into targetPerpDir (row 0), + // rotate the y-axis into targetUpDir (row 1), + // rotate the z-axis into targetDir (row 2). + // + + Vec3 row[3]; + row[0] = targetPerpDir.normalized (); + row[1] = targetUpDir .normalized (); + row[2] = targetDir .normalized (); + + result.x[0][0] = row[0][0]; + result.x[0][1] = row[0][1]; + result.x[0][2] = row[0][2]; + result.x[0][3] = (T)0; + + result.x[1][0] = row[1][0]; + result.x[1][1] = row[1][1]; + result.x[1][2] = row[1][2]; + result.x[1][3] = (T)0; + + result.x[2][0] = row[2][0]; + result.x[2][1] = row[2][1]; + result.x[2][2] = row[2][2]; + result.x[2][3] = (T)0; + + result.x[3][0] = (T)0; + result.x[3][1] = (T)0; + result.x[3][2] = (T)0; + result.x[3][3] = (T)1; +} + + +// Compute an orthonormal direct frame from : a position, an x axis direction and a normal to the y axis +// If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis. +// Inputs are : +// -the position of the frame +// -the x axis direction of the frame +// -a normal to the y axis of the frame +// Return is the orthonormal frame +template +Matrix44 +computeLocalFrame( const Vec3& p, + const Vec3& xDir, + const Vec3& normal) +{ + Vec3 _xDir(xDir); + Vec3 x = _xDir.normalize(); + Vec3 y = (normal % x).normalize(); + Vec3 z = (x % y).normalize(); + + Matrix44 L; + L[0][0] = x[0]; + L[0][1] = x[1]; + L[0][2] = x[2]; + L[0][3] = 0.0; + + L[1][0] = y[0]; + L[1][1] = y[1]; + L[1][2] = y[2]; + L[1][3] = 0.0; + + L[2][0] = z[0]; + L[2][1] = z[1]; + L[2][2] = z[2]; + L[2][3] = 0.0; + + L[3][0] = p[0]; + L[3][1] = p[1]; + L[3][2] = p[2]; + L[3][3] = 1.0; + + return L; +} + +// Add a translate/rotate/scale offset to an input frame +// and put it in another frame of reference +// Inputs are : +// - input frame +// - translate offset +// - rotate offset in degrees +// - scale offset +// - frame of reference +// Output is the offsetted frame +template +Matrix44 +addOffset( const Matrix44& inMat, + const Vec3& tOffset, + const Vec3& rOffset, + const Vec3& sOffset, + const Matrix44& ref) +{ + Matrix44 O; + + Vec3 _rOffset(rOffset); + _rOffset *= M_PI / 180.0; + O.rotate (_rOffset); + + O[3][0] = tOffset[0]; + O[3][1] = tOffset[1]; + O[3][2] = tOffset[2]; + + Matrix44 S; + S.scale (sOffset); + + Matrix44 X = S * O * inMat * ref; + + return X; +} + +// Compute Translate/Rotate/Scale matrix from matrix A with the Rotate/Scale of Matrix B +// Inputs are : +// -keepRotateA : if true keep rotate from matrix A, use B otherwise +// -keepScaleA : if true keep scale from matrix A, use B otherwise +// -Matrix A +// -Matrix B +// Return Matrix A with tweaked rotation/scale +template +Matrix44 +computeRSMatrix( bool keepRotateA, + bool keepScaleA, + const Matrix44& A, + const Matrix44& B) +{ + Vec3 as, ah, ar, at; + extractSHRT (A, as, ah, ar, at); + + Vec3 bs, bh, br, bt; + extractSHRT (B, bs, bh, br, bt); + + if (!keepRotateA) + ar = br; + + if (!keepScaleA) + as = bs; + + Matrix44 mat; + mat.makeIdentity(); + mat.translate (at); + mat.rotate (ar); + mat.scale (as); + + return mat; +} + + + +//----------------------------------------------------------------------------- +// Implementation for 3x3 Matrix +//------------------------------ + + +template +bool +extractScaling (const Matrix33 &mat, Vec2 &scl, bool exc) +{ + T shr; + Matrix33 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return false; + + return true; +} + + +template +Matrix33 +sansScaling (const Matrix33 &mat, bool exc) +{ + Vec2 scl; + T shr; + T rot; + Vec2 tran; + + if (! extractSHRT (mat, scl, shr, rot, tran, exc)) + return mat; + + Matrix33 M; + + M.translate (tran); + M.rotate (rot); + M.shear (shr); + + return M; +} + + +template +bool +removeScaling (Matrix33 &mat, bool exc) +{ + Vec2 scl; + T shr; + T rot; + Vec2 tran; + + if (! extractSHRT (mat, scl, shr, rot, tran, exc)) + return false; + + mat.makeIdentity (); + mat.translate (tran); + mat.rotate (rot); + mat.shear (shr); + + return true; +} + + +template +bool +extractScalingAndShear (const Matrix33 &mat, Vec2 &scl, T &shr, bool exc) +{ + Matrix33 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return false; + + return true; +} + + +template +Matrix33 +sansScalingAndShear (const Matrix33 &mat, bool exc) +{ + Vec2 scl; + T shr; + Matrix33 M (mat); + + if (! extractAndRemoveScalingAndShear (M, scl, shr, exc)) + return mat; + + return M; +} + + +template +bool +removeScalingAndShear (Matrix33 &mat, bool exc) +{ + Vec2 scl; + T shr; + + if (! extractAndRemoveScalingAndShear (mat, scl, shr, exc)) + return false; + + return true; +} + +template +bool +extractAndRemoveScalingAndShear (Matrix33 &mat, + Vec2 &scl, T &shr, bool exc) +{ + Vec2 row[2]; + + row[0] = Vec2 (mat[0][0], mat[0][1]); + row[1] = Vec2 (mat[1][0], mat[1][1]); + + T maxVal = 0; + for (int i=0; i < 2; i++) + for (int j=0; j < 2; j++) + if (Imath::abs (row[i][j]) > maxVal) + maxVal = Imath::abs (row[i][j]); + + // + // We normalize the 2x2 matrix here. + // It was noticed that this can improve numerical stability significantly, + // especially when many of the upper 2x2 matrix's coefficients are very + // close to zero; we correct for this step at the end by multiplying the + // scaling factors by maxVal at the end (shear and rotation are not + // affected by the normalization). + + if (maxVal != 0) + { + for (int i=0; i < 2; i++) + if (! checkForZeroScaleInRow (maxVal, row[i], exc)) + return false; + else + row[i] /= maxVal; + } + + // Compute X scale factor. + scl.x = row[0].length (); + if (! checkForZeroScaleInRow (scl.x, row[0], exc)) + return false; + + // Normalize first row. + row[0] /= scl.x; + + // An XY shear factor will shear the X coord. as the Y coord. changes. + // There are 2 combinations (XY, YX), although we only extract the XY + // shear factor because we can effect the an YX shear factor by + // shearing in XY combined with rotations and scales. + // + // shear matrix < 1, YX, 0, + // XY, 1, 0, + // 0, 0, 1 > + + // Compute XY shear factor and make 2nd row orthogonal to 1st. + shr = row[0].dot (row[1]); + row[1] -= shr * row[0]; + + // Now, compute Y scale. + scl.y = row[1].length (); + if (! checkForZeroScaleInRow (scl.y, row[1], exc)) + return false; + + // Normalize 2nd row and correct the XY shear factor for Y scaling. + row[1] /= scl.y; + shr /= scl.y; + + // At this point, the upper 2x2 matrix in mat is orthonormal. + // Check for a coordinate system flip. If the determinant + // is -1, then flip the rotation matrix and adjust the scale(Y) + // and shear(XY) factors to compensate. + if (row[0][0] * row[1][1] - row[0][1] * row[1][0] < 0) + { + row[1][0] *= -1; + row[1][1] *= -1; + scl[1] *= -1; + shr *= -1; + } + + // Copy over the orthonormal rows into the returned matrix. + // The upper 2x2 matrix in mat is now a rotation matrix. + for (int i=0; i < 2; i++) + { + mat[i][0] = row[i][0]; + mat[i][1] = row[i][1]; + } + + scl *= maxVal; + + return true; +} + + +template +void +extractEuler (const Matrix33 &mat, T &rot) +{ + // + // Normalize the local x and y axes to remove scaling. + // + + Vec2 i (mat[0][0], mat[0][1]); + Vec2 j (mat[1][0], mat[1][1]); + + i.normalize(); + j.normalize(); + + // + // Extract the angle, rot. + // + + rot = - Math::atan2 (j[0], i[0]); +} + + +template +bool +extractSHRT (const Matrix33 &mat, + Vec2 &s, + T &h, + T &r, + Vec2 &t, + bool exc) +{ + Matrix33 rot; + + rot = mat; + if (! extractAndRemoveScalingAndShear (rot, s, h, exc)) + return false; + + extractEuler (rot, r); + + t.x = mat[2][0]; + t.y = mat[2][1]; + + return true; +} + + +template +bool +checkForZeroScaleInRow (const T& scl, + const Vec2 &row, + bool exc /* = true */ ) +{ + for (int i = 0; i < 2; i++) + { + if ((abs (scl) < 1 && abs (row[i]) >= limits::max() * abs (scl))) + { + if (exc) + throw Imath::ZeroScaleExc ("Cannot remove zero scaling " + "from matrix."); + else + return false; + } + } + + return true; +} + + +template +Matrix33 +outerProduct (const Vec3 &a, const Vec3 &b ) +{ + return Matrix33 (a.x*b.x, a.x*b.y, a.x*b.z, + a.y*b.x, a.y*b.y, a.y*b.z, + a.z*b.x, a.z*b.y, a.z*b.z ); +} + + +// Computes the translation and rotation that brings the 'from' points +// as close as possible to the 'to' points under the Frobenius norm. +// To be more specific, let x be the matrix of 'from' points and y be +// the matrix of 'to' points, we want to find the matrix A of the form +// [ R t ] +// [ 0 1 ] +// that minimizes +// || (A*x - y)^T * W * (A*x - y) ||_F +// If doScaling is true, then a uniform scale is allowed also. +template +Imath::M44d +procrustesRotationAndTranslation (const Imath::Vec3* A, // From these + const Imath::Vec3* B, // To these + const T* weights, + const size_t numPoints, + const bool doScaling = false); + +// Unweighted: +template +Imath::M44d +procrustesRotationAndTranslation (const Imath::Vec3* A, + const Imath::Vec3* B, + const size_t numPoints, + const bool doScaling = false); + +// Compute the SVD of a 3x3 matrix using Jacobi transformations. This method +// should be quite accurate (competitive with LAPACK) even for poorly +// conditioned matrices, and because it has been written specifically for the +// 3x3/4x4 case it is much faster than calling out to LAPACK. +// +// The SVD of a 3x3/4x4 matrix A is defined as follows: +// A = U * S * V^T +// where S is the diagonal matrix of singular values and both U and V are +// orthonormal. By convention, the entries S are all positive and sorted from +// the largest to the smallest. However, some uses of this function may +// require that the matrix U*V^T have positive determinant; in this case, we +// may make the smallest singular value negative to ensure that this is +// satisfied. +// +// Currently only available for single- and double-precision matrices. +template +void +jacobiSVD (const Imath::Matrix33& A, + Imath::Matrix33& U, + Imath::Vec3& S, + Imath::Matrix33& V, + const T tol = Imath::limits::epsilon(), + const bool forcePositiveDeterminant = false); + +template +void +jacobiSVD (const Imath::Matrix44& A, + Imath::Matrix44& U, + Imath::Vec4& S, + Imath::Matrix44& V, + const T tol = Imath::limits::epsilon(), + const bool forcePositiveDeterminant = false); + +// Compute the eigenvalues (S) and the eigenvectors (V) of +// a real symmetric matrix using Jacobi transformation. +// +// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: +// A = V * S * V^T +// where V is orthonormal and S is the diagonal matrix of eigenvalues. +// Input matrix A must be symmetric. A is also modified during +// the computation so that upper diagonal entries of A become zero. +// +template +void +jacobiEigenSolver (Matrix33& A, + Vec3& S, + Matrix33& V, + const T tol); + +template +inline +void +jacobiEigenSolver (Matrix33& A, + Vec3& S, + Matrix33& V) +{ + jacobiEigenSolver(A,S,V,limits::epsilon()); +} + +template +void +jacobiEigenSolver (Matrix44& A, + Vec4& S, + Matrix44& V, + const T tol); + +template +inline +void +jacobiEigenSolver (Matrix44& A, + Vec4& S, + Matrix44& V) +{ + jacobiEigenSolver(A,S,V,limits::epsilon()); +} + +// Compute a eigenvector corresponding to the abs max/min eigenvalue +// of a real symmetric matrix using Jacobi transformation. +template +void +maxEigenVector (TM& A, TV& S); +template +void +minEigenVector (TM& A, TV& S); + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlane.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlane.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlane.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlane.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,256 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHPLANE_H +#define INCLUDED_IMATHPLANE_H + +//---------------------------------------------------------------------- +// +// template class Plane3 +// +// The Imath::Plane3<> class represents a half space, so the +// normal may point either towards or away from origin. The +// plane P can be represented by Imath::Plane3 as either p or -p +// corresponding to the two half-spaces on either side of the +// plane. Any function which computes a distance will return +// either negative or positive values for the distance indicating +// which half-space the point is in. Note that reflection, and +// intersection functions will operate as expected. +// +//---------------------------------------------------------------------- + +#include "ImathVec.h" +#include "ImathLine.h" + +namespace Imath { + + +template +class Plane3 +{ + public: + + Vec3 normal; + T distance; + + Plane3() {} + Plane3(const Vec3 &normal, T distance); + Plane3(const Vec3 &point, const Vec3 &normal); + Plane3(const Vec3 &point1, + const Vec3 &point2, + const Vec3 &point3); + + //---------------------- + // Various set methods + //---------------------- + + void set(const Vec3 &normal, + T distance); + + void set(const Vec3 &point, + const Vec3 &normal); + + void set(const Vec3 &point1, + const Vec3 &point2, + const Vec3 &point3 ); + + //---------------------- + // Utilities + //---------------------- + + bool intersect(const Line3 &line, + Vec3 &intersection) const; + + bool intersectT(const Line3 &line, + T ¶meter) const; + + T distanceTo(const Vec3 &) const; + + Vec3 reflectPoint(const Vec3 &) const; + Vec3 reflectVector(const Vec3 &) const; +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Plane3 Plane3f; +typedef Plane3 Plane3d; + + +//--------------- +// Implementation +//--------------- + +template +inline Plane3::Plane3(const Vec3 &p0, + const Vec3 &p1, + const Vec3 &p2) +{ + set(p0,p1,p2); +} + +template +inline Plane3::Plane3(const Vec3 &n, T d) +{ + set(n, d); +} + +template +inline Plane3::Plane3(const Vec3 &p, const Vec3 &n) +{ + set(p, n); +} + +template +inline void Plane3::set(const Vec3& point1, + const Vec3& point2, + const Vec3& point3) +{ + normal = (point2 - point1) % (point3 - point1); + normal.normalize(); + distance = normal ^ point1; +} + +template +inline void Plane3::set(const Vec3& point, const Vec3& n) +{ + normal = n; + normal.normalize(); + distance = normal ^ point; +} + +template +inline void Plane3::set(const Vec3& n, T d) +{ + normal = n; + normal.normalize(); + distance = d; +} + +template +inline T Plane3::distanceTo(const Vec3 &point) const +{ + return (point ^ normal) - distance; +} + +template +inline Vec3 Plane3::reflectPoint(const Vec3 &point) const +{ + return normal * distanceTo(point) * -2.0 + point; +} + + +template +inline Vec3 Plane3::reflectVector(const Vec3 &v) const +{ + return normal * (normal ^ v) * 2.0 - v; +} + + +template +inline bool Plane3::intersect(const Line3& line, Vec3& point) const +{ + T d = normal ^ line.dir; + if ( d == 0.0 ) return false; + T t = - ((normal ^ line.pos) - distance) / d; + point = line(t); + return true; +} + +template +inline bool Plane3::intersectT(const Line3& line, T &t) const +{ + T d = normal ^ line.dir; + if ( d == 0.0 ) return false; + t = - ((normal ^ line.pos) - distance) / d; + return true; +} + +template +std::ostream &operator<< (std::ostream &o, const Plane3 &plane) +{ + return o << "(" << plane.normal << ", " << plane.distance + << ")"; +} + +template +Plane3 operator* (const Plane3 &plane, const Matrix44 &M) +{ + // T + // -1 + // Could also compute M but that would suck. + // + + Vec3 dir1 = Vec3 (1, 0, 0) % plane.normal; + T dir1Len = dir1 ^ dir1; + + Vec3 tmp = Vec3 (0, 1, 0) % plane.normal; + T tmpLen = tmp ^ tmp; + + if (tmpLen > dir1Len) + { + dir1 = tmp; + dir1Len = tmpLen; + } + + tmp = Vec3 (0, 0, 1) % plane.normal; + tmpLen = tmp ^ tmp; + + if (tmpLen > dir1Len) + { + dir1 = tmp; + } + + Vec3 dir2 = dir1 % plane.normal; + Vec3 point = plane.distance * plane.normal; + + return Plane3 ( point * M, + (point + dir2) * M, + (point + dir1) * M ); +} + +template +Plane3 operator- (const Plane3 &plane) +{ + return Plane3(-plane.normal,-plane.distance); +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlatform.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlatform.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlatform.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathPlatform.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_IMATHPLATFORM_H +#define INCLUDED_IMATHPLATFORM_H + +//---------------------------------------------------------------------------- +// +// ImathPlatform.h +// +// This file contains functions and constants which aren't +// provided by the system libraries, compilers, or includes on +// certain platforms. +// +//---------------------------------------------------------------------------- + +#include + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +#ifndef M_PI_2 + #define M_PI_2 1.57079632679489661923 // pi/2 +#endif + + +//----------------------------------------------------------------------------- +// +// Some, but not all, C++ compilers support the C99 restrict +// keyword or some variant of it, for example, __restrict. +// +//----------------------------------------------------------------------------- + +#if defined __GNUC__ + + // + // supports __restrict + // + + #define IMATH_RESTRICT __restrict + +#elif defined (__INTEL_COMPILER) || \ + defined(__ICL) || \ + defined(__ICC) || \ + defined(__ECC) + + // + // supports restrict + // + + #define IMATH_RESTRICT restrict + +#elif defined __sgi + + // + // supports restrict + // + + #define IMATH_RESTRICT restrict + +#elif defined _MSC_VER + + // + // supports __restrict + // + +// #define IMATH_RESTRICT __restrict + #define IMATH_RESTRICT + +#else + + // + // restrict / __restrict not supported + // + + #define IMATH_RESTRICT + +#endif + +#endif // INCLUDED_IMATHPLATFORM_H diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathQuat.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathQuat.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathQuat.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathQuat.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,963 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHQUAT_H +#define INCLUDED_IMATHQUAT_H + +//---------------------------------------------------------------------- +// +// template class Quat +// +// "Quaternions came from Hamilton ... and have been an unmixed +// evil to those who have touched them in any way. Vector is a +// useless survival ... and has never been of the slightest use +// to any creature." +// +// - Lord Kelvin +// +// This class implements the quaternion numerical type -- you +// will probably want to use this class to represent orientations +// in R3 and to convert between various euler angle reps. You +// should probably use Imath::Euler<> for that. +// +//---------------------------------------------------------------------- + +#include "ImathExc.h" +#include "ImathMatrix.h" + +#include + +namespace Imath { + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// Disable MS VC++ warnings about conversion from double to float +#pragma warning(disable:4244) +#endif + +template +class Quat +{ + public: + + T r; // real part + Vec3 v; // imaginary vector + + + //----------------------------------------------------- + // Constructors - default constructor is identity quat + //----------------------------------------------------- + + Quat (); + + template + Quat (const Quat &q); + + Quat (T s, T i, T j, T k); + + Quat (T s, Vec3 d); + + static Quat identity (); + + + //------------------------------------------------- + // Basic Algebra - Operators and Methods + // The operator return values are *NOT* normalized + // + // operator^ and euclideanInnnerProduct() both + // implement the 4D dot product + // + // operator/ uses the inverse() quaternion + // + // operator~ is conjugate -- if (S+V) is quat then + // the conjugate (S+V)* == (S-V) + // + // some operators (*,/,*=,/=) treat the quat as + // a 4D vector when one of the operands is scalar + //------------------------------------------------- + + const Quat & operator = (const Quat &q); + const Quat & operator *= (const Quat &q); + const Quat & operator *= (T t); + const Quat & operator /= (const Quat &q); + const Quat & operator /= (T t); + const Quat & operator += (const Quat &q); + const Quat & operator -= (const Quat &q); + T & operator [] (int index); // as 4D vector + T operator [] (int index) const; + + template bool operator == (const Quat &q) const; + template bool operator != (const Quat &q) const; + + Quat & invert (); // this -> 1 / this + Quat inverse () const; + Quat & normalize (); // returns this + Quat normalized () const; + T length () const; // in R4 + Vec3 rotateVector(const Vec3 &original) const; + T euclideanInnerProduct(const Quat &q) const; + + //----------------------- + // Rotation conversion + //----------------------- + + Quat & setAxisAngle (const Vec3 &axis, T radians); + + Quat & setRotation (const Vec3 &fromDirection, + const Vec3 &toDirection); + + T angle () const; + Vec3 axis () const; + + Matrix33 toMatrix33 () const; + Matrix44 toMatrix44 () const; + + Quat log () const; + Quat exp () const; + + + private: + + void setRotationInternal (const Vec3 &f0, + const Vec3 &t0, + Quat &q); +}; + + +template +Quat slerp (const Quat &q1, const Quat &q2, T t); + +template +Quat slerpShortestArc + (const Quat &q1, const Quat &q2, T t); + + +template +Quat squad (const Quat &q1, const Quat &q2, + const Quat &qa, const Quat &qb, T t); + +template +void intermediate (const Quat &q0, const Quat &q1, + const Quat &q2, const Quat &q3, + Quat &qa, Quat &qb); + +template +Matrix33 operator * (const Matrix33 &M, const Quat &q); + +template +Matrix33 operator * (const Quat &q, const Matrix33 &M); + +template +std::ostream & operator << (std::ostream &o, const Quat &q); + +template +Quat operator * (const Quat &q1, const Quat &q2); + +template +Quat operator / (const Quat &q1, const Quat &q2); + +template +Quat operator / (const Quat &q, T t); + +template +Quat operator * (const Quat &q, T t); + +template +Quat operator * (T t, const Quat &q); + +template +Quat operator + (const Quat &q1, const Quat &q2); + +template +Quat operator - (const Quat &q1, const Quat &q2); + +template +Quat operator ~ (const Quat &q); + +template +Quat operator - (const Quat &q); + +template +Vec3 operator * (const Vec3 &v, const Quat &q); + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Quat Quatf; +typedef Quat Quatd; + + +//--------------- +// Implementation +//--------------- + +template +inline +Quat::Quat (): r (1), v (0, 0, 0) +{ + // empty +} + + +template +template +inline +Quat::Quat (const Quat &q): r (q.r), v (q.v) +{ + // empty +} + + +template +inline +Quat::Quat (T s, T i, T j, T k): r (s), v (i, j, k) +{ + // empty +} + + +template +inline +Quat::Quat (T s, Vec3 d): r (s), v (d) +{ + // empty +} + + +template +inline Quat +Quat::identity () +{ + return Quat(); +} + +template +inline const Quat & +Quat::operator = (const Quat &q) +{ + r = q.r; + v = q.v; + return *this; +} + + +template +inline const Quat & +Quat::operator *= (const Quat &q) +{ + T rtmp = r * q.r - (v ^ q.v); + v = r * q.v + v * q.r + v % q.v; + r = rtmp; + return *this; +} + + +template +inline const Quat & +Quat::operator *= (T t) +{ + r *= t; + v *= t; + return *this; +} + + +template +inline const Quat & +Quat::operator /= (const Quat &q) +{ + *this = *this * q.inverse(); + return *this; +} + + +template +inline const Quat & +Quat::operator /= (T t) +{ + r /= t; + v /= t; + return *this; +} + + +template +inline const Quat & +Quat::operator += (const Quat &q) +{ + r += q.r; + v += q.v; + return *this; +} + + +template +inline const Quat & +Quat::operator -= (const Quat &q) +{ + r -= q.r; + v -= q.v; + return *this; +} + + +template +inline T & +Quat::operator [] (int index) +{ + return index ? v[index - 1] : r; +} + + +template +inline T +Quat::operator [] (int index) const +{ + return index ? v[index - 1] : r; +} + + +template +template +inline bool +Quat::operator == (const Quat &q) const +{ + return r == q.r && v == q.v; +} + + +template +template +inline bool +Quat::operator != (const Quat &q) const +{ + return r != q.r || v != q.v; +} + + +template +inline T +operator ^ (const Quat& q1 ,const Quat& q2) +{ + return q1.r * q2.r + (q1.v ^ q2.v); +} + + +template +inline T +Quat::length () const +{ + return Math::sqrt (r * r + (v ^ v)); +} + + +template +inline Quat & +Quat::normalize () +{ + if (T l = length()) + { + r /= l; + v /= l; + } + else + { + r = 1; + v = Vec3 (0); + } + + return *this; +} + + +template +inline Quat +Quat::normalized () const +{ + if (T l = length()) + return Quat (r / l, v / l); + + return Quat(); +} + + +template +inline Quat +Quat::inverse () const +{ + // + // 1 Q* + // - = ---- where Q* is conjugate (operator~) + // Q Q* Q and (Q* Q) == Q ^ Q (4D dot) + // + + T qdot = *this ^ *this; + return Quat (r / qdot, -v / qdot); +} + + +template +inline Quat & +Quat::invert () +{ + T qdot = (*this) ^ (*this); + r /= qdot; + v = -v / qdot; + return *this; +} + + +template +inline Vec3 +Quat::rotateVector(const Vec3& original) const +{ + // + // Given a vector p and a quaternion q (aka this), + // calculate p' = qpq* + // + // Assumes unit quaternions (because non-unit + // quaternions cannot be used to rotate vectors + // anyway). + // + + Quat vec (0, original); // temporarily promote grade of original + Quat inv (*this); + inv.v *= -1; // unit multiplicative inverse + Quat result = *this * vec * inv; + return result.v; +} + + +template +inline T +Quat::euclideanInnerProduct (const Quat &q) const +{ + return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z; +} + + +template +T +angle4D (const Quat &q1, const Quat &q2) +{ + // + // Compute the angle between two quaternions, + // interpreting the quaternions as 4D vectors. + // + + Quat d = q1 - q2; + T lengthD = Math::sqrt (d ^ d); + + Quat s = q1 + q2; + T lengthS = Math::sqrt (s ^ s); + + return 2 * Math::atan2 (lengthD, lengthS); +} + + +template +Quat +slerp (const Quat &q1, const Quat &q2, T t) +{ + // + // Spherical linear interpolation. + // Assumes q1 and q2 are normalized and that q1 != -q2. + // + // This method does *not* interpolate along the shortest + // arc between q1 and q2. If you desire interpolation + // along the shortest arc, and q1^q2 is negative, then + // consider calling slerpShortestArc(), below, or flipping + // the second quaternion explicitly. + // + // The implementation of squad() depends on a slerp() + // that interpolates as is, without the automatic + // flipping. + // + // Don Hatch explains the method we use here on his + // web page, The Right Way to Calculate Stuff, at + // http://www.plunk.org/~hatch/rightway.php + // + + T a = angle4D (q1, q2); + T s = 1 - t; + + Quat q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 + + sinx_over_x (t * a) / sinx_over_x (a) * t * q2; + + return q.normalized(); +} + + +template +Quat +slerpShortestArc (const Quat &q1, const Quat &q2, T t) +{ + // + // Spherical linear interpolation along the shortest + // arc from q1 to either q2 or -q2, whichever is closer. + // Assumes q1 and q2 are unit quaternions. + // + + if ((q1 ^ q2) >= 0) + return slerp (q1, q2, t); + else + return slerp (q1, -q2, t); +} + + +template +Quat +spline (const Quat &q0, const Quat &q1, + const Quat &q2, const Quat &q3, + T t) +{ + // + // Spherical Cubic Spline Interpolation - + // from Advanced Animation and Rendering + // Techniques by Watt and Watt, Page 366: + // A spherical curve is constructed using three + // spherical linear interpolations of a quadrangle + // of unit quaternions: q1, qa, qb, q2. + // Given a set of quaternion keys: q0, q1, q2, q3, + // this routine does the interpolation between + // q1 and q2 by constructing two intermediate + // quaternions: qa and qb. The qa and qb are + // computed by the intermediate function to + // guarantee the continuity of tangents across + // adjacent cubic segments. The qa represents in-tangent + // for q1 and the qb represents the out-tangent for q2. + // + // The q1 q2 is the cubic segment being interpolated. + // The q0 is from the previous adjacent segment and q3 is + // from the next adjacent segment. The q0 and q3 are used + // in computing qa and qb. + // + + Quat qa = intermediate (q0, q1, q2); + Quat qb = intermediate (q1, q2, q3); + Quat result = squad (q1, qa, qb, q2, t); + + return result; +} + + +template +Quat +squad (const Quat &q1, const Quat &qa, + const Quat &qb, const Quat &q2, + T t) +{ + // + // Spherical Quadrangle Interpolation - + // from Advanced Animation and Rendering + // Techniques by Watt and Watt, Page 366: + // It constructs a spherical cubic interpolation as + // a series of three spherical linear interpolations + // of a quadrangle of unit quaternions. + // + + Quat r1 = slerp (q1, q2, t); + Quat r2 = slerp (qa, qb, t); + Quat result = slerp (r1, r2, 2 * t * (1 - t)); + + return result; +} + + +template +Quat +intermediate (const Quat &q0, const Quat &q1, const Quat &q2) +{ + // + // From advanced Animation and Rendering + // Techniques by Watt and Watt, Page 366: + // computing the inner quadrangle + // points (qa and qb) to guarantee tangent + // continuity. + // + + Quat q1inv = q1.inverse(); + Quat c1 = q1inv * q2; + Quat c2 = q1inv * q0; + Quat c3 = (T) (-0.25) * (c2.log() + c1.log()); + Quat qa = q1 * c3.exp(); + qa.normalize(); + return qa; +} + + +template +inline Quat +Quat::log () const +{ + // + // For unit quaternion, from Advanced Animation and + // Rendering Techniques by Watt and Watt, Page 366: + // + + T theta = Math::acos (std::min (r, (T) 1.0)); + + if (theta == 0) + return Quat (0, v); + + T sintheta = Math::sin (theta); + + T k; + if (abs (sintheta) < 1 && abs (theta) >= limits::max() * abs (sintheta)) + k = 1; + else + k = theta / sintheta; + + return Quat ((T) 0, v.x * k, v.y * k, v.z * k); +} + + +template +inline Quat +Quat::exp () const +{ + // + // For pure quaternion (zero scalar part): + // from Advanced Animation and Rendering + // Techniques by Watt and Watt, Page 366: + // + + T theta = v.length(); + T sintheta = Math::sin (theta); + + T k; + if (abs (theta) < 1 && abs (sintheta) >= limits::max() * abs (theta)) + k = 1; + else + k = sintheta / theta; + + T costheta = Math::cos (theta); + + return Quat (costheta, v.x * k, v.y * k, v.z * k); +} + + +template +inline T +Quat::angle () const +{ + return 2 * Math::atan2 (v.length(), r); +} + + +template +inline Vec3 +Quat::axis () const +{ + return v.normalized(); +} + + +template +inline Quat & +Quat::setAxisAngle (const Vec3 &axis, T radians) +{ + r = Math::cos (radians / 2); + v = axis.normalized() * Math::sin (radians / 2); + return *this; +} + + +template +Quat & +Quat::setRotation (const Vec3 &from, const Vec3 &to) +{ + // + // Create a quaternion that rotates vector from into vector to, + // such that the rotation is around an axis that is the cross + // product of from and to. + // + // This function calls function setRotationInternal(), which is + // numerically accurate only for rotation angles that are not much + // greater than pi/2. In order to achieve good accuracy for angles + // greater than pi/2, we split large angles in half, and rotate in + // two steps. + // + + // + // Normalize from and to, yielding f0 and t0. + // + + Vec3 f0 = from.normalized(); + Vec3 t0 = to.normalized(); + + if ((f0 ^ t0) >= 0) + { + // + // The rotation angle is less than or equal to pi/2. + // + + setRotationInternal (f0, t0, *this); + } + else + { + // + // The angle is greater than pi/2. After computing h0, + // which is halfway between f0 and t0, we rotate first + // from f0 to h0, then from h0 to t0. + // + + Vec3 h0 = (f0 + t0).normalized(); + + if ((h0 ^ h0) != 0) + { + setRotationInternal (f0, h0, *this); + + Quat q; + setRotationInternal (h0, t0, q); + + *this *= q; + } + else + { + // + // f0 and t0 point in exactly opposite directions. + // Pick an arbitrary axis that is orthogonal to f0, + // and rotate by pi. + // + + r = T (0); + + Vec3 f02 = f0 * f0; + + if (f02.x <= f02.y && f02.x <= f02.z) + v = (f0 % Vec3 (1, 0, 0)).normalized(); + else if (f02.y <= f02.z) + v = (f0 % Vec3 (0, 1, 0)).normalized(); + else + v = (f0 % Vec3 (0, 0, 1)).normalized(); + } + } + + return *this; +} + + +template +void +Quat::setRotationInternal (const Vec3 &f0, const Vec3 &t0, Quat &q) +{ + // + // The following is equivalent to setAxisAngle(n,2*phi), + // where the rotation axis, n, is orthogonal to the f0 and + // t0 vectors, and 2*phi is the angle between f0 and t0. + // + // This function is called by setRotation(), above; it assumes + // that f0 and t0 are normalized and that the angle between + // them is not much greater than pi/2. This function becomes + // numerically inaccurate if f0 and t0 point into nearly + // opposite directions. + // + + // + // Find a normalized vector, h0, that is halfway between f0 and t0. + // The angle between f0 and h0 is phi. + // + + Vec3 h0 = (f0 + t0).normalized(); + + // + // Store the rotation axis and rotation angle. + // + + q.r = f0 ^ h0; // f0 ^ h0 == cos (phi) + q.v = f0 % h0; // (f0 % h0).length() == sin (phi) +} + + +template +Matrix33 +Quat::toMatrix33() const +{ + return Matrix33 (1 - 2 * (v.y * v.y + v.z * v.z), + 2 * (v.x * v.y + v.z * r), + 2 * (v.z * v.x - v.y * r), + + 2 * (v.x * v.y - v.z * r), + 1 - 2 * (v.z * v.z + v.x * v.x), + 2 * (v.y * v.z + v.x * r), + + 2 * (v.z * v.x + v.y * r), + 2 * (v.y * v.z - v.x * r), + 1 - 2 * (v.y * v.y + v.x * v.x)); +} + +template +Matrix44 +Quat::toMatrix44() const +{ + return Matrix44 (1 - 2 * (v.y * v.y + v.z * v.z), + 2 * (v.x * v.y + v.z * r), + 2 * (v.z * v.x - v.y * r), + 0, + 2 * (v.x * v.y - v.z * r), + 1 - 2 * (v.z * v.z + v.x * v.x), + 2 * (v.y * v.z + v.x * r), + 0, + 2 * (v.z * v.x + v.y * r), + 2 * (v.y * v.z - v.x * r), + 1 - 2 * (v.y * v.y + v.x * v.x), + 0, + 0, + 0, + 0, + 1); +} + + +template +inline Matrix33 +operator * (const Matrix33 &M, const Quat &q) +{ + return M * q.toMatrix33(); +} + + +template +inline Matrix33 +operator * (const Quat &q, const Matrix33 &M) +{ + return q.toMatrix33() * M; +} + + +template +std::ostream & +operator << (std::ostream &o, const Quat &q) +{ + return o << "(" << q.r + << " " << q.v.x + << " " << q.v.y + << " " << q.v.z + << ")"; +} + + +template +inline Quat +operator * (const Quat &q1, const Quat &q2) +{ + return Quat (q1.r * q2.r - (q1.v ^ q2.v), + q1.r * q2.v + q1.v * q2.r + q1.v % q2.v); +} + + +template +inline Quat +operator / (const Quat &q1, const Quat &q2) +{ + return q1 * q2.inverse(); +} + + +template +inline Quat +operator / (const Quat &q, T t) +{ + return Quat (q.r / t, q.v / t); +} + + +template +inline Quat +operator * (const Quat &q, T t) +{ + return Quat (q.r * t, q.v * t); +} + + +template +inline Quat +operator * (T t, const Quat &q) +{ + return Quat (q.r * t, q.v * t); +} + + +template +inline Quat +operator + (const Quat &q1, const Quat &q2) +{ + return Quat (q1.r + q2.r, q1.v + q2.v); +} + + +template +inline Quat +operator - (const Quat &q1, const Quat &q2) +{ + return Quat (q1.r - q2.r, q1.v - q2.v); +} + + +template +inline Quat +operator ~ (const Quat &q) +{ + return Quat (q.r, -q.v); +} + + +template +inline Quat +operator - (const Quat &q) +{ + return Quat (-q.r, -q.v); +} + + +template +inline Vec3 +operator * (const Vec3 &v, const Quat &q) +{ + Vec3 a = q.v % v; + Vec3 b = q.v % a; + return v + T (2) * (q.r * a + b); +} + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +#pragma warning(default:4244) +#endif + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,195 @@ + +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// Routines that generate pseudo-random numbers compatible +// with the standard erand48(), nrand48(), etc. functions. +// +//----------------------------------------------------------------------------- + +#include "ImathRandom.h" +#include "ImathInt64.h" + +namespace Imath { +namespace { + +// +// Static state used by Imath::drand48(), Imath::lrand48() and Imath::srand48() +// + +unsigned short staticState[3] = {0, 0, 0}; + + +void +rand48Next (unsigned short state[3]) +{ + // + // drand48() and friends are all based on a linear congruential + // sequence, + // + // x[n+1] = (a * x[n] + c) % m, + // + // where a and c are as specified below, and m == (1 << 48) + // + + static const Int64 a = Int64 (0x5deece66dLL); + static const Int64 c = Int64 (0xbLL); + + // + // Assemble the 48-bit value x[n] from the + // three 16-bit values stored in state. + // + + Int64 x = (Int64 (state[2]) << 32) | + (Int64 (state[1]) << 16) | + Int64 (state[0]); + + // + // Compute x[n+1], except for the "modulo m" part. + // + + x = a * x + c; + + // + // Disassemble the 48 least significant bits of x[n+1] into + // three 16-bit values. Discard the 16 most significant bits; + // this takes care of the "modulo m" operation. + // + // We assume that sizeof (unsigned short) == 2. + // + + state[2] = (unsigned short)(x >> 32); + state[1] = (unsigned short)(x >> 16); + state[0] = (unsigned short)(x); +} + +} // namespace + + +double +erand48 (unsigned short state[3]) +{ + // + // Generate double-precision floating-point values between 0.0 and 1.0: + // + // The exponent is set to 0x3ff, which indicates a value greater + // than or equal to 1.0, and less than 2.0. The 48 most significant + // bits of the significand (mantissa) are filled with pseudo-random + // bits generated by rand48Next(). The remaining 4 bits are a copy + // of the 4 most significant bits of the significand. This results + // in bit patterns between 0x3ff0000000000000 and 0x3fffffffffffffff, + // which correspond to uniformly distributed floating-point values + // between 1.0 and 1.99999999999999978. Subtracting 1.0 from those + // values produces numbers between 0.0 and 0.99999999999999978, that + // is, between 0.0 and 1.0-DBL_EPSILON. + // + + rand48Next (state); + + union {double d; Int64 i;} u; + + u.i = (Int64 (0x3ff) << 52) | // sign and exponent + (Int64 (state[2]) << 36) | // significand + (Int64 (state[1]) << 20) | + (Int64 (state[0]) << 4) | + (Int64 (state[2]) >> 12); + + return u.d - 1; +} + + +double +drand48 () +{ + return Imath::erand48 (staticState); +} + + +long int +nrand48 (unsigned short state[3]) +{ + // + // Generate uniformly distributed integers between 0 and 0x7fffffff. + // + + rand48Next (state); + + return ((long int) (state[2]) << 15) | + ((long int) (state[1]) >> 1); +} + + +long int +lrand48 () +{ + return Imath::nrand48 (staticState); +} + + +void +srand48 (long int seed) +{ + staticState[2] = (unsigned short)(seed >> 16); + staticState[1] = (unsigned short)(seed); + staticState[0] = 0x330e; +} + + +float +Rand32::nextf () +{ + // + // Generate single-precision floating-point values between 0.0 and 1.0: + // + // The exponent is set to 0x7f, which indicates a value greater than + // or equal to 1.0, and less than 2.0. The 23 bits of the significand + // (mantissa) are filled with pseudo-random bits generated by + // Rand32::next(). This results in in bit patterns between 0x3f800000 + // and 0x3fffffff, which correspond to uniformly distributed floating- + // point values between 1.0 and 1.99999988. Subtracting 1.0 from + // those values produces numbers between 0.0 and 0.99999988, that is, + // between 0.0 and 1.0-FLT_EPSILON. + // + + next (); + + union {float f; unsigned int i;} u; + + u.i = 0x3f800000 | (_state & 0x7fffff); + return u.f - 1; +} + +} // namespace Imath diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRandom.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + +#ifndef INCLUDED_IMATHRANDOM_H +#define INCLUDED_IMATHRANDOM_H + +//----------------------------------------------------------------------------- +// +// Generators for uniformly distributed pseudo-random numbers and +// functions that use those generators to generate numbers with +// non-uniform distributions: +// +// class Rand32 +// class Rand48 +// solidSphereRand() +// hollowSphereRand() +// gaussRand() +// gaussSphereRand() +// +// Note: class Rand48() calls erand48() and nrand48(), which are not +// available on all operating systems. For compatibility we include +// our own versions of erand48() and nrand48(). Our functions have +// been reverse-engineered from the corresponding Unix/Linux man page. +// +//----------------------------------------------------------------------------- + +#include +#include + +namespace Imath { + +//----------------------------------------------- +// Fast random-number generator that generates +// a uniformly distributed sequence with a period +// length of 2^32. +//----------------------------------------------- + +class Rand32 +{ + public: + + //------------ + // Constructor + //------------ + + Rand32 (unsigned long int seed = 0); + + + //-------------------------------- + // Re-initialize with a given seed + //-------------------------------- + + void init (unsigned long int seed); + + + //---------------------------------------------------------- + // Get the next value in the sequence (range: [false, true]) + //---------------------------------------------------------- + + bool nextb (); + + + //--------------------------------------------------------------- + // Get the next value in the sequence (range: [0 ... 0xffffffff]) + //--------------------------------------------------------------- + + unsigned long int nexti (); + + + //------------------------------------------------------ + // Get the next value in the sequence (range: [0 ... 1[) + //------------------------------------------------------ + + float nextf (); + + + //------------------------------------------------------------------- + // Get the next value in the sequence (range [rangeMin ... rangeMax[) + //------------------------------------------------------------------- + + float nextf (float rangeMin, float rangeMax); + + + private: + + void next (); + + unsigned long int _state; +}; + + +//-------------------------------------------------------- +// Random-number generator based on the C Standard Library +// functions erand48(), nrand48() & company; generates a +// uniformly distributed sequence. +//-------------------------------------------------------- + +class Rand48 +{ + public: + + //------------ + // Constructor + //------------ + + Rand48 (unsigned long int seed = 0); + + + //-------------------------------- + // Re-initialize with a given seed + //-------------------------------- + + void init (unsigned long int seed); + + + //---------------------------------------------------------- + // Get the next value in the sequence (range: [false, true]) + //---------------------------------------------------------- + + bool nextb (); + + + //--------------------------------------------------------------- + // Get the next value in the sequence (range: [0 ... 0x7fffffff]) + //--------------------------------------------------------------- + + long int nexti (); + + + //------------------------------------------------------ + // Get the next value in the sequence (range: [0 ... 1[) + //------------------------------------------------------ + + double nextf (); + + + //------------------------------------------------------------------- + // Get the next value in the sequence (range [rangeMin ... rangeMax[) + //------------------------------------------------------------------- + + double nextf (double rangeMin, double rangeMax); + + + private: + + unsigned short int _state[3]; +}; + + +//------------------------------------------------------------ +// Return random points uniformly distributed in a sphere with +// radius 1 around the origin (distance from origin <= 1). +//------------------------------------------------------------ + +template +Vec +solidSphereRand (Rand &rand); + + +//------------------------------------------------------------- +// Return random points uniformly distributed on the surface of +// a sphere with radius 1 around the origin. +//------------------------------------------------------------- + +template +Vec +hollowSphereRand (Rand &rand); + + +//----------------------------------------------- +// Return random numbers with a normal (Gaussian) +// distribution with zero mean and unit variance. +//----------------------------------------------- + +template +float +gaussRand (Rand &rand); + + +//---------------------------------------------------- +// Return random points whose distance from the origin +// has a normal (Gaussian) distribution with zero mean +// and unit variance. +//---------------------------------------------------- + +template +Vec +gaussSphereRand (Rand &rand); + + +//--------------------------------- +// erand48(), nrand48() and friends +//--------------------------------- + +double erand48 (unsigned short state[3]); +double drand48 (); +long int nrand48 (unsigned short state[3]); +long int lrand48 (); +void srand48 (long int seed); + + +//--------------- +// Implementation +//--------------- + + +inline void +Rand32::init (unsigned long int seed) +{ + _state = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL; +} + + +inline +Rand32::Rand32 (unsigned long int seed) +{ + init (seed); +} + + +inline void +Rand32::next () +{ + _state = 1664525L * _state + 1013904223L; +} + + +inline bool +Rand32::nextb () +{ + next (); + // Return the 31st (most significant) bit, by and-ing with 2 ^ 31. + return !!(_state & 2147483648UL); +} + + +inline unsigned long int +Rand32::nexti () +{ + next (); + return _state & 0xffffffff; +} + + +inline float +Rand32::nextf (float rangeMin, float rangeMax) +{ + float f = nextf(); + return rangeMin * (1 - f) + rangeMax * f; +} + + +inline void +Rand48::init (unsigned long int seed) +{ + seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL; + + _state[0] = (unsigned short int) (seed & 0xFFFF); + _state[1] = (unsigned short int) ((seed >> 16) & 0xFFFF); + _state[2] = (unsigned short int) (seed & 0xFFFF); +} + + +inline +Rand48::Rand48 (unsigned long int seed) +{ + init (seed); +} + + +inline bool +Rand48::nextb () +{ + return Imath::nrand48 (_state) & 1; +} + + +inline long int +Rand48::nexti () +{ + return Imath::nrand48 (_state); +} + + +inline double +Rand48::nextf () +{ + return Imath::erand48 (_state); +} + + +inline double +Rand48::nextf (double rangeMin, double rangeMax) +{ + double f = nextf(); + return rangeMin * (1 - f) + rangeMax * f; +} + + +template +Vec +solidSphereRand (Rand &rand) +{ + Vec v; + + do + { + for (unsigned int i = 0; i < Vec::dimensions(); i++) + v[i] = (typename Vec::BaseType) rand.nextf (-1, 1); + } + while (v.length2() > 1); + + return v; +} + + +template +Vec +hollowSphereRand (Rand &rand) +{ + Vec v; + typename Vec::BaseType length; + + do + { + for (unsigned int i = 0; i < Vec::dimensions(); i++) + v[i] = (typename Vec::BaseType) rand.nextf (-1, 1); + + length = v.length(); + } + while (length > 1 || length == 0); + + return v / length; +} + + +template +float +gaussRand (Rand &rand) +{ + float x; // Note: to avoid numerical problems with very small + float y; // numbers, we make these variables singe-precision + float length2; // floats, but later we call the double-precision log() + // and sqrt() functions instead of logf() and sqrtf(). + do + { + x = float (rand.nextf (-1, 1)); + y = float (rand.nextf (-1, 1)); + length2 = x * x + y * y; + } + while (length2 >= 1 || length2 == 0); + + return x * sqrt (-2 * log (double (length2)) / length2); +} + + +template +Vec +gaussSphereRand (Rand &rand) +{ + return hollowSphereRand (rand) * gaussRand (rand); +} + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRoots.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRoots.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRoots.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathRoots.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,219 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHROOTS_H +#define INCLUDED_IMATHROOTS_H + +//--------------------------------------------------------------------- +// +// Functions to solve linear, quadratic or cubic equations +// +//--------------------------------------------------------------------- + +#include +#include + +namespace Imath { + +//-------------------------------------------------------------------------- +// Find the real solutions of a linear, quadratic or cubic equation: +// +// function equation solved +// +// solveLinear (a, b, x) a * x + b == 0 +// solveQuadratic (a, b, c, x) a * x*x + b * x + c == 0 +// solveNormalizedCubic (r, s, t, x) x*x*x + r * x*x + s * x + t == 0 +// solveCubic (a, b, c, d, x) a * x*x*x + b * x*x + c * x + d == 0 +// +// Return value: +// +// 3 three real solutions, stored in x[0], x[1] and x[2] +// 2 two real solutions, stored in x[0] and x[1] +// 1 one real solution, stored in x[1] +// 0 no real solutions +// -1 all real numbers are solutions +// +// Notes: +// +// * It is possible that an equation has real solutions, but that the +// solutions (or some intermediate result) are not representable. +// In this case, either some of the solutions returned are invalid +// (nan or infinity), or, if floating-point exceptions have been +// enabled with Iex::mathExcOn(), an Iex::MathExc exception is +// thrown. +// +// * Cubic equations are solved using Cardano's Formula; even though +// only real solutions are produced, some intermediate results are +// complex (std::complex). +// +//-------------------------------------------------------------------------- + +template int solveLinear (T a, T b, T &x); +template int solveQuadratic (T a, T b, T c, T x[2]); +template int solveNormalizedCubic (T r, T s, T t, T x[3]); +template int solveCubic (T a, T b, T c, T d, T x[3]); + + +//--------------- +// Implementation +//--------------- + +template +int +solveLinear (T a, T b, T &x) +{ + if (a != 0) + { + x = -b / a; + return 1; + } + else if (b != 0) + { + return 0; + } + else + { + return -1; + } +} + + +template +int +solveQuadratic (T a, T b, T c, T x[2]) +{ + if (a == 0) + { + return solveLinear (b, c, x[0]); + } + else + { + T D = b * b - 4 * a * c; + + if (D > 0) + { + T s = Math::sqrt (D); + T q = -(b + (b > 0 ? 1 : -1) * s) / T(2); + + x[0] = q / a; + x[1] = c / q; + return 2; + } + if (D == 0) + { + x[0] = -b / (2 * a); + return 1; + } + else + { + return 0; + } + } +} + + +template +int +solveNormalizedCubic (T r, T s, T t, T x[3]) +{ + T p = (3 * s - r * r) / 3; + T q = 2 * r * r * r / 27 - r * s / 3 + t; + T p3 = p / 3; + T q2 = q / 2; + T D = p3 * p3 * p3 + q2 * q2; + + if (D == 0 && p3 == 0) + { + x[0] = -r / 3; + x[1] = -r / 3; + x[2] = -r / 3; + return 1; + } + + std::complex u = std::pow (-q / 2 + std::sqrt (std::complex (D)), + T (1) / T (3)); + + std::complex v = -p / (T (3) * u); + + const T sqrt3 = T (1.73205080756887729352744634150587); // enough digits + // for long double + std::complex y0 (u + v); + + std::complex y1 (-(u + v) / T (2) + + (u - v) / T (2) * std::complex (0, sqrt3)); + + std::complex y2 (-(u + v) / T (2) - + (u - v) / T (2) * std::complex (0, sqrt3)); + + if (D > 0) + { + x[0] = y0.real() - r / 3; + return 1; + } + else if (D == 0) + { + x[0] = y0.real() - r / 3; + x[1] = y1.real() - r / 3; + return 2; + } + else + { + x[0] = y0.real() - r / 3; + x[1] = y1.real() - r / 3; + x[2] = y2.real() - r / 3; + return 3; + } +} + + +template +int +solveCubic (T a, T b, T c, T d, T x[3]) +{ + if (a == 0) + { + return solveQuadratic (b, c, d, x); + } + else + { + return solveNormalizedCubic (b / a, c / a, d / a, x); + } +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathShear.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathShear.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathShear.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathShear.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,659 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHSHEAR_H +#define INCLUDED_IMATHSHEAR_H + +//---------------------------------------------------- +// +// Shear6 class template. +// +//---------------------------------------------------- + +#include "ImathExc.h" +#include "ImathLimits.h" +#include "ImathMath.h" +#include "ImathVec.h" + +#include + + +namespace Imath { + + + + +template class Shear6 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T xy, xz, yz, yx, zx, zy; + + T & operator [] (int i); + const T & operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Shear6 (); // (0 0 0 0 0 0) + Shear6 (T XY, T XZ, T YZ); // (XY XZ YZ 0 0 0) + Shear6 (const Vec3 &v); // (v.x v.y v.z 0 0 0) + template // (v.x v.y v.z 0 0 0) + Shear6 (const Vec3 &v); + Shear6 (T XY, T XZ, T YZ, // (XY XZ YZ YX ZX ZY) + T YX, T ZX, T ZY); + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Shear6 (const Shear6 &h); + template Shear6 (const Shear6 &h); + + const Shear6 & operator = (const Shear6 &h); + template + const Shear6 & operator = (const Vec3 &v); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + template + void setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY); + + template + void setValue (const Shear6 &h); + + template + void getValue (S &XY, S &XZ, S &YZ, + S &YX, S &ZX, S &ZY) const; + + template + void getValue (Shear6 &h) const; + + T * getValue(); + const T * getValue() const; + + + //--------- + // Equality + //--------- + + template + bool operator == (const Shear6 &h) const; + + template + bool operator != (const Shear6 &h) const; + + //----------------------------------------------------------------------- + // Compare two shears and test if they are "approximately equal": + // + // equalWithAbsError (h, e) + // + // Returns true if the coefficients of this and h are the same with + // an absolute error of no more than e, i.e., for all i + // + // abs (this[i] - h[i]) <= e + // + // equalWithRelError (h, e) + // + // Returns true if the coefficients of this and h are the same with + // a relative error of no more than e, i.e., for all i + // + // abs (this[i] - h[i]) <= e * abs (this[i]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Shear6 &h, T e) const; + bool equalWithRelError (const Shear6 &h, T e) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Shear6 & operator += (const Shear6 &h); + Shear6 operator + (const Shear6 &h) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Shear6 & operator -= (const Shear6 &h); + Shear6 operator - (const Shear6 &h) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Shear6 operator - () const; + const Shear6 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Shear6 & operator *= (const Shear6 &h); + const Shear6 & operator *= (T a); + Shear6 operator * (const Shear6 &h) const; + Shear6 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Shear6 & operator /= (const Shear6 &h); + const Shear6 & operator /= (T a); + Shear6 operator / (const Shear6 &h) const; + Shear6 operator / (T a) const; + + + //---------------------------------------------------------- + // Number of dimensions, i.e. number of elements in a Shear6 + //---------------------------------------------------------- + + static unsigned int dimensions() {return 6;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + + //-------------------------------------------------------------- + // Base type -- in templates, which accept a parameter, V, which + // could be either a Vec2 or a Shear6, you can refer to T as + // V::BaseType + //-------------------------------------------------------------- + + typedef T BaseType; +}; + + +//-------------- +// Stream output +//-------------- + +template +std::ostream & operator << (std::ostream &s, const Shear6 &h); + + +//---------------------------------------------------- +// Reverse multiplication: scalar * Shear6 +//---------------------------------------------------- + +template Shear6 operator * (S a, const Shear6 &h); + + +//------------------------- +// Typedefs for convenience +//------------------------- + +typedef Vec3 Shear3f; +typedef Vec3 Shear3d; +typedef Shear6 Shear6f; +typedef Shear6 Shear6d; + + + + +//----------------------- +// Implementation of Shear6 +//----------------------- + +template +inline T & +Shear6::operator [] (int i) +{ + return (&xy)[i]; +} + +template +inline const T & +Shear6::operator [] (int i) const +{ + return (&xy)[i]; +} + +template +inline +Shear6::Shear6 () +{ + xy = xz = yz = yx = zx = zy = 0; +} + +template +inline +Shear6::Shear6 (T XY, T XZ, T YZ) +{ + xy = XY; + xz = XZ; + yz = YZ; + yx = 0; + zx = 0; + zy = 0; +} + +template +inline +Shear6::Shear6 (const Vec3 &v) +{ + xy = v.x; + xz = v.y; + yz = v.z; + yx = 0; + zx = 0; + zy = 0; +} + +template +template +inline +Shear6::Shear6 (const Vec3 &v) +{ + xy = T (v.x); + xz = T (v.y); + yz = T (v.z); + yx = 0; + zx = 0; + zy = 0; +} + +template +inline +Shear6::Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY) +{ + xy = XY; + xz = XZ; + yz = YZ; + yx = YX; + zx = ZX; + zy = ZY; +} + +template +inline +Shear6::Shear6 (const Shear6 &h) +{ + xy = h.xy; + xz = h.xz; + yz = h.yz; + yx = h.yx; + zx = h.zx; + zy = h.zy; +} + +template +template +inline +Shear6::Shear6 (const Shear6 &h) +{ + xy = T (h.xy); + xz = T (h.xz); + yz = T (h.yz); + yx = T (h.yx); + zx = T (h.zx); + zy = T (h.zy); +} + +template +inline const Shear6 & +Shear6::operator = (const Shear6 &h) +{ + xy = h.xy; + xz = h.xz; + yz = h.yz; + yx = h.yx; + zx = h.zx; + zy = h.zy; + return *this; +} + +template +template +inline const Shear6 & +Shear6::operator = (const Vec3 &v) +{ + xy = T (v.x); + xz = T (v.y); + yz = T (v.z); + yx = 0; + zx = 0; + zy = 0; + return *this; +} + +template +template +inline void +Shear6::setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY) +{ + xy = T (XY); + xz = T (XZ); + yz = T (YZ); + yx = T (YX); + zx = T (ZX); + zy = T (ZY); +} + +template +template +inline void +Shear6::setValue (const Shear6 &h) +{ + xy = T (h.xy); + xz = T (h.xz); + yz = T (h.yz); + yx = T (h.yx); + zx = T (h.zx); + zy = T (h.zy); +} + +template +template +inline void +Shear6::getValue (S &XY, S &XZ, S &YZ, S &YX, S &ZX, S &ZY) const +{ + XY = S (xy); + XZ = S (xz); + YZ = S (yz); + YX = S (yx); + ZX = S (zx); + ZY = S (zy); +} + +template +template +inline void +Shear6::getValue (Shear6 &h) const +{ + h.xy = S (xy); + h.xz = S (xz); + h.yz = S (yz); + h.yx = S (yx); + h.zx = S (zx); + h.zy = S (zy); +} + +template +inline T * +Shear6::getValue() +{ + return (T *) &xy; +} + +template +inline const T * +Shear6::getValue() const +{ + return (const T *) &xy; +} + +template +template +inline bool +Shear6::operator == (const Shear6 &h) const +{ + return xy == h.xy && xz == h.xz && yz == h.yz && + yx == h.yx && zx == h.zx && zy == h.zy; +} + +template +template +inline bool +Shear6::operator != (const Shear6 &h) const +{ + return xy != h.xy || xz != h.xz || yz != h.yz || + yx != h.yx || zx != h.zx || zy != h.zy; +} + +template +bool +Shear6::equalWithAbsError (const Shear6 &h, T e) const +{ + for (int i = 0; i < 6; i++) + if (!Imath::equalWithAbsError ((*this)[i], h[i], e)) + return false; + + return true; +} + +template +bool +Shear6::equalWithRelError (const Shear6 &h, T e) const +{ + for (int i = 0; i < 6; i++) + if (!Imath::equalWithRelError ((*this)[i], h[i], e)) + return false; + + return true; +} + + +template +inline const Shear6 & +Shear6::operator += (const Shear6 &h) +{ + xy += h.xy; + xz += h.xz; + yz += h.yz; + yx += h.yx; + zx += h.zx; + zy += h.zy; + return *this; +} + +template +inline Shear6 +Shear6::operator + (const Shear6 &h) const +{ + return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz, + yx + h.yx, zx + h.zx, zy + h.zy); +} + +template +inline const Shear6 & +Shear6::operator -= (const Shear6 &h) +{ + xy -= h.xy; + xz -= h.xz; + yz -= h.yz; + yx -= h.yx; + zx -= h.zx; + zy -= h.zy; + return *this; +} + +template +inline Shear6 +Shear6::operator - (const Shear6 &h) const +{ + return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz, + yx - h.yx, zx - h.zx, zy - h.zy); +} + +template +inline Shear6 +Shear6::operator - () const +{ + return Shear6 (-xy, -xz, -yz, -yx, -zx, -zy); +} + +template +inline const Shear6 & +Shear6::negate () +{ + xy = -xy; + xz = -xz; + yz = -yz; + yx = -yx; + zx = -zx; + zy = -zy; + return *this; +} + +template +inline const Shear6 & +Shear6::operator *= (const Shear6 &h) +{ + xy *= h.xy; + xz *= h.xz; + yz *= h.yz; + yx *= h.yx; + zx *= h.zx; + zy *= h.zy; + return *this; +} + +template +inline const Shear6 & +Shear6::operator *= (T a) +{ + xy *= a; + xz *= a; + yz *= a; + yx *= a; + zx *= a; + zy *= a; + return *this; +} + +template +inline Shear6 +Shear6::operator * (const Shear6 &h) const +{ + return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz, + yx * h.yx, zx * h.zx, zy * h.zy); +} + +template +inline Shear6 +Shear6::operator * (T a) const +{ + return Shear6 (xy * a, xz * a, yz * a, + yx * a, zx * a, zy * a); +} + +template +inline const Shear6 & +Shear6::operator /= (const Shear6 &h) +{ + xy /= h.xy; + xz /= h.xz; + yz /= h.yz; + yx /= h.yx; + zx /= h.zx; + zy /= h.zy; + return *this; +} + +template +inline const Shear6 & +Shear6::operator /= (T a) +{ + xy /= a; + xz /= a; + yz /= a; + yx /= a; + zx /= a; + zy /= a; + return *this; +} + +template +inline Shear6 +Shear6::operator / (const Shear6 &h) const +{ + return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz, + yx / h.yx, zx / h.zx, zy / h.zy); +} + +template +inline Shear6 +Shear6::operator / (T a) const +{ + return Shear6 (xy / a, xz / a, yz / a, + yx / a, zx / a, zy / a); +} + + +//----------------------------- +// Stream output implementation +//----------------------------- + +template +std::ostream & +operator << (std::ostream &s, const Shear6 &h) +{ + return s << '(' + << h.xy << ' ' << h.xz << ' ' << h.yz + << h.yx << ' ' << h.zx << ' ' << h.zy + << ')'; +} + + +//----------------------------------------- +// Implementation of reverse multiplication +//----------------------------------------- + +template +inline Shear6 +operator * (S a, const Shear6 &h) +{ + return Shear6 (a * h.xy, a * h.xz, a * h.yz, + a * h.yx, a * h.zx, a * h.zy); +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathSphere.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathSphere.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathSphere.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathSphere.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHSPHERE_H +#define INCLUDED_IMATHSPHERE_H + +//------------------------------------- +// +// A 3D sphere class template +// +//------------------------------------- + +#include "ImathVec.h" +#include "ImathBox.h" +#include "ImathLine.h" + +namespace Imath { + +template +class Sphere3 +{ + public: + + Vec3 center; + T radius; + + //--------------- + // Constructors + //--------------- + + Sphere3() : center(0,0,0), radius(0) {} + Sphere3(const Vec3 &c, T r) : center(c), radius(r) {} + + //------------------------------------------------------------------- + // Utilities: + // + // s.circumscribe(b) sets center and radius of sphere s + // so that the s tightly encloses box b. + // + // s.intersectT (l, t) If sphere s and line l intersect, then + // intersectT() computes the smallest t, + // t >= 0, so that l(t) is a point on the + // sphere. intersectT() then returns true. + // + // If s and l do not intersect, intersectT() + // returns false. + // + // s.intersect (l, i) If sphere s and line l intersect, then + // intersect() calls s.intersectT(l,t) and + // computes i = l(t). + // + // If s and l do not intersect, intersect() + // returns false. + // + //------------------------------------------------------------------- + + void circumscribe(const Box > &box); + bool intersect(const Line3 &l, Vec3 &intersection) const; + bool intersectT(const Line3 &l, T &t) const; +}; + + +//-------------------- +// Convenient typedefs +//-------------------- + +typedef Sphere3 Sphere3f; +typedef Sphere3 Sphere3d; + + +//--------------- +// Implementation +//--------------- + +template +void Sphere3::circumscribe(const Box > &box) +{ + center = T(0.5) * (box.min + box.max); + radius = (box.max - center).length(); +} + + +template +bool Sphere3::intersectT(const Line3 &line, T &t) const +{ + bool doesIntersect = true; + + Vec3 v = line.pos - center; + T B = T(2.0) * (line.dir ^ v); + T C = (v ^ v) - (radius * radius); + + // compute discriminant + // if negative, there is no intersection + + T discr = B*B - T(4.0)*C; + + if (discr < 0.0) + { + // line and Sphere3 do not intersect + + doesIntersect = false; + } + else + { + // t0: (-B - sqrt(B^2 - 4AC)) / 2A (A = 1) + + T sqroot = Math::sqrt(discr); + t = (-B - sqroot) * T(0.5); + + if (t < 0.0) + { + // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1) + + t = (-B + sqroot) * T(0.5); + } + + if (t < 0.0) + doesIntersect = false; + } + + return doesIntersect; +} + + +template +bool Sphere3::intersect(const Line3 &line, Vec3 &intersection) const +{ + T t; + + if (intersectT (line, t)) + { + intersection = line(t); + return true; + } + else + { + return false; + } +} + + +} //namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,540 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +//---------------------------------------------------------------------------- +// +// Specializations of the Vec2 and Vec3 templates. +// +//---------------------------------------------------------------------------- + +#include "ImathVec.h" + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// suppress exception specification warnings +#pragma warning(disable:4290) +#endif + + +namespace Imath { + +namespace +{ + +template +bool +normalizeOrThrow(Vec2 &v) +{ + int axis = -1; + for (int i = 0; i < 2; i ++) + { + if (v[i] != 0) + { + if (axis != -1) + { + throw IntVecNormalizeExc ("Cannot normalize an integer " + "vector unless it is parallel " + "to a principal axis"); + } + axis = i; + } + } + v[axis] = (v[axis] > 0) ? 1 : -1; + return true; +} + + +template +bool +normalizeOrThrow(Vec3 &v) +{ + int axis = -1; + for (int i = 0; i < 3; i ++) + { + if (v[i] != 0) + { + if (axis != -1) + { + throw IntVecNormalizeExc ("Cannot normalize an integer " + "vector unless it is parallel " + "to a principal axis"); + } + axis = i; + } + } + v[axis] = (v[axis] > 0) ? 1 : -1; + return true; +} + + +template +bool +normalizeOrThrow(Vec4 &v) +{ + int axis = -1; + for (int i = 0; i < 4; i ++) + { + if (v[i] != 0) + { + if (axis != -1) + { + throw IntVecNormalizeExc ("Cannot normalize an integer " + "vector unless it is parallel " + "to a principal axis"); + } + axis = i; + } + } + v[axis] = (v[axis] > 0) ? 1 : -1; + return true; +} + +} + + +// Vec2 + +template <> +short +Vec2::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + short lenS = (short) (lenF + 0.5f); + return lenS; +} + +template <> +const Vec2 & +Vec2::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec2 & +Vec2::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec2 & +Vec2::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec2 +Vec2::normalized () const +{ + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec2 +Vec2::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec2 +Vec2::normalizedNonNull () const +{ + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + + +// Vec2 + +template <> +int +Vec2::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + int lenI = (int) (lenF + 0.5f); + return lenI; +} + +template <> +const Vec2 & +Vec2::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec2 & +Vec2::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec2 & +Vec2::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec2 +Vec2::normalized () const +{ + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec2 +Vec2::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec2 +Vec2::normalizedNonNull () const +{ + Vec2 v(*this); + normalizeOrThrow(v); + return v; +} + + +// Vec3 + +template <> +short +Vec3::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + short lenS = (short) (lenF + 0.5f); + return lenS; +} + +template <> +const Vec3 & +Vec3::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec3 & +Vec3::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec3 & +Vec3::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec3 +Vec3::normalized () const +{ + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec3 +Vec3::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec3 +Vec3::normalizedNonNull () const +{ + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + + +// Vec3 + +template <> +int +Vec3::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + int lenI = (int) (lenF + 0.5f); + return lenI; +} + +template <> +const Vec3 & +Vec3::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec3 & +Vec3::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec3 & +Vec3::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec3 +Vec3::normalized () const +{ + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec3 +Vec3::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec3 +Vec3::normalizedNonNull () const +{ + Vec3 v(*this); + normalizeOrThrow(v); + return v; +} + + +// Vec4 + +template <> +short +Vec4::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + short lenS = (short) (lenF + 0.5f); + return lenS; +} + +template <> +const Vec4 & +Vec4::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec4 & +Vec4::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0) && (w == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec4 & +Vec4::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec4 +Vec4::normalized () const +{ + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec4 +Vec4::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0) && (w == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec4 +Vec4::normalizedNonNull () const +{ + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + + +// Vec4 + +template <> +int +Vec4::length () const +{ + float lenF = Math::sqrt ((float)dot (*this)); + int lenI = (int) (lenF + 0.5f); + return lenI; +} + +template <> +const Vec4 & +Vec4::normalize () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec4 & +Vec4::normalizeExc () throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0) && (w == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + normalizeOrThrow(*this); + return *this; +} + +template <> +const Vec4 & +Vec4::normalizeNonNull () +{ + normalizeOrThrow(*this); + return *this; +} + +template <> +Vec4 +Vec4::normalized () const +{ + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec4 +Vec4::normalizedExc () const throw (Iex::MathExc) +{ + if ((x == 0) && (y == 0) && (z == 0) && (w == 0)) + throw NullVecExc ("Cannot normalize null vector."); + + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + +template <> +Vec4 +Vec4::normalizedNonNull () const +{ + Vec4 v(*this); + normalizeOrThrow(v); + return v; +} + +} // namespace Imath diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVec.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2226 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHVEC_H +#define INCLUDED_IMATHVEC_H + +//---------------------------------------------------- +// +// 2D, 3D and 4D point/vector class templates +// +//---------------------------------------------------- + +#include "ImathExc.h" +#include "ImathLimits.h" +#include "ImathMath.h" + +#include + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +// suppress exception specification warnings +#pragma warning(push) +#pragma warning(disable:4290) +#endif + + +namespace Imath { + +template class Vec2; +template class Vec3; +template class Vec4; + +enum InfException {INF_EXCEPTION}; + + +template class Vec2 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T x, y; + + T & operator [] (int i); + const T & operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Vec2 (); // no initialization + explicit Vec2 (T a); // (a a) + Vec2 (T a, T b); // (a b) + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Vec2 (const Vec2 &v); + template Vec2 (const Vec2 &v); + + const Vec2 & operator = (const Vec2 &v); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + template + void setValue (S a, S b); + + template + void setValue (const Vec2 &v); + + template + void getValue (S &a, S &b) const; + + template + void getValue (Vec2 &v) const; + + T * getValue (); + const T * getValue () const; + + + //--------- + // Equality + //--------- + + template + bool operator == (const Vec2 &v) const; + + template + bool operator != (const Vec2 &v) const; + + + //----------------------------------------------------------------------- + // Compare two vectors and test if they are "approximately equal": + // + // equalWithAbsError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // an absolute error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e + // + // equalWithRelError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // a relative error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e * abs (this[i]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Vec2 &v, T e) const; + bool equalWithRelError (const Vec2 &v, T e) const; + + //------------ + // Dot product + //------------ + + T dot (const Vec2 &v) const; + T operator ^ (const Vec2 &v) const; + + + //------------------------------------------------ + // Right-handed cross product, i.e. z component of + // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) + //------------------------------------------------ + + T cross (const Vec2 &v) const; + T operator % (const Vec2 &v) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Vec2 & operator += (const Vec2 &v); + Vec2 operator + (const Vec2 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Vec2 & operator -= (const Vec2 &v); + Vec2 operator - (const Vec2 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Vec2 operator - () const; + const Vec2 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Vec2 & operator *= (const Vec2 &v); + const Vec2 & operator *= (T a); + Vec2 operator * (const Vec2 &v) const; + Vec2 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Vec2 & operator /= (const Vec2 &v); + const Vec2 & operator /= (T a); + Vec2 operator / (const Vec2 &v) const; + Vec2 operator / (T a) const; + + + //---------------------------------------------------------------- + // Length and normalization: If v.length() is 0.0, v.normalize() + // and v.normalized() produce a null vector; v.normalizeExc() and + // v.normalizedExc() throw a NullVecExc. + // v.normalizeNonNull() and v.normalizedNonNull() are slightly + // faster than the other normalization routines, but if v.length() + // is 0.0, the result is undefined. + //---------------------------------------------------------------- + + T length () const; + T length2 () const; + + const Vec2 & normalize (); // modifies *this + const Vec2 & normalizeExc () throw (Iex::MathExc); + const Vec2 & normalizeNonNull (); + + Vec2 normalized () const; // does not modify *this + Vec2 normalizedExc () const throw (Iex::MathExc); + Vec2 normalizedNonNull () const; + + + //-------------------------------------------------------- + // Number of dimensions, i.e. number of elements in a Vec2 + //-------------------------------------------------------- + + static unsigned int dimensions() {return 2;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + + //-------------------------------------------------------------- + // Base type -- in templates, which accept a parameter, V, which + // could be either a Vec2, a Vec3, or a Vec4 you can + // refer to T as V::BaseType + //-------------------------------------------------------------- + + typedef T BaseType; + + private: + + T lengthTiny () const; +}; + + +template class Vec3 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T x, y, z; + + T & operator [] (int i); + const T & operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Vec3 (); // no initialization + explicit Vec3 (T a); // (a a a) + Vec3 (T a, T b, T c); // (a b c) + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Vec3 (const Vec3 &v); + template Vec3 (const Vec3 &v); + + const Vec3 & operator = (const Vec3 &v); + + + //--------------------------------------------------------- + // Vec4 to Vec3 conversion, divides x, y and z by w: + // + // The one-argument conversion function divides by w even + // if w is zero. The result depends on how the environment + // handles floating-point exceptions. + // + // The two-argument version thows an InfPointExc exception + // if w is zero or if division by w would overflow. + //--------------------------------------------------------- + + template explicit Vec3 (const Vec4 &v); + template explicit Vec3 (const Vec4 &v, InfException); + + + //---------------------- + // Compatibility with Sb + //---------------------- + + template + void setValue (S a, S b, S c); + + template + void setValue (const Vec3 &v); + + template + void getValue (S &a, S &b, S &c) const; + + template + void getValue (Vec3 &v) const; + + T * getValue(); + const T * getValue() const; + + + //--------- + // Equality + //--------- + + template + bool operator == (const Vec3 &v) const; + + template + bool operator != (const Vec3 &v) const; + + //----------------------------------------------------------------------- + // Compare two vectors and test if they are "approximately equal": + // + // equalWithAbsError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // an absolute error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e + // + // equalWithRelError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // a relative error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e * abs (this[i]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Vec3 &v, T e) const; + bool equalWithRelError (const Vec3 &v, T e) const; + + //------------ + // Dot product + //------------ + + T dot (const Vec3 &v) const; + T operator ^ (const Vec3 &v) const; + + + //--------------------------- + // Right-handed cross product + //--------------------------- + + Vec3 cross (const Vec3 &v) const; + const Vec3 & operator %= (const Vec3 &v); + Vec3 operator % (const Vec3 &v) const; + + + //------------------------ + // Component-wise addition + //------------------------ + + const Vec3 & operator += (const Vec3 &v); + Vec3 operator + (const Vec3 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Vec3 & operator -= (const Vec3 &v); + Vec3 operator - (const Vec3 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Vec3 operator - () const; + const Vec3 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Vec3 & operator *= (const Vec3 &v); + const Vec3 & operator *= (T a); + Vec3 operator * (const Vec3 &v) const; + Vec3 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Vec3 & operator /= (const Vec3 &v); + const Vec3 & operator /= (T a); + Vec3 operator / (const Vec3 &v) const; + Vec3 operator / (T a) const; + + + //---------------------------------------------------------------- + // Length and normalization: If v.length() is 0.0, v.normalize() + // and v.normalized() produce a null vector; v.normalizeExc() and + // v.normalizedExc() throw a NullVecExc. + // v.normalizeNonNull() and v.normalizedNonNull() are slightly + // faster than the other normalization routines, but if v.length() + // is 0.0, the result is undefined. + //---------------------------------------------------------------- + + T length () const; + T length2 () const; + + const Vec3 & normalize (); // modifies *this + const Vec3 & normalizeExc () throw (Iex::MathExc); + const Vec3 & normalizeNonNull (); + + Vec3 normalized () const; // does not modify *this + Vec3 normalizedExc () const throw (Iex::MathExc); + Vec3 normalizedNonNull () const; + + + //-------------------------------------------------------- + // Number of dimensions, i.e. number of elements in a Vec3 + //-------------------------------------------------------- + + static unsigned int dimensions() {return 3;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + + //-------------------------------------------------------------- + // Base type -- in templates, which accept a parameter, V, which + // could be either a Vec2, a Vec3, or a Vec4 you can + // refer to T as V::BaseType + //-------------------------------------------------------------- + + typedef T BaseType; + + private: + + T lengthTiny () const; +}; + + + +template class Vec4 +{ + public: + + //------------------- + // Access to elements + //------------------- + + T x, y, z, w; + + T & operator [] (int i); + const T & operator [] (int i) const; + + + //------------- + // Constructors + //------------- + + Vec4 (); // no initialization + explicit Vec4 (T a); // (a a a a) + Vec4 (T a, T b, T c, T d); // (a b c d) + + + //--------------------------------- + // Copy constructors and assignment + //--------------------------------- + + Vec4 (const Vec4 &v); + template Vec4 (const Vec4 &v); + + const Vec4 & operator = (const Vec4 &v); + + + //------------------------------------- + // Vec3 to Vec4 conversion, sets w to 1 + //------------------------------------- + + template explicit Vec4 (const Vec3 &v); + + + //--------- + // Equality + //--------- + + template + bool operator == (const Vec4 &v) const; + + template + bool operator != (const Vec4 &v) const; + + + //----------------------------------------------------------------------- + // Compare two vectors and test if they are "approximately equal": + // + // equalWithAbsError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // an absolute error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e + // + // equalWithRelError (v, e) + // + // Returns true if the coefficients of this and v are the same with + // a relative error of no more than e, i.e., for all i + // + // abs (this[i] - v[i]) <= e * abs (this[i]) + //----------------------------------------------------------------------- + + bool equalWithAbsError (const Vec4 &v, T e) const; + bool equalWithRelError (const Vec4 &v, T e) const; + + + //------------ + // Dot product + //------------ + + T dot (const Vec4 &v) const; + T operator ^ (const Vec4 &v) const; + + + //----------------------------------- + // Cross product is not defined in 4D + //----------------------------------- + + //------------------------ + // Component-wise addition + //------------------------ + + const Vec4 & operator += (const Vec4 &v); + Vec4 operator + (const Vec4 &v) const; + + + //--------------------------- + // Component-wise subtraction + //--------------------------- + + const Vec4 & operator -= (const Vec4 &v); + Vec4 operator - (const Vec4 &v) const; + + + //------------------------------------ + // Component-wise multiplication by -1 + //------------------------------------ + + Vec4 operator - () const; + const Vec4 & negate (); + + + //------------------------------ + // Component-wise multiplication + //------------------------------ + + const Vec4 & operator *= (const Vec4 &v); + const Vec4 & operator *= (T a); + Vec4 operator * (const Vec4 &v) const; + Vec4 operator * (T a) const; + + + //------------------------ + // Component-wise division + //------------------------ + + const Vec4 & operator /= (const Vec4 &v); + const Vec4 & operator /= (T a); + Vec4 operator / (const Vec4 &v) const; + Vec4 operator / (T a) const; + + + //---------------------------------------------------------------- + // Length and normalization: If v.length() is 0.0, v.normalize() + // and v.normalized() produce a null vector; v.normalizeExc() and + // v.normalizedExc() throw a NullVecExc. + // v.normalizeNonNull() and v.normalizedNonNull() are slightly + // faster than the other normalization routines, but if v.length() + // is 0.0, the result is undefined. + //---------------------------------------------------------------- + + T length () const; + T length2 () const; + + const Vec4 & normalize (); // modifies *this + const Vec4 & normalizeExc () throw (Iex::MathExc); + const Vec4 & normalizeNonNull (); + + Vec4 normalized () const; // does not modify *this + Vec4 normalizedExc () const throw (Iex::MathExc); + Vec4 normalizedNonNull () const; + + + //-------------------------------------------------------- + // Number of dimensions, i.e. number of elements in a Vec4 + //-------------------------------------------------------- + + static unsigned int dimensions() {return 4;} + + + //------------------------------------------------- + // Limitations of type T (see also class limits) + //------------------------------------------------- + + static T baseTypeMin() {return limits::min();} + static T baseTypeMax() {return limits::max();} + static T baseTypeSmallest() {return limits::smallest();} + static T baseTypeEpsilon() {return limits::epsilon();} + + + //-------------------------------------------------------------- + // Base type -- in templates, which accept a parameter, V, which + // could be either a Vec2, a Vec3, or a Vec4 you can + // refer to T as V::BaseType + //-------------------------------------------------------------- + + typedef T BaseType; + + private: + + T lengthTiny () const; +}; + + +//-------------- +// Stream output +//-------------- + +template +std::ostream & operator << (std::ostream &s, const Vec2 &v); + +template +std::ostream & operator << (std::ostream &s, const Vec3 &v); + +template +std::ostream & operator << (std::ostream &s, const Vec4 &v); + +//---------------------------------------------------- +// Reverse multiplication: S * Vec2 and S * Vec3 +//---------------------------------------------------- + +template Vec2 operator * (T a, const Vec2 &v); +template Vec3 operator * (T a, const Vec3 &v); +template Vec4 operator * (T a, const Vec4 &v); + + +//------------------------- +// Typedefs for convenience +//------------------------- + +typedef Vec2 V2s; +typedef Vec2 V2i; +typedef Vec2 V2f; +typedef Vec2 V2d; +typedef Vec3 V3s; +typedef Vec3 V3i; +typedef Vec3 V3f; +typedef Vec3 V3d; +typedef Vec4 V4s; +typedef Vec4 V4i; +typedef Vec4 V4f; +typedef Vec4 V4d; + + +//------------------------------------------- +// Specializations for VecN, VecN +//------------------------------------------- + +// Vec2 + +template <> short +Vec2::length () const; + +template <> const Vec2 & +Vec2::normalize (); + +template <> const Vec2 & +Vec2::normalizeExc () throw (Iex::MathExc); + +template <> const Vec2 & +Vec2::normalizeNonNull (); + +template <> Vec2 +Vec2::normalized () const; + +template <> Vec2 +Vec2::normalizedExc () const throw (Iex::MathExc); + +template <> Vec2 +Vec2::normalizedNonNull () const; + + +// Vec2 + +template <> int +Vec2::length () const; + +template <> const Vec2 & +Vec2::normalize (); + +template <> const Vec2 & +Vec2::normalizeExc () throw (Iex::MathExc); + +template <> const Vec2 & +Vec2::normalizeNonNull (); + +template <> Vec2 +Vec2::normalized () const; + +template <> Vec2 +Vec2::normalizedExc () const throw (Iex::MathExc); + +template <> Vec2 +Vec2::normalizedNonNull () const; + + +// Vec3 + +template <> short +Vec3::length () const; + +template <> const Vec3 & +Vec3::normalize (); + +template <> const Vec3 & +Vec3::normalizeExc () throw (Iex::MathExc); + +template <> const Vec3 & +Vec3::normalizeNonNull (); + +template <> Vec3 +Vec3::normalized () const; + +template <> Vec3 +Vec3::normalizedExc () const throw (Iex::MathExc); + +template <> Vec3 +Vec3::normalizedNonNull () const; + + +// Vec3 + +template <> int +Vec3::length () const; + +template <> const Vec3 & +Vec3::normalize (); + +template <> const Vec3 & +Vec3::normalizeExc () throw (Iex::MathExc); + +template <> const Vec3 & +Vec3::normalizeNonNull (); + +template <> Vec3 +Vec3::normalized () const; + +template <> Vec3 +Vec3::normalizedExc () const throw (Iex::MathExc); + +template <> Vec3 +Vec3::normalizedNonNull () const; + +// Vec4 + +template <> short +Vec4::length () const; + +template <> const Vec4 & +Vec4::normalize (); + +template <> const Vec4 & +Vec4::normalizeExc () throw (Iex::MathExc); + +template <> const Vec4 & +Vec4::normalizeNonNull (); + +template <> Vec4 +Vec4::normalized () const; + +template <> Vec4 +Vec4::normalizedExc () const throw (Iex::MathExc); + +template <> Vec4 +Vec4::normalizedNonNull () const; + + +// Vec4 + +template <> int +Vec4::length () const; + +template <> const Vec4 & +Vec4::normalize (); + +template <> const Vec4 & +Vec4::normalizeExc () throw (Iex::MathExc); + +template <> const Vec4 & +Vec4::normalizeNonNull (); + +template <> Vec4 +Vec4::normalized () const; + +template <> Vec4 +Vec4::normalizedExc () const throw (Iex::MathExc); + +template <> Vec4 +Vec4::normalizedNonNull () const; + + +//------------------------ +// Implementation of Vec2: +//------------------------ + +template +inline T & +Vec2::operator [] (int i) +{ + return (&x)[i]; +} + +template +inline const T & +Vec2::operator [] (int i) const +{ + return (&x)[i]; +} + +template +inline +Vec2::Vec2 () +{ + // empty +} + +template +inline +Vec2::Vec2 (T a) +{ + x = y = a; +} + +template +inline +Vec2::Vec2 (T a, T b) +{ + x = a; + y = b; +} + +template +inline +Vec2::Vec2 (const Vec2 &v) +{ + x = v.x; + y = v.y; +} + +template +template +inline +Vec2::Vec2 (const Vec2 &v) +{ + x = T (v.x); + y = T (v.y); +} + +template +inline const Vec2 & +Vec2::operator = (const Vec2 &v) +{ + x = v.x; + y = v.y; + return *this; +} + +template +template +inline void +Vec2::setValue (S a, S b) +{ + x = T (a); + y = T (b); +} + +template +template +inline void +Vec2::setValue (const Vec2 &v) +{ + x = T (v.x); + y = T (v.y); +} + +template +template +inline void +Vec2::getValue (S &a, S &b) const +{ + a = S (x); + b = S (y); +} + +template +template +inline void +Vec2::getValue (Vec2 &v) const +{ + v.x = S (x); + v.y = S (y); +} + +template +inline T * +Vec2::getValue() +{ + return (T *) &x; +} + +template +inline const T * +Vec2::getValue() const +{ + return (const T *) &x; +} + +template +template +inline bool +Vec2::operator == (const Vec2 &v) const +{ + return x == v.x && y == v.y; +} + +template +template +inline bool +Vec2::operator != (const Vec2 &v) const +{ + return x != v.x || y != v.y; +} + +template +bool +Vec2::equalWithAbsError (const Vec2 &v, T e) const +{ + for (int i = 0; i < 2; i++) + if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +bool +Vec2::equalWithRelError (const Vec2 &v, T e) const +{ + for (int i = 0; i < 2; i++) + if (!Imath::equalWithRelError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +inline T +Vec2::dot (const Vec2 &v) const +{ + return x * v.x + y * v.y; +} + +template +inline T +Vec2::operator ^ (const Vec2 &v) const +{ + return dot (v); +} + +template +inline T +Vec2::cross (const Vec2 &v) const +{ + return x * v.y - y * v.x; + +} + +template +inline T +Vec2::operator % (const Vec2 &v) const +{ + return x * v.y - y * v.x; +} + +template +inline const Vec2 & +Vec2::operator += (const Vec2 &v) +{ + x += v.x; + y += v.y; + return *this; +} + +template +inline Vec2 +Vec2::operator + (const Vec2 &v) const +{ + return Vec2 (x + v.x, y + v.y); +} + +template +inline const Vec2 & +Vec2::operator -= (const Vec2 &v) +{ + x -= v.x; + y -= v.y; + return *this; +} + +template +inline Vec2 +Vec2::operator - (const Vec2 &v) const +{ + return Vec2 (x - v.x, y - v.y); +} + +template +inline Vec2 +Vec2::operator - () const +{ + return Vec2 (-x, -y); +} + +template +inline const Vec2 & +Vec2::negate () +{ + x = -x; + y = -y; + return *this; +} + +template +inline const Vec2 & +Vec2::operator *= (const Vec2 &v) +{ + x *= v.x; + y *= v.y; + return *this; +} + +template +inline const Vec2 & +Vec2::operator *= (T a) +{ + x *= a; + y *= a; + return *this; +} + +template +inline Vec2 +Vec2::operator * (const Vec2 &v) const +{ + return Vec2 (x * v.x, y * v.y); +} + +template +inline Vec2 +Vec2::operator * (T a) const +{ + return Vec2 (x * a, y * a); +} + +template +inline const Vec2 & +Vec2::operator /= (const Vec2 &v) +{ + x /= v.x; + y /= v.y; + return *this; +} + +template +inline const Vec2 & +Vec2::operator /= (T a) +{ + x /= a; + y /= a; + return *this; +} + +template +inline Vec2 +Vec2::operator / (const Vec2 &v) const +{ + return Vec2 (x / v.x, y / v.y); +} + +template +inline Vec2 +Vec2::operator / (T a) const +{ + return Vec2 (x / a, y / a); +} + +template +T +Vec2::lengthTiny () const +{ + T absX = (x >= T (0))? x: -x; + T absY = (y >= T (0))? y: -y; + + T max = absX; + + if (max < absY) + max = absY; + + if (max == T (0)) + return T (0); + + // + // Do not replace the divisions by max with multiplications by 1/max. + // Computing 1/max can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + absX /= max; + absY /= max; + + return max * Math::sqrt (absX * absX + absY * absY); +} + +template +inline T +Vec2::length () const +{ + T length2 = dot (*this); + + if (length2 < T (2) * limits::smallest()) + return lengthTiny(); + + return Math::sqrt (length2); +} + +template +inline T +Vec2::length2 () const +{ + return dot (*this); +} + +template +const Vec2 & +Vec2::normalize () +{ + T l = length(); + + if (l != T (0)) + { + // + // Do not replace the divisions by l with multiplications by 1/l. + // Computing 1/l can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + x /= l; + y /= l; + } + + return *this; +} + +template +const Vec2 & +Vec2::normalizeExc () throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + x /= l; + y /= l; + return *this; +} + +template +inline +const Vec2 & +Vec2::normalizeNonNull () +{ + T l = length(); + x /= l; + y /= l; + return *this; +} + +template +Vec2 +Vec2::normalized () const +{ + T l = length(); + + if (l == T (0)) + return Vec2 (T (0)); + + return Vec2 (x / l, y / l); +} + +template +Vec2 +Vec2::normalizedExc () const throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + return Vec2 (x / l, y / l); +} + +template +inline +Vec2 +Vec2::normalizedNonNull () const +{ + T l = length(); + return Vec2 (x / l, y / l); +} + + +//----------------------- +// Implementation of Vec3 +//----------------------- + +template +inline T & +Vec3::operator [] (int i) +{ + return (&x)[i]; +} + +template +inline const T & +Vec3::operator [] (int i) const +{ + return (&x)[i]; +} + +template +inline +Vec3::Vec3 () +{ + // empty +} + +template +inline +Vec3::Vec3 (T a) +{ + x = y = z = a; +} + +template +inline +Vec3::Vec3 (T a, T b, T c) +{ + x = a; + y = b; + z = c; +} + +template +inline +Vec3::Vec3 (const Vec3 &v) +{ + x = v.x; + y = v.y; + z = v.z; +} + +template +template +inline +Vec3::Vec3 (const Vec3 &v) +{ + x = T (v.x); + y = T (v.y); + z = T (v.z); +} + +template +inline const Vec3 & +Vec3::operator = (const Vec3 &v) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + +template +template +inline +Vec3::Vec3 (const Vec4 &v) +{ + x = T (v.x / v.w); + y = T (v.y / v.w); + z = T (v.z / v.w); +} + +template +template +Vec3::Vec3 (const Vec4 &v, InfException) +{ + T vx = T (v.x); + T vy = T (v.y); + T vz = T (v.z); + T vw = T (v.w); + + T absW = (vw >= T (0))? vw: -vw; + + if (absW < 1) + { + T m = baseTypeMax() * absW; + + if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m) + throw InfPointExc ("Cannot normalize point at infinity."); + } + + x = vx / vw; + y = vy / vw; + z = vz / vw; +} + +template +template +inline void +Vec3::setValue (S a, S b, S c) +{ + x = T (a); + y = T (b); + z = T (c); +} + +template +template +inline void +Vec3::setValue (const Vec3 &v) +{ + x = T (v.x); + y = T (v.y); + z = T (v.z); +} + +template +template +inline void +Vec3::getValue (S &a, S &b, S &c) const +{ + a = S (x); + b = S (y); + c = S (z); +} + +template +template +inline void +Vec3::getValue (Vec3 &v) const +{ + v.x = S (x); + v.y = S (y); + v.z = S (z); +} + +template +inline T * +Vec3::getValue() +{ + return (T *) &x; +} + +template +inline const T * +Vec3::getValue() const +{ + return (const T *) &x; +} + +template +template +inline bool +Vec3::operator == (const Vec3 &v) const +{ + return x == v.x && y == v.y && z == v.z; +} + +template +template +inline bool +Vec3::operator != (const Vec3 &v) const +{ + return x != v.x || y != v.y || z != v.z; +} + +template +bool +Vec3::equalWithAbsError (const Vec3 &v, T e) const +{ + for (int i = 0; i < 3; i++) + if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +bool +Vec3::equalWithRelError (const Vec3 &v, T e) const +{ + for (int i = 0; i < 3; i++) + if (!Imath::equalWithRelError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +inline T +Vec3::dot (const Vec3 &v) const +{ + return x * v.x + y * v.y + z * v.z; +} + +template +inline T +Vec3::operator ^ (const Vec3 &v) const +{ + return dot (v); +} + +template +inline Vec3 +Vec3::cross (const Vec3 &v) const +{ + return Vec3 (y * v.z - z * v.y, + z * v.x - x * v.z, + x * v.y - y * v.x); +} + +template +inline const Vec3 & +Vec3::operator %= (const Vec3 &v) +{ + T a = y * v.z - z * v.y; + T b = z * v.x - x * v.z; + T c = x * v.y - y * v.x; + x = a; + y = b; + z = c; + return *this; +} + +template +inline Vec3 +Vec3::operator % (const Vec3 &v) const +{ + return Vec3 (y * v.z - z * v.y, + z * v.x - x * v.z, + x * v.y - y * v.x); +} + +template +inline const Vec3 & +Vec3::operator += (const Vec3 &v) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + +template +inline Vec3 +Vec3::operator + (const Vec3 &v) const +{ + return Vec3 (x + v.x, y + v.y, z + v.z); +} + +template +inline const Vec3 & +Vec3::operator -= (const Vec3 &v) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + +template +inline Vec3 +Vec3::operator - (const Vec3 &v) const +{ + return Vec3 (x - v.x, y - v.y, z - v.z); +} + +template +inline Vec3 +Vec3::operator - () const +{ + return Vec3 (-x, -y, -z); +} + +template +inline const Vec3 & +Vec3::negate () +{ + x = -x; + y = -y; + z = -z; + return *this; +} + +template +inline const Vec3 & +Vec3::operator *= (const Vec3 &v) +{ + x *= v.x; + y *= v.y; + z *= v.z; + return *this; +} + +template +inline const Vec3 & +Vec3::operator *= (T a) +{ + x *= a; + y *= a; + z *= a; + return *this; +} + +template +inline Vec3 +Vec3::operator * (const Vec3 &v) const +{ + return Vec3 (x * v.x, y * v.y, z * v.z); +} + +template +inline Vec3 +Vec3::operator * (T a) const +{ + return Vec3 (x * a, y * a, z * a); +} + +template +inline const Vec3 & +Vec3::operator /= (const Vec3 &v) +{ + x /= v.x; + y /= v.y; + z /= v.z; + return *this; +} + +template +inline const Vec3 & +Vec3::operator /= (T a) +{ + x /= a; + y /= a; + z /= a; + return *this; +} + +template +inline Vec3 +Vec3::operator / (const Vec3 &v) const +{ + return Vec3 (x / v.x, y / v.y, z / v.z); +} + +template +inline Vec3 +Vec3::operator / (T a) const +{ + return Vec3 (x / a, y / a, z / a); +} + +template +T +Vec3::lengthTiny () const +{ + T absX = (x >= T (0))? x: -x; + T absY = (y >= T (0))? y: -y; + T absZ = (z >= T (0))? z: -z; + + T max = absX; + + if (max < absY) + max = absY; + + if (max < absZ) + max = absZ; + + if (max == T (0)) + return T (0); + + // + // Do not replace the divisions by max with multiplications by 1/max. + // Computing 1/max can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + absX /= max; + absY /= max; + absZ /= max; + + return max * Math::sqrt (absX * absX + absY * absY + absZ * absZ); +} + +template +inline T +Vec3::length () const +{ + T length2 = dot (*this); + + if (length2 < T (2) * limits::smallest()) + return lengthTiny(); + + return Math::sqrt (length2); +} + +template +inline T +Vec3::length2 () const +{ + return dot (*this); +} + +template +const Vec3 & +Vec3::normalize () +{ + T l = length(); + + if (l != T (0)) + { + // + // Do not replace the divisions by l with multiplications by 1/l. + // Computing 1/l can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + x /= l; + y /= l; + z /= l; + } + + return *this; +} + +template +const Vec3 & +Vec3::normalizeExc () throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + x /= l; + y /= l; + z /= l; + return *this; +} + +template +inline +const Vec3 & +Vec3::normalizeNonNull () +{ + T l = length(); + x /= l; + y /= l; + z /= l; + return *this; +} + +template +Vec3 +Vec3::normalized () const +{ + T l = length(); + + if (l == T (0)) + return Vec3 (T (0)); + + return Vec3 (x / l, y / l, z / l); +} + +template +Vec3 +Vec3::normalizedExc () const throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + return Vec3 (x / l, y / l, z / l); +} + +template +inline +Vec3 +Vec3::normalizedNonNull () const +{ + T l = length(); + return Vec3 (x / l, y / l, z / l); +} + + +//----------------------- +// Implementation of Vec4 +//----------------------- + +template +inline T & +Vec4::operator [] (int i) +{ + return (&x)[i]; +} + +template +inline const T & +Vec4::operator [] (int i) const +{ + return (&x)[i]; +} + +template +inline +Vec4::Vec4 () +{ + // empty +} + +template +inline +Vec4::Vec4 (T a) +{ + x = y = z = w = a; +} + +template +inline +Vec4::Vec4 (T a, T b, T c, T d) +{ + x = a; + y = b; + z = c; + w = d; +} + +template +inline +Vec4::Vec4 (const Vec4 &v) +{ + x = v.x; + y = v.y; + z = v.z; + w = v.w; +} + +template +template +inline +Vec4::Vec4 (const Vec4 &v) +{ + x = T (v.x); + y = T (v.y); + z = T (v.z); + w = T (v.w); +} + +template +inline const Vec4 & +Vec4::operator = (const Vec4 &v) +{ + x = v.x; + y = v.y; + z = v.z; + w = v.w; + return *this; +} + +template +template +inline +Vec4::Vec4 (const Vec3 &v) +{ + x = T (v.x); + y = T (v.y); + z = T (v.z); + w = T (1); +} + +template +template +inline bool +Vec4::operator == (const Vec4 &v) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +template +template +inline bool +Vec4::operator != (const Vec4 &v) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + +template +bool +Vec4::equalWithAbsError (const Vec4 &v, T e) const +{ + for (int i = 0; i < 4; i++) + if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +bool +Vec4::equalWithRelError (const Vec4 &v, T e) const +{ + for (int i = 0; i < 4; i++) + if (!Imath::equalWithRelError ((*this)[i], v[i], e)) + return false; + + return true; +} + +template +inline T +Vec4::dot (const Vec4 &v) const +{ + return x * v.x + y * v.y + z * v.z + w * v.w; +} + +template +inline T +Vec4::operator ^ (const Vec4 &v) const +{ + return dot (v); +} + + +template +inline const Vec4 & +Vec4::operator += (const Vec4 &v) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; +} + +template +inline Vec4 +Vec4::operator + (const Vec4 &v) const +{ + return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w); +} + +template +inline const Vec4 & +Vec4::operator -= (const Vec4 &v) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; +} + +template +inline Vec4 +Vec4::operator - (const Vec4 &v) const +{ + return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w); +} + +template +inline Vec4 +Vec4::operator - () const +{ + return Vec4 (-x, -y, -z, -w); +} + +template +inline const Vec4 & +Vec4::negate () +{ + x = -x; + y = -y; + z = -z; + w = -w; + return *this; +} + +template +inline const Vec4 & +Vec4::operator *= (const Vec4 &v) +{ + x *= v.x; + y *= v.y; + z *= v.z; + w *= v.w; + return *this; +} + +template +inline const Vec4 & +Vec4::operator *= (T a) +{ + x *= a; + y *= a; + z *= a; + w *= a; + return *this; +} + +template +inline Vec4 +Vec4::operator * (const Vec4 &v) const +{ + return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w); +} + +template +inline Vec4 +Vec4::operator * (T a) const +{ + return Vec4 (x * a, y * a, z * a, w * a); +} + +template +inline const Vec4 & +Vec4::operator /= (const Vec4 &v) +{ + x /= v.x; + y /= v.y; + z /= v.z; + w /= v.w; + return *this; +} + +template +inline const Vec4 & +Vec4::operator /= (T a) +{ + x /= a; + y /= a; + z /= a; + w /= a; + return *this; +} + +template +inline Vec4 +Vec4::operator / (const Vec4 &v) const +{ + return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w); +} + +template +inline Vec4 +Vec4::operator / (T a) const +{ + return Vec4 (x / a, y / a, z / a, w / a); +} + +template +T +Vec4::lengthTiny () const +{ + T absX = (x >= T (0))? x: -x; + T absY = (y >= T (0))? y: -y; + T absZ = (z >= T (0))? z: -z; + T absW = (w >= T (0))? w: -w; + + T max = absX; + + if (max < absY) + max = absY; + + if (max < absZ) + max = absZ; + + if (max < absW) + max = absW; + + if (max == T (0)) + return T (0); + + // + // Do not replace the divisions by max with multiplications by 1/max. + // Computing 1/max can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + absX /= max; + absY /= max; + absZ /= max; + absW /= max; + + return max * + Math::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW); +} + +template +inline T +Vec4::length () const +{ + T length2 = dot (*this); + + if (length2 < T (2) * limits::smallest()) + return lengthTiny(); + + return Math::sqrt (length2); +} + +template +inline T +Vec4::length2 () const +{ + return dot (*this); +} + +template +const Vec4 & +Vec4::normalize () +{ + T l = length(); + + if (l != T (0)) + { + // + // Do not replace the divisions by l with multiplications by 1/l. + // Computing 1/l can overflow but the divisions below will always + // produce results less than or equal to 1. + // + + x /= l; + y /= l; + z /= l; + w /= l; + } + + return *this; +} + +template +const Vec4 & +Vec4::normalizeExc () throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + x /= l; + y /= l; + z /= l; + w /= l; + return *this; +} + +template +inline +const Vec4 & +Vec4::normalizeNonNull () +{ + T l = length(); + x /= l; + y /= l; + z /= l; + w /= l; + return *this; +} + +template +Vec4 +Vec4::normalized () const +{ + T l = length(); + + if (l == T (0)) + return Vec4 (T (0)); + + return Vec4 (x / l, y / l, z / l, w / l); +} + +template +Vec4 +Vec4::normalizedExc () const throw (Iex::MathExc) +{ + T l = length(); + + if (l == T (0)) + throw NullVecExc ("Cannot normalize null vector."); + + return Vec4 (x / l, y / l, z / l, w / l); +} + +template +inline +Vec4 +Vec4::normalizedNonNull () const +{ + T l = length(); + return Vec4 (x / l, y / l, z / l, w / l); +} + +//----------------------------- +// Stream output implementation +//----------------------------- + +template +std::ostream & +operator << (std::ostream &s, const Vec2 &v) +{ + return s << '(' << v.x << ' ' << v.y << ')'; +} + +template +std::ostream & +operator << (std::ostream &s, const Vec3 &v) +{ + return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')'; +} + +template +std::ostream & +operator << (std::ostream &s, const Vec4 &v) +{ + return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')'; +} + + +//----------------------------------------- +// Implementation of reverse multiplication +//----------------------------------------- + +template +inline Vec2 +operator * (T a, const Vec2 &v) +{ + return Vec2 (a * v.x, a * v.y); +} + +template +inline Vec3 +operator * (T a, const Vec3 &v) +{ + return Vec3 (a * v.x, a * v.y, a * v.z); +} + +template +inline Vec4 +operator * (T a, const Vec4 &v) +{ + return Vec4 (a * v.x, a * v.y, a * v.z, a * v.w); +} + + +#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER +#pragma warning(pop) +#endif + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVecAlgo.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVecAlgo.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVecAlgo.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/Imath/ImathVecAlgo.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,146 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHVECALGO_H +#define INCLUDED_IMATHVECALGO_H + +//------------------------------------------------------------------------- +// +// This file contains algorithms applied to or in conjunction +// with points (Imath::Vec2 and Imath::Vec3). +// The assumption made is that these functions are called much +// less often than the basic point functions or these functions +// require more support classes. +// +//------------------------------------------------------------------------- + +#include "ImathVec.h" +#include "ImathLimits.h" + +namespace Imath { + + +//----------------------------------------------------------------- +// Find the projection of vector t onto vector s (Vec2, Vec3, Vec4) +//----------------------------------------------------------------- + +template Vec project (const Vec &s, const Vec &t); + + +//------------------------------------------------ +// Find a vector that is perpendicular to s and +// in the same plane as s and t (Vec2, Vec3, Vec4) +//------------------------------------------------ + +template Vec orthogonal (const Vec &s, const Vec &t); + + +//----------------------------------------------- +// Find the direction of a ray s after reflection +// off a plane with normal t (Vec2, Vec3, Vec4) +//----------------------------------------------- + +template Vec reflect (const Vec &s, const Vec &t); + + +//-------------------------------------------------------------------- +// Find the vertex of triangle (v0, v1, v2) that is closest to point p +// (Vec2, Vec3, Vec4) +//-------------------------------------------------------------------- + +template Vec closestVertex (const Vec &v0, + const Vec &v1, + const Vec &v2, + const Vec &p); + +//--------------- +// Implementation +//--------------- + +template +Vec +project (const Vec &s, const Vec &t) +{ + Vec sNormalized = s.normalized(); + return sNormalized * (sNormalized ^ t); +} + +template +Vec +orthogonal (const Vec &s, const Vec &t) +{ + return t - project (s, t); +} + +template +Vec +reflect (const Vec &s, const Vec &t) +{ + return s - typename Vec::BaseType(2) * (s - project(t, s)); +} + +template +Vec +closestVertex(const Vec &v0, + const Vec &v1, + const Vec &v2, + const Vec &p) +{ + Vec nearest = v0; + typename Vec::BaseType neardot = (v0 - p).length2(); + typename Vec::BaseType tmp = (v1 - p).length2(); + + if (tmp < neardot) + { + neardot = tmp; + nearest = v1; + } + + tmp = (v2 - p).length2(); + + if (tmp < neardot) + { + neardot = tmp; + nearest = v2; + } + + return nearest; +} + + +} // namespace Imath + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/LICENSE diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/LICENSE --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/LICENSE 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,34 @@ +Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm +Entertainment Company Ltd. Portions contributed and copyright held by +others as indicated. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with + the distribution. + + * Neither the name of Industrial Light & Magic nor the names of + any other contributors to this software may be used to endorse or + promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h 2013-05-04 20:02:42.000000000 +0000 @@ -0,0 +1,36 @@ +// +// Define and set to 1 if the target system supports a proc filesystem +// compatible with the Linux kernel's proc filesystem. Note that this +// is only used by a program in the IlmImfTest test suite, it's not +// used by any OpenEXR library or application code. +// + +#undef HAVE_LINUX_PROCFS + +// +// Define and set to 1 if the target system is a Darwin-based system +// (e.g., OS X). +// + +#undef HAVE_DARWIN + +// +// Define and set to 1 if the target system has a complete +// implementation, specifically if it supports the std::right +// formatter. +// + +#undef HAVE_COMPLETE_IOMANIP + +// +// Define and set to 1 if the target system has support for large +// stack sizes. +// + +#undef HAVE_LARGE_STACK + +// +// Version string for runtime access +// +#define OPENEXR_VERSION_STRING "1.7.1" +#define OPENEXR_PACKAGE_STRING "OpenEXR 1.7.1" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h.cmakein diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h.cmakein --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h.cmakein 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/OpenEXRConfig.h.cmakein 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,36 @@ +// +// Define and set to 1 if the target system supports a proc filesystem +// compatible with the Linux kernel's proc filesystem. Note that this +// is only used by a program in the IlmImfTest test suite, it's not +// used by any OpenEXR library or application code. +// + +#undef HAVE_LINUX_PROCFS + +// +// Define and set to 1 if the target system is a Darwin-based system +// (e.g., OS X). +// + +#undef HAVE_DARWIN + +// +// Define and set to 1 if the target system has a complete +// implementation, specifically if it supports the std::right +// formatter. +// + +#undef HAVE_COMPLETE_IOMANIP + +// +// Define and set to 1 if the target system has support for large +// stack sizes. +// + +#undef HAVE_LARGE_STACK + +// +// Version string for runtime access +// +#define OPENEXR_VERSION_STRING "1.7.1" +#define OPENEXR_PACKAGE_STRING "OpenEXR 1.7.1" diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/openexr.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/openexr.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/openexr/openexr.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/openexr/openexr.pro 2013-05-16 14:09:20.000000000 +0000 @@ -0,0 +1,17 @@ + + +TEMPLATE = lib +TARGET = openexr + +CONFIG += staticlib + +HEADERS += Half/*.h Iex/Iex*.h IlmThread/IlmThread*.h Imath/Imath*.h IlmImf/*.h + +SOURCES += Half/half.cpp Iex/*.cpp IlmThread/*.cpp Imath/*.cpp IlmImf/*.cpp + + +INCLUDEPATH += ./ ./Half ./Iex ./IlmThread ./Imath ./IlmImf ../zlib + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/readme.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/readme.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/readme.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,76 @@ +This folder contains libraries and headers of a few very popular still image codecs +used by highgui module. +The libraries and headers are preferably to build Win32 and Win64 versions of OpenCV. +On UNIX systems all the libraries are automatically detected by configure script. +In order to use these versions of libraries instead of system ones on UNIX systems you +should use BUILD_ CMake flags (for example, BUILD_PNG for the libpng library). + +------------------------------------------------------------------------------------ +libjpeg 8d (8.4) - The Independent JPEG Group's JPEG software. + Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding. + See IGJ home page http://www.ijg.org + for details and links to the source code + + HAVE_JPEG preprocessor flag must be set to make highgui use libjpeg. + On UNIX systems configure script takes care of it. +------------------------------------------------------------------------------------ +libpng 1.5.12 - Portable Network Graphics library. + Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson. + See libpng home page http://www.libpng.org + for details and links to the source code + + HAVE_PNG preprocessor flag must be set to make highgui use libpng. + On UNIX systems configure script takes care of it. +------------------------------------------------------------------------------------ +libtiff 4.0.2 - Tag Image File Format (TIFF) Software + Copyright (c) 1988-1997 Sam Leffler + Copyright (c) 1991-1997 Silicon Graphics, Inc. + See libtiff home page http://www.remotesensing.org/libtiff/ + for details and links to the source code + + HAVE_TIFF preprocessor flag must be set to make highgui use libtiff. + On UNIX systems configure script takes care of it. + In this build support for ZIP (LZ77 compression) is turned on. +------------------------------------------------------------------------------------ +zlib 1.2.7 - General purpose LZ77 compression library + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. + See zlib home page http://www.zlib.net + for details and links to the source code + + No preprocessor definition is needed to make highgui use this library - + it is included automatically if either libpng or libtiff are used. +------------------------------------------------------------------------------------ +jasper-1.900.1 - JasPer is a collection of software + (i.e., a library and application programs) for the coding + and manipulation of images. This software can handle image data in a + variety of formats. One such format supported by JasPer is the JPEG-2000 + format defined in ISO/IEC 15444-1. + + Copyright (c) 1999-2000 Image Power, Inc. + Copyright (c) 1999-2000 The University of British Columbia + Copyright (c) 2001-2003 Michael David Adams + + The JasPer license can be found in src/libjasper. + + OpenCV on Windows uses pre-built libjasper library + (lib/libjasper*). To get the latest source code, + please, visit the project homepage: + http://www.ece.uvic.ca/~mdadams/jasper/ +------------------------------------------------------------------------------------ +openexr-1.7.1 - OpenEXR is a high dynamic-range (HDR) image file format developed + by Industrial Light & Magic for use in computer imaging applications. + + Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm + Entertainment Company Ltd. Portions contributed and copyright held by + others as indicated. All rights reserved. + + The project homepage: http://www.openexr.com +------------------------------------------------------------------------------------ +ffmpeg-0.8.0 - FFmpeg is a complete, cross-platform solution to record, + convert and stream audio and video. It includes libavcodec - + the leading audio/video codec library, and also libavformat, libavutils and + other helper libraries that are used by OpenCV (in highgui module) to + read and write video files. + + The project homepage: http://ffmpeg.org/ +------------------------------------------------------------------------------------ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,196 @@ +#Cross compile TBB from source +project(tbb) + +# 4.1 update 2 - works fine +set(tbb_ver "tbb41_20130116oss") +set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130116oss_src.tgz") +set(tbb_md5 "3809790e1001a1b32d59c9fee590ee85") +set(tbb_version_file "version_string.ver") +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow) + +# 4.1 update 1 - works fine +#set(tbb_ver "tbb41_20121003oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20121003oss_src.tgz") +#set(tbb_md5 "2a684fefb855d2d0318d1ef09afa75ff") +#set(tbb_version_file "version_string.ver") + +# 4.1 - works fine +#set(tbb_ver "tbb41_20120718oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20120718oss_src.tgz") +#set(tbb_md5 "31b9ec300f3d09da2504d5d882788dd4") +#set(tbb_version_file "version_string.ver") + +# 4.0 update 5 - works fine +#set(tbb_ver "tbb40_20120613oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120613oss_src.tgz") +#set(tbb_md5 "da01ed74944ec5950cfae3476901a172") +#set(tbb_version_file "version_string.ver") + +# 4.0 update 4 - works fine +#set(tbb_ver "tbb40_20120408oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120408oss_src.tgz") +#set(tbb_md5 "734b356da7fe0ed308741f3e6018251e") +#set(tbb_version_file "version_string.ver") + +# 4.0 update 3 - build broken +#set(tbb_ver "tbb40_20120201oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120201oss_src.tgz") +#set(tbb_md5 "4669e7d4adee018de7a7b8b972987218") +#set(tbb_version_file "version_string.tmp") + +# 4.0 update 2 - works fine +#set(tbb_ver "tbb40_20111130oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111130oss_src.tgz") +#set(tbb_md5 "1e6926b21e865e79772119cd44fc3ad8") +#set(tbb_version_file "version_string.tmp") +#set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE) + +# 4.0 update 1 - works fine +#set(tbb_ver "tbb40_20111003oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111003oss_src.tgz") +#set(tbb_md5 "7b5d94eb35a563b29ef402e0fd8f15c9") +#set(tbb_version_file "version_string.tmp") +#set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE) + +set(tbb_tarball "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_ver}_src.tgz") +set(tbb_src_dir "${CMAKE_CURRENT_BINARY_DIR}/${tbb_ver}") + +macro(getMD5 filename varname) + if(CMAKE_VERSION VERSION_GREATER 2.8.6) + file(MD5 "${filename}" ${varname}) + else() + execute_process(COMMAND ${CMAKE_COMMAND} -E md5sum "${filename}" + RESULT_VARIABLE getMD5_RESULT + OUTPUT_VARIABLE getMD5_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(getMD5_RESULT EQUAL 0) + string(REGEX MATCH "^[a-z0-9]+" ${varname} "${getMD5_OUTPUT}") + else() + set(${varname} "invalid_md5") + endif() + endif() +endmacro() + +if(EXISTS "${tbb_tarball}") + getMD5("${tbb_tarball}" tbb_local_md5) + if(NOT tbb_local_md5 STREQUAL tbb_md5) + message(WARNING "Local copy of TBB source tarball has invalid MD5 hash: ${tbb_local_md5} (expected: ${tbb_md5})") + file(REMOVE "${tbb_tarball}") + if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${tbb_ver}") + file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/${tbb_ver}") + endif() + endif() +endif() + +if(NOT EXISTS "${tbb_tarball}") + message(STATUS "Downloading ${tbb_ver}_src.tgz") + file(DOWNLOAD "${tbb_url}" "${tbb_tarball}" TIMEOUT 600 STATUS __statvar) + if(NOT __statvar EQUAL 0) + message(FATAL_ERROR "Failed to download TBB sources: ${tbb_url}") + endif() + getMD5("${tbb_tarball}" tbb_local_md5) + if(NOT tbb_local_md5 STREQUAL tbb_md5) + file(REMOVE "${tbb_tarball}") + message(FATAL_ERROR "Downloaded TBB source tarball has invalid MD5 hash: ${tbb_local_md5} (expected: ${tbb_md5})") + endif() + + if(EXISTS "${tbb_src_dir}") + file(REMOVE_RECURSE "${tbb_src_dir}") + endif() +endif() + +# untar TBB sources +if(NOT EXISTS "${tbb_src_dir}") + message(STATUS "Unpacking ${tbb_ver}_src.tgz to ${tbb_src_dir}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xz "${tbb_tarball}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE tbb_untar_RESULT) + + if(NOT tbb_untar_RESULT EQUAL 0 OR NOT EXISTS "${tbb_src_dir}") + message(FATAL_ERROR "Failed to unpack TBB sources") + endif() +endif() + +set(TBB_INCLUDE_DIRS "${tbb_src_dir}/include" PARENT_SCOPE) + +ocv_include_directories("${tbb_src_dir}/include" + "${tbb_src_dir}/src/" + "${tbb_src_dir}/src/rml/include" + "${CMAKE_CURRENT_SOURCE_DIR}") + +file(GLOB lib_srcs "${tbb_src_dir}/src/tbb/*.cpp") +file(GLOB lib_hdrs "${tbb_src_dir}/src/tbb/*.h") +list(APPEND lib_srcs "${tbb_src_dir}/src/rml/client/rml_tbb.cpp") + +if (WIN32) + add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0 + -D__TBB_BUILD=1 + -D_UNICODE + -DUNICODE + -DWINAPI_FAMILY=WINAPI_FAMILY_APP + -DDO_ITT_NOTIFY=0 + ) # defines were copied from windows.cl.inc +set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} /APPCONTAINER") +else() + add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0 #required + -D__TBB_BUILD=1 #required + -D__TBB_SURVIVE_THREAD_SWITCH=0 #no cilk support + -DTBB_USE_DEBUG=0 #just to be sure + -DTBB_NO_LEGACY=1 #don't need backward compatibility + -DDO_ITT_NOTIFY=0 #it seems that we don't need these notifications + ) +endif() + +if (HAVE_LIBPTHREAD) + add_definitions(-DUSE_PTHREAD) #required for Unix +endif() + +if (CMAKE_COMPILER_IS_GNUCXX) + add_definitions(-DTBB_USE_GCC_BUILTINS=1) #required for ARM GCC +endif() + +if(ANDROID_COMPILER_IS_CLANG) + add_definitions(-D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1) + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-prototypes) +endif() + +if(tbb_need_GENERIC_DWORD_LOAD_STORE) + #needed by TBB 4.0 update 1,2; fixed in TBB 4.0 update 3 but it has 2 new problems + add_definitions(-D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1) + set(tbb_need_GENERIC_DWORD_LOAD_STORE ON PARENT_SCOPE) +endif() + +set(TBB_SOURCE_FILES ${lib_srcs} ${lib_hdrs}) + +if (ARM AND NOT WIN32) + if (NOT ANDROID) + set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/arm_linux_stub.cpp") + endif() + set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"") +endif() + +set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}") + +add_library(tbb ${TBB_SOURCE_FILES}) +target_link_libraries(tbb c m dl) + +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations) +string(REPLACE "-Werror=non-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + +set_target_properties(tbb + PROPERTIES OUTPUT_NAME tbb + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(tbb PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS tbb ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() + +# get TBB version +ocv_parse_header("${tbb_src_dir}/include/tbb/tbb_stddef.h" TBB_VERSION_LINES TBB_VERSION_MAJOR TBB_VERSION_MINOR TBB_INTERFACE_VERSION CACHE) diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/android_additional.h diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/android_additional.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/android_additional.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/android_additional.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,41 @@ +#include + +static inline int getPossibleCPUs() +{ + FILE* cpuPossible = fopen("/sys/devices/system/cpu/possible", "r"); + if(!cpuPossible) + return 1; + + char buf[2000]; //big enough for 1000 CPUs in worst possible configuration + char* pbuf = fgets(buf, sizeof(buf), cpuPossible); + fclose(cpuPossible); + if(!pbuf) + return 1; + + //parse string of form "0-1,3,5-7,10,13-15" + int cpusAvailable = 0; + + while(*pbuf) + { + const char* pos = pbuf; + bool range = false; + while(*pbuf && *pbuf != ',') + { + if(*pbuf == '-') range = true; + ++pbuf; + } + if(*pbuf) *pbuf++ = 0; + if(!range) + ++cpusAvailable; + else + { + int rstart = 0, rend = 0; + sscanf(pos, "%d-%d", &rstart, &rend); + cpusAvailable += rend - rstart + 1; + } + + } + return cpusAvailable ? cpusAvailable : 1; +} + +#define __TBB_HardwareConcurrency() getPossibleCPUs() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/arm_linux_stub.cpp diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/arm_linux_stub.cpp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/arm_linux_stub.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/arm_linux_stub.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,10 @@ +#include "tbb/tbb_misc.h" + +namespace tbb { +namespace internal { + +void affinity_helper::protect_affinity_mask() {} +affinity_helper::~affinity_helper() {} + +} +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/version_string.tmp diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/version_string.tmp --- diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/version_string.tmp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/version_string.tmp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,9 @@ +#define __TBB_VERSION_STRINGS \ +"TBB: BUILD_HOST Unknown" ENDL \ +"TBB: BUILD_OS Android" ENDL \ +"TBB: BUILD_KERNEL Unknown" ENDL \ +"TBB: BUILD_GCC gcc version 4.4.3" ENDL \ +"TBB: BUILD_GLIBC Unknown" ENDL \ +"TBB: BUILD_LD Unknown" ENDL \ +"TBB: BUILD_TARGET Unknown" ENDL \ +"TBB: BUILD_COMMAND use cv::getBuildInformation() for details" ENDL diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/version_string.ver diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/version_string.ver --- diffimg-1.5.0/3rdparty/opencv/3rdparty/tbb/version_string.ver 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/tbb/version_string.ver 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,9 @@ +#define __TBB_VERSION_STRINGS(N) \ +#N": BUILD_HOST Unknown" ENDL \ +#N": BUILD_OS Android" ENDL \ +#N": BUILD_KERNEL Unknown" ENDL \ +#N": BUILD_GCC gcc version 4.4.3" ENDL \ +#N": BUILD_GLIBC Unknown" ENDL \ +#N": BUILD_LD Unknown" ENDL \ +#N": BUILD_TARGET Unknown" ENDL \ +#N": BUILD_COMMAND use cv::getBuildInformation() for details" ENDL diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,99 @@ +# ---------------------------------------------------------------------------- +# CMake file for zlib. See root CMakeLists.txt +# +# ---------------------------------------------------------------------------- + +project(${ZLIB_LIBRARY} C) + +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +include(CheckTypeSize) + +# +# Check for fseeko +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +# +# Check for unistd.h +# +check_include_file(unistd.h Z_HAVE_UNISTD_H) + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +endif() + +# +# Check to see if we have large file support +# +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1) +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein" + "${CMAKE_CURRENT_BINARY_DIR}/zconf.h" @ONLY) +ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") + +set(ZLIB_PUBLIC_HDRS + "${CMAKE_CURRENT_BINARY_DIR}/zconf.h" + zlib.h +) +set(ZLIB_PRIVATE_HDRS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c +) + +add_library(${ZLIB_LIBRARY} STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +set_target_properties(${ZLIB_LIBRARY} PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() +endif() + +ocv_warnings_disable(CMAKE_C_FLAGS -Wattributes -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations) + +set_target_properties(${ZLIB_LIBRARY} PROPERTIES + OUTPUT_NAME ${ZLIB_LIBRARY} + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} + ) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${ZLIB_LIBRARY} PROPERTIES FOLDER "3rdparty") +endif() + +if(NOT BUILD_SHARED_LIBS) + install(TARGETS ${ZLIB_LIBRARY} ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT main) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/ChangeLog diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/ChangeLog --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/ChangeLog 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1409 @@ + + ChangeLog file for zlib + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no libary use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/README diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/README --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/README 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/README 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.7 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.7 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/adler32.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/adler32.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/adler32.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/adler32.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* 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 -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + 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; + MOD28(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); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + 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); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/compress.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/compress.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/compress.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/compress.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + 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 (dest, destLen, source, sourceLen, level) + 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 (dest, destLen, source, sourceLen) + 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 (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/crc32.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/crc32.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/crc32.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/crc32.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,425 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + 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(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + 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)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t 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() +{ + z_crc_t c; + int n, k; + z_crc_t 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 = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)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] = ZSWAP32(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] = ZSWAP32(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 z_crc_t 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 z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(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(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t 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(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt 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)) { + z_crc_t 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(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t 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(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t 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)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + 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(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_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 (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* 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; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/crc32.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/crc32.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/crc32.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/crc32.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t 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 + } +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/deflate.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/deflate.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/deflate.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/deflate.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1965 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * 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://tools.ietf.org/html/rfc1951 + * + * 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$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and 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. + */ + +/* =========================================================================== + * 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 block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +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)); +#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 + +#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 */ + +/* 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 + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * 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)<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_(strm, level, version, stream_size) + 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_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + 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) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#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->high_water = 0; /* nothing written to s->window yet */ + + 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 (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + 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); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + 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 deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + 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 ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + 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(strm, good_length, max_lazy, nice_length, max_chain) + 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. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * 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 (s, b) + 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(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + 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_BLOCK || 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 == Z_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 != Z_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 != Z_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 != Z_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 != Z_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 && RANK(flush) <= RANK(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 = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(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 if (flush != Z_BLOCK) { /* 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 */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + 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 (strm) + 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 (dest, source) + 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((voidpf)dest, (voidpf)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((voidpf)ds, (voidpf)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((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)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(strm, buf, size) + 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; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + 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 (s) + 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->insert = 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(s, cur_match) + deflate_state *s; + IPos cur_match; /* current 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 */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current 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; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, 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(s) + 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; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + 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.) + */ + 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) break; + + /* 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 + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* 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); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * 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, last) { \ + _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), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? 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(s, flush) + 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); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return 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(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* 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: + */ + hash_head = NIL; + 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). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() 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); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return 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(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* 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: + */ + hash_head = NIL; + 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). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() 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; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * 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 prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length 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 run, plus one for the unrolled loop. + */ + 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 */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } 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); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + 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); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/deflate.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/deflate.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/deflate.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/deflate.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.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$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.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 + +/* =========================================================================== + * 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 Buf_size 16 +/* size of bit buffer in bi_buf */ + +#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 suppress 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 */ + uInt insert; /* bytes at end of window left to insert */ + +#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. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} 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. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#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 ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzclose.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzclose.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzclose.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzclose.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzguts.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzguts.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzguts.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzguts.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,193 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#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 + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# 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) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzlib.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzlib.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzlib.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzlib.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,620 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + case 'T': + state->direct = 1; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen(path); + state->path = malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif + strcpy(state->path, path); + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open(path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzread.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzread.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzread.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzread.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,589 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in, *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#undef gzgetc +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzwrite.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzwrite.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/gzwrite.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/gzwrite.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,565 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->x.pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->x.pos++; + return c & 0xff; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + va_end(va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (state->size) { + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/infback.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/infback.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/infback.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/infback.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + 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. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables 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_(strm, windowBits, window, version, stream_size) +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) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + 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->wnext = 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 fixedtables(state) +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 */ +# include "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(strm, in, in_desc, out, out_desc) +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 here; /* 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 */ + 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: + /* 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 (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.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 (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.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; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + 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 (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.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 (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.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(strm) +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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffast.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffast.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffast.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffast.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "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 ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + 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 wnext; /* 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 here; /* 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; + wnext = state->wnext; + 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; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.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; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.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) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 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 (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - 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 */ + here = dcode[here.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 */ + here = lcode[here.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 wnext == 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffast.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffast.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffast.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffast.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.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 ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffixed.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffixed.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inffixed.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inffixed.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,94 @@ + /* 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 this 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} + }; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inflate.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inflate.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inflate.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inflate.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1496 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * 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 wnext == 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. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "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 inflateResetKeep(strm) +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; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +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; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + 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) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + 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->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +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 < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + 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; +} + +/* + 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(state) +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 */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + 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}", (low & 127) == 99 ? 64 : 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(strm, out) +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->wnext = 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->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 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) + +/* + 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(strm, flush) +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 here; /* 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 (state->wbits == 0) + state->wbits = len; + else 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 = ZSWAP32(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 || flush == Z_TREES) 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 */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + 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_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + 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 (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.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 (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.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; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + 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_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + 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->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - 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 + ZSWAP32(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 || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + 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) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +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(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + unsigned char *next; + unsigned avail; + int ret; + + /* 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 identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + next = strm->next_out; + avail = strm->avail_out; + strm->next_out = (Bytef *)dictionary + dictLength; + strm->avail_out = 0; + ret = updatewindow(strm, dictLength); + strm->avail_out = avail; + strm->next_out = next; + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +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(have, buf, len) +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(strm) +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(strm) +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(dest, source) +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((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)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; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inflate.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inflate.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inflate.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inflate.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.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. + */ + +/* 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: same as COPY below, but only first time in */ + 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: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob 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 BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K 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 wnext; /* 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 */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inftrees.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inftrees.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inftrees.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inftrees.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.7 Copyright 1995-2012 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 ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +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 here; /* 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, 78, 68}; + 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 */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; 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 for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + 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_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.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] = here; + } 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_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + 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 remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inftrees.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inftrees.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/inftrees.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/inftrees.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.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. + */ + +/* 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 the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/trees.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/trees.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/trees.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/trees.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1224 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * 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$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#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. + */ + +/* =========================================================================== + * 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 +# include "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 int detect_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(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + 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 |= (ush)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 |= (ush)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 |= (ush)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 |= (ush)(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: */ +#ifdef NO_INIT_GLOBAL_POINTERS + 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; +#endif + + /* 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< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 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 +# 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 ZLIB_INTERNAL _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 ZLIB_INTERNAL _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 ZLIB_INTERNAL _tr_init(s) + 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; +#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(s) + 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(s, tree, k) + 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(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + 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 (tree, max_code, bl_count) + 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<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 (s, tree, max_code) + 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 (s, tree, max_code) + 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(s) + 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(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, 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 ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 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 */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + 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); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one 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 (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_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, last); + +#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)+last, 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)+last, 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 (last) { + 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*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + 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(s, ltree, dtree) + 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); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return 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(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + 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(s) + 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(s) + 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(s, buf, len, header) + 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 */ + + 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++); + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/trees.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/trees.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/trees.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/trees.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_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 ZLIB_INTERNAL _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 ZLIB_INTERNAL _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 +}; + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/uncompr.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/uncompr.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/uncompr.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/uncompr.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + 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. + + 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 (dest, destLen, source, sourceLen) + 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; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zconf.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zconf.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zconf.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zconf.h 2013-05-04 20:02:30.000000000 +0000 @@ -0,0 +1,510 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_H */ + +/* + * 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. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#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 + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#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 + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(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 + /* 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 + +/* ./configure may #define Z_U4 here */ + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# else +# if (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# else +# if (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +# endif +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#ifdef _WIN32 +# include /* for wchar_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#else +# define _LFS64_LARGEFILE 0 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# 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(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zconf.h.cmakein diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zconf.h.cmakein --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zconf.h.cmakein 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zconf.h.cmakein 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,510 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +#cmakedefine Z_PREFIX +#cmakedefine Z_HAVE_UNISTD_H + +/* + * 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. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#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 + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#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 + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(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 + /* 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 + +/* ./configure may #define Z_U4 here */ + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# else +# if (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# else +# if (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +# endif +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#ifdef _WIN32 +# include /* for wchar_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#else +# define _LFS64_LARGEFILE 0 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# 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(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# 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 */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zlib.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zlib.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zlib.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zlib.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1744 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.7, May 2nd, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.7" +#define ZLIB_VERNUM 0x1270 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 7 +#define ZLIB_VER_SUBREVISION 0 + +/* + 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, + 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 { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number 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 number of bytes output so far */ + + z_const 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 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* 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, or + 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 accumulate 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. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + 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). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and 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 Z_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, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +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, + Z_BLOCK, or Z_TREES. 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. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + 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 of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + 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 effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 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() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). 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. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip 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 + next_in or next_out was Z_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_STRATEGY 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 any parameter is invalid (such as an invalid + method), or 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. 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. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. 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 + provided in deflateInit or deflateInit2. 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 (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). 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 Z_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 Z_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(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +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, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, 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 zero to request that inflate use the window size in + the zlib header of the compressed stream. + + 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_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +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 at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. 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 (e.g. dictionary being Z_NULL) 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 possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible 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 Z_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 Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +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. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + 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 or Z_TREES 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 parameters 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_in 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) + */ + +#ifndef Z_SOLO + + /* 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 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. + + 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 uncompressed buffer. + + 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. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library 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. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +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", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + 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. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +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 (if 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 fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +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 is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -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 written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will 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. This can be determined using + zlibCompileFlags(). +*/ + +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. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +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. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + 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 is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +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, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +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. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +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. +*/ + +#endif /* !Z_SOLO */ + + /* 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 Z_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. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +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 Z_NULL, this function returns the required + initial value 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, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zlib.pro diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zlib.pro --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zlib.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zlib.pro 2013-05-05 17:06:00.000000000 +0000 @@ -0,0 +1,17 @@ + + +TEMPLATE = lib +TARGET = zlib + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.c + + +INCLUDEPATH += ./ + +win32:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS + + diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zutil.c diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zutil.c --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zutil.c 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zutil.c 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,324 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +#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 ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(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 +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# 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 ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + 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(err) + 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 ZLIB_INTERNAL 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 ZLIB_INTERNAL 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 ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#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 ZLIB_INTERNAL 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 ZLIB_INTERNAL 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 ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL 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 ZLIB_INTERNAL zcalloc (opaque, items, size) + 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 ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff -Nru diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zutil.h diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zutil.h --- diffimg-1.5.0/3rdparty/opencv/3rdparty/zlib/zutil.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/3rdparty/zlib/zutil.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,252 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.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$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#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 +# ifndef Z_SOLO +# 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 +# endif +# else /* MSC or DJGPP */ +# include +# endif +# 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 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# 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)) && !defined __INTERIX +# 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 + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#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(pyr) || defined(Z_SOLO) +# 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 + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL 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 + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#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);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff -Nru diffimg-1.5.0/3rdparty/opencv/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/CMakeLists.txt 2013-05-05 20:24:06.000000000 +0000 @@ -0,0 +1,876 @@ +# ---------------------------------------------------------------------------- +# Root CMake file for OpenCV +# +# From the off-tree build directory, invoke: +# $ cmake +# +# +# - OCT-2008: Initial version +# +# ---------------------------------------------------------------------------- + +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +# -------------------------------------------------------------- +# Indicate CMake 2.7 and above that we don't want to mix relative +# and absolute paths in linker lib lists. +# Run "cmake --help-policy CMP0003" for more information. +# -------------------------------------------------------------- +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif() + +# Following block can broke build in case of cross-compilng +# but CMAKE_CROSSCOMPILING variable will be set only on project(OpenCV) command +# so we will try to detect crosscompiling by presense of CMAKE_TOOLCHAIN_FILE +if(NOT CMAKE_TOOLCHAIN_FILE) + # it _must_ go before project(OpenCV) in order to work + if(WIN32) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") + else() + set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory") + endif() + + if(MSVC) + set(CMAKE_USE_RELATIVE_PATHS ON CACHE INTERNAL "" FORCE) + endif() +else(NOT CMAKE_TOOLCHAIN_FILE) + #Android: set output folder to ${CMAKE_BINARY_DIR} + set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to" ) + # any crosscompiling + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") +endif(NOT CMAKE_TOOLCHAIN_FILE) + +# -------------------------------------------------------------- +# Top level OpenCV project +# -------------------------------------------------------------- +if(CMAKE_GENERATOR MATCHES Xcode AND XCODE_VERSION VERSION_GREATER 4.3) + cmake_minimum_required(VERSION 2.8.8) +elseif(IOS) + cmake_minimum_required(VERSION 2.8.0) +else() + cmake_minimum_required(VERSION 2.6.3) +endif() + +# must go before the project command +set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) +if(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8") + set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) +endif() + +project(OpenCV CXX C) + +include(cmake/OpenCVUtils.cmake) + +# ---------------------------------------------------------------------------- +# Break in case of popular CMake configuration mistakes +# ---------------------------------------------------------------------------- +if(NOT CMAKE_SIZEOF_VOID_P GREATER 0) + message(FATAL_ERROR "CMake fails to deterimine the bitness of target platform. + Please check your CMake and compiler installation. If you are crosscompiling then ensure that your CMake toolchain file correctly sets the compiler details.") +endif() + +# ---------------------------------------------------------------------------- +# Detect compiler and target platform architecture +# ---------------------------------------------------------------------------- +include(cmake/OpenCVDetectCXXCompiler.cmake) + +# Add these standard paths to the search paths for FIND_LIBRARY +# to find libraries from these locations first +if(UNIX AND NOT ANDROID) + if(X86_64 OR CMAKE_SIZEOF_VOID_P EQUAL 8) + if(EXISTS /lib64) + list(APPEND CMAKE_LIBRARY_PATH /lib64) + else() + list(APPEND CMAKE_LIBRARY_PATH /lib) + endif() + if(EXISTS /usr/lib64) + list(APPEND CMAKE_LIBRARY_PATH /usr/lib64) + else() + list(APPEND CMAKE_LIBRARY_PATH /usr/lib) + endif() + elseif(X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4) + if(EXISTS /lib32) + list(APPEND CMAKE_LIBRARY_PATH /lib32) + else() + list(APPEND CMAKE_LIBRARY_PATH /lib) + endif() + if(EXISTS /usr/lib32) + list(APPEND CMAKE_LIBRARY_PATH /usr/lib32) + else() + list(APPEND CMAKE_LIBRARY_PATH /usr/lib) + endif() + endif() +endif() + + +# ---------------------------------------------------------------------------- +# OpenCV cmake options +# ---------------------------------------------------------------------------- + +# Optional 3rd party components +# =================================================== +OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS) +OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE ) +OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) ) +OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" ON) +OCV_OPTION(WITH_VFW "Include Video for Windows support" ON IF WIN32 ) +OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON IF (NOT ANDROID AND NOT IOS)) +OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) ) +OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) ) +OCV_OPTION(WITH_IMAGEIO "ImageIO support for OS X" OFF IF APPLE ) +OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF IF (MSVC OR X86 OR X86_64) ) +OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) ) +OCV_OPTION(WITH_JPEG "Include JPEG support" ON) +OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ON IF (NOT IOS) ) +OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF IF (NOT ANDROID AND NOT APPLE) ) +OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_PNG "Include PNG support" ON) +OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" ON IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_GIGEAPI "Include Smartek GigE support" ON IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_QT "Build with Qt Backend support" OFF IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_WIN32UI "Build with Win32 UI Backend support" ON IF WIN32 ) +OCV_OPTION(WITH_QUICKTIME "Use QuickTime for Video I/O insted of QTKit" OFF IF APPLE ) +OCV_OPTION(WITH_TBB "Include Intel TBB support" OFF IF (NOT IOS) ) +OCV_OPTION(WITH_CSTRIPES "Include C= support" OFF IF WIN32 ) +OCV_OPTION(WITH_TIFF "Include TIFF support" ON IF (NOT IOS) ) +OCV_OPTION(WITH_UNICAP "Include Unicap support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) ) +OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON IF (UNIX AND NOT ANDROID) ) +OCV_OPTION(WITH_DSHOW "Build HighGUI with DirectShow support" ON IF (WIN32 AND NOT ARM) ) +OCV_OPTION(WITH_MSMF "Build HighGUI with Media Foundation support" OFF IF WIN32 ) +OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF IF (NOT ANDROID AND NOT APPLE) ) +OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) ) +OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) ) + + +# OpenCV build components +# =================================================== +OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR IOS) ) +OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID) IF (NOT IOS) ) +OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID ) +OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" ON ) +OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF ) +OCV_OPTION(BUILD_PACKAGE "Enables 'make package_source' command" ON ) +OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" ON IF (NOT IOS) ) +OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" ON IF (NOT IOS) ) +OCV_OPTION(BUILD_WITH_DEBUG_INFO "Include debug info into debug libs (not MSCV only)" ON ) +OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of staticaly linked CRT for staticaly linked OpenCV" ON IF MSVC ) +OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX ) +OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID AND ANDROID_SOURCE_TREE ) +OCV_OPTION(BUILD_ANDROID_PACKAGE "Build platform-specific package for Google Play" OFF IF ANDROID ) + +# 3rd party libs +OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR APPLE ) +OCV_OPTION(BUILD_TIFF "Build libtiff from source" WIN32 OR ANDROID OR APPLE ) +OCV_OPTION(BUILD_JASPER "Build libjasper from source" WIN32 OR ANDROID OR APPLE ) +OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 OR ANDROID OR APPLE ) +OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR ANDROID OR APPLE ) +OCV_OPTION(BUILD_OPENEXR "Build openexr from source" WIN32 OR ANDROID OR APPLE ) +OCV_OPTION(BUILD_TBB "Download and build TBB from source" ANDROID ) + +# OpenCV installation options +# =================================================== +OCV_OPTION(INSTALL_C_EXAMPLES "Install C examples" OFF ) +OCV_OPTION(INSTALL_PYTHON_EXAMPLES "Install Python examples" OFF ) +OCV_OPTION(INSTALL_ANDROID_EXAMPLES "Install Android examples" OFF IF ANDROID ) +OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help with side by side installs." OFF IF (UNIX AND NOT ANDROID AND NOT IOS AND BUILD_SHARED_LIBS) ) + + +# OpenCV build options +# =================================================== +OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" ON IF (NOT IOS) ) +OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) IF (CMAKE_VERSION VERSION_GREATER "2.8.0") ) +OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CMAKE_COMPILER_IS_GNUCXX ) +OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC" ON IF CMAKE_COMPILER_IS_GNUCXX AND NOT (APPLE AND CMAKE_COMPILER_IS_CLANGCXX) ) +OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) ) +OCV_OPTION(ENABLE_FAST_MATH "Enable -ffast-math (not recommended for GCC 4.6.x)" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSE "Enable SSE instructions" ON IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSE2 "Enable SSE2 instructions" ON IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSE3 "Enable SSE3 instructions" ON IF ((CV_ICC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSSE3 "Enable SSSE3 instructions" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSE41 "Enable SSE4.1 instructions" OFF IF ((CV_ICC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_SSE42 "Enable SSE4.2 instructions" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_AVX "Enable AVX instructions" OFF IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) +OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF ) +OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF ) + + +# uncategorized options +# =================================================== +OCV_OPTION(CMAKE_VERBOSE "Verbose mode" OFF ) + +# backward compatibility +# =================================================== +include(cmake/OpenCVLegacyOptions.cmake OPTIONAL) + + +# ---------------------------------------------------------------------------- +# Get actual OpenCV version number from sources +# ---------------------------------------------------------------------------- +include(cmake/OpenCVVersion.cmake) + + +# ---------------------------------------------------------------------------- +# Build & install layouts +# ---------------------------------------------------------------------------- + +# Save libs and executables in the same place +set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Output directory for applications" ) + +set(OpenCV_BINARY_DIR "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Output directory for libs" ) # XBEE + +if(ANDROID OR WIN32) + set(OPENCV_DOC_INSTALL_PATH doc) +elseif(INSTALL_TO_MANGLED_PATHS) + set(OPENCV_DOC_INSTALL_PATH share/OpenCV-${OPENCV_VERSION}/doc) +else() + set(OPENCV_DOC_INSTALL_PATH share/OpenCV/doc) +endif() + +if(ANDROID) + set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}") + set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}") + set(OPENCV_LIB_INSTALL_PATH sdk/native/libs/${ANDROID_NDK_ABI_NAME}) + set(OPENCV_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME}) + set(OPENCV_CONFIG_INSTALL_PATH sdk/native/jni) + set(OPENCV_INCLUDE_INSTALL_PATH sdk/native/jni/include) +else() + set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib") + set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}") + set(OPENCV_LIB_INSTALL_PATH lib${LIB_SUFFIX}) + set(OPENCV_3P_LIB_INSTALL_PATH share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}) + set(OPENCV_INCLUDE_INSTALL_PATH include) + + math(EXPR SIZEOF_VOID_P_BITS "8 * ${CMAKE_SIZEOF_VOID_P}") + if(LIB_SUFFIX AND NOT SIZEOF_VOID_P_BITS EQUAL LIB_SUFFIX) + set(OPENCV_CONFIG_INSTALL_PATH lib${LIB_SUFFIX}/cmake/opencv) + else() + set(OPENCV_CONFIG_INSTALL_PATH share/OpenCV) + endif() +endif() + +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}") +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +if(INSTALL_TO_MANGLED_PATHS) + set(OPENCV_INCLUDE_INSTALL_PATH ${OPENCV_INCLUDE_INSTALL_PATH}/opencv-${OPENCV_VERSION}) +endif() + +if(WIN32) + # Postfix of DLLs: + set(OPENCV_DLLVERSION "${OPENCV_VERSION_MAJOR}${OPENCV_VERSION_MINOR}${OPENCV_VERSION_PATCH}") + set(OPENCV_DEBUG_POSTFIX d) +else() + # Postfix of so's: + set(OPENCV_DLLVERSION "") + set(OPENCV_DEBUG_POSTFIX "") +endif() + +if(DEFINED CMAKE_DEBUG_POSTFIX) + set(OPENCV_DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}") +endif() + +if(CMAKE_VERBOSE) + set(CMAKE_VERBOSE_MAKEFILE 1) +endif() + + +# ---------------------------------------------------------------------------- +# Path for build/platform -specific headers +# ---------------------------------------------------------------------------- +set(OPENCV_CONFIG_FILE_INCLUDE_DIR "${CMAKE_BINARY_DIR}/" CACHE PATH "Where to create the platform-dependant cvconfig.h") +add_definitions(-DHAVE_CVCONFIG_H) +ocv_include_directories(${OPENCV_CONFIG_FILE_INCLUDE_DIR}) + + +# ---------------------------------------------------------------------------- +# Autodetect if we are in a GIT repository +# ---------------------------------------------------------------------------- + +# don't use FindGit because it requires CMake 2.8.2 +set(git_names git eg) # eg = easy git +# Prefer .cmd variants on Windows unless running in a Makefile in the MSYS shell +if(CMAKE_HOST_WIN32) + if(NOT CMAKE_GENERATOR MATCHES "MSYS") + set(git_names git.cmd git eg.cmd eg) + endif() +endif() + +find_host_program(GIT_EXECUTABLE NAMES ${git_names} PATH_SUFFIXES Git/cmd Git/bin DOC "git command line client") +mark_as_advanced(GIT_EXECUTABLE) + +if(GIT_EXECUTABLE) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty --match "2.[0-9].[0-9]*" + WORKING_DIRECTORY "${OpenCV_SOURCE_DIR}" + OUTPUT_VARIABLE OPENCV_VCSVERSION + RESULT_VARIABLE GIT_RESULT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT GIT_RESULT EQUAL 0) + set(OPENCV_VCSVERSION "unknown") + endif() +else() + # We don't have git: + set(OPENCV_VCSVERSION "unknown") +endif() + + +# ---------------------------------------------------------------------------- +# OpenCV compiler and linker options +# ---------------------------------------------------------------------------- +# In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release: +if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE Release) +endif() + +include(cmake/OpenCVCompilerOptions.cmake) + + +# ---------------------------------------------------------------------------- +# Use statically or dynamically linked CRT? +# Default: dynamic +# ---------------------------------------------------------------------------- +if(MSVC) + include(cmake/OpenCVCRTLinkage.cmake) +endif(MSVC) + +if(WIN32 AND NOT MINGW) + add_definitions(-D_VARIADIC_MAX=10) +endif(WIN32 AND NOT MINGW) + + +# ---------------------------------------------------------------------------- +# CHECK FOR SYSTEM LIBRARIES, OPTIONS, ETC.. +# ---------------------------------------------------------------------------- +if(UNIX) + include(cmake/OpenCVFindPkgConfig.cmake OPTIONAL) + include(CheckFunctionExists) + include(CheckIncludeFile) + + if(NOT APPLE) + CHECK_INCLUDE_FILE(alloca.h HAVE_ALLOCA_H) + CHECK_FUNCTION_EXISTS(alloca HAVE_ALLOCA) + CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) + CHECK_INCLUDE_FILE(pthread.h HAVE_LIBPTHREAD) + if(ANDROID) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|NetBSD|DragonFly") + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread) + else() + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m pthread rt) + endif() + else() + add_definitions(-DHAVE_ALLOCA -DHAVE_ALLOCA_H -DHAVE_LIBPTHREAD -DHAVE_UNISTD_H) + endif() +endif() + +include(cmake/OpenCVPCHSupport.cmake) +include(cmake/OpenCVModule.cmake) + +# ---------------------------------------------------------------------------- +# Detect 3rd-party libraries +# ---------------------------------------------------------------------------- + +include(cmake/OpenCVFindLibsGrfmt.cmake) +include(cmake/OpenCVFindLibsGUI.cmake) +include(cmake/OpenCVFindLibsVideo.cmake) +include(cmake/OpenCVFindLibsPerf.cmake) + + +# ---------------------------------------------------------------------------- +# Detect other 3rd-party libraries/tools +# ---------------------------------------------------------------------------- + +# --- LATEX for pdf documentation --- +if(BUILD_DOCS) + include(cmake/OpenCVFindLATEX.cmake) +endif(BUILD_DOCS) + +# --- Python Support --- +include(cmake/OpenCVDetectPython.cmake) + +# --- Java Support --- +include(cmake/OpenCVDetectApacheAnt.cmake) +if(ANDROID) + include(cmake/OpenCVDetectAndroidSDK.cmake) + + if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13) + message(WARNING "OpenCV requires Android SDK tools revision 14 or newer. Otherwise tests and samples will no be compiled.") + endif() +elseif(ANT_EXECUTABLE) + find_package(JNI) +endif() + +if(ANDROID AND ANDROID_EXECUTABLE AND ANT_EXECUTABLE AND (ANT_VERSION VERSION_GREATER 1.7) AND (ANDROID_TOOLS_Pkg_Revision GREATER 13)) + SET(CAN_BUILD_ANDROID_PROJECTS TRUE) +else() + SET(CAN_BUILD_ANDROID_PROJECTS FALSE) +endif() + +# --- OpenCL --- +if(WITH_OPENCL) + include(cmake/OpenCVDetectOpenCL.cmake) +endif() + +# ---------------------------------------------------------------------------- +# Solution folders: +# ---------------------------------------------------------------------------- +if(ENABLE_SOLUTION_FOLDERS) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") +endif() + +# Extra OpenCV targets: uninstall, package_source, perf, etc. +include(cmake/OpenCVExtraTargets.cmake) + + +# ---------------------------------------------------------------------------- +# Process subdirectories +# ---------------------------------------------------------------------------- + +# opencv.hpp and legacy headers +add_subdirectory(include) + +# OpenCV modules +#add_subdirectory(modules) +# modification XBEE +add_subdirectory(core) +add_subdirectory(highgui) +add_subdirectory(imgproc) +add_subdirectory(3rdparty) + + +# Generate targets for documentation +#add_subdirectory(doc) + +# various data that is used by cv libraries and/or demo applications. +#add_subdirectory(data) + +# extra applications +#if(BUILD_opencv_apps) +# add_subdirectory(apps) +#endif() + +# examples +#if(BUILD_EXAMPLES OR BUILD_ANDROID_EXAMPLES OR INSTALL_PYTHON_EXAMPLES) +# add_subdirectory(samples) +#endif() + +#if(ANDROID) +# add_subdirectory(android/service) +#endif() + +#if(BUILD_ANDROID_PACKAGE) +# add_subdirectory(android/package) +#endif() + +#if (ANDROID) +# add_subdirectory(android/libinfo) +#endif() + +# ---------------------------------------------------------------------------- +# Finalization: generate configuration-based files +# ---------------------------------------------------------------------------- +ocv_track_build_dependencies() + +# Generate platform-dependent and configuration-dependent headers +include(cmake/OpenCVGenHeaders.cmake) + +# Generate opencv.pc for pkg-config command +include(cmake/OpenCVGenPkgconfig.cmake) + +# Generate OpenCV.mk for ndk-build (Android build tool) +include(cmake/OpenCVGenAndroidMK.cmake) + +# Generate OpenCVСonfig.cmake and OpenCVConfig-version.cmake for cmake projects +include(cmake/OpenCVGenConfig.cmake) + + +# ---------------------------------------------------------------------------- +# Summary: +# ---------------------------------------------------------------------------- +status("") +status("General configuration for OpenCV ${OPENCV_VERSION} =====================================") +if(OPENCV_VCSVERSION) + status(" Version control:" ${OPENCV_VCSVERSION}) +endif() + +# ========================== build platform ========================== +status("") +status(" Platform:") +status(" Host:" ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_VERSION} ${CMAKE_HOST_SYSTEM_PROCESSOR}) +if(CMAKE_CROSSCOMPILING) + status(" Target:" ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}) +endif() +status(" CMake:" ${CMAKE_VERSION}) +status(" CMake generator:" ${CMAKE_GENERATOR}) +status(" CMake build tool:" ${CMAKE_BUILD_TOOL}) +if(MSVC) + status(" MSVC:" ${MSVC_VERSION}) +endif() +if(CMAKE_GENERATOR MATCHES Xcode) + status(" Xcode:" ${XCODE_VERSION}) +endif() +if(NOT CMAKE_GENERATOR MATCHES "Xcode|Visual Studio") + status(" Configuration:" ${CMAKE_BUILD_TYPE}) +endif() + +# ========================== C/C++ options ========================== +if(CMAKE_CXX_COMPILER_VERSION) + set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_CXX_COMPILER_VERSION})") +elseif(CMAKE_COMPILER_IS_CLANGCXX) + set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_CLANG_REGEX_VERSION})") +elseif(CMAKE_COMPILER_IS_GNUCXX) + set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} (ver ${CMAKE_GCC_REGEX_VERSION})") +else() + set(OPENCV_COMPILER_STR "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}") +endif() +string(STRIP "${OPENCV_COMPILER_STR}" OPENCV_COMPILER_STR) + +status("") +status(" C/C++:") +status(" Built as dynamic libs?:" BUILD_SHARED_LIBS THEN YES ELSE NO) +status(" C++ Compiler:" ${OPENCV_COMPILER_STR}) +status(" C++ flags (Release):" ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}) +status(" C++ flags (Debug):" ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}) +status(" C Compiler:" ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}) +status(" C flags (Release):" ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}) +status(" C flags (Debug):" ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG}) +if(WIN32) + status(" Linker flags (Release):" ${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) + status(" Linker flags (Debug):" ${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_DEBUG}) +else() + status(" Linker flags (Release):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}) + status(" Linker flags (Debug):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}) +endif() +status(" Precompiled headers:" PCHSupport_FOUND AND ENABLE_PRECOMPILED_HEADERS THEN YES ELSE NO) + +# ========================== OpenCV modules ========================== +status("") +status(" OpenCV modules:") +string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD}") +string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_USER_ST "${OPENCV_MODULES_DISABLED_USER}") +string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_FORCE_ST "${OPENCV_MODULES_DISABLED_FORCE}") +set(OPENCV_MODULES_DISABLED_AUTO_ST "") +foreach(m ${OPENCV_MODULES_DISABLED_AUTO}) + set(__mdeps "") + foreach(d ${OPENCV_MODULE_${m}_DEPS}) + if(d MATCHES "^opencv_" AND NOT HAVE_${d}) + list(APPEND __mdeps ${d}) + endif() + endforeach() + if(__mdeps) + list(APPEND OPENCV_MODULES_DISABLED_AUTO_ST "${m}(deps: ${__mdeps})") + else() + list(APPEND OPENCV_MODULES_DISABLED_AUTO_ST "${m}") + endif() +endforeach() +string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_AUTO_ST "${OPENCV_MODULES_DISABLED_AUTO_ST}") + +status(" To be built:" OPENCV_MODULES_BUILD THEN ${OPENCV_MODULES_BUILD_ST} ELSE "-") +status(" Disabled:" OPENCV_MODULES_DISABLED_USER THEN ${OPENCV_MODULES_DISABLED_USER_ST} ELSE "-") +status(" Disabled by dependency:" OPENCV_MODULES_DISABLED_AUTO THEN ${OPENCV_MODULES_DISABLED_AUTO_ST} ELSE "-") +status(" Unavailable:" OPENCV_MODULES_DISABLED_FORCE THEN ${OPENCV_MODULES_DISABLED_FORCE_ST} ELSE "-") + +# ========================== Android details ========================== +if(ANDROID) + status("") + status(" Android: ") + status(" Android ABI:" ${ANDROID_ABI}) + status(" STL type:" ${ANDROID_STL}) + status(" Native API level:" android-${ANDROID_NATIVE_API_LEVEL}) + android_get_compatible_target(android_sdk_target_status ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET} 11) + status(" SDK target:" "${android_sdk_target_status}") + if(BUILD_WITH_ANDROID_NDK) + status(" Android NDK:" "${ANDROID_NDK} (toolchain: ${ANDROID_TOOLCHAIN_NAME})") + elseif(BUILD_WITH_STANDALONE_TOOLCHAIN) + status(" Android toolchain:" "${ANDROID_STANDALONE_TOOLCHAIN}") + endif() + status(" android tool:" ANDROID_EXECUTABLE THEN "${ANDROID_EXECUTABLE} (${ANDROID_TOOLS_Pkg_Desc})" ELSE NO) + status(" Google Play package:" BUILD_ANDROID_PACKAGE THEN YES ELSE NO) + status(" Android examples:" BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) +endif() + +# ========================== GUI ========================== +status("") +status(" GUI: ") + +if(HAVE_QT) + status(" QT 4.x:" HAVE_QT THEN "YES (ver ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} ${QT_EDITION})" ELSE NO) + status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${QT_QTOPENGL_LIBRARY})" ELSE NO) +else() + if(DEFINED WITH_QT) + status(" QT 4.x:" NO) + endif() + if(DEFINED WITH_WIN32UI) + status(" Win32 UI:" HAVE_WIN32UI THEN YES ELSE NO) + else() + if(APPLE) + if(WITH_CARBON) + status(" Carbon:" YES) + else() + status(" Cocoa:" YES) + endif() + else() + status(" GTK+ 2.x:" HAVE_GTK THEN "YES (ver ${ALIASOF_gtk+-2.0_VERSION})" ELSE NO) + status(" GThread :" HAVE_GTHREAD THEN "YES (ver ${ALIASOF_gthread-2.0_VERSION})" ELSE NO) + status(" GtkGlExt:" HAVE_GTKGLEXT THEN "YES (ver ${ALIASOF_gtkglext-1.0_VERSION})" ELSE NO) + endif() + endif() +endif() + +status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO) + +# ========================== MEDIA IO ========================== +status("") +status(" Media I/O: ") +status(" ZLib:" BUILD_ZLIB THEN "build (ver ${ZLIB_VERSION_STRING})" ELSE "${ZLIB_LIBRARY} (ver ${ZLIB_VERSION_STRING})") + +if(WITH_JPEG) + status(" JPEG:" JPEG_FOUND THEN "${JPEG_LIBRARY} (ver ${JPEG_LIB_VERSION})" ELSE "build (ver ${JPEG_LIB_VERSION})") +else() + status(" JPEG:" "NO") +endif() +if(WITH_PNG) + status(" PNG:" PNG_FOUND THEN "${PNG_LIBRARY} (ver ${PNG_VERSION})" ELSE "build (ver ${PNG_VERSION})") +else() + status(" PNG:" "NO") +endif() +if(WITH_TIFF) + if(TIFF_VERSION_STRING AND TIFF_FOUND) + status(" TIFF:" "${TIFF_LIBRARY} (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})") + else() + status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION})" ELSE "build (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})") + endif() +else() + status(" TIFF:" "NO") +endif() +if(WITH_JASPER) + status(" JPEG 2000:" JASPER_FOUND THEN "${JASPER_LIBRARY} (ver ${JASPER_VERSION_STRING})" ELSE "build (ver ${JASPER_VERSION_STRING})") +else() + status(" JPEG 2000:" "NO") +endif() +if(WITH_OPENEXR) + status(" OpenEXR:" OPENEXR_FOUND THEN "${OPENEXR_LIBRARIES} (ver ${OPENEXR_VERSION})" ELSE "build (ver ${OPENEXR_VERSION})") +else() + status(" OpenEXR:" "NO") +endif() + +# ========================== VIDEO IO ========================== +status("") +status(" Video I/O:") + +if (DEFINED WITH_VFW) + status(" Video for Windows:" HAVE_VFW THEN YES ELSE NO) +endif(DEFINED WITH_VFW) + +if(DEFINED WITH_1394) + status(" DC1394 1.x:" HAVE_DC1394 THEN "YES (ver ${ALIASOF_libdc1394_VERSION})" ELSE NO) + status(" DC1394 2.x:" HAVE_DC1394_2 THEN "YES (ver ${ALIASOF_libdc1394-2_VERSION})" ELSE NO) +endif(DEFINED WITH_1394) + +if(ANDROID) + if(HAVE_opencv_androidcamera) + status(" AndroidNativeCamera:" BUILD_ANDROID_CAMERA_WRAPPER + THEN "YES, build for Android${ANDROID_VERSION}" ELSE "YES, use prebuilt libraries") + else() + status(" AndroidNativeCamera:" "NO (native camera requires Android API level 8 or higher)") + endif() +endif() + +if(DEFINED WITH_AVFOUNDATION) + status(" AVFoundation:" WITH_AVFOUNDATION THEN YES ELSE NO) +endif(DEFINED WITH_AVFOUNDATION) + +if(DEFINED WITH_FFMPEG) + if(WIN32) + status(" FFMPEG:" WITH_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO) + else() + status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO) + endif() + status(" codec:" HAVE_FFMPEG_CODEC THEN "YES (ver ${ALIASOF_libavcodec_VERSION})" ELSE NO) + status(" format:" HAVE_FFMPEG_FORMAT THEN "YES (ver ${ALIASOF_libavformat_VERSION})" ELSE NO) + status(" util:" HAVE_FFMPEG_UTIL THEN "YES (ver ${ALIASOF_libavutil_VERSION})" ELSE NO) + status(" swscale:" HAVE_FFMPEG_SWSCALE THEN "YES (ver ${ALIASOF_libswscale_VERSION})" ELSE NO) + status(" gentoo-style:" HAVE_GENTOO_FFMPEG THEN YES ELSE NO) +endif(DEFINED WITH_FFMPEG) + +if(DEFINED WITH_GSTREAMER) + status(" GStreamer:" HAVE_GSTREAMER THEN "" ELSE NO) + if(HAVE_GSTREAMER) + status(" base:" "YES (ver ${ALIASOF_gstreamer-base-0.10_VERSION})") + status(" app:" "YES (ver ${ALIASOF_gstreamer-app-0.10_VERSION})") + status(" video:" "YES (ver ${ALIASOF_gstreamer-video-0.10_VERSION})") + endif() +endif(DEFINED WITH_GSTREAMER) + +if(DEFINED WITH_OPENNI) + status(" OpenNI:" HAVE_OPENNI THEN "YES (ver ${OPENNI_VERSION_STRING}, build ${OPENNI_VERSION_BUILD})" + ELSE NO) + status(" OpenNI PrimeSensor Modules:" HAVE_OPENNI_PRIME_SENSOR_MODULE + THEN "YES (${OPENNI_PRIME_SENSOR_MODULE})" ELSE NO) +endif(DEFINED WITH_OPENNI) + +if(DEFINED WITH_PVAPI) + status(" PvAPI:" HAVE_PVAPI THEN YES ELSE NO) +endif(DEFINED WITH_PVAPI) + +if(DEFINED WITH_GIGEAPI) + status(" GigEVisionSDK:" HAVE_GIGE_API THEN YES ELSE NO) +endif(DEFINED WITH_GIGEAPI) + +if(DEFINED WITH_QUICKTIME) + status(" QuickTime:" WITH_QUICKTIME THEN YES ELSE NO) + status(" QTKit:" WITH_QUICKTIME THEN NO ELSE YES) +endif(DEFINED WITH_QUICKTIME) + +if(DEFINED WITH_UNICAP) + status(" UniCap:" HAVE_UNICAP THEN "YES (ver ${ALIASOF_libunicap_VERSION})" ELSE NO) + status(" UniCap ucil:" HAVE_UNICAP_UCIL THEN "YES (ver ${ALIASOF_libucil_VERSION})" ELSE NO) +endif(DEFINED WITH_UNICAP) + +if(DEFINED WITH_V4L) + if(HAVE_CAMV4L) + set(HAVE_CAMV4L_STR "YES") + else() + set(HAVE_CAMV4L_STR "NO") + endif() + if(HAVE_CAMV4L2) + set(HAVE_CAMV4L2_STR "YES") + elseif(HAVE_VIDEOIO) + set(HAVE_CAMV4L2_STR "YES(videoio)") + else() + set(HAVE_CAMV4L2_STR "NO") + endif() + status(" V4L/V4L2:" HAVE_LIBV4L THEN "Using libv4l (ver ${ALIASOF_libv4l1_VERSION})" + ELSE "${HAVE_CAMV4L_STR}/${HAVE_CAMV4L2_STR}") +endif(DEFINED WITH_V4L) + +if(DEFINED WITH_DSHOW) + status(" DirectShow:" HAVE_DSHOW THEN YES ELSE NO) +endif(DEFINED WITH_DSHOW) + +if(DEFINED WITH_MSMF) + status(" Media Foundation:" HAVE_MSMF THEN YES ELSE NO) +endif(DEFINED WITH_MSMF) + +if(DEFINED WITH_XIMEA) + status(" XIMEA:" HAVE_XIMEA THEN YES ELSE NO) +endif(DEFINED WITH_XIMEA) + +if(DEFINED WITH_XINE) + status(" Xine:" HAVE_XINE THEN "YES (ver ${ALIASOF_libxine_VERSION})" ELSE NO) +endif(DEFINED WITH_XINE) + +# ========================== Other third-party libraries ========================== +status("") +status(" Other third-party libraries:") + +if(WITH_IPP AND IPP_FOUND) + status(" Use IPP:" "${IPP_LATEST_VERSION_STR} [${IPP_LATEST_VERSION_MAJOR}.${IPP_LATEST_VERSION_MINOR}.${IPP_LATEST_VERSION_BUILD}]") + status(" at:" "${IPP_ROOT_DIR}") +else() + status(" Use IPP:" WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO) +endif() + +status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) +status(" Use TBB:" HAVE_TBB THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO) +status(" Use OpenMP:" HAVE_OPENMP THEN YES ELSE NO) +status(" Use GCD" HAVE_GCD THEN YES ELSE NO) +status(" Use Concurrency" HAVE_CONCURRENCY THEN YES ELSE NO) +status(" Use C=:" HAVE_CSTRIPES THEN YES ELSE NO) +status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO) +status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO) + +if(HAVE_CUDA) + status("") + status(" NVIDIA CUDA") + + status(" Use CUFFT:" HAVE_CUFFT THEN YES ELSE NO) + status(" Use CUBLAS:" HAVE_CUBLAS THEN YES ELSE NO) + status(" USE NVCUVID:" HAVE_NVCUVID THEN YES ELSE NO) + status(" NVIDIA GPU arch:" ${OPENCV_CUDA_ARCH_BIN}) + status(" NVIDIA PTX archs:" ${OPENCV_CUDA_ARCH_PTX}) + status(" Use fast math:" CUDA_FAST_MATH THEN YES ELSE NO) +endif() + +if(HAVE_OPENCL) + status("") + status(" OpenCL") + if(OPENCL_INCLUDE_DIR) + status(" Include path:" ${OPENCL_INCLUDE_DIRS}) + endif() + if(OPENCL_LIBRARIES) + status(" libraries:" ${OPENCL_LIBRARIES}) + endif() + status(" Use AMD FFT:" HAVE_CLAMDFFT THEN YES ELSE NO) + status(" Use AMD BLAS:" HAVE_CLAMDBLAS THEN YES ELSE NO) +endif() + +# ========================== python ========================== +status("") +status(" Python:") +status(" Interpreter:" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_FULL})" ELSE NO) +if(BUILD_opencv_python) + if(PYTHONLIBS_VERSION_STRING) + status(" Libraries:" HAVE_opencv_python THEN "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})" ELSE NO) + else() + status(" Libraries:" HAVE_opencv_python THEN ${PYTHON_LIBRARIES} ELSE NO) + endif() + status(" numpy:" PYTHON_USE_NUMPY THEN "${PYTHON_NUMPY_INCLUDE_DIR} (ver ${PYTHON_NUMPY_VERSION})" ELSE "NO (Python wrappers can not be generated)") + status(" packages path:" PYTHON_EXECUTABLE THEN "${PYTHON_PACKAGES_PATH}" ELSE "-") +endif() + +# ========================== java ========================== +status("") +status(" Java:") +status(" ant:" ANT_EXECUTABLE THEN "${ANT_EXECUTABLE} (ver ${ANT_VERSION})" ELSE NO) +if(NOT ANDROID) + status(" JNI:" JNI_INCLUDE_DIRS THEN "${JNI_INCLUDE_DIRS}" ELSE NO) +endif() +status(" Java tests:" BUILD_TESTS AND (NOT ANDROID OR CAN_BUILD_ANDROID_PROJECTS) THEN YES ELSE NO) + +# ========================== documentation ========================== +if(BUILD_DOCS) + status("") + status(" Documentation:") + if(HAVE_SPHINX) + status(" Build Documentation:" PDFLATEX_COMPILER THEN YES ELSE "YES (only HTML and without math expressions)") + else() + status(" Build Documentation:" NO) + endif() + status(" Sphinx:" HAVE_SPHINX THEN "${SPHINX_BUILD} (ver ${SPHINX_VERSION})" ELSE NO) + status(" PdfLaTeX compiler:" PDFLATEX_COMPILER THEN "${PDFLATEX_COMPILER}" ELSE NO) +endif() + +# ========================== samples and tests ========================== +status("") +status(" Tests and samples:") +status(" Tests:" BUILD_TESTS AND HAVE_opencv_ts THEN YES ELSE NO) +status(" Performance tests:" BUILD_PERF_TESTS AND HAVE_opencv_ts THEN YES ELSE NO) +status(" C/C++ Examples:" BUILD_EXAMPLES THEN YES ELSE NO) + +# ========================== auxiliary ========================== +status("") +status(" Install path:" "${CMAKE_INSTALL_PREFIX}") +status("") +status(" cvconfig.h is in:" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}") +status("-----------------------------------------------------------------") +status("") + +ocv_finalize_status() + +# ---------------------------------------------------------------------------- +# Warn in the case of in-source build +# ---------------------------------------------------------------------------- +if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") + message(WARNING "The source directory is the same as binary directory. \"make clean\" may damage the source tree") +endif() + diff -Nru diffimg-1.5.0/3rdparty/opencv/README diffimg-2.0.0/3rdparty/opencv/README --- diffimg-1.5.0/3rdparty/opencv/README 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/README 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,6 @@ +OpenCV: open source computer vision library + +Homepage: http://opencv.org +Online docs: http://docs.opencv.org +Q&A forum: http://answers.opencv.org +Dev zone: http://code.opencv.org diff -Nru diffimg-1.5.0/3rdparty/opencv/README.diffimg diffimg-2.0.0/3rdparty/opencv/README.diffimg --- diffimg-1.5.0/3rdparty/opencv/README.diffimg 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/README.diffimg 2013-07-17 16:45:30.000000000 +0000 @@ -0,0 +1 @@ +This release has been slightly modified for os2 compilation diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/CMakeParseArguments.cmake diffimg-2.0.0/3rdparty/opencv/cmake/CMakeParseArguments.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/CMakeParseArguments.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/CMakeParseArguments.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,138 @@ +# CMAKE_PARSE_ARGUMENTS( args...) +# +# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for +# parsing the arguments given to that macro or function. +# It processes the arguments and defines a set of variables which hold the +# values of the respective options. +# +# The argument contains all options for the respective macro, +# i.e. keywords which can be used when calling the macro without any value +# following, like e.g. the OPTIONAL keyword of the install() command. +# +# The argument contains all keywords for this macro +# which are followed by one value, like e.g. DESTINATION keyword of the +# install() command. +# +# The argument contains all keywords for this macro +# which can be followed by more than one value, like e.g. the TARGETS or +# FILES keywords of the install() command. +# +# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the +# keywords listed in , and +# a variable composed of the given +# followed by "_" and the name of the respective keyword. +# These variables will then hold the respective value from the argument list. +# For the keywords this will be TRUE or FALSE. +# +# All remaining arguments are collected in a variable +# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether +# your macro was called with unrecognized parameters. +# +# As an example here a my_install() macro, which takes similar arguments as the +# real install() command: +# +# function(MY_INSTALL) +# set(options OPTIONAL FAST) +# set(oneValueArgs DESTINATION RENAME) +# set(multiValueArgs TARGETS CONFIGURATIONS) +# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) +# ... +# +# Assume my_install() has been called like this: +# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) +# +# After the cmake_parse_arguments() call the macro will have set the following +# variables: +# MY_INSTALL_OPTIONAL = TRUE +# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() +# MY_INSTALL_DESTINATION = "bin" +# MY_INSTALL_RENAME = "" (was not used) +# MY_INSTALL_TARGETS = "foo;bar" +# MY_INSTALL_CONFIGURATIONS = "" (was not used) +# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" +# +# You can the continue and process these variables. +# +# Keywords terminate lists of values, e.g. if directly after a one_value_keyword +# another recognized keyword follows, this is interpreted as the beginning of +# the new option. +# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in +# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. + +#============================================================================= +# Copyright 2010 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) + return() +endif() +set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) + + +function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) + # first set all result variables to empty/FALSE + foreach(arg_name ${_singleArgNames} ${_multiArgNames}) + set(${prefix}_${arg_name}) + endforeach(arg_name) + + foreach(option ${_optionNames}) + set(${prefix}_${option} FALSE) + endforeach(option) + + set(${prefix}_UNPARSED_ARGUMENTS) + + set(insideValues FALSE) + set(currentArgName) + + # now iterate over all arguments and fill the result variables + foreach(currentArg ${ARGN}) + list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword + + if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) + if(insideValues) + if("${insideValues}" STREQUAL "SINGLE") + set(${prefix}_${currentArgName} ${currentArg}) + set(insideValues FALSE) + elseif("${insideValues}" STREQUAL "MULTI") + list(APPEND ${prefix}_${currentArgName} ${currentArg}) + endif() + else(insideValues) + list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) + endif(insideValues) + else() + if(NOT ${optionIndex} EQUAL -1) + set(${prefix}_${currentArg} TRUE) + set(insideValues FALSE) + elseif(NOT ${singleArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "SINGLE") + elseif(NOT ${multiArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "MULTI") + endif() + endif() + + endforeach(currentArg) + + # propagate the result variables to the caller: + foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) + set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) + endforeach(arg_name) + set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) + +endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVCRTLinkage.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVCRTLinkage.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVCRTLinkage.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVCRTLinkage.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,65 @@ +if(NOT MSVC) + message(FATAL_ERROR "CRT options are available only for MSVC") +endif() + +if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT) + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif() + if(${flag_var} MATCHES "/MDd") + string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") + endif() + endforeach(flag_var) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcrtd.lib") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib") +else() + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MT") + string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}") + endif() + if(${flag_var} MATCHES "/MTd") + string(REGEX REPLACE "/MTd" "/MDd" ${flag_var} "${${flag_var}}") + endif() + endforeach(flag_var) +endif() + +if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.8 AND NOT ${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} LESS 8.6) + include(ProcessorCount) + ProcessorCount(N) + if(NOT N EQUAL 0) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP${N} ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP${N} ") + endif() +endif() + +if(NOT BUILD_WITH_DEBUG_INFO AND NOT MSVC) + string(REPLACE "/debug" "" CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/DEBUG" "" CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL:YES" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + + string(REPLACE "/debug" "" CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/DEBUG" "" CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL:YES" "/INCREMENTAL:NO" CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}") + + string(REPLACE "/debug" "" CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + string(REPLACE "/DEBUG" "" CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL:YES" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + + string(REPLACE "/Zi" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") + string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") +endif() + diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVCompilerOptions.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVCompilerOptions.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVCompilerOptions.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVCompilerOptions.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,294 @@ +if(MINGW OR (X86 AND UNIX AND NOT APPLE)) + # mingw compiler is known to produce unstable SSE code with -O3 hence we are trying to use -O2 instead + if(CMAKE_COMPILER_IS_GNUCXX) + foreach(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + string(REPLACE "-O3" "-O2" ${flags} "${${flags}}") + endforeach() + endif() + + if(CMAKE_COMPILER_IS_GNUCC) + foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG) + string(REPLACE "-O3" "-O2" ${flags} "${${flags}}") + endforeach() + endif() +endif() + +if(MSVC) + string(REGEX REPLACE "^ *| * $" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "^ *| * $" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}") + if(CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS_INIT) + # override cmake default exception handling option + string(REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "Flags used by the compiler during all build types." FORCE) + endif() +endif() + +set(OPENCV_EXTRA_FLAGS "") +set(OPENCV_EXTRA_C_FLAGS "") +set(OPENCV_EXTRA_CXX_FLAGS "") +set(OPENCV_EXTRA_FLAGS_RELEASE "") +set(OPENCV_EXTRA_FLAGS_DEBUG "") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS "") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "") + +macro(add_extra_compiler_option option) + if(CMAKE_BUILD_TYPE) + set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE}) + endif() + ocv_check_flag_support(CXX "${option}" _varname "${OPENCV_EXTRA_CXX_FLAGS} ${ARGN}") + if(${_varname}) + set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} ${option}") + endif() + + ocv_check_flag_support(C "${option}" _varname "${OPENCV_EXTRA_C_FLAGS} ${ARGN}") + if(${_varname}) + set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} ${option}") + endif() +endmacro() + +if(MINGW) + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838 + # here we are trying to workaround the problem + add_extra_compiler_option(-mstackrealign) + if(NOT HAVE_CXX_MSTACKREALIGN) + add_extra_compiler_option(-mpreferred-stack-boundary=2) + endif() +endif() + +if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY) + add_definitions(-DOPENCV_CAN_BREAK_BINARY_COMPATIBILITY) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + # High level of warnings. + add_extra_compiler_option(-W) + add_extra_compiler_option(-Wall) + add_extra_compiler_option(-Werror=return-type) + if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY) + add_extra_compiler_option(-Werror=non-virtual-dtor) + endif() + add_extra_compiler_option(-Werror=address) + add_extra_compiler_option(-Werror=sequence-point) + add_extra_compiler_option(-Wformat) + add_extra_compiler_option(-Werror=format-security -Wformat) + add_extra_compiler_option(-Wmissing-declarations) + add_extra_compiler_option(-Wmissing-prototypes) + add_extra_compiler_option(-Wstrict-prototypes) + add_extra_compiler_option(-Wundef) + add_extra_compiler_option(-Winit-self) + add_extra_compiler_option(-Wpointer-arith) + add_extra_compiler_option(-Wshadow) + add_extra_compiler_option(-Wsign-promo) + + if(ENABLE_NOISY_WARNINGS) + add_extra_compiler_option(-Wcast-align) + add_extra_compiler_option(-Wstrict-aliasing=2) + else() + add_extra_compiler_option(-Wno-narrowing) + add_extra_compiler_option(-Wno-delete-non-virtual-dtor) + add_extra_compiler_option(-Wno-unnamed-type-template-args) + endif() + add_extra_compiler_option(-fdiagnostics-show-option) + + # The -Wno-long-long is required in 64bit systems when including sytem headers. + if(X86_64) + add_extra_compiler_option(-Wno-long-long) + endif() + + # We need pthread's + if(UNIX AND NOT ANDROID AND NOT (APPLE AND CMAKE_COMPILER_IS_CLANGCXX)) + add_extra_compiler_option(-pthread) + endif() + + if(OPENCV_WARNINGS_ARE_ERRORS) + add_extra_compiler_option(-Werror) + endif() + + if(X86 AND NOT MINGW64 AND NOT X86_64 AND NOT APPLE) + add_extra_compiler_option(-march=i686) + endif() + + # Other optimizations + if(ENABLE_OMIT_FRAME_POINTER) + add_extra_compiler_option(-fomit-frame-pointer) + else() + add_extra_compiler_option(-fno-omit-frame-pointer) + endif() + if(ENABLE_FAST_MATH) + add_extra_compiler_option(-ffast-math) + endif() + if(ENABLE_POWERPC) + add_extra_compiler_option("-mcpu=G3 -mtune=G5") + endif() + if(ENABLE_SSE) + add_extra_compiler_option(-msse) + endif() + if(ENABLE_SSE2) + add_extra_compiler_option(-msse2) + endif() + + # SSE3 and further should be disabled under MingW because it generates compiler errors + if(NOT MINGW) + if(ENABLE_AVX) + add_extra_compiler_option(-mavx) + endif() + + # GCC depresses SSEx instructions when -mavx is used. Instead, it generates new AVX instructions or AVX equivalence for all SSEx instructions when needed. + if(NOT OPENCV_EXTRA_CXX_FLAGS MATCHES "-mavx") + if(ENABLE_SSE3) + add_extra_compiler_option(-msse3) + endif() + + if(ENABLE_SSSE3) + add_extra_compiler_option(-mssse3) + endif() + + if(ENABLE_SSE41) + add_extra_compiler_option(-msse4.1) + endif() + + if(ENABLE_SSE42) + add_extra_compiler_option(-msse4.2) + endif() + endif() + endif(NOT MINGW) + + if(X86 OR X86_64) + if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4) + if(OPENCV_EXTRA_CXX_FLAGS MATCHES "-m(sse2|avx)") + add_extra_compiler_option(-mfpmath=sse)# !! important - be on the same wave with x64 compilers + else() + add_extra_compiler_option(-mfpmath=387) + endif() + endif() + endif() + + # Profiling? + if(ENABLE_PROFILING) + add_extra_compiler_option("-pg -g") + # turn off incompatible options + foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG + OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS) + string(REPLACE "-fomit-frame-pointer" "" ${flags} "${${flags}}") + string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}") + endforeach() + elseif(NOT APPLE AND NOT ANDROID) + # Remove unreferenced functions: function level linking + add_extra_compiler_option(-ffunction-sections) + endif() + + set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} -DNDEBUG") + set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -O0 -DDEBUG -D_DEBUG") + if(BUILD_WITH_DEBUG_INFO) + set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -ggdb3") + endif() +endif() + +if(MSVC) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS") + # 64-bit portability warnings, in MSVC80 + if(MSVC80) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Wp64") + endif() + + if(BUILD_WITH_DEBUG_INFO) + set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /debug") + endif() + + # Remove unreferenced functions: function level linking + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Gy") + if(NOT MSVC_VERSION LESS 1400) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /bigobj") + endif() + if(BUILD_WITH_DEBUG_INFO) + set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} /Zi") + endif() + + if(ENABLE_AVX AND NOT MSVC_VERSION LESS 1600) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:AVX") + endif() + + if(ENABLE_SSE4_1 AND CV_ICC AND NOT OPENCV_EXTRA_FLAGS MATCHES "/arch:") + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE4.1") + endif() + + if(ENABLE_SSE3 AND CV_ICC AND NOT OPENCV_EXTRA_FLAGS MATCHES "/arch:") + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE3") + endif() + + if(NOT MSVC64) + # 64-bit MSVC compiler uses SSE/SSE2 by default + if(ENABLE_SSE2 AND NOT OPENCV_EXTRA_FLAGS MATCHES "/arch:") + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE2") + endif() + if(ENABLE_SSE AND NOT OPENCV_EXTRA_FLAGS MATCHES "/arch:") + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE") + endif() + endif() + + if(ENABLE_SSE OR ENABLE_SSE2 OR ENABLE_SSE3 OR ENABLE_SSE4_1 OR ENABLE_AVX) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Oi") + endif() + + if(X86 OR X86_64) + if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND ENABLE_SSE2) + set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /fp:fast") # !! important - be on the same wave with x64 compilers + endif() + endif() +endif() + +# Extra link libs if the user selects building static libs: +if(NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX AND NOT ANDROID) + # Android does not need these settings because they are already set by toolchain file + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} stdc++) + set(OPENCV_EXTRA_FLAGS "-fPIC ${OPENCV_EXTRA_FLAGS}") +endif() + +# Add user supplied extra options (optimization, etc...) +# ========================================================== +set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS}" CACHE INTERNAL "Extra compiler options") +set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS}" CACHE INTERNAL "Extra compiler options for C sources") +set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS}" CACHE INTERNAL "Extra compiler options for C++ sources") +set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE}" CACHE INTERNAL "Extra compiler options for Release build") +set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG}" CACHE INTERNAL "Extra compiler options for Debug build") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS}" CACHE INTERNAL "Extra linker flags") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}" CACHE INTERNAL "Extra linker flags for Release build") +set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Extra linker flags for Debug build") + +#combine all "extra" options +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_C_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_EXTRA_EXE_LINKER_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}") + +if(MSVC) + # avoid warnings from MSVC about overriding the /W* option + # we replace /W3 with /W4 only for C++ files, + # since all the 3rd-party libraries OpenCV uses are in C, + # and we do not care about their warnings. + string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + + if(NOT ENABLE_NOISY_WARNINGS AND MSVC_VERSION EQUAL 1400) + ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4510 /wd4610 /wd4312 /wd4201 /wd4244 /wd4328 /wd4267) + endif() + + # allow extern "C" functions throw exceptions + foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + string(REPLACE "/EHsc-" "/EHs" ${flags} "${${flags}}") + string(REPLACE "/EHsc" "/EHs" ${flags} "${${flags}}") + + string(REPLACE "/Zm1000" "" ${flags} "${${flags}}") + endforeach() + + if(NOT ENABLE_NOISY_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") #class 'std::XXX' needs to have dll-interface to be used by clients of YYY + endif() +endif() \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVConfig.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVConfig.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVConfig.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVConfig.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,159 @@ +# =================================================================================== +# The OpenCV CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# FIND_PACKAGE(OpenCV REQUIRED) +# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ${OpenCV_LIBS}) +# +# Or you can search for specific OpenCV modules: +# +# FIND_PACKAGE(OpenCV REQUIRED core highgui) +# +# If the module is found then OPENCV__FOUND is set to TRUE. +# +# This file will define the following variables: +# - OpenCV_LIBS : The list of libraries to links against. +# - OpenCV_LIB_DIR : The directory(es) where lib files are. Calling LINK_DIRECTORIES +# with this path is NOT needed. +# - OpenCV_INCLUDE_DIRS : The OpenCV include directories. +# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability +# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API +# - OpenCV_VERSION : The version of this OpenCV build. Example: "2.4.0" +# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION. Example: "2" +# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION. Example: "4" +# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION. Example: "0" +# +# Advanced variables: +# - OpenCV_SHARED +# - OpenCV_CONFIG_PATH +# - OpenCV_LIB_COMPONENTS +# +# =================================================================================== +# +# Windows pack specific options: +# - OpenCV_STATIC +# - OpenCV_CUDA + +if(CMAKE_VERSION VERSION_GREATER 2.6) + get_property(OpenCV_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + if(NOT ";${OpenCV_LANGUAGES};" MATCHES ";CXX;") + enable_language(CXX) + endif() +endif() + +if(NOT DEFINED OpenCV_STATIC) + # look for global setting + if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set(OpenCV_STATIC OFF) + else() + set(OpenCV_STATIC ON) + endif() +endif() + +if(NOT DEFINED OpenCV_CUDA) + # if user' app uses CUDA, then it probably wants CUDA-enabled OpenCV binaries + if(CUDA_FOUND) + set(OpenCV_CUDA ON) + endif() +endif() + +if(MSVC) + if(CMAKE_CL_64) + set(OpenCV_ARCH x64) + set(OpenCV_TBB_ARCH intel64) + else() + set(OpenCV_ARCH x86) + set(OpenCV_TBB_ARCH ia32) + endif() + if(MSVC_VERSION EQUAL 1400) + set(OpenCV_RUNTIME vc8) + elseif(MSVC_VERSION EQUAL 1500) + set(OpenCV_RUNTIME vc9) + elseif(MSVC_VERSION EQUAL 1600) + set(OpenCV_RUNTIME vc10) + elseif(MSVC_VERSION EQUAL 1700) + set(OpenCV_RUNTIME vc11) + endif() +elseif(MINGW) + set(OpenCV_RUNTIME mingw) + + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine + OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "64") + set(MINGW64 1) + set(OpenCV_ARCH x64) + else() + set(OpenCV_ARCH x86) + endif() +endif() + +if(CMAKE_VERSION VERSION_GREATER 2.6.2) + unset(OpenCV_CONFIG_PATH CACHE) +endif() + +get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE) +if(OpenCV_RUNTIME AND OpenCV_ARCH) + if(OpenCV_STATIC AND EXISTS "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake") + if(OpenCV_CUDA AND EXISTS "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake") + set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib") + else() + set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib") + endif() + elseif(EXISTS "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib/OpenCVConfig.cmake") + if(OpenCV_CUDA AND EXISTS "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib/OpenCVConfig.cmake") + set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib") + else() + set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib") + endif() + endif() +endif() + +if(OpenCV_LIB_PATH AND EXISTS "${OpenCV_LIB_PATH}/OpenCVConfig.cmake") + set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release OpenCV libraries are located" FORCE) + set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug OpenCV libraries are located" FORCE) + set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release 3rdpaty OpenCV dependencies are located" FORCE) + set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug 3rdpaty OpenCV dependencies are located" FORCE) + + include("${OpenCV_LIB_PATH}/OpenCVConfig.cmake") + + if(OpenCV_CUDA) + set(_OpenCV_LIBS "") + foreach(_lib ${OpenCV_LIBS}) + string(REPLACE "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}" "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}" _lib2 "${_lib}") + if(NOT EXISTS "${_lib}" AND EXISTS "${_lib2}") + list(APPEND _OpenCV_LIBS "${_lib2}") + else() + list(APPEND _OpenCV_LIBS "${_lib}") + endif() + endforeach() + set(OpenCV_LIBS ${_OpenCV_LIBS}) + endif() + set(OpenCV_FOUND TRUE CACHE BOOL "" FORCE) + set(OPENCV_FOUND TRUE CACHE BOOL "" FORCE) + + if(NOT OpenCV_FIND_QUIETLY) + message(STATUS "Found OpenCV ${OpenCV_VERSION} in ${OpenCV_LIB_PATH}") + if(NOT OpenCV_LIB_PATH MATCHES "/staticlib") + get_filename_component(_OpenCV_LIB_PATH "${OpenCV_LIB_PATH}/../bin" ABSOLUTE) + file(TO_NATIVE_PATH "${_OpenCV_LIB_PATH}" _OpenCV_LIB_PATH) + message(STATUS "You might need to add ${_OpenCV_LIB_PATH} to your PATH to be able to run your applications.") + if(OpenCV_LIB_PATH MATCHES "/gpu/") + string(REPLACE "\\gpu" "" _OpenCV_LIB_PATH2 "${_OpenCV_LIB_PATH}") + message(STATUS "GPU support is enabled so you might also need ${_OpenCV_LIB_PATH2} in your PATH (it must go after the ${_OpenCV_LIB_PATH}).") + endif() + endif() + endif() +else() + if(NOT OpenCV_FIND_QUIETLY) + message(WARNING "Found OpenCV 2.4.3 Windows Super Pack but it has not binaries compatible with your configuration. + You should manually point CMake variable OpenCV_DIR to your build of OpenCV library.") + endif() + set(OpenCV_FOUND FALSE CACHE BOOL "" FORCE) + set(OPENCV_FOUND FALSE CACHE BOOL "" FORCE) +endif() + diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectAndroidSDK.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectAndroidSDK.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectAndroidSDK.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectAndroidSDK.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,365 @@ +if(EXISTS "${ANDROID_EXECUTABLE}") + set(ANDROID_SDK_DETECT_QUIET TRUE) +endif() + +file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH) +file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH) + +if(CMAKE_HOST_WIN32) + set(ANDROID_SDK_OS windows) +elseif(CMAKE_HOST_APPLE) + set(ANDROID_SDK_OS macosx) +else() + set(ANDROID_SDK_OS linux) +endif() + +#find android SDK: search in ANDROID_SDK first +find_host_program(ANDROID_EXECUTABLE + NAMES android.bat android + PATH_SUFFIXES tools + PATHS + ENV ANDROID_SDK + DOC "Android SDK location" + NO_DEFAULT_PATH + ) + +# Now search default paths +find_host_program(ANDROID_EXECUTABLE + NAMES android.bat android + PATH_SUFFIXES android-sdk-${ANDROID_SDK_OS}/tools + android-sdk-${ANDROID_SDK_OS}_x86/tools + android-sdk-${ANDROID_SDK_OS}_86/tools + android-sdk/tools + PATHS /opt + "${HOME_ENV_PATH}/NVPACK" + "$ENV{SystemDrive}/NVPACK" + "${ProgramFiles_ENV_PATH}/Android" + DOC "Android SDK location" + ) + +if(ANDROID_EXECUTABLE) + if(NOT ANDROID_SDK_DETECT_QUIET) + message(STATUS "Found android tool: ${ANDROID_EXECUTABLE}") + endif() + + get_filename_component(ANDROID_SDK_TOOLS_PATH "${ANDROID_EXECUTABLE}" PATH) + + #read source.properties + if(EXISTS "${ANDROID_SDK_TOOLS_PATH}/source.properties") + file(STRINGS "${ANDROID_SDK_TOOLS_PATH}/source.properties" ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES REGEX "^[ ]*[^#].*$") + foreach(line ${ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES}) + string(REPLACE "\\:" ":" line ${line}) + string(REPLACE "=" ";" line ${line}) + list(GET line 0 line_name) + list(GET line 1 line_value) + string(REPLACE "." "_" line_name ${line_name}) + SET(ANDROID_TOOLS_${line_name} "${line_value}" CACHE INTERNAL "from ${ANDROID_SDK_TOOLS_PATH}/source.properties") + MARK_AS_ADVANCED(ANDROID_TOOLS_${line_name}) + endforeach() + endif() + + #fix missing revision (SDK tools before r9 don't set revision number correctly) + if(NOT ANDROID_TOOLS_Pkg_Revision) + SET(ANDROID_TOOLS_Pkg_Revision "Unknown" CACHE INTERNAL "") + MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Revision) + endif() + + #fix missing description + if(NOT ANDROID_TOOLS_Pkg_Desc) + SET(ANDROID_TOOLS_Pkg_Desc "Android SDK Tools, revision ${ANDROID_TOOLS_Pkg_Revision}." CACHE INTERNAL "") + MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Desc) + endif() + + #warn about outdated SDK + if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13) + SET(ANDROID_TOOLS_Pkg_Desc "${ANDROID_TOOLS_Pkg_Desc} It is recommended to update your SDK tools to revision 14 or newer." CACHE INTERNAL "") + endif() + + if(ANDROID_TOOLS_Pkg_Revision GREATER 13) + SET(ANDROID_PROJECT_PROPERTIES_FILE project.properties) + SET(ANDROID_ANT_PROPERTIES_FILE ant.properties) + else() + SET(ANDROID_PROJECT_PROPERTIES_FILE default.properties) + SET(ANDROID_ANT_PROPERTIES_FILE build.properties) + endif() + + set(ANDROID_MANIFEST_FILE AndroidManifest.xml) + set(ANDROID_LIB_PROJECT_FILES build.xml local.properties proguard-project.txt ${ANDROID_PROJECT_PROPERTIES_FILE}) + set(ANDROID_PROJECT_FILES ${ANDROID_LIB_PROJECT_FILES}) + + #get installed targets + if(ANDROID_TOOLS_Pkg_Revision GREATER 11) + execute_process(COMMAND ${ANDROID_EXECUTABLE} list target -c + RESULT_VARIABLE ANDROID_PROCESS + OUTPUT_VARIABLE ANDROID_SDK_TARGETS + ERROR_VARIABLE ANDROID_PROCESS_ERRORS + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX MATCHALL "[^\n]+" ANDROID_SDK_TARGETS "${ANDROID_SDK_TARGETS}") + else() + #old SDKs (r11 and older) don't provide compact list + execute_process(COMMAND ${ANDROID_EXECUTABLE} list target + RESULT_VARIABLE ANDROID_PROCESS + OUTPUT_VARIABLE ANDROID_SDK_TARGETS_FULL + ERROR_VARIABLE ANDROID_PROCESS_ERRORS + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX MATCHALL "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" ANDROID_SDK_TARGETS_FULL "${ANDROID_SDK_TARGETS_FULL}") + + SET(ANDROID_SDK_TARGETS "") + if(ANDROID_PROCESS EQUAL 0) + foreach(line ${ANDROID_SDK_TARGETS_FULL}) + string(REGEX REPLACE "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" "\\2" line "${line}") + list(APPEND ANDROID_SDK_TARGETS "${line}") + endforeach() + endif() + endif() + + if(NOT ANDROID_PROCESS EQUAL 0) + message(ERROR "Failed to get list of installed Android targets.") + set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND") + endif() + + # clear ANDROID_SDK_TARGET if no target is provided by user + if(NOT ANDROID_SDK_TARGET) + set(ANDROID_SDK_TARGET "" CACHE STRING "Android SDK target for the OpenCV Java API and samples") + endif() + if(ANDROID_SDK_TARGETS AND CMAKE_VERSION VERSION_GREATER "2.8") + set_property( CACHE ANDROID_SDK_TARGET PROPERTY STRINGS ${ANDROID_SDK_TARGETS} ) + endif() +endif(ANDROID_EXECUTABLE) + +# finds minimal installed SDK target compatible with provided names or API levels +# usage: +# get_compatible_android_api_level(VARIABLE [level1] [level2] ...) +macro(android_get_compatible_target VAR) + set(${VAR} "${VAR}-NOTFOUND") + if(ANDROID_SDK_TARGETS) + list(GET ANDROID_SDK_TARGETS 0 __lvl) + string(REGEX MATCH "[0-9]+$" __lvl "${__lvl}") + + #find minimal level mathing to all provided levels + foreach(lvl ${ARGN}) + string(REGEX MATCH "[0-9]+$" __level "${lvl}") + if(__level GREATER __lvl) + set(__lvl ${__level}) + endif() + endforeach() + + #search for compatible levels + foreach(lvl ${ANDROID_SDK_TARGETS}) + string(REGEX MATCH "[0-9]+$" __level "${lvl}") + if(__level EQUAL __lvl) + #look for exact match + foreach(usrlvl ${ARGN}) + if("${usrlvl}" STREQUAL "${lvl}") + set(${VAR} "${lvl}") + break() + endif() + endforeach() + if("${${VAR}}" STREQUAL "${lvl}") + break() #exact match was found + elseif(NOT ${VAR}) + set(${VAR} "${lvl}") + endif() + elseif(__level GREATER __lvl) + if(NOT ${VAR}) + set(${VAR} "${lvl}") + endif() + break() + endif() + endforeach() + + unset(__lvl) + unset(__level) + endif() +endmacro() + +unset(__android_project_chain CACHE) +#add_android_project(target_name ${path} NATIVE_DEPS opencv_core LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11) +macro(add_android_project target path) + # parse arguments + set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST) + set(__varname "android_proj_") + foreach(v ${android_proj_arglist}) + set(${__varname}${v} "") + endforeach() + foreach(arg ${ARGN}) + set(__var "${__varname}") + foreach(v ${android_proj_arglist}) + if("${v}" STREQUAL "${arg}") + set(__varname "android_proj_${v}") + break() + endif() + endforeach() + if(__var STREQUAL __varname) + list(APPEND ${__var} "${arg}") + endif() + endforeach() + + # get compatible SDK target + android_get_compatible_target(android_proj_sdk_target ${ANDROID_NATIVE_API_LEVEL} ${android_proj_SDK_TARGET}) + + if(NOT android_proj_sdk_target) + message(WARNING "Can not find any SDK target compatible with: ${ANDROID_NATIVE_API_LEVEL} ${android_proj_SDK_TARGET} + The project ${target} will not be build") + endif() + + # check native dependencies + if(android_proj_IGNORE_JAVA) + ocv_check_dependencies(${android_proj_NATIVE_DEPS}) + else() + ocv_check_dependencies(${android_proj_NATIVE_DEPS} opencv_java) + endif() + + if(OCV_DEPENDENCIES_FOUND AND android_proj_sdk_target AND ANDROID_EXECUTABLE AND ANT_EXECUTABLE AND ANDROID_TOOLS_Pkg_Revision GREATER 13 AND EXISTS "${path}/${ANDROID_MANIFEST_FILE}") + + project(${target}) + set(android_proj_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/.build") + + # get project sources + file(GLOB_RECURSE android_proj_files RELATIVE "${path}" "${path}/res/*" "${path}/src/*") + + if(NOT android_proj_IGNORE_MANIFEST) + list(APPEND android_proj_files ${ANDROID_MANIFEST_FILE}) + endif() + + # copy sources out from the build tree + set(android_proj_file_deps "") + foreach(f ${android_proj_files}) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/${f}" + COMMAND ${CMAKE_COMMAND} -E copy "${path}/${f}" "${android_proj_bin_dir}/${f}" + MAIN_DEPENDENCY "${path}/${f}" + COMMENT "Copying ${f}") + list(APPEND android_proj_file_deps "${path}/${f}" "${android_proj_bin_dir}/${f}") + endforeach() + + set(android_proj_lib_deps_commands "") + set(android_proj_target_files ${ANDROID_PROJECT_FILES}) + ocv_list_add_prefix(android_proj_target_files "${android_proj_bin_dir}/") + + # process Android library dependencies + foreach(dep ${android_proj_LIBRARY_DEPS}) + file(RELATIVE_PATH __dep "${android_proj_bin_dir}" "${dep}") + list(APPEND android_proj_lib_deps_commands + COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${android_proj_bin_dir}" --library "${__dep}") + endforeach() + + # fix Android project + add_custom_command( + OUTPUT ${android_proj_target_files} + COMMAND ${CMAKE_COMMAND} -E remove ${android_proj_target_files} + COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${android_proj_bin_dir}" --target "${android_proj_sdk_target}" --name "${target}" + ${android_proj_lib_deps_commands} + MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}" + DEPENDS "${path}/${ANDROID_MANIFEST_FILE}" + COMMENT "Updating Android project at ${path}. SDK target: ${android_proj_sdk_target}" + ) + + list(APPEND android_proj_file_deps ${android_proj_target_files}) + + # build native part + file(GLOB_RECURSE android_proj_jni_files "${path}/jni/*.c" "${path}/jni/*.h" "${path}/jni/*.cpp" "${path}/jni/*.hpp") + ocv_list_filterout(android_proj_jni_files "\\\\.svn") + + if(android_proj_jni_files AND EXISTS ${path}/jni/Android.mk AND NOT DEFINED JNI_LIB_NAME) + # find local module name in Android.mk file to build native lib + file(STRINGS "${path}/jni/Android.mk" JNI_LIB_NAME REGEX "LOCAL_MODULE[ ]*:=[ ]*.*" ) + string(REGEX REPLACE "LOCAL_MODULE[ ]*:=[ ]*([a-zA-Z_][a-zA-Z_0-9]*)[ ]*" "\\1" JNI_LIB_NAME "${JNI_LIB_NAME}") + + # find using of native app glue to determine native activity + file(STRINGS "${path}/jni/Android.mk" NATIVE_APP_GLUE REGEX ".*(call import-module,android/native_app_glue)" ) + + if(JNI_LIB_NAME) + ocv_include_modules_recurse(${android_proj_NATIVE_DEPS}) + ocv_include_directories("${path}/jni") + + if (NATIVE_APP_GLUE) + include_directories(${ANDROID_NDK}/sources/android/native_app_glue) + list(APPEND android_proj_jni_files ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) + ocv_warnings_disable(CMAKE_C_FLAGS -Wstrict-prototypes -Wunused-parameter -Wmissing-prototypes) + set(android_proj_NATIVE_DEPS ${android_proj_NATIVE_DEPS} android) + endif() + + add_library(${JNI_LIB_NAME} MODULE ${android_proj_jni_files}) + target_link_libraries(${JNI_LIB_NAME} ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS}) + + set_target_properties(${JNI_LIB_NAME} PROPERTIES + OUTPUT_NAME "${JNI_LIB_NAME}" + LIBRARY_OUTPUT_DIRECTORY "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}" + ) + + get_target_property(android_proj_jni_location "${JNI_LIB_NAME}" LOCATION) + if (NOT (CMAKE_BUILD_TYPE MATCHES "debug")) + add_custom_command(TARGET ${JNI_LIB_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${android_proj_jni_location}") + endif() + endif() + endif() + + # build java part + if(android_proj_IGNORE_JAVA) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/bin/${target}-debug.apk" + COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug + COMMAND ${CMAKE_COMMAND} -E touch "${android_proj_bin_dir}/bin/${target}-debug.apk" # needed because ant does not update the timestamp of updated apk + WORKING_DIRECTORY "${android_proj_bin_dir}" + MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}" + DEPENDS ${android_proj_file_deps} ${JNI_LIB_NAME}) + else() + add_custom_command( + OUTPUT "${android_proj_bin_dir}/bin/${target}-debug.apk" + COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug + COMMAND ${CMAKE_COMMAND} -E touch "${android_proj_bin_dir}/bin/${target}-debug.apk" # needed because ant does not update the timestamp of updated apk + WORKING_DIRECTORY "${android_proj_bin_dir}" + MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}" + DEPENDS "${OpenCV_BINARY_DIR}/bin/classes.jar.dephelper" opencv_java # as we are part of OpenCV we can just force this dependency + DEPENDS ${android_proj_file_deps} ${JNI_LIB_NAME}) + endif() + + unset(JNI_LIB_NAME) + + add_custom_target(${target} ALL SOURCES "${android_proj_bin_dir}/bin/${target}-debug.apk" ) + if(NOT android_proj_IGNORE_JAVA) + add_dependencies(${target} opencv_java) + endif() + if(android_proj_native_deps) + add_dependencies(${target} ${android_proj_native_deps}) + endif() + + if(__android_project_chain) + add_dependencies(${target} ${__android_project_chain}) + endif() + set(__android_project_chain ${target} CACHE INTERNAL "auxiliary variable used for Android progects chaining") + + # put the final .apk to the OpenCV's bin folder + add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${android_proj_bin_dir}/bin/${target}-debug.apk" "${OpenCV_BINARY_DIR}/bin/${target}.apk") + if(INSTALL_ANDROID_EXAMPLES AND "${target}" MATCHES "^example-") + #apk + install(FILES "${OpenCV_BINARY_DIR}/bin/${target}.apk" DESTINATION "samples" COMPONENT main) + get_filename_component(sample_dir "${path}" NAME) + #java part + list(REMOVE_ITEM android_proj_files ${ANDROID_MANIFEST_FILE}) + foreach(f ${android_proj_files} ${ANDROID_MANIFEST_FILE}) + get_filename_component(install_subdir "${f}" PATH) + install(FILES "${android_proj_bin_dir}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main) + endforeach() + #jni part + eclipse files + file(GLOB_RECURSE jni_files RELATIVE "${path}" "${path}/jni/*" "${path}/.cproject") + ocv_list_filterout(jni_files "\\\\.svn") + foreach(f ${jni_files} ".classpath" ".project" ".settings/org.eclipse.jdt.core.prefs") + get_filename_component(install_subdir "${f}" PATH) + install(FILES "${path}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main) + endforeach() + #update proj + if(android_proj_lib_deps_commands) + set(inst_lib_opt " --library ../../sdk/java") + endif() + install(CODE "EXECUTE_PROCESS(COMMAND ${ANDROID_EXECUTABLE} --silent update project --path . --target \"${android_proj_sdk_target}\" --name \"${target}\" ${inst_lib_opt} + WORKING_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}\" + )" COMPONENT main) + #empty 'gen' + install(CODE "MAKE_DIRECTORY(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}/gen\")" COMPONENT main) + endif() + endif() +endmacro() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectApacheAnt.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectApacheAnt.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectApacheAnt.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectApacheAnt.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,31 @@ +file(TO_CMAKE_PATH "$ENV{ANT_DIR}" ANT_DIR_ENV_PATH) +file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH) + +if(CMAKE_HOST_WIN32) + set(ANT_NAME ant.bat) +else() + set(ANT_NAME ant) +endif() + +find_host_program(ANT_EXECUTABLE NAMES ${ANT_NAME} + PATHS "${ANT_DIR_ENV_PATH}/bin" "${ProgramFiles_ENV_PATH}/apache-ant/bin" + NO_DEFAULT_PATH + ) + +find_host_program(ANT_EXECUTABLE NAMES ${ANT_NAME}) + +if(ANT_EXECUTABLE) + execute_process(COMMAND ${ANT_EXECUTABLE} -version + RESULT_VARIABLE ANT_ERROR_LEVEL + OUTPUT_VARIABLE ANT_VERSION_FULL + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (ANT_ERROR_LEVEL) + unset(ANT_EXECUTABLE) + unset(ANT_EXECUTABLE CACHE) + else() + string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" ANT_VERSION "${ANT_VERSION_FULL}") + set(ANT_VERSION "${ANT_VERSION}" CACHE INTERNAL "Detected ant vesion") + + message(STATUS "Found apache ant ${ANT_VERSION}: ${ANT_EXECUTABLE}") + endif() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCStripes.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCStripes.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCStripes.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCStripes.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,11 @@ +if(WIN32) + find_path( CSTRIPES_LIB_DIR + NAMES "С=.lib" + DOC "The path to C= lib and dll") + if(CSTRIPES_LIB_DIR) + ocv_include_directories("${CSTRIPES_LIB_DIR}/..") + link_directories("${CSTRIPES_LIB_DIR}") + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} "C=") + set(HAVE_CSTRIPES 1) + endif() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCUDA.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCUDA.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCUDA.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCUDA.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,181 @@ +if(${CMAKE_VERSION} VERSION_LESS "2.8.3") + message(STATUS "WITH_CUDA flag requires CMake 2.8.3 or newer. CUDA support is disabled.") + return() +endif() + +if(WIN32 AND NOT MSVC) + message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).") + return() +endif() + +if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).") + return() +endif() + +find_package(CUDA 4.2 QUIET) + +if(CUDA_FOUND) + set(HAVE_CUDA 1) + + if(WITH_CUFFT) + set(HAVE_CUFFT 1) + endif() + + if(WITH_CUBLAS) + set(HAVE_CUBLAS 1) + endif() + + if(WITH_NVCUVID) + find_cuda_helper_libs(nvcuvid) + set(HAVE_NVCUVID 1) + endif() + + message(STATUS "CUDA detected: " ${CUDA_VERSION}) + + set(_generations "Fermi" "Kepler") + if(NOT CMAKE_CROSSCOMPILING) + list(APPEND _generations "Auto") + endif() + set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures.") + if( CMAKE_VERSION VERSION_GREATER "2.8" ) + set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} ) + endif() + + if(CUDA_GENERATION) + if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};") + string(REPLACE ";" ", " _generations "${_generations}") + message(FATAL_ERROR "ERROR: ${_generations} Generations are suppered.") + endif() + unset(CUDA_ARCH_BIN CACHE) + unset(CUDA_ARCH_PTX CACHE) + endif() + + set(__cuda_arch_ptx "") + if(CUDA_GENERATION STREQUAL "Fermi") + set(__cuda_arch_bin "2.0 2.1(2.0)") + elseif(CUDA_GENERATION STREQUAL "Kepler") + set(__cuda_arch_bin "3.0") + elseif(CUDA_GENERATION STREQUAL "Auto") + execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/" + RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT _nvcc_res EQUAL 0) + message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.") + else() + set(__cuda_arch_bin "${_nvcc_out}") + endif() + endif() + + if(NOT DEFINED __cuda_arch_bin) + set(__cuda_arch_bin "1.1 1.2 1.3 2.0 2.1(2.0) 3.0") + set(__cuda_arch_ptx "2.0 3.0") + endif() + + set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported") + set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for") + + string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}") + string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}") + + # Ckeck if user specified 1.0 compute capability: we don't support it + string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}") + set(CUDA_ARCH_BIN_OR_PTX_10 0) + if(NOT ${HAS_ARCH_10} STREQUAL "") + set(CUDA_ARCH_BIN_OR_PTX_10 1) + endif() + + # NVCC flags to be set + set(NVCC_FLAGS_EXTRA "") + + # These vars will be passed into the templates + set(OPENCV_CUDA_ARCH_BIN "") + set(OPENCV_CUDA_ARCH_PTX "") + set(OPENCV_CUDA_ARCH_FEATURES "") + + # Tell NVCC to add binaries for the specified GPUs + string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_NO_POINTS}") + foreach(ARCH IN LISTS ARCH_LIST) + if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)") + # User explicitly specified PTX for the concrete BIN + set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1}) + set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${CMAKE_MATCH_1}") + set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${CMAKE_MATCH_2}") + else() + # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN + set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH}) + set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${ARCH}") + set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}") + endif() + endforeach() + + # Tell NVCC to add PTX intermediate code for the specified architectures + string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}") + foreach(ARCH IN LISTS ARCH_LIST) + set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH}) + set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}") + set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}") + endforeach() + + if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --target-cpu-architecture=ARM") + endif() + + # These vars will be processed in other scripts + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA}) + set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}") + + message(STATUS "CUDA NVCC target flags: ${CUDA_NVCC_FLAGS}") + + OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF) + + if(CUDA_FAST_MATH) + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math) + endif() + + mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR) + + find_cuda_helper_libs(npp) + + macro(ocv_cuda_compile VAR) + foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + set(${var}_backup_in_cuda_compile_ "${${var}}") + + # we remove /EHa as it generates warnings under windows + string(REPLACE "/EHa" "" ${var} "${${var}}") + + # we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1) + string(REPLACE "-ggdb3" "" ${var} "${${var}}") + + # we remove -Wsign-promo as it generates warnings under linux + string(REPLACE "-Wsign-promo" "" ${var} "${${var}}") + endforeach() + + if(BUILD_SHARED_LIBS) + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS) + endif() + + if(UNIX OR APPLE) + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC) + endif() + if(APPLE) + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only) + endif() + + # disabled because of multiple warnings during building nvcc auto generated files + if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_GCC_REGEX_VERSION VERSION_GREATER "4.6.0") + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-but-set-variable) + endif() + + CUDA_COMPILE(${VAR} ${ARGN}) + + foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + set(${var} "${${var}_backup_in_cuda_compile_}") + unset(${var}_backup_in_cuda_compile_) + endforeach() + endmacro() +else() + unset(CUDA_ARCH_BIN CACHE) + unset(CUDA_ARCH_PTX CACHE) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCXXCompiler.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCXXCompiler.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectCXXCompiler.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectCXXCompiler.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,108 @@ +# ---------------------------------------------------------------------------- +# Detect Microsoft compiler: +# ---------------------------------------------------------------------------- +if(CMAKE_CL_64) + set(MSVC64 1) +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_GNUCXX 1) + set(CMAKE_COMPILER_IS_CLANGCXX 1) +endif() +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_GNUCC 1) + set(CMAKE_COMPILER_IS_CLANGCC 1) +endif() + +if((CMAKE_COMPILER_IS_CLANGCXX OR CMAKE_COMPILER_IS_CLANGCC) AND NOT CMAKE_GENERATOR MATCHES "Xcode") + set(ENABLE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE) +endif() + +# ---------------------------------------------------------------------------- +# Detect Intel ICC compiler -- for -fPIC in 3rdparty ( UNIX ONLY ): +# see include/opencv/cxtypes.h file for related ICC & CV_ICC defines. +# NOTE: The system needs to determine if the '-fPIC' option needs to be added +# for the 3rdparty static libs being compiled. The CMakeLists.txt files +# in 3rdparty use the CV_ICC definition being set here to determine if +# the -fPIC flag should be used. +# ---------------------------------------------------------------------------- +if(UNIX) + if (__ICL) + set(CV_ICC __ICL) + elseif(__ICC) + set(CV_ICC __ICC) + elseif(__ECL) + set(CV_ICC __ECL) + elseif(__ECC) + set(CV_ICC __ECC) + elseif(__INTEL_COMPILER) + set(CV_ICC __INTEL_COMPILER) + elseif(CMAKE_C_COMPILER MATCHES "icc") + set(CV_ICC icc_matches_c_compiler) + endif() +endif() + +if(MSVC AND CMAKE_C_COMPILER MATCHES "icc") + set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS) +endif() + +# ---------------------------------------------------------------------------- +# Detect GNU version: +# ---------------------------------------------------------------------------- +if(CMAKE_COMPILER_IS_CLANGCXX) + set(CMAKE_GCC_REGEX_VERSION "4.2.1") + set(CMAKE_OPENCV_GCC_VERSION_MAJOR 4) + set(CMAKE_OPENCV_GCC_VERSION_MINOR 2) + set(CMAKE_OPENCV_GCC_VERSION 42) + set(CMAKE_OPENCV_GCC_VERSION_NUM 402) + + execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -v + ERROR_VARIABLE CMAKE_OPENCV_CLANG_VERSION_FULL + ERROR_STRIP_TRAILING_WHITESPACE) + + string(REGEX MATCH "version.*$" CMAKE_OPENCV_CLANG_VERSION_FULL "${CMAKE_OPENCV_CLANG_VERSION_FULL}") + string(REGEX MATCH "[0-9]+\\.[0-9]+" CMAKE_CLANG_REGEX_VERSION "${CMAKE_OPENCV_CLANG_VERSION_FULL}") + +elseif(CMAKE_COMPILER_IS_GNUCXX) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpversion + OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -v + ERROR_VARIABLE CMAKE_OPENCV_GCC_INFO_FULL + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # Typical output in CMAKE_OPENCV_GCC_VERSION_FULL: "c+//0 (whatever) 4.2.3 (...)" + # Look for the version number + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}") + if(NOT CMAKE_GCC_REGEX_VERSION) + string(REGEX MATCH "[0-9]+\\.[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}") + endif() + + # Split the three parts: + string(REGEX MATCHALL "[0-9]+" CMAKE_OPENCV_GCC_VERSIONS "${CMAKE_GCC_REGEX_VERSION}") + + list(GET CMAKE_OPENCV_GCC_VERSIONS 0 CMAKE_OPENCV_GCC_VERSION_MAJOR) + list(GET CMAKE_OPENCV_GCC_VERSIONS 1 CMAKE_OPENCV_GCC_VERSION_MINOR) + + set(CMAKE_OPENCV_GCC_VERSION ${CMAKE_OPENCV_GCC_VERSION_MAJOR}${CMAKE_OPENCV_GCC_VERSION_MINOR}) + math(EXPR CMAKE_OPENCV_GCC_VERSION_NUM "${CMAKE_OPENCV_GCC_VERSION_MAJOR}*100 + ${CMAKE_OPENCV_GCC_VERSION_MINOR}") + message(STATUS "Detected version of GNU GCC: ${CMAKE_OPENCV_GCC_VERSION} (${CMAKE_OPENCV_GCC_VERSION_NUM})") + + if(WIN32) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine + OUTPUT_VARIABLE CMAKE_OPENCV_GCC_TARGET_MACHINE + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") + set(MINGW64 1) + endif() + endif() +endif() + +if(MINGW64 OR CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*" OR CMAKE_GENERATOR MATCHES "Visual Studio.*Win64") + set(X86_64 1) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*") + set(X86 1) +elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|ARM.*") + set(ARM 1) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectOpenCL.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectOpenCL.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectOpenCL.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectOpenCL.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,104 @@ +if(APPLE) + set(OPENCL_FOUND YES) + set(OPENCL_LIBRARY "-framework OpenCL" CACHE STRING "OpenCL library") + set(OPENCL_INCLUDE_DIR "" CACHE STRING "OpenCL include directory") + mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY) +else(APPLE) + find_package(OpenCL QUIET) + + if (NOT OPENCL_FOUND) + find_path(OPENCL_ROOT_DIR + NAMES OpenCL/cl.h CL/cl.h include/CL/cl.h include/nvidia-current/CL/cl.h + PATHS ENV OCLROOT ENV AMDAPPSDKROOT ENV CUDA_PATH ENV INTELOCLSDKROOT + DOC "OpenCL root directory" + NO_DEFAULT_PATH) + + find_path(OPENCL_INCLUDE_DIR + NAMES OpenCL/cl.h CL/cl.h + HINTS ${OPENCL_ROOT_DIR} + PATH_SUFFIXES include include/nvidia-current + DOC "OpenCL include directory") + + if (X86_64) + set(OPENCL_POSSIBLE_LIB_SUFFIXES lib/Win64 lib/x86_64 lib/x64) + elseif (X86) + set(OPENCL_POSSIBLE_LIB_SUFFIXES lib/Win32 lib/x86) + endif() + + find_library(OPENCL_LIBRARY + NAMES OpenCL + HINTS ${OPENCL_ROOT_DIR} + PATH_SUFFIXES ${OPENCL_POSSIBLE_LIB_SUFFIXES} + DOC "OpenCL library") + + mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY) + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENCL DEFAULT_MSG OPENCL_LIBRARY OPENCL_INCLUDE_DIR ) + endif() +endif(APPLE) + +if(OPENCL_FOUND) + set(HAVE_OPENCL 1) + set(OPENCL_INCLUDE_DIRS ${OPENCL_INCLUDE_DIR}) + set(OPENCL_LIBRARIES ${OPENCL_LIBRARY}) + + if (X86_64) + set(CLAMD_POSSIBLE_LIB_SUFFIXES lib64/import) + elseif (X86) + set(CLAMD_POSSIBLE_LIB_SUFFIXES lib32/import) + endif() + + if(WITH_OPENCLAMDFFT) + find_path(CLAMDFFT_ROOT_DIR + NAMES include/clAmdFft.h + PATHS ENV CLAMDFFT_PATH ENV ProgramFiles + PATH_SUFFIXES clAmdFft AMD/clAmdFft + DOC "AMD FFT root directory" + NO_DEFAULT_PATH) + + find_path(CLAMDFFT_INCLUDE_DIR + NAMES clAmdFft.h + HINTS ${CLAMDFFT_ROOT_DIR} + PATH_SUFFIXES include + DOC "clAmdFft include directory") + + find_library(CLAMDFFT_LIBRARY + NAMES clAmdFft.Runtime + HINTS ${CLAMDFFT_ROOT_DIR} + PATH_SUFFIXES ${CLAMD_POSSIBLE_LIB_SUFFIXES} + DOC "clAmdFft library") + + if(CLAMDFFT_LIBRARY AND CLAMDFFT_INCLUDE_DIR) + set(HAVE_CLAMDFFT 1) + list(APPEND OPENCL_INCLUDE_DIRS "${CLAMDFFT_INCLUDE_DIR}") + list(APPEND OPENCL_LIBRARIES "${CLAMDFFT_LIBRARY}") + endif() + endif() + + if(WITH_OPENCLAMDBLAS) + find_path(CLAMDBLAS_ROOT_DIR + NAMES include/clAmdBlas.h + PATHS ENV CLAMDFFT_PATH ENV ProgramFiles + PATH_SUFFIXES clAmdBlas AMD/clAmdBlas + DOC "AMD FFT root directory" + NO_DEFAULT_PATH) + + find_path(CLAMDBLAS_INCLUDE_DIR + NAMES clAmdBlas.h + HINTS ${CLAMDBLAS_ROOT_DIR} + PATH_SUFFIXES include + DOC "clAmdFft include directory") + + find_library(CLAMDBLAS_LIBRARY + NAMES clAmdBlas + HINTS ${CLAMDBLAS_ROOT_DIR} + PATH_SUFFIXES ${CLAMD_POSSIBLE_LIB_SUFFIXES} + DOC "clAmdBlas library") + + if(CLAMDBLAS_LIBRARY AND CLAMDBLAS_INCLUDE_DIR) + set(HAVE_CLAMDBLAS 1) + list(APPEND OPENCL_INCLUDE_DIRS "${CLAMDBLAS_INCLUDE_DIR}") + list(APPEND OPENCL_LIBRARIES "${CLAMDBLAS_LIBRARY}") + endif() + endif() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectPython.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectPython.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectPython.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectPython.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,124 @@ +if(WIN32 AND NOT PYTHON_EXECUTABLE) + # search for executable with the same bitness as resulting binaries + # standard FindPythonInterp always prefers executable from system path + # this is really important because we are using the interpreter for numpy search and for choosing the install location + foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) + find_host_program(PYTHON_EXECUTABLE + NAMES python${_CURRENT_VERSION} python + PATHS + [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath] + [HKEY_CURRENT_USER\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath] + NO_SYSTEM_ENVIRONMENT_PATH + ) + endforeach() +endif() +find_host_package(PythonInterp 2.0) + +unset(PYTHON_USE_NUMPY CACHE) +unset(HAVE_SPHINX CACHE) +if(PYTHON_EXECUTABLE) + if(PYTHON_VERSION_STRING) + set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") + set(PYTHON_VERSION_FULL "${PYTHON_VERSION_STRING}") + else() + execute_process(COMMAND ${PYTHON_EXECUTABLE} --version + ERROR_VARIABLE PYTHON_VERSION_FULL + ERROR_STRIP_TRAILING_WHITESPACE) + + string(REGEX MATCH "[0-9]+.[0-9]+" PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_FULL}") + endif() + + if("${PYTHON_VERSION_FULL}" MATCHES "[0-9]+.[0-9]+.[0-9]+") + set(PYTHON_VERSION_FULL "${CMAKE_MATCH_0}") + elseif("${PYTHON_VERSION_FULL}" MATCHES "[0-9]+.[0-9]+") + set(PYTHON_VERSION_FULL "${CMAKE_MATCH_0}") + else() + unset(PYTHON_VERSION_FULL) + endif() + + if(NOT ANDROID AND NOT IOS) + if(CMAKE_VERSION VERSION_GREATER 2.8.8 AND PYTHON_VERSION_FULL) + find_host_package(PythonLibs ${PYTHON_VERSION_FULL} EXACT) + else() + find_host_package(PythonLibs ${PYTHON_VERSION_FULL}) + endif() + # cmake 2.4 (at least on Ubuntu 8.04 (hardy)) don't define PYTHONLIBS_FOUND + if(NOT PYTHONLIBS_FOUND AND PYTHON_INCLUDE_PATH) + set(PYTHONLIBS_FOUND ON) + endif() + endif() + + if(NOT ANDROID AND NOT IOS) + if(CMAKE_HOST_UNIX) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import *; print get_python_lib()" + RESULT_VARIABLE PYTHON_CVPY_PROCESS + OUTPUT_VARIABLE PYTHON_STD_PACKAGES_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + if("${PYTHON_STD_PACKAGES_PATH}" MATCHES "site-packages") + set(_PYTHON_PACKAGES_PATH "python${PYTHON_VERSION_MAJOR_MINOR}/site-packages") + else() #debian based assumed, install to the dist-packages. + set(_PYTHON_PACKAGES_PATH "python${PYTHON_VERSION_MAJOR_MINOR}/dist-packages") + endif() + if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${PYTHON_PACKAGES_PATH}") + set(_PYTHON_PACKAGES_PATH "lib${LIB_SUFFIX}/${_PYTHON_PACKAGES_PATH}") + else() + set(_PYTHON_PACKAGES_PATH "lib/${_PYTHON_PACKAGES_PATH}") + endif() + elseif(CMAKE_HOST_WIN32) + get_filename_component(PYTHON_PATH "${PYTHON_EXECUTABLE}" PATH) + file(TO_CMAKE_PATH "${PYTHON_PATH}" PYTHON_PATH) + if(NOT EXISTS "${PYTHON_PATH}/Lib/site-packages") + unset(PYTHON_PATH) + get_filename_component(PYTHON_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE) + if(NOT PYTHON_PATH) + get_filename_component(PYTHON_PATH "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE) + endif() + file(TO_CMAKE_PATH "${PYTHON_PATH}" PYTHON_PATH) + endif() + set(_PYTHON_PACKAGES_PATH "${PYTHON_PATH}/Lib/site-packages") + endif() + SET(PYTHON_PACKAGES_PATH "${_PYTHON_PACKAGES_PATH}" CACHE PATH "Where to install the python packages.") + + if(NOT PYTHON_NUMPY_INCLUDE_DIR) + # Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print numpy.distutils.misc_util.get_numpy_include_dirs()[0]" + RESULT_VARIABLE PYTHON_NUMPY_PROCESS + OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(PYTHON_NUMPY_PROCESS EQUAL 0) + file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIR}" _PYTHON_NUMPY_INCLUDE_DIR) + set(PYTHON_NUMPY_INCLUDE_DIR ${_PYTHON_NUMPY_INCLUDE_DIR} CACHE PATH "Path to numpy headers") + endif() + endif() + + if(PYTHON_NUMPY_INCLUDE_DIR) + set(PYTHON_USE_NUMPY TRUE) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print numpy.version.version" + RESULT_VARIABLE PYTHON_NUMPY_PROCESS + OUTPUT_VARIABLE PYTHON_NUMPY_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + endif(NOT ANDROID AND NOT IOS) + + if(BUILD_DOCS) + find_host_program(SPHINX_BUILD sphinx-build) + if(SPHINX_BUILD) + if(UNIX) + execute_process(COMMAND sh -c "${SPHINX_BUILD} -_ 2>&1 | sed -ne 1p" + RESULT_VARIABLE SPHINX_PROCESS + OUTPUT_VARIABLE SPHINX_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import sphinx; print sphinx.__version__" + RESULT_VARIABLE SPHINX_PROCESS + OUTPUT_VARIABLE SPHINX_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + if(SPHINX_PROCESS EQUAL 0) + set(HAVE_SPHINX 1) + message(STATUS "Found Sphinx ${SPHINX_VERSION}: ${SPHINX_BUILD}") + endif() + endif() + endif(BUILD_DOCS) +endif(PYTHON_EXECUTABLE) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectTBB.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectTBB.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVDetectTBB.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVDetectTBB.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,90 @@ +if(BUILD_TBB) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/tbb") + include_directories(SYSTEM ${TBB_INCLUDE_DIRS}) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) + add_definitions(-DTBB_USE_GCC_BUILTINS=1 -D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1) + if(tbb_need_GENERIC_DWORD_LOAD_STORE) + add_definitions(-D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1) + endif() + set(HAVE_TBB 1) +elseif(UNIX AND NOT APPLE) + PKG_CHECK_MODULES(TBB tbb) + + if(TBB_FOUND) + set(HAVE_TBB 1) + if(NOT ${TBB_INCLUDE_DIRS} STREQUAL "") + ocv_include_directories(${TBB_INCLUDE_DIRS}) + endif() + link_directories(${TBB_LIBRARY_DIRS}) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${TBB_LIBRARIES}) + endif() +endif() + +if(NOT HAVE_TBB) + set(TBB_DEFAULT_INCLUDE_DIRS + "/opt/intel/tbb/include" "/usr/local/include" "/usr/include" + "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB" + "C:/Program Files (x86)/tbb/include" + "C:/Program Files (x86)/tbb/include" + "${CMAKE_INSTALL_PREFIX}/include") + + find_path(TBB_INCLUDE_DIRS "tbb/tbb.h" PATHS ${TBB_INCLUDE_DIR} ${TBB_DEFAULT_INCLUDE_DIRS} DOC "The path to TBB headers") + if(TBB_INCLUDE_DIRS) + if(UNIX) + set(TBB_LIB_DIR "${TBB_INCLUDE_DIRS}/../lib" CACHE PATH "Full path of TBB library directory") + link_directories("${TBB_LIB_DIR}") + endif() + if(APPLE) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libtbb.dylib) + elseif(ANDROID) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) + add_definitions(-DTBB_USE_GCC_BUILTINS) + elseif (UNIX) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) + elseif (WIN32) + if(CMAKE_COMPILER_IS_GNUCXX) + set(TBB_LIB_DIR "${TBB_INCLUDE_DIRS}/../lib" CACHE PATH "Full path of TBB library directory") + link_directories("${TBB_LIB_DIR}") + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) + else() + get_filename_component(_TBB_LIB_PATH "${TBB_INCLUDE_DIRS}/../lib" ABSOLUTE) + + if(CMAKE_SYSTEM_PROCESSOR MATCHES amd64*|x86_64* OR MSVC64) + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/intel64") + else() + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/ia32") + endif() + + if(MSVC80) + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/vc8") + elseif(MSVC90) + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/vc9") + elseif(MSVC10) + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/vc10") + elseif(MSVC11) + set(_TBB_LIB_PATH "${_TBB_LIB_PATH}/vc11") + endif() + set(TBB_LIB_DIR "${_TBB_LIB_PATH}" CACHE PATH "Full path of TBB library directory") + link_directories("${TBB_LIB_DIR}") + endif() + endif() + + set(HAVE_TBB 1) + if(NOT "${TBB_INCLUDE_DIRS}" STREQUAL "") + ocv_include_directories("${TBB_INCLUDE_DIRS}") + endif() + endif(TBB_INCLUDE_DIRS) +endif(NOT HAVE_TBB) + +# get TBB version +if(HAVE_TBB) + find_file(TBB_STDDEF_PATH tbb/tbb_stddef.h "${TBB_INCLUDE_DIRS}") + mark_as_advanced(TBB _STDDEF_PATH) +endif() +if(HAVE_TBB AND TBB_STDDEF_PATH) + ocv_parse_header("${TBB_STDDEF_PATH}" TBB_VERSION_LINES TBB_VERSION_MAJOR TBB_VERSION_MINOR TBB_INTERFACE_VERSION) +else() + unset(TBB_VERSION_MAJOR) + unset(TBB_VERSION_MINOR) + unset(TBB_INTERFACE_VERSION) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVExtraTargets.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVExtraTargets.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVExtraTargets.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVExtraTargets.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,38 @@ +# ---------------------------------------------------------------------------- +# Uninstall target, for "make uninstall" +# ---------------------------------------------------------------------------- +CONFIGURE_FILE( + "${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets") +endif() + + +# ---------------------------------------------------------------------------- +# target building all OpenCV modules +# ---------------------------------------------------------------------------- +add_custom_target(opencv_modules) +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(opencv_modules PROPERTIES FOLDER "extra") +endif() + + +# ---------------------------------------------------------------------------- +# targets building all tests +# ---------------------------------------------------------------------------- +if(BUILD_TESTS) + add_custom_target(opencv_tests) + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(opencv_tests PROPERTIES FOLDER "extra") + endif() +endif() +if(BUILD_PERF_TESTS) + add_custom_target(opencv_perf_tests) + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(opencv_perf_tests PROPERTIES FOLDER "extra") + endif() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindIPP.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindIPP.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindIPP.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindIPP.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,339 @@ +# +# The script to detect Intel(R) Integrated Performance Primitives (IPP) +# installation/package +# +# This will try to find Intel IPP libraries, and include path by automatic +# search through typical install locations and if failed it will +# examine IPPROOT environment variable. +# Note, IPPROOT is not set by IPP installer, it should be set manually. +# +# On return this will define: +# +# IPP_FOUND - True if Intel IPP found +# IPP_ROOT_DIR - root of IPP installation +# IPP_INCLUDE_DIRS - IPP include folder +# IPP_LIBRARY_DIRS - IPP libraries folder +# IPP_LIBRARIES - IPP libraries names that are used by OpenCV +# IPP_LATEST_VERSION_STR - string with the newest detected IPP version +# IPP_LATEST_VERSION_MAJOR - numbers of IPP version (MAJOR.MINOR.BUILD) +# IPP_LATEST_VERSION_MINOR +# IPP_LATEST_VERSION_BUILD +# +# Created: 30 Dec 2010 by Vladimir Dudnik (vladimir.dudnik@intel.com) +# + +set(IPP_FOUND) +set(IPP_VERSION_STR "5.3.0.0") # will not detect earlier versions +set(IPP_VERSION_MAJOR 0) +set(IPP_VERSION_MINOR 0) +set(IPP_VERSION_BUILD 0) +set(IPP_ROOT_DIR) +set(IPP_INCLUDE_DIRS) +set(IPP_LIBRARY_DIRS) +set(IPP_LIBRARIES) +set(IPP_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) +set(IPP_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) +set(IPP_PREFIX "ipp") +set(IPP_SUFFIX "_l") +set(IPPCORE "core") # core functionality +set(IPPS "s") # signal processing +set(IPPI "i") # image processing +set(IPPCC "cc") # color conversion +set(IPPCV "cv") # computer vision +set(IPPVM "vm") # vector math + + +set(IPP_X64 0) +if (CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) + set(IPP_X64 1) +endif() +if (CMAKE_CL_64) + set(IPP_X64 1) +endif() + +# ------------------------------------------------------------------------ +# This function detect IPP version by analyzing ippversion.h file +# Note, ippversion.h file was inroduced since IPP 5.3 +# ------------------------------------------------------------------------ +function(get_ipp_version _ROOT_DIR) + set(_VERSION_STR) + set(_MAJOR) + set(_MINOR) + set(_BUILD) + + # read IPP version info from file + file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR1 REGEX "IPP_VERSION_MAJOR") + file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR2 REGEX "IPP_VERSION_MINOR") + file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR3 REGEX "IPP_VERSION_BUILD") + if("${STR3}" STREQUAL "") + file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR3 REGEX "IPP_VERSION_UPDATE") + endif() + file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR4 REGEX "IPP_VERSION_STR") + + # extract info and assign to variables + string(REGEX MATCHALL "[0-9]+" _MAJOR ${STR1}) + string(REGEX MATCHALL "[0-9]+" _MINOR ${STR2}) + string(REGEX MATCHALL "[0-9]+" _BUILD ${STR3}) + string(REGEX MATCHALL "[0-9]+[.]+[0-9]+[^\"]+|[0-9]+[.]+[0-9]+" _VERSION_STR ${STR4}) + + # export info to parent scope + set(IPP_VERSION_STR ${_VERSION_STR} PARENT_SCOPE) + set(IPP_VERSION_MAJOR ${_MAJOR} PARENT_SCOPE) + set(IPP_VERSION_MINOR ${_MINOR} PARENT_SCOPE) + set(IPP_VERSION_BUILD ${_BUILD} PARENT_SCOPE) + + message(STATUS "found IPP: ${_MAJOR}.${_MINOR}.${_BUILD} [${_VERSION_STR}]") + message(STATUS "at: ${_ROOT_DIR}") + + return() + +endfunction() + + +# ------------------------------------------------------------------------ +# This is auxiliary function called from set_ipp_variables() +# to set IPP_LIBRARIES variable in IPP 6.x style (IPP 5.3 should also work) +# ------------------------------------------------------------------------ +function(set_ipp_old_libraries) + set(IPP_PREFIX "ipp") + set(IPP_SUFFIX) # old style static core libs suffix + set(IPP_ARCH) # architecture suffix + set(IPP_DISP "emerged") # old style dipatcher and cpu-specific + set(IPP_MRGD "merged") # static libraries + set(IPPCORE "core") # core functionality + set(IPPSP "s") # signal processing + set(IPPIP "i") # image processing + set(IPPCC "cc") # color conversion + set(IPPCV "cv") # computer vision + set(IPPVM "vm") # vector math + + if (IPP_X64) + set(IPP_ARCH "em64t") + endif() + + if(WIN32) + set(IPP_SUFFIX "l") + endif() + + set(IPP_LIBRARIES + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPVM}${IPP_MRGD}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPVM}${IPP_DISP}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCC}${IPP_MRGD}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCC}${IPP_DISP}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCV}${IPP_MRGD}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCV}${IPP_DISP}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPIP}${IPP_MRGD}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPIP}${IPP_DISP}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPSP}${IPP_MRGD}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPSP}${IPP_DISP}${IPP_ARCH}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCORE}${IPP_ARCH}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + PARENT_SCOPE) + + return() + +endfunction() + + +# ------------------------------------------------------------------------ +# This is auxiliary function called from set_ipp_variables() +# to set IPP_LIBRARIES variable in IPP 7.x style +# ------------------------------------------------------------------------ +function(set_ipp_new_libraries) + set(IPP_PREFIX "ipp") + set(IPP_SUFFIX "_l") # static not threaded libs suffix + set(IPP_THRD "_t") # static threaded libs suffix + set(IPPCORE "core") # core functionality + set(IPPSP "s") # signal processing + set(IPPIP "i") # image processing + set(IPPCC "cc") # color conversion + set(IPPCV "cv") # computer vision + set(IPPVM "vm") # vector math + + set(IPP_LIBRARIES + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPVM}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCC}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCV}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPI}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPS}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCORE}${IPP_SUFFIX}${IPP_LIB_SUFFIX} + PARENT_SCOPE) + + return() + +endfunction() + + +# ------------------------------------------------------------------------ +# This function will set +# IPP_INCLUDE_DIRS, IPP_LIBRARY_DIRS and IPP_LIBRARIES variables depending +# on IPP version parameter. +# Since IPP 7.0 version library names and install folder structure +# was changed +# ------------------------------------------------------------------------ +function(set_ipp_variables _LATEST_VERSION) + if(${_LATEST_VERSION} VERSION_LESS "7.0") +# message(STATUS "old") + + # set INCLUDE and LIB folders + set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include PARENT_SCOPE) + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib PARENT_SCOPE) + + if (IPP_X64) + if(NOT EXISTS ${IPP_ROOT_DIR}/../em64t) + message(SEND_ERROR "IPP EM64T libraries not found") + endif() + else() + if(NOT EXISTS ${IPP_ROOT_DIR}/../ia32) + message(SEND_ERROR "IPP IA32 libraries not found") + endif() + endif() + + # set IPP_LIBRARIES variable (6.x lib names) + set_ipp_old_libraries() + set(IPP_LIBRARIES ${IPP_LIBRARIES} PARENT_SCOPE) + message(STATUS "IPP libs: ${IPP_LIBRARIES}") + + else() +# message(STATUS "new") + + # set INCLUDE and LIB folders + set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include PARENT_SCOPE) + + if (IPP_X64) + if(NOT EXISTS ${IPP_ROOT_DIR}/lib/intel64) + message(SEND_ERROR "IPP EM64T libraries not found") + endif() + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/intel64 PARENT_SCOPE) + else() + if(NOT EXISTS ${IPP_ROOT_DIR}/lib/ia32) + message(SEND_ERROR "IPP IA32 libraries not found") + endif() + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/ia32 PARENT_SCOPE) + endif() + + # set IPP_LIBRARIES variable (7.x lib names) + set_ipp_new_libraries() + set(IPP_LIBRARIES ${IPP_LIBRARIES} PARENT_SCOPE) + message(STATUS "IPP libs: ${IPP_LIBRARIES}") + + endif() + + return() + +endfunction() + + +# ------------------------------------------------------------------------ +# This section will look for IPP through IPPROOT env variable +# Note, IPPROOT is not set by IPP installer, you may need to set it manually +# ------------------------------------------------------------------------ +find_path( + IPP_H_PATH + NAMES ippversion.h + PATHS $ENV{IPPROOT} + PATH_SUFFIXES include + DOC "The path to Intel(R) IPP header files" + NO_DEFAULT_PATH + NO_CMAKE_PATH) + +if(IPP_H_PATH) + set(IPP_FOUND 1) + + # traverse up to IPPROOT level + get_filename_component(IPP_ROOT_DIR ${IPP_H_PATH} PATH) + + # extract IPP version info + get_ipp_version(${IPP_ROOT_DIR}) + + # keep info in the same vars for auto search and search by IPPROOT + set(IPP_LATEST_VERSION_STR ${IPP_VERSION_STR}) + set(IPP_LATEST_VERSION_MAJOR ${IPP_VERSION_MAJOR}) + set(IPP_LATEST_VERSION_MINOR ${IPP_VERSION_MINOR}) + set(IPP_LATEST_VERSION_BUILD ${IPP_VERSION_BUILD}) + + # set IPP INCLUDE, LIB dirs and library names + set_ipp_variables(${IPP_LATEST_VERSION_STR}) +endif() + + +if(NOT IPP_FOUND) + # reset var from previous search + set(IPP_H_PATH) + + + # ------------------------------------------------------------------------ + # This section will look for IPP through system program folders + # Note, if several IPP installations found the newest version will be + # selected + # ------------------------------------------------------------------------ + foreach(curdir ${CMAKE_SYSTEM_PREFIX_PATH}) + set(curdir ${curdir}/intel) + file(TO_CMAKE_PATH ${curdir} CURDIR) + + if(EXISTS ${curdir}) + file(GLOB_RECURSE IPP_H_DIR ${curdir}/ippversion.h) + + if(IPP_H_DIR) + set(IPP_FOUND 1) + endif() + + # init IPP_LATEST_VERSION version with oldest detectable version (5.3.0.0) + # IPP prior 5.3 did not have ippversion.h file + set(IPP_LATEST_VERSION_STR ${IPP_VERSION_STR}) + + # look through all dirs where ippversion.h was found + foreach(item ${IPP_H_DIR}) + + # traverse up to IPPROOT level + get_filename_component(_FILE_PATH ${item} PATH) + get_filename_component(_ROOT_DIR ${_FILE_PATH} PATH) + + # extract IPP version info + get_ipp_version(${_ROOT_DIR}) + + # remember the latest version (if many found) + if(${IPP_LATEST_VERSION_STR} VERSION_LESS ${IPP_VERSION_STR}) + set(IPP_LATEST_VERSION_STR ${IPP_VERSION_STR}) + set(IPP_LATEST_VERSION_MAJOR ${IPP_VERSION_MAJOR}) + set(IPP_LATEST_VERSION_MINOR ${IPP_VERSION_MINOR}) + set(IPP_LATEST_VERSION_BUILD ${IPP_VERSION_BUILD}) + set(IPP_ROOT_DIR ${_ROOT_DIR}) + endif() + endforeach() + endif() + endforeach() +endif() + +if(IPP_FOUND) + # set IPP INCLUDE, LIB dirs and library names + set_ipp_variables(${IPP_LATEST_VERSION_STR}) + + # set CACHE variable IPP_H_PATH, + # path to IPP header files for the latest version + find_path( + IPP_H_PATH + NAMES ippversion.h + PATHS ${IPP_ROOT_DIR} + PATH_SUFFIXES include + DOC "The path to Intel(R) IPP header files" + NO_DEFAULT_PATH + NO_CMAKE_PATH) +endif() + +if(WIN32 AND MINGW AND NOT IPP_LATEST_VERSION_MAJOR LESS 7) + # Since IPP built with Microsoft compiler and /GS option + # ====================================================== + # From Windows SDK 7.1 + # (usually in "C:\Program Files\Microsoft Visual Studio 10.0\VC\lib"), + # to avoid undefined reference to __security_cookie and _chkstk: + set(MSV_RUNTMCHK "RunTmChk") + set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_RUNTMCHK}${IPP_LIB_SUFFIX}) + + # To avoid undefined reference to _alldiv and _chkstk + # =================================================== + # NB: it may require a recompilation of w32api (after having modified + # the file ntdll.def) to export the required functions + # See http://code.opencv.org/issues/1906 for additional details + set(MSV_NTDLL "ntdll") + set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_NTDLL}${IPP_LIB_SUFFIX}) +endif() \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLATEX.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLATEX.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLATEX.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLATEX.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,114 @@ +# - Find Latex +# This module finds if Latex is installed and determines where the +# executables are. This code sets the following variables: +# +# LATEX_COMPILER: path to the LaTeX compiler +# PDFLATEX_COMPILER: path to the PdfLaTeX compiler +# BIBTEX_COMPILER: path to the BibTeX compiler +# MAKEINDEX_COMPILER: path to the MakeIndex compiler +# DVIPS_CONVERTER: path to the DVIPS converter +# PS2PDF_CONVERTER: path to the PS2PDF converter +# LATEX2HTML_CONVERTER: path to the LaTeX2Html converter +# + +IF (WIN32) + + # Try to find the MikTex binary path (look for its package manager). + + FIND_PATH(MIKTEX_BINARY_PATH mpm.exe + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MiK\\MiKTeX\\CurrentVersion\\MiKTeX;Install Root]/miktex/bin" + DOC + "Path to the MikTex binary directory." + ) + MARK_AS_ADVANCED(MIKTEX_BINARY_PATH) + + # Try to find the GhostScript binary path (look for gswin32). + + GET_FILENAME_COMPONENT(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00 + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\8.00;GS_DLL]" PATH + ) + + GET_FILENAME_COMPONENT(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04 + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\7.04;GS_DLL]" PATH + ) + + FIND_PATH(GHOSTSCRIPT_BINARY_PATH gswin32.exe + ${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00} + ${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04} + DOC "Path to the GhostScript binary directory." + ) + MARK_AS_ADVANCED(GHOSTSCRIPT_BINARY_PATH) + + FIND_PATH(GHOSTSCRIPT_LIBRARY_PATH ps2pdf13.bat + "${GHOSTSCRIPT_BINARY_PATH}/../lib" + DOC "Path to the GhostScript library directory." + ) + MARK_AS_ADVANCED(GHOSTSCRIPT_LIBRARY_PATH) + +ENDIF (WIN32) + +FIND_HOST_PROGRAM(LATEX_COMPILER + NAMES latex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +FIND_HOST_PROGRAM(PDFLATEX_COMPILER + NAMES pdflatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +FIND_HOST_PROGRAM(BIBTEX_COMPILER + NAMES bibtex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +FIND_HOST_PROGRAM(MAKEINDEX_COMPILER + NAMES makeindex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +FIND_HOST_PROGRAM(DVIPS_CONVERTER + NAMES dvips + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +FIND_HOST_PROGRAM(DVIPDF_CONVERTER + NAMES dvipdfm dvipdft dvipdf + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + +IF (WIN32) + FIND_HOST_PROGRAM(PS2PDF_CONVERTER + NAMES ps2pdf14.bat + PATHS ${GHOSTSCRIPT_LIBRARY_PATH} + ) +ELSE (WIN32) + FIND_HOST_PROGRAM(PS2PDF_CONVERTER + NAMES ps2pdf14 ps2pdf + PATHS /usr/bin /usr/texbin + ) +ENDIF (WIN32) + +FIND_HOST_PROGRAM(LATEX2HTML_CONVERTER + NAMES latex2html + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin /usr/texbin +) + + +MARK_AS_ADVANCED( + LATEX_COMPILER + PDFLATEX_COMPILER + BIBTEX_COMPILER + MAKEINDEX_COMPILER + DVIPS_CONVERTER + DVIPDF_CONVERTER + PS2PDF_CONVERTER + LATEX2HTML_CONVERTER +) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsGUI.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsGUI.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsGUI.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsGUI.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,51 @@ +# ---------------------------------------------------------------------------- +# Detect 3rd-party GUI libraries +# ---------------------------------------------------------------------------- + +#--- Win32 UI --- +ocv_clear_vars(HAVE_WIN32UI) +if(WITH_WIN32UI) + TRY_COMPILE(HAVE_WIN32UI + "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp" + "${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp" + CMAKE_FLAGS "\"user32.lib\" \"gdi32.lib\"" + OUTPUT_VARIABLE OUTPUT) +endif(WITH_WIN32UI) + +# --- QT4 --- +ocv_clear_vars(HAVE_QT) +if(WITH_QT) + find_package(Qt4) + if(QT4_FOUND) + set(HAVE_QT TRUE) + add_definitions(-DHAVE_QT) # We need to define the macro this way, using cvconfig.h does not work + endif() +endif() + +# --- GTK --- +ocv_clear_vars(HAVE_GTK HAVE_GTHREAD HAVE_GTKGLEXT) +if(WITH_GTK AND NOT HAVE_QT) + CHECK_MODULE(gtk+-2.0 HAVE_GTK) + CHECK_MODULE(gthread-2.0 HAVE_GTHREAD) + if(WITH_OPENGL) + CHECK_MODULE(gtkglext-1.0 HAVE_GTKGLEXT) + endif() +endif() + +# --- OpenGl --- +ocv_clear_vars(HAVE_OPENGL HAVE_QT_OPENGL) +if(WITH_OPENGL) + if(WITH_WIN32UI OR (HAVE_QT AND QT_QTOPENGL_FOUND) OR HAVE_GTKGLEXT) + find_package (OpenGL QUIET) + if(OPENGL_FOUND) + set(HAVE_OPENGL TRUE) + list(APPEND OPENCV_LINKER_LIBS ${OPENGL_LIBRARIES}) + if(QT_QTOPENGL_FOUND) + set(HAVE_QT_OPENGL TRUE) + add_definitions(-DHAVE_QT_OPENGL) + else() + ocv_include_directories(${OPENGL_INCLUDE_DIR}) + endif() + endif() + endif() +endif(WITH_OPENGL) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsGrfmt.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsGrfmt.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsGrfmt.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsGrfmt.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,164 @@ +# ---------------------------------------------------------------------------- +# Detect 3rd-party image IO libraries +# ---------------------------------------------------------------------------- + +# --- zlib (required) --- +if(BUILD_ZLIB) + ocv_clear_vars(ZLIB_FOUND) +else() + include(FindZLIB) + if(ZLIB_FOUND AND ANDROID) + if(ZLIB_LIBRARY STREQUAL "${ANDROID_SYSROOT}/usr/lib/libz.so") + set(ZLIB_LIBRARY z) + set(ZLIB_LIBRARIES z) + endif() + endif() +endif() + +if(NOT ZLIB_FOUND) + ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIR) + + set(ZLIB_LIBRARY zlib) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/zlib") + set(ZLIB_INCLUDE_DIR "${${ZLIB_LIBRARY}_SOURCE_DIR}" "${${ZLIB_LIBRARY}_BINARY_DIR}") + + ocv_parse_header2(ZLIB "${${ZLIB_LIBRARY}_SOURCE_DIR}/zlib.h" ZLIB_VERSION) +endif() + +# --- libtiff (optional, should be searched after zlib) --- +if(WITH_TIFF) + if(BUILD_TIFF) + ocv_clear_vars(TIFF_FOUND) + else() + include(FindTIFF) + if(TIFF_FOUND) + ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION) + endif() + endif() +endif() + +if(WITH_TIFF AND NOT TIFF_FOUND) + ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR) + + set(TIFF_LIBRARY libtiff) + set(TIFF_LIBRARIES ${TIFF_LIBRARY}) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff") + set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}") + ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION) +endif() + +if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION) + set(TIFF_VERSION ${TIFF_VERSION_CLASSIC}) +endif() + +if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG) + set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION}) +endif() + +if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR) + list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR) + if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h") + file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*") + string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}") + unset(tiff_version_str) + endif() + unset(_TIFF_INCLUDE_DIR) +endif() + +# --- libjpeg (optional) --- +if(WITH_JPEG AND NOT IOS) + if(BUILD_JPEG) + ocv_clear_vars(JPEG_FOUND) + else() + include(FindJPEG) + endif() +endif() + +if(WITH_JPEG AND NOT JPEG_FOUND) + ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR) + + set(JPEG_LIBRARY libjpeg) + set(JPEG_LIBRARIES ${JPEG_LIBRARY}) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg") + set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}") +endif() + +ocv_parse_header("${JPEG_INCLUDE_DIR}/jpeglib.h" JPEG_VERSION_LINES JPEG_LIB_VERSION) + + +# --- libjasper (optional, should be searched after libjpeg) --- +if(WITH_JASPER) + if(BUILD_JASPER) + ocv_clear_vars(JASPER_FOUND) + else() + include(FindJasper) + endif() +endif() + +if(WITH_JASPER AND NOT JASPER_FOUND) + ocv_clear_vars(JASPER_LIBRARY JASPER_LIBRARIES JASPER_INCLUDE_DIR) + + set(JASPER_LIBRARY libjasper) + set(JASPER_LIBRARIES ${JASPER_LIBRARY}) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjasper") + set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}") +endif() + +if(NOT JASPER_VERSION_STRING) + ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "") +endif() + +# --- libpng (optional, should be searched after zlib) --- +if(WITH_PNG AND NOT IOS) + if(BUILD_PNG) + ocv_clear_vars(PNG_FOUND) + else() + include(FindPNG) + if(PNG_FOUND) + include(CheckIncludeFile) + check_include_file("${PNG_PNG_INCLUDE_DIR}/png.h" HAVE_PNG_H) + check_include_file("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" HAVE_LIBPNG_PNG_H) + if(HAVE_PNG_H) + ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE) + elseif(HAVE_LIBPNG_PNG_H) + ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE) + endif() + endif() + endif() +endif() + +if(WITH_PNG AND NOT PNG_FOUND) + ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_PNG_INCLUDE_DIR HAVE_PNG_H HAVE_LIBPNG_PNG_H PNG_DEFINITIONS) + + set(PNG_LIBRARY libpng) + set(PNG_LIBRARIES ${PNG_LIBRARY}) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libpng") + set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}") + set(PNG_DEFINITIONS "") + ocv_parse_header("${PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE) +endif() + +set(PNG_VERSION "${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}") + +# --- OpenEXR (optional) --- +if(WITH_OPENEXR) + if(BUILD_OPENEXR) + ocv_clear_vars(OPENEXR_FOUND) + else() + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenEXR.cmake") + endif() +endif() + +if(WITH_OPENEXR AND NOT OPENEXR_FOUND) + ocv_clear_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION) + + set(OPENEXR_LIBRARIES IlmImf) + set(OPENEXR_ILMIMF_LIBRARY IlmImf) + add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/openexr") +endif() + +#cmake 2.8.2 bug - it fails to determine zlib version +if(ZLIB_FOUND) + ocv_parse_header2(ZLIB "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_VERSION) +endif() \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsPerf.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsPerf.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsPerf.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsPerf.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,74 @@ +# ---------------------------------------------------------------------------- +# Detect other 3rd-party performance and math libraries +# ---------------------------------------------------------------------------- + +# --- TBB --- +if(WITH_TBB) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectTBB.cmake") +endif(WITH_TBB) + +# --- IPP --- +ocv_clear_vars(IPP_FOUND) +if(WITH_IPP) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPP.cmake") + if(IPP_FOUND) + add_definitions(-DHAVE_IPP) + ocv_include_directories(${IPP_INCLUDE_DIRS}) + link_directories(${IPP_LIBRARY_DIRS}) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${IPP_LIBRARIES}) + endif() +endif(WITH_IPP) + +# --- CUDA --- +if(WITH_CUDA) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCUDA.cmake") +endif(WITH_CUDA) + +# --- Eigen --- +if(WITH_EIGEN) + find_path(EIGEN_INCLUDE_PATH "Eigen/Core" + PATHS /usr/local /opt /usr ENV ProgramFiles ENV ProgramW6432 + PATH_SUFFIXES include/eigen3 include/eigen2 Eigen/include/eigen3 Eigen/include/eigen2 + DOC "The path to Eigen3/Eigen2 headers" + CMAKE_FIND_ROOT_PATH_BOTH) + + if(EIGEN_INCLUDE_PATH) + ocv_include_directories(${EIGEN_INCLUDE_PATH}) + ocv_parse_header("${EIGEN_INCLUDE_PATH}/Eigen/src/Core/util/Macros.h" EIGEN_VERSION_LINES EIGEN_WORLD_VERSION EIGEN_MAJOR_VERSION EIGEN_MINOR_VERSION) + set(HAVE_EIGEN 1) + endif() +endif(WITH_EIGEN) + +# --- C= --- +if(WITH_CSTRIPES AND NOT HAVE_TBB) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCStripes.cmake") +else() + set(HAVE_CSTRIPES 0) +endif() + +# --- OpenMP --- +if(NOT HAVE_TBB AND NOT HAVE_CSTRIPES) + set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/omptest.cpp") + file(WRITE "${_fname}" "#ifndef _OPENMP\n#error\n#endif\nint main() { return 0; }\n") + try_compile(HAVE_OPENMP "${CMAKE_BINARY_DIR}" "${_fname}") + file(REMOVE "${_fname}") +else() + set(HAVE_OPENMP 0) +endif() + +# --- GCD --- +if(APPLE AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP) + set(HAVE_GCD 1) +else() + set(HAVE_GCD 0) +endif() + +# --- Concurrency --- +if(MSVC AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP) + set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concurrencytest.cpp") + file(WRITE "${_fname}" "#if _MSC_VER < 1600\n#error\n#endif\nint main() { return 0; }\n") + try_compile(HAVE_CONCURRENCY "${CMAKE_BINARY_DIR}" "${_fname}") + file(REMOVE "${_fname}") +else() + set(HAVE_CONCURRENCY 0) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsVideo.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsVideo.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindLibsVideo.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindLibsVideo.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,207 @@ +# ---------------------------------------------------------------------------- +# Detect 3rd-party video IO libraries +# ---------------------------------------------------------------------------- + +ocv_clear_vars(HAVE_VFW) +if (WITH_VFW) + TRY_COMPILE(HAVE_VFW + "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp" + "${OpenCV_SOURCE_DIR}/cmake/checks/vfwtest.cpp" + CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=vfw32" + OUTPUT_VARIABLE OUTPUT) + endif(WITH_VFW) + +# --- GStreamer --- +ocv_clear_vars(HAVE_GSTREAMER) +if(WITH_GSTREAMER) + CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER) + if(HAVE_GSTREAMER) + CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER) + endif() + if(HAVE_GSTREAMER) + CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER) + endif() +endif(WITH_GSTREAMER) + +# --- unicap --- +ocv_clear_vars(HAVE_UNICAP) +if(WITH_UNICAP) + CHECK_MODULE(libunicap HAVE_UNICAP_) + CHECK_MODULE(libucil HAVE_UNICAP_UCIL) + if(HAVE_UNICAP_ AND HAVE_UNICAP_UCIL) + set(HAVE_UNICAP TRUE) + endif() +endif(WITH_UNICAP) + +# --- PvApi --- +ocv_clear_vars(HAVE_PVAPI) +if(WITH_PVAPI) + find_path(PVAPI_INCLUDE_PATH "PvApi.h" + PATHS /usr/local /opt /usr ENV ProgramFiles ENV ProgramW6432 + PATH_SUFFIXES include "Allied Vision Technologies/GigESDK/inc-pc" "AVT GigE SDK/inc-pc" "GigESDK/inc-pc" + DOC "The path to PvAPI header") + + if(PVAPI_INCLUDE_PATH) + if(X86 AND NOT WIN32) + set(PVAPI_SDK_SUBDIR x86) + elseif(X86_64) + set(PVAPI_SDK_SUBDIR x64) + elseif(ARM) + set(PVAPI_SDK_SUBDIR arm) + endif() + + get_filename_component(_PVAPI_LIBRARY "${PVAPI_INCLUDE_PATH}/../lib-pc" ABSOLUTE) + if(PVAPI_SDK_SUBDIR) + set(_PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${PVAPI_SDK_SUBDIR}") + endif() + if(NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX) + set(_PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${CMAKE_OPENCV_GCC_VERSION_MAJOR}.${CMAKE_OPENCV_GCC_VERSION_MINOR}") + endif() + + set(PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${CMAKE_STATIC_LIBRARY_PREFIX}PvAPI${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE PATH "The PvAPI library") + if(EXISTS "${PVAPI_LIBRARY}") + set(HAVE_PVAPI TRUE) + endif() + endif(PVAPI_INCLUDE_PATH) +endif(WITH_PVAPI) + +# --- GigEVisionSDK --- +ocv_clear_vars(HAVE_GIGE_API) +if(WITH_GIGEAPI) + find_path(GIGEAPI_INCLUDE_PATH "GigEVisionSDK.h" + PATHS /usr/local /var /opt /usr ENV ProgramFiles ENV ProgramW6432 + PATH_SUFFIXES include "Smartek Vision Technologies/GigEVisionSDK/gige_cpp" "GigEVisionSDK/gige_cpp" "GigEVisionSDK/gige_c" + DOC "The path to Smartek GigEVisionSDK header") + FIND_LIBRARY(GIGEAPI_LIBRARIES NAMES GigEVisionSDK) + if(GIGEAPI_LIBRARIES AND GIGEAPI_INCLUDE_PATH) + set(HAVE_GIGE_API TRUE) + endif() +endif(WITH_GIGEAPI) + +# --- Dc1394 --- +ocv_clear_vars(HAVE_DC1394 HAVE_DC1394_2) +if(WITH_1394) + CHECK_MODULE(libdc1394-2 HAVE_DC1394_2) + if(NOT HAVE_DC1394_2) + CHECK_MODULE(libdc1394 HAVE_DC1394) + endif() +endif(WITH_1394) + +# --- xine --- +ocv_clear_vars(HAVE_XINE) +if(WITH_XINE) + CHECK_MODULE(libxine HAVE_XINE) +endif(WITH_XINE) + +# --- V4L --- +ocv_clear_vars(HAVE_LIBV4L HAVE_CAMV4L HAVE_CAMV4L2 HAVE_VIDEOIO) +if(WITH_V4L) + CHECK_MODULE(libv4l1 HAVE_LIBV4L) + CHECK_INCLUDE_FILE(linux/videodev.h HAVE_CAMV4L) + CHECK_INCLUDE_FILE(linux/videodev2.h HAVE_CAMV4L2) + CHECK_INCLUDE_FILE(sys/videoio.h HAVE_VIDEOIO) +endif(WITH_V4L) + +# --- OpenNI --- +ocv_clear_vars(HAVE_OPENNI HAVE_OPENNI_PRIME_SENSOR_MODULE) +if(WITH_OPENNI) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenNI.cmake") +endif(WITH_OPENNI) + +# --- XIMEA --- +ocv_clear_vars(HAVE_XIMEA) +if(WITH_XIMEA) + include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindXimea.cmake") + if(XIMEA_FOUND) + set(HAVE_XIMEA TRUE) + endif() +endif(WITH_XIMEA) + +# --- FFMPEG --- +ocv_clear_vars(HAVE_FFMPEG HAVE_FFMPEG_CODEC HAVE_FFMPEG_FORMAT HAVE_FFMPEG_UTIL HAVE_FFMPEG_SWSCALE HAVE_GENTOO_FFMPEG HAVE_FFMPEG_FFMPEG) +if(WITH_FFMPEG) + if(WIN32 AND NOT ARM) + include("${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/ffmpeg_version.cmake") + elseif(UNIX) + CHECK_MODULE(libavcodec HAVE_FFMPEG_CODEC) + CHECK_MODULE(libavformat HAVE_FFMPEG_FORMAT) + CHECK_MODULE(libavutil HAVE_FFMPEG_UTIL) + CHECK_MODULE(libswscale HAVE_FFMPEG_SWSCALE) + + CHECK_INCLUDE_FILE(libavformat/avformat.h HAVE_GENTOO_FFMPEG) + CHECK_INCLUDE_FILE(ffmpeg/avformat.h HAVE_FFMPEG_FFMPEG) + if(NOT HAVE_GENTOO_FFMPEG AND NOT HAVE_FFMPEG_FFMPEG) + if(EXISTS /usr/include/ffmpeg/libavformat/avformat.h OR HAVE_FFMPEG_SWSCALE) + set(HAVE_GENTOO_FFMPEG TRUE) + endif() + endif() + if(HAVE_FFMPEG_CODEC AND HAVE_FFMPEG_FORMAT AND HAVE_FFMPEG_UTIL AND HAVE_FFMPEG_SWSCALE) + set(HAVE_FFMPEG TRUE) + endif() + + if(HAVE_FFMPEG) + # Find the bzip2 library because it is required on some systems + FIND_LIBRARY(BZIP2_LIBRARIES NAMES bz2 bzip2) + if(NOT BZIP2_LIBRARIES) + # Do an other trial + FIND_FILE(BZIP2_LIBRARIES NAMES libbz2.so.1 PATHS /lib) + endif() + endif(HAVE_FFMPEG) + endif() + + if(APPLE) + find_path(FFMPEG_INCLUDE_DIR "libavformat/avformat.h" + PATHS /usr/local /usr /opt + PATH_SUFFIXES include + DOC "The path to FFMPEG headers") + if(FFMPEG_INCLUDE_DIR) + set(HAVE_GENTOO_FFMPEG TRUE) + set(FFMPEG_LIB_DIR "${FFMPEG_INCLUDE_DIR}/../lib" CACHE PATH "Full path of FFMPEG library directory") + if(EXISTS "${FFMPEG_LIB_DIR}/libavcodec.a") + set(HAVE_FFMPEG_CODEC 1) + set(ALIASOF_libavcodec_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libavformat.a") + set(HAVE_FFMPEG_FORMAT 1) + set(ALIASOF_libavformat_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libavutil.a") + set(HAVE_FFMPEG_UTIL 1) + set(ALIASOF_libavutil_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libswscale.a") + set(HAVE_FFMPEG_SWSCALE 1) + set(ALIASOF_libswscale_VERSION "Unknown") + set(HAVE_FFMPEG 1) + endif() + endif() + endif() + endif() + endif(FFMPEG_INCLUDE_DIR) + if(HAVE_FFMPEG) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "${FFMPEG_LIB_DIR}/libavcodec.a" + "${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a" + "${FFMPEG_LIB_DIR}/libswscale.a") + ocv_include_directories(${FFMPEG_INCLUDE_DIR}) + endif() + endif(APPLE) +endif(WITH_FFMPEG) + +# --- VideoInput/DirectShow --- +if(WITH_DSHOW) + # always have VideoInput on Windows + set(HAVE_DSHOW 1) +endif(WITH_DSHOW) + +# --- VideoInput/Microsoft Media Foundation --- +if(WITH_MSMF) + check_include_file(Mfapi.h HAVE_MSMF) +endif(WITH_MSMF) + +# --- Extra HighGUI libs on Windows --- +if(WIN32) + list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 vfw32) + if(MINGW64) + list(APPEND HIGHGUI_LIBRARIES avifil32 avicap32 winmm msvfw32) + list(REMOVE_ITEM HIGHGUI_LIBRARIES vfw32) + elseif(MINGW) + list(APPEND HIGHGUI_LIBRARIES winmm) + endif() +endif(WIN32) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindOpenEXR.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindOpenEXR.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindOpenEXR.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindOpenEXR.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,108 @@ +# The script is taken from http://code.google.com/p/nvidia-texture-tools/ + +# +# Try to find OpenEXR's libraries, and include path. +# Once done this will define: +# +# OPENEXR_FOUND = OpenEXR found. +# OPENEXR_INCLUDE_PATHS = OpenEXR include directories. +# OPENEXR_LIBRARIES = libraries that are needed to use OpenEXR. +# + +SET(OPENEXR_LIBRARIES "") +SET(OPENEXR_LIBSEARCH_SUFFIXES "") +file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH) + +if(WIN32) + SET(OPENEXR_ROOT "C:/Deploy" CACHE STRING "Path to the OpenEXR \"Deploy\" folder") + if(CMAKE_CL_64) + SET(OPENEXR_LIBSEARCH_SUFFIXES x64/Release x64 x64/Debug) + elseif(MSVC) + SET(OPENEXR_LIBSEARCH_SUFFIXES Win32/Release Win32 Win32/Debug) + endif() +else() + set(OPENEXR_ROOT "") +endif() + +SET(LIBRARY_PATHS + /usr/lib + /usr/local/lib + /sw/lib + /opt/local/lib + "${ProgramFiles_ENV_PATH}/OpenEXR/lib/static" + "${OPENEXR_ROOT}/lib") + +FIND_PATH(OPENEXR_INCLUDE_PATH ImfRgbaFile.h + PATH_SUFFIXES OpenEXR + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + "${ProgramFiles_ENV_PATH}/OpenEXR/include" + "${OPENEXR_ROOT}/include") + +FIND_LIBRARY(OPENEXR_HALF_LIBRARY + NAMES Half + PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES} + PATHS ${LIBRARY_PATHS}) + +FIND_LIBRARY(OPENEXR_IEX_LIBRARY + NAMES Iex + PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES} + PATHS ${LIBRARY_PATHS}) + +FIND_LIBRARY(OPENEXR_IMATH_LIBRARY + NAMES Imath + PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES} + PATHS ${LIBRARY_PATHS}) + +FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY + NAMES IlmImf + PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES} + PATHS ${LIBRARY_PATHS}) + +FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY + NAMES IlmThread + PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES} + PATHS ${LIBRARY_PATHS}) + +IF (OPENEXR_INCLUDE_PATH AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY) + SET(OPENEXR_FOUND TRUE) + SET(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATH} CACHE PATH "The include paths needed to use OpenEXR") + SET(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR" FORCE) +ENDIF () + +IF(OPENEXR_FOUND) + IF(NOT OPENEXR_FIND_QUIETLY) + MESSAGE(STATUS "Found OpenEXR: ${OPENEXR_ILMIMF_LIBRARY}") + ENDIF() + if(PKG_CONFIG_FOUND AND NOT OPENEXR_VERSION) + get_filename_component(OPENEXR_LIB_PATH "${OPENEXR_ILMIMF_LIBRARY}" PATH) + if(EXISTS "${OPENEXR_LIB_PATH}/pkgconfig/OpenEXR.pc") + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --modversion "${OPENEXR_LIB_PATH}/pkgconfig/OpenEXR.pc" + RESULT_VARIABLE PKG_CONFIG_PROCESS + OUTPUT_VARIABLE OPENEXR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + if(NOT PKG_CONFIG_PROCESS EQUAL 0) + SET(OPENEXR_VERSION "Unknown") + endif() + endif() + endif() + if(NOT OPENEXR_VERSION) + SET(OPENEXR_VERSION "Unknown") + endif() +ELSE() + IF(OPENEXR_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find OpenEXR library") + ENDIF() +ENDIF() + +MARK_AS_ADVANCED( + OPENEXR_INCLUDE_PATHS + OPENEXR_LIBRARIES + OPENEXR_ILMIMF_LIBRARY + OPENEXR_IMATH_LIBRARY + OPENEXR_IEX_LIBRARY + OPENEXR_HALF_LIBRARY + OPENEXR_ILMTHREAD_LIBRARY) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindOpenNI.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindOpenNI.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindOpenNI.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindOpenNI.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,89 @@ +# Main variables: +# OPENNI_LIBRARY and OPENNI_INCLUDES to link OpenCV modules with OpenNI +# HAVE_OPENNI for conditional compilation OpenCV with/without OpenNI + +if(NOT "${OPENNI_LIB_DIR}" STREQUAL "${OPENNI_LIB_DIR_INTERNAL}") + unset(OPENNI_LIBRARY CACHE) + unset(OPENNI_LIB_DIR CACHE) +endif() + +if(NOT "${OPENNI_INCLUDE_DIR}" STREQUAL "${OPENNI_INCLUDE_DIR_INTERNAL}") + unset(OPENNI_INCLUDES CACHE) + unset(OPENNI_INCLUDE_DIR CACHE) +endif() + +if(NOT "${OPENNI_PRIME_SENSOR_MODULE_BIN_DIR}" STREQUAL "${OPENNI_PRIME_SENSOR_MODULE_BIN_DIR_INTERNAL}") + unset(OPENNI_PRIME_SENSOR_MODULE CACHE) + unset(OPENNI_PRIME_SENSOR_MODULE_BIN_DIR CACHE) +endif() + +if(WIN32) + if(NOT (MSVC64 OR MINGW64)) + find_file(OPENNI_INCLUDES "XnCppWrapper.h" PATHS "$ENV{OPEN_NI_INSTALL_PATH}Include" DOC "OpenNI c++ interface header") + find_library(OPENNI_LIBRARY "OpenNI" PATHS $ENV{OPEN_NI_LIB} DOC "OpenNI library") + else() + find_file(OPENNI_INCLUDES "XnCppWrapper.h" PATHS "$ENV{OPEN_NI_INSTALL_PATH64}Include" DOC "OpenNI c++ interface header") + find_library(OPENNI_LIBRARY "OpenNI64" PATHS $ENV{OPEN_NI_LIB64} DOC "OpenNI library") + endif() +elseif(UNIX OR APPLE) + find_file(OPENNI_INCLUDES "XnCppWrapper.h" PATHS "/usr/include/ni" "/usr/include/openni" DOC "OpenNI c++ interface header") + find_library(OPENNI_LIBRARY "OpenNI" PATHS "/usr/lib" DOC "OpenNI library") +endif() + +if(OPENNI_LIBRARY AND OPENNI_INCLUDES) + set(HAVE_OPENNI TRUE) + # the check: are PrimeSensor Modules for OpenNI installed + if(WIN32) + if(NOT (MSVC64 OR MINGW64)) + find_file(OPENNI_PRIME_SENSOR_MODULE "XnCore.dll" PATHS "$ENV{OPEN_NI_INSTALL_PATH}../PrimeSense/Sensor/Bin" "$ENV{OPEN_NI_INSTALL_PATH}../PrimeSense/SensorKinect/Bin" DOC "Core library of PrimeSensor Modules for OpenNI") + else() + find_file(OPENNI_PRIME_SENSOR_MODULE "XnCore64.dll" PATHS "$ENV{OPEN_NI_INSTALL_PATH64}../PrimeSense/Sensor/Bin64" "$ENV{OPEN_NI_INSTALL_PATH64}../PrimeSense/SensorKinect/Bin64" DOC "Core library of PrimeSensor Modules for OpenNI") + endif() + elseif(UNIX OR APPLE) + find_library(OPENNI_PRIME_SENSOR_MODULE "XnCore" PATHS "/usr/lib" DOC "Core library of PrimeSensor Modules for OpenNI") + endif() + + if(OPENNI_PRIME_SENSOR_MODULE) + set(HAVE_OPENNI_PRIME_SENSOR_MODULE TRUE) + endif() +endif() #if(OPENNI_LIBRARY AND OPENNI_INCLUDES) + +get_filename_component(OPENNI_LIB_DIR "${OPENNI_LIBRARY}" PATH) +get_filename_component(OPENNI_INCLUDE_DIR ${OPENNI_INCLUDES} PATH) +get_filename_component(OPENNI_PRIME_SENSOR_MODULE_BIN_DIR "${OPENNI_PRIME_SENSOR_MODULE}" PATH) + +if(HAVE_OPENNI) + set(OPENNI_LIB_DIR "${OPENNI_LIB_DIR}" CACHE PATH "Path to OpenNI libraries" FORCE) + set(OPENNI_INCLUDE_DIR "${OPENNI_INCLUDE_DIR}" CACHE PATH "Path to OpenNI headers" FORCE) + set(OPENNI_PRIME_SENSOR_MODULE_BIN_DIR "${OPENNI_PRIME_SENSOR_MODULE_BIN_DIR}" CACHE PATH "Path to OpenNI PrimeSensor Module binaries" FORCE) +endif() + +if(OPENNI_LIBRARY) + set(OPENNI_LIB_DIR_INTERNAL "${OPENNI_LIB_DIR}" CACHE INTERNAL "This is the value of the last time OPENNI_LIB_DIR was set successfully." FORCE) +else() + message( WARNING, " OpenNI library directory (set by OPENNI_LIB_DIR variable) is not found or does not have OpenNI libraries." ) +endif() + +if(OPENNI_INCLUDES) + set(OPENNI_INCLUDE_DIR_INTERNAL "${OPENNI_INCLUDE_DIR}" CACHE INTERNAL "This is the value of the last time OPENNI_INCLUDE_DIR was set successfully." FORCE) +else() + message( WARNING, " OpenNI include directory (set by OPENNI_INCLUDE_DIR variable) is not found or does not have OpenNI include files." ) +endif() + +if(OPENNI_PRIME_SENSOR_MODULE) + set(OPENNI_PRIME_SENSOR_MODULE_BIN_DIR_INTERNAL "${OPENNI_PRIME_SENSOR_MODULE_BIN_DIR}" CACHE INTERNAL "This is the value of the last time OPENNI_PRIME_SENSOR_MODULE_BIN_DIR was set successfully." FORCE) +else() + message( WARNING, " PrimeSensor Module binaries directory (set by OPENNI_PRIME_SENSOR_MODULE_BIN_DIR variable) is not found or does not have PrimeSensor Module binaries." ) +endif() + +mark_as_advanced(FORCE OPENNI_PRIME_SENSOR_MODULE) +mark_as_advanced(FORCE OPENNI_LIBRARY) +mark_as_advanced(FORCE OPENNI_INCLUDES) + +if(HAVE_OPENNI) + ocv_parse_header("${OPENNI_INCLUDE_DIR}/XnVersion.h" OPENNI_VERSION_LINES XN_MAJOR_VERSION XN_MINOR_VERSION XN_MAINTENANCE_VERSION XN_BUILD_VERSION) + if(XN_MAJOR_VERSION) + set(OPENNI_VERSION_STRING ${XN_MAJOR_VERSION}.${XN_MINOR_VERSION}.${XN_MAINTENANCE_VERSION} CACHE INTERNAL "OpenNI version") + set(OPENNI_VERSION_BUILD ${XN_BUILD_VERSION} CACHE INTERNAL "OpenNI build version") + endif() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindPkgConfig.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindPkgConfig.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindPkgConfig.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindPkgConfig.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,365 @@ +# +# OpenCV note: the file has been extracted from CMake 2.6.2 distribution. +# It is used to build OpenCV with CMake 2.4.x +# + +# - a pkg-config module for CMake +# +# Usage: +# pkg_check_modules( [REQUIRED] []*) +# checks for all the given modules +# +# pkg_search_module( [REQUIRED] []*) +# checks for given modules and uses the first working one +# +# When the 'REQUIRED' argument was set, macros will fail with an error +# when module(s) could not be found +# +# It sets the following variables: +# PKG_CONFIG_FOUND ... true if pkg-config works on the system +# PKG_CONFIG_EXECUTABLE ... pathname of the pkg-config program +# _FOUND ... set to 1 if module(s) exist +# +# For the following variables two sets of values exist; first one is the +# common one and has the given PREFIX. The second set contains flags +# which are given out when pkgconfig was called with the '--static' +# option. +# _LIBRARIES ... only the libraries (w/o the '-l') +# _LIBRARY_DIRS ... the paths of the libraries (w/o the '-L') +# _LDFLAGS ... all required linker flags +# _LDFLAGS_OTHER ... all other linker flags +# _INCLUDE_DIRS ... the '-I' preprocessor flags (w/o the '-I') +# _CFLAGS ... all required cflags +# _CFLAGS_OTHER ... the other compiler flags +# +# = for common case +# = _STATIC for static linking +# +# There are some special variables whose prefix depends on the count +# of given modules. When there is only one module, stays +# unchanged. When there are multiple modules, the prefix will be +# changed to _: +# _VERSION ... version of the module +# _PREFIX ... prefix-directory of the module +# _INCLUDEDIR ... include-dir of the module +# _LIBDIR ... lib-dir of the module +# +# = when |MODULES| == 1, else +# = _ +# +# A parameter can have the following formats: +# {MODNAME} ... matches any version +# {MODNAME}>={VERSION} ... at least version is required +# {MODNAME}={VERSION} ... exactly version is required +# {MODNAME}<={VERSION} ... modules must not be newer than +# +# Examples +# pkg_check_modules (GLIB2 glib-2.0) +# +# pkg_check_modules (GLIB2 glib-2.0>=2.10) +# requires at least version 2.10 of glib2 and defines e.g. +# GLIB2_VERSION=2.10.3 +# +# pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0) +# requires both glib2 and gtk2, and defines e.g. +# FOO_glib-2.0_VERSION=2.10.3 +# FOO_gtk+-2.0_VERSION=2.8.20 +# +# pkg_check_modules (XRENDER REQUIRED xrender) +# defines e.g.: +# XRENDER_LIBRARIES=Xrender;X11 +# XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp +# +# pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2) + + +# Copyright (C) 2006 Enrico Scholz +# +# Redistribution and use, with or without modification, are permitted +# provided that the following conditions are met: +# +# 1. Redistributions must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +### Common stuff #### +set(PKG_CONFIG_VERSION 1) +set(PKG_CONFIG_FOUND 0) + +find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable") +mark_as_advanced(PKG_CONFIG_EXECUTABLE) + +if(PKG_CONFIG_EXECUTABLE) + set(PKG_CONFIG_FOUND 1) +endif(PKG_CONFIG_EXECUTABLE) + + +# Unsets the given variables +macro(_pkgconfig_unset var) + set(${var} "" CACHE INTERNAL "") +endmacro(_pkgconfig_unset) + +macro(_pkgconfig_set var value) + set(${var} ${value} CACHE INTERNAL "") +endmacro(_pkgconfig_set) + +# Invokes pkgconfig, cleans up the result and sets variables +macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp) + set(_pkgconfig_invoke_result) + + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist} + OUTPUT_VARIABLE _pkgconfig_invoke_result + RESULT_VARIABLE _pkgconfig_failed) + + if (_pkgconfig_failed) + set(_pkgconfig_${_varname} "") + _pkgconfig_unset(${_prefix}_${_varname}) + else(_pkgconfig_failed) + string(REGEX REPLACE "[\r\n]" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}") + string(REGEX REPLACE " +$" "" _pkgconfig_invoke_result "${_pkgconfig_invoke_result}") + + if (NOT ${_regexp} STREQUAL "") + string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}") + endif(NOT ${_regexp} STREQUAL "") + + separate_arguments(_pkgconfig_invoke_result) + + #message(STATUS " ${_varname} ... ${_pkgconfig_invoke_result}") + set(_pkgconfig_${_varname} ${_pkgconfig_invoke_result}) + _pkgconfig_set(${_prefix}_${_varname} "${_pkgconfig_invoke_result}") + endif(_pkgconfig_failed) +endmacro(_pkgconfig_invoke) + +# Invokes pkgconfig two times; once without '--static' and once with +# '--static' +macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp) + _pkgconfig_invoke("${_pkglist}" ${_prefix} ${_varname} "${cleanup_regexp}" ${ARGN}) + _pkgconfig_invoke("${_pkglist}" ${_prefix} STATIC_${_varname} "${cleanup_regexp}" --static ${ARGN}) +endmacro(_pkgconfig_invoke_dyn) + +# Splits given arguments into options and a package list +macro(_pkgconfig_parse_options _result _is_req) + set(${_is_req} 0) + + foreach(_pkg ${ARGN}) + if (_pkg STREQUAL "REQUIRED") + set(${_is_req} 1) + endif (_pkg STREQUAL "REQUIRED") + endforeach(_pkg ${ARGN}) + + set(${_result} ${ARGN}) + list(REMOVE_ITEM ${_result} "REQUIRED") +endmacro(_pkgconfig_parse_options) + +### +macro(_pkg_check_modules_internal _is_required _is_silent _prefix) + _pkgconfig_unset(${_prefix}_FOUND) + _pkgconfig_unset(${_prefix}_VERSION) + _pkgconfig_unset(${_prefix}_PREFIX) + _pkgconfig_unset(${_prefix}_INCLUDEDIR) + _pkgconfig_unset(${_prefix}_LIBDIR) + _pkgconfig_unset(${_prefix}_LIBS) + _pkgconfig_unset(${_prefix}_LIBS_L) + _pkgconfig_unset(${_prefix}_LIBS_PATHS) + _pkgconfig_unset(${_prefix}_LIBS_OTHER) + _pkgconfig_unset(${_prefix}_CFLAGS) + _pkgconfig_unset(${_prefix}_CFLAGS_I) + _pkgconfig_unset(${_prefix}_CFLAGS_OTHER) + _pkgconfig_unset(${_prefix}_STATIC_LIBDIR) + _pkgconfig_unset(${_prefix}_STATIC_LIBS) + _pkgconfig_unset(${_prefix}_STATIC_LIBS_L) + _pkgconfig_unset(${_prefix}_STATIC_LIBS_PATHS) + _pkgconfig_unset(${_prefix}_STATIC_LIBS_OTHER) + _pkgconfig_unset(${_prefix}_STATIC_CFLAGS) + _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_I) + _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_OTHER) + + # create a better addressable variable of the modules and calculate its size + set(_pkg_check_modules_list ${ARGN}) + list(LENGTH _pkg_check_modules_list _pkg_check_modules_cnt) + + if(PKG_CONFIG_EXECUTABLE) + # give out status message telling checked module + if (NOT ${_is_silent}) + if (_pkg_check_modules_cnt EQUAL 1) + message(STATUS "checking for module '${_pkg_check_modules_list}'") + else(_pkg_check_modules_cnt EQUAL 1) + message(STATUS "checking for modules '${_pkg_check_modules_list}'") + endif(_pkg_check_modules_cnt EQUAL 1) + endif(NOT ${_is_silent}) + + set(_pkg_check_modules_packages) + set(_pkg_check_modules_failed) + + # iterate through module list and check whether they exist and match the required version + foreach (_pkg_check_modules_pkg ${_pkg_check_modules_list}) + set(_pkg_check_modules_exist_query) + + # check whether version is given + if (_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*") + string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\1" _pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}") + string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\2" _pkg_check_modules_pkg_op "${_pkg_check_modules_pkg}") + string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\3" _pkg_check_modules_pkg_ver "${_pkg_check_modules_pkg}") + else(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*") + set(_pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}") + set(_pkg_check_modules_pkg_op) + set(_pkg_check_modules_pkg_ver) + endif(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*") + + # handle the operands + if (_pkg_check_modules_pkg_op STREQUAL ">=") + list(APPEND _pkg_check_modules_exist_query --atleast-version) + endif(_pkg_check_modules_pkg_op STREQUAL ">=") + + if (_pkg_check_modules_pkg_op STREQUAL "=") + list(APPEND _pkg_check_modules_exist_query --exact-version) + endif(_pkg_check_modules_pkg_op STREQUAL "=") + + if (_pkg_check_modules_pkg_op STREQUAL "<=") + list(APPEND _pkg_check_modules_exist_query --max-version) + endif(_pkg_check_modules_pkg_op STREQUAL "<=") + + # create the final query which is of the format: + # * --atleast-version + # * --exact-version + # * --max-version + # * --exists + if (_pkg_check_modules_pkg_op) + list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_ver}") + else(_pkg_check_modules_pkg_op) + list(APPEND _pkg_check_modules_exist_query --exists) + endif(_pkg_check_modules_pkg_op) + + _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_VERSION) + _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_PREFIX) + _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_INCLUDEDIR) + _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_LIBDIR) + + list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_name}") + list(APPEND _pkg_check_modules_packages "${_pkg_check_modules_pkg_name}") + + # execute the query + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query} + RESULT_VARIABLE _pkgconfig_retval) + + # evaluate result and tell failures + if (_pkgconfig_retval) + if(NOT ${_is_silent}) + message(STATUS " package '${_pkg_check_modules_pkg}' not found") + endif(NOT ${_is_silent}) + + set(_pkg_check_modules_failed 1) + endif(_pkgconfig_retval) + endforeach(_pkg_check_modules_pkg) + + if(_pkg_check_modules_failed) + # fail when requested + if (${_is_required}) + message(SEND_ERROR "A required package was not found") + endif (${_is_required}) + else(_pkg_check_modules_failed) + # when we are here, we checked whether requested modules + # exist. Now, go through them and set variables + + _pkgconfig_set(${_prefix}_FOUND 1) + list(LENGTH _pkg_check_modules_packages pkg_count) + + # iterate through all modules again and set individual variables + foreach (_pkg_check_modules_pkg ${_pkg_check_modules_packages}) + # handle case when there is only one package required + if (pkg_count EQUAL 1) + set(_pkg_check_prefix "${_prefix}") + else(pkg_count EQUAL 1) + set(_pkg_check_prefix "${_prefix}_${_pkg_check_modules_pkg}") + endif(pkg_count EQUAL 1) + + _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" VERSION "" --modversion ) + _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" PREFIX "" --variable=prefix ) + _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" INCLUDEDIR "" --variable=includedir ) + _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" LIBDIR "" --variable=libdir ) + + message(STATUS " found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}") + endforeach(_pkg_check_modules_pkg) + + # set variables which are combined for multiple modules + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARIES "(^| )-l" --libs-only-l ) + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS "(^| )-L" --libs-only-L ) + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS "" --libs ) + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER "" --libs-only-other ) + + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS "(^| )-I" --cflags-only-I ) + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS "" --cflags ) + _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER "" --cflags-only-other ) + endif(_pkg_check_modules_failed) + else(PKG_CONFIG_EXECUTABLE) + if (${_is_required}) + message(SEND_ERROR "pkg-config tool not found") + endif (${_is_required}) + endif(PKG_CONFIG_EXECUTABLE) +endmacro(_pkg_check_modules_internal) + +### +### User visible macros start here +### + +### +macro(pkg_check_modules _prefix _module0) + # check cached value + if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND) + _pkgconfig_parse_options (_pkg_modules _pkg_is_required "${_module0}" ${ARGN}) + _pkg_check_modules_internal("${_pkg_is_required}" 0 "${_prefix}" ${_pkg_modules}) + + _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION}) + endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND) +endmacro(pkg_check_modules) + +### +macro(pkg_search_module _prefix _module0) + # check cached value + if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND) + set(_pkg_modules_found 0) + _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required "${_module0}" ${ARGN}) + + message(STATUS "checking for one of the modules '${_pkg_modules_alt}'") + + # iterate through all modules and stop at the first working one. + foreach(_pkg_alt ${_pkg_modules_alt}) + if(NOT _pkg_modules_found) + _pkg_check_modules_internal(0 1 "${_prefix}" "${_pkg_alt}") + endif(NOT _pkg_modules_found) + + if (${_prefix}_FOUND) + set(_pkg_modules_found 1) + endif(${_prefix}_FOUND) + endforeach(_pkg_alt) + + if (NOT ${_prefix}_FOUND) + if(${_pkg_is_required}) + message(SEND_ERROR "None of the required '${_pkg_modules_alt}' found") + endif(${_pkg_is_required}) + endif(NOT ${_prefix}_FOUND) + + _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION}) + endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND) +endmacro(pkg_search_module) + +### Local Variables: +### mode: cmake +### End: diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindXimea.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindXimea.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVFindXimea.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVFindXimea.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,42 @@ +# - Find XIMEA +# This module finds if XIMEA Software package is installed +# and determines where the binaries and header files are. +# This code sets the following variables: +# +# XIMEA_FOUND - True if XIMEA API found +# XIMEA_PATH: - Path to the XIMEA API folder +# XIMEA_LIBRARY_DIR - XIMEA libraries folder +# +# Created: 5 Aug 2011 by Marian Zajko (marian.zajko@ximea.com) +# Updated: 25 June 2012 by Igor Kuzmin (parafin@ximea.com) +# + +set(XIMEA_FOUND) +set(XIMEA_PATH) +set(XIMEA_LIBRARY_DIR) + +if(WIN32) + # Try to find the XIMEA API path in registry. + GET_FILENAME_COMPONENT(XIMEA_PATH "[HKEY_CURRENT_USER\\Software\\XIMEA\\CamSupport\\API;Path]" ABSOLUTE) + + if(EXISTS XIMEA_PATH) + set(XIMEA_FOUND 1) + # set LIB folders + set(XIMEA_LIBRARY_DIR "${XIMEA_PATH}/x86") + else() + set(XIMEA_FOUND 0) + endif() +else() + if(EXISTS /opt/XIMEA) + set(XIMEA_FOUND 1) + # set folders + set(XIMEA_PATH /opt/XIMEA/include) + else() + set(XIMEA_FOUND 0) + endif() +endif() + +mark_as_advanced(FORCE XIMEA_FOUND) +mark_as_advanced(FORCE XIMEA_PATH) +mark_as_advanced(FORCE XIMEA_LIBRARY_DIR) + diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenAndroidMK.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenAndroidMK.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenAndroidMK.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenAndroidMK.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,106 @@ +if(ANDROID) + # -------------------------------------------------------------------------------------------- + # Installation for Android ndk-build makefile: OpenCV.mk + # Part 1/2: ${BIN_DIR}/OpenCV.mk -> For use *without* "make install" + # Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install" + # ------------------------------------------------------------------------------------------- + + # build type + if(BUILD_SHARED_LIBS) + set(OPENCV_LIBTYPE_CONFIGMAKE "SHARED") + else() + set(OPENCV_LIBTYPE_CONFIGMAKE "STATIC") + endif() + + if(BUILD_FAT_JAVA_LIB) + set(OPENCV_LIBTYPE_CONFIGMAKE "SHARED") + set(OPENCV_STATIC_LIBTYPE_CONFIGMAKE "STATIC") + else() + set(OPENCV_STATIC_LIBTYPE_CONFIGMAKE ${OPENCV_LIBTYPE_CONFIGMAKE}) + endif() + + # setup lists of camera libs + foreach(abi ARMEABI ARMEABI_V7A X86 MIPS) + ANDROID_GET_ABI_RAWNAME(${abi} ndkabi) + if(BUILD_ANDROID_CAMERA_WRAPPER) + if(ndkabi STREQUAL ANDROID_NDK_ABI_NAME) + set(OPENCV_CAMERA_LIBS_${abi}_CONFIGCMAKE "native_camera_r${ANDROID_VERSION}") + else() + set(OPENCV_CAMERA_LIBS_${abi}_CONFIGCMAKE "") + endif() + elseif(HAVE_opencv_androidcamera) + set(OPENCV_CAMERA_LIBS_${abi}_CONFIGCMAKE "") + file(GLOB OPENCV_CAMERA_LIBS "${OpenCV_SOURCE_DIR}/3rdparty/lib/${ndkabi}/libnative_camera_r*.so") + if(OPENCV_CAMERA_LIBS) + list(SORT OPENCV_CAMERA_LIBS) + endif() + foreach(cam_lib ${OPENCV_CAMERA_LIBS}) + get_filename_component(cam_lib "${cam_lib}" NAME) + string(REGEX REPLACE "lib(native_camera_r[0-9]+\\.[0-9]+\\.[0-9]+)\\.so" "\\1" cam_lib "${cam_lib}") + set(OPENCV_CAMERA_LIBS_${abi}_CONFIGCMAKE "${OPENCV_CAMERA_LIBS_${abi}_CONFIGCMAKE} ${cam_lib}") + endforeach() + endif() + endforeach() + + # build the list of opencv libs and dependencies for all modules + set(OPENCV_MODULES_CONFIGMAKE "") + set(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "") + set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE "") + foreach(m ${OPENCV_MODULES_PUBLIC}) + list(INSERT OPENCV_MODULES_CONFIGMAKE 0 ${${m}_MODULE_DEPS_${ocv_optkind}} ${m}) + if(${m}_EXTRA_DEPS_${ocv_optkind}) + list(INSERT OPENCV_EXTRA_COMPONENTS_CONFIGMAKE 0 ${${m}_EXTRA_DEPS_${ocv_optkind}}) + endif() + endforeach() + + # split 3rdparty libs and modules + foreach(mod ${OPENCV_MODULES_CONFIGMAKE}) + if(NOT mod MATCHES "^opencv_.+$") + list(INSERT OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE 0 ${mod}) + endif() + endforeach() + if(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE) + list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) + endif() + + # convert CMake lists to makefile literals + foreach(lst OPENCV_MODULES_CONFIGMAKE OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE OPENCV_EXTRA_COMPONENTS_CONFIGMAKE) + ocv_list_unique(${lst}) + ocv_list_reverse(${lst}) + string(REPLACE ";" " " ${lst} "${${lst}}") + endforeach() + string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + + # prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there. + set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) + foreach(mod ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}) + string(REPLACE "tbb" "" OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB "${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}") + endforeach() + + if(BUILD_FAT_JAVA_LIB) + set(OPENCV_LIBS_CONFIGMAKE java) + else() + set(OPENCV_LIBS_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + endif() + + # ------------------------------------------------------------------------------------------- + # Part 1/2: ${BIN_DIR}/OpenCV.mk -> For use *without* "make install" + # ------------------------------------------------------------------------------------------- + set(OPENCV_INCLUDE_DIRS_CONFIGCMAKE "\"${OPENCV_CONFIG_FILE_INCLUDE_DIR}\" \"${OpenCV_SOURCE_DIR}/include\" \"${OpenCV_SOURCE_DIR}/include/opencv\"") + set(OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE "\"${OpenCV_SOURCE_DIR}\"") + set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/lib/\$(OPENCV_TARGET_ARCH_ABI)") + set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/3rdparty/lib/\$(OPENCV_TARGET_ARCH_ABI)") + + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" IMMEDIATE @ONLY) + + # ------------------------------------------------------------------------------------------- + # Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install" + # ------------------------------------------------------------------------------------------- + set(OPENCV_INCLUDE_DIRS_CONFIGCMAKE "\"\$(LOCAL_PATH)/\$(OPENCV_THIS_DIR)/include/opencv\" \"\$(LOCAL_PATH)/\$(OPENCV_THIS_DIR)/include\"") + set(OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE "") + set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../libs/\$(OPENCV_TARGET_ARCH_ABI)") + set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../3rdparty/libs/\$(OPENCV_TARGET_ARCH_ABI)") + + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" IMMEDIATE @ONLY) + install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}) +endif(ANDROID) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenConfig.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenConfig.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenConfig.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenConfig.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,182 @@ +# -------------------------------------------------------------------------------------------- +# Installation for CMake Module: OpenCVConfig.cmake +# Part 1/3: ${BIN_DIR}/OpenCVConfig.cmake -> For use *without* "make install" +# Part 2/3: ${BIN_DIR}/unix-install/OpenCVConfig.cmake -> For use with "make install" +# Part 3/3: ${BIN_DIR}/win-install/OpenCVConfig.cmake -> For use within binary installers/packages +# ------------------------------------------------------------------------------------------- + +if(INSTALL_TO_MANGLED_PATHS) + set(OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE TRUE) +else() + set(OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE FALSE) +endif() + +if(NOT OpenCV_CUDA_CC) + set(OpenCV_CUDA_CC_CONFIGCMAKE "\"\"") + set(OpenCV_CUDA_VERSION "") +else() + set(OpenCV_CUDA_CC_CONFIGCMAKE "${OpenCV_CUDA_CC}") + set(OpenCV_CUDA_VERSION ${CUDA_VERSION_STRING}) +endif() + +if(NOT ANDROID_NATIVE_API_LEVEL) + set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE 0) +else() + set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE "${ANDROID_NATIVE_API_LEVEL}") +endif() + +if(CMAKE_GENERATOR MATCHES "Visual" OR CMAKE_GENERATOR MATCHES "Xcode") + set(OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE TRUE) +else() + set(OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE FALSE) +endif() + + + +if(WIN32) + if(MINGW) + set(OPENCV_LINK_LIBRARY_SUFFIX ".dll.a") + else() + set(OPENCV_LINK_LIBRARY_SUFFIX ".lib") + endif() +endif() + +#build list of modules available for the OpenCV user +set(OpenCV_LIB_COMPONENTS "") +foreach(m ${OPENCV_MODULES_PUBLIC}) + list(INSERT OpenCV_LIB_COMPONENTS 0 ${${m}_MODULE_DEPS_OPT} ${m}) +endforeach() +ocv_list_unique(OpenCV_LIB_COMPONENTS) +set(OPENCV_MODULES_CONFIGCMAKE ${OpenCV_LIB_COMPONENTS}) +ocv_list_filterout(OpenCV_LIB_COMPONENTS "^opencv_") +if(OpenCV_LIB_COMPONENTS) + list(REMOVE_ITEM OPENCV_MODULES_CONFIGCMAKE ${OpenCV_LIB_COMPONENTS}) +endif() + +if(BUILD_FAT_JAVA_LIB AND HAVE_opencv_java) + list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_java) +endif() + +macro(ocv_generate_dependencies_map_configcmake suffix configuration) + set(OPENCV_DEPENDENCIES_MAP_${suffix} "") + set(OPENCV_PROCESSED_LIBS "") + set(OPENCV_LIBS_TO_PROCESS ${OPENCV_MODULES_CONFIGCMAKE}) + while(OPENCV_LIBS_TO_PROCESS) + list(GET OPENCV_LIBS_TO_PROCESS 0 __ocv_lib) + get_target_property(__libname ${__ocv_lib} LOCATION_${configuration}) + get_filename_component(__libname "${__libname}" NAME) + + if(WIN32) + string(REGEX REPLACE "${CMAKE_SHARED_LIBRARY_SUFFIX}$" "${OPENCV_LINK_LIBRARY_SUFFIX}" __libname "${__libname}") + endif() + + if (CUDA_FOUND AND WIN32) + if(${__ocv_lib}_EXTRA_DEPS_${suffix}) + list(REMOVE_ITEM ${__ocv_lib}_EXTRA_DEPS_${suffix} ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDA_npp_LIBRARY} ${CUDA_nvcuvid_LIBRARY} ${CUDA_nvcuvenc_LIBRARY}) + endif() + endif() + + string(REPLACE " " "\\ " __mod_deps "${${__ocv_lib}_MODULE_DEPS_${suffix}}") + string(REPLACE " " "\\ " __ext_deps "${${__ocv_lib}_EXTRA_DEPS_${suffix}}") + string(REPLACE "\"" "\\\"" __mod_deps "${__mod_deps}") + string(REPLACE "\"" "\\\"" __ext_deps "${__ext_deps}") + + + set(OPENCV_DEPENDENCIES_MAP_${suffix} "${OPENCV_DEPENDENCIES_MAP_${suffix}}set(OpenCV_${__ocv_lib}_LIBNAME_${suffix} \"${__libname}\")\n") + set(OPENCV_DEPENDENCIES_MAP_${suffix} "${OPENCV_DEPENDENCIES_MAP_${suffix}}set(OpenCV_${__ocv_lib}_DEPS_${suffix} ${__mod_deps})\n") + set(OPENCV_DEPENDENCIES_MAP_${suffix} "${OPENCV_DEPENDENCIES_MAP_${suffix}}set(OpenCV_${__ocv_lib}_EXTRA_DEPS_${suffix} ${__ext_deps})\n") + + list(APPEND OPENCV_PROCESSED_LIBS ${__ocv_lib}) + list(APPEND OPENCV_LIBS_TO_PROCESS ${${__ocv_lib}_MODULE_DEPS_${suffix}}) + list(REMOVE_ITEM OPENCV_LIBS_TO_PROCESS ${OPENCV_PROCESSED_LIBS}) + endwhile() + unset(OPENCV_PROCESSED_LIBS) + unset(OPENCV_LIBS_TO_PROCESS) + unset(__ocv_lib) + unset(__libname) +endmacro() + +ocv_generate_dependencies_map_configcmake(OPT Release) +ocv_generate_dependencies_map_configcmake(DBG Debug) + + +# ------------------------------------------------------------------------------------------- +# Part 1/3: ${BIN_DIR}/OpenCVConfig.cmake -> For use *without* "make install" +# ------------------------------------------------------------------------------------------- +set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"${OPENCV_CONFIG_FILE_INCLUDE_DIR}\" \"${OpenCV_SOURCE_DIR}/include\" \"${OpenCV_SOURCE_DIR}/include/opencv\"") +set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"${LIBRARY_OUTPUT_PATH}\"") +set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"${3P_LIBRARY_OUTPUT_PATH}\"") + +set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "") +foreach(m ${OPENCV_MODULES_BUILD}) + if(EXISTS "${OPENCV_MODULE_${m}_LOCATION}/include") + list(APPEND OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "${OPENCV_MODULE_${m}_LOCATION}/include") + endif() +endforeach() + +if(ANDROID AND NOT BUILD_SHARED_LIBS AND HAVE_TBB) + #export TBB headers location because static linkage of TBB might be troublesome if application wants to use TBB itself + list(APPEND OpenCV2_INCLUDE_DIRS_CONFIGCMAKE ${TBB_INCLUDE_DIRS}) +endif() + +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" IMMEDIATE @ONLY) +#support for version checking when finding opencv. find_package(OpenCV 2.3.1 EXACT) should now work. +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) + + +# -------------------------------------------------------------------------------------------- +# Part 2/3: ${BIN_DIR}/unix-install/OpenCVConfig.cmake -> For use *with* "make install" +# ------------------------------------------------------------------------------------------- +set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}/opencv" "\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}\"") + +set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"") +if(ANDROID) + set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/sdk/native/libs/\${ANDROID_NDK_ABI_NAME}\"") + set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/sdk/native/3rdparty/libs/\${ANDROID_NDK_ABI_NAME}\"") +else() + set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_LIB_INSTALL_PATH}\"") + set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_3P_LIB_INSTALL_PATH}\"") +endif() +if(INSTALL_TO_MANGLED_PATHS) + string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "${OPENCV_3P_LIB_INSTALL_PATH}") + set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE}\"") +endif() + +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" IMMEDIATE @ONLY) +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) + +if(UNIX) + #http://www.vtk.org/Wiki/CMake/Tutorials/Packaging reference + # For a command "find_package( [major[.minor]] [EXACT] [REQUIRED|QUIET])" + # cmake will look in the following dir on unix: + # /(share|lib)/cmake/*/ (U) + # /(share|lib)/*/ (U) + # /(share|lib)/*/(cmake|CMake)/ (U) + if(INSTALL_TO_MANGLED_PATHS) + install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/) + install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}-${OPENCV_VERSION}/) + else() + install(FILES "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/) + install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/) + endif() +endif() + +if(ANDROID) + install(FILES "${OpenCV_SOURCE_DIR}/android/android.toolchain.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/) +endif() + +# -------------------------------------------------------------------------------------------- +# Part 3/3: ${BIN_DIR}/win-install/OpenCVConfig.cmake -> For use within binary installers/packages +# -------------------------------------------------------------------------------------------- +if(WIN32) + set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_CONFIG_PATH}/include\" \"\${OpenCV_CONFIG_PATH}/include/opencv\"") + set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"") + set(OpenCV_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_CONFIG_PATH}/${OPENCV_LIB_INSTALL_PATH}\"") + set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_CONFIG_PATH}/${OPENCV_3P_LIB_INSTALL_PATH}\"") + + exec_program(mkdir ARGS "-p \"${CMAKE_BINARY_DIR}/win-install/\"" OUTPUT_VARIABLE RET_VAL) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" IMMEDIATE @ONLY) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) + install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}/") + install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" DESTINATION "${CMAKE_INSTALL_PREFIX}/") +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenHeaders.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenHeaders.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenHeaders.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenHeaders.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,36 @@ +# ---------------------------------------------------------------------------- +# Variables for cvconfig.h.cmake +# ---------------------------------------------------------------------------- +set(PACKAGE "opencv") +set(PACKAGE_BUGREPORT "opencvlibrary-devel@lists.sourceforge.net") +set(PACKAGE_NAME "opencv") +set(PACKAGE_STRING "${PACKAGE} ${OPENCV_VERSION}") +set(PACKAGE_TARNAME "${PACKAGE}") +set(PACKAGE_VERSION "${OPENCV_VERSION}") + +# platform-specific config file +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/cvconfig.h.cmake" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h") + +# ---------------------------------------------------------------------------- +# opencv_modules.hpp based on actual modules list +# ---------------------------------------------------------------------------- +set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "") + +set(OPENCV_MOD_LIST ${OPENCV_MODULES_PUBLIC}) +ocv_list_sort(OPENCV_MOD_LIST) +foreach(m ${OPENCV_MOD_LIST}) + string(TOUPPER "${m}" m) + set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#define HAVE_${m}\n") +endforeach() + +set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}\n") + +#set(OPENCV_MOD_LIST ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE}) +#ocv_list_sort(OPENCV_MOD_LIST) +#foreach(m ${OPENCV_MOD_LIST}) +# string(TOUPPER "${m}" m) +# set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#undef HAVE_${m}\n") +#endforeach() + +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv_modules.hpp.in" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") +install(FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2 COMPONENT main) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenPkgconfig.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenPkgconfig.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVGenPkgconfig.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVGenPkgconfig.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,75 @@ +# -------------------------------------------------------------------------------------------- +# according to man pkg-config +# The package name specified on the pkg-config command line is defined to +# be the name of the metadata file, minus the .pc extension. If a library +# can install multiple versions simultaneously, it must give each version +# its own name (for example, GTK 1.2 might have the package name "gtk+" +# while GTK 2.0 has "gtk+-2.0"). +# +# ${BIN_DIR}/unix-install/opencv.pc -> For use *with* "make install" +# ------------------------------------------------------------------------------------------- +set(prefix "${CMAKE_INSTALL_PREFIX}") +set(exec_prefix "\${prefix}") +set(libdir "") #TODO: need link paths for OpenCV_EXTRA_COMPONENTS +set(includedir "\${prefix}/${OPENCV_INCLUDE_INSTALL_PATH}") +set(VERSION ${OPENCV_VERSION}) + +if(CMAKE_BUILD_TYPE MATCHES "Release") + set(ocv_optkind OPT) +else() + set(ocv_optkind DBG) +endif() + +#build the list of opencv libs and dependencies for all modules +set(OpenCV_LIB_COMPONENTS "") +set(OpenCV_EXTRA_COMPONENTS "") +foreach(m ${OPENCV_MODULES_PUBLIC}) + list(INSERT OpenCV_LIB_COMPONENTS 0 ${${m}_MODULE_DEPS_${ocv_optkind}} ${m}) + if(${m}_EXTRA_DEPS_${ocv_optkind}) + list(INSERT OpenCV_EXTRA_COMPONENTS 0 ${${m}_EXTRA_DEPS_${ocv_optkind}}) + endif() +endforeach() + +ocv_list_unique(OpenCV_LIB_COMPONENTS) +ocv_list_unique(OpenCV_EXTRA_COMPONENTS) +ocv_list_reverse(OpenCV_LIB_COMPONENTS) +ocv_list_reverse(OpenCV_EXTRA_COMPONENTS) + +#build the list of components +set(OpenCV_LIB_COMPONENTS_ "") +foreach(CVLib ${OpenCV_LIB_COMPONENTS}) + get_target_property(libpath ${CVLib} LOCATION_${CMAKE_BUILD_TYPE}) + get_filename_component(libname "${libpath}" NAME) + + if(INSTALL_TO_MANGLED_PATHS) + set(libname "${libname}.${OPENCV_VERSION}") + endif() + + #need better solution.... + if(libpath MATCHES "3rdparty") + set(installDir "share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}") + else() + set(installDir "${OPENCV_LIB_INSTALL_PATH}") + endif() + + set(OpenCV_LIB_COMPONENTS_ "${OpenCV_LIB_COMPONENTS_} \${exec_prefix}/${installDir}/${libname}") +endforeach() + +# add extra dependencies required for OpenCV +set(OpenCV_LIB_COMPONENTS ${OpenCV_LIB_COMPONENTS_}) +if(OpenCV_EXTRA_COMPONENTS) + string(REPLACE ";" " " OpenCV_EXTRA_COMPONENTS "${OpenCV_EXTRA_COMPONENTS}") + set(OpenCV_LIB_COMPONENTS "${OpenCV_LIB_COMPONENTS} ${OpenCV_EXTRA_COMPONENTS}") +endif() + +#generate the .pc file +if(INSTALL_TO_MANGLED_PATHS) + set(OPENCV_PC_FILE_NAME "opencv-${OPENCV_VERSION}.pc") +else() + set(OPENCV_PC_FILE_NAME opencv.pc) +endif() +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv-XXX.pc.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME}" @ONLY IMMEDIATE) + +if(UNIX AND NOT ANDROID) + install(FILES ${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME} DESTINATION ${OPENCV_LIB_INSTALL_PATH}/pkgconfig) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVLegacyOptions.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVLegacyOptions.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVLegacyOptions.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVLegacyOptions.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,25 @@ +macro(ocv_legacy_option old superseded_by) + if(DEFINED ${old}) + if(ARGV2) + set(${superseded_by} ${${old}} CACHE ${ARGV2} "Set via depricated ${old}" FORCE) + else() + set(${superseded_by} ${${old}} CACHE BOOL "Set via depricated ${old}" FORCE) + endif() + unset(${old} CACHE) + endif() +endmacro() + +ocv_legacy_option(BUILD_NEW_PYTHON_SUPPORT BUILD_opencv_python) +ocv_legacy_option(BUILD_JAVA_SUPPORT BUILD_opencv_java) +ocv_legacy_option(WITH_ANDROID_CAMERA BUILD_opencv_androidcamera) +ocv_legacy_option(WITH_VIDEOINPUT WITH_DSHOW) + +if(DEFINED OPENCV_BUILD_3RDPARTY_LIBS) + set(BUILD_ZLIB ${OPENCV_BUILD_3RDPARTY_LIBS} CACHE BOOL "Set via depricated OPENCV_BUILD_3RDPARTY_LIBS" FORCE) + set(BUILD_TIFF ${OPENCV_BUILD_3RDPARTY_LIBS} CACHE BOOL "Set via depricated OPENCV_BUILD_3RDPARTY_LIBS" FORCE) + set(BUILD_JASPER ${OPENCV_BUILD_3RDPARTY_LIBS} CACHE BOOL "Set via depricated OPENCV_BUILD_3RDPARTY_LIBS" FORCE) + set(BUILD_JPEG ${OPENCV_BUILD_3RDPARTY_LIBS} CACHE BOOL "Set via depricated OPENCV_BUILD_3RDPARTY_LIBS" FORCE) + set(BUILD_PNG ${OPENCV_BUILD_3RDPARTY_LIBS} CACHE BOOL "Set via depricated OPENCV_BUILD_3RDPARTY_LIBS" FORCE) + unset(OPENCV_BUILD_3RDPARTY_LIBS CACHE) +endif() + diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVModule.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVModule.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVModule.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVModule.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,772 @@ +# Local variables (set for each module): +# +# name - short name in lower case i.e. core +# the_module - full name in lower case i.e. opencv_core + +# Global variables: +# +# OPENCV_MODULE_${the_module}_LOCATION +# OPENCV_MODULE_${the_module}_DESCRIPTION +# OPENCV_MODULE_${the_module}_CLASS - PUBLIC|INTERNAL|BINDINGS +# OPENCV_MODULE_${the_module}_HEADERS +# OPENCV_MODULE_${the_module}_SOURCES +# OPENCV_MODULE_${the_module}_DEPS - final flattened set of module dependencies +# OPENCV_MODULE_${the_module}_DEPS_EXT +# OPENCV_MODULE_${the_module}_REQ_DEPS +# OPENCV_MODULE_${the_module}_OPT_DEPS +# HAVE_${the_module} - for fast check of module availability + +# To control the setup of the module you could also set: +# the_description - text to be used as current module description +# OPENCV_MODULE_TYPE - STATIC|SHARED - set to force override global settings for current module +# OPENCV_MODULE_IS_PART_OF_WORLD - ON|OFF (default ON) - should the module be added to the opencv_world? +# BUILD_${the_module}_INIT - ON|OFF (default ON) - initial value for BUILD_${the_module} + +# The verbose template for OpenCV module: +# +# ocv_add_module(modname ) +# ocv_glob_module_sources() or glob them manually and ocv_set_module_sources(...) +# ocv_module_include_directories() +# ocv_create_module() +# +# ocv_add_precompiled_headers(${the_module}) +# +# ocv_add_accuracy_tests() +# ocv_add_perf_tests() +# +# +# If module have no "extra" then you can define it in one line: +# +# ocv_define_module(modname ) + +# clean flags for modules enabled on previous cmake run +# this is necessary to correctly handle modules removal +foreach(mod ${OPENCV_MODULES_BUILD} ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE}) + if(HAVE_${mod}) + unset(HAVE_${mod} CACHE) + endif() + unset(OPENCV_MODULE_${mod}_REQ_DEPS CACHE) + unset(OPENCV_MODULE_${mod}_OPT_DEPS CACHE) +endforeach() + +# clean modules info which needs to be recalculated +set(OPENCV_MODULES_PUBLIC "" CACHE INTERNAL "List of OpenCV modules marked for export") +set(OPENCV_MODULES_BUILD "" CACHE INTERNAL "List of OpenCV modules included into the build") +set(OPENCV_MODULES_DISABLED_USER "" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user") +set(OPENCV_MODULES_DISABLED_AUTO "" CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies") +set(OPENCV_MODULES_DISABLED_FORCE "" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration") + +# adds dependencies to OpenCV module +# Usage: +# add_dependencies(opencv_ [REQUIRED] [] [OPTIONAL ]) +# Notes: +# * - can include full names of modules or full pathes to shared/static libraries or cmake targets +macro(ocv_add_dependencies full_modname) + #we don't clean the dependencies here to allow this macro several times for every module + foreach(d "REQUIRED" ${ARGN}) + if(d STREQUAL "REQUIRED") + set(__depsvar OPENCV_MODULE_${full_modname}_REQ_DEPS) + elseif(d STREQUAL "OPTIONAL") + set(__depsvar OPENCV_MODULE_${full_modname}_OPT_DEPS) + else() + list(APPEND ${__depsvar} "${d}") + endif() + endforeach() + unset(__depsvar) + + ocv_list_unique(OPENCV_MODULE_${full_modname}_REQ_DEPS) + ocv_list_unique(OPENCV_MODULE_${full_modname}_OPT_DEPS) + + set(OPENCV_MODULE_${full_modname}_REQ_DEPS ${OPENCV_MODULE_${full_modname}_REQ_DEPS} CACHE INTERNAL "Required dependencies of ${full_modname} module") + set(OPENCV_MODULE_${full_modname}_OPT_DEPS ${OPENCV_MODULE_${full_modname}_OPT_DEPS} CACHE INTERNAL "Optional dependencies of ${full_modname} module") +endmacro() + +# declare new OpenCV module in current folder +# Usage: +# ocv_add_module( [INTERNAL|BINDINGS] [REQUIRED] [] [OPTIONAL ]) +# Example: +# ocv_add_module(yaom INTERNAL opencv_core opencv_highgui opencv_flann OPTIONAL opencv_gpu) +macro(ocv_add_module _name) + string(TOLOWER "${_name}" name) + string(REGEX REPLACE "^opencv_" "" ${name} "${name}") + set(the_module opencv_${name}) + + # the first pass - collect modules info, the second pass - create targets + if(OPENCV_INITIAL_PASS) + #guard agains redefinition + if(";${OPENCV_MODULES_BUILD};${OPENCV_MODULES_DISABLED_USER};" MATCHES ";${the_module};") + message(FATAL_ERROR "Redefinition of the ${the_module} module. + at: ${CMAKE_CURRENT_SOURCE_DIR} + previously defined at: ${OPENCV_MODULE_${the_module}_LOCATION} +") + endif() + + if(NOT DEFINED the_description) + set(the_description "The ${name} OpenCV module") + endif() + + if(NOT DEFINED BUILD_${the_module}_INIT) + set(BUILD_${the_module}_INIT ON) + endif() + + # create option to enable/disable this module + option(BUILD_${the_module} "Include ${the_module} module into the OpenCV build" ${BUILD_${the_module}_INIT}) + + # remember the module details + set(OPENCV_MODULE_${the_module}_DESCRIPTION "${the_description}" CACHE INTERNAL "Brief description of ${the_module} module") + set(OPENCV_MODULE_${the_module}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${the_module} module sources") + + # parse list of dependencies + if("${ARGV1}" STREQUAL "INTERNAL" OR "${ARGV1}" STREQUAL "BINDINGS") + set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The cathegory of the module") + set(__ocv_argn__ ${ARGN}) + list(REMOVE_AT __ocv_argn__ 0) + ocv_add_dependencies(${the_module} ${__ocv_argn__}) + unset(__ocv_argn__) + else() + set(OPENCV_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The cathegory of the module") + ocv_add_dependencies(${the_module} ${ARGN}) + if(BUILD_${the_module}) + set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export") + endif() + endif() + + # add self to the world dependencies + if(NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" OR OPENCV_MODULE_IS_PART_OF_WORLD) + ocv_add_dependencies(opencv_world OPTIONAL ${the_module}) + endif() + + if(BUILD_${the_module}) + set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD} "${the_module}" CACHE INTERNAL "List of OpenCV modules included into the build") + else() + set(OPENCV_MODULES_DISABLED_USER ${OPENCV_MODULES_DISABLED_USER} "${the_module}" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user") + endif() + + # TODO: add submodules if any + + # stop processing of current file + return() + else(OPENCV_INITIAL_PASS) + if(NOT BUILD_${the_module}) + return() # extra protection from redefinition + endif() + project(${the_module}) + endif(OPENCV_INITIAL_PASS) +endmacro() + +# excludes module from current configuration +macro(ocv_module_disable module) + set(__modname ${module}) + if(NOT __modname MATCHES "^opencv_") + set(__modname opencv_${module}) + endif() + list(APPEND OPENCV_MODULES_DISABLED_FORCE "${__modname}") + set(HAVE_${__modname} OFF CACHE INTERNAL "Module ${__modname} can not be built in current configuration") + set(OPENCV_MODULE_${__modname}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${__modname} module sources") + set(OPENCV_MODULES_DISABLED_FORCE "${OPENCV_MODULES_DISABLED_FORCE}" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration") + if(BUILD_${__modname}) + # touch variable controlling build of the module to suppress "unused variable" CMake warning + endif() + unset(__modname) + return() # leave the current folder +endmacro() + + +# Internal macro; partly disables OpenCV module +macro(__ocv_module_turn_off the_module) + list(REMOVE_ITEM OPENCV_MODULES_DISABLED_AUTO "${the_module}") + list(APPEND OPENCV_MODULES_DISABLED_AUTO "${the_module}") + list(REMOVE_ITEM OPENCV_MODULES_BUILD "${the_module}") + list(REMOVE_ITEM OPENCV_MODULES_PUBLIC "${the_module}") + set(HAVE_${the_module} OFF CACHE INTERNAL "Module ${the_module} can not be built in current configuration") +endmacro() + +# Internal macro for dependencies tracking +macro(__ocv_flatten_module_required_dependencies the_module) + set(__flattened_deps "") + set(__resolved_deps "") + set(__req_depends ${OPENCV_MODULE_${the_module}_REQ_DEPS}) + + while(__req_depends) + ocv_list_pop_front(__req_depends __dep) + if(__dep STREQUAL the_module) + __ocv_module_turn_off(${the_module}) # TODO: think how to deal with cyclic dependency + break() + elseif(";${OPENCV_MODULES_DISABLED_USER};${OPENCV_MODULES_DISABLED_AUTO};" MATCHES ";${__dep};") + __ocv_module_turn_off(${the_module}) # depends on disabled module + list(APPEND __flattened_deps "${__dep}") + elseif(";${OPENCV_MODULES_BUILD};" MATCHES ";${__dep};") + if(";${__resolved_deps};" MATCHES ";${__dep};") + list(APPEND __flattened_deps "${__dep}") # all dependencies of this module are already resolved + else() + # put all required subdependencies before this dependency and mark it as resolved + list(APPEND __resolved_deps "${__dep}") + list(INSERT __req_depends 0 ${OPENCV_MODULE_${__dep}_REQ_DEPS} ${__dep}) + endif() + elseif(__dep MATCHES "^opencv_") + __ocv_module_turn_off(${the_module}) # depends on missing module + message(WARNING "Unknown \"${__dep}\" module is listened in the dependencies of \"${the_module}\" module") + break() + else() + # skip non-modules + endif() + endwhile() + + if(__flattened_deps) + list(REMOVE_DUPLICATES __flattened_deps) + set(OPENCV_MODULE_${the_module}_DEPS ${__flattened_deps}) + else() + set(OPENCV_MODULE_${the_module}_DEPS "") + endif() + + ocv_clear_vars(__resolved_deps __flattened_deps __req_depends __dep) +endmacro() + +# Internal macro for dependencies tracking +macro(__ocv_flatten_module_optional_dependencies the_module) + set(__flattened_deps "") + set(__resolved_deps "") + set(__opt_depends ${OPENCV_MODULE_${the_module}_REQ_DEPS} ${OPENCV_MODULE_${the_module}_OPT_DEPS}) + + while(__opt_depends) + ocv_list_pop_front(__opt_depends __dep) + if(__dep STREQUAL the_module) + __ocv_module_turn_off(${the_module}) # TODO: think how to deal with cyclic dependency + break() + elseif(";${OPENCV_MODULES_BUILD};" MATCHES ";${__dep};") + if(";${__resolved_deps};" MATCHES ";${__dep};") + list(APPEND __flattened_deps "${__dep}") # all dependencies of this module are already resolved + else() + # put all subdependencies before this dependency and mark it as resolved + list(APPEND __resolved_deps "${__dep}") + list(INSERT __opt_depends 0 ${OPENCV_MODULE_${__dep}_REQ_DEPS} ${OPENCV_MODULE_${__dep}_OPT_DEPS} ${__dep}) + endif() + else() + # skip non-modules or missing modules + endif() + endwhile() + + if(__flattened_deps) + list(REMOVE_DUPLICATES __flattened_deps) + set(OPENCV_MODULE_${the_module}_DEPS ${__flattened_deps}) + else() + set(OPENCV_MODULE_${the_module}_DEPS "") + endif() + + ocv_clear_vars(__resolved_deps __flattened_deps __opt_depends __dep) +endmacro() + +macro(__ocv_flatten_module_dependencies) + foreach(m ${OPENCV_MODULES_DISABLED_USER}) + set(HAVE_${m} OFF CACHE INTERNAL "Module ${m} will not be built in current configuration") + endforeach() + foreach(m ${OPENCV_MODULES_BUILD}) + set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will be built in current configuration") + __ocv_flatten_module_required_dependencies(${m}) + set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened required dependencies of ${m} module") + endforeach() + + foreach(m ${OPENCV_MODULES_BUILD}) + __ocv_flatten_module_optional_dependencies(${m}) + + # save dependencies from other modules + set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module") + # save extra dependencies + set(OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_REQ_DEPS} ${OPENCV_MODULE_${m}_OPT_DEPS}) + if(OPENCV_MODULE_${m}_DEPS_EXT AND OPENCV_MODULE_${m}_DEPS) + list(REMOVE_ITEM OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_DEPS}) + endif() + ocv_list_filterout(OPENCV_MODULE_${m}_DEPS_EXT "^opencv_[^ ]+$") + set(OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_DEPS_EXT} CACHE INTERNAL "Extra dependencies of ${m} module") + endforeach() + + # order modules by dependencies + set(OPENCV_MODULES_BUILD_ "") + foreach(m ${OPENCV_MODULES_BUILD}) + list(APPEND OPENCV_MODULES_BUILD_ ${OPENCV_MODULE_${m}_DEPS} ${m}) + endforeach() + ocv_list_unique(OPENCV_MODULES_BUILD_) + + set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} CACHE INTERNAL "List of OpenCV modules marked for export") + set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD_} CACHE INTERNAL "List of OpenCV modules included into the build") + set(OPENCV_MODULES_DISABLED_AUTO ${OPENCV_MODULES_DISABLED_AUTO} CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies") +endmacro() + +# collect modules from specified directories +# NB: must be called only once! +macro(ocv_glob_modules) + if(DEFINED OPENCV_INITIAL_PASS) + message(FATAL_ERROR "OpenCV has already loaded its modules. Calling ocv_glob_modules second time is not allowed.") + endif() + set(__directories_observed "") + + # collect modules + set(OPENCV_INITIAL_PASS ON) + foreach(__path ${ARGN}) + ocv_get_real_path(__path "${__path}") + + list(FIND __directories_observed "${__path}" __pathIdx) + if(__pathIdx GREATER -1) + message(FATAL_ERROR "The directory ${__path} is observed for OpenCV modules second time.") + endif() + list(APPEND __directories_observed "${__path}") + + file(GLOB __ocvmodules RELATIVE "${__path}" "${__path}/*") + if(__ocvmodules) + list(SORT __ocvmodules) + foreach(mod ${__ocvmodules}) + ocv_get_real_path(__modpath "${__path}/${mod}") + if(EXISTS "${__modpath}/CMakeLists.txt") + + list(FIND __directories_observed "${__modpath}" __pathIdx) + if(__pathIdx GREATER -1) + message(FATAL_ERROR "The module from ${__modpath} is already loaded.") + endif() + list(APPEND __directories_observed "${__modpath}") + + if(OCV_MODULE_RELOCATE_ON_INITIAL_PASS) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") + file(COPY "${__modpath}/CMakeLists.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") + add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") + if("${OPENCV_MODULE_opencv_${mod}_LOCATION}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") + set(OPENCV_MODULE_opencv_${mod}_LOCATION "${__modpath}" CACHE PATH "" FORCE) + endif() + else() + add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") + endif() + endif() + endforeach() + endif() + endforeach() + ocv_clear_vars(__ocvmodules __directories_observed __path __modpath __pathIdx) + + # resolve dependencies + __ocv_flatten_module_dependencies() + + # create modules + set(OPENCV_INITIAL_PASS OFF PARENT_SCOPE) + set(OPENCV_INITIAL_PASS OFF) + foreach(m ${OPENCV_MODULES_BUILD}) + if(m MATCHES "^opencv_") + string(REGEX REPLACE "^opencv_" "" __shortname "${m}") + add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}") + endif() + endforeach() + unset(__shortname) +endmacro() + +# setup include paths for the list of passed modules +macro(ocv_include_modules) + foreach(d ${ARGN}) + if(d MATCHES "^opencv_" AND HAVE_${d}) + if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include") + ocv_include_directories("${OPENCV_MODULE_${d}_LOCATION}/include") + endif() + elseif(EXISTS "${d}") + ocv_include_directories("${d}") + endif() + endforeach() +endmacro() + +# setup include paths for the list of passed modules and recursively add dependent modules +macro(ocv_include_modules_recurse) + foreach(d ${ARGN}) + if(d MATCHES "^opencv_" AND HAVE_${d}) + if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include") + ocv_include_directories("${OPENCV_MODULE_${d}_LOCATION}/include") + endif() + if(OPENCV_MODULE_${d}_DEPS) + ocv_include_modules_recurse(${OPENCV_MODULE_${d}_DEPS}) + endif() + elseif(EXISTS "${d}") + ocv_include_directories("${d}") + endif() + endforeach() +endmacro() + +# setup include path for OpenCV headers for specified module +# ocv_module_include_directories() +macro(ocv_module_include_directories) + ocv_include_directories("${OPENCV_MODULE_${the_module}_LOCATION}/include" + "${OPENCV_MODULE_${the_module}_LOCATION}/src" + "${CMAKE_CURRENT_BINARY_DIR}" # for precompiled headers + ) + ocv_include_modules(${OPENCV_MODULE_${the_module}_DEPS} ${ARGN}) +endmacro() + + +# sets header and source files for the current module +# NB: all files specified as headers will be installed +# Usage: +# ocv_set_module_sources([HEADERS] [SOURCES] ) +macro(ocv_set_module_sources) + set(OPENCV_MODULE_${the_module}_HEADERS "") + set(OPENCV_MODULE_${the_module}_SOURCES "") + + foreach(f "HEADERS" ${ARGN}) + if(f STREQUAL "HEADERS" OR f STREQUAL "SOURCES") + set(__filesvar "OPENCV_MODULE_${the_module}_${f}") + else() + list(APPEND ${__filesvar} "${f}") + endif() + endforeach() + + # the hacky way to embeed any files into the OpenCV without modification of its build system + if(COMMAND ocv_get_module_external_sources) + ocv_get_module_external_sources() + endif() + + # use full paths for module to be independent from the module location + ocv_convert_to_full_paths(OPENCV_MODULE_${the_module}_HEADERS) + + set(OPENCV_MODULE_${the_module}_HEADERS ${OPENCV_MODULE_${the_module}_HEADERS} CACHE INTERNAL "List of header files for ${the_module}") + set(OPENCV_MODULE_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_SOURCES} CACHE INTERNAL "List of source files for ${the_module}") +endmacro() + +# finds and sets headers and sources for the standard OpenCV module +# Usage: +# ocv_glob_module_sources() +macro(ocv_glob_module_sources) + file(GLOB_RECURSE lib_srcs "src/*.cpp") + file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h") + file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") + file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") + + file(GLOB cl_kernels "src/opencl/*.cl") + + source_group("Src" FILES ${lib_srcs} ${lib_int_hdrs}) + source_group("Include" FILES ${lib_hdrs}) + source_group("Include\\detail" FILES ${lib_hdrs_detail}) + + if(HAVE_OPENCL AND cl_kernels) + ocv_include_directories(${OPENCL_INCLUDE_DIRS}) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/kernels.cpp" + COMMAND ${CMAKE_COMMAND} -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake" + DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake") + source_group("Src\\OpenCL" FILES ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/kernels.cpp") + list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/kernels.cpp") + endif() + + ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail} SOURCES ${lib_srcs} ${lib_int_hdrs}) +endmacro() + +# creates OpenCV module in current folder +# creates new target, configures standard dependencies, compilers flags, install rules +# Usage: +# ocv_create_module() +# ocv_create_module(SKIP_LINK) +macro(ocv_create_module) + add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}) + + if(NOT "${ARGN}" STREQUAL "SKIP_LINK") + target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN}) + if(HAVE_OPENCL AND OPENCL_LIBRARIES) + target_link_libraries(${the_module} ${OPENCL_LIBRARIES}) + endif() + endif() + + add_dependencies(opencv_modules ${the_module}) + + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${the_module} PROPERTIES FOLDER "modules") + endif() + + set_target_properties(${the_module} PROPERTIES + OUTPUT_NAME "${the_module}${OPENCV_DLLVERSION}" + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} + LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} + RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} + INSTALL_NAME_DIR lib + ) + + # For dynamic link numbering convenions + if(NOT ANDROID) + # Android SDK build scripts can include only .so files into final .apk + # As result we should not set version properties for Android + set_target_properties(${the_module} PROPERTIES + VERSION ${OPENCV_LIBVERSION} + SOVERSION ${OPENCV_SOVERSION} + ) + endif() + + if(BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(${the_module} PROPERTIES DEFINE_SYMBOL CVAPI_EXPORTS) + else() + add_definitions(-DCVAPI_EXPORTS) + endif() + endif() + + if(MSVC) + if(CMAKE_CROSSCOMPILING) + set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:secchk") + endif() + set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libc /DEBUG") + endif() + + install(TARGETS ${the_module} + RUNTIME DESTINATION bin COMPONENT main + LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main + ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main + ) + + # only "public" headers need to be installed + if(OPENCV_MODULE_${the_module}_HEADERS AND ";${OPENCV_MODULES_PUBLIC};" MATCHES ";${the_module};") + foreach(hdr ${OPENCV_MODULE_${the_module}_HEADERS}) + string(REGEX REPLACE "^.*opencv2/" "opencv2/" hdr2 "${hdr}") + if(hdr2 MATCHES "^(opencv2/.*)/[^/]+.h(..)?$") + install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT main) + endif() + endforeach() + endif() +endmacro() + +# opencv precompiled headers macro (can add pch to modules and tests) +# this macro must be called after any "add_definitions" commands, otherwise precompiled headers will not work +# Usage: +# ocv_add_precompiled_headers(${the_module}) +macro(ocv_add_precompiled_headers the_target) + if("${the_target}" MATCHES "^opencv_test_.*$") + SET(pch_path "test/test_") + elseif("${the_target}" MATCHES "^opencv_perf_.*$") + SET(pch_path "perf/perf_") + else() + SET(pch_path "src/") + endif() + ocv_add_precompiled_header_to_target(${the_target} "${CMAKE_CURRENT_SOURCE_DIR}/${pch_path}precomp.hpp") + unset(pch_path) +endmacro() + +# short command for adding simple OpenCV module +# see ocv_add_module for argument details +# Usage: +# ocv_define_module(module_name [INTERNAL] [REQUIRED] [] [OPTIONAL ]) +macro(ocv_define_module module_name) + ocv_add_module(${module_name} ${ARGN}) + ocv_glob_module_sources() + ocv_module_include_directories() + ocv_create_module() + ocv_add_precompiled_headers(${the_module}) + + ocv_add_accuracy_tests() + ocv_add_perf_tests() +endmacro() + +# ensures that all passed modules are available +# sets OCV_DEPENDENCIES_FOUND variable to TRUE/FALSE +macro(ocv_check_dependencies) + set(OCV_DEPENDENCIES_FOUND TRUE) + foreach(d ${ARGN}) + if(d MATCHES "^opencv_[^ ]+$" AND NOT HAVE_${d}) + set(OCV_DEPENDENCIES_FOUND FALSE) + break() + endif() + endforeach() +endmacro() + +# auxiliary macro to parse arguments of ocv_add_accuracy_tests and ocv_add_perf_tests commands +macro(__ocv_parse_test_sources tests_type) + set(OPENCV_${tests_type}_${the_module}_SOURCES "") + set(OPENCV_${tests_type}_${the_module}_DEPS "") + set(__file_group_name "") + set(__file_group_sources "") + foreach(arg "DEPENDS_ON" ${ARGN} "FILES") + if(arg STREQUAL "FILES") + set(__currentvar "__file_group_sources") + if(__file_group_name AND __file_group_sources) + source_group("${__file_group_name}" FILES ${__file_group_sources}) + list(APPEND OPENCV_${tests_type}_${the_module}_SOURCES ${__file_group_sources}) + endif() + set(__file_group_name "") + set(__file_group_sources "") + elseif(arg STREQUAL "DEPENDS_ON") + set(__currentvar "OPENCV_TEST_${the_module}_DEPS") + elseif("${__currentvar}" STREQUAL "__file_group_sources" AND NOT __file_group_name) + set(__file_group_name "${arg}") + else() + list(APPEND ${__currentvar} "${arg}") + endif() + endforeach() + unset(__file_group_name) + unset(__file_group_sources) + unset(__currentvar) +endmacro() + +# this is a command for adding OpenCV performance tests to the module +# ocv_add_perf_tests() +function(ocv_add_perf_tests) + set(perf_path "${CMAKE_CURRENT_SOURCE_DIR}/perf") + if(BUILD_PERF_TESTS AND EXISTS "${perf_path}") + __ocv_parse_test_sources(PERF ${ARGN}) + + # opencv_highgui is required for imread/imwrite + set(perf_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_PERF_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS}) + ocv_check_dependencies(${perf_deps}) + + if(OCV_DEPENDENCIES_FOUND) + set(the_target "opencv_perf_${name}") + # project(${the_target}) + + ocv_module_include_directories(${perf_deps} "${perf_path}") + + if(NOT OPENCV_PERF_${the_module}_SOURCES) + file(GLOB perf_srcs "${perf_path}/*.cpp") + file(GLOB perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h") + source_group("Src" FILES ${perf_srcs}) + source_group("Include" FILES ${perf_hdrs}) + set(OPENCV_PERF_${the_module}_SOURCES ${perf_srcs} ${perf_hdrs}) + endif() + + add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES}) + target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${perf_deps} ${OPENCV_LINKER_LIBS}) + add_dependencies(opencv_perf_tests ${the_target}) + + # Additional target properties + set_target_properties(${the_target} PROPERTIES + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + ) + + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${the_target} PROPERTIES FOLDER "tests performance") + endif() + + ocv_add_precompiled_headers(${the_target}) + + else(OCV_DEPENDENCIES_FOUND) + # TODO: warn about unsatisfied dependencies + endif(OCV_DEPENDENCIES_FOUND) + endif() +endfunction() + +# this is a command for adding OpenCV accuracy/regression tests to the module +# ocv_add_accuracy_tests([FILES ] [DEPENDS_ON] ) +function(ocv_add_accuracy_tests) + set(test_path "${CMAKE_CURRENT_SOURCE_DIR}/test") + ocv_check_dependencies(${test_deps}) + if(BUILD_TESTS AND EXISTS "${test_path}") + __ocv_parse_test_sources(TEST ${ARGN}) + + # opencv_highgui is required for imread/imwrite + set(test_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_TEST_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS}) + ocv_check_dependencies(${test_deps}) + + if(OCV_DEPENDENCIES_FOUND) + set(the_target "opencv_test_${name}") + # project(${the_target}) + + ocv_module_include_directories(${test_deps} "${test_path}") + + if(NOT OPENCV_TEST_${the_module}_SOURCES) + file(GLOB test_srcs "${test_path}/*.cpp") + file(GLOB test_hdrs "${test_path}/*.hpp" "${test_path}/*.h") + source_group("Src" FILES ${test_srcs}) + source_group("Include" FILES ${test_hdrs}) + set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs}) + endif() + + add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES}) + target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS}) + add_dependencies(opencv_tests ${the_target}) + + # Additional target properties + set_target_properties(${the_target} PROPERTIES + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + ) + + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${the_target} PROPERTIES FOLDER "tests accuracy") + endif() + + enable_testing() + get_target_property(LOC ${the_target} LOCATION) + add_test(${the_target} "${LOC}") + + ocv_add_precompiled_headers(${the_target}) + else(OCV_DEPENDENCIES_FOUND) + # TODO: warn about unsatisfied dependencies + endif(OCV_DEPENDENCIES_FOUND) + endif() +endfunction() + +# internal macro; finds all link dependencies of the module +# should be used at the end of CMake processing +macro(__ocv_track_module_link_dependencies the_module optkind) + set(${the_module}_MODULE_DEPS_${optkind} "") + set(${the_module}_EXTRA_DEPS_${optkind} "") + + get_target_property(__module_type ${the_module} TYPE) + if(__module_type STREQUAL "STATIC_LIBRARY") + #in case of static library we have to inherit its dependencies (in right order!!!) + if(NOT DEFINED ${the_module}_LIB_DEPENDS_${optkind}) + ocv_split_libs_list(${the_module}_LIB_DEPENDS ${the_module}_LIB_DEPENDS_DBG ${the_module}_LIB_DEPENDS_OPT) + endif() + + set(__resolved_deps "") + set(__mod_depends ${${the_module}_LIB_DEPENDS_${optkind}}) + set(__has_cycle FALSE) + + while(__mod_depends) + list(GET __mod_depends 0 __dep) + list(REMOVE_AT __mod_depends 0) + if(__dep STREQUAL the_module) + set(__has_cycle TRUE) + else()#if("${OPENCV_MODULES_BUILD}" MATCHES "(^|;)${__dep}(;|$)") + ocv_regex_escape(__rdep "${__dep}") + if(__resolved_deps MATCHES "(^|;)${__rdep}(;|$)") + #all dependencies of this module are already resolved + list(APPEND ${the_module}_MODULE_DEPS_${optkind} "${__dep}") + else() + get_target_property(__module_type ${__dep} TYPE) + if(__module_type STREQUAL "STATIC_LIBRARY") + if(NOT DEFINED ${__dep}_LIB_DEPENDS_${optkind}) + ocv_split_libs_list(${__dep}_LIB_DEPENDS ${__dep}_LIB_DEPENDS_DBG ${__dep}_LIB_DEPENDS_OPT) + endif() + list(INSERT __mod_depends 0 ${${__dep}_LIB_DEPENDS_${optkind}} ${__dep}) + list(APPEND __resolved_deps "${__dep}") + elseif(NOT __module_type) + list(APPEND ${the_module}_EXTRA_DEPS_${optkind} "${__dep}") + endif() + endif() + #else() + # get_target_property(__dep_location "${__dep}" LOCATION) + endif() + endwhile() + + ocv_list_unique(${the_module}_MODULE_DEPS_${optkind}) + #ocv_list_reverse(${the_module}_MODULE_DEPS_${optkind}) + ocv_list_unique(${the_module}_EXTRA_DEPS_${optkind}) + #ocv_list_reverse(${the_module}_EXTRA_DEPS_${optkind}) + + if(__has_cycle) + # not sure if it can work + list(APPEND ${the_module}_MODULE_DEPS_${optkind} "${the_module}") + endif() + + unset(__dep_location) + unset(__mod_depends) + unset(__resolved_deps) + unset(__has_cycle) + unset(__rdep) + endif()#STATIC_LIBRARY + unset(__module_type) + + #message("${the_module}_MODULE_DEPS_${optkind}") + #message(" ${${the_module}_MODULE_DEPS_${optkind}}") + #message(" ${OPENCV_MODULE_${the_module}_DEPS}") + #message("") + #message("${the_module}_EXTRA_DEPS_${optkind}") + #message(" ${${the_module}_EXTRA_DEPS_${optkind}}") + #message("") +endmacro() + +# creates lists of build dependencies needed for external projects +macro(ocv_track_build_dependencies) + foreach(m ${OPENCV_MODULES_BUILD}) + __ocv_track_module_link_dependencies("${m}" OPT) + __ocv_track_module_link_dependencies("${m}" DBG) + endforeach() +endmacro() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVPCHSupport.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVPCHSupport.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVPCHSupport.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVPCHSupport.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,350 @@ +# taken from http://public.kitware.com/Bug/view.php?id=1260 and slightly adjusted + +# - Try to find precompiled headers support for GCC 3.4 and 4.x +# Once done this will define: +# +# Variable: +# PCHSupport_FOUND +# +# Macro: +# ADD_PRECOMPILED_HEADER _targetName _input _dowarn +# ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use _dowarn +# ADD_NATIVE_PRECOMPILED_HEADER _targetName _input _dowarn +# GET_NATIVE_PRECOMPILED_HEADER _targetName _input + +IF(CMAKE_COMPILER_IS_GNUCXX) + + EXEC_PROGRAM( + ${CMAKE_CXX_COMPILER} + ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion + OUTPUT_VARIABLE gcc_compiler_version) + #MESSAGE("GCC Version: ${gcc_compiler_version}") + IF(gcc_compiler_version VERSION_GREATER "4.2.-1") + SET(PCHSupport_FOUND TRUE) + ENDIF() + + SET(_PCH_include_prefix "-I") + SET(_PCH_isystem_prefix "-isystem") + +ELSEIF(CMAKE_GENERATOR MATCHES "^Visual.*$") + SET(PCHSupport_FOUND TRUE) + SET(_PCH_include_prefix "/I") + SET(_PCH_isystem_prefix "/I") +ELSE() + SET(PCHSupport_FOUND FALSE) +ENDIF() + +MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) + + STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) + SET(${_out_compile_flags} ${${_flags_var_name}} ) + + IF(CMAKE_COMPILER_IS_GNUCXX) + + GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE) + IF(${_targetType} STREQUAL SHARED_LIBRARY AND NOT WIN32) + LIST(APPEND ${_out_compile_flags} "-fPIC") + ENDIF() + + ELSE() + ## TODO ... ? or does it work out of the box + ENDIF() + + GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES ) + FOREACH(item ${DIRINC}) + if(item MATCHES "^${OpenCV_SOURCE_DIR}/modules/") + LIST(APPEND ${_out_compile_flags} "${_PCH_include_prefix}\"${item}\"") + else() + LIST(APPEND ${_out_compile_flags} "${_PCH_isystem_prefix}\"${item}\"") + endif() + ENDFOREACH(item) + + GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) + GET_DIRECTORY_PROPERTY(_global_definitions DIRECTORY ${OpenCV_SOURCE_DIR} DEFINITIONS) + #MESSAGE("_directory_flags ${_directory_flags} ${_global_definitions}" ) + LIST(APPEND ${_out_compile_flags} ${_directory_flags}) + LIST(APPEND ${_out_compile_flags} ${_global_definitions}) + LIST(APPEND ${_out_compile_flags} ${CMAKE_CXX_FLAGS}) + + SEPARATE_ARGUMENTS(${_out_compile_flags}) + +ENDMACRO(_PCH_GET_COMPILE_FLAGS) + + +MACRO(_PCH_WRITE_PCHDEP_CXX _targetName _include_file _dephelp) + + SET(${_dephelp} ${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch_dephelp.cxx) + IF(CMAKE_HOST_WIN32) + ADD_CUSTOM_COMMAND( + OUTPUT "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "#include \\\"${_include_file}\\\"" > "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "int testfunction();" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "int testfunction()" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo " return 0;" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "}" >> "${${_dephelp}}" + DEPENDS "${_include_file}" + ) + else() + ADD_CUSTOM_COMMAND( + OUTPUT "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "\\#include \\\"${_include_file}\\\"" > "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "int testfunction\\(\\)\\;" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "int testfunction\\(\\)" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo " \\return 0\\;" >> "${${_dephelp}}" + COMMAND ${CMAKE_COMMAND} -E echo "}" >> "${${_dephelp}}" + DEPENDS "${_include_file}" + ) + endif() + +ENDMACRO(_PCH_WRITE_PCHDEP_CXX ) + +MACRO(_PCH_GET_COMPILE_COMMAND out_command _input _output) + + FILE(TO_NATIVE_PATH ${_input} _native_input) + FILE(TO_NATIVE_PATH ${_output} _native_output) + + IF(CMAKE_COMPILER_IS_GNUCXX) + IF(CMAKE_CXX_COMPILER_ARG1) + # remove leading space in compiler argument + STRING(REGEX REPLACE "^ +" "" pchsupport_compiler_cxx_arg1 ${CMAKE_CXX_COMPILER_ARG1}) + + SET(${out_command} + ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input} + ) + ELSE(CMAKE_CXX_COMPILER_ARG1) + SET(${out_command} + ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input} + ) + ENDIF(CMAKE_CXX_COMPILER_ARG1) + ELSE(CMAKE_COMPILER_IS_GNUCXX) + + SET(_dummy_str "#include <${_input}>") + FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pch_dummy.cpp ${_dummy_str}) + + SET(${out_command} + ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} /c /Fp${_native_output} /Yc${_native_input} pch_dummy.cpp + ) + #/out:${_output} + + ENDIF(CMAKE_COMPILER_IS_GNUCXX) + +ENDMACRO(_PCH_GET_COMPILE_COMMAND ) + + +MACRO(_PCH_GET_TARGET_COMPILE_FLAGS _cflags _header_name _pch_path _dowarn ) + + FILE(TO_NATIVE_PATH ${_pch_path} _native_pch_path) + + IF(CMAKE_COMPILER_IS_GNUCXX) + # for use with distcc and gcc >4.0.1 if preprocessed files are accessible + # on all remote machines set + # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess + # if you want warnings for invalid header files (which is very inconvenient + # if you have different versions of the headers for different build types + # you may set _pch_dowarn + IF (_dowarn) + SET(${_cflags} "${PCH_ADDITIONAL_COMPILER_FLAGS} -include \"${CMAKE_CURRENT_BINARY_DIR}/${_header_name}\" -Winvalid-pch " ) + ELSE (_dowarn) + SET(${_cflags} "${PCH_ADDITIONAL_COMPILER_FLAGS} -include \"${CMAKE_CURRENT_BINARY_DIR}/${_header_name}\" " ) + ENDIF (_dowarn) + + ELSE(CMAKE_COMPILER_IS_GNUCXX) + + set(${_cflags} "/Fp${_native_pch_path} /Yu${_header_name}" ) + + ENDIF(CMAKE_COMPILER_IS_GNUCXX) + +ENDMACRO(_PCH_GET_TARGET_COMPILE_FLAGS ) + + +MACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input _output) + + GET_FILENAME_COMPONENT(_name ${_input} NAME) + GET_FILENAME_COMPONENT(_path ${_input} PATH) + SET(${_output} "${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch/${_targetName}_${CMAKE_BUILD_TYPE}.gch") + +ENDMACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input) + + +MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) + + # to do: test whether compiler flags match between target _targetName + # and _pch_output_to_use + GET_FILENAME_COMPONENT(_name ${_input} NAME) + + IF(ARGN STREQUAL "0") + SET(_dowarn 0) + ELSE() + SET(_dowarn 1) + ENDIF() + + _PCH_GET_TARGET_COMPILE_FLAGS(_target_cflags ${_name} ${_pch_output_to_use} ${_dowarn}) + #MESSAGE("Add flags ${_target_cflags} to ${_targetName} " ) + + GET_TARGET_PROPERTY(_sources ${_targetName} SOURCES) + FOREACH(src ${_sources}) + if(NOT "${src}" MATCHES "\\.mm$") + get_source_file_property(_flags "${src}" COMPILE_FLAGS) + if(_flags) + set(_flags "${_flags} ${_target_cflags}") + else() + set(_flags "${_target_cflags}") + endif() + + set_source_files_properties("${src}" PROPERTIES COMPILE_FLAGS "${_flags}") + endif() + ENDFOREACH() + + ADD_CUSTOM_TARGET(pch_Generate_${_targetName} + DEPENDS ${_pch_output_to_use} + ) + + ADD_DEPENDENCIES(${_targetName} pch_Generate_${_targetName} ) + +ENDMACRO(ADD_PRECOMPILED_HEADER_TO_TARGET) + +MACRO(ADD_PRECOMPILED_HEADER _targetName _input) + + SET(_PCH_current_target ${_targetName}) + + IF(NOT CMAKE_BUILD_TYPE) + MESSAGE(FATAL_ERROR + "This is the ADD_PRECOMPILED_HEADER macro. " + "You must set CMAKE_BUILD_TYPE!" + ) + ENDIF() + + IF(ARGN STREQUAL "0") + SET(_dowarn 0) + ELSE() + SET(_dowarn 1) + ENDIF() + + GET_FILENAME_COMPONENT(_name ${_input} NAME) + GET_FILENAME_COMPONENT(_path ${_input} PATH) + GET_PRECOMPILED_HEADER_OUTPUT( ${_targetName} ${_input} _output) + + _PCH_WRITE_PCHDEP_CXX(${_targetName} "${_input}" _pch_dephelp_cxx) + + ADD_LIBRARY(${_targetName}_pch_dephelp STATIC "${_pch_dephelp_cxx}" "${_input}" ) + + set_target_properties(${_targetName}_pch_dephelp PROPERTIES + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + ARCHIVE_OUTPUT_DIRECTORY "${LIBRARY_OUTPUT_PATH}" + ) + + _PCH_GET_COMPILE_FLAGS(_compile_FLAGS) + + #MESSAGE("_compile_FLAGS: ${_compile_FLAGS}") + #message("COMMAND ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input}") + + ADD_CUSTOM_COMMAND( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name}" + COMMAND ${CMAKE_COMMAND} -E copy "${_input}" "${CMAKE_CURRENT_BINARY_DIR}/${_name}" # ensure same directory! Required by gcc + DEPENDS "${_input}" + ) + + #message("_command ${_input} ${_output}") + _PCH_GET_COMPILE_COMMAND(_command ${CMAKE_CURRENT_BINARY_DIR}/${_name} ${_output} ) + + GET_FILENAME_COMPONENT(_outdir ${_output} PATH) + ADD_CUSTOM_COMMAND( + OUTPUT "${_output}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${_outdir}" + COMMAND ${_command} + DEPENDS "${_input}" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_name}" + DEPENDS ${_targetName}_pch_dephelp + ) + + ADD_PRECOMPILED_HEADER_TO_TARGET(${_targetName} ${_input} ${_output} ${_dowarn}) + +ENDMACRO(ADD_PRECOMPILED_HEADER) + + +# Generates the use of precompiled in a target, +# without using depency targets (2 extra for each target) +# Using Visual, must also add ${_targetName}_pch to sources +# Not needed by Xcode + +MACRO(GET_NATIVE_PRECOMPILED_HEADER _targetName _input) + + if(CMAKE_GENERATOR MATCHES "^Visual.*$") + SET(_dummy_str "#include \"${_input}\"\n" +"// This is required to suppress LNK4221. Very annoying.\n" +"void *g_${_targetName}Dummy = 0\;\n") + + # Use of cxx extension for generated files (as Qt does) + SET(${_targetName}_pch ${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch.cxx) + if(EXISTS ${${_targetName}_pch}) + # Check if contents is the same, if not rewrite + # todo + else() + FILE(WRITE ${${_targetName}_pch} ${_dummy_str}) + endif() + endif() + +ENDMACRO(GET_NATIVE_PRECOMPILED_HEADER) + + +MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _input) + + IF(ARGN STREQUAL "0") + SET(_dowarn 0) + ELSE() + SET(_dowarn 1) + ENDIF() + + if(CMAKE_GENERATOR MATCHES "^Visual.*$") + + # Auto include the precompile (useful for moc processing, since the use of + # precompiled is specified at the target level + # and I don't want to specifiy /F- for each moc/res/ui generated files (using Qt) + + GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS) + if (oldProps MATCHES NOTFOUND) + SET(oldProps "") + endif() + + SET(newProperties "${oldProps} /Yu\"${_input}\" /FI\"${_input}\"") + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS "${newProperties}") + + #also inlude ${oldProps} to have the same compile options + SET_SOURCE_FILES_PROPERTIES(${${_targetName}_pch} PROPERTIES COMPILE_FLAGS "${oldProps} /Yc\"${_input}\"") + + elseif (CMAKE_GENERATOR MATCHES Xcode) + + # For Xcode, cmake needs my patch to process + # GCC_PREFIX_HEADER and GCC_PRECOMPILE_PREFIX_HEADER as target properties + + # When buiding out of the tree, precompiled may not be located + # Use full path instead. + GET_FILENAME_COMPONENT(fullPath ${_input} ABSOLUTE) + + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${fullPath}") + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + + else() + + #Fallback to the "old" precompiled suppport + #ADD_PRECOMPILED_HEADER(${_targetName} ${_input} ${_dowarn}) + + endif() + +ENDMACRO(ADD_NATIVE_PRECOMPILED_HEADER) + +macro(ocv_add_precompiled_header_to_target the_target pch_header) + if(PCHSupport_FOUND AND ENABLE_PRECOMPILED_HEADERS AND EXISTS "${pch_header}") + if(CMAKE_GENERATOR MATCHES Visual) + string(REGEX REPLACE "hpp$" "cpp" ${the_target}_pch "${pch_header}") + add_native_precompiled_header(${the_target} ${pch_header}) + unset(${the_target}_pch) + elseif(CMAKE_GENERATOR MATCHES Xcode) + add_native_precompiled_header(${the_target} ${pch_header}) + elseif(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_GENERATOR MATCHES "Makefiles|Ninja") + add_precompiled_header(${the_target} ${pch_header}) + endif() + endif() +endmacro() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVUtils.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVUtils.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVUtils.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVUtils.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,521 @@ +# Search packages for host system instead of packages for target system +# in case of cross compilation thess macro should be defined by toolchain file +if(NOT COMMAND find_host_package) + macro(find_host_package) + find_package(${ARGN}) + endmacro() +endif() +if(NOT COMMAND find_host_program) + macro(find_host_program) + find_program(${ARGN}) + endmacro() +endif() + +# adds include directories in such way that directories from the OpenCV source tree go first +function(ocv_include_directories) + set(__add_before "") + foreach(dir ${ARGN}) + get_filename_component(__abs_dir "${dir}" ABSOLUTE) + if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}") + list(APPEND __add_before "${dir}") + else() + include_directories(AFTER SYSTEM "${dir}") + endif() + endforeach() + include_directories(BEFORE ${__add_before}) +endfunction() + +# clears all passed variables +macro(ocv_clear_vars) + foreach(_var ${ARGN}) + unset(${_var} CACHE) + endforeach() +endmacro() + +set(OCV_COMPILER_FAIL_REGEX + "command line option .* is valid for .* but not for C\\+\\+" # GNU + "command line option .* is valid for .* but not for C" # GNU + "unrecognized .*option" # GNU + "unknown .*option" # Clang + "ignoring unknown option" # MSVC + "warning D9002" # MSVC, any lang + "option .*not supported" # Intel + "[Uu]nknown option" # HP + "[Ww]arning: [Oo]ption" # SunPro + "command option .* is not recognized" # XL + "not supported in this configuration; ignored" # AIX + "File with unknown suffix passed to linker" # PGI + "WARNING: unknown flag:" # Open64 + ) + +MACRO(ocv_check_compiler_flag LANG FLAG RESULT) + if(NOT DEFINED ${RESULT}) + if("_${LANG}_" MATCHES "_CXX_") + set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx") + if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ") + FILE(WRITE "${_fname}" "int main() { return 0; }\n") + else() + FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n") + endif() + elseif("_${LANG}_" MATCHES "_C_") + set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c") + if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ") + FILE(WRITE "${_fname}" "int main(void) { return 0; }\n") + else() + FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n") + endif() + elseif("_${LANG}_" MATCHES "_OBJCXX_") + set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm") + if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ") + FILE(WRITE "${_fname}" "int main() { return 0; }\n") + else() + FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n") + endif() + else() + unset(_fname) + endif() + if(_fname) + MESSAGE(STATUS "Performing Test ${RESULT}") + TRY_COMPILE(${RESULT} + ${CMAKE_BINARY_DIR} + "${_fname}" + COMPILE_DEFINITIONS "${FLAG}" + OUTPUT_VARIABLE OUTPUT) + + FOREACH(_regex ${OCV_COMPILER_FAIL_REGEX}) + IF("${OUTPUT}" MATCHES "${_regex}") + SET(${RESULT} 0) + break() + ENDIF() + ENDFOREACH() + + IF(${RESULT}) + SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}") + MESSAGE(STATUS "Performing Test ${RESULT} - Success") + ELSE(${RESULT}) + MESSAGE(STATUS "Performing Test ${RESULT} - Failed") + SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}") + ENDIF(${RESULT}) + else() + SET(${RESULT} 0) + endif() + endif() +ENDMACRO() + +macro(ocv_check_flag_support lang flag varname) + if("_${lang}_" MATCHES "_CXX_") + set(_lang CXX) + elseif("_${lang}_" MATCHES "_C_") + set(_lang C) + elseif("_${lang}_" MATCHES "_OBJCXX_") + set(_lang OBJCXX) + else() + set(_lang ${lang}) + endif() + + string(TOUPPER "${flag}" ${varname}) + string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}") + string(REGEX REPLACE " -|-|=| |\\." "_" ${varname} "${${varname}}") + + ocv_check_compiler_flag("${_lang}" "${ARGN} ${flag}" ${${varname}}) +endmacro() + +# turns off warnings +macro(ocv_warnings_disable) + if(NOT ENABLE_NOISY_WARNINGS) + set(_flag_vars "") + set(_msvc_warnings "") + set(_gxx_warnings "") + foreach(arg ${ARGN}) + if(arg MATCHES "^CMAKE_") + list(APPEND _flag_vars ${arg}) + elseif(arg MATCHES "^/wd") + list(APPEND _msvc_warnings ${arg}) + elseif(arg MATCHES "^-W") + list(APPEND _gxx_warnings ${arg}) + endif() + endforeach() + if(MSVC AND _msvc_warnings AND _flag_vars) + foreach(var ${_flag_vars}) + foreach(warning ${_msvc_warnings}) + set(${var} "${${var}} ${warning}") + endforeach() + endforeach() + elseif((CMAKE_COMPILER_IS_GNUCXX OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars) + foreach(var ${_flag_vars}) + foreach(warning ${_gxx_warnings}) + if(NOT warning MATCHES "^-Wno-") + string(REPLACE "${warning}" "" ${var} "${${var}}") + string(REPLACE "-W" "-Wno-" warning "${warning}") + endif() + ocv_check_flag_support(${var} "${warning}" _varname) + if(${_varname}) + set(${var} "${${var}} ${warning}") + endif() + endforeach() + endforeach() + endif() + unset(_flag_vars) + unset(_msvc_warnings) + unset(_gxx_warnings) + endif(NOT ENABLE_NOISY_WARNINGS) +endmacro() + +# Provides an option that the user can optionally select. +# Can accept condition to control when option is available for user. +# Usage: +# option( "help string describing the option" [IF ]) +macro(OCV_OPTION variable description value) + set(__value ${value}) + set(__condition "") + set(__varname "__value") + foreach(arg ${ARGN}) + if(arg STREQUAL "IF" OR arg STREQUAL "if") + set(__varname "__condition") + else() + list(APPEND ${__varname} ${arg}) + endif() + endforeach() + unset(__varname) + if("${__condition}" STREQUAL "") + set(__condition 2 GREATER 1) + endif() + + if(${__condition}) + if("${__value}" MATCHES ";") + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + elseif(DEFINED ${__value}) + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + else() + option(${variable} "${description}" ${__value}) + endif() + else() + unset(${variable} CACHE) + endif() + unset(__condition) + unset(__value) +endmacro() + + +# Macros that checks if module have been installed. +# After it adds module to build and define +# constants passed as second arg +macro(CHECK_MODULE module_name define) + set(${define} 0) + if(PKG_CONFIG_FOUND) + set(ALIAS ALIASOF_${module_name}) + set(ALIAS_FOUND ${ALIAS}_FOUND) + set(ALIAS_INCLUDE_DIRS ${ALIAS}_INCLUDE_DIRS) + set(ALIAS_LIBRARY_DIRS ${ALIAS}_LIBRARY_DIRS) + set(ALIAS_LIBRARIES ${ALIAS}_LIBRARIES) + + PKG_CHECK_MODULES(${ALIAS} ${module_name}) + + if(${ALIAS_FOUND}) + set(${define} 1) + foreach(P "${ALIAS_INCLUDE_DIRS}") + if(${P}) + list(APPEND HIGHGUI_INCLUDE_DIRS ${${P}}) + endif() + endforeach() + + foreach(P "${ALIAS_LIBRARY_DIRS}") + if(${P}) + list(APPEND HIGHGUI_LIBRARY_DIRS ${${P}}) + endif() + endforeach() + + list(APPEND HIGHGUI_LIBRARIES ${${ALIAS_LIBRARIES}}) + endif() + endif() +endmacro() + + +set(OPENCV_BUILD_INFO_FILE "${OpenCV_BINARY_DIR}/version_string.tmp") +file(REMOVE "${OPENCV_BUILD_INFO_FILE}") +function(ocv_output_status msg) + message(STATUS "${msg}") + string(REPLACE "\\" "\\\\" msg "${msg}") + string(REPLACE "\"" "\\\"" msg "${msg}") + file(APPEND "${OPENCV_BUILD_INFO_FILE}" "\"${msg}\\n\"\n") +endfunction() + +macro(ocv_finalize_status) + if(NOT OPENCV_SKIP_STATUS_FINALIZATION) + if(TARGET opencv_core) + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET) + endif() + endif() +endmacro() + + +# Status report function. +# Automatically align right column and selects text based on condition. +# Usage: +# status() +# status( [ ...]) +# status( THEN ELSE ) +function(status text) + set(status_cond) + set(status_then) + set(status_else) + + set(status_current_name "cond") + foreach(arg ${ARGN}) + if(arg STREQUAL "THEN") + set(status_current_name "then") + elseif(arg STREQUAL "ELSE") + set(status_current_name "else") + else() + list(APPEND status_${status_current_name} ${arg}) + endif() + endforeach() + + if(DEFINED status_cond) + set(status_placeholder_length 32) + string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder) + string(LENGTH "${text}" status_text_length) + if(status_text_length LESS status_placeholder_length) + string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text) + elseif(DEFINED status_then OR DEFINED status_else) + ocv_output_status("${text}") + set(status_text "${status_placeholder}") + else() + set(status_text "${text}") + endif() + + if(DEFINED status_then OR DEFINED status_else) + if(${status_cond}) + string(REPLACE ";" " " status_then "${status_then}") + string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}") + ocv_output_status("${status_text} ${status_then}") + else() + string(REPLACE ";" " " status_else "${status_else}") + string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}") + ocv_output_status("${status_text} ${status_else}") + endif() + else() + string(REPLACE ";" " " status_cond "${status_cond}") + string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}") + ocv_output_status("${status_text} ${status_cond}") + endif() + else() + ocv_output_status("${text}") + endif() +endfunction() + + +# splits cmake libraries list of format "general;item1;debug;item2;release;item3" to two lists +macro(ocv_split_libs_list lst lstdbg lstopt) + set(${lstdbg} "") + set(${lstopt} "") + set(perv_keyword "") + foreach(word ${${lst}}) + if(word STREQUAL "debug" OR word STREQUAL "optimized") + set(perv_keyword ${word}) + elseif(word STREQUAL "general") + set(perv_keyword "") + elseif(perv_keyword STREQUAL "debug") + list(APPEND ${lstdbg} "${word}") + set(perv_keyword "") + elseif(perv_keyword STREQUAL "optimized") + list(APPEND ${lstopt} "${word}") + set(perv_keyword "") + else() + list(APPEND ${lstdbg} "${word}") + list(APPEND ${lstopt} "${word}") + set(perv_keyword "") + endif() + endforeach() +endmacro() + + +# remove all matching elements from the list +macro(ocv_list_filterout lst regex) + foreach(item ${${lst}}) + if(item MATCHES "${regex}") + list(REMOVE_ITEM ${lst} "${item}") + endif() + endforeach() +endmacro() + + +# stable & safe duplicates removal macro +macro(ocv_list_unique __lst) + if(${__lst}) + list(REMOVE_DUPLICATES ${__lst}) + endif() +endmacro() + + +# safe list reversal macro +macro(ocv_list_reverse __lst) + if(${__lst}) + list(REVERSE ${__lst}) + endif() +endmacro() + + +# safe list sorting macro +macro(ocv_list_sort __lst) + if(${__lst}) + list(SORT ${__lst}) + endif() +endmacro() + + +# add prefix to each item in the list +macro(ocv_list_add_prefix LST PREFIX) + set(__tmp "") + foreach(item ${${LST}}) + list(APPEND __tmp "${PREFIX}${item}") + endforeach() + set(${LST} ${__tmp}) + unset(__tmp) +endmacro() + + +# add suffix to each item in the list +macro(ocv_list_add_suffix LST SUFFIX) + set(__tmp "") + foreach(item ${${LST}}) + list(APPEND __tmp "${item}${SUFFIX}") + endforeach() + set(${LST} ${__tmp}) + unset(__tmp) +endmacro() + + +# gets and removes the first element from list +macro(ocv_list_pop_front LST VAR) + if(${LST}) + list(GET ${LST} 0 ${VAR}) + list(REMOVE_AT ${LST} 0) + else() + set(${VAR} "") + endif() +endmacro() + + +# simple regex escaping routine (does not cover all cases!!!) +macro(ocv_regex_escape var regex) + string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}") +endmacro() + + +# get absolute path with symlinks resolved +macro(ocv_get_real_path VAR PATHSTR) + if(CMAKE_VERSION VERSION_LESS 2.8) + get_filename_component(${VAR} "${PATHSTR}" ABSOLUTE) + else() + get_filename_component(${VAR} "${PATHSTR}" REALPATH) + endif() +endmacro() + + +# convert list of paths to full paths +macro(ocv_convert_to_full_paths VAR) + if(${VAR}) + set(__tmp "") + foreach(path ${${VAR}}) + get_filename_component(${VAR} "${path}" ABSOLUTE) + list(APPEND __tmp "${${VAR}}") + endforeach() + set(${VAR} ${__tmp}) + unset(__tmp) + endif() +endmacro() + + +# read set of version defines from the header file +macro(ocv_parse_header FILENAME FILE_VAR) + set(vars_regex "") + set(__parnet_scope OFF) + set(__add_cache OFF) + foreach(name ${ARGN}) + if("${name}" STREQUAL "PARENT_SCOPE") + set(__parnet_scope ON) + elseif("${name}" STREQUAL "CACHE") + set(__add_cache ON) + elseif(vars_regex) + set(vars_regex "${vars_regex}|${name}") + else() + set(vars_regex "${name}") + endif() + endforeach() + if(EXISTS "${FILENAME}") + file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" ) + else() + unset(${FILE_VAR}) + endif() + foreach(name ${ARGN}) + if(NOT "${name}" STREQUAL "PARENT_SCOPE" AND NOT "${name}" STREQUAL "CACHE") + if(${FILE_VAR}) + if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*") + string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}") + else() + set(${name} "") + endif() + if(__add_cache) + set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE) + elseif(__parnet_scope) + set(${name} "${${name}}" PARENT_SCOPE) + endif() + else() + unset(${name} CACHE) + endif() + endif() + endforeach() +endmacro() + +# read single version define from the header file +macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME) + ocv_clear_vars(${LIBNAME}_VERSION_MAJOR + ${LIBNAME}_VERSION_MAJOR + ${LIBNAME}_VERSION_MINOR + ${LIBNAME}_VERSION_PATCH + ${LIBNAME}_VERSION_TWEAK + ${LIBNAME}_VERSION_STRING) + set(${LIBNAME}_H "") + if(EXISTS "${HDR_PATH}") + file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1) + endif() + + if(${LIBNAME}_H) + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}") + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR "${${LIBNAME}_H}") + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}") + set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN}) + set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN}) + set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN}) + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}") + + # append a TWEAK version if it exists: + set(${LIBNAME}_VERSION_TWEAK "") + if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$") + set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN}) + endif() + if(${LIBNAME}_VERSION_TWEAK) + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN}) + else() + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN}) + endif() + endif() +endmacro() + + +################################################################################################ +# short command to setup source group +function(ocv_source_group group) + cmake_parse_arguments(OCV_SOURCE_GROUP "" "" "GLOB" ${ARGN}) + file(GLOB srcs ${OCV_SOURCE_GROUP_GLOB}) + source_group(${group} FILES ${srcs}) +endfunction() \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVVersion.cmake diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVVersion.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/OpenCVVersion.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/OpenCVVersion.cmake 2013-05-05 19:02:00.000000000 +0000 @@ -0,0 +1,19 @@ +SET(OPENCV_VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/core/include/opencv2/core/version.hpp") +FILE(STRINGS "${OPENCV_VERSION_FILE}" OPENCV_VERSION_PARTS REGEX "#define CV_VERSION_[A-Z]+[ ]+[0-9]+" ) + +string(REGEX REPLACE ".+CV_VERSION_EPOCH[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MAJOR "${OPENCV_VERSION_PARTS}") +string(REGEX REPLACE ".+CV_VERSION_MAJOR[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_MINOR "${OPENCV_VERSION_PARTS}") +string(REGEX REPLACE ".+CV_VERSION_MINOR[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_PATCH "${OPENCV_VERSION_PARTS}") +string(REGEX REPLACE ".+CV_VERSION_REVISION[ ]+([0-9]+).*" "\\1" OPENCV_VERSION_TWEAK "${OPENCV_VERSION_PARTS}") + +set(OPENCV_VERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}") +if(OPENCV_VERSION_TWEAK GREATER 0) + set(OPENCV_VERSION "${OPENCV_VERSION}.${OPENCV_VERSION_TWEAK}") +endif() + +set(OPENCV_SOVERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}") +set(OPENCV_LIBVERSION "${OPENCV_VERSION_MAJOR}.${OPENCV_VERSION_MINOR}.${OPENCV_VERSION_PATCH}") + +# create a dependency on version file +# we never use output of the following command but cmake will rerun automatically if the version file changes +configure_file("${OPENCV_VERSION_FILE}" "${CMAKE_BINARY_DIR}/junk/version.junk" COPYONLY) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/checks/OpenCVDetectCudaArch.cu diffimg-2.0.0/3rdparty/opencv/cmake/checks/OpenCVDetectCudaArch.cu --- diffimg-1.5.0/3rdparty/opencv/cmake/checks/OpenCVDetectCudaArch.cu 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/checks/OpenCVDetectCudaArch.cu 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,14 @@ +#include +int main() +{ + int count = 0; + if (cudaSuccess != cudaGetDeviceCount(&count)){return -1;} + if (count == 0) {return -1;} + for (int device = 0; device < count; ++device) + { + cudaDeviceProp prop; + if (cudaSuccess != cudaGetDeviceProperties(&prop, device)){ continue;} + printf("%d.%d ", prop.major, prop.minor); + } + return 0; +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/checks/vfwtest.cpp diffimg-2.0.0/3rdparty/opencv/cmake/checks/vfwtest.cpp --- diffimg-1.5.0/3rdparty/opencv/cmake/checks/vfwtest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/checks/vfwtest.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,10 @@ + +#include +#include + +int main() +{ + AVIFileInit(); + AVIFileExit(); + return 0; +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/checks/win32uitest.cpp diffimg-2.0.0/3rdparty/opencv/cmake/checks/win32uitest.cpp --- diffimg-1.5.0/3rdparty/opencv/cmake/checks/win32uitest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/checks/win32uitest.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,11 @@ +#include + +int main(int argc, char** argv) +{ + CreateWindow(NULL /*lpClassName*/, NULL /*lpWindowName*/, 0 /*dwStyle*/, 0 /*x*/, + 0 /*y*/, 0 /*nWidth*/, 0 /*nHeight*/, NULL /*hWndParent*/, NULL /*hMenu*/, + NULL /*hInstance*/, NULL /*lpParam*/); + DeleteDC(NULL); + + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/cl2cpp.cmake diffimg-2.0.0/3rdparty/opencv/cmake/cl2cpp.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/cl2cpp.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/cl2cpp.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,35 @@ +file(GLOB cl_list "${CL_DIR}/*.cl" ) + +file(WRITE ${OUTPUT} "// This file is auto-generated. Do not edit! + +namespace cv +{ +namespace ocl +{ +") + +foreach(cl ${cl_list}) + get_filename_component(cl_filename "${cl}" NAME_WE) + #message("${cl_filename}") + + file(READ "${cl}" lines) + + string(REPLACE "\r" "" lines "${lines}\n") + string(REPLACE "\t" " " lines "${lines}") + + string(REGEX REPLACE "/\\*([^*]/|\\*[^/]|[^*/])*\\*/" "" lines "${lines}") # multiline comments + string(REGEX REPLACE "/\\*([^\n])*\\*/" "" lines "${lines}") # single-line comments + string(REGEX REPLACE "[ ]*//[^\n]*\n" "\n" lines "${lines}") # single-line comments + string(REGEX REPLACE "\n[ ]*(\n[ ]*)*" "\n" lines "${lines}") # empty lines & leading whitespace + string(REGEX REPLACE "^\n" "" lines "${lines}") # leading new line + + string(REPLACE "\\" "\\\\" lines "${lines}") + string(REPLACE "\"" "\\\"" lines "${lines}") + string(REPLACE "\n" "\\n\"\n\"" lines "${lines}") + + string(REGEX REPLACE "\"$" "" lines "${lines}") # unneeded " at the eof + + file(APPEND ${OUTPUT} "const char* ${cl_filename}=\"${lines};\n") +endforeach() + +file(APPEND ${OUTPUT} "}\n}\n") \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCV.mk.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCV.mk.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCV.mk.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCV.mk.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,132 @@ +# In order to compile your application under cygwin +# you might need to define NDK_USE_CYGPATH=1 before calling the ndk-build + +USER_LOCAL_PATH:=$(LOCAL_PATH) +LOCAL_PATH:=$(subst ?,,$(firstword ?$(subst \, ,$(subst /, ,$(call my-dir))))) + +OPENCV_TARGET_ARCH_ABI:=$(TARGET_ARCH_ABI) +OPENCV_THIS_DIR:=$(patsubst $(LOCAL_PATH)\\%,%,$(patsubst $(LOCAL_PATH)/%,%,$(call my-dir))) +OPENCV_MK_DIR:=$(dir $(lastword $(MAKEFILE_LIST))) +OPENCV_LIBS_DIR:=@OPENCV_LIBS_DIR_CONFIGCMAKE@ +OPENCV_3RDPARTY_LIBS_DIR:=@OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE@ +OPENCV_BASEDIR:=@OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE@ +OPENCV_LOCAL_C_INCLUDES:=@OPENCV_INCLUDE_DIRS_CONFIGCMAKE@ +OPENCV_MODULES:=@OPENCV_MODULES_CONFIGMAKE@ + +ifeq ($(OPENCV_LIB_TYPE),) + OPENCV_LIB_TYPE:=@OPENCV_LIBTYPE_CONFIGMAKE@ +endif + +ifeq ($(OPENCV_LIB_TYPE),SHARED) + OPENCV_LIBS:=@OPENCV_LIBS_CONFIGMAKE@ + OPENCV_LIB_TYPE:=@OPENCV_LIBTYPE_CONFIGMAKE@ +else + OPENCV_LIBS:=$(OPENCV_MODULES) + OPENCV_LIB_TYPE:=@OPENCV_STATIC_LIBTYPE_CONFIGMAKE@ +endif + +ifeq ($(OPENCV_LIB_TYPE),SHARED) + OPENCV_3RDPARTY_COMPONENTS:= + OPENCV_EXTRA_COMPONENTS:= +else + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),x86) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),armeabi) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),mips) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif +endif + +ifeq (${OPENCV_CAMERA_MODULES},on) + ifeq ($(TARGET_ARCH_ABI),armeabi) + OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_ARMEABI_CONFIGCMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_ARMEABI_V7A_CONFIGCMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),x86) + OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_X86_CONFIGCMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),mips) + OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_MIPS_CONFIGCMAKE@ + endif +else + OPENCV_CAMERA_MODULES:= +endif + +ifeq ($(OPENCV_LIB_TYPE),SHARED) + OPENCV_LIB_SUFFIX:=so +else + OPENCV_LIB_SUFFIX:=a + OPENCV_INSTALL_MODULES:=on +endif + +define add_opencv_module + include $(CLEAR_VARS) + LOCAL_MODULE:=opencv_$1 + LOCAL_SRC_FILES:=$(OPENCV_LIBS_DIR)/libopencv_$1.$(OPENCV_LIB_SUFFIX) + include $(PREBUILT_$(OPENCV_LIB_TYPE)_LIBRARY) +endef + +define add_opencv_3rdparty_component + include $(CLEAR_VARS) + LOCAL_MODULE:=$1 + LOCAL_SRC_FILES:=$(OPENCV_3RDPARTY_LIBS_DIR)/lib$1.a + include $(PREBUILT_STATIC_LIBRARY) +endef + +define add_opencv_camera_module + include $(CLEAR_VARS) + LOCAL_MODULE:=$1 + LOCAL_SRC_FILES:=$(OPENCV_LIBS_DIR)/lib$1.so + include $(PREBUILT_SHARED_LIBRARY) +endef + +ifeq ($(OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED),) + ifeq ($(OPENCV_INSTALL_MODULES),on) + $(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module)))) + endif + + $(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module)))) + $(foreach module,$(OPENCV_CAMERA_MODULES),$(eval $(call add_opencv_camera_module,$(module)))) + + ifneq ($(OPENCV_BASEDIR),) + OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include) + endif + + #turn off module installation to prevent their redefinition + OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED:=on +endif + +ifeq ($(OPENCV_LOCAL_CFLAGS),) + OPENCV_LOCAL_CFLAGS := -fPIC -DANDROID -fsigned-char +endif + +include $(CLEAR_VARS) +LOCAL_C_INCLUDES += $(OPENCV_LOCAL_C_INCLUDES) +LOCAL_CFLAGS += $(OPENCV_LOCAL_CFLAGS) + +ifeq ($(OPENCV_INSTALL_MODULES),on) + LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(foreach mod, $(OPENCV_LIBS), opencv_$(mod)) +else + LOCAL_LDLIBS += -L$(call host-path,$(LOCAL_PATH)/$(OPENCV_LIBS_DIR)) $(foreach lib, $(OPENCV_LIBS), -lopencv_$(lib)) +endif + +ifeq ($(OPENCV_LIB_TYPE),STATIC) + LOCAL_STATIC_LIBRARIES += $(OPENCV_3RDPARTY_COMPONENTS) +endif + +LOCAL_LDLIBS += $(foreach lib,$(OPENCV_EXTRA_COMPONENTS), -l$(lib)) + +#restore the LOCAL_PATH +LOCAL_PATH:=$(USER_LOCAL_PATH) diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCVConfig-version.cmake.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCVConfig-version.cmake.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCVConfig-version.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCVConfig-version.cmake.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,14 @@ +set(OpenCV_VERSION @OPENCV_VERSION@) +set(PACKAGE_VERSION ${OpenCV_VERSION}) + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if(PACKAGE_FIND_VERSION VERSION_LESS PACKAGE_VERSION) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCVConfig.cmake.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCVConfig.cmake.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/OpenCVConfig.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/OpenCVConfig.cmake.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,315 @@ +# =================================================================================== +# The OpenCV CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# FIND_PACKAGE(OpenCV REQUIRED) +# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ${OpenCV_LIBS}) +# +# Or you can search for specific OpenCV modules: +# +# FIND_PACKAGE(OpenCV REQUIRED core highgui) +# +# If the module is found then OPENCV__FOUND is set to TRUE. +# +# This file will define the following variables: +# - OpenCV_LIBS : The list of libraries to links against. +# - OpenCV_LIB_DIR : The directory(es) where lib files are. Calling LINK_DIRECTORIES +# with this path is NOT needed. +# - OpenCV_INCLUDE_DIRS : The OpenCV include directories. +# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability +# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API +# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION@" +# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@" +# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@" +# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION: "@OPENCV_VERSION_PATCH@" +# - OpenCV_VERSION_TWEAK : Tweak version part of OpenCV_VERSION: "@OPENCV_VERSION_TWEAK@" +# +# Advanced variables: +# - OpenCV_SHARED +# - OpenCV_CONFIG_PATH +# - OpenCV_INSTALL_PATH (not set on Windows) +# - OpenCV_LIB_COMPONENTS +# - OpenCV_USE_MANGLED_PATHS +# - OpenCV_HAVE_ANDROID_CAMERA +# +# =================================================================================== + +# Version Compute Capability from which OpenCV has been compiled is remembered +set(OpenCV_COMPUTE_CAPABILITIES @OpenCV_CUDA_CC_CONFIGCMAKE@) + +set(OpenCV_CUDA_VERSION @OpenCV_CUDA_VERSION@) +set(OpenCV_USE_CUBLAS @HAVE_CUBLAS@) +set(OpenCV_USE_CUFFT @HAVE_CUFFT@) +set(OpenCV_USE_NVCUVID @HAVE_NVCUVID@) + +# Android API level from which OpenCV has been compiled is remembered +set(OpenCV_ANDROID_NATIVE_API_LEVEL @OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE@) + +# Some additional settings are required if OpenCV is built as static libs +set(OpenCV_SHARED @BUILD_SHARED_LIBS@) + +# Enables mangled install paths, that help with side by side installs +set(OpenCV_USE_MANGLED_PATHS @OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE@) + +# Extract the directory where *this* file has been installed (determined at cmake run-time) +get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE) + +if(NOT WIN32 OR OpenCV_ANDROID_NATIVE_API_LEVEL GREATER 0) + if(OpenCV_ANDROID_NATIVE_API_LEVEL GREATER 0) + set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../../..") + else() + set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../..") + endif() + # Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings + if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8) + get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" ABSOLUTE) + else() + get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" REALPATH) + endif() +endif() + +# Presence of Android native camera wrappers +set(OpenCV_HAVE_ANDROID_CAMERA @HAVE_opencv_androidcamera@) + +# ====================================================== +# Include directories to add to the user project: +# ====================================================== + +# Provide the include directories to the caller +set(OpenCV_INCLUDE_DIRS @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@) +include_directories(${OpenCV_INCLUDE_DIRS}) + +# ====================================================== +# Link directories to add to the user project: +# ====================================================== + +# Provide the libs directories to the caller +set(OpenCV_LIB_DIR_OPT @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release OpenCV libraries are located") +set(OpenCV_LIB_DIR_DBG @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug OpenCV libraries are located") +set(OpenCV_3RDPARTY_LIB_DIR_OPT @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release 3rdpaty OpenCV dependencies are located") +set(OpenCV_3RDPARTY_LIB_DIR_DBG @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug 3rdpaty OpenCV dependencies are located") +mark_as_advanced(FORCE OpenCV_LIB_DIR_OPT OpenCV_LIB_DIR_DBG OpenCV_3RDPARTY_LIB_DIR_OPT OpenCV_3RDPARTY_LIB_DIR_DBG OpenCV_CONFIG_PATH) + +# ====================================================== +# Version variables: +# ====================================================== +SET(OpenCV_VERSION @OPENCV_VERSION@) +SET(OpenCV_VERSION_MAJOR @OPENCV_VERSION_MAJOR@) +SET(OpenCV_VERSION_MINOR @OPENCV_VERSION_MINOR@) +SET(OpenCV_VERSION_PATCH @OPENCV_VERSION_PATCH@) +SET(OpenCV_VERSION_TWEAK @OPENCV_VERSION_TWEAK@) + +# ==================================================================== +# Link libraries: e.g. libopencv_core.so, opencv_imgproc220d.lib, etc... +# ==================================================================== + +SET(OpenCV_LIB_COMPONENTS @OPENCV_MODULES_CONFIGCMAKE@) + +@OPENCV_DEPENDENCIES_MAP_OPT@ + +@OPENCV_DEPENDENCIES_MAP_DBG@ + +# ============================================================== +# Extra include directories, needed by OpenCV 2 new structure +# ============================================================== +SET(OpenCV2_INCLUDE_DIRS @OpenCV2_INCLUDE_DIRS_CONFIGCMAKE@) +if(OpenCV2_INCLUDE_DIRS) + include_directories(${OpenCV2_INCLUDE_DIRS}) + list(APPEND OpenCV_INCLUDE_DIRS ${OpenCV2_INCLUDE_DIRS}) + + set(OpenCV_ADD_DEBUG_RELEASE @OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE@) + if(OpenCV_ADD_DEBUG_RELEASE) + set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_DIR_OPT}/Release") + set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_DIR_DBG}/Debug") + set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_3RDPARTY_LIB_DIR_OPT}/Release") + set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_3RDPARTY_LIB_DIR_DBG}/Debug") + endif() +endif() + +# ============================================================== +# Check OpenCV availability +# ============================================================== +if(ANDROID AND OpenCV_ANDROID_NATIVE_API_LEVEL GREATER ANDROID_NATIVE_API_LEVEL) + message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") + #always FATAL_ERROR because we can't say to the caller that OpenCV is not found + #http://www.mail-archive.com/cmake@cmake.org/msg37831.html + if(OpenCV_FIND_REQUIRED) + message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") + elseif(NOT OpenCV_FIND_QUIETLY) + message(WARNING "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") + endif() + set(OpenCV_FOUND "OpenCV_FOUND-NOTFOUND") + return()#Android toolchain requires CMake > 2.6 +endif() + +# ============================================================== +# Form list of modules (components) to find +# ============================================================== +if(NOT OpenCV_FIND_COMPONENTS) + set(OpenCV_FIND_COMPONENTS ${OpenCV_LIB_COMPONENTS}) + list(REMOVE_ITEM OpenCV_FIND_COMPONENTS opencv_java) + if(GTest_FOUND OR GTEST_FOUND) + list(REMOVE_ITEM OpenCV_FIND_COMPONENTS opencv_ts) + endif() +endif() + +# expand short module names and see if requested components exist +set(OpenCV_FIND_COMPONENTS_ "") +foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) + if(NOT __cvcomponent MATCHES "^opencv_") + set(__cvcomponent opencv_${__cvcomponent}) + endif() + list(FIND OpenCV_LIB_COMPONENTS ${__cvcomponent} __cvcomponentIdx) + if(__cvcomponentIdx LESS 0) + #requested component is not found... + if(OpenCV_FIND_REQUIRED) + message(FATAL_ERROR "${__cvcomponent} is required but was not found") + elseif(NOT OpenCV_FIND_QUIETLY) + message(WARNING "${__cvcomponent} is required but was not found") + endif() + #indicate that module is NOT found + string(TOUPPER "${__cvcomponent}" __cvcomponent) + set(${__cvcomponent}_FOUND "${__cvcomponent}_FOUND-NOTFOUND") + else() + list(APPEND OpenCV_FIND_COMPONENTS_ ${__cvcomponent}) + #indicate that module is found + string(TOUPPER "${__cvcomponent}" __cvcomponent) + set(${__cvcomponent}_FOUND 1) + endif() +endforeach() +set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_}) + +# ============================================================== +# Resolve dependencies +# ============================================================== +if(OpenCV_USE_MANGLED_PATHS) + set(OpenCV_LIB_SUFFIX ".${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH}") +else() + set(OpenCV_LIB_SUFFIX "") +endif() + +foreach(__opttype OPT DBG) + SET(OpenCV_LIBS_${__opttype} "") + SET(OpenCV_EXTRA_LIBS_${__opttype} "") + foreach(__cvlib ${OpenCV_FIND_COMPONENTS}) + foreach(__cvdep ${OpenCV_${__cvlib}_DEPS_${__opttype}}) + if(__cvdep MATCHES "^opencv_") + list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}${OpenCV_LIB_SUFFIX}") + #indicate that this module is also found + string(TOUPPER "${__cvdep}" __cvdep) + set(${__cvdep}_FOUND 1) + elseif(EXISTS "${OpenCV_3RDPARTY_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}") + list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_3RDPARTY_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}") + endif() + endforeach() + list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_LIB_DIR_${__opttype}}/${OpenCV_${__cvlib}_LIBNAME_${__opttype}}${OpenCV_LIB_SUFFIX}") + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${OpenCV_${__cvlib}_EXTRA_DEPS_${__opttype}}) + endforeach() + + if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 2.4) + if(OpenCV_LIBS_${__opttype}) + list(REMOVE_DUPLICATES OpenCV_LIBS_${__opttype}) + endif() + if(OpenCV_EXTRA_LIBS_${__opttype}) + list(REMOVE_DUPLICATES OpenCV_EXTRA_LIBS_${__opttype}) + endif() + else() + #TODO: duplicates are annoying but they should not be the problem + endif() + + # CUDA + if(OpenCV_CUDA_VERSION AND (CMAKE_CROSSCOMPILING OR (WIN32 AND NOT OpenCV_SHARED))) + if(NOT CUDA_FOUND) + find_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED) + else() + if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION) + message(FATAL_ERROR "OpenCV static library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}") + endif() + endif() + + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) + + if(OpenCV_USE_CUBLAS) + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUBLAS_LIBRARIES}) + endif() + + if(OpenCV_USE_CUFFT) + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUFFT_LIBRARIES}) + endif() + + if(OpenCV_USE_NVCUVID) + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvid_LIBRARIES}) + endif() + + if(WIN32) + list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvenc_LIBRARIES}) + endif() + endif() +endforeach() + +if(OpenCV_LIBS_DBG) + list(REVERSE OpenCV_LIBS_DBG) +endif() + +if(OpenCV_LIBS_OPT) + list(REVERSE OpenCV_LIBS_OPT) +endif() + +# CMake>=2.6 supports the notation "debug XXd optimized XX" +if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 2.4) + # Modern CMake: + SET(OpenCV_LIBS "") + foreach(__cvlib ${OpenCV_LIBS_DBG} ${OpenCV_EXTRA_LIBS_DBG}) + list(APPEND OpenCV_LIBS debug "${__cvlib}") + endforeach() + foreach(__cvlib ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT}) + list(APPEND OpenCV_LIBS optimized "${__cvlib}") + endforeach() +else() + # Old CMake: + if(CMAKE_BUILD_TYPE MATCHES "Debug") + SET(OpenCV_LIBS ${OpenCV_LIBS_DBG} ${OpenCV_EXTRA_LIBS_DBG}) + else() + SET(OpenCV_LIBS ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT}) + endif() +endif() + +# ============================================================== +# Android camera helper macro +# ============================================================== +if(OpenCV_HAVE_ANDROID_CAMERA) + macro(COPY_NATIVE_CAMERA_LIBS target) + get_target_property(target_location ${target} LOCATION) + get_filename_component(target_location "${target_location}" PATH) + file(GLOB camera_wrappers "${OpenCV_LIB_DIR_OPT}/libnative_camera_r*.so") + foreach(wrapper ${camera_wrappers}) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${target_location}" + ) + endforeach() + endmacro() +endif() + +# ============================================================== +# Compatibility stuff +# ============================================================== +if(CMAKE_BUILD_TYPE MATCHES "Debug") + SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_DBG} ${OpenCV_3RDPARTY_LIB_DIR_DBG}) +else() + SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_OPT} ${OpenCV_3RDPARTY_LIB_DIR_OPT}) +endif() +set(OpenCV_LIBRARIES ${OpenCV_LIBS}) + +if(CMAKE_CROSSCOMPILING AND OpenCV_SHARED AND (CMAKE_SYSTEM_NAME MATCHES "Linux")) + foreach(dir ${OpenCV_LIB_DIR}) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${dir}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath-link,${dir}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-rpath-link,${dir}") + endforeach() +endif() diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/cmake_uninstall.cmake.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/cmake_uninstall.cmake.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/cmake_uninstall.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/cmake_uninstall.cmake.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,27 @@ +# ----------------------------------------------- +# File that provides "make uninstall" target +# We use the file 'install_manifest.txt' +# ----------------------------------------------- +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) + + diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/cvconfig.h.cmake diffimg-2.0.0/3rdparty/opencv/cmake/templates/cvconfig.h.cmake --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/cvconfig.h.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/cvconfig.h.cmake 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,230 @@ +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#cmakedefine CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#cmakedefine C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#cmakedefine HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#cmakedefine HAVE_ALLOCA_H 1 + +/* Video for Windows support */ +#cmakedefine HAVE_VFW + +/* V4L capturing support */ +#cmakedefine HAVE_CAMV4L + +/* V4L2 capturing support */ +#cmakedefine HAVE_CAMV4L2 + +/* V4L2 capturing support in videoio.h */ +#cmakedefine HAVE_VIDEOIO + +/* V4L/V4L2 capturing support via libv4l */ +#cmakedefine HAVE_LIBV4L + +/* Carbon windowing environment */ +#cmakedefine HAVE_CARBON + +/* IEEE1394 capturing support */ +#cmakedefine HAVE_DC1394 + +/* libdc1394 0.9.4 or 0.9.5 */ +#cmakedefine HAVE_DC1394_095 + +/* IEEE1394 capturing support - libdc1394 v2.x */ +#cmakedefine HAVE_DC1394_2 + +/* ffmpeg in Gentoo */ +#cmakedefine HAVE_GENTOO_FFMPEG + +/* FFMpeg video library */ +#cmakedefine HAVE_FFMPEG + +/* FFMpeg version flag */ +#cmakedefine NEW_FFMPEG + +/* ffmpeg's libswscale */ +#cmakedefine HAVE_FFMPEG_SWSCALE + +/* GStreamer multimedia framework */ +#cmakedefine HAVE_GSTREAMER + +/* GTK+ 2.0 Thread support */ +#cmakedefine HAVE_GTHREAD + +/* Win32 UI */ +#cmakedefine HAVE_WIN32UI + +/* GTK+ 2.x toolkit */ +#cmakedefine HAVE_GTK + +/* OpenEXR codec */ +#cmakedefine HAVE_ILMIMF + +/* Apple ImageIO Framework */ +#cmakedefine HAVE_IMAGEIO + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* JPEG-2000 codec */ +#cmakedefine HAVE_JASPER + +/* IJG JPEG codec */ +#cmakedefine HAVE_JPEG + +/* Define to 1 if you have the `dl' library (-ldl). */ +#cmakedefine HAVE_LIBDL 1 + +/* Define to 1 if you have the `gomp' library (-lgomp). */ +#cmakedefine HAVE_LIBGOMP 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#cmakedefine HAVE_LIBM 1 + +/* libpng/png.h needs to be included */ +#cmakedefine HAVE_LIBPNG_PNG_H + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#cmakedefine HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `lrint' function. */ +#cmakedefine HAVE_LRINT 1 + +/* PNG codec */ +#cmakedefine HAVE_PNG + +/* Define to 1 if you have the `png_get_valid' function. */ +#cmakedefine HAVE_PNG_GET_VALID 1 + +/* png.h needs to be included */ +#cmakedefine HAVE_PNG_H + +/* Define to 1 if you have the `png_set_tRNS_to_alpha' function. */ +#cmakedefine HAVE_PNG_SET_TRNS_TO_ALPHA 1 + +/* QuickTime video libraries */ +#cmakedefine HAVE_QUICKTIME + +/* AVFoundation video libraries */ +#cmakedefine HAVE_AVFOUNDATION + +/* TIFF codec */ +#cmakedefine HAVE_TIFF + +/* Unicap video capture library */ +#cmakedefine HAVE_UNICAP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Xine video library */ +#cmakedefine HAVE_XINE + +/* OpenNI library */ +#cmakedefine HAVE_OPENNI + +/* LZ77 compression/decompression library (used for PNG) */ +#cmakedefine HAVE_ZLIB + +/* Intel Integrated Performance Primitives */ +#cmakedefine HAVE_IPP + +/* OpenCV compiled as static or dynamic libs */ +#cmakedefine BUILD_SHARED_LIBS + +/* Name of package */ +#define PACKAGE "${PACKAGE}" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "${PACKAGE_NAME}" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "${PACKAGE_STRING}" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "${PACKAGE_TARNAME}" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "${PACKAGE_VERSION}" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#cmakedefine STACK_DIRECTION + +/* Version number of package */ +#define VERSION "${PACKAGE_VERSION}" + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#cmakedefine WORDS_BIGENDIAN + +/* Intel Threading Building Blocks */ +#cmakedefine HAVE_TBB + +/* C= */ +#cmakedefine HAVE_CSTRIPES + +/* Eigen Matrix & Linear Algebra Library */ +#cmakedefine HAVE_EIGEN + +/* NVidia Cuda Runtime API*/ +#cmakedefine HAVE_CUDA + +/* NVidia Cuda Fast Fourier Transform (FFT) API*/ +#cmakedefine HAVE_CUFFT + +/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/ +#cmakedefine HAVE_CUBLAS + +/* NVidia Video Decoding API*/ +#cmakedefine HAVE_NVCUVID + +/* Compile for 'real' NVIDIA GPU architectures */ +#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}" + +/* Compile for 'virtual' NVIDIA PTX architectures */ +#define CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX}" + +/* NVIDIA GPU features are used */ +#define CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES}" + +/* Create PTX or BIN for 1.0 compute capability */ +#cmakedefine CUDA_ARCH_BIN_OR_PTX_10 + +/* OpenCL Support */ +#cmakedefine HAVE_OPENCL + +/* AMD's OpenCL Fast Fourier Transform Library*/ +#cmakedefine HAVE_CLAMDFFT + +/* AMD's Basic Linear Algebra Subprograms Library*/ +#cmakedefine HAVE_CLAMDBLAS + +/* DirectShow Video Capture library */ +#cmakedefine HAVE_DSHOW + +/* Microsoft Media Foundation Capture library */ +#cmakedefine HAVE_MSMF + +/* XIMEA camera support */ +#cmakedefine HAVE_XIMEA + +/* OpenGL support*/ +#cmakedefine HAVE_OPENGL + +/* Clp support */ +#cmakedefine HAVE_CLP diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/opencv-XXX.pc.cmake.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/opencv-XXX.pc.cmake.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/opencv-XXX.pc.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/opencv-XXX.pc.cmake.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir_old=@includedir@/opencv +includedir_new=@includedir@ + +Name: OpenCV +Description: Open Source Computer Vision Library +Version: @VERSION@ +Libs: @OpenCV_LIB_COMPONENTS@ +Cflags: -I${includedir_old} -I${includedir_new} diff -Nru diffimg-1.5.0/3rdparty/opencv/cmake/templates/opencv_modules.hpp.in diffimg-2.0.0/3rdparty/opencv/cmake/templates/opencv_modules.hpp.in --- diffimg-1.5.0/3rdparty/opencv/cmake/templates/opencv_modules.hpp.in 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cmake/templates/opencv_modules.hpp.in 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,9 @@ +/* + * ** File generated automatically, do not modify ** + * + * This file defines the list of modules available in current build configuration + * + * +*/ + +@OPENCV_MODULE_DEFINITIONS_CONFIGMAKE@ \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/core/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/core/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,27 @@ +set(the_description "The Core Functionality") +ocv_add_module(core ${ZLIB_LIBRARIES}) +ocv_module_include_directories(${ZLIB_INCLUDE_DIR}) + +if(HAVE_CUDA) + ocv_source_group("Src\\Cuda" GLOB "src/cuda/*.cu") + ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include" ${CUDA_INCLUDE_DIRS}) + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) + + file(GLOB lib_cuda "src/cuda/*.cu") + ocv_cuda_compile(cuda_objs ${lib_cuda}) + + set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) +else() + set(lib_cuda "") + set(cuda_objs "") + set(cuda_link_libs "") +endif() + +ocv_glob_module_sources(SOURCES ${lib_cuda} ${cuda_objs} "${opencv_core_BINARY_DIR}/version_string.inc") + +ocv_create_module(${cuda_link_libs}) +ocv_add_precompiled_headers(${the_module}) + +ocv_add_accuracy_tests() +ocv_add_perf_tests() + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/core.pro diffimg-2.0.0/3rdparty/opencv/core/core.pro --- diffimg-1.5.0/3rdparty/opencv/core/core.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/core.pro 2013-05-06 13:21:42.000000000 +0000 @@ -0,0 +1,17 @@ + + +OPENCV_ROOT = $${PWD}/.. + +TEMPLATE = lib +TARGET = opencv_core + +#DESTDIR = $${QWT_ROOT}/lib + +CONFIG += staticlib + +HEADERS += include/opencv2/core/*.hpp + + +SOURCES += src/*.cpp + +INCLUDEPATH += ./include ./ ../ ../3rdparty/zlib \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/basic_structures.rst diffimg-2.0.0/3rdparty/opencv/core/doc/basic_structures.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/basic_structures.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/basic_structures.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2569 @@ +Basic Structures +================ + +.. highlight:: cpp + +DataType +-------- +.. ocv:class:: DataType + +Template "trait" class for OpenCV primitive data types. A primitive OpenCV data type is one of ``unsigned char``, ``bool``, ``signed char``, ``unsigned short``, ``signed short``, ``int``, ``float``, ``double``, or a tuple of values of one of these types, where all the values in the tuple have the same type. Any primitive type from the list can be defined by an identifier in the form ``CV_{U|S|F}C()``, for example: ``uchar`` ~ ``CV_8UC1``, 3-element floating-point tuple ~ ``CV_32FC3``, and so on. A universal OpenCV structure that is able to store a single instance of such a primitive data type is +:ocv:class:`Vec`. Multiple instances of such a type can be stored in a ``std::vector``, ``Mat``, ``Mat_``, ``SparseMat``, ``SparseMat_``, or any other container that is able to store ``Vec`` instances. + +The ``DataType`` class is basically used to provide a description of such primitive data types without adding any fields or methods to the corresponding classes (and it is actually impossible to add anything to primitive C/C++ data types). This technique is known in C++ as class traits. It is not ``DataType`` itself that is used but its specialized versions, such as: :: + + template<> class DataType + { + typedef uchar value_type; + typedef int work_type; + typedef uchar channel_type; + enum { channel_type = CV_8U, channels = 1, fmt='u', type = CV_8U }; + }; + ... + template DataType > + { + typedef std::complex<_Tp> value_type; + typedef std::complex<_Tp> work_type; + typedef _Tp channel_type; + // DataDepth is another helper trait class + enum { depth = DataDepth<_Tp>::value, channels=2, + fmt=(channels-1)*256+DataDepth<_Tp>::fmt, + type=CV_MAKETYPE(depth, channels) }; + }; + ... + +The main purpose of this class is to convert compilation-time type information to an OpenCV-compatible data type identifier, for example: :: + + // allocates a 30x40 floating-point matrix + Mat A(30, 40, DataType::type); + + Mat B = Mat_ >(3, 3); + // the statement below will print 6, 2 /*, that is depth == CV_64F, channels == 2 */ + cout << B.depth() << ", " << B.channels() << endl; + + +So, such traits are used to tell OpenCV which data type you are working with, even if such a type is not native to OpenCV. For example, the matrix ``B`` initialization above is compiled because OpenCV defines the proper specialized template class ``DataType >`` . This mechanism is also useful (and used in OpenCV this way) for generic algorithms implementations. + + +Point\_ +------- +.. ocv:class:: Point_ + +Template class for 2D points specified by its coordinates +:math:`x` and +:math:`y` . +An instance of the class is interchangeable with C structures, ``CvPoint`` and ``CvPoint2D32f`` . There is also a cast operator to convert point coordinates to the specified type. The conversion from floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion uses this +operation for each of the coordinates. Besides the class members listed in the declaration above, the following operations on points are implemented: :: + + pt1 = pt2 + pt3; + pt1 = pt2 - pt3; + pt1 = pt2 * a; + pt1 = a * pt2; + pt1 += pt2; + pt1 -= pt2; + pt1 *= a; + double value = norm(pt); // L2 norm + pt1 == pt2; + pt1 != pt2; + +For your convenience, the following type aliases are defined: :: + + typedef Point_ Point2i; + typedef Point2i Point; + typedef Point_ Point2f; + typedef Point_ Point2d; + +Example: :: + + Point2f a(0.3f, 0.f), b(0.f, 0.4f); + Point pt = (a + b)*10.f; + cout << pt.x << ", " << pt.y << endl; + + +Point3\_ +-------- +.. ocv:class:: Point3_ + +Template class for 3D points specified by its coordinates +:math:`x`, +:math:`y` and +:math:`z` . +An instance of the class is interchangeable with the C structure ``CvPoint2D32f`` . Similarly to ``Point_`` , the coordinates of 3D points can be converted to another type. The vector arithmetic and comparison operations are also supported. + +The following ``Point3_<>`` aliases are available: :: + + typedef Point3_ Point3i; + typedef Point3_ Point3f; + typedef Point3_ Point3d; + +Size\_ +------ +.. ocv:class:: Size_ + +Template class for specifying the size of an image or rectangle. The class includes two members called ``width`` and ``height``. The structure can be converted to and from the old OpenCV structures +``CvSize`` and ``CvSize2D32f`` . The same set of arithmetic and comparison operations as for ``Point_`` is available. + +OpenCV defines the following ``Size_<>`` aliases: :: + + typedef Size_ Size2i; + typedef Size2i Size; + typedef Size_ Size2f; + +Rect\_ +------ +.. ocv:class:: Rect_ + +Template class for 2D rectangles, described by the following parameters: + +* Coordinates of the top-left corner. This is a default interpretation of ``Rect_::x`` and ``Rect_::y`` in OpenCV. Though, in your algorithms you may count ``x`` and ``y`` from the bottom-left corner. +* Rectangle width and height. + +OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the right and bottom boundaries are not. For example, the method ``Rect_::contains`` returns ``true`` if + +.. math:: + + x \leq pt.x < x+width, + y \leq pt.y < y+height + +Virtually every loop over an image +ROI in OpenCV (where ROI is specified by ``Rect_`` ) is implemented as: :: + + for(int y = roi.y; y < roi.y + rect.height; y++) + for(int x = roi.x; x < roi.x + rect.width; x++) + { + // ... + } + + +In addition to the class members, the following operations on rectangles are implemented: + +* + :math:`\texttt{rect} = \texttt{rect} \pm \texttt{point}` (shifting a rectangle by a certain offset) + +* + :math:`\texttt{rect} = \texttt{rect} \pm \texttt{size}` (expanding or shrinking a rectangle by a certain amount) + +* ``rect += point, rect -= point, rect += size, rect -= size`` (augmenting operations) + +* ``rect = rect1 & rect2`` (rectangle intersection) + +* ``rect = rect1 | rect2`` (minimum area rectangle containing ``rect2`` and ``rect3`` ) + +* ``rect &= rect1, rect |= rect1`` (and the corresponding augmenting operations) + +* ``rect == rect1, rect != rect1`` (rectangle comparison) + +This is an example how the partial ordering on rectangles can be established (rect1 +:math:`\subseteq` rect2): :: + + template inline bool + operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2) + { + return (r1 & r2) == r1; + } + + +For your convenience, the ``Rect_<>`` alias is available: :: + + typedef Rect_ Rect; + +RotatedRect +----------- +.. ocv:class:: RotatedRect + +The class represents rotated (i.e. not up-right) rectangles on a plane. Each rectangle is specified by the center point (mass center), length of each side (represented by cv::Size2f structure) and the rotation angle in degrees. + + .. ocv:function:: RotatedRect::RotatedRect() + .. ocv:function:: RotatedRect::RotatedRect(const Point2f& center, const Size2f& size, float angle) + .. ocv:function:: RotatedRect::RotatedRect(const CvBox2D& box) + + :param center: The rectangle mass center. + :param size: Width and height of the rectangle. + :param angle: The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle. + :param box: The rotated rectangle parameters as the obsolete CvBox2D structure. + + .. ocv:function:: void RotatedRect::points( Point2f pts[] ) const + .. ocv:function:: Rect RotatedRect::boundingRect() const + .. ocv:function:: RotatedRect::operator CvBox2D() const + + :param pts: The points array for storing rectangle vertices. + +The sample below demonstrates how to use RotatedRect: + +:: + + Mat image(200, 200, CV_8UC3, Scalar(0)); + RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30); + + Point2f vertices[4]; + rRect.points(vertices); + for (int i = 0; i < 4; i++) + line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0)); + + Rect brect = rRect.boundingRect(); + rectangle(image, brect, Scalar(255,0,0)); + + imshow("rectangles", image); + waitKey(0); + +.. image:: pics/rotatedrect.png + +.. seealso:: + + :ocv:func:`CamShift` , + :ocv:func:`fitEllipse` , + :ocv:func:`minAreaRect` , + :ocv:struct:`CvBox2D` + +TermCriteria +------------ +.. ocv:class:: TermCriteria + + The class defining termination criteria for iterative algorithms. You can initialize it by default constructor and then override any parameters, or the structure may be fully initialized using the advanced variant of the constructor. + +TermCriteria::TermCriteria +-------------------------- +The constructors. + +.. ocv:function:: TermCriteria::TermCriteria() + +.. ocv:function:: TermCriteria::TermCriteria(int type, int maxCount, double epsilon) + +.. ocv:function:: TermCriteria::TermCriteria(const CvTermCriteria& criteria) + + :param type: The type of termination criteria: ``TermCriteria::COUNT``, ``TermCriteria::EPS`` or ``TermCriteria::COUNT`` + ``TermCriteria::EPS``. + + :param maxCount: The maximum number of iterations or elements to compute. + + :param epsilon: The desired accuracy or change in parameters at which the iterative algorithm stops. + + :param criteria: Termination criteria in the deprecated ``CvTermCriteria`` format. + +TermCriteria::operator CvTermCriteria +------------------------------------- +Converts to the deprecated ``CvTermCriteria`` format. + +.. ocv:function:: TermCriteria::operator CvTermCriteria() const + +Matx +---- +.. ocv:class:: Matx + +Template class for small matrices whose type and size are known at compilation time: :: + + template class Matx {...}; + + typedef Matx Matx12f; + typedef Matx Matx12d; + ... + typedef Matx Matx16f; + typedef Matx Matx16d; + + typedef Matx Matx21f; + typedef Matx Matx21d; + ... + typedef Matx Matx61f; + typedef Matx Matx61d; + + typedef Matx Matx22f; + typedef Matx Matx22d; + ... + typedef Matx Matx66f; + typedef Matx Matx66d; + +If you need a more flexible type, use :ocv:class:`Mat` . The elements of the matrix ``M`` are accessible using the ``M(i,j)`` notation. Most of the common matrix operations (see also +:ref:`MatrixExpressions` ) are available. To do an operation on ``Matx`` that is not implemented, you can easily convert the matrix to +``Mat`` and backwards. :: + + Matx33f m(1, 2, 3, + 4, 5, 6, + 7, 8, 9); + cout << sum(Mat(m*m.t())) << endl; + + +Vec +--- +.. ocv:class:: Vec + +Template class for short numerical vectors, a partial case of :ocv:class:`Matx`: :: + + template class Vec : public Matx<_Tp, n, 1> {...}; + + typedef Vec Vec2b; + typedef Vec Vec3b; + typedef Vec Vec4b; + + typedef Vec Vec2s; + typedef Vec Vec3s; + typedef Vec Vec4s; + + typedef Vec Vec2i; + typedef Vec Vec3i; + typedef Vec Vec4i; + + typedef Vec Vec2f; + typedef Vec Vec3f; + typedef Vec Vec4f; + typedef Vec Vec6f; + + typedef Vec Vec2d; + typedef Vec Vec3d; + typedef Vec Vec4d; + typedef Vec Vec6d; + +It is possible to convert ``Vec`` to/from ``Point_``, ``Vec`` to/from ``Point3_`` , and ``Vec`` to :ocv:struct:`CvScalar` or :ocv:class:`Scalar_`. Use ``operator[]`` to access the elements of ``Vec``. + +All the expected vector operations are also implemented: + +* ``v1 = v2 + v3`` +* ``v1 = v2 - v3`` +* ``v1 = v2 * scale`` +* ``v1 = scale * v2`` +* ``v1 = -v2`` +* ``v1 += v2`` and other augmenting operations +* ``v1 == v2, v1 != v2`` +* ``norm(v1)`` (euclidean norm) + +The ``Vec`` class is commonly used to describe pixel types of multi-channel arrays. See :ocv:class:`Mat` for details. + +Scalar\_ +-------- +.. ocv:class:: Scalar_ + +Template class for a 4-element vector derived from Vec. :: + + template class Scalar_ : public Vec<_Tp, 4> { ... }; + + typedef Scalar_ Scalar; + +Being derived from ``Vec<_Tp, 4>`` , ``Scalar_`` and ``Scalar`` can be used just as typical 4-element vectors. In addition, they can be converted to/from ``CvScalar`` . The type ``Scalar`` is widely used in OpenCV to pass pixel values. + +Range +----- +.. ocv:class:: Range + +Template class specifying a continuous subsequence (slice) of a sequence. :: + + class Range + { + public: + ... + int start, end; + }; + +The class is used to specify a row or a column span in a matrix ( +:ocv:class:`Mat` ) and for many other purposes. ``Range(a,b)`` is basically the same as ``a:b`` in Matlab or ``a..b`` in Python. As in Python, ``start`` is an inclusive left boundary of the range and ``end`` is an exclusive right boundary of the range. Such a half-opened interval is usually denoted as +:math:`[start,end)` . + +The static method ``Range::all()`` returns a special variable that means "the whole sequence" or "the whole range", just like " ``:`` " in Matlab or " ``...`` " in Python. All the methods and functions in OpenCV that take ``Range`` support this special ``Range::all()`` value. But, of course, in case of your own custom processing, you will probably have to check and handle it explicitly: :: + + void my_function(..., const Range& r, ....) + { + if(r == Range::all()) { + // process all the data + } + else { + // process [r.start, r.end) + } + } + + +.. _Ptr: + +Ptr +--- +.. ocv:class:: Ptr + +Template class for smart reference-counting pointers :: + + template class Ptr + { + public: + // default constructor + Ptr(); + // constructor that wraps the object pointer + Ptr(_Tp* _obj); + // destructor: calls release() + ~Ptr(); + // copy constructor; increments ptr's reference counter + Ptr(const Ptr& ptr); + // assignment operator; decrements own reference counter + // (with release()) and increments ptr's reference counter + Ptr& operator = (const Ptr& ptr); + // increments reference counter + void addref(); + // decrements reference counter; when it becomes 0, + // delete_obj() is called + void release(); + // user-specified custom object deletion operation. + // by default, "delete obj;" is called + void delete_obj(); + // returns true if obj == 0; + bool empty() const; + + // provide access to the object fields and methods + _Tp* operator -> (); + const _Tp* operator -> () const; + + // return the underlying object pointer; + // thanks to the methods, the Ptr<_Tp> can be + // used instead of _Tp* + operator _Tp* (); + operator const _Tp*() const; + protected: + // the encapsulated object pointer + _Tp* obj; + // the associated reference counter + int* refcount; + }; + + +The ``Ptr<_Tp>`` class is a template class that wraps pointers of the corresponding type. It is +similar to ``shared_ptr`` that is part of the Boost library +(http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/shared_ptr.htm) and also part of the +`C++0x `_ standard. + +This class provides the following options: + +* + Default constructor, copy constructor, and assignment operator for an arbitrary C++ class + or a C structure. For some objects, like files, windows, mutexes, sockets, and others, a copy + constructor or an assignment operator are difficult to define. For some other objects, like + complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally, + some of complex OpenCV and your own data structures may be written in C. + However, copy constructors and default constructors can simplify programming a lot.Besides, + they are often required (for example, by STL containers). By wrapping a pointer to such a + complex object ``TObj`` to ``Ptr``, you automatically get all of the necessary + constructors and the assignment operator. + +* + *O(1)* complexity of the above-mentioned operations. While some structures, like ``std::vector``, + provide a copy constructor and an assignment operator, the operations may take a considerable + amount of time if the data structures are large. But if the structures are put into ``Ptr<>``, + the overhead is small and independent of the data size. + +* + Automatic destruction, even for C structures. See the example below with ``FILE*``. + +* + Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers + can store only objects of the same type and the same size. The classical solution to store objects + of different types in the same container is to store pointers to the base class ``base_class_t*`` + instead but then you loose the automatic memory management. Again, by using ``Ptr()`` + instead of the raw pointers, you can solve the problem. + +The ``Ptr`` class treats the wrapped object as a black box. The reference counter is allocated and +managed separately. The only thing the pointer class needs to know about the object is how to +deallocate it. This knowledge is encapsulated in the ``Ptr::delete_obj()`` method that is called when +the reference counter becomes 0. If the object is a C++ class instance, no additional coding is +needed, because the default implementation of this method calls ``delete obj;``. However, if the +object is deallocated in a different way, the specialized method should be created. For example, +if you want to wrap ``FILE``, the ``delete_obj`` may be implemented as follows: :: + + template<> inline void Ptr::delete_obj() + { + fclose(obj); // no need to clear the pointer afterwards, + // it is done externally. + } + ... + + // now use it: + Ptr f(fopen("myfile.txt", "r")); + if(f.empty()) + throw ...; + fprintf(f, ....); + ... + // the file will be closed automatically by the Ptr destructor. + + +.. note:: The reference increment/decrement operations are implemented as atomic operations, + and therefore it is normally safe to use the classes in multi-threaded applications. + The same is true for :ocv:class:`Mat` and other C++ OpenCV classes that operate on + the reference counters. + +Ptr::Ptr +-------- +Various Ptr constructors. + +.. ocv:function:: Ptr::Ptr() +.. ocv:function:: Ptr::Ptr(_Tp* _obj) +.. ocv:function:: Ptr::Ptr(const Ptr& ptr) + +Ptr::~Ptr +--------- +The Ptr destructor. + +.. ocv:function:: Ptr::~Ptr() + +Ptr::operator = +---------------- +Assignment operator. + +.. ocv:function:: Ptr& Ptr::operator = (const Ptr& ptr) + +Decrements own reference counter (with ``release()``) and increments ptr's reference counter. + +Ptr::addref +----------- +Increments reference counter. + +.. ocv:function:: void Ptr::addref() + +Ptr::release +------------ +Decrements reference counter; when it becomes 0, ``delete_obj()`` is called. + +.. ocv:function:: void Ptr::release() + +Ptr::delete_obj +--------------- +User-specified custom object deletion operation. By default, ``delete obj;`` is called. + +.. ocv:function:: void Ptr::delete_obj() + +Ptr::empty +---------- +Returns true if obj == 0; + +bool empty() const; + +Ptr::operator -> +---------------- +Provide access to the object fields and methods. + + .. ocv:function:: template _Tp* Ptr::operator -> () + .. ocv:function:: template const _Tp* Ptr::operator -> () const + + +Ptr::operator _Tp* +------------------ +Returns the underlying object pointer. Thanks to the methods, the ``Ptr<_Tp>`` can be used instead +of ``_Tp*``. + + .. ocv:function:: template Ptr::operator _Tp* () + .. ocv:function:: template Ptr::operator const _Tp*() const + + +Mat +--- +.. ocv:class:: Mat + +OpenCV C++ n-dimensional dense array class :: + + class CV_EXPORTS Mat + { + public: + // ... a lot of methods ... + ... + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the array dimensionality, >= 2 + int dims; + //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions + int rows, cols; + //! pointer to the data + uchar* data; + + //! pointer to the reference counter; + // when array points to user-allocated data, the pointer is NULL + int* refcount; + + // other members + ... + }; + + +The class ``Mat`` represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a ``SparseMat`` ). The data layout of the array +:math:`M` is defined by the array ``M.step[]``, so that the address of element +:math:`(i_0,...,i_{M.dims-1})`, where +:math:`0\leq i_k= M.step[i+1]`` (in fact, ``M.step[i] >= M.step[i+1]*M.size[i+1]`` ). This means that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, and so on. ``M.step[M.dims-1]`` is minimal and always equal to the element size ``M.elemSize()`` . + +So, the data layout in ``Mat`` is fully compatible with ``CvMat``, ``IplImage``, and ``CvMatND`` types from OpenCV 1.x. It is also compatible with the majority of dense array types from the standard toolkits and SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this compatibility, it is possible to make a ``Mat`` header for user-allocated data and process it in-place using OpenCV functions. + +There are many different ways to create a ``Mat`` object. The most popular options are listed below: + +* + + Use the ``create(nrows, ncols, type)`` method or the similar ``Mat(nrows, ncols, type[, fillValue])`` constructor. A new array of the specified size and type is allocated. ``type`` has the same meaning as in the ``cvCreateMat`` method. + For example, ``CV_8UC1`` means a 8-bit single-channel array, ``CV_32FC2`` means a 2-channel (complex) floating-point array, and so on. + + :: + + // make a 7x7 complex matrix filled with 1+3j. + Mat M(7,7,CV_32FC2,Scalar(1,3)); + // and now turn M to a 100x60 15-channel 8-bit matrix. + // The old content will be deallocated + M.create(100,60,CV_8UC(15)); + + .. + + As noted in the introduction to this chapter, ``create()`` allocates only a new array when the shape or type of the current array are different from the specified ones. + +* + + Create a multi-dimensional array: + + :: + + // create a 100x100x100 8-bit array + int sz[] = {100, 100, 100}; + Mat bigCube(3, sz, CV_8U, Scalar::all(0)); + + .. + + It passes the number of dimensions =1 to the ``Mat`` constructor but the created array will be 2-dimensional with the number of columns set to 1. So, ``Mat::dims`` is always >= 2 (can also be 0 when the array is empty). + +* + + Use a copy constructor or assignment operator where there can be an array or expression on the right side (see below). As noted in the introduction, the array assignment is an O(1) operation because it only copies the header and increases the reference counter. The ``Mat::clone()`` method can be used to get a full (deep) copy of the array when you need it. + +* + + Construct a header for a part of another array. It can be a single row, single column, several rows, several columns, rectangular region in the array (called a *minor* in algebra) or a diagonal. Such operations are also O(1) because the new header references the same data. You can actually modify a part of the array using this feature, for example: + + :: + + // add the 5-th row, multiplied by 3 to the 3rd row + M.row(3) = M.row(3) + M.row(5)*3; + + // now copy the 7-th column to the 1-st column + // M.col(1) = M.col(7); // this will not work + Mat M1 = M.col(1); + M.col(7).copyTo(M1); + + // create a new 320x240 image + Mat img(Size(320,240),CV_8UC3); + // select a ROI + Mat roi(img, Rect(10,10,100,100)); + // fill the ROI with (0,255,0) (which is green in RGB space); + // the original 320x240 image will be modified + roi = Scalar(0,255,0); + + .. + + Due to the additional ``datastart`` and ``dataend`` members, it is possible to compute a relative sub-array position in the main *container* array using ``locateROI()``: + + :: + + Mat A = Mat::eye(10, 10, CV_32S); + // extracts A columns, 1 (inclusive) to 3 (exclusive). + Mat B = A(Range::all(), Range(1, 3)); + // extracts B rows, 5 (inclusive) to 9 (exclusive). + // that is, C ~ A(Range(5, 9), Range(1, 3)) + Mat C = B(Range(5, 9), Range::all()); + Size size; Point ofs; + C.locateROI(size, ofs); + // size will be (width=10,height=10) and the ofs will be (x=1, y=5) + + .. + + As in case of whole matrices, if you need a deep copy, use the ``clone()`` method of the extracted sub-matrices. + +* + + Make a header for user-allocated data. It can be useful to do the following: + + #. + Process "foreign" data using OpenCV (for example, when you implement a DirectShow* filter or a processing module for ``gstreamer``, and so on). For example: + + :: + + void process_video_frame(const unsigned char* pixels, + int width, int height, int step) + { + Mat img(height, width, CV_8UC3, pixels, step); + GaussianBlur(img, img, Size(7,7), 1.5, 1.5); + } + + .. + + #. + Quickly initialize small matrices and/or get a super-fast element access. + + :: + + double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; + Mat M = Mat(3, 3, CV_64F, m).inv(); + + .. + + Partial yet very common cases of this *user-allocated data* case are conversions from ``CvMat`` and ``IplImage`` to ``Mat``. For this purpose, there are special constructors taking pointers to ``CvMat`` or ``IplImage`` and the optional flag indicating whether to copy the data or not. + + Backward conversion from ``Mat`` to ``CvMat`` or ``IplImage`` is provided via cast operators ``Mat::operator CvMat() const`` and ``Mat::operator IplImage()``. The operators do NOT copy the data. + + :: + + IplImage* img = cvLoadImage("greatwave.jpg", 1); + Mat mtx(img); // convert IplImage* -> Mat + CvMat oldmat = mtx; // convert Mat -> CvMat + CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && + oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); + + .. + +* + + Use MATLAB-style array initializers, ``zeros(), ones(), eye()``, for example: + + :: + + // create a double-precision identity martix and add it to M. + M += Mat::eye(M.rows, M.cols, CV_64F); + + .. + +* + + Use a comma-separated initializer: + + :: + + // create a 3x3 double-precision identity matrix + Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); + + .. + + With this approach, you first call a constructor of the :ocv:class:`Mat_` class with the proper parameters, and then you just put ``<<`` operator followed by comma-separated values that can be constants, variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation errors. + +Once the array is created, it is automatically managed via a reference-counting mechanism. If the array header is built on top of user-allocated data, you should handle the data by yourself. +The array data is deallocated when no one points to it. If you want to release the data pointed by a array header before the array destructor is called, use ``Mat::release()`` . + +The next important thing to learn about the array class is element access. This manual already described how to compute an address of each array element. Normally, you are not required to use the formula directly in the code. If you know the array element type (which can be retrieved using the method ``Mat::type()`` ), you can access the element +:math:`M_{ij}` of a 2-dimensional array as: :: + + M.at(i,j) += 1.f; + + +assuming that M is a double-precision floating-point array. There are several variants of the method ``at`` for a different number of dimensions. + +If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to the row first, and then just use the plain C operator ``[]`` : :: + + // compute sum of positive matrix elements + // (assuming that M isa double-precision matrix) + double sum=0; + for(int i = 0; i < M.rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < M.cols; j++) + sum += std::max(Mi[j], 0.); + } + + +Some operations, like the one above, do not actually depend on the array shape. They just process elements of an array one by one (or elements from multiple arrays that have the same coordinates, for example, array addition). Such operations are called *element-wise*. It makes sense to check whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If yes, process them as a long single row: :: + + // compute the sum of positive matrix elements, optimized variant + double sum=0; + int cols = M.cols, rows = M.rows; + if(M.isContinuous()) + { + cols *= rows; + rows = 1; + } + for(int i = 0; i < rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < cols; j++) + sum += std::max(Mi[j], 0.); + } + + +In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is smaller, which is especially noticeable in case of small matrices. + +Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: :: + + // compute sum of positive matrix elements, iterator-based variant + double sum=0; + MatConstIterator_ it = M.begin(), it_end = M.end(); + for(; it != it_end; ++it) + sum += std::max(*it, 0.); + + +The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, including ``std::sort()`` . + + +.. _MatrixExpressions: + +Matrix Expressions +------------------ + +This is a list of implemented matrix operations that can be combined in arbitrary complex expressions +(here ``A``, ``B`` stand for matrices ( ``Mat`` ), ``s`` for a scalar ( ``Scalar`` ), +``alpha`` for a real-valued scalar ( ``double`` )): + +* + Addition, subtraction, negation: + ``A+B, A-B, A+s, A-s, s+A, s-A, -A`` + +* + Scaling: + ``A*alpha`` + +* + Per-element multiplication and division: + ``A.mul(B), A/B, alpha/A`` + +* + Matrix multiplication: + ``A*B`` + +* + Transposition: + ``A.t()`` (means ``A``\ :sup:`T`) + +* + Matrix inversion and pseudo-inversion, solving linear systems and least-squares problems: + + ``A.inv([method])`` (~ ``A``\ :sup:`-1`) ``, A.inv([method])*B`` (~ ``X: AX=B``) + +* + Comparison: + ``A cmpop B, A cmpop alpha, alpha cmpop A``, where ``cmpop`` is one of ``: >, >=, ==, !=, <=, <``. The result of comparison is an 8-bit single channel mask whose elements are set to 255 (if the particular element or pair of elements satisfy the condition) or 0. + +* + Bitwise logical operations: ``A logicop B, A logicop s, s logicop A, ~A``, where ``logicop`` is one of ``: &, |, ^``. + +* + Element-wise minimum and maximum: + ``min(A, B), min(A, alpha), max(A, B), max(A, alpha)`` + +* + Element-wise absolute value: + ``abs(A)`` + +* + Cross-product, dot-product: + ``A.cross(B)`` + ``A.dot(B)`` + +* + Any function of matrix or matrices and scalars that returns a matrix or a scalar, such as ``norm``, ``mean``, ``sum``, ``countNonZero``, ``trace``, ``determinant``, ``repeat``, and others. + +* + Matrix initializers ( ``Mat::eye(), Mat::zeros(), Mat::ones()`` ), matrix comma-separated initializers, matrix constructors and operators that extract sub-matrices (see :ocv:class:`Mat` description). + +* + ``Mat_()`` constructors to cast the result to the proper type. + +.. note:: Comma-separated initializers and probably some other operations may require additional explicit ``Mat()`` or ``Mat_()`` constructor calls to resolve a possible ambiguity. + +Here are examples of matrix expressions: + +:: + + // compute pseudo-inverse of A, equivalent to A.inv(DECOMP_SVD) + SVD svd(A); + Mat pinvA = svd.vt.t()*Mat::diag(1./svd.w)*svd.u.t(); + + // compute the new vector of parameters in the Levenberg-Marquardt algorithm + x -= (A.t()*A + lambda*Mat::eye(A.cols,A.cols,A.type())).inv(DECOMP_CHOLESKY)*(A.t()*err); + + // sharpen image using "unsharp mask" algorithm + Mat blurred; double sigma = 1, threshold = 5, amount = 1; + GaussianBlur(img, blurred, Size(), sigma, sigma); + Mat lowConstrastMask = abs(img - blurred) < threshold; + Mat sharpened = img*(1+amount) + blurred*(-amount); + img.copyTo(sharpened, lowContrastMask); + +.. + + +Below is the formal description of the ``Mat`` methods. + +Mat::Mat +-------- +Various Mat constructors + +.. ocv:function:: Mat::Mat() + +.. ocv:function:: Mat::Mat(int rows, int cols, int type) + +.. ocv:function:: Mat::Mat(Size size, int type) + +.. ocv:function:: Mat::Mat(int rows, int cols, int type, const Scalar& s) + +.. ocv:function:: Mat::Mat(Size size, int type, const Scalar& s) + +.. ocv:function:: Mat::Mat(const Mat& m) + +.. ocv:function:: Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP) + +.. ocv:function:: Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP) + +.. ocv:function:: Mat::Mat( const Mat& m, const Range& rowRange, const Range& colRange=Range::all() ) + +.. ocv:function:: Mat::Mat(const Mat& m, const Rect& roi) + +.. ocv:function:: Mat::Mat(const CvMat* m, bool copyData=false) + +.. ocv:function:: Mat::Mat(const IplImage* img, bool copyData=false) + +.. ocv:function:: template explicit Mat::Mat(const Vec& vec, bool copyData=true) + +.. ocv:function:: template explicit Mat::Mat(const Matx& vec, bool copyData=true) + +.. ocv:function:: template explicit Mat::Mat(const vector& vec, bool copyData=false) + +.. ocv:function:: Mat::Mat(int ndims, const int* sizes, int type) + +.. ocv:function:: Mat::Mat(int ndims, const int* sizes, int type, const Scalar& s) + +.. ocv:function:: Mat::Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0) + +.. ocv:function:: Mat::Mat(const Mat& m, const Range* ranges) + + :param ndims: Array dimensionality. + + :param rows: Number of rows in a 2D array. + + :param cols: Number of columns in a 2D array. + + :param roi: Region of interest. + + :param size: 2D array size: ``Size(cols, rows)`` . In the ``Size()`` constructor, the number of rows and the number of columns go in the reverse order. + + :param sizes: Array of integers specifying an n-dimensional array shape. + + :param type: Array type. Use ``CV_8UC1, ..., CV_64FC4`` to create 1-4 channel matrices, or ``CV_8UC(n), ..., CV_64FC(n)`` to create multi-channel (up to ``CV_MAX_CN`` channels) matrices. + + :param s: An optional value to initialize each matrix element with. To set all the matrix elements to the particular value after the construction, use the assignment operator ``Mat::operator=(const Scalar& value)`` . + + :param data: Pointer to the user data. Matrix constructors that take ``data`` and ``step`` parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it. + + :param step: Number of bytes each matrix row occupies. The value should include the padding bytes at the end of each row, if any. If the parameter is missing (set to ``AUTO_STEP`` ), no padding is assumed and the actual step is calculated as ``cols*elemSize()`` . See :ocv:func:`Mat::elemSize` . + + :param steps: Array of ``ndims-1`` steps in case of a multi-dimensional array (the last step is always set to the element size). If not specified, the matrix is assumed to be continuous. + + :param m: Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied by these constructors. Instead, the header pointing to ``m`` data or its sub-array is constructed and associated with it. The reference counter, if any, is incremented. So, when you modify the matrix formed using such a constructor, you also modify the corresponding elements of ``m`` . If you want to have an independent copy of the sub-array, use ``Mat::clone()`` . + + :param img: Pointer to the old-style ``IplImage`` image structure. By default, the data is shared between the original image and the new matrix. But when ``copyData`` is set, the full copy of the image data is created. + + :param vec: STL vector whose elements form the matrix. The matrix has a single column and the number of rows equal to the number of vector elements. Type of the matrix matches the type of vector elements. The constructor can handle arbitrary types, for which there is a properly declared :ocv:class:`DataType` . This means that the vector elements must be primitive numbers or uni-type numerical tuples of numbers. Mixed-type structures are not supported. The corresponding constructor is explicit. Since STL vectors are not automatically converted to ``Mat`` instances, you should write ``Mat(vec)`` explicitly. Unless you copy the data into the matrix ( ``copyData=true`` ), no new elements will be added to the vector because it can potentially yield vector data reallocation, and, thus, the matrix data pointer will be invalid. + + :param copyData: Flag to specify whether the underlying data of the STL vector or the old-style ``CvMat`` or ``IplImage`` should be copied to (``true``) or shared with (``false``) the newly constructed matrix. When the data is copied, the allocated buffer is managed using ``Mat`` reference counting mechanism. While the data is shared, the reference counter is NULL, and you should not deallocate the data until the matrix is not destructed. + + :param rowRange: Range of the ``m`` rows to take. As usual, the range start is inclusive and the range end is exclusive. Use ``Range::all()`` to take all the rows. + + :param colRange: Range of the ``m`` columns to take. Use ``Range::all()`` to take all the columns. + + :param ranges: Array of selected ranges of ``m`` along each dimensionality. + +These are various constructors that form a matrix. As noted in the :ref:`AutomaticAllocation`, +often the default constructor is enough, and the proper matrix will be allocated by an OpenCV function. The constructed matrix can further be assigned to another matrix or matrix expression or can be allocated with +:ocv:func:`Mat::create` . In the former case, the old content is de-referenced. + + +Mat::~Mat +--------- +The Mat destructor. + +.. ocv:function:: Mat::~Mat() + +The matrix destructor calls :ocv:func:`Mat::release` . + + +Mat::operator = +--------------- +Provides matrix assignment operators. + +.. ocv:function:: Mat& Mat::operator = (const Mat& m) + +.. ocv:function:: Mat& Mat::operator =( const MatExpr& expr ) + +.. ocv:function:: Mat& Mat::operator = (const Scalar& s) + + :param m: Assigned, right-hand-side matrix. Matrix assignment is an O(1) operation. This means that no data is copied but the data is shared and the reference counter, if any, is incremented. Before assigning new data, the old data is de-referenced via :ocv:func:`Mat::release` . + + :param expr: Assigned matrix expression object. As opposite to the first form of the assignment operation, the second form can reuse already allocated matrix if it has the right size and type to fit the matrix expression result. It is automatically handled by the real function that the matrix expressions is expanded to. For example, ``C=A+B`` is expanded to ``add(A, B, C)``, and :func:`add` takes care of automatic ``C`` reallocation. + + :param s: Scalar assigned to each matrix element. The matrix size or type is not changed. + +These are available assignment operators. Since they all are very different, make sure to read the operator parameters description. + +Mat::row +-------- +Creates a matrix header for the specified matrix row. + +.. ocv:function:: Mat Mat::row(int y) const + + :param y: A 0-based row index. + +The method makes a new header for the specified matrix row and returns it. This is an O(1) operation, regardless of the matrix size. The underlying data of the new matrix is shared with the original matrix. Here is the example of one of the classical basic matrix processing operations, ``axpy``, used by LU and many other algorithms: :: + + inline void matrix_axpy(Mat& A, int i, int j, double alpha) + { + A.row(i) += A.row(j)*alpha; + } + + +.. note:: + + In the current implementation, the following code does not work as expected: :: + + Mat A; + ... + A.row(i) = A.row(j); // will not work + + + This happens because ``A.row(i)`` forms a temporary header that is further assigned to another header. Remember that each of these operations is O(1), that is, no data is copied. Thus, the above assignment is not true if you may have expected the j-th row to be copied to the i-th row. To achieve that, you should either turn this simple assignment into an expression or use the :ocv:func:`Mat::copyTo` method: :: + + Mat A; + ... + // works, but looks a bit obscure. + A.row(i) = A.row(j) + 0; + + // this is a bit longer, but the recommended method. + A.row(j).copyTo(A.row(i)); + +Mat::col +-------- +Creates a matrix header for the specified matrix column. + +.. ocv:function:: Mat Mat::col(int x) const + + :param x: A 0-based column index. + +The method makes a new header for the specified matrix column and returns it. This is an O(1) operation, regardless of the matrix size. The underlying data of the new matrix is shared with the original matrix. See also the +:ocv:func:`Mat::row` description. + + +Mat::rowRange +------------- +Creates a matrix header for the specified row span. + +.. ocv:function:: Mat Mat::rowRange(int startrow, int endrow) const + +.. ocv:function:: Mat Mat::rowRange(const Range& r) const + + :param startrow: An inclusive 0-based start index of the row span. + + :param endrow: An exclusive 0-based ending index of the row span. + + :param r: :ocv:class:`Range` structure containing both the start and the end indices. + +The method makes a new header for the specified row span of the matrix. Similarly to +:ocv:func:`Mat::row` and +:ocv:func:`Mat::col` , this is an O(1) operation. + +Mat::colRange +------------- +Creates a matrix header for the specified row span. + +.. ocv:function:: Mat Mat::colRange(int startcol, int endcol) const + +.. ocv:function:: Mat Mat::colRange(const Range& r) const + + :param startcol: An inclusive 0-based start index of the column span. + + :param endcol: An exclusive 0-based ending index of the column span. + + :param r: :ocv:class:`Range` structure containing both the start and the end indices. + +The method makes a new header for the specified column span of the matrix. Similarly to +:ocv:func:`Mat::row` and +:ocv:func:`Mat::col` , this is an O(1) operation. + +Mat::diag +--------- +Extracts a diagonal from a matrix, or creates a diagonal matrix. + +.. ocv:function:: Mat Mat::diag( int d=0 ) const + +.. ocv:function:: static Mat Mat::diag( const Mat& d ) + + :param d: Single-column matrix that forms a diagonal matrix or index of the diagonal, with the following values: + + * **d=0** is the main diagonal. + + * **d>0** is a diagonal from the lower half. For example, ``d=1`` means the diagonal is set immediately below the main one. + + * **d<0** is a diagonal from the upper half. For example, ``d=1`` means the diagonal is set immediately above the main one. + +The method makes a new header for the specified matrix diagonal. The new matrix is represented as a single-column matrix. Similarly to +:ocv:func:`Mat::row` and +:ocv:func:`Mat::col` , this is an O(1) operation. + +Mat::clone +---------- +Creates a full copy of the array and the underlying data. + +.. ocv:function:: Mat Mat::clone() const + +The method creates a full copy of the array. The original ``step[]`` is not taken into account. So, the array copy is a continuous array occupying ``total()*elemSize()`` bytes. + + +Mat::copyTo +----------- +Copies the matrix to another one. + +.. ocv:function:: void Mat::copyTo( OutputArray m ) const +.. ocv:function:: void Mat::copyTo( OutputArray m, InputArray mask ) const + + :param m: Destination matrix. If it does not have a proper size or type before the operation, it is reallocated. + + :param mask: Operation mask. Its non-zero elements indicate which matrix elements need to be copied. + +The method copies the matrix data to another matrix. Before copying the data, the method invokes :: + + m.create(this->size(), this->type); + + +so that the destination matrix is reallocated if needed. While ``m.copyTo(m);`` works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices. + +When the operation mask is specified, and the ``Mat::create`` call shown above reallocated the matrix, the newly allocated matrix is initialized with all zeros before copying the data. + +.. _Mat::convertTo: + +Mat::convertTo +-------------- +Converts an array to another data type with optional scaling. + +.. ocv:function:: void Mat::convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const + + :param m: output matrix; if it does not have a proper size or type before the operation, it is reallocated. + + :param rtype: desired output matrix type or, rather, the depth since the number of channels are the same as the input has; if ``rtype`` is negative, the output matrix will have the same type as the input. + + :param alpha: optional scale factor. + + :param beta: optional delta added to the scaled values. + +The method converts source pixel values to the target data type. ``saturate_cast<>`` is applied at the end to avoid possible overflows: + +.. math:: + + m(x,y) = saturate \_ cast( \alpha (*this)(x,y) + \beta ) + + +Mat::assignTo +------------- +Provides a functional form of ``convertTo``. + +.. ocv:function:: void Mat::assignTo( Mat& m, int type=-1 ) const + + :param m: Destination array. + + :param type: Desired destination array depth (or -1 if it should be the same as the source type). + +This is an internally used method called by the +:ref:`MatrixExpressions` engine. + +Mat::setTo +---------- +Sets all or some of the array elements to the specified value. + +.. ocv:function:: Mat& Mat::setTo( InputArray value, InputArray mask=noArray() ) + + :param value: Assigned scalar converted to the actual array type. + + :param mask: Operation mask of the same size as ``*this``. This is an advanced variant of the ``Mat::operator=(const Scalar& s)`` operator. + + +Mat::reshape +------------ +Changes the shape and/or the number of channels of a 2D matrix without copying the data. + +.. ocv:function:: Mat Mat::reshape(int cn, int rows=0) const + + :param cn: New number of channels. If the parameter is 0, the number of channels remains the same. + + :param rows: New number of rows. If the parameter is 0, the number of rows remains the same. + +The method makes a new matrix header for ``*this`` elements. The new matrix may have a different size and/or different number of channels. Any combination is possible if: + +* + No extra elements are included into the new matrix and no elements are excluded. Consequently, the product ``rows*cols*channels()`` must stay the same after the transformation. + +* + No data is copied. That is, this is an O(1) operation. Consequently, if you change the number of rows, or the operation changes the indices of elements row in some other way, the matrix must be continuous. See + :ocv:func:`Mat::isContinuous` . + +For example, if there is a set of 3D points stored as an STL vector, and you want to represent the points as a ``3xN`` matrix, do the following: :: + + std::vector vec; + ... + + Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation + reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel. + // Also, an O(1) operation + t(); // finally, transpose the Nx3 matrix. + // This involves copying all the elements + + + + +Mat::t +------ +Transposes a matrix. + +.. ocv:function:: MatExpr Mat::t() const + +The method performs matrix transposition by means of matrix expressions. It does not perform the actual transposition but returns a temporary matrix transposition object that can be further used as a part of more complex matrix expressions or can be assigned to a matrix: :: + + Mat A1 = A + Mat::eye(A.size(), A.type)*lambda; + Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I) + + +Mat::inv +-------- +Inverses a matrix. + +.. ocv:function:: MatExpr Mat::inv(int method=DECOMP_LU) const + + :param method: Matrix inversion method. Possible values are the following: + + * **DECOMP_LU** is the LU decomposition. The matrix must be non-singular. + + * **DECOMP_CHOLESKY** is the Cholesky :math:`LL^T` decomposition for symmetrical positively defined matrices only. This type is about twice faster than LU on big matrices. + + * **DECOMP_SVD** is the SVD decomposition. If the matrix is singular or even non-square, the pseudo inversion is computed. + +The method performs a matrix inversion by means of matrix expressions. This means that a temporary matrix inversion object is returned by the method and can be used further as a part of more complex matrix expressions or can be assigned to a matrix. + + +Mat::mul +-------- +Performs an element-wise multiplication or division of the two matrices. + +.. ocv:function:: MatExpr Mat::mul(InputArray m, double scale=1) const + + :param m: Another array of the same type and the same size as ``*this``, or a matrix expression. + + :param scale: Optional scale factor. + +The method returns a temporary object encoding per-element array multiplication, with optional scale. Note that this is not a matrix multiplication that corresponds to a simpler "*" operator. + +Example: :: + + Mat C = A.mul(5/B); // equivalent to divide(A, B, C, 5) + + +Mat::cross +---------- +Computes a cross-product of two 3-element vectors. + +.. ocv:function:: Mat Mat::cross(InputArray m) const + + :param m: Another cross-product operand. + +The method computes a cross-product of two 3-element vectors. The vectors must be 3-element floating-point vectors of the same shape and size. The result is another 3-element vector of the same shape and type as operands. + + +Mat::dot +-------- +Computes a dot-product of two vectors. + +.. ocv:function:: double Mat::dot(InputArray m) const + + :param m: another dot-product operand. + +The method computes a dot-product of two matrices. If the matrices are not single-column or single-row vectors, the top-to-bottom left-to-right scan ordering is used to treat them as 1D vectors. The vectors must have the same size and type. If the matrices have more than one channel, the dot products from all the channels are summed together. + + +Mat::zeros +---------- +Returns a zero array of the specified size and type. + +.. ocv:function:: static MatExpr Mat::zeros(int rows, int cols, int type) +.. ocv:function:: static MatExpr Mat::zeros(Size size, int type) +.. ocv:function:: static MatExpr Mat::zeros( int ndims, const int* sz, int type ) + + :param ndims: Array dimensionality. + + :param rows: Number of rows. + + :param cols: Number of columns. + + :param size: Alternative to the matrix size specification ``Size(cols, rows)`` . + + :param sz: Array of integers specifying the array shape. + + :param type: Created matrix type. + +The method returns a Matlab-style zero array initializer. It can be used to quickly form a constant array as a function parameter, part of a matrix expression, or as a matrix initializer. :: + + Mat A; + A = Mat::zeros(3, 3, CV_32F); + + +In the example above, a new matrix is allocated only if ``A`` is not a 3x3 floating-point matrix. Otherwise, the existing matrix ``A`` is filled with zeros. + + +Mat::ones +------------- +Returns an array of all 1's of the specified size and type. + +.. ocv:function:: static MatExpr Mat::ones(int rows, int cols, int type) +.. ocv:function:: static MatExpr Mat::ones(Size size, int type) +.. ocv:function:: static MatExpr Mat::ones( int ndims, const int* sz, int type ) + + :param ndims: Array dimensionality. + + :param rows: Number of rows. + + :param cols: Number of columns. + + :param size: Alternative to the matrix size specification ``Size(cols, rows)`` . + + :param sz: Array of integers specifying the array shape. + + :param type: Created matrix type. + +The method returns a Matlab-style 1's array initializer, similarly to +:ocv:func:`Mat::zeros`. Note that using this method you can initialize an array with an arbitrary value, using the following Matlab idiom: :: + + Mat A = Mat::ones(100, 100, CV_8U)*3; // make 100x100 matrix filled with 3. + + +The above operation does not form a 100x100 matrix of 1's and then multiply it by 3. Instead, it just remembers the scale factor (3 in this case) and use it when actually invoking the matrix initializer. + + +Mat::eye +------------ +Returns an identity matrix of the specified size and type. + +.. ocv:function:: static MatExpr Mat::eye(int rows, int cols, int type) +.. ocv:function:: static MatExpr Mat::eye(Size size, int type) + + :param rows: Number of rows. + + :param cols: Number of columns. + + :param size: Alternative matrix size specification as ``Size(cols, rows)`` . + + :param type: Created matrix type. + +The method returns a Matlab-style identity matrix initializer, similarly to +:ocv:func:`Mat::zeros`. Similarly to +:ocv:func:`Mat::ones`, you can use a scale operation to create a scaled identity matrix efficiently: :: + + // make a 4x4 diagonal matrix with 0.1's on the diagonal. + Mat A = Mat::eye(4, 4, CV_32F)*0.1; + + +Mat::create +--------------- +Allocates new array data if needed. + +.. ocv:function:: void Mat::create(int rows, int cols, int type) +.. ocv:function:: void Mat::create(Size size, int type) +.. ocv:function:: void Mat::create(int ndims, const int* sizes, int type) + + :param ndims: New array dimensionality. + + :param rows: New number of rows. + + :param cols: New number of columns. + + :param size: Alternative new matrix size specification: ``Size(cols, rows)`` + + :param sizes: Array of integers specifying a new array shape. + + :param type: New matrix type. + +This is one of the key ``Mat`` methods. Most new-style OpenCV functions and methods that produce arrays call this method for each output array. The method uses the following algorithm: + +#. + If the current array shape and the type match the new ones, return immediately. Otherwise, de-reference the previous data by calling + :ocv:func:`Mat::release`. + +#. + Initialize the new header. + +#. + Allocate the new data of ``total()*elemSize()`` bytes. + +#. + Allocate the new, associated with the data, reference counter and set it to 1. + +Such a scheme makes the memory management robust and efficient at the same time and helps avoid extra typing for you. This means that usually there is no need to explicitly allocate output arrays. That is, instead of writing: :: + + Mat color; + ... + Mat gray(color.rows, color.cols, color.depth()); + cvtColor(color, gray, CV_BGR2GRAY); + + +you can simply write: :: + + Mat color; + ... + Mat gray; + cvtColor(color, gray, CV_BGR2GRAY); + + +because ``cvtColor`` , as well as the most of OpenCV functions, calls ``Mat::create()`` for the output array internally. + + +Mat::addref +----------- +Increments the reference counter. + +.. ocv:function:: void Mat::addref() + +The method increments the reference counter associated with the matrix data. If the matrix header points to an external data set (see +:ocv:func:`Mat::Mat` ), the reference counter is NULL, and the method has no effect in this case. Normally, to avoid memory leaks, the method should not be called explicitly. It is called implicitly by the matrix assignment operator. The reference counter increment is an atomic operation on the platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in different threads. + + +Mat::release +------------ +Decrements the reference counter and deallocates the matrix if needed. + +.. ocv:function:: void Mat::release() + +The method decrements the reference counter associated with the matrix data. When the reference counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers are set to NULL's. If the matrix header points to an external data set (see +:ocv:func:`Mat::Mat` ), the reference counter is NULL, and the method has no effect in this case. + +This method can be called manually to force the matrix data deallocation. But since this method is automatically called in the destructor, or by any other method that changes the data pointer, it is usually not needed. The reference counter decrement and check for 0 is an atomic operation on the platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in different threads. + +Mat::resize +----------- +Changes the number of matrix rows. + +.. ocv:function:: void Mat::resize( size_t sz ) +.. ocv:function:: void Mat::resize( size_t sz, const Scalar& s ) + + :param sz: New number of rows. + :param s: Value assigned to the newly added elements. + +The methods change the number of matrix rows. If the matrix is reallocated, the first ``min(Mat::rows, sz)`` rows are preserved. The methods emulate the corresponding methods of the STL vector class. + + +Mat::reserve +------------ +Reserves space for the certain number of rows. + +.. ocv:function:: void Mat::reserve( size_t sz ) + + :param sz: Number of rows. + +The method reserves space for ``sz`` rows. If the matrix already has enough space to store ``sz`` rows, nothing happens. If the matrix is reallocated, the first ``Mat::rows`` rows are preserved. The method emulates the corresponding method of the STL vector class. + +Mat::push_back +-------------- +Adds elements to the bottom of the matrix. + +.. ocv:function:: template void Mat::push_back(const T& elem) + +.. ocv:function:: void Mat::push_back( const Mat& m ) + + :param elem: Added element(s). + +The methods add one or more elements to the bottom of the matrix. They emulate the corresponding method of the STL vector class. When ``elem`` is ``Mat`` , its type and the number of columns must be the same as in the container matrix. + +Mat::pop_back +------------- +Removes elements from the bottom of the matrix. + +.. ocv:function:: template void Mat::pop_back(size_t nelems=1) + + :param nelems: Number of removed rows. If it is greater than the total number of rows, an exception is thrown. + +The method removes one or more rows from the bottom of the matrix. + + +Mat::locateROI +-------------- +Locates the matrix header within a parent matrix. + +.. ocv:function:: void Mat::locateROI( Size& wholeSize, Point& ofs ) const + + :param wholeSize: Output parameter that contains the size of the whole matrix containing ``*this`` as a part. + + :param ofs: Output parameter that contains an offset of ``*this`` inside the whole matrix. + +After you extracted a submatrix from a matrix using +:ocv:func:`Mat::row`, +:ocv:func:`Mat::col`, +:ocv:func:`Mat::rowRange`, +:ocv:func:`Mat::colRange` , and others, the resultant submatrix points just to the part of the original big matrix. However, each submatrix contains information (represented by ``datastart`` and ``dataend`` fields) that helps reconstruct the original matrix size and the position of the extracted submatrix within the original matrix. The method ``locateROI`` does exactly that. + + +Mat::adjustROI +-------------- +Adjusts a submatrix size and position within the parent matrix. + +.. ocv:function:: Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright ) + + :param dtop: Shift of the top submatrix boundary upwards. + + :param dbottom: Shift of the bottom submatrix boundary downwards. + + :param dleft: Shift of the left submatrix boundary to the left. + + :param dright: Shift of the right submatrix boundary to the right. + +The method is complimentary to +:ocv:func:`Mat::locateROI` . The typical use of these functions is to determine the submatrix position within the parent matrix and then shift the position somehow. Typically, it can be required for filtering operations when pixels outside of the ROI should be taken into account. When all the method parameters are positive, the ROI needs to grow in all directions by the specified amount, for example: :: + + A.adjustROI(2, 2, 2, 2); + + +In this example, the matrix size is increased by 4 elements in each direction. The matrix is shifted by 2 elements to the left and 2 elements up, which brings in all the necessary pixels for the filtering with the 5x5 kernel. + +``adjustROI`` forces the adjusted ROI to be inside of the parent matrix that is boundaries of the adjusted ROI are constrained by boundaries of the parent matrix. For example, if the submatrix ``A`` is located in the first row of a parent matrix and you called ``A.adjustROI(2, 2, 2, 2)`` then ``A`` will not be increased in the upward direction. + +The function is used internally by the OpenCV filtering functions, like +:ocv:func:`filter2D` , morphological operations, and so on. + +.. seealso:: :ocv:func:`copyMakeBorder` + + +Mat::operator() +--------------- +Extracts a rectangular submatrix. + +.. ocv:function:: Mat Mat::operator()( Range rowRange, Range colRange ) const + +.. ocv:function:: Mat Mat::operator()( const Rect& roi ) const + +.. ocv:function:: Mat Mat::operator()( const Range* ranges ) const + + + :param rowRange: Start and end row of the extracted submatrix. The upper boundary is not included. To select all the rows, use ``Range::all()``. + + :param colRange: Start and end column of the extracted submatrix. The upper boundary is not included. To select all the columns, use ``Range::all()``. + + :param roi: Extracted submatrix specified as a rectangle. + + :param ranges: Array of selected ranges along each array dimension. + +The operators make a new header for the specified sub-array of ``*this`` . They are the most generalized forms of +:ocv:func:`Mat::row`, +:ocv:func:`Mat::col`, +:ocv:func:`Mat::rowRange`, and +:ocv:func:`Mat::colRange` . For example, ``A(Range(0, 10), Range::all())`` is equivalent to ``A.rowRange(0, 10)`` . Similarly to all of the above, the operators are O(1) operations, that is, no matrix data is copied. + + +Mat::operator CvMat +------------------- +Creates the ``CvMat`` header for the matrix. + +.. ocv:function:: Mat::operator CvMat() const + + +The operator creates the ``CvMat`` header for the matrix without copying the underlying data. The reference counter is not taken into account by this operation. Thus, you should make sure than the original matrix is not deallocated while the ``CvMat`` header is used. The operator is useful for intermixing the new and the old OpenCV API's, for example: :: + + Mat img(Size(320, 240), CV_8UC3); + ... + + CvMat cvimg = img; + mycvOldFunc( &cvimg, ...); + + +where ``mycvOldFunc`` is a function written to work with OpenCV 1.x data structures. + + +Mat::operator IplImage +---------------------- +Creates the ``IplImage`` header for the matrix. + +.. ocv:function:: Mat::operator IplImage() const + +The operator creates the ``IplImage`` header for the matrix without copying the underlying data. You should make sure than the original matrix is not deallocated while the ``IplImage`` header is used. Similarly to ``Mat::operator CvMat`` , the operator is useful for intermixing the new and the old OpenCV API's. + +Mat::total +---------- +Returns the total number of array elements. + +.. ocv:function:: size_t Mat::total() const + +The method returns the number of array elements (a number of pixels if the array represents an image). + +Mat::isContinuous +----------------- +Reports whether the matrix is continuous or not. + +.. ocv:function:: bool Mat::isContinuous() const + +The method returns ``true`` if the matrix elements are stored continuously without gaps at the end of each row. Otherwise, it returns ``false``. Obviously, ``1x1`` or ``1xN`` matrices are always continuous. Matrices created with +:ocv:func:`Mat::create` are always continuous. But if you extract a part of the matrix using +:ocv:func:`Mat::col`, +:ocv:func:`Mat::diag` , and so on, or constructed a matrix header for externally allocated data, such matrices may no longer have this property. + +The continuity flag is stored as a bit in the ``Mat::flags`` field and is computed automatically when you construct a matrix header. Thus, the continuity check is a very fast operation, though theoretically it could be done as follows: :: + + // alternative implementation of Mat::isContinuous() + bool myCheckMatContinuity(const Mat& m) + { + //return (m.flags & Mat::CONTINUOUS_FLAG) != 0; + return m.rows == 1 || m.step == m.cols*m.elemSize(); + } + + +The method is used in quite a few of OpenCV functions. The point is that element-wise operations (such as arithmetic and logical operations, math functions, alpha blending, color space transformations, and others) do not depend on the image geometry. Thus, if all the input and output arrays are continuous, the functions can process them as very long single-row vectors. The example below illustrates how an alpha-blending function can be implemented. :: + + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == CV_MAKETYPE(DataType::depth, 4) && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + // here is the idiom: check the arrays for continuity and, + // if this is the case, + // treat the arrays as 1D vectors + if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + size.width *= 4; + + for( int i = 0; i < size.height; i++ ) + { + // when the arrays are continuous, + // the outer loop is executed only once + const T* ptr1 = src1.ptr(i); + const T* ptr2 = src2.ptr(i); + T* dptr = dst.ptr(i); + + for( int j = 0; j < size.width; j += 4 ) + { + float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale; + dptr[j] = saturate_cast(ptr1[j]*alpha + ptr2[j]*beta); + dptr[j+1] = saturate_cast(ptr1[j+1]*alpha + ptr2[j+1]*beta); + dptr[j+2] = saturate_cast(ptr1[j+2]*alpha + ptr2[j+2]*beta); + dptr[j+3] = saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale); + } + } + } + + +This approach, while being very simple, can boost the performance of a simple element-operation by 10-20 percents, especially if the image is rather small and the operation is quite simple. + +Another OpenCV idiom in this function, a call of +:ocv:func:`Mat::create` for the destination array, that allocates the destination array unless it already has the proper size and type. And while the newly allocated arrays are always continuous, you still need to check the destination array because :ocv:func:`Mat::create` does not always allocate a new matrix. + + +Mat::elemSize +------------- +Returns the matrix element size in bytes. + +.. ocv:function:: size_t Mat::elemSize() const + +The method returns the matrix element size in bytes. For example, if the matrix type is ``CV_16SC3`` , the method returns ``3*sizeof(short)`` or 6. + + +Mat::elemSize1 +-------------- +Returns the size of each matrix element channel in bytes. + +.. ocv:function:: size_t Mat::elemSize1() const + +The method returns the matrix element channel size in bytes, that is, it ignores the number of channels. For example, if the matrix type is ``CV_16SC3`` , the method returns ``sizeof(short)`` or 2. + + +Mat::type +--------- +Returns the type of a matrix element. + +.. ocv:function:: int Mat::type() const + +The method returns a matrix element type. This is an identifier compatible with the ``CvMat`` type system, like ``CV_16SC3`` or 16-bit signed 3-channel array, and so on. + + +Mat::depth +---------- +Returns the depth of a matrix element. + +.. ocv:function:: int Mat::depth() const + +The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed 3-channel array, the method returns ``CV_16S`` . A complete list of matrix types contains the following values: + +* ``CV_8U`` - 8-bit unsigned integers ( ``0..255`` ) + +* ``CV_8S`` - 8-bit signed integers ( ``-128..127`` ) + +* ``CV_16U`` - 16-bit unsigned integers ( ``0..65535`` ) + +* ``CV_16S`` - 16-bit signed integers ( ``-32768..32767`` ) + +* ``CV_32S`` - 32-bit signed integers ( ``-2147483648..2147483647`` ) + +* ``CV_32F`` - 32-bit floating-point numbers ( ``-FLT_MAX..FLT_MAX, INF, NAN`` ) + +* ``CV_64F`` - 64-bit floating-point numbers ( ``-DBL_MAX..DBL_MAX, INF, NAN`` ) + + +Mat::channels +------------- +Returns the number of matrix channels. + +.. ocv:function:: int Mat::channels() const + +The method returns the number of matrix channels. + + +Mat::step1 +---------- +Returns a normalized step. + +.. ocv:function:: size_t Mat::step1( int i=0 ) const + +The method returns a matrix step divided by +:ocv:func:`Mat::elemSize1()` . It can be useful to quickly access an arbitrary matrix element. + + +Mat::size +--------- +Returns a matrix size. + +.. ocv:function:: Size Mat::size() const + +The method returns a matrix size: ``Size(cols, rows)`` . When the matrix is more than 2-dimensional, the returned size is (-1, -1). + + +Mat::empty +---------- +Returns ``true`` if the array has no elements. + +.. ocv:function:: bool Mat::empty() const + +The method returns ``true`` if ``Mat::total()`` is 0 or if ``Mat::data`` is NULL. Because of ``pop_back()`` and ``resize()`` methods ``M.total() == 0`` does not imply that ``M.data == NULL`` . + + +Mat::ptr +-------- +Returns a pointer to the specified matrix row. + +.. ocv:function:: uchar* Mat::ptr(int i0=0) + +.. ocv:function:: const uchar* Mat::ptr(int i0=0) const + +.. ocv:function:: template _Tp* Mat::ptr(int i0=0) + +.. ocv:function:: template const _Tp* Mat::ptr(int i0=0) const + + :param i0: A 0-based row index. + +The methods return ``uchar*`` or typed pointer to the specified matrix row. See the sample in +:ocv:func:`Mat::isContinuous` to know how to use these methods. + + +Mat::at +------- +Returns a reference to the specified array element. + +.. ocv:function:: template T& Mat::at(int i) const + +.. ocv:function:: template const T& Mat::at(int i) const + +.. ocv:function:: template T& Mat::at(int i, int j) + +.. ocv:function:: template const T& Mat::at(int i, int j) const + +.. ocv:function:: template T& Mat::at(Point pt) + +.. ocv:function:: template const T& Mat::at(Point pt) const + +.. ocv:function:: template T& Mat::at(int i, int j, int k) + +.. ocv:function:: template const T& Mat::at(int i, int j, int k) const + +.. ocv:function:: template T& Mat::at(const int* idx) + +.. ocv:function:: template const T& Mat::at(const int* idx) const + + :param i: Index along the dimension 0 + :param j: Index along the dimension 1 + :param k: Index along the dimension 2 + + :param pt: Element position specified as ``Point(j,i)`` . + + :param idx: Array of ``Mat::dims`` indices. + +The template methods return a reference to the specified array element. For the sake of higher performance, the index range checks are only performed in the Debug configuration. + +Note that the variants with a single index (i) can be used to access elements of single-row or single-column 2-dimensional arrays. That is, if, for example, ``A`` is a ``1 x N`` floating-point matrix and ``B`` is an ``M x 1`` integer matrix, you can simply write ``A.at(k+4)`` and ``B.at(2*i+1)`` instead of ``A.at(0,k+4)`` and ``B.at(2*i+1,0)`` , respectively. + +The example below initializes a Hilbert matrix: :: + + Mat H(100, 100, CV_64F); + for(int i = 0; i < H.rows; i++) + for(int j = 0; j < H.cols; j++) + H.at(i,j)=1./(i+j+1); + + + +Mat::begin +-------------- +Returns the matrix iterator and sets it to the first matrix element. + +.. ocv:function:: template MatIterator_<_Tp> Mat::begin() + +.. ocv:function:: template MatConstIterator_<_Tp> Mat::begin() const + +The methods return the matrix read-only or read-write iterators. The use of matrix iterators is very similar to the use of bi-directional STL iterators. In the example below, the alpha blending function is rewritten using the matrix iterators: :: + + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + typedef Vec VT; + + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == DataType::type && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + MatConstIterator_ it1 = src1.begin(), it1_end = src1.end(); + MatConstIterator_ it2 = src2.begin(); + MatIterator_ dst_it = dst.begin(); + + for( ; it1 != it1_end; ++it1, ++it2, ++dst_it ) + { + VT pix1 = *it1, pix2 = *it2; + float alpha = pix1[3]*inv_scale, beta = pix2[3]*inv_scale; + *dst_it = VT(saturate_cast(pix1[0]*alpha + pix2[0]*beta), + saturate_cast(pix1[1]*alpha + pix2[1]*beta), + saturate_cast(pix1[2]*alpha + pix2[2]*beta), + saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale)); + } + } + + + +Mat::end +------------ +Returns the matrix iterator and sets it to the after-last matrix element. + +.. ocv:function:: template MatIterator_<_Tp> Mat::end() + +.. ocv:function:: template MatConstIterator_<_Tp> Mat::end() const + +The methods return the matrix read-only or read-write iterators, set to the point following the last matrix element. + +Mat\_ +----- +.. ocv:class:: Mat_ + +Template matrix class derived from +:ocv:class:`Mat` . :: + + template class Mat_ : public Mat + { + public: + // ... some specific methods + // and + // no new extra fields + }; + + +The class ``Mat_<_Tp>`` is a "thin" template wrapper on top of the ``Mat`` class. It does not have any extra data fields. Nor this class nor ``Mat`` has any virtual methods. Thus, references or pointers to these two classes can be freely but carefully converted one to another. For example: :: + + // create a 100x100 8-bit matrix + Mat M(100,100,CV_8U); + // this will be compiled fine. no any data conversion will be done. + Mat_& M1 = (Mat_&)M; + // the program is likely to crash at the statement below + M1(99,99) = 1.f; + + +While ``Mat`` is sufficient in most cases, ``Mat_`` can be more convenient if you use a lot of element access operations and if you know matrix type at the compilation time. Note that ``Mat::at<_Tp>(int y, int x)`` and ``Mat_<_Tp>::operator ()(int y, int x)`` do absolutely the same and run at the same speed, but the latter is certainly shorter: :: + + Mat_ M(20,20); + for(int i = 0; i < M.rows; i++) + for(int j = 0; j < M.cols; j++) + M(i,j) = 1./(i+j+1); + Mat E, V; + eigen(M,E,V); + cout << E.at(0,0)/E.at(M.rows-1,0); + + +To use ``Mat_`` for multi-channel images/matrices, pass ``Vec`` as a ``Mat_`` parameter: :: + + // allocate a 320x240 color image and fill it with green (in RGB space) + Mat_ img(240, 320, Vec3b(0,255,0)); + // now draw a diagonal white line + for(int i = 0; i < 100; i++) + img(i,i)=Vec3b(255,255,255); + // and now scramble the 2nd (red) channel of each pixel + for(int i = 0; i < img.rows; i++) + for(int j = 0; j < img.cols; j++) + img(i,j)[2] ^= (uchar)(i ^ j); + + +InputArray +---------- +.. ocv:class:: InputArray + +This is the proxy class for passing read-only input arrays into OpenCV functions. It is defined as :: + + typedef const _InputArray& InputArray; + +where ``_InputArray`` is a class that can be constructed from ``Mat``, ``Mat_``, ``Matx``, ``std::vector``, ``std::vector >`` or ``std::vector``. It can also be constructed from a matrix expression. + +Since this is mostly implementation-level class, and its interface may change in future versions, we do not describe it in details. There are a few key things, though, that should be kept in mind: + + * When you see in the reference manual or in OpenCV source code a function that takes ``InputArray``, it means that you can actually pass ``Mat``, ``Matx``, ``vector`` etc. (see above the complete list). + + * Optional input arguments: If some of the input arrays may be empty, pass ``cv::noArray()`` (or simply ``cv::Mat()`` as you probably did before). + + * The class is designed solely for passing parameters. That is, normally you *should not* declare class members, local and global variables of this type. + + * If you want to design your own function or a class method that can operate of arrays of multiple types, you can use ``InputArray`` (or ``OutputArray``) for the respective parameters. Inside a function you should use ``_InputArray::getMat()`` method to construct a matrix header for the array (without copying data). ``_InputArray::kind()`` can be used to distinguish ``Mat`` from ``vector<>`` etc., but normally it is not needed. + +Here is how you can use a function that takes ``InputArray`` :: + + std::vector vec; + // points or a circle + for( int i = 0; i < 30; i++ ) + vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)), + (float)(100 - 30*sin(i*CV_PI*2/5)))); + cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20)); + +That is, we form an STL vector containing points, and apply in-place affine transformation to the vector using the 2x3 matrix created inline as ``Matx`` instance. + +Here is how such a function can be implemented (for simplicity, we implement a very specific case of it, according to the assertion statement inside) :: + + void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m) + { + // get Mat headers for input arrays. This is O(1) operation, + // unless _src and/or _m are matrix expressions. + Mat src = _src.getMat(), m = _m.getMat(); + CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) ); + + // [re]create the output array so that it has the proper size and type. + // In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize. + _dst.create(src.size(), src.type()); + Mat dst = _dst.getMat(); + + for( int i = 0; i < src.rows; i++ ) + for( int j = 0; j < src.cols; j++ ) + { + Point2f pt = src.at(i, j); + dst.at(i, j) = Point2f(m.at(0, 0)*pt.x + + m.at(0, 1)*pt.y + + m.at(0, 2), + m.at(1, 0)*pt.x + + m.at(1, 1)*pt.y + + m.at(1, 2)); + } + } + +There is another related type, ``InputArrayOfArrays``, which is currently defined as a synonym for ``InputArray``: :: + + typedef InputArray InputArrayOfArrays; + +It denotes function arguments that are either vectors of vectors or vectors of matrices. A separate synonym is needed to generate Python/Java etc. wrappers properly. At the function implementation level their use is similar, but ``_InputArray::getMat(idx)`` should be used to get header for the idx-th component of the outer vector and ``_InputArray::size().area()`` should be used to find the number of components (vectors/matrices) of the outer vector. + + +OutputArray +----------- +.. ocv:class:: OutputArray : public InputArray + +This type is very similar to ``InputArray`` except that it is used for input/output and output function parameters. Just like with ``InputArray``, OpenCV users should not care about ``OutputArray``, they just pass ``Mat``, ``vector`` etc. to the functions. The same limitation as for ``InputArray``: **Do not explicitly create OutputArray instances** applies here too. + +If you want to make your function polymorphic (i.e. accept different arrays as output parameters), it is also not very difficult. Take the sample above as the reference. Note that ``_OutputArray::create()`` needs to be called before ``_OutputArray::getMat()``. This way you guarantee that the output array is properly allocated. + +Optional output parameters. If you do not need certain output array to be computed and returned to you, pass ``cv::noArray()``, just like you would in the case of optional input array. At the implementation level, use ``_OutputArray::needed()`` to check if certain output array needs to be computed or not. + +There are several synonyms for ``OutputArray`` that are used to assist automatic Python/Java/... wrapper generators: :: + + typedef OutputArray OutputArrayOfArrays; + typedef OutputArray InputOutputArray; + typedef OutputArray InputOutputArrayOfArrays; + +NAryMatIterator +--------------- +.. ocv:class:: NAryMatIterator + +n-ary multi-dimensional array iterator. :: + + class CV_EXPORTS NAryMatIterator + { + public: + //! the default constructor + NAryMatIterator(); + //! the full constructor taking arbitrary number of n-dim matrices + NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1); + //! the separate iterator initialization method + void init(const Mat** arrays, Mat* planes, int narrays=-1); + + //! proceeds to the next plane of every iterated matrix + NAryMatIterator& operator ++(); + //! proceeds to the next plane of every iterated matrix (postfix increment operator) + NAryMatIterator operator ++(int); + + ... + int nplanes; // the total number of planes + }; + + +Use the class to implement unary, binary, and, generally, n-ary element-wise operations on multi-dimensional arrays. Some of the arguments of an n-ary function may be continuous arrays, some may be not. It is possible to use conventional +``MatIterator`` 's for each array but incrementing all of the iterators after each small operations may be a big overhead. In this case consider using ``NAryMatIterator`` to iterate through several matrices simultaneously as long as they have the same geometry (dimensionality and all the dimension sizes are the same). On each iteration ``it.planes[0]``, ``it.planes[1]`` , ... will be the slices of the corresponding matrices. + +The example below illustrates how you can compute a normalized and threshold 3D color histogram: :: + + void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb) + { + const int histSize[] = {N, N, N}; + + // make sure that the histogram has a proper size and type + hist.create(3, histSize, CV_32F); + + // and clear it + hist = Scalar(0); + + // the loop below assumes that the image + // is a 8-bit 3-channel. check it. + CV_Assert(image.type() == CV_8UC3); + MatConstIterator_ it = image.begin(), + it_end = image.end(); + for( ; it != it_end; ++it ) + { + const Vec3b& pix = *it; + hist.at(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f; + } + + minProb *= image.rows*image.cols; + Mat plane; + NAryMatIterator it(&hist, &plane, 1); + double s = 0; + // iterate through the matrix. on each iteration + // it.planes[*] (of type Mat) will be set to the current plane. + for(int p = 0; p < it.nplanes; p++, ++it) + { + threshold(it.planes[0], it.planes[0], minProb, 0, THRESH_TOZERO); + s += sum(it.planes[0])[0]; + } + + s = 1./s; + it = NAryMatIterator(&hist, &plane, 1); + for(int p = 0; p < it.nplanes; p++, ++it) + it.planes[0] *= s; + } + + +SparseMat +--------- +.. ocv:class:: SparseMat + +The class ``SparseMat`` represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements of any type that +:ocv:class:`Mat` can store. *Sparse* means that only non-zero elements are stored (though, as a result of operations on a sparse matrix, some of its stored elements can actually become 0. It is up to you to detect such elements and delete them using ``SparseMat::erase`` ). The non-zero elements are stored in a hash table that grows when it is filled so that the search time is O(1) in average (regardless of whether element is there or not). Elements can be accessed using the following methods: + +* + Query operations (``SparseMat::ptr`` and the higher-level ``SparseMat::ref``, ``SparseMat::value`` and ``SparseMat::find``), for example: + + :: + + const int dims = 5; + int size[] = {10, 10, 10, 10, 10}; + SparseMat sparse_mat(dims, size, CV_32F); + for(int i = 0; i < 1000; i++) + { + int idx[dims]; + for(int k = 0; k < dims; k++) + idx[k] = rand() + sparse_mat.ref(idx) += 1.f; + } + + .. + +* + Sparse matrix iterators. They are similar to ``MatIterator`` but different from :ocv:class:`NAryMatIterator`. That is, the iteration loop is familiar to STL users: + + :: + + // prints elements of a sparse floating-point matrix + // and the sum of elements. + SparseMatConstIterator_ + it = sparse_mat.begin(), + it_end = sparse_mat.end(); + double s = 0; + int dims = sparse_mat.dims(); + for(; it != it_end; ++it) + { + // print element indices and the element value + const SparseMat::Node* n = it.node(); + printf("("); + for(int i = 0; i < dims; i++) + printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")"); + printf(": %g\n", it.value()); + s += *it; + } + printf("Element sum is %g\n", s); + + .. + + If you run this loop, you will notice that elements are not enumerated in a logical order (lexicographical, and so on). They come in the same order as they are stored in the hash table (semi-randomly). You may collect pointers to the nodes and sort them to get the proper ordering. Note, however, that pointers to the nodes may become invalid when you add more elements to the matrix. This may happen due to possible buffer reallocation. + +* + Combination of the above 2 methods when you need to process 2 or more sparse matrices simultaneously. For example, this is how you can compute unnormalized cross-correlation of the 2 floating-point sparse matrices: + + :: + + double cross_corr(const SparseMat& a, const SparseMat& b) + { + const SparseMat *_a = &a, *_b = &b; + // if b contains less elements than a, + // it is faster to iterate through b + if(_a->nzcount() > _b->nzcount()) + std::swap(_a, _b); + SparseMatConstIterator_ it = _a->begin(), + it_end = _a->end(); + double ccorr = 0; + for(; it != it_end; ++it) + { + // take the next element from the first matrix + float avalue = *it; + const Node* anode = it.node(); + // and try to find an element with the same index in the second matrix. + // since the hash value depends only on the element index, + // reuse the hash value stored in the node + float bvalue = _b->value(anode->idx,&anode->hashval); + ccorr += avalue*bvalue; + } + return ccorr; + } + + .. + +SparseMat::SparseMat +-------------------- +Various SparseMat constructors. + +.. ocv:function:: SparseMat::SparseMat() +.. ocv:function:: SparseMat::SparseMat( int dims, const int* _sizes, int _type ) +.. ocv:function:: SparseMat::SparseMat( const SparseMat& m ) +.. ocv:function:: SparseMat::SparseMat( const Mat& m ) +.. ocv:function:: SparseMat::SparseMat( const CvSparseMat* m ) + + + :param m: Source matrix for copy constructor. If m is dense matrix (ocv:class:`Mat`) then it will be converted to sparse representation. + :param dims: Array dimensionality. + :param _sizes: Sparce matrix size on all dementions. + :param _type: Sparse matrix data type. + :param try1d: if try1d is true and matrix is a single-column matrix (Nx1), then the sparse matrix will be 1-dimensional. + +SparseMat::~SparseMat +--------------------- +SparseMat object destructor. + +.. ocv:function:: SparseMat::~SparseMat() + +SparseMat::operator= +-------------------- +Provides sparse matrix assignment operators. + +.. ocv:function:: SparseMat& SparseMat::operator = (const SparseMat& m) +.. ocv:function:: SparseMat& SparseMat::operator = (const Mat& m) + +The last variant is equivalent to the corresponding constructor with try1d=false. + + +SparseMat::clone +---------------- +Creates a full copy of the matrix. + +.. ocv:function:: SparseMat SparseMat::clone() const + +SparseMat::copyTo +----------------- +Copy all the data to the destination matrix.The destination will be reallocated if needed. + +.. ocv:function:: void SparseMat::copyTo( SparseMat& m ) const +.. ocv:function:: void SparseMat::copyTo( Mat& m ) const + + :param m: Target for copiing. + +The last variant converts 1D or 2D sparse matrix to dense 2D matrix. If the sparse matrix is 1D, the result will be a single-column matrix. + +SparceMat::convertTo +-------------------- +Convert sparse matrix with possible type change and scaling. + +.. ocv:function:: void SparseMat::convertTo( SparseMat& m, int rtype, double alpha=1 ) const +.. ocv:function:: void SparseMat::convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const + +The first version converts arbitrary sparse matrix to dense matrix and multiplies all the matrix elements by the specified scalar. +The second versiob converts sparse matrix to dense matrix with optional type conversion and scaling. +When rtype=-1, the destination element type will be the same as the sparse matrix element type. +Otherwise, rtype will specify the depth and the number of channels will remain the same as in the sparse matrix. + +SparseMat:create +---------------- +Reallocates sparse matrix. If it was already of the proper size and type, it is simply cleared with clear(), otherwise, +the old matrix is released (using release()) and the new one is allocated. + +.. ocv:function:: void SparseMat::create(int dims, const int* _sizes, int _type) + + :param dims: Array dimensionality. + :param _sizes: Sparce matrix size on all dementions. + :param _type: Sparse matrix data type. + +SparseMat::clear +---------------- +Sets all the matrix elements to 0, which means clearing the hash table. + +.. ocv:function:: void SparseMat::clear() + +SparseMat::addref +----------------- +Manually increases reference counter to the header. + +.. ocv:function:: void SparseMat::addref() + +SparseMat::release +------------------ +Decreses the header reference counter when it reaches 0. The header and all the underlying data are deallocated. + +.. ocv:function:: void SparseMat::release() + +SparseMat::CvSparseMat * +------------------------ +Converts sparse matrix to the old-style representation. All the elements are copied. + +.. ocv:function:: SparseMat::operator CvSparseMat*() const + +SparseMat::elemSize +------------------- +Size of each element in bytes (the matrix nodes will be bigger because of element indices and other SparseMat::Node elements). + +.. ocv:function:: size_t SparseMat::elemSize() const + +SparseMat::elemSize1 +-------------------- +elemSize()/channels(). + +.. ocv:function:: size_t SparseMat::elemSize() const + +SparseMat::type +--------------- +Returns the type of a matrix element. + +.. ocv:function:: int SparseMat::type() const + +The method returns a sparse matrix element type. This is an identifier compatible with the ``CvMat`` type system, like ``CV_16SC3`` or 16-bit signed 3-channel array, and so on. + +SparseMat::depth +---------------- +Returns the depth of a sparse matrix element. + +.. ocv:function:: int SparseMat::depth() const + +The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed 3-channel array, the method returns ``CV_16S`` + +* ``CV_8U`` - 8-bit unsigned integers ( ``0..255`` ) + +* ``CV_8S`` - 8-bit signed integers ( ``-128..127`` ) + +* ``CV_16U`` - 16-bit unsigned integers ( ``0..65535`` ) + +* ``CV_16S`` - 16-bit signed integers ( ``-32768..32767`` ) + +* ``CV_32S`` - 32-bit signed integers ( ``-2147483648..2147483647`` ) + +* ``CV_32F`` - 32-bit floating-point numbers ( ``-FLT_MAX..FLT_MAX, INF, NAN`` ) + +* ``CV_64F`` - 64-bit floating-point numbers ( ``-DBL_MAX..DBL_MAX, INF, NAN`` ) + +SparseMat::channels +------------------- +Returns the number of matrix channels. + +.. ocv:function:: int SparseMat::channels() const + +The method returns the number of matrix channels. + +SparseMat::size +--------------- +Returns the array of sizes or matrix size by i dimention and 0 if the matrix is not allocated. + +.. ocv:function:: const int* SparseMat::size() const +.. ocv:function:: int SparseMat::size(int i) const + + :param i: Dimention index. + +SparseMat::dims +--------------- +Returns the matrix dimensionality. + +.. ocv:function:: int SparseMat::dims() const + +SparseMat::nzcount +------------------ +Returns the number of non-zero elements. + +.. ocv:function:: size_t SparseMat::nzcount() const + +SparseMat::hash +--------------- +Compute element hash value from the element indices. + +.. ocv:function:: size_t SparseMat::hash(int i0) const +.. ocv:function:: size_t SparseMat::hash(int i0, int i1) const +.. ocv:function:: size_t SparseMat::hash(int i0, int i1, int i2) const +.. ocv:function:: size_t SparseMat::hash(const int* idx) const + +SparseMat::ptr +-------------- +Low-level element-access functions, special variants for 1D, 2D, 3D cases, and the generic one for n-D case. + +.. ocv:function:: uchar* SparseMat::ptr(int i0, bool createMissing, size_t* hashval=0) +.. ocv:function:: uchar* SparseMat::ptr(int i0, int i1, bool createMissing, size_t* hashval=0) +.. ocv:function:: uchar* SparseMat::ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0) +.. ocv:function:: uchar* SparseMat::ptr(const int* idx, bool createMissing, size_t* hashval=0) + +Return pointer to the matrix element. If the element is there (it is non-zero), the pointer to it is returned. +If it is not there and ``createMissing=false``, NULL pointer is returned. If it is not there and ``createMissing=true``, +the new elementis created and initialized with 0. Pointer to it is returned. If the optional hashval pointer is not ``NULL``, +the element hash value is not computed but ``hashval`` is taken instead. + +SparseMat::erase +---------------- +Erase the specified matrix element. When there is no such an element, the methods do nothing. + +.. ocv:function:: void SparseMat::erase(int i0, int i1, size_t* hashval=0) +.. ocv:function:: void SparseMat::erase(int i0, int i1, int i2, size_t* hashval=0) +.. ocv:function:: void SparseMat::erase(const int* idx, size_t* hashval=0) + +SparseMat\_ +----------- +.. ocv:class:: SparseMat_ + +Template sparse n-dimensional array class derived from +:ocv:class:`SparseMat` :: + + template class SparseMat_ : public SparseMat + { + public: + typedef SparseMatIterator_<_Tp> iterator; + typedef SparseMatConstIterator_<_Tp> const_iterator; + + // constructors; + // the created matrix will have data type = DataType<_Tp>::type + SparseMat_(); + SparseMat_(int dims, const int* _sizes); + SparseMat_(const SparseMat& m); + SparseMat_(const SparseMat_& m); + SparseMat_(const Mat& m); + SparseMat_(const CvSparseMat* m); + // assignment operators; data type conversion is done when necessary + SparseMat_& operator = (const SparseMat& m); + SparseMat_& operator = (const SparseMat_& m); + SparseMat_& operator = (const Mat& m); + + // equivalent to the correspoding parent class methods + SparseMat_ clone() const; + void create(int dims, const int* _sizes); + operator CvSparseMat*() const; + + // overriden methods that do extra checks for the data type + int type() const; + int depth() const; + int channels() const; + + // more convenient element access operations. + // ref() is retained (but <_Tp> specification is not needed anymore); + // operator () is equivalent to SparseMat::value<_Tp> + _Tp& ref(int i0, size_t* hashval=0); + _Tp operator()(int i0, size_t* hashval=0) const; + _Tp& ref(int i0, int i1, size_t* hashval=0); + _Tp operator()(int i0, int i1, size_t* hashval=0) const; + _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; + _Tp& ref(const int* idx, size_t* hashval=0); + _Tp operator()(const int* idx, size_t* hashval=0) const; + + // iterators + SparseMatIterator_<_Tp> begin(); + SparseMatConstIterator_<_Tp> begin() const; + SparseMatIterator_<_Tp> end(); + SparseMatConstIterator_<_Tp> end() const; + }; + +``SparseMat_`` is a thin wrapper on top of :ocv:class:`SparseMat` created in the same way as ``Mat_`` . +It simplifies notation of some operations. :: + + int sz[] = {10, 20, 30}; + SparseMat_ M(3, sz); + ... + M.ref(1, 2, 3) = M(4, 5, 6) + M(7, 8, 9); + + +Algorithm +--------- +.. ocv:class:: Algorithm + +This is a base class for all more or less complex algorithms in OpenCV, especially for classes of algorithms, for which there can be multiple implementations. The examples are stereo correspondence (for which there are algorithms like block matching, semi-global block matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck etc.). + +The class provides the following features for all derived classes: + + * so called "virtual constructor". That is, each Algorithm derivative is registered at program start and you can get the list of registered algorithms and create instance of a particular algorithm by its name (see ``Algorithm::create``). If you plan to add your own algorithms, it is good practice to add a unique prefix to your algorithms to distinguish them from other algorithms. + + * setting/retrieving algorithm parameters by name. If you used video capturing functionality from OpenCV highgui module, you are probably familar with ``cvSetCaptureProperty()``, ``cvGetCaptureProperty()``, ``VideoCapture::set()`` and ``VideoCapture::get()``. ``Algorithm`` provides similar method where instead of integer id's you specify the parameter names as text strings. See ``Algorithm::set`` and ``Algorithm::get`` for details. + + * reading and writing parameters from/to XML or YAML files. Every Algorithm derivative can store all its parameters and then read them back. There is no need to re-implement it each time. + +Here is example of SIFT use in your application via Algorithm interface: :: + + #include "opencv2/opencv.hpp" + #include "opencv2/nonfree/nonfree.hpp" + + ... + + initModule_nonfree(); // to load SURF/SIFT etc. + + Ptr sift = Algorithm::create("Feature2D.SIFT"); + + FileStorage fs("sift_params.xml", FileStorage::READ); + if( fs.isOpened() ) // if we have file with parameters, read them + { + sift->read(fs["sift_params"]); + fs.release(); + } + else // else modify the parameters and store them; user can later edit the file to use different parameters + { + sift->set("contrastThreshold", 0.01f); // lower the contrast threshold, compared to the default value + + { + WriteStructContext ws(fs, "sift_params", CV_NODE_MAP); + sift->write(fs); + } + } + + Mat image = imread("myimage.png", 0), descriptors; + vector keypoints; + (*sift)(image, noArray(), keypoints, descriptors); + +Algorithm::name +--------------- +Returns the algorithm name + +.. ocv:function:: string Algorithm::name() const + +Algorithm::get +-------------- +Returns the algorithm parameter + +.. ocv:function:: template typename ParamType<_Tp>::member_type Algorithm::get(const string& name) const + + :param name: The parameter name. + +The method returns value of the particular parameter. Since the compiler can not deduce the type of the returned parameter, you should specify it explicitly in angle brackets. Here are the allowed forms of get: + + * myalgo.get("param_name") + * myalgo.get("param_name") + * myalgo.get("param_name") + * myalgo.get("param_name") + * myalgo.get("param_name") + * myalgo.get >("param_name") + * myalgo.get("param_name") (it returns Ptr). + +In some cases the actual type of the parameter can be cast to the specified type, e.g. integer parameter can be cast to double, ``bool`` can be cast to ``int``. But "dangerous" transformations (string<->number, double->int, 1x1 Mat<->number, ...) are not performed and the method will throw an exception. In the case of ``Mat`` or ``vector`` parameters the method does not clone the matrix data, so do not modify the matrices. Use ``Algorithm::set`` instead - slower, but more safe. + + +Algorithm::set +-------------- +Sets the algorithm parameter + +.. ocv:function:: void Algorithm::set(const string& name, int value) +.. ocv:function:: void Algorithm::set(const string& name, double value) +.. ocv:function:: void Algorithm::set(const string& name, bool value) +.. ocv:function:: void Algorithm::set(const string& name, const string& value) +.. ocv:function:: void Algorithm::set(const string& name, const Mat& value) +.. ocv:function:: void Algorithm::set(const string& name, const vector& value) +.. ocv:function:: void Algorithm::set(const string& name, const Ptr& value) + + :param name: The parameter name. + :param value: The parameter value. + +The method sets value of the particular parameter. Some of the algorithm parameters may be declared as read-only. If you try to set such a parameter, you will get exception with the corresponding error message. + + +Algorithm::write +---------------- +Stores algorithm parameters in a file storage + +.. ocv:function:: void Algorithm::write(FileStorage& fs) const + + :param fs: File storage. + +The method stores all the algorithm parameters (in alphabetic order) to the file storage. The method is virtual. If you define your own Algorithm derivative, your can override the method and store some extra information. However, it's rarely needed. Here are some examples: + + * SIFT feature detector (from nonfree module). The class only stores algorithm parameters and no keypoints or their descriptors. Therefore, it's enough to store the algorithm parameters, which is what ``Algorithm::write()`` does. Therefore, there is no dedicated ``SIFT::write()``. + + * Background subtractor (from video module). It has the algorithm parameters and also it has the current background model. However, the background model is not stored. First, it's rather big. Then, if you have stored the background model, it would likely become irrelevant on the next run (because of shifted camera, changed background, different lighting etc.). Therefore, ``BackgroundSubtractorMOG`` and ``BackgroundSubtractorMOG2`` also rely on the standard ``Algorithm::write()`` to store just the algorithm parameters. + + * Expectation Maximization (from ml module). The algorithm finds mixture of gaussians that approximates user data best of all. In this case the model may be re-used on the next run to test new data against the trained statistical model. So EM needs to store the model. However, since the model is described by a few parameters that are available as read-only algorithm parameters (i.e. they are available via ``EM::get()``), EM also relies on ``Algorithm::write()`` to store both EM parameters and the model (represented by read-only algorithm parameters). + + +Algorithm::read +--------------- +Reads algorithm parameters from a file storage + +.. ocv:function:: void Algorithm::read(const FileNode& fn) + + :param fn: File node of the file storage. + +The method reads all the algorithm parameters from the specified node of a file storage. Similarly to ``Algorithm::write()``, if you implement an algorithm that needs to read some extra data and/or re-compute some internal data, you may override the method. + +Algorithm::getList +------------------ +Returns the list of registered algorithms + +.. ocv:function:: void Algorithm::getList(vector& algorithms) + + :param algorithms: The output vector of algorithm names. + +This static method returns the list of registered algorithms in alphabetical order. Here is how to use it :: + + vector algorithms; + Algorithm::getList(algorithms); + cout << "Algorithms: " << algorithms.size() << endl; + for (size_t i=0; i < algorithms.size(); i++) + cout << algorithms[i] << endl; + + +Algorithm::create +----------------- +Creates algorithm instance by name + +.. ocv:function:: template Ptr<_Tp> Algorithm::create(const string& name) + + :param name: The algorithm name, one of the names returned by ``Algorithm::getList()``. + +This static method creates a new instance of the specified algorithm. If there is no such algorithm, the method will silently return null pointer (that can be checked by ``Ptr::empty()`` method). Also, you should specify the particular ``Algorithm`` subclass as ``_Tp`` (or simply ``Algorithm`` if you do not know it at that point). :: + + Ptr bgfg = Algorithm::create("BackgroundSubtractor.MOG2"); + +.. note:: This is important note about seemingly mysterious behavior of ``Algorithm::create()`` when it returns NULL while it should not. The reason is simple - ``Algorithm::create()`` resides in OpenCV`s core module and the algorithms are implemented in other modules. If you create algorithms dynamically, C++ linker may decide to throw away the modules where the actual algorithms are implemented, since you do not call any functions from the modules. To avoid this problem, you need to call ``initModule_();`` somewhere in the beginning of the program before ``Algorithm::create()``. For example, call ``initModule_nonfree()`` in order to use SURF/SIFT, call ``initModule_ml()`` to use expectation maximization etc. + +Creating Own Algorithms +----------------------- + +The above methods are usually enough for users. If you want to make your own algorithm, derived from ``Algorithm``, you should basically follow a few conventions and add a little semi-standard piece of code to your class: + + * Make a class and specify ``Algorithm`` as its base class. + * The algorithm parameters should be the class members. See ``Algorithm::get()`` for the list of possible types of the parameters. + * Add public virtual method ``AlgorithmInfo* info() const;`` to your class. + * Add constructor function, ``AlgorithmInfo`` instance and implement the ``info()`` method. The simplest way is to take http://code.opencv.org/projects/opencv/repository/revisions/master/entry/modules/ml/src/ml_init.cpp as the reference and modify it according to the list of your parameters. + * Add some public function (e.g. ``initModule_()``) that calls info() of your algorithm and put it into the same source file as ``info()`` implementation. This is to force C++ linker to include this object file into the target application. See ``Algorithm::create()`` for details. + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/clustering.rst diffimg-2.0.0/3rdparty/opencv/core/doc/clustering.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/clustering.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/clustering.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,81 @@ +Clustering +========== + +.. highlight:: cpp + +kmeans +------ +Finds centers of clusters and groups input samples around the clusters. + +.. ocv:function:: double kmeans( InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray centers=noArray() ) + +.. ocv:pyfunction:: cv2.kmeans(data, K, criteria, attempts, flags[, bestLabels[, centers]]) -> retval, bestLabels, centers + +.. ocv:cfunction:: int cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, CvTermCriteria termcrit, int attempts=1, CvRNG* rng=0, int flags=0, CvArr* _centers=0, double* compactness=0 ) + +.. ocv:pyoldfunction:: cv.KMeans2(samples, nclusters, labels, termcrit, attempts=1, flags=0, centers=None) -> float + + :param samples: Floating-point matrix of input samples, one row per sample. + + :param cluster_count: Number of clusters to split the set by. + + :param labels: Input/output integer array that stores the cluster indices for every sample. + + :param criteria: The algorithm termination criteria, that is, the maximum number of iterations and/or the desired accuracy. The accuracy is specified as ``criteria.epsilon``. As soon as each of the cluster centers moves by less than ``criteria.epsilon`` on some iteration, the algorithm stops. + + :param attempts: Flag to specify the number of times the algorithm is executed using different initial labellings. The algorithm returns the labels that yield the best compactness (see the last function parameter). + + :param rng: CvRNG state initialized by RNG(). + + :param flags: Flag that can take the following values: + + * **KMEANS_RANDOM_CENTERS** Select random initial centers in each attempt. + + * **KMEANS_PP_CENTERS** Use ``kmeans++`` center initialization by Arthur and Vassilvitskii [Arthur2007]. + + * **KMEANS_USE_INITIAL_LABELS** During the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of ``KMEANS_*_CENTERS`` flag to specify the exact method. + + :param centers: Output matrix of the cluster centers, one row per each cluster center. + + :param compactness: The returned value that is described below. + +The function ``kmeans`` implements a k-means algorithm that finds the +centers of ``cluster_count`` clusters and groups the input samples +around the clusters. As an output, +:math:`\texttt{labels}_i` contains a 0-based cluster index for +the sample stored in the +:math:`i^{th}` row of the ``samples`` matrix. + +The function returns the compactness measure that is computed as + +.. math:: + + \sum _i \| \texttt{samples} _i - \texttt{centers} _{ \texttt{labels} _i} \| ^2 + +after every attempt. The best (minimum) value is chosen and the +corresponding labels and the compactness value are returned by the function. +Basically, you can use only the core of the function, set the number of +attempts to 1, initialize labels each time using a custom algorithm, pass them with the +( ``flags`` = ``KMEANS_USE_INITIAL_LABELS`` ) flag, and then choose the best (most-compact) clustering. + +partition +------------- +Splits an element set into equivalency classes. + +.. ocv:function:: template int partition( const vector<_Tp>& vec, vector& labels, _EqPredicate predicate=_EqPredicate()) + + :param vec: Set of elements stored as a vector. + + :param labels: Output vector of labels. It contains as many elements as ``vec``. Each label ``labels[i]`` is a 0-based cluster index of ``vec[i]`` . + + :param predicate: Equivalence predicate (pointer to a boolean function of two arguments or an instance of the class that has the method ``bool operator()(const _Tp& a, const _Tp& b)`` ). The predicate returns ``true`` when the elements are certainly in the same class, and returns ``false`` if they may or may not be in the same class. + +The generic function ``partition`` implements an +:math:`O(N^2)` algorithm for +splitting a set of +:math:`N` elements into one or more equivalency classes, as described in +http://en.wikipedia.org/wiki/Disjoint-set_data_structure +. The function +returns the number of equivalency classes. + +.. [Arthur2007] Arthur and S. Vassilvitskii. k-means++: the advantages of careful seeding, Proceedings of the eighteenth annual ACM-SIAM symposium on Discrete algorithms, 2007 diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/core.rst diffimg-2.0.0/3rdparty/opencv/core/doc/core.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/core.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/core.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,17 @@ +**************************** +core. The Core Functionality +**************************** + +.. toctree:: + :maxdepth: 2 + + basic_structures + old_basic_structures + dynamic_structures + operations_on_arrays + drawing_functions + xml_yaml_persistence + old_xml_yaml_persistence + clustering + utility_and_system_functions_and_macros + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/drawing_functions.rst diffimg-2.0.0/3rdparty/opencv/core/doc/drawing_functions.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/drawing_functions.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/drawing_functions.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,522 @@ +Drawing Functions +================= + +.. highlight:: cpp + +Drawing functions work with matrices/images of arbitrary depth. +The boundaries of the shapes can be rendered with antialiasing (implemented only for 8-bit images for now). +All the functions include the parameter ``color`` that uses an RGB value (that may be constructed +with ``CV_RGB`` or the :ocv:class:`Scalar_` constructor +) for color +images and brightness for grayscale images. For color images, the channel ordering +is normally *Blue, Green, Red*. +This is what :ocv:func:`imshow`, :ocv:func:`imread`, and :ocv:func:`imwrite` expect. +So, if you form a color using the +``Scalar`` constructor, it should look like: + +.. math:: + + \texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component]) + +If you are using your own image rendering and I/O functions, you can use any channel ordering. The drawing functions process each channel independently and do not depend on the channel order or even on the used color space. The whole image can be converted from BGR to RGB or to a different color space using +:ocv:func:`cvtColor` . + +If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, many drawing functions can handle pixel coordinates specified with sub-pixel accuracy. This means that the coordinates can be passed as fixed-point numbers encoded as integers. The number of fractional bits is specified by the ``shift`` parameter and the real point coordinates are calculated as +:math:`\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})` . This feature is especially effective when rendering antialiased shapes. + +.. note:: The functions do not support alpha-transparency when the target image is 4-channel. In this case, the ``color[3]`` is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image. + +circle +---------- +Draws a circle. + +.. ocv:function:: void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0) + +.. ocv:pyfunction:: cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> None + +.. ocv:cfunction:: void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.Circle(img, center, radius, color, thickness=1, lineType=8, shift=0)-> None + + :param img: Image where the circle is drawn. + + :param center: Center of the circle. + + :param radius: Radius of the circle. + + :param color: Circle color. + + :param thickness: Thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn. + + :param lineType: Type of the circle boundary. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the coordinates of the center and in the radius value. + +The function ``circle`` draws a simple or filled circle with a given center and radius. + +clipLine +------------ +Clips the line against the image rectangle. + +.. ocv:function:: bool clipLine(Size imgSize, Point& pt1, Point& pt2) + +.. ocv:function:: bool clipLine(Rect imgRect, Point& pt1, Point& pt2) + +.. ocv:pyfunction:: cv2.clipLine(imgRect, pt1, pt2) -> retval, pt1, pt2 + +.. ocv:cfunction:: int cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 ) + +.. ocv:pyoldfunction:: cv.ClipLine(imgSize, pt1, pt2) -> (point1, point2) + + :param imgSize: Image size. The image rectangle is ``Rect(0, 0, imgSize.width, imgSize.height)`` . + + :param imgRect: Image rectangle. + + :param pt1: First line point. + + :param pt2: Second line point. + +The functions ``clipLine`` calculate a part of the line segment that is entirely within the specified rectangle. +They return ``false`` if the line segment is completely outside the rectangle. Otherwise, they return ``true`` . + +ellipse +----------- +Draws a simple or thick elliptic arc or fills an ellipse sector. + +.. ocv:function:: void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0) + +.. ocv:function:: void ellipse(Mat& img, const RotatedRect& box, const Scalar& color, int thickness=1, int lineType=8) + +.. ocv:pyfunction:: cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) -> None +.. ocv:pyfunction:: cv2.ellipse(img, box, color[, thickness[, lineType]]) -> None + +.. ocv:cfunction:: void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.Ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness=1, lineType=8, shift=0)-> None + +.. ocv:cfunction:: void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.EllipseBox(img, box, color, thickness=1, lineType=8, shift=0)-> None + + :param img: Image. + + :param center: Center of the ellipse. + + :param axes: Length of the ellipse axes. + + :param angle: Ellipse rotation angle in degrees. + + :param startAngle: Starting angle of the elliptic arc in degrees. + + :param endAngle: Ending angle of the elliptic arc in degrees. + + :param box: Alternative ellipse representation via :ocv:class:`RotatedRect` or ``CvBox2D``. This means that the function draws an ellipse inscribed in the rotated rectangle. + + :param color: Ellipse color. + + :param thickness: Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn. + + :param lineType: Type of the ellipse boundary. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the coordinates of the center and values of axes. + +The functions ``ellipse`` with less parameters draw an ellipse outline, a filled ellipse, an elliptic arc, or a filled ellipse sector. +A piecewise-linear curve is used to approximate the elliptic arc boundary. If you need more control of the ellipse rendering, you can retrieve the curve using +:ocv:func:`ellipse2Poly` and then render it with +:ocv:func:`polylines` or fill it with +:ocv:func:`fillPoly` . If you use the first variant of the function and want to draw the whole ellipse, not an arc, pass ``startAngle=0`` and ``endAngle=360`` . The figure below explains the meaning of the parameters. + +**Figure 1. Parameters of Elliptic Arc** + +.. image:: pics/ellipse.png + +ellipse2Poly +---------------- +Approximates an elliptic arc with a polyline. + +.. ocv:function:: void ellipse2Poly( Point center, Size axes, int angle, int arcStart, int arcEnd, int delta, vector& pts ) + +.. ocv:pyfunction:: cv2.ellipse2Poly(center, axes, angle, arcStart, arcEnd, delta) -> pts + + :param center: Center of the arc. + + :param axes: Half-sizes of the arc. See the :ocv:func:`ellipse` for details. + + :param angle: Rotation angle of the ellipse in degrees. See the :ocv:func:`ellipse` for details. + + :param arcStart: Starting angle of the elliptic arc in degrees. + + :param arcEnd: Ending angle of the elliptic arc in degrees. + + :param delta: Angle between the subsequent polyline vertices. It defines the approximation accuracy. + + :param pts: Output vector of polyline vertices. + +The function ``ellipse2Poly`` computes the vertices of a polyline that approximates the specified elliptic arc. It is used by +:ocv:func:`ellipse` . + + + +fillConvexPoly +------------------ +Fills a convex polygon. + +.. ocv:function:: void fillConvexPoly(Mat& img, const Point* pts, int npts, const Scalar& color, int lineType=8, int shift=0) + +.. ocv:pyfunction:: cv2.fillConvexPoly(img, points, color[, lineType[, shift]]) -> None + +.. ocv:cfunction:: void cvFillConvexPoly( CvArr* img, const CvPoint* pts, int npts, CvScalar color, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.FillConvexPoly(img, pn, color, lineType=8, shift=0)-> None + + :param img: Image. + + :param pts: Polygon vertices. + + :param npts: Number of polygon vertices. + + :param color: Polygon color. + + :param lineType: Type of the polygon boundaries. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the vertex coordinates. + +The function ``fillConvexPoly`` draws a filled convex polygon. +This function is much faster than the function ``fillPoly`` . It can fill not only convex polygons but any monotonic polygon without self-intersections, +that is, a polygon whose contour intersects every horizontal line (scan line) twice at the most (though, its top-most and/or the bottom edge could be horizontal). + + + +fillPoly +------------ +Fills the area bounded by one or more polygons. + +.. ocv:function:: void fillPoly(Mat& img, const Point** pts, const int* npts, int ncontours, const Scalar& color, int lineType=8, int shift=0, Point offset=Point() ) + +.. ocv:pyfunction:: cv2.fillPoly(img, pts, color[, lineType[, shift[, offset]]]) -> None + +.. ocv:cfunction:: void cvFillPoly( CvArr* img, CvPoint** pts, const int* npts, int contours, CvScalar color, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.FillPoly(img, polys, color, lineType=8, shift=0)-> None + + :param img: Image. + + :param pts: Array of polygons where each polygon is represented as an array of points. + + :param npts: Array of polygon vertex counters. + + :param ncontours: Number of contours that bind the filled region. + + :param color: Polygon color. + + :param lineType: Type of the polygon boundaries. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the vertex coordinates. + + :param offset: Optional offset of all points of the contours. + +The function ``fillPoly`` fills an area bounded by several polygonal contours. The function can fill complex areas, for example, +areas with holes, contours with self-intersections (some of their parts), and so forth. + + + +getTextSize +--------------- +Calculates the width and height of a text string. + +.. ocv:function:: Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine) + +.. ocv:pyfunction:: cv2.getTextSize(text, fontFace, fontScale, thickness) -> retval, baseLine + +.. ocv:cfunction:: void cvGetTextSize( const char* text_string, const CvFont* font, CvSize* text_size, int* baseline ) + +.. ocv:pyoldfunction:: cv.GetTextSize(textString, font)-> (textSize, baseline) + + :param text: Input text string. + + :param fontFace: Font to use. See the :ocv:func:`putText` for details. + + :param fontScale: Font scale. See the :ocv:func:`putText` for details. + + :param thickness: Thickness of lines used to render the text. See :ocv:func:`putText` for details. + + :param baseLine: Output parameter - y-coordinate of the baseline relative to the bottom-most text point. + +The function ``getTextSize`` calculates and returns the size of a box that contains the specified text. +That is, the following code renders some text, the tight box surrounding it, and the baseline: :: + + string text = "Funny text inside the box"; + int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX; + double fontScale = 2; + int thickness = 3; + + Mat img(600, 800, CV_8UC3, Scalar::all(0)); + + int baseline=0; + Size textSize = getTextSize(text, fontFace, + fontScale, thickness, &baseline); + baseline += thickness; + + // center the text + Point textOrg((img.cols - textSize.width)/2, + (img.rows + textSize.height)/2); + + // draw the box + rectangle(img, textOrg + Point(0, baseline), + textOrg + Point(textSize.width, -textSize.height), + Scalar(0,0,255)); + // ... and the baseline first + line(img, textOrg + Point(0, thickness), + textOrg + Point(textSize.width, thickness), + Scalar(0, 0, 255)); + + // then put the text itself + putText(img, text, textOrg, fontFace, fontScale, + Scalar::all(255), thickness, 8); + + +InitFont +-------- +Initializes font structure (OpenCV 1.x API). + +.. ocv:cfunction:: void cvInitFont( CvFont* font, int font_face, double hscale, double vscale, double shear=0, int thickness=1, int line_type=8 ) + + :param font: Pointer to the font structure initialized by the function + + :param font_face: Font name identifier. Only a subset of Hershey fonts http://sources.isc.org/utils/misc/hershey-font.txt are supported now: + + * **CV_FONT_HERSHEY_SIMPLEX** normal size sans-serif font + + * **CV_FONT_HERSHEY_PLAIN** small size sans-serif font + + * **CV_FONT_HERSHEY_DUPLEX** normal size sans-serif font (more complex than ``CV_FONT_HERSHEY_SIMPLEX`` ) + + * **CV_FONT_HERSHEY_COMPLEX** normal size serif font + + * **CV_FONT_HERSHEY_TRIPLEX** normal size serif font (more complex than ``CV_FONT_HERSHEY_COMPLEX`` ) + + * **CV_FONT_HERSHEY_COMPLEX_SMALL** smaller version of ``CV_FONT_HERSHEY_COMPLEX`` + + * **CV_FONT_HERSHEY_SCRIPT_SIMPLEX** hand-writing style font + + * **CV_FONT_HERSHEY_SCRIPT_COMPLEX** more complex variant of ``CV_FONT_HERSHEY_SCRIPT_SIMPLEX`` + + The parameter can be composited from one of the values above and an optional ``CV_FONT_ITALIC`` flag, which indicates italic or oblique font. + + + :param hscale: Horizontal scale. If equal to ``1.0f`` , the characters have the original width depending on the font type. If equal to ``0.5f`` , the characters are of half the original width. + + + :param vscale: Vertical scale. If equal to ``1.0f`` , the characters have the original height depending on the font type. If equal to ``0.5f`` , the characters are of half the original height. + + + :param shear: Approximate tangent of the character slope relative to the vertical line. A zero value means a non-italic font, ``1.0f`` means about a 45 degree slope, etc. + + + :param thickness: Thickness of the text strokes + + + :param line_type: Type of the strokes, see :ocv:func:`line` description + + +The function initializes the font structure that can be passed to text rendering functions. + +.. seealso:: :ocv:cfunc:`PutText` + +.. _Line: + +line +-------- +Draws a line segment connecting two points. + +.. ocv:function:: void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) + +.. ocv:pyfunction:: cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> None + +.. ocv:cfunction:: void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.Line(img, pt1, pt2, color, thickness=1, lineType=8, shift=0)-> None + + :param img: Image. + + :param pt1: First point of the line segment. + + :param pt2: Second point of the line segment. + + :param color: Line color. + + :param thickness: Line thickness. + + :param lineType: Type of the line: + + * **8** (or omitted) - 8-connected line. + + * **4** - 4-connected line. + + * **CV_AA** - antialiased line. + + :param shift: Number of fractional bits in the point coordinates. + +The function ``line`` draws the line segment between ``pt1`` and ``pt2`` points in the image. The line is clipped by the image boundaries. For non-antialiased lines with integer coordinates, the 8-connected or 4-connected Bresenham algorithm is used. Thick lines are drawn with rounding endings. +Antialiased lines are drawn using Gaussian filtering. To specify the line color, you may use the macro ``CV_RGB(r, g, b)`` . + + +LineIterator +------------ +.. ocv:class:: LineIterator + +Class for iterating pixels on a raster line. :: + + class LineIterator + { + public: + // creates iterators for the line connecting pt1 and pt2 + // the line will be clipped on the image boundaries + // the line is 8-connected or 4-connected + // If leftToRight=true, then the iteration is always done + // from the left-most point to the right most, + // not to depend on the ordering of pt1 and pt2 parameters + LineIterator(const Mat& img, Point pt1, Point pt2, + int connectivity=8, bool leftToRight=false); + // returns pointer to the current line pixel + uchar* operator *(); + // move the iterator to the next pixel + LineIterator& operator ++(); + LineIterator operator ++(int); + Point pos() const; + + // internal state of the iterator + uchar* ptr; + int err, count; + int minusDelta, plusDelta; + int minusStep, plusStep; + }; + +The class ``LineIterator`` is used to get each pixel of a raster line. It can be treated as versatile implementation of the Bresenham algorithm where you can stop at each pixel and do some extra processing, for example, grab pixel values along the line or draw a line with an effect (for example, with XOR operation). + +The number of pixels along the line is stored in ``LineIterator::count`` . The method ``LineIterator::pos`` returns the current position in the image :: + + // grabs pixels along the line (pt1, pt2) + // from 8-bit 3-channel image to the buffer + LineIterator it(img, pt1, pt2, 8); + LineIterator it2 = it; + vector buf(it.count); + + for(int i = 0; i < it.count; i++, ++it) + buf[i] = *(const Vec3b)*it; + + // alternative way of iterating through the line + for(int i = 0; i < it2.count; i++, ++it2) + { + Vec3b val = img.at(it2.pos()); + CV_Assert(buf[i] == val); + } + + +rectangle +------------- +Draws a simple, thick, or filled up-right rectangle. + +.. ocv:function:: void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) + +.. ocv:function:: void rectangle( Mat& img, Rect rec, const Scalar& color, int thickness=1, int lineType=8, int shift=0 ) + +.. ocv:pyfunction:: cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> None + +.. ocv:cfunction:: void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.Rectangle(img, pt1, pt2, color, thickness=1, lineType=8, shift=0)-> None + + :param img: Image. + + :param pt1: Vertex of the rectangle. + + :param pt2: Vertex of the rectangle opposite to ``pt1`` . + + :param rec: Alternative specification of the drawn rectangle. + + :param color: Rectangle color or brightness (grayscale image). + + :param thickness: Thickness of lines that make up the rectangle. Negative values, like ``CV_FILLED`` , mean that the function has to draw a filled rectangle. + + :param lineType: Type of the line. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the point coordinates. + +The function ``rectangle`` draws a rectangle outline or a filled rectangle whose two opposite corners are ``pt1`` and ``pt2``, or ``r.tl()`` and ``r.br()-Point(1,1)``. + + + +polylines +------------- +Draws several polygonal curves. + +.. ocv:function:: void polylines( Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 ) + +.. ocv:function:: void polylines( InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 ) + +.. ocv:pyfunction:: cv2.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) -> None + +.. ocv:cfunction:: void cvPolyLine( CvArr* img, CvPoint** pts, const int* npts, int contours, int is_closed, CvScalar color, int thickness=1, int line_type=8, int shift=0 ) + +.. ocv:pyoldfunction:: cv.PolyLine(img, polys, is_closed, color, thickness=1, lineType=8, shift=0) -> None + + :param img: Image. + + :param pts: Array of polygonal curves. + + :param npts: Array of polygon vertex counters. + + :param ncontours: Number of curves. + + :param isClosed: Flag indicating whether the drawn polylines are closed or not. If they are closed, the function draws a line from the last vertex of each curve to its first vertex. + + :param color: Polyline color. + + :param thickness: Thickness of the polyline edges. + + :param lineType: Type of the line segments. See the :ocv:func:`line` description. + + :param shift: Number of fractional bits in the vertex coordinates. + +The function ``polylines`` draws one or more polygonal curves. + + + +putText +----------- +Draws a text string. + +.. ocv:function:: void putText( Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false ) + +.. ocv:pyfunction:: cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) -> None + +.. ocv:cfunction:: void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color ) +.. ocv:pyoldfunction:: cv.PutText(img, text, org, font, color)-> None + + :param img: Image. + + :param text: Text string to be drawn. + + :param org: Bottom-left corner of the text string in the image. + + :param font: ``CvFont`` structure initialized using :ocv:cfunc:`InitFont`. + + :param fontFace: Font type. One of ``FONT_HERSHEY_SIMPLEX``, ``FONT_HERSHEY_PLAIN``, ``FONT_HERSHEY_DUPLEX``, ``FONT_HERSHEY_COMPLEX``, ``FONT_HERSHEY_TRIPLEX``, ``FONT_HERSHEY_COMPLEX_SMALL``, ``FONT_HERSHEY_SCRIPT_SIMPLEX``, or ``FONT_HERSHEY_SCRIPT_COMPLEX``, + where each of the font ID's can be combined with ``FONT_HERSHEY_ITALIC`` to get the slanted letters. + + :param fontScale: Font scale factor that is multiplied by the font-specific base size. + + :param color: Text color. + + :param thickness: Thickness of the lines used to draw a text. + + :param lineType: Line type. See the ``line`` for details. + + :param bottomLeftOrigin: When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner. + +The function ``putText`` renders the specified text string in the image. +Symbols that cannot be rendered using the specified font are +replaced by question marks. See +:ocv:func:`getTextSize` for a text rendering code example. + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/dynamic_structures.rst diffimg-2.0.0/3rdparty/opencv/core/doc/dynamic_structures.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/dynamic_structures.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/dynamic_structures.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1587 @@ +Dynamic Structures +================== + +.. highlight:: c + +The section describes OpenCV 1.x API for creating growable sequences and other dynamic data structures allocated in ``CvMemStorage``. If you use the new C++, Python, Java etc interface, you will unlikely need this functionality. Use ``std::vector`` or other high-level data structures. + +CvMemStorage +------------ + +.. ocv:struct:: CvMemStorage + + A storage for various OpenCV dynamic data structures, such as ``CvSeq``, ``CvSet`` etc. + + .. ocv:member:: CvMemBlock* bottom + + the first memory block in the double-linked list of blocks + + .. ocv:member:: CvMemBlock* top + + the current partially allocated memory block in the list of blocks + + .. ocv:member:: CvMemStorage* parent + + the parent storage (if any) from which the new memory blocks are borrowed. + + .. ocv:member:: int free_space + + number of free bytes in the ``top`` block + + .. ocv:member:: int block_size + + the total size of the memory blocks + +Memory storage is a low-level structure used to store dynamically growing data structures such as sequences, contours, graphs, subdivisions, etc. It is organized as a list of memory blocks of equal size - +``bottom`` field is the beginning of the list of blocks and ``top`` is the currently used block, but not necessarily the last block of the list. All blocks between ``bottom`` and ``top``, not including the +latter, are considered fully occupied; all blocks between ``top`` and the last block, not including ``top``, are considered free and ``top`` itself is partly occupied - ``free_space`` contains the number of free bytes left in the end of ``top``. + +A new memory buffer that may be allocated explicitly by :ocv:cfunc:`MemStorageAlloc` function or implicitly by higher-level functions, such as :ocv:cfunc:`SeqPush`, :ocv:cfunc:`GraphAddEdge` etc. + +The buffer is put in the end of already allocated space in the ``top`` memory block, if there is enough free space. After allocation, ``free_space`` is decreased by the size of the allocated buffer plus some padding to keep the proper alignment. When the allocated buffer does not fit into the available portion of +``top``, the next storage block from the list is taken as ``top`` and ``free_space`` is reset to the whole block size prior to the allocation. + +If there are no more free blocks, a new block is allocated (or borrowed from the parent, see :ocv:cfunc:`CreateChildMemStorage`) and added to the end of list. Thus, the storage behaves as a stack with ``bottom`` indicating bottom of the stack and the pair (``top``, ``free_space``) +indicating top of the stack. The stack top may be saved via :ocv:cfunc:`SaveMemStoragePos`, restored via +:ocv:cfunc:`RestoreMemStoragePos`, or reset via :ocv:cfunc:`ClearMemStorage`. + +CvMemBlock +---------- + +.. ocv:struct:: CvMemBlock + +The structure :ocv:struct:`CvMemBlock` represents a single block of memory storage. The actual data in the memory blocks follows the header. + +CvMemStoragePos +--------------- + +.. ocv:struct:: CvMemStoragePos + +The structure stores the position in the memory storage. It is used by :ocv:cfunc:`SaveMemStoragePos` and :ocv:cfunc:`RestoreMemStoragePos`. + +CvSeq +----- + +.. ocv:struct:: CvSeq + + Dynamically growing sequence. + + .. ocv:member:: int flags + + sequence flags, including the sequence signature (CV_SEQ_MAGIC_VAL or CV_SET_MAGIC_VAL), type of the elements and some other information about the sequence. + + .. ocv:member:: int header_size + + size of the sequence header. It should be sizeof(CvSeq) at minimum. See :ocv:cfunc:`CreateSeq`. + + .. ocv:member:: CvSeq* h_prev + .. ocv:member:: CvSeq* h_next + .. ocv:member:: CvSeq* v_prev + .. ocv:member:: CvSeq* v_next + + pointers to another sequences in a sequence tree. Sequence trees are used to store hierarchical contour structures, retrieved by :ocv:cfunc:`FindContours` + + .. ocv:member:: int total + + the number of sequence elements + + .. ocv:member:: int elem_size + + size of each sequence element in bytes + + .. ocv:member:: CvMemStorage* storage + + memory storage where the sequence resides. It can be a NULL pointer. + + .. ocv:member:: CvSeqBlock* first + + pointer to the first data block + +The structure ``CvSeq`` is a base for all of OpenCV dynamic data structures. +There are two types of sequences - dense and sparse. The base type for dense +sequences is :ocv:struct:`CvSeq` and such sequences are used to represent +growable 1d arrays - vectors, stacks, queues, and deques. They have no gaps +in the middle - if an element is removed from the middle or inserted +into the middle of the sequence, the elements from the closer end are +shifted. Sparse sequences have :ocv:struct:`CvSet` as a base class and they are +discussed later in more detail. They are sequences of nodes; each may be either occupied or free as indicated by the node flag. Such sequences are used for unordered data structures such as sets of elements, graphs, hash tables and so forth. + + +CvSlice +------- + +.. ocv:struct:: CvSlice + + A sequence slice. In C++ interface the class :ocv:class:`Range` should be used instead. + + .. ocv:member:: int start_index + + inclusive start index of the sequence slice + + .. ocv:member:: int end_index + + exclusive end index of the sequence slice + +There are helper functions to construct the slice and to compute its length: + +.. ocv:cfunction:: CvSlice cvSlice( int start, int end ) + + :param start: Inclusive left boundary. + + :param end: Exclusive right boundary. + +:: + + #define CV_WHOLE_SEQ_END_INDEX 0x3fffffff + #define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) + +.. ocv:cfunction:: int cvSliceLength( CvSlice slice, const CvSeq* seq ) + + :param slice: The slice of sequence. + + :param seq: Source sequence. + +Calculates the sequence slice length. + +Some of functions that operate on sequences take a ``CvSlice slice`` parameter that is often set to the whole sequence (CV_WHOLE_SEQ) by default. Either of the ``start_index`` and ``end_index`` may be negative or exceed the sequence length. If they are equal, the slice is considered empty (i.e., contains no elements). Because sequences are treated as circular structures, the slice may select a +few elements in the end of a sequence followed by a few elements at the beginning of the sequence. For example, ``cvSlice(-2, 3)`` in the case of a 10-element sequence will select a 5-element slice, containing the pre-last (8th), last (9th), the very first (0th), second (1th) and third (2nd) +elements. The functions normalize the slice argument in the following way: + + #. :ocv:cfunc:`SliceLength` is called to determine the length of the slice, + #. ``start_index`` of the slice is normalized similarly to the argument of :ocv:cfunc:`GetSeqElem` (i.e., negative indices are allowed). The actual slice to process starts at the normalized ``start_index`` and lasts :ocv:cfunc:`SliceLength` elements (again, assuming the sequence is a circular structure). + +If a function does not accept a slice argument, but you want to process only a part of the sequence, the sub-sequence may be extracted using the :ocv:cfunc:`SeqSlice` function, or stored into a continuous +buffer with :ocv:cfunc:`CvtSeqToArray` (optionally, followed by :ocv:cfunc:`MakeSeqHeaderForArray`). + +CvSet +----- + +.. ocv:struct:: CvSet + +The structure ``CvSet`` is a base for OpenCV 1.x sparse data structures. It is derived from :ocv:struct:`CvSeq` and includes an additional member ``free_elems`` - a list of free nodes. Every node of the set, whether free or not, is an element of the underlying sequence. While there are no restrictions on elements of dense sequences, the set (and derived structures) elements must start with an integer field and be able to fit CvSetElem structure, because these two fields (an integer followed by a pointer) are required for the organization of a node set with the list of free nodes. If a node is free, the ``flags`` +field is negative (the most-significant bit, or MSB, of the field is set), and the ``next_free`` points to the next free node (the first free node is referenced by the ``free_elems`` field of :ocv:struct:`CvSet`). And if a node is occupied, the ``flags`` field is positive and contains the node index that may be retrieved using the (``set_elem->flags & CV_SET_ELEM_IDX_MASK``) expressions, the rest of the node content is determined by the user. In particular, the occupied nodes are not linked as the free nodes are, so the second field can be used for such a link as well as for some different purpose. The macro ``CV_IS_SET_ELEM(set_elem_ptr)`` can be used to determined whether the specified node is occupied or not. + +Initially the set and the free node list are empty. When a new node is requested from the set, it is taken from the list of free nodes, which is then updated. If the list appears to be empty, a new sequence block is allocated and all the nodes within the block are joined in the list of free nodes. Thus, the ``total`` +field of the set is the total number of nodes both occupied and free. When an occupied node is released, it is added to the list of free nodes. The node released last will be occupied first. + +``CvSet`` is used to represent graphs (:ocv:struct:`CvGraph`), sparse multi-dimensional arrays (:ocv:struct:`CvSparseMat`), and planar subdivisions (:ocv:struct:`CvSubdiv2D`). + +CvSetElem +--------- + +.. ocv:struct:: CvSetElem + +The structure is represent single element of :ocv:struct:`CvSet`. It consists of two fields: element data pointer and flags. + +CvGraph +------- +.. ocv:struct:: CvGraph + +The structure ``CvGraph`` is a base for graphs used in OpenCV 1.x. It inherits from +:ocv:struct:`CvSet`, that is, it is considered as a set of vertices. Besides, it contains another set as a member, a set of graph edges. Graphs in OpenCV are represented using adjacency lists format. + +CvGraphVtx +---------- +.. ocv:struct:: CvGraphVtx + +The structure represents single vertex in :ocv:struct:`CvGraph`. It consists of two filds: pointer to first edge and flags. + +CvGraphEdge +----------- +.. ocv:struct:: CvGraphEdge + +The structure represents edge in :ocv:struct:`CvGraph`. Each edge consists of: + +- Two pointers to the starting and ending vertices (vtx[0] and vtx[1] respectively); +- Two pointers to next edges for the starting and ending vertices, where + next[0] points to the next edge in the vtx[0] adjacency list and + next[1] points to the next edge in the vtx[1] adjacency list; +- Weight; +- Flags. + +CvGraphScanner +-------------- + +.. ocv:struct:: CvGraphScanner + +The structure ``CvGraphScanner`` is used for depth-first graph traversal. See discussion of the functions below. + + +CvTreeNodeIterator +------------------ + +.. ocv:struct:: CvTreeNodeIterator + +The structure ``CvTreeNodeIterator`` is used to traverse trees of sequences. + +ClearGraph +---------- +Clears a graph. + +.. ocv:cfunction:: void cvClearGraph( CvGraph* graph ) + + :param graph: Graph + +The function removes all vertices and edges from a graph. The function has O(1) time complexity. + +ClearMemStorage +--------------- +Clears memory storage. + +.. ocv:cfunction:: void cvClearMemStorage( CvMemStorage* storage ) + + :param storage: Memory storage + +The function resets the top (free space boundary) of the storage to the very beginning. This function does not deallocate any memory. If the storage has a parent, the function returns +all blocks to the parent. + +ClearSeq +-------- +Clears a sequence. + +.. ocv:cfunction:: void cvClearSeq( CvSeq* seq ) + + :param seq: Sequence + +The function removes all elements from a sequence. The function does not return the memory to the storage block, but this memory is reused later when new elements are added to the sequence. The function has +'O(1)' time complexity. + +.. note:: It is impossible to deallocate a sequence, i.e. free space in the memory storage occupied by the sequence. Instead, call :ocv:cfunc:`ClearMemStorage` or :ocv:cfunc:`ReleaseMemStorage` from time to time somewhere in a top-level processing loop. + +ClearSet +-------- +Clears a set. + +.. ocv:cfunction:: void cvClearSet( CvSet* set_header ) + + :param set_header: Cleared set + +The function removes all elements from set. It has O(1) time complexity. + +CloneGraph +---------- +Clones a graph. + +.. ocv:cfunction:: CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) + + :param graph: The graph to copy + + :param storage: Container for the copy + +The function creates a full copy of the specified graph. If the +graph vertices or edges have pointers to some external data, it can still be +shared between the copies. The vertex and edge indices in the new graph +may be different from the original because the function defragments +the vertex and edge sets. + +CloneSeq +-------- +Creates a copy of a sequence. + +.. ocv:cfunction:: CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage=NULL ) +.. ocv:pyoldfunction:: cv.CloneSeq(seq, storage)-> None + + :param seq: Sequence + + :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. + +The function makes a complete copy of the input sequence and returns it. + +The call ``cvCloneSeq( seq, storage )`` is equivalent to ``cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 )``. + + +CreateChildMemStorage +--------------------- +Creates child memory storage. + +.. ocv:cfunction:: CvMemStorage* cvCreateChildMemStorage(CvMemStorage* parent) + + :param parent: Parent memory storage + +The function creates a child memory +storage that is similar to simple memory storage except for the +differences in the memory allocation/deallocation mechanism. When a +child storage needs a new block to add to the block list, it tries +to get this block from the parent. The first unoccupied parent block +available is taken and excluded from the parent block list. If no blocks +are available, the parent either allocates a block or borrows one from +its own parent, if any. In other words, the chain, or a more complex +structure, of memory storages where every storage is a child/parent of +another is possible. When a child storage is released or even cleared, +it returns all blocks to the parent. In other aspects, child storage +is the same as simple storage. + +Child storage is useful in the following situation. Imagine +that the user needs to process dynamic data residing in a given storage area and +put the result back to that same storage area. With the simplest approach, +when temporary data is resided in the same storage area as the input and +output data, the storage area will look as follows after processing: + +Dynamic data processing without using child storage + +.. image:: pics/memstorage1.png + +That is, garbage appears in the middle of the storage. However, if +one creates a child memory storage at the beginning of processing, +writes temporary data there, and releases the child storage at the end, +no garbage will appear in the source/destination storage: + +Dynamic data processing using a child storage + +.. image:: pics/memstorage2.png + +CreateGraph +----------- +Creates an empty graph. + +.. ocv:cfunction:: CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size, int edge_size, CvMemStorage* storage ) + + + :param graph_flags: Type of the created graph. Usually, it is either ``CV_SEQ_KIND_GRAPH`` for generic unoriented graphs and ``CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED`` for generic oriented graphs. + + :param header_size: Graph header size; may not be less than ``sizeof(CvGraph)`` + + :param vtx_size: Graph vertex size; the custom vertex structure must start with :ocv:struct:`CvGraphVtx` (use ``CV_GRAPH_VERTEX_FIELDS()`` ) + + :param edge_size: Graph edge size; the custom edge structure must start with :ocv:struct:`CvGraphEdge` (use ``CV_GRAPH_EDGE_FIELDS()`` ) + + :param storage: The graph container + +The function creates an empty graph and returns a pointer to it. + +CreateGraphScanner +------------------ +Creates structure for depth-first graph traversal. + +.. ocv:cfunction:: CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL, int mask=CV_GRAPH_ALL_ITEMS ) + + + :param graph: Graph + + :param vtx: Initial vertex to start from. If NULL, the traversal starts from the first vertex (a vertex with the minimal index in the sequence of vertices). + + :param mask: Event mask indicating which events are of interest to the user (where :ocv:cfunc:`NextGraphItem` function returns control to the user) It can be ``CV_GRAPH_ALL_ITEMS`` (all events are of interest) or a combination of the following flags: + + * **CV_GRAPH_VERTEX** stop at the graph vertices visited for the first time + + * **CV_GRAPH_TREE_EDGE** stop at tree edges ( ``tree edge`` is the edge connecting the last visited vertex and the vertex to be visited next) + + * **CV_GRAPH_BACK_EDGE** stop at back edges ( ``back edge`` is an edge connecting the last visited vertex with some of its ancestors in the search tree) + + * **CV_GRAPH_FORWARD_EDGE** stop at forward edges ( ``forward edge`` is an edge connecting the last visited vertex with some of its descendants in the search tree. The forward edges are only possible during oriented graph traversal) + + * **CV_GRAPH_CROSS_EDGE** stop at cross edges ( ``cross edge`` is an edge connecting different search trees or branches of the same tree. The ``cross edges`` are only possible during oriented graph traversal) + + * **CV_GRAPH_ANY_EDGE** stop at any edge ( ``tree, back, forward`` , and ``cross edges`` ) + + * **CV_GRAPH_NEW_TREE** stop in the beginning of every new search tree. When the traversal procedure visits all vertices and edges reachable from the initial vertex (the visited vertices together with tree edges make up a tree), it searches for some unvisited vertex in the graph and resumes the traversal process from that vertex. Before starting a new tree (including the very first tree when ``cvNextGraphItem`` is called for the first time) it generates a ``CV_GRAPH_NEW_TREE`` event. For unoriented graphs, each search tree corresponds to a connected component of the graph. + + * **CV_GRAPH_BACKTRACKING** stop at every already visited vertex during backtracking - returning to already visited vertexes of the traversal tree. + +The function creates a structure for depth-first graph traversal/search. The initialized structure is used in the +:ocv:cfunc:`NextGraphItem` +function - the incremental traversal procedure. + +CreateMemStorage +---------------- +Creates memory storage. + +.. ocv:cfunction:: CvMemStorage* cvCreateMemStorage( int block_size=0 ) + +.. ocv:pyoldfunction:: cv.CreateMemStorage(blockSize=0) -> memstorage + + + :param block_size: Size of the storage blocks in bytes. If it is 0, the block size is set to a default value - currently it is about 64K. + +The function creates an empty memory storage. See +:ocv:struct:`CvMemStorage` +description. + +CreateSeq +--------- +Creates a sequence. + +.. ocv:cfunction:: CvSeq* cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* storage ) + + + :param seq_flags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be set to 0, otherwise the appropriate type must be selected from the list of predefined sequence types. + + :param header_size: Size of the sequence header; must be greater than or equal to ``sizeof(CvSeq)`` . If a specific type or its extension is indicated, this type must fit the base type header. + + :param elem_size: Size of the sequence elements in bytes. The size must be consistent with the sequence type. For example, for a sequence of points to be created, the element type ``CV_SEQ_ELTYPE_POINT`` should be specified and the parameter ``elem_size`` must be equal to ``sizeof(CvPoint)`` . + + :param storage: Sequence location + +The function creates a sequence and returns +the pointer to it. The function allocates the sequence header in +the storage block as one continuous chunk and sets the structure +fields +``flags`` +, +``elemSize`` +, +``headerSize`` +, and +``storage`` +to passed values, sets +``delta_elems`` +to the +default value (that may be reassigned using the +:ocv:cfunc:`SetSeqBlockSize` +function), and clears other header fields, including the space following +the first +``sizeof(CvSeq)`` +bytes. + +CreateSet +--------- +Creates an empty set. + +.. ocv:cfunction:: CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage* storage ) + + :param set_flags: Type of the created set + + :param header_size: Set header size; may not be less than ``sizeof(CvSet)`` + + :param elem_size: Set element size; may not be less than :ocv:struct:`CvSetElem` + + :param storage: Container for the set + +The function creates an empty set with a specified header size and element size, and returns the pointer to the set. This function is just a thin layer on top of +:ocv:cfunc:`CreateSeq`. + +CvtSeqToArray +------------- +Copies a sequence to one continuous block of memory. + +.. ocv:cfunction:: void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ ) + + :param seq: Sequence + + :param elements: Pointer to the destination array that must be large enough. It should be a pointer to data, not a matrix header. + + :param slice: The sequence portion to copy to the array + +The function copies the entire sequence or subsequence to the specified buffer and returns the pointer to the buffer. + +EndWriteSeq +----------- +Finishes the process of writing a sequence. + +.. ocv:cfunction:: CvSeq* cvEndWriteSeq( CvSeqWriter* writer ) + + :param writer: Writer state + +The function finishes the writing process and +returns the pointer to the written sequence. The function also truncates +the last incomplete sequence block to return the remaining part of the +block to memory storage. After that, the sequence can be read and +modified safely. See +:ocv:cfunc:`StartWriteSeq` +and +:ocv:cfunc:`StartAppendToSeq` + +FindGraphEdge +------------- +Finds an edge in a graph. + +.. ocv:cfunction:: CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +:: + + #define cvGraphFindEdge cvFindGraphEdge + +.. + +The function finds the graph edge connecting two specified vertices and returns a pointer to it or NULL if the edge does not exist. + +FindGraphEdgeByPtr +------------------ +Finds an edge in a graph by using its pointer. + +.. ocv:cfunction:: CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* start_vtx, const CvGraphVtx* end_vtx ) + + :param graph: Graph + + :param start_vtx: Pointer to the starting vertex of the edge + + :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +:: + + #define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr + +.. + +The function finds the graph edge connecting two specified vertices and returns pointer to it or NULL if the edge does not exists. + +FlushSeqWriter +-------------- +Updates sequence headers from the writer. + +.. ocv:cfunction:: void cvFlushSeqWriter( CvSeqWriter* writer ) + + :param writer: Writer state + +The function is intended to enable the user to +read sequence elements, whenever required, during the writing process, +e.g., in order to check specific conditions. The function updates the +sequence headers to make reading from the sequence possible. The writer +is not closed, however, so that the writing process can be continued at +any time. If an algorithm requires frequent flushes, consider using +:ocv:cfunc:`SeqPush` +instead. + +GetGraphVtx +----------- +Finds a graph vertex by using its index. + +.. ocv:cfunction:: CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx ) + + :param graph: Graph + + :param vtx_idx: Index of the vertex + +The function finds the graph vertex by using its index and returns the pointer to it or NULL if the vertex does not belong to the graph. + +GetSeqElem +---------- +Returns a pointer to a sequence element according to its index. + +.. ocv:cfunction:: schar* cvGetSeqElem( const CvSeq* seq, int index ) + + :param seq: Sequence + + :param index: Index of element + +:: + + #define CV_GET_SEQ_ELEM( TYPE, seq, index ) (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) ) + +.. + + +The function finds the element with the given +index in the sequence and returns the pointer to it. If the element +is not found, the function returns 0. The function supports negative +indices, where -1 stands for the last sequence element, -2 stands for +the one before last, etc. If the sequence is most likely to consist of +a single sequence block or the desired element is likely to be located +in the first block, then the macro +``CV_GET_SEQ_ELEM( elemType, seq, index )`` +should be used, where the parameter +``elemType`` +is the +type of sequence elements ( +:ocv:struct:`CvPoint` +for example), the parameter +``seq`` +is a sequence, and the parameter +``index`` +is the index +of the desired element. The macro checks first whether the desired element +belongs to the first block of the sequence and returns it if it does; +otherwise the macro calls the main function +``GetSeqElem`` +. Negative +indices always cause the +:ocv:cfunc:`GetSeqElem` +call. The function has O(1) +time complexity assuming that the number of blocks is much smaller than the +number of elements. + +GetSeqReaderPos +--------------- +Returns the current reader position. + +.. ocv:cfunction:: int cvGetSeqReaderPos( CvSeqReader* reader ) + + :param reader: Reader state + +The function returns the current reader position (within 0 ... +``reader->seq->total`` +- 1). + +GetSetElem +---------- +Finds a set element by its index. + +.. ocv:cfunction:: CvSetElem* cvGetSetElem( const CvSet* set_header, int idx ) + + :param set_header: Set + + :param idx: Index of the set element within a sequence + +The function finds a set element by its index. The function returns the pointer to it or 0 if the index is invalid or the corresponding node is free. The function supports negative indices as it uses +:ocv:cfunc:`GetSeqElem` +to locate the node. + +GraphAddEdge +------------ +Adds an edge to a graph. + +.. ocv:cfunction:: int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + + :param edge: Optional input parameter, initialization data for the edge + + :param inserted_edge: Optional output parameter to contain the address of the inserted edge + +The function connects two specified vertices. The function returns 1 if the edge has been added successfully, 0 if the edge connecting the two vertices exists already and -1 if either of the vertices was not found, the starting and the ending vertex are the same, or there is some other critical situation. In the latter case (i.e., when the result is negative), the function also reports an error by default. + +GraphAddEdgeByPtr +----------------- +Adds an edge to a graph by using its pointer. + +.. ocv:cfunction:: int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) + + :param graph: Graph + + :param start_vtx: Pointer to the starting vertex of the edge + + :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + + :param edge: Optional input parameter, initialization data for the edge + + :param inserted_edge: Optional output parameter to contain the address of the inserted edge within the edge set + +The function connects two specified vertices. The +function returns 1 if the edge has been added successfully, 0 if the +edge connecting the two vertices exists already, and -1 if either of the +vertices was not found, the starting and the ending vertex are the same +or there is some other critical situation. In the latter case (i.e., when +the result is negative), the function also reports an error by default. + +GraphAddVtx +----------- +Adds a vertex to a graph. + +.. ocv:cfunction:: int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL, CvGraphVtx** inserted_vtx=NULL ) + + :param graph: Graph + + :param vtx: Optional input argument used to initialize the added vertex (only user-defined fields beyond ``sizeof(CvGraphVtx)`` are copied) + + :param inserted_vtx: Optional output argument. If not ``NULL`` , the address of the new vertex is written here. + +The function adds a vertex to the graph and returns the vertex index. + +GraphEdgeIdx +------------ +Returns the index of a graph edge. + +.. ocv:cfunction:: int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge ) + + :param graph: Graph + + :param edge: Pointer to the graph edge + +The function returns the index of a graph edge. + +GraphRemoveEdge +--------------- +Removes an edge from a graph. + +.. ocv:cfunction:: void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. + +GraphRemoveEdgeByPtr +-------------------- +Removes an edge from a graph by using its pointer. + +.. ocv:cfunction:: void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ) + + :param graph: Graph + + :param start_vtx: Pointer to the starting vertex of the edge + + :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. + +GraphRemoveVtx +-------------- +Removes a vertex from a graph. + +.. ocv:cfunction:: int cvGraphRemoveVtx( CvGraph* graph, int index ) + + :param graph: Graph + + :param index: Index of the removed vertex + +The function removes a vertex from a graph +together with all the edges incident to it. The function reports an error +if the input vertex does not belong to the graph. The return value is the +number of edges deleted, or -1 if the vertex does not belong to the graph. + +GraphRemoveVtxByPtr +------------------- +Removes a vertex from a graph by using its pointer. + +.. ocv:cfunction:: int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the removed vertex + +The function removes a vertex from the graph by using its pointer together with all the edges incident to it. The function reports an error if the vertex does not belong to the graph. The return value is the number of edges deleted, or -1 if the vertex does not belong to the graph. + +GraphVtxDegree +-------------- +Counts the number of edges incident to the vertex. + +.. ocv:cfunction:: int cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ) + + :param graph: Graph + + :param vtx_idx: Index of the graph vertex + +The function returns the number of edges incident to the specified vertex, both incoming and outgoing. To count the edges, the following code is used: + +:: + + CvGraphEdge* edge = vertex->first; int count = 0; + while( edge ) + { + edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); + count++; + } + +.. + +The macro +``CV_NEXT_GRAPH_EDGE( edge, vertex )`` +returns the edge incident to +``vertex`` +that follows after +``edge`` +. + +GraphVtxDegreeByPtr +------------------- +Finds an edge in a graph. + +.. ocv:cfunction:: int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the graph vertex + +The function returns the number of edges incident to the specified vertex, both incoming and outcoming. + +GraphVtxIdx +----------- +Returns the index of a graph vertex. + +.. ocv:cfunction:: int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the graph vertex + +The function returns the index of a graph vertex. + +InitTreeNodeIterator +-------------------- +Initializes the tree node iterator. + +.. ocv:cfunction:: void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, const void* first, int max_level ) + + :param tree_iterator: Tree iterator initialized by the function + + :param first: The initial node to start traversing from + + :param max_level: The maximal level of the tree ( ``first`` node assumed to be at the first level) to traverse up to. For example, 1 means that only nodes at the same level as ``first`` should be visited, 2 means that the nodes on the same level as ``first`` and their direct children should be visited, and so forth. + +The function initializes the tree iterator. The tree is traversed in depth-first order. + +InsertNodeIntoTree +------------------ +Adds a new node to a tree. + +.. ocv:cfunction:: void cvInsertNodeIntoTree( void* node, void* parent, void* frame ) + + :param node: The inserted node + + :param parent: The parent node that is already in the tree + + :param frame: The top level node. If ``parent`` and ``frame`` are the same, the ``v_prev`` field of ``node`` is set to NULL rather than ``parent`` . + +The function adds another node into tree. The function does not allocate any memory, it can only modify links of the tree nodes. + +MakeSeqHeaderForArray +--------------------- +Constructs a sequence header for an array. + +.. ocv:cfunction:: CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block ) + + :param seq_type: Type of the created sequence + + :param header_size: Size of the header of the sequence. Parameter sequence must point to the structure of that size or greater + + :param elem_size: Size of the sequence elements + + :param elements: Elements that will form a sequence + + :param total: Total number of elements in the sequence. The number of array elements must be equal to the value of this parameter. + + :param seq: Pointer to the local variable that is used as the sequence header + + :param block: Pointer to the local variable that is the header of the single sequence block + +The function initializes a sequence +header for an array. The sequence header as well as the sequence block are +allocated by the user (for example, on stack). No data is copied by the +function. The resultant sequence will consists of a single block and +have NULL storage pointer; thus, it is possible to read its elements, +but the attempts to add elements to the sequence will raise an error in +most cases. + +MemStorageAlloc +--------------- +Allocates a memory buffer in a storage block. + +.. ocv:cfunction:: void* cvMemStorageAlloc( CvMemStorage* storage, size_t size ) + + :param storage: Memory storage + + :param size: Buffer size + +The function allocates a memory buffer in +a storage block. The buffer size must not exceed the storage block size, +otherwise a runtime error is raised. The buffer address is aligned by +``CV_STRUCT_ALIGN=sizeof(double)`` +(for the moment) bytes. + +MemStorageAllocString +--------------------- +Allocates a text string in a storage block. + +.. ocv:cfunction:: CvString cvMemStorageAllocString(CvMemStorage* storage, const char* ptr, int len=-1) + + :param storage: Memory storage + + :param ptr: The string + + :param len: Length of the string (not counting the ending ``NUL`` ) . If the parameter is negative, the function computes the length. + +:: + + typedef struct CvString + { + int len; + char* ptr; + } + CvString; + +.. + +The function creates copy of the string +in memory storage. It returns the structure that contains user-passed +or computed length of the string and pointer to the copied string. + +NextGraphItem +------------- +Executes one or more steps of the graph traversal procedure. + +.. ocv:cfunction:: int cvNextGraphItem( CvGraphScanner* scanner ) + + :param scanner: Graph traversal state. It is updated by this function. + +The function traverses through the graph +until an event of interest to the user (that is, an event, specified +in the +``mask`` +in the +:ocv:cfunc:`CreateGraphScanner` +call) is met or the +traversal is completed. In the first case, it returns one of the events +listed in the description of the +``mask`` +parameter above and with +the next call it resumes the traversal. In the latter case, it returns +``CV_GRAPH_OVER`` +(-1). When the event is +``CV_GRAPH_VERTEX`` +, +``CV_GRAPH_BACKTRACKING`` +, or +``CV_GRAPH_NEW_TREE`` +, +the currently observed vertex is stored in +``scanner-:math:`>`vtx`` +. And if the +event is edge-related, the edge itself is stored at +``scanner-:math:`>`edge`` +, +the previously visited vertex - at +``scanner-:math:`>`vtx`` +and the other ending +vertex of the edge - at +``scanner-:math:`>`dst`` +. + +NextTreeNode +------------ +Returns the currently observed node and moves the iterator toward the next node. + +.. ocv:cfunction:: void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator ) + + :param tree_iterator: Tree iterator initialized by the function + +The function returns the currently observed node and then updates the +iterator - moving it toward the next node. In other words, the function +behavior is similar to the +``*p++`` +expression on a typical C +pointer or C++ collection iterator. The function returns NULL if there +are no more nodes. + +PrevTreeNode +------------ +Returns the currently observed node and moves the iterator toward the previous node. + +.. ocv:cfunction:: void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ) + + :param tree_iterator: Tree iterator initialized by the function + +The function returns the currently observed node and then updates +the iterator - moving it toward the previous node. In other words, +the function behavior is similar to the +``*p--`` +expression on a +typical C pointer or C++ collection iterator. The function returns NULL +if there are no more nodes. + +ReleaseGraphScanner +------------------- +Completes the graph traversal procedure. + +.. ocv:cfunction:: void cvReleaseGraphScanner( CvGraphScanner** scanner ) + + :param scanner: Double pointer to graph traverser + +The function completes the graph traversal procedure and releases the traverser state. + +ReleaseMemStorage +----------------- +Releases memory storage. + +.. ocv:cfunction:: void cvReleaseMemStorage( CvMemStorage** storage ) + + :param storage: Pointer to the released storage + +The function deallocates all storage memory +blocks or returns them to the parent, if any. Then it deallocates the +storage header and clears the pointer to the storage. All child storage +associated with a given parent storage block must be released before the +parent storage block is released. + +RestoreMemStoragePos +-------------------- +Restores memory storage position. + +.. ocv:cfunction:: void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos) + + :param storage: Memory storage + + :param pos: New storage top position + +The function restores the position of the storage top from the parameter +``pos`` +. This function and the function +``cvClearMemStorage`` +are the only methods to release memory occupied in memory blocks. Note again that there is no way to free memory in the middle of an occupied portion of a storage block. + +SaveMemStoragePos +----------------- +Saves memory storage position. + +.. ocv:cfunction:: void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos) + + :param storage: Memory storage + + :param pos: The output position of the storage top + +The function saves the current position +of the storage top to the parameter +``pos`` +. The function +``cvRestoreMemStoragePos`` +can further retrieve this position. + +SeqElemIdx +---------- +Returns the index of a specific sequence element. + +.. ocv:cfunction:: int cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block=NULL ) + + :param seq: Sequence + + :param element: Pointer to the element within the sequence + + :param block: Optional argument. If the pointer is not ``NULL`` , the address of the sequence block that contains the element is stored in this location. + +The function returns the index of a sequence element or a negative number if the element is not found. + +SeqInsert +--------- +Inserts an element in the middle of a sequence. + +.. ocv:cfunction:: schar* cvSeqInsert( CvSeq* seq, int before_index, const void* element=NULL ) + + :param seq: Sequence + + :param before_index: Index before which the element is inserted. Inserting before 0 (the minimal allowed value of the parameter) is equal to :ocv:cfunc:`SeqPushFront` and inserting before ``seq->total`` (the maximal allowed value of the parameter) is equal to :ocv:cfunc:`SeqPush` . + + :param element: Inserted element + +The function shifts the sequence elements from the inserted position to the nearest end of the sequence and copies the +``element`` +content there if the pointer is not NULL. The function returns a pointer to the inserted element. + +SeqInsertSlice +-------------- +Inserts an array in the middle of a sequence. + +.. ocv:cfunction:: void cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ) + + :param seq: Sequence + + :param before_index: Index before which the array is inserted + + :param from_arr: The array to take elements from + +The function inserts all +``fromArr`` +array elements at the specified position of the sequence. The array +``fromArr`` +can be a matrix or another sequence. + +SeqInvert +--------- +Reverses the order of sequence elements. + +.. ocv:cfunction:: void cvSeqInvert( CvSeq* seq ) + + :param seq: Sequence + +The function reverses the sequence in-place - the first element becomes the last one, the last element becomes the first one and so forth. + +SeqPop +------ +Removes an element from the end of a sequence. + +.. ocv:cfunction:: void cvSeqPop( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Optional parameter . If the pointer is not zero, the function copies the removed element to this location. + +The function removes an element from a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. + +SeqPopFront +----------- +Removes an element from the beginning of a sequence. + +.. ocv:cfunction:: void cvSeqPopFront( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Optional parameter. If the pointer is not zero, the function copies the removed element to this location. + +The function removes an element from the beginning of a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. + +SeqPopMulti +----------- +Removes several elements from either end of a sequence. + +.. ocv:cfunction:: void cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front=0 ) + + :param seq: Sequence + + :param elements: Removed elements + + :param count: Number of elements to pop + + :param in_front: The flags specifying which end of the modified sequence. + + * **CV_BACK** the elements are added to the end of the sequence + + * **CV_FRONT** the elements are added to the beginning of the sequence + +The function removes several elements from either end of the sequence. If the number of the elements to be removed exceeds the total number of elements in the sequence, the function removes as many elements as possible. + +SeqPush +------- +Adds an element to the end of a sequence. + +.. ocv:cfunction:: schar* cvSeqPush( CvSeq* seq, const void* element=NULL ) + + :param seq: Sequence + + :param element: Added element + +The function adds an element to the end of a sequence and returns a pointer to the allocated element. If the input +``element`` +is NULL, the function simply allocates a space for one more element. + +The following code demonstrates how to create a new sequence using this function: + +:: + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC1, /* sequence of integer elements */ + sizeof(CvSeq), /* header size - no extra fields */ + sizeof(int), /* element size */ + storage /* the container storage */ ); + int i; + for( i = 0; i < 100; i++ ) + { + int* added = (int*)cvSeqPush( seq, &i ); + printf( " + } + + ... + /* release memory storage in the end */ + cvReleaseMemStorage( &storage ); + +.. + +The function has O(1) complexity, but there is a faster method for writing large sequences (see +:ocv:cfunc:`StartWriteSeq` +and related functions). + +SeqPushFront +------------ +Adds an element to the beginning of a sequence. + +.. ocv:cfunction:: schar* cvSeqPushFront( CvSeq* seq, const void* element=NULL ) + + :param seq: Sequence + + :param element: Added element + +The function is similar to +:ocv:cfunc:`SeqPush` +but it adds the new element to the beginning of the sequence. The function has O(1) complexity. + +SeqPushMulti +------------ +Pushes several elements to either end of a sequence. + +.. ocv:cfunction:: void cvSeqPushMulti( CvSeq* seq, const void* elements, int count, int in_front=0 ) + + :param seq: Sequence + + :param elements: Added elements + + :param count: Number of elements to push + + :param in_front: The flags specifying which end of the modified sequence. + + * **CV_BACK** the elements are added to the end of the sequence + + * **CV_FRONT** the elements are added to the beginning of the sequence + +The function adds several elements to either +end of a sequence. The elements are added to the sequence in the same +order as they are arranged in the input array but they can fall into +different sequence blocks. + +SeqRemove +--------- +Removes an element from the middle of a sequence. + +.. ocv:cfunction:: void cvSeqRemove( CvSeq* seq, int index ) + + :param seq: Sequence + + :param index: Index of removed element + +The function removes elements with the given +index. If the index is out of range the function reports an error. An +attempt to remove an element from an empty sequence is a special +case of this situation. The function removes an element by shifting +the sequence elements between the nearest end of the sequence and the +``index`` +-th position, not counting the latter. + +SeqRemoveSlice +-------------- +Removes a sequence slice. + +.. ocv:cfunction:: void cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) + + :param seq: Sequence + + :param slice: The part of the sequence to remove + +The function removes a slice from the sequence. + +SeqSearch +--------- +Searches for an element in a sequence. + +.. ocv:cfunction:: schar* cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, int is_sorted, int* elem_idx, void* userdata=NULL ) + + :param seq: The sequence + + :param elem: The element to look for + + :param func: The comparison function that returns negative, zero or positive value depending on the relationships among the elements (see also :ocv:cfunc:`SeqSort` ) + + :param is_sorted: Whether the sequence is sorted or not + + :param elem_idx: Output parameter; index of the found element + + :param userdata: The user parameter passed to the comparison function; helps to avoid global variables in some cases + +:: + + /* a < b ? -1 : a > b ? 1 : 0 */ + typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); + +.. + +The function searches for the element in the sequence. If +the sequence is sorted, a binary O(log(N)) search is used; otherwise, a +simple linear search is used. If the element is not found, the function +returns a NULL pointer and the index is set to the number of sequence +elements if a linear search is used, or to the smallest index +``i, seq(i)>elem`` +. + +SeqSlice +-------- +Makes a separate header for a sequence slice. + +.. ocv:cfunction:: CvSeq* cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage=NULL, int copy_data=0 ) + + :param seq: Sequence + + :param slice: The part of the sequence to be extracted + + :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. + + :param copy_data: The flag that indicates whether to copy the elements of the extracted slice ( ``copy_data!=0`` ) or not ( ``copy_data=0`` ) + +The function creates a sequence that represents the specified slice of the input sequence. The new sequence either shares the elements with the original sequence or has its own copy of the elements. So if one needs to process a part of sequence but the processing function does not have a slice parameter, the required sub-sequence may be extracted using this function. + +SeqSort +------- +Sorts sequence element using the specified comparison function. + +.. ocv:cfunction:: void cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata=NULL ) + + :param seq: The sequence to sort + + :param func: The comparison function that returns a negative, zero, or positive value depending on the relationships among the elements (see the above declaration and the example below) - a similar function is used by ``qsort`` from C runline except that in the latter, ``userdata`` is not used + + :param userdata: The user parameter passed to the comparison function; helps to avoid global variables in some cases + +:: + + /* a < b ? -1 : a > b ? 1 : 0 */ + typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); + +.. + +The function sorts the sequence in-place using the specified criteria. Below is an example of using this function: + +:: + + /* Sort 2d points in top-to-bottom left-to-right order */ + static int cmp_func( const void* _a, const void* _b, void* userdata ) + { + CvPoint* a = (CvPoint*)_a; + CvPoint* b = (CvPoint*)_b; + int y_diff = a->y - b->y; + int x_diff = a->x - b->x; + return y_diff ? y_diff : x_diff; + } + + ... + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); + int i; + + for( i = 0; i < 10; i++ ) + { + CvPoint pt; + pt.x = rand() + pt.y = rand() + cvSeqPush( seq, &pt ); + } + + cvSeqSort( seq, cmp_func, 0 /* userdata is not used here */ ); + + /* print out the sorted sequence */ + for( i = 0; i < seq->total; i++ ) + { + CvPoint* pt = (CvPoint*)cvSeqElem( seq, i ); + printf( "( + } + + cvReleaseMemStorage( &storage ); + +.. + +SetAdd +------ +Occupies a node in the set. + +.. ocv:cfunction:: int cvSetAdd( CvSet* set_header, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL ) + + :param set_header: Set + + :param elem: Optional input argument, an inserted element. If not NULL, the function copies the data to the allocated node (the MSB of the first integer field is cleared after copying). + + :param inserted_elem: Optional output argument; the pointer to the allocated cell + +The function allocates a new node, optionally copies +input element data to it, and returns the pointer and the index to the +node. The index value is taken from the lower bits of the +``flags`` +field of the node. The function has O(1) complexity; however, there exists +a faster function for allocating set nodes (see +:ocv:cfunc:`SetNew` +). + +SetNew +------ +Adds an element to a set (fast variant). + +.. ocv:cfunction:: CvSetElem* cvSetNew( CvSet* set_header ) + + :param set_header: Set + +The function is an inline lightweight variant of +:ocv:cfunc:`SetAdd` +. It occupies a new node and returns a pointer to it rather than an index. + +SetRemove +--------- +Removes an element from a set. + +.. ocv:cfunction:: void cvSetRemove( CvSet* set_header, int index ) + + :param set_header: Set + + :param index: Index of the removed element + +The function removes an element with a specified +index from the set. If the node at the specified location is not occupied, +the function does nothing. The function has O(1) complexity; however, +:ocv:cfunc:`SetRemoveByPtr` +provides a quicker way to remove a set element +if it is located already. + +SetRemoveByPtr +-------------- +Removes a set element based on its pointer. + +.. ocv:cfunction:: void cvSetRemoveByPtr( CvSet* set_header, void* elem ) + + :param set_header: Set + + :param elem: Removed element + +The function is an inline lightweight variant of +:ocv:cfunc:`SetRemove` +that requires an element pointer. The function does not check whether the node is occupied or not - the user should take care of that. + +SetSeqBlockSize +--------------- +Sets up sequence block size. + +.. ocv:cfunction:: void cvSetSeqBlockSize( CvSeq* seq, int delta_elems ) + + :param seq: Sequence + + :param delta_elems: Desirable sequence block size for elements + +The function affects memory allocation +granularity. When the free space in the sequence buffers has run out, +the function allocates the space for +``delta_elems`` +sequence +elements. If this block immediately follows the one previously allocated, +the two blocks are concatenated; otherwise, a new sequence block is +created. Therefore, the bigger the parameter is, the lower the possible +sequence fragmentation, but the more space in the storage block is wasted. When +the sequence is created, the parameter +``delta_elems`` +is set to +the default value of about 1K. The function can be called any time after +the sequence is created and affects future allocations. The function +can modify the passed value of the parameter to meet memory storage +constraints. + +SetSeqReaderPos +--------------- +Moves the reader to the specified position. + +.. ocv:cfunction:: void cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative=0 ) + + :param reader: Reader state + + :param index: The destination position. If the positioning mode is used (see the next parameter), the actual position will be ``index`` mod ``reader->seq->total`` . + + :param is_relative: If it is not zero, then ``index`` is a relative to the current position + +The function moves the read position to an absolute position or relative to the current position. + +StartAppendToSeq +---------------- +Initializes the process of writing data to a sequence. + +.. ocv:cfunction:: void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ) + + :param seq: Pointer to the sequence + + :param writer: Writer state; initialized by the function + +The function initializes the process of +writing data to a sequence. Written elements are added to the end of the +sequence by using the +``CV_WRITE_SEQ_ELEM( written_elem, writer )`` +macro. Note +that during the writing process, other operations on the sequence may +yield an incorrect result or even corrupt the sequence (see description of +:ocv:cfunc:`FlushSeqWriter` +, which helps to avoid some of these problems). + +StartReadSeq +------------ +Initializes the process of sequential reading from a sequence. + +.. ocv:cfunction:: void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse=0 ) + + :param seq: Sequence + + :param reader: Reader state; initialized by the function + + :param reverse: Determines the direction of the sequence traversal. If ``reverse`` is 0, the reader is positioned at the first sequence element; otherwise it is positioned at the last element. + +The function initializes the reader state. After +that, all the sequence elements from the first one down to the last one +can be read by subsequent calls of the macro +``CV_READ_SEQ_ELEM( read_elem, reader )`` +in the case of forward reading and by using +``CV_REV_READ_SEQ_ELEM( read_elem, reader )`` +in the case of reverse +reading. Both macros put the sequence element to +``read_elem`` +and +move the reading pointer toward the next element. A circular structure +of sequence blocks is used for the reading process, that is, after the +last element has been read by the macro +``CV_READ_SEQ_ELEM`` +, the +first element is read when the macro is called again. The same applies to +``CV_REV_READ_SEQ_ELEM`` +. There is no function to finish the reading +process, since it neither changes the sequence nor creates any temporary +buffers. The reader field +``ptr`` +points to the current element of +the sequence that is to be read next. The code below demonstrates how +to use the sequence writer and reader. + +:: + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); + CvSeqWriter writer; + CvSeqReader reader; + int i; + + cvStartAppendToSeq( seq, &writer ); + for( i = 0; i < 10; i++ ) + { + int val = rand() + CV_WRITE_SEQ_ELEM( val, writer ); + printf(" + } + cvEndWriteSeq( &writer ); + + cvStartReadSeq( seq, &reader, 0 ); + for( i = 0; i < seq->total; i++ ) + { + int val; + #if 1 + CV_READ_SEQ_ELEM( val, reader ); + printf(" + #else /* alternative way, that is prefferable if sequence elements are large, + or their size/type is unknown at compile time */ + printf(" + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + #endif + } + ... + + cvReleaseStorage( &storage ); + +.. + +StartWriteSeq +------------- +Creates a new sequence and initializes a writer for it. + +.. ocv:cfunction:: void cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer ) + + :param seq_flags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be equal to 0; otherwise the appropriate type must be selected from the list of predefined sequence types. + + :param header_size: Size of the sequence header. The parameter value may not be less than ``sizeof(CvSeq)`` . If a certain type or extension is specified, it must fit within the base type header. + + :param elem_size: Size of the sequence elements in bytes; must be consistent with the sequence type. For example, if a sequence of points is created (element type ``CV_SEQ_ELTYPE_POINT`` ), then the parameter ``elem_size`` must be equal to ``sizeof(CvPoint)`` . + + :param storage: Sequence location + + :param writer: Writer state; initialized by the function + +The function is a combination of +:ocv:cfunc:`CreateSeq` +and +:ocv:cfunc:`StartAppendToSeq` +. The pointer to the +created sequence is stored at +``writer->seq`` +and is also returned by the +:ocv:cfunc:`EndWriteSeq` +function that should be called at the end. + +TreeToNodeSeq +------------- +Gathers all node pointers to a single sequence. + +.. ocv:cfunction:: CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) + + :param first: The initial tree node + + :param header_size: Header size of the created sequence (sizeof(CvSeq) is the most frequently used value) + + :param storage: Container for the sequence + +The function puts pointers of all nodes reachable from ``first`` into a single sequence. The pointers are written sequentially in the depth-first order. + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/intro.rst diffimg-2.0.0/3rdparty/opencv/core/doc/intro.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/intro.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/intro.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,229 @@ +************ +Introduction +************ + +.. highlight:: cpp + +OpenCV (Open Source Computer Vision Library: http://opencv.org) is an open-source BSD-licensed library that includes several hundreds of computer vision algorithms. The document describes the so-called OpenCV 2.x API, which is essentially a C++ API, as opposite to the C-based OpenCV 1.x API. The latter is described in opencv1x.pdf. + +OpenCV has a modular structure, which means that the package includes several shared or static libraries. The following modules are available: + + * **core** - a compact module defining basic data structures, including the dense multi-dimensional array ``Mat`` and basic functions used by all other modules. + * **imgproc** - an image processing module that includes linear and non-linear image filtering, geometrical image transformations (resize, affine and perspective warping, generic table-based remapping), color space conversion, histograms, and so on. + * **video** - a video analysis module that includes motion estimation, background subtraction, and object tracking algorithms. + * **calib3d** - basic multiple-view geometry algorithms, single and stereo camera calibration, object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction. + * **features2d** - salient feature detectors, descriptors, and descriptor matchers. + * **objdetect** - detection of objects and instances of the predefined classes (for example, faces, eyes, mugs, people, cars, and so on). + * **highgui** - an easy-to-use interface to video capturing, image and video codecs, as well as simple UI capabilities. + * **gpu** - GPU-accelerated algorithms from different OpenCV modules. + * ... some other helper modules, such as FLANN and Google test wrappers, Python bindings, and others. + +The further chapters of the document describe functionality of each module. But first, make sure to get familiar with the common API concepts used thoroughly in the library. + +API Concepts +================ + +``cv`` Namespace +------------------ + +All the OpenCV classes and functions are placed into the ``cv`` namespace. Therefore, to access this functionality from your code, use the ``cv::`` specifier or ``using namespace cv;`` directive: + +.. code-block:: c + + #include "opencv2/core/core.hpp" + ... + cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5); + ... + +or :: + + #include "opencv2/core/core.hpp" + using namespace cv; + ... + Mat H = findHomography(points1, points2, CV_RANSAC, 5 ); + ... + +Some of the current or future OpenCV external names may conflict with STL +or other libraries. In this case, use explicit namespace specifiers to resolve the name conflicts: :: + + Mat a(100, 100, CV_32F); + randu(a, Scalar::all(1), Scalar::all(std::rand())); + cv::log(a, a); + a /= std::log(2.); + +Automatic Memory Management +--------------------------- + +OpenCV handles all the memory automatically. + +First of all, ``std::vector``, ``Mat``, and other data structures used by the functions and methods have destructors that deallocate the underlying memory buffers when needed. This means that the destructors do not always deallocate the buffers as in case of ``Mat``. They take into account possible data sharing. A destructor decrements the reference counter associated with the matrix data buffer. The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other structures refer to the same buffer. Similarly, when a ``Mat`` instance is copied, no actual data is really copied. Instead, the reference counter is incremented to memorize that there is another owner of the same data. There is also the ``Mat::clone`` method that creates a full copy of the matrix data. See the example below: :: + + // create a big 8Mb matrix + Mat A(1000, 1000, CV_64F); + + // create another header for the same matrix; + // this is an instant operation, regardless of the matrix size. + Mat B = A; + // create another header for the 3-rd row of A; no data is copied either + Mat C = B.row(3); + // now create a separate copy of the matrix + Mat D = B.clone(); + // copy the 5-th row of B to C, that is, copy the 5-th row of A + // to the 3-rd row of A. + B.row(5).copyTo(C); + // now let A and D share the data; after that the modified version + // of A is still referenced by B and C. + A = D; + // now make B an empty matrix (which references no memory buffers), + // but the modified version of A will still be referenced by C, + // despite that C is just a single row of the original A + B.release(); + + // finally, make a full copy of C. As a result, the big modified + // matrix will be deallocated, since it is not referenced by anyone + C = C.clone(); + +You see that the use of ``Mat`` and other basic structures is simple. But what about high-level classes or even user data types created without taking automatic memory management into account? For them, OpenCV offers the ``Ptr<>`` template class that is similar to ``std::shared_ptr`` from C++ TR1. So, instead of using plain pointers:: + + T* ptr = new T(...); + +you can use:: + + Ptr ptr = new T(...); + +That is, ``Ptr ptr`` encapsulates a pointer to a ``T`` instance and a reference counter associated with the pointer. See the +:ocv:class:`Ptr` +description for details. + +.. _AutomaticAllocation: + +Automatic Allocation of the Output Data +--------------------------------------- + +OpenCV deallocates the memory automatically, as well as automatically allocates the memory for output function parameters most of the time. So, if a function has one or more input arrays (``cv::Mat`` instances) and some output arrays, the output arrays are automatically allocated or reallocated. The size and type of the output arrays are determined from the size and type of input arrays. If needed, the functions take extra parameters that help to figure out the output array properties. + +Example: :: + + #include "cv.h" + #include "highgui.h" + + using namespace cv; + + int main(int, char**) + { + VideoCapture cap(0); + if(!cap.isOpened()) return -1; + + Mat frame, edges; + namedWindow("edges",1); + for(;;) + { + cap >> frame; + cvtColor(frame, edges, CV_BGR2GRAY); + GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); + Canny(edges, edges, 0, 30, 3); + imshow("edges", edges); + if(waitKey(30) >= 0) break; + } + return 0; + } + +The array ``frame`` is automatically allocated by the ``>>`` operator since the video frame resolution and the bit-depth is known to the video capturing module. The array ``edges`` is automatically allocated by the ``cvtColor`` function. It has the same size and the bit-depth as the input array. The number of channels is 1 because the color conversion code ``CV_BGR2GRAY`` is passed, which means a color to grayscale conversion. Note that ``frame`` and ``edges`` are allocated only once during the first execution of the loop body since all the next video frames have the same resolution. If you somehow change the video resolution, the arrays are automatically reallocated. + +The key component of this technology is the ``Mat::create`` method. It takes the desired array size and type. If the array already has the specified size and type, the method does nothing. Otherwise, it releases the previously allocated data, if any (this part involves decrementing the reference counter and comparing it with zero), and then allocates a new buffer of the required size. Most functions call the ``Mat::create`` method for each output array, and so the automatic output data allocation is implemented. + +Some notable exceptions from this scheme are ``cv::mixChannels``, ``cv::RNG::fill``, and a few other functions and methods. They are not able to allocate the output array, so you have to do this in advance. + +Saturation Arithmetics +---------------------- + +As a computer vision library, OpenCV deals a lot with image pixels that are often encoded in a compact, 8- or 16-bit per channel, form and thus have a limited value range. Furthermore, certain operations on images, like color space conversions, brightness/contrast adjustments, sharpening, complex interpolation (bi-cubic, Lanczos) can produce values out of the available range. If you just store the lowest 8 (16) bits of the result, this results in visual artifacts and may affect a further image analysis. To solve this problem, the so-called *saturation* arithmetics is used. For example, to store ``r``, the result of an operation, to an 8-bit image, you find the nearest value within the 0..255 range: + +.. math:: + + I(x,y)= \min ( \max (\textrm{round}(r), 0), 255) + +Similar rules are applied to 8-bit signed, 16-bit signed and unsigned types. This semantics is used everywhere in the library. In C++ code, it is done using the ``saturate_cast<>`` functions that resemble standard C++ cast operations. See below the implementation of the formula provided above:: + + I.at(y, x) = saturate_cast(r); + +where ``cv::uchar`` is an OpenCV 8-bit unsigned integer type. In the optimized SIMD code, such SSE2 instructions as ``paddusb``, ``packuswb``, and so on are used. They help achieve exactly the same behavior as in C++ code. + +.. note:: Saturation is not applied when the result is 32-bit integer. + +Fixed Pixel Types. Limited Use of Templates +------------------------------------------- + +Templates is a great feature of C++ that enables implementation of very powerful, efficient and yet safe data structures and algorithms. However, the extensive use of templates may dramatically increase compilation time and code size. Besides, it is difficult to separate an interface and implementation when templates are used exclusively. This could be fine for basic algorithms but not good for computer vision libraries where a single algorithm may span thousands lines of code. Because of this and also to simplify development of bindings for other languages, like Python, Java, Matlab that do not have templates at all or have limited template capabilities, the current OpenCV implementation is based on polymorphism and runtime dispatching over templates. In those places where runtime dispatching would be too slow (like pixel access operators), impossible (generic ``Ptr<>`` implementation), or just very inconvenient (``saturate_cast<>()``) the current implementation introduces small template classes, methods, and functions. Anywhere else in the current OpenCV version the use of templates is limited. + +Consequently, there is a limited fixed set of primitive data types the library can operate on. That is, array elements should have one of the following types: + + * 8-bit unsigned integer (uchar) + * 8-bit signed integer (schar) + * 16-bit unsigned integer (ushort) + * 16-bit signed integer (short) + * 32-bit signed integer (int) + * 32-bit floating-point number (float) + * 64-bit floating-point number (double) + * a tuple of several elements where all elements have the same type (one of the above). An array whose elements are such tuples, are called multi-channel arrays, as opposite to the single-channel arrays, whose elements are scalar values. The maximum possible number of channels is defined by the ``CV_CN_MAX`` constant, which is currently set to 512. + +For these basic types, the following enumeration is applied:: + + enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; + +Multi-channel (``n``-channel) types can be specified using the following options: + +* ``CV_8UC1`` ... ``CV_64FC4`` constants (for a number of channels from 1 to 4) +* ``CV_8UC(n)`` ... ``CV_64FC(n)`` or ``CV_MAKETYPE(CV_8U, n)`` ... ``CV_MAKETYPE(CV_64F, n)`` macros when the number of channels is more than 4 or unknown at the compilation time. + +.. note:: ``CV_32FC1 == CV_32F``, ``CV_32FC2 == CV_32FC(2) == CV_MAKETYPE(CV_32F, 2)``, and ``CV_MAKETYPE(depth, n) == ((x&7)<<3) + (n-1)``. This means that the constant type is formed from the ``depth``, taking the lowest 3 bits, and the number of channels minus 1, taking the next ``log2(CV_CN_MAX)`` bits. + +Examples: :: + + Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix + Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point + // matrix (10-element complex vector) + Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image + // of 1920 columns and 1080 rows. + Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of + // the same size and same + // channel type as img + +Arrays with more complex elements cannot be constructed or processed using OpenCV. Furthermore, each function or method can handle only a subset of all possible array types. Usually, the more complex the algorithm is, the smaller the supported subset of formats is. See below typical examples of such limitations: + + * The face detection algorithm only works with 8-bit grayscale or color images. + * Linear algebra functions and most of the machine learning algorithms work with floating-point arrays only. + * Basic functions, such as ``cv::add``, support all types. + * Color space conversion functions support 8-bit unsigned, 16-bit unsigned, and 32-bit floating-point types. + +The subset of supported types for each function has been defined from practical needs and could be extended in future based on user requests. + + +InputArray and OutputArray +-------------------------- + +Many OpenCV functions process dense 2-dimensional or multi-dimensional numerical arrays. Usually, such functions take cpp:class:`Mat` as parameters, but in some cases it's more convenient to use ``std::vector<>`` (for a point set, for example) or ``Matx<>`` (for 3x3 homography matrix and such). To avoid many duplicates in the API, special "proxy" classes have been introduced. The base "proxy" class is ``InputArray``. It is used for passing read-only arrays on a function input. The derived from ``InputArray`` class ``OutputArray`` is used to specify an output array for a function. Normally, you should not care of those intermediate types (and you should not declare variables of those types explicitly) - it will all just work automatically. You can assume that instead of ``InputArray``/``OutputArray`` you can always use ``Mat``, ``std::vector<>``, ``Matx<>``, ``Vec<>`` or ``Scalar``. When a function has an optional input or output array, and you do not have or do not want one, pass ``cv::noArray()``. + +Error Handling +-------------- + +OpenCV uses exceptions to signal critical errors. When the input data has a correct format and belongs to the specified value range, but the algorithm cannot succeed for some reason (for example, the optimization algorithm did not converge), it returns a special error code (typically, just a boolean variable). + +The exceptions can be instances of the ``cv::Exception`` class or its derivatives. In its turn, ``cv::Exception`` is a derivative of ``std::exception``. So it can be gracefully handled in the code using other standard C++ library components. + +The exception is typically thrown either using the ``CV_Error(errcode, description)`` macro, or its printf-like ``CV_Error_(errcode, printf-spec, (printf-args))`` variant, or using the ``CV_Assert(condition)`` macro that checks the condition and throws an exception when it is not satisfied. For performance-critical code, there is ``CV_DbgAssert(condition)`` that is only retained in the Debug configuration. Due to the automatic memory management, all the intermediate buffers are automatically deallocated in case of a sudden error. You only need to add a try statement to catch exceptions, if needed: :: + + try + { + ... // call OpenCV + } + catch( cv::Exception& e ) + { + const char* err_msg = e.what(); + std::cout << "exception caught: " << err_msg << std::endl; + } + +Multi-threading and Re-enterability +----------------------------------- + +The current OpenCV implementation is fully re-enterable. That is, the same function, the same *constant* method of a class instance, or the same *non-constant* method of different class instances can be called from different threads. Also, the same ``cv::Mat`` can be used in different threads because the reference-counting operations use the architecture-specific atomic instructions. diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/old_basic_structures.rst diffimg-2.0.0/3rdparty/opencv/core/doc/old_basic_structures.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/old_basic_structures.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/old_basic_structures.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1754 @@ +Basic C Structures and Operations +================================= + +.. highlight:: c + +The section describes the main data structures, used by the OpenCV 1.x API, and the basic functions to create and process the data structures. + +CvPoint +------- +.. ocv:cfunction:: CvPoint cvPoint( int x, int y ) + + constructs ``CvPoint`` structure. + +.. ocv:cfunction:: CvPoint cvPointFrom32f( CvPoint2D32f point ) + + converts ``CvPoint2D32f`` to ``CvPoint``. + +.. ocv:struct:: CvPoint + + 2D point with integer coordinates (usually zero-based). + + :param x: x-coordinate of the point. + + :param y: y-coordinate of the point. + + :param point: the point to convert. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint2D32f +------------ + +.. ocv:cfunction:: CvPoint2D32f cvPoint2D32f( double x, double y ) + + constructs ``CvPoint2D32f`` structure. + +.. ocv:cfunction:: CvPoint2D32f cvPointTo32f( CvPoint point ) + + converts ``CvPoint`` to ``CvPoint2D32f``. + +.. ocv:struct:: CvPoint2D32f + + 2D point with floating-point coordinates. + + :param x: floating-point x-coordinate of the point. + + :param y: floating-point y-coordinate of the point. + + :param point: the point to convert. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint3D32f +------------ + +.. ocv:struct:: CvPoint3D32f + + 3D point with floating-point coordinates + +.. ocv:cfunction:: CvPoint3D32f cvPoint3D32f( double x, double y, double z ) + + constructs ``CvPoint3D32f`` structure. + + :param x: floating-point x-coordinate of the point. + + :param y: floating-point y-coordinate of the point. + + :param z: floating-point z-coordinate of the point. + +.. seealso:: :ocv:class:`Point3\_` + +CvPoint2D64f +------------ + +.. ocv:struct:: CvPoint2D64f + + 2D point with double-precision floating-point coordinates. + +.. ocv:cfunction:: CvPoint2D64f cvPoint2D64f( double x, double y ) + + constructs ``CvPoint2D64f`` structure. + + :param x: double-precision floating-point x-coordinate of the point. + + :param y: double-precision floating-point y-coordinate of the point. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint3D64f +------------ + +.. ocv:struct:: CvPoint3D64f + + 3D point with double-precision floating-point coordinates. + +.. ocv:cfunction:: CvPoint3D64f cvPoint3D64f( double x, double y, double z ) + + constructs ``CvPoint3D64f`` structure. + + :param x: double-precision floating-point x-coordinate of the point. + + :param y: double-precision floating-point y-coordinate of the point. + + :param z: double-precision floating-point z-coordinate of the point. + +.. seealso:: :ocv:class:`Point3\_` + +CvSize +------ + +.. ocv:struct:: CvSize + + Size of a rectangle or an image. + +.. ocv:cfunction:: CvSize cvSize( int width, int height ) + + constructs ``CvSize`` structure. + + :param width: width of the rectangle. + + :param height: height of the rectangle. + +.. seealso:: :ocv:class:`Size\_` + +CvSize2D32f +----------- + +.. ocv:struct:: CvSize2D32f + + Sub-pixel accurate size of a rectangle. + +.. ocv:cfunction:: CvSize2D32f cvSize2D32f( double width, double height ) + + constructs ``CvSize2D32f`` structure. + + :param width: floating-point width of the rectangle. + + :param height: floating-point height of the rectangle. + +.. seealso:: :ocv:class:`Size\_` + +CvRect +------ + +.. ocv:struct:: CvRect + + Stores coordinates of a rectangle. + +.. ocv:cfunction:: CvRect cvRect( int x, int y, int width, int height ) + + constructs ``CvRect`` structure. + + :param x: x-coordinate of the top-left corner. + + :param y: y-coordinate of the top-left corner (sometimes bottom-left corner). + + :param width: width of the rectangle. + + :param height: height of the rectangle. + +.. seealso:: :ocv:class:`Rect\_` + + +CvBox2D +------- + +.. ocv:struct:: CvBox2D + + Stores coordinates of a rotated rectangle. + + .. ocv:member:: CvPoint2D32f center + + Center of the box + + .. ocv:member:: CvSize2D32f size + + Box width and height + + .. ocv:member:: float angle + + Angle between the horizontal axis and the first side (i.e. length) in degrees + +.. seealso:: :ocv:class:`RotatedRect` + + +CvScalar +-------- + +.. ocv:struct:: CvScalar + + A container for 1-,2-,3- or 4-tuples of doubles. + + .. ocv:member:: double[4] val + +.. ocv::cfunction:: CvScalar cvScalar( double val0, double val1=0, double val2=0, double val3=0 ) + + initializes val[0] with val0, val[1] with val1, val[2] with val2 and val[3] with val3. + +.. ocv::cfunction:: CvScalar cvScalarAll( double val0123 ) + + initializes all of val[0]...val[3] with val0123 + +.. ocv::cfunction:: CvScalar cvRealScalar( double val0 ) + + initializes val[0] with val0, val[1], val[2] and val[3] with 0. + +.. seealso:: :ocv:class:`Scalar\_` + +CvTermCriteria +-------------- + +.. ocv:struct:: CvTermCriteria + + Termination criteria for iterative algorithms. + + .. ocv:member:: int type + + type of the termination criteria, one of: + + * ``CV_TERMCRIT_ITER`` - stop the algorithm after ``max_iter`` iterations at maximum. + + * ``CV_TERMCRIT_EPS`` - stop the algorithm after the achieved algorithm-dependent accuracy becomes lower than ``epsilon``. + + * ``CV_TERMCRIT_ITER+CV_TERMCRIT_EPS`` - stop the algorithm after ``max_iter`` iterations or when the achieved accuracy is lower than ``epsilon``, whichever comes the earliest. + + .. ocv:member:: int max_iter + + Maximum number of iterations + + .. ocv:member:: double epsilon + + Required accuracy + +.. seealso:: :ocv:class:`TermCriteria` + +CvMat +----- + +.. ocv:struct:: CvMat + + A multi-channel dense matrix. + + .. ocv:member:: int type + + ``CvMat`` signature (``CV_MAT_MAGIC_VAL``) plus type of the elements. Type of the matrix elements can be retrieved using ``CV_MAT_TYPE`` macro: :: + + int type = CV_MAT_TYPE(matrix->type); + + For description of possible matrix elements, see :ocv:class:`Mat`. + + .. ocv:member:: int step + + Full row length in bytes + + .. ocv:member:: int* refcount + + Underlying data reference counter + + .. ocv:member:: union data + + Pointers to the actual matrix data: + + * ptr - pointer to 8-bit unsigned elements + * s - pointer to 16-bit signed elements + * i - pointer to 32-bit signed elements + * fl - pointer to 32-bit floating-point elements + * db - pointer to 64-bit floating-point elements + + .. ocv:member:: int rows + + Number of rows + + .. ocv:member:: int cols + + Number of columns + +Matrix elements are stored row by row. Element (i, j) (i - 0-based row index, j - 0-based column index) of a matrix can be retrieved or modified using ``CV_MAT_ELEM`` macro: :: + + uchar pixval = CV_MAT_ELEM(grayimg, uchar, i, j) + CV_MAT_ELEM(cameraMatrix, float, 0, 2) = image.width*0.5f; + +To access multiple-channel matrices, you can use ``CV_MAT_ELEM(matrix, type, i, j*nchannels + channel_idx)``. + +``CvMat`` is now obsolete; consider using :ocv:class:`Mat` instead. + +CvMatND +------- + +.. ocv:struct:: CvMatND + + Multi-dimensional dense multi-channel array. + + .. ocv:member:: int type + + A ``CvMatND`` signature (``CV_MATND_MAGIC_VAL``) plus the type of elements. Type of the matrix elements can be retrieved using ``CV_MAT_TYPE`` macro: :: + + int type = CV_MAT_TYPE(ndmatrix->type); + + .. ocv:member:: int dims + + The number of array dimensions + + .. ocv:member:: int* refcount + + Underlying data reference counter + + .. ocv:member:: union data + + Pointers to the actual matrix data + + * ptr - pointer to 8-bit unsigned elements + * s - pointer to 16-bit signed elements + * i - pointer to 32-bit signed elements + * fl - pointer to 32-bit floating-point elements + * db - pointer to 64-bit floating-point elements + + .. ocv:member:: array dim + + Arrays of pairs (array size along the i-th dimension, distance between neighbor elements along i-th dimension): :: + + for(int i = 0; i < ndmatrix->dims; i++) + printf("size[i] = %d, step[i] = %d\n", ndmatrix->dim[i].size, ndmatrix->dim[i].step); + +``CvMatND`` is now obsolete; consider using :ocv:class:`Mat` instead. + +CvSparseMat +----------- + +.. ocv:struct:: CvSparseMat + + Multi-dimensional sparse multi-channel array. + + .. ocv:member:: int type + + A ``CvSparseMat`` signature (CV_SPARSE_MAT_MAGIC_VAL) plus the type of sparse matrix elements. Similarly to ``CvMat`` and ``CvMatND``, use ``CV_MAT_TYPE()`` to retrieve type of the elements. + + .. ocv:member:: int dims + + Number of dimensions + + .. ocv:member:: int* refcount + + Underlying reference counter. Not used. + + .. ocv:member:: CvSet* heap + + A pool of hash table nodes + + .. ocv:member:: void** hashtable + + The hash table. Each entry is a list of nodes. + + .. ocv:member:: int hashsize + + Size of the hash table + + .. ocv:member:: int[] size + + Array of dimension sizes + +IplImage +-------- + +.. ocv:struct:: IplImage + + IPL image header + + .. ocv:member:: int nSize + + ``sizeof(IplImage)`` + + .. ocv:member:: int ID + + Version, always equals 0 + + .. ocv:member:: int nChannels + + Number of channels. Most OpenCV functions support 1-4 channels. + + .. ocv:member:: int alphaChannel + + Ignored by OpenCV + + .. ocv:member:: int depth + + Channel depth in bits + the optional sign bit ( ``IPL_DEPTH_SIGN`` ). The supported depths are: + + * ``IPL_DEPTH_8U`` - unsigned 8-bit integer. Equivalent to ``CV_8U`` in matrix types. + * ``IPL_DEPTH_8S`` - signed 8-bit integer. Equivalent to ``CV_8S`` in matrix types. + * ``IPL_DEPTH_16U`` - unsigned 16-bit integer. Equivalent to ``CV_16U`` in matrix types. + * ``IPL_DEPTH_16S`` - signed 8-bit integer. Equivalent to ``CV_16S`` in matrix types. + * ``IPL_DEPTH_32S`` - signed 32-bit integer. Equivalent to ``CV_32S`` in matrix types. + * ``IPL_DEPTH_32F`` - single-precision floating-point number. Equivalent to ``CV_32F`` in matrix types. + * ``IPL_DEPTH_64F`` - double-precision floating-point number. Equivalent to ``CV_64F`` in matrix types. + + .. ocv:member:: char[] colorModel + + Ignored by OpenCV. + + .. ocv:member:: char[] channelSeq + + Ignored by OpenCV + + .. ocv:member:: int dataOrder + + 0 = ``IPL_DATA_ORDER_PIXEL`` - interleaved color channels, 1 - separate color channels. :ocv:cfunc:`CreateImage` only creates images with interleaved channels. For example, the usual layout of a color image is: :math:`b_{00} g_{00} r_{00} b_{10} g_{10} r_{10} ...` + + .. ocv:member:: int origin + + 0 - top-left origin, 1 - bottom-left origin (Windows bitmap style) + + .. ocv:member:: int align + + Alignment of image rows (4 or 8). OpenCV ignores this and uses widthStep instead. + + .. ocv:member:: int width + + Image width in pixels + + .. ocv:member:: int height + + Image height in pixels + + .. ocv:member:: IplROI* roi + + Region Of Interest (ROI). If not NULL, only this image region will be processed. + + .. ocv:member:: IplImage* maskROI + + Must be NULL in OpenCV + + .. ocv:member:: void* imageId + + Must be NULL in OpenCV + + .. ocv:member:: void* tileInfo + + Must be NULL in OpenCV + + .. ocv:member:: int imageSize + + Image data size in bytes. For interleaved data, this equals :math:`\texttt{image->height} \cdot \texttt{image->widthStep}` + + .. ocv:member:: char* imageData + + A pointer to the aligned image data. Do not assign imageData directly. Use :ocv:cfunc:`SetData`. + + .. ocv:member:: int widthStep + + The size of an aligned image row, in bytes. + + .. ocv:member:: int[] BorderMode + + Border completion mode, ignored by OpenCV + + .. ocv:member:: int[] BorderConst + + Constant border value, ignored by OpenCV + + .. ocv:member:: char* imageDataOrigin + + A pointer to the origin of the image data (not necessarily aligned). This is used for image deallocation. + +The ``IplImage`` is taken from the Intel Image Processing Library, in which the format is native. OpenCV only supports a subset of possible ``IplImage`` formats, as outlined in the parameter list above. + +In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require that the image size or ROI size of all source and destination images match exactly. On the other hand, the Intel Image Processing Library processes the area of intersection between the source and destination images (or ROIs), allowing them to vary independently. + +CvArr +----- + +.. ocv:struct:: CvArr + +This is the "metatype" used *only* as a function parameter. It denotes that the function accepts arrays of multiple types, such as IplImage*, CvMat* or even CvSeq* sometimes. The particular array type is determined at runtime by analyzing the first 4 bytes of the header. In C++ interface the role of ``CvArr`` is played by ``InputArray`` and ``OutputArray``. + +ClearND +------- +Clears a specific array element. + +.. ocv:cfunction:: void cvClearND( CvArr* arr, const int* idx ) + +.. ocv:pyoldfunction:: cv.ClearND(arr, idx)-> None + + :param arr: Input array + :param idx: Array of the element indices + +The function clears (sets to zero) a specific element of a dense array or deletes the element of a sparse array. If the sparse array element does not exists, the function does nothing. + +CloneImage +---------- +Makes a full copy of an image, including the header, data, and ROI. + +.. ocv:cfunction:: IplImage* cvCloneImage(const IplImage* image) +.. ocv:pyoldfunction:: cv.CloneImage(image) -> image + + :param image: The original image + +CloneMat +-------- +Creates a full matrix copy. + +.. ocv:cfunction:: CvMat* cvCloneMat(const CvMat* mat) +.. ocv:pyoldfunction:: cv.CloneMat(mat) -> mat + + :param mat: Matrix to be copied + +Creates a full copy of a matrix and returns a pointer to the copy. Note that the matrix copy is compacted, that is, it will not have gaps between rows. + +CloneMatND +---------- +Creates full copy of a multi-dimensional array and returns a pointer to the copy. + +.. ocv:cfunction:: CvMatND* cvCloneMatND(const CvMatND* mat) +.. ocv:pyoldfunction:: cv.CloneMatND(mat) -> matND + + :param mat: Input array + +CloneSparseMat +-------------- +Creates full copy of sparse array. + +.. ocv:cfunction:: CvSparseMat* cvCloneSparseMat(const CvSparseMat* mat) + + :param mat: Input array + +The function creates a copy of the input array and returns pointer to the copy. + + +ConvertScale +------------ +Converts one array to another with optional linear transformation. + +.. ocv:cfunction:: void cvConvertScale(const CvArr* src, CvArr* dst, double scale=1, double shift=0) +.. ocv:pyoldfunction:: cv.ConvertScale(src, dst, scale=1.0, shift=0.0)-> None +.. ocv:pyoldfunction:: cv.Convert(src, dst)-> None + + :: + + #define cvCvtScale cvConvertScale + #define cvScale cvConvertScale + #define cvConvert(src, dst ) cvConvertScale((src), (dst), 1, 0 ) + + .. + + :param src: Source array + + :param dst: Destination array + + :param scale: Scale factor + + :param shift: Value added to the scaled source array elements + +The function has several different purposes, and thus has several different names. It copies one array to another with optional scaling, which is performed first, and/or optional type conversion, performed after: + +.. math:: + + \texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...) + + +All the channels of multi-channel arrays are processed independently. + +The type of conversion is done with rounding and saturation, that is if the +result of scaling + conversion can not be represented exactly by a value +of the destination array element type, it is set to the nearest representable +value on the real axis. + + +Copy +---- +Copies one array to another. + +.. ocv:cfunction:: void cvCopy(const CvArr* src, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Copy(src, dst, mask=None)-> None + + :param src: The source array + + :param dst: The destination array + + :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed + +The function copies selected elements from an input array to an output array: + +.. math:: + + \texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0. + +If any of the passed arrays is of ``IplImage`` type, then its ROI and COI fields are used. Both arrays must have the same type, the same number of dimensions, and the same size. The function can also copy sparse arrays (mask is not supported in this case). + + +CreateData +---------- +Allocates array data + +.. ocv:cfunction:: void cvCreateData(CvArr* arr) +.. ocv:pyoldfunction:: cv.CreateData(arr) -> None + + :param arr: Array header + +The function allocates image, matrix or multi-dimensional dense array data. Note that in the case of matrix types OpenCV allocation functions are used. In the case of IplImage they are used +unless ``CV_TURN_ON_IPL_COMPATIBILITY()`` has been called before. In the latter case IPL functions are used to allocate the data. + +CreateImage +----------- +Creates an image header and allocates the image data. + +.. ocv:cfunction:: IplImage* cvCreateImage(CvSize size, int depth, int channels) +.. ocv:pyoldfunction:: cv.CreateImage(size, depth, channels)->image + + :param size: Image width and height + + :param depth: Bit depth of image elements. See :ocv:struct:`IplImage` for valid depths. + + :param channels: Number of channels per pixel. See :ocv:struct:`IplImage` for details. This function only creates images with interleaved channels. + +This function call is equivalent to the following code: :: + + header = cvCreateImageHeader(size, depth, channels); + cvCreateData(header); + +CreateImageHeader +----------------- +Creates an image header but does not allocate the image data. + +.. ocv:cfunction:: IplImage* cvCreateImageHeader(CvSize size, int depth, int channels) +.. ocv:pyoldfunction:: cv.CreateImageHeader(size, depth, channels) -> image + + :param size: Image width and height + + :param depth: Image depth (see :ocv:cfunc:`CreateImage` ) + + :param channels: Number of channels (see :ocv:cfunc:`CreateImage` ) + +CreateMat +--------- +Creates a matrix header and allocates the matrix data. + +.. ocv:cfunction:: CvMat* cvCreateMat( int rows, int cols, int type) +.. ocv:pyoldfunction:: cv.CreateMat(rows, cols, type) -> mat + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: The type of the matrix elements in the form ``CV_C`` , where S=signed, U=unsigned, F=float. For example, CV _ 8UC1 means the elements are 8-bit unsigned and the there is 1 channel, and CV _ 32SC2 means the elements are 32-bit signed and there are 2 channels. + +The function call is equivalent to the following code: :: + + CvMat* mat = cvCreateMatHeader(rows, cols, type); + cvCreateData(mat); + +CreateMatHeader +--------------- +Creates a matrix header but does not allocate the matrix data. + +.. ocv:cfunction:: CvMat* cvCreateMatHeader( int rows, int cols, int type) +.. ocv:pyoldfunction:: cv.CreateMatHeader(rows, cols, type) -> mat + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: Type of the matrix elements, see :ocv:cfunc:`CreateMat` + +The function allocates a new matrix header and returns a pointer to it. The matrix data can then be allocated using :ocv:cfunc:`CreateData` or set explicitly to user-allocated data via :ocv:cfunc:`SetData`. + +CreateMatND +----------- +Creates the header and allocates the data for a multi-dimensional dense array. + +.. ocv:cfunction:: CvMatND* cvCreateMatND( int dims, const int* sizes, int type) +.. ocv:pyoldfunction:: cv.CreateMatND(dims, type) -> matND + + :param dims: Number of array dimensions. This must not exceed CV_MAX_DIM (32 by default, but can be changed at build time). + + :param sizes: Array of dimension sizes. + + :param type: Type of array elements, see :ocv:cfunc:`CreateMat` . + +This function call is equivalent to the following code: :: + + CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type); + cvCreateData(mat); + +CreateMatNDHeader +----------------- +Creates a new matrix header but does not allocate the matrix data. + +.. ocv:cfunction:: CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type) +.. ocv:pyoldfunction:: cv.CreateMatNDHeader(dims, type) -> matND + + :param dims: Number of array dimensions + + :param sizes: Array of dimension sizes + + :param type: Type of array elements, see :ocv:cfunc:`CreateMat` + +The function allocates a header for a multi-dimensional dense array. The array data can further be allocated using :ocv:cfunc:`CreateData` or set explicitly to user-allocated data via :ocv:cfunc:`SetData`. + +CreateSparseMat +--------------- +Creates sparse array. + +.. ocv:cfunction:: CvSparseMat* cvCreateSparseMat(int dims, const int* sizes, int type) + + :param dims: Number of array dimensions. In contrast to the dense matrix, the number of dimensions is practically unlimited (up to :math:`2^{16}` ). + + :param sizes: Array of dimension sizes + + :param type: Type of array elements. The same as for CvMat + +The function allocates a multi-dimensional sparse array. Initially the array contain no elements, that is +:ocv:cfunc:`PtrND` and other related functions will return 0 for every index. + + +CrossProduct +------------ +Calculates the cross product of two 3D vectors. + +.. ocv:cfunction:: void cvCrossProduct(const CvArr* src1, const CvArr* src2, CvArr* dst) +.. ocv:pyoldfunction:: cv.CrossProduct(src1, src2, dst)-> None + + :param src1: The first source vector + + :param src2: The second source vector + + :param dst: The destination vector + +The function calculates the cross product of two 3D vectors: + +.. math:: + + \texttt{dst} = \texttt{src1} \times \texttt{src2} + +or: + +.. math:: + + \begin{array}{l} \texttt{dst} _1 = \texttt{src1} _2 \texttt{src2} _3 - \texttt{src1} _3 \texttt{src2} _2 \\ \texttt{dst} _2 = \texttt{src1} _3 \texttt{src2} _1 - \texttt{src1} _1 \texttt{src2} _3 \\ \texttt{dst} _3 = \texttt{src1} _1 \texttt{src2} _2 - \texttt{src1} _2 \texttt{src2} _1 \end{array} + + +DotProduct +---------- +Calculates the dot product of two arrays in Euclidean metrics. + +.. ocv:cfunction:: double cvDotProduct(const CvArr* src1, const CvArr* src2) +.. ocv:pyoldfunction:: cv.DotProduct(src1, src2) -> float + + :param src1: The first source array + + :param src2: The second source array + +The function calculates and returns the Euclidean dot product of two arrays. + +.. math:: + + src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I)) + +In the case of multiple channel arrays, the results for all channels are accumulated. In particular, +``cvDotProduct(a,a)`` where ``a`` is a complex vector, will return :math:`||\texttt{a}||^2`. +The function can process multi-dimensional arrays, row by row, layer by layer, and so on. + + +Get?D +----- + +.. ocv:cfunction:: CvScalar cvGet1D(const CvArr* arr, int idx0) +.. ocv:cfunction:: CvScalar cvGet2D(const CvArr* arr, int idx0, int idx1) +.. ocv:cfunction:: CvScalar cvGet3D(const CvArr* arr, int idx0, int idx1, int idx2) +.. ocv:cfunction:: CvScalar cvGetND( const CvArr* arr, const int* idx ) + +.. ocv:pyoldfunction:: cv.Get1D(arr, idx) -> scalar +.. ocv:pyoldfunction:: cv.Get2D(arr, idx0, idx1) -> scalar +.. ocv:pyoldfunction:: cv.Get3D(arr, idx0, idx1, idx2) -> scalar +.. ocv:pyoldfunction:: cv.GetND(arr, indices) -> scalar + + Return a specific array element. + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + +The functions return a specific array element. In the case of a sparse array the functions return 0 if the requested node does not exist (no new node is created by the functions). + +GetCol(s) +--------- +Returns one of more array columns. + +.. ocv:cfunction:: CvMat* cvGetCol(const CvArr* arr, CvMat* submat, int col) + +.. ocv:cfunction:: CvMat* cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) + +.. ocv:pyoldfunction:: cv.GetCol(arr, col)-> submat + +.. ocv:pyoldfunction:: cv.GetCols(arr, startCol, endCol)-> submat + + :param arr: Input array + + :param submat: Pointer to the resulting sub-array header + + :param col: Zero-based index of the selected column + + :param start_col: Zero-based index of the starting column (inclusive) of the span + + :param end_col: Zero-based index of the ending column (exclusive) of the span + +The functions return the header, corresponding to a specified column span of the input array. That is, no data is copied. Therefore, any modifications of the submatrix will affect the original array. If you need to copy the columns, use :ocv:cfunc:`CloneMat`. ``cvGetCol(arr, submat, col)`` is a shortcut for ``cvGetCols(arr, submat, col, col+1)``. + +GetDiag +------- +Returns one of array diagonals. + +.. ocv:cfunction:: CvMat* cvGetDiag(const CvArr* arr, CvMat* submat, int diag=0) +.. ocv:pyoldfunction:: cv.GetDiag(arr, diag=0)-> submat + + :param arr: Input array + + :param submat: Pointer to the resulting sub-array header + + :param diag: Index of the array diagonal. Zero value corresponds to the main diagonal, -1 corresponds to the diagonal above the main, 1 corresponds to the diagonal below the main, and so forth. + +The function returns the header, corresponding to a specified diagonal of the input array. + +GetDims +------- +Return number of array dimensions + +.. ocv:cfunction:: int cvGetDims(const CvArr* arr, int* sizes=NULL) +.. ocv:pyoldfunction:: cv.GetDims(arr) -> (dim1, dim2, ...) + + :param arr: Input array + + :param sizes: Optional output vector of the array dimension sizes. For + 2d arrays the number of rows (height) goes first, number of columns + (width) next. + +The function returns the array dimensionality and the array of dimension sizes. In the case of ``IplImage`` or `CvMat` it always returns 2 regardless of number of image/matrix rows. For example, the following code calculates total number of array elements: :: + + int sizes[CV_MAX_DIM]; + int i, total = 1; + int dims = cvGetDims(arr, size); + for(i = 0; i < dims; i++ ) + total *= sizes[i]; + +GetDimSize +---------- +Returns array size along the specified dimension. + +.. ocv:cfunction:: int cvGetDimSize(const CvArr* arr, int index) + + :param arr: Input array + + :param index: Zero-based dimension index (for matrices 0 means number of rows, 1 means number of columns; for images 0 means height, 1 means width) + +GetElemType +----------- +Returns type of array elements. + +.. ocv:cfunction:: int cvGetElemType(const CvArr* arr) +.. ocv:pyoldfunction:: cv.GetElemType(arr)-> int + + :param arr: Input array + +The function returns type of the array elements. In the case of ``IplImage`` the type is converted to ``CvMat``-like representation. For example, if the image has been created as: :: + + IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); + +The code ``cvGetElemType(img)`` will return ``CV_8UC3``. + +GetImage +-------- +Returns image header for arbitrary array. + +.. ocv:cfunction:: IplImage* cvGetImage( const CvArr* arr, IplImage* image_header ) + +.. ocv:pyoldfunction:: cv.GetImage(arr) -> iplimage + + :param arr: Input array + + :param image_header: Pointer to ``IplImage`` structure used as a temporary buffer + +The function returns the image header for the input array that can be a matrix (:ocv:struct:`CvMat`) or image (:ocv:struct:`IplImage`). In the case of an image the function simply returns the input pointer. In the case of ``CvMat`` it initializes an ``image_header`` structure with the parameters of the input matrix. Note that if we transform ``IplImage`` to ``CvMat`` using :ocv:cfunc:`GetMat` and then transform ``CvMat`` back to IplImage using this function, we will get different headers if the ROI is set in the original image. + +GetImageCOI +----------- +Returns the index of the channel of interest. + +.. ocv:cfunction:: int cvGetImageCOI(const IplImage* image) +.. ocv:pyoldfunction:: cv.GetImageCOI(image) -> int + + :param image: A pointer to the image header + +Returns the channel of interest of in an IplImage. Returned values correspond to the ``coi`` in +:ocv:cfunc:`SetImageCOI`. + +GetImageROI +----------- +Returns the image ROI. + +.. ocv:cfunction:: CvRect cvGetImageROI(const IplImage* image) +.. ocv:pyoldfunction:: cv.GetImageROI(image)-> CvRect + + :param image: A pointer to the image header + +If there is no ROI set, ``cvRect(0,0,image->width,image->height)`` is returned. + +GetMat +------ +Returns matrix header for arbitrary array. + +.. ocv:cfunction:: CvMat* cvGetMat(const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0) +.. ocv:pyoldfunction:: cv.GetMat(arr, allowND=0) -> mat + + :param arr: Input array + + :param header: Pointer to :ocv:struct:`CvMat` structure used as a temporary buffer + + :param coi: Optional output parameter for storing COI + + :param allowND: If non-zero, the function accepts multi-dimensional dense arrays (CvMatND*) and returns 2D matrix (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or more than 2 dimensions). The ``CvMatND`` array must be continuous. + +The function returns a matrix header for the input array that can be a matrix - :ocv:struct:`CvMat`, an image - :ocv:struct:`IplImage`, or a multi-dimensional dense array - :ocv:struct:`CvMatND` (the third option is allowed only if ``allowND != 0``) . In the case of matrix the function simply returns the input pointer. In the case of ``IplImage*`` or ``CvMatND`` it initializes the ``header`` structure with parameters of the current image ROI and returns ``&header``. Because COI is not supported by ``CvMat``, it is returned separately. + +The function provides an easy way to handle both types of arrays - ``IplImage`` and ``CvMat`` using the same code. Input array must have non-zero data pointer, otherwise the function will report an error. + +.. seealso:: :ocv:cfunc:`GetImage`, :ocv:func:`cvarrToMat`. + +.. note:: If the input array is ``IplImage`` with planar data layout and COI set, the function returns the pointer to the selected plane and ``COI == 0``. This feature allows user to process ``IplImage`` structures with planar data layout, even though OpenCV does not support such images. + +GetNextSparseNode +----------------- +Returns the next sparse matrix element + +.. ocv:cfunction:: CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator ) + + :param mat_iterator: Sparse array iterator + +The function moves iterator to the next sparse matrix element and returns pointer to it. In the current version there is no any particular order of the elements, because they are stored in the hash table. The sample below demonstrates how to iterate through the sparse matrix: :: + + // print all the non-zero sparse matrix elements and compute their sum + double sum = 0; + int i, dims = cvGetDims(sparsemat); + CvSparseMatIterator it; + CvSparseNode* node = cvInitSparseMatIterator(sparsemat, &it); + + for(; node != 0; node = cvGetNextSparseNode(&it)) + { + /* get pointer to the element indices */ + int* idx = CV_NODE_IDX(array, node); + /* get value of the element (assume that the type is CV_32FC1) */ + float val = *(float*)CV_NODE_VAL(array, node); + printf("M"); + for(i = 0; i < dims; i++ ) + printf("[%d]", idx[i]); + printf("=%g\n", val); + + sum += val; + } + + printf("nTotal sum = %g\n", sum); + + +GetRawData +---------- +Retrieves low-level information about the array. + +.. ocv:cfunction:: void cvGetRawData( const CvArr* arr, uchar** data, int* step=NULL, CvSize* roi_size=NULL ) + + :param arr: Array header + + :param data: Output pointer to the whole image origin or ROI origin if ROI is set + + :param step: Output full row length in bytes + + :param roi_size: Output ROI size + +The function fills output variables with low-level information about the array data. All output parameters are optional, so some of the pointers may be set to ``NULL``. If the array is ``IplImage`` with ROI set, the parameters of ROI are returned. + +The following example shows how to get access to array elements. It computes absolute values of the array elements :: + + float* data; + int step; + CvSize size; + + cvGetRawData(array, (uchar**)&data, &step, &size); + step /= sizeof(data[0]); + + for(int y = 0; y < size.height; y++, data += step ) + for(int x = 0; x < size.width; x++ ) + data[x] = (float)fabs(data[x]); + +GetReal?D +--------- +Return a specific element of single-channel 1D, 2D, 3D or nD array. + +.. ocv:cfunction:: double cvGetReal1D(const CvArr* arr, int idx0) +.. ocv:cfunction:: double cvGetReal2D(const CvArr* arr, int idx0, int idx1) +.. ocv:cfunction:: double cvGetReal3D(const CvArr* arr, int idx0, int idx1, int idx2) +.. ocv:cfunction:: double cvGetRealND( const CvArr* arr, const int* idx ) + +.. ocv:pyoldfunction:: cv.GetReal1D(arr, idx0)->float +.. ocv:pyoldfunction:: cv.GetReal2D(arr, idx0, idx1)->float +.. ocv:pyoldfunction:: cv.GetReal3D(arr, idx0, idx1, idx2)->float +.. ocv:pyoldfunction:: cv.GetRealND(arr, idx)->float + + :param arr: Input array. Must have a single channel. + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + +Returns a specific element of a single-channel array. If the array has multiple channels, a runtime error is raised. Note that ``Get?D`` functions can be used safely for both single-channel and multiple-channel arrays though they are a bit slower. + +In the case of a sparse array the functions return 0 if the requested node does not exist (no new node is created by the functions). + + +GetRow(s) +--------- +Returns array row or row span. + +.. ocv:cfunction:: CvMat* cvGetRow(const CvArr* arr, CvMat* submat, int row) + +.. ocv:cfunction:: CvMat* cvGetRows( const CvArr* arr, CvMat* submat, int start_row, int end_row, int delta_row=1 ) + +.. ocv:pyoldfunction:: cv.GetRow(arr, row)-> submat +.. ocv:pyoldfunction:: cv.GetRows(arr, startRow, endRow, deltaRow=1)-> submat + + :param arr: Input array + + :param submat: Pointer to the resulting sub-array header + + :param row: Zero-based index of the selected row + + :param start_row: Zero-based index of the starting row (inclusive) of the span + + :param end_row: Zero-based index of the ending row (exclusive) of the span + + :param delta_row: Index step in the row span. That is, the function extracts every ``delta_row`` -th row from ``start_row`` and up to (but not including) ``end_row`` . + +The functions return the header, corresponding to a specified row/row span of the input array. ``cvGetRow(arr, submat, row)`` is a shortcut for ``cvGetRows(arr, submat, row, row+1)``. + + +GetSize +------- +Returns size of matrix or image ROI. + +.. ocv:cfunction:: CvSize cvGetSize(const CvArr* arr) +.. ocv:pyoldfunction:: cv.GetSize(arr)-> (width, height) + + :param arr: array header + +The function returns number of rows (CvSize::height) and number of columns (CvSize::width) of the input matrix or image. In the case of image the size of ROI is returned. + +GetSubRect +---------- +Returns matrix header corresponding to the rectangular sub-array of input image or matrix. + +.. ocv:cfunction:: CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect) +.. ocv:pyoldfunction:: cv.GetSubRect(arr, rect) -> submat + + :param arr: Input array + + :param submat: Pointer to the resultant sub-array header + + :param rect: Zero-based coordinates of the rectangle of interest + +The function returns header, corresponding to a specified rectangle of the input array. In other words, it allows the user to treat a rectangular part of input array as a stand-alone array. ROI is taken into account by the function so the sub-array of ROI is actually extracted. + +DecRefData +---------- +Decrements an array data reference counter. + +.. ocv:cfunction:: void cvDecRefData(CvArr* arr) + + :param arr: Pointer to an array header + +The function decrements the data reference counter in a :ocv:struct:`CvMat` or :ocv:struct:`CvMatND` if the reference counter pointer is not NULL. If the counter reaches zero, the data is deallocated. In the current implementation the reference counter is not NULL only if the data was allocated using the :ocv:cfunc:`CreateData` function. The counter will be NULL in other cases such as: external data was assigned to the header using :ocv:cfunc:`SetData`, header is part of a larger matrix or image, or the header was converted from an image or n-dimensional matrix header. + + +IncRefData +---------- +Increments array data reference counter. + +.. ocv:cfunction:: int cvIncRefData(CvArr* arr) + + :param arr: Array header + +The function increments :ocv:struct:`CvMat` or :ocv:struct:`CvMatND` data reference counter and returns the new counter value if the reference counter pointer is not NULL, otherwise it returns zero. + + +InitImageHeader +--------------- +Initializes an image header that was previously allocated. + +.. ocv:cfunction:: IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth, int channels, int origin=0, int align=4) + + :param image: Image header to initialize + + :param size: Image width and height + + :param depth: Image depth (see :ocv:cfunc:`CreateImage` ) + + :param channels: Number of channels (see :ocv:cfunc:`CreateImage` ) + + :param origin: Top-left ``IPL_ORIGIN_TL`` or bottom-left ``IPL_ORIGIN_BL`` + + :param align: Alignment for image rows, typically 4 or 8 bytes + +The returned ``IplImage*`` points to the initialized header. + + +InitMatHeader +------------- +Initializes a pre-allocated matrix header. + +.. ocv:cfunction:: CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP) + + :param mat: A pointer to the matrix header to be initialized + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: Type of the matrix elements, see :ocv:cfunc:`CreateMat` . + + :param data: Optional: data pointer assigned to the matrix header + + :param step: Optional: full row width in bytes of the assigned data. By default, the minimal possible step is used which assumes there are no gaps between subsequent rows of the matrix. + +This function is often used to process raw data with OpenCV matrix functions. For example, the following code computes the matrix product of two matrices, stored as ordinary arrays: :: + + double a[] = { 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12 }; + + double b[] = { 1, 5, 9, + 2, 6, 10, + 3, 7, 11, + 4, 8, 12 }; + + double c[9]; + CvMat Ma, Mb, Mc ; + + cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a); + cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b); + cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c); + + cvMatMulAdd(&Ma, &Mb, 0, &Mc); + // the c array now contains the product of a (3x4) and b (4x3) + + +InitMatNDHeader +--------------- +Initializes a pre-allocated multi-dimensional array header. + +.. ocv:cfunction:: CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL) + + :param mat: A pointer to the array header to be initialized + + :param dims: The number of array dimensions + + :param sizes: An array of dimension sizes + + :param type: Type of array elements, see :ocv:cfunc:`CreateMat` + + :param data: Optional data pointer assigned to the matrix header + + +InitSparseMatIterator +--------------------- +Initializes sparse array elements iterator. + +.. ocv:cfunction:: CvSparseNode* cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* mat_iterator ) + + :param mat: Input array + + :param mat_iterator: Initialized iterator + +The function initializes iterator of sparse array elements and returns pointer to the first element, or NULL if the array is empty. + + +Mat +--- +Initializes matrix header (lightweight variant). + +.. ocv:cfunction:: CvMat cvMat( int rows, int cols, int type, void* data=NULL) + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: Type of the matrix elements - see :ocv:cfunc:`CreateMat` + + :param data: Optional data pointer assigned to the matrix header + +Initializes a matrix header and assigns data to it. The matrix is filled *row*-wise (the first ``cols`` elements of data form the first row of the matrix, etc.) + +This function is a fast inline substitution for :ocv:cfunc:`InitMatHeader`. Namely, it is equivalent to: :: + + CvMat mat; + cvInitMatHeader(&mat, rows, cols, type, data, CV_AUTOSTEP); + + +Ptr?D +----- +Return pointer to a particular array element. + +.. ocv:cfunction:: uchar* cvPtr1D(const CvArr* arr, int idx0, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtr3D(const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtrND( const CvArr* arr, const int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL ) + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param type: Optional output parameter: type of matrix elements + + :param create_node: Optional input parameter for sparse matrices. Non-zero value of the parameter means that the requested element is created if it does not exist already. + + :param precalc_hashval: Optional input parameter for sparse matrices. If the pointer is not NULL, the function does not recalculate the node hash value, but takes it from the specified location. It is useful for speeding up pair-wise operations (TODO: provide an example) + +The functions return a pointer to a specific array element. Number of array dimension should match to the number of indices passed to the function except for ``cvPtr1D`` function that can be used for sequential access to 1D, 2D or nD dense arrays. + +The functions can be used for sparse arrays as well - if the requested node does not exist they create it and set it to zero. + +All these as well as other functions accessing array elements ( +:ocv:cfunc:`GetND` +, +:ocv:cfunc:`GetRealND` +, +:ocv:cfunc:`Set` +, +:ocv:cfunc:`SetND` +, +:ocv:cfunc:`SetRealND` +) raise an error in case if the element index is out of range. + + +ReleaseData +----------- +Releases array data. + +.. ocv:cfunction:: void cvReleaseData(CvArr* arr) + + :param arr: Array header + +The function releases the array data. In the case of +:ocv:struct:`CvMat` +or +:ocv:struct:`CvMatND` +it simply calls cvDecRefData(), that is the function can not deallocate external data. See also the note to +:ocv:cfunc:`CreateData` +. + + +ReleaseImage +------------ +Deallocates the image header and the image data. + +.. ocv:cfunction:: void cvReleaseImage(IplImage** image) + + :param image: Double pointer to the image header + +This call is a shortened form of :: + + if(*image ) + { + cvReleaseData(*image); + cvReleaseImageHeader(image); + } + +.. + +ReleaseImageHeader +------------------ +Deallocates an image header. + +.. ocv:cfunction:: void cvReleaseImageHeader(IplImage** image) + + :param image: Double pointer to the image header + +This call is an analogue of :: + + if(image ) + { + iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI); + *image = 0; + } + +.. + +but it does not use IPL functions by default (see the ``CV_TURN_ON_IPL_COMPATIBILITY`` macro). + + +ReleaseMat +---------- +Deallocates a matrix. + +.. ocv:cfunction:: void cvReleaseMat(CvMat** mat) + + :param mat: Double pointer to the matrix + +The function decrements the matrix data reference counter and deallocates matrix header. If the data reference counter is 0, it also deallocates the data. :: + + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); + +.. + +ReleaseMatND +------------ +Deallocates a multi-dimensional array. + +.. ocv:cfunction:: void cvReleaseMatND(CvMatND** mat) + + :param mat: Double pointer to the array + +The function decrements the array data reference counter and releases the array header. If the reference counter reaches 0, it also deallocates the data. :: + + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); + +.. + +ReleaseSparseMat +---------------- +Deallocates sparse array. + +.. ocv:cfunction:: void cvReleaseSparseMat(CvSparseMat** mat) + + :param mat: Double pointer to the array + +The function releases the sparse array and clears the array pointer upon exit. + +ResetImageROI +------------- +Resets the image ROI to include the entire image and releases the ROI structure. + +.. ocv:cfunction:: void cvResetImageROI(IplImage* image) +.. ocv:pyoldfunction:: cv.ResetImageROI(image)-> None + + :param image: A pointer to the image header + +This produces a similar result to the following, but in addition it releases the ROI structure. :: + + cvSetImageROI(image, cvRect(0, 0, image->width, image->height )); + cvSetImageCOI(image, 0); + +.. + +Reshape +------- +Changes shape of matrix/image without copying data. + +.. ocv:cfunction:: CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 ) + +.. ocv:pyoldfunction:: cv.Reshape(arr, newCn, newRows=0) -> mat + + :param arr: Input array + + :param header: Output header to be filled + + :param new_cn: New number of channels. 'new_cn = 0' means that the number of channels remains unchanged. + + :param new_rows: New number of rows. 'new_rows = 0' means that the number of rows remains unchanged unless it needs to be changed according to ``new_cn`` value. + +The function initializes the CvMat header so that it points to the same data as the original array but has a different shape - different number of channels, different number of rows, or both. + +The following example code creates one image buffer and two image headers, the first is for a 320x240x3 image and the second is for a 960x240x1 image: :: + + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + CvMat gray_mat_hdr; + IplImage gray_img_hdr, *gray_img; + cvReshape(color_img, &gray_mat_hdr, 1); + gray_img = cvGetImage(&gray_mat_hdr, &gray_img_hdr); + +.. + +And the next example converts a 3x3 matrix to a single 1x9 vector: + +:: + + CvMat* mat = cvCreateMat(3, 3, CV_32F); + CvMat row_header, *row; + row = cvReshape(mat, &row_header, 0, 1); + +.. + +ReshapeMatND +------------ +Changes the shape of a multi-dimensional array without copying the data. + +.. ocv:cfunction:: CvArr* cvReshapeMatND( const CvArr* arr, int sizeof_header, CvArr* header, int new_cn, int new_dims, int* new_sizes ) + +.. ocv:pyoldfunction:: cv.ReshapeMatND(arr, newCn, newDims) -> mat + + :param arr: Input array + + :param sizeof_header: Size of output header to distinguish between IplImage, CvMat and CvMatND output headers + + :param header: Output header to be filled + + :param new_cn: New number of channels. ``new_cn = 0`` means that the number of channels remains unchanged. + + :param new_dims: New number of dimensions. ``new_dims = 0`` means that the number of dimensions remains the same. + + :param new_sizes: Array of new dimension sizes. Only ``new_dims-1`` values are used, because the total number of elements must remain the same. Thus, if ``new_dims = 1``, ``new_sizes`` array is not used. + +The function is an advanced version of :ocv:cfunc:`Reshape` that can work with multi-dimensional arrays as well (though it can work with ordinary images and matrices) and change the number of dimensions. + +Below are the two samples from the +:ocv:cfunc:`Reshape` +description rewritten using +:ocv:cfunc:`ReshapeMatND` +: :: + + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + IplImage gray_img_hdr, *gray_img; + gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); + + ... + + /* second example is modified to convert 2x2x2 array to 8x1 vector */ + int size[] = { 2, 2, 2 }; + CvMatND* mat = cvCreateMatND(3, size, CV_32F); + CvMat row_header, *row; + row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); + +.. + +Set +--- +Sets every element of an array to a given value. + +.. ocv:cfunction:: void cvSet(CvArr* arr, CvScalar value, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Set(arr, value, mask=None)-> None + + :param arr: The destination array + + :param value: Fill value + + :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed + +The function copies the scalar ``value`` to every selected element of the destination array: + +.. math:: + + \texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0 + +If array ``arr`` is of ``IplImage`` type, then is ROI used, but COI must not be set. + +Set?D +----- +Change the particular array element. + +.. ocv:cfunction:: void cvSet1D(CvArr* arr, int idx0, CvScalar value) + +.. ocv:cfunction:: void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value) + +.. ocv:cfunction:: void cvSet3D(CvArr* arr, int idx0, int idx1, int idx2, CvScalar value) + +.. ocv:cfunction:: void cvSetND( CvArr* arr, const int* idx, CvScalar value ) + +.. ocv:pyoldfunction:: cv.Set1D(arr, idx, value) -> None +.. ocv:pyoldfunction:: cv.Set2D(arr, idx0, idx1, value) -> None +.. ocv:pyoldfunction:: cv.Set3D(arr, idx0, idx1, idx2, value) -> None +.. ocv:pyoldfunction:: cv.SetND(arr, indices, value) -> None + + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param value: The assigned value + +The functions assign the new value to a particular array element. In the case of a sparse array the functions create the node if it does not exist yet. + +SetData +------- +Assigns user data to the array header. + +.. ocv:cfunction:: void cvSetData(CvArr* arr, void* data, int step) +.. ocv:pyoldfunction:: cv.SetData(arr, data, step)-> None + + :param arr: Array header + + :param data: User data + + :param step: Full row length in bytes + +The function assigns user data to the array header. Header should be initialized before using +:ocv:cfunc:`cvCreateMatHeader`, :ocv:cfunc:`cvCreateImageHeader`, :ocv:cfunc:`cvCreateMatNDHeader`, +:ocv:cfunc:`cvInitMatHeader`, :ocv:cfunc:`cvInitImageHeader` or :ocv:cfunc:`cvInitMatNDHeader`. + + + +SetImageCOI +----------- +Sets the channel of interest in an IplImage. + +.. ocv:cfunction:: void cvSetImageCOI( IplImage* image, int coi) +.. ocv:pyoldfunction:: cv.SetImageCOI(image, coi)-> None + + :param image: A pointer to the image header + + :param coi: The channel of interest. 0 - all channels are selected, 1 - first channel is selected, etc. Note that the channel indices become 1-based. + +If the ROI is set to ``NULL`` and the coi is *not* 0, the ROI is allocated. Most OpenCV functions do *not* support the COI setting, so to process an individual image/matrix channel one may copy (via :ocv:cfunc:`Copy` or :ocv:cfunc:`Split`) the channel to a separate image/matrix, process it and then copy the result back (via :ocv:cfunc:`Copy` or :ocv:cfunc:`Merge`) if needed. + + +SetImageROI +----------- +Sets an image Region Of Interest (ROI) for a given rectangle. + +.. ocv:cfunction:: void cvSetImageROI( IplImage* image, CvRect rect) +.. ocv:pyoldfunction:: cv.SetImageROI(image, rect)-> None + + :param image: A pointer to the image header + + :param rect: The ROI rectangle + +If the original image ROI was ``NULL`` and the ``rect`` is not the whole image, the ROI structure is allocated. + +Most OpenCV functions support the use of ROI and treat the image rectangle as a separate image. For example, all of the pixel coordinates are counted from the top-left (or bottom-left) corner of the ROI, not the original image. + + +SetReal?D +--------- +Change a specific array element. + +.. ocv:cfunction:: void cvSetReal1D(CvArr* arr, int idx0, double value) + +.. ocv:cfunction:: void cvSetReal2D(CvArr* arr, int idx0, int idx1, double value) + +.. ocv:cfunction:: void cvSetReal3D(CvArr* arr, int idx0, int idx1, int idx2, double value) + +.. ocv:cfunction:: void cvSetRealND( CvArr* arr, const int* idx, double value ) + +.. ocv:pyoldfunction:: cv.SetReal1D(arr, idx, value) -> None +.. ocv:pyoldfunction:: cv.SetReal2D(arr, idx0, idx1, value) -> None +.. ocv:pyoldfunction:: cv.SetReal3D(arr, idx0, idx1, idx2, value) -> None +.. ocv:pyoldfunction:: cv.SetRealND(arr, indices, value) -> None + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param value: The assigned value + +The functions assign a new value to a specific element of a single-channel array. If the array has multiple channels, a runtime error is raised. Note that the ``Set*D`` function can be used safely for both single-channel and multiple-channel arrays, though they are a bit slower. + +In the case of a sparse array the functions create the node if it does not yet exist. + +SetZero +------- +Clears the array. + +.. ocv:cfunction:: void cvSetZero(CvArr* arr) +.. ocv:pyoldfunction:: cv.SetZero(arr) -> None + + :param arr: Array to be cleared + +The function clears the array. In the case of dense arrays (CvMat, CvMatND or IplImage), cvZero(array) is equivalent to cvSet(array,cvScalarAll(0),0). In the case of sparse arrays all the elements are removed. + +mGet +---- +Returns the particular element of single-channel floating-point matrix. + +.. ocv:cfunction:: double cvmGet(const CvMat* mat, int row, int col) +.. ocv:pyoldfunction:: cv.mGet(mat, row, col) -> float + + :param mat: Input matrix + + :param row: The zero-based index of row + + :param col: The zero-based index of column + +The function is a fast replacement for :ocv:cfunc:`GetReal2D` in the case of single-channel floating-point matrices. It is faster because it is inline, it does fewer checks for array type and array element type, and it checks for the row and column ranges only in debug mode. + +mSet +---- +Sets a specific element of a single-channel floating-point matrix. + +.. ocv:cfunction:: void cvmSet(CvMat* mat, int row, int col, double value) +.. ocv:pyoldfunction:: cv.mSet(mat, row, col, value)-> None + + :param mat: The matrix + + :param row: The zero-based index of row + + :param col: The zero-based index of column + + :param value: The new value of the matrix element + +The function is a fast replacement for :ocv:cfunc:`SetReal2D` in the case of single-channel floating-point matrices. It is faster because it is inline, it does fewer checks for array type and array element type, and it checks for the row and column ranges only in debug mode. + + +SetIPLAllocators +---------------- +Makes OpenCV use IPL functions for allocating IplImage and IplROI structures. + +.. ocv:cfunction:: void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, Cv_iplCreateROI create_roi, Cv_iplCloneImage clone_image ) + + :param create_header: pointer to a function, creating IPL image header. + + :param allocate_data: pointer to a function, allocating IPL image data. + + :param deallocate: pointer to a function, deallocating IPL image. + + :param create_roi: pointer to a function, creating IPL image ROI (i.e. Region of Interest). + + :param clone_image: pointer to a function, cloning an IPL image. + +Normally, the function is not called directly. Instead, a simple macro ``CV_TURN_ON_IPL_COMPATIBILITY()`` is used that calls ``cvSetIPLAllocators`` and passes there pointers to IPL allocation functions. :: + + ... + CV_TURN_ON_IPL_COMPATIBILITY() + ... + + +RNG +--- +Initializes a random number generator state. + +.. ocv:cfunction:: CvRNG cvRNG(int64 seed=-1) +.. ocv:pyoldfunction:: cv.RNG(seed=-1LL)-> CvRNG + + :param seed: 64-bit value used to initiate a random sequence + +The function initializes a random number generator and returns the state. The pointer to the state can be then passed to the :ocv:cfunc:`RandInt`, :ocv:cfunc:`RandReal` and :ocv:cfunc:`RandArr` functions. In the current implementation a multiply-with-carry generator is used. + +.. seealso:: the C++ class :ocv:class:`RNG` replaced ``CvRNG``. + + +RandArr +------- +Fills an array with random numbers and updates the RNG state. + +.. ocv:cfunction:: void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 ) + +.. ocv:pyoldfunction:: cv.RandArr(rng, arr, distType, param1, param2)-> None + + :param rng: CvRNG state initialized by :ocv:cfunc:`RNG` + + :param arr: The destination array + + :param dist_type: Distribution type + + * **CV_RAND_UNI** uniform distribution + + * **CV_RAND_NORMAL** normal or Gaussian distribution + + :param param1: The first parameter of the distribution. In the case of a uniform distribution it is the inclusive lower boundary of the random numbers range. In the case of a normal distribution it is the mean value of the random numbers. + + :param param2: The second parameter of the distribution. In the case of a uniform distribution it is the exclusive upper boundary of the random numbers range. In the case of a normal distribution it is the standard deviation of the random numbers. + +The function fills the destination array with uniformly or normally distributed random numbers. + +.. seealso:: :ocv:func:`randu`, :ocv:func:`randn`, :ocv:func:`RNG::fill`. + +RandInt +------- +Returns a 32-bit unsigned integer and updates RNG. + +.. ocv:cfunction:: unsigned cvRandInt(CvRNG* rng) +.. ocv:pyoldfunction:: cv.RandInt(rng)-> unsigned + + :param rng: CvRNG state initialized by :ocv:cfunc:`RNG`. + +The function returns a uniformly-distributed random 32-bit unsigned integer and updates the RNG state. It is similar to the rand() function from the C runtime library, except that OpenCV functions always generates a 32-bit random number, regardless of the platform. + + +RandReal +-------- +Returns a floating-point random number and updates RNG. + +.. ocv:cfunction:: double cvRandReal(CvRNG* rng) +.. ocv:pyoldfunction:: cv.RandReal(rng) -> float + + :param rng: RNG state initialized by :ocv:cfunc:`RNG` + +The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not included). + + +fromarray +--------- +Create a CvMat from an object that supports the array interface. + +.. ocv:pyoldfunction:: cv.fromarray(array, allowND=False) -> mat + + :param object: Any object that supports the array interface + + :param allowND: If true, will return a CvMatND + +If the object supports the `array interface `_ +, +return a :ocv:struct:`CvMat` or :ocv:struct:`CvMatND`, depending on ``allowND`` flag: + + * If ``allowND = False``, then the object's array must be either 2D or 3D. If it is 2D, then the returned CvMat has a single channel. If it is 3D, then the returned CvMat will have N channels, where N is the last dimension of the array. In this case, N cannot be greater than OpenCV's channel limit, ``CV_CN_MAX``. + + * If``allowND = True``, then ``fromarray`` returns a single-channel :ocv:struct:`CvMatND` with the same shape as the original array. + +For example, `NumPy `_ arrays support the array interface, so can be converted to OpenCV objects: + +.. code-block::python + + >>> import cv2.cv as cv, numpy + >>> a = numpy.ones((480, 640)) + >>> mat = cv.fromarray(a) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640) 1 + >>> a = numpy.ones((480, 640, 3)) + >>> mat = cv.fromarray(a) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640) 3 + >>> a = numpy.ones((480, 640, 3)) + >>> mat = cv.fromarray(a, allowND = True) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640, 3) 1 + +.. note:: In the new Python wrappers (**cv2** module) the function is not needed, since cv2 can process Numpy arrays (and this is the only supported array type). + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/old_xml_yaml_persistence.rst diffimg-2.0.0/3rdparty/opencv/core/doc/old_xml_yaml_persistence.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/old_xml_yaml_persistence.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/old_xml_yaml_persistence.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,913 @@ +XML/YAML Persistence (C API) +============================== + +The section describes the OpenCV 1.x API for reading and writing data structures to/from XML or YAML files. It is now recommended to use the new C++ interface for reading and writing data. + +.. highlight:: c + +CvFileStorage +------------- + +.. ocv:struct:: CvFileStorage + +The structure ``CvFileStorage`` is a "black box" representation of the file storage associated with a file on disk. Several functions that are described below take ``CvFileStorage*`` as inputs and allow the user to save or to load hierarchical collections that consist of scalar values, standard CXCore objects (such as matrices, sequences, graphs), and user-defined objects. + +OpenCV can read and write data in XML (http://www.w3c.org/XML) or YAML +(http://www.yaml.org) formats. Below is an example of 3x3 floating-point identity matrix ``A``, stored in XML and YAML files using CXCore functions: + +XML: :: + + + + + 3 + 3 +
f
+ 1. 0. 0. 0. 1. 0. 0. 0. 1. +
+
+ +YAML: :: + + %YAML:1.0 + A: !!opencv-matrix + rows: 3 + cols: 3 + dt: f + data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.] + +As it can be seen from the examples, XML uses nested tags to represent +hierarchy, while YAML uses indentation for that purpose (similar +to the Python programming language). + +The same functions can read and write data in both formats; +the particular format is determined by the extension of the opened file, ".xml" for XML files and ".yml" or ".yaml" for YAML. + +CvFileNode +---------- + +.. ocv:struct:: CvFileNode + + File storage node. When XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of nodes. Each node can be a "leaf", that is, contain a single number or a string, or be a collection of other nodes. Collections are also referenced to as "structures" in the data writing functions. There can be named collections (mappings), where each element has a name and is accessed by a name, and ordered collections (sequences), where elements do not have names, but rather accessed by index. + + .. ocv:member:: int tag + + type of the file node: + + * CV_NODE_NONE - empty node + * CV_NODE_INT - an integer + * CV_NODE_REAL - a floating-point number + * CV_NODE_STR - text string + * CV_NODE_SEQ - a sequence + * CV_NODE_MAP - a mapping + + type of the node can be retrieved using ``CV_NODE_TYPE(node->tag)`` macro. + + .. ocv:member:: CvTypeInfo* info + + optional pointer to the user type information. If you look at the matrix representation in XML and YAML, shown above, you may notice ``type_id="opencv-matrix"`` or ``!!opencv-matrix`` strings. They are used to specify that the certain element of a file is a representation of a data structure of certain type ("opencv-matrix" corresponds to :ocv:struct:`CvMat`). When a file is parsed, such type identifiers are passed to :ocv:cfunc:`FindType` to find type information and the pointer to it is stored in the file node. See :ocv:struct:`CvTypeInfo` for more details. + + .. ocv:member:: union data + + the node data, declared as: :: + + union + { + double f; /* scalar floating-point number */ + int i; /* scalar integer number */ + CvString str; /* text string */ + CvSeq* seq; /* sequence (ordered collection of file nodes) */ + struct CvMap* map; /* map (collection of named file nodes) */ + } data; + + .. + + Primitive nodes are read using :ocv:cfunc:`ReadInt`, :ocv:cfunc:`ReadReal` and :ocv:cfunc:`ReadString`. Sequences are read by iterating through ``node->data.seq`` (see "Dynamic Data Structures" section). Mappings are read using :ocv:cfunc:`GetFileNodeByName`. Nodes with the specified type (so that ``node->info != NULL``) can be read using :ocv:cfunc:`Read`. + +CvAttrList +---------- + +.. ocv:struct:: CvAttrList + +List of attributes. :: + + typedef struct CvAttrList + { + const char** attr; /* NULL-terminated array of (attribute_name,attribute_value) pairs */ + struct CvAttrList* next; /* pointer to next chunk of the attributes list */ + } + CvAttrList; + + /* initializes CvAttrList structure */ + inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL ); + + /* returns attribute value or 0 (NULL) if there is no such attribute */ + const char* cvAttrValue( const CvAttrList* attr, const char* attr_name ); + +.. + +In the current implementation, attributes are used to pass extra parameters when writing user objects (see +:ocv:cfunc:`Write`). XML attributes inside tags are not supported, aside from the object type specification (``type_id`` attribute). + +CvTypeInfo +---------- + +.. ocv:struct:: CvTypeInfo + +Type information. :: + + typedef int (CV_CDECL *CvIsInstanceFunc)( const void* structPtr ); + typedef void (CV_CDECL *CvReleaseFunc)( void** structDblPtr ); + typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); + typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, + const char* name, + const void* structPtr, + CvAttrList attributes ); + typedef void* (CV_CDECL *CvCloneFunc)( const void* structPtr ); + + typedef struct CvTypeInfo + { + int flags; /* not used */ + int header_size; /* sizeof(CvTypeInfo) */ + struct CvTypeInfo* prev; /* previous registered type in the list */ + struct CvTypeInfo* next; /* next registered type in the list */ + const char* type_name; /* type name, written to file storage */ + + /* methods */ + CvIsInstanceFunc is_instance; /* checks if the passed object belongs to the type */ + CvReleaseFunc release; /* releases object (memory etc.) */ + CvReadFunc read; /* reads object from file storage */ + CvWriteFunc write; /* writes object to file storage */ + CvCloneFunc clone; /* creates a copy of the object */ + } + CvTypeInfo; + +.. + +The structure contains information about one of the standard or user-defined types. Instances of the type may or may not contain a pointer to the corresponding :ocv:struct:`CvTypeInfo` structure. In any case, there is a way to find the type info structure for a given object using the :ocv:cfunc:`TypeOf` function. Alternatively, type info can be found by type name using :ocv:cfunc:`FindType`, which is used when an object is read from file storage. The user can register a new type with :ocv:cfunc:`RegisterType` +that adds the type information structure into the beginning of the type list. Thus, it is possible to create specialized types from generic standard types and override the basic methods. + +Clone +----- +Makes a clone of an object. + +.. ocv:cfunction:: void* cvClone( const void* struct_ptr ) + + :param struct_ptr: The object to clone + +The function finds the type of a given object and calls ``clone`` with the passed object. Of course, if you know the object type, for example, ``struct_ptr`` is ``CvMat*``, it is faster to call the specific function, like :ocv:cfunc:`CloneMat`. + +EndWriteStruct +-------------- +Finishes writing to a file node collection. + +.. ocv:cfunction:: void cvEndWriteStruct(CvFileStorage* fs) + + :param fs: File storage + +.. seealso:: :ocv:cfunc:`StartWriteStruct`. + +FindType +-------- +Finds a type by its name. + +.. ocv:cfunction:: CvTypeInfo* cvFindType( const char* type_name ) + + :param type_name: Type name + +The function finds a registered type by its name. It returns NULL if there is no type with the specified name. + +FirstType +--------- +Returns the beginning of a type list. + +.. ocv:cfunction:: CvTypeInfo* cvFirstType(void) + +The function returns the first type in the list of registered types. Navigation through the list can be done via the ``prev`` and ``next`` fields of the :ocv:struct:`CvTypeInfo` structure. + +GetFileNode +----------- +Finds a node in a map or file storage. + +.. ocv:cfunction:: CvFileNode* cvGetFileNode( CvFileStorage* fs, CvFileNode* map, const CvStringHashNode* key, int create_missing=0 ) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches a top-level node. If both ``map`` and ``key`` are NULLs, the function returns the root file node - a map that contains top-level nodes. + + :param key: Unique pointer to the node name, retrieved with :ocv:cfunc:`GetHashedKey` + + :param create_missing: Flag that specifies whether an absent node should be added to the map + +The function finds a file node. It is a faster version of :ocv:cfunc:`GetFileNodeByName` +(see :ocv:cfunc:`GetHashedKey` discussion). Also, the function can insert a new node, if it is not in the map yet. + +GetFileNodeByName +----------------- +Finds a node in a map or file storage. + +.. ocv:cfunction:: CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* map, const char* name) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches in all the top-level nodes (streams), starting with the first one. + + :param name: The file node name + +The function finds a file node by ``name``. The node is searched either in ``map`` or, if the pointer is NULL, among the top-level file storage nodes. Using this function for maps and :ocv:cfunc:`GetSeqElem` +(or sequence reader) for sequences, it is possible to navigate through the file storage. To speed up multiple queries for a certain key (e.g., in the case of an array of structures) one may use a combination of :ocv:cfunc:`GetHashedKey` and :ocv:cfunc:`GetFileNode`. + +GetFileNodeName +--------------- +Returns the name of a file node. + +.. ocv:cfunction:: const char* cvGetFileNodeName( const CvFileNode* node ) + + :param node: File node + +The function returns the name of a file node or NULL, if the file node does not have a name or if ``node`` is ``NULL``. + +GetHashedKey +------------ +Returns a unique pointer for a given name. + +.. ocv:cfunction:: CvStringHashNode* cvGetHashedKey( CvFileStorage* fs, const char* name, int len=-1, int create_missing=0 ) + + :param fs: File storage + + :param name: Literal node name + + :param len: Length of the name (if it is known apriori), or -1 if it needs to be calculated + + :param create_missing: Flag that specifies, whether an absent key should be added into the hash table + +The function returns a unique pointer for each particular file node name. This pointer can be then passed to the :ocv:cfunc:`GetFileNode` function that is faster than :ocv:cfunc:`GetFileNodeByName` +because it compares text strings by comparing pointers rather than the strings' content. + +Consider the following example where an array of points is encoded as a sequence of 2-entry maps: :: + + points: + - { x: 10, y: 10 } + - { x: 20, y: 20 } + - { x: 30, y: 30 } + # ... + +.. + +Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. :: + + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ ); + CvStringHashNode* x_key = cvGetHashedNode( fs, "x", -1, 1 ); + CvStringHashNode* y_key = cvGetHashedNode( fs, "y", -1, 1 ); + CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" ); + + if( CV_NODE_IS_SEQ(points->tag) ) + { + CvSeq* seq = points->data.seq; + int i, total = seq->total; + CvSeqReader reader; + cvStartReadSeq( seq, &reader, 0 ); + for( i = 0; i < total; i++ ) + { + CvFileNode* pt = (CvFileNode*)reader.ptr; + #if 1 /* faster variant */ + CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 ); + CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #elif 1 /* slower variant; does not use x_key & y_key */ + CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" ); + CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #else /* the slowest yet the easiest to use variant */ + int x = cvReadIntByName( fs, pt, "x", 0 /* default value */ ); + int y = cvReadIntByName( fs, pt, "y", 0 /* default value */ ); + #endif + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + printf(" + } + } + cvReleaseFileStorage( &fs ); + return 0; + } + +.. + +Please note that whatever method of accessing a map you are using, it is +still much slower than using plain sequences; for example, in the above +example, it is more efficient to encode the points as pairs of integers +in a single numeric sequence. + +GetRootFileNode +--------------- +Retrieves one of the top-level nodes of the file storage. + +.. ocv:cfunction:: CvFileNode* cvGetRootFileNode( const CvFileStorage* fs, int stream_index=0 ) + + :param fs: File storage + + :param stream_index: Zero-based index of the stream. See :ocv:cfunc:`StartNextStream` . In most cases, there is only one stream in the file; however, there can be several. + +The function returns one of the top-level file nodes. The top-level nodes do not have a name, they correspond to the streams that are stored one after another in the file storage. If the index is out of range, the function returns a NULL pointer, so all the top-level nodes can be iterated by subsequent calls to the function with ``stream_index=0,1,...``, until the NULL pointer is returned. This function +can be used as a base for recursive traversal of the file storage. + + +Load +---- +Loads an object from a file. + +.. ocv:cfunction:: void* cvLoad( const char* filename, CvMemStorage* memstorage=NULL, const char* name=NULL, const char** real_name=NULL ) + +.. ocv:pyoldfunction:: cv.Load(filename, storage=None, name=None)-> generic + + :param filename: File name + + :param memstorage: Memory storage for dynamic structures, such as :ocv:struct:`CvSeq` or :ocv:struct:`CvGraph` . It is not used for matrices or images. + + :param name: Optional object name. If it is NULL, the first top-level object in the storage will be loaded. + + :param real_name: Optional output parameter that will contain the name of the loaded object (useful if ``name=NULL`` ) + +The function loads an object from a file. It basically reads the specified file, find the first top-level node and calls :ocv:cfunc:`Read` for that node. If the file node does not have type information or the type information can not be found by the type name, the function returns NULL. After the object is loaded, the file storage is closed and all the temporary buffers are deleted. Thus, to load a dynamic structure, such as a sequence, contour, or graph, one should pass a valid memory storage destination to the function. + +OpenFileStorage +--------------- +Opens file storage for reading or writing data. + +.. ocv:cfunction:: CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags, const char* encoding=NULL ) + + :param filename: Name of the file associated with the storage + + :param memstorage: Memory storage used for temporary data and for + storing dynamic structures, such as :ocv:struct:`CvSeq` or :ocv:struct:`CvGraph` . + If it is NULL, a temporary memory storage is created and used. + + :param flags: Can be one of the following: + + * **CV_STORAGE_READ** the storage is open for reading + + * **CV_STORAGE_WRITE** the storage is open for writing + +The function opens file storage for reading or writing data. In the latter case, a new file is created or an existing file is rewritten. The type of the read or written file is determined by the filename extension: ``.xml`` for ``XML`` and ``.yml`` or ``.yaml`` for ``YAML``. The function returns a pointer to the :ocv:struct:`CvFileStorage` structure. If the file cannot be opened then the function returns ``NULL``. + +Read +---- +Decodes an object and returns a pointer to it. + +.. ocv:cfunction:: void* cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* attributes=NULL ) + + :param fs: File storage + + :param node: The root object node + + :param attributes: Unused parameter + +The function decodes a user object (creates an object in a native representation from the file storage subtree) and returns it. The object to be decoded must be an instance of a registered type that supports the ``read`` method (see :ocv:struct:`CvTypeInfo`). The type of the object is determined by the type name that is encoded in the file. If the object is a dynamic structure, it is created either in memory storage and passed to :ocv:cfunc:`OpenFileStorage` or, if a NULL pointer was passed, in temporary +memory storage, which is released when :ocv:cfunc:`ReleaseFileStorage` is called. Otherwise, if the object is not a dynamic structure, it is created in a heap and should be released with a specialized function or by using the generic :ocv:cfunc:`Release`. + +ReadByName +---------- +Finds an object by name and decodes it. + +.. ocv:cfunction:: void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, const char* name, CvAttrList* attributes=NULL ) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches a top-level node. + + :param name: The node name + + :param attributes: Unused parameter + +The function is a simple superposition of :ocv:cfunc:`GetFileNodeByName` and :ocv:cfunc:`Read`. + +ReadInt +------- +Retrieves an integer value from a file node. + +.. ocv:cfunction:: int cvReadInt( const CvFileNode* node, int default_value=0 ) + + :param node: File node + + :param default_value: The value that is returned if ``node`` is NULL + +The function returns an integer that is represented by the file node. If the file node is NULL, the +``default_value`` is returned (thus, it is convenient to call the function right after :ocv:cfunc:`GetFileNode` without checking for a NULL pointer). If the file node has type ``CV_NODE_INT``, then ``node->data.i`` is returned. If the file node has type ``CV_NODE_REAL``, then ``node->data.f`` +is converted to an integer and returned. Otherwise the error is reported. + +ReadIntByName +------------- +Finds a file node and returns its value. + +.. ocv:cfunction:: int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, int default_value=0 ) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches a top-level node. + + :param name: The node name + + :param default_value: The value that is returned if the file node is not found + +The function is a simple superposition of :ocv:cfunc:`GetFileNodeByName` and :ocv:cfunc:`ReadInt`. + +ReadRawData +----------- +Reads multiple numbers. + +.. ocv:cfunction:: void cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, void* dst, const char* dt) + + :param fs: File storage + + :param src: The file node (a sequence) to read numbers from + + :param dst: Pointer to the destination array + + :param dt: Specification of each array element. It has the same format as in :ocv:cfunc:`WriteRawData` . + +The function reads elements from a file node that represents a sequence of scalars. + + +ReadRawDataSlice +---------------- +Initializes file node sequence reader. + +.. ocv:cfunction:: void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int count, void* dst, const char* dt ) + + :param fs: File storage + + :param reader: The sequence reader. Initialize it with :ocv:cfunc:`StartReadRawData` . + + :param count: The number of elements to read + + :param dst: Pointer to the destination array + + :param dt: Specification of each array element. It has the same format as in :ocv:cfunc:`WriteRawData` . + +The function reads one or more elements from the file node, representing a sequence, to a user-specified array. The total number of read sequence elements is a product of ``total`` +and the number of components in each array element. For example, if ``dt=2if``, the function will read ``total*3`` sequence elements. As with any sequence, some parts of the file node sequence can be skipped or read repeatedly by repositioning the reader using :ocv:cfunc:`SetSeqReaderPos`. + +ReadReal +-------- +Retrieves a floating-point value from a file node. + +.. ocv:cfunction:: double cvReadReal( const CvFileNode* node, double default_value=0. ) + + :param node: File node + + :param default_value: The value that is returned if ``node`` is NULL + +The function returns a floating-point value +that is represented by the file node. If the file node is NULL, the +``default_value`` +is returned (thus, it is convenient to call +the function right after +:ocv:cfunc:`GetFileNode` +without checking for a NULL +pointer). If the file node has type +``CV_NODE_REAL`` +, +then +``node->data.f`` +is returned. If the file node has type +``CV_NODE_INT`` +, then +``node-:math:`>`data.f`` +is converted to floating-point +and returned. Otherwise the result is not determined. + + +ReadRealByName +-------------- +Finds a file node and returns its value. + +.. ocv:cfunction:: double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, double default_value=0. ) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches a top-level node. + + :param name: The node name + + :param default_value: The value that is returned if the file node is not found + +The function is a simple superposition of +:ocv:cfunc:`GetFileNodeByName` +and +:ocv:cfunc:`ReadReal` +. + + +ReadString +---------- +Retrieves a text string from a file node. + +.. ocv:cfunction:: const char* cvReadString( const CvFileNode* node, const char* default_value=NULL ) + + :param node: File node + + :param default_value: The value that is returned if ``node`` is NULL + +The function returns a text string that is represented +by the file node. If the file node is NULL, the +``default_value`` +is returned (thus, it is convenient to call the function right after +:ocv:cfunc:`GetFileNode` +without checking for a NULL pointer). If +the file node has type +``CV_NODE_STR`` +, then +``node-:math:`>`data.str.ptr`` +is returned. Otherwise the result is not determined. + + +ReadStringByName +---------------- +Finds a file node by its name and returns its value. + +.. ocv:cfunction:: const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, const char* default_value=NULL ) + + :param fs: File storage + + :param map: The parent map. If it is NULL, the function searches a top-level node. + + :param name: The node name + + :param default_value: The value that is returned if the file node is not found + +The function is a simple superposition of +:ocv:cfunc:`GetFileNodeByName` +and +:ocv:cfunc:`ReadString` +. + + +RegisterType +------------ +Registers a new type. + +.. ocv:cfunction:: void cvRegisterType(const CvTypeInfo* info) + + :param info: Type info structure + +The function registers a new type, which is +described by +``info`` +. The function creates a copy of the structure, +so the user should delete it after calling the function. + + +Release +------- +Releases an object. + +.. ocv:cfunction:: void cvRelease( void** struct_ptr ) + + :param struct_ptr: Double pointer to the object + +The function finds the type of a given object and calls +``release`` +with the double pointer. + + +ReleaseFileStorage +------------------ +Releases file storage. + +.. ocv:cfunction:: void cvReleaseFileStorage(CvFileStorage** fs) + + :param fs: Double pointer to the released file storage + +The function closes the file associated with the storage and releases all the temporary structures. It must be called after all I/O operations with the storage are finished. + + +Save +---- +Saves an object to a file. + +.. ocv:cfunction:: void cvSave( const char* filename, const void* struct_ptr, const char* name=NULL, const char* comment=NULL, CvAttrList attributes=cvAttrList() ) + +.. ocv:pyoldfunction:: cv.Save(filename, structPtr, name=None, comment=None)-> None + + :param filename: File name + + :param struct_ptr: Object to save + + :param name: Optional object name. If it is NULL, the name will be formed from ``filename`` . + + :param comment: Optional comment to put in the beginning of the file + + :param attributes: Optional attributes passed to :ocv:cfunc:`Write` + +The function saves an object to a file. It provides a simple interface to +:ocv:cfunc:`Write` +. + + +StartNextStream +--------------- +Starts the next stream. + +.. ocv:cfunction:: void cvStartNextStream(CvFileStorage* fs) + + :param fs: File storage + +The function finishes the currently written stream and starts the next stream. In the case of XML the file with multiple streams looks like this: :: + + + + + + + + ... + +The YAML file will look like this: :: + + %YAML:1.0 + # stream #1 data + ... + --- + # stream #2 data + +This is useful for concatenating files or for resuming the writing process. + + +StartReadRawData +---------------- +Initializes the file node sequence reader. + +.. ocv:cfunction:: void cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader) + + :param fs: File storage + + :param src: The file node (a sequence) to read numbers from + + :param reader: Pointer to the sequence reader + +The function initializes the sequence reader to read data from a file node. The initialized reader can be then passed to :ocv:cfunc:`ReadRawDataSlice`. + + +StartWriteStruct +---------------- +Starts writing a new structure. + +.. ocv:cfunction:: void cvStartWriteStruct( CvFileStorage* fs, const char* name, int struct_flags, const char* type_name=NULL, CvAttrList attributes=cvAttrList() ) + + :param fs: File storage + + :param name: Name of the written structure. The structure can be accessed by this name when the storage is read. + + :param struct_flags: A combination one of the following values: + + * **CV_NODE_SEQ** the written structure is a sequence (see discussion of :ocv:struct:`CvFileStorage` ), that is, its elements do not have a name. + + * **CV_NODE_MAP** the written structure is a map (see discussion of :ocv:struct:`CvFileStorage` ), that is, all its elements have names. + + One and only one of the two above flags must be specified + + * **CV_NODE_FLOW** the optional flag that makes sense only for YAML streams. It means that the structure is written as a flow (not as a block), which is more compact. It is recommended to use this flag for structures or arrays whose elements are all scalars. + + :param type_name: Optional parameter - the object type name. In + case of XML it is written as a ``type_id`` attribute of the + structure opening tag. In the case of YAML it is written after a colon + following the structure name (see the example in :ocv:struct:`CvFileStorage` + description). Mainly it is used with user objects. When the storage + is read, the encoded type name is used to determine the object type + (see :ocv:struct:`CvTypeInfo` and :ocv:cfunc:`FindType` ). + + :param attributes: This parameter is not used in the current implementation + +The function starts writing a compound structure (collection) that can be a sequence or a map. After all the structure fields, which can be scalars or structures, are written, :ocv:cfunc:`EndWriteStruct` should be called. The function can be used to group some objects or to implement the ``write`` function for a some user object (see :ocv:struct:`CvTypeInfo`). + + +TypeOf +------ +Returns the type of an object. + +.. ocv:cfunction:: CvTypeInfo* cvTypeOf( const void* struct_ptr ) + + :param struct_ptr: The object pointer + +The function finds the type of a given object. It iterates through the list of registered types and calls the ``is_instance`` function/method for every type info structure with that object until one of them returns non-zero or until the whole list has been traversed. In the latter case, the function returns NULL. + + +UnregisterType +-------------- +Unregisters the type. + +.. ocv:cfunction:: void cvUnregisterType( const char* type_name ) + + :param type_name: Name of an unregistered type + +The function unregisters a type with a specified name. If the name is unknown, it is possible to locate the type info by an instance of the type using :ocv:cfunc:`TypeOf` or by iterating the type list, starting from :ocv:cfunc:`FirstType`, and then calling ``cvUnregisterType(info->typeName)``. + + +Write +----- +Writes an object to file storage. + +.. ocv:cfunction:: void cvWrite( CvFileStorage* fs, const char* name, const void* ptr, CvAttrList attributes=cvAttrList() ) + + :param fs: File storage + + :param name: Name of the written object. Should be NULL if and only if the parent structure is a sequence. + + :param ptr: Pointer to the object + + :param attributes: The attributes of the object. They are specific for each particular type (see the discussion below). + +The function writes an object to file storage. First, the appropriate type info is found using :ocv:cfunc:`TypeOf`. Then, the ``write`` method associated with the type info is called. + +Attributes are used to customize the writing procedure. The standard types support the following attributes (all the ``dt`` attributes have the same format as in :ocv:cfunc:`WriteRawData`): + +#. + CvSeq + + * **header_dt** description of user fields of the sequence header that follow CvSeq, or CvChain (if the sequence is a Freeman chain) or CvContour (if the sequence is a contour or point sequence) + + * **dt** description of the sequence elements. + + * **recursive** if the attribute is present and is not equal to "0" or "false", the whole tree of sequences (contours) is stored. + +#. + CvGraph + + * **header_dt** description of user fields of the graph header that follows CvGraph; + + * **vertex_dt** description of user fields of graph vertices + + * **edge_dt** description of user fields of graph edges (note that the edge weight is always written, so there is no need to specify it explicitly) + +Below is the code that creates the YAML file shown in the +``CvFileStorage`` +description: + +:: + + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvMat* mat = cvCreateMat( 3, 3, CV_32F ); + CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE ); + + cvSetIdentity( mat ); + cvWrite( fs, "A", mat, cvAttrList(0,0) ); + + cvReleaseFileStorage( &fs ); + cvReleaseMat( &mat ); + return 0; + } + +.. + + +WriteComment +------------ +Writes a comment. + +.. ocv:cfunction:: void cvWriteComment( CvFileStorage* fs, const char* comment, int eol_comment ) + + :param fs: File storage + + :param comment: The written comment, single-line or multi-line + + :param eol_comment: If non-zero, the function tries to put the comment at the end of current line. If the flag is zero, if the comment is multi-line, or if it does not fit at the end of the current line, the comment starts a new line. + +The function writes a comment into file storage. The comments are skipped when the storage is read. + +WriteFileNode +------------- +Writes a file node to another file storage. + +.. ocv:cfunction:: void cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, const CvFileNode* node, int embed ) + + :param fs: Destination file storage + + :param new_node_name: New name of the file node in the destination file storage. To keep the existing name, use :ocv:cfunc:`cvGetFileNodeName` + + :param node: The written node + + :param embed: If the written node is a collection and this parameter is not zero, no extra level of hierarchy is created. Instead, all the elements of ``node`` are written into the currently written structure. Of course, map elements can only be embedded into another map, and sequence elements can only be embedded into another sequence. + +The function writes a copy of a file node to file storage. Possible applications of the function are merging several file storages into one and conversion between XML and YAML formats. + +WriteInt +-------- +Writes an integer value. + +.. ocv:cfunction:: void cvWriteInt( CvFileStorage* fs, const char* name, int value) + + :param fs: File storage + + :param name: Name of the written value. Should be NULL if and only if the parent structure is a sequence. + + :param value: The written value + +The function writes a single integer value (with or without a name) to the file storage. + + +WriteRawData +------------ +Writes multiple numbers. + +.. ocv:cfunction:: void cvWriteRawData( CvFileStorage* fs, const void* src, int len, const char* dt ) + + :param fs: File storage + + :param src: Pointer to the written array + + :param len: Number of the array elements to write + + :param dt: Specification of each array element that has the following format ``([count]{'u'|'c'|'w'|'s'|'i'|'f'|'d'})...`` + where the characters correspond to fundamental C types: + + * **u** 8-bit unsigned number + + * **c** 8-bit signed number + + * **w** 16-bit unsigned number + + * **s** 16-bit signed number + + * **i** 32-bit signed number + + * **f** single precision floating-point number + + * **d** double precision floating-point number + + * **r** pointer, 32 lower bits of which are written as a signed integer. The type can be used to store structures with links between the elements. ``count`` is the optional counter of values of a given type. For + example, ``2if`` means that each array element is a structure + of 2 integers, followed by a single-precision floating-point number. The + equivalent notations of the above specification are ' ``iif`` ', + ' ``2i1f`` ' and so forth. Other examples: ``u`` means that the + array consists of bytes, and ``2d`` means the array consists of pairs + of doubles. + +The function writes an array, whose elements consist +of single or multiple numbers. The function call can be replaced with +a loop containing a few +:ocv:cfunc:`WriteInt` +and +:ocv:cfunc:`WriteReal` +calls, but +a single call is more efficient. Note that because none of the elements +have a name, they should be written to a sequence rather than a map. + + +WriteReal +--------- +Writes a floating-point value. + +.. ocv:cfunction:: void cvWriteReal( CvFileStorage* fs, const char* name, double value ) + + :param fs: File storage + + :param name: Name of the written value. Should be NULL if and only if the parent structure is a sequence. + + :param value: The written value + +The function writes a single floating-point value (with or without a name) to file storage. Special values are encoded as follows: NaN (Not A Number) as .NaN, infinity as +.Inf or -.Inf. + +The following example shows how to use the low-level writing functions to store custom structures, such as termination criteria, without registering a new type. :: + + void write_termcriteria( CvFileStorage* fs, const char* struct_name, + CvTermCriteria* termcrit ) + { + cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0)); + cvWriteComment( fs, "termination criteria", 1 ); // just a description + if( termcrit->type & CV_TERMCRIT_ITER ) + cvWriteInteger( fs, "max_iterations", termcrit->max_iter ); + if( termcrit->type & CV_TERMCRIT_EPS ) + cvWriteReal( fs, "accuracy", termcrit->epsilon ); + cvEndWriteStruct( fs ); + } + +.. + + +WriteString +----------- +Writes a text string. + +.. ocv:cfunction:: void cvWriteString( CvFileStorage* fs, const char* name, const char* str, int quote=0 ) + + :param fs: File storage + + :param name: Name of the written string . Should be NULL if and only if the parent structure is a sequence. + + :param str: The written text string + + :param quote: If non-zero, the written string is put in quotes, regardless of whether they are required. Otherwise, if the flag is zero, quotes are used only when they are required (e.g. when the string starts with a digit or contains spaces). + +The function writes a text string to file storage. diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/operations_on_arrays.rst diffimg-2.0.0/3rdparty/opencv/core/doc/operations_on_arrays.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/operations_on_arrays.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/operations_on_arrays.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3500 @@ +Operations on Arrays +==================== + +.. highlight:: cpp + +abs +--- +Calculates an absolute value of each matrix element. + +.. ocv:function:: MatExpr abs( const Mat& m ) +.. ocv:function:: MatExpr abs( const MatExpr& e ) + + :param m: matrix. + :param e: matrix expression. + +``abs`` is a meta-function that is expanded to one of :ocv:func:`absdiff` or :ocv:func:`convertScaleAbs` forms: + + * ``C = abs(A-B)`` is equivalent to ``absdiff(A, B, C)`` + + * ``C = abs(A)`` is equivalent to ``absdiff(A, Scalar::all(0), C)`` + + * ``C = Mat_ >(abs(A*alpha + beta))`` is equivalent to ``convertScaleAbs(A, C, alpha, beta)`` + +The output matrix has the same size and the same type as the input one except for the last case, where ``C`` is ``depth=CV_8U`` . + + .. seealso:: :ref:`MatrixExpressions`, :ocv:func:`absdiff`, :ocv:func:`convertScaleAbs` + + +absdiff +------- +Calculates the per-element absolute difference between two arrays or between an array and a scalar. + +.. ocv:function:: void absdiff(InputArray src1, InputArray src2, OutputArray dst) + +.. ocv:pyfunction:: cv2.absdiff(src1, src2[, dst]) -> dst + +.. ocv:cfunction:: void cvAbsDiff(const CvArr* src1, const CvArr* src2, CvArr* dst) +.. ocv:cfunction:: void cvAbsDiffS(const CvArr* src, CvArr* dst, CvScalar value) +.. ocv:pyoldfunction:: cv.AbsDiff(src1, src2, dst)-> None +.. ocv:pyoldfunction:: cv.AbsDiffS(src, dst, value)-> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size and type as input arrays. + +The function ``absdiff`` calculates: + + * + Absolute difference between two arrays when they have the same size and type: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|) + + * + Absolute difference between an array and a scalar when the second array is constructed from ``Scalar`` or has as many elements as the number of channels in ``src1``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |) + + * + Absolute difference between a scalar and an array when the first array is constructed from ``Scalar`` or has as many elements as the number of channels in ``src2``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |) + + where ``I`` is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently. + +.. note:: Saturation is not applied when the arrays have the depth ``CV_32S``. You may even get a negative value in the case of overflow. + +.. seealso:: :ocv:func:`abs` + + +add +--- + +Calculates the per-element sum of two arrays or an array and a scalar. + +.. ocv:function:: void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1) + +.. ocv:pyfunction:: cv2.add(src1, src2[, dst[, mask[, dtype]]]) -> dst + +.. ocv:cfunction:: void cvAdd(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) +.. ocv:cfunction:: void cvAddS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Add(src1, src2, dst, mask=None)-> None +.. ocv:pyoldfunction:: cv.AddS(src, value, dst, mask=None)-> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size and number of channels as the input array(s); the depth is defined by ``dtype`` or ``src1``/``src2``. + + :param mask: optional operation mask - 8-bit single channel array, that specifies elements of the output array to be changed. + + :param dtype: optional depth of the output array (see the discussion below). + +The function ``add`` calculates: + + * + Sum of two arrays when both input arrays have the same size and the same number of channels: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0 + + * + Sum of an array and a scalar when ``src2`` is constructed from ``Scalar`` or has the same number of elements as ``src1.channels()``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0 + + * + Sum of a scalar and an array when ``src1`` is constructed from ``Scalar`` or has the same number of elements as ``src2.channels()``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0 + + where ``I`` is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: :: + + dst = src1 + src2; + dst += src1; // equivalent to add(dst, src1, dst); + +The input arrays and the output array can all have the same or different depths. For example, you can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit floating-point array. Depth of the output array is determined by the ``dtype`` parameter. In the second and third cases above, as well as in the first case, when ``src1.depth() == src2.depth()``, ``dtype`` can be set to the default ``-1``. In this case, the output array will have the same depth as the input array, be it ``src1``, ``src2`` or both. + +.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow. + +.. seealso:: + + :ocv:func:`subtract`, + :ocv:func:`addWeighted`, + :ocv:func:`scaleAdd`, + :ocv:func:`Mat::convertTo`, + :ref:`MatrixExpressions` + + + +addWeighted +----------- +Calculates the weighted sum of two arrays. + +.. ocv:function:: void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1) + +.. ocv:pyfunction:: cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) -> dst + +.. ocv:cfunction:: void cvAddWeighted(const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst) +.. ocv:pyoldfunction:: cv.AddWeighted(src1, alpha, src2, beta, gamma, dst)-> None + + :param src1: first input array. + + :param alpha: weight of the first array elements. + + :param src2: second input array of the same size and channel number as ``src1``. + + :param beta: weight of the second array elements. + + :param dst: output array that has the same size and number of channels as the input arrays. + + :param gamma: scalar added to each sum. + + :param dtype: optional depth of the output array; when both input arrays have the same depth, ``dtype`` can be set to ``-1``, which will be equivalent to ``src1.depth()``. + +The function ``addWeighted`` calculates the weighted sum of two arrays as follows: + +.. math:: + + \texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} ) + +where ``I`` is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently. + +The function can be replaced with a matrix expression: :: + + dst = src1*alpha + src2*beta + gamma; + +.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow. + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`subtract`, + :ocv:func:`scaleAdd`, + :ocv:func:`Mat::convertTo`, + :ref:`MatrixExpressions` + + + +bitwise_and +----------- +Calculates the per-element bit-wise conjunction of two arrays or an array and a scalar. + +.. ocv:function:: void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.bitwise_and(src1, src2[, dst[, mask]]) -> dst + +.. ocv:cfunction:: void cvAnd(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) +.. ocv:cfunction:: void cvAndS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.And(src1, src2, dst, mask=None)-> None +.. ocv:pyoldfunction:: cv.AndS(src, value, dst, mask=None)-> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size and type as the input arrays. + + :param mask: optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed. + +The function calculates the per-element bit-wise logical conjunction for: + + * + Two arrays when ``src1`` and ``src2`` have the same size: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + * + An array and a scalar when ``src2`` is constructed from ``Scalar`` or has the same number of elements as ``src1.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0 + + * + A scalar and an array when ``src1`` is constructed from ``Scalar`` or has the same number of elements as ``src2.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + +In case of floating-point arrays, their machine-specific bit representations (usually IEEE754-compliant) are used for the operation. In case of multi-channel arrays, each channel is processed independently. In the second and third cases above, the scalar is first converted to the array type. + + + +bitwise_not +----------- +Inverts every bit of an array. + +.. ocv:function:: void bitwise_not(InputArray src, OutputArray dst, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.bitwise_not(src[, dst[, mask]]) -> dst + +.. ocv:cfunction:: void cvNot(const CvArr* src, CvArr* dst) +.. ocv:pyoldfunction:: cv.Not(src, dst)-> None + + :param src: input array. + + :param dst: output array that has the same size and type as the input array. + + :param mask: optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed. + +The function calculates per-element bit-wise inversion of the input array: + +.. math:: + + \texttt{dst} (I) = \neg \texttt{src} (I) + +In case of a floating-point input array, its machine-specific bit representation (usually IEEE754-compliant) is used for the operation. In case of multi-channel arrays, each channel is processed independently. + + + +bitwise_or +---------- +Calculates the per-element bit-wise disjunction of two arrays or an array and a scalar. + +.. ocv:function:: void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.bitwise_or(src1, src2[, dst[, mask]]) -> dst + +.. ocv:cfunction:: void cvOr(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) +.. ocv:cfunction:: void cvOrS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Or(src1, src2, dst, mask=None)-> None +.. ocv:pyoldfunction:: cv.OrS(src, value, dst, mask=None)-> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size and type as the input arrays. + + :param mask: optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed. + +The function calculates the per-element bit-wise logical disjunction for: + + * + Two arrays when ``src1`` and ``src2`` have the same size: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + * + An array and a scalar when ``src2`` is constructed from ``Scalar`` or has the same number of elements as ``src1.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0 + + * + A scalar and an array when ``src1`` is constructed from ``Scalar`` or has the same number of elements as ``src2.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + +In case of floating-point arrays, their machine-specific bit representations (usually IEEE754-compliant) are used for the operation. In case of multi-channel arrays, each channel is processed independently. In the second and third cases above, the scalar is first converted to the array type. + + +bitwise_xor +----------- +Calculates the per-element bit-wise "exclusive or" operation on two arrays or an array and a scalar. + +.. ocv:function:: void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.bitwise_xor(src1, src2[, dst[, mask]]) -> dst + +.. ocv:cfunction:: void cvXor(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) +.. ocv:cfunction:: void cvXorS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Xor(src1, src2, dst, mask=None)-> None +.. ocv:pyoldfunction:: cv.XorS(src, value, dst, mask=None)-> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size and type as the input arrays. + + :param mask: optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed. + +The function calculates the per-element bit-wise logical "exclusive-or" operation for: + + * + Two arrays when ``src1`` and ``src2`` have the same size: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + * + An array and a scalar when ``src2`` is constructed from ``Scalar`` or has the same number of elements as ``src1.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0 + + * + A scalar and an array when ``src1`` is constructed from ``Scalar`` or has the same number of elements as ``src2.channels()``: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 + + +In case of floating-point arrays, their machine-specific bit representations (usually IEEE754-compliant) are used for the operation. In case of multi-channel arrays, each channel is processed independently. In the 2nd and 3rd cases above, the scalar is first converted to the array type. + + +calcCovarMatrix +--------------- +Calculates the covariance matrix of a set of vectors. + +.. ocv:function:: void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean, int flags, int ctype=CV_64F) + +.. ocv:function:: void calcCovarMatrix( InputArray samples, OutputArray covar, OutputArray mean, int flags, int ctype=CV_64F) + +.. ocv:pyfunction:: cv2.calcCovarMatrix(samples, flags[, covar[, mean[, ctype]]]) -> covar, mean + +.. ocv:cfunction:: void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags ) + +.. ocv:pyoldfunction:: cv.CalcCovarMatrix(vects, covMat, avg, flags)-> None + + :param samples: samples stored either as separate matrices or as rows/columns of a single matrix. + + :param nsamples: number of samples when they are stored separately. + + :param covar: output covariance matrix of the type ``ctype`` and square size. + + :param ctype: type of the matrixl; it equals 'CV_64F' by default. + + :param mean: input or output (depending on the flags) array as the average value of the input vectors. + + :param vects: a set of vectors. + + :param flags: operation flags as a combination of the following values: + + * **CV_COVAR_SCRAMBLED** The output covariance matrix is calculated as: + + .. math:: + + \texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...], + + The covariance matrix will be ``nsamples x nsamples``. Such an unusual covariance matrix is used for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of the "scrambled" covariance matrix. + + * **CV_COVAR_NORMAL** The output covariance matrix is calculated as: + + .. math:: + + \texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T, + + ``covar`` will be a square matrix of the same size as the total number of elements in each input vector. One and only one of ``CV_COVAR_SCRAMBLED`` and ``CV_COVAR_NORMAL`` must be specified. + + * **CV_COVAR_USE_AVG** If the flag is specified, the function does not calculate ``mean`` from the input vectors but, instead, uses the passed ``mean`` vector. This is useful if ``mean`` has been pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In this case, ``mean`` is not a mean vector of the input sub-set of vectors but rather the mean vector of the whole set. + + * **CV_COVAR_SCALE** If the flag is specified, the covariance matrix is scaled. In the "normal" mode, ``scale`` is ``1./nsamples`` . In the "scrambled" mode, ``scale`` is the reciprocal of the total number of elements in each input vector. By default (if the flag is not specified), the covariance matrix is not scaled ( ``scale=1`` ). + + * **CV_COVAR_ROWS** [Only useful in the second variant of the function] If the flag is specified, all the input vectors are stored as rows of the ``samples`` matrix. ``mean`` should be a single-row vector in this case. + + * **CV_COVAR_COLS** [Only useful in the second variant of the function] If the flag is specified, all the input vectors are stored as columns of the ``samples`` matrix. ``mean`` should be a single-column vector in this case. + +The functions ``calcCovarMatrix`` calculate the covariance matrix and, optionally, the mean vector of the set of input vectors. + +.. seealso:: + + :ocv:class:`PCA`, + :ocv:func:`mulTransposed`, + :ocv:func:`Mahalanobis` + + + +cartToPolar +----------- +Calculates the magnitude and angle of 2D vectors. + +.. ocv:function:: void cartToPolar(InputArray x, InputArray y, OutputArray magnitude, OutputArray angle, bool angleInDegrees=false) + +.. ocv:pyfunction:: cv2.cartToPolar(x, y[, magnitude[, angle[, angleInDegrees]]]) -> magnitude, angle + +.. ocv:cfunction:: void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude, CvArr* angle=NULL, int angle_in_degrees=0 ) + +.. ocv:pyoldfunction:: cv.CartToPolar(x, y, magnitude, angle=None, angleInDegrees=0)-> None + + :param x: array of x-coordinates; this must be a single-precision or double-precision floating-point array. + + :param y: array of y-coordinates, that must have the same size and same type as ``x``. + + :param magnitude: output array of magnitudes of the same size and type as ``x``. + + :param angle: output array of angles that has the same size and type as ``x``; the angles are measured in radians (from 0 to 2*Pi) or in degrees (0 to 360 degrees). + + :param angleInDegrees: a flag, indicating whether the angles are measured in radians (which is by default), or in degrees. + + :param angle_in_degrees: a flag, indicating whether the angles are measured in radians, or in degrees (specific to C syntax). + +The function ``cartToPolar`` calculates either the magnitude, angle, or both for every 2D vector (x(I),y(I)): + +.. math:: + + \begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array} + +The angles are calculated with accuracy about 0.3 degrees. For the point (0,0), the angle is set to 0. + +.. seealso:: + + :ocv:func:`Sobel`, + :ocv:func:`Scharr` + +checkRange +---------- +Checks every element of an input array for invalid values. + +.. ocv:function:: bool checkRange( InputArray a, bool quiet=true, Point* pos=0, double minVal=-DBL_MAX, double maxVal=DBL_MAX ) + +.. ocv:pyfunction:: cv2.checkRange(a[, quiet[, minVal[, maxVal]]]) -> retval, pos + + :param a: input array. + + :param quiet: a flag, indicating whether the functions quietly return false when the array elements are out of range or they throw an exception. + + :param pos: optional output parameter, where the position of the first outlier is stored; in the second function ``pos``, when not NULL, must be a pointer to array of ``src.dims`` elements. + + :param minVal: inclusive lower boundary of valid values range. + + :param maxVal: exclusive upper boundary of valid values range. + +The functions ``checkRange`` check that every array element is neither NaN nor +infinite. When ``minVal < -DBL_MAX`` and ``maxVal < DBL_MAX``, the functions also check that each value is between ``minVal`` and ``maxVal``. In case of multi-channel arrays, each channel is processed independently. +If some values are out of range, position of the first outlier is stored in ``pos`` (when +``pos != NULL``). Then, the functions either return false (when ``quiet=true``) or throw an exception. + + + +compare +------- +Performs the per-element comparison of two arrays or an array and scalar value. + +.. ocv:function:: void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop) + +.. ocv:pyfunction:: cv2.compare(src1, src2, cmpop[, dst]) -> dst + +.. ocv:cfunction:: void cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op ) + +.. ocv:pyoldfunction:: cv.Cmp(src1, src2, dst, cmpOp)-> None + +.. ocv:cfunction:: void cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op ) + +.. ocv:pyoldfunction:: cv.CmpS(src, value, dst, cmpOp)-> None + + :param src1: first input array or a scalar (in the case of ``cvCmp``, ``cv.Cmp``, ``cvCmpS``, ``cv.CmpS`` it is always an array); when it is an array, it must have a single channel. + + :param src2: second input array or a scalar (in the case of ``cvCmp`` and ``cv.Cmp`` it is always an array; in the case of ``cvCmpS``, ``cv.CmpS`` it is always a scalar); when it is an array, it must have a single channel. + + :param src: single input array. + + :param value: scalar value. + + :param dst: output array that has the same size as the input arrays and type= ``CV_8UC1`` . + + :param cmpop: a flag, that specifies correspondence between the arrays: + + * **CMP_EQ** ``src1`` is equal to ``src2``. + * **CMP_GT** ``src1`` is greater than ``src2``. + * **CMP_GE** ``src1`` is greater than or equal to ``src2``. + * **CMP_LT** ``src1`` is less than ``src2``. + * **CMP_LE** ``src1`` is less than or equal to ``src2``. + * **CMP_NE** ``src1`` is unequal to ``src2``. + +The function compares: + + + * + Elements of two arrays when ``src1`` and ``src2`` have the same size: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I) + + * + Elements of ``src1`` with a scalar ``src2`` when ``src2`` is constructed from ``Scalar`` or has a single element: + + .. math:: + + \texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2} + + * + ``src1`` with elements of ``src2`` when ``src1`` is constructed from ``Scalar`` or has a single element: + + .. math:: + + \texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I) + + +When the comparison result is true, the corresponding element of output array is set to 255. +The comparison operations can be replaced with the equivalent matrix expressions: :: + + Mat dst1 = src1 >= src2; + Mat dst2 = src1 < 8; + ... + + +.. seealso:: + + :ocv:func:`checkRange`, + :ocv:func:`min`, + :ocv:func:`max`, + :ocv:func:`threshold`, + :ref:`MatrixExpressions` + + + +completeSymm +------------ +Copies the lower or the upper half of a square matrix to another half. + +.. ocv:function:: void completeSymm(InputOutputArray mtx, bool lowerToUpper=false) + +.. ocv:pyfunction:: cv2.completeSymm(mtx[, lowerToUpper]) -> None + + :param mtx: input-output floating-point square matrix. + + :param lowerToUpper: operation flag; if true, the lower half is copied to the upper half. Otherwise, the upper half is copied to the lower half. + +The function ``completeSymm`` copies the lower half of a square matrix to its another half. The matrix diagonal remains unchanged: + + * + :math:`\texttt{mtx}_{ij}=\texttt{mtx}_{ji}` for + :math:`i > j` if ``lowerToUpper=false`` + + * + :math:`\texttt{mtx}_{ij}=\texttt{mtx}_{ji}` for + :math:`i < j` if ``lowerToUpper=true`` + +.. seealso:: + + :ocv:func:`flip`, + :ocv:func:`transpose` + + + +convertScaleAbs +--------------- +Scales, calculates absolute values, and converts the result to 8-bit. + +.. ocv:function:: void convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0) + +.. ocv:pyfunction:: cv2.convertScaleAbs(src[, dst[, alpha[, beta]]]) -> dst + +.. ocv:cfunction:: void cvConvertScaleAbs(const CvArr* src, CvArr* dst, double scale=1, double shift=0) +.. ocv:pyoldfunction:: cv.ConvertScaleAbs(src, dst, scale=1.0, shift=0.0)-> None + + :param src: input array. + + :param dst: output array. + + :param alpha: optional scale factor. + + :param beta: optional delta added to the scaled values. + +On each element of the input array, the function ``convertScaleAbs`` performs three operations sequentially: scaling, taking an absolute value, conversion to an unsigned 8-bit type: + + +.. math:: + + \texttt{dst} (I)= \texttt{saturate\_cast} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |) + +In case of multi-channel arrays, the function processes each channel independently. When the output is not 8-bit, the operation can be emulated by calling the ``Mat::convertTo`` method (or by using matrix expressions) and then by calculating an absolute value of the result. For example: :: + + Mat_ A(30,30); + randu(A, Scalar(-100), Scalar(100)); + Mat_ B = A*5 + 3; + B = abs(B); + // Mat_ B = abs(A*5+3) will also do the job, + // but it will allocate a temporary matrix + + +.. seealso:: + + :ocv:func:`Mat::convertTo`, + :ocv:func:`abs` + + + +countNonZero +------------ +Counts non-zero array elements. + +.. ocv:function:: int countNonZero( InputArray src ) + +.. ocv:pyfunction:: cv2.countNonZero(src) -> retval + +.. ocv:cfunction:: int cvCountNonZero(const CvArr* arr) + +.. ocv:pyoldfunction:: cv.CountNonZero(arr)-> int + + :param src: single-channel array. + +The function returns the number of non-zero elements in ``src`` : + +.. math:: + + \sum _{I: \; \texttt{src} (I) \ne0 } 1 + +.. seealso:: + + :ocv:func:`mean`, + :ocv:func:`meanStdDev`, + :ocv:func:`norm`, + :ocv:func:`minMaxLoc`, + :ocv:func:`calcCovarMatrix` + + + +cvarrToMat +---------- +Converts ``CvMat``, ``IplImage`` , or ``CvMatND`` to ``Mat``. + +.. ocv:function:: Mat cvarrToMat( const CvArr* arr, bool copyData=false, bool allowND=true, int coiMode=0 ) + + :param arr: input ``CvMat``, ``IplImage`` , or ``CvMatND``. + + :param copyData: when false (default value), no data is copied and only the new header is created, in this case, the original array should not be deallocated while the new matrix header is used; if the parameter is true, all the data is copied and you may deallocate the original array right after the conversion. + + :param allowND: when true (default value), ``CvMatND`` is converted to 2-dimensional ``Mat``, if it is possible (see the discussion below); if it is not possible, or when the parameter is false, the function will report an error. + + :param coiMode: parameter specifying how the IplImage COI (when set) is handled. + + * If ``coiMode=0`` and COI is set, the function reports an error. + + * If ``coiMode=1`` , the function never reports an error. Instead, it returns the header to the whole original image and you will have to check and process COI manually. See :ocv:func:`extractImageCOI` . + +The function ``cvarrToMat`` converts ``CvMat``, ``IplImage`` , or ``CvMatND`` header to +:ocv:class:`Mat` header, and optionally duplicates the underlying data. The constructed header is returned by the function. + +When ``copyData=false`` , the conversion is done really fast (in O(1) time) and the newly created matrix header will have ``refcount=0`` , which means that no reference counting is done for the matrix data. In this case, you have to preserve the data until the new header is destructed. Otherwise, when ``copyData=true`` , the new buffer is allocated and managed as if you created a new matrix from scratch and copied the data there. That is, ``cvarrToMat(arr, true)`` is equivalent to ``cvarrToMat(arr, false).clone()`` (assuming that COI is not set). The function provides a uniform way of supporting +``CvArr`` paradigm in the code that is migrated to use new-style data structures internally. The reverse transformation, from +``Mat`` to +``CvMat`` or +``IplImage`` can be done by a simple assignment: :: + + CvMat* A = cvCreateMat(10, 10, CV_32F); + cvSetIdentity(A); + IplImage A1; cvGetImage(A, &A1); + Mat B = cvarrToMat(A); + Mat B1 = cvarrToMat(&A1); + IplImage C = B; + CvMat C1 = B1; + // now A, A1, B, B1, C and C1 are different headers + // for the same 10x10 floating-point array. + // note that you will need to use "&" + // to pass C & C1 to OpenCV functions, for example: + printf("%g\n", cvNorm(&C1, 0, CV_L2)); + +Normally, the function is used to convert an old-style 2D array ( +``CvMat`` or +``IplImage`` ) to ``Mat`` . However, the function can also take +``CvMatND`` as an input and create +:ocv:func:`Mat` for it, if it is possible. And, for ``CvMatND A`` , it is possible if and only if ``A.dim[i].size*A.dim.step[i] == A.dim.step[i-1]`` for all or for all but one ``i, 0 < i < A.dims`` . That is, the matrix data should be continuous or it should be representable as a sequence of continuous matrices. By using this function in this way, you can process +``CvMatND`` using an arbitrary element-wise function. + +The last parameter, ``coiMode`` , specifies how to deal with an image with COI set. By default, it is 0 and the function reports an error when an image with COI comes in. And ``coiMode=1`` means that no error is signalled. You have to check COI presence and handle it manually. The modern structures, such as +:ocv:class:`Mat` and +``MatND`` do not support COI natively. To process an individual channel of a new-style array, you need either to organize a loop over the array (for example, using matrix iterators) where the channel of interest will be processed, or extract the COI using +:ocv:func:`mixChannels` (for new-style arrays) or +:ocv:func:`extractImageCOI` (for old-style arrays), process this individual channel, and insert it back to the output array if needed (using +:ocv:func:`mixChannels` or +:ocv:func:`insertImageCOI` , respectively). + +.. seealso:: + + :ocv:cfunc:`cvGetImage`, + :ocv:cfunc:`cvGetMat`, + :ocv:func:`extractImageCOI`, + :ocv:func:`insertImageCOI`, + :ocv:func:`mixChannels` + +dct +--- +Performs a forward or inverse discrete Cosine transform of 1D or 2D array. + +.. ocv:function:: void dct(InputArray src, OutputArray dst, int flags=0) + +.. ocv:pyfunction:: cv2.dct(src[, dst[, flags]]) -> dst + +.. ocv:cfunction:: void cvDCT(const CvArr* src, CvArr* dst, int flags) +.. ocv:pyoldfunction:: cv.DCT(src, dst, flags)-> None + + :param src: input floating-point array. + + :param dst: output array of the same size and type as ``src`` . + + :param flags: transformation flags as a combination of the following values: + + * **DCT_INVERSE** performs an inverse 1D or 2D transform instead of the default forward transform. + + * **DCT_ROWS** performs a forward or inverse transform of every individual row of the input matrix. This flag enables you to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself) to perform 3D and higher-dimensional transforms and so forth. + +The function ``dct`` performs a forward or inverse discrete Cosine transform (DCT) of a 1D or 2D floating-point array: + +* + Forward Cosine transform of a 1D vector of ``N`` elements: + + .. math:: + + Y = C^{(N)} \cdot X + + where + + .. math:: + + C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right ) + + and + + :math:`\alpha_0=1`, :math:`\alpha_j=2` for *j > 0*. + +* + Inverse Cosine transform of a 1D vector of ``N`` elements: + + .. math:: + + X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y + + (since + :math:`C^{(N)}` is an orthogonal matrix, + :math:`C^{(N)} \cdot \left(C^{(N)}\right)^T = I` ) + +* + Forward 2D Cosine transform of ``M x N`` matrix: + + .. math:: + + Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T + +* + Inverse 2D Cosine transform of ``M x N`` matrix: + + .. math:: + + X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)} + + +The function chooses the mode of operation by looking at the flags and size of the input array: + +* + If ``(flags & DCT_INVERSE) == 0`` , the function does a forward 1D or 2D transform. Otherwise, it is an inverse 1D or 2D transform. + +* + If ``(flags & DCT_ROWS) != 0`` , the function performs a 1D transform of each row. + +* + If the array is a single column or a single row, the function performs a 1D transform. + +* + If none of the above is true, the function performs a 2D transform. + +.. note:: + + Currently ``dct`` supports even-size arrays (2, 4, 6 ...). For data analysis and approximation, you can pad the array when necessary. + + Also, the function performance depends very much, and not monotonically, on the array size (see + :ocv:func:`getOptimalDFTSize` ). In the current implementation DCT of a vector of size ``N`` is calculated via DFT of a vector of size ``N/2`` . Thus, the optimal DCT size ``N1 >= N`` can be calculated as: :: + + size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); } + N1 = getOptimalDCTSize(N); + +.. seealso:: :ocv:func:`dft` , :ocv:func:`getOptimalDFTSize` , :ocv:func:`idct` + + + +dft +--- +Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. + +.. ocv:function:: void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0) + +.. ocv:pyfunction:: cv2.dft(src[, dst[, flags[, nonzeroRows]]]) -> dst + +.. ocv:cfunction:: void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows=0 ) + +.. ocv:pyoldfunction:: cv.DFT(src, dst, flags, nonzeroRows=0)-> None + + :param src: input array that could be real or complex. + + :param dst: output array whose size and type depends on the ``flags`` . + + :param flags: transformation flags, representing a combination of the following values: + + * **DFT_INVERSE** performs an inverse 1D or 2D transform instead of the default forward transform. + + * **DFT_SCALE** scales the result: divide it by the number of array elements. Normally, it is combined with ``DFT_INVERSE``. + * **DFT_ROWS** performs a forward or inverse transform of every individual row of the input matrix; this flag enables you to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself) to perform 3D and higher-dimensional transformations and so forth. + + * **DFT_COMPLEX_OUTPUT** performs a forward transformation of 1D or 2D real array; the result, though being a complex array, has complex-conjugate symmetry (*CCS*, see the function description below for details), and such an array can be packed into a real array of the same size as input, which is the fastest option and which is what the function does by default; however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) - pass the flag to enable the function to produce a full-size complex output array. + + * **DFT_REAL_OUTPUT** performs an inverse transformation of a 1D or 2D complex array; the result is normally a complex array of the same size, however, if the input array has conjugate-complex symmetry (for example, it is a result of forward transformation with ``DFT_COMPLEX_OUTPUT`` flag), the output is a real array; while the function itself does not check whether the input is symmetrical or not, you can pass the flag and then the function will assume the symmetry and produce the real output array (note that when the input is packed into a real array and inverse transformation is executed, the function treats the input as a packed complex-conjugate symmetrical array, and the output will also be a real array). + + :param nonzeroRows: when the parameter is not zero, the function assumes that only the first ``nonzeroRows`` rows of the input array (``DFT_INVERSE`` is not set) or only the first ``nonzeroRows`` of the output array (``DFT_INVERSE`` is set) contain non-zeros, thus, the function can handle the rest of the rows more efficiently and save some time; this technique is very useful for calculating array cross-correlation or convolution using DFT. + + +The function performs one of the following: + +* + Forward the Fourier transform of a 1D vector of ``N`` elements: + + .. math:: + + Y = F^{(N)} \cdot X, + + where + :math:`F^{(N)}_{jk}=\exp(-2\pi i j k/N)` and + :math:`i=\sqrt{-1}` + +* + Inverse the Fourier transform of a 1D vector of ``N`` elements: + + .. math:: + + \begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array} + + where + :math:`F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T` + +* + Forward the 2D Fourier transform of a ``M x N`` matrix: + + .. math:: + + Y = F^{(M)} \cdot X \cdot F^{(N)} + +* + Inverse the 2D Fourier transform of a ``M x N`` matrix: + + .. math:: + + \begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array} + + +In case of real (single-channel) data, the output spectrum of the forward Fourier transform or input spectrum of the inverse Fourier transform can be represented in a packed format called *CCS* (complex-conjugate-symmetrical). It was borrowed from IPL (Intel* Image Processing Library). Here is how 2D *CCS* spectrum looks: + +.. math:: + + \begin{bmatrix} Re Y_{0,0} & Re Y_{0,1} & Im Y_{0,1} & Re Y_{0,2} & Im Y_{0,2} & \cdots & Re Y_{0,N/2-1} & Im Y_{0,N/2-1} & Re Y_{0,N/2} \\ Re Y_{1,0} & Re Y_{1,1} & Im Y_{1,1} & Re Y_{1,2} & Im Y_{1,2} & \cdots & Re Y_{1,N/2-1} & Im Y_{1,N/2-1} & Re Y_{1,N/2} \\ Im Y_{1,0} & Re Y_{2,1} & Im Y_{2,1} & Re Y_{2,2} & Im Y_{2,2} & \cdots & Re Y_{2,N/2-1} & Im Y_{2,N/2-1} & Im Y_{1,N/2} \\ \hdotsfor{9} \\ Re Y_{M/2-1,0} & Re Y_{M-3,1} & Im Y_{M-3,1} & \hdotsfor{3} & Re Y_{M-3,N/2-1} & Im Y_{M-3,N/2-1}& Re Y_{M/2-1,N/2} \\ Im Y_{M/2-1,0} & Re Y_{M-2,1} & Im Y_{M-2,1} & \hdotsfor{3} & Re Y_{M-2,N/2-1} & Im Y_{M-2,N/2-1}& Im Y_{M/2-1,N/2} \\ Re Y_{M/2,0} & Re Y_{M-1,1} & Im Y_{M-1,1} & \hdotsfor{3} & Re Y_{M-1,N/2-1} & Im Y_{M-1,N/2-1}& Re Y_{M/2,N/2} \end{bmatrix} + +In case of 1D transform of a real vector, the output looks like the first row of the matrix above. + +So, the function chooses an operation mode depending on the flags and size of the input array: + + * If ``DFT_ROWS`` is set or the input array has a single row or single column, the function performs a 1D forward or inverse transform of each row of a matrix when ``DFT_ROWS`` is set. Otherwise, it performs a 2D transform. + + * If the input array is real and ``DFT_INVERSE`` is not set, the function performs a forward 1D or 2D transform: + + * When ``DFT_COMPLEX_OUTPUT`` is set, the output is a complex matrix of the same size as input. + + * When ``DFT_COMPLEX_OUTPUT`` is not set, the output is a real matrix of the same size as input. In case of 2D transform, it uses the packed format as shown above. In case of a single 1D transform, it looks like the first row of the matrix above. In case of multiple 1D transforms (when using the ``DCT_ROWS`` flag), each row of the output matrix looks like the first row of the matrix above. + + * If the input array is complex and either ``DFT_INVERSE`` or ``DFT_REAL_OUTPUT`` are not set, the output is a complex array of the same size as input. The function performs a forward or inverse 1D or 2D transform of the whole input array or each row of the input array independently, depending on the flags ``DFT_INVERSE`` and ``DFT_ROWS``. + + * When ``DFT_INVERSE`` is set and the input array is real, or it is complex but ``DFT_REAL_OUTPUT`` is set, the output is a real array of the same size as input. The function performs a 1D or 2D inverse transformation of the whole input array or each individual row, depending on the flags ``DFT_INVERSE`` and ``DFT_ROWS``. + +If ``DFT_SCALE`` is set, the scaling is done after the transformation. + +Unlike :ocv:func:`dct` , the function supports arrays of arbitrary size. But only those arrays are processed efficiently, whose sizes can be factorized in a product of small prime numbers (2, 3, and 5 in the current implementation). Such an efficient DFT size can be calculated using the :ocv:func:`getOptimalDFTSize` method. + +The sample below illustrates how to calculate a DFT-based convolution of two 2D real arrays: :: + + void convolveDFT(InputArray A, InputArray B, OutputArray C) + { + // reallocate the output array if needed + C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type()); + Size dftSize; + // calculate the size of DFT transform + dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1); + dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1); + + // allocate temporary buffers and initialize them with 0's + Mat tempA(dftSize, A.type(), Scalar::all(0)); + Mat tempB(dftSize, B.type(), Scalar::all(0)); + + // copy A and B to the top-left corners of tempA and tempB, respectively + Mat roiA(tempA, Rect(0,0,A.cols,A.rows)); + A.copyTo(roiA); + Mat roiB(tempB, Rect(0,0,B.cols,B.rows)); + B.copyTo(roiB); + + // now transform the padded A & B in-place; + // use "nonzeroRows" hint for faster processing + dft(tempA, tempA, 0, A.rows); + dft(tempB, tempB, 0, B.rows); + + // multiply the spectrums; + // the function handles packed spectrum representations well + mulSpectrums(tempA, tempB, tempA); + + // transform the product back from the frequency domain. + // Even though all the result rows will be non-zero, + // you need only the first C.rows of them, and thus you + // pass nonzeroRows == C.rows + dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows); + + // now copy the result back to C. + tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C); + + // all the temporary buffers will be deallocated automatically + } + + +To optimize this sample, consider the following approaches: + +* + Since ``nonzeroRows != 0`` is passed to the forward transform calls and since ``A`` and ``B`` are copied to the top-left corners of ``tempA`` and ``tempB``, respectively, it is not necessary to clear the whole ``tempA`` and ``tempB``. It is only necessary to clear the ``tempA.cols - A.cols`` ( ``tempB.cols - B.cols``) rightmost columns of the matrices. + +* + This DFT-based convolution does not have to be applied to the whole big arrays, especially if ``B`` is significantly smaller than ``A`` or vice versa. Instead, you can calculate convolution by parts. To do this, you need to split the output array ``C`` into multiple tiles. For each tile, estimate which parts of ``A`` and ``B`` are required to calculate convolution in this tile. If the tiles in ``C`` are too small, the speed will decrease a lot because of repeated work. In the ultimate case, when each tile in ``C`` is a single pixel, the algorithm becomes equivalent to the naive convolution algorithm. If the tiles are too big, the temporary arrays ``tempA`` and ``tempB`` become too big and there is also a slowdown because of bad cache locality. So, there is an optimal tile size somewhere in the middle. + +* + If different tiles in ``C`` can be calculated in parallel and, thus, the convolution is done by parts, the loop can be threaded. + +All of the above improvements have been implemented in :ocv:func:`matchTemplate` and :ocv:func:`filter2D` . Therefore, by using them, you can get the performance even better than with the above theoretically optimal implementation. Though, those two functions actually calculate cross-correlation, not convolution, so you need to "flip" the second convolution operand ``B`` vertically and horizontally using :ocv:func:`flip` . + +.. seealso:: :ocv:func:`dct` , :ocv:func:`getOptimalDFTSize` , :ocv:func:`mulSpectrums`, :ocv:func:`filter2D` , :ocv:func:`matchTemplate` , :ocv:func:`flip` , :ocv:func:`cartToPolar` , :ocv:func:`magnitude` , :ocv:func:`phase` + + + +divide +------ +Performs per-element division of two arrays or a scalar by an array. + +.. ocv:function:: void divide(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1) + +.. ocv:function:: void divide(double scale, InputArray src2, OutputArray dst, int dtype=-1) + +.. ocv:pyfunction:: cv2.divide(src1, src2[, dst[, scale[, dtype]]]) -> dst +.. ocv:pyfunction:: cv2.divide(scale, src2[, dst[, dtype]]) -> dst + +.. ocv:cfunction:: void cvDiv(const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1) +.. ocv:pyoldfunction:: cv.Div(src1, src2, dst, scale=1) -> None + + :param src1: first input array. + + :param src2: second input array of the same size and type as ``src1``. + + :param scale: scalar factor. + + :param dst: output array of the same size and type as ``src2``. + + :param dtype: optional depth of the output array; if ``-1``, ``dst`` will have depth ``src2.depth()``, but in case of an array-by-array division, you can only pass ``-1`` when ``src1.depth()==src2.depth()``. + +The functions ``divide`` divide one array by another: + +.. math:: + + \texttt{dst(I) = saturate(src1(I)*scale/src2(I))} + +or a scalar by an array when there is no ``src1`` : + +.. math:: + + \texttt{dst(I) = saturate(scale/src2(I))} + +When ``src2(I)`` is zero, ``dst(I)`` will also be zero. Different channels of multi-channel arrays are processed independently. + +.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow. + +.. seealso:: + + :ocv:func:`multiply`, + :ocv:func:`add`, + :ocv:func:`subtract`, + :ref:`MatrixExpressions` + + + +determinant +----------- +Returns the determinant of a square floating-point matrix. + +.. ocv:function:: double determinant(InputArray mtx) + +.. ocv:pyfunction:: cv2.determinant(mtx) -> retval + +.. ocv:cfunction:: double cvDet( const CvArr* mat ) + +.. ocv:pyoldfunction:: cv.Det(mat) -> float + + :param mtx: input matrix that must have ``CV_32FC1`` or ``CV_64FC1`` type and square size. + +The function ``determinant`` calculates and returns the determinant of the specified matrix. For small matrices ( ``mtx.cols=mtx.rows<=3`` ), +the direct method is used. For larger matrices, the function uses LU factorization with partial pivoting. + +For symmetric positively-determined matrices, it is also possible to use :ocv:func:`eigen` decomposition to calculate the determinant. + +.. seealso:: + + :ocv:func:`trace`, + :ocv:func:`invert`, + :ocv:func:`solve`, + :ocv:func:`eigen`, + :ref:`MatrixExpressions` + + + +eigen +----- +Calculates eigenvalues and eigenvectors of a symmetric matrix. + +.. ocv:function:: bool eigen(InputArray src, OutputArray eigenvalues, int lowindex=-1, int highindex=-1) + +.. ocv:function:: bool eigen(InputArray src, OutputArray eigenvalues, OutputArray eigenvectors, int lowindex=-1,int highindex=-1) + +.. ocv:pyfunction:: cv2.eigen(src, computeEigenvectors[, eigenvalues[, eigenvectors]]) -> retval, eigenvalues, eigenvectors + +.. ocv:cfunction:: void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0, int lowindex=-1, int highindex=-1 ) + +.. ocv:pyoldfunction:: cv.EigenVV(mat, evects, evals, eps, lowindex=-1, highindex=-1)-> None + + :param src: input matrix that must have ``CV_32FC1`` or ``CV_64FC1`` type, square size and be symmetrical (``src`` :sup:`T` == ``src``). + + :param eigenvalues: output vector of eigenvalues of the same type as ``src``; the eigenvalues are stored in the descending order. + + :param eigenvectors: output matrix of eigenvectors; it has the same size and type as ``src``; the eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding eigenvalues. + + :param lowindex: optional index of largest eigenvalue/-vector to calculate; the parameter is ignored in the current implementation. + + :param highindex: optional index of smallest eigenvalue/-vector to calculate; the parameter is ignored in the current implementation. + +The functions ``eigen`` calculate just eigenvalues, or eigenvalues and eigenvectors of the symmetric matrix ``src`` : :: + + src*eigenvectors.row(i).t() = eigenvalues.at(i)*eigenvectors.row(i).t() + +.. note:: in the new and the old interfaces different ordering of eigenvalues and eigenvectors parameters is used. + +.. seealso:: :ocv:func:`completeSymm` , :ocv:class:`PCA` + + + +exp +--- +Calculates the exponent of every array element. + +.. ocv:function:: void exp(InputArray src, OutputArray dst) + +.. ocv:pyfunction:: cv2.exp(src[, dst]) -> dst + +.. ocv:cfunction:: void cvExp(const CvArr* src, CvArr* dst) +.. ocv:pyoldfunction:: cv.Exp(src, dst)-> None + + :param src: input array. + + :param dst: output array of the same size and type as ``src``. + +The function ``exp`` calculates the exponent of every element of the input array: + +.. math:: + + \texttt{dst} [I] = e^{ src(I) } + +The maximum relative error is about ``7e-6`` for single-precision input and less than ``1e-10`` for double-precision input. Currently, the function converts denormalized values to zeros on output. Special values (NaN, Inf) are not handled. + +.. seealso:: :ocv:func:`log` , :ocv:func:`cartToPolar` , :ocv:func:`polarToCart` , :ocv:func:`phase` , :ocv:func:`pow` , :ocv:func:`sqrt` , :ocv:func:`magnitude` + + + +extractImageCOI +--------------- +Extracts the selected image channel. + +.. ocv:function:: void extractImageCOI( const CvArr* arr, OutputArray coiimg, int coi=-1 ) + + :param arr: input array; it should be a pointer to ``CvMat`` or ``IplImage``. + + :param coiimg: output array with a single channel and the same size and depth as ``arr``. + + :param coi: if the parameter is ``>=0``, it specifies the channel to extract, if it is ``<0`` and ``arr`` is a pointer to ``IplImage`` with a valid COI set, the selected COI is extracted. + +The function ``extractImageCOI`` is used to extract an image COI from an old-style array and put the result to the new-style C++ matrix. As usual, the output matrix is reallocated using ``Mat::create`` if needed. + +To extract a channel from a new-style matrix, use +:ocv:func:`mixChannels` or +:ocv:func:`split` . + +.. seealso:: :ocv:func:`mixChannels` , :ocv:func:`split` , :ocv:func:`merge` , :ocv:func:`cvarrToMat` , :ocv:cfunc:`cvSetImageCOI` , :ocv:cfunc:`cvGetImageCOI` + + +insertImageCOI +-------------- +Copies the selected image channel from a new-style C++ matrix to the old-style C array. + +.. ocv:function:: void insertImageCOI( InputArray coiimg, CvArr* arr, int coi=-1 ) + + :param coiimg: input array with a single channel and the same size and depth as ``arr``. + + :param arr: output array, it should be a pointer to ``CvMat`` or ``IplImage``. + + :param coi: if the parameter is ``>=0``, it specifies the channel to insert, if it is ``<0`` and ``arr`` is a pointer to ``IplImage`` with a valid COI set, the selected COI is extracted. + +The function ``insertImageCOI`` is used to extract an image COI from a new-style C++ matrix and put the result to the old-style array. + +The sample below illustrates how to use the function: +:: + + Mat temp(240, 320, CV_8UC1, Scalar(255)); + IplImage* img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + insertImageCOI(temp, img, 1); //insert to the first channel + cvNamedWindow("window",1); + cvShowImage("window", img); //you should see green image, because channel number 1 is green (BGR) + cvWaitKey(0); + cvDestroyAllWindows(); + cvReleaseImage(&img); + +To insert a channel to a new-style matrix, use +:ocv:func:`merge` . + +.. seealso:: :ocv:func:`mixChannels` , :ocv:func:`split` , :ocv:func:`merge` , :ocv:func:`cvarrToMat` , :ocv:cfunc:`cvSetImageCOI` , :ocv:cfunc:`cvGetImageCOI` + + +flip +---- +Flips a 2D array around vertical, horizontal, or both axes. + +.. ocv:function:: void flip(InputArray src, OutputArray dst, int flipCode) + +.. ocv:pyfunction:: cv2.flip(src, flipCode[, dst]) -> dst + +.. ocv:cfunction:: void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0 ) + +.. ocv:pyoldfunction:: cv.Flip(src, dst=None, flipMode=0)-> None + + :param src: input array. + + :param dst: output array of the same size and type as ``src``. + + :param flipCode: a flag to specify how to flip the array; 0 means flipping around the x-axis and positive value (for example, 1) means flipping around y-axis. Negative value (for example, -1) means flipping around both axes (see the discussion below for the formulas). + +The function ``flip`` flips the array in one of three different ways (row and column indices are 0-based): + +.. math:: + + \texttt{dst} _{ij} = + \left\{ + \begin{array}{l l} + \texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ + \texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ + \texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ + \end{array} + \right. + +The example scenarios of using the function are the following: + + * + Vertical flipping of the image (``flipCode == 0``) to switch between top-left and bottom-left image origin. This is a typical operation in video processing on Microsoft Windows* OS. + + * + Horizontal flipping of the image with the subsequent horizontal shift and absolute difference calculation to check for a vertical-axis symmetry (``flipCode > 0``). + + * + Simultaneous horizontal and vertical flipping of the image with the subsequent shift and absolute difference calculation to check for a central symmetry (``flipCode < 0``). + + * + Reversing the order of point arrays (``flipCode > 0`` or ``flipCode == 0``). + +.. seealso:: :ocv:func:`transpose` , :ocv:func:`repeat` , :ocv:func:`completeSymm` + + + +gemm +---- +Performs generalized matrix multiplication. + +.. ocv:function:: void gemm( InputArray src1, InputArray src2, double alpha, InputArray src3, double gamma, OutputArray dst, int flags=0 ) + +.. ocv:pyfunction:: cv2.gemm(src1, src2, alpha, src3, gamma[, dst[, flags]]) -> dst + +.. ocv:cfunction:: void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0) +.. ocv:pyoldfunction:: cv.GEMM(src1, src2, alpha, src3, beta, dst, tABC=0)-> None + + :param src1: first multiplied input matrix that should have ``CV_32FC1``, ``CV_64FC1``, ``CV_32FC2``, or ``CV_64FC2`` type. + + :param src2: second multiplied input matrix of the same type as ``src1``. + + :param alpha: weight of the matrix product. + + :param src3: third optional delta matrix added to the matrix product; it should have the same type as ``src1`` and ``src2``. + + :param beta: weight of ``src3``. + + :param dst: output matrix; it has the proper size and the same type as input matrices. + + :param flags: operation flags: + + * **GEMM_1_T** transposes ``src1``. + * **GEMM_2_T** transposes ``src2``. + * **GEMM_3_T** transposes ``src3``. + +The function performs generalized matrix multiplication similar to the ``gemm`` functions in BLAS level 3. For example, ``gemm(src1, src2, alpha, src3, beta, dst, GEMM_1_T + GEMM_3_T)`` corresponds to + +.. math:: + + \texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T + +The function can be replaced with a matrix expression. For example, the above call can be replaced with: :: + + dst = alpha*src1.t()*src2 + beta*src3.t(); + + +.. seealso:: :ocv:func:`mulTransposed` , :ocv:func:`transform` , :ref:`MatrixExpressions` + + + +getConvertElem +-------------- +Returns a conversion function for a single pixel. + +.. ocv:function:: ConvertData getConvertElem(int fromType, int toType) + +.. ocv:function:: ConvertScaleData getConvertScaleElem(int fromType, int toType) + + :param fromType: input pixel type. + + :param toType: output pixel type. + + :param from: callback parameter: pointer to the input pixel. + + :param to: callback parameter: pointer to the output pixel + + :param cn: callback parameter: the number of channels; it can be arbitrary, 1, 100, 100000, etc. + + :param alpha: ``ConvertScaleData`` callback optional parameter: the scale factor. + + :param beta: ``ConvertScaleData`` callback optional parameter: the delta or offset. + +The functions ``getConvertElem`` and ``getConvertScaleElem`` return pointers to the functions for converting individual pixels from one type to another. While the main function purpose is to convert single pixels (actually, for converting sparse matrices from one type to another), you can use them to convert the whole row of a dense matrix or the whole matrix at once, by setting ``cn = matrix.cols*matrix.rows*matrix.channels()`` if the matrix data is continuous. + +``ConvertData`` and ``ConvertScaleData`` are defined as: :: + + typedef void (*ConvertData)(const void* from, void* to, int cn) + typedef void (*ConvertScaleData)(const void* from, void* to, + int cn, double alpha, double beta) + +.. seealso:: :ocv:func:`Mat::convertTo` , :ocv:func:`SparseMat::convertTo` + + + +getOptimalDFTSize +----------------- +Returns the optimal DFT size for a given vector size. + +.. ocv:function:: int getOptimalDFTSize(int vecsize) + +.. ocv:pyfunction:: cv2.getOptimalDFTSize(vecsize) -> retval + +.. ocv:cfunction:: int cvGetOptimalDFTSize(int size0) +.. ocv:pyoldfunction:: cv.GetOptimalDFTSize(size0)-> int + + :param vecsize: vector size. + +DFT performance is not a monotonic function of a vector size. Therefore, when you calculate convolution of two arrays or perform the spectral analysis of an array, it usually makes sense to pad the input data with zeros to get a bit larger array that can be transformed much faster than the original one. +Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process. Though, the arrays whose size is a product of 2's, 3's, and 5's (for example, 300 = 5*5*3*2*2) are also processed quite efficiently. + +The function ``getOptimalDFTSize`` returns the minimum number ``N`` that is greater than or equal to ``vecsize`` so that the DFT of a vector of size ``N`` can be processed efficiently. In the current implementation ``N`` = 2 :sup:`p` * 3 :sup:`q` * 5 :sup:`r` for some integer ``p``, ``q``, ``r``. + +The function returns a negative number if ``vecsize`` is too large (very close to ``INT_MAX`` ). + +While the function cannot be used directly to estimate the optimal vector size for DCT transform (since the current DCT implementation supports only even-size vectors), it can be easily processed as ``getOptimalDFTSize((vecsize+1)/2)*2``. + +.. seealso:: :ocv:func:`dft` , :ocv:func:`dct` , :ocv:func:`idft` , :ocv:func:`idct` , :ocv:func:`mulSpectrums` + + + +idct +---- +Calculates the inverse Discrete Cosine Transform of a 1D or 2D array. + +.. ocv:function:: void idct(InputArray src, OutputArray dst, int flags=0) + +.. ocv:pyfunction:: cv2.idct(src[, dst[, flags]]) -> dst + + :param src: input floating-point single-channel array. + + :param dst: output array of the same size and type as ``src``. + + :param flags: operation flags. + +``idct(src, dst, flags)`` is equivalent to ``dct(src, dst, flags | DCT_INVERSE)``. + +.. seealso:: + + :ocv:func:`dct`, + :ocv:func:`dft`, + :ocv:func:`idft`, + :ocv:func:`getOptimalDFTSize` + + + +idft +---- +Calculates the inverse Discrete Fourier Transform of a 1D or 2D array. + +.. ocv:function:: void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0) + +.. ocv:pyfunction:: cv2.idft(src[, dst[, flags[, nonzeroRows]]]) -> dst + + :param src: input floating-point real or complex array. + + :param dst: output array whose size and type depend on the ``flags``. + + :param flags: operation flags (see :ocv:func:`dft`). + + :param nonzeroRows: number of ``dst`` rows to process; the rest of the rows have undefined content (see the convolution sample in :ocv:func:`dft` description. + +``idft(src, dst, flags)`` is equivalent to ``dft(src, dst, flags | DFT_INVERSE)`` . + +See :ocv:func:`dft` for details. + +.. note:: None of ``dft`` and ``idft`` scales the result by default. So, you should pass ``DFT_SCALE`` to one of ``dft`` or ``idft`` explicitly to make these transforms mutually inverse. + +.. seealso:: + + :ocv:func:`dft`, + :ocv:func:`dct`, + :ocv:func:`idct`, + :ocv:func:`mulSpectrums`, + :ocv:func:`getOptimalDFTSize` + + + +inRange +------- +Checks if array elements lie between the elements of two other arrays. + +.. ocv:function:: void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst) + +.. ocv:pyfunction:: cv2.inRange(src, lowerb, upperb[, dst]) -> dst + +.. ocv:cfunction:: void cvInRange(const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst) +.. ocv:cfunction:: void cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst) +.. ocv:pyoldfunction:: cv.InRange(src, lower, upper, dst)-> None +.. ocv:pyoldfunction:: cv.InRangeS(src, lower, upper, dst)-> None + + :param src: first input array. + + :param lowerb: inclusive lower boundary array or a scalar. + + :param upperb: inclusive upper boundary array or a scalar. + + :param dst: output array of the same size as ``src`` and ``CV_8U`` type. + +The function checks the range as follows: + + * For every element of a single-channel input array: + + .. math:: + + \texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 + + * For two-channel arrays: + + .. math:: + + \texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1 + + * and so forth. + +That is, ``dst`` (I) is set to 255 (all ``1`` -bits) if ``src`` (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise. + +When the lower and/or upper boundary parameters are scalars, the indexes ``(I)`` at ``lowerb`` and ``upperb`` in the above formulas should be omitted. + + +invert +------ +Finds the inverse or pseudo-inverse of a matrix. + +.. ocv:function:: double invert(InputArray src, OutputArray dst, int flags=DECOMP_LU) + +.. ocv:pyfunction:: cv2.invert(src[, dst[, flags]]) -> retval, dst + +.. ocv:cfunction:: double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU ) + +.. ocv:pyoldfunction:: cv.Invert(src, dst, method=CV_LU) -> float + + :param src: input floating-point ``M x N`` matrix. + + :param dst: output matrix of ``N x M`` size and the same type as ``src``. + + :param flags: inversion method : + + * **DECOMP_LU** Gaussian elimination with the optimal pivot element chosen. + + * **DECOMP_SVD** singular value decomposition (SVD) method. + + * **DECOMP_CHOLESKY** Cholesky decomposition; the matrix must be symmetrical and positively defined. + +The function ``invert`` inverts the matrix ``src`` and stores the result in ``dst`` . +When the matrix ``src`` is singular or non-square, the function calculates the pseudo-inverse matrix (the ``dst`` matrix) so that ``norm(src*dst - I)`` is minimal, where I is an identity matrix. + +In case of the ``DECOMP_LU`` method, the function returns non-zero value if the inverse has been successfully calculated and 0 if ``src`` is singular. + +In case of the ``DECOMP_SVD`` method, the function returns the inverse condition number of ``src`` (the ratio of the smallest singular value to the largest singular value) and 0 if ``src`` is singular. The SVD method calculates a pseudo-inverse matrix if ``src`` is singular. + +Similarly to ``DECOMP_LU`` , the method ``DECOMP_CHOLESKY`` works only with non-singular square matrices that should also be symmetrical and positively defined. In this case, the function stores the inverted matrix in ``dst`` and returns non-zero. Otherwise, it returns 0. + +.. seealso:: + + :ocv:func:`solve`, + :ocv:class:`SVD` + + + +log +--- +Calculates the natural logarithm of every array element. + +.. ocv:function:: void log(InputArray src, OutputArray dst) + +.. ocv:pyfunction:: cv2.log(src[, dst]) -> dst + +.. ocv:cfunction:: void cvLog(const CvArr* src, CvArr* dst) +.. ocv:pyoldfunction:: cv.Log(src, dst)-> None + + :param src: input array. + + :param dst: output array of the same size and type as ``src`` . + +The function ``log`` calculates the natural logarithm of the absolute value of every element of the input array: + +.. math:: + + \texttt{dst} (I) = \fork{\log |\texttt{src}(I)|}{if $\texttt{src}(I) \ne 0$ }{\texttt{C}}{otherwise} + +where ``C`` is a large negative number (about -700 in the current implementation). +The maximum relative error is about ``7e-6`` for single-precision input and less than ``1e-10`` for double-precision input. Special values (NaN, Inf) are not handled. + +.. seealso:: + + :ocv:func:`exp`, + :ocv:func:`cartToPolar`, + :ocv:func:`polarToCart`, + :ocv:func:`phase`, + :ocv:func:`pow`, + :ocv:func:`sqrt`, + :ocv:func:`magnitude` + + + +LUT +--- +Performs a look-up table transform of an array. + +.. ocv:function:: void LUT( InputArray src, InputArray lut, OutputArray dst, int interpolation=0 ) + +.. ocv:pyfunction:: cv2.LUT(src, lut[, dst[, interpolation]]) -> dst + +.. ocv:cfunction:: void cvLUT(const CvArr* src, CvArr* dst, const CvArr* lut) +.. ocv:pyoldfunction:: cv.LUT(src, dst, lut)-> None + + :param src: input array of 8-bit elements. + + :param lut: look-up table of 256 elements; in case of multi-channel input array, the table should either have a single channel (in this case the same table is used for all channels) or the same number of channels as in the input array. + + :param dst: output array of the same size and number of channels as ``src``, and the same depth as ``lut``. + +The function ``LUT`` fills the output array with values from the look-up table. Indices of the entries are taken from the input array. That is, the function processes each element of ``src`` as follows: + +.. math:: + + \texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)} + +where + +.. math:: + + d = \fork{0}{if \texttt{src} has depth \texttt{CV\_8U}}{128}{if \texttt{src} has depth \texttt{CV\_8S}} + +.. seealso:: + + :ocv:func:`convertScaleAbs`, + :ocv:func:`Mat::convertTo` + + + +magnitude +--------- +Calculates the magnitude of 2D vectors. + +.. ocv:function:: void magnitude(InputArray x, InputArray y, OutputArray magnitude) + +.. ocv:pyfunction:: cv2.magnitude(x, y[, magnitude]) -> magnitude + + :param x: floating-point array of x-coordinates of the vectors. + + :param y: floating-point array of y-coordinates of the vectors; it must have the same size as ``x``. + + :param magnitude: output array of the same size and type as ``x``. + +The function ``magnitude`` calculates the magnitude of 2D vectors formed from the corresponding elements of ``x`` and ``y`` arrays: + +.. math:: + + \texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2} + +.. seealso:: + + :ocv:func:`cartToPolar`, + :ocv:func:`polarToCart`, + :ocv:func:`phase`, + :ocv:func:`sqrt` + + + +Mahalanobis +----------- +Calculates the Mahalanobis distance between two vectors. + +.. ocv:function:: double Mahalanobis( InputArray v1, InputArray v2, InputArray icovar ) + +.. ocv:pyfunction:: cv2.Mahalanobis(v1, v2, icovar) -> retval + +.. ocv:cfunction:: double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat ) + +.. ocv:pyoldfunction:: cv.Mahalonobis(vec1, vec2, mat) -> None + + :param vec1: first 1D input vector. + + :param vec2: second 1D input vector. + + :param icovar: inverse covariance matrix. + +The function ``Mahalanobis`` calculates and returns the weighted distance between two vectors: + +.. math:: + + d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} } + +The covariance matrix may be calculated using the +:ocv:func:`calcCovarMatrix` function and then inverted using the +:ocv:func:`invert` function (preferably using the ``DECOMP_SVD`` method, as the most accurate). + + + +max +--- +Calculates per-element maximum of two arrays or an array and a scalar. + +.. ocv:function:: MatExpr max( const Mat& a, const Mat& b ) + +.. ocv:function:: MatExpr max( const Mat& a, double s ) + +.. ocv:function:: MatExpr max( double s, const Mat& a ) + +.. ocv:function:: void max(InputArray src1, InputArray src2, OutputArray dst) + +.. ocv:function:: void max(const Mat& src1, const Mat& src2, Mat& dst) + +.. ocv:function:: void max( const Mat& src1, double src2, Mat& dst ) + +.. ocv:pyfunction:: cv2.max(src1, src2[, dst]) -> dst + +.. ocv:cfunction:: void cvMax(const CvArr* src1, const CvArr* src2, CvArr* dst) +.. ocv:cfunction:: void cvMaxS(const CvArr* src, double value, CvArr* dst) +.. ocv:pyoldfunction:: cv.Max(src1, src2, dst)-> None +.. ocv:pyoldfunction:: cv.MaxS(src, value, dst)-> None + + :param src1: first input array. + + :param src2: second input array of the same size and type as ``src1`` . + + :param value: real scalar value. + + :param dst: output array of the same size and type as ``src1``. + +The functions ``max`` calculate the per-element maximum of two arrays: + +.. math:: + + \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I)) + +or array and a scalar: + +.. math:: + + \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} ) + +In the second variant, when the input array is multi-channel, each channel is compared with ``value`` independently. + +The first 3 variants of the function listed above are actually a part of +:ref:`MatrixExpressions` . They return an expression object that can be further either transformed/ assigned to a matrix, or passed to a function, and so on. + +.. seealso:: + + :ocv:func:`min`, + :ocv:func:`compare`, + :ocv:func:`inRange`, + :ocv:func:`minMaxLoc`, + :ref:`MatrixExpressions` + + +mean +---- +Calculates an average (mean) of array elements. + +.. ocv:function:: Scalar mean(InputArray src, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.mean(src[, mask]) -> retval + +.. ocv:cfunction:: CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.Avg(arr, mask=None) -> scalar + + :param src: input array that should have from 1 to 4 channels so that the result can be stored in :ocv:class:`Scalar_` . + + :param mask: optional operation mask. + +The function ``mean`` calculates the mean value ``M`` of array elements, independently for each channel, and return it: + +.. math:: + + \begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array} + +When all the mask elements are 0's, the functions return ``Scalar::all(0)`` . + +.. seealso:: + + :ocv:func:`countNonZero`, + :ocv:func:`meanStdDev`, + :ocv:func:`norm`, + :ocv:func:`minMaxLoc` + + + +meanStdDev +---------- +Calculates a mean and standard deviation of array elements. + +.. ocv:function:: void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, InputArray mask=noArray()) + +.. ocv:pyfunction:: cv2.meanStdDev(src[, mean[, stddev[, mask]]]) -> mean, stddev + +.. ocv:cfunction:: void cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.AvgSdv(arr, mask=None) -> (mean, stdDev) + + :param src: input array that should have from 1 to 4 channels so that the results can be stored in :ocv:class:`Scalar_` 's. + + :param mean: output parameter: calculated mean value. + + :param stddev: output parameter: calculateded standard deviation. + + :param mask: optional operation mask. + +The function ``meanStdDev`` calculates the mean and the standard deviation ``M`` of array elements independently for each channel and returns it via the output parameters: + +.. math:: + + \begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array} + +When all the mask elements are 0's, the functions return ``mean=stddev=Scalar::all(0)`` . + +.. note:: The calculated standard deviation is only the diagonal of the complete normalized covariance matrix. If the full matrix is needed, you can reshape the multi-channel array ``M x N`` to the single-channel array ``M*N x mtx.channels()`` (only possible when the matrix is continuous) and then pass the matrix to :ocv:func:`calcCovarMatrix` . + +.. seealso:: + + :ocv:func:`countNonZero`, + :ocv:func:`mean`, + :ocv:func:`norm`, + :ocv:func:`minMaxLoc`, + :ocv:func:`calcCovarMatrix` + + + +merge +----- +Creates one multichannel array out of several single-channel ones. + +.. ocv:function:: void merge(const Mat* mv, size_t count, OutputArray dst) + +.. ocv:function:: void merge( InputArrayOfArrays mv, OutputArray dst ) + +.. ocv:pyfunction:: cv2.merge(mv[, dst]) -> dst + +.. ocv:cfunction:: void cvMerge(const CvArr* src0, const CvArr* src1, const CvArr* src2, const CvArr* src3, CvArr* dst) +.. ocv:pyoldfunction:: cv.Merge(src0, src1, src2, src3, dst)-> None + + :param mv: input array or vector of matrices to be merged; all the matrices in ``mv`` must have the same size and the same depth. + + :param count: number of input matrices when ``mv`` is a plain C array; it must be greater than zero. + + :param dst: output array of the same size and the same depth as ``mv[0]``; The number of channels will be the total number of channels in the matrix array. + +The functions ``merge`` merge several arrays to make a single multi-channel array. That is, each element of the output array will be a concatenation of the elements of the input arrays, where elements of i-th input array are treated as ``mv[i].channels()``-element vectors. + +The function +:ocv:func:`split` does the reverse operation. If you need to shuffle channels in some other advanced way, use +:ocv:func:`mixChannels` . + +.. seealso:: + + :ocv:func:`mixChannels`, + :ocv:func:`split`, + :ocv:func:`Mat::reshape` + + + +min +--- +Calculates per-element minimum of two arrays or an array and a scalar. + +.. ocv:function:: MatExpr min( const Mat& a, const Mat& b ) + +.. ocv:function:: MatExpr min( const Mat& a, double s ) + +.. ocv:function:: MatExpr min( double s, const Mat& a ) + +.. ocv:function:: void min(InputArray src1, InputArray src2, OutputArray dst) + +.. ocv:function:: void min(const Mat& src1, const Mat& src2, Mat& dst) + +.. ocv:function:: void min( const Mat& src1, double src2, Mat& dst ) + +.. ocv:pyfunction:: cv2.min(src1, src2[, dst]) -> dst + +.. ocv:cfunction:: void cvMin(const CvArr* src1, const CvArr* src2, CvArr* dst) +.. ocv:cfunction:: void cvMinS(const CvArr* src, double value, CvArr* dst) +.. ocv:pyoldfunction:: cv.Min(src1, src2, dst)-> None +.. ocv:pyoldfunction:: cv.MinS(src, value, dst)-> None + + :param src1: first input array. + + :param src2: second input array of the same size and type as ``src1``. + + :param value: real scalar value. + + :param dst: output array of the same size and type as ``src1``. + +The functions ``min`` calculate the per-element minimum of two arrays: + +.. math:: + + \texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I)) + +or array and a scalar: + +.. math:: + + \texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{value} ) + +In the second variant, when the input array is multi-channel, each channel is compared with ``value`` independently. + +The first three variants of the function listed above are actually a part of +:ref:`MatrixExpressions` . They return the expression object that can be further either transformed/assigned to a matrix, or passed to a function, and so on. + +.. seealso:: + + :ocv:func:`max`, + :ocv:func:`compare`, + :ocv:func:`inRange`, + :ocv:func:`minMaxLoc`, + :ref:`MatrixExpressions` + + +minMaxIdx +--------- +Finds the global minimum and maximum in an array + +.. ocv:function:: void minMaxIdx(InputArray src, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0, InputArray mask=noArray()) + + :param src: input single-channel array. + + :param minVal: pointer to the returned minimum value; ``NULL`` is used if not required. + + :param maxVal: pointer to the returned maximum value; ``NULL`` is used if not required. + + :param minIdx: pointer to the returned minimum location (in nD case); ``NULL`` is used if not required; Otherwise, it must point to an array of ``src.dims`` elements, the coordinates of the minimum element in each dimension are stored there sequentially. + + .. note:: + + When ``minIdx`` is not NULL, it must have at least 2 elements (as well as ``maxIdx``), even if ``src`` is a single-row or single-column matrix. In OpenCV (following MATLAB) each array has at least 2 dimensions, i.e. single-column matrix is ``Mx1`` matrix (and therefore ``minIdx``/``maxIdx`` will be ``(i1,0)``/``(i2,0)``) and single-row matrix is ``1xN`` matrix (and therefore ``minIdx``/``maxIdx`` will be ``(0,j1)``/``(0,j2)``). + + :param maxIdx: pointer to the returned maximum location (in nD case). ``NULL`` is used if not required. + + The function ``minMaxIdx`` finds the minimum and maximum element values and their positions. The extremums are searched across the whole array or, if ``mask`` is not an empty array, in the specified array region. + + The function does not work with multi-channel arrays. If you need to find minimum or maximum elements across all the channels, use + :ocv:func:`Mat::reshape` first to reinterpret the array as single-channel. Or you may extract the particular channel using either + :ocv:func:`extractImageCOI` , or + :ocv:func:`mixChannels` , or + :ocv:func:`split` . + + In case of a sparse matrix, the minimum is found among non-zero elements only. + + + +minMaxLoc +--------- +Finds the global minimum and maximum in an array. + +.. ocv:function:: void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) + +.. ocv:function:: void minMaxLoc( const SparseMat& a, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0 ) + +.. ocv:pyfunction:: cv2.minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc + +.. ocv:cfunction:: void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.MinMaxLoc(arr, mask=None)-> (minVal, maxVal, minLoc, maxLoc) + + :param src: input single-channel array. + + :param minVal: pointer to the returned minimum value; ``NULL`` is used if not required. + + :param maxVal: pointer to the returned maximum value; ``NULL`` is used if not required. + + :param minLoc: pointer to the returned minimum location (in 2D case); ``NULL`` is used if not required. + + :param maxLoc: pointer to the returned maximum location (in 2D case); ``NULL`` is used if not required. + + :param mask: optional mask used to select a sub-array. + +The functions ``minMaxLoc`` find the minimum and maximum element values and their positions. The extremums are searched across the whole array or, +if ``mask`` is not an empty array, in the specified array region. + +The functions do not work with multi-channel arrays. If you need to find minimum or maximum elements across all the channels, use +:ocv:func:`Mat::reshape` first to reinterpret the array as single-channel. Or you may extract the particular channel using either +:ocv:func:`extractImageCOI` , or +:ocv:func:`mixChannels` , or +:ocv:func:`split` . + +.. seealso:: + + :ocv:func:`max`, + :ocv:func:`min`, + :ocv:func:`compare`, + :ocv:func:`inRange`, + :ocv:func:`extractImageCOI`, + :ocv:func:`mixChannels`, + :ocv:func:`split`, + :ocv:func:`Mat::reshape` + + + +mixChannels +----------- +Copies specified channels from input arrays to the specified channels of output arrays. + +.. ocv:function:: void mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs ) + +.. ocv:function:: void mixChannels( const vector& src, vector& dst, const int* fromTo, size_t npairs ) + +.. ocv:pyfunction:: cv2.mixChannels(src, dst, fromTo) -> None + +.. ocv:cfunction:: void cvMixChannels( const CvArr** src, int src_count, CvArr** dst, int dst_count, const int* from_to, int pair_count ) + +.. ocv:pyoldfunction:: cv.MixChannels(src, dst, fromTo) -> None + + :param src: input array or vector of matricesl; all of the matrices must have the same size and the same depth. + + :param nsrcs: number of matrices in ``src``. + + :param dst: output array or vector of matrices; all the matrices *must be allocated*; their size and depth must be the same as in ``src[0]``. + + :param ndsts: number of matrices in ``dst``. + + :param fromTo: array of index pairs specifying which channels are copied and where; ``fromTo[k*2]`` is a 0-based index of the input channel in ``src``, ``fromTo[k*2+1]`` is an index of the output channel in ``dst``; the continuous channel numbering is used: the first input image channels are indexed from ``0`` to ``src[0].channels()-1``, the second input image channels are indexed from ``src[0].channels()`` to ``src[0].channels() + src[1].channels()-1``, and so on, the same scheme is used for the output image channels; as a special case, when ``fromTo[k*2]`` is negative, the corresponding output channel is filled with zero . + + :param npairs: number of index pairs in ``fromTo``. + +The functions ``mixChannels`` provide an advanced mechanism for shuffling image channels. + +:ocv:func:`split` and +:ocv:func:`merge` and some forms of +:ocv:func:`cvtColor` are partial cases of ``mixChannels`` . + +In the example below, the code splits a 4-channel RGBA image into a 3-channel BGR (with R and B channels swapped) and a separate alpha-channel image: :: + + Mat rgba( 100, 100, CV_8UC4, Scalar(1,2,3,4) ); + Mat bgr( rgba.rows, rgba.cols, CV_8UC3 ); + Mat alpha( rgba.rows, rgba.cols, CV_8UC1 ); + + // forming an array of matrices is a quite efficient operation, + // because the matrix data is not copied, only the headers + Mat out[] = { bgr, alpha }; + // rgba[0] -> bgr[2], rgba[1] -> bgr[1], + // rgba[2] -> bgr[0], rgba[3] -> alpha[0] + int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; + mixChannels( &rgba, 1, out, 2, from_to, 4 ); + + +.. note:: Unlike many other new-style C++ functions in OpenCV (see the introduction section and :ocv:func:`Mat::create` ), ``mixChannels`` requires the output arrays to be pre-allocated before calling the function. + +.. seealso:: + + :ocv:func:`split`, + :ocv:func:`merge`, + :ocv:func:`cvtColor` + + + +mulSpectrums +------------ +Performs the per-element multiplication of two Fourier spectrums. + +.. ocv:function:: void mulSpectrums( InputArray a, InputArray b, OutputArray c, int flags, bool conjB=false ) + +.. ocv:pyfunction:: cv2.mulSpectrums(a, b, flags[, c[, conjB]]) -> c + +.. ocv:cfunction:: void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags) +.. ocv:pyoldfunction:: cv.MulSpectrums(src1, src2, dst, flags)-> None + + :param src1: first input array. + + :param src2: second input array of the same size and type as ``src1`` . + + :param dst: output array of the same size and type as ``src1`` . + + :param flags: operation flags; currently, the only supported flag is ``DFT_ROWS``, which indicates that each row of ``src1`` and ``src2`` is an independent 1D Fourier spectrum. + + :param conjB: optional flag that conjugates the second input array before the multiplication (true) or not (false). + +The function ``mulSpectrums`` performs the per-element multiplication of the two CCS-packed or complex matrices that are results of a real or complex Fourier transform. + +The function, together with +:ocv:func:`dft` and +:ocv:func:`idft` , may be used to calculate convolution (pass ``conjB=false`` ) or correlation (pass ``conjB=true`` ) of two arrays rapidly. When the arrays are complex, they are simply multiplied (per element) with an optional conjugation of the second-array elements. When the arrays are real, they are assumed to be CCS-packed (see +:ocv:func:`dft` for details). + + + +multiply +-------- +Calculates the per-element scaled product of two arrays. + +.. ocv:function:: void multiply( InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1 ) + +.. ocv:pyfunction:: cv2.multiply(src1, src2[, dst[, scale[, dtype]]]) -> dst + +.. ocv:cfunction:: void cvMul(const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1) +.. ocv:pyoldfunction:: cv.Mul(src1, src2, dst, scale=1) -> None + + :param src1: first input array. + + :param src2: second input array of the same size and the same type as ``src1``. + + :param dst: output array of the same size and type as ``src1``. + + :param scale: optional scale factor. + +The function ``multiply`` calculates the per-element product of two arrays: + +.. math:: + + \texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I)) + +There is also a +:ref:`MatrixExpressions` -friendly variant of the first function. See +:ocv:func:`Mat::mul` . + +For a not-per-element matrix product, see +:ocv:func:`gemm` . + +.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow. + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`subtract`, + :ocv:func:`divide`, + :ref:`MatrixExpressions`, + :ocv:func:`scaleAdd`, + :ocv:func:`addWeighted`, + :ocv:func:`accumulate`, + :ocv:func:`accumulateProduct`, + :ocv:func:`accumulateSquare`, + :ocv:func:`Mat::convertTo` + + + +mulTransposed +------------- +Calculates the product of a matrix and its transposition. + +.. ocv:function:: void mulTransposed( InputArray src, OutputArray dst, bool aTa, InputArray delta=noArray(), double scale=1, int dtype=-1 ) + +.. ocv:pyfunction:: cv2.mulTransposed(src, aTa[, dst[, delta[, scale[, dtype]]]]) -> dst + +.. ocv:cfunction:: void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL, double scale=1. ) + +.. ocv:pyoldfunction:: cv.MulTransposed(src, dst, order, delta=None, scale=1.0) -> None + + :param src: input single-channel matrix. Note that unlike :ocv:func:`gemm`, the function can multiply not only floating-point matrices. + + :param dst: output square matrix. + + :param aTa: Flag specifying the multiplication ordering. See the description below. + + :param delta: Optional delta matrix subtracted from ``src`` before the multiplication. When the matrix is empty ( ``delta=noArray()`` ), it is assumed to be zero, that is, nothing is subtracted. If it has the same size as ``src`` , it is simply subtracted. Otherwise, it is "repeated" (see :ocv:func:`repeat` ) to cover the full ``src`` and then subtracted. Type of the delta matrix, when it is not empty, must be the same as the type of created output matrix. See the ``dtype`` parameter description below. + + :param scale: Optional scale factor for the matrix product. + + :param dtype: Optional type of the output matrix. When it is negative, the output matrix will have the same type as ``src`` . Otherwise, it will be ``type=CV_MAT_DEPTH(dtype)`` that should be either ``CV_32F`` or ``CV_64F`` . + +The function ``mulTransposed`` calculates the product of ``src`` and its transposition: + +.. math:: + + \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} ) + +if ``aTa=true`` , and + +.. math:: + + \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T + +otherwise. The function is used to calculate the covariance matrix. With zero delta, it can be used as a faster substitute for general matrix product ``A*B`` when ``B=A'`` + +.. seealso:: + + :ocv:func:`calcCovarMatrix`, + :ocv:func:`gemm`, + :ocv:func:`repeat`, + :ocv:func:`reduce` + + + +norm +---- +Calculates an absolute array norm, an absolute difference norm, or a relative difference norm. + +.. ocv:function:: double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray()) + +.. ocv:function:: double norm( InputArray src1, InputArray src2, int normType=NORM_L2, InputArray mask=noArray() ) + +.. ocv:function:: double norm( const SparseMat& src, int normType ) + +.. ocv:pyfunction:: cv2.norm(src1[, normType[, mask]]) -> retval +.. ocv:pyfunction:: cv2.norm(src1, src2[, normType[, mask]]) -> retval + +.. ocv:cfunction:: double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.Norm(arr1, arr2, normType=CV_L2, mask=None) -> float + + :param src1: first input array. + + :param src2: second input array of the same size and the same type as ``src1``. + + :param normType: type of the norm (see the details below). + + :param mask: optional operation mask; it must have the same size as ``src1`` and ``CV_8UC1`` type. + +The functions ``norm`` calculate an absolute norm of ``src1`` (when there is no ``src2`` ): + +.. math:: + + norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if $\texttt{normType} = \texttt{NORM\_INF}$ } + { \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if $\texttt{normType} = \texttt{NORM\_L1}$ } + { \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if $\texttt{normType} = \texttt{NORM\_L2}$ } + +or an absolute or relative difference norm if ``src2`` is there: + +.. math:: + + norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if $\texttt{normType} = \texttt{NORM\_INF}$ } + { \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if $\texttt{normType} = \texttt{NORM\_L1}$ } + { \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if $\texttt{normType} = \texttt{NORM\_L2}$ } + +or + +.. math:: + + norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if $\texttt{normType} = \texttt{NORM\_RELATIVE\_INF}$ } + { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if $\texttt{normType} = \texttt{NORM\_RELATIVE\_L1}$ } + { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if $\texttt{normType} = \texttt{NORM\_RELATIVE\_L2}$ } + +The functions ``norm`` return the calculated norm. + +When the ``mask`` parameter is specified and it is not empty, the norm is calculated only over the region specified by the mask. + +A multi-channel input arrays are treated as a single-channel, that is, the results for all channels are combined. + + + +normalize +--------- +Normalizes the norm or value range of an array. + +.. ocv:function:: void normalize( InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() ) + +.. ocv:function:: void normalize(const SparseMat& src, SparseMat& dst, double alpha, int normType) + +.. ocv:pyfunction:: cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) -> dst + + :param src: input array. + + :param dst: output array of the same size as ``src`` . + + :param alpha: norm value to normalize to or the lower range boundary in case of the range normalization. + + :param beta: upper range boundary in case of the range normalization; it is not used for the norm normalization. + + :param normType: normalization type (see the details below). + + :param dtype: when negative, the output array has the same type as ``src``; otherwise, it has the same number of channels as ``src`` and the depth ``=CV_MAT_DEPTH(dtype)``. + + :param mask: optional operation mask. + + +The functions ``normalize`` scale and shift the input array elements so that + +.. math:: + + \| \texttt{dst} \| _{L_p}= \texttt{alpha} + +(where p=Inf, 1 or 2) when ``normType=NORM_INF``, ``NORM_L1``, or ``NORM_L2``, respectively; or so that + +.. math:: + + \min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta} + +when ``normType=NORM_MINMAX`` (for dense arrays only). +The optional mask specifies a sub-array to be normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or min-max but modify the whole array, you can use +:ocv:func:`norm` and +:ocv:func:`Mat::convertTo`. + +In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this, the range transformation for sparse matrices is not allowed since it can shift the zero level. + +.. seealso:: + + :ocv:func:`norm`, + :ocv:func:`Mat::convertTo`, + :ocv:func:`SparseMat::convertTo` + + + +PCA +--- +.. ocv:class:: PCA + +Principal Component Analysis class. + +The class is used to calculate a special basis for a set of vectors. The basis will consist of eigenvectors of the covariance matrix calculated from the input set of vectors. The class ``PCA`` can also transform vectors to/from the new coordinate space defined by the basis. Usually, in this new coordinate system, each vector from the original set (and any linear combination of such vectors) can be quite accurately approximated by taking its first few components, corresponding to the eigenvectors of the largest eigenvalues of the covariance matrix. Geometrically it means that you calculate a projection of the vector to a subspace formed by a few eigenvectors corresponding to the dominant eigenvalues of the covariance matrix. And usually such a projection is very close to the original vector. So, you can represent the original vector from a high-dimensional space with a much shorter vector consisting of the projected vector's coordinates in the subspace. Such a transformation is also known as Karhunen-Loeve Transform, or KLT. See +http://en.wikipedia.org/wiki/Principal\_component\_analysis . + +The sample below is the function that takes two matrices. The first function stores a set of vectors (a row per vector) that is used to calculate PCA. The second function stores another "test" set of vectors (a row per vector). First, these vectors are compressed with PCA, then reconstructed back, and then the reconstruction error norm is computed and printed for each vector. :: + + PCA compressPCA(InputArray pcaset, int maxComponents, + const Mat& testset, OutputArray compressed) + { + PCA pca(pcaset, // pass the data + Mat(), // there is no pre-computed mean vector, + // so let the PCA engine to compute it + CV_PCA_DATA_AS_ROW, // indicate that the vectors + // are stored as matrix rows + // (use CV_PCA_DATA_AS_COL if the vectors are + // the matrix columns) + maxComponents // specify how many principal components to retain + ); + // if there is no test data, just return the computed basis, ready-to-use + if( !testset.data ) + return pca; + CV_Assert( testset.cols == pcaset.cols ); + + compressed.create(testset.rows, maxComponents, testset.type()); + + Mat reconstructed; + for( int i = 0; i < testset.rows; i++ ) + { + Mat vec = testset.row(i), coeffs = compressed.row(i); + // compress the vector, the result will be stored + // in the i-th row of the output matrix + pca.project(vec, coeffs); + // and then reconstruct it + pca.backProject(coeffs, reconstructed); + // and measure the error + printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2)); + } + return pca; + } + + +.. seealso:: + + :ocv:func:`calcCovarMatrix`, + :ocv:func:`mulTransposed`, + :ocv:class:`SVD`, + :ocv:func:`dft`, + :ocv:func:`dct` + + + +PCA::PCA +-------- +PCA constructors + +.. ocv:function:: PCA::PCA() + +.. ocv:function:: PCA::PCA(InputArray data, InputArray mean, int flags, int maxComponents=0) + +.. ocv:function:: PCA::PCA(InputArray data, InputArray mean, int flags, double retainedVariance) + + :param data: input samples stored as matrix rows or matrix columns. + + :param mean: optional mean value; if the matrix is empty (``noArray()``), the mean is computed from the data. + + :param flags: operation flags; currently the parameter is only used to specify the data layout: + + * **CV_PCA_DATA_AS_ROW** indicates that the input samples are stored as matrix rows. + + * **CV_PCA_DATA_AS_COL** indicates that the input samples are stored as matrix columns. + + :param maxComponents: maximum number of components that PCA should retain; by default, all the components are retained. + + :param retainedVariance: Percentage of variance that PCA should retain. Using this parameter will let the PCA decided how many components to retain but it will always keep at least 2. + +The default constructor initializes an empty PCA structure. The other constructors initialize the structure and call +:ocv:funcx:`PCA::operator()` . + + + +PCA::operator () +---------------- +Performs Principal Component Analysis of the supplied dataset. + +.. ocv:function:: PCA& PCA::operator()(InputArray data, InputArray mean, int flags, int maxComponents=0) + +.. ocv:function:: PCA& PCA::computeVar(InputArray data, InputArray mean, int flags, double retainedVariance) + +.. ocv:pyfunction:: cv2.PCACompute(data[, mean[, eigenvectors[, maxComponents]]]) -> mean, eigenvectors + +.. ocv:pyfunction:: cv2.PCAComputeVar(data, retainedVariance[, mean[, eigenvectors]]) -> mean, eigenvectors + + :param data: input samples stored as the matrix rows or as the matrix columns. + + :param mean: optional mean value; if the matrix is empty (``noArray()``), the mean is computed from the data. + + :param flags: operation flags; currently the parameter is only used to specify the data layout. + + * **CV_PCA_DATA_AS_ROW** indicates that the input samples are stored as matrix rows. + + * **CV_PCA_DATA_AS_COL** indicates that the input samples are stored as matrix columns. + + :param maxComponents: maximum number of components that PCA should retain; by default, all the components are retained. + + :param retainedVariance: Percentage of variance that PCA should retain. Using this parameter will let the PCA decided how many components to retain but it will always keep at least 2. + +The operator performs PCA of the supplied dataset. It is safe to reuse the same PCA structure for multiple datasets. That is, if the structure has been previously used with another dataset, the existing internal data is reclaimed and the new ``eigenvalues``, ``eigenvectors`` , and ``mean`` are allocated and computed. + +The computed eigenvalues are sorted from the largest to the smallest and the corresponding eigenvectors are stored as ``PCA::eigenvectors`` rows. + + + +PCA::project +------------ +Projects vector(s) to the principal component subspace. + +.. ocv:function:: Mat PCA::project(InputArray vec) const + +.. ocv:function:: void PCA::project(InputArray vec, OutputArray result) const + +.. ocv:pyfunction:: cv2.PCAProject(data, mean, eigenvectors[, result]) -> result + + :param vec: input vector(s); must have the same dimensionality and the same layout as the input data used at PCA phase, that is, if ``CV_PCA_DATA_AS_ROW`` are specified, then ``vec.cols==data.cols`` (vector dimensionality) and ``vec.rows`` is the number of vectors to project, and the same is true for the ``CV_PCA_DATA_AS_COL`` case. + + :param result: output vectors; in case of ``CV_PCA_DATA_AS_COL``, the output matrix has as many columns as the number of input vectors, this means that ``result.cols==vec.cols`` and the number of rows match the number of principal components (for example, ``maxComponents`` parameter passed to the constructor). + +The methods project one or more vectors to the principal component subspace, where each vector projection is represented by coefficients in the principal component basis. The first form of the method returns the matrix that the second form writes to the result. So the first form can be used as a part of expression while the second form can be more efficient in a processing loop. + + + +PCA::backProject +---------------- +Reconstructs vectors from their PC projections. + +.. ocv:function:: Mat PCA::backProject(InputArray vec) const + +.. ocv:function:: void PCA::backProject(InputArray vec, OutputArray result) const + +.. ocv:pyfunction:: cv2.PCABackProject(data, mean, eigenvectors[, result]) -> result + + :param vec: coordinates of the vectors in the principal component subspace, the layout and size are the same as of ``PCA::project`` output vectors. + + :param result: reconstructed vectors; the layout and size are the same as of ``PCA::project`` input vectors. + +The methods are inverse operations to +:ocv:func:`PCA::project`. They take PC coordinates of projected vectors and reconstruct the original vectors. Unless all the principal components have been retained, the reconstructed vectors are different from the originals. But typically, the difference is small if the number of components is large enough (but still much smaller than the original vector dimensionality). As a result, PCA is used. + + + +perspectiveTransform +-------------------- +Performs the perspective matrix transformation of vectors. + +.. ocv:function:: void perspectiveTransform( InputArray src, OutputArray dst, InputArray m ) + +.. ocv:pyfunction:: cv2.perspectiveTransform(src, m[, dst]) -> dst + +.. ocv:cfunction:: void cvPerspectiveTransform(const CvArr* src, CvArr* dst, const CvMat* mat) +.. ocv:pyoldfunction:: cv.PerspectiveTransform(src, dst, mat)-> None + + :param src: input two-channel or three-channel floating-point array; each element is a 2D/3D vector to be transformed. + + :param dst: output array of the same size and type as ``src``. + + :param m: ``3x3`` or ``4x4`` floating-point transformation matrix. + +The function ``perspectiveTransform`` transforms every element of ``src`` by treating it as a 2D or 3D vector, in the following way: + +.. math:: + + (x, y, z) \rightarrow (x'/w, y'/w, z'/w) + +where + +.. math:: + + (x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix} + +and + +.. math:: + + w = \fork{w'}{if $w' \ne 0$}{\infty}{otherwise} + +Here a 3D vector transformation is shown. In case of a 2D vector transformation, the ``z`` component is omitted. + +.. note:: The function transforms a sparse set of 2D or 3D vectors. If you want to transform an image using perspective transformation, use :ocv:func:`warpPerspective` . If you have an inverse problem, that is, you want to compute the most probable perspective transformation out of several pairs of corresponding points, you can use :ocv:func:`getPerspectiveTransform` or :ocv:func:`findHomography` . + +.. seealso:: + + :ocv:func:`transform`, + :ocv:func:`warpPerspective`, + :ocv:func:`getPerspectiveTransform`, + :ocv:func:`findHomography` + + + +phase +----- +Calculates the rotation angle of 2D vectors. + +.. ocv:function:: void phase(InputArray x, InputArray y, OutputArray angle, bool angleInDegrees=false) + +.. ocv:pyfunction:: cv2.phase(x, y[, angle[, angleInDegrees]]) -> angle + + :param x: input floating-point array of x-coordinates of 2D vectors. + + :param y: input array of y-coordinates of 2D vectors; it must have the same size and the same type as ``x``. + + :param angle: output array of vector angles; it has the same size and same type as ``x`` . + + :param angleInDegrees: when true, the function calculates the angle in degrees, otherwise, they are measured in radians. + +The function ``phase`` calculates the rotation angle of each 2D vector that is formed from the corresponding elements of ``x`` and ``y`` : + +.. math:: + + \texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I)) + +The angle estimation accuracy is about 0.3 degrees. When ``x(I)=y(I)=0`` , the corresponding ``angle(I)`` is set to 0. + + +polarToCart +----------- +Calculates x and y coordinates of 2D vectors from their magnitude and angle. + +.. ocv:function:: void polarToCart(InputArray magnitude, InputArray angle, OutputArray x, OutputArray y, bool angleInDegrees=false) + +.. ocv:pyfunction:: cv2.polarToCart(magnitude, angle[, x[, y[, angleInDegrees]]]) -> x, y + +.. ocv:cfunction:: void cvPolarToCart( const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angle_in_degrees=0 ) + +.. ocv:pyoldfunction:: cv.PolarToCart(magnitude, angle, x, y, angleInDegrees=0)-> None + + :param magnitude: input floating-point array of magnitudes of 2D vectors; it can be an empty matrix (``=Mat()``), in this case, the function assumes that all the magnitudes are =1; if it is not empty, it must have the same size and type as ``angle``. + + :param angle: input floating-point array of angles of 2D vectors. + + :param x: output array of x-coordinates of 2D vectors; it has the same size and type as ``angle``. + + :param y: output array of y-coordinates of 2D vectors; it has the same size and type as ``angle``. + + :param angleInDegrees: when true, the input angles are measured in degrees, otherwise, they are measured in radians. + +The function ``polarToCart`` calculates the Cartesian coordinates of each 2D vector represented by the corresponding elements of ``magnitude`` and ``angle`` : + +.. math:: + + \begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array} + +The relative accuracy of the estimated coordinates is about ``1e-6``. + +.. seealso:: + + :ocv:func:`cartToPolar`, + :ocv:func:`magnitude`, + :ocv:func:`phase`, + :ocv:func:`exp`, + :ocv:func:`log`, + :ocv:func:`pow`, + :ocv:func:`sqrt` + + + +pow +--- +Raises every array element to a power. + +.. ocv:function:: void pow( InputArray src, double power, OutputArray dst ) + +.. ocv:pyfunction:: cv2.pow(src, power[, dst]) -> dst + +.. ocv:cfunction:: void cvPow( const CvArr* src, CvArr* dst, double power) +.. ocv:pyoldfunction:: cv.Pow(src, dst, power)-> None + + :param src: input array. + + :param power: exponent of power. + + :param dst: output array of the same size and type as ``src``. + +The function ``pow`` raises every element of the input array to ``power`` : + +.. math:: + + \texttt{dst} (I) = \fork{\texttt{src}(I)^power}{if \texttt{power} is integer}{|\texttt{src}(I)|^power}{otherwise} + +So, for a non-integer power exponent, the absolute values of input array elements are used. However, it is possible to get true values for negative values using some extra operations. In the example below, computing the 5th root of array ``src`` shows: :: + + Mat mask = src < 0; + pow(src, 1./5, dst); + subtract(Scalar::all(0), dst, dst, mask); + + +For some values of ``power`` , such as integer values, 0.5 and -0.5, specialized faster algorithms are used. + +Special values (NaN, Inf) are not handled. + +.. seealso:: + + :ocv:func:`sqrt`, + :ocv:func:`exp`, + :ocv:func:`log`, + :ocv:func:`cartToPolar`, + :ocv:func:`polarToCart` + + + +RNG +--- + +.. ocv:class:: RNG + +Random number generator. It encapsulates the state (currently, a 64-bit integer) and has methods to return scalar random values and to fill arrays with random values. Currently it supports uniform and Gaussian (normal) distributions. The generator uses Multiply-With-Carry algorithm, introduced by G. Marsaglia ( +http://en.wikipedia.org/wiki/Multiply-with-carry +). Gaussian-distribution random numbers are generated using the Ziggurat algorithm ( +http://en.wikipedia.org/wiki/Ziggurat_algorithm +), introduced by G. Marsaglia and W. W. Tsang. + + + +RNG::RNG +-------- +The constructors + +.. ocv:function:: RNG::RNG() + +.. ocv:function:: RNG::RNG(uint64 state) + + :param state: 64-bit value used to initialize the RNG. + +These are the RNG constructors. The first form sets the state to some pre-defined value, equal to ``2**32-1`` in the current implementation. The second form sets the state to the specified value. If you passed ``state=0`` , the constructor uses the above default value instead to avoid the singular random number sequence, consisting of all zeros. + + + +RNG::next +--------- +Returns the next random number. + +.. ocv:function:: unsigned RNG::next() + +The method updates the state using the MWC algorithm and returns the next 32-bit random number. + + + +RNG::operator T +--------------- +Returns the next random number of the specified type. + +.. ocv:function:: RNG::operator uchar() + +.. ocv:function:: RNG::operator schar() + +.. ocv:function:: RNG::operator ushort() + +.. ocv:function:: RNG::operator short() + +.. ocv:function:: RNG::operator int() + +.. ocv:function:: RNG::operator unsigned() + +.. ocv:function:: RNG::operator float() + +.. ocv:function:: RNG::operator double() + +Each of the methods updates the state using the MWC algorithm and returns the next random number of the specified type. In case of integer types, the returned number is from the available value range for the specified type. In case of floating-point types, the returned value is from ``[0,1)`` range. + + + +RNG::operator () +---------------- +Returns the next random number. + +.. ocv:function:: unsigned RNG::operator ()() + +.. ocv:function:: unsigned RNG::operator ()(unsigned N) + + :param N: upper non-inclusive boundary of the returned random number. + +The methods transform the state using the MWC algorithm and return the next random number. The first form is equivalent to +:ocv:func:`RNG::next` . The second form returns the random number modulo ``N`` , which means that the result is in the range ``[0, N)`` . + + + +RNG::uniform +------------ +Returns the next random number sampled from the uniform distribution. + +.. ocv:function:: int RNG::uniform(int a, int b) + +.. ocv:function:: float RNG::uniform(float a, float b) + +.. ocv:function:: double RNG::uniform(double a, double b) + + :param a: lower inclusive boundary of the returned random numbers. + + :param b: upper non-inclusive boundary of the returned random numbers. + +The methods transform the state using the MWC algorithm and return the next uniformly-distributed random number of the specified type, deduced from the input parameter type, from the range ``[a, b)`` . There is a nuance illustrated by the following sample: :: + + RNG rng; + + // always produces 0 + double a = rng.uniform(0, 1); + + // produces double from [0, 1) + double a1 = rng.uniform((double)0, (double)1); + + // produces float from [0, 1) + double b = rng.uniform(0.f, 1.f); + + // produces double from [0, 1) + double c = rng.uniform(0., 1.); + + // may cause compiler error because of ambiguity: + // RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)? + double d = rng.uniform(0, 0.999999); + + +The compiler does not take into account the type of the variable to which you assign the result of ``RNG::uniform`` . The only thing that matters to the compiler is the type of ``a`` and ``b`` parameters. So, if you want a floating-point random number, but the range boundaries are integer numbers, either put dots in the end, if they are constants, or use explicit type cast operators, as in the ``a1`` initialization above. + + + +RNG::gaussian +------------- +Returns the next random number sampled from the Gaussian distribution. + +.. ocv:function:: double RNG::gaussian(double sigma) + + :param sigma: standard deviation of the distribution. + +The method transforms the state using the MWC algorithm and returns the next random number from the Gaussian distribution ``N(0,sigma)`` . That is, the mean value of the returned random numbers is zero and the standard deviation is the specified ``sigma`` . + + + +RNG::fill +--------- +Fills arrays with random numbers. + +.. ocv:function:: void RNG::fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false ) + + :param mat: 2D or N-dimensional matrix; currently matrices with more than 4 channels are not supported by the methods, use :ocv:func:`Mat::reshape` as a possible workaround. + + :param distType: distribution type, ``RNG::UNIFORM`` or ``RNG::NORMAL``. + + :param a: first distribution parameter; in case of the uniform distribution, this is an inclusive lower boundary, in case of the normal distribution, this is a mean value. + + :param b: second distribution parameter; in case of the uniform distribution, this is a non-inclusive upper boundary, in case of the normal distribution, this is a standard deviation (diagonal of the standard deviation matrix or the full standard deviation matrix). + + :param saturateRange: pre-saturation flag; for uniform distribution only; if true, the method will first convert a and b to the acceptable value range (according to the mat datatype) and then will generate uniformly distributed random numbers within the range ``[saturate(a), saturate(b))``, if ``saturateRange=false``, the method will generate uniformly distributed random numbers in the original range ``[a, b)`` and then will saturate them, it means, for example, that ``theRNG().fill(mat_8u, RNG::UNIFORM, -DBL_MAX, DBL_MAX)`` will likely produce array mostly filled with 0's and 255's, since the range ``(0, 255)`` is significantly smaller than ``[-DBL_MAX, DBL_MAX)``. + +Each of the methods fills the matrix with the random values from the specified distribution. As the new numbers are generated, the RNG state is updated accordingly. In case of multiple-channel images, every channel is filled independently, which means that RNG cannot generate samples from the multi-dimensional Gaussian distribution with non-diagonal covariance matrix directly. To do that, the method generates samples from multi-dimensional standard Gaussian distribution with zero mean and identity covariation matrix, and then transforms them using :ocv:func:`transform` to get samples from the specified Gaussian distribution. + +randu +----- +Generates a single uniformly-distributed random number or an array of random numbers. + +.. ocv:function:: template _Tp randu() + +.. ocv:function:: void randu( InputOutputArray dst, InputArray low, InputArray high ) + +.. ocv:pyfunction:: cv2.randu(dst, low, high) -> None + + :param dst: output array of random numbers; the array must be pre-allocated. + + :param low: inclusive lower boundary of the generated random numbers. + + :param high: exclusive upper boundary of the generated random numbers. + +The template functions ``randu`` generate and return the next uniformly-distributed random value of the specified type. ``randu()`` is an equivalent to ``(int)theRNG();`` , and so on. See +:ocv:class:`RNG` description. + +The second non-template variant of the function fills the matrix ``dst`` with uniformly-distributed random numbers from the specified range: + +.. math:: + + \texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c + +.. seealso:: + + :ocv:class:`RNG`, + :ocv:func:`randn`, + :ocv:func:`theRNG` + + + +randn +----- +Fills the array with normally distributed random numbers. + +.. ocv:function:: void randn( InputOutputArray dst, InputArray mean, InputArray stddev ) + +.. ocv:pyfunction:: cv2.randn(dst, mean, stddev) -> None + + :param dst: output array of random numbers; the array must be pre-allocated and have 1 to 4 channels. + + :param mean: mean value (expectation) of the generated random numbers. + + :param stddev: standard deviation of the generated random numbers; it can be either a vector (in which case a diagonal standard deviation matrix is assumed) or a square matrix. + +The function ``randn`` fills the matrix ``dst`` with normally distributed random numbers with the specified mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the value range of the output array data type. + +.. seealso:: + + :ocv:class:`RNG`, + :ocv:func:`randu` + + + +randShuffle +----------- +Shuffles the array elements randomly. + +.. ocv:function:: void randShuffle( InputOutputArray dst, double iterFactor=1., RNG* rng=0 ) + +.. ocv:pyfunction:: cv2.randShuffle(dst[, iterFactor]) -> None + + :param dst: input/output numerical 1D array. + + :param iterFactor: scale factor that determines the number of random swap operations (see the details below). + + :param rng: optional random number generator used for shuffling; if it is zero, :ocv:func:`theRNG` () is used instead. + +The function ``randShuffle`` shuffles the specified 1D array by randomly choosing pairs of elements and swapping them. The number of such swap operations will be ``dst.rows*dst.cols*iterFactor`` . + +.. seealso:: + + :ocv:class:`RNG`, + :ocv:func:`sort` + + + +reduce +------ +Reduces a matrix to a vector. + +.. ocv:function:: void reduce( InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1 ) + +.. ocv:pyfunction:: cv2.reduce(src, dim, rtype[, dst[, dtype]]) -> dst + +.. ocv:cfunction:: void cvReduce(const CvArr* src, CvArr* dst, int dim=-1, int op=CV_REDUCE_SUM) +.. ocv:pyoldfunction:: cv.Reduce(src, dst, dim=-1, op=CV_REDUCE_SUM)-> None + + :param src: input 2D matrix. + + :param dst: output vector. Its size and type is defined by ``dim`` and ``dtype`` parameters. + + :param dim: dimension index along which the matrix is reduced. 0 means that the matrix is reduced to a single row. 1 means that the matrix is reduced to a single column. + + :param rtype: reduction operation that could be one of the following: + + * **CV_REDUCE_SUM**: the output is the sum of all rows/columns of the matrix. + + * **CV_REDUCE_AVG**: the output is the mean vector of all rows/columns of the matrix. + + * **CV_REDUCE_MAX**: the output is the maximum (column/row-wise) of all rows/columns of the matrix. + + * **CV_REDUCE_MIN**: the output is the minimum (column/row-wise) of all rows/columns of the matrix. + + :param dtype: when negative, the output vector will have the same type as the input matrix, otherwise, its type will be ``CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels())``. + +The function ``reduce`` reduces the matrix to a vector by treating the matrix rows/columns as a set of 1D vectors and performing the specified operation on the vectors until a single row/column is obtained. For example, the function can be used to compute horizontal and vertical projections of a raster image. In case of ``CV_REDUCE_SUM`` and ``CV_REDUCE_AVG`` , the output may have a larger element bit-depth to preserve accuracy. And multi-channel arrays are also supported in these two reduction modes. + +.. seealso:: :ocv:func:`repeat` + + + +repeat +------ +Fills the output array with repeated copies of the input array. + +.. ocv:function:: void repeat(InputArray src, int ny, int nx, OutputArray dst) + +.. ocv:function:: Mat repeat( const Mat& src, int ny, int nx ) + +.. ocv:pyfunction:: cv2.repeat(src, ny, nx[, dst]) -> dst + +.. ocv:cfunction:: void cvRepeat(const CvArr* src, CvArr* dst) + +.. ocv:pyoldfunction:: cv.Repeat(src, dst)-> None + + :param src: input array to replicate. + + :param dst: output array of the same type as ``src``. + + :param ny: Flag to specify how many times the ``src`` is repeated along the vertical axis. + + :param nx: Flag to specify how many times the ``src`` is repeated along the horizontal axis. + +The functions +:ocv:func:`repeat` duplicate the input array one or more times along each of the two axes: + +.. math:: + + \texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols } + +The second variant of the function is more convenient to use with +:ref:`MatrixExpressions` . + +.. seealso:: + + :ocv:func:`reduce`, + :ref:`MatrixExpressions` + + + +scaleAdd +-------- +Calculates the sum of a scaled array and another array. + +.. ocv:function:: void scaleAdd( InputArray src1, double alpha, InputArray src2, OutputArray dst ) + +.. ocv:pyfunction:: cv2.scaleAdd(src1, alpha, src2[, dst]) -> dst + +.. ocv:cfunction:: void cvScaleAdd(const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst) +.. ocv:pyoldfunction:: cv.ScaleAdd(src1, scale, src2, dst)-> None + + :param src1: first input array. + + :param scale: scale factor for the first array. + + :param src2: second input array of the same size and type as ``src1``. + + :param dst: output array of the same size and type as ``src1``. + +The function ``scaleAdd`` is one of the classical primitive linear algebra operations, known as ``DAXPY`` or ``SAXPY`` in `BLAS `_. It calculates the sum of a scaled array and another array: + +.. math:: + + \texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I) + +The function can also be emulated with a matrix expression, for example: :: + + Mat A(3, 3, CV_64F); + ... + A.row(0) = A.row(1)*2 + A.row(2); + + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`addWeighted`, + :ocv:func:`subtract`, + :ocv:func:`Mat::dot`, + :ocv:func:`Mat::convertTo`, + :ref:`MatrixExpressions` + + + +setIdentity +----------- +Initializes a scaled identity matrix. + +.. ocv:function:: void setIdentity( InputOutputArray mtx, const Scalar& s=Scalar(1) ) + +.. ocv:pyfunction:: cv2.setIdentity(mtx[, s]) -> None + +.. ocv:cfunction:: void cvSetIdentity(CvArr* mat, CvScalar value=cvRealScalar(1)) + +.. ocv:pyoldfunction:: cv.SetIdentity(mat, value=1)-> None + + :param mtx: matrix to initialize (not necessarily square). + + :param value: value to assign to diagonal elements. + +The function +:ocv:func:`setIdentity` initializes a scaled identity matrix: + +.. math:: + + \texttt{mtx} (i,j)= \fork{\texttt{value}}{ if $i=j$}{0}{otherwise} + +The function can also be emulated using the matrix initializers and the matrix expressions: :: + + Mat A = Mat::eye(4, 3, CV_32F)*5; + // A will be set to [[5, 0, 0], [0, 5, 0], [0, 0, 5], [0, 0, 0]] + + +.. seealso:: + + :ocv:func:`Mat::zeros`, + :ocv:func:`Mat::ones`, + :ref:`MatrixExpressions`, + :ocv:func:`Mat::setTo`, + :ocv:func:`Mat::operator=` + + + +solve +----- +Solves one or more linear systems or least-squares problems. + +.. ocv:function:: bool solve(InputArray src1, InputArray src2, OutputArray dst, int flags=DECOMP_LU) + +.. ocv:pyfunction:: cv2.solve(src1, src2[, dst[, flags]]) -> retval, dst + +.. ocv:cfunction:: int cvSolve(const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU) +.. ocv:pyoldfunction:: cv.Solve(A, B, X, method=CV_LU)-> None + + :param src1: input matrix on the left-hand side of the system. + + :param src2: input matrix on the right-hand side of the system. + + :param dst: output solution. + + :param flags: solution (matrix inversion) method. + + * **DECOMP_LU** Gaussian elimination with optimal pivot element chosen. + + * **DECOMP_CHOLESKY** Cholesky :math:`LL^T` factorization; the matrix ``src1`` must be symmetrical and positively defined. + + * **DECOMP_EIG** eigenvalue decomposition; the matrix ``src1`` must be symmetrical. + + * **DECOMP_SVD** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix ``src1`` can be singular. + + * **DECOMP_QR** QR factorization; the system can be over-defined and/or the matrix ``src1`` can be singular. + + * **DECOMP_NORMAL** while all the previous flags are mutually exclusive, this flag can be used together with any of the previous; it means that the normal equations :math:`\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}` are solved instead of the original system :math:`\texttt{src1}\cdot\texttt{dst}=\texttt{src2}` . + +The function ``solve`` solves a linear system or least-squares problem (the latter is possible with SVD or QR methods, or by specifying the flag ``DECOMP_NORMAL`` ): + +.. math:: + + \texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \| + +If ``DECOMP_LU`` or ``DECOMP_CHOLESKY`` method is used, the function returns 1 if ``src1`` (or +:math:`\texttt{src1}^T\texttt{src1}` ) is non-singular. Otherwise, it returns 0. In the latter case, ``dst`` is not valid. Other methods find a pseudo-solution in case of a singular left-hand side part. + +.. note:: If you want to find a unity-norm solution of an under-defined singular system :math:`\texttt{src1}\cdot\texttt{dst}=0` , the function ``solve`` will not do the work. Use :ocv:func:`SVD::solveZ` instead. + +.. seealso:: + + :ocv:func:`invert`, + :ocv:class:`SVD`, + :ocv:func:`eigen` + + + +solveCubic +---------- +Finds the real roots of a cubic equation. + +.. ocv:function:: int solveCubic( InputArray coeffs, OutputArray roots ) + +.. ocv:pyfunction:: cv2.solveCubic(coeffs[, roots]) -> retval, roots + +.. ocv:cfunction:: int cvSolveCubic( const CvMat* coeffs, CvMat* roots ) + +.. ocv:pyoldfunction:: cv.SolveCubic(coeffs, roots)-> None + + :param coeffs: equation coefficients, an array of 3 or 4 elements. + + :param roots: output array of real roots that has 1 or 3 elements. + +The function ``solveCubic`` finds the real roots of a cubic equation: + +* if ``coeffs`` is a 4-element vector: + +.. math:: + + \texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0 + +* if ``coeffs`` is a 3-element vector: + +.. math:: + + x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0 + +The roots are stored in the ``roots`` array. + + + +solvePoly +--------- +Finds the real or complex roots of a polynomial equation. + +.. ocv:function:: double solvePoly( InputArray coeffs, OutputArray roots, int maxIters=300 ) + +.. ocv:pyfunction:: cv2.solvePoly(coeffs[, roots[, maxIters]]) -> retval, roots + + :param coeffs: array of polynomial coefficients. + + :param roots: output (complex) array of roots. + + :param maxIters: maximum number of iterations the algorithm does. + +The function ``solvePoly`` finds real and complex roots of a polynomial equation: + +.. math:: + + \texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0 + + + +sort +---- +Sorts each row or each column of a matrix. + +.. ocv:function:: void sort(InputArray src, OutputArray dst, int flags) + +.. ocv:pyfunction:: cv2.sort(src, flags[, dst]) -> dst + + :param src: input single-channel array. + + :param dst: output array of the same size and type as ``src``. + + :param flags: operation flags, a combination of the following values: + + * **CV_SORT_EVERY_ROW** each matrix row is sorted independently. + + * **CV_SORT_EVERY_COLUMN** each matrix column is sorted independently; this flag and the previous one are mutually exclusive. + + * **CV_SORT_ASCENDING** each matrix row is sorted in the ascending order. + + * **CV_SORT_DESCENDING** each matrix row is sorted in the descending order; this flag and the previous one are also mutually exclusive. + +The function ``sort`` sorts each matrix row or each matrix column in ascending or descending order. So you should pass two operation flags to get desired behaviour. If you want to sort matrix rows or columns lexicographically, you can use STL ``std::sort`` generic function with the proper comparison predicate. + +.. seealso:: + + :ocv:func:`sortIdx`, + :ocv:func:`randShuffle` + + + +sortIdx +------- +Sorts each row or each column of a matrix. + +.. ocv:function:: void sortIdx(InputArray src, OutputArray dst, int flags) + +.. ocv:pyfunction:: cv2.sortIdx(src, flags[, dst]) -> dst + + :param src: input single-channel array. + + :param dst: output integer array of the same size as ``src``. + + :param flags: operation flags that could be a combination of the following values: + + * **CV_SORT_EVERY_ROW** each matrix row is sorted independently. + + * **CV_SORT_EVERY_COLUMN** each matrix column is sorted independently; this flag and the previous one are mutually exclusive. + + * **CV_SORT_ASCENDING** each matrix row is sorted in the ascending order. + + * **CV_SORT_DESCENDING** each matrix row is sorted in the descending order; his flag and the previous one are also mutually exclusive. + +The function ``sortIdx`` sorts each matrix row or each matrix column in the ascending or descending order. So you should pass two operation flags to get desired behaviour. Instead of reordering the elements themselves, it stores the indices of sorted elements in the output array. For example: :: + + Mat A = Mat::eye(3,3,CV_32F), B; + sortIdx(A, B, CV_SORT_EVERY_ROW + CV_SORT_ASCENDING); + // B will probably contain + // (because of equal elements in A some permutations are possible): + // [[1, 2, 0], [0, 2, 1], [0, 1, 2]] + + +.. seealso:: + + :ocv:func:`sort`, + :ocv:func:`randShuffle` + + + +split +----- +Divides a multi-channel array into several single-channel arrays. + +.. ocv:function:: void split( const Mat& src, Mat* mvbegin ) + +.. ocv:function:: void split( InputArray m, OutputArrayOfArrays mv ) + +.. ocv:pyfunction:: cv2.split(m[, mv]) -> mv + +.. ocv:cfunction:: void cvSplit(const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3) + +.. ocv:pyoldfunction:: cv.Split(src, dst0, dst1, dst2, dst3)-> None + + :param src: input multi-channel array. + + :param mv: output array or vector of arrays; in the first variant of the function the number of arrays must match ``src.channels()``; the arrays themselves are reallocated, if needed. + +The functions ``split`` split a multi-channel array into separate single-channel arrays: + +.. math:: + + \texttt{mv} [c](I) = \texttt{src} (I)_c + +If you need to extract a single channel or do some other sophisticated channel permutation, use +:ocv:func:`mixChannels` . + +.. seealso:: + + :ocv:func:`merge`, + :ocv:func:`mixChannels`, + :ocv:func:`cvtColor` + + + +sqrt +---- +Calculates a square root of array elements. + +.. ocv:function:: void sqrt(InputArray src, OutputArray dst) + +.. ocv:pyfunction:: cv2.sqrt(src[, dst]) -> dst + +.. ocv:cfunction:: float cvSqrt(float value) +.. ocv:pyoldfunction:: cv.Sqrt(value)-> float + + :param src: input floating-point array. + + :param dst: output array of the same size and type as ``src``. + +The functions ``sqrt`` calculate a square root of each input array element. In case of multi-channel arrays, each channel is processed independently. The accuracy is approximately the same as of the built-in ``std::sqrt`` . + +.. seealso:: + + :ocv:func:`pow`, + :ocv:func:`magnitude` + + + +subtract +-------- +Calculates the per-element difference between two arrays or array and a scalar. + +.. ocv:function:: void subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1) + +.. ocv:pyfunction:: cv2.subtract(src1, src2[, dst[, mask[, dtype]]]) -> dst + +.. ocv:cfunction:: void cvSub(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) +.. ocv:cfunction:: void cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL ) +.. ocv:cfunction:: void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.Sub(src1, src2, dst, mask=None) -> None +.. ocv:pyoldfunction:: cv.SubRS(src, value, dst, mask=None) -> None +.. ocv:pyoldfunction:: cv.SubS(src, value, dst, mask=None) -> None + + :param src1: first input array or a scalar. + + :param src2: second input array or a scalar. + + :param dst: output array of the same size and the same number of channels as the input array. + + :param mask: optional operation mask; this is an 8-bit single channel array that specifies elements of the output array to be changed. + + :param dtype: optional depth of the output array (see the details below). + +The function ``subtract`` calculates: + + * + Difference between two arrays, when both input arrays have the same size and the same number of channels: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0 + + * + Difference between an array and a scalar, when ``src2`` is constructed from ``Scalar`` or has the same number of elements as ``src1.channels()``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0 + + * + Difference between a scalar and an array, when ``src1`` is constructed from ``Scalar`` or has the same number of elements as ``src2.channels()``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0 + + * + The reverse difference between a scalar and an array in the case of ``SubRS``: + + .. math:: + + \texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0 + +where ``I`` is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: :: + + dst = src1 - src2; + dst -= src1; // equivalent to subtract(dst, src1, dst); + +The input arrays and the output array can all have the same or different depths. For example, you can subtract to 8-bit unsigned arrays and store the difference in a 16-bit signed array. Depth of the output array is determined by ``dtype`` parameter. In the second and third cases above, as well as in the first case, when ``src1.depth() == src2.depth()``, ``dtype`` can be set to the default ``-1``. In this case the output array will have the same depth as the input array, be it ``src1``, ``src2`` or both. + +.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow. + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`addWeighted`, + :ocv:func:`scaleAdd`, + :ocv:func:`Mat::convertTo`, + :ref:`MatrixExpressions` + + + +SVD +--- +.. ocv:class:: SVD + +Class for computing Singular Value Decomposition of a floating-point matrix. The Singular Value Decomposition is used to solve least-square problems, under-determined linear systems, invert matrices, compute condition numbers, and so on. + +For a faster operation, you can pass ``flags=SVD::MODIFY_A|...`` to modify the decomposed matrix when it is not necessary to preserve it. If you want to compute a condition number of a matrix or an absolute value of its determinant, you do not need ``u`` and ``vt`` . You can pass ``flags=SVD::NO_UV|...`` . Another flag ``FULL_UV`` indicates that full-size ``u`` and ``vt`` must be computed, which is not necessary most of the time. + +.. seealso:: + + :ocv:func:`invert`, + :ocv:func:`solve`, + :ocv:func:`eigen`, + :ocv:func:`determinant` + + + +SVD::SVD +-------- +The constructors. + +.. ocv:function:: SVD::SVD() + +.. ocv:function:: SVD::SVD( InputArray src, int flags=0 ) + + :param src: decomposed matrix. + + :param flags: operation flags. + + * **SVD::MODIFY_A** use the algorithm to modify the decomposed matrix; it can save space and speed up processing. + + * **SVD::NO_UV** indicates that only a vector of singular values ``w`` is to be processed, while ``u`` and ``vt`` will be set to empty matrices. + + * **SVD::FULL_UV** when the matrix is not square, by default the algorithm produces ``u`` and ``vt`` matrices of sufficiently large size for the further ``A`` reconstruction; if, however, ``FULL_UV`` flag is specified, ``u`` and ``vt`` will be full-size square orthogonal matrices. + +The first constructor initializes an empty ``SVD`` structure. The second constructor initializes an empty ``SVD`` structure and then calls +:ocv:funcx:`SVD::operator()` . + + +SVD::operator () +---------------- +Performs SVD of a matrix. + +.. ocv:function:: SVD& SVD::operator()( InputArray src, int flags=0 ) + + :param src: decomposed matrix. + + :param flags: operation flags. + + * **SVD::MODIFY_A** use the algorithm to modify the decomposed matrix; it can save space and speed up processing. + + * **SVD::NO_UV** use only singular values; the algorithm does not compute ``u`` and ``vt`` matrices. + + * **SVD::FULL_UV** when the matrix is not square, by default the algorithm produces ``u`` and ``vt`` matrices of sufficiently large size for the further ``A`` reconstruction; if, however, the ``FULL_UV`` flag is specified, ``u`` and ``vt`` are full-size square orthogonal matrices. + +The operator performs the singular value decomposition of the supplied matrix. The ``u``,``vt`` , and the vector of singular values ``w`` are stored in the structure. The same ``SVD`` structure can be reused many times with different matrices. Each time, if needed, the previous ``u``,``vt`` , and ``w`` are reclaimed and the new matrices are created, which is all handled by +:ocv:func:`Mat::create` . + + +SVD::compute +------------ +Performs SVD of a matrix + +.. ocv:function:: static void SVD::compute( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags=0 ) + +.. ocv:function:: static void SVD::compute( InputArray src, OutputArray w, int flags=0 ) + +.. ocv:pyfunction:: cv2.SVDecomp(src[, w[, u[, vt[, flags]]]]) -> w, u, vt + +.. ocv:cfunction:: void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 ) + +.. ocv:pyoldfunction:: cv.SVD(A, W, U=None, V=None, flags=0) -> None + + :param src: decomposed matrix + + :param w: calculated singular values + + :param u: calculated left singular vectors + + :param V: calculated right singular vectors + + :param vt: transposed matrix of right singular values + + :param flags: operation flags - see :ocv:func:`SVD::SVD`. + +The methods/functions perform SVD of matrix. Unlike ``SVD::SVD`` constructor and ``SVD::operator()``, they store the results to the user-provided matrices. :: + + Mat A, w, u, vt; + SVD::compute(A, w, u, vt); + + +SVD::solveZ +----------- +Solves an under-determined singular linear system. + +.. ocv:function:: static void SVD::solveZ( InputArray src, OutputArray dst ) + + :param src: left-hand-side matrix. + + :param dst: found solution. + +The method finds a unit-length solution ``x`` of a singular linear system +``A*x = 0``. Depending on the rank of ``A``, there can be no solutions, a single solution or an infinite number of solutions. In general, the algorithm solves the following problem: + +.. math:: + + dst = \arg \min _{x: \| x \| =1} \| src \cdot x \| + + +SVD::backSubst +-------------- +Performs a singular value back substitution. + +.. ocv:function:: void SVD::backSubst( InputArray rhs, OutputArray dst ) const + +.. ocv:function:: static void SVD::backSubst( InputArray w, InputArray u, InputArray vt, InputArray rhs, OutputArray dst ) + +.. ocv:pyfunction:: cv2.SVBackSubst(w, u, vt, rhs[, dst]) -> dst + +.. ocv:cfunction:: void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V, const CvArr* B, CvArr* X, int flags ) + +.. ocv:pyoldfunction:: cv.SVBkSb(W, U, V, B, X, flags) -> None + + :param w: singular values + + :param u: left singular vectors + + :param V: right singular vectors + + :param vt: transposed matrix of right singular vectors. + + :param rhs: right-hand side of a linear system ``(u*w*v')*dst = rhs`` to be solved, where ``A`` has been previously decomposed. + + :param dst: found solution of the system. + +The method calculates a back substitution for the specified right-hand side: + +.. math:: + + \texttt{x} = \texttt{vt} ^T \cdot diag( \texttt{w} )^{-1} \cdot \texttt{u} ^T \cdot \texttt{rhs} \sim \texttt{A} ^{-1} \cdot \texttt{rhs} + +Using this technique you can either get a very accurate solution of the convenient linear system, or the best (in the least-squares terms) pseudo-solution of an overdetermined linear system. + +.. note:: Explicit SVD with the further back substitution only makes sense if you need to solve many linear systems with the same left-hand side (for example, ``src`` ). If all you need is to solve a single system (possibly with multiple ``rhs`` immediately available), simply call :ocv:func:`solve` add pass ``DECOMP_SVD`` there. It does absolutely the same thing. + + + +sum +--- +Calculates the sum of array elements. + +.. ocv:function:: Scalar sum( InputArray src ) + +.. ocv:pyfunction:: cv2.sumElems(src) -> retval + +.. ocv:cfunction:: CvScalar cvSum(const CvArr* arr) + +.. ocv:pyoldfunction:: cv.Sum(arr) -> scalar + + :param arr: input array that must have from 1 to 4 channels. + +The functions ``sum`` calculate and return the sum of array elements, independently for each channel. + +.. seealso:: + + :ocv:func:`countNonZero`, + :ocv:func:`mean`, + :ocv:func:`meanStdDev`, + :ocv:func:`norm`, + :ocv:func:`minMaxLoc`, + :ocv:func:`reduce` + + + +theRNG +------ +Returns the default random number generator. + +.. ocv:function:: RNG& theRNG() + +The function ``theRNG`` returns the default random number generator. For each thread, there is a separate random number generator, so you can use the function safely in multi-thread environments. If you just need to get a single random number using this generator or initialize an array, you can use +:ocv:func:`randu` or +:ocv:func:`randn` instead. But if you are going to generate many random numbers inside a loop, it is much faster to use this function to retrieve the generator and then use ``RNG::operator _Tp()`` . + +.. seealso:: + + :ocv:class:`RNG`, + :ocv:func:`randu`, + :ocv:func:`randn` + + + +trace +----- +Returns the trace of a matrix. + +.. ocv:function:: Scalar trace( InputArray mtx ) + +.. ocv:pyfunction:: cv2.trace(mtx) -> retval + +.. ocv:cfunction:: CvScalar cvTrace(const CvArr* mat) + +.. ocv:pyoldfunction:: cv.Trace(mat) -> scalar + + :param mat: input matrix. + +The function ``trace`` returns the sum of the diagonal elements of the matrix ``mtx`` . + +.. math:: + + \mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i) + + + +transform +--------- +Performs the matrix transformation of every array element. + +.. ocv:function:: void transform( InputArray src, OutputArray dst, InputArray m ) + +.. ocv:pyfunction:: cv2.transform(src, m[, dst]) -> dst + +.. ocv:cfunction:: void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL ) + +.. ocv:pyoldfunction:: cv.Transform(src, dst, transmat, shiftvec=None)-> None + + :param src: input array that must have as many channels (1 to 4) as ``m.cols`` or ``m.cols-1``. + + :param dst: output array of the same size and depth as ``src``; it has as many channels as ``m.rows``. + + :param m: transformation ``2x2`` or ``2x3`` floating-point matrix. + + :param shiftvec: optional translation vector (when ``m`` is ``2x2``) + +The function ``transform`` performs the matrix transformation of every element of the array ``src`` and stores the results in ``dst`` : + +.. math:: + + \texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I) + +(when ``m.cols=src.channels()`` ), or + +.. math:: + + \texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1] + +(when ``m.cols=src.channels()+1`` ) + +Every element of the ``N`` -channel array ``src`` is interpreted as ``N`` -element vector that is transformed using +the ``M x N`` or ``M x (N+1)`` matrix ``m`` +to ``M``-element vector - the corresponding element of the output array ``dst`` . + +The function may be used for geometrical transformation of +``N`` -dimensional +points, arbitrary linear color space transformation (such as various kinds of RGB to YUV transforms), shuffling the image channels, and so forth. + +.. seealso:: + + :ocv:func:`perspectiveTransform`, + :ocv:func:`getAffineTransform`, + :ocv:func:`estimateRigidTransform`, + :ocv:func:`warpAffine`, + :ocv:func:`warpPerspective` + + + +transpose +--------- +Transposes a matrix. + +.. ocv:function:: void transpose(InputArray src, OutputArray dst) + +.. ocv:pyfunction:: cv2.transpose(src[, dst]) -> dst + +.. ocv:cfunction:: void cvTranspose(const CvArr* src, CvArr* dst) +.. ocv:pyoldfunction:: cv.Transpose(src, dst)-> None + + :param src: input array. + + :param dst: output array of the same type as ``src``. + +The function :ocv:func:`transpose` transposes the matrix ``src`` : + +.. math:: + + \texttt{dst} (i,j) = \texttt{src} (j,i) + +.. note:: No complex conjugation is done in case of a complex matrix. It it should be done separately if needed. Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/core/doc/pics/ellipse.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/core/doc/pics/ellipse.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/core/doc/pics/memstorage1.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/core/doc/pics/memstorage1.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/core/doc/pics/memstorage2.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/core/doc/pics/memstorage2.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/core/doc/pics/rotatedrect.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/core/doc/pics/rotatedrect.png differ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/utility_and_system_functions_and_macros.rst diffimg-2.0.0/3rdparty/opencv/core/doc/utility_and_system_functions_and_macros.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/utility_and_system_functions_and_macros.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/utility_and_system_functions_and_macros.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,492 @@ +Utility and System Functions and Macros +======================================= + +.. highlight:: cpp + +alignPtr +------------ +Aligns a pointer to the specified number of bytes. + +.. ocv:function:: template _Tp* alignPtr(_Tp* ptr, int n=sizeof(_Tp)) + + :param ptr: Aligned pointer. + + :param n: Alignment size that must be a power of two. + +The function returns the aligned pointer of the same type as the input pointer: + +.. math:: + + \texttt{(\_Tp*)(((size\_t)ptr + n-1) \& -n)} + + + +alignSize +------------- +Aligns a buffer size to the specified number of bytes. + +.. ocv:function:: size_t alignSize(size_t sz, int n) + + :param sz: Buffer size to align. + + :param n: Alignment size that must be a power of two. + +The function returns the minimum number that is greater or equal to ``sz`` and is divisible by ``n`` : + +.. math:: + + \texttt{(sz + n-1) \& -n} + + + +allocate +------------ +Allocates an array of elements. + +.. ocv:function:: template _Tp* allocate(size_t n) + + :param n: Number of elements to allocate. + +The generic function ``allocate`` allocates a buffer for the specified number of elements. For each element, the default constructor is called. + + + +deallocate +-------------- +Deallocates an array of elements. + +.. ocv:function:: template void deallocate(_Tp* ptr, size_t n) + + :param ptr: Pointer to the deallocated buffer. + + :param n: Number of elements in the buffer. + +The generic function ``deallocate`` deallocates the buffer allocated with +:ocv:func:`allocate` . The number of elements must match the number passed to +:ocv:func:`allocate` . + + + +fastAtan2 +--------- +Calculates the angle of a 2D vector in degrees. + +.. ocv:function:: float fastAtan2(float y, float x) + +.. ocv:pyfunction:: cv2.fastAtan2(y, x) -> retval + +.. ocv:cfunction:: float cvFastArctan(float y, float x) +.. ocv:pyoldfunction:: cv.FastArctan(y, x)-> float + + :param x: x-coordinate of the vector. + + :param y: y-coordinate of the vector. + +The function ``fastAtan2`` calculates the full-range angle of an input 2D vector. The angle is measured in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. + + +cubeRoot +-------- +Computes the cube root of an argument. + +.. ocv:function:: float cubeRoot(float val) + +.. ocv:pyfunction:: cv2.cubeRoot(val) -> retval + +.. ocv:cfunction:: float cvCbrt( float value ) + +.. ocv:pyoldfunction:: cv.Cbrt(value)-> float + + :param val: A function argument. + +The function ``cubeRoot`` computes :math:`\sqrt[3]{\texttt{val}}`. Negative arguments are handled correctly. NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for single-precision data. + + +Ceil +----- +Rounds floating-point number to the nearest integer not smaller than the original. + +.. ocv:cfunction:: int cvCeil(double value) +.. ocv:pyoldfunction:: cv.Ceil(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + +The function computes an integer ``i`` such that: + +.. math:: + + i-1 < \texttt{value} \le i + + +Floor +----- +Rounds floating-point number to the nearest integer not larger than the original. + +.. ocv:cfunction:: int cvFloor(double value) +.. ocv:pyoldfunction:: cv.Floor(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + +The function computes an integer ``i`` such that: + +.. math:: + + i \le \texttt{value} < i+1 + + +Round +----- +Rounds floating-point number to the nearest integer + +.. ocv:cfunction:: int cvRound(double value) +.. ocv:pyoldfunction:: cv.Round(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + + +IsInf +----- +Determines if the argument is Infinity. + +.. ocv:cfunction:: int cvIsInf(double value) +.. ocv:pyoldfunction:: cv.IsInf(value)-> int + + :param value: The input floating-point value + +The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard) and 0 otherwise. + +IsNaN +----- +Determines if the argument is Not A Number. + +.. ocv:cfunction:: int cvIsNaN(double value) +.. ocv:pyoldfunction:: cv.IsNaN(value)-> int + + :param value: The input floating-point value + +The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 otherwise. + + +CV_Assert +--------- +Checks a condition at runtime and throws exception if it fails + +.. ocv:function:: CV_Assert(expr) + +The macros ``CV_Assert`` (and ``CV_DbgAssert``) evaluate the specified expression. If it is 0, the macros raise an error (see :ocv:func:`error` ). The macro ``CV_Assert`` checks the condition in both Debug and Release configurations while ``CV_DbgAssert`` is only retained in the Debug configuration. + + +error +----- +Signals an error and raises an exception. + +.. ocv:function:: void error( const Exception& exc ) + +.. ocv:cfunction:: void cvError( int status, const char* func_name, const char* err_msg, const char* file_name, int line ) + + :param exc: Exception to throw. + + :param status: Error code. Normally, it is a negative value. The list of pre-defined error codes can be found in ``cxerror.h`` . + + :param err_msg: Text of the error message. + + :param args: ``printf`` -like formatted error message in parentheses. + +The function and the helper macros ``CV_Error`` and ``CV_Error_``: :: + + #define CV_Error( code, msg ) error(...) + #define CV_Error_( code, args ) error(...) + +call the error handler. Currently, the error handler prints the error code ( ``exc.code`` ), the context ( ``exc.file``,``exc.line`` ), and the error message ``exc.err`` to the standard error stream ``stderr`` . In the Debug configuration, it then provokes memory access violation, so that the execution stack and all the parameters can be analyzed by the debugger. In the Release configuration, the exception ``exc`` is thrown. + +The macro ``CV_Error_`` can be used to construct an error message on-fly to include some dynamic information, for example: :: + + // note the extra parentheses around the formatted text message + CV_Error_(CV_StsOutOfRange, + ("the matrix element ( + i, j, mtx.at(i,j))) + + +Exception +--------- +.. ocv:class:: Exception : public std::exception + +Exception class passed to an error. :: + + class Exception + { + public: + // various constructors and the copy operation + Exception() { code = 0; line = 0; } + Exception(int _code, const string& _err, + const string& _func, const string& _file, int _line); + Exception(const Exception& exc); + Exception& operator = (const Exception& exc); + + // the error code + int code; + // the error text message + string err; + // function name where the error happened + string func; + // the source file name where the error happened + string file; + // the source file line where the error happened + int line; + }; + +The class ``Exception`` encapsulates all or almost all necessary information about the error happened in the program. The exception is usually constructed and thrown implicitly via ``CV_Error`` and ``CV_Error_`` macros. See +:ocv:func:`error` . + + + +fastMalloc +-------------- +Allocates an aligned memory buffer. + +.. ocv:function:: void* fastMalloc( size_t bufSize ) + +.. ocv:cfunction:: void* cvAlloc( size_t size ) + + :param size: Allocated buffer size. + +The function allocates the buffer of the specified size and returns it. When the buffer size is 16 bytes or more, the returned buffer is aligned to 16 bytes. + + + +fastFree +-------- +Deallocates a memory buffer. + +.. ocv:function:: void fastFree(void* ptr) +.. ocv:cfunction:: void cvFree( void** pptr ) + + :param ptr: Pointer to the allocated buffer. + + :param pptr: Double pointer to the allocated buffer + +The function deallocates the buffer allocated with :ocv:func:`fastMalloc` . If NULL pointer is passed, the function does nothing. C version of the function clears the pointer ``*pptr`` to avoid problems with double memory deallocation. + + +format +------ +Returns a text string formatted using the ``printf``\ -like expression. + +.. ocv:function:: string format( const char* fmt, ... ) + + :param fmt: ``printf`` -compatible formatting specifiers. + +The function acts like ``sprintf`` but forms and returns an STL string. It can be used to form an error message in the +:ocv:class:`Exception` constructor. + + +getBuildInformation +------------------- +Returns full configuration time cmake output. + +.. ocv:function:: const std::string& getBuildInformation() + +Returned value is raw cmake output including version control system revision, compiler version, compiler flags, enabled modules and third party libraries, etc. Output format depends on target architecture. + + +checkHardwareSupport +-------------------- +Returns true if the specified feature is supported by the host hardware. + +.. ocv:function:: bool checkHardwareSupport(int feature) +.. ocv:cfunction:: int cvCheckHardwareSupport(int feature) +.. ocv:pyfunction:: cv2.checkHardwareSupport(feature) -> retval + + :param feature: The feature of interest, one of: + + * ``CV_CPU_MMX`` - MMX + * ``CV_CPU_SSE`` - SSE + * ``CV_CPU_SSE2`` - SSE 2 + * ``CV_CPU_SSE3`` - SSE 3 + * ``CV_CPU_SSSE3`` - SSSE 3 + * ``CV_CPU_SSE4_1`` - SSE 4.1 + * ``CV_CPU_SSE4_2`` - SSE 4.2 + * ``CV_CPU_POPCNT`` - POPCOUNT + * ``CV_CPU_AVX`` - AVX + +The function returns true if the host hardware supports the specified feature. When user calls ``setUseOptimized(false)``, the subsequent calls to ``checkHardwareSupport()`` will return false until ``setUseOptimized(true)`` is called. This way user can dynamically switch on and off the optimized code in OpenCV. + + + +getNumberOfCPUs +----------------- +Returns the number of logical CPUs available for the process. + +.. ocv:function:: int getNumberOfCPUs() + + + +getNumThreads +----------------- +Returns the number of threads used by OpenCV for parallel regions. +Always returns 1 if OpenCV is built without threading support. + +.. ocv:function:: int getNumThreads() + +The exact meaning of return value depends on the threading framework used by OpenCV library: + + * **TBB** – The number of threads, that OpenCV will try to use for parallel regions. + If there is any ``tbb::thread_scheduler_init`` in user code conflicting with OpenCV, then + function returns default number of threads used by TBB library. + * **OpenMP** – An upper bound on the number of threads that could be used to form a new team. + * **Concurrency** – The number of threads, that OpenCV will try to use for parallel regions. + * **GCD** – Unsupported; returns the GCD thread pool limit (512) for compatibility. + * **C=** – The number of threads, that OpenCV will try to use for parallel regions, + if before called ``setNumThreads`` with ``threads > 0``, + otherwise returns the number of logical CPUs, available for the process. + +.. seealso:: + :ocv:func:`setNumThreads`, + :ocv:func:`getThreadNum` + + + +getThreadNum +---------------- +Returns the index of the currently executed thread within the current parallel region. +Always returns 0 if called outside of parallel region. + +.. ocv:function:: int getThreadNum() + +The exact meaning of return value depends on the threading framework used by OpenCV library: + + * **TBB** – Unsupported with current 4.1 TBB release. May be will be supported in future. + * **OpenMP** – The thread number, within the current team, of the calling thread. + * **Concurrency** – An ID for the virtual processor that the current context is executing + on (0 for master thread and unique number for others, but not necessary 1,2,3,...). + * **GCD** – System calling thread's ID. Never returns 0 inside parallel region. + * **C=** – The index of the current parallel task. + +.. seealso:: + :ocv:func:`setNumThreads`, + :ocv:func:`getNumThreads` + + + +getTickCount +------------ +Returns the number of ticks. + +.. ocv:function:: int64 getTickCount() + +.. ocv:pyfunction:: cv2.getTickCount() -> retval + +The function returns the number of ticks after the certain event (for example, when the machine was turned on). +It can be used to initialize +:ocv:func:`RNG` or to measure a function execution time by reading the tick count before and after the function call. See also the tick frequency. + + + +getTickFrequency +---------------- +Returns the number of ticks per second. + +.. ocv:function:: double getTickFrequency() + +.. ocv:pyfunction:: cv2.getTickFrequency() -> retval + +The function returns the number of ticks per second. +That is, the following code computes the execution time in seconds: :: + + double t = (double)getTickCount(); + // do something ... + t = ((double)getTickCount() - t)/getTickFrequency(); + + + +getCPUTickCount +--------------- +Returns the number of CPU ticks. + +.. ocv:function:: int64 getCPUTickCount() + +.. ocv:pyfunction:: cv2.getCPUTickCount() -> retval + +The function returns the current number of CPU ticks on some architectures (such as x86, x64, PowerPC). On other platforms the function is equivalent to ``getTickCount``. It can also be used for very accurate time measurements, as well as for RNG initialization. Note that in case of multi-CPU systems a thread, from which ``getCPUTickCount`` is called, can be suspended and resumed at another CPU with its own counter. So, theoretically (and practically) the subsequent calls to the function do not necessary return the monotonously increasing values. Also, since a modern CPU varies the CPU frequency depending on the load, the number of CPU clocks spent in some code cannot be directly converted to time units. Therefore, ``getTickCount`` is generally a preferable solution for measuring execution time. + + +saturate_cast +------------- +Template function for accurate conversion from one primitive type to another. + +.. ocv:function:: template<...> _Tp saturate_cast(_Tp2 v) + + :param v: Function parameter. + +The functions ``saturate_cast`` resemble the standard C++ cast operations, such as ``static_cast()`` and others. They perform an efficient and accurate conversion from one primitive type to another (see the introduction chapter). ``saturate`` in the name means that when the input value ``v`` is out of the range of the target type, the result is not formed just by taking low bits of the input, but instead the value is clipped. For example: :: + + uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) + short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) + +Such clipping is done when the target type is ``unsigned char`` , ``signed char`` , ``unsigned short`` or ``signed short`` . For 32-bit integers, no clipping is done. + +When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit), the floating-point value is first rounded to the nearest integer and then clipped if needed (when the target type is 8- or 16-bit). + +This operation is used in the simplest or most complex image processing functions in OpenCV. + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`subtract`, + :ocv:func:`multiply`, + :ocv:func:`divide`, + :ocv:func:`Mat::convertTo` + +setNumThreads +----------------- +OpenCV will try to set the number of threads for the next parallel region. +If ``threads == 0``, OpenCV will disable threading optimizations and run all it's +functions sequentially. Passing ``threads < 0`` will reset threads number to system default. +This function must be called outside of parallel region. + +.. ocv:function:: void setNumThreads(int nthreads) + + :param nthreads: Number of threads used by OpenCV. + +OpenCV will try to run it's functions with specified threads number, but +some behaviour differs from framework: + + * **TBB** – User-defined parallel constructions will run with the same threads number, + if another does not specified. If late on user creates own scheduler, OpenCV will be use it. + * **OpenMP** – No special defined behaviour. + * **Concurrency** – If ``threads == 1``, OpenCV will disable threading optimizations + and run it's functions sequentially. + * **GCD** – Supports only values <= 0. + * **C=** – No special defined behaviour. + +.. seealso:: + :ocv:func:`getNumThreads`, + :ocv:func:`getThreadNum` + + + +setUseOptimized +--------------- +Enables or disables the optimized code. + +.. ocv:function:: int cvUseOptimized( int on_off ) + +.. ocv:pyfunction:: cv2.setUseOptimized(onoff) -> None + +.. ocv:cfunction:: int cvUseOptimized( int on_off ) + + :param on_off: The boolean flag specifying whether the optimized code should be used (``on_off=true``) or not (``on_off=false``). + +The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX, and other instructions on the platforms that support it). It sets a global flag that is further checked by OpenCV functions. Since the flag is not checked in the inner OpenCV loops, it is only safe to call the function on the very top level in your application where you can be sure that no other OpenCV function is currently executed. + +By default, the optimized code is enabled unless you disable it in CMake. The current status can be retrieved using ``useOptimized``. + +useOptimized +------------ +Returns the status of optimized code usage. + +.. ocv:function:: bool useOptimized() + +.. ocv:pyfunction:: cv2.useOptimized() -> retval + +The function returns ``true`` if the optimized code is enabled. Otherwise, it returns ``false``. diff -Nru diffimg-1.5.0/3rdparty/opencv/core/doc/xml_yaml_persistence.rst diffimg-2.0.0/3rdparty/opencv/core/doc/xml_yaml_persistence.rst --- diffimg-1.5.0/3rdparty/opencv/core/doc/xml_yaml_persistence.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/doc/xml_yaml_persistence.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,703 @@ +XML/YAML Persistence +==================== + +.. highlight:: cpp + +XML/YAML file storages. Writing to a file storage. +-------------------------------------------------- + +You can store and then restore various OpenCV data structures to/from XML (http://www.w3c.org/XML) or YAML +(http://www.yaml.org) formats. Also, it is possible store and load arbitrarily complex data structures, which include OpenCV data structures, as well as primitive data types (integer and floating-point numbers and text strings) as their elements. + +Use the following procedure to write something to XML or YAML: + #. Create new :ocv:class:`FileStorage` and open it for writing. It can be done with a single call to :ocv:func:`FileStorage::FileStorage` constructor that takes a filename, or you can use the default constructor and then call :ocv:func:`FileStorage::open`. Format of the file (XML or YAML) is determined from the filename extension (".xml" and ".yml"/".yaml", respectively) + #. Write all the data you want using the streaming operator ``>>``, just like in the case of STL streams. + #. Close the file using :ocv:func:`FileStorage::release`. ``FileStorage`` destructor also closes the file. + +Here is an example: :: + + #include "opencv2/opencv.hpp" + #include + + using namespace cv; + + int main(int, char** argv) + { + FileStorage fs("test.yml", FileStorage::WRITE); + + fs << "frameCount" << 5; + time_t rawtime; time(&rawtime); + fs << "calibrationDate" << asctime(localtime(&rawtime)); + Mat cameraMatrix = (Mat_(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); + Mat distCoeffs = (Mat_(5,1) << 0.1, 0.01, -0.001, 0, 0); + fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs; + fs << "features" << "["; + for( int i = 0; i < 3; i++ ) + { + int x = rand() % 640; + int y = rand() % 480; + uchar lbp = rand() % 256; + + fs << "{:" << "x" << x << "y" << y << "lbp" << "[:"; + for( int j = 0; j < 8; j++ ) + fs << ((lbp >> j) & 1); + fs << "]" << "}"; + } + fs << "]"; + fs.release(); + return 0; + } + +The sample above stores to XML and integer, text string (calibration date), 2 matrices, and a custom structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here is output of the sample: + +.. code-block:: yaml + + %YAML:1.0 + frameCount: 5 + calibrationDate: "Fri Jun 17 14:09:29 2011\n" + cameraMatrix: !!opencv-matrix + rows: 3 + cols: 3 + dt: d + data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ] + distCoeffs: !!opencv-matrix + rows: 5 + cols: 1 + dt: d + data: [ 1.0000000000000001e-01, 1.0000000000000000e-02, + -1.0000000000000000e-03, 0., 0. ] + features: + - { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] } + - { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] } + - { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] } + +As an exercise, you can replace ".yml" with ".xml" in the sample above and see, how the corresponding XML file will look like. + +Several things can be noted by looking at the sample code and the output: + * + The produced YAML (and XML) consists of heterogeneous collections that can be nested. There are 2 types of collections: named collections (mappings) and unnamed collections (sequences). In mappings each element has a name and is accessed by name. This is similar to structures and ``std::map`` in C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by indices. This is similar to arrays and ``std::vector`` in C/C++ and lists, tuples in Python. "Heterogeneous" means that elements of each single collection can have different types. + + Top-level collection in YAML/XML is a mapping. Each matrix is stored as a mapping, and the matrix elements are stored as a sequence. Then, there is a sequence of features, where each feature is represented a mapping, and lbp value in a nested sequence. + + * + When you write to a mapping (a structure), you write element name followed by its value. When you write to a sequence, you simply write the elements one by one. OpenCV data structures (such as cv::Mat) are written in absolutely the same way as simple C data structures - using **``<<``** operator. + + * + To write a mapping, you first write the special string **"{"** to the storage, then write the elements as pairs (``fs << << ``) and then write the closing **"}"**. + + * + To write a sequence, you first write the special string **"["**, then write the elements, then write the closing **"]"**. + + * + In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline form. In the sample above matrix elements, as well as each feature, including its lbp value, is stored in such inline form. To store a mapping/sequence in a compact form, put ":" after the opening character, e.g. use **"{:"** instead of **"{"** and **"[:"** instead of **"["**. When the data is written to XML, those extra ":" are ignored. + + +Reading data from a file storage. +--------------------------------- + +To read the previously written XML or YAML file, do the following: + + #. + Open the file storage using :ocv:func:`FileStorage::FileStorage` constructor or :ocv:func:`FileStorage::open` method. In the current implementation the whole file is parsed and the whole representation of file storage is built in memory as a hierarchy of file nodes (see :ocv:class:`FileNode`) + + #. + Read the data you are interested in. Use :ocv:func:`FileStorage::operator []`, :ocv:func:`FileNode::operator []` and/or :ocv:class:`FileNodeIterator`. + + #. + Close the storage using :ocv:func:`FileStorage::release`. + +Here is how to read the file created by the code sample above: :: + + FileStorage fs2("test.yml", FileStorage::READ); + + // first method: use (type) operator on FileNode. + int frameCount = (int)fs2["frameCount"]; + + std::string date; + // second method: use FileNode::operator >> + fs2["calibrationDate"] >> date; + + Mat cameraMatrix2, distCoeffs2; + fs2["cameraMatrix"] >> cameraMatrix2; + fs2["distCoeffs"] >> distCoeffs2; + + cout << "frameCount: " << frameCount << endl + << "calibration date: " << date << endl + << "camera matrix: " << cameraMatrix2 << endl + << "distortion coeffs: " << distCoeffs2 << endl; + + FileNode features = fs2["features"]; + FileNodeIterator it = features.begin(), it_end = features.end(); + int idx = 0; + std::vector lbpval; + + // iterate through a sequence using FileNodeIterator + for( ; it != it_end; ++it, idx++ ) + { + cout << "feature #" << idx << ": "; + cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: ("; + // you can also easily read numerical arrays using FileNode >> std::vector operator. + (*it)["lbp"] >> lbpval; + for( int i = 0; i < (int)lbpval.size(); i++ ) + cout << " " << (int)lbpval[i]; + cout << ")" << endl; + } + fs.release(); + +FileStorage +----------- +.. ocv:class:: FileStorage + +XML/YAML file storage class that encapsulates all the information necessary for writing or reading data to/from a file. + +FileStorage::FileStorage +------------------------ +The constructors. + +.. ocv:function:: FileStorage::FileStorage() + +.. ocv:function:: FileStorage::FileStorage(const string& source, int flags, const string& encoding=string()) + + :param source: Name of the file to open or the text string to read the data from. Extension of the file (``.xml`` or ``.yml``/``.yaml``) determines its format (XML or YAML respectively). Also you can append ``.gz`` to work with compressed files, for example ``myHugeMatrix.xml.gz``. If both ``FileStorage::WRITE`` and ``FileStorage::MEMORY`` flags are specified, ``source`` is used just to specify the output file format (e.g. ``mydata.xml``, ``.yml`` etc.). + + :param flags: Mode of operation. Possible values are: + + * **FileStorage::READ** Open the file for reading. + + * **FileStorage::WRITE** Open the file for writing. + + * **FileStorage::APPEND** Open the file for appending. + + * **FileStorage::MEMORY** Read data from ``source`` or write data to the internal buffer (which is returned by ``FileStorage::release``) + + :param encoding: Encoding of the file. Note that UTF-16 XML encoding is not supported currently and you should use 8-bit encoding instead of it. + +The full constructor opens the file. Alternatively you can use the default constructor and then call :ocv:func:`FileStorage::open`. + + +FileStorage::open +----------------- +Opens a file. + +.. ocv:function:: bool FileStorage::open(const string& filename, int flags, const string& encoding=string()) + +See description of parameters in :ocv:func:`FileStorage::FileStorage`. The method calls :ocv:func:`FileStorage::release` before opening the file. + + +FileStorage::isOpened +--------------------- +Checks whether the file is opened. + +.. ocv:function:: bool FileStorage::isOpened() const + + :returns: ``true`` if the object is associated with the current file and ``false`` otherwise. + +It is a good practice to call this method after you tried to open a file. + + +FileStorage::release +-------------------- +Closes the file and releases all the memory buffers. + +.. ocv:function:: void FileStorage::release() + +Call this method after all I/O operations with the storage are finished. + + +FileStorage::releaseAndGetString +-------------------------------- +Closes the file and releases all the memory buffers. + +.. ocv:function:: string FileStorage::releaseAndGetString() + +Call this method after all I/O operations with the storage are finished. If the storage was opened for writing data and ``FileStorage::WRITE`` was specified + + +FileStorage::getFirstTopLevelNode +--------------------------------- +Returns the first element of the top-level mapping. + +.. ocv:function:: FileNode FileStorage::getFirstTopLevelNode() const + + :returns: The first element of the top-level mapping. + + +FileStorage::root +----------------- +Returns the top-level mapping + +.. ocv:function:: FileNode FileStorage::root(int streamidx=0) const + + :param streamidx: Zero-based index of the stream. In most cases there is only one stream in the file. However, YAML supports multiple streams and so there can be several. + + :returns: The top-level mapping. + + +FileStorage::operator[] +----------------------- +Returns the specified element of the top-level mapping. + +.. ocv:function:: FileNode FileStorage::operator[](const string& nodename) const + +.. ocv:function:: FileNode FileStorage::operator[](const char* nodename) const + + :param nodename: Name of the file node. + + :returns: Node with the given name. + + +FileStorage::operator* +---------------------- +Returns the obsolete C FileStorage structure. + +.. ocv:function:: CvFileStorage* FileStorage::operator *() + +.. ocv:function:: const CvFileStorage* FileStorage::operator *() const + + :returns: Pointer to the underlying C FileStorage structure + + +FileStorage::writeRaw +--------------------- +Writes multiple numbers. + +.. ocv:function:: void FileStorage::writeRaw( const string& fmt, const uchar* vec, size_t len ) + + :param fmt: Specification of each array element that has the following format ``([count]{'u'|'c'|'w'|'s'|'i'|'f'|'d'})...`` where the characters correspond to fundamental C++ types: + + * **u** 8-bit unsigned number + + * **c** 8-bit signed number + + * **w** 16-bit unsigned number + + * **s** 16-bit signed number + + * **i** 32-bit signed number + + * **f** single precision floating-point number + + * **d** double precision floating-point number + + * **r** pointer, 32 lower bits of which are written as a signed integer. The type can be used to store structures with links between the elements. + + ``count`` is the optional counter of values of a given type. For example, ``2if`` means that each array element is a structure of 2 integers, followed by a single-precision floating-point number. The equivalent notations of the above specification are ' ``iif`` ', ' ``2i1f`` ' and so forth. Other examples: ``u`` means that the array consists of bytes, and ``2d`` means the array consists of pairs of doubles. + + :param vec: Pointer to the written array. + + :param len: Number of the ``uchar`` elements to write. + +Writes one or more numbers of the specified format to the currently written structure. Usually it is more convenient to use :ocv:func:`operator <<` instead of this method. + +FileStorage::writeObj +--------------------- +Writes the registered C structure (CvMat, CvMatND, CvSeq). + +.. ocv:function:: void FileStorage::writeObj( const string& name, const void* obj ) + + :param name: Name of the written object. + + :param obj: Pointer to the object. + +See :ocv:cfunc:`Write` for details. + + +FileStorage::getDefaultObjectName +--------------------------------- +Returns the normalized object name for the specified name of a file. + +.. ocv:function:: static string FileStorage::getDefaultObjectName(const string& filename) + + :param filename: Name of a file + + :returns: The normalized object name. + + +operator << +----------- +Writes data to a file storage. + +.. ocv:function:: template FileStorage& operator << (FileStorage& fs, const _Tp& value) + +.. ocv:function:: template FileStorage& operator << ( FileStorage& fs, const vector<_Tp>& vec ) + + :param fs: Opened file storage to write data. + + :param value: Value to be written to the file storage. + + :param vec: Vector of values to be written to the file storage. + +It is the main function to write data to a file storage. See an example of its usage at the beginning of the section. + + +operator >> +----------- +Reads data from a file storage. + +.. ocv:function:: template void operator >> (const FileNode& n, _Tp& value) + +.. ocv:function:: template void operator >> (const FileNode& n, vector<_Tp>& vec) + +.. ocv:function:: template FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) + +.. ocv:function:: template FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec) + + :param n: Node from which data will be read. + + :param it: Iterator from which data will be read. + + :param value: Value to be read from the file storage. + + :param vec: Vector of values to be read from the file storage. + +It is the main function to read data from a file storage. See an example of its usage at the beginning of the section. + + +FileNode +-------- +.. ocv:class:: FileNode + +File Storage Node class. The node is used to store each and every element of the file storage opened for reading. When XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of nodes. Each node can be a “leaf†that is contain a single number or a string, or be a collection of other nodes. There can be named collections (mappings) where each element has a name and it is accessed by a name, and ordered collections (sequences) where elements do not have names but rather accessed by index. Type of the file node can be determined using :ocv:func:`FileNode::type` method. + +Note that file nodes are only used for navigating file storages opened for reading. When a file storage is opened for writing, no data is stored in memory after it is written. + + +FileNode::FileNode +------------------ +The constructors. + +.. ocv:function:: FileNode::FileNode() + +.. ocv:function:: FileNode::FileNode(const CvFileStorage* fs, const CvFileNode* node) + +.. ocv:function:: FileNode::FileNode(const FileNode& node) + + :param fs: Pointer to the obsolete file storage structure. + + :param node: File node to be used as initialization for the created file node. + +These constructors are used to create a default file node, construct it from obsolete structures or from the another file node. + + +FileNode::operator[] +-------------------- +Returns element of a mapping node or a sequence node. + +.. ocv:function:: FileNode FileNode::operator[](const string& nodename) const + +.. ocv:function:: FileNode FileNode::operator[](const char* nodename) const + +.. ocv:function:: FileNode FileNode::operator[](int i) const + + :param nodename: Name of an element in the mapping node. + + :param i: Index of an element in the sequence node. + + :returns: Returns the element with the given identifier. + + +FileNode::type +-------------- +Returns type of the node. + +.. ocv:function:: int FileNode::type() const + + :returns: Type of the node. Possible values are: + + * **FileNode::NONE** Empty node. + + * **FileNode::INT** Integer. + + * **FileNode::REAL** Floating-point number. + + * **FileNode::FLOAT** Synonym or ``REAL``. + + * **FileNode::STR** Text string in UTF-8 encoding. + + * **FileNode::STRING** Synonym for ``STR``. + + * **FileNode::REF** Integer of type ``size_t``. Typically used for storing complex dynamic structures where some elements reference the others. + + * **FileNode::SEQ** Sequence. + + * **FileNode::MAP** Mapping. + + * **FileNode::FLOW** Compact representation of a sequence or mapping. Used only by the YAML writer. + + * **FileNode::USER** Registered object (e.g. a matrix). + + * **FileNode::EMPTY** Empty structure (sequence or mapping). + + * **FileNode::NAMED** The node has a name (i.e. it is an element of a mapping). + + +FileNode::empty +--------------- +Checks whether the node is empty. + +.. ocv:function:: bool FileNode::empty() const + + :returns: ``true`` if the node is empty. + + +FileNode::isNone +---------------- +Checks whether the node is a "none" object + +.. ocv:function:: bool FileNode::isNone() const + + :returns: ``true`` if the node is a "none" object. + + +FileNode::isSeq +--------------- +Checks whether the node is a sequence. + +.. ocv:function:: bool FileNode::isSeq() const + + :returns: ``true`` if the node is a sequence. + + +FileNode::isMap +--------------- +Checks whether the node is a mapping. + +.. ocv:function:: bool FileNode::isMap() const + + :returns: ``true`` if the node is a mapping. + + +FileNode::isInt +--------------- +Checks whether the node is an integer. + +.. ocv:function:: bool FileNode::isInt() const + + :returns: ``true`` if the node is an integer. + + +FileNode::isReal +---------------- +Checks whether the node is a floating-point number. + +.. ocv:function:: bool FileNode::isReal() const + + :returns: ``true`` if the node is a floating-point number. + + +FileNode::isString +------------------ +Checks whether the node is a text string. + +.. ocv:function:: bool FileNode::isString() const + + :returns: ``true`` if the node is a text string. + + +FileNode::isNamed +----------------- +Checks whether the node has a name. + +.. ocv:function:: bool FileNode::isNamed() const + + :returns: ``true`` if the node has a name. + + +FileNode::name +-------------- +Returns the node name. + +.. ocv:function:: string FileNode::name() const + + :returns: The node name or an empty string if the node is nameless. + + +FileNode::size +-------------- +Returns the number of elements in the node. + +.. ocv:function:: size_t FileNode::size() const + + :returns: The number of elements in the node, if it is a sequence or mapping, or 1 otherwise. + + +FileNode::operator int +---------------------- +Returns the node content as an integer. + +.. ocv:function:: FileNode::operator int() const + + :returns: The node content as an integer. If the node stores a floating-point number, it is rounded. + + +FileNode::operator float +------------------------ +Returns the node content as float. + +.. ocv:function:: FileNode::operator float() const + + :returns: The node content as float. + + +FileNode::operator double +------------------------- +Returns the node content as double. + +.. ocv:function:: FileNode::operator double() const + + :returns: The node content as double. + + +FileNode::operator string +------------------------- +Returns the node content as text string. + +.. ocv:function:: FileNode::operator string() const + + :returns: The node content as a text string. + + +FileNode::operator* +------------------- +Returns pointer to the underlying obsolete file node structure. + +.. ocv:function:: CvFileNode* FileNode::operator *() + + :returns: Pointer to the underlying obsolete file node structure. + + +FileNode::begin +--------------- +Returns the iterator pointing to the first node element. + +.. ocv:function:: FileNodeIterator FileNode::begin() const + + :returns: Iterator pointing to the first node element. + + +FileNode::end +------------- +Returns the iterator pointing to the element following the last node element. + +.. ocv:function:: FileNodeIterator FileNode::end() const + + :returns: Iterator pointing to the element following the last node element. + + +FileNode::readRaw +----------------- +Reads node elements to the buffer with the specified format. + +.. ocv:function:: void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const + + :param fmt: Specification of each array element. It has the same format as in :ocv:func:`FileStorage::writeRaw`. + + :param vec: Pointer to the destination array. + + :param len: Number of elements to read. If it is greater than number of remaining elements then all of them will be read. + +Usually it is more convenient to use :ocv:func:`operator >>` instead of this method. + +FileNode::readObj +----------------- +Reads the registered object. + +.. ocv:function:: void* FileNode::readObj() const + + :returns: Pointer to the read object. + +See :ocv:cfunc:`Read` for details. + +FileNodeIterator +---------------- +.. ocv:class:: FileNodeIterator + +The class ``FileNodeIterator`` is used to iterate through sequences and mappings. A standard STL notation, with ``node.begin()``, ``node.end()`` denoting the beginning and the end of a sequence, stored in ``node``. See the data reading sample in the beginning of the section. + + +FileNodeIterator::FileNodeIterator +---------------------------------- +The constructors. + +.. ocv:function:: FileNodeIterator::FileNodeIterator() + +.. ocv:function:: FileNodeIterator::FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0) + +.. ocv:function:: FileNodeIterator::FileNodeIterator(const FileNodeIterator& it) + + :param fs: File storage for the iterator. + + :param node: File node for the iterator. + + :param ofs: Index of the element in the node. The created iterator will point to this element. + + :param it: Iterator to be used as initialization for the created iterator. + +These constructors are used to create a default iterator, set it to specific element in a file node or construct it from another iterator. + + +FileNodeIterator::operator* +--------------------------- +Returns the currently observed element. + +.. ocv:function:: FileNode FileNodeIterator::operator *() const + + :returns: Currently observed element. + + +FileNodeIterator::operator-> +---------------------------- +Accesses methods of the currently observed element. + +.. ocv:function:: FileNode FileNodeIterator::operator ->() const + + +FileNodeIterator::operator ++ +----------------------------- +Moves iterator to the next node. + +.. ocv:function:: FileNodeIterator& FileNodeIterator::operator ++ () + +.. ocv:function:: FileNodeIterator FileNodeIterator::operator ++ (int) + + +FileNodeIterator::operator -- +----------------------------- +Moves iterator to the previous node. + +.. ocv:function:: FileNodeIterator& FileNodeIterator::operator -- () + +.. ocv:function:: FileNodeIterator FileNodeIterator::operator -- (int) + + +FileNodeIterator::operator += +----------------------------- +Moves iterator forward by the specified offset. + +.. ocv:function:: FileNodeIterator& FileNodeIterator::operator +=( int ofs ) + + :param ofs: Offset (possibly negative) to move the iterator. + + +FileNodeIterator::operator -= +----------------------------- +Moves iterator backward by the specified offset (possibly negative). + +.. ocv:function:: FileNodeIterator& FileNodeIterator::operator -=( int ofs ) + + :param ofs: Offset (possibly negative) to move the iterator. + + +FileNodeIterator::readRaw +------------------------- +Reads node elements to the buffer with the specified format. + +.. ocv:function:: FileNodeIterator& FileNodeIterator::readRaw( const string& fmt, uchar* vec, size_t maxCount=(size_t)INT_MAX ) + + :param fmt: Specification of each array element. It has the same format as in :ocv:func:`FileStorage::writeRaw`. + + :param vec: Pointer to the destination array. + + :param maxCount: Number of elements to read. If it is greater than number of remaining elements then all of them will be read. + +Usually it is more convenient to use :ocv:func:`operator >>` instead of this method. diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/core.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/core.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/core.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/core.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,4789 @@ +/*! \file core.hpp + \brief The Core Functionality + */ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_HPP__ +#define __OPENCV_CORE_HPP__ + +#include "opencv2/core/types_c.h" +#include "opencv2/core/version.hpp" + +#ifdef __cplusplus + +#ifndef SKIP_INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // SKIP_INCLUDES + +/*! \namespace cv + Namespace where all the C++ OpenCV functionality resides +*/ +namespace cv { + +#undef abs +#undef min +#undef max +#undef Complex + +using std::vector; +using std::string; +using std::ptrdiff_t; + +template class CV_EXPORTS Size_; +template class CV_EXPORTS Point_; +template class CV_EXPORTS Rect_; +template class CV_EXPORTS Vec; +template class CV_EXPORTS Matx; + +typedef std::string String; + +class Mat; +class SparseMat; +typedef Mat MatND; + +namespace ogl { + class Buffer; + class Texture2D; + class Arrays; +} + +// < Deprecated +class GlBuffer; +class GlTexture; +class GlArrays; +class GlCamera; +// > + +namespace gpu { + class GpuMat; +} + +class CV_EXPORTS MatExpr; +class CV_EXPORTS MatOp_Base; +class CV_EXPORTS MatArg; +class CV_EXPORTS MatConstIterator; + +template class CV_EXPORTS Mat_; +template class CV_EXPORTS MatIterator_; +template class CV_EXPORTS MatConstIterator_; +template class CV_EXPORTS MatCommaInitializer_; + +#if !defined(ANDROID) || (defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T) +typedef std::basic_string WString; + +CV_EXPORTS string fromUtf16(const WString& str); +CV_EXPORTS WString toUtf16(const string& str); +#endif + +CV_EXPORTS string format( const char* fmt, ... ); +CV_EXPORTS string tempfile( const char* suffix CV_DEFAULT(0)); + +// matrix decomposition types +enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 }; +enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_L2SQR=5, NORM_HAMMING=6, NORM_HAMMING2=7, NORM_TYPE_MASK=7, NORM_RELATIVE=8, NORM_MINMAX=32 }; +enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 }; +enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 }; +enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32, + DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS }; + + +/*! + The standard OpenCV exception class. + Instances of the class are thrown by various functions and methods in the case of critical errors. + */ +class CV_EXPORTS Exception : public std::exception +{ +public: + /*! + Default constructor + */ + Exception(); + /*! + Full constructor. Normally the constuctor is not called explicitly. + Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used. + */ + Exception(int _code, const string& _err, const string& _func, const string& _file, int _line); + virtual ~Exception() throw(); + + /*! + \return the error description and the context as a text string. + */ + virtual const char *what() const throw(); + void formatMessage(); + + string msg; ///< the formatted error message + + int code; ///< error code @see CVStatus + string err; ///< error description + string func; ///< function name. Available only when the compiler supports __func__ macro + string file; ///< source file name where the error has occured + int line; ///< line number in the source file where the error has occured +}; + + +//! Signals an error and raises the exception. + +/*! + By default the function prints information about the error to stderr, + then it either stops if setBreakOnError() had been called before or raises the exception. + It is possible to alternate error processing by using redirectError(). + + \param exc the exception raisen. + */ +CV_EXPORTS void error( const Exception& exc ); + +//! Sets/resets the break-on-error mode. + +/*! + When the break-on-error mode is set, the default error handler + issues a hardware exception, which can make debugging more convenient. + + \return the previous state + */ +CV_EXPORTS bool setBreakOnError(bool flag); + +typedef int (CV_CDECL *ErrorCallback)( int status, const char* func_name, + const char* err_msg, const char* file_name, + int line, void* userdata ); + +//! Sets the new error handler and the optional user data. + +/*! + The function sets the new error handler, called from cv::error(). + + \param errCallback the new error handler. If NULL, the default error handler is used. + \param userdata the optional user data pointer, passed to the callback. + \param prevUserdata the optional output parameter where the previous user data pointer is stored + + \return the previous error handler +*/ +CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, + void* userdata=0, void** prevUserdata=0); + +#ifdef __GNUC__ +#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, __func__, __FILE__, __LINE__) ) +#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, __func__, __FILE__, __LINE__) ) +#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) ) +#else +#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, "", __FILE__, __LINE__) ) +#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, "", __FILE__, __LINE__) ) +#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) ) +#endif + +#ifdef _DEBUG +#define CV_DbgAssert(expr) CV_Assert(expr) +#else +#define CV_DbgAssert(expr) +#endif + +CV_EXPORTS void setNumThreads(int nthreads); +CV_EXPORTS int getNumThreads(); +CV_EXPORTS int getThreadNum(); + +CV_EXPORTS_W const string& getBuildInformation(); + +//! Returns the number of ticks. + +/*! + The function returns the number of ticks since the certain event (e.g. when the machine was turned on). + It can be used to initialize cv::RNG or to measure a function execution time by reading the tick count + before and after the function call. The granularity of ticks depends on the hardware and OS used. Use + cv::getTickFrequency() to convert ticks to seconds. +*/ +CV_EXPORTS_W int64 getTickCount(); + +/*! + Returns the number of ticks per seconds. + + The function returns the number of ticks (as returned by cv::getTickCount()) per second. + The following code computes the execution time in milliseconds: + + \code + double exec_time = (double)getTickCount(); + // do something ... + exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency(); + \endcode +*/ +CV_EXPORTS_W double getTickFrequency(); + +/*! + Returns the number of CPU ticks. + + On platforms where the feature is available, the function returns the number of CPU ticks + since the certain event (normally, the system power-on moment). Using this function + one can accurately measure the execution time of very small code fragments, + for which cv::getTickCount() granularity is not enough. +*/ +CV_EXPORTS_W int64 getCPUTickCount(); + +/*! + Returns SSE etc. support status + + The function returns true if certain hardware features are available. + Currently, the following features are recognized: + - CV_CPU_MMX - MMX + - CV_CPU_SSE - SSE + - CV_CPU_SSE2 - SSE 2 + - CV_CPU_SSE3 - SSE 3 + - CV_CPU_SSSE3 - SSSE 3 + - CV_CPU_SSE4_1 - SSE 4.1 + - CV_CPU_SSE4_2 - SSE 4.2 + - CV_CPU_POPCNT - POPCOUNT + - CV_CPU_AVX - AVX + + \note {Note that the function output is not static. Once you called cv::useOptimized(false), + most of the hardware acceleration is disabled and thus the function will returns false, + until you call cv::useOptimized(true)} +*/ +CV_EXPORTS_W bool checkHardwareSupport(int feature); + +//! returns the number of CPUs (including hyper-threading) +CV_EXPORTS_W int getNumberOfCPUs(); + +/*! + Allocates memory buffer + + This is specialized OpenCV memory allocation function that returns properly aligned memory buffers. + The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree(). + If there is not enough memory, the function calls cv::error(), which raises an exception. + + \param bufSize buffer size in bytes + \return the allocated memory buffer. +*/ +CV_EXPORTS void* fastMalloc(size_t bufSize); + +/*! + Frees the memory allocated with cv::fastMalloc + + This is the corresponding deallocation function for cv::fastMalloc(). + When ptr==NULL, the function has no effect. +*/ +CV_EXPORTS void fastFree(void* ptr); + +template static inline _Tp* allocate(size_t n) +{ + return new _Tp[n]; +} + +template static inline void deallocate(_Tp* ptr, size_t) +{ + delete[] ptr; +} + +/*! + Aligns pointer by the certain number of bytes + + This small inline function aligns the pointer by the certian number of bytes by shifting + it forward by 0 or a positive offset. +*/ +template static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp)) +{ + return (_Tp*)(((size_t)ptr + n-1) & -n); +} + +/*! + Aligns buffer size by the certain number of bytes + + This small inline function aligns a buffer size by the certian number of bytes by enlarging it. +*/ +static inline size_t alignSize(size_t sz, int n) +{ + return (sz + n-1) & -n; +} + +/*! + Turns on/off available optimization + + The function turns on or off the optimized code in OpenCV. Some optimization can not be enabled + or disabled, but, for example, most of SSE code in OpenCV can be temporarily turned on or off this way. + + \note{Since optimization may imply using special data structures, it may be unsafe + to call this function anywhere in the code. Instead, call it somewhere at the top level.} +*/ +CV_EXPORTS_W void setUseOptimized(bool onoff); + +/*! + Returns the current optimization status + + The function returns the current optimization status, which is controlled by cv::setUseOptimized(). +*/ +CV_EXPORTS_W bool useOptimized(); + +/*! + The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree() +*/ +template class CV_EXPORTS Allocator +{ +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template class rebind { typedef Allocator other; }; + + explicit Allocator() {} + ~Allocator() {} + explicit Allocator(Allocator const&) {} + template + explicit Allocator(Allocator const&) {} + + // address + pointer address(reference r) { return &r; } + const_pointer address(const_reference r) { return &r; } + + pointer allocate(size_type count, const void* =0) + { return reinterpret_cast(fastMalloc(count * sizeof (_Tp))); } + + void deallocate(pointer p, size_type) {fastFree(p); } + + size_type max_size() const + { return max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); } + + void construct(pointer p, const _Tp& v) { new(static_cast(p)) _Tp(v); } + void destroy(pointer p) { p->~_Tp(); } +}; + +/////////////////////// Vec (used as element of multi-channel images ///////////////////// + +/*! + A helper class for cv::DataType + + The class is specialized for each fundamental numerical data type supported by OpenCV. + It provides DataDepth::value constant. +*/ +template class CV_EXPORTS DataDepth {}; + +template<> class DataDepth { public: enum { value = CV_8U, fmt=(int)'u' }; }; +template<> class DataDepth { public: enum { value = CV_8U, fmt=(int)'u' }; }; +template<> class DataDepth { public: enum { value = CV_8S, fmt=(int)'c' }; }; +template<> class DataDepth { public: enum { value = CV_8S, fmt=(int)'c' }; }; +template<> class DataDepth { public: enum { value = CV_16U, fmt=(int)'w' }; }; +template<> class DataDepth { public: enum { value = CV_16S, fmt=(int)'s' }; }; +template<> class DataDepth { public: enum { value = CV_32S, fmt=(int)'i' }; }; +// this is temporary solution to support 32-bit unsigned integers +template<> class DataDepth { public: enum { value = CV_32S, fmt=(int)'i' }; }; +template<> class DataDepth { public: enum { value = CV_32F, fmt=(int)'f' }; }; +template<> class DataDepth { public: enum { value = CV_64F, fmt=(int)'d' }; }; +template class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; }; + + +////////////////////////////// Small Matrix /////////////////////////// + +/*! + A short numerical vector. + + This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) + on which you can perform basic arithmetical operations, access individual elements using [] operator etc. + The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., + which elements are dynamically allocated in the heap. + + The template takes 2 parameters: + -# _Tp element type + -# cn the number of elements + + In addition to the universal notation like Vec, you can use shorter aliases + for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. + */ + +struct CV_EXPORTS Matx_AddOp {}; +struct CV_EXPORTS Matx_SubOp {}; +struct CV_EXPORTS Matx_ScaleOp {}; +struct CV_EXPORTS Matx_MulOp {}; +struct CV_EXPORTS Matx_MatMulOp {}; +struct CV_EXPORTS Matx_TOp {}; + +template class CV_EXPORTS Matx +{ +public: + typedef _Tp value_type; + typedef Matx<_Tp, (m < n ? m : n), 1> diag_type; + typedef Matx<_Tp, m, n> mat_type; + enum { depth = DataDepth<_Tp>::value, rows = m, cols = n, channels = rows*cols, + type = CV_MAKETYPE(depth, channels) }; + + //! default constructor + Matx(); + + Matx(_Tp v0); //!< 1x1 matrix + Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11, + _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix + explicit Matx(const _Tp* vals); //!< initialize from a plain array + + static Matx all(_Tp alpha); + static Matx zeros(); + static Matx ones(); + static Matx eye(); + static Matx diag(const diag_type& d); + static Matx randu(_Tp a, _Tp b); + static Matx randn(_Tp a, _Tp b); + + //! dot product computed with the default precision + _Tp dot(const Matx<_Tp, m, n>& v) const; + + //! dot product computed in double-precision arithmetics + double ddot(const Matx<_Tp, m, n>& v) const; + + //! convertion to another data type + template operator Matx() const; + + //! change the matrix shape + template Matx<_Tp, m1, n1> reshape() const; + + //! extract part of the matrix + template Matx<_Tp, m1, n1> get_minor(int i, int j) const; + + //! extract the matrix row + Matx<_Tp, 1, n> row(int i) const; + + //! extract the matrix column + Matx<_Tp, m, 1> col(int i) const; + + //! extract the matrix diagonal + diag_type diag() const; + + //! transpose the matrix + Matx<_Tp, n, m> t() const; + + //! invert matrix the matrix + Matx<_Tp, n, m> inv(int method=DECOMP_LU) const; + + //! solve linear system + template Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const; + Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const; + + //! multiply two matrices element-wise + Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const; + + //! element access + const _Tp& operator ()(int i, int j) const; + _Tp& operator ()(int i, int j); + + //! 1D element access + const _Tp& operator ()(int i) const; + _Tp& operator ()(int i); + + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp); + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp); + template Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp); + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp); + template Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp); + Matx(const Matx<_Tp, n, m>& a, Matx_TOp); + + _Tp val[m*n]; //< matrix elements +}; + + +typedef Matx Matx12f; +typedef Matx Matx12d; +typedef Matx Matx13f; +typedef Matx Matx13d; +typedef Matx Matx14f; +typedef Matx Matx14d; +typedef Matx Matx16f; +typedef Matx Matx16d; + +typedef Matx Matx21f; +typedef Matx Matx21d; +typedef Matx Matx31f; +typedef Matx Matx31d; +typedef Matx Matx41f; +typedef Matx Matx41d; +typedef Matx Matx61f; +typedef Matx Matx61d; + +typedef Matx Matx22f; +typedef Matx Matx22d; +typedef Matx Matx23f; +typedef Matx Matx23d; +typedef Matx Matx32f; +typedef Matx Matx32d; + +typedef Matx Matx33f; +typedef Matx Matx33d; + +typedef Matx Matx34f; +typedef Matx Matx34d; +typedef Matx Matx43f; +typedef Matx Matx43d; + +typedef Matx Matx44f; +typedef Matx Matx44d; +typedef Matx Matx66f; +typedef Matx Matx66d; + + +/*! + A short numerical vector. + + This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) + on which you can perform basic arithmetical operations, access individual elements using [] operator etc. + The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., + which elements are dynamically allocated in the heap. + + The template takes 2 parameters: + -# _Tp element type + -# cn the number of elements + + In addition to the universal notation like Vec, you can use shorter aliases + for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. +*/ +template class CV_EXPORTS Vec : public Matx<_Tp, cn, 1> +{ +public: + typedef _Tp value_type; + enum { depth = DataDepth<_Tp>::value, channels = cn, type = CV_MAKETYPE(depth, channels) }; + + //! default constructor + Vec(); + + Vec(_Tp v0); //!< 1-element vector constructor + Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor + explicit Vec(const _Tp* values); + + Vec(const Vec<_Tp, cn>& v); + + static Vec all(_Tp alpha); + + //! per-element multiplication + Vec mul(const Vec<_Tp, cn>& v) const; + + //! conjugation (makes sense for complex numbers and quaternions) + Vec conj() const; + + /*! + cross product of the two 3D vectors. + + For other dimensionalities the exception is raised + */ + Vec cross(const Vec& v) const; + //! convertion to another data type + template operator Vec() const; + //! conversion to 4-element CvScalar. + operator CvScalar() const; + + /*! element access */ + const _Tp& operator [](int i) const; + _Tp& operator[](int i); + const _Tp& operator ()(int i) const; + _Tp& operator ()(int i); + + Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp); + Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp); + template Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp); +}; + + +/* \typedef + + Shorter aliases for the most popular specializations of Vec +*/ +typedef Vec Vec2b; +typedef Vec Vec3b; +typedef Vec Vec4b; + +typedef Vec Vec2s; +typedef Vec Vec3s; +typedef Vec Vec4s; + +typedef Vec Vec2w; +typedef Vec Vec3w; +typedef Vec Vec4w; + +typedef Vec Vec2i; +typedef Vec Vec3i; +typedef Vec Vec4i; +typedef Vec Vec6i; +typedef Vec Vec8i; + +typedef Vec Vec2f; +typedef Vec Vec3f; +typedef Vec Vec4f; +typedef Vec Vec6f; + +typedef Vec Vec2d; +typedef Vec Vec3d; +typedef Vec Vec4d; +typedef Vec Vec6d; + + +//////////////////////////////// Complex ////////////////////////////// + +/*! + A complex number class. + + The template class is similar and compatible with std::complex, however it provides slightly + more convenient access to the real and imaginary parts using through the simple field access, as opposite + to std::complex::real() and std::complex::imag(). +*/ +template class CV_EXPORTS Complex +{ +public: + + //! constructors + Complex(); + Complex( _Tp _re, _Tp _im=0 ); + Complex( const std::complex<_Tp>& c ); + + //! conversion to another data type + template operator Complex() const; + //! conjugation + Complex conj() const; + //! conversion to std::complex + operator std::complex<_Tp>() const; + + _Tp re, im; //< the real and the imaginary parts +}; + + +/*! + \typedef +*/ +typedef Complex Complexf; +typedef Complex Complexd; + + +//////////////////////////////// Point_ //////////////////////////////// + +/*! + template 2D point class. + + The class defines a point in 2D space. Data type of the point coordinates is specified + as a template parameter. There are a few shorter aliases available for user convenience. + See cv::Point, cv::Point2i, cv::Point2f and cv::Point2d. +*/ +template class CV_EXPORTS Point_ +{ +public: + typedef _Tp value_type; + + // various constructors + Point_(); + Point_(_Tp _x, _Tp _y); + Point_(const Point_& pt); + Point_(const CvPoint& pt); + Point_(const CvPoint2D32f& pt); + Point_(const Size_<_Tp>& sz); + Point_(const Vec<_Tp, 2>& v); + + Point_& operator = (const Point_& pt); + //! conversion to another data type + template operator Point_<_Tp2>() const; + + //! conversion to the old-style C structures + operator CvPoint() const; + operator CvPoint2D32f() const; + operator Vec<_Tp, 2>() const; + + //! dot product + _Tp dot(const Point_& pt) const; + //! dot product computed in double-precision arithmetics + double ddot(const Point_& pt) const; + //! cross-product + double cross(const Point_& pt) const; + //! checks whether the point is inside the specified rectangle + bool inside(const Rect_<_Tp>& r) const; + + _Tp x, y; //< the point coordinates +}; + +/*! + template 3D point class. + + The class defines a point in 3D space. Data type of the point coordinates is specified + as a template parameter. + + \see cv::Point3i, cv::Point3f and cv::Point3d +*/ +template class CV_EXPORTS Point3_ +{ +public: + typedef _Tp value_type; + + // various constructors + Point3_(); + Point3_(_Tp _x, _Tp _y, _Tp _z); + Point3_(const Point3_& pt); + explicit Point3_(const Point_<_Tp>& pt); + Point3_(const CvPoint3D32f& pt); + Point3_(const Vec<_Tp, 3>& v); + + Point3_& operator = (const Point3_& pt); + //! conversion to another data type + template operator Point3_<_Tp2>() const; + //! conversion to the old-style CvPoint... + operator CvPoint3D32f() const; + //! conversion to cv::Vec<> + operator Vec<_Tp, 3>() const; + + //! dot product + _Tp dot(const Point3_& pt) const; + //! dot product computed in double-precision arithmetics + double ddot(const Point3_& pt) const; + //! cross product of the 2 3D points + Point3_ cross(const Point3_& pt) const; + + _Tp x, y, z; //< the point coordinates +}; + +//////////////////////////////// Size_ //////////////////////////////// + +/*! + The 2D size class + + The class represents the size of a 2D rectangle, image size, matrix size etc. + Normally, cv::Size ~ cv::Size_ is used. +*/ +template class CV_EXPORTS Size_ +{ +public: + typedef _Tp value_type; + + //! various constructors + Size_(); + Size_(_Tp _width, _Tp _height); + Size_(const Size_& sz); + Size_(const CvSize& sz); + Size_(const CvSize2D32f& sz); + Size_(const Point_<_Tp>& pt); + + Size_& operator = (const Size_& sz); + //! the area (width*height) + _Tp area() const; + + //! conversion of another data type. + template operator Size_<_Tp2>() const; + + //! conversion to the old-style OpenCV types + operator CvSize() const; + operator CvSize2D32f() const; + + _Tp width, height; // the width and the height +}; + +//////////////////////////////// Rect_ //////////////////////////////// + +/*! + The 2D up-right rectangle class + + The class represents a 2D rectangle with coordinates of the specified data type. + Normally, cv::Rect ~ cv::Rect_ is used. +*/ +template class CV_EXPORTS Rect_ +{ +public: + typedef _Tp value_type; + + //! various constructors + Rect_(); + Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height); + Rect_(const Rect_& r); + Rect_(const CvRect& r); + Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz); + Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2); + + Rect_& operator = ( const Rect_& r ); + //! the top-left corner + Point_<_Tp> tl() const; + //! the bottom-right corner + Point_<_Tp> br() const; + + //! size (width, height) of the rectangle + Size_<_Tp> size() const; + //! area (width*height) of the rectangle + _Tp area() const; + + //! conversion to another data type + template operator Rect_<_Tp2>() const; + //! conversion to the old-style CvRect + operator CvRect() const; + + //! checks whether the rectangle contains the point + bool contains(const Point_<_Tp>& pt) const; + + _Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle +}; + + +/*! + \typedef + + shorter aliases for the most popular cv::Point_<>, cv::Size_<> and cv::Rect_<> specializations +*/ +typedef Point_ Point2i; +typedef Point2i Point; +typedef Size_ Size2i; +typedef Size2i Size; +typedef Rect_ Rect; +typedef Point_ Point2f; +typedef Point_ Point2d; +typedef Size_ Size2f; +typedef Point3_ Point3i; +typedef Point3_ Point3f; +typedef Point3_ Point3d; + + +/*! + The rotated 2D rectangle. + + The class represents rotated (i.e. not up-right) rectangles on a plane. + Each rectangle is described by the center point (mass center), length of each side + (represented by cv::Size2f structure) and the rotation angle in degrees. +*/ +class CV_EXPORTS RotatedRect +{ +public: + //! various constructors + RotatedRect(); + RotatedRect(const Point2f& center, const Size2f& size, float angle); + RotatedRect(const CvBox2D& box); + + //! returns 4 vertices of the rectangle + void points(Point2f pts[]) const; + //! returns the minimal up-right rectangle containing the rotated rectangle + Rect boundingRect() const; + //! conversion to the old-style CvBox2D structure + operator CvBox2D() const; + + Point2f center; //< the rectangle mass center + Size2f size; //< width and height of the rectangle + float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle. +}; + +//////////////////////////////// Scalar_ /////////////////////////////// + +/*! + The template scalar class. + + This is partially specialized cv::Vec class with the number of elements = 4, i.e. a short vector of four elements. + Normally, cv::Scalar ~ cv::Scalar_ is used. +*/ +template class CV_EXPORTS Scalar_ : public Vec<_Tp, 4> +{ +public: + //! various constructors + Scalar_(); + Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0); + Scalar_(const CvScalar& s); + Scalar_(_Tp v0); + + //! returns a scalar with all elements set to v0 + static Scalar_<_Tp> all(_Tp v0); + //! conversion to the old-style CvScalar + operator CvScalar() const; + + //! conversion to another data type + template operator Scalar_() const; + + //! per-element product + Scalar_<_Tp> mul(const Scalar_<_Tp>& t, double scale=1 ) const; + + // returns (v0, -v1, -v2, -v3) + Scalar_<_Tp> conj() const; + + // returns true iff v1 == v2 == v3 == 0 + bool isReal() const; +}; + +typedef Scalar_ Scalar; + +CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0); + +//////////////////////////////// Range ///////////////////////////////// + +/*! + The 2D range class + + This is the class used to specify a continuous subsequence, i.e. part of a contour, or a column span in a matrix. +*/ +class CV_EXPORTS Range +{ +public: + Range(); + Range(int _start, int _end); + Range(const CvSlice& slice); + int size() const; + bool empty() const; + static Range all(); + operator CvSlice() const; + + int start, end; +}; + +/////////////////////////////// DataType //////////////////////////////// + +/*! + Informative template class for OpenCV "scalars". + + The class is specialized for each primitive numerical type supported by OpenCV (such as unsigned char or float), + as well as for more complex types, like cv::Complex<>, std::complex<>, cv::Vec<> etc. + The common property of all such types (called "scalars", do not confuse it with cv::Scalar_) + is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented + by the depth id (CV_8U ... CV_64F) and the number of channels. + OpenCV matrices, 2D or nD, dense or sparse, can store "scalars", + as long as the number of channels does not exceed CV_CN_MAX. +*/ +template class DataType +{ +public: + typedef _Tp value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 1, depth = -1, channels = 1, fmt=0, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef bool value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef uchar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef schar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef schar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef ushort value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef short value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef int value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef float value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template<> class DataType +{ +public: + typedef double value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 1, + fmt=DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template class DataType > +{ +public: + typedef Matx<_Tp, m, n> value_type; + typedef Matx::work_type, m, n> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = m*n, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template class DataType > +{ +public: + typedef Vec<_Tp, cn> value_type; + typedef Vec::work_type, cn> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + enum { generic_type = 0, depth = DataDepth::value, channels = cn, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; +}; + +template class DataType > +{ +public: + typedef std::complex<_Tp> value_type; + typedef value_type work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 2, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Complex<_Tp> value_type; + typedef value_type work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 2, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Point_<_Tp> value_type; + typedef Point_::work_type> work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 2, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Point3_<_Tp> value_type; + typedef Point3_::work_type> work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 3, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Size_<_Tp> value_type; + typedef Size_::work_type> work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 2, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Rect_<_Tp> value_type; + typedef Rect_::work_type> work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 4, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template class DataType > +{ +public: + typedef Scalar_<_Tp> value_type; + typedef Scalar_::work_type> work_type; + typedef _Tp channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 4, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +template<> class DataType +{ +public: + typedef Range value_type; + typedef value_type work_type; + typedef int channel_type; + enum { generic_type = 0, depth = DataDepth::value, channels = 2, + fmt = ((channels-1)<<8) + DataDepth::fmt, + type = CV_MAKETYPE(depth, channels) }; + typedef Vec vec_type; +}; + +//////////////////// generic_type ref-counting pointer class for C/C++ objects //////////////////////// + +/*! + Smart pointer to dynamically allocated objects. + + This is template pointer-wrapping class that stores the associated reference counter along with the + object pointer. The class is similar to std::smart_ptr<> from the recent addons to the C++ standard, + but is shorter to write :) and self-contained (i.e. does add any dependency on the compiler or an external library). + + Basically, you can use "Ptr ptr" (or faster "const Ptr& ptr" for read-only access) + everywhere instead of "MyObjectType* ptr", where MyObjectType is some C structure or a C++ class. + To make it all work, you need to specialize Ptr<>::delete_obj(), like: + + \code + template<> void Ptr::delete_obj() { call_destructor_func(obj); } + \endcode + + \note{if MyObjectType is a C++ class with a destructor, you do not need to specialize delete_obj(), + since the default implementation calls "delete obj;"} + + \note{Another good property of the class is that the operations on the reference counter are atomic, + i.e. it is safe to use the class in multi-threaded applications} +*/ +template class CV_EXPORTS Ptr +{ +public: + //! empty constructor + Ptr(); + //! take ownership of the pointer. The associated reference counter is allocated and set to 1 + Ptr(_Tp* _obj); + //! calls release() + ~Ptr(); + //! copy constructor. Copies the members and calls addref() + Ptr(const Ptr& ptr); + template Ptr(const Ptr<_Tp2>& ptr); + //! copy operator. Calls ptr.addref() and release() before copying the members + Ptr& operator = (const Ptr& ptr); + //! increments the reference counter + void addref(); + //! decrements the reference counter. If it reaches 0, delete_obj() is called + void release(); + //! deletes the object. Override if needed + void delete_obj(); + //! returns true iff obj==NULL + bool empty() const; + + //! cast pointer to another type + template Ptr<_Tp2> ptr(); + template const Ptr<_Tp2> ptr() const; + + //! helper operators making "Ptr ptr" use very similar to "T* ptr". + _Tp* operator -> (); + const _Tp* operator -> () const; + + operator _Tp* (); + operator const _Tp*() const; + + _Tp* obj; //< the object pointer. + int* refcount; //< the associated reference counter +}; + + +//////////////////////// Input/Output Array Arguments ///////////////////////////////// + +/*! + Proxy datatype for passing Mat's and vector<>'s as input parameters + */ +class CV_EXPORTS _InputArray +{ +public: + enum { + KIND_SHIFT = 16, + FIXED_TYPE = 0x8000 << KIND_SHIFT, + FIXED_SIZE = 0x4000 << KIND_SHIFT, + KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1, + + NONE = 0 << KIND_SHIFT, + MAT = 1 << KIND_SHIFT, + MATX = 2 << KIND_SHIFT, + STD_VECTOR = 3 << KIND_SHIFT, + STD_VECTOR_VECTOR = 4 << KIND_SHIFT, + STD_VECTOR_MAT = 5 << KIND_SHIFT, + EXPR = 6 << KIND_SHIFT, + OPENGL_BUFFER = 7 << KIND_SHIFT, + OPENGL_TEXTURE = 8 << KIND_SHIFT, + GPU_MAT = 9 << KIND_SHIFT + }; + _InputArray(); + + _InputArray(const Mat& m); + _InputArray(const MatExpr& expr); + template _InputArray(const _Tp* vec, int n); + template _InputArray(const vector<_Tp>& vec); + template _InputArray(const vector >& vec); + _InputArray(const vector& vec); + template _InputArray(const vector >& vec); + template _InputArray(const Mat_<_Tp>& m); + template _InputArray(const Matx<_Tp, m, n>& matx); + _InputArray(const Scalar& s); + _InputArray(const double& val); + // < Deprecated + _InputArray(const GlBuffer& buf); + _InputArray(const GlTexture& tex); + // > + _InputArray(const gpu::GpuMat& d_mat); + _InputArray(const ogl::Buffer& buf); + _InputArray(const ogl::Texture2D& tex); + + virtual Mat getMat(int i=-1) const; + virtual void getMatVector(vector& mv) const; + // < Deprecated + virtual GlBuffer getGlBuffer() const; + virtual GlTexture getGlTexture() const; + // > + virtual gpu::GpuMat getGpuMat() const; + /*virtual*/ ogl::Buffer getOGlBuffer() const; + /*virtual*/ ogl::Texture2D getOGlTexture2D() const; + + virtual int kind() const; + virtual Size size(int i=-1) const; + virtual size_t total(int i=-1) const; + virtual int type(int i=-1) const; + virtual int depth(int i=-1) const; + virtual int channels(int i=-1) const; + virtual bool empty() const; + +#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY + virtual ~_InputArray(); +#endif + + int flags; + void* obj; + Size sz; +}; + + +enum +{ + DEPTH_MASK_8U = 1 << CV_8U, + DEPTH_MASK_8S = 1 << CV_8S, + DEPTH_MASK_16U = 1 << CV_16U, + DEPTH_MASK_16S = 1 << CV_16S, + DEPTH_MASK_32S = 1 << CV_32S, + DEPTH_MASK_32F = 1 << CV_32F, + DEPTH_MASK_64F = 1 << CV_64F, + DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1, + DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S, + DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F +}; + + +/*! + Proxy datatype for passing Mat's and vector<>'s as input parameters + */ +class CV_EXPORTS _OutputArray : public _InputArray +{ +public: + _OutputArray(); + + _OutputArray(Mat& m); + template _OutputArray(vector<_Tp>& vec); + template _OutputArray(vector >& vec); + _OutputArray(vector& vec); + template _OutputArray(vector >& vec); + template _OutputArray(Mat_<_Tp>& m); + template _OutputArray(Matx<_Tp, m, n>& matx); + template _OutputArray(_Tp* vec, int n); + _OutputArray(gpu::GpuMat& d_mat); + _OutputArray(ogl::Buffer& buf); + _OutputArray(ogl::Texture2D& tex); + + _OutputArray(const Mat& m); + template _OutputArray(const vector<_Tp>& vec); + template _OutputArray(const vector >& vec); + _OutputArray(const vector& vec); + template _OutputArray(const vector >& vec); + template _OutputArray(const Mat_<_Tp>& m); + template _OutputArray(const Matx<_Tp, m, n>& matx); + template _OutputArray(const _Tp* vec, int n); + _OutputArray(const gpu::GpuMat& d_mat); + _OutputArray(const ogl::Buffer& buf); + _OutputArray(const ogl::Texture2D& tex); + + virtual bool fixedSize() const; + virtual bool fixedType() const; + virtual bool needed() const; + virtual Mat& getMatRef(int i=-1) const; + /*virtual*/ gpu::GpuMat& getGpuMatRef() const; + /*virtual*/ ogl::Buffer& getOGlBufferRef() const; + /*virtual*/ ogl::Texture2D& getOGlTexture2DRef() const; + virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void release() const; + virtual void clear() const; + +#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY + virtual ~_OutputArray(); +#endif +}; + +typedef const _InputArray& InputArray; +typedef InputArray InputArrayOfArrays; +typedef const _OutputArray& OutputArray; +typedef OutputArray OutputArrayOfArrays; +typedef OutputArray InputOutputArray; +typedef OutputArray InputOutputArrayOfArrays; + +CV_EXPORTS OutputArray noArray(); + +/////////////////////////////////////// Mat /////////////////////////////////////////// + +enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 }; + +static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); } + +/*! + Custom array allocator + +*/ +class CV_EXPORTS MatAllocator +{ +public: + MatAllocator() {} + virtual ~MatAllocator() {} + virtual void allocate(int dims, const int* sizes, int type, int*& refcount, + uchar*& datastart, uchar*& data, size_t* step) = 0; + virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0; +}; + +/*! + The n-dimensional matrix class. + + The class represents an n-dimensional dense numerical array that can act as + a matrix, image, optical flow map, 3-focal tensor etc. + It is very similar to CvMat and CvMatND types from earlier versions of OpenCV, + and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism. + + There are many different ways to create cv::Mat object. Here are the some popular ones: +
    +
  • using cv::Mat::create(nrows, ncols, type) method or + the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor. + A new matrix of the specified size and specifed type will be allocated. + "type" has the same meaning as in cvCreateMat function, + e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex) + floating-point matrix etc: + + \code + // make 7x7 complex matrix filled with 1+3j. + cv::Mat M(7,7,CV_32FC2,Scalar(1,3)); + // and now turn M to 100x60 15-channel 8-bit matrix. + // The old content will be deallocated + M.create(100,60,CV_8UC(15)); + \endcode + + As noted in the introduction of this chapter, Mat::create() + will only allocate a new matrix when the current matrix dimensionality + or type are different from the specified. + +
  • by using a copy constructor or assignment operator, where on the right side it can + be a matrix or expression, see below. Again, as noted in the introduction, + matrix assignment is O(1) operation because it only copies the header + and increases the reference counter. cv::Mat::clone() method can be used to get a full + (a.k.a. deep) copy of the matrix when you need it. + +
  • by constructing a header for a part of another matrix. It can be a single row, single column, + several rows, several columns, rectangular region in the matrix (called a minor in algebra) or + a diagonal. Such operations are also O(1), because the new header will reference the same data. + You can actually modify a part of the matrix using this feature, e.g. + + \code + // add 5-th row, multiplied by 3 to the 3rd row + M.row(3) = M.row(3) + M.row(5)*3; + + // now copy 7-th column to the 1-st column + // M.col(1) = M.col(7); // this will not work + Mat M1 = M.col(1); + M.col(7).copyTo(M1); + + // create new 320x240 image + cv::Mat img(Size(320,240),CV_8UC3); + // select a roi + cv::Mat roi(img, Rect(10,10,100,100)); + // fill the ROI with (0,255,0) (which is green in RGB space); + // the original 320x240 image will be modified + roi = Scalar(0,255,0); + \endcode + + Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to + compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI(): + + \code + Mat A = Mat::eye(10, 10, CV_32S); + // extracts A columns, 1 (inclusive) to 3 (exclusive). + Mat B = A(Range::all(), Range(1, 3)); + // extracts B rows, 5 (inclusive) to 9 (exclusive). + // that is, C ~ A(Range(5, 9), Range(1, 3)) + Mat C = B(Range(5, 9), Range::all()); + Size size; Point ofs; + C.locateROI(size, ofs); + // size will be (width=10,height=10) and the ofs will be (x=1, y=5) + \endcode + + As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method + of the extracted sub-matrices. + +
  • by making a header for user-allocated-data. It can be useful for +
      +
    1. processing "foreign" data using OpenCV (e.g. when you implement + a DirectShow filter or a processing module for gstreamer etc.), e.g. + + \code + void process_video_frame(const unsigned char* pixels, + int width, int height, int step) + { + cv::Mat img(height, width, CV_8UC3, pixels, step); + cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5); + } + \endcode + +
    2. for quick initialization of small matrices and/or super-fast element access + + \code + double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; + cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv(); + \endcode +
    + + partial yet very common cases of this "user-allocated data" case are conversions + from CvMat and IplImage to cv::Mat. For this purpose there are special constructors + taking pointers to CvMat or IplImage and the optional + flag indicating whether to copy the data or not. + + Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators + cv::Mat::operator CvMat() an cv::Mat::operator IplImage(). + The operators do not copy the data. + + + \code + IplImage* img = cvLoadImage("greatwave.jpg", 1); + Mat mtx(img); // convert IplImage* -> cv::Mat + CvMat oldmat = mtx; // convert cv::Mat -> CvMat + CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && + oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); + \endcode + +
  • by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.: + + \code + // create a double-precision identity martix and add it to M. + M += Mat::eye(M.rows, M.cols, CV_64F); + \endcode + +
  • by using comma-separated initializer: + + \code + // create 3x3 double-precision identity matrix + Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); + \endcode + + here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix, + and then we just put "<<" operator followed by comma-separated values that can be constants, + variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors. + +
+ + Once matrix is created, it will be automatically managed by using reference-counting mechanism + (unless the matrix header is built on top of user-allocated data, + in which case you should handle the data by yourself). + The matrix data will be deallocated when no one points to it; + if you want to release the data pointed by a matrix header before the matrix destructor is called, + use cv::Mat::release(). + + The next important thing to learn about the matrix class is element access. Here is how the matrix is stored. + The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row, + cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member, + cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be + a part of another matrix or because there can some padding space in the end of each row for a proper alignment. + + \image html roi.png + + Given these parameters, address of the matrix element M_{ij} is computed as following: + + addr(M_{ij})=M.data + M.step*i + j*M.elemSize() + + if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method: + + addr(M_{ij})=&M.at(i,j) + + (where & is used to convert the reference returned by cv::Mat::at() to a pointer). + if you need to process a whole row of matrix, the most efficient way is to get + the pointer to the row first, and then just use plain C operator []: + + \code + // compute sum of positive matrix elements + // (assuming that M is double-precision matrix) + double sum=0; + for(int i = 0; i < M.rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < M.cols; j++) + sum += std::max(Mi[j], 0.); + } + \endcode + + Some operations, like the above one, do not actually depend on the matrix shape, + they just process elements of a matrix one by one (or elements from multiple matrices + that are sitting in the same place, e.g. matrix addition). Such operations are called + element-wise and it makes sense to check whether all the input/output matrices are continuous, + i.e. have no gaps in the end of each row, and if yes, process them as a single long row: + + \code + // compute sum of positive matrix elements, optimized variant + double sum=0; + int cols = M.cols, rows = M.rows; + if(M.isContinuous()) + { + cols *= rows; + rows = 1; + } + for(int i = 0; i < rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < cols; j++) + sum += std::max(Mi[j], 0.); + } + \endcode + in the case of continuous matrix the outer loop body will be executed just once, + so the overhead will be smaller, which will be especially noticeable in the case of small matrices. + + Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: + \code + // compute sum of positive matrix elements, iterator-based variant + double sum=0; + MatConstIterator_ it = M.begin(), it_end = M.end(); + for(; it != it_end; ++it) + sum += std::max(*it, 0.); + \endcode + + The matrix iterators are random-access iterators, so they can be passed + to any STL algorithm, including std::sort(). +*/ +class CV_EXPORTS Mat +{ +public: + //! default constructor + Mat(); + //! constructs 2D matrix of the specified size and type + // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + Mat(int rows, int cols, int type); + Mat(Size size, int type); + //! constucts 2D matrix and fills it with the specified value _s. + Mat(int rows, int cols, int type, const Scalar& s); + Mat(Size size, int type, const Scalar& s); + + //! constructs n-dimensional matrix + Mat(int ndims, const int* sizes, int type); + Mat(int ndims, const int* sizes, int type, const Scalar& s); + + //! copy constructor + Mat(const Mat& m); + //! constructor for matrix headers pointing to user-allocated data + Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); + Mat(Size size, int type, void* data, size_t step=AUTO_STEP); + Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); + + //! creates a matrix header for a part of the bigger matrix + Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); + Mat(const Mat& m, const Rect& roi); + Mat(const Mat& m, const Range* ranges); + //! converts old-style CvMat to the new matrix; the data is not copied by default + Mat(const CvMat* m, bool copyData=false); + //! converts old-style CvMatND to the new matrix; the data is not copied by default + Mat(const CvMatND* m, bool copyData=false); + //! converts old-style IplImage to the new matrix; the data is not copied by default + Mat(const IplImage* img, bool copyData=false); + //! builds matrix from std::vector with or without copying the data + template explicit Mat(const vector<_Tp>& vec, bool copyData=false); + //! builds matrix from cv::Vec; the data is copied by default + template explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); + //! builds matrix from cv::Matx; the data is copied by default + template explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); + //! builds matrix from a 2D point + template explicit Mat(const Point_<_Tp>& pt, bool copyData=true); + //! builds matrix from a 3D point + template explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); + //! builds matrix from comma initializer + template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); + + //! download data from GpuMat + explicit Mat(const gpu::GpuMat& m); + + //! destructor - calls release() + ~Mat(); + //! assignment operators + Mat& operator = (const Mat& m); + Mat& operator = (const MatExpr& expr); + + //! returns a new matrix header for the specified row + Mat row(int y) const; + //! returns a new matrix header for the specified column + Mat col(int x) const; + //! ... for the specified row span + Mat rowRange(int startrow, int endrow) const; + Mat rowRange(const Range& r) const; + //! ... for the specified column span + Mat colRange(int startcol, int endcol) const; + Mat colRange(const Range& r) const; + //! ... for the specified diagonal + // (d=0 - the main diagonal, + // >0 - a diagonal from the lower half, + // <0 - a diagonal from the upper half) + Mat diag(int d=0) const; + //! constructs a square diagonal matrix which main diagonal is vector "d" + static Mat diag(const Mat& d); + + //! returns deep copy of the matrix, i.e. the data is copied + Mat clone() const; + //! copies the matrix content to "m". + // It calls m.create(this->size(), this->type()). + void copyTo( OutputArray m ) const; + //! copies those matrix elements to "m" that are marked with non-zero mask elements. + void copyTo( OutputArray m, InputArray mask ) const; + //! converts matrix to another datatype with optional scalng. See cvConvertScale. + void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; + + void assignTo( Mat& m, int type=-1 ) const; + + //! sets every matrix element to s + Mat& operator = (const Scalar& s); + //! sets some of the matrix elements to s, according to the mask + Mat& setTo(InputArray value, InputArray mask=noArray()); + //! creates alternative matrix header for the same data, with different + // number of channels and/or different number of rows. see cvReshape. + Mat reshape(int cn, int rows=0) const; + Mat reshape(int cn, int newndims, const int* newsz) const; + + //! matrix transposition by means of matrix expressions + MatExpr t() const; + //! matrix inversion by means of matrix expressions + MatExpr inv(int method=DECOMP_LU) const; + //! per-element matrix multiplication by means of matrix expressions + MatExpr mul(InputArray m, double scale=1) const; + + //! computes cross-product of 2 3D vectors + Mat cross(InputArray m) const; + //! computes dot-product + double dot(InputArray m) const; + + //! Matlab-style matrix initialization + static MatExpr zeros(int rows, int cols, int type); + static MatExpr zeros(Size size, int type); + static MatExpr zeros(int ndims, const int* sz, int type); + static MatExpr ones(int rows, int cols, int type); + static MatExpr ones(Size size, int type); + static MatExpr ones(int ndims, const int* sz, int type); + static MatExpr eye(int rows, int cols, int type); + static MatExpr eye(Size size, int type); + + //! allocates new matrix data unless the matrix already has specified size and type. + // previous data is unreferenced if needed. + void create(int rows, int cols, int type); + void create(Size size, int type); + void create(int ndims, const int* sizes, int type); + + //! increases the reference counter; use with care to avoid memleaks + void addref(); + //! decreases reference counter; + // deallocates the data when reference counter reaches 0. + void release(); + + //! deallocates the matrix data + void deallocate(); + //! internal use function; properly re-allocates _size, _step arrays + void copySize(const Mat& m); + + //! reserves enough space to fit sz hyper-planes + void reserve(size_t sz); + //! resizes matrix to the specified number of hyper-planes + void resize(size_t sz); + //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements + void resize(size_t sz, const Scalar& s); + //! internal function + void push_back_(const void* elem); + //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) + template void push_back(const _Tp& elem); + template void push_back(const Mat_<_Tp>& elem); + void push_back(const Mat& m); + //! removes several hyper-planes from bottom of the matrix + void pop_back(size_t nelems=1); + + //! locates matrix header within a parent matrix. See below + void locateROI( Size& wholeSize, Point& ofs ) const; + //! moves/resizes the current matrix ROI inside the parent matrix. + Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); + //! extracts a rectangular sub-matrix + // (this is a generalized form of row, rowRange etc.) + Mat operator()( Range rowRange, Range colRange ) const; + Mat operator()( const Rect& roi ) const; + Mat operator()( const Range* ranges ) const; + + //! converts header to CvMat; no data is copied + operator CvMat() const; + //! converts header to CvMatND; no data is copied + operator CvMatND() const; + //! converts header to IplImage; no data is copied + operator IplImage() const; + + template operator vector<_Tp>() const; + template operator Vec<_Tp, n>() const; + template operator Matx<_Tp, m, n>() const; + + //! returns true iff the matrix data is continuous + // (i.e. when there are no gaps between successive rows). + // similar to CV_IS_MAT_CONT(cvmat->type) + bool isContinuous() const; + + //! returns true if the matrix is a submatrix of another matrix + bool isSubmatrix() const; + + //! returns element size in bytes, + // similar to CV_ELEM_SIZE(cvmat->type) + size_t elemSize() const; + //! returns the size of element channel in bytes. + size_t elemSize1() const; + //! returns element type, similar to CV_MAT_TYPE(cvmat->type) + int type() const; + //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) + int depth() const; + //! returns element type, similar to CV_MAT_CN(cvmat->type) + int channels() const; + //! returns step/elemSize1() + size_t step1(int i=0) const; + //! returns true if matrix data is NULL + bool empty() const; + //! returns the total number of matrix elements + size_t total() const; + + //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise + int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; + + //! returns pointer to i0-th submatrix along the dimension #0 + uchar* ptr(int i0=0); + const uchar* ptr(int i0=0) const; + + //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 + uchar* ptr(int i0, int i1); + const uchar* ptr(int i0, int i1) const; + + //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 + uchar* ptr(int i0, int i1, int i2); + const uchar* ptr(int i0, int i1, int i2) const; + + //! returns pointer to the matrix element + uchar* ptr(const int* idx); + //! returns read-only pointer to the matrix element + const uchar* ptr(const int* idx) const; + + template uchar* ptr(const Vec& idx); + template const uchar* ptr(const Vec& idx) const; + + //! template version of the above method + template _Tp* ptr(int i0=0); + template const _Tp* ptr(int i0=0) const; + + template _Tp* ptr(int i0, int i1); + template const _Tp* ptr(int i0, int i1) const; + + template _Tp* ptr(int i0, int i1, int i2); + template const _Tp* ptr(int i0, int i1, int i2) const; + + template _Tp* ptr(const int* idx); + template const _Tp* ptr(const int* idx) const; + + template _Tp* ptr(const Vec& idx); + template const _Tp* ptr(const Vec& idx) const; + + //! the same as above, with the pointer dereferencing + template _Tp& at(int i0=0); + template const _Tp& at(int i0=0) const; + + template _Tp& at(int i0, int i1); + template const _Tp& at(int i0, int i1) const; + + template _Tp& at(int i0, int i1, int i2); + template const _Tp& at(int i0, int i1, int i2) const; + + template _Tp& at(const int* idx); + template const _Tp& at(const int* idx) const; + + template _Tp& at(const Vec& idx); + template const _Tp& at(const Vec& idx) const; + + //! special versions for 2D arrays (especially convenient for referencing image pixels) + template _Tp& at(Point pt); + template const _Tp& at(Point pt) const; + + //! template methods for iteration over matrix elements. + // the iterators take care of skipping gaps in the end of rows (if any) + template MatIterator_<_Tp> begin(); + template MatIterator_<_Tp> end(); + template MatConstIterator_<_Tp> begin() const; + template MatConstIterator_<_Tp> end() const; + + enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG }; + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the matrix dimensionality, >= 2 + int dims; + //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions + int rows, cols; + //! pointer to the data + uchar* data; + + //! pointer to the reference counter; + // when matrix points to user-allocated data, the pointer is NULL + int* refcount; + + //! helper fields used in locateROI and adjustROI + uchar* datastart; + uchar* dataend; + uchar* datalimit; + + //! custom allocator + MatAllocator* allocator; + + struct CV_EXPORTS MSize + { + MSize(int* _p); + Size operator()() const; + const int& operator[](int i) const; + int& operator[](int i); + operator const int*() const; + bool operator == (const MSize& sz) const; + bool operator != (const MSize& sz) const; + + int* p; + }; + + struct CV_EXPORTS MStep + { + MStep(); + MStep(size_t s); + const size_t& operator[](int i) const; + size_t& operator[](int i); + operator size_t() const; + MStep& operator = (size_t s); + + size_t* p; + size_t buf[2]; + protected: + MStep& operator = (const MStep&); + }; + + MSize size; + MStep step; + +protected: + void initEmpty(); +}; + + +/*! + Random Number Generator + + The class implements RNG using Multiply-with-Carry algorithm +*/ +class CV_EXPORTS RNG +{ +public: + enum { UNIFORM=0, NORMAL=1 }; + + RNG(); + RNG(uint64 state); + //! updates the state and returns the next 32-bit unsigned integer random number + unsigned next(); + + operator uchar(); + operator schar(); + operator ushort(); + operator short(); + operator unsigned(); + //! returns a random integer sampled uniformly from [0, N). + unsigned operator ()(unsigned N); + unsigned operator ()(); + operator int(); + operator float(); + operator double(); + //! returns uniformly distributed integer random number from [a,b) range + int uniform(int a, int b); + //! returns uniformly distributed floating-point random number from [a,b) range + float uniform(float a, float b); + //! returns uniformly distributed double-precision floating-point random number from [a,b) range + double uniform(double a, double b); + void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false ); + //! returns Gaussian random variate with mean zero. + double gaussian(double sigma); + + uint64 state; +}; + + +/*! + Termination criteria in iterative algorithms + */ +class CV_EXPORTS TermCriteria +{ +public: + enum + { + COUNT=1, //!< the maximum number of iterations or elements to compute + MAX_ITER=COUNT, //!< ditto + EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops + }; + + //! default constructor + TermCriteria(); + //! full constructor + TermCriteria(int type, int maxCount, double epsilon); + //! conversion from CvTermCriteria + TermCriteria(const CvTermCriteria& criteria); + //! conversion to CvTermCriteria + operator CvTermCriteria() const; + + int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS + int maxCount; // the maximum number of iterations/elements + double epsilon; // the desired accuracy +}; + + +typedef void (*BinaryFunc)(const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, + void*); + +CV_EXPORTS BinaryFunc getConvertFunc(int sdepth, int ddepth); +CV_EXPORTS BinaryFunc getConvertScaleFunc(int sdepth, int ddepth); +CV_EXPORTS BinaryFunc getCopyMaskFunc(size_t esz); + +//! swaps two matrices +CV_EXPORTS void swap(Mat& a, Mat& b); + +//! converts array (CvMat or IplImage) to cv::Mat +CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false, + bool allowND=true, int coiMode=0); +//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it. +CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1); +//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage +CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1); + +//! adds one matrix to another (dst = src1 + src2) +CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst, + InputArray mask=noArray(), int dtype=-1); +//! subtracts one matrix from another (dst = src1 - src2) +CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst, + InputArray mask=noArray(), int dtype=-1); + +//! computes element-wise weighted product of the two arrays (dst = scale*src1*src2) +CV_EXPORTS_W void multiply(InputArray src1, InputArray src2, + OutputArray dst, double scale=1, int dtype=-1); + +//! computes element-wise weighted quotient of the two arrays (dst = scale*src1/src2) +CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst, + double scale=1, int dtype=-1); + +//! computes element-wise weighted reciprocal of an array (dst = scale/src2) +CV_EXPORTS_W void divide(double scale, InputArray src2, + OutputArray dst, int dtype=-1); + +//! adds scaled array to another one (dst = alpha*src1 + src2) +CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst); + +//! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma) +CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2, + double beta, double gamma, OutputArray dst, int dtype=-1); + +//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_castabs(src(i)*alpha+beta) +CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst, + double alpha=1, double beta=0); +//! transforms array of numbers using a lookup table: dst(i)=lut(src(i)) +CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst, + int interpolation=0); + +//! computes sum of array elements +CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src); +//! computes the number of nonzero array elements +CV_EXPORTS_W int countNonZero( InputArray src ); +//! returns the list of locations of non-zero pixels +CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx ); + +//! computes mean value of selected array elements +CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask=noArray()); +//! computes mean value and standard deviation of all or selected array elements +CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, + InputArray mask=noArray()); +//! computes norm of the selected array part +CV_EXPORTS_W double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray()); +//! computes norm of selected part of the difference between two arrays +CV_EXPORTS_W double norm(InputArray src1, InputArray src2, + int normType=NORM_L2, InputArray mask=noArray()); + +//! naive nearest neighbor finder +CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2, + OutputArray dist, int dtype, OutputArray nidx, + int normType=NORM_L2, int K=0, + InputArray mask=noArray(), int update=0, + bool crosscheck=false); + +//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values +CV_EXPORTS_W void normalize( InputArray src, OutputArray dst, double alpha=1, double beta=0, + int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray()); + +//! finds global minimum and maximum array elements and returns their values and their locations +CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal, + CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0, + CV_OUT Point* maxLoc=0, InputArray mask=noArray()); +CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal, + int* minIdx=0, int* maxIdx=0, InputArray mask=noArray()); + +//! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows +CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1); + +//! makes multi-channel array out of several single-channel arrays +CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst); +CV_EXPORTS void merge(const vector& mv, OutputArray dst ); + +//! makes multi-channel array out of several single-channel arrays +CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst); + +//! copies each plane of a multi-channel array to a dedicated array +CV_EXPORTS void split(const Mat& src, Mat* mvbegin); +CV_EXPORTS void split(const Mat& m, vector& mv ); + +//! copies each plane of a multi-channel array to a dedicated array +CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv); + +//! copies selected channels from the input arrays to the selected channels of the output arrays +CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, + const int* fromTo, size_t npairs); +CV_EXPORTS void mixChannels(const vector& src, vector& dst, + const int* fromTo, size_t npairs); +CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputArrayOfArrays dst, + const vector& fromTo); + +//! extracts a single channel from src (coi is 0-based index) +CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi); + +//! inserts a single channel to dst (coi is 0-based index) +CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi); + +//! reverses the order of the rows, columns or both in a matrix +CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode); + +//! replicates the input matrix the specified number of times in the horizontal and/or vertical direction +CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst); +CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx); + +CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst); +CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst); +CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst); + +CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst); +CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst); +CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst); + +//! computes bitwise conjunction of the two arrays (dst = src1 & src2) +CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask=noArray()); +//! computes bitwise disjunction of the two arrays (dst = src1 | src2) +CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask=noArray()); +//! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2) +CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask=noArray()); +//! inverts each bit of array (dst = ~src) +CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst, + InputArray mask=noArray()); +//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2)) +CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst); +//! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb) +CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, + InputArray upperb, OutputArray dst); +//! compares elements of two arrays (dst = src1 src2) +CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop); +//! computes per-element minimum of two arrays (dst = min(src1, src2)) +CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst); +//! computes per-element maximum of two arrays (dst = max(src1, src2)) +CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst); + +//! computes per-element minimum of two arrays (dst = min(src1, src2)) +CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst); +//! computes per-element minimum of array and scalar (dst = min(src1, src2)) +CV_EXPORTS void min(const Mat& src1, double src2, Mat& dst); +//! computes per-element maximum of two arrays (dst = max(src1, src2)) +CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst); +//! computes per-element maximum of array and scalar (dst = max(src1, src2)) +CV_EXPORTS void max(const Mat& src1, double src2, Mat& dst); + +//! computes square root of each matrix element (dst = src**0.5) +CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst); +//! raises the input matrix elements to the specified power (b = a**power) +CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst); +//! computes exponent of each matrix element (dst = e**src) +CV_EXPORTS_W void exp(InputArray src, OutputArray dst); +//! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src)) +CV_EXPORTS_W void log(InputArray src, OutputArray dst); +//! computes cube root of the argument +CV_EXPORTS_W float cubeRoot(float val); +//! computes the angle in degrees (0..360) of the vector (x,y) +CV_EXPORTS_W float fastAtan2(float y, float x); + +CV_EXPORTS void exp(const float* src, float* dst, int n); +CV_EXPORTS void log(const float* src, float* dst, int n); +CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n); + +//! converts polar coordinates to Cartesian +CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle, + OutputArray x, OutputArray y, bool angleInDegrees=false); +//! converts Cartesian coordinates to polar +CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y, + OutputArray magnitude, OutputArray angle, + bool angleInDegrees=false); +//! computes angle (angle(i)) of each (x(i), y(i)) vector +CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle, + bool angleInDegrees=false); +//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector +CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude); +//! checks that each matrix element is within the specified range. +CV_EXPORTS_W bool checkRange(InputArray a, bool quiet=true, CV_OUT Point* pos=0, + double minVal=-DBL_MAX, double maxVal=DBL_MAX); +//! converts NaN's to the given number +CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val=0); + +//! implements generalized matrix product algorithm GEMM from BLAS +CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha, + InputArray src3, double gamma, OutputArray dst, int flags=0); +//! multiplies matrix by its transposition from the left or from the right +CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa, + InputArray delta=noArray(), + double scale=1, int dtype=-1 ); +//! transposes the matrix +CV_EXPORTS_W void transpose(InputArray src, OutputArray dst); +//! performs affine transformation of each element of multi-channel input matrix +CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m ); +//! performs perspective transformation of each element of multi-channel input matrix +CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m ); + +//! extends the symmetrical matrix from the lower half or from the upper half +CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper=false); +//! initializes scaled identity matrix +CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s=Scalar(1)); +//! computes determinant of a square matrix +CV_EXPORTS_W double determinant(InputArray mtx); +//! computes trace of a matrix +CV_EXPORTS_W Scalar trace(InputArray mtx); +//! computes inverse or pseudo-inverse matrix +CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags=DECOMP_LU); +//! solves linear system or a least-square problem +CV_EXPORTS_W bool solve(InputArray src1, InputArray src2, + OutputArray dst, int flags=DECOMP_LU); + +enum +{ + SORT_EVERY_ROW=0, + SORT_EVERY_COLUMN=1, + SORT_ASCENDING=0, + SORT_DESCENDING=16 +}; + +//! sorts independently each matrix row or each matrix column +CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags); +//! sorts independently each matrix row or each matrix column +CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags); +//! finds real roots of a cubic polynomial +CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots); +//! finds real and complex roots of a polynomial +CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters=300); +//! finds eigenvalues of a symmetric matrix +CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues, int lowindex=-1, + int highindex=-1); +//! finds eigenvalues and eigenvectors of a symmetric matrix +CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues, + OutputArray eigenvectors, + int lowindex=-1, int highindex=-1); +CV_EXPORTS_W bool eigen(InputArray src, bool computeEigenvectors, + OutputArray eigenvalues, OutputArray eigenvectors); + +enum +{ + COVAR_SCRAMBLED=0, + COVAR_NORMAL=1, + COVAR_USE_AVG=2, + COVAR_SCALE=4, + COVAR_ROWS=8, + COVAR_COLS=16 +}; + +//! computes covariation matrix of a set of samples +CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean, + int flags, int ctype=CV_64F); +//! computes covariation matrix of a set of samples +CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar, + OutputArray mean, int flags, int ctype=CV_64F); + +/*! + Principal Component Analysis + + The class PCA is used to compute the special basis for a set of vectors. + The basis will consist of eigenvectors of the covariance matrix computed + from the input set of vectors. After PCA is performed, vectors can be transformed from + the original high-dimensional space to the subspace formed by a few most + prominent eigenvectors (called the principal components), + corresponding to the largest eigenvalues of the covariation matrix. + Thus the dimensionality of the vector and the correlation between the coordinates is reduced. + + The following sample is the function that takes two matrices. The first one stores the set + of vectors (a row per vector) that is used to compute PCA, the second one stores another + "test" set of vectors (a row per vector) that are first compressed with PCA, + then reconstructed back and then the reconstruction error norm is computed and printed for each vector. + + \code + using namespace cv; + + PCA compressPCA(const Mat& pcaset, int maxComponents, + const Mat& testset, Mat& compressed) + { + PCA pca(pcaset, // pass the data + Mat(), // we do not have a pre-computed mean vector, + // so let the PCA engine to compute it + CV_PCA_DATA_AS_ROW, // indicate that the vectors + // are stored as matrix rows + // (use CV_PCA_DATA_AS_COL if the vectors are + // the matrix columns) + maxComponents // specify, how many principal components to retain + ); + // if there is no test data, just return the computed basis, ready-to-use + if( !testset.data ) + return pca; + CV_Assert( testset.cols == pcaset.cols ); + + compressed.create(testset.rows, maxComponents, testset.type()); + + Mat reconstructed; + for( int i = 0; i < testset.rows; i++ ) + { + Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed; + // compress the vector, the result will be stored + // in the i-th row of the output matrix + pca.project(vec, coeffs); + // and then reconstruct it + pca.backProject(coeffs, reconstructed); + // and measure the error + printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2)); + } + return pca; + } + \endcode +*/ +class CV_EXPORTS PCA +{ +public: + //! default constructor + PCA(); + //! the constructor that performs PCA + PCA(InputArray data, InputArray mean, int flags, int maxComponents=0); + PCA(InputArray data, InputArray mean, int flags, double retainedVariance); + //! operator that performs PCA. The previously stored data, if any, is released + PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents=0); + PCA& computeVar(InputArray data, InputArray mean, int flags, double retainedVariance); + //! projects vector from the original space to the principal components subspace + Mat project(InputArray vec) const; + //! projects vector from the original space to the principal components subspace + void project(InputArray vec, OutputArray result) const; + //! reconstructs the original vector from the projection + Mat backProject(InputArray vec) const; + //! reconstructs the original vector from the projection + void backProject(InputArray vec, OutputArray result) const; + + Mat eigenvectors; //!< eigenvectors of the covariation matrix + Mat eigenvalues; //!< eigenvalues of the covariation matrix + Mat mean; //!< mean value subtracted before the projection and added after the back projection +}; + +CV_EXPORTS_W void PCACompute(InputArray data, CV_OUT InputOutputArray mean, + OutputArray eigenvectors, int maxComponents=0); + +CV_EXPORTS_W void PCAComputeVar(InputArray data, CV_OUT InputOutputArray mean, + OutputArray eigenvectors, double retainedVariance); + +CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result); + +CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result); + + +/*! + Singular Value Decomposition class + + The class is used to compute Singular Value Decomposition of a floating-point matrix and then + use it to solve least-square problems, under-determined linear systems, invert matrices, + compute condition numbers etc. + + For a bit faster operation you can pass flags=SVD::MODIFY_A|... to modify the decomposed matrix + when it is not necessarily to preserve it. If you want to compute condition number of a matrix + or absolute value of its determinant - you do not need SVD::u or SVD::vt, + so you can pass flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that the full-size SVD::u and SVD::vt + must be computed, which is not necessary most of the time. +*/ +class CV_EXPORTS SVD +{ +public: + enum { MODIFY_A=1, NO_UV=2, FULL_UV=4 }; + //! the default constructor + SVD(); + //! the constructor that performs SVD + SVD( InputArray src, int flags=0 ); + //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released. + SVD& operator ()( InputArray src, int flags=0 ); + + //! decomposes matrix and stores the results to user-provided matrices + static void compute( InputArray src, OutputArray w, + OutputArray u, OutputArray vt, int flags=0 ); + //! computes singular values of a matrix + static void compute( InputArray src, OutputArray w, int flags=0 ); + //! performs back substitution + static void backSubst( InputArray w, InputArray u, + InputArray vt, InputArray rhs, + OutputArray dst ); + + template static void compute( const Matx<_Tp, m, n>& a, + Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ); + template static void compute( const Matx<_Tp, m, n>& a, + Matx<_Tp, nm, 1>& w ); + template static void backSubst( const Matx<_Tp, nm, 1>& w, + const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst ); + + //! finds dst = arg min_{|dst|=1} |m*dst| + static void solveZ( InputArray src, OutputArray dst ); + //! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix + void backSubst( InputArray rhs, OutputArray dst ) const; + + Mat u, w, vt; +}; + +//! computes SVD of src +CV_EXPORTS_W void SVDecomp( InputArray src, CV_OUT OutputArray w, + CV_OUT OutputArray u, CV_OUT OutputArray vt, int flags=0 ); + +//! performs back substitution for the previously computed SVD +CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt, + InputArray rhs, CV_OUT OutputArray dst ); + +//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix +CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar); +//! a synonym for Mahalanobis +CV_EXPORTS double Mahalonobis(InputArray v1, InputArray v2, InputArray icovar); + +//! performs forward or inverse 1D or 2D Discrete Fourier Transformation +CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0); +//! performs inverse 1D or 2D Discrete Fourier Transformation +CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0); +//! performs forward or inverse 1D or 2D Discrete Cosine Transformation +CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags=0); +//! performs inverse 1D or 2D Discrete Cosine Transformation +CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags=0); +//! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication +CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c, + int flags, bool conjB=false); +//! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently +CV_EXPORTS_W int getOptimalDFTSize(int vecsize); + +/*! + Various k-Means flags +*/ +enum +{ + KMEANS_RANDOM_CENTERS=0, // Chooses random centers for k-Means initialization + KMEANS_PP_CENTERS=2, // Uses k-Means++ algorithm for initialization + KMEANS_USE_INITIAL_LABELS=1 // Uses the user-provided labels for K-Means initialization +}; +//! clusters the input data using k-Means algorithm +CV_EXPORTS_W double kmeans( InputArray data, int K, CV_OUT InputOutputArray bestLabels, + TermCriteria criteria, int attempts, + int flags, OutputArray centers=noArray() ); + +//! returns the thread-local Random number generator +CV_EXPORTS RNG& theRNG(); + +//! returns the next unifomly-distributed random number of the specified type +template static inline _Tp randu() { return (_Tp)theRNG(); } + +//! fills array with uniformly-distributed random numbers from the range [low, high) +CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high); + +//! fills array with normally-distributed random numbers with the specified mean and the standard deviation +CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev); + +//! shuffles the input array elements +CV_EXPORTS void randShuffle(InputOutputArray dst, double iterFactor=1., RNG* rng=0); +CV_EXPORTS_AS(randShuffle) void randShuffle_(InputOutputArray dst, double iterFactor=1.); + +//! draws the line segment (pt1, pt2) in the image +CV_EXPORTS_W void line(CV_IN_OUT Mat& img, Point pt1, Point pt2, const Scalar& color, + int thickness=1, int lineType=8, int shift=0); + +//! draws the rectangle outline or a solid rectangle with the opposite corners pt1 and pt2 in the image +CV_EXPORTS_W void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2, + const Scalar& color, int thickness=1, + int lineType=8, int shift=0); + +//! draws the rectangle outline or a solid rectangle covering rec in the image +CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec, + const Scalar& color, int thickness=1, + int lineType=8, int shift=0); + +//! draws the circle outline or a solid circle in the image +CV_EXPORTS_W void circle(CV_IN_OUT Mat& img, Point center, int radius, + const Scalar& color, int thickness=1, + int lineType=8, int shift=0); + +//! draws an elliptic arc, ellipse sector or a rotated ellipse in the image +CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, Point center, Size axes, + double angle, double startAngle, double endAngle, + const Scalar& color, int thickness=1, + int lineType=8, int shift=0); + +//! draws a rotated ellipse in the image +CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, const RotatedRect& box, const Scalar& color, + int thickness=1, int lineType=8); + +//! draws a filled convex polygon in the image +CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts, + const Scalar& color, int lineType=8, + int shift=0); +CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points, + const Scalar& color, int lineType=8, + int shift=0); + +//! fills an area bounded by one or more polygons +CV_EXPORTS void fillPoly(Mat& img, const Point** pts, + const int* npts, int ncontours, + const Scalar& color, int lineType=8, int shift=0, + Point offset=Point() ); + +CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts, + const Scalar& color, int lineType=8, int shift=0, + Point offset=Point() ); + +//! draws one or more polygonal curves +CV_EXPORTS void polylines(Mat& img, const Point** pts, const int* npts, + int ncontours, bool isClosed, const Scalar& color, + int thickness=1, int lineType=8, int shift=0 ); + +CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts, + bool isClosed, const Scalar& color, + int thickness=1, int lineType=8, int shift=0 ); + +//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height) +CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2); + +//! clips the line segment by the rectangle imgRect +CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2); + +/*! + Line iterator class + + The class is used to iterate over all the pixels on the raster line + segment connecting two specified points. +*/ +class CV_EXPORTS LineIterator +{ +public: + //! intializes the iterator + LineIterator( const Mat& img, Point pt1, Point pt2, + int connectivity=8, bool leftToRight=false ); + //! returns pointer to the current pixel + uchar* operator *(); + //! prefix increment operator (++it). shifts iterator to the next pixel + LineIterator& operator ++(); + //! postfix increment operator (it++). shifts iterator to the next pixel + LineIterator operator ++(int); + //! returns coordinates of the current pixel + Point pos() const; + + uchar* ptr; + const uchar* ptr0; + int step, elemSize; + int err, count; + int minusDelta, plusDelta; + int minusStep, plusStep; +}; + +//! converts elliptic arc to a polygonal curve +CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle, + int arcStart, int arcEnd, int delta, + CV_OUT vector& pts ); + +enum +{ + FONT_HERSHEY_SIMPLEX = 0, + FONT_HERSHEY_PLAIN = 1, + FONT_HERSHEY_DUPLEX = 2, + FONT_HERSHEY_COMPLEX = 3, + FONT_HERSHEY_TRIPLEX = 4, + FONT_HERSHEY_COMPLEX_SMALL = 5, + FONT_HERSHEY_SCRIPT_SIMPLEX = 6, + FONT_HERSHEY_SCRIPT_COMPLEX = 7, + FONT_ITALIC = 16 +}; + +//! renders text string in the image +CV_EXPORTS_W void putText( Mat& img, const string& text, Point org, + int fontFace, double fontScale, Scalar color, + int thickness=1, int lineType=8, + bool bottomLeftOrigin=false ); + +//! returns bounding box of the text string +CV_EXPORTS_W Size getTextSize(const string& text, int fontFace, + double fontScale, int thickness, + CV_OUT int* baseLine); + +///////////////////////////////// Mat_<_Tp> //////////////////////////////////// + +/*! + Template matrix class derived from Mat + + The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields, + nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes + can be safely converted one to another. But do it with care, for example: + + \code + // create 100x100 8-bit matrix + Mat M(100,100,CV_8U); + // this will compile fine. no any data conversion will be done. + Mat_& M1 = (Mat_&)M; + // the program will likely crash at the statement below + M1(99,99) = 1.f; + \endcode + + While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element + access operations and if you know matrix type at compile time. + Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the + same thing and run at the same speed, but the latter is certainly shorter: + + \code + Mat_ M(20,20); + for(int i = 0; i < M.rows; i++) + for(int j = 0; j < M.cols; j++) + M(i,j) = 1./(i+j+1); + Mat E, V; + eigen(M,E,V); + cout << E.at(0,0)/E.at(M.rows-1,0); + \endcode + + It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter: + + \code + // allocate 320x240 color image and fill it with green (in RGB space) + Mat_ img(240, 320, Vec3b(0,255,0)); + // now draw a diagonal white line + for(int i = 0; i < 100; i++) + img(i,i)=Vec3b(255,255,255); + // and now modify the 2nd (red) channel of each pixel + for(int i = 0; i < img.rows; i++) + for(int j = 0; j < img.cols; j++) + img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y) + \endcode +*/ +template class CV_EXPORTS Mat_ : public Mat +{ +public: + typedef _Tp value_type; + typedef typename DataType<_Tp>::channel_type channel_type; + typedef MatIterator_<_Tp> iterator; + typedef MatConstIterator_<_Tp> const_iterator; + + //! default constructor + Mat_(); + //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type) + Mat_(int _rows, int _cols); + //! constructor that sets each matrix element to specified value + Mat_(int _rows, int _cols, const _Tp& value); + //! equivalent to Mat(_size, DataType<_Tp>::type) + explicit Mat_(Size _size); + //! constructor that sets each matrix element to specified value + Mat_(Size _size, const _Tp& value); + //! n-dim array constructor + Mat_(int _ndims, const int* _sizes); + //! n-dim array constructor that sets each matrix element to specified value + Mat_(int _ndims, const int* _sizes, const _Tp& value); + //! copy/conversion contructor. If m is of different type, it's converted + Mat_(const Mat& m); + //! copy constructor + Mat_(const Mat_& m); + //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type + Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP); + //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type + Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0); + //! selects a submatrix + Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all()); + //! selects a submatrix + Mat_(const Mat_& m, const Rect& roi); + //! selects a submatrix, n-dim version + Mat_(const Mat_& m, const Range* ranges); + //! from a matrix expression + explicit Mat_(const MatExpr& e); + //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column + explicit Mat_(const vector<_Tp>& vec, bool copyData=false); + template explicit Mat_(const Vec::channel_type, n>& vec, bool copyData=true); + template explicit Mat_(const Matx::channel_type, m, n>& mtx, bool copyData=true); + explicit Mat_(const Point_::channel_type>& pt, bool copyData=true); + explicit Mat_(const Point3_::channel_type>& pt, bool copyData=true); + explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); + + Mat_& operator = (const Mat& m); + Mat_& operator = (const Mat_& m); + //! set all the elements to s. + Mat_& operator = (const _Tp& s); + //! assign a matrix expression + Mat_& operator = (const MatExpr& e); + + //! iterators; they are smart enough to skip gaps in the end of rows + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type) + void create(int _rows, int _cols); + //! equivalent to Mat::create(_size, DataType<_Tp>::type) + void create(Size _size); + //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type) + void create(int _ndims, const int* _sizes); + //! cross-product + Mat_ cross(const Mat_& m) const; + //! data type conversion + template operator Mat_() const; + //! overridden forms of Mat::row() etc. + Mat_ row(int y) const; + Mat_ col(int x) const; + Mat_ diag(int d=0) const; + Mat_ clone() const; + + //! overridden forms of Mat::elemSize() etc. + size_t elemSize() const; + size_t elemSize1() const; + int type() const; + int depth() const; + int channels() const; + size_t step1(int i=0) const; + //! returns step()/sizeof(_Tp) + size_t stepT(int i=0) const; + + //! overridden forms of Mat::zeros() etc. Data type is omitted, of course + static MatExpr zeros(int rows, int cols); + static MatExpr zeros(Size size); + static MatExpr zeros(int _ndims, const int* _sizes); + static MatExpr ones(int rows, int cols); + static MatExpr ones(Size size); + static MatExpr ones(int _ndims, const int* _sizes); + static MatExpr eye(int rows, int cols); + static MatExpr eye(Size size); + + //! some more overriden methods + Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright ); + Mat_ operator()( const Range& rowRange, const Range& colRange ) const; + Mat_ operator()( const Rect& roi ) const; + Mat_ operator()( const Range* ranges ) const; + + //! more convenient forms of row and element access operators + _Tp* operator [](int y); + const _Tp* operator [](int y) const; + + //! returns reference to the specified element + _Tp& operator ()(const int* idx); + //! returns read-only reference to the specified element + const _Tp& operator ()(const int* idx) const; + + //! returns reference to the specified element + template _Tp& operator ()(const Vec& idx); + //! returns read-only reference to the specified element + template const _Tp& operator ()(const Vec& idx) const; + + //! returns reference to the specified element (1D case) + _Tp& operator ()(int idx0); + //! returns read-only reference to the specified element (1D case) + const _Tp& operator ()(int idx0) const; + //! returns reference to the specified element (2D case) + _Tp& operator ()(int idx0, int idx1); + //! returns read-only reference to the specified element (2D case) + const _Tp& operator ()(int idx0, int idx1) const; + //! returns reference to the specified element (3D case) + _Tp& operator ()(int idx0, int idx1, int idx2); + //! returns read-only reference to the specified element (3D case) + const _Tp& operator ()(int idx0, int idx1, int idx2) const; + + _Tp& operator ()(Point pt); + const _Tp& operator ()(Point pt) const; + + //! conversion to vector. + operator vector<_Tp>() const; + //! conversion to Vec + template operator Vec::channel_type, n>() const; + //! conversion to Matx + template operator Matx::channel_type, m, n>() const; +}; + +typedef Mat_ Mat1b; +typedef Mat_ Mat2b; +typedef Mat_ Mat3b; +typedef Mat_ Mat4b; + +typedef Mat_ Mat1s; +typedef Mat_ Mat2s; +typedef Mat_ Mat3s; +typedef Mat_ Mat4s; + +typedef Mat_ Mat1w; +typedef Mat_ Mat2w; +typedef Mat_ Mat3w; +typedef Mat_ Mat4w; + +typedef Mat_ Mat1i; +typedef Mat_ Mat2i; +typedef Mat_ Mat3i; +typedef Mat_ Mat4i; + +typedef Mat_ Mat1f; +typedef Mat_ Mat2f; +typedef Mat_ Mat3f; +typedef Mat_ Mat4f; + +typedef Mat_ Mat1d; +typedef Mat_ Mat2d; +typedef Mat_ Mat3d; +typedef Mat_ Mat4d; + +//////////// Iterators & Comma initializers ////////////////// + +class CV_EXPORTS MatConstIterator +{ +public: + typedef uchar* value_type; + typedef ptrdiff_t difference_type; + typedef const uchar** pointer; + typedef uchar* reference; + typedef std::random_access_iterator_tag iterator_category; + + //! default constructor + MatConstIterator(); + //! constructor that sets the iterator to the beginning of the matrix + MatConstIterator(const Mat* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, const int* _idx); + //! copy constructor + MatConstIterator(const MatConstIterator& it); + + //! copy operator + MatConstIterator& operator = (const MatConstIterator& it); + //! returns the current matrix element + uchar* operator *() const; + //! returns the i-th matrix element, relative to the current + uchar* operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatConstIterator& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatConstIterator& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatConstIterator& operator --(); + //! decrements the iterator + MatConstIterator operator --(int); + //! increments the iterator + MatConstIterator& operator ++(); + //! increments the iterator + MatConstIterator operator ++(int); + //! returns the current iterator position + Point pos() const; + //! returns the current iterator position + void pos(int* _idx) const; + ptrdiff_t lpos() const; + void seek(ptrdiff_t ofs, bool relative=false); + void seek(const int* _idx, bool relative=false); + + const Mat* m; + size_t elemSize; + uchar* ptr; + uchar* sliceStart; + uchar* sliceEnd; +}; + +/*! + Matrix read-only iterator + + */ +template +class CV_EXPORTS MatConstIterator_ : public MatConstIterator +{ +public: + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + typedef std::random_access_iterator_tag iterator_category; + + //! default constructor + MatConstIterator_(); + //! constructor that sets the iterator to the beginning of the matrix + MatConstIterator_(const Mat_<_Tp>* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx); + //! copy constructor + MatConstIterator_(const MatConstIterator_& it); + + //! copy operator + MatConstIterator_& operator = (const MatConstIterator_& it); + //! returns the current matrix element + _Tp operator *() const; + //! returns the i-th matrix element, relative to the current + _Tp operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatConstIterator_& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatConstIterator_& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatConstIterator_& operator --(); + //! decrements the iterator + MatConstIterator_ operator --(int); + //! increments the iterator + MatConstIterator_& operator ++(); + //! increments the iterator + MatConstIterator_ operator ++(int); + //! returns the current iterator position + Point pos() const; +}; + + +/*! + Matrix read-write iterator + +*/ +template +class CV_EXPORTS MatIterator_ : public MatConstIterator_<_Tp> +{ +public: + typedef _Tp* pointer; + typedef _Tp& reference; + typedef std::random_access_iterator_tag iterator_category; + + //! the default constructor + MatIterator_(); + //! constructor that sets the iterator to the beginning of the matrix + MatIterator_(Mat_<_Tp>* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(const Mat_<_Tp>* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(const Mat_<_Tp>* _m, const int* _idx); + //! copy constructor + MatIterator_(const MatIterator_& it); + //! copy operator + MatIterator_& operator = (const MatIterator_<_Tp>& it ); + + //! returns the current matrix element + _Tp& operator *() const; + //! returns the i-th matrix element, relative to the current + _Tp& operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatIterator_& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatIterator_& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatIterator_& operator --(); + //! decrements the iterator + MatIterator_ operator --(int); + //! increments the iterator + MatIterator_& operator ++(); + //! increments the iterator + MatIterator_ operator ++(int); +}; + +template class CV_EXPORTS MatOp_Iter_; + +/*! + Comma-separated Matrix Initializer + + The class instances are usually not created explicitly. + Instead, they are created on "matrix << firstValue" operator. + + The sample below initializes 2x2 rotation matrix: + + \code + double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180); + Mat R = (Mat_(2,2) << a, -b, b, a); + \endcode +*/ +template class CV_EXPORTS MatCommaInitializer_ +{ +public: + //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat + MatCommaInitializer_(Mat_<_Tp>* _m); + //! the operator that takes the next value and put it to the matrix + template MatCommaInitializer_<_Tp>& operator , (T2 v); + //! another form of conversion operator + Mat_<_Tp> operator *() const; + operator Mat_<_Tp>() const; +protected: + MatIterator_<_Tp> it; +}; + + +template class CV_EXPORTS MatxCommaInitializer +{ +public: + MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); + template MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); + Matx<_Tp, m, n> operator *() const; + + Matx<_Tp, m, n>* dst; + int idx; +}; + +template class CV_EXPORTS VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> +{ +public: + VecCommaInitializer(Vec<_Tp, m>* _vec); + template VecCommaInitializer<_Tp, m>& operator , (T2 val); + Vec<_Tp, m> operator *() const; +}; + +/*! + Automatically Allocated Buffer Class + + The class is used for temporary buffers in functions and methods. + If a temporary buffer is usually small (a few K's of memory), + but its size depends on the parameters, it makes sense to create a small + fixed-size array on stack and use it if it's large enough. If the required buffer size + is larger than the fixed size, another buffer of sufficient size is allocated dynamically + and released after the processing. Therefore, in typical cases, when the buffer size is small, + there is no overhead associated with malloc()/free(). + At the same time, there is no limit on the size of processed data. + + This is what AutoBuffer does. The template takes 2 parameters - type of the buffer elements and + the number of stack-allocated elements. Here is how the class is used: + + \code + void my_func(const cv::Mat& m) + { + cv::AutoBuffer buf; // create automatic buffer containing 1000 floats + + buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used, + // otherwise the buffer of "m.rows" floats will be allocated + // dynamically and deallocated in cv::AutoBuffer destructor + ... + } + \endcode +*/ +template class CV_EXPORTS AutoBuffer +{ +public: + typedef _Tp value_type; + enum { buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) }; + + //! the default contructor + AutoBuffer(); + //! constructor taking the real buffer size + AutoBuffer(size_t _size); + //! destructor. calls deallocate() + ~AutoBuffer(); + + //! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used + void allocate(size_t _size); + //! deallocates the buffer if it was dynamically allocated + void deallocate(); + //! returns pointer to the real buffer, stack-allocated or head-allocated + operator _Tp* (); + //! returns read-only pointer to the real buffer, stack-allocated or head-allocated + operator const _Tp* () const; + +protected: + //! pointer to the real buffer, can point to buf if the buffer is small enough + _Tp* ptr; + //! size of the real buffer + size_t size; + //! pre-allocated buffer + _Tp buf[fixed_size+buffer_padding]; +}; + +/////////////////////////// multi-dimensional dense matrix ////////////////////////// + +/*! + n-Dimensional Dense Matrix Iterator Class. + + The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's). + + The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators. + It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays. + + Here is the example on how the iterator can be used to normalize 3D histogram: + + \code + void normalizeColorHist(Mat& hist) + { + #if 1 + // intialize iterator (the style is different from STL). + // after initialization the iterator will contain + // the number of slices or planes + // the iterator will go through + Mat* arrays[] = { &hist, 0 }; + Mat planes[1]; + NAryMatIterator it(arrays, planes); + double s = 0; + // iterate through the matrix. on each iteration + // it.planes[i] (of type Mat) will be set to the current plane of + // i-th n-dim matrix passed to the iterator constructor. + for(int p = 0; p < it.nplanes; p++, ++it) + s += sum(it.planes[0])[0]; + it = NAryMatIterator(hist); + s = 1./s; + for(int p = 0; p < it.nplanes; p++, ++it) + it.planes[0] *= s; + #elif 1 + // this is a shorter implementation of the above + // using built-in operations on Mat + double s = sum(hist)[0]; + hist.convertTo(hist, hist.type(), 1./s, 0); + #else + // and this is even shorter one + // (assuming that the histogram elements are non-negative) + normalize(hist, hist, 1, 0, NORM_L1); + #endif + } + \endcode + + You can iterate through several matrices simultaneously as long as they have the same geometry + (dimensionality and all the dimension sizes are the same), which is useful for binary + and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator. + Then, during the iteration it.planes[0], it.planes[1], ... will + be the slices of the corresponding matrices +*/ +class CV_EXPORTS NAryMatIterator +{ +public: + //! the default constructor + NAryMatIterator(); + //! the full constructor taking arbitrary number of n-dim matrices + NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1); + //! the full constructor taking arbitrary number of n-dim matrices + NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1); + //! the separate iterator initialization method + void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1); + + //! proceeds to the next plane of every iterated matrix + NAryMatIterator& operator ++(); + //! proceeds to the next plane of every iterated matrix (postfix increment operator) + NAryMatIterator operator ++(int); + + //! the iterated arrays + const Mat** arrays; + //! the current planes + Mat* planes; + //! data pointers + uchar** ptrs; + //! the number of arrays + int narrays; + //! the number of hyper-planes that the iterator steps through + size_t nplanes; + //! the size of each segment (in elements) + size_t size; +protected: + int iterdepth; + size_t idx; +}; + +//typedef NAryMatIterator NAryMatNDIterator; + +typedef void (*ConvertData)(const void* from, void* to, int cn); +typedef void (*ConvertScaleData)(const void* from, void* to, int cn, double alpha, double beta); + +//! returns the function for converting pixels from one data type to another +CV_EXPORTS ConvertData getConvertElem(int fromType, int toType); +//! returns the function for converting pixels from one data type to another with the optional scaling +CV_EXPORTS ConvertScaleData getConvertScaleElem(int fromType, int toType); + + +/////////////////////////// multi-dimensional sparse matrix ////////////////////////// + +class SparseMatIterator; +class SparseMatConstIterator; +template class SparseMatIterator_; +template class SparseMatConstIterator_; + +/*! + Sparse matrix class. + + The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements + of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements + are stored (though, as a result of some operations on a sparse matrix, some of its stored elements + can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase(). + The non-zero elements are stored in a hash table that grows when it's filled enough, + so that the search time remains O(1) in average. Elements can be accessed using the following methods: + +
    +
  1. Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(), + cv::SparseMat::value() and cv::SparseMat::find, for example: + \code + const int dims = 5; + int size[] = {10, 10, 10, 10, 10}; + SparseMat sparse_mat(dims, size, CV_32F); + for(int i = 0; i < 1000; i++) + { + int idx[dims]; + for(int k = 0; k < dims; k++) + idx[k] = rand()%sparse_mat.size(k); + sparse_mat.ref(idx) += 1.f; + } + \endcode + +
  2. Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style, + that is, the iteration is done as following: + \code + // prints elements of a sparse floating-point matrix and the sum of elements. + SparseMatConstIterator_ + it = sparse_mat.begin(), + it_end = sparse_mat.end(); + double s = 0; + int dims = sparse_mat.dims(); + for(; it != it_end; ++it) + { + // print element indices and the element value + const Node* n = it.node(); + printf("(") + for(int i = 0; i < dims; i++) + printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')'); + printf(": %f\n", *it); + s += *it; + } + printf("Element sum is %g\n", s); + \endcode + If you run this loop, you will notice that elements are enumerated + in no any logical order (lexicographical etc.), + they come in the same order as they stored in the hash table, i.e. semi-randomly. + + You may collect pointers to the nodes and sort them to get the proper ordering. + Note, however, that pointers to the nodes may become invalid when you add more + elements to the matrix; this is because of possible buffer reallocation. + +
  3. A combination of the above 2 methods when you need to process 2 or more sparse + matrices simultaneously, e.g. this is how you can compute unnormalized + cross-correlation of the 2 floating-point sparse matrices: + \code + double crossCorr(const SparseMat& a, const SparseMat& b) + { + const SparseMat *_a = &a, *_b = &b; + // if b contains less elements than a, + // it's faster to iterate through b + if(_a->nzcount() > _b->nzcount()) + std::swap(_a, _b); + SparseMatConstIterator_ it = _a->begin(), + it_end = _a->end(); + double ccorr = 0; + for(; it != it_end; ++it) + { + // take the next element from the first matrix + float avalue = *it; + const Node* anode = it.node(); + // and try to find element with the same index in the second matrix. + // since the hash value depends only on the element index, + // we reuse hashvalue stored in the node + float bvalue = _b->value(anode->idx,&anode->hashval); + ccorr += avalue*bvalue; + } + return ccorr; + } + \endcode +
+*/ +class CV_EXPORTS SparseMat +{ +public: + typedef SparseMatIterator iterator; + typedef SparseMatConstIterator const_iterator; + + //! the sparse matrix header + struct CV_EXPORTS Hdr + { + Hdr(int _dims, const int* _sizes, int _type); + void clear(); + int refcount; + int dims; + int valueOffset; + size_t nodeSize; + size_t nodeCount; + size_t freeList; + vector pool; + vector hashtab; + int size[CV_MAX_DIM]; + }; + + //! sparse matrix node - element of a hash table + struct CV_EXPORTS Node + { + //! hash value + size_t hashval; + //! index of the next node in the same hash table entry + size_t next; + //! index of the matrix element + int idx[CV_MAX_DIM]; + }; + + //! default constructor + SparseMat(); + //! creates matrix of the specified size and type + SparseMat(int dims, const int* _sizes, int _type); + //! copy constructor + SparseMat(const SparseMat& m); + //! converts dense 2d matrix to the sparse form + /*! + \param m the input matrix + \param try1d if true and m is a single-column matrix (Nx1), + then the sparse matrix will be 1-dimensional. + */ + explicit SparseMat(const Mat& m); + //! converts old-style sparse matrix to the new-style. All the data is copied + SparseMat(const CvSparseMat* m); + //! the destructor + ~SparseMat(); + + //! assignment operator. This is O(1) operation, i.e. no data is copied + SparseMat& operator = (const SparseMat& m); + //! equivalent to the corresponding constructor + SparseMat& operator = (const Mat& m); + + //! creates full copy of the matrix + SparseMat clone() const; + + //! copies all the data to the destination matrix. All the previous content of m is erased + void copyTo( SparseMat& m ) const; + //! converts sparse matrix to dense matrix. + void copyTo( Mat& m ) const; + //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type + void convertTo( SparseMat& m, int rtype, double alpha=1 ) const; + //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling. + /*! + \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this) + \param alpha The scale factor + \param beta The optional delta added to the scaled values before the conversion + */ + void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const; + + // not used now + void assignTo( SparseMat& m, int type=-1 ) const; + + //! reallocates sparse matrix. + /*! + If the matrix already had the proper size and type, + it is simply cleared with clear(), otherwise, + the old matrix is released (using release()) and the new one is allocated. + */ + void create(int dims, const int* _sizes, int _type); + //! sets all the sparse matrix elements to 0, which means clearing the hash table. + void clear(); + //! manually increments the reference counter to the header. + void addref(); + // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated. + void release(); + + //! converts sparse matrix to the old-style representation; all the elements are copied. + operator CvSparseMat*() const; + //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements) + size_t elemSize() const; + //! returns elemSize()/channels() + size_t elemSize1() const; + + //! returns type of sparse matrix elements + int type() const; + //! returns the depth of sparse matrix elements + int depth() const; + //! returns the number of channels + int channels() const; + + //! returns the array of sizes, or NULL if the matrix is not allocated + const int* size() const; + //! returns the size of i-th matrix dimension (or 0) + int size(int i) const; + //! returns the matrix dimensionality + int dims() const; + //! returns the number of non-zero elements (=the number of hash table nodes) + size_t nzcount() const; + + //! computes the element hash value (1D case) + size_t hash(int i0) const; + //! computes the element hash value (2D case) + size_t hash(int i0, int i1) const; + //! computes the element hash value (3D case) + size_t hash(int i0, int i1, int i2) const; + //! computes the element hash value (nD case) + size_t hash(const int* idx) const; + + //@{ + /*! + specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case. + + return pointer to the matrix element. +
    +
  • if the element is there (it's non-zero), the pointer to it is returned +
  • if it's not there and createMissing=false, NULL pointer is returned +
  • if it's not there and createMissing=true, then the new element + is created and initialized with 0. Pointer to it is returned +
  • if the optional hashval pointer is not NULL, the element hash value is + not computed, but *hashval is taken instead. +
+ */ + //! returns pointer to the specified element (1D case) + uchar* ptr(int i0, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (2D case) + uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (3D case) + uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (nD case) + uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0); + //@} + + //@{ + /*! + return read-write reference to the specified sparse matrix element. + + ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]). + The methods always return a valid reference. + If the element did not exist, it is created and initialiazed with 0. + */ + //! returns reference to the specified element (1D case) + template _Tp& ref(int i0, size_t* hashval=0); + //! returns reference to the specified element (2D case) + template _Tp& ref(int i0, int i1, size_t* hashval=0); + //! returns reference to the specified element (3D case) + template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! returns reference to the specified element (nD case) + template _Tp& ref(const int* idx, size_t* hashval=0); + //@} + + //@{ + /*! + return value of the specified sparse matrix element. + + value<_Tp>(i0,...[,hashval]) is equivalent + + \code + { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); } + \endcode + + That is, if the element did not exist, the methods return 0. + */ + //! returns value of the specified element (1D case) + template _Tp value(int i0, size_t* hashval=0) const; + //! returns value of the specified element (2D case) + template _Tp value(int i0, int i1, size_t* hashval=0) const; + //! returns value of the specified element (3D case) + template _Tp value(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns value of the specified element (nD case) + template _Tp value(const int* idx, size_t* hashval=0) const; + //@} + + //@{ + /*! + Return pointer to the specified sparse matrix element if it exists + + find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]). + + If the specified element does not exist, the methods return NULL. + */ + //! returns pointer to the specified element (1D case) + template const _Tp* find(int i0, size_t* hashval=0) const; + //! returns pointer to the specified element (2D case) + template const _Tp* find(int i0, int i1, size_t* hashval=0) const; + //! returns pointer to the specified element (3D case) + template const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns pointer to the specified element (nD case) + template const _Tp* find(const int* idx, size_t* hashval=0) const; + + //! erases the specified element (2D case) + void erase(int i0, int i1, size_t* hashval=0); + //! erases the specified element (3D case) + void erase(int i0, int i1, int i2, size_t* hashval=0); + //! erases the specified element (nD case) + void erase(const int* idx, size_t* hashval=0); + + //@{ + /*! + return the sparse matrix iterator pointing to the first sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix beginning + SparseMatIterator begin(); + //! returns the sparse matrix iterator at the matrix beginning + template SparseMatIterator_<_Tp> begin(); + //! returns the read-only sparse matrix iterator at the matrix beginning + SparseMatConstIterator begin() const; + //! returns the read-only sparse matrix iterator at the matrix beginning + template SparseMatConstIterator_<_Tp> begin() const; + //@} + /*! + return the sparse matrix iterator pointing to the element following the last sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix end + SparseMatIterator end(); + //! returns the read-only sparse matrix iterator at the matrix end + SparseMatConstIterator end() const; + //! returns the typed sparse matrix iterator at the matrix end + template SparseMatIterator_<_Tp> end(); + //! returns the typed read-only sparse matrix iterator at the matrix end + template SparseMatConstIterator_<_Tp> end() const; + + //! returns the value stored in the sparse martix node + template _Tp& value(Node* n); + //! returns the value stored in the sparse martix node + template const _Tp& value(const Node* n) const; + + ////////////// some internal-use methods /////////////// + Node* node(size_t nidx); + const Node* node(size_t nidx) const; + + uchar* newNode(const int* idx, size_t hashval); + void removeNode(size_t hidx, size_t nidx, size_t previdx); + void resizeHashTab(size_t newsize); + + enum { MAGIC_VAL=0x42FD0000, MAX_DIM=CV_MAX_DIM, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 }; + + int flags; + Hdr* hdr; +}; + +//! finds global minimum and maximum sparse array elements and returns their values and their locations +CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal, + double* maxVal, int* minIdx=0, int* maxIdx=0); +//! computes norm of a sparse matrix +CV_EXPORTS double norm( const SparseMat& src, int normType ); +//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values +CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType ); + +/*! + Read-Only Sparse Matrix Iterator. + Here is how to use the iterator to compute the sum of floating-point sparse matrix elements: + + \code + SparseMatConstIterator it = m.begin(), it_end = m.end(); + double s = 0; + CV_Assert( m.type() == CV_32F ); + for( ; it != it_end; ++it ) + s += it.value(); + \endcode +*/ +class CV_EXPORTS SparseMatConstIterator +{ +public: + //! the default constructor + SparseMatConstIterator(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatConstIterator(const SparseMat* _m); + //! the copy constructor + SparseMatConstIterator(const SparseMatConstIterator& it); + + //! the assignment operator + SparseMatConstIterator& operator = (const SparseMatConstIterator& it); + + //! template method returning the current matrix element + template const _Tp& value() const; + //! returns the current node of the sparse matrix. it.node->idx is the current element index + const SparseMat::Node* node() const; + + //! moves iterator to the previous element + SparseMatConstIterator& operator --(); + //! moves iterator to the previous element + SparseMatConstIterator operator --(int); + //! moves iterator to the next element + SparseMatConstIterator& operator ++(); + //! moves iterator to the next element + SparseMatConstIterator operator ++(int); + + //! moves iterator to the element after the last element + void seekEnd(); + + const SparseMat* m; + size_t hashidx; + uchar* ptr; +}; + +/*! + Read-write Sparse Matrix Iterator + + The class is similar to cv::SparseMatConstIterator, + but can be used for in-place modification of the matrix elements. +*/ +class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator +{ +public: + //! the default constructor + SparseMatIterator(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatIterator(SparseMat* _m); + //! the full constructor setting the iterator to the specified sparse matrix element + SparseMatIterator(SparseMat* _m, const int* idx); + //! the copy constructor + SparseMatIterator(const SparseMatIterator& it); + + //! the assignment operator + SparseMatIterator& operator = (const SparseMatIterator& it); + //! returns read-write reference to the current sparse matrix element + template _Tp& value() const; + //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!) + SparseMat::Node* node() const; + + //! moves iterator to the next element + SparseMatIterator& operator ++(); + //! moves iterator to the next element + SparseMatIterator operator ++(int); +}; + +/*! + The Template Sparse Matrix class derived from cv::SparseMat + + The class provides slightly more convenient operations for accessing elements. + + \code + SparseMat m; + ... + SparseMat_ m_ = (SparseMat_&)m; + m_.ref(1)++; // equivalent to m.ref(1)++; + m_.ref(2) += m_(3); // equivalent to m.ref(2) += m.value(3); + \endcode +*/ +template class CV_EXPORTS SparseMat_ : public SparseMat +{ +public: + typedef SparseMatIterator_<_Tp> iterator; + typedef SparseMatConstIterator_<_Tp> const_iterator; + + //! the default constructor + SparseMat_(); + //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type) + SparseMat_(int dims, const int* _sizes); + //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted + SparseMat_(const SparseMat& m); + //! the copy constructor. This is O(1) operation - no data is copied + SparseMat_(const SparseMat_& m); + //! converts dense matrix to the sparse form + SparseMat_(const Mat& m); + //! converts the old-style sparse matrix to the C++ class. All the elements are copied + SparseMat_(const CvSparseMat* m); + //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted + SparseMat_& operator = (const SparseMat& m); + //! the assignment operator. This is O(1) operation - no data is copied + SparseMat_& operator = (const SparseMat_& m); + //! converts dense matrix to the sparse form + SparseMat_& operator = (const Mat& m); + + //! makes full copy of the matrix. All the elements are duplicated + SparseMat_ clone() const; + //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type) + void create(int dims, const int* _sizes); + //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied + operator CvSparseMat*() const; + + //! returns type of the matrix elements + int type() const; + //! returns depth of the matrix elements + int depth() const; + //! returns the number of channels in each matrix element + int channels() const; + + //! equivalent to SparseMat::ref<_Tp>(i0, hashval) + _Tp& ref(int i0, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval) + _Tp& ref(int i0, int i1, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval) + _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(idx, hashval) + _Tp& ref(const int* idx, size_t* hashval=0); + + //! equivalent to SparseMat::value<_Tp>(i0, hashval) + _Tp operator()(int i0, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval) + _Tp operator()(int i0, int i1, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval) + _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(idx, hashval) + _Tp operator()(const int* idx, size_t* hashval=0) const; + + //! returns sparse matrix iterator pointing to the first sparse matrix element + SparseMatIterator_<_Tp> begin(); + //! returns read-only sparse matrix iterator pointing to the first sparse matrix element + SparseMatConstIterator_<_Tp> begin() const; + //! returns sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatIterator_<_Tp> end(); + //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatConstIterator_<_Tp> end() const; +}; + + +/*! + Template Read-Only Sparse Matrix Iterator Class. + + This is the derived from SparseMatConstIterator class that + introduces more convenient operator *() for accessing the current element. +*/ +template class CV_EXPORTS SparseMatConstIterator_ : public SparseMatConstIterator +{ +public: + typedef std::forward_iterator_tag iterator_category; + + //! the default constructor + SparseMatConstIterator_(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatConstIterator_(const SparseMat_<_Tp>* _m); + SparseMatConstIterator_(const SparseMat* _m); + //! the copy constructor + SparseMatConstIterator_(const SparseMatConstIterator_& it); + + //! the assignment operator + SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it); + //! the element access operator + const _Tp& operator *() const; + + //! moves iterator to the next element + SparseMatConstIterator_& operator ++(); + //! moves iterator to the next element + SparseMatConstIterator_ operator ++(int); +}; + +/*! + Template Read-Write Sparse Matrix Iterator Class. + + This is the derived from cv::SparseMatConstIterator_ class that + introduces more convenient operator *() for accessing the current element. +*/ +template class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp> +{ +public: + typedef std::forward_iterator_tag iterator_category; + + //! the default constructor + SparseMatIterator_(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatIterator_(SparseMat_<_Tp>* _m); + SparseMatIterator_(SparseMat* _m); + //! the copy constructor + SparseMatIterator_(const SparseMatIterator_& it); + + //! the assignment operator + SparseMatIterator_& operator = (const SparseMatIterator_& it); + //! returns the reference to the current element + _Tp& operator *() const; + + //! moves the iterator to the next element + SparseMatIterator_& operator ++(); + //! moves the iterator to the next element + SparseMatIterator_ operator ++(int); +}; + +//////////////////// Fast Nearest-Neighbor Search Structure //////////////////// + +/*! + Fast Nearest Neighbor Search Class. + + The class implements D. Lowe BBF (Best-Bin-First) algorithm for the last + approximate (or accurate) nearest neighbor search in multi-dimensional spaces. + + First, a set of vectors is passed to KDTree::KDTree() constructor + or KDTree::build() method, where it is reordered. + + Then arbitrary vectors can be passed to KDTree::findNearest() methods, which + find the K nearest neighbors among the vectors from the initial set. + The user can balance between the speed and accuracy of the search by varying Emax + parameter, which is the number of leaves that the algorithm checks. + The larger parameter values yield more accurate results at the expense of lower processing speed. + + \code + KDTree T(points, false); + const int K = 3, Emax = INT_MAX; + int idx[K]; + float dist[K]; + T.findNearest(query_vec, K, Emax, idx, 0, dist); + CV_Assert(dist[0] <= dist[1] && dist[1] <= dist[2]); + \endcode +*/ +class CV_EXPORTS_W KDTree +{ +public: + /*! + The node of the search tree. + */ + struct Node + { + Node() : idx(-1), left(-1), right(-1), boundary(0.f) {} + Node(int _idx, int _left, int _right, float _boundary) + : idx(_idx), left(_left), right(_right), boundary(_boundary) {} + //! split dimension; >=0 for nodes (dim), < 0 for leaves (index of the point) + int idx; + //! node indices of the left and the right branches + int left, right; + //! go to the left if query_vec[node.idx]<=node.boundary, otherwise go to the right + float boundary; + }; + + //! the default constructor + CV_WRAP KDTree(); + //! the full constructor that builds the search tree + CV_WRAP KDTree(InputArray points, bool copyAndReorderPoints=false); + //! the full constructor that builds the search tree + CV_WRAP KDTree(InputArray points, InputArray _labels, + bool copyAndReorderPoints=false); + //! builds the search tree + CV_WRAP void build(InputArray points, bool copyAndReorderPoints=false); + //! builds the search tree + CV_WRAP void build(InputArray points, InputArray labels, + bool copyAndReorderPoints=false); + //! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves + CV_WRAP int findNearest(InputArray vec, int K, int Emax, + OutputArray neighborsIdx, + OutputArray neighbors=noArray(), + OutputArray dist=noArray(), + OutputArray labels=noArray()) const; + //! finds all the points from the initial set that belong to the specified box + CV_WRAP void findOrthoRange(InputArray minBounds, + InputArray maxBounds, + OutputArray neighborsIdx, + OutputArray neighbors=noArray(), + OutputArray labels=noArray()) const; + //! returns vectors with the specified indices + CV_WRAP void getPoints(InputArray idx, OutputArray pts, + OutputArray labels=noArray()) const; + //! return a vector with the specified index + const float* getPoint(int ptidx, int* label=0) const; + //! returns the search space dimensionality + CV_WRAP int dims() const; + + vector nodes; //!< all the tree nodes + CV_PROP Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set. + CV_PROP vector labels; //!< the parallel array of labels. + CV_PROP int maxDepth; //!< maximum depth of the search tree. Do not modify it + CV_PROP_RW int normType; //!< type of the distance (cv::NORM_L1 or cv::NORM_L2) used for search. Initially set to cv::NORM_L2, but you can modify it +}; + +//////////////////////////////////////// XML & YAML I/O //////////////////////////////////// + +class CV_EXPORTS FileNode; + +/*! + XML/YAML File Storage Class. + + The class describes an object associated with XML or YAML file. + It can be used to store data to such a file or read and decode the data. + + The storage is organized as a tree of nested sequences (or lists) and mappings. + Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator. + Mapping is analogue of std::map or C structure, which elements are accessed by names. + The most top level structure is a mapping. + Leaves of the file storage tree are integers, floating-point numbers and text strings. + + For example, the following code: + + \code + // open file storage for writing. Type of the file is determined from the extension + FileStorage fs("test.yml", FileStorage::WRITE); + fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH"; + fs << "test_mat" << Mat::eye(3,3,CV_32F); + + fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" << + "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]"; + fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:"; + + const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1}; + fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0]))); + + fs << "]" << "}"; + \endcode + + will produce the following file: + + \verbatim + %YAML:1.0 + test_int: 5 + test_real: 3.1000000000000001e+00 + test_string: ABCDEFGH + test_mat: !!opencv-matrix + rows: 3 + cols: 3 + dt: f + data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ] + test_list: + - 1.0000000000000000e-13 + - 2 + - 3.1415926535897931e+00 + - -3435345 + - "2-502 2-029 3egegeg" + - { month:12, day:31, year:1969 } + test_map: + x: 1 + y: 2 + width: 100 + height: 200 + lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ] + \endverbatim + + and to read the file above, the following code can be used: + + \code + // open file storage for reading. + // Type of the file is determined from the content, not the extension + FileStorage fs("test.yml", FileStorage::READ); + int test_int = (int)fs["test_int"]; + double test_real = (double)fs["test_real"]; + string test_string = (string)fs["test_string"]; + + Mat M; + fs["test_mat"] >> M; + + FileNode tl = fs["test_list"]; + CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6); + double tl0 = (double)tl[0]; + int tl1 = (int)tl[1]; + double tl2 = (double)tl[2]; + int tl3 = (int)tl[3]; + string tl4 = (string)tl[4]; + CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3); + + int month = (int)tl[5]["month"]; + int day = (int)tl[5]["day"]; + int year = (int)tl[5]["year"]; + + FileNode tm = fs["test_map"]; + + int x = (int)tm["x"]; + int y = (int)tm["y"]; + int width = (int)tm["width"]; + int height = (int)tm["height"]; + + int lbp_val = 0; + FileNodeIterator it = tm["lbp"].begin(); + + for(int k = 0; k < 8; k++, ++it) + lbp_val |= ((int)*it) << k; + \endcode +*/ +class CV_EXPORTS_W FileStorage +{ +public: + //! file storage mode + enum + { + READ=0, //! read mode + WRITE=1, //! write mode + APPEND=2, //! append mode + MEMORY=4, + FORMAT_MASK=(7<<3), + FORMAT_AUTO=0, + FORMAT_XML=(1<<3), + FORMAT_YAML=(2<<3) + }; + enum + { + UNDEFINED=0, + VALUE_EXPECTED=1, + NAME_EXPECTED=2, + INSIDE_MAP=4 + }; + //! the default constructor + CV_WRAP FileStorage(); + //! the full constructor that opens file storage for reading or writing + CV_WRAP FileStorage(const string& source, int flags, const string& encoding=string()); + //! the constructor that takes pointer to the C FileStorage structure + FileStorage(CvFileStorage* fs); + //! the destructor. calls release() + virtual ~FileStorage(); + + //! opens file storage for reading or writing. The previous storage is closed with release() + CV_WRAP virtual bool open(const string& filename, int flags, const string& encoding=string()); + //! returns true if the object is associated with currently opened file. + CV_WRAP virtual bool isOpened() const; + //! closes the file and releases all the memory buffers + CV_WRAP virtual void release(); + //! closes the file, releases all the memory buffers and returns the text string + CV_WRAP string releaseAndGetString(); + + //! returns the first element of the top-level mapping + CV_WRAP FileNode getFirstTopLevelNode() const; + //! returns the top-level mapping. YAML supports multiple streams + CV_WRAP FileNode root(int streamidx=0) const; + //! returns the specified element of the top-level mapping + FileNode operator[](const string& nodename) const; + //! returns the specified element of the top-level mapping + CV_WRAP FileNode operator[](const char* nodename) const; + + //! returns pointer to the underlying C FileStorage structure + CvFileStorage* operator *() { return fs; } + //! returns pointer to the underlying C FileStorage structure + const CvFileStorage* operator *() const { return fs; } + //! writes one or more numbers of the specified format to the currently written structure + void writeRaw( const string& fmt, const uchar* vec, size_t len ); + //! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite() + void writeObj( const string& name, const void* obj ); + + //! returns the normalized object name for the specified file name + static string getDefaultObjectName(const string& filename); + + Ptr fs; //!< the underlying C FileStorage structure + string elname; //!< the currently written element + vector structs; //!< the stack of written structures + int state; //!< the writer state +}; + +class CV_EXPORTS FileNodeIterator; + +/*! + File Storage Node class + + The node is used to store each and every element of the file storage opened for reading - + from the primitive objects, such as numbers and text strings, to the complex nodes: + sequences, mappings and the registered objects. + + Note that file nodes are only used for navigating file storages opened for reading. + When a file storage is opened for writing, no data is stored in memory after it is written. +*/ +class CV_EXPORTS_W_SIMPLE FileNode +{ +public: + //! type of the file storage node + enum + { + NONE=0, //!< empty node + INT=1, //!< an integer + REAL=2, //!< floating-point number + FLOAT=REAL, //!< synonym or REAL + STR=3, //!< text string in UTF-8 encoding + STRING=STR, //!< synonym for STR + REF=4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others + SEQ=5, //!< sequence + MAP=6, //!< mapping + TYPE_MASK=7, + FLOW=8, //!< compact representation of a sequence or mapping. Used only by YAML writer + USER=16, //!< a registered object (e.g. a matrix) + EMPTY=32, //!< empty structure (sequence or mapping) + NAMED=64 //!< the node has a name (i.e. it is element of a mapping) + }; + //! the default constructor + CV_WRAP FileNode(); + //! the full constructor wrapping CvFileNode structure. + FileNode(const CvFileStorage* fs, const CvFileNode* node); + //! the copy constructor + FileNode(const FileNode& node); + //! returns element of a mapping node + FileNode operator[](const string& nodename) const; + //! returns element of a mapping node + CV_WRAP FileNode operator[](const char* nodename) const; + //! returns element of a sequence node + CV_WRAP FileNode operator[](int i) const; + //! returns type of the node + CV_WRAP int type() const; + + //! returns true if the node is empty + CV_WRAP bool empty() const; + //! returns true if the node is a "none" object + CV_WRAP bool isNone() const; + //! returns true if the node is a sequence + CV_WRAP bool isSeq() const; + //! returns true if the node is a mapping + CV_WRAP bool isMap() const; + //! returns true if the node is an integer + CV_WRAP bool isInt() const; + //! returns true if the node is a floating-point number + CV_WRAP bool isReal() const; + //! returns true if the node is a text string + CV_WRAP bool isString() const; + //! returns true if the node has a name + CV_WRAP bool isNamed() const; + //! returns the node name or an empty string if the node is nameless + CV_WRAP string name() const; + //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise. + CV_WRAP size_t size() const; + //! returns the node content as an integer. If the node stores floating-point number, it is rounded. + operator int() const; + //! returns the node content as float + operator float() const; + //! returns the node content as double + operator double() const; + //! returns the node content as text string + operator string() const; + + //! returns pointer to the underlying file node + CvFileNode* operator *(); + //! returns pointer to the underlying file node + const CvFileNode* operator* () const; + + //! returns iterator pointing to the first node element + FileNodeIterator begin() const; + //! returns iterator pointing to the element following the last node element + FileNodeIterator end() const; + + //! reads node elements to the buffer with the specified format + void readRaw( const string& fmt, uchar* vec, size_t len ) const; + //! reads the registered object and returns pointer to it + void* readObj() const; + + // do not use wrapper pointer classes for better efficiency + const CvFileStorage* fs; + const CvFileNode* node; +}; + + +/*! + File Node Iterator + + The class is used for iterating sequences (usually) and mappings. + */ +class CV_EXPORTS FileNodeIterator +{ +public: + //! the default constructor + FileNodeIterator(); + //! the full constructor set to the ofs-th element of the node + FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0); + //! the copy constructor + FileNodeIterator(const FileNodeIterator& it); + //! returns the currently observed element + FileNode operator *() const; + //! accesses the currently observed element methods + FileNode operator ->() const; + + //! moves iterator to the next node + FileNodeIterator& operator ++ (); + //! moves iterator to the next node + FileNodeIterator operator ++ (int); + //! moves iterator to the previous node + FileNodeIterator& operator -- (); + //! moves iterator to the previous node + FileNodeIterator operator -- (int); + //! moves iterator forward by the specified offset (possibly negative) + FileNodeIterator& operator += (int ofs); + //! moves iterator backward by the specified offset (possibly negative) + FileNodeIterator& operator -= (int ofs); + + //! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format + FileNodeIterator& readRaw( const string& fmt, uchar* vec, + size_t maxCount=(size_t)INT_MAX ); + + const CvFileStorage* fs; + const CvFileNode* container; + CvSeqReader reader; + size_t remaining; +}; + +////////////// convenient wrappers for operating old-style dynamic structures ////////////// + +template class SeqIterator; + +typedef Ptr MemStorage; + +/*! + Template Sequence Class derived from CvSeq + + The class provides more convenient access to sequence elements, + STL-style operations and iterators. + + \note The class is targeted for simple data types, + i.e. no constructors or destructors + are called for the sequence elements. +*/ +template class CV_EXPORTS Seq +{ +public: + typedef SeqIterator<_Tp> iterator; + typedef SeqIterator<_Tp> const_iterator; + + //! the default constructor + Seq(); + //! the constructor for wrapping CvSeq structure. The real element type in CvSeq should match _Tp. + Seq(const CvSeq* seq); + //! creates the empty sequence that resides in the specified storage + Seq(MemStorage& storage, int headerSize = sizeof(CvSeq)); + //! returns read-write reference to the specified element + _Tp& operator [](int idx); + //! returns read-only reference to the specified element + const _Tp& operator[](int idx) const; + //! returns iterator pointing to the beginning of the sequence + SeqIterator<_Tp> begin() const; + //! returns iterator pointing to the element following the last sequence element + SeqIterator<_Tp> end() const; + //! returns the number of elements in the sequence + size_t size() const; + //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...) + int type() const; + //! returns the depth of sequence elements (CV_8U ... CV_64F) + int depth() const; + //! returns the number of channels in each sequence element + int channels() const; + //! returns the size of each sequence element + size_t elemSize() const; + //! returns index of the specified sequence element + size_t index(const _Tp& elem) const; + //! appends the specified element to the end of the sequence + void push_back(const _Tp& elem); + //! appends the specified element to the front of the sequence + void push_front(const _Tp& elem); + //! appends zero or more elements to the end of the sequence + void push_back(const _Tp* elems, size_t count); + //! appends zero or more elements to the front of the sequence + void push_front(const _Tp* elems, size_t count); + //! inserts the specified element to the specified position + void insert(int idx, const _Tp& elem); + //! inserts zero or more elements to the specified position + void insert(int idx, const _Tp* elems, size_t count); + //! removes element at the specified position + void remove(int idx); + //! removes the specified subsequence + void remove(const Range& r); + + //! returns reference to the first sequence element + _Tp& front(); + //! returns read-only reference to the first sequence element + const _Tp& front() const; + //! returns reference to the last sequence element + _Tp& back(); + //! returns read-only reference to the last sequence element + const _Tp& back() const; + //! returns true iff the sequence contains no elements + bool empty() const; + + //! removes all the elements from the sequence + void clear(); + //! removes the first element from the sequence + void pop_front(); + //! removes the last element from the sequence + void pop_back(); + //! removes zero or more elements from the beginning of the sequence + void pop_front(_Tp* elems, size_t count); + //! removes zero or more elements from the end of the sequence + void pop_back(_Tp* elems, size_t count); + + //! copies the whole sequence or the sequence slice to the specified vector + void copyTo(vector<_Tp>& vec, const Range& range=Range::all()) const; + //! returns the vector containing all the sequence elements + operator vector<_Tp>() const; + + CvSeq* seq; +}; + + +/*! + STL-style Sequence Iterator inherited from the CvSeqReader structure +*/ +template class CV_EXPORTS SeqIterator : public CvSeqReader +{ +public: + //! the default constructor + SeqIterator(); + //! the constructor setting the iterator to the beginning or to the end of the sequence + SeqIterator(const Seq<_Tp>& seq, bool seekEnd=false); + //! positions the iterator within the sequence + void seek(size_t pos); + //! reports the current iterator position + size_t tell() const; + //! returns reference to the current sequence element + _Tp& operator *(); + //! returns read-only reference to the current sequence element + const _Tp& operator *() const; + //! moves iterator to the next sequence element + SeqIterator& operator ++(); + //! moves iterator to the next sequence element + SeqIterator operator ++(int) const; + //! moves iterator to the previous sequence element + SeqIterator& operator --(); + //! moves iterator to the previous sequence element + SeqIterator operator --(int) const; + + //! moves iterator forward by the specified offset (possibly negative) + SeqIterator& operator +=(int); + //! moves iterator backward by the specified offset (possibly negative) + SeqIterator& operator -=(int); + + // this is index of the current element module seq->total*2 + // (to distinguish between 0 and seq->total) + int index; +}; + + +class CV_EXPORTS Algorithm; +class CV_EXPORTS AlgorithmInfo; +struct CV_EXPORTS AlgorithmInfoData; + +template struct ParamType {}; + +/*! + Base class for high-level OpenCV algorithms +*/ +class CV_EXPORTS_W Algorithm +{ +public: + Algorithm(); + virtual ~Algorithm(); + string name() const; + + template typename ParamType<_Tp>::member_type get(const string& name) const; + template typename ParamType<_Tp>::member_type get(const char* name) const; + + CV_WRAP int getInt(const string& name) const; + CV_WRAP double getDouble(const string& name) const; + CV_WRAP bool getBool(const string& name) const; + CV_WRAP string getString(const string& name) const; + CV_WRAP Mat getMat(const string& name) const; + CV_WRAP vector getMatVector(const string& name) const; + CV_WRAP Ptr getAlgorithm(const string& name) const; + + void set(const string& name, int value); + void set(const string& name, double value); + void set(const string& name, bool value); + void set(const string& name, const string& value); + void set(const string& name, const Mat& value); + void set(const string& name, const vector& value); + void set(const string& name, const Ptr& value); + template void set(const string& name, const Ptr<_Tp>& value); + + CV_WRAP void setInt(const string& name, int value); + CV_WRAP void setDouble(const string& name, double value); + CV_WRAP void setBool(const string& name, bool value); + CV_WRAP void setString(const string& name, const string& value); + CV_WRAP void setMat(const string& name, const Mat& value); + CV_WRAP void setMatVector(const string& name, const vector& value); + CV_WRAP void setAlgorithm(const string& name, const Ptr& value); + template void setAlgorithm(const string& name, const Ptr<_Tp>& value); + + void set(const char* name, int value); + void set(const char* name, double value); + void set(const char* name, bool value); + void set(const char* name, const string& value); + void set(const char* name, const Mat& value); + void set(const char* name, const vector& value); + void set(const char* name, const Ptr& value); + template void set(const char* name, const Ptr<_Tp>& value); + + void setInt(const char* name, int value); + void setDouble(const char* name, double value); + void setBool(const char* name, bool value); + void setString(const char* name, const string& value); + void setMat(const char* name, const Mat& value); + void setMatVector(const char* name, const vector& value); + void setAlgorithm(const char* name, const Ptr& value); + template void setAlgorithm(const char* name, const Ptr<_Tp>& value); + + CV_WRAP string paramHelp(const string& name) const; + int paramType(const char* name) const; + CV_WRAP int paramType(const string& name) const; + CV_WRAP void getParams(CV_OUT vector& names) const; + + + virtual void write(FileStorage& fs) const; + virtual void read(const FileNode& fn); + + typedef Algorithm* (*Constructor)(void); + typedef int (Algorithm::*Getter)() const; + typedef void (Algorithm::*Setter)(int); + + CV_WRAP static void getList(CV_OUT vector& algorithms); + CV_WRAP static Ptr _create(const string& name); + template static Ptr<_Tp> create(const string& name); + + virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; } +}; + + +class CV_EXPORTS AlgorithmInfo +{ +public: + friend class Algorithm; + AlgorithmInfo(const string& name, Algorithm::Constructor create); + ~AlgorithmInfo(); + void get(const Algorithm* algo, const char* name, int argType, void* value) const; + void addParam_(Algorithm& algo, const char* name, int argType, + void* value, bool readOnly, + Algorithm::Getter getter, Algorithm::Setter setter, + const string& help=string()); + string paramHelp(const char* name) const; + int paramType(const char* name) const; + void getParams(vector& names) const; + + void write(const Algorithm* algo, FileStorage& fs) const; + void read(Algorithm* algo, const FileNode& fn) const; + string name() const; + + void addParam(Algorithm& algo, const char* name, + int& value, bool readOnly=false, + int (Algorithm::*getter)()=0, + void (Algorithm::*setter)(int)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + short& value, bool readOnly=false, + int (Algorithm::*getter)()=0, + void (Algorithm::*setter)(int)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + bool& value, bool readOnly=false, + int (Algorithm::*getter)()=0, + void (Algorithm::*setter)(int)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + double& value, bool readOnly=false, + double (Algorithm::*getter)()=0, + void (Algorithm::*setter)(double)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + string& value, bool readOnly=false, + string (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const string&)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + Mat& value, bool readOnly=false, + Mat (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const Mat&)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + vector& value, bool readOnly=false, + vector (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const vector&)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + Ptr& value, bool readOnly=false, + Ptr (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const Ptr&)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + float& value, bool readOnly=false, + float (Algorithm::*getter)()=0, + void (Algorithm::*setter)(float)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + unsigned int& value, bool readOnly=false, + unsigned int (Algorithm::*getter)()=0, + void (Algorithm::*setter)(unsigned int)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + uint64& value, bool readOnly=false, + uint64 (Algorithm::*getter)()=0, + void (Algorithm::*setter)(uint64)=0, + const string& help=string()); + void addParam(Algorithm& algo, const char* name, + uchar& value, bool readOnly=false, + uchar (Algorithm::*getter)()=0, + void (Algorithm::*setter)(uchar)=0, + const string& help=string()); + template void addParam(Algorithm& algo, const char* name, + Ptr<_Tp>& value, bool readOnly=false, + Ptr<_Tp> (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const Ptr<_Tp>&)=0, + const string& help=string()); + template void addParam(Algorithm& algo, const char* name, + Ptr<_Tp>& value, bool readOnly=false, + Ptr<_Tp> (Algorithm::*getter)()=0, + void (Algorithm::*setter)(const Ptr<_Tp>&)=0, + const string& help=string()); +protected: + AlgorithmInfoData* data; + void set(Algorithm* algo, const char* name, int argType, + const void* value, bool force=false) const; +}; + + +struct CV_EXPORTS Param +{ + enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, SHORT=10, UCHAR=11 }; + + Param(); + Param(int _type, bool _readonly, int _offset, + Algorithm::Getter _getter=0, + Algorithm::Setter _setter=0, + const string& _help=string()); + int type; + int offset; + bool readonly; + Algorithm::Getter getter; + Algorithm::Setter setter; + string help; +}; + +template<> struct ParamType +{ + typedef bool const_param_type; + typedef bool member_type; + + enum { type = Param::BOOLEAN }; +}; + +template<> struct ParamType +{ + typedef int const_param_type; + typedef int member_type; + + enum { type = Param::INT }; +}; + +template<> struct ParamType +{ + typedef int const_param_type; + typedef int member_type; + + enum { type = Param::SHORT }; +}; + +template<> struct ParamType +{ + typedef double const_param_type; + typedef double member_type; + + enum { type = Param::REAL }; +}; + +template<> struct ParamType +{ + typedef const string& const_param_type; + typedef string member_type; + + enum { type = Param::STRING }; +}; + +template<> struct ParamType +{ + typedef const Mat& const_param_type; + typedef Mat member_type; + + enum { type = Param::MAT }; +}; + +template<> struct ParamType > +{ + typedef const vector& const_param_type; + typedef vector member_type; + + enum { type = Param::MAT_VECTOR }; +}; + +template<> struct ParamType +{ + typedef const Ptr& const_param_type; + typedef Ptr member_type; + + enum { type = Param::ALGORITHM }; +}; + +template<> struct ParamType +{ + typedef float const_param_type; + typedef float member_type; + + enum { type = Param::FLOAT }; +}; + +template<> struct ParamType +{ + typedef unsigned const_param_type; + typedef unsigned member_type; + + enum { type = Param::UNSIGNED_INT }; +}; + +template<> struct ParamType +{ + typedef uint64 const_param_type; + typedef uint64 member_type; + + enum { type = Param::UINT64 }; +}; + +template<> struct ParamType +{ + typedef uchar const_param_type; + typedef uchar member_type; + + enum { type = Param::UCHAR }; +}; + +/*! +"\nThe CommandLineParser class is designed for command line arguments parsing\n" + "Keys map: \n" + "Before you start to work with CommandLineParser you have to create a map for keys.\n" + " It will look like this\n" + " const char* keys =\n" + " {\n" + " { s| string| 123asd |string parameter}\n" + " { d| digit | 100 |digit parameter }\n" + " { c|noCamera|false |without camera }\n" + " { 1| |some text|help }\n" + " { 2| |333 |another help }\n" + " };\n" + "Usage syntax: \n" + " \"{\" - start of parameter string.\n" + " \"}\" - end of parameter string\n" + " \"|\" - separator between short name, full name, default value and help\n" + "Supported syntax: \n" + " --key1=arg1 \n" + " -key2=arg2 \n" + "Usage: \n" + " Imagine that the input parameters are next:\n" + " -s=string_value --digit=250 --noCamera lena.jpg 10000\n" + " CommandLineParser parser(argc, argv, keys) - create a parser object\n" + " parser.get(\"s\" or \"string\") will return you first parameter value\n" + " parser.get(\"s\", false or \"string\", false) will return you first parameter value\n" + " without spaces in end and begin\n" + " parser.get(\"d\" or \"digit\") will return you second parameter value.\n" + " It also works with 'unsigned int', 'double', and 'float' types>\n" + " parser.get(\"c\" or \"noCamera\") will return you true .\n" + " If you enter this key in commandline>\n" + " It return you false otherwise.\n" + " parser.get(\"1\") will return you the first argument without parameter (lena.jpg) \n" + " parser.get(\"2\") will return you the second argument without parameter (10000)\n" + " It also works with 'unsigned int', 'double', and 'float' types \n" +*/ +class CV_EXPORTS CommandLineParser +{ + public: + + //! the default constructor + CommandLineParser(int argc, const char* const argv[], const char* key_map); + + //! get parameter, you can choose: delete spaces in end and begin or not + template + _Tp get(const std::string& name, bool space_delete=true) + { + if (!has(name)) + { + return _Tp(); + } + std::string str = getString(name); + return analyzeValue<_Tp>(str, space_delete); + } + + //! print short name, full name, current value and help for all params + void printParams(); + + protected: + std::map > data; + std::string getString(const std::string& name); + + bool has(const std::string& keys); + + template + _Tp analyzeValue(const std::string& str, bool space_delete=false); + + template + static _Tp getData(const std::string& str) + { + _Tp res = _Tp(); + std::stringstream s1(str); + s1 >> res; + return res; + } + + template + _Tp fromStringNumber(const std::string& str);//the default conversion function for numbers + + }; + +template<> CV_EXPORTS +bool CommandLineParser::get(const std::string& name, bool space_delete); + +template<> CV_EXPORTS +std::string CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + +template<> CV_EXPORTS +int CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + +template<> CV_EXPORTS +unsigned int CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + +template<> CV_EXPORTS +uint64 CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + +template<> CV_EXPORTS +float CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + +template<> CV_EXPORTS +double CommandLineParser::analyzeValue(const std::string& str, bool space_delete); + + +/////////////////////////////// Parallel Primitives ////////////////////////////////// + +// a base body class +class CV_EXPORTS ParallelLoopBody +{ +public: + virtual ~ParallelLoopBody(); + virtual void operator() (const Range& range) const = 0; +}; + +CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.); + +/////////////////////////// Synchronization Primitives /////////////////////////////// + +class CV_EXPORTS Mutex +{ +public: + Mutex(); + ~Mutex(); + Mutex(const Mutex& m); + Mutex& operator = (const Mutex& m); + + void lock(); + bool trylock(); + void unlock(); + + struct Impl; +protected: + Impl* impl; +}; + +class CV_EXPORTS AutoLock +{ +public: + AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); } + ~AutoLock() { mutex->unlock(); } +protected: + Mutex* mutex; +}; + +} + +#endif // __cplusplus + +#include "opencv2/core/operations.hpp" +#include "opencv2/core/mat.hpp" + +#endif /*__OPENCV_CORE_HPP__*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/core_c.h diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/core_c.h --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/core_c.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/core_c.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1885 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + + +#ifndef __OPENCV_CORE_C_H__ +#define __OPENCV_CORE_C_H__ + +#include "opencv2/core/types_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************************\ +* Array allocation, deallocation, initialization and access to elements * +\****************************************************************************************/ + +/* wrapper. + If there is no enough memory, the function + (as well as other OpenCV functions that call cvAlloc) + raises an error. */ +CVAPI(void*) cvAlloc( size_t size ); + +/* wrapper. + Here and further all the memory releasing functions + (that all call cvFree) take double pointer in order to + to clear pointer to the data after releasing it. + Passing pointer to NULL pointer is Ok: nothing happens in this case +*/ +CVAPI(void) cvFree_( void* ptr ); +#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0) + +/* Allocates and initializes IplImage header */ +CVAPI(IplImage*) cvCreateImageHeader( CvSize size, int depth, int channels ); + +/* Inializes IplImage header */ +CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth, + int channels, int origin CV_DEFAULT(0), + int align CV_DEFAULT(4)); + +/* Creates IPL image (header and data) */ +CVAPI(IplImage*) cvCreateImage( CvSize size, int depth, int channels ); + +/* Releases (i.e. deallocates) IPL image header */ +CVAPI(void) cvReleaseImageHeader( IplImage** image ); + +/* Releases IPL image header and data */ +CVAPI(void) cvReleaseImage( IplImage** image ); + +/* Creates a copy of IPL image (widthStep may differ) */ +CVAPI(IplImage*) cvCloneImage( const IplImage* image ); + +/* Sets a Channel Of Interest (only a few functions support COI) - + use cvCopy to extract the selected channel and/or put it back */ +CVAPI(void) cvSetImageCOI( IplImage* image, int coi ); + +/* Retrieves image Channel Of Interest */ +CVAPI(int) cvGetImageCOI( const IplImage* image ); + +/* Sets image ROI (region of interest) (COI is not changed) */ +CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect ); + +/* Resets image ROI and COI */ +CVAPI(void) cvResetImageROI( IplImage* image ); + +/* Retrieves image ROI */ +CVAPI(CvRect) cvGetImageROI( const IplImage* image ); + +/* Allocates and initalizes CvMat header */ +CVAPI(CvMat*) cvCreateMatHeader( int rows, int cols, int type ); + +#define CV_AUTOSTEP 0x7fffffff + +/* Initializes CvMat header */ +CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols, + int type, void* data CV_DEFAULT(NULL), + int step CV_DEFAULT(CV_AUTOSTEP) ); + +/* Allocates and initializes CvMat header and allocates data */ +CVAPI(CvMat*) cvCreateMat( int rows, int cols, int type ); + +/* Releases CvMat header and deallocates matrix data + (reference counting is used for data) */ +CVAPI(void) cvReleaseMat( CvMat** mat ); + +/* Decrements CvMat data reference counter and deallocates the data if + it reaches 0 */ +CV_INLINE void cvDecRefData( CvArr* arr ) +{ + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + mat->data.ptr = NULL; + if( mat->refcount != NULL && --*mat->refcount == 0 ) + cvFree( &mat->refcount ); + mat->refcount = NULL; + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + mat->data.ptr = NULL; + if( mat->refcount != NULL && --*mat->refcount == 0 ) + cvFree( &mat->refcount ); + mat->refcount = NULL; + } +} + +/* Increments CvMat data reference counter */ +CV_INLINE int cvIncRefData( CvArr* arr ) +{ + int refcount = 0; + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + if( mat->refcount != NULL ) + refcount = ++*mat->refcount; + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + if( mat->refcount != NULL ) + refcount = ++*mat->refcount; + } + return refcount; +} + + +/* Creates an exact copy of the input matrix (except, may be, step value) */ +CVAPI(CvMat*) cvCloneMat( const CvMat* mat ); + + +/* Makes a new matrix from subrectangle of input array. + No data is copied */ +CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ); +#define cvGetSubArr cvGetSubRect + +/* Selects row span of the input array: arr(start_row:delta_row:end_row,:) + (end_row is not included into the span). */ +CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat, + int start_row, int end_row, + int delta_row CV_DEFAULT(1)); + +CV_INLINE CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row ) +{ + return cvGetRows( arr, submat, row, row + 1, 1 ); +} + + +/* Selects column span of the input array: arr(:,start_col:end_col) + (end_col is not included into the span) */ +CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat, + int start_col, int end_col ); + +CV_INLINE CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col ) +{ + return cvGetCols( arr, submat, col, col + 1 ); +} + +/* Select a diagonal of the input array. + (diag = 0 means the main diagonal, >0 means a diagonal above the main one, + <0 - below the main one). + The diagonal will be represented as a column (nx1 matrix). */ +CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat, + int diag CV_DEFAULT(0)); + +/* low-level scalar <-> raw data conversion functions */ +CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type, + int extend_to_12 CV_DEFAULT(0) ); + +CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar ); + +/* Allocates and initializes CvMatND header */ +CVAPI(CvMatND*) cvCreateMatNDHeader( int dims, const int* sizes, int type ); + +/* Allocates and initializes CvMatND header and allocates data */ +CVAPI(CvMatND*) cvCreateMatND( int dims, const int* sizes, int type ); + +/* Initializes preallocated CvMatND header */ +CVAPI(CvMatND*) cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, + int type, void* data CV_DEFAULT(NULL) ); + +/* Releases CvMatND */ +CV_INLINE void cvReleaseMatND( CvMatND** mat ) +{ + cvReleaseMat( (CvMat**)mat ); +} + +/* Creates a copy of CvMatND (except, may be, steps) */ +CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat ); + +/* Allocates and initializes CvSparseMat header and allocates data */ +CVAPI(CvSparseMat*) cvCreateSparseMat( int dims, const int* sizes, int type ); + +/* Releases CvSparseMat */ +CVAPI(void) cvReleaseSparseMat( CvSparseMat** mat ); + +/* Creates a copy of CvSparseMat (except, may be, zero items) */ +CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat ); + +/* Initializes sparse array iterator + (returns the first node or NULL if the array is empty) */ +CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat, + CvSparseMatIterator* mat_iterator ); + +// returns next sparse array node (or NULL if there is no more nodes) +CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator ) +{ + if( mat_iterator->node->next ) + return mat_iterator->node = mat_iterator->node->next; + else + { + int idx; + for( idx = ++mat_iterator->curidx; idx < mat_iterator->mat->hashsize; idx++ ) + { + CvSparseNode* node = (CvSparseNode*)mat_iterator->mat->hashtable[idx]; + if( node ) + { + mat_iterator->curidx = idx; + return mat_iterator->node = node; + } + } + return NULL; + } +} + +/**************** matrix iterator: used for n-ary operations on dense arrays *********/ + +#define CV_MAX_ARR 10 + +typedef struct CvNArrayIterator +{ + int count; /* number of arrays */ + int dims; /* number of dimensions to iterate */ + CvSize size; /* maximal common linear size: { width = size, height = 1 } */ + uchar* ptr[CV_MAX_ARR]; /* pointers to the array slices */ + int stack[CV_MAX_DIM]; /* for internal use */ + CvMatND* hdr[CV_MAX_ARR]; /* pointers to the headers of the + matrices that are processed */ +} +CvNArrayIterator; + +#define CV_NO_DEPTH_CHECK 1 +#define CV_NO_CN_CHECK 2 +#define CV_NO_SIZE_CHECK 4 + +/* initializes iterator that traverses through several arrays simulteneously + (the function together with cvNextArraySlice is used for + N-ari element-wise operations) */ +CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs, + const CvArr* mask, CvMatND* stubs, + CvNArrayIterator* array_iterator, + int flags CV_DEFAULT(0) ); + +/* returns zero value if iteration is finished, non-zero (slice length) otherwise */ +CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator ); + + +/* Returns type of array elements: + CV_8UC1 ... CV_64FC4 ... */ +CVAPI(int) cvGetElemType( const CvArr* arr ); + +/* Retrieves number of an array dimensions and + optionally sizes of the dimensions */ +CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) ); + + +/* Retrieves size of a particular array dimension. + For 2d arrays cvGetDimSize(arr,0) returns number of rows (image height) + and cvGetDimSize(arr,1) returns number of columns (image width) */ +CVAPI(int) cvGetDimSize( const CvArr* arr, int index ); + + +/* ptr = &arr(idx0,idx1,...). All indexes are zero-based, + the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D */ +CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL)); +CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) ); +CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, + int* type CV_DEFAULT(NULL)); + +/* For CvMat or IplImage number of indices should be 2 + (row index (y) goes first, column index (x) goes next). + For CvMatND or CvSparseMat number of infices should match number of and + indices order should match the array dimension order. */ +CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL), + int create_node CV_DEFAULT(1), + unsigned* precalc_hashval CV_DEFAULT(NULL)); + +/* value = arr(idx0,idx1,...) */ +CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 ); +CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 ); +CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx ); + +/* for 1-channel arrays */ +CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 ); +CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 ); +CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx ); + +/* arr(idx0,idx1,...) = value */ +CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value ); +CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); +CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value ); +CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value ); + +/* for 1-channel arrays */ +CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value ); +CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value ); +CVAPI(void) cvSetReal3D( CvArr* arr, int idx0, + int idx1, int idx2, double value ); +CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value ); + +/* clears element of ND dense array, + in case of sparse arrays it deletes the specified node */ +CVAPI(void) cvClearND( CvArr* arr, const int* idx ); + +/* Converts CvArr (IplImage or CvMat,...) to CvMat. + If the last parameter is non-zero, function can + convert multi(>2)-dimensional array to CvMat as long as + the last array's dimension is continous. The resultant + matrix will be have appropriate (a huge) number of rows */ +CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header, + int* coi CV_DEFAULT(NULL), + int allowND CV_DEFAULT(0)); + +/* Converts CvArr (IplImage or CvMat) to IplImage */ +CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header ); + + +/* Changes a shape of multi-dimensional array. + new_cn == 0 means that number of channels remains unchanged. + new_dims == 0 means that number and sizes of dimensions remain the same + (unless they need to be changed to set the new number of channels) + if new_dims == 1, there is no need to specify new dimension sizes + The resultant configuration should be achievable w/o data copying. + If the resultant array is sparse, CvSparseMat header should be passed + to the function else if the result is 1 or 2 dimensional, + CvMat header should be passed to the function + else CvMatND header should be passed */ +CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr, + int sizeof_header, CvArr* header, + int new_cn, int new_dims, int* new_sizes ); + +#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes ) \ + cvReshapeMatND( (arr), sizeof(*(header)), (header), \ + (new_cn), (new_dims), (new_sizes)) + +CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header, + int new_cn, int new_rows CV_DEFAULT(0) ); + +/* Repeats source 2d array several times in both horizontal and + vertical direction to fill destination array */ +CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst ); + +/* Allocates array data */ +CVAPI(void) cvCreateData( CvArr* arr ); + +/* Releases array data */ +CVAPI(void) cvReleaseData( CvArr* arr ); + +/* Attaches user data to the array header. The step is reffered to + the pre-last dimension. That is, all the planes of the array + must be joint (w/o gaps) */ +CVAPI(void) cvSetData( CvArr* arr, void* data, int step ); + +/* Retrieves raw data of CvMat, IplImage or CvMatND. + In the latter case the function raises an error if + the array can not be represented as a matrix */ +CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data, + int* step CV_DEFAULT(NULL), + CvSize* roi_size CV_DEFAULT(NULL)); + +/* Returns width and height of array in elements */ +CVAPI(CvSize) cvGetSize( const CvArr* arr ); + +/* Copies source array to destination array */ +CVAPI(void) cvCopy( const CvArr* src, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Sets all or "masked" elements of input array + to the same value*/ +CVAPI(void) cvSet( CvArr* arr, CvScalar value, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Clears all the array elements (sets them to 0) */ +CVAPI(void) cvSetZero( CvArr* arr ); +#define cvZero cvSetZero + + +/* Splits a multi-channel array into the set of single-channel arrays or + extracts particular [color] plane */ +CVAPI(void) cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, + CvArr* dst2, CvArr* dst3 ); + +/* Merges a set of single-channel arrays into the single multi-channel array + or inserts one particular [color] plane to the array */ +CVAPI(void) cvMerge( const CvArr* src0, const CvArr* src1, + const CvArr* src2, const CvArr* src3, + CvArr* dst ); + +/* Copies several channels from input arrays to + certain channels of output arrays */ +CVAPI(void) cvMixChannels( const CvArr** src, int src_count, + CvArr** dst, int dst_count, + const int* from_to, int pair_count ); + +/* Performs linear transformation on every source array element: + dst(x,y,c) = scale*src(x,y,c)+shift. + Arbitrary combination of input and output array depths are allowed + (number of channels must be the same), thus the function can be used + for type conversion */ +CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst, + double scale CV_DEFAULT(1), + double shift CV_DEFAULT(0) ); +#define cvCvtScale cvConvertScale +#define cvScale cvConvertScale +#define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 ) + + +/* Performs linear transformation on every source array element, + stores absolute value of the result: + dst(x,y,c) = abs(scale*src(x,y,c)+shift). + destination array must have 8u type. + In other cases one may use cvConvertScale + cvAbsDiffS */ +CVAPI(void) cvConvertScaleAbs( const CvArr* src, CvArr* dst, + double scale CV_DEFAULT(1), + double shift CV_DEFAULT(0) ); +#define cvCvtScaleAbs cvConvertScaleAbs + + +/* checks termination criteria validity and + sets eps to default_eps (if it is not set), + max_iter to default_max_iters (if it is not set) +*/ +CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria, + double default_eps, + int default_max_iters ); + +/****************************************************************************************\ +* Arithmetic, logic and comparison operations * +\****************************************************************************************/ + +/* dst(mask) = src1(mask) + src2(mask) */ +CVAPI(void) cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(mask) = src(mask) + value */ +CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(mask) = src1(mask) - src2(mask) */ +CVAPI(void) cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(mask) = src(mask) - value = src(mask) + (-value) */ +CV_INLINE void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)) +{ + cvAddS( src, cvScalar( -value.val[0], -value.val[1], -value.val[2], -value.val[3]), + dst, mask ); +} + +/* dst(mask) = value - src(mask) */ +CVAPI(void) cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src1(idx) * src2(idx) * scale + (scaled element-wise multiplication of 2 arrays) */ +CVAPI(void) cvMul( const CvArr* src1, const CvArr* src2, + CvArr* dst, double scale CV_DEFAULT(1) ); + +/* element-wise division/inversion with scaling: + dst(idx) = src1(idx) * scale / src2(idx) + or dst(idx) = scale / src2(idx) if src1 == 0 */ +CVAPI(void) cvDiv( const CvArr* src1, const CvArr* src2, + CvArr* dst, double scale CV_DEFAULT(1)); + +/* dst = src1 * scale + src2 */ +CVAPI(void) cvScaleAdd( const CvArr* src1, CvScalar scale, + const CvArr* src2, CvArr* dst ); +#define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C) + +/* dst = src1 * alpha + src2 * beta + gamma */ +CVAPI(void) cvAddWeighted( const CvArr* src1, double alpha, + const CvArr* src2, double beta, + double gamma, CvArr* dst ); + +/* result = sum_i(src1(i) * src2(i)) (results for all channels are accumulated together) */ +CVAPI(double) cvDotProduct( const CvArr* src1, const CvArr* src2 ); + +/* dst(idx) = src1(idx) & src2(idx) */ +CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src(idx) & value */ +CVAPI(void) cvAndS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src1(idx) | src2(idx) */ +CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src(idx) | value */ +CVAPI(void) cvOrS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src1(idx) ^ src2(idx) */ +CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = src(idx) ^ value */ +CVAPI(void) cvXorS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/* dst(idx) = ~src(idx) */ +CVAPI(void) cvNot( const CvArr* src, CvArr* dst ); + +/* dst(idx) = lower(idx) <= src(idx) < upper(idx) */ +CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower, + const CvArr* upper, CvArr* dst ); + +/* dst(idx) = lower <= src(idx) < upper */ +CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower, + CvScalar upper, CvArr* dst ); + +#define CV_CMP_EQ 0 +#define CV_CMP_GT 1 +#define CV_CMP_GE 2 +#define CV_CMP_LT 3 +#define CV_CMP_LE 4 +#define CV_CMP_NE 5 + +/* The comparison operation support single-channel arrays only. + Destination image should be 8uC1 or 8sC1 */ + +/* dst(idx) = src1(idx) _cmp_op_ src2(idx) */ +CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op ); + +/* dst(idx) = src1(idx) _cmp_op_ value */ +CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op ); + +/* dst(idx) = min(src1(idx),src2(idx)) */ +CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/* dst(idx) = max(src1(idx),src2(idx)) */ +CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/* dst(idx) = min(src(idx),value) */ +CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst ); + +/* dst(idx) = max(src(idx),value) */ +CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst ); + +/* dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */ +CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/* dst(x,y,c) = abs(src(x,y,c) - value(c)) */ +CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); +#define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0)) + +/****************************************************************************************\ +* Math operations * +\****************************************************************************************/ + +/* Does cartesian->polar coordinates conversion. + Either of output components (magnitude or angle) is optional */ +CVAPI(void) cvCartToPolar( const CvArr* x, const CvArr* y, + CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL), + int angle_in_degrees CV_DEFAULT(0)); + +/* Does polar->cartesian coordinates conversion. + Either of output components (magnitude or angle) is optional. + If magnitude is missing it is assumed to be all 1's */ +CVAPI(void) cvPolarToCart( const CvArr* magnitude, const CvArr* angle, + CvArr* x, CvArr* y, + int angle_in_degrees CV_DEFAULT(0)); + +/* Does powering: dst(idx) = src(idx)^power */ +CVAPI(void) cvPow( const CvArr* src, CvArr* dst, double power ); + +/* Does exponention: dst(idx) = exp(src(idx)). + Overflow is not handled yet. Underflow is handled. + Maximal relative error is ~7e-6 for single-precision input */ +CVAPI(void) cvExp( const CvArr* src, CvArr* dst ); + +/* Calculates natural logarithms: dst(idx) = log(abs(src(idx))). + Logarithm of 0 gives large negative number(~-700) + Maximal relative error is ~3e-7 for single-precision output +*/ +CVAPI(void) cvLog( const CvArr* src, CvArr* dst ); + +/* Fast arctangent calculation */ +CVAPI(float) cvFastArctan( float y, float x ); + +/* Fast cubic root calculation */ +CVAPI(float) cvCbrt( float value ); + +/* Checks array values for NaNs, Infs or simply for too large numbers + (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set, + no runtime errors is raised (function returns zero value in case of "bad" values). + Otherwise cvError is called */ +#define CV_CHECK_RANGE 1 +#define CV_CHECK_QUIET 2 +CVAPI(int) cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0), + double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0)); +#define cvCheckArray cvCheckArr + +#define CV_RAND_UNI 0 +#define CV_RAND_NORMAL 1 +CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, + CvScalar param1, CvScalar param2 ); + +CVAPI(void) cvRandShuffle( CvArr* mat, CvRNG* rng, + double iter_factor CV_DEFAULT(1.)); + +#define CV_SORT_EVERY_ROW 0 +#define CV_SORT_EVERY_COLUMN 1 +#define CV_SORT_ASCENDING 0 +#define CV_SORT_DESCENDING 16 + +CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), + CvArr* idxmat CV_DEFAULT(NULL), + int flags CV_DEFAULT(0)); + +/* Finds real roots of a cubic equation */ +CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots ); + +/* Finds all real and complex roots of a polynomial equation */ +CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2, + int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100)); + +/****************************************************************************************\ +* Matrix operations * +\****************************************************************************************/ + +/* Calculates cross product of two 3d vectors */ +CVAPI(void) cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/* Matrix transform: dst = A*B + C, C is optional */ +#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 ) +#define cvMatMul( src1, src2, dst ) cvMatMulAdd( (src1), (src2), NULL, (dst)) + +#define CV_GEMM_A_T 1 +#define CV_GEMM_B_T 2 +#define CV_GEMM_C_T 4 +/* Extended matrix transform: + dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */ +CVAPI(void) cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, + const CvArr* src3, double beta, CvArr* dst, + int tABC CV_DEFAULT(0)); +#define cvMatMulAddEx cvGEMM + +/* Transforms each element of source array and stores + resultant vectors in destination array */ +CVAPI(void) cvTransform( const CvArr* src, CvArr* dst, + const CvMat* transmat, + const CvMat* shiftvec CV_DEFAULT(NULL)); +#define cvMatMulAddS cvTransform + +/* Does perspective transform on every element of input array */ +CVAPI(void) cvPerspectiveTransform( const CvArr* src, CvArr* dst, + const CvMat* mat ); + +/* Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */ +CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order, + const CvArr* delta CV_DEFAULT(NULL), + double scale CV_DEFAULT(1.) ); + +/* Tranposes matrix. Square matrices can be transposed in-place */ +CVAPI(void) cvTranspose( const CvArr* src, CvArr* dst ); +#define cvT cvTranspose + +/* Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */ +CVAPI(void) cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) ); + +/* Mirror array data around horizontal (flip=0), + vertical (flip=1) or both(flip=-1) axises: + cvFlip(src) flips images vertically and sequences horizontally (inplace) */ +CVAPI(void) cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), + int flip_mode CV_DEFAULT(0)); +#define cvMirror cvFlip + + +#define CV_SVD_MODIFY_A 1 +#define CV_SVD_U_T 2 +#define CV_SVD_V_T 4 + +/* Performs Singular Value Decomposition of a matrix */ +CVAPI(void) cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL), + CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0)); + +/* Performs Singular Value Back Substitution (solves A*X = B): + flags must be the same as in cvSVD */ +CVAPI(void) cvSVBkSb( const CvArr* W, const CvArr* U, + const CvArr* V, const CvArr* B, + CvArr* X, int flags ); + +#define CV_LU 0 +#define CV_SVD 1 +#define CV_SVD_SYM 2 +#define CV_CHOLESKY 3 +#define CV_QR 4 +#define CV_NORMAL 16 + +/* Inverts matrix */ +CVAPI(double) cvInvert( const CvArr* src, CvArr* dst, + int method CV_DEFAULT(CV_LU)); +#define cvInv cvInvert + +/* Solves linear system (src1)*(dst) = (src2) + (returns 0 if src1 is a singular and CV_LU method is used) */ +CVAPI(int) cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, + int method CV_DEFAULT(CV_LU)); + +/* Calculates determinant of input matrix */ +CVAPI(double) cvDet( const CvArr* mat ); + +/* Calculates trace of the matrix (sum of elements on the main diagonal) */ +CVAPI(CvScalar) cvTrace( const CvArr* mat ); + +/* Finds eigen values and vectors of a symmetric matrix */ +CVAPI(void) cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, + double eps CV_DEFAULT(0), + int lowindex CV_DEFAULT(-1), + int highindex CV_DEFAULT(-1)); + +///* Finds selected eigen values and vectors of a symmetric matrix */ +//CVAPI(void) cvSelectedEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, +// int lowindex, int highindex ); + +/* Makes an identity matrix (mat_ij = i == j) */ +CVAPI(void) cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) ); + +/* Fills matrix with given range of numbers */ +CVAPI(CvArr*) cvRange( CvArr* mat, double start, double end ); + +/* Calculates covariation matrix for a set of vectors */ +/* transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */ +#define CV_COVAR_SCRAMBLED 0 + +/* [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */ +#define CV_COVAR_NORMAL 1 + +/* do not calc average (i.e. mean vector) - use the input vector instead + (useful for calculating covariance matrix by parts) */ +#define CV_COVAR_USE_AVG 2 + +/* scale the covariance matrix coefficients by number of the vectors */ +#define CV_COVAR_SCALE 4 + +/* all the input vectors are stored in a single matrix, as its rows */ +#define CV_COVAR_ROWS 8 + +/* all the input vectors are stored in a single matrix, as its columns */ +#define CV_COVAR_COLS 16 + +CVAPI(void) cvCalcCovarMatrix( const CvArr** vects, int count, + CvArr* cov_mat, CvArr* avg, int flags ); + +#define CV_PCA_DATA_AS_ROW 0 +#define CV_PCA_DATA_AS_COL 1 +#define CV_PCA_USE_AVG 2 +CVAPI(void) cvCalcPCA( const CvArr* data, CvArr* mean, + CvArr* eigenvals, CvArr* eigenvects, int flags ); + +CVAPI(void) cvProjectPCA( const CvArr* data, const CvArr* mean, + const CvArr* eigenvects, CvArr* result ); + +CVAPI(void) cvBackProjectPCA( const CvArr* proj, const CvArr* mean, + const CvArr* eigenvects, CvArr* result ); + +/* Calculates Mahalanobis(weighted) distance */ +CVAPI(double) cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat ); +#define cvMahalonobis cvMahalanobis + +/****************************************************************************************\ +* Array Statistics * +\****************************************************************************************/ + +/* Finds sum of array elements */ +CVAPI(CvScalar) cvSum( const CvArr* arr ); + +/* Calculates number of non-zero pixels */ +CVAPI(int) cvCountNonZero( const CvArr* arr ); + +/* Calculates mean value of array elements */ +CVAPI(CvScalar) cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) ); + +/* Calculates mean and standard deviation of pixel values */ +CVAPI(void) cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Finds global minimum, maximum and their positions */ +CVAPI(void) cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, + CvPoint* min_loc CV_DEFAULT(NULL), + CvPoint* max_loc CV_DEFAULT(NULL), + const CvArr* mask CV_DEFAULT(NULL) ); + +/* types of array norm */ +#define CV_C 1 +#define CV_L1 2 +#define CV_L2 4 +#define CV_NORM_MASK 7 +#define CV_RELATIVE 8 +#define CV_DIFF 16 +#define CV_MINMAX 32 + +#define CV_DIFF_C (CV_DIFF | CV_C) +#define CV_DIFF_L1 (CV_DIFF | CV_L1) +#define CV_DIFF_L2 (CV_DIFF | CV_L2) +#define CV_RELATIVE_C (CV_RELATIVE | CV_C) +#define CV_RELATIVE_L1 (CV_RELATIVE | CV_L1) +#define CV_RELATIVE_L2 (CV_RELATIVE | CV_L2) + +/* Finds norm, difference norm or relative difference norm for an array (or two arrays) */ +CVAPI(double) cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL), + int norm_type CV_DEFAULT(CV_L2), + const CvArr* mask CV_DEFAULT(NULL) ); + +CVAPI(void) cvNormalize( const CvArr* src, CvArr* dst, + double a CV_DEFAULT(1.), double b CV_DEFAULT(0.), + int norm_type CV_DEFAULT(CV_L2), + const CvArr* mask CV_DEFAULT(NULL) ); + + +#define CV_REDUCE_SUM 0 +#define CV_REDUCE_AVG 1 +#define CV_REDUCE_MAX 2 +#define CV_REDUCE_MIN 3 + +CVAPI(void) cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1), + int op CV_DEFAULT(CV_REDUCE_SUM) ); + +/****************************************************************************************\ +* Discrete Linear Transforms and Related Functions * +\****************************************************************************************/ + +#define CV_DXT_FORWARD 0 +#define CV_DXT_INVERSE 1 +#define CV_DXT_SCALE 2 /* divide result by size of array */ +#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE) +#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE +#define CV_DXT_ROWS 4 /* transform each row individually */ +#define CV_DXT_MUL_CONJ 8 /* conjugate the second argument of cvMulSpectrums */ + +/* Discrete Fourier Transform: + complex->complex, + real->ccs (forward), + ccs->real (inverse) */ +CVAPI(void) cvDFT( const CvArr* src, CvArr* dst, int flags, + int nonzero_rows CV_DEFAULT(0) ); +#define cvFFT cvDFT + +/* Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) */ +CVAPI(void) cvMulSpectrums( const CvArr* src1, const CvArr* src2, + CvArr* dst, int flags ); + +/* Finds optimal DFT vector size >= size0 */ +CVAPI(int) cvGetOptimalDFTSize( int size0 ); + +/* Discrete Cosine Transform */ +CVAPI(void) cvDCT( const CvArr* src, CvArr* dst, int flags ); + +/****************************************************************************************\ +* Dynamic data structures * +\****************************************************************************************/ + +/* Calculates length of sequence slice (with support of negative indices). */ +CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq ); + + +/* Creates new memory storage. + block_size == 0 means that default, + somewhat optimal size, is used (currently, it is 64K) */ +CVAPI(CvMemStorage*) cvCreateMemStorage( int block_size CV_DEFAULT(0)); + + +/* Creates a memory storage that will borrow memory blocks from parent storage */ +CVAPI(CvMemStorage*) cvCreateChildMemStorage( CvMemStorage* parent ); + + +/* Releases memory storage. All the children of a parent must be released before + the parent. A child storage returns all the blocks to parent when it is released */ +CVAPI(void) cvReleaseMemStorage( CvMemStorage** storage ); + + +/* Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos) + to reuse memory allocated for the storage - cvClearSeq,cvClearSet ... + do not free any memory. + A child storage returns all the blocks to the parent when it is cleared */ +CVAPI(void) cvClearMemStorage( CvMemStorage* storage ); + +/* Remember a storage "free memory" position */ +CVAPI(void) cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos ); + +/* Restore a storage "free memory" position */ +CVAPI(void) cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos ); + +/* Allocates continuous buffer of the specified size in the storage */ +CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size ); + +/* Allocates string in memory storage */ +CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, + int len CV_DEFAULT(-1) ); + +/* Creates new empty sequence that will reside in the specified storage */ +CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size, + size_t elem_size, CvMemStorage* storage ); + +/* Changes default size (granularity) of sequence blocks. + The default size is ~1Kbyte */ +CVAPI(void) cvSetSeqBlockSize( CvSeq* seq, int delta_elems ); + + +/* Adds new element to the end of sequence. Returns pointer to the element */ +CVAPI(schar*) cvSeqPush( CvSeq* seq, const void* element CV_DEFAULT(NULL)); + + +/* Adds new element to the beginning of sequence. Returns pointer to it */ +CVAPI(schar*) cvSeqPushFront( CvSeq* seq, const void* element CV_DEFAULT(NULL)); + + +/* Removes the last element from sequence and optionally saves it */ +CVAPI(void) cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL)); + + +/* Removes the first element from sequence and optioanally saves it */ +CVAPI(void) cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL)); + + +#define CV_FRONT 1 +#define CV_BACK 0 +/* Adds several new elements to the end of sequence */ +CVAPI(void) cvSeqPushMulti( CvSeq* seq, const void* elements, + int count, int in_front CV_DEFAULT(0) ); + +/* Removes several elements from the end of sequence and optionally saves them */ +CVAPI(void) cvSeqPopMulti( CvSeq* seq, void* elements, + int count, int in_front CV_DEFAULT(0) ); + +/* Inserts a new element in the middle of sequence. + cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */ +CVAPI(schar*) cvSeqInsert( CvSeq* seq, int before_index, + const void* element CV_DEFAULT(NULL)); + +/* Removes specified sequence element */ +CVAPI(void) cvSeqRemove( CvSeq* seq, int index ); + + +/* Removes all the elements from the sequence. The freed memory + can be reused later only by the same sequence unless cvClearMemStorage + or cvRestoreMemStoragePos is called */ +CVAPI(void) cvClearSeq( CvSeq* seq ); + + +/* Retrieves pointer to specified sequence element. + Negative indices are supported and mean counting from the end + (e.g -1 means the last sequence element) */ +CVAPI(schar*) cvGetSeqElem( const CvSeq* seq, int index ); + +/* Calculates index of the specified sequence element. + Returns -1 if element does not belong to the sequence */ +CVAPI(int) cvSeqElemIdx( const CvSeq* seq, const void* element, + CvSeqBlock** block CV_DEFAULT(NULL) ); + +/* Initializes sequence writer. The new elements will be added to the end of sequence */ +CVAPI(void) cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ); + + +/* Combination of cvCreateSeq and cvStartAppendToSeq */ +CVAPI(void) cvStartWriteSeq( int seq_flags, int header_size, + int elem_size, CvMemStorage* storage, + CvSeqWriter* writer ); + +/* Closes sequence writer, updates sequence header and returns pointer + to the resultant sequence + (which may be useful if the sequence was created using cvStartWriteSeq)) +*/ +CVAPI(CvSeq*) cvEndWriteSeq( CvSeqWriter* writer ); + + +/* Updates sequence header. May be useful to get access to some of previously + written elements via cvGetSeqElem or sequence reader */ +CVAPI(void) cvFlushSeqWriter( CvSeqWriter* writer ); + + +/* Initializes sequence reader. + The sequence can be read in forward or backward direction */ +CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, + int reverse CV_DEFAULT(0) ); + + +/* Returns current sequence reader position (currently observed sequence element) */ +CVAPI(int) cvGetSeqReaderPos( CvSeqReader* reader ); + + +/* Changes sequence reader position. It may seek to an absolute or + to relative to the current position */ +CVAPI(void) cvSetSeqReaderPos( CvSeqReader* reader, int index, + int is_relative CV_DEFAULT(0)); + +/* Copies sequence content to a continuous piece of memory */ +CVAPI(void*) cvCvtSeqToArray( const CvSeq* seq, void* elements, + CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) ); + +/* Creates sequence header for array. + After that all the operations on sequences that do not alter the content + can be applied to the resultant sequence */ +CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size, + int elem_size, void* elements, int total, + CvSeq* seq, CvSeqBlock* block ); + +/* Extracts sequence slice (with or without copying sequence elements) */ +CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice, + CvMemStorage* storage CV_DEFAULT(NULL), + int copy_data CV_DEFAULT(0)); + +CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT(NULL)) +{ + return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 ); +} + +/* Removes sequence slice */ +CVAPI(void) cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ); + +/* Inserts a sequence or array into another sequence */ +CVAPI(void) cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ); + +/* a < b ? -1 : a > b ? 1 : 0 */ +typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata ); + +/* Sorts sequence in-place given element comparison function */ +CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) ); + +/* Finds element in a [sorted] sequence */ +CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, + int is_sorted, int* elem_idx, + void* userdata CV_DEFAULT(NULL) ); + +/* Reverses order of sequence elements in-place */ +CVAPI(void) cvSeqInvert( CvSeq* seq ); + +/* Splits sequence into one or more equivalence classes using the specified criteria */ +CVAPI(int) cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, + CvSeq** labels, CvCmpFunc is_equal, void* userdata ); + +/************ Internal sequence functions ************/ +CVAPI(void) cvChangeSeqBlock( void* reader, int direction ); +CVAPI(void) cvCreateSeqBlock( CvSeqWriter* writer ); + + +/* Creates a new set */ +CVAPI(CvSet*) cvCreateSet( int set_flags, int header_size, + int elem_size, CvMemStorage* storage ); + +/* Adds new element to the set and returns pointer to it */ +CVAPI(int) cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL), + CvSetElem** inserted_elem CV_DEFAULT(NULL) ); + +/* Fast variant of cvSetAdd */ +CV_INLINE CvSetElem* cvSetNew( CvSet* set_header ) +{ + CvSetElem* elem = set_header->free_elems; + if( elem ) + { + set_header->free_elems = elem->next_free; + elem->flags = elem->flags & CV_SET_ELEM_IDX_MASK; + set_header->active_count++; + } + else + cvSetAdd( set_header, NULL, (CvSetElem**)&elem ); + return elem; +} + +/* Removes set element given its pointer */ +CV_INLINE void cvSetRemoveByPtr( CvSet* set_header, void* elem ) +{ + CvSetElem* _elem = (CvSetElem*)elem; + assert( _elem->flags >= 0 /*&& (elem->flags & CV_SET_ELEM_IDX_MASK) < set_header->total*/ ); + _elem->next_free = set_header->free_elems; + _elem->flags = (_elem->flags & CV_SET_ELEM_IDX_MASK) | CV_SET_ELEM_FREE_FLAG; + set_header->free_elems = _elem; + set_header->active_count--; +} + +/* Removes element from the set by its index */ +CVAPI(void) cvSetRemove( CvSet* set_header, int index ); + +/* Returns a set element by index. If the element doesn't belong to the set, + NULL is returned */ +CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx ) +{ + CvSetElem* elem = (CvSetElem*)cvGetSeqElem( (CvSeq*)set_header, idx ); + return elem && CV_IS_SET_ELEM( elem ) ? elem : 0; +} + +/* Removes all the elements from the set */ +CVAPI(void) cvClearSet( CvSet* set_header ); + +/* Creates new graph */ +CVAPI(CvGraph*) cvCreateGraph( int graph_flags, int header_size, + int vtx_size, int edge_size, + CvMemStorage* storage ); + +/* Adds new vertex to the graph */ +CVAPI(int) cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL), + CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) ); + + +/* Removes vertex from the graph together with all incident edges */ +CVAPI(int) cvGraphRemoveVtx( CvGraph* graph, int index ); +CVAPI(int) cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ); + + +/* Link two vertices specifed by indices or pointers if they + are not connected or return pointer to already existing edge + connecting the vertices. + Functions return 1 if a new edge was created, 0 otherwise */ +CVAPI(int) cvGraphAddEdge( CvGraph* graph, + int start_idx, int end_idx, + const CvGraphEdge* edge CV_DEFAULT(NULL), + CvGraphEdge** inserted_edge CV_DEFAULT(NULL) ); + +CVAPI(int) cvGraphAddEdgeByPtr( CvGraph* graph, + CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, + const CvGraphEdge* edge CV_DEFAULT(NULL), + CvGraphEdge** inserted_edge CV_DEFAULT(NULL) ); + +/* Remove edge connecting two vertices */ +CVAPI(void) cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ); +CVAPI(void) cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, + CvGraphVtx* end_vtx ); + +/* Find edge connecting two vertices */ +CVAPI(CvGraphEdge*) cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ); +CVAPI(CvGraphEdge*) cvFindGraphEdgeByPtr( const CvGraph* graph, + const CvGraphVtx* start_vtx, + const CvGraphVtx* end_vtx ); +#define cvGraphFindEdge cvFindGraphEdge +#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr + +/* Remove all vertices and edges from the graph */ +CVAPI(void) cvClearGraph( CvGraph* graph ); + + +/* Count number of edges incident to the vertex */ +CVAPI(int) cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ); +CVAPI(int) cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ); + + +/* Retrieves graph vertex by given index */ +#define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx)) + +/* Retrieves index of a graph vertex given its pointer */ +#define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK) + +/* Retrieves index of a graph edge given its pointer */ +#define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK) + +#define cvGraphGetVtxCount( graph ) ((graph)->active_count) +#define cvGraphGetEdgeCount( graph ) ((graph)->edges->active_count) + +#define CV_GRAPH_VERTEX 1 +#define CV_GRAPH_TREE_EDGE 2 +#define CV_GRAPH_BACK_EDGE 4 +#define CV_GRAPH_FORWARD_EDGE 8 +#define CV_GRAPH_CROSS_EDGE 16 +#define CV_GRAPH_ANY_EDGE 30 +#define CV_GRAPH_NEW_TREE 32 +#define CV_GRAPH_BACKTRACKING 64 +#define CV_GRAPH_OVER -1 + +#define CV_GRAPH_ALL_ITEMS -1 + +/* flags for graph vertices and edges */ +#define CV_GRAPH_ITEM_VISITED_FLAG (1 << 30) +#define CV_IS_GRAPH_VERTEX_VISITED(vtx) \ + (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG) +#define CV_IS_GRAPH_EDGE_VISITED(edge) \ + (((CvGraphEdge*)(edge))->flags & CV_GRAPH_ITEM_VISITED_FLAG) +#define CV_GRAPH_SEARCH_TREE_NODE_FLAG (1 << 29) +#define CV_GRAPH_FORWARD_EDGE_FLAG (1 << 28) + +typedef struct CvGraphScanner +{ + CvGraphVtx* vtx; /* current graph vertex (or current edge origin) */ + CvGraphVtx* dst; /* current graph edge destination vertex */ + CvGraphEdge* edge; /* current edge */ + + CvGraph* graph; /* the graph */ + CvSeq* stack; /* the graph vertex stack */ + int index; /* the lower bound of certainly visited vertices */ + int mask; /* event mask */ +} +CvGraphScanner; + +/* Creates new graph scanner. */ +CVAPI(CvGraphScanner*) cvCreateGraphScanner( CvGraph* graph, + CvGraphVtx* vtx CV_DEFAULT(NULL), + int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS)); + +/* Releases graph scanner. */ +CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner ); + +/* Get next graph element */ +CVAPI(int) cvNextGraphItem( CvGraphScanner* scanner ); + +/* Creates a copy of graph */ +CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ); + +/****************************************************************************************\ +* Drawing * +\****************************************************************************************/ + +/****************************************************************************************\ +* Drawing functions work with images/matrices of arbitrary type. * +* For color images the channel order is BGR[A] * +* Antialiasing is supported only for 8-bit image now. * +* All the functions include parameter color that means rgb value (that may be * +* constructed with CV_RGB macro) for color images and brightness * +* for grayscale images. * +* If a drawn figure is partially or completely outside of the image, it is clipped.* +\****************************************************************************************/ + +#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 ) +#define CV_FILLED -1 + +#define CV_AA 16 + +/* Draws 4-connected, 8-connected or antialiased line segment connecting two points */ +CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +/* Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2), + if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn */ +CVAPI(void) cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + int shift CV_DEFAULT(0)); + +/* Draws a rectangle specified by a CvRect structure */ +CVAPI(void) cvRectangleR( CvArr* img, CvRect r, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + int shift CV_DEFAULT(0)); + + +/* Draws a circle with specified center and radius. + Thickness works in the same way as with cvRectangle */ +CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +/* Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector, + depending on , and parameters. The resultant figure + is rotated by . All the angles are in degrees */ +CVAPI(void) cvEllipse( CvArr* img, CvPoint center, CvSize axes, + double angle, double start_angle, double end_angle, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +CV_INLINE void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, + int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ) +{ + CvSize axes; + axes.width = cvRound(box.size.width*0.5); + axes.height = cvRound(box.size.height*0.5); + + cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle, + 0, 360, color, thickness, line_type, shift ); +} + +/* Fills convex or monotonous polygon. */ +CVAPI(void) cvFillConvexPoly( CvArr* img, const CvPoint* pts, int npts, CvScalar color, + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +/* Fills an area bounded by one or more arbitrary polygons */ +CVAPI(void) cvFillPoly( CvArr* img, CvPoint** pts, const int* npts, + int contours, CvScalar color, + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +/* Draws one or more polygonal curves */ +CVAPI(void) cvPolyLine( CvArr* img, CvPoint** pts, const int* npts, int contours, + int is_closed, CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +#define cvDrawRect cvRectangle +#define cvDrawLine cvLine +#define cvDrawCircle cvCircle +#define cvDrawEllipse cvEllipse +#define cvDrawPolyLine cvPolyLine + +/* Clips the line segment connecting *pt1 and *pt2 + by the rectangular window + (0<=xptr will point + to pt1 (or pt2, see left_to_right description) location in the image. + Returns the number of pixels on the line between the ending points. */ +CVAPI(int) cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2, + CvLineIterator* line_iterator, + int connectivity CV_DEFAULT(8), + int left_to_right CV_DEFAULT(0)); + +/* Moves iterator to the next line point */ +#define CV_NEXT_LINE_POINT( line_iterator ) \ +{ \ + int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \ + (line_iterator).err += (line_iterator).minus_delta + \ + ((line_iterator).plus_delta & _line_iterator_mask); \ + (line_iterator).ptr += (line_iterator).minus_step + \ + ((line_iterator).plus_step & _line_iterator_mask); \ +} + + +/* basic font types */ +#define CV_FONT_HERSHEY_SIMPLEX 0 +#define CV_FONT_HERSHEY_PLAIN 1 +#define CV_FONT_HERSHEY_DUPLEX 2 +#define CV_FONT_HERSHEY_COMPLEX 3 +#define CV_FONT_HERSHEY_TRIPLEX 4 +#define CV_FONT_HERSHEY_COMPLEX_SMALL 5 +#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX 6 +#define CV_FONT_HERSHEY_SCRIPT_COMPLEX 7 + +/* font flags */ +#define CV_FONT_ITALIC 16 + +#define CV_FONT_VECTOR0 CV_FONT_HERSHEY_SIMPLEX + + +/* Font structure */ +typedef struct CvFont +{ + const char* nameFont; //Qt:nameFont + CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red\_component[, alpha_component]) + int font_face; //Qt: bool italic /* =CV_FONT_* */ + const int* ascii; /* font data and metrics */ + const int* greek; + const int* cyrillic; + float hscale, vscale; + float shear; /* slope coefficient: 0 - normal, >0 - italic */ + int thickness; //Qt: weight /* letters thickness */ + float dx; /* horizontal interval between letters */ + int line_type; //Qt: PointSize +} +CvFont; + +/* Initializes font structure used further in cvPutText */ +CVAPI(void) cvInitFont( CvFont* font, int font_face, + double hscale, double vscale, + double shear CV_DEFAULT(0), + int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8)); + +CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) ) +{ + CvFont font; + cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA ); + return font; +} + +/* Renders text stroke with specified font and color at specified location. + CvFont should be initialized with cvInitFont */ +CVAPI(void) cvPutText( CvArr* img, const char* text, CvPoint org, + const CvFont* font, CvScalar color ); + +/* Calculates bounding box of text stroke (useful for alignment) */ +CVAPI(void) cvGetTextSize( const char* text_string, const CvFont* font, + CvSize* text_size, int* baseline ); + + + +/* Unpacks color value, if arrtype is CV_8UC?, is treated as + packed color value, otherwise the first channels (depending on arrtype) + of destination scalar are set to the same value = */ +CVAPI(CvScalar) cvColorToScalar( double packed_color, int arrtype ); + +/* Returns the polygon points which make up the given ellipse. The ellipse is define by + the box of size 'axes' rotated 'angle' around the 'center'. A partial sweep + of the ellipse arc can be done by spcifying arc_start and arc_end to be something + other than 0 and 360, respectively. The input array 'pts' must be large enough to + hold the result. The total number of points stored into 'pts' is returned by this + function. */ +CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes, + int angle, int arc_start, int arc_end, CvPoint * pts, int delta ); + +/* Draws contour outlines or filled interiors on the image */ +CVAPI(void) cvDrawContours( CvArr *img, CvSeq* contour, + CvScalar external_color, CvScalar hole_color, + int max_level, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + CvPoint offset CV_DEFAULT(cvPoint(0,0))); + +/* Does look-up transformation. Elements of the source array + (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */ +CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut ); + + +/******************* Iteration through the sequence tree *****************/ +typedef struct CvTreeNodeIterator +{ + const void* node; + int level; + int max_level; +} +CvTreeNodeIterator; + +CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, + const void* first, int max_level ); +CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator ); +CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ); + +/* Inserts sequence into tree with specified "parent" sequence. + If parent is equal to frame (e.g. the most external contour), + then added contour will have null pointer to parent. */ +CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame ); + +/* Removes contour from tree (together with the contour children). */ +CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame ); + +/* Gathers pointers to all the sequences, + accessible from the , to the single sequence */ +CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size, + CvMemStorage* storage ); + +/* The function implements the K-means algorithm for clustering an array of sample + vectors in a specified number of classes */ +#define CV_KMEANS_USE_INITIAL_LABELS 1 +CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, + CvTermCriteria termcrit, int attempts CV_DEFAULT(1), + CvRNG* rng CV_DEFAULT(0), int flags CV_DEFAULT(0), + CvArr* _centers CV_DEFAULT(0), double* compactness CV_DEFAULT(0) ); + +/****************************************************************************************\ +* System functions * +\****************************************************************************************/ + +/* Add the function pointers table with associated information to the IPP primitives list */ +CVAPI(int) cvRegisterModule( const CvModuleInfo* module_info ); + +/* Loads optimized functions from IPP, MKL etc. or switches back to pure C code */ +CVAPI(int) cvUseOptimized( int on_off ); + +/* Retrieves information about the registered modules and loaded optimized plugins */ +CVAPI(void) cvGetModuleInfo( const char* module_name, + const char** version, + const char** loaded_addon_plugins ); + +typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata); +typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata); + +/* Set user-defined memory managment functions (substitutors for malloc and free) that + will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage) */ +CVAPI(void) cvSetMemoryManager( CvAllocFunc alloc_func CV_DEFAULT(NULL), + CvFreeFunc free_func CV_DEFAULT(NULL), + void* userdata CV_DEFAULT(NULL)); + + +typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) + (int,int,int,char*,char*,int,int,int,int,int, + IplROI*,IplImage*,void*,IplTileInfo*); +typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int); +typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int); +typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int); +typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*); + +/* Makes OpenCV use IPL functions for IplImage allocation/deallocation */ +CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, + Cv_iplAllocateImageData allocate_data, + Cv_iplDeallocate deallocate, + Cv_iplCreateROI create_roi, + Cv_iplCloneImage clone_image ); + +#define CV_TURN_ON_IPL_COMPATIBILITY() \ + cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, \ + iplDeallocate, iplCreateROI, iplCloneImage ) + +/****************************************************************************************\ +* Data Persistence * +\****************************************************************************************/ + +/********************************** High-level functions ********************************/ + +/* opens existing or creates new file storage */ +CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, + int flags, const char* encoding CV_DEFAULT(NULL) ); + +/* closes file storage and deallocates buffers */ +CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs ); + +/* returns attribute value or 0 (NULL) if there is no such attribute */ +CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name ); + +/* starts writing compound structure (map or sequence) */ +CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name, + int struct_flags, const char* type_name CV_DEFAULT(NULL), + CvAttrList attributes CV_DEFAULT(cvAttrList())); + +/* finishes writing compound structure */ +CVAPI(void) cvEndWriteStruct( CvFileStorage* fs ); + +/* writes an integer */ +CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value ); + +/* writes a floating-point number */ +CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value ); + +/* writes a string */ +CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name, + const char* str, int quote CV_DEFAULT(0) ); + +/* writes a comment */ +CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment, + int eol_comment ); + +/* writes instance of a standard type (matrix, image, sequence, graph etc.) + or user-defined type */ +CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr, + CvAttrList attributes CV_DEFAULT(cvAttrList())); + +/* starts the next stream */ +CVAPI(void) cvStartNextStream( CvFileStorage* fs ); + +/* helper function: writes multiple integer or floating-point numbers */ +CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src, + int len, const char* dt ); + +/* returns the hash entry corresponding to the specified literal key string or 0 + if there is no such a key in the storage */ +CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name, + int len CV_DEFAULT(-1), + int create_missing CV_DEFAULT(0)); + +/* returns file node with the specified key within the specified map + (collection of named nodes) */ +CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs, + int stream_index CV_DEFAULT(0) ); + +/* returns file node with the specified key within the specified map + (collection of named nodes) */ +CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map, + const CvStringHashNode* key, + int create_missing CV_DEFAULT(0) ); + +/* this is a slower version of cvGetFileNode that takes the key as a literal string */ +CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs, + const CvFileNode* map, + const char* name ); + +CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) ) +{ + return !node ? default_value : + CV_NODE_IS_INT(node->tag) ? node->data.i : + CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff; +} + + +CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, int default_value CV_DEFAULT(0) ) +{ + return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value ); +} + + +CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) ) +{ + return !node ? default_value : + CV_NODE_IS_INT(node->tag) ? (double)node->data.i : + CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300; +} + + +CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, double default_value CV_DEFAULT(0.) ) +{ + return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value ); +} + + +CV_INLINE const char* cvReadString( const CvFileNode* node, + const char* default_value CV_DEFAULT(NULL) ) +{ + return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0; +} + + +CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, const char* default_value CV_DEFAULT(NULL) ) +{ + return cvReadString( cvGetFileNodeByName( fs, map, name ), default_value ); +} + + +/* decodes standard or user-defined object and returns it */ +CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node, + CvAttrList* attributes CV_DEFAULT(NULL)); + +/* decodes standard or user-defined object and returns it */ +CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, + const char* name, CvAttrList* attributes CV_DEFAULT(NULL) ) +{ + return cvRead( fs, cvGetFileNodeByName( fs, map, name ), attributes ); +} + + +/* starts reading data from sequence or scalar numeric node */ +CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, + CvSeqReader* reader ); + +/* reads multiple numbers and stores them to array */ +CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, + int count, void* dst, const char* dt ); + +/* combination of two previous functions for easier reading of whole sequences */ +CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, + void* dst, const char* dt ); + +/* writes a copy of file node to file storage */ +CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, + const CvFileNode* node, int embed ); + +/* returns name of file node */ +CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node ); + +/*********************************** Adding own types ***********************************/ + +CVAPI(void) cvRegisterType( const CvTypeInfo* info ); +CVAPI(void) cvUnregisterType( const char* type_name ); +CVAPI(CvTypeInfo*) cvFirstType(void); +CVAPI(CvTypeInfo*) cvFindType( const char* type_name ); +CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr ); + +/* universal functions */ +CVAPI(void) cvRelease( void** struct_ptr ); +CVAPI(void*) cvClone( const void* struct_ptr ); + +/* simple API for reading/writing data */ +CVAPI(void) cvSave( const char* filename, const void* struct_ptr, + const char* name CV_DEFAULT(NULL), + const char* comment CV_DEFAULT(NULL), + CvAttrList attributes CV_DEFAULT(cvAttrList())); +CVAPI(void*) cvLoad( const char* filename, + CvMemStorage* memstorage CV_DEFAULT(NULL), + const char* name CV_DEFAULT(NULL), + const char** real_name CV_DEFAULT(NULL) ); + +/*********************************** Measuring Execution Time ***************************/ + +/* helper functions for RNG initialization and accurate time measurement: + uses internal clock counter on x86 */ +CVAPI(int64) cvGetTickCount( void ); +CVAPI(double) cvGetTickFrequency( void ); + +/*********************************** CPU capabilities ***********************************/ + +#define CV_CPU_NONE 0 +#define CV_CPU_MMX 1 +#define CV_CPU_SSE 2 +#define CV_CPU_SSE2 3 +#define CV_CPU_SSE3 4 +#define CV_CPU_SSSE3 5 +#define CV_CPU_SSE4_1 6 +#define CV_CPU_SSE4_2 7 +#define CV_CPU_POPCNT 8 +#define CV_CPU_AVX 10 +#define CV_HARDWARE_MAX_FEATURE 255 + +CVAPI(int) cvCheckHardwareSupport(int feature); + +/*********************************** Multi-Threading ************************************/ + +/* retrieve/set the number of threads used in OpenMP implementations */ +CVAPI(int) cvGetNumThreads( void ); +CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) ); +/* get index of the thread being executed */ +CVAPI(int) cvGetThreadNum( void ); + + +/********************************** Error Handling **************************************/ + +/* Get current OpenCV error status */ +CVAPI(int) cvGetErrStatus( void ); + +/* Sets error status silently */ +CVAPI(void) cvSetErrStatus( int status ); + +#define CV_ErrModeLeaf 0 /* Print error and exit program */ +#define CV_ErrModeParent 1 /* Print error and continue */ +#define CV_ErrModeSilent 2 /* Don't print and continue */ + +/* Retrives current error processing mode */ +CVAPI(int) cvGetErrMode( void ); + +/* Sets error processing mode, returns previously used mode */ +CVAPI(int) cvSetErrMode( int mode ); + +/* Sets error status and performs some additonal actions (displaying message box, + writing message to stderr, terminating application etc.) + depending on the current error mode */ +CVAPI(void) cvError( int status, const char* func_name, + const char* err_msg, const char* file_name, int line ); + +/* Retrieves textual description of the error given its code */ +CVAPI(const char*) cvErrorStr( int status ); + +/* Retrieves detailed information about the last error occured */ +CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description, + const char** filename, int* line ); + +/* Maps IPP error codes to the counterparts from OpenCV */ +CVAPI(int) cvErrorFromIppStatus( int ipp_status ); + +typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, + const char* err_msg, const char* file_name, int line, void* userdata ); + +/* Assigns a new error-handling function */ +CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler, + void* userdata CV_DEFAULT(NULL), + void** prev_userdata CV_DEFAULT(NULL) ); + +/* + Output to: + cvNulDevReport - nothing + cvStdErrReport - console(fprintf(stderr,...)) + cvGuiBoxReport - MessageBox(WIN32) + */ +CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +#define OPENCV_ERROR(status,func,context) \ +cvError((status),(func),(context),__FILE__,__LINE__) + +#define OPENCV_ERRCHK(func,context) \ +{if (cvGetErrStatus() >= 0) \ +{OPENCV_ERROR(CV_StsBackTrace,(func),(context));}} + +#define OPENCV_ASSERT(expr,func,context) \ +{if (! (expr)) \ +{OPENCV_ERROR(CV_StsInternal,(func),(context));}} + +#define OPENCV_RSTERR() (cvSetErrStatus(CV_StsOk)) + +#define OPENCV_CALL( Func ) \ +{ \ +Func; \ +} + + +/* CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */ +#ifdef CV_NO_FUNC_NAMES +#define CV_FUNCNAME( Name ) +#define cvFuncName "" +#else +#define CV_FUNCNAME( Name ) \ +static char cvFuncName[] = Name +#endif + + +/* + CV_ERROR macro unconditionally raises error with passed code and message. + After raising error, control will be transferred to the exit label. + */ +#define CV_ERROR( Code, Msg ) \ +{ \ + cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ + __CV_EXIT__; \ +} + +/* Simplified form of CV_ERROR */ +#define CV_ERROR_FROM_CODE( code ) \ + CV_ERROR( code, "" ) + +/* + CV_CHECK macro checks error status after CV (or IPL) + function call. If error detected, control will be transferred to the exit + label. + */ +#define CV_CHECK() \ +{ \ + if( cvGetErrStatus() < 0 ) \ + CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \ +} + + +/* + CV_CALL macro calls CV (or IPL) function, checks error status and + signals a error if the function failed. Useful in "parent node" + error procesing mode + */ +#define CV_CALL( Func ) \ +{ \ + Func; \ + CV_CHECK(); \ +} + + +/* Runtime assertion macro */ +#define CV_ASSERT( Condition ) \ +{ \ + if( !(Condition) ) \ + CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \ +} + +#define __CV_BEGIN__ { +#define __CV_END__ goto exit; exit: ; } +#define __CV_EXIT__ goto exit + +#ifdef __cplusplus +} + +// classes for automatic module/RTTI data registration/unregistration +struct CV_EXPORTS CvModule +{ + CvModule( CvModuleInfo* _info ); + ~CvModule(); + CvModuleInfo* info; + + static CvModuleInfo* first; + static CvModuleInfo* last; +}; + +struct CV_EXPORTS CvType +{ + CvType( const char* type_name, + CvIsInstanceFunc is_instance, CvReleaseFunc release=0, + CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 ); + ~CvType(); + CvTypeInfo* info; + + static CvTypeInfo* first; + static CvTypeInfo* last; +}; + +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/cuda_devptrs.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/cuda_devptrs.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/cuda_devptrs.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/cuda_devptrs.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,199 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_DEVPTRS_HPP__ +#define __OPENCV_CORE_DEVPTRS_HPP__ + +#ifdef __cplusplus + +#ifdef __CUDACC__ + #define __CV_GPU_HOST_DEVICE__ __host__ __device__ __forceinline__ +#else + #define __CV_GPU_HOST_DEVICE__ +#endif + +namespace cv +{ + namespace gpu + { + // Simple lightweight structures that encapsulates information about an image on device. + // It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile + + template struct StaticAssert; + template <> struct StaticAssert {static __CV_GPU_HOST_DEVICE__ void check(){}}; + + template struct DevPtr + { + typedef T elem_type; + typedef int index_type; + + enum { elem_size = sizeof(elem_type) }; + + T* data; + + __CV_GPU_HOST_DEVICE__ DevPtr() : data(0) {} + __CV_GPU_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {} + + __CV_GPU_HOST_DEVICE__ size_t elemSize() const { return elem_size; } + __CV_GPU_HOST_DEVICE__ operator T*() { return data; } + __CV_GPU_HOST_DEVICE__ operator const T*() const { return data; } + }; + + template struct PtrSz : public DevPtr + { + __CV_GPU_HOST_DEVICE__ PtrSz() : size(0) {} + __CV_GPU_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr(data_), size(size_) {} + + size_t size; + }; + + template struct PtrStep : public DevPtr + { + __CV_GPU_HOST_DEVICE__ PtrStep() : step(0) {} + __CV_GPU_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr(data_), step(step_) {} + + /** \brief stride between two consecutive rows in bytes. Step is stored always and everywhere in bytes!!! */ + size_t step; + + __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr::data + y * step); } + __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr::data + y * step); } + + __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } + __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } + }; + + template struct PtrStepSz : public PtrStep + { + __CV_GPU_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {} + __CV_GPU_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_) + : PtrStep(data_, step_), cols(cols_), rows(rows_) {} + + template + explicit PtrStepSz(const PtrStepSz& d) : PtrStep((T*)d.data, d.step), cols(d.cols), rows(d.rows){} + + int cols; + int rows; + }; + + typedef PtrStepSz PtrStepSzb; + typedef PtrStepSz PtrStepSzf; + typedef PtrStepSz PtrStepSzi; + + typedef PtrStep PtrStepb; + typedef PtrStep PtrStepf; + typedef PtrStep PtrStepi; + + +#if defined __GNUC__ + #define __CV_GPU_DEPR_BEFORE__ + #define __CV_GPU_DEPR_AFTER__ __attribute__ ((deprecated)) +#elif defined(__MSVC__) //|| defined(__CUDACC__) + #pragma deprecated(DevMem2D_) + #define __CV_GPU_DEPR_BEFORE__ __declspec(deprecated) + #define __CV_GPU_DEPR_AFTER__ +#else + #define __CV_GPU_DEPR_BEFORE__ + #define __CV_GPU_DEPR_AFTER__ +#endif + + template struct __CV_GPU_DEPR_BEFORE__ DevMem2D_ : public PtrStepSz + { + DevMem2D_() {} + DevMem2D_(int rows_, int cols_, T* data_, size_t step_) : PtrStepSz(rows_, cols_, data_, step_) {} + + template + explicit __CV_GPU_DEPR_BEFORE__ DevMem2D_(const DevMem2D_& d) : PtrStepSz(d.rows, d.cols, (T*)d.data, d.step) {} + } __CV_GPU_DEPR_AFTER__ ; + + typedef DevMem2D_ DevMem2Db; + typedef DevMem2Db DevMem2D; + typedef DevMem2D_ DevMem2Df; + typedef DevMem2D_ DevMem2Di; + + template struct PtrElemStep_ : public PtrStep + { + PtrElemStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) + { + StaticAssert<256 % sizeof(T) == 0>::check(); + + PtrStep::step /= PtrStep::elem_size; + } + __CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return PtrStep::data + y * PtrStep::step; } + __CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return PtrStep::data + y * PtrStep::step; } + + __CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } + __CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } + }; + + template struct PtrStep_ : public PtrStep + { + PtrStep_() {} + PtrStep_(const DevMem2D_& mem) : PtrStep(mem.data, mem.step) {} + }; + + typedef PtrElemStep_ PtrElemStep; + typedef PtrElemStep_ PtrElemStepf; + typedef PtrElemStep_ PtrElemStepi; + +//#undef __CV_GPU_DEPR_BEFORE__ +//#undef __CV_GPU_DEPR_AFTER__ + + namespace device + { + using cv::gpu::PtrSz; + using cv::gpu::PtrStep; + using cv::gpu::PtrStepSz; + + using cv::gpu::PtrStepSzb; + using cv::gpu::PtrStepSzf; + using cv::gpu::PtrStepSzi; + + using cv::gpu::PtrStepb; + using cv::gpu::PtrStepf; + using cv::gpu::PtrStepi; + } + } +} + +#endif // __cplusplus + +#endif /* __OPENCV_CORE_DEVPTRS_HPP__ */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/devmem2d.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/devmem2d.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/devmem2d.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/devmem2d.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,43 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "opencv2/core/cuda_devptrs.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/eigen.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/eigen.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/eigen.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/eigen.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,281 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_EIGEN_HPP__ +#define __OPENCV_CORE_EIGEN_HPP__ + +#ifdef __cplusplus + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" + +#if defined _MSC_VER && _MSC_VER >= 1200 +#pragma warning( disable: 4714 ) //__forceinline is not inlined +#pragma warning( disable: 4127 ) //conditional expression is constant +#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data +#endif + +namespace cv +{ + +template +void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst ) +{ + if( !(src.Flags & Eigen::RowMajorBit) ) + { + Mat _src(src.cols(), src.rows(), DataType<_Tp>::type, + (void*)src.data(), src.stride()*sizeof(_Tp)); + transpose(_src, dst); + } + else + { + Mat _src(src.rows(), src.cols(), DataType<_Tp>::type, + (void*)src.data(), src.stride()*sizeof(_Tp)); + _src.copyTo(dst); + } +} + +template +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst ) +{ + CV_DbgAssert(src.rows == _rows && src.cols == _cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else if( src.cols == src.rows ) + { + src.convertTo(_dst, _dst.type()); + transpose(_dst, _dst); + } + else + Mat(src.t()).convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +// Matx case +template +void cv2eigen( const Matx<_Tp, _rows, _cols>& src, + Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst ) +{ + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(_cols, _rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + transpose(src, _dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(_rows, _cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +template +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst ) +{ + dst.resize(src.rows, src.cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else if( src.cols == src.rows ) + { + src.convertTo(_dst, _dst.type()); + transpose(_dst, _dst); + } + else + Mat(src.t()).convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +// Matx case +template +void cv2eigen( const Matx<_Tp, _rows, _cols>& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst ) +{ + dst.resize(_rows, _cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(_cols, _rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + transpose(src, _dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(_rows, _cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +template +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst ) +{ + CV_Assert(src.cols == 1); + dst.resize(src.rows); + + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else + Mat(src.t()).convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +// Matx case +template +void cv2eigen( const Matx<_Tp, _rows, 1>& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst ) +{ + dst.resize(_rows); + + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(1, _rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + transpose(src, _dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(_rows, 1, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + src.copyTo(_dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + + +template +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst ) +{ + CV_Assert(src.rows == 1); + dst.resize(src.cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else + Mat(src.t()).convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + +//Matx +template +void cv2eigen( const Matx<_Tp, 1, _cols>& src, + Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst ) +{ + dst.resize(_cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + Mat _dst(_cols, 1, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + transpose(src, _dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } + else + { + Mat _dst(1, _cols, DataType<_Tp>::type, + dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + CV_DbgAssert(_dst.data == (uchar*)dst.data()); + } +} + + +} + +#endif + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/gpumat.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/gpumat.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/gpumat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/gpumat.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,562 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_GPUMAT_HPP__ +#define __OPENCV_GPUMAT_HPP__ + +#ifdef __cplusplus + +#include "opencv2/core/core.hpp" +#include "opencv2/core/cuda_devptrs.hpp" + +namespace cv { namespace gpu +{ + //////////////////////////////// Initialization & Info //////////////////////// + + //! This is the only function that do not throw exceptions if the library is compiled without Cuda. + CV_EXPORTS int getCudaEnabledDeviceCount(); + + //! Functions below throw cv::Expception if the library is compiled without Cuda. + + CV_EXPORTS void setDevice(int device); + CV_EXPORTS int getDevice(); + + //! Explicitly destroys and cleans up all resources associated with the current device in the current process. + //! Any subsequent API call to this device will reinitialize the device. + CV_EXPORTS void resetDevice(); + + enum FeatureSet + { + FEATURE_SET_COMPUTE_10 = 10, + FEATURE_SET_COMPUTE_11 = 11, + FEATURE_SET_COMPUTE_12 = 12, + FEATURE_SET_COMPUTE_13 = 13, + FEATURE_SET_COMPUTE_20 = 20, + FEATURE_SET_COMPUTE_21 = 21, + FEATURE_SET_COMPUTE_30 = 30, + FEATURE_SET_COMPUTE_35 = 35, + + GLOBAL_ATOMICS = FEATURE_SET_COMPUTE_11, + SHARED_ATOMICS = FEATURE_SET_COMPUTE_12, + NATIVE_DOUBLE = FEATURE_SET_COMPUTE_13, + WARP_SHUFFLE_FUNCTIONS = FEATURE_SET_COMPUTE_30, + DYNAMIC_PARALLELISM = FEATURE_SET_COMPUTE_35 + }; + + // Checks whether current device supports the given feature + CV_EXPORTS bool deviceSupports(FeatureSet feature_set); + + // Gives information about what GPU archs this OpenCV GPU module was + // compiled for + class CV_EXPORTS TargetArchs + { + public: + static bool builtWith(FeatureSet feature_set); + static bool has(int major, int minor); + static bool hasPtx(int major, int minor); + static bool hasBin(int major, int minor); + static bool hasEqualOrLessPtx(int major, int minor); + static bool hasEqualOrGreater(int major, int minor); + static bool hasEqualOrGreaterPtx(int major, int minor); + static bool hasEqualOrGreaterBin(int major, int minor); + private: + TargetArchs(); + }; + + // Gives information about the given GPU + class CV_EXPORTS DeviceInfo + { + public: + // Creates DeviceInfo object for the current GPU + DeviceInfo() : device_id_(getDevice()) { query(); } + + // Creates DeviceInfo object for the given GPU + DeviceInfo(int device_id) : device_id_(device_id) { query(); } + + std::string name() const { return name_; } + + // Return compute capability versions + int majorVersion() const { return majorVersion_; } + int minorVersion() const { return minorVersion_; } + + int multiProcessorCount() const { return multi_processor_count_; } + + size_t sharedMemPerBlock() const; + + void queryMemory(size_t& totalMemory, size_t& freeMemory) const; + size_t freeMemory() const; + size_t totalMemory() const; + + // Checks whether device supports the given feature + bool supports(FeatureSet feature_set) const; + + // Checks whether the GPU module can be run on the given device + bool isCompatible() const; + + int deviceID() const { return device_id_; } + + private: + void query(); + + int device_id_; + + std::string name_; + int multi_processor_count_; + int majorVersion_; + int minorVersion_; + }; + + CV_EXPORTS void printCudaDeviceInfo(int device); + CV_EXPORTS void printShortCudaDeviceInfo(int device); + + //////////////////////////////// GpuMat /////////////////////////////// + + //! Smart pointer for GPU memory with reference counting. Its interface is mostly similar with cv::Mat. + class CV_EXPORTS GpuMat + { + public: + //! default constructor + GpuMat(); + + //! constructs GpuMatrix of the specified size and type (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + GpuMat(int rows, int cols, int type); + GpuMat(Size size, int type); + + //! constucts GpuMatrix and fills it with the specified value _s. + GpuMat(int rows, int cols, int type, Scalar s); + GpuMat(Size size, int type, Scalar s); + + //! copy constructor + GpuMat(const GpuMat& m); + + //! constructor for GpuMatrix headers pointing to user-allocated data + GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP); + GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP); + + //! creates a matrix header for a part of the bigger matrix + GpuMat(const GpuMat& m, Range rowRange, Range colRange); + GpuMat(const GpuMat& m, Rect roi); + + //! builds GpuMat from Mat. Perfom blocking upload to device. + explicit GpuMat(const Mat& m); + + //! destructor - calls release() + ~GpuMat(); + + //! assignment operators + GpuMat& operator = (const GpuMat& m); + + //! pefroms blocking upload data to GpuMat. + void upload(const Mat& m); + + //! downloads data from device to host memory. Blocking calls. + void download(Mat& m) const; + + //! returns a new GpuMatrix header for the specified row + GpuMat row(int y) const; + //! returns a new GpuMatrix header for the specified column + GpuMat col(int x) const; + //! ... for the specified row span + GpuMat rowRange(int startrow, int endrow) const; + GpuMat rowRange(Range r) const; + //! ... for the specified column span + GpuMat colRange(int startcol, int endcol) const; + GpuMat colRange(Range r) const; + + //! returns deep copy of the GpuMatrix, i.e. the data is copied + GpuMat clone() const; + //! copies the GpuMatrix content to "m". + // It calls m.create(this->size(), this->type()). + void copyTo(GpuMat& m) const; + //! copies those GpuMatrix elements to "m" that are marked with non-zero mask elements. + void copyTo(GpuMat& m, const GpuMat& mask) const; + //! converts GpuMatrix to another datatype with optional scalng. See cvConvertScale. + void convertTo(GpuMat& m, int rtype, double alpha = 1, double beta = 0) const; + + void assignTo(GpuMat& m, int type=-1) const; + + //! sets every GpuMatrix element to s + GpuMat& operator = (Scalar s); + //! sets some of the GpuMatrix elements to s, according to the mask + GpuMat& setTo(Scalar s, const GpuMat& mask = GpuMat()); + //! creates alternative GpuMatrix header for the same data, with different + // number of channels and/or different number of rows. see cvReshape. + GpuMat reshape(int cn, int rows = 0) const; + + //! allocates new GpuMatrix data unless the GpuMatrix already has specified size and type. + // previous data is unreferenced if needed. + void create(int rows, int cols, int type); + void create(Size size, int type); + //! decreases reference counter; + // deallocate the data when reference counter reaches 0. + void release(); + + //! swaps with other smart pointer + void swap(GpuMat& mat); + + //! locates GpuMatrix header within a parent GpuMatrix. See below + void locateROI(Size& wholeSize, Point& ofs) const; + //! moves/resizes the current GpuMatrix ROI inside the parent GpuMatrix. + GpuMat& adjustROI(int dtop, int dbottom, int dleft, int dright); + //! extracts a rectangular sub-GpuMatrix + // (this is a generalized form of row, rowRange etc.) + GpuMat operator()(Range rowRange, Range colRange) const; + GpuMat operator()(Rect roi) const; + + //! returns true iff the GpuMatrix data is continuous + // (i.e. when there are no gaps between successive rows). + // similar to CV_IS_GpuMat_CONT(cvGpuMat->type) + bool isContinuous() const; + //! returns element size in bytes, + // similar to CV_ELEM_SIZE(cvMat->type) + size_t elemSize() const; + //! returns the size of element channel in bytes. + size_t elemSize1() const; + //! returns element type, similar to CV_MAT_TYPE(cvMat->type) + int type() const; + //! returns element type, similar to CV_MAT_DEPTH(cvMat->type) + int depth() const; + //! returns element type, similar to CV_MAT_CN(cvMat->type) + int channels() const; + //! returns step/elemSize1() + size_t step1() const; + //! returns GpuMatrix size: + // width == number of columns, height == number of rows + Size size() const; + //! returns true if GpuMatrix data is NULL + bool empty() const; + + //! returns pointer to y-th row + uchar* ptr(int y = 0); + const uchar* ptr(int y = 0) const; + + //! template version of the above method + template _Tp* ptr(int y = 0); + template const _Tp* ptr(int y = 0) const; + + template operator PtrStepSz<_Tp>() const; + template operator PtrStep<_Tp>() const; + + // Deprecated function + __CV_GPU_DEPR_BEFORE__ template operator DevMem2D_<_Tp>() const __CV_GPU_DEPR_AFTER__; + __CV_GPU_DEPR_BEFORE__ template operator PtrStep_<_Tp>() const __CV_GPU_DEPR_AFTER__; + #undef __CV_GPU_DEPR_BEFORE__ + #undef __CV_GPU_DEPR_AFTER__ + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + + //! the number of rows and columns + int rows, cols; + + //! a distance between successive rows in bytes; includes the gap if any + size_t step; + + //! pointer to the data + uchar* data; + + //! pointer to the reference counter; + // when GpuMatrix points to user-allocated data, the pointer is NULL + int* refcount; + + //! helper fields used in locateROI and adjustROI + uchar* datastart; + uchar* dataend; + }; + + //! Creates continuous GPU matrix + CV_EXPORTS void createContinuous(int rows, int cols, int type, GpuMat& m); + CV_EXPORTS GpuMat createContinuous(int rows, int cols, int type); + CV_EXPORTS void createContinuous(Size size, int type, GpuMat& m); + CV_EXPORTS GpuMat createContinuous(Size size, int type); + + //! Ensures that size of the given matrix is not less than (rows, cols) size + //! and matrix type is match specified one too + CV_EXPORTS void ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m); + CV_EXPORTS void ensureSizeIsEnough(Size size, int type, GpuMat& m); + + CV_EXPORTS GpuMat allocMatFromBuf(int rows, int cols, int type, GpuMat &mat); + + //////////////////////////////////////////////////////////////////////// + // Error handling + + CV_EXPORTS void error(const char* error_string, const char* file, const int line, const char* func = ""); + + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + + inline GpuMat::GpuMat() + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) + { + } + + inline GpuMat::GpuMat(int rows_, int cols_, int type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) + { + if (rows_ > 0 && cols_ > 0) + create(rows_, cols_, type_); + } + + inline GpuMat::GpuMat(Size size_, int type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) + { + if (size_.height > 0 && size_.width > 0) + create(size_.height, size_.width, type_); + } + + inline GpuMat::GpuMat(int rows_, int cols_, int type_, Scalar s_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) + { + if (rows_ > 0 && cols_ > 0) + { + create(rows_, cols_, type_); + setTo(s_); + } + } + + inline GpuMat::GpuMat(Size size_, int type_, Scalar s_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) + { + if (size_.height > 0 && size_.width > 0) + { + create(size_.height, size_.width, type_); + setTo(s_); + } + } + + inline GpuMat::~GpuMat() + { + release(); + } + + inline GpuMat GpuMat::clone() const + { + GpuMat m; + copyTo(m); + return m; + } + + inline void GpuMat::assignTo(GpuMat& m, int _type) const + { + if (_type < 0) + m = *this; + else + convertTo(m, _type); + } + + inline size_t GpuMat::step1() const + { + return step / elemSize1(); + } + + inline bool GpuMat::empty() const + { + return data == 0; + } + + template inline _Tp* GpuMat::ptr(int y) + { + return (_Tp*)ptr(y); + } + + template inline const _Tp* GpuMat::ptr(int y) const + { + return (const _Tp*)ptr(y); + } + + inline void swap(GpuMat& a, GpuMat& b) + { + a.swap(b); + } + + inline GpuMat GpuMat::row(int y) const + { + return GpuMat(*this, Range(y, y+1), Range::all()); + } + + inline GpuMat GpuMat::col(int x) const + { + return GpuMat(*this, Range::all(), Range(x, x+1)); + } + + inline GpuMat GpuMat::rowRange(int startrow, int endrow) const + { + return GpuMat(*this, Range(startrow, endrow), Range::all()); + } + + inline GpuMat GpuMat::rowRange(Range r) const + { + return GpuMat(*this, r, Range::all()); + } + + inline GpuMat GpuMat::colRange(int startcol, int endcol) const + { + return GpuMat(*this, Range::all(), Range(startcol, endcol)); + } + + inline GpuMat GpuMat::colRange(Range r) const + { + return GpuMat(*this, Range::all(), r); + } + + inline void GpuMat::create(Size size_, int type_) + { + create(size_.height, size_.width, type_); + } + + inline GpuMat GpuMat::operator()(Range _rowRange, Range _colRange) const + { + return GpuMat(*this, _rowRange, _colRange); + } + + inline GpuMat GpuMat::operator()(Rect roi) const + { + return GpuMat(*this, roi); + } + + inline bool GpuMat::isContinuous() const + { + return (flags & Mat::CONTINUOUS_FLAG) != 0; + } + + inline size_t GpuMat::elemSize() const + { + return CV_ELEM_SIZE(flags); + } + + inline size_t GpuMat::elemSize1() const + { + return CV_ELEM_SIZE1(flags); + } + + inline int GpuMat::type() const + { + return CV_MAT_TYPE(flags); + } + + inline int GpuMat::depth() const + { + return CV_MAT_DEPTH(flags); + } + + inline int GpuMat::channels() const + { + return CV_MAT_CN(flags); + } + + inline Size GpuMat::size() const + { + return Size(cols, rows); + } + + inline uchar* GpuMat::ptr(int y) + { + CV_DbgAssert((unsigned)y < (unsigned)rows); + return data + step * y; + } + + inline const uchar* GpuMat::ptr(int y) const + { + CV_DbgAssert((unsigned)y < (unsigned)rows); + return data + step * y; + } + + inline GpuMat& GpuMat::operator = (Scalar s) + { + setTo(s); + return *this; + } + + template inline GpuMat::operator PtrStepSz() const + { + return PtrStepSz(rows, cols, (T*)data, step); + } + + template inline GpuMat::operator PtrStep() const + { + return PtrStep((T*)data, step); + } + + template inline GpuMat::operator DevMem2D_() const + { + return DevMem2D_(rows, cols, (T*)data, step); + } + + template inline GpuMat::operator PtrStep_() const + { + return PtrStep_(static_cast< DevMem2D_ >(*this)); + } + + inline GpuMat createContinuous(int rows, int cols, int type) + { + GpuMat m; + createContinuous(rows, cols, type, m); + return m; + } + + inline void createContinuous(Size size, int type, GpuMat& m) + { + createContinuous(size.height, size.width, type, m); + } + + inline GpuMat createContinuous(Size size, int type) + { + GpuMat m; + createContinuous(size, type, m); + return m; + } + + inline void ensureSizeIsEnough(Size size, int type, GpuMat& m) + { + ensureSizeIsEnough(size.height, size.width, type, m); + } +}} + +#endif // __cplusplus + +#endif // __OPENCV_GPUMAT_HPP__ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/internal.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/internal.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/internal.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/internal.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,796 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* The header is for internal use and it is likely to change. + It contains some macro definitions that are used in cxcore, cv, cvaux + and, probably, other libraries. If you need some of this functionality, + the safe way is to copy it into your code and rename the macros. +*/ +#ifndef __OPENCV_CORE_INTERNAL_HPP__ +#define __OPENCV_CORE_INTERNAL_HPP__ + +#include + +#if defined WIN32 || defined _WIN32 +# ifndef WIN32 +# define WIN32 +# endif +# ifndef _WIN32 +# define _WIN32 +# endif +#endif + +#if !defined WIN32 && !defined WINCE +# include +#endif + +#ifdef __BORLANDC__ +# ifndef WIN32 +# define WIN32 +# endif +# ifndef _WIN32 +# define _WIN32 +# endif +# define CV_DLL +# undef _CV_ALWAYS_PROFILE_ +# define _CV_ALWAYS_NO_PROFILE_ +#endif + +#ifndef FALSE +# define FALSE 0 +#endif +#ifndef TRUE +# define TRUE 1 +#endif + +#define __BEGIN__ __CV_BEGIN__ +#define __END__ __CV_END__ +#define EXIT __CV_EXIT__ + +#ifdef HAVE_IPP +# include "ipp.h" + +CV_INLINE IppiSize ippiSize(int width, int height) +{ + IppiSize size = { width, height }; + return size; +} +#endif + +#ifndef IPPI_CALL +# define IPPI_CALL(func) CV_Assert((func) >= 0) +#endif + +#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) +# include "emmintrin.h" +# define CV_SSE 1 +# define CV_SSE2 1 +# if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include "pmmintrin.h" +# define CV_SSE3 1 +# endif +# if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include "tmmintrin.h" +# define CV_SSSE3 1 +# endif +# if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSE4_1 1 +# endif +# if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSE4_2 1 +# endif +# if defined __AVX__ || (defined _MSC_FULL_VER && _MSC_FULL_VER >= 160040219) +// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX +// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32 +# include +# define CV_AVX 1 +# if defined(_XCR_XFEATURE_ENABLED_MASK) +# define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK) +# else +# define __xgetbv() 0 +# endif +# endif +#endif + +#ifdef __ARM_NEON__ +# include +# define CV_NEON 1 +# define CPU_HAS_NEON_FEATURE (true) +#endif + +#ifndef CV_SSE +# define CV_SSE 0 +#endif +#ifndef CV_SSE2 +# define CV_SSE2 0 +#endif +#ifndef CV_SSE3 +# define CV_SSE3 0 +#endif +#ifndef CV_SSSE3 +# define CV_SSSE3 0 +#endif +#ifndef CV_SSE4_1 +# define CV_SSE4_1 0 +#endif +#ifndef CV_SSE4_2 +# define CV_SSE4_2 0 +#endif +#ifndef CV_AVX +# define CV_AVX 0 +#endif +#ifndef CV_NEON +# define CV_NEON 0 +#endif + +#ifdef HAVE_TBB +# include "tbb/tbb_stddef.h" +# if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202 +# include "tbb/tbb.h" +# include "tbb/task.h" +# undef min +# undef max +# else +# undef HAVE_TBB +# endif +#endif + +#ifdef HAVE_EIGEN +# if defined __GNUC__ && defined __APPLE__ +# pragma GCC diagnostic ignored "-Wshadow" +# endif +# include +# include "opencv2/core/eigen.hpp" +#endif + +#ifdef __cplusplus + +namespace cv +{ +#ifdef HAVE_TBB + + typedef tbb::blocked_range BlockedRange; + + template static inline + void parallel_for( const BlockedRange& range, const Body& body ) + { + tbb::parallel_for(range, body); + } + + template static inline + void parallel_do( Iterator first, Iterator last, const Body& body ) + { + tbb::parallel_do(first, last, body); + } + + typedef tbb::split Split; + + template static inline + void parallel_reduce( const BlockedRange& range, Body& body ) + { + tbb::parallel_reduce(range, body); + } + + typedef tbb::concurrent_vector ConcurrentRectVector; + typedef tbb::concurrent_vector ConcurrentDoubleVector; +#else + class BlockedRange + { + public: + BlockedRange() : _begin(0), _end(0), _grainsize(0) {} + BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {} + int begin() const { return _begin; } + int end() const { return _end; } + int grainsize() const { return _grainsize; } + + protected: + int _begin, _end, _grainsize; + }; + + template static inline + void parallel_for( const BlockedRange& range, const Body& body ) + { + body(range); + } + typedef std::vector ConcurrentRectVector; + typedef std::vector ConcurrentDoubleVector; + + template static inline + void parallel_do( Iterator first, Iterator last, const Body& body ) + { + for( ; first != last; ++first ) + body(*first); + } + + class Split {}; + + template static inline + void parallel_reduce( const BlockedRange& range, Body& body ) + { + body(range); + } +#endif +} //namespace cv + +#define CV_INIT_ALGORITHM(classname, algname, memberinit) \ + static ::cv::Algorithm* create##classname() \ + { \ + return new classname; \ + } \ + \ + static ::cv::AlgorithmInfo& classname##_info() \ + { \ + static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname); \ + return classname##_info_var; \ + } \ + \ + static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \ + \ + ::cv::AlgorithmInfo* classname::info() const \ + { \ + static volatile bool initialized = false; \ + \ + if( !initialized ) \ + { \ + initialized = true; \ + classname obj; \ + memberinit; \ + } \ + return &classname##_info(); \ + } + +#endif //__cplusplus + +/* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */ +#define CV_MAX_INLINE_MAT_OP_SIZE 10 + +/* maximal linear size of matrix to allocate it on stack. */ +#define CV_MAX_LOCAL_MAT_SIZE 32 + +/* maximal size of local memory storage */ +#define CV_MAX_LOCAL_SIZE \ + (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double)) + +/* default image row align (in bytes) */ +#define CV_DEFAULT_IMAGE_ROW_ALIGN 4 + +/* matrices are continuous by default */ +#define CV_DEFAULT_MAT_ROW_ALIGN 1 + +/* maximum size of dynamic memory buffer. + cvAlloc reports an error if a larger block is requested. */ +#define CV_MAX_ALLOC_SIZE (((size_t)1 << (sizeof(size_t)*8-2))) + +/* the alignment of all the allocated buffers */ +#define CV_MALLOC_ALIGN 16 + +/* default alignment for dynamic data strucutures, resided in storages. */ +#define CV_STRUCT_ALIGN ((int)sizeof(double)) + +/* default storage block size */ +#define CV_STORAGE_BLOCK_SIZE ((1<<16) - 128) + +/* default memory block for sparse array elements */ +#define CV_SPARSE_MAT_BLOCK (1<<12) + +/* initial hash table size */ +#define CV_SPARSE_HASH_SIZE0 (1<<10) + +/* maximal average node_count/hash_size ratio beyond which hash table is resized */ +#define CV_SPARSE_HASH_RATIO 3 + +/* max length of strings */ +#define CV_MAX_STRLEN 1024 + +#if 0 /*def CV_CHECK_FOR_NANS*/ +# define CV_CHECK_NANS( arr ) cvCheckArray((arr)) +#else +# define CV_CHECK_NANS( arr ) +#endif + +/****************************************************************************************\ +* Common declarations * +\****************************************************************************************/ + +/* get alloca declaration */ +#ifdef __GNUC__ +# undef alloca +# define alloca __builtin_alloca +# define CV_HAVE_ALLOCA 1 +#elif defined WIN32 || defined _WIN32 || \ + defined WINCE || defined _MSC_VER || defined __BORLANDC__ +# include +# define CV_HAVE_ALLOCA 1 +#elif defined HAVE_ALLOCA_H +# include +# define CV_HAVE_ALLOCA 1 +#elif defined HAVE_ALLOCA +# include +# define CV_HAVE_ALLOCA 1 +#else +# undef CV_HAVE_ALLOCA +#endif + +#ifdef __GNUC__ +# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined _MSC_VER +# define CV_DECL_ALIGNED(x) __declspec(align(x)) +#else +# define CV_DECL_ALIGNED(x) +#endif + +#if CV_HAVE_ALLOCA +/* ! DO NOT make it an inline function */ +# define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN ) +#endif + +#ifndef CV_IMPL +# define CV_IMPL CV_EXTERN_C +#endif + +#define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; } + +/* default step, set in case of continuous data + to work around checks for valid step in some ipp functions */ +#define CV_STUB_STEP (1 << 30) + +#define CV_SIZEOF_FLOAT ((int)sizeof(float)) +#define CV_SIZEOF_SHORT ((int)sizeof(short)) + +#define CV_ORIGIN_TL 0 +#define CV_ORIGIN_BL 1 + +/* IEEE754 constants and macros */ +#define CV_POS_INF 0x7f800000 +#define CV_NEG_INF 0x807fffff /* CV_TOGGLE_FLT(0xff800000) */ +#define CV_1F 0x3f800000 +#define CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0)) +#define CV_TOGGLE_DBL(x) \ + ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0)) + +#define CV_NOP(a) (a) +#define CV_ADD(a, b) ((a) + (b)) +#define CV_SUB(a, b) ((a) - (b)) +#define CV_MUL(a, b) ((a) * (b)) +#define CV_AND(a, b) ((a) & (b)) +#define CV_OR(a, b) ((a) | (b)) +#define CV_XOR(a, b) ((a) ^ (b)) +#define CV_ANDN(a, b) (~(a) & (b)) +#define CV_ORN(a, b) (~(a) | (b)) +#define CV_SQR(a) ((a) * (a)) + +#define CV_LT(a, b) ((a) < (b)) +#define CV_LE(a, b) ((a) <= (b)) +#define CV_EQ(a, b) ((a) == (b)) +#define CV_NE(a, b) ((a) != (b)) +#define CV_GT(a, b) ((a) > (b)) +#define CV_GE(a, b) ((a) >= (b)) + +#define CV_NONZERO(a) ((a) != 0) +#define CV_NONZERO_FLT(a) (((a)+(a)) != 0) + +/* general-purpose saturation macros */ +#define CV_CAST_8U(t) (uchar)(!((t) & ~255) ? (t) : (t) > 0 ? 255 : 0) +#define CV_CAST_8S(t) (schar)(!(((t)+128) & ~255) ? (t) : (t) > 0 ? 127 : -128) +#define CV_CAST_16U(t) (ushort)(!((t) & ~65535) ? (t) : (t) > 0 ? 65535 : 0) +#define CV_CAST_16S(t) (short)(!(((t)+32768) & ~65535) ? (t) : (t) > 0 ? 32767 : -32768) +#define CV_CAST_32S(t) (int)(t) +#define CV_CAST_64S(t) (int64)(t) +#define CV_CAST_32F(t) (float)(t) +#define CV_CAST_64F(t) (double)(t) + +#define CV_PASTE2(a,b) a##b +#define CV_PASTE(a,b) CV_PASTE2(a,b) + +#define CV_EMPTY +#define CV_MAKE_STR(a) #a + +#define CV_ZERO_OBJ(x) memset((x), 0, sizeof(*(x))) + +#define CV_DIM(static_array) ((int)(sizeof(static_array)/sizeof((static_array)[0]))) + +#define cvUnsupportedFormat "Unsupported format" + +CV_INLINE void* cvAlignPtr( const void* ptr, int align CV_DEFAULT(32) ) +{ + assert( (align & (align-1)) == 0 ); + return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) ); +} + +CV_INLINE int cvAlign( int size, int align ) +{ + assert( (align & (align-1)) == 0 && size < INT_MAX ); + return (size + align - 1) & -align; +} + +CV_INLINE CvSize cvGetMatSize( const CvMat* mat ) +{ + CvSize size; + size.width = mat->cols; + size.height = mat->rows; + return size; +} + +#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) +#define CV_FLT_TO_FIX(x,n) cvRound((x)*(1<<(n))) + +/****************************************************************************************\ + + Generic implementation of QuickSort algorithm. + ---------------------------------------------- + Using this macro user can declare customized sort function that can be much faster + than built-in qsort function because of lower overhead on elements + comparison and exchange. The macro takes less_than (or LT) argument - a macro or function + that takes 2 arguments returns non-zero if the first argument should be before the second + one in the sorted sequence and zero otherwise. + + Example: + + Suppose that the task is to sort points by ascending of y coordinates and if + y's are equal x's should ascend. + + The code is: + ------------------------------------------------------------------------------ + #define cmp_pts( pt1, pt2 ) \ + ((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x)) + + [static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts ) + ------------------------------------------------------------------------------ + + After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );" + is available to user. + + aux is an additional parameter, which can be used when comparing elements. + The current implementation was derived from *BSD system qsort(): + + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + +\****************************************************************************************/ + +#define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type ) \ +void func_name( T *array, size_t total, user_data_type aux ) \ +{ \ + int isort_thresh = 7; \ + T t; \ + int sp = 0; \ + \ + struct \ + { \ + T *lb; \ + T *ub; \ + } \ + stack[48]; \ + \ + aux = aux; \ + \ + if( total <= 1 ) \ + return; \ + \ + stack[0].lb = array; \ + stack[0].ub = array + (total - 1); \ + \ + while( sp >= 0 ) \ + { \ + T* left = stack[sp].lb; \ + T* right = stack[sp--].ub; \ + \ + for(;;) \ + { \ + int i, n = (int)(right - left) + 1, m; \ + T* ptr; \ + T* ptr2; \ + \ + if( n <= isort_thresh ) \ + { \ + insert_sort: \ + for( ptr = left + 1; ptr <= right; ptr++ ) \ + { \ + for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) \ + CV_SWAP( ptr2[0], ptr2[-1], t ); \ + } \ + break; \ + } \ + else \ + { \ + T* left0; \ + T* left1; \ + T* right0; \ + T* right1; \ + T* pivot; \ + T* a; \ + T* b; \ + T* c; \ + int swap_cnt = 0; \ + \ + left0 = left; \ + right0 = right; \ + pivot = left + (n/2); \ + \ + if( n > 40 ) \ + { \ + int d = n / 8; \ + a = left, b = left + d, c = left + 2*d; \ + left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ + \ + a = pivot - d, b = pivot, c = pivot + d; \ + pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ + \ + a = right - 2*d, b = right - d, c = right; \ + right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ + } \ + \ + a = left, b = pivot, c = right; \ + pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ + if( pivot != left0 ) \ + { \ + CV_SWAP( *pivot, *left0, t ); \ + pivot = left0; \ + } \ + left = left1 = left0 + 1; \ + right = right1 = right0; \ + \ + for(;;) \ + { \ + while( left <= right && !LT(*pivot, *left) ) \ + { \ + if( !LT(*left, *pivot) ) \ + { \ + if( left > left1 ) \ + CV_SWAP( *left1, *left, t ); \ + swap_cnt = 1; \ + left1++; \ + } \ + left++; \ + } \ + \ + while( left <= right && !LT(*right, *pivot) ) \ + { \ + if( !LT(*pivot, *right) ) \ + { \ + if( right < right1 ) \ + CV_SWAP( *right1, *right, t ); \ + swap_cnt = 1; \ + right1--; \ + } \ + right--; \ + } \ + \ + if( left > right ) \ + break; \ + CV_SWAP( *left, *right, t ); \ + swap_cnt = 1; \ + left++; \ + right--; \ + } \ + \ + if( swap_cnt == 0 ) \ + { \ + left = left0, right = right0; \ + goto insert_sort; \ + } \ + \ + n = MIN( (int)(left1 - left0), (int)(left - left1) ); \ + for( i = 0; i < n; i++ ) \ + CV_SWAP( left0[i], left[i-n], t ); \ + \ + n = MIN( (int)(right0 - right1), (int)(right1 - right) ); \ + for( i = 0; i < n; i++ ) \ + CV_SWAP( left[i], right0[i-n+1], t ); \ + n = (int)(left - left1); \ + m = (int)(right1 - right); \ + if( n > 1 ) \ + { \ + if( m > 1 ) \ + { \ + if( n > m ) \ + { \ + stack[++sp].lb = left0; \ + stack[sp].ub = left0 + n - 1; \ + left = right0 - m + 1, right = right0; \ + } \ + else \ + { \ + stack[++sp].lb = right0 - m + 1; \ + stack[sp].ub = right0; \ + left = left0, right = left0 + n - 1; \ + } \ + } \ + else \ + left = left0, right = left0 + n - 1; \ + } \ + else if( m > 1 ) \ + left = right0 - m + 1, right = right0; \ + else \ + break; \ + } \ + } \ + } \ +} + +#define CV_IMPLEMENT_QSORT( func_name, T, cmp ) \ + CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int ) + +/****************************************************************************************\ +* Structures and macros for integration with IPP * +\****************************************************************************************/ + +/* IPP-compatible return codes */ +typedef enum CvStatus +{ + CV_BADMEMBLOCK_ERR = -113, + CV_INPLACE_NOT_SUPPORTED_ERR= -112, + CV_UNMATCHED_ROI_ERR = -111, + CV_NOTFOUND_ERR = -110, + CV_BADCONVERGENCE_ERR = -109, + + CV_BADDEPTH_ERR = -107, + CV_BADROI_ERR = -106, + CV_BADHEADER_ERR = -105, + CV_UNMATCHED_FORMATS_ERR = -104, + CV_UNSUPPORTED_COI_ERR = -103, + CV_UNSUPPORTED_CHANNELS_ERR = -102, + CV_UNSUPPORTED_DEPTH_ERR = -101, + CV_UNSUPPORTED_FORMAT_ERR = -100, + + CV_BADARG_ERR = -49, //ipp comp + CV_NOTDEFINED_ERR = -48, //ipp comp + + CV_BADCHANNELS_ERR = -47, //ipp comp + CV_BADRANGE_ERR = -44, //ipp comp + CV_BADSTEP_ERR = -29, //ipp comp + + CV_BADFLAG_ERR = -12, + CV_DIV_BY_ZERO_ERR = -11, //ipp comp + CV_BADCOEF_ERR = -10, + + CV_BADFACTOR_ERR = -7, + CV_BADPOINT_ERR = -6, + CV_BADSCALE_ERR = -4, + CV_OUTOFMEM_ERR = -3, + CV_NULLPTR_ERR = -2, + CV_BADSIZE_ERR = -1, + CV_NO_ERR = 0, + CV_OK = CV_NO_ERR +} +CvStatus; + +#define CV_NOTHROW throw() + +typedef struct CvFuncTable +{ + void* fn_2d[CV_DEPTH_MAX]; +} +CvFuncTable; + +typedef struct CvBigFuncTable +{ + void* fn_2d[CV_DEPTH_MAX*4]; +} CvBigFuncTable; + +#define CV_INIT_FUNC_TAB( tab, FUNCNAME, FLAG ) \ + (tab).fn_2d[CV_8U] = (void*)FUNCNAME##_8u##FLAG; \ + (tab).fn_2d[CV_8S] = 0; \ + (tab).fn_2d[CV_16U] = (void*)FUNCNAME##_16u##FLAG; \ + (tab).fn_2d[CV_16S] = (void*)FUNCNAME##_16s##FLAG; \ + (tab).fn_2d[CV_32S] = (void*)FUNCNAME##_32s##FLAG; \ + (tab).fn_2d[CV_32F] = (void*)FUNCNAME##_32f##FLAG; \ + (tab).fn_2d[CV_64F] = (void*)FUNCNAME##_64f##FLAG + +#ifdef __cplusplus + +// < Deprecated + +class CV_EXPORTS CvOpenGlFuncTab +{ +public: + virtual ~CvOpenGlFuncTab(); + + virtual void genBuffers(int n, unsigned int* buffers) const = 0; + virtual void deleteBuffers(int n, const unsigned int* buffers) const = 0; + + virtual void bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const = 0; + virtual void bufferSubData(unsigned int target, ptrdiff_t offset, ptrdiff_t size, const void* data) const = 0; + + virtual void bindBuffer(unsigned int target, unsigned int buffer) const = 0; + + virtual void* mapBuffer(unsigned int target, unsigned int access) const = 0; + virtual void unmapBuffer(unsigned int target) const = 0; + + virtual void generateBitmapFont(const std::string& family, int height, int weight, bool italic, bool underline, int start, int count, int base) const = 0; + + virtual bool isGlContextInitialized() const = 0; +}; + +CV_EXPORTS void icvSetOpenGlFuncTab(const CvOpenGlFuncTab* tab); + +CV_EXPORTS bool icvCheckGlError(const char* file, const int line, const char* func = ""); + +// > + +namespace cv { namespace ogl { +CV_EXPORTS bool checkError(const char* file, const int line, const char* func = ""); +}} + +#if defined(__GNUC__) + #define CV_CheckGlError() CV_DbgAssert( (cv::ogl::checkError(__FILE__, __LINE__, __func__)) ) +#else + #define CV_CheckGlError() CV_DbgAssert( (cv::ogl::checkError(__FILE__, __LINE__)) ) +#endif + +#endif //__cplusplus + +#endif // __OPENCV_CORE_INTERNAL_HPP__ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/mat.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/mat.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/mat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/mat.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2617 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__ +#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__ + +#ifndef SKIP_INCLUDES +#include +#include +#endif // SKIP_INCLUDES + +#ifdef __cplusplus + +namespace cv +{ + +//////////////////////////////// Mat //////////////////////////////// + +inline void Mat::initEmpty() +{ + flags = MAGIC_VAL; + dims = rows = cols = 0; + data = datastart = dataend = datalimit = 0; + refcount = 0; + allocator = 0; +} + +inline Mat::Mat() : size(&rows) +{ + initEmpty(); +} + +inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows) +{ + initEmpty(); + create(_rows, _cols, _type); +} + +inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows) +{ + initEmpty(); + create(_rows, _cols, _type); + *this = _s; +} + +inline Mat::Mat(Size _sz, int _type) : size(&rows) +{ + initEmpty(); + create( _sz.height, _sz.width, _type ); +} + +inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows) +{ + initEmpty(); + create(_sz.height, _sz.width, _type); + *this = _s; +} + +inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows) +{ + initEmpty(); + create(_dims, _sz, _type); +} + +inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows) +{ + initEmpty(); + create(_dims, _sz, _type); + *this = _s; +} + +inline Mat::Mat(const Mat& m) + : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data), + refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), + datalimit(m.datalimit), allocator(m.allocator), size(&rows) +{ + if( refcount ) + CV_XADD(refcount, 1); + if( m.dims <= 2 ) + { + step[0] = m.step[0]; step[1] = m.step[1]; + } + else + { + dims = 0; + copySize(m); + } +} + +inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step) + : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols), + data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), + datalimit(0), allocator(0), size(&rows) +{ + size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz; + if( _step == AUTO_STEP ) + { + _step = minstep; + flags |= CONTINUOUS_FLAG; + } + else + { + if( rows == 1 ) _step = minstep; + CV_DbgAssert( _step >= minstep ); + flags |= _step == minstep ? CONTINUOUS_FLAG : 0; + } + step[0] = _step; step[1] = esz; + datalimit = datastart + _step*rows; + dataend = datalimit - _step + minstep; +} + +inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step) + : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width), + data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), + datalimit(0), allocator(0), size(&rows) +{ + size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz; + if( _step == AUTO_STEP ) + { + _step = minstep; + flags |= CONTINUOUS_FLAG; + } + else + { + if( rows == 1 ) _step = minstep; + CV_DbgAssert( _step >= minstep ); + flags |= _step == minstep ? CONTINUOUS_FLAG : 0; + } + step[0] = _step; step[1] = esz; + datalimit = datastart + _step*rows; + dataend = datalimit - _step + minstep; +} + + +template inline Mat::Mat(const vector<_Tp>& vec, bool copyData) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + if(vec.empty()) + return; + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + data = datastart = (uchar*)&vec[0]; + datalimit = dataend = datastart + rows*step[0]; + } + else + Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this); +} + + +template inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(2), rows(n), cols(1), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + data = datastart = (uchar*)vec.val; + datalimit = dataend = datastart + rows*step[0]; + } + else + Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this); +} + + +template inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(2), rows(m), cols(n), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + if( !copyData ) + { + step[0] = cols*sizeof(_Tp); + step[1] = sizeof(_Tp); + data = datastart = (uchar*)M.val; + datalimit = dataend = datastart + rows*step[0]; + } + else + Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this); +} + + +template inline Mat::Mat(const Point_<_Tp>& pt, bool copyData) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(2), rows(2), cols(1), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + data = datastart = (uchar*)&pt.x; + datalimit = dataend = datastart + rows*step[0]; + } + else + { + create(2, 1, DataType<_Tp>::type); + ((_Tp*)data)[0] = pt.x; + ((_Tp*)data)[1] = pt.y; + } +} + + +template inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(2), rows(3), cols(1), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + data = datastart = (uchar*)&pt.x; + datalimit = dataend = datastart + rows*step[0]; + } + else + { + create(3, 1, DataType<_Tp>::type); + ((_Tp*)data)[0] = pt.x; + ((_Tp*)data)[1] = pt.y; + ((_Tp*)data)[2] = pt.z; + } +} + + +template inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer) + : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), + dims(0), rows(0), cols(0), data(0), refcount(0), + datastart(0), dataend(0), allocator(0), size(&rows) +{ + *this = *commaInitializer; +} + +inline Mat::~Mat() +{ + release(); + if( step.p != step.buf ) + fastFree(step.p); +} + +inline Mat& Mat::operator = (const Mat& m) +{ + if( this != &m ) + { + if( m.refcount ) + CV_XADD(m.refcount, 1); + release(); + flags = m.flags; + if( dims <= 2 && m.dims <= 2 ) + { + dims = m.dims; + rows = m.rows; + cols = m.cols; + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + copySize(m); + data = m.data; + datastart = m.datastart; + dataend = m.dataend; + datalimit = m.datalimit; + refcount = m.refcount; + allocator = m.allocator; + } + return *this; +} + +inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); } +inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); } +inline Mat Mat::rowRange(int startrow, int endrow) const + { return Mat(*this, Range(startrow, endrow), Range::all()); } +inline Mat Mat::rowRange(const Range& r) const + { return Mat(*this, r, Range::all()); } +inline Mat Mat::colRange(int startcol, int endcol) const + { return Mat(*this, Range::all(), Range(startcol, endcol)); } +inline Mat Mat::colRange(const Range& r) const + { return Mat(*this, Range::all(), r); } + +inline Mat Mat::diag(const Mat& d) +{ + CV_Assert( d.cols == 1 || d.rows == 1 ); + int len = d.rows + d.cols - 1; + Mat m(len, len, d.type(), Scalar(0)), md = m.diag(); + if( d.cols == 1 ) + d.copyTo(md); + else + transpose(d, md); + return m; +} + +inline Mat Mat::clone() const +{ + Mat m; + copyTo(m); + return m; +} + +inline void Mat::assignTo( Mat& m, int _type ) const +{ + if( _type < 0 ) + m = *this; + else + convertTo(m, _type); +} + +inline void Mat::create(int _rows, int _cols, int _type) +{ + _type &= TYPE_MASK; + if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data ) + return; + int sz[] = {_rows, _cols}; + create(2, sz, _type); +} + +inline void Mat::create(Size _sz, int _type) +{ + create(_sz.height, _sz.width, _type); +} + +inline void Mat::addref() +{ if( refcount ) CV_XADD(refcount, 1); } + +inline void Mat::release() +{ + if( refcount && CV_XADD(refcount, -1) == 1 ) + deallocate(); + data = datastart = dataend = datalimit = 0; + size.p[0] = 0; + refcount = 0; +} + +inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const +{ + return Mat(*this, _rowRange, _colRange); +} + +inline Mat Mat::operator()( const Rect& roi ) const +{ return Mat(*this, roi); } + +inline Mat Mat::operator()(const Range* ranges) const +{ + return Mat(*this, ranges); +} + +inline Mat::operator CvMat() const +{ + CV_DbgAssert(dims <= 2); + CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data); + m.step = (int)step[0]; + m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG); + return m; +} + +inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; } +inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; } +inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; } +inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); } +inline int Mat::type() const { return CV_MAT_TYPE(flags); } +inline int Mat::depth() const { return CV_MAT_DEPTH(flags); } +inline int Mat::channels() const { return CV_MAT_CN(flags); } +inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); } +inline bool Mat::empty() const { return data == 0 || total() == 0; } +inline size_t Mat::total() const +{ + if( dims <= 2 ) + return (size_t)rows*cols; + size_t p = 1; + for( int i = 0; i < dims; i++ ) + p *= size[i]; + return p; +} + +inline uchar* Mat::ptr(int y) +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return data + step.p[0]*y; +} + +inline const uchar* Mat::ptr(int y) const +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return data + step.p[0]*y; +} + +template inline _Tp* Mat::ptr(int y) +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return (_Tp*)(data + step.p[0]*y); +} + +template inline const _Tp* Mat::ptr(int y) const +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return (const _Tp*)(data + step.p[0]*y); +} + + +inline uchar* Mat::ptr(int i0, int i1) +{ + CV_DbgAssert( dims >= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] ); + return data + i0*step.p[0] + i1*step.p[1]; +} + +inline const uchar* Mat::ptr(int i0, int i1) const +{ + CV_DbgAssert( dims >= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] ); + return data + i0*step.p[0] + i1*step.p[1]; +} + +template inline _Tp* Mat::ptr(int i0, int i1) +{ + CV_DbgAssert( dims >= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] ); + return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]); +} + +template inline const _Tp* Mat::ptr(int i0, int i1) const +{ + CV_DbgAssert( dims >= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] ); + return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]); +} + +inline uchar* Mat::ptr(int i0, int i1, int i2) +{ + CV_DbgAssert( dims >= 3 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + (unsigned)i2 < (unsigned)size.p[2] ); + return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]; +} + +inline const uchar* Mat::ptr(int i0, int i1, int i2) const +{ + CV_DbgAssert( dims >= 3 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + (unsigned)i2 < (unsigned)size.p[2] ); + return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]; +} + +template inline _Tp* Mat::ptr(int i0, int i1, int i2) +{ + CV_DbgAssert( dims >= 3 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + (unsigned)i2 < (unsigned)size.p[2] ); + return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]); +} + +template inline const _Tp* Mat::ptr(int i0, int i1, int i2) const +{ + CV_DbgAssert( dims >= 3 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + (unsigned)i2 < (unsigned)size.p[2] ); + return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]); +} + +inline uchar* Mat::ptr(const int* idx) +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i]*step.p[i]; + } + return p; +} + +inline const uchar* Mat::ptr(const int* idx) const +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i]*step.p[i]; + } + return p; +} + +template inline _Tp& Mat::at(int i0, int i1) +{ + CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && + CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + return ((_Tp*)(data + step.p[0]*i0))[i1]; +} + +template inline const _Tp& Mat::at(int i0, int i1) const +{ + CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && + CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + return ((const _Tp*)(data + step.p[0]*i0))[i1]; +} + +template inline _Tp& Mat::at(Point pt) +{ + CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] && + (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && + CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + return ((_Tp*)(data + step.p[0]*pt.y))[pt.x]; +} + +template inline const _Tp& Mat::at(Point pt) const +{ + CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] && + (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && + CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x]; +} + +template inline _Tp& Mat::at(int i0) +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) && + elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + if( isContinuous() || size.p[0] == 1 ) + return ((_Tp*)data)[i0]; + if( size.p[1] == 1 ) + return *(_Tp*)(data + step.p[0]*i0); + int i = i0/cols, j = i0 - i*cols; + return ((_Tp*)(data + step.p[0]*i))[j]; +} + +template inline const _Tp& Mat::at(int i0) const +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) && + elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + if( isContinuous() || size.p[0] == 1 ) + return ((const _Tp*)data)[i0]; + if( size.p[1] == 1 ) + return *(const _Tp*)(data + step.p[0]*i0); + int i = i0/cols, j = i0 - i*cols; + return ((const _Tp*)(data + step.p[0]*i))[j]; +} + +template inline _Tp& Mat::at(int i0, int i1, int i2) +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(i0, i1, i2); +} +template inline const _Tp& Mat::at(int i0, int i1, int i2) const +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(i0, i1, i2); +} +template inline _Tp& Mat::at(const int* idx) +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(idx); +} +template inline const _Tp& Mat::at(const int* idx) const +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(idx); +} +template _Tp& Mat::at(const Vec& idx) +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(idx.val); +} +template inline const _Tp& Mat::at(const Vec& idx) const +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(idx.val); +} + + +template inline MatConstIterator_<_Tp> Mat::begin() const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this); +} + +template inline MatConstIterator_<_Tp> Mat::end() const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this); + it += total(); + return it; +} + +template inline MatIterator_<_Tp> Mat::begin() +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return MatIterator_<_Tp>((Mat_<_Tp>*)this); +} + +template inline MatIterator_<_Tp> Mat::end() +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + MatIterator_<_Tp> it((Mat_<_Tp>*)this); + it += total(); + return it; +} + +template inline Mat::operator vector<_Tp>() const +{ + vector<_Tp> v; + copyTo(v); + return v; +} + +template inline Mat::operator Vec<_Tp, n>() const +{ + CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) && + rows + cols - 1 == n && channels() == 1 ); + + if( isContinuous() && type() == DataType<_Tp>::type ) + return Vec<_Tp, n>((_Tp*)data); + Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val); + convertTo(tmp, tmp.type()); + return v; +} + +template inline Mat::operator Matx<_Tp, m, n>() const +{ + CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 ); + + if( isContinuous() && type() == DataType<_Tp>::type ) + return Matx<_Tp, m, n>((_Tp*)data); + Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val); + convertTo(tmp, tmp.type()); + return mtx; +} + + +template inline void Mat::push_back(const _Tp& elem) +{ + if( !data ) + { + *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone(); + return; + } + CV_Assert(DataType<_Tp>::type == type() && cols == 1 + /* && dims == 2 (cols == 1 implies dims == 2) */); + uchar* tmp = dataend + step[0]; + if( !isSubmatrix() && isContinuous() && tmp <= datalimit ) + { + *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem; + dataend = tmp; + } + else + push_back_(&elem); +} + +template inline void Mat::push_back(const Mat_<_Tp>& m) +{ + push_back((const Mat&)m); +} + +inline Mat::MSize::MSize(int* _p) : p(_p) {} +inline Size Mat::MSize::operator()() const +{ + CV_DbgAssert(p[-1] <= 2); + return Size(p[1], p[0]); +} +inline const int& Mat::MSize::operator[](int i) const { return p[i]; } +inline int& Mat::MSize::operator[](int i) { return p[i]; } +inline Mat::MSize::operator const int*() const { return p; } + +inline bool Mat::MSize::operator == (const MSize& sz) const +{ + int d = p[-1], dsz = sz.p[-1]; + if( d != dsz ) + return false; + if( d == 2 ) + return p[0] == sz.p[0] && p[1] == sz.p[1]; + + for( int i = 0; i < d; i++ ) + if( p[i] != sz.p[i] ) + return false; + return true; +} + +inline bool Mat::MSize::operator != (const MSize& sz) const +{ + return !(*this == sz); +} + +inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; } +inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; } +inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; } +inline size_t& Mat::MStep::operator[](int i) { return p[i]; } +inline Mat::MStep::operator size_t() const +{ + CV_DbgAssert( p == buf ); + return buf[0]; +} +inline Mat::MStep& Mat::MStep::operator = (size_t s) +{ + CV_DbgAssert( p == buf ); + buf[0] = s; + return *this; +} + +static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0) +{ + return cvarrToMat(arr, copyData, true, coiMode); +} + +///////////////////////////////////////////// SVD ////////////////////////////////////////////////////// + +inline SVD::SVD() {} +inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); } +inline void SVD::solveZ( InputArray m, OutputArray _dst ) +{ + Mat mtx = m.getMat(); + SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV)); + _dst.create(svd.vt.cols, 1, svd.vt.type()); + Mat dst = _dst.getMat(); + svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst); +} + +template inline void + SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ) +{ + assert( nm == MIN(m, n)); + Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false); + SVD::compute(_a, _w, _u, _vt); + CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]); +} + +template inline void +SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w ) +{ + assert( nm == MIN(m, n)); + Mat _a(a, false), _w(w, false); + SVD::compute(_a, _w); + CV_Assert(_w.data == (uchar*)&w.val[0]); +} + +template inline void +SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, + const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, + Matx<_Tp, n, nb>& dst ) +{ + assert( nm == MIN(m, n)); + Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false); + SVD::backSubst(_w, _u, _vt, _rhs, _dst); + CV_Assert(_dst.data == (uchar*)&dst.val[0]); +} + +///////////////////////////////// Mat_<_Tp> //////////////////////////////////// + +template inline Mat_<_Tp>::Mat_() + : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; } + +template inline Mat_<_Tp>::Mat_(int _rows, int _cols) + : Mat(_rows, _cols, DataType<_Tp>::type) {} + +template inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) + : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; } + +template inline Mat_<_Tp>::Mat_(Size _sz) + : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {} + +template inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value) + : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; } + +template inline Mat_<_Tp>::Mat_(int _dims, const int* _sz) + : Mat(_dims, _sz, DataType<_Tp>::type) {} + +template inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s) + : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {} + +template inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges) + : Mat(m, ranges) {} + +template inline Mat_<_Tp>::Mat_(const Mat& m) + : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; } + +template inline Mat_<_Tp>::Mat_(const Mat_& m) + : Mat(m) {} + +template inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps) + : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {} + +template inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange) + : Mat(m, _rowRange, _colRange) {} + +template inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi) + : Mat(m, roi) {} + +template template inline + Mat_<_Tp>::Mat_(const Vec::channel_type, n>& vec, bool copyData) + : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec) +{ + CV_Assert(n%DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template template inline + Mat_<_Tp>::Mat_(const Matx::channel_type,m,n>& M, bool copyData) + : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M) +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline Mat_<_Tp>::Mat_(const Point_::channel_type>& pt, bool copyData) + : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt) +{ + CV_Assert(2 % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline Mat_<_Tp>::Mat_(const Point3_::channel_type>& pt, bool copyData) + : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt) +{ + CV_Assert(3 % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer) + : Mat(commaInitializer) {} + +template inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData) + : Mat(vec, copyData) {} + +template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m) +{ + if( DataType<_Tp>::type == m.type() ) + { + Mat::operator = (m); + return *this; + } + if( DataType<_Tp>::depth == m.depth() ) + { + return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0)); + } + CV_DbgAssert(DataType<_Tp>::channels == m.channels()); + m.convertTo(*this, type()); + return *this; +} + +template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m) +{ + Mat::operator=(m); + return *this; +} + +template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s) +{ + typedef typename DataType<_Tp>::vec_type VT; + Mat::operator=(Scalar((const VT&)s)); + return *this; +} + +template inline void Mat_<_Tp>::create(int _rows, int _cols) +{ + Mat::create(_rows, _cols, DataType<_Tp>::type); +} + +template inline void Mat_<_Tp>::create(Size _sz) +{ + Mat::create(_sz, DataType<_Tp>::type); +} + +template inline void Mat_<_Tp>::create(int _dims, const int* _sz) +{ + Mat::create(_dims, _sz, DataType<_Tp>::type); +} + + +template inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const +{ return Mat_<_Tp>(Mat::cross(m)); } + +template template inline Mat_<_Tp>::operator Mat_() const +{ return Mat_(*this); } + +template inline Mat_<_Tp> Mat_<_Tp>::row(int y) const +{ return Mat_(*this, Range(y, y+1), Range::all()); } +template inline Mat_<_Tp> Mat_<_Tp>::col(int x) const +{ return Mat_(*this, Range::all(), Range(x, x+1)); } +template inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const +{ return Mat_(Mat::diag(d)); } +template inline Mat_<_Tp> Mat_<_Tp>::clone() const +{ return Mat_(Mat::clone()); } + +template inline size_t Mat_<_Tp>::elemSize() const +{ + CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) ); + return sizeof(_Tp); +} + +template inline size_t Mat_<_Tp>::elemSize1() const +{ + CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels ); + return sizeof(_Tp)/DataType<_Tp>::channels; +} +template inline int Mat_<_Tp>::type() const +{ + CV_DbgAssert( Mat::type() == DataType<_Tp>::type ); + return DataType<_Tp>::type; +} +template inline int Mat_<_Tp>::depth() const +{ + CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth ); + return DataType<_Tp>::depth; +} +template inline int Mat_<_Tp>::channels() const +{ + CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels ); + return DataType<_Tp>::channels; +} +template inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); } +template inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); } + +template inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright ) +{ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); } + +template inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const +{ return Mat_<_Tp>(*this, _rowRange, _colRange); } + +template inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const +{ return Mat_<_Tp>(*this, roi); } + +template inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const +{ return Mat_<_Tp>(*this, ranges); } + +template inline _Tp* Mat_<_Tp>::operator [](int y) +{ return (_Tp*)ptr(y); } +template inline const _Tp* Mat_<_Tp>::operator [](int y) const +{ return (const _Tp*)ptr(y); } + +template inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1) +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + type() == DataType<_Tp>::type ); + return ((_Tp*)(data + step.p[0]*i0))[i1]; +} + +template inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)i0 < (unsigned)size.p[0] && + (unsigned)i1 < (unsigned)size.p[1] && + type() == DataType<_Tp>::type ); + return ((const _Tp*)(data + step.p[0]*i0))[i1]; +} + +template inline _Tp& Mat_<_Tp>::operator ()(Point pt) +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)pt.y < (unsigned)size.p[0] && + (unsigned)pt.x < (unsigned)size.p[1] && + type() == DataType<_Tp>::type ); + return ((_Tp*)(data + step.p[0]*pt.y))[pt.x]; +} + +template inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const +{ + CV_DbgAssert( dims <= 2 && data && + (unsigned)pt.y < (unsigned)size.p[0] && + (unsigned)pt.x < (unsigned)size.p[1] && + type() == DataType<_Tp>::type ); + return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x]; +} + +template inline _Tp& Mat_<_Tp>::operator ()(const int* idx) +{ + return Mat::at<_Tp>(idx); +} + +template inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const +{ + return Mat::at<_Tp>(idx); +} + +template template inline _Tp& Mat_<_Tp>::operator ()(const Vec& idx) +{ + return Mat::at<_Tp>(idx); +} + +template template inline const _Tp& Mat_<_Tp>::operator ()(const Vec& idx) const +{ + return Mat::at<_Tp>(idx); +} + +template inline _Tp& Mat_<_Tp>::operator ()(int i0) +{ + return this->at<_Tp>(i0); +} + +template inline const _Tp& Mat_<_Tp>::operator ()(int i0) const +{ + return this->at<_Tp>(i0); +} + +template inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) +{ + return this->at<_Tp>(i0, i1, i2); +} + +template inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const +{ + return this->at<_Tp>(i0, i1, i2); +} + + +template inline Mat_<_Tp>::operator vector<_Tp>() const +{ + vector<_Tp> v; + copyTo(v); + return v; +} + +template template inline Mat_<_Tp>::operator Vec::channel_type, n>() const +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + return this->Mat::operator Vec::channel_type, n>(); +} + +template template inline Mat_<_Tp>::operator Matx::channel_type, m, n>() const +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + return this->Mat::operator Matx::channel_type, m, n>(); +} + +template inline void +process( const Mat_& m1, Mat_& m2, Op op ) +{ + int y, x, rows = m1.rows, cols = m1.cols; + + CV_DbgAssert( m1.size() == m2.size() ); + + for( y = 0; y < rows; y++ ) + { + const T1* src = m1[y]; + T2* dst = m2[y]; + + for( x = 0; x < cols; x++ ) + dst[x] = op(src[x]); + } +} + +template inline void +process( const Mat_& m1, const Mat_& m2, Mat_& m3, Op op ) +{ + int y, x, rows = m1.rows, cols = m1.cols; + + CV_DbgAssert( m1.size() == m2.size() ); + + for( y = 0; y < rows; y++ ) + { + const T1* src1 = m1[y]; + const T2* src2 = m2[y]; + T3* dst = m3[y]; + + for( x = 0; x < cols; x++ ) + dst[x] = op( src1[x], src2[x] ); + } +} + + +/////////////////////////////// Input/Output Arrays ///////////////////////////////// + +template inline _InputArray::_InputArray(const vector<_Tp>& vec) + : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {} + +template inline _InputArray::_InputArray(const vector >& vec) + : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {} + +template inline _InputArray::_InputArray(const vector >& vec) + : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {} + +template inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx) + : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {} + +template inline _InputArray::_InputArray(const _Tp* vec, int n) + : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {} + +inline _InputArray::_InputArray(const Scalar& s) + : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {} + +template inline _InputArray::_InputArray(const Mat_<_Tp>& m) + : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {} + +template inline _OutputArray::_OutputArray(vector<_Tp>& vec) + : _InputArray(vec) {} +template inline _OutputArray::_OutputArray(vector >& vec) + : _InputArray(vec) {} +template inline _OutputArray::_OutputArray(vector >& vec) + : _InputArray(vec) {} +template inline _OutputArray::_OutputArray(Mat_<_Tp>& m) + : _InputArray(m) {} +template inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) + : _InputArray(mtx) {} +template inline _OutputArray::_OutputArray(_Tp* vec, int n) + : _InputArray(vec, n) {} + +template inline _OutputArray::_OutputArray(const vector<_Tp>& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} +template inline _OutputArray::_OutputArray(const vector >& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} +template inline _OutputArray::_OutputArray(const vector >& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} + +template inline _OutputArray::_OutputArray(const Mat_<_Tp>& m) + : _InputArray(m) {flags |= FIXED_SIZE;} +template inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) + : _InputArray(mtx) {} +template inline _OutputArray::_OutputArray(const _Tp* vec, int n) + : _InputArray(vec, n) {} + +//////////////////////////////////// Matrix Expressions ///////////////////////////////////////// + +class CV_EXPORTS MatOp +{ +public: + MatOp() {}; + virtual ~MatOp() {}; + + virtual bool elementWise(const MatExpr& expr) const; + virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0; + virtual void roi(const MatExpr& expr, const Range& rowRange, + const Range& colRange, MatExpr& res) const; + virtual void diag(const MatExpr& expr, int d, MatExpr& res) const; + virtual void augAssignAdd(const MatExpr& expr, Mat& m) const; + virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const; + virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const; + virtual void augAssignDivide(const MatExpr& expr, Mat& m) const; + virtual void augAssignAnd(const MatExpr& expr, Mat& m) const; + virtual void augAssignOr(const MatExpr& expr, Mat& m) const; + virtual void augAssignXor(const MatExpr& expr, Mat& m) const; + + virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const; + + virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + + virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const; + + virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void divide(double s, const MatExpr& expr, MatExpr& res) const; + + virtual void abs(const MatExpr& expr, MatExpr& res) const; + + virtual void transpose(const MatExpr& expr, MatExpr& res) const; + virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void invert(const MatExpr& expr, int method, MatExpr& res) const; + + virtual Size size(const MatExpr& expr) const; + virtual int type(const MatExpr& expr) const; +}; + + +class CV_EXPORTS MatExpr +{ +public: + MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {} + MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(), + const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar()) + : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {} + explicit MatExpr(const Mat& m); + operator Mat() const + { + Mat m; + op->assign(*this, m); + return m; + } + + template operator Mat_<_Tp>() const + { + Mat_<_Tp> m; + op->assign(*this, m, DataType<_Tp>::type); + return m; + } + + MatExpr row(int y) const; + MatExpr col(int x) const; + MatExpr diag(int d=0) const; + MatExpr operator()( const Range& rowRange, const Range& colRange ) const; + MatExpr operator()( const Rect& roi ) const; + + Mat cross(const Mat& m) const; + double dot(const Mat& m) const; + + MatExpr t() const; + MatExpr inv(int method = DECOMP_LU) const; + MatExpr mul(const MatExpr& e, double scale=1) const; + MatExpr mul(const Mat& m, double scale=1) const; + + Size size() const; + int type() const; + + const MatOp* op; + int flags; + + Mat a, b, c; + double alpha, beta; + Scalar s; +}; + + +CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator - (const Mat& m); +CV_EXPORTS MatExpr operator - (const MatExpr& e); + +CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator * (const Mat& a, double s); +CV_EXPORTS MatExpr operator * (double s, const Mat& a); +CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator * (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator / (const Mat& a, double s); +CV_EXPORTS MatExpr operator / (double s, const Mat& a); +CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator / (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator < (const Mat& a, double s); +CV_EXPORTS MatExpr operator < (double s, const Mat& a); + +CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator <= (const Mat& a, double s); +CV_EXPORTS MatExpr operator <= (double s, const Mat& a); + +CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator == (const Mat& a, double s); +CV_EXPORTS MatExpr operator == (double s, const Mat& a); + +CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator != (const Mat& a, double s); +CV_EXPORTS MatExpr operator != (double s, const Mat& a); + +CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator >= (const Mat& a, double s); +CV_EXPORTS MatExpr operator >= (double s, const Mat& a); + +CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator > (const Mat& a, double s); +CV_EXPORTS MatExpr operator > (double s, const Mat& a); + +CV_EXPORTS MatExpr min(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr min(const Mat& a, double s); +CV_EXPORTS MatExpr min(double s, const Mat& a); + +CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr max(const Mat& a, double s); +CV_EXPORTS MatExpr max(double s, const Mat& a); + +template static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + return cv::min((const Mat&)a, (const Mat&)b); +} + +template static inline MatExpr min(const Mat_<_Tp>& a, double s) +{ + return cv::min((const Mat&)a, s); +} + +template static inline MatExpr min(double s, const Mat_<_Tp>& a) +{ + return cv::min((const Mat&)a, s); +} + +template static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + return cv::max((const Mat&)a, (const Mat&)b); +} + +template static inline MatExpr max(const Mat_<_Tp>& a, double s) +{ + return cv::max((const Mat&)a, s); +} + +template static inline MatExpr max(double s, const Mat_<_Tp>& a) +{ + return cv::max((const Mat&)a, s); +} + +template static inline void min(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c) +{ + cv::min((const Mat&)a, (const Mat&)b, (Mat&)c); +} + +template static inline void min(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c) +{ + cv::min((const Mat&)a, s, (Mat&)c); +} + +template static inline void min(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c) +{ + cv::min((const Mat&)a, s, (Mat&)c); +} + +template static inline void max(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c) +{ + cv::max((const Mat&)a, (const Mat&)b, (Mat&)c); +} + +template static inline void max(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c) +{ + cv::max((const Mat&)a, s, (Mat&)c); +} + +template static inline void max(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c) +{ + cv::max((const Mat&)a, s, (Mat&)c); +} + + +CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a); + +CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a); + +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a); + +CV_EXPORTS MatExpr operator ~(const Mat& m); + +CV_EXPORTS MatExpr abs(const Mat& m); +CV_EXPORTS MatExpr abs(const MatExpr& e); + +template static inline MatExpr abs(const Mat_<_Tp>& m) +{ + return cv::abs((const Mat&)m); +} + +////////////////////////////// Augmenting algebraic operations ////////////////////////////////// + +inline Mat& Mat::operator = (const MatExpr& e) +{ + e.op->assign(e, *this); + return *this; +} + +template inline Mat_<_Tp>::Mat_(const MatExpr& e) +{ + e.op->assign(e, *this, DataType<_Tp>::type); +} + +template Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e) +{ + e.op->assign(e, *this, DataType<_Tp>::type); + return *this; +} + +static inline Mat& operator += (const Mat& a, const Mat& b) +{ + add(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator += (const Mat& a, const Scalar& s) +{ + add(a, s, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + add(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s) +{ + add(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator += (const Mat& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator -= (const Mat& a, const Mat& b) +{ + subtract(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator -= (const Mat& a, const Scalar& s) +{ + subtract(a, s, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + subtract(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s) +{ + subtract(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator -= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator *= (const Mat& a, const Mat& b) +{ + gemm(a, b, 1, Mat(), 0, (Mat&)a, 0); + return (Mat&)a; +} + +static inline Mat& operator *= (const Mat& a, double s) +{ + a.convertTo((Mat&)a, -1, s); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + gemm(a, b, 1, Mat(), 0, (Mat&)a, 0); + return (Mat_<_Tp>&)a; +} + +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s) +{ + a.convertTo((Mat&)a, -1, s); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator *= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator /= (const Mat& a, const Mat& b) +{ + divide(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator /= (const Mat& a, double s) +{ + a.convertTo((Mat&)a, -1, 1./s); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + divide(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s) +{ + a.convertTo((Mat&)a, -1, 1./s); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator /= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, (Mat&)a); + return (Mat&)a; +} + +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +////////////////////////////// Logical operations /////////////////////////////// + +static inline Mat& operator &= (const Mat& a, const Mat& b) +{ + bitwise_and(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator &= (const Mat& a, const Scalar& s) +{ + bitwise_and(a, s, (Mat&)a); + return (Mat&)a; +} + +template static inline Mat_<_Tp>& +operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + bitwise_and(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline Mat_<_Tp>& +operator &= (const Mat_<_Tp>& a, const Scalar& s) +{ + bitwise_and(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator |= (const Mat& a, const Mat& b) +{ + bitwise_or(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator |= (const Mat& a, const Scalar& s) +{ + bitwise_or(a, s, (Mat&)a); + return (Mat&)a; +} + +template static inline Mat_<_Tp>& +operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + bitwise_or(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline Mat_<_Tp>& +operator |= (const Mat_<_Tp>& a, const Scalar& s) +{ + bitwise_or(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator ^= (const Mat& a, const Mat& b) +{ + bitwise_xor(a, b, (Mat&)a); + return (Mat&)a; +} + +static inline Mat& operator ^= (const Mat& a, const Scalar& s) +{ + bitwise_xor(a, s, (Mat&)a); + return (Mat&)a; +} + +template static inline Mat_<_Tp>& +operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + bitwise_xor(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +template static inline Mat_<_Tp>& +operator ^= (const Mat_<_Tp>& a, const Scalar& s) +{ + bitwise_xor(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +/////////////////////////////// Miscellaneous operations ////////////////////////////// + +template void split(const Mat& src, vector >& mv) +{ split(src, (vector&)mv ); } + +////////////////////////////////////////////////////////////// + +template inline MatExpr Mat_<_Tp>::zeros(int rows, int cols) +{ + return Mat::zeros(rows, cols, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::zeros(Size sz) +{ + return Mat::zeros(sz, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::ones(int rows, int cols) +{ + return Mat::ones(rows, cols, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::ones(Size sz) +{ + return Mat::ones(sz, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::eye(int rows, int cols) +{ + return Mat::eye(rows, cols, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::eye(Size sz) +{ + return Mat::eye(sz, DataType<_Tp>::type); +} + +//////////////////////////////// Iterators & Comma initializers ////////////////////////////////// + +inline MatConstIterator::MatConstIterator() + : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {} + +inline MatConstIterator::MatConstIterator(const Mat* _m) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + if( m && m->isContinuous() ) + { + sliceStart = m->data; + sliceEnd = sliceStart + m->total()*elemSize; + } + seek((const int*)0); +} + +inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + CV_Assert(m && m->dims <= 2); + if( m->isContinuous() ) + { + sliceStart = m->data; + sliceEnd = sliceStart + m->total()*elemSize; + } + int idx[]={_row, _col}; + seek(idx); +} + +inline MatConstIterator::MatConstIterator(const Mat* _m, Point _pt) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + CV_Assert(m && m->dims <= 2); + if( m->isContinuous() ) + { + sliceStart = m->data; + sliceEnd = sliceStart + m->total()*elemSize; + } + int idx[]={_pt.y, _pt.x}; + seek(idx); +} + +inline MatConstIterator::MatConstIterator(const MatConstIterator& it) + : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd) +{} + +inline MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it ) +{ + m = it.m; elemSize = it.elemSize; ptr = it.ptr; + sliceStart = it.sliceStart; sliceEnd = it.sliceEnd; + return *this; +} + +inline uchar* MatConstIterator::operator *() const { return ptr; } + +inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs) +{ + if( !m || ofs == 0 ) + return *this; + ptrdiff_t ofsb = ofs*elemSize; + ptr += ofsb; + if( ptr < sliceStart || sliceEnd <= ptr ) + { + ptr -= ofsb; + seek(ofs, true); + } + return *this; +} + +inline MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs) +{ return (*this += -ofs); } + +inline MatConstIterator& MatConstIterator::operator --() +{ + if( m && (ptr -= elemSize) < sliceStart ) + { + ptr += elemSize; + seek(-1, true); + } + return *this; +} + +inline MatConstIterator MatConstIterator::operator --(int) +{ + MatConstIterator b = *this; + *this += -1; + return b; +} + +inline MatConstIterator& MatConstIterator::operator ++() +{ + if( m && (ptr += elemSize) >= sliceEnd ) + { + ptr -= elemSize; + seek(1, true); + } + return *this; +} + +inline MatConstIterator MatConstIterator::operator ++(int) +{ + MatConstIterator b = *this; + *this += 1; + return b; +} + +template inline MatConstIterator_<_Tp>::MatConstIterator_() {} + +template inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m) + : MatConstIterator(_m) {} + +template inline MatConstIterator_<_Tp>:: + MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col) + : MatConstIterator(_m, _row, _col) {} + +template inline MatConstIterator_<_Tp>:: + MatConstIterator_(const Mat_<_Tp>* _m, Point _pt) + : MatConstIterator(_m, _pt) {} + +template inline MatConstIterator_<_Tp>:: + MatConstIterator_(const MatConstIterator_& it) + : MatConstIterator(it) {} + +template inline MatConstIterator_<_Tp>& + MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it ) +{ + MatConstIterator::operator = (it); + return *this; +} + +template inline _Tp MatConstIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); } + +template inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs) +{ + MatConstIterator::operator += (ofs); + return *this; +} + +template inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs) +{ return (*this += -ofs); } + +template inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --() +{ + MatConstIterator::operator --(); + return *this; +} + +template inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int) +{ + MatConstIterator_ b = *this; + MatConstIterator::operator --(); + return b; +} + +template inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++() +{ + MatConstIterator::operator ++(); + return *this; +} + +template inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int) +{ + MatConstIterator_ b = *this; + MatConstIterator::operator ++(); + return b; +} + +template inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {} + +template inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m) + : MatConstIterator_<_Tp>(_m) {} + +template inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col) + : MatConstIterator_<_Tp>(_m, _row, _col) {} + +template inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt) + : MatConstIterator_<_Tp>(_m, _pt) {} + +template inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx) + : MatConstIterator_<_Tp>(_m, _idx) {} + +template inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it) + : MatConstIterator_<_Tp>(it) {} + +template inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it ) +{ + MatConstIterator::operator = (it); + return *this; +} + +template inline _Tp& MatIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); } + +template inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs) +{ + MatConstIterator::operator += (ofs); + return *this; +} + +template inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs) +{ + MatConstIterator::operator += (-ofs); + return *this; +} + +template inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --() +{ + MatConstIterator::operator --(); + return *this; +} + +template inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int) +{ + MatIterator_ b = *this; + MatConstIterator::operator --(); + return b; +} + +template inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++() +{ + MatConstIterator::operator ++(); + return *this; +} + +template inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int) +{ + MatIterator_ b = *this; + MatConstIterator::operator ++(); + return b; +} + +template inline Point MatConstIterator_<_Tp>::pos() const +{ + if( !m ) + return Point(); + CV_DbgAssert( m->dims <= 2 ); + if( m->isContinuous() ) + { + ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data; + int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols); + return Point(x, y); + } + else + { + ptrdiff_t ofs = (uchar*)ptr - m->data; + int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp)); + return Point(x, y); + } +} + +static inline bool +operator == (const MatConstIterator& a, const MatConstIterator& b) +{ return a.m == b.m && a.ptr == b.ptr; } + +template static inline bool +operator != (const MatConstIterator& a, const MatConstIterator& b) +{ return !(a == b); } + +template static inline bool +operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b) +{ return a.m == b.m && a.ptr == b.ptr; } + +template static inline bool +operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b) +{ return a.m != b.m || a.ptr != b.ptr; } + +template static inline bool +operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b) +{ return a.m == b.m && a.ptr == b.ptr; } + +template static inline bool +operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b) +{ return a.m != b.m || a.ptr != b.ptr; } + +static inline bool +operator < (const MatConstIterator& a, const MatConstIterator& b) +{ return a.ptr < b.ptr; } + +static inline bool +operator > (const MatConstIterator& a, const MatConstIterator& b) +{ return a.ptr > b.ptr; } + +static inline bool +operator <= (const MatConstIterator& a, const MatConstIterator& b) +{ return a.ptr <= b.ptr; } + +static inline bool +operator >= (const MatConstIterator& a, const MatConstIterator& b) +{ return a.ptr >= b.ptr; } + +CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a); + +static inline MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs) +{ MatConstIterator b = a; return b += ofs; } + +static inline MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a) +{ MatConstIterator b = a; return b += ofs; } + +static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs) +{ MatConstIterator b = a; return b += -ofs; } + +template static inline MatConstIterator_<_Tp> +operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs) +{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; } + +template static inline MatConstIterator_<_Tp> +operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a) +{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; } + +template static inline MatConstIterator_<_Tp> +operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs) +{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; } + +inline uchar* MatConstIterator::operator [](ptrdiff_t i) const +{ return *(*this + i); } + +template inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const +{ return *(_Tp*)MatConstIterator::operator [](i); } + +template static inline MatIterator_<_Tp> +operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs) +{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; } + +template static inline MatIterator_<_Tp> +operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a) +{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; } + +template static inline MatIterator_<_Tp> +operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs) +{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; } + +template inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const +{ return *(*this + i); } + +template inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const +{ return Mat::begin<_Tp>(); } + +template inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const +{ return Mat::end<_Tp>(); } + +template inline MatIterator_<_Tp> Mat_<_Tp>::begin() +{ return Mat::begin<_Tp>(); } + +template inline MatIterator_<_Tp> Mat_<_Tp>::end() +{ return Mat::end<_Tp>(); } + +template inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {} + +template template inline MatCommaInitializer_<_Tp>& +MatCommaInitializer_<_Tp>::operator , (T2 v) +{ + CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() ); + *this->it = _Tp(v); ++this->it; + return *this; +} + +template inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const +{ + CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() ); + return Mat_<_Tp>(*this->it.m); +} + +template inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const +{ + CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() ); + return Mat_<_Tp>(*this->it.m); +} + +template static inline MatCommaInitializer_<_Tp> +operator << (const Mat_<_Tp>& m, T2 val) +{ + MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m); + return (commaInitializer, val); +} + +//////////////////////////////// SparseMat //////////////////////////////// + +inline SparseMat::SparseMat() +: flags(MAGIC_VAL), hdr(0) +{ +} + +inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type) +: flags(MAGIC_VAL), hdr(0) +{ + create(_dims, _sizes, _type); +} + +inline SparseMat::SparseMat(const SparseMat& m) +: flags(m.flags), hdr(m.hdr) +{ + addref(); +} + +inline SparseMat::~SparseMat() +{ + release(); +} + +inline SparseMat& SparseMat::operator = (const SparseMat& m) +{ + if( this != &m ) + { + if( m.hdr ) + CV_XADD(&m.hdr->refcount, 1); + release(); + flags = m.flags; + hdr = m.hdr; + } + return *this; +} + +inline SparseMat& SparseMat::operator = (const Mat& m) +{ return (*this = SparseMat(m)); } + +inline SparseMat SparseMat::clone() const +{ + SparseMat temp; + this->copyTo(temp); + return temp; +} + + +inline void SparseMat::assignTo( SparseMat& m, int _type ) const +{ + if( _type < 0 ) + m = *this; + else + convertTo(m, _type); +} + +inline void SparseMat::addref() +{ if( hdr ) CV_XADD(&hdr->refcount, 1); } + +inline void SparseMat::release() +{ + if( hdr && CV_XADD(&hdr->refcount, -1) == 1 ) + delete hdr; + hdr = 0; +} + +inline size_t SparseMat::elemSize() const +{ return CV_ELEM_SIZE(flags); } + +inline size_t SparseMat::elemSize1() const +{ return CV_ELEM_SIZE1(flags); } + +inline int SparseMat::type() const +{ return CV_MAT_TYPE(flags); } + +inline int SparseMat::depth() const +{ return CV_MAT_DEPTH(flags); } + +inline int SparseMat::channels() const +{ return CV_MAT_CN(flags); } + +inline const int* SparseMat::size() const +{ + return hdr ? hdr->size : 0; +} + +inline int SparseMat::size(int i) const +{ + if( hdr ) + { + CV_DbgAssert((unsigned)i < (unsigned)hdr->dims); + return hdr->size[i]; + } + return 0; +} + +inline int SparseMat::dims() const +{ + return hdr ? hdr->dims : 0; +} + +inline size_t SparseMat::nzcount() const +{ + return hdr ? hdr->nodeCount : 0; +} + +inline size_t SparseMat::hash(int i0) const +{ + return (size_t)i0; +} + +inline size_t SparseMat::hash(int i0, int i1) const +{ + return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1; +} + +inline size_t SparseMat::hash(int i0, int i1, int i2) const +{ + return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2; +} + +inline size_t SparseMat::hash(const int* idx) const +{ + size_t h = (unsigned)idx[0]; + if( !hdr ) + return 0; + int i, d = hdr->dims; + for( i = 1; i < d; i++ ) + h = h*HASH_SCALE + (unsigned)idx[i]; + return h; +} + +template inline _Tp& SparseMat::ref(int i0, size_t* hashval) +{ return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); } + +template inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval) +{ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); } + +template inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval) +{ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); } + +template inline _Tp& SparseMat::ref(const int* idx, size_t* hashval) +{ return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); } + +template inline _Tp SparseMat::value(int i0, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); + return p ? *p : _Tp(); +} + +template inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); + return p ? *p : _Tp(); +} + +template inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); + return p ? *p : _Tp(); +} + +template inline _Tp SparseMat::value(const int* idx, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); + return p ? *p : _Tp(); +} + +template inline const _Tp* SparseMat::find(int i0, size_t* hashval) const +{ return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); } + +template inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const +{ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); } + +template inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const +{ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); } + +template inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const +{ return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); } + +template inline _Tp& SparseMat::value(Node* n) +{ return *(_Tp*)((uchar*)n + hdr->valueOffset); } + +template inline const _Tp& SparseMat::value(const Node* n) const +{ return *(const _Tp*)((const uchar*)n + hdr->valueOffset); } + +inline SparseMat::Node* SparseMat::node(size_t nidx) +{ return (Node*)&hdr->pool[nidx]; } + +inline const SparseMat::Node* SparseMat::node(size_t nidx) const +{ return (const Node*)&hdr->pool[nidx]; } + +inline SparseMatIterator SparseMat::begin() +{ return SparseMatIterator(this); } + +inline SparseMatConstIterator SparseMat::begin() const +{ return SparseMatConstIterator(this); } + +inline SparseMatIterator SparseMat::end() +{ SparseMatIterator it(this); it.seekEnd(); return it; } + +inline SparseMatConstIterator SparseMat::end() const +{ SparseMatConstIterator it(this); it.seekEnd(); return it; } + +template inline SparseMatIterator_<_Tp> SparseMat::begin() +{ return SparseMatIterator_<_Tp>(this); } + +template inline SparseMatConstIterator_<_Tp> SparseMat::begin() const +{ return SparseMatConstIterator_<_Tp>(this); } + +template inline SparseMatIterator_<_Tp> SparseMat::end() +{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; } + +template inline SparseMatConstIterator_<_Tp> SparseMat::end() const +{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; } + + +inline SparseMatConstIterator::SparseMatConstIterator() +: m(0), hashidx(0), ptr(0) +{ +} + +inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it) +: m(it.m), hashidx(it.hashidx), ptr(it.ptr) +{ +} + +static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2) +{ return it1.m == it2.m && it1.ptr == it2.ptr; } + +static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2) +{ return !(it1 == it2); } + + +inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it) +{ + if( this != &it ) + { + m = it.m; + hashidx = it.hashidx; + ptr = it.ptr; + } + return *this; +} + +template inline const _Tp& SparseMatConstIterator::value() const +{ return *(_Tp*)ptr; } + +inline const SparseMat::Node* SparseMatConstIterator::node() const +{ + return ptr && m && m->hdr ? + (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0; +} + +inline SparseMatConstIterator SparseMatConstIterator::operator ++(int) +{ + SparseMatConstIterator it = *this; + ++*this; + return it; +} + + +inline void SparseMatConstIterator::seekEnd() +{ + if( m && m->hdr ) + { + hashidx = m->hdr->hashtab.size(); + ptr = 0; + } +} + +inline SparseMatIterator::SparseMatIterator() +{} + +inline SparseMatIterator::SparseMatIterator(SparseMat* _m) +: SparseMatConstIterator(_m) +{} + +inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it) +: SparseMatConstIterator(it) +{ +} + +inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it) +{ + (SparseMatConstIterator&)*this = it; + return *this; +} + +template inline _Tp& SparseMatIterator::value() const +{ return *(_Tp*)ptr; } + +inline SparseMat::Node* SparseMatIterator::node() const +{ + return (SparseMat::Node*)SparseMatConstIterator::node(); +} + +inline SparseMatIterator& SparseMatIterator::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +inline SparseMatIterator SparseMatIterator::operator ++(int) +{ + SparseMatIterator it = *this; + ++*this; + return it; +} + + +template inline SparseMat_<_Tp>::SparseMat_() +{ flags = MAGIC_VAL | DataType<_Tp>::type; } + +template inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes) +: SparseMat(_dims, _sizes, DataType<_Tp>::type) +{} + +template inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m) +{ + if( m.type() == DataType<_Tp>::type ) + *this = (const SparseMat_<_Tp>&)m; + else + m.convertTo(this, DataType<_Tp>::type); +} + +template inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m) +{ + this->flags = m.flags; + this->hdr = m.hdr; + if( this->hdr ) + CV_XADD(&this->hdr->refcount, 1); +} + +template inline SparseMat_<_Tp>::SparseMat_(const Mat& m) +{ + SparseMat sm(m); + *this = sm; +} + +template inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m) +{ + SparseMat sm(m); + *this = sm; +} + +template inline SparseMat_<_Tp>& +SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m) +{ + if( this != &m ) + { + if( m.hdr ) CV_XADD(&m.hdr->refcount, 1); + release(); + flags = m.flags; + hdr = m.hdr; + } + return *this; +} + +template inline SparseMat_<_Tp>& +SparseMat_<_Tp>::operator = (const SparseMat& m) +{ + if( m.type() == DataType<_Tp>::type ) + return (*this = (const SparseMat_<_Tp>&)m); + m.convertTo(*this, DataType<_Tp>::type); + return *this; +} + +template inline SparseMat_<_Tp>& +SparseMat_<_Tp>::operator = (const Mat& m) +{ return (*this = SparseMat(m)); } + +template inline SparseMat_<_Tp> +SparseMat_<_Tp>::clone() const +{ + SparseMat_<_Tp> m; + this->copyTo(m); + return m; +} + +template inline void +SparseMat_<_Tp>::create(int _dims, const int* _sizes) +{ + SparseMat::create(_dims, _sizes, DataType<_Tp>::type); +} + +template inline +SparseMat_<_Tp>::operator CvSparseMat*() const +{ + return SparseMat::operator CvSparseMat*(); +} + +template inline int SparseMat_<_Tp>::type() const +{ return DataType<_Tp>::type; } + +template inline int SparseMat_<_Tp>::depth() const +{ return DataType<_Tp>::depth; } + +template inline int SparseMat_<_Tp>::channels() const +{ return DataType<_Tp>::channels; } + +template inline _Tp& +SparseMat_<_Tp>::ref(int i0, size_t* hashval) +{ return SparseMat::ref<_Tp>(i0, hashval); } + +template inline _Tp +SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const +{ return SparseMat::value<_Tp>(i0, hashval); } + +template inline _Tp& +SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval) +{ return SparseMat::ref<_Tp>(i0, i1, hashval); } + +template inline _Tp +SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const +{ return SparseMat::value<_Tp>(i0, i1, hashval); } + +template inline _Tp& +SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval) +{ return SparseMat::ref<_Tp>(i0, i1, i2, hashval); } + +template inline _Tp +SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const +{ return SparseMat::value<_Tp>(i0, i1, i2, hashval); } + +template inline _Tp& +SparseMat_<_Tp>::ref(const int* idx, size_t* hashval) +{ return SparseMat::ref<_Tp>(idx, hashval); } + +template inline _Tp +SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const +{ return SparseMat::value<_Tp>(idx, hashval); } + +template inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin() +{ return SparseMatIterator_<_Tp>(this); } + +template inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const +{ return SparseMatConstIterator_<_Tp>(this); } + +template inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end() +{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; } + +template inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const +{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; } + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_() +{} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m) +: SparseMatConstIterator(_m) +{} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m) +: SparseMatConstIterator(_m) +{ + CV_Assert( _m->type() == DataType<_Tp>::type ); +} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it) +: SparseMatConstIterator(it) +{} + +template inline SparseMatConstIterator_<_Tp>& +SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it) +{ return reinterpret_cast&> + (*reinterpret_cast(this) = + reinterpret_cast(it)); } + +template inline const _Tp& +SparseMatConstIterator_<_Tp>::operator *() const +{ return *(const _Tp*)this->ptr; } + +template inline SparseMatConstIterator_<_Tp>& +SparseMatConstIterator_<_Tp>::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +template inline SparseMatConstIterator_<_Tp> +SparseMatConstIterator_<_Tp>::operator ++(int) +{ + SparseMatConstIterator it = *this; + SparseMatConstIterator::operator ++(); + return it; +} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_() +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m) +: SparseMatConstIterator_<_Tp>(_m) +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m) +: SparseMatConstIterator_<_Tp>(_m) +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it) +: SparseMatConstIterator_<_Tp>(it) +{} + +template inline SparseMatIterator_<_Tp>& +SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it) +{ return reinterpret_cast&> + (*reinterpret_cast(this) = + reinterpret_cast(it)); } + +template inline _Tp& +SparseMatIterator_<_Tp>::operator *() const +{ return *(_Tp*)this->ptr; } + +template inline SparseMatIterator_<_Tp>& +SparseMatIterator_<_Tp>::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +template inline SparseMatIterator_<_Tp> +SparseMatIterator_<_Tp>::operator ++(int) +{ + SparseMatIterator it = *this; + SparseMatConstIterator::operator ++(); + return it; +} + +} + +#endif +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,284 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OPENGL_INTEROP_HPP__ +#define __OPENCV_OPENGL_INTEROP_HPP__ + +#ifdef __cplusplus + +#include "opencv2/core/core.hpp" +#include "opencv2/core/opengl_interop_deprecated.hpp" + +namespace cv { namespace ogl { + +/////////////////// OpenGL Objects /////////////////// + +//! Smart pointer for OpenGL buffer memory with reference counting. +class CV_EXPORTS Buffer +{ +public: + enum Target + { + ARRAY_BUFFER = 0x8892, //!< The buffer will be used as a source for vertex data + ELEMENT_ARRAY_BUFFER = 0x8893, //!< The buffer will be used for indices (in glDrawElements, for example) + PIXEL_PACK_BUFFER = 0x88EB, //!< The buffer will be used for reading from OpenGL textures + PIXEL_UNPACK_BUFFER = 0x88EC //!< The buffer will be used for writing to OpenGL textures + }; + + enum Access + { + READ_ONLY = 0x88B8, + WRITE_ONLY = 0x88B9, + READ_WRITE = 0x88BA + }; + + //! create empty buffer + Buffer(); + + //! create buffer from existed buffer id + Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease = false); + Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease = false); + + //! create buffer + Buffer(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + Buffer(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + + //! copy from host/device memory + explicit Buffer(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false); + + //! create buffer + void create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false) { create(asize.height, asize.width, atype, target, autoRelease); } + + //! release memory and delete buffer object + void release(); + + //! set auto release mode (if true, release will be called in object's destructor) + void setAutoRelease(bool flag); + + //! copy from host/device memory + void copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false); + + //! copy to host/device memory + void copyTo(OutputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false) const; + + //! create copy of current buffer + Buffer clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const; + + //! bind buffer for specified target + void bind(Target target) const; + + //! unbind any buffers from specified target + static void unbind(Target target); + + //! map to host memory + Mat mapHost(Access access); + void unmapHost(); + + //! map to device memory + gpu::GpuMat mapDevice(); + void unmapDevice(); + + int rows() const { return rows_; } + int cols() const { return cols_; } + Size size() const { return Size(cols_, rows_); } + bool empty() const { return rows_ == 0 || cols_ == 0; } + + int type() const { return type_; } + int depth() const { return CV_MAT_DEPTH(type_); } + int channels() const { return CV_MAT_CN(type_); } + int elemSize() const { return CV_ELEM_SIZE(type_); } + int elemSize1() const { return CV_ELEM_SIZE1(type_); } + + unsigned int bufId() const; + + class Impl; + +private: + Ptr impl_; + int rows_; + int cols_; + int type_; +}; + +//! Smart pointer for OpenGL 2D texture memory with reference counting. +class CV_EXPORTS Texture2D +{ +public: + enum Format + { + NONE = 0, + DEPTH_COMPONENT = 0x1902, //!< Depth + RGB = 0x1907, //!< Red, Green, Blue + RGBA = 0x1908 //!< Red, Green, Blue, Alpha + }; + + //! create empty texture + Texture2D(); + + //! create texture from existed texture id + Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease = false); + Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease = false); + + //! create texture + Texture2D(int arows, int acols, Format aformat, bool autoRelease = false); + Texture2D(Size asize, Format aformat, bool autoRelease = false); + + //! copy from host/device memory + explicit Texture2D(InputArray arr, bool autoRelease = false); + + //! create texture + void create(int arows, int acols, Format aformat, bool autoRelease = false); + void create(Size asize, Format aformat, bool autoRelease = false) { create(asize.height, asize.width, aformat, autoRelease); } + + //! release memory and delete texture object + void release(); + + //! set auto release mode (if true, release will be called in object's destructor) + void setAutoRelease(bool flag); + + //! copy from host/device memory + void copyFrom(InputArray arr, bool autoRelease = false); + + //! copy to host/device memory + void copyTo(OutputArray arr, int ddepth = CV_32F, bool autoRelease = false) const; + + //! bind texture to current active texture unit for GL_TEXTURE_2D target + void bind() const; + + int rows() const { return rows_; } + int cols() const { return cols_; } + Size size() const { return Size(cols_, rows_); } + bool empty() const { return rows_ == 0 || cols_ == 0; } + + Format format() const { return format_; } + + unsigned int texId() const; + + class Impl; + +private: + Ptr impl_; + int rows_; + int cols_; + Format format_; +}; + +//! OpenGL Arrays +class CV_EXPORTS Arrays +{ +public: + Arrays(); + + void setVertexArray(InputArray vertex); + void resetVertexArray(); + + void setColorArray(InputArray color); + void resetColorArray(); + + void setNormalArray(InputArray normal); + void resetNormalArray(); + + void setTexCoordArray(InputArray texCoord); + void resetTexCoordArray(); + + void release(); + + void setAutoRelease(bool flag); + + void bind() const; + + int size() const { return size_; } + bool empty() const { return size_ == 0; } + +private: + int size_; + Buffer vertex_; + Buffer color_; + Buffer normal_; + Buffer texCoord_; +}; + +/////////////////// Render Functions /////////////////// + +//! render texture rectangle in window +CV_EXPORTS void render(const Texture2D& tex, + Rect_ wndRect = Rect_(0.0, 0.0, 1.0, 1.0), + Rect_ texRect = Rect_(0.0, 0.0, 1.0, 1.0)); + +//! render mode +enum { + POINTS = 0x0000, + LINES = 0x0001, + LINE_LOOP = 0x0002, + LINE_STRIP = 0x0003, + TRIANGLES = 0x0004, + TRIANGLE_STRIP = 0x0005, + TRIANGLE_FAN = 0x0006, + QUADS = 0x0007, + QUAD_STRIP = 0x0008, + POLYGON = 0x0009 +}; + +//! render OpenGL arrays +CV_EXPORTS void render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255)); +CV_EXPORTS void render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255)); + +}} // namespace cv::gl + +namespace cv { namespace gpu { + +//! set a CUDA device to use OpenGL interoperability +CV_EXPORTS void setGlDevice(int device = 0); + +}} + +namespace cv { + +template <> CV_EXPORTS void Ptr::delete_obj(); +template <> CV_EXPORTS void Ptr::delete_obj(); + +} + +#endif // __cplusplus + +#endif // __OPENCV_OPENGL_INTEROP_HPP__ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop_deprecated.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop_deprecated.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop_deprecated.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/opengl_interop_deprecated.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,330 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OPENGL_INTEROP_DEPRECATED_HPP__ +#define __OPENCV_OPENGL_INTEROP_DEPRECATED_HPP__ + +#ifdef __cplusplus + +#include "opencv2/core/core.hpp" + +namespace cv +{ +//! Smart pointer for OpenGL buffer memory with reference counting. +class CV_EXPORTS GlBuffer +{ +public: + enum Usage + { + ARRAY_BUFFER = 0x8892, // buffer will use for OpenGL arrays (vertices, colors, normals, etc) + TEXTURE_BUFFER = 0x88EC // buffer will ise for OpenGL textures + }; + + //! create empty buffer + explicit GlBuffer(Usage usage); + + //! create buffer + GlBuffer(int rows, int cols, int type, Usage usage); + GlBuffer(Size size, int type, Usage usage); + + //! copy from host/device memory + GlBuffer(InputArray mat, Usage usage); + + void create(int rows, int cols, int type, Usage usage); + void create(Size size, int type, Usage usage); + void create(int rows, int cols, int type); + void create(Size size, int type); + + void release(); + + //! copy from host/device memory + void copyFrom(InputArray mat); + + void bind() const; + void unbind() const; + + //! map to host memory + Mat mapHost(); + void unmapHost(); + + //! map to device memory + gpu::GpuMat mapDevice(); + void unmapDevice(); + + inline int rows() const { return rows_; } + inline int cols() const { return cols_; } + inline Size size() const { return Size(cols_, rows_); } + inline bool empty() const { return rows_ == 0 || cols_ == 0; } + + inline int type() const { return type_; } + inline int depth() const { return CV_MAT_DEPTH(type_); } + inline int channels() const { return CV_MAT_CN(type_); } + inline int elemSize() const { return CV_ELEM_SIZE(type_); } + inline int elemSize1() const { return CV_ELEM_SIZE1(type_); } + + inline Usage usage() const { return usage_; } + + class Impl; +private: + int rows_; + int cols_; + int type_; + Usage usage_; + + Ptr impl_; +}; + +template <> CV_EXPORTS void Ptr::delete_obj(); + +//! Smart pointer for OpenGL 2d texture memory with reference counting. +class CV_EXPORTS GlTexture +{ +public: + //! create empty texture + GlTexture(); + + //! create texture + GlTexture(int rows, int cols, int type); + GlTexture(Size size, int type); + + //! copy from host/device memory + explicit GlTexture(InputArray mat, bool bgra = true); + + void create(int rows, int cols, int type); + void create(Size size, int type); + void release(); + + //! copy from host/device memory + void copyFrom(InputArray mat, bool bgra = true); + + void bind() const; + void unbind() const; + + inline int rows() const { return rows_; } + inline int cols() const { return cols_; } + inline Size size() const { return Size(cols_, rows_); } + inline bool empty() const { return rows_ == 0 || cols_ == 0; } + + inline int type() const { return type_; } + inline int depth() const { return CV_MAT_DEPTH(type_); } + inline int channels() const { return CV_MAT_CN(type_); } + inline int elemSize() const { return CV_ELEM_SIZE(type_); } + inline int elemSize1() const { return CV_ELEM_SIZE1(type_); } + + class Impl; +private: + int rows_; + int cols_; + int type_; + + Ptr impl_; + GlBuffer buf_; +}; + +template <> CV_EXPORTS void Ptr::delete_obj(); + +//! OpenGL Arrays +class CV_EXPORTS GlArrays +{ +public: + inline GlArrays() + : vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER) + { + } + + void setVertexArray(InputArray vertex); + inline void resetVertexArray() { vertex_.release(); } + + void setColorArray(InputArray color, bool bgra = true); + inline void resetColorArray() { color_.release(); } + + void setNormalArray(InputArray normal); + inline void resetNormalArray() { normal_.release(); } + + void setTexCoordArray(InputArray texCoord); + inline void resetTexCoordArray() { texCoord_.release(); } + + void bind() const; + void unbind() const; + + inline int rows() const { return vertex_.rows(); } + inline int cols() const { return vertex_.cols(); } + inline Size size() const { return vertex_.size(); } + inline bool empty() const { return vertex_.empty(); } + +private: + GlBuffer vertex_; + GlBuffer color_; + bool bgra_; + GlBuffer normal_; + GlBuffer texCoord_; +}; + +//! OpenGL Font +class CV_EXPORTS GlFont +{ +public: + enum Weight + { + WEIGHT_LIGHT = 300, + WEIGHT_NORMAL = 400, + WEIGHT_SEMIBOLD = 600, + WEIGHT_BOLD = 700, + WEIGHT_BLACK = 900 + }; + + enum Style + { + STYLE_NORMAL = 0, + STYLE_ITALIC = 1, + STYLE_UNDERLINE = 2 + }; + + static Ptr get(const std::string& family, int height = 12, Weight weight = WEIGHT_NORMAL, Style style = STYLE_NORMAL); + + void draw(const char* str, int len) const; + + inline const std::string& family() const { return family_; } + inline int height() const { return height_; } + inline Weight weight() const { return weight_; } + inline Style style() const { return style_; } + +private: + GlFont(const std::string& family, int height, Weight weight, Style style); + + std::string family_; + int height_; + Weight weight_; + Style style_; + + unsigned int base_; + + GlFont(const GlFont&); + GlFont& operator =(const GlFont&); +}; + +//! render functions + +//! render texture rectangle in window +CV_EXPORTS void render(const GlTexture& tex, + Rect_ wndRect = Rect_(0.0, 0.0, 1.0, 1.0), + Rect_ texRect = Rect_(0.0, 0.0, 1.0, 1.0)); + +//! render mode +namespace RenderMode { + enum { + POINTS = 0x0000, + LINES = 0x0001, + LINE_LOOP = 0x0002, + LINE_STRIP = 0x0003, + TRIANGLES = 0x0004, + TRIANGLE_STRIP = 0x0005, + TRIANGLE_FAN = 0x0006, + QUADS = 0x0007, + QUAD_STRIP = 0x0008, + POLYGON = 0x0009 + }; +} + +//! render OpenGL arrays +CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS, Scalar color = Scalar::all(255)); + +CV_EXPORTS void render(const std::string& str, const Ptr& font, Scalar color, Point2d pos); + +//! OpenGL camera +class CV_EXPORTS GlCamera +{ +public: + GlCamera(); + + void lookAt(Point3d eye, Point3d center, Point3d up); + void setCameraPos(Point3d pos, double yaw, double pitch, double roll); + + void setScale(Point3d scale); + + void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true); + void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar); + void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar); + + void setupProjectionMatrix() const; + void setupModelViewMatrix() const; + +private: + Point3d eye_; + Point3d center_; + Point3d up_; + + Point3d pos_; + double yaw_; + double pitch_; + double roll_; + + bool useLookAtParams_; + + Point3d scale_; + + Mat projectionMatrix_; + + double fov_; + double aspect_; + + double left_; + double right_; + double bottom_; + double top_; + + double zNear_; + double zFar_; + + bool perspectiveProjection_; +}; + +inline void GlBuffer::create(Size _size, int _type, Usage _usage) { create(_size.height, _size.width, _type, _usage); } +inline void GlBuffer::create(int _rows, int _cols, int _type) { create(_rows, _cols, _type, usage()); } +inline void GlBuffer::create(Size _size, int _type) { create(_size.height, _size.width, _type, usage()); } +inline void GlTexture::create(Size _size, int _type) { create(_size.height, _size.width, _type); } + +} // namespace cv + +#endif // __cplusplus + +#endif // __OPENCV_OPENGL_INTEROP_DEPRECATED_HPP__ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/operations.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/operations.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/operations.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/operations.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,3992 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_OPERATIONS_HPP__ +#define __OPENCV_CORE_OPERATIONS_HPP__ + +#ifndef SKIP_INCLUDES + #include + #include +#endif // SKIP_INCLUDES + + +#ifdef __cplusplus + +/////// exchange-add operation for atomic operations on reference counters /////// +#if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32) // atomic increment on the linux version of the Intel(tm) compiler + #define CV_XADD(addr,delta) _InterlockedExchangeAdd(const_cast(reinterpret_cast(addr)), delta) +#elif defined __GNUC__ + + #if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ + #ifdef __ATOMIC_SEQ_CST + #define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), (delta), __ATOMIC_SEQ_CST) + #else + #define CV_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), (delta), 5) + #endif + #elif __GNUC__*10 + __GNUC_MINOR__ >= 42 + + #if !(defined WIN32 || defined _WIN32) && (defined __i486__ || defined __i586__ || \ + defined __i686__ || defined __MMX__ || defined __SSE__ || defined __ppc__) || \ + (defined __GNUC__ && defined _STLPORT_MAJOR) + #define CV_XADD __sync_fetch_and_add + #else + #include + #define CV_XADD __gnu_cxx::__exchange_and_add + #endif + + #else + #include + #if __GNUC__*10 + __GNUC_MINOR__ >= 34 + #define CV_XADD __gnu_cxx::__exchange_and_add + #else + #define CV_XADD __exchange_and_add + #endif + #endif + +#elif defined WIN32 || defined _WIN32 || defined WINCE + namespace cv { CV_EXPORTS int _interlockedExchangeAdd(int* addr, int delta); } + #define CV_XADD cv::_interlockedExchangeAdd + +#else + static inline int CV_XADD(int* addr, int delta) + { int tmp = *addr; *addr += delta; return tmp; } +#endif + +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) //conditional expression is constant +#endif + +namespace cv +{ + +using std::cos; +using std::sin; +using std::max; +using std::min; +using std::exp; +using std::log; +using std::pow; +using std::sqrt; + + +/////////////// saturate_cast (used in image & signal processing) /////////////////// + +template static inline _Tp saturate_cast(uchar v) { return _Tp(v); } +template static inline _Tp saturate_cast(schar v) { return _Tp(v); } +template static inline _Tp saturate_cast(ushort v) { return _Tp(v); } +template static inline _Tp saturate_cast(short v) { return _Tp(v); } +template static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } +template static inline _Tp saturate_cast(int v) { return _Tp(v); } +template static inline _Tp saturate_cast(float v) { return _Tp(v); } +template static inline _Tp saturate_cast(double v) { return _Tp(v); } + +template<> inline uchar saturate_cast(schar v) +{ return (uchar)std::max((int)v, 0); } +template<> inline uchar saturate_cast(ushort v) +{ return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(int v) +{ return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } +template<> inline uchar saturate_cast(short v) +{ return saturate_cast((int)v); } +template<> inline uchar saturate_cast(unsigned v) +{ return (uchar)std::min(v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(float v) +{ int iv = cvRound(v); return saturate_cast(iv); } +template<> inline uchar saturate_cast(double v) +{ int iv = cvRound(v); return saturate_cast(iv); } + +template<> inline schar saturate_cast(uchar v) +{ return (schar)std::min((int)v, SCHAR_MAX); } +template<> inline schar saturate_cast(ushort v) +{ return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); } +template<> inline schar saturate_cast(int v) +{ + return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? + v : v > 0 ? SCHAR_MAX : SCHAR_MIN); +} +template<> inline schar saturate_cast(short v) +{ return saturate_cast((int)v); } +template<> inline schar saturate_cast(unsigned v) +{ return (schar)std::min(v, (unsigned)SCHAR_MAX); } + +template<> inline schar saturate_cast(float v) +{ int iv = cvRound(v); return saturate_cast(iv); } +template<> inline schar saturate_cast(double v) +{ int iv = cvRound(v); return saturate_cast(iv); } + +template<> inline ushort saturate_cast(schar v) +{ return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(short v) +{ return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(int v) +{ return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } +template<> inline ushort saturate_cast(unsigned v) +{ return (ushort)std::min(v, (unsigned)USHRT_MAX); } +template<> inline ushort saturate_cast(float v) +{ int iv = cvRound(v); return saturate_cast(iv); } +template<> inline ushort saturate_cast(double v) +{ int iv = cvRound(v); return saturate_cast(iv); } + +template<> inline short saturate_cast(ushort v) +{ return (short)std::min((int)v, SHRT_MAX); } +template<> inline short saturate_cast(int v) +{ + return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? + v : v > 0 ? SHRT_MAX : SHRT_MIN); +} +template<> inline short saturate_cast(unsigned v) +{ return (short)std::min(v, (unsigned)SHRT_MAX); } +template<> inline short saturate_cast(float v) +{ int iv = cvRound(v); return saturate_cast(iv); } +template<> inline short saturate_cast(double v) +{ int iv = cvRound(v); return saturate_cast(iv); } + +template<> inline int saturate_cast(float v) { return cvRound(v); } +template<> inline int saturate_cast(double v) { return cvRound(v); } + +// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. +template<> inline unsigned saturate_cast(float v){ return cvRound(v); } +template<> inline unsigned saturate_cast(double v) { return cvRound(v); } + +inline int fast_abs(uchar v) { return v; } +inline int fast_abs(schar v) { return std::abs((int)v); } +inline int fast_abs(ushort v) { return v; } +inline int fast_abs(short v) { return std::abs((int)v); } +inline int fast_abs(int v) { return std::abs(v); } +inline float fast_abs(float v) { return std::abs(v); } +inline double fast_abs(double v) { return std::abs(v); } + +//////////////////////////////// Matx ///////////////////////////////// + + +template inline Matx<_Tp, m, n>::Matx() +{ + for(int i = 0; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0) +{ + val[0] = v0; + for(int i = 1; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) +{ + assert(channels >= 2); + val[0] = v0; val[1] = v1; + for(int i = 2; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) +{ + assert(channels >= 3); + val[0] = v0; val[1] = v1; val[2] = v2; + for(int i = 3; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) +{ + assert(channels >= 4); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + for(int i = 4; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) +{ + assert(channels >= 5); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; + for(int i = 5; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5) +{ + assert(channels >= 6); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; + for(int i = 6; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6) +{ + assert(channels >= 7); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; + for(int i = 7; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7) +{ + assert(channels >= 8); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + for(int i = 8; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8) +{ + assert(channels >= 9); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; + for(int i = 9; i < channels; i++) val[i] = _Tp(0); +} + +template inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9) +{ + assert(channels >= 10); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; + for(int i = 10; i < channels; i++) val[i] = _Tp(0); +} + + +template +inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11) +{ + assert(channels == 12); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; +} + +template +inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11, + _Tp v12, _Tp v13, _Tp v14, _Tp v15) +{ + assert(channels == 16); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; +} + +template inline Matx<_Tp, m, n>::Matx(const _Tp* values) +{ + for( int i = 0; i < channels; i++ ) val[i] = values[i]; +} + +template inline Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) +{ + Matx<_Tp, m, n> M; + for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() +{ + return all(0); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() +{ + return all(1); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < MIN(m,n); i++) + M(i,i) = 1; + return M; +} + +template inline _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const +{ + _Tp s = 0; + for( int i = 0; i < m*n; i++ ) s += val[i]*M.val[i]; + return s; +} + + +template inline double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const +{ + double s = 0; + for( int i = 0; i < m*n; i++ ) s += (double)val[i]*M.val[i]; + return s; +} + + + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < MIN(m,n); i++) + M(i,i) = d(i, 0); + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b) +{ + Matx<_Tp,m,n> M; + Mat matM(M, false); + cv::randu(matM, Scalar(a), Scalar(b)); + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b) +{ + Matx<_Tp,m,n> M; + Mat matM(M, false); + cv::randn(matM, Scalar(a), Scalar(b)); + return M; +} + +template template +inline Matx<_Tp, m, n>::operator Matx() const +{ + Matx M; + for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast(val[i]); + return M; +} + + +template template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const +{ + CV_DbgAssert(m1*n1 == m*n); + return (const Matx<_Tp, m1, n1>&)*this; +} + + +template +template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const +{ + CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n); + Matx<_Tp, m1, n1> s; + for( int di = 0; di < m1; di++ ) + for( int dj = 0; dj < n1; dj++ ) + s(di, dj) = (*this)(i+di, j+dj); + return s; +} + + +template inline +Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const +{ + CV_DbgAssert((unsigned)i < (unsigned)m); + return Matx<_Tp, 1, n>(&val[i*n]); +} + + +template inline +Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const +{ + CV_DbgAssert((unsigned)j < (unsigned)n); + Matx<_Tp, m, 1> v; + for( int i = 0; i < m; i++ ) + v.val[i] = val[i*n + j]; + return v; +} + + +template inline +typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const +{ + diag_type d; + for( int i = 0; i < MIN(m, n); i++ ) + d.val[i] = val[i*n + i]; + return d; +} + + +template inline +const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); + return this->val[i*n + j]; +} + + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int i, int j) +{ + CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); + return val[i*n + j]; +} + + +template inline +const _Tp& Matx<_Tp, m, n>::operator ()(int i) const +{ + CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int i) +{ + CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + + +template static inline +Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + + +template static inline +Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) +{ + for( int i = 0; i < m*n; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); +} + + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) +{ + for( int i = 0; i < m*n; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); +} + + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) +{ + for( int i = 0; i < m*n; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * alpha); +} + + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) +{ + for( int i = 0; i < m*n; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); +} + + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + { + _Tp s = 0; + for( int k = 0; k < l; k++ ) + s += a(i, k) * b(k, j); + val[i*n + j] = s; + } +} + + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + val[i*n + j] = a(j, i); +} + + +template static inline +Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_AddOp()); +} + + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_SubOp()); +} + + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); +} + + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); +} + + +template static inline +Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) +{ + Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); + return reinterpret_cast&>(c); +} + + +template static inline +Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b) +{ + Matx<_Tp, 2, 1> tmp = a*Vec<_Tp,2>(b.x, b.y); + return Point_<_Tp>(tmp.val[0], tmp.val[1]); +} + + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b) +{ + Matx<_Tp, 3, 1> tmp = a*Vec<_Tp,3>(b.x, b.y, b.z); + return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]); +} + + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b) +{ + Matx<_Tp, 3, 1> tmp = a*Vec<_Tp,3>(b.x, b.y, 1); + return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]); +} + + +template static inline +Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b) +{ + return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1); +} + + +template static inline +Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b) +{ + Matx c(Matx(a), b, Matx_MatMulOp()); + return reinterpret_cast(c); +} + + +static inline +Scalar operator * (const Matx& a, const Scalar& b) +{ + Matx c(a, b, Matx_MatMulOp()); + return reinterpret_cast(c); +} + + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const +{ + return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); +} + + +CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); + + +template struct CV_EXPORTS Matx_DetOp +{ + double operator ()(const Matx<_Tp, m, m>& a) const + { + Matx<_Tp, m, m> temp = a; + double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); + if( p == 0 ) + return p; + for( int i = 0; i < m; i++ ) + p *= temp(i, i); + return 1./p; + } +}; + + +template struct CV_EXPORTS Matx_DetOp<_Tp, 1> +{ + double operator ()(const Matx<_Tp, 1, 1>& a) const + { + return a(0,0); + } +}; + + +template struct CV_EXPORTS Matx_DetOp<_Tp, 2> +{ + double operator ()(const Matx<_Tp, 2, 2>& a) const + { + return a(0,0)*a(1,1) - a(0,1)*a(1,0); + } +}; + + +template struct CV_EXPORTS Matx_DetOp<_Tp, 3> +{ + double operator ()(const Matx<_Tp, 3, 3>& a) const + { + return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - + a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + + a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); + } +}; + +template static inline +double determinant(const Matx<_Tp, m, m>& a) +{ + return Matx_DetOp<_Tp, m>()(a); +} + + +template static inline +double trace(const Matx<_Tp, m, n>& a) +{ + _Tp s = 0; + for( int i = 0; i < std::min(m, n); i++ ) + s += a(i,i); + return s; +} + + +template inline +Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const +{ + return Matx<_Tp, n, m>(*this, Matx_TOp()); +} + + +template struct CV_EXPORTS Matx_FastInvOp +{ + bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const + { + Matx<_Tp, m, m> temp = a; + + // assume that b is all 0's on input => make it a unity matrix + for( int i = 0; i < m; i++ ) + b(i, i) = (_Tp)1; + + if( method == DECOMP_CHOLESKY ) + return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m); + + return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0; + } +}; + + +template struct CV_EXPORTS Matx_FastInvOp<_Tp, 2> +{ + bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const + { + _Tp d = determinant(a); + if( d == 0 ) + return false; + d = 1/d; + b(1,1) = a(0,0)*d; + b(0,0) = a(1,1)*d; + b(0,1) = -a(0,1)*d; + b(1,0) = -a(1,0)*d; + return true; + } +}; + + +template struct CV_EXPORTS Matx_FastInvOp<_Tp, 3> +{ + bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const + { + _Tp d = (_Tp)determinant(a); + if( d == 0 ) + return false; + d = 1/d; + b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d; + b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d; + b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d; + + b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d; + b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d; + b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d; + + b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d; + b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d; + b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d; + return true; + } +}; + + +template inline +Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const +{ + Matx<_Tp, n, m> b; + bool ok; + if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) + ok = Matx_FastInvOp<_Tp, m>()(*this, b, method); + else + { + Mat A(*this, false), B(b, false); + ok = (invert(A, B, method) != 0); + } + return ok ? b : Matx<_Tp, n, m>::zeros(); +} + + +template struct CV_EXPORTS Matx_FastSolveOp +{ + bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b, + Matx<_Tp, m, n>& x, int method) const + { + Matx<_Tp, m, m> temp = a; + x = b; + if( method == DECOMP_CHOLESKY ) + return Cholesky(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n); + + return LU(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n) != 0; + } +}; + + +template struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1> +{ + bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b, + Matx<_Tp, 2, 1>& x, int) const + { + _Tp d = determinant(a); + if( d == 0 ) + return false; + d = 1/d; + x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d; + x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d; + return true; + } +}; + + +template struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1> +{ + bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b, + Matx<_Tp, 3, 1>& x, int) const + { + _Tp d = (_Tp)determinant(a); + if( d == 0 ) + return false; + d = 1/d; + x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) - + a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) + + a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2))); + + x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) - + b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) + + a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0))); + + x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) - + a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) + + b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0))); + return true; + } +}; + + +template template inline +Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const +{ + Matx<_Tp, n, l> x; + bool ok; + if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) + ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method); + else + { + Mat A(*this, false), B(rhs, false), X(x, false); + ok = cv::solve(A, B, X, method); + } + + return ok ? x : Matx<_Tp, n, l>::zeros(); +} + +template inline +Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const +{ + Matx<_Tp, n, 1> x = solve(reinterpret_cast&>(rhs), method); + return reinterpret_cast&>(x); +} + +template static inline +_AccTp normL2Sqr(const _Tp* a, int n) +{ + _AccTp s = 0; + int i=0; + #if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + { + _AccTp v0 = a[i], v1 = a[i+1], v2 = a[i+2], v3 = a[i+3]; + s += v0*v0 + v1*v1 + v2*v2 + v3*v3; + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = a[i]; + s += v*v; + } + return s; +} + + +template static inline +_AccTp normL1(const _Tp* a, int n) +{ + _AccTp s = 0; + int i = 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + s += (_AccTp)fast_abs(a[i]) + (_AccTp)fast_abs(a[i+1]) + + (_AccTp)fast_abs(a[i+2]) + (_AccTp)fast_abs(a[i+3]); + } +#endif + for( ; i < n; i++ ) + s += fast_abs(a[i]); + return s; +} + + +template static inline +_AccTp normInf(const _Tp* a, int n) +{ + _AccTp s = 0; + for( int i = 0; i < n; i++ ) + s = std::max(s, (_AccTp)fast_abs(a[i])); + return s; +} + + +template static inline +_AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + int i= 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]); + s += v0*v0 + v1*v1 + v2*v2 + v3*v3; + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = _AccTp(a[i] - b[i]); + s += v*v; + } + return s; +} + +CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n); +CV_EXPORTS float normL1_(const float* a, const float* b, int n); +CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n); +CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n); +CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize); + +template<> inline float normL2Sqr(const float* a, const float* b, int n) +{ + if( n >= 8 ) + return normL2Sqr_(a, b, n); + float s = 0; + for( int i = 0; i < n; i++ ) + { + float v = a[i] - b[i]; + s += v*v; + } + return s; +} + + +template static inline +_AccTp normL1(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + int i= 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]); + s += std::abs(v0) + std::abs(v1) + std::abs(v2) + std::abs(v3); + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = _AccTp(a[i] - b[i]); + s += std::abs(v); + } + return s; +} + +template<> inline float normL1(const float* a, const float* b, int n) +{ + if( n >= 8 ) + return normL1_(a, b, n); + float s = 0; + for( int i = 0; i < n; i++ ) + { + float v = a[i] - b[i]; + s += std::abs(v); + } + return s; +} + +template<> inline int normL1(const uchar* a, const uchar* b, int n) +{ + return normL1_(a, b, n); +} + +template static inline +_AccTp normInf(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + for( int i = 0; i < n; i++ ) + { + _AccTp v0 = a[i] - b[i]; + s = std::max(s, std::abs(v0)); + } + return s; +} + + +template static inline +double norm(const Matx<_Tp, m, n>& M) +{ + return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); +} + + +template static inline +double norm(const Matx<_Tp, m, n>& M, int normType) +{ + return normType == NORM_INF ? (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n) : + normType == NORM_L1 ? (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n) : + std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); +} + + +template static inline +bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + if( a.val[i] != b.val[i] ) return false; + return true; +} + +template static inline +bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return !(a == b); +} + + +template static inline +MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) +{ + MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); + return (commaInitializer, val); +} + +template inline +MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) + : dst(_mtx), idx(0) +{} + +template template inline +MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) +{ + CV_DbgAssert( idx < m*n ); + dst->val[idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const +{ + CV_DbgAssert( idx == n*m ); + return *dst; +} + +/////////////////////////// short vector (Vec) ///////////////////////////// + +template inline Vec<_Tp, cn>::Vec() +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0) + : Matx<_Tp, cn, 1>(v0) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) + : Matx<_Tp, cn, 1>(v0, v1) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) + : Matx<_Tp, cn, 1>(v0, v1, v2) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) +{} + +template inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) +{} + +template inline Vec<_Tp, cn>::Vec(const _Tp* values) + : Matx<_Tp, cn, 1>(values) +{} + + +template inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) + : Matx<_Tp, cn, 1>(m.val) +{} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) +: Matx<_Tp, cn, 1>(a, b, op) +{} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) +: Matx<_Tp, cn, 1>(a, b, op) +{} + +template template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) +: Matx<_Tp, cn, 1>(a, alpha, op) +{} + +template inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = alpha; + return v; +} + +template inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const +{ + Vec<_Tp, cn> w; + for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); + return w; +} + +template Vec<_Tp, 2> conjugate(const Vec<_Tp, 2>& v) +{ + return Vec<_Tp, 2>(v[0], -v[1]); +} + +template Vec<_Tp, 4> conjugate(const Vec<_Tp, 4>& v) +{ + return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); +} + +template<> inline Vec Vec::conj() const +{ + return conjugate(*this); +} + +template<> inline Vec Vec::conj() const +{ + return conjugate(*this); +} + +template<> inline Vec Vec::conj() const +{ + return conjugate(*this); +} + +template<> inline Vec Vec::conj() const +{ + return conjugate(*this); +} + +template inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const +{ + CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined"); + return Vec<_Tp, cn>(); +} + +template template +inline Vec<_Tp, cn>::operator Vec() const +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast(this->val[i]); + return v; +} + +template inline Vec<_Tp, cn>::operator CvScalar() const +{ + CvScalar s = {{0,0,0,0}}; + int i; + for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = this->val[i]; + for( ; i < 4; i++ ) s.val[i] = 0; + return s; +} + +template inline const _Tp& Vec<_Tp, cn>::operator [](int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline _Tp& Vec<_Tp, cn>::operator [](int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline _Tp& Vec<_Tp, cn>::operator ()(int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template static inline Vec<_Tp1, cn>& +operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + +template static inline Vec<_Tp1, cn>& +operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + +template static inline Vec<_Tp, cn> +operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_AddOp()); +} + +template static inline Vec<_Tp, cn> +operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_SubOp()); +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) +{ + float ialpha = 1.f/alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline Vec<_Tp, cn> +operator * (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator * (int alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator * (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator * (float alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator * (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator * (double alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator / (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator / (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator / (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline Vec<_Tp, cn> +operator - (const Vec<_Tp, cn>& a) +{ + Vec<_Tp,cn> t; + for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); + return t; +} + +template inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), + saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), + saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), + saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); +} + +template inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + v1 = v1 * v2; + return v1; +} + +template<> inline Vec Vec::cross(const Vec& v) const +{ + return Vec(val[1]*v.val[2] - val[2]*v.val[1], + val[2]*v.val[0] - val[0]*v.val[2], + val[0]*v.val[1] - val[1]*v.val[0]); +} + +template<> inline Vec Vec::cross(const Vec& v) const +{ + return Vec(val[1]*v.val[2] - val[2]*v.val[1], + val[2]*v.val[0] - val[0]*v.val[2], + val[0]*v.val[1] - val[1]*v.val[0]); +} + +template inline Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) +{ + double nv = norm(v); + return v * (nv ? 1./nv : 0.); +} + +template static inline +VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) +{ + VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); + return (commaInitializer, val); +} + +template inline +VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) + : MatxCommaInitializer<_Tp, cn, 1>(_vec) +{} + +template template inline +VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) +{ + CV_DbgAssert( this->idx < cn ); + this->dst->val[this->idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const +{ + CV_DbgAssert( this->idx == cn ); + return *this->dst; +} + +//////////////////////////////// Complex ////////////////////////////// + +template inline Complex<_Tp>::Complex() : re(0), im(0) {} +template inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {} +template template inline Complex<_Tp>::operator Complex() const +{ return Complex(saturate_cast(re), saturate_cast(im)); } +template inline Complex<_Tp> Complex<_Tp>::conj() const +{ return Complex<_Tp>(re, -im); } + +template static inline +bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ return a.re == b.re && a.im == b.im; } + +template static inline +bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ return a.re != b.re || a.im != b.im; } + +template static inline +Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ return Complex<_Tp>( a.re + b.re, a.im + b.im ); } + +template static inline +Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b) +{ a.re += b.re; a.im += b.im; return a; } + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ return Complex<_Tp>( a.re - b.re, a.im - b.im ); } + +template static inline +Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b) +{ a.re -= b.re; a.im -= b.im; return a; } + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a) +{ return Complex<_Tp>(-a.re, -a.im); } + +template static inline +Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); } + +template static inline +Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b) +{ return Complex<_Tp>( a.re*b, a.im*b ); } + +template static inline +Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a) +{ return Complex<_Tp>( a.re*b, a.im*b ); } + +template static inline +Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b) +{ return Complex<_Tp>( a.re + b, a.im ); } + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b) +{ return Complex<_Tp>( a.re - b, a.im ); } + +template static inline +Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a) +{ return Complex<_Tp>( a.re + b, a.im ); } + +template static inline +Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a) +{ return Complex<_Tp>( b - a.re, -a.im ); } + +template static inline +Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b) +{ a.re += b; return a; } + +template static inline +Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b) +{ a.re -= b; return a; } + +template static inline +Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b) +{ a.re *= b; a.im *= b; return a; } + +template static inline +double abs(const Complex<_Tp>& a) +{ return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); } + +template static inline +Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + double t = 1./((double)b.re*b.re + (double)b.im*b.im); + return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t), + (_Tp)((-a.re*b.im + a.im*b.re)*t) ); +} + +template static inline +Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return (a = a / b); +} + +template static inline +Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b) +{ + _Tp t = (_Tp)1/b; + return Complex<_Tp>( a.re*t, a.im*t ); +} + +template static inline +Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a) +{ + return Complex<_Tp>(b)/a; +} + +template static inline +Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b) +{ + _Tp t = (_Tp)1/b; + a.re *= t; a.im *= t; return a; +} + +//////////////////////////////// 2D Point //////////////////////////////// + +template inline Point_<_Tp>::Point_() : x(0), y(0) {} +template inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {} +template inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {} +template inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {} +template inline Point_<_Tp>::Point_(const CvPoint2D32f& pt) + : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {} +template inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {} +template inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {} +template inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt) +{ x = pt.x; y = pt.y; return *this; } + +template template inline Point_<_Tp>::operator Point_<_Tp2>() const +{ return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); } +template inline Point_<_Tp>::operator CvPoint() const +{ return cvPoint(saturate_cast(x), saturate_cast(y)); } +template inline Point_<_Tp>::operator CvPoint2D32f() const +{ return cvPoint2D32f((float)x, (float)y); } +template inline Point_<_Tp>::operator Vec<_Tp, 2>() const +{ return Vec<_Tp, 2>(x, y); } + +template inline _Tp Point_<_Tp>::dot(const Point_& pt) const +{ return saturate_cast<_Tp>(x*pt.x + y*pt.y); } +template inline double Point_<_Tp>::ddot(const Point_& pt) const +{ return (double)x*pt.x + (double)y*pt.y; } + +template inline double Point_<_Tp>::cross(const Point_& pt) const +{ return (double)x*pt.y - (double)y*pt.x; } + +template static inline Point_<_Tp>& +operator += (Point_<_Tp>& a, const Point_<_Tp>& b) +{ + a.x = saturate_cast<_Tp>(a.x + b.x); + a.y = saturate_cast<_Tp>(a.y + b.y); + return a; +} + +template static inline Point_<_Tp>& +operator -= (Point_<_Tp>& a, const Point_<_Tp>& b) +{ + a.x = saturate_cast<_Tp>(a.x - b.x); + a.y = saturate_cast<_Tp>(a.y - b.y); + return a; +} + +template static inline Point_<_Tp>& +operator *= (Point_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + return a; +} + +template static inline Point_<_Tp>& +operator *= (Point_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + return a; +} + +template static inline Point_<_Tp>& +operator *= (Point_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + return a; +} + +template static inline double norm(const Point_<_Tp>& pt) +{ return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); } + +template static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ return a.x == b.x && a.y == b.y; } + +template static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ return a.x != b.x || a.y != b.y; } + +template static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); } + +template static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); } + +template static inline Point_<_Tp> operator - (const Point_<_Tp>& a) +{ return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); } + +template static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b) +{ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } + +template static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b) +{ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } + +template static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b) +{ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } + +template static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b) +{ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } + +template static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b) +{ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } + +template static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b) +{ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } + +//////////////////////////////// 3D Point //////////////////////////////// + +template inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {} +template inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {} +template inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {} +template inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {} +template inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) : + x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {} +template inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {} + +template template inline Point3_<_Tp>::operator Point3_<_Tp2>() const +{ return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); } + +template inline Point3_<_Tp>::operator CvPoint3D32f() const +{ return cvPoint3D32f((float)x, (float)y, (float)z); } + +template inline Point3_<_Tp>::operator Vec<_Tp, 3>() const +{ return Vec<_Tp, 3>(x, y, z); } + +template inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt) +{ x = pt.x; y = pt.y; z = pt.z; return *this; } + +template inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const +{ return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); } +template inline double Point3_<_Tp>::ddot(const Point3_& pt) const +{ return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; } + +template inline Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const +{ + return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x); +} + +template static inline Point3_<_Tp>& +operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + a.x = saturate_cast<_Tp>(a.x + b.x); + a.y = saturate_cast<_Tp>(a.y + b.y); + a.z = saturate_cast<_Tp>(a.z + b.z); + return a; +} + +template static inline Point3_<_Tp>& +operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + a.x = saturate_cast<_Tp>(a.x - b.x); + a.y = saturate_cast<_Tp>(a.y - b.y); + a.z = saturate_cast<_Tp>(a.z - b.z); + return a; +} + +template static inline Point3_<_Tp>& +operator *= (Point3_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + a.z = saturate_cast<_Tp>(a.z*b); + return a; +} + +template static inline Point3_<_Tp>& +operator *= (Point3_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + a.z = saturate_cast<_Tp>(a.z*b); + return a; +} + +template static inline Point3_<_Tp>& +operator *= (Point3_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x*b); + a.y = saturate_cast<_Tp>(a.y*b); + a.z = saturate_cast<_Tp>(a.z*b); + return a; +} + +template static inline double norm(const Point3_<_Tp>& pt) +{ return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); } + +template static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ return a.x == b.x && a.y == b.y && a.z == b.z; } + +template static inline bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ return a.x != b.x || a.y != b.y || a.z != b.z; } + +template static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), + saturate_cast<_Tp>(a.y + b.y), + saturate_cast<_Tp>(a.z + b.z)); } + +template static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), + saturate_cast<_Tp>(a.y - b.y), + saturate_cast<_Tp>(a.z - b.z)); } + +template static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a) +{ return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), + saturate_cast<_Tp>(-a.y), + saturate_cast<_Tp>(-a.z) ); } + +template static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), + saturate_cast<_Tp>(a.y*b), + saturate_cast<_Tp>(a.z*b) ); } + +template static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), + saturate_cast<_Tp>(b.y*a), + saturate_cast<_Tp>(b.z*a) ); } + +template static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), + saturate_cast<_Tp>(a.y*b), + saturate_cast<_Tp>(a.z*b) ); } + +template static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), + saturate_cast<_Tp>(b.y*a), + saturate_cast<_Tp>(b.z*a) ); } + +template static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), + saturate_cast<_Tp>(a.y*b), + saturate_cast<_Tp>(a.z*b) ); } + +template static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b) +{ return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), + saturate_cast<_Tp>(b.y*a), + saturate_cast<_Tp>(b.z*a) ); } + +//////////////////////////////// Size //////////////////////////////// + +template inline Size_<_Tp>::Size_() + : width(0), height(0) {} +template inline Size_<_Tp>::Size_(_Tp _width, _Tp _height) + : width(_width), height(_height) {} +template inline Size_<_Tp>::Size_(const Size_& sz) + : width(sz.width), height(sz.height) {} +template inline Size_<_Tp>::Size_(const CvSize& sz) + : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {} +template inline Size_<_Tp>::Size_(const CvSize2D32f& sz) + : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {} +template inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {} + +template template inline Size_<_Tp>::operator Size_<_Tp2>() const +{ return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); } +template inline Size_<_Tp>::operator CvSize() const +{ return cvSize(saturate_cast(width), saturate_cast(height)); } +template inline Size_<_Tp>::operator CvSize2D32f() const +{ return cvSize2D32f((float)width, (float)height); } + +template inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz) +{ width = sz.width; height = sz.height; return *this; } +template static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b) +{ return Size_<_Tp>(a.width * b, a.height * b); } +template static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ return Size_<_Tp>(a.width + b.width, a.height + b.height); } +template static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ return Size_<_Tp>(a.width - b.width, a.height - b.height); } +template inline _Tp Size_<_Tp>::area() const { return width*height; } + +template static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b) +{ a.width += b.width; a.height += b.height; return a; } +template static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b) +{ a.width -= b.width; a.height -= b.height; return a; } + +template static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ return a.width == b.width && a.height == b.height; } +template static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ return a.width != b.width || a.height != b.height; } + +//////////////////////////////// Rect //////////////////////////////// + + +template inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {} +template inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {} +template inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {} +template inline Rect_<_Tp>::Rect_(const CvRect& r) : x((_Tp)r.x), y((_Tp)r.y), width((_Tp)r.width), height((_Tp)r.height) {} +template inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) : + x(org.x), y(org.y), width(sz.width), height(sz.height) {} +template inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2) +{ + x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y); + width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y; +} +template inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r ) +{ x = r.x; y = r.y; width = r.width; height = r.height; return *this; } + +template inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); } +template inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); } + +template static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b ) +{ a.x += b.x; a.y += b.y; return a; } +template static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b ) +{ a.x -= b.x; a.y -= b.y; return a; } + +template static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b ) +{ a.width += b.width; a.height += b.height; return a; } + +template static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b ) +{ a.width -= b.width; a.height -= b.height; return a; } + +template static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y); + a.width = std::min(a.x + a.width, b.x + b.width) - x1; + a.height = std::min(a.y + a.height, b.y + b.height) - y1; + a.x = x1; a.y = y1; + if( a.width <= 0 || a.height <= 0 ) + a = Rect(); + return a; +} + +template static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y); + a.width = std::max(a.x + a.width, b.x + b.width) - x1; + a.height = std::max(a.y + a.height, b.y + b.height) - y1; + a.x = x1; a.y = y1; + return a; +} + +template inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); } +template inline _Tp Rect_<_Tp>::area() const { return width*height; } + +template template inline Rect_<_Tp>::operator Rect_<_Tp2>() const +{ return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), + saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); } +template inline Rect_<_Tp>::operator CvRect() const +{ return cvRect(saturate_cast(x), saturate_cast(y), + saturate_cast(width), saturate_cast(height)); } + +template inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const +{ return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; } + +template static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +} + +template static inline bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height; +} + +template static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b) +{ + return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height ); +} + +template static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b) +{ + return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height ); +} + +template static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b) +{ + return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height ); +} + +template static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c &= b; +} + +template static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c |= b; +} + +template inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const +{ + return r.contains(*this); +} + +inline RotatedRect::RotatedRect() { angle = 0; } +inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle) + : center(_center), size(_size), angle(_angle) {} +inline RotatedRect::RotatedRect(const CvBox2D& box) + : center(box.center), size(box.size), angle(box.angle) {} +inline RotatedRect::operator CvBox2D() const +{ + CvBox2D box; box.center = center; box.size = size; box.angle = angle; + return box; +} + +//////////////////////////////// Scalar_ /////////////////////////////// + +template inline Scalar_<_Tp>::Scalar_() +{ this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; } + +template inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3) +{ this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; } + +template inline Scalar_<_Tp>::Scalar_(const CvScalar& s) +{ + this->val[0] = saturate_cast<_Tp>(s.val[0]); + this->val[1] = saturate_cast<_Tp>(s.val[1]); + this->val[2] = saturate_cast<_Tp>(s.val[2]); + this->val[3] = saturate_cast<_Tp>(s.val[3]); +} + +template inline Scalar_<_Tp>::Scalar_(_Tp v0) +{ this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; } + +template inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0) +{ return Scalar_<_Tp>(v0, v0, v0, v0); } +template inline Scalar_<_Tp>::operator CvScalar() const +{ return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); } + +template template inline Scalar_<_Tp>::operator Scalar_() const +{ + return Scalar_(saturate_cast(this->val[0]), + saturate_cast(this->val[1]), + saturate_cast(this->val[2]), + saturate_cast(this->val[3])); +} + +template static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]); + a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]); + a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]); + a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]); + return a; +} + +template static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]); + a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]); + a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]); + a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]); + return a; +} + +template static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v ) +{ + a.val[0] = saturate_cast<_Tp>(a.val[0] * v); + a.val[1] = saturate_cast<_Tp>(a.val[1] * v); + a.val[2] = saturate_cast<_Tp>(a.val[2] * v); + a.val[3] = saturate_cast<_Tp>(a.val[3] * v); + return a; +} + +template inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const +{ + return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale), + saturate_cast<_Tp>(this->val[1]*t.val[1]*scale), + saturate_cast<_Tp>(this->val[2]*t.val[2]*scale), + saturate_cast<_Tp>(this->val[3]*t.val[3]*scale)); +} + +template static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) +{ + return a.val[0] == b.val[0] && a.val[1] == b.val[1] && + a.val[2] == b.val[2] && a.val[3] == b.val[3]; +} + +template static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) +{ + return a.val[0] != b.val[0] || a.val[1] != b.val[1] || + a.val[2] != b.val[2] || a.val[3] != b.val[3]; +} + +template static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]), + saturate_cast<_Tp>(a.val[1] + b.val[1]), + saturate_cast<_Tp>(a.val[2] + b.val[2]), + saturate_cast<_Tp>(a.val[3] + b.val[3])); +} + +template static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]), + saturate_cast<_Tp>(a.val[1] - b.val[1]), + saturate_cast<_Tp>(a.val[2] - b.val[2]), + saturate_cast<_Tp>(a.val[3] - b.val[3])); +} + +template static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha), + saturate_cast<_Tp>(a.val[1] * alpha), + saturate_cast<_Tp>(a.val[2] * alpha), + saturate_cast<_Tp>(a.val[3] * alpha)); +} + +template static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a) +{ + return a*alpha; +} + +template static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]), + saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3])); +} + + +template static inline Scalar_<_Tp> +operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]), + saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]), + saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]), + saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0])); +} + +template static inline Scalar_<_Tp>& +operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a*b; + return a; +} + +template inline Scalar_<_Tp> Scalar_<_Tp>::conj() const +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0]), + saturate_cast<_Tp>(-this->val[1]), + saturate_cast<_Tp>(-this->val[2]), + saturate_cast<_Tp>(-this->val[3])); +} + +template inline bool Scalar_<_Tp>::isReal() const +{ + return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0; +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] / alpha), + saturate_cast<_Tp>(a.val[1] / alpha), + saturate_cast<_Tp>(a.val[2] / alpha), + saturate_cast<_Tp>(a.val[3] / alpha)); +} + +template static inline +Scalar_ operator / (const Scalar_& a, float alpha) +{ + float s = 1/alpha; + return Scalar_(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s); +} + +template static inline +Scalar_ operator / (const Scalar_& a, double alpha) +{ + double s = 1/alpha; + return Scalar_(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha) +{ + a = a/alpha; + return a; +} + +template static inline +Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b) +{ + _Tp s = a/(b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]); + return b.conj()*s; +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return a*((_Tp)1/b); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a/b; + return a; +} + +//////////////////////////////// Range ///////////////////////////////// + +inline Range::Range() : start(0), end(0) {} +inline Range::Range(int _start, int _end) : start(_start), end(_end) {} +inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index) +{ + if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX ) + *this = Range::all(); +} + +inline int Range::size() const { return end - start; } +inline bool Range::empty() const { return start == end; } +inline Range Range::all() { return Range(INT_MIN, INT_MAX); } + +static inline bool operator == (const Range& r1, const Range& r2) +{ return r1.start == r2.start && r1.end == r2.end; } + +static inline bool operator != (const Range& r1, const Range& r2) +{ return !(r1 == r2); } + +static inline bool operator !(const Range& r) +{ return r.start == r.end; } + +static inline Range operator & (const Range& r1, const Range& r2) +{ + Range r(std::max(r1.start, r2.start), std::min(r1.end, r2.end)); + r.end = std::max(r.end, r.start); + return r; +} + +static inline Range& operator &= (Range& r1, const Range& r2) +{ + r1 = r1 & r2; + return r1; +} + +static inline Range operator + (const Range& r1, int delta) +{ + return Range(r1.start + delta, r1.end + delta); +} + +static inline Range operator + (int delta, const Range& r1) +{ + return Range(r1.start + delta, r1.end + delta); +} + +static inline Range operator - (const Range& r1, int delta) +{ + return r1 + (-delta); +} + +inline Range::operator CvSlice() const +{ return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; } + + + +//////////////////////////////// Vector //////////////////////////////// + +// template vector class. It is similar to STL's vector, +// with a few important differences: +// 1) it can be created on top of user-allocated data w/o copying it +// 2) vector b = a means copying the header, +// not the underlying data (use clone() to make a deep copy) +template class CV_EXPORTS Vector +{ +public: + typedef _Tp value_type; + typedef _Tp* iterator; + typedef const _Tp* const_iterator; + typedef _Tp& reference; + typedef const _Tp& const_reference; + + struct CV_EXPORTS Hdr + { + Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {}; + _Tp* data; + _Tp* datastart; + int* refcount; + size_t size; + size_t capacity; + }; + + Vector() {} + Vector(size_t _size) { resize(_size); } + Vector(size_t _size, const _Tp& val) + { + resize(_size); + for(size_t i = 0; i < _size; i++) + hdr.data[i] = val; + } + Vector(_Tp* _data, size_t _size, bool _copyData=false) + { set(_data, _size, _copyData); } + + template Vector(const Vec<_Tp, n>& vec) + { set((_Tp*)&vec.val[0], n, true); } + + Vector(const std::vector<_Tp>& vec, bool _copyData=false) + { set(!vec.empty() ? (_Tp*)&vec[0] : 0, vec.size(), _copyData); } + + Vector(const Vector& d) { *this = d; } + + Vector(const Vector& d, const Range& r_) + { + Range r = r_ == Range::all() ? Range(0, d.size()) : r_; + /*if( r == Range::all() ) + r = Range(0, d.size());*/ + if( r.size() > 0 && r.start >= 0 && r.end <= d.size() ) + { + if( d.hdr.refcount ) + CV_XADD(d.hdr.refcount, 1); + hdr.refcount = d.hdr.refcount; + hdr.datastart = d.hdr.datastart; + hdr.data = d.hdr.data + r.start; + hdr.capacity = hdr.size = r.size(); + } + } + + Vector<_Tp>& operator = (const Vector& d) + { + if( this != &d ) + { + if( d.hdr.refcount ) + CV_XADD(d.hdr.refcount, 1); + release(); + hdr = d.hdr; + } + return *this; + } + + ~Vector() { release(); } + + Vector<_Tp> clone() const + { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); } + + void copyTo(Vector<_Tp>& vec) const + { + size_t i, sz = size(); + vec.resize(sz); + const _Tp* src = hdr.data; + _Tp* dst = vec.hdr.data; + for( i = 0; i < sz; i++ ) + dst[i] = src[i]; + } + + void copyTo(std::vector<_Tp>& vec) const + { + size_t i, sz = size(); + vec.resize(sz); + const _Tp* src = hdr.data; + _Tp* dst = sz ? &vec[0] : 0; + for( i = 0; i < sz; i++ ) + dst[i] = src[i]; + } + + operator CvMat() const + { return cvMat((int)size(), 1, type(), (void*)hdr.data); } + + _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; } + const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; } + Vector operator() (const Range& r) const { return Vector(*this, r); } + _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; } + const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; } + _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; } + const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; } + + _Tp* begin() { return hdr.data; } + _Tp* end() { return hdr.data + hdr.size; } + const _Tp* begin() const { return hdr.data; } + const _Tp* end() const { return hdr.data + hdr.size; } + + void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); } + void release() + { + if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 ) + { + delete[] hdr.datastart; + delete hdr.refcount; + } + hdr = Hdr(); + } + + void set(_Tp* _data, size_t _size, bool _copyData=false) + { + if( !_copyData ) + { + release(); + hdr.data = hdr.datastart = _data; + hdr.size = hdr.capacity = _size; + hdr.refcount = 0; + } + else + { + reserve(_size); + for( size_t i = 0; i < _size; i++ ) + hdr.data[i] = _data[i]; + hdr.size = _size; + } + } + + void reserve(size_t newCapacity) + { + _Tp* newData; + int* newRefcount; + size_t i, oldSize = hdr.size; + if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity ) + return; + newCapacity = std::max(newCapacity, oldSize); + newData = new _Tp[newCapacity]; + newRefcount = new int(1); + for( i = 0; i < oldSize; i++ ) + newData[i] = hdr.data[i]; + release(); + hdr.data = hdr.datastart = newData; + hdr.capacity = newCapacity; + hdr.size = oldSize; + hdr.refcount = newRefcount; + } + + void resize(size_t newSize) + { + size_t i; + newSize = std::max(newSize, (size_t)0); + if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize ) + return; + if( newSize > hdr.capacity ) + reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2))); + for( i = hdr.size; i < newSize; i++ ) + hdr.data[i] = _Tp(); + hdr.size = newSize; + } + + Vector<_Tp>& push_back(const _Tp& elem) + { + if( hdr.size == hdr.capacity ) + reserve( std::max((size_t)4, hdr.capacity*2) ); + hdr.data[hdr.size++] = elem; + return *this; + } + + Vector<_Tp>& pop_back() + { + if( hdr.size > 0 ) + --hdr.size; + return *this; + } + + size_t size() const { return hdr.size; } + size_t capacity() const { return hdr.capacity; } + bool empty() const { return hdr.size == 0; } + void clear() { resize(0); } + int type() const { return DataType<_Tp>::type; } + +protected: + Hdr hdr; +}; + + +template inline typename DataType<_Tp>::work_type +dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2) +{ + typedef typename DataType<_Tp>::work_type _Tw; + size_t i = 0, n = v1.size(); + assert(v1.size() == v2.size()); + + _Tw s = 0; + const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0]; + for( ; i < n; i++ ) + s += (_Tw)ptr1[i]*ptr2[i]; + + return s; +} + +// Multiply-with-Carry RNG +inline RNG::RNG() { state = 0xffffffff; } +inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; } +inline unsigned RNG::next() +{ + state = (uint64)(unsigned)state*CV_RNG_COEFF + (unsigned)(state >> 32); + return (unsigned)state; +} + +inline RNG::operator uchar() { return (uchar)next(); } +inline RNG::operator schar() { return (schar)next(); } +inline RNG::operator ushort() { return (ushort)next(); } +inline RNG::operator short() { return (short)next(); } +inline RNG::operator unsigned() { return next(); } +inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);} +inline unsigned RNG::operator ()() {return next();} +inline RNG::operator int() { return (int)next(); } +// * (2^32-1)^-1 +inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; } +inline RNG::operator double() +{ + unsigned t = next(); + return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20; +} +inline int RNG::uniform(int a, int b) { return a == b ? a : (int)(next()%(b - a) + a); } +inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; } +inline double RNG::uniform(double a, double b) { return ((double)*this)*(b - a) + a; } + +inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {} +inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon) + : type(_type), maxCount(_maxCount), epsilon(_epsilon) {} +inline TermCriteria::TermCriteria(const CvTermCriteria& criteria) + : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {} +inline TermCriteria::operator CvTermCriteria() const +{ return cvTermCriteria(type, maxCount, epsilon); } + +inline uchar* LineIterator::operator *() { return ptr; } +inline LineIterator& LineIterator::operator ++() +{ + int mask = err < 0 ? -1 : 0; + err += minusDelta + (plusDelta & mask); + ptr += minusStep + (plusStep & mask); + return *this; +} +inline LineIterator LineIterator::operator ++(int) +{ + LineIterator it = *this; + ++(*this); + return it; +} +inline Point LineIterator::pos() const +{ + Point p; + p.y = (int)((ptr - ptr0)/step); + p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize); + return p; +} + +/////////////////////////////// AutoBuffer //////////////////////////////////////// + +template inline AutoBuffer<_Tp, fixed_size>::AutoBuffer() +{ + ptr = buf; + size = fixed_size; +} + +template inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size) +{ + ptr = buf; + size = fixed_size; + allocate(_size); +} + +template inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer() +{ deallocate(); } + +template inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size) +{ + if(_size <= size) + return; + deallocate(); + if(_size > fixed_size) + { + ptr = cv::allocate<_Tp>(_size); + size = _size; + } +} + +template inline void AutoBuffer<_Tp, fixed_size>::deallocate() +{ + if( ptr != buf ) + { + cv::deallocate<_Tp>(ptr, size); + ptr = buf; + size = fixed_size; + } +} + +template inline AutoBuffer<_Tp, fixed_size>::operator _Tp* () +{ return ptr; } + +template inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const +{ return ptr; } + + +/////////////////////////////////// Ptr //////////////////////////////////////// + +template inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {} +template inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj) +{ + if(obj) + { + refcount = (int*)fastMalloc(sizeof(*refcount)); + *refcount = 1; + } + else + refcount = 0; +} + +template inline void Ptr<_Tp>::addref() +{ if( refcount ) CV_XADD(refcount, 1); } + +template inline void Ptr<_Tp>::release() +{ + if( refcount && CV_XADD(refcount, -1) == 1 ) + { + delete_obj(); + fastFree(refcount); + } + refcount = 0; + obj = 0; +} + +template inline void Ptr<_Tp>::delete_obj() +{ + if( obj ) delete obj; +} + +template inline Ptr<_Tp>::~Ptr() { release(); } + +template inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& _ptr) +{ + obj = _ptr.obj; + refcount = _ptr.refcount; + addref(); +} + +template inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& _ptr) +{ + int* _refcount = _ptr.refcount; + if( _refcount ) + CV_XADD(_refcount, 1); + release(); + obj = _ptr.obj; + refcount = _refcount; + return *this; +} + +template inline _Tp* Ptr<_Tp>::operator -> () { return obj; } +template inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; } + +template inline Ptr<_Tp>::operator _Tp* () { return obj; } +template inline Ptr<_Tp>::operator const _Tp*() const { return obj; } + +template inline bool Ptr<_Tp>::empty() const { return obj == 0; } + +template template Ptr<_Tp>::Ptr(const Ptr<_Tp2>& p) + : obj(0), refcount(0) +{ + if (p.empty()) + return; + + _Tp* p_casted = dynamic_cast<_Tp*>(p.obj); + if (!p_casted) + return; + + obj = p_casted; + refcount = p.refcount; + addref(); +} + +template template inline Ptr<_Tp2> Ptr<_Tp>::ptr() +{ + Ptr<_Tp2> p; + if( !obj ) + return p; + + _Tp2* obj_casted = dynamic_cast<_Tp2*>(obj); + if (!obj_casted) + return p; + + if( refcount ) + CV_XADD(refcount, 1); + + p.obj = obj_casted; + p.refcount = refcount; + return p; +} + +template template inline const Ptr<_Tp2> Ptr<_Tp>::ptr() const +{ + Ptr<_Tp2> p; + if( !obj ) + return p; + + _Tp2* obj_casted = dynamic_cast<_Tp2*>(obj); + if (!obj_casted) + return p; + + if( refcount ) + CV_XADD(refcount, 1); + + p.obj = obj_casted; + p.refcount = refcount; + return p; +} + +//// specializied implementations of Ptr::delete_obj() for classic OpenCV types + +template<> CV_EXPORTS void Ptr::delete_obj(); +template<> CV_EXPORTS void Ptr::delete_obj(); +template<> CV_EXPORTS void Ptr::delete_obj(); +template<> CV_EXPORTS void Ptr::delete_obj(); +template<> CV_EXPORTS void Ptr::delete_obj(); +template<> CV_EXPORTS void Ptr::delete_obj(); + +//////////////////////////////////////// XML & YAML I/O //////////////////////////////////// + +CV_EXPORTS_W void write( FileStorage& fs, const string& name, int value ); +CV_EXPORTS_W void write( FileStorage& fs, const string& name, float value ); +CV_EXPORTS_W void write( FileStorage& fs, const string& name, double value ); +CV_EXPORTS_W void write( FileStorage& fs, const string& name, const string& value ); + +template inline void write(FileStorage& fs, const _Tp& value) +{ write(fs, string(), value); } + +CV_EXPORTS void writeScalar( FileStorage& fs, int value ); +CV_EXPORTS void writeScalar( FileStorage& fs, float value ); +CV_EXPORTS void writeScalar( FileStorage& fs, double value ); +CV_EXPORTS void writeScalar( FileStorage& fs, const string& value ); + +template<> inline void write( FileStorage& fs, const int& value ) +{ + writeScalar(fs, value); +} + +template<> inline void write( FileStorage& fs, const float& value ) +{ + writeScalar(fs, value); +} + +template<> inline void write( FileStorage& fs, const double& value ) +{ + writeScalar(fs, value); +} + +template<> inline void write( FileStorage& fs, const string& value ) +{ + writeScalar(fs, value); +} + +template inline void write(FileStorage& fs, const Point_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); +} + +template inline void write(FileStorage& fs, const Point3_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); + write(fs, pt.z); +} + +template inline void write(FileStorage& fs, const Size_<_Tp>& sz ) +{ + write(fs, sz.width); + write(fs, sz.height); +} + +template inline void write(FileStorage& fs, const Complex<_Tp>& c ) +{ + write(fs, c.re); + write(fs, c.im); +} + +template inline void write(FileStorage& fs, const Rect_<_Tp>& r ) +{ + write(fs, r.x); + write(fs, r.y); + write(fs, r.width); + write(fs, r.height); +} + +template inline void write(FileStorage& fs, const Vec<_Tp, cn>& v ) +{ + for(int i = 0; i < cn; i++) + write(fs, v.val[i]); +} + +template inline void write(FileStorage& fs, const Scalar_<_Tp>& s ) +{ + write(fs, s.val[0]); + write(fs, s.val[1]); + write(fs, s.val[2]); + write(fs, s.val[3]); +} + +inline void write(FileStorage& fs, const Range& r ) +{ + write(fs, r.start); + write(fs, r.end); +} + +class CV_EXPORTS WriteStructContext +{ +public: + WriteStructContext(FileStorage& _fs, const string& name, + int flags, const string& typeName=string()); + ~WriteStructContext(); + FileStorage* fs; +}; + +template inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, pt.x); + write(fs, pt.y); +} + +template inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, pt.x); + write(fs, pt.y); + write(fs, pt.z); +} + +template inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, sz.width); + write(fs, sz.height); +} + +template inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, c.re); + write(fs, c.im); +} + +template inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, r.x); + write(fs, r.y); + write(fs, r.width); + write(fs, r.height); +} + +template inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + for(int i = 0; i < cn; i++) + write(fs, v.val[i]); +} + +template inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, s.val[0]); + write(fs, s.val[1]); + write(fs, s.val[2]); + write(fs, s.val[3]); +} + +inline void write(FileStorage& fs, const string& name, const Range& r ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); + write(fs, r.start); + write(fs, r.end); +} + +template class CV_EXPORTS VecWriterProxy +{ +public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const vector<_Tp>& vec) const + { + size_t i, count = vec.size(); + for( i = 0; i < count; i++ ) + write( *fs, vec[i] ); + } + FileStorage* fs; +}; + +template class CV_EXPORTS VecWriterProxy<_Tp,1> +{ +public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const vector<_Tp>& vec) const + { + int _fmt = DataType<_Tp>::fmt; + char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' }; + fs->writeRaw( string(fmt), !vec.empty() ? (uchar*)&vec[0] : 0, vec.size()*sizeof(_Tp) ); + } + FileStorage* fs; +}; + +template static inline void write( FileStorage& fs, const vector<_Tp>& vec ) +{ + VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); + w(vec); +} + +template static inline void write( FileStorage& fs, const string& name, + const vector<_Tp>& vec ) +{ + WriteStructContext ws(fs, name, CV_NODE_SEQ+(DataType<_Tp>::fmt != 0 ? CV_NODE_FLOW : 0)); + write(fs, vec); +} + +CV_EXPORTS_W void write( FileStorage& fs, const string& name, const Mat& value ); +CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value ); + +template static inline FileStorage& operator << (FileStorage& fs, const _Tp& value) +{ + if( !fs.isOpened() ) + return fs; + if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP ) + CV_Error( CV_StsError, "No element name has been given" ); + write( fs, fs.elname, value ); + if( fs.state & FileStorage::INSIDE_MAP ) + fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP; + return fs; +} + +CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str); + +static inline FileStorage& operator << (FileStorage& fs, const char* str) +{ return (fs << string(str)); } + +static inline FileStorage& operator << (FileStorage& fs, char* value) +{ return (fs << string(value)); } + +inline FileNode::FileNode() : fs(0), node(0) {} +inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) + : fs(_fs), node(_node) {} + +inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {} + +inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); } +inline bool FileNode::empty() const { return node == 0; } +inline bool FileNode::isNone() const { return type() == NONE; } +inline bool FileNode::isSeq() const { return type() == SEQ; } +inline bool FileNode::isMap() const { return type() == MAP; } +inline bool FileNode::isInt() const { return type() == INT; } +inline bool FileNode::isReal() const { return type() == REAL; } +inline bool FileNode::isString() const { return type() == STR; } +inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; } +inline size_t FileNode::size() const +{ + int t = type(); + return t == MAP ? (size_t)((CvSet*)node->data.map)->active_count : + t == SEQ ? (size_t)node->data.seq->total : (size_t)!isNone(); +} + +inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; } +inline const CvFileNode* FileNode::operator* () const { return node; } + +static inline void read(const FileNode& node, int& value, int default_value) +{ + value = !node.node ? default_value : + CV_NODE_IS_INT(node.node->tag) ? node.node->data.i : + CV_NODE_IS_REAL(node.node->tag) ? cvRound(node.node->data.f) : 0x7fffffff; +} + +static inline void read(const FileNode& node, bool& value, bool default_value) +{ + int temp; read(node, temp, (int)default_value); + value = temp != 0; +} + +static inline void read(const FileNode& node, uchar& value, uchar default_value) +{ + int temp; read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline void read(const FileNode& node, schar& value, schar default_value) +{ + int temp; read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline void read(const FileNode& node, ushort& value, ushort default_value) +{ + int temp; read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline void read(const FileNode& node, short& value, short default_value) +{ + int temp; read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline void read(const FileNode& node, float& value, float default_value) +{ + value = !node.node ? default_value : + CV_NODE_IS_INT(node.node->tag) ? (float)node.node->data.i : + CV_NODE_IS_REAL(node.node->tag) ? (float)node.node->data.f : 1e30f; +} + +static inline void read(const FileNode& node, double& value, double default_value) +{ + value = !node.node ? default_value : + CV_NODE_IS_INT(node.node->tag) ? (double)node.node->data.i : + CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : 1e300; +} + +static inline void read(const FileNode& node, string& value, const string& default_value) +{ + value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? string(node.node->data.str.ptr) : string(""); +} + +CV_EXPORTS_W void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() ); +CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() ); + +inline FileNode::operator int() const +{ + int value; + read(*this, value, 0); + return value; +} +inline FileNode::operator float() const +{ + float value; + read(*this, value, 0.f); + return value; +} +inline FileNode::operator double() const +{ + double value; + read(*this, value, 0.); + return value; +} +inline FileNode::operator string() const +{ + string value; + read(*this, value, value); + return value; +} + +inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const +{ + begin().readRaw( fmt, vec, len ); +} + +template class CV_EXPORTS VecReaderProxy +{ +public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(vector<_Tp>& vec, size_t count) const + { + count = std::min(count, it->remaining); + vec.resize(count); + for( size_t i = 0; i < count; i++, ++(*it) ) + read(**it, vec[i], _Tp()); + } + FileNodeIterator* it; +}; + +template class CV_EXPORTS VecReaderProxy<_Tp,1> +{ +public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(vector<_Tp>& vec, size_t count) const + { + size_t remaining = it->remaining, cn = DataType<_Tp>::channels; + int _fmt = DataType<_Tp>::fmt; + char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' }; + size_t remaining1 = remaining/cn; + count = count < remaining1 ? count : remaining1; + vec.resize(count); + it->readRaw( string(fmt), !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp) ); + } + FileNodeIterator* it; +}; + +template static inline void +read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX ) +{ + VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + r(vec, maxCount); +} + +template static inline void +read( const FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() ) +{ + if(!node.node) + vec = default_value; + else + { + FileNodeIterator it = node.begin(); + read( it, vec ); + } +} + +inline FileNodeIterator FileNode::begin() const +{ + return FileNodeIterator(fs, node); +} + +inline FileNodeIterator FileNode::end() const +{ + return FileNodeIterator(fs, node, size()); +} + +inline FileNode FileNodeIterator::operator *() const +{ return FileNode(fs, (const CvFileNode*)reader.ptr); } + +inline FileNode FileNodeIterator::operator ->() const +{ return FileNode(fs, (const CvFileNode*)reader.ptr); } + +template static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) +{ read( *it, value, _Tp()); return ++it; } + +template static inline +FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec) +{ + VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + r(vec, (size_t)INT_MAX); + return it; +} + +template static inline void operator >> (const FileNode& n, _Tp& value) +{ read( n, value, _Tp()); } + +template static inline void operator >> (const FileNode& n, vector<_Tp>& vec) +{ FileNodeIterator it = n.begin(); it >> vec; } + +static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it1.fs == it2.fs && it1.container == it2.container && + it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining; +} + +static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return !(it1 == it2); +} + +static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it2.remaining - it1.remaining; +} + +static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it1.remaining > it2.remaining; +} + +inline FileNode FileStorage::getFirstTopLevelNode() const +{ + FileNode r = root(); + FileNodeIterator it = r.begin(); + return it != r.end() ? *it : FileNode(); +} + +//////////////////////////////////////// Various algorithms //////////////////////////////////// + +template static inline _Tp gcd(_Tp a, _Tp b) +{ + if( a < b ) + std::swap(a, b); + while( b > 0 ) + { + _Tp r = a % b; + a = b; + b = r; + } + return a; +} + +/****************************************************************************************\ + + Generic implementation of QuickSort algorithm + Use it as: vector<_Tp> a; ... sort(a,); + + The current implementation was derived from *BSD system qsort(): + + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + +\****************************************************************************************/ + +template void sort( vector<_Tp>& vec, _LT LT=_LT() ) +{ + int isort_thresh = 7; + int sp = 0; + + struct + { + _Tp *lb; + _Tp *ub; + } stack[48]; + + size_t total = vec.size(); + + if( total <= 1 ) + return; + + _Tp* arr = &vec[0]; + stack[0].lb = arr; + stack[0].ub = arr + (total - 1); + + while( sp >= 0 ) + { + _Tp* left = stack[sp].lb; + _Tp* right = stack[sp--].ub; + + for(;;) + { + int i, n = (int)(right - left) + 1, m; + _Tp* ptr; + _Tp* ptr2; + + if( n <= isort_thresh ) + { + insert_sort: + for( ptr = left + 1; ptr <= right; ptr++ ) + { + for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) + std::swap( ptr2[0], ptr2[-1] ); + } + break; + } + else + { + _Tp* left0; + _Tp* left1; + _Tp* right0; + _Tp* right1; + _Tp* pivot; + _Tp* a; + _Tp* b; + _Tp* c; + int swap_cnt = 0; + + left0 = left; + right0 = right; + pivot = left + (n/2); + + if( n > 40 ) + { + int d = n / 8; + a = left, b = left + d, c = left + 2*d; + left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); + + a = pivot - d, b = pivot, c = pivot + d; + pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); + + a = right - 2*d, b = right - d, c = right; + right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); + } + + a = left, b = pivot, c = right; + pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) + : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); + if( pivot != left0 ) + { + std::swap( *pivot, *left0 ); + pivot = left0; + } + left = left1 = left0 + 1; + right = right1 = right0; + + for(;;) + { + while( left <= right && !LT(*pivot, *left) ) + { + if( !LT(*left, *pivot) ) + { + if( left > left1 ) + std::swap( *left1, *left ); + swap_cnt = 1; + left1++; + } + left++; + } + + while( left <= right && !LT(*right, *pivot) ) + { + if( !LT(*pivot, *right) ) + { + if( right < right1 ) + std::swap( *right1, *right ); + swap_cnt = 1; + right1--; + } + right--; + } + + if( left > right ) + break; + std::swap( *left, *right ); + swap_cnt = 1; + left++; + right--; + } + + if( swap_cnt == 0 ) + { + left = left0, right = right0; + goto insert_sort; + } + + n = std::min( (int)(left1 - left0), (int)(left - left1) ); + for( i = 0; i < n; i++ ) + std::swap( left0[i], left[i-n] ); + + n = std::min( (int)(right0 - right1), (int)(right1 - right) ); + for( i = 0; i < n; i++ ) + std::swap( left[i], right0[i-n+1] ); + n = (int)(left - left1); + m = (int)(right1 - right); + if( n > 1 ) + { + if( m > 1 ) + { + if( n > m ) + { + stack[++sp].lb = left0; + stack[sp].ub = left0 + n - 1; + left = right0 - m + 1, right = right0; + } + else + { + stack[++sp].lb = right0 - m + 1; + stack[sp].ub = right0; + left = left0, right = left0 + n - 1; + } + } + else + left = left0, right = left0 + n - 1; + } + else if( m > 1 ) + left = right0 - m + 1, right = right0; + else + break; + } + } + } +} + +template class CV_EXPORTS LessThan +{ +public: + bool operator()(const _Tp& a, const _Tp& b) const { return a < b; } +}; + +template class CV_EXPORTS GreaterEq +{ +public: + bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; } +}; + +template class CV_EXPORTS LessThanIdx +{ +public: + LessThanIdx( const _Tp* _arr ) : arr(_arr) {} + bool operator()(int a, int b) const { return arr[a] < arr[b]; } + const _Tp* arr; +}; + +template class CV_EXPORTS GreaterEqIdx +{ +public: + GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {} + bool operator()(int a, int b) const { return arr[a] >= arr[b]; } + const _Tp* arr; +}; + + +// This function splits the input sequence or set into one or more equivalence classes and +// returns the vector of labels - 0-based class indexes for each element. +// predicate(a,b) returns true if the two sequence elements certainly belong to the same class. +// +// The algorithm is described in "Introduction to Algorithms" +// by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets" +template int +partition( const vector<_Tp>& _vec, vector& labels, + _EqPredicate predicate=_EqPredicate()) +{ + int i, j, N = (int)_vec.size(); + const _Tp* vec = &_vec[0]; + + const int PARENT=0; + const int RANK=1; + + vector _nodes(N*2); + int (*nodes)[2] = (int(*)[2])&_nodes[0]; + + // The first O(N) pass: create N single-vertex trees + for(i = 0; i < N; i++) + { + nodes[i][PARENT]=-1; + nodes[i][RANK] = 0; + } + + // The main O(N^2) pass: merge connected components + for( i = 0; i < N; i++ ) + { + int root = i; + + // find root + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + + for( j = 0; j < N; j++ ) + { + if( i == j || !predicate(vec[i], vec[j])) + continue; + int root2 = j; + + while( nodes[root2][PARENT] >= 0 ) + root2 = nodes[root2][PARENT]; + + if( root2 != root ) + { + // unite both trees + int rank = nodes[root][RANK], rank2 = nodes[root2][RANK]; + if( rank > rank2 ) + nodes[root2][PARENT] = root; + else + { + nodes[root][PARENT] = root2; + nodes[root2][RANK] += rank == rank2; + root = root2; + } + assert( nodes[root][PARENT] < 0 ); + + int k = j, parent; + + // compress the path from node2 to root + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + + // compress the path from node to root + k = i; + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + } + } + } + + // Final O(N) pass: enumerate classes + labels.resize(N); + int nclasses = 0; + + for( i = 0; i < N; i++ ) + { + int root = i; + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + // re-use the rank as the class label + if( nodes[root][RANK] >= 0 ) + nodes[root][RANK] = ~nclasses++; + labels[i] = ~nodes[root][RANK]; + } + + return nclasses; +} + + +////////////////////////////////////////////////////////////////////////////// + +// bridge C++ => C Seq API +CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0); +CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0); +CV_EXPORTS void seqPop( CvSeq* seq, void* element=0); +CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0); +CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements, + int count, int in_front=0 ); +CV_EXPORTS void seqRemove( CvSeq* seq, int index ); +CV_EXPORTS void clearSeq( CvSeq* seq ); +CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index ); +CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice ); +CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ); + +template inline Seq<_Tp>::Seq() : seq(0) {} +template inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq) +{ + CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp)); +} + +template inline Seq<_Tp>::Seq( MemStorage& storage, + int headerSize ) +{ + CV_Assert(headerSize >= (int)sizeof(CvSeq)); + seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage); +} + +template inline _Tp& Seq<_Tp>::operator [](int idx) +{ return *(_Tp*)getSeqElem(seq, idx); } + +template inline const _Tp& Seq<_Tp>::operator [](int idx) const +{ return *(_Tp*)getSeqElem(seq, idx); } + +template inline SeqIterator<_Tp> Seq<_Tp>::begin() const +{ return SeqIterator<_Tp>(*this); } + +template inline SeqIterator<_Tp> Seq<_Tp>::end() const +{ return SeqIterator<_Tp>(*this, true); } + +template inline size_t Seq<_Tp>::size() const +{ return seq ? seq->total : 0; } + +template inline int Seq<_Tp>::type() const +{ return seq ? CV_MAT_TYPE(seq->flags) : 0; } + +template inline int Seq<_Tp>::depth() const +{ return seq ? CV_MAT_DEPTH(seq->flags) : 0; } + +template inline int Seq<_Tp>::channels() const +{ return seq ? CV_MAT_CN(seq->flags) : 0; } + +template inline size_t Seq<_Tp>::elemSize() const +{ return seq ? seq->elem_size : 0; } + +template inline size_t Seq<_Tp>::index(const _Tp& elem) const +{ return cvSeqElemIdx(seq, &elem); } + +template inline void Seq<_Tp>::push_back(const _Tp& elem) +{ cvSeqPush(seq, &elem); } + +template inline void Seq<_Tp>::push_front(const _Tp& elem) +{ cvSeqPushFront(seq, &elem); } + +template inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count) +{ cvSeqPushMulti(seq, elem, (int)count, 0); } + +template inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count) +{ cvSeqPushMulti(seq, elem, (int)count, 1); } + +template inline _Tp& Seq<_Tp>::back() +{ return *(_Tp*)getSeqElem(seq, -1); } + +template inline const _Tp& Seq<_Tp>::back() const +{ return *(const _Tp*)getSeqElem(seq, -1); } + +template inline _Tp& Seq<_Tp>::front() +{ return *(_Tp*)getSeqElem(seq, 0); } + +template inline const _Tp& Seq<_Tp>::front() const +{ return *(const _Tp*)getSeqElem(seq, 0); } + +template inline bool Seq<_Tp>::empty() const +{ return !seq || seq->total == 0; } + +template inline void Seq<_Tp>::clear() +{ if(seq) clearSeq(seq); } + +template inline void Seq<_Tp>::pop_back() +{ seqPop(seq); } + +template inline void Seq<_Tp>::pop_front() +{ seqPopFront(seq); } + +template inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count) +{ seqPopMulti(seq, elem, (int)count, 0); } + +template inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count) +{ seqPopMulti(seq, elem, (int)count, 1); } + +template inline void Seq<_Tp>::insert(int idx, const _Tp& elem) +{ seqInsert(seq, idx, &elem); } + +template inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count) +{ + CvMat m = cvMat(1, count, DataType<_Tp>::type, elems); + seqInsertSlice(seq, idx, &m); +} + +template inline void Seq<_Tp>::remove(int idx) +{ seqRemove(seq, idx); } + +template inline void Seq<_Tp>::remove(const Range& r) +{ seqRemoveSlice(seq, r); } + +template inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const +{ + size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start; + vec.resize(len); + if( seq && len ) + cvCvtSeqToArray(seq, &vec[0], range); +} + +template inline Seq<_Tp>::operator vector<_Tp>() const +{ + vector<_Tp> vec; + copyTo(vec); + return vec; +} + +template inline SeqIterator<_Tp>::SeqIterator() +{ memset(this, 0, sizeof(*this)); } + +template inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& _seq, bool seekEnd) +{ + cvStartReadSeq(_seq.seq, this); + index = seekEnd ? _seq.seq->total : 0; +} + +template inline void SeqIterator<_Tp>::seek(size_t pos) +{ + cvSetSeqReaderPos(this, (int)pos, false); + index = pos; +} + +template inline size_t SeqIterator<_Tp>::tell() const +{ return index; } + +template inline _Tp& SeqIterator<_Tp>::operator *() +{ return *(_Tp*)ptr; } + +template inline const _Tp& SeqIterator<_Tp>::operator *() const +{ return *(const _Tp*)ptr; } + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++() +{ + CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this); + if( ++index >= seq->total*2 ) + index = 0; + return *this; +} + +template inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const +{ + SeqIterator<_Tp> it = *this; + ++*this; + return it; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --() +{ + CV_PREV_SEQ_ELEM(sizeof(_Tp), *this); + if( --index < 0 ) + index = seq->total*2-1; + return *this; +} + +template inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const +{ + SeqIterator<_Tp> it = *this; + --*this; + return it; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta) +{ + cvSetSeqReaderPos(this, delta, 1); + index += delta; + int n = seq->total*2; + if( index < 0 ) + index += n; + if( index >= n ) + index -= n; + return *this; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta) +{ + return (*this += -delta); +} + +template inline ptrdiff_t operator - (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + ptrdiff_t delta = a.index - b.index, n = a.seq->total; + if( std::abs(static_cast(delta)) > n ) + delta += delta < 0 ? n : -n; + return delta; +} + +template inline bool operator == (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + return a.seq == b.seq && a.index == b.index; +} + +template inline bool operator != (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + return !(a == b); +} + + +template struct CV_EXPORTS RTTIImpl +{ +public: + static int isInstance(const void* ptr) + { + static _ClsName dummy; + static void* dummyp = &dummy; + union + { + const void* p; + const void** pp; + } a, b; + a.p = dummyp; + b.p = ptr; + return *a.pp == *b.pp; + } + static void release(void** dbptr) + { + if(dbptr && *dbptr) + { + delete (_ClsName*)*dbptr; + *dbptr = 0; + } + } + static void* read(CvFileStorage* fs, CvFileNode* n) + { + FileNode fn(fs, n); + _ClsName* obj = new _ClsName; + if(obj->read(fn)) + return obj; + delete obj; + return 0; + } + + static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList) + { + if(ptr && _fs) + { + FileStorage fs(_fs); + fs.fs.addref(); + ((const _ClsName*)ptr)->write(fs, string(name)); + } + } + + static void* clone(const void* ptr) + { + if(!ptr) + return 0; + return new _ClsName(*(const _ClsName*)ptr); + } +}; + + +class CV_EXPORTS Formatter +{ +public: + virtual ~Formatter() {} + virtual void write(std::ostream& out, const Mat& m, const int* params=0, int nparams=0) const = 0; + virtual void write(std::ostream& out, const void* data, int nelems, int type, + const int* params=0, int nparams=0) const = 0; + static const Formatter* get(const char* fmt=""); + static const Formatter* setDefault(const Formatter* fmt); +}; + + +struct CV_EXPORTS Formatted +{ + Formatted(const Mat& m, const Formatter* fmt, + const vector& params); + Formatted(const Mat& m, const Formatter* fmt, + const int* params=0); + Mat mtx; + const Formatter* fmt; + vector params; +}; + +static inline Formatted format(const Mat& mtx, const char* fmt, + const vector& params=vector()) +{ + return Formatted(mtx, Formatter::get(fmt), params); +} + +template static inline Formatted format(const vector >& vec, + const char* fmt, const vector& params=vector()) +{ + return Formatted(Mat(vec), Formatter::get(fmt), params); +} + +template static inline Formatted format(const vector >& vec, + const char* fmt, const vector& params=vector()) +{ + return Formatted(Mat(vec), Formatter::get(fmt), params); +} + +/** \brief prints Mat to the output stream in Matlab notation + * use like + @verbatim + Mat my_mat = Mat::eye(3,3,CV_32F); + std::cout << my_mat; + @endverbatim + */ +static inline std::ostream& operator << (std::ostream& out, const Mat& mtx) +{ + Formatter::get()->write(out, mtx); + return out; +} + +/** \brief prints Mat to the output stream allows in the specified notation (see format) + * use like + @verbatim + Mat my_mat = Mat::eye(3,3,CV_32F); + std::cout << my_mat; + @endverbatim + */ +static inline std::ostream& operator << (std::ostream& out, const Formatted& fmtd) +{ + fmtd.fmt->write(out, fmtd.mtx); + return out; +} + + +template static inline std::ostream& operator << (std::ostream& out, + const vector >& vec) +{ + Formatter::get()->write(out, Mat(vec)); + return out; +} + + +template static inline std::ostream& operator << (std::ostream& out, + const vector >& vec) +{ + Formatter::get()->write(out, Mat(vec)); + return out; +} + + +/** Writes a Matx to an output stream. + */ +template inline std::ostream& operator<<(std::ostream& out, const Matx<_Tp, m, n>& matx) +{ + out << cv::Mat(matx); + return out; +} + +/** Writes a point to an output stream in Matlab notation + */ +template inline std::ostream& operator<<(std::ostream& out, const Point_<_Tp>& p) +{ + out << "[" << p.x << ", " << p.y << "]"; + return out; +} + +/** Writes a point to an output stream in Matlab notation + */ +template inline std::ostream& operator<<(std::ostream& out, const Point3_<_Tp>& p) +{ + out << "[" << p.x << ", " << p.y << ", " << p.z << "]"; + return out; +} + +/** Writes a Vec to an output stream. Format example : [10, 20, 30] + */ +template inline std::ostream& operator<<(std::ostream& out, const Vec<_Tp, n>& vec) +{ + out << "["; + + if(Vec<_Tp, n>::depth < CV_32F) + { + for (int i = 0; i < n - 1; ++i) { + out << (int)vec[i] << ", "; + } + out << (int)vec[n-1] << "]"; + } + else + { + for (int i = 0; i < n - 1; ++i) { + out << vec[i] << ", "; + } + out << vec[n-1] << "]"; + } + + return out; +} + +/** Writes a Size_ to an output stream. Format example : [640 x 480] + */ +template inline std::ostream& operator<<(std::ostream& out, const Size_<_Tp>& size) +{ + out << "[" << size.width << " x " << size.height << "]"; + return out; +} + +/** Writes a Rect_ to an output stream. Format example : [640 x 480 from (10, 20)] + */ +template inline std::ostream& operator<<(std::ostream& out, const Rect_<_Tp>& rect) +{ + out << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]"; + return out; +} + + +template inline Ptr<_Tp> Algorithm::create(const string& name) +{ + return _create(name).ptr<_Tp>(); +} + +template +inline void Algorithm::set(const char* _name, const Ptr<_Tp>& value) +{ + Ptr algo_ptr = value. template ptr(); + if (algo_ptr.empty()) { + CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported Ptr type of the second parameter of the method Algorithm::set"); + } + info()->set(this, _name, ParamType::type, &algo_ptr); +} + +template +inline void Algorithm::set(const string& _name, const Ptr<_Tp>& value) +{ + this->set<_Tp>(_name.c_str(), value); +} + +template +inline void Algorithm::setAlgorithm(const char* _name, const Ptr<_Tp>& value) +{ + Ptr algo_ptr = value. template ptr(); + if (algo_ptr.empty()) { + CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported Ptr type of the second parameter of the method Algorithm::set"); + } + info()->set(this, _name, ParamType::type, &algo_ptr); +} + +template +inline void Algorithm::setAlgorithm(const string& _name, const Ptr<_Tp>& value) +{ + this->set<_Tp>(_name.c_str(), value); +} + +template inline typename ParamType<_Tp>::member_type Algorithm::get(const string& _name) const +{ + typename ParamType<_Tp>::member_type value; + info()->get(this, _name.c_str(), ParamType<_Tp>::type, &value); + return value; +} + +template inline typename ParamType<_Tp>::member_type Algorithm::get(const char* _name) const +{ + typename ParamType<_Tp>::member_type value; + info()->get(this, _name, ParamType<_Tp>::type, &value); + return value; +} + +template inline void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + Ptr<_Tp>& value, bool readOnly, Ptr<_Tp> (Algorithm::*getter)(), void (Algorithm::*setter)(const Ptr<_Tp>&), + const string& help) +{ + //TODO: static assert: _Tp inherits from _Base + addParam_(algo, parameter, ParamType<_Base>::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +template inline void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + Ptr<_Tp>& value, bool readOnly, Ptr<_Tp> (Algorithm::*getter)(), void (Algorithm::*setter)(const Ptr<_Tp>&), + const string& help) +{ + //TODO: static assert: _Tp inherits from Algorithm + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // __cplusplus +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/types_c.h diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/types_c.h --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/types_c.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/types_c.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1893 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_TYPES_H__ +#define __OPENCV_CORE_TYPES_H__ + +#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER +# if _MSC_VER > 1300 +# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio 2005 warnings */ +# endif +#endif + + +#ifndef SKIP_INCLUDES + +#include +#include +#include +#include + +#if !defined _MSC_VER && !defined __BORLANDC__ +# include +#endif + +#if defined __ICL +# define CV_ICC __ICL +#elif defined __ICC +# define CV_ICC __ICC +#elif defined __ECL +# define CV_ICC __ECL +#elif defined __ECC +# define CV_ICC __ECC +#elif defined __INTEL_COMPILER +# define CV_ICC __INTEL_COMPILER +#endif + +#if defined CV_ICC && !defined CV_ENABLE_UNROLLED +# define CV_ENABLE_UNROLLED 0 +#else +# define CV_ENABLE_UNROLLED 1 +#endif + +#if (defined _M_X64 && defined _MSC_VER && _MSC_VER >= 1400) || (__GNUC__ >= 4 && defined __x86_64__) +# if defined WIN32 +# include +# endif +# if defined __SSE2__ || !defined __GNUC__ +# include +# endif +#endif + +#if defined __BORLANDC__ +# include +#else +# include +#endif + +#ifdef HAVE_IPL +# ifndef __IPL_H__ +# if defined WIN32 || defined _WIN32 +# include +# else +# include +# endif +# endif +#elif defined __IPL_H__ +# define HAVE_IPL +#endif + +#endif // SKIP_INCLUDES + +#if defined WIN32 || defined _WIN32 +# define CV_CDECL __cdecl +# define CV_STDCALL __stdcall +#else +# define CV_CDECL +# define CV_STDCALL +#endif + +#ifndef CV_EXTERN_C +# ifdef __cplusplus +# define CV_EXTERN_C extern "C" +# define CV_DEFAULT(val) = val +# else +# define CV_EXTERN_C +# define CV_DEFAULT(val) +# endif +#endif + +#ifndef CV_EXTERN_C_FUNCPTR +# ifdef __cplusplus +# define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; } +# else +# define CV_EXTERN_C_FUNCPTR(x) typedef x +# endif +#endif + +#ifndef CV_INLINE +# if defined __cplusplus +# define CV_INLINE inline +# elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__ +# define CV_INLINE __inline +# else +# define CV_INLINE static +# endif +#endif /* CV_INLINE */ + +#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS +# define CV_EXPORTS __declspec(dllexport) +#else +# define CV_EXPORTS +#endif + +#ifndef CVAPI +# define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL +#endif + +#if defined _MSC_VER || defined __BORLANDC__ + typedef __int64 int64; + typedef unsigned __int64 uint64; +# define CV_BIG_INT(n) n##I64 +# define CV_BIG_UINT(n) n##UI64 +#else + typedef int64_t int64; + typedef uint64_t uint64; +# define CV_BIG_INT(n) n##LL +# define CV_BIG_UINT(n) n##ULL +#endif + +#ifndef HAVE_IPL + typedef unsigned char uchar; + typedef unsigned short ushort; +#endif + +typedef signed char schar; + +/* special informative macros for wrapper generators */ +#define CV_CARRAY(counter) +#define CV_CUSTOM_CARRAY(args) +#define CV_EXPORTS_W CV_EXPORTS +#define CV_EXPORTS_W_SIMPLE CV_EXPORTS +#define CV_EXPORTS_AS(synonym) CV_EXPORTS +#define CV_EXPORTS_W_MAP CV_EXPORTS +#define CV_IN_OUT +#define CV_OUT +#define CV_PROP +#define CV_PROP_RW +#define CV_WRAP +#define CV_WRAP_AS(synonym) +#define CV_WRAP_DEFAULT(value) + +/* CvArr* is used to pass arbitrary + * array-like data structures + * into functions where the particular + * array type is recognized at runtime: + */ +typedef void CvArr; + +typedef union Cv32suf +{ + int i; + unsigned u; + float f; +} +Cv32suf; + +typedef union Cv64suf +{ + int64 i; + uint64 u; + double f; +} +Cv64suf; + +typedef int CVStatus; + +enum { + CV_StsOk= 0, /* everithing is ok */ + CV_StsBackTrace= -1, /* pseudo error for back trace */ + CV_StsError= -2, /* unknown /unspecified error */ + CV_StsInternal= -3, /* internal error (bad state) */ + CV_StsNoMem= -4, /* insufficient memory */ + CV_StsBadArg= -5, /* function arg/param is bad */ + CV_StsBadFunc= -6, /* unsupported function */ + CV_StsNoConv= -7, /* iter. didn't converge */ + CV_StsAutoTrace= -8, /* tracing */ + CV_HeaderIsNull= -9, /* image header is NULL */ + CV_BadImageSize= -10, /* image size is invalid */ + CV_BadOffset= -11, /* offset is invalid */ + CV_BadDataPtr= -12, /**/ + CV_BadStep= -13, /**/ + CV_BadModelOrChSeq= -14, /**/ + CV_BadNumChannels= -15, /**/ + CV_BadNumChannel1U= -16, /**/ + CV_BadDepth= -17, /**/ + CV_BadAlphaChannel= -18, /**/ + CV_BadOrder= -19, /**/ + CV_BadOrigin= -20, /**/ + CV_BadAlign= -21, /**/ + CV_BadCallBack= -22, /**/ + CV_BadTileSize= -23, /**/ + CV_BadCOI= -24, /**/ + CV_BadROISize= -25, /**/ + CV_MaskIsTiled= -26, /**/ + CV_StsNullPtr= -27, /* null pointer */ + CV_StsVecLengthErr= -28, /* incorrect vector length */ + CV_StsFilterStructContentErr= -29, /* incorr. filter structure content */ + CV_StsKernelStructContentErr= -30, /* incorr. transform kernel content */ + CV_StsFilterOffsetErr= -31, /* incorrect filter ofset value */ + CV_StsBadSize= -201, /* the input/output structure size is incorrect */ + CV_StsDivByZero= -202, /* division by zero */ + CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */ + CV_StsObjectNotFound= -204, /* request can't be completed */ + CV_StsUnmatchedFormats= -205, /* formats of input/output arrays differ */ + CV_StsBadFlag= -206, /* flag is wrong or not supported */ + CV_StsBadPoint= -207, /* bad CvPoint */ + CV_StsBadMask= -208, /* bad format of mask (neither 8uC1 nor 8sC1)*/ + CV_StsUnmatchedSizes= -209, /* sizes of input/output structures do not match */ + CV_StsUnsupportedFormat= -210, /* the data format/type is not supported by the function*/ + CV_StsOutOfRange= -211, /* some of parameters are out of range */ + CV_StsParseError= -212, /* invalid syntax/structure of the parsed file */ + CV_StsNotImplemented= -213, /* the requested function/feature is not implemented */ + CV_StsBadMemBlock= -214, /* an allocated block has been corrupted */ + CV_StsAssert= -215, /* assertion failed */ + CV_GpuNotSupported= -216, + CV_GpuApiCallError= -217, + CV_OpenGlNotSupported= -218, + CV_OpenGlApiCallError= -219 +}; + +/****************************************************************************************\ +* Common macros and inline functions * +\****************************************************************************************/ + +#ifdef HAVE_TEGRA_OPTIMIZATION +# include "tegra_round.hpp" +#endif + +#define CV_PI 3.1415926535897932384626433832795 +#define CV_LOG2 0.69314718055994530941723212145818 + +#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t)) + +#ifndef MIN +# define MIN(a,b) ((a) > (b) ? (b) : (a)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif + +/* min & max without jumps */ +#define CV_IMIN(a, b) ((a) ^ (((a)^(b)) & (((a) < (b)) - 1))) + +#define CV_IMAX(a, b) ((a) ^ (((a)^(b)) & (((a) > (b)) - 1))) + +/* absolute value without jumps */ +#ifndef __cplusplus +# define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0)) +#else +# define CV_IABS(a) abs(a) +#endif +#define CV_CMP(a,b) (((a) > (b)) - ((a) < (b))) +#define CV_SIGN(a) CV_CMP((a),0) + +CV_INLINE int cvRound( double value ) +{ +#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__) + __m128d t = _mm_set_sd( value ); + return _mm_cvtsd_si32(t); +#elif defined _MSC_VER && defined _M_IX86 + int t; + __asm + { + fld value; + fistp t; + } + return t; +#elif defined _MSC_VER && defined _M_ARM && defined HAVE_TEGRA_OPTIMIZATION + TEGRA_ROUND(value); +#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__ +# ifdef HAVE_TEGRA_OPTIMIZATION + TEGRA_ROUND(value); +# else + return (int)lrint(value); +# endif +#else + double intpart, fractpart; + fractpart = modf(value, &intpart); + if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0)) + return (int)(value + (value >= 0 ? 0.5 : -0.5)); + else + return (int)intpart; +#endif +} + +#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP) +# include "emmintrin.h" +#endif + +CV_INLINE int cvFloor( double value ) +{ +#if defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__) + __m128d t = _mm_set_sd( value ); + int i = _mm_cvtsd_si32(t); + return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i))); +#elif defined __GNUC__ + int i = (int)value; + return i - (i > value); +#else + int i = cvRound(value); + float diff = (float)(value - i); + return i - (diff < 0); +#endif +} + + +CV_INLINE int cvCeil( double value ) +{ +#if defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__) + __m128d t = _mm_set_sd( value ); + int i = _mm_cvtsd_si32(t); + return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t)); +#elif defined __GNUC__ + int i = (int)value; + return i + (i < value); +#else + int i = cvRound(value); + float diff = (float)(i - value); + return i + (diff < 0); +#endif +} + +#define cvInvSqrt(value) ((float)(1./sqrt(value))) +#define cvSqrt(value) ((float)sqrt(value)) + +CV_INLINE int cvIsNaN( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + + ((unsigned)ieee754.u != 0) > 0x7ff00000; +} + + +CV_INLINE int cvIsInf( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + (unsigned)ieee754.u == 0; +} + + +/*************** Random number generation *******************/ + +typedef uint64 CvRNG; + +#define CV_RNG_COEFF 4164903690U + +CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1)) +{ + CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1; + return rng; +} + +/* Return random 32-bit unsigned integer: */ +CV_INLINE unsigned cvRandInt( CvRNG* rng ) +{ + uint64 temp = *rng; + temp = (uint64)(unsigned)temp*CV_RNG_COEFF + (temp >> 32); + *rng = temp; + return (unsigned)temp; +} + +/* Returns random floating-point number between 0 and 1: */ +CV_INLINE double cvRandReal( CvRNG* rng ) +{ + return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */; +} + +/****************************************************************************************\ +* Image type (IplImage) * +\****************************************************************************************/ + +#ifndef HAVE_IPL + +/* + * The following definitions (until #endif) + * is an extract from IPL headers. + * Copyright (c) 1995 Intel Corporation. + */ +#define IPL_DEPTH_SIGN 0x80000000 + +#define IPL_DEPTH_1U 1 +#define IPL_DEPTH_8U 8 +#define IPL_DEPTH_16U 16 +#define IPL_DEPTH_32F 32 + +#define IPL_DEPTH_8S (IPL_DEPTH_SIGN| 8) +#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16) +#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32) + +#define IPL_DATA_ORDER_PIXEL 0 +#define IPL_DATA_ORDER_PLANE 1 + +#define IPL_ORIGIN_TL 0 +#define IPL_ORIGIN_BL 1 + +#define IPL_ALIGN_4BYTES 4 +#define IPL_ALIGN_8BYTES 8 +#define IPL_ALIGN_16BYTES 16 +#define IPL_ALIGN_32BYTES 32 + +#define IPL_ALIGN_DWORD IPL_ALIGN_4BYTES +#define IPL_ALIGN_QWORD IPL_ALIGN_8BYTES + +#define IPL_BORDER_CONSTANT 0 +#define IPL_BORDER_REPLICATE 1 +#define IPL_BORDER_REFLECT 2 +#define IPL_BORDER_WRAP 3 + +typedef struct _IplImage +{ + int nSize; /* sizeof(IplImage) */ + int ID; /* version (=0)*/ + int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ + int alphaChannel; /* Ignored by OpenCV */ + int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, + IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */ + char colorModel[4]; /* Ignored by OpenCV */ + char channelSeq[4]; /* ditto */ + int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels. + cvCreateImage can only create interleaved images */ + int origin; /* 0 - top-left origin, + 1 - bottom-left origin (Windows bitmaps style). */ + int align; /* Alignment of image rows (4 or 8). + OpenCV ignores it and uses widthStep instead. */ + int width; /* Image width in pixels. */ + int height; /* Image height in pixels. */ + struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */ + struct _IplImage *maskROI; /* Must be NULL. */ + void *imageId; /* " " */ + struct _IplTileInfo *tileInfo; /* " " */ + int imageSize; /* Image data size in bytes + (==image->height*image->widthStep + in case of interleaved data)*/ + char *imageData; /* Pointer to aligned image data. */ + int widthStep; /* Size of aligned image row in bytes. */ + int BorderMode[4]; /* Ignored by OpenCV. */ + int BorderConst[4]; /* Ditto. */ + char *imageDataOrigin; /* Pointer to very origin of image data + (not necessarily aligned) - + needed for correct deallocation */ +} +IplImage; + +typedef struct _IplTileInfo IplTileInfo; + +typedef struct _IplROI +{ + int coi; /* 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/ + int xOffset; + int yOffset; + int width; + int height; +} +IplROI; + +typedef struct _IplConvKernel +{ + int nCols; + int nRows; + int anchorX; + int anchorY; + int *values; + int nShiftR; +} +IplConvKernel; + +typedef struct _IplConvKernelFP +{ + int nCols; + int nRows; + int anchorX; + int anchorY; + float *values; +} +IplConvKernelFP; + +#define IPL_IMAGE_HEADER 1 +#define IPL_IMAGE_DATA 2 +#define IPL_IMAGE_ROI 4 + +#endif/*HAVE_IPL*/ + +/* extra border mode */ +#define IPL_BORDER_REFLECT_101 4 +#define IPL_BORDER_TRANSPARENT 5 + +#define IPL_IMAGE_MAGIC_VAL ((int)sizeof(IplImage)) +#define CV_TYPE_NAME_IMAGE "opencv-image" + +#define CV_IS_IMAGE_HDR(img) \ + ((img) != NULL && ((const IplImage*)(img))->nSize == sizeof(IplImage)) + +#define CV_IS_IMAGE(img) \ + (CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL) + +/* for storing double-precision + floating point data in IplImage's */ +#define IPL_DEPTH_64F 64 + +/* get reference to pixel at (col,row), + for multi-channel images (col) should be multiplied by number of channels */ +#define CV_IMAGE_ELEM( image, elemtype, row, col ) \ + (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)]) + +/****************************************************************************************\ +* Matrix type (CvMat) * +\****************************************************************************************/ + +#define CV_CN_MAX 512 +#define CV_CN_SHIFT 3 +#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) + +#define CV_8U 0 +#define CV_8S 1 +#define CV_16U 2 +#define CV_16S 3 +#define CV_32S 4 +#define CV_32F 5 +#define CV_64F 6 +#define CV_USRTYPE1 7 + +#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) +#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) + +#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) +#define CV_MAKE_TYPE CV_MAKETYPE + +#define CV_8UC1 CV_MAKETYPE(CV_8U,1) +#define CV_8UC2 CV_MAKETYPE(CV_8U,2) +#define CV_8UC3 CV_MAKETYPE(CV_8U,3) +#define CV_8UC4 CV_MAKETYPE(CV_8U,4) +#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n)) + +#define CV_8SC1 CV_MAKETYPE(CV_8S,1) +#define CV_8SC2 CV_MAKETYPE(CV_8S,2) +#define CV_8SC3 CV_MAKETYPE(CV_8S,3) +#define CV_8SC4 CV_MAKETYPE(CV_8S,4) +#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n)) + +#define CV_16UC1 CV_MAKETYPE(CV_16U,1) +#define CV_16UC2 CV_MAKETYPE(CV_16U,2) +#define CV_16UC3 CV_MAKETYPE(CV_16U,3) +#define CV_16UC4 CV_MAKETYPE(CV_16U,4) +#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n)) + +#define CV_16SC1 CV_MAKETYPE(CV_16S,1) +#define CV_16SC2 CV_MAKETYPE(CV_16S,2) +#define CV_16SC3 CV_MAKETYPE(CV_16S,3) +#define CV_16SC4 CV_MAKETYPE(CV_16S,4) +#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n)) + +#define CV_32SC1 CV_MAKETYPE(CV_32S,1) +#define CV_32SC2 CV_MAKETYPE(CV_32S,2) +#define CV_32SC3 CV_MAKETYPE(CV_32S,3) +#define CV_32SC4 CV_MAKETYPE(CV_32S,4) +#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n)) + +#define CV_32FC1 CV_MAKETYPE(CV_32F,1) +#define CV_32FC2 CV_MAKETYPE(CV_32F,2) +#define CV_32FC3 CV_MAKETYPE(CV_32F,3) +#define CV_32FC4 CV_MAKETYPE(CV_32F,4) +#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n)) + +#define CV_64FC1 CV_MAKETYPE(CV_64F,1) +#define CV_64FC2 CV_MAKETYPE(CV_64F,2) +#define CV_64FC3 CV_MAKETYPE(CV_64F,3) +#define CV_64FC4 CV_MAKETYPE(CV_64F,4) +#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n)) + +#define CV_AUTO_STEP 0x7fffffff +#define CV_WHOLE_ARR cvSlice( 0, 0x3fffffff ) + +#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) +#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) +#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1) +#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK) +#define CV_MAT_CONT_FLAG_SHIFT 14 +#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT) +#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG) +#define CV_IS_CONT_MAT CV_IS_MAT_CONT +#define CV_SUBMAT_FLAG_SHIFT 15 +#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT) +#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG) + +#define CV_MAGIC_MASK 0xFFFF0000 +#define CV_MAT_MAGIC_VAL 0x42420000 +#define CV_TYPE_NAME_MAT "opencv-matrix" + +typedef struct CvMat +{ + int type; + int step; + + /* for internal use only */ + int* refcount; + int hdr_refcount; + + union + { + uchar* ptr; + short* s; + int* i; + float* fl; + double* db; + } data; + +#ifdef __cplusplus + union + { + int rows; + int height; + }; + + union + { + int cols; + int width; + }; +#else + int rows; + int cols; +#endif + +} +CvMat; + + +#define CV_IS_MAT_HDR(mat) \ + ((mat) != NULL && \ + (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \ + ((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0) + +#define CV_IS_MAT_HDR_Z(mat) \ + ((mat) != NULL && \ + (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \ + ((const CvMat*)(mat))->cols >= 0 && ((const CvMat*)(mat))->rows >= 0) + +#define CV_IS_MAT(mat) \ + (CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL) + +#define CV_IS_MASK_ARR(mat) \ + (((mat)->type & (CV_MAT_TYPE_MASK & ~CV_8SC1)) == 0) + +#define CV_ARE_TYPES_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_TYPE_MASK) == 0) + +#define CV_ARE_CNS_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_CN_MASK) == 0) + +#define CV_ARE_DEPTHS_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_DEPTH_MASK) == 0) + +#define CV_ARE_SIZES_EQ(mat1, mat2) \ + ((mat1)->rows == (mat2)->rows && (mat1)->cols == (mat2)->cols) + +#define CV_IS_MAT_CONST(mat) \ + (((mat)->rows|(mat)->cols) == 1) + +/* Size of each channel item, + 0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */ +#define CV_ELEM_SIZE1(type) \ + ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15) + +/* 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */ +#define CV_ELEM_SIZE(type) \ + (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3)) + +#define IPL2CV_DEPTH(depth) \ + ((((CV_8U)+(CV_16U<<4)+(CV_32F<<8)+(CV_64F<<16)+(CV_8S<<20)+ \ + (CV_16S<<24)+(CV_32S<<28)) >> ((((depth) & 0xF0) >> 2) + \ + (((depth) & IPL_DEPTH_SIGN) ? 20 : 0))) & 15) + +/* Inline constructor. No data is allocated internally!!! + * (Use together with cvCreateData, or use cvCreateMat instead to + * get a matrix with allocated data): + */ +CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL)) +{ + CvMat m; + + assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F ); + type = CV_MAT_TYPE(type); + m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type; + m.cols = cols; + m.rows = rows; + m.step = m.cols*CV_ELEM_SIZE(type); + m.data.ptr = (uchar*)data; + m.refcount = NULL; + m.hdr_refcount = 0; + + return m; +} + + +#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \ + (assert( (unsigned)(row) < (unsigned)(mat).rows && \ + (unsigned)(col) < (unsigned)(mat).cols ), \ + (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col)) + +#define CV_MAT_ELEM_PTR( mat, row, col ) \ + CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) ) + +#define CV_MAT_ELEM( mat, elemtype, row, col ) \ + (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype))) + + +CV_INLINE double cvmGet( const CvMat* mat, int row, int col ) +{ + int type; + + type = CV_MAT_TYPE(mat->type); + assert( (unsigned)row < (unsigned)mat->rows && + (unsigned)col < (unsigned)mat->cols ); + + if( type == CV_32FC1 ) + return ((float*)(mat->data.ptr + (size_t)mat->step*row))[col]; + else + { + assert( type == CV_64FC1 ); + return ((double*)(mat->data.ptr + (size_t)mat->step*row))[col]; + } +} + + +CV_INLINE void cvmSet( CvMat* mat, int row, int col, double value ) +{ + int type; + type = CV_MAT_TYPE(mat->type); + assert( (unsigned)row < (unsigned)mat->rows && + (unsigned)col < (unsigned)mat->cols ); + + if( type == CV_32FC1 ) + ((float*)(mat->data.ptr + (size_t)mat->step*row))[col] = (float)value; + else + { + assert( type == CV_64FC1 ); + ((double*)(mat->data.ptr + (size_t)mat->step*row))[col] = (double)value; + } +} + + +CV_INLINE int cvIplDepth( int type ) +{ + int depth = CV_MAT_DEPTH(type); + return CV_ELEM_SIZE1(depth)*8 | (depth == CV_8S || depth == CV_16S || + depth == CV_32S ? IPL_DEPTH_SIGN : 0); +} + + +/****************************************************************************************\ +* Multi-dimensional dense array (CvMatND) * +\****************************************************************************************/ + +#define CV_MATND_MAGIC_VAL 0x42430000 +#define CV_TYPE_NAME_MATND "opencv-nd-matrix" + +#define CV_MAX_DIM 32 +#define CV_MAX_DIM_HEAP 1024 + +typedef struct CvMatND +{ + int type; + int dims; + + int* refcount; + int hdr_refcount; + + union + { + uchar* ptr; + float* fl; + double* db; + int* i; + short* s; + } data; + + struct + { + int size; + int step; + } + dim[CV_MAX_DIM]; +} +CvMatND; + +#define CV_IS_MATND_HDR(mat) \ + ((mat) != NULL && (((const CvMatND*)(mat))->type & CV_MAGIC_MASK) == CV_MATND_MAGIC_VAL) + +#define CV_IS_MATND(mat) \ + (CV_IS_MATND_HDR(mat) && ((const CvMatND*)(mat))->data.ptr != NULL) + + +/****************************************************************************************\ +* Multi-dimensional sparse array (CvSparseMat) * +\****************************************************************************************/ + +#define CV_SPARSE_MAT_MAGIC_VAL 0x42440000 +#define CV_TYPE_NAME_SPARSE_MAT "opencv-sparse-matrix" + +struct CvSet; + +typedef struct CvSparseMat +{ + int type; + int dims; + int* refcount; + int hdr_refcount; + + struct CvSet* heap; + void** hashtable; + int hashsize; + int valoffset; + int idxoffset; + int size[CV_MAX_DIM]; +} +CvSparseMat; + +#define CV_IS_SPARSE_MAT_HDR(mat) \ + ((mat) != NULL && \ + (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL) + +#define CV_IS_SPARSE_MAT(mat) \ + CV_IS_SPARSE_MAT_HDR(mat) + +/**************** iteration through a sparse array *****************/ + +typedef struct CvSparseNode +{ + unsigned hashval; + struct CvSparseNode* next; +} +CvSparseNode; + +typedef struct CvSparseMatIterator +{ + CvSparseMat* mat; + CvSparseNode* node; + int curidx; +} +CvSparseMatIterator; + +#define CV_NODE_VAL(mat,node) ((void*)((uchar*)(node) + (mat)->valoffset)) +#define CV_NODE_IDX(mat,node) ((int*)((uchar*)(node) + (mat)->idxoffset)) + +/****************************************************************************************\ +* Histogram * +\****************************************************************************************/ + +typedef int CvHistType; + +#define CV_HIST_MAGIC_VAL 0x42450000 +#define CV_HIST_UNIFORM_FLAG (1 << 10) + +/* indicates whether bin ranges are set already or not */ +#define CV_HIST_RANGES_FLAG (1 << 11) + +#define CV_HIST_ARRAY 0 +#define CV_HIST_SPARSE 1 +#define CV_HIST_TREE CV_HIST_SPARSE + +/* should be used as a parameter only, + it turns to CV_HIST_UNIFORM_FLAG of hist->type */ +#define CV_HIST_UNIFORM 1 + +typedef struct CvHistogram +{ + int type; + CvArr* bins; + float thresh[CV_MAX_DIM][2]; /* For uniform histograms. */ + float** thresh2; /* For non-uniform histograms. */ + CvMatND mat; /* Embedded matrix header for array histograms. */ +} +CvHistogram; + +#define CV_IS_HIST( hist ) \ + ((hist) != NULL && \ + (((CvHistogram*)(hist))->type & CV_MAGIC_MASK) == CV_HIST_MAGIC_VAL && \ + (hist)->bins != NULL) + +#define CV_IS_UNIFORM_HIST( hist ) \ + (((hist)->type & CV_HIST_UNIFORM_FLAG) != 0) + +#define CV_IS_SPARSE_HIST( hist ) \ + CV_IS_SPARSE_MAT((hist)->bins) + +#define CV_HIST_HAS_RANGES( hist ) \ + (((hist)->type & CV_HIST_RANGES_FLAG) != 0) + +/****************************************************************************************\ +* Other supplementary data type definitions * +\****************************************************************************************/ + +/*************************************** CvRect *****************************************/ + +typedef struct CvRect +{ + int x; + int y; + int width; + int height; +} +CvRect; + +CV_INLINE CvRect cvRect( int x, int y, int width, int height ) +{ + CvRect r; + + r.x = x; + r.y = y; + r.width = width; + r.height = height; + + return r; +} + + +CV_INLINE IplROI cvRectToROI( CvRect rect, int coi ) +{ + IplROI roi; + roi.xOffset = rect.x; + roi.yOffset = rect.y; + roi.width = rect.width; + roi.height = rect.height; + roi.coi = coi; + + return roi; +} + + +CV_INLINE CvRect cvROIToRect( IplROI roi ) +{ + return cvRect( roi.xOffset, roi.yOffset, roi.width, roi.height ); +} + +/*********************************** CvTermCriteria *************************************/ + +#define CV_TERMCRIT_ITER 1 +#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER +#define CV_TERMCRIT_EPS 2 + +typedef struct CvTermCriteria +{ + int type; /* may be combination of + CV_TERMCRIT_ITER + CV_TERMCRIT_EPS */ + int max_iter; + double epsilon; +} +CvTermCriteria; + +CV_INLINE CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon ) +{ + CvTermCriteria t; + + t.type = type; + t.max_iter = max_iter; + t.epsilon = (float)epsilon; + + return t; +} + + +/******************************* CvPoint and variants ***********************************/ + +typedef struct CvPoint +{ + int x; + int y; +} +CvPoint; + + +CV_INLINE CvPoint cvPoint( int x, int y ) +{ + CvPoint p; + + p.x = x; + p.y = y; + + return p; +} + + +typedef struct CvPoint2D32f +{ + float x; + float y; +} +CvPoint2D32f; + + +CV_INLINE CvPoint2D32f cvPoint2D32f( double x, double y ) +{ + CvPoint2D32f p; + + p.x = (float)x; + p.y = (float)y; + + return p; +} + + +CV_INLINE CvPoint2D32f cvPointTo32f( CvPoint point ) +{ + return cvPoint2D32f( (float)point.x, (float)point.y ); +} + + +CV_INLINE CvPoint cvPointFrom32f( CvPoint2D32f point ) +{ + CvPoint ipt; + ipt.x = cvRound(point.x); + ipt.y = cvRound(point.y); + + return ipt; +} + + +typedef struct CvPoint3D32f +{ + float x; + float y; + float z; +} +CvPoint3D32f; + + +CV_INLINE CvPoint3D32f cvPoint3D32f( double x, double y, double z ) +{ + CvPoint3D32f p; + + p.x = (float)x; + p.y = (float)y; + p.z = (float)z; + + return p; +} + + +typedef struct CvPoint2D64f +{ + double x; + double y; +} +CvPoint2D64f; + + +CV_INLINE CvPoint2D64f cvPoint2D64f( double x, double y ) +{ + CvPoint2D64f p; + + p.x = x; + p.y = y; + + return p; +} + + +typedef struct CvPoint3D64f +{ + double x; + double y; + double z; +} +CvPoint3D64f; + + +CV_INLINE CvPoint3D64f cvPoint3D64f( double x, double y, double z ) +{ + CvPoint3D64f p; + + p.x = x; + p.y = y; + p.z = z; + + return p; +} + + +/******************************** CvSize's & CvBox **************************************/ + +typedef struct CvSize +{ + int width; + int height; +} +CvSize; + +CV_INLINE CvSize cvSize( int width, int height ) +{ + CvSize s; + + s.width = width; + s.height = height; + + return s; +} + +typedef struct CvSize2D32f +{ + float width; + float height; +} +CvSize2D32f; + + +CV_INLINE CvSize2D32f cvSize2D32f( double width, double height ) +{ + CvSize2D32f s; + + s.width = (float)width; + s.height = (float)height; + + return s; +} + +typedef struct CvBox2D +{ + CvPoint2D32f center; /* Center of the box. */ + CvSize2D32f size; /* Box width and length. */ + float angle; /* Angle between the horizontal axis */ + /* and the first side (i.e. length) in degrees */ +} +CvBox2D; + + +/* Line iterator state: */ +typedef struct CvLineIterator +{ + /* Pointer to the current point: */ + uchar* ptr; + + /* Bresenham algorithm state: */ + int err; + int plus_delta; + int minus_delta; + int plus_step; + int minus_step; +} +CvLineIterator; + + + +/************************************* CvSlice ******************************************/ + +typedef struct CvSlice +{ + int start_index, end_index; +} +CvSlice; + +CV_INLINE CvSlice cvSlice( int start, int end ) +{ + CvSlice slice; + slice.start_index = start; + slice.end_index = end; + + return slice; +} + +#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff +#define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) + + +/************************************* CvScalar *****************************************/ + +typedef struct CvScalar +{ + double val[4]; +} +CvScalar; + +CV_INLINE CvScalar cvScalar( double val0, double val1 CV_DEFAULT(0), + double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0)) +{ + CvScalar scalar; + scalar.val[0] = val0; scalar.val[1] = val1; + scalar.val[2] = val2; scalar.val[3] = val3; + return scalar; +} + + +CV_INLINE CvScalar cvRealScalar( double val0 ) +{ + CvScalar scalar; + scalar.val[0] = val0; + scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + return scalar; +} + +CV_INLINE CvScalar cvScalarAll( double val0123 ) +{ + CvScalar scalar; + scalar.val[0] = val0123; + scalar.val[1] = val0123; + scalar.val[2] = val0123; + scalar.val[3] = val0123; + return scalar; +} + +/****************************************************************************************\ +* Dynamic Data structures * +\****************************************************************************************/ + +/******************************** Memory storage ****************************************/ + +typedef struct CvMemBlock +{ + struct CvMemBlock* prev; + struct CvMemBlock* next; +} +CvMemBlock; + +#define CV_STORAGE_MAGIC_VAL 0x42890000 + +typedef struct CvMemStorage +{ + int signature; + CvMemBlock* bottom; /* First allocated block. */ + CvMemBlock* top; /* Current memory block - top of the stack. */ + struct CvMemStorage* parent; /* We get new blocks from parent as needed. */ + int block_size; /* Block size. */ + int free_space; /* Remaining free space in current block. */ +} +CvMemStorage; + +#define CV_IS_STORAGE(storage) \ + ((storage) != NULL && \ + (((CvMemStorage*)(storage))->signature & CV_MAGIC_MASK) == CV_STORAGE_MAGIC_VAL) + + +typedef struct CvMemStoragePos +{ + CvMemBlock* top; + int free_space; +} +CvMemStoragePos; + + +/*********************************** Sequence *******************************************/ + +typedef struct CvSeqBlock +{ + struct CvSeqBlock* prev; /* Previous sequence block. */ + struct CvSeqBlock* next; /* Next sequence block. */ + int start_index; /* Index of the first element in the block + */ + /* sequence->first->start_index. */ + int count; /* Number of elements in the block. */ + schar* data; /* Pointer to the first element of the block. */ +} +CvSeqBlock; + + +#define CV_TREE_NODE_FIELDS(node_type) \ + int flags; /* Miscellaneous flags. */ \ + int header_size; /* Size of sequence header. */ \ + struct node_type* h_prev; /* Previous sequence. */ \ + struct node_type* h_next; /* Next sequence. */ \ + struct node_type* v_prev; /* 2nd previous sequence. */ \ + struct node_type* v_next /* 2nd next sequence. */ + +/* + Read/Write sequence. + Elements can be dynamically inserted to or deleted from the sequence. +*/ +#define CV_SEQUENCE_FIELDS() \ + CV_TREE_NODE_FIELDS(CvSeq); \ + int total; /* Total number of elements. */ \ + int elem_size; /* Size of sequence element in bytes. */ \ + schar* block_max; /* Maximal bound of the last block. */ \ + schar* ptr; /* Current write pointer. */ \ + int delta_elems; /* Grow seq this many at a time. */ \ + CvMemStorage* storage; /* Where the seq is stored. */ \ + CvSeqBlock* free_blocks; /* Free blocks list. */ \ + CvSeqBlock* first; /* Pointer to the first sequence block. */ + +typedef struct CvSeq +{ + CV_SEQUENCE_FIELDS() +} +CvSeq; + +#define CV_TYPE_NAME_SEQ "opencv-sequence" +#define CV_TYPE_NAME_SEQ_TREE "opencv-sequence-tree" + +/*************************************** Set ********************************************/ +/* + Set. + Order is not preserved. There can be gaps between sequence elements. + After the element has been inserted it stays in the same place all the time. + The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists. +*/ +#define CV_SET_ELEM_FIELDS(elem_type) \ + int flags; \ + struct elem_type* next_free; + +typedef struct CvSetElem +{ + CV_SET_ELEM_FIELDS(CvSetElem) +} +CvSetElem; + +#define CV_SET_FIELDS() \ + CV_SEQUENCE_FIELDS() \ + CvSetElem* free_elems; \ + int active_count; + +typedef struct CvSet +{ + CV_SET_FIELDS() +} +CvSet; + + +#define CV_SET_ELEM_IDX_MASK ((1 << 26) - 1) +#define CV_SET_ELEM_FREE_FLAG (1 << (sizeof(int)*8-1)) + +/* Checks whether the element pointed by ptr belongs to a set or not */ +#define CV_IS_SET_ELEM( ptr ) (((CvSetElem*)(ptr))->flags >= 0) + +/************************************* Graph ********************************************/ + +/* + We represent a graph as a set of vertices. + Vertices contain their adjacency lists (more exactly, pointers to first incoming or + outcoming edge (or 0 if isolated vertex)). Edges are stored in another set. + There is a singly-linked list of incoming/outcoming edges for each vertex. + + Each edge consists of + + o Two pointers to the starting and ending vertices + (vtx[0] and vtx[1] respectively). + + A graph may be oriented or not. In the latter case, edges between + vertex i to vertex j are not distinguished during search operations. + + o Two pointers to next edges for the starting and ending vertices, where + next[0] points to the next edge in the vtx[0] adjacency list and + next[1] points to the next edge in the vtx[1] adjacency list. +*/ +#define CV_GRAPH_EDGE_FIELDS() \ + int flags; \ + float weight; \ + struct CvGraphEdge* next[2]; \ + struct CvGraphVtx* vtx[2]; + + +#define CV_GRAPH_VERTEX_FIELDS() \ + int flags; \ + struct CvGraphEdge* first; + + +typedef struct CvGraphEdge +{ + CV_GRAPH_EDGE_FIELDS() +} +CvGraphEdge; + +typedef struct CvGraphVtx +{ + CV_GRAPH_VERTEX_FIELDS() +} +CvGraphVtx; + +typedef struct CvGraphVtx2D +{ + CV_GRAPH_VERTEX_FIELDS() + CvPoint2D32f* ptr; +} +CvGraphVtx2D; + +/* + Graph is "derived" from the set (this is set a of vertices) + and includes another set (edges) +*/ +#define CV_GRAPH_FIELDS() \ + CV_SET_FIELDS() \ + CvSet* edges; + +typedef struct CvGraph +{ + CV_GRAPH_FIELDS() +} +CvGraph; + +#define CV_TYPE_NAME_GRAPH "opencv-graph" + +/*********************************** Chain/Countour *************************************/ + +typedef struct CvChain +{ + CV_SEQUENCE_FIELDS() + CvPoint origin; +} +CvChain; + +#define CV_CONTOUR_FIELDS() \ + CV_SEQUENCE_FIELDS() \ + CvRect rect; \ + int color; \ + int reserved[3]; + +typedef struct CvContour +{ + CV_CONTOUR_FIELDS() +} +CvContour; + +typedef CvContour CvPoint2DSeq; + +/****************************************************************************************\ +* Sequence types * +\****************************************************************************************/ + +#define CV_SEQ_MAGIC_VAL 0x42990000 + +#define CV_IS_SEQ(seq) \ + ((seq) != NULL && (((CvSeq*)(seq))->flags & CV_MAGIC_MASK) == CV_SEQ_MAGIC_VAL) + +#define CV_SET_MAGIC_VAL 0x42980000 +#define CV_IS_SET(set) \ + ((set) != NULL && (((CvSeq*)(set))->flags & CV_MAGIC_MASK) == CV_SET_MAGIC_VAL) + +#define CV_SEQ_ELTYPE_BITS 12 +#define CV_SEQ_ELTYPE_MASK ((1 << CV_SEQ_ELTYPE_BITS) - 1) + +#define CV_SEQ_ELTYPE_POINT CV_32SC2 /* (x,y) */ +#define CV_SEQ_ELTYPE_CODE CV_8UC1 /* freeman code: 0..7 */ +#define CV_SEQ_ELTYPE_GENERIC 0 +#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1 +#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &(x,y) */ +#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #(x,y) */ +#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /* &next_o, &next_d, &vtx_o, &vtx_d */ +#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /* first_edge, &(x,y) */ +#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /* vertex of the binary tree */ +#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /* connected component */ +#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */ + +#define CV_SEQ_KIND_BITS 2 +#define CV_SEQ_KIND_MASK (((1 << CV_SEQ_KIND_BITS) - 1)<flags & CV_SEQ_ELTYPE_MASK) +#define CV_SEQ_KIND( seq ) ((seq)->flags & CV_SEQ_KIND_MASK ) + +/* flag checking */ +#define CV_IS_SEQ_INDEX( seq ) ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC)) + +#define CV_IS_SEQ_CURVE( seq ) (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE) +#define CV_IS_SEQ_CLOSED( seq ) (((seq)->flags & CV_SEQ_FLAG_CLOSED) != 0) +#define CV_IS_SEQ_CONVEX( seq ) 0 +#define CV_IS_SEQ_HOLE( seq ) (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0) +#define CV_IS_SEQ_SIMPLE( seq ) 1 + +/* type checking macros */ +#define CV_IS_SEQ_POINT_SET( seq ) \ + ((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2)) + +#define CV_IS_SEQ_POINT_SUBSET( seq ) \ + (CV_IS_SEQ_INDEX( seq ) || CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_PPOINT) + +#define CV_IS_SEQ_POLYLINE( seq ) \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && CV_IS_SEQ_POINT_SET(seq)) + +#define CV_IS_SEQ_POLYGON( seq ) \ + (CV_IS_SEQ_POLYLINE(seq) && CV_IS_SEQ_CLOSED(seq)) + +#define CV_IS_SEQ_CHAIN( seq ) \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && (seq)->elem_size == 1) + +#define CV_IS_SEQ_CONTOUR( seq ) \ + (CV_IS_SEQ_CLOSED(seq) && (CV_IS_SEQ_POLYLINE(seq) || CV_IS_SEQ_CHAIN(seq))) + +#define CV_IS_SEQ_CHAIN_CONTOUR( seq ) \ + (CV_IS_SEQ_CHAIN( seq ) && CV_IS_SEQ_CLOSED( seq )) + +#define CV_IS_SEQ_POLYGON_TREE( seq ) \ + (CV_SEQ_ELTYPE (seq) == CV_SEQ_ELTYPE_TRIAN_ATR && \ + CV_SEQ_KIND( seq ) == CV_SEQ_KIND_BIN_TREE ) + +#define CV_IS_GRAPH( seq ) \ + (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_GRAPH) + +#define CV_IS_GRAPH_ORIENTED( seq ) \ + (((seq)->flags & CV_GRAPH_FLAG_ORIENTED) != 0) + +#define CV_IS_SUBDIV2D( seq ) \ + (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_SUBDIV2D) + +/****************************************************************************************/ +/* Sequence writer & reader */ +/****************************************************************************************/ + +#define CV_SEQ_WRITER_FIELDS() \ + int header_size; \ + CvSeq* seq; /* the sequence written */ \ + CvSeqBlock* block; /* current block */ \ + schar* ptr; /* pointer to free space */ \ + schar* block_min; /* pointer to the beginning of block*/\ + schar* block_max; /* pointer to the end of block */ + +typedef struct CvSeqWriter +{ + CV_SEQ_WRITER_FIELDS() +} +CvSeqWriter; + + +#define CV_SEQ_READER_FIELDS() \ + int header_size; \ + CvSeq* seq; /* sequence, beign read */ \ + CvSeqBlock* block; /* current block */ \ + schar* ptr; /* pointer to element be read next */ \ + schar* block_min; /* pointer to the beginning of block */\ + schar* block_max; /* pointer to the end of block */ \ + int delta_index;/* = seq->first->start_index */ \ + schar* prev_elem; /* pointer to previous element */ + + +typedef struct CvSeqReader +{ + CV_SEQ_READER_FIELDS() +} +CvSeqReader; + +/****************************************************************************************/ +/* Operations on sequences */ +/****************************************************************************************/ + +#define CV_SEQ_ELEM( seq, elem_type, index ) \ +/* assert gives some guarantee that parameter is valid */ \ +( assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) && \ + (seq)->elem_size == sizeof(elem_type)), \ + (elem_type*)((seq)->first && (unsigned)index < \ + (unsigned)((seq)->first->count) ? \ + (seq)->first->data + (index) * sizeof(elem_type) : \ + cvGetSeqElem( (CvSeq*)(seq), (index) ))) +#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) ) + +/* Add element to sequence: */ +#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer ) \ +{ \ + if( (writer).ptr >= (writer).block_max ) \ + { \ + cvCreateSeqBlock( &writer); \ + } \ + memcpy((writer).ptr, elem_ptr, (writer).seq->elem_size);\ + (writer).ptr += (writer).seq->elem_size; \ +} + +#define CV_WRITE_SEQ_ELEM( elem, writer ) \ +{ \ + assert( (writer).seq->elem_size == sizeof(elem)); \ + if( (writer).ptr >= (writer).block_max ) \ + { \ + cvCreateSeqBlock( &writer); \ + } \ + assert( (writer).ptr <= (writer).block_max - sizeof(elem));\ + memcpy((writer).ptr, &(elem), sizeof(elem)); \ + (writer).ptr += sizeof(elem); \ +} + + +/* Move reader position forward: */ +#define CV_NEXT_SEQ_ELEM( elem_size, reader ) \ +{ \ + if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \ + { \ + cvChangeSeqBlock( &(reader), 1 ); \ + } \ +} + + +/* Move reader position backward: */ +#define CV_PREV_SEQ_ELEM( elem_size, reader ) \ +{ \ + if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \ + { \ + cvChangeSeqBlock( &(reader), -1 ); \ + } \ +} + +/* Read element and move read position forward: */ +#define CV_READ_SEQ_ELEM( elem, reader ) \ +{ \ + assert( (reader).seq->elem_size == sizeof(elem)); \ + memcpy( &(elem), (reader).ptr, sizeof((elem))); \ + CV_NEXT_SEQ_ELEM( sizeof(elem), reader ) \ +} + +/* Read element and move read position backward: */ +#define CV_REV_READ_SEQ_ELEM( elem, reader ) \ +{ \ + assert( (reader).seq->elem_size == sizeof(elem)); \ + memcpy(&(elem), (reader).ptr, sizeof((elem))); \ + CV_PREV_SEQ_ELEM( sizeof(elem), reader ) \ +} + + +#define CV_READ_CHAIN_POINT( _pt, reader ) \ +{ \ + (_pt) = (reader).pt; \ + if( (reader).ptr ) \ + { \ + CV_READ_SEQ_ELEM( (reader).code, (reader)); \ + assert( ((reader).code & ~7) == 0 ); \ + (reader).pt.x += (reader).deltas[(int)(reader).code][0]; \ + (reader).pt.y += (reader).deltas[(int)(reader).code][1]; \ + } \ +} + +#define CV_CURRENT_POINT( reader ) (*((CvPoint*)((reader).ptr))) +#define CV_PREV_POINT( reader ) (*((CvPoint*)((reader).prev_elem))) + +#define CV_READ_EDGE( pt1, pt2, reader ) \ +{ \ + assert( sizeof(pt1) == sizeof(CvPoint) && \ + sizeof(pt2) == sizeof(CvPoint) && \ + reader.seq->elem_size == sizeof(CvPoint)); \ + (pt1) = CV_PREV_POINT( reader ); \ + (pt2) = CV_CURRENT_POINT( reader ); \ + (reader).prev_elem = (reader).ptr; \ + CV_NEXT_SEQ_ELEM( sizeof(CvPoint), (reader)); \ +} + +/************ Graph macros ************/ + +/* Return next graph edge for given vertex: */ +#define CV_NEXT_GRAPH_EDGE( edge, vertex ) \ + (assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)), \ + (edge)->next[(edge)->vtx[1] == (vertex)]) + + + +/****************************************************************************************\ +* Data structures for persistence (a.k.a serialization) functionality * +\****************************************************************************************/ + +/* "black box" file storage */ +typedef struct CvFileStorage CvFileStorage; + +/* Storage flags: */ +#define CV_STORAGE_READ 0 +#define CV_STORAGE_WRITE 1 +#define CV_STORAGE_WRITE_TEXT CV_STORAGE_WRITE +#define CV_STORAGE_WRITE_BINARY CV_STORAGE_WRITE +#define CV_STORAGE_APPEND 2 +#define CV_STORAGE_MEMORY 4 +#define CV_STORAGE_FORMAT_MASK (7<<3) +#define CV_STORAGE_FORMAT_AUTO 0 +#define CV_STORAGE_FORMAT_XML 8 +#define CV_STORAGE_FORMAT_YAML 16 + +/* List of attributes: */ +typedef struct CvAttrList +{ + const char** attr; /* NULL-terminated array of (attribute_name,attribute_value) pairs. */ + struct CvAttrList* next; /* Pointer to next chunk of the attributes list. */ +} +CvAttrList; + +CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL), + CvAttrList* next CV_DEFAULT(NULL) ) +{ + CvAttrList l; + l.attr = attr; + l.next = next; + + return l; +} + +struct CvTypeInfo; + +#define CV_NODE_NONE 0 +#define CV_NODE_INT 1 +#define CV_NODE_INTEGER CV_NODE_INT +#define CV_NODE_REAL 2 +#define CV_NODE_FLOAT CV_NODE_REAL +#define CV_NODE_STR 3 +#define CV_NODE_STRING CV_NODE_STR +#define CV_NODE_REF 4 /* not used */ +#define CV_NODE_SEQ 5 +#define CV_NODE_MAP 6 +#define CV_NODE_TYPE_MASK 7 + +#define CV_NODE_TYPE(flags) ((flags) & CV_NODE_TYPE_MASK) + +/* file node flags */ +#define CV_NODE_FLOW 8 /* Used only for writing structures in YAML format. */ +#define CV_NODE_USER 16 +#define CV_NODE_EMPTY 32 +#define CV_NODE_NAMED 64 + +#define CV_NODE_IS_INT(flags) (CV_NODE_TYPE(flags) == CV_NODE_INT) +#define CV_NODE_IS_REAL(flags) (CV_NODE_TYPE(flags) == CV_NODE_REAL) +#define CV_NODE_IS_STRING(flags) (CV_NODE_TYPE(flags) == CV_NODE_STRING) +#define CV_NODE_IS_SEQ(flags) (CV_NODE_TYPE(flags) == CV_NODE_SEQ) +#define CV_NODE_IS_MAP(flags) (CV_NODE_TYPE(flags) == CV_NODE_MAP) +#define CV_NODE_IS_COLLECTION(flags) (CV_NODE_TYPE(flags) >= CV_NODE_SEQ) +#define CV_NODE_IS_FLOW(flags) (((flags) & CV_NODE_FLOW) != 0) +#define CV_NODE_IS_EMPTY(flags) (((flags) & CV_NODE_EMPTY) != 0) +#define CV_NODE_IS_USER(flags) (((flags) & CV_NODE_USER) != 0) +#define CV_NODE_HAS_NAME(flags) (((flags) & CV_NODE_NAMED) != 0) + +#define CV_NODE_SEQ_SIMPLE 256 +#define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0) + +typedef struct CvString +{ + int len; + char* ptr; +} +CvString; + +/* All the keys (names) of elements in the readed file storage + are stored in the hash to speed up the lookup operations: */ +typedef struct CvStringHashNode +{ + unsigned hashval; + CvString str; + struct CvStringHashNode* next; +} +CvStringHashNode; + +typedef struct CvGenericHash CvFileNodeHash; + +/* Basic element of the file storage - scalar or collection: */ +typedef struct CvFileNode +{ + int tag; + struct CvTypeInfo* info; /* type information + (only for user-defined object, for others it is 0) */ + union + { + double f; /* scalar floating-point number */ + int i; /* scalar integer number */ + CvString str; /* text string */ + CvSeq* seq; /* sequence (ordered collection of file nodes) */ + CvFileNodeHash* map; /* map (collection of named file nodes) */ + } data; +} +CvFileNode; + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr ); +typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr ); +typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); +typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name, + const void* struct_ptr, CvAttrList attributes ); +typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr ); +#ifdef __cplusplus +} +#endif + +typedef struct CvTypeInfo +{ + int flags; + int header_size; + struct CvTypeInfo* prev; + struct CvTypeInfo* next; + const char* type_name; + CvIsInstanceFunc is_instance; + CvReleaseFunc release; + CvReadFunc read; + CvWriteFunc write; + CvCloneFunc clone; +} +CvTypeInfo; + + +/**** System data types ******/ + +typedef struct CvPluginFuncInfo +{ + void** func_addr; + void* default_func_addr; + const char* func_names; + int search_modules; + int loaded_from; +} +CvPluginFuncInfo; + +typedef struct CvModuleInfo +{ + struct CvModuleInfo* next; + const char* name; + const char* version; + CvPluginFuncInfo* func_tab; +} +CvModuleInfo; + +#endif /*__OPENCV_CORE_TYPES_H__*/ + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/version.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/version.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/version.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/version.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,69 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright( C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +//(including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort(including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* + definition of the current version of OpenCV + Usefull to test in user programs +*/ + +#ifndef __OPENCV_VERSION_HPP__ +#define __OPENCV_VERSION_HPP__ + +#define CV_VERSION_EPOCH 2 +#define CV_VERSION_MAJOR 4 +#define CV_VERSION_MINOR 5 +#define CV_VERSION_REVISION 0 + +#define CVAUX_STR_EXP(__A) #__A +#define CVAUX_STR(__A) CVAUX_STR_EXP(__A) + +#if CV_VERSION_REVISION +# define CV_VERSION CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) +#else +# define CV_VERSION CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) +#endif + +/* old style version constants*/ +#define CV_MAJOR_VERSION CV_VERSION_EPOCH +#define CV_MINOR_VERSION CV_VERSION_MAJOR +#define CV_SUBMINOR_VERSION CV_VERSION_MINOR + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/wimage.hpp diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/wimage.hpp --- diffimg-1.5.0/3rdparty/opencv/core/include/opencv2/core/wimage.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/include/opencv2/core/wimage.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,621 @@ +/////////////////////////////////////////////////////////////////////////////// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to +// this license. If you do not agree to this license, do not download, +// install, copy or use the software. +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2008, Google, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation or contributors may not be used to endorse +// or promote products derived from this software without specific +// prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" +// and any express or implied warranties, including, but not limited to, the +// implied warranties of merchantability and fitness for a particular purpose +// are disclaimed. In no event shall the Intel Corporation or contributors be +// liable for any direct, indirect, incidental, special, exemplary, or +// consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. + + +///////////////////////////////////////////////////////////////////////////////// +// +// Image class which provides a thin layer around an IplImage. The goals +// of the class design are: +// 1. All the data has explicit ownership to avoid memory leaks +// 2. No hidden allocations or copies for performance. +// 3. Easy access to OpenCV methods (which will access IPP if available) +// 4. Can easily treat external data as an image +// 5. Easy to create images which are subsets of other images +// 6. Fast pixel access which can take advantage of number of channels +// if known at compile time. +// +// The WImage class is the image class which provides the data accessors. +// The 'W' comes from the fact that it is also a wrapper around the popular +// but inconvenient IplImage class. A WImage can be constructed either using a +// WImageBuffer class which allocates and frees the data, +// or using a WImageView class which constructs a subimage or a view into +// external data. The view class does no memory management. Each class +// actually has two versions, one when the number of channels is known at +// compile time and one when it isn't. Using the one with the number of +// channels specified can provide some compile time optimizations by using the +// fact that the number of channels is a constant. +// +// We use the convention (c,r) to refer to column c and row r with (0,0) being +// the upper left corner. This is similar to standard Euclidean coordinates +// with the first coordinate varying in the horizontal direction and the second +// coordinate varying in the vertical direction. +// Thus (c,r) is usually in the domain [0, width) X [0, height) +// +// Example usage: +// WImageBuffer3_b im(5,7); // Make a 5X7 3 channel image of type uchar +// WImageView3_b sub_im(im, 2,2, 3,3); // 3X3 submatrix +// vector vec(10, 3.0f); +// WImageView1_f user_im(&vec[0], 2, 5); // 2X5 image w/ supplied data +// +// im.SetZero(); // same as cvSetZero(im.Ipl()) +// *im(2, 3) = 15; // Modify the element at column 2, row 3 +// MySetRand(&sub_im); +// +// // Copy the second row into the first. This can be done with no memory +// // allocation and will use SSE if IPP is available. +// int w = im.Width(); +// im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1)); +// +// // Doesn't care about source of data since using WImage +// void MySetRand(WImage_b* im) { // Works with any number of channels +// for (int r = 0; r < im->Height(); ++r) { +// float* row = im->Row(r); +// for (int c = 0; c < im->Width(); ++c) { +// for (int ch = 0; ch < im->Channels(); ++ch, ++row) { +// *row = uchar(rand() & 255); +// } +// } +// } +// } +// +// Functions that are not part of the basic image allocation, viewing, and +// access should come from OpenCV, except some useful functions that are not +// part of OpenCV can be found in wimage_util.h +#ifndef __OPENCV_CORE_WIMAGE_HPP__ +#define __OPENCV_CORE_WIMAGE_HPP__ + +#include "opencv2/core/core_c.h" + +#ifdef __cplusplus + +namespace cv { + +template class WImage; +template class WImageBuffer; +template class WImageView; + +template class WImageC; +template class WImageBufferC; +template class WImageViewC; + +// Commonly used typedefs. +typedef WImage WImage_b; +typedef WImageView WImageView_b; +typedef WImageBuffer WImageBuffer_b; + +typedef WImageC WImage1_b; +typedef WImageViewC WImageView1_b; +typedef WImageBufferC WImageBuffer1_b; + +typedef WImageC WImage3_b; +typedef WImageViewC WImageView3_b; +typedef WImageBufferC WImageBuffer3_b; + +typedef WImage WImage_f; +typedef WImageView WImageView_f; +typedef WImageBuffer WImageBuffer_f; + +typedef WImageC WImage1_f; +typedef WImageViewC WImageView1_f; +typedef WImageBufferC WImageBuffer1_f; + +typedef WImageC WImage3_f; +typedef WImageViewC WImageView3_f; +typedef WImageBufferC WImageBuffer3_f; + +// There isn't a standard for signed and unsigned short so be more +// explicit in the typename for these cases. +typedef WImage WImage_16s; +typedef WImageView WImageView_16s; +typedef WImageBuffer WImageBuffer_16s; + +typedef WImageC WImage1_16s; +typedef WImageViewC WImageView1_16s; +typedef WImageBufferC WImageBuffer1_16s; + +typedef WImageC WImage3_16s; +typedef WImageViewC WImageView3_16s; +typedef WImageBufferC WImageBuffer3_16s; + +typedef WImage WImage_16u; +typedef WImageView WImageView_16u; +typedef WImageBuffer WImageBuffer_16u; + +typedef WImageC WImage1_16u; +typedef WImageViewC WImageView1_16u; +typedef WImageBufferC WImageBuffer1_16u; + +typedef WImageC WImage3_16u; +typedef WImageViewC WImageView3_16u; +typedef WImageBufferC WImageBuffer3_16u; + +// +// WImage definitions +// +// This WImage class gives access to the data it refers to. It can be +// constructed either by allocating the data with a WImageBuffer class or +// using the WImageView class to refer to a subimage or outside data. +template +class WImage +{ +public: + typedef T BaseType; + + // WImage is an abstract class with no other virtual methods so make the + // destructor virtual. + virtual ~WImage() = 0; + + // Accessors + IplImage* Ipl() {return image_; } + const IplImage* Ipl() const {return image_; } + T* ImageData() { return reinterpret_cast(image_->imageData); } + const T* ImageData() const { + return reinterpret_cast(image_->imageData); + } + + int Width() const {return image_->width; } + int Height() const {return image_->height; } + + // WidthStep is the number of bytes to go to the pixel with the next y coord + int WidthStep() const {return image_->widthStep; } + + int Channels() const {return image_->nChannels; } + int ChannelSize() const {return sizeof(T); } // number of bytes per channel + + // Number of bytes per pixel + int PixelSize() const {return Channels() * ChannelSize(); } + + // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number + // of bits per channel and with the signed bit set. + // This is known at compile time using specializations. + int Depth() const; + + inline const T* Row(int r) const { + return reinterpret_cast(image_->imageData + r*image_->widthStep); + } + + inline T* Row(int r) { + return reinterpret_cast(image_->imageData + r*image_->widthStep); + } + + // Pixel accessors which returns a pointer to the start of the channel + inline T* operator() (int c, int r) { + return reinterpret_cast(image_->imageData + r*image_->widthStep) + + c*Channels(); + } + + inline const T* operator() (int c, int r) const { + return reinterpret_cast(image_->imageData + r*image_->widthStep) + + c*Channels(); + } + + // Copy the contents from another image which is just a convenience to cvCopy + void CopyFrom(const WImage& src) { cvCopy(src.Ipl(), image_); } + + // Set contents to zero which is just a convenient to cvSetZero + void SetZero() { cvSetZero(image_); } + + // Construct a view into a region of this image + WImageView View(int c, int r, int width, int height); + +protected: + // Disallow copy and assignment + WImage(const WImage&); + void operator=(const WImage&); + + explicit WImage(IplImage* img) : image_(img) { + assert(!img || img->depth == Depth()); + } + + void SetIpl(IplImage* image) { + assert(!image || image->depth == Depth()); + image_ = image; + } + + IplImage* image_; +}; + + + +// Image class when both the pixel type and number of channels +// are known at compile time. This wrapper will speed up some of the operations +// like accessing individual pixels using the () operator. +template +class WImageC : public WImage +{ +public: + typedef typename WImage::BaseType BaseType; + enum { kChannels = C }; + + explicit WImageC(IplImage* img) : WImage(img) { + assert(!img || img->nChannels == Channels()); + } + + // Construct a view into a region of this image + WImageViewC View(int c, int r, int width, int height); + + // Copy the contents from another image which is just a convenience to cvCopy + void CopyFrom(const WImageC& src) { + cvCopy(src.Ipl(), WImage::image_); + } + + // WImageC is an abstract class with no other virtual methods so make the + // destructor virtual. + virtual ~WImageC() = 0; + + int Channels() const {return C; } + +protected: + // Disallow copy and assignment + WImageC(const WImageC&); + void operator=(const WImageC&); + + void SetIpl(IplImage* image) { + assert(!image || image->depth == WImage::Depth()); + WImage::SetIpl(image); + } +}; + +// +// WImageBuffer definitions +// +// Image class which owns the data, so it can be allocated and is always +// freed. It cannot be copied but can be explicity cloned. +// +template +class WImageBuffer : public WImage +{ +public: + typedef typename WImage::BaseType BaseType; + + // Default constructor which creates an object that can be + WImageBuffer() : WImage(0) {} + + WImageBuffer(int width, int height, int nchannels) : WImage(0) { + Allocate(width, height, nchannels); + } + + // Constructor which takes ownership of a given IplImage so releases + // the image on destruction. + explicit WImageBuffer(IplImage* img) : WImage(img) {} + + // Allocate an image. Does nothing if current size is the same as + // the new size. + void Allocate(int width, int height, int nchannels); + + // Set the data to point to an image, releasing the old data + void SetIpl(IplImage* img) { + ReleaseImage(); + WImage::SetIpl(img); + } + + // Clone an image which reallocates the image if of a different dimension. + void CloneFrom(const WImage& src) { + Allocate(src.Width(), src.Height(), src.Channels()); + CopyFrom(src); + } + + ~WImageBuffer() { + ReleaseImage(); + } + + // Release the image if it isn't null. + void ReleaseImage() { + if (WImage::image_) { + IplImage* image = WImage::image_; + cvReleaseImage(&image); + WImage::SetIpl(0); + } + } + + bool IsNull() const {return WImage::image_ == NULL; } + +private: + // Disallow copy and assignment + WImageBuffer(const WImageBuffer&); + void operator=(const WImageBuffer&); +}; + +// Like a WImageBuffer class but when the number of channels is known +// at compile time. +template +class WImageBufferC : public WImageC +{ +public: + typedef typename WImage::BaseType BaseType; + enum { kChannels = C }; + + // Default constructor which creates an object that can be + WImageBufferC() : WImageC(0) {} + + WImageBufferC(int width, int height) : WImageC(0) { + Allocate(width, height); + } + + // Constructor which takes ownership of a given IplImage so releases + // the image on destruction. + explicit WImageBufferC(IplImage* img) : WImageC(img) {} + + // Allocate an image. Does nothing if current size is the same as + // the new size. + void Allocate(int width, int height); + + // Set the data to point to an image, releasing the old data + void SetIpl(IplImage* img) { + ReleaseImage(); + WImageC::SetIpl(img); + } + + // Clone an image which reallocates the image if of a different dimension. + void CloneFrom(const WImageC& src) { + Allocate(src.Width(), src.Height()); + CopyFrom(src); + } + + ~WImageBufferC() { + ReleaseImage(); + } + + // Release the image if it isn't null. + void ReleaseImage() { + if (WImage::image_) { + IplImage* image = WImage::image_; + cvReleaseImage(&image); + WImageC::SetIpl(0); + } + } + + bool IsNull() const {return WImage::image_ == NULL; } + +private: + // Disallow copy and assignment + WImageBufferC(const WImageBufferC&); + void operator=(const WImageBufferC&); +}; + +// +// WImageView definitions +// +// View into an image class which allows treating a subimage as an image +// or treating external data as an image +// +template +class WImageView : public WImage +{ +public: + typedef typename WImage::BaseType BaseType; + + // Construct a subimage. No checks are done that the subimage lies + // completely inside the original image. + WImageView(WImage* img, int c, int r, int width, int height); + + // Refer to external data. + // If not given width_step assumed to be same as width. + WImageView(T* data, int width, int height, int channels, int width_step = -1); + + // Refer to external data. This does NOT take ownership + // of the supplied IplImage. + WImageView(IplImage* img) : WImage(img) {} + + // Copy constructor + WImageView(const WImage& img) : WImage(0) { + header_ = *(img.Ipl()); + WImage::SetIpl(&header_); + } + + WImageView& operator=(const WImage& img) { + header_ = *(img.Ipl()); + WImage::SetIpl(&header_); + return *this; + } + +protected: + IplImage header_; +}; + + +template +class WImageViewC : public WImageC +{ +public: + typedef typename WImage::BaseType BaseType; + enum { kChannels = C }; + + // Default constructor needed for vectors of views. + WImageViewC(); + + virtual ~WImageViewC() {} + + // Construct a subimage. No checks are done that the subimage lies + // completely inside the original image. + WImageViewC(WImageC* img, + int c, int r, int width, int height); + + // Refer to external data + WImageViewC(T* data, int width, int height, int width_step = -1); + + // Refer to external data. This does NOT take ownership + // of the supplied IplImage. + WImageViewC(IplImage* img) : WImageC(img) {} + + // Copy constructor which does a shallow copy to allow multiple views + // of same data. gcc-4.1.1 gets confused if both versions of + // the constructor and assignment operator are not provided. + WImageViewC(const WImageC& img) : WImageC(0) { + header_ = *(img.Ipl()); + WImageC::SetIpl(&header_); + } + WImageViewC(const WImageViewC& img) : WImageC(0) { + header_ = *(img.Ipl()); + WImageC::SetIpl(&header_); + } + + WImageViewC& operator=(const WImageC& img) { + header_ = *(img.Ipl()); + WImageC::SetIpl(&header_); + return *this; + } + WImageViewC& operator=(const WImageViewC& img) { + header_ = *(img.Ipl()); + WImageC::SetIpl(&header_); + return *this; + } + +protected: + IplImage header_; +}; + + +// Specializations for depth +template<> +inline int WImage::Depth() const {return IPL_DEPTH_8U; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_8S; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_16S; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_16U; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_32S; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_32F; } +template<> +inline int WImage::Depth() const {return IPL_DEPTH_64F; } + +// +// Pure virtual destructors still need to be defined. +// +template inline WImage::~WImage() {} +template inline WImageC::~WImageC() {} + +// +// Allocate ImageData +// +template +inline void WImageBuffer::Allocate(int width, int height, int nchannels) +{ + if (IsNull() || WImage::Width() != width || + WImage::Height() != height || WImage::Channels() != nchannels) { + ReleaseImage(); + WImage::image_ = cvCreateImage(cvSize(width, height), + WImage::Depth(), nchannels); + } +} + +template +inline void WImageBufferC::Allocate(int width, int height) +{ + if (IsNull() || WImage::Width() != width || WImage::Height() != height) { + ReleaseImage(); + WImageC::SetIpl(cvCreateImage(cvSize(width, height),WImage::Depth(), C)); + } +} + +// +// ImageView methods +// +template +WImageView::WImageView(WImage* img, int c, int r, int width, int height) + : WImage(0) +{ + header_ = *(img->Ipl()); + header_.imageData = reinterpret_cast((*img)(c, r)); + header_.width = width; + header_.height = height; + WImage::SetIpl(&header_); +} + +template +WImageView::WImageView(T* data, int width, int height, int nchannels, int width_step) + : WImage(0) +{ + cvInitImageHeader(&header_, cvSize(width, height), WImage::Depth(), nchannels); + header_.imageData = reinterpret_cast(data); + if (width_step > 0) { + header_.widthStep = width_step; + } + WImage::SetIpl(&header_); +} + +template +WImageViewC::WImageViewC(WImageC* img, int c, int r, int width, int height) + : WImageC(0) +{ + header_ = *(img->Ipl()); + header_.imageData = reinterpret_cast((*img)(c, r)); + header_.width = width; + header_.height = height; + WImageC::SetIpl(&header_); +} + +template +WImageViewC::WImageViewC() : WImageC(0) { + cvInitImageHeader(&header_, cvSize(0, 0), WImage::Depth(), C); + header_.imageData = reinterpret_cast(0); + WImageC::SetIpl(&header_); +} + +template +WImageViewC::WImageViewC(T* data, int width, int height, int width_step) + : WImageC(0) +{ + cvInitImageHeader(&header_, cvSize(width, height), WImage::Depth(), C); + header_.imageData = reinterpret_cast(data); + if (width_step > 0) { + header_.widthStep = width_step; + } + WImageC::SetIpl(&header_); +} + +// Construct a view into a region of an image +template +WImageView WImage::View(int c, int r, int width, int height) { + return WImageView(this, c, r, width, height); +} + +template +WImageViewC WImageC::View(int c, int r, int width, int height) { + return WImageViewC(this, c, r, width, height); +} + +} // end of namespace + +#endif // __cplusplus + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_abs.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_abs.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_abs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_abs.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,27 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_SIZES_ABS TYPICAL_MAT_SIZES +#define TYPICAL_MAT_TYPES_ABS CV_8SC1, CV_8SC4, CV_32SC1, CV_32FC1 +#define TYPICAL_MATS_ABS testing::Combine( testing::Values( TYPICAL_MAT_SIZES_ABS), testing::Values( TYPICAL_MAT_TYPES_ABS) ) + +PERF_TEST_P(Size_MatType, abs, TYPICAL_MATS_ABS) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + cv::Mat a = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, WARMUP_RNG).out(c); + + TEST_CYCLE() c = cv::abs(a); + + SANITY_CHECK(c); +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_addWeighted.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_addWeighted.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_addWeighted.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_addWeighted.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,36 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_TYPES_ADWEIGHTED CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1 +#define TYPICAL_MATS_ADWEIGHTED testing::Combine(testing::Values(szVGA, sz720p, sz1080p), testing::Values(TYPICAL_MAT_TYPES_ADWEIGHTED)) + +PERF_TEST_P(Size_MatType, addWeighted, TYPICAL_MATS_ADWEIGHTED) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + Mat src1(size, type); + Mat src2(size, type); + double alpha = 3.75; + double beta = -0.125; + double gamma = 100.0; + + Mat dst(size, type); + + declare.in(src1, src2, dst, WARMUP_RNG).out(dst); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + // there might be not enough precision for integers + src1 /= 2048; + src2 /= 2048; + } + + TEST_CYCLE() cv::addWeighted( src1, alpha, src2, beta, gamma, dst, dst.type() ); + + SANITY_CHECK(dst, 1); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_arithm.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_arithm.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_arithm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_arithm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,204 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_SIZES_CORE_ARITHM ::szVGA, ::sz720p, ::sz1080p +#define TYPICAL_MAT_TYPES_CORE_ARITHM CV_8UC1, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_8UC4, CV_32SC1, CV_32FC1 +#define TYPICAL_MATS_CORE_ARITHM testing::Combine( testing::Values( TYPICAL_MAT_SIZES_CORE_ARITHM ), testing::Values( TYPICAL_MAT_TYPES_CORE_ARITHM ) ) + +PERF_TEST_P(Size_MatType, min, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + TEST_CYCLE() min(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, minScalar, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Scalar b; + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + TEST_CYCLE() min(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, max, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + TEST_CYCLE() max(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, maxScalar, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Scalar b; + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + TEST_CYCLE() max(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, absdiff, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: absdiff can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() absdiff(a, b, c); + + SANITY_CHECK(c, 1e-8); +} + +PERF_TEST_P(Size_MatType, absdiffScalar, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Scalar b; + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: absdiff can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() absdiff(a, b, c); + + SANITY_CHECK(c, 1e-8); +} + +PERF_TEST_P(Size_MatType, add, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + declare.time(50); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: add can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() add(a, b, c); + + SANITY_CHECK(c, 1e-8); +} + +PERF_TEST_P(Size_MatType, addScalar, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Scalar b; + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: add can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() add(a, b, c); + + SANITY_CHECK(c, 1e-8); +} + +PERF_TEST_P(Size_MatType, subtract, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: subtract can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() subtract(a, b, c); + + SANITY_CHECK(c, 1e-8); +} + +PERF_TEST_P(Size_MatType, subtractScalar, TYPICAL_MATS_CORE_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Scalar b; + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + + if (CV_MAT_DEPTH(type) == CV_32S) + { + //see ticket 1529: subtract can be without saturation on 32S + a /= 2; + b /= 2; + } + + TEST_CYCLE() subtract(a, b, c); + + SANITY_CHECK(c, 1e-8); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_bitwise.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_bitwise.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_bitwise.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_bitwise.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,76 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_SIZES_BITW_ARITHM TYPICAL_MAT_SIZES +#define TYPICAL_MAT_TYPES_BITW_ARITHM CV_8UC1, CV_8SC1, CV_8UC4, CV_32SC1, CV_32SC4 +#define TYPICAL_MATS_BITW_ARITHM testing::Combine(testing::Values(TYPICAL_MAT_SIZES_BITW_ARITHM), testing::Values(TYPICAL_MAT_TYPES_BITW_ARITHM)) + +PERF_TEST_P(Size_MatType, bitwise_not, TYPICAL_MATS_BITW_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + cv::Mat a = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, WARMUP_RNG).out(c); + declare.iterations(200); + + TEST_CYCLE() cv::bitwise_not(a, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, bitwise_and, TYPICAL_MATS_BITW_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + declare.time(100); + + TEST_CYCLE() bitwise_and(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, bitwise_or, TYPICAL_MATS_BITW_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + declare.time(100); + + TEST_CYCLE() bitwise_or(a, b, c); + + SANITY_CHECK(c); +} + +PERF_TEST_P(Size_MatType, bitwise_xor, TYPICAL_MATS_BITW_ARITHM) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + cv::Mat a = Mat(sz, type); + cv::Mat b = Mat(sz, type); + cv::Mat c = Mat(sz, type); + + declare.in(a, b, WARMUP_RNG).out(c); + declare.time(100); + + TEST_CYCLE() bitwise_xor(a, b, c); + + SANITY_CHECK(c); +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_compare.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_compare.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_compare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_compare.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,59 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(CmpType, CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE) + +typedef std::tr1::tuple Size_MatType_CmpType_t; +typedef perf::TestBaseWithParam Size_MatType_CmpType; + +PERF_TEST_P( Size_MatType_CmpType, compare, + testing::Combine( + testing::Values(::perf::szVGA, ::perf::sz1080p), + testing::Values(CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1), + testing::ValuesIn(CmpType::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType1 = get<1>(GetParam()); + CmpType cmpType = get<2>(GetParam()); + + Mat src1(sz, matType1); + Mat src2(sz, matType1); + Mat dst(sz, CV_8UC(CV_MAT_CN(matType1))); + + declare.in(src1, src2, WARMUP_RNG).out(dst); + + TEST_CYCLE() cv::compare(src1, src2, dst, cmpType); + + SANITY_CHECK(dst); +} + +PERF_TEST_P( Size_MatType_CmpType, compareScalar, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::ValuesIn(CmpType::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + CmpType cmpType = get<2>(GetParam()); + + Mat src1(sz, matType); + Scalar src2; + Mat dst(sz, CV_8UC(CV_MAT_CN(matType))); + + declare.in(src1, src2, WARMUP_RNG).out(dst); + + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) cv::compare(src1, src2, dst, cmpType); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_convertTo.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_convertTo.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_convertTo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_convertTo.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,37 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Size_DepthSrc_DepthDst_Channels_alpha_t; +typedef perf::TestBaseWithParam Size_DepthSrc_DepthDst_Channels_alpha; + +PERF_TEST_P( Size_DepthSrc_DepthDst_Channels_alpha, convertTo, + testing::Combine + ( + testing::Values(szVGA, sz1080p), + testing::Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F), + testing::Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F), + testing::Values(1, 4), + testing::Values(1.0, 1./255) + ) + ) +{ + Size sz = get<0>(GetParam()); + int depthSrc = get<1>(GetParam()); + int depthDst = get<2>(GetParam()); + int channels = get<3>(GetParam()); + double alpha = get<4>(GetParam()); + + Mat src(sz, CV_MAKETYPE(depthSrc, channels)); + randu(src, 0, 255); + Mat dst(sz, CV_MAKETYPE(depthDst, channels)); + + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) src.convertTo(dst, depthDst, alpha); + + SANITY_CHECK(dst, alpha == 1.0 ? 1e-12 : 1e-7); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_dft.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_dft.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_dft.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_dft.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,26 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define MAT_TYPES_DFT CV_32FC1, CV_64FC1 +#define MAT_SIZES_DFT sz1080p, sz2K +#define TEST_MATS_DFT testing::Combine(testing::Values(MAT_SIZES_DFT), testing::Values(MAT_TYPES_DFT)) + +PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).time(60); + + TEST_CYCLE() dft(src, dst); + + SANITY_CHECK(dst, 1e-5); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_dot.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_dot.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_dot.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_dot.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,31 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef tr1::tuple MatType_Length_t; +typedef TestBaseWithParam MatType_Length; + +PERF_TEST_P( MatType_Length, dot, + testing::Combine( + testing::Values( CV_8UC1, CV_32SC1, CV_32FC1 ), + testing::Values( 32, 64, 128, 256, 512, 1024 ) + )) +{ + int type = get<0>(GetParam()); + int size = get<1>(GetParam()); + Mat a(size, size, type); + Mat b(size, size, type); + + declare.in(a, b, WARMUP_RNG); + declare.time(100); + + double product; + + TEST_CYCLE_N(1000) product = a.dot(b); + + SANITY_CHECK(product, 1e-6, ERROR_RELATIVE); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_inRange.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_inRange.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_inRange.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_inRange.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,26 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_TYPES_INRANGE CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_32FC4 +#define TYPICAL_MATS_INRANGE testing::Combine(testing::Values(szVGA, sz720p, sz1080p), testing::Values(TYPICAL_MAT_TYPES_INRANGE)) + +PERF_TEST_P(Size_MatType, inRange, TYPICAL_MATS_INRANGE) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + Mat src1(size, type); + Mat src2(size, type); + Mat src3(size, type); + Mat dst(size, type); + + declare.in(src1, src2, src3, WARMUP_RNG).out(dst); + + TEST_CYCLE() inRange( src1, src2, src3, dst ); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_main.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_main.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3 @@ +#include "perf_precomp.hpp" + +CV_PERF_TEST_MAIN(core) diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_mat.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_mat.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_mat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_mat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +PERF_TEST_P(Size_MatType, Mat_Eye, + testing::Combine(testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES)) + + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + Mat diagonalMatrix(size.height, size.width, type); + + declare.out(diagonalMatrix); + + int runs = (size.width <= 640) ? 15 : 5; + TEST_CYCLE_MULTIRUN(runs) + { + diagonalMatrix = Mat::eye(size, type); + } + + SANITY_CHECK(diagonalMatrix, 1); +} + +PERF_TEST_P(Size_MatType, Mat_Zeros, + testing::Combine(testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES, CV_32FC3)) + + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + Mat zeroMatrix(size.height, size.width, type); + + declare.out(zeroMatrix); + + int runs = (size.width <= 640) ? 15 : 5; + TEST_CYCLE_MULTIRUN(runs) + { + zeroMatrix = Mat::zeros(size, type); + } + + SANITY_CHECK(zeroMatrix, 1); +} + +PERF_TEST_P(Size_MatType, Mat_Clone, + testing::Combine(testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES)) + + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + Mat source(size.height, size.width, type); + Mat destination(size.height, size.width, type);; + + declare.in(source, WARMUP_RNG).out(destination); + + TEST_CYCLE() + { + source.clone(); + } + destination = source.clone(); + + SANITY_CHECK(destination, 1); +} + +PERF_TEST_P(Size_MatType, Mat_Clone_Roi, + testing::Combine(testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES)) + + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + + unsigned int width = size.width; + unsigned int height = size.height; + Mat source(height, width, type); + Mat destination(size.height/2, size.width/2, type); + + declare.in(source, WARMUP_RNG).out(destination); + + Mat roi(source, Rect(width/4, height/4, 3*width/4, 3*height/4)); + + TEST_CYCLE() + { + roi.clone(); + } + destination = roi.clone(); + + SANITY_CHECK(destination, 1); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_math.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_math.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_math.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_math.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,71 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef perf::TestBaseWithParam VectorLength; + +typedef std::tr1::tuple MaxDim_MaxPoints_t; +typedef perf::TestBaseWithParam MaxDim_MaxPoints; + +PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*1024, 1024*1024)) +{ + size_t length = GetParam(); + vector X(length); + vector Y(length); + vector angle(length); + + declare.in(X, Y, WARMUP_RNG).out(angle); + + TEST_CYCLE_N(200) cv::phase(X, Y, angle, true); + + SANITY_CHECK(angle, 5e-5); +} + +PERF_TEST_P( MaxDim_MaxPoints, kmeans, + testing::Combine( testing::Values( 16, 32, 64 ), + testing::Values( 300, 400, 500) ) ) +{ + RNG& rng = theRNG(); + const int MAX_DIM = get<0>(GetParam()); + const int MAX_POINTS = get<1>(GetParam()); + const int attempts = 5; + + Mat labels, centers; + int i, N = 0, N0 = 0, K = 0, dims = 0; + dims = rng.uniform(1, MAX_DIM+1); + N = rng.uniform(1, MAX_POINTS+1); + N0 = rng.uniform(1, MAX(N/10, 2)); + K = rng.uniform(1, N+1); + + Mat data0(N0, dims, CV_32F); + rng.fill(data0, RNG::UNIFORM, -1, 1); + + Mat data(N, dims, CV_32F); + for( i = 0; i < N; i++ ) + data0.row(rng.uniform(0, N0)).copyTo(data.row(i)); + + declare.in(data); + + TEST_CYCLE() + { + kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0), + attempts, KMEANS_PP_CENTERS, centers); + } + + Mat clusterPointsNumber = Mat::zeros(1, K, CV_32S); + + for( i = 0; i < labels.rows; i++ ) + { + int clusterIdx = labels.at(i); + clusterPointsNumber.at(clusterIdx)++; + } + + Mat sortedClusterPointsNumber; + cv::sort(clusterPointsNumber, sortedClusterPointsNumber, cv::SORT_EVERY_ROW + cv::SORT_ASCENDING); + + SANITY_CHECK(sortedClusterPointsNumber); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_merge.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_merge.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_merge.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_merge.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,37 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Size_SrcDepth_DstChannels_t; +typedef perf::TestBaseWithParam Size_SrcDepth_DstChannels; + +PERF_TEST_P( Size_SrcDepth_DstChannels, merge, + testing::Combine + ( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(CV_8U, CV_16S, CV_32S, CV_32F, CV_64F), + testing::Values(2, 3, 4) + ) + ) +{ + Size sz = get<0>(GetParam()); + int srcDepth = get<1>(GetParam()); + int dstChannels = get<2>(GetParam()); + + vector mv; + for( int i = 0; i < dstChannels; ++i ) + { + mv.push_back( Mat(sz, CV_MAKETYPE(srcDepth, 1)) ); + randu(mv[i], 0, 255); + } + + Mat dst; + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) merge( (vector &)mv, dst ); + + SANITY_CHECK(dst, 1e-12); +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_minmaxloc.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_minmaxloc.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_minmaxloc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_minmaxloc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,35 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +PERF_TEST_P(Size_MatType, minMaxLoc, testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(CV_8UC1, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + double minVal, maxVal; + Point minLoc, maxLoc; + + if (matType == CV_8U) + randu(src, 1, 254 /*do not include 0 and 255 to avoid early exit on 1 byte data*/); + else if (matType == CV_8S) + randu(src, -127, 126); + else + warmup(src, WARMUP_RNG); + + declare.in(src); + + TEST_CYCLE() minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); + + SANITY_CHECK(minVal, 1e-12); + SANITY_CHECK(maxVal, 1e-12); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_norm.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_norm.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_norm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_norm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,200 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + + +CV_FLAGS(NormType, NORM_INF, NORM_L1, NORM_L2, NORM_TYPE_MASK, NORM_RELATIVE, NORM_MINMAX) +typedef std::tr1::tuple Size_MatType_NormType_t; +typedef perf::TestBaseWithParam Size_MatType_NormType; + +PERF_TEST_P(Size_MatType_NormType, norm, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src(sz, matType); + double n; + + declare.in(src, WARMUP_RNG); + + TEST_CYCLE() n = norm(src, normType); + + SANITY_CHECK(n, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_NormType, norm_mask, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src(sz, matType); + Mat mask = Mat::ones(sz, CV_8U); + double n; + + declare.in(src, WARMUP_RNG).in(mask); + + TEST_CYCLE() n = norm(src, normType, mask); + + SANITY_CHECK(n, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_NormType, norm2, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)(NORM_RELATIVE+NORM_INF), (int)(NORM_RELATIVE+NORM_L1), (int)(NORM_RELATIVE+NORM_L2)) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src1(sz, matType); + Mat src2(sz, matType); + double n; + + declare.in(src1, src2, WARMUP_RNG); + + TEST_CYCLE() n = norm(src1, src2, normType); + + SANITY_CHECK(n, 1e-5, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_NormType, norm2_mask, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)(NORM_RELATIVE|NORM_INF), (int)(NORM_RELATIVE|NORM_L1), (int)(NORM_RELATIVE|NORM_L2)) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src1(sz, matType); + Mat src2(sz, matType); + Mat mask = Mat::ones(sz, CV_8U); + double n; + + declare.in(src1, src2, WARMUP_RNG).in(mask); + + TEST_CYCLE() n = norm(src1, src2, normType, mask); + + SANITY_CHECK(n, 1e-5, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_NormType, normalize, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src(sz, matType); + Mat dst(sz, matType); + + double alpha = 100.; + if(normType==NORM_L1) alpha = (double)src.total() * src.channels(); + if(normType==NORM_L2) alpha = (double)src.total()/10; + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() normalize(src, dst, alpha, 0., normType); + + SANITY_CHECK(dst, 1e-6); +} + +PERF_TEST_P(Size_MatType_NormType, normalize_mask, + testing::Combine( + testing::Values(::perf::szVGA, ::perf::sz1080p), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src(sz, matType); + Mat dst(sz, matType); + Mat mask = Mat::ones(sz, CV_8U); + + double alpha = 100.; + if(normType==NORM_L1) alpha = (double)src.total() * src.channels(); + if(normType==NORM_L2) alpha = (double)src.total()/10; + + declare.in(src, WARMUP_RNG).in(mask).out(dst); + declare.time(100); + + TEST_CYCLE() normalize(src, dst, alpha, 0., normType, -1, mask); + + SANITY_CHECK(dst, 1e-6); +} + +PERF_TEST_P(Size_MatType_NormType, normalize_32f, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int normType = get<2>(GetParam()); + + Mat src(sz, matType); + Mat dst(sz, CV_32F); + + double alpha = 100.; + if(normType==NORM_L1) alpha = (double)src.total() * src.channels(); + if(normType==NORM_L2) alpha = (double)src.total()/10; + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() normalize(src, dst, alpha, 0., normType, CV_32F); + + SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P( Size_MatType, normalize_minmax, TYPICAL_MATS ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + Mat dst(sz, matType); + + declare.in(src, WARMUP_RNG).out(dst); + declare.time(30); + + TEST_CYCLE() normalize(src, dst, 20., 100., NORM_MINMAX); + + SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_precomp.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "perf_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_precomp.hpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,18 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_PERF_PRECOMP_HPP__ +#define __OPENCV_PERF_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" + +#ifdef GTEST_CREATE_SHARED_LIBRARY +#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_reduce.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_reduce.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_reduce.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_reduce.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,68 @@ +#include "perf_precomp.hpp" +#include "opencv2/core/core_c.h" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(ROp, CV_REDUCE_SUM, CV_REDUCE_AVG, CV_REDUCE_MAX, CV_REDUCE_MIN) +typedef std::tr1::tuple Size_MatType_ROp_t; +typedef perf::TestBaseWithParam Size_MatType_ROp; + + +PERF_TEST_P(Size_MatType_ROp, reduceR, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::ValuesIn(ROp::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int reduceOp = get<2>(GetParam()); + + int ddepth = -1; + if( CV_MAT_DEPTH(matType) < CV_32S && (reduceOp == CV_REDUCE_SUM || reduceOp == CV_REDUCE_AVG) ) + ddepth = CV_32S; + + Mat src(sz, matType); + Mat vec(1, sz.width, ddepth < 0 ? matType : ddepth); + + declare.in(src, WARMUP_RNG).out(vec); + declare.time(100); + + TEST_CYCLE() reduce(src, vec, 0, reduceOp, ddepth); + + SANITY_CHECK(vec, 1); +} + +PERF_TEST_P(Size_MatType_ROp, reduceC, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(TYPICAL_MAT_TYPES), + testing::ValuesIn(ROp::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int reduceOp = get<2>(GetParam()); + + int ddepth = -1; + if( CV_MAT_DEPTH(matType)< CV_32S && (reduceOp == CV_REDUCE_SUM || reduceOp == CV_REDUCE_AVG) ) + ddepth = CV_32S; + + Mat src(sz, matType); + Mat vec(sz.height, 1, ddepth < 0 ? matType : ddepth); + + declare.in(src, WARMUP_RNG).out(vec); + declare.time(100); + + TEST_CYCLE() reduce(src, vec, 1, reduceOp, ddepth); + + SANITY_CHECK(vec, 1); +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_split.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_split.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_split.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_split.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,33 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Size_Depth_Channels_t; +typedef perf::TestBaseWithParam Size_Depth_Channels; + +PERF_TEST_P( Size_Depth_Channels, split, + testing::Combine + ( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(CV_8U, CV_16S, CV_32F, CV_64F), + testing::Values(2, 3, 4) + ) + ) +{ + Size sz = get<0>(GetParam()); + int depth = get<1>(GetParam()); + int channels = get<2>(GetParam()); + + Mat m(sz, CV_MAKETYPE(depth, channels)); + randu(m, 0, 255); + + vector mv; + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) split(m, (vector&)mv); + + SANITY_CHECK(mv, 1e-12); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/perf/perf_stat.cpp diffimg-2.0.0/3rdparty/opencv/core/perf/perf_stat.cpp --- diffimg-1.5.0/3rdparty/opencv/core/perf/perf_stat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/perf/perf_stat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,104 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +PERF_TEST_P(Size_MatType, sum, TYPICAL_MATS) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat arr(sz, type); + Scalar s; + + declare.in(arr, WARMUP_RNG).out(s); + + TEST_CYCLE() s = sum(arr); + + SANITY_CHECK(s, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat src(sz, type); + Scalar s; + + declare.in(src, WARMUP_RNG).out(s); + + TEST_CYCLE() s = mean(src); + + SANITY_CHECK(s, 1e-6); +} + +PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat src(sz, type); + Mat mask = Mat::ones(src.size(), CV_8U); + Scalar s; + + declare.in(src, WARMUP_RNG).in(mask).out(s); + + TEST_CYCLE() s = mean(src, mask); + + SANITY_CHECK(s, 1e-6); +} + +PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + Scalar mean; + Scalar dev; + + declare.in(src, WARMUP_RNG).out(mean, dev); + + TEST_CYCLE() meanStdDev(src, mean, dev); + + SANITY_CHECK(mean, 1e-6); + SANITY_CHECK(dev, 1e-6); +} + +PERF_TEST_P(Size_MatType, meanStdDev_mask, TYPICAL_MATS) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + Mat mask = Mat::ones(sz, CV_8U); + Scalar mean; + Scalar dev; + + declare.in(src, WARMUP_RNG).in(mask).out(mean, dev); + + TEST_CYCLE() meanStdDev(src, mean, dev, mask); + + SANITY_CHECK(mean, 1e-6); + SANITY_CHECK(dev, 1e-6); +} + +PERF_TEST_P(Size_MatType, countNonZero, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), testing::Values( CV_8UC1, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1 ) )) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + int cnt = 0; + + declare.in(src, WARMUP_RNG); + + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) cnt = countNonZero(src); + + SANITY_CHECK(cnt); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/algorithm.cpp diffimg-2.0.0/3rdparty/opencv/core/src/algorithm.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/algorithm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/algorithm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1275 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +using std::pair; + +template struct sorted_vector +{ + sorted_vector() {} + void clear() { vec.clear(); } + size_t size() const { return vec.size(); } + _ValueTp& operator [](size_t idx) { return vec[idx]; } + const _ValueTp& operator [](size_t idx) const { return vec[idx]; } + + void add(const _KeyTp& k, const _ValueTp& val) + { + pair<_KeyTp, _ValueTp> p(k, val); + vec.push_back(p); + size_t i = vec.size()-1; + for( ; i > 0 && vec[i].first < vec[i-1].first; i-- ) + std::swap(vec[i-1], vec[i]); + CV_Assert( i == 0 || vec[i].first != vec[i-1].first ); + } + + bool find(const _KeyTp& key, _ValueTp& value) const + { + size_t a = 0, b = vec.size(); + while( b > a ) + { + size_t c = (a + b)/2; + if( vec[c].first < key ) + a = c+1; + else + b = c; + } + + if( a < vec.size() && vec[a].first == key ) + { + value = vec[a].second; + return true; + } + return false; + } + + void get_keys(vector<_KeyTp>& keys) const + { + size_t i = 0, n = vec.size(); + keys.resize(n); + + for( i = 0; i < n; i++ ) + keys[i] = vec[i].first; + } + + vector > vec; +}; + + +template inline const _ValueTp* findstr(const sorted_vector& vec, + const char* key) +{ + if( !key ) + return 0; + + size_t a = 0, b = vec.vec.size(); + while( b > a ) + { + size_t c = (a + b)/2; + if( strcmp(vec.vec[c].first.c_str(), key) < 0 ) + a = c+1; + else + b = c; + } + + if( ( a < vec.vec.size() ) && ( strcmp(vec.vec[a].first.c_str(), key) == 0 )) + return &vec.vec[a].second; + return 0; +} + + +Param::Param() +{ + type = 0; + offset = 0; + readonly = false; + getter = 0; + setter = 0; +} + + +Param::Param(int _type, bool _readonly, int _offset, + Algorithm::Getter _getter, Algorithm::Setter _setter, + const string& _help) +{ + type = _type; + readonly = _readonly; + offset = _offset; + getter = _getter; + setter = _setter; + help = _help; +} + +struct CV_EXPORTS AlgorithmInfoData +{ + sorted_vector params; + string _name; +}; + + +static sorted_vector& alglist() +{ + static sorted_vector alglist_var; + return alglist_var; +} + +void Algorithm::getList(vector& algorithms) +{ + alglist().get_keys(algorithms); +} + +Ptr Algorithm::_create(const string& name) +{ + Algorithm::Constructor c = 0; + if( !alglist().find(name, c) ) + return Ptr(); + return c(); +} + +Algorithm::Algorithm() +{ +} + +Algorithm::~Algorithm() +{ +} + +string Algorithm::name() const +{ + return info()->name(); +} + +void Algorithm::set(const string& parameter, int value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const string& parameter, double value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const string& parameter, bool value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const string& parameter, const string& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const string& parameter, const Mat& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const string& parameter, const vector& value) +{ + info()->set(this, parameter.c_str(), ParamType >::type, &value); +} + +void Algorithm::set(const string& parameter, const Ptr& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, int value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, double value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, bool value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, const string& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, const Mat& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::set(const char* parameter, const vector& value) +{ + info()->set(this, parameter, ParamType >::type, &value); +} + +void Algorithm::set(const char* parameter, const Ptr& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + + +void Algorithm::setInt(const string& parameter, int value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setDouble(const string& parameter, double value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setBool(const string& parameter, bool value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setString(const string& parameter, const string& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setMat(const string& parameter, const Mat& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setMatVector(const string& parameter, const vector& value) +{ + info()->set(this, parameter.c_str(), ParamType >::type, &value); +} + +void Algorithm::setAlgorithm(const string& parameter, const Ptr& value) +{ + info()->set(this, parameter.c_str(), ParamType::type, &value); +} + +void Algorithm::setInt(const char* parameter, int value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::setDouble(const char* parameter, double value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::setBool(const char* parameter, bool value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::setString(const char* parameter, const string& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::setMat(const char* parameter, const Mat& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + +void Algorithm::setMatVector(const char* parameter, const vector& value) +{ + info()->set(this, parameter, ParamType >::type, &value); +} + +void Algorithm::setAlgorithm(const char* parameter, const Ptr& value) +{ + info()->set(this, parameter, ParamType::type, &value); +} + + + + +int Algorithm::getInt(const string& parameter) const +{ + return get(parameter); +} + +double Algorithm::getDouble(const string& parameter) const +{ + return get(parameter); +} + +bool Algorithm::getBool(const string& parameter) const +{ + return get(parameter); +} + +string Algorithm::getString(const string& parameter) const +{ + return get(parameter); +} + +Mat Algorithm::getMat(const string& parameter) const +{ + return get(parameter); +} + +vector Algorithm::getMatVector(const string& parameter) const +{ + return get >(parameter); +} + +Ptr Algorithm::getAlgorithm(const string& parameter) const +{ + return get(parameter); +} + +string Algorithm::paramHelp(const string& parameter) const +{ + return info()->paramHelp(parameter.c_str()); +} + +int Algorithm::paramType(const string& parameter) const +{ + return info()->paramType(parameter.c_str()); +} + +int Algorithm::paramType(const char* parameter) const +{ + return info()->paramType(parameter); +} + +void Algorithm::getParams(vector& names) const +{ + info()->getParams(names); +} + +void Algorithm::write(FileStorage& fs) const +{ + info()->write(this, fs); +} + +void Algorithm::read(const FileNode& fn) +{ + info()->read(this, fn); +} + + +AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create) +{ + data = new AlgorithmInfoData; + data->_name = _name; + if (!alglist().find(_name, create)) + alglist().add(_name, create); +} + +AlgorithmInfo::~AlgorithmInfo() +{ + delete data; +} + +void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const +{ + size_t i = 0, nparams = data->params.vec.size(); + cv::write(fs, "name", algo->name()); + for( i = 0; i < nparams; i++ ) + { + const Param& p = data->params.vec[i].second; + const string& pname = data->params.vec[i].first; + if( p.type == Param::INT ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::BOOLEAN ) + cv::write(fs, pname, (int)algo->get(pname)); + else if( p.type == Param::SHORT ) + cv::write(fs, pname, (int)algo->get(pname)); + else if( p.type == Param::REAL ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::STRING ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::MAT ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::MAT_VECTOR ) + cv::write(fs, pname, algo->get >(pname)); + else if( p.type == Param::ALGORITHM ) + { + WriteStructContext ws(fs, pname, CV_NODE_MAP); + Ptr nestedAlgo = algo->get(pname); + nestedAlgo->write(fs); + } + else if( p.type == Param::FLOAT) + cv::write(fs, pname, algo->getDouble(pname)); + else if( p.type == Param::UNSIGNED_INT) + cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , unsigned int) + else if( p.type == Param::UINT64) + cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , uint64) + else if( p.type == Param::UCHAR) + cv::write(fs, pname, algo->getInt(pname)); + else + { + string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type); + CV_Error( CV_StsUnsupportedFormat, msg.c_str()); + } + } +} + +void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const +{ + size_t i = 0, nparams = data->params.vec.size(); + AlgorithmInfo* info = algo->info(); + + for( i = 0; i < nparams; i++ ) + { + const Param& p = data->params.vec[i].second; + const string& pname = data->params.vec[i].first; + const FileNode n = fn[pname]; + if( n.empty() ) + continue; + if( p.type == Param::INT || p.type == Param::SHORT ) + { + int val = (int)n; + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::BOOLEAN ) + { + bool val = (int)n != 0; + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::REAL ) + { + double val = (double)n; + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::STRING ) + { + string val = (string)n; + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::MAT ) + { + Mat m; + cv::read(n, m); + info->set(algo, pname.c_str(), p.type, &m, true); + } + else if( p.type == Param::MAT_VECTOR ) + { + vector mv; + cv::read(n, mv); + info->set(algo, pname.c_str(), p.type, &mv, true); + } + else if( p.type == Param::ALGORITHM ) + { + Ptr nestedAlgo = Algorithm::_create((string)n["name"]); + CV_Assert( !nestedAlgo.empty() ); + nestedAlgo->read(n); + info->set(algo, pname.c_str(), p.type, &nestedAlgo, true); + } + else if( p.type == Param::FLOAT ) + { + float val = (float)n; + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::UNSIGNED_INT ) + { + unsigned int val = (unsigned int)((int)n);//TODO: implement conversion (unsigned int)FileNode + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::UINT64) + { + uint64 val = (uint64)((int)n);//TODO: implement conversion (uint64)FileNode + info->set(algo, pname.c_str(), p.type, &val, true); + } + else if( p.type == Param::UCHAR) + { + uchar val = (uchar)((int)n); + info->set(algo, pname.c_str(), p.type, &val, true); + } + else + { + string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type); + CV_Error( CV_StsUnsupportedFormat, msg.c_str()); + } + } +} + +string AlgorithmInfo::name() const +{ + return data->_name; +} + +union GetSetParam +{ + int (Algorithm::*get_int)() const; + bool (Algorithm::*get_bool)() const; + double (Algorithm::*get_double)() const; + string (Algorithm::*get_string)() const; + Mat (Algorithm::*get_mat)() const; + vector (Algorithm::*get_mat_vector)() const; + Ptr (Algorithm::*get_algo)() const; + float (Algorithm::*get_float)() const; + unsigned int (Algorithm::*get_uint)() const; + uint64 (Algorithm::*get_uint64)() const; + uchar (Algorithm::*get_uchar)() const; + + void (Algorithm::*set_int)(int); + void (Algorithm::*set_bool)(bool); + void (Algorithm::*set_double)(double); + void (Algorithm::*set_string)(const string&); + void (Algorithm::*set_mat)(const Mat&); + void (Algorithm::*set_mat_vector)(const vector&); + void (Algorithm::*set_algo)(const Ptr&); + void (Algorithm::*set_float)(float); + void (Algorithm::*set_uint)(unsigned int); + void (Algorithm::*set_uint64)(uint64); + void (Algorithm::*set_uchar)(uchar); +}; + +static string getNameOfType(int argType); + +static string getNameOfType(int argType) +{ + switch(argType) + { + case Param::INT: return "integer"; + case Param::SHORT: return "short"; + case Param::BOOLEAN: return "boolean"; + case Param::REAL: return "double"; + case Param::STRING: return "string"; + case Param::MAT: return "cv::Mat"; + case Param::MAT_VECTOR: return "std::vector"; + case Param::ALGORITHM: return "algorithm"; + case Param::FLOAT: return "float"; + case Param::UNSIGNED_INT: return "unsigned int"; + case Param::UINT64: return "unsigned int64"; + case Param::UCHAR: return "unsigned char"; + default: CV_Error(CV_StsBadArg, "Wrong argument type"); + } + return ""; +} +static string getErrorMessageForWrongArgumentInSetter(string algoName, string paramName, int paramType, int argType); +static string getErrorMessageForWrongArgumentInSetter(string algoName, string paramName, int paramType, int argType) +{ + string message = string("Argument error: the setter") + + " method was called for the parameter '" + paramName + "' of the algorithm '" + algoName + +"', the parameter has " + getNameOfType(paramType) + " type, "; + + if (paramType == Param::INT || paramType == Param::BOOLEAN || paramType == Param::REAL + || paramType == Param::FLOAT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR) + { + message += "so it should be set by integer, unsigned integer, uint64, unsigned char, boolean, float or double value, "; + } + else if (paramType == Param::SHORT) + { + message += "so it should be set by integer value, "; + } + message += "but the setter was called with " + getNameOfType(argType) + " value"; + + return message; +} + +static string getErrorMessageForWrongArgumentInGetter(string algoName, string paramName, int paramType, int argType); +static string getErrorMessageForWrongArgumentInGetter(string algoName, string paramName, int paramType, int argType) +{ + string message = string("Argument error: the getter") + + " method was called for the parameter '" + paramName + "' of the algorithm '" + algoName + +"', the parameter has " + getNameOfType(paramType) + " type, "; + + if (paramType == Param::BOOLEAN) + { + message += "so it should be get as integer, unsigned integer, uint64, boolean, unsigned char, float or double value, "; + } + else if (paramType == Param::INT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR) + { + message += "so it should be get as integer, unsigned integer, uint64, unsigned char, float or double value, "; + } + else if (paramType == Param::SHORT) + { + message += "so it should be get as integer value, "; + } + else if (paramType == Param::FLOAT || paramType == Param::REAL) + { + message += "so it should be get as float or double value, "; + } + message += "but the getter was called to get a " + getNameOfType(argType) + " value"; + + return message; +} + +void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, const void* value, bool force) const +{ + const Param* p = findstr(data->params, parameter); + + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "") ); + + if( !force && p->readonly ) + CV_Error_( CV_StsError, ("Parameter '%s' is readonly", parameter)); + + GetSetParam f; + f.set_int = p->setter; + + if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT + || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR) + { + if ( !( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN + || p->type == Param::UNSIGNED_INT || p->type == Param::UINT64 || p->type == Param::FLOAT || argType == Param::UCHAR + || (p->type == Param::SHORT && argType == Param::INT)) ) + { + string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + if( p->type == Param::INT ) + { + bool is_ok = true; + int val = argType == Param::INT ? *(const int*)value : + argType == Param::BOOLEAN ? (int)*(const bool*)value : + argType == Param::REAL ? saturate_cast(*(const double*)value) : + argType == Param::FLOAT ? saturate_cast(*(const float*)value) : + argType == Param::UNSIGNED_INT ? (int)*(const unsigned int*)value : + argType == Param::UINT64 ? (int)*(const uint64*)value : + argType == Param::UCHAR ? (int)*(const uchar*)value : + (int)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + + if( p->setter ) + (algo->*f.set_int)(val); + else + *(int*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::SHORT ) + { + CV_DbgAssert(argType == Param::INT); + int val = *(const int*)value; + if( p->setter ) + (algo->*f.set_int)(val); + else + *(short*)((uchar*)algo + p->offset) = (short)val; + } + else if( p->type == Param::BOOLEAN ) + { + bool is_ok = true; + bool val = argType == Param::INT ? *(const int*)value != 0 : + argType == Param::BOOLEAN ? *(const bool*)value : + argType == Param::REAL ? (*(const double*)value != 0) : + argType == Param::FLOAT ? (*(const float*)value != 0) : + argType == Param::UNSIGNED_INT ? (*(const unsigned int*)value != 0): + argType == Param::UINT64 ? (*(const uint64*)value != 0): + argType == Param::UCHAR ? (*(const uchar*)value != 0): + (int)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + + if( p->setter ) + (algo->*f.set_bool)(val); + else + *(bool*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::REAL ) + { + bool is_ok = true; + double val = argType == Param::INT ? (double)*(const int*)value : + argType == Param::BOOLEAN ? (double)*(const bool*)value : + argType == Param::REAL ? (double)(*(const double*)value ) : + argType == Param::FLOAT ? (double)(*(const float*)value ) : + argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) : + argType == Param::UINT64 ? (double)(*(const uint64*)value ) : + argType == Param::UCHAR ? (double)(*(const uchar*)value ) : + (double)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + if( p->setter ) + (algo->*f.set_double)(val); + else + *(double*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::FLOAT ) + { + bool is_ok = true; + double val = argType == Param::INT ? (double)*(const int*)value : + argType == Param::BOOLEAN ? (double)*(const bool*)value : + argType == Param::REAL ? (double)(*(const double*)value ) : + argType == Param::FLOAT ? (double)(*(const float*)value ) : + argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) : + argType == Param::UINT64 ? (double)(*(const uint64*)value ) : + argType == Param::UCHAR ? (double)(*(const uchar*)value ) : + (double)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + if( p->setter ) + (algo->*f.set_float)((float)val); + else + *(float*)((uchar*)algo + p->offset) = (float)val; + } + else if( p->type == Param::UNSIGNED_INT ) + { + bool is_ok = true; + unsigned int val = argType == Param::INT ? (unsigned int)*(const int*)value : + argType == Param::BOOLEAN ? (unsigned int)*(const bool*)value : + argType == Param::REAL ? saturate_cast(*(const double*)value ) : + argType == Param::FLOAT ? saturate_cast(*(const float*)value ) : + argType == Param::UNSIGNED_INT ? (unsigned int)(*(const unsigned int*)value ) : + argType == Param::UINT64 ? (unsigned int)(*(const uint64*)value ) : + argType == Param::UCHAR ? (unsigned int)(*(const uchar*)value ) : + (int)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + if( p->setter ) + (algo->*f.set_uint)(val); + else + *(unsigned int*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::UINT64 ) + { + bool is_ok = true; + uint64 val = argType == Param::INT ? (uint64)*(const int*)value : + argType == Param::BOOLEAN ? (uint64)*(const bool*)value : + argType == Param::REAL ? saturate_cast(*(const double*)value ) : + argType == Param::FLOAT ? saturate_cast(*(const float*)value ) : + argType == Param::UNSIGNED_INT ? (uint64)(*(const unsigned int*)value ) : + argType == Param::UINT64 ? (uint64)(*(const uint64*)value ) : + argType == Param::UCHAR ? (uint64)(*(const uchar*)value ) : + (int)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + if( p->setter ) + (algo->*f.set_uint64)(val); + else + *(uint64*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::UCHAR ) + { + bool is_ok = true; + uchar val = argType == Param::INT ? (uchar)*(const int*)value : + argType == Param::BOOLEAN ? (uchar)*(const bool*)value : + argType == Param::REAL ? saturate_cast(*(const double*)value ) : + argType == Param::FLOAT ? saturate_cast(*(const float*)value ) : + argType == Param::UNSIGNED_INT ? (uchar)(*(const unsigned int*)value ) : + argType == Param::UINT64 ? (uchar)(*(const uint64*)value ) : + argType == Param::UCHAR ? (uchar)(*(const uchar*)value ) : + (int)(is_ok = false); + + if (!is_ok) + { + CV_Error(CV_StsBadArg, "Wrong argument type in the setter"); + } + if( p->setter ) + (algo->*f.set_uchar)(val); + else + *(uchar*)((uchar*)algo + p->offset) = val; + } + else + CV_Error(CV_StsBadArg, "Wrong parameter type in the setter"); + } + else if( argType == Param::STRING ) + { + if( p->type != Param::STRING ) + { + string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + const string& val = *(const string*)value; + if( p->setter ) + (algo->*f.set_string)(val); + else + *(string*)((uchar*)algo + p->offset) = val; + } + else if( argType == Param::MAT ) + { + if( p->type != Param::MAT ) + { + string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + const Mat& val = *(const Mat*)value; + if( p->setter ) + (algo->*f.set_mat)(val); + else + *(Mat*)((uchar*)algo + p->offset) = val; + } + else if( argType == Param::MAT_VECTOR ) + { + if( p->type != Param::MAT_VECTOR ) + { + string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + const vector& val = *(const vector*)value; + if( p->setter ) + (algo->*f.set_mat_vector)(val); + else + *(vector*)((uchar*)algo + p->offset) = val; + } + else if( argType == Param::ALGORITHM ) + { + if( p->type != Param::ALGORITHM ) + { + string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + const Ptr& val = *(const Ptr*)value; + if( p->setter ) + (algo->*f.set_algo)(val); + else + *(Ptr*)((uchar*)algo + p->offset) = val; + } + else + CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); +} + +void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argType, void* value) const +{ + const Param* p = findstr(data->params, parameter); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "") ); + + GetSetParam f; + f.get_int = p->getter; + + if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT + || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR) + { + if( p->type == Param::INT ) + { + if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = (int)val; + else if ( argType == Param::REAL ) + *(double*)value = (double)val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)val; + else if ( argType == Param::UNSIGNED_INT ) + *(unsigned int*)value = (unsigned int)val; + else if ( argType == Param::UINT64 ) + *(uint64*)value = (uint64)val; + else if ( argType == Param::UCHAR) + *(uchar*)value = (uchar)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + + } + else if( p->type == Param::SHORT ) + { + if( argType != Param::INT ) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + int val = p->getter ? (algo->*f.get_int)() : *(short*)((uchar*)algo + p->offset); + + *(int*)value = val; + } + else if( p->type == Param::BOOLEAN ) + { + if (!( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = (int)val; + else if( argType == Param::BOOLEAN ) + *(bool*)value = val; + else if ( argType == Param::REAL ) + *(double*)value = (int)val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)((int)val); + else if ( argType == Param::UNSIGNED_INT ) + *(unsigned int*)value = (unsigned int)val; + else if ( argType == Param::UINT64 ) + *(uint64*)value = (int)val; + else if ( argType == Param::UCHAR) + *(uchar*)value = (uchar)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + } + else if( p->type == Param::REAL ) + { + if(!( argType == Param::REAL || argType == Param::FLOAT)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset); + + if ( argType == Param::REAL ) + *(double*)value = val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + } + else if( p->type == Param::FLOAT ) + { + if(!( argType == Param::REAL || argType == Param::FLOAT)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + float val = p->getter ? (algo->*f.get_float)() : *(float*)((uchar*)algo + p->offset); + + if ( argType == Param::REAL ) + *(double*)value = (double)val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + } + else if( p->type == Param::UNSIGNED_INT ) + { + if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + unsigned int val = p->getter ? (algo->*f.get_uint)() : *(unsigned int*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = (int)val; + else if ( argType == Param::REAL ) + *(double*)value = (double)val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)val; + else if ( argType == Param::UNSIGNED_INT ) + *(unsigned int*)value = (unsigned int)val; + else if ( argType == Param::UINT64 ) + *(uint64*)value = (uint64)val; + else if ( argType == Param::UCHAR) + *(uchar*)value = (uchar)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + } + else if( p->type == Param::UINT64 ) + { + if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + uint64 val = p->getter ? (algo->*f.get_uint64)() : *(uint64*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = (int)val; + else if ( argType == Param::REAL ) + *(double*)value = (double)val; + else if ( argType == Param::FLOAT) + *(float*)value = (float)val; + else if ( argType == Param::UNSIGNED_INT ) + *(unsigned int*)value = (unsigned int)val; + else if ( argType == Param::UINT64 ) + *(uint64*)value = (uint64)val; + else if ( argType == Param::UCHAR) + *(uchar*)value = (uchar)val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + } + else if( p->type == Param::UCHAR ) + { + if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + uchar val = p->getter ? (algo->*f.get_uchar)() : *(uchar*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = val; + else if ( argType == Param::REAL ) + *(double*)value = val; + else if ( argType == Param::FLOAT) + *(float*)value = val; + else if ( argType == Param::UNSIGNED_INT ) + *(unsigned int*)value = val; + else if ( argType == Param::UINT64 ) + *(uint64*)value = val; + else if ( argType == Param::UCHAR) + *(uchar*)value = val; + else + CV_Error(CV_StsBadArg, "Wrong argument type"); + + } + else + CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); + } + else if( argType == Param::STRING ) + { + if( p->type != Param::STRING ) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + *(string*)value = p->getter ? (algo->*f.get_string)() : + *(string*)((uchar*)algo + p->offset); + } + else if( argType == Param::MAT ) + { + if( p->type != Param::MAT ) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + *(Mat*)value = p->getter ? (algo->*f.get_mat)() : + *(Mat*)((uchar*)algo + p->offset); + } + else if( argType == Param::MAT_VECTOR ) + { + if( p->type != Param::MAT_VECTOR ) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + *(vector*)value = p->getter ? (algo->*f.get_mat_vector)() : + *(vector*)((uchar*)algo + p->offset); + } + else if( argType == Param::ALGORITHM ) + { + if( p->type != Param::ALGORITHM ) + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } + + *(Ptr*)value = p->getter ? (algo->*f.get_algo)() : + *(Ptr*)((uchar*)algo + p->offset); + } + else + { + string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType); + CV_Error(CV_StsBadArg, message); + } +} + + +int AlgorithmInfo::paramType(const char* parameter) const +{ + const Param* p = findstr(data->params, parameter); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "") ); + return p->type; +} + + +string AlgorithmInfo::paramHelp(const char* parameter) const +{ + const Param* p = findstr(data->params, parameter); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "") ); + return p->help; +} + + +void AlgorithmInfo::getParams(vector& names) const +{ + data->params.get_keys(names); +} + + +void AlgorithmInfo::addParam_(Algorithm& algo, const char* parameter, int argType, + void* value, bool readOnly, + Algorithm::Getter getter, Algorithm::Setter setter, + const string& help) +{ + CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || + argType == Param::REAL || argType == Param::STRING || + argType == Param::MAT || argType == Param::MAT_VECTOR || + argType == Param::ALGORITHM || argType == Param::SHORT + || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 + || argType == Param::UCHAR); + data->params.add(string(parameter), Param(argType, readOnly, + (int)((size_t)value - (size_t)(void*)&algo), + getter, setter, help)); +} + + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + int& value, bool readOnly, + int (Algorithm::*getter)(), + void (Algorithm::*setter)(int), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + short& value, bool readOnly, + int (Algorithm::*getter)(), + void (Algorithm::*setter)(int), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + bool& value, bool readOnly, + int (Algorithm::*getter)(), + void (Algorithm::*setter)(int), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + double& value, bool readOnly, + double (Algorithm::*getter)(), + void (Algorithm::*setter)(double), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + string& value, bool readOnly, + string (Algorithm::*getter)(), + void (Algorithm::*setter)(const string&), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + Mat& value, bool readOnly, + Mat (Algorithm::*getter)(), + void (Algorithm::*setter)(const Mat&), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + vector& value, bool readOnly, + vector (Algorithm::*getter)(), + void (Algorithm::*setter)(const vector&), + const string& help) +{ + addParam_(algo, parameter, ParamType >::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + Ptr& value, bool readOnly, + Ptr (Algorithm::*getter)(), + void (Algorithm::*setter)(const Ptr&), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + float& value, bool readOnly, + float (Algorithm::*getter)(), + void (Algorithm::*setter)(float), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + unsigned int& value, bool readOnly, + unsigned int (Algorithm::*getter)(), + void (Algorithm::*setter)(unsigned int), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + uint64& value, bool readOnly, + uint64 (Algorithm::*getter)(), + void (Algorithm::*setter)(uint64), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, + uchar& value, bool readOnly, + uchar (Algorithm::*getter)(), + void (Algorithm::*setter)(uchar), + const string& help) +{ + addParam_(algo, parameter, ParamType::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/alloc.cpp diffimg-2.0.0/3rdparty/opencv/core/src/alloc.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/alloc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/alloc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,702 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#define CV_USE_SYSTEM_MALLOC 1 + +namespace cv +{ + +static void* OutOfMemoryError(size_t size) +{ + CV_Error_(CV_StsNoMem, ("Failed to allocate %lu bytes", (unsigned long)size)); + return 0; +} + +#if CV_USE_SYSTEM_MALLOC + +#if defined WIN32 || defined _WIN32 +void deleteThreadAllocData() {} +#endif + +void* fastMalloc( size_t size ) +{ + uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN); + if(!udata) + return OutOfMemoryError(size); + uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN); + adata[-1] = udata; + return adata; +} + +void fastFree(void* ptr) +{ + if(ptr) + { + uchar* udata = ((uchar**)ptr)[-1]; + CV_DbgAssert(udata < (uchar*)ptr && + ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+CV_MALLOC_ALIGN)); + free(udata); + } +} + +#else //CV_USE_SYSTEM_MALLOC + +#if 0 +#define SANITY_CHECK(block) \ + CV_Assert(((size_t)(block) & (MEM_BLOCK_SIZE-1)) == 0 && \ + (unsigned)(block)->binIdx <= (unsigned)MAX_BIN && \ + (block)->signature == MEM_BLOCK_SIGNATURE) +#else +#define SANITY_CHECK(block) +#endif + +#define STAT(stmt) + +#ifdef WIN32 +struct CriticalSection +{ + CriticalSection() { InitializeCriticalSection(&cs); } + ~CriticalSection() { DeleteCriticalSection(&cs); } + void lock() { EnterCriticalSection(&cs); } + void unlock() { LeaveCriticalSection(&cs); } + bool trylock() { return TryEnterCriticalSection(&cs) != 0; } + + CRITICAL_SECTION cs; +}; + +void* SystemAlloc(size_t size) +{ + void* ptr = malloc(size); + return ptr ? ptr : OutOfMemoryError(size); +} + +void SystemFree(void* ptr, size_t) +{ + free(ptr); +} +#else //WIN32 + +#include + +struct CriticalSection +{ + CriticalSection() { pthread_mutex_init(&mutex, 0); } + ~CriticalSection() { pthread_mutex_destroy(&mutex); } + void lock() { pthread_mutex_lock(&mutex); } + void unlock() { pthread_mutex_unlock(&mutex); } + bool trylock() { return pthread_mutex_trylock(&mutex) == 0; } + + pthread_mutex_t mutex; +}; + +void* SystemAlloc(size_t size) +{ + #ifndef MAP_ANONYMOUS + #define MAP_ANONYMOUS MAP_ANON + #endif + void* ptr = 0; + ptr = mmap(ptr, size, (PROT_READ | PROT_WRITE), MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + return ptr != MAP_FAILED ? ptr : OutOfMemoryError(size); +} + +void SystemFree(void* ptr, size_t size) +{ + munmap(ptr, size); +} +#endif //WIN32 + +struct AutoLock +{ + AutoLock(CriticalSection& _cs) : cs(&_cs) { cs->lock(); } + ~AutoLock() { cs->unlock(); } + CriticalSection* cs; +}; + +const size_t MEM_BLOCK_SIGNATURE = 0x01234567; +const int MEM_BLOCK_SHIFT = 14; +const size_t MEM_BLOCK_SIZE = 1 << MEM_BLOCK_SHIFT; +const size_t HDR_SIZE = 128; +const size_t MAX_BLOCK_SIZE = MEM_BLOCK_SIZE - HDR_SIZE; +const int MAX_BIN = 28; + +static const int binSizeTab[MAX_BIN+1] = +{ 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 128, 160, 192, 256, 320, 384, 480, 544, 672, 768, +896, 1056, 1328, 1600, 2688, 4048, 5408, 8128, 16256 }; + +struct MallocTables +{ + void initBinTab() + { + int i, j = 0, n; + for( i = 0; i <= MAX_BIN; i++ ) + { + n = binSizeTab[i]>>3; + for( ; j <= n; j++ ) + binIdx[j] = (uchar)i; + } + } + int bin(size_t size) + { + assert( size <= MAX_BLOCK_SIZE ); + return binIdx[(size + 7)>>3]; + } + + MallocTables() + { + initBinTab(); + } + + uchar binIdx[MAX_BLOCK_SIZE/8+1]; +}; + +MallocTables mallocTables; + +struct Node +{ + Node* next; +}; + +struct ThreadData; + +struct Block +{ + Block(Block* _next) + { + signature = MEM_BLOCK_SIGNATURE; + prev = 0; + next = _next; + privateFreeList = publicFreeList = 0; + bumpPtr = endPtr = 0; + objSize = 0; + threadData = 0; + data = (uchar*)this + HDR_SIZE; + } + + ~Block() {} + + void init(Block* _prev, Block* _next, int _objSize, ThreadData* _threadData) + { + prev = _prev; + if(prev) + prev->next = this; + next = _next; + if(next) + next->prev = this; + objSize = _objSize; + binIdx = mallocTables.bin(objSize); + threadData = _threadData; + privateFreeList = publicFreeList = 0; + bumpPtr = data; + int nobjects = MAX_BLOCK_SIZE/objSize; + endPtr = bumpPtr + nobjects*objSize; + almostEmptyThreshold = (nobjects + 1)/2; + allocated = 0; + } + + bool isFilled() const { return allocated > almostEmptyThreshold; } + + size_t signature; + Block* prev; + Block* next; + Node* privateFreeList; + Node* publicFreeList; + uchar* bumpPtr; + uchar* endPtr; + uchar* data; + ThreadData* threadData; + int objSize; + int binIdx; + int allocated; + int almostEmptyThreshold; + CriticalSection cs; +}; + +struct BigBlock +{ + BigBlock(int bigBlockSize, BigBlock* _next) + { + first = alignPtr((Block*)(this+1), MEM_BLOCK_SIZE); + next = _next; + nblocks = (int)(((char*)this + bigBlockSize - (char*)first)/MEM_BLOCK_SIZE); + Block* p = 0; + for( int i = nblocks-1; i >= 0; i-- ) + p = ::new((uchar*)first + i*MEM_BLOCK_SIZE) Block(p); + } + + ~BigBlock() + { + for( int i = nblocks-1; i >= 0; i-- ) + ((Block*)((uchar*)first+i*MEM_BLOCK_SIZE))->~Block(); + } + + BigBlock* next; + Block* first; + int nblocks; +}; + +struct BlockPool +{ + BlockPool(int _bigBlockSize=1<<20) : pool(0), bigBlockSize(_bigBlockSize) + { + } + + ~BlockPool() + { + AutoLock lock(cs); + while( pool ) + { + BigBlock* nextBlock = pool->next; + pool->~BigBlock(); + SystemFree(pool, bigBlockSize); + pool = nextBlock; + } + } + + Block* alloc() + { + AutoLock lock(cs); + Block* block; + if( !freeBlocks ) + { + BigBlock* bblock = ::new(SystemAlloc(bigBlockSize)) BigBlock(bigBlockSize, pool); + assert( bblock != 0 ); + freeBlocks = bblock->first; + pool = bblock; + } + block = freeBlocks; + freeBlocks = freeBlocks->next; + if( freeBlocks ) + freeBlocks->prev = 0; + STAT(stat.bruttoBytes += MEM_BLOCK_SIZE); + return block; + } + + void free(Block* block) + { + AutoLock lock(cs); + block->prev = 0; + block->next = freeBlocks; + freeBlocks = block; + STAT(stat.bruttoBytes -= MEM_BLOCK_SIZE); + } + + CriticalSection cs; + Block* freeBlocks; + BigBlock* pool; + int bigBlockSize; + int blocksPerBigBlock; +}; + +BlockPool mallocPool; + +enum { START=0, FREE=1, GC=2 }; + +struct ThreadData +{ + ThreadData() { for(int i = 0; i <= MAX_BIN; i++) bins[i][START] = bins[i][FREE] = bins[i][GC] = 0; } + ~ThreadData() + { + // mark all the thread blocks as abandoned or even release them + for( int i = 0; i <= MAX_BIN; i++ ) + { + Block *bin = bins[i][START], *block = bin; + bins[i][START] = bins[i][FREE] = bins[i][GC] = 0; + if( block ) + { + do + { + Block* next = block->next; + int allocated = block->allocated; + { + AutoLock lock(block->cs); + block->next = block->prev = 0; + block->threadData = 0; + Node *node = block->publicFreeList; + for( ; node != 0; node = node->next ) + allocated--; + } + if( allocated == 0 ) + mallocPool.free(block); + block = next; + } + while( block != bin ); + } + } + } + + void moveBlockToFreeList( Block* block ) + { + int i = block->binIdx; + Block*& freePtr = bins[i][FREE]; + CV_DbgAssert( block->next->prev == block && block->prev->next == block ); + if( block != freePtr ) + { + Block*& gcPtr = bins[i][GC]; + if( gcPtr == block ) + gcPtr = block->next; + if( block->next != block ) + { + block->prev->next = block->next; + block->next->prev = block->prev; + } + block->next = freePtr->next; + block->prev = freePtr; + freePtr = block->next->prev = block->prev->next = block; + } + } + + Block* bins[MAX_BIN+1][3]; + +#ifdef WIN32 +#ifdef WINCE +# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) +#endif //WINCE + + static DWORD tlsKey; + static ThreadData* get() + { + ThreadData* data; + if( tlsKey == TLS_OUT_OF_INDEXES ) + tlsKey = TlsAlloc(); + data = (ThreadData*)TlsGetValue(tlsKey); + if( !data ) + { + data = new ThreadData; + TlsSetValue(tlsKey, data); + } + return data; + } +#else //WIN32 + static void deleteData(void* data) + { + delete (ThreadData*)data; + } + + static pthread_key_t tlsKey; + static ThreadData* get() + { + ThreadData* data; + if( !tlsKey ) + pthread_key_create(&tlsKey, deleteData); + data = (ThreadData*)pthread_getspecific(tlsKey); + if( !data ) + { + data = new ThreadData; + pthread_setspecific(tlsKey, data); + } + return data; + } +#endif //WIN32 +}; + +#ifdef WIN32 +DWORD ThreadData::tlsKey = TLS_OUT_OF_INDEXES; + +void deleteThreadAllocData() +{ + if( ThreadData::tlsKey != TLS_OUT_OF_INDEXES ) + delete (ThreadData*)TlsGetValue( ThreadData::tlsKey ); +} + +#else //WIN32 +pthread_key_t ThreadData::tlsKey = 0; +#endif //WIN32 + +#if 0 +static void checkList(ThreadData* tls, int idx) +{ + Block* block = tls->bins[idx][START]; + if( !block ) + { + CV_DbgAssert( tls->bins[idx][FREE] == 0 && tls->bins[idx][GC] == 0 ); + } + else + { + bool gcInside = false; + bool freeInside = false; + do + { + if( tls->bins[idx][FREE] == block ) + freeInside = true; + if( tls->bins[idx][GC] == block ) + gcInside = true; + block = block->next; + } + while( block != tls->bins[idx][START] ); + CV_DbgAssert( gcInside && freeInside ); + } +} +#else +#define checkList(tls, idx) +#endif + +void* fastMalloc( size_t size ) +{ + if( size > MAX_BLOCK_SIZE ) + { + size_t size1 = size + sizeof(uchar*)*2 + MEM_BLOCK_SIZE; + uchar* udata = (uchar*)SystemAlloc(size1); + uchar** adata = alignPtr((uchar**)udata + 2, MEM_BLOCK_SIZE); + adata[-1] = udata; + adata[-2] = (uchar*)size1; + return adata; + } + + { + ThreadData* tls = ThreadData::get(); + int idx = mallocTables.bin(size); + Block*& startPtr = tls->bins[idx][START]; + Block*& gcPtr = tls->bins[idx][GC]; + Block*& freePtr = tls->bins[idx][FREE], *block = freePtr; + checkList(tls, idx); + size = binSizeTab[idx]; + STAT( + stat.nettoBytes += size; + stat.mallocCalls++; + ); + uchar* data = 0; + + for(;;) + { + if( block ) + { + // try to find non-full block + for(;;) + { + CV_DbgAssert( block->next->prev == block && block->prev->next == block ); + if( block->bumpPtr ) + { + data = block->bumpPtr; + if( (block->bumpPtr += size) >= block->endPtr ) + block->bumpPtr = 0; + break; + } + + if( block->privateFreeList ) + { + data = (uchar*)block->privateFreeList; + block->privateFreeList = block->privateFreeList->next; + break; + } + + if( block == startPtr ) + break; + block = block->next; + } +#if 0 + avg_k += _k; + avg_nk++; + if( avg_nk == 1000 ) + { + printf("avg search iters per 1e3 allocs = %g\n", (double)avg_k/avg_nk ); + avg_k = avg_nk = 0; + } +#endif + + freePtr = block; + if( !data ) + { + block = gcPtr; + for( int k = 0; k < 2; k++ ) + { + SANITY_CHECK(block); + CV_DbgAssert( block->next->prev == block && block->prev->next == block ); + if( block->publicFreeList ) + { + { + AutoLock lock(block->cs); + block->privateFreeList = block->publicFreeList; + block->publicFreeList = 0; + } + Node* node = block->privateFreeList; + for(;node != 0; node = node->next) + --block->allocated; + data = (uchar*)block->privateFreeList; + block->privateFreeList = block->privateFreeList->next; + gcPtr = block->next; + if( block->allocated+1 <= block->almostEmptyThreshold ) + tls->moveBlockToFreeList(block); + break; + } + block = block->next; + } + if( !data ) + gcPtr = block; + } + } + + if( data ) + break; + block = mallocPool.alloc(); + block->init(startPtr ? startPtr->prev : block, startPtr ? startPtr : block, (int)size, tls); + if( !startPtr ) + startPtr = gcPtr = freePtr = block; + checkList(tls, block->binIdx); + SANITY_CHECK(block); + } + + ++block->allocated; + return data; + } +} + +void fastFree( void* ptr ) +{ + if( ((size_t)ptr & (MEM_BLOCK_SIZE-1)) == 0 ) + { + if( ptr != 0 ) + { + void* origPtr = ((void**)ptr)[-1]; + size_t sz = (size_t)((void**)ptr)[-2]; + SystemFree( origPtr, sz ); + } + return; + } + + { + ThreadData* tls = ThreadData::get(); + Node* node = (Node*)ptr; + Block* block = (Block*)((size_t)ptr & -(int)MEM_BLOCK_SIZE); + assert( block->signature == MEM_BLOCK_SIGNATURE ); + + if( block->threadData == tls ) + { + STAT( + stat.nettoBytes -= block->objSize; + stat.freeCalls++; + float ratio = (float)stat.nettoBytes/stat.bruttoBytes; + if( stat.minUsageRatio > ratio ) + stat.minUsageRatio = ratio; + ); + + SANITY_CHECK(block); + + bool prevFilled = block->isFilled(); + --block->allocated; + if( !block->isFilled() && (block->allocated == 0 || prevFilled) ) + { + if( block->allocated == 0 ) + { + int idx = block->binIdx; + Block*& startPtr = tls->bins[idx][START]; + Block*& freePtr = tls->bins[idx][FREE]; + Block*& gcPtr = tls->bins[idx][GC]; + + if( block == block->next ) + { + CV_DbgAssert( startPtr == block && freePtr == block && gcPtr == block ); + startPtr = freePtr = gcPtr = 0; + } + else + { + if( freePtr == block ) + freePtr = block->next; + if( gcPtr == block ) + gcPtr = block->next; + if( startPtr == block ) + startPtr = block->next; + block->prev->next = block->next; + block->next->prev = block->prev; + } + mallocPool.free(block); + checkList(tls, idx); + return; + } + + tls->moveBlockToFreeList(block); + } + node->next = block->privateFreeList; + block->privateFreeList = node; + } + else + { + AutoLock lock(block->cs); + SANITY_CHECK(block); + + node->next = block->publicFreeList; + block->publicFreeList = node; + if( block->threadData == 0 ) + { + // take ownership of the abandoned block. + // note that it can happen at the same time as + // ThreadData::deleteData() marks the blocks as abandoned, + // so this part of the algorithm needs to be checked for data races + int idx = block->binIdx; + block->threadData = tls; + Block*& startPtr = tls->bins[idx][START]; + + if( startPtr ) + { + block->next = startPtr; + block->prev = startPtr->prev; + block->next->prev = block->prev->next = block; + } + else + startPtr = tls->bins[idx][FREE] = tls->bins[idx][GC] = block; + } + } + } +} + +#endif //CV_USE_SYSTEM_MALLOC + +} + +CV_IMPL void cvSetMemoryManager( CvAllocFunc, CvFreeFunc, void * ) +{ + CV_Error( -1, "Custom memory allocator is not supported" ); +} + +CV_IMPL void* cvAlloc( size_t size ) +{ + return cv::fastMalloc( size ); +} + +CV_IMPL void cvFree_( void* ptr ) +{ + cv::fastFree( ptr ); +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/arithm.cpp diffimg-2.0.0/3rdparty/opencv/core/src/arithm.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/arithm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/arithm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2937 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Arithmetic and logical operations: +, -, *, /, &, |, ^, ~, abs ... +// +// */ + +#include "precomp.hpp" + +namespace cv +{ + +#if ARITHM_USE_IPP +struct IPPArithmInitializer +{ + IPPArithmInitializer(void) + { + ippStaticInit(); + } +}; + +IPPArithmInitializer ippArithmInitializer; +#endif + +struct NOP {}; + +template +void vBinOp8(const T* src1, size_t step1, const T* src2, size_t step2, T* dst, size_t step, Size sz) +{ +#if CV_SSE2 + Op8 op8; +#endif + Op op; + + for( ; sz.height--; src1 += step1/sizeof(src1[0]), + src2 += step2/sizeof(src2[0]), + dst += step/sizeof(dst[0]) ) + { + int x = 0; + + #if CV_SSE2 + if( USE_SSE2 ) + { + for( ; x <= sz.width - 32; x += 32 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 16)); + r0 = op8(r0,_mm_loadu_si128((const __m128i*)(src2 + x))); + r1 = op8(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 16))); + _mm_storeu_si128((__m128i*)(dst + x), r0); + _mm_storeu_si128((__m128i*)(dst + x + 16), r1); + } + for( ; x <= sz.width - 8; x += 8 ) + { + __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x)); + r0 = op8(r0,_mm_loadl_epi64((const __m128i*)(src2 + x))); + _mm_storel_epi64((__m128i*)(dst + x), r0); + } + } + #endif +#if CV_ENABLE_UNROLLED + for( ; x <= sz.width - 4; x += 4 ) + { + T v0 = op(src1[x], src2[x]); + T v1 = op(src1[x+1], src2[x+1]); + dst[x] = v0; dst[x+1] = v1; + v0 = op(src1[x+2], src2[x+2]); + v1 = op(src1[x+3], src2[x+3]); + dst[x+2] = v0; dst[x+3] = v1; + } +#endif + for( ; x < sz.width; x++ ) + dst[x] = op(src1[x], src2[x]); + } +} + +template +void vBinOp16(const T* src1, size_t step1, const T* src2, size_t step2, + T* dst, size_t step, Size sz) +{ +#if CV_SSE2 + Op16 op16; +#endif + Op op; + + for( ; sz.height--; src1 += step1/sizeof(src1[0]), + src2 += step2/sizeof(src2[0]), + dst += step/sizeof(dst[0]) ) + { + int x = 0; + + #if CV_SSE2 + if( USE_SSE2 ) + { + for( ; x <= sz.width - 16; x += 16 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 8)); + r0 = op16(r0,_mm_loadu_si128((const __m128i*)(src2 + x))); + r1 = op16(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 8))); + _mm_storeu_si128((__m128i*)(dst + x), r0); + _mm_storeu_si128((__m128i*)(dst + x + 8), r1); + } + for( ; x <= sz.width - 4; x += 4 ) + { + __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x)); + r0 = op16(r0,_mm_loadl_epi64((const __m128i*)(src2 + x))); + _mm_storel_epi64((__m128i*)(dst + x), r0); + } + } + else + #endif + + for( ; x <= sz.width - 4; x += 4 ) + { + T v0 = op(src1[x], src2[x]); + T v1 = op(src1[x+1], src2[x+1]); + dst[x] = v0; dst[x+1] = v1; + v0 = op(src1[x+2], src2[x+2]); + v1 = op(src1[x+3], src2[x+3]); + dst[x+2] = v0; dst[x+3] = v1; + } + + for( ; x < sz.width; x++ ) + dst[x] = op(src1[x], src2[x]); + } +} + + +template +void vBinOp32s(const int* src1, size_t step1, const int* src2, size_t step2, + int* dst, size_t step, Size sz) +{ +#if CV_SSE2 + Op32 op32; +#endif + Op op; + + for( ; sz.height--; src1 += step1/sizeof(src1[0]), + src2 += step2/sizeof(src2[0]), + dst += step/sizeof(dst[0]) ) + { + int x = 0; + +#if CV_SSE2 + if( USE_SSE2 ) + { + if( (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 ) + for( ; x <= sz.width - 8; x += 8 ) + { + __m128i r0 = _mm_load_si128((const __m128i*)(src1 + x)); + __m128i r1 = _mm_load_si128((const __m128i*)(src1 + x + 4)); + r0 = op32(r0,_mm_load_si128((const __m128i*)(src2 + x))); + r1 = op32(r1,_mm_load_si128((const __m128i*)(src2 + x + 4))); + _mm_store_si128((__m128i*)(dst + x), r0); + _mm_store_si128((__m128i*)(dst + x + 4), r1); + } + else + for( ; x <= sz.width - 8; x += 8 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 4)); + r0 = op32(r0,_mm_loadu_si128((const __m128i*)(src2 + x))); + r1 = op32(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 4))); + _mm_storeu_si128((__m128i*)(dst + x), r0); + _mm_storeu_si128((__m128i*)(dst + x + 4), r1); + } + } +#endif +#if CV_ENABLE_UNROLLED + for( ; x <= sz.width - 4; x += 4 ) + { + int v0 = op(src1[x], src2[x]); + int v1 = op(src1[x+1], src2[x+1]); + dst[x] = v0; dst[x+1] = v1; + v0 = op(src1[x+2], src2[x+2]); + v1 = op(src1[x+3], src2[x+3]); + dst[x+2] = v0; dst[x+3] = v1; + } +#endif + for( ; x < sz.width; x++ ) + dst[x] = op(src1[x], src2[x]); + } +} + + +template +void vBinOp32f(const float* src1, size_t step1, const float* src2, size_t step2, + float* dst, size_t step, Size sz) +{ +#if CV_SSE2 + Op32 op32; +#endif + Op op; + + for( ; sz.height--; src1 += step1/sizeof(src1[0]), + src2 += step2/sizeof(src2[0]), + dst += step/sizeof(dst[0]) ) + { + int x = 0; + + #if CV_SSE2 + if( USE_SSE2 ) + { + if( (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 ) + for( ; x <= sz.width - 8; x += 8 ) + { + __m128 r0 = _mm_load_ps(src1 + x); + __m128 r1 = _mm_load_ps(src1 + x + 4); + r0 = op32(r0,_mm_load_ps(src2 + x)); + r1 = op32(r1,_mm_load_ps(src2 + x + 4)); + _mm_store_ps(dst + x, r0); + _mm_store_ps(dst + x + 4, r1); + } + else + for( ; x <= sz.width - 8; x += 8 ) + { + __m128 r0 = _mm_loadu_ps(src1 + x); + __m128 r1 = _mm_loadu_ps(src1 + x + 4); + r0 = op32(r0,_mm_loadu_ps(src2 + x)); + r1 = op32(r1,_mm_loadu_ps(src2 + x + 4)); + _mm_storeu_ps(dst + x, r0); + _mm_storeu_ps(dst + x + 4, r1); + } + } + #endif +#if CV_ENABLE_UNROLLED + for( ; x <= sz.width - 4; x += 4 ) + { + float v0 = op(src1[x], src2[x]); + float v1 = op(src1[x+1], src2[x+1]); + dst[x] = v0; dst[x+1] = v1; + v0 = op(src1[x+2], src2[x+2]); + v1 = op(src1[x+3], src2[x+3]); + dst[x+2] = v0; dst[x+3] = v1; + } +#endif + for( ; x < sz.width; x++ ) + dst[x] = op(src1[x], src2[x]); + } +} + +template +void vBinOp64f(const double* src1, size_t step1, const double* src2, size_t step2, + double* dst, size_t step, Size sz) +{ +#if CV_SSE2 + Op64 op64; +#endif + Op op; + + for( ; sz.height--; src1 += step1/sizeof(src1[0]), + src2 += step2/sizeof(src2[0]), + dst += step/sizeof(dst[0]) ) + { + int x = 0; + + #if CV_SSE2 + if( USE_SSE2 && (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 ) + for( ; x <= sz.width - 4; x += 4 ) + { + __m128d r0 = _mm_load_pd(src1 + x); + __m128d r1 = _mm_load_pd(src1 + x + 2); + r0 = op64(r0,_mm_load_pd(src2 + x)); + r1 = op64(r1,_mm_load_pd(src2 + x + 2)); + _mm_store_pd(dst + x, r0); + _mm_store_pd(dst + x + 2, r1); + } + else + #endif + for( ; x <= sz.width - 4; x += 4 ) + { + double v0 = op(src1[x], src2[x]); + double v1 = op(src1[x+1], src2[x+1]); + dst[x] = v0; dst[x+1] = v1; + v0 = op(src1[x+2], src2[x+2]); + v1 = op(src1[x+3], src2[x+3]); + dst[x+2] = v0; dst[x+3] = v1; + } + + for( ; x < sz.width; x++ ) + dst[x] = op(src1[x], src2[x]); + } +} + +#if CV_SSE2 + +struct _VAdd8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epu8(a,b); }}; +struct _VSub8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epu8(a,b); }}; +struct _VMin8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_min_epu8(a,b); }}; +struct _VMax8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_max_epu8(a,b); }}; +struct _VAbsDiff8u +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_add_epi8(_mm_subs_epu8(a,b),_mm_subs_epu8(b,a)); } +}; + +struct _VAdd8s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epi8(a,b); }}; +struct _VSub8s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epi8(a,b); }}; +struct _VMin8s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i m = _mm_cmpgt_epi8(a, b); + return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m)); + } +}; +struct _VMax8s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i m = _mm_cmpgt_epi8(b, a); + return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m)); + } +}; +struct _VAbsDiff8s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i d = _mm_subs_epi8(a, b); + __m128i m = _mm_cmpgt_epi8(b, a); + return _mm_subs_epi8(_mm_xor_si128(d, m), m); + } +}; + +struct _VAdd16u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epu16(a,b); }}; +struct _VSub16u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epu16(a,b); }}; +struct _VMin16u +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_subs_epu16(a,_mm_subs_epu16(a,b)); } +}; +struct _VMax16u +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_adds_epu16(_mm_subs_epu16(a,b),b); } +}; +struct _VAbsDiff16u +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_add_epi16(_mm_subs_epu16(a,b),_mm_subs_epu16(b,a)); } +}; + +struct _VAdd16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epi16(a,b); }}; +struct _VSub16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epi16(a,b); }}; +struct _VMin16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_min_epi16(a,b); }}; +struct _VMax16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_max_epi16(a,b); }}; +struct _VAbsDiff16s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i M = _mm_max_epi16(a,b), m = _mm_min_epi16(a,b); + return _mm_subs_epi16(M, m); + } +}; + +struct _VAdd32s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_add_epi32(a,b); }}; +struct _VSub32s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_sub_epi32(a,b); }}; +struct _VMin32s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i m = _mm_cmpgt_epi32(a, b); + return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m)); + } +}; +struct _VMax32s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i m = _mm_cmpgt_epi32(b, a); + return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m)); + } +}; +struct _VAbsDiff32s +{ + __m128i operator()(const __m128i& a, const __m128i& b) const + { + __m128i d = _mm_sub_epi32(a, b); + __m128i m = _mm_cmpgt_epi32(b, a); + return _mm_sub_epi32(_mm_xor_si128(d, m), m); + } +}; + +struct _VAdd32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_add_ps(a,b); }}; +struct _VSub32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_sub_ps(a,b); }}; +struct _VMin32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_min_ps(a,b); }}; +struct _VMax32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_max_ps(a,b); }}; +static int CV_DECL_ALIGNED(16) v32f_absmask[] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }; +struct _VAbsDiff32f +{ + __m128 operator()(const __m128& a, const __m128& b) const + { + return _mm_and_ps(_mm_sub_ps(a,b), *(const __m128*)v32f_absmask); + } +}; + +struct _VAdd64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_add_pd(a,b); }}; +struct _VSub64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_sub_pd(a,b); }}; +struct _VMin64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_min_pd(a,b); }}; +struct _VMax64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_max_pd(a,b); }}; + +static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff }; +struct _VAbsDiff64f +{ + __m128d operator()(const __m128d& a, const __m128d& b) const + { + return _mm_and_pd(_mm_sub_pd(a,b), *(const __m128d*)v64f_absmask); + } +}; + +struct _VAnd8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_and_si128(a,b); }}; +struct _VOr8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_or_si128(a,b); }}; +struct _VXor8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_xor_si128(a,b); }}; +struct _VNot8u { __m128i operator()(const __m128i& a, const __m128i&) const { return _mm_xor_si128(_mm_set1_epi32(-1),a); }}; + +#endif + +#if CV_SSE2 +#define IF_SIMD(op) op +#else +#define IF_SIMD(op) NOP +#endif + +template<> inline uchar OpAdd::operator ()(uchar a, uchar b) const +{ return CV_FAST_CAST_8U(a + b); } +template<> inline uchar OpSub::operator ()(uchar a, uchar b) const +{ return CV_FAST_CAST_8U(a - b); } + +template struct OpAbsDiff +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator()(T a, T b) const { return (T)std::abs(a - b); } +}; + +template<> inline short OpAbsDiff::operator ()(short a, short b) const +{ return saturate_cast(std::abs(a - b)); } + +template<> inline schar OpAbsDiff::operator ()(schar a, schar b) const +{ return saturate_cast(std::abs(a - b)); } + +template struct OpAbsDiffS +{ + typedef T type1; + typedef WT type2; + typedef T rtype; + T operator()(T a, WT b) const { return saturate_cast(std::abs(a - b)); } +}; + +template struct OpAnd +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator()( T a, T b ) const { return a & b; } +}; + +template struct OpOr +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator()( T a, T b ) const { return a | b; } +}; + +template struct OpXor +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator()( T a, T b ) const { return a ^ b; } +}; + +template struct OpNot +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator()( T a, T ) const { return ~a; } +}; + +static inline void fixSteps(Size sz, size_t elemSize, size_t& step1, size_t& step2, size_t& step) +{ + if( sz.height == 1 ) + step1 = step2 = step = sz.width*elemSize; +} + +static void add8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAdd_8u_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp8, IF_SIMD(_VAdd8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void add8s( const schar* src1, size_t step1, + const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* ) +{ + vBinOp8, IF_SIMD(_VAdd8s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void add16u( const ushort* src1, size_t step1, + const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAdd_16u_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp16, IF_SIMD(_VAdd16u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void add16s( const short* src1, size_t step1, + const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAdd_16s_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp16, IF_SIMD(_VAdd16s)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void add32s( const int* src1, size_t step1, + const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* ) +{ + vBinOp32s, IF_SIMD(_VAdd32s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void add32f( const float* src1, size_t step1, + const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAdd_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp32f, IF_SIMD(_VAdd32f)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void add64f( const double* src1, size_t step1, + const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* ) +{ + vBinOp64f, IF_SIMD(_VAdd64f)>(src1, step1, src2, step2, dst, step, sz); +} + +static void sub8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiSub_8u_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp8, IF_SIMD(_VSub8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void sub8s( const schar* src1, size_t step1, + const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* ) +{ + vBinOp8, IF_SIMD(_VSub8s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void sub16u( const ushort* src1, size_t step1, + const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiSub_16u_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp16, IF_SIMD(_VSub16u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void sub16s( const short* src1, size_t step1, + const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiSub_16s_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (int)step, (IppiSize&)sz, 0), + (vBinOp16, IF_SIMD(_VSub16s)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void sub32s( const int* src1, size_t step1, + const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* ) +{ + vBinOp32s, IF_SIMD(_VSub32s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void sub32f( const float* src1, size_t step1, + const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiSub_32f_C1R(src2, (int)step2, src1, (int)step1, dst, (int)step, (IppiSize&)sz), + (vBinOp32f, IF_SIMD(_VSub32f)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void sub64f( const double* src1, size_t step1, + const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* ) +{ + vBinOp64f, IF_SIMD(_VSub64f)>(src1, step1, src2, step2, dst, step, sz); +} + +template<> inline uchar OpMin::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); } +template<> inline uchar OpMax::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); } + +static void max8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + uchar* s1 = (uchar*)src1; + uchar* s2 = (uchar*)src2; + uchar* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMaxEvery_8u(s1, s2, d, sz.width); + s1 += step1; + s2 += step2; + d += step; + } + } +#else + vBinOp8, IF_SIMD(_VMax8u)>(src1, step1, src2, step2, dst, step, sz); +#endif + +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMaxEvery_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp8, IF_SIMD(_VMax8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void max8s( const schar* src1, size_t step1, + const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* ) +{ + vBinOp8, IF_SIMD(_VMax8s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void max16u( const ushort* src1, size_t step1, + const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + ushort* s1 = (ushort*)src1; + ushort* s2 = (ushort*)src2; + ushort* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMaxEvery_16u(s1, s2, d, sz.width); + s1 = (ushort*)((uchar*)s1 + step1); + s2 = (ushort*)((uchar*)s2 + step2); + d = (ushort*)((uchar*)d + step); + } + } +#else + vBinOp16, IF_SIMD(_VMax16u)>(src1, step1, src2, step2, dst, step, sz); +#endif + +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMaxEvery_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp16, IF_SIMD(_VMax16u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void max16s( const short* src1, size_t step1, + const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* ) +{ + vBinOp16, IF_SIMD(_VMax16s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void max32s( const int* src1, size_t step1, + const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* ) +{ + vBinOp32s, IF_SIMD(_VMax32s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void max32f( const float* src1, size_t step1, + const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + float* s1 = (float*)src1; + float* s2 = (float*)src2; + float* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMaxEvery_32f(s1, s2, d, sz.width); + s1 = (float*)((uchar*)s1 + step1); + s2 = (float*)((uchar*)s2 + step2); + d = (float*)((uchar*)d + step); + } + } +#else + vBinOp32f, IF_SIMD(_VMax32f)>(src1, step1, src2, step2, dst, step, sz); +#endif +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMaxEvery_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp32f, IF_SIMD(_VMax32f)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void max64f( const double* src1, size_t step1, + const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* ) +{ + vBinOp64f, IF_SIMD(_VMax64f)>(src1, step1, src2, step2, dst, step, sz); +} + +static void min8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + uchar* s1 = (uchar*)src1; + uchar* s2 = (uchar*)src2; + uchar* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMinEvery_8u(s1, s2, d, sz.width); + s1 += step1; + s2 += step2; + d += step; + } + } +#else + vBinOp8, IF_SIMD(_VMin8u)>(src1, step1, src2, step2, dst, step, sz); +#endif + +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMinEvery_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp8, IF_SIMD(_VMin8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void min8s( const schar* src1, size_t step1, + const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* ) +{ + vBinOp8, IF_SIMD(_VMin8s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void min16u( const ushort* src1, size_t step1, + const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + ushort* s1 = (ushort*)src1; + ushort* s2 = (ushort*)src2; + ushort* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMinEvery_16u(s1, s2, d, sz.width); + s1 = (ushort*)((uchar*)s1 + step1); + s2 = (ushort*)((uchar*)s2 + step2); + d = (ushort*)((uchar*)d + step); + } + } +#else + vBinOp16, IF_SIMD(_VMin16u)>(src1, step1, src2, step2, dst, step, sz); +#endif + +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMinEvery_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp16, IF_SIMD(_VMin16u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void min16s( const short* src1, size_t step1, + const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* ) +{ + vBinOp16, IF_SIMD(_VMin16s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void min32s( const int* src1, size_t step1, + const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* ) +{ + vBinOp32s, IF_SIMD(_VMin32s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void min32f( const float* src1, size_t step1, + const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* ) +{ +#if (ARITHM_USE_IPP == 1) + { + float* s1 = (float*)src1; + float* s2 = (float*)src2; + float* d = dst; + fixSteps(sz, sizeof(dst[0]), step1, step2, step); + for(int i = 0; i < sz.height; i++) + { + ippsMinEvery_32f(s1, s2, d, sz.width); + s1 = (float*)((uchar*)s1 + step1); + s2 = (float*)((uchar*)s2 + step2); + d = (float*)((uchar*)d + step); + } + } +#else + vBinOp32f, IF_SIMD(_VMin32f)>(src1, step1, src2, step2, dst, step, sz); +#endif +// IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); +// ippiMinEvery_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz), +// (vBinOp32f, IF_SIMD(_VMin32f)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void min64f( const double* src1, size_t step1, + const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* ) +{ + vBinOp64f, IF_SIMD(_VMin64f)>(src1, step1, src2, step2, dst, step, sz); +} + +static void absdiff8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAbsDiff_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp8, IF_SIMD(_VAbsDiff8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void absdiff8s( const schar* src1, size_t step1, + const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* ) +{ + vBinOp8, IF_SIMD(_VAbsDiff8s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void absdiff16u( const ushort* src1, size_t step1, + const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAbsDiff_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp16, IF_SIMD(_VAbsDiff16u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void absdiff16s( const short* src1, size_t step1, + const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* ) +{ + vBinOp16, IF_SIMD(_VAbsDiff16s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void absdiff32s( const int* src1, size_t step1, + const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* ) +{ + vBinOp32s, IF_SIMD(_VAbsDiff32s)>(src1, step1, src2, step2, dst, step, sz); +} + +static void absdiff32f( const float* src1, size_t step1, + const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAbsDiff_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp32f, IF_SIMD(_VAbsDiff32f)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void absdiff64f( const double* src1, size_t step1, + const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* ) +{ + vBinOp64f, IF_SIMD(_VAbsDiff64f)>(src1, step1, src2, step2, dst, step, sz); +} + + +static void and8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiAnd_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp8, IF_SIMD(_VAnd8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void or8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiOr_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp8, IF_SIMD(_VOr8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void xor8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiXor_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (int)step, (IppiSize&)sz), + (vBinOp8, IF_SIMD(_VXor8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +static void not8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* ) +{ + IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step); + ippiNot_8u_C1R(src1, (int)step1, dst, (int)step, (IppiSize&)sz), + (vBinOp8, IF_SIMD(_VNot8u)>(src1, step1, src2, step2, dst, step, sz))); +} + +/****************************************************************************************\ +* logical operations * +\****************************************************************************************/ + +void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize ) +{ + int scn = (int)sc.total(), cn = CV_MAT_CN(buftype); + size_t esz = CV_ELEM_SIZE(buftype); + getConvertFunc(sc.depth(), buftype)(sc.data, 0, 0, 0, scbuf, 0, Size(std::min(cn, scn), 1), 0); + // unroll the scalar + if( scn < cn ) + { + CV_Assert( scn == 1 ); + size_t esz1 = CV_ELEM_SIZE1(buftype); + for( size_t i = esz1; i < esz; i++ ) + scbuf[i] = scbuf[i - esz1]; + } + for( size_t i = esz; i < blocksize*esz; i++ ) + scbuf[i] = scbuf[i - esz]; +} + +static void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst, + InputArray _mask, const BinaryFunc* tab, bool bitwise) +{ + int kind1 = _src1.kind(), kind2 = _src2.kind(); + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + bool haveMask = !_mask.empty(), haveScalar = false; + BinaryFunc func; + int c; + + if( src1.dims <= 2 && src2.dims <= 2 && kind1 == kind2 && + src1.size() == src2.size() && src1.type() == src2.type() && !haveMask ) + { + _dst.create(src1.size(), src1.type()); + Mat dst = _dst.getMat(); + if( bitwise ) + { + func = *tab; + c = (int)src1.elemSize(); + } + else + { + func = tab[src1.depth()]; + c = src1.channels(); + } + + Size sz = getContinuousSize(src1, src2, dst); + size_t len = sz.width*(size_t)c; + if( len == (size_t)(int)len ) + { + sz.width = (int)len; + func(src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, 0); + return; + } + } + + if( (kind1 == _InputArray::MATX) + (kind2 == _InputArray::MATX) == 1 || + src1.size != src2.size || src1.type() != src2.type() ) + { + if( checkScalar(src1, src2.type(), kind1, kind2) ) + // src1 is a scalar; swap it with src2 + swap(src1, src2); + else if( !checkScalar(src2, src1.type(), kind2, kind1) ) + CV_Error( CV_StsUnmatchedSizes, + "The operation is neither 'array op array' (where arrays have the same size and type), " + "nor 'array op scalar', nor 'scalar op array'" ); + haveScalar = true; + } + + size_t esz = src1.elemSize(); + size_t blocksize0 = (BLOCK_SIZE + esz-1)/esz; + int cn = src1.channels(); + BinaryFunc copymask = 0; + Mat mask; + bool reallocate = false; + + if( haveMask ) + { + mask = _mask.getMat(); + CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) ); + CV_Assert( mask.size == src1.size ); + copymask = getCopyMaskFunc(esz); + Mat tdst = _dst.getMat(); + reallocate = tdst.size != src1.size || tdst.type() != src1.type(); + } + + AutoBuffer _buf; + uchar *scbuf = 0, *maskbuf = 0; + + _dst.create(src1.dims, src1.size, src1.type()); + Mat dst = _dst.getMat(); + + // if this is mask operation and dst has been reallocated, + // we have to + if( haveMask && reallocate ) + dst = Scalar::all(0); + + if( bitwise ) + { + func = *tab; + c = (int)esz; + } + else + { + func = tab[src1.depth()]; + c = cn; + } + + if( !haveScalar ) + { + const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 }; + uchar* ptrs[4]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size, blocksize = total; + + if( blocksize*c > INT_MAX ) + blocksize = INT_MAX/c; + + if( haveMask ) + { + blocksize = std::min(blocksize, blocksize0); + _buf.allocate(blocksize*esz); + maskbuf = _buf; + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + + func( ptrs[0], 0, ptrs[1], 0, haveMask ? maskbuf : ptrs[2], 0, Size(bsz*c, 1), 0 ); + if( haveMask ) + { + copymask( maskbuf, 0, ptrs[3], 0, ptrs[2], 0, Size(bsz, 1), &esz ); + ptrs[3] += bsz; + } + + bsz *= (int)esz; + ptrs[0] += bsz; ptrs[1] += bsz; ptrs[2] += bsz; + } + } + } + else + { + const Mat* arrays[] = { &src1, &dst, &mask, 0 }; + uchar* ptrs[3]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size, blocksize = std::min(total, blocksize0); + + _buf.allocate(blocksize*(haveMask ? 2 : 1)*esz + 32); + scbuf = _buf; + maskbuf = alignPtr(scbuf + blocksize*esz, 16); + + convertAndUnrollScalar( src2, src1.type(), scbuf, blocksize); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + + func( ptrs[0], 0, scbuf, 0, haveMask ? maskbuf : ptrs[1], 0, Size(bsz*c, 1), 0 ); + if( haveMask ) + { + copymask( maskbuf, 0, ptrs[2], 0, ptrs[1], 0, Size(bsz, 1), &esz ); + ptrs[2] += bsz; + } + + bsz *= (int)esz; + ptrs[0] += bsz; ptrs[1] += bsz; + } + } + } +} + +static BinaryFunc maxTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(max8u), (BinaryFunc)GET_OPTIMIZED(max8s), + (BinaryFunc)GET_OPTIMIZED(max16u), (BinaryFunc)GET_OPTIMIZED(max16s), + (BinaryFunc)GET_OPTIMIZED(max32s), + (BinaryFunc)GET_OPTIMIZED(max32f), (BinaryFunc)max64f, + 0 +}; + +static BinaryFunc minTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(min8u), (BinaryFunc)GET_OPTIMIZED(min8s), + (BinaryFunc)GET_OPTIMIZED(min16u), (BinaryFunc)GET_OPTIMIZED(min16s), + (BinaryFunc)GET_OPTIMIZED(min32s), + (BinaryFunc)GET_OPTIMIZED(min32f), (BinaryFunc)min64f, + 0 +}; + +} + +void cv::bitwise_and(InputArray a, InputArray b, OutputArray c, InputArray mask) +{ + BinaryFunc f = (BinaryFunc)GET_OPTIMIZED(and8u); + binary_op(a, b, c, mask, &f, true); +} + +void cv::bitwise_or(InputArray a, InputArray b, OutputArray c, InputArray mask) +{ + BinaryFunc f = (BinaryFunc)GET_OPTIMIZED(or8u); + binary_op(a, b, c, mask, &f, true); +} + +void cv::bitwise_xor(InputArray a, InputArray b, OutputArray c, InputArray mask) +{ + BinaryFunc f = (BinaryFunc)GET_OPTIMIZED(xor8u); + binary_op(a, b, c, mask, &f, true); +} + +void cv::bitwise_not(InputArray a, OutputArray c, InputArray mask) +{ + BinaryFunc f = (BinaryFunc)GET_OPTIMIZED(not8u); + binary_op(a, a, c, mask, &f, true); +} + +void cv::max( InputArray src1, InputArray src2, OutputArray dst ) +{ + binary_op(src1, src2, dst, noArray(), maxTab, false ); +} + +void cv::min( InputArray src1, InputArray src2, OutputArray dst ) +{ + binary_op(src1, src2, dst, noArray(), minTab, false ); +} + +void cv::max(const Mat& src1, const Mat& src2, Mat& dst) +{ + OutputArray _dst(dst); + binary_op(src1, src2, _dst, noArray(), maxTab, false ); +} + +void cv::min(const Mat& src1, const Mat& src2, Mat& dst) +{ + OutputArray _dst(dst); + binary_op(src1, src2, _dst, noArray(), minTab, false ); +} + +void cv::max(const Mat& src1, double src2, Mat& dst) +{ + OutputArray _dst(dst); + binary_op(src1, src2, _dst, noArray(), maxTab, false ); +} + +void cv::min(const Mat& src1, double src2, Mat& dst) +{ + OutputArray _dst(dst); + binary_op(src1, src2, _dst, noArray(), minTab, false ); +} + +/****************************************************************************************\ +* add/subtract * +\****************************************************************************************/ + +namespace cv +{ + +static int actualScalarDepth(const double* data, int len) +{ + int i = 0, minval = INT_MAX, maxval = INT_MIN; + for(; i < len; ++i) + { + int ival = cvRound(data[i]); + if( ival != data[i] ) + break; + minval = MIN(minval, ival); + maxval = MAX(maxval, ival); + } + return i < len ? CV_64F : + minval >= 0 && maxval <= (int)UCHAR_MAX ? CV_8U : + minval >= (int)SCHAR_MIN && maxval <= (int)SCHAR_MAX ? CV_8S : + minval >= 0 && maxval <= (int)USHRT_MAX ? CV_16U : + minval >= (int)SHRT_MIN && maxval <= (int)SHRT_MAX ? CV_16S : + CV_32S; +} + +static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, + InputArray _mask, int dtype, BinaryFunc* tab, bool muldiv=false, void* usrdata=0) +{ + int kind1 = _src1.kind(), kind2 = _src2.kind(); + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + bool haveMask = !_mask.empty(); + bool reallocate = false; + + bool src1Scalar = checkScalar(src1, src2.type(), kind1, kind2); + bool src2Scalar = checkScalar(src2, src1.type(), kind2, kind1); + + if( (kind1 == kind2 || src1.channels() == 1) && src1.dims <= 2 && src2.dims <= 2 && + src1.size() == src2.size() && src1.type() == src2.type() && + !haveMask && ((!_dst.fixedType() && (dtype < 0 || CV_MAT_DEPTH(dtype) == src1.depth())) || + (_dst.fixedType() && _dst.type() == _src1.type())) && + ((src1Scalar && src2Scalar) || (!src1Scalar && !src2Scalar)) ) + { + _dst.create(src1.size(), src1.type()); + Mat dst = _dst.getMat(); + Size sz = getContinuousSize(src1, src2, dst, src1.channels()); + tab[src1.depth()](src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, usrdata); + return; + } + + bool haveScalar = false, swapped12 = false; + int depth2 = src2.depth(); + if( src1.size != src2.size || src1.channels() != src2.channels() || + ((kind1 == _InputArray::MATX || kind2 == _InputArray::MATX) && + src1.cols == 1 && src2.rows == 4) ) + { + if( checkScalar(src1, src2.type(), kind1, kind2) ) + { + // src1 is a scalar; swap it with src2 + swap(src1, src2); + swapped12 = true; + } + else if( !checkScalar(src2, src1.type(), kind2, kind1) ) + CV_Error( CV_StsUnmatchedSizes, + "The operation is neither 'array op array' (where arrays have the same size and the same number of channels), " + "nor 'array op scalar', nor 'scalar op array'" ); + haveScalar = true; + CV_Assert(src2.type() == CV_64F && (src2.rows == 4 || src2.rows == 1)); + + if (!muldiv) + { + depth2 = actualScalarDepth(src2.ptr(), src1.channels()); + if( depth2 == CV_64F && (src1.depth() < CV_32S || src1.depth() == CV_32F) ) + depth2 = CV_32F; + } + else + depth2 = CV_64F; + } + + int cn = src1.channels(), depth1 = src1.depth(), wtype; + BinaryFunc cvtsrc1 = 0, cvtsrc2 = 0, cvtdst = 0; + + if( dtype < 0 ) + { + if( _dst.fixedType() ) + dtype = _dst.type(); + else + { + if( !haveScalar && src1.type() != src2.type() ) + CV_Error(CV_StsBadArg, + "When the input arrays in add/subtract/multiply/divide functions have different types, " + "the output array type must be explicitly specified"); + dtype = src1.type(); + } + } + dtype = CV_MAT_DEPTH(dtype); + + if( depth1 == depth2 && dtype == depth1 ) + wtype = dtype; + else if( !muldiv ) + { + wtype = depth1 <= CV_8S && depth2 <= CV_8S ? CV_16S : + depth1 <= CV_32S && depth2 <= CV_32S ? CV_32S : std::max(depth1, depth2); + wtype = std::max(wtype, dtype); + + // when the result of addition should be converted to an integer type, + // and just one of the input arrays is floating-point, it makes sense to convert that input to integer type before the operation, + // instead of converting the other input to floating-point and then converting the operation result back to integers. + if( dtype < CV_32F && (depth1 < CV_32F || depth2 < CV_32F) ) + wtype = CV_32S; + } + else + { + wtype = std::max(depth1, std::max(depth2, CV_32F)); + wtype = std::max(wtype, dtype); + } + + cvtsrc1 = depth1 == wtype ? 0 : getConvertFunc(depth1, wtype); + cvtsrc2 = depth2 == depth1 ? cvtsrc1 : depth2 == wtype ? 0 : getConvertFunc(depth2, wtype); + cvtdst = dtype == wtype ? 0 : getConvertFunc(wtype, dtype); + + dtype = CV_MAKETYPE(dtype, cn); + wtype = CV_MAKETYPE(wtype, cn); + + size_t esz1 = src1.elemSize(), esz2 = src2.elemSize(); + size_t dsz = CV_ELEM_SIZE(dtype), wsz = CV_ELEM_SIZE(wtype); + size_t blocksize0 = (size_t)(BLOCK_SIZE + wsz-1)/wsz; + BinaryFunc copymask = 0; + Mat mask; + + if( haveMask ) + { + mask = _mask.getMat(); + CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) ); + CV_Assert( mask.size == src1.size ); + copymask = getCopyMaskFunc(dsz); + Mat tdst = _dst.getMat(); + reallocate = tdst.size != src1.size || tdst.type() != dtype; + } + + AutoBuffer _buf; + uchar *buf, *maskbuf = 0, *buf1 = 0, *buf2 = 0, *wbuf = 0; + size_t bufesz = (cvtsrc1 ? wsz : 0) + (cvtsrc2 || haveScalar ? wsz : 0) + (cvtdst ? wsz : 0) + (haveMask ? dsz : 0); + + _dst.create(src1.dims, src1.size, dtype); + Mat dst = _dst.getMat(); + + if( haveMask && reallocate ) + dst = Scalar::all(0); + + BinaryFunc func = tab[CV_MAT_DEPTH(wtype)]; + + if( !haveScalar ) + { + const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 }; + uchar* ptrs[4]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size, blocksize = total; + + if( haveMask || cvtsrc1 || cvtsrc2 || cvtdst ) + blocksize = std::min(blocksize, blocksize0); + + _buf.allocate(bufesz*blocksize + 64); + buf = _buf; + if( cvtsrc1 ) + buf1 = buf, buf = alignPtr(buf + blocksize*wsz, 16); + if( cvtsrc2 ) + buf2 = buf, buf = alignPtr(buf + blocksize*wsz, 16); + wbuf = maskbuf = buf; + if( cvtdst ) + buf = alignPtr(buf + blocksize*wsz, 16); + if( haveMask ) + maskbuf = buf; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + Size bszn(bsz*cn, 1); + const uchar *sptr1 = ptrs[0], *sptr2 = ptrs[1]; + uchar* dptr = ptrs[2]; + if( cvtsrc1 ) + { + cvtsrc1( sptr1, 0, 0, 0, buf1, 0, bszn, 0 ); + sptr1 = buf1; + } + if( ptrs[0] == ptrs[1] ) + sptr2 = sptr1; + else if( cvtsrc2 ) + { + cvtsrc2( sptr2, 0, 0, 0, buf2, 0, bszn, 0 ); + sptr2 = buf2; + } + + if( !haveMask && !cvtdst ) + func( sptr1, 0, sptr2, 0, dptr, 0, bszn, usrdata ); + else + { + func( sptr1, 0, sptr2, 0, wbuf, 0, bszn, usrdata ); + if( !haveMask ) + cvtdst( wbuf, 0, 0, 0, dptr, 0, bszn, 0 ); + else if( !cvtdst ) + { + copymask( wbuf, 0, ptrs[3], 0, dptr, 0, Size(bsz, 1), &dsz ); + ptrs[3] += bsz; + } + else + { + cvtdst( wbuf, 0, 0, 0, maskbuf, 0, bszn, 0 ); + copymask( maskbuf, 0, ptrs[3], 0, dptr, 0, Size(bsz, 1), &dsz ); + ptrs[3] += bsz; + } + } + ptrs[0] += bsz*esz1; ptrs[1] += bsz*esz2; ptrs[2] += bsz*dsz; + } + } + } + else + { + const Mat* arrays[] = { &src1, &dst, &mask, 0 }; + uchar* ptrs[3]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size, blocksize = std::min(total, blocksize0); + + _buf.allocate(bufesz*blocksize + 64); + buf = _buf; + if( cvtsrc1 ) + buf1 = buf, buf = alignPtr(buf + blocksize*wsz, 16); + buf2 = buf; buf = alignPtr(buf + blocksize*wsz, 16); + wbuf = maskbuf = buf; + if( cvtdst ) + buf = alignPtr(buf + blocksize*wsz, 16); + if( haveMask ) + maskbuf = buf; + + convertAndUnrollScalar( src2, wtype, buf2, blocksize); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + Size bszn(bsz*cn, 1); + const uchar *sptr1 = ptrs[0]; + const uchar* sptr2 = buf2; + uchar* dptr = ptrs[1]; + + if( cvtsrc1 ) + { + cvtsrc1( sptr1, 0, 0, 0, buf1, 0, bszn, 0 ); + sptr1 = buf1; + } + + if( swapped12 ) + std::swap(sptr1, sptr2); + + if( !haveMask && !cvtdst ) + func( sptr1, 0, sptr2, 0, dptr, 0, bszn, usrdata ); + else + { + func( sptr1, 0, sptr2, 0, wbuf, 0, bszn, usrdata ); + if( !haveMask ) + cvtdst( wbuf, 0, 0, 0, dptr, 0, bszn, 0 ); + else if( !cvtdst ) + { + copymask( wbuf, 0, ptrs[2], 0, dptr, 0, Size(bsz, 1), &dsz ); + ptrs[2] += bsz; + } + else + { + cvtdst( wbuf, 0, 0, 0, maskbuf, 0, bszn, 0 ); + copymask( maskbuf, 0, ptrs[2], 0, dptr, 0, Size(bsz, 1), &dsz ); + ptrs[2] += bsz; + } + } + ptrs[0] += bsz*esz1; ptrs[1] += bsz*dsz; + } + } + } +} + +static BinaryFunc addTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(add8u), (BinaryFunc)GET_OPTIMIZED(add8s), + (BinaryFunc)GET_OPTIMIZED(add16u), (BinaryFunc)GET_OPTIMIZED(add16s), + (BinaryFunc)GET_OPTIMIZED(add32s), + (BinaryFunc)GET_OPTIMIZED(add32f), (BinaryFunc)add64f, + 0 +}; + +static BinaryFunc subTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(sub8u), (BinaryFunc)GET_OPTIMIZED(sub8s), + (BinaryFunc)GET_OPTIMIZED(sub16u), (BinaryFunc)GET_OPTIMIZED(sub16s), + (BinaryFunc)GET_OPTIMIZED(sub32s), + (BinaryFunc)GET_OPTIMIZED(sub32f), (BinaryFunc)sub64f, + 0 +}; + +static BinaryFunc absdiffTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(absdiff8u), (BinaryFunc)GET_OPTIMIZED(absdiff8s), + (BinaryFunc)GET_OPTIMIZED(absdiff16u), (BinaryFunc)GET_OPTIMIZED(absdiff16s), + (BinaryFunc)GET_OPTIMIZED(absdiff32s), + (BinaryFunc)GET_OPTIMIZED(absdiff32f), (BinaryFunc)absdiff64f, + 0 +}; + +} + +void cv::add( InputArray src1, InputArray src2, OutputArray dst, + InputArray mask, int dtype ) +{ + arithm_op(src1, src2, dst, mask, dtype, addTab ); +} + +void cv::subtract( InputArray src1, InputArray src2, OutputArray dst, + InputArray mask, int dtype ) +{ +#ifdef HAVE_TEGRA_OPTIMIZATION + if (mask.empty() && src1.depth() == CV_8U && src2.depth() == CV_8U) + { + if (dtype == -1 && dst.fixedType()) + dtype = dst.depth(); + + if (!dst.fixedType() || dtype == dst.depth()) + { + if (dtype == CV_16S) + { + Mat _dst = dst.getMat(); + if(tegra::subtract_8u8u16s(src1.getMat(), src2.getMat(), _dst)) + return; + } + else if (dtype == CV_32F) + { + Mat _dst = dst.getMat(); + if(tegra::subtract_8u8u32f(src1.getMat(), src2.getMat(), _dst)) + return; + } + else if (dtype == CV_8S) + { + Mat _dst = dst.getMat(); + if(tegra::subtract_8u8u8s(src1.getMat(), src2.getMat(), _dst)) + return; + } + } + } +#endif + arithm_op(src1, src2, dst, mask, dtype, subTab ); +} + +void cv::absdiff( InputArray src1, InputArray src2, OutputArray dst ) +{ + arithm_op(src1, src2, dst, noArray(), -1, absdiffTab); +} + +/****************************************************************************************\ +* multiply/divide * +\****************************************************************************************/ + +namespace cv +{ + +template static void +mul_( const T* src1, size_t step1, const T* src2, size_t step2, + T* dst, size_t step, Size size, WT scale ) +{ + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + step /= sizeof(dst[0]); + + if( scale == (WT)1. ) + { + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int i=0; + #if CV_ENABLE_UNROLLED + for(; i <= size.width - 4; i += 4 ) + { + T t0; + T t1; + t0 = saturate_cast(src1[i ] * src2[i ]); + t1 = saturate_cast(src1[i+1] * src2[i+1]); + dst[i ] = t0; + dst[i+1] = t1; + + t0 = saturate_cast(src1[i+2] * src2[i+2]); + t1 = saturate_cast(src1[i+3] * src2[i+3]); + dst[i+2] = t0; + dst[i+3] = t1; + } + #endif + for( ; i < size.width; i++ ) + dst[i] = saturate_cast(src1[i] * src2[i]); + } + } + else + { + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int i = 0; + #if CV_ENABLE_UNROLLED + for(; i <= size.width - 4; i += 4 ) + { + T t0 = saturate_cast(scale*(WT)src1[i]*src2[i]); + T t1 = saturate_cast(scale*(WT)src1[i+1]*src2[i+1]); + dst[i] = t0; dst[i+1] = t1; + + t0 = saturate_cast(scale*(WT)src1[i+2]*src2[i+2]); + t1 = saturate_cast(scale*(WT)src1[i+3]*src2[i+3]); + dst[i+2] = t0; dst[i+3] = t1; + } + #endif + for( ; i < size.width; i++ ) + dst[i] = saturate_cast(scale*(WT)src1[i]*src2[i]); + } + } +} + +template static void +div_( const T* src1, size_t step1, const T* src2, size_t step2, + T* dst, size_t step, Size size, double scale ) +{ + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + step /= sizeof(dst[0]); + + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int i = 0; + #if CV_ENABLE_UNROLLED + for( ; i <= size.width - 4; i += 4 ) + { + if( src2[i] != 0 && src2[i+1] != 0 && src2[i+2] != 0 && src2[i+3] != 0 ) + { + double a = (double)src2[i] * src2[i+1]; + double b = (double)src2[i+2] * src2[i+3]; + double d = scale/(a * b); + b *= d; + a *= d; + + T z0 = saturate_cast(src2[i+1] * ((double)src1[i] * b)); + T z1 = saturate_cast(src2[i] * ((double)src1[i+1] * b)); + T z2 = saturate_cast(src2[i+3] * ((double)src1[i+2] * a)); + T z3 = saturate_cast(src2[i+2] * ((double)src1[i+3] * a)); + + dst[i] = z0; dst[i+1] = z1; + dst[i+2] = z2; dst[i+3] = z3; + } + else + { + T z0 = src2[i] != 0 ? saturate_cast(src1[i]*scale/src2[i]) : 0; + T z1 = src2[i+1] != 0 ? saturate_cast(src1[i+1]*scale/src2[i+1]) : 0; + T z2 = src2[i+2] != 0 ? saturate_cast(src1[i+2]*scale/src2[i+2]) : 0; + T z3 = src2[i+3] != 0 ? saturate_cast(src1[i+3]*scale/src2[i+3]) : 0; + + dst[i] = z0; dst[i+1] = z1; + dst[i+2] = z2; dst[i+3] = z3; + } + } + #endif + for( ; i < size.width; i++ ) + dst[i] = src2[i] != 0 ? saturate_cast(src1[i]*scale/src2[i]) : 0; + } +} + +template static void +recip_( const T*, size_t, const T* src2, size_t step2, + T* dst, size_t step, Size size, double scale ) +{ + step2 /= sizeof(src2[0]); + step /= sizeof(dst[0]); + + for( ; size.height--; src2 += step2, dst += step ) + { + int i = 0; + #if CV_ENABLE_UNROLLED + for( ; i <= size.width - 4; i += 4 ) + { + if( src2[i] != 0 && src2[i+1] != 0 && src2[i+2] != 0 && src2[i+3] != 0 ) + { + double a = (double)src2[i] * src2[i+1]; + double b = (double)src2[i+2] * src2[i+3]; + double d = scale/(a * b); + b *= d; + a *= d; + + T z0 = saturate_cast(src2[i+1] * b); + T z1 = saturate_cast(src2[i] * b); + T z2 = saturate_cast(src2[i+3] * a); + T z3 = saturate_cast(src2[i+2] * a); + + dst[i] = z0; dst[i+1] = z1; + dst[i+2] = z2; dst[i+3] = z3; + } + else + { + T z0 = src2[i] != 0 ? saturate_cast(scale/src2[i]) : 0; + T z1 = src2[i+1] != 0 ? saturate_cast(scale/src2[i+1]) : 0; + T z2 = src2[i+2] != 0 ? saturate_cast(scale/src2[i+2]) : 0; + T z3 = src2[i+3] != 0 ? saturate_cast(scale/src2[i+3]) : 0; + + dst[i] = z0; dst[i+1] = z1; + dst[i+2] = z2; dst[i+3] = z3; + } + } + #endif + for( ; i < size.width; i++ ) + dst[i] = src2[i] != 0 ? saturate_cast(scale/src2[i]) : 0; + } +} + + +static void mul8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale); +} + +static void mul8s( const schar* src1, size_t step1, const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale); +} + +static void mul16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale); +} + +static void mul16s( const short* src1, size_t step1, const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale); +} + +static void mul32s( const int* src1, size_t step1, const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void mul32f( const float* src1, size_t step1, const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale); +} + +static void mul64f( const double* src1, size_t step1, const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* scale) +{ + mul_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* scale) +{ + if( src1 ) + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); + else + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div8s( const schar* src1, size_t step1, const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div16s( const short* src1, size_t step1, const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div32s( const int* src1, size_t step1, const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div32f( const float* src1, size_t step1, const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void div64f( const double* src1, size_t step1, const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* scale) +{ + div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip8s( const schar* src1, size_t step1, const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip16s( const short* src1, size_t step1, const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip32s( const int* src1, size_t step1, const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip32f( const float* src1, size_t step1, const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + +static void recip64f( const double* src1, size_t step1, const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* scale) +{ + recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale); +} + + +static BinaryFunc mulTab[] = +{ + (BinaryFunc)mul8u, (BinaryFunc)mul8s, (BinaryFunc)mul16u, + (BinaryFunc)mul16s, (BinaryFunc)mul32s, (BinaryFunc)mul32f, + (BinaryFunc)mul64f, 0 +}; + +static BinaryFunc divTab[] = +{ + (BinaryFunc)div8u, (BinaryFunc)div8s, (BinaryFunc)div16u, + (BinaryFunc)div16s, (BinaryFunc)div32s, (BinaryFunc)div32f, + (BinaryFunc)div64f, 0 +}; + +static BinaryFunc recipTab[] = +{ + (BinaryFunc)recip8u, (BinaryFunc)recip8s, (BinaryFunc)recip16u, + (BinaryFunc)recip16s, (BinaryFunc)recip32s, (BinaryFunc)recip32f, + (BinaryFunc)recip64f, 0 +}; + + +} + +void cv::multiply(InputArray src1, InputArray src2, + OutputArray dst, double scale, int dtype) +{ + arithm_op(src1, src2, dst, noArray(), dtype, mulTab, true, &scale); +} + +void cv::divide(InputArray src1, InputArray src2, + OutputArray dst, double scale, int dtype) +{ + arithm_op(src1, src2, dst, noArray(), dtype, divTab, true, &scale); +} + +void cv::divide(double scale, InputArray src2, + OutputArray dst, int dtype) +{ + arithm_op(src2, src2, dst, noArray(), dtype, recipTab, true, &scale); +} + +/****************************************************************************************\ +* addWeighted * +\****************************************************************************************/ + +namespace cv +{ + +template static void +addWeighted_( const T* src1, size_t step1, const T* src2, size_t step2, + T* dst, size_t step, Size size, void* _scalars ) +{ + const double* scalars = (const double*)_scalars; + WT alpha = (WT)scalars[0], beta = (WT)scalars[1], gamma = (WT)scalars[2]; + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + step /= sizeof(dst[0]); + + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + T t0 = saturate_cast(src1[x]*alpha + src2[x]*beta + gamma); + T t1 = saturate_cast(src1[x+1]*alpha + src2[x+1]*beta + gamma); + dst[x] = t0; dst[x+1] = t1; + + t0 = saturate_cast(src1[x+2]*alpha + src2[x+2]*beta + gamma); + t1 = saturate_cast(src1[x+3]*alpha + src2[x+3]*beta + gamma); + dst[x+2] = t0; dst[x+3] = t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = saturate_cast(src1[x]*alpha + src2[x]*beta + gamma); + } +} + + +static void +addWeighted8u( const uchar* src1, size_t step1, + const uchar* src2, size_t step2, + uchar* dst, size_t step, Size size, + void* _scalars ) +{ + const double* scalars = (const double*)_scalars; + float alpha = (float)scalars[0], beta = (float)scalars[1], gamma = (float)scalars[2]; + + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + +#if CV_SSE2 + if( USE_SSE2 ) + { + __m128 a4 = _mm_set1_ps(alpha), b4 = _mm_set1_ps(beta), g4 = _mm_set1_ps(gamma); + __m128i z = _mm_setzero_si128(); + + for( ; x <= size.width - 8; x += 8 ) + { + __m128i u = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(src1 + x)), z); + __m128i v = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(src2 + x)), z); + + __m128 u0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(u, z)); + __m128 u1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(u, z)); + __m128 v0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(v, z)); + __m128 v1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(v, z)); + + u0 = _mm_add_ps(_mm_mul_ps(u0, a4), _mm_mul_ps(v0, b4)); + u1 = _mm_add_ps(_mm_mul_ps(u1, a4), _mm_mul_ps(v1, b4)); + u0 = _mm_add_ps(u0, g4); u1 = _mm_add_ps(u1, g4); + + u = _mm_packs_epi32(_mm_cvtps_epi32(u0), _mm_cvtps_epi32(u1)); + u = _mm_packus_epi16(u, u); + + _mm_storel_epi64((__m128i*)(dst + x), u); + } + } +#endif + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + float t0, t1; + t0 = CV_8TO32F(src1[x])*alpha + CV_8TO32F(src2[x])*beta + gamma; + t1 = CV_8TO32F(src1[x+1])*alpha + CV_8TO32F(src2[x+1])*beta + gamma; + + dst[x] = saturate_cast(t0); + dst[x+1] = saturate_cast(t1); + + t0 = CV_8TO32F(src1[x+2])*alpha + CV_8TO32F(src2[x+2])*beta + gamma; + t1 = CV_8TO32F(src1[x+3])*alpha + CV_8TO32F(src2[x+3])*beta + gamma; + + dst[x+2] = saturate_cast(t0); + dst[x+3] = saturate_cast(t1); + } + #endif + + for( ; x < size.width; x++ ) + { + float t0 = CV_8TO32F(src1[x])*alpha + CV_8TO32F(src2[x])*beta + gamma; + dst[x] = saturate_cast(t0); + } + } +} + +static void addWeighted8s( const schar* src1, size_t step1, const schar* src2, size_t step2, + schar* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static void addWeighted16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, + ushort* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static void addWeighted16s( const short* src1, size_t step1, const short* src2, size_t step2, + short* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static void addWeighted32s( const int* src1, size_t step1, const int* src2, size_t step2, + int* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, + float* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, + double* dst, size_t step, Size sz, void* scalars ) +{ + addWeighted_(src1, step1, src2, step2, dst, step, sz, scalars); +} + +static BinaryFunc addWeightedTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(addWeighted8u), (BinaryFunc)GET_OPTIMIZED(addWeighted8s), (BinaryFunc)GET_OPTIMIZED(addWeighted16u), + (BinaryFunc)GET_OPTIMIZED(addWeighted16s), (BinaryFunc)GET_OPTIMIZED(addWeighted32s), (BinaryFunc)addWeighted32f, + (BinaryFunc)addWeighted64f, 0 +}; + +} + +void cv::addWeighted( InputArray src1, double alpha, InputArray src2, + double beta, double gamma, OutputArray dst, int dtype ) +{ + double scalars[] = {alpha, beta, gamma}; + arithm_op(src1, src2, dst, noArray(), dtype, addWeightedTab, true, scalars); +} + + +/****************************************************************************************\ +* compare * +\****************************************************************************************/ + +namespace cv +{ + +template static void +cmp_(const T* src1, size_t step1, const T* src2, size_t step2, + uchar* dst, size_t step, Size size, int code) +{ + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + if( code == CMP_GE || code == CMP_LT ) + { + std::swap(src1, src2); + std::swap(step1, step2); + code = code == CMP_GE ? CMP_LE : CMP_GT; + } + + if( code == CMP_GT || code == CMP_LE ) + { + int m = code == CMP_GT ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + int t0, t1; + t0 = -(src1[x] > src2[x]) ^ m; + t1 = -(src1[x+1] > src2[x+1]) ^ m; + dst[x] = (uchar)t0; dst[x+1] = (uchar)t1; + t0 = -(src1[x+2] > src2[x+2]) ^ m; + t1 = -(src1[x+3] > src2[x+3]) ^ m; + dst[x+2] = (uchar)t0; dst[x+3] = (uchar)t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = (uchar)(-(src1[x] > src2[x]) ^ m); + } + } + else if( code == CMP_EQ || code == CMP_NE ) + { + int m = code == CMP_EQ ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + int t0, t1; + t0 = -(src1[x] == src2[x]) ^ m; + t1 = -(src1[x+1] == src2[x+1]) ^ m; + dst[x] = (uchar)t0; dst[x+1] = (uchar)t1; + t0 = -(src1[x+2] == src2[x+2]) ^ m; + t1 = -(src1[x+3] == src2[x+3]) ^ m; + dst[x+2] = (uchar)t0; dst[x+3] = (uchar)t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = (uchar)(-(src1[x] == src2[x]) ^ m); + } + } +} + + +static void cmp8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + //vz optimized cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); + int code = *(int*)_cmpop; + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + if( code == CMP_GE || code == CMP_LT ) + { + std::swap(src1, src2); + std::swap(step1, step2); + code = code == CMP_GE ? CMP_LE : CMP_GT; + } + + if( code == CMP_GT || code == CMP_LE ) + { + int m = code == CMP_GT ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x =0; + #if CV_SSE2 + if( USE_SSE2 ){ + __m128i m128 = code == CMP_GT ? _mm_setzero_si128() : _mm_set1_epi8 (-1); + __m128i c128 = _mm_set1_epi8 (-128); + for( ; x <= size.width - 16; x += 16 ) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + // no simd for 8u comparison, that's why we need the trick + r00 = _mm_sub_epi8(r00,c128); + r10 = _mm_sub_epi8(r10,c128); + + r00 =_mm_xor_si128(_mm_cmpgt_epi8(r00, r10), m128); + _mm_storeu_si128((__m128i*)(dst + x),r00); + + } + } + #endif + + for( ; x < size.width; x++ ){ + dst[x] = (uchar)(-(src1[x] > src2[x]) ^ m); + } + } + } + else if( code == CMP_EQ || code == CMP_NE ) + { + int m = code == CMP_EQ ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + #if CV_SSE2 + if( USE_SSE2 ){ + __m128i m128 = code == CMP_EQ ? _mm_setzero_si128() : _mm_set1_epi8 (-1); + for( ; x <= size.width - 16; x += 16 ) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + r00 = _mm_xor_si128 ( _mm_cmpeq_epi8 (r00, r10), m128); + _mm_storeu_si128((__m128i*)(dst + x), r00); + } + } + #endif + for( ; x < size.width; x++ ) + dst[x] = (uchar)(-(src1[x] == src2[x]) ^ m); + } + } +} + +static void cmp8s(const schar* src1, size_t step1, const schar* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); +} + +static void cmp16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); +} + +static void cmp16s(const short* src1, size_t step1, const short* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + //vz optimized cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); + + int code = *(int*)_cmpop; + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + if( code == CMP_GE || code == CMP_LT ) + { + std::swap(src1, src2); + std::swap(step1, step2); + code = code == CMP_GE ? CMP_LE : CMP_GT; + } + + if( code == CMP_GT || code == CMP_LE ) + { + int m = code == CMP_GT ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x =0; + #if CV_SSE2 + if( USE_SSE2){// + __m128i m128 = code == CMP_GT ? _mm_setzero_si128() : _mm_set1_epi16 (-1); + for( ; x <= size.width - 16; x += 16 ) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + r00 = _mm_xor_si128 ( _mm_cmpgt_epi16 (r00, r10), m128); + __m128i r01 = _mm_loadu_si128((const __m128i*)(src1 + x + 8)); + __m128i r11 = _mm_loadu_si128((const __m128i*)(src2 + x + 8)); + r01 = _mm_xor_si128 ( _mm_cmpgt_epi16 (r01, r11), m128); + r11 = _mm_packs_epi16(r00, r01); + _mm_storeu_si128((__m128i*)(dst + x), r11); + } + if( x <= size.width-8) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + r00 = _mm_xor_si128 ( _mm_cmpgt_epi16 (r00, r10), m128); + r10 = _mm_packs_epi16(r00, r00); + _mm_storel_epi64((__m128i*)(dst + x), r10); + + x += 8; + } + } + #endif + + for( ; x < size.width; x++ ){ + dst[x] = (uchar)(-(src1[x] > src2[x]) ^ m); + } + } + } + else if( code == CMP_EQ || code == CMP_NE ) + { + int m = code == CMP_EQ ? 0 : 255; + for( ; size.height--; src1 += step1, src2 += step2, dst += step ) + { + int x = 0; + #if CV_SSE2 + if( USE_SSE2 ){ + __m128i m128 = code == CMP_EQ ? _mm_setzero_si128() : _mm_set1_epi16 (-1); + for( ; x <= size.width - 16; x += 16 ) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + r00 = _mm_xor_si128 ( _mm_cmpeq_epi16 (r00, r10), m128); + __m128i r01 = _mm_loadu_si128((const __m128i*)(src1 + x + 8)); + __m128i r11 = _mm_loadu_si128((const __m128i*)(src2 + x + 8)); + r01 = _mm_xor_si128 ( _mm_cmpeq_epi16 (r01, r11), m128); + r11 = _mm_packs_epi16(r00, r01); + _mm_storeu_si128((__m128i*)(dst + x), r11); + } + if( x <= size.width - 8) + { + __m128i r00 = _mm_loadu_si128((const __m128i*)(src1 + x)); + __m128i r10 = _mm_loadu_si128((const __m128i*)(src2 + x)); + r00 = _mm_xor_si128 ( _mm_cmpeq_epi16 (r00, r10), m128); + r10 = _mm_packs_epi16(r00, r00); + _mm_storel_epi64((__m128i*)(dst + x), r10); + + x += 8; + } + } + #endif + for( ; x < size.width; x++ ) + dst[x] = (uchar)(-(src1[x] == src2[x]) ^ m); + } + } +} + +static void cmp32s(const int* src1, size_t step1, const int* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); +} + +static void cmp32f(const float* src1, size_t step1, const float* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); +} + +static void cmp64f(const double* src1, size_t step1, const double* src2, size_t step2, + uchar* dst, size_t step, Size size, void* _cmpop) +{ + cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop); +} + +static BinaryFunc cmpTab[] = +{ + (BinaryFunc)GET_OPTIMIZED(cmp8u), (BinaryFunc)GET_OPTIMIZED(cmp8s), + (BinaryFunc)GET_OPTIMIZED(cmp16u), (BinaryFunc)GET_OPTIMIZED(cmp16s), + (BinaryFunc)GET_OPTIMIZED(cmp32s), + (BinaryFunc)GET_OPTIMIZED(cmp32f), (BinaryFunc)cmp64f, + 0 +}; + + +static double getMinVal(int depth) +{ + static const double tab[] = {0, -128, 0, -32768, INT_MIN, -FLT_MAX, -DBL_MAX, 0}; + return tab[depth]; +} + +static double getMaxVal(int depth) +{ + static const double tab[] = {255, 127, 65535, 32767, INT_MAX, FLT_MAX, DBL_MAX, 0}; + return tab[depth]; +} + +} + +void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op) +{ + CV_Assert( op == CMP_LT || op == CMP_LE || op == CMP_EQ || + op == CMP_NE || op == CMP_GE || op == CMP_GT ); + + int kind1 = _src1.kind(), kind2 = _src2.kind(); + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + + if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() ) + { + int cn = src1.channels(); + _dst.create(src1.size(), CV_8UC(cn)); + Mat dst = _dst.getMat(); + Size sz = getContinuousSize(src1, src2, dst, src1.channels()); + cmpTab[src1.depth()](src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, &op); + return; + } + + bool haveScalar = false; + + if( (kind1 == _InputArray::MATX) + (kind2 == _InputArray::MATX) == 1 || + src1.size != src2.size || src1.type() != src2.type() ) + { + if( checkScalar(src1, src2.type(), kind1, kind2) ) + { + // src1 is a scalar; swap it with src2 + swap(src1, src2); + op = op == CMP_LT ? CMP_GT : op == CMP_LE ? CMP_GE : + op == CMP_GE ? CMP_LE : op == CMP_GT ? CMP_LT : op; + } + else if( !checkScalar(src2, src1.type(), kind2, kind1) ) + CV_Error( CV_StsUnmatchedSizes, + "The operation is neither 'array op array' (where arrays have the same size and the same type), " + "nor 'array op scalar', nor 'scalar op array'" ); + haveScalar = true; + } + + + int cn = src1.channels(), depth1 = src1.depth(), depth2 = src2.depth(); + + _dst.create(src1.dims, src1.size, CV_8UC(cn)); + src1 = src1.reshape(1); src2 = src2.reshape(1); + Mat dst = _dst.getMat().reshape(1); + + size_t esz = src1.elemSize(); + size_t blocksize0 = (size_t)(BLOCK_SIZE + esz-1)/esz; + BinaryFunc func = cmpTab[depth1]; + + if( !haveScalar ) + { + const Mat* arrays[] = { &src1, &src2, &dst, 0 }; + uchar* ptrs[3]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], 0, ptrs[1], 0, ptrs[2], 0, Size((int)total, 1), &op ); + } + else + { + const Mat* arrays[] = { &src1, &dst, 0 }; + uchar* ptrs[2]; + + NAryMatIterator it(arrays, ptrs); + size_t total = it.size, blocksize = std::min(total, blocksize0); + + AutoBuffer _buf(blocksize*esz); + uchar *buf = _buf; + + if( depth1 > CV_32S ) + convertAndUnrollScalar( src2, depth1, buf, blocksize ); + else + { + double fval=0; + getConvertFunc(depth2, CV_64F)(src2.data, 0, 0, 0, (uchar*)&fval, 0, Size(1,1), 0); + if( fval < getMinVal(depth1) ) + { + dst = Scalar::all(op == CMP_GT || op == CMP_GE || op == CMP_NE ? 255 : 0); + return; + } + + if( fval > getMaxVal(depth1) ) + { + dst = Scalar::all(op == CMP_LT || op == CMP_LE || op == CMP_NE ? 255 : 0); + return; + } + + int ival = cvRound(fval); + if( fval != ival ) + { + if( op == CMP_LT || op == CMP_GE ) + ival = cvCeil(fval); + else if( op == CMP_LE || op == CMP_GT ) + ival = cvFloor(fval); + else + { + dst = Scalar::all(op == CMP_NE ? 255 : 0); + return; + } + } + convertAndUnrollScalar(Mat(1, 1, CV_32S, &ival), depth1, buf, blocksize); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + func( ptrs[0], 0, buf, 0, ptrs[1], 0, Size(bsz, 1), &op); + ptrs[0] += bsz*esz; + ptrs[1] += bsz; + } + } + } +} + +/****************************************************************************************\ +* inRange * +\****************************************************************************************/ + +namespace cv +{ + +template static void +inRange_(const T* src1, size_t step1, const T* src2, size_t step2, + const T* src3, size_t step3, uchar* dst, size_t step, + Size size) +{ + step1 /= sizeof(src1[0]); + step2 /= sizeof(src2[0]); + step3 /= sizeof(src3[0]); + + for( ; size.height--; src1 += step1, src2 += step2, src3 += step3, dst += step ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + int t0, t1; + t0 = src2[x] <= src1[x] && src1[x] <= src3[x]; + t1 = src2[x+1] <= src1[x+1] && src1[x+1] <= src3[x+1]; + dst[x] = (uchar)-t0; dst[x+1] = (uchar)-t1; + t0 = src2[x+2] <= src1[x+2] && src1[x+2] <= src3[x+2]; + t1 = src2[x+3] <= src1[x+3] && src1[x+3] <= src3[x+3]; + dst[x+2] = (uchar)-t0; dst[x+3] = (uchar)-t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = (uchar)-(src2[x] <= src1[x] && src1[x] <= src3[x]); + } +} + + +static void inRange8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, + const uchar* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange8s(const schar* src1, size_t step1, const schar* src2, size_t step2, + const schar* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, + const ushort* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange16s(const short* src1, size_t step1, const short* src2, size_t step2, + const short* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange32s(const int* src1, size_t step1, const int* src2, size_t step2, + const int* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange32f(const float* src1, size_t step1, const float* src2, size_t step2, + const float* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRange64f(const double* src1, size_t step1, const double* src2, size_t step2, + const double* src3, size_t step3, uchar* dst, size_t step, Size size) +{ + inRange_(src1, step1, src2, step2, src3, step3, dst, step, size); +} + +static void inRangeReduce(const uchar* src, uchar* dst, size_t len, int cn) +{ + int k = cn % 4 ? cn % 4 : 4; + size_t i, j; + if( k == 1 ) + for( i = j = 0; i < len; i++, j += cn ) + dst[i] = src[j]; + else if( k == 2 ) + for( i = j = 0; i < len; i++, j += cn ) + dst[i] = src[j] & src[j+1]; + else if( k == 3 ) + for( i = j = 0; i < len; i++, j += cn ) + dst[i] = src[j] & src[j+1] & src[j+2]; + else + for( i = j = 0; i < len; i++, j += cn ) + dst[i] = src[j] & src[j+1] & src[j+2] & src[j+3]; + + for( ; k < cn; k += 4 ) + { + for( i = 0, j = k; i < len; i++, j += cn ) + dst[i] &= src[j] & src[j+1] & src[j+2] & src[j+3]; + } +} + +typedef void (*InRangeFunc)( const uchar* src1, size_t step1, const uchar* src2, size_t step2, + const uchar* src3, size_t step3, uchar* dst, size_t step, Size sz ); + +static InRangeFunc inRangeTab[] = +{ + (InRangeFunc)GET_OPTIMIZED(inRange8u), (InRangeFunc)GET_OPTIMIZED(inRange8s), (InRangeFunc)GET_OPTIMIZED(inRange16u), + (InRangeFunc)GET_OPTIMIZED(inRange16s), (InRangeFunc)GET_OPTIMIZED(inRange32s), (InRangeFunc)GET_OPTIMIZED(inRange32f), + (InRangeFunc)inRange64f, 0 +}; + +} + +void cv::inRange(InputArray _src, InputArray _lowerb, + InputArray _upperb, OutputArray _dst) +{ + int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind(); + Mat src = _src.getMat(), lb = _lowerb.getMat(), ub = _upperb.getMat(); + + bool lbScalar = false, ubScalar = false; + + if( (lkind == _InputArray::MATX && skind != _InputArray::MATX) || + src.size != lb.size || src.type() != lb.type() ) + { + if( !checkScalar(lb, src.type(), lkind, skind) ) + CV_Error( CV_StsUnmatchedSizes, + "The lower bounary is neither an array of the same size and same type as src, nor a scalar"); + lbScalar = true; + } + + if( (ukind == _InputArray::MATX && skind != _InputArray::MATX) || + src.size != ub.size || src.type() != ub.type() ) + { + if( !checkScalar(ub, src.type(), ukind, skind) ) + CV_Error( CV_StsUnmatchedSizes, + "The upper bounary is neither an array of the same size and same type as src, nor a scalar"); + ubScalar = true; + } + + CV_Assert( ((int)lbScalar ^ (int)ubScalar) == 0 ); + + int cn = src.channels(), depth = src.depth(); + + size_t esz = src.elemSize(); + size_t blocksize0 = (size_t)(BLOCK_SIZE + esz-1)/esz; + + _dst.create(src.dims, src.size, CV_8U); + Mat dst = _dst.getMat(); + InRangeFunc func = inRangeTab[depth]; + + const Mat* arrays_sc[] = { &src, &dst, 0 }; + const Mat* arrays_nosc[] = { &src, &dst, &lb, &ub, 0 }; + uchar* ptrs[4]; + + NAryMatIterator it(lbScalar && ubScalar ? arrays_sc : arrays_nosc, ptrs); + size_t total = it.size, blocksize = std::min(total, blocksize0); + + AutoBuffer _buf(blocksize*(((int)lbScalar + (int)ubScalar)*esz + cn) + 2*cn*sizeof(int) + 128); + uchar *buf = _buf, *mbuf = buf, *lbuf = 0, *ubuf = 0; + buf = alignPtr(buf + blocksize*cn, 16); + + if( lbScalar && ubScalar ) + { + lbuf = buf; + ubuf = buf = alignPtr(buf + blocksize*esz, 16); + + CV_Assert( lb.type() == ub.type() ); + int scdepth = lb.depth(); + + if( scdepth != depth && depth < CV_32S ) + { + int* ilbuf = (int*)alignPtr(buf + blocksize*esz, 16); + int* iubuf = ilbuf + cn; + + BinaryFunc sccvtfunc = getConvertFunc(scdepth, CV_32S); + sccvtfunc(lb.data, 0, 0, 0, (uchar*)ilbuf, 0, Size(cn, 1), 0); + sccvtfunc(ub.data, 0, 0, 0, (uchar*)iubuf, 0, Size(cn, 1), 0); + int minval = cvRound(getMinVal(depth)), maxval = cvRound(getMaxVal(depth)); + + for( int k = 0; k < cn; k++ ) + { + if( ilbuf[k] > iubuf[k] || ilbuf[k] > maxval || iubuf[k] < minval ) + ilbuf[k] = minval+1, iubuf[k] = minval; + } + lb = Mat(cn, 1, CV_32S, ilbuf); + ub = Mat(cn, 1, CV_32S, iubuf); + } + + convertAndUnrollScalar( lb, src.type(), lbuf, blocksize ); + convertAndUnrollScalar( ub, src.type(), ubuf, blocksize ); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( size_t j = 0; j < total; j += blocksize ) + { + int bsz = (int)MIN(total - j, blocksize); + size_t delta = bsz*esz; + uchar *lptr = lbuf, *uptr = ubuf; + if( !lbScalar ) + { + lptr = ptrs[2]; + ptrs[2] += delta; + } + if( !ubScalar ) + { + int idx = !lbScalar ? 3 : 2; + uptr = ptrs[idx]; + ptrs[idx] += delta; + } + func( ptrs[0], 0, lptr, 0, uptr, 0, cn == 1 ? ptrs[1] : mbuf, 0, Size(bsz*cn, 1)); + if( cn > 1 ) + inRangeReduce(mbuf, ptrs[1], bsz, cn); + ptrs[0] += delta; + ptrs[1] += bsz; + } + } +} + +/****************************************************************************************\ +* Earlier API: cvAdd etc. * +\****************************************************************************************/ + +CV_IMPL void +cvNot( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + cv::bitwise_not( src, dst ); +} + + +CV_IMPL void +cvAnd( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_and( src1, src2, dst, mask ); +} + + +CV_IMPL void +cvOr( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_or( src1, src2, dst, mask ); +} + + +CV_IMPL void +cvXor( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_xor( src1, src2, dst, mask ); +} + + +CV_IMPL void +cvAndS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_and( src, (const cv::Scalar&)s, dst, mask ); +} + + +CV_IMPL void +cvOrS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_or( src, (const cv::Scalar&)s, dst, mask ); +} + + +CV_IMPL void +cvXorS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::bitwise_xor( src, (const cv::Scalar&)s, dst, mask ); +} + + +CV_IMPL void cvAdd( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::add( src1, src2, dst, mask, dst.type() ); +} + + +CV_IMPL void cvSub( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::subtract( src1, src2, dst, mask, dst.type() ); +} + + +CV_IMPL void cvAddS( const CvArr* srcarr1, CvScalar value, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::add( src1, (const cv::Scalar&)value, dst, mask, dst.type() ); +} + + +CV_IMPL void cvSubRS( const CvArr* srcarr1, CvScalar value, CvArr* dstarr, const CvArr* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::subtract( (const cv::Scalar&)value, src1, dst, mask, dst.type() ); +} + + +CV_IMPL void cvMul( const CvArr* srcarr1, const CvArr* srcarr2, + CvArr* dstarr, double scale ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + cv::multiply( src1, src2, dst, scale, dst.type() ); +} + + +CV_IMPL void cvDiv( const CvArr* srcarr1, const CvArr* srcarr2, + CvArr* dstarr, double scale ) +{ + cv::Mat src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr), mask; + CV_Assert( src2.size == dst.size && src2.channels() == dst.channels() ); + + if( srcarr1 ) + cv::divide( cv::cvarrToMat(srcarr1), src2, dst, scale, dst.type() ); + else + cv::divide( scale, src2, dst, dst.type() ); +} + + +CV_IMPL void +cvAddWeighted( const CvArr* srcarr1, double alpha, + const CvArr* srcarr2, double beta, + double gamma, CvArr* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2), + dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() ); + cv::addWeighted( src1, alpha, src2, beta, gamma, dst, dst.type() ); +} + + +CV_IMPL void +cvAbsDiff( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::absdiff( src1, cv::cvarrToMat(srcarr2), dst ); +} + + +CV_IMPL void +cvAbsDiffS( const CvArr* srcarr1, CvArr* dstarr, CvScalar scalar ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::absdiff( src1, (const cv::Scalar&)scalar, dst ); +} + + +CV_IMPL void +cvInRange( const void* srcarr1, const void* srcarr2, + const void* srcarr3, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && dst.type() == CV_8U ); + + cv::inRange( src1, cv::cvarrToMat(srcarr2), cv::cvarrToMat(srcarr3), dst ); +} + + +CV_IMPL void +cvInRangeS( const void* srcarr1, CvScalar lowerb, CvScalar upperb, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && dst.type() == CV_8U ); + + cv::inRange( src1, (const cv::Scalar&)lowerb, (const cv::Scalar&)upperb, dst ); +} + + +CV_IMPL void +cvCmp( const void* srcarr1, const void* srcarr2, void* dstarr, int cmp_op ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && dst.type() == CV_8U ); + + cv::compare( src1, cv::cvarrToMat(srcarr2), dst, cmp_op ); +} + + +CV_IMPL void +cvCmpS( const void* srcarr1, double value, void* dstarr, int cmp_op ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && dst.type() == CV_8U ); + + cv::compare( src1, value, dst, cmp_op ); +} + + +CV_IMPL void +cvMin( const void* srcarr1, const void* srcarr2, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::min( src1, cv::cvarrToMat(srcarr2), dst ); +} + + +CV_IMPL void +cvMax( const void* srcarr1, const void* srcarr2, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::max( src1, cv::cvarrToMat(srcarr2), dst ); +} + + +CV_IMPL void +cvMinS( const void* srcarr1, double value, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::min( src1, value, dst ); +} + + +CV_IMPL void +cvMaxS( const void* srcarr1, double value, void* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + + cv::max( src1, value, dst ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/array.cpp diffimg-2.0.0/3rdparty/opencv/core/src/array.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/array.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/array.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3206 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// CvMat, CvMatND, CvSparceMat and IplImage support functions +// (creation, deletion, copying, retrieving and setting elements etc.) +// +// */ + +#include "precomp.hpp" + + +static struct +{ + Cv_iplCreateImageHeader createHeader; + Cv_iplAllocateImageData allocateData; + Cv_iplDeallocate deallocate; + Cv_iplCreateROI createROI; + Cv_iplCloneImage cloneImage; +} +CvIPL; + +// Makes the library use native IPL image allocators +CV_IMPL void +cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, + Cv_iplAllocateImageData allocateData, + Cv_iplDeallocate deallocate, + Cv_iplCreateROI createROI, + Cv_iplCloneImage cloneImage ) +{ + int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) + + (createROI != 0) + (cloneImage != 0); + + if( count != 0 && count != 5 ) + CV_Error( CV_StsBadArg, "Either all the pointers should be null or " + "they all should be non-null" ); + + CvIPL.createHeader = createHeader; + CvIPL.allocateData = allocateData; + CvIPL.deallocate = deallocate; + CvIPL.createROI = createROI; + CvIPL.cloneImage = cloneImage; +} + + +/****************************************************************************************\ +* CvMat creation and basic operations * +\****************************************************************************************/ + +// Creates CvMat and underlying data +CV_IMPL CvMat* +cvCreateMat( int height, int width, int type ) +{ + CvMat* arr = cvCreateMatHeader( height, width, type ); + cvCreateData( arr ); + + return arr; +} + + +static void icvCheckHuge( CvMat* arr ) +{ + if( (int64)arr->step*arr->rows > INT_MAX ) + arr->type &= ~CV_MAT_CONT_FLAG; +} + +// Creates CvMat header only +CV_IMPL CvMat* +cvCreateMatHeader( int rows, int cols, int type ) +{ + type = CV_MAT_TYPE(type); + + if( rows < 0 || cols <= 0 ) + CV_Error( CV_StsBadSize, "Non-positive width or height" ); + + int min_step = CV_ELEM_SIZE(type)*cols; + if( min_step <= 0 ) + CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" ); + + CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr)); + + arr->step = min_step; + arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG; + arr->rows = rows; + arr->cols = cols; + arr->data.ptr = 0; + arr->refcount = 0; + arr->hdr_refcount = 1; + + icvCheckHuge( arr ); + return arr; +} + + +// Initializes CvMat header, allocated by the user +CV_IMPL CvMat* +cvInitMatHeader( CvMat* arr, int rows, int cols, + int type, void* data, int step ) +{ + if( !arr ) + CV_Error( CV_StsNullPtr, "" ); + + if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) + CV_Error( CV_BadNumChannels, "" ); + + if( rows < 0 || cols <= 0 ) + CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); + + type = CV_MAT_TYPE( type ); + arr->type = type | CV_MAT_MAGIC_VAL; + arr->rows = rows; + arr->cols = cols; + arr->data.ptr = (uchar*)data; + arr->refcount = 0; + arr->hdr_refcount = 0; + + int pix_size = CV_ELEM_SIZE(type); + int min_step = arr->cols*pix_size; + + if( step != CV_AUTOSTEP && step != 0 ) + { + if( step < min_step ) + CV_Error( CV_BadStep, "" ); + arr->step = step; + } + else + { + arr->step = min_step; + } + + arr->type = CV_MAT_MAGIC_VAL | type | + (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0); + + icvCheckHuge( arr ); + return arr; +} + + +// Deallocates the CvMat structure and underlying data +CV_IMPL void +cvReleaseMat( CvMat** array ) +{ + if( !array ) + CV_Error( CV_HeaderIsNull, "" ); + + if( *array ) + { + CvMat* arr = *array; + + if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) ) + CV_Error( CV_StsBadFlag, "" ); + + *array = 0; + + cvDecRefData( arr ); + cvFree( &arr ); + } +} + + +// Creates a copy of matrix +CV_IMPL CvMat* +cvCloneMat( const CvMat* src ) +{ + if( !CV_IS_MAT_HDR( src )) + CV_Error( CV_StsBadArg, "Bad CvMat header" ); + + CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type ); + + if( src->data.ptr ) + { + cvCreateData( dst ); + cvCopy( src, dst ); + } + + return dst; +} + + +/****************************************************************************************\ +* CvMatND creation and basic operations * +\****************************************************************************************/ + +CV_IMPL CvMatND* +cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, + int type, void* data ) +{ + type = CV_MAT_TYPE(type); + int64 step = CV_ELEM_SIZE(type); + + if( !mat ) + CV_Error( CV_StsNullPtr, "NULL matrix header pointer" ); + + if( step == 0 ) + CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + + if( !sizes ) + CV_Error( CV_StsNullPtr, "NULL pointer" ); + + if( dims <= 0 || dims > CV_MAX_DIM ) + CV_Error( CV_StsOutOfRange, + "non-positive or too large number of dimensions" ); + + for( int i = dims - 1; i >= 0; i-- ) + { + if( sizes[i] < 0 ) + CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); + mat->dim[i].size = sizes[i]; + if( step > INT_MAX ) + CV_Error( CV_StsOutOfRange, "The array is too big" ); + mat->dim[i].step = (int)step; + step *= sizes[i]; + } + + mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type; + mat->dims = dims; + mat->data.ptr = (uchar*)data; + mat->refcount = 0; + mat->hdr_refcount = 0; + return mat; +} + + +// Creates CvMatND and underlying data +CV_IMPL CvMatND* +cvCreateMatND( int dims, const int* sizes, int type ) +{ + CvMatND* arr = cvCreateMatNDHeader( dims, sizes, type ); + cvCreateData( arr ); + + return arr; +} + + +// Creates CvMatND header only +CV_IMPL CvMatND* +cvCreateMatNDHeader( int dims, const int* sizes, int type ) +{ + if( dims <= 0 || dims > CV_MAX_DIM ) + CV_Error( CV_StsOutOfRange, + "non-positive or too large number of dimensions" ); + + CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) ); + + cvInitMatNDHeader( arr, dims, sizes, type, 0 ); + arr->hdr_refcount = 1; + return arr; +} + + +// Creates a copy of nD array +CV_IMPL CvMatND* +cvCloneMatND( const CvMatND* src ) +{ + if( !CV_IS_MATND_HDR( src )) + CV_Error( CV_StsBadArg, "Bad CvMatND header" ); + + CV_Assert( src->dims <= CV_MAX_DIM ); + int sizes[CV_MAX_DIM]; + + for( int i = 0; i < src->dims; i++ ) + sizes[i] = src->dim[i].size; + + CvMatND* dst = cvCreateMatNDHeader( src->dims, sizes, src->type ); + + if( src->data.ptr ) + { + cvCreateData( dst ); + cv::Mat _src(src), _dst(dst); + uchar* data0 = dst->data.ptr; + _src.copyTo(_dst); + CV_Assert(_dst.data == data0); + //cvCopy( src, dst ); + } + + return dst; +} + + +static CvMatND* +cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi ) +{ + CvMatND* result = 0; + + if( coi ) + *coi = 0; + + if( !matnd || !arr ) + CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); + + if( CV_IS_MATND_HDR(arr)) + { + if( !((CvMatND*)arr)->data.ptr ) + CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); + + result = (CvMatND*)arr; + } + else + { + CvMat stub, *mat = (CvMat*)arr; + + if( CV_IS_IMAGE_HDR( mat )) + mat = cvGetMat( mat, &stub, coi ); + + if( !CV_IS_MAT_HDR( mat )) + CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" ); + + if( !mat->data.ptr ) + CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); + + matnd->data.ptr = mat->data.ptr; + matnd->refcount = 0; + matnd->hdr_refcount = 0; + matnd->type = mat->type; + matnd->dims = 2; + matnd->dim[0].size = mat->rows; + matnd->dim[0].step = mat->step; + matnd->dim[1].size = mat->cols; + matnd->dim[1].step = CV_ELEM_SIZE(mat->type); + result = matnd; + } + + return result; +} + + +// returns number of dimensions to iterate. +/* +Checks whether arrays have equal type, sizes (mask is optional array +that needs to have the same size, but 8uC1 or 8sC1 type). +Returns number of dimensions to iterate through: +0 means that all arrays are continuous, +1 means that all arrays are vectors of continuous arrays etc. +and the size of largest common continuous part of the arrays +*/ +CV_IMPL int +cvInitNArrayIterator( int count, CvArr** arrs, + const CvArr* mask, CvMatND* stubs, + CvNArrayIterator* iterator, int flags ) +{ + int dims = -1; + int i, j, size, dim0 = -1; + int64 step; + CvMatND* hdr0 = 0; + + if( count < 1 || count > CV_MAX_ARR ) + CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" ); + + if( !arrs || !stubs ) + CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); + + if( !iterator ) + CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" ); + + for( i = 0; i <= count; i++ ) + { + const CvArr* arr = i < count ? arrs[i] : mask; + CvMatND* hdr; + + if( !arr ) + { + if( i < count ) + CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); + break; + } + + if( CV_IS_MATND( arr )) + hdr = (CvMatND*)arr; + else + { + int coi = 0; + hdr = cvGetMatND( arr, stubs + i, &coi ); + if( coi != 0 ) + CV_Error( CV_BadCOI, "COI set is not allowed here" ); + } + + iterator->hdr[i] = hdr; + + if( i > 0 ) + { + if( hdr->dims != hdr0->dims ) + CV_Error( CV_StsUnmatchedSizes, + "Number of dimensions is the same for all arrays" ); + + if( i < count ) + { + switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK)) + { + case 0: + if( !CV_ARE_TYPES_EQ( hdr, hdr0 )) + CV_Error( CV_StsUnmatchedFormats, + "Data type is not the same for all arrays" ); + break; + case CV_NO_DEPTH_CHECK: + if( !CV_ARE_CNS_EQ( hdr, hdr0 )) + CV_Error( CV_StsUnmatchedFormats, + "Number of channels is not the same for all arrays" ); + break; + case CV_NO_CN_CHECK: + if( !CV_ARE_CNS_EQ( hdr, hdr0 )) + CV_Error( CV_StsUnmatchedFormats, + "Depth is not the same for all arrays" ); + break; + } + } + else + { + if( !CV_IS_MASK_ARR( hdr )) + CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" ); + } + + if( !(flags & CV_NO_SIZE_CHECK) ) + { + for( j = 0; j < hdr->dims; j++ ) + if( hdr->dim[j].size != hdr0->dim[j].size ) + CV_Error( CV_StsUnmatchedSizes, + "Dimension sizes are the same for all arrays" ); + } + } + else + hdr0 = hdr; + + step = CV_ELEM_SIZE(hdr->type); + for( j = hdr->dims - 1; j > dim0; j-- ) + { + if( step != hdr->dim[j].step ) + break; + step *= hdr->dim[j].size; + } + + if( j == dim0 && step > INT_MAX ) + j++; + + if( j > dim0 ) + dim0 = j; + + iterator->hdr[i] = (CvMatND*)hdr; + iterator->ptr[i] = (uchar*)hdr->data.ptr; + } + + size = 1; + for( j = hdr0->dims - 1; j > dim0; j-- ) + size *= hdr0->dim[j].size; + + dims = dim0 + 1; + iterator->dims = dims; + iterator->count = count; + iterator->size = cvSize(size,1); + + for( i = 0; i < dims; i++ ) + iterator->stack[i] = hdr0->dim[i].size; + + return dims; +} + + +// returns zero value if iteration is finished, non-zero otherwise +CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator ) +{ + assert( iterator != 0 ); + int i, dims, size = 0; + + for( dims = iterator->dims; dims > 0; dims-- ) + { + for( i = 0; i < iterator->count; i++ ) + iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step; + + if( --iterator->stack[dims-1] > 0 ) + break; + + size = iterator->hdr[0]->dim[dims-1].size; + + for( i = 0; i < iterator->count; i++ ) + iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step; + + iterator->stack[dims-1] = size; + } + + return dims > 0; +} + + +/****************************************************************************************\ +* CvSparseMat creation and basic operations * +\****************************************************************************************/ + + +// Creates CvMatND and underlying data +CV_IMPL CvSparseMat* +cvCreateSparseMat( int dims, const int* sizes, int type ) +{ + type = CV_MAT_TYPE( type ); + int pix_size1 = CV_ELEM_SIZE1(type); + int pix_size = pix_size1*CV_MAT_CN(type); + int i, size; + CvMemStorage* storage; + + if( pix_size == 0 ) + CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + + if( dims <= 0 || dims > CV_MAX_DIM_HEAP ) + CV_Error( CV_StsOutOfRange, "bad number of dimensions" ); + + if( !sizes ) + CV_Error( CV_StsNullPtr, "NULL pointer" ); + + for( i = 0; i < dims; i++ ) + { + if( sizes[i] <= 0 ) + CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); + } + + CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])); + + arr->type = CV_SPARSE_MAT_MAGIC_VAL | type; + arr->dims = dims; + arr->refcount = 0; + arr->hdr_refcount = 1; + memcpy( arr->size, sizes, dims*sizeof(sizes[0])); + + arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1); + arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int)); + size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem)); + + storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ); + arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ); + + arr->hashsize = CV_SPARSE_HASH_SIZE0; + size = arr->hashsize*sizeof(arr->hashtable[0]); + + arr->hashtable = (void**)cvAlloc( size ); + memset( arr->hashtable, 0, size ); + + return arr; +} + + +// Creates CvMatND and underlying data +CV_IMPL void +cvReleaseSparseMat( CvSparseMat** array ) +{ + if( !array ) + CV_Error( CV_HeaderIsNull, "" ); + + if( *array ) + { + CvSparseMat* arr = *array; + + if( !CV_IS_SPARSE_MAT_HDR(arr) ) + CV_Error( CV_StsBadFlag, "" ); + + *array = 0; + + CvMemStorage* storage = arr->heap->storage; + cvReleaseMemStorage( &storage ); + cvFree( &arr->hashtable ); + cvFree( &arr ); + } +} + + +// Creates CvMatND and underlying data +CV_IMPL CvSparseMat* +cvCloneSparseMat( const CvSparseMat* src ) +{ + if( !CV_IS_SPARSE_MAT_HDR(src) ) + CV_Error( CV_StsBadArg, "Invalid sparse array header" ); + + CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type ); + cvCopy( src, dst ); + return dst; +} + + +CvSparseNode* +cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) +{ + CvSparseNode* node = 0; + int idx; + + if( !CV_IS_SPARSE_MAT( mat )) + CV_Error( CV_StsBadArg, "Invalid sparse matrix header" ); + + if( !iterator ) + CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + + iterator->mat = (CvSparseMat*)mat; + iterator->node = 0; + + for( idx = 0; idx < mat->hashsize; idx++ ) + if( mat->hashtable[idx] ) + { + node = iterator->node = (CvSparseNode*)mat->hashtable[idx]; + break; + } + + iterator->curidx = idx; + return node; +} + +#define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE + +static uchar* +icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type, + int create_node, unsigned* precalc_hashval ) +{ + uchar* ptr = 0; + int i, tabidx; + unsigned hashval = 0; + CvSparseNode *node; + assert( CV_IS_SPARSE_MAT( mat )); + + if( !precalc_hashval ) + { + for( i = 0; i < mat->dims; i++ ) + { + int t = idx[i]; + if( (unsigned)t >= (unsigned)mat->size[i] ) + CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; + } + } + else + { + hashval = *precalc_hashval; + } + + tabidx = hashval & (mat->hashsize - 1); + hashval &= INT_MAX; + + if( create_node >= -1 ) + { + for( node = (CvSparseNode*)mat->hashtable[tabidx]; + node != 0; node = node->next ) + { + if( node->hashval == hashval ) + { + int* nodeidx = CV_NODE_IDX(mat,node); + for( i = 0; i < mat->dims; i++ ) + if( idx[i] != nodeidx[i] ) + break; + if( i == mat->dims ) + { + ptr = (uchar*)CV_NODE_VAL(mat,node); + break; + } + } + } + } + + if( !ptr && create_node ) + { + if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO ) + { + void** newtable; + int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0); + int newrawsize = newsize*sizeof(newtable[0]); + + CvSparseMatIterator iterator; + assert( (newsize & (newsize - 1)) == 0 ); + + // resize hash table + newtable = (void**)cvAlloc( newrawsize ); + memset( newtable, 0, newrawsize ); + + node = cvInitSparseMatIterator( mat, &iterator ); + while( node ) + { + CvSparseNode* next = cvGetNextSparseNode( &iterator ); + int newidx = node->hashval & (newsize - 1); + node->next = (CvSparseNode*)newtable[newidx]; + newtable[newidx] = node; + node = next; + } + + cvFree( &mat->hashtable ); + mat->hashtable = newtable; + mat->hashsize = newsize; + tabidx = hashval & (newsize - 1); + } + + node = (CvSparseNode*)cvSetNew( mat->heap ); + node->hashval = hashval; + node->next = (CvSparseNode*)mat->hashtable[tabidx]; + mat->hashtable[tabidx] = node; + memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0])); + ptr = (uchar*)CV_NODE_VAL(mat,node); + if( create_node > 0 ) + memset( ptr, 0, CV_ELEM_SIZE(mat->type)); + } + + if( _type ) + *_type = CV_MAT_TYPE(mat->type); + + return ptr; +} + + +static void +icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ) +{ + int i, tabidx; + unsigned hashval = 0; + CvSparseNode *node, *prev = 0; + assert( CV_IS_SPARSE_MAT( mat )); + + if( !precalc_hashval ) + { + for( i = 0; i < mat->dims; i++ ) + { + int t = idx[i]; + if( (unsigned)t >= (unsigned)mat->size[i] ) + CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; + } + } + else + { + hashval = *precalc_hashval; + } + + tabidx = hashval & (mat->hashsize - 1); + hashval &= INT_MAX; + + for( node = (CvSparseNode*)mat->hashtable[tabidx]; + node != 0; prev = node, node = node->next ) + { + if( node->hashval == hashval ) + { + int* nodeidx = CV_NODE_IDX(mat,node); + for( i = 0; i < mat->dims; i++ ) + if( idx[i] != nodeidx[i] ) + break; + if( i == mat->dims ) + break; + } + } + + if( node ) + { + if( prev ) + prev->next = node->next; + else + mat->hashtable[tabidx] = node->next; + cvSetRemoveByPtr( mat->heap, node ); + } +} + + +/****************************************************************************************\ +* Common for multiple array types operations * +\****************************************************************************************/ + +// Allocates underlying array data +CV_IMPL void +cvCreateData( CvArr* arr ) +{ + if( CV_IS_MAT_HDR_Z( arr )) + { + size_t step, total_size; + CvMat* mat = (CvMat*)arr; + step = mat->step; + + if( mat->rows == 0 || mat->cols == 0 ) + return; + + if( mat->data.ptr != 0 ) + CV_Error( CV_StsError, "Data is already allocated" ); + + if( step == 0 ) + step = CV_ELEM_SIZE(mat->type)*mat->cols; + + int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN; + total_size = (size_t)_total_size; + if(_total_size != (int64)total_size) + CV_Error(CV_StsNoMem, "Too big buffer is allocated" ); + mat->refcount = (int*)cvAlloc( (size_t)total_size ); + mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); + *mat->refcount = 1; + } + else if( CV_IS_IMAGE_HDR(arr)) + { + IplImage* img = (IplImage*)arr; + + if( img->imageData != 0 ) + CV_Error( CV_StsError, "Data is already allocated" ); + + if( !CvIPL.allocateData ) + { + img->imageData = img->imageDataOrigin = + (char*)cvAlloc( (size_t)img->imageSize ); + } + else + { + int depth = img->depth; + int width = img->width; + + if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F ) + { + img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double); + img->depth = IPL_DEPTH_8U; + } + + CvIPL.allocateData( img, 0, 0 ); + + img->width = width; + img->depth = depth; + } + } + else if( CV_IS_MATND_HDR( arr )) + { + CvMatND* mat = (CvMatND*)arr; + int i; + size_t total_size = CV_ELEM_SIZE(mat->type); + + if( mat->dim[0].size == 0 ) + return; + + if( mat->data.ptr != 0 ) + CV_Error( CV_StsError, "Data is already allocated" ); + + if( CV_IS_MAT_CONT( mat->type )) + { + total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ? + (size_t)mat->dim[0].step : total_size); + } + else + { + for( i = mat->dims - 1; i >= 0; i-- ) + { + size_t size = (size_t)mat->dim[i].step*mat->dim[i].size; + + if( total_size < size ) + total_size = size; + } + } + + mat->refcount = (int*)cvAlloc( total_size + + sizeof(int) + CV_MALLOC_ALIGN ); + mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); + *mat->refcount = 1; + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); +} + + +// Assigns external data to array +CV_IMPL void +cvSetData( CvArr* arr, void* data, int step ) +{ + int pix_size, min_step; + + if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) ) + cvReleaseData( arr ); + + if( CV_IS_MAT_HDR( arr )) + { + CvMat* mat = (CvMat*)arr; + + int type = CV_MAT_TYPE(mat->type); + pix_size = CV_ELEM_SIZE(type); + min_step = mat->cols*pix_size; + + if( step != CV_AUTOSTEP && step != 0 ) + { + if( step < min_step && data != 0 ) + CV_Error( CV_BadStep, "" ); + mat->step = step; + } + else + mat->step = min_step; + + mat->data.ptr = (uchar*)data; + mat->type = CV_MAT_MAGIC_VAL | type | + (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0); + icvCheckHuge( mat ); + } + else if( CV_IS_IMAGE_HDR( arr )) + { + IplImage* img = (IplImage*)arr; + + pix_size = ((img->depth & 255) >> 3)*img->nChannels; + min_step = img->width*pix_size; + + if( step != CV_AUTOSTEP && img->height > 1 ) + { + if( step < min_step && data != 0 ) + CV_Error( CV_BadStep, "" ); + img->widthStep = step; + } + else + { + img->widthStep = min_step; + } + + img->imageSize = img->widthStep * img->height; + img->imageData = img->imageDataOrigin = (char*)data; + + if( (((int)(size_t)data | step) & 7) == 0 && + cvAlign(img->width * pix_size, 8) == step ) + img->align = 8; + else + img->align = 4; + } + else if( CV_IS_MATND_HDR( arr )) + { + CvMatND* mat = (CvMatND*)arr; + int i; + int64 cur_step; + + if( step != CV_AUTOSTEP ) + CV_Error( CV_BadStep, + "For multidimensional array only CV_AUTOSTEP is allowed here" ); + + mat->data.ptr = (uchar*)data; + cur_step = CV_ELEM_SIZE(mat->type); + + for( i = mat->dims - 1; i >= 0; i-- ) + { + if( cur_step > INT_MAX ) + CV_Error( CV_StsOutOfRange, "The array is too big" ); + mat->dim[i].step = (int)cur_step; + cur_step *= mat->dim[i].size; + } + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); +} + + +// Deallocates array's data +CV_IMPL void +cvReleaseData( CvArr* arr ) +{ + if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr )) + { + CvMat* mat = (CvMat*)arr; + cvDecRefData( mat ); + } + else if( CV_IS_IMAGE_HDR( arr )) + { + IplImage* img = (IplImage*)arr; + + if( !CvIPL.deallocate ) + { + char* ptr = img->imageDataOrigin; + img->imageData = img->imageDataOrigin = 0; + cvFree( &ptr ); + } + else + { + CvIPL.deallocate( img, IPL_IMAGE_DATA ); + } + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); +} + + +// Retrieves essential information about image ROI or CvMat data +CV_IMPL void +cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) +{ + if( CV_IS_MAT( arr )) + { + CvMat *mat = (CvMat*)arr; + + if( step ) + *step = mat->step; + + if( data ) + *data = mat->data.ptr; + + if( roi_size ) + *roi_size = cvGetMatSize( mat ); + } + else if( CV_IS_IMAGE( arr )) + { + IplImage* img = (IplImage*)arr; + + if( step ) + *step = img->widthStep; + + if( data ) + *data = cvPtr2D( img, 0, 0 ); + + if( roi_size ) + { + if( img->roi ) + { + *roi_size = cvSize( img->roi->width, img->roi->height ); + } + else + { + *roi_size = cvSize( img->width, img->height ); + } + } + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + + if( !CV_IS_MAT_CONT( mat->type )) + CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + + if( data ) + *data = mat->data.ptr; + + if( roi_size || step ) + { + int i, size1 = mat->dim[0].size, size2 = 1; + + if( mat->dims > 2 ) + for( i = 1; i < mat->dims; i++ ) + size1 *= mat->dim[i].size; + else + size2 = mat->dim[1].size; + + if( roi_size ) + { + roi_size->width = size2; + roi_size->height = size1; + } + + if( step ) + *step = mat->dim[0].step; + } + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); +} + + +CV_IMPL int +cvGetElemType( const CvArr* arr ) +{ + int type = -1; + if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr)) + type = CV_MAT_TYPE( ((CvMat*)arr)->type ); + else if( CV_IS_IMAGE(arr)) + { + IplImage* img = (IplImage*)arr; + type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels ); + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + + return type; +} + + +// Returns a number of array dimensions +CV_IMPL int +cvGetDims( const CvArr* arr, int* sizes ) +{ + int dims = -1; + if( CV_IS_MAT_HDR( arr )) + { + CvMat* mat = (CvMat*)arr; + + dims = 2; + if( sizes ) + { + sizes[0] = mat->rows; + sizes[1] = mat->cols; + } + } + else if( CV_IS_IMAGE( arr )) + { + IplImage* img = (IplImage*)arr; + dims = 2; + + if( sizes ) + { + sizes[0] = img->height; + sizes[1] = img->width; + } + } + else if( CV_IS_MATND_HDR( arr )) + { + CvMatND* mat = (CvMatND*)arr; + dims = mat->dims; + + if( sizes ) + { + int i; + for( i = 0; i < dims; i++ ) + sizes[i] = mat->dim[i].size; + } + } + else if( CV_IS_SPARSE_MAT_HDR( arr )) + { + CvSparseMat* mat = (CvSparseMat*)arr; + dims = mat->dims; + + if( sizes ) + memcpy( sizes, mat->size, dims*sizeof(sizes[0])); + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + + return dims; +} + + +// Returns the size of particular array dimension +CV_IMPL int +cvGetDimSize( const CvArr* arr, int index ) +{ + int size = -1; + + if( CV_IS_MAT( arr )) + { + CvMat *mat = (CvMat*)arr; + + switch( index ) + { + case 0: + size = mat->rows; + break; + case 1: + size = mat->cols; + break; + default: + CV_Error( CV_StsOutOfRange, "bad dimension index" ); + } + } + else if( CV_IS_IMAGE( arr )) + { + IplImage* img = (IplImage*)arr; + + switch( index ) + { + case 0: + size = !img->roi ? img->height : img->roi->height; + break; + case 1: + size = !img->roi ? img->width : img->roi->width; + break; + default: + CV_Error( CV_StsOutOfRange, "bad dimension index" ); + } + } + else if( CV_IS_MATND_HDR( arr )) + { + CvMatND* mat = (CvMatND*)arr; + + if( (unsigned)index >= (unsigned)mat->dims ) + CV_Error( CV_StsOutOfRange, "bad dimension index" ); + + size = mat->dim[index].size; + } + else if( CV_IS_SPARSE_MAT_HDR( arr )) + { + CvSparseMat* mat = (CvSparseMat*)arr; + + if( (unsigned)index >= (unsigned)mat->dims ) + CV_Error( CV_StsOutOfRange, "bad dimension index" ); + + size = mat->size[index]; + } + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + + return size; +} + + +// Returns the size of CvMat or IplImage +CV_IMPL CvSize +cvGetSize( const CvArr* arr ) +{ + CvSize size = { 0, 0 }; + + if( CV_IS_MAT_HDR_Z( arr )) + { + CvMat *mat = (CvMat*)arr; + + size.width = mat->cols; + size.height = mat->rows; + } + else if( CV_IS_IMAGE_HDR( arr )) + { + IplImage* img = (IplImage*)arr; + + if( img->roi ) + { + size.width = img->roi->width; + size.height = img->roi->height; + } + else + { + size.width = img->width; + size.height = img->height; + } + } + else + CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" ); + + return size; +} + + +// Selects sub-array (no data is copied) +CV_IMPL CvMat* +cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ) +{ + CvMat* res = 0; + CvMat stub, *mat = (CvMat*)arr; + + if( !CV_IS_MAT( mat )) + mat = cvGetMat( mat, &stub ); + + if( !submat ) + CV_Error( CV_StsNullPtr, "" ); + + if( (rect.x|rect.y|rect.width|rect.height) < 0 ) + CV_Error( CV_StsBadSize, "" ); + + if( rect.x + rect.width > mat->cols || + rect.y + rect.height > mat->rows ) + CV_Error( CV_StsBadSize, "" ); + + { + /* + int* refcount = mat->refcount; + + if( refcount ) + ++*refcount; + + cvDecRefData( submat ); + */ + submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step + + rect.x*CV_ELEM_SIZE(mat->type); + submat->step = mat->step; + submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) | + (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0); + submat->rows = rect.height; + submat->cols = rect.width; + submat->refcount = 0; + res = submat; + } + + return res; +} + + +// Selects array's row span. +CV_IMPL CvMat* +cvGetRows( const CvArr* arr, CvMat* submat, + int start_row, int end_row, int delta_row ) +{ + CvMat* res = 0; + CvMat stub, *mat = (CvMat*)arr; + + if( !CV_IS_MAT( mat )) + mat = cvGetMat( mat, &stub ); + + if( !submat ) + CV_Error( CV_StsNullPtr, "" ); + + if( (unsigned)start_row >= (unsigned)mat->rows || + (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + { + /* + int* refcount = mat->refcount; + + if( refcount ) + ++*refcount; + + cvDecRefData( submat ); + */ + if( delta_row == 1 ) + { + submat->rows = end_row - start_row; + submat->step = mat->step; + } + else + { + submat->rows = (end_row - start_row + delta_row - 1)/delta_row; + submat->step = mat->step * delta_row; + } + + submat->cols = mat->cols; + submat->step &= submat->rows > 1 ? -1 : 0; + submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step; + submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) & + (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1); + submat->refcount = 0; + submat->hdr_refcount = 0; + res = submat; + } + + return res; +} + + +// Selects array's column span. +CV_IMPL CvMat* +cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) +{ + CvMat* res = 0; + CvMat stub, *mat = (CvMat*)arr; + int cols; + + if( !CV_IS_MAT( mat )) + mat = cvGetMat( mat, &stub ); + + if( !submat ) + CV_Error( CV_StsNullPtr, "" ); + + cols = mat->cols; + if( (unsigned)start_col >= (unsigned)cols || + (unsigned)end_col > (unsigned)cols ) + CV_Error( CV_StsOutOfRange, "" ); + + { + /* + int* refcount = mat->refcount; + + if( refcount ) + ++*refcount; + + cvDecRefData( submat ); + */ + submat->rows = mat->rows; + submat->cols = end_col - start_col; + submat->step = mat->step; + submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type); + submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1); + submat->refcount = 0; + submat->hdr_refcount = 0; + res = submat; + } + + return res; +} + + +// Selects array diagonal +CV_IMPL CvMat* +cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) +{ + CvMat* res = 0; + CvMat stub, *mat = (CvMat*)arr; + int len, pix_size; + + if( !CV_IS_MAT( mat )) + mat = cvGetMat( mat, &stub ); + + if( !submat ) + CV_Error( CV_StsNullPtr, "" ); + + pix_size = CV_ELEM_SIZE(mat->type); + + /*{ + int* refcount = mat->refcount; + + if( refcount ) + ++*refcount; + + cvDecRefData( submat ); + }*/ + + if( diag >= 0 ) + { + len = mat->cols - diag; + + if( len <= 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + len = CV_IMIN( len, mat->rows ); + submat->data.ptr = mat->data.ptr + diag*pix_size; + } + else + { + len = mat->rows + diag; + + if( len <= 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + len = CV_IMIN( len, mat->cols ); + submat->data.ptr = mat->data.ptr - diag*mat->step; + } + + submat->rows = len; + submat->cols = 1; + submat->step = mat->step + (submat->rows > 1 ? pix_size : 0); + submat->type = mat->type; + if( submat->rows > 1 ) + submat->type &= ~CV_MAT_CONT_FLAG; + else + submat->type |= CV_MAT_CONT_FLAG; + submat->refcount = 0; + submat->hdr_refcount = 0; + res = submat; + + return res; +} + + +/****************************************************************************************\ +* Operations on CvScalar and accessing array elements * +\****************************************************************************************/ + +// Converts CvScalar to specified type +CV_IMPL void +cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 ) +{ + type = CV_MAT_TYPE(type); + int cn = CV_MAT_CN( type ); + int depth = type & CV_MAT_DEPTH_MASK; + + assert( scalar && data ); + if( (unsigned)(cn - 1) >= 4 ) + CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + + switch( depth ) + { + case CV_8UC1: + while( cn-- ) + { + int t = cvRound( scalar->val[cn] ); + ((uchar*)data)[cn] = CV_CAST_8U(t); + } + break; + case CV_8SC1: + while( cn-- ) + { + int t = cvRound( scalar->val[cn] ); + ((char*)data)[cn] = CV_CAST_8S(t); + } + break; + case CV_16UC1: + while( cn-- ) + { + int t = cvRound( scalar->val[cn] ); + ((ushort*)data)[cn] = CV_CAST_16U(t); + } + break; + case CV_16SC1: + while( cn-- ) + { + int t = cvRound( scalar->val[cn] ); + ((short*)data)[cn] = CV_CAST_16S(t); + } + break; + case CV_32SC1: + while( cn-- ) + ((int*)data)[cn] = cvRound( scalar->val[cn] ); + break; + case CV_32FC1: + while( cn-- ) + ((float*)data)[cn] = (float)(scalar->val[cn]); + break; + case CV_64FC1: + while( cn-- ) + ((double*)data)[cn] = (double)(scalar->val[cn]); + break; + default: + assert(0); + CV_Error( CV_BadDepth, "" ); + } + + if( extend_to_12 ) + { + int pix_size = CV_ELEM_SIZE(type); + int offset = CV_ELEM_SIZE1(depth)*12; + + do + { + offset -= pix_size; + memcpy((char*)data + offset, data, pix_size); + } + while( offset > pix_size ); + } +} + + +// Converts data of specified type to CvScalar +CV_IMPL void +cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) +{ + int cn = CV_MAT_CN( flags ); + + assert( scalar && data ); + + if( (unsigned)(cn - 1) >= 4 ) + CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + + memset( scalar->val, 0, sizeof(scalar->val)); + + switch( CV_MAT_DEPTH( flags )) + { + case CV_8U: + while( cn-- ) + scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]); + break; + case CV_8S: + while( cn-- ) + scalar->val[cn] = CV_8TO32F(((char*)data)[cn]); + break; + case CV_16U: + while( cn-- ) + scalar->val[cn] = ((ushort*)data)[cn]; + break; + case CV_16S: + while( cn-- ) + scalar->val[cn] = ((short*)data)[cn]; + break; + case CV_32S: + while( cn-- ) + scalar->val[cn] = ((int*)data)[cn]; + break; + case CV_32F: + while( cn-- ) + scalar->val[cn] = ((float*)data)[cn]; + break; + case CV_64F: + while( cn-- ) + scalar->val[cn] = ((double*)data)[cn]; + break; + default: + assert(0); + CV_Error( CV_BadDepth, "" ); + } +} + + +static double icvGetReal( const void* data, int type ) +{ + switch( type ) + { + case CV_8U: + return *(uchar*)data; + case CV_8S: + return *(char*)data; + case CV_16U: + return *(ushort*)data; + case CV_16S: + return *(short*)data; + case CV_32S: + return *(int*)data; + case CV_32F: + return *(float*)data; + case CV_64F: + return *(double*)data; + } + + return 0; +} + + +static void icvSetReal( double value, const void* data, int type ) +{ + if( type < CV_32F ) + { + int ivalue = cvRound(value); + switch( type ) + { + case CV_8U: + *(uchar*)data = CV_CAST_8U(ivalue); + break; + case CV_8S: + *(char*)data = CV_CAST_8S(ivalue); + break; + case CV_16U: + *(ushort*)data = CV_CAST_16U(ivalue); + break; + case CV_16S: + *(short*)data = CV_CAST_16S(ivalue); + break; + case CV_32S: + *(int*)data = CV_CAST_32S(ivalue); + break; + } + } + else + { + switch( type ) + { + case CV_32F: + *(float*)data = (float)value; + break; + case CV_64F: + *(double*)data = value; + break; + } + } +} + + +// Returns pointer to specified element of array (linear index is used) +CV_IMPL uchar* +cvPtr1D( const CvArr* arr, int idx, int* _type ) +{ + uchar* ptr = 0; + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + + int type = CV_MAT_TYPE(mat->type); + int pix_size = CV_ELEM_SIZE(type); + + if( _type ) + *_type = type; + + // the first part is mul-free sufficient check + // that the index is within the matrix + if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && + (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + if( CV_IS_MAT_CONT(mat->type)) + { + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else + { + int row, col; + if( mat->cols == 1 ) + row = idx, col = 0; + else + row = idx/mat->cols, col = idx - row*mat->cols; + ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size; + } + } + else if( CV_IS_IMAGE_HDR( arr )) + { + IplImage* img = (IplImage*)arr; + int width = !img->roi ? img->width : img->roi->width; + int y = idx/width, x = idx - y*width; + + ptr = cvPtr2D( arr, y, x, _type ); + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + int j, type = CV_MAT_TYPE(mat->type); + size_t size = mat->dim[0].size; + + if( _type ) + *_type = type; + + for( j = 1; j < mat->dims; j++ ) + size *= mat->dim[j].size; + + if((unsigned)idx >= (unsigned)size ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + if( CV_IS_MAT_CONT(mat->type)) + { + int pix_size = CV_ELEM_SIZE(type); + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else + { + ptr = mat->data.ptr; + for( j = mat->dims - 1; j >= 0; j-- ) + { + int sz = mat->dim[j].size; + if( sz ) + { + int t = idx/sz; + ptr += (idx - t*sz)*mat->dim[j].step; + idx = t; + } + } + } + } + else if( CV_IS_SPARSE_MAT( arr )) + { + CvSparseMat* m = (CvSparseMat*)arr; + if( m->dims == 1 ) + ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 ); + else + { + int i, n = m->dims; + CV_DbgAssert( n <= CV_MAX_DIM_HEAP ); + int _idx[CV_MAX_DIM_HEAP]; + + for( i = n - 1; i >= 0; i-- ) + { + int t = idx / m->size[i]; + _idx[i] = idx - t*m->size[i]; + idx = t; + } + ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 ); + } + } + else + { + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + } + + return ptr; +} + + +// Returns pointer to specified element of 2d array +CV_IMPL uchar* +cvPtr2D( const CvArr* arr, int y, int x, int* _type ) +{ + uchar* ptr = 0; + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + int type; + + if( (unsigned)y >= (unsigned)(mat->rows) || + (unsigned)x >= (unsigned)(mat->cols) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + type = CV_MAT_TYPE(mat->type); + if( _type ) + *_type = type; + + ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); + } + else if( CV_IS_IMAGE( arr )) + { + IplImage* img = (IplImage*)arr; + int pix_size = (img->depth & 255) >> 3; + int width, height; + ptr = (uchar*)img->imageData; + + if( img->dataOrder == 0 ) + pix_size *= img->nChannels; + + if( img->roi ) + { + width = img->roi->width; + height = img->roi->height; + + ptr += img->roi->yOffset*img->widthStep + + img->roi->xOffset*pix_size; + + if( img->dataOrder ) + { + int coi = img->roi->coi; + if( !coi ) + CV_Error( CV_BadCOI, + "COI must be non-null in case of planar images" ); + ptr += (coi - 1)*img->imageSize; + } + } + else + { + width = img->width; + height = img->height; + } + + if( (unsigned)y >= (unsigned)height || + (unsigned)x >= (unsigned)width ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr += y*img->widthStep + x*pix_size; + + if( _type ) + { + int type = IPL2CV_DEPTH(img->depth); + if( type < 0 || (unsigned)(img->nChannels - 1) > 3 ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + *_type = CV_MAKETYPE( type, img->nChannels ); + } + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + + if( mat->dims != 2 || + (unsigned)y >= (unsigned)(mat->dim[0].size) || + (unsigned)x >= (unsigned)(mat->dim[1].size) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step; + if( _type ) + *_type = CV_MAT_TYPE(mat->type); + } + else if( CV_IS_SPARSE_MAT( arr )) + { + int idx[] = { y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); + } + else + { + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + } + + return ptr; +} + + +// Returns pointer to specified element of 3d array +CV_IMPL uchar* +cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) +{ + uchar* ptr = 0; + if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + + if( mat->dims != 3 || + (unsigned)z >= (unsigned)(mat->dim[0].size) || + (unsigned)y >= (unsigned)(mat->dim[1].size) || + (unsigned)x >= (unsigned)(mat->dim[2].size) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)z*mat->dim[0].step + + (size_t)y*mat->dim[1].step + x*mat->dim[2].step; + + if( _type ) + *_type = CV_MAT_TYPE(mat->type); + } + else if( CV_IS_SPARSE_MAT( arr )) + { + int idx[] = { z, y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); + } + else + { + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + } + + return ptr; +} + + +// Returns pointer to specified element of n-d array +CV_IMPL uchar* +cvPtrND( const CvArr* arr, const int* idx, int* _type, + int create_node, unsigned* precalc_hashval ) +{ + uchar* ptr = 0; + if( !idx ) + CV_Error( CV_StsNullPtr, "NULL pointer to indices" ); + + if( CV_IS_SPARSE_MAT( arr )) + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, + _type, create_node, precalc_hashval ); + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + int i; + ptr = mat->data.ptr; + + for( i = 0; i < mat->dims; i++ ) + { + if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + ptr += (size_t)idx[i]*mat->dim[i].step; + } + + if( _type ) + *_type = CV_MAT_TYPE(mat->type); + } + else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) ) + ptr = cvPtr2D( arr, idx[0], idx[1], _type ); + else + CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + + return ptr; +} + + +// Returns specifed element of n-D array given linear index +CV_IMPL CvScalar +cvGet1D( const CvArr* arr, int idx ) +{ + CvScalar scalar = {{0,0,0,0}}; + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) + { + CvMat* mat = (CvMat*)arr; + + type = CV_MAT_TYPE(mat->type); + int pix_size = CV_ELEM_SIZE(type); + + // the first part is mul-free sufficient check + // that the index is within the matrix + if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && + (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) + ptr = cvPtr1D( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); + + if( ptr ) + cvRawDataToScalar( ptr, type, &scalar ); + + return scalar; +} + + +// Returns specifed element of 2D array +CV_IMPL CvScalar +cvGet2D( const CvArr* arr, int y, int x ) +{ + CvScalar scalar = {{0,0,0,0}}; + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + + if( (unsigned)y >= (unsigned)(mat->rows) || + (unsigned)x >= (unsigned)(mat->cols) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + type = CV_MAT_TYPE(mat->type); + ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); + } + else if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr2D( arr, y, x, &type ); + else + { + int idx[] = { y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + } + + if( ptr ) + cvRawDataToScalar( ptr, type, &scalar ); + + return scalar; +} + + +// Returns specifed element of 3D array +CV_IMPL CvScalar +cvGet3D( const CvArr* arr, int z, int y, int x ) +{ + CvScalar scalar = {{0,0,0,0}}; + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr3D( arr, z, y, x, &type ); + else + { + int idx[] = { z, y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + } + + if( ptr ) + cvRawDataToScalar( ptr, type, &scalar ); + return scalar; +} + + +// Returns specifed element of nD array +CV_IMPL CvScalar +cvGetND( const CvArr* arr, const int* idx ) +{ + CvScalar scalar = {{0,0,0,0}}; + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtrND( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + + if( ptr ) + cvRawDataToScalar( ptr, type, &scalar ); + + return scalar; +} + + +// Returns specifed element of n-D array given linear index +CV_IMPL double +cvGetReal1D( const CvArr* arr, int idx ) +{ + double value = 0; + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) + { + CvMat* mat = (CvMat*)arr; + + type = CV_MAT_TYPE(mat->type); + int pix_size = CV_ELEM_SIZE(type); + + // the first part is mul-free sufficient check + // that the index is within the matrix + if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && + (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) + ptr = cvPtr1D( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); + + if( ptr ) + { + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + + value = icvGetReal( ptr, type ); + } + return value; +} + + +// Returns specifed element of 2D array +CV_IMPL double +cvGetReal2D( const CvArr* arr, int y, int x ) +{ + double value = 0; + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + + if( (unsigned)y >= (unsigned)(mat->rows) || + (unsigned)x >= (unsigned)(mat->cols) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + type = CV_MAT_TYPE(mat->type); + ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); + } + else if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr2D( arr, y, x, &type ); + else + { + int idx[] = { y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + } + + if( ptr ) + { + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + + value = icvGetReal( ptr, type ); + } + + return value; +} + + +// Returns specifed element of 3D array +CV_IMPL double +cvGetReal3D( const CvArr* arr, int z, int y, int x ) +{ + double value = 0; + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr3D( arr, z, y, x, &type ); + else + { + int idx[] = { z, y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + } + + if( ptr ) + { + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + + value = icvGetReal( ptr, type ); + } + + return value; +} + + +// Returns specifed element of nD array +CV_IMPL double +cvGetRealND( const CvArr* arr, const int* idx ) +{ + double value = 0; + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtrND( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); + + if( ptr ) + { + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + + value = icvGetReal( ptr, type ); + } + + return value; +} + + +// Assigns new value to specifed element of nD array given linear index +CV_IMPL void +cvSet1D( CvArr* arr, int idx, CvScalar scalar ) +{ + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) + { + CvMat* mat = (CvMat*)arr; + + type = CV_MAT_TYPE(mat->type); + int pix_size = CV_ELEM_SIZE(type); + + // the first part is mul-free sufficient check + // that the index is within the matrix + if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && + (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) + ptr = cvPtr1D( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); + + cvScalarToRawData( &scalar, ptr, type ); +} + + +// Assigns new value to specifed element of 2D array +CV_IMPL void +cvSet2D( CvArr* arr, int y, int x, CvScalar scalar ) +{ + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + + if( (unsigned)y >= (unsigned)(mat->rows) || + (unsigned)x >= (unsigned)(mat->cols) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + type = CV_MAT_TYPE(mat->type); + ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); + } + else if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr2D( arr, y, x, &type ); + else + { + int idx[] = { y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + } + cvScalarToRawData( &scalar, ptr, type ); +} + + +// Assigns new value to specifed element of 3D array +CV_IMPL void +cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar ) +{ + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr3D( arr, z, y, x, &type ); + else + { + int idx[] = { z, y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + } + cvScalarToRawData( &scalar, ptr, type ); +} + + +// Assigns new value to specifed element of nD array +CV_IMPL void +cvSetND( CvArr* arr, const int* idx, CvScalar scalar ) +{ + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtrND( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + cvScalarToRawData( &scalar, ptr, type ); +} + + +CV_IMPL void +cvSetReal1D( CvArr* arr, int idx, double value ) +{ + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) + { + CvMat* mat = (CvMat*)arr; + + type = CV_MAT_TYPE(mat->type); + int pix_size = CV_ELEM_SIZE(type); + + // the first part is mul-free sufficient check + // that the index is within the matrix + if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && + (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + ptr = mat->data.ptr + (size_t)idx*pix_size; + } + else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) + ptr = cvPtr1D( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); + + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + + if( ptr ) + icvSetReal( value, ptr, type ); +} + + +CV_IMPL void +cvSetReal2D( CvArr* arr, int y, int x, double value ) +{ + int type = 0; + uchar* ptr; + + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + + if( (unsigned)y >= (unsigned)(mat->rows) || + (unsigned)x >= (unsigned)(mat->cols) ) + CV_Error( CV_StsOutOfRange, "index is out of range" ); + + type = CV_MAT_TYPE(mat->type); + ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); + } + else if( !CV_IS_SPARSE_MAT( arr )) + { + ptr = cvPtr2D( arr, y, x, &type ); + } + else + { + int idx[] = { y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + } + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + + if( ptr ) + icvSetReal( value, ptr, type ); +} + + +CV_IMPL void +cvSetReal3D( CvArr* arr, int z, int y, int x, double value ) +{ + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtr3D( arr, z, y, x, &type ); + else + { + int idx[] = { z, y, x }; + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + } + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + + if( ptr ) + icvSetReal( value, ptr, type ); +} + + +CV_IMPL void +cvSetRealND( CvArr* arr, const int* idx, double value ) +{ + int type = 0; + uchar* ptr; + + if( !CV_IS_SPARSE_MAT( arr )) + ptr = cvPtrND( arr, idx, &type ); + else + ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); + + if( CV_MAT_CN( type ) > 1 ) + CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + + if( ptr ) + icvSetReal( value, ptr, type ); +} + + +CV_IMPL void +cvClearND( CvArr* arr, const int* idx ) +{ + if( !CV_IS_SPARSE_MAT( arr )) + { + int type; + uchar* ptr; + ptr = cvPtrND( arr, idx, &type ); + if( ptr ) + memset( ptr, 0, CV_ELEM_SIZE(type) ); + } + else + icvDeleteNode( (CvSparseMat*)arr, idx, 0 ); +} + + +/****************************************************************************************\ +* Conversion to CvMat or IplImage * +\****************************************************************************************/ + +// convert array (CvMat or IplImage) to CvMat +CV_IMPL CvMat* +cvGetMat( const CvArr* array, CvMat* mat, + int* pCOI, int allowND ) +{ + CvMat* result = 0; + CvMat* src = (CvMat*)array; + int coi = 0; + + if( !mat || !src ) + CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); + + if( CV_IS_MAT_HDR(src)) + { + if( !src->data.ptr ) + CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); + + result = (CvMat*)src; + } + else if( CV_IS_IMAGE_HDR(src) ) + { + const IplImage* img = (const IplImage*)src; + int depth, order; + + if( img->imageData == 0 ) + CV_Error( CV_StsNullPtr, "The image has NULL data pointer" ); + + depth = IPL2CV_DEPTH( img->depth ); + if( depth < 0 ) + CV_Error( CV_BadDepth, "" ); + + order = img->dataOrder & (img->nChannels > 1 ? -1 : 0); + + if( img->roi ) + { + if( order == IPL_DATA_ORDER_PLANE ) + { + int type = depth; + + if( img->roi->coi == 0 ) + CV_Error( CV_StsBadFlag, + "Images with planar data layout should be used with COI selected" ); + + cvInitMatHeader( mat, img->roi->height, + img->roi->width, type, + img->imageData + (img->roi->coi-1)*img->imageSize + + img->roi->yOffset*img->widthStep + + img->roi->xOffset*CV_ELEM_SIZE(type), + img->widthStep ); + } + else /* pixel order */ + { + int type = CV_MAKETYPE( depth, img->nChannels ); + coi = img->roi->coi; + + if( img->nChannels > CV_CN_MAX ) + CV_Error( CV_BadNumChannels, + "The image is interleaved and has over CV_CN_MAX channels" ); + + cvInitMatHeader( mat, img->roi->height, img->roi->width, + type, img->imageData + + img->roi->yOffset*img->widthStep + + img->roi->xOffset*CV_ELEM_SIZE(type), + img->widthStep ); + } + } + else + { + int type = CV_MAKETYPE( depth, img->nChannels ); + + if( order != IPL_DATA_ORDER_PIXEL ) + CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" ); + + cvInitMatHeader( mat, img->height, img->width, type, + img->imageData, img->widthStep ); + } + + result = mat; + } + else if( allowND && CV_IS_MATND_HDR(src) ) + { + CvMatND* matnd = (CvMatND*)src; + int i; + int size1 = matnd->dim[0].size, size2 = 1; + + if( !src->data.ptr ) + CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); + + if( !CV_IS_MAT_CONT( matnd->type )) + CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + + if( matnd->dims > 2 ) + for( i = 1; i < matnd->dims; i++ ) + size2 *= matnd->dim[i].size; + else + size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size; + + mat->refcount = 0; + mat->hdr_refcount = 0; + mat->data.ptr = matnd->data.ptr; + mat->rows = size1; + mat->cols = size2; + mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG; + mat->step = size2*CV_ELEM_SIZE(matnd->type); + mat->step &= size1 > 1 ? -1 : 0; + + icvCheckHuge( mat ); + result = mat; + } + else + CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" ); + + if( pCOI ) + *pCOI = coi; + + return result; +} + + +CV_IMPL CvArr* +cvReshapeMatND( const CvArr* arr, + int sizeof_header, CvArr* _header, + int new_cn, int new_dims, int* new_sizes ) +{ + CvArr* result = 0; + int dims, coi = 0; + + if( !arr || !_header ) + CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" ); + + if( new_cn == 0 && new_dims == 0 ) + CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" ); + + dims = cvGetDims( arr ); + + if( new_dims == 0 ) + { + new_sizes = 0; + new_dims = dims; + } + else if( new_dims == 1 ) + { + new_sizes = 0; + } + else + { + if( new_dims <= 0 || new_dims > CV_MAX_DIM ) + CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" ); + if( !new_sizes ) + CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" ); + } + + if( new_dims <= 2 ) + { + CvMat* mat = (CvMat*)arr; + CvMat header; + int* refcount = 0; + int hdr_refcount = 0; + int total_width, new_rows, cn; + + if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) ) + CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" ); + + if( mat == (CvMat*)_header ) + { + refcount = mat->refcount; + hdr_refcount = mat->hdr_refcount; + } + + if( !CV_IS_MAT( mat )) + mat = cvGetMat( mat, &header, &coi, 1 ); + + cn = CV_MAT_CN( mat->type ); + total_width = mat->cols * cn; + + if( new_cn == 0 ) + new_cn = cn; + + if( new_sizes ) + new_rows = new_sizes[0]; + else if( new_dims == 1 ) + new_rows = total_width*mat->rows/new_cn; + else + { + new_rows = mat->rows; + if( new_cn > total_width ) + new_rows = mat->rows * total_width / new_cn; + } + + if( new_rows != mat->rows ) + { + int total_size = total_width * mat->rows; + + if( !CV_IS_MAT_CONT( mat->type )) + CV_Error( CV_BadStep, + "The matrix is not continuous so the number of rows can not be changed" ); + + total_width = total_size / new_rows; + + if( total_width * new_rows != total_size ) + CV_Error( CV_StsBadArg, "The total number of matrix elements " + "is not divisible by the new number of rows" ); + } + + header.rows = new_rows; + header.cols = total_width / new_cn; + + if( header.cols * new_cn != total_width || + (new_sizes && header.cols != new_sizes[1]) ) + CV_Error( CV_StsBadArg, "The total matrix width is not " + "divisible by the new number of columns" ); + + header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); + header.step = header.cols * CV_ELEM_SIZE(mat->type); + header.step &= new_rows > 1 ? -1 : 0; + header.refcount = refcount; + header.hdr_refcount = hdr_refcount; + + if( sizeof_header == sizeof(CvMat) ) + *(CvMat*)_header = header; + else + { + CvMatND* __header = (CvMatND*)_header; + cvGetMatND(&header, __header, 0); + if( new_dims > 0 ) + __header->dims = new_dims; + } + } + else + { + CvMatND* header = (CvMatND*)_header; + + if( sizeof_header != sizeof(CvMatND)) + CV_Error( CV_StsBadSize, "The output header should be CvMatND" ); + + if( !new_sizes ) + { + if( !CV_IS_MATND( arr )) + CV_Error( CV_StsBadArg, "The input array must be CvMatND" ); + + { + CvMatND* mat = (CvMatND*)arr; + assert( new_cn > 0 ); + int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type); + int new_size = last_dim_size/new_cn; + + if( new_size*new_cn != last_dim_size ) + CV_Error( CV_StsBadArg, + "The last dimension full size is not divisible by new number of channels"); + + if( mat != header ) + { + memcpy( header, mat, sizeof(*header)); + header->refcount = 0; + header->hdr_refcount = 0; + } + + header->dim[header->dims-1].size = new_size; + header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn); + } + } + else + { + CvMatND stub; + CvMatND* mat = (CvMatND*)arr; + int i, size1, size2; + int step; + + if( new_cn != 0 ) + CV_Error( CV_StsBadArg, + "Simultaneous change of shape and number of channels is not supported. " + "Do it by 2 separate calls" ); + + if( !CV_IS_MATND( mat )) + { + cvGetMatND( mat, &stub, &coi ); + mat = &stub; + } + + if( CV_IS_MAT_CONT( mat->type )) + CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" ); + + size1 = mat->dim[0].size; + for( i = 1; i < dims; i++ ) + size1 *= mat->dim[i].size; + + size2 = 1; + for( i = 0; i < new_dims; i++ ) + { + if( new_sizes[i] <= 0 ) + CV_Error( CV_StsBadSize, + "One of new dimension sizes is non-positive" ); + size2 *= new_sizes[i]; + } + + if( size1 != size2 ) + CV_Error( CV_StsBadSize, + "Number of elements in the original and reshaped array is different" ); + + if( header != mat ) + { + header->refcount = 0; + header->hdr_refcount = 0; + } + + header->dims = new_dims; + header->type = mat->type; + header->data.ptr = mat->data.ptr; + step = CV_ELEM_SIZE(header->type); + + for( i = new_dims - 1; i >= 0; i-- ) + { + header->dim[i].size = new_sizes[i]; + header->dim[i].step = step; + step *= new_sizes[i]; + } + } + } + + if( coi ) + CV_Error( CV_BadCOI, "COI is not supported by this operation" ); + + result = _header; + return result; +} + + +CV_IMPL CvMat* +cvReshape( const CvArr* array, CvMat* header, + int new_cn, int new_rows ) +{ + CvMat* result = 0; + CvMat *mat = (CvMat*)array; + int total_width, new_width; + + if( !header ) + CV_Error( CV_StsNullPtr, "" ); + + if( !CV_IS_MAT( mat )) + { + int coi = 0; + mat = cvGetMat( mat, header, &coi, 1 ); + if( coi ) + CV_Error( CV_BadCOI, "COI is not supported" ); + } + + if( new_cn == 0 ) + new_cn = CV_MAT_CN(mat->type); + else if( (unsigned)(new_cn - 1) > 3 ) + CV_Error( CV_BadNumChannels, "" ); + + if( mat != header ) + { + int hdr_refcount = header->hdr_refcount; + *header = *mat; + header->refcount = 0; + header->hdr_refcount = hdr_refcount; + } + + total_width = mat->cols * CV_MAT_CN( mat->type ); + + if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 ) + new_rows = mat->rows * total_width / new_cn; + + if( new_rows == 0 || new_rows == mat->rows ) + { + header->rows = mat->rows; + header->step = mat->step; + } + else + { + int total_size = total_width * mat->rows; + if( !CV_IS_MAT_CONT( mat->type )) + CV_Error( CV_BadStep, + "The matrix is not continuous, thus its number of rows can not be changed" ); + + if( (unsigned)new_rows > (unsigned)total_size ) + CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + + total_width = total_size / new_rows; + + if( total_width * new_rows != total_size ) + CV_Error( CV_StsBadArg, "The total number of matrix elements " + "is not divisible by the new number of rows" ); + + header->rows = new_rows; + header->step = total_width * CV_ELEM_SIZE1(mat->type); + } + + new_width = total_width / new_cn; + + if( new_width * new_cn != total_width ) + CV_Error( CV_BadNumChannels, + "The total width is not divisible by the new number of channels" ); + + header->cols = new_width; + header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); + + result = header; + return result; +} + + +// convert array (CvMat or IplImage) to IplImage +CV_IMPL IplImage* +cvGetImage( const CvArr* array, IplImage* img ) +{ + IplImage* result = 0; + const IplImage* src = (const IplImage*)array; + int depth; + + if( !img ) + CV_Error( CV_StsNullPtr, "" ); + + if( !CV_IS_IMAGE_HDR(src) ) + { + const CvMat* mat = (const CvMat*)src; + + if( !CV_IS_MAT_HDR(mat)) + CV_Error( CV_StsBadFlag, "" ); + + if( mat->data.ptr == 0 ) + CV_Error( CV_StsNullPtr, "" ); + + depth = cvIplDepth(mat->type); + + cvInitImageHeader( img, cvSize(mat->cols, mat->rows), + depth, CV_MAT_CN(mat->type) ); + cvSetData( img, mat->data.ptr, mat->step ); + + result = img; + } + else + { + result = (IplImage*)src; + } + + return result; +} + + +/****************************************************************************************\ +* IplImage-specific functions * +\****************************************************************************************/ + +static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height ) +{ + IplROI *roi = 0; + if( !CvIPL.createROI ) + { + roi = (IplROI*)cvAlloc( sizeof(*roi)); + + roi->coi = coi; + roi->xOffset = xOffset; + roi->yOffset = yOffset; + roi->width = width; + roi->height = height; + } + else + { + roi = CvIPL.createROI( coi, xOffset, yOffset, width, height ); + } + + return roi; +} + +static void +icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq ) +{ + static const char* tab[][2] = + { + {"GRAY", "GRAY"}, + {"",""}, + {"RGB","BGR"}, + {"RGB","BGRA"} + }; + + nchannels--; + *colorModel = *channelSeq = ""; + + if( (unsigned)nchannels <= 3 ) + { + *colorModel = tab[nchannels][0]; + *channelSeq = tab[nchannels][1]; + } +} + + +// create IplImage header +CV_IMPL IplImage * +cvCreateImageHeader( CvSize size, int depth, int channels ) +{ + IplImage *img = 0; + + if( !CvIPL.createHeader ) + { + img = (IplImage *)cvAlloc( sizeof( *img )); + cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL, + CV_DEFAULT_IMAGE_ROW_ALIGN ); + } + else + { + const char *colorModel, *channelSeq; + + icvGetColorModel( channels, &colorModel, &channelSeq ); + + img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq, + IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, + CV_DEFAULT_IMAGE_ROW_ALIGN, + size.width, size.height, 0, 0, 0, 0 ); + } + + return img; +} + + +// create IplImage header and allocate underlying data +CV_IMPL IplImage * +cvCreateImage( CvSize size, int depth, int channels ) +{ + IplImage *img = cvCreateImageHeader( size, depth, channels ); + assert( img ); + cvCreateData( img ); + + return img; +} + + +// initalize IplImage header, allocated by the user +CV_IMPL IplImage* +cvInitImageHeader( IplImage * image, CvSize size, int depth, + int channels, int origin, int align ) +{ + const char *colorModel, *channelSeq; + + if( !image ) + CV_Error( CV_HeaderIsNull, "null pointer to header" ); + + memset( image, 0, sizeof( *image )); + image->nSize = sizeof( *image ); + + icvGetColorModel( channels, &colorModel, &channelSeq ); + strncpy( image->colorModel, colorModel, 4 ); + strncpy( image->channelSeq, channelSeq, 4 ); + + if( size.width < 0 || size.height < 0 ) + CV_Error( CV_BadROISize, "Bad input roi" ); + + if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U && + depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U && + depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S && + depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) || + channels < 0 ) + CV_Error( CV_BadDepth, "Unsupported format" ); + if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL ) + CV_Error( CV_BadOrigin, "Bad input origin" ); + + if( align != 4 && align != 8 ) + CV_Error( CV_BadAlign, "Bad input align" ); + + image->width = size.width; + image->height = size.height; + + if( image->roi ) + { + image->roi->coi = 0; + image->roi->xOffset = image->roi->yOffset = 0; + image->roi->width = size.width; + image->roi->height = size.height; + } + + image->nChannels = MAX( channels, 1 ); + image->depth = depth; + image->align = align; + image->widthStep = (((image->width * image->nChannels * + (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1)); + image->origin = origin; + image->imageSize = image->widthStep * image->height; + + return image; +} + + +CV_IMPL void +cvReleaseImageHeader( IplImage** image ) +{ + if( !image ) + CV_Error( CV_StsNullPtr, "" ); + + if( *image ) + { + IplImage* img = *image; + *image = 0; + + if( !CvIPL.deallocate ) + { + cvFree( &img->roi ); + cvFree( &img ); + } + else + { + CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI ); + } + } +} + + +CV_IMPL void +cvReleaseImage( IplImage ** image ) +{ + if( !image ) + CV_Error( CV_StsNullPtr, "" ); + + if( *image ) + { + IplImage* img = *image; + *image = 0; + + cvReleaseData( img ); + cvReleaseImageHeader( &img ); + } +} + + +CV_IMPL void +cvSetImageROI( IplImage* image, CvRect rect ) +{ + if( !image ) + CV_Error( CV_HeaderIsNull, "" ); + + // allow zero ROI width or height + CV_Assert( rect.width >= 0 && rect.height >= 0 && + rect.x < image->width && rect.y < image->height && + rect.x + rect.width >= (int)(rect.width > 0) && + rect.y + rect.height >= (int)(rect.height > 0) ); + + rect.width += rect.x; + rect.height += rect.y; + + rect.x = std::max(rect.x, 0); + rect.y = std::max(rect.y, 0); + rect.width = std::min(rect.width, image->width); + rect.height = std::min(rect.height, image->height); + + rect.width -= rect.x; + rect.height -= rect.y; + + if( image->roi ) + { + image->roi->xOffset = rect.x; + image->roi->yOffset = rect.y; + image->roi->width = rect.width; + image->roi->height = rect.height; + } + else + image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ); +} + + +CV_IMPL void +cvResetImageROI( IplImage* image ) +{ + if( !image ) + CV_Error( CV_HeaderIsNull, "" ); + + if( image->roi ) + { + if( !CvIPL.deallocate ) + { + cvFree( &image->roi ); + } + else + { + CvIPL.deallocate( image, IPL_IMAGE_ROI ); + image->roi = 0; + } + } +} + + +CV_IMPL CvRect +cvGetImageROI( const IplImage* img ) +{ + CvRect rect = { 0, 0, 0, 0 }; + if( !img ) + CV_Error( CV_StsNullPtr, "Null pointer to image" ); + + if( img->roi ) + rect = cvRect( img->roi->xOffset, img->roi->yOffset, + img->roi->width, img->roi->height ); + else + rect = cvRect( 0, 0, img->width, img->height ); + + return rect; +} + + +CV_IMPL void +cvSetImageCOI( IplImage* image, int coi ) +{ + if( !image ) + CV_Error( CV_HeaderIsNull, "" ); + + if( (unsigned)coi > (unsigned)(image->nChannels) ) + CV_Error( CV_BadCOI, "" ); + + if( image->roi || coi != 0 ) + { + if( image->roi ) + { + image->roi->coi = coi; + } + else + { + image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ); + } + } +} + + +CV_IMPL int +cvGetImageCOI( const IplImage* image ) +{ + if( !image ) + CV_Error( CV_HeaderIsNull, "" ); + + return image->roi ? image->roi->coi : 0; +} + + +CV_IMPL IplImage* +cvCloneImage( const IplImage* src ) +{ + IplImage* dst = 0; + + if( !CV_IS_IMAGE_HDR( src )) + CV_Error( CV_StsBadArg, "Bad image header" ); + + if( !CvIPL.cloneImage ) + { + dst = (IplImage*)cvAlloc( sizeof(*dst)); + + memcpy( dst, src, sizeof(*src)); + dst->imageData = dst->imageDataOrigin = 0; + dst->roi = 0; + + if( src->roi ) + { + dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset, + src->roi->yOffset, src->roi->width, src->roi->height ); + } + + if( src->imageData ) + { + int size = src->imageSize; + cvCreateData( dst ); + memcpy( dst->imageData, src->imageData, size ); + } + } + else + dst = CvIPL.cloneImage( src ); + + return dst; +} + + +/****************************************************************************************\ +* Additional operations on CvTermCriteria * +\****************************************************************************************/ + +CV_IMPL CvTermCriteria +cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, + int default_max_iters ) +{ + CvTermCriteria crit; + + crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS; + crit.max_iter = default_max_iters; + crit.epsilon = (float)default_eps; + + if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 ) + CV_Error( CV_StsBadArg, + "Unknown type of term criteria" ); + + if( (criteria.type & CV_TERMCRIT_ITER) != 0 ) + { + if( criteria.max_iter <= 0 ) + CV_Error( CV_StsBadArg, + "Iterations flag is set and maximum number of iterations is <= 0" ); + crit.max_iter = criteria.max_iter; + } + + if( (criteria.type & CV_TERMCRIT_EPS) != 0 ) + { + if( criteria.epsilon < 0 ) + CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" ); + + crit.epsilon = criteria.epsilon; + } + + if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 ) + CV_Error( CV_StsBadArg, + "Neither accuracy nor maximum iterations " + "number flags are set in criteria type" ); + + crit.epsilon = (float)MAX( 0, crit.epsilon ); + crit.max_iter = MAX( 1, crit.max_iter ); + + return crit; +} + +namespace cv +{ + +template<> void Ptr::delete_obj() +{ cvReleaseMat(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseImage(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseMatND(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseSparseMat(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseMemStorage(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseFileStorage(&obj); } + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/cmdparser.cpp diffimg-2.0.0/3rdparty/opencv/core/src/cmdparser.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/cmdparser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/cmdparser.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,382 @@ +#include "precomp.hpp" + +#include +#include + +using namespace std; +using namespace cv; + +namespace { +void helpParser() +{ + printf("\nThe CommandLineParser class is designed for command line arguments parsing\n" + "Keys map: \n" + "Before you start to work with CommandLineParser you have to create a map for keys.\n" + " It will look like this\n" + " const char* keys =\n" + " {\n" + " { s| string| 123asd |string parameter}\n" + " { d| digit | 100 |digit parameter }\n" + " { c|noCamera|false |without camera }\n" + " { 1| |some text|help }\n" + " { 2| |333 |another help }\n" + " };\n" + "Usage syntax: \n" + " \"{\" - start of parameter string.\n" + " \"}\" - end of parameter string\n" + " \"|\" - separator between short name, full name, default value and help\n" + "Supported syntax: \n" + " --key1=arg1 \n" + " -key2=arg2 \n" + "Usage: \n" + " Imagine that the input parameters are next:\n" + " -s=string_value --digit=250 --noCamera lena.jpg 10000\n" + " CommandLineParser parser(argc, argv, keys) - create a parser object\n" + " parser.get(\"s\" or \"string\") will return you first parameter value\n" + " parser.get(\"s\", false or \"string\", false) will return you first parameter value\n" + " without spaces in end and begin\n" + " parser.get(\"d\" or \"digit\") will return you second parameter value.\n" + " It also works with 'unsigned int', 'double', and 'float' types>\n" + " parser.get(\"c\" or \"noCamera\") will return you true .\n" + " If you enter this key in commandline>\n" + " It return you false otherwise.\n" + " parser.get(\"1\") will return you the first argument without parameter (lena.jpg) \n" + " parser.get(\"2\") will return you the second argument without parameter (10000)\n" + " It also works with 'unsigned int', 'double', and 'float' types \n" + ); +} + +vector split_string(const string& str, const string& delimiters) +{ + vector res; + + string split_str = str; + size_t pos_delim = split_str.find(delimiters); + + while ( pos_delim != string::npos) + { + if (pos_delim == 0) + { + res.push_back(""); + split_str.erase(0, 1); + } + else + { + res.push_back(split_str.substr(0, pos_delim)); + split_str.erase(0, pos_delim + 1); + } + + pos_delim = split_str.find(delimiters); + } + + res.push_back(split_str); + + return res; +} + +string del_space(string name) +{ + while ((name.find_first_of(' ') == 0) && (name.length() > 0)) + name.erase(0, 1); + + while ((name.find_last_of(' ') == (name.length() - 1)) && (name.length() > 0)) + name.erase(name.end() - 1, name.end()); + + return name; +} + +}//namespace + +CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys) +{ + std::string keys_buffer; + std::string values_buffer; + std::string buffer; + std::string curName; + std::vector keysVector; + std::vector paramVector; + std::map >::iterator it; + size_t flagPosition; + int currentIndex = 1; + //bool isFound = false; + bool withNoKey = false; + bool hasValueThroughEq = false; + + keys_buffer = keys; + while (!keys_buffer.empty()) + { + + flagPosition = keys_buffer.find_first_of('}'); + flagPosition++; + buffer = keys_buffer.substr(0, flagPosition); + keys_buffer.erase(0, flagPosition); + + flagPosition = buffer.find('{'); + if (flagPosition != buffer.npos) + buffer.erase(flagPosition, (flagPosition + 1)); + + flagPosition = buffer.find('}'); + if (flagPosition != buffer.npos) + buffer.erase(flagPosition); + + paramVector = split_string(buffer, "|"); + while (paramVector.size() < 4) paramVector.push_back(""); + + buffer = paramVector[0]; + buffer += '|' + paramVector[1]; + + //if (buffer == "") CV_ERROR(CV_StsBadArg, "In CommandLineParser need set short and full name"); + + paramVector.erase(paramVector.begin(), paramVector.begin() + 2); + data[buffer] = paramVector; + } + + buffer.clear(); + keys_buffer.clear(); + paramVector.clear(); + for (int i = 1; i < argc; i++) + { + if (!argv[i]) + break; + curName = argv[i]; + if (curName.find('-') == 0 && ((curName[1] < '0') || (curName[1] > '9'))) + { + while (curName.find('-') == 0) + curName.erase(curName.begin(), (curName.begin() + 1)); + } + else + withNoKey = true; + if (curName.find('=') != curName.npos) + { + hasValueThroughEq = true; + buffer = curName; + curName.erase(curName.find('=')); + buffer.erase(0, (buffer.find('=') + 1)); + } + + values_buffer = del_space(values_buffer); + + for(it = data.begin(); it != data.end(); it++) + { + keys_buffer = it->first; + keysVector = split_string(keys_buffer, "|"); + + for (size_t j = 0; j < keysVector.size(); j++) keysVector[j] = del_space(keysVector[j]); + + values_buffer = it->second[0]; + if (((curName == keysVector[0]) || (curName == keysVector[1])) && hasValueThroughEq) + { + it->second[0] = buffer; + //isFound = true; + break; + } + + if (!hasValueThroughEq && ((curName == keysVector[0]) || (curName == keysVector[1])) + && ( + values_buffer.find("false") != values_buffer.npos || + values_buffer == "" + )) + { + it->second[0] = "true"; + //isFound = true; + break; + } + + if (!hasValueThroughEq && (values_buffer.find("false") == values_buffer.npos) && + ((curName == keysVector[0]) || (curName == keysVector[1]))) + { + it->second[0] = argv[++i]; + //isFound = true; + break; + } + + + if (withNoKey) + { + std::string noKeyStr = it->first; + if(atoi(noKeyStr.c_str()) == currentIndex) + { + it->second[0] = curName; + currentIndex++; + //isFound = true; + break; + } + } + } + + withNoKey = false; + hasValueThroughEq = false; + //isFound = false; + } +} + +bool CommandLineParser::has(const std::string& keys) +{ + std::map >::iterator it; + std::vector keysVector; + + for(it = data.begin(); it != data.end(); it++) + { + keysVector = split_string(it->first, "|"); + for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]); + + if (keysVector.size() == 1) keysVector.push_back(""); + + if ((del_space(keys).compare(keysVector[0]) == 0) || + (del_space(keys).compare(keysVector[1]) == 0)) + return true; + } + + return false; +} + +std::string CommandLineParser::getString(const std::string& keys) +{ + std::map >::iterator it; + std::vector valueVector; + + for(it = data.begin(); it != data.end(); it++) + { + valueVector = split_string(it->first, "|"); + for (size_t i = 0; i < valueVector.size(); i++) valueVector[i] = del_space(valueVector[i]); + + if (valueVector.size() == 1) valueVector.push_back(""); + + if ((del_space(keys).compare(valueVector[0]) == 0) || + (del_space(keys).compare(valueVector[1]) == 0)) + return it->second[0]; + } + return string(); +} + +template + _Tp CommandLineParser::fromStringNumber(const std::string& str)//the default conversion function for numbers +{ + return getData<_Tp>(str); +} + + void CommandLineParser::printParams() + { + int col_p = 30; + int col_d = 50; + + std::map >::iterator it; + std::vector keysVector; + std::string buf; + for(it = data.begin(); it != data.end(); it++) + { + keysVector = split_string(it->first, "|"); + for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]); + + cout << " "; + buf = ""; + if (keysVector[0] != "") + { + buf = "-" + keysVector[0]; + if (keysVector[1] != "") buf += ", --" + keysVector[1]; + } + else if (keysVector[1] != "") buf += "--" + keysVector[1]; + if (del_space(it->second[0]) != "") buf += "=[" + del_space(it->second[0]) + "]"; + + cout << setw(col_p-2) << left << buf; + + if ((int)buf.length() > col_p-2) + { + cout << endl << " "; + cout << setw(col_p-2) << left << " "; + } + + buf = ""; + if (del_space(it->second[1]) != "") buf += del_space(it->second[1]); + + for(;;) + { + bool tr = ((int)buf.length() > col_d-2) ? true: false; + std::string::size_type pos = 0; + + if (tr) + { + pos = buf.find_first_of(' '); + for(;;) + { + if (buf.find_first_of(' ', pos + 1 ) < (std::string::size_type)(col_d-2) && + buf.find_first_of(' ', pos + 1 ) != std::string::npos) + pos = buf.find_first_of(' ', pos + 1); + else + break; + } + pos++; + cout << setw(col_d-2) << left << buf.substr(0, pos) << endl; + } + else + { + cout << setw(col_d-2) << left << buf<< endl; + break; + } + + buf.erase(0, pos); + cout << " "; + cout << setw(col_p-2) << left << " "; + } + } + } + +template<> +bool CommandLineParser::get(const std::string& name, bool space_delete) +{ + std::string str_buf = getString(name); + + if (space_delete && str_buf != "") + { + str_buf = del_space(str_buf); + } + + if (str_buf == "true") + return true; + + return false; +} +template<> +std::string CommandLineParser::analyzeValue(const std::string& str, bool space_delete) +{ + if (space_delete) + { + return del_space(str); + } + return str; +} + +template<> +int CommandLineParser::analyzeValue(const std::string& str, bool /*space_delete*/) +{ + return fromStringNumber(str); +} + +template<> +unsigned int CommandLineParser::analyzeValue(const std::string& str, bool /*space_delete*/) +{ + return fromStringNumber(str); +} + +template<> +uint64 CommandLineParser::analyzeValue(const std::string& str, bool /*space_delete*/) +{ + return fromStringNumber(str); +} + +template<> +float CommandLineParser::analyzeValue(const std::string& str, bool /*space_delete*/) +{ + return fromStringNumber(str); +} + +template<> +double CommandLineParser::analyzeValue(const std::string& str, bool /*space_delete*/) +{ + return fromStringNumber(str); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/convert.cpp diffimg-2.0.0/3rdparty/opencv/core/src/convert.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/convert.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/convert.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1374 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +/****************************************************************************************\ +* split & merge * +\****************************************************************************************/ + +template static void +split_( const T* src, T** dst, int len, int cn ) +{ + int k = cn % 4 ? cn % 4 : 4; + int i, j; + if( k == 1 ) + { + T* dst0 = dst[0]; + for( i = j = 0; i < len; i++, j += cn ) + dst0[i] = src[j]; + } + else if( k == 2 ) + { + T *dst0 = dst[0], *dst1 = dst[1]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst0[i] = src[j]; + dst1[i] = src[j+1]; + } + } + else if( k == 3 ) + { + T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst0[i] = src[j]; + dst1[i] = src[j+1]; + dst2[i] = src[j+2]; + } + } + else + { + T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2], *dst3 = dst[3]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst0[i] = src[j]; dst1[i] = src[j+1]; + dst2[i] = src[j+2]; dst3[i] = src[j+3]; + } + } + + for( ; k < cn; k += 4 ) + { + T *dst0 = dst[k], *dst1 = dst[k+1], *dst2 = dst[k+2], *dst3 = dst[k+3]; + for( i = 0, j = k; i < len; i++, j += cn ) + { + dst0[i] = src[j]; dst1[i] = src[j+1]; + dst2[i] = src[j+2]; dst3[i] = src[j+3]; + } + } +} + +template static void +merge_( const T** src, T* dst, int len, int cn ) +{ + int k = cn % 4 ? cn % 4 : 4; + int i, j; + if( k == 1 ) + { + const T* src0 = src[0]; + for( i = j = 0; i < len; i++, j += cn ) + dst[j] = src0[i]; + } + else if( k == 2 ) + { + const T *src0 = src[0], *src1 = src[1]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst[j] = src0[i]; + dst[j+1] = src1[i]; + } + } + else if( k == 3 ) + { + const T *src0 = src[0], *src1 = src[1], *src2 = src[2]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst[j] = src0[i]; + dst[j+1] = src1[i]; + dst[j+2] = src2[i]; + } + } + else + { + const T *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3]; + for( i = j = 0; i < len; i++, j += cn ) + { + dst[j] = src0[i]; dst[j+1] = src1[i]; + dst[j+2] = src2[i]; dst[j+3] = src3[i]; + } + } + + for( ; k < cn; k += 4 ) + { + const T *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3]; + for( i = 0, j = k; i < len; i++, j += cn ) + { + dst[j] = src0[i]; dst[j+1] = src1[i]; + dst[j+2] = src2[i]; dst[j+3] = src3[i]; + } + } +} + +static void split8u(const uchar* src, uchar** dst, int len, int cn ) +{ + split_(src, dst, len, cn); +} + +static void split16u(const ushort* src, ushort** dst, int len, int cn ) +{ + split_(src, dst, len, cn); +} + +static void split32s(const int* src, int** dst, int len, int cn ) +{ + split_(src, dst, len, cn); +} + +static void split64s(const int64* src, int64** dst, int len, int cn ) +{ + split_(src, dst, len, cn); +} + +static void merge8u(const uchar** src, uchar* dst, int len, int cn ) +{ + merge_(src, dst, len, cn); +} + +static void merge16u(const ushort** src, ushort* dst, int len, int cn ) +{ + merge_(src, dst, len, cn); +} + +static void merge32s(const int** src, int* dst, int len, int cn ) +{ + merge_(src, dst, len, cn); +} + +static void merge64s(const int64** src, int64* dst, int len, int cn ) +{ + merge_(src, dst, len, cn); +} + +typedef void (*SplitFunc)(const uchar* src, uchar** dst, int len, int cn); +typedef void (*MergeFunc)(const uchar** src, uchar* dst, int len, int cn); + +static SplitFunc splitTab[] = +{ + (SplitFunc)GET_OPTIMIZED(split8u), (SplitFunc)GET_OPTIMIZED(split8u), (SplitFunc)GET_OPTIMIZED(split16u), (SplitFunc)GET_OPTIMIZED(split16u), + (SplitFunc)GET_OPTIMIZED(split32s), (SplitFunc)GET_OPTIMIZED(split32s), (SplitFunc)GET_OPTIMIZED(split64s), 0 +}; + +static MergeFunc mergeTab[] = +{ + (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge16u), (MergeFunc)GET_OPTIMIZED(merge16u), + (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge64s), 0 +}; + +} + +void cv::split(const Mat& src, Mat* mv) +{ + int k, depth = src.depth(), cn = src.channels(); + if( cn == 1 ) + { + src.copyTo(mv[0]); + return; + } + + SplitFunc func = splitTab[depth]; + CV_Assert( func != 0 ); + + int esz = (int)src.elemSize(), esz1 = (int)src.elemSize1(); + int blocksize0 = (BLOCK_SIZE + esz-1)/esz; + AutoBuffer _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16); + const Mat** arrays = (const Mat**)(uchar*)_buf; + uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16); + + arrays[0] = &src; + for( k = 0; k < cn; k++ ) + { + mv[k].create(src.dims, src.size, depth); + arrays[k+1] = &mv[k]; + } + + NAryMatIterator it(arrays, ptrs, cn+1); + int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( int j = 0; j < total; j += blocksize ) + { + int bsz = std::min(total - j, blocksize); + func( ptrs[0], &ptrs[1], bsz, cn ); + + if( j + blocksize < total ) + { + ptrs[0] += bsz*esz; + for( k = 0; k < cn; k++ ) + ptrs[k+1] += bsz*esz1; + } + } + } +} + +void cv::split(InputArray _m, OutputArrayOfArrays _mv) +{ + Mat m = _m.getMat(); + if( m.empty() ) + { + _mv.release(); + return; + } + CV_Assert( !_mv.fixedType() || CV_MAT_TYPE(_mv.flags) == m.depth() ); + _mv.create(m.channels(), 1, m.depth()); + Mat* dst = &_mv.getMatRef(0); + split(m, dst); +} + +void cv::split(const Mat& src, vector& mv) +{ + split(_InputArray(src), _OutputArray(mv)); +} + +void cv::merge(const Mat* mv, size_t n, OutputArray _dst) +{ + CV_Assert( mv && n > 0 ); + + int depth = mv[0].depth(); + bool allch1 = true; + int k, cn = 0; + size_t i; + + for( i = 0; i < n; i++ ) + { + CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth); + allch1 = allch1 && mv[i].channels() == 1; + cn += mv[i].channels(); + } + + CV_Assert( 0 < cn && cn <= CV_CN_MAX ); + _dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn)); + Mat dst = _dst.getMat(); + + if( n == 1 ) + { + mv[0].copyTo(dst); + return; + } + + if( !allch1 ) + { + AutoBuffer pairs(cn*2); + int j, ni=0; + + for( i = 0, j = 0; i < n; i++, j += ni ) + { + ni = mv[i].channels(); + for( k = 0; k < ni; k++ ) + { + pairs[(j+k)*2] = j + k; + pairs[(j+k)*2+1] = j + k; + } + } + mixChannels( mv, n, &dst, 1, &pairs[0], cn ); + return; + } + + size_t esz = dst.elemSize(), esz1 = dst.elemSize1(); + int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz); + AutoBuffer _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16); + const Mat** arrays = (const Mat**)(uchar*)_buf; + uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16); + + arrays[0] = &dst; + for( k = 0; k < cn; k++ ) + arrays[k+1] = &mv[k]; + + NAryMatIterator it(arrays, ptrs, cn+1); + int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0); + MergeFunc func = mergeTab[depth]; + + for( i = 0; i < it.nplanes; i++, ++it ) + { + for( int j = 0; j < total; j += blocksize ) + { + int bsz = std::min(total - j, blocksize); + func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn ); + + if( j + blocksize < total ) + { + ptrs[0] += bsz*esz; + for( int t = 0; t < cn; t++ ) + ptrs[t+1] += bsz*esz1; + } + } + } +} + +void cv::merge(InputArrayOfArrays _mv, OutputArray _dst) +{ + vector mv; + _mv.getMatVector(mv); + merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst); +} + +void cv::merge(const vector& _mv, OutputArray _dst) +{ + merge(_InputArray(_mv), _dst); +} + +/****************************************************************************************\ +* Generalized split/merge: mixing channels * +\****************************************************************************************/ + +namespace cv +{ + +template static void +mixChannels_( const T** src, const int* sdelta, + T** dst, const int* ddelta, + int len, int npairs ) +{ + int i, k; + for( k = 0; k < npairs; k++ ) + { + const T* s = src[k]; + T* d = dst[k]; + int ds = sdelta[k], dd = ddelta[k]; + if( s ) + { + for( i = 0; i <= len - 2; i += 2, s += ds*2, d += dd*2 ) + { + T t0 = s[0], t1 = s[ds]; + d[0] = t0; d[dd] = t1; + } + if( i < len ) + d[0] = s[0]; + } + else + { + for( i = 0; i <= len - 2; i += 2, d += dd*2 ) + d[0] = d[dd] = 0; + if( i < len ) + d[0] = 0; + } + } +} + + +static void mixChannels8u( const uchar** src, const int* sdelta, + uchar** dst, const int* ddelta, + int len, int npairs ) +{ + mixChannels_(src, sdelta, dst, ddelta, len, npairs); +} + +static void mixChannels16u( const ushort** src, const int* sdelta, + ushort** dst, const int* ddelta, + int len, int npairs ) +{ + mixChannels_(src, sdelta, dst, ddelta, len, npairs); +} + +static void mixChannels32s( const int** src, const int* sdelta, + int** dst, const int* ddelta, + int len, int npairs ) +{ + mixChannels_(src, sdelta, dst, ddelta, len, npairs); +} + +static void mixChannels64s( const int64** src, const int* sdelta, + int64** dst, const int* ddelta, + int len, int npairs ) +{ + mixChannels_(src, sdelta, dst, ddelta, len, npairs); +} + +typedef void (*MixChannelsFunc)( const uchar** src, const int* sdelta, + uchar** dst, const int* ddelta, int len, int npairs ); + +static MixChannelsFunc mixchTab[] = +{ + (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels16u, + (MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels32s, + (MixChannelsFunc)mixChannels64s, 0 +}; + +} + +void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs ) +{ + if( npairs == 0 ) + return; + CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 ); + + size_t i, j, k, esz1 = dst[0].elemSize1(); + int depth = dst[0].depth(); + + AutoBuffer buf((nsrcs + ndsts + 1)*(sizeof(Mat*) + sizeof(uchar*)) + npairs*(sizeof(uchar*)*2 + sizeof(int)*6)); + const Mat** arrays = (const Mat**)(uchar*)buf; + uchar** ptrs = (uchar**)(arrays + nsrcs + ndsts); + const uchar** srcs = (const uchar**)(ptrs + nsrcs + ndsts + 1); + uchar** dsts = (uchar**)(srcs + npairs); + int* tab = (int*)(dsts + npairs); + int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs; + + for( i = 0; i < nsrcs; i++ ) + arrays[i] = &src[i]; + for( i = 0; i < ndsts; i++ ) + arrays[i + nsrcs] = &dst[i]; + ptrs[nsrcs + ndsts] = 0; + + for( i = 0; i < npairs; i++ ) + { + int i0 = fromTo[i*2], i1 = fromTo[i*2+1]; + if( i0 >= 0 ) + { + for( j = 0; j < nsrcs; i0 -= src[j].channels(), j++ ) + if( i0 < src[j].channels() ) + break; + CV_Assert(j < nsrcs && src[j].depth() == depth); + tab[i*4] = (int)j; tab[i*4+1] = (int)(i0*esz1); + sdelta[i] = src[j].channels(); + } + else + { + tab[i*4] = (int)(nsrcs + ndsts); tab[i*4+1] = 0; + sdelta[i] = 0; + } + + for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ ) + if( i1 < dst[j].channels() ) + break; + CV_Assert(i1 >= 0 && j < ndsts && dst[j].depth() == depth); + tab[i*4+2] = (int)(j + nsrcs); tab[i*4+3] = (int)(i1*esz1); + ddelta[i] = dst[j].channels(); + } + + NAryMatIterator it(arrays, ptrs, (int)(nsrcs + ndsts)); + int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1)); + MixChannelsFunc func = mixchTab[depth]; + + for( i = 0; i < it.nplanes; i++, ++it ) + { + for( k = 0; k < npairs; k++ ) + { + srcs[k] = ptrs[tab[k*4]] + tab[k*4+1]; + dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3]; + } + + for( int t = 0; t < total; t += blocksize ) + { + int bsz = std::min(total - t, blocksize); + func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs ); + + if( t + blocksize < total ) + for( k = 0; k < npairs; k++ ) + { + srcs[k] += blocksize*sdelta[k]*esz1; + dsts[k] += blocksize*ddelta[k]*esz1; + } + } + } +} + + +void cv::mixChannels(const vector& src, vector& dst, + const int* fromTo, size_t npairs) +{ + mixChannels(!src.empty() ? &src[0] : 0, src.size(), + !dst.empty() ? &dst[0] : 0, dst.size(), fromTo, npairs); +} + +void cv::mixChannels(InputArrayOfArrays src, InputArrayOfArrays dst, + const vector& fromTo) +{ + if(fromTo.empty()) + return; + bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT && + src.kind() != _InputArray::STD_VECTOR_VECTOR; + bool dst_is_mat = dst.kind() != _InputArray::STD_VECTOR_MAT && + dst.kind() != _InputArray::STD_VECTOR_VECTOR; + int i; + int nsrc = src_is_mat ? 1 : (int)src.total(); + int ndst = dst_is_mat ? 1 : (int)dst.total(); + + CV_Assert(fromTo.size()%2 == 0 && nsrc > 0 && ndst > 0); + cv::AutoBuffer _buf(nsrc + ndst); + Mat* buf = _buf; + for( i = 0; i < nsrc; i++ ) + buf[i] = src.getMat(src_is_mat ? -1 : i); + for( i = 0; i < ndst; i++ ) + buf[nsrc + i] = dst.getMat(dst_is_mat ? -1 : i); + mixChannels(&buf[0], nsrc, &buf[nsrc], ndst, &fromTo[0], fromTo.size()/2); +} + +void cv::extractChannel(InputArray _src, OutputArray _dst, int coi) +{ + Mat src = _src.getMat(); + CV_Assert( 0 <= coi && coi < src.channels() ); + _dst.create(src.dims, &src.size[0], src.depth()); + Mat dst = _dst.getMat(); + int ch[] = { coi, 0 }; + mixChannels(&src, 1, &dst, 1, ch, 1); +} + +void cv::insertChannel(InputArray _src, InputOutputArray _dst, int coi) +{ + Mat src = _src.getMat(), dst = _dst.getMat(); + CV_Assert( src.size == dst.size && src.depth() == dst.depth() ); + CV_Assert( 0 <= coi && coi < dst.channels() && src.channels() == 1 ); + int ch[] = { 0, coi }; + mixChannels(&src, 1, &dst, 1, ch, 1); +} + +/****************************************************************************************\ +* convertScale[Abs] * +\****************************************************************************************/ + +namespace cv +{ + +template static void +cvtScaleAbs_( const T* src, size_t sstep, + DT* dst, size_t dstep, Size size, + WT scale, WT shift ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + DT t0, t1; + t0 = saturate_cast
(std::abs(src[x]*scale + shift)); + t1 = saturate_cast
(std::abs(src[x+1]*scale + shift)); + dst[x] = t0; dst[x+1] = t1; + t0 = saturate_cast
(std::abs(src[x+2]*scale + shift)); + t1 = saturate_cast
(std::abs(src[x+3]*scale + shift)); + dst[x+2] = t0; dst[x+3] = t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = saturate_cast
(std::abs(src[x]*scale + shift)); + } +} + + +template static void +cvtScale_( const T* src, size_t sstep, + DT* dst, size_t dstep, Size size, + WT scale, WT shift ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + DT t0, t1; + t0 = saturate_cast
(src[x]*scale + shift); + t1 = saturate_cast
(src[x+1]*scale + shift); + dst[x] = t0; dst[x+1] = t1; + t0 = saturate_cast
(src[x+2]*scale + shift); + t1 = saturate_cast
(src[x+3]*scale + shift); + dst[x+2] = t0; dst[x+3] = t1; + } + #endif + + for( ; x < size.width; x++ ) + dst[x] = saturate_cast
(src[x]*scale + shift); + } +} + +//vz optimized template specialization +template<> void +cvtScale_( const short* src, size_t sstep, + short* dst, size_t dstep, Size size, + float scale, float shift ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + #if CV_SSE2 + if(USE_SSE2) + { + __m128 scale128 = _mm_set1_ps (scale); + __m128 shift128 = _mm_set1_ps (shift); + for(; x <= size.width - 8; x += 8 ) + { + __m128i r0 = _mm_loadl_epi64((const __m128i*)(src + x)); + __m128i r1 = _mm_loadl_epi64((const __m128i*)(src + x + 4)); + __m128 rf0 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r0, r0), 16)); + __m128 rf1 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r1, r1), 16)); + rf0 = _mm_add_ps(_mm_mul_ps(rf0, scale128), shift128); + rf1 = _mm_add_ps(_mm_mul_ps(rf1, scale128), shift128); + r0 = _mm_cvtps_epi32(rf0); + r1 = _mm_cvtps_epi32(rf1); + r0 = _mm_packs_epi32(r0, r1); + _mm_storeu_si128((__m128i*)(dst + x), r0); + } + } + #endif + + for(; x < size.width; x++ ) + dst[x] = saturate_cast(src[x]*scale + shift); + } +} + +template<> void +cvtScale_( const short* src, size_t sstep, + int* dst, size_t dstep, Size size, + float scale, float shift ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + + #if CV_SSE2 + if(USE_SSE2)//~5X + { + __m128 scale128 = _mm_set1_ps (scale); + __m128 shift128 = _mm_set1_ps (shift); + for(; x <= size.width - 8; x += 8 ) + { + __m128i r0 = _mm_loadl_epi64((const __m128i*)(src + x)); + __m128i r1 = _mm_loadl_epi64((const __m128i*)(src + x + 4)); + __m128 rf0 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r0, r0), 16)); + __m128 rf1 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r1, r1), 16)); + rf0 = _mm_add_ps(_mm_mul_ps(rf0, scale128), shift128); + rf1 = _mm_add_ps(_mm_mul_ps(rf1, scale128), shift128); + r0 = _mm_cvtps_epi32(rf0); + r1 = _mm_cvtps_epi32(rf1); + + _mm_storeu_si128((__m128i*)(dst + x), r0); + _mm_storeu_si128((__m128i*)(dst + x + 4), r1); + } + } + #endif + + //We will wait Haswell + /* + #if CV_AVX + if(USE_AVX)//2X - bad variant + { + ////TODO:AVX implementation (optimization?) required + __m256 scale256 = _mm256_set1_ps (scale); + __m256 shift256 = _mm256_set1_ps (shift); + for(; x <= size.width - 8; x += 8 ) + { + __m256i buf = _mm256_set_epi32((int)(*(src+x+7)),(int)(*(src+x+6)),(int)(*(src+x+5)),(int)(*(src+x+4)),(int)(*(src+x+3)),(int)(*(src+x+2)),(int)(*(src+x+1)),(int)(*(src+x))); + __m256 r0 = _mm256_add_ps( _mm256_mul_ps(_mm256_cvtepi32_ps (buf), scale256), shift256); + __m256i res = _mm256_cvtps_epi32(r0); + _mm256_storeu_si256 ((__m256i*)(dst+x), res); + } + } + #endif*/ + + for(; x < size.width; x++ ) + dst[x] = saturate_cast(src[x]*scale + shift); + } +} + +template static void +cvt_( const T* src, size_t sstep, + DT* dst, size_t dstep, Size size ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + DT t0, t1; + t0 = saturate_cast
(src[x]); + t1 = saturate_cast
(src[x+1]); + dst[x] = t0; dst[x+1] = t1; + t0 = saturate_cast
(src[x+2]); + t1 = saturate_cast
(src[x+3]); + dst[x+2] = t0; dst[x+3] = t1; + } + #endif + for( ; x < size.width; x++ ) + dst[x] = saturate_cast
(src[x]); + } +} + +//vz optimized template specialization, test Core_ConvertScale/ElemWiseTest +template<> void +cvt_( const float* src, size_t sstep, + short* dst, size_t dstep, Size size ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + { + int x = 0; + #if CV_SSE2 + if(USE_SSE2){ + for( ; x <= size.width - 8; x += 8 ) + { + __m128 src128 = _mm_loadu_ps (src + x); + __m128i src_int128 = _mm_cvtps_epi32 (src128); + + src128 = _mm_loadu_ps (src + x + 4); + __m128i src1_int128 = _mm_cvtps_epi32 (src128); + + src1_int128 = _mm_packs_epi32(src_int128, src1_int128); + _mm_storeu_si128((__m128i*)(dst + x),src1_int128); + } + } + #endif + for( ; x < size.width; x++ ) + dst[x] = saturate_cast(src[x]); + } + +} + + +template static void +cpy_( const T* src, size_t sstep, T* dst, size_t dstep, Size size ) +{ + sstep /= sizeof(src[0]); + dstep /= sizeof(dst[0]); + + for( ; size.height--; src += sstep, dst += dstep ) + memcpy(dst, src, size.width*sizeof(src[0])); +} + +#define DEF_CVT_SCALE_ABS_FUNC(suffix, tfunc, stype, dtype, wtype) \ +static void cvtScaleAbs##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ + dtype* dst, size_t dstep, Size size, double* scale) \ +{ \ + tfunc(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \ +} + +#define DEF_CVT_SCALE_FUNC(suffix, stype, dtype, wtype) \ +static void cvtScale##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ +dtype* dst, size_t dstep, Size size, double* scale) \ +{ \ + cvtScale_(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \ +} + + +#define DEF_CVT_FUNC(suffix, stype, dtype) \ +static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ + dtype* dst, size_t dstep, Size size, double*) \ +{ \ + cvt_(src, sstep, dst, dstep, size); \ +} + +#define DEF_CPY_FUNC(suffix, stype) \ +static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ +stype* dst, size_t dstep, Size size, double*) \ +{ \ + cpy_(src, sstep, dst, dstep, size); \ +} + + +DEF_CVT_SCALE_ABS_FUNC(8u, cvtScaleAbs_, uchar, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(8s8u, cvtScaleAbs_, schar, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(16u8u, cvtScaleAbs_, ushort, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(16s8u, cvtScaleAbs_, short, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(32s8u, cvtScaleAbs_, int, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(32f8u, cvtScaleAbs_, float, uchar, float); +DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float); + +DEF_CVT_SCALE_FUNC(8u, uchar, uchar, float); +DEF_CVT_SCALE_FUNC(8s8u, schar, uchar, float); +DEF_CVT_SCALE_FUNC(16u8u, ushort, uchar, float); +DEF_CVT_SCALE_FUNC(16s8u, short, uchar, float); +DEF_CVT_SCALE_FUNC(32s8u, int, uchar, float); +DEF_CVT_SCALE_FUNC(32f8u, float, uchar, float); +DEF_CVT_SCALE_FUNC(64f8u, double, uchar, float); + +DEF_CVT_SCALE_FUNC(8u8s, uchar, schar, float); +DEF_CVT_SCALE_FUNC(8s, schar, schar, float); +DEF_CVT_SCALE_FUNC(16u8s, ushort, schar, float); +DEF_CVT_SCALE_FUNC(16s8s, short, schar, float); +DEF_CVT_SCALE_FUNC(32s8s, int, schar, float); +DEF_CVT_SCALE_FUNC(32f8s, float, schar, float); +DEF_CVT_SCALE_FUNC(64f8s, double, schar, float); + +DEF_CVT_SCALE_FUNC(8u16u, uchar, ushort, float); +DEF_CVT_SCALE_FUNC(8s16u, schar, ushort, float); +DEF_CVT_SCALE_FUNC(16u, ushort, ushort, float); +DEF_CVT_SCALE_FUNC(16s16u, short, ushort, float); +DEF_CVT_SCALE_FUNC(32s16u, int, ushort, float); +DEF_CVT_SCALE_FUNC(32f16u, float, ushort, float); +DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float); + +DEF_CVT_SCALE_FUNC(8u16s, uchar, short, float); +DEF_CVT_SCALE_FUNC(8s16s, schar, short, float); +DEF_CVT_SCALE_FUNC(16u16s, ushort, short, float); +DEF_CVT_SCALE_FUNC(16s, short, short, float); +DEF_CVT_SCALE_FUNC(32s16s, int, short, float); +DEF_CVT_SCALE_FUNC(32f16s, float, short, float); +DEF_CVT_SCALE_FUNC(64f16s, double, short, float); + +DEF_CVT_SCALE_FUNC(8u32s, uchar, int, float); +DEF_CVT_SCALE_FUNC(8s32s, schar, int, float); +DEF_CVT_SCALE_FUNC(16u32s, ushort, int, float); +DEF_CVT_SCALE_FUNC(16s32s, short, int, float); +DEF_CVT_SCALE_FUNC(32s, int, int, double); +DEF_CVT_SCALE_FUNC(32f32s, float, int, float); +DEF_CVT_SCALE_FUNC(64f32s, double, int, double); + +DEF_CVT_SCALE_FUNC(8u32f, uchar, float, float); +DEF_CVT_SCALE_FUNC(8s32f, schar, float, float); +DEF_CVT_SCALE_FUNC(16u32f, ushort, float, float); +DEF_CVT_SCALE_FUNC(16s32f, short, float, float); +DEF_CVT_SCALE_FUNC(32s32f, int, float, double); +DEF_CVT_SCALE_FUNC(32f, float, float, float); +DEF_CVT_SCALE_FUNC(64f32f, double, float, double); + +DEF_CVT_SCALE_FUNC(8u64f, uchar, double, double); +DEF_CVT_SCALE_FUNC(8s64f, schar, double, double); +DEF_CVT_SCALE_FUNC(16u64f, ushort, double, double); +DEF_CVT_SCALE_FUNC(16s64f, short, double, double); +DEF_CVT_SCALE_FUNC(32s64f, int, double, double); +DEF_CVT_SCALE_FUNC(32f64f, float, double, double); +DEF_CVT_SCALE_FUNC(64f, double, double, double); + +DEF_CPY_FUNC(8u, uchar); +DEF_CVT_FUNC(8s8u, schar, uchar); +DEF_CVT_FUNC(16u8u, ushort, uchar); +DEF_CVT_FUNC(16s8u, short, uchar); +DEF_CVT_FUNC(32s8u, int, uchar); +DEF_CVT_FUNC(32f8u, float, uchar); +DEF_CVT_FUNC(64f8u, double, uchar); + +DEF_CVT_FUNC(8u8s, uchar, schar); +DEF_CVT_FUNC(16u8s, ushort, schar); +DEF_CVT_FUNC(16s8s, short, schar); +DEF_CVT_FUNC(32s8s, int, schar); +DEF_CVT_FUNC(32f8s, float, schar); +DEF_CVT_FUNC(64f8s, double, schar); + +DEF_CVT_FUNC(8u16u, uchar, ushort); +DEF_CVT_FUNC(8s16u, schar, ushort); +DEF_CPY_FUNC(16u, ushort); +DEF_CVT_FUNC(16s16u, short, ushort); +DEF_CVT_FUNC(32s16u, int, ushort); +DEF_CVT_FUNC(32f16u, float, ushort); +DEF_CVT_FUNC(64f16u, double, ushort); + +DEF_CVT_FUNC(8u16s, uchar, short); +DEF_CVT_FUNC(8s16s, schar, short); +DEF_CVT_FUNC(16u16s, ushort, short); +DEF_CVT_FUNC(32s16s, int, short); +DEF_CVT_FUNC(32f16s, float, short); +DEF_CVT_FUNC(64f16s, double, short); + +DEF_CVT_FUNC(8u32s, uchar, int); +DEF_CVT_FUNC(8s32s, schar, int); +DEF_CVT_FUNC(16u32s, ushort, int); +DEF_CVT_FUNC(16s32s, short, int); +DEF_CPY_FUNC(32s, int); +DEF_CVT_FUNC(32f32s, float, int); +DEF_CVT_FUNC(64f32s, double, int); + +DEF_CVT_FUNC(8u32f, uchar, float); +DEF_CVT_FUNC(8s32f, schar, float); +DEF_CVT_FUNC(16u32f, ushort, float); +DEF_CVT_FUNC(16s32f, short, float); +DEF_CVT_FUNC(32s32f, int, float); +DEF_CVT_FUNC(64f32f, double, float); + +DEF_CVT_FUNC(8u64f, uchar, double); +DEF_CVT_FUNC(8s64f, schar, double); +DEF_CVT_FUNC(16u64f, ushort, double); +DEF_CVT_FUNC(16s64f, short, double); +DEF_CVT_FUNC(32s64f, int, double); +DEF_CVT_FUNC(32f64f, float, double); +DEF_CPY_FUNC(64s, int64); + +static BinaryFunc cvtScaleAbsTab[] = +{ + (BinaryFunc)cvtScaleAbs8u, (BinaryFunc)cvtScaleAbs8s8u, (BinaryFunc)cvtScaleAbs16u8u, + (BinaryFunc)cvtScaleAbs16s8u, (BinaryFunc)cvtScaleAbs32s8u, (BinaryFunc)cvtScaleAbs32f8u, + (BinaryFunc)cvtScaleAbs64f8u, 0 +}; + +static BinaryFunc cvtScaleTab[][8] = +{ + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u), (BinaryFunc)GET_OPTIMIZED(cvtScale8s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale16u8u), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale32s8u), (BinaryFunc)GET_OPTIMIZED(cvtScale32f8u), + (BinaryFunc)cvtScale64f8u, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u8s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u8s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s8s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s8s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f8s), + (BinaryFunc)cvtScale64f8s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u16u), (BinaryFunc)GET_OPTIMIZED(cvtScale8s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale16u), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale32s16u), (BinaryFunc)GET_OPTIMIZED(cvtScale32f16u), + (BinaryFunc)cvtScale64f16u, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u16s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s16s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u16s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s16s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f16s), + (BinaryFunc)cvtScale64f16s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u32s), (BinaryFunc)GET_OPTIMIZED(cvtScale8s32s), (BinaryFunc)GET_OPTIMIZED(cvtScale16u32s), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s32s), (BinaryFunc)GET_OPTIMIZED(cvtScale32s), (BinaryFunc)GET_OPTIMIZED(cvtScale32f32s), + (BinaryFunc)cvtScale64f32s, 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvtScale8u32f), (BinaryFunc)GET_OPTIMIZED(cvtScale8s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale16u32f), + (BinaryFunc)GET_OPTIMIZED(cvtScale16s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale32s32f), (BinaryFunc)GET_OPTIMIZED(cvtScale32f), + (BinaryFunc)cvtScale64f32f, 0 + }, + { + (BinaryFunc)cvtScale8u64f, (BinaryFunc)cvtScale8s64f, (BinaryFunc)cvtScale16u64f, + (BinaryFunc)cvtScale16s64f, (BinaryFunc)cvtScale32s64f, (BinaryFunc)cvtScale32f64f, + (BinaryFunc)cvtScale64f, 0 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +static BinaryFunc cvtTab[][8] = +{ + { + (BinaryFunc)(cvt8u), (BinaryFunc)GET_OPTIMIZED(cvt8s8u), (BinaryFunc)GET_OPTIMIZED(cvt16u8u), + (BinaryFunc)GET_OPTIMIZED(cvt16s8u), (BinaryFunc)GET_OPTIMIZED(cvt32s8u), (BinaryFunc)GET_OPTIMIZED(cvt32f8u), + (BinaryFunc)GET_OPTIMIZED(cvt64f8u), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u8s), (BinaryFunc)cvt8u, (BinaryFunc)GET_OPTIMIZED(cvt16u8s), + (BinaryFunc)GET_OPTIMIZED(cvt16s8s), (BinaryFunc)GET_OPTIMIZED(cvt32s8s), (BinaryFunc)GET_OPTIMIZED(cvt32f8s), + (BinaryFunc)GET_OPTIMIZED(cvt64f8s), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u16u), (BinaryFunc)GET_OPTIMIZED(cvt8s16u), (BinaryFunc)cvt16u, + (BinaryFunc)GET_OPTIMIZED(cvt16s16u), (BinaryFunc)GET_OPTIMIZED(cvt32s16u), (BinaryFunc)GET_OPTIMIZED(cvt32f16u), + (BinaryFunc)GET_OPTIMIZED(cvt64f16u), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u16s), (BinaryFunc)GET_OPTIMIZED(cvt8s16s), (BinaryFunc)GET_OPTIMIZED(cvt16u16s), + (BinaryFunc)cvt16u, (BinaryFunc)GET_OPTIMIZED(cvt32s16s), (BinaryFunc)GET_OPTIMIZED(cvt32f16s), + (BinaryFunc)GET_OPTIMIZED(cvt64f16s), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u32s), (BinaryFunc)GET_OPTIMIZED(cvt8s32s), (BinaryFunc)GET_OPTIMIZED(cvt16u32s), + (BinaryFunc)GET_OPTIMIZED(cvt16s32s), (BinaryFunc)cvt32s, (BinaryFunc)GET_OPTIMIZED(cvt32f32s), + (BinaryFunc)GET_OPTIMIZED(cvt64f32s), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u32f), (BinaryFunc)GET_OPTIMIZED(cvt8s32f), (BinaryFunc)GET_OPTIMIZED(cvt16u32f), + (BinaryFunc)GET_OPTIMIZED(cvt16s32f), (BinaryFunc)GET_OPTIMIZED(cvt32s32f), (BinaryFunc)cvt32s, + (BinaryFunc)GET_OPTIMIZED(cvt64f32f), 0 + }, + { + (BinaryFunc)GET_OPTIMIZED(cvt8u64f), (BinaryFunc)GET_OPTIMIZED(cvt8s64f), (BinaryFunc)GET_OPTIMIZED(cvt16u64f), + (BinaryFunc)GET_OPTIMIZED(cvt16s64f), (BinaryFunc)GET_OPTIMIZED(cvt32s64f), (BinaryFunc)GET_OPTIMIZED(cvt32f64f), + (BinaryFunc)(cvt64s), 0 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +BinaryFunc getConvertFunc(int sdepth, int ddepth) +{ + return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; +} + +BinaryFunc getConvertScaleFunc(int sdepth, int ddepth) +{ + return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; +} + +} + +void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, double beta ) +{ + Mat src = _src.getMat(); + int cn = src.channels(); + double scale[] = {alpha, beta}; + _dst.create( src.dims, src.size, CV_8UC(cn) ); + Mat dst = _dst.getMat(); + BinaryFunc func = cvtScaleAbsTab[src.depth()]; + CV_Assert( func != 0 ); + + if( src.dims <= 2 ) + { + Size sz = getContinuousSize(src, dst, cn); + func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale ); + } + else + { + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + Size sz((int)it.size*cn, 1); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale ); + } +} + +void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) const +{ + bool noScale = fabs(alpha-1) < DBL_EPSILON && fabs(beta) < DBL_EPSILON; + + if( _type < 0 ) + _type = _dst.fixedType() ? _dst.type() : type(); + else + _type = CV_MAKETYPE(CV_MAT_DEPTH(_type), channels()); + + int sdepth = depth(), ddepth = CV_MAT_DEPTH(_type); + if( sdepth == ddepth && noScale ) + { + copyTo(_dst); + return; + } + + Mat src = *this; + + BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); + double scale[] = {alpha, beta}; + int cn = channels(); + CV_Assert( func != 0 ); + + if( dims <= 2 ) + { + _dst.create( size(), _type ); + Mat dst = _dst.getMat(); + Size sz = getContinuousSize(src, dst, cn); + func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale ); + } + else + { + _dst.create( dims, size, _type ); + Mat dst = _dst.getMat(); + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + Size sz((int)(it.size*cn), 1); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale); + } +} + +/****************************************************************************************\ +* LUT Transform * +\****************************************************************************************/ + +namespace cv +{ + +template static void +LUT8u_( const uchar* src, const T* lut, T* dst, int len, int cn, int lutcn ) +{ + if( lutcn == 1 ) + { + for( int i = 0; i < len*cn; i++ ) + dst[i] = lut[src[i]]; + } + else + { + for( int i = 0; i < len*cn; i += cn ) + for( int k = 0; k < cn; k++ ) + dst[i+k] = lut[src[i+k]*cn+k]; + } +} + +static void LUT8u_8u( const uchar* src, const uchar* lut, uchar* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_8s( const uchar* src, const schar* lut, schar* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_16u( const uchar* src, const ushort* lut, ushort* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_16s( const uchar* src, const short* lut, short* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_32s( const uchar* src, const int* lut, int* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_32f( const uchar* src, const float* lut, float* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +static void LUT8u_64f( const uchar* src, const double* lut, double* dst, int len, int cn, int lutcn ) +{ + LUT8u_( src, lut, dst, len, cn, lutcn ); +} + +typedef void (*LUTFunc)( const uchar* src, const uchar* lut, uchar* dst, int len, int cn, int lutcn ); + +static LUTFunc lutTab[] = +{ + (LUTFunc)LUT8u_8u, (LUTFunc)LUT8u_8s, (LUTFunc)LUT8u_16u, (LUTFunc)LUT8u_16s, + (LUTFunc)LUT8u_32s, (LUTFunc)LUT8u_32f, (LUTFunc)LUT8u_64f, 0 +}; + +} + +void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst, int interpolation ) +{ + Mat src = _src.getMat(), lut = _lut.getMat(); + CV_Assert( interpolation == 0 ); + int cn = src.channels(); + int lutcn = lut.channels(); + + CV_Assert( (lutcn == cn || lutcn == 1) && + lut.total() == 256 && lut.isContinuous() && + (src.depth() == CV_8U || src.depth() == CV_8S) ); + _dst.create( src.dims, src.size, CV_MAKETYPE(lut.depth(), cn)); + Mat dst = _dst.getMat(); + + LUTFunc func = lutTab[lut.depth()]; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], lut.data, ptrs[1], len, cn, lutcn); +} + + +void cv::normalize( InputArray _src, OutputArray _dst, double a, double b, + int norm_type, int rtype, InputArray _mask ) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + + double scale = 1, shift = 0; + if( norm_type == CV_MINMAX ) + { + double smin = 0, smax = 0; + double dmin = MIN( a, b ), dmax = MAX( a, b ); + minMaxLoc( _src, &smin, &smax, 0, 0, mask ); + scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0); + shift = dmin - smin*scale; + } + else if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C ) + { + scale = norm( src, norm_type, mask ); + scale = scale > DBL_EPSILON ? a/scale : 0.; + shift = 0; + } + else + CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + + if( rtype < 0 ) + rtype = _dst.fixedType() ? _dst.depth() : src.depth(); + + _dst.create(src.dims, src.size, CV_MAKETYPE(rtype, src.channels())); + Mat dst = _dst.getMat(); + + if( !mask.data ) + src.convertTo( dst, rtype, scale, shift ); + else + { + Mat temp; + src.convertTo( temp, rtype, scale, shift ); + temp.copyTo( dst, mask ); + } +} + +CV_IMPL void +cvSplit( const void* srcarr, void* dstarr0, void* dstarr1, void* dstarr2, void* dstarr3 ) +{ + void* dptrs[] = { dstarr0, dstarr1, dstarr2, dstarr3 }; + cv::Mat src = cv::cvarrToMat(srcarr); + int i, j, nz = 0; + for( i = 0; i < 4; i++ ) + nz += dptrs[i] != 0; + CV_Assert( nz > 0 ); + cv::vector dvec(nz); + cv::vector pairs(nz*2); + + for( i = j = 0; i < 4; i++ ) + { + if( dptrs[i] != 0 ) + { + dvec[j] = cv::cvarrToMat(dptrs[i]); + CV_Assert( dvec[j].size() == src.size() ); + CV_Assert( dvec[j].depth() == src.depth() ); + CV_Assert( dvec[j].channels() == 1 ); + CV_Assert( i < src.channels() ); + pairs[j*2] = i; + pairs[j*2+1] = j; + j++; + } + } + if( nz == src.channels() ) + cv::split( src, dvec ); + else + { + cv::mixChannels( &src, 1, &dvec[0], nz, &pairs[0], nz ); + } +} + + +CV_IMPL void +cvMerge( const void* srcarr0, const void* srcarr1, const void* srcarr2, + const void* srcarr3, void* dstarr ) +{ + const void* sptrs[] = { srcarr0, srcarr1, srcarr2, srcarr3 }; + cv::Mat dst = cv::cvarrToMat(dstarr); + int i, j, nz = 0; + for( i = 0; i < 4; i++ ) + nz += sptrs[i] != 0; + CV_Assert( nz > 0 ); + cv::vector svec(nz); + cv::vector pairs(nz*2); + + for( i = j = 0; i < 4; i++ ) + { + if( sptrs[i] != 0 ) + { + svec[j] = cv::cvarrToMat(sptrs[i]); + CV_Assert( svec[j].size == dst.size && + svec[j].depth() == dst.depth() && + svec[j].channels() == 1 && i < dst.channels() ); + pairs[j*2] = j; + pairs[j*2+1] = i; + j++; + } + } + + if( nz == dst.channels() ) + cv::merge( svec, dst ); + else + { + cv::mixChannels( &svec[0], nz, &dst, 1, &pairs[0], nz ); + } +} + + +CV_IMPL void +cvMixChannels( const CvArr** src, int src_count, + CvArr** dst, int dst_count, + const int* from_to, int pair_count ) +{ + cv::AutoBuffer buf(src_count + dst_count); + + int i; + for( i = 0; i < src_count; i++ ) + buf[i] = cv::cvarrToMat(src[i]); + for( i = 0; i < dst_count; i++ ) + buf[i+src_count] = cv::cvarrToMat(dst[i]); + cv::mixChannels(&buf[0], src_count, &buf[src_count], dst_count, from_to, pair_count); +} + +CV_IMPL void +cvConvertScaleAbs( const void* srcarr, void* dstarr, + double scale, double shift ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.size == dst.size && dst.type() == CV_8UC(src.channels())); + cv::convertScaleAbs( src, dst, scale, shift ); +} + +CV_IMPL void +cvConvertScale( const void* srcarr, void* dstarr, + double scale, double shift ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size == dst.size && src.channels() == dst.channels() ); + src.convertTo(dst, dst.type(), scale, shift); +} + +CV_IMPL void cvLUT( const void* srcarr, void* dstarr, const void* lutarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), lut = cv::cvarrToMat(lutarr); + + CV_Assert( dst.size() == src.size() && dst.type() == CV_MAKETYPE(lut.depth(), src.channels()) ); + cv::LUT( src, lut, dst ); +} + +CV_IMPL void cvNormalize( const CvArr* srcarr, CvArr* dstarr, + double a, double b, int norm_type, const CvArr* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + CV_Assert( dst.size() == src.size() && src.channels() == dst.channels() ); + cv::normalize( src, dst, a, b, norm_type, dst.type(), mask ); +} + +/* End of file. */ \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/copy.cpp diffimg-2.0.0/3rdparty/opencv/core/src/copy.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/copy.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/copy.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,632 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Mat basic operations: Copy, Set +// +// */ + +#include "precomp.hpp" + +namespace cv +{ + +template static void +copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size) +{ + for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep ) + { + const T* src = (const T*)_src; + T* dst = (T*)_dst; + int x = 0; + #if CV_ENABLE_UNROLLED + for( ; x <= size.width - 4; x += 4 ) + { + if( mask[x] ) + dst[x] = src[x]; + if( mask[x+1] ) + dst[x+1] = src[x+1]; + if( mask[x+2] ) + dst[x+2] = src[x+2]; + if( mask[x+3] ) + dst[x+3] = src[x+3]; + } + #endif + for( ; x < size.width; x++ ) + if( mask[x] ) + dst[x] = src[x]; + } +} + +template<> void +copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size) +{ + for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep ) + { + const uchar* src = (const uchar*)_src; + uchar* dst = (uchar*)_dst; + int x = 0; + #if CV_SSE4_2 + if(USE_SSE4_2)// + { + __m128i zero = _mm_setzero_si128 (); + + for( ; x <= size.width - 16; x += 16 ) + { + const __m128i rSrc = _mm_lddqu_si128((const __m128i*)(src+x)); + __m128i _mask = _mm_lddqu_si128((const __m128i*)(mask+x)); + __m128i rDst = _mm_lddqu_si128((__m128i*)(dst+x)); + __m128i _negMask = _mm_cmpeq_epi8(_mask, zero); + rDst = _mm_blendv_epi8(rSrc, rDst, _negMask); + _mm_storeu_si128((__m128i*)(dst + x), rDst); + } + } + #endif + for( ; x < size.width; x++ ) + if( mask[x] ) + dst[x] = src[x]; + } +} + +template<> void +copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size) +{ + for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep ) + { + const ushort* src = (const ushort*)_src; + ushort* dst = (ushort*)_dst; + int x = 0; + #if CV_SSE4_2 + if(USE_SSE4_2)// + { + __m128i zero = _mm_setzero_si128 (); + for( ; x <= size.width - 8; x += 8 ) + { + const __m128i rSrc =_mm_lddqu_si128((const __m128i*)(src+x)); + __m128i _mask = _mm_loadl_epi64((const __m128i*)(mask+x)); + _mask = _mm_unpacklo_epi8(_mask, _mask); + __m128i rDst = _mm_lddqu_si128((const __m128i*)(dst+x)); + __m128i _negMask = _mm_cmpeq_epi8(_mask, zero); + rDst = _mm_blendv_epi8(rSrc, rDst, _negMask); + _mm_storeu_si128((__m128i*)(dst + x), rDst); + } + } + #endif + for( ; x < size.width; x++ ) + if( mask[x] ) + dst[x] = src[x]; + } +} + +static void +copyMaskGeneric(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz) +{ + size_t k, esz = *(size_t*)_esz; + for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep ) + { + const uchar* src = _src; + uchar* dst = _dst; + int x = 0; + for( ; x < size.width; x++, src += esz, dst += esz ) + { + if( !mask[x] ) + continue; + for( k = 0; k < esz; k++ ) + dst[k] = src[k]; + } + } +} + + +#define DEF_COPY_MASK(suffix, type) \ +static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \ + uchar* dst, size_t dstep, Size size, void*) \ +{ \ + copyMask_(src, sstep, mask, mstep, dst, dstep, size); \ +} + + +DEF_COPY_MASK(8u, uchar); +DEF_COPY_MASK(16u, ushort); +DEF_COPY_MASK(8uC3, Vec3b); +DEF_COPY_MASK(32s, int); +DEF_COPY_MASK(16uC3, Vec3s); +DEF_COPY_MASK(32sC2, Vec2i); +DEF_COPY_MASK(32sC3, Vec3i); +DEF_COPY_MASK(32sC4, Vec4i); +DEF_COPY_MASK(32sC6, Vec6i); +DEF_COPY_MASK(32sC8, Vec8i); + +BinaryFunc copyMaskTab[] = +{ + 0, + copyMask8u, + copyMask16u, + copyMask8uC3, + copyMask32s, + 0, + copyMask16uC3, + 0, + copyMask32sC2, + 0, 0, 0, + copyMask32sC3, + 0, 0, 0, + copyMask32sC4, + 0, 0, 0, 0, 0, 0, 0, + copyMask32sC6, + 0, 0, 0, 0, 0, 0, 0, + copyMask32sC8 +}; + +BinaryFunc getCopyMaskFunc(size_t esz) +{ + return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric; +} + +/* dst = src */ +void Mat::copyTo( OutputArray _dst ) const +{ + int dtype = _dst.type(); + if( _dst.fixedType() && dtype != type() ) + { + CV_Assert( channels() == CV_MAT_CN(dtype) ); + convertTo( _dst, dtype ); + return; + } + + if( empty() ) + { + _dst.release(); + return; + } + + if( dims <= 2 ) + { + _dst.create( rows, cols, type() ); + Mat dst = _dst.getMat(); + if( data == dst.data ) + return; + + if( rows > 0 && cols > 0 ) + { + const uchar* sptr = data; + uchar* dptr = dst.data; + + // to handle the copying 1xn matrix => nx1 std vector. + Size sz = size() == dst.size() ? + getContinuousSize(*this, dst) : + getContinuousSize(*this); + size_t len = sz.width*elemSize(); + + for( ; sz.height--; sptr += step, dptr += dst.step ) + memcpy( dptr, sptr, len ); + } + return; + } + + _dst.create( dims, size, type() ); + Mat dst = _dst.getMat(); + if( data == dst.data ) + return; + + if( total() != 0 ) + { + const Mat* arrays[] = { this, &dst }; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs, 2); + size_t sz = it.size*elemSize(); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + memcpy(ptrs[1], ptrs[0], sz); + } +} + +void Mat::copyTo( OutputArray _dst, InputArray _mask ) const +{ + Mat mask = _mask.getMat(); + if( !mask.data ) + { + copyTo(_dst); + return; + } + + int cn = channels(), mcn = mask.channels(); + CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) ); + bool colorMask = mcn > 1; + + size_t esz = colorMask ? elemSize1() : elemSize(); + BinaryFunc copymask = getCopyMaskFunc(esz); + + uchar* data0 = _dst.getMat().data; + _dst.create( dims, size, type() ); + Mat dst = _dst.getMat(); + + if( dst.data != data0 ) // do not leave dst uninitialized + dst = Scalar(0); + + if( dims <= 2 ) + { + Size sz = getContinuousSize(*this, dst, mask, mcn); + copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); + return; + } + + const Mat* arrays[] = { this, &dst, &mask, 0 }; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + Size sz((int)(it.size*mcn), 1); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz); +} + +Mat& Mat::operator = (const Scalar& s) +{ + const Mat* arrays[] = { this }; + uchar* dptr; + NAryMatIterator it(arrays, &dptr, 1); + size_t elsize = it.size*elemSize(); + const int64* is = (const int64*)&s.val[0]; + + if( is[0] == 0 && is[1] == 0 && is[2] == 0 && is[3] == 0 ) + { + for( size_t i = 0; i < it.nplanes; i++, ++it ) + memset( dptr, 0, elsize ); + } + else + { + if( it.nplanes > 0 ) + { + double scalar[12]; + scalarToRawData(s, scalar, type(), 12); + size_t blockSize = 12*elemSize1(); + + for( size_t j = 0; j < elsize; j += blockSize ) + { + size_t sz = MIN(blockSize, elsize - j); + memcpy( dptr + j, scalar, sz ); + } + } + + for( size_t i = 1; i < it.nplanes; i++ ) + { + ++it; + memcpy( dptr, data, elsize ); + } + } + return *this; +} + + +Mat& Mat::setTo(InputArray _value, InputArray _mask) +{ + if( !data ) + return *this; + + Mat value = _value.getMat(), mask = _mask.getMat(); + + CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT )); + CV_Assert( mask.empty() || mask.type() == CV_8U ); + + size_t esz = elemSize(); + BinaryFunc copymask = getCopyMaskFunc(esz); + + const Mat* arrays[] = { this, !mask.empty() ? &mask : 0, 0 }; + uchar* ptrs[2]={0,0}; + NAryMatIterator it(arrays, ptrs); + int totalsz = (int)it.size, blockSize0 = std::min(totalsz, (int)((BLOCK_SIZE + esz-1)/esz)); + AutoBuffer _scbuf(blockSize0*esz + 32); + uchar* scbuf = alignPtr((uchar*)_scbuf, (int)sizeof(double)); + convertAndUnrollScalar( value, type(), scbuf, blockSize0 ); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( int j = 0; j < totalsz; j += blockSize0 ) + { + Size sz(std::min(blockSize0, totalsz - j), 1); + size_t blockSize = sz.width*esz; + if( ptrs[1] ) + { + copymask(scbuf, 0, ptrs[1], 0, ptrs[0], 0, sz, &esz); + ptrs[1] += sz.width; + } + else + memcpy(ptrs[0], scbuf, blockSize); + ptrs[0] += blockSize; + } + } + return *this; +} + + +static void +flipHoriz( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size size, size_t esz ) +{ + int i, j, limit = (int)(((size.width + 1)/2)*esz); + AutoBuffer _tab(size.width*esz); + int* tab = _tab; + + for( i = 0; i < size.width; i++ ) + for( size_t k = 0; k < esz; k++ ) + tab[i*esz + k] = (int)((size.width - i - 1)*esz + k); + + for( ; size.height--; src += sstep, dst += dstep ) + { + for( i = 0; i < limit; i++ ) + { + j = tab[i]; + uchar t0 = src[i], t1 = src[j]; + dst[i] = t1; dst[j] = t0; + } + } +} + +static void +flipVert( const uchar* src0, size_t sstep, uchar* dst0, size_t dstep, Size size, size_t esz ) +{ + const uchar* src1 = src0 + (size.height - 1)*sstep; + uchar* dst1 = dst0 + (size.height - 1)*dstep; + size.width *= (int)esz; + + for( int y = 0; y < (size.height + 1)/2; y++, src0 += sstep, src1 -= sstep, + dst0 += dstep, dst1 -= dstep ) + { + int i = 0; + if( ((size_t)src0|(size_t)dst0|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 ) + { + for( ; i <= size.width - 16; i += 16 ) + { + int t0 = ((int*)(src0 + i))[0]; + int t1 = ((int*)(src1 + i))[0]; + + ((int*)(dst0 + i))[0] = t1; + ((int*)(dst1 + i))[0] = t0; + + t0 = ((int*)(src0 + i))[1]; + t1 = ((int*)(src1 + i))[1]; + + ((int*)(dst0 + i))[1] = t1; + ((int*)(dst1 + i))[1] = t0; + + t0 = ((int*)(src0 + i))[2]; + t1 = ((int*)(src1 + i))[2]; + + ((int*)(dst0 + i))[2] = t1; + ((int*)(dst1 + i))[2] = t0; + + t0 = ((int*)(src0 + i))[3]; + t1 = ((int*)(src1 + i))[3]; + + ((int*)(dst0 + i))[3] = t1; + ((int*)(dst1 + i))[3] = t0; + } + + for( ; i <= size.width - 4; i += 4 ) + { + int t0 = ((int*)(src0 + i))[0]; + int t1 = ((int*)(src1 + i))[0]; + + ((int*)(dst0 + i))[0] = t1; + ((int*)(dst1 + i))[0] = t0; + } + } + + for( ; i < size.width; i++ ) + { + uchar t0 = src0[i]; + uchar t1 = src1[i]; + + dst0[i] = t1; + dst1[i] = t0; + } + } +} + +void flip( InputArray _src, OutputArray _dst, int flip_mode ) +{ + Mat src = _src.getMat(); + + CV_Assert( src.dims <= 2 ); + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + size_t esz = src.elemSize(); + + if( flip_mode <= 0 ) + flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz ); + else + flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz ); + + if( flip_mode < 0 ) + flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz ); +} + + +void repeat(InputArray _src, int ny, int nx, OutputArray _dst) +{ + Mat src = _src.getMat(); + CV_Assert( src.dims <= 2 ); + + _dst.create(src.rows*ny, src.cols*nx, src.type()); + Mat dst = _dst.getMat(); + Size ssize = src.size(), dsize = dst.size(); + int esz = (int)src.elemSize(); + int x, y; + ssize.width *= esz; dsize.width *= esz; + + for( y = 0; y < ssize.height; y++ ) + { + for( x = 0; x < dsize.width; x += ssize.width ) + memcpy( dst.data + y*dst.step + x, src.data + y*src.step, ssize.width ); + } + + for( ; y < dsize.height; y++ ) + memcpy( dst.data + y*dst.step, dst.data + (y - ssize.height)*dst.step, dsize.width ); +} + +Mat repeat(const Mat& src, int ny, int nx) +{ + if( nx == 1 && ny == 1 ) + return src; + Mat dst; + repeat(src, ny, nx, dst); + return dst; +} + +} + +/* dst = src */ +CV_IMPL void +cvCopy( const void* srcarr, void* dstarr, const void* maskarr ) +{ + if( CV_IS_SPARSE_MAT(srcarr) && CV_IS_SPARSE_MAT(dstarr)) + { + CV_Assert( maskarr == 0 ); + CvSparseMat* src1 = (CvSparseMat*)srcarr; + CvSparseMat* dst1 = (CvSparseMat*)dstarr; + CvSparseMatIterator iterator; + CvSparseNode* node; + + dst1->dims = src1->dims; + memcpy( dst1->size, src1->size, src1->dims*sizeof(src1->size[0])); + dst1->valoffset = src1->valoffset; + dst1->idxoffset = src1->idxoffset; + cvClearSet( dst1->heap ); + + if( src1->heap->active_count >= dst1->hashsize*CV_SPARSE_HASH_RATIO ) + { + cvFree( &dst1->hashtable ); + dst1->hashsize = src1->hashsize; + dst1->hashtable = + (void**)cvAlloc( dst1->hashsize*sizeof(dst1->hashtable[0])); + } + + memset( dst1->hashtable, 0, dst1->hashsize*sizeof(dst1->hashtable[0])); + + for( node = cvInitSparseMatIterator( src1, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap ); + int tabidx = node->hashval & (dst1->hashsize - 1); + memcpy( node_copy, node, dst1->heap->elem_size ); + node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx]; + dst1->hashtable[tabidx] = node_copy; + } + return; + } + cv::Mat src = cv::cvarrToMat(srcarr, false, true, 1), dst = cv::cvarrToMat(dstarr, false, true, 1); + CV_Assert( src.depth() == dst.depth() && src.size == dst.size ); + + int coi1 = 0, coi2 = 0; + if( CV_IS_IMAGE(srcarr) ) + coi1 = cvGetImageCOI((const IplImage*)srcarr); + if( CV_IS_IMAGE(dstarr) ) + coi2 = cvGetImageCOI((const IplImage*)dstarr); + + if( coi1 || coi2 ) + { + CV_Assert( (coi1 != 0 || src.channels() == 1) && + (coi2 != 0 || dst.channels() == 1) ); + + int pair[] = { std::max(coi1-1, 0), std::max(coi2-1, 0) }; + cv::mixChannels( &src, 1, &dst, 1, pair, 1 ); + return; + } + else + CV_Assert( src.channels() == dst.channels() ); + + if( !maskarr ) + src.copyTo(dst); + else + src.copyTo(dst, cv::cvarrToMat(maskarr)); +} + +CV_IMPL void +cvSet( void* arr, CvScalar value, const void* maskarr ) +{ + cv::Mat m = cv::cvarrToMat(arr); + if( !maskarr ) + m = value; + else + m.setTo(cv::Scalar(value), cv::cvarrToMat(maskarr)); +} + +CV_IMPL void +cvSetZero( CvArr* arr ) +{ + if( CV_IS_SPARSE_MAT(arr) ) + { + CvSparseMat* mat1 = (CvSparseMat*)arr; + cvClearSet( mat1->heap ); + if( mat1->hashtable ) + memset( mat1->hashtable, 0, mat1->hashsize*sizeof(mat1->hashtable[0])); + return; + } + cv::Mat m = cv::cvarrToMat(arr); + m = cv::Scalar(0); +} + +CV_IMPL void +cvFlip( const CvArr* srcarr, CvArr* dstarr, int flip_mode ) +{ + cv::Mat src = cv::cvarrToMat(srcarr); + cv::Mat dst; + + if (!dstarr) + dst = src; + else + dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.type() == dst.type() && src.size() == dst.size() ); + cv::flip( src, dst, flip_mode ); +} + +CV_IMPL void +cvRepeat( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.type() == dst.type() && + dst.rows % src.rows == 0 && dst.cols % src.cols == 0 ); + cv::repeat(src, dst.rows/src.rows, dst.cols/src.cols, dst); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/cuda/matrix_operations.cu diffimg-2.0.0/3rdparty/opencv/core/src/cuda/matrix_operations.cu --- diffimg-1.5.0/3rdparty/opencv/core/src/cuda/matrix_operations.cu 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/cuda/matrix_operations.cu 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,382 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "opencv2/gpu/device/saturate_cast.hpp" +#include "opencv2/gpu/device/transform.hpp" +#include "opencv2/gpu/device/functional.hpp" +#include "opencv2/gpu/device/type_traits.hpp" + +namespace cv { namespace gpu { namespace device +{ + void writeScalar(const uchar*); + void writeScalar(const schar*); + void writeScalar(const ushort*); + void writeScalar(const short int*); + void writeScalar(const int*); + void writeScalar(const float*); + void writeScalar(const double*); + void copyToWithMask_gpu(PtrStepSzb src, PtrStepSzb dst, size_t elemSize1, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream); + void convert_gpu(PtrStepSzb, int, PtrStepSzb, int, double, double, cudaStream_t); +}}} + +namespace cv { namespace gpu { namespace device +{ + template struct shift_and_sizeof; + template <> struct shift_and_sizeof { enum { shift = 0 }; }; + template <> struct shift_and_sizeof { enum { shift = 0 }; }; + template <> struct shift_and_sizeof { enum { shift = 1 }; }; + template <> struct shift_and_sizeof { enum { shift = 1 }; }; + template <> struct shift_and_sizeof { enum { shift = 2 }; }; + template <> struct shift_and_sizeof { enum { shift = 2 }; }; + template <> struct shift_and_sizeof { enum { shift = 3 }; }; + + /////////////////////////////////////////////////////////////////////////// + ////////////////////////////////// CopyTo ///////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + template void copyToWithMask(PtrStepSzb src, PtrStepSzb dst, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream) + { + if (colorMask) + cv::gpu::device::transform((PtrStepSz)src, (PtrStepSz)dst, identity(), SingleMask(mask), stream); + else + cv::gpu::device::transform((PtrStepSz)src, (PtrStepSz)dst, identity(), SingleMaskChannels(mask, cn), stream); + } + + void copyToWithMask_gpu(PtrStepSzb src, PtrStepSzb dst, size_t elemSize1, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream) + { + typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream); + + static func_t tab[] = + { + 0, + copyToWithMask, + copyToWithMask, + 0, + copyToWithMask, + 0, + 0, + 0, + copyToWithMask + }; + + tab[elemSize1](src, dst, cn, mask, colorMask, stream); + } + + /////////////////////////////////////////////////////////////////////////// + ////////////////////////////////// SetTo ////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + __constant__ uchar scalar_8u[4]; + __constant__ schar scalar_8s[4]; + __constant__ ushort scalar_16u[4]; + __constant__ short scalar_16s[4]; + __constant__ int scalar_32s[4]; + __constant__ float scalar_32f[4]; + __constant__ double scalar_64f[4]; + + template __device__ __forceinline__ T readScalar(int i); + template <> __device__ __forceinline__ uchar readScalar(int i) {return scalar_8u[i];} + template <> __device__ __forceinline__ schar readScalar(int i) {return scalar_8s[i];} + template <> __device__ __forceinline__ ushort readScalar(int i) {return scalar_16u[i];} + template <> __device__ __forceinline__ short readScalar(int i) {return scalar_16s[i];} + template <> __device__ __forceinline__ int readScalar(int i) {return scalar_32s[i];} + template <> __device__ __forceinline__ float readScalar(int i) {return scalar_32f[i];} + template <> __device__ __forceinline__ double readScalar(int i) {return scalar_64f[i];} + + void writeScalar(const uchar* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_8u, vals, sizeof(uchar) * 4) ); + } + void writeScalar(const schar* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_8s, vals, sizeof(schar) * 4) ); + } + void writeScalar(const ushort* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_16u, vals, sizeof(ushort) * 4) ); + } + void writeScalar(const short* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_16s, vals, sizeof(short) * 4) ); + } + void writeScalar(const int* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_32s, vals, sizeof(int) * 4) ); + } + void writeScalar(const float* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_32f, vals, sizeof(float) * 4) ); + } + void writeScalar(const double* vals) + { + cudaSafeCall( cudaMemcpyToSymbol(scalar_64f, vals, sizeof(double) * 4) ); + } + + template + __global__ void set_to_without_mask(T* mat, int cols, int rows, size_t step, int channels) + { + size_t x = blockIdx.x * blockDim.x + threadIdx.x; + size_t y = blockIdx.y * blockDim.y + threadIdx.y; + + if ((x < cols * channels ) && (y < rows)) + { + size_t idx = y * ( step >> shift_and_sizeof::shift ) + x; + mat[idx] = readScalar(x % channels); + } + } + + template + __global__ void set_to_with_mask(T* mat, const uchar* mask, int cols, int rows, size_t step, int channels, size_t step_mask) + { + size_t x = blockIdx.x * blockDim.x + threadIdx.x; + size_t y = blockIdx.y * blockDim.y + threadIdx.y; + + if ((x < cols * channels ) && (y < rows)) + if (mask[y * step_mask + x / channels] != 0) + { + size_t idx = y * ( step >> shift_and_sizeof::shift ) + x; + mat[idx] = readScalar(x % channels); + } + } + template + void set_to_gpu(PtrStepSzb mat, const T* scalar, PtrStepSzb mask, int channels, cudaStream_t stream) + { + writeScalar(scalar); + + dim3 threadsPerBlock(32, 8, 1); + dim3 numBlocks (mat.cols * channels / threadsPerBlock.x + 1, mat.rows / threadsPerBlock.y + 1, 1); + + set_to_with_mask<<>>((T*)mat.data, (uchar*)mask.data, mat.cols, mat.rows, mat.step, channels, mask.step); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall ( cudaDeviceSynchronize() ); + } + + template void set_to_gpu(PtrStepSzb mat, const uchar* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const schar* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const ushort* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const short* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const int* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const float* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const double* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + + template + void set_to_gpu(PtrStepSzb mat, const T* scalar, int channels, cudaStream_t stream) + { + writeScalar(scalar); + + dim3 threadsPerBlock(32, 8, 1); + dim3 numBlocks (mat.cols * channels / threadsPerBlock.x + 1, mat.rows / threadsPerBlock.y + 1, 1); + + set_to_without_mask<<>>((T*)mat.data, mat.cols, mat.rows, mat.step, channels); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall ( cudaDeviceSynchronize() ); + } + + template void set_to_gpu(PtrStepSzb mat, const uchar* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const schar* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const ushort* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const short* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const int* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const float* scalar, int channels, cudaStream_t stream); + template void set_to_gpu(PtrStepSzb mat, const double* scalar, int channels, cudaStream_t stream); + + /////////////////////////////////////////////////////////////////////////// + //////////////////////////////// ConvertTo //////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + template struct Convertor : unary_function + { + Convertor(S alpha_, S beta_) : alpha(alpha_), beta(beta_) {} + + __device__ __forceinline__ D operator()(typename TypeTraits::ParameterType src) const + { + return saturate_cast(alpha * src + beta); + } + + S alpha, beta; + }; + + namespace detail + { + template struct ConvertTraitsDispatcher : DefaultTransformFunctorTraits + { + }; + template struct ConvertTraitsDispatcher<1, 1, F> : DefaultTransformFunctorTraits + { + enum { smart_shift = 8 }; + }; + template struct ConvertTraitsDispatcher<1, 2, F> : DefaultTransformFunctorTraits + { + enum { smart_shift = 4 }; + }; + template struct ConvertTraitsDispatcher<1, 4, F> : DefaultTransformFunctorTraits + { + enum { smart_block_dim_y = 8 }; + enum { smart_shift = 4 }; + }; + + template struct ConvertTraitsDispatcher<2, 2, F> : DefaultTransformFunctorTraits + { + enum { smart_shift = 4 }; + }; + template struct ConvertTraitsDispatcher<2, 4, F> : DefaultTransformFunctorTraits + { + enum { smart_shift = 2 }; + }; + + template struct ConvertTraitsDispatcher<4, 2, F> : DefaultTransformFunctorTraits + { + enum { smart_block_dim_y = 8 }; + enum { smart_shift = 4 }; + }; + template struct ConvertTraitsDispatcher<4, 4, F> : DefaultTransformFunctorTraits + { + enum { smart_block_dim_y = 8 }; + enum { smart_shift = 2 }; + }; + + template struct ConvertTraits : ConvertTraitsDispatcher + { + }; + } + + template struct TransformFunctorTraits< Convertor > : detail::ConvertTraits< Convertor > + { + }; + + template + void cvt_(PtrStepSzb src, PtrStepSzb dst, double alpha, double beta, cudaStream_t stream) + { + cudaSafeCall( cudaSetDoubleForDevice(&alpha) ); + cudaSafeCall( cudaSetDoubleForDevice(&beta) ); + Convertor op(static_cast(alpha), static_cast(beta)); + cv::gpu::device::transform((PtrStepSz)src, (PtrStepSz)dst, op, WithOutMask(), stream); + } + +#if defined __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmissing-declarations" +#endif + + void convert_gpu(PtrStepSzb src, int sdepth, PtrStepSzb dst, int ddepth, double alpha, double beta, cudaStream_t stream) + { + typedef void (*caller_t)(PtrStepSzb src, PtrStepSzb dst, double alpha, double beta, cudaStream_t stream); + + static const caller_t tab[7][7] = + { + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + }, + { + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_, + cvt_ + } + }; + + caller_t func = tab[sdepth][ddepth]; + func(src, dst, alpha, beta, stream); + } + +#if defined __clang__ +# pragma clang diagnostic pop +#endif +}}} // namespace cv { namespace gpu { namespace device diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/datastructs.cpp diffimg-2.0.0/3rdparty/opencv/core/src/datastructs.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/datastructs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/datastructs.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,4060 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +#define ICV_FREE_PTR(storage) \ + ((schar*)(storage)->top + (storage)->block_size - (storage)->free_space) + +#define ICV_ALIGNED_SEQ_BLOCK_SIZE \ + (int)cvAlign(sizeof(CvSeqBlock), CV_STRUCT_ALIGN) + +CV_INLINE int +cvAlignLeft( int size, int align ) +{ + return size & -align; +} + +#define CV_GET_LAST_ELEM( seq, block ) \ + ((block)->data + ((block)->count - 1)*((seq)->elem_size)) + +#define CV_SWAP_ELEMS(a,b,elem_size) \ +{ \ + int k; \ + for( k = 0; k < elem_size; k++ ) \ + { \ + char t0 = (a)[k]; \ + char t1 = (b)[k]; \ + (a)[k] = t1; \ + (b)[k] = t0; \ + } \ +} + +#define ICV_SHIFT_TAB_MAX 32 +static const schar icvPower2ShiftTab[] = +{ + 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5 +}; + +/****************************************************************************************\ +* Functions for manipulating memory storage - list of memory blocks * +\****************************************************************************************/ + +/* Initialize allocated storage: */ +static void +icvInitMemStorage( CvMemStorage* storage, int block_size ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + if( block_size <= 0 ) + block_size = CV_STORAGE_BLOCK_SIZE; + + block_size = cvAlign( block_size, CV_STRUCT_ALIGN ); + assert( sizeof(CvMemBlock) % CV_STRUCT_ALIGN == 0 ); + + memset( storage, 0, sizeof( *storage )); + storage->signature = CV_STORAGE_MAGIC_VAL; + storage->block_size = block_size; +} + + +/* Create root memory storage: */ +CV_IMPL CvMemStorage* +cvCreateMemStorage( int block_size ) +{ + CvMemStorage* storage = (CvMemStorage *)cvAlloc( sizeof( CvMemStorage )); + icvInitMemStorage( storage, block_size ); + return storage; +} + + +/* Create child memory storage: */ +CV_IMPL CvMemStorage * +cvCreateChildMemStorage( CvMemStorage * parent ) +{ + if( !parent ) + CV_Error( CV_StsNullPtr, "" ); + + CvMemStorage* storage = cvCreateMemStorage(parent->block_size); + storage->parent = parent; + + return storage; +} + + +/* Release all blocks of the storage (or return them to parent, if any): */ +static void +icvDestroyMemStorage( CvMemStorage* storage ) +{ + int k = 0; + + CvMemBlock *block; + CvMemBlock *dst_top = 0; + + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + if( storage->parent ) + dst_top = storage->parent->top; + + for( block = storage->bottom; block != 0; k++ ) + { + CvMemBlock *temp = block; + + block = block->next; + if( storage->parent ) + { + if( dst_top ) + { + temp->prev = dst_top; + temp->next = dst_top->next; + if( temp->next ) + temp->next->prev = temp; + dst_top = dst_top->next = temp; + } + else + { + dst_top = storage->parent->bottom = storage->parent->top = temp; + temp->prev = temp->next = 0; + storage->free_space = storage->block_size - sizeof( *temp ); + } + } + else + { + cvFree( &temp ); + } + } + + storage->top = storage->bottom = 0; + storage->free_space = 0; +} + + +/* Release memory storage: */ +CV_IMPL void +cvReleaseMemStorage( CvMemStorage** storage ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + CvMemStorage* st = *storage; + *storage = 0; + if( st ) + { + icvDestroyMemStorage( st ); + cvFree( &st ); + } +} + + +/* Clears memory storage (return blocks to the parent, if any): */ +CV_IMPL void +cvClearMemStorage( CvMemStorage * storage ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + if( storage->parent ) + icvDestroyMemStorage( storage ); + else + { + storage->top = storage->bottom; + storage->free_space = storage->bottom ? storage->block_size - sizeof(CvMemBlock) : 0; + } +} + + +/* Moves stack pointer to next block. + If no blocks, allocate new one and link it to the storage: */ +static void +icvGoNextMemBlock( CvMemStorage * storage ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + if( !storage->top || !storage->top->next ) + { + CvMemBlock *block; + + if( !(storage->parent) ) + { + block = (CvMemBlock *)cvAlloc( storage->block_size ); + } + else + { + CvMemStorage *parent = storage->parent; + CvMemStoragePos parent_pos; + + cvSaveMemStoragePos( parent, &parent_pos ); + icvGoNextMemBlock( parent ); + + block = parent->top; + cvRestoreMemStoragePos( parent, &parent_pos ); + + if( block == parent->top ) /* the single allocated block */ + { + assert( parent->bottom == block ); + parent->top = parent->bottom = 0; + parent->free_space = 0; + } + else + { + /* cut the block from the parent's list of blocks */ + parent->top->next = block->next; + if( block->next ) + block->next->prev = parent->top; + } + } + + /* link block */ + block->next = 0; + block->prev = storage->top; + + if( storage->top ) + storage->top->next = block; + else + storage->top = storage->bottom = block; + } + + if( storage->top->next ) + storage->top = storage->top->next; + storage->free_space = storage->block_size - sizeof(CvMemBlock); + assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); +} + + +/* Remember memory storage position: */ +CV_IMPL void +cvSaveMemStoragePos( const CvMemStorage * storage, CvMemStoragePos * pos ) +{ + if( !storage || !pos ) + CV_Error( CV_StsNullPtr, "" ); + + pos->top = storage->top; + pos->free_space = storage->free_space; +} + + +/* Restore memory storage position: */ +CV_IMPL void +cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos ) +{ + if( !storage || !pos ) + CV_Error( CV_StsNullPtr, "" ); + if( pos->free_space > storage->block_size ) + CV_Error( CV_StsBadSize, "" ); + + /* + // this breaks icvGoNextMemBlock, so comment it off for now + if( storage->parent && (!pos->top || pos->top->next) ) + { + CvMemBlock* save_bottom; + if( !pos->top ) + save_bottom = 0; + else + { + save_bottom = storage->bottom; + storage->bottom = pos->top->next; + pos->top->next = 0; + storage->bottom->prev = 0; + } + icvDestroyMemStorage( storage ); + storage->bottom = save_bottom; + }*/ + + storage->top = pos->top; + storage->free_space = pos->free_space; + + if( !storage->top ) + { + storage->top = storage->bottom; + storage->free_space = storage->top ? storage->block_size - sizeof(CvMemBlock) : 0; + } +} + + +/* Allocate continuous buffer of the specified size in the storage: */ +CV_IMPL void* +cvMemStorageAlloc( CvMemStorage* storage, size_t size ) +{ + schar *ptr = 0; + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + + if( size > INT_MAX ) + CV_Error( CV_StsOutOfRange, "Too large memory block is requested" ); + + assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); + + if( (size_t)storage->free_space < size ) + { + size_t max_free_space = cvAlignLeft(storage->block_size - sizeof(CvMemBlock), CV_STRUCT_ALIGN); + if( max_free_space < size ) + CV_Error( CV_StsOutOfRange, "requested size is negative or too big" ); + + icvGoNextMemBlock( storage ); + } + + ptr = ICV_FREE_PTR(storage); + assert( (size_t)ptr % CV_STRUCT_ALIGN == 0 ); + storage->free_space = cvAlignLeft(storage->free_space - (int)size, CV_STRUCT_ALIGN ); + + return ptr; +} + + +CV_IMPL CvString +cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len ) +{ + CvString str; + + str.len = len >= 0 ? len : (int)strlen(ptr); + str.ptr = (char*)cvMemStorageAlloc( storage, str.len + 1 ); + memcpy( str.ptr, ptr, str.len ); + str.ptr[str.len] = '\0'; + + return str; +} + + +/****************************************************************************************\ +* Sequence implementation * +\****************************************************************************************/ + +/* Create empty sequence: */ +CV_IMPL CvSeq * +cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* storage ) +{ + CvSeq *seq = 0; + + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + if( header_size < sizeof( CvSeq ) || elem_size <= 0 ) + CV_Error( CV_StsBadSize, "" ); + + /* allocate sequence header */ + seq = (CvSeq*)cvMemStorageAlloc( storage, header_size ); + memset( seq, 0, header_size ); + + seq->header_size = (int)header_size; + seq->flags = (seq_flags & ~CV_MAGIC_MASK) | CV_SEQ_MAGIC_VAL; + { + int elemtype = CV_MAT_TYPE(seq_flags); + int typesize = CV_ELEM_SIZE(elemtype); + + if( elemtype != CV_SEQ_ELTYPE_GENERIC && elemtype != CV_USRTYPE1 && + typesize != 0 && typesize != (int)elem_size ) + CV_Error( CV_StsBadSize, + "Specified element size doesn't match to the size of the specified element type " + "(try to use 0 for element type)" ); + } + seq->elem_size = (int)elem_size; + seq->storage = storage; + + cvSetSeqBlockSize( seq, (int)((1 << 10)/elem_size) ); + + return seq; +} + + +/* adjusts field of sequence. It determines how much the sequence + grows if there are no free space inside the sequence buffers */ +CV_IMPL void +cvSetSeqBlockSize( CvSeq *seq, int delta_elements ) +{ + int elem_size; + int useful_block_size; + + if( !seq || !seq->storage ) + CV_Error( CV_StsNullPtr, "" ); + if( delta_elements < 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + useful_block_size = cvAlignLeft(seq->storage->block_size - sizeof(CvMemBlock) - + sizeof(CvSeqBlock), CV_STRUCT_ALIGN); + elem_size = seq->elem_size; + + if( delta_elements == 0 ) + { + delta_elements = (1 << 10) / elem_size; + delta_elements = MAX( delta_elements, 1 ); + } + if( delta_elements * elem_size > useful_block_size ) + { + delta_elements = useful_block_size / elem_size; + if( delta_elements == 0 ) + CV_Error( CV_StsOutOfRange, "Storage block size is too small " + "to fit the sequence elements" ); + } + + seq->delta_elems = delta_elements; +} + + +/* Find a sequence element by its index: */ +CV_IMPL schar* +cvGetSeqElem( const CvSeq *seq, int index ) +{ + CvSeqBlock *block; + int count, total = seq->total; + + if( (unsigned)index >= (unsigned)total ) + { + index += index < 0 ? total : 0; + index -= index >= total ? total : 0; + if( (unsigned)index >= (unsigned)total ) + return 0; + } + + block = seq->first; + if( index + index <= total ) + { + while( index >= (count = block->count) ) + { + block = block->next; + index -= count; + } + } + else + { + do + { + block = block->prev; + total -= block->count; + } + while( index < total ); + index -= total; + } + + return block->data + index * seq->elem_size; +} + + +/* Calculate index of a sequence element: */ +CV_IMPL int +cvSeqElemIdx( const CvSeq* seq, const void* _element, CvSeqBlock** _block ) +{ + const schar *element = (const schar *)_element; + int elem_size; + int id = -1; + CvSeqBlock *first_block; + CvSeqBlock *block; + + if( !seq || !element ) + CV_Error( CV_StsNullPtr, "" ); + + block = first_block = seq->first; + elem_size = seq->elem_size; + + for( ;; ) + { + if( (unsigned)(element - block->data) < (unsigned) (block->count * elem_size) ) + { + if( _block ) + *_block = block; + if( elem_size <= ICV_SHIFT_TAB_MAX && (id = icvPower2ShiftTab[elem_size - 1]) >= 0 ) + id = (int)((size_t)(element - block->data) >> id); + else + id = (int)((size_t)(element - block->data) / elem_size); + id += block->start_index - seq->first->start_index; + break; + } + block = block->next; + if( block == first_block ) + break; + } + + return id; +} + + +CV_IMPL int +cvSliceLength( CvSlice slice, const CvSeq* seq ) +{ + int total = seq->total; + int length = slice.end_index - slice.start_index; + + if( length != 0 ) + { + if( slice.start_index < 0 ) + slice.start_index += total; + if( slice.end_index <= 0 ) + slice.end_index += total; + + length = slice.end_index - slice.start_index; + } + + while( length < 0 ) + length += total; + if( length > total ) + length = total; + + return length; +} + + +/* Copy all sequence elements into single continuous array: */ +CV_IMPL void* +cvCvtSeqToArray( const CvSeq *seq, void *array, CvSlice slice ) +{ + int elem_size, total; + CvSeqReader reader; + char *dst = (char*)array; + + if( !seq || !array ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = seq->elem_size; + total = cvSliceLength( slice, seq )*elem_size; + + if( total == 0 ) + return 0; + + cvStartReadSeq( seq, &reader, 0 ); + cvSetSeqReaderPos( &reader, slice.start_index, 0 ); + + do + { + int count = (int)(reader.block_max - reader.ptr); + if( count > total ) + count = total; + + memcpy( dst, reader.ptr, count ); + dst += count; + reader.block = reader.block->next; + reader.ptr = reader.block->data; + reader.block_max = reader.ptr + reader.block->count*elem_size; + total -= count; + } + while( total > 0 ); + + return array; +} + + +/* Construct a sequence from an array without copying any data. + NB: The resultant sequence cannot grow beyond its initial size: */ +CV_IMPL CvSeq* +cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, + void *array, int total, CvSeq *seq, CvSeqBlock * block ) +{ + CvSeq* result = 0; + + if( elem_size <= 0 || header_size < (int)sizeof( CvSeq ) || total < 0 ) + CV_Error( CV_StsBadSize, "" ); + + if( !seq || ((!array || !block) && total > 0) ) + CV_Error( CV_StsNullPtr, "" ); + + memset( seq, 0, header_size ); + + seq->header_size = header_size; + seq->flags = (seq_flags & ~CV_MAGIC_MASK) | CV_SEQ_MAGIC_VAL; + { + int elemtype = CV_MAT_TYPE(seq_flags); + int typesize = CV_ELEM_SIZE(elemtype); + + if( elemtype != CV_SEQ_ELTYPE_GENERIC && + typesize != 0 && typesize != elem_size ) + CV_Error( CV_StsBadSize, + "Element size doesn't match to the size of predefined element type " + "(try to use 0 for sequence element type)" ); + } + seq->elem_size = elem_size; + seq->total = total; + seq->block_max = seq->ptr = (schar *) array + total * elem_size; + + if( total > 0 ) + { + seq->first = block; + block->prev = block->next = block; + block->start_index = 0; + block->count = total; + block->data = (schar *) array; + } + + result = seq; + + return result; +} + + +/* The function allocates space for at least one more sequence element. + If there are free sequence blocks (seq->free_blocks != 0) + they are reused, otherwise the space is allocated in the storage: */ +static void +icvGrowSeq( CvSeq *seq, int in_front_of ) +{ + CvSeqBlock *block; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + block = seq->free_blocks; + + if( !block ) + { + int elem_size = seq->elem_size; + int delta_elems = seq->delta_elems; + CvMemStorage *storage = seq->storage; + + if( seq->total >= delta_elems*4 ) + cvSetSeqBlockSize( seq, delta_elems*2 ); + + if( !storage ) + CV_Error( CV_StsNullPtr, "The sequence has NULL storage pointer" ); + + /* If there is a free space just after last allocated block + and it is big enough then enlarge the last block. + This can happen only if the new block is added to the end of sequence: */ + if( (unsigned)(ICV_FREE_PTR(storage) - seq->block_max) < CV_STRUCT_ALIGN && + storage->free_space >= seq->elem_size && !in_front_of ) + { + int delta = storage->free_space / elem_size; + + delta = MIN( delta, delta_elems ) * elem_size; + seq->block_max += delta; + storage->free_space = cvAlignLeft((int)(((schar*)storage->top + storage->block_size) - + seq->block_max), CV_STRUCT_ALIGN ); + return; + } + else + { + int delta = elem_size * delta_elems + ICV_ALIGNED_SEQ_BLOCK_SIZE; + + /* Try to allocate elements: */ + if( storage->free_space < delta ) + { + int small_block_size = MAX(1, delta_elems/3)*elem_size + + ICV_ALIGNED_SEQ_BLOCK_SIZE; + /* try to allocate smaller part */ + if( storage->free_space >= small_block_size + CV_STRUCT_ALIGN ) + { + delta = (storage->free_space - ICV_ALIGNED_SEQ_BLOCK_SIZE)/seq->elem_size; + delta = delta*seq->elem_size + ICV_ALIGNED_SEQ_BLOCK_SIZE; + } + else + { + icvGoNextMemBlock( storage ); + assert( storage->free_space >= delta ); + } + } + + block = (CvSeqBlock*)cvMemStorageAlloc( storage, delta ); + block->data = (schar*)cvAlignPtr( block + 1, CV_STRUCT_ALIGN ); + block->count = delta - ICV_ALIGNED_SEQ_BLOCK_SIZE; + block->prev = block->next = 0; + } + } + else + { + seq->free_blocks = block->next; + } + + if( !(seq->first) ) + { + seq->first = block; + block->prev = block->next = block; + } + else + { + block->prev = seq->first->prev; + block->next = seq->first; + block->prev->next = block->next->prev = block; + } + + /* For free blocks the field means + * total number of bytes in the block. + * + * For used blocks it means current number + * of sequence elements in the block: + */ + assert( block->count % seq->elem_size == 0 && block->count > 0 ); + + if( !in_front_of ) + { + seq->ptr = block->data; + seq->block_max = block->data + block->count; + block->start_index = block == block->prev ? 0 : + block->prev->start_index + block->prev->count; + } + else + { + int delta = block->count / seq->elem_size; + block->data += block->count; + + if( block != block->prev ) + { + assert( seq->first->start_index == 0 ); + seq->first = block; + } + else + { + seq->block_max = seq->ptr = block->data; + } + + block->start_index = 0; + + for( ;; ) + { + block->start_index += delta; + block = block->next; + if( block == seq->first ) + break; + } + } + + block->count = 0; +} + +/* Recycle a sequence block: */ +static void +icvFreeSeqBlock( CvSeq *seq, int in_front_of ) +{ + CvSeqBlock *block = seq->first; + + assert( (in_front_of ? block : block->prev)->count == 0 ); + + if( block == block->prev ) /* single block case */ + { + block->count = (int)(seq->block_max - block->data) + block->start_index * seq->elem_size; + block->data = seq->block_max - block->count; + seq->first = 0; + seq->ptr = seq->block_max = 0; + seq->total = 0; + } + else + { + if( !in_front_of ) + { + block = block->prev; + assert( seq->ptr == block->data ); + + block->count = (int)(seq->block_max - seq->ptr); + seq->block_max = seq->ptr = block->prev->data + + block->prev->count * seq->elem_size; + } + else + { + int delta = block->start_index; + + block->count = delta * seq->elem_size; + block->data -= block->count; + + /* Update start indices of sequence blocks: */ + for( ;; ) + { + block->start_index -= delta; + block = block->next; + if( block == seq->first ) + break; + } + + seq->first = block->next; + } + + block->prev->next = block->next; + block->next->prev = block->prev; + } + + assert( block->count > 0 && block->count % seq->elem_size == 0 ); + block->next = seq->free_blocks; + seq->free_blocks = block; +} + + +/****************************************************************************************\ +* Sequence Writer implementation * +\****************************************************************************************/ + +/* Initialize sequence writer: */ +CV_IMPL void +cvStartAppendToSeq( CvSeq *seq, CvSeqWriter * writer ) +{ + if( !seq || !writer ) + CV_Error( CV_StsNullPtr, "" ); + + memset( writer, 0, sizeof( *writer )); + writer->header_size = sizeof( CvSeqWriter ); + + writer->seq = seq; + writer->block = seq->first ? seq->first->prev : 0; + writer->ptr = seq->ptr; + writer->block_max = seq->block_max; +} + + +/* Initialize sequence writer: */ +CV_IMPL void +cvStartWriteSeq( int seq_flags, int header_size, + int elem_size, CvMemStorage * storage, CvSeqWriter * writer ) +{ + if( !storage || !writer ) + CV_Error( CV_StsNullPtr, "" ); + + CvSeq* seq = cvCreateSeq( seq_flags, header_size, elem_size, storage ); + cvStartAppendToSeq( seq, writer ); +} + + +/* Update sequence header: */ +CV_IMPL void +cvFlushSeqWriter( CvSeqWriter * writer ) +{ + if( !writer ) + CV_Error( CV_StsNullPtr, "" ); + + CvSeq* seq = writer->seq; + seq->ptr = writer->ptr; + + if( writer->block ) + { + int total = 0; + CvSeqBlock *first_block = writer->seq->first; + CvSeqBlock *block = first_block; + + writer->block->count = (int)((writer->ptr - writer->block->data) / seq->elem_size); + assert( writer->block->count > 0 ); + + do + { + total += block->count; + block = block->next; + } + while( block != first_block ); + + writer->seq->total = total; + } +} + + +/* Calls icvFlushSeqWriter and finishes writing process: */ +CV_IMPL CvSeq * +cvEndWriteSeq( CvSeqWriter * writer ) +{ + if( !writer ) + CV_Error( CV_StsNullPtr, "" ); + + cvFlushSeqWriter( writer ); + CvSeq* seq = writer->seq; + + /* Truncate the last block: */ + if( writer->block && writer->seq->storage ) + { + CvMemStorage *storage = seq->storage; + schar *storage_block_max = (schar *) storage->top + storage->block_size; + + assert( writer->block->count > 0 ); + + if( (unsigned)((storage_block_max - storage->free_space) + - seq->block_max) < CV_STRUCT_ALIGN ) + { + storage->free_space = cvAlignLeft((int)(storage_block_max - seq->ptr), CV_STRUCT_ALIGN); + seq->block_max = seq->ptr; + } + } + + writer->ptr = 0; + return seq; +} + + +/* Create new sequence block: */ +CV_IMPL void +cvCreateSeqBlock( CvSeqWriter * writer ) +{ + if( !writer || !writer->seq ) + CV_Error( CV_StsNullPtr, "" ); + + CvSeq* seq = writer->seq; + + cvFlushSeqWriter( writer ); + + icvGrowSeq( seq, 0 ); + + writer->block = seq->first->prev; + writer->ptr = seq->ptr; + writer->block_max = seq->block_max; +} + + +/****************************************************************************************\ +* Sequence Reader implementation * +\****************************************************************************************/ + +/* Initialize sequence reader: */ +CV_IMPL void +cvStartReadSeq( const CvSeq *seq, CvSeqReader * reader, int reverse ) +{ + CvSeqBlock *first_block; + CvSeqBlock *last_block; + + if( reader ) + { + reader->seq = 0; + reader->block = 0; + reader->ptr = reader->block_max = reader->block_min = 0; + } + + if( !seq || !reader ) + CV_Error( CV_StsNullPtr, "" ); + + reader->header_size = sizeof( CvSeqReader ); + reader->seq = (CvSeq*)seq; + + first_block = seq->first; + + if( first_block ) + { + last_block = first_block->prev; + reader->ptr = first_block->data; + reader->prev_elem = CV_GET_LAST_ELEM( seq, last_block ); + reader->delta_index = seq->first->start_index; + + if( reverse ) + { + schar *temp = reader->ptr; + + reader->ptr = reader->prev_elem; + reader->prev_elem = temp; + + reader->block = last_block; + } + else + { + reader->block = first_block; + } + + reader->block_min = reader->block->data; + reader->block_max = reader->block_min + reader->block->count * seq->elem_size; + } + else + { + reader->delta_index = 0; + reader->block = 0; + + reader->ptr = reader->prev_elem = reader->block_min = reader->block_max = 0; + } +} + + +/* Change the current reading block + * to the previous or to the next: + */ +CV_IMPL void +cvChangeSeqBlock( void* _reader, int direction ) +{ + CvSeqReader* reader = (CvSeqReader*)_reader; + + if( !reader ) + CV_Error( CV_StsNullPtr, "" ); + + if( direction > 0 ) + { + reader->block = reader->block->next; + reader->ptr = reader->block->data; + } + else + { + reader->block = reader->block->prev; + reader->ptr = CV_GET_LAST_ELEM( reader->seq, reader->block ); + } + reader->block_min = reader->block->data; + reader->block_max = reader->block_min + reader->block->count * reader->seq->elem_size; +} + + +/* Return the current reader position: */ +CV_IMPL int +cvGetSeqReaderPos( CvSeqReader* reader ) +{ + int elem_size; + int index = -1; + + if( !reader || !reader->ptr ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = reader->seq->elem_size; + if( elem_size <= ICV_SHIFT_TAB_MAX && (index = icvPower2ShiftTab[elem_size - 1]) >= 0 ) + index = (int)((reader->ptr - reader->block_min) >> index); + else + index = (int)((reader->ptr - reader->block_min) / elem_size); + + index += reader->block->start_index - reader->delta_index; + + return index; +} + + +/* Set reader position to given position, + * either absolute or relative to the + * current one: + */ +CV_IMPL void +cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) +{ + CvSeqBlock *block; + int elem_size, count, total; + + if( !reader || !reader->seq ) + CV_Error( CV_StsNullPtr, "" ); + + total = reader->seq->total; + elem_size = reader->seq->elem_size; + + if( !is_relative ) + { + if( index < 0 ) + { + if( index < -total ) + CV_Error( CV_StsOutOfRange, "" ); + index += total; + } + else if( index >= total ) + { + index -= total; + if( index >= total ) + CV_Error( CV_StsOutOfRange, "" ); + } + + block = reader->seq->first; + if( index >= (count = block->count) ) + { + if( index + index <= total ) + { + do + { + block = block->next; + index -= count; + } + while( index >= (count = block->count) ); + } + else + { + do + { + block = block->prev; + total -= block->count; + } + while( index < total ); + index -= total; + } + } + reader->ptr = block->data + index * elem_size; + if( reader->block != block ) + { + reader->block = block; + reader->block_min = block->data; + reader->block_max = block->data + block->count * elem_size; + } + } + else + { + schar* ptr = reader->ptr; + index *= elem_size; + block = reader->block; + + if( index > 0 ) + { + while( ptr + index >= reader->block_max ) + { + int delta = (int)(reader->block_max - ptr); + index -= delta; + reader->block = block = block->next; + reader->block_min = ptr = block->data; + reader->block_max = block->data + block->count*elem_size; + } + reader->ptr = ptr + index; + } + else + { + while( ptr + index < reader->block_min ) + { + int delta = (int)(ptr - reader->block_min); + index += delta; + reader->block = block = block->prev; + reader->block_min = block->data; + reader->block_max = ptr = block->data + block->count*elem_size; + } + reader->ptr = ptr + index; + } + } +} + + +/* Push element onto the sequence: */ +CV_IMPL schar* +cvSeqPush( CvSeq *seq, const void *element ) +{ + schar *ptr = 0; + size_t elem_size; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = seq->elem_size; + ptr = seq->ptr; + + if( ptr >= seq->block_max ) + { + icvGrowSeq( seq, 0 ); + + ptr = seq->ptr; + assert( ptr + elem_size <= seq->block_max /*&& ptr == seq->block_min */ ); + } + + if( element ) + memcpy( ptr, element, elem_size ); + seq->first->prev->count++; + seq->total++; + seq->ptr = ptr + elem_size; + + return ptr; +} + + +/* Pop last element off of the sequence: */ +CV_IMPL void +cvSeqPop( CvSeq *seq, void *element ) +{ + schar *ptr; + int elem_size; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + if( seq->total <= 0 ) + CV_Error( CV_StsBadSize, "" ); + + elem_size = seq->elem_size; + seq->ptr = ptr = seq->ptr - elem_size; + + if( element ) + memcpy( element, ptr, elem_size ); + seq->ptr = ptr; + seq->total--; + + if( --(seq->first->prev->count) == 0 ) + { + icvFreeSeqBlock( seq, 0 ); + assert( seq->ptr == seq->block_max ); + } +} + + +/* Push element onto the front of the sequence: */ +CV_IMPL schar* +cvSeqPushFront( CvSeq *seq, const void *element ) +{ + schar* ptr = 0; + int elem_size; + CvSeqBlock *block; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = seq->elem_size; + block = seq->first; + + if( !block || block->start_index == 0 ) + { + icvGrowSeq( seq, 1 ); + + block = seq->first; + assert( block->start_index > 0 ); + } + + ptr = block->data -= elem_size; + + if( element ) + memcpy( ptr, element, elem_size ); + block->count++; + block->start_index--; + seq->total++; + + return ptr; +} + + +/* Shift out first element of the sequence: */ +CV_IMPL void +cvSeqPopFront( CvSeq *seq, void *element ) +{ + int elem_size; + CvSeqBlock *block; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + if( seq->total <= 0 ) + CV_Error( CV_StsBadSize, "" ); + + elem_size = seq->elem_size; + block = seq->first; + + if( element ) + memcpy( element, block->data, elem_size ); + block->data += elem_size; + block->start_index++; + seq->total--; + + if( --(block->count) == 0 ) + icvFreeSeqBlock( seq, 1 ); +} + +/* Insert new element in middle of sequence: */ +CV_IMPL schar* +cvSeqInsert( CvSeq *seq, int before_index, const void *element ) +{ + int elem_size; + int block_size; + CvSeqBlock *block; + int delta_index; + int total; + schar* ret_ptr = 0; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + + total = seq->total; + before_index += before_index < 0 ? total : 0; + before_index -= before_index > total ? total : 0; + + if( (unsigned)before_index > (unsigned)total ) + CV_Error( CV_StsOutOfRange, "" ); + + if( before_index == total ) + { + ret_ptr = cvSeqPush( seq, element ); + } + else if( before_index == 0 ) + { + ret_ptr = cvSeqPushFront( seq, element ); + } + else + { + elem_size = seq->elem_size; + + if( before_index >= total >> 1 ) + { + schar *ptr = seq->ptr + elem_size; + + if( ptr > seq->block_max ) + { + icvGrowSeq( seq, 0 ); + + ptr = seq->ptr + elem_size; + assert( ptr <= seq->block_max ); + } + + delta_index = seq->first->start_index; + block = seq->first->prev; + block->count++; + block_size = (int)(ptr - block->data); + + while( before_index < block->start_index - delta_index ) + { + CvSeqBlock *prev_block = block->prev; + + memmove( block->data + elem_size, block->data, block_size - elem_size ); + block_size = prev_block->count * elem_size; + memcpy( block->data, prev_block->data + block_size - elem_size, elem_size ); + block = prev_block; + + /* Check that we don't fall into an infinite loop: */ + assert( block != seq->first->prev ); + } + + before_index = (before_index - block->start_index + delta_index) * elem_size; + memmove( block->data + before_index + elem_size, block->data + before_index, + block_size - before_index - elem_size ); + + ret_ptr = block->data + before_index; + + if( element ) + memcpy( ret_ptr, element, elem_size ); + seq->ptr = ptr; + } + else + { + block = seq->first; + + if( block->start_index == 0 ) + { + icvGrowSeq( seq, 1 ); + + block = seq->first; + } + + delta_index = block->start_index; + block->count++; + block->start_index--; + block->data -= elem_size; + + while( before_index > block->start_index - delta_index + block->count ) + { + CvSeqBlock *next_block = block->next; + + block_size = block->count * elem_size; + memmove( block->data, block->data + elem_size, block_size - elem_size ); + memcpy( block->data + block_size - elem_size, next_block->data, elem_size ); + block = next_block; + + /* Check that we don't fall into an infinite loop: */ + assert( block != seq->first ); + } + + before_index = (before_index - block->start_index + delta_index) * elem_size; + memmove( block->data, block->data + elem_size, before_index - elem_size ); + + ret_ptr = block->data + before_index - elem_size; + + if( element ) + memcpy( ret_ptr, element, elem_size ); + } + + seq->total = total + 1; + } + + return ret_ptr; +} + + +/* Removes element from sequence: */ +CV_IMPL void +cvSeqRemove( CvSeq *seq, int index ) +{ + schar *ptr; + int elem_size; + int block_size; + CvSeqBlock *block; + int delta_index; + int total, front = 0; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + + total = seq->total; + + index += index < 0 ? total : 0; + index -= index >= total ? total : 0; + + if( (unsigned) index >= (unsigned) total ) + CV_Error( CV_StsOutOfRange, "Invalid index" ); + + if( index == total - 1 ) + { + cvSeqPop( seq, 0 ); + } + else if( index == 0 ) + { + cvSeqPopFront( seq, 0 ); + } + else + { + block = seq->first; + elem_size = seq->elem_size; + delta_index = block->start_index; + while( block->start_index - delta_index + block->count <= index ) + block = block->next; + + ptr = block->data + (index - block->start_index + delta_index) * elem_size; + + front = index < total >> 1; + if( !front ) + { + block_size = block->count * elem_size - (int)(ptr - block->data); + + while( block != seq->first->prev ) /* while not the last block */ + { + CvSeqBlock *next_block = block->next; + + memmove( ptr, ptr + elem_size, block_size - elem_size ); + memcpy( ptr + block_size - elem_size, next_block->data, elem_size ); + block = next_block; + ptr = block->data; + block_size = block->count * elem_size; + } + + memmove( ptr, ptr + elem_size, block_size - elem_size ); + seq->ptr -= elem_size; + } + else + { + ptr += elem_size; + block_size = (int)(ptr - block->data); + + while( block != seq->first ) + { + CvSeqBlock *prev_block = block->prev; + + memmove( block->data + elem_size, block->data, block_size - elem_size ); + block_size = prev_block->count * elem_size; + memcpy( block->data, prev_block->data + block_size - elem_size, elem_size ); + block = prev_block; + } + + memmove( block->data + elem_size, block->data, block_size - elem_size ); + block->data += elem_size; + block->start_index++; + } + + seq->total = total - 1; + if( --block->count == 0 ) + icvFreeSeqBlock( seq, front ); + } +} + + +/* Add several elements to the beginning or end of a sequence: */ +CV_IMPL void +cvSeqPushMulti( CvSeq *seq, const void *_elements, int count, int front ) +{ + char *elements = (char *) _elements; + + if( !seq ) + CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + if( count < 0 ) + CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + + int elem_size = seq->elem_size; + + if( !front ) + { + while( count > 0 ) + { + int delta = (int)((seq->block_max - seq->ptr) / elem_size); + + delta = MIN( delta, count ); + if( delta > 0 ) + { + seq->first->prev->count += delta; + seq->total += delta; + count -= delta; + delta *= elem_size; + if( elements ) + { + memcpy( seq->ptr, elements, delta ); + elements += delta; + } + seq->ptr += delta; + } + + if( count > 0 ) + icvGrowSeq( seq, 0 ); + } + } + else + { + CvSeqBlock* block = seq->first; + + while( count > 0 ) + { + int delta; + + if( !block || block->start_index == 0 ) + { + icvGrowSeq( seq, 1 ); + + block = seq->first; + assert( block->start_index > 0 ); + } + + delta = MIN( block->start_index, count ); + count -= delta; + block->start_index -= delta; + block->count += delta; + seq->total += delta; + delta *= elem_size; + block->data -= delta; + + if( elements ) + memcpy( block->data, elements + count*elem_size, delta ); + } + } +} + + +/* Remove several elements from the end of sequence: */ +CV_IMPL void +cvSeqPopMulti( CvSeq *seq, void *_elements, int count, int front ) +{ + char *elements = (char *) _elements; + + if( !seq ) + CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + if( count < 0 ) + CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + + count = MIN( count, seq->total ); + + if( !front ) + { + if( elements ) + elements += count * seq->elem_size; + + while( count > 0 ) + { + int delta = seq->first->prev->count; + + delta = MIN( delta, count ); + assert( delta > 0 ); + + seq->first->prev->count -= delta; + seq->total -= delta; + count -= delta; + delta *= seq->elem_size; + seq->ptr -= delta; + + if( elements ) + { + elements -= delta; + memcpy( elements, seq->ptr, delta ); + } + + if( seq->first->prev->count == 0 ) + icvFreeSeqBlock( seq, 0 ); + } + } + else + { + while( count > 0 ) + { + int delta = seq->first->count; + + delta = MIN( delta, count ); + assert( delta > 0 ); + + seq->first->count -= delta; + seq->total -= delta; + count -= delta; + seq->first->start_index += delta; + delta *= seq->elem_size; + + if( elements ) + { + memcpy( elements, seq->first->data, delta ); + elements += delta; + } + + seq->first->data += delta; + if( seq->first->count == 0 ) + icvFreeSeqBlock( seq, 1 ); + } + } +} + + +/* Remove all elements from a sequence: */ +CV_IMPL void +cvClearSeq( CvSeq *seq ) +{ + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + cvSeqPopMulti( seq, 0, seq->total ); +} + + +CV_IMPL CvSeq* +cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_data ) +{ + CvSeq* subseq = 0; + int elem_size, count, length; + CvSeqReader reader; + CvSeqBlock *block, *first_block = 0, *last_block = 0; + + if( !CV_IS_SEQ(seq) ) + CV_Error( CV_StsBadArg, "Invalid sequence header" ); + + if( !storage ) + { + storage = seq->storage; + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + } + + elem_size = seq->elem_size; + length = cvSliceLength( slice, seq ); + if( slice.start_index < 0 ) + slice.start_index += seq->total; + else if( slice.start_index >= seq->total ) + slice.start_index -= seq->total; + if( (unsigned)length > (unsigned)seq->total || + ((unsigned)slice.start_index >= (unsigned)seq->total && length != 0) ) + CV_Error( CV_StsOutOfRange, "Bad sequence slice" ); + + subseq = cvCreateSeq( seq->flags, seq->header_size, elem_size, storage ); + + if( length > 0 ) + { + cvStartReadSeq( seq, &reader, 0 ); + cvSetSeqReaderPos( &reader, slice.start_index, 0 ); + count = (int)((reader.block_max - reader.ptr)/elem_size); + + do + { + int bl = MIN( count, length ); + + if( !copy_data ) + { + block = (CvSeqBlock*)cvMemStorageAlloc( storage, sizeof(*block) ); + if( !first_block ) + { + first_block = subseq->first = block->prev = block->next = block; + block->start_index = 0; + } + else + { + block->prev = last_block; + block->next = first_block; + last_block->next = first_block->prev = block; + block->start_index = last_block->start_index + last_block->count; + } + last_block = block; + block->data = reader.ptr; + block->count = bl; + subseq->total += bl; + } + else + cvSeqPushMulti( subseq, reader.ptr, bl, 0 ); + length -= bl; + reader.block = reader.block->next; + reader.ptr = reader.block->data; + count = reader.block->count; + } + while( length > 0 ); + } + + return subseq; +} + + +// Remove slice from the middle of the sequence. +// !!! TODO !!! Implement more efficient algorithm +CV_IMPL void +cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) +{ + int total, length; + + if( !CV_IS_SEQ(seq) ) + CV_Error( CV_StsBadArg, "Invalid sequence header" ); + + length = cvSliceLength( slice, seq ); + total = seq->total; + + if( slice.start_index < 0 ) + slice.start_index += total; + else if( slice.start_index >= total ) + slice.start_index -= total; + + if( (unsigned)slice.start_index >= (unsigned)total ) + CV_Error( CV_StsOutOfRange, "start slice index is out of range" ); + + slice.end_index = slice.start_index + length; + + if( slice.end_index < total ) + { + CvSeqReader reader_to, reader_from; + int elem_size = seq->elem_size; + + cvStartReadSeq( seq, &reader_to ); + cvStartReadSeq( seq, &reader_from ); + + if( slice.start_index > total - slice.end_index ) + { + int i, count = seq->total - slice.end_index; + cvSetSeqReaderPos( &reader_to, slice.start_index ); + cvSetSeqReaderPos( &reader_from, slice.end_index ); + + for( i = 0; i < count; i++ ) + { + memcpy( reader_to.ptr, reader_from.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, reader_to ); + CV_NEXT_SEQ_ELEM( elem_size, reader_from ); + } + + cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index ); + } + else + { + int i, count = slice.start_index; + cvSetSeqReaderPos( &reader_to, slice.end_index ); + cvSetSeqReaderPos( &reader_from, slice.start_index ); + + for( i = 0; i < count; i++ ) + { + CV_PREV_SEQ_ELEM( elem_size, reader_to ); + CV_PREV_SEQ_ELEM( elem_size, reader_from ); + + memcpy( reader_to.ptr, reader_from.ptr, elem_size ); + } + + cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index, 1 ); + } + } + else + { + cvSeqPopMulti( seq, 0, total - slice.start_index ); + cvSeqPopMulti( seq, 0, slice.end_index - total, 1 ); + } +} + + +// Insert a sequence into the middle of another sequence: +// !!! TODO !!! Implement more efficient algorithm +CV_IMPL void +cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) +{ + CvSeqReader reader_to, reader_from; + int i, elem_size, total, from_total; + CvSeq from_header, *from = (CvSeq*)from_arr; + CvSeqBlock block; + + if( !CV_IS_SEQ(seq) ) + CV_Error( CV_StsBadArg, "Invalid destination sequence header" ); + + if( !CV_IS_SEQ(from)) + { + CvMat* mat = (CvMat*)from; + if( !CV_IS_MAT(mat)) + CV_Error( CV_StsBadArg, "Source is not a sequence nor matrix" ); + + if( !CV_IS_MAT_CONT(mat->type) || (mat->rows != 1 && mat->cols != 1) ) + CV_Error( CV_StsBadArg, "The source array must be 1d coninuous vector" ); + + from = cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(from_header), + CV_ELEM_SIZE(mat->type), + mat->data.ptr, mat->cols + mat->rows - 1, + &from_header, &block ); + } + + if( seq->elem_size != from->elem_size ) + CV_Error( CV_StsUnmatchedSizes, + "Source and destination sequence element sizes are different." ); + + from_total = from->total; + + if( from_total == 0 ) + return; + + total = seq->total; + index += index < 0 ? total : 0; + index -= index > total ? total : 0; + + if( (unsigned)index > (unsigned)total ) + CV_Error( CV_StsOutOfRange, "" ); + + elem_size = seq->elem_size; + + if( index < (total >> 1) ) + { + cvSeqPushMulti( seq, 0, from_total, 1 ); + + cvStartReadSeq( seq, &reader_to ); + cvStartReadSeq( seq, &reader_from ); + cvSetSeqReaderPos( &reader_from, from_total ); + + for( i = 0; i < index; i++ ) + { + memcpy( reader_to.ptr, reader_from.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, reader_to ); + CV_NEXT_SEQ_ELEM( elem_size, reader_from ); + } + } + else + { + cvSeqPushMulti( seq, 0, from_total ); + + cvStartReadSeq( seq, &reader_to ); + cvStartReadSeq( seq, &reader_from ); + cvSetSeqReaderPos( &reader_from, total ); + cvSetSeqReaderPos( &reader_to, seq->total ); + + for( i = 0; i < total - index; i++ ) + { + CV_PREV_SEQ_ELEM( elem_size, reader_to ); + CV_PREV_SEQ_ELEM( elem_size, reader_from ); + memcpy( reader_to.ptr, reader_from.ptr, elem_size ); + } + } + + cvStartReadSeq( from, &reader_from ); + cvSetSeqReaderPos( &reader_to, index ); + + for( i = 0; i < from_total; i++ ) + { + memcpy( reader_to.ptr, reader_from.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, reader_to ); + CV_NEXT_SEQ_ELEM( elem_size, reader_from ); + } +} + +// Sort the sequence using user-specified comparison function. +// The semantics is similar to qsort() function. +// The code is based on BSD system qsort(): +// * Copyright (c) 1992, 1993 +// * The Regents of the University of California. All rights reserved. +// * +// * Redistribution and use in source and binary forms, with or without +// * modification, are permitted provided that the following conditions +// * are met: +// * 1. Redistributions of source code must retain the above copyright +// * notice, this list of conditions and the following disclaimer. +// * 2. Redistributions in binary form must reproduce the above copyright +// * notice, this list of conditions and the following disclaimer in the +// * documentation and/or other materials provided with the distribution. +// * 3. All advertising materials mentioning features or use of this software +// * must display the following acknowledgement: +// * This product includes software developed by the University of +// * California, Berkeley and its contributors. +// * 4. Neither the name of the University nor the names of its contributors +// * may be used to endorse or promote products derived from this software +// * without specific prior written permission. +// * +// * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +// * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +// * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// * SUCH DAMAGE. + +typedef struct CvSeqReaderPos +{ + CvSeqBlock* block; + schar* ptr; + schar* block_min; + schar* block_max; +} +CvSeqReaderPos; + +#define CV_SAVE_READER_POS( reader, pos ) \ +{ \ + (pos).block = (reader).block; \ + (pos).ptr = (reader).ptr; \ + (pos).block_min = (reader).block_min; \ + (pos).block_max = (reader).block_max; \ +} + +#define CV_RESTORE_READER_POS( reader, pos )\ +{ \ + (reader).block = (pos).block; \ + (reader).ptr = (pos).ptr; \ + (reader).block_min = (pos).block_min; \ + (reader).block_max = (pos).block_max; \ +} + +inline schar* +icvMed3( schar* a, schar* b, schar* c, CvCmpFunc cmp_func, void* aux ) +{ + return cmp_func(a, b, aux) < 0 ? + (cmp_func(b, c, aux) < 0 ? b : cmp_func(a, c, aux) < 0 ? c : a) + :(cmp_func(b, c, aux) > 0 ? b : cmp_func(a, c, aux) < 0 ? a : c); +} + +CV_IMPL void +cvSeqSort( CvSeq* seq, CvCmpFunc cmp_func, void* aux ) +{ + int elem_size; + int isort_thresh = 7; + CvSeqReader left, right; + int sp = 0; + + struct + { + CvSeqReaderPos lb; + CvSeqReaderPos ub; + } + stack[48]; + + if( !CV_IS_SEQ(seq) ) + CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + + if( !cmp_func ) + CV_Error( CV_StsNullPtr, "Null compare function" ); + + if( seq->total <= 1 ) + return; + + elem_size = seq->elem_size; + isort_thresh *= elem_size; + + cvStartReadSeq( seq, &left, 0 ); + right = left; + CV_SAVE_READER_POS( left, stack[0].lb ); + CV_PREV_SEQ_ELEM( elem_size, right ); + CV_SAVE_READER_POS( right, stack[0].ub ); + + while( sp >= 0 ) + { + CV_RESTORE_READER_POS( left, stack[sp].lb ); + CV_RESTORE_READER_POS( right, stack[sp].ub ); + sp--; + + for(;;) + { + int i, n, m; + CvSeqReader ptr, ptr2; + + if( left.block == right.block ) + n = (int)(right.ptr - left.ptr) + elem_size; + else + { + n = cvGetSeqReaderPos( &right ); + n = (n - cvGetSeqReaderPos( &left ) + 1)*elem_size; + } + + if( n <= isort_thresh ) + { + insert_sort: + ptr = ptr2 = left; + CV_NEXT_SEQ_ELEM( elem_size, ptr ); + CV_NEXT_SEQ_ELEM( elem_size, right ); + while( ptr.ptr != right.ptr ) + { + ptr2.ptr = ptr.ptr; + if( ptr2.block != ptr.block ) + { + ptr2.block = ptr.block; + ptr2.block_min = ptr.block_min; + ptr2.block_max = ptr.block_max; + } + while( ptr2.ptr != left.ptr ) + { + schar* cur = ptr2.ptr; + CV_PREV_SEQ_ELEM( elem_size, ptr2 ); + if( cmp_func( ptr2.ptr, cur, aux ) <= 0 ) + break; + CV_SWAP_ELEMS( ptr2.ptr, cur, elem_size ); + } + CV_NEXT_SEQ_ELEM( elem_size, ptr ); + } + break; + } + else + { + CvSeqReader left0, left1, right0, right1; + CvSeqReader tmp0, tmp1; + schar *m1, *m2, *m3, *pivot; + int swap_cnt = 0; + int l, l0, l1, r, r0, r1; + + left0 = tmp0 = left; + right0 = right1 = right; + n /= elem_size; + + if( n > 40 ) + { + int d = n / 8; + schar *p1, *p2, *p3; + p1 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p2 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p3 = tmp0.ptr; + m1 = icvMed3( p1, p2, p3, cmp_func, aux ); + cvSetSeqReaderPos( &tmp0, (n/2) - d*3, 1 ); + p1 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p2 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p3 = tmp0.ptr; + m2 = icvMed3( p1, p2, p3, cmp_func, aux ); + cvSetSeqReaderPos( &tmp0, n - 1 - d*3 - n/2, 1 ); + p1 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p2 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, d, 1 ); + p3 = tmp0.ptr; + m3 = icvMed3( p1, p2, p3, cmp_func, aux ); + } + else + { + m1 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, n/2, 1 ); + m2 = tmp0.ptr; + cvSetSeqReaderPos( &tmp0, n - 1 - n/2, 1 ); + m3 = tmp0.ptr; + } + + pivot = icvMed3( m1, m2, m3, cmp_func, aux ); + left = left0; + if( pivot != left.ptr ) + { + CV_SWAP_ELEMS( pivot, left.ptr, elem_size ); + pivot = left.ptr; + } + CV_NEXT_SEQ_ELEM( elem_size, left ); + left1 = left; + + for(;;) + { + while( left.ptr != right.ptr && (r = cmp_func(left.ptr, pivot, aux)) <= 0 ) + { + if( r == 0 ) + { + if( left1.ptr != left.ptr ) + CV_SWAP_ELEMS( left1.ptr, left.ptr, elem_size ); + swap_cnt = 1; + CV_NEXT_SEQ_ELEM( elem_size, left1 ); + } + CV_NEXT_SEQ_ELEM( elem_size, left ); + } + + while( left.ptr != right.ptr && (r = cmp_func(right.ptr,pivot, aux)) >= 0 ) + { + if( r == 0 ) + { + if( right1.ptr != right.ptr ) + CV_SWAP_ELEMS( right1.ptr, right.ptr, elem_size ); + swap_cnt = 1; + CV_PREV_SEQ_ELEM( elem_size, right1 ); + } + CV_PREV_SEQ_ELEM( elem_size, right ); + } + + if( left.ptr == right.ptr ) + { + r = cmp_func(left.ptr, pivot, aux); + if( r == 0 ) + { + if( left1.ptr != left.ptr ) + CV_SWAP_ELEMS( left1.ptr, left.ptr, elem_size ); + swap_cnt = 1; + CV_NEXT_SEQ_ELEM( elem_size, left1 ); + } + if( r <= 0 ) + { + CV_NEXT_SEQ_ELEM( elem_size, left ); + } + else + { + CV_PREV_SEQ_ELEM( elem_size, right ); + } + break; + } + + CV_SWAP_ELEMS( left.ptr, right.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, left ); + r = left.ptr == right.ptr; + CV_PREV_SEQ_ELEM( elem_size, right ); + swap_cnt = 1; + if( r ) + break; + } + + if( swap_cnt == 0 ) + { + left = left0, right = right0; + goto insert_sort; + } + + l = cvGetSeqReaderPos( &left ); + if( l == 0 ) + l = seq->total; + l0 = cvGetSeqReaderPos( &left0 ); + l1 = cvGetSeqReaderPos( &left1 ); + if( l1 == 0 ) + l1 = seq->total; + + n = MIN( l - l1, l1 - l0 ); + if( n > 0 ) + { + tmp0 = left0; + tmp1 = left; + cvSetSeqReaderPos( &tmp1, 0-n, 1 ); + for( i = 0; i < n; i++ ) + { + CV_SWAP_ELEMS( tmp0.ptr, tmp1.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, tmp0 ); + CV_NEXT_SEQ_ELEM( elem_size, tmp1 ); + } + } + + r = cvGetSeqReaderPos( &right ); + r0 = cvGetSeqReaderPos( &right0 ); + r1 = cvGetSeqReaderPos( &right1 ); + m = MIN( r0 - r1, r1 - r ); + if( m > 0 ) + { + tmp0 = left; + tmp1 = right0; + cvSetSeqReaderPos( &tmp1, 1-m, 1 ); + for( i = 0; i < m; i++ ) + { + CV_SWAP_ELEMS( tmp0.ptr, tmp1.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, tmp0 ); + CV_NEXT_SEQ_ELEM( elem_size, tmp1 ); + } + } + + n = l - l1; + m = r1 - r; + if( n > 1 ) + { + if( m > 1 ) + { + if( n > m ) + { + sp++; + CV_SAVE_READER_POS( left0, stack[sp].lb ); + cvSetSeqReaderPos( &left0, n - 1, 1 ); + CV_SAVE_READER_POS( left0, stack[sp].ub ); + left = right = right0; + cvSetSeqReaderPos( &left, 1 - m, 1 ); + } + else + { + sp++; + CV_SAVE_READER_POS( right0, stack[sp].ub ); + cvSetSeqReaderPos( &right0, 1 - m, 1 ); + CV_SAVE_READER_POS( right0, stack[sp].lb ); + left = right = left0; + cvSetSeqReaderPos( &right, n - 1, 1 ); + } + } + else + { + left = right = left0; + cvSetSeqReaderPos( &right, n - 1, 1 ); + } + } + else if( m > 1 ) + { + left = right = right0; + cvSetSeqReaderPos( &left, 1 - m, 1 ); + } + else + break; + } + } + } +} + + +CV_IMPL schar* +cvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, + int is_sorted, int* _idx, void* userdata ) +{ + schar* result = 0; + const schar* elem = (const schar*)_elem; + int idx = -1; + int i, j; + + if( _idx ) + *_idx = idx; + + if( !CV_IS_SEQ(seq) ) + CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + + if( !elem ) + CV_Error( CV_StsNullPtr, "Null element pointer" ); + + int elem_size = seq->elem_size; + int total = seq->total; + + if( total == 0 ) + return 0; + + if( !is_sorted ) + { + CvSeqReader reader; + cvStartReadSeq( seq, &reader, 0 ); + + if( cmp_func ) + { + for( i = 0; i < total; i++ ) + { + if( cmp_func( elem, reader.ptr, userdata ) == 0 ) + break; + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + else if( (elem_size & (sizeof(int)-1)) == 0 ) + { + for( i = 0; i < total; i++ ) + { + for( j = 0; j < elem_size; j += sizeof(int) ) + { + if( *(const int*)(reader.ptr + j) != *(const int*)(elem + j) ) + break; + } + if( j == elem_size ) + break; + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + else + { + for( i = 0; i < total; i++ ) + { + for( j = 0; j < elem_size; j++ ) + { + if( reader.ptr[j] != elem[j] ) + break; + } + if( j == elem_size ) + break; + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + + idx = i; + if( i < total ) + result = reader.ptr; + } + else + { + if( !cmp_func ) + CV_Error( CV_StsNullPtr, "Null compare function" ); + + i = 0, j = total; + + while( j > i ) + { + int k = (i+j)>>1, code; + schar* ptr = cvGetSeqElem( seq, k ); + code = cmp_func( elem, ptr, userdata ); + if( !code ) + { + result = ptr; + idx = k; + if( _idx ) + *_idx = idx; + return result; + } + if( code < 0 ) + j = k; + else + i = k+1; + } + idx = j; + } + + if( _idx ) + *_idx = idx; + + return result; +} + + +CV_IMPL void +cvSeqInvert( CvSeq* seq ) +{ + CvSeqReader left_reader, right_reader; + int elem_size; + int i, count; + + cvStartReadSeq( seq, &left_reader, 0 ); + cvStartReadSeq( seq, &right_reader, 1 ); + elem_size = seq->elem_size; + count = seq->total >> 1; + + for( i = 0; i < count; i++ ) + { + CV_SWAP_ELEMS( left_reader.ptr, right_reader.ptr, elem_size ); + CV_NEXT_SEQ_ELEM( elem_size, left_reader ); + CV_PREV_SEQ_ELEM( elem_size, right_reader ); + } +} + + +typedef struct CvPTreeNode +{ + struct CvPTreeNode* parent; + schar* element; + int rank; +} +CvPTreeNode; + + +// This function splits the input sequence or set into one or more equivalence classes. +// is_equal(a,b,...) returns non-zero if the two sequence elements +// belong to the same class. The function returns sequence of integers - +// 0-based class indexes for each element. +// +// The algorithm is described in "Introduction to Algorithms" +// by Cormen, Leiserson and Rivest, chapter "Data structures for disjoint sets" +CV_IMPL int +cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, + CvCmpFunc is_equal, void* userdata ) +{ + CvSeq* result = 0; + CvMemStorage* temp_storage = 0; + int class_idx = 0; + + CvSeqWriter writer; + CvSeqReader reader, reader0; + CvSeq* nodes; + int i, j; + int is_set; + + if( !labels ) + CV_Error( CV_StsNullPtr, "" ); + + if( !seq || !is_equal ) + CV_Error( CV_StsNullPtr, "" ); + + if( !storage ) + storage = seq->storage; + + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + is_set = CV_IS_SET(seq); + + temp_storage = cvCreateChildMemStorage( storage ); + + nodes = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPTreeNode), temp_storage ); + + cvStartReadSeq( seq, &reader ); + memset( &writer, 0, sizeof(writer)); + cvStartAppendToSeq( nodes, &writer ); + + // Initial O(N) pass. Make a forest of single-vertex trees. + for( i = 0; i < seq->total; i++ ) + { + CvPTreeNode node = { 0, 0, 0 }; + if( !is_set || CV_IS_SET_ELEM( reader.ptr )) + node.element = reader.ptr; + CV_WRITE_SEQ_ELEM( node, writer ); + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + } + + cvEndWriteSeq( &writer ); + + // Because in the next loop we will iterate + // through all the sequence nodes each time, + // we do not need to initialize reader every time: + cvStartReadSeq( nodes, &reader ); + cvStartReadSeq( nodes, &reader0 ); + + // The main O(N^2) pass. Merge connected components. + for( i = 0; i < nodes->total; i++ ) + { + CvPTreeNode* node = (CvPTreeNode*)(reader0.ptr); + CvPTreeNode* root = node; + CV_NEXT_SEQ_ELEM( nodes->elem_size, reader0 ); + + if( !node->element ) + continue; + + // find root + while( root->parent ) + root = root->parent; + + for( j = 0; j < nodes->total; j++ ) + { + CvPTreeNode* node2 = (CvPTreeNode*)reader.ptr; + + if( node2->element && node2 != node && + is_equal( node->element, node2->element, userdata )) + { + CvPTreeNode* root2 = node2; + + // unite both trees + while( root2->parent ) + root2 = root2->parent; + + if( root2 != root ) + { + if( root->rank > root2->rank ) + root2->parent = root; + else + { + root->parent = root2; + root2->rank += root->rank == root2->rank; + root = root2; + } + assert( root->parent == 0 ); + + // Compress path from node2 to the root: + while( node2->parent ) + { + CvPTreeNode* temp = node2; + node2 = node2->parent; + temp->parent = root; + } + + // Compress path from node to the root: + node2 = node; + while( node2->parent ) + { + CvPTreeNode* temp = node2; + node2 = node2->parent; + temp->parent = root; + } + } + } + + CV_NEXT_SEQ_ELEM( sizeof(*node), reader ); + } + } + + // Final O(N) pass (Enumerate classes) + // Reuse reader one more time + result = cvCreateSeq( 0, sizeof(CvSeq), sizeof(int), storage ); + cvStartAppendToSeq( result, &writer ); + + for( i = 0; i < nodes->total; i++ ) + { + CvPTreeNode* node = (CvPTreeNode*)reader.ptr; + int idx = -1; + + if( node->element ) + { + while( node->parent ) + node = node->parent; + if( node->rank >= 0 ) + node->rank = ~class_idx++; + idx = ~node->rank; + } + + CV_NEXT_SEQ_ELEM( sizeof(*node), reader ); + CV_WRITE_SEQ_ELEM( idx, writer ); + } + + cvEndWriteSeq( &writer ); + + if( labels ) + *labels = result; + + cvReleaseMemStorage( &temp_storage ); + return class_idx; +} + + +/****************************************************************************************\ +* Set implementation * +\****************************************************************************************/ + +/* Creates empty set: */ +CV_IMPL CvSet* +cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage * storage ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + if( header_size < (int)sizeof( CvSet ) || + elem_size < (int)sizeof(void*)*2 || + (elem_size & (sizeof(void*)-1)) != 0 ) + CV_Error( CV_StsBadSize, "" ); + + CvSet* set = (CvSet*) cvCreateSeq( set_flags, header_size, elem_size, storage ); + set->flags = (set->flags & ~CV_MAGIC_MASK) | CV_SET_MAGIC_VAL; + + return set; +} + + +/* Add new element to the set: */ +CV_IMPL int +cvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element ) +{ + int id = -1; + CvSetElem *free_elem; + + if( !set ) + CV_Error( CV_StsNullPtr, "" ); + + if( !(set->free_elems) ) + { + int count = set->total; + int elem_size = set->elem_size; + schar *ptr; + icvGrowSeq( (CvSeq *) set, 0 ); + + set->free_elems = (CvSetElem*) (ptr = set->ptr); + for( ; ptr + elem_size <= set->block_max; ptr += elem_size, count++ ) + { + ((CvSetElem*)ptr)->flags = count | CV_SET_ELEM_FREE_FLAG; + ((CvSetElem*)ptr)->next_free = (CvSetElem*)(ptr + elem_size); + } + assert( count <= CV_SET_ELEM_IDX_MASK+1 ); + ((CvSetElem*)(ptr - elem_size))->next_free = 0; + set->first->prev->count += count - set->total; + set->total = count; + set->ptr = set->block_max; + } + + free_elem = set->free_elems; + set->free_elems = free_elem->next_free; + + id = free_elem->flags & CV_SET_ELEM_IDX_MASK; + if( element ) + memcpy( free_elem, element, set->elem_size ); + + free_elem->flags = id; + set->active_count++; + + if( inserted_element ) + *inserted_element = free_elem; + + return id; +} + + +/* Remove element from a set given element index: */ +CV_IMPL void +cvSetRemove( CvSet* set, int index ) +{ + CvSetElem* elem = cvGetSetElem( set, index ); + if( elem ) + cvSetRemoveByPtr( set, elem ); + else if( !set ) + CV_Error( CV_StsNullPtr, "" ); +} + + +/* Remove all elements from a set: */ +CV_IMPL void +cvClearSet( CvSet* set ) +{ + cvClearSeq( (CvSeq*)set ); + set->free_elems = 0; + set->active_count = 0; +} + + +/****************************************************************************************\ +* Graph implementation * +\****************************************************************************************/ + +/* Create a new graph: */ +CV_IMPL CvGraph * +cvCreateGraph( int graph_type, int header_size, + int vtx_size, int edge_size, CvMemStorage * storage ) +{ + CvGraph *graph = 0; + CvSet *edges = 0; + CvSet *vertices = 0; + + if( header_size < (int) sizeof( CvGraph ) + || edge_size < (int) sizeof( CvGraphEdge ) + || vtx_size < (int) sizeof( CvGraphVtx ) + ){ + CV_Error( CV_StsBadSize, "" ); + } + + vertices = cvCreateSet( graph_type, header_size, vtx_size, storage ); + edges = cvCreateSet( CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_GRAPH_EDGE, + sizeof( CvSet ), edge_size, storage ); + + graph = (CvGraph*)vertices; + graph->edges = edges; + + return graph; +} + + +/* Remove all vertices and edges from a graph: */ +CV_IMPL void +cvClearGraph( CvGraph * graph ) +{ + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + cvClearSet( graph->edges ); + cvClearSet( (CvSet*)graph ); +} + + +/* Add a vertex to a graph: */ +CV_IMPL int +cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted_vertex ) +{ + CvGraphVtx *vertex = 0; + int index = -1; + + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + vertex = (CvGraphVtx*)cvSetNew((CvSet*)graph); + if( vertex ) + { + if( _vertex ) + memcpy( vertex + 1, _vertex + 1, graph->elem_size - sizeof(CvGraphVtx) ); + vertex->first = 0; + index = vertex->flags; + } + + if( _inserted_vertex ) + *_inserted_vertex = vertex; + + return index; +} + + +/* Remove a vertex from the graph together with its incident edges: */ +CV_IMPL int +cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) +{ + int count = -1; + + if( !graph || !vtx ) + CV_Error( CV_StsNullPtr, "" ); + + if( !CV_IS_SET_ELEM(vtx)) + CV_Error( CV_StsBadArg, "The vertex does not belong to the graph" ); + + count = graph->edges->active_count; + for( ;; ) + { + CvGraphEdge *edge = vtx->first; + if( !edge ) + break; + cvGraphRemoveEdgeByPtr( graph, edge->vtx[0], edge->vtx[1] ); + } + count -= graph->edges->active_count; + cvSetRemoveByPtr( (CvSet*)graph, vtx ); + + return count; +} + + +/* Remove a vertex from the graph together with its incident edges: */ +CV_IMPL int +cvGraphRemoveVtx( CvGraph* graph, int index ) +{ + int count = -1; + CvGraphVtx *vtx = 0; + + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + vtx = cvGetGraphVtx( graph, index ); + if( !vtx ) + CV_Error( CV_StsBadArg, "The vertex is not found" ); + + count = graph->edges->active_count; + for( ;; ) + { + CvGraphEdge *edge = vtx->first; + count++; + + if( !edge ) + break; + cvGraphRemoveEdgeByPtr( graph, edge->vtx[0], edge->vtx[1] ); + } + count -= graph->edges->active_count; + cvSetRemoveByPtr( (CvSet*)graph, vtx ); + + return count; +} + + +/* Find a graph edge given pointers to the ending vertices: */ +CV_IMPL CvGraphEdge* +cvFindGraphEdgeByPtr( const CvGraph* graph, + const CvGraphVtx* start_vtx, + const CvGraphVtx* end_vtx ) +{ + int ofs = 0; + + if( !graph || !start_vtx || !end_vtx ) + CV_Error( CV_StsNullPtr, "" ); + + if( start_vtx == end_vtx ) + return 0; + + if( !CV_IS_GRAPH_ORIENTED( graph ) && + (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) + { + const CvGraphVtx* t; + CV_SWAP( start_vtx, end_vtx, t ); + } + + CvGraphEdge* edge = start_vtx->first; + for( ; edge; edge = edge->next[ofs] ) + { + ofs = start_vtx == edge->vtx[1]; + assert( ofs == 1 || start_vtx == edge->vtx[0] ); + if( edge->vtx[1] == end_vtx ) + break; + } + + return edge; +} + + +/* Find an edge in the graph given indices of the ending vertices: */ +CV_IMPL CvGraphEdge * +cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) +{ + CvGraphVtx *start_vtx; + CvGraphVtx *end_vtx; + + if( !graph ) + CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + + start_vtx = cvGetGraphVtx( graph, start_idx ); + end_vtx = cvGetGraphVtx( graph, end_idx ); + + return cvFindGraphEdgeByPtr( graph, start_vtx, end_vtx ); +} + + +/* Given two vertices, return the edge + * connecting them, creating it if it + * did not already exist: + */ +CV_IMPL int +cvGraphAddEdgeByPtr( CvGraph* graph, + CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, + const CvGraphEdge* _edge, + CvGraphEdge ** _inserted_edge ) +{ + CvGraphEdge *edge = 0; + int result = -1; + int delta; + + if( !graph ) + CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + + if( !CV_IS_GRAPH_ORIENTED( graph ) && + (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) + { + CvGraphVtx* t; + CV_SWAP( start_vtx, end_vtx, t ); + } + + edge = cvFindGraphEdgeByPtr( graph, start_vtx, end_vtx ); + if( edge ) + { + result = 0; + if( _inserted_edge ) + *_inserted_edge = edge; + return result; + } + + if( start_vtx == end_vtx ) + CV_Error( start_vtx ? CV_StsBadArg : CV_StsNullPtr, + "vertex pointers coinside (or set to NULL)" ); + + edge = (CvGraphEdge*)cvSetNew( (CvSet*)(graph->edges) ); + assert( edge->flags >= 0 ); + + edge->vtx[0] = start_vtx; + edge->vtx[1] = end_vtx; + edge->next[0] = start_vtx->first; + edge->next[1] = end_vtx->first; + start_vtx->first = end_vtx->first = edge; + + delta = graph->edges->elem_size - sizeof(*edge); + if( _edge ) + { + if( delta > 0 ) + memcpy( edge + 1, _edge + 1, delta ); + edge->weight = _edge->weight; + } + else + { + if( delta > 0 ) + memset( edge + 1, 0, delta ); + edge->weight = 1.f; + } + + result = 1; + + if( _inserted_edge ) + *_inserted_edge = edge; + + return result; +} + +/* Given two vertices, return the edge + * connecting them, creating it if it + * did not already exist: + */ +CV_IMPL int +cvGraphAddEdge( CvGraph* graph, + int start_idx, int end_idx, + const CvGraphEdge* _edge, + CvGraphEdge ** _inserted_edge ) +{ + CvGraphVtx *start_vtx; + CvGraphVtx *end_vtx; + + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + start_vtx = cvGetGraphVtx( graph, start_idx ); + end_vtx = cvGetGraphVtx( graph, end_idx ); + + return cvGraphAddEdgeByPtr( graph, start_vtx, end_vtx, _edge, _inserted_edge ); +} + + +/* Remove the graph edge connecting two given vertices: */ +CV_IMPL void +cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ) +{ + int ofs, prev_ofs; + CvGraphEdge *edge, *next_edge, *prev_edge; + + if( !graph || !start_vtx || !end_vtx ) + CV_Error( CV_StsNullPtr, "" ); + + if( start_vtx == end_vtx ) + return; + + if( !CV_IS_GRAPH_ORIENTED( graph ) && + (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) + { + CvGraphVtx* t; + CV_SWAP( start_vtx, end_vtx, t ); + } + + for( ofs = prev_ofs = 0, prev_edge = 0, edge = start_vtx->first; edge != 0; + prev_ofs = ofs, prev_edge = edge, edge = edge->next[ofs] ) + { + ofs = start_vtx == edge->vtx[1]; + assert( ofs == 1 || start_vtx == edge->vtx[0] ); + if( edge->vtx[1] == end_vtx ) + break; + } + + if( !edge ) + return; + + next_edge = edge->next[ofs]; + if( prev_edge ) + prev_edge->next[prev_ofs] = next_edge; + else + start_vtx->first = next_edge; + + for( ofs = prev_ofs = 0, prev_edge = 0, edge = end_vtx->first; edge != 0; + prev_ofs = ofs, prev_edge = edge, edge = edge->next[ofs] ) + { + ofs = end_vtx == edge->vtx[1]; + assert( ofs == 1 || end_vtx == edge->vtx[0] ); + if( edge->vtx[0] == start_vtx ) + break; + } + + assert( edge != 0 ); + + next_edge = edge->next[ofs]; + if( prev_edge ) + prev_edge->next[prev_ofs] = next_edge; + else + end_vtx->first = next_edge; + + cvSetRemoveByPtr( graph->edges, edge ); +} + + +/* Remove the graph edge connecting two given vertices: */ +CV_IMPL void +cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) +{ + CvGraphVtx *start_vtx; + CvGraphVtx *end_vtx; + + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + start_vtx = cvGetGraphVtx( graph, start_idx ); + end_vtx = cvGetGraphVtx( graph, end_idx ); + + cvGraphRemoveEdgeByPtr( graph, start_vtx, end_vtx ); +} + + +/* Count number of edges incident to a given vertex: */ +CV_IMPL int +cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vertex ) +{ + CvGraphEdge *edge; + int count; + + if( !graph || !vertex ) + CV_Error( CV_StsNullPtr, "" ); + + for( edge = vertex->first, count = 0; edge; ) + { + count++; + edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); + } + + return count; +} + + +/* Count number of edges incident to a given vertex: */ +CV_IMPL int +cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ) +{ + CvGraphVtx *vertex; + CvGraphEdge *edge; + int count; + + if( !graph ) + CV_Error( CV_StsNullPtr, "" ); + + vertex = cvGetGraphVtx( graph, vtx_idx ); + if( !vertex ) + CV_Error( CV_StsObjectNotFound, "" ); + + for( edge = vertex->first, count = 0; edge; ) + { + count++; + edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); + } + + return count; +} + + +typedef struct CvGraphItem +{ + CvGraphVtx* vtx; + CvGraphEdge* edge; +} +CvGraphItem; + + +static void +icvSeqElemsClearFlags( CvSeq* seq, int offset, int clear_mask ) +{ + CvSeqReader reader; + int i, total, elem_size; + + if( !seq ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = seq->elem_size; + total = seq->total; + + if( (unsigned)offset > (unsigned)elem_size ) + CV_Error( CV_StsBadArg, "" ); + + cvStartReadSeq( seq, &reader ); + + for( i = 0; i < total; i++ ) + { + int* flag_ptr = (int*)(reader.ptr + offset); + *flag_ptr &= ~clear_mask; + + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } +} + + +static schar* +icvSeqFindNextElem( CvSeq* seq, int offset, int mask, + int value, int* start_index ) +{ + schar* elem_ptr = 0; + + CvSeqReader reader; + int total, elem_size, index; + + if( !seq || !start_index ) + CV_Error( CV_StsNullPtr, "" ); + + elem_size = seq->elem_size; + total = seq->total; + index = *start_index; + + if( (unsigned)offset > (unsigned)elem_size ) + CV_Error( CV_StsBadArg, "" ); + + if( total == 0 ) + return 0; + + if( (unsigned)index >= (unsigned)total ) + { + index %= total; + index += index < 0 ? total : 0; + } + + cvStartReadSeq( seq, &reader ); + + if( index != 0 ) + cvSetSeqReaderPos( &reader, index ); + + for( index = 0; index < total; index++ ) + { + int* flag_ptr = (int*)(reader.ptr + offset); + if( (*flag_ptr & mask) == value ) + break; + + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + + if( index < total ) + { + elem_ptr = reader.ptr; + *start_index = index; + } + + return elem_ptr; +} + +#define CV_FIELD_OFFSET( field, structtype ) ((int)(size_t)&((structtype*)0)->field) + +CV_IMPL CvGraphScanner* +cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx, int mask ) +{ + if( !graph ) + CV_Error( CV_StsNullPtr, "Null graph pointer" ); + + CV_Assert( graph->storage != 0 ); + + CvGraphScanner* scanner = (CvGraphScanner*)cvAlloc( sizeof(*scanner) ); + memset( scanner, 0, sizeof(*scanner)); + + scanner->graph = graph; + scanner->mask = mask; + scanner->vtx = vtx; + scanner->index = vtx == 0 ? 0 : -1; + + CvMemStorage* child_storage = cvCreateChildMemStorage( graph->storage ); + + scanner->stack = cvCreateSeq( 0, sizeof(CvSet), + sizeof(CvGraphItem), child_storage ); + + icvSeqElemsClearFlags( (CvSeq*)graph, + CV_FIELD_OFFSET( flags, CvGraphVtx), + CV_GRAPH_ITEM_VISITED_FLAG| + CV_GRAPH_SEARCH_TREE_NODE_FLAG ); + + icvSeqElemsClearFlags( (CvSeq*)(graph->edges), + CV_FIELD_OFFSET( flags, CvGraphEdge), + CV_GRAPH_ITEM_VISITED_FLAG ); + + return scanner; +} + + +CV_IMPL void +cvReleaseGraphScanner( CvGraphScanner** scanner ) +{ + if( !scanner ) + CV_Error( CV_StsNullPtr, "Null double pointer to graph scanner" ); + + if( *scanner ) + { + if( (*scanner)->stack ) + cvReleaseMemStorage( &((*scanner)->stack->storage)); + cvFree( scanner ); + } +} + + +CV_IMPL int +cvNextGraphItem( CvGraphScanner* scanner ) +{ + int code = -1; + CvGraphVtx* vtx; + CvGraphVtx* dst; + CvGraphEdge* edge; + CvGraphItem item; + + if( !scanner || !(scanner->stack)) + CV_Error( CV_StsNullPtr, "Null graph scanner" ); + + dst = scanner->dst; + vtx = scanner->vtx; + edge = scanner->edge; + + for(;;) + { + for(;;) + { + if( dst && !CV_IS_GRAPH_VERTEX_VISITED(dst) ) + { + scanner->vtx = vtx = dst; + edge = vtx->first; + dst->flags |= CV_GRAPH_ITEM_VISITED_FLAG; + + if((scanner->mask & CV_GRAPH_VERTEX)) + { + scanner->vtx = vtx; + scanner->edge = vtx->first; + scanner->dst = 0; + code = CV_GRAPH_VERTEX; + return code; + } + } + + while( edge ) + { + dst = edge->vtx[vtx == edge->vtx[0]]; + + if( !CV_IS_GRAPH_EDGE_VISITED(edge) ) + { + // Check that the edge is outgoing: + if( !CV_IS_GRAPH_ORIENTED( scanner->graph ) || dst != edge->vtx[0] ) + { + edge->flags |= CV_GRAPH_ITEM_VISITED_FLAG; + + if( !CV_IS_GRAPH_VERTEX_VISITED(dst) ) + { + item.vtx = vtx; + item.edge = edge; + + vtx->flags |= CV_GRAPH_SEARCH_TREE_NODE_FLAG; + + cvSeqPush( scanner->stack, &item ); + + if( scanner->mask & CV_GRAPH_TREE_EDGE ) + { + code = CV_GRAPH_TREE_EDGE; + scanner->vtx = vtx; + scanner->dst = dst; + scanner->edge = edge; + return code; + } + break; + } + else + { + if( scanner->mask & (CV_GRAPH_BACK_EDGE| + CV_GRAPH_CROSS_EDGE| + CV_GRAPH_FORWARD_EDGE) ) + { + code = (dst->flags & CV_GRAPH_SEARCH_TREE_NODE_FLAG) ? + CV_GRAPH_BACK_EDGE : + (edge->flags & CV_GRAPH_FORWARD_EDGE_FLAG) ? + CV_GRAPH_FORWARD_EDGE : CV_GRAPH_CROSS_EDGE; + edge->flags &= ~CV_GRAPH_FORWARD_EDGE_FLAG; + if( scanner->mask & code ) + { + scanner->vtx = vtx; + scanner->dst = dst; + scanner->edge = edge; + return code; + } + } + } + } + else if( (dst->flags & (CV_GRAPH_ITEM_VISITED_FLAG| + CV_GRAPH_SEARCH_TREE_NODE_FLAG)) == + (CV_GRAPH_ITEM_VISITED_FLAG| + CV_GRAPH_SEARCH_TREE_NODE_FLAG)) + { + edge->flags |= CV_GRAPH_FORWARD_EDGE_FLAG; + } + } + + edge = CV_NEXT_GRAPH_EDGE( edge, vtx ); + } + + if( !edge ) /* need to backtrack */ + { + if( scanner->stack->total == 0 ) + { + if( scanner->index >= 0 ) + vtx = 0; + else + scanner->index = 0; + break; + } + cvSeqPop( scanner->stack, &item ); + vtx = item.vtx; + vtx->flags &= ~CV_GRAPH_SEARCH_TREE_NODE_FLAG; + edge = item.edge; + dst = 0; + + if( scanner->mask & CV_GRAPH_BACKTRACKING ) + { + scanner->vtx = vtx; + scanner->edge = edge; + scanner->dst = edge->vtx[vtx == edge->vtx[0]]; + code = CV_GRAPH_BACKTRACKING; + return code; + } + } + } + + if( !vtx ) + { + vtx = (CvGraphVtx*)icvSeqFindNextElem( (CvSeq*)(scanner->graph), + CV_FIELD_OFFSET( flags, CvGraphVtx ), CV_GRAPH_ITEM_VISITED_FLAG|INT_MIN, + 0, &(scanner->index) ); + + if( !vtx ) + { + code = CV_GRAPH_OVER; + break; + } + } + + dst = vtx; + if( scanner->mask & CV_GRAPH_NEW_TREE ) + { + scanner->dst = dst; + scanner->edge = 0; + scanner->vtx = 0; + code = CV_GRAPH_NEW_TREE; + break; + } + } + + return code; +} + + +CV_IMPL CvGraph* +cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) +{ + int* flag_buffer = 0; + CvGraphVtx** ptr_buffer = 0; + CvGraph* result = 0; + + int i, k; + int vtx_size, edge_size; + CvSeqReader reader; + + if( !CV_IS_GRAPH(graph)) + CV_Error( CV_StsBadArg, "Invalid graph pointer" ); + + if( !storage ) + storage = graph->storage; + + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + + vtx_size = graph->elem_size; + edge_size = graph->edges->elem_size; + + flag_buffer = (int*)cvAlloc( graph->total*sizeof(flag_buffer[0])); + ptr_buffer = (CvGraphVtx**)cvAlloc( graph->total*sizeof(ptr_buffer[0])); + result = cvCreateGraph( graph->flags, graph->header_size, + vtx_size, edge_size, storage ); + memcpy( result + sizeof(CvGraph), graph + sizeof(CvGraph), + graph->header_size - sizeof(CvGraph)); + + // Pass 1. Save flags, copy vertices: + cvStartReadSeq( (CvSeq*)graph, &reader ); + for( i = 0, k = 0; i < graph->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + CvGraphVtx* vtx = (CvGraphVtx*)reader.ptr; + CvGraphVtx* dstvtx = 0; + cvGraphAddVtx( result, vtx, &dstvtx ); + flag_buffer[k] = dstvtx->flags = vtx->flags; + vtx->flags = k; + ptr_buffer[k++] = dstvtx; + } + CV_NEXT_SEQ_ELEM( vtx_size, reader ); + } + + // Pass 2. Copy edges: + cvStartReadSeq( (CvSeq*)graph->edges, &reader ); + for( i = 0; i < graph->edges->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + CvGraphEdge* edge = (CvGraphEdge*)reader.ptr; + CvGraphEdge* dstedge = 0; + CvGraphVtx* new_org = ptr_buffer[edge->vtx[0]->flags]; + CvGraphVtx* new_dst = ptr_buffer[edge->vtx[1]->flags]; + cvGraphAddEdgeByPtr( result, new_org, new_dst, edge, &dstedge ); + dstedge->flags = edge->flags; + } + CV_NEXT_SEQ_ELEM( edge_size, reader ); + } + + // Pass 3. Restore flags: + cvStartReadSeq( (CvSeq*)graph, &reader ); + for( i = 0, k = 0; i < graph->edges->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + CvGraphVtx* vtx = (CvGraphVtx*)reader.ptr; + vtx->flags = flag_buffer[k++]; + } + CV_NEXT_SEQ_ELEM( vtx_size, reader ); + } + + cvFree( &flag_buffer ); + cvFree( &ptr_buffer ); + + if( cvGetErrStatus() < 0 ) + result = 0; + + return result; +} + + +/****************************************************************************************\ +* Working with sequence tree * +\****************************************************************************************/ + +// Gather pointers to all the sequences, accessible from the , to the single sequence. +CV_IMPL CvSeq* +cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) +{ + CvSeq* allseq = 0; + CvTreeNodeIterator iterator; + + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + + allseq = cvCreateSeq( 0, header_size, sizeof(first), storage ); + + if( first ) + { + cvInitTreeNodeIterator( &iterator, first, INT_MAX ); + + for(;;) + { + void* node = cvNextTreeNode( &iterator ); + if( !node ) + break; + cvSeqPush( allseq, &node ); + } + } + + + + return allseq; +} + + +typedef struct CvTreeNode +{ + int flags; /* micsellaneous flags */ + int header_size; /* size of sequence header */ + struct CvTreeNode* h_prev; /* previous sequence */ + struct CvTreeNode* h_next; /* next sequence */ + struct CvTreeNode* v_prev; /* 2nd previous sequence */ + struct CvTreeNode* v_next; /* 2nd next sequence */ +} +CvTreeNode; + + + +// Insert contour into tree given certain parent sequence. +// If parent is equal to frame (the most external contour), +// then added contour will have null pointer to parent: +CV_IMPL void +cvInsertNodeIntoTree( void* _node, void* _parent, void* _frame ) +{ + CvTreeNode* node = (CvTreeNode*)_node; + CvTreeNode* parent = (CvTreeNode*)_parent; + + if( !node || !parent ) + CV_Error( CV_StsNullPtr, "" ); + + node->v_prev = _parent != _frame ? parent : 0; + node->h_next = parent->v_next; + + assert( parent->v_next != node ); + + if( parent->v_next ) + parent->v_next->h_prev = node; + parent->v_next = node; +} + + +// Remove contour from tree, together with the contour's children: +CV_IMPL void +cvRemoveNodeFromTree( void* _node, void* _frame ) +{ + CvTreeNode* node = (CvTreeNode*)_node; + CvTreeNode* frame = (CvTreeNode*)_frame; + + if( !node ) + CV_Error( CV_StsNullPtr, "" ); + + if( node == frame ) + CV_Error( CV_StsBadArg, "frame node could not be deleted" ); + + if( node->h_next ) + node->h_next->h_prev = node->h_prev; + + if( node->h_prev ) + node->h_prev->h_next = node->h_next; + else + { + CvTreeNode* parent = node->v_prev; + if( !parent ) + parent = frame; + + if( parent ) + { + assert( parent->v_next == node ); + parent->v_next = node->h_next; + } + } +} + + +CV_IMPL void +cvInitTreeNodeIterator( CvTreeNodeIterator* treeIterator, + const void* first, int max_level ) +{ + if( !treeIterator || !first ) + CV_Error( CV_StsNullPtr, "" ); + + if( max_level < 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + treeIterator->node = (void*)first; + treeIterator->level = 0; + treeIterator->max_level = max_level; +} + + +CV_IMPL void* +cvNextTreeNode( CvTreeNodeIterator* treeIterator ) +{ + CvTreeNode* prevNode = 0; + CvTreeNode* node; + int level; + + if( !treeIterator ) + CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + + prevNode = node = (CvTreeNode*)treeIterator->node; + level = treeIterator->level; + + if( node ) + { + if( node->v_next && level+1 < treeIterator->max_level ) + { + node = node->v_next; + level++; + } + else + { + while( node->h_next == 0 ) + { + node = node->v_prev; + if( --level < 0 ) + { + node = 0; + break; + } + } + node = node && treeIterator->max_level != 0 ? node->h_next : 0; + } + } + + treeIterator->node = node; + treeIterator->level = level; + return prevNode; +} + + +CV_IMPL void* +cvPrevTreeNode( CvTreeNodeIterator* treeIterator ) +{ + CvTreeNode* prevNode = 0; + CvTreeNode* node; + int level; + + if( !treeIterator ) + CV_Error( CV_StsNullPtr, "" ); + + prevNode = node = (CvTreeNode*)treeIterator->node; + level = treeIterator->level; + + if( node ) + { + if( !node->h_prev ) + { + node = node->v_prev; + if( --level < 0 ) + node = 0; + } + else + { + node = node->h_prev; + + while( node->v_next && level < treeIterator->max_level ) + { + node = node->v_next; + level++; + + while( node->h_next ) + node = node->h_next; + } + } + } + + treeIterator->node = node; + treeIterator->level = level; + return prevNode; +} + + +namespace cv +{ + +// This is reimplementation of kd-trees from cvkdtree*.* by Xavier Delacour, cleaned-up and +// adopted to work with the new OpenCV data structures. It's in cxcore to be shared by +// both cv (CvFeatureTree) and ml (kNN). + +// The algorithm is taken from: +// J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search +// in highdimensional spaces. In Proc. IEEE Conf. Comp. Vision Patt. Recog., +// pages 1000--1006, 1997. http://citeseer.ist.psu.edu/beis97shape.html + +const int MAX_TREE_DEPTH = 32; + +KDTree::KDTree() +{ + maxDepth = -1; + normType = NORM_L2; +} + +KDTree::KDTree(InputArray _points, bool _copyData) +{ + maxDepth = -1; + normType = NORM_L2; + build(_points, _copyData); +} + +KDTree::KDTree(InputArray _points, InputArray _labels, bool _copyData) +{ + maxDepth = -1; + normType = NORM_L2; + build(_points, _labels, _copyData); +} + +struct SubTree +{ + SubTree() : first(0), last(0), nodeIdx(0), depth(0) {} + SubTree(int _first, int _last, int _nodeIdx, int _depth) + : first(_first), last(_last), nodeIdx(_nodeIdx), depth(_depth) {} + int first; + int last; + int nodeIdx; + int depth; +}; + + +static float +medianPartition( size_t* ofs, int a, int b, const float* vals ) +{ + int k, a0 = a, b0 = b; + int middle = (a + b)/2; + while( b > a ) + { + int i0 = a, i1 = (a+b)/2, i2 = b; + float v0 = vals[ofs[i0]], v1 = vals[ofs[i1]], v2 = vals[ofs[i2]]; + int ip = v0 < v1 ? (v1 < v2 ? i1 : v0 < v2 ? i2 : i0) : + v0 < v2 ? i0 : (v1 < v2 ? i2 : i1); + float pivot = vals[ofs[ip]]; + std::swap(ofs[ip], ofs[i2]); + + for( i1 = i0, i0--; i1 <= i2; i1++ ) + if( vals[ofs[i1]] <= pivot ) + { + i0++; + std::swap(ofs[i0], ofs[i1]); + } + if( i0 == middle ) + break; + if( i0 > middle ) + b = i0 - (b == i0); + else + a = i0; + } + + float pivot = vals[ofs[middle]]; + int less = 0, more = 0; + for( k = a0; k < middle; k++ ) + { + CV_Assert(vals[ofs[k]] <= pivot); + less += vals[ofs[k]] < pivot; + } + for( k = b0; k > middle; k-- ) + { + CV_Assert(vals[ofs[k]] >= pivot); + more += vals[ofs[k]] > pivot; + } + CV_Assert(std::abs(more - less) <= 1); + + return vals[ofs[middle]]; +} + +static void +computeSums( const Mat& points, const size_t* ofs, int a, int b, double* sums ) +{ + int i, j, dims = points.cols; + const float* data = points.ptr(0); + for( j = 0; j < dims; j++ ) + sums[j*2] = sums[j*2+1] = 0; + for( i = a; i <= b; i++ ) + { + const float* row = data + ofs[i]; + for( j = 0; j < dims; j++ ) + { + double t = row[j], s = sums[j*2] + t, s2 = sums[j*2+1] + t*t; + sums[j*2] = s; sums[j*2+1] = s2; + } + } +} + + +void KDTree::build(InputArray _points, bool _copyData) +{ + build(_points, noArray(), _copyData); +} + + +void KDTree::build(InputArray __points, InputArray __labels, bool _copyData) +{ + Mat _points = __points.getMat(), _labels = __labels.getMat(); + CV_Assert(_points.type() == CV_32F && !_points.empty()); + vector().swap(nodes); + + if( !_copyData ) + points = _points; + else + { + points.release(); + points.create(_points.size(), _points.type()); + } + + int i, j, n = _points.rows, ptdims = _points.cols, top = 0; + const float* data = _points.ptr(0); + float* dstdata = points.ptr(0); + size_t step = _points.step1(); + size_t dstep = points.step1(); + int ptpos = 0; + labels.resize(n); + const int* _labels_data = 0; + + if( !_labels.empty() ) + { + int nlabels = _labels.checkVector(1, CV_32S, true); + CV_Assert(nlabels == n); + _labels_data = (const int*)_labels.data; + } + + Mat sumstack(MAX_TREE_DEPTH*2, ptdims*2, CV_64F); + SubTree stack[MAX_TREE_DEPTH*2]; + + vector _ptofs(n); + size_t* ptofs = &_ptofs[0]; + + for( i = 0; i < n; i++ ) + ptofs[i] = i*step; + + nodes.push_back(Node()); + computeSums(points, ptofs, 0, n-1, sumstack.ptr(top)); + stack[top++] = SubTree(0, n-1, 0, 0); + int _maxDepth = 0; + + while( --top >= 0 ) + { + int first = stack[top].first, last = stack[top].last; + int depth = stack[top].depth, nidx = stack[top].nodeIdx; + int count = last - first + 1, dim = -1; + const double* sums = sumstack.ptr(top); + double invCount = 1./count, maxVar = -1.; + + if( count == 1 ) + { + int idx0 = (int)(ptofs[first]/step); + int idx = _copyData ? ptpos++ : idx0; + nodes[nidx].idx = ~idx; + if( _copyData ) + { + const float* src = data + ptofs[first]; + float* dst = dstdata + idx*dstep; + for( j = 0; j < ptdims; j++ ) + dst[j] = src[j]; + } + labels[idx] = _labels_data ? _labels_data[idx0] : idx0; + _maxDepth = std::max(_maxDepth, depth); + continue; + } + + // find the dimensionality with the biggest variance + for( j = 0; j < ptdims; j++ ) + { + double m = sums[j*2]*invCount; + double varj = sums[j*2+1]*invCount - m*m; + if( maxVar < varj ) + { + maxVar = varj; + dim = j; + } + } + + int left = (int)nodes.size(), right = left + 1; + nodes.push_back(Node()); + nodes.push_back(Node()); + nodes[nidx].idx = dim; + nodes[nidx].left = left; + nodes[nidx].right = right; + nodes[nidx].boundary = medianPartition(ptofs, first, last, data + dim); + + int middle = (first + last)/2; + double *lsums = (double*)sums, *rsums = lsums + ptdims*2; + computeSums(points, ptofs, middle+1, last, rsums); + for( j = 0; j < ptdims*2; j++ ) + lsums[j] = sums[j] - rsums[j]; + stack[top++] = SubTree(first, middle, left, depth+1); + stack[top++] = SubTree(middle+1, last, right, depth+1); + } + maxDepth = _maxDepth; +} + + +struct PQueueElem +{ + PQueueElem() : dist(0), idx(0) {} + PQueueElem(float _dist, int _idx) : dist(_dist), idx(_idx) {} + float dist; + int idx; +}; + + +int KDTree::findNearest(InputArray _vec, int K, int emax, + OutputArray _neighborsIdx, OutputArray _neighbors, + OutputArray _dist, OutputArray _labels) const + +{ + Mat vecmat = _vec.getMat(); + CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols ); + const float* vec = vecmat.ptr(); + K = std::min(K, points.rows); + int ptdims = points.cols; + + CV_Assert(K > 0 && (normType == NORM_L2 || normType == NORM_L1)); + + AutoBuffer _buf((K+1)*(sizeof(float) + sizeof(int))); + int* idx = (int*)(uchar*)_buf; + float* dist = (float*)(idx + K + 1); + int i, j, ncount = 0, e = 0; + + int qsize = 0, maxqsize = 1 << 10; + AutoBuffer _pqueue(maxqsize*sizeof(PQueueElem)); + PQueueElem* pqueue = (PQueueElem*)(uchar*)_pqueue; + emax = std::max(emax, 1); + + for( e = 0; e < emax; ) + { + float d, alt_d = 0.f; + int nidx; + + if( e == 0 ) + nidx = 0; + else + { + // take the next node from the priority queue + if( qsize == 0 ) + break; + nidx = pqueue[0].idx; + alt_d = pqueue[0].dist; + if( --qsize > 0 ) + { + std::swap(pqueue[0], pqueue[qsize]); + d = pqueue[0].dist; + for( i = 0;;) + { + int left = i*2 + 1, right = i*2 + 2; + if( left >= qsize ) + break; + if( right < qsize && pqueue[right].dist < pqueue[left].dist ) + left = right; + if( pqueue[left].dist >= d ) + break; + std::swap(pqueue[i], pqueue[left]); + i = left; + } + } + + if( ncount == K && alt_d > dist[ncount-1] ) + continue; + } + + for(;;) + { + if( nidx < 0 ) + break; + const Node& n = nodes[nidx]; + + if( n.idx < 0 ) + { + i = ~n.idx; + const float* row = points.ptr(i); + if( normType == NORM_L2 ) + for( j = 0, d = 0.f; j < ptdims; j++ ) + { + float t = vec[j] - row[j]; + d += t*t; + } + else + for( j = 0, d = 0.f; j < ptdims; j++ ) + d += std::abs(vec[j] - row[j]); + + dist[ncount] = d; + idx[ncount] = i; + for( i = ncount-1; i >= 0; i-- ) + { + if( dist[i] <= d ) + break; + std::swap(dist[i], dist[i+1]); + std::swap(idx[i], idx[i+1]); + } + ncount += ncount < K; + e++; + break; + } + + int alt; + if( vec[n.idx] <= n.boundary ) + { + nidx = n.left; + alt = n.right; + } + else + { + nidx = n.right; + alt = n.left; + } + + d = vec[n.idx] - n.boundary; + if( normType == NORM_L2 ) + d = d*d + alt_d; + else + d = std::abs(d) + alt_d; + // subtree prunning + if( ncount == K && d > dist[ncount-1] ) + continue; + // add alternative subtree to the priority queue + pqueue[qsize] = PQueueElem(d, alt); + for( i = qsize; i > 0; ) + { + int parent = (i-1)/2; + if( parent < 0 || pqueue[parent].dist <= d ) + break; + std::swap(pqueue[i], pqueue[parent]); + i = parent; + } + qsize += qsize+1 < maxqsize; + } + } + + K = std::min(K, ncount); + if( _neighborsIdx.needed() ) + { + _neighborsIdx.create(K, 1, CV_32S, -1, true); + Mat nidx = _neighborsIdx.getMat(); + Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx); + } + if( _dist.needed() ) + sqrt(Mat(K, 1, CV_32F, dist), _dist); + + if( _neighbors.needed() || _labels.needed() ) + getPoints(Mat(K, 1, CV_32S, idx), _neighbors, _labels); + return K; +} + + +void KDTree::findOrthoRange(InputArray _lowerBound, + InputArray _upperBound, + OutputArray _neighborsIdx, + OutputArray _neighbors, + OutputArray _labels ) const +{ + int ptdims = points.cols; + Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat(); + CV_Assert( lowerBound.size == upperBound.size && + lowerBound.isContinuous() && + upperBound.isContinuous() && + lowerBound.type() == upperBound.type() && + lowerBound.type() == CV_32F && + lowerBound.total() == (size_t)ptdims ); + const float* L = lowerBound.ptr(); + const float* R = upperBound.ptr(); + + vector idx; + AutoBuffer _stack(MAX_TREE_DEPTH*2 + 1); + int* stack = _stack; + int top = 0; + + stack[top++] = 0; + + while( --top >= 0 ) + { + int nidx = stack[top]; + if( nidx < 0 ) + break; + const Node& n = nodes[nidx]; + if( n.idx < 0 ) + { + int j, i = ~n.idx; + const float* row = points.ptr(i); + for( j = 0; j < ptdims; j++ ) + if( row[j] < L[j] || row[j] >= R[j] ) + break; + if( j == ptdims ) + idx.push_back(i); + continue; + } + if( L[n.idx] <= n.boundary ) + stack[top++] = n.left; + if( R[n.idx] > n.boundary ) + stack[top++] = n.right; + } + + if( _neighborsIdx.needed() ) + { + _neighborsIdx.create((int)idx.size(), 1, CV_32S, -1, true); + Mat nidx = _neighborsIdx.getMat(); + Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx); + } + getPoints( idx, _neighbors, _labels ); +} + + +void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) const +{ + Mat idxmat = _idx.getMat(), pts, labelsmat; + CV_Assert( idxmat.isContinuous() && idxmat.type() == CV_32S && + (idxmat.cols == 1 || idxmat.rows == 1) ); + const int* idx = idxmat.ptr(); + int* dstlabels = 0; + + int ptdims = points.cols; + int i, nidx = (int)idxmat.total(); + if( nidx == 0 ) + { + _pts.release(); + _labels.release(); + return; + } + + if( _pts.needed() ) + { + _pts.create( nidx, ptdims, points.type()); + pts = _pts.getMat(); + } + + if(_labels.needed()) + { + _labels.create(nidx, 1, CV_32S, -1, true); + labelsmat = _labels.getMat(); + CV_Assert( labelsmat.isContinuous() ); + dstlabels = labelsmat.ptr(); + } + const int* srclabels = !labels.empty() ? &labels[0] : 0; + + for( i = 0; i < nidx; i++ ) + { + int k = idx[i]; + CV_Assert( (unsigned)k < (unsigned)points.rows ); + const float* src = points.ptr(k); + if( pts.data ) + std::copy(src, src + ptdims, pts.ptr(i)); + if( dstlabels ) + dstlabels[i] = srclabels ? srclabels[k] : k; + } +} + + +const float* KDTree::getPoint(int ptidx, int* label) const +{ + CV_Assert( (unsigned)ptidx < (unsigned)points.rows); + if(label) + *label = labels[ptidx]; + return points.ptr(ptidx); +} + + +int KDTree::dims() const +{ + return !points.empty() ? points.cols : 0; +} + +//////////////////////////////////////////////////////////////////////////////// + +schar* seqPush( CvSeq* seq, const void* element ) +{ + return cvSeqPush(seq, element); +} + +schar* seqPushFront( CvSeq* seq, const void* element ) +{ + return cvSeqPushFront(seq, element); +} + +void seqPop( CvSeq* seq, void* element ) +{ + cvSeqPop(seq, element); +} + +void seqPopFront( CvSeq* seq, void* element ) +{ + cvSeqPopFront(seq, element); +} + +void seqRemove( CvSeq* seq, int index ) +{ + cvSeqRemove(seq, index); +} + +void clearSeq( CvSeq* seq ) +{ + cvClearSeq(seq); +} + +schar* getSeqElem( const CvSeq* seq, int index ) +{ + return cvGetSeqElem(seq, index); +} + +void seqRemoveSlice( CvSeq* seq, CvSlice slice ) +{ + return cvSeqRemoveSlice(seq, slice); +} + +void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ) +{ + cvSeqInsertSlice(seq, before_index, from_arr); +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/drawing.cpp diffimg-2.0.0/3rdparty/opencv/core/src/drawing.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/drawing.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/drawing.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2409 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +namespace cv +{ + +enum { XY_SHIFT = 16, XY_ONE = 1 << XY_SHIFT, DRAWING_STORAGE_BLOCK = (1<<12) - 256 }; + +struct PolyEdge +{ + PolyEdge() : y0(0), y1(0), x(0), dx(0), next(0) {} + //PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {} + + int y0, y1; + int x, dx; + PolyEdge *next; +}; + +static void +CollectPolyEdges( Mat& img, const Point* v, int npts, + vector& edges, const void* color, int line_type, + int shift, Point offset=Point() ); + +static void +FillEdgeCollection( Mat& img, vector& edges, const void* color ); + +static void +PolyLine( Mat& img, const Point* v, int npts, bool closed, + const void* color, int thickness, int line_type, int shift ); + +static void +FillConvexPoly( Mat& img, const Point* v, int npts, + const void* color, int line_type, int shift ); + +/****************************************************************************************\ +* Lines * +\****************************************************************************************/ + +bool clipLine( Size img_size, Point& pt1, Point& pt2 ) +{ + int64 x1, y1, x2, y2; + int c1, c2; + int64 right = img_size.width-1, bottom = img_size.height-1; + + if( img_size.width <= 0 || img_size.height <= 0 ) + return false; + + x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y; + c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8; + c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8; + + if( (c1 & c2) == 0 && (c1 | c2) != 0 ) + { + int64 a; + if( c1 & 12 ) + { + a = c1 < 8 ? 0 : bottom; + x1 += (a - y1) * (x2 - x1) / (y2 - y1); + y1 = a; + c1 = (x1 < 0) + (x1 > right) * 2; + } + if( c2 & 12 ) + { + a = c2 < 8 ? 0 : bottom; + x2 += (a - y2) * (x2 - x1) / (y2 - y1); + y2 = a; + c2 = (x2 < 0) + (x2 > right) * 2; + } + if( (c1 & c2) == 0 && (c1 | c2) != 0 ) + { + if( c1 ) + { + a = c1 == 1 ? 0 : right; + y1 += (a - x1) * (y2 - y1) / (x2 - x1); + x1 = a; + c1 = 0; + } + if( c2 ) + { + a = c2 == 1 ? 0 : right; + y2 += (a - x2) * (y2 - y1) / (x2 - x1); + x2 = a; + c2 = 0; + } + } + + assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 ); + + pt1.x = (int)x1; + pt1.y = (int)y1; + pt2.x = (int)x2; + pt2.y = (int)y2; + } + + return (c1 | c2) == 0; +} + +bool clipLine( Rect img_rect, Point& pt1, Point& pt2 ) +{ + Point tl = img_rect.tl(); + pt1 -= tl; pt2 -= tl; + bool inside = clipLine(img_rect.size(), pt1, pt2); + pt1 += tl; pt2 += tl; + + return inside; +} + +/* + Initializes line iterator. + Returns number of points on the line or negative number if error. +*/ +LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2, + int connectivity, bool left_to_right) +{ + count = -1; + + CV_Assert( connectivity == 8 || connectivity == 4 ); + + if( (unsigned)pt1.x >= (unsigned)(img.cols) || + (unsigned)pt2.x >= (unsigned)(img.cols) || + (unsigned)pt1.y >= (unsigned)(img.rows) || + (unsigned)pt2.y >= (unsigned)(img.rows) ) + { + if( !clipLine( img.size(), pt1, pt2 ) ) + { + ptr = img.data; + err = plusDelta = minusDelta = plusStep = minusStep = count = 0; + return; + } + } + + int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0; + size_t istep = img.step; + + int dx = pt2.x - pt1.x; + int dy = pt2.y - pt1.y; + int s = dx < 0 ? -1 : 0; + + if( left_to_right ) + { + dx = (dx ^ s) - s; + dy = (dy ^ s) - s; + pt1.x ^= (pt1.x ^ pt2.x) & s; + pt1.y ^= (pt1.y ^ pt2.y) & s; + } + else + { + dx = (dx ^ s) - s; + bt_pix = (bt_pix ^ s) - s; + } + + ptr = (uchar*)(img.data + pt1.y * istep + pt1.x * bt_pix0); + + s = dy < 0 ? -1 : 0; + dy = (dy ^ s) - s; + istep = (istep ^ s) - s; + + s = dy > dx ? -1 : 0; + + /* conditional swaps */ + dx ^= dy & s; + dy ^= dx & s; + dx ^= dy & s; + + bt_pix ^= istep & s; + istep ^= bt_pix & s; + bt_pix ^= istep & s; + + if( connectivity == 8 ) + { + assert( dx >= 0 && dy >= 0 ); + + err = dx - (dy + dy); + plusDelta = dx + dx; + minusDelta = -(dy + dy); + plusStep = (int)istep; + minusStep = bt_pix; + count = dx + 1; + } + else /* connectivity == 4 */ + { + assert( dx >= 0 && dy >= 0 ); + + err = 0; + plusDelta = (dx + dx) + (dy + dy); + minusDelta = -(dy + dy); + plusStep = (int)istep - bt_pix; + minusStep = bt_pix; + count = dx + dy + 1; + } + + this->ptr0 = img.data; + this->step = (int)img.step; + this->elemSize = bt_pix0; +} + +static void +Line( Mat& img, Point pt1, Point pt2, + const void* _color, int connectivity = 8 ) +{ + if( connectivity == 0 ) + connectivity = 8; + if( connectivity == 1 ) + connectivity = 4; + + LineIterator iterator(img, pt1, pt2, connectivity, true); + int i, count = iterator.count; + int pix_size = (int)img.elemSize(); + const uchar* color = (const uchar*)_color; + + for( i = 0; i < count; i++, ++iterator ) + { + uchar* ptr = *iterator; + if( pix_size == 1 ) + ptr[0] = color[0]; + else if( pix_size == 3 ) + { + ptr[0] = color[0]; + ptr[1] = color[1]; + ptr[2] = color[2]; + } + else + memcpy( *iterator, color, pix_size ); + } +} + + +/* Correction table depent on the slope */ +static const uchar SlopeCorrTable[] = { + 181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201, + 203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254 +}; + +/* Gaussian for antialiasing filter */ +static const int FilterTable[] = { + 168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254, + 254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168, + 158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45, + 40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5 +}; + +static void +LineAA( Mat& img, Point pt1, Point pt2, const void* color ) +{ + int dx, dy; + int ecount, scount = 0; + int slope; + int ax, ay; + int x_step, y_step; + int i, j; + int ep_table[9]; + int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2]; + int _cb, _cg, _cr; + int nch = img.channels(); + uchar* ptr = img.data; + size_t step = img.step; + Size size = img.size(); + + if( !((nch == 1 || nch == 3) && img.depth() == CV_8U) ) + { + Line(img, pt1, pt2, color); + return; + } + + pt1.x -= XY_ONE*2; + pt1.y -= XY_ONE*2; + pt2.x -= XY_ONE*2; + pt2.y -= XY_ONE*2; + ptr += img.step*2 + 2*nch; + + size.width = ((size.width - 5) << XY_SHIFT) + 1; + size.height = ((size.height - 5) << XY_SHIFT) + 1; + + if( !clipLine( size, pt1, pt2 )) + return; + + dx = pt2.x - pt1.x; + dy = pt2.y - pt1.y; + + j = dx < 0 ? -1 : 0; + ax = (dx ^ j) - j; + i = dy < 0 ? -1 : 0; + ay = (dy ^ i) - i; + + if( ax > ay ) + { + dx = ax; + dy = (dy ^ j) - j; + pt1.x ^= pt2.x & j; + pt2.x ^= pt1.x & j; + pt1.x ^= pt2.x & j; + pt1.y ^= pt2.y & j; + pt2.y ^= pt1.y & j; + pt1.y ^= pt2.y & j; + + x_step = XY_ONE; + y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1)); + pt2.x += XY_ONE; + ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT); + j = -(pt1.x & (XY_ONE - 1)); + pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1); + slope = (y_step >> (XY_SHIFT - 5)) & 0x3f; + slope ^= (y_step < 0 ? 0x3f : 0); + + /* Get 4-bit fractions for end-point adjustments */ + i = (pt1.x >> (XY_SHIFT - 7)) & 0x78; + j = (pt2.x >> (XY_SHIFT - 7)) & 0x78; + } + else + { + dy = ay; + dx = (dx ^ i) - i; + pt1.x ^= pt2.x & i; + pt2.x ^= pt1.x & i; + pt1.x ^= pt2.x & i; + pt1.y ^= pt2.y & i; + pt2.y ^= pt1.y & i; + pt1.y ^= pt2.y & i; + + x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1)); + y_step = XY_ONE; + pt2.y += XY_ONE; + ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT); + j = -(pt1.y & (XY_ONE - 1)); + pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1); + slope = (x_step >> (XY_SHIFT - 5)) & 0x3f; + slope ^= (x_step < 0 ? 0x3f : 0); + + /* Get 4-bit fractions for end-point adjustments */ + i = (pt1.y >> (XY_SHIFT - 7)) & 0x78; + j = (pt2.y >> (XY_SHIFT - 7)) & 0x78; + } + + slope = (slope & 0x20) ? 0x100 : SlopeCorrTable[slope]; + + /* Calc end point correction table */ + { + int t0 = slope << 7; + int t1 = ((0x78 - i) | 4) * slope; + int t2 = (j | 4) * slope; + + ep_table[0] = 0; + ep_table[8] = slope; + ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff; + ep_table[2] = (t1 >> 8) & 0x1ff; + ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff; + ep_table[5] = ((t1 + t0) >> 8) & 0x1ff; + ep_table[6] = (t2 >> 8) & 0x1ff; + ep_table[7] = ((t2 + t0) >> 8) & 0x1ff; + } + + if( nch == 3 ) + { + #define ICV_PUT_POINT() \ + { \ + _cb = tptr[0]; \ + _cb += ((cb - _cb)*a + 127)>> 8;\ + _cg = tptr[1]; \ + _cg += ((cg - _cg)*a + 127)>> 8;\ + _cr = tptr[2]; \ + _cr += ((cr - _cr)*a + 127)>> 8;\ + tptr[0] = (uchar)_cb; \ + tptr[1] = (uchar)_cg; \ + tptr[2] = (uchar)_cr; \ + } + if( ax > ay ) + { + ptr += (pt1.x >> XY_SHIFT) * 3; + + while( ecount >= 0 ) + { + uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step; + + int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 + + (((ecount >= 2) + 1) & (ecount | 2))]; + int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31; + + a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += step; + a = (ep_corr * FilterTable[dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += step; + a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + pt1.y += y_step; + ptr += 3; + scount++; + ecount--; + } + } + else + { + ptr += (pt1.y >> XY_SHIFT) * step; + + while( ecount >= 0 ) + { + uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3; + + int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 + + (((ecount >= 2) + 1) & (ecount | 2))]; + int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31; + + a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += 3; + a = (ep_corr * FilterTable[dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += 3; + a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + pt1.x += x_step; + ptr += step; + scount++; + ecount--; + } + } + #undef ICV_PUT_POINT + } + else + { + #define ICV_PUT_POINT() \ + { \ + _cb = tptr[0]; \ + _cb += ((cb - _cb)*a + 127)>> 8;\ + tptr[0] = (uchar)_cb; \ + } + + if( ax > ay ) + { + ptr += (pt1.x >> XY_SHIFT); + + while( ecount >= 0 ) + { + uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step; + + int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 + + (((ecount >= 2) + 1) & (ecount | 2))]; + int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31; + + a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += step; + a = (ep_corr * FilterTable[dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr += step; + a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + pt1.y += y_step; + ptr++; + scount++; + ecount--; + } + } + else + { + ptr += (pt1.y >> XY_SHIFT) * step; + + while( ecount >= 0 ) + { + uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1); + + int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 + + (((ecount >= 2) + 1) & (ecount | 2))]; + int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31; + + a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr++; + a = (ep_corr * FilterTable[dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + tptr++; + a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff; + ICV_PUT_POINT(); + ICV_PUT_POINT(); + + pt1.x += x_step; + ptr += step; + scount++; + ecount--; + } + } + #undef ICV_PUT_POINT + } +} + + +static void +Line2( Mat& img, Point pt1, Point pt2, const void* color ) +{ + int dx, dy; + int ecount; + int ax, ay; + int i, j, x, y; + int x_step, y_step; + int cb = ((uchar*)color)[0]; + int cg = ((uchar*)color)[1]; + int cr = ((uchar*)color)[2]; + int pix_size = (int)img.elemSize(); + uchar *ptr = img.data, *tptr; + size_t step = img.step; + Size size = img.size(), sizeScaled(size.width*XY_ONE, size.height*XY_ONE); + + //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U ); + + if( !clipLine( sizeScaled, pt1, pt2 )) + return; + + dx = pt2.x - pt1.x; + dy = pt2.y - pt1.y; + + j = dx < 0 ? -1 : 0; + ax = (dx ^ j) - j; + i = dy < 0 ? -1 : 0; + ay = (dy ^ i) - i; + + if( ax > ay ) + { + dx = ax; + dy = (dy ^ j) - j; + pt1.x ^= pt2.x & j; + pt2.x ^= pt1.x & j; + pt1.x ^= pt2.x & j; + pt1.y ^= pt2.y & j; + pt2.y ^= pt1.y & j; + pt1.y ^= pt2.y & j; + + x_step = XY_ONE; + y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1)); + ecount = (pt2.x - pt1.x) >> XY_SHIFT; + } + else + { + dy = ay; + dx = (dx ^ i) - i; + pt1.x ^= pt2.x & i; + pt2.x ^= pt1.x & i; + pt1.x ^= pt2.x & i; + pt1.y ^= pt2.y & i; + pt2.y ^= pt1.y & i; + pt1.y ^= pt2.y & i; + + x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1)); + y_step = XY_ONE; + ecount = (pt2.y - pt1.y) >> XY_SHIFT; + } + + pt1.x += (XY_ONE >> 1); + pt1.y += (XY_ONE >> 1); + + if( pix_size == 3 ) + { + #define ICV_PUT_POINT(_x,_y) \ + x = (_x); y = (_y); \ + if( 0 <= x && x < size.width && \ + 0 <= y && y < size.height ) \ + { \ + tptr = ptr + y*step + x*3; \ + tptr[0] = (uchar)cb; \ + tptr[1] = (uchar)cg; \ + tptr[2] = (uchar)cr; \ + } + + ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, + (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); + + if( ax > ay ) + { + pt1.x >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); + pt1.x++; + pt1.y += y_step; + ecount--; + } + } + else + { + pt1.y >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); + pt1.x += x_step; + pt1.y++; + ecount--; + } + } + + #undef ICV_PUT_POINT + } + else if( pix_size == 1 ) + { + #define ICV_PUT_POINT(_x,_y) \ + x = (_x); y = (_y); \ + if( 0 <= x && x < size.width && \ + 0 <= y && y < size.height ) \ + { \ + tptr = ptr + y*step + x;\ + tptr[0] = (uchar)cb; \ + } + + ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, + (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); + + if( ax > ay ) + { + pt1.x >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); + pt1.x++; + pt1.y += y_step; + ecount--; + } + } + else + { + pt1.y >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); + pt1.x += x_step; + pt1.y++; + ecount--; + } + } + + #undef ICV_PUT_POINT + } + else + { + #define ICV_PUT_POINT(_x,_y) \ + x = (_x); y = (_y); \ + if( 0 <= x && x < size.width && \ + 0 <= y && y < size.height ) \ + { \ + tptr = ptr + y*step + x*pix_size;\ + for( j = 0; j < pix_size; j++ ) \ + tptr[j] = ((uchar*)color)[j]; \ + } + + ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, + (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); + + if( ax > ay ) + { + pt1.x >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); + pt1.x++; + pt1.y += y_step; + ecount--; + } + } + else + { + pt1.y >>= XY_SHIFT; + + while( ecount >= 0 ) + { + ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); + pt1.x += x_step; + pt1.y++; + ecount--; + } + } + + #undef ICV_PUT_POINT + } +} + + +/****************************************************************************************\ +* Antialiazed Elliptic Arcs via Antialiazed Lines * +\****************************************************************************************/ + +static const float SinTable[] = + { 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f, + 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f, + 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f, + 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f, + 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f, + 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f, + 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f, + 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f, + 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f, + 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f, + 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f, + 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f, + 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f, + 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f, + 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f, + 1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f, + 0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f, + 0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f, + 0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f, + 0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f, + 0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f, + 0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f, + 0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f, + 0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f, + 0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f, + 0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f, + 0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f, + 0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f, + 0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f, + 0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f, + 0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f, + -0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f, + -0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f, + -0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f, + -0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f, + -0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f, + -0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f, + -0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f, + -0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f, + -0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f, + -0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f, + -0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f, + -0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f, + -0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f, + -0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f, + -1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f, + -0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f, + -0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f, + -0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f, + -0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f, + -0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f, + -0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f, + -0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f, + -0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f, + -0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f, + -0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f, + -0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f, + -0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f, + -0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f, + -0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f, + -0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f, + 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f, + 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f, + 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f, + 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f, + 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f, + 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f, + 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f, + 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f, + 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f, + 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f, + 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f, + 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f, + 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f, + 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f, + 1.0000000f +}; + + +static void +sincos( int angle, float& cosval, float& sinval ) +{ + angle += (angle < 0 ? 360 : 0); + sinval = SinTable[angle]; + cosval = SinTable[450 - angle]; +} + +/* + constructs polygon that represents elliptic arc. +*/ +void ellipse2Poly( Point center, Size axes, int angle, + int arc_start, int arc_end, + int delta, vector& pts ) +{ + float alpha, beta; + double size_a = axes.width, size_b = axes.height; + double cx = center.x, cy = center.y; + Point prevPt(INT_MIN,INT_MIN); + int i; + + while( angle < 0 ) + angle += 360; + while( angle > 360 ) + angle -= 360; + + if( arc_start > arc_end ) + { + i = arc_start; + arc_start = arc_end; + arc_end = i; + } + while( arc_start < 0 ) + { + arc_start += 360; + arc_end += 360; + } + while( arc_end > 360 ) + { + arc_end -= 360; + arc_start -= 360; + } + if( arc_end - arc_start > 360 ) + { + arc_start = 0; + arc_end = 360; + } + sincos( angle, alpha, beta ); + pts.resize(0); + + for( i = arc_start; i < arc_end + delta; i += delta ) + { + double x, y; + angle = i; + if( angle > arc_end ) + angle = arc_end; + if( angle < 0 ) + angle += 360; + + x = size_a * SinTable[450-angle]; + y = size_b * SinTable[angle]; + Point pt; + pt.x = cvRound( cx + x * alpha - y * beta ); + pt.y = cvRound( cy + x * beta + y * alpha ); + if( pt != prevPt ) + pts.push_back(pt); + } + + if( pts.size() < 2 ) + pts.push_back(pts[0]); +} + + +static void +EllipseEx( Mat& img, Point center, Size axes, + int angle, int arc_start, int arc_end, + const void* color, int thickness, int line_type ) +{ + axes.width = std::abs(axes.width), axes.height = std::abs(axes.height); + int delta = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT; + delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5; + + vector v; + ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v ); + + if( thickness >= 0 ) + PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT ); + else if( arc_end - arc_start >= 360 ) + FillConvexPoly( img, &v[0], (int)v.size(), color, line_type, XY_SHIFT ); + else + { + v.push_back(center); + vector edges; + CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT ); + FillEdgeCollection( img, edges, color ); + } +} + + +/****************************************************************************************\ +* Polygons filling * +\****************************************************************************************/ + +/* helper macros: filling horizontal row */ +#define ICV_HLINE( ptr, xl, xr, color, pix_size ) \ +{ \ + uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \ + uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \ + \ + for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\ + { \ + int hline_j; \ + for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \ + { \ + hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \ + } \ + } \ +} + + +/* filling convex polygon. v - array of vertices, ntps - number of points */ +static void +FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift ) +{ + struct + { + int idx, di; + int x, dx, ye; + } + edge[2]; + + int delta = shift ? 1 << (shift - 1) : 0; + int i, y, imin = 0, left = 0, right = 1, x1, x2; + int edges = npts; + int xmin, xmax, ymin, ymax; + uchar* ptr = img.data; + Size size = img.size(); + int pix_size = (int)img.elemSize(); + Point p0; + int delta1, delta2; + + if( line_type < CV_AA ) + delta1 = delta2 = XY_ONE >> 1; + else + delta1 = XY_ONE - 1, delta2 = 0; + + p0 = v[npts - 1]; + p0.x <<= XY_SHIFT - shift; + p0.y <<= XY_SHIFT - shift; + + assert( 0 <= shift && shift <= XY_SHIFT ); + xmin = xmax = v[0].x; + ymin = ymax = v[0].y; + + for( i = 0; i < npts; i++ ) + { + Point p = v[i]; + if( p.y < ymin ) + { + ymin = p.y; + imin = i; + } + + ymax = std::max( ymax, p.y ); + xmax = std::max( xmax, p.x ); + xmin = MIN( xmin, p.x ); + + p.x <<= XY_SHIFT - shift; + p.y <<= XY_SHIFT - shift; + + if( line_type <= 8 ) + { + if( shift == 0 ) + { + Point pt0, pt1; + pt0.x = p0.x >> XY_SHIFT; + pt0.y = p0.y >> XY_SHIFT; + pt1.x = p.x >> XY_SHIFT; + pt1.y = p.y >> XY_SHIFT; + Line( img, pt0, pt1, color, line_type ); + } + else + Line2( img, p0, p, color ); + } + else + LineAA( img, p0, p, color ); + p0 = p; + } + + xmin = (xmin + delta) >> shift; + xmax = (xmax + delta) >> shift; + ymin = (ymin + delta) >> shift; + ymax = (ymax + delta) >> shift; + + if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height ) + return; + + ymax = MIN( ymax, size.height - 1 ); + edge[0].idx = edge[1].idx = imin; + + edge[0].ye = edge[1].ye = y = ymin; + edge[0].di = 1; + edge[1].di = npts - 1; + + ptr += img.step*y; + + do + { + if( line_type < CV_AA || y < ymax || y == ymin ) + { + for( i = 0; i < 2; i++ ) + { + if( y >= edge[i].ye ) + { + int idx = edge[i].idx, di = edge[i].di; + int xs = 0, xe, ye, ty = 0; + + for(;;) + { + ty = (v[idx].y + delta) >> shift; + if( ty > y || edges == 0 ) + break; + xs = v[idx].x; + idx += di; + idx -= ((idx < npts) - 1) & npts; /* idx -= idx >= npts ? npts : 0 */ + edges--; + } + + ye = ty; + xs <<= XY_SHIFT - shift; + xe = v[idx].x << (XY_SHIFT - shift); + + /* no more edges */ + if( y >= ye ) + return; + + edge[i].ye = ye; + edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y)); + edge[i].x = xs; + edge[i].idx = idx; + } + } + } + + if( edge[left].x > edge[right].x ) + { + left ^= 1; + right ^= 1; + } + + x1 = edge[left].x; + x2 = edge[right].x; + + if( y >= 0 ) + { + int xx1 = (x1 + delta1) >> XY_SHIFT; + int xx2 = (x2 + delta2) >> XY_SHIFT; + + if( xx2 >= 0 && xx1 < size.width ) + { + if( xx1 < 0 ) + xx1 = 0; + if( xx2 >= size.width ) + xx2 = size.width - 1; + ICV_HLINE( ptr, xx1, xx2, color, pix_size ); + } + } + + x1 += edge[left].dx; + x2 += edge[right].dx; + + edge[left].x = x1; + edge[right].x = x2; + ptr += img.step; + } + while( ++y <= ymax ); +} + + +/******** Arbitrary polygon **********/ + +static void +CollectPolyEdges( Mat& img, const Point* v, int count, vector& edges, + const void* color, int line_type, int shift, Point offset ) +{ + int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0); + Point pt0 = v[count-1], pt1; + pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift); + pt0.y = (pt0.y + delta) >> shift; + + edges.reserve( edges.size() + count ); + + for( i = 0; i < count; i++, pt0 = pt1 ) + { + Point t0, t1; + PolyEdge edge; + + pt1 = v[i]; + pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift); + pt1.y = (pt1.y + delta) >> shift; + + if( line_type < CV_AA ) + { + t0.y = pt0.y; t1.y = pt1.y; + t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT; + t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT; + Line( img, t0, t1, color, line_type ); + } + else + { + t0.x = pt0.x; t1.x = pt1.x; + t0.y = pt0.y << XY_SHIFT; + t1.y = pt1.y << XY_SHIFT; + LineAA( img, t0, t1, color ); + } + + if( pt0.y == pt1.y ) + continue; + + if( pt0.y < pt1.y ) + { + edge.y0 = pt0.y; + edge.y1 = pt1.y; + edge.x = pt0.x; + } + else + { + edge.y0 = pt1.y; + edge.y1 = pt0.y; + edge.x = pt1.x; + } + edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y); + edges.push_back(edge); + } +} + +struct CmpEdges +{ + bool operator ()(const PolyEdge& e1, const PolyEdge& e2) + { + return e1.y0 - e2.y0 ? e1.y0 < e2.y0 : + e1.x - e2.x ? e1.x < e2.x : e1.dx < e2.dx; + } +}; + +/**************** helper macros and functions for sequence/contour processing ***********/ + +static void +FillEdgeCollection( Mat& img, vector& edges, const void* color ) +{ + PolyEdge tmp; + int i, y, total = (int)edges.size(); + Size size = img.size(); + PolyEdge* e; + int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX; + int pix_size = (int)img.elemSize(); + + if( total < 2 ) + return; + + for( i = 0; i < total; i++ ) + { + PolyEdge& e1 = edges[i]; + assert( e1.y0 < e1.y1 ); + y_min = std::min( y_min, e1.y0 ); + y_max = std::max( y_max, e1.y1 ); + x_min = std::min( x_min, e1.x ); + x_max = std::max( x_max, e1.x ); + } + + if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<y0; y < y_max; y++ ) + { + PolyEdge *last, *prelast, *keep_prelast; + int sort_flag = 0; + int draw = 0; + int clipline = y < 0; + + prelast = &tmp; + last = tmp.next; + while( last || e->y0 == y ) + { + if( last && last->y1 == y ) + { + // exclude edge if y reachs its lower point + prelast->next = last->next; + last = last->next; + continue; + } + keep_prelast = prelast; + if( last && (e->y0 > y || last->x < e->x) ) + { + // go to the next edge in active list + prelast = last; + last = last->next; + } + else if( i < total ) + { + // insert new edge into active list if y reachs its upper point + prelast->next = e; + e->next = last; + prelast = e; + e = &edges[++i]; + } + else + break; + + if( draw ) + { + if( !clipline ) + { + // convert x's from fixed-point to image coordinates + uchar *timg = img.data + y * img.step; + int x1 = keep_prelast->x; + int x2 = prelast->x; + + if( x1 > x2 ) + { + int t = x1; + + x1 = x2; + x2 = t; + } + + x1 = (x1 + XY_ONE - 1) >> XY_SHIFT; + x2 = x2 >> XY_SHIFT; + + // clip and draw the line + if( x1 < size.width && x2 >= 0 ) + { + if( x1 < 0 ) + x1 = 0; + if( x2 >= size.width ) + x2 = size.width - 1; + ICV_HLINE( timg, x1, x2, color, pix_size ); + } + } + keep_prelast->x += keep_prelast->dx; + prelast->x += prelast->dx; + } + draw ^= 1; + } + + // sort edges (using bubble sort) + keep_prelast = 0; + + do + { + prelast = &tmp; + last = tmp.next; + + while( last != keep_prelast && last->next != 0 ) + { + PolyEdge *te = last->next; + + // swap edges + if( last->x > te->x ) + { + prelast->next = te; + last->next = te->next; + te->next = last; + prelast = te; + sort_flag = 1; + } + else + { + prelast = last; + last = te; + } + } + keep_prelast = prelast; + } + while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp ); + } +} + + +/* draws simple or filled circle */ +static void +Circle( Mat& img, Point center, int radius, const void* color, int fill ) +{ + Size size = img.size(); + size_t step = img.step; + int pix_size = (int)img.elemSize(); + uchar* ptr = img.data; + int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1; + int inside = center.x >= radius && center.x < size.width - radius && + center.y >= radius && center.y < size.height - radius; + + #define ICV_PUT_POINT( ptr, x ) \ + memcpy( ptr + (x)*pix_size, color, pix_size ); + + while( dx >= dy ) + { + int mask; + int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx; + int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy; + + if( inside ) + { + uchar *tptr0 = ptr + y11 * step; + uchar *tptr1 = ptr + y12 * step; + + if( !fill ) + { + ICV_PUT_POINT( tptr0, x11 ); + ICV_PUT_POINT( tptr1, x11 ); + ICV_PUT_POINT( tptr0, x12 ); + ICV_PUT_POINT( tptr1, x12 ); + } + else + { + ICV_HLINE( tptr0, x11, x12, color, pix_size ); + ICV_HLINE( tptr1, x11, x12, color, pix_size ); + } + + tptr0 = ptr + y21 * step; + tptr1 = ptr + y22 * step; + + if( !fill ) + { + ICV_PUT_POINT( tptr0, x21 ); + ICV_PUT_POINT( tptr1, x21 ); + ICV_PUT_POINT( tptr0, x22 ); + ICV_PUT_POINT( tptr1, x22 ); + } + else + { + ICV_HLINE( tptr0, x21, x22, color, pix_size ); + ICV_HLINE( tptr1, x21, x22, color, pix_size ); + } + } + else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 ) + { + if( fill ) + { + x11 = std::max( x11, 0 ); + x12 = MIN( x12, size.width - 1 ); + } + + if( (unsigned)y11 < (unsigned)size.height ) + { + uchar *tptr = ptr + y11 * step; + + if( !fill ) + { + if( x11 >= 0 ) + ICV_PUT_POINT( tptr, x11 ); + if( x12 < size.width ) + ICV_PUT_POINT( tptr, x12 ); + } + else + ICV_HLINE( tptr, x11, x12, color, pix_size ); + } + + if( (unsigned)y12 < (unsigned)size.height ) + { + uchar *tptr = ptr + y12 * step; + + if( !fill ) + { + if( x11 >= 0 ) + ICV_PUT_POINT( tptr, x11 ); + if( x12 < size.width ) + ICV_PUT_POINT( tptr, x12 ); + } + else + ICV_HLINE( tptr, x11, x12, color, pix_size ); + } + + if( x21 < size.width && x22 >= 0 ) + { + if( fill ) + { + x21 = std::max( x21, 0 ); + x22 = MIN( x22, size.width - 1 ); + } + + if( (unsigned)y21 < (unsigned)size.height ) + { + uchar *tptr = ptr + y21 * step; + + if( !fill ) + { + if( x21 >= 0 ) + ICV_PUT_POINT( tptr, x21 ); + if( x22 < size.width ) + ICV_PUT_POINT( tptr, x22 ); + } + else + ICV_HLINE( tptr, x21, x22, color, pix_size ); + } + + if( (unsigned)y22 < (unsigned)size.height ) + { + uchar *tptr = ptr + y22 * step; + + if( !fill ) + { + if( x21 >= 0 ) + ICV_PUT_POINT( tptr, x21 ); + if( x22 < size.width ) + ICV_PUT_POINT( tptr, x22 ); + } + else + ICV_HLINE( tptr, x21, x22, color, pix_size ); + } + } + } + dy++; + err += plus; + plus += 2; + + mask = (err <= 0) - 1; + + err -= minus & mask; + dx += mask; + minus -= mask & 2; + } + + #undef ICV_PUT_POINT +} + + +static void +ThickLine( Mat& img, Point p0, Point p1, const void* color, + int thickness, int line_type, int flags, int shift ) +{ + static const double INV_XY_ONE = 1./XY_ONE; + + p0.x <<= XY_SHIFT - shift; + p0.y <<= XY_SHIFT - shift; + p1.x <<= XY_SHIFT - shift; + p1.y <<= XY_SHIFT - shift; + + if( thickness <= 1 ) + { + if( line_type < CV_AA ) + { + if( line_type == 1 || line_type == 4 || shift == 0 ) + { + p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT; + p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT; + p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT; + p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT; + Line( img, p0, p1, color, line_type ); + } + else + Line2( img, p0, p1, color ); + } + else + LineAA( img, p0, p1, color ); + } + else + { + Point pt[4], dp = Point(0,0); + double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE; + double r = dx * dx + dy * dy; + int i, oddThickness = thickness & 1; + thickness <<= XY_SHIFT - 1; + + if( fabs(r) > DBL_EPSILON ) + { + r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r); + dp.x = cvRound( dy * r ); + dp.y = cvRound( dx * r ); + + pt[0].x = p0.x + dp.x; + pt[0].y = p0.y + dp.y; + pt[1].x = p0.x - dp.x; + pt[1].y = p0.y - dp.y; + pt[2].x = p1.x - dp.x; + pt[2].y = p1.y - dp.y; + pt[3].x = p1.x + dp.x; + pt[3].y = p1.y + dp.y; + + FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT ); + } + + for( i = 0; i < 2; i++ ) + { + if( flags & (i+1) ) + { + if( line_type < CV_AA ) + { + Point center; + center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT; + center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT; + Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 ); + } + else + { + EllipseEx( img, p0, cvSize(thickness, thickness), + 0, 0, 360, color, -1, line_type ); + } + } + p0 = p1; + } + } +} + + +static void +PolyLine( Mat& img, const Point* v, int count, bool is_closed, + const void* color, int thickness, + int line_type, int shift ) +{ + if( !v || count <= 0 ) + return; + + int i = is_closed ? count - 1 : 0; + int flags = 2 + !is_closed; + Point p0; + CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 ); + + p0 = v[i]; + for( i = !is_closed; i < count; i++ ) + { + Point p = v[i]; + ThickLine( img, p0, p, color, thickness, line_type, flags, shift ); + p0 = p; + flags = 2; + } +} + +/****************************************************************************************\ +* External functions * +\****************************************************************************************/ + +void line( Mat& img, Point pt1, Point pt2, const Scalar& color, + int thickness, int line_type, int shift ) +{ + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + CV_Assert( 0 <= thickness && thickness <= 255 ); + CV_Assert( 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData( color, buf, img.type(), 0 ); + ThickLine( img, pt1, pt2, buf, thickness, line_type, 3, shift ); +} + +void rectangle( Mat& img, Point pt1, Point pt2, + const Scalar& color, int thickness, + int lineType, int shift ) +{ + if( lineType == CV_AA && img.depth() != CV_8U ) + lineType = 8; + + CV_Assert( thickness <= 255 ); + CV_Assert( 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + Point pt[4]; + + pt[0] = pt1; + pt[1].x = pt2.x; + pt[1].y = pt1.y; + pt[2] = pt2; + pt[3].x = pt1.x; + pt[3].y = pt2.y; + + if( thickness >= 0 ) + PolyLine( img, pt, 4, true, buf, thickness, lineType, shift ); + else + FillConvexPoly( img, pt, 4, buf, lineType, shift ); +} + + +void rectangle( Mat& img, Rect rec, + const Scalar& color, int thickness, + int lineType, int shift ) +{ + CV_Assert( 0 <= shift && shift <= XY_SHIFT ); + if( rec.area() > 0 ) + rectangle( img, rec.tl(), rec.br() - Point(1<= 0 && thickness <= 255 && + 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + if( thickness > 1 || line_type >= CV_AA ) + { + center.x <<= XY_SHIFT - shift; + center.y <<= XY_SHIFT - shift; + radius <<= XY_SHIFT - shift; + EllipseEx( img, center, Size(radius, radius), + 0, 0, 360, buf, thickness, line_type ); + } + else + Circle( img, center, radius, buf, thickness < 0 ); +} + + +void ellipse( Mat& img, Point center, Size axes, + double angle, double start_angle, double end_angle, + const Scalar& color, int thickness, int line_type, int shift ) +{ + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + CV_Assert( axes.width >= 0 && axes.height >= 0 && + thickness <= 255 && 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + int _angle = cvRound(angle); + int _start_angle = cvRound(start_angle); + int _end_angle = cvRound(end_angle); + center.x <<= XY_SHIFT - shift; + center.y <<= XY_SHIFT - shift; + axes.width <<= XY_SHIFT - shift; + axes.height <<= XY_SHIFT - shift; + + EllipseEx( img, center, axes, _angle, _start_angle, + _end_angle, buf, thickness, line_type ); +} + +void ellipse(Mat& img, const RotatedRect& box, const Scalar& color, + int thickness, int lineType) +{ + if( lineType == CV_AA && img.depth() != CV_8U ) + lineType = 8; + + CV_Assert( box.size.width >= 0 && box.size.height >= 0 && + thickness <= 255 ); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + int _angle = cvRound(box.angle); + Point center(cvRound(box.center.x*(1 << XY_SHIFT)), + cvRound(box.center.y*(1 << XY_SHIFT))); + Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))), + cvRound(box.size.height*(1 << (XY_SHIFT - 1)))); + EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType ); +} + +void fillConvexPoly( Mat& img, const Point* pts, int npts, + const Scalar& color, int line_type, int shift ) +{ + if( !pts || npts <= 0 ) + return; + + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + double buf[4]; + CV_Assert( 0 <= shift && shift <= XY_SHIFT ); + scalarToRawData(color, buf, img.type(), 0); + FillConvexPoly( img, pts, npts, buf, line_type, shift ); +} + + +void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours, + const Scalar& color, int line_type, + int shift, Point offset ) +{ + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + CV_Assert( pts && npts && ncontours >= 0 && 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + vector edges; + + int i, total = 0; + for( i = 0; i < ncontours; i++ ) + total += npts[i]; + + edges.reserve( total + 1 ); + for( i = 0; i < ncontours; i++ ) + CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset ); + + FillEdgeCollection(img, edges, buf); +} + + +void polylines( Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, + const Scalar& color, int thickness, int line_type, int shift ) +{ + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + CV_Assert( pts && npts && ncontours >= 0 && + 0 <= thickness && thickness <= 255 && + 0 <= shift && shift <= XY_SHIFT ); + + double buf[4]; + scalarToRawData( color, buf, img.type(), 0 ); + + for( int i = 0; i < ncontours; i++ ) + PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift ); +} + + +enum { FONT_SIZE_SHIFT=8, FONT_ITALIC_ALPHA=(1 << 8), + FONT_ITALIC_DIGIT=(2 << 8), FONT_ITALIC_PUNCT=(4 << 8), + FONT_ITALIC_BRACES=(8 << 8), FONT_HAVE_GREEK=(16 << 8), + FONT_HAVE_CYRILLIC=(32 << 8) }; + +static const int HersheyPlain[] = { +(5 + 4*16) + FONT_HAVE_GREEK, +199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220, +200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192, +215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, +14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84, +194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, +112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, +195, 223, 196, 88 }; + +static const int HersheyPlainItalic[] = { +(5 + 4*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK, +199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220, +200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192, +215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84, +194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, +162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, +195, 223, 196, 88 }; + +static const int HersheyComplexSmall[] = { +(6 + 7*16) + FONT_HAVE_GREEK, +1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220, +1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242, +1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, +1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084, +1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, +1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, +1225, 1229, 1226, 1246 }; + +static const int HersheyComplexSmallItalic[] = { +(6 + 7*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK, +1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220, +1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242, +1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, +1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084, +1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, +1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, +1225, 1229, 1226, 1246 }; + +static const int HersheySimplex[] = { +(9 + 12*16) + FONT_HAVE_GREEK, +2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720, +700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692, +715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, +514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584, +694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, +612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, +695, 723, 696, 2246 }; + +static const int HersheyDuplex[] = { +(9 + 12*16) + FONT_HAVE_GREEK, +2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720, +2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731, +2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, +2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084, +2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, +2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, +2225, 2229, 2226, 2246 }; + +static const int HersheyComplex[] = { +(9 + 12*16) + FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC, +2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220, +2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242, +2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, +2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084, +2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, +2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, +2225, 2229, 2226, 2246 }; + +static const int HersheyComplexItalic[] = { +(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + +FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC, +2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220, +2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242, +2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, +2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084, +2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, +2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, +2225, 2229, 2226, 2246 }; + +static const int HersheyTriplex[] = { +(9 + 12*16) + FONT_HAVE_GREEK, +2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220, +3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231, +3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, +2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084, +2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, +3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, +2225, 2229, 2226, 2246 }; + +static const int HersheyTriplexItalic[] = { +(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + +FONT_ITALIC_PUNCT + FONT_HAVE_GREEK, +2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270, +3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231, +3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, +2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084, +2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, +3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176, +2225, 2229, 2226, 2246 }; + +static const int HersheyScriptSimplex[] = { +(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK, +2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720, +700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692, +715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, +564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584, +694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, +662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, +695, 723, 696, 2246 }; + +static const int HersheyScriptComplex[] = { +(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + FONT_HAVE_GREEK, +2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220, +2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242, +2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, +2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084, +2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, +2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, +2225, 2229, 2226, 2246 }; + + +static const int* getFontData(int fontFace) +{ + bool isItalic = (fontFace & FONT_ITALIC) != 0; + const int* ascii = 0; + + switch( fontFace & 15 ) + { + case FONT_HERSHEY_SIMPLEX: + ascii = HersheySimplex; + break; + case FONT_HERSHEY_PLAIN: + ascii = !isItalic ? HersheyPlain : HersheyPlainItalic; + break; + case FONT_HERSHEY_DUPLEX: + ascii = HersheyDuplex; + break; + case FONT_HERSHEY_COMPLEX: + ascii = !isItalic ? HersheyComplex : HersheyComplexItalic; + break; + case FONT_HERSHEY_TRIPLEX: + ascii = !isItalic ? HersheyTriplex : HersheyTriplexItalic; + break; + case FONT_HERSHEY_COMPLEX_SMALL: + ascii = !isItalic ? HersheyComplexSmall : HersheyComplexSmallItalic; + break; + case FONT_HERSHEY_SCRIPT_SIMPLEX: + ascii = HersheyScriptSimplex; + break; + case FONT_HERSHEY_SCRIPT_COMPLEX: + ascii = HersheyScriptComplex; + break; + default: + CV_Error( CV_StsOutOfRange, "Unknown font type" ); + } + return ascii; +} + + +void putText( Mat& img, const string& text, Point org, + int fontFace, double fontScale, Scalar color, + int thickness, int line_type, bool bottomLeftOrigin ) + +{ + const int* ascii = getFontData(fontFace); + + double buf[4]; + scalarToRawData(color, buf, img.type(), 0); + + int base_line = -(ascii[0] & 15); + int hscale = cvRound(fontScale*XY_ONE), vscale = hscale; + + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + if( bottomLeftOrigin ) + vscale = -vscale; + + int view_x = org.x << XY_SHIFT; + int view_y = (org.y << XY_SHIFT) + base_line*vscale; + vector pts; + pts.reserve(1 << 10); + const char **faces = cv::g_HersheyGlyphs; + + for( int i = 0; text[i] != '\0'; i++ ) + { + int c = (uchar)text[i]; + Point p; + + if( c >= 127 || c < ' ' ) + c = '?'; + + const char* ptr = faces[ascii[(c-' ')+1]]; + p.x = (uchar)ptr[0] - 'R'; + p.y = (uchar)ptr[1] - 'R'; + int dx = p.y*hscale; + view_x -= p.x*hscale; + pts.resize(0); + + for( ptr += 2;; ) + { + if( *ptr == ' ' || !*ptr ) + { + if( pts.size() > 1 ) + PolyLine( img, &pts[0], (int)pts.size(), false, buf, thickness, line_type, XY_SHIFT ); + if( !*ptr++ ) + break; + pts.resize(0); + } + else + { + p.x = (uchar)ptr[0] - 'R'; + p.y = (uchar)ptr[1] - 'R'; + ptr += 2; + pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y)); + } + } + view_x += dx; + } +} + +Size getTextSize( const string& text, int fontFace, double fontScale, int thickness, int* _base_line) +{ + Size size; + double view_x = 0; + const char **faces = cv::g_HersheyGlyphs; + const int* ascii = getFontData(fontFace); + + int base_line = (ascii[0] & 15); + int cap_line = (ascii[0] >> 4) & 15; + size.height = cvRound((cap_line + base_line)*fontScale + (thickness+1)/2); + + for( int i = 0; text[i] != '\0'; i++ ) + { + int c = (uchar)text[i]; + Point p; + + if( c >= 127 || c < ' ' ) + c = '?'; + + const char* ptr = faces[ascii[(c-' ')+1]]; + p.x = (uchar)ptr[0] - 'R'; + p.y = (uchar)ptr[1] - 'R'; + view_x += (p.y - p.x)*fontScale; + } + + size.width = cvRound(view_x + thickness); + if( _base_line ) + *_base_line = cvRound(base_line*fontScale + thickness*0.5); + return size; +} + +} + + +void cv::fillConvexPoly(InputOutputArray _img, InputArray _points, + const Scalar& color, int lineType, int shift) +{ + Mat img = _img.getMat(), points = _points.getMat(); + CV_Assert(points.checkVector(2, CV_32S) >= 0); + fillConvexPoly(img, (const Point*)points.data, points.rows*points.cols*points.channels()/2, color, lineType, shift); +} + + +void cv::fillPoly(InputOutputArray _img, InputArrayOfArrays pts, + const Scalar& color, int lineType, int shift, Point offset) +{ + Mat img = _img.getMat(); + int i, ncontours = (int)pts.total(); + if( ncontours == 0 ) + return; + AutoBuffer _ptsptr(ncontours); + AutoBuffer _npts(ncontours); + Point** ptsptr = _ptsptr; + int* npts = _npts; + + for( i = 0; i < ncontours; i++ ) + { + Mat p = pts.getMat(i); + CV_Assert(p.checkVector(2, CV_32S) >= 0); + ptsptr[i] = (Point*)p.data; + npts[i] = p.rows*p.cols*p.channels()/2; + } + fillPoly(img, (const Point**)ptsptr, npts, (int)ncontours, color, lineType, shift, offset); +} + + +void cv::polylines(InputOutputArray _img, InputArrayOfArrays pts, + bool isClosed, const Scalar& color, + int thickness, int lineType, int shift ) +{ + Mat img = _img.getMat(); + bool manyContours = pts.kind() == _InputArray::STD_VECTOR_VECTOR || + pts.kind() == _InputArray::STD_VECTOR_MAT; + int i, ncontours = manyContours ? (int)pts.total() : 1; + if( ncontours == 0 ) + return; + AutoBuffer _ptsptr(ncontours); + AutoBuffer _npts(ncontours); + Point** ptsptr = _ptsptr; + int* npts = _npts; + + for( i = 0; i < ncontours; i++ ) + { + Mat p = pts.getMat(manyContours ? i : -1); + if( p.total() == 0 ) + continue; + CV_Assert(p.checkVector(2, CV_32S) >= 0); + ptsptr[i] = (Point*)p.data; + npts[i] = p.rows*p.cols*p.channels()/2; + } + polylines(img, (const Point**)ptsptr, npts, (int)ncontours, isClosed, color, thickness, lineType, shift); +} + + +static const int CodeDeltas[8][2] = +{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} }; + +#define CV_ADJUST_EDGE_COUNT( count, seq ) \ + ((count) -= ((count) == (seq)->total && !CV_IS_SEQ_CLOSED(seq))) + +CV_IMPL void +cvDrawContours( void* _img, CvSeq* contour, + CvScalar _externalColor, CvScalar _holeColor, + int maxLevel, int thickness, + int line_type, CvPoint _offset ) +{ + CvSeq *contour0 = contour, *h_next = 0; + CvTreeNodeIterator iterator; + cv::vector edges; + cv::vector pts; + cv::Scalar externalColor = _externalColor, holeColor = _holeColor; + cv::Mat img = cv::cvarrToMat(_img); + cv::Point offset = _offset; + double ext_buf[4], hole_buf[4]; + + if( line_type == CV_AA && img.depth() != CV_8U ) + line_type = 8; + + if( !contour ) + return; + + CV_Assert( thickness <= 255 ); + + scalarToRawData( externalColor, ext_buf, img.type(), 0 ); + scalarToRawData( holeColor, hole_buf, img.type(), 0 ); + + maxLevel = MAX(maxLevel, INT_MIN+2); + maxLevel = MIN(maxLevel, INT_MAX-1); + + if( maxLevel < 0 ) + { + h_next = contour->h_next; + contour->h_next = 0; + maxLevel = -maxLevel+1; + } + + cvInitTreeNodeIterator( &iterator, contour, maxLevel ); + while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 ) + { + CvSeqReader reader; + int i, count = contour->total; + int elem_type = CV_MAT_TYPE(contour->flags); + void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf; + + cvStartReadSeq( contour, &reader, 0 ); + if( thickness < 0 ) + pts.resize(0); + + if( CV_IS_SEQ_CHAIN_CONTOUR( contour )) + { + cv::Point pt = ((CvChain*)contour)->origin; + cv::Point prev_pt = pt; + char prev_code = reader.ptr ? reader.ptr[0] : '\0'; + + prev_pt += offset; + + for( i = 0; i < count; i++ ) + { + char code; + CV_READ_SEQ_ELEM( code, reader ); + + assert( (code & ~7) == 0 ); + + if( code != prev_code ) + { + prev_code = code; + if( thickness >= 0 ) + cv::ThickLine( img, prev_pt, pt, clr, thickness, line_type, 2, 0 ); + else + pts.push_back(pt); + prev_pt = pt; + } + + pt.x += CodeDeltas[(int)code][0]; + pt.y += CodeDeltas[(int)code][1]; + } + + if( thickness >= 0 ) + cv::ThickLine( img, prev_pt, + cv::Point(((CvChain*)contour)->origin) + offset, + clr, thickness, line_type, 2, 0 ); + else + cv::CollectPolyEdges(img, &pts[0], (int)pts.size(), + edges, ext_buf, line_type, 0, offset); + } + else if( CV_IS_SEQ_POLYLINE( contour )) + { + CV_Assert( elem_type == CV_32SC2 ); + cv::Point pt1, pt2; + int shift = 0; + + count -= !CV_IS_SEQ_CLOSED(contour); + CV_READ_SEQ_ELEM( pt1, reader ); + pt1 += offset; + if( thickness < 0 ) + pts.push_back(pt1); + + for( i = 0; i < count; i++ ) + { + CV_READ_SEQ_ELEM( pt2, reader ); + pt2 += offset; + if( thickness >= 0 ) + cv::ThickLine( img, pt1, pt2, clr, thickness, line_type, 2, shift ); + else + pts.push_back(pt2); + pt1 = pt2; + } + if( thickness < 0 ) + cv::CollectPolyEdges( img, &pts[0], (int)pts.size(), + edges, ext_buf, line_type, 0, cv::Point() ); + } + } + + if( thickness < 0 ) + cv::FillEdgeCollection( img, edges, ext_buf ); + + if( h_next && contour0 ) + contour0->h_next = h_next; +} + +CV_IMPL int +cvClipLine( CvSize size, CvPoint* pt1, CvPoint* pt2 ) +{ + CV_Assert( pt1 && pt2 ); + return cv::clipLine( size, *(cv::Point*)pt1, *(cv::Point*)pt2 ); +} + + +CV_IMPL int +cvEllipse2Poly( CvPoint center, CvSize axes, int angle, + int arc_start, int arc_end, CvPoint* _pts, int delta ) +{ + cv::vector pts; + cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts ); + memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) ); + return (int)pts.size(); +} + +CV_IMPL CvScalar +cvColorToScalar( double packed_color, int type ) +{ + CvScalar scalar; + + if( CV_MAT_DEPTH( type ) == CV_8U ) + { + int icolor = cvRound( packed_color ); + if( CV_MAT_CN( type ) > 1 ) + { + scalar.val[0] = icolor & 255; + scalar.val[1] = (icolor >> 8) & 255; + scalar.val[2] = (icolor >> 16) & 255; + scalar.val[3] = (icolor >> 24) & 255; + } + else + { + scalar.val[0] = CV_CAST_8U( icolor ); + scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + } + } + else if( CV_MAT_DEPTH( type ) == CV_8S ) + { + int icolor = cvRound( packed_color ); + if( CV_MAT_CN( type ) > 1 ) + { + scalar.val[0] = (char)icolor; + scalar.val[1] = (char)(icolor >> 8); + scalar.val[2] = (char)(icolor >> 16); + scalar.val[3] = (char)(icolor >> 24); + } + else + { + scalar.val[0] = CV_CAST_8S( icolor ); + scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + } + } + else + { + int cn = CV_MAT_CN( type ); + switch( cn ) + { + case 1: + scalar.val[0] = packed_color; + scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + break; + case 2: + scalar.val[0] = scalar.val[1] = packed_color; + scalar.val[2] = scalar.val[3] = 0; + break; + case 3: + scalar.val[0] = scalar.val[1] = scalar.val[2] = packed_color; + scalar.val[3] = 0; + break; + default: + scalar.val[0] = scalar.val[1] = + scalar.val[2] = scalar.val[3] = packed_color; + break; + } + } + + return scalar; +} + +CV_IMPL int +cvInitLineIterator( const CvArr* img, CvPoint pt1, CvPoint pt2, + CvLineIterator* iterator, int connectivity, + int left_to_right ) +{ + CV_Assert( iterator != 0 ); + cv::LineIterator li(cv::cvarrToMat(img), pt1, pt2, connectivity, left_to_right!=0); + + iterator->err = li.err; + iterator->minus_delta = li.minusDelta; + iterator->plus_delta = li.plusDelta; + iterator->minus_step = li.minusStep; + iterator->plus_step = li.plusStep; + iterator->ptr = li.ptr; + + return li.count; +} + +CV_IMPL void +cvLine( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color, + int thickness, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::line( img, pt1, pt2, color, thickness, line_type, shift ); +} + +CV_IMPL void +cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2, + CvScalar color, int thickness, + int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift ); +} + +CV_IMPL void +cvRectangleR( CvArr* _img, CvRect rec, + CvScalar color, int thickness, + int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::rectangle( img, rec, color, thickness, line_type, shift ); +} + +CV_IMPL void +cvCircle( CvArr* _img, CvPoint center, int radius, + CvScalar color, int thickness, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::circle( img, center, radius, color, thickness, line_type, shift ); +} + +CV_IMPL void +cvEllipse( CvArr* _img, CvPoint center, CvSize axes, + double angle, double start_angle, double end_angle, + CvScalar color, int thickness, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::ellipse( img, center, axes, angle, start_angle, end_angle, + color, thickness, line_type, shift ); +} + +CV_IMPL void +cvFillConvexPoly( CvArr* _img, const CvPoint *pts, int npts, + CvScalar color, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + cv::fillConvexPoly( img, (const cv::Point*)pts, npts, + color, line_type, shift ); +} + +CV_IMPL void +cvFillPoly( CvArr* _img, CvPoint **pts, const int *npts, int ncontours, + CvScalar color, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + + cv::fillPoly( img, (const cv::Point**)pts, npts, ncontours, color, line_type, shift ); +} + +CV_IMPL void +cvPolyLine( CvArr* _img, CvPoint **pts, const int *npts, + int ncontours, int closed, CvScalar color, + int thickness, int line_type, int shift ) +{ + cv::Mat img = cv::cvarrToMat(_img); + + cv::polylines( img, (const cv::Point**)pts, npts, ncontours, + closed != 0, color, thickness, line_type, shift ); +} + +CV_IMPL void +cvPutText( CvArr* _img, const char *text, CvPoint org, const CvFont *_font, CvScalar color ) +{ + cv::Mat img = cv::cvarrToMat(_img); + CV_Assert( text != 0 && _font != 0); + cv::putText( img, text, org, _font->font_face, (_font->hscale+_font->vscale)*0.5, + color, _font->thickness, _font->line_type, + CV_IS_IMAGE(_img) && ((IplImage*)_img)->origin != 0 ); +} + + +CV_IMPL void +cvInitFont( CvFont *font, int font_face, double hscale, double vscale, + double shear, int thickness, int line_type ) +{ + CV_Assert( font != 0 && hscale > 0 && vscale > 0 && thickness >= 0 ); + + font->ascii = cv::getFontData(font_face); + font->font_face = font_face; + font->hscale = (float)hscale; + font->vscale = (float)vscale; + font->thickness = thickness; + font->shear = (float)shear; + font->greek = font->cyrillic = 0; + font->line_type = line_type; +} + +CV_IMPL void +cvGetTextSize( const char *text, const CvFont *_font, CvSize *_size, int *_base_line ) +{ + CV_Assert(text != 0 && _font != 0); + cv::Size size = cv::getTextSize( text, _font->font_face, (_font->hscale + _font->vscale)*0.5, + _font->thickness, _base_line ); + if( _size ) + *_size = size; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/dxt.cpp diffimg-2.0.0/3rdparty/opencv/core/src/dxt.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/dxt.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/dxt.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2683 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +// On Win64 optimized versions of DFT and DCT fail the tests (fixed in VS2010) +#if defined _MSC_VER && !defined CV_ICC && defined _M_X64 && _MSC_VER < 1600 +# pragma optimize("", off) +# pragma warning(disable: 4748) +#endif + +/****************************************************************************************\ + Discrete Fourier Transform +\****************************************************************************************/ + +#define CV_MAX_LOCAL_DFT_SIZE (1 << 15) + +static unsigned char bitrevTab[] = +{ + 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 const double DFTTab[][2] = +{ +{ 1.00000000000000000, 0.00000000000000000 }, +{-1.00000000000000000, 0.00000000000000000 }, +{ 0.00000000000000000, 1.00000000000000000 }, +{ 0.70710678118654757, 0.70710678118654746 }, +{ 0.92387953251128674, 0.38268343236508978 }, +{ 0.98078528040323043, 0.19509032201612825 }, +{ 0.99518472667219693, 0.09801714032956060 }, +{ 0.99879545620517241, 0.04906767432741802 }, +{ 0.99969881869620425, 0.02454122852291229 }, +{ 0.99992470183914450, 0.01227153828571993 }, +{ 0.99998117528260111, 0.00613588464915448 }, +{ 0.99999529380957619, 0.00306795676296598 }, +{ 0.99999882345170188, 0.00153398018628477 }, +{ 0.99999970586288223, 0.00076699031874270 }, +{ 0.99999992646571789, 0.00038349518757140 }, +{ 0.99999998161642933, 0.00019174759731070 }, +{ 0.99999999540410733, 0.00009587379909598 }, +{ 0.99999999885102686, 0.00004793689960307 }, +{ 0.99999999971275666, 0.00002396844980842 }, +{ 0.99999999992818922, 0.00001198422490507 }, +{ 0.99999999998204725, 0.00000599211245264 }, +{ 0.99999999999551181, 0.00000299605622633 }, +{ 0.99999999999887801, 0.00000149802811317 }, +{ 0.99999999999971945, 0.00000074901405658 }, +{ 0.99999999999992983, 0.00000037450702829 }, +{ 0.99999999999998246, 0.00000018725351415 }, +{ 0.99999999999999567, 0.00000009362675707 }, +{ 0.99999999999999889, 0.00000004681337854 }, +{ 0.99999999999999978, 0.00000002340668927 }, +{ 0.99999999999999989, 0.00000001170334463 }, +{ 1.00000000000000000, 0.00000000585167232 }, +{ 1.00000000000000000, 0.00000000292583616 } +}; + +#define BitRev(i,shift) \ + ((int)((((unsigned)bitrevTab[(i)&255] << 24)+ \ + ((unsigned)bitrevTab[((i)>> 8)&255] << 16)+ \ + ((unsigned)bitrevTab[((i)>>16)&255] << 8)+ \ + ((unsigned)bitrevTab[((i)>>24)])) >> (shift))) + +static int +DFTFactorize( int n, int* factors ) +{ + int nf = 0, f, i, j; + + if( n <= 5 ) + { + factors[0] = n; + return 1; + } + + f = (((n - 1)^n)+1) >> 1; + if( f > 1 ) + { + factors[nf++] = f; + n = f == n ? 1 : n/f; + } + + for( f = 3; n > 1; ) + { + int d = n/f; + if( d*f == n ) + { + factors[nf++] = f; + n = d; + } + else + { + f += 2; + if( f*f > n ) + break; + } + } + + if( n > 1 ) + factors[nf++] = n; + + f = (factors[0] & 1) == 0; + for( i = f; i < (nf+f)/2; i++ ) + CV_SWAP( factors[i], factors[nf-i-1+f], j ); + + return nf; +} + +static void +DFTInit( int n0, int nf, int* factors, int* itab, int elem_size, void* _wave, int inv_itab ) +{ + int digits[34], radix[34]; + int n = factors[0], m = 0; + int* itab0 = itab; + int i, j, k; + Complex w, w1; + double t; + + if( n0 <= 5 ) + { + itab[0] = 0; + itab[n0-1] = n0-1; + + if( n0 != 4 ) + { + for( i = 1; i < n0-1; i++ ) + itab[i] = i; + } + else + { + itab[1] = 2; + itab[2] = 1; + } + if( n0 == 5 ) + { + if( elem_size == sizeof(Complex) ) + ((Complex*)_wave)[0] = Complex(1.,0.); + else + ((Complex*)_wave)[0] = Complex(1.f,0.f); + } + if( n0 != 4 ) + return; + m = 2; + } + else + { + // radix[] is initialized from index 'nf' down to zero + assert (nf < 34); + radix[nf] = 1; + digits[nf] = 0; + for( i = 0; i < nf; i++ ) + { + digits[i] = 0; + radix[nf-i-1] = radix[nf-i]*factors[nf-i-1]; + } + + if( inv_itab && factors[0] != factors[nf-1] ) + itab = (int*)_wave; + + if( (n & 1) == 0 ) + { + int a = radix[1], na2 = n*a>>1, na4 = na2 >> 1; + for( m = 0; (unsigned)(1 << m) < (unsigned)n; m++ ) + ; + if( n <= 2 ) + { + itab[0] = 0; + itab[1] = na2; + } + else if( n <= 256 ) + { + int shift = 10 - m; + for( i = 0; i <= n - 4; i += 4 ) + { + j = (bitrevTab[i>>2]>>shift)*a; + itab[i] = j; + itab[i+1] = j + na2; + itab[i+2] = j + na4; + itab[i+3] = j + na2 + na4; + } + } + else + { + int shift = 34 - m; + for( i = 0; i < n; i += 4 ) + { + int i4 = i >> 2; + j = BitRev(i4,shift)*a; + itab[i] = j; + itab[i+1] = j + na2; + itab[i+2] = j + na4; + itab[i+3] = j + na2 + na4; + } + } + + digits[1]++; + + if( nf >= 2 ) + { + for( i = n, j = radix[2]; i < n0; ) + { + for( k = 0; k < n; k++ ) + itab[i+k] = itab[k] + j; + if( (i += n) >= n0 ) + break; + j += radix[2]; + for( k = 1; ++digits[k] >= factors[k]; k++ ) + { + digits[k] = 0; + j += radix[k+2] - radix[k]; + } + } + } + } + else + { + for( i = 0, j = 0;; ) + { + itab[i] = j; + if( ++i >= n0 ) + break; + j += radix[1]; + for( k = 0; ++digits[k] >= factors[k]; k++ ) + { + digits[k] = 0; + j += radix[k+2] - radix[k]; + } + } + } + + if( itab != itab0 ) + { + itab0[0] = 0; + for( i = n0 & 1; i < n0; i += 2 ) + { + int k0 = itab[i]; + int k1 = itab[i+1]; + itab0[k0] = i; + itab0[k1] = i+1; + } + } + } + + if( (n0 & (n0-1)) == 0 ) + { + w.re = w1.re = DFTTab[m][0]; + w.im = w1.im = -DFTTab[m][1]; + } + else + { + t = -CV_PI*2/n0; + w.im = w1.im = sin(t); + w.re = w1.re = std::sqrt(1. - w1.im*w1.im); + } + n = (n0+1)/2; + + if( elem_size == sizeof(Complex) ) + { + Complex* wave = (Complex*)_wave; + + wave[0].re = 1.; + wave[0].im = 0.; + + if( (n0 & 1) == 0 ) + { + wave[n].re = -1.; + wave[n].im = 0; + } + + for( i = 1; i < n; i++ ) + { + wave[i] = w; + wave[n0-i].re = w.re; + wave[n0-i].im = -w.im; + + t = w.re*w1.re - w.im*w1.im; + w.im = w.re*w1.im + w.im*w1.re; + w.re = t; + } + } + else + { + Complex* wave = (Complex*)_wave; + assert( elem_size == sizeof(Complex) ); + + wave[0].re = 1.f; + wave[0].im = 0.f; + + if( (n0 & 1) == 0 ) + { + wave[n].re = -1.f; + wave[n].im = 0.f; + } + + for( i = 1; i < n; i++ ) + { + wave[i].re = (float)w.re; + wave[i].im = (float)w.im; + wave[n0-i].re = (float)w.re; + wave[n0-i].im = (float)-w.im; + + t = w.re*w1.re - w.im*w1.im; + w.im = w.re*w1.im + w.im*w1.re; + w.re = t; + } + } +} + +template struct DFT_VecR4 +{ + int operator()(Complex*, int, int, int&, const Complex*) const { return 1; } +}; + +#if CV_SSE3 + +// optimized radix-4 transform +template<> struct DFT_VecR4 +{ + int operator()(Complex* dst, int N, int n0, int& _dw0, const Complex* wave) const + { + int n = 1, i, j, nx, dw, dw0 = _dw0; + __m128 z = _mm_setzero_ps(), x02=z, x13=z, w01=z, w23=z, y01, y23, t0, t1; + Cv32suf t; t.i = 0x80000000; + __m128 neg0_mask = _mm_load_ss(&t.f); + __m128 neg3_mask = _mm_shuffle_ps(neg0_mask, neg0_mask, _MM_SHUFFLE(0,1,2,3)); + + for( ; n*4 <= N; ) + { + nx = n; + n *= 4; + dw0 /= 4; + + for( i = 0; i < n0; i += n ) + { + Complexf *v0, *v1; + + v0 = dst + i; + v1 = v0 + nx*2; + + x02 = _mm_loadl_pi(x02, (const __m64*)&v0[0]); + x13 = _mm_loadl_pi(x13, (const __m64*)&v0[nx]); + x02 = _mm_loadh_pi(x02, (const __m64*)&v1[0]); + x13 = _mm_loadh_pi(x13, (const __m64*)&v1[nx]); + + y01 = _mm_add_ps(x02, x13); + y23 = _mm_sub_ps(x02, x13); + t1 = _mm_xor_ps(_mm_shuffle_ps(y01, y23, _MM_SHUFFLE(2,3,3,2)), neg3_mask); + t0 = _mm_movelh_ps(y01, y23); + y01 = _mm_add_ps(t0, t1); + y23 = _mm_sub_ps(t0, t1); + + _mm_storel_pi((__m64*)&v0[0], y01); + _mm_storeh_pi((__m64*)&v0[nx], y01); + _mm_storel_pi((__m64*)&v1[0], y23); + _mm_storeh_pi((__m64*)&v1[nx], y23); + + for( j = 1, dw = dw0; j < nx; j++, dw += dw0 ) + { + v0 = dst + i + j; + v1 = v0 + nx*2; + + x13 = _mm_loadl_pi(x13, (const __m64*)&v0[nx]); + w23 = _mm_loadl_pi(w23, (const __m64*)&wave[dw*2]); + x13 = _mm_loadh_pi(x13, (const __m64*)&v1[nx]); // x1, x3 = r1 i1 r3 i3 + w23 = _mm_loadh_pi(w23, (const __m64*)&wave[dw*3]); // w2, w3 = wr2 wi2 wr3 wi3 + + t0 = _mm_mul_ps(_mm_moveldup_ps(x13), w23); + t1 = _mm_mul_ps(_mm_movehdup_ps(x13), _mm_shuffle_ps(w23, w23, _MM_SHUFFLE(2,3,0,1))); + x13 = _mm_addsub_ps(t0, t1); + // re(x1*w2), im(x1*w2), re(x3*w3), im(x3*w3) + x02 = _mm_loadl_pi(x02, (const __m64*)&v1[0]); // x2 = r2 i2 + w01 = _mm_loadl_pi(w01, (const __m64*)&wave[dw]); // w1 = wr1 wi1 + x02 = _mm_shuffle_ps(x02, x02, _MM_SHUFFLE(0,0,1,1)); + w01 = _mm_shuffle_ps(w01, w01, _MM_SHUFFLE(1,0,0,1)); + x02 = _mm_mul_ps(x02, w01); + x02 = _mm_addsub_ps(x02, _mm_movelh_ps(x02, x02)); + // re(x0) im(x0) re(x2*w1), im(x2*w1) + x02 = _mm_loadl_pi(x02, (const __m64*)&v0[0]); + + y01 = _mm_add_ps(x02, x13); + y23 = _mm_sub_ps(x02, x13); + t1 = _mm_xor_ps(_mm_shuffle_ps(y01, y23, _MM_SHUFFLE(2,3,3,2)), neg3_mask); + t0 = _mm_movelh_ps(y01, y23); + y01 = _mm_add_ps(t0, t1); + y23 = _mm_sub_ps(t0, t1); + + _mm_storel_pi((__m64*)&v0[0], y01); + _mm_storeh_pi((__m64*)&v0[nx], y01); + _mm_storel_pi((__m64*)&v1[0], y23); + _mm_storeh_pi((__m64*)&v1[nx], y23); + } + } + } + + _dw0 = dw0; + return n; + } +}; + +#endif + +#ifdef HAVE_IPP +static void ippsDFTFwd_CToC( const Complex* src, Complex* dst, + const void* spec, uchar* buf) +{ + ippsDFTFwd_CToC_32fc( (const Ipp32fc*)src, (Ipp32fc*)dst, + (const IppsDFTSpec_C_32fc*)spec, buf); +} + +static void ippsDFTFwd_CToC( const Complex* src, Complex* dst, + const void* spec, uchar* buf) +{ + ippsDFTFwd_CToC_64fc( (const Ipp64fc*)src, (Ipp64fc*)dst, + (const IppsDFTSpec_C_64fc*)spec, buf); +} + +static void ippsDFTInv_CToC( const Complex* src, Complex* dst, + const void* spec, uchar* buf) +{ + ippsDFTInv_CToC_32fc( (const Ipp32fc*)src, (Ipp32fc*)dst, + (const IppsDFTSpec_C_32fc*)spec, buf); +} + +static void ippsDFTInv_CToC( const Complex* src, Complex* dst, + const void* spec, uchar* buf) +{ + ippsDFTInv_CToC_64fc( (const Ipp64fc*)src, (Ipp64fc*)dst, + (const IppsDFTSpec_C_64fc*)spec, buf); +} + +static void ippsDFTFwd_RToPack( const float* src, float* dst, + const void* spec, uchar* buf) +{ + ippsDFTFwd_RToPack_32f( src, dst, (const IppsDFTSpec_R_32f*)spec, buf); +} + +static void ippsDFTFwd_RToPack( const double* src, double* dst, + const void* spec, uchar* buf) +{ + ippsDFTFwd_RToPack_64f( src, dst, (const IppsDFTSpec_R_64f*)spec, buf); +} + +static void ippsDFTInv_PackToR( const float* src, float* dst, + const void* spec, uchar* buf) +{ + ippsDFTInv_PackToR_32f( src, dst, (const IppsDFTSpec_R_32f*)spec, buf); +} + +static void ippsDFTInv_PackToR( const double* src, double* dst, + const void* spec, uchar* buf) +{ + ippsDFTInv_PackToR_64f( src, dst, (const IppsDFTSpec_R_64f*)spec, buf); +} +#endif + +enum { DFT_NO_PERMUTE=256, DFT_COMPLEX_INPUT_OR_OUTPUT=512 }; + +// mixed-radix complex discrete Fourier transform: double-precision version +template static void +DFT( const Complex* src, Complex* dst, int n, + int nf, const int* factors, const int* itab, + const Complex* wave, int tab_size, + const void* +#ifdef HAVE_IPP + spec +#endif + , Complex* buf, + int flags, double _scale ) +{ + static const T sin_120 = (T)0.86602540378443864676372317075294; + static const T fft5_2 = (T)0.559016994374947424102293417182819; + static const T fft5_3 = (T)-0.951056516295153572116439333379382; + static const T fft5_4 = (T)-1.538841768587626701285145288018455; + static const T fft5_5 = (T)0.363271264002680442947733378740309; + + int n0 = n, f_idx, nx; + int inv = flags & DFT_INVERSE; + int dw0 = tab_size, dw; + int i, j, k; + Complex t; + T scale = (T)_scale; + int tab_step; + +#ifdef HAVE_IPP + if( spec ) + { + if( !inv ) + ippsDFTFwd_CToC( src, dst, spec, (uchar*)buf ); + else + ippsDFTInv_CToC( src, dst, spec, (uchar*)buf ); + return; + } +#endif + + tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n; + + // 0. shuffle data + if( dst != src ) + { + assert( (flags & DFT_NO_PERMUTE) == 0 ); + if( !inv ) + { + for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step ) + { + int k0 = itab[0], k1 = itab[tab_step]; + assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n ); + dst[i] = src[k0]; dst[i+1] = src[k1]; + } + + if( i < n ) + dst[n-1] = src[n-1]; + } + else + { + for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step ) + { + int k0 = itab[0], k1 = itab[tab_step]; + assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n ); + t.re = src[k0].re; t.im = -src[k0].im; + dst[i] = t; + t.re = src[k1].re; t.im = -src[k1].im; + dst[i+1] = t; + } + + if( i < n ) + { + t.re = src[n-1].re; t.im = -src[n-1].im; + dst[i] = t; + } + } + } + else + { + if( (flags & DFT_NO_PERMUTE) == 0 ) + { + CV_Assert( factors[0] == factors[nf-1] ); + if( nf == 1 ) + { + if( (n & 3) == 0 ) + { + int n2 = n/2; + Complex* dsth = dst + n2; + + for( i = 0; i < n2; i += 2, itab += tab_step*2 ) + { + j = itab[0]; + assert( (unsigned)j < (unsigned)n2 ); + + CV_SWAP(dst[i+1], dsth[j], t); + if( j > i ) + { + CV_SWAP(dst[i], dst[j], t); + CV_SWAP(dsth[i+1], dsth[j+1], t); + } + } + } + // else do nothing + } + else + { + for( i = 0; i < n; i++, itab += tab_step ) + { + j = itab[0]; + assert( (unsigned)j < (unsigned)n ); + if( j > i ) + CV_SWAP(dst[i], dst[j], t); + } + } + } + + if( inv ) + { + for( i = 0; i <= n - 2; i += 2 ) + { + T t0 = -dst[i].im; + T t1 = -dst[i+1].im; + dst[i].im = t0; dst[i+1].im = t1; + } + + if( i < n ) + dst[n-1].im = -dst[n-1].im; + } + } + + n = 1; + // 1. power-2 transforms + if( (factors[0] & 1) == 0 ) + { + if( factors[0] >= 4 && checkHardwareSupport(CV_CPU_SSE3)) + { + DFT_VecR4 vr4; + n = vr4(dst, factors[0], n0, dw0, wave); + } + + // radix-4 transform + for( ; n*4 <= factors[0]; ) + { + nx = n; + n *= 4; + dw0 /= 4; + + for( i = 0; i < n0; i += n ) + { + Complex *v0, *v1; + T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4; + + v0 = dst + i; + v1 = v0 + nx*2; + + r0 = v1[0].re; i0 = v1[0].im; + r4 = v1[nx].re; i4 = v1[nx].im; + + r1 = r0 + r4; i1 = i0 + i4; + r3 = i0 - i4; i3 = r4 - r0; + + r2 = v0[0].re; i2 = v0[0].im; + r4 = v0[nx].re; i4 = v0[nx].im; + + r0 = r2 + r4; i0 = i2 + i4; + r2 -= r4; i2 -= i4; + + v0[0].re = r0 + r1; v0[0].im = i0 + i1; + v1[0].re = r0 - r1; v1[0].im = i0 - i1; + v0[nx].re = r2 + r3; v0[nx].im = i2 + i3; + v1[nx].re = r2 - r3; v1[nx].im = i2 - i3; + + for( j = 1, dw = dw0; j < nx; j++, dw += dw0 ) + { + v0 = dst + i + j; + v1 = v0 + nx*2; + + r2 = v0[nx].re*wave[dw*2].re - v0[nx].im*wave[dw*2].im; + i2 = v0[nx].re*wave[dw*2].im + v0[nx].im*wave[dw*2].re; + r0 = v1[0].re*wave[dw].im + v1[0].im*wave[dw].re; + i0 = v1[0].re*wave[dw].re - v1[0].im*wave[dw].im; + r3 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re; + i3 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im; + + r1 = i0 + i3; i1 = r0 + r3; + r3 = r0 - r3; i3 = i3 - i0; + r4 = v0[0].re; i4 = v0[0].im; + + r0 = r4 + r2; i0 = i4 + i2; + r2 = r4 - r2; i2 = i4 - i2; + + v0[0].re = r0 + r1; v0[0].im = i0 + i1; + v1[0].re = r0 - r1; v1[0].im = i0 - i1; + v0[nx].re = r2 + r3; v0[nx].im = i2 + i3; + v1[nx].re = r2 - r3; v1[nx].im = i2 - i3; + } + } + } + + for( ; n < factors[0]; ) + { + // do the remaining radix-2 transform + nx = n; + n *= 2; + dw0 /= 2; + + for( i = 0; i < n0; i += n ) + { + Complex* v = dst + i; + T r0 = v[0].re + v[nx].re; + T i0 = v[0].im + v[nx].im; + T r1 = v[0].re - v[nx].re; + T i1 = v[0].im - v[nx].im; + v[0].re = r0; v[0].im = i0; + v[nx].re = r1; v[nx].im = i1; + + for( j = 1, dw = dw0; j < nx; j++, dw += dw0 ) + { + v = dst + i + j; + r1 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im; + i1 = v[nx].im*wave[dw].re + v[nx].re*wave[dw].im; + r0 = v[0].re; i0 = v[0].im; + + v[0].re = r0 + r1; v[0].im = i0 + i1; + v[nx].re = r0 - r1; v[nx].im = i0 - i1; + } + } + } + } + + // 2. all the other transforms + for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ ) + { + int factor = factors[f_idx]; + nx = n; + n *= factor; + dw0 /= factor; + + if( factor == 3 ) + { + // radix-3 + for( i = 0; i < n0; i += n ) + { + Complex* v = dst + i; + + T r1 = v[nx].re + v[nx*2].re; + T i1 = v[nx].im + v[nx*2].im; + T r0 = v[0].re; + T i0 = v[0].im; + T r2 = sin_120*(v[nx].im - v[nx*2].im); + T i2 = sin_120*(v[nx*2].re - v[nx].re); + v[0].re = r0 + r1; v[0].im = i0 + i1; + r0 -= (T)0.5*r1; i0 -= (T)0.5*i1; + v[nx].re = r0 + r2; v[nx].im = i0 + i2; + v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2; + + for( j = 1, dw = dw0; j < nx; j++, dw += dw0 ) + { + v = dst + i + j; + r0 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im; + i0 = v[nx].re*wave[dw].im + v[nx].im*wave[dw].re; + i2 = v[nx*2].re*wave[dw*2].re - v[nx*2].im*wave[dw*2].im; + r2 = v[nx*2].re*wave[dw*2].im + v[nx*2].im*wave[dw*2].re; + r1 = r0 + i2; i1 = i0 + r2; + + r2 = sin_120*(i0 - r2); i2 = sin_120*(i2 - r0); + r0 = v[0].re; i0 = v[0].im; + v[0].re = r0 + r1; v[0].im = i0 + i1; + r0 -= (T)0.5*r1; i0 -= (T)0.5*i1; + v[nx].re = r0 + r2; v[nx].im = i0 + i2; + v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2; + } + } + } + else if( factor == 5 ) + { + // radix-5 + for( i = 0; i < n0; i += n ) + { + for( j = 0, dw = 0; j < nx; j++, dw += dw0 ) + { + Complex* v0 = dst + i + j; + Complex* v1 = v0 + nx*2; + Complex* v2 = v1 + nx*2; + + T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4, r5, i5; + + r3 = v0[nx].re*wave[dw].re - v0[nx].im*wave[dw].im; + i3 = v0[nx].re*wave[dw].im + v0[nx].im*wave[dw].re; + r2 = v2[0].re*wave[dw*4].re - v2[0].im*wave[dw*4].im; + i2 = v2[0].re*wave[dw*4].im + v2[0].im*wave[dw*4].re; + + r1 = r3 + r2; i1 = i3 + i2; + r3 -= r2; i3 -= i2; + + r4 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im; + i4 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re; + r0 = v1[0].re*wave[dw*2].re - v1[0].im*wave[dw*2].im; + i0 = v1[0].re*wave[dw*2].im + v1[0].im*wave[dw*2].re; + + r2 = r4 + r0; i2 = i4 + i0; + r4 -= r0; i4 -= i0; + + r0 = v0[0].re; i0 = v0[0].im; + r5 = r1 + r2; i5 = i1 + i2; + + v0[0].re = r0 + r5; v0[0].im = i0 + i5; + + r0 -= (T)0.25*r5; i0 -= (T)0.25*i5; + r1 = fft5_2*(r1 - r2); i1 = fft5_2*(i1 - i2); + r2 = -fft5_3*(i3 + i4); i2 = fft5_3*(r3 + r4); + + i3 *= -fft5_5; r3 *= fft5_5; + i4 *= -fft5_4; r4 *= fft5_4; + + r5 = r2 + i3; i5 = i2 + r3; + r2 -= i4; i2 -= r4; + + r3 = r0 + r1; i3 = i0 + i1; + r0 -= r1; i0 -= i1; + + v0[nx].re = r3 + r2; v0[nx].im = i3 + i2; + v2[0].re = r3 - r2; v2[0].im = i3 - i2; + + v1[0].re = r0 + r5; v1[0].im = i0 + i5; + v1[nx].re = r0 - r5; v1[nx].im = i0 - i5; + } + } + } + else + { + // radix-"factor" - an odd number + int p, q, factor2 = (factor - 1)/2; + int d, dd, dw_f = tab_size/factor; + Complex* a = buf; + Complex* b = buf + factor2; + + for( i = 0; i < n0; i += n ) + { + for( j = 0, dw = 0; j < nx; j++, dw += dw0 ) + { + Complex* v = dst + i + j; + Complex v_0 = v[0]; + Complex vn_0 = v_0; + + if( j == 0 ) + { + for( p = 1, k = nx; p <= factor2; p++, k += nx ) + { + T r0 = v[k].re + v[n-k].re; + T i0 = v[k].im - v[n-k].im; + T r1 = v[k].re - v[n-k].re; + T i1 = v[k].im + v[n-k].im; + + vn_0.re += r0; vn_0.im += i1; + a[p-1].re = r0; a[p-1].im = i0; + b[p-1].re = r1; b[p-1].im = i1; + } + } + else + { + const Complex* wave_ = wave + dw*factor; + d = dw; + + for( p = 1, k = nx; p <= factor2; p++, k += nx, d += dw ) + { + T r2 = v[k].re*wave[d].re - v[k].im*wave[d].im; + T i2 = v[k].re*wave[d].im + v[k].im*wave[d].re; + + T r1 = v[n-k].re*wave_[-d].re - v[n-k].im*wave_[-d].im; + T i1 = v[n-k].re*wave_[-d].im + v[n-k].im*wave_[-d].re; + + T r0 = r2 + r1; + T i0 = i2 - i1; + r1 = r2 - r1; + i1 = i2 + i1; + + vn_0.re += r0; vn_0.im += i1; + a[p-1].re = r0; a[p-1].im = i0; + b[p-1].re = r1; b[p-1].im = i1; + } + } + + v[0] = vn_0; + + for( p = 1, k = nx; p <= factor2; p++, k += nx ) + { + Complex s0 = v_0, s1 = v_0; + d = dd = dw_f*p; + + for( q = 0; q < factor2; q++ ) + { + T r0 = wave[d].re * a[q].re; + T i0 = wave[d].im * a[q].im; + T r1 = wave[d].re * b[q].im; + T i1 = wave[d].im * b[q].re; + + s1.re += r0 + i0; s0.re += r0 - i0; + s1.im += r1 - i1; s0.im += r1 + i1; + + d += dd; + d -= -(d >= tab_size) & tab_size; + } + + v[k] = s0; + v[n-k] = s1; + } + } + } + } + } + + if( scale != 1 ) + { + T re_scale = scale, im_scale = scale; + if( inv ) + im_scale = -im_scale; + + for( i = 0; i < n0; i++ ) + { + T t0 = dst[i].re*re_scale; + T t1 = dst[i].im*im_scale; + dst[i].re = t0; + dst[i].im = t1; + } + } + else if( inv ) + { + for( i = 0; i <= n0 - 2; i += 2 ) + { + T t0 = -dst[i].im; + T t1 = -dst[i+1].im; + dst[i].im = t0; + dst[i+1].im = t1; + } + + if( i < n0 ) + dst[n0-1].im = -dst[n0-1].im; + } +} + + +/* FFT of real vector + output vector format: + re(0), re(1), im(1), ... , re(n/2-1), im((n+1)/2-1) [, re((n+1)/2)] OR ... + re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */ +template static void +RealDFT( const T* src, T* dst, int n, int nf, int* factors, const int* itab, + const Complex* wave, int tab_size, const void* +#ifdef HAVE_IPP + spec +#endif + , + Complex* buf, int flags, double _scale ) +{ + int complex_output = (flags & DFT_COMPLEX_INPUT_OR_OUTPUT) != 0; + T scale = (T)_scale; + int j, n2 = n >> 1; + dst += complex_output; + +#ifdef HAVE_IPP + if( spec ) + { + ippsDFTFwd_RToPack( src, dst, spec, (uchar*)buf ); + goto finalize; + } +#endif + assert( tab_size == n ); + + if( n == 1 ) + { + dst[0] = src[0]*scale; + } + else if( n == 2 ) + { + T t = (src[0] + src[1])*scale; + dst[1] = (src[0] - src[1])*scale; + dst[0] = t; + } + else if( n & 1 ) + { + dst -= complex_output; + Complex* _dst = (Complex*)dst; + _dst[0].re = src[0]*scale; + _dst[0].im = 0; + for( j = 1; j < n; j += 2 ) + { + T t0 = src[itab[j]]*scale; + T t1 = src[itab[j+1]]*scale; + _dst[j].re = t0; + _dst[j].im = 0; + _dst[j+1].re = t1; + _dst[j+1].im = 0; + } + DFT( _dst, _dst, n, nf, factors, itab, wave, + tab_size, 0, buf, DFT_NO_PERMUTE, 1 ); + if( !complex_output ) + dst[1] = dst[0]; + } + else + { + T t0, t; + T h1_re, h1_im, h2_re, h2_im; + T scale2 = scale*(T)0.5; + factors[0] >>= 1; + + DFT( (Complex*)src, (Complex*)dst, n2, nf - (factors[0] == 1), + factors + (factors[0] == 1), + itab, wave, tab_size, 0, buf, 0, 1 ); + factors[0] <<= 1; + + t = dst[0] - dst[1]; + dst[0] = (dst[0] + dst[1])*scale; + dst[1] = t*scale; + + t0 = dst[n2]; + t = dst[n-1]; + dst[n-1] = dst[1]; + + for( j = 2, wave++; j < n2; j += 2, wave++ ) + { + /* calc odd */ + h2_re = scale2*(dst[j+1] + t); + h2_im = scale2*(dst[n-j] - dst[j]); + + /* calc even */ + h1_re = scale2*(dst[j] + dst[n-j]); + h1_im = scale2*(dst[j+1] - t); + + /* rotate */ + t = h2_re*wave->re - h2_im*wave->im; + h2_im = h2_re*wave->im + h2_im*wave->re; + h2_re = t; + t = dst[n-j-1]; + + dst[j-1] = h1_re + h2_re; + dst[n-j-1] = h1_re - h2_re; + dst[j] = h1_im + h2_im; + dst[n-j] = h2_im - h1_im; + } + + if( j <= n2 ) + { + dst[n2-1] = t0*scale; + dst[n2] = -t*scale; + } + } + +#ifdef HAVE_IPP +finalize: +#endif + if( complex_output && (n & 1) == 0 ) + { + dst[-1] = dst[0]; + dst[0] = 0; + if( (n & 1) == 0 ) + dst[n] = 0; + } +} + +/* Inverse FFT of complex conjugate-symmetric vector + input vector format: + re[0], re[1], im[1], ... , re[n/2-1], im[n/2-1], re[n/2] OR + re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */ +template static void +CCSIDFT( const T* src, T* dst, int n, int nf, int* factors, const int* itab, + const Complex* wave, int tab_size, + const void* +#ifdef HAVE_IPP + spec +#endif + , Complex* buf, + int flags, double _scale ) +{ + int complex_input = (flags & DFT_COMPLEX_INPUT_OR_OUTPUT) != 0; + int j, k, n2 = (n+1) >> 1; + T scale = (T)_scale; + T save_s1 = 0.; + T t0, t1, t2, t3, t; + + assert( tab_size == n ); + + if( complex_input ) + { + assert( src != dst ); + save_s1 = src[1]; + ((T*)src)[1] = src[0]; + src++; + } +#ifdef HAVE_IPP + if( spec ) + { + ippsDFTInv_PackToR( src, dst, spec, (uchar*)buf ); + goto finalize; + } +#endif + if( n == 1 ) + { + dst[0] = (T)(src[0]*scale); + } + else if( n == 2 ) + { + t = (src[0] + src[1])*scale; + dst[1] = (src[0] - src[1])*scale; + dst[0] = t; + } + else if( n & 1 ) + { + Complex* _src = (Complex*)(src-1); + Complex* _dst = (Complex*)dst; + + _dst[0].re = src[0]; + _dst[0].im = 0; + for( j = 1; j < n2; j++ ) + { + int k0 = itab[j], k1 = itab[n-j]; + t0 = _src[j].re; t1 = _src[j].im; + _dst[k0].re = t0; _dst[k0].im = -t1; + _dst[k1].re = t0; _dst[k1].im = t1; + } + + DFT( _dst, _dst, n, nf, factors, itab, wave, + tab_size, 0, buf, DFT_NO_PERMUTE, 1. ); + dst[0] *= scale; + for( j = 1; j < n; j += 2 ) + { + t0 = dst[j*2]*scale; + t1 = dst[j*2+2]*scale; + dst[j] = t0; + dst[j+1] = t1; + } + } + else + { + int inplace = src == dst; + const Complex* w = wave; + + t = src[1]; + t0 = (src[0] + src[n-1]); + t1 = (src[n-1] - src[0]); + dst[0] = t0; + dst[1] = t1; + + for( j = 2, w++; j < n2; j += 2, w++ ) + { + T h1_re, h1_im, h2_re, h2_im; + + h1_re = (t + src[n-j-1]); + h1_im = (src[j] - src[n-j]); + + h2_re = (t - src[n-j-1]); + h2_im = (src[j] + src[n-j]); + + t = h2_re*w->re + h2_im*w->im; + h2_im = h2_im*w->re - h2_re*w->im; + h2_re = t; + + t = src[j+1]; + t0 = h1_re - h2_im; + t1 = -h1_im - h2_re; + t2 = h1_re + h2_im; + t3 = h1_im - h2_re; + + if( inplace ) + { + dst[j] = t0; + dst[j+1] = t1; + dst[n-j] = t2; + dst[n-j+1]= t3; + } + else + { + int j2 = j >> 1; + k = itab[j2]; + dst[k] = t0; + dst[k+1] = t1; + k = itab[n2-j2]; + dst[k] = t2; + dst[k+1]= t3; + } + } + + if( j <= n2 ) + { + t0 = t*2; + t1 = src[n2]*2; + + if( inplace ) + { + dst[n2] = t0; + dst[n2+1] = t1; + } + else + { + k = itab[n2]; + dst[k*2] = t0; + dst[k*2+1] = t1; + } + } + + factors[0] >>= 1; + DFT( (Complex*)dst, (Complex*)dst, n2, + nf - (factors[0] == 1), + factors + (factors[0] == 1), itab, + wave, tab_size, 0, buf, + inplace ? 0 : DFT_NO_PERMUTE, 1. ); + factors[0] <<= 1; + + for( j = 0; j < n; j += 2 ) + { + t0 = dst[j]*scale; + t1 = dst[j+1]*(-scale); + dst[j] = t0; + dst[j+1] = t1; + } + } + +#ifdef HAVE_IPP +finalize: +#endif + if( complex_input ) + ((T*)src)[0] = (T)save_s1; +} + +static void +CopyColumn( const uchar* _src, size_t src_step, + uchar* _dst, size_t dst_step, + int len, size_t elem_size ) +{ + int i, t0, t1; + const int* src = (const int*)_src; + int* dst = (int*)_dst; + src_step /= sizeof(src[0]); + dst_step /= sizeof(dst[0]); + + if( elem_size == sizeof(int) ) + { + for( i = 0; i < len; i++, src += src_step, dst += dst_step ) + dst[0] = src[0]; + } + else if( elem_size == sizeof(int)*2 ) + { + for( i = 0; i < len; i++, src += src_step, dst += dst_step ) + { + t0 = src[0]; t1 = src[1]; + dst[0] = t0; dst[1] = t1; + } + } + else if( elem_size == sizeof(int)*4 ) + { + for( i = 0; i < len; i++, src += src_step, dst += dst_step ) + { + t0 = src[0]; t1 = src[1]; + dst[0] = t0; dst[1] = t1; + t0 = src[2]; t1 = src[3]; + dst[2] = t0; dst[3] = t1; + } + } +} + + +static void +CopyFrom2Columns( const uchar* _src, size_t src_step, + uchar* _dst0, uchar* _dst1, + int len, size_t elem_size ) +{ + int i, t0, t1; + const int* src = (const int*)_src; + int* dst0 = (int*)_dst0; + int* dst1 = (int*)_dst1; + src_step /= sizeof(src[0]); + + if( elem_size == sizeof(int) ) + { + for( i = 0; i < len; i++, src += src_step ) + { + t0 = src[0]; t1 = src[1]; + dst0[i] = t0; dst1[i] = t1; + } + } + else if( elem_size == sizeof(int)*2 ) + { + for( i = 0; i < len*2; i += 2, src += src_step ) + { + t0 = src[0]; t1 = src[1]; + dst0[i] = t0; dst0[i+1] = t1; + t0 = src[2]; t1 = src[3]; + dst1[i] = t0; dst1[i+1] = t1; + } + } + else if( elem_size == sizeof(int)*4 ) + { + for( i = 0; i < len*4; i += 4, src += src_step ) + { + t0 = src[0]; t1 = src[1]; + dst0[i] = t0; dst0[i+1] = t1; + t0 = src[2]; t1 = src[3]; + dst0[i+2] = t0; dst0[i+3] = t1; + t0 = src[4]; t1 = src[5]; + dst1[i] = t0; dst1[i+1] = t1; + t0 = src[6]; t1 = src[7]; + dst1[i+2] = t0; dst1[i+3] = t1; + } + } +} + + +static void +CopyTo2Columns( const uchar* _src0, const uchar* _src1, + uchar* _dst, size_t dst_step, + int len, size_t elem_size ) +{ + int i, t0, t1; + const int* src0 = (const int*)_src0; + const int* src1 = (const int*)_src1; + int* dst = (int*)_dst; + dst_step /= sizeof(dst[0]); + + if( elem_size == sizeof(int) ) + { + for( i = 0; i < len; i++, dst += dst_step ) + { + t0 = src0[i]; t1 = src1[i]; + dst[0] = t0; dst[1] = t1; + } + } + else if( elem_size == sizeof(int)*2 ) + { + for( i = 0; i < len*2; i += 2, dst += dst_step ) + { + t0 = src0[i]; t1 = src0[i+1]; + dst[0] = t0; dst[1] = t1; + t0 = src1[i]; t1 = src1[i+1]; + dst[2] = t0; dst[3] = t1; + } + } + else if( elem_size == sizeof(int)*4 ) + { + for( i = 0; i < len*4; i += 4, dst += dst_step ) + { + t0 = src0[i]; t1 = src0[i+1]; + dst[0] = t0; dst[1] = t1; + t0 = src0[i+2]; t1 = src0[i+3]; + dst[2] = t0; dst[3] = t1; + t0 = src1[i]; t1 = src1[i+1]; + dst[4] = t0; dst[5] = t1; + t0 = src1[i+2]; t1 = src1[i+3]; + dst[6] = t0; dst[7] = t1; + } + } +} + + +static void +ExpandCCS( uchar* _ptr, int n, int elem_size ) +{ + int i; + if( elem_size == (int)sizeof(float) ) + { + float* p = (float*)_ptr; + for( i = 1; i < (n+1)/2; i++ ) + { + p[(n-i)*2] = p[i*2-1]; + p[(n-i)*2+1] = -p[i*2]; + } + if( (n & 1) == 0 ) + { + p[n] = p[n-1]; + p[n+1] = 0.f; + n--; + } + for( i = n-1; i > 0; i-- ) + p[i+1] = p[i]; + p[1] = 0.f; + } + else + { + double* p = (double*)_ptr; + for( i = 1; i < (n+1)/2; i++ ) + { + p[(n-i)*2] = p[i*2-1]; + p[(n-i)*2+1] = -p[i*2]; + } + if( (n & 1) == 0 ) + { + p[n] = p[n-1]; + p[n+1] = 0.f; + n--; + } + for( i = n-1; i > 0; i-- ) + p[i+1] = p[i]; + p[1] = 0.f; + } +} + + +typedef void (*DFTFunc)( + const void* src, void* dst, int n, int nf, int* factors, + const int* itab, const void* wave, int tab_size, + const void* spec, void* buf, int inv, double scale ); + +static void DFT_32f( const Complexf* src, Complexf* dst, int n, + int nf, const int* factors, const int* itab, + const Complexf* wave, int tab_size, + const void* spec, Complexf* buf, + int flags, double scale ) +{ + DFT(src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + +static void DFT_64f( const Complexd* src, Complexd* dst, int n, + int nf, const int* factors, const int* itab, + const Complexd* wave, int tab_size, + const void* spec, Complexd* buf, + int flags, double scale ) +{ + DFT(src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + + +static void RealDFT_32f( const float* src, float* dst, int n, int nf, int* factors, + const int* itab, const Complexf* wave, int tab_size, const void* spec, + Complexf* buf, int flags, double scale ) +{ + RealDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + +static void RealDFT_64f( const double* src, double* dst, int n, int nf, int* factors, + const int* itab, const Complexd* wave, int tab_size, const void* spec, + Complexd* buf, int flags, double scale ) +{ + RealDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + +static void CCSIDFT_32f( const float* src, float* dst, int n, int nf, int* factors, + const int* itab, const Complexf* wave, int tab_size, const void* spec, + Complexf* buf, int flags, double scale ) +{ + CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + +static void CCSIDFT_64f( const double* src, double* dst, int n, int nf, int* factors, + const int* itab, const Complexd* wave, int tab_size, const void* spec, + Complexd* buf, int flags, double scale ) +{ + CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale); +} + +} + + +void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows ) +{ + static DFTFunc dft_tbl[6] = + { + (DFTFunc)DFT_32f, + (DFTFunc)RealDFT_32f, + (DFTFunc)CCSIDFT_32f, + (DFTFunc)DFT_64f, + (DFTFunc)RealDFT_64f, + (DFTFunc)CCSIDFT_64f + }; + + AutoBuffer buf; + void *spec = 0; + + Mat src0 = _src0.getMat(), src = src0; + int prev_len = 0, stage = 0; + bool inv = (flags & DFT_INVERSE) != 0; + int nf = 0, real_transform = src.channels() == 1 || (inv && (flags & DFT_REAL_OUTPUT)!=0); + int type = src.type(), depth = src.depth(); + int elem_size = (int)src.elemSize1(), complex_elem_size = elem_size*2; + int factors[34]; + bool inplace_transform = false; +#ifdef HAVE_IPP + void *spec_r = 0, *spec_c = 0; + int ipp_norm_flag = !(flags & DFT_SCALE) ? 8 : inv ? 2 : 1; +#endif + + CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 ); + + if( !inv && src.channels() == 1 && (flags & DFT_COMPLEX_OUTPUT) ) + _dst.create( src.size(), CV_MAKETYPE(depth, 2) ); + else if( inv && src.channels() == 2 && (flags & DFT_REAL_OUTPUT) ) + _dst.create( src.size(), depth ); + else + _dst.create( src.size(), type ); + + Mat dst = _dst.getMat(); + + if( !real_transform ) + elem_size = complex_elem_size; + + if( src.cols == 1 && nonzero_rows > 0 ) + CV_Error( CV_StsNotImplemented, + "This mode (using nonzero_rows with a single-column matrix) breaks the function's logic, so it is prohibited.\n" + "For fast convolution/correlation use 2-column matrix or single-row matrix instead" ); + + // determine, which transform to do first - row-wise + // (stage 0) or column-wise (stage 1) transform + if( !(flags & DFT_ROWS) && src.rows > 1 && + ((src.cols == 1 && (!src.isContinuous() || !dst.isContinuous())) || + (src.cols > 1 && inv && real_transform)) ) + stage = 1; + + for(;;) + { + double scale = 1; + uchar* wave = 0; + int* itab = 0; + uchar* ptr; + int i, len, count, sz = 0; + int use_buf = 0, odd_real = 0; + DFTFunc dft_func; + + if( stage == 0 ) // row-wise transform + { + len = !inv ? src.cols : dst.cols; + count = src.rows; + if( len == 1 && !(flags & DFT_ROWS) ) + { + len = !inv ? src.rows : dst.rows; + count = 1; + } + odd_real = real_transform && (len & 1); + } + else + { + len = dst.rows; + count = !inv ? src0.cols : dst.cols; + sz = 2*len*complex_elem_size; + } + + spec = 0; +#ifdef HAVE_IPP + if( len*count >= 64 ) // use IPP DFT if available + { + int ipp_sz = 0; + + if( real_transform && stage == 0 ) + { + if( depth == CV_32F ) + { + if( spec_r ) + IPPI_CALL( ippsDFTFree_R_32f( (IppsDFTSpec_R_32f*)spec_r )); + IPPI_CALL( ippsDFTInitAlloc_R_32f( + (IppsDFTSpec_R_32f**)&spec_r, len, ipp_norm_flag, ippAlgHintNone )); + IPPI_CALL( ippsDFTGetBufSize_R_32f( (IppsDFTSpec_R_32f*)spec_r, &ipp_sz )); + } + else + { + if( spec_r ) + IPPI_CALL( ippsDFTFree_R_64f( (IppsDFTSpec_R_64f*)spec_r )); + IPPI_CALL( ippsDFTInitAlloc_R_64f( + (IppsDFTSpec_R_64f**)&spec_r, len, ipp_norm_flag, ippAlgHintNone )); + IPPI_CALL( ippsDFTGetBufSize_R_64f( (IppsDFTSpec_R_64f*)spec_r, &ipp_sz )); + } + spec = spec_r; + } + else + { + if( depth == CV_32F ) + { + if( spec_c ) + IPPI_CALL( ippsDFTFree_C_32fc( (IppsDFTSpec_C_32fc*)spec_c )); + IPPI_CALL( ippsDFTInitAlloc_C_32fc( + (IppsDFTSpec_C_32fc**)&spec_c, len, ipp_norm_flag, ippAlgHintNone )); + IPPI_CALL( ippsDFTGetBufSize_C_32fc( (IppsDFTSpec_C_32fc*)spec_c, &ipp_sz )); + } + else + { + if( spec_c ) + IPPI_CALL( ippsDFTFree_C_64fc( (IppsDFTSpec_C_64fc*)spec_c )); + IPPI_CALL( ippsDFTInitAlloc_C_64fc( + (IppsDFTSpec_C_64fc**)&spec_c, len, ipp_norm_flag, ippAlgHintNone )); + IPPI_CALL( ippsDFTGetBufSize_C_64fc( (IppsDFTSpec_C_64fc*)spec_c, &ipp_sz )); + } + spec = spec_c; + } + + sz += ipp_sz; + } + else +#endif + { + if( len != prev_len ) + nf = DFTFactorize( len, factors ); + + inplace_transform = factors[0] == factors[nf-1]; + sz += len*(complex_elem_size + sizeof(int)); + i = nf > 1 && (factors[0] & 1) == 0; + if( (factors[i] & 1) != 0 && factors[i] > 5 ) + sz += (factors[i]+1)*complex_elem_size; + + if( (stage == 0 && ((src.data == dst.data && !inplace_transform) || odd_real)) || + (stage == 1 && !inplace_transform) ) + { + use_buf = 1; + sz += len*complex_elem_size; + } + } + + ptr = (uchar*)buf; + buf.allocate( sz + 32 ); + if( ptr != (uchar*)buf ) + prev_len = 0; // because we release the buffer, + // force recalculation of + // twiddle factors and permutation table + ptr = (uchar*)buf; + if( !spec ) + { + wave = ptr; + ptr += len*complex_elem_size; + itab = (int*)ptr; + ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 ); + + if( len != prev_len || (!inplace_transform && inv && real_transform)) + DFTInit( len, nf, factors, itab, complex_elem_size, + wave, stage == 0 && inv && real_transform ); + // otherwise reuse the tables calculated on the previous stage + } + + if( stage == 0 ) + { + uchar* tmp_buf = 0; + int dptr_offset = 0; + int dst_full_len = len*elem_size; + int _flags = (int)inv + (src.channels() != dst.channels() ? + DFT_COMPLEX_INPUT_OR_OUTPUT : 0); + if( use_buf ) + { + tmp_buf = ptr; + ptr += len*complex_elem_size; + if( odd_real && !inv && len > 1 && + !(_flags & DFT_COMPLEX_INPUT_OR_OUTPUT)) + dptr_offset = elem_size; + } + + if( !inv && (_flags & DFT_COMPLEX_INPUT_OR_OUTPUT) ) + dst_full_len += (len & 1) ? elem_size : complex_elem_size; + + dft_func = dft_tbl[(!real_transform ? 0 : !inv ? 1 : 2) + (depth == CV_64F)*3]; + + if( count > 1 && !(flags & DFT_ROWS) && (!inv || !real_transform) ) + stage = 1; + else if( flags & CV_DXT_SCALE ) + scale = 1./(len * (flags & DFT_ROWS ? 1 : count)); + + if( nonzero_rows <= 0 || nonzero_rows > count ) + nonzero_rows = count; + + for( i = 0; i < nonzero_rows; i++ ) + { + uchar* sptr = src.data + i*src.step; + uchar* dptr0 = dst.data + i*dst.step; + uchar* dptr = dptr0; + + if( tmp_buf ) + dptr = tmp_buf; + + dft_func( sptr, dptr, len, nf, factors, itab, wave, len, spec, ptr, _flags, scale ); + if( dptr != dptr0 ) + memcpy( dptr0, dptr + dptr_offset, dst_full_len ); + } + + for( ; i < count; i++ ) + { + uchar* dptr0 = dst.data + i*dst.step; + memset( dptr0, 0, dst_full_len ); + } + + if( stage != 1 ) + break; + src = dst; + } + else + { + int a = 0, b = count; + uchar *buf0, *buf1, *dbuf0, *dbuf1; + uchar* sptr0 = src.data; + uchar* dptr0 = dst.data; + buf0 = ptr; + ptr += len*complex_elem_size; + buf1 = ptr; + ptr += len*complex_elem_size; + dbuf0 = buf0, dbuf1 = buf1; + + if( use_buf ) + { + dbuf1 = ptr; + dbuf0 = buf1; + ptr += len*complex_elem_size; + } + + dft_func = dft_tbl[(depth == CV_64F)*3]; + + if( real_transform && inv && src.cols > 1 ) + stage = 0; + else if( flags & CV_DXT_SCALE ) + scale = 1./(len * count); + + if( real_transform ) + { + int even; + a = 1; + even = (count & 1) == 0; + b = (count+1)/2; + if( !inv ) + { + memset( buf0, 0, len*complex_elem_size ); + CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, elem_size ); + sptr0 += dst.channels()*elem_size; + if( even ) + { + memset( buf1, 0, len*complex_elem_size ); + CopyColumn( sptr0 + (count-2)*elem_size, src.step, + buf1, complex_elem_size, len, elem_size ); + } + } + else if( src.channels() == 1 ) + { + CopyColumn( sptr0, src.step, buf0, elem_size, len, elem_size ); + ExpandCCS( buf0, len, elem_size ); + if( even ) + { + CopyColumn( sptr0 + (count-1)*elem_size, src.step, + buf1, elem_size, len, elem_size ); + ExpandCCS( buf1, len, elem_size ); + } + sptr0 += elem_size; + } + else + { + CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, complex_elem_size ); + if( even ) + { + CopyColumn( sptr0 + b*complex_elem_size, src.step, + buf1, complex_elem_size, len, complex_elem_size ); + } + sptr0 += complex_elem_size; + } + + if( even ) + dft_func( buf1, dbuf1, len, nf, factors, itab, + wave, len, spec, ptr, inv, scale ); + dft_func( buf0, dbuf0, len, nf, factors, itab, + wave, len, spec, ptr, inv, scale ); + + if( dst.channels() == 1 ) + { + if( !inv ) + { + // copy the half of output vector to the first/last column. + // before doing that, defgragment the vector + memcpy( dbuf0 + elem_size, dbuf0, elem_size ); + CopyColumn( dbuf0 + elem_size, elem_size, dptr0, + dst.step, len, elem_size ); + if( even ) + { + memcpy( dbuf1 + elem_size, dbuf1, elem_size ); + CopyColumn( dbuf1 + elem_size, elem_size, + dptr0 + (count-1)*elem_size, + dst.step, len, elem_size ); + } + dptr0 += elem_size; + } + else + { + // copy the real part of the complex vector to the first/last column + CopyColumn( dbuf0, complex_elem_size, dptr0, dst.step, len, elem_size ); + if( even ) + CopyColumn( dbuf1, complex_elem_size, dptr0 + (count-1)*elem_size, + dst.step, len, elem_size ); + dptr0 += elem_size; + } + } + else + { + assert( !inv ); + CopyColumn( dbuf0, complex_elem_size, dptr0, + dst.step, len, complex_elem_size ); + if( even ) + CopyColumn( dbuf1, complex_elem_size, + dptr0 + b*complex_elem_size, + dst.step, len, complex_elem_size ); + dptr0 += complex_elem_size; + } + } + + for( i = a; i < b; i += 2 ) + { + if( i+1 < b ) + { + CopyFrom2Columns( sptr0, src.step, buf0, buf1, len, complex_elem_size ); + dft_func( buf1, dbuf1, len, nf, factors, itab, + wave, len, spec, ptr, inv, scale ); + } + else + CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, complex_elem_size ); + + dft_func( buf0, dbuf0, len, nf, factors, itab, + wave, len, spec, ptr, inv, scale ); + + if( i+1 < b ) + CopyTo2Columns( dbuf0, dbuf1, dptr0, dst.step, len, complex_elem_size ); + else + CopyColumn( dbuf0, complex_elem_size, dptr0, dst.step, len, complex_elem_size ); + sptr0 += 2*complex_elem_size; + dptr0 += 2*complex_elem_size; + } + + if( stage != 0 ) + { + if( !inv && real_transform && dst.channels() == 2 && len > 1 ) + { + int n = dst.cols; + if( elem_size == (int)sizeof(float) ) + { + float* p0 = (float*)dst.data; + size_t dstep = dst.step/sizeof(p0[0]); + for( i = 0; i < len; i++ ) + { + float* p = p0 + dstep*i; + float* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i); + + for( int j = 1; j < (n+1)/2; j++ ) + { + p[(n-j)*2] = q[j*2]; + p[(n-j)*2+1] = -q[j*2+1]; + } + } + } + else + { + double* p0 = (double*)dst.data; + size_t dstep = dst.step/sizeof(p0[0]); + for( i = 0; i < len; i++ ) + { + double* p = p0 + dstep*i; + double* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i); + + for( int j = 1; j < (n+1)/2; j++ ) + { + p[(n-j)*2] = q[j*2]; + p[(n-j)*2+1] = -q[j*2+1]; + } + } + } + } + break; + } + src = dst; + } + } + +#ifdef HAVE_IPP + if( spec_c ) + { + if( depth == CV_32F ) + ippsDFTFree_C_32fc( (IppsDFTSpec_C_32fc*)spec_c ); + else + ippsDFTFree_C_64fc( (IppsDFTSpec_C_64fc*)spec_c ); + } + + if( spec_r ) + { + if( depth == CV_32F ) + ippsDFTFree_R_32f( (IppsDFTSpec_R_32f*)spec_r ); + else + ippsDFTFree_R_64f( (IppsDFTSpec_R_64f*)spec_r ); + } +#endif +} + + +void cv::idft( InputArray src, OutputArray dst, int flags, int nonzero_rows ) +{ + dft( src, dst, flags | DFT_INVERSE, nonzero_rows ); +} + +void cv::mulSpectrums( InputArray _srcA, InputArray _srcB, + OutputArray _dst, int flags, bool conjB ) +{ + Mat srcA = _srcA.getMat(), srcB = _srcB.getMat(); + int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type(); + int rows = srcA.rows, cols = srcA.cols; + int j, k; + + CV_Assert( type == srcB.type() && srcA.size() == srcB.size() ); + CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 ); + + _dst.create( srcA.rows, srcA.cols, type ); + Mat dst = _dst.getMat(); + + bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 && + srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous())); + + if( is_1d && !(flags & DFT_ROWS) ) + cols = cols + rows - 1, rows = 1; + + int ncols = cols*cn; + int j0 = cn == 1; + int j1 = ncols - (cols % 2 == 0 && cn == 1); + + if( depth == CV_32F ) + { + const float* dataA = (const float*)srcA.data; + const float* dataB = (const float*)srcB.data; + float* dataC = (float*)dst.data; + + size_t stepA = srcA.step/sizeof(dataA[0]); + size_t stepB = srcB.step/sizeof(dataB[0]); + size_t stepC = dst.step/sizeof(dataC[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; + dataC[0] = dataA[0]*dataB[0]; + if( rows % 2 == 0 ) + dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB]; + if( !conjB ) + for( j = 1; j <= rows - 2; j += 2 ) + { + double re = (double)dataA[j*stepA]*dataB[j*stepB] - + (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + double im = (double)dataA[j*stepA]*dataB[(j+1)*stepB] + + (double)dataA[(j+1)*stepA]*dataB[j*stepB]; + dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im; + } + else + for( j = 1; j <= rows - 2; j += 2 ) + { + double re = (double)dataA[j*stepA]*dataB[j*stepB] + + (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] - + (double)dataA[j*stepA]*dataB[(j+1)*stepB]; + dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im; + } + if( k == 1 ) + dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; + } + } + + for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) + { + if( is_1d && cn == 1 ) + { + dataC[0] = dataA[0]*dataB[0]; + if( cols % 2 == 0 ) + dataC[j1] = dataA[j1]*dataB[j1]; + } + + if( !conjB ) + for( j = j0; j < j1; j += 2 ) + { + double re = (double)dataA[j]*dataB[j] - (double)dataA[j+1]*dataB[j+1]; + double im = (double)dataA[j+1]*dataB[j] + (double)dataA[j]*dataB[j+1]; + dataC[j] = (float)re; dataC[j+1] = (float)im; + } + else + for( j = j0; j < j1; j += 2 ) + { + double re = (double)dataA[j]*dataB[j] + (double)dataA[j+1]*dataB[j+1]; + double im = (double)dataA[j+1]*dataB[j] - (double)dataA[j]*dataB[j+1]; + dataC[j] = (float)re; dataC[j+1] = (float)im; + } + } + } + else + { + const double* dataA = (const double*)srcA.data; + const double* dataB = (const double*)srcB.data; + double* dataC = (double*)dst.data; + + size_t stepA = srcA.step/sizeof(dataA[0]); + size_t stepB = srcB.step/sizeof(dataB[0]); + size_t stepC = dst.step/sizeof(dataC[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; + dataC[0] = dataA[0]*dataB[0]; + if( rows % 2 == 0 ) + dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB]; + if( !conjB ) + for( j = 1; j <= rows - 2; j += 2 ) + { + double re = dataA[j*stepA]*dataB[j*stepB] - + dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + double im = dataA[j*stepA]*dataB[(j+1)*stepB] + + dataA[(j+1)*stepA]*dataB[j*stepB]; + dataC[j*stepC] = re; dataC[(j+1)*stepC] = im; + } + else + for( j = 1; j <= rows - 2; j += 2 ) + { + double re = dataA[j*stepA]*dataB[j*stepB] + + dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + double im = dataA[(j+1)*stepA]*dataB[j*stepB] - + dataA[j*stepA]*dataB[(j+1)*stepB]; + dataC[j*stepC] = re; dataC[(j+1)*stepC] = im; + } + if( k == 1 ) + dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; + } + } + + for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) + { + if( is_1d && cn == 1 ) + { + dataC[0] = dataA[0]*dataB[0]; + if( cols % 2 == 0 ) + dataC[j1] = dataA[j1]*dataB[j1]; + } + + if( !conjB ) + for( j = j0; j < j1; j += 2 ) + { + double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]; + double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]; + dataC[j] = re; dataC[j+1] = im; + } + else + for( j = j0; j < j1; j += 2 ) + { + double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]; + double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]; + dataC[j] = re; dataC[j+1] = im; + } + } + } +} + + +/****************************************************************************************\ + Discrete Cosine Transform +\****************************************************************************************/ + +namespace cv +{ + +/* DCT is calculated using DFT, as described here: + http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/: +*/ +template static void +DCT( const T* src, int src_step, T* dft_src, T* dft_dst, T* dst, int dst_step, + int n, int nf, int* factors, const int* itab, const Complex* dft_wave, + const Complex* dct_wave, const void* spec, Complex* buf ) +{ + static const T sin_45 = (T)0.70710678118654752440084436210485; + int j, n2 = n >> 1; + + src_step /= sizeof(src[0]); + dst_step /= sizeof(dst[0]); + T* dst1 = dst + (n-1)*dst_step; + + if( n == 1 ) + { + dst[0] = src[0]; + return; + } + + for( j = 0; j < n2; j++, src += src_step*2 ) + { + dft_src[j] = src[0]; + dft_src[n-j-1] = src[src_step]; + } + + RealDFT( dft_src, dft_dst, n, nf, factors, + itab, dft_wave, n, spec, buf, 0, 1.0 ); + src = dft_dst; + + dst[0] = (T)(src[0]*dct_wave->re*sin_45); + dst += dst_step; + for( j = 1, dct_wave++; j < n2; j++, dct_wave++, + dst += dst_step, dst1 -= dst_step ) + { + T t0 = dct_wave->re*src[j*2-1] - dct_wave->im*src[j*2]; + T t1 = -dct_wave->im*src[j*2-1] - dct_wave->re*src[j*2]; + dst[0] = t0; + dst1[0] = t1; + } + + dst[0] = src[n-1]*dct_wave->re; +} + + +template static void +IDCT( const T* src, int src_step, T* dft_src, T* dft_dst, T* dst, int dst_step, + int n, int nf, int* factors, const int* itab, const Complex* dft_wave, + const Complex* dct_wave, const void* spec, Complex* buf ) +{ + static const T sin_45 = (T)0.70710678118654752440084436210485; + int j, n2 = n >> 1; + + src_step /= sizeof(src[0]); + dst_step /= sizeof(dst[0]); + const T* src1 = src + (n-1)*src_step; + + if( n == 1 ) + { + dst[0] = src[0]; + return; + } + + dft_src[0] = (T)(src[0]*2*dct_wave->re*sin_45); + src += src_step; + for( j = 1, dct_wave++; j < n2; j++, dct_wave++, + src += src_step, src1 -= src_step ) + { + T t0 = dct_wave->re*src[0] - dct_wave->im*src1[0]; + T t1 = -dct_wave->im*src[0] - dct_wave->re*src1[0]; + dft_src[j*2-1] = t0; + dft_src[j*2] = t1; + } + + dft_src[n-1] = (T)(src[0]*2*dct_wave->re); + CCSIDFT( dft_src, dft_dst, n, nf, factors, itab, + dft_wave, n, spec, buf, 0, 1.0 ); + + for( j = 0; j < n2; j++, dst += dst_step*2 ) + { + dst[0] = dft_dst[j]; + dst[dst_step] = dft_dst[n-j-1]; + } +} + + +static void +DCTInit( int n, int elem_size, void* _wave, int inv ) +{ + static const double DctScale[] = + { + 0.707106781186547570, 0.500000000000000000, 0.353553390593273790, + 0.250000000000000000, 0.176776695296636890, 0.125000000000000000, + 0.088388347648318447, 0.062500000000000000, 0.044194173824159223, + 0.031250000000000000, 0.022097086912079612, 0.015625000000000000, + 0.011048543456039806, 0.007812500000000000, 0.005524271728019903, + 0.003906250000000000, 0.002762135864009952, 0.001953125000000000, + 0.001381067932004976, 0.000976562500000000, 0.000690533966002488, + 0.000488281250000000, 0.000345266983001244, 0.000244140625000000, + 0.000172633491500622, 0.000122070312500000, 0.000086316745750311, + 0.000061035156250000, 0.000043158372875155, 0.000030517578125000 + }; + + int i; + Complex w, w1; + double t, scale; + + if( n == 1 ) + return; + + assert( (n&1) == 0 ); + + if( (n & (n - 1)) == 0 ) + { + int m; + for( m = 0; (unsigned)(1 << m) < (unsigned)n; m++ ) + ; + scale = (!inv ? 2 : 1)*DctScale[m]; + w1.re = DFTTab[m+2][0]; + w1.im = -DFTTab[m+2][1]; + } + else + { + t = 1./(2*n); + scale = (!inv ? 2 : 1)*std::sqrt(t); + w1.im = sin(-CV_PI*t); + w1.re = std::sqrt(1. - w1.im*w1.im); + } + n >>= 1; + + if( elem_size == sizeof(Complex) ) + { + Complex* wave = (Complex*)_wave; + + w.re = scale; + w.im = 0.; + + for( i = 0; i <= n; i++ ) + { + wave[i] = w; + t = w.re*w1.re - w.im*w1.im; + w.im = w.re*w1.im + w.im*w1.re; + w.re = t; + } + } + else + { + Complex* wave = (Complex*)_wave; + assert( elem_size == sizeof(Complex) ); + + w.re = (float)scale; + w.im = 0.f; + + for( i = 0; i <= n; i++ ) + { + wave[i].re = (float)w.re; + wave[i].im = (float)w.im; + t = w.re*w1.re - w.im*w1.im; + w.im = w.re*w1.im + w.im*w1.re; + w.re = t; + } + } +} + + +typedef void (*DCTFunc)(const void* src, int src_step, void* dft_src, + void* dft_dst, void* dst, int dst_step, int n, + int nf, int* factors, const int* itab, const void* dft_wave, + const void* dct_wave, const void* spec, void* buf ); + +static void DCT_32f(const float* src, int src_step, float* dft_src, float* dft_dst, + float* dst, int dst_step, int n, int nf, int* factors, const int* itab, + const Complexf* dft_wave, const Complexf* dct_wave, const void* spec, Complexf* buf ) +{ + DCT(src, src_step, dft_src, dft_dst, dst, dst_step, + n, nf, factors, itab, dft_wave, dct_wave, spec, buf); +} + +static void IDCT_32f(const float* src, int src_step, float* dft_src, float* dft_dst, + float* dst, int dst_step, int n, int nf, int* factors, const int* itab, + const Complexf* dft_wave, const Complexf* dct_wave, const void* spec, Complexf* buf ) +{ + IDCT(src, src_step, dft_src, dft_dst, dst, dst_step, + n, nf, factors, itab, dft_wave, dct_wave, spec, buf); +} + +static void DCT_64f(const double* src, int src_step, double* dft_src, double* dft_dst, + double* dst, int dst_step, int n, int nf, int* factors, const int* itab, + const Complexd* dft_wave, const Complexd* dct_wave, const void* spec, Complexd* buf ) +{ + DCT(src, src_step, dft_src, dft_dst, dst, dst_step, + n, nf, factors, itab, dft_wave, dct_wave, spec, buf); +} + +static void IDCT_64f(const double* src, int src_step, double* dft_src, double* dft_dst, + double* dst, int dst_step, int n, int nf, int* factors, const int* itab, + const Complexd* dft_wave, const Complexd* dct_wave, const void* spec, Complexd* buf ) +{ + IDCT(src, src_step, dft_src, dft_dst, dst, dst_step, + n, nf, factors, itab, dft_wave, dct_wave, spec, buf); +} + +} + +void cv::dct( InputArray _src0, OutputArray _dst, int flags ) +{ + static DCTFunc dct_tbl[4] = + { + (DCTFunc)DCT_32f, + (DCTFunc)IDCT_32f, + (DCTFunc)DCT_64f, + (DCTFunc)IDCT_64f + }; + + bool inv = (flags & DCT_INVERSE) != 0; + Mat src0 = _src0.getMat(), src = src0; + int type = src.type(), depth = src.depth(); + void /* *spec_dft = 0, */ *spec = 0; + + double scale = 1.; + int prev_len = 0, nf = 0, stage, end_stage; + uchar *src_dft_buf = 0, *dst_dft_buf = 0; + uchar *dft_wave = 0, *dct_wave = 0; + int* itab = 0; + uchar* ptr = 0; + int elem_size = (int)src.elemSize(), complex_elem_size = elem_size*2; + int factors[34], inplace_transform; + int i, len, count; + AutoBuffer buf; + + CV_Assert( type == CV_32FC1 || type == CV_64FC1 ); + _dst.create( src.rows, src.cols, type ); + Mat dst = _dst.getMat(); + + DCTFunc dct_func = dct_tbl[(int)inv + (depth == CV_64F)*2]; + + if( (flags & DFT_ROWS) || src.rows == 1 || + (src.cols == 1 && (src.isContinuous() && dst.isContinuous()))) + { + stage = end_stage = 0; + } + else + { + stage = src.cols == 1; + end_stage = 1; + } + + for( ; stage <= end_stage; stage++ ) + { + uchar *sptr = src.data, *dptr = dst.data; + size_t sstep0, sstep1, dstep0, dstep1; + + if( stage == 0 ) + { + len = src.cols; + count = src.rows; + if( len == 1 && !(flags & DFT_ROWS) ) + { + len = src.rows; + count = 1; + } + sstep0 = src.step; + dstep0 = dst.step; + sstep1 = dstep1 = elem_size; + } + else + { + len = dst.rows; + count = dst.cols; + sstep1 = src.step; + dstep1 = dst.step; + sstep0 = dstep0 = elem_size; + } + + if( len != prev_len ) + { + int sz; + + if( len > 1 && (len & 1) ) + CV_Error( CV_StsNotImplemented, "Odd-size DCT\'s are not implemented" ); + + sz = len*elem_size; + sz += (len/2 + 1)*complex_elem_size; + + spec = 0; + inplace_transform = 1; + /*if( len*count >= 64 && DFTInitAlloc_R_32f_p ) + { + int ipp_sz = 0; + if( depth == CV_32F ) + { + if( spec_dft ) + IPPI_CALL( DFTFree_R_32f_p( spec_dft )); + IPPI_CALL( DFTInitAlloc_R_32f_p( &spec_dft, len, 8, cvAlgHintNone )); + IPPI_CALL( DFTGetBufSize_R_32f_p( spec_dft, &ipp_sz )); + } + else + { + if( spec_dft ) + IPPI_CALL( DFTFree_R_64f_p( spec_dft )); + IPPI_CALL( DFTInitAlloc_R_64f_p( &spec_dft, len, 8, cvAlgHintNone )); + IPPI_CALL( DFTGetBufSize_R_64f_p( spec_dft, &ipp_sz )); + } + spec = spec_dft; + sz += ipp_sz; + } + else*/ + { + sz += len*(complex_elem_size + sizeof(int)) + complex_elem_size; + + nf = DFTFactorize( len, factors ); + inplace_transform = factors[0] == factors[nf-1]; + + i = nf > 1 && (factors[0] & 1) == 0; + if( (factors[i] & 1) != 0 && factors[i] > 5 ) + sz += (factors[i]+1)*complex_elem_size; + + if( !inplace_transform ) + sz += len*elem_size; + } + + buf.allocate( sz + 32 ); + ptr = (uchar*)buf; + + if( !spec ) + { + dft_wave = ptr; + ptr += len*complex_elem_size; + itab = (int*)ptr; + ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 ); + DFTInit( len, nf, factors, itab, complex_elem_size, dft_wave, inv ); + } + + dct_wave = ptr; + ptr += (len/2 + 1)*complex_elem_size; + src_dft_buf = dst_dft_buf = ptr; + ptr += len*elem_size; + if( !inplace_transform ) + { + dst_dft_buf = ptr; + ptr += len*elem_size; + } + DCTInit( len, complex_elem_size, dct_wave, inv ); + if( !inv ) + scale += scale; + prev_len = len; + } + // otherwise reuse the tables calculated on the previous stage + for( i = 0; i < count; i++ ) + { + dct_func( sptr + i*sstep0, (int)sstep1, src_dft_buf, dst_dft_buf, + dptr + i*dstep0, (int)dstep1, len, nf, factors, + itab, dft_wave, dct_wave, spec, ptr ); + } + src = dst; + } +} + + +void cv::idct( InputArray src, OutputArray dst, int flags ) +{ + dct( src, dst, flags | DCT_INVERSE ); +} + +namespace cv +{ + +static const int optimalDFTSizeTab[] = { +1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, +50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, +162, 180, 192, 200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, +384, 400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675, 720, +729, 750, 768, 800, 810, 864, 900, 960, 972, 1000, 1024, 1080, 1125, 1152, 1200, +1215, 1250, 1280, 1296, 1350, 1440, 1458, 1500, 1536, 1600, 1620, 1728, 1800, 1875, +1920, 1944, 2000, 2025, 2048, 2160, 2187, 2250, 2304, 2400, 2430, 2500, 2560, 2592, +2700, 2880, 2916, 3000, 3072, 3125, 3200, 3240, 3375, 3456, 3600, 3645, 3750, 3840, +3888, 4000, 4050, 4096, 4320, 4374, 4500, 4608, 4800, 4860, 5000, 5120, 5184, 5400, +5625, 5760, 5832, 6000, 6075, 6144, 6250, 6400, 6480, 6561, 6750, 6912, 7200, 7290, +7500, 7680, 7776, 8000, 8100, 8192, 8640, 8748, 9000, 9216, 9375, 9600, 9720, 10000, +10125, 10240, 10368, 10800, 10935, 11250, 11520, 11664, 12000, 12150, 12288, 12500, +12800, 12960, 13122, 13500, 13824, 14400, 14580, 15000, 15360, 15552, 15625, 16000, +16200, 16384, 16875, 17280, 17496, 18000, 18225, 18432, 18750, 19200, 19440, 19683, +20000, 20250, 20480, 20736, 21600, 21870, 22500, 23040, 23328, 24000, 24300, 24576, +25000, 25600, 25920, 26244, 27000, 27648, 28125, 28800, 29160, 30000, 30375, 30720, +31104, 31250, 32000, 32400, 32768, 32805, 33750, 34560, 34992, 36000, 36450, 36864, +37500, 38400, 38880, 39366, 40000, 40500, 40960, 41472, 43200, 43740, 45000, 46080, +46656, 46875, 48000, 48600, 49152, 50000, 50625, 51200, 51840, 52488, 54000, 54675, +55296, 56250, 57600, 58320, 59049, 60000, 60750, 61440, 62208, 62500, 64000, 64800, +65536, 65610, 67500, 69120, 69984, 72000, 72900, 73728, 75000, 76800, 77760, 78125, +78732, 80000, 81000, 81920, 82944, 84375, 86400, 87480, 90000, 91125, 92160, 93312, +93750, 96000, 97200, 98304, 98415, 100000, 101250, 102400, 103680, 104976, 108000, +109350, 110592, 112500, 115200, 116640, 118098, 120000, 121500, 122880, 124416, 125000, +128000, 129600, 131072, 131220, 135000, 138240, 139968, 140625, 144000, 145800, 147456, +150000, 151875, 153600, 155520, 156250, 157464, 160000, 162000, 163840, 164025, 165888, +168750, 172800, 174960, 177147, 180000, 182250, 184320, 186624, 187500, 192000, 194400, +196608, 196830, 200000, 202500, 204800, 207360, 209952, 216000, 218700, 221184, 225000, +230400, 233280, 234375, 236196, 240000, 243000, 245760, 248832, 250000, 253125, 256000, +259200, 262144, 262440, 270000, 273375, 276480, 279936, 281250, 288000, 291600, 294912, +295245, 300000, 303750, 307200, 311040, 312500, 314928, 320000, 324000, 327680, 328050, +331776, 337500, 345600, 349920, 354294, 360000, 364500, 368640, 373248, 375000, 384000, +388800, 390625, 393216, 393660, 400000, 405000, 409600, 414720, 419904, 421875, 432000, +437400, 442368, 450000, 455625, 460800, 466560, 468750, 472392, 480000, 486000, 491520, +492075, 497664, 500000, 506250, 512000, 518400, 524288, 524880, 531441, 540000, 546750, +552960, 559872, 562500, 576000, 583200, 589824, 590490, 600000, 607500, 614400, 622080, +625000, 629856, 640000, 648000, 655360, 656100, 663552, 675000, 691200, 699840, 703125, +708588, 720000, 729000, 737280, 746496, 750000, 759375, 768000, 777600, 781250, 786432, +787320, 800000, 810000, 819200, 820125, 829440, 839808, 843750, 864000, 874800, 884736, +885735, 900000, 911250, 921600, 933120, 937500, 944784, 960000, 972000, 983040, 984150, +995328, 1000000, 1012500, 1024000, 1036800, 1048576, 1049760, 1062882, 1080000, 1093500, +1105920, 1119744, 1125000, 1152000, 1166400, 1171875, 1179648, 1180980, 1200000, +1215000, 1228800, 1244160, 1250000, 1259712, 1265625, 1280000, 1296000, 1310720, +1312200, 1327104, 1350000, 1366875, 1382400, 1399680, 1406250, 1417176, 1440000, +1458000, 1474560, 1476225, 1492992, 1500000, 1518750, 1536000, 1555200, 1562500, +1572864, 1574640, 1594323, 1600000, 1620000, 1638400, 1640250, 1658880, 1679616, +1687500, 1728000, 1749600, 1769472, 1771470, 1800000, 1822500, 1843200, 1866240, +1875000, 1889568, 1920000, 1944000, 1953125, 1966080, 1968300, 1990656, 2000000, +2025000, 2048000, 2073600, 2097152, 2099520, 2109375, 2125764, 2160000, 2187000, +2211840, 2239488, 2250000, 2278125, 2304000, 2332800, 2343750, 2359296, 2361960, +2400000, 2430000, 2457600, 2460375, 2488320, 2500000, 2519424, 2531250, 2560000, +2592000, 2621440, 2624400, 2654208, 2657205, 2700000, 2733750, 2764800, 2799360, +2812500, 2834352, 2880000, 2916000, 2949120, 2952450, 2985984, 3000000, 3037500, +3072000, 3110400, 3125000, 3145728, 3149280, 3188646, 3200000, 3240000, 3276800, +3280500, 3317760, 3359232, 3375000, 3456000, 3499200, 3515625, 3538944, 3542940, +3600000, 3645000, 3686400, 3732480, 3750000, 3779136, 3796875, 3840000, 3888000, +3906250, 3932160, 3936600, 3981312, 4000000, 4050000, 4096000, 4100625, 4147200, +4194304, 4199040, 4218750, 4251528, 4320000, 4374000, 4423680, 4428675, 4478976, +4500000, 4556250, 4608000, 4665600, 4687500, 4718592, 4723920, 4782969, 4800000, +4860000, 4915200, 4920750, 4976640, 5000000, 5038848, 5062500, 5120000, 5184000, +5242880, 5248800, 5308416, 5314410, 5400000, 5467500, 5529600, 5598720, 5625000, +5668704, 5760000, 5832000, 5859375, 5898240, 5904900, 5971968, 6000000, 6075000, +6144000, 6220800, 6250000, 6291456, 6298560, 6328125, 6377292, 6400000, 6480000, +6553600, 6561000, 6635520, 6718464, 6750000, 6834375, 6912000, 6998400, 7031250, +7077888, 7085880, 7200000, 7290000, 7372800, 7381125, 7464960, 7500000, 7558272, +7593750, 7680000, 7776000, 7812500, 7864320, 7873200, 7962624, 7971615, 8000000, +8100000, 8192000, 8201250, 8294400, 8388608, 8398080, 8437500, 8503056, 8640000, +8748000, 8847360, 8857350, 8957952, 9000000, 9112500, 9216000, 9331200, 9375000, +9437184, 9447840, 9565938, 9600000, 9720000, 9765625, 9830400, 9841500, 9953280, +10000000, 10077696, 10125000, 10240000, 10368000, 10485760, 10497600, 10546875, 10616832, +10628820, 10800000, 10935000, 11059200, 11197440, 11250000, 11337408, 11390625, 11520000, +11664000, 11718750, 11796480, 11809800, 11943936, 12000000, 12150000, 12288000, 12301875, +12441600, 12500000, 12582912, 12597120, 12656250, 12754584, 12800000, 12960000, 13107200, +13122000, 13271040, 13286025, 13436928, 13500000, 13668750, 13824000, 13996800, 14062500, +14155776, 14171760, 14400000, 14580000, 14745600, 14762250, 14929920, 15000000, 15116544, +15187500, 15360000, 15552000, 15625000, 15728640, 15746400, 15925248, 15943230, 16000000, +16200000, 16384000, 16402500, 16588800, 16777216, 16796160, 16875000, 17006112, 17280000, +17496000, 17578125, 17694720, 17714700, 17915904, 18000000, 18225000, 18432000, 18662400, +18750000, 18874368, 18895680, 18984375, 19131876, 19200000, 19440000, 19531250, 19660800, +19683000, 19906560, 20000000, 20155392, 20250000, 20480000, 20503125, 20736000, 20971520, +20995200, 21093750, 21233664, 21257640, 21600000, 21870000, 22118400, 22143375, 22394880, +22500000, 22674816, 22781250, 23040000, 23328000, 23437500, 23592960, 23619600, 23887872, +23914845, 24000000, 24300000, 24576000, 24603750, 24883200, 25000000, 25165824, 25194240, +25312500, 25509168, 25600000, 25920000, 26214400, 26244000, 26542080, 26572050, 26873856, +27000000, 27337500, 27648000, 27993600, 28125000, 28311552, 28343520, 28800000, 29160000, +29296875, 29491200, 29524500, 29859840, 30000000, 30233088, 30375000, 30720000, 31104000, +31250000, 31457280, 31492800, 31640625, 31850496, 31886460, 32000000, 32400000, 32768000, +32805000, 33177600, 33554432, 33592320, 33750000, 34012224, 34171875, 34560000, 34992000, +35156250, 35389440, 35429400, 35831808, 36000000, 36450000, 36864000, 36905625, 37324800, +37500000, 37748736, 37791360, 37968750, 38263752, 38400000, 38880000, 39062500, 39321600, +39366000, 39813120, 39858075, 40000000, 40310784, 40500000, 40960000, 41006250, 41472000, +41943040, 41990400, 42187500, 42467328, 42515280, 43200000, 43740000, 44236800, 44286750, +44789760, 45000000, 45349632, 45562500, 46080000, 46656000, 46875000, 47185920, 47239200, +47775744, 47829690, 48000000, 48600000, 48828125, 49152000, 49207500, 49766400, 50000000, +50331648, 50388480, 50625000, 51018336, 51200000, 51840000, 52428800, 52488000, 52734375, +53084160, 53144100, 53747712, 54000000, 54675000, 55296000, 55987200, 56250000, 56623104, +56687040, 56953125, 57600000, 58320000, 58593750, 58982400, 59049000, 59719680, 60000000, +60466176, 60750000, 61440000, 61509375, 62208000, 62500000, 62914560, 62985600, 63281250, +63700992, 63772920, 64000000, 64800000, 65536000, 65610000, 66355200, 66430125, 67108864, +67184640, 67500000, 68024448, 68343750, 69120000, 69984000, 70312500, 70778880, 70858800, +71663616, 72000000, 72900000, 73728000, 73811250, 74649600, 75000000, 75497472, 75582720, +75937500, 76527504, 76800000, 77760000, 78125000, 78643200, 78732000, 79626240, 79716150, +80000000, 80621568, 81000000, 81920000, 82012500, 82944000, 83886080, 83980800, 84375000, +84934656, 85030560, 86400000, 87480000, 87890625, 88473600, 88573500, 89579520, 90000000, +90699264, 91125000, 92160000, 93312000, 93750000, 94371840, 94478400, 94921875, 95551488, +95659380, 96000000, 97200000, 97656250, 98304000, 98415000, 99532800, 100000000, +100663296, 100776960, 101250000, 102036672, 102400000, 102515625, 103680000, 104857600, +104976000, 105468750, 106168320, 106288200, 107495424, 108000000, 109350000, 110592000, +110716875, 111974400, 112500000, 113246208, 113374080, 113906250, 115200000, 116640000, +117187500, 117964800, 118098000, 119439360, 119574225, 120000000, 120932352, 121500000, +122880000, 123018750, 124416000, 125000000, 125829120, 125971200, 126562500, 127401984, +127545840, 128000000, 129600000, 131072000, 131220000, 132710400, 132860250, 134217728, +134369280, 135000000, 136048896, 136687500, 138240000, 139968000, 140625000, 141557760, +141717600, 143327232, 144000000, 145800000, 146484375, 147456000, 147622500, 149299200, +150000000, 150994944, 151165440, 151875000, 153055008, 153600000, 155520000, 156250000, +157286400, 157464000, 158203125, 159252480, 159432300, 160000000, 161243136, 162000000, +163840000, 164025000, 165888000, 167772160, 167961600, 168750000, 169869312, 170061120, +170859375, 172800000, 174960000, 175781250, 176947200, 177147000, 179159040, 180000000, +181398528, 182250000, 184320000, 184528125, 186624000, 187500000, 188743680, 188956800, +189843750, 191102976, 191318760, 192000000, 194400000, 195312500, 196608000, 196830000, +199065600, 199290375, 200000000, 201326592, 201553920, 202500000, 204073344, 204800000, +205031250, 207360000, 209715200, 209952000, 210937500, 212336640, 212576400, 214990848, +216000000, 218700000, 221184000, 221433750, 223948800, 225000000, 226492416, 226748160, +227812500, 230400000, 233280000, 234375000, 235929600, 236196000, 238878720, 239148450, +240000000, 241864704, 243000000, 244140625, 245760000, 246037500, 248832000, 250000000, +251658240, 251942400, 253125000, 254803968, 255091680, 256000000, 259200000, 262144000, +262440000, 263671875, 265420800, 265720500, 268435456, 268738560, 270000000, 272097792, +273375000, 276480000, 279936000, 281250000, 283115520, 283435200, 284765625, 286654464, +288000000, 291600000, 292968750, 294912000, 295245000, 298598400, 300000000, 301989888, +302330880, 303750000, 306110016, 307200000, 307546875, 311040000, 312500000, 314572800, +314928000, 316406250, 318504960, 318864600, 320000000, 322486272, 324000000, 327680000, +328050000, 331776000, 332150625, 335544320, 335923200, 337500000, 339738624, 340122240, +341718750, 345600000, 349920000, 351562500, 353894400, 354294000, 358318080, 360000000, +362797056, 364500000, 368640000, 369056250, 373248000, 375000000, 377487360, 377913600, +379687500, 382205952, 382637520, 384000000, 388800000, 390625000, 393216000, 393660000, +398131200, 398580750, 400000000, 402653184, 403107840, 405000000, 408146688, 409600000, +410062500, 414720000, 419430400, 419904000, 421875000, 424673280, 425152800, 429981696, +432000000, 437400000, 439453125, 442368000, 442867500, 447897600, 450000000, 452984832, +453496320, 455625000, 460800000, 466560000, 468750000, 471859200, 472392000, 474609375, +477757440, 478296900, 480000000, 483729408, 486000000, 488281250, 491520000, 492075000, +497664000, 500000000, 503316480, 503884800, 506250000, 509607936, 510183360, 512000000, +512578125, 518400000, 524288000, 524880000, 527343750, 530841600, 531441000, 536870912, +537477120, 540000000, 544195584, 546750000, 552960000, 553584375, 559872000, 562500000, +566231040, 566870400, 569531250, 573308928, 576000000, 583200000, 585937500, 589824000, +590490000, 597196800, 597871125, 600000000, 603979776, 604661760, 607500000, 612220032, +614400000, 615093750, 622080000, 625000000, 629145600, 629856000, 632812500, 637009920, +637729200, 640000000, 644972544, 648000000, 655360000, 656100000, 663552000, 664301250, +671088640, 671846400, 675000000, 679477248, 680244480, 683437500, 691200000, 699840000, +703125000, 707788800, 708588000, 716636160, 720000000, 725594112, 729000000, 732421875, +737280000, 738112500, 746496000, 750000000, 754974720, 755827200, 759375000, 764411904, +765275040, 768000000, 777600000, 781250000, 786432000, 787320000, 791015625, 796262400, +797161500, 800000000, 805306368, 806215680, 810000000, 816293376, 819200000, 820125000, +829440000, 838860800, 839808000, 843750000, 849346560, 850305600, 854296875, 859963392, +864000000, 874800000, 878906250, 884736000, 885735000, 895795200, 900000000, 905969664, +906992640, 911250000, 921600000, 922640625, 933120000, 937500000, 943718400, 944784000, +949218750, 955514880, 956593800, 960000000, 967458816, 972000000, 976562500, 983040000, +984150000, 995328000, 996451875, 1000000000, 1006632960, 1007769600, 1012500000, +1019215872, 1020366720, 1024000000, 1025156250, 1036800000, 1048576000, 1049760000, +1054687500, 1061683200, 1062882000, 1073741824, 1074954240, 1080000000, 1088391168, +1093500000, 1105920000, 1107168750, 1119744000, 1125000000, 1132462080, 1133740800, +1139062500, 1146617856, 1152000000, 1166400000, 1171875000, 1179648000, 1180980000, +1194393600, 1195742250, 1200000000, 1207959552, 1209323520, 1215000000, 1220703125, +1224440064, 1228800000, 1230187500, 1244160000, 1250000000, 1258291200, 1259712000, +1265625000, 1274019840, 1275458400, 1280000000, 1289945088, 1296000000, 1310720000, +1312200000, 1318359375, 1327104000, 1328602500, 1342177280, 1343692800, 1350000000, +1358954496, 1360488960, 1366875000, 1382400000, 1399680000, 1406250000, 1415577600, +1417176000, 1423828125, 1433272320, 1440000000, 1451188224, 1458000000, 1464843750, +1474560000, 1476225000, 1492992000, 1500000000, 1509949440, 1511654400, 1518750000, +1528823808, 1530550080, 1536000000, 1537734375, 1555200000, 1562500000, 1572864000, +1574640000, 1582031250, 1592524800, 1594323000, 1600000000, 1610612736, 1612431360, +1620000000, 1632586752, 1638400000, 1640250000, 1658880000, 1660753125, 1677721600, +1679616000, 1687500000, 1698693120, 1700611200, 1708593750, 1719926784, 1728000000, +1749600000, 1757812500, 1769472000, 1771470000, 1791590400, 1800000000, 1811939328, +1813985280, 1822500000, 1843200000, 1845281250, 1866240000, 1875000000, 1887436800, +1889568000, 1898437500, 1911029760, 1913187600, 1920000000, 1934917632, 1944000000, +1953125000, 1966080000, 1968300000, 1990656000, 1992903750, 2000000000, 2013265920, +2015539200, 2025000000, 2038431744, 2040733440, 2048000000, 2050312500, 2073600000, +2097152000, 2099520000, 2109375000, 2123366400, 2125764000 +}; + +} + +int cv::getOptimalDFTSize( int size0 ) +{ + int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) - 1; + if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] ) + return -1; + + while( a < b ) + { + int c = (a + b) >> 1; + if( size0 <= optimalDFTSizeTab[c] ) + b = c; + else + a = c+1; + } + + return optimalDFTSizeTab[b]; +} + +CV_IMPL void +cvDFT( const CvArr* srcarr, CvArr* dstarr, int flags, int nonzero_rows ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0; + int _flags = ((flags & CV_DXT_INVERSE) ? cv::DFT_INVERSE : 0) | + ((flags & CV_DXT_SCALE) ? cv::DFT_SCALE : 0) | + ((flags & CV_DXT_ROWS) ? cv::DFT_ROWS : 0); + + CV_Assert( src.size == dst.size ); + + if( src.type() != dst.type() ) + { + if( dst.channels() == 2 ) + _flags |= cv::DFT_COMPLEX_OUTPUT; + else + _flags |= cv::DFT_REAL_OUTPUT; + } + + cv::dft( src, dst, _flags, nonzero_rows ); + CV_Assert( dst.data == dst0.data ); // otherwise it means that the destination size or type was incorrect +} + + +CV_IMPL void +cvMulSpectrums( const CvArr* srcAarr, const CvArr* srcBarr, + CvArr* dstarr, int flags ) +{ + cv::Mat srcA = cv::cvarrToMat(srcAarr), + srcB = cv::cvarrToMat(srcBarr), + dst = cv::cvarrToMat(dstarr); + CV_Assert( srcA.size == dst.size && srcA.type() == dst.type() ); + + cv::mulSpectrums(srcA, srcB, dst, + (flags & CV_DXT_ROWS) ? cv::DFT_ROWS : 0, + (flags & CV_DXT_MUL_CONJ) != 0 ); +} + + +CV_IMPL void +cvDCT( const CvArr* srcarr, CvArr* dstarr, int flags ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + int _flags = ((flags & CV_DXT_INVERSE) ? cv::DCT_INVERSE : 0) | + ((flags & CV_DXT_ROWS) ? cv::DCT_ROWS : 0); + cv::dct( src, dst, _flags ); +} + + +CV_IMPL int +cvGetOptimalDFTSize( int size0 ) +{ + return cv::getOptimalDFTSize(size0); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/gl_core_3_1.cpp diffimg-2.0.0/3rdparty/opencv/core/src/gl_core_3_1.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/gl_core_3_1.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/gl_core_3_1.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2760 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include +#include +#include "cvconfig.h" +#include "opencv2/core/core.hpp" +#include "gl_core_3_1.hpp" + +#ifdef HAVE_OPENGL + #if defined(__APPLE__) + #include + + static void* AppleGLGetProcAddress (const char* name) + { + static const struct mach_header* image = 0; + if (!image) + image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); + + // prepend a '_' for the Unix C symbol mangling convention + std::string symbolName = "_"; + symbolName += std::string(name); + + NSSymbol symbol = image ? NSLookupSymbolInImage(image, &symbolName[0], NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : 0; + + return symbol ? NSAddressOfSymbol(symbol) : 0; + } + #endif // __APPLE__ + + #if defined(__sgi) || defined (__sun) + #include + #include + + static void* SunGetProcAddress (const char* name) + { + typedef void* (func_t*)(const GLubyte*); + + static void* h = 0; + static func_t gpa = 0; + + if (!h) + { + h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); + if (!h) + return 0; + gpa = (func_t) dlsym(h, "glXGetProcAddress"); + } + + return gpa ? gpa((const GLubyte*) name) : dlsym(h, name); + } + #endif // __sgi || __sun + + #if defined(_WIN32) + #ifdef _MSC_VER + #pragma warning(disable: 4055) + #pragma warning(disable: 4054) + #endif + + static int TestPointer(const PROC pTest) + { + if(!pTest) + return 0; + + ptrdiff_t iTest = (ptrdiff_t) pTest; + + if (iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) + return 0; + + return 1; + } + + static PROC WinGetProcAddress(const char* name) + { + PROC pFunc = wglGetProcAddress((LPCSTR) name); + if (TestPointer(pFunc)) + return pFunc; + + HMODULE glMod = GetModuleHandleA("OpenGL32.dll"); + return (PROC) GetProcAddress(glMod, (LPCSTR) name); + } + #endif // _WIN32 + + #if defined(_WIN32) + #define CV_GL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) + #elif defined(__APPLE__) + #define CV_GL_GET_PROC_ADDRESS(name) AppleGLGetProcAddress(name) + #elif defined(__sgi) || defined(__sun) + #define CV_GL_GET_PROC_ADDRESS(name) SunGetProcAddress(name) + #else // GLX + #include + + #define CV_GL_GET_PROC_ADDRESS(name) glXGetProcAddressARB((const GLubyte*) name) + #endif + + static void* IntGetProcAddress(const char* name) + { + void* func = (void*) CV_GL_GET_PROC_ADDRESS(name); + if (!func) + { + std::ostringstream msg; + msg << "Can't load OpenGL extension [" << name << "]"; + CV_Error(CV_OpenGlApiCallError, msg.str()); + } + return func; + } +#else + static void* IntGetProcAddress(const char*) + { + CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + return 0; + } +#endif + +namespace gl +{ + ////////////////////////////////////////////// + // Function pointer types + + // Extension: 1.1 + typedef void (CODEGEN_FUNCPTR *PFNCULLFACEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNFRONTFACEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNHINTPROC)(GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNLINEWIDTHPROC)(GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNPOINTSIZEPROC)(GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNPOLYGONMODEPROC)(GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNSCISSORPROC)(GLint , GLint , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERFPROC)(GLenum , GLenum , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERFVPROC)(GLenum , GLenum , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERIPROC)(GLenum , GLenum , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERIVPROC)(GLenum , GLenum , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNTEXIMAGE1DPROC)(GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNTEXIMAGE2DPROC)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNDRAWBUFFERPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNCLEARPROC)(GLbitfield ); + typedef void (CODEGEN_FUNCPTR *PFNCLEARCOLORPROC)(GLfloat , GLfloat , GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNCLEARSTENCILPROC)(GLint ); + typedef void (CODEGEN_FUNCPTR *PFNCLEARDEPTHPROC)(GLdouble ); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILMASKPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNCOLORMASKPROC)(GLboolean , GLboolean , GLboolean , GLboolean ); + typedef void (CODEGEN_FUNCPTR *PFNDEPTHMASKPROC)(GLboolean ); + typedef void (CODEGEN_FUNCPTR *PFNDISABLEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNENABLEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNFINISHPROC)(); + typedef void (CODEGEN_FUNCPTR *PFNFLUSHPROC)(); + typedef void (CODEGEN_FUNCPTR *PFNBLENDFUNCPROC)(GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNLOGICOPPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILFUNCPROC)(GLenum , GLint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILOPPROC)(GLenum , GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDEPTHFUNCPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNPIXELSTOREFPROC)(GLenum , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNPIXELSTOREIPROC)(GLenum , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNREADBUFFERPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNREADPIXELSPROC)(GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETBOOLEANVPROC)(GLenum , GLboolean *); + typedef void (CODEGEN_FUNCPTR *PFNGETDOUBLEVPROC)(GLenum , GLdouble *); + typedef GLenum (CODEGEN_FUNCPTR *PFNGETERRORPROC)(); + typedef void (CODEGEN_FUNCPTR *PFNGETFLOATVPROC)(GLenum , GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNGETINTEGERVPROC)(GLenum , GLint *); + typedef const GLubyte * (CODEGEN_FUNCPTR *PFNGETSTRINGPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXIMAGEPROC)(GLenum , GLint , GLenum , GLenum , GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXPARAMETERFVPROC)(GLenum , GLenum , GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXPARAMETERIVPROC)(GLenum , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXLEVELPARAMETERFVPROC)(GLenum , GLint , GLenum , GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXLEVELPARAMETERIVPROC)(GLenum , GLint , GLenum , GLint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISENABLEDPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDEPTHRANGEPROC)(GLdouble , GLdouble ); + typedef void (CODEGEN_FUNCPTR *PFNVIEWPORTPROC)(GLint , GLint , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNDRAWARRAYSPROC)(GLenum , GLint , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNDRAWELEMENTSPROC)(GLenum , GLsizei , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETPOINTERVPROC)(GLenum , GLvoid* *); + typedef void (CODEGEN_FUNCPTR *PFNPOLYGONOFFSETPROC)(GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNCOPYTEXIMAGE1DPROC)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNCOPYTEXIMAGE2DPROC)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLsizei , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNCOPYTEXSUBIMAGE1DPROC)(GLenum , GLint , GLint , GLint , GLint , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNCOPYTEXSUBIMAGE2DPROC)(GLenum , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNTEXSUBIMAGE1DPROC)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNTEXSUBIMAGE2DPROC)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNBINDTEXTUREPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETETEXTURESPROC)(GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGENTEXTURESPROC)(GLsizei , GLuint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISTEXTUREPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNINDEXUBPROC)(GLubyte ); + typedef void (CODEGEN_FUNCPTR *PFNINDEXUBVPROC)(const GLubyte *); + + // Extension: 1.2 + typedef void (CODEGEN_FUNCPTR *PFNBLENDCOLORPROC)(GLfloat , GLfloat , GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNBLENDEQUATIONPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDRAWRANGEELEMENTSPROC)(GLenum , GLuint , GLuint , GLsizei , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNTEXSUBIMAGE3DPROC)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOPYTEXSUBIMAGE3DPROC)(GLenum , GLint , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei ); + + // Extension: 1.3 + typedef void (CODEGEN_FUNCPTR *PFNACTIVETEXTUREPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNSAMPLECOVERAGEPROC)(GLfloat , GLboolean ); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXIMAGE3DPROC)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXIMAGE2DPROC)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXIMAGE1DPROC)(GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETCOMPRESSEDTEXIMAGEPROC)(GLenum , GLint , GLvoid *); + + // Extension: 1.4 + typedef void (CODEGEN_FUNCPTR *PFNBLENDFUNCSEPARATEPROC)(GLenum , GLenum , GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNMULTIDRAWARRAYSPROC)(GLenum , const GLint *, const GLsizei *, GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNMULTIDRAWELEMENTSPROC)(GLenum , const GLsizei *, GLenum , const GLvoid* const *, GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNPOINTPARAMETERFPROC)(GLenum , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNPOINTPARAMETERFVPROC)(GLenum , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNPOINTPARAMETERIPROC)(GLenum , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNPOINTPARAMETERIVPROC)(GLenum , const GLint *); + + // Extension: 1.5 + typedef void (CODEGEN_FUNCPTR *PFNGENQUERIESPROC)(GLsizei , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNDELETEQUERIESPROC)(GLsizei , const GLuint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISQUERYPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBEGINQUERYPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNENDQUERYPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNGETQUERYIVPROC)(GLenum , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETQUERYOBJECTIVPROC)(GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETQUERYOBJECTUIVPROC)(GLuint , GLenum , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNBINDBUFFERPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETEBUFFERSPROC)(GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGENBUFFERSPROC)(GLsizei , GLuint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISBUFFERPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBUFFERDATAPROC)(GLenum , GLsizeiptr , const GLvoid *, GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNBUFFERSUBDATAPROC)(GLenum , GLintptr , GLsizeiptr , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETBUFFERSUBDATAPROC)(GLenum , GLintptr , GLsizeiptr , GLvoid *); + typedef GLvoid* (CODEGEN_FUNCPTR *PFNMAPBUFFERPROC)(GLenum , GLenum ); + typedef GLboolean (CODEGEN_FUNCPTR *PFNUNMAPBUFFERPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNGETBUFFERPARAMETERIVPROC)(GLenum , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETBUFFERPOINTERVPROC)(GLenum , GLenum , GLvoid* *); + + // Extension: 2.0 + typedef void (CODEGEN_FUNCPTR *PFNBLENDEQUATIONSEPARATEPROC)(GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDRAWBUFFERSPROC)(GLsizei , const GLenum *); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILOPSEPARATEPROC)(GLenum , GLenum , GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILFUNCSEPARATEPROC)(GLenum , GLenum , GLint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNSTENCILMASKSEPARATEPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNATTACHSHADERPROC)(GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBINDATTRIBLOCATIONPROC)(GLuint , GLuint , const GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNCOMPILESHADERPROC)(GLuint ); + typedef GLuint (CODEGEN_FUNCPTR *PFNCREATEPROGRAMPROC)(); + typedef GLuint (CODEGEN_FUNCPTR *PFNCREATESHADERPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDELETEPROGRAMPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETESHADERPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDETACHSHADERPROC)(GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDISABLEVERTEXATTRIBARRAYPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNENABLEVERTEXATTRIBARRAYPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEATTRIBPROC)(GLuint , GLuint , GLsizei , GLsizei *, GLint *, GLenum *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEUNIFORMPROC)(GLuint , GLuint , GLsizei , GLsizei *, GLint *, GLenum *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETATTACHEDSHADERSPROC)(GLuint , GLsizei , GLsizei *, GLuint *); + typedef GLint (CODEGEN_FUNCPTR *PFNGETATTRIBLOCATIONPROC)(GLuint , const GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETPROGRAMIVPROC)(GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETPROGRAMINFOLOGPROC)(GLuint , GLsizei , GLsizei *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETSHADERIVPROC)(GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETSHADERINFOLOGPROC)(GLuint , GLsizei , GLsizei *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETSHADERSOURCEPROC)(GLuint , GLsizei , GLsizei *, GLchar *); + typedef GLint (CODEGEN_FUNCPTR *PFNGETUNIFORMLOCATIONPROC)(GLuint , const GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETUNIFORMFVPROC)(GLuint , GLint , GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNGETUNIFORMIVPROC)(GLuint , GLint , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBDVPROC)(GLuint , GLenum , GLdouble *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBFVPROC)(GLuint , GLenum , GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBIVPROC)(GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBPOINTERVPROC)(GLuint , GLenum , GLvoid* *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISPROGRAMPROC)(GLuint ); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISSHADERPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNLINKPROGRAMPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNSHADERSOURCEPROC)(GLuint , GLsizei , const GLchar* const *, const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNUSEPROGRAMPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1FPROC)(GLint , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2FPROC)(GLint , GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3FPROC)(GLint , GLfloat , GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4FPROC)(GLint , GLfloat , GLfloat , GLfloat , GLfloat ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1IPROC)(GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2IPROC)(GLint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3IPROC)(GLint , GLint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4IPROC)(GLint , GLint , GLint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1FVPROC)(GLint , GLsizei , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2FVPROC)(GLint , GLsizei , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3FVPROC)(GLint , GLsizei , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4FVPROC)(GLint , GLsizei , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1IVPROC)(GLint , GLsizei , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2IVPROC)(GLint , GLsizei , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3IVPROC)(GLint , GLsizei , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4IVPROC)(GLint , GLsizei , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX2FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX3FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX4FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNVALIDATEPROGRAMPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBPOINTERPROC)(GLuint , GLint , GLenum , GLboolean , GLsizei , const GLvoid *); + + // Extension: 2.1 + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX2X3FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX3X2FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX2X4FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX4X2FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX3X4FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMMATRIX4X3FVPROC)(GLint , GLsizei , GLboolean , const GLfloat *); + + // Extension: ARB_vertex_array_object + typedef void (CODEGEN_FUNCPTR *PFNBINDVERTEXARRAYPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETEVERTEXARRAYSPROC)(GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGENVERTEXARRAYSPROC)(GLsizei , GLuint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISVERTEXARRAYPROC)(GLuint ); + + // Extension: ARB_map_buffer_range + typedef GLvoid* (CODEGEN_FUNCPTR *PFNMAPBUFFERRANGEPROC)(GLenum , GLintptr , GLsizeiptr , GLbitfield ); + typedef void (CODEGEN_FUNCPTR *PFNFLUSHMAPPEDBUFFERRANGEPROC)(GLenum , GLintptr , GLsizeiptr ); + + // Extension: ARB_framebuffer_object + typedef GLboolean (CODEGEN_FUNCPTR *PFNISRENDERBUFFERPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBINDRENDERBUFFERPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETERENDERBUFFERSPROC)(GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGENRENDERBUFFERSPROC)(GLsizei , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNRENDERBUFFERSTORAGEPROC)(GLenum , GLenum , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNGETRENDERBUFFERPARAMETERIVPROC)(GLenum , GLenum , GLint *); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISFRAMEBUFFERPROC)(GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBINDFRAMEBUFFERPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDELETEFRAMEBUFFERSPROC)(GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGENFRAMEBUFFERSPROC)(GLsizei , GLuint *); + typedef GLenum (CODEGEN_FUNCPTR *PFNCHECKFRAMEBUFFERSTATUSPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNFRAMEBUFFERTEXTURE1DPROC)(GLenum , GLenum , GLenum , GLuint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNFRAMEBUFFERTEXTURE2DPROC)(GLenum , GLenum , GLenum , GLuint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNFRAMEBUFFERTEXTURE3DPROC)(GLenum , GLenum , GLenum , GLuint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNFRAMEBUFFERRENDERBUFFERPROC)(GLenum , GLenum , GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum , GLenum , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGENERATEMIPMAPPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNBLITFRAMEBUFFERPROC)(GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLbitfield , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum , GLsizei , GLenum , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNFRAMEBUFFERTEXTURELAYERPROC)(GLenum , GLenum , GLuint , GLint , GLint ); + + // Extension: 3.0 + typedef void (CODEGEN_FUNCPTR *PFNCOLORMASKIPROC)(GLuint , GLboolean , GLboolean , GLboolean , GLboolean ); + typedef void (CODEGEN_FUNCPTR *PFNGETBOOLEANI_VPROC)(GLenum , GLuint , GLboolean *); + typedef void (CODEGEN_FUNCPTR *PFNGETINTEGERI_VPROC)(GLenum , GLuint , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNENABLEIPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNDISABLEIPROC)(GLenum , GLuint ); + typedef GLboolean (CODEGEN_FUNCPTR *PFNISENABLEDIPROC)(GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNBEGINTRANSFORMFEEDBACKPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNENDTRANSFORMFEEDBACKPROC)(); + typedef void (CODEGEN_FUNCPTR *PFNBINDBUFFERRANGEPROC)(GLenum , GLuint , GLuint , GLintptr , GLsizeiptr ); + typedef void (CODEGEN_FUNCPTR *PFNBINDBUFFERBASEPROC)(GLenum , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNTRANSFORMFEEDBACKVARYINGSPROC)(GLuint , GLsizei , const GLchar* const *, GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint , GLuint , GLsizei , GLsizei *, GLsizei *, GLenum *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNCLAMPCOLORPROC)(GLenum , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNBEGINCONDITIONALRENDERPROC)(GLuint , GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNENDCONDITIONALRENDERPROC)(); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBIPOINTERPROC)(GLuint , GLint , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBIIVPROC)(GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETVERTEXATTRIBIUIVPROC)(GLuint , GLenum , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI1IPROC)(GLuint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI2IPROC)(GLuint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI3IPROC)(GLuint , GLint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4IPROC)(GLuint , GLint , GLint , GLint , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI1UIPROC)(GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI2UIPROC)(GLuint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI3UIPROC)(GLuint , GLuint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4UIPROC)(GLuint , GLuint , GLuint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI1IVPROC)(GLuint , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI2IVPROC)(GLuint , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI3IVPROC)(GLuint , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4IVPROC)(GLuint , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI1UIVPROC)(GLuint , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI2UIVPROC)(GLuint , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI3UIVPROC)(GLuint , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4UIVPROC)(GLuint , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4BVPROC)(GLuint , const GLbyte *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4SVPROC)(GLuint , const GLshort *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4UBVPROC)(GLuint , const GLubyte *); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXATTRIBI4USVPROC)(GLuint , const GLushort *); + typedef void (CODEGEN_FUNCPTR *PFNGETUNIFORMUIVPROC)(GLuint , GLint , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNBINDFRAGDATALOCATIONPROC)(GLuint , GLuint , const GLchar *); + typedef GLint (CODEGEN_FUNCPTR *PFNGETFRAGDATALOCATIONPROC)(GLuint , const GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1UIPROC)(GLint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2UIPROC)(GLint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3UIPROC)(GLint , GLuint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4UIPROC)(GLint , GLuint , GLuint , GLuint , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM1UIVPROC)(GLint , GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM2UIVPROC)(GLint , GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM3UIVPROC)(GLint , GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORM4UIVPROC)(GLint , GLsizei , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERIIVPROC)(GLenum , GLenum , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNTEXPARAMETERIUIVPROC)(GLenum , GLenum , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXPARAMETERIIVPROC)(GLenum , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETTEXPARAMETERIUIVPROC)(GLenum , GLenum , GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNCLEARBUFFERIVPROC)(GLenum , GLint , const GLint *); + typedef void (CODEGEN_FUNCPTR *PFNCLEARBUFFERUIVPROC)(GLenum , GLint , const GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNCLEARBUFFERFVPROC)(GLenum , GLint , const GLfloat *); + typedef void (CODEGEN_FUNCPTR *PFNCLEARBUFFERFIPROC)(GLenum , GLint , GLfloat , GLint ); + typedef const GLubyte * (CODEGEN_FUNCPTR *PFNGETSTRINGIPROC)(GLenum , GLuint ); + + // Extension: ARB_uniform_buffer_object + typedef void (CODEGEN_FUNCPTR *PFNGETUNIFORMINDICESPROC)(GLuint , GLsizei , const GLchar* const *, GLuint *); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEUNIFORMSIVPROC)(GLuint , GLsizei , const GLuint *, GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEUNIFORMNAMEPROC)(GLuint , GLuint , GLsizei , GLsizei *, GLchar *); + typedef GLuint (CODEGEN_FUNCPTR *PFNGETUNIFORMBLOCKINDEXPROC)(GLuint , const GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEUNIFORMBLOCKIVPROC)(GLuint , GLuint , GLenum , GLint *); + typedef void (CODEGEN_FUNCPTR *PFNGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint , GLuint , GLsizei , GLsizei *, GLchar *); + typedef void (CODEGEN_FUNCPTR *PFNUNIFORMBLOCKBINDINGPROC)(GLuint , GLuint , GLuint ); + + // Extension: ARB_copy_buffer + typedef void (CODEGEN_FUNCPTR *PFNCOPYBUFFERSUBDATAPROC)(GLenum , GLenum , GLintptr , GLintptr , GLsizeiptr ); + + // Extension: 3.1 + typedef void (CODEGEN_FUNCPTR *PFNDRAWARRAYSINSTANCEDPROC)(GLenum , GLint , GLsizei , GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNDRAWELEMENTSINSTANCEDPROC)(GLenum , GLsizei , GLenum , const GLvoid *, GLsizei ); + typedef void (CODEGEN_FUNCPTR *PFNTEXBUFFERPROC)(GLenum , GLenum , GLuint ); + typedef void (CODEGEN_FUNCPTR *PFNPRIMITIVERESTARTINDEXPROC)(GLuint ); + + // Legacy + typedef void (CODEGEN_FUNCPTR *PFNENABLECLIENTSTATEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNDISABLECLIENTSTATEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNVERTEXPOINTERPROC)(GLint , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNNORMALPOINTERPROC)(GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNCOLORPOINTERPROC)(GLint , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNTEXCOORDPOINTERPROC)(GLint , GLenum , GLsizei , const GLvoid *); + typedef void (CODEGEN_FUNCPTR *PFNTEXENVIPROC)(GLenum , GLenum , GLint ); + typedef void (CODEGEN_FUNCPTR *PFNMATRIXMODEPROC)(GLenum ); + typedef void (CODEGEN_FUNCPTR *PFNLOADIDENTITYPROC)(void); + typedef void (CODEGEN_FUNCPTR *PFNORTHOPROC)(GLdouble , GLdouble , GLdouble , GLdouble , GLdouble , GLdouble ); + typedef void (CODEGEN_FUNCPTR *PFNCOLOR3DPROC)(GLdouble , GLdouble , GLdouble ); + + ////////////////////////////////////////////// + // Function pointers + + // Extension: 1.1 + PFNCULLFACEPROC CullFace; + PFNFRONTFACEPROC FrontFace; + PFNHINTPROC Hint; + PFNLINEWIDTHPROC LineWidth; + PFNPOINTSIZEPROC PointSize; + PFNPOLYGONMODEPROC PolygonMode; + PFNSCISSORPROC Scissor; + PFNTEXPARAMETERFPROC TexParameterf; + PFNTEXPARAMETERFVPROC TexParameterfv; + PFNTEXPARAMETERIPROC TexParameteri; + PFNTEXPARAMETERIVPROC TexParameteriv; + PFNTEXIMAGE1DPROC TexImage1D; + PFNTEXIMAGE2DPROC TexImage2D; + PFNDRAWBUFFERPROC DrawBuffer; + PFNCLEARPROC Clear; + PFNCLEARCOLORPROC ClearColor; + PFNCLEARSTENCILPROC ClearStencil; + PFNCLEARDEPTHPROC ClearDepth; + PFNSTENCILMASKPROC StencilMask; + PFNCOLORMASKPROC ColorMask; + PFNDEPTHMASKPROC DepthMask; + PFNDISABLEPROC Disable; + PFNENABLEPROC Enable; + PFNFINISHPROC Finish; + PFNFLUSHPROC Flush; + PFNBLENDFUNCPROC BlendFunc; + PFNLOGICOPPROC LogicOp; + PFNSTENCILFUNCPROC StencilFunc; + PFNSTENCILOPPROC StencilOp; + PFNDEPTHFUNCPROC DepthFunc; + PFNPIXELSTOREFPROC PixelStoref; + PFNPIXELSTOREIPROC PixelStorei; + PFNREADBUFFERPROC ReadBuffer; + PFNREADPIXELSPROC ReadPixels; + PFNGETBOOLEANVPROC GetBooleanv; + PFNGETDOUBLEVPROC GetDoublev; + PFNGETERRORPROC GetError; + PFNGETFLOATVPROC GetFloatv; + PFNGETINTEGERVPROC GetIntegerv; + PFNGETSTRINGPROC GetString; + PFNGETTEXIMAGEPROC GetTexImage; + PFNGETTEXPARAMETERFVPROC GetTexParameterfv; + PFNGETTEXPARAMETERIVPROC GetTexParameteriv; + PFNGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv; + PFNGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; + PFNISENABLEDPROC IsEnabled; + PFNDEPTHRANGEPROC DepthRange; + PFNVIEWPORTPROC Viewport; + PFNDRAWARRAYSPROC DrawArrays; + PFNDRAWELEMENTSPROC DrawElements; + PFNGETPOINTERVPROC GetPointerv; + PFNPOLYGONOFFSETPROC PolygonOffset; + PFNCOPYTEXIMAGE1DPROC CopyTexImage1D; + PFNCOPYTEXIMAGE2DPROC CopyTexImage2D; + PFNCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D; + PFNCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D; + PFNTEXSUBIMAGE1DPROC TexSubImage1D; + PFNTEXSUBIMAGE2DPROC TexSubImage2D; + PFNBINDTEXTUREPROC BindTexture; + PFNDELETETEXTURESPROC DeleteTextures; + PFNGENTEXTURESPROC GenTextures; + PFNISTEXTUREPROC IsTexture; + PFNINDEXUBPROC Indexub; + PFNINDEXUBVPROC Indexubv; + + // Extension: 1.2 + PFNBLENDCOLORPROC BlendColor; + PFNBLENDEQUATIONPROC BlendEquation; + PFNDRAWRANGEELEMENTSPROC DrawRangeElements; + PFNTEXSUBIMAGE3DPROC TexSubImage3D; + PFNCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D; + + // Extension: 1.3 + PFNACTIVETEXTUREPROC ActiveTexture; + PFNSAMPLECOVERAGEPROC SampleCoverage; + PFNCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D; + PFNCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D; + PFNCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D; + PFNCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D; + PFNCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D; + PFNCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D; + PFNGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage; + + // Extension: 1.4 + PFNBLENDFUNCSEPARATEPROC BlendFuncSeparate; + PFNMULTIDRAWARRAYSPROC MultiDrawArrays; + PFNMULTIDRAWELEMENTSPROC MultiDrawElements; + PFNPOINTPARAMETERFPROC PointParameterf; + PFNPOINTPARAMETERFVPROC PointParameterfv; + PFNPOINTPARAMETERIPROC PointParameteri; + PFNPOINTPARAMETERIVPROC PointParameteriv; + + // Extension: 1.5 + PFNGENQUERIESPROC GenQueries; + PFNDELETEQUERIESPROC DeleteQueries; + PFNISQUERYPROC IsQuery; + PFNBEGINQUERYPROC BeginQuery; + PFNENDQUERYPROC EndQuery; + PFNGETQUERYIVPROC GetQueryiv; + PFNGETQUERYOBJECTIVPROC GetQueryObjectiv; + PFNGETQUERYOBJECTUIVPROC GetQueryObjectuiv; + PFNBINDBUFFERPROC BindBuffer; + PFNDELETEBUFFERSPROC DeleteBuffers; + PFNGENBUFFERSPROC GenBuffers; + PFNISBUFFERPROC IsBuffer; + PFNBUFFERDATAPROC BufferData; + PFNBUFFERSUBDATAPROC BufferSubData; + PFNGETBUFFERSUBDATAPROC GetBufferSubData; + PFNMAPBUFFERPROC MapBuffer; + PFNUNMAPBUFFERPROC UnmapBuffer; + PFNGETBUFFERPARAMETERIVPROC GetBufferParameteriv; + PFNGETBUFFERPOINTERVPROC GetBufferPointerv; + + // Extension: 2.0 + PFNBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; + PFNDRAWBUFFERSPROC DrawBuffers; + PFNSTENCILOPSEPARATEPROC StencilOpSeparate; + PFNSTENCILFUNCSEPARATEPROC StencilFuncSeparate; + PFNSTENCILMASKSEPARATEPROC StencilMaskSeparate; + PFNATTACHSHADERPROC AttachShader; + PFNBINDATTRIBLOCATIONPROC BindAttribLocation; + PFNCOMPILESHADERPROC CompileShader; + PFNCREATEPROGRAMPROC CreateProgram; + PFNCREATESHADERPROC CreateShader; + PFNDELETEPROGRAMPROC DeleteProgram; + PFNDELETESHADERPROC DeleteShader; + PFNDETACHSHADERPROC DetachShader; + PFNDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; + PFNENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; + PFNGETACTIVEATTRIBPROC GetActiveAttrib; + PFNGETACTIVEUNIFORMPROC GetActiveUniform; + PFNGETATTACHEDSHADERSPROC GetAttachedShaders; + PFNGETATTRIBLOCATIONPROC GetAttribLocation; + PFNGETPROGRAMIVPROC GetProgramiv; + PFNGETPROGRAMINFOLOGPROC GetProgramInfoLog; + PFNGETSHADERIVPROC GetShaderiv; + PFNGETSHADERINFOLOGPROC GetShaderInfoLog; + PFNGETSHADERSOURCEPROC GetShaderSource; + PFNGETUNIFORMLOCATIONPROC GetUniformLocation; + PFNGETUNIFORMFVPROC GetUniformfv; + PFNGETUNIFORMIVPROC GetUniformiv; + PFNGETVERTEXATTRIBDVPROC GetVertexAttribdv; + PFNGETVERTEXATTRIBFVPROC GetVertexAttribfv; + PFNGETVERTEXATTRIBIVPROC GetVertexAttribiv; + PFNGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; + PFNISPROGRAMPROC IsProgram; + PFNISSHADERPROC IsShader; + PFNLINKPROGRAMPROC LinkProgram; + PFNSHADERSOURCEPROC ShaderSource; + PFNUSEPROGRAMPROC UseProgram; + PFNUNIFORM1FPROC Uniform1f; + PFNUNIFORM2FPROC Uniform2f; + PFNUNIFORM3FPROC Uniform3f; + PFNUNIFORM4FPROC Uniform4f; + PFNUNIFORM1IPROC Uniform1i; + PFNUNIFORM2IPROC Uniform2i; + PFNUNIFORM3IPROC Uniform3i; + PFNUNIFORM4IPROC Uniform4i; + PFNUNIFORM1FVPROC Uniform1fv; + PFNUNIFORM2FVPROC Uniform2fv; + PFNUNIFORM3FVPROC Uniform3fv; + PFNUNIFORM4FVPROC Uniform4fv; + PFNUNIFORM1IVPROC Uniform1iv; + PFNUNIFORM2IVPROC Uniform2iv; + PFNUNIFORM3IVPROC Uniform3iv; + PFNUNIFORM4IVPROC Uniform4iv; + PFNUNIFORMMATRIX2FVPROC UniformMatrix2fv; + PFNUNIFORMMATRIX3FVPROC UniformMatrix3fv; + PFNUNIFORMMATRIX4FVPROC UniformMatrix4fv; + PFNVALIDATEPROGRAMPROC ValidateProgram; + PFNVERTEXATTRIBPOINTERPROC VertexAttribPointer; + + // Extension: 2.1 + PFNUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv; + PFNUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv; + PFNUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv; + PFNUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv; + PFNUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv; + PFNUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv; + + // Extension: ARB_vertex_array_object + PFNBINDVERTEXARRAYPROC BindVertexArray; + PFNDELETEVERTEXARRAYSPROC DeleteVertexArrays; + PFNGENVERTEXARRAYSPROC GenVertexArrays; + PFNISVERTEXARRAYPROC IsVertexArray; + + // Extension: ARB_map_buffer_range + PFNMAPBUFFERRANGEPROC MapBufferRange; + PFNFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; + + // Extension: ARB_framebuffer_object + PFNISRENDERBUFFERPROC IsRenderbuffer; + PFNBINDRENDERBUFFERPROC BindRenderbuffer; + PFNDELETERENDERBUFFERSPROC DeleteRenderbuffers; + PFNGENRENDERBUFFERSPROC GenRenderbuffers; + PFNRENDERBUFFERSTORAGEPROC RenderbufferStorage; + PFNGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv; + PFNISFRAMEBUFFERPROC IsFramebuffer; + PFNBINDFRAMEBUFFERPROC BindFramebuffer; + PFNDELETEFRAMEBUFFERSPROC DeleteFramebuffers; + PFNGENFRAMEBUFFERSPROC GenFramebuffers; + PFNCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus; + PFNFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D; + PFNFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D; + PFNFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D; + PFNFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer; + PFNGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv; + PFNGENERATEMIPMAPPROC GenerateMipmap; + PFNBLITFRAMEBUFFERPROC BlitFramebuffer; + PFNRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample; + PFNFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer; + + // Extension: 3.0 + PFNCOLORMASKIPROC ColorMaski; + PFNGETBOOLEANI_VPROC GetBooleani_v; + PFNGETINTEGERI_VPROC GetIntegeri_v; + PFNENABLEIPROC Enablei; + PFNDISABLEIPROC Disablei; + PFNISENABLEDIPROC IsEnabledi; + PFNBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback; + PFNENDTRANSFORMFEEDBACKPROC EndTransformFeedback; + PFNBINDBUFFERRANGEPROC BindBufferRange; + PFNBINDBUFFERBASEPROC BindBufferBase; + PFNTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings; + PFNGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying; + PFNCLAMPCOLORPROC ClampColor; + PFNBEGINCONDITIONALRENDERPROC BeginConditionalRender; + PFNENDCONDITIONALRENDERPROC EndConditionalRender; + PFNVERTEXATTRIBIPOINTERPROC VertexAttribIPointer; + PFNGETVERTEXATTRIBIIVPROC GetVertexAttribIiv; + PFNGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv; + PFNVERTEXATTRIBI1IPROC VertexAttribI1i; + PFNVERTEXATTRIBI2IPROC VertexAttribI2i; + PFNVERTEXATTRIBI3IPROC VertexAttribI3i; + PFNVERTEXATTRIBI4IPROC VertexAttribI4i; + PFNVERTEXATTRIBI1UIPROC VertexAttribI1ui; + PFNVERTEXATTRIBI2UIPROC VertexAttribI2ui; + PFNVERTEXATTRIBI3UIPROC VertexAttribI3ui; + PFNVERTEXATTRIBI4UIPROC VertexAttribI4ui; + PFNVERTEXATTRIBI1IVPROC VertexAttribI1iv; + PFNVERTEXATTRIBI2IVPROC VertexAttribI2iv; + PFNVERTEXATTRIBI3IVPROC VertexAttribI3iv; + PFNVERTEXATTRIBI4IVPROC VertexAttribI4iv; + PFNVERTEXATTRIBI1UIVPROC VertexAttribI1uiv; + PFNVERTEXATTRIBI2UIVPROC VertexAttribI2uiv; + PFNVERTEXATTRIBI3UIVPROC VertexAttribI3uiv; + PFNVERTEXATTRIBI4UIVPROC VertexAttribI4uiv; + PFNVERTEXATTRIBI4BVPROC VertexAttribI4bv; + PFNVERTEXATTRIBI4SVPROC VertexAttribI4sv; + PFNVERTEXATTRIBI4UBVPROC VertexAttribI4ubv; + PFNVERTEXATTRIBI4USVPROC VertexAttribI4usv; + PFNGETUNIFORMUIVPROC GetUniformuiv; + PFNBINDFRAGDATALOCATIONPROC BindFragDataLocation; + PFNGETFRAGDATALOCATIONPROC GetFragDataLocation; + PFNUNIFORM1UIPROC Uniform1ui; + PFNUNIFORM2UIPROC Uniform2ui; + PFNUNIFORM3UIPROC Uniform3ui; + PFNUNIFORM4UIPROC Uniform4ui; + PFNUNIFORM1UIVPROC Uniform1uiv; + PFNUNIFORM2UIVPROC Uniform2uiv; + PFNUNIFORM3UIVPROC Uniform3uiv; + PFNUNIFORM4UIVPROC Uniform4uiv; + PFNTEXPARAMETERIIVPROC TexParameterIiv; + PFNTEXPARAMETERIUIVPROC TexParameterIuiv; + PFNGETTEXPARAMETERIIVPROC GetTexParameterIiv; + PFNGETTEXPARAMETERIUIVPROC GetTexParameterIuiv; + PFNCLEARBUFFERIVPROC ClearBufferiv; + PFNCLEARBUFFERUIVPROC ClearBufferuiv; + PFNCLEARBUFFERFVPROC ClearBufferfv; + PFNCLEARBUFFERFIPROC ClearBufferfi; + PFNGETSTRINGIPROC GetStringi; + + // Extension: ARB_uniform_buffer_object + PFNGETUNIFORMINDICESPROC GetUniformIndices; + PFNGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv; + PFNGETACTIVEUNIFORMNAMEPROC GetActiveUniformName; + PFNGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex; + PFNGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv; + PFNGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName; + PFNUNIFORMBLOCKBINDINGPROC UniformBlockBinding; + + // Extension: ARB_copy_buffer + PFNCOPYBUFFERSUBDATAPROC CopyBufferSubData; + + // Extension: 3.1 + PFNDRAWARRAYSINSTANCEDPROC DrawArraysInstanced; + PFNDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced; + PFNTEXBUFFERPROC TexBuffer; + PFNPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex; + + // Legacy + PFNENABLECLIENTSTATEPROC EnableClientState; + PFNDISABLECLIENTSTATEPROC DisableClientState; + PFNVERTEXPOINTERPROC VertexPointer; + PFNNORMALPOINTERPROC NormalPointer; + PFNCOLORPOINTERPROC ColorPointer; + PFNTEXCOORDPOINTERPROC TexCoordPointer; + + PFNTEXENVIPROC TexEnvi; + + PFNMATRIXMODEPROC MatrixMode; + PFNLOADIDENTITYPROC LoadIdentity; + PFNORTHOPROC Ortho; + + PFNCOLOR3DPROC Color3d; + + ////////////////////////////////////////////// + // Switch functions + + // Extension: 1.1 + + static void CODEGEN_FUNCPTR Switch_CullFace(GLenum mode) + { + CullFace = (PFNCULLFACEPROC)IntGetProcAddress("glCullFace"); + CullFace(mode); + } + + static void CODEGEN_FUNCPTR Switch_FrontFace(GLenum mode) + { + FrontFace = (PFNFRONTFACEPROC)IntGetProcAddress("glFrontFace"); + FrontFace(mode); + } + + static void CODEGEN_FUNCPTR Switch_Hint(GLenum target, GLenum mode) + { + Hint = (PFNHINTPROC)IntGetProcAddress("glHint"); + Hint(target, mode); + } + + static void CODEGEN_FUNCPTR Switch_LineWidth(GLfloat width) + { + LineWidth = (PFNLINEWIDTHPROC)IntGetProcAddress("glLineWidth"); + LineWidth(width); + } + + static void CODEGEN_FUNCPTR Switch_PointSize(GLfloat size) + { + PointSize = (PFNPOINTSIZEPROC)IntGetProcAddress("glPointSize"); + PointSize(size); + } + + static void CODEGEN_FUNCPTR Switch_PolygonMode(GLenum face, GLenum mode) + { + PolygonMode = (PFNPOLYGONMODEPROC)IntGetProcAddress("glPolygonMode"); + PolygonMode(face, mode); + } + + static void CODEGEN_FUNCPTR Switch_Scissor(GLint x, GLint y, GLsizei width, GLsizei height) + { + Scissor = (PFNSCISSORPROC)IntGetProcAddress("glScissor"); + Scissor(x, y, width, height); + } + + static void CODEGEN_FUNCPTR Switch_TexParameterf(GLenum target, GLenum pname, GLfloat param) + { + TexParameterf = (PFNTEXPARAMETERFPROC)IntGetProcAddress("glTexParameterf"); + TexParameterf(target, pname, param); + } + + static void CODEGEN_FUNCPTR Switch_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) + { + TexParameterfv = (PFNTEXPARAMETERFVPROC)IntGetProcAddress("glTexParameterfv"); + TexParameterfv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_TexParameteri(GLenum target, GLenum pname, GLint param) + { + TexParameteri = (PFNTEXPARAMETERIPROC)IntGetProcAddress("glTexParameteri"); + TexParameteri(target, pname, param); + } + + static void CODEGEN_FUNCPTR Switch_TexParameteriv(GLenum target, GLenum pname, const GLint *params) + { + TexParameteriv = (PFNTEXPARAMETERIVPROC)IntGetProcAddress("glTexParameteriv"); + TexParameteriv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_TexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) + { + TexImage1D = (PFNTEXIMAGE1DPROC)IntGetProcAddress("glTexImage1D"); + TexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) + { + TexImage2D = (PFNTEXIMAGE2DPROC)IntGetProcAddress("glTexImage2D"); + TexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_DrawBuffer(GLenum mode) + { + DrawBuffer = (PFNDRAWBUFFERPROC)IntGetProcAddress("glDrawBuffer"); + DrawBuffer(mode); + } + + static void CODEGEN_FUNCPTR Switch_Clear(GLbitfield mask) + { + Clear = (PFNCLEARPROC)IntGetProcAddress("glClear"); + Clear(mask); + } + + static void CODEGEN_FUNCPTR Switch_ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + { + ClearColor = (PFNCLEARCOLORPROC)IntGetProcAddress("glClearColor"); + ClearColor(red, green, blue, alpha); + } + + static void CODEGEN_FUNCPTR Switch_ClearStencil(GLint s) + { + ClearStencil = (PFNCLEARSTENCILPROC)IntGetProcAddress("glClearStencil"); + ClearStencil(s); + } + + static void CODEGEN_FUNCPTR Switch_ClearDepth(GLdouble depth) + { + ClearDepth = (PFNCLEARDEPTHPROC)IntGetProcAddress("glClearDepth"); + ClearDepth(depth); + } + + static void CODEGEN_FUNCPTR Switch_StencilMask(GLuint mask) + { + StencilMask = (PFNSTENCILMASKPROC)IntGetProcAddress("glStencilMask"); + StencilMask(mask); + } + + static void CODEGEN_FUNCPTR Switch_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) + { + ColorMask = (PFNCOLORMASKPROC)IntGetProcAddress("glColorMask"); + ColorMask(red, green, blue, alpha); + } + + static void CODEGEN_FUNCPTR Switch_DepthMask(GLboolean flag) + { + DepthMask = (PFNDEPTHMASKPROC)IntGetProcAddress("glDepthMask"); + DepthMask(flag); + } + + static void CODEGEN_FUNCPTR Switch_Disable(GLenum cap) + { + Disable = (PFNDISABLEPROC)IntGetProcAddress("glDisable"); + Disable(cap); + } + + static void CODEGEN_FUNCPTR Switch_Enable(GLenum cap) + { + Enable = (PFNENABLEPROC)IntGetProcAddress("glEnable"); + Enable(cap); + } + + static void CODEGEN_FUNCPTR Switch_Finish() + { + Finish = (PFNFINISHPROC)IntGetProcAddress("glFinish"); + Finish(); + } + + static void CODEGEN_FUNCPTR Switch_Flush() + { + Flush = (PFNFLUSHPROC)IntGetProcAddress("glFlush"); + Flush(); + } + + static void CODEGEN_FUNCPTR Switch_BlendFunc(GLenum sfactor, GLenum dfactor) + { + BlendFunc = (PFNBLENDFUNCPROC)IntGetProcAddress("glBlendFunc"); + BlendFunc(sfactor, dfactor); + } + + static void CODEGEN_FUNCPTR Switch_LogicOp(GLenum opcode) + { + LogicOp = (PFNLOGICOPPROC)IntGetProcAddress("glLogicOp"); + LogicOp(opcode); + } + + static void CODEGEN_FUNCPTR Switch_StencilFunc(GLenum func, GLint ref, GLuint mask) + { + StencilFunc = (PFNSTENCILFUNCPROC)IntGetProcAddress("glStencilFunc"); + StencilFunc(func, ref, mask); + } + + static void CODEGEN_FUNCPTR Switch_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) + { + StencilOp = (PFNSTENCILOPPROC)IntGetProcAddress("glStencilOp"); + StencilOp(fail, zfail, zpass); + } + + static void CODEGEN_FUNCPTR Switch_DepthFunc(GLenum func) + { + DepthFunc = (PFNDEPTHFUNCPROC)IntGetProcAddress("glDepthFunc"); + DepthFunc(func); + } + + static void CODEGEN_FUNCPTR Switch_PixelStoref(GLenum pname, GLfloat param) + { + PixelStoref = (PFNPIXELSTOREFPROC)IntGetProcAddress("glPixelStoref"); + PixelStoref(pname, param); + } + + static void CODEGEN_FUNCPTR Switch_PixelStorei(GLenum pname, GLint param) + { + PixelStorei = (PFNPIXELSTOREIPROC)IntGetProcAddress("glPixelStorei"); + PixelStorei(pname, param); + } + + static void CODEGEN_FUNCPTR Switch_ReadBuffer(GLenum mode) + { + ReadBuffer = (PFNREADBUFFERPROC)IntGetProcAddress("glReadBuffer"); + ReadBuffer(mode); + } + + static void CODEGEN_FUNCPTR Switch_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) + { + ReadPixels = (PFNREADPIXELSPROC)IntGetProcAddress("glReadPixels"); + ReadPixels(x, y, width, height, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_GetBooleanv(GLenum pname, GLboolean *params) + { + GetBooleanv = (PFNGETBOOLEANVPROC)IntGetProcAddress("glGetBooleanv"); + GetBooleanv(pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetDoublev(GLenum pname, GLdouble *params) + { + GetDoublev = (PFNGETDOUBLEVPROC)IntGetProcAddress("glGetDoublev"); + GetDoublev(pname, params); + } + + static GLenum CODEGEN_FUNCPTR Switch_GetError() + { + GetError = (PFNGETERRORPROC)IntGetProcAddress("glGetError"); + return GetError(); + } + + static void CODEGEN_FUNCPTR Switch_GetFloatv(GLenum pname, GLfloat *params) + { + GetFloatv = (PFNGETFLOATVPROC)IntGetProcAddress("glGetFloatv"); + GetFloatv(pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetIntegerv(GLenum pname, GLint *params) + { + GetIntegerv = (PFNGETINTEGERVPROC)IntGetProcAddress("glGetIntegerv"); + GetIntegerv(pname, params); + } + + static const GLubyte * CODEGEN_FUNCPTR Switch_GetString(GLenum name) + { + GetString = (PFNGETSTRINGPROC)IntGetProcAddress("glGetString"); + return GetString(name); + } + + static void CODEGEN_FUNCPTR Switch_GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) + { + GetTexImage = (PFNGETTEXIMAGEPROC)IntGetProcAddress("glGetTexImage"); + GetTexImage(target, level, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) + { + GetTexParameterfv = (PFNGETTEXPARAMETERFVPROC)IntGetProcAddress("glGetTexParameterfv"); + GetTexParameterfv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) + { + GetTexParameteriv = (PFNGETTEXPARAMETERIVPROC)IntGetProcAddress("glGetTexParameteriv"); + GetTexParameteriv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) + { + GetTexLevelParameterfv = (PFNGETTEXLEVELPARAMETERFVPROC)IntGetProcAddress("glGetTexLevelParameterfv"); + GetTexLevelParameterfv(target, level, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) + { + GetTexLevelParameteriv = (PFNGETTEXLEVELPARAMETERIVPROC)IntGetProcAddress("glGetTexLevelParameteriv"); + GetTexLevelParameteriv(target, level, pname, params); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsEnabled(GLenum cap) + { + IsEnabled = (PFNISENABLEDPROC)IntGetProcAddress("glIsEnabled"); + return IsEnabled(cap); + } + + static void CODEGEN_FUNCPTR Switch_DepthRange(GLdouble ren_near, GLdouble ren_far) + { + DepthRange = (PFNDEPTHRANGEPROC)IntGetProcAddress("glDepthRange"); + DepthRange(ren_near, ren_far); + } + + static void CODEGEN_FUNCPTR Switch_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) + { + Viewport = (PFNVIEWPORTPROC)IntGetProcAddress("glViewport"); + Viewport(x, y, width, height); + } + + static void CODEGEN_FUNCPTR Switch_DrawArrays(GLenum mode, GLint first, GLsizei count) + { + DrawArrays = (PFNDRAWARRAYSPROC)IntGetProcAddress("glDrawArrays"); + DrawArrays(mode, first, count); + } + + static void CODEGEN_FUNCPTR Switch_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) + { + DrawElements = (PFNDRAWELEMENTSPROC)IntGetProcAddress("glDrawElements"); + DrawElements(mode, count, type, indices); + } + + static void CODEGEN_FUNCPTR Switch_GetPointerv(GLenum pname, GLvoid* *params) + { + GetPointerv = (PFNGETPOINTERVPROC)IntGetProcAddress("glGetPointerv"); + GetPointerv(pname, params); + } + + static void CODEGEN_FUNCPTR Switch_PolygonOffset(GLfloat factor, GLfloat units) + { + PolygonOffset = (PFNPOLYGONOFFSETPROC)IntGetProcAddress("glPolygonOffset"); + PolygonOffset(factor, units); + } + + static void CODEGEN_FUNCPTR Switch_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) + { + CopyTexImage1D = (PFNCOPYTEXIMAGE1DPROC)IntGetProcAddress("glCopyTexImage1D"); + CopyTexImage1D(target, level, internalformat, x, y, width, border); + } + + static void CODEGEN_FUNCPTR Switch_CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) + { + CopyTexImage2D = (PFNCOPYTEXIMAGE2DPROC)IntGetProcAddress("glCopyTexImage2D"); + CopyTexImage2D(target, level, internalformat, x, y, width, height, border); + } + + static void CODEGEN_FUNCPTR Switch_CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) + { + CopyTexSubImage1D = (PFNCOPYTEXSUBIMAGE1DPROC)IntGetProcAddress("glCopyTexSubImage1D"); + CopyTexSubImage1D(target, level, xoffset, x, y, width); + } + + static void CODEGEN_FUNCPTR Switch_CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) + { + CopyTexSubImage2D = (PFNCOPYTEXSUBIMAGE2DPROC)IntGetProcAddress("glCopyTexSubImage2D"); + CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + + static void CODEGEN_FUNCPTR Switch_TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) + { + TexSubImage1D = (PFNTEXSUBIMAGE1DPROC)IntGetProcAddress("glTexSubImage1D"); + TexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + TexSubImage2D = (PFNTEXSUBIMAGE2DPROC)IntGetProcAddress("glTexSubImage2D"); + TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_BindTexture(GLenum target, GLuint texture) + { + BindTexture = (PFNBINDTEXTUREPROC)IntGetProcAddress("glBindTexture"); + BindTexture(target, texture); + } + + static void CODEGEN_FUNCPTR Switch_DeleteTextures(GLsizei n, const GLuint *textures) + { + DeleteTextures = (PFNDELETETEXTURESPROC)IntGetProcAddress("glDeleteTextures"); + DeleteTextures(n, textures); + } + + static void CODEGEN_FUNCPTR Switch_GenTextures(GLsizei n, GLuint *textures) + { + GenTextures = (PFNGENTEXTURESPROC)IntGetProcAddress("glGenTextures"); + GenTextures(n, textures); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsTexture(GLuint texture) + { + IsTexture = (PFNISTEXTUREPROC)IntGetProcAddress("glIsTexture"); + return IsTexture(texture); + } + + static void CODEGEN_FUNCPTR Switch_Indexub(GLubyte c) + { + Indexub = (PFNINDEXUBPROC)IntGetProcAddress("glIndexub"); + Indexub(c); + } + + static void CODEGEN_FUNCPTR Switch_Indexubv(const GLubyte *c) + { + Indexubv = (PFNINDEXUBVPROC)IntGetProcAddress("glIndexubv"); + Indexubv(c); + } + + // Extension: 1.2 + + static void CODEGEN_FUNCPTR Switch_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + { + BlendColor = (PFNBLENDCOLORPROC)IntGetProcAddress("glBlendColor"); + BlendColor(red, green, blue, alpha); + } + + static void CODEGEN_FUNCPTR Switch_BlendEquation(GLenum mode) + { + BlendEquation = (PFNBLENDEQUATIONPROC)IntGetProcAddress("glBlendEquation"); + BlendEquation(mode); + } + + static void CODEGEN_FUNCPTR Switch_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) + { + DrawRangeElements = (PFNDRAWRANGEELEMENTSPROC)IntGetProcAddress("glDrawRangeElements"); + DrawRangeElements(mode, start, end, count, type, indices); + } + + static void CODEGEN_FUNCPTR Switch_TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) + { + TexSubImage3D = (PFNTEXSUBIMAGE3DPROC)IntGetProcAddress("glTexSubImage3D"); + TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } + + static void CODEGEN_FUNCPTR Switch_CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) + { + CopyTexSubImage3D = (PFNCOPYTEXSUBIMAGE3DPROC)IntGetProcAddress("glCopyTexSubImage3D"); + CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + } + + // Extension: 1.3 + + static void CODEGEN_FUNCPTR Switch_ActiveTexture(GLenum texture) + { + ActiveTexture = (PFNACTIVETEXTUREPROC)IntGetProcAddress("glActiveTexture"); + ActiveTexture(texture); + } + + static void CODEGEN_FUNCPTR Switch_SampleCoverage(GLfloat value, GLboolean invert) + { + SampleCoverage = (PFNSAMPLECOVERAGEPROC)IntGetProcAddress("glSampleCoverage"); + SampleCoverage(value, invert); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) + { + CompressedTexImage3D = (PFNCOMPRESSEDTEXIMAGE3DPROC)IntGetProcAddress("glCompressedTexImage3D"); + CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) + { + CompressedTexImage2D = (PFNCOMPRESSEDTEXIMAGE2DPROC)IntGetProcAddress("glCompressedTexImage2D"); + CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) + { + CompressedTexImage1D = (PFNCOMPRESSEDTEXIMAGE1DPROC)IntGetProcAddress("glCompressedTexImage1D"); + CompressedTexImage1D(target, level, internalformat, width, border, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) + { + CompressedTexSubImage3D = (PFNCOMPRESSEDTEXSUBIMAGE3DPROC)IntGetProcAddress("glCompressedTexSubImage3D"); + CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) + { + CompressedTexSubImage2D = (PFNCOMPRESSEDTEXSUBIMAGE2DPROC)IntGetProcAddress("glCompressedTexSubImage2D"); + CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) + { + CompressedTexSubImage1D = (PFNCOMPRESSEDTEXSUBIMAGE1DPROC)IntGetProcAddress("glCompressedTexSubImage1D"); + CompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data); + } + + static void CODEGEN_FUNCPTR Switch_GetCompressedTexImage(GLenum target, GLint level, GLvoid *img) + { + GetCompressedTexImage = (PFNGETCOMPRESSEDTEXIMAGEPROC)IntGetProcAddress("glGetCompressedTexImage"); + GetCompressedTexImage(target, level, img); + } + + // Extension: 1.4 + + static void CODEGEN_FUNCPTR Switch_BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) + { + BlendFuncSeparate = (PFNBLENDFUNCSEPARATEPROC)IntGetProcAddress("glBlendFuncSeparate"); + BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + } + + static void CODEGEN_FUNCPTR Switch_MultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) + { + MultiDrawArrays = (PFNMULTIDRAWARRAYSPROC)IntGetProcAddress("glMultiDrawArrays"); + MultiDrawArrays(mode, first, count, drawcount); + } + + static void CODEGEN_FUNCPTR Switch_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount) + { + MultiDrawElements = (PFNMULTIDRAWELEMENTSPROC)IntGetProcAddress("glMultiDrawElements"); + MultiDrawElements(mode, count, type, indices, drawcount); + } + + static void CODEGEN_FUNCPTR Switch_PointParameterf(GLenum pname, GLfloat param) + { + PointParameterf = (PFNPOINTPARAMETERFPROC)IntGetProcAddress("glPointParameterf"); + PointParameterf(pname, param); + } + + static void CODEGEN_FUNCPTR Switch_PointParameterfv(GLenum pname, const GLfloat *params) + { + PointParameterfv = (PFNPOINTPARAMETERFVPROC)IntGetProcAddress("glPointParameterfv"); + PointParameterfv(pname, params); + } + + static void CODEGEN_FUNCPTR Switch_PointParameteri(GLenum pname, GLint param) + { + PointParameteri = (PFNPOINTPARAMETERIPROC)IntGetProcAddress("glPointParameteri"); + PointParameteri(pname, param); + } + + static void CODEGEN_FUNCPTR Switch_PointParameteriv(GLenum pname, const GLint *params) + { + PointParameteriv = (PFNPOINTPARAMETERIVPROC)IntGetProcAddress("glPointParameteriv"); + PointParameteriv(pname, params); + } + + // Extension: 1.5 + + static void CODEGEN_FUNCPTR Switch_GenQueries(GLsizei n, GLuint *ids) + { + GenQueries = (PFNGENQUERIESPROC)IntGetProcAddress("glGenQueries"); + GenQueries(n, ids); + } + + static void CODEGEN_FUNCPTR Switch_DeleteQueries(GLsizei n, const GLuint *ids) + { + DeleteQueries = (PFNDELETEQUERIESPROC)IntGetProcAddress("glDeleteQueries"); + DeleteQueries(n, ids); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsQuery(GLuint id) + { + IsQuery = (PFNISQUERYPROC)IntGetProcAddress("glIsQuery"); + return IsQuery(id); + } + + static void CODEGEN_FUNCPTR Switch_BeginQuery(GLenum target, GLuint id) + { + BeginQuery = (PFNBEGINQUERYPROC)IntGetProcAddress("glBeginQuery"); + BeginQuery(target, id); + } + + static void CODEGEN_FUNCPTR Switch_EndQuery(GLenum target) + { + EndQuery = (PFNENDQUERYPROC)IntGetProcAddress("glEndQuery"); + EndQuery(target); + } + + static void CODEGEN_FUNCPTR Switch_GetQueryiv(GLenum target, GLenum pname, GLint *params) + { + GetQueryiv = (PFNGETQUERYIVPROC)IntGetProcAddress("glGetQueryiv"); + GetQueryiv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params) + { + GetQueryObjectiv = (PFNGETQUERYOBJECTIVPROC)IntGetProcAddress("glGetQueryObjectiv"); + GetQueryObjectiv(id, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) + { + GetQueryObjectuiv = (PFNGETQUERYOBJECTUIVPROC)IntGetProcAddress("glGetQueryObjectuiv"); + GetQueryObjectuiv(id, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_BindBuffer(GLenum target, GLuint buffer) + { + BindBuffer = (PFNBINDBUFFERPROC)IntGetProcAddress("glBindBuffer"); + BindBuffer(target, buffer); + } + + static void CODEGEN_FUNCPTR Switch_DeleteBuffers(GLsizei n, const GLuint *buffers) + { + DeleteBuffers = (PFNDELETEBUFFERSPROC)IntGetProcAddress("glDeleteBuffers"); + DeleteBuffers(n, buffers); + } + + static void CODEGEN_FUNCPTR Switch_GenBuffers(GLsizei n, GLuint *buffers) + { + GenBuffers = (PFNGENBUFFERSPROC)IntGetProcAddress("glGenBuffers"); + GenBuffers(n, buffers); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsBuffer(GLuint buffer) + { + IsBuffer = (PFNISBUFFERPROC)IntGetProcAddress("glIsBuffer"); + return IsBuffer(buffer); + } + + static void CODEGEN_FUNCPTR Switch_BufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) + { + BufferData = (PFNBUFFERDATAPROC)IntGetProcAddress("glBufferData"); + BufferData(target, size, data, usage); + } + + static void CODEGEN_FUNCPTR Switch_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) + { + BufferSubData = (PFNBUFFERSUBDATAPROC)IntGetProcAddress("glBufferSubData"); + BufferSubData(target, offset, size, data); + } + + static void CODEGEN_FUNCPTR Switch_GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) + { + GetBufferSubData = (PFNGETBUFFERSUBDATAPROC)IntGetProcAddress("glGetBufferSubData"); + GetBufferSubData(target, offset, size, data); + } + + static GLvoid* CODEGEN_FUNCPTR Switch_MapBuffer(GLenum target, GLenum access) + { + MapBuffer = (PFNMAPBUFFERPROC)IntGetProcAddress("glMapBuffer"); + return MapBuffer(target, access); + } + + static GLboolean CODEGEN_FUNCPTR Switch_UnmapBuffer(GLenum target) + { + UnmapBuffer = (PFNUNMAPBUFFERPROC)IntGetProcAddress("glUnmapBuffer"); + return UnmapBuffer(target); + } + + static void CODEGEN_FUNCPTR Switch_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params) + { + GetBufferParameteriv = (PFNGETBUFFERPARAMETERIVPROC)IntGetProcAddress("glGetBufferParameteriv"); + GetBufferParameteriv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetBufferPointerv(GLenum target, GLenum pname, GLvoid* *params) + { + GetBufferPointerv = (PFNGETBUFFERPOINTERVPROC)IntGetProcAddress("glGetBufferPointerv"); + GetBufferPointerv(target, pname, params); + } + + // Extension: 2.0 + + static void CODEGEN_FUNCPTR Switch_BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) + { + BlendEquationSeparate = (PFNBLENDEQUATIONSEPARATEPROC)IntGetProcAddress("glBlendEquationSeparate"); + BlendEquationSeparate(modeRGB, modeAlpha); + } + + static void CODEGEN_FUNCPTR Switch_DrawBuffers(GLsizei n, const GLenum *bufs) + { + DrawBuffers = (PFNDRAWBUFFERSPROC)IntGetProcAddress("glDrawBuffers"); + DrawBuffers(n, bufs); + } + + static void CODEGEN_FUNCPTR Switch_StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) + { + StencilOpSeparate = (PFNSTENCILOPSEPARATEPROC)IntGetProcAddress("glStencilOpSeparate"); + StencilOpSeparate(face, sfail, dpfail, dppass); + } + + static void CODEGEN_FUNCPTR Switch_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) + { + StencilFuncSeparate = (PFNSTENCILFUNCSEPARATEPROC)IntGetProcAddress("glStencilFuncSeparate"); + StencilFuncSeparate(face, func, ref, mask); + } + + static void CODEGEN_FUNCPTR Switch_StencilMaskSeparate(GLenum face, GLuint mask) + { + StencilMaskSeparate = (PFNSTENCILMASKSEPARATEPROC)IntGetProcAddress("glStencilMaskSeparate"); + StencilMaskSeparate(face, mask); + } + + static void CODEGEN_FUNCPTR Switch_AttachShader(GLuint program, GLuint shader) + { + AttachShader = (PFNATTACHSHADERPROC)IntGetProcAddress("glAttachShader"); + AttachShader(program, shader); + } + + static void CODEGEN_FUNCPTR Switch_BindAttribLocation(GLuint program, GLuint index, const GLchar *name) + { + BindAttribLocation = (PFNBINDATTRIBLOCATIONPROC)IntGetProcAddress("glBindAttribLocation"); + BindAttribLocation(program, index, name); + } + + static void CODEGEN_FUNCPTR Switch_CompileShader(GLuint shader) + { + CompileShader = (PFNCOMPILESHADERPROC)IntGetProcAddress("glCompileShader"); + CompileShader(shader); + } + + static GLuint CODEGEN_FUNCPTR Switch_CreateProgram() + { + CreateProgram = (PFNCREATEPROGRAMPROC)IntGetProcAddress("glCreateProgram"); + return CreateProgram(); + } + + static GLuint CODEGEN_FUNCPTR Switch_CreateShader(GLenum type) + { + CreateShader = (PFNCREATESHADERPROC)IntGetProcAddress("glCreateShader"); + return CreateShader(type); + } + + static void CODEGEN_FUNCPTR Switch_DeleteProgram(GLuint program) + { + DeleteProgram = (PFNDELETEPROGRAMPROC)IntGetProcAddress("glDeleteProgram"); + DeleteProgram(program); + } + + static void CODEGEN_FUNCPTR Switch_DeleteShader(GLuint shader) + { + DeleteShader = (PFNDELETESHADERPROC)IntGetProcAddress("glDeleteShader"); + DeleteShader(shader); + } + + static void CODEGEN_FUNCPTR Switch_DetachShader(GLuint program, GLuint shader) + { + DetachShader = (PFNDETACHSHADERPROC)IntGetProcAddress("glDetachShader"); + DetachShader(program, shader); + } + + static void CODEGEN_FUNCPTR Switch_DisableVertexAttribArray(GLuint index) + { + DisableVertexAttribArray = (PFNDISABLEVERTEXATTRIBARRAYPROC)IntGetProcAddress("glDisableVertexAttribArray"); + DisableVertexAttribArray(index); + } + + static void CODEGEN_FUNCPTR Switch_EnableVertexAttribArray(GLuint index) + { + EnableVertexAttribArray = (PFNENABLEVERTEXATTRIBARRAYPROC)IntGetProcAddress("glEnableVertexAttribArray"); + EnableVertexAttribArray(index); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + { + GetActiveAttrib = (PFNGETACTIVEATTRIBPROC)IntGetProcAddress("glGetActiveAttrib"); + GetActiveAttrib(program, index, bufSize, length, size, type, name); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + { + GetActiveUniform = (PFNGETACTIVEUNIFORMPROC)IntGetProcAddress("glGetActiveUniform"); + GetActiveUniform(program, index, bufSize, length, size, type, name); + } + + static void CODEGEN_FUNCPTR Switch_GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) + { + GetAttachedShaders = (PFNGETATTACHEDSHADERSPROC)IntGetProcAddress("glGetAttachedShaders"); + GetAttachedShaders(program, maxCount, count, obj); + } + + static GLint CODEGEN_FUNCPTR Switch_GetAttribLocation(GLuint program, const GLchar *name) + { + GetAttribLocation = (PFNGETATTRIBLOCATIONPROC)IntGetProcAddress("glGetAttribLocation"); + return GetAttribLocation(program, name); + } + + static void CODEGEN_FUNCPTR Switch_GetProgramiv(GLuint program, GLenum pname, GLint *params) + { + GetProgramiv = (PFNGETPROGRAMIVPROC)IntGetProcAddress("glGetProgramiv"); + GetProgramiv(program, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) + { + GetProgramInfoLog = (PFNGETPROGRAMINFOLOGPROC)IntGetProcAddress("glGetProgramInfoLog"); + GetProgramInfoLog(program, bufSize, length, infoLog); + } + + static void CODEGEN_FUNCPTR Switch_GetShaderiv(GLuint shader, GLenum pname, GLint *params) + { + GetShaderiv = (PFNGETSHADERIVPROC)IntGetProcAddress("glGetShaderiv"); + GetShaderiv(shader, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) + { + GetShaderInfoLog = (PFNGETSHADERINFOLOGPROC)IntGetProcAddress("glGetShaderInfoLog"); + GetShaderInfoLog(shader, bufSize, length, infoLog); + } + + static void CODEGEN_FUNCPTR Switch_GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) + { + GetShaderSource = (PFNGETSHADERSOURCEPROC)IntGetProcAddress("glGetShaderSource"); + GetShaderSource(shader, bufSize, length, source); + } + + static GLint CODEGEN_FUNCPTR Switch_GetUniformLocation(GLuint program, const GLchar *name) + { + GetUniformLocation = (PFNGETUNIFORMLOCATIONPROC)IntGetProcAddress("glGetUniformLocation"); + return GetUniformLocation(program, name); + } + + static void CODEGEN_FUNCPTR Switch_GetUniformfv(GLuint program, GLint location, GLfloat *params) + { + GetUniformfv = (PFNGETUNIFORMFVPROC)IntGetProcAddress("glGetUniformfv"); + GetUniformfv(program, location, params); + } + + static void CODEGEN_FUNCPTR Switch_GetUniformiv(GLuint program, GLint location, GLint *params) + { + GetUniformiv = (PFNGETUNIFORMIVPROC)IntGetProcAddress("glGetUniformiv"); + GetUniformiv(program, location, params); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) + { + GetVertexAttribdv = (PFNGETVERTEXATTRIBDVPROC)IntGetProcAddress("glGetVertexAttribdv"); + GetVertexAttribdv(index, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) + { + GetVertexAttribfv = (PFNGETVERTEXATTRIBFVPROC)IntGetProcAddress("glGetVertexAttribfv"); + GetVertexAttribfv(index, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params) + { + GetVertexAttribiv = (PFNGETVERTEXATTRIBIVPROC)IntGetProcAddress("glGetVertexAttribiv"); + GetVertexAttribiv(index, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid* *pointer) + { + GetVertexAttribPointerv = (PFNGETVERTEXATTRIBPOINTERVPROC)IntGetProcAddress("glGetVertexAttribPointerv"); + GetVertexAttribPointerv(index, pname, pointer); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsProgram(GLuint program) + { + IsProgram = (PFNISPROGRAMPROC)IntGetProcAddress("glIsProgram"); + return IsProgram(program); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsShader(GLuint shader) + { + IsShader = (PFNISSHADERPROC)IntGetProcAddress("glIsShader"); + return IsShader(shader); + } + + static void CODEGEN_FUNCPTR Switch_LinkProgram(GLuint program) + { + LinkProgram = (PFNLINKPROGRAMPROC)IntGetProcAddress("glLinkProgram"); + LinkProgram(program); + } + + static void CODEGEN_FUNCPTR Switch_ShaderSource(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length) + { + ShaderSource = (PFNSHADERSOURCEPROC)IntGetProcAddress("glShaderSource"); + ShaderSource(shader, count, string, length); + } + + static void CODEGEN_FUNCPTR Switch_UseProgram(GLuint program) + { + UseProgram = (PFNUSEPROGRAMPROC)IntGetProcAddress("glUseProgram"); + UseProgram(program); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1f(GLint location, GLfloat v0) + { + Uniform1f = (PFNUNIFORM1FPROC)IntGetProcAddress("glUniform1f"); + Uniform1f(location, v0); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2f(GLint location, GLfloat v0, GLfloat v1) + { + Uniform2f = (PFNUNIFORM2FPROC)IntGetProcAddress("glUniform2f"); + Uniform2f(location, v0, v1); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) + { + Uniform3f = (PFNUNIFORM3FPROC)IntGetProcAddress("glUniform3f"); + Uniform3f(location, v0, v1, v2); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) + { + Uniform4f = (PFNUNIFORM4FPROC)IntGetProcAddress("glUniform4f"); + Uniform4f(location, v0, v1, v2, v3); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1i(GLint location, GLint v0) + { + Uniform1i = (PFNUNIFORM1IPROC)IntGetProcAddress("glUniform1i"); + Uniform1i(location, v0); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2i(GLint location, GLint v0, GLint v1) + { + Uniform2i = (PFNUNIFORM2IPROC)IntGetProcAddress("glUniform2i"); + Uniform2i(location, v0, v1); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3i(GLint location, GLint v0, GLint v1, GLint v2) + { + Uniform3i = (PFNUNIFORM3IPROC)IntGetProcAddress("glUniform3i"); + Uniform3i(location, v0, v1, v2); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) + { + Uniform4i = (PFNUNIFORM4IPROC)IntGetProcAddress("glUniform4i"); + Uniform4i(location, v0, v1, v2, v3); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1fv(GLint location, GLsizei count, const GLfloat *value) + { + Uniform1fv = (PFNUNIFORM1FVPROC)IntGetProcAddress("glUniform1fv"); + Uniform1fv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2fv(GLint location, GLsizei count, const GLfloat *value) + { + Uniform2fv = (PFNUNIFORM2FVPROC)IntGetProcAddress("glUniform2fv"); + Uniform2fv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3fv(GLint location, GLsizei count, const GLfloat *value) + { + Uniform3fv = (PFNUNIFORM3FVPROC)IntGetProcAddress("glUniform3fv"); + Uniform3fv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4fv(GLint location, GLsizei count, const GLfloat *value) + { + Uniform4fv = (PFNUNIFORM4FVPROC)IntGetProcAddress("glUniform4fv"); + Uniform4fv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1iv(GLint location, GLsizei count, const GLint *value) + { + Uniform1iv = (PFNUNIFORM1IVPROC)IntGetProcAddress("glUniform1iv"); + Uniform1iv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2iv(GLint location, GLsizei count, const GLint *value) + { + Uniform2iv = (PFNUNIFORM2IVPROC)IntGetProcAddress("glUniform2iv"); + Uniform2iv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3iv(GLint location, GLsizei count, const GLint *value) + { + Uniform3iv = (PFNUNIFORM3IVPROC)IntGetProcAddress("glUniform3iv"); + Uniform3iv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4iv(GLint location, GLsizei count, const GLint *value) + { + Uniform4iv = (PFNUNIFORM4IVPROC)IntGetProcAddress("glUniform4iv"); + Uniform4iv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix2fv = (PFNUNIFORMMATRIX2FVPROC)IntGetProcAddress("glUniformMatrix2fv"); + UniformMatrix2fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix3fv = (PFNUNIFORMMATRIX3FVPROC)IntGetProcAddress("glUniformMatrix3fv"); + UniformMatrix3fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix4fv = (PFNUNIFORMMATRIX4FVPROC)IntGetProcAddress("glUniformMatrix4fv"); + UniformMatrix4fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_ValidateProgram(GLuint program) + { + ValidateProgram = (PFNVALIDATEPROGRAMPROC)IntGetProcAddress("glValidateProgram"); + ValidateProgram(program); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) + { + VertexAttribPointer = (PFNVERTEXATTRIBPOINTERPROC)IntGetProcAddress("glVertexAttribPointer"); + VertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + // Extension: 2.1 + + static void CODEGEN_FUNCPTR Switch_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix2x3fv = (PFNUNIFORMMATRIX2X3FVPROC)IntGetProcAddress("glUniformMatrix2x3fv"); + UniformMatrix2x3fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix3x2fv = (PFNUNIFORMMATRIX3X2FVPROC)IntGetProcAddress("glUniformMatrix3x2fv"); + UniformMatrix3x2fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix2x4fv = (PFNUNIFORMMATRIX2X4FVPROC)IntGetProcAddress("glUniformMatrix2x4fv"); + UniformMatrix2x4fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix4x2fv = (PFNUNIFORMMATRIX4X2FVPROC)IntGetProcAddress("glUniformMatrix4x2fv"); + UniformMatrix4x2fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix3x4fv = (PFNUNIFORMMATRIX3X4FVPROC)IntGetProcAddress("glUniformMatrix3x4fv"); + UniformMatrix3x4fv(location, count, transpose, value); + } + + static void CODEGEN_FUNCPTR Switch_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + UniformMatrix4x3fv = (PFNUNIFORMMATRIX4X3FVPROC)IntGetProcAddress("glUniformMatrix4x3fv"); + UniformMatrix4x3fv(location, count, transpose, value); + } + + // Extension: ARB_vertex_array_object + + static void CODEGEN_FUNCPTR Switch_BindVertexArray(GLuint ren_array) + { + BindVertexArray = (PFNBINDVERTEXARRAYPROC)IntGetProcAddress("glBindVertexArray"); + BindVertexArray(ren_array); + } + + static void CODEGEN_FUNCPTR Switch_DeleteVertexArrays(GLsizei n, const GLuint *arrays) + { + DeleteVertexArrays = (PFNDELETEVERTEXARRAYSPROC)IntGetProcAddress("glDeleteVertexArrays"); + DeleteVertexArrays(n, arrays); + } + + static void CODEGEN_FUNCPTR Switch_GenVertexArrays(GLsizei n, GLuint *arrays) + { + GenVertexArrays = (PFNGENVERTEXARRAYSPROC)IntGetProcAddress("glGenVertexArrays"); + GenVertexArrays(n, arrays); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsVertexArray(GLuint ren_array) + { + IsVertexArray = (PFNISVERTEXARRAYPROC)IntGetProcAddress("glIsVertexArray"); + return IsVertexArray(ren_array); + } + + // Extension: ARB_map_buffer_range + + static GLvoid* CODEGEN_FUNCPTR Switch_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) + { + MapBufferRange = (PFNMAPBUFFERRANGEPROC)IntGetProcAddress("glMapBufferRange"); + return MapBufferRange(target, offset, length, access); + } + + static void CODEGEN_FUNCPTR Switch_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) + { + FlushMappedBufferRange = (PFNFLUSHMAPPEDBUFFERRANGEPROC)IntGetProcAddress("glFlushMappedBufferRange"); + FlushMappedBufferRange(target, offset, length); + } + + // Extension: ARB_framebuffer_object + + static GLboolean CODEGEN_FUNCPTR Switch_IsRenderbuffer(GLuint renderbuffer) + { + IsRenderbuffer = (PFNISRENDERBUFFERPROC)IntGetProcAddress("glIsRenderbuffer"); + return IsRenderbuffer(renderbuffer); + } + + static void CODEGEN_FUNCPTR Switch_BindRenderbuffer(GLenum target, GLuint renderbuffer) + { + BindRenderbuffer = (PFNBINDRENDERBUFFERPROC)IntGetProcAddress("glBindRenderbuffer"); + BindRenderbuffer(target, renderbuffer); + } + + static void CODEGEN_FUNCPTR Switch_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) + { + DeleteRenderbuffers = (PFNDELETERENDERBUFFERSPROC)IntGetProcAddress("glDeleteRenderbuffers"); + DeleteRenderbuffers(n, renderbuffers); + } + + static void CODEGEN_FUNCPTR Switch_GenRenderbuffers(GLsizei n, GLuint *renderbuffers) + { + GenRenderbuffers = (PFNGENRENDERBUFFERSPROC)IntGetProcAddress("glGenRenderbuffers"); + GenRenderbuffers(n, renderbuffers); + } + + static void CODEGEN_FUNCPTR Switch_RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) + { + RenderbufferStorage = (PFNRENDERBUFFERSTORAGEPROC)IntGetProcAddress("glRenderbufferStorage"); + RenderbufferStorage(target, internalformat, width, height); + } + + static void CODEGEN_FUNCPTR Switch_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) + { + GetRenderbufferParameteriv = (PFNGETRENDERBUFFERPARAMETERIVPROC)IntGetProcAddress("glGetRenderbufferParameteriv"); + GetRenderbufferParameteriv(target, pname, params); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsFramebuffer(GLuint framebuffer) + { + IsFramebuffer = (PFNISFRAMEBUFFERPROC)IntGetProcAddress("glIsFramebuffer"); + return IsFramebuffer(framebuffer); + } + + static void CODEGEN_FUNCPTR Switch_BindFramebuffer(GLenum target, GLuint framebuffer) + { + BindFramebuffer = (PFNBINDFRAMEBUFFERPROC)IntGetProcAddress("glBindFramebuffer"); + BindFramebuffer(target, framebuffer); + } + + static void CODEGEN_FUNCPTR Switch_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) + { + DeleteFramebuffers = (PFNDELETEFRAMEBUFFERSPROC)IntGetProcAddress("glDeleteFramebuffers"); + DeleteFramebuffers(n, framebuffers); + } + + static void CODEGEN_FUNCPTR Switch_GenFramebuffers(GLsizei n, GLuint *framebuffers) + { + GenFramebuffers = (PFNGENFRAMEBUFFERSPROC)IntGetProcAddress("glGenFramebuffers"); + GenFramebuffers(n, framebuffers); + } + + static GLenum CODEGEN_FUNCPTR Switch_CheckFramebufferStatus(GLenum target) + { + CheckFramebufferStatus = (PFNCHECKFRAMEBUFFERSTATUSPROC)IntGetProcAddress("glCheckFramebufferStatus"); + return CheckFramebufferStatus(target); + } + + static void CODEGEN_FUNCPTR Switch_FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + { + FramebufferTexture1D = (PFNFRAMEBUFFERTEXTURE1DPROC)IntGetProcAddress("glFramebufferTexture1D"); + FramebufferTexture1D(target, attachment, textarget, texture, level); + } + + static void CODEGEN_FUNCPTR Switch_FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + { + FramebufferTexture2D = (PFNFRAMEBUFFERTEXTURE2DPROC)IntGetProcAddress("glFramebufferTexture2D"); + FramebufferTexture2D(target, attachment, textarget, texture, level); + } + + static void CODEGEN_FUNCPTR Switch_FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) + { + FramebufferTexture3D = (PFNFRAMEBUFFERTEXTURE3DPROC)IntGetProcAddress("glFramebufferTexture3D"); + FramebufferTexture3D(target, attachment, textarget, texture, level, zoffset); + } + + static void CODEGEN_FUNCPTR Switch_FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) + { + FramebufferRenderbuffer = (PFNFRAMEBUFFERRENDERBUFFERPROC)IntGetProcAddress("glFramebufferRenderbuffer"); + FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + } + + static void CODEGEN_FUNCPTR Switch_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) + { + GetFramebufferAttachmentParameteriv = (PFNGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)IntGetProcAddress("glGetFramebufferAttachmentParameteriv"); + GetFramebufferAttachmentParameteriv(target, attachment, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GenerateMipmap(GLenum target) + { + GenerateMipmap = (PFNGENERATEMIPMAPPROC)IntGetProcAddress("glGenerateMipmap"); + GenerateMipmap(target); + } + + static void CODEGEN_FUNCPTR Switch_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) + { + BlitFramebuffer = (PFNBLITFRAMEBUFFERPROC)IntGetProcAddress("glBlitFramebuffer"); + BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } + + static void CODEGEN_FUNCPTR Switch_RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) + { + RenderbufferStorageMultisample = (PFNRENDERBUFFERSTORAGEMULTISAMPLEPROC)IntGetProcAddress("glRenderbufferStorageMultisample"); + RenderbufferStorageMultisample(target, samples, internalformat, width, height); + } + + static void CODEGEN_FUNCPTR Switch_FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) + { + FramebufferTextureLayer = (PFNFRAMEBUFFERTEXTURELAYERPROC)IntGetProcAddress("glFramebufferTextureLayer"); + FramebufferTextureLayer(target, attachment, texture, level, layer); + } + + // Extension: 3.0 + + static void CODEGEN_FUNCPTR Switch_ColorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) + { + ColorMaski = (PFNCOLORMASKIPROC)IntGetProcAddress("glColorMaski"); + ColorMaski(index, r, g, b, a); + } + + static void CODEGEN_FUNCPTR Switch_GetBooleani_v(GLenum target, GLuint index, GLboolean *data) + { + GetBooleani_v = (PFNGETBOOLEANI_VPROC)IntGetProcAddress("glGetBooleani_v"); + GetBooleani_v(target, index, data); + } + + static void CODEGEN_FUNCPTR Switch_GetIntegeri_v(GLenum target, GLuint index, GLint *data) + { + GetIntegeri_v = (PFNGETINTEGERI_VPROC)IntGetProcAddress("glGetIntegeri_v"); + GetIntegeri_v(target, index, data); + } + + static void CODEGEN_FUNCPTR Switch_Enablei(GLenum target, GLuint index) + { + Enablei = (PFNENABLEIPROC)IntGetProcAddress("glEnablei"); + Enablei(target, index); + } + + static void CODEGEN_FUNCPTR Switch_Disablei(GLenum target, GLuint index) + { + Disablei = (PFNDISABLEIPROC)IntGetProcAddress("glDisablei"); + Disablei(target, index); + } + + static GLboolean CODEGEN_FUNCPTR Switch_IsEnabledi(GLenum target, GLuint index) + { + IsEnabledi = (PFNISENABLEDIPROC)IntGetProcAddress("glIsEnabledi"); + return IsEnabledi(target, index); + } + + static void CODEGEN_FUNCPTR Switch_BeginTransformFeedback(GLenum primitiveMode) + { + BeginTransformFeedback = (PFNBEGINTRANSFORMFEEDBACKPROC)IntGetProcAddress("glBeginTransformFeedback"); + BeginTransformFeedback(primitiveMode); + } + + static void CODEGEN_FUNCPTR Switch_EndTransformFeedback() + { + EndTransformFeedback = (PFNENDTRANSFORMFEEDBACKPROC)IntGetProcAddress("glEndTransformFeedback"); + EndTransformFeedback(); + } + + static void CODEGEN_FUNCPTR Switch_BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) + { + BindBufferRange = (PFNBINDBUFFERRANGEPROC)IntGetProcAddress("glBindBufferRange"); + BindBufferRange(target, index, buffer, offset, size); + } + + static void CODEGEN_FUNCPTR Switch_BindBufferBase(GLenum target, GLuint index, GLuint buffer) + { + BindBufferBase = (PFNBINDBUFFERBASEPROC)IntGetProcAddress("glBindBufferBase"); + BindBufferBase(target, index, buffer); + } + + static void CODEGEN_FUNCPTR Switch_TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode) + { + TransformFeedbackVaryings = (PFNTRANSFORMFEEDBACKVARYINGSPROC)IntGetProcAddress("glTransformFeedbackVaryings"); + TransformFeedbackVaryings(program, count, varyings, bufferMode); + } + + static void CODEGEN_FUNCPTR Switch_GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) + { + GetTransformFeedbackVarying = (PFNGETTRANSFORMFEEDBACKVARYINGPROC)IntGetProcAddress("glGetTransformFeedbackVarying"); + GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + } + + static void CODEGEN_FUNCPTR Switch_ClampColor(GLenum target, GLenum clamp) + { + ClampColor = (PFNCLAMPCOLORPROC)IntGetProcAddress("glClampColor"); + ClampColor(target, clamp); + } + + static void CODEGEN_FUNCPTR Switch_BeginConditionalRender(GLuint id, GLenum mode) + { + BeginConditionalRender = (PFNBEGINCONDITIONALRENDERPROC)IntGetProcAddress("glBeginConditionalRender"); + BeginConditionalRender(id, mode); + } + + static void CODEGEN_FUNCPTR Switch_EndConditionalRender() + { + EndConditionalRender = (PFNENDCONDITIONALRENDERPROC)IntGetProcAddress("glEndConditionalRender"); + EndConditionalRender(); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) + { + VertexAttribIPointer = (PFNVERTEXATTRIBIPOINTERPROC)IntGetProcAddress("glVertexAttribIPointer"); + VertexAttribIPointer(index, size, type, stride, pointer); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) + { + GetVertexAttribIiv = (PFNGETVERTEXATTRIBIIVPROC)IntGetProcAddress("glGetVertexAttribIiv"); + GetVertexAttribIiv(index, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) + { + GetVertexAttribIuiv = (PFNGETVERTEXATTRIBIUIVPROC)IntGetProcAddress("glGetVertexAttribIuiv"); + GetVertexAttribIuiv(index, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI1i(GLuint index, GLint x) + { + VertexAttribI1i = (PFNVERTEXATTRIBI1IPROC)IntGetProcAddress("glVertexAttribI1i"); + VertexAttribI1i(index, x); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI2i(GLuint index, GLint x, GLint y) + { + VertexAttribI2i = (PFNVERTEXATTRIBI2IPROC)IntGetProcAddress("glVertexAttribI2i"); + VertexAttribI2i(index, x, y); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI3i(GLuint index, GLint x, GLint y, GLint z) + { + VertexAttribI3i = (PFNVERTEXATTRIBI3IPROC)IntGetProcAddress("glVertexAttribI3i"); + VertexAttribI3i(index, x, y, z); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) + { + VertexAttribI4i = (PFNVERTEXATTRIBI4IPROC)IntGetProcAddress("glVertexAttribI4i"); + VertexAttribI4i(index, x, y, z, w); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI1ui(GLuint index, GLuint x) + { + VertexAttribI1ui = (PFNVERTEXATTRIBI1UIPROC)IntGetProcAddress("glVertexAttribI1ui"); + VertexAttribI1ui(index, x); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI2ui(GLuint index, GLuint x, GLuint y) + { + VertexAttribI2ui = (PFNVERTEXATTRIBI2UIPROC)IntGetProcAddress("glVertexAttribI2ui"); + VertexAttribI2ui(index, x, y); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z) + { + VertexAttribI3ui = (PFNVERTEXATTRIBI3UIPROC)IntGetProcAddress("glVertexAttribI3ui"); + VertexAttribI3ui(index, x, y, z); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) + { + VertexAttribI4ui = (PFNVERTEXATTRIBI4UIPROC)IntGetProcAddress("glVertexAttribI4ui"); + VertexAttribI4ui(index, x, y, z, w); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI1iv(GLuint index, const GLint *v) + { + VertexAttribI1iv = (PFNVERTEXATTRIBI1IVPROC)IntGetProcAddress("glVertexAttribI1iv"); + VertexAttribI1iv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI2iv(GLuint index, const GLint *v) + { + VertexAttribI2iv = (PFNVERTEXATTRIBI2IVPROC)IntGetProcAddress("glVertexAttribI2iv"); + VertexAttribI2iv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI3iv(GLuint index, const GLint *v) + { + VertexAttribI3iv = (PFNVERTEXATTRIBI3IVPROC)IntGetProcAddress("glVertexAttribI3iv"); + VertexAttribI3iv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4iv(GLuint index, const GLint *v) + { + VertexAttribI4iv = (PFNVERTEXATTRIBI4IVPROC)IntGetProcAddress("glVertexAttribI4iv"); + VertexAttribI4iv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI1uiv(GLuint index, const GLuint *v) + { + VertexAttribI1uiv = (PFNVERTEXATTRIBI1UIVPROC)IntGetProcAddress("glVertexAttribI1uiv"); + VertexAttribI1uiv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI2uiv(GLuint index, const GLuint *v) + { + VertexAttribI2uiv = (PFNVERTEXATTRIBI2UIVPROC)IntGetProcAddress("glVertexAttribI2uiv"); + VertexAttribI2uiv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI3uiv(GLuint index, const GLuint *v) + { + VertexAttribI3uiv = (PFNVERTEXATTRIBI3UIVPROC)IntGetProcAddress("glVertexAttribI3uiv"); + VertexAttribI3uiv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4uiv(GLuint index, const GLuint *v) + { + VertexAttribI4uiv = (PFNVERTEXATTRIBI4UIVPROC)IntGetProcAddress("glVertexAttribI4uiv"); + VertexAttribI4uiv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4bv(GLuint index, const GLbyte *v) + { + VertexAttribI4bv = (PFNVERTEXATTRIBI4BVPROC)IntGetProcAddress("glVertexAttribI4bv"); + VertexAttribI4bv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4sv(GLuint index, const GLshort *v) + { + VertexAttribI4sv = (PFNVERTEXATTRIBI4SVPROC)IntGetProcAddress("glVertexAttribI4sv"); + VertexAttribI4sv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4ubv(GLuint index, const GLubyte *v) + { + VertexAttribI4ubv = (PFNVERTEXATTRIBI4UBVPROC)IntGetProcAddress("glVertexAttribI4ubv"); + VertexAttribI4ubv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_VertexAttribI4usv(GLuint index, const GLushort *v) + { + VertexAttribI4usv = (PFNVERTEXATTRIBI4USVPROC)IntGetProcAddress("glVertexAttribI4usv"); + VertexAttribI4usv(index, v); + } + + static void CODEGEN_FUNCPTR Switch_GetUniformuiv(GLuint program, GLint location, GLuint *params) + { + GetUniformuiv = (PFNGETUNIFORMUIVPROC)IntGetProcAddress("glGetUniformuiv"); + GetUniformuiv(program, location, params); + } + + static void CODEGEN_FUNCPTR Switch_BindFragDataLocation(GLuint program, GLuint color, const GLchar *name) + { + BindFragDataLocation = (PFNBINDFRAGDATALOCATIONPROC)IntGetProcAddress("glBindFragDataLocation"); + BindFragDataLocation(program, color, name); + } + + static GLint CODEGEN_FUNCPTR Switch_GetFragDataLocation(GLuint program, const GLchar *name) + { + GetFragDataLocation = (PFNGETFRAGDATALOCATIONPROC)IntGetProcAddress("glGetFragDataLocation"); + return GetFragDataLocation(program, name); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1ui(GLint location, GLuint v0) + { + Uniform1ui = (PFNUNIFORM1UIPROC)IntGetProcAddress("glUniform1ui"); + Uniform1ui(location, v0); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2ui(GLint location, GLuint v0, GLuint v1) + { + Uniform2ui = (PFNUNIFORM2UIPROC)IntGetProcAddress("glUniform2ui"); + Uniform2ui(location, v0, v1); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) + { + Uniform3ui = (PFNUNIFORM3UIPROC)IntGetProcAddress("glUniform3ui"); + Uniform3ui(location, v0, v1, v2); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + { + Uniform4ui = (PFNUNIFORM4UIPROC)IntGetProcAddress("glUniform4ui"); + Uniform4ui(location, v0, v1, v2, v3); + } + + static void CODEGEN_FUNCPTR Switch_Uniform1uiv(GLint location, GLsizei count, const GLuint *value) + { + Uniform1uiv = (PFNUNIFORM1UIVPROC)IntGetProcAddress("glUniform1uiv"); + Uniform1uiv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform2uiv(GLint location, GLsizei count, const GLuint *value) + { + Uniform2uiv = (PFNUNIFORM2UIVPROC)IntGetProcAddress("glUniform2uiv"); + Uniform2uiv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform3uiv(GLint location, GLsizei count, const GLuint *value) + { + Uniform3uiv = (PFNUNIFORM3UIVPROC)IntGetProcAddress("glUniform3uiv"); + Uniform3uiv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_Uniform4uiv(GLint location, GLsizei count, const GLuint *value) + { + Uniform4uiv = (PFNUNIFORM4UIVPROC)IntGetProcAddress("glUniform4uiv"); + Uniform4uiv(location, count, value); + } + + static void CODEGEN_FUNCPTR Switch_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) + { + TexParameterIiv = (PFNTEXPARAMETERIIVPROC)IntGetProcAddress("glTexParameterIiv"); + TexParameterIiv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) + { + TexParameterIuiv = (PFNTEXPARAMETERIUIVPROC)IntGetProcAddress("glTexParameterIuiv"); + TexParameterIuiv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) + { + GetTexParameterIiv = (PFNGETTEXPARAMETERIIVPROC)IntGetProcAddress("glGetTexParameterIiv"); + GetTexParameterIiv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) + { + GetTexParameterIuiv = (PFNGETTEXPARAMETERIUIVPROC)IntGetProcAddress("glGetTexParameterIuiv"); + GetTexParameterIuiv(target, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) + { + ClearBufferiv = (PFNCLEARBUFFERIVPROC)IntGetProcAddress("glClearBufferiv"); + ClearBufferiv(buffer, drawbuffer, value); + } + + static void CODEGEN_FUNCPTR Switch_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) + { + ClearBufferuiv = (PFNCLEARBUFFERUIVPROC)IntGetProcAddress("glClearBufferuiv"); + ClearBufferuiv(buffer, drawbuffer, value); + } + + static void CODEGEN_FUNCPTR Switch_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) + { + ClearBufferfv = (PFNCLEARBUFFERFVPROC)IntGetProcAddress("glClearBufferfv"); + ClearBufferfv(buffer, drawbuffer, value); + } + + static void CODEGEN_FUNCPTR Switch_ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) + { + ClearBufferfi = (PFNCLEARBUFFERFIPROC)IntGetProcAddress("glClearBufferfi"); + ClearBufferfi(buffer, drawbuffer, depth, stencil); + } + + static const GLubyte * CODEGEN_FUNCPTR Switch_GetStringi(GLenum name, GLuint index) + { + GetStringi = (PFNGETSTRINGIPROC)IntGetProcAddress("glGetStringi"); + return GetStringi(name, index); + } + + // Extension: ARB_uniform_buffer_object + + static void CODEGEN_FUNCPTR Switch_GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices) + { + GetUniformIndices = (PFNGETUNIFORMINDICESPROC)IntGetProcAddress("glGetUniformIndices"); + GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) + { + GetActiveUniformsiv = (PFNGETACTIVEUNIFORMSIVPROC)IntGetProcAddress("glGetActiveUniformsiv"); + GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName) + { + GetActiveUniformName = (PFNGETACTIVEUNIFORMNAMEPROC)IntGetProcAddress("glGetActiveUniformName"); + GetActiveUniformName(program, uniformIndex, bufSize, length, uniformName); + } + + static GLuint CODEGEN_FUNCPTR Switch_GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) + { + GetUniformBlockIndex = (PFNGETUNIFORMBLOCKINDEXPROC)IntGetProcAddress("glGetUniformBlockIndex"); + return GetUniformBlockIndex(program, uniformBlockName); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params) + { + GetActiveUniformBlockiv = (PFNGETACTIVEUNIFORMBLOCKIVPROC)IntGetProcAddress("glGetActiveUniformBlockiv"); + GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + } + + static void CODEGEN_FUNCPTR Switch_GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) + { + GetActiveUniformBlockName = (PFNGETACTIVEUNIFORMBLOCKNAMEPROC)IntGetProcAddress("glGetActiveUniformBlockName"); + GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + } + + static void CODEGEN_FUNCPTR Switch_UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) + { + UniformBlockBinding = (PFNUNIFORMBLOCKBINDINGPROC)IntGetProcAddress("glUniformBlockBinding"); + UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + + // Extension: ARB_copy_buffer + + static void CODEGEN_FUNCPTR Switch_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) + { + CopyBufferSubData = (PFNCOPYBUFFERSUBDATAPROC)IntGetProcAddress("glCopyBufferSubData"); + CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); + } + + // Extension: 3.1 + + static void CODEGEN_FUNCPTR Switch_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) + { + DrawArraysInstanced = (PFNDRAWARRAYSINSTANCEDPROC)IntGetProcAddress("glDrawArraysInstanced"); + DrawArraysInstanced(mode, first, count, instancecount); + } + + static void CODEGEN_FUNCPTR Switch_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount) + { + DrawElementsInstanced = (PFNDRAWELEMENTSINSTANCEDPROC)IntGetProcAddress("glDrawElementsInstanced"); + DrawElementsInstanced(mode, count, type, indices, instancecount); + } + + static void CODEGEN_FUNCPTR Switch_TexBuffer(GLenum target, GLenum internalformat, GLuint buffer) + { + TexBuffer = (PFNTEXBUFFERPROC)IntGetProcAddress("glTexBuffer"); + TexBuffer(target, internalformat, buffer); + } + + static void CODEGEN_FUNCPTR Switch_PrimitiveRestartIndex(GLuint index) + { + PrimitiveRestartIndex = (PFNPRIMITIVERESTARTINDEXPROC)IntGetProcAddress("glPrimitiveRestartIndex"); + PrimitiveRestartIndex(index); + } + + // Legacy + + static void CODEGEN_FUNCPTR Switch_EnableClientState(GLenum cap) + { + EnableClientState = (PFNENABLECLIENTSTATEPROC)IntGetProcAddress("glEnableClientState"); + EnableClientState(cap); + } + + static void CODEGEN_FUNCPTR Switch_DisableClientState(GLenum cap) + { + DisableClientState = (PFNDISABLECLIENTSTATEPROC)IntGetProcAddress("glDisableClientState"); + DisableClientState(cap); + } + + static void CODEGEN_FUNCPTR Switch_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) + { + VertexPointer = (PFNVERTEXPOINTERPROC)IntGetProcAddress("glVertexPointer"); + VertexPointer(size, type, stride, ptr); + } + + static void CODEGEN_FUNCPTR Switch_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) + { + NormalPointer = (PFNNORMALPOINTERPROC)IntGetProcAddress("glNormalPointer"); + NormalPointer(type, stride, ptr); + } + + static void CODEGEN_FUNCPTR Switch_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) + { + ColorPointer = (PFNCOLORPOINTERPROC)IntGetProcAddress("glColorPointer"); + ColorPointer(size, type, stride, ptr); + } + + static void CODEGEN_FUNCPTR Switch_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) + { + TexCoordPointer = (PFNTEXCOORDPOINTERPROC)IntGetProcAddress("glTexCoordPointer"); + TexCoordPointer(size, type, stride, ptr); + } + + static void CODEGEN_FUNCPTR Switch_TexEnvi(GLenum target, GLenum pname, GLint param) + { + TexEnvi = (PFNTEXENVIPROC)IntGetProcAddress("glTexEnvi"); + TexEnvi(target, pname, param); + } + + static void CODEGEN_FUNCPTR Switch_MatrixMode(GLenum mode) + { + MatrixMode = (PFNMATRIXMODEPROC)IntGetProcAddress("glMatrixMode"); + MatrixMode(mode); + } + + static void CODEGEN_FUNCPTR Switch_LoadIdentity(void) + { + LoadIdentity = (PFNLOADIDENTITYPROC)IntGetProcAddress("glLoadIdentity"); + LoadIdentity(); + } + + static void CODEGEN_FUNCPTR Switch_Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) + { + Ortho = (PFNORTHOPROC)IntGetProcAddress("glOrtho"); + Ortho(left, right, bottom, top, near_val, far_val); + } + + static void CODEGEN_FUNCPTR Switch_Color3d(GLdouble red, GLdouble green, GLdouble blue) + { + Color3d = (PFNCOLOR3DPROC)IntGetProcAddress("glColor3d"); + Color3d(red, green, blue); + } + + struct InitializeVariables + { + InitializeVariables() + { + // Extension: 1.1 + CullFace = Switch_CullFace; + FrontFace = Switch_FrontFace; + Hint = Switch_Hint; + LineWidth = Switch_LineWidth; + PointSize = Switch_PointSize; + PolygonMode = Switch_PolygonMode; + Scissor = Switch_Scissor; + TexParameterf = Switch_TexParameterf; + TexParameterfv = Switch_TexParameterfv; + TexParameteri = Switch_TexParameteri; + TexParameteriv = Switch_TexParameteriv; + TexImage1D = Switch_TexImage1D; + TexImage2D = Switch_TexImage2D; + DrawBuffer = Switch_DrawBuffer; + Clear = Switch_Clear; + ClearColor = Switch_ClearColor; + ClearStencil = Switch_ClearStencil; + ClearDepth = Switch_ClearDepth; + StencilMask = Switch_StencilMask; + ColorMask = Switch_ColorMask; + DepthMask = Switch_DepthMask; + Disable = Switch_Disable; + Enable = Switch_Enable; + Finish = Switch_Finish; + Flush = Switch_Flush; + BlendFunc = Switch_BlendFunc; + LogicOp = Switch_LogicOp; + StencilFunc = Switch_StencilFunc; + StencilOp = Switch_StencilOp; + DepthFunc = Switch_DepthFunc; + PixelStoref = Switch_PixelStoref; + PixelStorei = Switch_PixelStorei; + ReadBuffer = Switch_ReadBuffer; + ReadPixels = Switch_ReadPixels; + GetBooleanv = Switch_GetBooleanv; + GetDoublev = Switch_GetDoublev; + GetError = Switch_GetError; + GetFloatv = Switch_GetFloatv; + GetIntegerv = Switch_GetIntegerv; + GetString = Switch_GetString; + GetTexImage = Switch_GetTexImage; + GetTexParameterfv = Switch_GetTexParameterfv; + GetTexParameteriv = Switch_GetTexParameteriv; + GetTexLevelParameterfv = Switch_GetTexLevelParameterfv; + GetTexLevelParameteriv = Switch_GetTexLevelParameteriv; + IsEnabled = Switch_IsEnabled; + DepthRange = Switch_DepthRange; + Viewport = Switch_Viewport; + DrawArrays = Switch_DrawArrays; + DrawElements = Switch_DrawElements; + GetPointerv = Switch_GetPointerv; + PolygonOffset = Switch_PolygonOffset; + CopyTexImage1D = Switch_CopyTexImage1D; + CopyTexImage2D = Switch_CopyTexImage2D; + CopyTexSubImage1D = Switch_CopyTexSubImage1D; + CopyTexSubImage2D = Switch_CopyTexSubImage2D; + TexSubImage1D = Switch_TexSubImage1D; + TexSubImage2D = Switch_TexSubImage2D; + BindTexture = Switch_BindTexture; + DeleteTextures = Switch_DeleteTextures; + GenTextures = Switch_GenTextures; + IsTexture = Switch_IsTexture; + Indexub = Switch_Indexub; + Indexubv = Switch_Indexubv; + + // Extension: 1.2 + BlendColor = Switch_BlendColor; + BlendEquation = Switch_BlendEquation; + DrawRangeElements = Switch_DrawRangeElements; + TexSubImage3D = Switch_TexSubImage3D; + CopyTexSubImage3D = Switch_CopyTexSubImage3D; + + // Extension: 1.3 + ActiveTexture = Switch_ActiveTexture; + SampleCoverage = Switch_SampleCoverage; + CompressedTexImage3D = Switch_CompressedTexImage3D; + CompressedTexImage2D = Switch_CompressedTexImage2D; + CompressedTexImage1D = Switch_CompressedTexImage1D; + CompressedTexSubImage3D = Switch_CompressedTexSubImage3D; + CompressedTexSubImage2D = Switch_CompressedTexSubImage2D; + CompressedTexSubImage1D = Switch_CompressedTexSubImage1D; + GetCompressedTexImage = Switch_GetCompressedTexImage; + + // Extension: 1.4 + BlendFuncSeparate = Switch_BlendFuncSeparate; + MultiDrawArrays = Switch_MultiDrawArrays; + MultiDrawElements = Switch_MultiDrawElements; + PointParameterf = Switch_PointParameterf; + PointParameterfv = Switch_PointParameterfv; + PointParameteri = Switch_PointParameteri; + PointParameteriv = Switch_PointParameteriv; + + // Extension: 1.5 + GenQueries = Switch_GenQueries; + DeleteQueries = Switch_DeleteQueries; + IsQuery = Switch_IsQuery; + BeginQuery = Switch_BeginQuery; + EndQuery = Switch_EndQuery; + GetQueryiv = Switch_GetQueryiv; + GetQueryObjectiv = Switch_GetQueryObjectiv; + GetQueryObjectuiv = Switch_GetQueryObjectuiv; + BindBuffer = Switch_BindBuffer; + DeleteBuffers = Switch_DeleteBuffers; + GenBuffers = Switch_GenBuffers; + IsBuffer = Switch_IsBuffer; + BufferData = Switch_BufferData; + BufferSubData = Switch_BufferSubData; + GetBufferSubData = Switch_GetBufferSubData; + MapBuffer = Switch_MapBuffer; + UnmapBuffer = Switch_UnmapBuffer; + GetBufferParameteriv = Switch_GetBufferParameteriv; + GetBufferPointerv = Switch_GetBufferPointerv; + + // Extension: 2.0 + BlendEquationSeparate = Switch_BlendEquationSeparate; + DrawBuffers = Switch_DrawBuffers; + StencilOpSeparate = Switch_StencilOpSeparate; + StencilFuncSeparate = Switch_StencilFuncSeparate; + StencilMaskSeparate = Switch_StencilMaskSeparate; + AttachShader = Switch_AttachShader; + BindAttribLocation = Switch_BindAttribLocation; + CompileShader = Switch_CompileShader; + CreateProgram = Switch_CreateProgram; + CreateShader = Switch_CreateShader; + DeleteProgram = Switch_DeleteProgram; + DeleteShader = Switch_DeleteShader; + DetachShader = Switch_DetachShader; + DisableVertexAttribArray = Switch_DisableVertexAttribArray; + EnableVertexAttribArray = Switch_EnableVertexAttribArray; + GetActiveAttrib = Switch_GetActiveAttrib; + GetActiveUniform = Switch_GetActiveUniform; + GetAttachedShaders = Switch_GetAttachedShaders; + GetAttribLocation = Switch_GetAttribLocation; + GetProgramiv = Switch_GetProgramiv; + GetProgramInfoLog = Switch_GetProgramInfoLog; + GetShaderiv = Switch_GetShaderiv; + GetShaderInfoLog = Switch_GetShaderInfoLog; + GetShaderSource = Switch_GetShaderSource; + GetUniformLocation = Switch_GetUniformLocation; + GetUniformfv = Switch_GetUniformfv; + GetUniformiv = Switch_GetUniformiv; + GetVertexAttribdv = Switch_GetVertexAttribdv; + GetVertexAttribfv = Switch_GetVertexAttribfv; + GetVertexAttribiv = Switch_GetVertexAttribiv; + GetVertexAttribPointerv = Switch_GetVertexAttribPointerv; + IsProgram = Switch_IsProgram; + IsShader = Switch_IsShader; + LinkProgram = Switch_LinkProgram; + ShaderSource = Switch_ShaderSource; + UseProgram = Switch_UseProgram; + Uniform1f = Switch_Uniform1f; + Uniform2f = Switch_Uniform2f; + Uniform3f = Switch_Uniform3f; + Uniform4f = Switch_Uniform4f; + Uniform1i = Switch_Uniform1i; + Uniform2i = Switch_Uniform2i; + Uniform3i = Switch_Uniform3i; + Uniform4i = Switch_Uniform4i; + Uniform1fv = Switch_Uniform1fv; + Uniform2fv = Switch_Uniform2fv; + Uniform3fv = Switch_Uniform3fv; + Uniform4fv = Switch_Uniform4fv; + Uniform1iv = Switch_Uniform1iv; + Uniform2iv = Switch_Uniform2iv; + Uniform3iv = Switch_Uniform3iv; + Uniform4iv = Switch_Uniform4iv; + UniformMatrix2fv = Switch_UniformMatrix2fv; + UniformMatrix3fv = Switch_UniformMatrix3fv; + UniformMatrix4fv = Switch_UniformMatrix4fv; + ValidateProgram = Switch_ValidateProgram; + VertexAttribPointer = Switch_VertexAttribPointer; + + // Extension: 2.1 + UniformMatrix2x3fv = Switch_UniformMatrix2x3fv; + UniformMatrix3x2fv = Switch_UniformMatrix3x2fv; + UniformMatrix2x4fv = Switch_UniformMatrix2x4fv; + UniformMatrix4x2fv = Switch_UniformMatrix4x2fv; + UniformMatrix3x4fv = Switch_UniformMatrix3x4fv; + UniformMatrix4x3fv = Switch_UniformMatrix4x3fv; + + // Extension: ARB_vertex_array_object + BindVertexArray = Switch_BindVertexArray; + DeleteVertexArrays = Switch_DeleteVertexArrays; + GenVertexArrays = Switch_GenVertexArrays; + IsVertexArray = Switch_IsVertexArray; + + // Extension: ARB_map_buffer_range + MapBufferRange = Switch_MapBufferRange; + FlushMappedBufferRange = Switch_FlushMappedBufferRange; + + // Extension: ARB_framebuffer_object + IsRenderbuffer = Switch_IsRenderbuffer; + BindRenderbuffer = Switch_BindRenderbuffer; + DeleteRenderbuffers = Switch_DeleteRenderbuffers; + GenRenderbuffers = Switch_GenRenderbuffers; + RenderbufferStorage = Switch_RenderbufferStorage; + GetRenderbufferParameteriv = Switch_GetRenderbufferParameteriv; + IsFramebuffer = Switch_IsFramebuffer; + BindFramebuffer = Switch_BindFramebuffer; + DeleteFramebuffers = Switch_DeleteFramebuffers; + GenFramebuffers = Switch_GenFramebuffers; + CheckFramebufferStatus = Switch_CheckFramebufferStatus; + FramebufferTexture1D = Switch_FramebufferTexture1D; + FramebufferTexture2D = Switch_FramebufferTexture2D; + FramebufferTexture3D = Switch_FramebufferTexture3D; + FramebufferRenderbuffer = Switch_FramebufferRenderbuffer; + GetFramebufferAttachmentParameteriv = Switch_GetFramebufferAttachmentParameteriv; + GenerateMipmap = Switch_GenerateMipmap; + BlitFramebuffer = Switch_BlitFramebuffer; + RenderbufferStorageMultisample = Switch_RenderbufferStorageMultisample; + FramebufferTextureLayer = Switch_FramebufferTextureLayer; + + // Extension: 3.0 + ColorMaski = Switch_ColorMaski; + GetBooleani_v = Switch_GetBooleani_v; + GetIntegeri_v = Switch_GetIntegeri_v; + Enablei = Switch_Enablei; + Disablei = Switch_Disablei; + IsEnabledi = Switch_IsEnabledi; + BeginTransformFeedback = Switch_BeginTransformFeedback; + EndTransformFeedback = Switch_EndTransformFeedback; + BindBufferRange = Switch_BindBufferRange; + BindBufferBase = Switch_BindBufferBase; + TransformFeedbackVaryings = Switch_TransformFeedbackVaryings; + GetTransformFeedbackVarying = Switch_GetTransformFeedbackVarying; + ClampColor = Switch_ClampColor; + BeginConditionalRender = Switch_BeginConditionalRender; + EndConditionalRender = Switch_EndConditionalRender; + VertexAttribIPointer = Switch_VertexAttribIPointer; + GetVertexAttribIiv = Switch_GetVertexAttribIiv; + GetVertexAttribIuiv = Switch_GetVertexAttribIuiv; + VertexAttribI1i = Switch_VertexAttribI1i; + VertexAttribI2i = Switch_VertexAttribI2i; + VertexAttribI3i = Switch_VertexAttribI3i; + VertexAttribI4i = Switch_VertexAttribI4i; + VertexAttribI1ui = Switch_VertexAttribI1ui; + VertexAttribI2ui = Switch_VertexAttribI2ui; + VertexAttribI3ui = Switch_VertexAttribI3ui; + VertexAttribI4ui = Switch_VertexAttribI4ui; + VertexAttribI1iv = Switch_VertexAttribI1iv; + VertexAttribI2iv = Switch_VertexAttribI2iv; + VertexAttribI3iv = Switch_VertexAttribI3iv; + VertexAttribI4iv = Switch_VertexAttribI4iv; + VertexAttribI1uiv = Switch_VertexAttribI1uiv; + VertexAttribI2uiv = Switch_VertexAttribI2uiv; + VertexAttribI3uiv = Switch_VertexAttribI3uiv; + VertexAttribI4uiv = Switch_VertexAttribI4uiv; + VertexAttribI4bv = Switch_VertexAttribI4bv; + VertexAttribI4sv = Switch_VertexAttribI4sv; + VertexAttribI4ubv = Switch_VertexAttribI4ubv; + VertexAttribI4usv = Switch_VertexAttribI4usv; + GetUniformuiv = Switch_GetUniformuiv; + BindFragDataLocation = Switch_BindFragDataLocation; + GetFragDataLocation = Switch_GetFragDataLocation; + Uniform1ui = Switch_Uniform1ui; + Uniform2ui = Switch_Uniform2ui; + Uniform3ui = Switch_Uniform3ui; + Uniform4ui = Switch_Uniform4ui; + Uniform1uiv = Switch_Uniform1uiv; + Uniform2uiv = Switch_Uniform2uiv; + Uniform3uiv = Switch_Uniform3uiv; + Uniform4uiv = Switch_Uniform4uiv; + TexParameterIiv = Switch_TexParameterIiv; + TexParameterIuiv = Switch_TexParameterIuiv; + GetTexParameterIiv = Switch_GetTexParameterIiv; + GetTexParameterIuiv = Switch_GetTexParameterIuiv; + ClearBufferiv = Switch_ClearBufferiv; + ClearBufferuiv = Switch_ClearBufferuiv; + ClearBufferfv = Switch_ClearBufferfv; + ClearBufferfi = Switch_ClearBufferfi; + GetStringi = Switch_GetStringi; + + // Extension: ARB_uniform_buffer_object + GetUniformIndices = Switch_GetUniformIndices; + GetActiveUniformsiv = Switch_GetActiveUniformsiv; + GetActiveUniformName = Switch_GetActiveUniformName; + GetUniformBlockIndex = Switch_GetUniformBlockIndex; + GetActiveUniformBlockiv = Switch_GetActiveUniformBlockiv; + GetActiveUniformBlockName = Switch_GetActiveUniformBlockName; + UniformBlockBinding = Switch_UniformBlockBinding; + + // Extension: ARB_copy_buffer + CopyBufferSubData = Switch_CopyBufferSubData; + + // Extension: 3.1 + DrawArraysInstanced = Switch_DrawArraysInstanced; + DrawElementsInstanced = Switch_DrawElementsInstanced; + TexBuffer = Switch_TexBuffer; + PrimitiveRestartIndex = Switch_PrimitiveRestartIndex; + + // Legacy + EnableClientState = Switch_EnableClientState; + DisableClientState = Switch_DisableClientState; + VertexPointer = Switch_VertexPointer; + NormalPointer = Switch_NormalPointer; + ColorPointer = Switch_ColorPointer; + TexCoordPointer = Switch_TexCoordPointer; + TexEnvi = Switch_TexEnvi; + MatrixMode = Switch_MatrixMode; + LoadIdentity = Switch_LoadIdentity; + Ortho = Switch_Ortho; + Color3d = Switch_Color3d; + } + }; + + InitializeVariables g_initVariables; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/gl_core_3_1.hpp diffimg-2.0.0/3rdparty/opencv/core/src/gl_core_3_1.hpp --- diffimg-1.5.0/3rdparty/opencv/core/src/gl_core_3_1.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/gl_core_3_1.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1373 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENGL_NOLOAD_STYLE_HPP +#define OPENGL_NOLOAD_STYLE_HPP + +#if defined(__gl_h_) || defined(__GL_H__) +#error Attempt to include auto-generated header after including gl.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error Attempt to include auto-generated header after including glext.h +#endif +#if defined(__gl_ATI_h_) +#error Attempt to include auto-generated header after including glATI.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#ifndef APIENTRY + #if defined(__MINGW32__) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN 1 + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #elif (defined(_MSC_VER) && _MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN 1 + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #else + #define APIENTRY + #endif +#endif // APIENTRY + +#ifndef CODEGEN_FUNCPTR + #define CODEGEN_REMOVE_FUNCPTR + #if defined(_WIN32) + #define CODEGEN_FUNCPTR APIENTRY + #else + #define CODEGEN_FUNCPTR + #endif +#endif // CODEGEN_FUNCPTR + +#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS +#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS + typedef unsigned int GLenum; + typedef unsigned char GLboolean; + typedef unsigned int GLbitfield; + typedef signed char GLbyte; + typedef short GLshort; + typedef int GLint; + typedef int GLsizei; + typedef unsigned char GLubyte; + typedef unsigned short GLushort; + typedef unsigned int GLuint; + typedef float GLfloat; + typedef float GLclampf; + typedef double GLdouble; + typedef double GLclampd; + #define GLvoid void +#endif // GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS + +#include + +#ifndef GL_VERSION_2_0 + // GL type for program/shader text + typedef char GLchar; +#endif + +#ifndef GL_VERSION_1_5 + // GL types for handling large vertex buffer objects + typedef ptrdiff_t GLintptr; + typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object + // GL types for handling large vertex buffer objects + typedef ptrdiff_t GLintptrARB; + typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects + // GL types for program/shader text and shader object handles + typedef char GLcharARB; + typedef unsigned int GLhandleARB; +#endif + +// GL type for "half" precision (s10e5) float data in host memory +#ifndef GL_ARB_half_float_pixel + typedef unsigned short GLhalfARB; +#endif +#ifndef GL_NV_half_float + typedef unsigned short GLhalfNV; +#endif + +#ifndef GLEXT_64_TYPES_DEFINED + // This code block is duplicated in glxext.h, so must be protected + #define GLEXT_64_TYPES_DEFINED + + // Define int32_t, int64_t, and uint64_t types for UST/MSC + // (as used in the GL_EXT_timer_query extension) + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #include + #elif defined(__sun__) || defined(__digital__) + #include + #if defined(__STDC__) + #if defined(__arch64__) || defined(_LP64) + typedef long int int64_t; + typedef unsigned long int uint64_t; + #else + typedef long long int int64_t; + typedef unsigned long long int uint64_t; + #endif // __arch64__ + #endif // __STDC__ + #elif defined( __VMS ) || defined(__sgi) + #include + #elif defined(__SCO__) || defined(__USLC__) + #include + #elif defined(__UNIXOS2__) || defined(__SOL64__) + typedef long int int32_t; + typedef long long int int64_t; + typedef unsigned long long int uint64_t; + #elif defined(_WIN32) && defined(__GNUC__) + #include + #elif defined(_WIN32) + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #else + // Fallback if nothing above works + #include + #endif +#endif + +#ifndef GL_EXT_timer_query + typedef int64_t GLint64EXT; + typedef uint64_t GLuint64EXT; +#endif + +#ifndef GL_ARB_sync + typedef int64_t GLint64; + typedef uint64_t GLuint64; + typedef struct __GLsync *GLsync; +#endif + +#ifndef GL_ARB_cl_event + // These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event + struct _cl_context; + struct _cl_event; +#endif + +#ifndef GL_ARB_debug_output + typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_AMD_debug_output + typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_KHR_debug + typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_NV_vdpau_interop + typedef GLintptr GLvdpauSurfaceNV; +#endif + +namespace gl +{ + enum + { + // Version: 1.1 + DEPTH_BUFFER_BIT = 0x00000100, + STENCIL_BUFFER_BIT = 0x00000400, + COLOR_BUFFER_BIT = 0x00004000, + FALSE_ = 0, + TRUE_ = 1, + POINTS = 0x0000, + LINES = 0x0001, + LINE_LOOP = 0x0002, + LINE_STRIP = 0x0003, + TRIANGLES = 0x0004, + TRIANGLE_STRIP = 0x0005, + TRIANGLE_FAN = 0x0006, + QUADS = 0x0007, + NEVER = 0x0200, + LESS = 0x0201, + EQUAL = 0x0202, + LEQUAL = 0x0203, + GREATER = 0x0204, + NOTEQUAL = 0x0205, + GEQUAL = 0x0206, + ALWAYS = 0x0207, + ZERO = 0, + ONE = 1, + SRC_COLOR = 0x0300, + ONE_MINUS_SRC_COLOR = 0x0301, + SRC_ALPHA = 0x0302, + ONE_MINUS_SRC_ALPHA = 0x0303, + DST_ALPHA = 0x0304, + ONE_MINUS_DST_ALPHA = 0x0305, + DST_COLOR = 0x0306, + ONE_MINUS_DST_COLOR = 0x0307, + SRC_ALPHA_SATURATE = 0x0308, + NONE = 0, + FRONT_LEFT = 0x0400, + FRONT_RIGHT = 0x0401, + BACK_LEFT = 0x0402, + BACK_RIGHT = 0x0403, + FRONT = 0x0404, + BACK = 0x0405, + LEFT = 0x0406, + RIGHT = 0x0407, + FRONT_AND_BACK = 0x0408, + NO_ERROR_ = 0, + INVALID_ENUM = 0x0500, + INVALID_VALUE = 0x0501, + INVALID_OPERATION = 0x0502, + OUT_OF_MEMORY = 0x0505, + CW = 0x0900, + CCW = 0x0901, + POINT_SIZE = 0x0B11, + POINT_SIZE_RANGE = 0x0B12, + POINT_SIZE_GRANULARITY = 0x0B13, + LINE_SMOOTH = 0x0B20, + LINE_WIDTH = 0x0B21, + LINE_WIDTH_RANGE = 0x0B22, + LINE_WIDTH_GRANULARITY = 0x0B23, + POLYGON_MODE = 0x0B40, + POLYGON_SMOOTH = 0x0B41, + CULL_FACE = 0x0B44, + CULL_FACE_MODE = 0x0B45, + FRONT_FACE = 0x0B46, + DEPTH_RANGE = 0x0B70, + DEPTH_TEST = 0x0B71, + DEPTH_WRITEMASK = 0x0B72, + DEPTH_CLEAR_VALUE = 0x0B73, + DEPTH_FUNC = 0x0B74, + STENCIL_TEST = 0x0B90, + STENCIL_CLEAR_VALUE = 0x0B91, + STENCIL_FUNC = 0x0B92, + STENCIL_VALUE_MASK = 0x0B93, + STENCIL_FAIL = 0x0B94, + STENCIL_PASS_DEPTH_FAIL = 0x0B95, + STENCIL_PASS_DEPTH_PASS = 0x0B96, + STENCIL_REF = 0x0B97, + STENCIL_WRITEMASK = 0x0B98, + VIEWPORT = 0x0BA2, + DITHER = 0x0BD0, + BLEND_DST = 0x0BE0, + BLEND_SRC = 0x0BE1, + BLEND = 0x0BE2, + LOGIC_OP_MODE = 0x0BF0, + COLOR_LOGIC_OP = 0x0BF2, + DRAW_BUFFER = 0x0C01, + READ_BUFFER = 0x0C02, + SCISSOR_BOX = 0x0C10, + SCISSOR_TEST = 0x0C11, + COLOR_CLEAR_VALUE = 0x0C22, + COLOR_WRITEMASK = 0x0C23, + DOUBLEBUFFER = 0x0C32, + STEREO = 0x0C33, + LINE_SMOOTH_HINT = 0x0C52, + POLYGON_SMOOTH_HINT = 0x0C53, + UNPACK_SWAP_BYTES = 0x0CF0, + UNPACK_LSB_FIRST = 0x0CF1, + UNPACK_ROW_LENGTH = 0x0CF2, + UNPACK_SKIP_ROWS = 0x0CF3, + UNPACK_SKIP_PIXELS = 0x0CF4, + UNPACK_ALIGNMENT = 0x0CF5, + PACK_SWAP_BYTES = 0x0D00, + PACK_LSB_FIRST = 0x0D01, + PACK_ROW_LENGTH = 0x0D02, + PACK_SKIP_ROWS = 0x0D03, + PACK_SKIP_PIXELS = 0x0D04, + PACK_ALIGNMENT = 0x0D05, + MAX_TEXTURE_SIZE = 0x0D33, + MAX_VIEWPORT_DIMS = 0x0D3A, + SUBPIXEL_BITS = 0x0D50, + TEXTURE_1D = 0x0DE0, + TEXTURE_2D = 0x0DE1, + POLYGON_OFFSET_UNITS = 0x2A00, + POLYGON_OFFSET_POINT = 0x2A01, + POLYGON_OFFSET_LINE = 0x2A02, + POLYGON_OFFSET_FILL = 0x8037, + POLYGON_OFFSET_FACTOR = 0x8038, + TEXTURE_BINDING_1D = 0x8068, + TEXTURE_BINDING_2D = 0x8069, + TEXTURE_WIDTH = 0x1000, + TEXTURE_HEIGHT = 0x1001, + TEXTURE_INTERNAL_FORMAT = 0x1003, + TEXTURE_BORDER_COLOR = 0x1004, + TEXTURE_RED_SIZE = 0x805C, + TEXTURE_GREEN_SIZE = 0x805D, + TEXTURE_BLUE_SIZE = 0x805E, + TEXTURE_ALPHA_SIZE = 0x805F, + DONT_CARE = 0x1100, + FASTEST = 0x1101, + NICEST = 0x1102, + BYTE = 0x1400, + UNSIGNED_BYTE = 0x1401, + SHORT = 0x1402, + UNSIGNED_SHORT = 0x1403, + INT = 0x1404, + UNSIGNED_INT = 0x1405, + FLOAT = 0x1406, + DOUBLE = 0x140A, + CLEAR = 0x1500, + AND = 0x1501, + AND_REVERSE = 0x1502, + COPY = 0x1503, + AND_INVERTED = 0x1504, + NOOP = 0x1505, + XOR = 0x1506, + OR = 0x1507, + NOR = 0x1508, + EQUIV = 0x1509, + INVERT = 0x150A, + OR_REVERSE = 0x150B, + COPY_INVERTED = 0x150C, + OR_INVERTED = 0x150D, + NAND = 0x150E, + SET = 0x150F, + TEXTURE = 0x1702, + COLOR = 0x1800, + DEPTH = 0x1801, + STENCIL = 0x1802, + STENCIL_INDEX = 0x1901, + DEPTH_COMPONENT = 0x1902, + RED = 0x1903, + GREEN = 0x1904, + BLUE = 0x1905, + ALPHA = 0x1906, + RGB = 0x1907, + RGBA = 0x1908, + POINT = 0x1B00, + LINE = 0x1B01, + FILL = 0x1B02, + KEEP = 0x1E00, + REPLACE = 0x1E01, + INCR = 0x1E02, + DECR = 0x1E03, + VENDOR = 0x1F00, + RENDERER = 0x1F01, + VERSION_ = 0x1F02, + EXTENSIONS = 0x1F03, + NEAREST = 0x2600, + LINEAR = 0x2601, + NEAREST_MIPMAP_NEAREST = 0x2700, + LINEAR_MIPMAP_NEAREST = 0x2701, + NEAREST_MIPMAP_LINEAR = 0x2702, + LINEAR_MIPMAP_LINEAR = 0x2703, + TEXTURE_MAG_FILTER = 0x2800, + TEXTURE_MIN_FILTER = 0x2801, + TEXTURE_WRAP_S = 0x2802, + TEXTURE_WRAP_T = 0x2803, + PROXY_TEXTURE_1D = 0x8063, + PROXY_TEXTURE_2D = 0x8064, + REPEAT = 0x2901, + R3_G3_B2 = 0x2A10, + RGB4 = 0x804F, + RGB5 = 0x8050, + RGB8 = 0x8051, + RGB10 = 0x8052, + RGB12 = 0x8053, + RGB16 = 0x8054, + RGBA2 = 0x8055, + RGBA4 = 0x8056, + RGB5_A1 = 0x8057, + RGBA8 = 0x8058, + RGB10_A2 = 0x8059, + RGBA12 = 0x805A, + RGBA16 = 0x805B, + + // Core Extension: ARB_imaging + CONSTANT_COLOR = 0x8001, + ONE_MINUS_CONSTANT_COLOR = 0x8002, + CONSTANT_ALPHA = 0x8003, + ONE_MINUS_CONSTANT_ALPHA = 0x8004, + BLEND_COLOR = 0x8005, + FUNC_ADD = 0x8006, + MIN = 0x8007, + MAX = 0x8008, + BLEND_EQUATION = 0x8009, + FUNC_SUBTRACT = 0x800A, + FUNC_REVERSE_SUBTRACT = 0x800B, + CONVOLUTION_1D = 0x8010, + CONVOLUTION_2D = 0x8011, + SEPARABLE_2D = 0x8012, + CONVOLUTION_BORDER_MODE = 0x8013, + CONVOLUTION_FILTER_SCALE = 0x8014, + CONVOLUTION_FILTER_BIAS = 0x8015, + REDUCE = 0x8016, + CONVOLUTION_FORMAT = 0x8017, + CONVOLUTION_WIDTH = 0x8018, + CONVOLUTION_HEIGHT = 0x8019, + MAX_CONVOLUTION_WIDTH = 0x801A, + MAX_CONVOLUTION_HEIGHT = 0x801B, + POST_CONVOLUTION_RED_SCALE = 0x801C, + POST_CONVOLUTION_GREEN_SCALE = 0x801D, + POST_CONVOLUTION_BLUE_SCALE = 0x801E, + POST_CONVOLUTION_ALPHA_SCALE = 0x801F, + POST_CONVOLUTION_RED_BIAS = 0x8020, + POST_CONVOLUTION_GREEN_BIAS = 0x8021, + POST_CONVOLUTION_BLUE_BIAS = 0x8022, + POST_CONVOLUTION_ALPHA_BIAS = 0x8023, + HISTOGRAM = 0x8024, + PROXY_HISTOGRAM = 0x8025, + HISTOGRAM_WIDTH = 0x8026, + HISTOGRAM_FORMAT = 0x8027, + HISTOGRAM_RED_SIZE = 0x8028, + HISTOGRAM_GREEN_SIZE = 0x8029, + HISTOGRAM_BLUE_SIZE = 0x802A, + HISTOGRAM_ALPHA_SIZE = 0x802B, + HISTOGRAM_LUMINANCE_SIZE = 0x802C, + HISTOGRAM_SINK = 0x802D, + MINMAX = 0x802E, + MINMAX_FORMAT = 0x802F, + MINMAX_SINK = 0x8030, + TABLE_TOO_LARGE = 0x8031, + COLOR_MATRIX = 0x80B1, + COLOR_MATRIX_STACK_DEPTH = 0x80B2, + MAX_COLOR_MATRIX_STACK_DEPTH = 0x80B3, + POST_COLOR_MATRIX_RED_SCALE = 0x80B4, + POST_COLOR_MATRIX_GREEN_SCALE = 0x80B5, + POST_COLOR_MATRIX_BLUE_SCALE = 0x80B6, + POST_COLOR_MATRIX_ALPHA_SCALE = 0x80B7, + POST_COLOR_MATRIX_RED_BIAS = 0x80B8, + POST_COLOR_MATRIX_GREEN_BIAS = 0x80B9, + POST_COLOR_MATRIX_BLUE_BIAS = 0x80BA, + POST_COLOR_MATRIX_ALPHA_BIAS = 0x80BB, + COLOR_TABLE = 0x80D0, + POST_CONVOLUTION_COLOR_TABLE = 0x80D1, + POST_COLOR_MATRIX_COLOR_TABLE = 0x80D2, + PROXY_COLOR_TABLE = 0x80D3, + PROXY_POST_CONVOLUTION_COLOR_TABLE = 0x80D4, + PROXY_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D5, + COLOR_TABLE_SCALE = 0x80D6, + COLOR_TABLE_BIAS = 0x80D7, + COLOR_TABLE_FORMAT = 0x80D8, + COLOR_TABLE_WIDTH = 0x80D9, + COLOR_TABLE_RED_SIZE = 0x80DA, + COLOR_TABLE_GREEN_SIZE = 0x80DB, + COLOR_TABLE_BLUE_SIZE = 0x80DC, + COLOR_TABLE_ALPHA_SIZE = 0x80DD, + COLOR_TABLE_LUMINANCE_SIZE = 0x80DE, + COLOR_TABLE_INTENSITY_SIZE = 0x80DF, + CONSTANT_BORDER = 0x8151, + REPLICATE_BORDER = 0x8153, + CONVOLUTION_BORDER_COLOR = 0x8154, + + // Version: 1.2 + UNSIGNED_BYTE_3_3_2 = 0x8032, + UNSIGNED_SHORT_4_4_4_4 = 0x8033, + UNSIGNED_SHORT_5_5_5_1 = 0x8034, + UNSIGNED_INT_8_8_8_8 = 0x8035, + UNSIGNED_INT_10_10_10_2 = 0x8036, + TEXTURE_BINDING_3D = 0x806A, + PACK_SKIP_IMAGES = 0x806B, + PACK_IMAGE_HEIGHT = 0x806C, + UNPACK_SKIP_IMAGES = 0x806D, + UNPACK_IMAGE_HEIGHT = 0x806E, + TEXTURE_3D = 0x806F, + PROXY_TEXTURE_3D = 0x8070, + TEXTURE_DEPTH = 0x8071, + TEXTURE_WRAP_R = 0x8072, + MAX_3D_TEXTURE_SIZE = 0x8073, + UNSIGNED_BYTE_2_3_3_REV = 0x8362, + UNSIGNED_SHORT_5_6_5 = 0x8363, + UNSIGNED_SHORT_5_6_5_REV = 0x8364, + UNSIGNED_SHORT_4_4_4_4_REV = 0x8365, + UNSIGNED_SHORT_1_5_5_5_REV = 0x8366, + UNSIGNED_INT_8_8_8_8_REV = 0x8367, + UNSIGNED_INT_2_10_10_10_REV = 0x8368, + BGR = 0x80E0, + BGRA = 0x80E1, + MAX_ELEMENTS_VERTICES = 0x80E8, + MAX_ELEMENTS_INDICES = 0x80E9, + CLAMP_TO_EDGE = 0x812F, + TEXTURE_MIN_LOD = 0x813A, + TEXTURE_MAX_LOD = 0x813B, + TEXTURE_BASE_LEVEL = 0x813C, + TEXTURE_MAX_LEVEL = 0x813D, + SMOOTH_POINT_SIZE_RANGE = 0x0B12, + SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13, + SMOOTH_LINE_WIDTH_RANGE = 0x0B22, + SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23, + ALIASED_LINE_WIDTH_RANGE = 0x846E, + + // Version: 1.3 + TEXTURE0 = 0x84C0, + TEXTURE1 = 0x84C1, + TEXTURE2 = 0x84C2, + TEXTURE3 = 0x84C3, + TEXTURE4 = 0x84C4, + TEXTURE5 = 0x84C5, + TEXTURE6 = 0x84C6, + TEXTURE7 = 0x84C7, + TEXTURE8 = 0x84C8, + TEXTURE9 = 0x84C9, + TEXTURE10 = 0x84CA, + TEXTURE11 = 0x84CB, + TEXTURE12 = 0x84CC, + TEXTURE13 = 0x84CD, + TEXTURE14 = 0x84CE, + TEXTURE15 = 0x84CF, + TEXTURE16 = 0x84D0, + TEXTURE17 = 0x84D1, + TEXTURE18 = 0x84D2, + TEXTURE19 = 0x84D3, + TEXTURE20 = 0x84D4, + TEXTURE21 = 0x84D5, + TEXTURE22 = 0x84D6, + TEXTURE23 = 0x84D7, + TEXTURE24 = 0x84D8, + TEXTURE25 = 0x84D9, + TEXTURE26 = 0x84DA, + TEXTURE27 = 0x84DB, + TEXTURE28 = 0x84DC, + TEXTURE29 = 0x84DD, + TEXTURE30 = 0x84DE, + TEXTURE31 = 0x84DF, + ACTIVE_TEXTURE = 0x84E0, + MULTISAMPLE = 0x809D, + SAMPLE_ALPHA_TO_COVERAGE = 0x809E, + SAMPLE_ALPHA_TO_ONE = 0x809F, + SAMPLE_COVERAGE = 0x80A0, + SAMPLE_BUFFERS = 0x80A8, + SAMPLES = 0x80A9, + SAMPLE_COVERAGE_VALUE = 0x80AA, + SAMPLE_COVERAGE_INVERT = 0x80AB, + TEXTURE_CUBE_MAP = 0x8513, + TEXTURE_BINDING_CUBE_MAP = 0x8514, + TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, + TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, + TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, + TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, + TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, + TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, + PROXY_TEXTURE_CUBE_MAP = 0x851B, + MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C, + COMPRESSED_RGB = 0x84ED, + COMPRESSED_RGBA = 0x84EE, + TEXTURE_COMPRESSION_HINT = 0x84EF, + TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0, + TEXTURE_COMPRESSED = 0x86A1, + NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2, + COMPRESSED_TEXTURE_FORMATS = 0x86A3, + CLAMP_TO_BORDER = 0x812D, + + // Version: 1.4 + BLEND_DST_RGB = 0x80C8, + BLEND_SRC_RGB = 0x80C9, + BLEND_DST_ALPHA = 0x80CA, + BLEND_SRC_ALPHA = 0x80CB, + POINT_FADE_THRESHOLD_SIZE = 0x8128, + DEPTH_COMPONENT16 = 0x81A5, + DEPTH_COMPONENT24 = 0x81A6, + DEPTH_COMPONENT32 = 0x81A7, + MIRRORED_REPEAT = 0x8370, + MAX_TEXTURE_LOD_BIAS = 0x84FD, + TEXTURE_LOD_BIAS = 0x8501, + INCR_WRAP = 0x8507, + DECR_WRAP = 0x8508, + TEXTURE_DEPTH_SIZE = 0x884A, + TEXTURE_COMPARE_MODE = 0x884C, + TEXTURE_COMPARE_FUNC = 0x884D, + + // Version: 1.5 + BUFFER_SIZE = 0x8764, + BUFFER_USAGE = 0x8765, + QUERY_COUNTER_BITS = 0x8864, + CURRENT_QUERY = 0x8865, + QUERY_RESULT = 0x8866, + QUERY_RESULT_AVAILABLE = 0x8867, + ARRAY_BUFFER = 0x8892, + ELEMENT_ARRAY_BUFFER = 0x8893, + ARRAY_BUFFER_BINDING = 0x8894, + ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, + READ_ONLY = 0x88B8, + WRITE_ONLY = 0x88B9, + READ_WRITE = 0x88BA, + BUFFER_ACCESS = 0x88BB, + BUFFER_MAPPED = 0x88BC, + BUFFER_MAP_POINTER = 0x88BD, + STREAM_DRAW = 0x88E0, + STREAM_READ = 0x88E1, + STREAM_COPY = 0x88E2, + STATIC_DRAW = 0x88E4, + STATIC_READ = 0x88E5, + STATIC_COPY = 0x88E6, + DYNAMIC_DRAW = 0x88E8, + DYNAMIC_READ = 0x88E9, + DYNAMIC_COPY = 0x88EA, + SAMPLES_PASSED = 0x8914, + SRC1_ALPHA = 0x8589, + + // Version: 2.0 + BLEND_EQUATION_RGB = 0x8009, + VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, + VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, + VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, + VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, + CURRENT_VERTEX_ATTRIB = 0x8626, + VERTEX_PROGRAM_POINT_SIZE = 0x8642, + VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, + STENCIL_BACK_FUNC = 0x8800, + STENCIL_BACK_FAIL = 0x8801, + STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, + STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, + MAX_DRAW_BUFFERS = 0x8824, + DRAW_BUFFER0 = 0x8825, + DRAW_BUFFER1 = 0x8826, + DRAW_BUFFER2 = 0x8827, + DRAW_BUFFER3 = 0x8828, + DRAW_BUFFER4 = 0x8829, + DRAW_BUFFER5 = 0x882A, + DRAW_BUFFER6 = 0x882B, + DRAW_BUFFER7 = 0x882C, + DRAW_BUFFER8 = 0x882D, + DRAW_BUFFER9 = 0x882E, + DRAW_BUFFER10 = 0x882F, + DRAW_BUFFER11 = 0x8830, + DRAW_BUFFER12 = 0x8831, + DRAW_BUFFER13 = 0x8832, + DRAW_BUFFER14 = 0x8833, + DRAW_BUFFER15 = 0x8834, + BLEND_EQUATION_ALPHA = 0x883D, + MAX_VERTEX_ATTRIBS = 0x8869, + VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, + MAX_TEXTURE_IMAGE_UNITS = 0x8872, + FRAGMENT_SHADER = 0x8B30, + VERTEX_SHADER = 0x8B31, + MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49, + MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A, + MAX_VARYING_FLOATS = 0x8B4B, + MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, + MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, + SHADER_TYPE = 0x8B4F, + FLOAT_VEC2 = 0x8B50, + FLOAT_VEC3 = 0x8B51, + FLOAT_VEC4 = 0x8B52, + INT_VEC2 = 0x8B53, + INT_VEC3 = 0x8B54, + INT_VEC4 = 0x8B55, + BOOL = 0x8B56, + BOOL_VEC2 = 0x8B57, + BOOL_VEC3 = 0x8B58, + BOOL_VEC4 = 0x8B59, + FLOAT_MAT2 = 0x8B5A, + FLOAT_MAT3 = 0x8B5B, + FLOAT_MAT4 = 0x8B5C, + SAMPLER_1D = 0x8B5D, + SAMPLER_2D = 0x8B5E, + SAMPLER_3D = 0x8B5F, + SAMPLER_CUBE = 0x8B60, + SAMPLER_1D_SHADOW = 0x8B61, + SAMPLER_2D_SHADOW = 0x8B62, + DELETE_STATUS = 0x8B80, + COMPILE_STATUS = 0x8B81, + LINK_STATUS = 0x8B82, + VALIDATE_STATUS = 0x8B83, + INFO_LOG_LENGTH = 0x8B84, + ATTACHED_SHADERS = 0x8B85, + ACTIVE_UNIFORMS = 0x8B86, + ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, + SHADER_SOURCE_LENGTH = 0x8B88, + ACTIVE_ATTRIBUTES = 0x8B89, + ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, + FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B, + SHADING_LANGUAGE_VERSION = 0x8B8C, + CURRENT_PROGRAM = 0x8B8D, + POINT_SPRITE_COORD_ORIGIN = 0x8CA0, + LOWER_LEFT = 0x8CA1, + UPPER_LEFT = 0x8CA2, + STENCIL_BACK_REF = 0x8CA3, + STENCIL_BACK_VALUE_MASK = 0x8CA4, + STENCIL_BACK_WRITEMASK = 0x8CA5, + + // Version: 2.1 + PIXEL_PACK_BUFFER = 0x88EB, + PIXEL_UNPACK_BUFFER = 0x88EC, + PIXEL_PACK_BUFFER_BINDING = 0x88ED, + PIXEL_UNPACK_BUFFER_BINDING = 0x88EF, + FLOAT_MAT2x3 = 0x8B65, + FLOAT_MAT2x4 = 0x8B66, + FLOAT_MAT3x2 = 0x8B67, + FLOAT_MAT3x4 = 0x8B68, + FLOAT_MAT4x2 = 0x8B69, + FLOAT_MAT4x3 = 0x8B6A, + SRGB = 0x8C40, + SRGB8 = 0x8C41, + SRGB_ALPHA = 0x8C42, + SRGB8_ALPHA8 = 0x8C43, + COMPRESSED_SRGB = 0x8C48, + COMPRESSED_SRGB_ALPHA = 0x8C49, + + // Core Extension: ARB_vertex_array_object + VERTEX_ARRAY_BINDING = 0x85B5, + + // Core Extension: ARB_texture_rg + RG = 0x8227, + RG_INTEGER = 0x8228, + R8 = 0x8229, + R16 = 0x822A, + RG8 = 0x822B, + RG16 = 0x822C, + R16F = 0x822D, + R32F = 0x822E, + RG16F = 0x822F, + RG32F = 0x8230, + R8I = 0x8231, + R8UI = 0x8232, + R16I = 0x8233, + R16UI = 0x8234, + R32I = 0x8235, + R32UI = 0x8236, + RG8I = 0x8237, + RG8UI = 0x8238, + RG16I = 0x8239, + RG16UI = 0x823A, + RG32I = 0x823B, + RG32UI = 0x823C, + + // Core Extension: ARB_texture_compression_rgtc + COMPRESSED_RED_RGTC1 = 0x8DBB, + COMPRESSED_SIGNED_RED_RGTC1 = 0x8DBC, + COMPRESSED_RG_RGTC2 = 0x8DBD, + COMPRESSED_SIGNED_RG_RGTC2 = 0x8DBE, + + // Core Extension: ARB_map_buffer_range + MAP_READ_BIT = 0x0001, + MAP_WRITE_BIT = 0x0002, + MAP_INVALIDATE_RANGE_BIT = 0x0004, + MAP_INVALIDATE_BUFFER_BIT = 0x0008, + MAP_FLUSH_EXPLICIT_BIT = 0x0010, + MAP_UNSYNCHRONIZED_BIT = 0x0020, + + // Core Extension: ARB_half_float_vertex + HALF_FLOAT = 0x140B, + + // Core Extension: ARB_framebuffer_sRGB + FRAMEBUFFER_SRGB = 0x8DB9, + + // Core Extension: ARB_framebuffer_object + INVALID_FRAMEBUFFER_OPERATION = 0x0506, + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210, + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211, + FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212, + FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213, + FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214, + FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215, + FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216, + FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217, + FRAMEBUFFER_DEFAULT = 0x8218, + FRAMEBUFFER_UNDEFINED = 0x8219, + DEPTH_STENCIL_ATTACHMENT = 0x821A, + INDEX = 0x8222, + MAX_RENDERBUFFER_SIZE = 0x84E8, + DEPTH_STENCIL = 0x84F9, + UNSIGNED_INT_24_8 = 0x84FA, + DEPTH24_STENCIL8 = 0x88F0, + TEXTURE_STENCIL_SIZE = 0x88F1, + TEXTURE_RED_TYPE = 0x8C10, + TEXTURE_GREEN_TYPE = 0x8C11, + TEXTURE_BLUE_TYPE = 0x8C12, + TEXTURE_ALPHA_TYPE = 0x8C13, + TEXTURE_DEPTH_TYPE = 0x8C16, + UNSIGNED_NORMALIZED = 0x8C17, + FRAMEBUFFER_BINDING = 0x8CA6, + DRAW_FRAMEBUFFER_BINDING = 0x8CA6, + RENDERBUFFER_BINDING = 0x8CA7, + READ_FRAMEBUFFER = 0x8CA8, + DRAW_FRAMEBUFFER = 0x8CA9, + READ_FRAMEBUFFER_BINDING = 0x8CAA, + RENDERBUFFER_SAMPLES = 0x8CAB, + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0, + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2, + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4, + FRAMEBUFFER_COMPLETE = 0x8CD5, + FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6, + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7, + FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0x8CDB, + FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0x8CDC, + FRAMEBUFFER_UNSUPPORTED = 0x8CDD, + MAX_COLOR_ATTACHMENTS = 0x8CDF, + COLOR_ATTACHMENT0 = 0x8CE0, + COLOR_ATTACHMENT1 = 0x8CE1, + COLOR_ATTACHMENT2 = 0x8CE2, + COLOR_ATTACHMENT3 = 0x8CE3, + COLOR_ATTACHMENT4 = 0x8CE4, + COLOR_ATTACHMENT5 = 0x8CE5, + COLOR_ATTACHMENT6 = 0x8CE6, + COLOR_ATTACHMENT7 = 0x8CE7, + COLOR_ATTACHMENT8 = 0x8CE8, + COLOR_ATTACHMENT9 = 0x8CE9, + COLOR_ATTACHMENT10 = 0x8CEA, + COLOR_ATTACHMENT11 = 0x8CEB, + COLOR_ATTACHMENT12 = 0x8CEC, + COLOR_ATTACHMENT13 = 0x8CED, + COLOR_ATTACHMENT14 = 0x8CEE, + COLOR_ATTACHMENT15 = 0x8CEF, + DEPTH_ATTACHMENT = 0x8D00, + STENCIL_ATTACHMENT = 0x8D20, + FRAMEBUFFER = 0x8D40, + RENDERBUFFER = 0x8D41, + RENDERBUFFER_WIDTH = 0x8D42, + RENDERBUFFER_HEIGHT = 0x8D43, + RENDERBUFFER_INTERNAL_FORMAT = 0x8D44, + STENCIL_INDEX1 = 0x8D46, + STENCIL_INDEX4 = 0x8D47, + STENCIL_INDEX8 = 0x8D48, + STENCIL_INDEX16 = 0x8D49, + RENDERBUFFER_RED_SIZE = 0x8D50, + RENDERBUFFER_GREEN_SIZE = 0x8D51, + RENDERBUFFER_BLUE_SIZE = 0x8D52, + RENDERBUFFER_ALPHA_SIZE = 0x8D53, + RENDERBUFFER_DEPTH_SIZE = 0x8D54, + RENDERBUFFER_STENCIL_SIZE = 0x8D55, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56, + MAX_SAMPLES = 0x8D57, + TEXTURE_LUMINANCE_TYPE = 0x8C14, + TEXTURE_INTENSITY_TYPE = 0x8C15, + + // Core Extension: ARB_depth_buffer_float + DEPTH_COMPONENT32F = 0x8CAC, + DEPTH32F_STENCIL8 = 0x8CAD, + FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD, + + // Version: 3.0 + COMPARE_REF_TO_TEXTURE = 0x884E, + CLIP_DISTANCE0 = 0x3000, + CLIP_DISTANCE1 = 0x3001, + CLIP_DISTANCE2 = 0x3002, + CLIP_DISTANCE3 = 0x3003, + CLIP_DISTANCE4 = 0x3004, + CLIP_DISTANCE5 = 0x3005, + CLIP_DISTANCE6 = 0x3006, + CLIP_DISTANCE7 = 0x3007, + MAX_CLIP_DISTANCES = 0x0D32, + MAJOR_VERSION = 0x821B, + MINOR_VERSION = 0x821C, + NUM_EXTENSIONS = 0x821D, + CONTEXT_FLAGS = 0x821E, + COMPRESSED_RED = 0x8225, + COMPRESSED_RG = 0x8226, + CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = 0x0001, + RGBA32F = 0x8814, + RGB32F = 0x8815, + RGBA16F = 0x881A, + RGB16F = 0x881B, + VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD, + MAX_ARRAY_TEXTURE_LAYERS = 0x88FF, + MIN_PROGRAM_TEXEL_OFFSET = 0x8904, + MAX_PROGRAM_TEXEL_OFFSET = 0x8905, + CLAMP_READ_COLOR = 0x891C, + FIXED_ONLY = 0x891D, + TEXTURE_1D_ARRAY = 0x8C18, + PROXY_TEXTURE_1D_ARRAY = 0x8C19, + TEXTURE_2D_ARRAY = 0x8C1A, + PROXY_TEXTURE_2D_ARRAY = 0x8C1B, + TEXTURE_BINDING_1D_ARRAY = 0x8C1C, + TEXTURE_BINDING_2D_ARRAY = 0x8C1D, + R11F_G11F_B10F = 0x8C3A, + UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B, + RGB9_E5 = 0x8C3D, + UNSIGNED_INT_5_9_9_9_REV = 0x8C3E, + TEXTURE_SHARED_SIZE = 0x8C3F, + TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76, + TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F, + MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80, + TRANSFORM_FEEDBACK_VARYINGS = 0x8C83, + TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84, + TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85, + PRIMITIVES_GENERATED = 0x8C87, + TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88, + RASTERIZER_DISCARD = 0x8C89, + MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A, + MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B, + INTERLEAVED_ATTRIBS = 0x8C8C, + SEPARATE_ATTRIBS = 0x8C8D, + TRANSFORM_FEEDBACK_BUFFER = 0x8C8E, + TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F, + RGBA32UI = 0x8D70, + RGB32UI = 0x8D71, + RGBA16UI = 0x8D76, + RGB16UI = 0x8D77, + RGBA8UI = 0x8D7C, + RGB8UI = 0x8D7D, + RGBA32I = 0x8D82, + RGB32I = 0x8D83, + RGBA16I = 0x8D88, + RGB16I = 0x8D89, + RGBA8I = 0x8D8E, + RGB8I = 0x8D8F, + RED_INTEGER = 0x8D94, + GREEN_INTEGER = 0x8D95, + BLUE_INTEGER = 0x8D96, + RGB_INTEGER = 0x8D98, + RGBA_INTEGER = 0x8D99, + BGR_INTEGER = 0x8D9A, + BGRA_INTEGER = 0x8D9B, + SAMPLER_1D_ARRAY = 0x8DC0, + SAMPLER_2D_ARRAY = 0x8DC1, + SAMPLER_1D_ARRAY_SHADOW = 0x8DC3, + SAMPLER_2D_ARRAY_SHADOW = 0x8DC4, + SAMPLER_CUBE_SHADOW = 0x8DC5, + UNSIGNED_INT_VEC2 = 0x8DC6, + UNSIGNED_INT_VEC3 = 0x8DC7, + UNSIGNED_INT_VEC4 = 0x8DC8, + INT_SAMPLER_1D = 0x8DC9, + INT_SAMPLER_2D = 0x8DCA, + INT_SAMPLER_3D = 0x8DCB, + INT_SAMPLER_CUBE = 0x8DCC, + INT_SAMPLER_1D_ARRAY = 0x8DCE, + INT_SAMPLER_2D_ARRAY = 0x8DCF, + UNSIGNED_INT_SAMPLER_1D = 0x8DD1, + UNSIGNED_INT_SAMPLER_2D = 0x8DD2, + UNSIGNED_INT_SAMPLER_3D = 0x8DD3, + UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, + UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, + UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, + QUERY_WAIT = 0x8E13, + QUERY_NO_WAIT = 0x8E14, + QUERY_BY_REGION_WAIT = 0x8E15, + QUERY_BY_REGION_NO_WAIT = 0x8E16, + BUFFER_ACCESS_FLAGS = 0x911F, + BUFFER_MAP_LENGTH = 0x9120, + BUFFER_MAP_OFFSET = 0x9121, + + // Core Extension: ARB_uniform_buffer_object + UNIFORM_BUFFER = 0x8A11, + UNIFORM_BUFFER_BINDING = 0x8A28, + UNIFORM_BUFFER_START = 0x8A29, + UNIFORM_BUFFER_SIZE = 0x8A2A, + MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B, + MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D, + MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E, + MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F, + MAX_UNIFORM_BLOCK_SIZE = 0x8A30, + MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31, + MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33, + UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34, + ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = 0x8A35, + ACTIVE_UNIFORM_BLOCKS = 0x8A36, + UNIFORM_TYPE = 0x8A37, + UNIFORM_SIZE = 0x8A38, + UNIFORM_NAME_LENGTH = 0x8A39, + UNIFORM_BLOCK_INDEX = 0x8A3A, + UNIFORM_OFFSET = 0x8A3B, + UNIFORM_ARRAY_STRIDE = 0x8A3C, + UNIFORM_MATRIX_STRIDE = 0x8A3D, + UNIFORM_IS_ROW_MAJOR = 0x8A3E, + UNIFORM_BLOCK_BINDING = 0x8A3F, + UNIFORM_BLOCK_DATA_SIZE = 0x8A40, + UNIFORM_BLOCK_NAME_LENGTH = 0x8A41, + UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42, + UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43, + UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44, + UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46, + INVALID_INDEX = 0xFFFFFFFF, + MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C, + MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32, + UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45, + + // Core Extension: ARB_copy_buffer + COPY_READ_BUFFER = 0x8F36, + COPY_WRITE_BUFFER = 0x8F37, + COPY_READ_BUFFER_BINDING = 0x8F36, + COPY_WRITE_BUFFER_BINDING = 0x8F37, + + // Version: 3.1 + SAMPLER_2D_RECT = 0x8B63, + SAMPLER_2D_RECT_SHADOW = 0x8B64, + SAMPLER_BUFFER = 0x8DC2, + INT_SAMPLER_2D_RECT = 0x8DCD, + INT_SAMPLER_BUFFER = 0x8DD0, + UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5, + UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, + TEXTURE_BUFFER = 0x8C2A, + MAX_TEXTURE_BUFFER_SIZE = 0x8C2B, + TEXTURE_BINDING_BUFFER = 0x8C2C, + TEXTURE_BUFFER_DATA_STORE_BINDING = 0x8C2D, + TEXTURE_RECTANGLE = 0x84F5, + TEXTURE_BINDING_RECTANGLE = 0x84F6, + PROXY_TEXTURE_RECTANGLE = 0x84F7, + MAX_RECTANGLE_TEXTURE_SIZE = 0x84F8, + RED_SNORM = 0x8F90, + RG_SNORM = 0x8F91, + RGB_SNORM = 0x8F92, + RGBA_SNORM = 0x8F93, + R8_SNORM = 0x8F94, + RG8_SNORM = 0x8F95, + RGB8_SNORM = 0x8F96, + RGBA8_SNORM = 0x8F97, + R16_SNORM = 0x8F98, + RG16_SNORM = 0x8F99, + RGB16_SNORM = 0x8F9A, + RGBA16_SNORM = 0x8F9B, + SIGNED_NORMALIZED = 0x8F9C, + PRIMITIVE_RESTART = 0x8F9D, + PRIMITIVE_RESTART_INDEX = 0x8F9E, + + // Legacy + VERTEX_ARRAY = 0x8074, + NORMAL_ARRAY = 0x8075, + COLOR_ARRAY = 0x8076, + TEXTURE_COORD_ARRAY = 0x8078, + TEXTURE_ENV = 0x2300, + TEXTURE_ENV_MODE = 0x2200, + MODELVIEW = 0x1700, + PROJECTION = 0x1701, + LIGHTING = 0x0B50 + }; + + // Extension: 1.1 + extern void (CODEGEN_FUNCPTR *CullFace)(GLenum mode); + extern void (CODEGEN_FUNCPTR *FrontFace)(GLenum mode); + extern void (CODEGEN_FUNCPTR *Hint)(GLenum target, GLenum mode); + extern void (CODEGEN_FUNCPTR *LineWidth)(GLfloat width); + extern void (CODEGEN_FUNCPTR *PointSize)(GLfloat size); + extern void (CODEGEN_FUNCPTR *PolygonMode)(GLenum face, GLenum mode); + extern void (CODEGEN_FUNCPTR *Scissor)(GLint x, GLint y, GLsizei width, GLsizei height); + extern void (CODEGEN_FUNCPTR *TexParameterf)(GLenum target, GLenum pname, GLfloat param); + extern void (CODEGEN_FUNCPTR *TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params); + extern void (CODEGEN_FUNCPTR *TexParameteri)(GLenum target, GLenum pname, GLint param); + extern void (CODEGEN_FUNCPTR *TexParameteriv)(GLenum target, GLenum pname, const GLint *params); + extern void (CODEGEN_FUNCPTR *TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *DrawBuffer)(GLenum mode); + extern void (CODEGEN_FUNCPTR *Clear)(GLbitfield mask); + extern void (CODEGEN_FUNCPTR *ClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + extern void (CODEGEN_FUNCPTR *ClearStencil)(GLint s); + extern void (CODEGEN_FUNCPTR *ClearDepth)(GLdouble depth); + extern void (CODEGEN_FUNCPTR *StencilMask)(GLuint mask); + extern void (CODEGEN_FUNCPTR *ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + extern void (CODEGEN_FUNCPTR *DepthMask)(GLboolean flag); + extern void (CODEGEN_FUNCPTR *Disable)(GLenum cap); + extern void (CODEGEN_FUNCPTR *Enable)(GLenum cap); + extern void (CODEGEN_FUNCPTR *Finish)(); + extern void (CODEGEN_FUNCPTR *Flush)(); + extern void (CODEGEN_FUNCPTR *BlendFunc)(GLenum sfactor, GLenum dfactor); + extern void (CODEGEN_FUNCPTR *LogicOp)(GLenum opcode); + extern void (CODEGEN_FUNCPTR *StencilFunc)(GLenum func, GLint ref, GLuint mask); + extern void (CODEGEN_FUNCPTR *StencilOp)(GLenum fail, GLenum zfail, GLenum zpass); + extern void (CODEGEN_FUNCPTR *DepthFunc)(GLenum func); + extern void (CODEGEN_FUNCPTR *PixelStoref)(GLenum pname, GLfloat param); + extern void (CODEGEN_FUNCPTR *PixelStorei)(GLenum pname, GLint param); + extern void (CODEGEN_FUNCPTR *ReadBuffer)(GLenum mode); + extern void (CODEGEN_FUNCPTR *ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *GetBooleanv)(GLenum pname, GLboolean *params); + extern void (CODEGEN_FUNCPTR *GetDoublev)(GLenum pname, GLdouble *params); + extern GLenum (CODEGEN_FUNCPTR *GetError)(); + extern void (CODEGEN_FUNCPTR *GetFloatv)(GLenum pname, GLfloat *params); + extern void (CODEGEN_FUNCPTR *GetIntegerv)(GLenum pname, GLint *params); + extern const GLubyte * (CODEGEN_FUNCPTR *GetString)(GLenum name); + extern void (CODEGEN_FUNCPTR *GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params); + extern void (CODEGEN_FUNCPTR *GetTexParameteriv)(GLenum target, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); + extern void (CODEGEN_FUNCPTR *GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + extern GLboolean (CODEGEN_FUNCPTR *IsEnabled)(GLenum cap); + extern void (CODEGEN_FUNCPTR *DepthRange)(GLdouble ren_near, GLdouble ren_far); + extern void (CODEGEN_FUNCPTR *Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); + extern void (CODEGEN_FUNCPTR *DrawArrays)(GLenum mode, GLint first, GLsizei count); + extern void (CODEGEN_FUNCPTR *DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); + extern void (CODEGEN_FUNCPTR *GetPointerv)(GLenum pname, GLvoid* *params); + extern void (CODEGEN_FUNCPTR *PolygonOffset)(GLfloat factor, GLfloat units); + extern void (CODEGEN_FUNCPTR *CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); + extern void (CODEGEN_FUNCPTR *CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + extern void (CODEGEN_FUNCPTR *CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + extern void (CODEGEN_FUNCPTR *CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + extern void (CODEGEN_FUNCPTR *TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *BindTexture)(GLenum target, GLuint texture); + extern void (CODEGEN_FUNCPTR *DeleteTextures)(GLsizei n, const GLuint *textures); + extern void (CODEGEN_FUNCPTR *GenTextures)(GLsizei n, GLuint *textures); + extern GLboolean (CODEGEN_FUNCPTR *IsTexture)(GLuint texture); + extern void (CODEGEN_FUNCPTR *Indexub)(GLubyte c); + extern void (CODEGEN_FUNCPTR *Indexubv)(const GLubyte *c); + + // Extension: 1.2 + extern void (CODEGEN_FUNCPTR *BlendColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + extern void (CODEGEN_FUNCPTR *BlendEquation)(GLenum mode); + extern void (CODEGEN_FUNCPTR *DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + extern void (CODEGEN_FUNCPTR *TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + extern void (CODEGEN_FUNCPTR *CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + // Extension: 1.3 + extern void (CODEGEN_FUNCPTR *ActiveTexture)(GLenum texture); + extern void (CODEGEN_FUNCPTR *SampleCoverage)(GLfloat value, GLboolean invert); + extern void (CODEGEN_FUNCPTR *CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *CompressedTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img); + + // Extension: 1.4 + extern void (CODEGEN_FUNCPTR *BlendFuncSeparate)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + extern void (CODEGEN_FUNCPTR *MultiDrawArrays)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); + extern void (CODEGEN_FUNCPTR *MultiDrawElements)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); + extern void (CODEGEN_FUNCPTR *PointParameterf)(GLenum pname, GLfloat param); + extern void (CODEGEN_FUNCPTR *PointParameterfv)(GLenum pname, const GLfloat *params); + extern void (CODEGEN_FUNCPTR *PointParameteri)(GLenum pname, GLint param); + extern void (CODEGEN_FUNCPTR *PointParameteriv)(GLenum pname, const GLint *params); + + // Extension: 1.5 + extern void (CODEGEN_FUNCPTR *GenQueries)(GLsizei n, GLuint *ids); + extern void (CODEGEN_FUNCPTR *DeleteQueries)(GLsizei n, const GLuint *ids); + extern GLboolean (CODEGEN_FUNCPTR *IsQuery)(GLuint id); + extern void (CODEGEN_FUNCPTR *BeginQuery)(GLenum target, GLuint id); + extern void (CODEGEN_FUNCPTR *EndQuery)(GLenum target); + extern void (CODEGEN_FUNCPTR *GetQueryiv)(GLenum target, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetQueryObjectiv)(GLuint id, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); + extern void (CODEGEN_FUNCPTR *BindBuffer)(GLenum target, GLuint buffer); + extern void (CODEGEN_FUNCPTR *DeleteBuffers)(GLsizei n, const GLuint *buffers); + extern void (CODEGEN_FUNCPTR *GenBuffers)(GLsizei n, GLuint *buffers); + extern GLboolean (CODEGEN_FUNCPTR *IsBuffer)(GLuint buffer); + extern void (CODEGEN_FUNCPTR *BufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); + extern void (CODEGEN_FUNCPTR *BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); + extern void (CODEGEN_FUNCPTR *GetBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); + extern GLvoid* (CODEGEN_FUNCPTR *MapBuffer)(GLenum target, GLenum access); + extern GLboolean (CODEGEN_FUNCPTR *UnmapBuffer)(GLenum target); + extern void (CODEGEN_FUNCPTR *GetBufferParameteriv)(GLenum target, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetBufferPointerv)(GLenum target, GLenum pname, GLvoid* *params); + + // Extension: 2.0 + extern void (CODEGEN_FUNCPTR *BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha); + extern void (CODEGEN_FUNCPTR *DrawBuffers)(GLsizei n, const GLenum *bufs); + extern void (CODEGEN_FUNCPTR *StencilOpSeparate)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + extern void (CODEGEN_FUNCPTR *StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask); + extern void (CODEGEN_FUNCPTR *StencilMaskSeparate)(GLenum face, GLuint mask); + extern void (CODEGEN_FUNCPTR *AttachShader)(GLuint program, GLuint shader); + extern void (CODEGEN_FUNCPTR *BindAttribLocation)(GLuint program, GLuint index, const GLchar *name); + extern void (CODEGEN_FUNCPTR *CompileShader)(GLuint shader); + extern GLuint (CODEGEN_FUNCPTR *CreateProgram)(); + extern GLuint (CODEGEN_FUNCPTR *CreateShader)(GLenum type); + extern void (CODEGEN_FUNCPTR *DeleteProgram)(GLuint program); + extern void (CODEGEN_FUNCPTR *DeleteShader)(GLuint shader); + extern void (CODEGEN_FUNCPTR *DetachShader)(GLuint program, GLuint shader); + extern void (CODEGEN_FUNCPTR *DisableVertexAttribArray)(GLuint index); + extern void (CODEGEN_FUNCPTR *EnableVertexAttribArray)(GLuint index); + extern void (CODEGEN_FUNCPTR *GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + extern void (CODEGEN_FUNCPTR *GetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + extern void (CODEGEN_FUNCPTR *GetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); + extern GLint (CODEGEN_FUNCPTR *GetAttribLocation)(GLuint program, const GLchar *name); + extern void (CODEGEN_FUNCPTR *GetProgramiv)(GLuint program, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + extern void (CODEGEN_FUNCPTR *GetShaderiv)(GLuint shader, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + extern void (CODEGEN_FUNCPTR *GetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); + extern GLint (CODEGEN_FUNCPTR *GetUniformLocation)(GLuint program, const GLchar *name); + extern void (CODEGEN_FUNCPTR *GetUniformfv)(GLuint program, GLint location, GLfloat *params); + extern void (CODEGEN_FUNCPTR *GetUniformiv)(GLuint program, GLint location, GLint *params); + extern void (CODEGEN_FUNCPTR *GetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); + extern void (CODEGEN_FUNCPTR *GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params); + extern void (CODEGEN_FUNCPTR *GetVertexAttribiv)(GLuint index, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid* *pointer); + extern GLboolean (CODEGEN_FUNCPTR *IsProgram)(GLuint program); + extern GLboolean (CODEGEN_FUNCPTR *IsShader)(GLuint shader); + extern void (CODEGEN_FUNCPTR *LinkProgram)(GLuint program); + extern void (CODEGEN_FUNCPTR *ShaderSource)(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); + extern void (CODEGEN_FUNCPTR *UseProgram)(GLuint program); + extern void (CODEGEN_FUNCPTR *Uniform1f)(GLint location, GLfloat v0); + extern void (CODEGEN_FUNCPTR *Uniform2f)(GLint location, GLfloat v0, GLfloat v1); + extern void (CODEGEN_FUNCPTR *Uniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + extern void (CODEGEN_FUNCPTR *Uniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + extern void (CODEGEN_FUNCPTR *Uniform1i)(GLint location, GLint v0); + extern void (CODEGEN_FUNCPTR *Uniform2i)(GLint location, GLint v0, GLint v1); + extern void (CODEGEN_FUNCPTR *Uniform3i)(GLint location, GLint v0, GLint v1, GLint v2); + extern void (CODEGEN_FUNCPTR *Uniform4i)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + extern void (CODEGEN_FUNCPTR *Uniform1fv)(GLint location, GLsizei count, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *Uniform2fv)(GLint location, GLsizei count, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *Uniform3fv)(GLint location, GLsizei count, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *Uniform4fv)(GLint location, GLsizei count, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *Uniform1iv)(GLint location, GLsizei count, const GLint *value); + extern void (CODEGEN_FUNCPTR *Uniform2iv)(GLint location, GLsizei count, const GLint *value); + extern void (CODEGEN_FUNCPTR *Uniform3iv)(GLint location, GLsizei count, const GLint *value); + extern void (CODEGEN_FUNCPTR *Uniform4iv)(GLint location, GLsizei count, const GLint *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *ValidateProgram)(GLuint program); + extern void (CODEGEN_FUNCPTR *VertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); + + // Extension: 2.1 + extern void (CODEGEN_FUNCPTR *UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + + // Extension: ARB_vertex_array_object + extern void (CODEGEN_FUNCPTR *BindVertexArray)(GLuint ren_array); + extern void (CODEGEN_FUNCPTR *DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + extern void (CODEGEN_FUNCPTR *GenVertexArrays)(GLsizei n, GLuint *arrays); + extern GLboolean (CODEGEN_FUNCPTR *IsVertexArray)(GLuint ren_array); + + // Extension: ARB_map_buffer_range + extern GLvoid* (CODEGEN_FUNCPTR *MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + extern void (CODEGEN_FUNCPTR *FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); + + // Extension: ARB_framebuffer_object + extern GLboolean (CODEGEN_FUNCPTR *IsRenderbuffer)(GLuint renderbuffer); + extern void (CODEGEN_FUNCPTR *BindRenderbuffer)(GLenum target, GLuint renderbuffer); + extern void (CODEGEN_FUNCPTR *DeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers); + extern void (CODEGEN_FUNCPTR *GenRenderbuffers)(GLsizei n, GLuint *renderbuffers); + extern void (CODEGEN_FUNCPTR *RenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + extern void (CODEGEN_FUNCPTR *GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params); + extern GLboolean (CODEGEN_FUNCPTR *IsFramebuffer)(GLuint framebuffer); + extern void (CODEGEN_FUNCPTR *BindFramebuffer)(GLenum target, GLuint framebuffer); + extern void (CODEGEN_FUNCPTR *DeleteFramebuffers)(GLsizei n, const GLuint *framebuffers); + extern void (CODEGEN_FUNCPTR *GenFramebuffers)(GLsizei n, GLuint *framebuffers); + extern GLenum (CODEGEN_FUNCPTR *CheckFramebufferStatus)(GLenum target); + extern void (CODEGEN_FUNCPTR *FramebufferTexture1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + extern void (CODEGEN_FUNCPTR *FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + extern void (CODEGEN_FUNCPTR *FramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + extern void (CODEGEN_FUNCPTR *FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + extern void (CODEGEN_FUNCPTR *GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GenerateMipmap)(GLenum target); + extern void (CODEGEN_FUNCPTR *BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + extern void (CODEGEN_FUNCPTR *RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + extern void (CODEGEN_FUNCPTR *FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + + // Extension: 3.0 + extern void (CODEGEN_FUNCPTR *ColorMaski)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + extern void (CODEGEN_FUNCPTR *GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + extern void (CODEGEN_FUNCPTR *GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + extern void (CODEGEN_FUNCPTR *Enablei)(GLenum target, GLuint index); + extern void (CODEGEN_FUNCPTR *Disablei)(GLenum target, GLuint index); + extern GLboolean (CODEGEN_FUNCPTR *IsEnabledi)(GLenum target, GLuint index); + extern void (CODEGEN_FUNCPTR *BeginTransformFeedback)(GLenum primitiveMode); + extern void (CODEGEN_FUNCPTR *EndTransformFeedback)(); + extern void (CODEGEN_FUNCPTR *BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + extern void (CODEGEN_FUNCPTR *BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + extern void (CODEGEN_FUNCPTR *TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); + extern void (CODEGEN_FUNCPTR *GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + extern void (CODEGEN_FUNCPTR *ClampColor)(GLenum target, GLenum clamp); + extern void (CODEGEN_FUNCPTR *BeginConditionalRender)(GLuint id, GLenum mode); + extern void (CODEGEN_FUNCPTR *EndConditionalRender)(); + extern void (CODEGEN_FUNCPTR *VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + extern void (CODEGEN_FUNCPTR *GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + extern void (CODEGEN_FUNCPTR *VertexAttribI1i)(GLuint index, GLint x); + extern void (CODEGEN_FUNCPTR *VertexAttribI2i)(GLuint index, GLint x, GLint y); + extern void (CODEGEN_FUNCPTR *VertexAttribI3i)(GLuint index, GLint x, GLint y, GLint z); + extern void (CODEGEN_FUNCPTR *VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + extern void (CODEGEN_FUNCPTR *VertexAttribI1ui)(GLuint index, GLuint x); + extern void (CODEGEN_FUNCPTR *VertexAttribI2ui)(GLuint index, GLuint x, GLuint y); + extern void (CODEGEN_FUNCPTR *VertexAttribI3ui)(GLuint index, GLuint x, GLuint y, GLuint z); + extern void (CODEGEN_FUNCPTR *VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + extern void (CODEGEN_FUNCPTR *VertexAttribI1iv)(GLuint index, const GLint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI2iv)(GLuint index, const GLint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI3iv)(GLuint index, const GLint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4iv)(GLuint index, const GLint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI1uiv)(GLuint index, const GLuint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI2uiv)(GLuint index, const GLuint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI3uiv)(GLuint index, const GLuint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4uiv)(GLuint index, const GLuint *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4bv)(GLuint index, const GLbyte *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4sv)(GLuint index, const GLshort *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4ubv)(GLuint index, const GLubyte *v); + extern void (CODEGEN_FUNCPTR *VertexAttribI4usv)(GLuint index, const GLushort *v); + extern void (CODEGEN_FUNCPTR *GetUniformuiv)(GLuint program, GLint location, GLuint *params); + extern void (CODEGEN_FUNCPTR *BindFragDataLocation)(GLuint program, GLuint color, const GLchar *name); + extern GLint (CODEGEN_FUNCPTR *GetFragDataLocation)(GLuint program, const GLchar *name); + extern void (CODEGEN_FUNCPTR *Uniform1ui)(GLint location, GLuint v0); + extern void (CODEGEN_FUNCPTR *Uniform2ui)(GLint location, GLuint v0, GLuint v1); + extern void (CODEGEN_FUNCPTR *Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + extern void (CODEGEN_FUNCPTR *Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + extern void (CODEGEN_FUNCPTR *Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + extern void (CODEGEN_FUNCPTR *Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + extern void (CODEGEN_FUNCPTR *Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + extern void (CODEGEN_FUNCPTR *Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + extern void (CODEGEN_FUNCPTR *TexParameterIiv)(GLenum target, GLenum pname, const GLint *params); + extern void (CODEGEN_FUNCPTR *TexParameterIuiv)(GLenum target, GLenum pname, const GLuint *params); + extern void (CODEGEN_FUNCPTR *GetTexParameterIiv)(GLenum target, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetTexParameterIuiv)(GLenum target, GLenum pname, GLuint *params); + extern void (CODEGEN_FUNCPTR *ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + extern void (CODEGEN_FUNCPTR *ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + extern void (CODEGEN_FUNCPTR *ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + extern void (CODEGEN_FUNCPTR *ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + extern const GLubyte * (CODEGEN_FUNCPTR *GetStringi)(GLenum name, GLuint index); + + // Extension: ARB_uniform_buffer_object + extern void (CODEGEN_FUNCPTR *GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); + extern void (CODEGEN_FUNCPTR *GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetActiveUniformName)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); + extern GLuint (CODEGEN_FUNCPTR *GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + extern void (CODEGEN_FUNCPTR *GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + extern void (CODEGEN_FUNCPTR *GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + extern void (CODEGEN_FUNCPTR *UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + + // Extension: ARB_copy_buffer + extern void (CODEGEN_FUNCPTR *CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + + // Extension: 3.1 + extern void (CODEGEN_FUNCPTR *DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + extern void (CODEGEN_FUNCPTR *DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); + extern void (CODEGEN_FUNCPTR *TexBuffer)(GLenum target, GLenum internalformat, GLuint buffer); + extern void (CODEGEN_FUNCPTR *PrimitiveRestartIndex)(GLuint index); + + // Legacy + extern void (CODEGEN_FUNCPTR *EnableClientState)(GLenum cap); + extern void (CODEGEN_FUNCPTR *DisableClientState)(GLenum cap); + extern void (CODEGEN_FUNCPTR *VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); + extern void (CODEGEN_FUNCPTR *NormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr); + extern void (CODEGEN_FUNCPTR *ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); + extern void (CODEGEN_FUNCPTR *TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); + extern void (CODEGEN_FUNCPTR *TexEnvi)(GLenum target, GLenum pname, GLint param); + extern void (CODEGEN_FUNCPTR *MatrixMode)(GLenum mode); + extern void (CODEGEN_FUNCPTR *LoadIdentity)(void); + extern void (CODEGEN_FUNCPTR *Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val); + extern void (CODEGEN_FUNCPTR *Color3d)(GLdouble red, GLdouble green, GLdouble blue); +} + +#endif // OPENGL_NOLOAD_STYLE_HPP diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/gpumat.cpp diffimg-2.0.0/3rdparty/opencv/core/src/gpumat.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/gpumat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/gpumat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1587 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "opencv2/core/gpumat.hpp" +#include + +#ifdef HAVE_CUDA + #include + #include + + #define CUDART_MINIMUM_REQUIRED_VERSION 4020 + #define NPP_MINIMUM_REQUIRED_VERSION 4200 + + #if (CUDART_VERSION < CUDART_MINIMUM_REQUIRED_VERSION) + #error "Insufficient Cuda Runtime library version, please update it." + #endif + + #if (NPP_VERSION_MAJOR * 1000 + NPP_VERSION_MINOR * 100 + NPP_VERSION_BUILD < NPP_MINIMUM_REQUIRED_VERSION) + #error "Insufficient NPP version, please update it." + #endif +#endif + +using namespace std; +using namespace cv; +using namespace cv::gpu; + +#ifndef HAVE_CUDA + +#define throw_nogpu CV_Error(CV_GpuNotSupported, "The library is compiled without CUDA support") + +#else // HAVE_CUDA + +namespace +{ +#if defined(__GNUC__) + #define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, __func__) + #define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__, __func__) +#else /* defined(__CUDACC__) || defined(__MSVC__) */ + #define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__) + #define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__) +#endif + + inline void ___cudaSafeCall(cudaError_t err, const char *file, const int line, const char *func = "") + { + if (cudaSuccess != err) + cv::gpu::error(cudaGetErrorString(err), file, line, func); + } + + inline void ___nppSafeCall(int err, const char *file, const int line, const char *func = "") + { + if (err < 0) + { + std::ostringstream msg; + msg << "NPP API Call Error: " << err; + cv::gpu::error(msg.str().c_str(), file, line, func); + } + } +} + +#endif // HAVE_CUDA + +//////////////////////////////// Initialization & Info //////////////////////// + +#ifndef HAVE_CUDA + +int cv::gpu::getCudaEnabledDeviceCount() { return 0; } + +void cv::gpu::setDevice(int) { throw_nogpu; } +int cv::gpu::getDevice() { throw_nogpu; return 0; } + +void cv::gpu::resetDevice() { throw_nogpu; } + +bool cv::gpu::deviceSupports(FeatureSet) { throw_nogpu; return false; } + +bool cv::gpu::TargetArchs::builtWith(FeatureSet) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::has(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasPtx(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasBin(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasEqualOrGreater(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int, int) { throw_nogpu; return false; } +bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int, int) { throw_nogpu; return false; } + +size_t cv::gpu::DeviceInfo::sharedMemPerBlock() const { throw_nogpu; return 0; } +void cv::gpu::DeviceInfo::queryMemory(size_t&, size_t&) const { throw_nogpu; } +size_t cv::gpu::DeviceInfo::freeMemory() const { throw_nogpu; return 0; } +size_t cv::gpu::DeviceInfo::totalMemory() const { throw_nogpu; return 0; } +bool cv::gpu::DeviceInfo::supports(FeatureSet) const { throw_nogpu; return false; } +bool cv::gpu::DeviceInfo::isCompatible() const { throw_nogpu; return false; } +void cv::gpu::DeviceInfo::query() { throw_nogpu; } + +void cv::gpu::printCudaDeviceInfo(int) { throw_nogpu; } +void cv::gpu::printShortCudaDeviceInfo(int) { throw_nogpu; } + +#else // HAVE_CUDA + +int cv::gpu::getCudaEnabledDeviceCount() +{ + int count; + cudaError_t error = cudaGetDeviceCount( &count ); + + if (error == cudaErrorInsufficientDriver) + return -1; + + if (error == cudaErrorNoDevice) + return 0; + + cudaSafeCall( error ); + return count; +} + +void cv::gpu::setDevice(int device) +{ + cudaSafeCall( cudaSetDevice( device ) ); +} + +int cv::gpu::getDevice() +{ + int device; + cudaSafeCall( cudaGetDevice( &device ) ); + return device; +} + +void cv::gpu::resetDevice() +{ + cudaSafeCall( cudaDeviceReset() ); +} + +namespace +{ + class CudaArch + { + public: + CudaArch(); + + bool builtWith(FeatureSet feature_set) const; + bool hasPtx(int major, int minor) const; + bool hasBin(int major, int minor) const; + bool hasEqualOrLessPtx(int major, int minor) const; + bool hasEqualOrGreaterPtx(int major, int minor) const; + bool hasEqualOrGreaterBin(int major, int minor) const; + + private: + static void fromStr(const string& set_as_str, vector& arr); + + vector bin; + vector ptx; + vector features; + }; + + const CudaArch cudaArch; + + CudaArch::CudaArch() + { + fromStr(CUDA_ARCH_BIN, bin); + fromStr(CUDA_ARCH_PTX, ptx); + fromStr(CUDA_ARCH_FEATURES, features); + } + + bool CudaArch::builtWith(FeatureSet feature_set) const + { + return !features.empty() && (features.back() >= feature_set); + } + + bool CudaArch::hasPtx(int major, int minor) const + { + return find(ptx.begin(), ptx.end(), major * 10 + minor) != ptx.end(); + } + + bool CudaArch::hasBin(int major, int minor) const + { + return find(bin.begin(), bin.end(), major * 10 + minor) != bin.end(); + } + + bool CudaArch::hasEqualOrLessPtx(int major, int minor) const + { + return !ptx.empty() && (ptx.front() <= major * 10 + minor); + } + + bool CudaArch::hasEqualOrGreaterPtx(int major, int minor) const + { + return !ptx.empty() && (ptx.back() >= major * 10 + minor); + } + + bool CudaArch::hasEqualOrGreaterBin(int major, int minor) const + { + return !bin.empty() && (bin.back() >= major * 10 + minor); + } + + void CudaArch::fromStr(const string& set_as_str, vector& arr) + { + if (set_as_str.find_first_not_of(" ") == string::npos) + return; + + istringstream stream(set_as_str); + int cur_value; + + while (!stream.eof()) + { + stream >> cur_value; + arr.push_back(cur_value); + } + + sort(arr.begin(), arr.end()); + } +} + +bool cv::gpu::TargetArchs::builtWith(cv::gpu::FeatureSet feature_set) +{ + return cudaArch.builtWith(feature_set); +} + +bool cv::gpu::TargetArchs::has(int major, int minor) +{ + return hasPtx(major, minor) || hasBin(major, minor); +} + +bool cv::gpu::TargetArchs::hasPtx(int major, int minor) +{ + return cudaArch.hasPtx(major, minor); +} + +bool cv::gpu::TargetArchs::hasBin(int major, int minor) +{ + return cudaArch.hasBin(major, minor); +} + +bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int major, int minor) +{ + return cudaArch.hasEqualOrLessPtx(major, minor); +} + +bool cv::gpu::TargetArchs::hasEqualOrGreater(int major, int minor) +{ + return hasEqualOrGreaterPtx(major, minor) || hasEqualOrGreaterBin(major, minor); +} + +bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int major, int minor) +{ + return cudaArch.hasEqualOrGreaterPtx(major, minor); +} + +bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int major, int minor) +{ + return cudaArch.hasEqualOrGreaterBin(major, minor); +} + +bool cv::gpu::deviceSupports(FeatureSet feature_set) +{ + static int versions[] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + static const int cache_size = static_cast(sizeof(versions) / sizeof(versions[0])); + + const int devId = getDevice(); + + int version; + + if (devId < cache_size && versions[devId] >= 0) + version = versions[devId]; + else + { + DeviceInfo dev(devId); + version = dev.majorVersion() * 10 + dev.minorVersion(); + if (devId < cache_size) + versions[devId] = version; + } + + return TargetArchs::builtWith(feature_set) && (version >= feature_set); +} + +namespace +{ + class DeviceProps + { + public: + DeviceProps(); + ~DeviceProps(); + + cudaDeviceProp* get(int devID); + + private: + std::vector props_; + }; + + DeviceProps::DeviceProps() + { + props_.resize(10, 0); + } + + DeviceProps::~DeviceProps() + { + for (size_t i = 0; i < props_.size(); ++i) + { + if (props_[i]) + delete props_[i]; + } + props_.clear(); + } + + cudaDeviceProp* DeviceProps::get(int devID) + { + if (devID >= (int) props_.size()) + props_.resize(devID + 5, 0); + + if (!props_[devID]) + { + props_[devID] = new cudaDeviceProp; + cudaSafeCall( cudaGetDeviceProperties(props_[devID], devID) ); + } + + return props_[devID]; + } + + DeviceProps deviceProps; +} + +size_t cv::gpu::DeviceInfo::sharedMemPerBlock() const +{ + return deviceProps.get(device_id_)->sharedMemPerBlock; +} + +void cv::gpu::DeviceInfo::queryMemory(size_t& _totalMemory, size_t& _freeMemory) const +{ + int prevDeviceID = getDevice(); + if (prevDeviceID != device_id_) + setDevice(device_id_); + + cudaSafeCall( cudaMemGetInfo(&_freeMemory, &_totalMemory) ); + + if (prevDeviceID != device_id_) + setDevice(prevDeviceID); +} + +size_t cv::gpu::DeviceInfo::freeMemory() const +{ + size_t _totalMemory, _freeMemory; + queryMemory(_totalMemory, _freeMemory); + return _freeMemory; +} + +size_t cv::gpu::DeviceInfo::totalMemory() const +{ + size_t _totalMemory, _freeMemory; + queryMemory(_totalMemory, _freeMemory); + return _totalMemory; +} + +bool cv::gpu::DeviceInfo::supports(FeatureSet feature_set) const +{ + int version = majorVersion() * 10 + minorVersion(); + return version >= feature_set; +} + +bool cv::gpu::DeviceInfo::isCompatible() const +{ + // Check PTX compatibility + if (TargetArchs::hasEqualOrLessPtx(majorVersion(), minorVersion())) + return true; + + // Check BIN compatibility + for (int i = minorVersion(); i >= 0; --i) + if (TargetArchs::hasBin(majorVersion(), i)) + return true; + + return false; +} + +void cv::gpu::DeviceInfo::query() +{ + const cudaDeviceProp* prop = deviceProps.get(device_id_); + + name_ = prop->name; + multi_processor_count_ = prop->multiProcessorCount; + majorVersion_ = prop->major; + minorVersion_ = prop->minor; +} + +namespace +{ + int convertSMVer2Cores(int major, int minor) + { + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } SMtoCores; + + SMtoCores gpuArchCoresPerSM[] = { { 0x10, 8 }, { 0x11, 8 }, { 0x12, 8 }, { 0x13, 8 }, { 0x20, 32 }, { 0x21, 48 }, {0x30, 192}, {0x35, 192}, { -1, -1 } }; + + int index = 0; + while (gpuArchCoresPerSM[index].SM != -1) + { + if (gpuArchCoresPerSM[index].SM == ((major << 4) + minor) ) + return gpuArchCoresPerSM[index].Cores; + index++; + } + + return -1; + } +} + +void cv::gpu::printCudaDeviceInfo(int device) +{ + int count = getCudaEnabledDeviceCount(); + bool valid = (device >= 0) && (device < count); + + int beg = valid ? device : 0; + int end = valid ? device+1 : count; + + printf("*** CUDA Device Query (Runtime API) version (CUDART static linking) *** \n\n"); + printf("Device count: %d\n", count); + + int driverVersion = 0, runtimeVersion = 0; + cudaSafeCall( cudaDriverGetVersion(&driverVersion) ); + cudaSafeCall( cudaRuntimeGetVersion(&runtimeVersion) ); + + const char *computeMode[] = { + "Default (multiple host threads can use ::cudaSetDevice() with device simultaneously)", + "Exclusive (only one host thread in one process is able to use ::cudaSetDevice() with this device)", + "Prohibited (no host thread can use ::cudaSetDevice() with this device)", + "Exclusive Process (many threads in one process is able to use ::cudaSetDevice() with this device)", + "Unknown", + NULL + }; + + for(int dev = beg; dev < end; ++dev) + { + cudaDeviceProp prop; + cudaSafeCall( cudaGetDeviceProperties(&prop, dev) ); + + printf("\nDevice %d: \"%s\"\n", dev, prop.name); + printf(" CUDA Driver Version / Runtime Version %d.%d / %d.%d\n", driverVersion/1000, driverVersion%100, runtimeVersion/1000, runtimeVersion%100); + printf(" CUDA Capability Major/Minor version number: %d.%d\n", prop.major, prop.minor); + printf(" Total amount of global memory: %.0f MBytes (%llu bytes)\n", (float)prop.totalGlobalMem/1048576.0f, (unsigned long long) prop.totalGlobalMem); + + int cores = convertSMVer2Cores(prop.major, prop.minor); + if (cores > 0) + printf(" (%2d) Multiprocessors x (%2d) CUDA Cores/MP: %d CUDA Cores\n", prop.multiProcessorCount, cores, cores * prop.multiProcessorCount); + + printf(" GPU Clock Speed: %.2f GHz\n", prop.clockRate * 1e-6f); + + printf(" Max Texture Dimension Size (x,y,z) 1D=(%d), 2D=(%d,%d), 3D=(%d,%d,%d)\n", + prop.maxTexture1D, prop.maxTexture2D[0], prop.maxTexture2D[1], + prop.maxTexture3D[0], prop.maxTexture3D[1], prop.maxTexture3D[2]); + printf(" Max Layered Texture Size (dim) x layers 1D=(%d) x %d, 2D=(%d,%d) x %d\n", + prop.maxTexture1DLayered[0], prop.maxTexture1DLayered[1], + prop.maxTexture2DLayered[0], prop.maxTexture2DLayered[1], prop.maxTexture2DLayered[2]); + + printf(" Total amount of constant memory: %u bytes\n", (int)prop.totalConstMem); + printf(" Total amount of shared memory per block: %u bytes\n", (int)prop.sharedMemPerBlock); + printf(" Total number of registers available per block: %d\n", prop.regsPerBlock); + printf(" Warp size: %d\n", prop.warpSize); + printf(" Maximum number of threads per block: %d\n", prop.maxThreadsPerBlock); + printf(" Maximum sizes of each dimension of a block: %d x %d x %d\n", prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]); + printf(" Maximum sizes of each dimension of a grid: %d x %d x %d\n", prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]); + printf(" Maximum memory pitch: %u bytes\n", (int)prop.memPitch); + printf(" Texture alignment: %u bytes\n", (int)prop.textureAlignment); + + printf(" Concurrent copy and execution: %s with %d copy engine(s)\n", (prop.deviceOverlap ? "Yes" : "No"), prop.asyncEngineCount); + printf(" Run time limit on kernels: %s\n", prop.kernelExecTimeoutEnabled ? "Yes" : "No"); + printf(" Integrated GPU sharing Host Memory: %s\n", prop.integrated ? "Yes" : "No"); + printf(" Support host page-locked memory mapping: %s\n", prop.canMapHostMemory ? "Yes" : "No"); + + printf(" Concurrent kernel execution: %s\n", prop.concurrentKernels ? "Yes" : "No"); + printf(" Alignment requirement for Surfaces: %s\n", prop.surfaceAlignment ? "Yes" : "No"); + printf(" Device has ECC support enabled: %s\n", prop.ECCEnabled ? "Yes" : "No"); + printf(" Device is using TCC driver mode: %s\n", prop.tccDriver ? "Yes" : "No"); + printf(" Device supports Unified Addressing (UVA): %s\n", prop.unifiedAddressing ? "Yes" : "No"); + printf(" Device PCI Bus ID / PCI location ID: %d / %d\n", prop.pciBusID, prop.pciDeviceID ); + printf(" Compute Mode:\n"); + printf(" %s \n", computeMode[prop.computeMode]); + } + + printf("\n"); + printf("deviceQuery, CUDA Driver = CUDART"); + printf(", CUDA Driver Version = %d.%d", driverVersion / 1000, driverVersion % 100); + printf(", CUDA Runtime Version = %d.%d", runtimeVersion/1000, runtimeVersion%100); + printf(", NumDevs = %d\n\n", count); + fflush(stdout); +} + +void cv::gpu::printShortCudaDeviceInfo(int device) +{ + int count = getCudaEnabledDeviceCount(); + bool valid = (device >= 0) && (device < count); + + int beg = valid ? device : 0; + int end = valid ? device+1 : count; + + int driverVersion = 0, runtimeVersion = 0; + cudaSafeCall( cudaDriverGetVersion(&driverVersion) ); + cudaSafeCall( cudaRuntimeGetVersion(&runtimeVersion) ); + + for(int dev = beg; dev < end; ++dev) + { + cudaDeviceProp prop; + cudaSafeCall( cudaGetDeviceProperties(&prop, dev) ); + + const char *arch_str = prop.major < 2 ? " (not Fermi)" : ""; + printf("Device %d: \"%s\" %.0fMb", dev, prop.name, (float)prop.totalGlobalMem/1048576.0f); + printf(", sm_%d%d%s", prop.major, prop.minor, arch_str); + + int cores = convertSMVer2Cores(prop.major, prop.minor); + if (cores > 0) + printf(", %d cores", cores * prop.multiProcessorCount); + + printf(", Driver/Runtime ver.%d.%d/%d.%d\n", driverVersion/1000, driverVersion%100, runtimeVersion/1000, runtimeVersion%100); + } + fflush(stdout); +} + +#endif // HAVE_CUDA + +//////////////////////////////// GpuMat /////////////////////////////// + +cv::gpu::GpuMat::GpuMat(const GpuMat& m) + : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend) +{ + if (refcount) + CV_XADD(refcount, 1); +} + +cv::gpu::GpuMat::GpuMat(int rows_, int cols_, int type_, void* data_, size_t step_) : + flags(Mat::MAGIC_VAL + (type_ & TYPE_MASK)), rows(rows_), cols(cols_), + step(step_), data((uchar*)data_), refcount(0), + datastart((uchar*)data_), dataend((uchar*)data_) +{ + size_t minstep = cols * elemSize(); + + if (step == Mat::AUTO_STEP) + { + step = minstep; + flags |= Mat::CONTINUOUS_FLAG; + } + else + { + if (rows == 1) + step = minstep; + + CV_DbgAssert(step >= minstep); + + flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0; + } + dataend += step * (rows - 1) + minstep; +} + +cv::gpu::GpuMat::GpuMat(Size size_, int type_, void* data_, size_t step_) : + flags(Mat::MAGIC_VAL + (type_ & TYPE_MASK)), rows(size_.height), cols(size_.width), + step(step_), data((uchar*)data_), refcount(0), + datastart((uchar*)data_), dataend((uchar*)data_) +{ + size_t minstep = cols * elemSize(); + + if (step == Mat::AUTO_STEP) + { + step = minstep; + flags |= Mat::CONTINUOUS_FLAG; + } + else + { + if (rows == 1) + step = minstep; + + CV_DbgAssert(step >= minstep); + + flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0; + } + dataend += step * (rows - 1) + minstep; +} + +cv::gpu::GpuMat::GpuMat(const GpuMat& m, Range _rowRange, Range _colRange) +{ + flags = m.flags; + step = m.step; refcount = m.refcount; + data = m.data; datastart = m.datastart; dataend = m.dataend; + + if (_rowRange == Range::all()) + rows = m.rows; + else + { + CV_Assert(0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows); + + rows = _rowRange.size(); + data += step*_rowRange.start; + } + + if (_colRange == Range::all()) + cols = m.cols; + else + { + CV_Assert(0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols); + + cols = _colRange.size(); + data += _colRange.start*elemSize(); + flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1; + } + + if (rows == 1) + flags |= Mat::CONTINUOUS_FLAG; + + if (refcount) + CV_XADD(refcount, 1); + + if (rows <= 0 || cols <= 0) + rows = cols = 0; +} + +cv::gpu::GpuMat::GpuMat(const GpuMat& m, Rect roi) : + flags(m.flags), rows(roi.height), cols(roi.width), + step(m.step), data(m.data + roi.y*step), refcount(m.refcount), + datastart(m.datastart), dataend(m.dataend) +{ + flags &= roi.width < m.cols ? ~Mat::CONTINUOUS_FLAG : -1; + data += roi.x * elemSize(); + + CV_Assert(0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows); + + if (refcount) + CV_XADD(refcount, 1); + + if (rows <= 0 || cols <= 0) + rows = cols = 0; +} + +cv::gpu::GpuMat::GpuMat(const Mat& m) : + flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) +{ + upload(m); +} + +GpuMat& cv::gpu::GpuMat::operator = (const GpuMat& m) +{ + if (this != &m) + { + GpuMat temp(m); + swap(temp); + } + + return *this; +} + +void cv::gpu::GpuMat::swap(GpuMat& b) +{ + std::swap(flags, b.flags); + std::swap(rows, b.rows); + std::swap(cols, b.cols); + std::swap(step, b.step); + std::swap(data, b.data); + std::swap(datastart, b.datastart); + std::swap(dataend, b.dataend); + std::swap(refcount, b.refcount); +} + +void cv::gpu::GpuMat::locateROI(Size& wholeSize, Point& ofs) const +{ + size_t esz = elemSize(); + ptrdiff_t delta1 = data - datastart; + ptrdiff_t delta2 = dataend - datastart; + + CV_DbgAssert(step > 0); + + if (delta1 == 0) + ofs.x = ofs.y = 0; + else + { + ofs.y = static_cast(delta1 / step); + ofs.x = static_cast((delta1 - step * ofs.y) / esz); + + CV_DbgAssert(data == datastart + ofs.y * step + ofs.x * esz); + } + + size_t minstep = (ofs.x + cols) * esz; + + wholeSize.height = std::max(static_cast((delta2 - minstep) / step + 1), ofs.y + rows); + wholeSize.width = std::max(static_cast((delta2 - step * (wholeSize.height - 1)) / esz), ofs.x + cols); +} + +GpuMat& cv::gpu::GpuMat::adjustROI(int dtop, int dbottom, int dleft, int dright) +{ + Size wholeSize; + Point ofs; + locateROI(wholeSize, ofs); + + size_t esz = elemSize(); + + int row1 = std::max(ofs.y - dtop, 0); + int row2 = std::min(ofs.y + rows + dbottom, wholeSize.height); + + int col1 = std::max(ofs.x - dleft, 0); + int col2 = std::min(ofs.x + cols + dright, wholeSize.width); + + data += (row1 - ofs.y) * step + (col1 - ofs.x) * esz; + rows = row2 - row1; + cols = col2 - col1; + + if (esz * cols == step || rows == 1) + flags |= Mat::CONTINUOUS_FLAG; + else + flags &= ~Mat::CONTINUOUS_FLAG; + + return *this; +} + +GpuMat cv::gpu::GpuMat::reshape(int new_cn, int new_rows) const +{ + GpuMat hdr = *this; + + int cn = channels(); + if (new_cn == 0) + new_cn = cn; + + int total_width = cols * cn; + + if ((new_cn > total_width || total_width % new_cn != 0) && new_rows == 0) + new_rows = rows * total_width / new_cn; + + if (new_rows != 0 && new_rows != rows) + { + int total_size = total_width * rows; + + if (!isContinuous()) + CV_Error(CV_BadStep, "The matrix is not continuous, thus its number of rows can not be changed"); + + if ((unsigned)new_rows > (unsigned)total_size) + CV_Error(CV_StsOutOfRange, "Bad new number of rows"); + + total_width = total_size / new_rows; + + if (total_width * new_rows != total_size) + CV_Error(CV_StsBadArg, "The total number of matrix elements is not divisible by the new number of rows"); + + hdr.rows = new_rows; + hdr.step = total_width * elemSize1(); + } + + int new_width = total_width / new_cn; + + if (new_width * new_cn != total_width) + CV_Error(CV_BadNumChannels, "The total width is not divisible by the new number of channels"); + + hdr.cols = new_width; + hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn - 1) << CV_CN_SHIFT); + + return hdr; +} + +cv::Mat::Mat(const GpuMat& m) : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows) +{ + m.download(*this); +} + +void cv::gpu::createContinuous(int rows, int cols, int type, GpuMat& m) +{ + int area = rows * cols; + if (m.empty() || m.type() != type || !m.isContinuous() || m.size().area() < area) + m.create(1, area, type); + + m.cols = cols; + m.rows = rows; + m.step = m.elemSize() * cols; + m.flags |= Mat::CONTINUOUS_FLAG; +} + +void cv::gpu::ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m) +{ + if (m.empty() || m.type() != type || m.data != m.datastart) + m.create(rows, cols, type); + else + { + const size_t esz = m.elemSize(); + const ptrdiff_t delta2 = m.dataend - m.datastart; + + const size_t minstep = m.cols * esz; + + Size wholeSize; + wholeSize.height = std::max(static_cast((delta2 - minstep) / m.step + 1), m.rows); + wholeSize.width = std::max(static_cast((delta2 - m.step * (wholeSize.height - 1)) / esz), m.cols); + + if (wholeSize.height < rows || wholeSize.width < cols) + m.create(rows, cols, type); + else + { + m.cols = cols; + m.rows = rows; + } + } +} + +GpuMat cv::gpu::allocMatFromBuf(int rows, int cols, int type, GpuMat &mat) +{ + if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols) + return mat(Rect(0, 0, cols, rows)); + return mat = GpuMat(rows, cols, type); +} + +namespace +{ + class GpuFuncTable + { + public: + virtual ~GpuFuncTable() {} + + virtual void copy(const Mat& src, GpuMat& dst) const = 0; + virtual void copy(const GpuMat& src, Mat& dst) const = 0; + virtual void copy(const GpuMat& src, GpuMat& dst) const = 0; + + virtual void copyWithMask(const GpuMat& src, GpuMat& dst, const GpuMat& mask) const = 0; + + virtual void convert(const GpuMat& src, GpuMat& dst) const = 0; + virtual void convert(const GpuMat& src, GpuMat& dst, double alpha, double beta) const = 0; + + virtual void setTo(GpuMat& m, Scalar s, const GpuMat& mask) const = 0; + + virtual void mallocPitch(void** devPtr, size_t* step, size_t width, size_t height) const = 0; + virtual void free(void* devPtr) const = 0; + }; +} + +#ifndef HAVE_CUDA + +namespace +{ + class EmptyFuncTable : public GpuFuncTable + { + public: + void copy(const Mat&, GpuMat&) const { throw_nogpu; } + void copy(const GpuMat&, Mat&) const { throw_nogpu; } + void copy(const GpuMat&, GpuMat&) const { throw_nogpu; } + + void copyWithMask(const GpuMat&, GpuMat&, const GpuMat&) const { throw_nogpu; } + + void convert(const GpuMat&, GpuMat&) const { throw_nogpu; } + void convert(const GpuMat&, GpuMat&, double, double) const { throw_nogpu; } + + void setTo(GpuMat&, Scalar, const GpuMat&) const { throw_nogpu; } + + void mallocPitch(void**, size_t*, size_t, size_t) const { throw_nogpu; } + void free(void*) const {} + }; + + const GpuFuncTable* gpuFuncTable() + { + static EmptyFuncTable empty; + return ∅ + } +} + +#else // HAVE_CUDA + +namespace cv { namespace gpu { namespace device +{ + void copyToWithMask_gpu(PtrStepSzb src, PtrStepSzb dst, size_t elemSize1, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream); + + template + void set_to_gpu(PtrStepSzb mat, const T* scalar, int channels, cudaStream_t stream); + + template + void set_to_gpu(PtrStepSzb mat, const T* scalar, PtrStepSzb mask, int channels, cudaStream_t stream); + + void convert_gpu(PtrStepSzb src, int sdepth, PtrStepSzb dst, int ddepth, double alpha, double beta, cudaStream_t stream); +}}} + +namespace +{ + template void kernelSetCaller(GpuMat& src, Scalar s, cudaStream_t stream) + { + Scalar_ sf = s; + cv::gpu::device::set_to_gpu(src, sf.val, src.channels(), stream); + } + + template void kernelSetCaller(GpuMat& src, Scalar s, const GpuMat& mask, cudaStream_t stream) + { + Scalar_ sf = s; + cv::gpu::device::set_to_gpu(src, sf.val, mask, src.channels(), stream); + } +} + + +namespace cv { namespace gpu +{ + CV_EXPORTS void copyWithMask(const cv::gpu::GpuMat&, cv::gpu::GpuMat&, const cv::gpu::GpuMat&, CUstream_st*); + CV_EXPORTS void convertTo(const cv::gpu::GpuMat&, cv::gpu::GpuMat&); + CV_EXPORTS void convertTo(const cv::gpu::GpuMat&, cv::gpu::GpuMat&, double, double, CUstream_st*); + CV_EXPORTS void setTo(cv::gpu::GpuMat&, cv::Scalar, CUstream_st*); + CV_EXPORTS void setTo(cv::gpu::GpuMat&, cv::Scalar, const cv::gpu::GpuMat&, CUstream_st*); + CV_EXPORTS void setTo(cv::gpu::GpuMat&, cv::Scalar); + CV_EXPORTS void setTo(cv::gpu::GpuMat&, cv::Scalar, const cv::gpu::GpuMat&); +}} + + +namespace cv { namespace gpu +{ + void copyWithMask(const GpuMat& src, GpuMat& dst, const GpuMat& mask, cudaStream_t stream = 0) + { + CV_Assert(src.size() == dst.size() && src.type() == dst.type()); + CV_Assert(src.size() == mask.size() && mask.depth() == CV_8U && (mask.channels() == 1 || mask.channels() == src.channels())); + + cv::gpu::device::copyToWithMask_gpu(src.reshape(1), dst.reshape(1), src.elemSize1(), src.channels(), mask.reshape(1), mask.channels() != 1, stream); + } + + void convertTo(const GpuMat& src, GpuMat& dst) + { + cv::gpu::device::convert_gpu(src.reshape(1), src.depth(), dst.reshape(1), dst.depth(), 1.0, 0.0, 0); + } + + void convertTo(const GpuMat& src, GpuMat& dst, double alpha, double beta, cudaStream_t stream = 0) + { + cv::gpu::device::convert_gpu(src.reshape(1), src.depth(), dst.reshape(1), dst.depth(), alpha, beta, stream); + } + + void setTo(GpuMat& src, Scalar s, cudaStream_t stream) + { + typedef void (*caller_t)(GpuMat& src, Scalar s, cudaStream_t stream); + + static const caller_t callers[] = + { + kernelSetCaller, kernelSetCaller, kernelSetCaller, kernelSetCaller, kernelSetCaller, + kernelSetCaller, kernelSetCaller + }; + + callers[src.depth()](src, s, stream); + } + + void setTo(GpuMat& src, Scalar s, const GpuMat& mask, cudaStream_t stream) + { + typedef void (*caller_t)(GpuMat& src, Scalar s, const GpuMat& mask, cudaStream_t stream); + + static const caller_t callers[] = + { + kernelSetCaller, kernelSetCaller, kernelSetCaller, kernelSetCaller, kernelSetCaller, + kernelSetCaller, kernelSetCaller + }; + + callers[src.depth()](src, s, mask, stream); + } + + void setTo(GpuMat& src, Scalar s) + { + setTo(src, s, 0); + } + + void setTo(GpuMat& src, Scalar s, const GpuMat& mask) + { + setTo(src, s, mask, 0); + } +}} + +namespace +{ + template struct NPPTypeTraits; + template<> struct NPPTypeTraits { typedef Npp8u npp_type; }; + template<> struct NPPTypeTraits { typedef Npp8s npp_type; }; + template<> struct NPPTypeTraits { typedef Npp16u npp_type; }; + template<> struct NPPTypeTraits { typedef Npp16s npp_type; }; + template<> struct NPPTypeTraits { typedef Npp32s npp_type; }; + template<> struct NPPTypeTraits { typedef Npp32f npp_type; }; + template<> struct NPPTypeTraits { typedef Npp64f npp_type; }; + + ////////////////////////////////////////////////////////////////////////// + // Convert + + template struct NppConvertFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + typedef typename NPPTypeTraits::npp_type dst_t; + + typedef NppStatus (*func_ptr)(const src_t* pSrc, int nSrcStep, dst_t* pDst, int nDstStep, NppiSize oSizeROI); + }; + template struct NppConvertFunc + { + typedef typename NPPTypeTraits::npp_type dst_t; + + typedef NppStatus (*func_ptr)(const Npp32f* pSrc, int nSrcStep, dst_t* pDst, int nDstStep, NppiSize oSizeROI, NppRoundMode eRoundMode); + }; + + template::func_ptr func> struct NppCvt + { + typedef typename NPPTypeTraits::npp_type src_t; + typedef typename NPPTypeTraits::npp_type dst_t; + + static void call(const GpuMat& src, GpuMat& dst) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + nppSafeCall( func(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), sz) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + template::func_ptr func> struct NppCvt + { + typedef typename NPPTypeTraits::npp_type dst_t; + + static void call(const GpuMat& src, GpuMat& dst) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + nppSafeCall( func(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), sz, NPP_RND_NEAR) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Set + + template struct NppSetFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + + typedef NppStatus (*func_ptr)(const src_t values[], src_t* pSrc, int nSrcStep, NppiSize oSizeROI); + }; + template struct NppSetFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + + typedef NppStatus (*func_ptr)(src_t val, src_t* pSrc, int nSrcStep, NppiSize oSizeROI); + }; + template struct NppSetFunc + { + typedef NppStatus (*func_ptr)(Npp8s values[], Npp8s* pSrc, int nSrcStep, NppiSize oSizeROI); + }; + template<> struct NppSetFunc + { + typedef NppStatus (*func_ptr)(Npp8s val, Npp8s* pSrc, int nSrcStep, NppiSize oSizeROI); + }; + + template::func_ptr func> struct NppSet + { + typedef typename NPPTypeTraits::npp_type src_t; + + static void call(GpuMat& src, Scalar s) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + Scalar_ nppS = s; + + nppSafeCall( func(nppS.val, src.ptr(), static_cast(src.step), sz) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + template::func_ptr func> struct NppSet + { + typedef typename NPPTypeTraits::npp_type src_t; + + static void call(GpuMat& src, Scalar s) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + Scalar_ nppS = s; + + nppSafeCall( func(nppS[0], src.ptr(), static_cast(src.step), sz) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + + template struct NppSetMaskFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + + typedef NppStatus (*func_ptr)(const src_t values[], src_t* pSrc, int nSrcStep, NppiSize oSizeROI, const Npp8u* pMask, int nMaskStep); + }; + template struct NppSetMaskFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + + typedef NppStatus (*func_ptr)(src_t val, src_t* pSrc, int nSrcStep, NppiSize oSizeROI, const Npp8u* pMask, int nMaskStep); + }; + + template::func_ptr func> struct NppSetMask + { + typedef typename NPPTypeTraits::npp_type src_t; + + static void call(GpuMat& src, Scalar s, const GpuMat& mask) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + Scalar_ nppS = s; + + nppSafeCall( func(nppS.val, src.ptr(), static_cast(src.step), sz, mask.ptr(), static_cast(mask.step)) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + template::func_ptr func> struct NppSetMask + { + typedef typename NPPTypeTraits::npp_type src_t; + + static void call(GpuMat& src, Scalar s, const GpuMat& mask) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + Scalar_ nppS = s; + + nppSafeCall( func(nppS[0], src.ptr(), static_cast(src.step), sz, mask.ptr(), static_cast(mask.step)) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // CopyMasked + + template struct NppCopyMaskedFunc + { + typedef typename NPPTypeTraits::npp_type src_t; + + typedef NppStatus (*func_ptr)(const src_t* pSrc, int nSrcStep, src_t* pDst, int nDstStep, NppiSize oSizeROI, const Npp8u* pMask, int nMaskStep); + }; + + template::func_ptr func> struct NppCopyMasked + { + typedef typename NPPTypeTraits::npp_type src_t; + + static void call(const GpuMat& src, GpuMat& dst, const GpuMat& mask, cudaStream_t /*stream*/) + { + NppiSize sz; + sz.width = src.cols; + sz.height = src.rows; + + nppSafeCall( func(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), sz, mask.ptr(), static_cast(mask.step)) ); + + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + + template static inline bool isAligned(const T* ptr, size_t size) + { + return reinterpret_cast(ptr) % size == 0; + } + + ////////////////////////////////////////////////////////////////////////// + // CudaFuncTable + + class CudaFuncTable : public GpuFuncTable + { + public: + void copy(const Mat& src, GpuMat& dst) const + { + cudaSafeCall( cudaMemcpy2D(dst.data, dst.step, src.data, src.step, src.cols * src.elemSize(), src.rows, cudaMemcpyHostToDevice) ); + } + void copy(const GpuMat& src, Mat& dst) const + { + cudaSafeCall( cudaMemcpy2D(dst.data, dst.step, src.data, src.step, src.cols * src.elemSize(), src.rows, cudaMemcpyDeviceToHost) ); + } + void copy(const GpuMat& src, GpuMat& dst) const + { + cudaSafeCall( cudaMemcpy2D(dst.data, dst.step, src.data, src.step, src.cols * src.elemSize(), src.rows, cudaMemcpyDeviceToDevice) ); + } + + void copyWithMask(const GpuMat& src, GpuMat& dst, const GpuMat& mask) const + { + CV_Assert(src.depth() <= CV_64F && src.channels() <= 4); + CV_Assert(src.size() == dst.size() && src.type() == dst.type()); + CV_Assert(src.size() == mask.size() && mask.depth() == CV_8U && (mask.channels() == 1 || mask.channels() == src.channels())); + + if (src.depth() == CV_64F) + { + if (!TargetArchs::builtWith(NATIVE_DOUBLE) || !DeviceInfo().supports(NATIVE_DOUBLE)) + CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); + } + + typedef void (*func_t)(const GpuMat& src, GpuMat& dst, const GpuMat& mask, cudaStream_t stream); + static const func_t funcs[7][4] = + { + /* 8U */ {NppCopyMasked::call, cv::gpu::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, + /* 8S */ {cv::gpu::copyWithMask , cv::gpu::copyWithMask, cv::gpu::copyWithMask , cv::gpu::copyWithMask }, + /* 16U */ {NppCopyMasked::call, cv::gpu::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, + /* 16S */ {NppCopyMasked::call, cv::gpu::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, + /* 32S */ {NppCopyMasked::call, cv::gpu::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, + /* 32F */ {NppCopyMasked::call, cv::gpu::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, + /* 64F */ {cv::gpu::copyWithMask , cv::gpu::copyWithMask, cv::gpu::copyWithMask , cv::gpu::copyWithMask } + }; + + const func_t func = mask.channels() == src.channels() ? funcs[src.depth()][src.channels() - 1] : cv::gpu::copyWithMask; + + func(src, dst, mask, 0); + } + + void convert(const GpuMat& src, GpuMat& dst) const + { + typedef void (*func_t)(const GpuMat& src, GpuMat& dst); + static const func_t funcs[7][7][4] = + { + { + /* 8U -> 8U */ {0, 0, 0, 0}, + /* 8U -> 8S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 8U -> 16U */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, NppCvt::call}, + /* 8U -> 16S */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, NppCvt::call}, + /* 8U -> 32S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 8U -> 32F */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 8U -> 64F */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo } + }, + { + /* 8S -> 8U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 8S -> 8S */ {0,0,0,0}, + /* 8S -> 16U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 8S -> 16S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 8S -> 32S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 8S -> 32F */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 8S -> 64F */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo} + }, + { + /* 16U -> 8U */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, NppCvt::call}, + /* 16U -> 8S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16U -> 16U */ {0,0,0,0}, + /* 16U -> 16S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16U -> 32S */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16U -> 32F */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16U -> 64F */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo } + }, + { + /* 16S -> 8U */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, NppCvt::call}, + /* 16S -> 8S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16S -> 16U */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16S -> 16S */ {0,0,0,0}, + /* 16S -> 32S */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16S -> 32F */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo }, + /* 16S -> 64F */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo } + }, + { + /* 32S -> 8U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32S -> 8S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32S -> 16U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32S -> 16S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32S -> 32S */ {0,0,0,0}, + /* 32S -> 32F */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32S -> 64F */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo} + }, + { + /* 32F -> 8U */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32F -> 8S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32F -> 16U */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32F -> 16S */ {NppCvt::call, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32F -> 32S */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 32F -> 32F */ {0,0,0,0}, + /* 32F -> 64F */ {cv::gpu::convertTo , cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo} + }, + { + /* 64F -> 8U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 8S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 16U */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 16S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 32S */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 32F */ {cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo, cv::gpu::convertTo}, + /* 64F -> 64F */ {0,0,0,0} + } + }; + + CV_Assert(src.depth() <= CV_64F && src.channels() <= 4); + CV_Assert(dst.depth() <= CV_64F); + CV_Assert(src.size() == dst.size() && src.channels() == dst.channels()); + + if (src.depth() == CV_64F || dst.depth() == CV_64F) + { + if (!TargetArchs::builtWith(NATIVE_DOUBLE) || !DeviceInfo().supports(NATIVE_DOUBLE)) + CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); + } + + bool aligned = isAligned(src.data, 16) && isAligned(dst.data, 16); + if (!aligned) + { + cv::gpu::convertTo(src, dst); + return; + } + + const func_t func = funcs[src.depth()][dst.depth()][src.channels() - 1]; + CV_DbgAssert(func != 0); + + func(src, dst); + } + + void convert(const GpuMat& src, GpuMat& dst, double alpha, double beta) const + { + CV_Assert(src.depth() <= CV_64F && src.channels() <= 4); + CV_Assert(dst.depth() <= CV_64F); + + if (src.depth() == CV_64F || dst.depth() == CV_64F) + { + if (!TargetArchs::builtWith(NATIVE_DOUBLE) || !DeviceInfo().supports(NATIVE_DOUBLE)) + CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); + } + + cv::gpu::convertTo(src, dst, alpha, beta); + } + + void setTo(GpuMat& m, Scalar s, const GpuMat& mask) const + { + if (mask.empty()) + { + if (s[0] == 0.0 && s[1] == 0.0 && s[2] == 0.0 && s[3] == 0.0) + { + cudaSafeCall( cudaMemset2D(m.data, m.step, 0, m.cols * m.elemSize(), m.rows) ); + return; + } + + if (m.depth() == CV_8U) + { + int cn = m.channels(); + + if (cn == 1 || (cn == 2 && s[0] == s[1]) || (cn == 3 && s[0] == s[1] && s[0] == s[2]) || (cn == 4 && s[0] == s[1] && s[0] == s[2] && s[0] == s[3])) + { + int val = saturate_cast(s[0]); + cudaSafeCall( cudaMemset2D(m.data, m.step, val, m.cols * m.elemSize(), m.rows) ); + return; + } + } + + typedef void (*func_t)(GpuMat& src, Scalar s); + static const func_t funcs[7][4] = + { + {NppSet::call, cv::gpu::setTo , cv::gpu::setTo , NppSet::call}, + {NppSet::call, NppSet::call, NppSet::call, NppSet::call}, + {NppSet::call, NppSet::call, cv::gpu::setTo , NppSet::call}, + {NppSet::call, NppSet::call, cv::gpu::setTo , NppSet::call}, + {NppSet::call, cv::gpu::setTo , cv::gpu::setTo , NppSet::call}, + {NppSet::call, cv::gpu::setTo , cv::gpu::setTo , NppSet::call}, + {cv::gpu::setTo , cv::gpu::setTo , cv::gpu::setTo , cv::gpu::setTo } + }; + + CV_Assert(m.depth() <= CV_64F && m.channels() <= 4); + + if (m.depth() == CV_64F) + { + if (!TargetArchs::builtWith(NATIVE_DOUBLE) || !DeviceInfo().supports(NATIVE_DOUBLE)) + CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); + } + + funcs[m.depth()][m.channels() - 1](m, s); + } + else + { + typedef void (*func_t)(GpuMat& src, Scalar s, const GpuMat& mask); + static const func_t funcs[7][4] = + { + {NppSetMask::call, cv::gpu::setTo, cv::gpu::setTo, NppSetMask::call}, + {cv::gpu::setTo , cv::gpu::setTo, cv::gpu::setTo, cv::gpu::setTo }, + {NppSetMask::call, cv::gpu::setTo, cv::gpu::setTo, NppSetMask::call}, + {NppSetMask::call, cv::gpu::setTo, cv::gpu::setTo, NppSetMask::call}, + {NppSetMask::call, cv::gpu::setTo, cv::gpu::setTo, NppSetMask::call}, + {NppSetMask::call, cv::gpu::setTo, cv::gpu::setTo, NppSetMask::call}, + {cv::gpu::setTo , cv::gpu::setTo, cv::gpu::setTo, cv::gpu::setTo } + }; + + CV_Assert(m.depth() <= CV_64F && m.channels() <= 4); + + if (m.depth() == CV_64F) + { + if (!TargetArchs::builtWith(NATIVE_DOUBLE) || !DeviceInfo().supports(NATIVE_DOUBLE)) + CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); + } + + funcs[m.depth()][m.channels() - 1](m, s, mask); + } + } + + void mallocPitch(void** devPtr, size_t* step, size_t width, size_t height) const + { + cudaSafeCall( cudaMallocPitch(devPtr, step, width, height) ); + } + + void free(void* devPtr) const + { + cudaFree(devPtr); + } + }; + + const GpuFuncTable* gpuFuncTable() + { + static CudaFuncTable funcTable; + return &funcTable; + } +} + +#endif // HAVE_CUDA + +void cv::gpu::GpuMat::upload(const Mat& m) +{ + CV_DbgAssert(!m.empty()); + + create(m.size(), m.type()); + + gpuFuncTable()->copy(m, *this); +} + +void cv::gpu::GpuMat::download(Mat& m) const +{ + CV_DbgAssert(!empty()); + + m.create(size(), type()); + + gpuFuncTable()->copy(*this, m); +} + +void cv::gpu::GpuMat::copyTo(GpuMat& m) const +{ + CV_DbgAssert(!empty()); + + m.create(size(), type()); + + gpuFuncTable()->copy(*this, m); +} + +void cv::gpu::GpuMat::copyTo(GpuMat& mat, const GpuMat& mask) const +{ + if (mask.empty()) + copyTo(mat); + else + { + mat.create(size(), type()); + + gpuFuncTable()->copyWithMask(*this, mat, mask); + } +} + +void cv::gpu::GpuMat::convertTo(GpuMat& dst, int rtype, double alpha, double beta) const +{ + bool noScale = fabs(alpha - 1) < numeric_limits::epsilon() && fabs(beta) < numeric_limits::epsilon(); + + if (rtype < 0) + rtype = type(); + else + rtype = CV_MAKETYPE(CV_MAT_DEPTH(rtype), channels()); + + int sdepth = depth(); + int ddepth = CV_MAT_DEPTH(rtype); + if (sdepth == ddepth && noScale) + { + copyTo(dst); + return; + } + + GpuMat temp; + const GpuMat* psrc = this; + if (sdepth != ddepth && psrc == &dst) + { + temp = *this; + psrc = &temp; + } + + dst.create(size(), rtype); + + if (noScale) + gpuFuncTable()->convert(*psrc, dst); + else + gpuFuncTable()->convert(*psrc, dst, alpha, beta); +} + +GpuMat& cv::gpu::GpuMat::setTo(Scalar s, const GpuMat& mask) +{ + CV_Assert(mask.empty() || mask.type() == CV_8UC1); + CV_DbgAssert(!empty()); + + gpuFuncTable()->setTo(*this, s, mask); + + return *this; +} + +void cv::gpu::GpuMat::create(int _rows, int _cols, int _type) +{ + _type &= TYPE_MASK; + + if (rows == _rows && cols == _cols && type() == _type && data) + return; + + if (data) + release(); + + CV_DbgAssert(_rows >= 0 && _cols >= 0); + + if (_rows > 0 && _cols > 0) + { + flags = Mat::MAGIC_VAL + _type; + rows = _rows; + cols = _cols; + + size_t esz = elemSize(); + + void* devPtr; + gpuFuncTable()->mallocPitch(&devPtr, &step, esz * cols, rows); + + // Single row must be continuous + if (rows == 1) + step = esz * cols; + + if (esz * cols == step) + flags |= Mat::CONTINUOUS_FLAG; + + int64 _nettosize = static_cast(step) * rows; + size_t nettosize = static_cast(_nettosize); + + datastart = data = static_cast(devPtr); + dataend = data + nettosize; + + refcount = static_cast(fastMalloc(sizeof(*refcount))); + *refcount = 1; + } +} + +void cv::gpu::GpuMat::release() +{ + if (refcount && CV_XADD(refcount, -1) == 1) + { + fastFree(refcount); + + gpuFuncTable()->free(datastart); + } + + data = datastart = dataend = 0; + step = rows = cols = 0; + refcount = 0; +} + +//////////////////////////////////////////////////////////////////////// +// Error handling + +void cv::gpu::error(const char *error_string, const char *file, const int line, const char *func) +{ + int code = CV_GpuApiCallError; + + if (uncaught_exception()) + { + const char* errorStr = cvErrorStr(code); + const char* function = func ? func : "unknown function"; + + cerr << "OpenCV Error: " << errorStr << "(" << error_string << ") in " << function << ", file " << file << ", line " << line; + cerr.flush(); + } + else + cv::error( cv::Exception(code, error_string, func, file, line) ); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/lapack.cpp diffimg-2.0.0/3rdparty/opencv/core/src/lapack.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/lapack.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/lapack.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1835 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if defined _M_IX86 && defined _MSC_VER && _MSC_VER < 1700 +#pragma float_control(precise, on) +#endif + +namespace cv +{ + +/****************************************************************************************\ +* LU & Cholesky implementation for small matrices * +\****************************************************************************************/ + +template static inline int +LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +{ + int i, j, k, p = 1; + astep /= sizeof(A[0]); + bstep /= sizeof(b[0]); + + for( i = 0; i < m; i++ ) + { + k = i; + + for( j = i+1; j < m; j++ ) + if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) ) + k = j; + + if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() ) + return 0; + + if( k != i ) + { + for( j = i; j < m; j++ ) + std::swap(A[i*astep + j], A[k*astep + j]); + if( b ) + for( j = 0; j < n; j++ ) + std::swap(b[i*bstep + j], b[k*bstep + j]); + p = -p; + } + + _Tp d = -1/A[i*astep + i]; + + for( j = i+1; j < m; j++ ) + { + _Tp alpha = A[j*astep + i]*d; + + for( k = i+1; k < m; k++ ) + A[j*astep + k] += alpha*A[i*astep + k]; + + if( b ) + for( k = 0; k < n; k++ ) + b[j*bstep + k] += alpha*b[i*bstep + k]; + } + + A[i*astep + i] = -d; + } + + if( b ) + { + for( i = m-1; i >= 0; i-- ) + for( j = 0; j < n; j++ ) + { + _Tp s = b[i*bstep + j]; + for( k = i+1; k < m; k++ ) + s -= A[i*astep + k]*b[k*bstep + j]; + b[i*bstep + j] = s*A[i*astep + i]; + } + } + + return p; +} + + +int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n) +{ + return LUImpl(A, astep, m, b, bstep, n); +} + + +int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n) +{ + return LUImpl(A, astep, m, b, bstep, n); +} + + +template static inline bool +CholImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +{ + _Tp* L = A; + int i, j, k; + double s; + astep /= sizeof(A[0]); + bstep /= sizeof(b[0]); + + for( i = 0; i < m; i++ ) + { + for( j = 0; j < i; j++ ) + { + s = A[i*astep + j]; + for( k = 0; k < j; k++ ) + s -= L[i*astep + k]*L[j*astep + k]; + L[i*astep + j] = (_Tp)(s*L[j*astep + j]); + } + s = A[i*astep + i]; + for( k = 0; k < j; k++ ) + { + double t = L[i*astep + k]; + s -= t*t; + } + if( s < std::numeric_limits<_Tp>::epsilon() ) + return false; + L[i*astep + i] = (_Tp)(1./std::sqrt(s)); + } + + if( !b ) + return true; + + // LLt x = b + // 1: L y = b + // 2. Lt x = y + + /* + [ L00 ] y0 b0 + [ L10 L11 ] y1 = b1 + [ L20 L21 L22 ] y2 b2 + [ L30 L31 L32 L33 ] y3 b3 + + [ L00 L10 L20 L30 ] x0 y0 + [ L11 L21 L31 ] x1 = y1 + [ L22 L32 ] x2 y2 + [ L33 ] x3 y3 + */ + + for( i = 0; i < m; i++ ) + { + for( j = 0; j < n; j++ ) + { + s = b[i*bstep + j]; + for( k = 0; k < i; k++ ) + s -= L[i*astep + k]*b[k*bstep + j]; + b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); + } + } + + for( i = m-1; i >= 0; i-- ) + { + for( j = 0; j < n; j++ ) + { + s = b[i*bstep + j]; + for( k = m-1; k > i; k-- ) + s -= L[k*astep + i]*b[k*bstep + j]; + b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); + } + } + + return true; +} + + +bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n) +{ + return CholImpl(A, astep, m, b, bstep, n); +} + +bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n) +{ + return CholImpl(A, astep, m, b, bstep, n); +} + + +template static inline _Tp hypot(_Tp a, _Tp b) +{ + a = std::abs(a); + b = std::abs(b); + if( a > b ) + { + b /= a; + return a*std::sqrt(1 + b*b); + } + if( b > 0 ) + { + a /= b; + return b*std::sqrt(1 + a*a); + } + return 0; +} + + +template bool +JacobiImpl_( _Tp* A, size_t astep, _Tp* W, _Tp* V, size_t vstep, int n, uchar* buf ) +{ + const _Tp eps = std::numeric_limits<_Tp>::epsilon(); + int i, j, k, m; + + astep /= sizeof(A[0]); + if( V ) + { + vstep /= sizeof(V[0]); + for( i = 0; i < n; i++ ) + { + for( j = 0; j < n; j++ ) + V[i*vstep + j] = (_Tp)0; + V[i*vstep + i] = (_Tp)1; + } + } + + int iters, maxIters = n*n*30; + + int* indR = (int*)alignPtr(buf, sizeof(int)); + int* indC = indR + n; + _Tp mv = (_Tp)0; + + for( k = 0; k < n; k++ ) + { + W[k] = A[(astep + 1)*k]; + if( k < n - 1 ) + { + for( m = k+1, mv = std::abs(A[astep*k + m]), i = k+2; i < n; i++ ) + { + _Tp val = std::abs(A[astep*k+i]); + if( mv < val ) + mv = val, m = i; + } + indR[k] = m; + } + if( k > 0 ) + { + for( m = 0, mv = std::abs(A[k]), i = 1; i < k; i++ ) + { + _Tp val = std::abs(A[astep*i+k]); + if( mv < val ) + mv = val, m = i; + } + indC[k] = m; + } + } + + if( n > 1 ) for( iters = 0; iters < maxIters; iters++ ) + { + // find index (k,l) of pivot p + for( k = 0, mv = std::abs(A[indR[0]]), i = 1; i < n-1; i++ ) + { + _Tp val = std::abs(A[astep*i + indR[i]]); + if( mv < val ) + mv = val, k = i; + } + int l = indR[k]; + for( i = 1; i < n; i++ ) + { + _Tp val = std::abs(A[astep*indC[i] + i]); + if( mv < val ) + mv = val, k = indC[i], l = i; + } + + _Tp p = A[astep*k + l]; + if( std::abs(p) <= eps ) + break; + _Tp y = (_Tp)((W[l] - W[k])*0.5); + _Tp t = std::abs(y) + hypot(p, y); + _Tp s = hypot(p, t); + _Tp c = t/s; + s = p/s; t = (p/t)*p; + if( y < 0 ) + s = -s, t = -t; + A[astep*k + l] = 0; + + W[k] -= t; + W[l] += t; + + _Tp a0, b0; + +#undef rotate +#define rotate(v0, v1) a0 = v0, b0 = v1, v0 = a0*c - b0*s, v1 = a0*s + b0*c + + // rotate rows and columns k and l + for( i = 0; i < k; i++ ) + rotate(A[astep*i+k], A[astep*i+l]); + for( i = k+1; i < l; i++ ) + rotate(A[astep*k+i], A[astep*i+l]); + for( i = l+1; i < n; i++ ) + rotate(A[astep*k+i], A[astep*l+i]); + + // rotate eigenvectors + if( V ) + for( i = 0; i < n; i++ ) + rotate(V[vstep*k+i], V[vstep*l+i]); + +#undef rotate + + for( j = 0; j < 2; j++ ) + { + int idx = j == 0 ? k : l; + if( idx < n - 1 ) + { + for( m = idx+1, mv = std::abs(A[astep*idx + m]), i = idx+2; i < n; i++ ) + { + _Tp val = std::abs(A[astep*idx+i]); + if( mv < val ) + mv = val, m = i; + } + indR[idx] = m; + } + if( idx > 0 ) + { + for( m = 0, mv = std::abs(A[idx]), i = 1; i < idx; i++ ) + { + _Tp val = std::abs(A[astep*i+idx]); + if( mv < val ) + mv = val, m = i; + } + indC[idx] = m; + } + } + } + + // sort eigenvalues & eigenvectors + for( k = 0; k < n-1; k++ ) + { + m = k; + for( i = k+1; i < n; i++ ) + { + if( W[m] < W[i] ) + m = i; + } + if( k != m ) + { + std::swap(W[m], W[k]); + if( V ) + for( i = 0; i < n; i++ ) + std::swap(V[vstep*m + i], V[vstep*k + i]); + } + } + + return true; +} + +static bool Jacobi( float* S, size_t sstep, float* e, float* E, size_t estep, int n, uchar* buf ) +{ + return JacobiImpl_(S, sstep, e, E, estep, n, buf); +} + +static bool Jacobi( double* S, size_t sstep, double* e, double* E, size_t estep, int n, uchar* buf ) +{ + return JacobiImpl_(S, sstep, e, E, estep, n, buf); +} + + +template struct VBLAS +{ + int dot(const T*, const T*, int, T*) const { return 0; } + int givens(T*, T*, int, T, T) const { return 0; } + int givensx(T*, T*, int, T, T, T*, T*) const { return 0; } +}; + +#if CV_SSE2 +template<> inline int VBLAS::dot(const float* a, const float* b, int n, float* result) const +{ + if( n < 8 ) + return 0; + int k = 0; + __m128 s0 = _mm_setzero_ps(), s1 = _mm_setzero_ps(); + for( ; k <= n - 8; k += 8 ) + { + __m128 a0 = _mm_load_ps(a + k), a1 = _mm_load_ps(a + k + 4); + __m128 b0 = _mm_load_ps(b + k), b1 = _mm_load_ps(b + k + 4); + + s0 = _mm_add_ps(s0, _mm_mul_ps(a0, b0)); + s1 = _mm_add_ps(s1, _mm_mul_ps(a1, b1)); + } + s0 = _mm_add_ps(s0, s1); + float sbuf[4]; + _mm_storeu_ps(sbuf, s0); + *result = sbuf[0] + sbuf[1] + sbuf[2] + sbuf[3]; + return k; +} + + +template<> inline int VBLAS::givens(float* a, float* b, int n, float c, float s) const +{ + if( n < 4 ) + return 0; + int k = 0; + __m128 c4 = _mm_set1_ps(c), s4 = _mm_set1_ps(s); + for( ; k <= n - 4; k += 4 ) + { + __m128 a0 = _mm_load_ps(a + k); + __m128 b0 = _mm_load_ps(b + k); + __m128 t0 = _mm_add_ps(_mm_mul_ps(a0, c4), _mm_mul_ps(b0, s4)); + __m128 t1 = _mm_sub_ps(_mm_mul_ps(b0, c4), _mm_mul_ps(a0, s4)); + _mm_store_ps(a + k, t0); + _mm_store_ps(b + k, t1); + } + return k; +} + + +template<> inline int VBLAS::givensx(float* a, float* b, int n, float c, float s, + float* anorm, float* bnorm) const +{ + if( n < 4 ) + return 0; + int k = 0; + __m128 c4 = _mm_set1_ps(c), s4 = _mm_set1_ps(s); + __m128 sa = _mm_setzero_ps(), sb = _mm_setzero_ps(); + for( ; k <= n - 4; k += 4 ) + { + __m128 a0 = _mm_load_ps(a + k); + __m128 b0 = _mm_load_ps(b + k); + __m128 t0 = _mm_add_ps(_mm_mul_ps(a0, c4), _mm_mul_ps(b0, s4)); + __m128 t1 = _mm_sub_ps(_mm_mul_ps(b0, c4), _mm_mul_ps(a0, s4)); + _mm_store_ps(a + k, t0); + _mm_store_ps(b + k, t1); + sa = _mm_add_ps(sa, _mm_mul_ps(t0, t0)); + sb = _mm_add_ps(sb, _mm_mul_ps(t1, t1)); + } + float abuf[4], bbuf[4]; + _mm_storeu_ps(abuf, sa); + _mm_storeu_ps(bbuf, sb); + *anorm = abuf[0] + abuf[1] + abuf[2] + abuf[3]; + *bnorm = bbuf[0] + bbuf[1] + bbuf[2] + bbuf[3]; + return k; +} + + +template<> inline int VBLAS::dot(const double* a, const double* b, int n, double* result) const +{ + if( n < 4 ) + return 0; + int k = 0; + __m128d s0 = _mm_setzero_pd(), s1 = _mm_setzero_pd(); + for( ; k <= n - 4; k += 4 ) + { + __m128d a0 = _mm_load_pd(a + k), a1 = _mm_load_pd(a + k + 2); + __m128d b0 = _mm_load_pd(b + k), b1 = _mm_load_pd(b + k + 2); + + s0 = _mm_add_pd(s0, _mm_mul_pd(a0, b0)); + s1 = _mm_add_pd(s1, _mm_mul_pd(a1, b1)); + } + s0 = _mm_add_pd(s0, s1); + double sbuf[2]; + _mm_storeu_pd(sbuf, s0); + *result = sbuf[0] + sbuf[1]; + return k; +} + + +template<> inline int VBLAS::givens(double* a, double* b, int n, double c, double s) const +{ + int k = 0; + __m128d c2 = _mm_set1_pd(c), s2 = _mm_set1_pd(s); + for( ; k <= n - 2; k += 2 ) + { + __m128d a0 = _mm_load_pd(a + k); + __m128d b0 = _mm_load_pd(b + k); + __m128d t0 = _mm_add_pd(_mm_mul_pd(a0, c2), _mm_mul_pd(b0, s2)); + __m128d t1 = _mm_sub_pd(_mm_mul_pd(b0, c2), _mm_mul_pd(a0, s2)); + _mm_store_pd(a + k, t0); + _mm_store_pd(b + k, t1); + } + return k; +} + + +template<> inline int VBLAS::givensx(double* a, double* b, int n, double c, double s, + double* anorm, double* bnorm) const +{ + int k = 0; + __m128d c2 = _mm_set1_pd(c), s2 = _mm_set1_pd(s); + __m128d sa = _mm_setzero_pd(), sb = _mm_setzero_pd(); + for( ; k <= n - 2; k += 2 ) + { + __m128d a0 = _mm_load_pd(a + k); + __m128d b0 = _mm_load_pd(b + k); + __m128d t0 = _mm_add_pd(_mm_mul_pd(a0, c2), _mm_mul_pd(b0, s2)); + __m128d t1 = _mm_sub_pd(_mm_mul_pd(b0, c2), _mm_mul_pd(a0, s2)); + _mm_store_pd(a + k, t0); + _mm_store_pd(b + k, t1); + sa = _mm_add_pd(sa, _mm_mul_pd(t0, t0)); + sb = _mm_add_pd(sb, _mm_mul_pd(t1, t1)); + } + double abuf[2], bbuf[2]; + _mm_storeu_pd(abuf, sa); + _mm_storeu_pd(bbuf, sb); + *anorm = abuf[0] + abuf[1]; + *bnorm = bbuf[0] + bbuf[1]; + return k; +} +#endif + +template void +JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep, + int m, int n, int n1, double minval, _Tp eps) +{ + VBLAS<_Tp> vblas; + AutoBuffer Wbuf(n); + double* W = Wbuf; + int i, j, k, iter, max_iter = std::max(m, 30); + _Tp c, s; + double sd; + astep /= sizeof(At[0]); + vstep /= sizeof(Vt[0]); + + for( i = 0; i < n; i++ ) + { + for( k = 0, sd = 0; k < m; k++ ) + { + _Tp t = At[i*astep + k]; + sd += (double)t*t; + } + W[i] = sd; + + if( Vt ) + { + for( k = 0; k < n; k++ ) + Vt[i*vstep + k] = 0; + Vt[i*vstep + i] = 1; + } + } + + for( iter = 0; iter < max_iter; iter++ ) + { + bool changed = false; + + for( i = 0; i < n-1; i++ ) + for( j = i+1; j < n; j++ ) + { + _Tp *Ai = At + i*astep, *Aj = At + j*astep; + double a = W[i], p = 0, b = W[j]; + + for( k = 0; k < m; k++ ) + p += (double)Ai[k]*Aj[k]; + + if( std::abs(p) <= eps*std::sqrt((double)a*b) ) + continue; + + p *= 2; + double beta = a - b, gamma = hypot((double)p, beta); + if( beta < 0 ) + { + double delta = (gamma - beta)*0.5; + s = (_Tp)std::sqrt(delta/gamma); + c = (_Tp)(p/(gamma*s*2)); + } + else + { + c = (_Tp)std::sqrt((gamma + beta)/(gamma*2)); + s = (_Tp)(p/(gamma*c*2)); + } + + a = b = 0; + for( k = 0; k < m; k++ ) + { + _Tp t0 = c*Ai[k] + s*Aj[k]; + _Tp t1 = -s*Ai[k] + c*Aj[k]; + Ai[k] = t0; Aj[k] = t1; + + a += (double)t0*t0; b += (double)t1*t1; + } + W[i] = a; W[j] = b; + + changed = true; + + if( Vt ) + { + _Tp *Vi = Vt + i*vstep, *Vj = Vt + j*vstep; + k = vblas.givens(Vi, Vj, n, c, s); + + for( ; k < n; k++ ) + { + _Tp t0 = c*Vi[k] + s*Vj[k]; + _Tp t1 = -s*Vi[k] + c*Vj[k]; + Vi[k] = t0; Vj[k] = t1; + } + } + } + if( !changed ) + break; + } + + for( i = 0; i < n; i++ ) + { + for( k = 0, sd = 0; k < m; k++ ) + { + _Tp t = At[i*astep + k]; + sd += (double)t*t; + } + W[i] = std::sqrt(sd); + } + + for( i = 0; i < n-1; i++ ) + { + j = i; + for( k = i+1; k < n; k++ ) + { + if( W[j] < W[k] ) + j = k; + } + if( i != j ) + { + std::swap(W[i], W[j]); + if( Vt ) + { + for( k = 0; k < m; k++ ) + std::swap(At[i*astep + k], At[j*astep + k]); + + for( k = 0; k < n; k++ ) + std::swap(Vt[i*vstep + k], Vt[j*vstep + k]); + } + } + } + + for( i = 0; i < n; i++ ) + _W[i] = (_Tp)W[i]; + + if( !Vt ) + return; + + RNG rng(0x12345678); + for( i = 0; i < n1; i++ ) + { + sd = i < n ? W[i] : 0; + + while( sd <= minval ) + { + // if we got a zero singular value, then in order to get the corresponding left singular vector + // we generate a random vector, project it to the previously computed left singular vectors, + // subtract the projection and normalize the difference. + const _Tp val0 = (_Tp)(1./m); + for( k = 0; k < m; k++ ) + { + _Tp val = (rng.next() & 256) != 0 ? val0 : -val0; + At[i*astep + k] = val; + } + for( iter = 0; iter < 2; iter++ ) + { + for( j = 0; j < i; j++ ) + { + sd = 0; + for( k = 0; k < m; k++ ) + sd += At[i*astep + k]*At[j*astep + k]; + _Tp asum = 0; + for( k = 0; k < m; k++ ) + { + _Tp t = (_Tp)(At[i*astep + k] - sd*At[j*astep + k]); + At[i*astep + k] = t; + asum += std::abs(t); + } + asum = asum ? 1/asum : 0; + for( k = 0; k < m; k++ ) + At[i*astep + k] *= asum; + } + } + sd = 0; + for( k = 0; k < m; k++ ) + { + _Tp t = At[i*astep + k]; + sd += (double)t*t; + } + sd = std::sqrt(sd); + } + + s = (_Tp)(1/sd); + for( k = 0; k < m; k++ ) + At[i*astep + k] *= s; + } +} + + +static void JacobiSVD(float* At, size_t astep, float* W, float* Vt, size_t vstep, int m, int n, int n1=-1) +{ + JacobiSVDImpl_(At, astep, W, Vt, vstep, m, n, !Vt ? 0 : n1 < 0 ? n : n1, FLT_MIN, FLT_EPSILON*2); +} + +static void JacobiSVD(double* At, size_t astep, double* W, double* Vt, size_t vstep, int m, int n, int n1=-1) +{ + JacobiSVDImpl_(At, astep, W, Vt, vstep, m, n, !Vt ? 0 : n1 < 0 ? n : n1, DBL_MIN, DBL_EPSILON*10); +} + +/* y[0:m,0:n] += diag(a[0:1,0:m]) * x[0:m,0:n] */ +template static void +MatrAXPY( int m, int n, const T1* x, int dx, + const T2* a, int inca, T3* y, int dy ) +{ + int i, j; + for( i = 0; i < m; i++, x += dx, y += dy ) + { + T2 s = a[i*inca]; + j=0; + #if CV_ENABLE_UNROLLED + for(; j <= n - 4; j += 4 ) + { + T3 t0 = (T3)(y[j] + s*x[j]); + T3 t1 = (T3)(y[j+1] + s*x[j+1]); + y[j] = t0; + y[j+1] = t1; + t0 = (T3)(y[j+2] + s*x[j+2]); + t1 = (T3)(y[j+3] + s*x[j+3]); + y[j+2] = t0; + y[j+3] = t1; + } + #endif + for( ; j < n; j++ ) + y[j] = (T3)(y[j] + s*x[j]); + } +} + +template static void +SVBkSbImpl_( int m, int n, const T* w, int incw, + const T* u, int ldu, bool uT, + const T* v, int ldv, bool vT, + const T* b, int ldb, int nb, + T* x, int ldx, double* buffer, T eps ) +{ + double threshold = 0; + int udelta0 = uT ? ldu : 1, udelta1 = uT ? 1 : ldu; + int vdelta0 = vT ? ldv : 1, vdelta1 = vT ? 1 : ldv; + int i, j, nm = std::min(m, n); + + if( !b ) + nb = m; + + for( i = 0; i < n; i++ ) + for( j = 0; j < nb; j++ ) + x[i*ldx + j] = 0; + + for( i = 0; i < nm; i++ ) + threshold += w[i*incw]; + threshold *= eps; + + // v * inv(w) * uT * b + for( i = 0; i < nm; i++, u += udelta0, v += vdelta0 ) + { + double wi = w[i*incw]; + if( (double)std::abs(wi) <= threshold ) + continue; + wi = 1/wi; + + if( nb == 1 ) + { + double s = 0; + if( b ) + for( j = 0; j < m; j++ ) + s += u[j*udelta1]*b[j*ldb]; + else + s = u[0]; + s *= wi; + + for( j = 0; j < n; j++ ) + x[j*ldx] = (T)(x[j*ldx] + s*v[j*vdelta1]); + } + else + { + if( b ) + { + for( j = 0; j < nb; j++ ) + buffer[j] = 0; + MatrAXPY( m, nb, b, ldb, u, udelta1, buffer, 0 ); + for( j = 0; j < nb; j++ ) + buffer[j] *= wi; + } + else + { + for( j = 0; j < nb; j++ ) + buffer[j] = u[j*udelta1]*wi; + } + MatrAXPY( n, nb, buffer, 0, v, vdelta1, x, ldx ); + } + } +} + +static void +SVBkSb( int m, int n, const float* w, size_t wstep, + const float* u, size_t ustep, bool uT, + const float* v, size_t vstep, bool vT, + const float* b, size_t bstep, int nb, + float* x, size_t xstep, uchar* buffer ) +{ + SVBkSbImpl_(m, n, w, wstep ? (int)(wstep/sizeof(w[0])) : 1, + u, (int)(ustep/sizeof(u[0])), uT, + v, (int)(vstep/sizeof(v[0])), vT, + b, (int)(bstep/sizeof(b[0])), nb, + x, (int)(xstep/sizeof(x[0])), + (double*)alignPtr(buffer, sizeof(double)), (float)(DBL_EPSILON*2) ); +} + +static void +SVBkSb( int m, int n, const double* w, size_t wstep, + const double* u, size_t ustep, bool uT, + const double* v, size_t vstep, bool vT, + const double* b, size_t bstep, int nb, + double* x, size_t xstep, uchar* buffer ) +{ + SVBkSbImpl_(m, n, w, wstep ? (int)(wstep/sizeof(w[0])) : 1, + u, (int)(ustep/sizeof(u[0])), uT, + v, (int)(vstep/sizeof(v[0])), vT, + b, (int)(bstep/sizeof(b[0])), nb, + x, (int)(xstep/sizeof(x[0])), + (double*)alignPtr(buffer, sizeof(double)), DBL_EPSILON*2 ); +} + +} + +/****************************************************************************************\ +* Determinant of the matrix * +\****************************************************************************************/ + +#define det2(m) ((double)m(0,0)*m(1,1) - (double)m(0,1)*m(1,0)) +#define det3(m) (m(0,0)*((double)m(1,1)*m(2,2) - (double)m(1,2)*m(2,1)) - \ + m(0,1)*((double)m(1,0)*m(2,2) - (double)m(1,2)*m(2,0)) + \ + m(0,2)*((double)m(1,0)*m(2,1) - (double)m(1,1)*m(2,0))) + +double cv::determinant( InputArray _mat ) +{ + Mat mat = _mat.getMat(); + double result = 0; + int type = mat.type(), rows = mat.rows; + size_t step = mat.step; + const uchar* m = mat.data; + + CV_Assert( mat.rows == mat.cols && (type == CV_32F || type == CV_64F)); + + #define Mf(y, x) ((float*)(m + y*step))[x] + #define Md(y, x) ((double*)(m + y*step))[x] + + if( type == CV_32F ) + { + if( rows == 2 ) + result = det2(Mf); + else if( rows == 3 ) + result = det3(Mf); + else if( rows == 1 ) + result = Mf(0,0); + else + { + size_t bufSize = rows*rows*sizeof(float); + AutoBuffer buffer(bufSize); + Mat a(rows, rows, CV_32F, (uchar*)buffer); + mat.copyTo(a); + + result = LU((float*)a.data, a.step, rows, 0, 0, 0); + if( result ) + { + for( int i = 0; i < rows; i++ ) + result *= ((const float*)(a.data + a.step*i))[i]; + result = 1./result; + } + } + } + else + { + if( rows == 2 ) + result = det2(Md); + else if( rows == 3 ) + result = det3(Md); + else if( rows == 1 ) + result = Md(0,0); + else + { + size_t bufSize = rows*rows*sizeof(double); + AutoBuffer buffer(bufSize); + Mat a(rows, rows, CV_64F, (uchar*)buffer); + mat.copyTo(a); + + result = LU((double*)a.data, a.step, rows, 0, 0, 0); + if( result ) + { + for( int i = 0; i < rows; i++ ) + result *= ((const double*)(a.data + a.step*i))[i]; + result = 1./result; + } + } + } + + #undef Mf + #undef Md + + return result; +} + +/****************************************************************************************\ +* Inverse (or pseudo-inverse) of a matrix * +\****************************************************************************************/ + +#define Sf( y, x ) ((float*)(srcdata + y*srcstep))[x] +#define Sd( y, x ) ((double*)(srcdata + y*srcstep))[x] +#define Df( y, x ) ((float*)(dstdata + y*dststep))[x] +#define Dd( y, x ) ((double*)(dstdata + y*dststep))[x] + +double cv::invert( InputArray _src, OutputArray _dst, int method ) +{ + bool result = false; + Mat src = _src.getMat(); + int type = src.type(); + + CV_Assert(type == CV_32F || type == CV_64F); + + size_t esz = CV_ELEM_SIZE(type); + int m = src.rows, n = src.cols; + + if( method == DECOMP_SVD ) + { + int nm = std::min(m, n); + + AutoBuffer _buf((m*nm + nm + nm*n)*esz + sizeof(double)); + uchar* buf = alignPtr((uchar*)_buf, (int)esz); + Mat u(m, nm, type, buf); + Mat w(nm, 1, type, u.data + m*nm*esz); + Mat vt(nm, n, type, w.data + nm*esz); + + SVD::compute(src, w, u, vt); + SVD::backSubst(w, u, vt, Mat(), _dst); + return type == CV_32F ? + (((float*)w.data)[0] >= FLT_EPSILON ? + ((float*)w.data)[n-1]/((float*)w.data)[0] : 0) : + (((double*)w.data)[0] >= DBL_EPSILON ? + ((double*)w.data)[n-1]/((double*)w.data)[0] : 0); + } + + CV_Assert( m == n ); + + if( method == DECOMP_EIG ) + { + AutoBuffer _buf((n*n*2 + n)*esz + sizeof(double)); + uchar* buf = alignPtr((uchar*)_buf, (int)esz); + Mat u(n, n, type, buf); + Mat w(n, 1, type, u.data + n*n*esz); + Mat vt(n, n, type, w.data + n*esz); + + eigen(src, w, vt); + transpose(vt, u); + SVD::backSubst(w, u, vt, Mat(), _dst); + return type == CV_32F ? + (((float*)w.data)[0] >= FLT_EPSILON ? + ((float*)w.data)[n-1]/((float*)w.data)[0] : 0) : + (((double*)w.data)[0] >= DBL_EPSILON ? + ((double*)w.data)[n-1]/((double*)w.data)[0] : 0); + } + + CV_Assert( method == DECOMP_LU || method == DECOMP_CHOLESKY ); + + _dst.create( n, n, type ); + Mat dst = _dst.getMat(); + + if( n <= 3 ) + { + uchar* srcdata = src.data; + uchar* dstdata = dst.data; + size_t srcstep = src.step; + size_t dststep = dst.step; + + if( n == 2 ) + { + if( type == CV_32FC1 ) + { + double d = det2(Sf); + if( d != 0. ) + { + result = true; + d = 1./d; + + #if CV_SSE2 + if(USE_SSE2) + { + __m128 zero = _mm_setzero_ps(); + __m128 t0 = _mm_loadl_pi(zero, (const __m64*)srcdata); //t0 = sf(0,0) sf(0,1) + __m128 t1 = _mm_loadh_pi(zero, (const __m64*)(srcdata+srcstep)); //t1 = sf(1,0) sf(1,1) + __m128 s0 = _mm_or_ps(t0, t1); + __m128 det =_mm_set1_ps((float)d); + s0 = _mm_mul_ps(s0, det); + static const uchar CV_DECL_ALIGNED(16) inv[16] = {0,0,0,0,0,0,0,0x80,0,0,0,0x80,0,0,0,0}; + __m128 pattern = _mm_load_ps((const float*)inv); + s0 = _mm_xor_ps(s0, pattern);//==-1*s0 + s0 = _mm_shuffle_ps(s0, s0, _MM_SHUFFLE(0,2,1,3)); + _mm_storel_pi((__m64*)dstdata, s0); + _mm_storeh_pi((__m64*)((float*)(dstdata+dststep)), s0); + } + else + #endif + { + double t0, t1; + t0 = Sf(0,0)*d; + t1 = Sf(1,1)*d; + Df(1,1) = (float)t0; + Df(0,0) = (float)t1; + t0 = -Sf(0,1)*d; + t1 = -Sf(1,0)*d; + Df(0,1) = (float)t0; + Df(1,0) = (float)t1; + } + + } + } + else + { + double d = det2(Sd); + if( d != 0. ) + { + result = true; + d = 1./d; + #if CV_SSE2 + if(USE_SSE2) + { + __m128d s0 = _mm_loadu_pd((const double*)srcdata); //s0 = sf(0,0) sf(0,1) + __m128d s1 = _mm_loadu_pd ((const double*)(srcdata+srcstep));//s1 = sf(1,0) sf(1,1) + __m128d sm = _mm_unpacklo_pd(s0, _mm_load_sd((const double*)(srcdata+srcstep)+1)); //sm = sf(0,0) sf(1,1) - main diagonal + __m128d ss = _mm_shuffle_pd(s0, s1, _MM_SHUFFLE2(0,1)); //ss = sf(0,1) sf(1,0) - secondary diagonal + __m128d det = _mm_load1_pd((const double*)&d); + sm = _mm_mul_pd(sm, det); + + static const uchar CV_DECL_ALIGNED(16) inv[8] = {0,0,0,0,0,0,0,0x80}; + __m128d pattern = _mm_load1_pd((double*)inv); + ss = _mm_mul_pd(ss, det); + ss = _mm_xor_pd(ss, pattern);//==-1*ss + + s0 = _mm_shuffle_pd(sm, ss, _MM_SHUFFLE2(0,1)); + s1 = _mm_shuffle_pd(ss, sm, _MM_SHUFFLE2(0,1)); + _mm_storeu_pd((double*)dstdata, s0); + _mm_storeu_pd((double*)(dstdata+dststep), s1); + } + else + #endif + { + double t0, t1; + t0 = Sd(0,0)*d; + t1 = Sd(1,1)*d; + Dd(1,1) = t0; + Dd(0,0) = t1; + t0 = -Sd(0,1)*d; + t1 = -Sd(1,0)*d; + Dd(0,1) = t0; + Dd(1,0) = t1; + } + } + } + } + else if( n == 3 ) + { + if( type == CV_32FC1 ) + { + double d = det3(Sf); + + if( d != 0. ) + { + double t[12]; + + result = true; + d = 1./d; + t[0] = (((double)Sf(1,1) * Sf(2,2) - (double)Sf(1,2) * Sf(2,1)) * d); + t[1] = (((double)Sf(0,2) * Sf(2,1) - (double)Sf(0,1) * Sf(2,2)) * d); + t[2] = (((double)Sf(0,1) * Sf(1,2) - (double)Sf(0,2) * Sf(1,1)) * d); + + t[3] = (((double)Sf(1,2) * Sf(2,0) - (double)Sf(1,0) * Sf(2,2)) * d); + t[4] = (((double)Sf(0,0) * Sf(2,2) - (double)Sf(0,2) * Sf(2,0)) * d); + t[5] = (((double)Sf(0,2) * Sf(1,0) - (double)Sf(0,0) * Sf(1,2)) * d); + + t[6] = (((double)Sf(1,0) * Sf(2,1) - (double)Sf(1,1) * Sf(2,0)) * d); + t[7] = (((double)Sf(0,1) * Sf(2,0) - (double)Sf(0,0) * Sf(2,1)) * d); + t[8] = (((double)Sf(0,0) * Sf(1,1) - (double)Sf(0,1) * Sf(1,0)) * d); + + Df(0,0) = (float)t[0]; Df(0,1) = (float)t[1]; Df(0,2) = (float)t[2]; + Df(1,0) = (float)t[3]; Df(1,1) = (float)t[4]; Df(1,2) = (float)t[5]; + Df(2,0) = (float)t[6]; Df(2,1) = (float)t[7]; Df(2,2) = (float)t[8]; + } + } + else + { + double d = det3(Sd); + if( d != 0. ) + { + result = true; + d = 1./d; + double t[9]; + + t[0] = (Sd(1,1) * Sd(2,2) - Sd(1,2) * Sd(2,1)) * d; + t[1] = (Sd(0,2) * Sd(2,1) - Sd(0,1) * Sd(2,2)) * d; + t[2] = (Sd(0,1) * Sd(1,2) - Sd(0,2) * Sd(1,1)) * d; + + t[3] = (Sd(1,2) * Sd(2,0) - Sd(1,0) * Sd(2,2)) * d; + t[4] = (Sd(0,0) * Sd(2,2) - Sd(0,2) * Sd(2,0)) * d; + t[5] = (Sd(0,2) * Sd(1,0) - Sd(0,0) * Sd(1,2)) * d; + + t[6] = (Sd(1,0) * Sd(2,1) - Sd(1,1) * Sd(2,0)) * d; + t[7] = (Sd(0,1) * Sd(2,0) - Sd(0,0) * Sd(2,1)) * d; + t[8] = (Sd(0,0) * Sd(1,1) - Sd(0,1) * Sd(1,0)) * d; + + Dd(0,0) = t[0]; Dd(0,1) = t[1]; Dd(0,2) = t[2]; + Dd(1,0) = t[3]; Dd(1,1) = t[4]; Dd(1,2) = t[5]; + Dd(2,0) = t[6]; Dd(2,1) = t[7]; Dd(2,2) = t[8]; + } + } + } + else + { + assert( n == 1 ); + + if( type == CV_32FC1 ) + { + double d = Sf(0,0); + if( d != 0. ) + { + result = true; + Df(0,0) = (float)(1./d); + } + } + else + { + double d = Sd(0,0); + if( d != 0. ) + { + result = true; + Dd(0,0) = 1./d; + } + } + } + if( !result ) + dst = Scalar(0); + return result; + } + + int elem_size = CV_ELEM_SIZE(type); + AutoBuffer buf(n*n*elem_size); + Mat src1(n, n, type, (uchar*)buf); + src.copyTo(src1); + setIdentity(dst); + + if( method == DECOMP_LU && type == CV_32F ) + result = LU((float*)src1.data, src1.step, n, (float*)dst.data, dst.step, n) != 0; + else if( method == DECOMP_LU && type == CV_64F ) + result = LU((double*)src1.data, src1.step, n, (double*)dst.data, dst.step, n) != 0; + else if( method == DECOMP_CHOLESKY && type == CV_32F ) + result = Cholesky((float*)src1.data, src1.step, n, (float*)dst.data, dst.step, n); + else + result = Cholesky((double*)src1.data, src1.step, n, (double*)dst.data, dst.step, n); + + if( !result ) + dst = Scalar(0); + + return result; +} + + + +/****************************************************************************************\ +* Solving a linear system * +\****************************************************************************************/ + +bool cv::solve( InputArray _src, InputArray _src2arg, OutputArray _dst, int method ) +{ + bool result = true; + Mat src = _src.getMat(), _src2 = _src2arg.getMat(); + int type = src.type(); + bool is_normal = (method & DECOMP_NORMAL) != 0; + + CV_Assert( type == _src2.type() && (type == CV_32F || type == CV_64F) ); + + method &= ~DECOMP_NORMAL; + CV_Assert( (method != DECOMP_LU && method != DECOMP_CHOLESKY) || + is_normal || src.rows == src.cols ); + + // check case of a single equation and small matrix + if( (method == DECOMP_LU || method == DECOMP_CHOLESKY) && !is_normal && + src.rows <= 3 && src.rows == src.cols && _src2.cols == 1 ) + { + _dst.create( src.cols, _src2.cols, src.type() ); + Mat dst = _dst.getMat(); + + #define bf(y) ((float*)(bdata + y*src2step))[0] + #define bd(y) ((double*)(bdata + y*src2step))[0] + + uchar* srcdata = src.data; + uchar* bdata = _src2.data; + uchar* dstdata = dst.data; + size_t srcstep = src.step; + size_t src2step = _src2.step; + size_t dststep = dst.step; + + if( src.rows == 2 ) + { + if( type == CV_32FC1 ) + { + double d = det2(Sf); + if( d != 0. ) + { + double t; + d = 1./d; + t = (float)(((double)bf(0)*Sf(1,1) - (double)bf(1)*Sf(0,1))*d); + Df(1,0) = (float)(((double)bf(1)*Sf(0,0) - (double)bf(0)*Sf(1,0))*d); + Df(0,0) = (float)t; + } + else + result = false; + } + else + { + double d = det2(Sd); + if( d != 0. ) + { + double t; + d = 1./d; + t = (bd(0)*Sd(1,1) - bd(1)*Sd(0,1))*d; + Dd(1,0) = (bd(1)*Sd(0,0) - bd(0)*Sd(1,0))*d; + Dd(0,0) = t; + } + else + result = false; + } + } + else if( src.rows == 3 ) + { + if( type == CV_32FC1 ) + { + double d = det3(Sf); + if( d != 0. ) + { + float t[3]; + d = 1./d; + + t[0] = (float)(d* + (bf(0)*((double)Sf(1,1)*Sf(2,2) - (double)Sf(1,2)*Sf(2,1)) - + Sf(0,1)*((double)bf(1)*Sf(2,2) - (double)Sf(1,2)*bf(2)) + + Sf(0,2)*((double)bf(1)*Sf(2,1) - (double)Sf(1,1)*bf(2)))); + + t[1] = (float)(d* + (Sf(0,0)*(double)(bf(1)*Sf(2,2) - (double)Sf(1,2)*bf(2)) - + bf(0)*((double)Sf(1,0)*Sf(2,2) - (double)Sf(1,2)*Sf(2,0)) + + Sf(0,2)*((double)Sf(1,0)*bf(2) - (double)bf(1)*Sf(2,0)))); + + t[2] = (float)(d* + (Sf(0,0)*((double)Sf(1,1)*bf(2) - (double)bf(1)*Sf(2,1)) - + Sf(0,1)*((double)Sf(1,0)*bf(2) - (double)bf(1)*Sf(2,0)) + + bf(0)*((double)Sf(1,0)*Sf(2,1) - (double)Sf(1,1)*Sf(2,0)))); + + Df(0,0) = t[0]; + Df(1,0) = t[1]; + Df(2,0) = t[2]; + } + else + result = false; + } + else + { + double d = det3(Sd); + if( d != 0. ) + { + double t[9]; + + d = 1./d; + + t[0] = ((Sd(1,1) * Sd(2,2) - Sd(1,2) * Sd(2,1))*bd(0) + + (Sd(0,2) * Sd(2,1) - Sd(0,1) * Sd(2,2))*bd(1) + + (Sd(0,1) * Sd(1,2) - Sd(0,2) * Sd(1,1))*bd(2))*d; + + t[1] = ((Sd(1,2) * Sd(2,0) - Sd(1,0) * Sd(2,2))*bd(0) + + (Sd(0,0) * Sd(2,2) - Sd(0,2) * Sd(2,0))*bd(1) + + (Sd(0,2) * Sd(1,0) - Sd(0,0) * Sd(1,2))*bd(2))*d; + + t[2] = ((Sd(1,0) * Sd(2,1) - Sd(1,1) * Sd(2,0))*bd(0) + + (Sd(0,1) * Sd(2,0) - Sd(0,0) * Sd(2,1))*bd(1) + + (Sd(0,0) * Sd(1,1) - Sd(0,1) * Sd(1,0))*bd(2))*d; + + Dd(0,0) = t[0]; + Dd(1,0) = t[1]; + Dd(2,0) = t[2]; + } + else + result = false; + } + } + else + { + assert( src.rows == 1 ); + + if( type == CV_32FC1 ) + { + double d = Sf(0,0); + if( d != 0. ) + Df(0,0) = (float)(bf(0)/d); + else + result = false; + } + else + { + double d = Sd(0,0); + if( d != 0. ) + Dd(0,0) = (bd(0)/d); + else + result = false; + } + } + return result; + } + + if( method == DECOMP_QR ) + method = DECOMP_SVD; + + int m = src.rows, m_ = m, n = src.cols, nb = _src2.cols; + size_t esz = CV_ELEM_SIZE(type), bufsize = 0; + size_t vstep = alignSize(n*esz, 16); + size_t astep = method == DECOMP_SVD && !is_normal ? alignSize(m*esz, 16) : vstep; + AutoBuffer buffer; + + Mat src2 = _src2; + _dst.create( src.cols, src2.cols, src.type() ); + Mat dst = _dst.getMat(); + + if( m < n ) + CV_Error(CV_StsBadArg, "The function can not solve under-determined linear systems" ); + + if( m == n ) + is_normal = false; + else if( is_normal ) + { + m_ = n; + if( method == DECOMP_SVD ) + method = DECOMP_EIG; + } + + size_t asize = astep*(method == DECOMP_SVD || is_normal ? n : m); + bufsize += asize + 32; + + if( is_normal ) + bufsize += n*nb*esz; + + if( method == DECOMP_SVD || method == DECOMP_EIG ) + bufsize += n*5*esz + n*vstep + nb*sizeof(double) + 32; + + buffer.allocate(bufsize); + uchar* ptr = alignPtr((uchar*)buffer, 16); + + Mat a(m_, n, type, ptr, astep); + + if( is_normal ) + mulTransposed(src, a, true); + else if( method != DECOMP_SVD ) + src.copyTo(a); + else + { + a = Mat(n, m_, type, ptr, astep); + transpose(src, a); + } + ptr += asize; + + if( !is_normal ) + { + if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) + src2.copyTo(dst); + } + else + { + // a'*b + if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) + gemm( src, src2, 1, Mat(), 0, dst, GEMM_1_T ); + else + { + Mat tmp(n, nb, type, ptr); + ptr += n*nb*esz; + gemm( src, src2, 1, Mat(), 0, tmp, GEMM_1_T ); + src2 = tmp; + } + } + + if( method == DECOMP_LU ) + { + if( type == CV_32F ) + result = LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; + else + result = LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; + } + else if( method == DECOMP_CHOLESKY ) + { + if( type == CV_32F ) + result = Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); + else + result = Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); + } + else + { + ptr = alignPtr(ptr, 16); + Mat v(n, n, type, ptr, vstep), w(n, 1, type, ptr + vstep*n), u; + ptr += n*(vstep + esz); + + if( method == DECOMP_EIG ) + { + if( type == CV_32F ) + Jacobi(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, n, ptr); + else + Jacobi(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, n, ptr); + u = v; + } + else + { + if( type == CV_32F ) + JacobiSVD(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, m_, n); + else + JacobiSVD(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, m_, n); + u = a; + } + + if( type == CV_32F ) + { + SVBkSb(m_, n, w.ptr(), 0, u.ptr(), u.step, true, + v.ptr(), v.step, true, src2.ptr(), + src2.step, nb, dst.ptr(), dst.step, ptr); + } + else + { + SVBkSb(m_, n, w.ptr(), 0, u.ptr(), u.step, true, + v.ptr(), v.step, true, src2.ptr(), + src2.step, nb, dst.ptr(), dst.step, ptr); + } + result = true; + } + + if( !result ) + dst = Scalar(0); + + return result; +} + + +/////////////////// finding eigenvalues and eigenvectors of a symmetric matrix /////////////// + +bool cv::eigen( InputArray _src, bool computeEvects, OutputArray _evals, OutputArray _evects ) +{ + Mat src = _src.getMat(); + int type = src.type(); + int n = src.rows; + + CV_Assert( src.rows == src.cols ); + CV_Assert (type == CV_32F || type == CV_64F); + + Mat v; + if( computeEvects ) + { + _evects.create(n, n, type); + v = _evects.getMat(); + } + + size_t elemSize = src.elemSize(), astep = alignSize(n*elemSize, 16); + AutoBuffer buf(n*astep + n*5*elemSize + 32); + uchar* ptr = alignPtr((uchar*)buf, 16); + Mat a(n, n, type, ptr, astep), w(n, 1, type, ptr + astep*n); + ptr += astep*n + elemSize*n; + src.copyTo(a); + bool ok = type == CV_32F ? + Jacobi(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, n, ptr) : + Jacobi(a.ptr(), a.step, w.ptr(), v.ptr(), v.step, n, ptr); + + w.copyTo(_evals); + return ok; +} + +bool cv::eigen( InputArray src, OutputArray evals, int, int ) +{ + return eigen(src, false, evals, noArray()); +} + +bool cv::eigen( InputArray src, OutputArray evals, OutputArray evects, int, int) +{ + return eigen(src, true, evals, evects); +} + +namespace cv +{ + +static void _SVDcompute( InputArray _aarr, OutputArray _w, + OutputArray _u, OutputArray _vt, int flags ) +{ + Mat src = _aarr.getMat(); + int m = src.rows, n = src.cols; + int type = src.type(); + bool compute_uv = _u.needed() || _vt.needed(); + bool full_uv = (flags & SVD::FULL_UV) != 0; + + CV_Assert( type == CV_32F || type == CV_64F ); + + if( flags & SVD::NO_UV ) + { + _u.release(); + _vt.release(); + compute_uv = full_uv = false; + } + + bool at = false; + if( m < n ) + { + std::swap(m, n); + at = true; + } + + int urows = full_uv ? m : n; + size_t esz = src.elemSize(), astep = alignSize(m*esz, 16), vstep = alignSize(n*esz, 16); + AutoBuffer _buf(urows*astep + n*vstep + n*esz + 32); + uchar* buf = alignPtr((uchar*)_buf, 16); + Mat temp_a(n, m, type, buf, astep); + Mat temp_w(n, 1, type, buf + urows*astep); + Mat temp_u(urows, m, type, buf, astep), temp_v; + + if( compute_uv ) + temp_v = Mat(n, n, type, alignPtr(buf + urows*astep + n*esz, 16), vstep); + + if( urows > n ) + temp_u = Scalar::all(0); + + if( !at ) + transpose(src, temp_a); + else + src.copyTo(temp_a); + + if( type == CV_32F ) + { + JacobiSVD(temp_a.ptr(), temp_u.step, temp_w.ptr(), + temp_v.ptr(), temp_v.step, m, n, compute_uv ? urows : 0); + } + else + { + JacobiSVD(temp_a.ptr(), temp_u.step, temp_w.ptr(), + temp_v.ptr(), temp_v.step, m, n, compute_uv ? urows : 0); + } + temp_w.copyTo(_w); + if( compute_uv ) + { + if( !at ) + { + transpose(temp_u, _u); + temp_v.copyTo(_vt); + } + else + { + transpose(temp_v, _u); + temp_u.copyTo(_vt); + } + } +} + + +void SVD::compute( InputArray a, OutputArray w, OutputArray u, OutputArray vt, int flags ) +{ + _SVDcompute(a, w, u, vt, flags); +} + +void SVD::compute( InputArray a, OutputArray w, int flags ) +{ + _SVDcompute(a, w, noArray(), noArray(), flags); +} + +void SVD::backSubst( InputArray _w, InputArray _u, InputArray _vt, + InputArray _rhs, OutputArray _dst ) +{ + Mat w = _w.getMat(), u = _u.getMat(), vt = _vt.getMat(), rhs = _rhs.getMat(); + int type = w.type(), esz = (int)w.elemSize(); + int m = u.rows, n = vt.cols, nb = rhs.data ? rhs.cols : m, nm = std::min(m, n); + size_t wstep = w.rows == 1 ? (size_t)esz : w.cols == 1 ? (size_t)w.step : (size_t)w.step + esz; + AutoBuffer buffer(nb*sizeof(double) + 16); + CV_Assert( w.type() == u.type() && u.type() == vt.type() && u.data && vt.data && w.data ); + CV_Assert( u.cols >= nm && vt.rows >= nm && + (w.size() == Size(nm, 1) || w.size() == Size(1, nm) || w.size() == Size(vt.rows, u.cols)) ); + CV_Assert( rhs.data == 0 || (rhs.type() == type && rhs.rows == m) ); + + _dst.create( n, nb, type ); + Mat dst = _dst.getMat(); + if( type == CV_32F ) + SVBkSb(m, n, w.ptr(), wstep, u.ptr(), u.step, false, + vt.ptr(), vt.step, true, rhs.ptr(), rhs.step, nb, + dst.ptr(), dst.step, buffer); + else if( type == CV_64F ) + SVBkSb(m, n, w.ptr(), wstep, u.ptr(), u.step, false, + vt.ptr(), vt.step, true, rhs.ptr(), rhs.step, nb, + dst.ptr(), dst.step, buffer); + else + CV_Error( CV_StsUnsupportedFormat, "" ); +} + + +SVD& SVD::operator ()(InputArray a, int flags) +{ + _SVDcompute(a, w, u, vt, flags); + return *this; +} + + +void SVD::backSubst( InputArray rhs, OutputArray dst ) const +{ + backSubst( w, u, vt, rhs, dst ); +} + +} + + +void cv::SVDecomp(InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags) +{ + SVD::compute(src, w, u, vt, flags); +} + +void cv::SVBackSubst(InputArray w, InputArray u, InputArray vt, InputArray rhs, OutputArray dst) +{ + SVD::backSubst(w, u, vt, rhs, dst); +} + + +CV_IMPL double +cvDet( const CvArr* arr ) +{ + if( CV_IS_MAT(arr) && ((CvMat*)arr)->rows <= 3 ) + { + CvMat* mat = (CvMat*)arr; + int type = CV_MAT_TYPE(mat->type); + int rows = mat->rows; + uchar* m = mat->data.ptr; + int step = mat->step; + CV_Assert( rows == mat->cols ); + + #define Mf(y, x) ((float*)(m + y*step))[x] + #define Md(y, x) ((double*)(m + y*step))[x] + + if( type == CV_32F ) + { + if( rows == 2 ) + return det2(Mf); + if( rows == 3 ) + return det3(Mf); + } + else if( type == CV_64F ) + { + if( rows == 2 ) + return det2(Md); + if( rows == 3 ) + return det3(Md); + } + return cv::determinant(cv::Mat(mat)); + } + return cv::determinant(cv::cvarrToMat(arr)); +} + + +CV_IMPL double +cvInvert( const CvArr* srcarr, CvArr* dstarr, int method ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.type() == dst.type() && src.rows == dst.cols && src.cols == dst.rows ); + return cv::invert( src, dst, method == CV_CHOLESKY ? cv::DECOMP_CHOLESKY : + method == CV_SVD ? cv::DECOMP_SVD : + method == CV_SVD_SYM ? cv::DECOMP_EIG : cv::DECOMP_LU ); +} + + +CV_IMPL int +cvSolve( const CvArr* Aarr, const CvArr* barr, CvArr* xarr, int method ) +{ + cv::Mat A = cv::cvarrToMat(Aarr), b = cv::cvarrToMat(barr), x = cv::cvarrToMat(xarr); + + CV_Assert( A.type() == x.type() && A.cols == x.rows && x.cols == b.cols ); + bool is_normal = (method & CV_NORMAL) != 0; + method &= ~CV_NORMAL; + return cv::solve( A, b, x, (method == CV_CHOLESKY ? cv::DECOMP_CHOLESKY : + method == CV_SVD ? cv::DECOMP_SVD : + method == CV_SVD_SYM ? cv::DECOMP_EIG : + A.rows > A.cols ? cv::DECOMP_QR : cv::DECOMP_LU) + (is_normal ? cv::DECOMP_NORMAL : 0) ); +} + + +CV_IMPL void +cvEigenVV( CvArr* srcarr, CvArr* evectsarr, CvArr* evalsarr, double, + int lowindex, int highindex) +{ + cv::Mat src = cv::cvarrToMat(srcarr), evals0 = cv::cvarrToMat(evalsarr), evals = evals0; + if( evectsarr ) + { + cv::Mat evects0 = cv::cvarrToMat(evectsarr), evects = evects0; + eigen(src, evals, evects, lowindex, highindex); + if( evects0.data != evects.data ) + { + uchar* p = evects0.data; + evects.convertTo(evects0, evects0.type()); + CV_Assert( p == evects0.data ); + } + } + else + eigen(src, evals, lowindex, highindex); + if( evals0.data != evals.data ) + { + uchar* p = evals0.data; + if( evals0.size() == evals.size() ) + evals.convertTo(evals0, evals0.type()); + else if( evals0.type() == evals.type() ) + cv::transpose(evals, evals0); + else + cv::Mat(evals.t()).convertTo(evals0, evals0.type()); + CV_Assert( p == evals0.data ); + } +} + + +CV_IMPL void +cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags ) +{ + cv::Mat a = cv::cvarrToMat(aarr), w = cv::cvarrToMat(warr), u, v; + int m = a.rows, n = a.cols, type = a.type(), mn = std::max(m, n), nm = std::min(m, n); + + CV_Assert( w.type() == type && + (w.size() == cv::Size(nm,1) || w.size() == cv::Size(1, nm) || + w.size() == cv::Size(nm, nm) || w.size() == cv::Size(n, m)) ); + + cv::SVD svd; + + if( w.size() == cv::Size(nm, 1) ) + svd.w = cv::Mat(nm, 1, type, w.data ); + else if( w.isContinuous() ) + svd.w = w; + + if( uarr ) + { + u = cv::cvarrToMat(uarr); + CV_Assert( u.type() == type ); + svd.u = u; + } + + if( varr ) + { + v = cv::cvarrToMat(varr); + CV_Assert( v.type() == type ); + svd.vt = v; + } + + svd(a, ((flags & CV_SVD_MODIFY_A) ? cv::SVD::MODIFY_A : 0) | + ((!svd.u.data && !svd.vt.data) ? cv::SVD::NO_UV : 0) | + ((m != n && (svd.u.size() == cv::Size(mn, mn) || + svd.vt.size() == cv::Size(mn, mn))) ? cv::SVD::FULL_UV : 0)); + + if( u.data ) + { + if( flags & CV_SVD_U_T ) + cv::transpose( svd.u, u ); + else if( u.data != svd.u.data ) + { + CV_Assert( u.size() == svd.u.size() ); + svd.u.copyTo(u); + } + } + + if( v.data ) + { + if( !(flags & CV_SVD_V_T) ) + cv::transpose( svd.vt, v ); + else if( v.data != svd.vt.data ) + { + CV_Assert( v.size() == svd.vt.size() ); + svd.vt.copyTo(v); + } + } + + if( w.data != svd.w.data ) + { + if( w.size() == svd.w.size() ) + svd.w.copyTo(w); + else + { + w = cv::Scalar(0); + cv::Mat wd = w.diag(); + svd.w.copyTo(wd); + } + } +} + + +CV_IMPL void +cvSVBkSb( const CvArr* warr, const CvArr* uarr, + const CvArr* varr, const CvArr* rhsarr, + CvArr* dstarr, int flags ) +{ + cv::Mat w = cv::cvarrToMat(warr), u = cv::cvarrToMat(uarr), + v = cv::cvarrToMat(varr), rhs, + dst = cv::cvarrToMat(dstarr), dst0 = dst; + if( flags & CV_SVD_U_T ) + { + cv::Mat tmp; + transpose(u, tmp); + u = tmp; + } + if( !(flags & CV_SVD_V_T) ) + { + cv::Mat tmp; + transpose(v, tmp); + v = tmp; + } + if( rhsarr ) + rhs = cv::cvarrToMat(rhsarr); + + cv::SVD::backSubst(w, u, v, rhs, dst); + CV_Assert( dst.data == dst0.data ); +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/mathfuncs.cpp diffimg-2.0.0/3rdparty/opencv/core/src/mathfuncs.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/mathfuncs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/mathfuncs.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2559 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + + +namespace cv +{ + +static const int MAX_BLOCK_SIZE = 1024; +typedef void (*MathFunc)(const void* src, void* dst, int len); + +static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI); +static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI); +static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI); +static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI); + +float fastAtan2( float y, float x ) +{ + float ax = std::abs(x), ay = std::abs(y); + float a, c, c2; + if( ax >= ay ) + { + c = ay/(ax + (float)DBL_EPSILON); + c2 = c*c; + a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + else + { + c = ax/(ay + (float)DBL_EPSILON); + c2 = c*c; + a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + if( x < 0 ) + a = 180.f - a; + if( y < 0 ) + a = 360.f - a; + return a; +} + +static void FastAtan2_32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees=true ) +{ + int i = 0; + float scale = angleInDegrees ? 1 : (float)(CV_PI/180); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::FastAtan2_32f(Y, X, angle, len, scale)) + return; +#endif + +#if CV_SSE2 + if( USE_SSE2 ) + { + Cv32suf iabsmask; iabsmask.i = 0x7fffffff; + __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_set1_ps(iabsmask.f); + __m128 _90 = _mm_set1_ps(90.f), _180 = _mm_set1_ps(180.f), _360 = _mm_set1_ps(360.f); + __m128 z = _mm_setzero_ps(), scale4 = _mm_set1_ps(scale); + __m128 p1 = _mm_set1_ps(atan2_p1), p3 = _mm_set1_ps(atan2_p3); + __m128 p5 = _mm_set1_ps(atan2_p5), p7 = _mm_set1_ps(atan2_p7); + + for( ; i <= len - 4; i += 4 ) + { + __m128 x = _mm_loadu_ps(X + i), y = _mm_loadu_ps(Y + i); + __m128 ax = _mm_and_ps(x, absmask), ay = _mm_and_ps(y, absmask); + __m128 mask = _mm_cmplt_ps(ax, ay); + __m128 tmin = _mm_min_ps(ax, ay), tmax = _mm_max_ps(ax, ay); + __m128 c = _mm_div_ps(tmin, _mm_add_ps(tmax, eps)); + __m128 c2 = _mm_mul_ps(c, c); + __m128 a = _mm_mul_ps(c2, p7); + a = _mm_mul_ps(_mm_add_ps(a, p5), c2); + a = _mm_mul_ps(_mm_add_ps(a, p3), c2); + a = _mm_mul_ps(_mm_add_ps(a, p1), c); + + __m128 b = _mm_sub_ps(_90, a); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + b = _mm_sub_ps(_180, a); + mask = _mm_cmplt_ps(x, z); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + b = _mm_sub_ps(_360, a); + mask = _mm_cmplt_ps(y, z); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + a = _mm_mul_ps(a, scale4); + _mm_storeu_ps(angle + i, a); + } + } +#endif + + for( ; i < len; i++ ) + { + float x = X[i], y = Y[i]; + float ax = std::abs(x), ay = std::abs(y); + float a, c, c2; + if( ax >= ay ) + { + c = ay/(ax + (float)DBL_EPSILON); + c2 = c*c; + a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + else + { + c = ax/(ay + (float)DBL_EPSILON); + c2 = c*c; + a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + if( x < 0 ) + a = 180.f - a; + if( y < 0 ) + a = 360.f - a; + angle[i] = (float)(a*scale); + } +} + + +/* ************************************************************************** *\ + Fast cube root by Ken Turkowski + (http://www.worldserver.com/turk/computergraphics/papers.html) +\* ************************************************************************** */ +float cubeRoot( float value ) +{ + float fr; + Cv32suf v, m; + int ix, s; + int ex, shx; + + v.f = value; + ix = v.i & 0x7fffffff; + s = v.i & 0x80000000; + ex = (ix >> 23) - 127; + shx = ex % 3; + shx -= shx >= 0 ? 3 : 0; + ex = (ex - shx) / 3; /* exponent of cube root */ + v.i = (ix & ((1<<23)-1)) | ((shx + 127)<<23); + fr = v.f; + + /* 0.125 <= fr < 1.0 */ + /* Use quartic rational polynomial with error < 2^(-24) */ + fr = (float)(((((45.2548339756803022511987494 * fr + + 192.2798368355061050458134625) * fr + + 119.1654824285581628956914143) * fr + + 13.43250139086239872172837314) * fr + + 0.1636161226585754240958355063)/ + ((((14.80884093219134573786480845 * fr + + 151.9714051044435648658557668) * fr + + 168.5254414101568283957668343) * fr + + 33.9905941350215598754191872) * fr + + 1.0)); + + /* fr *= 2^ex * sign */ + m.f = value; + v.f = fr; + v.i = (v.i + (ex << 23) + s) & (m.i*2 != 0 ? -1 : 0); + return v.f; +} + +static void Magnitude_32f(const float* x, const float* y, float* mag, int len) +{ + int i = 0; + +#if CV_SSE + if( USE_SSE2 ) + { + for( ; i <= len - 8; i += 8 ) + { + __m128 x0 = _mm_loadu_ps(x + i), x1 = _mm_loadu_ps(x + i + 4); + __m128 y0 = _mm_loadu_ps(y + i), y1 = _mm_loadu_ps(y + i + 4); + x0 = _mm_add_ps(_mm_mul_ps(x0, x0), _mm_mul_ps(y0, y0)); + x1 = _mm_add_ps(_mm_mul_ps(x1, x1), _mm_mul_ps(y1, y1)); + x0 = _mm_sqrt_ps(x0); x1 = _mm_sqrt_ps(x1); + _mm_storeu_ps(mag + i, x0); _mm_storeu_ps(mag + i + 4, x1); + } + } +#endif + + for( ; i < len; i++ ) + { + float x0 = x[i], y0 = y[i]; + mag[i] = std::sqrt(x0*x0 + y0*y0); + } +} + +static void Magnitude_64f(const double* x, const double* y, double* mag, int len) +{ + int i = 0; + +#if CV_SSE2 + if( USE_SSE2 ) + { + for( ; i <= len - 4; i += 4 ) + { + __m128d x0 = _mm_loadu_pd(x + i), x1 = _mm_loadu_pd(x + i + 2); + __m128d y0 = _mm_loadu_pd(y + i), y1 = _mm_loadu_pd(y + i + 2); + x0 = _mm_add_pd(_mm_mul_pd(x0, x0), _mm_mul_pd(y0, y0)); + x1 = _mm_add_pd(_mm_mul_pd(x1, x1), _mm_mul_pd(y1, y1)); + x0 = _mm_sqrt_pd(x0); x1 = _mm_sqrt_pd(x1); + _mm_storeu_pd(mag + i, x0); _mm_storeu_pd(mag + i + 2, x1); + } + } +#endif + + for( ; i < len; i++ ) + { + double x0 = x[i], y0 = y[i]; + mag[i] = std::sqrt(x0*x0 + y0*y0); + } +} + + +static void InvSqrt_32f(const float* src, float* dst, int len) +{ + int i = 0; + +#if CV_SSE + if( USE_SSE2 ) + { + __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f); + if( (((size_t)src|(size_t)dst) & 15) == 0 ) + for( ; i <= len - 8; i += 8 ) + { + __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4); + __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5); + t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1); + t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0))); + t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1))); + _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1); + } + else + for( ; i <= len - 8; i += 8 ) + { + __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4); + __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5); + t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1); + t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0))); + t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1))); + _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1); + } + } +#endif + + for( ; i < len; i++ ) + dst[i] = 1/std::sqrt(src[i]); +} + + +static void InvSqrt_64f(const double* src, double* dst, int len) +{ + for( int i = 0; i < len; i++ ) + dst[i] = 1/std::sqrt(src[i]); +} + + +static void Sqrt_32f(const float* src, float* dst, int len) +{ + int i = 0; + +#if CV_SSE + if( USE_SSE2 ) + { + if( (((size_t)src|(size_t)dst) & 15) == 0 ) + for( ; i <= len - 8; i += 8 ) + { + __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4); + t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1); + _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1); + } + else + for( ; i <= len - 8; i += 8 ) + { + __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4); + t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1); + _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1); + } + } +#endif + + for( ; i < len; i++ ) + dst[i] = std::sqrt(src[i]); +} + + +static void Sqrt_64f(const double* src, double* dst, int len) +{ + int i = 0; + +#if CV_SSE2 + if( USE_SSE2 ) + { + if( (((size_t)src|(size_t)dst) & 15) == 0 ) + for( ; i <= len - 4; i += 4 ) + { + __m128d t0 = _mm_load_pd(src + i), t1 = _mm_load_pd(src + i + 2); + t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1); + _mm_store_pd(dst + i, t0); _mm_store_pd(dst + i + 2, t1); + } + else + for( ; i <= len - 4; i += 4 ) + { + __m128d t0 = _mm_loadu_pd(src + i), t1 = _mm_loadu_pd(src + i + 2); + t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1); + _mm_storeu_pd(dst + i, t0); _mm_storeu_pd(dst + i + 2, t1); + } + } +#endif + + for( ; i < len; i++ ) + dst[i] = std::sqrt(src[i]); +} + + +/****************************************************************************************\ +* Cartezian -> Polar * +\****************************************************************************************/ + +void magnitude( InputArray src1, InputArray src2, OutputArray dst ) +{ + Mat X = src1.getMat(), Y = src2.getMat(); + int type = X.type(), depth = X.depth(), cn = X.channels(); + CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F)); + dst.create(X.dims, X.size, X.type()); + Mat Mag = dst.getMat(); + + const Mat* arrays[] = {&X, &Y, &Mag, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size*cn; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + if( depth == CV_32F ) + { + const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; + float *mag = (float*)ptrs[2]; + Magnitude_32f( x, y, mag, len ); + } + else + { + const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; + double *mag = (double*)ptrs[2]; + Magnitude_64f( x, y, mag, len ); + } + } +} + + +void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegrees ) +{ + Mat X = src1.getMat(), Y = src2.getMat(); + int type = X.type(), depth = X.depth(), cn = X.channels(); + CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F)); + dst.create( X.dims, X.size, type ); + Mat Angle = dst.getMat(); + + const Mat* arrays[] = {&X, &Y, &Angle, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + cv::AutoBuffer _buf; + float* buf[2] = {0, 0}; + int j, k, total = (int)(it.size*cn), blockSize = total; + size_t esz1 = X.elemSize1(); + + if( depth == CV_64F ) + { + blockSize = std::min(blockSize, ((BLOCK_SIZE+cn-1)/cn)*cn); + _buf.allocate(blockSize*2); + buf[0] = _buf; + buf[1] = buf[0] + blockSize; + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int len = std::min(total - j, blockSize); + if( depth == CV_32F ) + { + const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; + float *angle = (float*)ptrs[2]; + FastAtan2_32f( y, x, angle, len, angleInDegrees ); + } + else + { + const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; + double *angle = (double*)ptrs[2]; + for( k = 0; k < len; k++ ) + { + buf[0][k] = (float)x[k]; + buf[1][k] = (float)y[k]; + } + + FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees ); + for( k = 0; k < len; k++ ) + angle[k] = buf[0][k]; + } + ptrs[0] += len*esz1; + ptrs[1] += len*esz1; + ptrs[2] += len*esz1; + } + } +} + + +void cartToPolar( InputArray src1, InputArray src2, + OutputArray dst1, OutputArray dst2, bool angleInDegrees ) +{ + Mat X = src1.getMat(), Y = src2.getMat(); + int type = X.type(), depth = X.depth(), cn = X.channels(); + CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F)); + dst1.create( X.dims, X.size, type ); + dst2.create( X.dims, X.size, type ); + Mat Mag = dst1.getMat(), Angle = dst2.getMat(); + + const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0}; + uchar* ptrs[4]; + NAryMatIterator it(arrays, ptrs); + cv::AutoBuffer _buf; + float* buf[2] = {0, 0}; + int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn); + size_t esz1 = X.elemSize1(); + + if( depth == CV_64F ) + { + _buf.allocate(blockSize*2); + buf[0] = _buf; + buf[1] = buf[0] + blockSize; + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int len = std::min(total - j, blockSize); + if( depth == CV_32F ) + { + const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; + float *mag = (float*)ptrs[2], *angle = (float*)ptrs[3]; + Magnitude_32f( x, y, mag, len ); + FastAtan2_32f( y, x, angle, len, angleInDegrees ); + } + else + { + const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; + double *angle = (double*)ptrs[3]; + + Magnitude_64f(x, y, (double*)ptrs[2], len); + for( k = 0; k < len; k++ ) + { + buf[0][k] = (float)x[k]; + buf[1][k] = (float)y[k]; + } + + FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees ); + for( k = 0; k < len; k++ ) + angle[k] = buf[0][k]; + } + ptrs[0] += len*esz1; + ptrs[1] += len*esz1; + ptrs[2] += len*esz1; + ptrs[3] += len*esz1; + } + } +} + + +/****************************************************************************************\ +* Polar -> Cartezian * +\****************************************************************************************/ + +static void SinCos_32f( const float *angle, float *sinval, float* cosval, + int len, int angle_in_degrees ) +{ + const int N = 64; + + static const double sin_table[] = + { + 0.00000000000000000000, 0.09801714032956060400, + 0.19509032201612825000, 0.29028467725446233000, + 0.38268343236508978000, 0.47139673682599764000, + 0.55557023301960218000, 0.63439328416364549000, + 0.70710678118654746000, 0.77301045336273699000, + 0.83146961230254524000, 0.88192126434835494000, + 0.92387953251128674000, 0.95694033573220894000, + 0.98078528040323043000, 0.99518472667219682000, + 1.00000000000000000000, 0.99518472667219693000, + 0.98078528040323043000, 0.95694033573220894000, + 0.92387953251128674000, 0.88192126434835505000, + 0.83146961230254546000, 0.77301045336273710000, + 0.70710678118654757000, 0.63439328416364549000, + 0.55557023301960218000, 0.47139673682599786000, + 0.38268343236508989000, 0.29028467725446239000, + 0.19509032201612861000, 0.09801714032956082600, + 0.00000000000000012246, -0.09801714032956059000, + -0.19509032201612836000, -0.29028467725446211000, + -0.38268343236508967000, -0.47139673682599764000, + -0.55557023301960196000, -0.63439328416364527000, + -0.70710678118654746000, -0.77301045336273666000, + -0.83146961230254524000, -0.88192126434835494000, + -0.92387953251128652000, -0.95694033573220882000, + -0.98078528040323032000, -0.99518472667219693000, + -1.00000000000000000000, -0.99518472667219693000, + -0.98078528040323043000, -0.95694033573220894000, + -0.92387953251128663000, -0.88192126434835505000, + -0.83146961230254546000, -0.77301045336273688000, + -0.70710678118654768000, -0.63439328416364593000, + -0.55557023301960218000, -0.47139673682599792000, + -0.38268343236509039000, -0.29028467725446250000, + -0.19509032201612872000, -0.09801714032956050600, + }; + + static const double k2 = (2*CV_PI)/N; + + static const double sin_a0 = -0.166630293345647*k2*k2*k2; + static const double sin_a2 = k2; + + static const double cos_a0 = -0.499818138450326*k2*k2; + /*static const double cos_a2 = 1;*/ + + double k1; + int i; + + if( !angle_in_degrees ) + k1 = N/(2*CV_PI); + else + k1 = N/360.; + + for( i = 0; i < len; i++ ) + { + double t = angle[i]*k1; + int it = cvRound(t); + t -= it; + int sin_idx = it & (N - 1); + int cos_idx = (N/4 - sin_idx) & (N - 1); + + double sin_b = (sin_a0*t*t + sin_a2)*t; + double cos_b = cos_a0*t*t + 1; + + double sin_a = sin_table[sin_idx]; + double cos_a = sin_table[cos_idx]; + + double sin_val = sin_a*cos_b + cos_a*sin_b; + double cos_val = cos_a*cos_b - sin_a*sin_b; + + sinval[i] = (float)sin_val; + cosval[i] = (float)cos_val; + } +} + + +void polarToCart( InputArray src1, InputArray src2, + OutputArray dst1, OutputArray dst2, bool angleInDegrees ) +{ + Mat Mag = src1.getMat(), Angle = src2.getMat(); + int type = Angle.type(), depth = Angle.depth(), cn = Angle.channels(); + CV_Assert( Mag.empty() || (Angle.size == Mag.size && type == Mag.type() && (depth == CV_32F || depth == CV_64F))); + dst1.create( Angle.dims, Angle.size, type ); + dst2.create( Angle.dims, Angle.size, type ); + Mat X = dst1.getMat(), Y = dst2.getMat(); + + const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0}; + uchar* ptrs[4]; + NAryMatIterator it(arrays, ptrs); + cv::AutoBuffer _buf; + float* buf[2] = {0, 0}; + int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn); + size_t esz1 = Angle.elemSize1(); + + if( depth == CV_64F ) + { + _buf.allocate(blockSize*2); + buf[0] = _buf; + buf[1] = buf[0] + blockSize; + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int len = std::min(total - j, blockSize); + if( depth == CV_32F ) + { + const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1]; + float *x = (float*)ptrs[2], *y = (float*)ptrs[3]; + + SinCos_32f( angle, y, x, len, angleInDegrees ); + if( mag ) + for( k = 0; k < len; k++ ) + { + float m = mag[k]; + x[k] *= m; y[k] *= m; + } + } + else + { + const double *mag = (const double*)ptrs[0], *angle = (const double*)ptrs[1]; + double *x = (double*)ptrs[2], *y = (double*)ptrs[3]; + + for( k = 0; k < len; k++ ) + buf[0][k] = (float)angle[k]; + + SinCos_32f( buf[0], buf[1], buf[0], len, angleInDegrees ); + if( mag ) + for( k = 0; k < len; k++ ) + { + double m = mag[k]; + x[k] = buf[0][k]*m; y[k] = buf[1][k]*m; + } + else + for( k = 0; k < len; k++ ) + { + x[k] = buf[0][k]; y[k] = buf[1][k]; + } + } + + if( ptrs[0] ) + ptrs[0] += len*esz1; + ptrs[1] += len*esz1; + ptrs[2] += len*esz1; + ptrs[3] += len*esz1; + } + } +} + +/****************************************************************************************\ +* E X P * +\****************************************************************************************/ + +typedef union +{ + struct { +#if ( defined( WORDS_BIGENDIAN ) && !defined( OPENCV_UNIVERSAL_BUILD ) ) || defined( __BIG_ENDIAN__ ) + int hi; + int lo; +#else + int lo; + int hi; +#endif + } i; + double d; +} +DBLINT; + +#ifndef HAVE_IPP + +#define EXPTAB_SCALE 6 +#define EXPTAB_MASK ((1 << EXPTAB_SCALE) - 1) + +#define EXPPOLY_32F_A0 .9670371139572337719125840413672004409288e-2 + +static const double expTab[] = { + 1.0 * EXPPOLY_32F_A0, + 1.0108892860517004600204097905619 * EXPPOLY_32F_A0, + 1.0218971486541166782344801347833 * EXPPOLY_32F_A0, + 1.0330248790212284225001082839705 * EXPPOLY_32F_A0, + 1.0442737824274138403219664787399 * EXPPOLY_32F_A0, + 1.0556451783605571588083413251529 * EXPPOLY_32F_A0, + 1.0671404006768236181695211209928 * EXPPOLY_32F_A0, + 1.0787607977571197937406800374385 * EXPPOLY_32F_A0, + 1.0905077326652576592070106557607 * EXPPOLY_32F_A0, + 1.1023825833078409435564142094256 * EXPPOLY_32F_A0, + 1.1143867425958925363088129569196 * EXPPOLY_32F_A0, + 1.126521618608241899794798643787 * EXPPOLY_32F_A0, + 1.1387886347566916537038302838415 * EXPPOLY_32F_A0, + 1.151189229952982705817759635202 * EXPPOLY_32F_A0, + 1.1637248587775775138135735990922 * EXPPOLY_32F_A0, + 1.1763969916502812762846457284838 * EXPPOLY_32F_A0, + 1.1892071150027210667174999705605 * EXPPOLY_32F_A0, + 1.2021567314527031420963969574978 * EXPPOLY_32F_A0, + 1.2152473599804688781165202513388 * EXPPOLY_32F_A0, + 1.2284805361068700056940089577928 * EXPPOLY_32F_A0, + 1.2418578120734840485936774687266 * EXPPOLY_32F_A0, + 1.2553807570246910895793906574423 * EXPPOLY_32F_A0, + 1.2690509571917332225544190810323 * EXPPOLY_32F_A0, + 1.2828700160787782807266697810215 * EXPPOLY_32F_A0, + 1.2968395546510096659337541177925 * EXPPOLY_32F_A0, + 1.3109612115247643419229917863308 * EXPPOLY_32F_A0, + 1.3252366431597412946295370954987 * EXPPOLY_32F_A0, + 1.3396675240533030053600306697244 * EXPPOLY_32F_A0, + 1.3542555469368927282980147401407 * EXPPOLY_32F_A0, + 1.3690024229745906119296011329822 * EXPPOLY_32F_A0, + 1.3839098819638319548726595272652 * EXPPOLY_32F_A0, + 1.3989796725383111402095281367152 * EXPPOLY_32F_A0, + 1.4142135623730950488016887242097 * EXPPOLY_32F_A0, + 1.4296133383919700112350657782751 * EXPPOLY_32F_A0, + 1.4451808069770466200370062414717 * EXPPOLY_32F_A0, + 1.4609177941806469886513028903106 * EXPPOLY_32F_A0, + 1.476826145939499311386907480374 * EXPPOLY_32F_A0, + 1.4929077282912648492006435314867 * EXPPOLY_32F_A0, + 1.5091644275934227397660195510332 * EXPPOLY_32F_A0, + 1.5255981507445383068512536895169 * EXPPOLY_32F_A0, + 1.5422108254079408236122918620907 * EXPPOLY_32F_A0, + 1.5590044002378369670337280894749 * EXPPOLY_32F_A0, + 1.5759808451078864864552701601819 * EXPPOLY_32F_A0, + 1.5931421513422668979372486431191 * EXPPOLY_32F_A0, + 1.6104903319492543081795206673574 * EXPPOLY_32F_A0, + 1.628027421857347766848218522014 * EXPPOLY_32F_A0, + 1.6457554781539648445187567247258 * EXPPOLY_32F_A0, + 1.6636765803267364350463364569764 * EXPPOLY_32F_A0, + 1.6817928305074290860622509524664 * EXPPOLY_32F_A0, + 1.7001063537185234695013625734975 * EXPPOLY_32F_A0, + 1.7186192981224779156293443764563 * EXPPOLY_32F_A0, + 1.7373338352737062489942020818722 * EXPPOLY_32F_A0, + 1.7562521603732994831121606193753 * EXPPOLY_32F_A0, + 1.7753764925265212525505592001993 * EXPPOLY_32F_A0, + 1.7947090750031071864277032421278 * EXPPOLY_32F_A0, + 1.8142521755003987562498346003623 * EXPPOLY_32F_A0, + 1.8340080864093424634870831895883 * EXPPOLY_32F_A0, + 1.8539791250833855683924530703377 * EXPPOLY_32F_A0, + 1.8741676341102999013299989499544 * EXPPOLY_32F_A0, + 1.8945759815869656413402186534269 * EXPPOLY_32F_A0, + 1.9152065613971472938726112702958 * EXPPOLY_32F_A0, + 1.9360617934922944505980559045667 * EXPPOLY_32F_A0, + 1.9571441241754002690183222516269 * EXPPOLY_32F_A0, + 1.9784560263879509682582499181312 * EXPPOLY_32F_A0, +}; + + +// the code below uses _mm_cast* intrinsics, which are not avialable on VS2005 +#if (defined _MSC_VER && _MSC_VER < 1500) || \ + (!defined __APPLE__ && defined __GNUC__ && __GNUC__*100 + __GNUC_MINOR__ < 402) +#undef CV_SSE2 +#define CV_SSE2 0 +#endif + +static const double exp_prescale = 1.4426950408889634073599246810019 * (1 << EXPTAB_SCALE); +static const double exp_postscale = 1./(1 << EXPTAB_SCALE); +static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < 3000 + +static void Exp_32f( const float *_x, float *y, int n ) +{ + static const float + A4 = (float)(1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0), + A3 = (float)(.6931471805521448196800669615864773144641 / EXPPOLY_32F_A0), + A2 = (float)(.2402265109513301490103372422686535526573 / EXPPOLY_32F_A0), + A1 = (float)(.5550339366753125211915322047004666939128e-1 / EXPPOLY_32F_A0); + +#undef EXPPOLY +#define EXPPOLY(x) \ + (((((x) + A1)*(x) + A2)*(x) + A3)*(x) + A4) + + int i = 0; + const Cv32suf* x = (const Cv32suf*)_x; + Cv32suf buf[4]; + +#if CV_SSE2 + if( n >= 8 && USE_SSE2 ) + { + static const __m128d prescale2 = _mm_set1_pd(exp_prescale); + static const __m128 postscale4 = _mm_set1_ps((float)exp_postscale); + static const __m128 maxval4 = _mm_set1_ps((float)(exp_max_val/exp_prescale)); + static const __m128 minval4 = _mm_set1_ps((float)(-exp_max_val/exp_prescale)); + + static const __m128 mA1 = _mm_set1_ps(A1); + static const __m128 mA2 = _mm_set1_ps(A2); + static const __m128 mA3 = _mm_set1_ps(A3); + static const __m128 mA4 = _mm_set1_ps(A4); + bool y_aligned = (size_t)(void*)y % 16 == 0; + + ushort CV_DECL_ALIGNED(16) tab_idx[8]; + + for( ; i <= n - 8; i += 8 ) + { + __m128 xf0, xf1; + xf0 = _mm_loadu_ps(&x[i].f); + xf1 = _mm_loadu_ps(&x[i+4].f); + __m128i xi0, xi1, xi2, xi3; + + xf0 = _mm_min_ps(_mm_max_ps(xf0, minval4), maxval4); + xf1 = _mm_min_ps(_mm_max_ps(xf1, minval4), maxval4); + + __m128d xd0 = _mm_cvtps_pd(xf0); + __m128d xd2 = _mm_cvtps_pd(_mm_movehl_ps(xf0, xf0)); + __m128d xd1 = _mm_cvtps_pd(xf1); + __m128d xd3 = _mm_cvtps_pd(_mm_movehl_ps(xf1, xf1)); + + xd0 = _mm_mul_pd(xd0, prescale2); + xd2 = _mm_mul_pd(xd2, prescale2); + xd1 = _mm_mul_pd(xd1, prescale2); + xd3 = _mm_mul_pd(xd3, prescale2); + + xi0 = _mm_cvtpd_epi32(xd0); + xi2 = _mm_cvtpd_epi32(xd2); + + xi1 = _mm_cvtpd_epi32(xd1); + xi3 = _mm_cvtpd_epi32(xd3); + + xd0 = _mm_sub_pd(xd0, _mm_cvtepi32_pd(xi0)); + xd2 = _mm_sub_pd(xd2, _mm_cvtepi32_pd(xi2)); + xd1 = _mm_sub_pd(xd1, _mm_cvtepi32_pd(xi1)); + xd3 = _mm_sub_pd(xd3, _mm_cvtepi32_pd(xi3)); + + xf0 = _mm_movelh_ps(_mm_cvtpd_ps(xd0), _mm_cvtpd_ps(xd2)); + xf1 = _mm_movelh_ps(_mm_cvtpd_ps(xd1), _mm_cvtpd_ps(xd3)); + + xf0 = _mm_mul_ps(xf0, postscale4); + xf1 = _mm_mul_ps(xf1, postscale4); + + xi0 = _mm_unpacklo_epi64(xi0, xi2); + xi1 = _mm_unpacklo_epi64(xi1, xi3); + xi0 = _mm_packs_epi32(xi0, xi1); + + _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi16(EXPTAB_MASK))); + + xi0 = _mm_add_epi16(_mm_srai_epi16(xi0, EXPTAB_SCALE), _mm_set1_epi16(127)); + xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(255)); + xi1 = _mm_unpackhi_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); + + __m128d yd0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); + __m128d yd1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); + __m128d yd2 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[4]), _mm_load_sd(expTab + tab_idx[5])); + __m128d yd3 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[6]), _mm_load_sd(expTab + tab_idx[7])); + + __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); + __m128 yf1 = _mm_movelh_ps(_mm_cvtpd_ps(yd2), _mm_cvtpd_ps(yd3)); + + yf0 = _mm_mul_ps(yf0, _mm_castsi128_ps(_mm_slli_epi32(xi0, 23))); + yf1 = _mm_mul_ps(yf1, _mm_castsi128_ps(_mm_slli_epi32(xi1, 23))); + + __m128 zf0 = _mm_add_ps(xf0, mA1); + __m128 zf1 = _mm_add_ps(xf1, mA1); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA2); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA2); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA3); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA3); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA4); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA4); + + zf0 = _mm_mul_ps(zf0, yf0); + zf1 = _mm_mul_ps(zf1, yf1); + + if( y_aligned ) + { + _mm_store_ps(y + i, zf0); + _mm_store_ps(y + i + 4, zf1); + } + else + { + _mm_storeu_ps(y + i, zf0); + _mm_storeu_ps(y + i + 4, zf1); + } + } + } + else +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0 = x[i].f * exp_prescale; + double x1 = x[i + 1].f * exp_prescale; + double x2 = x[i + 2].f * exp_prescale; + double x3 = x[i + 3].f * exp_prescale; + int val0, val1, val2, val3, t; + + if( ((x[i].i >> 23) & 255) > 127 + 10 ) + x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+1].i >> 23) & 255) > 127 + 10 ) + x1 = x[i+1].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+2].i >> 23) & 255) > 127 + 10 ) + x2 = x[i+2].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+3].i >> 23) & 255) > 127 + 10 ) + x3 = x[i+3].i < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + val1 = cvRound(x1); + val2 = cvRound(x2); + val3 = cvRound(x3); + + x0 = (x0 - val0)*exp_postscale; + x1 = (x1 - val1)*exp_postscale; + x2 = (x2 - val2)*exp_postscale; + x3 = (x3 - val3)*exp_postscale; + + t = (val0 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[0].i = t << 23; + + t = (val1 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[1].i = t << 23; + + t = (val2 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[2].i = t << 23; + + t = (val3 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[3].i = t << 23; + + x0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + x1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); + + y[i] = (float)x0; + y[i + 1] = (float)x1; + + x2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); + x3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); + + y[i + 2] = (float)x2; + y[i + 3] = (float)x3; + } + + for( ; i < n; i++ ) + { + double x0 = x[i].f * exp_prescale; + int val0, t; + + if( ((x[i].i >> 23) & 255) > 127 + 10 ) + x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + t = (val0 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + + buf[0].i = t << 23; + x0 = (x0 - val0)*exp_postscale; + + y[i] = (float)(buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY(x0)); + } +} + + +static void Exp_64f( const double *_x, double *y, int n ) +{ + static const double + A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0, + A4 = .69314718055994546743029643825322 / EXPPOLY_32F_A0, + A3 = .24022650695886477918181338054308 / EXPPOLY_32F_A0, + A2 = .55504108793649567998466049042729e-1 / EXPPOLY_32F_A0, + A1 = .96180973140732918010002372686186e-2 / EXPPOLY_32F_A0, + A0 = .13369713757180123244806654839424e-2 / EXPPOLY_32F_A0; + +#undef EXPPOLY +#define EXPPOLY(x) (((((A0*(x) + A1)*(x) + A2)*(x) + A3)*(x) + A4)*(x) + A5) + + int i = 0; + Cv64suf buf[4]; + const Cv64suf* x = (const Cv64suf*)_x; + +#if CV_SSE2 + if( USE_SSE2 ) + { + static const __m128d prescale2 = _mm_set1_pd(exp_prescale); + static const __m128d postscale2 = _mm_set1_pd(exp_postscale); + static const __m128d maxval2 = _mm_set1_pd(exp_max_val); + static const __m128d minval2 = _mm_set1_pd(-exp_max_val); + + static const __m128d mA0 = _mm_set1_pd(A0); + static const __m128d mA1 = _mm_set1_pd(A1); + static const __m128d mA2 = _mm_set1_pd(A2); + static const __m128d mA3 = _mm_set1_pd(A3); + static const __m128d mA4 = _mm_set1_pd(A4); + static const __m128d mA5 = _mm_set1_pd(A5); + + int CV_DECL_ALIGNED(16) tab_idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128d xf0 = _mm_loadu_pd(&x[i].f), xf1 = _mm_loadu_pd(&x[i+2].f); + __m128i xi0, xi1; + xf0 = _mm_min_pd(_mm_max_pd(xf0, minval2), maxval2); + xf1 = _mm_min_pd(_mm_max_pd(xf1, minval2), maxval2); + xf0 = _mm_mul_pd(xf0, prescale2); + xf1 = _mm_mul_pd(xf1, prescale2); + + xi0 = _mm_cvtpd_epi32(xf0); + xi1 = _mm_cvtpd_epi32(xf1); + xf0 = _mm_mul_pd(_mm_sub_pd(xf0, _mm_cvtepi32_pd(xi0)), postscale2); + xf1 = _mm_mul_pd(_mm_sub_pd(xf1, _mm_cvtepi32_pd(xi1)), postscale2); + + xi0 = _mm_unpacklo_epi64(xi0, xi1); + _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi32(EXPTAB_MASK))); + + xi0 = _mm_add_epi32(_mm_srai_epi32(xi0, EXPTAB_SCALE), _mm_set1_epi32(1023)); + xi0 = _mm_packs_epi32(xi0, xi0); + xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(2047)); + xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); + xi1 = _mm_unpackhi_epi32(xi0, _mm_setzero_si128()); + xi0 = _mm_unpacklo_epi32(xi0, _mm_setzero_si128()); + + __m128d yf0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); + __m128d yf1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); + yf0 = _mm_mul_pd(yf0, _mm_castsi128_pd(_mm_slli_epi64(xi0, 52))); + yf1 = _mm_mul_pd(yf1, _mm_castsi128_pd(_mm_slli_epi64(xi1, 52))); + + __m128d zf0 = _mm_add_pd(_mm_mul_pd(mA0, xf0), mA1); + __m128d zf1 = _mm_add_pd(_mm_mul_pd(mA0, xf1), mA1); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA2); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA2); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA3); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA3); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA4); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA4); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA5); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA5); + + zf0 = _mm_mul_pd(zf0, yf0); + zf1 = _mm_mul_pd(zf1, yf1); + + _mm_storeu_pd(y + i, zf0); + _mm_storeu_pd(y + i + 2, zf1); + } + } + else +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0 = x[i].f * exp_prescale; + double x1 = x[i + 1].f * exp_prescale; + double x2 = x[i + 2].f * exp_prescale; + double x3 = x[i + 3].f * exp_prescale; + + double y0, y1, y2, y3; + int val0, val1, val2, val3, t; + + t = (int)(x[i].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x0 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+1].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x1 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+2].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x2 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+3].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x3 = t < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + val1 = cvRound(x1); + val2 = cvRound(x2); + val3 = cvRound(x3); + + x0 = (x0 - val0)*exp_postscale; + x1 = (x1 - val1)*exp_postscale; + x2 = (x2 - val2)*exp_postscale; + x3 = (x3 - val3)*exp_postscale; + + t = (val0 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[0].i = (int64)t << 52; + + t = (val1 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[1].i = (int64)t << 52; + + t = (val2 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[2].i = (int64)t << 52; + + t = (val3 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[3].i = (int64)t << 52; + + y0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + y1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); + + y[i] = y0; + y[i + 1] = y1; + + y2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); + y3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); + + y[i + 2] = y2; + y[i + 3] = y3; + } + + for( ; i < n; i++ ) + { + double x0 = x[i].f * exp_prescale; + int val0, t; + + t = (int)(x[i].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x0 = t < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + t = (val0 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + + buf[0].i = (int64)t << 52; + x0 = (x0 - val0)*exp_postscale; + + y[i] = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + } +} + +#undef EXPTAB_SCALE +#undef EXPTAB_MASK +#undef EXPPOLY_32F_A0 + +#else + +#define Exp_32f ippsExp_32f_A21 +#define Exp_64f ippsExp_64f_A50 + +#endif + +void exp( InputArray _src, OutputArray _dst ) +{ + Mat src = _src.getMat(); + int type = src.type(), depth = src.depth(), cn = src.channels(); + + _dst.create( src.dims, src.size, type ); + Mat dst = _dst.getMat(); + + CV_Assert( depth == CV_32F || depth == CV_64F ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int len = (int)(it.size*cn); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + if( depth == CV_32F ) + Exp_32f( (const float*)ptrs[0], (float*)ptrs[1], len ); + else + Exp_64f( (const double*)ptrs[0], (double*)ptrs[1], len ); + } +} + + +/****************************************************************************************\ +* L O G * +\****************************************************************************************/ + +#ifndef HAVE_IPP + +#define LOGTAB_SCALE 8 +#define LOGTAB_MASK ((1 << LOGTAB_SCALE) - 1) +#define LOGTAB_MASK2 ((1 << (20 - LOGTAB_SCALE)) - 1) +#define LOGTAB_MASK2_32F ((1 << (23 - LOGTAB_SCALE)) - 1) + +static const double CV_DECL_ALIGNED(16) icvLogTab[] = { +0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000, +.00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420, +.00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760, +.01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884, +.01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846, +.01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877, +.02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084, +.02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498, +.03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697, +.03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906, +.03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624, +.04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509, +.04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239, +.04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234, +.05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481, +.05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465, +.06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647, +.06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377, +.06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657, +.07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909, +.07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971, +.07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856, +.08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201, +.08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240, +.08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143, +.09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470, +.09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035, +.10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484, +.10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141, +.10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982, +.11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951, +.11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627, +.11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889, +.12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962, +.12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690, +.12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024, +.13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233, +.13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031, +.13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422, +.14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983, +.14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649, +.14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620, +.15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201, +.15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127, +.15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333, +.16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365, +.16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536, +.16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449, +.17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421, +.17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377, +.17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131, +.18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440, +.18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312, +.18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479, +.19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516, +.19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087, +.19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205, +.20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441, +.20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032, +.20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127, +.21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848, +.21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817, +.21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088, +.22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991, +.22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000, +.22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611, +.22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689, +.23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808, +.23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901, +.23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077, +.24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387, +.24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544, +.24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049, +.25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888, +.25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758, +.25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106, +.25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819, +.26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688, +.26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491, +.26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791, +.27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619, +.27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196, +.27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112, +.28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985, +.28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118, +.28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378, +.28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485, +.29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504, +.29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070, +.29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377, +.30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746, +.30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308, +.30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908, +.30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908, +.31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714, +.31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293, +.31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273, +.32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246, +.32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486, +.32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113, +.32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382, +.33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112, +.33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095, +.33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412, +.34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111, +.34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197, +.34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017, +.34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325, +.35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033, +.35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986, +.35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814, +.36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978, +.36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478, +.36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377, +.36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919, +.37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504, +.37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430, +.37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158, +.37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198, +.38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667, +.38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277, +.38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377, +.38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772, +.39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686, +.39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737, +.39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026, +.40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084, +.40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230, +.40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667, +.40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649, +.41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544, +.41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173, +.41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268, +.41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298, +.42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564, +.42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450, +.42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816, +.42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056, +.43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162, +.43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278, +.43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465, +.43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305, +.44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794, +.44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416, +.44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000, +.44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805, +.45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159, +.45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320, +.45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337, +.45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321, +.46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064, +.46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290, +.46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098, +.46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511, +.47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439, +.47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105, +.47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359, +.47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131, +.48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314, +.48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855, +.48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154, +.48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801, +.49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124, +.49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487, +.49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095, +.49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420, +.49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711, +.50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690, +.50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566, +.50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294, +.50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094, +.51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126, +.51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458, +.51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967, +.51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256, +.52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705, +.52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926, +.52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617, +.52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512, +.53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126, +.53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908, +.53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771, +.53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489, +.53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695, +.54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818, +.54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948, +.54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321, +.54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084, +.55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766, +.55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506, +.55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960, +.55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801, +.55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714, +.56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590, +.56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889, +.56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945, +.56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239, +.57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691, +.57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502, +.57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626, +.57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614, +.57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094, +.58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310, +.58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754, +.58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783, +.58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397, +.59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541, +.59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395, +.59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931, +.59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344, +.59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811, +.60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338, +.60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470, +.60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279, +.60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021, +.60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021, +.61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864, +.61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505, +.61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565, +.61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789, +.62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084, +.62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725, +.62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556, +.62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234, +.62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333, +.63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322, +.63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320, +.63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126, +.63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744, +.63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814, +.64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934, +.64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961, +.64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361, +.64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591, +.64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653, +.65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762, +.65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033, +.65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288, +.65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182, +.65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172, +.66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323, +.66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080, +.66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213, +.66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547, +.66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000, +.67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661, +.67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450, +.67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489, +.67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079, +.67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069, +.68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711, +.68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742, +.68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520, +.68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220, +.68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078, +.69314718055994530941723212145818, 5.0e-01, +}; + + + +#define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*icvLogTab[(h)+1]) +static const double ln_2 = 0.69314718055994530941723212145818; + +static void Log_32f( const float *_x, float *y, int n ) +{ + static const float shift[] = { 0, -1.f/512 }; + static const float + A0 = 0.3333333333333333333333333f, + A1 = -0.5f, + A2 = 1.f; + + #undef LOGPOLY + #define LOGPOLY(x) (((A0*(x) + A1)*(x) + A2)*(x)) + + int i = 0; + Cv32suf buf[4]; + const int* x = (const int*)_x; + +#if CV_SSE2 + if( USE_SSE2 ) + { + static const __m128d ln2_2 = _mm_set1_pd(ln_2); + static const __m128 _1_4 = _mm_set1_ps(1.f); + static const __m128 shift4 = _mm_set1_ps(-1.f/512); + + static const __m128 mA0 = _mm_set1_ps(A0); + static const __m128 mA1 = _mm_set1_ps(A1); + static const __m128 mA2 = _mm_set1_ps(A2); + + int CV_DECL_ALIGNED(16) idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); + __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 23), _mm_set1_epi32(255)), _mm_set1_epi32(127)); + __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); + __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0,yi0)), ln2_2); + + __m128i xi0 = _mm_or_si128(_mm_and_si128(h0, _mm_set1_epi32(LOGTAB_MASK2_32F)), _mm_set1_epi32(127 << 23)); + + h0 = _mm_and_si128(_mm_srli_epi32(h0, 23 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK*2)); + _mm_store_si128((__m128i*)idx, h0); + h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); + + __m128d t0, t1, t2, t3, t4; + t0 = _mm_load_pd(icvLogTab + idx[0]); + t2 = _mm_load_pd(icvLogTab + idx[1]); + t1 = _mm_unpackhi_pd(t0, t2); + t0 = _mm_unpacklo_pd(t0, t2); + t2 = _mm_load_pd(icvLogTab + idx[2]); + t4 = _mm_load_pd(icvLogTab + idx[3]); + t3 = _mm_unpackhi_pd(t2, t4); + t2 = _mm_unpacklo_pd(t2, t4); + + yd0 = _mm_add_pd(yd0, t0); + yd1 = _mm_add_pd(yd1, t2); + + __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); + + __m128 xf0 = _mm_sub_ps(_mm_castsi128_ps(xi0), _1_4); + xf0 = _mm_mul_ps(xf0, _mm_movelh_ps(_mm_cvtpd_ps(t1), _mm_cvtpd_ps(t3))); + xf0 = _mm_add_ps(xf0, _mm_and_ps(_mm_castsi128_ps(h0), shift4)); + + __m128 zf0 = _mm_mul_ps(xf0, mA0); + zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA1), xf0); + zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA2), xf0); + yf0 = _mm_add_ps(yf0, zf0); + + _mm_storeu_ps(y + i, yf0); + } + } + else +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0, x1, x2, x3; + double y0, y1, y2, y3; + int h0, h1, h2, h3; + + h0 = x[i]; + h1 = x[i+1]; + buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); + buf[1].i = (h1 & LOGTAB_MASK2_32F) | (127 << 23); + + y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; + y1 = (((h1 >> 23) & 0xff) - 127) * ln_2; + + h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h1 = (h1 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + y1 += icvLogTab[h1]; + + h2 = x[i+2]; + h3 = x[i+3]; + + x0 = LOGTAB_TRANSLATE( buf[0].f, h0 ); + x1 = LOGTAB_TRANSLATE( buf[1].f, h1 ); + + buf[2].i = (h2 & LOGTAB_MASK2_32F) | (127 << 23); + buf[3].i = (h3 & LOGTAB_MASK2_32F) | (127 << 23); + + y2 = (((h2 >> 23) & 0xff) - 127) * ln_2; + y3 = (((h3 >> 23) & 0xff) - 127) * ln_2; + + h2 = (h2 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h3 = (h3 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y2 += icvLogTab[h2]; + y3 += icvLogTab[h3]; + + x2 = LOGTAB_TRANSLATE( buf[2].f, h2 ); + x3 = LOGTAB_TRANSLATE( buf[3].f, h3 ); + + x0 += shift[h0 == 510]; + x1 += shift[h1 == 510]; + y0 += LOGPOLY( x0 ); + y1 += LOGPOLY( x1 ); + + y[i] = (float) y0; + y[i + 1] = (float) y1; + + x2 += shift[h2 == 510]; + x3 += shift[h3 == 510]; + y2 += LOGPOLY( x2 ); + y3 += LOGPOLY( x3 ); + + y[i + 2] = (float) y2; + y[i + 3] = (float) y3; + } + + for( ; i < n; i++ ) + { + int h0 = x[i]; + double y0; + float x0; + + y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; + + buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); + h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + x0 = (float)LOGTAB_TRANSLATE( buf[0].f, h0 ); + x0 += shift[h0 == 510]; + y0 += LOGPOLY( x0 ); + + y[i] = (float)y0; + } +} + + +static void Log_64f( const double *x, double *y, int n ) +{ + static const double shift[] = { 0, -1./512 }; + static const double + A7 = 1.0, + A6 = -0.5, + A5 = 0.333333333333333314829616256247390992939472198486328125, + A4 = -0.25, + A3 = 0.2, + A2 = -0.1666666666666666574148081281236954964697360992431640625, + A1 = 0.1428571428571428769682682968777953647077083587646484375, + A0 = -0.125; + + #undef LOGPOLY + #define LOGPOLY(x,k) ((x)+=shift[k], xq = (x)*(x),\ + (((A0*xq + A2)*xq + A4)*xq + A6)*xq + \ + (((A1*xq + A3)*xq + A5)*xq + A7)*(x)) + + int i = 0; + DBLINT buf[4]; + DBLINT *X = (DBLINT *) x; + +#if CV_SSE2 + if( USE_SSE2 ) + { + static const __m128d ln2_2 = _mm_set1_pd(ln_2); + static const __m128d _1_2 = _mm_set1_pd(1.); + static const __m128d shift2 = _mm_set1_pd(-1./512); + + static const __m128i log_and_mask2 = _mm_set_epi32(LOGTAB_MASK2, 0xffffffff, LOGTAB_MASK2, 0xffffffff); + static const __m128i log_or_mask2 = _mm_set_epi32(1023 << 20, 0, 1023 << 20, 0); + + static const __m128d mA0 = _mm_set1_pd(A0); + static const __m128d mA1 = _mm_set1_pd(A1); + static const __m128d mA2 = _mm_set1_pd(A2); + static const __m128d mA3 = _mm_set1_pd(A3); + static const __m128d mA4 = _mm_set1_pd(A4); + static const __m128d mA5 = _mm_set1_pd(A5); + static const __m128d mA6 = _mm_set1_pd(A6); + static const __m128d mA7 = _mm_set1_pd(A7); + + int CV_DECL_ALIGNED(16) idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); + __m128i h1 = _mm_loadu_si128((const __m128i*)(x + i + 2)); + + __m128d xd0 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h0, log_and_mask2), log_or_mask2)); + __m128d xd1 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h1, log_and_mask2), log_or_mask2)); + + h0 = _mm_unpackhi_epi32(_mm_unpacklo_epi32(h0, h1), _mm_unpackhi_epi32(h0, h1)); + + __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 20), + _mm_set1_epi32(2047)), _mm_set1_epi32(1023)); + __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); + __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0, yi0)), ln2_2); + + h0 = _mm_and_si128(_mm_srli_epi32(h0, 20 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK * 2)); + _mm_store_si128((__m128i*)idx, h0); + h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); + + __m128d t0, t1, t2, t3, t4; + t0 = _mm_load_pd(icvLogTab + idx[0]); + t2 = _mm_load_pd(icvLogTab + idx[1]); + t1 = _mm_unpackhi_pd(t0, t2); + t0 = _mm_unpacklo_pd(t0, t2); + t2 = _mm_load_pd(icvLogTab + idx[2]); + t4 = _mm_load_pd(icvLogTab + idx[3]); + t3 = _mm_unpackhi_pd(t2, t4); + t2 = _mm_unpacklo_pd(t2, t4); + + yd0 = _mm_add_pd(yd0, t0); + yd1 = _mm_add_pd(yd1, t2); + + xd0 = _mm_mul_pd(_mm_sub_pd(xd0, _1_2), t1); + xd1 = _mm_mul_pd(_mm_sub_pd(xd1, _1_2), t3); + + xd0 = _mm_add_pd(xd0, _mm_and_pd(_mm_castsi128_pd(_mm_unpacklo_epi32(h0, h0)), shift2)); + xd1 = _mm_add_pd(xd1, _mm_and_pd(_mm_castsi128_pd(_mm_unpackhi_epi32(h0, h0)), shift2)); + + __m128d zd0 = _mm_mul_pd(xd0, mA0); + __m128d zd1 = _mm_mul_pd(xd1, mA0); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA1), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA1), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA2), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA2), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA3), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA3), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA4), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA4), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA5), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA5), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA6), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA6), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA7), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA7), xd1); + + yd0 = _mm_add_pd(yd0, zd0); + yd1 = _mm_add_pd(yd1, zd1); + + _mm_storeu_pd(y + i, yd0); + _mm_storeu_pd(y + i + 2, yd1); + } + } + else +#endif + for( ; i <= n - 4; i += 4 ) + { + double xq; + double x0, x1, x2, x3; + double y0, y1, y2, y3; + int h0, h1, h2, h3; + + h0 = X[i].i.lo; + h1 = X[i + 1].i.lo; + buf[0].i.lo = h0; + buf[1].i.lo = h1; + + h0 = X[i].i.hi; + h1 = X[i + 1].i.hi; + buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); + buf[1].i.hi = (h1 & LOGTAB_MASK2) | (1023 << 20); + + y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; + y1 = (((h1 >> 20) & 0x7ff) - 1023) * ln_2; + + h2 = X[i + 2].i.lo; + h3 = X[i + 3].i.lo; + buf[2].i.lo = h2; + buf[3].i.lo = h3; + + h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h1 = (h1 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + y1 += icvLogTab[h1]; + + h2 = X[i + 2].i.hi; + h3 = X[i + 3].i.hi; + + x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); + x1 = LOGTAB_TRANSLATE( buf[1].d, h1 ); + + buf[2].i.hi = (h2 & LOGTAB_MASK2) | (1023 << 20); + buf[3].i.hi = (h3 & LOGTAB_MASK2) | (1023 << 20); + + y2 = (((h2 >> 20) & 0x7ff) - 1023) * ln_2; + y3 = (((h3 >> 20) & 0x7ff) - 1023) * ln_2; + + h2 = (h2 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h3 = (h3 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y2 += icvLogTab[h2]; + y3 += icvLogTab[h3]; + + x2 = LOGTAB_TRANSLATE( buf[2].d, h2 ); + x3 = LOGTAB_TRANSLATE( buf[3].d, h3 ); + + y0 += LOGPOLY( x0, h0 == 510 ); + y1 += LOGPOLY( x1, h1 == 510 ); + + y[i] = y0; + y[i + 1] = y1; + + y2 += LOGPOLY( x2, h2 == 510 ); + y3 += LOGPOLY( x3, h3 == 510 ); + + y[i + 2] = y2; + y[i + 3] = y3; + } + + for( ; i < n; i++ ) + { + int h0 = X[i].i.hi; + double xq; + double x0, y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; + + buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); + buf[0].i.lo = X[i].i.lo; + h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); + y0 += LOGPOLY( x0, h0 == 510 ); + y[i] = y0; + } +} + +#else + +#define Log_32f ippsLn_32f_A21 +#define Log_64f ippsLn_64f_A50 + +#endif + +void log( InputArray _src, OutputArray _dst ) +{ + Mat src = _src.getMat(); + int type = src.type(), depth = src.depth(), cn = src.channels(); + + _dst.create( src.dims, src.size, type ); + Mat dst = _dst.getMat(); + + CV_Assert( depth == CV_32F || depth == CV_64F ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int len = (int)(it.size*cn); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + if( depth == CV_32F ) + Log_32f( (const float*)ptrs[0], (float*)ptrs[1], len ); + else + Log_64f( (const double*)ptrs[0], (double*)ptrs[1], len ); + } +} + +/****************************************************************************************\ +* P O W E R * +\****************************************************************************************/ + +template +static void +iPow_( const T* src, T* dst, int len, int power ) +{ + int i; + for( i = 0; i < len; i++ ) + { + WT a = 1, b = src[i]; + int p = power; + while( p > 1 ) + { + if( p & 1 ) + a *= b; + b *= b; + p >>= 1; + } + + a *= b; + dst[i] = saturate_cast(a); + } +} + + +static void iPow8u(const uchar* src, uchar* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow8s(const schar* src, schar* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow16u(const ushort* src, ushort* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow16s(const short* src, short* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow32s(const int* src, int* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow32f(const float* src, float* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + +static void iPow64f(const double* src, double* dst, int len, int power) +{ + iPow_(src, dst, len, power); +} + + +typedef void (*IPowFunc)( const uchar* src, uchar* dst, int len, int power ); + +static IPowFunc ipowTab[] = +{ + (IPowFunc)iPow8u, (IPowFunc)iPow8s, (IPowFunc)iPow16u, (IPowFunc)iPow16s, + (IPowFunc)iPow32s, (IPowFunc)iPow32f, (IPowFunc)iPow64f, 0 +}; + + +void pow( InputArray _src, double power, OutputArray _dst ) +{ + Mat src = _src.getMat(); + int type = src.type(), depth = src.depth(), cn = src.channels(); + + _dst.create( src.dims, src.size, type ); + Mat dst = _dst.getMat(); + + int ipower = cvRound(power); + bool is_ipower = false; + + if( fabs(ipower - power) < DBL_EPSILON ) + { + if( ipower < 0 ) + { + divide( 1., src, dst ); + if( ipower == -1 ) + return; + ipower = -ipower; + src = dst; + } + + switch( ipower ) + { + case 0: + dst = Scalar::all(1); + return; + case 1: + src.copyTo(dst); + return; + case 2: + multiply(src, src, dst); + return; + default: + is_ipower = true; + } + } + else + CV_Assert( depth == CV_32F || depth == CV_64F ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int len = (int)(it.size*cn); + + if( is_ipower ) + { + IPowFunc func = ipowTab[depth]; + CV_Assert( func != 0 ); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], ptrs[1], len, ipower ); + } + else if( fabs(fabs(power) - 0.5) < DBL_EPSILON ) + { + MathFunc func = power < 0 ? + (depth == CV_32F ? (MathFunc)InvSqrt_32f : (MathFunc)InvSqrt_64f) : + (depth == CV_32F ? (MathFunc)Sqrt_32f : (MathFunc)Sqrt_64f); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], ptrs[1], len ); + } + else + { + int j, k, blockSize = std::min(len, ((BLOCK_SIZE + cn-1)/cn)*cn); + size_t esz1 = src.elemSize1(); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < len; j += blockSize ) + { + int bsz = std::min(len - j, blockSize); + if( depth == CV_32F ) + { + const float* x = (const float*)ptrs[0]; + float* y = (float*)ptrs[1]; + + Log_32f(x, y, bsz); + for( k = 0; k < bsz; k++ ) + y[k] = (float)(y[k]*power); + Exp_32f(y, y, bsz); + } + else + { + const double* x = (const double*)ptrs[0]; + double* y = (double*)ptrs[1]; + + Log_64f(x, y, bsz); + for( k = 0; k < bsz; k++ ) + y[k] *= power; + Exp_64f(y, y, bsz); + } + ptrs[0] += bsz*esz1; + ptrs[1] += bsz*esz1; + } + } + } +} + +void sqrt(InputArray a, OutputArray b) +{ + pow(a, 0.5, b); +} + +/************************** CheckArray for NaN's, Inf's *********************************/ + +template struct mat_type_assotiations{}; + +template<> struct mat_type_assotiations +{ + typedef unsigned char type; + static const type min_allowable = 0x0; + static const type max_allowable = 0xFF; +}; + +template<> struct mat_type_assotiations +{ + typedef signed char type; + static const type min_allowable = SCHAR_MIN; + static const type max_allowable = SCHAR_MAX; +}; + +template<> struct mat_type_assotiations +{ + typedef unsigned short type; + static const type min_allowable = 0x0; + static const type max_allowable = USHRT_MAX; +}; +template<> struct mat_type_assotiations +{ + typedef signed short type; + static const type min_allowable = SHRT_MIN; + static const type max_allowable = SHRT_MAX; +}; + +template<> struct mat_type_assotiations +{ + typedef int type; + static const type min_allowable = (-INT_MAX - 1); + static const type max_allowable = INT_MAX; +}; + +// inclusive maxVal !!! +template +bool checkIntegerRange(cv::Mat src, Point& bad_pt, int minVal, int maxVal, double& bad_value) +{ + typedef mat_type_assotiations type_ass; + + if (minVal < type_ass::min_allowable && maxVal > type_ass::max_allowable) + { + return true; + } + else if (minVal > type_ass::max_allowable || maxVal < type_ass::min_allowable || maxVal < minVal) + { + bad_pt = cv::Point(0,0); + return false; + } + cv::Mat as_one_channel = src.reshape(1,0); + + for (int j = 0; j < as_one_channel.rows; ++j) + for (int i = 0; i < as_one_channel.cols; ++i) + { + if (as_one_channel.at(j ,i) < minVal || as_one_channel.at(j ,i) > maxVal) + { + bad_pt.y = j ; + bad_pt.x = i % src.channels(); + bad_value = as_one_channel.at(j ,i); + return false; + } + } + bad_value = 0.0; + + return true; +} + +typedef bool (*check_range_function)(cv::Mat src, Point& bad_pt, int minVal, int maxVal, double& bad_value); + +check_range_function check_range_functions[] = +{ + &checkIntegerRange, + &checkIntegerRange, + &checkIntegerRange, + &checkIntegerRange, + &checkIntegerRange +}; + +bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double maxVal) +{ + Mat src = _src.getMat(); + + if ( src.dims > 2 ) + { + const Mat* arrays[] = {&src, 0}; + Mat planes[1]; + NAryMatIterator it(arrays, planes); + + for ( size_t i = 0; i < it.nplanes; i++, ++it ) + { + if (!checkRange( it.planes[0], quiet, pt, minVal, maxVal )) + { + // todo: set index properly + return false; + } + } + return true; + } + + int depth = src.depth(); + Point badPt(-1, -1); + double badValue = 0; + + if (depth < CV_32F) + { + // see "Bug #1784" + int minVali = minVal<(-INT_MAX - 1) ? (-INT_MAX - 1) : cvFloor(minVal); + int maxVali = maxVal>INT_MAX ? INT_MAX : cvCeil(maxVal) - 1; // checkIntegerRang() use inclusive maxVal + + (check_range_functions[depth])(src, badPt, minVali, maxVali, badValue); + } + else + { + int i, loc = 0; + Size size = getContinuousSize( src, src.channels() ); + + if( depth == CV_32F ) + { + Cv32suf a, b; + int ia, ib; + const int* isrc = (const int*)src.data; + size_t step = src.step/sizeof(isrc[0]); + + a.f = (float)std::max(minVal, (double)-FLT_MAX); + b.f = (float)std::min(maxVal, (double)FLT_MAX); + + ia = CV_TOGGLE_FLT(a.i); + ib = CV_TOGGLE_FLT(b.i); + + for( ; badPt.x < 0 && size.height--; loc += size.width, isrc += step ) + { + for( i = 0; i < size.width; i++ ) + { + int val = isrc[i]; + val = CV_TOGGLE_FLT(val); + + if( val < ia || val >= ib ) + { + badPt = Point((loc + i) % src.cols, (loc + i) / src.cols); + badValue = ((const float*)isrc)[i]; + break; + } + } + } + } + else + { + Cv64suf a, b; + int64 ia, ib; + const int64* isrc = (const int64*)src.data; + size_t step = src.step/sizeof(isrc[0]); + + a.f = minVal; + b.f = maxVal; + + ia = CV_TOGGLE_DBL(a.i); + ib = CV_TOGGLE_DBL(b.i); + + for( ; badPt.x < 0 && size.height--; loc += size.width, isrc += step ) + { + for( i = 0; i < size.width; i++ ) + { + int64 val = isrc[i]; + val = CV_TOGGLE_DBL(val); + + if( val < ia || val >= ib ) + { + badPt = Point((loc + i) % src.cols, (loc + i) / src.cols); + badValue = ((const double*)isrc)[i]; + break; + } + } + } + } + } + + if( badPt.x >= 0 ) + { + if( pt ) + *pt = badPt; + if( !quiet ) + CV_Error_( CV_StsOutOfRange, + ("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue)); + } + return badPt.x < 0; +} + + +void patchNaNs( InputOutputArray _a, double _val ) +{ + Mat a = _a.getMat(); + CV_Assert( a.depth() == CV_32F ); + + const Mat* arrays[] = {&a, 0}; + int* ptrs[1]; + NAryMatIterator it(arrays, (uchar**)ptrs); + size_t len = it.size*a.channels(); + Cv32suf val; + val.f = (float)_val; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + int* tptr = ptrs[0]; + for( size_t j = 0; j < len; j++ ) + if( (tptr[j] & 0x7fffffff) > 0x7f800000 ) + tptr[j] = val.i; + } +} + + +void exp(const float* src, float* dst, int n) +{ + Exp_32f(src, dst, n); +} + +void log(const float* src, float* dst, int n) +{ + Log_32f(src, dst, n); +} + +void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees) +{ + FastAtan2_32f(y, x, dst, n, angleInDegrees); +} + +void magnitude(const float* x, const float* y, float* dst, int n) +{ + Magnitude_32f(x, y, dst, n); +} + +} + +CV_IMPL float cvCbrt(float value) { return cv::cubeRoot(value); } +CV_IMPL float cvFastArctan(float y, float x) { return cv::fastAtan2(y, x); } + +CV_IMPL void +cvCartToPolar( const CvArr* xarr, const CvArr* yarr, + CvArr* magarr, CvArr* anglearr, + int angle_in_degrees ) +{ + cv::Mat X = cv::cvarrToMat(xarr), Y = cv::cvarrToMat(yarr), Mag, Angle; + if( magarr ) + { + Mag = cv::cvarrToMat(magarr); + CV_Assert( Mag.size() == X.size() && Mag.type() == X.type() ); + } + if( anglearr ) + { + Angle = cv::cvarrToMat(anglearr); + CV_Assert( Angle.size() == X.size() && Angle.type() == X.type() ); + } + if( magarr ) + { + if( anglearr ) + cv::cartToPolar( X, Y, Mag, Angle, angle_in_degrees != 0 ); + else + cv::magnitude( X, Y, Mag ); + } + else + cv::phase( X, Y, Angle, angle_in_degrees != 0 ); +} + +CV_IMPL void +cvPolarToCart( const CvArr* magarr, const CvArr* anglearr, + CvArr* xarr, CvArr* yarr, int angle_in_degrees ) +{ + cv::Mat X, Y, Angle = cv::cvarrToMat(anglearr), Mag; + if( magarr ) + { + Mag = cv::cvarrToMat(magarr); + CV_Assert( Mag.size() == Angle.size() && Mag.type() == Angle.type() ); + } + if( xarr ) + { + X = cv::cvarrToMat(xarr); + CV_Assert( X.size() == Angle.size() && X.type() == Angle.type() ); + } + if( yarr ) + { + Y = cv::cvarrToMat(yarr); + CV_Assert( Y.size() == Angle.size() && Y.type() == Angle.type() ); + } + + cv::polarToCart( Mag, Angle, X, Y, angle_in_degrees != 0 ); +} + +CV_IMPL void cvExp( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.type() == dst.type() && src.size == dst.size ); + cv::exp( src, dst ); +} + +CV_IMPL void cvLog( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.type() == dst.type() && src.size == dst.size ); + cv::log( src, dst ); +} + +CV_IMPL void cvPow( const CvArr* srcarr, CvArr* dstarr, double power ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.type() == dst.type() && src.size == dst.size ); + cv::pow( src, power, dst ); +} + +CV_IMPL int cvCheckArr( const CvArr* arr, int flags, + double minVal, double maxVal ) +{ + if( (flags & CV_CHECK_RANGE) == 0 ) + minVal = -DBL_MAX, maxVal = DBL_MAX; + return cv::checkRange(cv::cvarrToMat(arr), (flags & CV_CHECK_QUIET) != 0, 0, minVal, maxVal ); +} + + +/* + Finds real roots of cubic, quadratic or linear equation. + The original code has been taken from Ken Turkowski web page + (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV. + Here is the copyright notice. + + ----------------------------------------------------------------------- + Copyright (C) 1978-1999 Ken Turkowski. + + All rights reserved. + + Warranty Information + Even though I have reviewed this software, I make no warranty + or representation, either express or implied, with respect to this + software, its quality, accuracy, merchantability, or fitness for a + particular purpose. As a result, this software is provided "as is," + and you, its user, are assuming the entire risk as to its quality + and accuracy. + + This code may be used and freely distributed as long as it includes + this copyright notice and the above warranty information. + ----------------------------------------------------------------------- +*/ + +int cv::solveCubic( InputArray _coeffs, OutputArray _roots ) +{ + const int n0 = 3; + Mat coeffs = _coeffs.getMat(); + int ctype = coeffs.type(); + + CV_Assert( ctype == CV_32F || ctype == CV_64F ); + CV_Assert( (coeffs.size() == Size(n0, 1) || + coeffs.size() == Size(n0+1, 1) || + coeffs.size() == Size(1, n0) || + coeffs.size() == Size(1, n0+1)) ); + + _roots.create(n0, 1, ctype, -1, true, DEPTH_MASK_FLT); + Mat roots = _roots.getMat(); + + int i = -1, n = 0; + double a0 = 1., a1, a2, a3; + double x0 = 0., x1 = 0., x2 = 0.; + int ncoeffs = coeffs.rows + coeffs.cols - 1; + + if( ctype == CV_32FC1 ) + { + if( ncoeffs == 4 ) + a0 = coeffs.at(++i); + + a1 = coeffs.at(i+1); + a2 = coeffs.at(i+2); + a3 = coeffs.at(i+3); + } + else + { + if( ncoeffs == 4 ) + a0 = coeffs.at(++i); + + a1 = coeffs.at(i+1); + a2 = coeffs.at(i+2); + a3 = coeffs.at(i+3); + } + + if( a0 == 0 ) + { + if( a1 == 0 ) + { + if( a2 == 0 ) + n = a3 == 0 ? -1 : 0; + else + { + // linear equation + x0 = -a3/a2; + n = 1; + } + } + else + { + // quadratic equation + double d = a2*a2 - 4*a1*a3; + if( d >= 0 ) + { + d = sqrt(d); + double q1 = (-a2 + d) * 0.5; + double q2 = (a2 + d) * -0.5; + if( fabs(q1) > fabs(q2) ) + { + x0 = q1 / a1; + x1 = a3 / q1; + } + else + { + x0 = q2 / a1; + x1 = a3 / q2; + } + n = d > 0 ? 2 : 1; + } + } + } + else + { + a0 = 1./a0; + a1 *= a0; + a2 *= a0; + a3 *= a0; + + double Q = (a1 * a1 - 3 * a2) * (1./9); + double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54); + double Qcubed = Q * Q * Q; + double d = Qcubed - R * R; + + if( d >= 0 ) + { + double theta = acos(R / sqrt(Qcubed)); + double sqrtQ = sqrt(Q); + double t0 = -2 * sqrtQ; + double t1 = theta * (1./3); + double t2 = a1 * (1./3); + x0 = t0 * cos(t1) - t2; + x1 = t0 * cos(t1 + (2.*CV_PI/3)) - t2; + x2 = t0 * cos(t1 + (4.*CV_PI/3)) - t2; + n = 3; + } + else + { + double e; + d = sqrt(-d); + e = pow(d + fabs(R), 0.333333333333); + if( R > 0 ) + e = -e; + x0 = (e + Q / e) - a1 * (1./3); + n = 1; + } + } + + if( roots.type() == CV_32FC1 ) + { + roots.at(0) = (float)x0; + roots.at(1) = (float)x1; + roots.at(2) = (float)x2; + } + else + { + roots.at(0) = x0; + roots.at(1) = x1; + roots.at(2) = x2; + } + + return n; +} + +/* finds complex roots of a polynomial using Durand-Kerner method: + http://en.wikipedia.org/wiki/Durand%E2%80%93Kerner_method */ +double cv::solvePoly( InputArray _coeffs0, OutputArray _roots0, int maxIters ) +{ + typedef Complex C; + + double maxDiff = 0; + int iter, i, j; + Mat coeffs0 = _coeffs0.getMat(); + int ctype = _coeffs0.type(); + int cdepth = CV_MAT_DEPTH(ctype); + + CV_Assert( CV_MAT_DEPTH(ctype) >= CV_32F && CV_MAT_CN(ctype) <= 2 ); + CV_Assert( coeffs0.rows == 1 || coeffs0.cols == 1 ); + + int n = coeffs0.cols + coeffs0.rows - 2; + + _roots0.create(n, 1, CV_MAKETYPE(cdepth, 2), -1, true, DEPTH_MASK_FLT); + Mat roots0 = _roots0.getMat(); + + AutoBuffer buf(n*2+2); + C *coeffs = buf, *roots = coeffs + n + 1; + Mat coeffs1(coeffs0.size(), CV_MAKETYPE(CV_64F, coeffs0.channels()), coeffs0.channels() == 2 ? coeffs : roots); + coeffs0.convertTo(coeffs1, coeffs1.type()); + if( coeffs0.channels() == 1 ) + { + const double* rcoeffs = (const double*)roots; + for( i = 0; i <= n; i++ ) + coeffs[i] = C(rcoeffs[i], 0); + } + + C p(1, 0), r(1, 1); + + for( i = 0; i < n; i++ ) + { + roots[i] = p; + p = p * r; + } + + maxIters = maxIters <= 0 ? 1000 : maxIters; + for( iter = 0; iter < maxIters; iter++ ) + { + maxDiff = 0; + for( i = 0; i < n; i++ ) + { + p = roots[i]; + C num = coeffs[n], denom = coeffs[n]; + for( j = 0; j < n; j++ ) + { + num = num*p + coeffs[n-j-1]; + if( j != i ) denom = denom * (p - roots[j]); + } + num /= denom; + roots[i] = p - num; + maxDiff = max(maxDiff, abs(num)); + } + if( maxDiff <= 0 ) + break; + } + + if( coeffs0.channels() == 1 ) + { + const double verySmallEps = 1e-100; + for( i = 0; i < n; i++ ) + if( fabs(roots[i].im) < verySmallEps ) + roots[i].im = 0; + } + + Mat(roots0.size(), CV_64FC2, roots).convertTo(roots0, roots0.type()); + return maxDiff; +} + + +CV_IMPL int +cvSolveCubic( const CvMat* coeffs, CvMat* roots ) +{ + cv::Mat _coeffs = cv::cvarrToMat(coeffs), _roots = cv::cvarrToMat(roots), _roots0 = _roots; + int nroots = cv::solveCubic(_coeffs, _roots); + CV_Assert( _roots.data == _roots0.data ); // check that the array of roots was not reallocated + return nroots; +} + + +void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int) +{ + cv::Mat _a = cv::cvarrToMat(a), _r = cv::cvarrToMat(r), _r0 = r; + cv::solvePoly(_a, _r, maxiter); + CV_Assert( _r.data == _r0.data ); // check that the array of roots was not reallocated +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/matmul.cpp diffimg-2.0.0/3rdparty/opencv/core/src/matmul.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/matmul.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/matmul.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3328 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_IPP +#include "ippversion.h" +#endif + +namespace cv +{ + +/****************************************************************************************\ +* GEMM * +\****************************************************************************************/ + +static void +GEMM_CopyBlock( const uchar* src, size_t src_step, + uchar* dst, size_t dst_step, + Size size, size_t pix_size ) +{ + int j; + size.width *= (int)(pix_size / sizeof(int)); + + for( ; size.height--; src += src_step, dst += dst_step ) + { + j=0; + #if CV_ENABLE_UNROLLED + for( ; j <= size.width - 4; j += 4 ) + { + int t0 = ((const int*)src)[j]; + int t1 = ((const int*)src)[j+1]; + ((int*)dst)[j] = t0; + ((int*)dst)[j+1] = t1; + t0 = ((const int*)src)[j+2]; + t1 = ((const int*)src)[j+3]; + ((int*)dst)[j+2] = t0; + ((int*)dst)[j+3] = t1; + } + #endif + for( ; j < size.width; j++ ) + ((int*)dst)[j] = ((const int*)src)[j]; + } +} + + +static void +GEMM_TransposeBlock( const uchar* src, size_t src_step, + uchar* dst, size_t dst_step, + Size size, size_t pix_size ) +{ + int i, j; + for( i = 0; i < size.width; i++, dst += dst_step, src += pix_size ) + { + const uchar* _src = src; + switch( pix_size ) + { + case sizeof(int): + for( j = 0; j < size.height; j++, _src += src_step ) + ((int*)dst)[j] = ((int*)_src)[0]; + break; + case sizeof(int)*2: + for( j = 0; j < size.height*2; j += 2, _src += src_step ) + { + int t0 = ((int*)_src)[0]; + int t1 = ((int*)_src)[1]; + ((int*)dst)[j] = t0; + ((int*)dst)[j+1] = t1; + } + break; + case sizeof(int)*4: + for( j = 0; j < size.height*4; j += 4, _src += src_step ) + { + int t0 = ((int*)_src)[0]; + int t1 = ((int*)_src)[1]; + ((int*)dst)[j] = t0; + ((int*)dst)[j+1] = t1; + t0 = ((int*)_src)[2]; + t1 = ((int*)_src)[3]; + ((int*)dst)[j+2] = t0; + ((int*)dst)[j+3] = t1; + } + break; + default: + assert(0); + return; + } + } +} + + +template static void +GEMMSingleMul( const T* a_data, size_t a_step, + const T* b_data, size_t b_step, + const T* c_data, size_t c_step, + T* d_data, size_t d_step, + Size a_size, Size d_size, + double alpha, double beta, int flags ) +{ + int i, j, k, n = a_size.width, m = d_size.width, drows = d_size.height; + const T *_a_data = a_data, *_b_data = b_data, *_c_data = c_data; + cv::AutoBuffer _a_buf; + T* a_buf = 0; + size_t a_step0, a_step1, c_step0, c_step1, t_step; + + a_step /= sizeof(a_data[0]); + b_step /= sizeof(b_data[0]); + c_step /= sizeof(c_data[0]); + d_step /= sizeof(d_data[0]); + a_step0 = a_step; + a_step1 = 1; + + if( !c_data ) + c_step0 = c_step1 = 0; + else if( !(flags & GEMM_3_T) ) + c_step0 = c_step, c_step1 = 1; + else + c_step0 = 1, c_step1 = c_step; + + if( flags & GEMM_1_T ) + { + CV_SWAP( a_step0, a_step1, t_step ); + n = a_size.height; + if( a_step > 1 && n > 1 ) + { + _a_buf.allocate(n); + a_buf = _a_buf; + } + } + + if( n == 1 ) /* external product */ + { + cv::AutoBuffer _b_buf; + T* b_buf = 0; + + if( a_step > 1 && a_size.height > 1 ) + { + _a_buf.allocate(drows); + a_buf = _a_buf; + for( k = 0; k < drows; k++ ) + a_buf[k] = a_data[a_step*k]; + a_data = a_buf; + } + + if( b_step > 1 ) + { + _b_buf.allocate(d_size.width); + b_buf = _b_buf; + for( j = 0; j < d_size.width; j++ ) + b_buf[j] = b_data[j*b_step]; + b_data = b_buf; + } + + for( i = 0; i < drows; i++, _c_data += c_step0, d_data += d_step ) + { + WT al = WT(a_data[i])*alpha; + c_data = _c_data; + for( j = 0; j <= d_size.width - 2; j += 2, c_data += 2*c_step1 ) + { + WT s0 = al*WT(b_data[j]); + WT s1 = al*WT(b_data[j+1]); + if( !c_data ) + { + d_data[j] = T(s0); + d_data[j+1] = T(s1); + } + else + { + d_data[j] = T(s0 + WT(c_data[0])*beta); + d_data[j+1] = T(s1 + WT(c_data[c_step1])*beta); + } + } + + for( ; j < d_size.width; j++, c_data += c_step1 ) + { + WT s0 = al*WT(b_data[j]); + if( !c_data ) + d_data[j] = T(s0); + else + d_data[j] = T(s0 + WT(c_data[0])*beta); + } + } + } + else if( flags & GEMM_2_T ) /* A * Bt */ + { + for( i = 0; i < drows; i++, _a_data += a_step0, _c_data += c_step0, d_data += d_step ) + { + a_data = _a_data; + b_data = _b_data; + c_data = _c_data; + + if( a_buf ) + { + for( k = 0; k < n; k++ ) + a_buf[k] = a_data[a_step1*k]; + a_data = a_buf; + } + + for( j = 0; j < d_size.width; j++, b_data += b_step, + c_data += c_step1 ) + { + WT s0(0), s1(0), s2(0), s3(0); + k = 0; + #if CV_ENABLE_UNROLLED + for( ; k <= n - 4; k += 4 ) + { + s0 += WT(a_data[k])*WT(b_data[k]); + s1 += WT(a_data[k+1])*WT(b_data[k+1]); + s2 += WT(a_data[k+2])*WT(b_data[k+2]); + s3 += WT(a_data[k+3])*WT(b_data[k+3]); + } + #endif + for( ; k < n; k++ ) + s0 += WT(a_data[k])*WT(b_data[k]); + s0 = (s0+s1+s2+s3)*alpha; + + if( !c_data ) + d_data[j] = T(s0); + else + d_data[j] = T(s0 + WT(c_data[0])*beta); + } + } + } + else if( d_size.width*sizeof(d_data[0]) <= 1600 ) + { + for( i = 0; i < drows; i++, _a_data += a_step0, + _c_data += c_step0, + d_data += d_step ) + { + a_data = _a_data, c_data = _c_data; + + if( a_buf ) + { + for( k = 0; k < n; k++ ) + a_buf[k] = a_data[a_step1*k]; + a_data = a_buf; + } + + for( j = 0; j <= m - 4; j += 4, c_data += 4*c_step1 ) + { + const T* b = _b_data + j; + WT s0(0), s1(0), s2(0), s3(0); + + for( k = 0; k < n; k++, b += b_step ) + { + WT a(a_data[k]); + s0 += a * WT(b[0]); s1 += a * WT(b[1]); + s2 += a * WT(b[2]); s3 += a * WT(b[3]); + } + + if( !c_data ) + { + d_data[j] = T(s0*alpha); + d_data[j+1] = T(s1*alpha); + d_data[j+2] = T(s2*alpha); + d_data[j+3] = T(s3*alpha); + } + else + { + s0 = s0*alpha; s1 = s1*alpha; + s2 = s2*alpha; s3 = s3*alpha; + d_data[j] = T(s0 + WT(c_data[0])*beta); + d_data[j+1] = T(s1 + WT(c_data[c_step1])*beta); + d_data[j+2] = T(s2 + WT(c_data[c_step1*2])*beta); + d_data[j+3] = T(s3 + WT(c_data[c_step1*3])*beta); + } + } + + for( ; j < m; j++, c_data += c_step1 ) + { + const T* b = _b_data + j; + WT s0(0); + + for( k = 0; k < n; k++, b += b_step ) + s0 += WT(a_data[k]) * WT(b[0]); + + s0 = s0*alpha; + if( !c_data ) + d_data[j] = T(s0); + else + d_data[j] = T(s0 + WT(c_data[0])*beta); + } + } + } + else + { + cv::AutoBuffer _d_buf(m); + WT* d_buf = _d_buf; + + for( i = 0; i < drows; i++, _a_data += a_step0, _c_data += c_step0, d_data += d_step ) + { + a_data = _a_data; + b_data = _b_data; + c_data = _c_data; + + if( a_buf ) + { + for( k = 0; k < n; k++ ) + a_buf[k] = _a_data[a_step1*k]; + a_data = a_buf; + } + + for( j = 0; j < m; j++ ) + d_buf[j] = WT(0); + + for( k = 0; k < n; k++, b_data += b_step ) + { + WT al(a_data[k]); + j=0; + #if CV_ENABLE_UNROLLED + for(; j <= m - 4; j += 4 ) + { + WT t0 = d_buf[j] + WT(b_data[j])*al; + WT t1 = d_buf[j+1] + WT(b_data[j+1])*al; + d_buf[j] = t0; + d_buf[j+1] = t1; + t0 = d_buf[j+2] + WT(b_data[j+2])*al; + t1 = d_buf[j+3] + WT(b_data[j+3])*al; + d_buf[j+2] = t0; + d_buf[j+3] = t1; + } + #endif + for( ; j < m; j++ ) + d_buf[j] += WT(b_data[j])*al; + } + + if( !c_data ) + for( j = 0; j < m; j++ ) + d_data[j] = T(d_buf[j]*alpha); + else + for( j = 0; j < m; j++, c_data += c_step1 ) + { + WT t = d_buf[j]*alpha; + d_data[j] = T(t + WT(c_data[0])*beta); + } + } + } +} + + +template static void +GEMMBlockMul( const T* a_data, size_t a_step, + const T* b_data, size_t b_step, + WT* d_data, size_t d_step, + Size a_size, Size d_size, int flags ) +{ + int i, j, k, n = a_size.width, m = d_size.width; + const T *_a_data = a_data, *_b_data = b_data; + cv::AutoBuffer _a_buf; + T* a_buf = 0; + size_t a_step0, a_step1, t_step; + int do_acc = flags & 16; + + a_step /= sizeof(a_data[0]); + b_step /= sizeof(b_data[0]); + d_step /= sizeof(d_data[0]); + + a_step0 = a_step; + a_step1 = 1; + + if( flags & GEMM_1_T ) + { + CV_SWAP( a_step0, a_step1, t_step ); + n = a_size.height; + _a_buf.allocate(n); + a_buf = _a_buf; + } + + if( flags & GEMM_2_T ) + { + /* second operand is transposed */ + for( i = 0; i < d_size.height; i++, _a_data += a_step0, d_data += d_step ) + { + a_data = _a_data; b_data = _b_data; + + if( a_buf ) + { + for( k = 0; k < n; k++ ) + a_buf[k] = a_data[a_step1*k]; + a_data = a_buf; + } + + for( j = 0; j < d_size.width; j++, b_data += b_step ) + { + WT s0 = do_acc ? d_data[j]:WT(0), s1(0); + for( k = 0; k <= n - 2; k += 2 ) + { + s0 += WT(a_data[k])*WT(b_data[k]); + s1 += WT(a_data[k+1])*WT(b_data[k+1]); + } + + for( ; k < n; k++ ) + s0 += WT(a_data[k])*WT(b_data[k]); + + d_data[j] = s0 + s1; + } + } + } + else + { + for( i = 0; i < d_size.height; i++, _a_data += a_step0, d_data += d_step ) + { + a_data = _a_data, b_data = _b_data; + + if( a_buf ) + { + for( k = 0; k < n; k++ ) + a_buf[k] = a_data[a_step1*k]; + a_data = a_buf; + } + + for( j = 0; j <= m - 4; j += 4 ) + { + WT s0, s1, s2, s3; + const T* b = b_data + j; + + if( do_acc ) + { + s0 = d_data[j]; s1 = d_data[j+1]; + s2 = d_data[j+2]; s3 = d_data[j+3]; + } + else + s0 = s1 = s2 = s3 = WT(0); + + for( k = 0; k < n; k++, b += b_step ) + { + WT a(a_data[k]); + s0 += a * WT(b[0]); s1 += a * WT(b[1]); + s2 += a * WT(b[2]); s3 += a * WT(b[3]); + } + + d_data[j] = s0; d_data[j+1] = s1; + d_data[j+2] = s2; d_data[j+3] = s3; + } + + for( ; j < m; j++ ) + { + const T* b = b_data + j; + WT s0 = do_acc ? d_data[j] : WT(0); + + for( k = 0; k < n; k++, b += b_step ) + s0 += WT(a_data[k]) * WT(b[0]); + + d_data[j] = s0; + } + } + } +} + + +template static void +GEMMStore( const T* c_data, size_t c_step, + const WT* d_buf, size_t d_buf_step, + T* d_data, size_t d_step, Size d_size, + double alpha, double beta, int flags ) +{ + const T* _c_data = c_data; + int j; + size_t c_step0, c_step1; + + c_step /= sizeof(c_data[0]); + d_buf_step /= sizeof(d_buf[0]); + d_step /= sizeof(d_data[0]); + + if( !c_data ) + c_step0 = c_step1 = 0; + else if( !(flags & GEMM_3_T) ) + c_step0 = c_step, c_step1 = 1; + else + c_step0 = 1, c_step1 = c_step; + + for( ; d_size.height--; _c_data += c_step0, d_buf += d_buf_step, d_data += d_step ) + { + if( _c_data ) + { + c_data = _c_data; + j=0; + #if CV_ENABLE_UNROLLED + for(; j <= d_size.width - 4; j += 4, c_data += 4*c_step1 ) + { + WT t0 = alpha*d_buf[j]; + WT t1 = alpha*d_buf[j+1]; + t0 += beta*WT(c_data[0]); + t1 += beta*WT(c_data[c_step1]); + d_data[j] = T(t0); + d_data[j+1] = T(t1); + t0 = alpha*d_buf[j+2]; + t1 = alpha*d_buf[j+3]; + t0 += beta*WT(c_data[c_step1*2]); + t1 += beta*WT(c_data[c_step1*3]); + d_data[j+2] = T(t0); + d_data[j+3] = T(t1); + } + #endif + for( ; j < d_size.width; j++, c_data += c_step1 ) + { + WT t0 = alpha*d_buf[j]; + d_data[j] = T(t0 + WT(c_data[0])*beta); + } + } + else + { + j = 0; + #if CV_ENABLE_UNROLLED + for( ; j <= d_size.width - 4; j += 4 ) + { + WT t0 = alpha*d_buf[j]; + WT t1 = alpha*d_buf[j+1]; + d_data[j] = T(t0); + d_data[j+1] = T(t1); + t0 = alpha*d_buf[j+2]; + t1 = alpha*d_buf[j+3]; + d_data[j+2] = T(t0); + d_data[j+3] = T(t1); + } + #endif + for( ; j < d_size.width; j++ ) + d_data[j] = T(alpha*d_buf[j]); + } + } +} + + +typedef void (*GEMMSingleMulFunc)( const void* src1, size_t step1, + const void* src2, size_t step2, const void* src3, size_t step3, + void* dst, size_t dststep, Size srcsize, Size dstsize, + double alpha, double beta, int flags ); + +typedef void (*GEMMBlockMulFunc)( const void* src1, size_t step1, + const void* src2, size_t step2, void* dst, size_t dststep, + Size srcsize, Size dstsize, int flags ); + +typedef void (*GEMMStoreFunc)( const void* src1, size_t step1, + const void* src2, size_t step2, void* dst, size_t dststep, + Size dstsize, double alpha, double beta, int flags ); + +static void GEMMSingleMul_32f( const float* a_data, size_t a_step, + const float* b_data, size_t b_step, + const float* c_data, size_t c_step, + float* d_data, size_t d_step, + Size a_size, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMSingleMul(a_data, a_step, b_data, b_step, c_data, + c_step, d_data, d_step, a_size, d_size, + alpha, beta, flags); +} + +static void GEMMSingleMul_64f( const double* a_data, size_t a_step, + const double* b_data, size_t b_step, + const double* c_data, size_t c_step, + double* d_data, size_t d_step, + Size a_size, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMSingleMul(a_data, a_step, b_data, b_step, c_data, + c_step, d_data, d_step, a_size, d_size, + alpha, beta, flags); +} + + +static void GEMMSingleMul_32fc( const Complexf* a_data, size_t a_step, + const Complexf* b_data, size_t b_step, + const Complexf* c_data, size_t c_step, + Complexf* d_data, size_t d_step, + Size a_size, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMSingleMul(a_data, a_step, b_data, b_step, c_data, + c_step, d_data, d_step, a_size, d_size, + alpha, beta, flags); +} + +static void GEMMSingleMul_64fc( const Complexd* a_data, size_t a_step, + const Complexd* b_data, size_t b_step, + const Complexd* c_data, size_t c_step, + Complexd* d_data, size_t d_step, + Size a_size, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMSingleMul(a_data, a_step, b_data, b_step, c_data, + c_step, d_data, d_step, a_size, d_size, + alpha, beta, flags); +} + +static void GEMMBlockMul_32f( const float* a_data, size_t a_step, + const float* b_data, size_t b_step, + double* d_data, size_t d_step, + Size a_size, Size d_size, int flags ) +{ + GEMMBlockMul(a_data, a_step, b_data, b_step, d_data, d_step, a_size, d_size, flags); +} + + +static void GEMMBlockMul_64f( const double* a_data, size_t a_step, + const double* b_data, size_t b_step, + double* d_data, size_t d_step, + Size a_size, Size d_size, int flags ) +{ + GEMMBlockMul(a_data, a_step, b_data, b_step, d_data, d_step, a_size, d_size, flags); +} + + +static void GEMMBlockMul_32fc( const Complexf* a_data, size_t a_step, + const Complexf* b_data, size_t b_step, + Complexd* d_data, size_t d_step, + Size a_size, Size d_size, int flags ) +{ + GEMMBlockMul(a_data, a_step, b_data, b_step, d_data, d_step, a_size, d_size, flags); +} + + +static void GEMMBlockMul_64fc( const Complexd* a_data, size_t a_step, + const Complexd* b_data, size_t b_step, + Complexd* d_data, size_t d_step, + Size a_size, Size d_size, int flags ) +{ + GEMMBlockMul(a_data, a_step, b_data, b_step, d_data, d_step, a_size, d_size, flags); +} + + +static void GEMMStore_32f( const float* c_data, size_t c_step, + const double* d_buf, size_t d_buf_step, + float* d_data, size_t d_step, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMStore(c_data, c_step, d_buf, d_buf_step, d_data, d_step, d_size, alpha, beta, flags); +} + + +static void GEMMStore_64f( const double* c_data, size_t c_step, + const double* d_buf, size_t d_buf_step, + double* d_data, size_t d_step, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMStore(c_data, c_step, d_buf, d_buf_step, d_data, d_step, d_size, alpha, beta, flags); +} + + +static void GEMMStore_32fc( const Complexf* c_data, size_t c_step, + const Complexd* d_buf, size_t d_buf_step, + Complexf* d_data, size_t d_step, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMStore(c_data, c_step, d_buf, d_buf_step, d_data, d_step, d_size, alpha, beta, flags); +} + + +static void GEMMStore_64fc( const Complexd* c_data, size_t c_step, + const Complexd* d_buf, size_t d_buf_step, + Complexd* d_data, size_t d_step, Size d_size, + double alpha, double beta, int flags ) +{ + GEMMStore(c_data, c_step, d_buf, d_buf_step, d_data, d_step, d_size, alpha, beta, flags); +} + +} + +void cv::gemm( InputArray matA, InputArray matB, double alpha, + InputArray matC, double beta, OutputArray _matD, int flags ) +{ + const int block_lin_size = 128; + const int block_size = block_lin_size * block_lin_size; + + static double zero[] = {0,0,0,0}; + static float zerof[] = {0,0,0,0}; + + Mat A = matA.getMat(), B = matB.getMat(), C = beta != 0 ? matC.getMat() : Mat(); + Size a_size = A.size(), d_size; + int i, len = 0, type = A.type(); + + CV_Assert( type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2) ); + + switch( flags & (GEMM_1_T|GEMM_2_T) ) + { + case 0: + d_size = Size( B.cols, a_size.height ); + len = B.rows; + CV_Assert( a_size.width == len ); + break; + case 1: + d_size = Size( B.cols, a_size.width ); + len = B.rows; + CV_Assert( a_size.height == len ); + break; + case 2: + d_size = Size( B.rows, a_size.height ); + len = B.cols; + CV_Assert( a_size.width == len ); + break; + case 3: + d_size = Size( B.rows, a_size.width ); + len = B.cols; + CV_Assert( a_size.height == len ); + break; + } + + if( C.data ) + { + CV_Assert( C.type() == type && + (((flags&GEMM_3_T) == 0 && C.rows == d_size.height && C.cols == d_size.width) || + ((flags&GEMM_3_T) != 0 && C.rows == d_size.width && C.cols == d_size.height))); + } + + _matD.create( d_size.height, d_size.width, type ); + Mat D = _matD.getMat(); + if( (flags & GEMM_3_T) != 0 && C.data == D.data ) + { + transpose( C, C ); + flags &= ~GEMM_3_T; + } + + if( flags == 0 && 2 <= len && len <= 4 && (len == d_size.width || len == d_size.height) ) + { + if( type == CV_32F ) + { + float* d = (float*)D.data; + const float *a = (const float*)A.data, + *b = (const float*)B.data, + *c = (const float*)C.data; + size_t d_step = D.step/sizeof(d[0]), + a_step = A.step/sizeof(a[0]), + b_step = B.step/sizeof(b[0]), + c_step = C.data ? C.step/sizeof(c[0]) : 0; + + if( !c ) + c = zerof; + + switch( len ) + { + case 2: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step]; + float t1 = a[0]*b[1] + a[1]*b[b_step+1]; + d[0] = (float)(t0*alpha + c[0]*beta); + d[1] = (float)(t1*alpha + c[1]*beta); + } + } + else if( a != d ) + { + int c_step0 = 1; + if( c == zerof ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step]; + float t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step]; + d[0] = (float)(t0*alpha + c[0]*beta); + d[d_step] = (float)(t1*alpha + c[c_step]*beta); + } + } + else + break; + return; + case 3: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2]; + float t1 = a[0]*b[1] + a[1]*b[b_step+1] + a[2]*b[b_step*2+1]; + float t2 = a[0]*b[2] + a[1]*b[b_step+2] + a[2]*b[b_step*2+2]; + d[0] = (float)(t0*alpha + c[0]*beta); + d[1] = (float)(t1*alpha + c[1]*beta); + d[2] = (float)(t2*alpha + c[2]*beta); + } + } + else if( a != d ) + { + int c_step0 = 1; + if( c == zerof ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2]; + float t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step] + a[a_step+2]*b[b_step*2]; + float t2 = a[a_step*2]*b[0] + a[a_step*2+1]*b[b_step] + a[a_step*2+2]*b[b_step*2]; + + d[0] = (float)(t0*alpha + c[0]*beta); + d[d_step] = (float)(t1*alpha + c[c_step]*beta); + d[d_step*2] = (float)(t2*alpha + c[c_step*2]*beta); + } + } + else + break; + return; + case 4: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2] + a[3]*b[b_step*3]; + float t1 = a[0]*b[1] + a[1]*b[b_step+1] + a[2]*b[b_step*2+1] + a[3]*b[b_step*3+1]; + float t2 = a[0]*b[2] + a[1]*b[b_step+2] + a[2]*b[b_step*2+2] + a[3]*b[b_step*3+2]; + float t3 = a[0]*b[3] + a[1]*b[b_step+3] + a[2]*b[b_step*2+3] + a[3]*b[b_step*3+3]; + d[0] = (float)(t0*alpha + c[0]*beta); + d[1] = (float)(t1*alpha + c[1]*beta); + d[2] = (float)(t2*alpha + c[2]*beta); + d[3] = (float)(t3*alpha + c[3]*beta); + } + } + else if( len <= 16 && a != d ) + { + int c_step0 = 1; + if( c == zerof ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + float t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2] + a[3]*b[b_step*3]; + float t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step] + + a[a_step+2]*b[b_step*2] + a[a_step+3]*b[b_step*3]; + float t2 = a[a_step*2]*b[0] + a[a_step*2+1]*b[b_step] + + a[a_step*2+2]*b[b_step*2] + a[a_step*2+3]*b[b_step*3]; + float t3 = a[a_step*3]*b[0] + a[a_step*3+1]*b[b_step] + + a[a_step*3+2]*b[b_step*2] + a[a_step*3+3]*b[b_step*3]; + d[0] = (float)(t0*alpha + c[0]*beta); + d[d_step] = (float)(t1*alpha + c[c_step]*beta); + d[d_step*2] = (float)(t2*alpha + c[c_step*2]*beta); + d[d_step*3] = (float)(t3*alpha + c[c_step*3]*beta); + } + } + else + break; + return; + } + } + + if( type == CV_64F ) + { + double* d = (double*)D.data; + const double *a = (const double*)A.data, + *b = (const double*)B.data, + *c = (const double*)C.data; + size_t d_step = D.step/sizeof(d[0]), + a_step = A.step/sizeof(a[0]), + b_step = B.step/sizeof(b[0]), + c_step = C.data ? C.step/sizeof(c[0]) : 0; + if( !c ) + c = zero; + + switch( len ) + { + case 2: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step]; + double t1 = a[0]*b[1] + a[1]*b[b_step+1]; + d[0] = t0*alpha + c[0]*beta; + d[1] = t1*alpha + c[1]*beta; + } + } + else if( a != d ) + { + int c_step0 = 1; + if( c == zero ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step]; + double t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step]; + d[0] = t0*alpha + c[0]*beta; + d[d_step] = t1*alpha + c[c_step]*beta; + } + } + else + break; + return; + case 3: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2]; + double t1 = a[0]*b[1] + a[1]*b[b_step+1] + a[2]*b[b_step*2+1]; + double t2 = a[0]*b[2] + a[1]*b[b_step+2] + a[2]*b[b_step*2+2]; + d[0] = t0*alpha + c[0]*beta; + d[1] = t1*alpha + c[1]*beta; + d[2] = t2*alpha + c[2]*beta; + } + } + else if( a != d ) + { + int c_step0 = 1; + if( c == zero ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2]; + double t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step] + a[a_step+2]*b[b_step*2]; + double t2 = a[a_step*2]*b[0] + a[a_step*2+1]*b[b_step] + a[a_step*2+2]*b[b_step*2]; + + d[0] = t0*alpha + c[0]*beta; + d[d_step] = t1*alpha + c[c_step]*beta; + d[d_step*2] = t2*alpha + c[c_step*2]*beta; + } + } + else + break; + return; + case 4: + if( len == d_size.width && b != d ) + { + for( i = 0; i < d_size.height; i++, d += d_step, a += a_step, c += c_step ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2] + a[3]*b[b_step*3]; + double t1 = a[0]*b[1] + a[1]*b[b_step+1] + a[2]*b[b_step*2+1] + a[3]*b[b_step*3+1]; + double t2 = a[0]*b[2] + a[1]*b[b_step+2] + a[2]*b[b_step*2+2] + a[3]*b[b_step*3+2]; + double t3 = a[0]*b[3] + a[1]*b[b_step+3] + a[2]*b[b_step*2+3] + a[3]*b[b_step*3+3]; + d[0] = t0*alpha + c[0]*beta; + d[1] = t1*alpha + c[1]*beta; + d[2] = t2*alpha + c[2]*beta; + d[3] = t3*alpha + c[3]*beta; + } + } + else if( d_size.width <= 16 && a != d ) + { + int c_step0 = 1; + if( c == zero ) + { + c_step0 = 0; + c_step = 1; + } + + for( i = 0; i < d_size.width; i++, d++, b++, c += c_step0 ) + { + double t0 = a[0]*b[0] + a[1]*b[b_step] + a[2]*b[b_step*2] + a[3]*b[b_step*3]; + double t1 = a[a_step]*b[0] + a[a_step+1]*b[b_step] + + a[a_step+2]*b[b_step*2] + a[a_step+3]*b[b_step*3]; + double t2 = a[a_step*2]*b[0] + a[a_step*2+1]*b[b_step] + + a[a_step*2+2]*b[b_step*2] + a[a_step*2+3]*b[b_step*3]; + double t3 = a[a_step*3]*b[0] + a[a_step*3+1]*b[b_step] + + a[a_step*3+2]*b[b_step*2] + a[a_step*3+3]*b[b_step*3]; + d[0] = t0*alpha + c[0]*beta; + d[d_step] = t1*alpha + c[c_step]*beta; + d[d_step*2] = t2*alpha + c[c_step*2]*beta; + d[d_step*3] = t3*alpha + c[c_step*3]*beta; + } + } + else + break; + return; + } + } + } + + { + size_t b_step = B.step; + GEMMSingleMulFunc singleMulFunc; + GEMMBlockMulFunc blockMulFunc; + GEMMStoreFunc storeFunc; + Mat *matD = &D, tmat; + const uchar* Cdata = C.data; + size_t Cstep = C.data ? (size_t)C.step : 0; + AutoBuffer buf; + + if( type == CV_32FC1 ) + { + singleMulFunc = (GEMMSingleMulFunc)GEMMSingleMul_32f; + blockMulFunc = (GEMMBlockMulFunc)GEMMBlockMul_32f; + storeFunc = (GEMMStoreFunc)GEMMStore_32f; + } + else if( type == CV_64FC1 ) + { + singleMulFunc = (GEMMSingleMulFunc)GEMMSingleMul_64f; + blockMulFunc = (GEMMBlockMulFunc)GEMMBlockMul_64f; + storeFunc = (GEMMStoreFunc)GEMMStore_64f; + } + else if( type == CV_32FC2 ) + { + singleMulFunc = (GEMMSingleMulFunc)GEMMSingleMul_32fc; + blockMulFunc = (GEMMBlockMulFunc)GEMMBlockMul_32fc; + storeFunc = (GEMMStoreFunc)GEMMStore_32fc; + } + else + { + CV_Assert( type == CV_64FC2 ); + singleMulFunc = (GEMMSingleMulFunc)GEMMSingleMul_64fc; + blockMulFunc = (GEMMBlockMulFunc)GEMMBlockMul_64fc; + storeFunc = (GEMMStoreFunc)GEMMStore_64fc; + } + + if( D.data == A.data || D.data == B.data ) + { + buf.allocate(d_size.width*d_size.height*CV_ELEM_SIZE(type)); + tmat = Mat(d_size.height, d_size.width, type, (uchar*)buf ); + matD = &tmat; + } + + if( (d_size.width == 1 || len == 1) && !(flags & GEMM_2_T) && B.isContinuous() ) + { + b_step = d_size.width == 1 ? 0 : CV_ELEM_SIZE(type); + flags |= GEMM_2_T; + } + + /*if( (d_size.width | d_size.height | len) >= 16 && icvBLAS_GEMM_32f_p != 0 ) + { + blas_func = type == CV_32FC1 ? (icvBLAS_GEMM_32f_t)icvBLAS_GEMM_32f_p : + type == CV_64FC1 ? (icvBLAS_GEMM_32f_t)icvBLAS_GEMM_64f_p : + type == CV_32FC2 ? (icvBLAS_GEMM_32f_t)icvBLAS_GEMM_32fc_p : + type == CV_64FC2 ? (icvBLAS_GEMM_32f_t)icvBLAS_GEMM_64fc_p : 0; + } + + if( blas_func ) + { + const char* transa = flags & GEMM_1_T ? "t" : "n"; + const char* transb = flags & GEMM_2_T ? "t" : "n"; + int lda, ldb, ldd; + + if( C->data.ptr ) + { + if( C->data.ptr != D->data.ptr ) + { + if( !(flags & GEMM_3_T) ) + cvCopy( C, D ); + else + cvTranspose( C, D ); + } + } + + if( CV_MAT_DEPTH(type) == CV_32F ) + { + Complex32f _alpha, _beta; + + lda = A->step/sizeof(float); + ldb = b_step/sizeof(float); + ldd = D->step/sizeof(float); + _alpha.re = (float)alpha; + _alpha.im = 0; + _beta.re = C->data.ptr ? (float)beta : 0; + _beta.im = 0; + if( CV_MAT_CN(type) == 2 ) + lda /= 2, ldb /= 2, ldd /= 2; + + blas_func( transb, transa, &d_size.width, &d_size.height, &len, + &_alpha, B->data.ptr, &ldb, A->data.ptr, &lda, + &_beta, D->data.ptr, &ldd ); + } + else + { + CvComplex64f _alpha, _beta; + + lda = A->step/sizeof(double); + ldb = b_step/sizeof(double); + ldd = D->step/sizeof(double); + _alpha.re = alpha; + _alpha.im = 0; + _beta.re = C->data.ptr ? beta : 0; + _beta.im = 0; + if( CV_MAT_CN(type) == 2 ) + lda /= 2, ldb /= 2, ldd /= 2; + + blas_func( transb, transa, &d_size.width, &d_size.height, &len, + &_alpha, B->data.ptr, &ldb, A->data.ptr, &lda, + &_beta, D->data.ptr, &ldd ); + } + } + else*/ if( ((d_size.height <= block_lin_size/2 || d_size.width <= block_lin_size/2) && + len <= 10000) || len <= 10 || + (d_size.width <= block_lin_size && + d_size.height <= block_lin_size && len <= block_lin_size) ) + { + singleMulFunc( A.data, A.step, B.data, b_step, Cdata, Cstep, + matD->data, matD->step, a_size, d_size, alpha, beta, flags ); + } + else + { + int is_a_t = flags & GEMM_1_T; + int is_b_t = flags & GEMM_2_T; + int elem_size = CV_ELEM_SIZE(type); + int dk0_1, dk0_2; + int a_buf_size = 0, b_buf_size, d_buf_size; + uchar* a_buf = 0; + uchar* b_buf = 0; + uchar* d_buf = 0; + int j, k, di = 0, dj = 0, dk = 0; + int dm0, dn0, dk0; + size_t a_step0, a_step1, b_step0, b_step1, c_step0, c_step1; + int work_elem_size = elem_size << (CV_MAT_DEPTH(type) == CV_32F ? 1 : 0); + + if( !is_a_t ) + a_step0 = A.step, a_step1 = elem_size; + else + a_step0 = elem_size, a_step1 = A.step; + + if( !is_b_t ) + b_step0 = b_step, b_step1 = elem_size; + else + b_step0 = elem_size, b_step1 = b_step; + + if( !C.data ) + { + c_step0 = c_step1 = 0; + flags &= ~GEMM_3_T; + } + else if( !(flags & GEMM_3_T) ) + c_step0 = C.step, c_step1 = elem_size; + else + c_step0 = elem_size, c_step1 = C.step; + + dm0 = std::min( block_lin_size, d_size.height ); + dn0 = std::min( block_lin_size, d_size.width ); + dk0_1 = block_size / dm0; + dk0_2 = block_size / dn0; + dk0 = std::min( dk0_1, dk0_2 ); + dk0 = std::min( dk0, len ); + if( dk0*dm0 > block_size ) + dm0 = block_size / dk0; + if( dk0*dn0 > block_size ) + dn0 = block_size / dk0; + + dk0_1 = (dn0+dn0/8+2) & -2; + b_buf_size = (dk0+dk0/8+1)*dk0_1*elem_size; + d_buf_size = (dk0+dk0/8+1)*dk0_1*work_elem_size; + + if( is_a_t ) + { + a_buf_size = (dm0+dm0/8+1)*((dk0+dk0/8+2)&-2)*elem_size; + flags &= ~GEMM_1_T; + } + + buf.allocate(a_buf_size + b_buf_size + d_buf_size); + d_buf = (uchar*)buf; + b_buf = d_buf + d_buf_size; + + if( is_a_t ) + a_buf = b_buf + b_buf_size; + + for( i = 0; i < d_size.height; i += di ) + { + di = dm0; + if( i + di >= d_size.height || 8*(i + di) + di > 8*d_size.height ) + di = d_size.height - i; + + for( j = 0; j < d_size.width; j += dj ) + { + uchar* _d = matD->data + i*matD->step + j*elem_size; + const uchar* _c = Cdata + i*c_step0 + j*c_step1; + size_t _d_step = matD->step; + dj = dn0; + + if( j + dj >= d_size.width || 8*(j + dj) + dj > 8*d_size.width ) + dj = d_size.width - j; + + flags &= 15; + if( dk0 < len ) + { + _d = d_buf; + _d_step = dj*work_elem_size; + } + + for( k = 0; k < len; k += dk ) + { + const uchar* _a = A.data + i*a_step0 + k*a_step1; + size_t _a_step = A.step; + const uchar* _b = B.data + k*b_step0 + j*b_step1; + size_t _b_step = b_step; + Size a_bl_size; + + dk = dk0; + if( k + dk >= len || 8*(k + dk) + dk > 8*len ) + dk = len - k; + + if( !is_a_t ) + a_bl_size.width = dk, a_bl_size.height = di; + else + a_bl_size.width = di, a_bl_size.height = dk; + + if( a_buf && is_a_t ) + { + _a_step = dk*elem_size; + GEMM_TransposeBlock( _a, A.step, a_buf, _a_step, a_bl_size, elem_size ); + std::swap( a_bl_size.width, a_bl_size.height ); + _a = a_buf; + } + + if( dj < d_size.width ) + { + Size b_size; + if( !is_b_t ) + b_size.width = dj, b_size.height = dk; + else + b_size.width = dk, b_size.height = dj; + + _b_step = b_size.width*elem_size; + GEMM_CopyBlock( _b, b_step, b_buf, _b_step, b_size, elem_size ); + _b = b_buf; + } + + if( dk0 < len ) + blockMulFunc( _a, _a_step, _b, _b_step, _d, _d_step, + a_bl_size, Size(dj,di), flags ); + else + singleMulFunc( _a, _a_step, _b, _b_step, _c, Cstep, + _d, _d_step, a_bl_size, Size(dj,di), alpha, beta, flags ); + flags |= 16; + } + + if( dk0 < len ) + storeFunc( _c, Cstep, _d, _d_step, + matD->data + i*matD->step + j*elem_size, + matD->step, Size(dj,di), alpha, beta, flags ); + } + } + } + + if( matD != &D ) + matD->copyTo(D); + } +} + +/****************************************************************************************\ +* Transform * +\****************************************************************************************/ + +namespace cv +{ + +template static void +transform_( const T* src, T* dst, const WT* m, int len, int scn, int dcn ) +{ + int x; + + if( scn == 2 && dcn == 2 ) + { + for( x = 0; x < len*2; x += 2 ) + { + WT v0 = src[x], v1 = src[x+1]; + T t0 = saturate_cast(m[0]*v0 + m[1]*v1 + m[2]); + T t1 = saturate_cast(m[3]*v0 + m[4]*v1 + m[5]); + dst[x] = t0; dst[x+1] = t1; + } + } + else if( scn == 3 && dcn == 3 ) + { + for( x = 0; x < len*3; x += 3 ) + { + WT v0 = src[x], v1 = src[x+1], v2 = src[x+2]; + T t0 = saturate_cast(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]); + T t1 = saturate_cast(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]); + T t2 = saturate_cast(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]); + dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; + } + } + else if( scn == 3 && dcn == 1 ) + { + for( x = 0; x < len; x++, src += 3 ) + dst[x] = saturate_cast(m[0]*src[0] + m[1]*src[1] + m[2]*src[2] + m[3]); + } + else if( scn == 4 && dcn == 4 ) + { + for( x = 0; x < len*4; x += 4 ) + { + WT v0 = src[x], v1 = src[x+1], v2 = src[x+2], v3 = src[x+3]; + T t0 = saturate_cast(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]*v3 + m[4]); + T t1 = saturate_cast(m[5]*v0 + m[6]*v1 + m[7]*v2 + m[8]*v3 + m[9]); + dst[x] = t0; dst[x+1] = t1; + t0 = saturate_cast(m[10]*v0 + m[11]*v1 + m[12]*v2 + m[13]*v3 + m[14]); + t1 = saturate_cast(m[15]*v0 + m[16]*v1 + m[17]*v2 + m[18]*v3 + m[19]); + dst[x+2] = t0; dst[x+3] = t1; + } + } + else + { + for( x = 0; x < len; x++, src += scn, dst += dcn ) + { + const WT* _m = m; + int j, k; + for( j = 0; j < dcn; j++, _m += scn + 1 ) + { + WT s = _m[scn]; + for( k = 0; k < scn; k++ ) + s += _m[k]*src[k]; + dst[j] = saturate_cast(s); + } + } + } +} + +#if CV_SSE2 + +static inline void +load3x3Matrix( const float* m, __m128& m0, __m128& m1, __m128& m2, __m128& m3 ) +{ + m0 = _mm_setr_ps(m[0], m[4], m[8], 0); + m1 = _mm_setr_ps(m[1], m[5], m[9], 0); + m2 = _mm_setr_ps(m[2], m[6], m[10], 0); + m3 = _mm_setr_ps(m[3], m[7], m[11], 0); +} + +static inline void +load4x4Matrix( const float* m, __m128& m0, __m128& m1, __m128& m2, __m128& m3, __m128& m4 ) +{ + m0 = _mm_setr_ps(m[0], m[5], m[10], m[15]); + m1 = _mm_setr_ps(m[1], m[6], m[11], m[16]); + m2 = _mm_setr_ps(m[2], m[7], m[12], m[17]); + m3 = _mm_setr_ps(m[3], m[8], m[13], m[18]); + m4 = _mm_setr_ps(m[4], m[9], m[14], m[19]); +} + +#endif + +static void +transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn ) +{ +#if CV_SSE2 + const int BITS = 10, SCALE = 1 << BITS; + const float MAX_M = (float)(1 << (15 - BITS)); + + if( USE_SSE2 && scn == 3 && dcn == 3 && + std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[2]) < MAX_M && std::abs(m[3]) < MAX_M*256 && + std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[6]) < MAX_M && std::abs(m[7]) < MAX_M*256 && + std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M && std::abs(m[11]) < MAX_M*256 ) + { + // faster fixed-point transformation + short m00 = saturate_cast(m[0]*SCALE), m01 = saturate_cast(m[1]*SCALE), + m02 = saturate_cast(m[2]*SCALE), m10 = saturate_cast(m[4]*SCALE), + m11 = saturate_cast(m[5]*SCALE), m12 = saturate_cast(m[6]*SCALE), + m20 = saturate_cast(m[8]*SCALE), m21 = saturate_cast(m[9]*SCALE), + m22 = saturate_cast(m[10]*SCALE); + int m03 = saturate_cast((m[3]+0.5f)*SCALE), m13 = saturate_cast((m[7]+0.5f)*SCALE ), + m23 = saturate_cast((m[11]+0.5f)*SCALE); + + __m128i m0 = _mm_setr_epi16(0, m00, m01, m02, m00, m01, m02, 0); + __m128i m1 = _mm_setr_epi16(0, m10, m11, m12, m10, m11, m12, 0); + __m128i m2 = _mm_setr_epi16(0, m20, m21, m22, m20, m21, m22, 0); + __m128i m3 = _mm_setr_epi32(m03, m13, m23, 0); + int x = 0; + + for( ; x <= (len - 8)*3; x += 8*3 ) + { + __m128i z = _mm_setzero_si128(), t0, t1, t2, r0, r1; + __m128i v0 = _mm_loadl_epi64((const __m128i*)(src + x)); + __m128i v1 = _mm_loadl_epi64((const __m128i*)(src + x + 8)); + __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 16)), v3; + v0 = _mm_unpacklo_epi8(v0, z); // b0 g0 r0 b1 g1 r1 b2 g2 + v1 = _mm_unpacklo_epi8(v1, z); // r2 b3 g3 r3 b4 g4 r4 b5 + v2 = _mm_unpacklo_epi8(v2, z); // g5 r5 b6 g6 r6 b7 g7 r7 + + v3 = _mm_srli_si128(v2, 2); // ? b6 g6 r6 b7 g7 r7 0 + v2 = _mm_or_si128(_mm_slli_si128(v2, 10), _mm_srli_si128(v1, 6)); // ? b4 g4 r4 b5 g5 r5 ? + v1 = _mm_or_si128(_mm_slli_si128(v1, 6), _mm_srli_si128(v0, 10)); // ? b2 g2 r2 b3 g3 r3 ? + v0 = _mm_slli_si128(v0, 2); // 0 b0 g0 r0 b1 g1 r1 ? + + // process pixels 0 & 1 + t0 = _mm_madd_epi16(v0, m0); // a0 b0 a1 b1 + t1 = _mm_madd_epi16(v0, m1); // c0 d0 c1 d1 + t2 = _mm_madd_epi16(v0, m2); // e0 f0 e1 f1 + v0 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0 + t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1 + t1 = _mm_unpacklo_epi32(t2, z); // e0 0 f0 0 + t2 = _mm_unpackhi_epi32(t2, z); // e1 0 f1 0 + r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v0, t1), _mm_unpackhi_epi64(v0,t1)), m3); // B0 G0 R0 0 + r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B1 G1 R1 0 + r0 = _mm_srai_epi32(r0, BITS); + r1 = _mm_srai_epi32(r1, BITS); + v0 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B0 G0 R0 B1 G1 R1 0 + + // process pixels 2 & 3 + t0 = _mm_madd_epi16(v1, m0); // a0 b0 a1 b1 + t1 = _mm_madd_epi16(v1, m1); // c0 d0 c1 d1 + t2 = _mm_madd_epi16(v1, m2); // e0 f0 e1 f1 + v1 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0 + t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1 + t1 = _mm_unpacklo_epi32(t2, z); // e0 0 f0 0 + t2 = _mm_unpackhi_epi32(t2, z); // e1 0 f1 0 + r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v1, t1), _mm_unpackhi_epi64(v1,t1)), m3); // B2 G2 R2 0 + r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B3 G3 R3 0 + r0 = _mm_srai_epi32(r0, BITS); + r1 = _mm_srai_epi32(r1, BITS); + v1 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B2 G2 R2 B3 G3 R3 0 + + // process pixels 4 & 5 + t0 = _mm_madd_epi16(v2, m0); // a0 b0 a1 b1 + t1 = _mm_madd_epi16(v2, m1); // c0 d0 c1 d1 + t2 = _mm_madd_epi16(v2, m2); // e0 f0 e1 f1 + v2 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0 + t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1 + t1 = _mm_unpacklo_epi32(t2, z); // e0 0 f0 0 + t2 = _mm_unpackhi_epi32(t2, z); // e1 0 f1 0 + r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v2, t1), _mm_unpackhi_epi64(v2,t1)), m3); // B4 G4 R4 0 + r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B5 G5 R5 0 + r0 = _mm_srai_epi32(r0, BITS); + r1 = _mm_srai_epi32(r1, BITS); + v2 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B4 G4 R4 B5 G5 R5 0 + + // process pixels 6 & 7 + t0 = _mm_madd_epi16(v3, m0); // a0 b0 a1 b1 + t1 = _mm_madd_epi16(v3, m1); // c0 d0 c1 d1 + t2 = _mm_madd_epi16(v3, m2); // e0 f0 e1 f1 + v3 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0 + t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1 + t1 = _mm_unpacklo_epi32(t2, z); // e0 0 f0 0 + t2 = _mm_unpackhi_epi32(t2, z); // e1 0 f1 0 + r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v3, t1), _mm_unpackhi_epi64(v3,t1)), m3); // B6 G6 R6 0 + r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B7 G7 R7 0 + r0 = _mm_srai_epi32(r0, BITS); + r1 = _mm_srai_epi32(r1, BITS); + v3 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B6 G6 R6 B7 G7 R7 0 + + v0 = _mm_or_si128(_mm_srli_si128(v0, 1), _mm_slli_si128(v1, 5)); + v1 = _mm_or_si128(_mm_srli_si128(v1, 3), _mm_slli_si128(v2, 3)); + v2 = _mm_or_si128(_mm_srli_si128(v2, 5), _mm_slli_si128(v3, 1)); + _mm_storel_epi64((__m128i*)(dst + x), v0); + _mm_storel_epi64((__m128i*)(dst + x + 8), v1); + _mm_storel_epi64((__m128i*)(dst + x + 16), v2); + } + + for( ; x < len*3; x += 3 ) + { + int v0 = src[x], v1 = src[x+1], v2 = src[x+2]; + uchar t0 = saturate_cast((m00*v0 + m01*v1 + m02*v2 + m03)>>BITS); + uchar t1 = saturate_cast((m10*v0 + m11*v1 + m12*v2 + m13)>>BITS); + uchar t2 = saturate_cast((m20*v0 + m21*v1 + m22*v2 + m23)>>BITS); + dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; + } + return; + } +#endif + + transform_(src, dst, m, len, scn, dcn); +} + +static void +transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn ) +{ +#if CV_SSE2 + if( USE_SSE2 && scn == 3 && dcn == 3 ) + { + __m128 m0, m1, m2, m3; + __m128i delta = _mm_setr_epi16(0,-32768,-32768,-32768,-32768,-32768,-32768,0); + load3x3Matrix(m, m0, m1, m2, m3); + m3 = _mm_sub_ps(m3, _mm_setr_ps(32768.f, 32768.f, 32768.f, 0.f)); + + int x = 0; + for( ; x <= (len - 4)*3; x += 4*3 ) + { + __m128i z = _mm_setzero_si128(); + __m128i v0 = _mm_loadu_si128((const __m128i*)(src + x)), v1; + __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 8)), v3; + v1 = _mm_unpacklo_epi16(_mm_srli_si128(v0, 6), z); // b1 g1 r1 + v3 = _mm_unpacklo_epi16(_mm_srli_si128(v2, 2), z); // b3 g3 r3 + v2 = _mm_or_si128(_mm_srli_si128(v0, 12), _mm_slli_si128(v2, 4)); + v0 = _mm_unpacklo_epi16(v0, z); // b0 g0 r0 + v2 = _mm_unpacklo_epi16(v2, z); // b2 g2 r2 + __m128 x0 = _mm_cvtepi32_ps(v0), x1 = _mm_cvtepi32_ps(v1); + __m128 x2 = _mm_cvtepi32_ps(v2), x3 = _mm_cvtepi32_ps(v3); + __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), m3); + __m128 y1 = _mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(2,2,2,2)))), m3); + __m128 y2 = _mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)))), m3); + __m128 y3 = _mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(2,2,2,2)))), m3); + v0 = _mm_cvtps_epi32(y0); v1 = _mm_cvtps_epi32(y1); + v2 = _mm_cvtps_epi32(y2); v3 = _mm_cvtps_epi32(y3); + + v0 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v0,4), v1), delta); // 0 b0 g0 r0 b1 g1 r1 0 + v2 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v2,4), v3), delta); // 0 b2 g2 r2 b3 g3 r3 0 + v1 = _mm_or_si128(_mm_srli_si128(v0,2), _mm_slli_si128(v2,10)); // b0 g0 r0 b1 g1 r1 b2 g2 + v2 = _mm_srli_si128(v2, 6); // r2 b3 g3 r3 0 0 0 0 + _mm_storeu_si128((__m128i*)(dst + x), v1); + _mm_storel_epi64((__m128i*)(dst + x + 8), v2); + } + + for( ; x < len*3; x += 3 ) + { + float v0 = src[x], v1 = src[x+1], v2 = src[x+2]; + ushort t0 = saturate_cast(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]); + ushort t1 = saturate_cast(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]); + ushort t2 = saturate_cast(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]); + dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; + } + return; + } +#endif + + transform_(src, dst, m, len, scn, dcn); +} + + +static void +transform_32f( const float* src, float* dst, const float* m, int len, int scn, int dcn ) +{ +#if CV_SSE2 + if( USE_SSE2 ) + { + int x = 0; + if( scn == 3 && dcn == 3 ) + { + __m128 m0, m1, m2, m3; + load3x3Matrix(m, m0, m1, m2, m3); + + for( ; x < (len - 1)*3; x += 3 ) + { + __m128 x0 = _mm_loadu_ps(src + x); + __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), m3); + _mm_storel_pi((__m64*)(dst + x), y0); + _mm_store_ss(dst + x + 2, _mm_movehl_ps(y0,y0)); + } + + for( ; x < len*3; x += 3 ) + { + float v0 = src[x], v1 = src[x+1], v2 = src[x+2]; + float t0 = saturate_cast(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]); + float t1 = saturate_cast(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]); + float t2 = saturate_cast(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]); + dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; + } + return; + } + + if( scn == 4 && dcn == 4 ) + { + __m128 m0, m1, m2, m3, m4; + load4x4Matrix(m, m0, m1, m2, m3, m4); + + for( ; x < len*4; x += 4 ) + { + __m128 x0 = _mm_loadu_ps(src + x); + __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps(_mm_add_ps( + _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))), + _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), + _mm_mul_ps(m3, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(3,3,3,3)))), m4); + _mm_storeu_ps(dst + x, y0); + } + return; + } + } +#endif + + transform_(src, dst, m, len, scn, dcn); +} + + +static void +transform_8s(const schar* src, schar* dst, const float* m, int len, int scn, int dcn) +{ + transform_(src, dst, m, len, scn, dcn); +} + +static void +transform_16s(const short* src, short* dst, const float* m, int len, int scn, int dcn) +{ + transform_(src, dst, m, len, scn, dcn); +} + +static void +transform_32s(const int* src, int* dst, const double* m, int len, int scn, int dcn) +{ + transform_(src, dst, m, len, scn, dcn); +} + +static void +transform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn) +{ + transform_(src, dst, m, len, scn, dcn); +} + +template static void +diagtransform_( const T* src, T* dst, const WT* m, int len, int cn, int ) +{ + int x; + + if( cn == 2 ) + { + for( x = 0; x < len*2; x += 2 ) + { + T t0 = saturate_cast(m[0]*src[x] + m[2]); + T t1 = saturate_cast(m[4]*src[x+1] + m[5]); + dst[x] = t0; dst[x+1] = t1; + } + } + else if( cn == 3 ) + { + for( x = 0; x < len*3; x += 3 ) + { + T t0 = saturate_cast(m[0]*src[x] + m[3]); + T t1 = saturate_cast(m[5]*src[x+1] + m[7]); + T t2 = saturate_cast(m[10]*src[x+2] + m[11]); + dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; + } + } + else if( cn == 4 ) + { + for( x = 0; x < len*4; x += 4 ) + { + T t0 = saturate_cast(m[0]*src[x] + m[4]); + T t1 = saturate_cast(m[6]*src[x+1] + m[9]); + dst[x] = t0; dst[x+1] = t1; + t0 = saturate_cast(m[12]*src[x+2] + m[14]); + t1 = saturate_cast(m[18]*src[x+3] + m[19]); + dst[x+2] = t0; dst[x+3] = t1; + } + } + else + { + for( x = 0; x < len; x++, src += cn, dst += cn ) + { + const WT* _m = m; + for( int j = 0; j < cn; j++, _m += cn + 1 ) + dst[j] = saturate_cast(src[j]*_m[j] + _m[cn]); + } + } +} + +static void +diagtransform_8u(const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_8s(const schar* src, schar* dst, const float* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_16u(const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_16s(const short* src, short* dst, const float* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_32s(const int* src, int* dst, const double* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_32f(const float* src, float* dst, const float* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + +static void +diagtransform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn) +{ + diagtransform_(src, dst, m, len, scn, dcn); +} + + +typedef void (*TransformFunc)( const uchar* src, uchar* dst, const uchar* m, int, int, int ); + +static TransformFunc transformTab[] = +{ + (TransformFunc)transform_8u, (TransformFunc)transform_8s, (TransformFunc)transform_16u, + (TransformFunc)transform_16s, (TransformFunc)transform_32s, (TransformFunc)transform_32f, + (TransformFunc)transform_64f, 0 +}; + +static TransformFunc diagTransformTab[] = +{ + (TransformFunc)diagtransform_8u, (TransformFunc)diagtransform_8s, (TransformFunc)diagtransform_16u, + (TransformFunc)diagtransform_16s, (TransformFunc)diagtransform_32s, (TransformFunc)diagtransform_32f, + (TransformFunc)diagtransform_64f, 0 +}; + +} + +void cv::transform( InputArray _src, OutputArray _dst, InputArray _mtx ) +{ + Mat src = _src.getMat(), m = _mtx.getMat(); + int depth = src.depth(), scn = src.channels(), dcn = m.rows; + CV_Assert( scn == m.cols || scn + 1 == m.cols ); + bool isDiag = false; + + _dst.create( src.size(), CV_MAKETYPE(depth, dcn) ); + Mat dst = _dst.getMat(); + + int mtype = depth == CV_32S || depth == CV_64F ? CV_64F : CV_32F; + AutoBuffer _mbuf; + double* mbuf; + + if( !m.isContinuous() || m.type() != mtype || m.cols != scn + 1 ) + { + _mbuf.allocate(dcn*(scn+1)); + mbuf = (double*)_mbuf; + Mat tmp(dcn, scn+1, mtype, mbuf); + memset(tmp.data, 0, tmp.total()*tmp.elemSize()); + if( m.cols == scn+1 ) + m.convertTo(tmp, mtype); + else + { + Mat tmppart = tmp.colRange(0, m.cols); + m.convertTo(tmppart, mtype); + } + m = tmp; + } + else + mbuf = (double*)m.data; + + if( scn == dcn ) + { + int i, j; + double eps = mtype == CV_32F ? FLT_EPSILON : DBL_EPSILON; + + if( scn == 1 ) + { + double alpha, beta; + if( mtype == CV_32F ) + alpha = m.at(0), beta = m.at(1); + else + alpha = m.at(0), beta = m.at(1); + src.convertTo(dst, dst.type(), alpha, beta); + return; + } + + for( i = 0, isDiag = true; isDiag && i < scn; i++ ) + { + for( j = 0; isDiag && j < scn; j++ ) + { + double v = mtype == CV_32F ? m.at(i, j) : m.at(i, j); + if( i != j && fabs(v) > eps ) + isDiag = false; + } + } + } + + TransformFunc func = isDiag ? diagTransformTab[depth] : transformTab[depth]; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + size_t i, total = it.size; + + for( i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], ptrs[1], (uchar*)mbuf, (int)total, scn, dcn ); +} + +/****************************************************************************************\ +* Perspective Transform * +\****************************************************************************************/ + +namespace cv +{ + +template static void +perspectiveTransform_( const T* src, T* dst, const double* m, int len, int scn, int dcn ) +{ + const double eps = FLT_EPSILON; + int i; + + if( scn == 2 && dcn == 2 ) + { + for( i = 0; i < len*2; i += 2 ) + { + T x = src[i], y = src[i + 1]; + double w = x*m[6] + y*m[7] + m[8]; + + if( fabs(w) > eps ) + { + w = 1./w; + dst[i] = (T)((x*m[0] + y*m[1] + m[2])*w); + dst[i+1] = (T)((x*m[3] + y*m[4] + m[5])*w); + } + else + dst[i] = dst[i+1] = (T)0; + } + } + else if( scn == 3 && dcn == 3 ) + { + for( i = 0; i < len*3; i += 3 ) + { + T x = src[i], y = src[i + 1], z = src[i + 2]; + double w = x*m[12] + y*m[13] + z*m[14] + m[15]; + + if( fabs(w) > eps ) + { + w = 1./w; + dst[i] = (T)((x*m[0] + y*m[1] + z*m[2] + m[3]) * w); + dst[i+1] = (T)((x*m[4] + y*m[5] + z*m[6] + m[7]) * w); + dst[i+2] = (T)((x*m[8] + y*m[9] + z*m[10] + m[11]) * w); + } + else + dst[i] = dst[i+1] = dst[i+2] = (T)0; + } + } + else if( scn == 3 && dcn == 2 ) + { + for( i = 0; i < len; i++, src += 3, dst += 2 ) + { + T x = src[0], y = src[1], z = src[2]; + double w = x*m[8] + y*m[9] + z*m[10] + m[11]; + + if( fabs(w) > eps ) + { + w = 1./w; + dst[0] = (T)((x*m[0] + y*m[1] + z*m[2] + m[3])*w); + dst[1] = (T)((x*m[4] + y*m[5] + z*m[6] + m[7])*w); + } + else + dst[0] = dst[1] = (T)0; + } + } + else + { + for( i = 0; i < len; i++, src += scn, dst += dcn ) + { + const double* _m = m + dcn*(scn + 1); + double w = _m[scn]; + int j, k; + for( k = 0; k < scn; k++ ) + w += _m[k]*src[k]; + if( fabs(w) > eps ) + { + _m = m; + for( j = 0; j < dcn; j++, _m += scn + 1 ) + { + double s = _m[scn]; + for( k = 0; k < scn; k++ ) + s += _m[k]*src[k]; + dst[j] = (T)(s*w); + } + } + else + for( j = 0; j < dcn; j++ ) + dst[j] = 0; + } + } +} + + +static void +perspectiveTransform_32f(const float* src, float* dst, const double* m, int len, int scn, int dcn) +{ + perspectiveTransform_(src, dst, m, len, scn, dcn); +} + +static void +perspectiveTransform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn) +{ + perspectiveTransform_(src, dst, m, len, scn, dcn); +} + +} + +void cv::perspectiveTransform( InputArray _src, OutputArray _dst, InputArray _mtx ) +{ + Mat src = _src.getMat(), m = _mtx.getMat(); + int depth = src.depth(), scn = src.channels(), dcn = m.rows-1; + CV_Assert( scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)); + + _dst.create( src.size(), CV_MAKETYPE(depth, dcn) ); + Mat dst = _dst.getMat(); + + const int mtype = CV_64F; + AutoBuffer _mbuf; + double* mbuf = _mbuf; + + if( !m.isContinuous() || m.type() != mtype ) + { + _mbuf.allocate((dcn+1)*(scn+1)); + Mat tmp(dcn+1, scn+1, mtype, (double*)_mbuf); + m.convertTo(tmp, mtype); + m = tmp; + } + else + mbuf = (double*)m.data; + + TransformFunc func = depth == CV_32F ? + (TransformFunc)perspectiveTransform_32f : + (TransformFunc)perspectiveTransform_64f; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + size_t i, total = it.size; + + for( i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], ptrs[1], (uchar*)mbuf, (int)total, scn, dcn ); +} + +/****************************************************************************************\ +* ScaleAdd * +\****************************************************************************************/ + +namespace cv +{ + +static void scaleAdd_32f(const float* src1, const float* src2, float* dst, + int len, float* _alpha) +{ + float alpha = *_alpha; + int i = 0; +#if CV_SSE2 + if( USE_SSE2 ) + { + __m128 a4 = _mm_set1_ps(alpha); + if( (((size_t)src1|(size_t)src2|(size_t)dst) & 15) == 0 ) + for( ; i <= len - 8; i += 8 ) + { + __m128 x0, x1, y0, y1, t0, t1; + x0 = _mm_load_ps(src1 + i); x1 = _mm_load_ps(src1 + i + 4); + y0 = _mm_load_ps(src2 + i); y1 = _mm_load_ps(src2 + i + 4); + t0 = _mm_add_ps(_mm_mul_ps(x0, a4), y0); + t1 = _mm_add_ps(_mm_mul_ps(x1, a4), y1); + _mm_store_ps(dst + i, t0); + _mm_store_ps(dst + i + 4, t1); + } + else + for( ; i <= len - 8; i += 8 ) + { + __m128 x0, x1, y0, y1, t0, t1; + x0 = _mm_loadu_ps(src1 + i); x1 = _mm_loadu_ps(src1 + i + 4); + y0 = _mm_loadu_ps(src2 + i); y1 = _mm_loadu_ps(src2 + i + 4); + t0 = _mm_add_ps(_mm_mul_ps(x0, a4), y0); + t1 = _mm_add_ps(_mm_mul_ps(x1, a4), y1); + _mm_storeu_ps(dst + i, t0); + _mm_storeu_ps(dst + i + 4, t1); + } + } + else +#endif + //vz why do we need unroll here? + for( ; i <= len - 4; i += 4 ) + { + float t0, t1; + t0 = src1[i]*alpha + src2[i]; + t1 = src1[i+1]*alpha + src2[i+1]; + dst[i] = t0; dst[i+1] = t1; + t0 = src1[i+2]*alpha + src2[i+2]; + t1 = src1[i+3]*alpha + src2[i+3]; + dst[i+2] = t0; dst[i+3] = t1; + } + for(; i < len; i++ ) + dst[i] = src1[i]*alpha + src2[i]; +} + + +static void scaleAdd_64f(const double* src1, const double* src2, double* dst, + int len, double* _alpha) +{ + double alpha = *_alpha; + int i = 0; +#if CV_SSE2 + if( USE_SSE2 && (((size_t)src1|(size_t)src2|(size_t)dst) & 15) == 0 ) + { + __m128d a2 = _mm_set1_pd(alpha); + for( ; i <= len - 4; i += 4 ) + { + __m128d x0, x1, y0, y1, t0, t1; + x0 = _mm_load_pd(src1 + i); x1 = _mm_load_pd(src1 + i + 2); + y0 = _mm_load_pd(src2 + i); y1 = _mm_load_pd(src2 + i + 2); + t0 = _mm_add_pd(_mm_mul_pd(x0, a2), y0); + t1 = _mm_add_pd(_mm_mul_pd(x1, a2), y1); + _mm_store_pd(dst + i, t0); + _mm_store_pd(dst + i + 2, t1); + } + } + else +#endif + //vz why do we need unroll here? + for( ; i <= len - 4; i += 4 ) + { + double t0, t1; + t0 = src1[i]*alpha + src2[i]; + t1 = src1[i+1]*alpha + src2[i+1]; + dst[i] = t0; dst[i+1] = t1; + t0 = src1[i+2]*alpha + src2[i+2]; + t1 = src1[i+3]*alpha + src2[i+3]; + dst[i+2] = t0; dst[i+3] = t1; + } + for(; i < len; i++ ) + dst[i] = src1[i]*alpha + src2[i]; +} + +typedef void (*ScaleAddFunc)(const uchar* src1, const uchar* src2, uchar* dst, int len, const void* alpha); + +} + +void cv::scaleAdd( InputArray _src1, double alpha, InputArray _src2, OutputArray _dst ) +{ + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + int depth = src1.depth(), cn = src1.channels(); + + CV_Assert( src1.type() == src2.type() ); + if( depth < CV_32F ) + { + addWeighted(_src1, alpha, _src2, 1, 0, _dst, depth); + return; + } + + _dst.create(src1.dims, src1.size, src1.type()); + Mat dst = _dst.getMat(); + + float falpha = (float)alpha; + void* palpha = depth == CV_32F ? (void*)&falpha : (void*)α + + ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f; + + if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) + { + size_t len = src1.total()*cn; + func(src1.data, src2.data, dst.data, (int)len, palpha); + return; + } + + const Mat* arrays[] = {&src1, &src2, &dst, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + size_t i, len = it.size*cn; + + for( i = 0; i < it.nplanes; i++, ++it ) + func( ptrs[0], ptrs[1], ptrs[2], (int)len, palpha ); +} + +/****************************************************************************************\ +* Covariation Matrix * +\****************************************************************************************/ + +void cv::calcCovarMatrix( const Mat* data, int nsamples, Mat& covar, Mat& _mean, int flags, int ctype ) +{ + CV_Assert( data && nsamples > 0 ); + Size size = data[0].size(); + int sz = size.width * size.height, esz = (int)data[0].elemSize(); + int type = data[0].type(); + Mat mean; + ctype = std::max(std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), _mean.depth()), CV_32F); + + if( (flags & CV_COVAR_USE_AVG) != 0 ) + { + CV_Assert( _mean.size() == size ); + if( _mean.isContinuous() && _mean.type() == ctype ) + mean = _mean.reshape(1, 1); + else + { + _mean.convertTo(mean, ctype); + mean = mean.reshape(1, 1); + } + } + + Mat _data(nsamples, sz, type); + + for( int i = 0; i < nsamples; i++ ) + { + CV_Assert( data[i].size() == size && data[i].type() == type ); + if( data[i].isContinuous() ) + memcpy( _data.ptr(i), data[i].data, sz*esz ); + else + { + Mat dataRow(size.height, size.width, type, _data.ptr(i)); + data[i].copyTo(dataRow); + } + } + + calcCovarMatrix( _data, covar, mean, (flags & ~(CV_COVAR_ROWS|CV_COVAR_COLS)) | CV_COVAR_ROWS, ctype ); + if( (flags & CV_COVAR_USE_AVG) == 0 ) + _mean = mean.reshape(1, size.height); +} + +void cv::calcCovarMatrix( InputArray _src, OutputArray _covar, InputOutputArray _mean, int flags, int ctype ) +{ + if(_src.kind() == _InputArray::STD_VECTOR_MAT) + { + std::vector src; + _src.getMatVector(src); + + CV_Assert( src.size() > 0 ); + + Size size = src[0].size(); + int type = src[0].type(); + + ctype = std::max(std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), _mean.depth()), CV_32F); + + Mat _data(static_cast(src.size()), size.area(), type); + + int i = 0; + for(vector::iterator each = src.begin(); each != src.end(); each++, i++ ) + { + CV_Assert( (*each).size() == size && (*each).type() == type ); + Mat dataRow(size.height, size.width, type, _data.ptr(i)); + (*each).copyTo(dataRow); + } + + Mat mean; + if( (flags & CV_COVAR_USE_AVG) != 0 ) + { + CV_Assert( _mean.size() == size ); + + if( mean.type() != ctype ) + { + mean = _mean.getMat(); + _mean.create(mean.size(), ctype); + Mat tmp = _mean.getMat(); + mean.convertTo(tmp, ctype); + mean = tmp; + } + + mean = _mean.getMat().reshape(1, 1); + } + + calcCovarMatrix( _data, _covar, mean, (flags & ~(CV_COVAR_ROWS|CV_COVAR_COLS)) | CV_COVAR_ROWS, ctype ); + + if( (flags & CV_COVAR_USE_AVG) == 0 ) + { + mean = mean.reshape(1, size.height); + mean.copyTo(_mean); + } + return; + } + + Mat data = _src.getMat(), mean; + CV_Assert( ((flags & CV_COVAR_ROWS) != 0) ^ ((flags & CV_COVAR_COLS) != 0) ); + bool takeRows = (flags & CV_COVAR_ROWS) != 0; + int type = data.type(); + int nsamples = takeRows ? data.rows : data.cols; + CV_Assert( nsamples > 0 ); + Size size = takeRows ? Size(data.cols, 1) : Size(1, data.rows); + + if( (flags & CV_COVAR_USE_AVG) != 0 ) + { + mean = _mean.getMat(); + ctype = std::max(std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), mean.depth()), CV_32F); + CV_Assert( mean.size() == size ); + if( mean.type() != ctype ) + { + _mean.create(mean.size(), ctype); + Mat tmp = _mean.getMat(); + mean.convertTo(tmp, ctype); + mean = tmp; + } + } + else + { + ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F); + reduce( _src, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype ); + mean = _mean.getMat(); + } + + mulTransposed( data, _covar, ((flags & CV_COVAR_NORMAL) == 0) ^ takeRows, + mean, (flags & CV_COVAR_SCALE) != 0 ? 1./nsamples : 1, ctype ); +} + +/****************************************************************************************\ +* Mahalanobis * +\****************************************************************************************/ + +double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar ) +{ + Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat(); + int type = v1.type(), depth = v1.depth(); + Size sz = v1.size(); + int i, j, len = sz.width*sz.height*v1.channels(); + AutoBuffer buf(len); + double result = 0; + + CV_Assert( type == v2.type() && type == icovar.type() && + sz == v2.size() && len == icovar.rows && len == icovar.cols ); + + sz.width *= v1.channels(); + if( v1.isContinuous() && v2.isContinuous() ) + { + sz.width *= sz.height; + sz.height = 1; + } + + if( depth == CV_32F ) + { + const float* src1 = (const float*)v1.data; + const float* src2 = (const float*)v2.data; + size_t step1 = v1.step/sizeof(src1[0]); + size_t step2 = v2.step/sizeof(src2[0]); + double* diff = buf; + const float* mat = (const float*)icovar.data; + size_t matstep = icovar.step/sizeof(mat[0]); + + for( ; sz.height--; src1 += step1, src2 += step2, diff += sz.width ) + { + for( i = 0; i < sz.width; i++ ) + diff[i] = src1[i] - src2[i]; + } + + diff = buf; + for( i = 0; i < len; i++, mat += matstep ) + { + double row_sum = 0; + j = 0; + #if CV_ENABLE_UNROLLED + for(; j <= len - 4; j += 4 ) + row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] + + diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3]; + #endif + for( ; j < len; j++ ) + row_sum += diff[j]*mat[j]; + result += row_sum * diff[i]; + } + } + else if( depth == CV_64F ) + { + const double* src1 = (const double*)v1.data; + const double* src2 = (const double*)v2.data; + size_t step1 = v1.step/sizeof(src1[0]); + size_t step2 = v2.step/sizeof(src2[0]); + double* diff = buf; + const double* mat = (const double*)icovar.data; + size_t matstep = icovar.step/sizeof(mat[0]); + + for( ; sz.height--; src1 += step1, src2 += step2, diff += sz.width ) + { + for( i = 0; i < sz.width; i++ ) + diff[i] = src1[i] - src2[i]; + } + + diff = buf; + for( i = 0; i < len; i++, mat += matstep ) + { + double row_sum = 0; + j = 0; + #if CV_ENABLE_UNROLLED + for(; j <= len - 4; j += 4 ) + row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] + + diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3]; + #endif + for( ; j < len; j++ ) + row_sum += diff[j]*mat[j]; + result += row_sum * diff[i]; + } + } + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + return std::sqrt(result); +} + +double cv::Mahalonobis( InputArray _v1, InputArray _v2, InputArray _icovar ) +{ + return Mahalanobis(_v1, _v2, _icovar); +} + +/****************************************************************************************\ +* MulTransposed * +\****************************************************************************************/ + +namespace cv +{ + +template static void +MulTransposedR( const Mat& srcmat, Mat& dstmat, const Mat& deltamat, double scale ) +{ + int i, j, k; + const sT* src = (const sT*)srcmat.data; + dT* dst = (dT*)dstmat.data; + const dT* delta = (const dT*)deltamat.data; + size_t srcstep = srcmat.step/sizeof(src[0]); + size_t dststep = dstmat.step/sizeof(dst[0]); + size_t deltastep = deltamat.rows > 1 ? deltamat.step/sizeof(delta[0]) : 0; + int delta_cols = deltamat.cols; + Size size = srcmat.size(); + dT* tdst = dst; + dT* col_buf = 0; + dT* delta_buf = 0; + int buf_size = size.height*sizeof(dT); + AutoBuffer buf; + + if( delta && delta_cols < size.width ) + { + assert( delta_cols == 1 ); + buf_size *= 5; + } + buf.allocate(buf_size); + col_buf = (dT*)(uchar*)buf; + + if( delta && delta_cols < size.width ) + { + delta_buf = col_buf + size.height; + for( i = 0; i < size.height; i++ ) + delta_buf[i*4] = delta_buf[i*4+1] = + delta_buf[i*4+2] = delta_buf[i*4+3] = delta[i*deltastep]; + delta = delta_buf; + deltastep = deltastep ? 4 : 0; + } + + if( !delta ) + for( i = 0; i < size.width; i++, tdst += dststep ) + { + for( k = 0; k < size.height; k++ ) + col_buf[k] = src[k*srcstep+i]; + + for( j = i; j <= size.width - 4; j += 4 ) + { + double s0 = 0, s1 = 0, s2 = 0, s3 = 0; + const sT *tsrc = src + j; + + for( k = 0; k < size.height; k++, tsrc += srcstep ) + { + double a = col_buf[k]; + s0 += a * tsrc[0]; + s1 += a * tsrc[1]; + s2 += a * tsrc[2]; + s3 += a * tsrc[3]; + } + + tdst[j] = (dT)(s0*scale); + tdst[j+1] = (dT)(s1*scale); + tdst[j+2] = (dT)(s2*scale); + tdst[j+3] = (dT)(s3*scale); + } + + for( ; j < size.width; j++ ) + { + double s0 = 0; + const sT *tsrc = src + j; + + for( k = 0; k < size.height; k++, tsrc += srcstep ) + s0 += (double)col_buf[k] * tsrc[0]; + + tdst[j] = (dT)(s0*scale); + } + } + else + for( i = 0; i < size.width; i++, tdst += dststep ) + { + if( !delta_buf ) + for( k = 0; k < size.height; k++ ) + col_buf[k] = src[k*srcstep+i] - delta[k*deltastep+i]; + else + for( k = 0; k < size.height; k++ ) + col_buf[k] = src[k*srcstep+i] - delta_buf[k*deltastep]; + + for( j = i; j <= size.width - 4; j += 4 ) + { + double s0 = 0, s1 = 0, s2 = 0, s3 = 0; + const sT *tsrc = src + j; + const dT *d = delta_buf ? delta_buf : delta + j; + + for( k = 0; k < size.height; k++, tsrc+=srcstep, d+=deltastep ) + { + double a = col_buf[k]; + s0 += a * (tsrc[0] - d[0]); + s1 += a * (tsrc[1] - d[1]); + s2 += a * (tsrc[2] - d[2]); + s3 += a * (tsrc[3] - d[3]); + } + + tdst[j] = (dT)(s0*scale); + tdst[j+1] = (dT)(s1*scale); + tdst[j+2] = (dT)(s2*scale); + tdst[j+3] = (dT)(s3*scale); + } + + for( ; j < size.width; j++ ) + { + double s0 = 0; + const sT *tsrc = src + j; + const dT *d = delta_buf ? delta_buf : delta + j; + + for( k = 0; k < size.height; k++, tsrc+=srcstep, d+=deltastep ) + s0 += (double)col_buf[k] * (tsrc[0] - d[0]); + + tdst[j] = (dT)(s0*scale); + } + } +} + + +template static void +MulTransposedL( const Mat& srcmat, Mat& dstmat, const Mat& deltamat, double scale ) +{ + int i, j, k; + const sT* src = (const sT*)srcmat.data; + dT* dst = (dT*)dstmat.data; + const dT* delta = (const dT*)deltamat.data; + size_t srcstep = srcmat.step/sizeof(src[0]); + size_t dststep = dstmat.step/sizeof(dst[0]); + size_t deltastep = deltamat.rows > 1 ? deltamat.step/sizeof(delta[0]) : 0; + int delta_cols = deltamat.cols; + Size size = srcmat.size(); + dT* tdst = dst; + + if( !delta ) + for( i = 0; i < size.height; i++, tdst += dststep ) + for( j = i; j < size.height; j++ ) + { + double s = 0; + const sT *tsrc1 = src + i*srcstep; + const sT *tsrc2 = src + j*srcstep; + + for( k = 0; k <= size.width - 4; k += 4 ) + s += (double)tsrc1[k]*tsrc2[k] + (double)tsrc1[k+1]*tsrc2[k+1] + + (double)tsrc1[k+2]*tsrc2[k+2] + (double)tsrc1[k+3]*tsrc2[k+3]; + for( ; k < size.width; k++ ) + s += (double)tsrc1[k] * tsrc2[k]; + tdst[j] = (dT)(s*scale); + } + else + { + dT delta_buf[4]; + int delta_shift = delta_cols == size.width ? 4 : 0; + AutoBuffer buf(size.width*sizeof(dT)); + dT* row_buf = (dT*)(uchar*)buf; + + for( i = 0; i < size.height; i++, tdst += dststep ) + { + const sT *tsrc1 = src + i*srcstep; + const dT *tdelta1 = delta + i*deltastep; + + if( delta_cols < size.width ) + for( k = 0; k < size.width; k++ ) + row_buf[k] = tsrc1[k] - tdelta1[0]; + else + for( k = 0; k < size.width; k++ ) + row_buf[k] = tsrc1[k] - tdelta1[k]; + + for( j = i; j < size.height; j++ ) + { + double s = 0; + const sT *tsrc2 = src + j*srcstep; + const dT *tdelta2 = delta + j*deltastep; + if( delta_cols < size.width ) + { + delta_buf[0] = delta_buf[1] = + delta_buf[2] = delta_buf[3] = tdelta2[0]; + tdelta2 = delta_buf; + } + for( k = 0; k <= size.width-4; k += 4, tdelta2 += delta_shift ) + s += (double)row_buf[k]*(tsrc2[k] - tdelta2[0]) + + (double)row_buf[k+1]*(tsrc2[k+1] - tdelta2[1]) + + (double)row_buf[k+2]*(tsrc2[k+2] - tdelta2[2]) + + (double)row_buf[k+3]*(tsrc2[k+3] - tdelta2[3]); + for( ; k < size.width; k++, tdelta2++ ) + s += (double)row_buf[k]*(tsrc2[k] - tdelta2[0]); + tdst[j] = (dT)(s*scale); + } + } + } +} + +typedef void (*MulTransposedFunc)(const Mat& src, Mat& dst, const Mat& delta, double scale); + +} + +void cv::mulTransposed( InputArray _src, OutputArray _dst, bool ata, + InputArray _delta, double scale, int dtype ) +{ + Mat src = _src.getMat(), delta = _delta.getMat(); + const int gemm_level = 100; // boundary above which GEMM is faster. + int stype = src.type(); + dtype = std::max(std::max(CV_MAT_DEPTH(dtype >= 0 ? dtype : stype), delta.depth()), CV_32F); + CV_Assert( src.channels() == 1 ); + + if( delta.data ) + { + CV_Assert( delta.channels() == 1 && + (delta.rows == src.rows || delta.rows == 1) && + (delta.cols == src.cols || delta.cols == 1)); + if( delta.type() != dtype ) + delta.convertTo(delta, dtype); + } + + int dsize = ata ? src.cols : src.rows; + _dst.create( dsize, dsize, dtype ); + Mat dst = _dst.getMat(); + + if( src.data == dst.data || (stype == dtype && + (dst.cols >= gemm_level && dst.rows >= gemm_level && + src.cols >= gemm_level && src.rows >= gemm_level))) + { + Mat src2; + const Mat* tsrc = &src; + if( delta.data ) + { + if( delta.size() == src.size() ) + subtract( src, delta, src2 ); + else + { + repeat(delta, src.rows/delta.rows, src.cols/delta.cols, src2); + subtract( src, src2, src2 ); + } + tsrc = &src2; + } + gemm( *tsrc, *tsrc, scale, Mat(), 0, dst, ata ? GEMM_1_T : GEMM_2_T ); + } + else + { + MulTransposedFunc func = 0; + if(stype == CV_8U && dtype == CV_32F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_8U && dtype == CV_64F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_16U && dtype == CV_32F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_16U && dtype == CV_64F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_16S && dtype == CV_32F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_16S && dtype == CV_64F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_32F && dtype == CV_32F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_32F && dtype == CV_64F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + else if(stype == CV_64F && dtype == CV_64F) + { + if(ata) + func = MulTransposedR; + else + func = MulTransposedL; + } + if( !func ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + func( src, dst, delta, scale ); + completeSymm( dst, false ); + } +} + +/****************************************************************************************\ +* Dot Product * +\****************************************************************************************/ + +namespace cv +{ + +template double +dotProd_(const T* src1, const T* src2, int len) +{ + int i = 0; + double result = 0; + #if CV_ENABLE_UNROLLED + for( ; i <= len - 4; i += 4 ) + result += (double)src1[i]*src2[i] + (double)src1[i+1]*src2[i+1] + + (double)src1[i+2]*src2[i+2] + (double)src1[i+3]*src2[i+3]; + #endif + for( ; i < len; i++ ) + result += (double)src1[i]*src2[i]; + + return result; +} + + +static double dotProd_8u(const uchar* src1, const uchar* src2, int len) +{ + double r = 0; +#if ARITHM_USE_IPP + ippiDotProd_8u64f_C1R(src1, (int)(len*sizeof(src1[0])), + src2, (int)(len*sizeof(src2[0])), + ippiSize(len, 1), &r); + return r; +#else + int i = 0; + +#if CV_SSE2 + if( USE_SSE2 ) + { + int j, len0 = len & -4, blockSize0 = (1 << 13), blockSize; + __m128i z = _mm_setzero_si128(); + while( i < len0 ) + { + blockSize = std::min(len0 - i, blockSize0); + __m128i s = _mm_setzero_si128(); + j = 0; + for( ; j <= blockSize - 16; j += 16 ) + { + __m128i b0 = _mm_loadu_si128((const __m128i*)(src1 + j)); + __m128i b1 = _mm_loadu_si128((const __m128i*)(src2 + j)); + __m128i s0, s1, s2, s3; + s0 = _mm_unpacklo_epi8(b0, z); + s2 = _mm_unpackhi_epi8(b0, z); + s1 = _mm_unpacklo_epi8(b1, z); + s3 = _mm_unpackhi_epi8(b1, z); + s0 = _mm_madd_epi16(s0, s1); + s2 = _mm_madd_epi16(s2, s3); + s = _mm_add_epi32(s, s0); + s = _mm_add_epi32(s, s2); + } + + for( ; j < blockSize; j += 4 ) + { + __m128i s0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src1 + j)), z); + __m128i s1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src2 + j)), z); + s0 = _mm_madd_epi16(s0, s1); + s = _mm_add_epi32(s, s0); + } + CV_DECL_ALIGNED(16) int buf[4]; + _mm_store_si128((__m128i*)buf, s); + r += buf[0] + buf[1] + buf[2] + buf[3]; + + src1 += blockSize; + src2 += blockSize; + i += blockSize; + } + } +#endif + return r + dotProd_(src1, src2, len - i); +#endif +} + + +static double dotProd_8s(const schar* src1, const schar* src2, int len) +{ + return dotProd_(src1, src2, len); +} + +static double dotProd_16u(const ushort* src1, const ushort* src2, int len) +{ + double r = 0; + IF_IPP(ippiDotProd_16u64f_C1R(src1, (int)(len*sizeof(src1[0])), + src2, (int)(len*sizeof(src2[0])), + ippiSize(len, 1), &r), + r = dotProd_(src1, src2, len)); + return r; +} + +static double dotProd_16s(const short* src1, const short* src2, int len) +{ + double r = 0; + IF_IPP(ippiDotProd_16s64f_C1R(src1, (int)(len*sizeof(src1[0])), + src2, (int)(len*sizeof(src2[0])), + ippiSize(len, 1), &r), + r = dotProd_(src1, src2, len)); + return r; +} + +static double dotProd_32s(const int* src1, const int* src2, int len) +{ + double r = 0; + IF_IPP(ippiDotProd_32s64f_C1R(src1, (int)(len*sizeof(src1[0])), + src2, (int)(len*sizeof(src2[0])), + ippiSize(len, 1), &r), + r = dotProd_(src1, src2, len)); + return r; +} + +static double dotProd_32f(const float* src1, const float* src2, int len) +{ + double r = 0; + IF_IPP(ippsDotProd_32f64f(src1, src2, len, &r), + r = dotProd_(src1, src2, len)); + return r; +} + +static double dotProd_64f(const double* src1, const double* src2, int len) +{ + double r = 0; + IF_IPP(ippsDotProd_64f(src1, src2, len, &r), + r = dotProd_(src1, src2, len)); + return r; +} + + +typedef double (*DotProdFunc)(const uchar* src1, const uchar* src2, int len); + +static DotProdFunc dotProdTab[] = +{ + (DotProdFunc)GET_OPTIMIZED(dotProd_8u), (DotProdFunc)GET_OPTIMIZED(dotProd_8s), + (DotProdFunc)dotProd_16u, (DotProdFunc)dotProd_16s, + (DotProdFunc)dotProd_32s, (DotProdFunc)GET_OPTIMIZED(dotProd_32f), + (DotProdFunc)dotProd_64f, 0 +}; + +double Mat::dot(InputArray _mat) const +{ + Mat mat = _mat.getMat(); + int cn = channels(); + DotProdFunc func = dotProdTab[depth()]; + CV_Assert( mat.type() == type() && mat.size == size && func != 0 ); + + if( isContinuous() && mat.isContinuous() ) + { + size_t len = total()*cn; + if( len == (size_t)(int)len ) + return func(data, mat.data, (int)len); + } + + const Mat* arrays[] = {this, &mat, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int len = (int)(it.size*cn); + double r = 0; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + r += func( ptrs[0], ptrs[1], len ); + + return r; +} + +/****************************************************************************************\ +* PCA * +\****************************************************************************************/ + +PCA::PCA() {} + +PCA::PCA(InputArray data, InputArray _mean, int flags, int maxComponents) +{ + operator()(data, _mean, flags, maxComponents); +} + +PCA::PCA(InputArray data, InputArray _mean, int flags, double retainedVariance) +{ + computeVar(data, _mean, flags, retainedVariance); +} + +PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComponents) +{ + Mat data = _data.getMat(), _mean = __mean.getMat(); + int covar_flags = CV_COVAR_SCALE; + int i, len, in_count; + Size mean_sz; + + CV_Assert( data.channels() == 1 ); + if( flags & CV_PCA_DATA_AS_COL ) + { + len = data.rows; + in_count = data.cols; + covar_flags |= CV_COVAR_COLS; + mean_sz = Size(1, len); + } + else + { + len = data.cols; + in_count = data.rows; + covar_flags |= CV_COVAR_ROWS; + mean_sz = Size(len, 1); + } + + int count = std::min(len, in_count), out_count = count; + if( maxComponents > 0 ) + out_count = std::min(count, maxComponents); + + // "scrambled" way to compute PCA (when cols(A)>rows(A)): + // B = A'A; B*x=b*x; C = AA'; C*y=c*y -> AA'*y=c*y -> A'A*(A'*y)=c*(A'*y) -> c = b, x=A'*y + if( len <= in_count ) + covar_flags |= CV_COVAR_NORMAL; + + int ctype = std::max(CV_32F, data.depth()); + mean.create( mean_sz, ctype ); + + Mat covar( count, count, ctype ); + + if( _mean.data ) + { + CV_Assert( _mean.size() == mean_sz ); + _mean.convertTo(mean, ctype); + } + + calcCovarMatrix( data, covar, mean, covar_flags, ctype ); + eigen( covar, eigenvalues, eigenvectors ); + + if( !(covar_flags & CV_COVAR_NORMAL) ) + { + // CV_PCA_DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A + // CV_PCA_DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' + Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols); + if( data.type() != ctype || tmp_mean.data == mean.data ) + { + data.convertTo( tmp_data, ctype ); + subtract( tmp_data, tmp_mean, tmp_data ); + } + else + { + subtract( data, tmp_mean, tmp_mean ); + tmp_data = tmp_mean; + } + + Mat evects1(count, len, ctype); + gemm( eigenvectors, tmp_data, 1, Mat(), 0, evects1, + (flags & CV_PCA_DATA_AS_COL) ? CV_GEMM_B_T : 0); + eigenvectors = evects1; + + // normalize eigenvectors + for( i = 0; i < out_count; i++ ) + { + Mat vec = eigenvectors.row(i); + normalize(vec, vec); + } + } + + if( count > out_count ) + { + // use clone() to physically copy the data and thus deallocate the original matrices + eigenvalues = eigenvalues.rowRange(0,out_count).clone(); + eigenvectors = eigenvectors.rowRange(0,out_count).clone(); + } + return *this; +} + +PCA& PCA::computeVar(InputArray _data, InputArray __mean, int flags, double retainedVariance) +{ + Mat data = _data.getMat(), _mean = __mean.getMat(); + int covar_flags = CV_COVAR_SCALE; + int i, len, in_count; + Size mean_sz; + + CV_Assert( data.channels() == 1 ); + if( flags & CV_PCA_DATA_AS_COL ) + { + len = data.rows; + in_count = data.cols; + covar_flags |= CV_COVAR_COLS; + mean_sz = Size(1, len); + } + else + { + len = data.cols; + in_count = data.rows; + covar_flags |= CV_COVAR_ROWS; + mean_sz = Size(len, 1); + } + + CV_Assert( retainedVariance > 0 && retainedVariance <= 1 ); + + int count = std::min(len, in_count); + + // "scrambled" way to compute PCA (when cols(A)>rows(A)): + // B = A'A; B*x=b*x; C = AA'; C*y=c*y -> AA'*y=c*y -> A'A*(A'*y)=c*(A'*y) -> c = b, x=A'*y + if( len <= in_count ) + covar_flags |= CV_COVAR_NORMAL; + + int ctype = std::max(CV_32F, data.depth()); + mean.create( mean_sz, ctype ); + + Mat covar( count, count, ctype ); + + if( _mean.data ) + { + CV_Assert( _mean.size() == mean_sz ); + _mean.convertTo(mean, ctype); + } + + calcCovarMatrix( data, covar, mean, covar_flags, ctype ); + eigen( covar, eigenvalues, eigenvectors ); + + if( !(covar_flags & CV_COVAR_NORMAL) ) + { + // CV_PCA_DATA_AS_ROW: cols(A)>rows(A). x=A'*y -> x'=y'*A + // CV_PCA_DATA_AS_COL: rows(A)>cols(A). x=A''*y -> x'=y'*A' + Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols); + if( data.type() != ctype || tmp_mean.data == mean.data ) + { + data.convertTo( tmp_data, ctype ); + subtract( tmp_data, tmp_mean, tmp_data ); + } + else + { + subtract( data, tmp_mean, tmp_mean ); + tmp_data = tmp_mean; + } + + Mat evects1(count, len, ctype); + gemm( eigenvectors, tmp_data, 1, Mat(), 0, evects1, + (flags & CV_PCA_DATA_AS_COL) ? CV_GEMM_B_T : 0); + eigenvectors = evects1; + + // normalize all eigenvectors + for( i = 0; i < eigenvectors.rows; i++ ) + { + Mat vec = eigenvectors.row(i); + normalize(vec, vec); + } + } + + // compute the cumulative energy content for each eigenvector + Mat g(eigenvalues.size(), ctype); + + for(int ig = 0; ig < g.rows; ig++) + { + g.at(ig,0) = 0; + for(int im = 0; im <= ig; im++) + { + g.at(ig,0) += eigenvalues.at(im,0); + } + } + + int L; + for(L = 0; L < eigenvalues.rows; L++) + { + double energy = g.at(L, 0) / g.at(g.rows - 1, 0); + if(energy > retainedVariance) + break; + } + + L = std::max(2, L); + + // use clone() to physically copy the data and thus deallocate the original matrices + eigenvalues = eigenvalues.rowRange(0,L).clone(); + eigenvectors = eigenvectors.rowRange(0,L).clone(); + + return *this; +} + +void PCA::project(InputArray _data, OutputArray result) const +{ + Mat data = _data.getMat(); + CV_Assert( mean.data && eigenvectors.data && + ((mean.rows == 1 && mean.cols == data.cols) || (mean.cols == 1 && mean.rows == data.rows))); + Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols); + int ctype = mean.type(); + if( data.type() != ctype || tmp_mean.data == mean.data ) + { + data.convertTo( tmp_data, ctype ); + subtract( tmp_data, tmp_mean, tmp_data ); + } + else + { + subtract( data, tmp_mean, tmp_mean ); + tmp_data = tmp_mean; + } + if( mean.rows == 1 ) + gemm( tmp_data, eigenvectors, 1, Mat(), 0, result, GEMM_2_T ); + else + gemm( eigenvectors, tmp_data, 1, Mat(), 0, result, 0 ); +} + +Mat PCA::project(InputArray data) const +{ + Mat result; + project(data, result); + return result; +} + +void PCA::backProject(InputArray _data, OutputArray result) const +{ + Mat data = _data.getMat(); + CV_Assert( mean.data && eigenvectors.data && + ((mean.rows == 1 && eigenvectors.rows == data.cols) || + (mean.cols == 1 && eigenvectors.rows == data.rows))); + + Mat tmp_data, tmp_mean; + data.convertTo(tmp_data, mean.type()); + if( mean.rows == 1 ) + { + tmp_mean = repeat(mean, data.rows, 1); + gemm( tmp_data, eigenvectors, 1, tmp_mean, 1, result, 0 ); + } + else + { + tmp_mean = repeat(mean, 1, data.cols); + gemm( eigenvectors, tmp_data, 1, tmp_mean, 1, result, GEMM_1_T ); + } +} + +Mat PCA::backProject(InputArray data) const +{ + Mat result; + backProject(data, result); + return result; +} + +} + +void cv::PCACompute(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, int maxComponents) +{ + PCA pca; + pca(data, mean, 0, maxComponents); + pca.mean.copyTo(mean); + pca.eigenvectors.copyTo(eigenvectors); +} + +void cv::PCAComputeVar(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, double retainedVariance) +{ + PCA pca; + pca.computeVar(data, mean, 0, retainedVariance); + pca.mean.copyTo(mean); + pca.eigenvectors.copyTo(eigenvectors); +} + +void cv::PCAProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result) +{ + PCA pca; + pca.mean = mean.getMat(); + pca.eigenvectors = eigenvectors.getMat(); + pca.project(data, result); +} + +void cv::PCABackProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result) +{ + PCA pca; + pca.mean = mean.getMat(); + pca.eigenvectors = eigenvectors.getMat(); + pca.backProject(data, result); +} + + +/****************************************************************************************\ +* Earlier API * +\****************************************************************************************/ + +CV_IMPL void cvGEMM( const CvArr* Aarr, const CvArr* Barr, double alpha, + const CvArr* Carr, double beta, CvArr* Darr, int flags ) +{ + cv::Mat A = cv::cvarrToMat(Aarr), B = cv::cvarrToMat(Barr); + cv::Mat C, D = cv::cvarrToMat(Darr); + + if( Carr ) + C = cv::cvarrToMat(Carr); + + CV_Assert( (D.rows == ((flags & CV_GEMM_A_T) == 0 ? A.rows : A.cols)) && + (D.cols == ((flags & CV_GEMM_B_T) == 0 ? B.cols : B.rows)) && + D.type() == A.type() ); + + gemm( A, B, alpha, C, beta, D, flags ); +} + + +CV_IMPL void +cvTransform( const CvArr* srcarr, CvArr* dstarr, + const CvMat* transmat, const CvMat* shiftvec ) +{ + cv::Mat m = cv::cvarrToMat(transmat), src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + if( shiftvec ) + { + cv::Mat v = cv::cvarrToMat(shiftvec).reshape(1,m.rows), + _m(m.rows, m.cols + 1, m.type()), m1 = _m.colRange(0,m.cols), v1 = _m.col(m.cols); + m.convertTo(m1, m1.type()); + v.convertTo(v1, v1.type()); + m = _m; + } + + CV_Assert( dst.depth() == src.depth() && dst.channels() == m.rows ); + cv::transform( src, dst, m ); +} + + +CV_IMPL void +cvPerspectiveTransform( const CvArr* srcarr, CvArr* dstarr, const CvMat* mat ) +{ + cv::Mat m = cv::cvarrToMat(mat), src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( dst.type() == src.type() && dst.channels() == m.rows-1 ); + cv::perspectiveTransform( src, dst, m ); +} + + +CV_IMPL void cvScaleAdd( const CvArr* srcarr1, CvScalar scale, + const CvArr* srcarr2, CvArr* dstarr ) +{ + cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src1.size == dst.size && src1.type() == dst.type() ); + cv::scaleAdd( src1, scale.val[0], cv::cvarrToMat(srcarr2), dst ); +} + + +CV_IMPL void +cvCalcCovarMatrix( const CvArr** vecarr, int count, + CvArr* covarr, CvArr* avgarr, int flags ) +{ + cv::Mat cov0 = cv::cvarrToMat(covarr), cov = cov0, mean0, mean; + CV_Assert( vecarr != 0 && count >= 1 ); + + if( avgarr ) + mean = mean0 = cv::cvarrToMat(avgarr); + + if( (flags & CV_COVAR_COLS) != 0 || (flags & CV_COVAR_ROWS) != 0 ) + { + + cv::Mat data = cv::cvarrToMat(vecarr[0]); + cv::calcCovarMatrix( data, cov, mean, flags, cov.type() ); + } + else + { + std::vector data(count); + for( int i = 0; i < count; i++ ) + data[i] = cv::cvarrToMat(vecarr[i]); + cv::calcCovarMatrix( &data[0], count, cov, mean, flags, cov.type() ); + } + + if( mean.data != mean0.data && mean0.data ) + mean.convertTo(mean0, mean0.type()); + + if( cov.data != cov0.data ) + cov.convertTo(cov0, cov0.type()); +} + + +CV_IMPL double +cvMahalanobis( const CvArr* srcAarr, const CvArr* srcBarr, const CvArr* matarr ) +{ + return cv::Mahalanobis(cv::cvarrToMat(srcAarr), + cv::cvarrToMat(srcBarr), cv::cvarrToMat(matarr)); +} + +CV_IMPL void +cvMulTransposed( const CvArr* srcarr, CvArr* dstarr, + int order, const CvArr* deltaarr, double scale ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0, delta; + if( deltaarr ) + delta = cv::cvarrToMat(deltaarr); + cv::mulTransposed( src, dst, order != 0, delta, scale, dst.type()); + if( dst.data != dst0.data ) + dst.convertTo(dst0, dst0.type()); +} + +CV_IMPL double cvDotProduct( const CvArr* srcAarr, const CvArr* srcBarr ) +{ + return cv::cvarrToMat(srcAarr).dot(cv::cvarrToMat(srcBarr)); +} + + +CV_IMPL void +cvCalcPCA( const CvArr* data_arr, CvArr* avg_arr, CvArr* eigenvals, CvArr* eigenvects, int flags ) +{ + cv::Mat data = cv::cvarrToMat(data_arr), mean0 = cv::cvarrToMat(avg_arr); + cv::Mat evals0 = cv::cvarrToMat(eigenvals), evects0 = cv::cvarrToMat(eigenvects); + cv::Mat mean = mean0, evals = evals0, evects = evects0; + + cv::PCA pca; + pca.mean = mean; + pca.eigenvalues = evals; + pca.eigenvectors = evects; + + pca(data, (flags & CV_PCA_USE_AVG) ? mean : cv::Mat(), + flags, evals.data ? evals.rows + evals.cols - 1 : 0); + + if( pca.mean.size() == mean.size() ) + pca.mean.convertTo( mean, mean.type() ); + else + { + cv::Mat temp; pca.mean.convertTo( temp, mean.type() ); + transpose( temp, mean ); + } + + evals = pca.eigenvalues; + evects = pca.eigenvectors; + int ecount0 = evals0.cols + evals0.rows - 1; + int ecount = evals.cols + evals.rows - 1; + + CV_Assert( (evals0.cols == 1 || evals0.rows == 1) && + ecount0 <= ecount && + evects0.cols == evects.cols && + evects0.rows == ecount0 ); + + cv::Mat temp = evals0; + if( evals.rows == 1 ) + evals.colRange(0, ecount0).convertTo(temp, evals0.type()); + else + evals.rowRange(0, ecount0).convertTo(temp, evals0.type()); + if( temp.data != evals0.data ) + transpose(temp, evals0); + evects.rowRange(0, ecount0).convertTo( evects0, evects0.type() ); + + // otherwise some datatype's or size's were incorrect, so the output arrays have been reallocated + CV_Assert( mean0.data == mean.data ); +} + + +CV_IMPL void +cvProjectPCA( const CvArr* data_arr, const CvArr* avg_arr, + const CvArr* eigenvects, CvArr* result_arr ) +{ + cv::Mat data = cv::cvarrToMat(data_arr), mean = cv::cvarrToMat(avg_arr); + cv::Mat evects = cv::cvarrToMat(eigenvects), dst0 = cv::cvarrToMat(result_arr), dst = dst0; + + cv::PCA pca; + pca.mean = mean; + int n; + if( mean.rows == 1 ) + { + CV_Assert(dst.cols <= evects.rows && dst.rows == data.rows); + n = dst.cols; + } + else + { + CV_Assert(dst.rows <= evects.rows && dst.cols == data.cols); + n = dst.rows; + } + pca.eigenvectors = evects.rowRange(0, n); + + cv::Mat result = pca.project(data); + if( result.cols != dst.cols ) + result = result.reshape(1, 1); + result.convertTo(dst, dst.type()); + + CV_Assert(dst0.data == dst.data); +} + + +CV_IMPL void +cvBackProjectPCA( const CvArr* proj_arr, const CvArr* avg_arr, + const CvArr* eigenvects, CvArr* result_arr ) +{ + cv::Mat data = cv::cvarrToMat(proj_arr), mean = cv::cvarrToMat(avg_arr); + cv::Mat evects = cv::cvarrToMat(eigenvects), dst0 = cv::cvarrToMat(result_arr), dst = dst0; + + cv::PCA pca; + pca.mean = mean; + int n; + if( mean.rows == 1 ) + { + CV_Assert(data.cols <= evects.rows && dst.rows == data.rows); + n = data.cols; + } + else + { + CV_Assert(data.rows <= evects.rows && dst.cols == data.cols); + n = data.rows; + } + pca.eigenvectors = evects.rowRange(0, n); + + cv::Mat result = pca.backProject(data); + result.convertTo(dst, dst.type()); + + CV_Assert(dst0.data == dst.data); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/matop.cpp diffimg-2.0.0/3rdparty/opencv/core/src/matop.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/matop.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/matop.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1651 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Mat basic operations: Copy, Set +// +// */ + +#include "precomp.hpp" + +namespace cv +{ + +class MatOp_Identity : public MatOp +{ +public: + MatOp_Identity() {} + virtual ~MatOp_Identity() {} + + bool elementWise(const MatExpr& /*expr*/) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + static void makeExpr(MatExpr& res, const Mat& m); +}; + +static MatOp_Identity g_MatOp_Identity; + +class MatOp_AddEx : public MatOp +{ +public: + MatOp_AddEx() {} + virtual ~MatOp_AddEx() {} + + bool elementWise(const MatExpr& /*expr*/) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const; + void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + void divide(double s, const MatExpr& e, MatExpr& res) const; + + void transpose(const MatExpr& e1, MatExpr& res) const; + void abs(const MatExpr& expr, MatExpr& res) const; + + static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar()); +}; + +static MatOp_AddEx g_MatOp_AddEx; + +class MatOp_Bin : public MatOp +{ +public: + MatOp_Bin() {} + virtual ~MatOp_Bin() {} + + bool elementWise(const MatExpr& /*expr*/) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + void divide(double s, const MatExpr& e, MatExpr& res) const; + + static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1); + static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s); +}; + +static MatOp_Bin g_MatOp_Bin; + +class MatOp_Cmp : public MatOp +{ +public: + MatOp_Cmp() {} + virtual ~MatOp_Cmp() {} + + bool elementWise(const MatExpr& /*expr*/) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b); + static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha); +}; + +static MatOp_Cmp g_MatOp_Cmp; + +class MatOp_GEMM : public MatOp +{ +public: + MatOp_GEMM() {} + virtual ~MatOp_GEMM() {} + + bool elementWise(const MatExpr& /*expr*/) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void multiply(const MatExpr& e, double s, MatExpr& res) const; + + void transpose(const MatExpr& expr, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, + double alpha=1, const Mat& c=Mat(), double beta=1); +}; + +static MatOp_GEMM g_MatOp_GEMM; + +class MatOp_Invert : public MatOp +{ +public: + MatOp_Invert() {} + virtual ~MatOp_Invert() {} + + bool elementWise(const MatExpr& /*expr*/) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int method, const Mat& m); +}; + +static MatOp_Invert g_MatOp_Invert; + +class MatOp_T : public MatOp +{ +public: + MatOp_T() {} + virtual ~MatOp_T() {} + + bool elementWise(const MatExpr& /*expr*/) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + void transpose(const MatExpr& expr, MatExpr& res) const; + + static void makeExpr(MatExpr& res, const Mat& a, double alpha=1); +}; + +static MatOp_T g_MatOp_T; + +class MatOp_Solve : public MatOp +{ +public: + MatOp_Solve() {} + virtual ~MatOp_Solve() {} + + bool elementWise(const MatExpr& /*expr*/) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b); +}; + +static MatOp_Solve g_MatOp_Solve; + +class MatOp_Initializer : public MatOp +{ +public: + MatOp_Initializer() {} + virtual ~MatOp_Initializer() {} + + bool elementWise(const MatExpr& /*expr*/) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e, double s, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1); +}; + +static MatOp_Initializer g_MatOp_Initializer; + +static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; } +static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; } +static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); } +static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; } +static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; } +static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); } +static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; } +static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; } +static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; } +static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; } +static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); } +static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Initializer; } + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +bool MatOp::elementWise(const MatExpr& /*expr*/) const +{ + return false; +} + +void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const +{ + if( elementWise(expr) ) + { + e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), + expr.alpha, expr.beta, expr.s); + if(expr.a.data) + e.a = expr.a(rowRange, colRange); + if(expr.b.data) + e.b = expr.b(rowRange, colRange); + if(expr.c.data) + e.c = expr.c(rowRange, colRange); + } + else + { + Mat m; + expr.op->assign(expr, m); + e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat()); + } +} + +void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const +{ + if( elementWise(expr) ) + { + e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), + expr.alpha, expr.beta, expr.s); + if(expr.a.data) + e.a = expr.a.diag(d); + if(expr.b.data) + e.b = expr.b.diag(d); + if(expr.c.data) + e.c = expr.c.diag(d); + } + else + { + Mat m; + expr.op->assign(expr, m); + e = MatExpr(&g_MatOp_Identity, 0, m.diag(d), Mat(), Mat()); + } +} + + +void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m += temp; +} + + +void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m -= temp; +} + + +void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m *= temp; +} + + +void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m /= temp; +} + + +void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m &= temp; +} + + +void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m |= temp; +} + + +void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m ^= temp; +} + + +void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( this == e2.op ) + { + double alpha = 1, beta = 1; + Scalar s; + Mat m1, m2; + if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) + { + m1 = e1.a; + alpha = e1.alpha; + s = e1.s; + } + else + e1.op->assign(e1, m1); + + if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) + { + m2 = e2.a; + beta = e2.alpha; + s += e2.s; + } + else + e2.op->assign(e2, m2); + MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); + } + else + e2.op->add(e1, e2, res); +} + + +void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const +{ + Mat m1; + expr1.op->assign(expr1, m1); + MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s); +} + + +void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( this == e2.op ) + { + double alpha = 1, beta = -1; + Scalar s; + Mat m1, m2; + if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) + { + m1 = e1.a; + alpha = e1.alpha; + s = e1.s; + } + else + e1.op->assign(e1, m1); + + if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) + { + m2 = e2.a; + beta = -e2.alpha; + s -= e2.s; + } + else + e2.op->assign(e2, m2); + MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); + } + else + e2.op->subtract(e1, e2, res); +} + + +void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s); +} + + +void MatOp::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( this == e2.op ) + { + Mat m1, m2; + + if( isReciprocal(e1) ) + { + if( isScaled(e2) ) + { + scale *= e2.alpha; + m2 = e2.a; + } + else + e2.op->assign(e2, m2); + + MatOp_Bin::makeExpr(res, '/', m2, e1.a, scale/e1.alpha); + } + else + { + char op = '*'; + if( isScaled(e1) ) + { + m1 = e1.a; + scale *= e1.alpha; + } + else + e1.op->assign(e1, m1); + + if( isScaled(e2) ) + { + m2 = e2.a; + scale *= e2.alpha; + } + else if( isReciprocal(e2) ) + { + op = '/'; + m2 = e2.a; + scale /= e2.alpha; + } + else + e2.op->assign(e2, m2); + + MatOp_Bin::makeExpr(res, op, m1, m2, scale); + } + } + else + e2.op->multiply(e1, e2, res, scale); +} + + +void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_AddEx::makeExpr(res, m, Mat(), s, 0); +} + + +void MatOp::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( this == e2.op ) + { + if( isReciprocal(e1) && isReciprocal(e2) ) + MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha/e2.alpha); + else + { + Mat m1, m2; + char op = '/'; + + if( isScaled(e1) ) + { + m1 = e1.a; + scale *= e1.alpha; + } + else + e1.op->assign(e1, m1); + + if( isScaled(e2) ) + { + m2 = e2.a; + scale /= e2.alpha; + } + else if( isReciprocal(e2) ) + { + m2 = e2.a; + scale /= e2.alpha; + op = '*'; + } + else + e2.op->assign(e2, m2); + MatOp_Bin::makeExpr(res, op, m1, m2, scale); + } + } + else + e2.op->divide(e1, e2, res, scale); +} + + +void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Bin::makeExpr(res, '/', m, Mat(), s); +} + + +void MatOp::abs(const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Bin::makeExpr(res, 'a', m, Mat()); +} + + +void MatOp::transpose(const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_T::makeExpr(res, m, 1); +} + + +void MatOp::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( this == e2.op ) + { + double scale = 1; + int flags = 0; + Mat m1, m2; + + if( isT(e1) ) + { + flags = CV_GEMM_A_T; + scale = e1.alpha; + m1 = e1.a; + } + else if( isScaled(e1) ) + { + scale = e1.alpha; + m1 = e1.a; + } + else + e1.op->assign(e1, m1); + + if( isT(e2) ) + { + flags |= CV_GEMM_B_T; + scale *= e2.alpha; + m2 = e2.a; + } + else if( isScaled(e2) ) + { + scale *= e2.alpha; + m2 = e2.a; + } + else + e2.op->assign(e2, m2); + + MatOp_GEMM::makeExpr(res, flags, m1, m2, scale); + } + else + e2.op->matmul(e1, e2, res); +} + + +void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Invert::makeExpr(res, method, m); +} + + +Size MatOp::size(const MatExpr& expr) const +{ + return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size(); +} + +int MatOp::type(const MatExpr& expr) const +{ + return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type(); +} + +////////////////////////////////////////////////////////////////////////////////////////////////// + +MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar()) +{ +} + +MatExpr MatExpr::row(int y) const +{ + MatExpr e; + op->roi(*this, Range(y, y+1), Range::all(), e); + return e; +} + +MatExpr MatExpr::col(int x) const +{ + MatExpr e; + op->roi(*this, Range::all(), Range(x, x+1), e); + return e; +} + +MatExpr MatExpr::diag(int d) const +{ + MatExpr e; + op->diag(*this, d, e); + return e; +} + +MatExpr MatExpr::operator()( const Range& rowRange, const Range& colRange ) const +{ + MatExpr e; + op->roi(*this, rowRange, colRange, e); + return e; +} + +MatExpr MatExpr::operator()( const Rect& roi ) const +{ + MatExpr e; + op->roi(*this, Range(roi.y, roi.y + roi.height), Range(roi.x, roi.x + roi.width), e); + return e; +} + +Mat MatExpr::cross(const Mat& m) const +{ + return ((Mat)*this).cross(m); +} + +double MatExpr::dot(const Mat& m) const +{ + return ((Mat)*this).dot(m); +} + +MatExpr MatExpr::t() const +{ + MatExpr e; + op->transpose(*this, e); + return e; +} + +MatExpr MatExpr::inv(int method) const +{ + MatExpr e; + op->invert(*this, method, e); + return e; +} + +MatExpr MatExpr::mul(const MatExpr& e, double scale) const +{ + MatExpr en; + op->multiply(*this, e, en, scale); + return en; +} + +MatExpr MatExpr::mul(const Mat& m, double scale) const +{ + MatExpr e; + op->multiply(*this, MatExpr(m), e, scale); + return e; +} + +MatExpr operator + (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, b, 1, 1); + return e; +} + +MatExpr operator + (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); + return e; +} + +MatExpr operator + (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); + return e; +} + +MatExpr operator + (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->add(e, MatExpr(m), en); + return en; +} + +MatExpr operator + (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->add(e, MatExpr(m), en); + return en; +} + +MatExpr operator + (const MatExpr& e, const Scalar& s) +{ + MatExpr en; + e.op->add(e, s, en); + return en; +} + +MatExpr operator + (const Scalar& s, const MatExpr& e) +{ + MatExpr en; + e.op->add(e, s, en); + return en; +} + +MatExpr operator + (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->add(e1, e2, en); + return en; +} + +MatExpr operator - (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, b, 1, -1); + return e; +} + +MatExpr operator - (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s); + return e; +} + +MatExpr operator - (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s); + return e; +} + +MatExpr operator - (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->subtract(e, MatExpr(m), en); + return en; +} + +MatExpr operator - (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->subtract(MatExpr(m), e, en); + return en; +} + +MatExpr operator - (const MatExpr& e, const Scalar& s) +{ + MatExpr en; + e.op->add(e, -s, en); + return en; +} + +MatExpr operator - (const Scalar& s, const MatExpr& e) +{ + MatExpr en; + e.op->subtract(s, e, en); + return en; +} + +MatExpr operator - (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->subtract(e1, e2, en); + return en; +} + +MatExpr operator - (const Mat& m) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0); + return e; +} + +MatExpr operator - (const MatExpr& e) +{ + MatExpr en; + e.op->subtract(Scalar(0), e, en); + return en; +} + +MatExpr operator * (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_GEMM::makeExpr(e, 0, a, b); + return e; +} + +MatExpr operator * (const Mat& a, double s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); + return e; +} + +MatExpr operator * (double s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); + return e; +} + +MatExpr operator * (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->matmul(e, MatExpr(m), en); + return en; +} + +MatExpr operator * (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->matmul(MatExpr(m), e, en); + return en; +} + +MatExpr operator * (const MatExpr& e, double s) +{ + MatExpr en; + e.op->multiply(e, s, en); + return en; +} + +MatExpr operator * (double s, const MatExpr& e) +{ + MatExpr en; + e.op->multiply(e, s, en); + return en; +} + +MatExpr operator * (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->matmul(e1, e2, en); + return en; +} + +MatExpr operator / (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '/', a, b); + return e; +} + +MatExpr operator / (const Mat& a, double s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0); + return e; +} + +MatExpr operator / (double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '/', a, Mat(), s); + return e; +} + +MatExpr operator / (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->divide(e, MatExpr(m), en); + return en; +} + +MatExpr operator / (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->divide(MatExpr(m), e, en); + return en; +} + +MatExpr operator / (const MatExpr& e, double s) +{ + MatExpr en; + e.op->multiply(e, 1./s, en); + return en; +} + +MatExpr operator / (double s, const MatExpr& e) +{ + MatExpr en; + e.op->divide(s, e, en); + return en; +} + +MatExpr operator / (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->divide(e1, e2, en); + return en; +} + +MatExpr operator < (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b); + return e; +} + +MatExpr operator < (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); + return e; +} + +MatExpr operator < (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); + return e; +} + +MatExpr operator <= (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b); + return e; +} + +MatExpr operator <= (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); + return e; +} + +MatExpr operator <= (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); + return e; +} + +MatExpr operator == (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b); + return e; +} + +MatExpr operator == (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); + return e; +} + +MatExpr operator == (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); + return e; +} + +MatExpr operator != (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b); + return e; +} + +MatExpr operator != (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); + return e; +} + +MatExpr operator != (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); + return e; +} + +MatExpr operator >= (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b); + return e; +} + +MatExpr operator >= (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); + return e; +} + +MatExpr operator >= (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); + return e; +} + +MatExpr operator > (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b); + return e; +} + +MatExpr operator > (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); + return e; +} + +MatExpr operator > (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); + return e; +} + +MatExpr min(const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, b); + return e; +} + +MatExpr min(const Mat& a, double s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, s); + return e; +} + +MatExpr min(double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, s); + return e; +} + +MatExpr max(const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, b); + return e; +} + +MatExpr max(const Mat& a, double s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, s); + return e; +} + +MatExpr max(double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, s); + return e; +} + +MatExpr operator & (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, b); + return e; +} + +MatExpr operator & (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, s); + return e; +} + +MatExpr operator & (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, s); + return e; +} + +MatExpr operator | (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, b); + return e; +} + +MatExpr operator | (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, s); + return e; +} + +MatExpr operator | (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, s); + return e; +} + +MatExpr operator ^ (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, b); + return e; +} + +MatExpr operator ^ (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, s); + return e; +} + +MatExpr operator ^ (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, s); + return e; +} + +MatExpr operator ~(const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '~', a, Scalar()); + return e; +} + +MatExpr abs(const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'a', a, Scalar()); + return e; +} + +MatExpr abs(const MatExpr& e) +{ + MatExpr en; + e.op->abs(e, en); + return en; +} + + +Size MatExpr::size() const +{ + if( isT(*this) || isInv(*this) ) + return Size(a.rows, a.cols); + if( isGEMM(*this) ) + return Size(b.cols, a.rows); + if( isSolve(*this) ) + return Size(b.cols, a.cols); + if( isInitializer(*this) ) + return a.size(); + return op ? op->size(*this) : Size(); +} + + +int MatExpr::type() const +{ + if( isInitializer(*this) ) + return a.type(); + if( isCmp(*this) ) + return CV_8U; + return op ? op->type(*this) : -1; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Identity::assign(const MatExpr& e, Mat& m, int _type) const +{ + if( _type == -1 || _type == e.a.type() ) + m = e.a; + else + { + CV_Assert( CV_MAT_CN(_type) == e.a.channels() ); + e.a.convertTo(m, _type); + } +} + +inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m) +{ + res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp; + if( e.b.data ) + { + if( e.s == Scalar() || !e.s.isReal() ) + { + if( e.alpha == 1 ) + { + if( e.beta == 1 ) + cv::add(e.a, e.b, dst); + else if( e.beta == -1 ) + cv::subtract(e.a, e.b, dst); + else + cv::scaleAdd(e.b, e.beta, e.a, dst); + } + else if( e.beta == 1 ) + { + if( e.alpha == -1 ) + cv::subtract(e.b, e.a, dst); + else + cv::scaleAdd(e.a, e.alpha, e.b, dst); + } + else + cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst); + + if( !e.s.isReal() ) + cv::add(dst, e.s, dst); + } + else + cv::addWeighted(e.a, e.alpha, e.b, e.beta, e.s[0], dst); + } + else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1)) + { + e.a.convertTo(m, _type, e.alpha, e.s[0]); + return; + } + else if( e.alpha == 1 ) + cv::add(e.a, e.s, dst); + else if( e.alpha == -1 ) + cv::subtract(e.s, e.a, dst); + else + { + e.a.convertTo(dst, e.a.type(), e.alpha); + cv::add(dst, e.s, dst); + } + + if( dst.data != m.data ) + dst.convertTo(m, m.type()); +} + + +void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const +{ + res = e; + res.s += s; +} + + +void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const +{ + res = e; + res.alpha = -res.alpha; + res.beta = -res.beta; + res.s = s - res.s; +} + +void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; + res.beta *= s; + res.s *= s; +} + +void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const +{ + if( isScaled(e) ) + MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s/e.alpha); + else + MatOp::divide(s, e, res); +} + + +void MatOp_AddEx::transpose(const MatExpr& e, MatExpr& res) const +{ + if( isScaled(e) ) + MatOp_T::makeExpr(res, e.a, e.alpha); + else + MatOp::transpose(e, res); +} + +void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const +{ + if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 ) + MatOp_Bin::makeExpr(res, 'a', e.a, -e.s*e.alpha); + else if( e.b.data && e.alpha + e.beta == 0 && e.alpha*e.beta == -1 ) + MatOp_Bin::makeExpr(res, 'a', e.a, e.b); + else + MatOp::abs(e, res); +} + +inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s) +{ + res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp; + + if( e.flags == '*' ) + cv::multiply(e.a, e.b, dst, e.alpha); + else if( e.flags == '/' && e.b.data ) + cv::divide(e.a, e.b, dst, e.alpha); + else if( e.flags == '/' && !e.b.data ) + cv::divide(e.alpha, e.a, dst ); + else if( e.flags == '&' && e.b.data ) + bitwise_and(e.a, e.b, dst); + else if( e.flags == '&' && !e.b.data ) + bitwise_and(e.a, e.s, dst); + else if( e.flags == '|' && e.b.data ) + bitwise_or(e.a, e.b, dst); + else if( e.flags == '|' && !e.b.data ) + bitwise_or(e.a, e.s, dst); + else if( e.flags == '^' && e.b.data ) + bitwise_xor(e.a, e.b, dst); + else if( e.flags == '^' && !e.b.data ) + bitwise_xor(e.a, e.s, dst); + else if( e.flags == '~' && !e.b.data ) + bitwise_not(e.a, dst); + else if( e.flags == 'm' && e.b.data ) + cv::min(e.a, e.b, dst); + else if( e.flags == 'm' && !e.b.data ) + cv::min(e.a, e.s[0], dst); + else if( e.flags == 'M' && e.b.data ) + cv::max(e.a, e.b, dst); + else if( e.flags == 'M' && !e.b.data ) + cv::max(e.a, e.s[0], dst); + else if( e.flags == 'a' && e.b.data ) + cv::absdiff(e.a, e.b, dst); + else if( e.flags == 'a' && !e.b.data ) + cv::absdiff(e.a, e.s, dst); + else + CV_Error(CV_StsError, "Unknown operation"); + + if( dst.data != m.data ) + dst.convertTo(m, _type); +} + +void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + if( e.flags == '*' || e.flags == '/' ) + { + res = e; + res.alpha *= s; + } + else + MatOp::multiply(e, s, res); +} + +void MatOp_Bin::divide(double s, const MatExpr& e, MatExpr& res) const +{ + if( e.flags == '/' && (!e.b.data || e.beta == 0) ) + MatOp_AddEx::makeExpr(res, e.a, Mat(), s/e.alpha, 0); + else + MatOp::divide(s, e, res); +} + +inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale) +{ + res = MatExpr(&g_MatOp_Bin, op, a, b, Mat(), scale, b.data ? 1 : 0); +} + +inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s) +{ + res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || _type == CV_8U ? m : temp; + + if( e.b.data ) + cv::compare(e.a, e.b, dst, e.flags); + else + cv::compare(e.a, e.alpha, dst, e.flags); + + if( dst.data != m.data ) + dst.convertTo(m, _type); +} + +inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b) +{ + res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1); +} + +inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha) +{ + res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_T::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; + + cv::transpose(e.a, dst); + + if( dst.data != m.data || e.alpha != 1 ) + dst.convertTo(m, _type, e.alpha); +} + +void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; +} + +void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const +{ + if( e.alpha == 1 ) + MatOp_Identity::makeExpr(res, e.a); + else + MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0); +} + +inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha) +{ + res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; + + cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, _type); +} + +void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) + MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), + e1.a, e1.b, alpha1, e2.a, alpha2); + else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) + MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), + e2.a, e2.b, alpha2, e1.a, alpha1); + else if( this == e2.op ) + MatOp::add(e1, e2, res); + else + e2.op->add(e1, e2, res); +} + +void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) + MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), + e1.a, e1.b, alpha1, e2.a, -alpha2); + else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) + MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), + e2.a, e2.b, -alpha2, e1.a, alpha1); + else if( this == e2.op ) + MatOp::subtract(e1, e2, res); + else + e2.op->subtract(e1, e2, res); +} + +void MatOp_GEMM::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; + res.beta *= s; +} + +void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const +{ + res = e; + res.flags = (!(e.flags & CV_GEMM_A_T) ? CV_GEMM_B_T : 0) | + (!(e.flags & CV_GEMM_B_T) ? CV_GEMM_A_T : 0) | + (!(e.flags & CV_GEMM_C_T) ? CV_GEMM_C_T : 0); + swap(res.a, res.b); +} + +inline void MatOp_GEMM::makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, + double alpha, const Mat& c, double beta) +{ + res = MatExpr(&g_MatOp_GEMM, flags, a, b, c, alpha, beta); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Invert::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; + + cv::invert(e.a, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, _type); +} + +void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( isInv(e1) && isIdentity(e2) ) + MatOp_Solve::makeExpr(res, e1.flags, e1.a, e2.a); + else if( this == e2.op ) + MatOp::matmul(e1, e2, res); + else + e2.op->matmul(e1, e2, res); +} + +inline void MatOp_Invert::makeExpr(MatExpr& res, int method, const Mat& m) +{ + res = MatExpr(&g_MatOp_Invert, method, m, Mat(), Mat(), 1, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Solve::assign(const MatExpr& e, Mat& m, int _type) const +{ + Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; + + cv::solve(e.a, e.b, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, _type); +} + +inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b) +{ + res = MatExpr(&g_MatOp_Solve, method, a, b, Mat(), 1, 1); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const +{ + if( _type == -1 ) + _type = e.a.type(); + m.create(e.a.size(), _type); + if( e.flags == 'I' ) + setIdentity(m, Scalar(e.alpha)); + else if( e.flags == '0' ) + m = Scalar(); + else if( e.flags == '1' ) + m = Scalar(e.alpha); + else + CV_Error(CV_StsError, "Invalid matrix initializer type"); +} + +void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; +} + +inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha) +{ + res = MatExpr(&g_MatOp_Initializer, method, Mat(sz, type, (void*)0), Mat(), Mat(), alpha, 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +MatExpr Mat::t() const +{ + MatExpr e; + MatOp_T::makeExpr(e, *this); + return e; +} + +MatExpr Mat::inv(int method) const +{ + MatExpr e; + MatOp_Invert::makeExpr(e, method, *this); + return e; +} + + +MatExpr Mat::mul(InputArray m, double scale) const +{ + MatExpr e; + if(m.kind() == _InputArray::EXPR) + { + const MatExpr& me = *(const MatExpr*)m.obj; + me.op->multiply(MatExpr(*this), me, e, scale); + } + else + MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale); + return e; +} + +MatExpr Mat::zeros(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type); + return e; +} + +MatExpr Mat::zeros(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '0', size, type); + return e; +} + +MatExpr Mat::ones(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type); + return e; +} + +MatExpr Mat::ones(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '1', size, type); + return e; +} + +MatExpr Mat::eye(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, 'I', Size(cols, rows), type); + return e; +} + +MatExpr Mat::eye(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, 'I', size, type); + return e; +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/matrix.cpp diffimg-2.0.0/3rdparty/opencv/core/src/matrix.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/matrix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/matrix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,4265 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "opencv2/core/gpumat.hpp" +#include "opencv2/core/opengl_interop.hpp" +#include "opencv2/core/opengl_interop_deprecated.hpp" + +/****************************************************************************************\ +* [scaled] Identity matrix initialization * +\****************************************************************************************/ + +namespace cv { + +void swap( Mat& a, Mat& b ) +{ + std::swap(a.flags, b.flags); + std::swap(a.dims, b.dims); + std::swap(a.rows, b.rows); + std::swap(a.cols, b.cols); + std::swap(a.data, b.data); + std::swap(a.refcount, b.refcount); + std::swap(a.datastart, b.datastart); + std::swap(a.dataend, b.dataend); + std::swap(a.datalimit, b.datalimit); + std::swap(a.allocator, b.allocator); + + std::swap(a.size.p, b.size.p); + std::swap(a.step.p, b.step.p); + std::swap(a.step.buf[0], b.step.buf[0]); + std::swap(a.step.buf[1], b.step.buf[1]); + + if( a.step.p == b.step.buf ) + { + a.step.p = a.step.buf; + a.size.p = &a.rows; + } + + if( b.step.p == a.step.buf ) + { + b.step.p = b.step.buf; + b.size.p = &b.rows; + } +} + + +static inline void setSize( Mat& m, int _dims, const int* _sz, + const size_t* _steps, bool autoSteps=false ) +{ + CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM ); + if( m.dims != _dims ) + { + if( m.step.p != m.step.buf ) + { + fastFree(m.step.p); + m.step.p = m.step.buf; + m.size.p = &m.rows; + } + if( _dims > 2 ) + { + m.step.p = (size_t*)fastMalloc(_dims*sizeof(m.step.p[0]) + (_dims+1)*sizeof(m.size.p[0])); + m.size.p = (int*)(m.step.p + _dims) + 1; + m.size.p[-1] = _dims; + m.rows = m.cols = -1; + } + } + + m.dims = _dims; + if( !_sz ) + return; + + size_t esz = CV_ELEM_SIZE(m.flags), total = esz; + int i; + for( i = _dims-1; i >= 0; i-- ) + { + int s = _sz[i]; + CV_Assert( s >= 0 ); + m.size.p[i] = s; + + if( _steps ) + m.step.p[i] = i < _dims-1 ? _steps[i] : esz; + else if( autoSteps ) + { + m.step.p[i] = total; + int64 total1 = (int64)total*s; + if( (uint64)total1 != (size_t)total1 ) + CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" ); + total = (size_t)total1; + } + } + + if( _dims == 1 ) + { + m.dims = 2; + m.cols = 1; + m.step[1] = esz; + } +} + +static void updateContinuityFlag(Mat& m) +{ + int i, j; + for( i = 0; i < m.dims; i++ ) + { + if( m.size[i] > 1 ) + break; + } + + for( j = m.dims-1; j > i; j-- ) + { + if( m.step[j]*m.size[j] < m.step[j-1] ) + break; + } + + uint64 t = (uint64)m.step[0]*m.size[0]; + if( j <= i && t == (size_t)t ) + m.flags |= Mat::CONTINUOUS_FLAG; + else + m.flags &= ~Mat::CONTINUOUS_FLAG; +} + +static void finalizeHdr(Mat& m) +{ + updateContinuityFlag(m); + int d = m.dims; + if( d > 2 ) + m.rows = m.cols = -1; + if( m.data ) + { + m.datalimit = m.datastart + m.size[0]*m.step[0]; + if( m.size[0] > 0 ) + { + m.dataend = m.data + m.size[d-1]*m.step[d-1]; + for( int i = 0; i < d-1; i++ ) + m.dataend += (m.size[i] - 1)*m.step[i]; + } + else + m.dataend = m.datalimit; + } + else + m.dataend = m.datalimit = 0; +} + + +void Mat::create(int d, const int* _sizes, int _type) +{ + int i; + CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes); + _type = CV_MAT_TYPE(_type); + + if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() ) + { + if( d == 2 && rows == _sizes[0] && cols == _sizes[1] ) + return; + for( i = 0; i < d; i++ ) + if( size[i] != _sizes[i] ) + break; + if( i == d && (d > 1 || size[1] == 1)) + return; + } + + release(); + if( d == 0 ) + return; + flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL; + setSize(*this, d, _sizes, 0, true); + + if( total() > 0 ) + { +#ifdef HAVE_TGPU + if( !allocator || allocator == tegra::getAllocator() ) allocator = tegra::getAllocator(d, _sizes, _type); +#endif + if( !allocator ) + { + size_t totalsize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount)); + data = datastart = (uchar*)fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(data + totalsize); + *refcount = 1; + } + else + { +#ifdef HAVE_TGPU + try + { + allocator->allocate(dims, size, _type, refcount, datastart, data, step.p); + CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) ); + }catch(...) + { + allocator = 0; + size_t totalSize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount)); + data = datastart = (uchar*)fastMalloc(totalSize + (int)sizeof(*refcount)); + refcount = (int*)(data + totalSize); + *refcount = 1; + } +#else + allocator->allocate(dims, size, _type, refcount, datastart, data, step.p); + CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) ); +#endif + } + } + + finalizeHdr(*this); +} + +void Mat::copySize(const Mat& m) +{ + setSize(*this, m.dims, 0, 0); + for( int i = 0; i < dims; i++ ) + { + size[i] = m.size[i]; + step[i] = m.step[i]; + } +} + +void Mat::deallocate() +{ + if( allocator ) + allocator->deallocate(refcount, datastart, data); + else + { + CV_DbgAssert(refcount != 0); + fastFree(datastart); + } +} + + +Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange) : size(&rows) +{ + initEmpty(); + CV_Assert( m.dims >= 2 ); + if( m.dims > 2 ) + { + AutoBuffer rs(m.dims); + rs[0] = _rowRange; + rs[1] = _colRange; + for( int i = 2; i < m.dims; i++ ) + rs[i] = Range::all(); + *this = m(rs); + return; + } + + *this = m; + if( _rowRange != Range::all() && _rowRange != Range(0,rows) ) + { + CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows ); + rows = _rowRange.size(); + data += step*_rowRange.start; + flags |= SUBMATRIX_FLAG; + } + + if( _colRange != Range::all() && _colRange != Range(0,cols) ) + { + CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols ); + cols = _colRange.size(); + data += _colRange.start*elemSize(); + flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1; + flags |= SUBMATRIX_FLAG; + } + + if( rows == 1 ) + flags |= CONTINUOUS_FLAG; + + if( rows <= 0 || cols <= 0 ) + { + release(); + rows = cols = 0; + } +} + + +Mat::Mat(const Mat& m, const Rect& roi) + : flags(m.flags), dims(2), rows(roi.height), cols(roi.width), + data(m.data + roi.y*m.step[0]), refcount(m.refcount), + datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), + allocator(m.allocator), size(&rows) +{ + CV_Assert( m.dims <= 2 ); + flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1; + flags |= roi.height == 1 ? CONTINUOUS_FLAG : 0; + + size_t esz = CV_ELEM_SIZE(flags); + data += roi.x*esz; + CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && + 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows ); + if( refcount ) + CV_XADD(refcount, 1); + if( roi.width < m.cols || roi.height < m.rows ) + flags |= SUBMATRIX_FLAG; + + step[0] = m.step[0]; step[1] = esz; + + if( rows <= 0 || cols <= 0 ) + { + release(); + rows = cols = 0; + } +} + + +Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _steps) : size(&rows) +{ + initEmpty(); + flags |= CV_MAT_TYPE(_type); + data = datastart = (uchar*)_data; + setSize(*this, _dims, _sizes, _steps, true); + finalizeHdr(*this); +} + + +Mat::Mat(const Mat& m, const Range* ranges) : size(&rows) +{ + initEmpty(); + int i, d = m.dims; + + CV_Assert(ranges); + for( i = 0; i < d; i++ ) + { + Range r = ranges[i]; + CV_Assert( r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]) ); + } + *this = m; + for( i = 0; i < d; i++ ) + { + Range r = ranges[i]; + if( r != Range::all() && r != Range(0, size.p[i])) + { + size.p[i] = r.end - r.start; + data += r.start*step.p[i]; + flags |= SUBMATRIX_FLAG; + } + } + updateContinuityFlag(*this); +} + + +Mat::Mat(const CvMatND* m, bool copyData) : size(&rows) +{ + initEmpty(); + if( !m ) + return; + data = datastart = m->data.ptr; + flags |= CV_MAT_TYPE(m->type); + int _sizes[CV_MAX_DIM]; + size_t _steps[CV_MAX_DIM]; + + int i, d = m->dims; + for( i = 0; i < d; i++ ) + { + _sizes[i] = m->dim[i].size; + _steps[i] = m->dim[i].step; + } + + setSize(*this, d, _sizes, _steps); + finalizeHdr(*this); + + if( copyData ) + { + Mat temp(*this); + temp.copyTo(*this); + } +} + + +Mat Mat::diag(int d) const +{ + CV_Assert( dims <= 2 ); + Mat m = *this; + size_t esz = elemSize(); + int len; + + if( d >= 0 ) + { + len = std::min(cols - d, rows); + m.data += esz*d; + } + else + { + len = std::min(rows + d, cols); + m.data -= step[0]*d; + } + CV_DbgAssert( len > 0 ); + + m.size[0] = m.rows = len; + m.size[1] = m.cols = 1; + m.step[0] += (len > 1 ? esz : 0); + + if( m.rows > 1 ) + m.flags &= ~CONTINUOUS_FLAG; + else + m.flags |= CONTINUOUS_FLAG; + + if( size() != Size(1,1) ) + m.flags |= SUBMATRIX_FLAG; + + return m; +} + + +Mat::Mat(const CvMat* m, bool copyData) : size(&rows) +{ + initEmpty(); + + if( !m ) + return; + + if( !copyData ) + { + flags = MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG)); + dims = 2; + rows = m->rows; + cols = m->cols; + data = datastart = m->data.ptr; + size_t esz = CV_ELEM_SIZE(m->type), minstep = cols*esz, _step = m->step; + if( _step == 0 ) + _step = minstep; + datalimit = datastart + _step*rows; + dataend = datalimit - _step + minstep; + step[0] = _step; step[1] = esz; + } + else + { + data = datastart = dataend = 0; + Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this); + } +} + + +Mat::Mat(const IplImage* img, bool copyData) : size(&rows) +{ + initEmpty(); + + if( !img ) + return; + + dims = 2; + CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0); + + int imgdepth = IPL2CV_DEPTH(img->depth); + size_t esz; + step[0] = img->widthStep; + + if(!img->roi) + { + CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL); + flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels); + rows = img->height; cols = img->width; + datastart = data = (uchar*)img->imageData; + esz = CV_ELEM_SIZE(flags); + } + else + { + CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL || img->roi->coi != 0); + bool selectedPlane = img->roi->coi && img->dataOrder == IPL_DATA_ORDER_PLANE; + flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels); + rows = img->roi->height; cols = img->roi->width; + esz = CV_ELEM_SIZE(flags); + data = datastart = (uchar*)img->imageData + + (selectedPlane ? (img->roi->coi - 1)*step*img->height : 0) + + img->roi->yOffset*step[0] + img->roi->xOffset*esz; + } + datalimit = datastart + step.p[0]*rows; + dataend = datastart + step.p[0]*(rows-1) + esz*cols; + flags |= (cols*esz == step.p[0] || rows == 1 ? CONTINUOUS_FLAG : 0); + step[1] = esz; + + if( copyData ) + { + Mat m = *this; + release(); + if( !img->roi || !img->roi->coi || + img->dataOrder == IPL_DATA_ORDER_PLANE) + m.copyTo(*this); + else + { + int ch[] = {img->roi->coi - 1, 0}; + create(m.rows, m.cols, m.type()); + mixChannels(&m, 1, this, 1, ch, 1); + } + } +} + + +Mat::operator IplImage() const +{ + CV_Assert( dims <= 2 ); + IplImage img; + cvInitImageHeader(&img, size(), cvIplDepth(flags), channels()); + cvSetData(&img, data, (int)step[0]); + return img; +} + + +void Mat::pop_back(size_t nelems) +{ + CV_Assert( nelems <= (size_t)size.p[0] ); + + if( isSubmatrix() ) + *this = rowRange(0, size.p[0] - (int)nelems); + else + { + size.p[0] -= (int)nelems; + dataend -= nelems*step.p[0]; + /*if( size.p[0] <= 1 ) + { + if( dims <= 2 ) + flags |= CONTINUOUS_FLAG; + else + updateContinuityFlag(*this); + }*/ + } +} + + +void Mat::push_back_(const void* elem) +{ + int r = size.p[0]; + if( isSubmatrix() || dataend + step.p[0] > datalimit ) + reserve( std::max(r + 1, (r*3+1)/2) ); + + size_t esz = elemSize(); + memcpy(data + r*step.p[0], elem, esz); + size.p[0] = r + 1; + dataend += step.p[0]; + if( esz < step.p[0] ) + flags &= ~CONTINUOUS_FLAG; +} + +void Mat::reserve(size_t nelems) +{ + const size_t MIN_SIZE = 64; + + CV_Assert( (int)nelems >= 0 ); + if( !isSubmatrix() && data + step.p[0]*nelems <= datalimit ) + return; + + int r = size.p[0]; + + if( (size_t)r >= nelems ) + return; + + size.p[0] = std::max((int)nelems, 1); + size_t newsize = total()*elemSize(); + + if( newsize < MIN_SIZE ) + size.p[0] = (int)((MIN_SIZE + newsize - 1)*nelems/newsize); + + Mat m(dims, size.p, type()); + size.p[0] = r; + if( r > 0 ) + { + Mat mpart = m.rowRange(0, r); + copyTo(mpart); + } + + *this = m; + size.p[0] = r; + dataend = data + step.p[0]*r; +} + + +void Mat::resize(size_t nelems) +{ + int saveRows = size.p[0]; + if( saveRows == (int)nelems ) + return; + CV_Assert( (int)nelems >= 0 ); + + if( isSubmatrix() || data + step.p[0]*nelems > datalimit ) + reserve(nelems); + + size.p[0] = (int)nelems; + dataend += (size.p[0] - saveRows)*step.p[0]; + + //updateContinuityFlag(*this); +} + + +void Mat::resize(size_t nelems, const Scalar& s) +{ + int saveRows = size.p[0]; + resize(nelems); + + if( size.p[0] > saveRows ) + { + Mat part = rowRange(saveRows, size.p[0]); + part = s; + } +} + +void Mat::push_back(const Mat& elems) +{ + int r = size.p[0], delta = elems.size.p[0]; + if( delta == 0 ) + return; + if( this == &elems ) + { + Mat tmp = elems; + push_back(tmp); + return; + } + if( !data ) + { + *this = elems.clone(); + return; + } + + size.p[0] = elems.size.p[0]; + bool eq = size == elems.size; + size.p[0] = r; + if( !eq ) + CV_Error(CV_StsUnmatchedSizes, ""); + if( type() != elems.type() ) + CV_Error(CV_StsUnmatchedFormats, ""); + + if( isSubmatrix() || dataend + step.p[0]*delta > datalimit ) + reserve( std::max(r + delta, (r*3+1)/2) ); + + size.p[0] += delta; + dataend += step.p[0]*delta; + + //updateContinuityFlag(*this); + + if( isContinuous() && elems.isContinuous() ) + memcpy(data + r*step.p[0], elems.data, elems.total()*elems.elemSize()); + else + { + Mat part = rowRange(r, r + delta); + elems.copyTo(part); + } +} + + +Mat cvarrToMat(const CvArr* arr, bool copyData, + bool /*allowND*/, int coiMode) +{ + if( !arr ) + return Mat(); + if( CV_IS_MAT(arr) ) + return Mat((const CvMat*)arr, copyData ); + if( CV_IS_MATND(arr) ) + return Mat((const CvMatND*)arr, copyData ); + if( CV_IS_IMAGE(arr) ) + { + const IplImage* iplimg = (const IplImage*)arr; + if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 ) + CV_Error(CV_BadCOI, "COI is not supported by the function"); + return Mat(iplimg, copyData); + } + if( CV_IS_SEQ(arr) ) + { + CvSeq* seq = (CvSeq*)arr; + CV_Assert(seq->total > 0 && CV_ELEM_SIZE(seq->flags) == seq->elem_size); + if(!copyData && seq->first->next == seq->first) + return Mat(seq->total, 1, CV_MAT_TYPE(seq->flags), seq->first->data); + Mat buf(seq->total, 1, CV_MAT_TYPE(seq->flags)); + cvCvtSeqToArray(seq, buf.data, CV_WHOLE_SEQ); + return buf; + } + CV_Error(CV_StsBadArg, "Unknown array type"); + return Mat(); +} + +void Mat::locateROI( Size& wholeSize, Point& ofs ) const +{ + CV_Assert( dims <= 2 && step[0] > 0 ); + size_t esz = elemSize(), minstep; + ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart; + + if( delta1 == 0 ) + ofs.x = ofs.y = 0; + else + { + ofs.y = (int)(delta1/step[0]); + ofs.x = (int)((delta1 - step[0]*ofs.y)/esz); + CV_DbgAssert( data == datastart + ofs.y*step[0] + ofs.x*esz ); + } + minstep = (ofs.x + cols)*esz; + wholeSize.height = (int)((delta2 - minstep)/step[0] + 1); + wholeSize.height = std::max(wholeSize.height, ofs.y + rows); + wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz); + wholeSize.width = std::max(wholeSize.width, ofs.x + cols); +} + +Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright ) +{ + CV_Assert( dims <= 2 && step[0] > 0 ); + Size wholeSize; Point ofs; + size_t esz = elemSize(); + locateROI( wholeSize, ofs ); + int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height); + int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width); + data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz; + rows = row2 - row1; cols = col2 - col1; + size.p[0] = rows; size.p[1] = cols; + if( esz*cols == step[0] || rows == 1 ) + flags |= CONTINUOUS_FLAG; + else + flags &= ~CONTINUOUS_FLAG; + return *this; +} + +} + +void cv::extractImageCOI(const CvArr* arr, OutputArray _ch, int coi) +{ + Mat mat = cvarrToMat(arr, false, true, 1); + _ch.create(mat.dims, mat.size, mat.depth()); + Mat ch = _ch.getMat(); + if(coi < 0) + { + CV_Assert( CV_IS_IMAGE(arr) ); + coi = cvGetImageCOI((const IplImage*)arr)-1; + } + CV_Assert(0 <= coi && coi < mat.channels()); + int _pairs[] = { coi, 0 }; + mixChannels( &mat, 1, &ch, 1, _pairs, 1 ); +} + +void cv::insertImageCOI(InputArray _ch, CvArr* arr, int coi) +{ + Mat ch = _ch.getMat(), mat = cvarrToMat(arr, false, true, 1); + if(coi < 0) + { + CV_Assert( CV_IS_IMAGE(arr) ); + coi = cvGetImageCOI((const IplImage*)arr)-1; + } + CV_Assert(ch.size == mat.size && ch.depth() == mat.depth() && 0 <= coi && coi < mat.channels()); + int _pairs[] = { 0, coi }; + mixChannels( &ch, 1, &mat, 1, _pairs, 1 ); +} + +namespace cv +{ + +Mat Mat::reshape(int new_cn, int new_rows) const +{ + int cn = channels(); + Mat hdr = *this; + + if( dims > 2 && new_rows == 0 && new_cn != 0 && size[dims-1]*cn % new_cn == 0 ) + { + hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT); + hdr.step[dims-1] = CV_ELEM_SIZE(hdr.flags); + hdr.size[dims-1] = hdr.size[dims-1]*cn / new_cn; + return hdr; + } + + CV_Assert( dims <= 2 ); + + if( new_cn == 0 ) + new_cn = cn; + + int total_width = cols * cn; + + if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 ) + new_rows = rows * total_width / new_cn; + + if( new_rows != 0 && new_rows != rows ) + { + int total_size = total_width * rows; + if( !isContinuous() ) + CV_Error( CV_BadStep, + "The matrix is not continuous, thus its number of rows can not be changed" ); + + if( (unsigned)new_rows > (unsigned)total_size ) + CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + + total_width = total_size / new_rows; + + if( total_width * new_rows != total_size ) + CV_Error( CV_StsBadArg, "The total number of matrix elements " + "is not divisible by the new number of rows" ); + + hdr.rows = new_rows; + hdr.step[0] = total_width * elemSize1(); + } + + int new_width = total_width / new_cn; + + if( new_width * new_cn != total_width ) + CV_Error( CV_BadNumChannels, + "The total width is not divisible by the new number of channels" ); + + hdr.cols = new_width; + hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT); + hdr.step[1] = CV_ELEM_SIZE(hdr.flags); + return hdr; +} + + +int Mat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) const +{ + return (depth() == _depth || _depth <= 0) && + (isContinuous() || !_requireContinuous) && + ((dims == 2 && (((rows == 1 || cols == 1) && channels() == _elemChannels) || + (cols == _elemChannels && channels() == 1))) || + (dims == 3 && channels() == 1 && size.p[2] == _elemChannels && (size.p[0] == 1 || size.p[1] == 1) && + (isContinuous() || step.p[1] == step.p[2]*size.p[2]))) + ? (int)(total()*channels()/_elemChannels) : -1; +} + + +void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to) +{ + int i, depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); + CV_Assert(cn <= 4); + switch(depth) + { + case CV_8U: + { + uchar* buf = (uchar*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_8S: + { + schar* buf = (schar*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_16U: + { + ushort* buf = (ushort*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_16S: + { + short* buf = (short*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_32S: + { + int* buf = (int*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_32F: + { + float* buf = (float*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + } + break; + case CV_64F: + { + double* buf = (double*)_buf; + for(i = 0; i < cn; i++) + buf[i] = saturate_cast(s.val[i]); + for(; i < unroll_to; i++) + buf[i] = buf[i-cn]; + break; + } + default: + CV_Error(CV_StsUnsupportedFormat,""); + } +} + + +/*************************************************************************************************\ + Input/Output Array +\*************************************************************************************************/ + +_InputArray::_InputArray() : flags(0), obj(0) {} +#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY +_InputArray::~_InputArray() {} +#endif +_InputArray::_InputArray(const Mat& m) : flags(MAT), obj((void*)&m) {} +_InputArray::_InputArray(const vector& vec) : flags(STD_VECTOR_MAT), obj((void*)&vec) {} +_InputArray::_InputArray(const double& val) : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&val), sz(Size(1,1)) {} +_InputArray::_InputArray(const MatExpr& expr) : flags(FIXED_TYPE + FIXED_SIZE + EXPR), obj((void*)&expr) {} +// < Deprecated +_InputArray::_InputArray(const GlBuffer&) : flags(0), obj(0) {} +_InputArray::_InputArray(const GlTexture&) : flags(0), obj(0) {} +// > +_InputArray::_InputArray(const gpu::GpuMat& d_mat) : flags(GPU_MAT), obj((void*)&d_mat) {} +_InputArray::_InputArray(const ogl::Buffer& buf) : flags(OPENGL_BUFFER), obj((void*)&buf) {} +_InputArray::_InputArray(const ogl::Texture2D& tex) : flags(OPENGL_TEXTURE), obj((void*)&tex) {} + +Mat _InputArray::getMat(int i) const +{ + int k = kind(); + + if( k == MAT ) + { + const Mat* m = (const Mat*)obj; + if( i < 0 ) + return *m; + return m->row(i); + } + + if( k == EXPR ) + { + CV_Assert( i < 0 ); + return (Mat)*((const MatExpr*)obj); + } + + if( k == MATX ) + { + CV_Assert( i < 0 ); + return Mat(sz, flags, obj); + } + + if( k == STD_VECTOR ) + { + CV_Assert( i < 0 ); + int t = CV_MAT_TYPE(flags); + const vector& v = *(const vector*)obj; + + return !v.empty() ? Mat(size(), t, (void*)&v[0]) : Mat(); + } + + if( k == NONE ) + return Mat(); + + if( k == STD_VECTOR_VECTOR ) + { + int t = type(i); + const vector >& vv = *(const vector >*)obj; + CV_Assert( 0 <= i && i < (int)vv.size() ); + const vector& v = vv[i]; + + return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat(); + } + + CV_Assert( k == STD_VECTOR_MAT ); + //if( k == STD_VECTOR_MAT ) + { + const vector& v = *(const vector*)obj; + CV_Assert( 0 <= i && i < (int)v.size() ); + + return v[i]; + } +} + + +void _InputArray::getMatVector(vector& mv) const +{ + int k = kind(); + + if( k == MAT ) + { + const Mat& m = *(const Mat*)obj; + int i, n = (int)m.size[0]; + mv.resize(n); + + for( i = 0; i < n; i++ ) + mv[i] = m.dims == 2 ? Mat(1, m.cols, m.type(), (void*)m.ptr(i)) : + Mat(m.dims-1, &m.size[1], m.type(), (void*)m.ptr(i), &m.step[1]); + return; + } + + if( k == EXPR ) + { + Mat m = *(const MatExpr*)obj; + int i, n = m.size[0]; + mv.resize(n); + + for( i = 0; i < n; i++ ) + mv[i] = m.row(i); + return; + } + + if( k == MATX ) + { + size_t i, n = sz.height, esz = CV_ELEM_SIZE(flags); + mv.resize(n); + + for( i = 0; i < n; i++ ) + mv[i] = Mat(1, sz.width, CV_MAT_TYPE(flags), (uchar*)obj + esz*sz.width*i); + return; + } + + if( k == STD_VECTOR ) + { + const vector& v = *(const vector*)obj; + + size_t i, n = v.size(), esz = CV_ELEM_SIZE(flags); + int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags); + mv.resize(n); + + for( i = 0; i < n; i++ ) + mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i)); + return; + } + + if( k == NONE ) + { + mv.clear(); + return; + } + + if( k == STD_VECTOR_VECTOR ) + { + const vector >& vv = *(const vector >*)obj; + int i, n = (int)vv.size(); + int t = CV_MAT_TYPE(flags); + mv.resize(n); + + for( i = 0; i < n; i++ ) + { + const vector& v = vv[i]; + mv[i] = Mat(size(i), t, (void*)&v[0]); + } + return; + } + + CV_Assert( k == STD_VECTOR_MAT ); + //if( k == STD_VECTOR_MAT ) + { + const vector& v = *(const vector*)obj; + mv.resize(v.size()); + std::copy(v.begin(), v.end(), mv.begin()); + return; + } +} + +GlBuffer _InputArray::getGlBuffer() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return GlBuffer(GlBuffer::ARRAY_BUFFER); +} + +GlTexture _InputArray::getGlTexture() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return GlTexture(); +} + +gpu::GpuMat _InputArray::getGpuMat() const +{ + int k = kind(); + + CV_Assert(k == GPU_MAT); + + const gpu::GpuMat* d_mat = (const gpu::GpuMat*)obj; + return *d_mat; +} + +ogl::Buffer _InputArray::getOGlBuffer() const +{ + int k = kind(); + + CV_Assert(k == OPENGL_BUFFER); + + const ogl::Buffer* gl_buf = (const ogl::Buffer*)obj; + return *gl_buf; +} + +ogl::Texture2D _InputArray::getOGlTexture2D() const +{ + int k = kind(); + + CV_Assert(k == OPENGL_TEXTURE); + + const ogl::Texture2D* gl_tex = (const ogl::Texture2D*)obj; + return *gl_tex; +} + +int _InputArray::kind() const +{ + return flags & KIND_MASK; +} + +Size _InputArray::size(int i) const +{ + int k = kind(); + + if( k == MAT ) + { + CV_Assert( i < 0 ); + return ((const Mat*)obj)->size(); + } + + if( k == EXPR ) + { + CV_Assert( i < 0 ); + return ((const MatExpr*)obj)->size(); + } + + if( k == MATX ) + { + CV_Assert( i < 0 ); + return sz; + } + + if( k == STD_VECTOR ) + { + CV_Assert( i < 0 ); + const vector& v = *(const vector*)obj; + const vector& iv = *(const vector*)obj; + size_t szb = v.size(), szi = iv.size(); + return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); + } + + if( k == NONE ) + return Size(); + + if( k == STD_VECTOR_VECTOR ) + { + const vector >& vv = *(const vector >*)obj; + if( i < 0 ) + return vv.empty() ? Size() : Size((int)vv.size(), 1); + CV_Assert( i < (int)vv.size() ); + const vector >& ivv = *(const vector >*)obj; + + size_t szb = vv[i].size(), szi = ivv[i].size(); + return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); + } + + if( k == STD_VECTOR_MAT ) + { + const vector& vv = *(const vector*)obj; + if( i < 0 ) + return vv.empty() ? Size() : Size((int)vv.size(), 1); + CV_Assert( i < (int)vv.size() ); + + return vv[i].size(); + } + + if( k == OPENGL_BUFFER ) + { + CV_Assert( i < 0 ); + const ogl::Buffer* buf = (const ogl::Buffer*)obj; + return buf->size(); + } + + if( k == OPENGL_TEXTURE ) + { + CV_Assert( i < 0 ); + const ogl::Texture2D* tex = (const ogl::Texture2D*)obj; + return tex->size(); + } + + CV_Assert( k == GPU_MAT ); + //if( k == GPU_MAT ) + { + CV_Assert( i < 0 ); + const gpu::GpuMat* d_mat = (const gpu::GpuMat*)obj; + return d_mat->size(); + } +} + +size_t _InputArray::total(int i) const +{ + int k = kind(); + + if( k == MAT ) + { + CV_Assert( i < 0 ); + return ((const Mat*)obj)->total(); + } + + if( k == STD_VECTOR_MAT ) + { + const vector& vv = *(const vector*)obj; + if( i < 0 ) + return vv.size(); + + CV_Assert( i < (int)vv.size() ); + return vv[i].total(); + } + + return size(i).area(); +} + +int _InputArray::type(int i) const +{ + int k = kind(); + + if( k == MAT ) + return ((const Mat*)obj)->type(); + + if( k == EXPR ) + return ((const MatExpr*)obj)->type(); + + if( k == MATX || k == STD_VECTOR || k == STD_VECTOR_VECTOR ) + return CV_MAT_TYPE(flags); + + if( k == NONE ) + return -1; + + if( k == STD_VECTOR_MAT ) + { + const vector& vv = *(const vector*)obj; + CV_Assert( i < (int)vv.size() ); + + return vv[i >= 0 ? i : 0].type(); + } + + if( k == OPENGL_BUFFER ) + return ((const ogl::Buffer*)obj)->type(); + + CV_Assert( k == GPU_MAT ); + //if( k == GPU_MAT ) + return ((const gpu::GpuMat*)obj)->type(); +} + +int _InputArray::depth(int i) const +{ + return CV_MAT_DEPTH(type(i)); +} + +int _InputArray::channels(int i) const +{ + return CV_MAT_CN(type(i)); +} + +bool _InputArray::empty() const +{ + int k = kind(); + + if( k == MAT ) + return ((const Mat*)obj)->empty(); + + if( k == EXPR ) + return false; + + if( k == MATX ) + return false; + + if( k == STD_VECTOR ) + { + const vector& v = *(const vector*)obj; + return v.empty(); + } + + if( k == NONE ) + return true; + + if( k == STD_VECTOR_VECTOR ) + { + const vector >& vv = *(const vector >*)obj; + return vv.empty(); + } + + if( k == STD_VECTOR_MAT ) + { + const vector& vv = *(const vector*)obj; + return vv.empty(); + } + + if( k == OPENGL_BUFFER ) + return ((const ogl::Buffer*)obj)->empty(); + + if( k == OPENGL_TEXTURE ) + return ((const ogl::Texture2D*)obj)->empty(); + + CV_Assert( k == GPU_MAT ); + //if( k == GPU_MAT ) + return ((const gpu::GpuMat*)obj)->empty(); +} + + +_OutputArray::_OutputArray() {} +#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY +_OutputArray::~_OutputArray() {} +#endif +_OutputArray::_OutputArray(Mat& m) : _InputArray(m) {} +_OutputArray::_OutputArray(vector& vec) : _InputArray(vec) {} +_OutputArray::_OutputArray(gpu::GpuMat& d_mat) : _InputArray(d_mat) {} +_OutputArray::_OutputArray(ogl::Buffer& buf) : _InputArray(buf) {} +_OutputArray::_OutputArray(ogl::Texture2D& tex) : _InputArray(tex) {} + +_OutputArray::_OutputArray(const Mat& m) : _InputArray(m) {flags |= FIXED_SIZE|FIXED_TYPE;} +_OutputArray::_OutputArray(const vector& vec) : _InputArray(vec) {flags |= FIXED_SIZE;} +_OutputArray::_OutputArray(const gpu::GpuMat& d_mat) : _InputArray(d_mat) {flags |= FIXED_SIZE|FIXED_TYPE;} +_OutputArray::_OutputArray(const ogl::Buffer& buf) : _InputArray(buf) {flags |= FIXED_SIZE|FIXED_TYPE;} +_OutputArray::_OutputArray(const ogl::Texture2D& tex) : _InputArray(tex) {flags |= FIXED_SIZE|FIXED_TYPE;} + + +bool _OutputArray::fixedSize() const +{ + return (flags & FIXED_SIZE) == FIXED_SIZE; +} + +bool _OutputArray::fixedType() const +{ + return (flags & FIXED_TYPE) == FIXED_TYPE; +} + +void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int fixedDepthMask) const +{ + int k = kind(); + if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz); + CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype); + ((Mat*)obj)->create(_sz, mtype); + return; + } + if( k == GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((gpu::GpuMat*)obj)->size() == _sz); + CV_Assert(!fixedType() || ((gpu::GpuMat*)obj)->type() == mtype); + ((gpu::GpuMat*)obj)->create(_sz, mtype); + return; + } + if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == _sz); + CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype); + ((ogl::Buffer*)obj)->create(_sz, mtype); + return; + } + int sizes[] = {_sz.height, _sz.width}; + create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); +} + +void _OutputArray::create(int rows, int cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const +{ + int k = kind(); + if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(cols, rows)); + CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype); + ((Mat*)obj)->create(rows, cols, mtype); + return; + } + if( k == GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((gpu::GpuMat*)obj)->size() == Size(cols, rows)); + CV_Assert(!fixedType() || ((gpu::GpuMat*)obj)->type() == mtype); + ((gpu::GpuMat*)obj)->create(rows, cols, mtype); + return; + } + if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 ) + { + CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(cols, rows)); + CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype); + ((ogl::Buffer*)obj)->create(rows, cols, mtype); + return; + } + int sizes[] = {rows, cols}; + create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); +} + +void _OutputArray::create(int dims, const int* sizes, int mtype, int i, bool allowTransposed, int fixedDepthMask) const +{ + int k = kind(); + mtype = CV_MAT_TYPE(mtype); + + if( k == MAT ) + { + CV_Assert( i < 0 ); + Mat& m = *(Mat*)obj; + if( allowTransposed ) + { + if( !m.isContinuous() ) + { + CV_Assert(!fixedType() && !fixedSize()); + m.release(); + } + + if( dims == 2 && m.dims == 2 && m.data && + m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] ) + return; + } + + if(fixedType()) + { + if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 ) + mtype = m.type(); + else + CV_Assert(CV_MAT_TYPE(mtype) == m.type()); + } + if(fixedSize()) + { + CV_Assert(m.dims == dims); + for(int j = 0; j < dims; ++j) + CV_Assert(m.size[j] == sizes[j]); + } + m.create(dims, sizes, mtype); + return; + } + + if( k == MATX ) + { + CV_Assert( i < 0 ); + int type0 = CV_MAT_TYPE(flags); + CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) ); + CV_Assert( dims == 2 && ((sizes[0] == sz.height && sizes[1] == sz.width) || + (allowTransposed && sizes[0] == sz.width && sizes[1] == sz.height))); + return; + } + + if( k == STD_VECTOR || k == STD_VECTOR_VECTOR ) + { + CV_Assert( dims == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) ); + size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0; + vector* v = (vector*)obj; + + if( k == STD_VECTOR_VECTOR ) + { + vector >& vv = *(vector >*)obj; + if( i < 0 ) + { + CV_Assert(!fixedSize() || len == vv.size()); + vv.resize(len); + return; + } + CV_Assert( i < (int)vv.size() ); + v = &vv[i]; + } + else + CV_Assert( i < 0 ); + + int type0 = CV_MAT_TYPE(flags); + CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) ); + + int esz = CV_ELEM_SIZE(type0); + CV_Assert(!fixedSize() || len == ((vector*)v)->size() / esz); + switch( esz ) + { + case 1: + ((vector*)v)->resize(len); + break; + case 2: + ((vector*)v)->resize(len); + break; + case 3: + ((vector*)v)->resize(len); + break; + case 4: + ((vector*)v)->resize(len); + break; + case 6: + ((vector*)v)->resize(len); + break; + case 8: + ((vector*)v)->resize(len); + break; + case 12: + ((vector*)v)->resize(len); + break; + case 16: + ((vector*)v)->resize(len); + break; + case 24: + ((vector*)v)->resize(len); + break; + case 32: + ((vector*)v)->resize(len); + break; + case 36: + ((vector >*)v)->resize(len); + break; + case 48: + ((vector >*)v)->resize(len); + break; + case 64: + ((vector >*)v)->resize(len); + break; + case 128: + ((vector >*)v)->resize(len); + break; + case 256: + ((vector >*)v)->resize(len); + break; + case 512: + ((vector >*)v)->resize(len); + break; + default: + CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); + } + return; + } + + if( k == NONE ) + { + CV_Error(CV_StsNullPtr, "create() called for the missing output array" ); + return; + } + + CV_Assert( k == STD_VECTOR_MAT ); + //if( k == STD_VECTOR_MAT ) + { + vector& v = *(vector*)obj; + + if( i < 0 ) + { + CV_Assert( dims == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) ); + size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size(); + + CV_Assert(!fixedSize() || len == len0); + v.resize(len); + if( fixedType() ) + { + int _type = CV_MAT_TYPE(flags); + for( size_t j = len0; j < len; j++ ) + { + if( v[j].type() == _type ) + continue; + CV_Assert( v[j].empty() ); + v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type; + } + } + return; + } + + CV_Assert( i < (int)v.size() ); + Mat& m = v[i]; + + if( allowTransposed ) + { + if( !m.isContinuous() ) + { + CV_Assert(!fixedType() && !fixedSize()); + m.release(); + } + + if( dims == 2 && m.dims == 2 && m.data && + m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] ) + return; + } + + if(fixedType()) + { + if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 ) + mtype = m.type(); + else + CV_Assert(!fixedType() || (CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0)); + } + if(fixedSize()) + { + CV_Assert(m.dims == dims); + for(int j = 0; j < dims; ++j) + CV_Assert(m.size[j] == sizes[j]); + } + + m.create(dims, sizes, mtype); + } +} + +void _OutputArray::release() const +{ + CV_Assert(!fixedSize()); + + int k = kind(); + + if( k == MAT ) + { + ((Mat*)obj)->release(); + return; + } + + if( k == GPU_MAT ) + { + ((gpu::GpuMat*)obj)->release(); + return; + } + + if( k == OPENGL_BUFFER ) + { + ((ogl::Buffer*)obj)->release(); + return; + } + + if( k == OPENGL_TEXTURE ) + { + ((ogl::Texture2D*)obj)->release(); + return; + } + + if( k == NONE ) + return; + + if( k == STD_VECTOR ) + { + create(Size(), CV_MAT_TYPE(flags)); + return; + } + + if( k == STD_VECTOR_VECTOR ) + { + ((vector >*)obj)->clear(); + return; + } + + CV_Assert( k == STD_VECTOR_MAT ); + //if( k == STD_VECTOR_MAT ) + { + ((vector*)obj)->clear(); + } +} + +void _OutputArray::clear() const +{ + int k = kind(); + + if( k == MAT ) + { + CV_Assert(!fixedSize()); + ((Mat*)obj)->resize(0); + return; + } + + release(); +} + +bool _OutputArray::needed() const +{ + return kind() != NONE; +} + +Mat& _OutputArray::getMatRef(int i) const +{ + int k = kind(); + if( i < 0 ) + { + CV_Assert( k == MAT ); + return *(Mat*)obj; + } + else + { + CV_Assert( k == STD_VECTOR_MAT ); + vector& v = *(vector*)obj; + CV_Assert( i < (int)v.size() ); + return v[i]; + } +} + +gpu::GpuMat& _OutputArray::getGpuMatRef() const +{ + int k = kind(); + CV_Assert( k == GPU_MAT ); + return *(gpu::GpuMat*)obj; +} + +ogl::Buffer& _OutputArray::getOGlBufferRef() const +{ + int k = kind(); + CV_Assert( k == OPENGL_BUFFER ); + return *(ogl::Buffer*)obj; +} + +ogl::Texture2D& _OutputArray::getOGlTexture2DRef() const +{ + int k = kind(); + CV_Assert( k == OPENGL_TEXTURE ); + return *(ogl::Texture2D*)obj; +} + +static _OutputArray _none; +OutputArray noArray() { return _none; } + +} + +/*************************************************************************************************\ + Matrix Operations +\*************************************************************************************************/ + +void cv::hconcat(const Mat* src, size_t nsrc, OutputArray _dst) +{ + if( nsrc == 0 || !src ) + { + _dst.release(); + return; + } + + int totalCols = 0, cols = 0; + size_t i; + for( i = 0; i < nsrc; i++ ) + { + CV_Assert( !src[i].empty() && src[i].dims <= 2 && + src[i].rows == src[0].rows && + src[i].type() == src[0].type()); + totalCols += src[i].cols; + } + _dst.create( src[0].rows, totalCols, src[0].type()); + Mat dst = _dst.getMat(); + for( i = 0; i < nsrc; i++ ) + { + Mat dpart = dst(Rect(cols, 0, src[i].cols, src[i].rows)); + src[i].copyTo(dpart); + cols += src[i].cols; + } +} + +void cv::hconcat(InputArray src1, InputArray src2, OutputArray dst) +{ + Mat src[] = {src1.getMat(), src2.getMat()}; + hconcat(src, 2, dst); +} + +void cv::hconcat(InputArray _src, OutputArray dst) +{ + vector src; + _src.getMatVector(src); + hconcat(!src.empty() ? &src[0] : 0, src.size(), dst); +} + +void cv::vconcat(const Mat* src, size_t nsrc, OutputArray _dst) +{ + if( nsrc == 0 || !src ) + { + _dst.release(); + return; + } + + int totalRows = 0, rows = 0; + size_t i; + for( i = 0; i < nsrc; i++ ) + { + CV_Assert( !src[i].empty() && src[i].dims <= 2 && + src[i].cols == src[0].cols && + src[i].type() == src[0].type()); + totalRows += src[i].rows; + } + _dst.create( totalRows, src[0].cols, src[0].type()); + Mat dst = _dst.getMat(); + for( i = 0; i < nsrc; i++ ) + { + Mat dpart(dst, Rect(0, rows, src[i].cols, src[i].rows)); + src[i].copyTo(dpart); + rows += src[i].rows; + } +} + +void cv::vconcat(InputArray src1, InputArray src2, OutputArray dst) +{ + Mat src[] = {src1.getMat(), src2.getMat()}; + vconcat(src, 2, dst); +} + +void cv::vconcat(InputArray _src, OutputArray dst) +{ + vector src; + _src.getMatVector(src); + vconcat(!src.empty() ? &src[0] : 0, src.size(), dst); +} + +//////////////////////////////////////// set identity //////////////////////////////////////////// +void cv::setIdentity( InputOutputArray _m, const Scalar& s ) +{ + Mat m = _m.getMat(); + CV_Assert( m.dims <= 2 ); + int i, j, rows = m.rows, cols = m.cols, type = m.type(); + + if( type == CV_32FC1 ) + { + float* data = (float*)m.data; + float val = (float)s[0]; + size_t step = m.step/sizeof(data[0]); + + for( i = 0; i < rows; i++, data += step ) + { + for( j = 0; j < cols; j++ ) + data[j] = 0; + if( i < cols ) + data[i] = val; + } + } + else if( type == CV_64FC1 ) + { + double* data = (double*)m.data; + double val = s[0]; + size_t step = m.step/sizeof(data[0]); + + for( i = 0; i < rows; i++, data += step ) + { + for( j = 0; j < cols; j++ ) + data[j] = j == i ? val : 0; + } + } + else + { + m = Scalar(0); + m.diag() = s; + } +} + +//////////////////////////////////////////// trace /////////////////////////////////////////// + +cv::Scalar cv::trace( InputArray _m ) +{ + Mat m = _m.getMat(); + CV_Assert( m.dims <= 2 ); + int i, type = m.type(); + int nm = std::min(m.rows, m.cols); + + if( type == CV_32FC1 ) + { + const float* ptr = (const float*)m.data; + size_t step = m.step/sizeof(ptr[0]) + 1; + double _s = 0; + for( i = 0; i < nm; i++ ) + _s += ptr[i*step]; + return _s; + } + + if( type == CV_64FC1 ) + { + const double* ptr = (const double*)m.data; + size_t step = m.step/sizeof(ptr[0]) + 1; + double _s = 0; + for( i = 0; i < nm; i++ ) + _s += ptr[i*step]; + return _s; + } + + return cv::sum(m.diag()); +} + +////////////////////////////////////// transpose ///////////////////////////////////////// + +namespace cv +{ + +template static void +transpose_( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz ) +{ + int i=0, j, m = sz.width, n = sz.height; + + #if CV_ENABLE_UNROLLED + for(; i <= m - 4; i += 4 ) + { + T* d0 = (T*)(dst + dstep*i); + T* d1 = (T*)(dst + dstep*(i+1)); + T* d2 = (T*)(dst + dstep*(i+2)); + T* d3 = (T*)(dst + dstep*(i+3)); + + for( j = 0; j <= n - 4; j += 4 ) + { + const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j); + const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1)); + const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2)); + const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3)); + + d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0]; + d1[j] = s0[1]; d1[j+1] = s1[1]; d1[j+2] = s2[1]; d1[j+3] = s3[1]; + d2[j] = s0[2]; d2[j+1] = s1[2]; d2[j+2] = s2[2]; d2[j+3] = s3[2]; + d3[j] = s0[3]; d3[j+1] = s1[3]; d3[j+2] = s2[3]; d3[j+3] = s3[3]; + } + + for( ; j < n; j++ ) + { + const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep); + d0[j] = s0[0]; d1[j] = s0[1]; d2[j] = s0[2]; d3[j] = s0[3]; + } + } + #endif + for( ; i < m; i++ ) + { + T* d0 = (T*)(dst + dstep*i); + j = 0; + #if CV_ENABLE_UNROLLED + for(; j <= n - 4; j += 4 ) + { + const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j); + const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1)); + const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2)); + const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3)); + + d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0]; + } + #endif + for( ; j < n; j++ ) + { + const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep); + d0[j] = s0[0]; + } + } +} + +template static void +transposeI_( uchar* data, size_t step, int n ) +{ + int i, j; + for( i = 0; i < n; i++ ) + { + T* row = (T*)(data + step*i); + uchar* data1 = data + i*sizeof(T); + for( j = i+1; j < n; j++ ) + std::swap( row[j], *(T*)(data1 + step*j) ); + } +} + +typedef void (*TransposeFunc)( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz ); +typedef void (*TransposeInplaceFunc)( uchar* data, size_t step, int n ); + +#define DEF_TRANSPOSE_FUNC(suffix, type) \ +static void transpose_##suffix( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz ) \ +{ transpose_(src, sstep, dst, dstep, sz); } \ +\ +static void transposeI_##suffix( uchar* data, size_t step, int n ) \ +{ transposeI_(data, step, n); } + +DEF_TRANSPOSE_FUNC(8u, uchar) +DEF_TRANSPOSE_FUNC(16u, ushort) +DEF_TRANSPOSE_FUNC(8uC3, Vec3b) +DEF_TRANSPOSE_FUNC(32s, int) +DEF_TRANSPOSE_FUNC(16uC3, Vec3s) +DEF_TRANSPOSE_FUNC(32sC2, Vec2i) +DEF_TRANSPOSE_FUNC(32sC3, Vec3i) +DEF_TRANSPOSE_FUNC(32sC4, Vec4i) +DEF_TRANSPOSE_FUNC(32sC6, Vec6i) +DEF_TRANSPOSE_FUNC(32sC8, Vec8i) + +static TransposeFunc transposeTab[] = +{ + 0, transpose_8u, transpose_16u, transpose_8uC3, transpose_32s, 0, transpose_16uC3, 0, + transpose_32sC2, 0, 0, 0, transpose_32sC3, 0, 0, 0, transpose_32sC4, + 0, 0, 0, 0, 0, 0, 0, transpose_32sC6, 0, 0, 0, 0, 0, 0, 0, transpose_32sC8 +}; + +static TransposeInplaceFunc transposeInplaceTab[] = +{ + 0, transposeI_8u, transposeI_16u, transposeI_8uC3, transposeI_32s, 0, transposeI_16uC3, 0, + transposeI_32sC2, 0, 0, 0, transposeI_32sC3, 0, 0, 0, transposeI_32sC4, + 0, 0, 0, 0, 0, 0, 0, transposeI_32sC6, 0, 0, 0, 0, 0, 0, 0, transposeI_32sC8 +}; + +} + +void cv::transpose( InputArray _src, OutputArray _dst ) +{ + Mat src = _src.getMat(); + size_t esz = src.elemSize(); + CV_Assert( src.dims <= 2 && esz <= (size_t)32 ); + + _dst.create(src.cols, src.rows, src.type()); + Mat dst = _dst.getMat(); + + // handle the case of single-column/single-row matrices, stored in STL vectors. + if( src.rows != dst.cols || src.cols != dst.rows ) + { + CV_Assert( src.size() == dst.size() && (src.cols == 1 || src.rows == 1) ); + src.copyTo(dst); + return; + } + + if( dst.data == src.data ) + { + TransposeInplaceFunc func = transposeInplaceTab[esz]; + CV_Assert( func != 0 ); + func( dst.data, dst.step, dst.rows ); + } + else + { + TransposeFunc func = transposeTab[esz]; + CV_Assert( func != 0 ); + func( src.data, src.step, dst.data, dst.step, src.size() ); + } +} + + +void cv::completeSymm( InputOutputArray _m, bool LtoR ) +{ + Mat m = _m.getMat(); + CV_Assert( m.dims <= 2 ); + + int i, j, nrows = m.rows, type = m.type(); + int j0 = 0, j1 = nrows; + CV_Assert( m.rows == m.cols ); + + if( type == CV_32FC1 || type == CV_32SC1 ) + { + int* data = (int*)m.data; + size_t step = m.step/sizeof(data[0]); + for( i = 0; i < nrows; i++ ) + { + if( !LtoR ) j1 = i; else j0 = i+1; + for( j = j0; j < j1; j++ ) + data[i*step + j] = data[j*step + i]; + } + } + else if( type == CV_64FC1 ) + { + double* data = (double*)m.data; + size_t step = m.step/sizeof(data[0]); + for( i = 0; i < nrows; i++ ) + { + if( !LtoR ) j1 = i; else j0 = i+1; + for( j = j0; j < j1; j++ ) + data[i*step + j] = data[j*step + i]; + } + } + else + CV_Error( CV_StsUnsupportedFormat, "" ); +} + + +cv::Mat cv::Mat::cross(InputArray _m) const +{ + Mat m = _m.getMat(); + int tp = type(), d = CV_MAT_DEPTH(tp); + CV_Assert( dims <= 2 && m.dims <= 2 && size() == m.size() && tp == m.type() && + ((rows == 3 && cols == 1) || (cols*channels() == 3 && rows == 1))); + Mat result(rows, cols, tp); + + if( d == CV_32F ) + { + const float *a = (const float*)data, *b = (const float*)m.data; + float* c = (float*)result.data; + size_t lda = rows > 1 ? step/sizeof(a[0]) : 1; + size_t ldb = rows > 1 ? m.step/sizeof(b[0]) : 1; + + c[0] = a[lda] * b[ldb*2] - a[lda*2] * b[ldb]; + c[1] = a[lda*2] * b[0] - a[0] * b[ldb*2]; + c[2] = a[0] * b[ldb] - a[lda] * b[0]; + } + else if( d == CV_64F ) + { + const double *a = (const double*)data, *b = (const double*)m.data; + double* c = (double*)result.data; + size_t lda = rows > 1 ? step/sizeof(a[0]) : 1; + size_t ldb = rows > 1 ? m.step/sizeof(b[0]) : 1; + + c[0] = a[lda] * b[ldb*2] - a[lda*2] * b[ldb]; + c[1] = a[lda*2] * b[0] - a[0] * b[ldb*2]; + c[2] = a[0] * b[ldb] - a[lda] * b[0]; + } + + return result; +} + + +////////////////////////////////////////// reduce //////////////////////////////////////////// + +namespace cv +{ + +template static void +reduceR_( const Mat& srcmat, Mat& dstmat ) +{ + typedef typename Op::rtype WT; + Size size = srcmat.size(); + size.width *= srcmat.channels(); + AutoBuffer buffer(size.width); + WT* buf = buffer; + ST* dst = (ST*)dstmat.data; + const T* src = (const T*)srcmat.data; + size_t srcstep = srcmat.step/sizeof(src[0]); + int i; + Op op; + + for( i = 0; i < size.width; i++ ) + buf[i] = src[i]; + + for( ; --size.height; ) + { + src += srcstep; + i = 0; + #if CV_ENABLE_UNROLLED + for(; i <= size.width - 4; i += 4 ) + { + WT s0, s1; + s0 = op(buf[i], (WT)src[i]); + s1 = op(buf[i+1], (WT)src[i+1]); + buf[i] = s0; buf[i+1] = s1; + + s0 = op(buf[i+2], (WT)src[i+2]); + s1 = op(buf[i+3], (WT)src[i+3]); + buf[i+2] = s0; buf[i+3] = s1; + } + #endif + for( ; i < size.width; i++ ) + buf[i] = op(buf[i], (WT)src[i]); + } + + for( i = 0; i < size.width; i++ ) + dst[i] = (ST)buf[i]; +} + + +template static void +reduceC_( const Mat& srcmat, Mat& dstmat ) +{ + typedef typename Op::rtype WT; + Size size = srcmat.size(); + int i, k, cn = srcmat.channels(); + size.width *= cn; + Op op; + + for( int y = 0; y < size.height; y++ ) + { + const T* src = (const T*)(srcmat.data + srcmat.step*y); + ST* dst = (ST*)(dstmat.data + dstmat.step*y); + if( size.width == cn ) + for( k = 0; k < cn; k++ ) + dst[k] = src[k]; + else + { + for( k = 0; k < cn; k++ ) + { + WT a0 = src[k], a1 = src[k+cn]; + for( i = 2*cn; i <= size.width - 4*cn; i += 4*cn ) + { + a0 = op(a0, (WT)src[i+k]); + a1 = op(a1, (WT)src[i+k+cn]); + a0 = op(a0, (WT)src[i+k+cn*2]); + a1 = op(a1, (WT)src[i+k+cn*3]); + } + + for( ; i < size.width; i += cn ) + { + a0 = op(a0, (WT)src[i+k]); + } + a0 = op(a0, a1); + dst[k] = (ST)a0; + } + } + } +} + +typedef void (*ReduceFunc)( const Mat& src, Mat& dst ); + +} + +#define reduceSumR8u32s reduceR_ > +#define reduceSumR8u32f reduceR_ > +#define reduceSumR8u64f reduceR_ > +#define reduceSumR16u32f reduceR_ > +#define reduceSumR16u64f reduceR_ > +#define reduceSumR16s32f reduceR_ > +#define reduceSumR16s64f reduceR_ > +#define reduceSumR32f32f reduceR_ > +#define reduceSumR32f64f reduceR_ > +#define reduceSumR64f64f reduceR_ > + +#define reduceMaxR8u reduceR_ > +#define reduceMaxR16u reduceR_ > +#define reduceMaxR16s reduceR_ > +#define reduceMaxR32f reduceR_ > +#define reduceMaxR64f reduceR_ > + +#define reduceMinR8u reduceR_ > +#define reduceMinR16u reduceR_ > +#define reduceMinR16s reduceR_ > +#define reduceMinR32f reduceR_ > +#define reduceMinR64f reduceR_ > + +#define reduceSumC8u32s reduceC_ > +#define reduceSumC8u32f reduceC_ > +#define reduceSumC8u64f reduceC_ > +#define reduceSumC16u32f reduceC_ > +#define reduceSumC16u64f reduceC_ > +#define reduceSumC16s32f reduceC_ > +#define reduceSumC16s64f reduceC_ > +#define reduceSumC32f32f reduceC_ > +#define reduceSumC32f64f reduceC_ > +#define reduceSumC64f64f reduceC_ > + +#define reduceMaxC8u reduceC_ > +#define reduceMaxC16u reduceC_ > +#define reduceMaxC16s reduceC_ > +#define reduceMaxC32f reduceC_ > +#define reduceMaxC64f reduceC_ > + +#define reduceMinC8u reduceC_ > +#define reduceMinC16u reduceC_ > +#define reduceMinC16s reduceC_ > +#define reduceMinC32f reduceC_ > +#define reduceMinC64f reduceC_ > + +void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) +{ + Mat src = _src.getMat(); + CV_Assert( src.dims <= 2 ); + int op0 = op; + int stype = src.type(), sdepth = src.depth(), cn = src.channels(); + if( dtype < 0 ) + dtype = _dst.fixedType() ? _dst.type() : stype; + int ddepth = CV_MAT_DEPTH(dtype); + + _dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1, + CV_MAKETYPE(dtype >= 0 ? dtype : stype, cn)); + Mat dst = _dst.getMat(), temp = dst; + + CV_Assert( op == CV_REDUCE_SUM || op == CV_REDUCE_MAX || + op == CV_REDUCE_MIN || op == CV_REDUCE_AVG ); + CV_Assert( src.channels() == dst.channels() ); + + if( op == CV_REDUCE_AVG ) + { + op = CV_REDUCE_SUM; + if( sdepth < CV_32S && ddepth < CV_32S ) + { + temp.create(dst.rows, dst.cols, CV_32SC(cn)); + ddepth = CV_32S; + } + } + + ReduceFunc func = 0; + if( dim == 0 ) + { + if( op == CV_REDUCE_SUM ) + { + if(sdepth == CV_8U && ddepth == CV_32S) + func = GET_OPTIMIZED(reduceSumR8u32s); + else if(sdepth == CV_8U && ddepth == CV_32F) + func = reduceSumR8u32f; + else if(sdepth == CV_8U && ddepth == CV_64F) + func = reduceSumR8u64f; + else if(sdepth == CV_16U && ddepth == CV_32F) + func = reduceSumR16u32f; + else if(sdepth == CV_16U && ddepth == CV_64F) + func = reduceSumR16u64f; + else if(sdepth == CV_16S && ddepth == CV_32F) + func = reduceSumR16s32f; + else if(sdepth == CV_16S && ddepth == CV_64F) + func = reduceSumR16s64f; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceSumR32f32f); + else if(sdepth == CV_32F && ddepth == CV_64F) + func = reduceSumR32f64f; + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceSumR64f64f; + } + else if(op == CV_REDUCE_MAX) + { + if(sdepth == CV_8U && ddepth == CV_8U) + func = GET_OPTIMIZED(reduceMaxR8u); + else if(sdepth == CV_16U && ddepth == CV_16U) + func = reduceMaxR16u; + else if(sdepth == CV_16S && ddepth == CV_16S) + func = reduceMaxR16s; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceMaxR32f); + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceMaxR64f; + } + else if(op == CV_REDUCE_MIN) + { + if(sdepth == CV_8U && ddepth == CV_8U) + func = GET_OPTIMIZED(reduceMinR8u); + else if(sdepth == CV_16U && ddepth == CV_16U) + func = reduceMinR16u; + else if(sdepth == CV_16S && ddepth == CV_16S) + func = reduceMinR16s; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceMinR32f); + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceMinR64f; + } + } + else + { + if(op == CV_REDUCE_SUM) + { + if(sdepth == CV_8U && ddepth == CV_32S) + func = GET_OPTIMIZED(reduceSumC8u32s); + else if(sdepth == CV_8U && ddepth == CV_32F) + func = reduceSumC8u32f; + else if(sdepth == CV_8U && ddepth == CV_64F) + func = reduceSumC8u64f; + else if(sdepth == CV_16U && ddepth == CV_32F) + func = reduceSumC16u32f; + else if(sdepth == CV_16U && ddepth == CV_64F) + func = reduceSumC16u64f; + else if(sdepth == CV_16S && ddepth == CV_32F) + func = reduceSumC16s32f; + else if(sdepth == CV_16S && ddepth == CV_64F) + func = reduceSumC16s64f; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceSumC32f32f); + else if(sdepth == CV_32F && ddepth == CV_64F) + func = reduceSumC32f64f; + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceSumC64f64f; + } + else if(op == CV_REDUCE_MAX) + { + if(sdepth == CV_8U && ddepth == CV_8U) + func = GET_OPTIMIZED(reduceMaxC8u); + else if(sdepth == CV_16U && ddepth == CV_16U) + func = reduceMaxC16u; + else if(sdepth == CV_16S && ddepth == CV_16S) + func = reduceMaxC16s; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceMaxC32f); + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceMaxC64f; + } + else if(op == CV_REDUCE_MIN) + { + if(sdepth == CV_8U && ddepth == CV_8U) + func = GET_OPTIMIZED(reduceMinC8u); + else if(sdepth == CV_16U && ddepth == CV_16U) + func = reduceMinC16u; + else if(sdepth == CV_16S && ddepth == CV_16S) + func = reduceMinC16s; + else if(sdepth == CV_32F && ddepth == CV_32F) + func = GET_OPTIMIZED(reduceMinC32f); + else if(sdepth == CV_64F && ddepth == CV_64F) + func = reduceMinC64f; + } + } + + if( !func ) + CV_Error( CV_StsUnsupportedFormat, + "Unsupported combination of input and output array formats" ); + + func( src, temp ); + + if( op0 == CV_REDUCE_AVG ) + temp.convertTo(dst, dst.type(), 1./(dim == 0 ? src.rows : src.cols)); +} + + +//////////////////////////////////////// sort /////////////////////////////////////////// + +namespace cv +{ + +template static void sort_( const Mat& src, Mat& dst, int flags ) +{ + AutoBuffer buf; + T* bptr; + int i, j, n, len; + bool sortRows = (flags & 1) == CV_SORT_EVERY_ROW; + bool inplace = src.data == dst.data; + bool sortDescending = (flags & CV_SORT_DESCENDING) != 0; + + if( sortRows ) + n = src.rows, len = src.cols; + else + { + n = src.cols, len = src.rows; + buf.allocate(len); + } + bptr = (T*)buf; + + for( i = 0; i < n; i++ ) + { + T* ptr = bptr; + if( sortRows ) + { + T* dptr = (T*)(dst.data + dst.step*i); + if( !inplace ) + { + const T* sptr = (const T*)(src.data + src.step*i); + for( j = 0; j < len; j++ ) + dptr[j] = sptr[j]; + } + ptr = dptr; + } + else + { + for( j = 0; j < len; j++ ) + ptr[j] = ((const T*)(src.data + src.step*j))[i]; + } + std::sort( ptr, ptr + len, LessThan() ); + if( sortDescending ) + for( j = 0; j < len/2; j++ ) + std::swap(ptr[j], ptr[len-1-j]); + if( !sortRows ) + for( j = 0; j < len; j++ ) + ((T*)(dst.data + dst.step*j))[i] = ptr[j]; + } +} + + +template static void sortIdx_( const Mat& src, Mat& dst, int flags ) +{ + AutoBuffer buf; + AutoBuffer ibuf; + T* bptr; + int* _iptr; + int i, j, n, len; + bool sortRows = (flags & 1) == CV_SORT_EVERY_ROW; + bool sortDescending = (flags & CV_SORT_DESCENDING) != 0; + + CV_Assert( src.data != dst.data ); + + if( sortRows ) + n = src.rows, len = src.cols; + else + { + n = src.cols, len = src.rows; + buf.allocate(len); + ibuf.allocate(len); + } + bptr = (T*)buf; + _iptr = (int*)ibuf; + + for( i = 0; i < n; i++ ) + { + T* ptr = bptr; + int* iptr = _iptr; + + if( sortRows ) + { + ptr = (T*)(src.data + src.step*i); + iptr = (int*)(dst.data + dst.step*i); + } + else + { + for( j = 0; j < len; j++ ) + ptr[j] = ((const T*)(src.data + src.step*j))[i]; + } + for( j = 0; j < len; j++ ) + iptr[j] = j; + std::sort( iptr, iptr + len, LessThanIdx(ptr) ); + if( sortDescending ) + for( j = 0; j < len/2; j++ ) + std::swap(iptr[j], iptr[len-1-j]); + if( !sortRows ) + for( j = 0; j < len; j++ ) + ((int*)(dst.data + dst.step*j))[i] = iptr[j]; + } +} + +typedef void (*SortFunc)(const Mat& src, Mat& dst, int flags); + +} + +void cv::sort( InputArray _src, OutputArray _dst, int flags ) +{ + static SortFunc tab[] = + { + sort_, sort_, sort_, sort_, + sort_, sort_, sort_, 0 + }; + Mat src = _src.getMat(); + SortFunc func = tab[src.depth()]; + CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 ); + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + func( src, dst, flags ); +} + +void cv::sortIdx( InputArray _src, OutputArray _dst, int flags ) +{ + static SortFunc tab[] = + { + sortIdx_, sortIdx_, sortIdx_, sortIdx_, + sortIdx_, sortIdx_, sortIdx_, 0 + }; + Mat src = _src.getMat(); + SortFunc func = tab[src.depth()]; + CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 ); + + Mat dst = _dst.getMat(); + if( dst.data == src.data ) + _dst.release(); + _dst.create( src.size(), CV_32S ); + dst = _dst.getMat(); + func( src, dst, flags ); +} + + +////////////////////////////////////////// kmeans //////////////////////////////////////////// + +namespace cv +{ + +static void generateRandomCenter(const vector& box, float* center, RNG& rng) +{ + size_t j, dims = box.size(); + float margin = 1.f/dims; + for( j = 0; j < dims; j++ ) + center[j] = ((float)rng*(1.f+margin*2.f)-margin)*(box[j][1] - box[j][0]) + box[j][0]; +} + +class KMeansPPDistanceComputer : public ParallelLoopBody +{ +public: + KMeansPPDistanceComputer( float *_tdist2, + const float *_data, + const float *_dist, + int _dims, + size_t _step, + size_t _stepci ) + : tdist2(_tdist2), + data(_data), + dist(_dist), + dims(_dims), + step(_step), + stepci(_stepci) { } + + void operator()( const cv::Range& range ) const + { + const int begin = range.start; + const int end = range.end; + + for ( int i = begin; i(0); + size_t step = _data.step/sizeof(data[0]); + vector _centers(K); + int* centers = &_centers[0]; + vector _dist(N*3); + float* dist = &_dist[0], *tdist = dist + N, *tdist2 = tdist + N; + double sum0 = 0; + + centers[0] = (unsigned)rng % N; + + for( i = 0; i < N; i++ ) + { + dist[i] = normL2Sqr_(data + step*i, data + step*centers[0], dims); + sum0 += dist[i]; + } + + for( k = 1; k < K; k++ ) + { + double bestSum = DBL_MAX; + int bestCenter = -1; + + for( j = 0; j < trials; j++ ) + { + double p = (double)rng*sum0, s = 0; + for( i = 0; i < N-1; i++ ) + if( (p -= dist[i]) <= 0 ) + break; + int ci = i; + + parallel_for_(Range(0, N), + KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci)); + for( i = 0; i < N; i++ ) + { + s += tdist2[i]; + } + + if( s < bestSum ) + { + bestSum = s; + bestCenter = ci; + std::swap(tdist, tdist2); + } + } + centers[k] = bestCenter; + sum0 = bestSum; + std::swap(dist, tdist); + } + + for( k = 0; k < K; k++ ) + { + const float* src = data + step*centers[k]; + float* dst = _out_centers.ptr(k); + for( j = 0; j < dims; j++ ) + dst[j] = src[j]; + } +} + +class KMeansDistanceComputer : public ParallelLoopBody +{ +public: + KMeansDistanceComputer( double *_distances, + int *_labels, + const Mat& _data, + const Mat& _centers ) + : distances(_distances), + labels(_labels), + data(_data), + centers(_centers) + { + } + + void operator()( const Range& range ) const + { + const int begin = range.start; + const int end = range.end; + const int K = centers.rows; + const int dims = centers.cols; + + const float *sample; + for( int i = begin; i(i); + int k_best = 0; + double min_dist = DBL_MAX; + + for( int k = 0; k < K; k++ ) + { + const float* center = centers.ptr(k); + const double dist = normL2Sqr_(sample, center, dims); + + if( min_dist > dist ) + { + min_dist = dist; + k_best = k; + } + } + + distances[i] = min_dist; + labels[i] = k_best; + } + } + +private: + KMeansDistanceComputer& operator=(const KMeansDistanceComputer&); // to quiet MSVC + + double *distances; + int *labels; + const Mat& data; + const Mat& centers; +}; + +} + +double cv::kmeans( InputArray _data, int K, + InputOutputArray _bestLabels, + TermCriteria criteria, int attempts, + int flags, OutputArray _centers ) +{ + const int SPP_TRIALS = 3; + Mat data = _data.getMat(); + bool isrow = data.rows == 1 && data.channels() > 1; + int N = !isrow ? data.rows : data.cols; + int dims = (!isrow ? data.cols : 1)*data.channels(); + int type = data.depth(); + + attempts = std::max(attempts, 1); + CV_Assert( data.dims <= 2 && type == CV_32F && K > 0 ); + CV_Assert( N >= K ); + + _bestLabels.create(N, 1, CV_32S, -1, true); + + Mat _labels, best_labels = _bestLabels.getMat(); + if( flags & CV_KMEANS_USE_INITIAL_LABELS ) + { + CV_Assert( (best_labels.cols == 1 || best_labels.rows == 1) && + best_labels.cols*best_labels.rows == N && + best_labels.type() == CV_32S && + best_labels.isContinuous()); + best_labels.copyTo(_labels); + } + else + { + if( !((best_labels.cols == 1 || best_labels.rows == 1) && + best_labels.cols*best_labels.rows == N && + best_labels.type() == CV_32S && + best_labels.isContinuous())) + best_labels.create(N, 1, CV_32S); + _labels.create(best_labels.size(), best_labels.type()); + } + int* labels = _labels.ptr(); + + Mat centers(K, dims, type), old_centers(K, dims, type), temp(1, dims, type); + vector counters(K); + vector _box(dims); + Vec2f* box = &_box[0]; + double best_compactness = DBL_MAX, compactness = 0; + RNG& rng = theRNG(); + int a, iter, i, j, k; + + if( criteria.type & TermCriteria::EPS ) + criteria.epsilon = std::max(criteria.epsilon, 0.); + else + criteria.epsilon = FLT_EPSILON; + criteria.epsilon *= criteria.epsilon; + + if( criteria.type & TermCriteria::COUNT ) + criteria.maxCount = std::min(std::max(criteria.maxCount, 2), 100); + else + criteria.maxCount = 100; + + if( K == 1 ) + { + attempts = 1; + criteria.maxCount = 2; + } + + const float* sample = data.ptr(0); + for( j = 0; j < dims; j++ ) + box[j] = Vec2f(sample[j], sample[j]); + + for( i = 1; i < N; i++ ) + { + sample = data.ptr(i); + for( j = 0; j < dims; j++ ) + { + float v = sample[j]; + box[j][0] = std::min(box[j][0], v); + box[j][1] = std::max(box[j][1], v); + } + } + + for( a = 0; a < attempts; a++ ) + { + double max_center_shift = DBL_MAX; + for( iter = 0;; ) + { + swap(centers, old_centers); + + if( iter == 0 && (a > 0 || !(flags & KMEANS_USE_INITIAL_LABELS)) ) + { + if( flags & KMEANS_PP_CENTERS ) + generateCentersPP(data, centers, K, rng, SPP_TRIALS); + else + { + for( k = 0; k < K; k++ ) + generateRandomCenter(_box, centers.ptr(k), rng); + } + } + else + { + if( iter == 0 && a == 0 && (flags & KMEANS_USE_INITIAL_LABELS) ) + { + for( i = 0; i < N; i++ ) + CV_Assert( (unsigned)labels[i] < (unsigned)K ); + } + + // compute centers + centers = Scalar(0); + for( k = 0; k < K; k++ ) + counters[k] = 0; + + for( i = 0; i < N; i++ ) + { + sample = data.ptr(i); + k = labels[i]; + float* center = centers.ptr(k); + j=0; + #if CV_ENABLE_UNROLLED + for(; j <= dims - 4; j += 4 ) + { + float t0 = center[j] + sample[j]; + float t1 = center[j+1] + sample[j+1]; + + center[j] = t0; + center[j+1] = t1; + + t0 = center[j+2] + sample[j+2]; + t1 = center[j+3] + sample[j+3]; + + center[j+2] = t0; + center[j+3] = t1; + } + #endif + for( ; j < dims; j++ ) + center[j] += sample[j]; + counters[k]++; + } + + if( iter > 0 ) + max_center_shift = 0; + + for( k = 0; k < K; k++ ) + { + if( counters[k] != 0 ) + continue; + + // if some cluster appeared to be empty then: + // 1. find the biggest cluster + // 2. find the farthest from the center point in the biggest cluster + // 3. exclude the farthest point from the biggest cluster and form a new 1-point cluster. + int max_k = 0; + for( int k1 = 1; k1 < K; k1++ ) + { + if( counters[max_k] < counters[k1] ) + max_k = k1; + } + + double max_dist = 0; + int farthest_i = -1; + float* new_center = centers.ptr(k); + float* old_center = centers.ptr(max_k); + float* _old_center = temp.ptr(); // normalized + float scale = 1.f/counters[max_k]; + for( j = 0; j < dims; j++ ) + _old_center[j] = old_center[j]*scale; + + for( i = 0; i < N; i++ ) + { + if( labels[i] != max_k ) + continue; + sample = data.ptr(i); + double dist = normL2Sqr_(sample, _old_center, dims); + + if( max_dist <= dist ) + { + max_dist = dist; + farthest_i = i; + } + } + + counters[max_k]--; + counters[k]++; + labels[farthest_i] = k; + sample = data.ptr(farthest_i); + + for( j = 0; j < dims; j++ ) + { + old_center[j] -= sample[j]; + new_center[j] += sample[j]; + } + } + + for( k = 0; k < K; k++ ) + { + float* center = centers.ptr(k); + CV_Assert( counters[k] != 0 ); + + float scale = 1.f/counters[k]; + for( j = 0; j < dims; j++ ) + center[j] *= scale; + + if( iter > 0 ) + { + double dist = 0; + const float* old_center = old_centers.ptr(k); + for( j = 0; j < dims; j++ ) + { + double t = center[j] - old_center[j]; + dist += t*t; + } + max_center_shift = std::max(max_center_shift, dist); + } + } + } + + if( ++iter == MAX(criteria.maxCount, 2) || max_center_shift <= criteria.epsilon ) + break; + + // assign labels + Mat dists(1, N, CV_64F); + double* dist = dists.ptr(0); + parallel_for_(Range(0, N), + KMeansDistanceComputer(dist, labels, data, centers)); + compactness = 0; + for( i = 0; i < N; i++ ) + { + compactness += dist[i]; + } + } + + if( compactness < best_compactness ) + { + best_compactness = compactness; + if( _centers.needed() ) + centers.copyTo(_centers); + _labels.copyTo(best_labels); + } + } + + return best_compactness; +} + + +CV_IMPL void cvSetIdentity( CvArr* arr, CvScalar value ) +{ + cv::Mat m = cv::cvarrToMat(arr); + cv::setIdentity(m, value); +} + + +CV_IMPL CvScalar cvTrace( const CvArr* arr ) +{ + return cv::trace(cv::cvarrToMat(arr)); +} + + +CV_IMPL void cvTranspose( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.rows == dst.cols && src.cols == dst.rows && src.type() == dst.type() ); + transpose( src, dst ); +} + + +CV_IMPL void cvCompleteSymm( CvMat* matrix, int LtoR ) +{ + cv::Mat m(matrix); + cv::completeSymm( m, LtoR != 0 ); +} + + +CV_IMPL void cvCrossProduct( const CvArr* srcAarr, const CvArr* srcBarr, CvArr* dstarr ) +{ + cv::Mat srcA = cv::cvarrToMat(srcAarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( srcA.size() == dst.size() && srcA.type() == dst.type() ); + srcA.cross(cv::cvarrToMat(srcBarr)).copyTo(dst); +} + + +CV_IMPL void +cvReduce( const CvArr* srcarr, CvArr* dstarr, int dim, int op ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + if( dim < 0 ) + dim = src.rows > dst.rows ? 0 : src.cols > dst.cols ? 1 : dst.cols == 1; + + if( dim > 1 ) + CV_Error( CV_StsOutOfRange, "The reduced dimensionality index is out of range" ); + + if( (dim == 0 && (dst.cols != src.cols || dst.rows != 1)) || + (dim == 1 && (dst.rows != src.rows || dst.cols != 1)) ) + CV_Error( CV_StsBadSize, "The output array size is incorrect" ); + + if( src.channels() != dst.channels() ) + CV_Error( CV_StsUnmatchedFormats, "Input and output arrays must have the same number of channels" ); + + cv::reduce(src, dst, dim, op, dst.type()); +} + + +CV_IMPL CvArr* +cvRange( CvArr* arr, double start, double end ) +{ + int ok = 0; + + CvMat stub, *mat = (CvMat*)arr; + double delta; + int type, step; + double val = start; + int i, j; + int rows, cols; + + if( !CV_IS_MAT(mat) ) + mat = cvGetMat( mat, &stub); + + rows = mat->rows; + cols = mat->cols; + type = CV_MAT_TYPE(mat->type); + delta = (end-start)/(rows*cols); + + if( CV_IS_MAT_CONT(mat->type) ) + { + cols *= rows; + rows = 1; + step = 1; + } + else + step = mat->step / CV_ELEM_SIZE(type); + + if( type == CV_32SC1 ) + { + int* idata = mat->data.i; + int ival = cvRound(val), idelta = cvRound(delta); + + if( fabs(val - ival) < DBL_EPSILON && + fabs(delta - idelta) < DBL_EPSILON ) + { + for( i = 0; i < rows; i++, idata += step ) + for( j = 0; j < cols; j++, ival += idelta ) + idata[j] = ival; + } + else + { + for( i = 0; i < rows; i++, idata += step ) + for( j = 0; j < cols; j++, val += delta ) + idata[j] = cvRound(val); + } + } + else if( type == CV_32FC1 ) + { + float* fdata = mat->data.fl; + for( i = 0; i < rows; i++, fdata += step ) + for( j = 0; j < cols; j++, val += delta ) + fdata[j] = (float)val; + } + else + CV_Error( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); + + ok = 1; + return ok ? arr : 0; +} + + +CV_IMPL void +cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags ) +{ + cv::Mat src = cv::cvarrToMat(_src); + + if( _idx ) + { + cv::Mat idx0 = cv::cvarrToMat(_idx), idx = idx0; + CV_Assert( src.size() == idx.size() && idx.type() == CV_32S && src.data != idx.data ); + cv::sortIdx( src, idx, flags ); + CV_Assert( idx0.data == idx.data ); + } + + if( _dst ) + { + cv::Mat dst0 = cv::cvarrToMat(_dst), dst = dst0; + CV_Assert( src.size() == dst.size() && src.type() == dst.type() ); + cv::sort( src, dst, flags ); + CV_Assert( dst0.data == dst.data ); + } +} + + +CV_IMPL int +cvKMeans2( const CvArr* _samples, int cluster_count, CvArr* _labels, + CvTermCriteria termcrit, int attempts, CvRNG*, + int flags, CvArr* _centers, double* _compactness ) +{ + cv::Mat data = cv::cvarrToMat(_samples), labels = cv::cvarrToMat(_labels), centers; + if( _centers ) + { + centers = cv::cvarrToMat(_centers); + + centers = centers.reshape(1); + data = data.reshape(1); + + CV_Assert( !centers.empty() ); + CV_Assert( centers.rows == cluster_count ); + CV_Assert( centers.cols == data.cols ); + CV_Assert( centers.depth() == data.depth() ); + } + CV_Assert( labels.isContinuous() && labels.type() == CV_32S && + (labels.cols == 1 || labels.rows == 1) && + labels.cols + labels.rows - 1 == data.rows ); + + double compactness = cv::kmeans(data, cluster_count, labels, termcrit, attempts, + flags, _centers ? cv::_OutputArray(centers) : cv::_OutputArray() ); + if( _compactness ) + *_compactness = compactness; + return 1; +} + +///////////////////////////// n-dimensional matrices //////////////////////////// + +namespace cv +{ + +Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const +{ + if(_newndims == dims) + { + if(_newsz == 0) + return reshape(_cn); + if(_newndims == 2) + return reshape(_cn, _newsz[0]); + } + + CV_Error(CV_StsNotImplemented, ""); + // TBD + return Mat(); +} + +Mat::operator CvMatND() const +{ + CvMatND mat; + cvInitMatNDHeader( &mat, dims, size, type(), data ); + int i, d = dims; + for( i = 0; i < d; i++ ) + mat.dim[i].step = (int)step[i]; + mat.type |= flags & CONTINUOUS_FLAG; + return mat; +} + +NAryMatIterator::NAryMatIterator() + : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0) +{ +} + +NAryMatIterator::NAryMatIterator(const Mat** _arrays, Mat* _planes, int _narrays) +: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0) +{ + init(_arrays, _planes, 0, _narrays); +} + +NAryMatIterator::NAryMatIterator(const Mat** _arrays, uchar** _ptrs, int _narrays) + : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0) +{ + init(_arrays, 0, _ptrs, _narrays); +} + +void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, uchar** _ptrs, int _narrays) +{ + CV_Assert( _arrays && (_ptrs || _planes) ); + int i, j, d1=0, i0 = -1, d = -1; + + arrays = _arrays; + ptrs = _ptrs; + planes = _planes; + narrays = _narrays; + nplanes = 0; + size = 0; + + if( narrays < 0 ) + { + for( i = 0; _arrays[i] != 0; i++ ) + ; + narrays = i; + CV_Assert(narrays <= 1000); + } + + iterdepth = 0; + + for( i = 0; i < narrays; i++ ) + { + CV_Assert(arrays[i] != 0); + const Mat& A = *arrays[i]; + if( ptrs ) + ptrs[i] = A.data; + + if( !A.data ) + continue; + + if( i0 < 0 ) + { + i0 = i; + d = A.dims; + + // find the first dimensionality which is different from 1; + // in any of the arrays the first "d1" step do not affect the continuity + for( d1 = 0; d1 < d; d1++ ) + if( A.size[d1] > 1 ) + break; + } + else + CV_Assert( A.size == arrays[i0]->size ); + + if( !A.isContinuous() ) + { + CV_Assert( A.step[d-1] == A.elemSize() ); + for( j = d-1; j > d1; j-- ) + if( A.step[j]*A.size[j] < A.step[j-1] ) + break; + iterdepth = std::max(iterdepth, j); + } + } + + if( i0 >= 0 ) + { + size = arrays[i0]->size[d-1]; + for( j = d-1; j > iterdepth; j-- ) + { + int64 total1 = (int64)size*arrays[i0]->size[j-1]; + if( total1 != (int)total1 ) + break; + size = (int)total1; + } + + iterdepth = j; + if( iterdepth == d1 ) + iterdepth = 0; + + nplanes = 1; + for( j = iterdepth-1; j >= 0; j-- ) + nplanes *= arrays[i0]->size[j]; + } + else + iterdepth = 0; + + idx = 0; + + if( !planes ) + return; + + for( i = 0; i < narrays; i++ ) + { + CV_Assert(arrays[i] != 0); + const Mat& A = *arrays[i]; + + if( !A.data ) + { + planes[i] = Mat(); + continue; + } + + planes[i] = Mat(1, (int)size, A.type(), A.data); + } +} + + +NAryMatIterator& NAryMatIterator::operator ++() +{ + if( idx >= nplanes-1 ) + return *this; + ++idx; + + if( iterdepth == 1 ) + { + if( ptrs ) + { + for( int i = 0; i < narrays; i++ ) + { + if( !ptrs[i] ) + continue; + ptrs[i] = arrays[i]->data + arrays[i]->step[0]*idx; + } + } + if( planes ) + { + for( int i = 0; i < narrays; i++ ) + { + if( !planes[i].data ) + continue; + planes[i].data = arrays[i]->data + arrays[i]->step[0]*idx; + } + } + } + else + { + for( int i = 0; i < narrays; i++ ) + { + const Mat& A = *arrays[i]; + if( !A.data ) + continue; + int _idx = (int)idx; + uchar* data = A.data; + for( int j = iterdepth-1; j >= 0 && _idx > 0; j-- ) + { + int szi = A.size[j], t = _idx/szi; + data += (_idx - t * szi)*A.step[j]; + _idx = t; + } + if( ptrs ) + ptrs[i] = data; + if( planes ) + planes[i].data = data; + } + } + + return *this; +} + +NAryMatIterator NAryMatIterator::operator ++(int) +{ + NAryMatIterator it = *this; + ++*this; + return it; +} + +/////////////////////////////////////////////////////////////////////////// +// MatConstIterator // +/////////////////////////////////////////////////////////////////////////// + +Point MatConstIterator::pos() const +{ + if( !m ) + return Point(); + CV_DbgAssert(m->dims <= 2); + + ptrdiff_t ofs = ptr - m->data; + int y = (int)(ofs/m->step[0]); + return Point((int)((ofs - y*m->step[0])/elemSize), y); +} + +void MatConstIterator::pos(int* _idx) const +{ + CV_Assert(m != 0 && _idx); + ptrdiff_t ofs = ptr - m->data; + for( int i = 0; i < m->dims; i++ ) + { + size_t s = m->step[i], v = ofs/s; + ofs -= v*s; + _idx[i] = (int)v; + } +} + +ptrdiff_t MatConstIterator::lpos() const +{ + if(!m) + return 0; + if( m->isContinuous() ) + return (ptr - sliceStart)/elemSize; + ptrdiff_t ofs = ptr - m->data; + int i, d = m->dims; + if( d == 2 ) + { + ptrdiff_t y = ofs/m->step[0]; + return y*m->cols + (ofs - y*m->step[0])/elemSize; + } + ptrdiff_t result = 0; + for( i = 0; i < d; i++ ) + { + size_t s = m->step[i], v = ofs/s; + ofs -= v*s; + result = result*m->size[i] + v; + } + return result; +} + +void MatConstIterator::seek(ptrdiff_t ofs, bool relative) +{ + if( m->isContinuous() ) + { + ptr = (relative ? ptr : sliceStart) + ofs*elemSize; + if( ptr < sliceStart ) + ptr = sliceStart; + else if( ptr > sliceEnd ) + ptr = sliceEnd; + return; + } + + int d = m->dims; + if( d == 2 ) + { + ptrdiff_t ofs0, y; + if( relative ) + { + ofs0 = ptr - m->data; + y = ofs0/m->step[0]; + ofs += y*m->cols + (ofs0 - y*m->step[0])/elemSize; + } + y = ofs/m->cols; + int y1 = std::min(std::max((int)y, 0), m->rows-1); + sliceStart = m->data + y1*m->step[0]; + sliceEnd = sliceStart + m->cols*elemSize; + ptr = y < 0 ? sliceStart : y >= m->rows ? sliceEnd : + sliceStart + (ofs - y*m->cols)*elemSize; + return; + } + + if( relative ) + ofs += lpos(); + + if( ofs < 0 ) + ofs = 0; + + int szi = m->size[d-1]; + ptrdiff_t t = ofs/szi; + int v = (int)(ofs - t*szi); + ofs = t; + ptr = m->data + v*elemSize; + sliceStart = m->data; + + for( int i = d-2; i >= 0; i-- ) + { + szi = m->size[i]; + t = ofs/szi; + v = (int)(ofs - t*szi); + ofs = t; + sliceStart += v*m->step[i]; + } + + sliceEnd = sliceStart + m->size[d-1]*elemSize; + if( ofs > 0 ) + ptr = sliceEnd; + else + ptr = sliceStart + (ptr - m->data); +} + +void MatConstIterator::seek(const int* _idx, bool relative) +{ + int i, d = m->dims; + ptrdiff_t ofs = 0; + if( !_idx ) + ; + else if( d == 2 ) + ofs = _idx[0]*m->size[1] + _idx[1]; + else + { + for( i = 0; i < d; i++ ) + ofs = ofs*m->size[i] + _idx[i]; + } + seek(ofs, relative); +} + +ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a) +{ + if( a.m != b.m ) + return INT_MAX; + if( a.sliceEnd == b.sliceEnd ) + return (b.ptr - a.ptr)/b.elemSize; + + return b.lpos() - a.lpos(); +} + +//////////////////////////////// SparseMat //////////////////////////////// + +template void +convertData_(const void* _from, void* _to, int cn) +{ + const T1* from = (const T1*)_from; + T2* to = (T2*)_to; + if( cn == 1 ) + *to = saturate_cast(*from); + else + for( int i = 0; i < cn; i++ ) + to[i] = saturate_cast(from[i]); +} + +template void +convertScaleData_(const void* _from, void* _to, int cn, double alpha, double beta) +{ + const T1* from = (const T1*)_from; + T2* to = (T2*)_to; + if( cn == 1 ) + *to = saturate_cast(*from*alpha + beta); + else + for( int i = 0; i < cn; i++ ) + to[i] = saturate_cast(from[i]*alpha + beta); +} + +ConvertData getConvertElem(int fromType, int toType) +{ + static ConvertData tab[][8] = + {{ convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { convertData_, convertData_, + convertData_, convertData_, + convertData_, convertData_, + convertData_, 0 }, + + { 0, 0, 0, 0, 0, 0, 0, 0 }}; + + ConvertData func = tab[CV_MAT_DEPTH(fromType)][CV_MAT_DEPTH(toType)]; + CV_Assert( func != 0 ); + return func; +} + +ConvertScaleData getConvertScaleElem(int fromType, int toType) +{ + static ConvertScaleData tab[][8] = + {{ convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, convertScaleData_, + convertScaleData_, 0 }, + + { 0, 0, 0, 0, 0, 0, 0, 0 }}; + + ConvertScaleData func = tab[CV_MAT_DEPTH(fromType)][CV_MAT_DEPTH(toType)]; + CV_Assert( func != 0 ); + return func; +} + +enum { HASH_SIZE0 = 8 }; + +static inline void copyElem(const uchar* from, uchar* to, size_t elemSize) +{ + size_t i; + for( i = 0; i + sizeof(int) <= elemSize; i += sizeof(int) ) + *(int*)(to + i) = *(const int*)(from + i); + for( ; i < elemSize; i++ ) + to[i] = from[i]; +} + +static inline bool isZeroElem(const uchar* data, size_t elemSize) +{ + size_t i; + for( i = 0; i + sizeof(int) <= elemSize; i += sizeof(int) ) + if( *(int*)(data + i) != 0 ) + return false; + for( ; i < elemSize; i++ ) + if( data[i] != 0 ) + return false; + return true; +} + +SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type ) +{ + refcount = 1; + + dims = _dims; + valueOffset = (int)alignSize(sizeof(SparseMat::Node) + + sizeof(int)*std::max(dims - CV_MAX_DIM, 0), CV_ELEM_SIZE1(_type)); + nodeSize = alignSize(valueOffset + + CV_ELEM_SIZE(_type), (int)sizeof(size_t)); + + int i; + for( i = 0; i < dims; i++ ) + size[i] = _sizes[i]; + for( ; i < CV_MAX_DIM; i++ ) + size[i] = 0; + clear(); +} + +void SparseMat::Hdr::clear() +{ + hashtab.clear(); + hashtab.resize(HASH_SIZE0); + pool.clear(); + pool.resize(nodeSize); + nodeCount = freeList = 0; +} + + +SparseMat::SparseMat(const Mat& m) +: flags(MAGIC_VAL), hdr(0) +{ + create( m.dims, m.size, m.type() ); + + int i, idx[CV_MAX_DIM] = {0}, d = m.dims, lastSize = m.size[d - 1]; + size_t esz = m.elemSize(); + uchar* dptr = m.data; + + for(;;) + { + for( i = 0; i < lastSize; i++, dptr += esz ) + { + if( isZeroElem(dptr, esz) ) + continue; + idx[d-1] = i; + uchar* to = newNode(idx, hash(idx)); + copyElem( dptr, to, esz ); + } + + for( i = d - 2; i >= 0; i-- ) + { + dptr += m.step[i] - m.size[i+1]*m.step[i+1]; + if( ++idx[i] < m.size[i] ) + break; + idx[i] = 0; + } + if( i < 0 ) + break; + } +} + +SparseMat::SparseMat(const CvSparseMat* m) +: flags(MAGIC_VAL), hdr(0) +{ + CV_Assert(m); + create( m->dims, &m->size[0], m->type ); + + CvSparseMatIterator it; + CvSparseNode* n = cvInitSparseMatIterator(m, &it); + size_t esz = elemSize(); + + for( ; n != 0; n = cvGetNextSparseNode(&it) ) + { + const int* idx = CV_NODE_IDX(m, n); + uchar* to = newNode(idx, hash(idx)); + copyElem((const uchar*)CV_NODE_VAL(m, n), to, esz); + } +} + +void SparseMat::create(int d, const int* _sizes, int _type) +{ + int i; + CV_Assert( _sizes && 0 < d && d <= CV_MAX_DIM ); + for( i = 0; i < d; i++ ) + CV_Assert( _sizes[i] > 0 ); + _type = CV_MAT_TYPE(_type); + if( hdr && _type == type() && hdr->dims == d && hdr->refcount == 1 ) + { + for( i = 0; i < d; i++ ) + if( _sizes[i] != hdr->size[i] ) + break; + if( i == d ) + { + clear(); + return; + } + } + release(); + flags = MAGIC_VAL | _type; + hdr = new Hdr(d, _sizes, _type); +} + +void SparseMat::copyTo( SparseMat& m ) const +{ + if( hdr == m.hdr ) + return; + if( !hdr ) + { + m.release(); + return; + } + m.create( hdr->dims, hdr->size, type() ); + SparseMatConstIterator from = begin(); + size_t i, N = nzcount(), esz = elemSize(); + + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = m.newNode(n->idx, n->hashval); + copyElem( from.ptr, to, esz ); + } +} + +void SparseMat::copyTo( Mat& m ) const +{ + CV_Assert( hdr ); + m.create( dims(), hdr->size, type() ); + m = Scalar(0); + + SparseMatConstIterator from = begin(); + size_t i, N = nzcount(), esz = elemSize(); + + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + copyElem( from.ptr, m.ptr(n->idx), esz); + } +} + + +void SparseMat::convertTo( SparseMat& m, int rtype, double alpha ) const +{ + int cn = channels(); + if( rtype < 0 ) + rtype = type(); + rtype = CV_MAKETYPE(rtype, cn); + if( hdr == m.hdr && rtype != type() ) + { + SparseMat temp; + convertTo(temp, rtype, alpha); + m = temp; + return; + } + + CV_Assert(hdr != 0); + if( hdr != m.hdr ) + m.create( hdr->dims, hdr->size, rtype ); + + SparseMatConstIterator from = begin(); + size_t i, N = nzcount(); + + if( alpha == 1 ) + { + ConvertData cvtfunc = getConvertElem(type(), rtype); + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = hdr == m.hdr ? from.ptr : m.newNode(n->idx, n->hashval); + cvtfunc( from.ptr, to, cn ); + } + } + else + { + ConvertScaleData cvtfunc = getConvertScaleElem(type(), rtype); + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = hdr == m.hdr ? from.ptr : m.newNode(n->idx, n->hashval); + cvtfunc( from.ptr, to, cn, alpha, 0 ); + } + } +} + + +void SparseMat::convertTo( Mat& m, int rtype, double alpha, double beta ) const +{ + int cn = channels(); + if( rtype < 0 ) + rtype = type(); + rtype = CV_MAKETYPE(rtype, cn); + + CV_Assert( hdr ); + m.create( dims(), hdr->size, rtype ); + m = Scalar(beta); + + SparseMatConstIterator from = begin(); + size_t i, N = nzcount(); + + if( alpha == 1 && beta == 0 ) + { + ConvertData cvtfunc = getConvertElem(type(), rtype); + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = m.ptr(n->idx); + cvtfunc( from.ptr, to, cn ); + } + } + else + { + ConvertScaleData cvtfunc = getConvertScaleElem(type(), rtype); + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = m.ptr(n->idx); + cvtfunc( from.ptr, to, cn, alpha, beta ); + } + } +} + +void SparseMat::clear() +{ + if( hdr ) + hdr->clear(); +} + +SparseMat::operator CvSparseMat*() const +{ + if( !hdr ) + return 0; + CvSparseMat* m = cvCreateSparseMat(hdr->dims, hdr->size, type()); + + SparseMatConstIterator from = begin(); + size_t i, N = nzcount(), esz = elemSize(); + + for( i = 0; i < N; i++, ++from ) + { + const Node* n = from.node(); + uchar* to = cvPtrND(m, n->idx, 0, -2, 0); + copyElem(from.ptr, to, esz); + } + return m; +} + +uchar* SparseMat::ptr(int i0, bool createMissing, size_t* hashval) +{ + CV_Assert( hdr && hdr->dims == 1 ); + size_t h = hashval ? *hashval : hash(i0); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx]; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h && elem->idx[0] == i0 ) + return &value(elem); + nidx = elem->next; + } + + if( createMissing ) + { + int idx[] = { i0 }; + return newNode( idx, h ); + } + return 0; +} + +uchar* SparseMat::ptr(int i0, int i1, bool createMissing, size_t* hashval) +{ + CV_Assert( hdr && hdr->dims == 2 ); + size_t h = hashval ? *hashval : hash(i0, i1); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx]; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h && elem->idx[0] == i0 && elem->idx[1] == i1 ) + return &value(elem); + nidx = elem->next; + } + + if( createMissing ) + { + int idx[] = { i0, i1 }; + return newNode( idx, h ); + } + return 0; +} + +uchar* SparseMat::ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval) +{ + CV_Assert( hdr && hdr->dims == 3 ); + size_t h = hashval ? *hashval : hash(i0, i1, i2); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx]; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h && elem->idx[0] == i0 && + elem->idx[1] == i1 && elem->idx[2] == i2 ) + return &value(elem); + nidx = elem->next; + } + + if( createMissing ) + { + int idx[] = { i0, i1, i2 }; + return newNode( idx, h ); + } + return 0; +} + +uchar* SparseMat::ptr(const int* idx, bool createMissing, size_t* hashval) +{ + CV_Assert( hdr ); + int i, d = hdr->dims; + size_t h = hashval ? *hashval : hash(idx); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx]; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h ) + { + for( i = 0; i < d; i++ ) + if( elem->idx[i] != idx[i] ) + break; + if( i == d ) + return &value(elem); + } + nidx = elem->next; + } + + return createMissing ? newNode(idx, h) : 0; +} + +void SparseMat::erase(int i0, int i1, size_t* hashval) +{ + CV_Assert( hdr && hdr->dims == 2 ); + size_t h = hashval ? *hashval : hash(i0, i1); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h && elem->idx[0] == i0 && elem->idx[1] == i1 ) + break; + previdx = nidx; + nidx = elem->next; + } + + if( nidx ) + removeNode(hidx, nidx, previdx); +} + +void SparseMat::erase(int i0, int i1, int i2, size_t* hashval) +{ + CV_Assert( hdr && hdr->dims == 3 ); + size_t h = hashval ? *hashval : hash(i0, i1, i2); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h && elem->idx[0] == i0 && + elem->idx[1] == i1 && elem->idx[2] == i2 ) + break; + previdx = nidx; + nidx = elem->next; + } + + if( nidx ) + removeNode(hidx, nidx, previdx); +} + +void SparseMat::erase(const int* idx, size_t* hashval) +{ + CV_Assert( hdr ); + int i, d = hdr->dims; + size_t h = hashval ? *hashval : hash(idx); + size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0; + uchar* pool = &hdr->pool[0]; + while( nidx != 0 ) + { + Node* elem = (Node*)(pool + nidx); + if( elem->hashval == h ) + { + for( i = 0; i < d; i++ ) + if( elem->idx[i] != idx[i] ) + break; + if( i == d ) + break; + } + previdx = nidx; + nidx = elem->next; + } + + if( nidx ) + removeNode(hidx, nidx, previdx); +} + +void SparseMat::resizeHashTab(size_t newsize) +{ + newsize = std::max(newsize, (size_t)8); + if((newsize & (newsize-1)) != 0) + newsize = (size_t)1 << cvCeil(std::log((double)newsize)/CV_LOG2); + + size_t i, hsize = hdr->hashtab.size(); + vector _newh(newsize); + size_t* newh = &_newh[0]; + for( i = 0; i < newsize; i++ ) + newh[i] = 0; + uchar* pool = &hdr->pool[0]; + for( i = 0; i < hsize; i++ ) + { + size_t nidx = hdr->hashtab[i]; + while( nidx ) + { + Node* elem = (Node*)(pool + nidx); + size_t next = elem->next; + size_t newhidx = elem->hashval & (newsize - 1); + elem->next = newh[newhidx]; + newh[newhidx] = nidx; + nidx = next; + } + } + hdr->hashtab = _newh; +} + +uchar* SparseMat::newNode(const int* idx, size_t hashval) +{ + const int HASH_MAX_FILL_FACTOR=3; + assert(hdr); + size_t hsize = hdr->hashtab.size(); + if( ++hdr->nodeCount > hsize*HASH_MAX_FILL_FACTOR ) + { + resizeHashTab(std::max(hsize*2, (size_t)8)); + hsize = hdr->hashtab.size(); + } + + if( !hdr->freeList ) + { + size_t i, nsz = hdr->nodeSize, psize = hdr->pool.size(), + newpsize = std::max(psize*2, 8*nsz); + hdr->pool.resize(newpsize); + uchar* pool = &hdr->pool[0]; + hdr->freeList = std::max(psize, nsz); + for( i = hdr->freeList; i < newpsize - nsz; i += nsz ) + ((Node*)(pool + i))->next = i + nsz; + ((Node*)(pool + i))->next = 0; + } + size_t nidx = hdr->freeList; + Node* elem = (Node*)&hdr->pool[nidx]; + hdr->freeList = elem->next; + elem->hashval = hashval; + size_t hidx = hashval & (hsize - 1); + elem->next = hdr->hashtab[hidx]; + hdr->hashtab[hidx] = nidx; + + int i, d = hdr->dims; + for( i = 0; i < d; i++ ) + elem->idx[i] = idx[i]; + size_t esz = elemSize(); + uchar* p = &value(elem); + if( esz == sizeof(float) ) + *((float*)p) = 0.f; + else if( esz == sizeof(double) ) + *((double*)p) = 0.; + else + memset(p, 0, esz); + + return p; +} + + +void SparseMat::removeNode(size_t hidx, size_t nidx, size_t previdx) +{ + Node* n = node(nidx); + if( previdx ) + { + Node* prev = node(previdx); + prev->next = n->next; + } + else + hdr->hashtab[hidx] = n->next; + n->next = hdr->freeList; + hdr->freeList = nidx; + --hdr->nodeCount; +} + + +SparseMatConstIterator::SparseMatConstIterator(const SparseMat* _m) +: m((SparseMat*)_m), hashidx(0), ptr(0) +{ + if(!_m || !_m->hdr) + return; + SparseMat::Hdr& hdr = *m->hdr; + const vector& htab = hdr.hashtab; + size_t i, hsize = htab.size(); + for( i = 0; i < hsize; i++ ) + { + size_t nidx = htab[i]; + if( nidx ) + { + hashidx = i; + ptr = &hdr.pool[nidx] + hdr.valueOffset; + return; + } + } +} + +SparseMatConstIterator& SparseMatConstIterator::operator ++() +{ + if( !ptr || !m || !m->hdr ) + return *this; + SparseMat::Hdr& hdr = *m->hdr; + size_t next = ((const SparseMat::Node*)(ptr - hdr.valueOffset))->next; + if( next ) + { + ptr = &hdr.pool[next] + hdr.valueOffset; + return *this; + } + size_t i = hashidx + 1, sz = hdr.hashtab.size(); + for( ; i < sz; i++ ) + { + size_t nidx = hdr.hashtab[i]; + if( nidx ) + { + hashidx = i; + ptr = &hdr.pool[nidx] + hdr.valueOffset; + return *this; + } + } + hashidx = sz; + ptr = 0; + return *this; +} + + +double norm( const SparseMat& src, int normType ) +{ + SparseMatConstIterator it = src.begin(); + + size_t i, N = src.nzcount(); + normType &= NORM_TYPE_MASK; + int type = src.type(); + double result = 0; + + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 ); + + if( type == CV_32F ) + { + if( normType == NORM_INF ) + for( i = 0; i < N; i++, ++it ) + result = std::max(result, std::abs((double)*(const float*)it.ptr)); + else if( normType == NORM_L1 ) + for( i = 0; i < N; i++, ++it ) + result += std::abs(*(const float*)it.ptr); + else + for( i = 0; i < N; i++, ++it ) + { + double v = *(const float*)it.ptr; + result += v*v; + } + } + else if( type == CV_64F ) + { + if( normType == NORM_INF ) + for( i = 0; i < N; i++, ++it ) + result = std::max(result, std::abs(*(const double*)it.ptr)); + else if( normType == NORM_L1 ) + for( i = 0; i < N; i++, ++it ) + result += std::abs(*(const double*)it.ptr); + else + for( i = 0; i < N; i++, ++it ) + { + double v = *(const double*)it.ptr; + result += v*v; + } + } + else + CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + + if( normType == NORM_L2 ) + result = std::sqrt(result); + return result; +} + +void minMaxLoc( const SparseMat& src, double* _minval, double* _maxval, int* _minidx, int* _maxidx ) +{ + SparseMatConstIterator it = src.begin(); + size_t i, N = src.nzcount(), d = src.hdr ? src.hdr->dims : 0; + int type = src.type(); + const int *minidx = 0, *maxidx = 0; + + if( type == CV_32F ) + { + float minval = FLT_MAX, maxval = -FLT_MAX; + for( i = 0; i < N; i++, ++it ) + { + float v = *(const float*)it.ptr; + if( v < minval ) + { + minval = v; + minidx = it.node()->idx; + } + if( v > maxval ) + { + maxval = v; + maxidx = it.node()->idx; + } + } + if( _minval ) + *_minval = minval; + if( _maxval ) + *_maxval = maxval; + } + else if( type == CV_64F ) + { + double minval = DBL_MAX, maxval = -DBL_MAX; + for( i = 0; i < N; i++, ++it ) + { + double v = *(const double*)it.ptr; + if( v < minval ) + { + minval = v; + minidx = it.node()->idx; + } + if( v > maxval ) + { + maxval = v; + maxidx = it.node()->idx; + } + } + if( _minval ) + *_minval = minval; + if( _maxval ) + *_maxval = maxval; + } + else + CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + + if( _minidx ) + for( i = 0; i < d; i++ ) + _minidx[i] = minidx[i]; + if( _maxidx ) + for( i = 0; i < d; i++ ) + _maxidx[i] = maxidx[i]; +} + + +void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type ) +{ + double scale = 1; + if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C ) + { + scale = norm( src, norm_type ); + scale = scale > DBL_EPSILON ? a/scale : 0.; + } + else + CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + + src.convertTo( dst, -1, scale ); +} + +////////////////////// RotatedRect ////////////////////// + +void RotatedRect::points(Point2f pt[]) const +{ + double _angle = angle*CV_PI/180.; + float b = (float)cos(_angle)*0.5f; + float a = (float)sin(_angle)*0.5f; + + pt[0].x = center.x - a*size.height - b*size.width; + pt[0].y = center.y + b*size.height - a*size.width; + pt[1].x = center.x + a*size.height - b*size.width; + pt[1].y = center.y - b*size.height - a*size.width; + pt[2].x = 2*center.x - pt[0].x; + pt[2].y = 2*center.y - pt[0].y; + pt[3].x = 2*center.x - pt[1].x; + pt[3].y = 2*center.y - pt[1].y; +} + +Rect RotatedRect::boundingRect() const +{ + Point2f pt[4]; + points(pt); + Rect r(cvFloor(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + cvFloor(min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)), + cvCeil(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + cvCeil(max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y))); + r.width -= r.x - 1; + r.height -= r.y - 1; + return r; +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/opengl_interop.cpp diffimg-2.0.0/3rdparty/opencv/core/src/opengl_interop.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/opengl_interop.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/opengl_interop.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1580 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "opencv2/core/opengl_interop.hpp" +#include "opencv2/core/gpumat.hpp" + +#ifdef HAVE_OPENGL + #include "gl_core_3_1.hpp" + + #ifdef HAVE_CUDA + #include + #include + #endif +#endif + +using namespace std; +using namespace cv; +using namespace cv::gpu; + +namespace +{ + #ifndef HAVE_OPENGL + void throw_nogl() { CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); } + #else + void throw_nogl() { CV_Error(CV_OpenGlApiCallError, "OpenGL context doesn't exist"); } + + #ifndef HAVE_CUDA + void throw_nocuda() { CV_Error(CV_GpuNotSupported, "The library is compiled without GPU support"); } + #else + void throw_nocuda() { CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform"); } + + #if defined(__GNUC__) + #define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, __func__) + #else /* defined(__CUDACC__) || defined(__MSVC__) */ + #define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__) + #endif + + void ___cudaSafeCall(cudaError_t err, const char* file, const int line, const char* func = "") + { + if (cudaSuccess != err) + cv::gpu::error(cudaGetErrorString(err), file, line, func); + } + #endif + #endif +} + +bool cv::ogl::checkError(const char* file, const int line, const char* func) +{ +#ifndef HAVE_OPENGL + (void) file; + (void) line; + (void) func; + return true; +#else + GLenum err = gl::GetError(); + + if (err != gl::NO_ERROR_) + { + const char* msg; + + switch (err) + { + case gl::INVALID_ENUM: + msg = "An unacceptable value is specified for an enumerated argument"; + break; + + case gl::INVALID_VALUE: + msg = "A numeric argument is out of range"; + break; + + case gl::INVALID_OPERATION: + msg = "The specified operation is not allowed in the current state"; + break; + + case gl::OUT_OF_MEMORY: + msg = "There is not enough memory left to execute the command"; + break; + + default: + msg = "Unknown error"; + }; + + cvError(CV_OpenGlApiCallError, func, msg, file, line); + + return false; + } + + return true; +#endif +} + +#ifdef HAVE_OPENGL +namespace +{ + const GLenum gl_types[] = { gl::UNSIGNED_BYTE, gl::BYTE, gl::UNSIGNED_SHORT, gl::SHORT, gl::INT, gl::FLOAT, gl::DOUBLE }; +} +#endif + +//////////////////////////////////////////////////////////////////////// +// setGlDevice + +void cv::gpu::setGlDevice(int device) +{ +#ifndef HAVE_OPENGL + (void) device; + throw_nogl(); +#else + #if !defined(HAVE_CUDA) || defined(CUDA_DISABLER) + (void) device; + throw_nocuda(); + #else + cudaSafeCall( cudaGLSetGLDevice(device) ); + #endif +#endif +} + +//////////////////////////////////////////////////////////////////////// +// CudaResource + +#if defined(HAVE_OPENGL) && defined(HAVE_CUDA) && !defined(CUDA_DISABLER) + +namespace +{ + class CudaResource + { + public: + CudaResource(); + ~CudaResource(); + + void registerBuffer(GLuint buffer); + void release(); + + void copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream = 0); + void copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream = 0); + + void* map(cudaStream_t stream = 0); + void unmap(cudaStream_t stream = 0); + + private: + cudaGraphicsResource_t resource_; + GLuint buffer_; + + class GraphicsMapHolder; + }; + + CudaResource::CudaResource() : resource_(0), buffer_(0) + { + } + + CudaResource::~CudaResource() + { + release(); + } + + void CudaResource::registerBuffer(GLuint buffer) + { + CV_DbgAssert( buffer != 0 ); + + if (buffer_ == buffer) + return; + + cudaGraphicsResource_t resource; + cudaSafeCall( cudaGraphicsGLRegisterBuffer(&resource, buffer, cudaGraphicsMapFlagsNone) ); + + release(); + + resource_ = resource; + buffer_ = buffer; + } + + void CudaResource::release() + { + if (resource_) + cudaGraphicsUnregisterResource(resource_); + + resource_ = 0; + buffer_ = 0; + } + + class CudaResource::GraphicsMapHolder + { + public: + GraphicsMapHolder(cudaGraphicsResource_t* resource, cudaStream_t stream); + ~GraphicsMapHolder(); + + void reset(); + + private: + cudaGraphicsResource_t* resource_; + cudaStream_t stream_; + }; + + CudaResource::GraphicsMapHolder::GraphicsMapHolder(cudaGraphicsResource_t* resource, cudaStream_t stream) : resource_(resource), stream_(stream) + { + if (resource_) + cudaSafeCall( cudaGraphicsMapResources(1, resource_, stream_) ); + } + + CudaResource::GraphicsMapHolder::~GraphicsMapHolder() + { + if (resource_) + cudaGraphicsUnmapResources(1, resource_, stream_); + } + + void CudaResource::GraphicsMapHolder::reset() + { + resource_ = 0; + } + + void CudaResource::copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream) + { + CV_DbgAssert( resource_ != 0 ); + + GraphicsMapHolder h(&resource_, stream); + (void) h; + + void* dst; + size_t size; + cudaSafeCall( cudaGraphicsResourceGetMappedPointer(&dst, &size, resource_) ); + + CV_DbgAssert( width * height == size ); + + if (stream == 0) + cudaSafeCall( cudaMemcpy2D(dst, width, src, spitch, width, height, cudaMemcpyDeviceToDevice) ); + else + cudaSafeCall( cudaMemcpy2DAsync(dst, width, src, spitch, width, height, cudaMemcpyDeviceToDevice, stream) ); + } + + void CudaResource::copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream) + { + CV_DbgAssert( resource_ != 0 ); + + GraphicsMapHolder h(&resource_, stream); + (void) h; + + void* src; + size_t size; + cudaSafeCall( cudaGraphicsResourceGetMappedPointer(&src, &size, resource_) ); + + CV_DbgAssert( width * height == size ); + + if (stream == 0) + cudaSafeCall( cudaMemcpy2D(dst, dpitch, src, width, width, height, cudaMemcpyDeviceToDevice) ); + else + cudaSafeCall( cudaMemcpy2DAsync(dst, dpitch, src, width, width, height, cudaMemcpyDeviceToDevice, stream) ); + } + + void* CudaResource::map(cudaStream_t stream) + { + CV_DbgAssert( resource_ != 0 ); + + GraphicsMapHolder h(&resource_, stream); + + void* ptr; + size_t size; + cudaSafeCall( cudaGraphicsResourceGetMappedPointer(&ptr, &size, resource_) ); + + h.reset(); + + return ptr; + } + + void CudaResource::unmap(cudaStream_t stream) + { + CV_Assert( resource_ != 0 ); + + cudaGraphicsUnmapResources(1, &resource_, stream); + } +} + +#endif + +//////////////////////////////////////////////////////////////////////// +// ogl::Buffer + +#ifndef HAVE_OPENGL + +class cv::ogl::Buffer::Impl +{ +}; + +#else + +class cv::ogl::Buffer::Impl +{ +public: + static const Ptr& empty(); + + Impl(GLuint bufId, bool autoRelease); + Impl(GLsizeiptr size, const GLvoid* data, GLenum target, bool autoRelease); + ~Impl(); + + void bind(GLenum target) const; + + void copyFrom(GLuint srcBuf, GLsizeiptr size); + + void copyFrom(GLsizeiptr size, const GLvoid* data); + void copyTo(GLsizeiptr size, GLvoid* data) const; + + void* mapHost(GLenum access); + void unmapHost(); + +#ifdef HAVE_CUDA + void copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream = 0); + void copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream = 0) const; + + void* mapDevice(cudaStream_t stream = 0); + void unmapDevice(cudaStream_t stream = 0); +#endif + + void setAutoRelease(bool flag) { autoRelease_ = flag; } + + GLuint bufId() const { return bufId_; } + +private: + Impl(); + + GLuint bufId_; + bool autoRelease_; + +#ifdef HAVE_CUDA + mutable CudaResource cudaResource_; +#endif +}; + +const Ptr& cv::ogl::Buffer::Impl::empty() +{ + static Ptr p(new Impl); + return p; +} + +cv::ogl::Buffer::Impl::Impl() : bufId_(0), autoRelease_(true) +{ +} + +cv::ogl::Buffer::Impl::Impl(GLuint abufId, bool autoRelease) : bufId_(abufId), autoRelease_(autoRelease) +{ +} + +cv::ogl::Buffer::Impl::Impl(GLsizeiptr size, const GLvoid* data, GLenum target, bool autoRelease) : bufId_(0), autoRelease_(autoRelease) +{ + gl::GenBuffers(1, &bufId_); + CV_CheckGlError(); + + CV_Assert( bufId_ != 0 ); + + gl::BindBuffer(target, bufId_); + CV_CheckGlError(); + + gl::BufferData(target, size, data, gl::DYNAMIC_DRAW); + CV_CheckGlError(); + + gl::BindBuffer(target, 0); + CV_CheckGlError(); +} + +cv::ogl::Buffer::Impl::~Impl() +{ + if (autoRelease_ && bufId_) + gl::DeleteBuffers(1, &bufId_); +} + +void cv::ogl::Buffer::Impl::bind(GLenum target) const +{ + gl::BindBuffer(target, bufId_); + CV_CheckGlError(); +} + +void cv::ogl::Buffer::Impl::copyFrom(GLuint srcBuf, GLsizeiptr size) +{ + gl::BindBuffer(gl::COPY_WRITE_BUFFER, bufId_); + CV_CheckGlError(); + + gl::BindBuffer(gl::COPY_READ_BUFFER, srcBuf); + CV_CheckGlError(); + + gl::CopyBufferSubData(gl::COPY_READ_BUFFER, gl::COPY_WRITE_BUFFER, 0, 0, size); + CV_CheckGlError(); +} + +void cv::ogl::Buffer::Impl::copyFrom(GLsizeiptr size, const GLvoid* data) +{ + gl::BindBuffer(gl::COPY_WRITE_BUFFER, bufId_); + CV_CheckGlError(); + + gl::BufferSubData(gl::COPY_WRITE_BUFFER, 0, size, data); + CV_CheckGlError(); +} + +void cv::ogl::Buffer::Impl::copyTo(GLsizeiptr size, GLvoid* data) const +{ + gl::BindBuffer(gl::COPY_READ_BUFFER, bufId_); + CV_CheckGlError(); + + gl::GetBufferSubData(gl::COPY_READ_BUFFER, 0, size, data); + CV_CheckGlError(); +} + +void* cv::ogl::Buffer::Impl::mapHost(GLenum access) +{ + gl::BindBuffer(gl::COPY_READ_BUFFER, bufId_); + CV_CheckGlError(); + + GLvoid* data = gl::MapBuffer(gl::COPY_READ_BUFFER, access); + CV_CheckGlError(); + + return data; +} + +void cv::ogl::Buffer::Impl::unmapHost() +{ + gl::UnmapBuffer(gl::COPY_READ_BUFFER); +} + +#ifdef HAVE_CUDA + void cv::ogl::Buffer::Impl::copyFrom(const void* src, size_t spitch, size_t width, size_t height, cudaStream_t stream) + { + cudaResource_.registerBuffer(bufId_); + cudaResource_.copyFrom(src, spitch, width, height, stream); + } + + void cv::ogl::Buffer::Impl::copyTo(void* dst, size_t dpitch, size_t width, size_t height, cudaStream_t stream) const + { + cudaResource_.registerBuffer(bufId_); + cudaResource_.copyTo(dst, dpitch, width, height, stream); + } + + void* cv::ogl::Buffer::Impl::mapDevice(cudaStream_t stream) + { + cudaResource_.registerBuffer(bufId_); + return cudaResource_.map(stream); + } + + void cv::ogl::Buffer::Impl::unmapDevice(cudaStream_t stream) + { + cudaResource_.unmap(stream); + } +#endif + +#endif // HAVE_OPENGL + +cv::ogl::Buffer::Buffer() : rows_(0), cols_(0), type_(0) +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + impl_ = Impl::empty(); +#endif +} + +cv::ogl::Buffer::Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ +#ifndef HAVE_OPENGL + (void) arows; + (void) acols; + (void) atype; + (void) abufId; + (void) autoRelease; + throw_nogl(); +#else + impl_ = new Impl(abufId, autoRelease); + rows_ = arows; + cols_ = acols; + type_ = atype; +#endif +} + +cv::ogl::Buffer::Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ +#ifndef HAVE_OPENGL + (void) asize; + (void) atype; + (void) abufId; + (void) autoRelease; + throw_nogl(); +#else + impl_ = new Impl(abufId, autoRelease); + rows_ = asize.height; + cols_ = asize.width; + type_ = atype; +#endif +} + +cv::ogl::Buffer::Buffer(int arows, int acols, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(arows, acols, atype, target, autoRelease); +} + +cv::ogl::Buffer::Buffer(Size asize, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(asize, atype, target, autoRelease); +} + +cv::ogl::Buffer::Buffer(InputArray arr, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) target; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + switch (kind) + { + case _InputArray::OPENGL_BUFFER: + { + copyFrom(arr, target, autoRelease); + break; + } + + case _InputArray::OPENGL_TEXTURE: + { + copyFrom(arr, target, autoRelease); + break; + } + + case _InputArray::GPU_MAT: + { + copyFrom(arr, target, autoRelease); + break; + } + + default: + { + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + const GLsizeiptr asize = mat.rows * mat.cols * mat.elemSize(); + impl_ = new Impl(asize, mat.data, target, autoRelease); + rows_ = mat.rows; + cols_ = mat.cols; + type_ = mat.type(); + break; + } + } +#endif +} + +void cv::ogl::Buffer::create(int arows, int acols, int atype, Target target, bool autoRelease) +{ +#ifndef HAVE_OPENGL + (void) arows; + (void) acols; + (void) atype; + (void) target; + (void) autoRelease; + throw_nogl(); +#else + if (rows_ != arows || cols_ != acols || type_ != atype) + { + const GLsizeiptr asize = arows * acols * CV_ELEM_SIZE(atype); + impl_ = new Impl(asize, 0, target, autoRelease); + rows_ = arows; + cols_ = acols; + type_ = atype; + } +#endif +} + +void cv::ogl::Buffer::release() +{ +#ifdef HAVE_OPENGL + if (*impl_.refcount == 1) + impl_->setAutoRelease(true); + impl_ = Impl::empty(); + rows_ = 0; + cols_ = 0; + type_ = 0; +#endif +} + +void cv::ogl::Buffer::setAutoRelease(bool flag) +{ +#ifndef HAVE_OPENGL + (void) flag; + throw_nogl(); +#else + impl_->setAutoRelease(flag); +#endif +} + +void cv::ogl::Buffer::copyFrom(InputArray arr, Target target, bool autoRelease) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) target; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + if (kind == _InputArray::OPENGL_TEXTURE) + { + ogl::Texture2D tex = arr.getOGlTexture2D(); + tex.copyTo(*this); + setAutoRelease(autoRelease); + return; + } + + const Size asize = arr.size(); + const int atype = arr.type(); + create(asize, atype, target, autoRelease); + + switch (kind) + { + case _InputArray::OPENGL_BUFFER: + { + ogl::Buffer buf = arr.getOGlBuffer(); + impl_->copyFrom(buf.bufId(), asize.area() * CV_ELEM_SIZE(atype)); + break; + } + + case _InputArray::GPU_MAT: + { + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + GpuMat dmat = arr.getGpuMat(); + impl_->copyFrom(dmat.data, dmat.step, dmat.cols * dmat.elemSize(), dmat.rows); + #endif + + break; + } + + default: + { + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + impl_->copyFrom(asize.area() * CV_ELEM_SIZE(atype), mat.data); + } + } +#endif +} + +void cv::ogl::Buffer::copyTo(OutputArray arr, Target target, bool autoRelease) const +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) target; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + switch (kind) + { + case _InputArray::OPENGL_BUFFER: + { + arr.getOGlBufferRef().copyFrom(*this, target, autoRelease); + break; + } + + case _InputArray::OPENGL_TEXTURE: + { + arr.getOGlTexture2DRef().copyFrom(*this, autoRelease); + break; + } + + case _InputArray::GPU_MAT: + { + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + GpuMat& dmat = arr.getGpuMatRef(); + dmat.create(rows_, cols_, type_); + impl_->copyTo(dmat.data, dmat.step, dmat.cols * dmat.elemSize(), dmat.rows); + #endif + + break; + } + + default: + { + arr.create(rows_, cols_, type_); + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + impl_->copyTo(mat.rows * mat.cols * mat.elemSize(), mat.data); + } + } +#endif +} + +cv::ogl::Buffer cv::ogl::Buffer::clone(Target target, bool autoRelease) const +{ +#ifndef HAVE_OPENGL + (void) target; + (void) autoRelease; + throw_nogl(); + return cv::ogl::Buffer(); +#else + ogl::Buffer buf; + buf.copyFrom(*this, target, autoRelease); + return buf; +#endif +} + +void cv::ogl::Buffer::bind(Target target) const +{ +#ifndef HAVE_OPENGL + (void) target; + throw_nogl(); +#else + impl_->bind(target); +#endif +} + +void cv::ogl::Buffer::unbind(Target target) +{ +#ifndef HAVE_OPENGL + (void) target; + throw_nogl(); +#else + gl::BindBuffer(target, 0); + CV_CheckGlError(); +#endif +} + +Mat cv::ogl::Buffer::mapHost(Access access) +{ +#ifndef HAVE_OPENGL + (void) access; + throw_nogl(); + return Mat(); +#else + return Mat(rows_, cols_, type_, impl_->mapHost(access)); +#endif +} + +void cv::ogl::Buffer::unmapHost() +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + return impl_->unmapHost(); +#endif +} + +GpuMat cv::ogl::Buffer::mapDevice() +{ +#ifndef HAVE_OPENGL + throw_nogl(); + return GpuMat(); +#else + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + return GpuMat(); + #else + return GpuMat(rows_, cols_, type_, impl_->mapDevice()); + #endif +#endif +} + +void cv::ogl::Buffer::unmapDevice() +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + impl_->unmapDevice(); + #endif +#endif +} + +unsigned int cv::ogl::Buffer::bufId() const +{ +#ifndef HAVE_OPENGL + throw_nogl(); + return 0; +#else + return impl_->bufId(); +#endif +} + +template <> void cv::Ptr::delete_obj() +{ + if (obj) delete obj; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// ogl::Texture + +#ifndef HAVE_OPENGL + +class cv::ogl::Texture2D::Impl +{ +}; + +#else + +class cv::ogl::Texture2D::Impl +{ +public: + static const Ptr empty(); + + Impl(GLuint texId, bool autoRelease); + Impl(GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels, bool autoRelease); + ~Impl(); + + void copyFrom(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + void copyTo(GLenum format, GLenum type, GLvoid* pixels) const; + + void bind() const; + + void setAutoRelease(bool flag) { autoRelease_ = flag; } + + GLuint texId() const { return texId_; } + +private: + Impl(); + + GLuint texId_; + bool autoRelease_; +}; + +const Ptr cv::ogl::Texture2D::Impl::empty() +{ + static Ptr p(new Impl); + return p; +} + +cv::ogl::Texture2D::Impl::Impl() : texId_(0), autoRelease_(true) +{ +} + +cv::ogl::Texture2D::Impl::Impl(GLuint atexId, bool autoRelease) : texId_(atexId), autoRelease_(autoRelease) +{ +} + +cv::ogl::Texture2D::Impl::Impl(GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels, bool autoRelease) : texId_(0), autoRelease_(autoRelease) +{ + gl::GenTextures(1, &texId_); + CV_CheckGlError(); + + CV_Assert(texId_ != 0); + + gl::BindTexture(gl::TEXTURE_2D, texId_); + CV_CheckGlError(); + + gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1); + CV_CheckGlError(); + + gl::TexImage2D(gl::TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, pixels); + CV_CheckGlError(); + + gl::GenerateMipmap(gl::TEXTURE_2D); + CV_CheckGlError(); +} + +cv::ogl::Texture2D::Impl::~Impl() +{ + if (autoRelease_ && texId_) + gl::DeleteTextures(1, &texId_); +} + +void cv::ogl::Texture2D::Impl::copyFrom(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + gl::BindTexture(gl::TEXTURE_2D, texId_); + CV_CheckGlError(); + + gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1); + CV_CheckGlError(); + + gl::TexSubImage2D(gl::TEXTURE_2D, 0, 0, 0, width, height, format, type, pixels); + CV_CheckGlError(); + + gl::GenerateMipmap(gl::TEXTURE_2D); + CV_CheckGlError(); +} + +void cv::ogl::Texture2D::Impl::copyTo(GLenum format, GLenum type, GLvoid* pixels) const +{ + gl::BindTexture(gl::TEXTURE_2D, texId_); + CV_CheckGlError(); + + gl::PixelStorei(gl::PACK_ALIGNMENT, 1); + CV_CheckGlError(); + + gl::GetTexImage(gl::TEXTURE_2D, 0, format, type, pixels); + CV_CheckGlError(); +} + +void cv::ogl::Texture2D::Impl::bind() const +{ + gl::BindTexture(gl::TEXTURE_2D, texId_); + CV_CheckGlError(); +} + +#endif // HAVE_OPENGL + +cv::ogl::Texture2D::Texture2D() : rows_(0), cols_(0), format_(NONE) +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + impl_ = Impl::empty(); +#endif +} + +cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ +#ifndef HAVE_OPENGL + (void) arows; + (void) acols; + (void) aformat; + (void) atexId; + (void) autoRelease; + throw_nogl(); +#else + impl_ = new Impl(atexId, autoRelease); + rows_ = arows; + cols_ = acols; + format_ = aformat; +#endif +} + +cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ +#ifndef HAVE_OPENGL + (void) asize; + (void) aformat; + (void) atexId; + (void) autoRelease; + throw_nogl(); +#else + impl_ = new Impl(atexId, autoRelease); + rows_ = asize.height; + cols_ = asize.width; + format_ = aformat; +#endif +} + +cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(arows, acols, aformat, autoRelease); +} + +cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(asize, aformat, autoRelease); +} + +cv::ogl::Texture2D::Texture2D(InputArray arr, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + const Size asize = arr.size(); + const int atype = arr.type(); + + const int depth = CV_MAT_DEPTH(atype); + const int cn = CV_MAT_CN(atype); + + CV_Assert( depth <= CV_32F ); + CV_Assert( cn == 1 || cn == 3 || cn == 4 ); + + const Format internalFormats[] = + { + NONE, DEPTH_COMPONENT, NONE, RGB, RGBA + }; + const GLenum srcFormats[] = + { + 0, gl::DEPTH_COMPONENT, 0, gl::BGR, gl::BGRA + }; + + switch (kind) + { + case _InputArray::OPENGL_BUFFER: + { + ogl::Buffer buf = arr.getOGlBuffer(); + buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_ = new Impl(internalFormats[cn], asize.width, asize.height, srcFormats[cn], gl_types[depth], 0, autoRelease); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + break; + } + + case _InputArray::GPU_MAT: + { + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + GpuMat dmat = arr.getGpuMat(); + ogl::Buffer buf(dmat, ogl::Buffer::PIXEL_UNPACK_BUFFER); + buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_ = new Impl(internalFormats[cn], asize.width, asize.height, srcFormats[cn], gl_types[depth], 0, autoRelease); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + #endif + + break; + } + + default: + { + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_ = new Impl(internalFormats[cn], asize.width, asize.height, srcFormats[cn], gl_types[depth], mat.data, autoRelease); + break; + } + } + + rows_ = asize.height; + cols_ = asize.width; + format_ = internalFormats[cn]; +#endif +} + +void cv::ogl::Texture2D::create(int arows, int acols, Format aformat, bool autoRelease) +{ +#ifndef HAVE_OPENGL + (void) arows; + (void) acols; + (void) aformat; + (void) autoRelease; + throw_nogl(); +#else + if (rows_ != arows || cols_ != acols || format_ != aformat) + { + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_ = new Impl(aformat, acols, arows, aformat, gl::FLOAT, 0, autoRelease); + rows_ = arows; + cols_ = acols; + format_ = aformat; + } +#endif +} + +void cv::ogl::Texture2D::release() +{ +#ifdef HAVE_OPENGL + if (*impl_.refcount == 1) + impl_->setAutoRelease(true); + impl_ = Impl::empty(); + rows_ = 0; + cols_ = 0; + format_ = NONE; +#endif +} + +void cv::ogl::Texture2D::setAutoRelease(bool flag) +{ +#ifndef HAVE_OPENGL + (void) flag; + throw_nogl(); +#else + impl_->setAutoRelease(flag); +#endif +} + +void cv::ogl::Texture2D::copyFrom(InputArray arr, bool autoRelease) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + const Size asize = arr.size(); + const int atype = arr.type(); + + const int depth = CV_MAT_DEPTH(atype); + const int cn = CV_MAT_CN(atype); + + CV_Assert( depth <= CV_32F ); + CV_Assert( cn == 1 || cn == 3 || cn == 4 ); + + const Format internalFormats[] = + { + NONE, DEPTH_COMPONENT, NONE, RGB, RGBA + }; + const GLenum srcFormats[] = + { + 0, gl::DEPTH_COMPONENT, 0, gl::BGR, gl::BGRA + }; + + create(asize, internalFormats[cn], autoRelease); + + switch(kind) + { + case _InputArray::OPENGL_BUFFER: + { + ogl::Buffer buf = arr.getOGlBuffer(); + buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], 0); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + break; + } + + case _InputArray::GPU_MAT: + { + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + GpuMat dmat = arr.getGpuMat(); + ogl::Buffer buf(dmat, ogl::Buffer::PIXEL_UNPACK_BUFFER); + buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], 0); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + #endif + + break; + } + + default: + { + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); + impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], mat.data); + } + } +#endif +} + +void cv::ogl::Texture2D::copyTo(OutputArray arr, int ddepth, bool autoRelease) const +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) ddepth; + (void) autoRelease; + throw_nogl(); +#else + const int kind = arr.kind(); + + const int cn = format_ == DEPTH_COMPONENT ? 1: format_ == RGB ? 3 : 4; + const GLenum dstFormat = format_ == DEPTH_COMPONENT ? gl::DEPTH_COMPONENT : format_ == RGB ? gl::BGR : gl::BGRA; + + switch(kind) + { + case _InputArray::OPENGL_BUFFER: + { + ogl::Buffer& buf = arr.getOGlBufferRef(); + buf.create(rows_, cols_, CV_MAKE_TYPE(ddepth, cn), ogl::Buffer::PIXEL_PACK_BUFFER, autoRelease); + buf.bind(ogl::Buffer::PIXEL_PACK_BUFFER); + impl_->copyTo(dstFormat, gl_types[ddepth], 0); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_PACK_BUFFER); + break; + } + + case _InputArray::GPU_MAT: + { + #if !defined HAVE_CUDA || defined(CUDA_DISABLER) + throw_nocuda(); + #else + ogl::Buffer buf(rows_, cols_, CV_MAKE_TYPE(ddepth, cn), ogl::Buffer::PIXEL_PACK_BUFFER); + buf.bind(ogl::Buffer::PIXEL_PACK_BUFFER); + impl_->copyTo(dstFormat, gl_types[ddepth], 0); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_PACK_BUFFER); + buf.copyTo(arr); + #endif + + break; + } + + default: + { + arr.create(rows_, cols_, CV_MAKE_TYPE(ddepth, cn)); + Mat mat = arr.getMat(); + CV_Assert( mat.isContinuous() ); + ogl::Buffer::unbind(ogl::Buffer::PIXEL_PACK_BUFFER); + impl_->copyTo(dstFormat, gl_types[ddepth], mat.data); + } + } +#endif +} + +void cv::ogl::Texture2D::bind() const +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + impl_->bind(); +#endif +} + +unsigned int cv::ogl::Texture2D::texId() const +{ +#ifndef HAVE_OPENGL + throw_nogl(); + return 0; +#else + return impl_->texId(); +#endif +} + +template <> void cv::Ptr::delete_obj() +{ + if (obj) delete obj; +} + +//////////////////////////////////////////////////////////////////////// +// ogl::Arrays + +cv::ogl::Arrays::Arrays() : size_(0) +{ +} + +void cv::ogl::Arrays::setVertexArray(InputArray vertex) +{ + const int cn = vertex.channels(); + const int depth = vertex.depth(); + + CV_Assert( cn == 2 || cn == 3 || cn == 4 ); + CV_Assert( depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F ); + + if (vertex.kind() == _InputArray::OPENGL_BUFFER) + vertex_ = vertex.getOGlBuffer(); + else + vertex_.copyFrom(vertex); + + size_ = vertex_.size().area(); +} + +void cv::ogl::Arrays::resetVertexArray() +{ + vertex_.release(); + size_ = 0; +} + +void cv::ogl::Arrays::setColorArray(InputArray color) +{ + const int cn = color.channels(); + + CV_Assert( cn == 3 || cn == 4 ); + + if (color.kind() == _InputArray::OPENGL_BUFFER) + color_ = color.getOGlBuffer(); + else + color_.copyFrom(color); +} + +void cv::ogl::Arrays::resetColorArray() +{ + color_.release(); +} + +void cv::ogl::Arrays::setNormalArray(InputArray normal) +{ + const int cn = normal.channels(); + const int depth = normal.depth(); + + CV_Assert( cn == 3 ); + CV_Assert( depth == CV_8S || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F ); + + if (normal.kind() == _InputArray::OPENGL_BUFFER) + normal_ = normal.getOGlBuffer(); + else + normal_.copyFrom(normal); +} + +void cv::ogl::Arrays::resetNormalArray() +{ + normal_.release(); +} + +void cv::ogl::Arrays::setTexCoordArray(InputArray texCoord) +{ + const int cn = texCoord.channels(); + const int depth = texCoord.depth(); + + CV_Assert( cn >= 1 && cn <= 4 ); + CV_Assert( depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F ); + + if (texCoord.kind() == _InputArray::OPENGL_BUFFER) + texCoord_ = texCoord.getOGlBuffer(); + else + texCoord_.copyFrom(texCoord); +} + +void cv::ogl::Arrays::resetTexCoordArray() +{ + texCoord_.release(); +} + +void cv::ogl::Arrays::release() +{ + resetVertexArray(); + resetColorArray(); + resetNormalArray(); + resetTexCoordArray(); +} + +void cv::ogl::Arrays::setAutoRelease(bool flag) +{ + vertex_.setAutoRelease(flag); + color_.setAutoRelease(flag); + normal_.setAutoRelease(flag); + texCoord_.setAutoRelease(flag); +} + +void cv::ogl::Arrays::bind() const +{ +#ifndef HAVE_OPENGL + throw_nogl(); +#else + CV_Assert( texCoord_.empty() || texCoord_.size().area() == size_ ); + CV_Assert( normal_.empty() || normal_.size().area() == size_ ); + CV_Assert( color_.empty() || color_.size().area() == size_ ); + + if (texCoord_.empty()) + { + gl::DisableClientState(gl::TEXTURE_COORD_ARRAY); + CV_CheckGlError(); + } + else + { + gl::EnableClientState(gl::TEXTURE_COORD_ARRAY); + CV_CheckGlError(); + + texCoord_.bind(ogl::Buffer::ARRAY_BUFFER); + + gl::TexCoordPointer(texCoord_.channels(), gl_types[texCoord_.depth()], 0, 0); + CV_CheckGlError(); + } + + if (normal_.empty()) + { + gl::DisableClientState(gl::NORMAL_ARRAY); + CV_CheckGlError(); + } + else + { + gl::EnableClientState(gl::NORMAL_ARRAY); + CV_CheckGlError(); + + normal_.bind(ogl::Buffer::ARRAY_BUFFER); + + gl::NormalPointer(gl_types[normal_.depth()], 0, 0); + CV_CheckGlError(); + } + + if (color_.empty()) + { + gl::DisableClientState(gl::COLOR_ARRAY); + CV_CheckGlError(); + } + else + { + gl::EnableClientState(gl::COLOR_ARRAY); + CV_CheckGlError(); + + color_.bind(ogl::Buffer::ARRAY_BUFFER); + + const int cn = color_.channels(); + + gl::ColorPointer(cn, gl_types[color_.depth()], 0, 0); + CV_CheckGlError(); + } + + if (vertex_.empty()) + { + gl::DisableClientState(gl::VERTEX_ARRAY); + CV_CheckGlError(); + } + else + { + gl::EnableClientState(gl::VERTEX_ARRAY); + CV_CheckGlError(); + + vertex_.bind(ogl::Buffer::ARRAY_BUFFER); + + gl::VertexPointer(vertex_.channels(), gl_types[vertex_.depth()], 0, 0); + CV_CheckGlError(); + } + + ogl::Buffer::unbind(ogl::Buffer::ARRAY_BUFFER); +#endif +} + +//////////////////////////////////////////////////////////////////////// +// Rendering + +void cv::ogl::render(const ogl::Texture2D& tex, Rect_ wndRect, Rect_ texRect) +{ +#ifndef HAVE_OPENGL + (void) tex; + (void) wndRect; + (void) texRect; + throw_nogl(); +#else + if (!tex.empty()) + { + gl::MatrixMode(gl::PROJECTION); + gl::LoadIdentity(); + gl::Ortho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0); + CV_CheckGlError(); + + gl::MatrixMode(gl::MODELVIEW); + gl::LoadIdentity(); + CV_CheckGlError(); + + gl::Disable(gl::LIGHTING); + CV_CheckGlError(); + + tex.bind(); + + gl::Enable(gl::TEXTURE_2D); + CV_CheckGlError(); + + gl::TexEnvi(gl::TEXTURE_ENV, gl::TEXTURE_ENV_MODE, gl::REPLACE); + CV_CheckGlError(); + + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR); + CV_CheckGlError(); + + const float vertex[] = + { + wndRect.x, wndRect.y, 0.0f, + wndRect.x, (wndRect.y + wndRect.height), 0.0f, + wndRect.x + wndRect.width, (wndRect.y + wndRect.height), 0.0f, + wndRect.x + wndRect.width, wndRect.y, 0.0f + }; + const float texCoords[] = + { + texRect.x, texRect.y, + texRect.x, texRect.y + texRect.height, + texRect.x + texRect.width, texRect.y + texRect.height, + texRect.x + texRect.width, texRect.y + }; + + ogl::Buffer::unbind(ogl::Buffer::ARRAY_BUFFER); + + gl::EnableClientState(gl::TEXTURE_COORD_ARRAY); + CV_CheckGlError(); + + gl::TexCoordPointer(2, gl::FLOAT, 0, texCoords); + CV_CheckGlError(); + + gl::DisableClientState(gl::NORMAL_ARRAY); + gl::DisableClientState(gl::COLOR_ARRAY); + CV_CheckGlError(); + + gl::EnableClientState(gl::VERTEX_ARRAY); + CV_CheckGlError(); + + gl::VertexPointer(3, gl::FLOAT, 0, vertex); + CV_CheckGlError(); + + gl::DrawArrays(gl::QUADS, 0, 4); + CV_CheckGlError(); + } +#endif +} + +void cv::ogl::render(const ogl::Arrays& arr, int mode, Scalar color) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) mode; + (void) color; + throw_nogl(); +#else + if (!arr.empty()) + { + gl::Color3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0); + + arr.bind(); + + gl::DrawArrays(mode, 0, arr.size()); + } +#endif +} + +void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scalar color) +{ +#ifndef HAVE_OPENGL + (void) arr; + (void) indices; + (void) mode; + (void) color; + throw_nogl(); +#else + if (!arr.empty() && !indices.empty()) + { + gl::Color3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0); + + arr.bind(); + + const int kind = indices.kind(); + + switch (kind) + { + case _InputArray::OPENGL_BUFFER : + { + ogl::Buffer buf = indices.getOGlBuffer(); + + const int depth = buf.depth(); + + CV_Assert( buf.channels() == 1 ); + CV_Assert( depth <= CV_32S ); + + GLenum type; + if (depth < CV_16U) + type = gl::UNSIGNED_BYTE; + else if (depth < CV_32S) + type = gl::UNSIGNED_SHORT; + else + type = gl::UNSIGNED_INT; + + buf.bind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); + + gl::DrawElements(mode, buf.size().area(), type, 0); + + ogl::Buffer::unbind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); + + break; + } + + default: + { + Mat mat = indices.getMat(); + + const int depth = mat.depth(); + + CV_Assert( mat.channels() == 1 ); + CV_Assert( depth <= CV_32S ); + CV_Assert( mat.isContinuous() ); + + GLenum type; + if (depth < CV_16U) + type = gl::UNSIGNED_BYTE; + else if (depth < CV_32S) + type = gl::UNSIGNED_SHORT; + else + type = gl::UNSIGNED_INT; + + ogl::Buffer::unbind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); + + gl::DrawElements(mode, mat.size().area(), type, mat.data); + } + } + } +#endif +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/opengl_interop_deprecated.cpp diffimg-2.0.0/3rdparty/opencv/core/src/opengl_interop_deprecated.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/opengl_interop_deprecated.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/opengl_interop_deprecated.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,330 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" +#include "opencv2/core/opengl_interop_deprecated.hpp" +#include "opencv2/core/gpumat.hpp" + +using namespace std; +using namespace cv; +using namespace cv::gpu; + +CvOpenGlFuncTab::~CvOpenGlFuncTab() +{ +} + +void icvSetOpenGlFuncTab(const CvOpenGlFuncTab*) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +//////////////////////////////////////////////////////////////////////// +// GlBuffer + +class cv::GlBuffer::Impl +{ +}; + +cv::GlBuffer::GlBuffer(Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlBuffer::GlBuffer(int, int, int, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlBuffer::GlBuffer(Size, int, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlBuffer::GlBuffer(InputArray, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlBuffer::create(int, int, int, Usage) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlBuffer::release() +{ +} + +void cv::GlBuffer::copyFrom(InputArray) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlBuffer::bind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlBuffer::unbind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +Mat cv::GlBuffer::mapHost() +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return Mat(); +} + +void cv::GlBuffer::unmapHost() +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +GpuMat cv::GlBuffer::mapDevice() +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return GpuMat(); +} + +void cv::GlBuffer::unmapDevice() +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +template <> void cv::Ptr::delete_obj() +{ + if (obj) delete obj; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// GlTexture + +class cv::GlTexture::Impl +{ +}; + +cv::GlTexture::GlTexture() : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlTexture::GlTexture(int, int, int) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlTexture::GlTexture(Size, int) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +cv::GlTexture::GlTexture(InputArray, bool) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlTexture::create(int, int, int) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlTexture::release() +{ +} + +void cv::GlTexture::copyFrom(InputArray, bool) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlTexture::bind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlTexture::unbind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +template <> void cv::Ptr::delete_obj() +{ + if (obj) delete obj; +} + +//////////////////////////////////////////////////////////////////////// +// GlArrays + +void cv::GlArrays::setVertexArray(InputArray) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlArrays::setColorArray(InputArray, bool) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlArrays::setNormalArray(InputArray) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlArrays::setTexCoordArray(InputArray) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlArrays::bind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlArrays::unbind() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +//////////////////////////////////////////////////////////////////////// +// GlFont + +cv::GlFont::GlFont(const string& _family, int _height, Weight _weight, Style _style) + : family_(_family), height_(_height), weight_(_weight), style_(_style), base_(0) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlFont::draw(const char*, int) const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +Ptr cv::GlFont::get(const std::string&, int, Weight, Style) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return Ptr(); +} + +//////////////////////////////////////////////////////////////////////// +// Rendering + +void cv::render(const GlTexture&, Rect_, Rect_) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::render(const GlArrays&, int, Scalar) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::render(const string&, const Ptr&, Scalar, Point2d) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +//////////////////////////////////////////////////////////////////////// +// GlCamera + +cv::GlCamera::GlCamera() : + eye_(0.0, 0.0, -5.0), center_(0.0, 0.0, 0.0), up_(0.0, 1.0, 0.0), + pos_(0.0, 0.0, -5.0), yaw_(0.0), pitch_(0.0), roll_(0.0), + useLookAtParams_(false), + + scale_(1.0, 1.0, 1.0), + + projectionMatrix_(), + fov_(45.0), aspect_(0.0), + left_(0.0), right_(1.0), bottom_(1.0), top_(0.0), + zNear_(-1.0), zFar_(1.0), + perspectiveProjection_(false) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::lookAt(Point3d, Point3d, Point3d) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setCameraPos(Point3d, double, double, double) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setScale(Point3d) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setProjectionMatrix(const Mat&, bool) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setPerspectiveProjection(double, double, double, double) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setOrthoProjection(double, double, double, double, double, double) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setupProjectionMatrix() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::GlCamera::setupModelViewMatrix() const +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +//////////////////////////////////////////////////////////////////////// +// Error handling + +bool icvCheckGlError(const char*, const int, const char*) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); + return false; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/out.cpp diffimg-2.0.0/3rdparty/opencv/core/src/out.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/out.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/out.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,307 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include + +namespace cv +{ + +static inline char getCloseBrace(char c) +{ + return c == '[' ? ']' : c == '(' ? ')' : c == '{' ? '}' : '\0'; +} + + +template static void writeElems(std::ostream& out, const _Tp* data, + int nelems, int cn, char obrace, char cbrace) +{ + typedef typename DataType<_Tp>::work_type _WTp; + nelems *= cn; + for(int i = 0; i < nelems; i += cn) + { + if(cn == 1) + { + out << (_WTp)data[i] << (i+1 < nelems ? ", " : ""); + continue; + } + out << obrace; + for(int j = 0; j < cn; j++) + out << (_WTp)data[i + j] << (j+1 < cn ? ", " : ""); + out << cbrace << (i+cn < nelems ? ", " : ""); + } +} + + +static void writeElems(std::ostream& out, const void* data, int nelems, int type, char brace) +{ + int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); + char cbrace = ' '; + if(!brace || isspace(brace)) + { + nelems *= cn; + cn = 1; + } + else + cbrace = getCloseBrace(brace); + if(depth == CV_8U) + writeElems(out, (const uchar*)data, nelems, cn, brace, cbrace); + else if(depth == CV_8S) + writeElems(out, (const schar*)data, nelems, cn, brace, cbrace); + else if(depth == CV_16U) + writeElems(out, (const ushort*)data, nelems, cn, brace, cbrace); + else if(depth == CV_16S) + writeElems(out, (const short*)data, nelems, cn, brace, cbrace); + else if(depth == CV_32S) + writeElems(out, (const int*)data, nelems, cn, brace, cbrace); + else if(depth == CV_32F) + { + std::streamsize pp = out.precision(); + out.precision(8); + writeElems(out, (const float*)data, nelems, cn, brace, cbrace); + out.precision(pp); + } + else if(depth == CV_64F) + { + std::streamsize pp = out.precision(); + out.precision(16); + writeElems(out, (const double*)data, nelems, cn, brace, cbrace); + out.precision(pp); + } + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +static void writeMat(std::ostream& out, const Mat& m, char rowsep, char elembrace, bool singleLine) +{ + CV_Assert(m.dims <= 2); + int type = m.type(); + + char crowbrace = getCloseBrace(rowsep); + char orowbrace = crowbrace ? rowsep : '\0'; + + if( orowbrace || isspace(rowsep) ) + rowsep = '\0'; + + for( int i = 0; i < m.rows; i++ ) + { + if(orowbrace) + out << orowbrace; + if( m.data ) + writeElems(out, m.ptr(i), m.cols, type, elembrace); + if(orowbrace) + out << crowbrace << (i+1 < m.rows ? ", " : ""); + if(i+1 < m.rows) + { + if(rowsep) + out << rowsep << (singleLine ? " " : ""); + if(!singleLine) + out << "\n "; + } + } +} + +class MatlabFormatter : public Formatter +{ +public: + virtual ~MatlabFormatter() {} + void write(std::ostream& out, const Mat& m, const int*, int) const + { + out << "["; + writeMat(out, m, ';', ' ', m.cols == 1); + out << "]"; + } + + void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const + { + writeElems(out, data, nelems, type, ' '); + } +}; + +class PythonFormatter : public Formatter +{ +public: + virtual ~PythonFormatter() {} + void write(std::ostream& out, const Mat& m, const int*, int) const + { + out << "["; + writeMat(out, m, m.cols > 1 ? '[' : ' ', '[', m.cols*m.channels() == 1); + out << "]"; + } + + void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const + { + writeElems(out, data, nelems, type, '['); + } +}; + + +class NumpyFormatter : public Formatter +{ +public: + virtual ~NumpyFormatter() {} + void write(std::ostream& out, const Mat& m, const int*, int) const + { + static const char* numpyTypes[] = + { + "uint8", "int8", "uint16", "int16", "int32", "float32", "float64", "uint64" + }; + out << "array(["; + writeMat(out, m, m.cols > 1 ? '[' : ' ', '[', m.cols*m.channels() == 1); + out << "], type='" << numpyTypes[m.depth()] << "')"; + } + + void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const + { + writeElems(out, data, nelems, type, '['); + } +}; + + +class CSVFormatter : public Formatter +{ +public: + virtual ~CSVFormatter() {} + void write(std::ostream& out, const Mat& m, const int*, int) const + { + writeMat(out, m, ' ', ' ', m.cols*m.channels() == 1); + if(m.rows > 1) + out << "\n"; + } + + void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const + { + writeElems(out, data, nelems, type, ' '); + } +}; + + +class CFormatter : public Formatter +{ +public: + virtual ~CFormatter() {} + void write(std::ostream& out, const Mat& m, const int*, int) const + { + out << "{"; + writeMat(out, m, ',', ' ', m.cols==1); + out << "}"; + } + + void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const + { + writeElems(out, data, nelems, type, ' '); + } +}; + + +static MatlabFormatter matlabFormatter; +static PythonFormatter pythonFormatter; +static NumpyFormatter numpyFormatter; +static CSVFormatter csvFormatter; +static CFormatter cFormatter; + +static const Formatter* g_defaultFormatter0 = &matlabFormatter; +static const Formatter* g_defaultFormatter = &matlabFormatter; + +static bool my_streq(const char* a, const char* b) +{ + size_t i, alen = strlen(a), blen = strlen(b); + if( alen != blen ) + return false; + for( i = 0; i < alen; i++ ) + if( a[i] != b[i] && a[i] - 32 != b[i] ) + return false; + return true; +} + +const Formatter* Formatter::get(const char* fmt) +{ + if(!fmt || my_streq(fmt, "")) + return g_defaultFormatter; + if( my_streq(fmt, "MATLAB")) + return &matlabFormatter; + if( my_streq(fmt, "CSV")) + return &csvFormatter; + if( my_streq(fmt, "PYTHON")) + return &pythonFormatter; + if( my_streq(fmt, "NUMPY")) + return &numpyFormatter; + if( my_streq(fmt, "C")) + return &cFormatter; + CV_Error(CV_StsBadArg, "Unknown formatter"); + return g_defaultFormatter; +} + +const Formatter* Formatter::setDefault(const Formatter* fmt) +{ + const Formatter* prevFmt = g_defaultFormatter; + if(!fmt) + fmt = g_defaultFormatter0; + g_defaultFormatter = fmt; + return prevFmt; +} + +Formatted::Formatted(const Mat& _m, const Formatter* _fmt, + const vector& _params) +{ + mtx = _m; + fmt = _fmt ? _fmt : Formatter::get(); + std::copy(_params.begin(), _params.end(), back_inserter(params)); +} + +Formatted::Formatted(const Mat& _m, const Formatter* _fmt, const int* _params) +{ + mtx = _m; + fmt = _fmt ? _fmt : Formatter::get(); + + if( _params ) + { + int i, maxParams = 100; + for(i = 0; i < maxParams && _params[i] != 0; i+=2) + ; + std::copy(_params, _params + i, back_inserter(params)); + } +} + +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/parallel.cpp diffimg-2.0.0/3rdparty/opencv/core/src/parallel.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/parallel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/parallel.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,496 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if defined WIN32 || defined WINCE + #include + #undef small + #undef min + #undef max + #undef abs +#endif + +#if defined __linux__ || defined __APPLE__ + #include + #include + #include + #if defined ANDROID + #include + #else + #include + #endif +#endif + +#ifdef _OPENMP + #define HAVE_OPENMP +#endif + +#ifdef __APPLE__ + #define HAVE_GCD +#endif + +#if defined _MSC_VER && _MSC_VER >= 1600 + #define HAVE_CONCURRENCY +#endif + +/* IMPORTANT: always use the same order of defines + 1. HAVE_TBB - 3rdparty library, should be explicitly enabled + 2. HAVE_CSTRIPES - 3rdparty library, should be explicitly enabled + 3. HAVE_OPENMP - integrated to compiler, should be explicitly enabled + 4. HAVE_GCD - system wide, used automatically (APPLE only) + 5. HAVE_CONCURRENCY - part of runtime, used automatically (Windows only - MSVS 10, MSVS 11) +*/ + +#if defined HAVE_TBB + #include "tbb/tbb_stddef.h" + #if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202 + #include "tbb/tbb.h" + #include "tbb/task.h" + #if TBB_INTERFACE_VERSION >= 6100 + #include "tbb/task_arena.h" + #endif + #undef min + #undef max + #else + #undef HAVE_TBB + #endif // end TBB version +#endif + +#ifndef HAVE_TBB + #if defined HAVE_CSTRIPES + #include "C=.h" + #undef shared + #elif defined HAVE_OPENMP + #include + #elif defined HAVE_GCD + #include + #include + #elif defined HAVE_CONCURRENCY + #include + #endif +#endif + +#if defined HAVE_TBB || defined HAVE_CSTRIPES || defined HAVE_OPENMP || defined HAVE_GCD || defined HAVE_CONCURRENCY + #define HAVE_PARALLEL_FRAMEWORK +#endif + +namespace cv +{ + ParallelLoopBody::~ParallelLoopBody() {} +} + +namespace +{ +#ifdef HAVE_PARALLEL_FRAMEWORK + class ParallelLoopBodyWrapper + { + public: + ParallelLoopBodyWrapper(const cv::ParallelLoopBody& _body, const cv::Range& _r, double _nstripes) + { + body = &_body; + wholeRange = _r; + double len = wholeRange.end - wholeRange.start; + nstripes = cvRound(_nstripes <= 0 ? len : MIN(MAX(_nstripes, 1.), len)); + } + void operator()(const cv::Range& sr) const + { + cv::Range r; + r.start = (int)(wholeRange.start + + ((size_t)sr.start*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes); + r.end = sr.end >= nstripes ? wholeRange.end : (int)(wholeRange.start + + ((size_t)sr.end*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes); + (*body)(r); + } + cv::Range stripeRange() const { return cv::Range(0, nstripes); } + + protected: + const cv::ParallelLoopBody* body; + cv::Range wholeRange; + int nstripes; + }; + +#if defined HAVE_TBB + class ProxyLoopBody : public ParallelLoopBodyWrapper + { + public: + ProxyLoopBody(const cv::ParallelLoopBody& _body, const cv::Range& _r, double _nstripes) + : ParallelLoopBodyWrapper(_body, _r, _nstripes) + {} + + void operator ()(const tbb::blocked_range& range) const + { + this->ParallelLoopBodyWrapper::operator()(cv::Range(range.begin(), range.end())); + } + }; +#elif defined HAVE_CSTRIPES || defined HAVE_OPENMP + typedef ParallelLoopBodyWrapper ProxyLoopBody; +#elif defined HAVE_GCD + typedef ParallelLoopBodyWrapper ProxyLoopBody; + static void block_function(void* context, size_t index) + { + ProxyLoopBody* ptr_body = static_cast(context); + (*ptr_body)(cv::Range(index, index + 1)); + } +#elif defined HAVE_CONCURRENCY + class ProxyLoopBody : public ParallelLoopBodyWrapper + { + public: + ProxyLoopBody(const cv::ParallelLoopBody& _body, const cv::Range& _r, double _nstripes) + : ParallelLoopBodyWrapper(_body, _r, _nstripes) + {} + + void operator ()(int i) const + { + this->ParallelLoopBodyWrapper::operator()(cv::Range(i, i + 1)); + } + }; +#else + typedef ParallelLoopBodyWrapper ProxyLoopBody; +#endif + +static int numThreads = -1; + +#if defined HAVE_TBB +static tbb::task_scheduler_init tbbScheduler(tbb::task_scheduler_init::deferred); +#elif defined HAVE_CSTRIPES +// nothing for C= +#elif defined HAVE_OPENMP +static int numThreadsMax = omp_get_max_threads(); +#elif defined HAVE_GCD +// nothing for GCD +#elif defined HAVE_CONCURRENCY +class SchedPtr +{ + Concurrency::Scheduler* sched_; +public: + Concurrency::Scheduler* operator->() { return sched_; } + operator Concurrency::Scheduler*() { return sched_; } + + void operator=(Concurrency::Scheduler* sched) + { + if (sched_) sched_->Release(); + sched_ = sched; + } + + SchedPtr() : sched_(0) {} + ~SchedPtr() { *this = 0; } +}; +static SchedPtr pplScheduler; +#endif + +#endif // HAVE_PARALLEL_FRAMEWORK + +} //namespace + +/* ================================ parallel_for_ ================================ */ + +void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes) +{ +#ifdef HAVE_PARALLEL_FRAMEWORK + + if(numThreads != 0) + { + ProxyLoopBody pbody(body, range, nstripes); + cv::Range stripeRange = pbody.stripeRange(); + +#if defined HAVE_TBB + + tbb::parallel_for(tbb::blocked_range(stripeRange.start, stripeRange.end), pbody); + +#elif defined HAVE_CSTRIPES + + parallel(MAX(0, numThreads)) + { + int offset = stripeRange.start; + int len = stripeRange.end - offset; + Range r(offset + CPX_RANGE_START(len), offset + CPX_RANGE_END(len)); + pbody(r); + barrier(); + } + +#elif defined HAVE_OPENMP + + #pragma omp parallel for schedule(dynamic) + for (int i = stripeRange.start; i < stripeRange.end; ++i) + pbody(Range(i, i + 1)); + +#elif defined HAVE_GCD + + dispatch_queue_t concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_apply_f(stripeRange.end - stripeRange.start, concurrent_queue, &pbody, block_function); + +#elif defined HAVE_CONCURRENCY + + if(!pplScheduler || pplScheduler->Id() == Concurrency::CurrentScheduler::Id()) + { + Concurrency::parallel_for(stripeRange.start, stripeRange.end, pbody); + } + else + { + pplScheduler->Attach(); + Concurrency::parallel_for(stripeRange.start, stripeRange.end, pbody); + Concurrency::CurrentScheduler::Detach(); + } + +#else + +#error You have hacked and compiling with unsupported parallel framework + +#endif + + } + else + +#endif // HAVE_PARALLEL_FRAMEWORK + { + (void)nstripes; + body(range); + } +} + +int cv::getNumThreads(void) +{ +#ifdef HAVE_PARALLEL_FRAMEWORK + + if(numThreads == 0) + return 1; + +#endif + +#if defined HAVE_TBB + + return tbbScheduler.is_active() + ? numThreads + : tbb::task_scheduler_init::default_num_threads(); + +#elif defined HAVE_CSTRIPES + + return numThreads > 0 + ? numThreads + : cv::getNumberOfCPUs(); + +#elif defined HAVE_OPENMP + + return omp_get_max_threads(); + +#elif defined HAVE_GCD + + return 512; // the GCD thread pool limit + +#elif defined HAVE_CONCURRENCY + + return 1 + (pplScheduler == 0 + ? Concurrency::CurrentScheduler::Get()->GetNumberOfVirtualProcessors() + : pplScheduler->GetNumberOfVirtualProcessors()); + +#else + + return 1; + +#endif +} + +void cv::setNumThreads( int threads ) +{ + (void)threads; +#ifdef HAVE_PARALLEL_FRAMEWORK + numThreads = threads; +#endif + +#ifdef HAVE_TBB + + if(tbbScheduler.is_active()) tbbScheduler.terminate(); + if(threads > 0) tbbScheduler.initialize(threads); + +#elif defined HAVE_CSTRIPES + + return; // nothing needed + +#elif defined HAVE_OPENMP + + if(omp_in_parallel()) + return; // can't change number of openmp threads inside a parallel region + + omp_set_num_threads(threads > 0 ? threads : numThreadsMax); + +#elif defined HAVE_GCD + + // unsupported + // there is only private dispatch_queue_set_width() and only for desktop + +#elif defined HAVE_CONCURRENCY + + if (threads <= 0) + { + pplScheduler = 0; + } + else if (threads == 1) + { + // Concurrency always uses >=2 threads, so we just disable it if 1 thread is requested + numThreads = 0; + } + else if (pplScheduler == 0 || 1 + pplScheduler->GetNumberOfVirtualProcessors() != (unsigned int)threads) + { + pplScheduler = Concurrency::Scheduler::Create(Concurrency::SchedulerPolicy(2, + Concurrency::MinConcurrency, threads-1, + Concurrency::MaxConcurrency, threads-1)); + } + +#endif +} + + +int cv::getThreadNum(void) +{ +#if defined HAVE_TBB + #if TBB_INTERFACE_VERSION >= 6100 && defined TBB_PREVIEW_TASK_ARENA && TBB_PREVIEW_TASK_ARENA + return tbb::task_arena::current_slot(); + #else + return 0; + #endif +#elif defined HAVE_CSTRIPES + return pix(); +#elif defined HAVE_OPENMP + return omp_get_thread_num(); +#elif defined HAVE_GCD + return (int)(size_t)(void*)pthread_self(); // no zero-based indexing +#elif defined HAVE_CONCURRENCY + return std::max(0, (int)Concurrency::Context::VirtualProcessorId()); // zero for master thread, unique number for others but not necessary 1,2,3,... +#else + return 0; +#endif +} + +#ifdef ANDROID +static inline int getNumberOfCPUsImpl() +{ + FILE* cpuPossible = fopen("/sys/devices/system/cpu/possible", "r"); + if(!cpuPossible) + return 1; + + char buf[2000]; //big enough for 1000 CPUs in worst possible configuration + char* pbuf = fgets(buf, sizeof(buf), cpuPossible); + fclose(cpuPossible); + if(!pbuf) + return 1; + + //parse string of form "0-1,3,5-7,10,13-15" + int cpusAvailable = 0; + + while(*pbuf) + { + const char* pos = pbuf; + bool range = false; + while(*pbuf && *pbuf != ',') + { + if(*pbuf == '-') range = true; + ++pbuf; + } + if(*pbuf) *pbuf++ = 0; + if(!range) + ++cpusAvailable; + else + { + int rstart = 0, rend = 0; + sscanf(pos, "%d-%d", &rstart, &rend); + cpusAvailable += rend - rstart + 1; + } + + } + return cpusAvailable ? cpusAvailable : 1; +} +#endif + +int cv::getNumberOfCPUs(void) +{ +#if defined WIN32 || defined _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + + return (int)sysinfo.dwNumberOfProcessors; +#elif defined ANDROID + static int ncpus = getNumberOfCPUsImpl(); + return ncpus; +#elif defined __linux__ + return (int)sysconf( _SC_NPROCESSORS_ONLN ); +#elif defined __APPLE__ + int numCPU=0; + int mib[4]; + size_t len = sizeof(numCPU); + + /* set the mib for hw.ncpu */ + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; + + /* get the number of CPUs from the system */ + sysctl(mib, 2, &numCPU, &len, NULL, 0); + + if( numCPU < 1 ) + { + mib[1] = HW_NCPU; + sysctl( mib, 2, &numCPU, &len, NULL, 0 ); + + if( numCPU < 1 ) + numCPU = 1; + } + + return (int)numCPU; +#else + return 1; +#endif +} + +CV_IMPL void cvSetNumThreads(int nt) +{ + cv::setNumThreads(nt); +} + +CV_IMPL int cvGetNumThreads() +{ + return cv::getNumThreads(); +} + +CV_IMPL int cvGetThreadNum() +{ + return cv::getThreadNum(); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/persistence.cpp diffimg-2.0.0/3rdparty/opencv/core/src/persistence.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/persistence.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/persistence.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,5559 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#include +#include +#include +#include + +#define USE_ZLIB 1 + +#ifdef __APPLE__ +# include "TargetConditionals.h" +# if (defined TARGET_OS_IPHONE && TARGET_OS_IPHONE) || (defined TARGET_IPHONE_SIMULATOR && TARGET_IPHONE_SIMULATOR) +# undef USE_ZLIB +# define USE_ZLIB 0 + typedef void* gzFile; +# endif +#endif + +#if USE_ZLIB +# undef HAVE_UNISTD_H //to avoid redefinition +# ifndef _LFS64_LARGEFILE +# define _LFS64_LARGEFILE 0 +# endif +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 0 +# endif +# include +#endif + +/****************************************************************************************\ +* Common macros and type definitions * +\****************************************************************************************/ + +#define cv_isprint(c) ((uchar)(c) >= (uchar)' ') +#define cv_isprint_or_tab(c) ((uchar)(c) >= (uchar)' ' || (c) == '\t') + +static inline bool cv_isalnum(char c) +{ + return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); +} + +static inline bool cv_isalpha(char c) +{ + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); +} + +static inline bool cv_isdigit(char c) +{ + return '0' <= c && c <= '9'; +} + +static inline bool cv_isspace(char c) +{ + return (9 <= c && c <= 13) || c == ' '; +} + +static char* icv_itoa( int _val, char* buffer, int /*radix*/ ) +{ + const int radix = 10; + char* ptr=buffer + 23 /* enough even for 64-bit integers */; + unsigned val = abs(_val); + + *ptr = '\0'; + do + { + unsigned r = val / radix; + *--ptr = (char)(val - (r*radix) + '0'); + val = r; + } + while( val != 0 ); + + if( _val < 0 ) + *--ptr = '-'; + + return ptr; +} + +cv::string cv::FileStorage::getDefaultObjectName(const string& _filename) +{ + static const char* stubname = "unnamed"; + const char* filename = _filename.c_str(); + const char* ptr2 = filename + _filename.size(); + const char* ptr = ptr2 - 1; + cv::AutoBuffer name_buf(_filename.size()+1); + + while( ptr >= filename && *ptr != '\\' && *ptr != '/' && *ptr != ':' ) + { + if( *ptr == '.' && (!*ptr2 || strncmp(ptr2, ".gz", 3) == 0) ) + ptr2 = ptr; + ptr--; + } + ptr++; + if( ptr == ptr2 ) + CV_Error( CV_StsBadArg, "Invalid filename" ); + + char* name = name_buf; + + // name must start with letter or '_' + if( !cv_isalpha(*ptr) && *ptr!= '_' ){ + *name++ = '_'; + } + + while( ptr < ptr2 ) + { + char c = *ptr++; + if( !cv_isalnum(c) && c != '-' && c != '_' ) + c = '_'; + *name++ = c; + } + *name = '\0'; + name = name_buf; + if( strcmp( name, "_" ) == 0 ) + strcpy( name, stubname ); + return cv::string(name); +} + +namespace cv +{ +#if !defined(ANDROID) || (defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T) +string fromUtf16(const WString& str) +{ + cv::AutoBuffer _buf(str.size()*4 + 1); + char* buf = _buf; + + size_t sz = wcstombs(buf, str.c_str(), str.size()); + if( sz == (size_t)-1 ) + return string(); + buf[sz] = '\0'; + return string(buf); +} + +WString toUtf16(const string& str) +{ + cv::AutoBuffer _buf(str.size() + 1); + wchar_t* buf = _buf; + + size_t sz = mbstowcs(buf, str.c_str(), str.size()); + if( sz == (size_t)-1 ) + return WString(); + buf[sz] = '\0'; + return WString(buf); +} +#endif +} + +typedef struct CvGenericHash +{ + CV_SET_FIELDS() + int tab_size; + void** table; +} +CvGenericHash; + +typedef CvGenericHash CvStringHash; + +typedef struct CvFileMapNode +{ + CvFileNode value; + const CvStringHashNode* key; + struct CvFileMapNode* next; +} +CvFileMapNode; + +typedef struct CvXMLStackRecord +{ + CvMemStoragePos pos; + CvString struct_tag; + int struct_indent; + int struct_flags; +} +CvXMLStackRecord; + +#define CV_XML_OPENING_TAG 1 +#define CV_XML_CLOSING_TAG 2 +#define CV_XML_EMPTY_TAG 3 +#define CV_XML_HEADER_TAG 4 +#define CV_XML_DIRECTIVE_TAG 5 + +//typedef void (*CvParse)( struct CvFileStorage* fs ); +typedef void (*CvStartWriteStruct)( struct CvFileStorage* fs, const char* key, + int struct_flags, const char* type_name ); +typedef void (*CvEndWriteStruct)( struct CvFileStorage* fs ); +typedef void (*CvWriteInt)( struct CvFileStorage* fs, const char* key, int value ); +typedef void (*CvWriteReal)( struct CvFileStorage* fs, const char* key, double value ); +typedef void (*CvWriteString)( struct CvFileStorage* fs, const char* key, + const char* value, int quote ); +typedef void (*CvWriteComment)( struct CvFileStorage* fs, const char* comment, int eol_comment ); +typedef void (*CvStartNextStream)( struct CvFileStorage* fs ); + +typedef struct CvFileStorage +{ + int flags; + int fmt; + int write_mode; + int is_first; + CvMemStorage* memstorage; + CvMemStorage* dststorage; + CvMemStorage* strstorage; + CvStringHash* str_hash; + CvSeq* roots; + CvSeq* write_stack; + int struct_indent; + int struct_flags; + CvString struct_tag; + int space; + char* filename; + FILE* file; + gzFile gzfile; + char* buffer; + char* buffer_start; + char* buffer_end; + int wrap_margin; + int lineno; + int dummy_eof; + const char* errmsg; + char errmsgbuf[128]; + + CvStartWriteStruct start_write_struct; + CvEndWriteStruct end_write_struct; + CvWriteInt write_int; + CvWriteReal write_real; + CvWriteString write_string; + CvWriteComment write_comment; + CvStartNextStream start_next_stream; + + const char* strbuf; + size_t strbufsize, strbufpos; + std::deque* outbuf; + + bool is_opened; +} +CvFileStorage; + +static void icvPuts( CvFileStorage* fs, const char* str ) +{ + if( fs->outbuf ) + std::copy(str, str + strlen(str), std::back_inserter(*fs->outbuf)); + else if( fs->file ) + fputs( str, fs->file ); +#if USE_ZLIB + else if( fs->gzfile ) + gzputs( fs->gzfile, str ); +#endif + else + CV_Error( CV_StsError, "The storage is not opened" ); +} + +static char* icvGets( CvFileStorage* fs, char* str, int maxCount ) +{ + if( fs->strbuf ) + { + size_t i = fs->strbufpos, len = fs->strbufsize; + int j = 0; + const char* instr = fs->strbuf; + while( i < len && j < maxCount-1 ) + { + char c = instr[i++]; + if( c == '\0' ) + break; + str[j++] = c; + if( c == '\n' ) + break; + } + str[j++] = '\0'; + fs->strbufpos = i; + return j > 1 ? str : 0; + } + if( fs->file ) + return fgets( str, maxCount, fs->file ); +#if USE_ZLIB + if( fs->gzfile ) + return gzgets( fs->gzfile, str, maxCount ); +#endif + CV_Error( CV_StsError, "The storage is not opened" ); + return 0; +} + +static int icvEof( CvFileStorage* fs ) +{ + if( fs->strbuf ) + return fs->strbufpos >= fs->strbufsize; + if( fs->file ) + return feof(fs->file); +#if USE_ZLIB + if( fs->gzfile ) + return gzeof(fs->gzfile); +#endif + return false; +} + +static void icvCloseFile( CvFileStorage* fs ) +{ + if( fs->file ) + fclose( fs->file ); +#if USE_ZLIB + else if( fs->gzfile ) + gzclose( fs->gzfile ); +#endif + fs->file = 0; + fs->gzfile = 0; + fs->strbuf = 0; + fs->strbufpos = 0; + fs->is_opened = false; +} + +static void icvRewind( CvFileStorage* fs ) +{ + if( fs->file ) + rewind(fs->file); +#if USE_ZLIB + else if( fs->gzfile ) + gzrewind(fs->gzfile); +#endif + fs->strbufpos = 0; +} + +#define CV_YML_INDENT 3 +#define CV_XML_INDENT 2 +#define CV_YML_INDENT_FLOW 1 +#define CV_FS_MAX_LEN 4096 + +#define CV_FILE_STORAGE ('Y' + ('A' << 8) + ('M' << 16) + ('L' << 24)) +#define CV_IS_FILE_STORAGE(fs) ((fs) != 0 && (fs)->flags == CV_FILE_STORAGE) + +#define CV_CHECK_FILE_STORAGE(fs) \ +{ \ + if( !CV_IS_FILE_STORAGE(fs) ) \ + CV_Error( (fs) ? CV_StsBadArg : CV_StsNullPtr, \ + "Invalid pointer to file storage" ); \ +} + +#define CV_CHECK_OUTPUT_FILE_STORAGE(fs) \ +{ \ + CV_CHECK_FILE_STORAGE(fs); \ + if( !fs->write_mode ) \ + CV_Error( CV_StsError, "The file storage is opened for reading" ); \ +} + +CV_IMPL const char* +cvAttrValue( const CvAttrList* attr, const char* attr_name ) +{ + while( attr && attr->attr ) + { + int i; + for( i = 0; attr->attr[i*2] != 0; i++ ) + { + if( strcmp( attr_name, attr->attr[i*2] ) == 0 ) + return attr->attr[i*2+1]; + } + attr = attr->next; + } + + return 0; +} + + +static CvGenericHash* +cvCreateMap( int flags, int header_size, int elem_size, + CvMemStorage* storage, int start_tab_size ) +{ + if( header_size < (int)sizeof(CvGenericHash) ) + CV_Error( CV_StsBadSize, "Too small map header_size" ); + + if( start_tab_size <= 0 ) + start_tab_size = 16; + + CvGenericHash* map = (CvGenericHash*)cvCreateSet( flags, header_size, elem_size, storage ); + + map->tab_size = start_tab_size; + start_tab_size *= sizeof(map->table[0]); + map->table = (void**)cvMemStorageAlloc( storage, start_tab_size ); + memset( map->table, 0, start_tab_size ); + + return map; +} + +#ifdef __GNUC__ +#define CV_PARSE_ERROR( errmsg ) \ + icvParseError( fs, __func__, (errmsg), __FILE__, __LINE__ ) +#else +#define CV_PARSE_ERROR( errmsg ) \ + icvParseError( fs, "", (errmsg), __FILE__, __LINE__ ) +#endif + +static void +icvParseError( CvFileStorage* fs, const char* func_name, + const char* err_msg, const char* source_file, int source_line ) +{ + char buf[1<<10]; + sprintf( buf, "%s(%d): %s", fs->filename, fs->lineno, err_msg ); + cvError( CV_StsParseError, func_name, buf, source_file, source_line ); +} + + +static void +icvFSCreateCollection( CvFileStorage* fs, int tag, CvFileNode* collection ) +{ + if( CV_NODE_IS_MAP(tag) ) + { + if( collection->tag != CV_NODE_NONE ) + { + assert( fs->fmt == CV_STORAGE_FORMAT_XML ); + CV_PARSE_ERROR( "Sequence element should not have name (use <_>)" ); + } + + collection->data.map = cvCreateMap( 0, sizeof(CvFileNodeHash), + sizeof(CvFileMapNode), fs->memstorage, 16 ); + } + else + { + CvSeq* seq; + seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvFileNode), fs->memstorage ); + + // if contains some scalar element, add it to the newly created collection + if( CV_NODE_TYPE(collection->tag) != CV_NODE_NONE ) + cvSeqPush( seq, collection ); + + collection->data.seq = seq; + } + + collection->tag = tag; + cvSetSeqBlockSize( collection->data.seq, 8 ); +} + + +/*static void +icvFSReleaseCollection( CvSeq* seq ) +{ + if( seq ) + { + int is_map = CV_IS_SET(seq); + CvSeqReader reader; + int i, total = seq->total; + cvStartReadSeq( seq, &reader, 0 ); + + for( i = 0; i < total; i++ ) + { + CvFileNode* node = (CvFileNode*)reader.ptr; + + if( (!is_map || CV_IS_SET_ELEM( node )) && CV_NODE_IS_COLLECTION(node->tag) ) + { + if( CV_NODE_IS_USER(node->tag) && node->info && node->data.obj.decoded ) + cvRelease( (void**)&node->data.obj.decoded ); + if( !CV_NODE_SEQ_IS_SIMPLE( node->data.seq )) + icvFSReleaseCollection( node->data.seq ); + } + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + } + } +}*/ + + +static char* +icvFSDoResize( CvFileStorage* fs, char* ptr, int len ) +{ + char* new_ptr = 0; + int written_len = (int)(ptr - fs->buffer_start); + int new_size = (int)((fs->buffer_end - fs->buffer_start)*3/2); + new_size = MAX( written_len + len, new_size ); + new_ptr = (char*)cvAlloc( new_size + 256 ); + fs->buffer = new_ptr + (fs->buffer - fs->buffer_start); + if( written_len > 0 ) + memcpy( new_ptr, fs->buffer_start, written_len ); + fs->buffer_start = new_ptr; + fs->buffer_end = fs->buffer_start + new_size; + new_ptr += written_len; + return new_ptr; +} + + +inline char* icvFSResizeWriteBuffer( CvFileStorage* fs, char* ptr, int len ) +{ + return ptr + len < fs->buffer_end ? ptr : icvFSDoResize( fs, ptr, len ); +} + + +static char* +icvFSFlush( CvFileStorage* fs ) +{ + char* ptr = fs->buffer; + int indent; + + if( ptr > fs->buffer_start + fs->space ) + { + ptr[0] = '\n'; + ptr[1] = '\0'; + icvPuts( fs, fs->buffer_start ); + fs->buffer = fs->buffer_start; + } + + indent = fs->struct_indent; + + if( fs->space != indent ) + { + if( fs->space < indent ) + memset( fs->buffer_start + fs->space, ' ', indent - fs->space ); + fs->space = indent; + } + + ptr = fs->buffer = fs->buffer_start + fs->space; + + return ptr; +} + + +static void +icvClose( CvFileStorage* fs, std::string* out ) +{ + if( out ) + out->clear(); + + if( !fs ) + CV_Error( CV_StsNullPtr, "NULL double pointer to file storage" ); + + if( fs->is_opened ) + { + if( fs->write_mode && (fs->file || fs->gzfile || fs->outbuf) ) + { + if( fs->write_stack ) + { + while( fs->write_stack->total > 0 ) + cvEndWriteStruct(fs); + } + icvFSFlush(fs); + if( fs->fmt == CV_STORAGE_FORMAT_XML ) + icvPuts( fs, "\n" ); + } + + icvCloseFile(fs); + } + + if( fs->outbuf && out ) + { + out->resize(fs->outbuf->size()); + std::copy(fs->outbuf->begin(), fs->outbuf->end(), out->begin()); + } +} + + +/* closes file storage and deallocates buffers */ +CV_IMPL void +cvReleaseFileStorage( CvFileStorage** p_fs ) +{ + if( !p_fs ) + CV_Error( CV_StsNullPtr, "NULL double pointer to file storage" ); + + if( *p_fs ) + { + CvFileStorage* fs = *p_fs; + *p_fs = 0; + + icvClose(fs, 0); + + cvReleaseMemStorage( &fs->strstorage ); + cvFree( &fs->buffer_start ); + cvReleaseMemStorage( &fs->memstorage ); + + if( fs->outbuf ) + delete fs->outbuf; + + memset( fs, 0, sizeof(*fs) ); + cvFree( &fs ); + } +} + + +#define CV_HASHVAL_SCALE 33 + +CV_IMPL CvStringHashNode* +cvGetHashedKey( CvFileStorage* fs, const char* str, int len, int create_missing ) +{ + CvStringHashNode* node = 0; + unsigned hashval = 0; + int i, tab_size; + + if( !fs ) + return 0; + + CvStringHash* map = fs->str_hash; + + if( len < 0 ) + { + for( i = 0; str[i] != '\0'; i++ ) + hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i]; + len = i; + } + else for( i = 0; i < len; i++ ) + hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i]; + + hashval &= INT_MAX; + tab_size = map->tab_size; + if( (tab_size & (tab_size - 1)) == 0 ) + i = (int)(hashval & (tab_size - 1)); + else + i = (int)(hashval % tab_size); + + for( node = (CvStringHashNode*)(map->table[i]); node != 0; node = node->next ) + { + if( node->hashval == hashval && + node->str.len == len && + memcmp( node->str.ptr, str, len ) == 0 ) + break; + } + + if( !node && create_missing ) + { + node = (CvStringHashNode*)cvSetNew( (CvSet*)map ); + node->hashval = hashval; + node->str = cvMemStorageAllocString( map->storage, str, len ); + node->next = (CvStringHashNode*)(map->table[i]); + map->table[i] = node; + } + + return node; +} + + +CV_IMPL CvFileNode* +cvGetFileNode( CvFileStorage* fs, CvFileNode* _map_node, + const CvStringHashNode* key, + int create_missing ) +{ + CvFileNode* value = 0; + int k = 0, attempts = 1; + + if( !fs ) + return 0; + + CV_CHECK_FILE_STORAGE(fs); + + if( !key ) + CV_Error( CV_StsNullPtr, "Null key element" ); + + if( _map_node ) + { + if( !fs->roots ) + return 0; + attempts = fs->roots->total; + } + + for( k = 0; k < attempts; k++ ) + { + int i, tab_size; + CvFileNode* map_node = _map_node; + CvFileMapNode* another; + CvFileNodeHash* map; + + if( !map_node ) + map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k ); + + if( !CV_NODE_IS_MAP(map_node->tag) ) + { + if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) && + CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE ) + CV_Error( CV_StsError, "The node is neither a map nor an empty collection" ); + return 0; + } + + map = map_node->data.map; + tab_size = map->tab_size; + + if( (tab_size & (tab_size - 1)) == 0 ) + i = (int)(key->hashval & (tab_size - 1)); + else + i = (int)(key->hashval % tab_size); + + for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next ) + if( another->key == key ) + { + if( !create_missing ) + { + value = &another->value; + return value; + } + CV_PARSE_ERROR( "Duplicated key" ); + } + + if( k == attempts - 1 && create_missing ) + { + CvFileMapNode* node = (CvFileMapNode*)cvSetNew( (CvSet*)map ); + node->key = key; + + node->next = (CvFileMapNode*)(map->table[i]); + map->table[i] = node; + value = (CvFileNode*)node; + } + } + + return value; +} + + +CV_IMPL CvFileNode* +cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* _map_node, const char* str ) +{ + CvFileNode* value = 0; + int i, len, tab_size; + unsigned hashval = 0; + int k = 0, attempts = 1; + + if( !fs ) + return 0; + + CV_CHECK_FILE_STORAGE(fs); + + if( !str ) + CV_Error( CV_StsNullPtr, "Null element name" ); + + for( i = 0; str[i] != '\0'; i++ ) + hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i]; + hashval &= INT_MAX; + len = i; + + if( !_map_node ) + { + if( !fs->roots ) + return 0; + attempts = fs->roots->total; + } + + for( k = 0; k < attempts; k++ ) + { + CvFileNodeHash* map; + const CvFileNode* map_node = _map_node; + CvFileMapNode* another; + + if( !map_node ) + map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k ); + + if( !CV_NODE_IS_MAP(map_node->tag) ) + { + if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) && + CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE ) + CV_Error( CV_StsError, "The node is neither a map nor an empty collection" ); + return 0; + } + + map = map_node->data.map; + tab_size = map->tab_size; + + if( (tab_size & (tab_size - 1)) == 0 ) + i = (int)(hashval & (tab_size - 1)); + else + i = (int)(hashval % tab_size); + + for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next ) + { + const CvStringHashNode* key = another->key; + + if( key->hashval == hashval && + key->str.len == len && + memcmp( key->str.ptr, str, len ) == 0 ) + { + value = &another->value; + return value; + } + } + } + + return value; +} + + +CV_IMPL CvFileNode* +cvGetRootFileNode( const CvFileStorage* fs, int stream_index ) +{ + CV_CHECK_FILE_STORAGE(fs); + + if( !fs->roots || (unsigned)stream_index >= (unsigned)fs->roots->total ) + return 0; + + return (CvFileNode*)cvGetSeqElem( fs->roots, stream_index ); +} + + +/* returns the sequence element by its index */ +/*CV_IMPL CvFileNode* +cvGetFileNodeFromSeq( CvFileStorage* fs, + CvFileNode* seq_node, int index ) +{ + CvFileNode* value = 0; + CvSeq* seq; + + if( !seq_node ) + seq = fs->roots; + else if( !CV_NODE_IS_SEQ(seq_node->tag) ) + { + if( CV_NODE_IS_MAP(seq_node->tag) ) + CV_Error( CV_StsError, "The node is map. Use cvGetFileNodeFromMap()." ); + if( CV_NODE_TYPE(seq_node->tag) == CV_NODE_NONE ) + CV_Error( CV_StsError, "The node is an empty object (None)." ); + if( index != 0 && index != -1 ) + CV_Error( CV_StsOutOfRange, "" ); + value = seq_node; + EXIT; + } + else + seq = seq_node->data.seq; + + if( !seq ) + CV_Error( CV_StsNullPtr, "The file storage is empty" ); + + value = (CvFileNode*)cvGetSeqElem( seq, index, 0 ); + + + + return value; +}*/ + + +static char* +icvDoubleToString( char* buf, double value ) +{ + Cv64suf val; + unsigned ieee754_hi; + + val.f = value; + ieee754_hi = (unsigned)(val.u >> 32); + + if( (ieee754_hi & 0x7ff00000) != 0x7ff00000 ) + { + int ivalue = cvRound(value); + if( ivalue == value ) + sprintf( buf, "%d.", ivalue ); + else + { + static const char* fmt = "%.16e"; + char* ptr = buf; + sprintf( buf, fmt, value ); + if( *ptr == '+' || *ptr == '-' ) + ptr++; + for( ; cv_isdigit(*ptr); ptr++ ) + ; + if( *ptr == ',' ) + *ptr = '.'; + } + } + else + { + unsigned ieee754_lo = (unsigned)val.u; + if( (ieee754_hi & 0x7fffffff) + (ieee754_lo != 0) > 0x7ff00000 ) + strcpy( buf, ".Nan" ); + else + strcpy( buf, (int)ieee754_hi < 0 ? "-.Inf" : ".Inf" ); + } + + return buf; +} + + +static char* +icvFloatToString( char* buf, float value ) +{ + Cv32suf val; + unsigned ieee754; + val.f = value; + ieee754 = val.u; + + if( (ieee754 & 0x7f800000) != 0x7f800000 ) + { + int ivalue = cvRound(value); + if( ivalue == value ) + sprintf( buf, "%d.", ivalue ); + else + { + static const char* fmt = "%.8e"; + char* ptr = buf; + sprintf( buf, fmt, value ); + if( *ptr == '+' || *ptr == '-' ) + ptr++; + for( ; cv_isdigit(*ptr); ptr++ ) + ; + if( *ptr == ',' ) + *ptr = '.'; + } + } + else + { + if( (ieee754 & 0x7fffffff) != 0x7f800000 ) + strcpy( buf, ".Nan" ); + else + strcpy( buf, (int)ieee754 < 0 ? "-.Inf" : ".Inf" ); + } + + return buf; +} + + +static void +icvProcessSpecialDouble( CvFileStorage* fs, char* buf, double* value, char** endptr ) +{ + char c = buf[0]; + int inf_hi = 0x7ff00000; + + if( c == '-' || c == '+' ) + { + inf_hi = c == '-' ? 0xfff00000 : 0x7ff00000; + c = *++buf; + } + + if( c != '.' ) + CV_PARSE_ERROR( "Bad format of floating-point constant" ); + + union{double d; uint64 i;} v; + v.d = 0.; + if( toupper(buf[1]) == 'I' && toupper(buf[2]) == 'N' && toupper(buf[3]) == 'F' ) + v.i = (uint64)inf_hi << 32; + else if( toupper(buf[1]) == 'N' && toupper(buf[2]) == 'A' && toupper(buf[3]) == 'N' ) + v.i = (uint64)-1; + else + CV_PARSE_ERROR( "Bad format of floating-point constant" ); + *value = v.d; + + *endptr = buf + 4; +} + + +static double icv_strtod( CvFileStorage* fs, char* ptr, char** endptr ) +{ + double fval = strtod( ptr, endptr ); + if( **endptr == '.' ) + { + char* dot_pos = *endptr; + *dot_pos = ','; + double fval2 = strtod( ptr, endptr ); + *dot_pos = '.'; + if( *endptr > dot_pos ) + fval = fval2; + else + *endptr = dot_pos; + } + + if( *endptr == ptr || cv_isalpha(**endptr) ) + icvProcessSpecialDouble( fs, ptr, &fval, endptr ); + + return fval; +} + + +/****************************************************************************************\ +* YAML Parser * +\****************************************************************************************/ + +static char* +icvYMLSkipSpaces( CvFileStorage* fs, char* ptr, int min_indent, int max_comment_indent ) +{ + for(;;) + { + while( *ptr == ' ' ) + ptr++; + if( *ptr == '#' ) + { + if( ptr - fs->buffer_start > max_comment_indent ) + return ptr; + *ptr = '\0'; + } + else if( cv_isprint(*ptr) ) + { + if( ptr - fs->buffer_start < min_indent ) + CV_PARSE_ERROR( "Incorrect indentation" ); + break; + } + else if( *ptr == '\0' || *ptr == '\n' || *ptr == '\r' ) + { + int max_size = (int)(fs->buffer_end - fs->buffer_start); + ptr = icvGets( fs, fs->buffer_start, max_size ); + if( !ptr ) + { + // emulate end of stream + ptr = fs->buffer_start; + ptr[0] = ptr[1] = ptr[2] = '.'; + ptr[3] = '\0'; + fs->dummy_eof = 1; + break; + } + else + { + int l = (int)strlen(ptr); + if( ptr[l-1] != '\n' && ptr[l-1] != '\r' && !icvEof(fs) ) + CV_PARSE_ERROR( "Too long string or a last string w/o newline" ); + } + + fs->lineno++; + } + else + CV_PARSE_ERROR( *ptr == '\t' ? "Tabs are prohibited in YAML!" : "Invalid character" ); + } + + return ptr; +} + + +static char* +icvYMLParseKey( CvFileStorage* fs, char* ptr, + CvFileNode* map_node, CvFileNode** value_placeholder ) +{ + char c; + char *endptr = ptr - 1, *saveptr; + CvStringHashNode* str_hash_node; + + if( *ptr == '-' ) + CV_PARSE_ERROR( "Key may not start with \'-\'" ); + + do c = *++endptr; + while( cv_isprint(c) && c != ':' ); + + if( c != ':' ) + CV_PARSE_ERROR( "Missing \':\'" ); + + saveptr = endptr + 1; + do c = *--endptr; + while( c == ' ' ); + + ++endptr; + if( endptr == ptr ) + CV_PARSE_ERROR( "An empty key" ); + + str_hash_node = cvGetHashedKey( fs, ptr, (int)(endptr - ptr), 1 ); + *value_placeholder = cvGetFileNode( fs, map_node, str_hash_node, 1 ); + ptr = saveptr; + + return ptr; +} + + +static char* +icvYMLParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node, + int parent_flags, int min_indent ) +{ + char buf[CV_FS_MAX_LEN + 1024]; + char* endptr = 0; + char c = ptr[0], d = ptr[1]; + int is_parent_flow = CV_NODE_IS_FLOW(parent_flags); + int value_type = CV_NODE_NONE; + int len; + + memset( node, 0, sizeof(*node) ); + + if( c == '!' ) // handle explicit type specification + { + if( d == '!' || d == '^' ) + { + ptr++; + value_type |= CV_NODE_USER; + } + + endptr = ptr++; + do d = *++endptr; + while( cv_isprint(d) && d != ' ' ); + len = (int)(endptr - ptr); + if( len == 0 ) + CV_PARSE_ERROR( "Empty type name" ); + d = *endptr; + *endptr = '\0'; + + if( len == 3 && !CV_NODE_IS_USER(value_type) ) + { + if( memcmp( ptr, "str", 3 ) == 0 ) + value_type = CV_NODE_STRING; + else if( memcmp( ptr, "int", 3 ) == 0 ) + value_type = CV_NODE_INT; + else if( memcmp( ptr, "seq", 3 ) == 0 ) + value_type = CV_NODE_SEQ; + else if( memcmp( ptr, "map", 3 ) == 0 ) + value_type = CV_NODE_MAP; + } + else if( len == 5 && !CV_NODE_IS_USER(value_type) ) + { + if( memcmp( ptr, "float", 5 ) == 0 ) + value_type = CV_NODE_REAL; + } + else if( CV_NODE_IS_USER(value_type) ) + { + node->info = cvFindType( ptr ); + if( !node->info ) + node->tag &= ~CV_NODE_USER; + } + + *endptr = d; + ptr = icvYMLSkipSpaces( fs, endptr, min_indent, INT_MAX ); + + c = *ptr; + + if( !CV_NODE_IS_USER(value_type) ) + { + if( value_type == CV_NODE_STRING && c != '\'' && c != '\"' ) + goto force_string; + if( value_type == CV_NODE_INT ) + goto force_int; + if( value_type == CV_NODE_REAL ) + goto force_real; + } + } + + if( cv_isdigit(c) || + ((c == '-' || c == '+') && (cv_isdigit(d) || d == '.')) || + (c == '.' && cv_isalnum(d))) // a number + { + double fval; + int ival; + endptr = ptr + (c == '-' || c == '+'); + while( cv_isdigit(*endptr) ) + endptr++; + if( *endptr == '.' || *endptr == 'e' ) + { +force_real: + fval = icv_strtod( fs, ptr, &endptr ); + /*if( endptr == ptr || cv_isalpha(*endptr) ) + icvProcessSpecialDouble( fs, endptr, &fval, &endptr ));*/ + + node->tag = CV_NODE_REAL; + node->data.f = fval; + } + else + { +force_int: + ival = (int)strtol( ptr, &endptr, 0 ); + node->tag = CV_NODE_INT; + node->data.i = ival; + } + + if( !endptr || endptr == ptr ) + CV_PARSE_ERROR( "Invalid numeric value (inconsistent explicit type specification?)" ); + + ptr = endptr; + } + else if( c == '\'' || c == '\"' ) // an explicit string + { + node->tag = CV_NODE_STRING; + if( c == '\'' ) + for( len = 0; len < CV_FS_MAX_LEN; ) + { + c = *++ptr; + if( cv_isalnum(c) || (c != '\'' && cv_isprint(c))) + buf[len++] = c; + else if( c == '\'' ) + { + c = *++ptr; + if( c != '\'' ) + break; + buf[len++] = c; + } + else + CV_PARSE_ERROR( "Invalid character" ); + } + else + for( len = 0; len < CV_FS_MAX_LEN; ) + { + c = *++ptr; + if( cv_isalnum(c) || (c != '\\' && c != '\"' && cv_isprint(c))) + buf[len++] = c; + else if( c == '\"' ) + { + ++ptr; + break; + } + else if( c == '\\' ) + { + d = *++ptr; + if( d == '\'' ) + buf[len++] = d; + else if( d == '\"' || d == '\\' || d == '\'' ) + buf[len++] = d; + else if( d == 'n' ) + buf[len++] = '\n'; + else if( d == 'r' ) + buf[len++] = '\r'; + else if( d == 't' ) + buf[len++] = '\t'; + else if( d == 'x' || (cv_isdigit(d) && d < '8') ) + { + int val, is_hex = d == 'x'; + c = ptr[3]; + ptr[3] = '\0'; + val = strtol( ptr + is_hex, &endptr, is_hex ? 8 : 16 ); + ptr[3] = c; + if( endptr == ptr + is_hex ) + buf[len++] = 'x'; + else + { + buf[len++] = (char)val; + ptr = endptr; + } + } + } + else + CV_PARSE_ERROR( "Invalid character" ); + } + + if( len >= CV_FS_MAX_LEN ) + CV_PARSE_ERROR( "Too long string literal" ); + + node->data.str = cvMemStorageAllocString( fs->memstorage, buf, len ); + } + else if( c == '[' || c == '{' ) // collection as a flow + { + int new_min_indent = min_indent + !is_parent_flow; + int struct_flags = CV_NODE_FLOW + (c == '{' ? CV_NODE_MAP : CV_NODE_SEQ); + int is_simple = 1; + + icvFSCreateCollection( fs, CV_NODE_TYPE(struct_flags) + + (node->info ? CV_NODE_USER : 0), node ); + + d = c == '[' ? ']' : '}'; + + for( ++ptr ;;) + { + CvFileNode* elem = 0; + + ptr = icvYMLSkipSpaces( fs, ptr, new_min_indent, INT_MAX ); + if( *ptr == '}' || *ptr == ']' ) + { + if( *ptr != d ) + CV_PARSE_ERROR( "The wrong closing bracket" ); + ptr++; + break; + } + + if( node->data.seq->total != 0 ) + { + if( *ptr != ',' ) + CV_PARSE_ERROR( "Missing , between the elements" ); + ptr = icvYMLSkipSpaces( fs, ptr + 1, new_min_indent, INT_MAX ); + } + + if( CV_NODE_IS_MAP(struct_flags) ) + { + ptr = icvYMLParseKey( fs, ptr, node, &elem ); + ptr = icvYMLSkipSpaces( fs, ptr, new_min_indent, INT_MAX ); + } + else + { + if( *ptr == ']' ) + break; + elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 ); + } + ptr = icvYMLParseValue( fs, ptr, elem, struct_flags, new_min_indent ); + if( CV_NODE_IS_MAP(struct_flags) ) + elem->tag |= CV_NODE_NAMED; + is_simple &= !CV_NODE_IS_COLLECTION(elem->tag); + } + node->data.seq->flags |= is_simple ? CV_NODE_SEQ_SIMPLE : 0; + } + else + { + int indent, struct_flags, is_simple; + + if( is_parent_flow || c != '-' ) + { + // implicit (one-line) string or nested block-style collection + if( !is_parent_flow ) + { + if( c == '?' ) + CV_PARSE_ERROR( "Complex keys are not supported" ); + if( c == '|' || c == '>' ) + CV_PARSE_ERROR( "Multi-line text literals are not supported" ); + } + +force_string: + endptr = ptr - 1; + + do c = *++endptr; + while( cv_isprint(c) && + (!is_parent_flow || (c != ',' && c != '}' && c != ']')) && + (is_parent_flow || c != ':' || value_type == CV_NODE_STRING)); + + if( endptr == ptr ) + CV_PARSE_ERROR( "Invalid character" ); + + if( is_parent_flow || c != ':' ) + { + char* str_end = endptr; + node->tag = CV_NODE_STRING; + // strip spaces in the end of string + do c = *--str_end; + while( str_end > ptr && c == ' ' ); + str_end++; + node->data.str = cvMemStorageAllocString( fs->memstorage, ptr, (int)(str_end - ptr) ); + ptr = endptr; + return ptr; + } + struct_flags = CV_NODE_MAP; + } + else + struct_flags = CV_NODE_SEQ; + + icvFSCreateCollection( fs, struct_flags + + (node->info ? CV_NODE_USER : 0), node ); + + indent = (int)(ptr - fs->buffer_start); + is_simple = 1; + + for(;;) + { + CvFileNode* elem = 0; + + if( CV_NODE_IS_MAP(struct_flags) ) + { + ptr = icvYMLParseKey( fs, ptr, node, &elem ); + } + else + { + c = *ptr++; + if( c != '-' ) + CV_PARSE_ERROR( "Block sequence elements must be preceded with \'-\'" ); + + elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 ); + } + + ptr = icvYMLSkipSpaces( fs, ptr, indent + 1, INT_MAX ); + ptr = icvYMLParseValue( fs, ptr, elem, struct_flags, indent + 1 ); + if( CV_NODE_IS_MAP(struct_flags) ) + elem->tag |= CV_NODE_NAMED; + is_simple &= !CV_NODE_IS_COLLECTION(elem->tag); + + ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ); + if( ptr - fs->buffer_start != indent ) + { + if( ptr - fs->buffer_start < indent ) + break; + else + CV_PARSE_ERROR( "Incorrect indentation" ); + } + if( memcmp( ptr, "...", 3 ) == 0 ) + break; + } + + node->data.seq->flags |= is_simple ? CV_NODE_SEQ_SIMPLE : 0; + } + + return ptr; +} + + +static void +icvYMLParse( CvFileStorage* fs ) +{ + char* ptr = fs->buffer_start; + int is_first = 1; + + for(;;) + { + // 0. skip leading comments and directives and ... + // 1. reach the first item + for(;;) + { + ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ); + if( !ptr ) + return; + + if( *ptr == '%' ) + { + if( memcmp( ptr, "%YAML:", 6 ) == 0 && + memcmp( ptr, "%YAML:1.", 8 ) != 0 ) + CV_PARSE_ERROR( "Unsupported YAML version (it must be 1.x)" ); + *ptr = '\0'; + } + else if( *ptr == '-' ) + { + if( memcmp(ptr, "---", 3) == 0 ) + { + ptr += 3; + break; + } + else if( is_first ) + break; + } + else if( cv_isalnum(*ptr) || *ptr=='_') + { + if( !is_first ) + CV_PARSE_ERROR( "The YAML streams must start with '---', except the first one" ); + break; + } + else if( fs->dummy_eof ) + break; + else + CV_PARSE_ERROR( "Invalid or unsupported syntax" ); + } + + ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ); + if( memcmp( ptr, "...", 3 ) != 0 ) + { + // 2. parse the collection + CvFileNode* root_node = (CvFileNode*)cvSeqPush( fs->roots, 0 ); + + ptr = icvYMLParseValue( fs, ptr, root_node, CV_NODE_NONE, 0 ); + if( !CV_NODE_IS_COLLECTION(root_node->tag) ) + CV_PARSE_ERROR( "Only collections as YAML streams are supported by this parser" ); + + // 3. parse until the end of file or next collection + ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ); + if( !ptr ) + return; + } + + if( fs->dummy_eof ) + break; + ptr += 3; + is_first = 0; + } +} + + +/****************************************************************************************\ +* YAML Emitter * +\****************************************************************************************/ + +static void +icvYMLWrite( CvFileStorage* fs, const char* key, const char* data ) +{ + int i, keylen = 0; + int datalen = 0; + int struct_flags; + char* ptr; + + struct_flags = fs->struct_flags; + + if( key && key[0] == '\0' ) + key = 0; + + if( CV_NODE_IS_COLLECTION(struct_flags) ) + { + if( (CV_NODE_IS_MAP(struct_flags) ^ (key != 0)) ) + CV_Error( CV_StsBadArg, "An attempt to add element without a key to a map, " + "or add element with key to sequence" ); + } + else + { + fs->is_first = 0; + struct_flags = CV_NODE_EMPTY | (key ? CV_NODE_MAP : CV_NODE_SEQ); + } + + if( key ) + { + keylen = (int)strlen(key); + if( keylen == 0 ) + CV_Error( CV_StsBadArg, "The key is an empty" ); + + if( keylen > CV_FS_MAX_LEN ) + CV_Error( CV_StsBadArg, "The key is too long" ); + } + + if( data ) + datalen = (int)strlen(data); + + if( CV_NODE_IS_FLOW(struct_flags) ) + { + int new_offset; + ptr = fs->buffer; + if( !CV_NODE_IS_EMPTY(struct_flags) ) + *ptr++ = ','; + new_offset = (int)(ptr - fs->buffer_start) + keylen + datalen; + if( new_offset > fs->wrap_margin && new_offset - fs->struct_indent > 10 ) + { + fs->buffer = ptr; + ptr = icvFSFlush(fs); + } + else + *ptr++ = ' '; + } + else + { + ptr = icvFSFlush(fs); + if( !CV_NODE_IS_MAP(struct_flags) ) + { + *ptr++ = '-'; + if( data ) + *ptr++ = ' '; + } + } + + if( key ) + { + if( !cv_isalpha(key[0]) && key[0] != '_' ) + CV_Error( CV_StsBadArg, "Key must start with a letter or _" ); + + ptr = icvFSResizeWriteBuffer( fs, ptr, keylen ); + + for( i = 0; i < keylen; i++ ) + { + char c = key[i]; + + ptr[i] = c; + if( !cv_isalnum(c) && c != '-' && c != '_' && c != ' ' ) + CV_Error( CV_StsBadArg, "Key names may only contain alphanumeric characters [a-zA-Z0-9], '-', '_' and ' '" ); + } + + ptr += keylen; + *ptr++ = ':'; + if( !CV_NODE_IS_FLOW(struct_flags) && data ) + *ptr++ = ' '; + } + + if( data ) + { + ptr = icvFSResizeWriteBuffer( fs, ptr, datalen ); + memcpy( ptr, data, datalen ); + ptr += datalen; + } + + fs->buffer = ptr; + fs->struct_flags = struct_flags & ~CV_NODE_EMPTY; +} + + +static void +icvYMLStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, + const char* type_name CV_DEFAULT(0)) +{ + int parent_flags; + char buf[CV_FS_MAX_LEN + 1024]; + const char* data = 0; + + struct_flags = (struct_flags & (CV_NODE_TYPE_MASK|CV_NODE_FLOW)) | CV_NODE_EMPTY; + if( !CV_NODE_IS_COLLECTION(struct_flags)) + CV_Error( CV_StsBadArg, + "Some collection type - CV_NODE_SEQ or CV_NODE_MAP, must be specified" ); + + if( CV_NODE_IS_FLOW(struct_flags) ) + { + char c = CV_NODE_IS_MAP(struct_flags) ? '{' : '['; + struct_flags |= CV_NODE_FLOW; + + if( type_name ) + sprintf( buf, "!!%s %c", type_name, c ); + else + { + buf[0] = c; + buf[1] = '\0'; + } + data = buf; + } + else if( type_name ) + { + sprintf( buf, "!!%s", type_name ); + data = buf; + } + + icvYMLWrite( fs, key, data ); + + parent_flags = fs->struct_flags; + cvSeqPush( fs->write_stack, &parent_flags ); + fs->struct_flags = struct_flags; + + if( !CV_NODE_IS_FLOW(parent_flags) ) + fs->struct_indent += CV_YML_INDENT + CV_NODE_IS_FLOW(struct_flags); +} + + +static void +icvYMLEndWriteStruct( CvFileStorage* fs ) +{ + int parent_flags = 0, struct_flags; + char* ptr; + + struct_flags = fs->struct_flags; + if( fs->write_stack->total == 0 ) + CV_Error( CV_StsError, "EndWriteStruct w/o matching StartWriteStruct" ); + + cvSeqPop( fs->write_stack, &parent_flags ); + + if( CV_NODE_IS_FLOW(struct_flags) ) + { + ptr = fs->buffer; + if( ptr > fs->buffer_start + fs->struct_indent && !CV_NODE_IS_EMPTY(struct_flags) ) + *ptr++ = ' '; + *ptr++ = CV_NODE_IS_MAP(struct_flags) ? '}' : ']'; + fs->buffer = ptr; + } + else if( CV_NODE_IS_EMPTY(struct_flags) ) + { + ptr = icvFSFlush(fs); + memcpy( ptr, CV_NODE_IS_MAP(struct_flags) ? "{}" : "[]", 2 ); + fs->buffer = ptr + 2; + } + + if( !CV_NODE_IS_FLOW(parent_flags) ) + fs->struct_indent -= CV_YML_INDENT + CV_NODE_IS_FLOW(struct_flags); + assert( fs->struct_indent >= 0 ); + + fs->struct_flags = parent_flags; +} + + +static void +icvYMLStartNextStream( CvFileStorage* fs ) +{ + if( !fs->is_first ) + { + while( fs->write_stack->total > 0 ) + icvYMLEndWriteStruct(fs); + + fs->struct_indent = 0; + icvFSFlush(fs); + icvPuts( fs, "...\n" ); + icvPuts( fs, "---\n" ); + fs->buffer = fs->buffer_start; + } +} + + +static void +icvYMLWriteInt( CvFileStorage* fs, const char* key, int value ) +{ + char buf[128]; + icvYMLWrite( fs, key, icv_itoa( value, buf, 10 )); +} + + +static void +icvYMLWriteReal( CvFileStorage* fs, const char* key, double value ) +{ + char buf[128]; + icvYMLWrite( fs, key, icvDoubleToString( buf, value )); +} + + +static void +icvYMLWriteString( CvFileStorage* fs, const char* key, + const char* str, int quote CV_DEFAULT(0)) +{ + char buf[CV_FS_MAX_LEN*4+16]; + char* data = (char*)str; + int i, len; + + if( !str ) + CV_Error( CV_StsNullPtr, "Null string pointer" ); + + len = (int)strlen(str); + if( len > CV_FS_MAX_LEN ) + CV_Error( CV_StsBadArg, "The written string is too long" ); + + if( quote || len == 0 || str[0] != str[len-1] || (str[0] != '\"' && str[0] != '\'') ) + { + int need_quote = quote || len == 0; + data = buf; + *data++ = '\"'; + for( i = 0; i < len; i++ ) + { + char c = str[i]; + + if( !need_quote && !cv_isalnum(c) && c != '_' && c != ' ' && c != '-' && + c != '(' && c != ')' && c != '/' && c != '+' && c != ';' ) + need_quote = 1; + + if( !cv_isalnum(c) && (!cv_isprint(c) || c == '\\' || c == '\'' || c == '\"') ) + { + *data++ = '\\'; + if( cv_isprint(c) ) + *data++ = c; + else if( c == '\n' ) + *data++ = 'n'; + else if( c == '\r' ) + *data++ = 'r'; + else if( c == '\t' ) + *data++ = 't'; + else + { + sprintf( data, "x%02x", c ); + data += 3; + } + } + else + *data++ = c; + } + if( !need_quote && (cv_isdigit(str[0]) || + str[0] == '+' || str[0] == '-' || str[0] == '.' )) + need_quote = 1; + + if( need_quote ) + *data++ = '\"'; + *data++ = '\0'; + data = buf + !need_quote; + } + + icvYMLWrite( fs, key, data ); +} + + +static void +icvYMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment ) +{ + int len; //, indent; + int multiline; + const char* eol; + char* ptr; + + if( !comment ) + CV_Error( CV_StsNullPtr, "Null comment" ); + + len = (int)strlen(comment); + eol = strchr(comment, '\n'); + multiline = eol != 0; + ptr = fs->buffer; + + if( !eol_comment || multiline || + fs->buffer_end - ptr < len || ptr == fs->buffer_start ) + ptr = icvFSFlush( fs ); + else + *ptr++ = ' '; + + while( comment ) + { + *ptr++ = '#'; + *ptr++ = ' '; + if( eol ) + { + ptr = icvFSResizeWriteBuffer( fs, ptr, (int)(eol - comment) + 1 ); + memcpy( ptr, comment, eol - comment + 1 ); + fs->buffer = ptr + (eol - comment); + comment = eol + 1; + eol = strchr( comment, '\n' ); + } + else + { + len = (int)strlen(comment); + ptr = icvFSResizeWriteBuffer( fs, ptr, len ); + memcpy( ptr, comment, len ); + fs->buffer = ptr + len; + comment = 0; + } + ptr = icvFSFlush( fs ); + } +} + + +/****************************************************************************************\ +* XML Parser * +\****************************************************************************************/ + +#define CV_XML_INSIDE_COMMENT 1 +#define CV_XML_INSIDE_TAG 2 +#define CV_XML_INSIDE_DIRECTIVE 3 + +static char* +icvXMLSkipSpaces( CvFileStorage* fs, char* ptr, int mode ) +{ + int level = 0; + + for(;;) + { + char c; + ptr--; + + if( mode == CV_XML_INSIDE_COMMENT ) + { + do c = *++ptr; + while( cv_isprint_or_tab(c) && (c != '-' || ptr[1] != '-' || ptr[2] != '>') ); + + if( c == '-' ) + { + assert( ptr[1] == '-' && ptr[2] == '>' ); + mode = 0; + ptr += 3; + } + } + else if( mode == CV_XML_INSIDE_DIRECTIVE ) + { + // !!!NOTE!!! This is not quite correct, but should work in most cases + do + { + c = *++ptr; + level += c == '<'; + level -= c == '>'; + if( level < 0 ) + return ptr; + } while( cv_isprint_or_tab(c) ); + } + else + { + do c = *++ptr; + while( c == ' ' || c == '\t' ); + + if( c == '<' && ptr[1] == '!' && ptr[2] == '-' && ptr[3] == '-' ) + { + if( mode != 0 ) + CV_PARSE_ERROR( "Comments are not allowed here" ); + mode = CV_XML_INSIDE_COMMENT; + ptr += 4; + } + else if( cv_isprint(c) ) + break; + } + + if( !cv_isprint(*ptr) ) + { + int max_size = (int)(fs->buffer_end - fs->buffer_start); + if( *ptr != '\0' && *ptr != '\n' && *ptr != '\r' ) + CV_PARSE_ERROR( "Invalid character in the stream" ); + ptr = icvGets( fs, fs->buffer_start, max_size ); + if( !ptr ) + { + ptr = fs->buffer_start; + *ptr = '\0'; + fs->dummy_eof = 1; + break; + } + else + { + int l = (int)strlen(ptr); + if( ptr[l-1] != '\n' && ptr[l-1] != '\r' && !icvEof(fs) ) + CV_PARSE_ERROR( "Too long string or a last string w/o newline" ); + } + fs->lineno++; + } + } + return ptr; +} + + +static char* +icvXMLParseTag( CvFileStorage* fs, char* ptr, CvStringHashNode** _tag, + CvAttrList** _list, int* _tag_type ); + +static char* +icvXMLParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node, + int value_type CV_DEFAULT(CV_NODE_NONE)) +{ + CvFileNode *elem = node; + int have_space = 1, is_simple = 1; + int is_user_type = CV_NODE_IS_USER(value_type); + memset( node, 0, sizeof(*node) ); + + value_type = CV_NODE_TYPE(value_type); + + for(;;) + { + char c = *ptr, d; + char* endptr; + + if( cv_isspace(c) || c == '\0' || (c == '<' && ptr[1] == '!' && ptr[2] == '-') ) + { + ptr = icvXMLSkipSpaces( fs, ptr, 0 ); + have_space = 1; + c = *ptr; + } + + d = ptr[1]; + + if( c =='<' || c == '\0' ) + { + CvStringHashNode *key = 0, *key2 = 0; + CvAttrList* list = 0; + CvTypeInfo* info = 0; + int tag_type = 0; + int is_noname = 0; + const char* type_name = 0; + int elem_type = CV_NODE_NONE; + + if( d == '/' || c == '\0' ) + break; + + ptr = icvXMLParseTag( fs, ptr, &key, &list, &tag_type ); + + if( tag_type == CV_XML_DIRECTIVE_TAG ) + CV_PARSE_ERROR( "Directive tags are not allowed here" ); + if( tag_type == CV_XML_EMPTY_TAG ) + CV_PARSE_ERROR( "Empty tags are not supported" ); + + assert( tag_type == CV_XML_OPENING_TAG ); + + type_name = list ? cvAttrValue( list, "type_id" ) : 0; + if( type_name ) + { + if( strcmp( type_name, "str" ) == 0 ) + elem_type = CV_NODE_STRING; + else if( strcmp( type_name, "map" ) == 0 ) + elem_type = CV_NODE_MAP; + else if( strcmp( type_name, "seq" ) == 0 ) + elem_type = CV_NODE_SEQ; + else + { + info = cvFindType( type_name ); + if( info ) + elem_type = CV_NODE_USER; + } + } + + is_noname = key->str.len == 1 && key->str.ptr[0] == '_'; + if( !CV_NODE_IS_COLLECTION(node->tag) ) + { + icvFSCreateCollection( fs, is_noname ? CV_NODE_SEQ : CV_NODE_MAP, node ); + } + else if( is_noname ^ CV_NODE_IS_SEQ(node->tag) ) + CV_PARSE_ERROR( is_noname ? "Map element should have a name" : + "Sequence element should not have name (use <_>)" ); + + if( is_noname ) + elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 ); + else + elem = cvGetFileNode( fs, node, key, 1 ); + + ptr = icvXMLParseValue( fs, ptr, elem, elem_type); + if( !is_noname ) + elem->tag |= CV_NODE_NAMED; + is_simple &= !CV_NODE_IS_COLLECTION(elem->tag); + elem->info = info; + ptr = icvXMLParseTag( fs, ptr, &key2, &list, &tag_type ); + if( tag_type != CV_XML_CLOSING_TAG || key2 != key ) + CV_PARSE_ERROR( "Mismatched closing tag" ); + have_space = 1; + } + else + { + if( !have_space ) + CV_PARSE_ERROR( "There should be space between literals" ); + + elem = node; + if( node->tag != CV_NODE_NONE ) + { + if( !CV_NODE_IS_COLLECTION(node->tag) ) + icvFSCreateCollection( fs, CV_NODE_SEQ, node ); + + elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 ); + elem->info = 0; + } + + if( value_type != CV_NODE_STRING && + (cv_isdigit(c) || ((c == '-' || c == '+') && + (cv_isdigit(d) || d == '.')) || (c == '.' && cv_isalnum(d))) ) // a number + { + double fval; + int ival; + endptr = ptr + (c == '-' || c == '+'); + while( cv_isdigit(*endptr) ) + endptr++; + if( *endptr == '.' || *endptr == 'e' ) + { + fval = icv_strtod( fs, ptr, &endptr ); + /*if( endptr == ptr || cv_isalpha(*endptr) ) + icvProcessSpecialDouble( fs, ptr, &fval, &endptr ));*/ + elem->tag = CV_NODE_REAL; + elem->data.f = fval; + } + else + { + ival = (int)strtol( ptr, &endptr, 0 ); + elem->tag = CV_NODE_INT; + elem->data.i = ival; + } + + if( endptr == ptr ) + CV_PARSE_ERROR( "Invalid numeric value (inconsistent explicit type specification?)" ); + + ptr = endptr; + } + else + { + // string + char buf[CV_FS_MAX_LEN+16]; + int i = 0, len, is_quoted = 0; + elem->tag = CV_NODE_STRING; + if( c == '\"' ) + is_quoted = 1; + else + --ptr; + + for( ;; ) + { + c = *++ptr; + if( !cv_isalnum(c) ) + { + if( c == '\"' ) + { + if( !is_quoted ) + CV_PARSE_ERROR( "Literal \" is not allowed within a string. Use "" ); + ++ptr; + break; + } + else if( !cv_isprint(c) || c == '<' || (!is_quoted && cv_isspace(c))) + { + if( is_quoted ) + CV_PARSE_ERROR( "Closing \" is expected" ); + break; + } + else if( c == '\'' || c == '>' ) + { + CV_PARSE_ERROR( "Literal \' or > are not allowed. Use ' or >" ); + } + else if( c == '&' ) + { + if( *++ptr == '#' ) + { + int val, base = 10; + ptr++; + if( *ptr == 'x' ) + { + base = 16; + ptr++; + } + val = (int)strtol( ptr, &endptr, base ); + if( (unsigned)val > (unsigned)255 || + !endptr || *endptr != ';' ) + CV_PARSE_ERROR( "Invalid numeric value in the string" ); + c = (char)val; + } + else + { + endptr = ptr; + do c = *++endptr; + while( cv_isalnum(c) ); + if( c != ';' ) + CV_PARSE_ERROR( "Invalid character in the symbol entity name" ); + len = (int)(endptr - ptr); + if( len == 2 && memcmp( ptr, "lt", len ) == 0 ) + c = '<'; + else if( len == 2 && memcmp( ptr, "gt", len ) == 0 ) + c = '>'; + else if( len == 3 && memcmp( ptr, "amp", len ) == 0 ) + c = '&'; + else if( len == 4 && memcmp( ptr, "apos", len ) == 0 ) + c = '\''; + else if( len == 4 && memcmp( ptr, "quot", len ) == 0 ) + c = '\"'; + else + { + memcpy( buf + i, ptr-1, len + 2 ); + i += len + 2; + } + } + ptr = endptr; + } + } + buf[i++] = c; + if( i >= CV_FS_MAX_LEN ) + CV_PARSE_ERROR( "Too long string literal" ); + } + elem->data.str = cvMemStorageAllocString( fs->memstorage, buf, i ); + } + + if( !CV_NODE_IS_COLLECTION(value_type) && value_type != CV_NODE_NONE ) + break; + have_space = 0; + } + } + + if( (CV_NODE_TYPE(node->tag) == CV_NODE_NONE || + (CV_NODE_TYPE(node->tag) != value_type && + !CV_NODE_IS_COLLECTION(node->tag))) && + CV_NODE_IS_COLLECTION(value_type) ) + { + icvFSCreateCollection( fs, CV_NODE_IS_MAP(value_type) ? + CV_NODE_MAP : CV_NODE_SEQ, node ); + } + + if( value_type != CV_NODE_NONE && + value_type != CV_NODE_TYPE(node->tag) ) + CV_PARSE_ERROR( "The actual type is different from the specified type" ); + + if( CV_NODE_IS_COLLECTION(node->tag) && is_simple ) + node->data.seq->flags |= CV_NODE_SEQ_SIMPLE; + + node->tag |= is_user_type ? CV_NODE_USER : 0; + return ptr; +} + + +static char* +icvXMLParseTag( CvFileStorage* fs, char* ptr, CvStringHashNode** _tag, + CvAttrList** _list, int* _tag_type ) +{ + int tag_type = 0; + CvStringHashNode* tagname = 0; + CvAttrList *first = 0, *last = 0; + int count = 0, max_count = 4; + int attr_buf_size = (max_count*2 + 1)*sizeof(char*) + sizeof(CvAttrList); + char* endptr; + char c; + int have_space; + + if( *ptr == '\0' ) + CV_PARSE_ERROR( "Preliminary end of the stream" ); + + if( *ptr != '<' ) + CV_PARSE_ERROR( "Tag should start with \'<\'" ); + + ptr++; + if( cv_isalnum(*ptr) || *ptr == '_' ) + tag_type = CV_XML_OPENING_TAG; + else if( *ptr == '/' ) + { + tag_type = CV_XML_CLOSING_TAG; + ptr++; + } + else if( *ptr == '?' ) + { + tag_type = CV_XML_HEADER_TAG; + ptr++; + } + else if( *ptr == '!' ) + { + tag_type = CV_XML_DIRECTIVE_TAG; + assert( ptr[1] != '-' || ptr[2] != '-' ); + ptr++; + } + else + CV_PARSE_ERROR( "Unknown tag type" ); + + for(;;) + { + CvStringHashNode* attrname; + + if( !cv_isalpha(*ptr) && *ptr != '_' ) + CV_PARSE_ERROR( "Name should start with a letter or underscore" ); + + endptr = ptr - 1; + do c = *++endptr; + while( cv_isalnum(c) || c == '_' || c == '-' ); + + attrname = cvGetHashedKey( fs, ptr, (int)(endptr - ptr), 1 ); + ptr = endptr; + + if( !tagname ) + tagname = attrname; + else + { + if( tag_type == CV_XML_CLOSING_TAG ) + CV_PARSE_ERROR( "Closing tag should not contain any attributes" ); + + if( !last || count >= max_count ) + { + CvAttrList* chunk; + + chunk = (CvAttrList*)cvMemStorageAlloc( fs->memstorage, attr_buf_size ); + memset( chunk, 0, attr_buf_size ); + chunk->attr = (const char**)(chunk + 1); + count = 0; + if( !last ) + first = last = chunk; + else + last = last->next = chunk; + } + last->attr[count*2] = attrname->str.ptr; + } + + if( last ) + { + CvFileNode stub; + + if( *ptr != '=' ) + { + ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG ); + if( *ptr != '=' ) + CV_PARSE_ERROR( "Attribute name should be followed by \'=\'" ); + } + + c = *++ptr; + if( c != '\"' && c != '\'' ) + { + ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG ); + if( *ptr != '\"' && *ptr != '\'' ) + CV_PARSE_ERROR( "Attribute value should be put into single or double quotes" ); + } + + ptr = icvXMLParseValue( fs, ptr, &stub, CV_NODE_STRING ); + assert( stub.tag == CV_NODE_STRING ); + last->attr[count*2+1] = stub.data.str.ptr; + count++; + } + + c = *ptr; + have_space = cv_isspace(c) || c == '\0'; + + if( c != '>' ) + { + ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG ); + c = *ptr; + } + + if( c == '>' ) + { + if( tag_type == CV_XML_HEADER_TAG ) + CV_PARSE_ERROR( "Invalid closing tag for ' ) + CV_PARSE_ERROR( "Invalid closing tag for ' && tag_type == CV_XML_OPENING_TAG ) + { + tag_type = CV_XML_EMPTY_TAG; + ptr += 2; + break; + } + + if( !have_space ) + CV_PARSE_ERROR( "There should be space between attributes" ); + } + + *_tag = tagname; + *_tag_type = tag_type; + *_list = first; + + return ptr; +} + + +static void +icvXMLParse( CvFileStorage* fs ) +{ + char* ptr = fs->buffer_start; + CvStringHashNode *key = 0, *key2 = 0; + CvAttrList* list = 0; + int tag_type = 0; + + // CV_XML_INSIDE_TAG is used to prohibit leading comments + ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG ); + + if( memcmp( ptr, "\'" ); + + ptr = icvXMLParseTag( fs, ptr, &key, &list, &tag_type ); + + /*{ + const char* version = cvAttrValue( list, "version" ); + if( version && strncmp( version, "1.", 2 ) != 0 ) + CV_Error( CV_StsParseError, "Unsupported version of XML" ); + }*/ + // we support any 8-bit encoding, so we do not need to check the actual encoding. + // we do not support utf-16, but in the case of utf-16 we will not get here anyway. + /*{ + const char* encoding = cvAttrValue( list, "encoding" ); + if( encoding && strcmp( encoding, "ASCII" ) != 0 && + strcmp( encoding, "UTF-8" ) != 0 && + strcmp( encoding, "utf-8" ) != 0 ) + CV_PARSE_ERROR( "Unsupported encoding" ); + }*/ + + while( *ptr != '\0' ) + { + ptr = icvXMLSkipSpaces( fs, ptr, 0 ); + + if( *ptr != '\0' ) + { + CvFileNode* root_node; + ptr = icvXMLParseTag( fs, ptr, &key, &list, &tag_type ); + if( tag_type != CV_XML_OPENING_TAG || + strcmp(key->str.ptr,"opencv_storage") != 0 ) + CV_PARSE_ERROR( " tag is missing" ); + + root_node = (CvFileNode*)cvSeqPush( fs->roots, 0 ); + ptr = icvXMLParseValue( fs, ptr, root_node, CV_NODE_NONE ); + ptr = icvXMLParseTag( fs, ptr, &key2, &list, &tag_type ); + if( tag_type != CV_XML_CLOSING_TAG || key != key2 ) + CV_PARSE_ERROR( " tag is missing" ); + ptr = icvXMLSkipSpaces( fs, ptr, 0 ); + } + } + + assert( fs->dummy_eof != 0 ); +} + + +/****************************************************************************************\ +* XML Emitter * +\****************************************************************************************/ + +#define icvXMLFlush icvFSFlush + +static void +icvXMLWriteTag( CvFileStorage* fs, const char* key, int tag_type, CvAttrList list ) +{ + char* ptr = fs->buffer; + int i, len = 0; + int struct_flags = fs->struct_flags; + + if( key && key[0] == '\0' ) + key = 0; + + if( tag_type == CV_XML_OPENING_TAG || tag_type == CV_XML_EMPTY_TAG ) + { + if( CV_NODE_IS_COLLECTION(struct_flags) ) + { + if( CV_NODE_IS_MAP(struct_flags) ^ (key != 0) ) + CV_Error( CV_StsBadArg, "An attempt to add element without a key to a map, " + "or add element with key to sequence" ); + } + else + { + struct_flags = CV_NODE_EMPTY + (key ? CV_NODE_MAP : CV_NODE_SEQ); + fs->is_first = 0; + } + + if( !CV_NODE_IS_EMPTY(struct_flags) ) + ptr = icvXMLFlush(fs); + } + + if( !key ) + key = "_"; + else if( key[0] == '_' && key[1] == '\0' ) + CV_Error( CV_StsBadArg, "A single _ is a reserved tag name" ); + + len = (int)strlen( key ); + *ptr++ = '<'; + if( tag_type == CV_XML_CLOSING_TAG ) + { + if( list.attr ) + CV_Error( CV_StsBadArg, "Closing tag should not include any attributes" ); + *ptr++ = '/'; + } + + if( !cv_isalpha(key[0]) && key[0] != '_' ) + CV_Error( CV_StsBadArg, "Key should start with a letter or _" ); + + ptr = icvFSResizeWriteBuffer( fs, ptr, len ); + for( i = 0; i < len; i++ ) + { + char c = key[i]; + if( !cv_isalnum(c) && c != '_' && c != '-' ) + CV_Error( CV_StsBadArg, "Key name may only contain alphanumeric characters [a-zA-Z0-9], '-' and '_'" ); + ptr[i] = c; + } + ptr += len; + + for(;;) + { + const char** attr = list.attr; + + for( ; attr && attr[0] != 0; attr += 2 ) + { + int len0 = (int)strlen(attr[0]); + int len1 = (int)strlen(attr[1]); + + ptr = icvFSResizeWriteBuffer( fs, ptr, len0 + len1 + 4 ); + *ptr++ = ' '; + memcpy( ptr, attr[0], len0 ); + ptr += len0; + *ptr++ = '='; + *ptr++ = '\"'; + memcpy( ptr, attr[1], len1 ); + ptr += len1; + *ptr++ = '\"'; + } + if( !list.next ) + break; + list = *list.next; + } + + if( tag_type == CV_XML_EMPTY_TAG ) + *ptr++ = '/'; + *ptr++ = '>'; + fs->buffer = ptr; + fs->struct_flags = struct_flags & ~CV_NODE_EMPTY; +} + + +static void +icvXMLStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, + const char* type_name CV_DEFAULT(0)) +{ + CvXMLStackRecord parent; + const char* attr[10]; + int idx = 0; + + struct_flags = (struct_flags & (CV_NODE_TYPE_MASK|CV_NODE_FLOW)) | CV_NODE_EMPTY; + if( !CV_NODE_IS_COLLECTION(struct_flags)) + CV_Error( CV_StsBadArg, + "Some collection type: CV_NODE_SEQ or CV_NODE_MAP must be specified" ); + + if( type_name ) + { + attr[idx++] = "type_id"; + attr[idx++] = type_name; + } + attr[idx++] = 0; + + icvXMLWriteTag( fs, key, CV_XML_OPENING_TAG, cvAttrList(attr,0) ); + + parent.struct_flags = fs->struct_flags & ~CV_NODE_EMPTY; + parent.struct_indent = fs->struct_indent; + parent.struct_tag = fs->struct_tag; + cvSaveMemStoragePos( fs->strstorage, &parent.pos ); + cvSeqPush( fs->write_stack, &parent ); + + fs->struct_indent += CV_XML_INDENT; + if( !CV_NODE_IS_FLOW(struct_flags) ) + icvXMLFlush( fs ); + + fs->struct_flags = struct_flags; + if( key ) + { + fs->struct_tag = cvMemStorageAllocString( fs->strstorage, (char*)key, -1 ); + } + else + { + fs->struct_tag.ptr = 0; + fs->struct_tag.len = 0; + } +} + + +static void +icvXMLEndWriteStruct( CvFileStorage* fs ) +{ + CvXMLStackRecord parent; + + if( fs->write_stack->total == 0 ) + CV_Error( CV_StsError, "An extra closing tag" ); + + icvXMLWriteTag( fs, fs->struct_tag.ptr, CV_XML_CLOSING_TAG, cvAttrList(0,0) ); + cvSeqPop( fs->write_stack, &parent ); + + fs->struct_indent = parent.struct_indent; + fs->struct_flags = parent.struct_flags; + fs->struct_tag = parent.struct_tag; + cvRestoreMemStoragePos( fs->strstorage, &parent.pos ); +} + + +static void +icvXMLStartNextStream( CvFileStorage* fs ) +{ + if( !fs->is_first ) + { + while( fs->write_stack->total > 0 ) + icvXMLEndWriteStruct(fs); + + fs->struct_indent = 0; + icvXMLFlush(fs); + /* XML does not allow multiple top-level elements, + so we just put a comment and continue + the current (and the only) "stream" */ + icvPuts( fs, "\n\n" ); + /*fputs( "\n", fs->file ); + fputs( "\n", fs->file );*/ + fs->buffer = fs->buffer_start; + } +} + + +static void +icvXMLWriteScalar( CvFileStorage* fs, const char* key, const char* data, int len ) +{ + if( CV_NODE_IS_MAP(fs->struct_flags) || + (!CV_NODE_IS_COLLECTION(fs->struct_flags) && key) ) + { + icvXMLWriteTag( fs, key, CV_XML_OPENING_TAG, cvAttrList(0,0) ); + char* ptr = icvFSResizeWriteBuffer( fs, fs->buffer, len ); + memcpy( ptr, data, len ); + fs->buffer = ptr + len; + icvXMLWriteTag( fs, key, CV_XML_CLOSING_TAG, cvAttrList(0,0) ); + } + else + { + char* ptr = fs->buffer; + int new_offset = (int)(ptr - fs->buffer_start) + len; + + if( key ) + CV_Error( CV_StsBadArg, "elements with keys can not be written to sequence" ); + + fs->struct_flags = CV_NODE_SEQ; + + if( (new_offset > fs->wrap_margin && new_offset - fs->struct_indent > 10) || + (ptr > fs->buffer_start && ptr[-1] == '>' && !CV_NODE_IS_EMPTY(fs->struct_flags)) ) + { + ptr = icvXMLFlush(fs); + } + else if( ptr > fs->buffer_start + fs->struct_indent && ptr[-1] != '>' ) + *ptr++ = ' '; + + memcpy( ptr, data, len ); + fs->buffer = ptr + len; + } +} + + +static void +icvXMLWriteInt( CvFileStorage* fs, const char* key, int value ) +{ + char buf[128], *ptr = icv_itoa( value, buf, 10 ); + int len = (int)strlen(ptr); + icvXMLWriteScalar( fs, key, ptr, len ); +} + + +static void +icvXMLWriteReal( CvFileStorage* fs, const char* key, double value ) +{ + char buf[128]; + int len = (int)strlen( icvDoubleToString( buf, value )); + icvXMLWriteScalar( fs, key, buf, len ); +} + + +static void +icvXMLWriteString( CvFileStorage* fs, const char* key, const char* str, int quote ) +{ + char buf[CV_FS_MAX_LEN*6+16]; + char* data = (char*)str; + int i, len; + + if( !str ) + CV_Error( CV_StsNullPtr, "Null string pointer" ); + + len = (int)strlen(str); + if( len > CV_FS_MAX_LEN ) + CV_Error( CV_StsBadArg, "The written string is too long" ); + + if( quote || len == 0 || str[0] != '\"' || str[0] != str[len-1] ) + { + int need_quote = quote || len == 0; + data = buf; + *data++ = '\"'; + for( i = 0; i < len; i++ ) + { + char c = str[i]; + + if( (uchar)c >= 128 || c == ' ' ) + { + *data++ = c; + need_quote = 1; + } + else if( !cv_isprint(c) || c == '<' || c == '>' || c == '&' || c == '\'' || c == '\"' ) + { + *data++ = '&'; + if( c == '<' ) + { + memcpy(data, "lt", 2); + data += 2; + } + else if( c == '>' ) + { + memcpy(data, "gt", 2); + data += 2; + } + else if( c == '&' ) + { + memcpy(data, "amp", 3); + data += 3; + } + else if( c == '\'' ) + { + memcpy(data, "apos", 4); + data += 4; + } + else if( c == '\"' ) + { + memcpy( data, "quot", 4); + data += 4; + } + else + { + sprintf( data, "#x%02x", (uchar)c ); + data += 4; + } + *data++ = ';'; + need_quote = 1; + } + else + *data++ = c; + } + if( !need_quote && (cv_isdigit(str[0]) || + str[0] == '+' || str[0] == '-' || str[0] == '.' )) + need_quote = 1; + + if( need_quote ) + *data++ = '\"'; + len = (int)(data - buf) - !need_quote; + *data++ = '\0'; + data = buf + !need_quote; + } + + icvXMLWriteScalar( fs, key, data, len ); +} + + +static void +icvXMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment ) +{ + int len; + int multiline; + const char* eol; + char* ptr; + + if( !comment ) + CV_Error( CV_StsNullPtr, "Null comment" ); + + if( strstr(comment, "--") != 0 ) + CV_Error( CV_StsBadArg, "Double hyphen \'--\' is not allowed in the comments" ); + + len = (int)strlen(comment); + eol = strchr(comment, '\n'); + multiline = eol != 0; + ptr = fs->buffer; + + if( multiline || !eol_comment || fs->buffer_end - ptr < len + 5 ) + ptr = icvXMLFlush( fs ); + else if( ptr > fs->buffer_start + fs->struct_indent ) + *ptr++ = ' '; + + if( !multiline ) + { + ptr = icvFSResizeWriteBuffer( fs, ptr, len + 9 ); + sprintf( ptr, "", comment ); + len = (int)strlen(ptr); + } + else + { + strcpy( ptr, "" ); + fs->buffer = ptr + 3; + icvXMLFlush( fs ); + } +} + + +/****************************************************************************************\ +* Common High-Level Functions * +\****************************************************************************************/ + +CV_IMPL CvFileStorage* +cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, const char* encoding ) +{ + CvFileStorage* fs = 0; + char* xml_buf = 0; + int default_block_size = 1 << 18; + bool append = (flags & 3) == CV_STORAGE_APPEND; + bool mem = (flags & CV_STORAGE_MEMORY) != 0; + bool write_mode = (flags & 3) != 0; + bool isGZ = false; + size_t fnamelen = 0; + + if( !filename || filename[0] == '\0' ) + { + if( !write_mode ) + CV_Error( CV_StsNullPtr, mem ? "NULL or empty filename" : "NULL or empty buffer" ); + mem = true; + } + else + fnamelen = strlen(filename); + + if( mem && append ) + CV_Error( CV_StsBadFlag, "CV_STORAGE_APPEND and CV_STORAGE_MEMORY are not currently compatible" ); + + fs = (CvFileStorage*)cvAlloc( sizeof(*fs) ); + memset( fs, 0, sizeof(*fs)); + + fs->memstorage = cvCreateMemStorage( default_block_size ); + fs->dststorage = dststorage ? dststorage : fs->memstorage; + + fs->flags = CV_FILE_STORAGE; + fs->write_mode = write_mode; + + if( !mem ) + { + fs->filename = (char*)cvMemStorageAlloc( fs->memstorage, fnamelen+1 ); + strcpy( fs->filename, filename ); + + char* dot_pos = strrchr(fs->filename, '.'); + char compression = '\0'; + + if( dot_pos && dot_pos[1] == 'g' && dot_pos[2] == 'z' && + (dot_pos[3] == '\0' || (cv_isdigit(dot_pos[3]) && dot_pos[4] == '\0')) ) + { + if( append ) + CV_Error(CV_StsNotImplemented, "Appending data to compressed file is not implemented" ); + isGZ = true; + compression = dot_pos[3]; + if( compression ) + dot_pos[3] = '\0', fnamelen--; + } + + if( !isGZ ) + { + fs->file = fopen(fs->filename, !fs->write_mode ? "rt" : !append ? "wt" : "a+t" ); + if( !fs->file ) + goto _exit_; + } + else + { + #if USE_ZLIB + char mode[] = { fs->write_mode ? 'w' : 'r', 'b', compression ? compression : '3', '\0' }; + fs->gzfile = gzopen(fs->filename, mode); + if( !fs->gzfile ) + goto _exit_; + #else + CV_Error(CV_StsNotImplemented, "There is no compressed file storage support in this configuration"); + #endif + } + } + + fs->roots = 0; + fs->struct_indent = 0; + fs->struct_flags = 0; + fs->wrap_margin = 71; + + if( fs->write_mode ) + { + int fmt = flags & CV_STORAGE_FORMAT_MASK; + + if( mem ) + fs->outbuf = new std::deque; + + if( fmt == CV_STORAGE_FORMAT_AUTO && filename ) + { + const char* dot_pos = filename + fnamelen - (isGZ ? 7 : 4); + fs->fmt = (dot_pos >= filename && (memcmp( dot_pos, ".xml", 4) == 0 || + memcmp(dot_pos, ".XML", 4) == 0 || memcmp(dot_pos, ".Xml", 4) == 0)) ? + CV_STORAGE_FORMAT_XML : CV_STORAGE_FORMAT_YAML; + } + else + fs->fmt = fmt != CV_STORAGE_FORMAT_AUTO ? fmt : CV_STORAGE_FORMAT_XML; + + // we use factor=6 for XML (the longest characters (' and ") are encoded with 6 bytes (' and ") + // and factor=4 for YAML ( as we use 4 bytes for non ASCII characters (e.g. \xAB)) + int buf_size = CV_FS_MAX_LEN*(fs->fmt == CV_STORAGE_FORMAT_XML ? 6 : 4) + 1024; + + if( append ) + fseek( fs->file, 0, SEEK_END ); + + fs->write_stack = cvCreateSeq( 0, sizeof(CvSeq), fs->fmt == CV_STORAGE_FORMAT_XML ? + sizeof(CvXMLStackRecord) : sizeof(int), fs->memstorage ); + fs->is_first = 1; + fs->struct_indent = 0; + fs->struct_flags = CV_NODE_EMPTY; + fs->buffer_start = fs->buffer = (char*)cvAlloc( buf_size + 1024 ); + fs->buffer_end = fs->buffer_start + buf_size; + if( fs->fmt == CV_STORAGE_FORMAT_XML ) + { + size_t file_size = fs->file ? (size_t)ftell( fs->file ) : (size_t)0; + fs->strstorage = cvCreateChildMemStorage( fs->memstorage ); + if( !append || file_size == 0 ) + { + if( encoding ) + { + if( strcmp( encoding, "UTF-16" ) == 0 || + strcmp( encoding, "utf-16" ) == 0 || + strcmp( encoding, "Utf-16" ) == 0 ) + CV_Error( CV_StsBadArg, "UTF-16 XML encoding is not supported! Use 8-bit encoding\n"); + + CV_Assert( strlen(encoding) < 1000 ); + char buf[1100]; + sprintf(buf, "\n", encoding); + icvPuts( fs, buf ); + } + else + icvPuts( fs, "\n" ); + icvPuts( fs, "\n" ); + } + else + { + int xml_buf_size = 1 << 10; + char substr[] = ""; + int last_occurence = -1; + xml_buf_size = MIN(xml_buf_size, int(file_size)); + fseek( fs->file, -xml_buf_size, SEEK_END ); + xml_buf = (char*)cvAlloc( xml_buf_size+2 ); + // find the last occurence of + for(;;) + { + int line_offset = ftell( fs->file ); + char* ptr0 = icvGets( fs, xml_buf, xml_buf_size ), *ptr; + if( !ptr0 ) + break; + ptr = ptr0; + for(;;) + { + ptr = strstr( ptr, substr ); + if( !ptr ) + break; + last_occurence = line_offset + (int)(ptr - ptr0); + ptr += strlen(substr); + } + } + if( last_occurence < 0 ) + CV_Error( CV_StsError, "Could not find in the end of file.\n" ); + icvCloseFile( fs ); + fs->file = fopen( fs->filename, "r+t" ); + fseek( fs->file, last_occurence, SEEK_SET ); + // replace the last "" with " ", which has the same length + icvPuts( fs, " " ); + fseek( fs->file, 0, SEEK_END ); + icvPuts( fs, "\n" ); + } + fs->start_write_struct = icvXMLStartWriteStruct; + fs->end_write_struct = icvXMLEndWriteStruct; + fs->write_int = icvXMLWriteInt; + fs->write_real = icvXMLWriteReal; + fs->write_string = icvXMLWriteString; + fs->write_comment = icvXMLWriteComment; + fs->start_next_stream = icvXMLStartNextStream; + } + else + { + if( !append ) + icvPuts( fs, "%YAML:1.0\n" ); + else + icvPuts( fs, "...\n---\n" ); + fs->start_write_struct = icvYMLStartWriteStruct; + fs->end_write_struct = icvYMLEndWriteStruct; + fs->write_int = icvYMLWriteInt; + fs->write_real = icvYMLWriteReal; + fs->write_string = icvYMLWriteString; + fs->write_comment = icvYMLWriteComment; + fs->start_next_stream = icvYMLStartNextStream; + } + } + else + { + if( mem ) + { + fs->strbuf = filename; + fs->strbufsize = fnamelen; + } + + size_t buf_size = 1 << 20; + const char* yaml_signature = "%YAML:"; + char buf[16]; + icvGets( fs, buf, sizeof(buf)-2 ); + fs->fmt = strncmp( buf, yaml_signature, strlen(yaml_signature) ) == 0 ? + CV_STORAGE_FORMAT_YAML : CV_STORAGE_FORMAT_XML; + + if( !isGZ ) + { + if( !mem ) + { + fseek( fs->file, 0, SEEK_END ); + buf_size = ftell( fs->file ); + } + else + buf_size = fs->strbufsize; + buf_size = MIN( buf_size, (size_t)(1 << 20) ); + buf_size = MAX( buf_size, (size_t)(CV_FS_MAX_LEN*2 + 1024) ); + } + icvRewind(fs); + + fs->str_hash = cvCreateMap( 0, sizeof(CvStringHash), + sizeof(CvStringHashNode), fs->memstorage, 256 ); + + fs->roots = cvCreateSeq( 0, sizeof(CvSeq), + sizeof(CvFileNode), fs->memstorage ); + + fs->buffer = fs->buffer_start = (char*)cvAlloc( buf_size + 256 ); + fs->buffer_end = fs->buffer_start + buf_size; + fs->buffer[0] = '\n'; + fs->buffer[1] = '\0'; + + //mode = cvGetErrMode(); + //cvSetErrMode( CV_ErrModeSilent ); + if( fs->fmt == CV_STORAGE_FORMAT_XML ) + icvXMLParse( fs ); + else + icvYMLParse( fs ); + //cvSetErrMode( mode ); + + // release resources that we do not need anymore + cvFree( &fs->buffer_start ); + fs->buffer = fs->buffer_end = 0; + } + fs->is_opened = true; + +_exit_: + if( fs ) + { + if( cvGetErrStatus() < 0 || (!fs->file && !fs->gzfile && !fs->outbuf && !fs->strbuf) ) + { + cvReleaseFileStorage( &fs ); + } + else if( !fs->write_mode ) + { + icvCloseFile(fs); + // we close the file since it's not needed anymore. But icvCloseFile() resets is_opened, + // which may be misleading. Since we restore the value of is_opened. + fs->is_opened = true; + } + } + + cvFree( &xml_buf ); + return fs; +} + + +CV_IMPL void +cvStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, + const char* type_name, CvAttrList /*attributes*/ ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->start_write_struct( fs, key, struct_flags, type_name ); +} + + +CV_IMPL void +cvEndWriteStruct( CvFileStorage* fs ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->end_write_struct( fs ); +} + + +CV_IMPL void +cvWriteInt( CvFileStorage* fs, const char* key, int value ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->write_int( fs, key, value ); +} + + +CV_IMPL void +cvWriteReal( CvFileStorage* fs, const char* key, double value ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->write_real( fs, key, value ); +} + + +CV_IMPL void +cvWriteString( CvFileStorage* fs, const char* key, const char* value, int quote ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->write_string( fs, key, value, quote ); +} + + +CV_IMPL void +cvWriteComment( CvFileStorage* fs, const char* comment, int eol_comment ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->write_comment( fs, comment, eol_comment ); +} + + +CV_IMPL void +cvStartNextStream( CvFileStorage* fs ) +{ + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + fs->start_next_stream( fs ); +} + + +static const char icvTypeSymbol[] = "ucwsifdr"; +#define CV_FS_MAX_FMT_PAIRS 128 + +static char* +icvEncodeFormat( int elem_type, char* dt ) +{ + sprintf( dt, "%d%c", CV_MAT_CN(elem_type), icvTypeSymbol[CV_MAT_DEPTH(elem_type)] ); + return dt + ( dt[2] == '\0' && dt[0] == '1' ); +} + +static int +icvDecodeFormat( const char* dt, int* fmt_pairs, int max_len ) +{ + int fmt_pair_count = 0; + int i = 0, k = 0, len = dt ? (int)strlen(dt) : 0; + + if( !dt || !len ) + return 0; + + assert( fmt_pairs != 0 && max_len > 0 ); + fmt_pairs[0] = 0; + max_len *= 2; + + for( ; k < len; k++ ) + { + char c = dt[k]; + + if( cv_isdigit(c) ) + { + int count = c - '0'; + if( cv_isdigit(dt[k+1]) ) + { + char* endptr = 0; + count = (int)strtol( dt+k, &endptr, 10 ); + k = (int)(endptr - dt) - 1; + } + + if( count <= 0 ) + CV_Error( CV_StsBadArg, "Invalid data type specification" ); + + fmt_pairs[i] = count; + } + else + { + const char* pos = strchr( icvTypeSymbol, c ); + if( !pos ) + CV_Error( CV_StsBadArg, "Invalid data type specification" ); + if( fmt_pairs[i] == 0 ) + fmt_pairs[i] = 1; + fmt_pairs[i+1] = (int)(pos - icvTypeSymbol); + if( i > 0 && fmt_pairs[i+1] == fmt_pairs[i-1] ) + fmt_pairs[i-2] += fmt_pairs[i]; + else + { + i += 2; + if( i >= max_len ) + CV_Error( CV_StsBadArg, "Too long data type specification" ); + } + fmt_pairs[i] = 0; + } + } + + fmt_pair_count = i/2; + return fmt_pair_count; +} + + +static int +icvCalcElemSize( const char* dt, int initial_size ) +{ + int size = 0; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS], i, fmt_pair_count; + int comp_size; + + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + fmt_pair_count *= 2; + for( i = 0, size = initial_size; i < fmt_pair_count; i += 2 ) + { + comp_size = CV_ELEM_SIZE(fmt_pairs[i+1]); + size = cvAlign( size, comp_size ); + size += comp_size * fmt_pairs[i]; + } + if( initial_size == 0 ) + { + comp_size = CV_ELEM_SIZE(fmt_pairs[1]); + size = cvAlign( size, comp_size ); + } + return size; +} + + +static int +icvDecodeSimpleFormat( const char* dt ) +{ + int elem_type = -1; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS], fmt_pair_count; + + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + if( fmt_pair_count != 1 || fmt_pairs[0] > 4 ) + CV_Error( CV_StsError, "Too complex format for the matrix" ); + + elem_type = CV_MAKETYPE( fmt_pairs[1], fmt_pairs[0] ); + + return elem_type; +} + + +CV_IMPL void +cvWriteRawData( CvFileStorage* fs, const void* _data, int len, const char* dt ) +{ + const char* data0 = (const char*)_data; + int offset = 0; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], k, fmt_pair_count; + char buf[256] = ""; + + CV_CHECK_OUTPUT_FILE_STORAGE( fs ); + + if( len < 0 ) + CV_Error( CV_StsOutOfRange, "Negative number of elements" ); + + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + + if( !len ) + return; + + if( !data0 ) + CV_Error( CV_StsNullPtr, "Null data pointer" ); + + if( fmt_pair_count == 1 ) + { + fmt_pairs[0] *= len; + len = 1; + } + + for(;len--;) + { + for( k = 0; k < fmt_pair_count; k++ ) + { + int i, count = fmt_pairs[k*2]; + int elem_type = fmt_pairs[k*2+1]; + int elem_size = CV_ELEM_SIZE(elem_type); + const char* data, *ptr; + + offset = cvAlign( offset, elem_size ); + data = data0 + offset; + + for( i = 0; i < count; i++ ) + { + switch( elem_type ) + { + case CV_8U: + ptr = icv_itoa( *(uchar*)data, buf, 10 ); + data++; + break; + case CV_8S: + ptr = icv_itoa( *(char*)data, buf, 10 ); + data++; + break; + case CV_16U: + ptr = icv_itoa( *(ushort*)data, buf, 10 ); + data += sizeof(ushort); + break; + case CV_16S: + ptr = icv_itoa( *(short*)data, buf, 10 ); + data += sizeof(short); + break; + case CV_32S: + ptr = icv_itoa( *(int*)data, buf, 10 ); + data += sizeof(int); + break; + case CV_32F: + ptr = icvFloatToString( buf, *(float*)data ); + data += sizeof(float); + break; + case CV_64F: + ptr = icvDoubleToString( buf, *(double*)data ); + data += sizeof(double); + break; + case CV_USRTYPE1: /* reference */ + ptr = icv_itoa( (int)*(size_t*)data, buf, 10 ); + data += sizeof(size_t); + break; + default: + assert(0); + return; + } + + if( fs->fmt == CV_STORAGE_FORMAT_XML ) + { + int buf_len = (int)strlen(ptr); + icvXMLWriteScalar( fs, 0, ptr, buf_len ); + } + else + icvYMLWrite( fs, 0, ptr ); + } + + offset = (int)(data - data0); + } + } +} + + +CV_IMPL void +cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader ) +{ + int node_type; + CV_CHECK_FILE_STORAGE( fs ); + + if( !src || !reader ) + CV_Error( CV_StsNullPtr, "Null pointer to source file node or reader" ); + + node_type = CV_NODE_TYPE(src->tag); + if( node_type == CV_NODE_INT || node_type == CV_NODE_REAL ) + { + // emulate reading from 1-element sequence + reader->ptr = (schar*)src; + reader->block_max = reader->ptr + sizeof(*src)*2; + reader->block_min = reader->ptr; + reader->seq = 0; + } + else if( node_type == CV_NODE_SEQ ) + { + cvStartReadSeq( src->data.seq, reader, 0 ); + } + else if( node_type == CV_NODE_NONE ) + { + memset( reader, 0, sizeof(*reader) ); + } + else + CV_Error( CV_StsBadArg, "The file node should be a numerical scalar or a sequence" ); +} + + +CV_IMPL void +cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, + int len, void* _data, const char* dt ) +{ + char* data0 = (char*)_data; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], k = 0, fmt_pair_count; + int i = 0, offset = 0, count = 0; + + CV_CHECK_FILE_STORAGE( fs ); + + if( !reader || !data0 ) + CV_Error( CV_StsNullPtr, "Null pointer to reader or destination array" ); + + if( !reader->seq && len != 1 ) + CV_Error( CV_StsBadSize, "The readed sequence is a scalar, thus len must be 1" ); + + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + + for(;;) + { + for( k = 0; k < fmt_pair_count; k++ ) + { + int elem_type = fmt_pairs[k*2+1]; + int elem_size = CV_ELEM_SIZE(elem_type); + char* data; + + count = fmt_pairs[k*2]; + offset = cvAlign( offset, elem_size ); + data = data0 + offset; + + for( i = 0; i < count; i++ ) + { + CvFileNode* node = (CvFileNode*)reader->ptr; + if( CV_NODE_IS_INT(node->tag) ) + { + int ival = node->data.i; + + switch( elem_type ) + { + case CV_8U: + *(uchar*)data = CV_CAST_8U(ival); + data++; + break; + case CV_8S: + *(char*)data = CV_CAST_8S(ival); + data++; + break; + case CV_16U: + *(ushort*)data = CV_CAST_16U(ival); + data += sizeof(ushort); + break; + case CV_16S: + *(short*)data = CV_CAST_16S(ival); + data += sizeof(short); + break; + case CV_32S: + *(int*)data = ival; + data += sizeof(int); + break; + case CV_32F: + *(float*)data = (float)ival; + data += sizeof(float); + break; + case CV_64F: + *(double*)data = (double)ival; + data += sizeof(double); + break; + case CV_USRTYPE1: /* reference */ + *(size_t*)data = ival; + data += sizeof(size_t); + break; + default: + assert(0); + return; + } + } + else if( CV_NODE_IS_REAL(node->tag) ) + { + double fval = node->data.f; + int ival; + + switch( elem_type ) + { + case CV_8U: + ival = cvRound(fval); + *(uchar*)data = CV_CAST_8U(ival); + data++; + break; + case CV_8S: + ival = cvRound(fval); + *(char*)data = CV_CAST_8S(ival); + data++; + break; + case CV_16U: + ival = cvRound(fval); + *(ushort*)data = CV_CAST_16U(ival); + data += sizeof(ushort); + break; + case CV_16S: + ival = cvRound(fval); + *(short*)data = CV_CAST_16S(ival); + data += sizeof(short); + break; + case CV_32S: + ival = cvRound(fval); + *(int*)data = ival; + data += sizeof(int); + break; + case CV_32F: + *(float*)data = (float)fval; + data += sizeof(float); + break; + case CV_64F: + *(double*)data = fval; + data += sizeof(double); + break; + case CV_USRTYPE1: /* reference */ + ival = cvRound(fval); + *(size_t*)data = ival; + data += sizeof(size_t); + break; + default: + assert(0); + return; + } + } + else + CV_Error( CV_StsError, + "The sequence element is not a numerical scalar" ); + + CV_NEXT_SEQ_ELEM( sizeof(CvFileNode), *reader ); + if( !--len ) + goto end_loop; + } + + offset = (int)(data - data0); + } + } + +end_loop: + if( i != count - 1 || k != fmt_pair_count - 1 ) + CV_Error( CV_StsBadSize, + "The sequence slice does not fit an integer number of records" ); + + if( !reader->seq ) + reader->ptr -= sizeof(CvFileNode); +} + + +CV_IMPL void +cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, + void* data, const char* dt ) +{ + CvSeqReader reader; + + if( !src || !data ) + CV_Error( CV_StsNullPtr, "Null pointers to source file node or destination array" ); + + cvStartReadRawData( fs, src, &reader ); + cvReadRawDataSlice( fs, &reader, CV_NODE_IS_SEQ(src->tag) ? + src->data.seq->total : 1, data, dt ); +} + + +static void +icvWriteFileNode( CvFileStorage* fs, const char* name, const CvFileNode* node ); + +static void +icvWriteCollection( CvFileStorage* fs, const CvFileNode* node ) +{ + int i, total = node->data.seq->total; + int elem_size = node->data.seq->elem_size; + int is_map = CV_NODE_IS_MAP(node->tag); + CvSeqReader reader; + + cvStartReadSeq( node->data.seq, &reader, 0 ); + + for( i = 0; i < total; i++ ) + { + CvFileMapNode* elem = (CvFileMapNode*)reader.ptr; + if( !is_map || CV_IS_SET_ELEM(elem) ) + { + const char* name = is_map ? elem->key->str.ptr : 0; + icvWriteFileNode( fs, name, &elem->value ); + } + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } +} + +static void +icvWriteFileNode( CvFileStorage* fs, const char* name, const CvFileNode* node ) +{ + switch( CV_NODE_TYPE(node->tag) ) + { + case CV_NODE_INT: + fs->write_int( fs, name, node->data.i ); + break; + case CV_NODE_REAL: + fs->write_real( fs, name, node->data.f ); + break; + case CV_NODE_STR: + fs->write_string( fs, name, node->data.str.ptr, 0 ); + break; + case CV_NODE_SEQ: + case CV_NODE_MAP: + fs->start_write_struct( fs, name, CV_NODE_TYPE(node->tag) + + (CV_NODE_SEQ_IS_SIMPLE(node->data.seq) ? CV_NODE_FLOW : 0), + node->info ? node->info->type_name : 0 ); + icvWriteCollection( fs, node ); + fs->end_write_struct( fs ); + break; + case CV_NODE_NONE: + fs->start_write_struct( fs, name, CV_NODE_SEQ, 0 ); + fs->end_write_struct( fs ); + break; + default: + CV_Error( CV_StsBadFlag, "Unknown type of file node" ); + } +} + + +CV_IMPL void +cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, + const CvFileNode* node, int embed ) +{ + CvFileStorage* dst = 0; + CV_CHECK_OUTPUT_FILE_STORAGE(fs); + + if( !node ) + return; + + if( CV_NODE_IS_COLLECTION(node->tag) && embed ) + { + icvWriteCollection( fs, node ); + } + else + { + icvWriteFileNode( fs, new_node_name, node ); + } + /* + int i, stream_count; + stream_count = fs->roots->total; + for( i = 0; i < stream_count; i++ ) + { + CvFileNode* node = (CvFileNode*)cvGetSeqElem( fs->roots, i, 0 ); + icvDumpCollection( dst, node ); + if( i < stream_count - 1 ) + dst->start_next_stream( dst ); + }*/ + cvReleaseFileStorage( &dst ); +} + + +CV_IMPL const char* +cvGetFileNodeName( const CvFileNode* file_node ) +{ + return file_node && CV_NODE_HAS_NAME(file_node->tag) ? + ((CvFileMapNode*)file_node)->key->str.ptr : 0; +} + +/****************************************************************************************\ +* Reading/Writing etc. for standard types * +\****************************************************************************************/ + +/*#define CV_TYPE_NAME_MAT "opencv-matrix" +#define CV_TYPE_NAME_MATND "opencv-nd-matrix" +#define CV_TYPE_NAME_SPARSE_MAT "opencv-sparse-matrix" +#define CV_TYPE_NAME_IMAGE "opencv-image" +#define CV_TYPE_NAME_SEQ "opencv-sequence" +#define CV_TYPE_NAME_SEQ_TREE "opencv-sequence-tree" +#define CV_TYPE_NAME_GRAPH "opencv-graph"*/ + +/******************************* CvMat ******************************/ + +static int +icvIsMat( const void* ptr ) +{ + return CV_IS_MAT_HDR_Z(ptr); +} + +static void +icvWriteMat( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList /*attr*/ ) +{ + const CvMat* mat = (const CvMat*)struct_ptr; + char dt[16]; + CvSize size; + int y; + + assert( CV_IS_MAT_HDR_Z(mat) ); + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_MAT ); + cvWriteInt( fs, "rows", mat->rows ); + cvWriteInt( fs, "cols", mat->cols ); + cvWriteString( fs, "dt", icvEncodeFormat( CV_MAT_TYPE(mat->type), dt ), 0 ); + cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW ); + + size = cvGetSize(mat); + if( size.height > 0 && size.width > 0 && mat->data.ptr ) + { + if( CV_IS_MAT_CONT(mat->type) ) + { + size.width *= size.height; + size.height = 1; + } + + for( y = 0; y < size.height; y++ ) + cvWriteRawData( fs, mat->data.ptr + (size_t)y*mat->step, size.width, dt ); + } + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); +} + + +static int +icvFileNodeSeqLen( CvFileNode* node ) +{ + return CV_NODE_IS_COLLECTION(node->tag) ? node->data.seq->total : + CV_NODE_TYPE(node->tag) != CV_NODE_NONE; +} + + +static void* +icvReadMat( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + CvMat* mat; + const char* dt; + CvFileNode* data; + int rows, cols, elem_type; + + rows = cvReadIntByName( fs, node, "rows", -1 ); + cols = cvReadIntByName( fs, node, "cols", -1 ); + dt = cvReadStringByName( fs, node, "dt", 0 ); + + if( rows < 0 || cols < 0 || !dt ) + CV_Error( CV_StsError, "Some of essential matrix attributes are absent" ); + + elem_type = icvDecodeSimpleFormat( dt ); + + data = cvGetFileNodeByName( fs, node, "data" ); + if( !data ) + CV_Error( CV_StsError, "The matrix data is not found in file storage" ); + + int nelems = icvFileNodeSeqLen( data ); + if( nelems > 0 && nelems != rows*cols*CV_MAT_CN(elem_type) ) + CV_Error( CV_StsUnmatchedSizes, + "The matrix size does not match to the number of stored elements" ); + + if( nelems > 0 ) + { + mat = cvCreateMat( rows, cols, elem_type ); + cvReadRawData( fs, data, mat->data.ptr, dt ); + } + else if( rows == 0 && cols == 0 ) + mat = cvCreateMatHeader( 0, 1, elem_type ); + else + mat = cvCreateMatHeader( rows, cols, elem_type ); + + ptr = mat; + return ptr; +} + + +/******************************* CvMatND ******************************/ + +static int +icvIsMatND( const void* ptr ) +{ + return CV_IS_MATND_HDR(ptr); +} + + +static void +icvWriteMatND( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList /*attr*/ ) +{ + CvMatND* mat = (CvMatND*)struct_ptr; + CvMatND stub; + CvNArrayIterator iterator; + int dims, sizes[CV_MAX_DIM]; + char dt[16]; + + assert( CV_IS_MATND_HDR(mat) ); + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_MATND ); + dims = cvGetDims( mat, sizes ); + cvStartWriteStruct( fs, "sizes", CV_NODE_SEQ + CV_NODE_FLOW ); + cvWriteRawData( fs, sizes, dims, "i" ); + cvEndWriteStruct( fs ); + cvWriteString( fs, "dt", icvEncodeFormat( cvGetElemType(mat), dt ), 0 ); + cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW ); + + if( mat->dim[0].size > 0 && mat->data.ptr ) + { + cvInitNArrayIterator( 1, (CvArr**)&mat, 0, &stub, &iterator ); + + do + cvWriteRawData( fs, iterator.ptr[0], iterator.size.width, dt ); + while( cvNextNArraySlice( &iterator )); + } + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); +} + + +static void* +icvReadMatND( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + CvMatND* mat; + const char* dt; + CvFileNode* data; + CvFileNode* sizes_node; + int sizes[CV_MAX_DIM], dims, elem_type; + int i, total_size; + + sizes_node = cvGetFileNodeByName( fs, node, "sizes" ); + dt = cvReadStringByName( fs, node, "dt", 0 ); + + if( !sizes_node || !dt ) + CV_Error( CV_StsError, "Some of essential matrix attributes are absent" ); + + dims = CV_NODE_IS_SEQ(sizes_node->tag) ? sizes_node->data.seq->total : + CV_NODE_IS_INT(sizes_node->tag) ? 1 : -1; + + if( dims <= 0 || dims > CV_MAX_DIM ) + CV_Error( CV_StsParseError, "Could not determine the matrix dimensionality" ); + + cvReadRawData( fs, sizes_node, sizes, "i" ); + elem_type = icvDecodeSimpleFormat( dt ); + + data = cvGetFileNodeByName( fs, node, "data" ); + if( !data ) + CV_Error( CV_StsError, "The matrix data is not found in file storage" ); + + + + for( total_size = CV_MAT_CN(elem_type), i = 0; i < dims; i++ ) + total_size *= sizes[i]; + + int nelems = icvFileNodeSeqLen( data ); + + if( nelems > 0 && nelems != total_size ) + CV_Error( CV_StsUnmatchedSizes, + "The matrix size does not match to the number of stored elements" ); + + if( nelems > 0 ) + { + mat = cvCreateMatND( dims, sizes, elem_type ); + cvReadRawData( fs, data, mat->data.ptr, dt ); + } + else + mat = cvCreateMatNDHeader( dims, sizes, elem_type ); + + ptr = mat; + return ptr; +} + + +/******************************* CvSparseMat ******************************/ + +static int +icvIsSparseMat( const void* ptr ) +{ + return CV_IS_SPARSE_MAT(ptr); +} + + +static int +icvSortIdxCmpFunc( const void* _a, const void* _b, void* userdata ) +{ + int i, dims = *(int*)userdata; + const int* a = *(const int**)_a; + const int* b = *(const int**)_b; + + for( i = 0; i < dims; i++ ) + { + int delta = a[i] - b[i]; + if( delta ) + return delta; + } + + return 0; +} + + +static void +icvWriteSparseMat( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList /*attr*/ ) +{ + CvMemStorage* memstorage = 0; + const CvSparseMat* mat = (const CvSparseMat*)struct_ptr; + CvSparseMatIterator iterator; + CvSparseNode* node; + CvSeq* elements; + CvSeqReader reader; + int i, dims; + int *prev_idx = 0; + char dt[16]; + + assert( CV_IS_SPARSE_MAT(mat) ); + + memstorage = cvCreateMemStorage(); + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_SPARSE_MAT ); + dims = cvGetDims( mat, 0 ); + + cvStartWriteStruct( fs, "sizes", CV_NODE_SEQ + CV_NODE_FLOW ); + cvWriteRawData( fs, mat->size, dims, "i" ); + cvEndWriteStruct( fs ); + cvWriteString( fs, "dt", icvEncodeFormat( CV_MAT_TYPE(mat->type), dt ), 0 ); + cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW ); + + elements = cvCreateSeq( CV_SEQ_ELTYPE_PTR, sizeof(CvSeq), sizeof(int*), memstorage ); + + node = cvInitSparseMatIterator( mat, &iterator ); + while( node ) + { + int* idx = CV_NODE_IDX( mat, node ); + cvSeqPush( elements, &idx ); + node = cvGetNextSparseNode( &iterator ); + } + + cvSeqSort( elements, icvSortIdxCmpFunc, &dims ); + cvStartReadSeq( elements, &reader, 0 ); + + for( i = 0; i < elements->total; i++ ) + { + int* idx; + void* val; + int k = 0; + + CV_READ_SEQ_ELEM( idx, reader ); + if( i > 0 ) + { + for( ; idx[k] == prev_idx[k]; k++ ) + assert( k < dims ); + if( k < dims - 1 ) + fs->write_int( fs, 0, k - dims + 1 ); + } + for( ; k < dims; k++ ) + fs->write_int( fs, 0, idx[k] ); + prev_idx = idx; + + node = (CvSparseNode*)((uchar*)idx - mat->idxoffset ); + val = CV_NODE_VAL( mat, node ); + + cvWriteRawData( fs, val, 1, dt ); + } + + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); + cvReleaseMemStorage( &memstorage ); +} + + +static void* +icvReadSparseMat( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + CvSparseMat* mat; + const char* dt; + CvFileNode* data; + CvFileNode* sizes_node; + CvSeqReader reader; + CvSeq* elements; + int sizes[CV_MAX_DIM_HEAP], dims, elem_type, cn; + int i; + + sizes_node = cvGetFileNodeByName( fs, node, "sizes" ); + dt = cvReadStringByName( fs, node, "dt", 0 ); + + if( !sizes_node || !dt ) + CV_Error( CV_StsError, "Some of essential matrix attributes are absent" ); + + dims = CV_NODE_IS_SEQ(sizes_node->tag) ? sizes_node->data.seq->total : + CV_NODE_IS_INT(sizes_node->tag) ? 1 : -1; + + if( dims <= 0 || dims > CV_MAX_DIM_HEAP ) + CV_Error( CV_StsParseError, "Could not determine sparse matrix dimensionality" ); + + cvReadRawData( fs, sizes_node, sizes, "i" ); + elem_type = icvDecodeSimpleFormat( dt ); + + data = cvGetFileNodeByName( fs, node, "data" ); + if( !data || !CV_NODE_IS_SEQ(data->tag) ) + CV_Error( CV_StsError, "The matrix data is not found in file storage" ); + + mat = cvCreateSparseMat( dims, sizes, elem_type ); + + cn = CV_MAT_CN(elem_type); + int idx[CV_MAX_DIM_HEAP]; + elements = data->data.seq; + cvStartReadRawData( fs, data, &reader ); + + for( i = 0; i < elements->total; ) + { + CvFileNode* elem = (CvFileNode*)reader.ptr; + uchar* val; + int k; + if( !CV_NODE_IS_INT(elem->tag )) + CV_Error( CV_StsParseError, "Sparse matrix data is corrupted" ); + k = elem->data.i; + if( i > 0 && k >= 0 ) + idx[dims-1] = k; + else + { + if( i > 0 ) + k = dims + k - 1; + else + idx[0] = k, k = 1; + for( ; k < dims; k++ ) + { + CV_NEXT_SEQ_ELEM( elements->elem_size, reader ); + i++; + elem = (CvFileNode*)reader.ptr; + if( !CV_NODE_IS_INT(elem->tag ) || elem->data.i < 0 ) + CV_Error( CV_StsParseError, "Sparse matrix data is corrupted" ); + idx[k] = elem->data.i; + } + } + CV_NEXT_SEQ_ELEM( elements->elem_size, reader ); + i++; + val = cvPtrND( mat, idx, 0, 1, 0 ); + cvReadRawDataSlice( fs, &reader, cn, val, dt ); + i += cn; + } + + ptr = mat; + return ptr; +} + + +/******************************* IplImage ******************************/ + +static int +icvIsImage( const void* ptr ) +{ + return CV_IS_IMAGE_HDR(ptr); +} + +static void +icvWriteImage( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList /*attr*/ ) +{ + const IplImage* image = (const IplImage*)struct_ptr; + char dt_buf[16], *dt; + CvSize size; + int y, depth; + + assert( CV_IS_IMAGE(image) ); + + if( image->dataOrder == IPL_DATA_ORDER_PLANE ) + CV_Error( CV_StsUnsupportedFormat, + "Images with planar data layout are not supported" ); + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_IMAGE ); + cvWriteInt( fs, "width", image->width ); + cvWriteInt( fs, "height", image->height ); + cvWriteString( fs, "origin", image->origin == IPL_ORIGIN_TL + ? "top-left" : "bottom-left", 0 ); + cvWriteString( fs, "layout", image->dataOrder == IPL_DATA_ORDER_PLANE + ? "planar" : "interleaved", 0 ); + if( image->roi ) + { + cvStartWriteStruct( fs, "roi", CV_NODE_MAP + CV_NODE_FLOW ); + cvWriteInt( fs, "x", image->roi->xOffset ); + cvWriteInt( fs, "y", image->roi->yOffset ); + cvWriteInt( fs, "width", image->roi->width ); + cvWriteInt( fs, "height", image->roi->height ); + cvWriteInt( fs, "coi", image->roi->coi ); + cvEndWriteStruct( fs ); + } + + depth = IPL2CV_DEPTH(image->depth); + sprintf( dt_buf, "%d%c", image->nChannels, icvTypeSymbol[depth] ); + dt = dt_buf + (dt_buf[2] == '\0' && dt_buf[0] == '1'); + cvWriteString( fs, "dt", dt, 0 ); + + size = cvSize(image->width, image->height); + if( size.width*image->nChannels*CV_ELEM_SIZE(depth) == image->widthStep ) + { + size.width *= size.height; + size.height = 1; + } + + cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW ); + for( y = 0; y < size.height; y++ ) + cvWriteRawData( fs, image->imageData + y*image->widthStep, size.width, dt ); + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); +} + + +static void* +icvReadImage( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + IplImage* image; + const char* dt; + CvFileNode* data; + CvFileNode* roi_node; + CvSeqReader reader; + CvRect roi; + int y, width, height, elem_type, coi, depth; + const char* origin, *data_order; + + width = cvReadIntByName( fs, node, "width", 0 ); + height = cvReadIntByName( fs, node, "height", 0 ); + dt = cvReadStringByName( fs, node, "dt", 0 ); + origin = cvReadStringByName( fs, node, "origin", 0 ); + + if( width == 0 || height == 0 || dt == 0 || origin == 0 ) + CV_Error( CV_StsError, "Some of essential image attributes are absent" ); + + elem_type = icvDecodeSimpleFormat( dt ); + data_order = cvReadStringByName( fs, node, "layout", "interleaved" ); + if( strcmp( data_order, "interleaved" ) != 0 ) + CV_Error( CV_StsError, "Only interleaved images can be read" ); + + data = cvGetFileNodeByName( fs, node, "data" ); + if( !data ) + CV_Error( CV_StsError, "The image data is not found in file storage" ); + + if( icvFileNodeSeqLen( data ) != width*height*CV_MAT_CN(elem_type) ) + CV_Error( CV_StsUnmatchedSizes, + "The matrix size does not match to the number of stored elements" ); + + depth = cvIplDepth(elem_type); + image = cvCreateImage( cvSize(width,height), depth, CV_MAT_CN(elem_type) ); + + roi_node = cvGetFileNodeByName( fs, node, "roi" ); + if( roi_node ) + { + roi.x = cvReadIntByName( fs, roi_node, "x", 0 ); + roi.y = cvReadIntByName( fs, roi_node, "y", 0 ); + roi.width = cvReadIntByName( fs, roi_node, "width", 0 ); + roi.height = cvReadIntByName( fs, roi_node, "height", 0 ); + coi = cvReadIntByName( fs, roi_node, "coi", 0 ); + + cvSetImageROI( image, roi ); + cvSetImageCOI( image, coi ); + } + + if( width*CV_ELEM_SIZE(elem_type) == image->widthStep ) + { + width *= height; + height = 1; + } + + width *= CV_MAT_CN(elem_type); + cvStartReadRawData( fs, data, &reader ); + for( y = 0; y < height; y++ ) + { + cvReadRawDataSlice( fs, &reader, width, + image->imageData + y*image->widthStep, dt ); + } + + ptr = image; + return ptr; +} + + +/******************************* CvSeq ******************************/ + +static int +icvIsSeq( const void* ptr ) +{ + return CV_IS_SEQ(ptr); +} + + +static void +icvReleaseSeq( void** ptr ) +{ + if( !ptr ) + CV_Error( CV_StsNullPtr, "NULL double pointer" ); + *ptr = 0; // it's impossible now to release seq, so just clear the pointer +} + + +static void* +icvCloneSeq( const void* ptr ) +{ + return cvSeqSlice( (CvSeq*)ptr, CV_WHOLE_SEQ, + 0 /* use the same storage as for the original sequence */, 1 ); +} + + +static void +icvWriteHeaderData( CvFileStorage* fs, const CvSeq* seq, + CvAttrList* attr, int initial_header_size ) +{ + char header_dt_buf[128]; + const char* header_dt = cvAttrValue( attr, "header_dt" ); + + if( header_dt ) + { + int dt_header_size; + dt_header_size = icvCalcElemSize( header_dt, initial_header_size ); + if( dt_header_size > seq->header_size ) + CV_Error( CV_StsUnmatchedSizes, + "The size of header calculated from \"header_dt\" is greater than header_size" ); + } + else if( seq->header_size > initial_header_size ) + { + if( CV_IS_SEQ(seq) && CV_IS_SEQ_POINT_SET(seq) && + seq->header_size == sizeof(CvPoint2DSeq) && + seq->elem_size == sizeof(int)*2 ) + { + CvPoint2DSeq* point_seq = (CvPoint2DSeq*)seq; + + cvStartWriteStruct( fs, "rect", CV_NODE_MAP + CV_NODE_FLOW ); + cvWriteInt( fs, "x", point_seq->rect.x ); + cvWriteInt( fs, "y", point_seq->rect.y ); + cvWriteInt( fs, "width", point_seq->rect.width ); + cvWriteInt( fs, "height", point_seq->rect.height ); + cvEndWriteStruct( fs ); + cvWriteInt( fs, "color", point_seq->color ); + } + else if( CV_IS_SEQ(seq) && CV_IS_SEQ_CHAIN(seq) && + CV_MAT_TYPE(seq->flags) == CV_8UC1 ) + { + CvChain* chain = (CvChain*)seq; + + cvStartWriteStruct( fs, "origin", CV_NODE_MAP + CV_NODE_FLOW ); + cvWriteInt( fs, "x", chain->origin.x ); + cvWriteInt( fs, "y", chain->origin.y ); + cvEndWriteStruct( fs ); + } + else + { + unsigned extra_size = seq->header_size - initial_header_size; + // a heuristic to provide nice defaults for sequences of int's & float's + if( extra_size % sizeof(int) == 0 ) + sprintf( header_dt_buf, "%ui", (unsigned)(extra_size/sizeof(int)) ); + else + sprintf( header_dt_buf, "%uu", extra_size ); + header_dt = header_dt_buf; + } + } + + if( header_dt ) + { + cvWriteString( fs, "header_dt", header_dt, 0 ); + cvStartWriteStruct( fs, "header_user_data", CV_NODE_SEQ + CV_NODE_FLOW ); + cvWriteRawData( fs, (uchar*)seq + sizeof(CvSeq), 1, header_dt ); + cvEndWriteStruct( fs ); + } +} + + +static char* +icvGetFormat( const CvSeq* seq, const char* dt_key, CvAttrList* attr, + int initial_elem_size, char* dt_buf ) +{ + char* dt = 0; + dt = (char*)cvAttrValue( attr, dt_key ); + + if( dt ) + { + int dt_elem_size; + dt_elem_size = icvCalcElemSize( dt, initial_elem_size ); + if( dt_elem_size != seq->elem_size ) + CV_Error( CV_StsUnmatchedSizes, + "The size of element calculated from \"dt\" and " + "the elem_size do not match" ); + } + else if( CV_MAT_TYPE(seq->flags) != 0 || seq->elem_size == 1 ) + { + if( CV_ELEM_SIZE(seq->flags) != seq->elem_size ) + CV_Error( CV_StsUnmatchedSizes, + "Size of sequence element (elem_size) is inconsistent with seq->flags" ); + dt = icvEncodeFormat( CV_MAT_TYPE(seq->flags), dt_buf ); + } + else if( seq->elem_size > initial_elem_size ) + { + unsigned extra_elem_size = seq->elem_size - initial_elem_size; + // a heuristic to provide nice defaults for sequences of int's & float's + if( extra_elem_size % sizeof(int) == 0 ) + sprintf( dt_buf, "%ui", (unsigned)(extra_elem_size/sizeof(int)) ); + else + sprintf( dt_buf, "%uu", extra_elem_size ); + dt = dt_buf; + } + + return dt; +} + + +static void +icvWriteSeq( CvFileStorage* fs, const char* name, + const void* struct_ptr, + CvAttrList attr, int level ) +{ + const CvSeq* seq = (CvSeq*)struct_ptr; + CvSeqBlock* block; + char buf[128]; + char dt_buf[128], *dt; + + assert( CV_IS_SEQ( seq )); + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_SEQ ); + + if( level >= 0 ) + cvWriteInt( fs, "level", level ); + + dt = icvGetFormat( seq, "dt", &attr, 0, dt_buf ); + + strcpy(buf, ""); + if( CV_IS_SEQ_CLOSED(seq) ) + strcat(buf, " closed"); + if( CV_IS_SEQ_HOLE(seq) ) + strcat(buf, " hole"); + if( CV_IS_SEQ_CURVE(seq) ) + strcat(buf, " curve"); + if( CV_SEQ_ELTYPE(seq) == 0 && seq->elem_size != 1 ) + strcat(buf, " untyped"); + + cvWriteString( fs, "flags", buf + (buf[0] ? 1 : 0), 1 ); + + cvWriteInt( fs, "count", seq->total ); + + cvWriteString( fs, "dt", dt, 0 ); + + icvWriteHeaderData( fs, seq, &attr, sizeof(CvSeq) ); + cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW ); + + for( block = seq->first; block; block = block->next ) + { + cvWriteRawData( fs, block->data, block->count, dt ); + if( block == seq->first->prev ) + break; + } + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); +} + + +static void +icvWriteSeqTree( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList attr ) +{ + const CvSeq* seq = (CvSeq*)struct_ptr; + const char* recursive_value = cvAttrValue( &attr, "recursive" ); + int is_recursive = recursive_value && + strcmp(recursive_value,"0") != 0 && + strcmp(recursive_value,"false") != 0 && + strcmp(recursive_value,"False") != 0 && + strcmp(recursive_value,"FALSE") != 0; + + assert( CV_IS_SEQ( seq )); + + if( !is_recursive ) + { + icvWriteSeq( fs, name, seq, attr, -1 ); + } + else + { + CvTreeNodeIterator tree_iterator; + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_SEQ_TREE ); + cvStartWriteStruct( fs, "sequences", CV_NODE_SEQ ); + cvInitTreeNodeIterator( &tree_iterator, seq, INT_MAX ); + + for(;;) + { + if( !tree_iterator.node ) + break; + icvWriteSeq( fs, 0, tree_iterator.node, attr, tree_iterator.level ); + cvNextTreeNode( &tree_iterator ); + } + + cvEndWriteStruct( fs ); + cvEndWriteStruct( fs ); + } +} + + +static void* +icvReadSeq( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + CvSeq* seq; + CvSeqBlock* block; + CvFileNode *data, *header_node, *rect_node, *origin_node; + CvSeqReader reader; + int total, flags; + int elem_size, header_size = sizeof(CvSeq); + int fmt_pairs[CV_FS_MAX_FMT_PAIRS], i, fmt_pair_count; + int items_per_elem = 0; + const char* flags_str; + const char* header_dt; + const char* dt; + char* endptr = 0; + + flags_str = cvReadStringByName( fs, node, "flags", 0 ); + total = cvReadIntByName( fs, node, "count", -1 ); + dt = cvReadStringByName( fs, node, "dt", 0 ); + + if( !flags_str || total == -1 || !dt ) + CV_Error( CV_StsError, "Some of essential sequence attributes are absent" ); + + flags = CV_SEQ_MAGIC_VAL; + + if( cv_isdigit(flags_str[0]) ) + { + const int OLD_SEQ_ELTYPE_BITS = 9; + const int OLD_SEQ_ELTYPE_MASK = (1 << OLD_SEQ_ELTYPE_BITS) - 1; + const int OLD_SEQ_KIND_BITS = 3; + const int OLD_SEQ_KIND_MASK = ((1 << OLD_SEQ_KIND_BITS) - 1) << OLD_SEQ_ELTYPE_BITS; + const int OLD_SEQ_KIND_CURVE = 1 << OLD_SEQ_ELTYPE_BITS; + const int OLD_SEQ_FLAG_SHIFT = OLD_SEQ_KIND_BITS + OLD_SEQ_ELTYPE_BITS; + const int OLD_SEQ_FLAG_CLOSED = 1 << OLD_SEQ_FLAG_SHIFT; + const int OLD_SEQ_FLAG_HOLE = 8 << OLD_SEQ_FLAG_SHIFT; + + int flags0 = (int)strtol( flags_str, &endptr, 16 ); + if( endptr == flags_str || (flags0 & CV_MAGIC_MASK) != CV_SEQ_MAGIC_VAL ) + CV_Error( CV_StsError, "The sequence flags are invalid" ); + if( (flags0 & OLD_SEQ_KIND_MASK) == OLD_SEQ_KIND_CURVE ) + flags |= CV_SEQ_KIND_CURVE; + if( flags0 & OLD_SEQ_FLAG_CLOSED ) + flags |= CV_SEQ_FLAG_CLOSED; + if( flags0 & OLD_SEQ_FLAG_HOLE ) + flags |= CV_SEQ_FLAG_HOLE; + flags |= flags0 & OLD_SEQ_ELTYPE_MASK; + } + else + { + if( strstr(flags_str, "curve") ) + flags |= CV_SEQ_KIND_CURVE; + if( strstr(flags_str, "closed") ) + flags |= CV_SEQ_FLAG_CLOSED; + if( strstr(flags_str, "hole") ) + flags |= CV_SEQ_FLAG_HOLE; + if( !strstr(flags_str, "untyped") ) + { + try + { + flags |= icvDecodeSimpleFormat(dt); + } + catch(...) + { + } + } + } + + header_dt = cvReadStringByName( fs, node, "header_dt", 0 ); + header_node = cvGetFileNodeByName( fs, node, "header_user_data" ); + + if( (header_dt != 0) ^ (header_node != 0) ) + CV_Error( CV_StsError, + "One of \"header_dt\" and \"header_user_data\" is there, while the other is not" ); + + rect_node = cvGetFileNodeByName( fs, node, "rect" ); + origin_node = cvGetFileNodeByName( fs, node, "origin" ); + + if( (header_node != 0) + (rect_node != 0) + (origin_node != 0) > 1 ) + CV_Error( CV_StsError, "Only one of \"header_user_data\", \"rect\" and \"origin\" tags may occur" ); + + if( header_dt ) + { + header_size = icvCalcElemSize( header_dt, header_size ); + } + else if( rect_node ) + header_size = sizeof(CvPoint2DSeq); + else if( origin_node ) + header_size = sizeof(CvChain); + + elem_size = icvCalcElemSize( dt, 0 ); + seq = cvCreateSeq( flags, header_size, elem_size, fs->dststorage ); + + if( header_node ) + { + cvReadRawData( fs, header_node, (char*)seq + sizeof(CvSeq), header_dt ); + } + else if( rect_node ) + { + CvPoint2DSeq* point_seq = (CvPoint2DSeq*)seq; + point_seq->rect.x = cvReadIntByName( fs, rect_node, "x", 0 ); + point_seq->rect.y = cvReadIntByName( fs, rect_node, "y", 0 ); + point_seq->rect.width = cvReadIntByName( fs, rect_node, "width", 0 ); + point_seq->rect.height = cvReadIntByName( fs, rect_node, "height", 0 ); + point_seq->color = cvReadIntByName( fs, node, "color", 0 ); + } + else if( origin_node ) + { + CvChain* chain = (CvChain*)seq; + chain->origin.x = cvReadIntByName( fs, origin_node, "x", 0 ); + chain->origin.y = cvReadIntByName( fs, origin_node, "y", 0 ); + } + + cvSeqPushMulti( seq, 0, total, 0 ); + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + fmt_pair_count *= 2; + for( i = 0; i < fmt_pair_count; i += 2 ) + items_per_elem += fmt_pairs[i]; + + data = cvGetFileNodeByName( fs, node, "data" ); + if( !data ) + CV_Error( CV_StsError, "The image data is not found in file storage" ); + + if( icvFileNodeSeqLen( data ) != total*items_per_elem ) + CV_Error( CV_StsError, "The number of stored elements does not match to \"count\"" ); + + cvStartReadRawData( fs, data, &reader ); + for( block = seq->first; block; block = block->next ) + { + int delta = block->count*items_per_elem; + cvReadRawDataSlice( fs, &reader, delta, block->data, dt ); + if( block == seq->first->prev ) + break; + } + + ptr = seq; + return ptr; +} + + +static void* +icvReadSeqTree( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + CvFileNode *sequences_node = cvGetFileNodeByName( fs, node, "sequences" ); + CvSeq* sequences; + CvSeq* root = 0; + CvSeq* parent = 0; + CvSeq* prev_seq = 0; + CvSeqReader reader; + int i, total; + int prev_level = 0; + + if( !sequences_node || !CV_NODE_IS_SEQ(sequences_node->tag) ) + CV_Error( CV_StsParseError, + "opencv-sequence-tree instance should contain a field \"sequences\" that should be a sequence" ); + + sequences = sequences_node->data.seq; + total = sequences->total; + + cvStartReadSeq( sequences, &reader, 0 ); + for( i = 0; i < total; i++ ) + { + CvFileNode* elem = (CvFileNode*)reader.ptr; + CvSeq* seq; + int level; + seq = (CvSeq*)cvRead( fs, elem ); + level = cvReadIntByName( fs, elem, "level", -1 ); + if( level < 0 ) + CV_Error( CV_StsParseError, "All the sequence tree nodes should contain \"level\" field" ); + if( !root ) + root = seq; + if( level > prev_level ) + { + assert( level == prev_level + 1 ); + parent = prev_seq; + prev_seq = 0; + if( parent ) + parent->v_next = seq; + } + else if( level < prev_level ) + { + for( ; prev_level > level; prev_level-- ) + prev_seq = prev_seq->v_prev; + parent = prev_seq->v_prev; + } + seq->h_prev = prev_seq; + if( prev_seq ) + prev_seq->h_next = seq; + seq->v_prev = parent; + prev_seq = seq; + prev_level = level; + CV_NEXT_SEQ_ELEM( sequences->elem_size, reader ); + } + + ptr = root; + return ptr; +} + +/******************************* CvGraph ******************************/ + +static int +icvIsGraph( const void* ptr ) +{ + return CV_IS_GRAPH(ptr); +} + + +static void +icvReleaseGraph( void** ptr ) +{ + if( !ptr ) + CV_Error( CV_StsNullPtr, "NULL double pointer" ); + + *ptr = 0; // it's impossible now to release graph, so just clear the pointer +} + + +static void* +icvCloneGraph( const void* ptr ) +{ + return cvCloneGraph( (const CvGraph*)ptr, 0 ); +} + + +static void +icvWriteGraph( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList attr ) +{ + int* flag_buf = 0; + char* write_buf = 0; + const CvGraph* graph = (const CvGraph*)struct_ptr; + CvSeqReader reader; + char buf[128]; + int i, k, vtx_count, edge_count; + char vtx_dt_buf[128], *vtx_dt; + char edge_dt_buf[128], *edge_dt; + int write_buf_size; + + assert( CV_IS_GRAPH(graph) ); + vtx_count = cvGraphGetVtxCount( graph ); + edge_count = cvGraphGetEdgeCount( graph ); + flag_buf = (int*)cvAlloc( vtx_count*sizeof(flag_buf[0])); + + // count vertices + cvStartReadSeq( (CvSeq*)graph, &reader ); + for( i = 0, k = 0; i < graph->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + CvGraphVtx* vtx = (CvGraphVtx*)reader.ptr; + flag_buf[k] = vtx->flags; + vtx->flags = k++; + } + CV_NEXT_SEQ_ELEM( graph->elem_size, reader ); + } + + // write header + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_GRAPH ); + + cvWriteString(fs, "flags", CV_IS_GRAPH_ORIENTED(graph) ? "oriented" : "", 1); + + cvWriteInt( fs, "vertex_count", vtx_count ); + vtx_dt = icvGetFormat( (CvSeq*)graph, "vertex_dt", + &attr, sizeof(CvGraphVtx), vtx_dt_buf ); + if( vtx_dt ) + cvWriteString( fs, "vertex_dt", vtx_dt, 0 ); + + cvWriteInt( fs, "edge_count", edge_count ); + edge_dt = icvGetFormat( (CvSeq*)graph->edges, "edge_dt", + &attr, sizeof(CvGraphEdge), buf ); + sprintf( edge_dt_buf, "2if%s", edge_dt ? edge_dt : "" ); + edge_dt = edge_dt_buf; + cvWriteString( fs, "edge_dt", edge_dt, 0 ); + + icvWriteHeaderData( fs, (CvSeq*)graph, &attr, sizeof(CvGraph) ); + + write_buf_size = MAX( 3*graph->elem_size, 1 << 16 ); + write_buf_size = MAX( 3*graph->edges->elem_size, write_buf_size ); + write_buf = (char*)cvAlloc( write_buf_size ); + + // as vertices and edges are written in similar way, + // do it as a parametrized 2-iteration loop + for( k = 0; k < 2; k++ ) + { + const char* dt = k == 0 ? vtx_dt : edge_dt; + if( dt ) + { + CvSet* data = k == 0 ? (CvSet*)graph : graph->edges; + int elem_size = data->elem_size; + int write_elem_size = icvCalcElemSize( dt, 0 ); + char* src_ptr = write_buf; + int write_max = write_buf_size / write_elem_size, write_count = 0; + + // alignment of user part of the edge data following 2if + int edge_user_align = sizeof(float); + + if( k == 1 ) + { + int fmt_pairs[CV_FS_MAX_FMT_PAIRS], fmt_pair_count; + fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + if( fmt_pair_count > 2 && CV_ELEM_SIZE(fmt_pairs[2*2+1]) >= (int)sizeof(double)) + edge_user_align = sizeof(double); + } + + cvStartWriteStruct( fs, k == 0 ? "vertices" : "edges", + CV_NODE_SEQ + CV_NODE_FLOW ); + cvStartReadSeq( (CvSeq*)data, &reader ); + for( i = 0; i < data->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + if( k == 0 ) // vertices + memcpy( src_ptr, reader.ptr + sizeof(CvGraphVtx), write_elem_size ); + else + { + CvGraphEdge* edge = (CvGraphEdge*)reader.ptr; + src_ptr = (char*)cvAlignPtr( src_ptr, sizeof(int) ); + ((int*)src_ptr)[0] = edge->vtx[0]->flags; + ((int*)src_ptr)[1] = edge->vtx[1]->flags; + *(float*)(src_ptr + sizeof(int)*2) = edge->weight; + if( elem_size > (int)sizeof(CvGraphEdge) ) + { + char* src_ptr2 = (char*)cvAlignPtr( src_ptr + 2*sizeof(int) + + sizeof(float), edge_user_align ); + memcpy( src_ptr2, edge + 1, elem_size - sizeof(CvGraphEdge) ); + } + } + src_ptr += write_elem_size; + if( ++write_count >= write_max ) + { + cvWriteRawData( fs, write_buf, write_count, dt ); + write_count = 0; + src_ptr = write_buf; + } + } + CV_NEXT_SEQ_ELEM( data->elem_size, reader ); + } + + if( write_count > 0 ) + cvWriteRawData( fs, write_buf, write_count, dt ); + cvEndWriteStruct( fs ); + } + } + + cvEndWriteStruct( fs ); + + // final stage. restore the graph flags + cvStartReadSeq( (CvSeq*)graph, &reader ); + vtx_count = 0; + for( i = 0; i < graph->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + ((CvGraphVtx*)reader.ptr)->flags = flag_buf[vtx_count++]; + CV_NEXT_SEQ_ELEM( graph->elem_size, reader ); + } + + cvFree( &write_buf ); + cvFree( &flag_buf ); +} + + +static void* +icvReadGraph( CvFileStorage* fs, CvFileNode* node ) +{ + void* ptr = 0; + char* read_buf = 0; + CvGraphVtx** vtx_buf = 0; + CvGraph* graph; + CvFileNode *header_node, *vtx_node, *edge_node; + int flags, vtx_count, edge_count; + int vtx_size = sizeof(CvGraphVtx), edge_size, header_size = sizeof(CvGraph); + int src_vtx_size = 0, src_edge_size; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS], fmt_pair_count; + int vtx_items_per_elem = 0, edge_items_per_elem = 0; + int edge_user_align = sizeof(float); + int read_buf_size; + int i, k; + const char* flags_str; + const char* header_dt; + const char* vtx_dt; + const char* edge_dt; + char* endptr = 0; + + flags_str = cvReadStringByName( fs, node, "flags", 0 ); + vtx_dt = cvReadStringByName( fs, node, "vertex_dt", 0 ); + edge_dt = cvReadStringByName( fs, node, "edge_dt", 0 ); + vtx_count = cvReadIntByName( fs, node, "vertex_count", -1 ); + edge_count = cvReadIntByName( fs, node, "edge_count", -1 ); + + if( !flags_str || vtx_count == -1 || edge_count == -1 || !edge_dt ) + CV_Error( CV_StsError, "Some of essential graph attributes are absent" ); + + flags = CV_SET_MAGIC_VAL + CV_GRAPH; + + if( isxdigit(flags_str[0]) ) + { + const int OLD_SEQ_ELTYPE_BITS = 9; + const int OLD_SEQ_KIND_BITS = 3; + const int OLD_SEQ_FLAG_SHIFT = OLD_SEQ_KIND_BITS + OLD_SEQ_ELTYPE_BITS; + const int OLD_GRAPH_FLAG_ORIENTED = 1 << OLD_SEQ_FLAG_SHIFT; + + int flags0 = (int)strtol( flags_str, &endptr, 16 ); + if( endptr == flags_str || (flags0 & CV_MAGIC_MASK) != CV_SET_MAGIC_VAL ) + CV_Error( CV_StsError, "The sequence flags are invalid" ); + if( flags0 & OLD_GRAPH_FLAG_ORIENTED ) + flags |= CV_GRAPH_FLAG_ORIENTED; + } + else + { + if( strstr(flags_str, "oriented") ) + flags |= CV_GRAPH_FLAG_ORIENTED; + } + + header_dt = cvReadStringByName( fs, node, "header_dt", 0 ); + header_node = cvGetFileNodeByName( fs, node, "header_user_data" ); + + if( (header_dt != 0) ^ (header_node != 0) ) + CV_Error( CV_StsError, + "One of \"header_dt\" and \"header_user_data\" is there, while the other is not" ); + + if( header_dt ) + header_size = icvCalcElemSize( header_dt, header_size ); + + if( vtx_dt ) + { + src_vtx_size = icvCalcElemSize( vtx_dt, 0 ); + vtx_size = icvCalcElemSize( vtx_dt, vtx_size ); + fmt_pair_count = icvDecodeFormat( edge_dt, + fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + fmt_pair_count *= 2; + for( i = 0; i < fmt_pair_count; i += 2 ) + vtx_items_per_elem += fmt_pairs[i]; + } + + { + char dst_edge_dt_buf[128]; + const char* dst_edge_dt = 0; + + fmt_pair_count = icvDecodeFormat( edge_dt, + fmt_pairs, CV_FS_MAX_FMT_PAIRS ); + if( fmt_pair_count < 2 || + fmt_pairs[0] != 2 || fmt_pairs[1] != CV_32S || + fmt_pairs[2] < 1 || fmt_pairs[3] != CV_32F ) + CV_Error( CV_StsBadArg, + "Graph edges should start with 2 integers and a float" ); + + // alignment of user part of the edge data following 2if + if( fmt_pair_count > 2 && CV_ELEM_SIZE(fmt_pairs[5]) >= (int)sizeof(double)) + edge_user_align = sizeof(double); + + fmt_pair_count *= 2; + for( i = 0; i < fmt_pair_count; i += 2 ) + edge_items_per_elem += fmt_pairs[i]; + + if( edge_dt[2] == 'f' || (edge_dt[2] == '1' && edge_dt[3] == 'f') ) + dst_edge_dt = edge_dt + 3 + cv_isdigit(edge_dt[2]); + else + { + int val = (int)strtol( edge_dt + 2, &endptr, 10 ); + sprintf( dst_edge_dt_buf, "%df%s", val-1, endptr ); + dst_edge_dt = dst_edge_dt_buf; + } + + edge_size = icvCalcElemSize( dst_edge_dt, sizeof(CvGraphEdge) ); + src_edge_size = icvCalcElemSize( edge_dt, 0 ); + } + + graph = cvCreateGraph( flags, header_size, vtx_size, edge_size, fs->dststorage ); + + if( header_node ) + cvReadRawData( fs, header_node, (char*)graph + sizeof(CvGraph), header_dt ); + + read_buf_size = MAX( src_vtx_size*3, 1 << 16 ); + read_buf_size = MAX( src_edge_size*3, read_buf_size ); + read_buf = (char*)cvAlloc( read_buf_size ); + vtx_buf = (CvGraphVtx**)cvAlloc( vtx_count * sizeof(vtx_buf[0]) ); + + vtx_node = cvGetFileNodeByName( fs, node, "vertices" ); + edge_node = cvGetFileNodeByName( fs, node, "edges" ); + if( !edge_node ) + CV_Error( CV_StsBadArg, "No edges data" ); + if( vtx_dt && !vtx_node ) + CV_Error( CV_StsBadArg, "No vertices data" ); + + // as vertices and edges are read in similar way, + // do it as a parametrized 2-iteration loop + for( k = 0; k < 2; k++ ) + { + const char* dt = k == 0 ? vtx_dt : edge_dt; + int elem_size = k == 0 ? vtx_size : edge_size; + int src_elem_size = k == 0 ? src_vtx_size : src_edge_size; + int items_per_elem = k == 0 ? vtx_items_per_elem : edge_items_per_elem; + int elem_count = k == 0 ? vtx_count : edge_count; + char* dst_ptr = read_buf; + int read_max = read_buf_size /MAX(src_elem_size, 1), read_count = 0; + CvSeqReader reader; + if(dt) + cvStartReadRawData( fs, k == 0 ? vtx_node : edge_node, &reader ); + + for( i = 0; i < elem_count; i++ ) + { + if( read_count == 0 && dt ) + { + int count = MIN( elem_count - i, read_max )*items_per_elem; + cvReadRawDataSlice( fs, &reader, count, read_buf, dt ); + read_count = count; + dst_ptr = read_buf; + } + + if( k == 0 ) + { + CvGraphVtx* vtx; + cvGraphAddVtx( graph, 0, &vtx ); + vtx_buf[i] = vtx; + if( dt ) + memcpy( vtx + 1, dst_ptr, src_elem_size ); + } + else + { + CvGraphEdge* edge = 0; + int vtx1 = ((int*)dst_ptr)[0]; + int vtx2 = ((int*)dst_ptr)[1]; + int result; + + if( (unsigned)vtx1 >= (unsigned)vtx_count || + (unsigned)vtx2 >= (unsigned)vtx_count ) + CV_Error( CV_StsOutOfRange, + "Some of stored vertex indices are out of range" ); + + result = cvGraphAddEdgeByPtr( graph, + vtx_buf[vtx1], vtx_buf[vtx2], 0, &edge ); + + if( result == 0 ) + CV_Error( CV_StsBadArg, "Duplicated edge has occured" ); + + edge->weight = *(float*)(dst_ptr + sizeof(int)*2); + if( elem_size > (int)sizeof(CvGraphEdge) ) + { + char* dst_ptr2 = (char*)cvAlignPtr( dst_ptr + sizeof(int)*2 + + sizeof(float), edge_user_align ); + memcpy( edge + 1, dst_ptr2, elem_size - sizeof(CvGraphEdge) ); + } + } + + dst_ptr += src_elem_size; + read_count--; + } + } + + ptr = graph; + cvFree( &read_buf ); + cvFree( &vtx_buf ); + + return ptr; +} + +/****************************************************************************************\ +* RTTI Functions * +\****************************************************************************************/ + +CvTypeInfo *CvType::first = 0, *CvType::last = 0; + +CvType::CvType( const char* type_name, + CvIsInstanceFunc is_instance, CvReleaseFunc release, + CvReadFunc read, CvWriteFunc write, CvCloneFunc clone ) +{ + CvTypeInfo _info; + _info.flags = 0; + _info.header_size = sizeof(_info); + _info.type_name = type_name; + _info.prev = _info.next = 0; + _info.is_instance = is_instance; + _info.release = release; + _info.clone = clone; + _info.read = read; + _info.write = write; + + cvRegisterType( &_info ); + info = first; +} + + +CvType::~CvType() +{ + cvUnregisterType( info->type_name ); +} + + +CvType seq_type( CV_TYPE_NAME_SEQ, icvIsSeq, icvReleaseSeq, icvReadSeq, + icvWriteSeqTree /* this is the entry point for + writing a single sequence too */, icvCloneSeq ); + +CvType seq_tree_type( CV_TYPE_NAME_SEQ_TREE, icvIsSeq, icvReleaseSeq, + icvReadSeqTree, icvWriteSeqTree, icvCloneSeq ); + +CvType seq_graph_type( CV_TYPE_NAME_GRAPH, icvIsGraph, icvReleaseGraph, + icvReadGraph, icvWriteGraph, icvCloneGraph ); + +CvType sparse_mat_type( CV_TYPE_NAME_SPARSE_MAT, icvIsSparseMat, + (CvReleaseFunc)cvReleaseSparseMat, icvReadSparseMat, + icvWriteSparseMat, (CvCloneFunc)cvCloneSparseMat ); + +CvType image_type( CV_TYPE_NAME_IMAGE, icvIsImage, (CvReleaseFunc)cvReleaseImage, + icvReadImage, icvWriteImage, (CvCloneFunc)cvCloneImage ); + +CvType mat_type( CV_TYPE_NAME_MAT, icvIsMat, (CvReleaseFunc)cvReleaseMat, + icvReadMat, icvWriteMat, (CvCloneFunc)cvCloneMat ); + +CvType matnd_type( CV_TYPE_NAME_MATND, icvIsMatND, (CvReleaseFunc)cvReleaseMatND, + icvReadMatND, icvWriteMatND, (CvCloneFunc)cvCloneMatND ); + +CV_IMPL void +cvRegisterType( const CvTypeInfo* _info ) +{ + CvTypeInfo* info = 0; + int i, len; + char c; + + //if( !CvType::first ) + // icvCreateStandardTypes(); + + if( !_info || _info->header_size != sizeof(CvTypeInfo) ) + CV_Error( CV_StsBadSize, "Invalid type info" ); + + if( !_info->is_instance || !_info->release || + !_info->read || !_info->write ) + CV_Error( CV_StsNullPtr, + "Some of required function pointers " + "(is_instance, release, read or write) are NULL"); + + c = _info->type_name[0]; + if( !cv_isalpha(c) && c != '_' ) + CV_Error( CV_StsBadArg, "Type name should start with a letter or _" ); + + len = (int)strlen(_info->type_name); + + for( i = 0; i < len; i++ ) + { + c = _info->type_name[i]; + if( !cv_isalnum(c) && c != '-' && c != '_' ) + CV_Error( CV_StsBadArg, + "Type name should contain only letters, digits, - and _" ); + } + + info = (CvTypeInfo*)malloc( sizeof(*info) + len + 1 ); + + *info = *_info; + info->type_name = (char*)(info + 1); + memcpy( (char*)info->type_name, _info->type_name, len + 1 ); + + info->flags = 0; + info->next = CvType::first; + info->prev = 0; + if( CvType::first ) + CvType::first->prev = info; + else + CvType::last = info; + CvType::first = info; +} + + +CV_IMPL void +cvUnregisterType( const char* type_name ) +{ + CvTypeInfo* info; + + info = cvFindType( type_name ); + if( info ) + { + if( info->prev ) + info->prev->next = info->next; + else + CvType::first = info->next; + + if( info->next ) + info->next->prev = info->prev; + else + CvType::last = info->prev; + + if( !CvType::first || !CvType::last ) + CvType::first = CvType::last = 0; + + free( info ); + } +} + + +CV_IMPL CvTypeInfo* +cvFirstType( void ) +{ + return CvType::first; +} + + +CV_IMPL CvTypeInfo* +cvFindType( const char* type_name ) +{ + CvTypeInfo* info = 0; + + if (type_name) + for( info = CvType::first; info != 0; info = info->next ) + if( strcmp( info->type_name, type_name ) == 0 ) + break; + + return info; +} + + +CV_IMPL CvTypeInfo* +cvTypeOf( const void* struct_ptr ) +{ + CvTypeInfo* info = 0; + + if( struct_ptr ) + { + for( info = CvType::first; info != 0; info = info->next ) + if( info->is_instance( struct_ptr )) + break; + } + + return info; +} + + +/* universal functions */ +CV_IMPL void +cvRelease( void** struct_ptr ) +{ + CvTypeInfo* info; + + if( !struct_ptr ) + CV_Error( CV_StsNullPtr, "NULL double pointer" ); + + if( *struct_ptr ) + { + info = cvTypeOf( *struct_ptr ); + if( !info ) + CV_Error( CV_StsError, "Unknown object type" ); + if( !info->release ) + CV_Error( CV_StsError, "release function pointer is NULL" ); + + info->release( struct_ptr ); + *struct_ptr = 0; + } +} + + +void* cvClone( const void* struct_ptr ) +{ + void* struct_copy = 0; + CvTypeInfo* info; + + if( !struct_ptr ) + CV_Error( CV_StsNullPtr, "NULL structure pointer" ); + + info = cvTypeOf( struct_ptr ); + if( !info ) + CV_Error( CV_StsError, "Unknown object type" ); + if( !info->clone ) + CV_Error( CV_StsError, "clone function pointer is NULL" ); + + struct_copy = info->clone( struct_ptr ); + return struct_copy; +} + + +/* reads matrix, image, sequence, graph etc. */ +CV_IMPL void* +cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* list ) +{ + void* obj = 0; + CV_CHECK_FILE_STORAGE( fs ); + + if( !node ) + return 0; + + if( !CV_NODE_IS_USER(node->tag) || !node->info ) + CV_Error( CV_StsError, "The node does not represent a user object (unknown type?)" ); + + obj = node->info->read( fs, node ); + if( list ) + *list = cvAttrList(0,0); + + return obj; +} + + +/* writes matrix, image, sequence, graph etc. */ +CV_IMPL void +cvWrite( CvFileStorage* fs, const char* name, + const void* ptr, CvAttrList attributes ) +{ + CvTypeInfo* info; + + CV_CHECK_OUTPUT_FILE_STORAGE( fs ); + + if( !ptr ) + CV_Error( CV_StsNullPtr, "Null pointer to the written object" ); + + info = cvTypeOf( ptr ); + if( !info ) + CV_Error( CV_StsBadArg, "Unknown object" ); + + if( !info->write ) + CV_Error( CV_StsBadArg, "The object does not have write function" ); + + info->write( fs, name, ptr, attributes ); +} + + +/* simple API for reading/writing data */ +CV_IMPL void +cvSave( const char* filename, const void* struct_ptr, + const char* _name, const char* comment, CvAttrList attributes ) +{ + CvFileStorage* fs = 0; + + if( !struct_ptr ) + CV_Error( CV_StsNullPtr, "NULL object pointer" ); + + fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE ); + if( !fs ) + CV_Error( CV_StsError, "Could not open the file storage. Check the path and permissions" ); + + cv::string name = _name ? cv::string(_name) : cv::FileStorage::getDefaultObjectName(filename); + + if( comment ) + cvWriteComment( fs, comment, 0 ); + cvWrite( fs, name.c_str(), struct_ptr, attributes ); + cvReleaseFileStorage( &fs ); +} + +CV_IMPL void* +cvLoad( const char* filename, CvMemStorage* memstorage, + const char* name, const char** _real_name ) +{ + void* ptr = 0; + const char* real_name = 0; + cv::FileStorage fs(cvOpenFileStorage(filename, memstorage, CV_STORAGE_READ)); + + CvFileNode* node = 0; + + if( !fs.isOpened() ) + return 0; + + if( name ) + { + node = cvGetFileNodeByName( *fs, 0, name ); + } + else + { + int i, k; + for( k = 0; k < (*fs)->roots->total; k++ ) + { + CvSeq* seq; + CvSeqReader reader; + + node = (CvFileNode*)cvGetSeqElem( (*fs)->roots, k ); + if( !CV_NODE_IS_MAP( node->tag )) + return 0; + seq = node->data.seq; + node = 0; + + cvStartReadSeq( seq, &reader, 0 ); + + // find the first element in the map + for( i = 0; i < seq->total; i++ ) + { + if( CV_IS_SET_ELEM( reader.ptr )) + { + node = (CvFileNode*)reader.ptr; + goto stop_search; + } + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + } + } + +stop_search: + ; + } + + if( !node ) + CV_Error( CV_StsObjectNotFound, "Could not find the/an object in file storage" ); + + real_name = cvGetFileNodeName( node ); + ptr = cvRead( *fs, node, 0 ); + + // sanity check + if( !memstorage && (CV_IS_SEQ( ptr ) || CV_IS_SET( ptr )) ) + CV_Error( CV_StsNullPtr, + "NULL memory storage is passed - the loaded dynamic structure can not be stored" ); + + if( cvGetErrStatus() < 0 ) + { + cvRelease( (void**)&ptr ); + real_name = 0; + } + + if( _real_name) + { + if (real_name) + { + *_real_name = (const char*)cvAlloc(strlen(real_name)); + memcpy((void*)*_real_name, real_name, strlen(real_name)); + } else { + *_real_name = 0; + } + } + + return ptr; +} + + +///////////////////////// new C++ interface for CvFileStorage /////////////////////////// + +namespace cv +{ + +static void getElemSize( const string& fmt, size_t& elemSize, size_t& cn ) +{ + const char* dt = fmt.c_str(); + cn = 1; + if( cv_isdigit(dt[0]) ) + { + cn = dt[0] - '0'; + dt++; + } + char c = dt[0]; + elemSize = cn*(c == 'u' || c == 'c' ? sizeof(uchar) : c == 'w' || c == 's' ? sizeof(ushort) : + c == 'i' ? sizeof(int) : c == 'f' ? sizeof(float) : c == 'd' ? sizeof(double) : + c == 'r' ? sizeof(void*) : (size_t)0); +} + +FileStorage::FileStorage() +{ + state = UNDEFINED; +} + +FileStorage::FileStorage(const string& filename, int flags, const string& encoding) +{ + state = UNDEFINED; + open( filename, flags, encoding ); +} + +FileStorage::FileStorage(CvFileStorage* _fs) +{ + fs = Ptr(_fs); + state = _fs ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED; +} + +FileStorage::~FileStorage() +{ + while( structs.size() > 0 ) + { + cvEndWriteStruct(fs); + structs.pop_back(); + } +} + +bool FileStorage::open(const string& filename, int flags, const string& encoding) +{ + release(); + fs = Ptr(cvOpenFileStorage( filename.c_str(), 0, flags, + !encoding.empty() ? encoding.c_str() : 0)); + bool ok = isOpened(); + state = ok ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED; + return ok; +} + +bool FileStorage::isOpened() const +{ + return !fs.empty() && fs.obj->is_opened; +} + +void FileStorage::release() +{ + fs.release(); + structs.clear(); + state = UNDEFINED; +} + +string FileStorage::releaseAndGetString() +{ + string buf; + buf.reserve(16); // HACK: Work around for compiler bug + if( fs.obj && fs.obj->outbuf ) + icvClose(fs.obj, &buf); + + release(); + return buf; +} + +FileNode FileStorage::root(int streamidx) const +{ + return isOpened() ? FileNode(fs, cvGetRootFileNode(fs, streamidx)) : FileNode(); +} + +FileStorage& operator << (FileStorage& fs, const string& str) +{ + enum { NAME_EXPECTED = FileStorage::NAME_EXPECTED, + VALUE_EXPECTED = FileStorage::VALUE_EXPECTED, + INSIDE_MAP = FileStorage::INSIDE_MAP }; + const char* _str = str.c_str(); + if( !fs.isOpened() || !_str ) + return fs; + if( *_str == '}' || *_str == ']' ) + { + if( fs.structs.empty() ) + CV_Error_( CV_StsError, ("Extra closing '%c'", *_str) ); + if( (*_str == ']' ? '[' : '{') != fs.structs.back() ) + CV_Error_( CV_StsError, + ("The closing '%c' does not match the opening '%c'", *_str, fs.structs.back())); + fs.structs.pop_back(); + fs.state = fs.structs.empty() || fs.structs.back() == '{' ? + INSIDE_MAP + NAME_EXPECTED : VALUE_EXPECTED; + cvEndWriteStruct( *fs ); + fs.elname = string(); + } + else if( fs.state == NAME_EXPECTED + INSIDE_MAP ) + { + if( !cv_isalpha(*_str) ) + CV_Error_( CV_StsError, ("Incorrect element name %s", _str) ); + fs.elname = str; + fs.state = VALUE_EXPECTED + INSIDE_MAP; + } + else if( (fs.state & 3) == VALUE_EXPECTED ) + { + if( *_str == '{' || *_str == '[' ) + { + fs.structs.push_back(*_str); + int flags = *_str++ == '{' ? CV_NODE_MAP : CV_NODE_SEQ; + fs.state = flags == CV_NODE_MAP ? INSIDE_MAP + + NAME_EXPECTED : VALUE_EXPECTED; + if( *_str == ':' ) + { + flags |= CV_NODE_FLOW; + _str++; + } + cvStartWriteStruct( *fs, fs.elname.size() > 0 ? fs.elname.c_str() : 0, + flags, *_str ? _str : 0 ); + fs.elname = string(); + } + else + { + write( fs, fs.elname, (_str[0] == '\\' && (_str[1] == '{' || _str[1] == '}' || + _str[1] == '[' || _str[1] == ']')) ? string(_str+1) : str ); + if( fs.state == INSIDE_MAP + VALUE_EXPECTED ) + fs.state = INSIDE_MAP + NAME_EXPECTED; + } + } + else + CV_Error( CV_StsError, "Invalid fs.state" ); + return fs; +} + + +void FileStorage::writeRaw( const string& fmt, const uchar* vec, size_t len ) +{ + if( !isOpened() ) + return; + size_t elemSize, cn; + getElemSize( fmt, elemSize, cn ); + CV_Assert( len % elemSize == 0 ); + cvWriteRawData( fs, vec, (int)(len/elemSize), fmt.c_str()); +} + + +void FileStorage::writeObj( const string& name, const void* obj ) +{ + if( !isOpened() ) + return; + cvWrite( fs, name.size() > 0 ? name.c_str() : 0, obj ); +} + + +FileNode FileStorage::operator[](const string& nodename) const +{ + return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename.c_str())); +} + +FileNode FileStorage::operator[](const char* nodename) const +{ + return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename)); +} + +FileNode FileNode::operator[](const string& nodename) const +{ + return FileNode(fs, cvGetFileNodeByName(fs, node, nodename.c_str())); +} + +FileNode FileNode::operator[](const char* nodename) const +{ + return FileNode(fs, cvGetFileNodeByName(fs, node, nodename)); +} + +FileNode FileNode::operator[](int i) const +{ + return isSeq() ? FileNode(fs, (CvFileNode*)cvGetSeqElem(node->data.seq, i)) : + i == 0 ? *this : FileNode(); +} + +string FileNode::name() const +{ + const char* str; + return !node || (str = cvGetFileNodeName(node)) == 0 ? string() : string(str); +} + +void* FileNode::readObj() const +{ + if( !fs || !node ) + return 0; + return cvRead( (CvFileStorage*)fs, (CvFileNode*)node ); +} + +FileNodeIterator::FileNodeIterator() +{ + fs = 0; + container = 0; + reader.ptr = 0; + remaining = 0; +} + +FileNodeIterator::FileNodeIterator(const CvFileStorage* _fs, + const CvFileNode* _node, size_t _ofs) +{ + if( _fs && _node && CV_NODE_TYPE(_node->tag) != CV_NODE_NONE ) + { + int node_type = _node->tag & FileNode::TYPE_MASK; + fs = _fs; + container = _node; + if( !(_node->tag & FileNode::USER) && (node_type == FileNode::SEQ || node_type == FileNode::MAP) ) + { + cvStartReadSeq( _node->data.seq, &reader ); + remaining = FileNode(_fs, _node).size(); + } + else + { + reader.ptr = (schar*)_node; + reader.seq = 0; + remaining = 1; + } + (*this) += (int)_ofs; + } + else + { + fs = 0; + container = 0; + reader.ptr = 0; + remaining = 0; + } +} + +FileNodeIterator::FileNodeIterator(const FileNodeIterator& it) +{ + fs = it.fs; + container = it.container; + reader = it.reader; + remaining = it.remaining; +} + +FileNodeIterator& FileNodeIterator::operator ++() +{ + if( remaining > 0 ) + { + if( reader.seq ) + CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); + remaining--; + } + return *this; +} + +FileNodeIterator FileNodeIterator::operator ++(int) +{ + FileNodeIterator it = *this; + ++(*this); + return it; +} + +FileNodeIterator& FileNodeIterator::operator --() +{ + if( remaining < FileNode(fs, container).size() ) + { + if( reader.seq ) + CV_PREV_SEQ_ELEM( reader.seq->elem_size, reader ); + remaining++; + } + return *this; +} + +FileNodeIterator FileNodeIterator::operator --(int) +{ + FileNodeIterator it = *this; + --(*this); + return it; +} + +FileNodeIterator& FileNodeIterator::operator += (int ofs) +{ + if( ofs == 0 ) + return *this; + if( ofs > 0 ) + ofs = std::min(ofs, (int)remaining); + else + { + size_t count = FileNode(fs, container).size(); + ofs = (int)(remaining - std::min(remaining - ofs, count)); + } + remaining -= ofs; + if( reader.seq ) + cvSetSeqReaderPos( &reader, ofs, 1 ); + return *this; +} + +FileNodeIterator& FileNodeIterator::operator -= (int ofs) +{ + return operator += (-ofs); +} + + +FileNodeIterator& FileNodeIterator::readRaw( const string& fmt, uchar* vec, size_t maxCount ) +{ + if( fs && container && remaining > 0 ) + { + size_t elem_size, cn; + getElemSize( fmt, elem_size, cn ); + CV_Assert( elem_size > 0 ); + size_t count = std::min(remaining, maxCount); + + if( reader.seq ) + { + cvReadRawDataSlice( fs, &reader, (int)count, vec, fmt.c_str() ); + remaining -= count*cn; + } + else + { + cvReadRawData( fs, container, vec, fmt.c_str() ); + remaining = 0; + } + } + return *this; +} + + +void write( FileStorage& fs, const string& name, int value ) +{ cvWriteInt( *fs, name.size() ? name.c_str() : 0, value ); } + +void write( FileStorage& fs, const string& name, float value ) +{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); } + +void write( FileStorage& fs, const string& name, double value ) +{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); } + +void write( FileStorage& fs, const string& name, const string& value ) +{ cvWriteString( *fs, name.size() ? name.c_str() : 0, value.c_str() ); } + +void writeScalar(FileStorage& fs, int value ) +{ cvWriteInt( *fs, 0, value ); } + +void writeScalar(FileStorage& fs, float value ) +{ cvWriteReal( *fs, 0, value ); } + +void writeScalar(FileStorage& fs, double value ) +{ cvWriteReal( *fs, 0, value ); } + +void writeScalar(FileStorage& fs, const string& value ) +{ cvWriteString( *fs, 0, value.c_str() ); } + + +void write( FileStorage& fs, const string& name, const Mat& value ) +{ + if( value.dims <= 2 ) + { + CvMat mat = value; + cvWrite( *fs, name.size() ? name.c_str() : 0, &mat ); + } + else + { + CvMatND mat = value; + cvWrite( *fs, name.size() ? name.c_str() : 0, &mat ); + } +} + +// TODO: the 4 functions below need to be implemented more efficiently +void write( FileStorage& fs, const string& name, const SparseMat& value ) +{ + Ptr mat = (CvSparseMat*)value; + cvWrite( *fs, name.size() ? name.c_str() : 0, mat ); +} + + +WriteStructContext::WriteStructContext(FileStorage& _fs, const string& name, + int flags, const string& typeName) : fs(&_fs) +{ + cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags, + !typeName.empty() ? typeName.c_str() : 0); +} + +WriteStructContext::~WriteStructContext() { cvEndWriteStruct(**fs); } + + +void read( const FileNode& node, Mat& mat, const Mat& default_mat ) +{ + if( node.empty() ) + { + default_mat.copyTo(mat); + return; + } + void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node); + if(CV_IS_MAT_HDR_Z(obj)) + { + Mat((const CvMat*)obj).copyTo(mat); + cvReleaseMat((CvMat**)&obj); + } + else if(CV_IS_MATND_HDR(obj)) + { + Mat((const CvMatND*)obj).copyTo(mat); + cvReleaseMatND((CvMatND**)&obj); + } + else + { + cvRelease(&obj); + CV_Error(CV_StsBadArg, "Unknown array type"); + } +} + +void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat ) +{ + if( node.empty() ) + { + default_mat.copyTo(mat); + return; + } + Ptr m = (CvSparseMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node); + CV_Assert(CV_IS_SPARSE_MAT(m)); + SparseMat(m).copyTo(mat); +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/precomp.cpp diffimg-2.0.0/3rdparty/opencv/core/src/precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,45 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/precomp.hpp diffimg-2.0.0/3rdparty/opencv/core/src/precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/core/src/precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,206 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_PRECOMP_H__ +#define __OPENCV_PRECOMP_H__ + +#ifdef HAVE_CVCONFIG_H +#include "cvconfig.h" +#endif + +#include "opencv2/core/core.hpp" +#include "opencv2/core/core_c.h" +#include "opencv2/core/internal.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_TEGRA_OPTIMIZATION +#include "opencv2/core/core_tegra.hpp" +#else +#define GET_OPTIMIZED(func) (func) +#endif + +namespace cv +{ + +// -128.f ... 255.f +extern const float g_8x32fTab[]; +#define CV_8TO32F(x) cv::g_8x32fTab[(x)+128] + +extern const ushort g_8x16uSqrTab[]; +#define CV_SQR_8U(x) cv::g_8x16uSqrTab[(x)+255] + +extern const char* g_HersheyGlyphs[]; + +extern const uchar g_Saturate8u[]; +#define CV_FAST_CAST_8U(t) (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256]) +#define CV_MIN_8U(a,b) ((a) - CV_FAST_CAST_8U((a) - (b))) +#define CV_MAX_8U(a,b) ((a) + CV_FAST_CAST_8U((b) - (a))) + + +#if defined WIN32 || defined _WIN32 +void deleteThreadAllocData(); +void deleteThreadRNGData(); +#endif + +template struct OpAdd +{ + typedef T1 type1; + typedef T2 type2; + typedef T3 rtype; + T3 operator ()(const T1 a, const T2 b) const { return saturate_cast(a + b); } +}; + +template struct OpSub +{ + typedef T1 type1; + typedef T2 type2; + typedef T3 rtype; + T3 operator ()(const T1 a, const T2 b) const { return saturate_cast(a - b); } +}; + +template struct OpRSub +{ + typedef T1 type1; + typedef T2 type2; + typedef T3 rtype; + T3 operator ()(const T1 a, const T2 b) const { return saturate_cast(b - a); } +}; + +template struct OpMin +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator ()(const T a, const T b) const { return std::min(a, b); } +}; + +template struct OpMax +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator ()(const T a, const T b) const { return std::max(a, b); } +}; + +inline Size getContinuousSize( const Mat& m1, int widthScale=1 ) +{ + return m1.isContinuous() ? Size(m1.cols*m1.rows*widthScale, 1) : + Size(m1.cols*widthScale, m1.rows); +} + +inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) +{ + return (m1.flags & m2.flags & Mat::CONTINUOUS_FLAG) != 0 ? + Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); +} + +inline Size getContinuousSize( const Mat& m1, const Mat& m2, + const Mat& m3, int widthScale=1 ) +{ + return (m1.flags & m2.flags & m3.flags & Mat::CONTINUOUS_FLAG) != 0 ? + Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); +} + +inline Size getContinuousSize( const Mat& m1, const Mat& m2, + const Mat& m3, const Mat& m4, + int widthScale=1 ) +{ + return (m1.flags & m2.flags & m3.flags & m4.flags & Mat::CONTINUOUS_FLAG) != 0 ? + Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); +} + +inline Size getContinuousSize( const Mat& m1, const Mat& m2, + const Mat& m3, const Mat& m4, + const Mat& m5, int widthScale=1 ) +{ + return (m1.flags & m2.flags & m3.flags & m4.flags & m5.flags & Mat::CONTINUOUS_FLAG) != 0 ? + Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); +} + +struct NoVec +{ + size_t operator()(const void*, const void*, void*, size_t) const { return 0; } +}; + +extern volatile bool USE_SSE2; +extern volatile bool USE_SSE4_2; +extern volatile bool USE_AVX; + +enum { BLOCK_SIZE = 1024 }; + +#ifdef HAVE_IPP +static inline IppiSize ippiSize(int width, int height) { IppiSize sz = { width, height}; return sz; } +static inline IppiSize ippiSize(Size _sz) { IppiSize sz = { _sz.width, _sz.height}; return sz; } +#endif + +#if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7) +#define ARITHM_USE_IPP 1 +#define IF_IPP(then_call, else_call) then_call +#else +#define ARITHM_USE_IPP 0 +#define IF_IPP(then_call, else_call) else_call +#endif + +inline bool checkScalar(const Mat& sc, int atype, int sckind, int akind) +{ + if( sc.dims > 2 || (sc.cols != 1 && sc.rows != 1) || !sc.isContinuous() ) + return false; + int cn = CV_MAT_CN(atype); + if( akind == _InputArray::MATX && sckind != _InputArray::MATX ) + return false; + return sc.size() == Size(1, 1) || sc.size() == Size(1, cn) || sc.size() == Size(cn, 1) || + (sc.size() == Size(1, 4) && sc.type() == CV_64F && cn <= 4); +} + +void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize ); + +} + +#endif /*_CXCORE_INTERNAL_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/rand.cpp diffimg-2.0.0/3rdparty/opencv/core/src/rand.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/rand.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/rand.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,886 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Filling CvMat/IplImage instances with random numbers +// +// */ + +#include "precomp.hpp" + +#if defined WIN32 || defined WINCE + #include + #undef small + #undef min + #undef max + #undef abs +#endif + +#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP) + #include "emmintrin.h" +#endif + +namespace cv +{ + +///////////////////////////// Functions Declaration ////////////////////////////////////// + +/* + Multiply-with-carry generator is used here: + temp = ( A*X(n) + carry ) + X(n+1) = temp mod (2^32) + carry = temp / (2^32) +*/ + +#define RNG_NEXT(x) ((uint64)(unsigned)(x)*CV_RNG_COEFF + ((x) >> 32)) + +/***************************************************************************************\ +* Pseudo-Random Number Generators (PRNGs) * +\***************************************************************************************/ + +template static void +randBits_( T* arr, int len, uint64* state, const Vec2i* p, bool small_flag ) +{ + uint64 temp = *state; + int i; + + if( !small_flag ) + { + for( i = 0; i <= len - 4; i += 4 ) + { + int t0, t1; + + temp = RNG_NEXT(temp); + t0 = ((int)temp & p[i][0]) + p[i][1]; + temp = RNG_NEXT(temp); + t1 = ((int)temp & p[i+1][0]) + p[i+1][1]; + arr[i] = saturate_cast(t0); + arr[i+1] = saturate_cast(t1); + + temp = RNG_NEXT(temp); + t0 = ((int)temp & p[i+2][0]) + p[i+2][1]; + temp = RNG_NEXT(temp); + t1 = ((int)temp & p[i+3][0]) + p[i+3][1]; + arr[i+2] = saturate_cast(t0); + arr[i+3] = saturate_cast(t1); + } + } + else + { + for( i = 0; i <= len - 4; i += 4 ) + { + int t0, t1, t; + temp = RNG_NEXT(temp); + t = (int)temp; + t0 = (t & p[i][0]) + p[i][1]; + t1 = ((t >> 8) & p[i+1][0]) + p[i+1][1]; + arr[i] = saturate_cast(t0); + arr[i+1] = saturate_cast(t1); + + t0 = ((t >> 16) & p[i+2][0]) + p[i+2][1]; + t1 = ((t >> 24) & p[i+3][0]) + p[i+3][1]; + arr[i+2] = saturate_cast(t0); + arr[i+3] = saturate_cast(t1); + } + } + + for( ; i < len; i++ ) + { + int t0; + temp = RNG_NEXT(temp); + + t0 = ((int)temp & p[i][0]) + p[i][1]; + arr[i] = saturate_cast(t0); + } + + *state = temp; +} + +struct DivStruct +{ + unsigned d; + unsigned M; + int sh1, sh2; + int delta; +}; + +template static void +randi_( T* arr, int len, uint64* state, const DivStruct* p ) +{ + uint64 temp = *state; + int i = 0; + unsigned t0, t1, v0, v1; + + for( i = 0; i <= len - 4; i += 4 ) + { + temp = RNG_NEXT(temp); + t0 = (unsigned)temp; + temp = RNG_NEXT(temp); + t1 = (unsigned)temp; + v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32); + v1 = (unsigned)(((uint64)t1 * p[i+1].M) >> 32); + v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2; + v1 = (v1 + ((t1 - v1) >> p[i+1].sh1)) >> p[i+1].sh2; + v0 = t0 - v0*p[i].d + p[i].delta; + v1 = t1 - v1*p[i+1].d + p[i+1].delta; + arr[i] = saturate_cast((int)v0); + arr[i+1] = saturate_cast((int)v1); + + temp = RNG_NEXT(temp); + t0 = (unsigned)temp; + temp = RNG_NEXT(temp); + t1 = (unsigned)temp; + v0 = (unsigned)(((uint64)t0 * p[i+2].M) >> 32); + v1 = (unsigned)(((uint64)t1 * p[i+3].M) >> 32); + v0 = (v0 + ((t0 - v0) >> p[i+2].sh1)) >> p[i+2].sh2; + v1 = (v1 + ((t1 - v1) >> p[i+3].sh1)) >> p[i+3].sh2; + v0 = t0 - v0*p[i+2].d + p[i+2].delta; + v1 = t1 - v1*p[i+3].d + p[i+3].delta; + arr[i+2] = saturate_cast((int)v0); + arr[i+3] = saturate_cast((int)v1); + } + + for( ; i < len; i++ ) + { + temp = RNG_NEXT(temp); + t0 = (unsigned)temp; + v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32); + v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2; + v0 = t0 - v0*p[i].d + p[i].delta; + arr[i] = saturate_cast((int)v0); + } + + *state = temp; +} + + +#define DEF_RANDI_FUNC(suffix, type) \ +static void randBits_##suffix(type* arr, int len, uint64* state, \ + const Vec2i* p, bool small_flag) \ +{ randBits_(arr, len, state, p, small_flag); } \ +\ +static void randi_##suffix(type* arr, int len, uint64* state, \ + const DivStruct* p, bool ) \ +{ randi_(arr, len, state, p); } + +DEF_RANDI_FUNC(8u, uchar) +DEF_RANDI_FUNC(8s, schar) +DEF_RANDI_FUNC(16u, ushort) +DEF_RANDI_FUNC(16s, short) +DEF_RANDI_FUNC(32s, int) + +static void randf_32f( float* arr, int len, uint64* state, const Vec2f* p, bool ) +{ + uint64 temp = *state; + int i = 0; + + for( ; i <= len - 4; i += 4 ) + { + float f[4]; + f[0] = (float)(int)(temp = RNG_NEXT(temp)); + f[1] = (float)(int)(temp = RNG_NEXT(temp)); + f[2] = (float)(int)(temp = RNG_NEXT(temp)); + f[3] = (float)(int)(temp = RNG_NEXT(temp)); + + // handwritten SSE is required not for performance but for numerical stability! + // both 32-bit gcc and MSVC compilers trend to generate double precision SSE + // while 64-bit compilers generate single precision SIMD instructions + // so manual vectorisation forces all compilers to the single precision +#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP) + __m128 q0 = _mm_loadu_ps((const float*)(p + i)); + __m128 q1 = _mm_loadu_ps((const float*)(p + i + 2)); + + __m128 q01l = _mm_unpacklo_ps(q0, q1); + __m128 q01h = _mm_unpackhi_ps(q0, q1); + + __m128 p0 = _mm_unpacklo_ps(q01l, q01h); + __m128 p1 = _mm_unpackhi_ps(q01l, q01h); + + _mm_storeu_ps(arr + i, _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(f), p0), p1)); +#else + arr[i+0] = f[0]*p[i+0][0] + p[i+0][1]; + arr[i+1] = f[1]*p[i+1][0] + p[i+1][1]; + arr[i+2] = f[2]*p[i+2][0] + p[i+2][1]; + arr[i+3] = f[3]*p[i+3][0] + p[i+3][1]; +#endif + } + + for( ; i < len; i++ ) + { + temp = RNG_NEXT(temp); +#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP) + _mm_store_ss(arr + i, _mm_add_ss( + _mm_mul_ss(_mm_set_ss((float)(int)temp), _mm_set_ss(p[i][0])), + _mm_set_ss(p[i][1])) + ); +#else + arr[i] = (int)temp*p[i][0] + p[i][1]; +#endif + } + + *state = temp; +} + + +static void +randf_64f( double* arr, int len, uint64* state, const Vec2d* p, bool ) +{ + uint64 temp = *state; + int64 v = 0; + int i; + + for( i = 0; i <= len - 4; i += 4 ) + { + double f0, f1; + + temp = RNG_NEXT(temp); + v = (temp >> 32)|(temp << 32); + f0 = v*p[i][0] + p[i][1]; + temp = RNG_NEXT(temp); + v = (temp >> 32)|(temp << 32); + f1 = v*p[i+1][0] + p[i+1][1]; + arr[i] = f0; arr[i+1] = f1; + + temp = RNG_NEXT(temp); + v = (temp >> 32)|(temp << 32); + f0 = v*p[i+2][0] + p[i+2][1]; + temp = RNG_NEXT(temp); + v = (temp >> 32)|(temp << 32); + f1 = v*p[i+3][0] + p[i+3][1]; + arr[i+2] = f0; arr[i+3] = f1; + } + + for( ; i < len; i++ ) + { + temp = RNG_NEXT(temp); + v = (temp >> 32)|(temp << 32); + arr[i] = v*p[i][0] + p[i][1]; + } + + *state = temp; +} + +typedef void (*RandFunc)(uchar* arr, int len, uint64* state, const void* p, bool small_flag); + + +static RandFunc randTab[][8] = +{ + { + (RandFunc)randi_8u, (RandFunc)randi_8s, (RandFunc)randi_16u, (RandFunc)randi_16s, + (RandFunc)randi_32s, (RandFunc)randf_32f, (RandFunc)randf_64f, 0 + }, + { + (RandFunc)randBits_8u, (RandFunc)randBits_8s, (RandFunc)randBits_16u, (RandFunc)randBits_16s, + (RandFunc)randBits_32s, 0, 0, 0 + } +}; + +/* + The code below implements the algorithm described in + "The Ziggurat Method for Generating Random Variables" + by Marsaglia and Tsang, Journal of Statistical Software. +*/ +static void +randn_0_1_32f( float* arr, int len, uint64* state ) +{ + const float r = 3.442620f; // The start of the right tail + const float rng_flt = 2.3283064365386962890625e-10f; // 2^-32 + static unsigned kn[128]; + static float wn[128], fn[128]; + uint64 temp = *state; + static bool initialized=false; + int i; + + if( !initialized ) + { + const double m1 = 2147483648.0; + double dn = 3.442619855899, tn = dn, vn = 9.91256303526217e-3; + + // Set up the tables + double q = vn/std::exp(-.5*dn*dn); + kn[0] = (unsigned)((dn/q)*m1); + kn[1] = 0; + + wn[0] = (float)(q/m1); + wn[127] = (float)(dn/m1); + + fn[0] = 1.f; + fn[127] = (float)std::exp(-.5*dn*dn); + + for(i=126;i>=1;i--) + { + dn = std::sqrt(-2.*std::log(vn/dn+std::exp(-.5*dn*dn))); + kn[i+1] = (unsigned)((dn/tn)*m1); + tn = dn; + fn[i] = (float)std::exp(-.5*dn*dn); + wn[i] = (float)(dn/m1); + } + initialized = true; + } + + for( i = 0; i < len; i++ ) + { + float x, y; + for(;;) + { + int hz = (int)temp; + temp = RNG_NEXT(temp); + int iz = hz & 127; + x = hz*wn[iz]; + if( (unsigned)std::abs(hz) < kn[iz] ) + break; + if( iz == 0) // iz==0, handles the base strip + { + do + { + x = (unsigned)temp*rng_flt; + temp = RNG_NEXT(temp); + y = (unsigned)temp*rng_flt; + temp = RNG_NEXT(temp); + x = (float)(-std::log(x+FLT_MIN)*0.2904764); + y = (float)-std::log(y+FLT_MIN); + } // .2904764 is 1/r + while( y + y < x*x ); + x = hz > 0 ? r + x : -r - x; + break; + } + // iz > 0, handle the wedges of other strips + y = (unsigned)temp*rng_flt; + temp = RNG_NEXT(temp); + if( fn[iz] + y*(fn[iz - 1] - fn[iz]) < std::exp(-.5*x*x) ) + break; + } + arr[i] = x; + } + *state = temp; +} + + +double RNG::gaussian(double sigma) +{ + float temp; + randn_0_1_32f( &temp, 1, &state ); + return temp*sigma; +} + + +template static void +randnScale_( const float* src, T* dst, int len, int cn, const PT* mean, const PT* stddev, bool stdmtx ) +{ + int i, j, k; + if( !stdmtx ) + { + if( cn == 1 ) + { + PT b = mean[0], a = stddev[0]; + for( i = 0; i < len; i++ ) + dst[i] = saturate_cast(src[i]*a + b); + } + else + { + for( i = 0; i < len; i++, src += cn, dst += cn ) + for( k = 0; k < cn; k++ ) + dst[k] = saturate_cast(src[k]*stddev[k] + mean[k]); + } + } + else + { + for( i = 0; i < len; i++, src += cn, dst += cn ) + { + for( j = 0; j < cn; j++ ) + { + PT s = mean[j]; + for( k = 0; k < cn; k++ ) + s += src[k]*stddev[j*cn + k]; + dst[j] = saturate_cast(s); + } + } + } +} + +static void randnScale_8u( const float* src, uchar* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_8s( const float* src, schar* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_16u( const float* src, ushort* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_16s( const float* src, short* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_32s( const float* src, int* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_32f( const float* src, float* dst, int len, int cn, + const float* mean, const float* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +static void randnScale_64f( const float* src, double* dst, int len, int cn, + const double* mean, const double* stddev, bool stdmtx ) +{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); } + +typedef void (*RandnScaleFunc)(const float* src, uchar* dst, int len, int cn, + const uchar*, const uchar*, bool); + +static RandnScaleFunc randnScaleTab[] = +{ + (RandnScaleFunc)randnScale_8u, (RandnScaleFunc)randnScale_8s, (RandnScaleFunc)randnScale_16u, + (RandnScaleFunc)randnScale_16s, (RandnScaleFunc)randnScale_32s, (RandnScaleFunc)randnScale_32f, + (RandnScaleFunc)randnScale_64f, 0 +}; + +void RNG::fill( InputOutputArray _mat, int disttype, + InputArray _param1arg, InputArray _param2arg, bool saturateRange ) +{ + Mat mat = _mat.getMat(), _param1 = _param1arg.getMat(), _param2 = _param2arg.getMat(); + int depth = mat.depth(), cn = mat.channels(); + AutoBuffer _parambuf; + int j, k, fast_int_mode = 0, smallFlag = 1; + RandFunc func = 0; + RandnScaleFunc scaleFunc = 0; + + CV_Assert(_param1.channels() == 1 && (_param1.rows == 1 || _param1.cols == 1) && + (_param1.rows + _param1.cols - 1 == cn || _param1.rows + _param1.cols - 1 == 1 || + (_param1.size() == Size(1, 4) && _param1.type() == CV_64F && cn <= 4))); + CV_Assert( _param2.channels() == 1 && + (((_param2.rows == 1 || _param2.cols == 1) && + (_param2.rows + _param2.cols - 1 == cn || _param2.rows + _param2.cols - 1 == 1 || + (_param1.size() == Size(1, 4) && _param1.type() == CV_64F && cn <= 4))) || + (_param2.rows == cn && _param2.cols == cn && disttype == NORMAL))); + + Vec2i* ip = 0; + Vec2d* dp = 0; + Vec2f* fp = 0; + DivStruct* ds = 0; + uchar* mean = 0; + uchar* stddev = 0; + bool stdmtx = false; + int n1 = (int)_param1.total(); + int n2 = (int)_param2.total(); + + if( disttype == UNIFORM ) + { + _parambuf.allocate(cn*8 + n1 + n2); + double* parambuf = _parambuf; + double* p1 = (double*)_param1.data; + double* p2 = (double*)_param2.data; + + if( !_param1.isContinuous() || _param1.type() != CV_64F || n1 != cn ) + { + Mat tmp(_param1.size(), CV_64F, parambuf); + _param1.convertTo(tmp, CV_64F); + p1 = parambuf; + if( n1 < cn ) + for( j = n1; j < cn; j++ ) + p1[j] = p1[j-n1]; + } + + if( !_param2.isContinuous() || _param2.type() != CV_64F || n2 != cn ) + { + Mat tmp(_param2.size(), CV_64F, parambuf + cn); + _param2.convertTo(tmp, CV_64F); + p2 = parambuf + cn; + if( n2 < cn ) + for( j = n2; j < cn; j++ ) + p2[j] = p2[j-n2]; + } + + if( depth <= CV_32S ) + { + ip = (Vec2i*)(parambuf + cn*2); + for( j = 0, fast_int_mode = 1; j < cn; j++ ) + { + double a = min(p1[j], p2[j]); + double b = max(p1[j], p2[j]); + if( saturateRange ) + { + a = max(a, depth == CV_8U || depth == CV_16U ? 0. : + depth == CV_8S ? -128. : depth == CV_16S ? -32768. : (double)INT_MIN); + b = min(b, depth == CV_8U ? 256. : depth == CV_16U ? 65536. : + depth == CV_8S ? 128. : depth == CV_16S ? 32768. : (double)INT_MAX); + } + ip[j][1] = cvCeil(a); + int idiff = ip[j][0] = cvFloor(b) - ip[j][1] - 1; + double diff = b - a; + + fast_int_mode &= diff <= 4294967296. && (idiff & (idiff+1)) == 0; + if( fast_int_mode ) + smallFlag &= idiff <= 255; + else + { + if( diff > INT_MAX ) + ip[j][0] = INT_MAX; + if( a < INT_MIN/2 ) + ip[j][1] = INT_MIN/2; + } + } + + if( !fast_int_mode ) + { + ds = (DivStruct*)(ip + cn); + for( j = 0; j < cn; j++ ) + { + ds[j].delta = ip[j][1]; + unsigned d = ds[j].d = (unsigned)(ip[j][0]+1); + int l = 0; + while(((uint64)1 << l) < d) + l++; + ds[j].M = (unsigned)(((uint64)1 << 32)*(((uint64)1 << l) - d)/d) + 1; + ds[j].sh1 = min(l, 1); + ds[j].sh2 = max(l - 1, 0); + } + } + + func = randTab[fast_int_mode][depth]; + } + else + { + double scale = depth == CV_64F ? + 5.4210108624275221700372640043497e-20 : // 2**-64 + 2.3283064365386962890625e-10; // 2**-32 + double maxdiff = saturateRange ? (double)FLT_MAX : DBL_MAX; + + // for each channel i compute such dparam[0][i] & dparam[1][i], + // so that a signed 32/64-bit integer X is transformed to + // the range [param1.val[i], param2.val[i]) using + // dparam[1][i]*X + dparam[0][i] + if( depth == CV_32F ) + { + fp = (Vec2f*)(parambuf + cn*2); + for( j = 0; j < cn; j++ ) + { + fp[j][0] = (float)(std::min(maxdiff, p2[j] - p1[j])*scale); + fp[j][1] = (float)((p2[j] + p1[j])*0.5); + } + } + else + { + dp = (Vec2d*)(parambuf + cn*2); + for( j = 0; j < cn; j++ ) + { + dp[j][0] = std::min(DBL_MAX, p2[j] - p1[j])*scale; + dp[j][1] = ((p2[j] + p1[j])*0.5); + } + } + + func = randTab[0][depth]; + } + CV_Assert( func != 0 ); + } + else if( disttype == CV_RAND_NORMAL ) + { + _parambuf.allocate(MAX(n1, cn) + MAX(n2, cn)); + double* parambuf = _parambuf; + + int ptype = depth == CV_64F ? CV_64F : CV_32F; + int esz = (int)CV_ELEM_SIZE(ptype); + + if( _param1.isContinuous() && _param1.type() == ptype ) + mean = _param1.data; + else + { + Mat tmp(_param1.size(), ptype, parambuf); + _param1.convertTo(tmp, ptype); + mean = (uchar*)parambuf; + } + + if( n1 < cn ) + for( j = n1*esz; j < cn*esz; j++ ) + mean[j] = mean[j - n1*esz]; + + if( _param2.isContinuous() && _param2.type() == ptype ) + stddev = _param2.data; + else + { + Mat tmp(_param2.size(), ptype, parambuf + cn); + _param2.convertTo(tmp, ptype); + stddev = (uchar*)(parambuf + cn); + } + + if( n1 < cn ) + for( j = n1*esz; j < cn*esz; j++ ) + stddev[j] = stddev[j - n1*esz]; + + stdmtx = _param2.rows == cn && _param2.cols == cn; + scaleFunc = randnScaleTab[depth]; + CV_Assert( scaleFunc != 0 ); + } + else + CV_Error( CV_StsBadArg, "Unknown distribution type" ); + + const Mat* arrays[] = {&mat, 0}; + uchar* ptr; + NAryMatIterator it(arrays, &ptr); + int total = (int)it.size, blockSize = std::min((BLOCK_SIZE + cn - 1)/cn, total); + size_t esz = mat.elemSize(); + AutoBuffer buf; + uchar* param = 0; + float* nbuf = 0; + + if( disttype == UNIFORM ) + { + buf.allocate(blockSize*cn*4); + param = (uchar*)(double*)buf; + + if( ip ) + { + if( ds ) + { + DivStruct* p = (DivStruct*)param; + for( j = 0; j < blockSize*cn; j += cn ) + for( k = 0; k < cn; k++ ) + p[j + k] = ds[k]; + } + else + { + Vec2i* p = (Vec2i*)param; + for( j = 0; j < blockSize*cn; j += cn ) + for( k = 0; k < cn; k++ ) + p[j + k] = ip[k]; + } + } + else if( fp ) + { + Vec2f* p = (Vec2f*)param; + for( j = 0; j < blockSize*cn; j += cn ) + for( k = 0; k < cn; k++ ) + p[j + k] = fp[k]; + } + else + { + Vec2d* p = (Vec2d*)param; + for( j = 0; j < blockSize*cn; j += cn ) + for( k = 0; k < cn; k++ ) + p[j + k] = dp[k]; + } + } + else + { + buf.allocate((blockSize*cn+1)/2); + nbuf = (float*)(double*)buf; + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int len = std::min(total - j, blockSize); + + if( disttype == CV_RAND_UNI ) + func( ptr, len*cn, &state, param, smallFlag != 0 ); + else + { + randn_0_1_32f(nbuf, len*cn, &state); + scaleFunc(nbuf, ptr, len, cn, mean, stddev, stdmtx); + } + ptr += len*esz; + } + } +} + +#ifdef WIN32 +#ifdef WINCE +# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) +#endif +static DWORD tlsRNGKey = TLS_OUT_OF_INDEXES; + +void deleteThreadRNGData() +{ + if( tlsRNGKey != TLS_OUT_OF_INDEXES ) + delete (RNG*)TlsGetValue( tlsRNGKey ); +} + +RNG& theRNG() +{ + if( tlsRNGKey == TLS_OUT_OF_INDEXES ) + { + tlsRNGKey = TlsAlloc(); + CV_Assert(tlsRNGKey != TLS_OUT_OF_INDEXES); + } + RNG* rng = (RNG*)TlsGetValue( tlsRNGKey ); + if( !rng ) + { + rng = new RNG; + TlsSetValue( tlsRNGKey, rng ); + } + return *rng; +} + +#else + +static pthread_key_t tlsRNGKey = 0; +static pthread_once_t tlsRNGKeyOnce = PTHREAD_ONCE_INIT; + +static void deleteRNG(void* data) +{ + delete (RNG*)data; +} + +static void makeRNGKey() +{ + int errcode = pthread_key_create(&tlsRNGKey, deleteRNG); + CV_Assert(errcode == 0); +} + +RNG& theRNG() +{ + pthread_once(&tlsRNGKeyOnce, makeRNGKey); + RNG* rng = (RNG*)pthread_getspecific(tlsRNGKey); + if( !rng ) + { + rng = new RNG; + pthread_setspecific(tlsRNGKey, rng); + } + return *rng; +} + +#endif + +} + +void cv::randu(InputOutputArray dst, InputArray low, InputArray high) +{ + theRNG().fill(dst, RNG::UNIFORM, low, high); +} + +void cv::randn(InputOutputArray dst, InputArray mean, InputArray stddev) +{ + theRNG().fill(dst, RNG::NORMAL, mean, stddev); +} + +namespace cv +{ + +template static void +randShuffle_( Mat& _arr, RNG& rng, double iterFactor ) +{ + int sz = _arr.rows*_arr.cols, iters = cvRound(iterFactor*sz); + if( _arr.isContinuous() ) + { + T* arr = (T*)_arr.data; + for( int i = 0; i < iters; i++ ) + { + int j = (unsigned)rng % sz, k = (unsigned)rng % sz; + std::swap( arr[j], arr[k] ); + } + } + else + { + uchar* data = _arr.data; + size_t step = _arr.step; + int cols = _arr.cols; + for( int i = 0; i < iters; i++ ) + { + int j1 = (unsigned)rng % sz, k1 = (unsigned)rng % sz; + int j0 = j1/cols, k0 = k1/cols; + j1 -= j0*cols; k1 -= k0*cols; + std::swap( ((T*)(data + step*j0))[j1], ((T*)(data + step*k0))[k1] ); + } + } +} + +typedef void (*RandShuffleFunc)( Mat& dst, RNG& rng, double iterFactor ); + +} + +void cv::randShuffle( InputOutputArray _dst, double iterFactor, RNG* _rng ) +{ + RandShuffleFunc tab[] = + { + 0, + randShuffle_, // 1 + randShuffle_, // 2 + randShuffle_ >, // 3 + randShuffle_, // 4 + 0, + randShuffle_ >, // 6 + 0, + randShuffle_ >, // 8 + 0, 0, 0, + randShuffle_ >, // 12 + 0, 0, 0, + randShuffle_ >, // 16 + 0, 0, 0, 0, 0, 0, 0, + randShuffle_ >, // 24 + 0, 0, 0, 0, 0, 0, 0, + randShuffle_ > // 32 + }; + + Mat dst = _dst.getMat(); + RNG& rng = _rng ? *_rng : theRNG(); + CV_Assert( dst.elemSize() <= 32 ); + RandShuffleFunc func = tab[dst.elemSize()]; + CV_Assert( func != 0 ); + func( dst, rng, iterFactor ); +} + +void cv::randShuffle_( InputOutputArray _dst, double iterFactor ) +{ + randShuffle(_dst, iterFactor); +} + +CV_IMPL void +cvRandArr( CvRNG* _rng, CvArr* arr, int disttype, CvScalar param1, CvScalar param2 ) +{ + cv::Mat mat = cv::cvarrToMat(arr); + // !!! this will only work for current 64-bit MWC RNG !!! + cv::RNG& rng = _rng ? (cv::RNG&)*_rng : cv::theRNG(); + rng.fill(mat, disttype == CV_RAND_NORMAL ? + cv::RNG::NORMAL : cv::RNG::UNIFORM, cv::Scalar(param1), cv::Scalar(param2) ); +} + +CV_IMPL void cvRandShuffle( CvArr* arr, CvRNG* _rng, double iter_factor ) +{ + cv::Mat dst = cv::cvarrToMat(arr); + cv::RNG& rng = _rng ? (cv::RNG&)*_rng : cv::theRNG(); + cv::randShuffle( dst, iter_factor, &rng ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/stat.cpp diffimg-2.0.0/3rdparty/opencv/core/src/stat.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/stat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/stat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2034 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include + +namespace cv +{ + +template static inline Scalar rawToScalar(const T& v) +{ + Scalar s; + typedef typename DataType::channel_type T1; + int i, n = DataType::channels; + for( i = 0; i < n; i++ ) + s.val[i] = ((T1*)&v)[i]; + return s; +} + +/****************************************************************************************\ +* sum * +\****************************************************************************************/ + +template +static int sum_(const T* src0, const uchar* mask, ST* dst, int len, int cn ) +{ + const T* src = src0; + if( !mask ) + { + int i=0; + int k = cn % 4; + if( k == 1 ) + { + ST s0 = dst[0]; + + #if CV_ENABLE_UNROLLED + for(; i <= len - 4; i += 4, src += cn*4 ) + s0 += src[0] + src[cn] + src[cn*2] + src[cn*3]; + #endif + for( ; i < len; i++, src += cn ) + s0 += src[0]; + dst[0] = s0; + } + else if( k == 2 ) + { + ST s0 = dst[0], s1 = dst[1]; + for( i = 0; i < len; i++, src += cn ) + { + s0 += src[0]; + s1 += src[1]; + } + dst[0] = s0; + dst[1] = s1; + } + else if( k == 3 ) + { + ST s0 = dst[0], s1 = dst[1], s2 = dst[2]; + for( i = 0; i < len; i++, src += cn ) + { + s0 += src[0]; + s1 += src[1]; + s2 += src[2]; + } + dst[0] = s0; + dst[1] = s1; + dst[2] = s2; + } + + for( ; k < cn; k += 4 ) + { + src = src0 + k; + ST s0 = dst[k], s1 = dst[k+1], s2 = dst[k+2], s3 = dst[k+3]; + for( i = 0; i < len; i++, src += cn ) + { + s0 += src[0]; s1 += src[1]; + s2 += src[2]; s3 += src[3]; + } + dst[k] = s0; + dst[k+1] = s1; + dst[k+2] = s2; + dst[k+3] = s3; + } + return len; + } + + int i, nzm = 0; + if( cn == 1 ) + { + ST s = dst[0]; + for( i = 0; i < len; i++ ) + if( mask[i] ) + { + s += src[i]; + nzm++; + } + dst[0] = s; + } + else if( cn == 3 ) + { + ST s0 = dst[0], s1 = dst[1], s2 = dst[2]; + for( i = 0; i < len; i++, src += 3 ) + if( mask[i] ) + { + s0 += src[0]; + s1 += src[1]; + s2 += src[2]; + nzm++; + } + dst[0] = s0; + dst[1] = s1; + dst[2] = s2; + } + else + { + for( i = 0; i < len; i++, src += cn ) + if( mask[i] ) + { + int k = 0; + #if CV_ENABLE_UNROLLED + for( ; k <= cn - 4; k += 4 ) + { + ST s0, s1; + s0 = dst[k] + src[k]; + s1 = dst[k+1] + src[k+1]; + dst[k] = s0; dst[k+1] = s1; + s0 = dst[k+2] + src[k+2]; + s1 = dst[k+3] + src[k+3]; + dst[k+2] = s0; dst[k+3] = s1; + } + #endif + for( ; k < cn; k++ ) + dst[k] += src[k]; + nzm++; + } + } + return nzm; +} + + +static int sum8u( const uchar* src, const uchar* mask, int* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum8s( const schar* src, const uchar* mask, int* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum16u( const ushort* src, const uchar* mask, int* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum16s( const short* src, const uchar* mask, int* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum32s( const int* src, const uchar* mask, double* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum32f( const float* src, const uchar* mask, double* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +static int sum64f( const double* src, const uchar* mask, double* dst, int len, int cn ) +{ return sum_(src, mask, dst, len, cn); } + +typedef int (*SumFunc)(const uchar*, const uchar* mask, uchar*, int, int); + +static SumFunc sumTab[] = +{ + (SumFunc)GET_OPTIMIZED(sum8u), (SumFunc)sum8s, + (SumFunc)sum16u, (SumFunc)sum16s, + (SumFunc)sum32s, + (SumFunc)GET_OPTIMIZED(sum32f), (SumFunc)sum64f, + 0 +}; + +template +static int countNonZero_(const T* src, int len ) +{ + int i=0, nz = 0; + #if CV_ENABLE_UNROLLED + for(; i <= len - 4; i += 4 ) + nz += (src[i] != 0) + (src[i+1] != 0) + (src[i+2] != 0) + (src[i+3] != 0); + #endif + for( ; i < len; i++ ) + nz += src[i] != 0; + return nz; +} + +static int countNonZero8u( const uchar* src, int len ) +{ + int i=0, nz = 0; +#if CV_SSE2 + if(USE_SSE2)//5x-6x + { + __m128i pattern = _mm_setzero_si128 (); + static uchar tab[256]; + static volatile bool initialized = false; + if( !initialized ) + { + // we compute inverse popcount table, + // since we pass (img[x] == 0) mask as index in the table. + for( int j = 0; j < 256; j++ ) + { + int val = 0; + for( int mask = 1; mask < 256; mask += mask ) + val += (j & mask) == 0; + tab[j] = (uchar)val; + } + initialized = true; + } + + for (; i<=len-16; i+=16) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)(src+i)); + int val = _mm_movemask_epi8(_mm_cmpeq_epi8(r0, pattern)); + nz += tab[val & 255] + tab[val >> 8]; + } + } +#endif + for( ; i < len; i++ ) + nz += src[i] != 0; + return nz; +} + +static int countNonZero16u( const ushort* src, int len ) +{ return countNonZero_(src, len); } + +static int countNonZero32s( const int* src, int len ) +{ return countNonZero_(src, len); } + +static int countNonZero32f( const float* src, int len ) +{ return countNonZero_(src, len); } + +static int countNonZero64f( const double* src, int len ) +{ return countNonZero_(src, len); } + +typedef int (*CountNonZeroFunc)(const uchar*, int); + +static CountNonZeroFunc countNonZeroTab[] = +{ + (CountNonZeroFunc)GET_OPTIMIZED(countNonZero8u), (CountNonZeroFunc)GET_OPTIMIZED(countNonZero8u), + (CountNonZeroFunc)GET_OPTIMIZED(countNonZero16u), (CountNonZeroFunc)GET_OPTIMIZED(countNonZero16u), + (CountNonZeroFunc)GET_OPTIMIZED(countNonZero32s), (CountNonZeroFunc)GET_OPTIMIZED(countNonZero32f), + (CountNonZeroFunc)GET_OPTIMIZED(countNonZero64f), 0 +}; + + +template +static int sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int len, int cn ) +{ + const T* src = src0; + + if( !mask ) + { + int i; + int k = cn % 4; + + if( k == 1 ) + { + ST s0 = sum[0]; + SQT sq0 = sqsum[0]; + for( i = 0; i < len; i++, src += cn ) + { + T v = src[0]; + s0 += v; sq0 += (SQT)v*v; + } + sum[0] = s0; + sqsum[0] = sq0; + } + else if( k == 2 ) + { + ST s0 = sum[0], s1 = sum[1]; + SQT sq0 = sqsum[0], sq1 = sqsum[1]; + for( i = 0; i < len; i++, src += cn ) + { + T v0 = src[0], v1 = src[1]; + s0 += v0; sq0 += (SQT)v0*v0; + s1 += v1; sq1 += (SQT)v1*v1; + } + sum[0] = s0; sum[1] = s1; + sqsum[0] = sq0; sqsum[1] = sq1; + } + else if( k == 3 ) + { + ST s0 = sum[0], s1 = sum[1], s2 = sum[2]; + SQT sq0 = sqsum[0], sq1 = sqsum[1], sq2 = sqsum[2]; + for( i = 0; i < len; i++, src += cn ) + { + T v0 = src[0], v1 = src[1], v2 = src[2]; + s0 += v0; sq0 += (SQT)v0*v0; + s1 += v1; sq1 += (SQT)v1*v1; + s2 += v2; sq2 += (SQT)v2*v2; + } + sum[0] = s0; sum[1] = s1; sum[2] = s2; + sqsum[0] = sq0; sqsum[1] = sq1; sqsum[2] = sq2; + } + + for( ; k < cn; k += 4 ) + { + src = src0 + k; + ST s0 = sum[k], s1 = sum[k+1], s2 = sum[k+2], s3 = sum[k+3]; + SQT sq0 = sqsum[k], sq1 = sqsum[k+1], sq2 = sqsum[k+2], sq3 = sqsum[k+3]; + for( i = 0; i < len; i++, src += cn ) + { + T v0, v1; + v0 = src[0], v1 = src[1]; + s0 += v0; sq0 += (SQT)v0*v0; + s1 += v1; sq1 += (SQT)v1*v1; + v0 = src[2], v1 = src[3]; + s2 += v0; sq2 += (SQT)v0*v0; + s3 += v1; sq3 += (SQT)v1*v1; + } + sum[k] = s0; sum[k+1] = s1; + sum[k+2] = s2; sum[k+3] = s3; + sqsum[k] = sq0; sqsum[k+1] = sq1; + sqsum[k+2] = sq2; sqsum[k+3] = sq3; + } + return len; + } + + int i, nzm = 0; + + if( cn == 1 ) + { + ST s0 = sum[0]; + SQT sq0 = sqsum[0]; + for( i = 0; i < len; i++ ) + if( mask[i] ) + { + T v = src[i]; + s0 += v; sq0 += (SQT)v*v; + nzm++; + } + sum[0] = s0; + sqsum[0] = sq0; + } + else if( cn == 3 ) + { + ST s0 = sum[0], s1 = sum[1], s2 = sum[2]; + SQT sq0 = sqsum[0], sq1 = sqsum[1], sq2 = sqsum[2]; + for( i = 0; i < len; i++, src += 3 ) + if( mask[i] ) + { + T v0 = src[0], v1 = src[1], v2 = src[2]; + s0 += v0; sq0 += (SQT)v0*v0; + s1 += v1; sq1 += (SQT)v1*v1; + s2 += v2; sq2 += (SQT)v2*v2; + nzm++; + } + sum[0] = s0; sum[1] = s1; sum[2] = s2; + sqsum[0] = sq0; sqsum[1] = sq1; sqsum[2] = sq2; + } + else + { + for( i = 0; i < len; i++, src += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + { + T v = src[k]; + ST s = sum[k] + v; + SQT sq = sqsum[k] + (SQT)v*v; + sum[k] = s; sqsum[k] = sq; + } + nzm++; + } + } + return nzm; +} + + +static int sqsum8u( const uchar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum8s( const schar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum16u( const ushort* src, const uchar* mask, int* sum, double* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum16s( const short* src, const uchar* mask, int* sum, double* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum32s( const int* src, const uchar* mask, double* sum, double* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum32f( const float* src, const uchar* mask, double* sum, double* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +static int sqsum64f( const double* src, const uchar* mask, double* sum, double* sqsum, int len, int cn ) +{ return sumsqr_(src, mask, sum, sqsum, len, cn); } + +typedef int (*SumSqrFunc)(const uchar*, const uchar* mask, uchar*, uchar*, int, int); + +static SumSqrFunc sumSqrTab[] = +{ + (SumSqrFunc)GET_OPTIMIZED(sqsum8u), (SumSqrFunc)sqsum8s, (SumSqrFunc)sqsum16u, (SumSqrFunc)sqsum16s, + (SumSqrFunc)sqsum32s, (SumSqrFunc)GET_OPTIMIZED(sqsum32f), (SumSqrFunc)sqsum64f, 0 +}; + +} + +cv::Scalar cv::sum( InputArray _src ) +{ + Mat src = _src.getMat(); + int k, cn = src.channels(), depth = src.depth(); + SumFunc func = sumTab[depth]; + + CV_Assert( cn <= 4 && func != 0 ); + + const Mat* arrays[] = {&src, 0}; + uchar* ptrs[1]; + NAryMatIterator it(arrays, ptrs); + Scalar s; + int total = (int)it.size, blockSize = total, intSumBlockSize = 0; + int j, count = 0; + AutoBuffer _buf; + int* buf = (int*)&s[0]; + size_t esz = 0; + bool blockSum = depth < CV_32S; + + if( blockSum ) + { + intSumBlockSize = depth <= CV_8S ? (1 << 23) : (1 << 15); + blockSize = std::min(blockSize, intSumBlockSize); + _buf.allocate(cn); + buf = _buf; + + for( k = 0; k < cn; k++ ) + buf[k] = 0; + esz = src.elemSize(); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int bsz = std::min(total - j, blockSize); + func( ptrs[0], 0, (uchar*)buf, bsz, cn ); + count += bsz; + if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) + { + for( k = 0; k < cn; k++ ) + { + s[k] += buf[k]; + buf[k] = 0; + } + count = 0; + } + ptrs[0] += bsz*esz; + } + } + return s; +} + +int cv::countNonZero( InputArray _src ) +{ + Mat src = _src.getMat(); + CountNonZeroFunc func = countNonZeroTab[src.depth()]; + + CV_Assert( src.channels() == 1 && func != 0 ); + + const Mat* arrays[] = {&src, 0}; + uchar* ptrs[1]; + NAryMatIterator it(arrays, ptrs); + int total = (int)it.size, nz = 0; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + nz += func( ptrs[0], total ); + + return nz; +} + +cv::Scalar cv::mean( InputArray _src, InputArray _mask ) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + CV_Assert( mask.empty() || mask.type() == CV_8U ); + + int k, cn = src.channels(), depth = src.depth(); + SumFunc func = sumTab[depth]; + + CV_Assert( cn <= 4 && func != 0 ); + + const Mat* arrays[] = {&src, &mask, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + Scalar s; + int total = (int)it.size, blockSize = total, intSumBlockSize = 0; + int j, count = 0; + AutoBuffer _buf; + int* buf = (int*)&s[0]; + bool blockSum = depth <= CV_16S; + size_t esz = 0, nz0 = 0; + + if( blockSum ) + { + intSumBlockSize = depth <= CV_8S ? (1 << 23) : (1 << 15); + blockSize = std::min(blockSize, intSumBlockSize); + _buf.allocate(cn); + buf = _buf; + + for( k = 0; k < cn; k++ ) + buf[k] = 0; + esz = src.elemSize(); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int bsz = std::min(total - j, blockSize); + int nz = func( ptrs[0], ptrs[1], (uchar*)buf, bsz, cn ); + count += nz; + nz0 += nz; + if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) + { + for( k = 0; k < cn; k++ ) + { + s[k] += buf[k]; + buf[k] = 0; + } + count = 0; + } + ptrs[0] += bsz*esz; + if( ptrs[1] ) + ptrs[1] += bsz; + } + } + return s*(nz0 ? 1./nz0 : 0); +} + + +void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + CV_Assert( mask.empty() || mask.type() == CV_8U ); + + int k, cn = src.channels(), depth = src.depth(); + SumSqrFunc func = sumSqrTab[depth]; + + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &mask, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int total = (int)it.size, blockSize = total, intSumBlockSize = 0; + int j, count = 0, nz0 = 0; + AutoBuffer _buf(cn*4); + double *s = (double*)_buf, *sq = s + cn; + int *sbuf = (int*)s, *sqbuf = (int*)sq; + bool blockSum = depth <= CV_16S, blockSqSum = depth <= CV_8S; + size_t esz = 0; + + for( k = 0; k < cn; k++ ) + s[k] = sq[k] = 0; + + if( blockSum ) + { + intSumBlockSize = 1 << 15; + blockSize = std::min(blockSize, intSumBlockSize); + sbuf = (int*)(sq + cn); + if( blockSqSum ) + sqbuf = sbuf + cn; + for( k = 0; k < cn; k++ ) + sbuf[k] = sqbuf[k] = 0; + esz = src.elemSize(); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int bsz = std::min(total - j, blockSize); + int nz = func( ptrs[0], ptrs[1], (uchar*)sbuf, (uchar*)sqbuf, bsz, cn ); + count += nz; + nz0 += nz; + if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) + { + for( k = 0; k < cn; k++ ) + { + s[k] += sbuf[k]; + sbuf[k] = 0; + } + if( blockSqSum ) + { + for( k = 0; k < cn; k++ ) + { + sq[k] += sqbuf[k]; + sqbuf[k] = 0; + } + } + count = 0; + } + ptrs[0] += bsz*esz; + if( ptrs[1] ) + ptrs[1] += bsz; + } + } + + double scale = nz0 ? 1./nz0 : 0.; + for( k = 0; k < cn; k++ ) + { + s[k] *= scale; + sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.)); + } + + for( j = 0; j < 2; j++ ) + { + const double* sptr = j == 0 ? s : sq; + _OutputArray _dst = j == 0 ? _mean : _sdv; + if( !_dst.needed() ) + continue; + + if( !_dst.fixedSize() ) + _dst.create(cn, 1, CV_64F, -1, true); + Mat dst = _dst.getMat(); + int dcn = (int)dst.total(); + CV_Assert( dst.type() == CV_64F && dst.isContinuous() && + (dst.cols == 1 || dst.rows == 1) && dcn >= cn ); + double* dptr = dst.ptr(); + for( k = 0; k < cn; k++ ) + dptr[k] = sptr[k]; + for( ; k < dcn; k++ ) + dptr[k] = 0; + } +} + +/****************************************************************************************\ +* minMaxLoc * +\****************************************************************************************/ + +namespace cv +{ + +template static void +minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal, + size_t* _minIdx, size_t* _maxIdx, int len, size_t startIdx ) +{ + WT minVal = *_minVal, maxVal = *_maxVal; + size_t minIdx = *_minIdx, maxIdx = *_maxIdx; + + if( !mask ) + { + for( int i = 0; i < len; i++ ) + { + T val = src[i]; + if( val < minVal ) + { + minVal = val; + minIdx = startIdx + i; + } + if( val > maxVal ) + { + maxVal = val; + maxIdx = startIdx + i; + } + } + } + else + { + for( int i = 0; i < len; i++ ) + { + T val = src[i]; + if( mask[i] && val < minVal ) + { + minVal = val; + minIdx = startIdx + i; + } + if( mask[i] && val > maxVal ) + { + maxVal = val; + maxIdx = startIdx + i; + } + } + } + + *_minIdx = minIdx; + *_maxIdx = maxIdx; + *_minVal = minVal; + *_maxVal = maxVal; +} + +static void minMaxIdx_8u(const uchar* src, const uchar* mask, int* minval, int* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_8s(const schar* src, const uchar* mask, int* minval, int* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_16u(const ushort* src, const uchar* mask, int* minval, int* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_16s(const short* src, const uchar* mask, int* minval, int* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_32s(const int* src, const uchar* mask, int* minval, int* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_32f(const float* src, const uchar* mask, float* minval, float* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +static void minMaxIdx_64f(const double* src, const uchar* mask, double* minval, double* maxval, + size_t* minidx, size_t* maxidx, int len, size_t startidx ) +{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); } + +typedef void (*MinMaxIdxFunc)(const uchar*, const uchar*, int*, int*, size_t*, size_t*, int, size_t); + +static MinMaxIdxFunc minmaxTab[] = +{ + (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_8u), (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_8s), + (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_16u), (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_16s), + (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_32s), + (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_32f), (MinMaxIdxFunc)GET_OPTIMIZED(minMaxIdx_64f), + 0 +}; + +static void ofs2idx(const Mat& a, size_t ofs, int* idx) +{ + int i, d = a.dims; + if( ofs > 0 ) + { + ofs--; + for( i = d-1; i >= 0; i-- ) + { + int sz = a.size[i]; + idx[i] = (int)(ofs % sz); + ofs /= sz; + } + } + else + { + for( i = d-1; i >= 0; i-- ) + idx[i] = -1; + } +} + +} + +void cv::minMaxIdx(InputArray _src, double* minVal, + double* maxVal, int* minIdx, int* maxIdx, + InputArray _mask) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + int depth = src.depth(), cn = src.channels(); + + CV_Assert( (cn == 1 && (mask.empty() || mask.type() == CV_8U)) || + (cn >= 1 && mask.empty() && !minIdx && !maxIdx) ); + MinMaxIdxFunc func = minmaxTab[depth]; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &mask, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + + size_t minidx = 0, maxidx = 0; + int iminval = INT_MAX, imaxval = INT_MIN; + float fminval = FLT_MAX, fmaxval = -FLT_MAX; + double dminval = DBL_MAX, dmaxval = -DBL_MAX; + size_t startidx = 1; + int *minval = &iminval, *maxval = &imaxval; + int planeSize = (int)it.size*cn; + + if( depth == CV_32F ) + minval = (int*)&fminval, maxval = (int*)&fmaxval; + else if( depth == CV_64F ) + minval = (int*)&dminval, maxval = (int*)&dmaxval; + + for( size_t i = 0; i < it.nplanes; i++, ++it, startidx += planeSize ) + func( ptrs[0], ptrs[1], minval, maxval, &minidx, &maxidx, planeSize, startidx ); + + if( minidx == 0 ) + dminval = dmaxval = 0; + else if( depth == CV_32F ) + dminval = fminval, dmaxval = fmaxval; + else if( depth <= CV_32S ) + dminval = iminval, dmaxval = imaxval; + + if( minVal ) + *minVal = dminval; + if( maxVal ) + *maxVal = dmaxval; + + if( minIdx ) + ofs2idx(src, minidx, minIdx); + if( maxIdx ) + ofs2idx(src, maxidx, maxIdx); +} + +void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal, + Point* minLoc, Point* maxLoc, InputArray mask ) +{ + Mat img = _img.getMat(); + CV_Assert(img.dims <= 2); + + minMaxIdx(_img, minVal, maxVal, (int*)minLoc, (int*)maxLoc, mask); + if( minLoc ) + std::swap(minLoc->x, minLoc->y); + if( maxLoc ) + std::swap(maxLoc->x, maxLoc->y); +} + +/****************************************************************************************\ +* norm * +\****************************************************************************************/ + +namespace cv +{ + +float normL2Sqr_(const float* a, const float* b, int n) +{ + int j = 0; float d = 0.f; +#if CV_SSE + if( USE_SSE2 ) + { + float CV_DECL_ALIGNED(16) buf[4]; + __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); + + for( ; j <= n - 8; j += 8 ) + { + __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); + __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); + d0 = _mm_add_ps(d0, _mm_mul_ps(t0, t0)); + d1 = _mm_add_ps(d1, _mm_mul_ps(t1, t1)); + } + _mm_store_ps(buf, _mm_add_ps(d0, d1)); + d = buf[0] + buf[1] + buf[2] + buf[3]; + } + else +#endif + { + for( ; j <= n - 4; j += 4 ) + { + float t0 = a[j] - b[j], t1 = a[j+1] - b[j+1], t2 = a[j+2] - b[j+2], t3 = a[j+3] - b[j+3]; + d += t0*t0 + t1*t1 + t2*t2 + t3*t3; + } + } + + for( ; j < n; j++ ) + { + float t = a[j] - b[j]; + d += t*t; + } + return d; +} + + +float normL1_(const float* a, const float* b, int n) +{ + int j = 0; float d = 0.f; +#if CV_SSE + if( USE_SSE2 ) + { + float CV_DECL_ALIGNED(16) buf[4]; + static const int CV_DECL_ALIGNED(16) absbuf[4] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; + __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); + __m128 absmask = _mm_load_ps((const float*)absbuf); + + for( ; j <= n - 8; j += 8 ) + { + __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); + __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); + d0 = _mm_add_ps(d0, _mm_and_ps(t0, absmask)); + d1 = _mm_add_ps(d1, _mm_and_ps(t1, absmask)); + } + _mm_store_ps(buf, _mm_add_ps(d0, d1)); + d = buf[0] + buf[1] + buf[2] + buf[3]; + } + else +#endif + { + for( ; j <= n - 4; j += 4 ) + { + d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + + std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); + } + } + + for( ; j < n; j++ ) + d += std::abs(a[j] - b[j]); + return d; +} + +int normL1_(const uchar* a, const uchar* b, int n) +{ + int j = 0, d = 0; +#if CV_SSE + if( USE_SSE2 ) + { + __m128i d0 = _mm_setzero_si128(); + + for( ; j <= n - 16; j += 16 ) + { + __m128i t0 = _mm_loadu_si128((const __m128i*)(a + j)); + __m128i t1 = _mm_loadu_si128((const __m128i*)(b + j)); + + d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); + } + + for( ; j <= n - 4; j += 4 ) + { + __m128i t0 = _mm_cvtsi32_si128(*(const int*)(a + j)); + __m128i t1 = _mm_cvtsi32_si128(*(const int*)(b + j)); + + d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); + } + d = _mm_cvtsi128_si32(_mm_add_epi32(d0, _mm_unpackhi_epi64(d0, d0))); + } + else +#endif + { + for( ; j <= n - 4; j += 4 ) + { + d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + + std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); + } + } + for( ; j < n; j++ ) + d += std::abs(a[j] - b[j]); + return d; +} + +static const uchar popCountTable[] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +static const uchar popCountTable2[] = +{ + 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4 +}; + +static const uchar popCountTable4[] = +{ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static int normHamming(const uchar* a, int n) +{ + int i = 0, result = 0; +#if CV_NEON + uint32x4_t bits = vmovq_n_u32(0); + for (; i <= n - 16; i += 16) { + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t bitsSet = vcntq_u8 (A_vec); + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + bits = vaddq_u32(bits, bitSet4); + } + uint64x2_t bitSet2 = vpaddlq_u32 (bits); + result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); + result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); +#else + for( ; i <= n - 4; i += 4 ) + result += popCountTable[a[i]] + popCountTable[a[i+1]] + + popCountTable[a[i+2]] + popCountTable[a[i+3]]; +#endif + for( ; i < n; i++ ) + result += popCountTable[a[i]]; + return result; +} + +int normHamming(const uchar* a, const uchar* b, int n) +{ + int i = 0, result = 0; +#if CV_NEON + uint32x4_t bits = vmovq_n_u32(0); + for (; i <= n - 16; i += 16) { + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t B_vec = vld1q_u8 (b + i); + uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); + uint8x16_t bitsSet = vcntq_u8 (AxorB); + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + bits = vaddq_u32(bits, bitSet4); + } + uint64x2_t bitSet2 = vpaddlq_u32 (bits); + result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); + result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); +#else + for( ; i <= n - 4; i += 4 ) + result += popCountTable[a[i] ^ b[i]] + popCountTable[a[i+1] ^ b[i+1]] + + popCountTable[a[i+2] ^ b[i+2]] + popCountTable[a[i+3] ^ b[i+3]]; +#endif + for( ; i < n; i++ ) + result += popCountTable[a[i] ^ b[i]]; + return result; +} + +static int normHamming(const uchar* a, int n, int cellSize) +{ + if( cellSize == 1 ) + return normHamming(a, n); + const uchar* tab = 0; + if( cellSize == 2 ) + tab = popCountTable2; + else if( cellSize == 4 ) + tab = popCountTable4; + else + CV_Error( CV_StsBadSize, "bad cell size (not 1, 2 or 4) in normHamming" ); + int i = 0, result = 0; +#if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + result += tab[a[i]] + tab[a[i+1]] + tab[a[i+2]] + tab[a[i+3]]; +#endif + for( ; i < n; i++ ) + result += tab[a[i]]; + return result; +} + +int normHamming(const uchar* a, const uchar* b, int n, int cellSize) +{ + if( cellSize == 1 ) + return normHamming(a, b, n); + const uchar* tab = 0; + if( cellSize == 2 ) + tab = popCountTable2; + else if( cellSize == 4 ) + tab = popCountTable4; + else + CV_Error( CV_StsBadSize, "bad cell size (not 1, 2 or 4) in normHamming" ); + int i = 0, result = 0; + #if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + result += tab[a[i] ^ b[i]] + tab[a[i+1] ^ b[i+1]] + + tab[a[i+2] ^ b[i+2]] + tab[a[i+3] ^ b[i+3]]; + #endif + for( ; i < n; i++ ) + result += tab[a[i] ^ b[i]]; + return result; +} + + +template int +normInf_(const T* src, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result = std::max(result, normInf(src, len*cn)); + } + else + { + for( int i = 0; i < len; i++, src += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + result = std::max(result, ST(fast_abs(src[k]))); + } + } + *_result = result; + return 0; +} + +template int +normL1_(const T* src, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result += normL1(src, len*cn); + } + else + { + for( int i = 0; i < len; i++, src += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + result += fast_abs(src[k]); + } + } + *_result = result; + return 0; +} + +template int +normL2_(const T* src, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result += normL2Sqr(src, len*cn); + } + else + { + for( int i = 0; i < len; i++, src += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + { + T v = src[k]; + result += (ST)v*v; + } + } + } + *_result = result; + return 0; +} + +template int +normDiffInf_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result = std::max(result, normInf(src1, src2, len*cn)); + } + else + { + for( int i = 0; i < len; i++, src1 += cn, src2 += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + result = std::max(result, (ST)std::abs(src1[k] - src2[k])); + } + } + *_result = result; + return 0; +} + +template int +normDiffL1_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result += normL1(src1, src2, len*cn); + } + else + { + for( int i = 0; i < len; i++, src1 += cn, src2 += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + result += std::abs(src1[k] - src2[k]); + } + } + *_result = result; + return 0; +} + +template int +normDiffL2_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn) +{ + ST result = *_result; + if( !mask ) + { + result += normL2Sqr(src1, src2, len*cn); + } + else + { + for( int i = 0; i < len; i++, src1 += cn, src2 += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + { + ST v = src1[k] - src2[k]; + result += v*v; + } + } + } + *_result = result; + return 0; +} + + +#define CV_DEF_NORM_FUNC(L, suffix, type, ntype) \ + static int norm##L##_##suffix(const type* src, const uchar* mask, ntype* r, int len, int cn) \ +{ return norm##L##_(src, mask, r, len, cn); } \ + static int normDiff##L##_##suffix(const type* src1, const type* src2, \ + const uchar* mask, ntype* r, int len, int cn) \ +{ return normDiff##L##_(src1, src2, mask, r, (int)len, cn); } + +#define CV_DEF_NORM_ALL(suffix, type, inftype, l1type, l2type) \ + CV_DEF_NORM_FUNC(Inf, suffix, type, inftype) \ + CV_DEF_NORM_FUNC(L1, suffix, type, l1type) \ + CV_DEF_NORM_FUNC(L2, suffix, type, l2type) + +CV_DEF_NORM_ALL(8u, uchar, int, int, int) +CV_DEF_NORM_ALL(8s, schar, int, int, int) +CV_DEF_NORM_ALL(16u, ushort, int, int, double) +CV_DEF_NORM_ALL(16s, short, int, int, double) +CV_DEF_NORM_ALL(32s, int, int, double, double) +CV_DEF_NORM_ALL(32f, float, float, double, double) +CV_DEF_NORM_ALL(64f, double, double, double, double) + + +typedef int (*NormFunc)(const uchar*, const uchar*, uchar*, int, int); +typedef int (*NormDiffFunc)(const uchar*, const uchar*, const uchar*, uchar*, int, int); + +static NormFunc normTab[3][8] = +{ + { + (NormFunc)GET_OPTIMIZED(normInf_8u), (NormFunc)GET_OPTIMIZED(normInf_8s), (NormFunc)GET_OPTIMIZED(normInf_16u), (NormFunc)GET_OPTIMIZED(normInf_16s), + (NormFunc)GET_OPTIMIZED(normInf_32s), (NormFunc)GET_OPTIMIZED(normInf_32f), (NormFunc)normInf_64f, 0 + }, + { + (NormFunc)GET_OPTIMIZED(normL1_8u), (NormFunc)GET_OPTIMIZED(normL1_8s), (NormFunc)GET_OPTIMIZED(normL1_16u), (NormFunc)GET_OPTIMIZED(normL1_16s), + (NormFunc)GET_OPTIMIZED(normL1_32s), (NormFunc)GET_OPTIMIZED(normL1_32f), (NormFunc)normL1_64f, 0 + }, + { + (NormFunc)GET_OPTIMIZED(normL2_8u), (NormFunc)GET_OPTIMIZED(normL2_8s), (NormFunc)GET_OPTIMIZED(normL2_16u), (NormFunc)GET_OPTIMIZED(normL2_16s), + (NormFunc)GET_OPTIMIZED(normL2_32s), (NormFunc)GET_OPTIMIZED(normL2_32f), (NormFunc)normL2_64f, 0 + } +}; + +static NormDiffFunc normDiffTab[3][8] = +{ + { + (NormDiffFunc)GET_OPTIMIZED(normDiffInf_8u), (NormDiffFunc)normDiffInf_8s, + (NormDiffFunc)normDiffInf_16u, (NormDiffFunc)normDiffInf_16s, + (NormDiffFunc)normDiffInf_32s, (NormDiffFunc)GET_OPTIMIZED(normDiffInf_32f), + (NormDiffFunc)normDiffInf_64f, 0 + }, + { + (NormDiffFunc)GET_OPTIMIZED(normDiffL1_8u), (NormDiffFunc)normDiffL1_8s, + (NormDiffFunc)normDiffL1_16u, (NormDiffFunc)normDiffL1_16s, + (NormDiffFunc)normDiffL1_32s, (NormDiffFunc)GET_OPTIMIZED(normDiffL1_32f), + (NormDiffFunc)normDiffL1_64f, 0 + }, + { + (NormDiffFunc)GET_OPTIMIZED(normDiffL2_8u), (NormDiffFunc)normDiffL2_8s, + (NormDiffFunc)normDiffL2_16u, (NormDiffFunc)normDiffL2_16s, + (NormDiffFunc)normDiffL2_32s, (NormDiffFunc)GET_OPTIMIZED(normDiffL2_32f), + (NormDiffFunc)normDiffL2_64f, 0 + } +}; + +} + +double cv::norm( InputArray _src, int normType, InputArray _mask ) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + int depth = src.depth(), cn = src.channels(); + + normType &= 7; + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || + ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src.type() == CV_8U) ); + + if( src.isContinuous() && mask.empty() ) + { + size_t len = src.total()*cn; + if( len == (size_t)(int)len ) + { + if( depth == CV_32F ) + { + const float* data = src.ptr(); + + if( normType == NORM_L2 ) + { + double result = 0; + GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1); + return std::sqrt(result); + } + if( normType == NORM_L2SQR ) + { + double result = 0; + GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1); + return result; + } + if( normType == NORM_L1 ) + { + double result = 0; + GET_OPTIMIZED(normL1_32f)(data, 0, &result, (int)len, 1); + return result; + } + if( normType == NORM_INF ) + { + float result = 0; + GET_OPTIMIZED(normInf_32f)(data, 0, &result, (int)len, 1); + return result; + } + } + if( depth == CV_8U ) + { + const uchar* data = src.ptr(); + + if( normType == NORM_HAMMING ) + return normHamming(data, (int)len); + + if( normType == NORM_HAMMING2 ) + return normHamming(data, (int)len, 2); + } + } + } + + CV_Assert( mask.empty() || mask.type() == CV_8U ); + + if( normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + { + if( !mask.empty() ) + { + Mat temp; + bitwise_and(src, mask, temp); + return norm(temp, normType); + } + int cellSize = normType == NORM_HAMMING ? 1 : 2; + + const Mat* arrays[] = {&src, 0}; + uchar* ptrs[1]; + NAryMatIterator it(arrays, ptrs); + int total = (int)it.size; + int result = 0; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + result += normHamming(ptrs[0], total, cellSize); + + return result; + } + + NormFunc func = normTab[normType >> 1][depth]; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &mask, 0}; + uchar* ptrs[2]; + union + { + double d; + int i; + float f; + } + result; + result.d = 0; + NAryMatIterator it(arrays, ptrs); + int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0; + bool blockSum = (normType == NORM_L1 && depth <= CV_16S) || + ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S); + int isum = 0; + int *ibuf = &result.i; + size_t esz = 0; + + if( blockSum ) + { + intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn; + blockSize = std::min(blockSize, intSumBlockSize); + ibuf = &isum; + esz = src.elemSize(); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int bsz = std::min(total - j, blockSize); + func( ptrs[0], ptrs[1], (uchar*)ibuf, bsz, cn ); + count += bsz; + if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) + { + result.d += isum; + isum = 0; + count = 0; + } + ptrs[0] += bsz*esz; + if( ptrs[1] ) + ptrs[1] += bsz; + } + } + + if( normType == NORM_INF ) + { + if( depth == CV_64F ) + ; + else if( depth == CV_32F ) + result.d = result.f; + else + result.d = result.i; + } + else if( normType == NORM_L2 ) + result.d = std::sqrt(result.d); + + return result.d; +} + + +double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ) +{ + if( normType & CV_RELATIVE ) + return norm(_src1, _src2, normType & ~CV_RELATIVE, _mask)/(norm(_src2, normType, _mask) + DBL_EPSILON); + + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); + int depth = src1.depth(), cn = src1.channels(); + + CV_Assert( src1.size == src2.size && src1.type() == src2.type() ); + + normType &= 7; + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || + ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); + + if( src1.isContinuous() && src2.isContinuous() && mask.empty() ) + { + size_t len = src1.total()*src1.channels(); + if( len == (size_t)(int)len ) + { + if( src1.depth() == CV_32F ) + { + const float* data1 = src1.ptr(); + const float* data2 = src2.ptr(); + + if( normType == NORM_L2 ) + { + double result = 0; + GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1); + return std::sqrt(result); + } + if( normType == NORM_L2SQR ) + { + double result = 0; + GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1); + return result; + } + if( normType == NORM_L1 ) + { + double result = 0; + GET_OPTIMIZED(normDiffL1_32f)(data1, data2, 0, &result, (int)len, 1); + return result; + } + if( normType == NORM_INF ) + { + float result = 0; + GET_OPTIMIZED(normDiffInf_32f)(data1, data2, 0, &result, (int)len, 1); + return result; + } + } + } + } + + CV_Assert( mask.empty() || mask.type() == CV_8U ); + + if( normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + { + if( !mask.empty() ) + { + Mat temp; + bitwise_xor(src1, src2, temp); + bitwise_and(temp, mask, temp); + return norm(temp, normType); + } + int cellSize = normType == NORM_HAMMING ? 1 : 2; + + const Mat* arrays[] = {&src1, &src2, 0}; + uchar* ptrs[2]; + NAryMatIterator it(arrays, ptrs); + int total = (int)it.size; + int result = 0; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + result += normHamming(ptrs[0], ptrs[1], total, cellSize); + + return result; + } + + NormDiffFunc func = normDiffTab[normType >> 1][depth]; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src1, &src2, &mask, 0}; + uchar* ptrs[3]; + union + { + double d; + float f; + int i; + unsigned u; + } + result; + result.d = 0; + NAryMatIterator it(arrays, ptrs); + int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0; + bool blockSum = (normType == NORM_L1 && depth <= CV_16S) || + ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S); + unsigned isum = 0; + unsigned *ibuf = &result.u; + size_t esz = 0; + + if( blockSum ) + { + intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15); + blockSize = std::min(blockSize, intSumBlockSize); + ibuf = &isum; + esz = src1.elemSize(); + } + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + for( j = 0; j < total; j += blockSize ) + { + int bsz = std::min(total - j, blockSize); + func( ptrs[0], ptrs[1], ptrs[2], (uchar*)ibuf, bsz, cn ); + count += bsz; + if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) + { + result.d += isum; + isum = 0; + count = 0; + } + ptrs[0] += bsz*esz; + ptrs[1] += bsz*esz; + if( ptrs[2] ) + ptrs[2] += bsz; + } + } + + if( normType == NORM_INF ) + { + if( depth == CV_64F ) + ; + else if( depth == CV_32F ) + result.d = result.f; + else + result.d = result.u; + } + else if( normType == NORM_L2 ) + result.d = std::sqrt(result.d); + + return result.d; +} + + +///////////////////////////////////// batch distance /////////////////////////////////////// + +namespace cv +{ + +template +void batchDistL1_(const _Tp* src1, const _Tp* src2, size_t step2, + int nvecs, int len, _Rt* dist, const uchar* mask) +{ + step2 /= sizeof(src2[0]); + if( !mask ) + { + for( int i = 0; i < nvecs; i++ ) + dist[i] = normL1<_Tp, _Rt>(src1, src2 + step2*i, len); + } + else + { + _Rt val0 = std::numeric_limits<_Rt>::max(); + for( int i = 0; i < nvecs; i++ ) + dist[i] = mask[i] ? normL1<_Tp, _Rt>(src1, src2 + step2*i, len) : val0; + } +} + +template +void batchDistL2Sqr_(const _Tp* src1, const _Tp* src2, size_t step2, + int nvecs, int len, _Rt* dist, const uchar* mask) +{ + step2 /= sizeof(src2[0]); + if( !mask ) + { + for( int i = 0; i < nvecs; i++ ) + dist[i] = normL2Sqr<_Tp, _Rt>(src1, src2 + step2*i, len); + } + else + { + _Rt val0 = std::numeric_limits<_Rt>::max(); + for( int i = 0; i < nvecs; i++ ) + dist[i] = mask[i] ? normL2Sqr<_Tp, _Rt>(src1, src2 + step2*i, len) : val0; + } +} + +template +void batchDistL2_(const _Tp* src1, const _Tp* src2, size_t step2, + int nvecs, int len, _Rt* dist, const uchar* mask) +{ + step2 /= sizeof(src2[0]); + if( !mask ) + { + for( int i = 0; i < nvecs; i++ ) + dist[i] = std::sqrt(normL2Sqr<_Tp, _Rt>(src1, src2 + step2*i, len)); + } + else + { + _Rt val0 = std::numeric_limits<_Rt>::max(); + for( int i = 0; i < nvecs; i++ ) + dist[i] = mask[i] ? std::sqrt(normL2Sqr<_Tp, _Rt>(src1, src2 + step2*i, len)) : val0; + } +} + +static void batchDistHamming(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, int* dist, const uchar* mask) +{ + step2 /= sizeof(src2[0]); + if( !mask ) + { + for( int i = 0; i < nvecs; i++ ) + dist[i] = normHamming(src1, src2 + step2*i, len); + } + else + { + int val0 = INT_MAX; + for( int i = 0; i < nvecs; i++ ) + dist[i] = mask[i] ? normHamming(src1, src2 + step2*i, len) : val0; + } +} + +static void batchDistHamming2(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, int* dist, const uchar* mask) +{ + step2 /= sizeof(src2[0]); + if( !mask ) + { + for( int i = 0; i < nvecs; i++ ) + dist[i] = normHamming(src1, src2 + step2*i, len, 2); + } + else + { + int val0 = INT_MAX; + for( int i = 0; i < nvecs; i++ ) + dist[i] = mask[i] ? normHamming(src1, src2 + step2*i, len, 2) : val0; + } +} + +static void batchDistL1_8u32s(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, int* dist, const uchar* mask) +{ + batchDistL1_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL1_8u32f(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL1_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL2Sqr_8u32s(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, int* dist, const uchar* mask) +{ + batchDistL2Sqr_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL2Sqr_8u32f(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL2Sqr_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL2_8u32f(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL2_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL1_32f(const float* src1, const float* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL1_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL2Sqr_32f(const float* src1, const float* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL2Sqr_(src1, src2, step2, nvecs, len, dist, mask); +} + +static void batchDistL2_32f(const float* src1, const float* src2, size_t step2, + int nvecs, int len, float* dist, const uchar* mask) +{ + batchDistL2_(src1, src2, step2, nvecs, len, dist, mask); +} + +typedef void (*BatchDistFunc)(const uchar* src1, const uchar* src2, size_t step2, + int nvecs, int len, uchar* dist, const uchar* mask); + + +struct BatchDistInvoker : public ParallelLoopBody +{ + BatchDistInvoker( const Mat& _src1, const Mat& _src2, + Mat& _dist, Mat& _nidx, int _K, + const Mat& _mask, int _update, + BatchDistFunc _func) + { + src1 = &_src1; + src2 = &_src2; + dist = &_dist; + nidx = &_nidx; + K = _K; + mask = &_mask; + update = _update; + func = _func; + } + + void operator()(const Range& range) const + { + AutoBuffer buf(src2->rows); + int* bufptr = buf; + + for( int i = range.start; i < range.end; i++ ) + { + func(src1->ptr(i), src2->ptr(), src2->step, src2->rows, src2->cols, + K > 0 ? (uchar*)bufptr : dist->ptr(i), mask->data ? mask->ptr(i) : 0); + + if( K > 0 ) + { + int* nidxptr = nidx->ptr(i); + // since positive float's can be compared just like int's, + // we handle both CV_32S and CV_32F cases with a single branch + int* distptr = (int*)dist->ptr(i); + + int j, k; + + for( j = 0; j < src2->rows; j++ ) + { + int d = bufptr[j]; + if( d < distptr[K-1] ) + { + for( k = K-2; k >= 0 && distptr[k] > d; k-- ) + { + nidxptr[k+1] = nidxptr[k]; + distptr[k+1] = distptr[k]; + } + nidxptr[k+1] = j + update; + distptr[k+1] = d; + } + } + } + } + } + + const Mat *src1; + const Mat *src2; + Mat *dist; + Mat *nidx; + const Mat *mask; + int K; + int update; + BatchDistFunc func; +}; + +} + +void cv::batchDistance( InputArray _src1, InputArray _src2, + OutputArray _dist, int dtype, OutputArray _nidx, + int normType, int K, InputArray _mask, + int update, bool crosscheck ) +{ + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); + int type = src1.type(); + CV_Assert( type == src2.type() && src1.cols == src2.cols && + (type == CV_32F || type == CV_8U)); + CV_Assert( _nidx.needed() == (K > 0) ); + + if( dtype == -1 ) + { + dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ? CV_32S : CV_32F; + } + CV_Assert( (type == CV_8U && dtype == CV_32S) || dtype == CV_32F); + + K = std::min(K, src2.rows); + + _dist.create(src1.rows, (K > 0 ? K : src2.rows), dtype); + Mat dist = _dist.getMat(), nidx; + if( _nidx.needed() ) + { + _nidx.create(dist.size(), CV_32S); + nidx = _nidx.getMat(); + } + + if( update == 0 && K > 0 ) + { + dist = Scalar::all(dtype == CV_32S ? (double)INT_MAX : (double)FLT_MAX); + nidx = Scalar::all(-1); + } + + if( crosscheck ) + { + CV_Assert( K == 1 && update == 0 && mask.empty() ); + Mat tdist, tidx; + batchDistance(src2, src1, tdist, dtype, tidx, normType, K, mask, 0, false); + + // if an idx-th element from src1 appeared to be the nearest to i-th element of src2, + // we update the minimum mutual distance between idx-th element of src1 and the whole src2 set. + // As a result, if nidx[idx] = i*, it means that idx-th element of src1 is the nearest + // to i*-th element of src2 and i*-th element of src2 is the closest to idx-th element of src1. + // If nidx[idx] = -1, it means that there is no such ideal couple for it in src2. + // This O(N) procedure is called cross-check and it helps to eliminate some false matches. + if( dtype == CV_32S ) + { + for( int i = 0; i < tdist.rows; i++ ) + { + int idx = tidx.at(i); + int d = tdist.at(i), d0 = dist.at(idx); + if( d < d0 ) + { + dist.at(idx) = d; + nidx.at(idx) = i + update; + } + } + } + else + { + for( int i = 0; i < tdist.rows; i++ ) + { + int idx = tidx.at(i); + float d = tdist.at(i), d0 = dist.at(idx); + if( d < d0 ) + { + dist.at(idx) = d; + nidx.at(idx) = i + update; + } + } + } + return; + } + + BatchDistFunc func = 0; + if( type == CV_8U ) + { + if( normType == NORM_L1 && dtype == CV_32S ) + func = (BatchDistFunc)batchDistL1_8u32s; + else if( normType == NORM_L1 && dtype == CV_32F ) + func = (BatchDistFunc)batchDistL1_8u32f; + else if( normType == NORM_L2SQR && dtype == CV_32S ) + func = (BatchDistFunc)batchDistL2Sqr_8u32s; + else if( normType == NORM_L2SQR && dtype == CV_32F ) + func = (BatchDistFunc)batchDistL2Sqr_8u32f; + else if( normType == NORM_L2 && dtype == CV_32F ) + func = (BatchDistFunc)batchDistL2_8u32f; + else if( normType == NORM_HAMMING && dtype == CV_32S ) + func = (BatchDistFunc)batchDistHamming; + else if( normType == NORM_HAMMING2 && dtype == CV_32S ) + func = (BatchDistFunc)batchDistHamming2; + } + else if( type == CV_32F && dtype == CV_32F ) + { + if( normType == NORM_L1 ) + func = (BatchDistFunc)batchDistL1_32f; + else if( normType == NORM_L2SQR ) + func = (BatchDistFunc)batchDistL2Sqr_32f; + else if( normType == NORM_L2 ) + func = (BatchDistFunc)batchDistL2_32f; + } + + if( func == 0 ) + CV_Error_(CV_StsUnsupportedFormat, + ("The combination of type=%d, dtype=%d and normType=%d is not supported", + type, dtype, normType)); + + parallel_for_(Range(0, src1.rows), + BatchDistInvoker(src1, src2, dist, nidx, K, mask, update, func)); +} + + +void cv::findNonZero( InputArray _src, OutputArray _idx ) +{ + Mat src = _src.getMat(); + CV_Assert( src.type() == CV_8UC1 ); + int n = countNonZero(src); + if( _idx.kind() == _InputArray::MAT && !_idx.getMatRef().isContinuous() ) + _idx.release(); + _idx.create(n, 1, CV_32SC2); + Mat idx = _idx.getMat(); + CV_Assert(idx.isContinuous()); + Point* idx_ptr = (Point*)idx.data; + + for( int i = 0; i < src.rows; i++ ) + { + const uchar* bin_ptr = src.ptr(i); + for( int j = 0; j < src.cols; j++ ) + if( bin_ptr[j] ) + *idx_ptr++ = Point(j, i); + } +} + + +CV_IMPL CvScalar cvSum( const CvArr* srcarr ) +{ + cv::Scalar sum = cv::sum(cv::cvarrToMat(srcarr, false, true, 1)); + if( CV_IS_IMAGE(srcarr) ) + { + int coi = cvGetImageCOI((IplImage*)srcarr); + if( coi ) + { + CV_Assert( 0 < coi && coi <= 4 ); + sum = cv::Scalar(sum[coi-1]); + } + } + return sum; +} + +CV_IMPL int cvCountNonZero( const CvArr* imgarr ) +{ + cv::Mat img = cv::cvarrToMat(imgarr, false, true, 1); + if( img.channels() > 1 ) + cv::extractImageCOI(imgarr, img); + return countNonZero(img); +} + + +CV_IMPL CvScalar +cvAvg( const void* imgarr, const void* maskarr ) +{ + cv::Mat img = cv::cvarrToMat(imgarr, false, true, 1); + cv::Scalar mean = !maskarr ? cv::mean(img) : cv::mean(img, cv::cvarrToMat(maskarr)); + if( CV_IS_IMAGE(imgarr) ) + { + int coi = cvGetImageCOI((IplImage*)imgarr); + if( coi ) + { + CV_Assert( 0 < coi && coi <= 4 ); + mean = cv::Scalar(mean[coi-1]); + } + } + return mean; +} + + +CV_IMPL void +cvAvgSdv( const CvArr* imgarr, CvScalar* _mean, CvScalar* _sdv, const void* maskarr ) +{ + cv::Scalar mean, sdv; + + cv::Mat mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + + cv::meanStdDev(cv::cvarrToMat(imgarr, false, true, 1), mean, sdv, mask ); + + if( CV_IS_IMAGE(imgarr) ) + { + int coi = cvGetImageCOI((IplImage*)imgarr); + if( coi ) + { + CV_Assert( 0 < coi && coi <= 4 ); + mean = cv::Scalar(mean[coi-1]); + sdv = cv::Scalar(sdv[coi-1]); + } + } + + if( _mean ) + *(cv::Scalar*)_mean = mean; + if( _sdv ) + *(cv::Scalar*)_sdv = sdv; +} + + +CV_IMPL void +cvMinMaxLoc( const void* imgarr, double* _minVal, double* _maxVal, + CvPoint* _minLoc, CvPoint* _maxLoc, const void* maskarr ) +{ + cv::Mat mask, img = cv::cvarrToMat(imgarr, false, true, 1); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + if( img.channels() > 1 ) + cv::extractImageCOI(imgarr, img); + + cv::minMaxLoc( img, _minVal, _maxVal, + (cv::Point*)_minLoc, (cv::Point*)_maxLoc, mask ); +} + + +CV_IMPL double +cvNorm( const void* imgA, const void* imgB, int normType, const void* maskarr ) +{ + cv::Mat a, mask; + if( !imgA ) + { + imgA = imgB; + imgB = 0; + } + + a = cv::cvarrToMat(imgA, false, true, 1); + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + + if( a.channels() > 1 && CV_IS_IMAGE(imgA) && cvGetImageCOI((const IplImage*)imgA) > 0 ) + cv::extractImageCOI(imgA, a); + + if( !imgB ) + return !maskarr ? cv::norm(a, normType) : cv::norm(a, normType, mask); + + cv::Mat b = cv::cvarrToMat(imgB, false, true, 1); + if( b.channels() > 1 && CV_IS_IMAGE(imgB) && cvGetImageCOI((const IplImage*)imgB) > 0 ) + cv::extractImageCOI(imgB, b); + + return !maskarr ? cv::norm(a, b, normType) : cv::norm(a, b, normType, mask); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/system.cpp diffimg-2.0.0/3rdparty/opencv/core/src/system.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/system.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/system.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,907 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if defined WIN32 || defined _WIN32 || defined WINCE +#ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?) + #define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx +#endif +#include +#undef small +#undef min +#undef max +#undef abs +#include +#if defined _MSC_VER + #if _MSC_VER >= 1400 + #include + #elif defined _M_IX86 + static void __cpuid(int* cpuid_data, int) + { + __asm + { + push ebx + push edi + mov edi, cpuid_data + mov eax, 1 + cpuid + mov [edi], eax + mov [edi + 4], ebx + mov [edi + 8], ecx + mov [edi + 12], edx + pop edi + pop ebx + } + } + #endif +#endif +#else +#include +#include +#include + +#if defined __MACH__ && defined __APPLE__ +#include +#include +#endif + +#endif + +#ifdef _OPENMP +#include "omp.h" +#endif + +#include + +#if defined __linux__ || defined __APPLE__ || defined __OS2__ +#include +#include +#include +#if defined ANDROID +#include +#else +#include +#endif +#endif + +#ifdef ANDROID +# include +#endif + +namespace cv +{ + +Exception::Exception() { code = 0; line = 0; } + +Exception::Exception(int _code, const string& _err, const string& _func, const string& _file, int _line) +: code(_code), err(_err), func(_func), file(_file), line(_line) +{ + formatMessage(); +} + +Exception::~Exception() throw() {} + +/*! + \return the error description and the context as a text string. + */ +const char* Exception::what() const throw() { return msg.c_str(); } + +void Exception::formatMessage() +{ + if( func.size() > 0 ) + msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str()); + else + msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str()); +} + +struct HWFeatures +{ + enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE }; + + HWFeatures(void) + { + memset( have, 0, sizeof(have) ); + x86_family = 0; + } + + static HWFeatures initialize(void) + { + HWFeatures f; + int cpuid_data[4] = { 0, 0, 0, 0 }; + + #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64) + __cpuid(cpuid_data, 1); + #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) + #ifdef __x86_64__ + asm __volatile__ + ( + "movl $1, %%eax\n\t" + "cpuid\n\t" + :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3]) + : + : "cc" + ); + #else + asm volatile + ( + "pushl %%ebx\n\t" + "movl $1,%%eax\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3]) + : + : "cc" + ); + #endif + #endif + + f.x86_family = (cpuid_data[0] >> 8) & 15; + if( f.x86_family >= 6 ) + { + f.have[CV_CPU_MMX] = (cpuid_data[3] & (1 << 23)) != 0; + f.have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0; + f.have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0; + f.have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0; + f.have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0; + f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0; + f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0; + f.have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0; + f.have[CV_CPU_AVX] = (((cpuid_data[2] & (1<<28)) != 0)&&((cpuid_data[2] & (1<<27)) != 0));//OS uses XSAVE_XRSTORE and CPU support AVX + } + + return f; + } + + int x86_family; + bool have[MAX_FEATURE+1]; +}; + +static HWFeatures featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures(); +static HWFeatures* currentFeatures = &featuresEnabled; + +bool checkHardwareSupport(int feature) +{ + CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE ); + return currentFeatures->have[feature]; +} + + +volatile bool useOptimizedFlag = true; +#ifdef HAVE_IPP +struct IPPInitializer +{ + IPPInitializer(void) { ippStaticInit(); } +}; + +IPPInitializer ippInitializer; +#endif + +volatile bool USE_SSE2 = featuresEnabled.have[CV_CPU_SSE2]; +volatile bool USE_SSE4_2 = featuresEnabled.have[CV_CPU_SSE4_2]; +volatile bool USE_AVX = featuresEnabled.have[CV_CPU_AVX]; + +void setUseOptimized( bool flag ) +{ + useOptimizedFlag = flag; + currentFeatures = flag ? &featuresEnabled : &featuresDisabled; + USE_SSE2 = currentFeatures->have[CV_CPU_SSE2]; +} + +bool useOptimized(void) +{ + return useOptimizedFlag; +} + +int64 getTickCount(void) +{ +#if defined WIN32 || defined _WIN32 || defined WINCE + LARGE_INTEGER counter; + QueryPerformanceCounter( &counter ); + return (int64)counter.QuadPart; +#elif defined __linux || defined __linux__ + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + return (int64)tp.tv_sec*1000000000 + tp.tv_nsec; +#elif defined __MACH__ && defined __APPLE__ + return (int64)mach_absolute_time(); +#else + struct timeval tv; + struct timezone tz; + gettimeofday( &tv, &tz ); + return (int64)tv.tv_sec*1000000 + tv.tv_usec; +#endif +} + +double getTickFrequency(void) +{ +#if defined WIN32 || defined _WIN32 || defined WINCE + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + return (double)freq.QuadPart; +#elif defined __linux || defined __linux__ + return 1e9; +#elif defined __MACH__ && defined __APPLE__ + static double freq = 0; + if( freq == 0 ) + { + mach_timebase_info_data_t sTimebaseInfo; + mach_timebase_info(&sTimebaseInfo); + freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer; + } + return freq; +#else + return 1e6; +#endif +} + +#if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__) +#if defined(__i386__) + +int64 getCPUTickCount(void) +{ + int64 x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; +} +#elif defined(__x86_64__) + +int64 getCPUTickCount(void) +{ + unsigned hi, lo; + __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); + return (int64)lo | ((int64)hi << 32); +} + +#elif defined(__ppc__) + +int64 getCPUTickCount(void) +{ + int64 result = 0; + unsigned upper, lower, tmp; + __asm__ volatile( + "0: \n" + "\tmftbu %0 \n" + "\tmftb %1 \n" + "\tmftbu %2 \n" + "\tcmpw %2,%0 \n" + "\tbne 0b \n" + : "=r"(upper),"=r"(lower),"=r"(tmp) + ); + return lower | ((int64)upper << 32); +} + +#else + +#error "RDTSC not defined" + +#endif + +#elif defined _MSC_VER && defined WIN32 && defined _M_IX86 + +int64 getCPUTickCount(void) +{ + __asm _emit 0x0f; + __asm _emit 0x31; +} + +#else + +#ifdef HAVE_IPP +int64 getCPUTickCount(void) +{ + return ippGetCpuClocks(); +} +#else +int64 getCPUTickCount(void) +{ + return getTickCount(); +} +#endif + +#endif + +const std::string& getBuildInformation() +{ + static std::string build_info = +#include "version_string.inc" + ; + return build_info; +} + +string format( const char* fmt, ... ) +{ + char buf[1 << 16]; + va_list args; + va_start( args, fmt ); + vsprintf( buf, fmt, args ); + return string(buf); +} + +string tempfile( const char* suffix ) +{ + const char *temp_dir = getenv("OPENCV_TEMP_PATH"); + string fname; + +#if defined WIN32 || defined _WIN32 + char temp_dir2[MAX_PATH + 1] = { 0 }; + char temp_file[MAX_PATH + 1] = { 0 }; + + if (temp_dir == 0 || temp_dir[0] == 0) + { + ::GetTempPathA(sizeof(temp_dir2), temp_dir2); + temp_dir = temp_dir2; + } + if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file)) + return string(); + + DeleteFileA(temp_file); + + fname = temp_file; +# else +# ifdef ANDROID + //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX"; + char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX"; +# else + char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX"; +# endif + + if (temp_dir == 0 || temp_dir[0] == 0) + fname = defaultTemplate; + else + { + fname = temp_dir; + char ech = fname[fname.size() - 1]; + if(ech != '/' && ech != '\\') + fname += "/"; + fname += "__opencv_temp.XXXXXX"; + } + + const int fd = mkstemp((char*)fname.c_str()); + if (fd == -1) return string(); + + close(fd); + remove(fname.c_str()); +# endif + + if (suffix) + { + if (suffix[0] != '.') + return fname + "." + suffix; + else + return fname + suffix; + } + return fname; +} + +static CvErrorCallback customErrorCallback = 0; +static void* customErrorCallbackData = 0; +static bool breakOnError = false; + +bool setBreakOnError(bool value) +{ + bool prevVal = breakOnError; + breakOnError = value; + return prevVal; +} + +void error( const Exception& exc ) +{ + if (customErrorCallback != 0) + customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(), + exc.file.c_str(), exc.line, customErrorCallbackData); + else + { + const char* errorStr = cvErrorStr(exc.code); + char buf[1 << 16]; + + sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d", + errorStr, exc.err.c_str(), exc.func.size() > 0 ? + exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line ); + fprintf( stderr, "%s\n", buf ); + fflush( stderr ); +# ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf); +# endif + } + + if(breakOnError) + { + static volatile int* p = 0; + *p = 0; + } + + throw exc; +} + +CvErrorCallback +redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata) +{ + if( prevUserdata ) + *prevUserdata = customErrorCallbackData; + + CvErrorCallback prevCallback = customErrorCallback; + + customErrorCallback = errCallback; + customErrorCallbackData = userdata; + + return prevCallback; +} + +} + +/*CV_IMPL int +cvGuiBoxReport( int code, const char *func_name, const char *err_msg, + const char *file, int line, void* ) +{ +#if (!defined WIN32 && !defined _WIN32) || defined WINCE + return cvStdErrReport( code, func_name, err_msg, file, line, 0 ); +#else + if( code != CV_StsBackTrace && code != CV_StsAutoTrace ) + { + size_t msg_len = strlen(err_msg ? err_msg : "") + 1024; + char* message = (char*)alloca(msg_len); + char title[100]; + + wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n" + "Press \"Abort\" to terminate application.\n" + "Press \"Retry\" to debug (if the app is running under debugger).\n" + "Press \"Ignore\" to continue (this is not safe).\n", + cvErrorStr(code), err_msg ? err_msg : "no description", + func_name, file, line ); + + wsprintf( title, "OpenCV GUI Error Handler" ); + + int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL ); + + if( answer == IDRETRY ) + { + CV_DBG_BREAK(); + } + return answer != IDIGNORE; + } + return 0; +#endif +}*/ + +CV_IMPL int cvCheckHardwareSupport(int feature) +{ + CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE ); + return cv::currentFeatures->have[feature]; +} + +CV_IMPL int cvUseOptimized( int flag ) +{ + int prevMode = cv::useOptimizedFlag; + cv::setUseOptimized( flag != 0 ); + return prevMode; +} + +CV_IMPL int64 cvGetTickCount(void) +{ + return cv::getTickCount(); +} + +CV_IMPL double cvGetTickFrequency(void) +{ + return cv::getTickFrequency()*1e-6; +} + +CV_IMPL CvErrorCallback +cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata) +{ + return cv::redirectError(errCallback, userdata, prevUserdata); +} + +CV_IMPL int cvNulDevReport( int, const char*, const char*, + const char*, int, void* ) +{ + return 0; +} + +CV_IMPL int cvStdErrReport( int, const char*, const char*, + const char*, int, void* ) +{ + return 0; +} + +CV_IMPL int cvGuiBoxReport( int, const char*, const char*, + const char*, int, void* ) +{ + return 0; +} + +CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* ) +{ + return 0; +} + + +CV_IMPL const char* cvErrorStr( int status ) +{ + static char buf[256]; + + switch (status) + { + case CV_StsOk : return "No Error"; + case CV_StsBackTrace : return "Backtrace"; + case CV_StsError : return "Unspecified error"; + case CV_StsInternal : return "Internal error"; + case CV_StsNoMem : return "Insufficient memory"; + case CV_StsBadArg : return "Bad argument"; + case CV_StsNoConv : return "Iterations do not converge"; + case CV_StsAutoTrace : return "Autotrace call"; + case CV_StsBadSize : return "Incorrect size of input array"; + case CV_StsNullPtr : return "Null pointer"; + case CV_StsDivByZero : return "Division by zero occured"; + case CV_BadStep : return "Image step is wrong"; + case CV_StsInplaceNotSupported : return "Inplace operation is not supported"; + case CV_StsObjectNotFound : return "Requested object was not found"; + case CV_BadDepth : return "Input image depth is not supported by function"; + case CV_StsUnmatchedFormats : return "Formats of input arguments do not match"; + case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match"; + case CV_StsOutOfRange : return "One of arguments\' values is out of range"; + case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats"; + case CV_BadCOI : return "Input COI is not supported"; + case CV_BadNumChannels : return "Bad number of channels"; + case CV_StsBadFlag : return "Bad flag (parameter or structure field)"; + case CV_StsBadPoint : return "Bad parameter of type CvPoint"; + case CV_StsBadMask : return "Bad type of mask argument"; + case CV_StsParseError : return "Parsing error"; + case CV_StsNotImplemented : return "The function/feature is not implemented"; + case CV_StsBadMemBlock : return "Memory block has been corrupted"; + case CV_StsAssert : return "Assertion failed"; + case CV_GpuNotSupported : return "No GPU support"; + case CV_GpuApiCallError : return "Gpu API call"; + case CV_OpenGlNotSupported : return "No OpenGL support"; + case CV_OpenGlApiCallError : return "OpenGL API call"; + }; + + sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status); + return buf; +} + +CV_IMPL int cvGetErrMode(void) +{ + return 0; +} + +CV_IMPL int cvSetErrMode(int) +{ + return 0; +} + +CV_IMPL int cvGetErrStatus(void) +{ + return 0; +} + +CV_IMPL void cvSetErrStatus(int) +{ +} + + +CV_IMPL void cvError( int code, const char* func_name, + const char* err_msg, + const char* file_name, int line ) +{ + cv::error(cv::Exception(code, err_msg, func_name, file_name, line)); +} + +/* function, which converts int to int */ +CV_IMPL int +cvErrorFromIppStatus( int status ) +{ + switch (status) + { + case CV_BADSIZE_ERR: return CV_StsBadSize; + case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock; + case CV_NULLPTR_ERR: return CV_StsNullPtr; + case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero; + case CV_BADSTEP_ERR: return CV_BadStep; + case CV_OUTOFMEM_ERR: return CV_StsNoMem; + case CV_BADARG_ERR: return CV_StsBadArg; + case CV_NOTDEFINED_ERR: return CV_StsError; + case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported; + case CV_NOTFOUND_ERR: return CV_StsObjectNotFound; + case CV_BADCONVERGENCE_ERR: return CV_StsNoConv; + case CV_BADDEPTH_ERR: return CV_BadDepth; + case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats; + case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI; + case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels; + case CV_BADFLAG_ERR: return CV_StsBadFlag; + case CV_BADRANGE_ERR: return CV_StsBadArg; + case CV_BADCOEF_ERR: return CV_StsBadArg; + case CV_BADFACTOR_ERR: return CV_StsBadArg; + case CV_BADPOINT_ERR: return CV_StsBadPoint; + + default: + return CV_StsError; + } +} + +static CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, 0 }; + +CvModuleInfo* CvModule::first = 0, *CvModule::last = 0; + +CvModule::CvModule( CvModuleInfo* _info ) +{ + cvRegisterModule( _info ); + info = last; +} + +CvModule::~CvModule(void) +{ + if( info ) + { + CvModuleInfo* p = first; + for( ; p != 0 && p->next != info; p = p->next ) + ; + + if( p ) + p->next = info->next; + + if( first == info ) + first = info->next; + + if( last == info ) + last = p; + + free( info ); + info = 0; + } +} + +CV_IMPL int +cvRegisterModule( const CvModuleInfo* module ) +{ + CV_Assert( module != 0 && module->name != 0 && module->version != 0 ); + + size_t name_len = strlen(module->name); + size_t version_len = strlen(module->version); + + CvModuleInfo* module_copy = (CvModuleInfo*)malloc( sizeof(*module_copy) + + name_len + 1 + version_len + 1 ); + + *module_copy = *module; + module_copy->name = (char*)(module_copy + 1); + module_copy->version = (char*)(module_copy + 1) + name_len + 1; + + memcpy( (void*)module_copy->name, module->name, name_len + 1 ); + memcpy( (void*)module_copy->version, module->version, version_len + 1 ); + module_copy->next = 0; + + if( CvModule::first == 0 ) + CvModule::first = module_copy; + else + CvModule::last->next = module_copy; + + CvModule::last = module_copy; + + return 0; +} + +CvModule cxcore_module( &cxcore_info ); + +CV_IMPL void +cvGetModuleInfo( const char* name, const char **version, const char **plugin_list ) +{ + static char joint_verinfo[1024] = ""; + static char plugin_list_buf[1024] = ""; + + if( version ) + *version = 0; + + if( plugin_list ) + *plugin_list = 0; + + CvModuleInfo* module; + + if( version ) + { + if( name ) + { + size_t i, name_len = strlen(name); + + for( module = CvModule::first; module != 0; module = module->next ) + { + if( strlen(module->name) == name_len ) + { + for( i = 0; i < name_len; i++ ) + { + int c0 = toupper(module->name[i]), c1 = toupper(name[i]); + if( c0 != c1 ) + break; + } + if( i == name_len ) + break; + } + } + if( !module ) + CV_Error( CV_StsObjectNotFound, "The module is not found" ); + + *version = module->version; + } + else + { + char* ptr = joint_verinfo; + + for( module = CvModule::first; module != 0; module = module->next ) + { + sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" ); + ptr += strlen(ptr); + } + + *version = joint_verinfo; + } + } + + if( plugin_list ) + *plugin_list = plugin_list_buf; +} + +#if defined BUILD_SHARED_LIBS && defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE +BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ); + +BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ) +{ + if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH ) + { + cv::deleteThreadAllocData(); + cv::deleteThreadRNGData(); + } + return TRUE; +} +#endif + +namespace cv +{ + +#if defined WIN32 || defined _WIN32 || defined WINCE + +struct Mutex::Impl +{ + Impl() { InitializeCriticalSection(&cs); refcount = 1; } + ~Impl() { DeleteCriticalSection(&cs); } + + void lock() { EnterCriticalSection(&cs); } + bool trylock() { return TryEnterCriticalSection(&cs) != 0; } + void unlock() { LeaveCriticalSection(&cs); } + + CRITICAL_SECTION cs; + int refcount; +}; + +#ifndef __GNUC__ +int _interlockedExchangeAdd(int* addr, int delta) +{ +#if defined _MSC_VER && _MSC_VER >= 1500 + return (int)_InterlockedExchangeAdd((long volatile*)addr, delta); +#else + return (int)InterlockedExchangeAdd((long volatile*)addr, delta); +#endif +} +#endif // __GNUC__ + +#elif defined __APPLE__ + +#include + +struct Mutex::Impl +{ + Impl() { sl = OS_SPINLOCK_INIT; refcount = 1; } + ~Impl() {} + + void lock() { OSSpinLockLock(&sl); } + bool trylock() { return OSSpinLockTry(&sl); } + void unlock() { OSSpinLockUnlock(&sl); } + + OSSpinLock sl; + int refcount; +}; + +#elif defined __linux__ && !defined ANDROID + +struct Mutex::Impl +{ + Impl() { pthread_spin_init(&sl, 0); refcount = 1; } + ~Impl() { pthread_spin_destroy(&sl); } + + void lock() { pthread_spin_lock(&sl); } + bool trylock() { return pthread_spin_trylock(&sl) == 0; } + void unlock() { pthread_spin_unlock(&sl); } + + pthread_spinlock_t sl; + int refcount; +}; + +#else + +struct Mutex::Impl +{ + Impl() { pthread_mutex_init(&sl, 0); refcount = 1; } + ~Impl() { pthread_mutex_destroy(&sl); } + + void lock() { pthread_mutex_lock(&sl); } + bool trylock() { return pthread_mutex_trylock(&sl) == 0; } + void unlock() { pthread_mutex_unlock(&sl); } + + pthread_mutex_t sl; + int refcount; +}; + +#endif + +Mutex::Mutex() +{ + impl = new Mutex::Impl; +} + +Mutex::~Mutex() +{ + if( CV_XADD(&impl->refcount, -1) == 1 ) + delete impl; + impl = 0; +} + +Mutex::Mutex(const Mutex& m) +{ + impl = m.impl; + CV_XADD(&impl->refcount, 1); +} + +Mutex& Mutex::operator = (const Mutex& m) +{ + CV_XADD(&m.impl->refcount, 1); + if( CV_XADD(&impl->refcount, -1) == 1 ) + delete impl; + impl = m.impl; + return *this; +} + +void Mutex::lock() { impl->lock(); } +void Mutex::unlock() { impl->unlock(); } +bool Mutex::trylock() { return impl->trylock(); } + +} + +/* End of file. */ \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/src/tables.cpp diffimg-2.0.0/3rdparty/opencv/core/src/tables.cpp --- diffimg-1.5.0/3rdparty/opencv/core/src/tables.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/src/tables.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3512 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// CvMat helper tables +// +// */ + +#include "precomp.hpp" + +namespace cv +{ + +const float g_8x32fTab[] = +{ + -128.f, -127.f, -126.f, -125.f, -124.f, -123.f, -122.f, -121.f, + -120.f, -119.f, -118.f, -117.f, -116.f, -115.f, -114.f, -113.f, + -112.f, -111.f, -110.f, -109.f, -108.f, -107.f, -106.f, -105.f, + -104.f, -103.f, -102.f, -101.f, -100.f, -99.f, -98.f, -97.f, + -96.f, -95.f, -94.f, -93.f, -92.f, -91.f, -90.f, -89.f, + -88.f, -87.f, -86.f, -85.f, -84.f, -83.f, -82.f, -81.f, + -80.f, -79.f, -78.f, -77.f, -76.f, -75.f, -74.f, -73.f, + -72.f, -71.f, -70.f, -69.f, -68.f, -67.f, -66.f, -65.f, + -64.f, -63.f, -62.f, -61.f, -60.f, -59.f, -58.f, -57.f, + -56.f, -55.f, -54.f, -53.f, -52.f, -51.f, -50.f, -49.f, + -48.f, -47.f, -46.f, -45.f, -44.f, -43.f, -42.f, -41.f, + -40.f, -39.f, -38.f, -37.f, -36.f, -35.f, -34.f, -33.f, + -32.f, -31.f, -30.f, -29.f, -28.f, -27.f, -26.f, -25.f, + -24.f, -23.f, -22.f, -21.f, -20.f, -19.f, -18.f, -17.f, + -16.f, -15.f, -14.f, -13.f, -12.f, -11.f, -10.f, -9.f, + -8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, + 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, + 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f, + 16.f, 17.f, 18.f, 19.f, 20.f, 21.f, 22.f, 23.f, + 24.f, 25.f, 26.f, 27.f, 28.f, 29.f, 30.f, 31.f, + 32.f, 33.f, 34.f, 35.f, 36.f, 37.f, 38.f, 39.f, + 40.f, 41.f, 42.f, 43.f, 44.f, 45.f, 46.f, 47.f, + 48.f, 49.f, 50.f, 51.f, 52.f, 53.f, 54.f, 55.f, + 56.f, 57.f, 58.f, 59.f, 60.f, 61.f, 62.f, 63.f, + 64.f, 65.f, 66.f, 67.f, 68.f, 69.f, 70.f, 71.f, + 72.f, 73.f, 74.f, 75.f, 76.f, 77.f, 78.f, 79.f, + 80.f, 81.f, 82.f, 83.f, 84.f, 85.f, 86.f, 87.f, + 88.f, 89.f, 90.f, 91.f, 92.f, 93.f, 94.f, 95.f, + 96.f, 97.f, 98.f, 99.f, 100.f, 101.f, 102.f, 103.f, + 104.f, 105.f, 106.f, 107.f, 108.f, 109.f, 110.f, 111.f, + 112.f, 113.f, 114.f, 115.f, 116.f, 117.f, 118.f, 119.f, + 120.f, 121.f, 122.f, 123.f, 124.f, 125.f, 126.f, 127.f, + 128.f, 129.f, 130.f, 131.f, 132.f, 133.f, 134.f, 135.f, + 136.f, 137.f, 138.f, 139.f, 140.f, 141.f, 142.f, 143.f, + 144.f, 145.f, 146.f, 147.f, 148.f, 149.f, 150.f, 151.f, + 152.f, 153.f, 154.f, 155.f, 156.f, 157.f, 158.f, 159.f, + 160.f, 161.f, 162.f, 163.f, 164.f, 165.f, 166.f, 167.f, + 168.f, 169.f, 170.f, 171.f, 172.f, 173.f, 174.f, 175.f, + 176.f, 177.f, 178.f, 179.f, 180.f, 181.f, 182.f, 183.f, + 184.f, 185.f, 186.f, 187.f, 188.f, 189.f, 190.f, 191.f, + 192.f, 193.f, 194.f, 195.f, 196.f, 197.f, 198.f, 199.f, + 200.f, 201.f, 202.f, 203.f, 204.f, 205.f, 206.f, 207.f, + 208.f, 209.f, 210.f, 211.f, 212.f, 213.f, 214.f, 215.f, + 216.f, 217.f, 218.f, 219.f, 220.f, 221.f, 222.f, 223.f, + 224.f, 225.f, 226.f, 227.f, 228.f, 229.f, 230.f, 231.f, + 232.f, 233.f, 234.f, 235.f, 236.f, 237.f, 238.f, 239.f, + 240.f, 241.f, 242.f, 243.f, 244.f, 245.f, 246.f, 247.f, + 248.f, 249.f, 250.f, 251.f, 252.f, 253.f, 254.f, 255.f +}; + +/* [-255..255].^2 */ +const ushort g_8x16uSqrTab[] = +{ + 65025, 64516, 64009, 63504, 63001, 62500, 62001, 61504, 61009, 60516, 60025, 59536, + 59049, 58564, 58081, 57600, 57121, 56644, 56169, 55696, 55225, 54756, 54289, 53824, + 53361, 52900, 52441, 51984, 51529, 51076, 50625, 50176, 49729, 49284, 48841, 48400, + 47961, 47524, 47089, 46656, 46225, 45796, 45369, 44944, 44521, 44100, 43681, 43264, + 42849, 42436, 42025, 41616, 41209, 40804, 40401, 40000, 39601, 39204, 38809, 38416, + 38025, 37636, 37249, 36864, 36481, 36100, 35721, 35344, 34969, 34596, 34225, 33856, + 33489, 33124, 32761, 32400, 32041, 31684, 31329, 30976, 30625, 30276, 29929, 29584, + 29241, 28900, 28561, 28224, 27889, 27556, 27225, 26896, 26569, 26244, 25921, 25600, + 25281, 24964, 24649, 24336, 24025, 23716, 23409, 23104, 22801, 22500, 22201, 21904, + 21609, 21316, 21025, 20736, 20449, 20164, 19881, 19600, 19321, 19044, 18769, 18496, + 18225, 17956, 17689, 17424, 17161, 16900, 16641, 16384, 16129, 15876, 15625, 15376, + 15129, 14884, 14641, 14400, 14161, 13924, 13689, 13456, 13225, 12996, 12769, 12544, + 12321, 12100, 11881, 11664, 11449, 11236, 11025, 10816, 10609, 10404, 10201, 10000, + 9801, 9604, 9409, 9216, 9025, 8836, 8649, 8464, 8281, 8100, 7921, 7744, + 7569, 7396, 7225, 7056, 6889, 6724, 6561, 6400, 6241, 6084, 5929, 5776, + 5625, 5476, 5329, 5184, 5041, 4900, 4761, 4624, 4489, 4356, 4225, 4096, + 3969, 3844, 3721, 3600, 3481, 3364, 3249, 3136, 3025, 2916, 2809, 2704, + 2601, 2500, 2401, 2304, 2209, 2116, 2025, 1936, 1849, 1764, 1681, 1600, + 1521, 1444, 1369, 1296, 1225, 1156, 1089, 1024, 961, 900, 841, 784, + 729, 676, 625, 576, 529, 484, 441, 400, 361, 324, 289, 256, + 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, + 9, 4, 1, 0, 1, 4, 9, 16, 25, 36, 49, 64, + 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, + 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, + 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, + 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, + 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, + 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, + 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, + 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000, 10201, 10404, 10609, 10816, + 11025, 11236, 11449, 11664, 11881, 12100, 12321, 12544, 12769, 12996, 13225, 13456, + 13689, 13924, 14161, 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129, 16384, + 16641, 16900, 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321, 19600, + 19881, 20164, 20449, 20736, 21025, 21316, 21609, 21904, 22201, 22500, 22801, 23104, + 23409, 23716, 24025, 24336, 24649, 24964, 25281, 25600, 25921, 26244, 26569, 26896, + 27225, 27556, 27889, 28224, 28561, 28900, 29241, 29584, 29929, 30276, 30625, 30976, + 31329, 31684, 32041, 32400, 32761, 33124, 33489, 33856, 34225, 34596, 34969, 35344, + 35721, 36100, 36481, 36864, 37249, 37636, 38025, 38416, 38809, 39204, 39601, 40000, + 40401, 40804, 41209, 41616, 42025, 42436, 42849, 43264, 43681, 44100, 44521, 44944, + 45369, 45796, 46225, 46656, 47089, 47524, 47961, 48400, 48841, 49284, 49729, 50176, + 50625, 51076, 51529, 51984, 52441, 52900, 53361, 53824, 54289, 54756, 55225, 55696, + 56169, 56644, 57121, 57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, + 62001, 62500, 63001, 63504, 64009, 64516, 65025 +}; + +const uchar g_Saturate8u[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255 +}; + +const char* g_HersheyGlyphs[] = { + "", + "MWRMNV RMVV PSTS", + "MWOMOV OMSMUNUPSQ OQSQURUUSVOV", + "MXVNTMRMPNOPOSPURVTVVU", + "MWOMOV OMRMTNUPUSTURVOV", + "MWOMOV OMUM OQSQ OVUV", + "MVOMOV OMUM OQSQ", + "MXVNTMRMPNOPOSPURVTVVUVR SRVR", + "MWOMOV UMUV OQUQ", + "PTRMRV", + "NUSMSTRVPVOTOS", + "MWOMOV UMOS QQUV", + "MVOMOV OVUV", + "LXNMNV NMRV VMRV VMVV", + "MWOMOV OMUV UMUV", + "MXRMPNOPOSPURVSVUUVSVPUNSMRM", + "MWOMOV OMSMUNUQSROR", + "MXRMPNOPOSPURVSVUUVSVPUNSMRM STVW", + "MWOMOV OMSMUNUQSROR RRUV", + "MWUNSMQMONOOPPTRUSUUSVQVOU", + "MWRMRV NMVM", + "MXOMOSPURVSVUUVSVM", + "MWNMRV VMRV", + "LXNMPV RMPV RMTV VMTV", + "MWOMUV UMOV", + "MWNMRQRV VMRQ", + "MWUMOV OMUM OVUV", + "MWRMNV RMVV PSTS", + "MWOMOV OMSMUNUPSQ OQSQURUUSVOV", + "MVOMOV OMUM", + "MWRMNV RMVV NVVV", + "MWOMOV OMUM OQSQ OVUV", + "MWUMOV OMUM OVUV", + "MWOMOV UMUV OQUQ", + "MXRMPNOPOSPURVSVUUVSVPUNSMRM QQTR TQQR", + "PTRMRV", + "MWOMOV UMOS QQUV", + "MWRMNV RMVV", + "LXNMNV NMRV VMRV VMVV", + "MWOMOV OMUV UMUV", + "MWOMUM PQTR TQPR OVUV", + "MXRMPNOPOSPURVSVUUVSVPUNSMRM", + "MWOMOV UMUV OMUM", + "MWOMOV OMSMUNUQSROR", + "MWOMRQOV OMUM OVUV", + "MWRMRV NMVM", + "MWNONNOMPMQNRPRV VOVNUMTMSNRP", + "LXRMRV PONPNSPTTTVSVPTOPO", + "MWOMUV UMOV", + "LXRMRV NOOPOSQTSTUSUPVO", + "MXOVQVOROPPNRMSMUNVPVRTVVV", + "MWSMMV SMUV OSTS", + "MWQMNV QMTMVNVPSQPQ SQURUTTURVNV", + "LXVPUNTMRMPNOONQNSOUPVRVTUUT", + "MXQMNV QMUMVOVQUTTURVNV", + "MVQMNV QMVM PQSQ NVSV", + "MVQMNV QMVM PQSQ", + "LXVPUNTMRMPNOONQNSOUPVRVTUUSRS", + "MXQMNV WMTV PQUQ", + "PUTMQV", + "OVUMSSRUQVPVOUOT", + "MVQMNV VMOS RQTV", + "NVRMOV OVTV", + "LYPMMV PMQV XMQV XMUV", + "MXQMNV QMTV WMTV", + "LXRMPNOONQNSOUPVRVTUUTVRVPUNTMRM", + "MWQMNV QMUMVNVPUQSRPR", + "LXRMPNOONQNSOUPVRVTUUTVRVPUNTMRM QVPUPTQSRSSTTVUWVW", + "MWQMNV QMUMVNVPUQSRPR QRRUSVTVUU", + "MWVNTMRMPNPPQQTRUSUUSVPVNU", + "MVSMPV PMVM", + "LXPMNSNUOVRVTUUSWM", + "MWOMQV WMQV", + "KXNMNV SMNV SMSV XMSV", + "NWQMTV WMNV", + "NWQMSQQV WMSQ", + "MWQMWMNVTV", + "", + "", + "", + "", + "", + "", + "LXNMRV VMRV NMVM", + "MWNLVX", + "LXRONU ROVU", + "MWNVVV", + "PVRMUQ", + "MWMMOKQKTMVMWK", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NWQPTPUQUV URQSPTPUQVSVUU", + "MWOMOV OSPURVTUUSTQRPPQOS", + "MWUQSPRPPQOSPURVSVUU", + "MWUMUV USTQRPPQOSPURVTUUS", + "MWOSUSTQRPPQOSPURVTV", + "NVUNTMSMRNRV PPTP", + "MWUPUVTXRYPY USTQRPPQOSPURVTUUS", + "MWOMOV OSPQRPTQUSUV", + "PTRLQMRNSMRL RPRV", + "PUSLRMSNTMSL SPSXRYQYPX", + "NWPMPV UPPT RSUV", + "PTRMRV", + "KYMPMV MSNQOPPPQQRSRV RSSQTPUPVQWSWV", + "MWOPOV OSPQRPTQUSUV", + "MWRPPQOSPURVTUUSTQRP", + "MWOPOY OSPURVTUUSTQRPPQOS", + "MWUPUY USTQRPPQOSPURVTUUS", + "NVPPPV PSQQSPTP", + "NWUQTPQPPQPRQSTSUTUUTVQVPU", + "NVRMRUSVTVUU PPTP", + "MWUPUV OPOSPURVTUUS", + "NVOPRV UPRV", + "LXNPPV RPPV RPTV VPTV", + "MWOPUV UPOV", + "MWOPRV UPRVQXPYOY", + "MWOPUPOVUV", + "MXVPUSTURVPUOSPQRPTQUUVV", + "MWOTQVSVTUTSSRPQRQTPUOUNTMRMQNPPOTNY", + "MXNQOPQPRQRSQW VPURSTQWPY", + "MWTNSMRMQNQORPTQUSTURVPUOSPQRP", + "NWUQSPQPPQPRQS SSQSPTPUQVSVUU", + "NWTMSNSOTP UPSPQQPSPUQVSWSXRYQY", + "LXNQOPPPQQQSPV QSRQTPUPVQVSUVTY", + "LXNQOPPPQQQURVSVTUUSVPVNUMTMSNSPTRUSWT", + "OVRPQSQURVSVTU", + "MWQPOV UPTPRQPS PSQUSVTV", + "MWOMPMQNRPUV RPOV", + "LYPPMY UPTSSUQVPVOUOS TSTUUVVVWU", + "MWNPOPOV UPTSRUOV", + "NWTMSNSOTP UPSPQQQRRSTS SSQTPUPVQWSXSYRZQZ", + "MWRPPQOSPURVTUUSTQRP", + "MXOQQPVP QPQRPV TPTRUV", + "MWOSPURVTUUSTQRPPQOSNY", + "MXVPRPPQOSPURVTUUSTQRP", + "MXOQQPVP SPRV", + "KXMQNPOPPQPUQVSVTUUSVP", + "MXPPOQOSPURVSVUUVSVQUPTPSQRSQY", + "MWOPPPQQSXTYUY UPTRPWOY", + "KYTMRY MQNPOPPQPUQVTVUUVSWP", + "LXOPNRNTOVQVRTRR UPVRVTUVSVRT", + "LWTSSQQPOQNSOUQVSUTS UPTSTUUVVV", + "MWQMOSPURVTUUSTQRPPQOS", + "MWUQSPRPPQOSPURVTV", + "LWTSSQQPOQNSOUQVSUTS VMTSTUUVVV", + "MWOSTSURUQSPRPPQOSPURVTV", + "OVVMUMTNSPQVPXOYNY QPUP", + "MXUSTQRPPQOSPURVTUUS VPTVSXRYPYOX", + "MVQMNV OSPQQPSPTQTRSTSUTVUV", + "PUSMSNTNTMSM QPRPSQSRRTRUSVTV", + "OUSMSNTNTMSM QPRPSQSRRVQXPYOYNX", + "NVRMOV UPTPRQPS PSQUSVTV", + "OTSMQSQURVSV", + "JYKPLPMQMSLV MSNQOPQPRQRSQV RSSQTPVPWQWRVTVUWVXV", + "MWNPOPPQPSOV PSQQRPTPUQURTTTUUVVV", + "MWRPPQOSPURVTUUSTQRP", + "MXNPOPPQPSNY PSQUSVUUVSUQSPQQPS", + "MXUSTQRPPQOSPURVTUUS VPSY", + "MVOPPPQQQSPV UQTPSPRQQS", + "NVTQSPQPPQPRQSRSSTSURVPVOU", + "NUSMQSQURVSV PPTP", + "MWNPOPPQPROTOUPVRVSUTS UPTSTUUVVV", + "MWNPOPPQPROTOUPVRVTUURUP", + "KYLPMPNQNRMTMUNVPVQURSSP RSRUSVUVVUWRWP", + "MWOQPPQPRQRUSVTVUU VQUPTPSQQUPVOVNU", + "MWNPOPPQPROTOUPVRVSUTS UPSVRXQYOYNX", + "NVUPOV PQQPSPTQ PUQVSVTU", + "", + "", + "", + "", + "", + "", + "MWUSTQRPPQOSPURVTUUSUPTNRMQM", + "MWUQSPRPPQOSPURVSVUU OSSS", + "MWRMQNPPOSOVPWRWSVTTUQUNTMRM PRTR", + "MWTMQY RPPQOSPURVSVUUVSUQSPRP", + "MWUQSPQPOQOSPTRUSVSWRXQX", + "", + "", + "KYTPTSUTVTWSWQVOUNSMQMONNOMQMSNUOVQWSWUV TQSPQPPQPSQTSTTS", + "MWUNORUV", + "MWONUROV", + "OUTKQKQYTY", + "OUPKSKSYPY", + "OUTKSLRNROSQQRSSRURVSXTY", + "OUPKQLRNROQQSRQSRURVQXPY", + "LYPMQNQOPPOPNONNOMPMSNUNWMNV USTTTUUVVVWUWTVSUS", + "PT", + "NV", + "MWRMPNOPOSPURVTUUSUPTNRM", + "MWPORMRV", + "MWONQMSMUNUPTROVUV", + "MWONQMSMUNUPSQ RQSQURUUSVQVOU", + "MWSMSV SMNSVS", + "MWPMOQQPRPTQUSTURVQVOU PMTM", + "MWTMRMPNOPOSPURVTUUSTQRPPQOS", + "MWUMQV OMUM", + "MWQMONOPQQSQUPUNSMQM QQOROUQVSVUUURSQ", + "MWUPTRRSPROPPNRMTNUPUSTURVPV", + "PURURVSVSURU", + "PUSVRVRUSUSWRY", + "PURPRQSQSPRP RURVSVSURU", + "PURPRQSQSPRP SVRVRUSUSWRY", + "PURMRR SMSR RURVSVSURU", + "NWPNRMSMUNUPRQRRSRSQUP RURVSVSURU", + "PTRMRQ", + "NVPMPQ TMTQ", + "NVQMPNPPQQSQTPTNSMQM", + "MWRKRX UNSMQMONOPQQTRUSUUSVQVOU", + "MWVLNX", + "OUTKRNQQQSRVTY", + "OUPKRNSQSSRVPY", + "PTRKRY", + "LXNRVR", + "LXRNRV NRVR", + "LXNPVP NTVT", + "MWOOUU UOOU", + "MWRORU OPUT UPOT", + "PURQRRSRSQRQ", + "PUSMRORQSQSPRP", + "PUSNRNRMSMSORQ", + "LXSOVRSU NRVR", + "MXQLQY TLTY OQVQ OTVT", + "LXVRURTSSURVOVNUNSORRQSPSNRMPMONOPQSSUUVVV", + "LXNNOQOSNV VNUQUSVV NNQOSOVN NVQUSUVV", + "LYRQQPOPNQNSOTQTRSSQTPVPWQWSVTTTSSRQ", + "", + "H\\NRMQLRMSNR VRWQXRWSVR", + "H\\MPLQLRMSNSOROQNPMP MQMRNRNQMQ WPVQVRWSXSYRYQXPWP WQWRXRXQWQ", + "I[KRYR", + "", + "H\\RUJPRTZPRU", + "", + "", + "", + "", + "", + "F^ISJQLPNPPQTTVUXUZT[Q ISJPLONOPPTSVTXTZS[Q IYJWLVNVPWTZV[X[ZZ[W IYJVLUNUPVTYVZXZZY[W", + "", + "F^ISJQLPNPPQTTVUXUZT[Q ISJPLONOPPTSVTXTZS[Q IW[W I[[[", + "", + "CaGO]OXI L[GU]U", + "", + "D`F^^^^FFFF^", + "", + "KYQVOUNSNQOOQNSNUOVQVSUUSVQV SVVS QVVQ OUUO NSSN NQQN", + "", + "H\\IR[R", + "H\\IR[R IQ[Q", + "", + "LYPFSCSP RDRP OPVP MRXR OVOWNWNVOUQTTTVUWWVYTZQ[O\\N^Na TTUUVWUYTZ N`O_P_S`V`W_ P_SaVaW_W^", + "LYPFSCSP RDRP OPVP MRXR OVOWNWNVOUQTTTVUWWVYTZ TTUUVWUYTZ RZTZV[W]W^V`TaQaO`N_N^O^O_ TZU[V]V^U`Ta", + "LYPFSCSP RDRP OPVP MRXR VVVWWWWVVUTTRTPUOVNYN^O`QaTaV`W^W\\VZTYQYN[ RTPVOYO^P`Qa TaU`V^V\\UZTY", + "LYPFSCSP RDRP OPVP MRXR QTOUNWOYQZTZVYWWVUTTQT QTPUOWPYQZ TZUYVWUUTT QZO[N]N^O`QaTaV`W^W]V[TZ QZP[O]O^P`Qa TaU`V^V]U[TZ", + "LYOEOFNFNEODQCTCVDWFVHTIQJOKNMNP TCUDVFUHTI NOONPNSOVOWN PNSPVPWNWM MRXR OVOWNWNVOUQTTTVUWWVYTZ TTUUVWUYTZ RZTZV[W]W^V`TaQaO`N_N^O^O_ TZU[V]V^U`Ta", + "LYOEOFNFNEODQCTCVDWFVHTI TCUDVFUHTI RITIVJWLWMVOTPQPOONNNMOMON TIUJVLVMUOTP MRXR QTOUNWOYQZTZVYWWVUTTQT QTPUOWPYQZ TZUYVWUUTT QZO[N]N^O`QaTaV`W^W]V[TZ QZP[O]O^P`Qa TaU`V^V]U[TZ", + "LYOCNI OCVC ODSDVC NIOHQGTGVHWJWMVOTPQPOONNNMOMON TGUHVJVMUOTP MRXR QTOUNWOYQZTZVYWWVUTTQT QTPUOWPYQZ TZUYVWUUTT QZO[N]N^O`QaTaV`W^W]V[TZ QZP[O]O^P`Qa TaU`V^V]U[TZ", + "LYNCNG VERLPP WCTIQP NEPCRCUE NEPDRDUEVE MRXR QTOUNWOYQZTZVYWWVUTTQT QTPUOWPYQZ TZUYVWUUTT QZO[N]N^O`QaTaV`W^W]V[TZ QZP[O]O^P`Qa TaU`V^V]U[TZ", + "LYOCNI OCVC ODSDVC NIOHQGTGVHWJWMVOTPQPOONNNMOMON TGUHVJVMUOTP MRXR VVVWWWWVVUTTRTPUOVNYN^O`QaTaV`W^W\\VZTYQYN[ RTPVOYO^P`Qa TaU`V^V\\UZTY", + "LYPFSCSP RDRP OPVP MRXR SVSa TTTa TTM]X] QaVa", + "LYOEOFNFNEODQCTCVDWFVHTI TCUDVFUHTI RITIVJWLWMVOTPQPOONNNMOMON TIUJVLVMUOTP MRXR SVSa TTTa TTM]X] QaVa", + "F^YXWZU[R[PZMXKWIWHXHZI[K[MZOWPURQTKWGYFZF[G\\H[IZH[G[FZFYFWGVHTLRPPVNZMZ OPUP", + "E^P[MZJXHUGRGOHLJIMGPFTFWGYI[L\\O\\R[UYXVZS[P[ NJNW OJOW LJSJVKWMWNVPSQOQ SJUKVMVNUPSQ LWQW SQTRUVVWWWXV SQURVVWW", + "E^P[MZJXHUGRGOHLJIMGPFTFWGYI[L\\O\\R[UYXVZS[P[ UKVJVNUKSJPJNKMLLOLRMUNVPWSWUVVT PJNLMOMRNUPW", + "E_IM[M IR[R IW[W K[YI", + "CaHQGRHSIRHQ RQQRRSSRRQ \\Q[R\\S]R\\Q", + "", + "E_NWLTIRLPNM LPJRLT JRZR VWXT[RXPVM XPZRXT", + "JZWNTLRIPLMN PLRJTL RJRZ WVTXR[PXMV PXRZTX", + "F^ZJSJOKMLKNJQJSKVMXOYSZZZ SFS^", + "F^JJQJUKWLYNZQZSYVWXUYQZJZ QFQ^", + "F^JJQJUKWLYNZQZSYVWXUYQZJZ ORZR", + "", + "H\\LBL[ RBR[ XBX[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "I[RFJ[ RFZ[ MTWT", + "G\\KFK[ KFTFWGXHYJYLXNWOTP KPTPWQXRYTYWXYWZT[K[", + "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV", + "G\\KFK[ KFRFUGWIXKYNYSXVWXUZR[K[", + "H[LFL[ LFYF LPTP L[Y[", + "HZLFL[ LFYF LPTP", + "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS USZS", + "G]KFK[ YFY[ KPYP", + "NVRFR[", + "JZVFVVUYTZR[P[NZMYLVLT", + "G\\KFK[ YFKT POY[", + "HYLFL[ L[X[", + "F^JFJ[ JFR[ ZFR[ ZFZ[", + "G]KFK[ KFY[ YFY[", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF", + "G\\KFK[ KFTFWGXHYJYMXOWPTQKQ", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF SWY]", + "G\\KFK[ KFTFWGXHYJYLXNWOTPKP RPY[", + "H\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX", + "JZRFR[ KFYF", + "G]KFKULXNZQ[S[VZXXYUYF", + "I[JFR[ ZFR[", + "F^HFM[ RFM[ RFW[ \\FW[", + "H\\KFY[ YFK[", + "I[JFRPR[ ZFRP", + "H\\YFK[ KFYF K[Y[", + "I[RFJ[ RFZ[ MTWT", + "G\\KFK[ KFTFWGXHYJYLXNWOTP KPTPWQXRYTYWXYWZT[K[", + "HYLFL[ LFXF", + "I[RFJ[ RFZ[ J[Z[", + "H[LFL[ LFYF LPTP L[Y[", + "H\\YFK[ KFYF K[Y[", + "G]KFK[ YFY[ KPYP", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF OPUP", + "NVRFR[", + "G\\KFK[ YFKT POY[", + "I[RFJ[ RFZ[", + "F^JFJ[ JFR[ ZFR[ ZFZ[", + "G]KFK[ KFY[ YFY[", + "I[KFYF OPUP K[Y[", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF", + "G]KFK[ YFY[ KFYF", + "G\\KFK[ KFTFWGXHYJYMXOWPTQKQ", + "I[KFRPK[ KFYF K[Y[", + "JZRFR[ KFYF", + "I[KKKILGMFOFPGQIRMR[ YKYIXGWFUFTGSIRM", + "H\\RFR[ PKMLLMKOKRLTMUPVTVWUXTYRYOXMWLTKPK", + "H\\KFY[ K[YF", + "G]RFR[ ILJLKMLQMSNTQUSUVTWSXQYMZL[L", + "H\\K[O[LTKPKLLINGQFSFVGXIYLYPXTU[Y[", + "G[G[IZLWOSSLVFV[UXSUQSNQLQKRKTLVNXQZT[Y[", + "F]SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFXFZG[I[KZMYNWOTP SPTPWQXRYTYWXYWZU[R[PZOX", + "H\\TLTMUNWNYMZKZIYGWFTFQGOIMLLNKRKVLYMZO[Q[TZVXWV", + "G^TFRGQIPMOSNVMXKZI[G[FZFXGWIWKXMZP[S[VZXXZT[O[KZHYGWFTFRHRJSMUPWRZT\\U", + "H\\VJVKWLYLZKZIYGVFRFOGNINLONPOSPPPMQLRKTKWLYMZP[S[VZXXYV", + "H\\RLPLNKMINGQFTFXG[G]F XGVNTTRXPZN[L[JZIXIVJULUNV QPZP", + "G^G[IZMVPQQNRJRGQFPFOGNINLONQOUOXNYMZKZQYVXXVZS[O[LZJXIVIT", + "F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX MRVOXN[L]J^H^G]F\\FZHXLVRUWUZV[W[YZZY\\V", + "IZWVUTSQROQLQIRGSFUFVGWIWLVQTVSXQZO[M[KZJXJVKUMUOV", + "JYT^R[PVOPOJPGRFTFUGVJVMURR[PaOdNfLgKfKdLaN^P\\SZWX", + "F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX ^I^G]F\\FZGXIVLTNROPO ROSQSXTZU[V[XZYY[V", + "I\\MRORSQVOXMYKYHXFVFUGTISNRSQVPXNZL[J[IZIXJWLWNXQZT[V[YZ[X", + "@aEMCLBJBICGEFFFHGIIIKHPGTE[ GTJLLHMGOFPFRGSISKRPQTO[ QTTLVHWGYFZF\\G]I]K\\PZWZZ[[\\[^Z_YaV", + "E]JMHLGJGIHGJFKFMGNINKMPLTJ[ LTOLQHRGTFVFXGYIYKXPVWVZW[X[ZZ[Y]V", + "H]TFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGVFTFRHRKSNUQWSZU\\V", + "F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFZF\\G]H^J^M]O\\PZQWQUPTO", + "H^ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[YZ[X", + "F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFYF[G\\H]J]M\\O[PYQVQSPTQUSUXVZX[ZZ[Y]V", + "H\\H[JZLXOTQQSMTJTGSFRFQGPIPKQMSOVQXSYUYWXYWZT[P[MZKXJVJT", + "H[RLPLNKMINGQFTFXG[G]F XGVNTTRXPZN[L[JZIXIVJULUNV", + "E]JMHLGJGIHGJFKFMGNINKMOLRKVKXLZN[P[RZSYUUXMZF XMWQVWVZW[X[ZZ[Y]V", + "F]KMILHJHIIGKFLFNGOIOKNOMRLVLYM[O[QZTWVTXPYMZIZGYFXFWGVIVKWNYP[Q", + "C_HMFLEJEIFGHFIFKGLILLK[ UFK[ UFS[ aF_G\\JYNVTS[", + "F^NLLLKKKILGNFPFRGSISLQUQXRZT[V[XZYXYVXUVU ]I]G\\FZFXGVITLPUNXLZJ[H[GZGX", + "F]KMILHJHIIGKFLFNGOIOKNOMRLVLXMZN[P[RZTXVUWSYM [FYMVWT]RbPfNgMfMdNaP^S[VY[V", + "H]ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWTTWPZN[K[JZJXKWNWPXQYR[R^QaPcNfLgKfKdLaN^Q[TYZV", + "", + "", + "", + "", + "", + "", + "I[JFR[ ZFR[ JFZF", + "G]IL[b", + "E_RJIZ RJ[Z", + "I[J[Z[", + "I[J[Z[ZZJZJ[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "I\\XMX[ XPVNTMQMONMPLSLUMXOZQ[T[VZXX", + "H[LFL[ LPNNPMSMUNWPXSXUWXUZS[P[NZLX", + "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX", + "I\\XFX[ XPVNTMQMONMPLSLUMXOZQ[T[VZXX", + "I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX", + "MYWFUFSGRJR[ OMVM", + "I\\XMX]W`VaTbQbOa XPVNTMQMONMPLSLUMXOZQ[T[VZXX", + "I\\MFM[ MQPNRMUMWNXQX[", + "NVQFRGSFREQF RMR[", + "MWRFSGTFSERF SMS^RaPbNb", + "IZMFM[ WMMW QSX[", + "NVRFR[", + "CaGMG[ GQJNLMOMQNRQR[ RQUNWMZM\\N]Q][", + "I\\MMM[ MQPNRMUMWNXQX[", + "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM", + "H[LMLb LPNNPMSMUNWPXSXUWXUZS[P[NZLX", + "I\\XMXb XPVNTMQMONMPLSLUMXOZQ[T[VZXX", + "KXOMO[ OSPPRNTMWM", + "J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX", + "MYRFRWSZU[W[ OMVM", + "I\\MMMWNZP[S[UZXW XMX[", + "JZLMR[ XMR[", + "G]JMN[ RMN[ RMV[ ZMV[", + "J[MMX[ XMM[", + "JZLMR[ XMR[P_NaLbKb", + "J[XMM[ MMXM M[X[", + "H]QMONMPLRKUKXLZN[P[RZUWWTYPZM QMSMTNUPWXXZY[Z[", + "I\\UFSGQIOMNPMTLZKb UFWFYHYKXMWNUORO ROTPVRWTWWVYUZS[Q[OZNYMV", + "I\\JPLNNMOMQNROSRSVR[ ZMYPXRR[P_Ob", + "I[TMQMONMPLSLVMYNZP[R[TZVXWUWRVOTMRKQIQGRFTFVGXI", + "JZWOVNTMQMONOPPRSS SSOTMVMXNZP[S[UZWX", + "JYTFRGQHQIRJUKXK XKTMQONRMUMWNYP[S]T_TaSbQbP`", + "H\\IQJOLMNMONOPNTL[ NTPPRNTMVMXOXRWWTb", + "G\\HQIOKMMMNNNPMUMXNZO[Q[SZUWVUWRXMXJWGUFSFRHRJSMUPWRZT", + "LWRMPTOXOZP[R[TYUW", + "I[OMK[ YNXMWMUNQROSNS NSPTQUSZT[U[VZ", + "JZKFMFOGPHX[ RML[", + "H]OMIb NQMVMYO[Q[SZUXWT YMWTVXVZW[Y[[Y\\W", + "I[LMOMNSMXL[ YMXPWRUURXOZL[", + "JZTFRGQHQIRJUKXK UKRLPMOOOQQSTTVT TTPUNVMXMZO\\S^T_TaRbPb", + "J[RMPNNPMSMVNYOZQ[S[UZWXXUXRWOVNTMRM", + "G]PML[ UMVSWXX[ IPKNNM[M", + "I[MSMVNYOZQ[S[UZWXXUXRWOVNTMRMPNNPMSIb", + "I][MQMONMPLSLVMYNZP[R[TZVXWUWRVOUNSM", + "H\\SMP[ JPLNOMZM", + "H\\IQJOLMNMONOPMVMYO[Q[TZVXXTYPYM", + "G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb", + "I[KMMMOOU`WbYb ZMYOWRM]K`Jb", + "F]VFNb GQHOJMLMMNMPLULXMZO[Q[TZVXXUZP[M", + "F]NMLNJQITIWJZK[M[OZQW RSQWRZS[U[WZYWZTZQYNXM", + "L\\UUTSRRPRNSMTLVLXMZO[Q[SZTXVRUWUZV[W[YZZY\\V", + "M[MVOSRNSLTITGSFQGPIOMNTNZO[P[RZTXUUURVVWWYW[V", + "MXTTTSSRQROSNTMVMXNZP[S[VYXV", + "L\\UUTSRRPRNSMTLVLXMZO[Q[SZTXZF VRUWUZV[W[YZZY\\V", + "NXOYQXRWSUSSRRQROSNUNXOZQ[S[UZVYXV", + "OWOVSQUNVLWIWGVFTGSIQQNZKaJdJfKgMfNcOZP[R[TZUYWV", + "L[UUTSRRPRNSMTLVLXMZO[Q[SZTY VRTYPdOfMgLfLdMaP^S\\U[XY[V", + "M\\MVOSRNSLTITGSFQGPIOMNSM[ M[NXOVQSSRURVSVUUXUZV[W[YZZY\\V", + "PWSMSNTNTMSM PVRRPXPZQ[R[TZUYWV", + "PWSMSNTNTMSM PVRRLdKfIgHfHdIaL^O\\Q[TYWV", + "M[MVOSRNSLTITGSFQGPIOMNSM[ M[NXOVQSSRURVSVUTVQV QVSWTZU[V[XZYY[V", + "OWOVQSTNULVIVGUFSGRIQMPTPZQ[R[TZUYWV", + "E^EVGSIRJSJTIXH[ IXJVLSNRPRQSQTPXO[ PXQVSSURWRXSXUWXWZX[Y[[Z\\Y^V", + "J\\JVLSNROSOTNXM[ NXOVQSSRURVSVUUXUZV[W[YZZY\\V", + "LZRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXWXYWZV", + "KZKVMSNQMUGg MUNSPRRRTSUUUWTYSZQ[ MZO[R[UZWYZV", + "L[UUTSRRPRNSMTLVLXMZO[Q[SZ VRUUSZPaOdOfPgRfScS\\U[XY[V", + "MZMVOSPQPSSSTTTVSYSZT[U[WZXYZV", + "NYNVPSQQQSSVTXTZR[ NZP[T[VZWYYV", + "OXOVQSSO VFPXPZQ[S[UZVYXV PNWN", + "L[LVNRLXLZM[O[QZSXUU VRTXTZU[V[XZYY[V", + "L[LVNRMWMZN[O[RZTXUUUR URVVWWYW[V", + "I^LRJTIWIYJ[L[NZPX RRPXPZQ[S[UZWXXUXR XRYVZW\\W^V", + "JZJVLSNRPRQSQZR[U[XYZV WSVRTRSSOZN[L[KZ", + "L[LVNRLXLZM[O[QZSXUU VRPdOfMgLfLdMaP^S\\U[XY[V", + "LZLVNSPRRRTTTVSXQZN[P\\Q^QaPdOfMgLfLdMaP^S\\WYZV", + "J\\K[NZQXSVUSWOXKXIWGUFSGRHQJPOPTQXRZT[V[XZYY", + "", + "", + "", + "", + "", + "I[WUWRVOUNSMQMONMPLSLVMYNZP[R[TZVXWUXPXKWHVGTFRFPGNI", + "JZWNUMRMPNNPMSMVNYOZQ[T[VZ MTUT", + "J[TFRGPJOLNOMTMXNZO[Q[SZUWVUWRXMXIWGVFTF NPWP", + "H\\VFNb QMNNLPKSKVLXNZQ[S[VZXXYUYRXPVNSMQM", + "I[XOWNTMQMNNMOLQLSMUOWSZT\\T^S_Q_", + "", + "", + "DaWNVLTKQKOLNMMOMRNTOUQVTVVUWS WKWSXUYV[V\\U]S]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYY", + "F^ZIJRZ[", + "F^JIZRJ[", + "KYOBOb OBVB ObVb", + "KYUBUb NBUB NbUb", + "KYTBQEPHPJQMSOSPORSTSUQWPZP\\Q_Tb", + "KYPBSETHTJSMQOQPURQTQUSWTZT\\S_Pb", + "F^[FYGVHSHPGNFLFJGIIIKKMMMOLPJPHNF [FI[ YTWTUUTWTYV[X[ZZ[X[VYT", + "NV", + "JZ", + "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF", + "H\\NJPISFS[", + "H\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[", + "H\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW", + "H\\UFKTZT UFU[", + "H\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW", + "H\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT", + "H\\YFO[ KFYF", + "H\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF", + "H\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX", + "MWRYQZR[SZRY", + "MWSZR[QZRYSZS\\R^Q_", + "MWRMQNROSNRM RYQZR[SZRY", + "MWRMQNROSNRM SZR[QZRYSZS\\R^Q_", + "MWRFRT RYQZR[SZRY", + "I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RYQZR[SZRY", + "NVRFRM", + "JZNFNM VFVM", + "KYQFOGNINKOMQNSNUMVKVIUGSFQF", + "H\\PBP_ TBT_ YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX", + "G][BIb", + "KYVBTDRGPKOPOTPYR]T`Vb", + "KYNBPDRGTKUPUTTYR]P`Nb", + "NVRBRb", + "E_IR[R", + "E_RIR[ IR[R", + "E_IO[O IU[U", + "G]KKYY YKKY", + "JZRLRX MOWU WOMU", + "MWRQQRRSSRRQ", + "MWSFRGQIQKRLSKRJ", + "MWRHQGRFSGSIRKQL", + "E_UMXP[RXTUW IR[R", + "G]OFOb UFUb JQZQ JWZW", + "E_\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\Z\\Y", + "G]IIJKKOKUJYI[ [IZKYOYUZY[[ IIKJOKUKYJ[I I[KZOYUYYZ[[", + "F_\\Q[OYNWNUOTPQTPUNVLVJUISIQJOLNNNPOQPTTUUWVYV[U\\S\\Q", + "KYOBO[ UBU[", + "F^RBR[ I[[[", + "F^[BI[[[", + "E_RIQJRKSJRI IYHZI[JZIY [YZZ[[\\Z[Y", + "F^RHNLKPJSJUKWMXOXQWRU RHVLYPZSZUYWWXUXSWRU RUQYP\\ RUSYT\\ P\\T\\", + "F^RNQKPINHMHKIJKJOKRLTNWR\\ RNSKTIVHWHYIZKZOYRXTVWR\\", + "F^RGPJLOIR RGTJXO[R IRLUPZR] [RXUTZR]", + "F^RTTWVXXXZW[U[SZQXPVPSQ SQUOVMVKUISHQHOINKNMOOQQ QQNPLPJQISIUJWLXNXPWRT RTQYP\\ RTSYT\\ P\\T\\", + "F^RRR[Q\\ RVQ\\ RIQHOHNINKONRR RISHUHVIVKUNRR RRNOLNJNIOIQJR RRVOXNZN[O[QZR RRNULVJVIUISJR RRVUXVZV[U[SZR", + "F^ISJSLTMVMXLZ ISIRJQLQMRNTNWMYLZ RGPIOLOOQUQXPZR\\ RGTIULUOSUSXTZR\\ [S[RZQXQWRVTVWWYXZ [SZSXTWVWXXZ KVYV", + "", + "", + "", + "PSSRRSQSPRPQQPRPSQSSRUQV QQQRRRRQQQ", + "PTQPPQPSQTSTTSTQSPQP RQQRRSSRRQ", + "NVPOTU TOPU NRVR", + "MWRKQMOPMR RKSMUPWR RMOQ RMUQ ROPQ ROTQ QQSQ MRWR", + "MWMRMQNOONQMSMUNVOWQWR PNTN OOUO NPVP NQVQ MRWR", + "LRLFLRRRLF LIPQ LLOR LOMQ", + "MWRKQMOPMR RKSMUPWR", + "MWWRWQVOUNSMQMONNOMQMR", + "G]]R]P\\MZJWHTGPGMHJJHMGPGR", + "MWMRMSNUOVQWSWUVVUWSWR", + "LXLPNRQSSSVRXP", + "RURUTTURTPRO", + "RVRRUPVNVLUKTK", + "NRRROPNNNLOKPK", + "MWWHVGTFQFOGNHMJMLNNOOUSVTWVWXVZU[S\\P\\N[MZ", + "G]IWHVGTGQHOINKMMMONPOTUUVWWYW[V\\U]S]P\\N[M", + "G]RRTUUVWWYW[V\\U]S]Q\\O[NYMWMUNTOPUOVMWKWIVHUGSGQHOINKMMMONPORR", + "H\\KFK[ HF[FQP[Z ZV[Y\\[ ZVZY WYZY WYZZ\\[", + "KYUARBPCNELHKLKRLUNWQXSXVWXUYR KPLMNKQJSJVKXMYPYVXZV]T_R`Oa", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ">f>RfR", + "D`D``D", + "RRR>Rf", + "D`DD``", + "D`DR`R", + "F^FY^K", + "KYK^YF", + "", + "KYKFY^", + "F^FK^Y", + "KYKRYR", + "MWMWWM", + "", + "MWMMWW", + "", + "", + "", + "", + "D`DOGQKSPTTTYS]Q`O", + "PUUDSGQKPPPTQYS]U`", + "OTODQGSKTPTTSYQ]O`", + "D`DUGSKQPPTPYQ]S`U", + "KYRJYNKVRZ", + "JZJRNKVYZR", + "KYKVKNYVYN", + "JZLXJPZTXL", + "JZJ]L]O\\Q[TXUVVSVOULTJSIQIPJOLNONSOVPXS[U\\X]Z]", + "I]]Z]X\\U[SXPVOSNONLOJPIQISJTLUOVSVVUXT[Q\\O]L]J", + "JZZGXGUHSIPLONNQNUOXPZQ[S[TZUXVUVQUNTLQIOHLGJG", + "G[GJGLHOIQLTNUQVUVXUZT[S[QZPXOUNQNNOLPISHUGXGZ", + "E[EPFRHTJUMVQVUUXSZP[NZLWLSMQNNPLSKVKYL\\M^", + "EYETHVKWPWSVVTXQYNYLXKVKSLPNNQMTMYN\\P_", + "OUQOOQOSQUSUUSUQSOQO QPPQPSQTSTTSTQSPQP RQQRRSSRRQ", + "", + "D`DRJR ORUR ZR`R", + "D`DUDO`O`U", + "JZRDJR RDZR", + "D`DR`R JYZY P`T`", + "D`DR`R DRRb `RRb", + "", + "", + "", + "", + "", + "KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK", + "LXLLLXXXXLLL", + "KYRJKVYVRJ", + "LXRHLRR\\XRRH", + "JZRIPOJOOSMYRUWYUSZOTORI", + "KYRKRY KRYR", + "MWMMWW WMMW", + "MWRLRX MOWU WOMU", + "", + "", + "NVQNOONQNSOUQVSVUUVSVQUOSNQN OQOS PPPT QOQU RORU SOSU TPTT UQUS", + "NVNNNVVVVNNN OOOU POPU QOQU RORU SOSU TOTU UOUU", + "MWRLMUWURL ROOT ROUT RRQT RRST", + "LULRUWUMLR ORTU ORTO RRTS RRTQ", + "MWRXWOMORX RUUP RUOP RRSP RRQP", + "OXXROMOWXR URPO URPU RRPQ RRPS", + "LXRLNWXPLPVWRL RRRL RRLP RRNW RRVW RRXP", + "", + "", + "", + "MWRLRX OOUO MUOWQXSXUWWU", + "LXRLRX LQMOWOXQ PWTW", + "KYMNWX WNMX OLLOKQ ULXOYQ", + "I[NII[ VI[[ MM[[ WMI[ NIVI MMWM", + "I[RGRV MJWP WJMP IVL\\ [VX\\ IV[V L\\X\\", + "G[MJSV KPSL G\\[\\[RG\\", + "LXPLPPLPLTPTPXTXTTXTXPTPTLPL", + "KYYPXNVLSKQKNLLNKQKSLVNXQYSYVXXVYT YPWNUMSMQNPOOQOSPUQVSWUWWVYT", + "KYRJKVYVRJ RZYNKNRZ", + "G]PIPGQFSFTGTI GZHXJVKTLPLKMJOIUIWJXKXPYTZV\\X]Z GZ]Z QZP[Q\\S\\T[SZ", + "JZRMRS RSQ\\ RSS\\ Q\\S\\ RMQJPHNG QJNG RMSJTHVG SJVG RMNKLKJM PLLLJM RMVKXKZM TLXLZM RMPNOOOR RMPOOR RMTNUOUR RMTOUR", + "JZRIRK RNRP RSRU RYQ\\ RYS\\ Q\\S\\ RGQIPJ RGSITJ PJRITJ RKPNNOMN RKTNVOWN NOPORNTOVO RPPSNTLTKRKSLT RPTSVTXTYRYSXT NTPTRSTTVT RUPXOYMZLZKYJWJYLZ RUTXUYWZXZYYZWZYXZ MZOZRYUZWZ", + "JZRYQ\\ RYS\\ Q\\S\\ RYUZXZZXZUYTWTYRZOYMWLUMVJUHSGQGOHNJOMMLKMJOKRMTKTJUJXLZOZRY", + "JZRYQ\\ RYS\\ Q\\S\\ RYVXVVXUXRZQZLYIXHVHTGPGNHLHKIJLJQLRLUNVNXRY", + "I[IPKR LKNP RGRO XKVP [PYR", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "QSRQQRRSSRRQ", + "PTQPPQPSQTSTTSTQSPQP", + "NVQNOONQNSOUQVSVUUVSVQUOSNQN", + "MWQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM", + "KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK", + "G]PGMHJJHMGPGTHWJZM\\P]T]W\\ZZ\\W]T]P\\MZJWHTGPG", + "AcPALBJCGEEGCJBLAPATBXCZE]G_JaLbPcTcXbZa]__]aZbXcTcPbLaJ_G]EZCXBTAPA", + "fRAPCMDJDGCEA>H@JAMAZB]D_G`M`PaRc RATCWDZD]C_AfHdJcMcZb]`_]`W`TaRc", + "AcRAPCMDJDGCEABGAKAPBTDXG\\L`Rc RATCWDZD]C_AbGcKcPbT`X]\\X`Rc BHbH", + "H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX QMONMPLSLUMXOZQ[ LbXF", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "KYRKMX RNVX RKWX OTTT KXPX TXYX", + "JZNKNX OKOX LKSKVLWNVPSQ SKULVNUPSQ OQSQVRWTWUVWSXLX SQURVTVUUWSX", + "KYVLWKWOVLTKQKOLNMMPMSNVOWQXTXVWWU QKOMNPNSOVQX", + "JZNKNX OKOX LKSKVLWMXPXSWVVWSXLX SKULVMWPWSVVUWSX", + "JYNKNX OKOX SOSS LKVKVOUK OQSQ LXVXVTUX", + "JXNKNX OKOX SOSS LKVKVOUK OQSQ LXQX", + "K[VLWKWOVLTKQKOLNMMPMSNVOWQXTXVW QKOMNPNSOVQX TXUWVU VSVX WSWX TSYS", + "J[NKNX OKOX VKVX WKWX LKQK TKYK OQVQ LXQX TXYX", + "NWRKRX SKSX PKUK PXUX", + "LXSKSURWQX TKTUSWQXPXNWMUNTOUNV QKVK", + "JZNKNX OKOX WKOS QQVX RQWX LKQK TKYK LXQX TXYX", + "KXOKOX PKPX MKRK MXWXWTVX", + "I\\MKMX NNRX NKRU WKRX WKWX XKXX KKNK WKZK KXOX UXZX", + "JZNKNX OMVX OKVV VKVX LKOK TKXK LXPX", + "KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK QKOMNPNSOVQX TXVVWSWPVMTK", + "JYNKNX OKOX LKSKVLWNWOVQSROR SKULVNVOUQSR LXQX", + "KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK QKOMNPNSOVQX TXVVWSWPVMTK PWPUQTSTTUUZV[W[XZ TUUXVZW[", + "JZNKNX OKOX LKSKVLWNWOVQSROR SKULVNVOUQSR LXQX SRTSUWVXWXXW SRUSVWWX", + "KZVMWKWOVMULSKQKOLNMNOOPQQTRVSWT NNOOQPTQVRWSWVVWTXRXPWOVNTNXOV", + "KZRKRX SKSX NKMOMKXKXOWK PXUX", + "J[NKNUOWQXTXVWWUWK OKOUPWQX LKQK UKYK", + "KYMKRX NKRU WKRX KKPK TKYK", + "I[LKOX MKOT RKOX RKUX SKUT XKUX JKOK VKZK", + "KZNKVX OKWX WKNX LKQK TKYK LXQX TXYX", + "LYNKRRRX OKSR WKSRSX LKQK TKYK PXUX", + "LYVKNX WKOX OKNONKWK NXWXWTVX", + "KYRKMX RNVX RKWX OTTT KXPX TXYX", + "JZNKNX OKOX LKSKVLWNVPSQ SKULVNUPSQ OQSQVRWTWUVWSXLX SQURVTVUUWSX", + "KXOKOX PKPX MKWKWOVK MXRX", + "KYRKLX RMWX RKXX MWVW LXXX", + "JYNKNX OKOX SOSS LKVKVOUK OQSQ LXVXVTUX", + "LYVKNX WKOX OKNONKWK NXWXWTVX", + "J[NKNX OKOX VKVX WKWX LKQK TKYK OQVQ LXQX TXYX", + "KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK QKOMNPNSOVQX TXVVWSWPVMTK QOQT TOTT QQTQ QRTR", + "NWRKRX SKSX PKUK PXUX", + "JZNKNX OKOX WKOS QQVX RQWX LKQK TKYK LXQX TXYX", + "KYRKMX RNVX RKWX KXPX TXYX", + "I\\MKMX NNRX NKRU WKRX WKWX XKXX KKNK WKZK KXOX UXZX", + "JZNKNX OMVX OKVV VKVX LKOK TKXK LXPX", + "JZMJLM XJWM PPOS UPTS MVLY XVWY MKWK MLWL PQTQ PRTR MWWW MXWX", + "KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK QKOMNPNSOVQX TXVVWSWPVMTK", + "J[NKNX OKOX VKVX WKWX LKYK LXQX TXYX", + "JYNKNX OKOX LKSKVLWNWOVQSROR SKULVNVOUQSR LXQX", + "K[MKRQ NKSQMX MKWKXOVK NWWW MXWXXTVX", + "KZRKRX SKSX NKMOMKXKXOWK PXUX", + "KZMONLOKPKQLRORX XOWLVKUKTLSOSX MONMOLPLQMRO XOWMVLULTMSO PXUX", + "KZRKRX SKSX QNNOMQMRNTQUTUWTXRXQWOTNQN QNOONQNROTQU TUVTWRWQVOTN PKUK PXUX", + "KZNKVX OKWX WKNX LKQK TKYK LXQX TXYX", + "J[RKRX SKSX LPMONOOSQU TUVSWOXOYP MONROTQUTUVTWRXO PKUK PXUX", + "KZMVNXQXMRMONMOLQKTKVLWMXOXRTXWXXV OUNRNOOMQK TKVMWOWRVU NWPW UWWW", + "KYTKKX SMTX TKUX NTTT IXNX RXWX", + "JYPKLX QKMX NKUKWLWNVPSQ UKVLVNUPSQ OQRQTRUSUUTWQXJX RQTSTUSWQX", + "KXVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUU RKPMOONRNVPX", + "JYPKLX QKMX NKTKVLWNWQVTUVTWQXJX TKULVNVQUTTVSWQX", + "JYPKLX QKMX SORS NKXKWNWK OQRQ JXTXUUSX", + "JXPKLX QKMX SORS NKXKWNWK OQRQ JXOX", + "KYVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUVVS RKPMOONRNVPX RXTVUS SSXS", + "J[PKLX QKMX XKTX YKUX NKSK VK[K OQVQ JXOX RXWX", + "NWTKPX UKQX RKWK NXSX", + "LXUKRUQWPX VKSURWPXOXMWLUMTNUMV SKXK", + "JZPKLX QKMX YKOR RPTX SPUX NKSK VK[K JXOX RXWX", + "KXQKMX RKNX OKTK KXUXVUTX", + "I\\OKKX OMPX PKQV YKPX YKUX ZKVX MKPK YK\\K IXMX SXXX", + "JZPKLX PKTX QKTU XKTX NKQK VKZK JXNX", + "KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RKPMOONRNVPX RXTVUTVQVMTK", + "JYPKLX QKMX NKUKWLXMXOWQTROR UKWMWOVQTR JXOX", + "KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RKPMOONRNVPX RXTVUTVQVMTK OWOVPUQURVRZS[T[UZ RVSZT[", + "JZPKLX QKMX NKUKWLXMXOWQTROR UKWMWOVQTR SRTWUXVXWW SRTSUWVX JXOX", + "KZWLXLYKXNWLUKRKPLOMOOPPUSVT ONPOURVSVVUWSXPXNWMULXMWNW", + "KZTKPX UKQX PKNNOKZKYNYK NXSX", + "J[PKMUMWOXSXUWVUYK QKNUNWOX NKSK WK[K", + "KYOKPX PKQV YKPX MKRK VK[K", + "I[NKMX OKNV TKMX TKSX UKTV ZKSX LKQK XK\\K", + "KZPKTX QKUX YKLX NKSK VK[K JXOX RXWX", + "LYPKRQPX QKSQ YKSQQX NKSK VK[K NXSX", + "LYXKLX YKMX QKONPKYK LXUXVUTX", + "", + "", + "", + "", + "", + "", + "", + "KZMHX\\", + "JZRMLW RMXW", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "LZQOPPPQOQOPQOTOVQVWWXXX TOUQUWWX URRSPTOUOWPXSXTWUU RSPUPWQX", + "JYNKNX OKOX ORPPROTOVPWRWUVWTXRXPWOU TOUPVRVUUWTX LKOK", + "LXVQUQURVRVQUPSOQOOPNRNUOWQXSXUWVV QOPPOROUPWQX", + "L[VKVX WKWX VRUPSOQOOPNRNUOWQXSXUWVU QOPPOROUPWQX TKWK VXYX", + "LXOSVSVRUPSOQOOPNRNUOWQXSXUWVV USUQSO QOPPOROUPWQX", + "LWTKULUMVMVLTKRKPMPX RKQMQX NOSO NXSX", + "LYQOOQOSQUSUUSUQSOQO QOPQPSQU SUTSTQSO TPUOVO PTOUOXPYTYVZ OWPXTXVYV[T\\P\\N[NYPX", + "J[NKNX OKOX ORPPROTOVPWRWX TOUPVRVX LKOK LXQX TXYX", + "NWRKRLSLSKRK RORX SOSX POSO PXUX", + "NWSKSLTLTKSK SOSZR\\ TOTZR\\P\\O[OZPZP[O[ QOTO", + "JZNKNX OKOX WOOU RSVX SSWX LKOK TOYO LXQX TXYX", + "NWRKRX SKSX PKSK PXUX", + "F_JOJX KOKX KRLPNOPORPSRSX POQPRRRX SRTPVOXOZP[R[X XOYPZRZX HOKO HXMX PXUX XX]X", + "J[NONX OOOX ORPPROTOVPWRWX TOUPVRVX LOOO LXQX TXYX", + "LYQOOPNRNUOWQXTXVWWUWRVPTOQO QOPPOROUPWQX TXUWVUVRUPTO", + "JYNON\\ OOO\\ ORPPROTOVPWRWUVWTXRXPWOU TOUPVRVUUWTX LOOO L\\Q\\", + "KYUOU\\ VOV\\ URTPROPONPMRMUNWPXRXTWUU POOPNRNUOWPX S\\X\\", + "KXOOOX POPX PRQPSOUOVPVQUQUPVP MOPO MXRX", + "LYTOUPUQVQVPTOQOOPORQSTTVU OQQRTSVTVWTXQXOWOVPVPWQX", + "LWPKPVRXTXUWUV QKQVRX NOTO", + "J[NONUOWQXSXUWVU OOOUPWQX VOVX WOWX LOOO TOWO VXYX", + "KYNORX OORV VORX LOQO TOXO", + "I[LOOX MOOU ROOX ROUX SOUU XOUX JOOO VOZO", + "KYNOUX OOVX VONX LOQO TOXO LXPX SXXX", + "KYNORX OORV VORXP[N\\M\\L[LZMZM[L[ LOQO TOXO", + "LXUONX VOOX OONQNOVO NXVXVVUX", + "K[QOOPNQMSMUNWPXQXSWUUWRXO QOOQNSNUOWPX QOSOUPWWXX SOTPVWXXYX", + "KXRKPMOOMUK\\ QLPNNTL\\ RKTKVLVNUPRQ TKULUNTPRQ RQTRUTUVTWRXQXOWNT RQSRTTTVRX", + "KYLQNOPORPSSSXR\\ LQNPPPRQSS WOVRSXQ\\", + "KYSOQOOPNQMSMUNWPXRXTWUVVTVRUPRNQLQKRJTJUKVM QOOQNSNVPX RXTVUTUQSO QLRKTKVM", + "LXVPTOQOOPOQPRRS QOPPPQRS RSOTNUNWPXSXUW RSPTOUOWPX", + "LWRKQLQMSNVNVMSNPOOPNRNTOVPWRXSYS[R\\P\\O[ SNQOPPOROTPVRX", + "IYJRKPLONOOPOQMX MONPNQLX OQPPROTOVPVRS\\ TOUPURR\\", + "IYJSKQLPNPOQOVPX MPNQNUOWPXQXSWTVUTVQVNULTKRKQLQNRPURWS QXSVTTUQUNTK", + "NWROPVPWQXSXUWVU SOQVQWRX", + "KYOOLX POMX UOVPWPVOTORQOR ORPSRWTXVWWU ORQSSWTX", + "LXLKNKPLWX NKOLVX RPMX RPNX", + "KZOOK\\ POL\\ NUNWOXQXSWTV VOTVTWUXWXXWYU WOUVUWVX", + "JYNOMX OONUMX VRVOWOVRTUQWNXMX LOOO", + "MXRKQLQMSNVN TNQOPPPRRSUS TNROQPQRRS SSPTOUOWQXSYTZT[S\\Q\\ SSQTPUPWQX", + "KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO QOOQNSNVPX RXTVUTUQSO", + "IZPPMX PPNX TPSX TPTX KQMOXO KQMPXP", + "JXSOQOOPNQMSJ\\ QOOQNSK\\ SOUPVRVTUVTWRXPXNWMU SOUQUTTVRX", + "K[YOQOOPNQMSMUNWPXRXTWUVVTVRUPYP QOOQNSNVPX RXTVUTUQSO", + "KZSPQX SPRX MQOOXO MQOPXP", + "JXKRLPMOOOPPPROUOWPX NOOPORNUNWPXQXSWUUVRVOUOVP", + "KZOPNQMSMUNWPXRXUWWUXRXPWOUOTPSRRUO\\ MUNVPWRWUVWTXR XQWPUPSR RUQXP\\", + "KXMONOPPS[T\\ NOOPR[T\\U\\ VOTRNYL\\", + "I[TKQ\\ UKP\\ JRKPLONOOPOVPWSWUVWT MONPNTOWPXSXUWWTXRYO", + "JZNPPPPONPMQLSLUMWNXPXQWRUSR LUNWPWRU RRRWSXUXWVXTXRWPVOVPWP RUSWUWWV", + "KZVOTVTWUXWXXWYU WOUVUWVX USUQSOQOOPNQMSMUNWPXRXTV QOOQNSNVPX", + "JXOKMR PKNRNVPX NROPQOSOUPVRVTUVTWRXPXNWMUMR SOUQUTTVRX MKPK", + "KXUPUQVQUPSOQOOPNQMSMUNWPXRXTWUV QOOQNSNVPX", + "KZWKTVTWUXWXXWYU XKUVUWVX USUQSOQOOPNQMSMUNWPXRXTV QOOQNSNVPX UKXK", + "KWNURTTSURUPSOQOOPNQMSMUNWPXRXTWUV QOOQNSNVPX", + "MXWKXLXKVKTLSNPYO[N\\ VKULTNQYP[N\\L\\L[M\\ POVO", + "KYVOTVSYR[ WOUVTYR[P\\M\\L[M[N\\ USUQSOQOOPNQMSMUNWPXRXTV QOOQNSNVPX", + "KZPKLX QKMX OQPPROTOVPVRUUUWVX TOUPURTUTWUXWXXWYU NKQK", + "MWSKSLTLTKSK NROPPOROSPSRRURWSX QORPRRQUQWRXTXUWVU", + "MWTKTLULUKTK ORPPQOSOTPTRRYQ[O\\M\\M[N\\ ROSPSRQYP[O\\", + "KXPKLX QKMX VPUQVQVPUOTORQPROR ORPSQWRXTXUWVU ORQSRWSX NKQK", + "NVSKPVPWQXSXTWUU TKQVQWRX QKTK", + "F^GRHPIOKOLPLQJX JOKPKQIX LQMPOOQOSPSQQX QORPRQPX SQTPVOXOZPZRYUYWZX XOYPYRXUXWYX[X\\W]U", + "J[KRLPMOOOPPPQNX NOOPOQMX PQQPSOUOWPWRVUVWWX UOVPVRUUUWVXXXYWZU", + "KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO QOOQNSNVPX RXTVUTUQSO", + "JYKRLPMOOOPPPQM\\ NOOPOQL\\ PQROTOVPWRWTVVUWSXQXOVOT TOVQVTUVSX J\\O\\", + "KYVOR\\ WOS\\ USUQSOQOOPNQMSMUNWPXRXTV QOOQNSNVPX P\\U\\", + "LXMRNPOOQORPRQPX POQPQQOX RQSPUOVOWPWQVQWP", + "LYVPVQWQVPTOQOOPORQSTTVU OQQRTSVTVWTXQXOWNVOVOW", + "NWSKPVPWQXSXTWUU TKQVQWRX POUO", + "IZJRKPLONOOPORNUNWOX MONPNRMUMWOXQXSWTV VOTVTWUXWXXWYU WOUVUWVX", + "JXKRLPMOOOPPPROUOWPX NOOPORNUNWPXQXSWUUVRVOUOVP", + "H\\IRJPKOMONPNRMUMWNX LOMPMRLULWNXOXQWRV TORVRWTX UOSVSWTXUXWWYUZRZOYOZP", + "JZMRNPPOROSPSR QORPRRQUPWNXMXLWLVMVLW XPWQXQXPWOVOTPSRRURWSX QUQWRXTXVWWU", + "IYJRKPLONOOPORNUNWOX MONPNRMUMWOXQXSWTV VOTVSYR[ WOUVTYR[P\\M\\L[M[N\\", + "KYWOWPVQNVMWMX NQOOROUQ OPRPUQVQ NVOVRWUW OVRXUXVV", + "H[RKSLSMTMTLRKOKMLLNLX OKNLMNMX XKYLYMZMZLXKVKTMTX VKUMUX JOWO JXOX RXWX", + "J[UKVLWLWKQKOLNNNX QKPLONOX VOVX WOWX LOWO LXQX TXYX", + "J[WKQKOLNNNX QKPLONOX UKVLVX WKWX LOVO LXQX TXYX", + "F_PKQLQMRMRLPKMKKLJNJX MKLLKNKX YKZL[L[KUKSLRNRX UKTLSNSX ZOZX [O[X HO[O HXMX PXUX XX]X", + "F_PKQLQMRMRLPKMKKLJNJX MKLLKNKX [KUKSLRNRX UKTLSNSX YKZLZX [K[X HOZO HXMX PXUX XX]X", + "NWRORX SOSX POSO PXUX", + "", + "LXVPTOROPPOQNSNUOWQXSXUW ROPQOSOVQX OSSS", + "LYSKQLPMOONRNUOWPXRXTWUVVTWQWNVLUKSK SKQMPOOSOVPX RXTVUTVPVMUK OQVQ", + "KZTKQ\\ UKP\\ QONPMRMUNWQXTXWWXUXRWPTOQO QOOPNRNUOWQX TXVWWUWRVPTO", + "LXUPVRVQUPSOQOOPNRNTOVRX QOOQOTPVRXSYS[R\\P\\", + "", + "", + "", + "I[VKWLXLVKSKQLPMOOLYK[J\\ SKQMPOMYL[J\\H\\H[I\\ ZK[L[KYKWLVNSYR[Q\\ YKXLWNTYS[Q\\O\\O[P\\ LOYO", + "IZVKWLXLXKSKQLPMOOLYK[J\\ SKQMPOMYL[J\\H\\H[I\\ VOTVTWUXWXXWYU WOUVUWVX LOWO", + "IZVKWL XKSKQLPMOOLYK[J\\ SKQMPOMYL[J\\H\\H[I\\ WKTVTWUXWXXWYU XKUVUWVX LOVO", + "F^SKTLTM ULSKPKNLMMLOIYH[G\\ PKNMMOJYI[G\\E\\E[F\\ ZK[L\\L\\KWKUL TMSOPYO[N\\ WKUMTOQYP[N\\L\\L[M\\ ZOXVXWYX[X\\W]U [OYVYWZX IO[O", + "F^SKTLTM ULSKPKNLMMLOIYH[G\\ PKNMMOJYI[G\\E\\E[F\\ ZK[L \\KWKUL TMSOPYO[N\\ WKUMTOQYP[N\\L\\L[M\\ [KXVXWYX[X\\W]U \\KYVYWZX IOZO", + "MWNROPPOROSPSRRURWSX QORPRRQUQWRXTXUWVU", + "", + "OU", + "LX", + "LYQKOLNONTOWQXTXVWWTWOVLTKQK QKPLOOOTPWQX TXUWVTVOULTK", + "LYPNSKSX RLRX OXVX", + "LYOMONNNNMOLQKTKVLWNVPTQQROSNUNX TKULVNUPTQ NWOVPVSWVWWV PVSXVXWVWU", + "LYOMONNNNMOLQKTKVLWNVPTQ TKULVNUPTQ RQTQVRWTWUVWTXQXOWNVNUOUOV TQURVTVUUWTX", + "LYSMSX TKTX TKMTXT QXVX", + "LYOKNQ OKVK OLSLVK NQOPQOTOVPWRWUVWTXQXOWNVNUOUOV TOUPVRVUUWTX", + "LYVMVNWNWMVLTKRKPLOMNPNUOWQXTXVWWUWSVQTPQPNR RKPMOPOUPWQX TXUWVUVSUQTP", + "LYNKNO VMRTPX WKTQQX NMPKRKUM NMPLRLUMVM", + "LYQKOLNNOPQQTQVPWNVLTKQK QKPLONPPQQ TQUPVNULTK QQORNTNUOWQXTXVWWUWTVRTQ QQPROTOUPWQX TXUWVUVTURTQ", + "LYOVOUNUNVOWQXSXUWVVWSWNVLTKQKOLNNNPORQSTSWQ SXUVVSVNULTK QKPLONOPPRQS", + "NVRVQWRXSWRV", + "NVSWRXQWRVSWSYQ[", + "NVROQPRQSPRO RVQWRXSWRV", + "NVROQPRQSPRO SWRXQWRVSWSYQ[", + "NVRKQLRSSLRK RLRO RVQWRXSWRV", + "LYNNONOONONNOLQKTKVLWNWOVQSRRSRTST TKVMVPUQSR RWRXSXSWRW", + "OVRKRP SKRP", + "LXOKOP PKOP UKUP VKUP", + "MWQKPLPNQOSOTNTLSKQK", + "MWRJRP OKUO UKOO", + "KZXHM\\", + "MWUHSJQMPPPTQWSZU\\ SJRLQPQTRXSZ", + "MWOHQJSMTPTTSWQZO\\ QJRLSPSTRXQZ", + "MWPHP\\ QHQ\\ PHUH P\\U\\", + "MWSHS\\ THT\\ OHTH O\\T\\", + "LWSHRIQKQMRORPPRRTRUQWQYR[S\\ RIQM QKRO RUQY QWR[", + "MXQHRISKSMRORPTRRTRUSWSYR[Q\\ RISM SKRO RUSY SWR[", + "MWTHPRT\\", + "MWPHTRP\\", + "OURHR\\", + "MWPHP\\ THT\\", + "I[LRXR", + "I[RLRX LRXR", + "JZRMRX MRWR MXWX", + "JZRMRX MMWM MRWR", + "JZMMWW WMMW", + "NVRQQRRSSRRQ", + "I[RLQMRNSMRL LRXR RVQWRXSWRV", + "I[LPXP LTXT", + "I[WLMX LPXP LTXT", + "I[LNXN LRXR LVXV", + "JZWLMRWX", + "JZMLWRMX", + "JZWKMOWS MTWT MXWX", + "JZMKWOMS MTWT MXWX", + "H[YUWUUTTSRPQOONNNLOKQKRLTNUOUQTRSTPUOWNYN", + "JZLTLRMPOPUSWSXR LRMQOQUTWTXRXP", + "JZMSRPWS MSRQWS", + "NVSKPO SKTLPO", + "NVQKTO QKPLTO", + "LXNKOMQNSNUMVK NKONQOSOUNVK", + "NVSLRMQLRKSLSNQP", + "NVSKQMQORPSORNQO", + "NVQLRMSLRKQLQNSP", + "NVQKSMSORPQORNSO", + "", + "JZWMQMONNOMQMSNUOVQWWW", + "JZMMMSNUOVQWSWUVVUWSWM", + "JZMMSMUNVOWQWSVUUVSWMW", + "JZMWMQNOONQMSMUNVOWQWW", + "JZWMQMONNOMQMSNUOVQWWW MRUR", + "I[TOUPXRUTTU UPWRUT LRWR", + "MWRMRX OPPORLTOUP PORMTO", + "I[POOPLROTPU OPMROT MRXR", + "MWRLRW OTPURXTUUT PURWTU", + "KYVSUPSOQOOPNQMSMUNWPXRXTWUVVTWQWNVLTKQKPLQLRK QOOQNSNVPX RXTVUTVQVNULTK", + "JZLKRX MKRV XKRX LKXK NLWL", + "G[IOLORW KORX [FRX", + "I[XIXJYJYIXHVHTJSLROQUPYO[ UITKSORUQXPZN\\L\\K[KZLZL[", + "I[XIXJYJYIXHVHTJSLROQUPYO[ UITKSORUQXPZN\\L\\K[KZLZL[ QNOONQNSOUQVSVUUVSVQUOSNQN", + "H\\ZRYTWUVUTTSSQPPONNMNKOJQJRKTMUNUPTQSSPTOVNWNYOZQZR", + "JZXKLX OKPLPNOOMOLNLLMKOKSLVLXK UTTUTWUXWXXWXUWTUT", + "J[YPXPXQYQYPXOWOVPUTTVSWQXOXMWLVLTMSORRPSNSLRKPKOLONPQUWWXXXYW OXMVMTOR ONPPVWWX", + "J[UPSOQOPQPRQTSTUS UOUSVTXTYRYQXNVLSKRKOLMNLQLRMUOWRXSXVW", + "KZQHQ\\ THT\\ WLVLVMWMWLUKPKNLNNOPVSWT NNOOVRWTWVVWTXQXOWNVNUOUOVNV", + "KYPKP[ TKT[ MQWQ MUWU", + "LXTLSLSMTMTLSKQKPLPNQPTRUS PNQOTQUSUUSW QPOROTPVSXTY OTPUSWTYT[S\\Q\\P[PZQZQ[P[", + "LXRKQLRMSLRK RMRQ RQQSRVSSRQ RVR\\ POONNOOPPOTOUNVOUPTO", + "LXRMSLRKQLRMRQQRSURV RQSRQURVRZQ[R\\S[RZ POONNOOPPOTOUNVOUPTO PXOWNXOYPXTXUWVXUYTX", + "LYVKVX NKVK QQVQ NXVX", + "", + "H\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RQQRRSSRRQ", + "LYQKPLPMQN TKULUMTN RNPOOQORPTRUSUUTVRVQUOSNRN RURY SUSY OWVW", + "LYRKPLONOOPQRRSRUQVOVNULSKRK RRRX SRSX OUVU", + "H\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RKRY KRYR", + "JYRRPQOQMRLTLUMWOXPXRWSUSTRR WMRR RMWMWR RMVNWR", + "JZLLMKOKQLRNRPQRPSNT OKPLQNQQPS VKUX WKTX NTXT", + "JYNKNU OKNR NROPQOSOUPVQVTTVTXUYVYWX SOUQUTTV LKOK", + "LYONRKRQ VNSKSQ RQPROTOUPWRXSXUWVUVTURSQ RTRUSUSTRT", + "JZRKRY MKMPNRPSTSVRWPWK LMMKNM QMRKSM VMWKXM OVUV", + "JYNKNX OKOX LKSKVLWNWOVQSROR SKULVNVOUQSR LXVXVUUX", + "LYWKTKQLONNQNSOVQXTYWY WKTLRNQQQSRVTXWY", + "JZRRPQOQMRLTLUMWOXPXRWSUSTRR SLQQ WMRR XQSS", + "KYPMTW TMPW MPWT WPMT", + "J[OUMULVLXMYOYPXPVNTMRMONMOLQKTKVLWMXOXRWTUVUXVYXYYXYVXUVU NMPLULWM", + "J[OOMOLNLLMKOKPLPNNPMRMUNWOXQYTYVXWWXUXRWPUNULVKXKYLYNXOVO NWPXUXWW", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "F^KHK\\ LHL\\ XHX\\ YHY\\ HH\\H H\\O\\ U\\\\\\", + "H]KHRQJ\\ JHQQ JHYHZMXH K[X[ J\\Y\\ZWX\\", + "KYVBTDRGPKOPOTPYR]T`Vb TDRHQKPPPTQYR\\T`", + "KYNBPDRGTKUPUTTYR]P`Nb PDRHSKTPTTSYR\\P`", + "KYOBOb PBPb OBVB ObVb", + "KYTBTb UBUb NBUB NbUb", + "JYTBQEPHPJQMSOSPORSTSUQWPZP\\Q_Tb RDQGQKRN RVQYQ]R`", + "KZPBSETHTJSMQOQPURQTQUSWTZT\\S_Pb RDSGSKRN RVSYS]R`", + "KYU@RCPFOIOLPOSVTYT\\S_Ra RCQEPHPKQNTUUXU[T^RaOd", + "KYO@RCTFUIULTOQVPYP\\Q_Ra RCSETHTKSNPUOXO[P^RaUd", + "AXCRGRR` GSRa FSRb X:Rb", + "F^[CZD[E\\D\\C[BYBWCUETGSJRNPZO^N` VDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "H\\RFK[ RFY[ RIX[ MUVU I[O[ U[[[", + "G]LFL[ MFM[ IFUFXGYHZJZLYNXOUP UFWGXHYJYLXNWOUP MPUPXQYRZTZWYYXZU[I[ UPWQXRYTYWXYWZU[", + "G\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV QFOGMILKKNKSLVMXOZQ[", + "G]LFL[ MFM[ IFSFVGXIYKZNZSYVXXVZS[I[ SFUGWIXKYNYSXVWXUZS[", + "G\\LFL[ MFM[ SLST IFYFYLXF MPSP I[Y[YUX[", + "G[LFL[ MFM[ SLST IFYFYLXF MPSP I[P[", + "G^XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXX QFOGMILKKNKSLVMXOZQ[ XSX[ YSY[ US\\S", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F LPXP H[O[ U[\\[", + "MXRFR[ SFS[ OFVF O[V[", + "KZUFUWTZR[P[NZMXMVNUOVNW TFTWSZR[ QFXF", + "F\\KFK[ LFL[ YFLS QOY[ POX[ HFOF UF[F H[O[ U[[[", + "I[NFN[ OFO[ KFRF K[Z[ZUY[", + "F_KFK[ LFRX KFR[ YFR[ YFY[ ZFZ[ HFLF YF]F H[N[ V[][", + "G^LFL[ MFYY MHY[ YFY[ IFMF VF\\F I[O[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF QFOGMILKKOKRLVMXOZQ[ S[UZWXXVYRYOXKWIUGSF", + "G]LFL[ MFM[ IFUFXGYHZJZMYOXPUQMQ UFWGXHYJYMXOWPUQ I[P[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF QFOGMILKKOKRLVMXOZQ[ S[UZWXXVYRYOXKWIUGSF NYNXOVQURUTVUXV_W`Y`Z^Z] UXV\\W^X_Y_Z^", + "G]LFL[ MFM[ IFUFXGYHZJZLYNXOUPMP UFWGXHYJYLXNWOUP I[P[ RPTQURXYYZZZ[Y TQUSWZX[Z[[Y[X", + "H\\XIYFYLXIVGSFPFMGKIKKLMMNOOUQWRYT KKMMONUPWQXRYTYXWZT[Q[NZLXKUK[LX", + "I\\RFR[ SFS[ LFKLKFZFZLYF O[V[", + "F^KFKULXNZQ[S[VZXXYUYF LFLUMXOZQ[ HFOF VF\\F", + "H\\KFR[ LFRX YFR[ IFOF UF[F", + "F^JFN[ KFNV RFN[ RFV[ SFVV ZFV[ GFNF WF]F", + "H\\KFX[ LFY[ YFK[ IFOF UF[F I[O[ U[[[", + "H]KFRQR[ LFSQS[ ZFSQ IFOF VF\\F O[V[", + "H\\XFK[ YFL[ LFKLKFYF K[Y[YUX[", + "H\\RFK[ RFY[ RIX[ MUVU I[O[ U[[[", + "G]LFL[ MFM[ IFUFXGYHZJZLYNXOUP UFWGXHYJYLXNWOUP MPUPXQYRZTZWYYXZU[I[ UPWQXRYTYWXYWZU[", + "I[NFN[ OFO[ KFZFZLYF K[R[", + "H\\RFJ[ RFZ[ RIY[ KZYZ J[Z[", + "G\\LFL[ MFM[ SLST IFYFYLXF MPSP I[Y[YUX[", + "H\\XFK[ YFL[ LFKLKFYF K[Y[YUX[", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F LPXP H[O[ U[\\[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF QFOGMILKKOKRLVMXOZQ[ S[UZWXXVYRYOXKWIUGSF OMOT UMUT OPUP OQUQ", + "MXRFR[ SFS[ OFVF O[V[", + "F\\KFK[ LFL[ YFLS QOY[ POX[ HFOF UF[F H[O[ U[[[", + "H\\RFK[ RFY[ RIX[ I[O[ U[[[", + "F_KFK[ LFRX KFR[ YFR[ YFY[ ZFZ[ HFLF YF]F H[N[ V[][", + "G^LFL[ MFYY MHY[ YFY[ IFMF VF\\F I[O[", + "G]KEJJ ZEYJ ONNS VNUS KWJ\\ ZWY\\ KGYG KHYH OPUP OQUQ KYYY KZYZ", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF QFOGMILKKOKRLVMXOZQ[ S[UZWXXVYRYOXKWIUGSF", + "F^KFK[ LFL[ XFX[ YFY[ HF\\F H[O[ U[\\[", + "G]LFL[ MFM[ IFUFXGYHZJZMYOXPUQMQ UFWGXHYJYMXOWPUQ I[P[", + "H]KFRPJ[ JFQP JFYFZLXF KZXZ J[Y[ZUX[", + "I\\RFR[ SFS[ LFKLKFZFZLYF O[V[", + "I\\KKKILGMFOFPGQIRMR[ KIMGOGQI ZKZIYGXFVFUGTISMS[ ZIXGVGTI O[V[", + "H]RFR[ SFS[ PKMLLMKOKRLTMUPVUVXUYTZRZOYMXLUKPK PKNLMMLOLRMTNUPV UVWUXTYRYOXMWLUK OFVF O[V[", + "H\\KFX[ LFY[ YFK[ IFOF UF[F I[O[ U[[[", + "G^RFR[ SFS[ IMJLLMMQNSOTQU JLKMLQMSNTQUTUWTXSYQZM[L TUVTWSXQYM[L\\M OFVF O[V[", + "G]JXK[O[MWKSJPJLKIMGPFTFWGYIZLZPYSWWU[Y[ZX MWLTKPKLLINGPF TFVGXIYLYPXTWW KZNZ VZYZ", + "H\\UFH[ UFV[ THU[ LUUU F[L[ R[X[", + "F^OFI[ PFJ[ LFWFZG[I[KZNYOVP WFYGZIZKYNXOVP MPVPXQYSYUXXVZR[F[ VPWQXSXUWXUZR[", + "H]ZH[H\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV TFRGPINLMOLSLVMYNZP[", + "F]OFI[ PFJ[ LFUFXGYHZKZOYSWWUYSZO[F[ UFWGXHYKYOXSVWTYRZO[", + "F]OFI[ PFJ[ TLRT LF[FZLZF MPSP F[U[WVT[", + "F\\OFI[ PFJ[ TLRT LF[FZLZF MPSP F[M[", + "H^ZH[H\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT TFRGPINLMOLSLVMYNZP[ R[TZVXXT UT\\T", + "E_NFH[ OFI[ [FU[ \\FV[ KFRF XF_F LPXP E[L[ R[Y[", + "LYUFO[ VFP[ RFYF L[S[", + "I[XFSWRYQZO[M[KZJXJVKULVKW WFRWQYO[ TF[F", + "F]OFI[ PFJ[ ]FLS SOW[ ROV[ LFSF YF_F F[M[ S[Y[", + "H\\QFK[ RFL[ NFUF H[W[YUV[", + "E`NFH[ NFO[ OFPY \\FO[ \\FV[ ]FW[ KFOF \\F`F E[K[ S[Z[", + "F_OFI[ OFVX OIV[ \\FV[ LFOF YF_F F[L[", + "G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF SFQGOIMLLOKSKVLYN[ Q[SZUXWUXRYNYKXHVF", + "F]OFI[ PFJ[ LFXF[G\\I\\K[NYPUQMQ XFZG[I[KZNXPUQ F[M[", + "G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF SFQGOIMLLOKSKVLYN[ Q[SZUXWUXRYNYKXHVF LYLXMVOUPURVSXS_T`V`W^W] SXT^U_V_W^", + "F^OFI[ PFJ[ LFWFZG[I[KZNYOVPMP WFYGZIZKYNXOVP RPTQURVZW[Y[ZYZX URWYXZYZZY F[M[", + "G^ZH[H\\F[L[JZHYGVFRFOGMIMKNMONVRXT MKOMVQWRXTXWWYVZS[O[LZKYJWJUI[JYKY", + "H]UFO[ VFP[ OFLLNF]F\\L\\F L[S[", + "F_NFKQJUJXKZN[R[UZWXXU\\F OFLQKUKXLZN[ KFRF YF_F", + "H\\NFO[ OFPY \\FO[ LFRF XF^F", + "E_MFK[ NFLY UFK[ UFS[ VFTY ]FS[ JFQF ZF`F", + "G]NFU[ OFV[ \\FH[ LFRF XF^F F[L[ R[X[", + "H]NFRPO[ OFSPP[ ]FSP LFRF YF_F L[S[", + "G][FH[ \\FI[ OFLLNF\\F H[V[XUU[", + "H\\KILKXWYYY[ LLXX KIKKLMXYY[ PPLTKVKXLZK[ KVMZ LTLVMXMZK[ SSXN VIVLWNYNYLWKVI VIWLYN", + "H\\QIK[ SIY[ RIX[ MUVU I[O[ U[[[ QBOCNENGOIQJSJUIVGVEUCSBQB", + "", + "", + "", + "", + "", + "G]IB[b", + "F^RJIZ RJ[Z", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "I]NONPMPMONNPMTMVNWOXQXXYZZ[ WOWXXZZ[[[ WQVRPSMTLVLXMZP[S[UZWX PSNTMVMXNZP[", + "G\\LFL[ MFM[ MPONQMSMVNXPYSYUXXVZS[Q[OZMX SMUNWPXSXUWXUZS[ IFMF", + "H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX QMONMPLSLUMXOZQ[", + "H]WFW[ XFX[ WPUNSMQMNNLPKSKULXNZQ[S[UZWX QMONMPLSLUMXOZQ[ TFXF W[[[", + "H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX WSWPVN QMONMPLSLUMXOZQ[", + "KXUGTHUIVHVGUFSFQGPIP[ SFRGQIQ[ MMUM M[T[", + "I\\QMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM ONNPNTOV UVVTVPUN VOWNYMYNWN NUMVLXLYM[P\\U\\X]Y^ LYMZP[U[X\\Y^Y_XaUbObLaK_K^L\\O[", + "G]LFL[ MFM[ MPONRMTMWNXPX[ TMVNWPW[ IFMF I[P[ T[[[", + "MXRFQGRHSGRF RMR[ SMS[ OMSM O[V[", + "MXSFRGSHTGSF TMT_SaQbObNaN`O_P`Oa SMS_RaQb PMTM", + "G\\LFL[ MFM[ WMMW RSX[ QSW[ IFMF TMZM I[P[ T[Z[", + "MXRFR[ SFS[ OFSF O[V[", + "BcGMG[ HMH[ HPJNMMOMRNSPS[ OMQNRPR[ SPUNXMZM]N^P^[ ZM\\N]P][ DMHM D[K[ O[V[ Z[a[", + "G]LML[ MMM[ MPONRMTMWNXPX[ TMVNWPW[ IMMM I[P[ T[[[", + "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM QMONMPLSLUMXOZQ[ S[UZWXXUXSWPUNSM", + "G\\LMLb MMMb MPONQMSMVNXPYSYUXXVZS[Q[OZMX SMUNWPXSXUWXUZS[ IMMM IbPb", + "H\\WMWb XMXb WPUNSMQMNNLPKSKULXNZQ[S[UZWX QMONMPLSLUMXOZQ[ Tb[b", + "IZNMN[ OMO[ OSPPRNTMWMXNXOWPVOWN KMOM K[R[", + "J[WOXMXQWOVNTMPMNNMOMQNRPSUUWVXW MPNQPRUTWUXVXYWZU[Q[OZNYMWM[NY", + "KZPFPWQZS[U[WZXX QFQWRZS[ MMUM", + "G]LMLXMZP[R[UZWX MMMXNZP[ WMW[ XMX[ IMMM TMXM W[[[", + "I[LMR[ MMRY XMR[ JMPM TMZM", + "F^JMN[ KMNX RMN[ RMV[ SMVX ZMV[ GMNM WM]M", + "H\\LMW[ MMX[ XML[ JMPM TMZM J[P[ T[Z[", + "H[LMR[ MMRY XMR[P_NaLbKbJaK`La JMPM TMZM", + "I[WML[ XMM[ MMLQLMXM L[X[XWW[", + "G^QMNNLPKRJUJXKZN[P[RZUWWTYPZM QMONMPLRKUKXLZN[ QMSMUNVPXXYZZ[ SMTNUPWXXZZ[[[", + "G\\TFQGOIMMLPKTJZIb TFRGPINMMPLTKZJb TFVFXGYHYKXMWNTOPO VFXHXKWMVNTO POTPVRWTWWVYUZR[P[NZMYLV POSPURVTVWUYTZR[", + "H\\IPKNMMOMQNROSRSVRZOb JOLNPNRO ZMYPXRSYP^Nb YMXPWRSY", + "I\\VNTMRMONMQLTLWMYNZP[R[UZWWXTXQWOSJRHRFSEUEWFYH RMPNNQMTMXNZ R[TZVWWTWPVNTKSISGTFVFYH", + "I[XPVNTMPMNNNPPRSS PMONOPQRSS SSNTLVLXMZP[S[UZWX SSOTMVMXNZP[", + "I[TFRGQHQIRJUKZKZJWKSMPOMRLULWMYP[S]T_TaSbQbPa ULQONRMUMWNYP[", + "G]HQIOKMNMONOPNTL[ MMNNNPMTK[ NTPPRNTMVMXNYOYRXWUb VMXOXRWWTb", + "F]GQHOJMMMNNNPMUMXNZO[ LMMNMPLULXMZO[Q[SZUXWUXRYMYIXGVFTFRHRJSMUPWRZT SZUWVUWRXMXIWGVF", + "LXRMPTOXOZP[S[UYVW SMQTPXPZQ[", + "H\\NMJ[ OMK[ XMYNZNYMWMUNQROSMS OSQTSZT[ OSPTRZS[U[WZYW", + "H\\KFMFOGPHQJWXXZY[ MFOHPJVXWZY[Z[ RMJ[ RMK[", + "F]MMGb NMHb MPLVLYN[P[RZTXVU XMUXUZV[Y[[Y\\W YMVXVZW[", + "H\\NML[ OMNSMXL[ YMXQVU ZMYPXRVUTWQYOZL[ KMOM", + "IZTFRGQHQIRJUKXK UKQLOMNONQPSSTVT UKRLPMOOOQQSST STOUMVLXLZN\\S^T_TaRbPb STPUNVMXMZO\\S^", + "I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RMPNNQMTMXNZ R[TZVWWTWPVN", + "G]PNL[ PNM[ VNV[ VNW[ IPKNNM[M IPKONN[N", + "H[LVMYNZP[R[UZWWXTXQWOVNTMRMONMQLTHb R[TZVWWTWPVN RMPNNQMTIb", + "H][MQMNNLQKTKWLYMZO[Q[TZVWWTWQVOUNSM QMONMQLTLXMZ Q[SZUWVTVPUN UN[N", + "H\\SNP[ SNQ[ JPLNOMZM JPLOONZN", + "H\\IQJOLMOMPNPPNVNYP[ NMONOPMVMYNZP[Q[TZVXXUYRYOXMWNXOYR XUYO", + "G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb JWLYNZQZTYWWYU ZOXNVNTPRSPYNb", + "I[KMMMONPPU_VaWb MMNNOPT_UaWbYb ZMYOWRM]K`Jb", + "F]UFOb VFNb GQHOJMMMNNNPMUMXOZRZTYWVYS LMMNMPLULXMZO[R[TZVXXUYS[M", + "F]JQLOONNMLNJQITIWJZK[M[OZQWRT IWJYKZMZOYQW QTQWRZS[U[WZYWZTZQYNXMWNYOZQ QWRYSZUZWYYW", + "H]XMVTUXUZV[Y[[Y\\W YMWTVXVZW[ VTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT QMONMQLTLXMZ", + "H[PFLSLVMYNZ QFMS MSNPPNRMTMVNWOXQXTWWUZR[P[NZMWMS VNWPWTVWTZR[ MFQF", + "I[WPWQXQXPWNUMRMONMQLTLWMYNZP[R[UZWW RMPNNQMTMXNZ", + "H]ZFVTUXUZV[Y[[Y\\W [FWTVXVZW[ VTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT QMONMQLTLXMZ WF[F", + "I[MVQUTTWRXPWNUMRMONMQLTLWMYNZP[R[UZWX RMPNNQMTMXNZ", + "KZZGYHZI[H[GZFXFVGUHTJSMP[O_Na XFVHUJTNRWQ[P^O`NaLbJbIaI`J_K`Ja OMYM", + "H\\YMU[T^RaObLbJaI`I_J^K_J` XMT[S^QaOb VTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT QMONMQLTLXMZ", + "H]PFJ[ QFK[ MTOPQNSMUMWNXOXQVWVZW[ UMWOWQUWUZV[Y[[Y\\W MFQF", + "LYUFTGUHVGUF MQNOPMSMTNTQRWRZS[ RMSNSQQWQZR[U[WYXW", + "LYVFUGVHWGVF NQOOQMTMUNUQR[Q^P`OaMbKbJaJ`K_L`Ka SMTNTQQ[P^O`Mb", + "H\\PFJ[ QFK[ XNWOXPYOYNXMWMUNQROSMS OSQTSZT[ OSPTRZS[U[WZYW MFQF", + "MYUFQTPXPZQ[T[VYWW VFRTQXQZR[ RFVF", + "AbBQCOEMHMINIPHTF[ GMHNHPGTE[ HTJPLNNMPMRNSOSQP[ PMRORQO[ RTTPVNXMZM\\N]O]Q[W[Z\\[ ZM\\O\\QZWZZ[[^[`YaW", + "F]GQHOJMMMNNNPMTK[ LMMNMPLTJ[ MTOPQNSMUMWNXOXQVWVZW[ UMWOWQUWUZV[Y[[Y\\W", + "I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RMPNNQMTMXNZ R[TZVWWTWPVN", + "G\\HQIOKMNMONOPNTJb MMNNNPMTIb NTOQQNSMUMWNXOYQYTXWVZS[Q[OZNWNT WNXPXTWWUZS[ FbMb", + "H\\XMRb YMSb VTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT QMONMQLTLXMZ ObVb", + "IZJQKOMMPMQNQPPTN[ OMPNPPOTM[ PTRPTNVMXMYNYOXPWOXN", + "J[XOXPYPYOXNUMRMONNONQORVVWW NPOQVUWVWYVZS[P[MZLYLXMXMY", + "KYTFPTOXOZP[S[UYVW UFQTPXPZQ[ NMWM", + "F]GQHOJMMMNNNQLWLYN[ LMMNMQKWKYLZN[P[RZTXVT XMVTUXUZV[Y[[Y\\W YMWTVXVZW[", + "H\\IQJOLMOMPNPQNWNYP[ NMONOQMWMYNZP[Q[TZVXXUYQYMXMYO", + "C`DQEOGMJMKNKQIWIYK[ IMJNJQHWHYIZK[M[OZQXRV TMRVRYSZU[W[YZ[X\\V]R]M\\M]O UMSVSYU[", + "H\\KQMNOMRMSOSR QMRORRQVPXNZL[K[JZJYKXLYKZ QVQYR[U[WZYW YNXOYPZOZNYMXMVNTPSRRVRYS[", + "G\\HQIOKMNMONOQMWMYO[ MMNNNQLWLYMZO[Q[SZUXWT ZMV[U^SaPbMbKaJ`J_K^L_K` YMU[T^RaPb", + "H\\YMXOVQNWLYK[ LQMOOMRMVO MOONRNVOXO LYNYRZUZWY NYR[U[WYXW", + "G^VGUHVIWHWGUFRFOGMILLL[ RFPGNIMLM[ \\G[H\\I]H]G\\FZFXGWIW[ ZFYGXIX[ IM[M I[P[ T[[[", + "G]WGVHWIXHWGUFRFOGMILLL[ RFPGNIMLM[ WMW[ XMX[ IMXM I[P[ T[[[", + "G]VGUHVIWHWGUF XFRFOGMILLL[ RFPGNIMLM[ WHW[ XFX[ IMWM I[P[ T[[[", + "BcRGQHRISHRGPFMFJGHIGLG[ MFKGIIHLH[ ]G\\H]I^H]G[FXFUGSIRLR[ XFVGTISLS[ ]M][ ^M^[ DM^M D[K[ O[V[ Z[a[", + "BcRGQHRISHRGPFMFJGHIGLG[ MFKGIIHLH[ \\G[H\\I]H]G[F ^FXFUGSIRLR[ XFVGTISLS[ ]H][ ^F^[ DM]M D[K[ O[V[ Z[a[", + "MXRMR[ SMS[ OMSM O[V[", + "", + "IZWNUMRMONMPLSLVMYNZQ[T[VZ RMPNNPMSMVNYOZQ[ MTUT", + "I\\TFQGOJNLMOLTLXMZO[Q[TZVWWUXRYMYIXGVFTF TFRGPJOLNOMTMXNZO[ Q[SZUWVUWRXMXIWGVF NPWP", + "G]UFOb VFNb QMMNKPJSJVKXMZP[S[WZYXZUZRYPWNTMQM QMNNLPKSKVLXNZP[ S[VZXXYUYRXPVNTM", + "I[TMVNXPXOWNTMQMNNMOLQLSMUOWSZ QMONNOMQMSNUSZT\\T^S_Q_", + "", + "", + "G]LMKNJPJRKUOYP[ JRKTOXP[P]O`MbLbKaJ_J\\KXMTOQRNTMVMYNZPZTYXWZU[T[SZSXTWUXTY VMXNYPYTXXWZ", + "E_YGXHYIZHYGWFTFQGOINKMNLRJ[I_Ha TFRGPIOKNNLWK[J^I`HaFbDbCaC`D_E`Da _G^H_I`H`G_F]F[GZHYJXMU[T_Sa ]F[HZJYNWWV[U^T`SaQbObNaN`O_P`Oa IM^M", + "F^[GZH[I\\H[GXFUFRGPIOKNNMRK[J_Ia UFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea YMWTVXVZW[Z[\\Y]W ZMXTWXWZX[ JMZM", + "F^YGXHYIZHZGXF \\FUFRGPIOKNNMRK[J_Ia UFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea [FWTVXVZW[Z[\\Y]W \\FXTWXWZX[ JMYM", + "@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca OFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a `G_H`IaH`G]FZFWGUITKSNRRP[O_Na ZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja ^M\\T[X[Z\\[_[aYbW _M]T\\X\\Z][ DM_M", + "@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca OFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a ^G]H^I_H_G]F aFZFWGUITKSNRRP[O_Na ZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja `F\\T[X[Z\\[_[aYbW aF]T\\X\\Z][ DM^M", + "LYMQNOPMSMTNTQRWRZS[ RMSNSQQWQZR[U[WYXW", + "", + "NV", + "JZ", + "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF QFOGNHMJLOLRMWNYOZQ[ S[UZVYWWXRXOWJVHUGSF", + "H\\NJPISFS[ RGR[ N[W[", + "H\\LJMKLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ TFVGWHXJXLWNTPPR KYLXNXSZVZXYYX NXS[W[XZYXYV", + "H\\LJMKLLKKKJLHMGPFTFWGXIXLWNTOQO TFVGWIWLVNTO TOVPXRYTYWXYWZT[P[MZLYKWKVLUMVLW WQXTXWWYVZT[", + "H\\THT[ UFU[ UFJUZU Q[X[", + "H\\MFKP KPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMVLW SMUNWPXSXUWXUZS[ MFWF MGRGWF", + "H\\WIVJWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNRNOOMQLT RFPGNIMKLOLUMXOZQ[ S[UZWXXUXTWQUOSN", + "H\\KFKL KJLHNFPFUIWIXHYF LHNGPGUI YFYIXLTQSSRVR[ XLSQRSQVQ[", + "H\\PFMGLILLMNPOTOWNXLXIWGTFPF PFNGMIMLNNPO TOVNWLWIVGTF POMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO PONPMQLSLWMYNZP[ T[VZWYXWXSWQVPTO", + "H\\XMWPURRSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNWMX QSORMPLMLLMIOGQF SFUGWIXLXRWVVXTZR[", + "MWRYQZR[SZRY", + "MWR[QZRYSZS\\R^Q_", + "MWRMQNROSNRM RYQZR[SZRY", + "MWRMQNROSNRM R[QZRYSZS\\R^Q_", + "MWRFQHRTSHRF RHRN RYQZR[SZRY", + "I[MJNKMLLKLJMHNGPFSFVGWHXJXLWNVORQRT SFUGVHWJWLVNTP RYQZR[SZRY", + "NVRFQM SFQM", + "JZNFMM OFMM VFUM WFUM", + "KYQFOGNINKOMQNSNUMVKVIUGSFQF", + "JZRFRR MIWO WIMO", + "G][BIb", + "KYVBTDRGPKOPOTPYR]T`Vb TDRHQKPPPTQYR\\T`", + "KYNBPDRGTKUPUTTYR]P`Nb PDRHSKTPTTSYR\\P`", + "KYOBOb PBPb OBVB ObVb", + "KYTBTb UBUb NBUB NbUb", + "JYTBQEPHPJQMSOSPORSTSUQWPZP\\Q_Tb RDQGQKRN RVQYQ]R`", + "KZPBSETHTJSMQOQPURQTQUSWTZT\\S_Pb RDSGSKRN RVSYS]R`", + "KYUBNRUb", + "KYOBVROb", + "NVRBRb", + "KYOBOb UBUb", + "E_IR[R", + "E_RIR[ IR[R", + "F^RJR[ JRZR J[Z[", + "F^RJR[ JJZJ JRZR", + "G]KKYY YKKY", + "MWQQQSSSSQQQ RQRS QRSR", + "E_RIQJRKSJRI IR[R RYQZR[SZRY", + "E_IO[O IU[U", + "E_YIK[ IO[O IU[U", + "E_IM[M IR[R IW[W", + "F^ZIJRZ[", + "F^JIZRJ[", + "F^ZFJMZT JVZV J[Z[", + "F^JFZMJT JVZV J[Z[", + "F_[WYWWVUTRPQOONMNKOJQJSKUMVOVQURTUPWNYM[M", + "F^IUISJPLONOPPTSVTXTZS[Q ISJQLPNPPQTTVUXUZT[Q[O", + "G]JTROZT JTRPZT", + "LXTFOL TFUGOL", + "LXPFUL PFOGUL", + "H\\KFLHNJQKSKVJXHYF KFLINKQLSLVKXIYF", + "MWRHQGRFSGSIRKQL", + "MWSFRGQIQKRLSKRJ", + "MWRHSGRFQGQIRKSL", + "MWQFRGSISKRLQKRJ", + "E[HMLMRY KMR[ [BR[", + "F^ZJSJOKMLKNJQJSKVMXOYSZZZ", + "F^JJJQKULWNYQZSZVYXWYUZQZJ", + "F^JJQJUKWLYNZQZSYVWXUYQZJZ", + "F^JZJSKOLMNKQJSJVKXMYOZSZZ", + "F^ZJSJOKMLKNJQJSKVMXOYSZZZ JRVR", + "E_XP[RXT UMZRUW IRZR", + "JZPLRITL MORJWO RJR[", + "E_LPIRLT OMJROW JR[R", + "JZPXR[TX MURZWU RIRZ", + "I\\XRWOVNTMRMONMQLTLWMYNZP[R[UZWXXUYPYKXHWGUFRFPGOHOIPIPH RMPNNQMTMXNZ R[TZVXWUXPXKWHUF", + "H\\JFR[ KFRY ZFR[ JFZF KGYG", + "AbDMIMRY HNR[ b:R[", + "F^[CZD[E\\D\\C[BYBWCUETGSJRNPZO^N` VDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia", + "F^[CZD[E\\D\\C[BYBWCUETGSJRNPZO^N` VDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK", + "F_\\S[UYVWVUUTTQPPONNLNJOIQISJULVNVPUQTTPUOWNYN[O\\Q\\S", + "F^[FI[ NFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F WTUUTWTYV[X[ZZ[X[VYTWT", + "F_[NZO[P\\O\\N[MZMYNXPVUTXRZP[M[JZIXIUJSPORMSKSIRGPFNGMIMKNNPQUXWZZ[[[\\Z\\Y M[KZJXJUKSMQ MKNMVXXZZ[", + "E`WNVLTKQKOLNMMPMSNUPVSVUUVS QKOMNPNSOUPV WKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX XKWSWUXV", + "H\\PBP_ TBT_ XIWJXKYJYIWGTFPFMGKIKKLMMNOOUQWRYT KKMMONUPWQXRYTYXWZT[P[MZKXKWLVMWLX", + "G]OFOb UFUb JQZQ JWZW", + "JZUITJUKVJVIUGSFQFOGNINKOMQOVR OMTPVRWTWVVXTZ PNNPMRMTNVPXU[ NVSYU[V]V_UaSbQbOaN_N^O]P^O_", + "JZRFQHRJSHRF RFRb RQQTRbSTRQ LMNNPMNLLM LMXM TMVNXMVLTM", + "JZRFQHRJSHRF RFRT RPQRSVRXQVSRRP RTRb R^Q`RbS`R^ LMNNPMNLLM LMXM TMVNXMVLTM L[N\\P[NZL[ L[X[ T[V\\X[VZT[", + "I\\XFX[ KFXF PPXP K[X[", + "", + "E`QFNGKIILHOHRIUKXNZQ[T[WZZX\\U]R]O\\LZIWGTFQF ROQPQQRRSRTQTPSORO RPRQSQSPRP", + "J[PFNGOIQJ PFOGOI UFWGVITJ UFVGVI QJOKNLMNMQNSOTQUTUVTWSXQXNWLVKTJQJ RUR[ SUS[ NXWX", + "I\\RFOGMILLLMMPORRSSSVRXPYMYLXIVGSFRF RSR[ SSS[ NWWW", + "D`PFMGJIHLGOGSHVJYM[P\\T\\W[ZY\\V]S]O\\LZIWGTFPF RFR\\ GQ]Q", + "G`PMMNKPJSJTKWMYPZQZTYVWWTWSVPTNQMPM ]GWG[HUN ]G]M\\IVO \\HVN", + "F\\IIJGLFOFQGRIRLQOPQNSKU OFPGQIQMPPNS VFT[ WFS[ KUYU", + "I\\MFMU NFMQ MQNOONQMTMWNXPXRWTUV TMVNWPWRTXTZU[W[YY KFNF", + "I\\RNOOMQLTLUMXOZR[S[VZXXYUYTXQVOSNRN RHNJRFRN SHWJSFSN RSQTQURVSVTUTTSSRS RTRUSUSTRT", + "G^QHRFR[ THSFS[ JHKFKMLPNRQSRS MHLFLNMQ [HZFZMYPWRTSSS XHYFYNXQ NWWW", + "G]LFL[ MFM[ IFUFXGYHZJZMYOXPUQMQ UFWGXHYJYMXOWPUQ I[Y[YVX[", + "H[YGUGQHNJLMKPKSLVNYQ[U\\Y\\ YGVHSJQMPPPSQVSYV[Y\\", + "F_OQMQKRJSIUIWJYKZM[O[QZRYSWSURSQROQ SHPQ ZJRR \\QST", + "H\\OKUY UKOY KOYU YOKU", + "F^NVLUKUIVHXHYI[K\\L\\N[OYOXNVKRJOJMKJMHPGTGWHYJZMZOYRVVUXUYV[X\\Y\\[[\\Y\\X[VYUXUVV JMKKMIPHTHWIYKZM", + "F^NMLNKNIMHKHJIHKGLGNHOJOKNMKQJTJVKYM[P\\T\\W[YYZVZTYQVMUKUJVHXGYG[H\\J\\K[MYNXNVM JVKXMZP[T[WZYXZV", + "I[KYYK QLULYKXOXS ULXLXO", + "I[YKKY LQLUKYOXSX LULXOX", + "I[YYKK SLOLKKLOLS OLLLLO", + "I[KKYY QXUXYYXUXQ UXXXXU", + "", + "F_JMILIJJHLGNGPHQIRKSP IJKHMHOIPJQLRPR[ [M\\L\\J[HYGWGUHTISKRP \\JZHXHVIUJTLSPS[", + "F^IGJKKMMOPPTPWOYMZK[G IGJJKLMNPOTOWNYLZJ[G PONPMQLSLVMXOZQ[S[UZWXXVXSWQVPTO PPNQMSMVNY VYWVWSVQTP", + "F^MJMV NKNU VKVU WJWV IGKIMJPKTKWJYI[G IYKWMVPUTUWVYW[Y", + "F^[ILIJJILINJPLQNQPPQNQLPJ[J IMJOKPMQ QMPKOJMI IXXXZW[U[SZQXPVPTQSSSUTWIW [TZRYQWP STTVUWWX", + "F]OUMTLTJUIWIXJZL[M[OZPXPWOUJPINIKJILHOGSGWHYJZLZOYRVUUWUYV[X[YZZX MSKPJNJKKILH SGVHXJYLYOXRVU", + "G_HKKHMKMV JILLLV MKPHRKRU OIQLQU RKUHWKW[ TIVLV[ WKZH[J\\M\\P[SZUXWUYP[ YIZJ[M[PZSYUWWTYP[", + "F^ISMSLRKOKMLJNHQGSGVHXJYMYOXRWS[S ITOTMRLOLMMJOHQG SGUHWJXMXOWRUT[T KXYX KYYY", + "F_GLJIMLMX IJLMLX MLPISLSX OJRMRX SLVIYLYW[Y UJXMXXZZ]W", + "G]ZIJY ZIWJQJ XKUKQJ ZIYLYR XKXNYR QRJR PSMSJR QRQY PSPVQY", + "F^HOJKOU JMOWRPWPZO[M[KZIXHWHUITKTMUPVRWUWXUZ WHVIUKUMWQXTXWWYUZ", + "F^IOLLPN KMOORLUN QMTOWLYN VMXO[L IULRPT KSOURRUT QSTUWRYT VSXU[R", + "F^JHNJPLQOQRPUNWJY JHMIOJQLRO RRQUOWMXJY ZHWIUJSLRO RRSUUWWXZY ZHVJTLSOSRTUVWZY IP[P IQ[Q", + "", + "", + "", + "", + "NVQQQSSSSQQQ QQSS SQQS", + "JZMPQRTTVVWYW[V]U^ MQST MRPSTUVWWY", + "JZWKVMTOPQMR SPMS UFVGWIWKVNTPQRMT", + "H\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM XNSM VMQNLP ONKR LVQW NWSVXT UVYR", + "H\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM XNSM VMQNLP ONKR LVQW NWSVXT UVYR", + "J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM OPUM NRVN MTWO NUXP OVWR PWVT", + "JZOGO^ UFU] MNWL MOWM MWWU MXWV", + "JZNFNX VLV^ NNVL NOVM NWVU NXVV", + "JZNBNW NNQLTLVMWOWQVSSUQVNW NNQMTMVN UMVOVQUSSU", + "E_HIHL \\I\\L HI\\I HJ\\J HK\\K HL\\L", + "JZMNMQ WNWQ MNWN MOWO MPWP MQWQ", + "JZMLWX MLONQOTOVNWMWKUKUMTO ONTO QOWM VKVN ULWL WXUVSUPUNVMWMYOYOWPU UVPU SUMW NVNY MXOX", + "JZPOOMOKMKMMNNPOSOUNWL NKNN MLOL MMSO POUN WLWY", + "A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\R\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW GdGeHeHdGd U;Q?LCIFGIFKENERFVGXJ[ R\\U[WZYWZTZPYMXKVITH", + "EfNSOUQVSVUUVSVQUOSNQNOONPMSMVNYP[S\\V\\Y[[Y\\W]T]P\\MZJXIUHRHOIMJKLIOHSHXI]KaMcPeTfYf]e`cba KLJNIRIXJ\\L`NbQdUeYe]d_cba POTO OPUP NQVQ NRVR NSVS OTUT PUTU aLaNcNcLaL bLbN aMcM aVaXcXcVaV bVbX aWcW", + "D`H@Hd M@Md W@Wd \\@\\d MMWK MNWL MOWM MWWU MXWV MYWW", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NVQQQSSSSQQQ QQSS SQQS", + "JZMPQRTTVVWYW[V]U^ MQST MRPSTUVWWY", + "JZWKVMTOPQMR SPMS UFVGWIWKVNTPQRMT", + "H\\PMMNLOKQKSLUMVPWTWWVXUYSYQXOWNTMPM MNLPLSMUNVPW WVXTXQWOVNTM", + "H\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM XNSM VMQNLP ONKR LVQW NWSVXT UVYR", + "J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM OPUM NRVN MTWO NUXP OVWR PWVT", + "JZOGO^ UFU] MNWL MOWM MWWU MXWV", + "JZNFNX VLV^ NNVL NOVM NWVU NXVV", + "JZNBNW NNQLTLVMWOWQVSSUQVNW NNQMTMVN UMVOVQUSSU", + "E_HIHL \\I\\L HI\\I HJ\\J HK\\K HL\\L", + "JZMNMQ WNWQ MNWN MOWO MPWP MQWQ", + "JZQCVMRTRU ULQS TITKPRRUUY W\\UYSXQXOYN[N]O_Ra W\\UZSYOYO]P_Ra SXPZN]", + "JZPOOMOKMKMMNNPOSOUNWL NKNN MLOL MMSO POUN WLSY", + "A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\R\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW GdGeHeHdGd U;Q?LCIFGIFKENERFVGXJ[ R\\U[WZYWZTZPYMXKVITH", + "IjNQOOQNSNUOVQVSUUSVQVOUNTMQMNNKPISHWH[I^K`NaRaW`[_]]`ZcVfQiMk WHZI]K_N`R`W_[^]\\`YcTgQi POTO OPUP NQVQ NRVR NSVS OTUT PUTU eLeNgNgLeL fLfN eMgM eVeXgXgVeV fVfX eWgW", + "D`H>Hf I>If M>Mf QBSBSDQDQAR?T>W>Y?[A\\D\\I[LYNWOUOSNRLQNOQNROSQVRXSVUUWUYV[X\\[\\`[cYeWfTfReQcQ`S`SbQb RBRD QCSC Y?ZA[D[IZLYN RLRNPQNRPSRVRX YVZX[[[`ZcYe R`Rb QaSa", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "AcHBHb IBIb [B[b \\B\\b DB`B DbMb Wb`b", + "BaGBQPFb FBPP EBPQ EB\\B^I[B Ga\\a Fb\\b^[[b", + "I[X+U1R8P=OANFMNMVN^OcPgRlUsXy U1S6QPBTJTLSNROMRRUSVTXTZPbOfOjPoRsVy T.R2Q5P:P>QCRF R^QaPfPjQoRrTv", + "I\\N+R1T5U:U>TBPJPLQNROWRRUQVPXPZTbUfUjToRsNy P.R2S5T:T>SCRF R^SaTfTjSoRrPv", + "I[V.S1Q4O8N=NCOIPMSXT\\UbUgTlSoQs S1Q5P8O=OBPHQLTWU[VaVgUlSpQsNv", + "I[N.Q1S4U8V=VCUITMQXP\\ObOgPlQoSs Q1S5T8U=UBTHSLPWO[NaNgOlQpSsVv", + "7Z:RARRo @RQo ?RRr Z\"VJRr", + "Ca].\\.[/[0\\1]1^0^.],[+Y+W,U.T0S3R:QJQjPsOv \\/\\0]0]/\\/ R:Rj U.T1S:SZRjQqPtOvMxKyIyGxFvFtGsHsItIuHvGv GtGuHuHtGt", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "H\\RFJ[ RIK[J[ RIY[Z[ RFZ[ MUWU LVXV", + "H\\LFL[ MGMZ LFTFWGXHYJYMXOWPTQ MGTGWHXJXMWOTP MPTPWQXRYTYWXYWZT[L[ MQTQWRXTXWWYTZMZ", + "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV ZKYKXIWHUGQGOHMKLNLSMVOYQZUZWYXXYVZV", + "H]LFL[ MGMZ LFSFVGXIYKZNZSYVXXVZS[L[ MGSGVHWIXKYNYSXVWXVYSZMZ", + "I\\MFM[ NGNZ MFYF NGYGYF NPTPTQ NQTQ NZYZY[ M[Y[", + "I[MFM[ NGN[M[ MFYF NGYGYF NPTPTQ NQTQ", + "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZRUR ZKYKXIWHUGQGOHNIMKLNLSMVNXOYQZUZWYXXYVYSUSUR", + "G]KFK[ KFLFL[K[ YFXFX[Y[ YFY[ LPXP LQXQ", + "NWRFR[S[ RFSFS[", + "J[VFVVUYSZQZOYNVMV VFWFWVVYUZS[Q[OZNYMV", + "H]LFL[M[ LFMFM[ ZFYFMR ZFMS POY[Z[ QOZ[", + "IZMFM[ MFNFNZ NZYZY[ M[Y[", + "F^JFJ[ KKK[J[ KKR[ JFRX ZFRX YKR[ YKY[Z[ ZFZ[", + "G]KFK[ LIL[K[ LIY[ KFXX XFXX XFYFY[", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF QGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG", + "H\\LFL[ MGM[L[ LFUFWGXHYJYMXOWPUQMQ MGUGWHXJXMWOUPMP", + "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF QGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG SXX]Y] SXTXY]", + "H\\LFL[ MGM[L[ LFTFWGXHYJYMXOWPTQMQ MGTGWHXJXMWOTPMP RQX[Y[ SQY[", + "H\\YIWGTFPFMGKIKKLMMNOOTQVRWSXUXXWYTZPZNYMXKX YIWIVHTGPGMHLILKMMONTPVQXSYUYXWZT[P[MZKX", + "J[RGR[ SGS[R[ LFYFYG LFLGYG", + "G]KFKULXNZQ[S[VZXXYUYF KFLFLUMXNYQZSZVYWXXUXFYF", + "H\\JFR[ JFKFRX ZFYFRX ZFR[", + "E_GFM[ GFHFMX RFMX RIM[ RIW[ RFWX ]F\\FWX ]FW[", + "H\\KFX[Y[ KFLFY[ YFXFK[ YFL[K[", + "I\\KFRPR[S[ KFLFSP ZFYFRP ZFSPS[", + "H\\XFK[ YFL[ KFYF KFKGXG LZYZY[ K[Y[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "E\\XFVHTKQPOSLWIZG[E[DZDXEWFXEY XFWJUTT[ XFU[ T[TYSVRTPRNQLQKRKTLWOZR[V[XZ", + "F^UGTHSJQOOUNWLZJ[ THSKQSPVOXMZJ[H[GZGXHWIXHY OLNNMOKOJNJLKJMHOGRFXFZG[I[KZMXNTORO XFYGZIZKYMXN TOWPXQYSYVXYWZU[S[RZRXSU TOVPWQXSXVWYU[", + "H]KHJJJLKNNOQOUNWMYKZIZGYFWFTGQJOMMQLULXMZP[R[UZWXXVXTWRURSSRU WFUGRJPMNQMUMXNZP[", + "F]UGTHSJQOOUNWLZJ[ THSKQSPVOXMZJ[H[GZGXHWJWLXNZP[S[UZWXYTZOZLYIWGUFPFMGKIJKJMKNMNNMOK", + "I\\WIVJVLWMYMZKZIYGWFTFRGQHPJPLQNSO TFRHQJQMSO SOQONPLRKTKWLYMZO[R[UZWXXVXTWRURSSRU QOOPMRLTLXMZ", + "G\\WHVJTORUQWOZM[ QLPNNOLOKMKKLINGQF[FXGWHVKTSSVRXPZM[K[IZHYHXIWJXIY SFWGXG OSPRRQVQXPZMXT", + "G]JIIKIMJOLPOPROTNWKXHXGWFVFTGRIQKPNPQQSSTUTWSYQZO WFUGSIRKQNQRST ZOYSWWUYSZO[L[JZIXIWJVKWJX YSWVUXRZO[", + "F^LLKKKILGOFRFOQMWLYKZI[G[FZFXGWHXGY RFOONRLWKYI[ JTKSMRVOXN[L]J^H^G]F\\FZGXJWLURTVTYV[W[YZ[X \\FZHXLVRUVUYV[", + "IYWHUKSPQUPWNZL[ YLWNTOQOONNLNJOHQGUFYFWHVJTPRVQXOZL[J[IZIXJWKXJY", + "IZYFWHUKSPPYN] YMWOTPQPOONMNKOIQGUFYFWIVKSTQXPZN]M^K_J^J\\KZMXOWRVVU", + "F^LLKKKIMGPFRFOQMWLYKZI[G[FZFXGWHXGY RFOONRLWKYI[ ZGWKUMSNPO ]G\\H]I^H^G]F\\FZGWLVMTNPO POSPTRUYV[ PORPSRTYV[W[YZ[X", + "I[MILKLMMOOPRPUOWNZK[H[GZFYFWGVHTKPUOWMZK[ VHTLRSQVPXNZK[I[HZHXIWKWMXPZR[U[WZYX", + "D`RFNOKUIXGZE[C[BZBXCWDXCY RFPMOQNVNZP[ RFQJPOOVOZP[ [FWORXP[ [FYMXQWVWZY[Z[\\Z^X [FZJYOXVXZY[", + "G^RFQJOPMULWJZH[F[EZEXFWGXFY RFRKSVT[ RFSKTVT[ `G_H`IaHaG`F^F\\GZJYLWQUWT[", + "H]SFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGWGUHSJQNPSPV QGOJMNLRLVMYO[", + "F]UGTHSJQOOUNWLZJ[ THSKQSPVOXMZJ[H[GZGXHWIXHY OLNNMOKOJNJLKJMHOGRFVFYGZH[J[MZOYPVQTQRP VFXGYHZJZMYOXPVQ", + "H]UJULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[XZZX WFXGYIYMXPVSSVOYK[", + "F^UGTHSJQOOUNWLZJ[ THSKQSPVOXMZJ[H[GZGXHWIXHY OLNNMOKOJNJLKJMHOGRFWFZG[I[KZMYNVORO WFYGZIZKYMXNVO ROUPVRWYX[ ROTPURVYX[Y[[Z]X", + "H\\NIMKMMNOPPSPVOXN[K\\H\\G[FZFXGWHVJUMSTRWPZN[ VJUNTUSXQZN[K[IZHXHWIVJWIX", + "I[YHXJVOTUSWQZO[ SLRNPONOMMMKNIPGSF\\FZGYHXKVSUVTXRZO[M[KZJYJXKWLXKY UFYGZG", + "G]HJJGLFMFOHOKNNKVKYL[ MFNHNKKSJVJYL[N[PZSWUTVR ZFVRUVUYW[X[ZZ\\X [FWRVVVYW[", + "G\\HJJGLFMFOHOKNOLVLYM[ MFNHNKLRKVKYM[N[QZTWVTXPYMZIZGYFXFWGVIVLWNYP[Q]Q", + "F]ILHLGKGIHGJFNFMHLLKUJ[ LLLUK[ VFTHRLOUMYK[ VFUHTLSUR[ TLTUS[ `F^G\\IZLWUUYS[", + "H\\PKOLMLLKLIMGOFQFSGTITLSPQUOXMZJ[H[GZGXHWIXHY QFRGSISLRPPUNXLZJ[ ]G\\H]I^H^G]F[FYGWIULSPRURXSZT[U[WZYX", + "G]JJLGNFOFQGQIOOORPT OFPGPINONRPTRTUSWQYNZL \\FZLWTUX ]F[LYQWUUXSZP[L[JZIXIWJVKWJX", + "G\\ZHYJWOVRUTSWQYOZL[ SLRNPONOMMMKNIPGSF]F[GZHYKXOVUTXQZL[H[GZGXHWJWLXOZQ[T[WZYX VFZG[G", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "H\\WMW[X[ WMXMX[ WPUNSMPMNNLPKSKULXNZP[S[UZWX WPSNPNNOMPLSLUMXNYPZSZWX", + "H\\LFL[M[ LFMFM[ MPONQMTMVNXPYSYUXXVZT[Q[OZMX MPQNTNVOWPXSXUWXVYTZQZMX", + "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX XPWQVOTNQNOONPMSMUNXOYQZTZVYWWXX", + "H\\WFW[X[ WFXFX[ WPUNSMPMNNLPKSKULXNZP[S[UZWX WPSNPNNOMPLSLUMXNYPZSZWX", + "I[MTXTXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX MSWSWQVOTNQNOONPMSMUNXOYQZTZVYWWXX", + "LZWFUFSGRJR[S[ WFWGUGSH TGSJS[ OMVMVN OMONVN", + "H\\XMWMW\\V_U`SaQaO`N_L_ XMX\\W_UaSbPbNaL_ WPUNSMPMNNLPKSKULXNZP[S[UZWX WPSNPNNOMPLSLUMXNYPZSZWX", + "H\\LFL[M[ LFMFM[ MQPNRMUMWNXQX[ MQPORNTNVOWQW[X[", + "NWRFQGQHRISITHTGSFRF RGRHSHSGRG RMR[S[ RMSMS[", + "NWRFQGQHRISITHTGSFRF RGRHSHSGRG RMRbSb RMSMSb", + "H[LFL[M[ LFMFM[ XMWMMW XMMX PTV[X[ QSX[", + "NWRFR[S[ RFSFS[", + "CbGMG[H[ GMHMH[ HQKNMMPMRNSQS[ HQKOMNONQORQR[S[ SQVNXM[M]N^Q^[ SQVOXNZN\\O]Q][^[", + "H\\LML[M[ LMMMM[ MQPNRMUMWNXQX[ MQPORNTNVOWQW[X[", + "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM QNOONPMSMUNXOYQZTZVYWXXUXSWPVOTNQN", + "H\\LMLbMb LMMMMb MPONQMTMVNXPYSYUXXVZT[Q[OZMX MPQNTNVOWPXSXUWXVYTZQZMX", + "H\\WMWbXb WMXMXb WPUNSMPMNNLPKSKULXNZP[S[UZWX WPSNPNNOMPLSLUMXNYPZSZWX", + "KYOMO[P[ OMPMP[ PSQPSNUMXM PSQQSOUNXNXM", + "J[XPWNTMQMNNMPNRPSUUWV VUWWWXVZ WYTZQZNY OZNXMX XPWPVN WOTNQNNO ONNPOR NQPRUTWUXWXXWZT[Q[NZMX", + "MXRFR[S[ RFSFS[ OMVMVN OMONVN", + "H\\LMLWMZO[R[TZWW LMMMMWNYPZRZTYWW WMW[X[ WMXMX[", + "JZLMR[ LMMMRY XMWMRY XMR[", + "F^IMN[ IMJMNX RMNX RPN[ RPV[ RMVX [MZMVX [MV[", + "I[LMW[X[ LMMMX[ XMWML[ XMM[L[", + "JZLMR[ LMMMRY XMWMRYNb XMR[ObNb", + "I[VNL[ XMNZ LMXM LMLNVN NZXZX[ L[X[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "K[UUTSRRPRNSMTLVLXMZO[Q[SZTX PRNTMVMYO[ VRTXTZV[XZYY[V WRUXUZV[", + "LZLVNSPO SFMXMZO[P[RZTXUUURVVWWXWZV TFNXNZO[", + "LXTSSTTTTSSRQROSNTMVMXNZP[S[VYXV QROTNVNYP[", + "K[UUTSRRPRNSMTLVLXMZO[Q[SZTX PRNTMVMYO[ ZFTXTZV[XZYY[V [FUXUZV[", + "LXOYQXRWSUSSRRQROSNTMVMXNZP[S[VYXV QROTNVNYP[", + "OXRRUOWLXIXGWFUGTIKdKfLgNfOcPZQ[S[UZVYXV TISNRRO[M`Kd", + "K[UUTSRRPRNSMTLVLXMZO[Q[SZTX PRNTMVMYO[ VRPd WRT[R`PdOfMgLfLdMaO_R]V[YY[V", + "L[LVNSPO SFL[ TFM[ OUQSSRTRVSVUUXUZV[ TRUSUUTXTZV[XZYY[V", + "NVSLRMSNTMSL QROXOZQ[SZTYVV RRPXPZQ[", + "NVSLRMSNTMSL QRKd RRO[M`KdJfHgGfGdHaJ_M]Q[TYVV", + "LZLVNSPO SFL[ TFM[ URUSVSURTRRTOU OURVSZT[ OUQVRZT[U[XYZV", + "NVNVPSRO UFOXOZQ[SZTYVV VFPXPZQ[", + "E^EVGSIRKSKUI[ IRJSJUH[ KUMSORPRRSRUP[ PRQSQUO[ RUTSVRWRYSYUXXXZY[ WRXSXUWXWZY[[Z\\Y^V", + "I[IVKSMROSOUM[ MRNSNUL[ OUQSSRTRVSVUUXUZV[ TRUSUUTXTZV[XZYY[V", + "KYRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXVXXWYV PRNTMVMYO[", + "L[LVNSPO QLHg RLIg OUQSSRTRVSVUUXUZV[ TRUSUUTXTZV[XZYY[V", + "K[UUTSRRPRNSMTLVLXMZO[Q[SZ PRNTMVMYO[ VRPdPfQgSfTcT[V[YY[V WRT[R`Pd", + "LZLVNSPRRSRUP[ PRQSQUO[ RUTSVRWRVU VRVUWWXWZV", + "NZNVPSQQQSTUUWUYTZR[ QSSUTWTYR[ NZP[U[XYZV", + "NVNVPSRO UFOXOZQ[SZTYVV VFPXPZQ[ PNVN", + "K[NRLXLZN[O[QZSXUU ORMXMZN[ VRTXTZV[XZYY[V WRUXUZV[", + "KZNRMTLWLZN[O[RZTXUUUR ORNTMWMZN[ URVVWWXWZV", + "H]LRJTIWIZK[L[NZPX MRKTJWJZK[ RRPXPZR[S[UZWXXUXR SRQXQZR[ XRYVZW[W]V", + "JZJVLSNRPRQSQUPXOZM[L[KZKYLYKZ WSVTWTWSVRURSSRUQXQZR[U[XYZV QSRU SSQU PXQZ QXOZ", + "K[NRLXLZN[O[QZSXUU ORMXMZN[ VRPd WRT[R`PdOfMgLfLdMaO_R]V[YY[V", + "LYLVNSPRRRTSTVSXPZN[ RRSSSVRXPZ N[P\\Q^QaPdNfLgKfKdLaO^R\\VYYV N[O\\P^PaOdNf", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NV", + "JZ", + "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF OGMJLOLRMWOZ NYQZSZVY UZWWXRXOWJUG VHSGQGNH", + "H\\NJPISFS[ NJNKPJRHR[S[", + "H\\LKLJMHNGPFTFVGWHXJXLWNUQL[ LKMKMJNHPGTGVHWJWLVNTQK[ LZYZY[ K[Y[", + "H\\MFXFQO MFMGWG WFPO QNSNVOXQYTYUXXVZS[P[MZLYKWLW POSOVPXS TOWQXTXUWXTZ XVVYSZPZMYLW OZLX", + "H\\UIU[V[ VFV[ VFKVZV UILV LUZUZV", + "H\\MFLO NGMN MFWFWG NGWG MNPMSMVNXPYSYUXXVZS[P[MZLYKWLW LOMOONSNVOXR TNWPXSXUWXTZ XVVYSZPZMYLW OZLX", + "H\\VGWIXIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQ WHTGRGOH PGNJMOMTNXQZ MVOYRZSZVYXV TZWXXUXTWQTO XSVPSOROOPMS QONQMT", + "H\\KFYFO[ KFKGXG XFN[O[", + "H\\PFMGLILKMMNNPOTPVQWRXTXWWYTZPZMYLWLTMRNQPPTOVNWMXKXIWGTFPF NGMIMKNMPNTOVPXRYTYWXYWZT[P[MZLYKWKTLRNPPOTNVMWKWIVG WHTGPGMH LXOZ UZXX", + "H\\WPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLXMXNZ WMVPSR WNUQRRQRNQLN PRMPLMLLMIPG LKNHQGRGUHWK SGVIWMWRVWTZ UYRZPZMY", + "MXRXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXTZS[R[QZQYRXSXTYT\\S^Q_ RYRZSZSYRY S[T\\ TZS^", + "MXRMQNQORPSPTOTNSMRM RNROSOSNRN RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXRMQNQORPSPTOTNSMRM RNROSOSNRN TZS[R[QZQYRXSXTYT\\S^Q_ RYRZSZSYRY S[T\\ TZS^", + "MXRFRTST RFSFST RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "I\\LKLJMHNGQFTFWGXHYJYLXNWOUPRQ LKMKMJNHQGTGWHXJXLWNUORP MIPG UGXI XMTP RPRTSTSP RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXTFRGQIQLRMSMTLTKSJRJQK RKRLSLSKRK RGQK QIRJ", + "MXTHSIRIQHQGRFSFTGTJSLQM RGRHSHSGRG SITJ THSL", + "F_\\MZMXNWPUVTXSYQZMZKYJWJUKSLRQOSMTKTISGQFPFNGMIMKNNPQUWXZZ[\\[ \\M\\NZNWP ZMXPVVUXSZQ[M[KZJYIWIUJSLQQNRMSKSIRG SHQGPGNH OGNINKONQQVWXYZZ\\Z\\[", + "I\\RBR_S_ RBSBS_ WIYIWGTFQFNGLILKMMNNVRWSXUXWWYTZQZOYNX WIVHTGQGNHMIMKNMVQXSYUYWXYWZT[Q[NZLXNX XXUZ", + "G^[BIbJb [B\\BJb", + "KYUBSDQGOKNPNTOYQ]S`UbVb UBVBTDRGPKOPOTPYR]T`Vb", + "KYNBPDRGTKUPUTTYR]P`NbOb NBOBQDSGUKVPVTUYS]Q`Ob", + "JZRFQGSQRR RFRR RFSGQQRR MINIVOWO MIWO MIMJWNWO WIVINOMO WIMO WIWJMNMO", + "F_JQ[Q[R JQJR[R", + "F_RIRZSZ RISISZ JQ[Q[R JQJR[R", + "F_JM[M[N JMJN[N JU[U[V JUJV[V", + "NWSFRGRM SGRM SFTGRM", + "I[NFMGMM NGMM NFOGMM WFVGVM WGVM WFXGVM", + "KYQFOGNINKOMQNSNUMVKVIUGSFQF QFNIOMSNVKUGQF SFOGNKQNUMVISF", + "F^ZIJRZ[ ZIZJLRZZZ[", + "F^JIZRJ[ JIJJXRJZJ[", + "G^OFObPb OFPFPb UFUbVb UFVFVb JP[P[Q JPJQ[Q JW[W[X JWJX[X", + "F^[FYGVHSHPGNFLFJGIIIKKMMMOLPJPHNF [FH[I[ [F\\FI[ YTWTUUTWTYV[X[ZZ[X[VYT NFJGIKMMPJNF LFIIKMOLPHLF YTUUTYX[[XYT WTTWV[ZZ[VWT", + "E`WMTKQKOLNMMOMRNTOUQVTVWT WMTLQLOMNONROTQUTUWT VKVSWUYVZV\\U]S]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[U[YZ VKWKWSXUZV YV[U\\S\\O[LZJYIWHTGQGNHLIKJJLIOIRJUKWLXNYQZUZYYYZ", + "E_JPLONOPPSTTUVVXVZU[S[QZOXNVNTOSPPTNULUJT ZPXOVOTPQTPUNVLVJUISIQJOLNNNPOQPTTVUXUZT KOJQJSKU YUZSZQYO", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NV", + "JZ", + "H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF TFRGPINLMOLSLVMYO[ Q[SZUXWUXRYNYKXHVF", + "H]TJO[ VFP[ VFSIPKNL UIQKNL", + "H]OJPKOLNKNJOHPGSFVFYGZIZKYMWOTQPSMUKWI[ VFXGYIYKXMVOPS JYKXMXRZUZWYXW MXR[U[WZXW", + "H]OJPKOLNKNJOHPGSFVFYGZIZKYMVOSP VFXGYIYKXMVO QPSPVQWRXTXWWYVZS[O[LZKYJWJVKULVKW SPUQVRWTWWVYUZS[", + "H]XGR[ YFS[ YFJUZU", + "H]QFLP QF[F QGVG[F LPMOPNSNVOWPXRXUWXUZR[O[LZKYJWJVKULVKW SNUOVPWRWUVXTZR[", + "H]YIXJYKZJZIYGWFTFQGOIMLLOKSKWLYMZO[R[UZWXXVXSWQVPTOQOOPMRLT TFRGPINLMOLSLXMZ R[TZVXWVWRVP", + "H]NFLL [FZIXLSRQUPWO[ XLRRPUOWN[ MIPFRFWI NHPGRGWIYIZH[F", + "H]SFPGOHNJNMOOQPTPXOYNZLZIYGVFSF SFQGPHOJOMPOQP TPWOXNYLYIXGVF QPMQKSJUJXKZN[R[VZWYXWXTWRVQTP QPNQLSKUKXLZN[ R[UZVYWWWSVQ", + "H]YMXOVQTRQROQNPMNMKNIPGSFVFXGYHZJZNYRXUVXTZQ[N[LZKXKWLVMWLX OQNONKOIQGSF XGYIYNXRWUUXSZQ[", + "MXPYOZP[QZPY", + "MXP[OZPYQZQ[P]N_", + "MXSMRNSOTNSM PYOZP[QZ", + "MXSMRNSOTNSM P[OZPYQZQ[P]N_", + "MXUFTGRS UGRS UFVGRS PYOZP[QZPY", + "H]OJPKOLNKNJOHPGSFWFZG[I[KZMYNSPQQQSRTTT WFYGZIZKYMXNVO PYOZP[QZPY", + "MXVFTHSJSKTLUKTJ", + "MXUHTGUFVGVHUJSL", + "E_\\N[O\\P]O]N\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQUSXUZW[Y[ZYZX K[IZHXHVITJSPP OLPQQTSWUYWZYZZY", + "H]TBL_ YBQ_ ZJYKZL[K[JZHYGVFRFOGMIMKNMONVRXT MKOMVQWRXTXWWYVZS[O[LZKYJWJVKULVKW", + "G]_BEb", + "KZZBVESHQKOONTNXO]P`Qb VESIQMPPOUOZP_Qb", + "JYSBTDUGVLVPUUSYQ\\N_Jb SBTEUJUOTTSWQ[N_", + "J[TFTR OIYO YIOO", + "E_IR[R", + "E_RIR[ IR[R", + "E_IO[O IU[U", + "NWUFSM VFSM", + "I[PFNM QFNM YFWM ZFWM", + "KZSFQGPIPKQMSNUNWMXKXIWGUFSF", + "F^ZIJRZ[", + "F^JIZRJ[", + "H]SFLb YFRb LQZQ KWYW", + "E_^F\\GXHUHQGOFMFKGJIJKLMNMPLQJQHOF ^FF[ XTVTTUSWSYU[W[YZZXZVXT", + "E`WNVLTKQKOLNMMPMSNUPVSVUUVS QKOMNPNSOUPV WKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX XKWSWUXV", + "F_\\S[UYVWVUUTTQPPONNLNJOIQISJULVNVPUQTTPUOWNYN[O\\Q\\S", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "H\\RFK[ RFY[ RIX[ MUVU I[O[ U[[[", + "G]LFL[ MFM[ IFYFYLXF MPUPXQYRZTZWYYXZU[I[ UPWQXRYTYWXYWZU[", + "G]LFL[ MFM[ IFUFXGYHZJZLYNXOUP UFWGXHYJYLXNWOUP MPUPXQYRZTZWYYXZU[I[ UPWQXRYTYWXYWZU[", + "I[NFN[ OFO[ KFZFZLYF K[R[", + "F^NFNLMTLXKZJ[ XFX[ YFY[ KF\\F G[\\[ G[Gb H[Gb [[\\b \\[\\b", + "G\\LFL[ MFM[ SLST IFYFYLXF MPSP I[Y[YUX[", + "CbRFR[ SFS[ OFVF GGHHGIFHFGGFHFIGJIKMLONPWPYOZM[I\\G]F^F_G_H^I]H^G NPLQKSJXIZH[ NPMQLSKXJZI[G[FZEX WPYQZS[X\\Z][ WPXQYSZX[Z\\[^[_Z`X O[V[", + "H\\LIKFKLLINGPFTFWGXIXLWNTOQO TFVGWIWLVNTO TOVPXRYTYWXYWZT[O[MZLYKWKVLUMVLW WQXTXWWYVZT[", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F XHLY H[O[ U[\\[", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F XHLY H[O[ U[\\[ N@N?M?M@NBPCTCVBW@", + "F^KFK[ LFL[ HFOF LPSPUOVMWIXGYFZF[G[HZIYHZG SPUQVSWXXZY[ SPTQUSVXWZX[Z[[Z\\X H[O[", + "E^MFMLLTKXJZI[H[GZGYHXIYHZ XFX[ YFY[ JF\\F U[\\[", + "F_KFK[ LFRX KFR[ YFR[ YFY[ ZFZ[ HFLF YF]F H[N[ V[][", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F LPXP H[O[ U[\\[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF QFOGMILKKOKRLVMXOZQ[ S[UZWXXVYRYOXKWIUGSF", + "F^KFK[ LFL[ XFX[ YFY[ HF\\F H[O[ U[\\[", + "G]LFL[ MFM[ IFUFXGYHZJZMYOXPUQMQ UFWGXHYJYMXOWPUQ I[P[", + "G\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV QFOGMILKKNKSLVMXOZQ[", + "I\\RFR[ SFS[ LFKLKFZFZLYF O[V[", + "H]KFRV LFSV ZFSVQYPZN[M[LZLYMXNYMZ IFOF VF\\F", + "F_RFR[ SFS[ OFVF PILJJLIOIRJULWPXUXYW[U\\R\\O[LYJUIPI PIMJKLJOJRKUMWPX UXXWZU[R[OZLXJUI O[V[", + "H\\KFX[ LFY[ YFK[ IFOF UF[F I[O[ U[[[", + "F^KFK[ LFL[ XFX[ YFY[ HFOF UF\\F H[\\[ [[\\b \\[\\b", + "F]KFKQLSOTRTUSWQ LFLQMSOT WFW[ XFX[ HFOF TF[F T[[[", + "BcGFG[ HFH[ RFR[ SFS[ ]F][ ^F^[ DFKF OFVF ZFaF D[a[", + "BcGFG[ HFH[ RFR[ SFS[ ]F][ ^F^[ DFKF OFVF ZFaF D[a[ `[ab a[ab", + "F`PFP[ QFQ[ IFHLHFTF QPXP[Q\\R]T]W\\Y[ZX[M[ XPZQ[R\\T\\W[YZZX[", + "CaHFH[ IFI[ EFLF IPPPSQTRUTUWTYSZP[E[ PPRQSRTTTWSYRZP[ [F[[ \\F\\[ XF_F X[_[", + "H]MFM[ NFN[ JFQF NPUPXQYRZTZWYYXZU[J[ UPWQXRYTYWXYWZU[", + "H]LIKFKLLINGQFSFVGXIYKZNZSYVXXVZS[P[MZLYKWKVLUMVLW SFUGWIXKYNYSXVWXUZS[ PPYP", + "CbHFH[ IFI[ EFLF E[L[ VFSGQIPKOOORPVQXSZV[X[[Z]X^V_R_O^K]I[GXFVF VFTGRIQKPOPRQVRXTZV[ X[ZZ\\X]V^R^O]K\\IZGXF IPOP", + "G]WFW[ XFX[ [FOFLGKHJJJLKNLOOPWP OFMGLHKJKLLNMOOP RPPQORLYKZJZIY PQOSMZL[J[IYIX T[[[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "I]NONPMPMONNPMTMVNWOXQXXYZZ[ WOWXXZZ[[[ WQVRPSMTLVLXMZP[S[UZWX PSNTMVMXNZP[", + "H\\XFWGQINKLNKQKULXNZQ[S[VZXXYUYSXPVNSMQMNNLPKS XFWHUIQJNLLN QMONMPLSLUMXOZQ[ S[UZWXXUXSWPUNSM", + "H\\MMM[ NMN[ JMUMXNYPYQXSUT UMWNXPXQWSUT NTUTXUYWYXXZU[J[ UTWUXWXXWZU[", + "HZMMM[ NMN[ JMXMXRWM J[Q[", + "F]NMNQMWLZK[ WMW[ XMX[ KM[M I[H`H[[[[`Z[", + "H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX WSWPVN QMONMPLSLUMXOZQ[", + "E`RMR[ SMS[ OMVM JNIOHNIMJMKNMRNSPTUTWSXRZN[M\\M]N\\O[N PTNUMVKZJ[ PTNVLZK[I[HZGX UTWUXVZZ[[ UTWVYZZ[\\[]Z^X O[V[", + "I[MOLMLQMONNPMTMWNXPXQWSTT TMVNWPWQVSTT QTTTWUXWXXWZT[P[MZLXLWMVNWMX TTVUWWWXVZT[", + "G]LML[ MMM[ WMW[ XMX[ IMPM TM[M I[P[ T[[[ WNMZ", + "G]LML[ MMM[ WMW[ XMX[ IMPM TM[M I[P[ T[[[ WNMZ OGOFNFNGOIQJSJUIVG", + "H\\MMM[ NMN[ JMQM NTPTSSTRVNWMXMYNXOWN PTSUTVVZW[ PTRUSVUZV[X[YZZX J[Q[", + "G]NMNQMWLZK[J[IZJYKZ WMW[ XMX[ KM[M T[[[", + "G^LML[ LMR[ MMRY XMR[ XMX[ YMY[ IMMM XM\\M I[O[ U[\\[", + "G]LML[ MMM[ WMW[ XMX[ IMPM TM[M MTWT I[P[ T[[[", + "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM QMONMPLSLUMXOZQ[ S[UZWXXUXSWPUNSM", + "G]LML[ MMM[ WMW[ XMX[ IM[M I[P[ T[[[", + "G\\LMLb MMMb MPONQMSMVNXPYSYUXXVZS[Q[OZMX SMUNWPXSXUWXUZS[ IMMM IbPb", + "H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX QMONMPLSLUMXOZQ[", + "I\\RMR[ SMS[ MMLRLMYMYRXM O[V[", + "I[LMR[ MMRY XMR[P_NaLbKbJaK`La JMPM TMZM", + "H]RFRb SFSb OFSF RPQNPMNMLNKQKWLZN[P[QZRX NMMNLQLWMZN[ WMXNYQYWXZW[ SPTNUMWMYNZQZWYZW[U[TZSX ObVb", + "H\\LMW[ MMX[ XML[ JMPM TMZM J[P[ T[Z[", + "G]LML[ MMM[ WMW[ XMX[ IMPM TM[M I[[[[`Z[", + "G]LMLTMVPWRWUVWT MMMTNVPW WMW[ XMX[ IMPM TM[M T[[[", + "CbHMH[ IMI[ RMR[ SMS[ \\M\\[ ]M][ EMLM OMVM YM`M E[`[", + "CbHMH[ IMI[ RMR[ SMS[ \\M\\[ ]M][ EMLM OMVM YM`M E[`[``_[", + "H]QMQ[ RMR[ LMKRKMUM RTVTYUZWZXYZV[N[ VTXUYWYXXZV[", + "E_JMJ[ KMK[ GMNM KTOTRUSWSXRZO[G[ OTQURWRXQZO[ YMY[ ZMZ[ VM]M V[][", + "J[OMO[ PMP[ LMSM PTTTWUXWXXWZT[L[ TTVUWWWXVZT[", + "I\\MOLMLQMONNPMSMVNXPYSYUXXVZS[P[NZLXLWMVNWMX SMUNWPXSXUWXUZS[ RTXT", + "DaIMI[ JMJ[ FMMM F[M[ VMSNQPPSPUQXSZV[X[[Z]X^U^S]P[NXMVM VMTNRPQSQURXTZV[ X[ZZ\\X]U]S\\PZNXM JTPT", + "G\\VMV[ WMW[ ZMOMLNKPKQLSOTVT OMMNLPLQMSOT TTQUPVNZM[ TTRUQVOZN[L[KZJX S[Z[", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "H\\RFKZ QIW[ RIX[ RFY[ MUVU I[O[ T[[[ KZJ[ KZM[ WZU[ WYV[ XYZ[", + "G]LFL[ MGMZ NFN[ IFUFXGYHZJZLYNXOUP XHYJYLXN UFWGXIXMWOUP NPUPXQYRZTZWYYXZU[I[ XRYTYWXY UPWQXSXXWZU[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "G\\XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXXYV MILKKNKSLVMX QFOGMJLNLSMWOZQ[", + "G]LFL[ MGMZ NFN[ IFSFVGXIYKZNZSYVXXVZS[I[ WIXKYNYSXVWX SFUGWJXNXSWWUZS[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "G\\LFL[ MGMZ NFN[ IFYFYL NPTP TLTT I[Y[YU JFLG KFLH OFNH PFNG TFYG VFYH WFYI XFYL TLSPTT TNRPTR TOPPTQ LZJ[ LYK[ NYO[ NZP[ T[YZ V[YY W[YX X[YU", + "G[LFL[ MGMZ NFN[ IFYFYL NPTP TLTT I[Q[ JFLG KFLH OFNH PFNG TFYG VFYH WFYI XFYL TLSPTT TNRPTR TOPPTQ LZJ[ LYK[ NYO[ NZP[", + "G^XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXZY[YS MILKKNKSLVMX QFOGMJLNLSMWOZQ[ XTXY WSWYVZ TS\\S USWT VSWU ZSYU [SYT", + "F^KFK[ LGLZ MFM[ WFW[ XGXZ YFY[ HFPF TF\\F MPWP H[P[ T[\\[ IFKG JFKH NFMH OFMG UFWG VFWH ZFYH [FYG KZI[ KYJ[ MYN[ MZO[ WZU[ WYV[ YYZ[ YZ[[", + "LXQFQ[ RGRZ SFS[ NFVF N[V[ OFQG PFQH TFSH UFSG QZO[ QYP[ SYT[ SZU[", + "JZSFSWRZQ[ TGTWSZ UFUWTZQ[O[MZLXLVMUNUOVOWNXMX MVMWNWNVMV PFXF QFSG RFSH VFUH WFUG", + "F\\KFK[ LGLZ MFM[ XGMR PPW[ QPX[ QNY[ HFPF UF[F H[P[ T[[[ IFKG JFKH NFMH OFMG WFXG ZFXG KZI[ KYJ[ MYN[ MZO[ WYU[ WYZ[", + "I[NFN[ OGOZ PFP[ KFSF K[Z[ZU LFNG MFNH QFPH RFPG NZL[ NYM[ PYQ[ PZR[ U[ZZ W[ZY X[ZX Y[ZU", + "E_JFJZ JFQ[ KFQX LFRX XFQ[ XFX[ YGYZ ZFZ[ GFLF XF]F G[M[ U[][ HFJG [FZH \\FZG JZH[ JZL[ XZV[ XYW[ ZY[[ ZZ\\[", + "F^KFKZ KFY[ LFXX MFYX YGY[ HFMF VF\\F H[N[ IFKG WFYG [FYG KZI[ KZM[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF MILKKNKSLVMX WXXVYSYNXKWI QFOGMJLNLSMWOZQ[ S[UZWWXSXNWJUGSF", + "G]LFL[ MGMZ NFN[ IFUFXGYHZJZMYOXPUQNQ XHYJYMXO UFWGXIXNWPUQ I[Q[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF MILKKNKSLVMX WXXVYSYNXKWI QFOGMJLNLSMWOZQ[ S[UZWWXSXNWJUGSF NXOVQURUTVUXV^W`Y`Z^Z\\ V\\W^X_Y_ UXW]X^Y^Z]", + "G]LFL[ MGMZ NFN[ IFUFXGYHZJZLYNXOUPNP XHYJYLXN UFWGXIXMWOUP RPTQUSWYX[Z[[Y[W WWXYYZZZ TQURXXYYZY[X I[Q[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "H\\XIYFYLXIVGSFPFMGKIKLLNOPURWSXUXXWZ LLMNOOUQWRXT MGLILKMMONUPXRYTYWXYWZT[Q[NZLXKUK[LX", + "H\\JFJL QFQ[ RGRZ SFS[ ZFZL JFZF N[V[ KFJL LFJI MFJH OFJG UFZG WFZH XFZI YFZL QZO[ QYP[ SYT[ SZU[", + "F^KFKULXNZQ[S[VZXXYUYG LGLVMX MFMVNYOZQ[ HFPF VF\\F IFKG JFKH NFMH OFMG WFYG [FYG", + "H\\KFR[ LFRXR[ MFSX YGR[ IFPF UF[F JFLH NFMH OFMG WFYG ZFYG", + "F^JFN[ KFNVN[ LFOV RFOVN[ RFV[ SFVVV[ TFWV ZGWVV[ GFOF RFTF WF]F HFKG IFKH MFLH NFLG XFZG \\FZG", + "H\\KFW[ LFX[ MFY[ XGLZ IFPF UF[F I[O[ T[[[ JFMH NFMH OFMG VFXG ZFXG LZJ[ LZN[ WZU[ WYV[ WYZ[", + "G]JFQQQ[ KFRQRZ LFSQS[ YGSQ HFOF VF\\F N[V[ IFKG NFLG WFYG [FYG QZO[ QYP[ SYT[ SZU[", + "H\\YFKFKL WFK[ XFL[ YFM[ K[Y[YU LFKL MFKI NFKH PFKG T[YZ V[YY W[YX X[YU", + "H\\RFKZ QIW[ RIX[ RFY[ MUVU I[O[ T[[[ KZJ[ KZM[ WZU[ WYV[ XYZ[", + "G]LFL[ MGMZ NFN[ IFUFXGYHZJZLYNXOUP XHYJYLXN UFWGXIXMWOUP NPUPXQYRZTZWYYXZU[I[ XRYTYWXY UPWQXSXXWZU[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "I[NFN[ OGOZ PFP[ KFZFZL K[S[ LFNG MFNH QFPH RFPG UFZG WFZH XFZI YFZL NYM[ NZL[ PYQ[ PZR[", + "H\\RFJ[ QIX[ RIY[ RFZ[ KYXY KZXZ J[Z[", + "G\\LFL[ MGMZ NFN[ IFYFYL NPTP TLTT I[Y[YU JFLG KFLH OFNH PFNG TFYG VFYH WFYI XFYL TLSPTT TNRPTR TOPPTQ LZJ[ LYK[ NYO[ NZP[ T[YZ V[YY W[YX X[YU", + "H\\YFKFKL WFK[ XFL[ YFM[ K[Y[YU LFKL MFKI NFKH PFKG T[YZ V[YY W[YX X[YU", + "F^KFK[ LGLZ MFM[ WFW[ XGXZ YFY[ HFPF TF\\F MPWP H[P[ T[\\[ IFKG JFKH NFMH OFMG UFWG VFWH ZFYH [FYG KZI[ KYJ[ MYN[ MZO[ WZU[ WYV[ YYZ[ YZ[[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF MILKKNKSLVMX WXXVYSYNXKWI QFOGMJLNLSMWOZQ[ S[UZWWXSXNWJUGSF OMOT UMUT OPUP OQUQ ONPP OOQP UNTP UOSP PQOS QQOR SQUR TQUS", + "LXQFQ[ RGRZ SFS[ NFVF N[V[ OFQG PFQH TFSH UFSG QZO[ QYP[ SYT[ SZU[", + "F\\KFK[ LGLZ MFM[ XGMR PPW[ QPX[ QNY[ HFPF UF[F H[P[ T[[[ IFKG JFKH NFMH OFMG WFXG ZFXG KZI[ KYJ[ MYN[ MZO[ WYU[ WYZ[", + "H\\RFKZ QIW[ RIX[ RFY[ I[O[ T[[[ KZJ[ KZM[ WZU[ WYV[ XYZ[", + "E_JFJZ JFQ[ KFQX LFRX XFQ[ XFX[ YGYZ ZFZ[ GFLF XF]F G[M[ U[][ HFJG [FZH \\FZG JZH[ JZL[ XZV[ XYW[ ZY[[ ZZ\\[", + "F^KFKZ KFY[ LFXX MFYX YGY[ HFMF VF\\F H[N[ IFKG WFYG [FYG KZI[ KZM[", + "G]JEJL ZEZL OMOT UMUT JUJ\\ ZUZ\\ JGZG JHZH JIZI OPUP OQUQ JXZX JYZY JZZZ JFMH ZFWH KIJK LIJJ XIZJ YIZK ONPP OOQP UNTP UOSP PQOS QQOR SQUR TQUS JVKX JWLX ZWXX ZVYX MYJ[ WYZ[", + "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF MILKKNKSLVMX WXXVYSYNXKWI QFOGMJLNLSMWOZQ[ S[UZWWXSXNWJUGSF", + "F^KFK[ LGLZ MFM[ WFW[ XGXZ YFY[ HF\\F H[P[ T[\\[ IFKG JFKH NFMH OFMG UFWG VFWH ZFYH [FYG KZI[ KYJ[ MYN[ MZO[ WZU[ WYV[ YYZ[ YZ[[", + "G]LFL[ MGMZ NFN[ IFUFXGYHZJZMYOXPUQNQ XHYJYMXO UFWGXIXNWPUQ I[Q[ JFLG KFLH OFNH PFNG LZJ[ LYK[ NYO[ NZP[", + "G]IFPPQQ JFQP KFRPI[ IFYFZLYIWF VFYH TFYG KYYY JZYZ I[Y[ZUYXWY", + "H\\JFJL QFQ[ RGRZ SFS[ ZFZL JFZF N[V[ KFJL LFJI MFJH OFJG UFZG WFZH XFZI YFZL QZO[ QYP[ SYT[ SZU[", + "H\\JMKILGMFOFPGQIRM LHMGOGPH JMKJMHOHPIQMQ[ RMR[ ZMYJWHUHTISMS[ XHWGUGTH ZMYIXGWFUFTGSIRM N[V[ QYP[ QZO[ SZU[ SYT[", + "G]QFQ[ RGRZ SFS[ NFVF N[V[ OFQG PFQH TFSH UFSG QZO[ QYP[ SYT[ SZU[ OKLLKMJOJRKTLUOVUVXUYTZRZOYMXLUKOK LMKOKRLT XTYRYOXM OKMLLOLRMUOV UVWUXRXOWLUK", + "H\\KFW[ LFX[ MFY[ XGLZ IFPF UF[F I[O[ T[[[ JFMH NFMH OFMG VFXG ZFXG LZJ[ LZN[ WZU[ WYV[ WYZ[", + "F^QFQ[ RGRZ SFS[ NFVF N[V[ OFQG PFQH TFSH UFSG QZO[ QYP[ SYT[ SZU[ HMIMJNKQLSMTPUTUWTXSYQZN[M\\M LRKNJLILKN HMIKJKKLLPMSNTPU YN[LZLYNXR TUVTWSXPYLZK[K\\M", + "G]NYKYJWK[O[MVKRJOJLKIMGPFTFWGYIZLZOYRWVU[Y[ZWYYVY LSKOKLLI XIYLYOXS O[MULPLKMHNGPF TFVGWHXKXPWUU[ KZNZ VZYZ", + "H\\UFIZ SJT[ THUZ UFUHVYV[ LUTU F[L[ Q[X[ IZG[ IZK[ TZR[ TYS[ VYW[", + "F^OFI[ PFJ[ QFK[ LFWFZG[I[KZNYOVP YGZIZKYNXO WFXGYIYKXNVP NPVPXQYSYUXXVZR[F[ WQXSXUWXUZ VPWRWUVXTZR[ MFPG NFOH RFPH SFPG JZG[ JYH[ KYL[ JZM[", + "H]ZH[H\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV QHOJNLMOLSLWMY TFRGPJOLNOMSMXNZP[", + "F]OFI[ PFJ[ QFK[ LFUFXGYHZKZOYSWWUYSZO[F[ WGXHYKYOXSVWTY UFWHXKXOWSUWRZO[ MFPG NFOH RFPH SFPG JZG[ JYH[ KYL[ JZM[", + "F]OFI[ PFJ[ QFK[ ULST LF[FZL NPTP F[U[WV MFPG NFOH RFPH SFPG WFZG XFZH YFZI ZFZL ULSPST TNRPSR TOQPSQ JZG[ JYH[ KYL[ JZM[ P[UZ R[UY UYWV", + "F\\OFI[ PFJ[ QFK[ ULST LF[FZL NPTP F[N[ MFPG NFOH RFPH SFPG WFZG XFZH YFZI ZFZL ULSPST TNRPSR TOQPSQ JZG[ JYH[ KYL[ JZM[", + "H^ZH[H\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT QHOJNLMOLSLWMY VXWWXT TFRGPJOLNOMSMXNZP[ R[TZVWWT TT\\T UTWU VTWW ZTXV [TXU", + "E_NFH[ OFI[ PFJ[ ZFT[ [FU[ \\FV[ KFSF WF_F LPXP E[M[ Q[Y[ LFOG MFNH QFOH RFOG XF[G YFZH ]F[H ^F[G IZF[ IYG[ JYK[ IZL[ UZR[ UYS[ VYW[ UZX[", + "KYTFN[ UFO[ VFP[ QFYF K[S[ RFUG SFTH WFUH XFUG OZL[ OYM[ PYQ[ OZR[", + "I\\WFRWQYO[ XFTSSVRX YFUSSXQZO[M[KZJXJVKULUMVMWLXKX KVKWLWLVKV TF\\F UFXG VFWH ZFXH [FXG", + "F]OFI[ PFJ[ QFK[ \\GMR QOU[ ROV[ SNWZ LFTF YF_F F[N[ R[Y[ MFPG NFOH RFPH SFPG ZF\\G ^F\\G JZG[ JYH[ KYL[ JZM[ UZS[ UYT[ VYX[", + "H\\QFK[ RFL[ SFM[ NFVF H[W[YU OFRG PFQH TFRH UFRG LZI[ LYJ[ MYN[ LZO[ R[WZ T[XX V[YU", + "D`MFGZ MGNYN[ NFOY OFPX [FPXN[ [FU[ \\FV[ ]FW[ JFOF [F`F D[J[ R[Z[ KFMG LFMH ^F\\H _F\\G GZE[ GZI[ VZS[ VYT[ WYX[ VZY[", + "F_OFIZ OFV[ PFVX QFWX \\GWXV[ LFQF YF_F F[L[ MFPG NFPH ZF\\G ^F\\G IZG[ IZK[", + "G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF OIMLLOKSKWLY UXWUXRYNYJXH SFQGOJNLMOLSLXMZN[ Q[SZUWVUWRXNXIWGVF", + "F]OFI[ PFJ[ QFK[ LFXF[G\\I\\K[NYPUQMQ ZG[I[KZNXP XFYGZIZKYNWPUQ F[N[ MFPG NFOH RFPH SFPG JZG[ JYH[ KYL[ JZM[", + "G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF OIMLLOKSKWLY UXWUXRYNYJXH SFQGOJNLMOLSLXMZN[ Q[SZUWVUWRXNXIWGVF LXMVOUPURVSXT]U^V^W] T^U_V_ SXS_T`V`W]W\\", + "F^OFI[ PFJ[ QFK[ LFWFZG[I[KZNYOVPNP YGZIZKYNXO WFXGYIYKXNVP RPTQURWXXYYYZX WYXZYZ URVZW[Y[ZXZW F[N[ MFPG NFOH RFPH SFPG JZG[ JYH[ KYL[ JZM[", + "G^ZH[H\\F[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ NLONVRWT OGNINKOMUPWRXTXWWYVZS[O[LZKYJWJUI[JYKY", + "G]TFN[ UFO[ VFP[ MFKL ]F\\L MF]F K[S[ NFKL PFLI RFMG YF\\G ZF\\H [F\\I \\F\\L OZL[ OYM[ PYQ[ OZR[", + "F_NFKQJUJXKZN[R[UZWXXU\\G OFLQKUKYLZ PFMQLULYN[ KFSF YF_F LFOG MFNH QFOH RFOG ZF\\G ^F\\G", + "H\\NFNHOYO[ OGPX PFQW [GO[ LFSF XF^F MFNH QFPH RFOG YF[G ]F[G", + "E_MFMHKYK[ NGLX OFMW UFMWK[ UFUHSYS[ VGTX WFUW ]GUWS[ JFRF UFWF ZF`F KFNG LFMH PFNI QFNG [F]G _F]G", + "G]NFT[ OFU[ PFV[ [GIZ LFSF XF^F F[L[ Q[X[ MFOH QFPH RFPG YF[G ]F[G IZG[ IZK[ TZR[ TYS[ UYW[", + "G]MFQPN[ NFRPO[ OFSPP[ \\GSP KFRF YF_F K[S[ LFNG PFOH QFNG ZF\\G ^F\\G OZL[ OYM[ PYQ[ OZR[", + "G]ZFH[ [FI[ \\FJ[ \\FNFLL H[V[XU OFLL PFMI RFNG R[VZ T[WX U[XU", + "", + "", + "", + "", + "", + "", + "H\\JFR[ KFRX LFSX JFZFR[ LGYG LHYH", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "I]NPNOOOOQMQMONNPMTMVNWOXQXXYZZ[ VOWQWXXZ TMUNVPVXWZZ[[[ VRUSPTMULWLXMZP[S[UZVX NUMWMXNZ USQTOUNWNXOZP[", + "G\\LFL[MZOZ MGMY IFNFNZ NPONQMSMVNXPYSYUXXVZS[Q[OZNX WPXRXVWX SMUNVOWRWVVYUZS[ JFLG KFLH", + "H[WQWPVPVRXRXPVNTMQMNNLPKSKULXNZQ[S[VZXX MPLRLVMX QMONNOMRMVNYOZQ[", + "H]VFV[[[ WGWZ SFXFX[ VPUNSMQMNNLPKSKULXNZQ[S[UZVX MPLRLVMX QMONNOMRMVNYOZQ[ TFVG UFVH XYY[ XZZ[", + "H[MSXSXQWOVNSMQMNNLPKSKULXNZQ[S[VZXX WRWQVO MPLRLVMX VSVPUNSM QMONNOMRMVNYOZQ[", + "KYWHWGVGVIXIXGWFTFRGQHPKP[ RHQKQZ TFSGRIR[ MMVM M[U[ PZN[ PYO[ RYS[ RZT[", + "I\\XNYOZNYMXMVNUO QMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM OONQNSOU UUVSVQUO QMPNOPOTPVQW SWTVUTUPTNSM NUMVLXLYM[N\\Q]U]X^Y_ N[Q\\U\\X] LYMZP[U[X\\Y^Y_XaUbObLaK_K^L\\O[ ObMaL_L^M\\O[", + "G^LFL[ MGMZ IFNFN[ NQOOPNRMUMWNXOYRY[ WOXRXZ UMVNWQW[ I[Q[ T[\\[ JFLG KFLH LZJ[ LYK[ NYO[ NZP[ WZU[ WYV[ YYZ[ YZ[[", + "LXQFQHSHSFQF RFRH QGSG QMQ[ RNRZ NMSMS[ N[V[ OMQN PMQO QZO[ QYP[ SYT[ SZU[", + "KXRFRHTHTFRF SFSH RGTG RMR^QaPb SNS]R` OMTMT]S`RaPbMbLaL_N_NaMaM` PMRN QMRO", + "G]LFL[ MGMZ IFNFN[ WNNW RSY[ RTX[ QTW[ TM[M I[Q[ T[[[ JFLG KFLH UMWN ZMWN LZJ[ LYK[ NYO[ NZP[ WYU[ VYZ[", + "LXQFQ[ RGRZ NFSFS[ N[V[ OFQG PFQH QZO[ QYP[ SYT[ SZU[", + "AcFMF[ GNGZ CMHMH[ HQIOJNLMOMQNROSRS[ QORRRZ OMPNQQQ[ SQTOUNWMZM\\N]O^R^[ \\O]R]Z ZM[N\\Q\\[ C[K[ N[V[ Y[a[ DMFN EMFO FZD[ FYE[ HYI[ HZJ[ QZO[ QYP[ SYT[ SZU[ \\ZZ[ \\Y[[ ^Y_[ ^Z`[", + "G^LML[ MNMZ IMNMN[ NQOOPNRMUMWNXOYRY[ WOXRXZ UMVNWQW[ I[Q[ T[\\[ JMLN KMLO LZJ[ LYK[ NYO[ NZP[ WZU[ WYV[ YYZ[ YZ[[", + "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM MPLRLVMX WXXVXRWP QMONNOMRMVNYOZQ[ S[UZVYWVWRVOUNSM", + "G\\LMLb MNMa IMNMNb NPONQMSMVNXPYSYUXXVZS[Q[OZNX WPXRXVWX SMUNVOWRWVVYUZS[ IbQb JMLN KMLO LaJb L`Kb N`Ob NaPb", + "H\\VNVb WOWa UNWNXMXb VPUNSMQMNNLPKSKULXNZQ[S[UZVX MPLRLVMX QMONNOMRMVNYOZQ[ Sb[b VaTb V`Ub X`Yb XaZb", + "IZNMN[ ONOZ KMPMP[ WOWNVNVPXPXNWMUMSNQPPS K[S[ LMNN MMNO NZL[ NYM[ PYQ[ PZR[", + "J[WOXMXQWOVNTMPMNNMOMQNSPTUUWVXY NNMQ NRPSUTWU XVWZ MONQPRUSWTXVXYWZU[Q[OZNYMWM[NY", + "KZPHPVQYRZT[V[XZYX QHQWRY PHRFRWSZT[ MMVM", + "G^LMLVMYNZP[S[UZVYWW MNMWNY IMNMNWOZP[ WMW[\\[ XNXZ TMYMY[ JMLN KMLO YYZ[ YZ[[", + "I[LMR[ MMRY NMSY XNSYR[ JMQM TMZM KMNO PMNN VMXN YMXN", + "F^JMN[ KMNX LMOX RMOXN[ RMV[ SMVX RMTMWX ZNWXV[ GMOM WM]M HMKN NMLN XMZN \\MZN", + "H\\LMV[ MMW[ NMX[ WNMZ JMQM TMZM J[P[ S[Z[ KMMN PMNN UMWN YMWN MZK[ MZO[ VZT[ WZY[", + "H[LMR[ MMRY NMSY XNSYP_NaLbJbIaI_K_KaJaJ` JMQM TMZM KMNO PMNN VMXN YMXN", + "I[VML[ WMM[ XMN[ XMLMLQ L[X[XW MMLQ NMLP OMLO QMLN S[XZ U[XY V[XX W[XW", + "G^[MZQYTWXUZR[P[MZKXJUJSKPMNPMRMUNVOWQYXZZ[[\\[ ZMYQXTWVUYTZR[ LXKVKRLP P[NZMYLVLRMONNPM RMTNUOVQXXYZ[[", + "G\\QFNGMHLJKNKb NHMJLNLa QFOGNIMNMb QFSFVGWHXJXLWNVOSP PPTPWQXRYTYWXYWZT[Q[OZNYMW VHWJWLVN WRXTXWWY SFUGVIVMUOSP TPVQWSWXVZT[ KbMb", + "F\\HRINKMMMONPOQRRYSb IOKNMNOOPP HRIPKOMOOPPQQTRYRa XMWPVRTUSWR[Qb YMWQ ZMYOWRTVSXR[ XMZM QbSb", + "H\\SMQMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMPLNKMJMHNGPFSFWH MPLSLUMX WXXUXSWP QMONNOMRMVNYOZQ[ S[UZVYWVWRVOUNOKNJNIOHQGTGWH", + "I[SMUNVOWOVNSMQMMNLOLQMRQS SSQSMTKVKXMZP[S[VZXXWXVZ NNMOMQNR MULVLXMY QMONNONQORQS QSNTMVMXNZP[", + "I[QHRGRFQFPGPIQJTKXKYKYJXJUKSLPNNPMRLULWMYNZP[S\\U]V_VaUbSbRaR`S`Sa POOPNRMUMWNYOZ UKRMQNOQNTNWOYQ[S\\", + "G]JMKNLPL[ KMLNMPMZ HPINJMLMMNNPN[ UMVNWQWb WOXRXa NQOOPNRMUMWNXOYRYb L[N[ WbYb", + "F]IMJNKPKTLWMYNZQ[S[VZWYXWYRYOXJVGTFRFPGOIOKPMSOVP[Q JMKNLPLTMWNY VYWWXRXOWJVHTG GPHNIMKMLNMPMTNXOZQ[ S[UZVXWSWNVJUHSGQGOI", + "KZNMONPPPXQZS[U[WZXX OMPNQPQXRZ LPMNNMPMQNRPRXSZT[", + "G]JMKNLPL[ KMLNMPMZ HPINJMLMMNNPN[ SOUNWNXOXPZPZNXMVMTNQQOTNW XNYOYP PSQSWYYYZX TWWZYZ RTUZV[X[YZZX L[N[", + "H\\JGKFMFOGQIXXYZZ[ OHPIWXXY MFNGOIVXXZZ[[[ RMJZJ[K[RM", + "G]KMKb LNLa MMMb VMVXWZX[Z[[Z\\X WNWXXZY[ XMXXYZZ[ MXNZP[R[TZUYVW KMMM VMXM KbMb", + "G]JMKNLPMTN[ KMLNMPNTOZ HPINJMLMMNNPOTPZ VVWTXQXMYMZNYQXSVVTXQZN[ XRYOYM", + "JZPGSFRFPGOHOIPJSKVLWKVJSKPLNMMOMQNRPSSTVUWTVSSTOUMVLXLZM[O\\S]U^V_VaTbRbOaPaRb OMNONQOR NVMXMZN[ VKSKQLPMOOOQQSST VTSTPUOVNXNZP\\S]", + "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM MPLRLVMX WXXVXRWP QMONNOMRMVNYOZQ[ S[UZVYWVWRVOUNSM", + "G]IQJOKNMM[M KOMNZN IQJPLO[O OONZM[LZMWOO UOVZW[XZWWUO [M[O OOMZ UOWZ", + "G\\QMNNLPKTKb MPLTLa QMONNOMSMb MWNYOZQ[S[VZXXYUYSXPVNSMQM WXXVXRWP S[UZVYWVWRVOUNSM KbMb", + "G]PMMNKPJSJUKXMZP[R[UZWXXUXSWPUNRM LPKRKVLX VXWVWRVP PMNNMOLRLVMYNZP[ R[TZUYVVVRUOTNRM RMZO[N[MPM RMZN", + "H\\JQKOLNNMZM LONNYN JQKPMOZO ROQZR[SZRO ZMZO RORZ", + "G\\JMKNLPLUMXOZQ[S[UZWXXVYRYNXMWMXPXSWWUZ KMLNMPMUNX WMXNXO HPINJMLMMNNPNVOYQ[", + "G]RQQNPMNMLNKOJRJUKXMZP[T[WZYXZUZRYOXNVMTMSNRQ LOKRKULX XXYUYRXO NMMNLQLVMYNZP[ T[VZWYXVXQWNVM RQQb RQRa RQSb QbSb", + "H\\LMMNNPT_VaXbZb[a NOOPU_V` INJMLMNNPPV_WaXb VSXPYMZMYOVSN\\K`JbKbL_N\\", + "F]HNINJPJUKXMZP[T[VZXXYVZRZNYMXMYPYSXWVZ JNKPKULX XMYNYO GPHNIMJMKNLPLVMYNZP[ QFSb RGRa SFQb QFSF QbSb", + "F^NMLNJPISIWJYKZM[O[QZRYSWSTRSQTQWRYSZU[W[YZZY[W[SZPXNVM KPJSJWKY RTRX YYZWZSYP NMLOKRKWLZM[ W[XZYWYRXOVM", + "G]WMUTUXVZW[Y[[Y\\W XMVTVZ WMYMWTVX UTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT NNLQKTKWLY PMNOMQLTLWMZN[", + "I\\PFNMMSMWNYOZQ[S[VZXWYTYRXOWNUMSMQNPOOQNT QFOMNQNWOZ VYWWXTXQWO MFRFPMNT S[UYVWWTWQVNUM NFQG OFPH", + "I[WQWPVPVRXRXPWNUMRMONMQLTLVMYNZP[R[UZWW OONQMTMWNY RMPOOQNTNWOZP[", + "G]YFVQUUUXVZW[Y[[Y\\W ZFWQVUVZ VF[FWTVX UTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT MOLQKTKWLY PMNOMQLTLWMZN[ WFZG XFYH", + "I[MVQUTTWRXPWNUMRMONMQLTLVMYNZP[R[UZWX OONQMTMWNY RMPOOQNTNWOZP[", + "JZZHZGYGYI[I[GZFXFVGTISKRNQRO[N^M`Kb TJSMRRP[O^ XFVHUJTMSRQZP]O_MaKbIbHaH_J_JaIaI` NMYM", + "H]XMT[S^QaOb YMU[S_ XMZMV[T_RaObLbJaI`I^K^K`J`J_ VTVQUNSMQMNNLQKTKVLYMZO[Q[SZTYUWVT NOMQLTLWMY QMOONQMTMWNZO[", + "G]OFI[K[ PFJ[ LFQFK[ MTOPQNSMUMWNXPXSVX WNWRVVVZ WPUUUXVZW[Y[[Y\\W MFPG NFOH", + "KXTFTHVHVFTF UFUH TGVG LQMOOMQMRNSPSSQX RNRRQVQZ RPPUPXQZR[T[VYWW", + "KXUFUHWHWFUF VFVH UGWG MQNOPMRMSNTPTSRZQ]P_NaLbJbIaI_K_KaJaJ` SNSSQZP]O_ SPRTP[O^N`Lb", + "G]OFI[K[ PFJ[ LFQFK[ YOYNXNXPZPZNYMWMUNQROS MSOSQTRUTYUZWZ QUSYTZ OSPTRZS[U[WZYW MFPG NFOH", + "LXTFQQPUPXQZR[T[VYWW UFRQQUQZ QFVFRTQX RFUG SFTH", + "@cAQBODMFMGNHPHSF[ GNGSE[ GPFTD[F[ HSJPLNNMPMRNSPSSQ[ RNRSP[ RPQTO[Q[ SSUPWNYM[M]N^P^S\\X ]N]R\\V\\Z ]P[U[X\\Z][_[aYbW", + "F^GQHOJMLMMNNPNSL[ MNMSK[ MPLTJ[L[ NSPPRNTMVMXNYPYSWX XNXRWVWZ XPVUVXWZX[Z[\\Y]W", + "H\\QMNNLQKTKVLYMZP[S[VZXWYTYRXOWNTMQM NOMQLTLWMY VYWWXTXQWO QMOONQMTMWNZP[ S[UYVWWTWQVNTM", + "G]HQIOKMMMNNOPOSNWKb NNNSMWJb NPMTIb OTPQQORNTMVMXNYOZRZTYWWZT[R[PZOWOT XOYQYTXWWY VMWNXQXTWWVYT[ FbNb JaGb J`Hb K`Lb JaMb", + "G\\WMQb XMRb WMYMSb UTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT MOLQKTKWLY PMNOMQLTLWMZN[ NbVb RaOb R`Pb S`Tb RaUb", + "I[JQKOMMOMPNQPQTO[ PNPTN[ PPOTM[O[ YOYNXNXPZPZNYMWMUNSPQT", + "J[XPXOWOWQYQYOXNUMRMONNONQOSQTTUVVWX ONNQ ORQSTTVU WVVZ NOOQQRTSVTWVWXVZS[P[MZLYLWNWNYMYMX", + "KYTFQQPUPXQZR[T[VYWW UFRQQUQZ TFVFRTQX NMXM", + "F^GQHOJMLMMNNPNSLX MNMRLVLZ MPKUKXLZN[P[RZTXVU XMVUVXWZX[Z[\\Y]W YMWUWZ XMZMXTWX", + "H\\IQJOLMNMONPPPSNX ONORNVNZ OPMUMXNZP[R[TZVXXUYQYMXMXNYP", + "CaDQEOGMIMJNKPKSIX JNJRIVIZ JPHUHXIZK[M[OZQXRU TMRURXSZU[W[YZ[X]U^Q^M]M]N^P UMSUSZ TMVMTTSX", + "G]JQLNNMPMRNSPSR PMQNQRPVOXMZK[I[HZHXJXJZIZIY RORRQVQY ZOZNYNYP[P[NZMXMVNTPSRRVRZS[ PVPXQZS[U[WZYW", + "G]HQIOKMMMNNOPOSMX NNNRMVMZ NPLULXMZO[Q[SZUXWT YMU[T^RaPb ZMV[T_ YM[MW[U_SaPbMbKaJ`J^L^L`K`K_", + "H\\YMXOVQNWLYK[ XOOOMPLR VORNONNO VORMOMMOLR LYUYWXXV NYRZUZVY NYR[U[WYXV", + "", + "", + "", + "", + "", + "", + "H\\WQVOUNSMQMNNLPKSKULXNZQ[S[VZWYXWYSYNXJWHVGSFQFNGMHNHOGQF MPLRLVMX VYWWXSXNWJVH QMONNOMRMVNYOZQ[ S[UZVXWTWMVIUGSF", + "I[UMWNXOYOXNUMRMONMPLSLUMXOZR[U[XZYYXYWZU[ NPMSMUNX RMPNOONRNVOYPZR[ NTTUUTTSNT NTTT", + "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF NHMJLNLSMWNY VYWWXSXNWJVH QFOGNIMNMSNXOZQ[ S[UZVXWSWNVIUGSF LPXQ LQXP", + "G]PMMNKPJSJUKXMZP[T[WZYXZUZSYPWNTMPM LPKSKULX XXYUYSXP PMNNMOLRLVMYNZP[T[VZWYXVXRWOVNTM QFSb RGRa SFQb QFSF QbSb", + "H\\TMVNXPYPYOWNTMPMMNLOKQKSLUNWPXRYSZT\\T^S_Q_O^P^Q_ MOLQLSMUOW PMNNMPMSNURY YPXO", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NV", + "JZ", + "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF NHMJLNLSMWNY VYWWXSXNWJVH QFOGNIMNMSNXOZQ[ S[UZVXWSWNVIUGSF", + "H\\QHQ[ RHRZ SFS[ SFPINJ M[W[ QZO[ QYP[ SYT[ SZU[", + "H\\LJLKMKMJLJ LIMINJNKMLLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ WHXJXLWN TFVGWJWLVNTPPR KYLXNXSYWYYX NXSZWZXY NXS[W[XZYXYV", + "H\\LJLKMKMJLJ LIMINJNKMLLLKKKJLHMGPFTFWGXIXLWNTO VGWIWLVN SFUGVIVLUNSO QOTOVPXRYTYWXYWZT[P[MZLYKWKVLUMUNVNWMXLX WRXTXWWY SOUPVQWTWWVZT[ LVLWMWMVLV", + "H\\SIS[ THTZ UFU[ UFJUZU P[X[ SZQ[ SYR[ UYV[ UZW[", + "H\\MFKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMUNVNWMXLX WPXRXVWX SMUNVOWRWVVYUZS[ LVLWMWMVLV MFWF MGUG MHQHUGWF", + "H\\VIVJWJWIVI WHVHUIUJVKWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNQNOONPMR NIMKLOLUMXNY WXXVXSWQ RFPGOHNJMNMUNXOZQ[ S[UZVYWVWSVPUOSN", + "H\\KFKL YFYIXLTQSSRWR[ SRRTQWQ[ XLSQQTPWP[R[ KJLHNFPFUIWIXHYF MHNGPGRH KJLINHPHUI", + "H\\PFMGLILLMNPOTOWNXLXIWGTFPF NGMIMLNN VNWLWIVG PFOGNINLONPO TOUNVLVIUGTF POMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO MQLSLWMY WYXWXSWQ PONPMSMWNZP[ T[VZWWWSVPTO", + "H\\MWMXNXNWMW WOVQURSSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNVOWOXNYMY MPLNLKMI VHWIXLXRWVVX QSORNQMNMKNHOGQF SFUGVIWLWSVWUYTZR[", + "MXRXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXTZS[R[QZQYRXSXTYT\\S^Q_ RYRZSZSYRY S[T\\ TZS^", + "MXRMQNQORPSPTOTNSMRM RNROSOSNRN RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXRMQNQORPSPTOTNSMRM RNROSOSNRN TZS[R[QZQYRXSXTYT\\S^Q_ RYRZSZSYRY S[T\\ TZS^", + "MXRFQGQIRQ RFRTST RFSFST SFTGTISQ RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "I\\MKMJNJNLLLLJMHNGPFTFWGXHYJYLXNWOSQ WHXIXMWN TFVGWIWMVOUP RQRTSTSQRQ RXQYQZR[S[TZTYSXRX RYRZSZSYRY", + "MXTFRGQIQLRMSMTLTKSJRJQK RKRLSLSKRK RGQK QIRJ", + "MXTHSIRIQHQGRFSFTGTJSLQM RGRHSHSGRG SITJ THSL", + "E_[O[NZNZP\\P\\N[MZMYNXPVUTXRZP[L[JZIXIUJSPORMSKSIRGPFNGMIMLNOPRTWWZY[[[\\Y\\X KZJXJUKSLR RMSI SKRG NGMK NNPQTVWYYZ N[LZKXKULSPO MINMQQUVXYZZ[Z\\Y", + "H\\PBP_ TBT_ XKXJWJWLYLYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ LLMNOOUQWRXT MGLILKMMONUPXRYTYWXYWZT[P[MZLYKWKUMUMWLWLV", + "G^[BIbJb [B\\BJb", + "KYUBSDQGOKNPNTOYQ]S`Ub QHPKOOOUPYQ\\ SDRFQIPOPUQ[R^S`", + "KYOBQDSGUKVPVTUYS]Q`Ob SHTKUOUUTYS\\ QDRFSITOTUS[R^Q`", + "JZRFQGSQRR RFRR RFSGQQRR MINIVOWO MIWO MIMJWNWO WIVINOMO WIMO WIWJMNMO", + "F_JQ[Q[R JQJR[R", + "F_RIRZSZ RISISZ JQ[Q[R JQJR[R", + "F_JM[M[N JMJN[N JU[U[V JUJV[V", + "NWSFRGRM SGRM SFTGRM", + "I[NFMGMM NGMM NFOGMM WFVGVM WGVM WFXGVM", + "KYQFOGNINKOMQNSNUMVKVIUGSFQF QFNIOMSNVKUGQF SFOGNKQNUMVISF", + "F^ZIJRZ[ ZIZJLRZZZ[", + "F^JIZRJ[ JIJJXRJZJ[", + "G^OFObPb OFPFPb UFUbVb UFVFVb JP[P[Q JPJQ[Q JW[W[X JWJX[X", + "F^[FYGVHSHPGNFLFJGIIIKKMMMOLPJPHNF [FH[ [FI[ [FJ[ YTWTUUTWTYV[X[ZZ[X[VYT OGLFIIJLMMPJOG NFJGIK KMOLPH ZUWTTWUZX[[XZU YTUUTY V[ZZ[V H[J[", + "E`VNULSKQKOLNMMOMRNTOUQVSVUUVS OMNONROT QKPLOOORPUQV VKVSWUYVZV\\U]R]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYXYWZ WLWSXU VKXKXSYUZV", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NV", + "JZ", + "H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF QHOJNLMOLSLWMY TYVWWUXRYNYJXH TFRGPJOLNOMSMXNZO[ Q[SZUWVUWRXNXIWGVF", + "H]TJO[Q[ WFUJP[ WFQ[ WFTIQKOL TJRKOL", + "H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMWOMUKWI[ XGYIYKXMVOSQ VFWGXIXKWMUOMU JYKXMXRYWYXX MXRZWZ MXR[U[WZXXXW", + "H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMXNVOSP XGYIYKXMWN VFWGXIXKWMUOSP QPSPVQWRXTXWWYUZR[O[LZKYJWJULULWKWKV VRWTWWVY SPUQVSVWUYTZR[", + "H]WJR[T[ ZFXJS[ ZFT[ ZFJUZU", + "H]QFLP QF[F QGYG PHUHYG[F LPMOPNSNVOWPXRXUWXUZQ[N[LZKYJWJULULWKWKV VPWRWUVXTZ SNUOVQVUUXSZQ[", + "H]YJYIXIXKZKZIYGWFTFQGOIMLLOKSKVLYMZO[R[UZWXXVXSWQVPTOQOOPNQMS PINLMOLSLWMY VXWVWSVQ TFRGPJOLNOMSMXNZO[ R[TZUYVVVRUPTO", + "H]NFLL [FZIXLTQRTQWP[ RSPWO[ XLRRPUOWN[P[ MIPFRFWI OGRGWI MIOHRHWIYIZH[F", + "H]SFPGOHNJNMOOQPTPWOYNZLZIYGWFSF UFPG PHOJONPO OORP SPWO XNYLYIXG YGUF SFQHPJPNQP TPVOWNXLXHWF QPMQKSJUJXKZN[R[VZWYXWXTWRVQTP RPMQ NQLSKUKXLZ KZP[VZ VYWWWTVR VQSP QPOQMSLULXMZN[ R[TZUYVWVSUQTP", + "H]XNWPVQTRQROQNPMNMKNIPGSFVFXGYHZKZNYRXUVXTZQ[N[LZKXKVMVMXLXLW OPNNNKOI XHYJYNXRWUUX QRPQOOOKPHQGSF VFWGXIXNWRVUUWSZQ[", + "MXPXOYOZP[Q[RZRYQXPX PYPZQZQYPY", + "MXQ[P[OZOYPXQXRYR[Q]P^N_ PYPZQZQYPY Q[Q\\P^", + "MXSMRNROSPTPUOUNTMSM SNSOTOTNSN PXOYOZP[Q[RZRYQXPX PYPZQZQYPY", + "MXSMRNROSPTPUOUNTMSM SNSOTOTNSN Q[P[OZOYPXQXRYR[Q]P^N_ PYPZQZQYPY Q[Q\\P^", + "MXVFUFTGRT VGUGRT VGVHRT VFWGWHRT PXOYOZP[Q[RZRYQXPX PYPZQZQYPY", + "H]OKOJPJPLNLNJOHPGSFWFZG[I[KZMYNWOSPQQQSSTTT UFZG YGZIZKYMXNVO WFXGYIYKXMWNSPRQRSST PXOYOZP[Q[RZRYQXPX PYPZQZQYPY", + "MXWFUGTHSJSLTMUMVLVKUJTJ UGTITJ TKTLULUKTK", + "MXVIUITHTGUFVFWGWIVKULSM UGUHVHVGUG VIVJUL", + "E_\\O\\N[N[P]P]N\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQURWTZV[X[YYYX L[HZ IZHXHVITJSLR PPQSTYVZ K[JZIXIVJTKSMRRO OLPOQRSVUYWZXZYY", + "H]TBL_ YBQ_ ZKZJYJYL[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ NLONVRWT OGNINKOMUPWRXTXWWYVZS[O[LZKYJWJULULWKWKV", + "G^_BEbFb _B`BFb", + "JZZBXCUERHPKNOMSMXN\\O_Qb SHQKOONTN\\ ZBWDTGRJQLPOOSN\\ NTO]P`Qb", + "JZSBUEVHWLWQVUTYR\\O_LaJb VHVPUUSYQ\\ SBTDUGVP VHUQTUSXRZP]M`Jb", + "J[TFSGUQTR TFTR TFUGSQTR OIPIXOYO OIYO OIOJYNYO YIXIPOOO YIOO YIYJONOO", + "F_JQ[Q[R JQJR[R", + "F_RIRZSZ RISISZ JQ[Q[R JQJR[R", + "F_JM[M[N JMJN[N JU[U[V JUJV[V", + "MWUFTGRM UGRM UFVGRM", + "H\\PFOGMM PGMM PFQGMM ZFYGWM ZGWM ZF[GWM", + "KZSFQGPIPKQMSNUNWMXKXIWGUFSF SFPIQMUNXKWGSF UFQGPKSNWMXIUF", + "F^ZIJRZ[ ZIZJLRZZZ[", + "F^JIZRJ[ JIJJXRJZJ[", + "G^SFKbLb SFTFLb YFQbRb YFZFRb KP\\P\\Q KPKQ\\Q IWZWZX IWIXZX", + "E^^F\\GXHUHQGOFMFKGJIJKLMNMPLQJQHOF ^FE[ ^FF[ ^FG[ XTVTTUSWSYU[W[YZZXZVXT PGMFJIKLNMQJPG OFKGJK LMPLQH YUVTSWTZW[ZXYU XTTUSY U[YZZV E[G[", + "E`UQUNTLRKPKNLMMLPLSMUOVQVSUTTUQ OLNMMPMSNU RKPLOMNPNSOUPV VKUQUSVUXVZV\\U]R]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYXYWZ WKVQVSWU VKXKWQWSXUZV", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + 0 }; + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_arithm.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_arithm.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_arithm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_arithm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1566 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +namespace cvtest +{ + +const int ARITHM_NTESTS = 1000; +const int ARITHM_RNG_SEED = -1; +const int ARITHM_MAX_CHANNELS = 4; +const int ARITHM_MAX_NDIMS = 4; +const int ARITHM_MAX_SIZE_LOG = 10; + +struct BaseElemWiseOp +{ + enum { FIX_ALPHA=1, FIX_BETA=2, FIX_GAMMA=4, REAL_GAMMA=8, SUPPORT_MASK=16, SCALAR_OUTPUT=32 }; + BaseElemWiseOp(int _ninputs, int _flags, double _alpha, double _beta, + Scalar _gamma=Scalar::all(0), int _context=1) + : ninputs(_ninputs), flags(_flags), alpha(_alpha), beta(_beta), gamma(_gamma), context(_context) {} + BaseElemWiseOp() { flags = 0; alpha = beta = 0; gamma = Scalar::all(0); } + virtual ~BaseElemWiseOp() {} + virtual void op(const vector&, Mat&, const Mat&) {} + virtual void refop(const vector&, Mat&, const Mat&) {} + virtual void getValueRange(int depth, double& minval, double& maxval) + { + minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.; + maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.; + } + + virtual void getRandomSize(RNG& rng, vector& size) + { + cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, cvtest::ARITHM_MAX_SIZE_LOG, size); + } + + virtual int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, + ninputs > 1 ? ARITHM_MAX_CHANNELS : 4); + } + + virtual double getMaxErr(int depth) { return depth < CV_32F ? 1 : depth == CV_32F ? 1e-5 : 1e-12; } + virtual void generateScalars(int depth, RNG& rng) + { + const double m = 3.; + + if( !(flags & FIX_ALPHA) ) + { + alpha = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2); + alpha *= rng.uniform(0, 2) ? 1 : -1; + } + if( !(flags & FIX_BETA) ) + { + beta = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2); + beta *= rng.uniform(0, 2) ? 1 : -1; + } + + if( !(flags & FIX_GAMMA) ) + { + for( int i = 0; i < 4; i++ ) + { + gamma[i] = exp(rng.uniform(-1, 6)*m*CV_LOG2); + gamma[i] *= rng.uniform(0, 2) ? 1 : -1; + } + if( flags & REAL_GAMMA ) + gamma = Scalar::all(gamma[0]); + } + + if( depth == CV_32F ) + { + Mat fl, db; + + db = Mat(1, 1, CV_64F, &alpha); + db.convertTo(fl, CV_32F); + fl.convertTo(db, CV_64F); + + db = Mat(1, 1, CV_64F, &beta); + db.convertTo(fl, CV_32F); + fl.convertTo(db, CV_64F); + + db = Mat(1, 4, CV_64F, &gamma[0]); + db.convertTo(fl, CV_32F); + fl.convertTo(db, CV_64F); + } + } + + int ninputs; + int flags; + double alpha; + double beta; + Scalar gamma; + int maxErr; + int context; +}; + + +struct BaseAddOp : public BaseElemWiseOp +{ + BaseAddOp(int _ninputs, int _flags, double _alpha, double _beta, Scalar _gamma=Scalar::all(0)) + : BaseElemWiseOp(_ninputs, _flags, _alpha, _beta, _gamma) {} + + void refop(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + if( !mask.empty() ) + { + cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, temp, src[0].type()); + cvtest::copy(temp, dst, mask); + } + else + cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, dst, src[0].type()); + } +}; + + +struct AddOp : public BaseAddOp +{ + AddOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( mask.empty() ) + add(src[0], src[1], dst); + else + add(src[0], src[1], dst, mask); + } +}; + + +struct SubOp : public BaseAddOp +{ + SubOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, -1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( mask.empty() ) + subtract(src[0], src[1], dst); + else + subtract(src[0], src[1], dst, mask); + } +}; + + +struct AddSOp : public BaseAddOp +{ + AddSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 0, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( mask.empty() ) + add(src[0], gamma, dst); + else + add(src[0], gamma, dst, mask); + } +}; + + +struct SubRSOp : public BaseAddOp +{ + SubRSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, -1, 0, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( mask.empty() ) + subtract(gamma, src[0], dst); + else + subtract(gamma, src[0], dst, mask); + } +}; + + +struct ScaleAddOp : public BaseAddOp +{ + ScaleAddOp() : BaseAddOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + scaleAdd(src[0], alpha, src[1], dst); + } + double getMaxErr(int depth) + { + return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-4 : 1e-12; + } +}; + + +struct AddWeightedOp : public BaseAddOp +{ + AddWeightedOp() : BaseAddOp(2, REAL_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + addWeighted(src[0], alpha, src[1], beta, gamma[0], dst); + } + double getMaxErr(int depth) + { + return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-10; + } +}; + +struct MulOp : public BaseElemWiseOp +{ + MulOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void getValueRange(int depth, double& minval, double& maxval) + { + minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.; + maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.; + minval = std::max(minval, -30000.); + maxval = std::min(maxval, 30000.); + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::multiply(src[0], src[1], dst, alpha); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::multiply(src[0], src[1], dst, alpha); + } + double getMaxErr(int depth) + { + return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12; + } +}; + +struct DivOp : public BaseElemWiseOp +{ + DivOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::divide(src[0], src[1], dst, alpha); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::divide(src[0], src[1], dst, alpha); + } + double getMaxErr(int depth) + { + return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12; + } +}; + +struct RecipOp : public BaseElemWiseOp +{ + RecipOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::divide(alpha, src[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::divide(Mat(), src[0], dst, alpha); + } + double getMaxErr(int depth) + { + return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-5 : 1e-12; + } +}; + +struct AbsDiffOp : public BaseAddOp +{ + AbsDiffOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, -1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + absdiff(src[0], src[1], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::add(src[0], 1, src[1], -1, Scalar::all(0), dst, src[0].type(), true); + } +}; + +struct AbsDiffSOp : public BaseAddOp +{ + AbsDiffSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA, 1, 0, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + absdiff(src[0], gamma, dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::add(src[0], 1, Mat(), 0, -gamma, dst, src[0].type(), true); + } +}; + +struct LogicOp : public BaseElemWiseOp +{ + LogicOp(char _opcode) : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)), opcode(_opcode) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( opcode == '&' ) + bitwise_and(src[0], src[1], dst, mask); + else if( opcode == '|' ) + bitwise_or(src[0], src[1], dst, mask); + else + bitwise_xor(src[0], src[1], dst, mask); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + if( !mask.empty() ) + { + cvtest::logicOp(src[0], src[1], temp, opcode); + cvtest::copy(temp, dst, mask); + } + else + cvtest::logicOp(src[0], src[1], dst, opcode); + } + double getMaxErr(int) + { + return 0; + } + char opcode; +}; + +struct LogicSOp : public BaseElemWiseOp +{ + LogicSOp(char _opcode) + : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+(_opcode != '~' ? SUPPORT_MASK : 0), 1, 1, Scalar::all(0)), opcode(_opcode) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + if( opcode == '&' ) + bitwise_and(src[0], gamma, dst, mask); + else if( opcode == '|' ) + bitwise_or(src[0], gamma, dst, mask); + else if( opcode == '^' ) + bitwise_xor(src[0], gamma, dst, mask); + else + bitwise_not(src[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + if( !mask.empty() ) + { + cvtest::logicOp(src[0], gamma, temp, opcode); + cvtest::copy(temp, dst, mask); + } + else + cvtest::logicOp(src[0], gamma, dst, opcode); + } + double getMaxErr(int) + { + return 0; + } + char opcode; +}; + +struct MinOp : public BaseElemWiseOp +{ + MinOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::min(src[0], src[1], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::min(src[0], src[1], dst); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct MaxOp : public BaseElemWiseOp +{ + MaxOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::max(src[0], src[1], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::max(src[0], src[1], dst); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct MinSOp : public BaseElemWiseOp +{ + MinSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::min(src[0], gamma[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::min(src[0], gamma[0], dst); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct MaxSOp : public BaseElemWiseOp +{ + MaxSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::max(src[0], gamma[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::max(src[0], gamma[0], dst); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct CmpOp : public BaseElemWiseOp +{ + CmpOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void generateScalars(int depth, RNG& rng) + { + BaseElemWiseOp::generateScalars(depth, rng); + cmpop = rng.uniform(0, 6); + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::compare(src[0], src[1], dst, cmpop); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::compare(src[0], src[1], dst, cmpop); + } + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + } + + double getMaxErr(int) + { + return 0; + } + int cmpop; +}; + +struct CmpSOp : public BaseElemWiseOp +{ + CmpSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}; + void generateScalars(int depth, RNG& rng) + { + BaseElemWiseOp::generateScalars(depth, rng); + cmpop = rng.uniform(0, 6); + if( depth < CV_32F ) + gamma[0] = cvRound(gamma[0]); + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::compare(src[0], gamma[0], dst, cmpop); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::compare(src[0], gamma[0], dst, cmpop); + } + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + } + double getMaxErr(int) + { + return 0; + } + int cmpop; +}; + + +struct CopyOp : public BaseElemWiseOp +{ + CopyOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat& mask) + { + src[0].copyTo(dst, mask); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + cvtest::copy(src[0], dst, mask); + } + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + } + double getMaxErr(int) + { + return 0; + } + int cmpop; +}; + + +struct SetOp : public BaseElemWiseOp +{ + SetOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}; + void op(const vector&, Mat& dst, const Mat& mask) + { + dst.setTo(gamma, mask); + } + void refop(const vector&, Mat& dst, const Mat& mask) + { + cvtest::set(dst, gamma, mask); + } + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + } + double getMaxErr(int) + { + return 0; + } +}; + +template static void +inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total, int cn) +{ + size_t i; + int c; + for( i = 0; i < total; i++ ) + { + _Tp val = src[i*cn]; + dst[i] = (a[0] <= val && val <= b[0]) ? uchar(255) : 0; + } + for( c = 1; c < cn; c++ ) + { + for( i = 0; i < total; i++ ) + { + _Tp val = src[i*cn + c]; + dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0; + } + } +} + +template static void inRange_(const _Tp* src, const _Tp* a, const _Tp* b, uchar* dst, size_t total, int cn) +{ + size_t i; + int c; + for( i = 0; i < total; i++ ) + { + _Tp val = src[i*cn]; + dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0; + } + for( c = 1; c < cn; c++ ) + { + for( i = 0; i < total; i++ ) + { + _Tp val = src[i*cn + c]; + dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0; + } + } +} + + +static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst) +{ + CV_Assert( src.type() == lb.type() && src.type() == rb.type() && + src.size == lb.size && src.size == rb.size ); + dst.create( src.dims, &src.size[0], CV_8U ); + const Mat *arrays[]={&src, &lb, &rb, &dst, 0}; + Mat planes[4]; + + NAryMatIterator it(arrays, planes); + size_t total = planes[0].total(); + size_t i, nplanes = it.nplanes; + int depth = src.depth(), cn = src.channels(); + + for( i = 0; i < nplanes; i++, ++it ) + { + const uchar* sptr = planes[0].data; + const uchar* aptr = planes[1].data; + const uchar* bptr = planes[2].data; + uchar* dptr = planes[3].data; + + switch( depth ) + { + case CV_8U: + inRange_((const uchar*)sptr, (const uchar*)aptr, (const uchar*)bptr, dptr, total, cn); + break; + case CV_8S: + inRange_((const schar*)sptr, (const schar*)aptr, (const schar*)bptr, dptr, total, cn); + break; + case CV_16U: + inRange_((const ushort*)sptr, (const ushort*)aptr, (const ushort*)bptr, dptr, total, cn); + break; + case CV_16S: + inRange_((const short*)sptr, (const short*)aptr, (const short*)bptr, dptr, total, cn); + break; + case CV_32S: + inRange_((const int*)sptr, (const int*)aptr, (const int*)bptr, dptr, total, cn); + break; + case CV_32F: + inRange_((const float*)sptr, (const float*)aptr, (const float*)bptr, dptr, total, cn); + break; + case CV_64F: + inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn); + break; + default: + CV_Error(CV_StsUnsupportedFormat, ""); + } + } +} + + +static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst) +{ + dst.create( src.dims, &src.size[0], CV_8U ); + const Mat *arrays[]={&src, &dst, 0}; + Mat planes[2]; + + NAryMatIterator it(arrays, planes); + size_t total = planes[0].total(); + size_t i, nplanes = it.nplanes; + int depth = src.depth(), cn = src.channels(); + union { double d[4]; float f[4]; int i[4];} lbuf, rbuf; + int wtype = CV_MAKETYPE(depth <= CV_32S ? CV_32S : depth, cn); + scalarToRawData(lb, lbuf.d, wtype, cn); + scalarToRawData(rb, rbuf.d, wtype, cn); + + for( i = 0; i < nplanes; i++, ++it ) + { + const uchar* sptr = planes[0].data; + uchar* dptr = planes[1].data; + + switch( depth ) + { + case CV_8U: + inRangeS_((const uchar*)sptr, lbuf.i, rbuf.i, dptr, total, cn); + break; + case CV_8S: + inRangeS_((const schar*)sptr, lbuf.i, rbuf.i, dptr, total, cn); + break; + case CV_16U: + inRangeS_((const ushort*)sptr, lbuf.i, rbuf.i, dptr, total, cn); + break; + case CV_16S: + inRangeS_((const short*)sptr, lbuf.i, rbuf.i, dptr, total, cn); + break; + case CV_32S: + inRangeS_((const int*)sptr, lbuf.i, rbuf.i, dptr, total, cn); + break; + case CV_32F: + inRangeS_((const float*)sptr, lbuf.f, rbuf.f, dptr, total, cn); + break; + case CV_64F: + inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn); + break; + default: + CV_Error(CV_StsUnsupportedFormat, ""); + } + } +} + + +struct InRangeSOp : public BaseElemWiseOp +{ + InRangeSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::inRange(src[0], gamma, gamma1, dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::inRangeS(src[0], gamma, gamma1, dst); + } + double getMaxErr(int) + { + return 0; + } + void generateScalars(int depth, RNG& rng) + { + BaseElemWiseOp::generateScalars(depth, rng); + Scalar temp = gamma; + BaseElemWiseOp::generateScalars(depth, rng); + for( int i = 0; i < 4; i++ ) + { + gamma1[i] = std::max(gamma[i], temp[i]); + gamma[i] = std::min(gamma[i], temp[i]); + } + } + Scalar gamma1; +}; + + +struct InRangeOp : public BaseElemWiseOp +{ + InRangeOp() : BaseElemWiseOp(3, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + Mat lb, rb; + cvtest::min(src[1], src[2], lb); + cvtest::max(src[1], src[2], rb); + + cv::inRange(src[0], lb, rb, dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + Mat lb, rb; + cvtest::min(src[1], src[2], lb); + cvtest::max(src[1], src[2], rb); + + cvtest::inRange(src[0], lb, rb, dst); + } + double getMaxErr(int) + { + return 0; + } +}; + + +struct ConvertScaleOp : public BaseElemWiseOp +{ + ConvertScaleOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), ddepth(0) { }; + void op(const vector& src, Mat& dst, const Mat&) + { + src[0].convertTo(dst, ddepth, alpha, gamma[0]); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::convert(src[0], dst, CV_MAKETYPE(ddepth, src[0].channels()), alpha, gamma[0]); + } + int getRandomType(RNG& rng) + { + int srctype = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + ddepth = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1); + return srctype; + } + double getMaxErr(int) + { + return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12; + } + void generateScalars(int depth, RNG& rng) + { + if( rng.uniform(0, 2) ) + BaseElemWiseOp::generateScalars(depth, rng); + else + { + alpha = 1; + gamma = Scalar::all(0); + } + } + int ddepth; +}; + + +struct ConvertScaleAbsOp : public BaseElemWiseOp +{ + ConvertScaleAbsOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector& src, Mat& dst, const Mat&) + { + cv::convertScaleAbs(src[0], dst, alpha, gamma[0]); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::add(src[0], alpha, Mat(), 0, Scalar::all(gamma[0]), dst, CV_8UC(src[0].channels()), true); + } + double getMaxErr(int) + { + return 1; + } + void generateScalars(int depth, RNG& rng) + { + if( rng.uniform(0, 2) ) + BaseElemWiseOp::generateScalars(depth, rng); + else + { + alpha = 1; + gamma = Scalar::all(0); + } + } +}; + + +static void flip(const Mat& src, Mat& dst, int flipcode) +{ + CV_Assert(src.dims == 2); + dst.create(src.size(), src.type()); + int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz; + + for( i = 0; i < dst.rows; i++ ) + { + const uchar* sptr = src.ptr(flipcode == 1 ? i : dst.rows - i - 1); + uchar* dptr = dst.ptr(i); + if( flipcode == 0 ) + memcpy(dptr, sptr, width); + else + { + for( j = 0; j < width; j += esz ) + for( k = 0; k < esz; k++ ) + dptr[j + k] = sptr[width - j - esz + k]; + } + } +} + + +static void setIdentity(Mat& dst, const Scalar& s) +{ + CV_Assert( dst.dims == 2 && dst.channels() <= 4 ); + double buf[4]; + scalarToRawData(s, buf, dst.type(), 0); + int i, k, esz = (int)dst.elemSize(), width = dst.cols*esz; + + for( i = 0; i < dst.rows; i++ ) + { + uchar* dptr = dst.ptr(i); + memset( dptr, 0, width ); + if( i < dst.cols ) + for( k = 0; k < esz; k++ ) + dptr[i*esz + k] = ((uchar*)buf)[k]; + } +} + + +struct FlipOp : public BaseElemWiseOp +{ + FlipOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void getRandomSize(RNG& rng, vector& size) + { + cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size); + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::flip(src[0], dst, flipcode); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::flip(src[0], dst, flipcode); + } + void generateScalars(int, RNG& rng) + { + flipcode = rng.uniform(0, 3) - 1; + } + double getMaxErr(int) + { + return 0; + } + int flipcode; +}; + +struct TransposeOp : public BaseElemWiseOp +{ + TransposeOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void getRandomSize(RNG& rng, vector& size) + { + cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size); + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::transpose(src[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::transpose(src[0], dst); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct SetIdentityOp : public BaseElemWiseOp +{ + SetIdentityOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}; + void getRandomSize(RNG& rng, vector& size) + { + cvtest::randomSize(rng, 2, 2, cvtest::ARITHM_MAX_SIZE_LOG, size); + } + void op(const vector&, Mat& dst, const Mat&) + { + cv::setIdentity(dst, gamma); + } + void refop(const vector&, Mat& dst, const Mat&) + { + cvtest::setIdentity(dst, gamma); + } + double getMaxErr(int) + { + return 0; + } +}; + +struct SetZeroOp : public BaseElemWiseOp +{ + SetZeroOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + void op(const vector&, Mat& dst, const Mat&) + { + dst = Scalar::all(0); + } + void refop(const vector&, Mat& dst, const Mat&) + { + cvtest::set(dst, Scalar::all(0)); + } + double getMaxErr(int) + { + return 0; + } +}; + + +static void exp(const Mat& src, Mat& dst) +{ + dst.create( src.dims, &src.size[0], src.type() ); + const Mat *arrays[]={&src, &dst, 0}; + Mat planes[2]; + + NAryMatIterator it(arrays, planes); + size_t j, total = planes[0].total()*src.channels(); + size_t i, nplanes = it.nplanes; + int depth = src.depth(); + + for( i = 0; i < nplanes; i++, ++it ) + { + const uchar* sptr = planes[0].data; + uchar* dptr = planes[1].data; + + if( depth == CV_32F ) + { + for( j = 0; j < total; j++ ) + ((float*)dptr)[j] = std::exp(((const float*)sptr)[j]); + } + else if( depth == CV_64F ) + { + for( j = 0; j < total; j++ ) + ((double*)dptr)[j] = std::exp(((const double*)sptr)[j]); + } + } +} + +static void log(const Mat& src, Mat& dst) +{ + dst.create( src.dims, &src.size[0], src.type() ); + const Mat *arrays[]={&src, &dst, 0}; + Mat planes[2]; + + NAryMatIterator it(arrays, planes); + size_t j, total = planes[0].total()*src.channels(); + size_t i, nplanes = it.nplanes; + int depth = src.depth(); + + for( i = 0; i < nplanes; i++, ++it ) + { + const uchar* sptr = planes[0].data; + uchar* dptr = planes[1].data; + + if( depth == CV_32F ) + { + for( j = 0; j < total; j++ ) + ((float*)dptr)[j] = (float)std::log(fabs(((const float*)sptr)[j])); + } + else if( depth == CV_64F ) + { + for( j = 0; j < total; j++ ) + ((double*)dptr)[j] = std::log(fabs(((const double*)sptr)[j])); + } + } +} + +struct ExpOp : public BaseElemWiseOp +{ + ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); + } + void getValueRange(int depth, double& minval, double& maxval) + { + maxval = depth == CV_32F ? 50 : 100; + minval = -maxval; + } + void op(const vector& src, Mat& dst, const Mat&) + { + cv::exp(src[0], dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + cvtest::exp(src[0], dst); + } + double getMaxErr(int depth) + { + return depth == CV_32F ? 1e-5 : 1e-12; + } +}; + + +struct LogOp : public BaseElemWiseOp +{ + LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); + } + void getValueRange(int depth, double& minval, double& maxval) + { + maxval = depth == CV_32F ? 50 : 100; + minval = -maxval; + } + void op(const vector& src, Mat& dst, const Mat&) + { + Mat temp; + cvtest::exp(src[0], temp); + cv::log(temp, dst); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + Mat temp; + cvtest::exp(src[0], temp); + cvtest::log(temp, dst); + } + double getMaxErr(int depth) + { + return depth == CV_32F ? 1e-5 : 1e-12; + } +}; + + +static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bool angleInDegrees) +{ + CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) && + mx.type() == my.type() && mx.size == my.size ); + mmag.create( mx.dims, &mx.size[0], mx.type() ); + mangle.create( mx.dims, &mx.size[0], mx.type() ); + const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0}; + Mat planes[4]; + + NAryMatIterator it(arrays, planes); + size_t j, total = planes[0].total(); + size_t i, nplanes = it.nplanes; + int depth = mx.depth(); + double scale = angleInDegrees ? 180/CV_PI : 1; + + for( i = 0; i < nplanes; i++, ++it ) + { + if( depth == CV_32F ) + { + const float* xptr = (const float*)planes[0].data; + const float* yptr = (const float*)planes[1].data; + float* mptr = (float*)planes[2].data; + float* aptr = (float*)planes[3].data; + + for( j = 0; j < total; j++ ) + { + mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]); + double a = atan2((double)yptr[j], (double)xptr[j]); + if( a < 0 ) a += CV_PI*2; + aptr[j] = (float)(a*scale); + } + } + else + { + const double* xptr = (const double*)planes[0].data; + const double* yptr = (const double*)planes[1].data; + double* mptr = (double*)planes[2].data; + double* aptr = (double*)planes[3].data; + + for( j = 0; j < total; j++ ) + { + mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]); + double a = atan2(yptr[j], xptr[j]); + if( a < 0 ) a += CV_PI*2; + aptr[j] = a*scale; + } + } + } +} + + +struct CartToPolarToCartOp : public BaseElemWiseOp +{ + CartToPolarToCartOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) + { + context = 3; + angleInDegrees = true; + } + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, 1); + } + void op(const vector& src, Mat& dst, const Mat&) + { + Mat mag, angle, x, y; + + cv::cartToPolar(src[0], src[1], mag, angle, angleInDegrees); + cv::polarToCart(mag, angle, x, y, angleInDegrees); + + Mat msrc[] = {mag, angle, x, y}; + int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3}; + dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4)); + cv::mixChannels(msrc, 4, &dst, 1, pairs, 4); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + Mat mag, angle; + cvtest::cartToPolar(src[0], src[1], mag, angle, angleInDegrees); + Mat msrc[] = {mag, angle, src[0], src[1]}; + int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3}; + dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4)); + cv::mixChannels(msrc, 4, &dst, 1, pairs, 4); + } + void generateScalars(int, RNG& rng) + { + angleInDegrees = rng.uniform(0, 2) != 0; + } + double getMaxErr(int) + { + return 1e-3; + } + bool angleInDegrees; +}; + + +struct MeanOp : public BaseElemWiseOp +{ + MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0)) + { + context = 3; + }; + void op(const vector& src, Mat& dst, const Mat& mask) + { + dst.create(1, 1, CV_64FC4); + dst.at(0,0) = cv::mean(src[0], mask); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + dst.create(1, 1, CV_64FC4); + dst.at(0,0) = cvtest::mean(src[0], mask); + } + double getMaxErr(int) + { + return 1e-6; + } +}; + + +struct SumOp : public BaseElemWiseOp +{ + SumOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT, 1, 1, Scalar::all(0)) + { + context = 3; + }; + void op(const vector& src, Mat& dst, const Mat&) + { + dst.create(1, 1, CV_64FC4); + dst.at(0,0) = cv::sum(src[0]); + } + void refop(const vector& src, Mat& dst, const Mat&) + { + dst.create(1, 1, CV_64FC4); + dst.at(0,0) = cvtest::mean(src[0])*(double)src[0].total(); + } + double getMaxErr(int) + { + return 1e-5; + } +}; + + +struct CountNonZeroOp : public BaseElemWiseOp +{ + CountNonZeroOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT+SUPPORT_MASK, 1, 1, Scalar::all(0)) + {} + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1); + } + void op(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + src[0].copyTo(temp); + if( !mask.empty() ) + temp.setTo(Scalar::all(0), mask); + dst.create(1, 1, CV_32S); + dst.at(0,0) = cv::countNonZero(temp); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + cvtest::compare(src[0], 0, temp, CMP_NE); + if( !mask.empty() ) + cvtest::set(temp, Scalar::all(0), mask); + dst.create(1, 1, CV_32S); + dst.at(0,0) = saturate_cast(cvtest::mean(temp)[0]/255*temp.total()); + } + double getMaxErr(int) + { + return 0; + } +}; + + +struct MeanStdDevOp : public BaseElemWiseOp +{ + Scalar sqmeanRef; + int cn; + + MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0)) + { + cn = 0; + context = 7; + }; + void op(const vector& src, Mat& dst, const Mat& mask) + { + dst.create(1, 2, CV_64FC4); + cv::meanStdDev(src[0], dst.at(0,0), dst.at(0,1), mask); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + Mat temp; + cvtest::convert(src[0], temp, CV_64F); + cvtest::multiply(temp, temp, temp); + Scalar mean = cvtest::mean(src[0], mask); + Scalar sqmean = cvtest::mean(temp, mask); + + sqmeanRef = sqmean; + cn = temp.channels(); + + for( int c = 0; c < 4; c++ ) + sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.)); + + dst.create(1, 2, CV_64FC4); + dst.at(0,0) = mean; + dst.at(0,1) = sqmean; + } + double getMaxErr(int) + { + CV_Assert(cn > 0); + double err = sqmeanRef[0]; + for(int i = 1; i < cn; ++i) + err = std::max(err, sqmeanRef[i]); + return 3e-7 * err; + } +}; + + +struct NormOp : public BaseElemWiseOp +{ + NormOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0)) + { + context = 1; + normType = 0; + }; + int getRandomType(RNG& rng) + { + int type = cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4); + for(;;) + { + normType = rng.uniform(1, 8); + if( normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR || + normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + break; + } + if( normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + { + type = CV_8U; + } + return type; + } + void op(const vector& src, Mat& dst, const Mat& mask) + { + dst.create(1, 2, CV_64FC1); + dst.at(0,0) = cv::norm(src[0], normType, mask); + dst.at(0,1) = cv::norm(src[0], src[1], normType, mask); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + dst.create(1, 2, CV_64FC1); + dst.at(0,0) = cvtest::norm(src[0], normType, mask); + dst.at(0,1) = cvtest::norm(src[0], src[1], normType, mask); + } + void generateScalars(int, RNG& /*rng*/) + { + } + double getMaxErr(int) + { + return 1e-6; + } + int normType; +}; + + +struct MinMaxLocOp : public BaseElemWiseOp +{ + MinMaxLocOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0)) + { + context = ARITHM_MAX_NDIMS*2 + 2; + }; + int getRandomType(RNG& rng) + { + return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + } + void saveOutput(const vector& minidx, const vector& maxidx, + double minval, double maxval, Mat& dst) + { + int i, ndims = (int)minidx.size(); + dst.create(1, ndims*2 + 2, CV_64FC1); + + for( i = 0; i < ndims; i++ ) + { + dst.at(0,i) = minidx[i]; + dst.at(0,i+ndims) = maxidx[i]; + } + dst.at(0,ndims*2) = minval; + dst.at(0,ndims*2+1) = maxval; + } + void op(const vector& src, Mat& dst, const Mat& mask) + { + int ndims = src[0].dims; + vector minidx(ndims), maxidx(ndims); + double minval=0, maxval=0; + cv::minMaxIdx(src[0], &minval, &maxval, &minidx[0], &maxidx[0], mask); + saveOutput(minidx, maxidx, minval, maxval, dst); + } + void refop(const vector& src, Mat& dst, const Mat& mask) + { + int ndims=src[0].dims; + vector minidx(ndims), maxidx(ndims); + double minval=0, maxval=0; + cvtest::minMaxLoc(src[0], &minval, &maxval, &minidx, &maxidx, mask); + saveOutput(minidx, maxidx, minval, maxval, dst); + } + double getMaxErr(int) + { + return 0; + } +}; + + +} + +typedef Ptr ElemWiseOpPtr; +class ElemWiseTest : public ::testing::TestWithParam {}; + +TEST_P(ElemWiseTest, accuracy) +{ + ElemWiseOpPtr op = GetParam(); + + int testIdx = 0; + RNG rng((uint64)cvtest::ARITHM_RNG_SEED); + for( testIdx = 0; testIdx < cvtest::ARITHM_NTESTS; testIdx++ ) + { + vector size; + op->getRandomSize(rng, size); + int type = op->getRandomType(rng); + int depth = CV_MAT_DEPTH(type); + bool haveMask = (op->flags & cvtest::BaseElemWiseOp::SUPPORT_MASK) != 0 && rng.uniform(0, 4) == 0; + + double minval=0, maxval=0; + op->getValueRange(depth, minval, maxval); + int i, ninputs = op->ninputs; + vector src(ninputs); + for( i = 0; i < ninputs; i++ ) + src[i] = cvtest::randomMat(rng, size, type, minval, maxval, true); + Mat dst0, dst, mask; + if( haveMask ) + mask = cvtest::randomMat(rng, size, CV_8U, 0, 2, true); + + if( (haveMask || ninputs == 0) && !(op->flags & cvtest::BaseElemWiseOp::SCALAR_OUTPUT)) + { + dst0 = cvtest::randomMat(rng, size, type, minval, maxval, false); + dst = cvtest::randomMat(rng, size, type, minval, maxval, true); + cvtest::copy(dst, dst0); + } + op->generateScalars(depth, rng); + + op->refop(src, dst0, mask); + op->op(src, dst, mask); + + double maxErr = op->getMaxErr(depth); + vector pos; + ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " << cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n"; + } +} + + +INSTANTIATE_TEST_CASE_P(Core_Copy, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CopyOp))); +INSTANTIATE_TEST_CASE_P(Core_Set, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetOp))); +INSTANTIATE_TEST_CASE_P(Core_SetZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetZeroOp))); +INSTANTIATE_TEST_CASE_P(Core_ConvertScale, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleOp))); +INSTANTIATE_TEST_CASE_P(Core_ConvertScaleAbs, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ConvertScaleAbsOp))); + +INSTANTIATE_TEST_CASE_P(Core_Add, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddOp))); +INSTANTIATE_TEST_CASE_P(Core_Sub, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubOp))); +INSTANTIATE_TEST_CASE_P(Core_AddS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddSOp))); +INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SubRSOp))); +INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ScaleAddOp))); +INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddWeightedOp))); +INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffOp))); + + +INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffSOp))); + +INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('&')))); +INSTANTIATE_TEST_CASE_P(Core_AndS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('&')))); +INSTANTIATE_TEST_CASE_P(Core_Or, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('|')))); +INSTANTIATE_TEST_CASE_P(Core_OrS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('|')))); +INSTANTIATE_TEST_CASE_P(Core_Xor, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('^')))); +INSTANTIATE_TEST_CASE_P(Core_XorS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('^')))); +INSTANTIATE_TEST_CASE_P(Core_Not, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicSOp('~')))); + +INSTANTIATE_TEST_CASE_P(Core_Max, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxOp))); +INSTANTIATE_TEST_CASE_P(Core_MaxS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MaxSOp))); +INSTANTIATE_TEST_CASE_P(Core_Min, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinOp))); +INSTANTIATE_TEST_CASE_P(Core_MinS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinSOp))); + +INSTANTIATE_TEST_CASE_P(Core_Mul, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MulOp))); +INSTANTIATE_TEST_CASE_P(Core_Div, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::DivOp))); +INSTANTIATE_TEST_CASE_P(Core_Recip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::RecipOp))); + +INSTANTIATE_TEST_CASE_P(Core_Cmp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpOp))); +INSTANTIATE_TEST_CASE_P(Core_CmpS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CmpSOp))); + +INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeSOp))); +INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::InRangeOp))); + +INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::FlipOp))); +INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::TransposeOp))); +INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SetIdentityOp))); + +INSTANTIATE_TEST_CASE_P(Core_Exp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ExpOp))); +INSTANTIATE_TEST_CASE_P(Core_Log, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogOp))); + +INSTANTIATE_TEST_CASE_P(Core_CountNonZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CountNonZeroOp))); +INSTANTIATE_TEST_CASE_P(Core_Mean, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanOp))); +INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MeanStdDevOp))); +INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::SumOp))); +INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::NormOp))); +INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinMaxLocOp))); +INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp))); + + +class CV_ArithmMaskTest : public cvtest::BaseTest +{ +public: + CV_ArithmMaskTest() {} + ~CV_ArithmMaskTest() {} +protected: + void run(int) + { + try + { + RNG& rng = theRNG(); + const int MAX_DIM=3; + int sizes[MAX_DIM]; + for( int iter = 0; iter < 100; iter++ ) + { + //ts->printf(cvtest::TS::LOG, "."); + + ts->update_context(this, iter, true); + int k, dims = rng.uniform(1, MAX_DIM+1), p = 1; + int depth = rng.uniform(CV_8U, CV_64F+1); + int cn = rng.uniform(1, 6); + int type = CV_MAKETYPE(depth, cn); + int op = rng.uniform(0, 5); + int depth1 = op <= 1 ? CV_64F : depth; + for( k = 0; k < dims; k++ ) + { + sizes[k] = rng.uniform(1, 30); + p *= sizes[k]; + } + Mat a(dims, sizes, type), a1; + Mat b(dims, sizes, type), b1; + Mat mask(dims, sizes, CV_8U); + Mat mask1; + Mat c, d; + + rng.fill(a, RNG::UNIFORM, 0, 100); + rng.fill(b, RNG::UNIFORM, 0, 100); + + // [-2,2) range means that the each generated random number + // will be one of -2, -1, 0, 1. Saturated to [0,255], it will become + // 0, 0, 0, 1 => the mask will be filled by ~25%. + rng.fill(mask, RNG::UNIFORM, -2, 2); + + a.convertTo(a1, depth1); + b.convertTo(b1, depth1); + // invert the mask + compare(mask, 0, mask1, CMP_EQ); + a1.setTo(0, mask1); + b1.setTo(0, mask1); + + if( op == 0 ) + { + add(a, b, c, mask); + add(a1, b1, d); + } + else if( op == 1 ) + { + subtract(a, b, c, mask); + subtract(a1, b1, d); + } + else if( op == 2 ) + { + bitwise_and(a, b, c, mask); + bitwise_and(a1, b1, d); + } + else if( op == 3 ) + { + bitwise_or(a, b, c, mask); + bitwise_or(a1, b1, d); + } + else if( op == 4 ) + { + bitwise_xor(a, b, c, mask); + bitwise_xor(a1, b1, d); + } + Mat d1; + d.convertTo(d1, depth); + CV_Assert( norm(c, d1, CV_C) <= DBL_EPSILON ); + } + + Mat_ tmpSrc(100,100); + tmpSrc = 124; + Mat_ tmpMask(100,100); + tmpMask = 255; + Mat_ tmpDst(100,100); + tmpDst = 2; + tmpSrc.copyTo(tmpDst,tmpMask); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Core_ArithmMask, uninitialized) { CV_ArithmMaskTest test; test.safe_run(); } + +TEST(Multiply, FloatingPointRounding) +{ + cv::Mat src(1, 1, CV_8UC1, cv::Scalar::all(110)), dst; + cv::Scalar s(147.286359696927, 1, 1 ,1); + + cv::multiply(src, s, dst, 1, CV_16U); + // with CV_32F this produce result 16202 + ASSERT_EQ(dst.at(0,0), 16201); +} + +TEST(Core_Add, AddToColumnWhen3Rows) +{ + cv::Mat m1 = (cv::Mat_(3, 2) << 1, 2, 3, 4, 5, 6); + m1.col(1) += 10; + + cv::Mat m2 = (cv::Mat_(3, 2) << 1, 12, 3, 14, 5, 16); + + ASSERT_EQ(0, countNonZero(m1 - m2)); +} + +TEST(Core_Add, AddToColumnWhen4Rows) +{ + cv::Mat m1 = (cv::Mat_(4, 2) << 1, 2, 3, 4, 5, 6, 7, 8); + m1.col(1) += 10; + + cv::Mat m2 = (cv::Mat_(4, 2) << 1, 12, 3, 14, 5, 16, 7, 18); + + ASSERT_EQ(0, countNonZero(m1 - m2)); +} + +TEST(Core_round, CvRound) +{ + ASSERT_EQ(2, cvRound(2.0)); + ASSERT_EQ(2, cvRound(2.1)); + ASSERT_EQ(-2, cvRound(-2.1)); + ASSERT_EQ(3, cvRound(2.8)); + ASSERT_EQ(-3, cvRound(-2.8)); + ASSERT_EQ(2, cvRound(2.5)); + ASSERT_EQ(4, cvRound(3.5)); + ASSERT_EQ(-2, cvRound(-2.5)); + ASSERT_EQ(-4, cvRound(-3.5)); +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_countnonzero.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_countnonzero.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_countnonzero.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_countnonzero.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,255 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include +#include +using namespace cv; +using namespace std; + +#define CORE_COUNTNONZERO_ERROR_COUNT 1 + +#define MESSAGE_ERROR_COUNT "Count non zero elements returned by OpenCV function is incorrect." + +#define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1 + +const int FLOAT_TYPE [2] = {CV_32F, CV_64F}; +const int INT_TYPE [5] = {CV_8U, CV_8S, CV_16U, CV_16S, CV_32S}; + +#define MAX_WIDTH 100 +#define MAX_HEIGHT 100 + +class CV_CountNonZeroTest: public cvtest::BaseTest +{ +public: + CV_CountNonZeroTest(); + ~CV_CountNonZeroTest(); + +protected: + void run (int); + +private: + float eps_32; + double eps_64; + Mat src; + int current_type; + + void generate_src_data(cv::Size size, int type); + void generate_src_data(cv::Size size, int type, int count_non_zero); + void generate_src_stat_data(cv::Size size, int type, int distribution); + + int get_count_non_zero(); + + void print_information(int right, int result); +}; + +CV_CountNonZeroTest::CV_CountNonZeroTest(): eps_32(std::numeric_limits::min()), eps_64(std::numeric_limits::min()), src(Mat()), current_type(-1) {} +CV_CountNonZeroTest::~CV_CountNonZeroTest() {} + +void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type) +{ + src.create(size, CV_MAKETYPE(type, 1)); + + for (int j = 0; j < size.width; ++j) + for (int i = 0; i < size.height; ++i) + switch (type) + { + case CV_8U: { src.at(i, j) = cv::randu(); break; } + case CV_8S: { src.at(i, j) = cv::randu() - 128; break; } + case CV_16U: { src.at(i, j) = cv::randu(); break; } + case CV_16S: { src.at(i, j) = cv::randu(); break; } + case CV_32S: { src.at(i, j) = cv::randu(); break; } + case CV_32F: { src.at(i, j) = cv::randu(); break; } + case CV_64F: { src.at(i, j) = cv::randu(); break; } + default: break; + } +} + +void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type, int count_non_zero) +{ + src = Mat::zeros(size, CV_MAKETYPE(type, 1)); + + int n = 0; RNG& rng = ts->get_rng(); + + while (n < count_non_zero) + { + int i = rng.next()%size.height, j = rng.next()%size.width; + + switch (type) + { + case CV_8U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } + case CV_8S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu() - 128; n += abs(sign(src.at(i, j)));} break; } + case CV_16U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } + case CV_16S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } + case CV_32S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } + case CV_32F: { if (fabs(src.at(i, j)) <= eps_32) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_32);} break; } + case CV_64F: { if (fabs(src.at(i, j)) <= eps_64) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_64);} break; } + + default: break; + } + } + +} + +void CV_CountNonZeroTest::generate_src_stat_data(cv::Size size, int type, int distribution) +{ + src.create(size, CV_MAKETYPE(type, 1)); + + double mean = 0.0, sigma = 1.0; + double left = -1.0, right = 1.0; + + RNG& rng = ts->get_rng(); + + if (distribution == RNG::NORMAL) + rng.fill(src, RNG::NORMAL, Scalar::all(mean), Scalar::all(sigma)); + else if (distribution == RNG::UNIFORM) + rng.fill(src, RNG::UNIFORM, Scalar::all(left), Scalar::all(right)); +} + +int CV_CountNonZeroTest::get_count_non_zero() +{ + int result = 0; + + for (int i = 0; i < src.rows; ++i) + for (int j = 0; j < src.cols; ++j) + { + if (current_type == CV_8U) result += (src.at(i, j) > 0); + else if (current_type == CV_8S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_16U) result += (src.at(i, j) > 0); + else if (current_type == CV_16S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_32S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_32F) result += (fabs(src.at(i, j)) > eps_32); + else result += (fabs(src.at(i, j)) > eps_64); + } + + return result; +} + +void CV_CountNonZeroTest::print_information(int right, int result) +{ + cout << endl; cout << "Checking for the work of countNonZero function..." << endl; cout << endl; + cout << "Type of Mat: "; + switch (current_type) + { + case 0: {cout << "CV_8U"; break;} + case 1: {cout << "CV_8S"; break;} + case 2: {cout << "CV_16U"; break;} + case 3: {cout << "CV_16S"; break;} + case 4: {cout << "CV_32S"; break;} + case 5: {cout << "CV_32F"; break;} + case 6: {cout << "CV_64F"; break;} + default: break; + } + cout << endl; + cout << "Number of rows: " << src.rows << " Number of cols: " << src.cols << endl; + cout << "True count non zero elements: " << right << " Result: " << result << endl; + cout << endl; +} + +void CV_CountNonZeroTest::run(int) +{ + const size_t N = 1500; + + for (int k = 1; k <= 3; ++k) + for (size_t i = 0; i < N; ++i) + { + RNG& rng = ts->get_rng(); + + int w = rng.next()%MAX_WIDTH + 1, h = rng.next()%MAX_HEIGHT + 1; + + current_type = rng.next()%7; + + switch (k) + { + case 1: { + generate_src_data(Size(w, h), current_type); + int right = get_count_non_zero(), result = countNonZero(src); + if (result != right) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: RANDOM" << endl; + print_information(right, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + case 2: { + int count_non_zero = rng.next()%(w*h); + generate_src_data(Size(w, h), current_type, count_non_zero); + int result = countNonZero(src); + if (result != count_non_zero) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: HALF-RANDOM" << endl; + print_information(count_non_zero, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + case 3: { + int distribution = cv::randu()%2; + generate_src_stat_data(Size(w, h), current_type, distribution); + int right = get_count_non_zero(), result = countNonZero(src); + if (right != result) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: STATISTIC" << endl; + print_information(right, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + default: break; + } + } +} + +TEST (Core_CountNonZero, accuracy) { CV_CountNonZeroTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_ds.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_ds.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_ds.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_ds.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2122 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +typedef struct CvTsSimpleSeq +{ + schar* array; + int count; + int max_count; + int elem_size; +} CvTsSimpleSeq; + + +static CvTsSimpleSeq* cvTsCreateSimpleSeq( int max_count, int elem_size ) +{ + CvTsSimpleSeq* seq = (CvTsSimpleSeq*)cvAlloc( sizeof(*seq) + max_count * elem_size ); + seq->elem_size = elem_size; + seq->max_count = max_count; + seq->count = 0; + seq->array = (schar*)(seq + 1); + return seq; +} + + +static void cvTsReleaseSimpleSeq( CvTsSimpleSeq** seq ) +{ + cvFree( seq ); +} + + +static schar* cvTsSimpleSeqElem( CvTsSimpleSeq* seq, int index ) +{ + assert( 0 <= index && index < seq->count ); + return seq->array + index * seq->elem_size; +} + + +static void cvTsClearSimpleSeq( CvTsSimpleSeq* seq ) +{ + seq->count = 0; +} + + +static void cvTsSimpleSeqShiftAndCopy( CvTsSimpleSeq* seq, int from_idx, int to_idx, void* elem=0 ) +{ + int elem_size = seq->elem_size; + + if( from_idx == to_idx ) + return; + assert( (from_idx > to_idx && !elem) || (from_idx < to_idx && elem) ); + + if( from_idx < seq->count ) + { + memmove( seq->array + to_idx*elem_size, seq->array + from_idx*elem_size, + (seq->count - from_idx)*elem_size ); + } + seq->count += to_idx - from_idx; + if( elem && to_idx > from_idx ) + memcpy( seq->array + from_idx*elem_size, elem, (to_idx - from_idx)*elem_size ); +} + +static void cvTsSimpleSeqInvert( CvTsSimpleSeq* seq ) +{ + int i, k, len = seq->count, elem_size = seq->elem_size; + schar *data = seq->array, t; + + for( i = 0; i < len/2; i++ ) + { + schar* a = data + i*elem_size; + schar* b = data + (len - i - 1)*elem_size; + for( k = 0; k < elem_size; k++ ) + CV_SWAP( a[k], b[k], t ); + } +} + +/****************************************************************************************\ + * simple cvset implementation * + \****************************************************************************************/ + +typedef struct CvTsSimpleSet +{ + schar* array; + int count, max_count; + int elem_size; + int* free_stack; + int free_count; +} CvTsSimpleSet; + + +static void cvTsClearSimpleSet( CvTsSimpleSet* set_header ) +{ + int i; + int elem_size = set_header->elem_size; + + for( i = 0; i < set_header->max_count; i++ ) + { + set_header->array[i*elem_size] = 0; + set_header->free_stack[i] = set_header->max_count - i - 1; + } + set_header->free_count = set_header->max_count; + set_header->count = 0; +} + + +static CvTsSimpleSet* cvTsCreateSimpleSet( int max_count, int elem_size ) +{ + CvTsSimpleSet* set_header = (CvTsSimpleSet*)cvAlloc( sizeof(*set_header) + max_count * + (elem_size + 1 + sizeof(int))); + set_header->elem_size = elem_size + 1; + set_header->max_count = max_count; + set_header->free_stack = (int*)(set_header + 1); + set_header->array = (schar*)(set_header->free_stack + max_count); + + cvTsClearSimpleSet( set_header ); + return set_header; +} + + +static void cvTsReleaseSimpleSet( CvTsSimpleSet** set_header ) +{ + cvFree( set_header ); +} + + +static schar* cvTsSimpleSetFind( CvTsSimpleSet* set_header, int index ) +{ + int idx = index * set_header->elem_size; + assert( 0 <= index && index < set_header->max_count ); + return set_header->array[idx] ? set_header->array + idx + 1 : 0; +} + + +static int cvTsSimpleSetAdd( CvTsSimpleSet* set_header, void* elem ) +{ + int idx, idx2; + assert( set_header->free_count > 0 ); + + idx = set_header->free_stack[--set_header->free_count]; + idx2 = idx * set_header->elem_size; + assert( set_header->array[idx2] == 0 ); + set_header->array[idx2] = 1; + if( set_header->elem_size > 1 ) + memcpy( set_header->array + idx2 + 1, elem, set_header->elem_size - 1 ); + set_header->count = MAX( set_header->count, idx + 1 ); + + return idx; +} + + +static void cvTsSimpleSetRemove( CvTsSimpleSet* set_header, int index ) +{ + assert( set_header->free_count < set_header->max_count && + 0 <= index && index < set_header->max_count ); + assert( set_header->array[index * set_header->elem_size] == 1 ); + + set_header->free_stack[set_header->free_count++] = index; + set_header->array[index * set_header->elem_size] = 0; +} + + +/****************************************************************************************\ + * simple graph implementation * + \****************************************************************************************/ + +typedef struct CvTsSimpleGraph +{ + char* matrix; + int edge_size; + int oriented; + CvTsSimpleSet* vtx; +} CvTsSimpleGraph; + + +static void cvTsClearSimpleGraph( CvTsSimpleGraph* graph ) +{ + int max_vtx_count = graph->vtx->max_count; + cvTsClearSimpleSet( graph->vtx ); + memset( graph->matrix, 0, max_vtx_count * max_vtx_count * graph->edge_size ); +} + + +static CvTsSimpleGraph* cvTsCreateSimpleGraph( int max_vtx_count, int vtx_size, + int edge_size, int oriented ) +{ + CvTsSimpleGraph* graph; + + assert( max_vtx_count > 1 && vtx_size >= 0 && edge_size >= 0 ); + graph = (CvTsSimpleGraph*)cvAlloc( sizeof(*graph) + + max_vtx_count * max_vtx_count * (edge_size + 1)); + graph->vtx = cvTsCreateSimpleSet( max_vtx_count, vtx_size ); + graph->edge_size = edge_size + 1; + graph->matrix = (char*)(graph + 1); + graph->oriented = oriented; + + cvTsClearSimpleGraph( graph ); + return graph; +} + + +static void cvTsReleaseSimpleGraph( CvTsSimpleGraph** graph ) +{ + if( *graph ) + { + cvTsReleaseSimpleSet( &(graph[0]->vtx) ); + cvFree( graph ); + } +} + + +static int cvTsSimpleGraphAddVertex( CvTsSimpleGraph* graph, void* vertex ) +{ + return cvTsSimpleSetAdd( graph->vtx, vertex ); +} + + +static void cvTsSimpleGraphRemoveVertex( CvTsSimpleGraph* graph, int index ) +{ + int i, max_vtx_count = graph->vtx->max_count; + int edge_size = graph->edge_size; + cvTsSimpleSetRemove( graph->vtx, index ); + + /* remove all the corresponding edges */ + for( i = 0; i < max_vtx_count; i++ ) + { + graph->matrix[(i*max_vtx_count + index)*edge_size] = + graph->matrix[(index*max_vtx_count + i)*edge_size] = 0; + } +} + + +static void cvTsSimpleGraphAddEdge( CvTsSimpleGraph* graph, int idx1, int idx2, void* edge ) +{ + int i, t, n = graph->oriented ? 1 : 2; + + assert( cvTsSimpleSetFind( graph->vtx, idx1 ) && + cvTsSimpleSetFind( graph->vtx, idx2 )); + + for( i = 0; i < n; i++ ) + { + int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size; + assert( graph->matrix[ofs] == 0 ); + graph->matrix[ofs] = 1; + if( graph->edge_size > 1 ) + memcpy( graph->matrix + ofs + 1, edge, graph->edge_size - 1 ); + + CV_SWAP( idx1, idx2, t ); + } +} + + +static void cvTsSimpleGraphRemoveEdge( CvTsSimpleGraph* graph, int idx1, int idx2 ) +{ + int i, t, n = graph->oriented ? 1 : 2; + + assert( cvTsSimpleSetFind( graph->vtx, idx1 ) && + cvTsSimpleSetFind( graph->vtx, idx2 )); + + for( i = 0; i < n; i++ ) + { + int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size; + assert( graph->matrix[ofs] == 1 ); + graph->matrix[ofs] = 0; + CV_SWAP( idx1, idx2, t ); + } +} + + +static schar* cvTsSimpleGraphFindVertex( CvTsSimpleGraph* graph, int index ) +{ + return cvTsSimpleSetFind( graph->vtx, index ); +} + + +static char* cvTsSimpleGraphFindEdge( CvTsSimpleGraph* graph, int idx1, int idx2 ) +{ + if( cvTsSimpleGraphFindVertex( graph, idx1 ) && + cvTsSimpleGraphFindVertex( graph, idx2 )) + { + char* edge = graph->matrix + (idx1 * graph->vtx->max_count + idx2)*graph->edge_size; + if( edge[0] ) return edge + 1; + } + return 0; +} + + +static int cvTsSimpleGraphVertexDegree( CvTsSimpleGraph* graph, int index ) +{ + int i, count = 0; + int edge_size = graph->edge_size; + int max_vtx_count = graph->vtx->max_count; + assert( cvTsSimpleGraphFindVertex( graph, index ) != 0 ); + + for( i = 0; i < max_vtx_count; i++ ) + { + count += graph->matrix[(i*max_vtx_count + index)*edge_size] + + graph->matrix[(index*max_vtx_count + i)*edge_size]; + } + + if( !graph->oriented ) + { + assert( count % 2 == 0 ); + count /= 2; + } + return count; +} + + +///////////////////////////////////// the tests ////////////////////////////////// + +#define CV_TS_SEQ_CHECK_CONDITION( expr, err_msg ) \ +if( !(expr) ) \ +{ \ +set_error_context( #expr, err_msg, __FILE__, __LINE__ ); \ +ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );\ +throw -1; \ +} + +class Core_DynStructBaseTest : public cvtest::BaseTest +{ +public: + Core_DynStructBaseTest(); + virtual ~Core_DynStructBaseTest(); + bool can_do_fast_forward(); + void clear(); + +protected: + int read_params( CvFileStorage* fs ); + void run_func(void); + void set_error_context( const char* condition, + const char* err_msg, + const char* file, int line ); + int test_seq_block_consistence( int _struct_idx, CvSeq* seq, int total ); + void update_progressbar(); + + int struct_count, max_struct_size, iterations, generations; + int min_log_storage_block_size, max_log_storage_block_size; + int min_log_elem_size, max_log_elem_size; + int gen, struct_idx, iter; + int test_progress; + int64 start_time; + double cpu_freq; + vector cxcore_struct; + vector simple_struct; + Ptr storage; +}; + + +Core_DynStructBaseTest::Core_DynStructBaseTest() +{ + struct_count = 2; + max_struct_size = 2000; + min_log_storage_block_size = 7; + max_log_storage_block_size = 12; + min_log_elem_size = 0; + max_log_elem_size = 8; + generations = 10; + iterations = max_struct_size*2; + gen = struct_idx = iter = -1; + test_progress = -1; + + storage = 0; +} + + +Core_DynStructBaseTest::~Core_DynStructBaseTest() +{ + clear(); +} + + +void Core_DynStructBaseTest::run_func() +{ +} + +bool Core_DynStructBaseTest::can_do_fast_forward() +{ + return false; +} + + +void Core_DynStructBaseTest::clear() +{ + cvtest::BaseTest::clear(); +} + + +int Core_DynStructBaseTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::BaseTest::read_params( fs ); + double sqrt_scale = sqrt(ts->get_test_case_count_scale()); + if( code < 0 ) + return code; + + struct_count = cvReadInt( find_param( fs, "struct_count" ), struct_count ); + max_struct_size = cvReadInt( find_param( fs, "max_struct_size" ), max_struct_size ); + generations = cvReadInt( find_param( fs, "generations" ), generations ); + iterations = cvReadInt( find_param( fs, "iterations" ), iterations ); + generations = cvRound(generations*sqrt_scale); + iterations = cvRound(iterations*sqrt_scale); + + min_log_storage_block_size = cvReadInt( find_param( fs, "min_log_storage_block_size" ), + min_log_storage_block_size ); + max_log_storage_block_size = cvReadInt( find_param( fs, "max_log_storage_block_size" ), + max_log_storage_block_size ); + min_log_elem_size = cvReadInt( find_param( fs, "min_log_elem_size" ), min_log_elem_size ); + max_log_elem_size = cvReadInt( find_param( fs, "max_log_elem_size" ), max_log_elem_size ); + + struct_count = cvtest::clipInt( struct_count, 1, 100 ); + max_struct_size = cvtest::clipInt( max_struct_size, 1, 1<<20 ); + generations = cvtest::clipInt( generations, 1, 100 ); + iterations = cvtest::clipInt( iterations, 100, 1<<20 ); + + min_log_storage_block_size = cvtest::clipInt( min_log_storage_block_size, 7, 20 ); + max_log_storage_block_size = cvtest::clipInt( max_log_storage_block_size, + min_log_storage_block_size, 20 ); + + min_log_elem_size = cvtest::clipInt( min_log_elem_size, 0, 8 ); + max_log_elem_size = cvtest::clipInt( max_log_elem_size, min_log_elem_size, 10 ); + + return 0; +} + + +void Core_DynStructBaseTest::update_progressbar() +{ + int64 t; + + if( test_progress < 0 ) + { + test_progress = 0; + cpu_freq = cv::getTickFrequency(); + start_time = cv::getTickCount(); + } + + t = cv::getTickCount(); + test_progress = update_progress( test_progress, 0, 0, (double)(t - start_time)/cpu_freq ); +} + + +void Core_DynStructBaseTest::set_error_context( const char* condition, + const char* err_msg, + const char* filename, int lineno ) +{ + ts->printf( cvtest::TS::LOG, "file %s, line %d: %s\n(\"%s\" failed).\n" + "generation = %d, struct_idx = %d, iter = %d\n", + filename, lineno, err_msg, condition, gen, struct_idx, iter ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); +} + + +int Core_DynStructBaseTest::test_seq_block_consistence( int _struct_idx, CvSeq* seq, int total ) +{ + int sum = 0; + struct_idx = _struct_idx; + + CV_TS_SEQ_CHECK_CONDITION( seq != 0, "Null sequence pointer" ); + + if( seq->first ) + { + CvSeqBlock* block = seq->first; + CvSeqBlock* prev_block = block->prev; + + int delta_idx = seq->first->start_index; + + for( ;; ) + { + CV_TS_SEQ_CHECK_CONDITION( sum == block->start_index - delta_idx && + block->count > 0 && block->prev == prev_block && + prev_block->next == block, + "sequence blocks are inconsistent" ); + sum += block->count; + prev_block = block; + block = block->next; + if( block == seq->first ) break; + } + + CV_TS_SEQ_CHECK_CONDITION( block->prev->count * seq->elem_size + + block->prev->data <= seq->block_max, + "block->data or block_max pointer are incorrect" ); + } + + CV_TS_SEQ_CHECK_CONDITION( seq->total == sum && sum == total, + "total number of elements is incorrect" ); + + return 0; +} + + +/////////////////////////////////// sequence tests //////////////////////////////////// + +class Core_SeqBaseTest : public Core_DynStructBaseTest +{ +public: + Core_SeqBaseTest(); + void clear(); + void run( int ); + +protected: + int test_multi_create(); + int test_get_seq_elem( int _struct_idx, int iters ); + int test_get_seq_reading( int _struct_idx, int iters ); + int test_seq_ops( int iters ); +}; + + +Core_SeqBaseTest::Core_SeqBaseTest() +{ +} + + +void Core_SeqBaseTest::clear() +{ + for( size_t i = 0; i < simple_struct.size(); i++ ) + cvTsReleaseSimpleSeq( (CvTsSimpleSeq**)&simple_struct[i] ); + Core_DynStructBaseTest::clear(); +} + + +int Core_SeqBaseTest::test_multi_create() +{ + vector writer(struct_count); + vector pos(struct_count); + vector index(struct_count); + int cur_count, elem_size; + RNG& rng = ts->get_rng(); + + for( int i = 0; i < struct_count; i++ ) + { + double t; + CvTsSimpleSeq* sseq; + + pos[i] = -1; + index[i] = i; + + t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size; + elem_size = cvRound( exp(t * CV_LOG2) ); + elem_size = MIN( elem_size, (int)(storage->block_size - sizeof(void*) - + sizeof(CvSeqBlock) - sizeof(CvMemBlock)) ); + + cvTsReleaseSimpleSeq( (CvTsSimpleSeq**)&simple_struct[i] ); + simple_struct[i] = sseq = cvTsCreateSimpleSeq( max_struct_size, elem_size ); + cxcore_struct[i] = 0; + sseq->count = cvtest::randInt( rng ) % max_struct_size; + Mat m( 1, MAX(sseq->count,1)*elem_size, CV_8UC1, sseq->array ); + cvtest::randUni( rng, m, Scalar::all(0), Scalar::all(256) ); + } + + for( cur_count = struct_count; cur_count > 0; cur_count-- ) + { + for(;;) + { + int k = cvtest::randInt( rng ) % cur_count; + struct_idx = index[k]; + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[struct_idx]; + + if( pos[struct_idx] < 0 ) + { + int hdr_size = (cvtest::randInt(rng) % 10)*4 + sizeof(CvSeq); + hdr_size = MIN( hdr_size, (int)(storage->block_size - sizeof(CvMemBlock)) ); + elem_size = sseq->elem_size; + + if( cvtest::randInt(rng) % 2 ) + { + cvStartWriteSeq( 0, hdr_size, elem_size, storage, &writer[struct_idx] ); + } + else + { + CvSeq* s; + s = cvCreateSeq( 0, hdr_size, elem_size, storage ); + cvStartAppendToSeq( s, &writer[struct_idx] ); + } + + cvSetSeqBlockSize( writer[struct_idx].seq, cvtest::randInt( rng ) % 10000 ); + pos[struct_idx] = 0; + } + + update_progressbar(); + if( pos[struct_idx] == sseq->count ) + { + cxcore_struct[struct_idx] = cvEndWriteSeq( &writer[struct_idx] ); + /* del index */ + for( ; k < cur_count-1; k++ ) + index[k] = index[k+1]; + break; + } + + { + schar* el = cvTsSimpleSeqElem( sseq, pos[struct_idx] ); + CV_WRITE_SEQ_ELEM_VAR( el, writer[struct_idx] ); + } + pos[struct_idx]++; + } + } + + return 0; +} + + +int Core_SeqBaseTest::test_get_seq_elem( int _struct_idx, int iters ) +{ + RNG& rng = ts->get_rng(); + + CvSeq* seq = (CvSeq*)cxcore_struct[_struct_idx]; + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[_struct_idx]; + struct_idx = _struct_idx; + + assert( seq->total == sseq->count ); + + if( sseq->count == 0 ) + return 0; + + for( int i = 0; i < iters; i++ ) + { + int idx = cvtest::randInt(rng) % (sseq->count*3) - sseq->count*3/2; + int idx0 = (unsigned)idx < (unsigned)(sseq->count) ? idx : idx < 0 ? + idx + sseq->count : idx - sseq->count; + int bad_range = (unsigned)idx0 >= (unsigned)(sseq->count); + schar* elem; + elem = cvGetSeqElem( seq, idx ); + + if( bad_range ) + { + CV_TS_SEQ_CHECK_CONDITION( elem == 0, + "cvGetSeqElem doesn't " + "handle \"out of range\" properly" ); + } + else + { + CV_TS_SEQ_CHECK_CONDITION( elem != 0 && + !memcmp( elem, cvTsSimpleSeqElem(sseq, idx0), sseq->elem_size ), + "cvGetSeqElem returns wrong element" ); + + idx = cvSeqElemIdx(seq, elem ); + CV_TS_SEQ_CHECK_CONDITION( idx >= 0 && idx == idx0, + "cvSeqElemIdx is incorrect" ); + } + } + + return 0; +} + + +int Core_SeqBaseTest::test_get_seq_reading( int _struct_idx, int iters ) +{ + const int max_val = 3*5 + 2; + CvSeq* seq = (CvSeq*)cxcore_struct[_struct_idx]; + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[_struct_idx]; + int total = seq->total; + RNG& rng = ts->get_rng(); + CvSeqReader reader; + vector _elem(sseq->elem_size); + schar* elem = &_elem[0]; + + assert( total == sseq->count ); + this->struct_idx = _struct_idx; + + int pos = cvtest::randInt(rng) % 2; + cvStartReadSeq( seq, &reader, pos ); + + if( total == 0 ) + { + CV_TS_SEQ_CHECK_CONDITION( reader.ptr == 0, "Empty sequence reader pointer is not NULL" ); + return 0; + } + + pos = pos ? seq->total - 1 : 0; + + CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos(&reader), + "initial reader position is wrong" ); + + for( iter = 0; iter < iters; iter++ ) + { + int op = cvtest::randInt(rng) % max_val; + + if( op >= max_val - 2 ) + { + int new_pos, new_pos0; + int bad_range; + int is_relative = op == max_val - 1; + + new_pos = cvtest::randInt(rng) % (total*2) - total; + new_pos0 = new_pos + (is_relative ? pos : 0 ); + + if( new_pos0 < 0 ) new_pos0 += total; + if( new_pos0 >= total ) new_pos0 -= total; + + bad_range = (unsigned)new_pos0 >= (unsigned)total; + cvSetSeqReaderPos( &reader, new_pos, is_relative ); + + if( !bad_range ) + { + CV_TS_SEQ_CHECK_CONDITION( new_pos0 == cvGetSeqReaderPos( &reader ), + "cvset reader position doesn't work" ); + pos = new_pos0; + } + else + { + CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ), + "reader doesn't stay at the current position after wrong positioning" ); + } + } + else + { + int direction = (op % 3) - 1; + memcpy( elem, reader.ptr, sseq->elem_size ); + + if( direction > 0 ) + { + CV_NEXT_SEQ_ELEM( sseq->elem_size, reader ); + } + else if( direction < 0 ) + { + CV_PREV_SEQ_ELEM( sseq->elem_size, reader ); + } + + CV_TS_SEQ_CHECK_CONDITION( memcmp(elem, cvTsSimpleSeqElem(sseq, pos), + sseq->elem_size) == 0, "reading is incorrect" ); + pos += direction; + if( -pos > 0 ) pos += total; + if( pos >= total ) pos -= total; + + CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ), + "reader doesn't move correctly after reading" ); + } + } + + return 0; +} + + +int Core_SeqBaseTest::test_seq_ops( int iters ) +{ + const int max_op = 14; + int max_elem_size = 0; + schar* elem2 = 0; + RNG& rng = ts->get_rng(); + + for( int i = 0; i < struct_count; i++ ) + max_elem_size = MAX( max_elem_size, ((CvSeq*)cxcore_struct[i])->elem_size ); + + vector elem_buf(max_struct_size*max_elem_size); + schar* elem = (schar*)&elem_buf[0]; + Mat elem_mat; + + for( iter = 0; iter < iters; iter++ ) + { + struct_idx = cvtest::randInt(rng) % struct_count; + int op = cvtest::randInt(rng) % max_op; + CvSeq* seq = (CvSeq*)cxcore_struct[struct_idx]; + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[struct_idx]; + int elem_size = sseq->elem_size; + int whence = 0, pos = 0, count = 0; + + switch( op ) + { + case 0: + case 1: + case 2: // push/pushfront/insert + if( sseq->count == sseq->max_count ) + break; + + elem_mat = Mat(1, elem_size, CV_8U, elem); + cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) ); + + whence = op - 1; + if( whence < 0 ) + { + pos = 0; + cvSeqPushFront( seq, elem ); + } + else if( whence > 0 ) + { + pos = sseq->count; + cvSeqPush( seq, elem ); + } + else + { + pos = cvtest::randInt(rng) % (sseq->count + 1); + cvSeqInsert( seq, pos, elem ); + } + + cvTsSimpleSeqShiftAndCopy( sseq, pos, pos + 1, elem ); + elem2 = cvGetSeqElem( seq, pos ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "The inserted element could not be retrieved" ); + CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count && + memcmp(elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0, + "The inserted sequence element is wrong" ); + break; + + case 3: + case 4: + case 5: // pop/popfront/remove + if( sseq->count == 0 ) + break; + + whence = op - 4; + if( whence < 0 ) + { + pos = 0; + cvSeqPopFront( seq, elem ); + } + else if( whence > 0 ) + { + pos = sseq->count-1; + cvSeqPop( seq, elem ); + } + else + { + pos = cvtest::randInt(rng) % sseq->count; + cvSeqRemove( seq, pos ); + } + + if( whence != 0 ) + CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count - 1 && + memcmp( elem, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0, + "The popped sequence element isn't correct" ); + + cvTsSimpleSeqShiftAndCopy( sseq, pos + 1, pos ); + + if( sseq->count > 0 ) + { + elem2 = cvGetSeqElem( seq, pos < sseq->count ? pos : -1 ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "GetSeqElem fails after removing the element" ); + + CV_TS_SEQ_CHECK_CONDITION( memcmp( elem2, + cvTsSimpleSeqElem(sseq, pos - (pos == sseq->count)), elem_size) == 0, + "The first shifted element is not correct after removing another element" ); + } + else + { + CV_TS_SEQ_CHECK_CONDITION( seq->first == 0, + "The sequence doesn't become empty after the final remove" ); + } + break; + + case 6: + case 7: + case 8: // push [front] multi/insert slice + if( sseq->count == sseq->max_count ) + break; + + count = cvtest::randInt( rng ) % (sseq->max_count - sseq->count + 1); + elem_mat = Mat(1, MAX(count,1) * elem_size, CV_8U, elem); + cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) ); + + whence = op - 7; + pos = whence < 0 ? 0 : whence > 0 ? sseq->count : (int)(cvtest::randInt(rng) % (sseq->count+1)); + if( whence != 0 ) + { + cvSeqPushMulti( seq, elem, count, whence < 0 ); + } + else + { + CvSeq header; + CvSeqBlock block; + cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(CvSeq), + sseq->elem_size, + elem, count, + &header, &block ); + + cvSeqInsertSlice( seq, pos, &header ); + } + cvTsSimpleSeqShiftAndCopy( sseq, pos, pos + count, elem ); + + if( sseq->count > 0 ) + { + // choose the random element among the added + pos = count > 0 ? (int)(cvtest::randInt(rng) % count + pos) : MAX(pos-1,0); + elem2 = cvGetSeqElem( seq, pos ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "multi push operation doesn't add elements" ); + CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count && + memcmp( elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0, + "One of the added elements is wrong" ); + } + else + { + CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0, + "Adding no elements to empty sequence fails" ); + } + break; + + case 9: + case 10: + case 11: // pop [front] multi + if( sseq->count == 0 ) + break; + + count = cvtest::randInt(rng) % (sseq->count+1); + whence = op - 10; + pos = whence < 0 ? 0 : whence > 0 ? sseq->count - count : + (int)(cvtest::randInt(rng) % (sseq->count - count + 1)); + + if( whence != 0 ) + { + cvSeqPopMulti( seq, elem, count, whence < 0 ); + + if( count > 0 ) + { + CV_TS_SEQ_CHECK_CONDITION( memcmp(elem, + cvTsSimpleSeqElem(sseq,pos), elem_size) == 0, + "The first (in the sequence order) removed element is wrong after popmulti" ); + } + } + else + { + cvSeqRemoveSlice( seq, cvSlice(pos, pos + count) ); + } + + CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count - count, + "The popmulti left a wrong number of elements in the sequence" ); + + cvTsSimpleSeqShiftAndCopy( sseq, pos + count, pos, 0 ); + if( sseq->count > 0 ) + { + pos = whence < 0 ? 0 : MIN( pos, sseq->count - 1 ); + elem2 = cvGetSeqElem( seq, pos ); + CV_TS_SEQ_CHECK_CONDITION( elem2 && + memcmp( elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0, + "The last sequence element is wrong after POP" ); + } + else + { + CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0, + "The sequence doesn't become empty after final POP" ); + } + break; + case 12: // seqslice + { + CvMemStoragePos storage_pos; + cvSaveMemStoragePos( storage, &storage_pos ); + + int copy_data = cvtest::randInt(rng) % 2; + count = cvtest::randInt(rng) % (seq->total + 1); + pos = cvtest::randInt(rng) % (seq->total - count + 1); + CvSeq* seq_slice = cvSeqSlice( seq, cvSlice(pos, pos + count), storage, copy_data ); + + CV_TS_SEQ_CHECK_CONDITION( seq_slice && seq_slice->total == count, + "cvSeqSlice returned incorrect slice" ); + + if( count > 0 ) + { + int test_idx = cvtest::randInt(rng) % count; + elem2 = cvGetSeqElem( seq_slice, test_idx ); + schar* elem3 = cvGetSeqElem( seq, pos + test_idx ); + CV_TS_SEQ_CHECK_CONDITION( elem2 && + memcmp( elem2, cvTsSimpleSeqElem(sseq,pos + test_idx), elem_size) == 0, + "The extracted slice elements are not correct" ); + CV_TS_SEQ_CHECK_CONDITION( (elem2 == elem3) ^ copy_data, + "copy_data flag is handled incorrectly" ); + } + + cvRestoreMemStoragePos( storage, &storage_pos ); + } + break; + case 13: // clear + cvTsClearSimpleSeq( sseq ); + cvClearSeq( seq ); + CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0, + "The sequence doesn't become empty after clear" ); + break; + default: + assert(0); + return -1; + } + + if( test_seq_block_consistence(struct_idx, seq, sseq->count) < 0 ) + return -1; + + if( test_get_seq_elem(struct_idx, 7) < 0 ) + return -1; + + update_progressbar(); + } + + return 0; +} + + +void Core_SeqBaseTest::run( int ) +{ + try + { + RNG& rng = ts->get_rng(); + int i; + double t; + + clear(); + test_progress = -1; + + simple_struct.resize(struct_count, 0); + cxcore_struct.resize(struct_count, 0); + + for( gen = 0; gen < generations; gen++ ) + { + struct_idx = iter = -1; + + if( !storage ) + { + t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + + min_log_storage_block_size; + storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ); + } + + iter = struct_idx = -1; + test_multi_create(); + + for( i = 0; i < struct_count; i++ ) + { + if( test_seq_block_consistence(i, (CvSeq*)cxcore_struct[i], + ((CvTsSimpleSeq*)simple_struct[i])->count) < 0 ) + return; + + if( test_get_seq_elem( i, MAX(iterations/3,7) ) < 0 ) + return; + + if( test_get_seq_reading( i, MAX(iterations/3,7) ) < 0 ) + return; + update_progressbar(); + } + + if( test_seq_ops( iterations ) < 0 ) + return; + + if( cvtest::randInt(rng) % 2 ) + storage.release(); + else + cvClearMemStorage( storage ); + } + } + catch(int) + { + } +} + + +////////////////////////////// more sequence tests ////////////////////////////////////// + +class Core_SeqSortInvTest : public Core_SeqBaseTest +{ +public: + Core_SeqSortInvTest(); + void run( int ); + +protected: +}; + + +Core_SeqSortInvTest::Core_SeqSortInvTest() +{ +} + + +static int icvCmpSeqElems( const void* a, const void* b, void* userdata ) +{ + return memcmp( a, b, ((CvSeq*)userdata)->elem_size ); +} + +static int icvCmpSeqElems2_elem_size = 0; +static int icvCmpSeqElems2( const void* a, const void* b ) +{ + return memcmp( a, b, icvCmpSeqElems2_elem_size ); +} + + +void Core_SeqSortInvTest::run( int ) +{ + try + { + RNG& rng = ts->get_rng(); + int i, k; + double t; + schar *elem0, *elem, *elem2; + vector buffer; + + clear(); + test_progress = -1; + + simple_struct.resize(struct_count, 0); + cxcore_struct.resize(struct_count, 0); + + for( gen = 0; gen < generations; gen++ ) + { + struct_idx = iter = -1; + + if( storage.empty() ) + { + t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + + min_log_storage_block_size; + storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ); + } + + for( iter = 0; iter < iterations/10; iter++ ) + { + int max_size = 0; + test_multi_create(); + + for( i = 0; i < struct_count; i++ ) + { + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[i]; + max_size = MAX( max_size, sseq->count*sseq->elem_size ); + } + + buffer.resize(max_size); + + for( i = 0; i < struct_count; i++ ) + { + CvSeq* seq = (CvSeq*)cxcore_struct[i]; + CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[i]; + CvSlice slice = CV_WHOLE_SEQ; + + //printf("%d. %d. %d-th size = %d\n", gen, iter, i, sseq->count ); + + cvSeqInvert( seq ); + cvTsSimpleSeqInvert( sseq ); + + if( test_seq_block_consistence( i, seq, sseq->count ) < 0 ) + return; + + if( sseq->count > 0 && cvtest::randInt(rng) % 2 == 0 ) + { + slice.end_index = cvtest::randInt(rng) % sseq->count + 1; + slice.start_index = cvtest::randInt(rng) % (sseq->count - slice.end_index + 1); + slice.end_index += slice.start_index; + } + + cvCvtSeqToArray( seq, &buffer[0], slice ); + + slice.end_index = MIN( slice.end_index, sseq->count ); + CV_TS_SEQ_CHECK_CONDITION( sseq->count == 0 || memcmp( &buffer[0], + sseq->array + slice.start_index*sseq->elem_size, + (slice.end_index - slice.start_index)*sseq->elem_size ) == 0, + "cvSeqInvert returned wrong result" ); + + for( k = 0; k < (sseq->count > 0 ? 10 : 0); k++ ) + { + int idx0 = cvtest::randInt(rng) % sseq->count, idx = 0; + elem0 = cvTsSimpleSeqElem( sseq, idx0 ); + elem = cvGetSeqElem( seq, idx0 ); + elem2 = cvSeqSearch( seq, elem0, k % 2 ? icvCmpSeqElems : 0, 0, &idx, seq ); + + CV_TS_SEQ_CHECK_CONDITION( elem != 0 && + memcmp( elem0, elem, seq->elem_size ) == 0, + "cvSeqInvert gives incorrect result" ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 && + memcmp( elem0, elem2, seq->elem_size ) == 0 && + elem2 == cvGetSeqElem( seq, idx ), + "cvSeqSearch failed (linear search)" ); + } + + cvSeqSort( seq, icvCmpSeqElems, seq ); + + if( test_seq_block_consistence( i, seq, sseq->count ) < 0 ) + return; + + if( sseq->count > 0 ) + { + // !!! This is not thread-safe !!! + icvCmpSeqElems2_elem_size = sseq->elem_size; + qsort( sseq->array, sseq->count, sseq->elem_size, icvCmpSeqElems2 ); + + if( cvtest::randInt(rng) % 2 == 0 ) + { + slice.end_index = cvtest::randInt(rng) % sseq->count + 1; + slice.start_index = cvtest::randInt(rng) % (sseq->count - slice.end_index + 1); + slice.end_index += slice.start_index; + } + } + + cvCvtSeqToArray( seq, &buffer[0], slice ); + CV_TS_SEQ_CHECK_CONDITION( sseq->count == 0 || memcmp( &buffer[0], + sseq->array + slice.start_index*sseq->elem_size, + (slice.end_index - slice.start_index)*sseq->elem_size ) == 0, + "cvSeqSort returned wrong result" ); + + for( k = 0; k < (sseq->count > 0 ? 10 : 0); k++ ) + { + int idx0 = cvtest::randInt(rng) % sseq->count, idx = 0; + elem0 = cvTsSimpleSeqElem( sseq, idx0 ); + elem = cvGetSeqElem( seq, idx0 ); + elem2 = cvSeqSearch( seq, elem0, icvCmpSeqElems, 1, &idx, seq ); + + CV_TS_SEQ_CHECK_CONDITION( elem != 0 && + memcmp( elem0, elem, seq->elem_size ) == 0, + "cvSeqSort gives incorrect result" ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 && + memcmp( elem0, elem2, seq->elem_size ) == 0 && + elem2 == cvGetSeqElem( seq, idx ), + "cvSeqSearch failed (binary search)" ); + } + } + + cvClearMemStorage( storage ); + } + + storage.release(); + } + } + catch (int) + { + } +} + + +/////////////////////////////////////// set tests /////////////////////////////////////// + +class Core_SetTest : public Core_DynStructBaseTest +{ +public: + Core_SetTest(); + void clear(); + void run( int ); + +protected: + //int test_seq_block_consistence( int struct_idx ); + int test_set_ops( int iters ); +}; + + +Core_SetTest::Core_SetTest() +{ +} + + +void Core_SetTest::clear() +{ + for( size_t i = 0; i < simple_struct.size(); i++ ) + cvTsReleaseSimpleSet( (CvTsSimpleSet**)&simple_struct[i] ); + Core_DynStructBaseTest::clear(); +} + + +int Core_SetTest::test_set_ops( int iters ) +{ + const int max_op = 4; + int max_elem_size = 0; + int idx, idx0; + CvSetElem *elem = 0, *elem2 = 0, *elem3 = 0; + schar* elem_data = 0; + RNG& rng = ts->get_rng(); + //int max_active_count = 0, mean_active_count = 0; + + for( int i = 0; i < struct_count; i++ ) + max_elem_size = MAX( max_elem_size, ((CvSeq*)cxcore_struct[i])->elem_size ); + + vector elem_buf(max_elem_size); + Mat elem_mat; + + for( iter = 0; iter < iters; iter++ ) + { + struct_idx = cvtest::randInt(rng) % struct_count; + + CvSet* cvset = (CvSet*)cxcore_struct[struct_idx]; + CvTsSimpleSet* sset = (CvTsSimpleSet*)simple_struct[struct_idx]; + int pure_elem_size = sset->elem_size - 1; + int prev_total = cvset->total, prev_count = cvset->active_count; + int op = cvtest::randInt(rng) % (iter <= iters/10 ? 2 : max_op); + int by_ptr = op % 2 == 0; + CvSetElem* first_free = cvset->free_elems; + CvSetElem* next_free = first_free ? first_free->next_free : 0; + int pass_data = 0; + + if( iter > iters/10 && cvtest::randInt(rng)%200 == 0 ) // clear set + { + prev_count = cvset->total; + cvClearSet( cvset ); + cvTsClearSimpleSet( sset ); + + CV_TS_SEQ_CHECK_CONDITION( cvset->active_count == 0 && cvset->total == 0 && + cvset->first == 0 && cvset->free_elems == 0 && + (cvset->free_blocks != 0 || prev_count == 0), + "cvClearSet doesn't remove all the elements" ); + continue; + } + else if( op == 0 || op == 1 ) // add element + { + if( sset->free_count == 0 ) + continue; + + elem_mat = Mat(1, cvset->elem_size, CV_8U, &elem_buf[0]); + cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) ); + elem = (CvSetElem*)&elem_buf[0]; + + if( by_ptr ) + { + elem2 = cvSetNew( cvset ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "cvSetNew returned NULL pointer" ); + } + else + { + pass_data = cvtest::randInt(rng) % 2; + idx = cvSetAdd( cvset, pass_data ? elem : 0, &elem2 ); + CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 && elem2->flags == idx, + "cvSetAdd returned NULL pointer or a wrong index" ); + } + + elem_data = (schar*)elem + sizeof(int); + + if( !pass_data ) + memcpy( (schar*)elem2 + sizeof(int), elem_data, pure_elem_size ); + + idx = elem2->flags; + idx0 = cvTsSimpleSetAdd( sset, elem_data ); + elem3 = cvGetSetElem( cvset, idx ); + + CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(elem3) && + idx == idx0 && elem3 == elem2 && (!pass_data || + memcmp( (char*)elem3 + sizeof(int), elem_data, pure_elem_size) == 0), + "The added element is not correct" ); + + CV_TS_SEQ_CHECK_CONDITION( (!first_free || elem3 == first_free) && + (!next_free || cvset->free_elems == next_free) && + cvset->active_count == prev_count + 1, + "The free node list is modified incorrectly" ); + } + else if( op == 2 || op == 3 ) // remove element + { + idx = cvtest::randInt(rng) % sset->max_count; + + if( sset->free_count == sset->max_count || idx >= sset->count ) + continue; + + elem_data = cvTsSimpleSetFind(sset, idx); + if( elem_data == 0 ) + continue; + + elem = cvGetSetElem( cvset, idx ); + CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(elem) && elem->flags == idx && + memcmp((char*)elem + sizeof(int), elem_data, pure_elem_size) == 0, + "cvGetSetElem returned wrong element" ); + + if( by_ptr ) + { + cvSetRemoveByPtr( cvset, elem ); + } + else + { + cvSetRemove( cvset, idx ); + } + + cvTsSimpleSetRemove( sset, idx ); + + CV_TS_SEQ_CHECK_CONDITION( !CV_IS_SET_ELEM(elem) && !cvGetSetElem(cvset, idx) && + (elem->flags & CV_SET_ELEM_IDX_MASK) == idx, + "cvSetRemove[ByPtr] didn't release the element properly" ); + + CV_TS_SEQ_CHECK_CONDITION( elem->next_free == first_free && + cvset->free_elems == elem && + cvset->active_count == prev_count - 1, + "The free node list has not been updated properly" ); + } + + //max_active_count = MAX( max_active_count, cvset->active_count ); + //mean_active_count += cvset->active_count; + CV_TS_SEQ_CHECK_CONDITION( cvset->active_count == sset->max_count - sset->free_count && + cvset->total >= cvset->active_count && + (cvset->total == 0 || cvset->total >= prev_total), + "The total number of cvset elements is not correct" ); + + // CvSet and simple set do not neccessary have the same "total" (active & free) number, + // so pass "set->total" to skip that check + test_seq_block_consistence( struct_idx, (CvSeq*)cvset, cvset->total ); + update_progressbar(); + } + + return 0; +} + + +void Core_SetTest::run( int ) +{ + try + { + RNG& rng = ts->get_rng(); + double t; + + clear(); + test_progress = -1; + + simple_struct.resize(struct_count, 0); + cxcore_struct.resize(struct_count, 0); + + for( gen = 0; gen < generations; gen++ ) + { + struct_idx = iter = -1; + t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size; + storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ); + + for( int i = 0; i < struct_count; i++ ) + { + t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size; + int pure_elem_size = cvRound( exp(t * CV_LOG2) ); + int elem_size = pure_elem_size + sizeof(int); + elem_size = (elem_size + sizeof(size_t) - 1) & ~(sizeof(size_t)-1); + elem_size = MAX( elem_size, (int)sizeof(CvSetElem) ); + elem_size = MIN( elem_size, (int)(storage->block_size - sizeof(void*) - sizeof(CvMemBlock) - sizeof(CvSeqBlock)) ); + pure_elem_size = MIN( pure_elem_size, elem_size-(int)sizeof(CvSetElem) ); + + cvTsReleaseSimpleSet( (CvTsSimpleSet**)&simple_struct[i] ); + simple_struct[i] = cvTsCreateSimpleSet( max_struct_size, pure_elem_size ); + cxcore_struct[i] = cvCreateSet( 0, sizeof(CvSet), elem_size, storage ); + } + + if( test_set_ops( iterations*100 ) < 0 ) + return; + + storage.release(); + } + } + catch(int) + { + } +} + + +/////////////////////////////////////// graph tests ////////////////////////////////// + +class Core_GraphTest : public Core_DynStructBaseTest +{ +public: + Core_GraphTest(); + void clear(); + void run( int ); + +protected: + //int test_seq_block_consistence( int struct_idx ); + int test_graph_ops( int iters ); +}; + + +Core_GraphTest::Core_GraphTest() +{ +} + + +void Core_GraphTest::clear() +{ + for( size_t i = 0; i < simple_struct.size(); i++ ) + cvTsReleaseSimpleGraph( (CvTsSimpleGraph**)&simple_struct[i] ); + Core_DynStructBaseTest::clear(); +} + + +int Core_GraphTest::test_graph_ops( int iters ) +{ + const int max_op = 4; + int i, k; + int max_elem_size = 0; + int idx, idx0; + CvGraphVtx *vtx = 0, *vtx2 = 0, *vtx3 = 0; + CvGraphEdge* edge = 0, *edge2 = 0; + RNG& rng = ts->get_rng(); + //int max_active_count = 0, mean_active_count = 0; + + for( i = 0; i < struct_count; i++ ) + { + CvGraph* graph = (CvGraph*)cxcore_struct[i]; + max_elem_size = MAX( max_elem_size, graph->elem_size ); + max_elem_size = MAX( max_elem_size, graph->edges->elem_size ); + } + + vector elem_buf(max_elem_size); + Mat elem_mat; + + for( iter = 0; iter < iters; iter++ ) + { + struct_idx = cvtest::randInt(rng) % struct_count; + CvGraph* graph = (CvGraph*)cxcore_struct[struct_idx]; + CvTsSimpleGraph* sgraph = (CvTsSimpleGraph*)simple_struct[struct_idx]; + CvSet* edges = graph->edges; + schar *vtx_data; + char *edge_data; + int pure_vtx_size = sgraph->vtx->elem_size - 1, + pure_edge_size = sgraph->edge_size - 1; + int prev_vtx_total = graph->total, + prev_edge_total = graph->edges->total, + prev_vtx_count = graph->active_count, + prev_edge_count = graph->edges->active_count; + int op = cvtest::randInt(rng) % max_op; + int pass_data = 0, vtx_degree0 = 0, vtx_degree = 0; + CvSetElem *first_free, *next_free; + + if( cvtest::randInt(rng) % 200 == 0 ) // clear graph + { + int prev_vtx_count2 = graph->total, prev_edge_count2 = graph->edges->total; + + cvClearGraph( graph ); + cvTsClearSimpleGraph( sgraph ); + + CV_TS_SEQ_CHECK_CONDITION( graph->active_count == 0 && graph->total == 0 && + graph->first == 0 && graph->free_elems == 0 && + (graph->free_blocks != 0 || prev_vtx_count2 == 0), + "The graph is not empty after clearing" ); + + CV_TS_SEQ_CHECK_CONDITION( edges->active_count == 0 && edges->total == 0 && + edges->first == 0 && edges->free_elems == 0 && + (edges->free_blocks != 0 || prev_edge_count2 == 0), + "The graph is not empty after clearing" ); + } + else if( op == 0 ) // add vertex + { + if( sgraph->vtx->free_count == 0 ) + continue; + + first_free = graph->free_elems; + next_free = first_free ? first_free->next_free : 0; + + if( pure_vtx_size ) + { + elem_mat = Mat(1, graph->elem_size, CV_8U, &elem_buf[0]); + cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) ); + } + + vtx = (CvGraphVtx*)&elem_buf[0]; + idx0 = cvTsSimpleGraphAddVertex( sgraph, vtx + 1 ); + + pass_data = cvtest::randInt(rng) % 2; + idx = cvGraphAddVtx( graph, pass_data ? vtx : 0, &vtx2 ); + + if( !pass_data && pure_vtx_size > 0 ) + memcpy( vtx2 + 1, vtx + 1, pure_vtx_size ); + + vtx3 = cvGetGraphVtx( graph, idx ); + + CV_TS_SEQ_CHECK_CONDITION( (CV_IS_SET_ELEM(vtx3) && vtx3->flags == idx && + vtx3->first == 0) || (idx == idx0 && vtx3 == vtx2 && + (!pass_data || pure_vtx_size == 0 || + memcmp(vtx3 + 1, vtx + 1, pure_vtx_size) == 0)), + "The added element is not correct" ); + + CV_TS_SEQ_CHECK_CONDITION( (!first_free || first_free == (CvSetElem*)vtx3) && + (!next_free || graph->free_elems == next_free) && + graph->active_count == prev_vtx_count + 1, + "The free node list is modified incorrectly" ); + } + else if( op == 1 ) // remove vertex + { + idx = cvtest::randInt(rng) % sgraph->vtx->max_count; + if( sgraph->vtx->free_count == sgraph->vtx->max_count || idx >= sgraph->vtx->count ) + continue; + + vtx_data = cvTsSimpleGraphFindVertex(sgraph, idx); + if( vtx_data == 0 ) + continue; + + vtx_degree0 = cvTsSimpleGraphVertexDegree( sgraph, idx ); + first_free = graph->free_elems; + + vtx = cvGetGraphVtx( graph, idx ); + CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(vtx) && vtx->flags == idx && + (pure_vtx_size == 0 || memcmp( vtx + 1, vtx_data, pure_vtx_size) == 0), + "cvGetGraphVtx returned wrong element" ); + + if( cvtest::randInt(rng) % 2 ) + { + vtx_degree = cvGraphVtxDegreeByPtr( graph, vtx ); + cvGraphRemoveVtxByPtr( graph, vtx ); + } + else + { + vtx_degree = cvGraphVtxDegree( graph, idx ); + cvGraphRemoveVtx( graph, idx ); + } + + cvTsSimpleGraphRemoveVertex( sgraph, idx ); + + CV_TS_SEQ_CHECK_CONDITION( vtx_degree == vtx_degree0, + "Number of incident edges is different in two graph representations" ); + + CV_TS_SEQ_CHECK_CONDITION( !CV_IS_SET_ELEM(vtx) && !cvGetGraphVtx(graph, idx) && + (vtx->flags & CV_SET_ELEM_IDX_MASK) == idx, + "cvGraphRemoveVtx[ByPtr] didn't release the vertex properly" ); + + CV_TS_SEQ_CHECK_CONDITION( graph->edges->active_count == prev_edge_count - vtx_degree, + "cvGraphRemoveVtx[ByPtr] didn't remove all the incident edges " + "(or removed some extra)" ); + + CV_TS_SEQ_CHECK_CONDITION( ((CvSetElem*)vtx)->next_free == first_free && + graph->free_elems == (CvSetElem*)vtx && + graph->active_count == prev_vtx_count - 1, + "The free node list has not been updated properly" ); + } + else if( op == 2 ) // add edge + { + int v_idx[2] = {0,0}, res = 0; + int v_prev_degree[2] = {0,0}, v_degree[2] = {0,0}; + + if( sgraph->vtx->free_count >= sgraph->vtx->max_count-1 ) + continue; + + for( i = 0, k = 0; i < 10; i++ ) + { + int j = cvtest::randInt(rng) % sgraph->vtx->count; + vtx_data = cvTsSimpleGraphFindVertex( sgraph, j ); + if( vtx_data ) + { + v_idx[k] = j; + if( k == 0 ) + k++; + else if( v_idx[0] != v_idx[1] && + cvTsSimpleGraphFindEdge( sgraph, v_idx[0], v_idx[1] ) == 0 ) + { + k++; + break; + } + } + } + + if( k < 2 ) + continue; + + first_free = graph->edges->free_elems; + next_free = first_free ? first_free->next_free : 0; + + edge = cvFindGraphEdge( graph, v_idx[0], v_idx[1] ); + CV_TS_SEQ_CHECK_CONDITION( edge == 0, "Extra edge appeared in the graph" ); + + if( pure_edge_size > 0 ) + { + elem_mat = Mat(1, graph->edges->elem_size, CV_8U, &elem_buf[0]); + cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) ); + } + edge = (CvGraphEdge*)&elem_buf[0]; + + // assign some default weight that is easy to check for + // consistensy, 'cause an edge weight is not stored + // in the simple graph + edge->weight = (float)(v_idx[0] + v_idx[1]); + pass_data = cvtest::randInt(rng) % 2; + + vtx = cvGetGraphVtx( graph, v_idx[0] ); + vtx2 = cvGetGraphVtx( graph, v_idx[1] ); + CV_TS_SEQ_CHECK_CONDITION( vtx != 0 && vtx2 != 0 && vtx->flags == v_idx[0] && + vtx2->flags == v_idx[1], "Some of the vertices are missing" ); + + if( cvtest::randInt(rng) % 2 ) + { + v_prev_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx ); + v_prev_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 ); + res = cvGraphAddEdgeByPtr(graph, vtx, vtx2, pass_data ? edge : 0, &edge2); + v_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx ); + v_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 ); + } + else + { + v_prev_degree[0] = cvGraphVtxDegree( graph, v_idx[0] ); + v_prev_degree[1] = cvGraphVtxDegree( graph, v_idx[1] ); + res = cvGraphAddEdge(graph, v_idx[0], v_idx[1], pass_data ? edge : 0, &edge2); + v_degree[0] = cvGraphVtxDegree( graph, v_idx[0] ); + v_degree[1] = cvGraphVtxDegree( graph, v_idx[1] ); + } + + //edge3 = (CvGraphEdge*)cvGetSetElem( graph->edges, idx ); + CV_TS_SEQ_CHECK_CONDITION( res == 1 && edge2 != 0 && CV_IS_SET_ELEM(edge2) && + ((edge2->vtx[0] == vtx && edge2->vtx[1] == vtx2) || + (!CV_IS_GRAPH_ORIENTED(graph) && edge2->vtx[0] == vtx2 && edge2->vtx[1] == vtx)) && + (!pass_data || pure_edge_size == 0 || memcmp( edge2 + 1, edge + 1, pure_edge_size ) == 0), + "The edge has been added incorrectly" ); + + if( !pass_data ) + { + if( pure_edge_size > 0 ) + memcpy( edge2 + 1, edge + 1, pure_edge_size ); + edge2->weight = edge->weight; + } + + CV_TS_SEQ_CHECK_CONDITION( v_degree[0] == v_prev_degree[0] + 1 && + v_degree[1] == v_prev_degree[1] + 1, + "The vertices lists have not been updated properly" ); + + cvTsSimpleGraphAddEdge( sgraph, v_idx[0], v_idx[1], edge + 1 ); + + CV_TS_SEQ_CHECK_CONDITION( (!first_free || first_free == (CvSetElem*)edge2) && + (!next_free || graph->edges->free_elems == next_free) && + graph->edges->active_count == prev_edge_count + 1, + "The free node list is modified incorrectly" ); + } + else if( op == 3 ) // find & remove edge + { + int v_idx[2] = {0,0}, by_ptr; + int v_prev_degree[2] = {0,0}, v_degree[2] = {0,0}; + + if( sgraph->vtx->free_count >= sgraph->vtx->max_count-1 ) + continue; + + edge_data = 0; + for( i = 0, k = 0; i < 10; i++ ) + { + int j = cvtest::randInt(rng) % sgraph->vtx->count; + vtx_data = cvTsSimpleGraphFindVertex( sgraph, j ); + if( vtx_data ) + { + v_idx[k] = j; + if( k == 0 ) + k++; + else + { + edge_data = cvTsSimpleGraphFindEdge( sgraph, v_idx[0], v_idx[1] ); + if( edge_data ) + { + k++; + break; + } + } + } + } + + if( k < 2 ) + continue; + + by_ptr = cvtest::randInt(rng) % 2; + first_free = graph->edges->free_elems; + + vtx = cvGetGraphVtx( graph, v_idx[0] ); + vtx2 = cvGetGraphVtx( graph, v_idx[1] ); + CV_TS_SEQ_CHECK_CONDITION( vtx != 0 && vtx2 != 0 && vtx->flags == v_idx[0] && + vtx2->flags == v_idx[1], "Some of the vertices are missing" ); + + if( by_ptr ) + { + edge = cvFindGraphEdgeByPtr( graph, vtx, vtx2 ); + v_prev_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx ); + v_prev_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 ); + } + else + { + edge = cvFindGraphEdge( graph, v_idx[0], v_idx[1] ); + v_prev_degree[0] = cvGraphVtxDegree( graph, v_idx[0] ); + v_prev_degree[1] = cvGraphVtxDegree( graph, v_idx[1] ); + } + + idx = edge->flags; + + CV_TS_SEQ_CHECK_CONDITION( edge != 0 && edge->weight == v_idx[0] + v_idx[1] && + ((edge->vtx[0] == vtx && edge->vtx[1] == vtx2) || + (!CV_IS_GRAPH_ORIENTED(graph) && edge->vtx[1] == vtx && edge->vtx[0] == vtx2)) && + (pure_edge_size == 0 || memcmp(edge + 1, edge_data, pure_edge_size) == 0), + "An edge is missing or incorrect" ); + + if( by_ptr ) + { + cvGraphRemoveEdgeByPtr( graph, vtx, vtx2 ); + edge2 = cvFindGraphEdgeByPtr( graph, vtx, vtx2 ); + v_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx ); + v_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 ); + } + else + { + cvGraphRemoveEdge(graph, v_idx[0], v_idx[1] ); + edge2 = cvFindGraphEdge( graph, v_idx[0], v_idx[1] ); + v_degree[0] = cvGraphVtxDegree( graph, v_idx[0] ); + v_degree[1] = cvGraphVtxDegree( graph, v_idx[1] ); + } + + CV_TS_SEQ_CHECK_CONDITION( !edge2 && !CV_IS_SET_ELEM(edge), + "The edge has not been removed from the edge set" ); + + CV_TS_SEQ_CHECK_CONDITION( v_degree[0] == v_prev_degree[0] - 1 && + v_degree[1] == v_prev_degree[1] - 1, + "The vertices lists have not been updated properly" ); + + cvTsSimpleGraphRemoveEdge( sgraph, v_idx[0], v_idx[1] ); + + CV_TS_SEQ_CHECK_CONDITION( graph->edges->free_elems == (CvSetElem*)edge && + graph->edges->free_elems->next_free == first_free && + graph->edges->active_count == prev_edge_count - 1, + "The free edge list has not been modified properly" ); + } + + //max_active_count = MAX( max_active_count, graph->active_count ); + //mean_active_count += graph->active_count; + + CV_TS_SEQ_CHECK_CONDITION( graph->active_count == sgraph->vtx->max_count - sgraph->vtx->free_count && + graph->total >= graph->active_count && + (graph->total == 0 || graph->total >= prev_vtx_total), + "The total number of graph vertices is not correct" ); + + CV_TS_SEQ_CHECK_CONDITION( graph->edges->total >= graph->edges->active_count && + (graph->edges->total == 0 || graph->edges->total >= prev_edge_total), + "The total number of graph vertices is not correct" ); + + // CvGraph and simple graph do not neccessary have the same "total" (active & free) number, + // so pass "graph->total" (or "graph->edges->total") to skip that check + test_seq_block_consistence( struct_idx, (CvSeq*)graph, graph->total ); + test_seq_block_consistence( struct_idx, (CvSeq*)graph->edges, graph->edges->total ); + update_progressbar(); + } + + return 0; +} + + +void Core_GraphTest::run( int ) +{ + try + { + RNG& rng = ts->get_rng(); + int i, k; + double t; + + clear(); + test_progress = -1; + + simple_struct.resize(struct_count, 0); + cxcore_struct.resize(struct_count, 0); + + for( gen = 0; gen < generations; gen++ ) + { + struct_idx = iter = -1; + t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size; + int block_size = cvRound( exp(t * CV_LOG2) ); + block_size = MAX(block_size, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock))); + + storage = cvCreateMemStorage(block_size); + + for( i = 0; i < struct_count; i++ ) + { + int pure_elem_size[2], elem_size[2]; + int is_oriented = (gen + i) % 2; + for( k = 0; k < 2; k++ ) + { + t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size; + int pe = cvRound( exp(t * CV_LOG2) ) - 1; // pure_elem_size==0 does also make sense + int delta = k == 0 ? sizeof(CvGraphVtx) : sizeof(CvGraphEdge); + int e = pe + delta; + e = (e + sizeof(size_t) - 1) & ~(sizeof(size_t)-1); + e = MIN( e, (int)(storage->block_size - sizeof(CvMemBlock) - + sizeof(CvSeqBlock) - sizeof(void*)) ); + pe = MIN(pe, e - delta); + pure_elem_size[k] = pe; + elem_size[k] = e; + } + + cvTsReleaseSimpleGraph( (CvTsSimpleGraph**)&simple_struct[i] ); + simple_struct[i] = cvTsCreateSimpleGraph( max_struct_size/4, pure_elem_size[0], + pure_elem_size[1], is_oriented ); + cxcore_struct[i] = cvCreateGraph( is_oriented ? CV_ORIENTED_GRAPH : CV_GRAPH, + sizeof(CvGraph), elem_size[0], elem_size[1], + storage ); + } + + if( test_graph_ops( iterations*10 ) < 0 ) + return; + + storage.release(); + } + } + catch(int) + { + } +} + + +//////////// graph scan test ////////////// + +class Core_GraphScanTest : public Core_DynStructBaseTest +{ +public: + Core_GraphScanTest(); + void run( int ); + +protected: + //int test_seq_block_consistence( int struct_idx ); + int create_random_graph( int ); +}; + + +Core_GraphScanTest::Core_GraphScanTest() +{ + iterations = 100; + struct_count = 1; +} + + +int Core_GraphScanTest::create_random_graph( int _struct_idx ) +{ + RNG& rng = ts->get_rng(); + int is_oriented = cvtest::randInt(rng) % 2; + int i, vtx_count = cvtest::randInt(rng) % max_struct_size; + int edge_count = cvtest::randInt(rng) % MAX(vtx_count*20, 1); + CvGraph* graph; + + struct_idx = _struct_idx; + cxcore_struct[_struct_idx] = graph = + cvCreateGraph(is_oriented ? CV_ORIENTED_GRAPH : CV_GRAPH, + sizeof(CvGraph), sizeof(CvGraphVtx), + sizeof(CvGraphEdge), storage ); + + for( i = 0; i < vtx_count; i++ ) + cvGraphAddVtx( graph ); + + assert( graph->active_count == vtx_count ); + + for( i = 0; i < edge_count; i++ ) + { + int j = cvtest::randInt(rng) % vtx_count; + int k = cvtest::randInt(rng) % vtx_count; + + if( j != k ) + cvGraphAddEdge( graph, j, k ); + } + + assert( graph->active_count == vtx_count && graph->edges->active_count <= edge_count ); + + return 0; +} + + +void Core_GraphScanTest::run( int ) +{ + CvGraphScanner* scanner = 0; + try + { + RNG& rng = ts->get_rng(); + vector vtx_mask, edge_mask; + double t; + int i; + + clear(); + test_progress = -1; + + cxcore_struct.resize(struct_count, 0); + + for( gen = 0; gen < generations; gen++ ) + { + struct_idx = iter = -1; + t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size; + int storage_blocksize = cvRound( exp(t * CV_LOG2) ); + storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock))); + storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphEdge) + sizeof(CvMemBlock) + sizeof(CvSeqBlock))); + storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphVtx) + sizeof(CvMemBlock) + sizeof(CvSeqBlock))); + storage = cvCreateMemStorage(storage_blocksize); + + if( gen == 0 ) + { + // special regression test for one sample graph. + // !!! ATTENTION !!! The test relies on the particular order of the inserted edges + // (LIFO: the edge inserted last goes first in the list of incident edges). + // if it is changed, the test will have to be modified. + + int vtx_count = -1, edge_count = 0, edges[][3] = + { + {0,4,'f'}, {0,1,'t'}, {1,4,'t'}, {1,2,'t'}, {2,3,'t'}, {4,3,'c'}, {3,1,'b'}, + {5,7,'t'}, {7,5,'b'}, {5,6,'t'}, {6,0,'c'}, {7,6,'c'}, {6,4,'c'}, {-1,-1,0} + }; + + CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH, sizeof(CvGraph), + sizeof(CvGraphVtx), sizeof(CvGraphEdge), storage ); + + for( i = 0; edges[i][0] >= 0; i++ ) + { + vtx_count = MAX( vtx_count, edges[i][0] ); + vtx_count = MAX( vtx_count, edges[i][1] ); + } + vtx_count++; + + for( i = 0; i < vtx_count; i++ ) + cvGraphAddVtx( graph ); + + for( i = 0; edges[i][0] >= 0; i++ ) + { + CvGraphEdge* edge; + cvGraphAddEdge( graph, edges[i][0], edges[i][1], 0, &edge ); + edge->weight = (float)edges[i][2]; + } + + edge_count = i; + scanner = cvCreateGraphScanner( graph, 0, CV_GRAPH_ALL_ITEMS ); + + for(;;) + { + int code, a = -1, b = -1; + const char* event = ""; + code = cvNextGraphItem( scanner ); + + switch( code ) + { + case CV_GRAPH_VERTEX: + event = "Vertex"; + vtx_count--; + a = cvGraphVtxIdx( graph, scanner->vtx ); + break; + case CV_GRAPH_TREE_EDGE: + event = "Tree Edge"; + edge_count--; + CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'t', + "Invalid edge type" ); + a = cvGraphVtxIdx( graph, scanner->vtx ); + b = cvGraphVtxIdx( graph, scanner->dst ); + break; + case CV_GRAPH_BACK_EDGE: + event = "Back Edge"; + edge_count--; + CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'b', + "Invalid edge type" ); + a = cvGraphVtxIdx( graph, scanner->vtx ); + b = cvGraphVtxIdx( graph, scanner->dst ); + break; + case CV_GRAPH_CROSS_EDGE: + event = "Cross Edge"; + edge_count--; + CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'c', + "Invalid edge type" ); + a = cvGraphVtxIdx( graph, scanner->vtx ); + b = cvGraphVtxIdx( graph, scanner->dst ); + break; + case CV_GRAPH_FORWARD_EDGE: + event = "Forward Edge"; + edge_count--; + CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'f', + "Invalid edge type" ); + a = cvGraphVtxIdx( graph, scanner->vtx ); + b = cvGraphVtxIdx( graph, scanner->dst ); + break; + case CV_GRAPH_BACKTRACKING: + event = "Backtracking"; + a = cvGraphVtxIdx( graph, scanner->vtx ); + break; + case CV_GRAPH_NEW_TREE: + event = "New search tree"; + break; + case CV_GRAPH_OVER: + event = "End of procedure"; + break; + default: + CV_TS_SEQ_CHECK_CONDITION( 0, "Invalid code appeared during graph scan" ); + } + + ts->printf( cvtest::TS::LOG, "%s", event ); + if( a >= 0 ) + { + if( b >= 0 ) + ts->printf( cvtest::TS::LOG, ": (%d,%d)", a, b ); + else + ts->printf( cvtest::TS::LOG, ": %d", a ); + } + + ts->printf( cvtest::TS::LOG, "\n" ); + + if( code < 0 ) + break; + } + + CV_TS_SEQ_CHECK_CONDITION( vtx_count == 0 && edge_count == 0, + "Not every vertex/edge has been visited" ); + update_progressbar(); + } + + // for a random graph the test just checks that every graph vertex and + // every edge is vitisted during the scan + for( iter = 0; iter < iterations; iter++ ) + { + create_random_graph(0); + CvGraph* graph = (CvGraph*)cxcore_struct[0]; + + // iterate twice to check that scanner doesn't damage the graph + for( i = 0; i < 2; i++ ) + { + CvGraphVtx* start_vtx = cvtest::randInt(rng) % 2 || graph->active_count == 0 ? 0 : + cvGetGraphVtx( graph, cvtest::randInt(rng) % graph->active_count ); + + scanner = cvCreateGraphScanner( graph, start_vtx, CV_GRAPH_ALL_ITEMS ); + + vtx_mask.resize(0); + vtx_mask.resize(graph->active_count, 0); + edge_mask.resize(0); + edge_mask.resize(graph->edges->active_count, 0); + + for(;;) + { + int code = cvNextGraphItem( scanner ); + + if( code == CV_GRAPH_OVER ) + break; + else if( code & CV_GRAPH_ANY_EDGE ) + { + int edge_idx = scanner->edge->flags & CV_SET_ELEM_IDX_MASK; + + CV_TS_SEQ_CHECK_CONDITION( edge_idx < graph->edges->active_count && + edge_mask[edge_idx] == 0, + "The edge is not found or visited for the second time" ); + edge_mask[edge_idx] = 1; + } + else if( code & CV_GRAPH_VERTEX ) + { + int vtx_idx = scanner->vtx->flags & CV_SET_ELEM_IDX_MASK; + + CV_TS_SEQ_CHECK_CONDITION( vtx_idx < graph->active_count && + vtx_mask[vtx_idx] == 0, + "The vtx is not found or visited for the second time" ); + vtx_mask[vtx_idx] = 1; + } + } + + cvReleaseGraphScanner( &scanner ); + + CV_TS_SEQ_CHECK_CONDITION( cvtest::norm(Mat(vtx_mask),CV_L1) == graph->active_count && + cvtest::norm(Mat(edge_mask),CV_L1) == graph->edges->active_count, + "Some vertices or edges have not been visited" ); + update_progressbar(); + } + cvClearMemStorage( storage ); + } + + storage.release(); + } + } + catch(int) + { + } + + cvReleaseGraphScanner( &scanner ); +} + + +TEST(Core_DS_Seq, basic_operations) { Core_SeqBaseTest test; test.safe_run(); } +TEST(Core_DS_Seq, sort_invert) { Core_SeqSortInvTest test; test.safe_run(); } +TEST(Core_DS_Set, basic_operations) { Core_SetTest test; test.safe_run(); } +TEST(Core_DS_Graph, basic_operations) { Core_GraphTest test; test.safe_run(); } +TEST(Core_DS_Graph, scan) { Core_GraphScanTest test; test.safe_run(); } + + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_dxt.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_dxt.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_dxt.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_dxt.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,870 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +namespace cvtest +{ + +static Mat initDFTWave( int n, bool inv ) +{ + int i; + double angle = (inv ? 1 : -1)*CV_PI*2/n; + Complexd wi, w1; + Mat wave(1, n, CV_64FC2); + Complexd* w = wave.ptr(); + + w1.re = cos(angle); + w1.im = sin(angle); + w[0].re = wi.re = 1.; + w[0].im = wi.im = 0.; + + for( i = 1; i < n; i++ ) + { + double t = wi.re*w1.re - wi.im*w1.im; + wi.im = wi.re*w1.im + wi.im*w1.re; + wi.re = t; + w[i] = wi; + } + + return wave; +} + + +static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat()) +{ + _dst.create(_src.size(), _src.type()); + int i, j, k, n = _dst.cols + _dst.rows - 1; + Mat wave = _wave; + double scale = (flags & DFT_SCALE) ? 1./n : 1.; + size_t esz = _src.elemSize(); + size_t srcstep = esz, dststep = esz; + const uchar* src0 = _src.data; + uchar* dst0 = _dst.data; + + CV_Assert( _src.cols + _src.rows - 1 == n ); + + if( wave.empty() ) + wave = initDFTWave( n, (flags & DFT_INVERSE) != 0 ); + + const Complexd* w = wave.ptr(); + if( !_src.isContinuous() ) + srcstep = _src.step; + if( !_dst.isContinuous() ) + dststep = _dst.step; + + if( _src.type() == CV_32FC2 ) + { + for( i = 0; i < n; i++ ) + { + Complexf* dst = (Complexf*)(dst0 + i*dststep); + Complexd sum(0,0); + int delta = i; + k = 0; + + for( j = 0; j < n; j++ ) + { + const Complexf* src = (const Complexf*)(src0 + j*srcstep); + sum.re += src->re*w[k].re - src->im*w[k].im; + sum.im += src->re*w[k].im + src->im*w[k].re; + k += delta; + k -= (k >= n ? n : 0); + } + + dst->re = (float)(sum.re*scale); + dst->im = (float)(sum.im*scale); + } + } + else if( _src.type() == CV_64FC2 ) + { + for( i = 0; i < n; i++ ) + { + Complexd* dst = (Complexd*)(dst0 + i*dststep); + Complexd sum(0,0); + int delta = i; + k = 0; + + for( j = 0; j < n; j++ ) + { + const Complexd* src = (const Complexd*)(src0 + j*srcstep); + sum.re += src->re*w[k].re - src->im*w[k].im; + sum.im += src->re*w[k].im + src->im*w[k].re; + k += delta; + k -= (k >= n ? n : 0); + } + + dst->re = sum.re*scale; + dst->im = sum.im*scale; + } + } + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +static void DFT_2D( const Mat& src, Mat& dst, int flags ) +{ + const int cn = 2; + int i; + dst.create(src.size(), src.type()); + Mat tmp( src.cols, src.rows, src.type()); + Mat wave = initDFTWave( dst.cols, (flags & DFT_INVERSE) != 0 ); + + // 1. row-wise transform + for( i = 0; i < dst.rows; i++ ) + { + Mat srci = src.row(i).reshape(cn, src.cols), dsti = tmp.col(i); + DFT_1D(srci, dsti, flags, wave ); + } + + if( (flags & DFT_ROWS) == 0 ) + { + if( dst.cols != dst.rows ) + wave = initDFTWave( dst.rows, (flags & DFT_INVERSE) != 0 ); + + // 2. column-wise transform + for( i = 0; i < dst.cols; i++ ) + { + Mat srci = tmp.row(i).reshape(cn, tmp.cols), dsti = dst.col(i); + DFT_1D(srci, dsti, flags, wave ); + } + } + else + cvtest::transpose(tmp, dst); +} + + +static Mat initDCTWave( int n, bool inv ) +{ + int i, k; + double angle = CV_PI*0.5/n; + Mat wave(n, n, CV_64F); + + double scale = sqrt(1./n); + for( k = 0; k < n; k++ ) + wave.at(0, k) = scale; + scale *= sqrt(2.); + for( i = 1; i < n; i++ ) + for( k = 0; k < n; k++ ) + wave.at(i, k) = scale*cos( angle*i*(2*k + 1) ); + + if( inv ) + cv::transpose( wave, wave ); + + return wave; +} + + +static void DCT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat() ) +{ + _dst.create( _src.size(), _src.type() ); + int i, j, n = _dst.cols + _dst.rows - 1; + Mat wave = _wave; + int srcstep = 1, dststep = 1; + double* w; + + CV_Assert( _src.cols + _src.rows - 1 == n); + + if( wave.empty() ) + wave = initDCTWave( n, (flags & DFT_INVERSE) != 0 ); + w = wave.ptr(); + + if( !_src.isContinuous() ) + srcstep = (int)(_src.step/_src.elemSize()); + if( !_dst.isContinuous() ) + dststep = (int)(_dst.step/_dst.elemSize()); + + if( _src.type() == CV_32FC1 ) + { + float *dst = _dst.ptr(); + + for( i = 0; i < n; i++, dst += dststep ) + { + const float* src = _src.ptr(); + double sum = 0; + + for( j = 0; j < n; j++, src += srcstep ) + sum += src[0]*w[j]; + w += n; + dst[0] = (float)sum; + } + } + else if( _src.type() == CV_64FC1 ) + { + double *dst = _dst.ptr(); + + for( i = 0; i < n; i++, dst += dststep ) + { + const double* src = _src.ptr(); + double sum = 0; + + for( j = 0; j < n; j++, src += srcstep ) + sum += src[0]*w[j]; + w += n; + dst[0] = sum; + } + } + else + assert(0); +} + + +static void DCT_2D( const Mat& src, Mat& dst, int flags ) +{ + const int cn = 1; + int i; + dst.create( src.size(), src.type() ); + Mat tmp(dst.cols, dst.rows, dst.type() ); + Mat wave = initDCTWave( dst.cols, (flags & DCT_INVERSE) != 0 ); + + // 1. row-wise transform + for( i = 0; i < dst.rows; i++ ) + { + Mat srci = src.row(i).reshape(cn, src.cols); + Mat dsti = tmp.col(i); + DCT_1D(srci, dsti, flags, wave); + } + + if( (flags & DCT_ROWS) == 0 ) + { + if( dst.cols != dst.rows ) + wave = initDCTWave( dst.rows, (flags & DCT_INVERSE) != 0 ); + + // 2. column-wise transform + for( i = 0; i < dst.cols; i++ ) + { + Mat srci = tmp.row(i).reshape(cn, tmp.cols); + Mat dsti = dst.col(i); + DCT_1D( srci, dsti, flags, wave ); + } + } + else + cvtest::transpose( tmp, dst ); +} + + +static void convertFromCCS( const Mat& _src0, const Mat& _src1, Mat& _dst, int flags ) +{ + if( _dst.rows > 1 && (_dst.cols > 1 || (flags & DFT_ROWS)) ) + { + int i, count = _dst.rows, len = _dst.cols; + bool is2d = (flags & DFT_ROWS) == 0; + Mat src0row, src1row, dstrow; + for( i = 0; i < count; i++ ) + { + int j = !is2d || i == 0 ? i : count - i; + src0row = _src0.row(i); + src1row = _src1.row(j); + dstrow = _dst.row(i); + convertFromCCS( src0row, src1row, dstrow, 0 ); + } + + if( is2d ) + { + src0row = _src0.col(0); + dstrow = _dst.col(0); + convertFromCCS( src0row, src0row, dstrow, 0 ); + if( (len & 1) == 0 ) + { + src0row = _src0.col(_src0.cols - 1); + dstrow = _dst.col(len/2); + convertFromCCS( src0row, src0row, dstrow, 0 ); + } + } + } + else + { + int i, n = _dst.cols + _dst.rows - 1, n2 = (n+1) >> 1; + int cn = _src0.channels(); + int srcstep = cn, dststep = 1; + + if( !_dst.isContinuous() ) + dststep = (int)(_dst.step/_dst.elemSize()); + + if( !_src0.isContinuous() ) + srcstep = (int)(_src0.step/_src0.elemSize1()); + + if( _dst.depth() == CV_32F ) + { + Complexf* dst = _dst.ptr(); + const float* src0 = _src0.ptr(); + const float* src1 = _src1.ptr(); + int delta0, delta1; + + dst->re = src0[0]; + dst->im = 0; + + if( (n & 1) == 0 ) + { + dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep]; + dst[n2*dststep].im = 0; + } + + delta0 = srcstep; + delta1 = delta0 + (cn == 1 ? srcstep : 1); + if( cn == 1 ) + srcstep *= 2; + + for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep ) + { + float t0 = src0[delta0]; + float t1 = src0[delta1]; + + dst[i*dststep].re = t0; + dst[i*dststep].im = t1; + + t0 = src1[delta0]; + t1 = -src1[delta1]; + + dst[(n-i)*dststep].re = t0; + dst[(n-i)*dststep].im = t1; + } + } + else + { + Complexd* dst = _dst.ptr(); + const double* src0 = _src0.ptr(); + const double* src1 = _src1.ptr(); + int delta0, delta1; + + dst->re = src0[0]; + dst->im = 0; + + if( (n & 1) == 0 ) + { + dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep]; + dst[n2*dststep].im = 0; + } + + delta0 = srcstep; + delta1 = delta0 + (cn == 1 ? srcstep : 1); + if( cn == 1 ) + srcstep *= 2; + + for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep ) + { + double t0 = src0[delta0]; + double t1 = src0[delta1]; + + dst[i*dststep].re = t0; + dst[i*dststep].im = t1; + + t0 = src1[delta0]; + t1 = -src1[delta1]; + + dst[(n-i)*dststep].re = t0; + dst[(n-i)*dststep].im = t1; + } + } + } +} + + +static void fixCCS( Mat& mat, int cols, int flags ) +{ + int i, rows = mat.rows; + int rows2 = (flags & DFT_ROWS) ? rows : rows/2 + 1, cols2 = cols/2 + 1; + + CV_Assert( cols2 == mat.cols ); + + if( mat.type() == CV_32FC2 ) + { + for( i = 0; i < rows2; i++ ) + { + Complexf* row = mat.ptr(i); + if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) ) + { + row[0].im = 0; + if( cols % 2 == 0 ) + row[cols2-1].im = 0; + } + else + { + Complexf* row2 = mat.ptr(rows-i); + row2[0].re = row[0].re; + row2[0].im = -row[0].im; + + if( cols % 2 == 0 ) + { + row2[cols2-1].re = row[cols2-1].re; + row2[cols2-1].im = -row[cols2-1].im; + } + } + } + } + else if( mat.type() == CV_64FC2 ) + { + for( i = 0; i < rows2; i++ ) + { + Complexd* row = mat.ptr(i); + if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) ) + { + row[0].im = 0; + if( cols % 2 == 0 ) + row[cols2-1].im = 0; + } + else + { + Complexd* row2 = mat.ptr(rows-i); + row2[0].re = row[0].re; + row2[0].im = -row[0].im; + + if( cols % 2 == 0 ) + { + row2[cols2-1].re = row[cols2-1].re; + row2[cols2-1].im = -row[cols2-1].im; + } + } + } + } +} + +#if defined _MSC_VER && _MSC_VER >= 1700 +#pragma optimize("", off) +#endif +static void mulComplex( const Mat& src1, const Mat& src2, Mat& dst, int flags ) +{ + dst.create(src1.rows, src1.cols, src1.type()); + int i, j, depth = src1.depth(), cols = src1.cols*2; + + CV_Assert( src1.size == src2.size && src1.type() == src2.type() && + (src1.type() == CV_32FC2 || src1.type() == CV_64FC2) ); + + for( i = 0; i < dst.rows; i++ ) + { + if( depth == CV_32F ) + { + const float* a = src1.ptr(i); + const float* b = src2.ptr(i); + float* c = dst.ptr(i); + + if( !(flags & CV_DXT_MUL_CONJ) ) + for( j = 0; j < cols; j += 2 ) + { + double re = (double)a[j]*(double)b[j] - (double)a[j+1]*(double)b[j+1]; + double im = (double)a[j+1]*(double)b[j] + (double)a[j]*(double)b[j+1]; + + c[j] = (float)re; + c[j+1] = (float)im; + } + else + for( j = 0; j < cols; j += 2 ) + { + double re = (double)a[j]*(double)b[j] + (double)a[j+1]*(double)b[j+1]; + double im = (double)a[j+1]*(double)b[j] - (double)a[j]*(double)b[j+1]; + + c[j] = (float)re; + c[j+1] = (float)im; + } + } + else + { + const double* a = src1.ptr(i); + const double* b = src2.ptr(i); + double* c = dst.ptr(i); + + if( !(flags & CV_DXT_MUL_CONJ) ) + for( j = 0; j < cols; j += 2 ) + { + double re = a[j]*b[j] - a[j+1]*b[j+1]; + double im = a[j+1]*b[j] + a[j]*b[j+1]; + + c[j] = re; + c[j+1] = im; + } + else + for( j = 0; j < cols; j += 2 ) + { + double re = a[j]*b[j] + a[j+1]*b[j+1]; + double im = a[j+1]*b[j] - a[j]*b[j+1]; + + c[j] = re; + c[j+1] = im; + } + } + } +} +#if defined _MSC_VER && _MSC_VER >= 1700 +#pragma optimize("", on) +#endif + +} + + +class CxCore_DXTBaseTest : public cvtest::ArrayTest +{ +public: + typedef cvtest::ArrayTest Base; + CxCore_DXTBaseTest( bool _allow_complex=false, bool _allow_odd=false, + bool _spectrum_mode=false ); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + int prepare_test_case( int test_case_idx ); + double get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ); + int flags; // transformation flags + bool allow_complex; // whether input/output may be complex or not: + // true for DFT and MulSpectrums, false for DCT + bool allow_odd; // whether input/output may be have odd (!=1) dimensions: + // true for DFT and MulSpectrums, false for DCT + bool spectrum_mode; // (2 complex/ccs inputs, 1 complex/ccs output): + // true for MulSpectrums, false for DFT and DCT + bool inplace; // inplace operation (set for each individual test case) + bool temp_dst; // use temporary destination (for real->ccs DFT and ccs MulSpectrums) +}; + + +CxCore_DXTBaseTest::CxCore_DXTBaseTest( bool _allow_complex, bool _allow_odd, bool _spectrum_mode ) +: Base(), flags(0), allow_complex(_allow_complex), allow_odd(_allow_odd), +spectrum_mode(_spectrum_mode), inplace(false), temp_dst(false) +{ + test_array[INPUT].push_back(NULL); + if( spectrum_mode ) + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); + + max_log_array_size = 9; + element_wise_relative_error = spectrum_mode; +} + + +void CxCore_DXTBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + int depth = cvtest::randInt(rng)%2 + CV_32F; + int cn = !allow_complex || !(bits & 256) ? 1 : 2; + Size size; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + flags = bits & (CV_DXT_INVERSE | CV_DXT_SCALE | CV_DXT_ROWS | CV_DXT_MUL_CONJ); + if( spectrum_mode ) + flags &= ~CV_DXT_INVERSE; + types[TEMP][0] = types[TEMP][1] = types[INPUT][0] = + types[OUTPUT][0] = CV_MAKETYPE(depth, cn); + size = sizes[INPUT][0]; + + temp_dst = false; + + if( flags & CV_DXT_ROWS && (bits&1024) ) + { + if( bits&16 ) + size.width = 1; + else + size.height = 1; + flags &= ~CV_DXT_ROWS; + } + + const int P2_MIN_SIZE = 32; + if( ((bits >> 10) & 1) == 0 ) + { + size.width = (size.width / P2_MIN_SIZE)*P2_MIN_SIZE; + size.width = MAX(size.width, 1); + size.height = (size.height / P2_MIN_SIZE)*P2_MIN_SIZE; + size.height = MAX(size.height, 1); + } + + if( !allow_odd ) + { + if( size.width > 1 && (size.width&1) != 0 ) + size.width = (size.width + 1) & -2; + + if( size.height > 1 && (size.height&1) != 0 && !(flags & CV_DXT_ROWS) ) + size.height = (size.height + 1) & -2; + } + + sizes[INPUT][0] = sizes[OUTPUT][0] = size; + sizes[TEMP][0] = sizes[TEMP][1] = cvSize(0,0); + + if( spectrum_mode ) + { + if( cn == 1 ) + { + types[OUTPUT][0] = depth + 8; + sizes[TEMP][0] = size; + } + sizes[INPUT][0] = sizes[INPUT][1] = size; + types[INPUT][1] = types[INPUT][0]; + } + else if( /*(cn == 2 && (bits&32)) ||*/ (cn == 1 && allow_complex) ) + { + types[TEMP][0] = depth + 8; // CV_??FC2 + sizes[TEMP][0] = size; + size = cvSize(size.width/2+1, size.height); + + if( flags & CV_DXT_INVERSE ) + { + if( cn == 2 ) + { + types[OUTPUT][0] = depth; + sizes[INPUT][0] = size; + } + types[TEMP][1] = types[TEMP][0]; + sizes[TEMP][1] = sizes[TEMP][0]; + } + else + { + if( allow_complex ) + types[OUTPUT][0] = depth + 8; + + if( cn == 2 ) + { + types[INPUT][0] = depth; + types[TEMP][1] = types[TEMP][0]; + sizes[TEMP][1] = size; + } + else + { + types[TEMP][1] = depth; + sizes[TEMP][1] = sizes[TEMP][0]; + } + temp_dst = true; + } + } + + inplace = false; + if( spectrum_mode || + (!temp_dst && types[INPUT][0] == types[OUTPUT][0]) || + (temp_dst && types[INPUT][0] == types[TEMP][1]) ) + inplace = (bits & 64) != 0; + + types[REF_OUTPUT][0] = types[OUTPUT][0]; + sizes[REF_OUTPUT][0] = sizes[OUTPUT][0]; +} + + +double CxCore_DXTBaseTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + return Base::get_success_error_level( test_case_idx, i, j ); +} + + +int CxCore_DXTBaseTest::prepare_test_case( int test_case_idx ) +{ + int code = Base::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + int in_type = test_mat[INPUT][0].type(); + int out_type = test_mat[OUTPUT][0].type(); + + if( CV_MAT_CN(in_type) == 2 && CV_MAT_CN(out_type) == 1 ) + cvtest::fixCCS( test_mat[INPUT][0], test_mat[OUTPUT][0].cols, flags ); + + if( inplace ) + cvtest::copy( test_mat[INPUT][test_case_idx & (int)spectrum_mode], + temp_dst ? test_mat[TEMP][1] : + in_type == out_type ? test_mat[OUTPUT][0] : + test_mat[TEMP][0] ); + } + + return code; +} + + +////////////////////// FFT //////////////////////// +class CxCore_DFTTest : public CxCore_DXTBaseTest +{ +public: + CxCore_DFTTest(); +protected: + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +CxCore_DFTTest::CxCore_DFTTest() : CxCore_DXTBaseTest( true, true, false ) +{ +} + + +void CxCore_DFTTest::run_func() +{ + Mat& dst = temp_dst ? test_mat[TEMP][1] : test_mat[OUTPUT][0]; + const Mat& src = inplace ? dst : test_mat[INPUT][0]; + + if(!(flags & CV_DXT_INVERSE)) + cv::dft( src, dst, flags ); + else + cv::idft(src, dst, flags & ~CV_DXT_INVERSE); +} + + +void CxCore_DFTTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_OUTPUT][0]; + Mat* tmp_src = &src; + Mat* tmp_dst = &dst; + int src_cn = src.channels(); + int dst_cn = dst.channels(); + + if( src_cn != 2 || dst_cn != 2 ) + { + tmp_src = &test_mat[TEMP][0]; + + if( !(flags & CV_DXT_INVERSE ) ) + { + Mat& cvdft_dst = test_mat[TEMP][1]; + cvtest::convertFromCCS( cvdft_dst, cvdft_dst, + test_mat[OUTPUT][0], flags ); + *tmp_src = Scalar::all(0); + cvtest::insert( src, *tmp_src, 0 ); + } + else + { + cvtest::convertFromCCS( src, src, *tmp_src, flags ); + tmp_dst = &test_mat[TEMP][1]; + } + } + + if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) ) + cvtest::DFT_1D( *tmp_src, *tmp_dst, flags ); + else + cvtest::DFT_2D( *tmp_src, *tmp_dst, flags ); + + if( tmp_dst != &dst ) + cvtest::extract( *tmp_dst, dst, 0 ); +} + +////////////////////// DCT //////////////////////// +class CxCore_DCTTest : public CxCore_DXTBaseTest +{ +public: + CxCore_DCTTest(); +protected: + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +CxCore_DCTTest::CxCore_DCTTest() : CxCore_DXTBaseTest( false, false, false ) +{ +} + + +void CxCore_DCTTest::run_func() +{ + Mat& dst = test_mat[OUTPUT][0]; + const Mat& src = inplace ? dst : test_mat[INPUT][0]; + + if(!(flags & CV_DXT_INVERSE)) + cv::dct( src, dst, flags ); + else + cv::idct( src, dst, flags & ~CV_DXT_INVERSE); +} + + +void CxCore_DCTTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + const Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_OUTPUT][0]; + + if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) ) + cvtest::DCT_1D( src, dst, flags ); + else + cvtest::DCT_2D( src, dst, flags ); +} + + +////////////////////// MulSpectrums //////////////////////// +class CxCore_MulSpectrumsTest : public CxCore_DXTBaseTest +{ +public: + CxCore_MulSpectrumsTest(); +protected: + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +CxCore_MulSpectrumsTest::CxCore_MulSpectrumsTest() : CxCore_DXTBaseTest( true, true, true ) +{ +} + + +void CxCore_MulSpectrumsTest::run_func() +{ + Mat& dst = !test_mat[TEMP].empty() && !test_mat[TEMP][0].empty() ? + test_mat[TEMP][0] : test_mat[OUTPUT][0]; + const Mat* src1 = &test_mat[INPUT][0], *src2 = &test_mat[INPUT][1]; + + if( inplace ) + { + if( ts->get_current_test_info()->test_case_idx & 1 ) + src2 = &dst; + else + src1 = &dst; + } + + cv::mulSpectrums( *src1, *src2, dst, flags, (flags & CV_DXT_MUL_CONJ) != 0 ); +} + + +void CxCore_MulSpectrumsTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat* src1 = &test_mat[INPUT][0]; + Mat* src2 = &test_mat[INPUT][1]; + Mat& dst = test_mat[OUTPUT][0]; + Mat& dst0 = test_mat[REF_OUTPUT][0]; + int cn = src1->channels(); + + if( cn == 1 ) + { + cvtest::convertFromCCS( *src1, *src1, dst, flags ); + cvtest::convertFromCCS( *src2, *src2, dst0, flags ); + src1 = &dst; + src2 = &dst0; + } + + cvtest::mulComplex( *src1, *src2, dst0, flags ); + if( cn == 1 ) + { + Mat& temp = test_mat[TEMP][0]; + cvtest::convertFromCCS( temp, temp, dst, flags ); + } +} + +TEST(Core_DCT, accuracy) { CxCore_DCTTest test; test.safe_run(); } +TEST(Core_DFT, accuracy) { CxCore_DFTTest test; test.safe_run(); } +TEST(Core_MulSpectrums, accuracy) { CxCore_MulSpectrumsTest test; test.safe_run(); } + +class Core_DFTComplexOutputTest : public cvtest::BaseTest +{ +public: + Core_DFTComplexOutputTest() {} + ~Core_DFTComplexOutputTest() {} +protected: + void run(int) + { + RNG& rng = theRNG(); + for( int i = 0; i < 10; i++ ) + { + int m = rng.uniform(2, 11); + int n = rng.uniform(2, 11); + int depth = rng.uniform(0, 2) + CV_32F; + Mat src8u(m, n, depth), src(m, n, depth), dst(m, n, CV_MAKETYPE(depth, 2)); + Mat z = Mat::zeros(m, n, depth), dstz; + randu(src8u, Scalar::all(0), Scalar::all(10)); + src8u.convertTo(src, src.type()); + dst = Scalar::all(123); + Mat mv[] = {src, z}, srcz; + merge(mv, 2, srcz); + dft(srcz, dstz); + dft(src, dst, DFT_COMPLEX_OUTPUT); + if(norm(dst, dstz, NORM_INF) > 1e-3) + { + cout << "actual:\n" << dst << endl << endl; + cout << "reference:\n" << dstz << endl << endl; + CV_Error(CV_StsError, ""); + } + } + } +}; + +TEST(Core_DFT, complex_output) { Core_DFTComplexOutputTest test; test.safe_run(); } + + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_eigen.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_eigen.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_eigen.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_eigen.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,411 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include + +using namespace cv; +using namespace std; + +#define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1 + +#define CORE_EIGEN_ERROR_COUNT 1 +#define CORE_EIGEN_ERROR_SIZE 2 +#define CORE_EIGEN_ERROR_DIFF 3 +#define CORE_EIGEN_ERROR_ORTHO 4 +#define CORE_EIGEN_ERROR_ORDER 5 + +#define MESSAGE_ERROR_COUNT "Matrix of eigen values must have the same rows as source matrix and 1 column." +#define MESSAGE_ERROR_SIZE "Source matrix and matrix of eigen vectors must have the same sizes." +#define MESSAGE_ERROR_DIFF_1 "Accurasy of eigen values computing less than required." +#define MESSAGE_ERROR_DIFF_2 "Accuracy of eigen vectors computing less than required." +#define MESSAGE_ERROR_ORTHO "Matrix of eigen vectors is not orthogonal." +#define MESSAGE_ERROR_ORDER "Eigen values are not sorted in ascending order." + +const int COUNT_NORM_TYPES = 3; +const int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF}; + +enum TASK_TYPE_EIGEN {VALUES, VECTORS}; + +class Core_EigenTest: public cvtest::BaseTest +{ +public: + + Core_EigenTest(); + ~Core_EigenTest(); + +protected: + + bool test_values(const cv::Mat& src); // complex test for eigen without vectors + bool check_full(int type); // compex test for symmetric matrix + virtual void run (int) = 0; // main testing method + +protected: + + float eps_val_32, eps_vec_32; + float eps_val_64, eps_vec_64; + int ntests; + + bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1); + bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1); + bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up) + bool check_orthogonality(const cv::Mat& U); // checking is matrix of eigen vectors orthogonal + bool test_pairs(const cv::Mat& src); // complex test for eigen with vectors + + void print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff); +}; + +class Core_EigenTest_Scalar : public Core_EigenTest +{ +public: + Core_EigenTest_Scalar() : Core_EigenTest() {} + ~Core_EigenTest_Scalar(); + + virtual void run(int) = 0; +}; + +class Core_EigenTest_Scalar_32 : public Core_EigenTest_Scalar +{ +public: + Core_EigenTest_Scalar_32() : Core_EigenTest_Scalar() {} + ~Core_EigenTest_Scalar_32(); + + void run(int); +}; + +class Core_EigenTest_Scalar_64 : public Core_EigenTest_Scalar +{ +public: + Core_EigenTest_Scalar_64() : Core_EigenTest_Scalar() {} + ~Core_EigenTest_Scalar_64(); + void run(int); +}; + +class Core_EigenTest_32 : public Core_EigenTest +{ +public: + Core_EigenTest_32(): Core_EigenTest() {} + ~Core_EigenTest_32() {} + void run(int); +}; + +class Core_EigenTest_64 : public Core_EigenTest +{ +public: + Core_EigenTest_64(): Core_EigenTest() {} + ~Core_EigenTest_64() {} + void run(int); +}; + +Core_EigenTest_Scalar::~Core_EigenTest_Scalar() {} +Core_EigenTest_Scalar_32::~Core_EigenTest_Scalar_32() {} +Core_EigenTest_Scalar_64::~Core_EigenTest_Scalar_64() {} + +void Core_EigenTest_Scalar_32::run(int) +{ + for (int i = 0; i < ntests; ++i) + { + float value = cv::randu(); + cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value)); + test_values(src); + } +} + +void Core_EigenTest_Scalar_64::run(int) +{ + for (int i = 0; i < ntests; ++i) + { + float value = cv::randu(); + cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value)); + test_values(src); + } +} + +void Core_EigenTest_32::run(int) { check_full(CV_32FC1); } +void Core_EigenTest_64::run(int) { check_full(CV_64FC1); } + +Core_EigenTest::Core_EigenTest() +: eps_val_32(1e-3f), eps_vec_32(1e-2f), + eps_val_64(1e-4f), eps_vec_64(1e-3f), ntests(100) {} +Core_EigenTest::~Core_EigenTest() {} + +bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index, int high_index) +{ + int n = src.rows, s = sign(high_index); + if (!( (evalues.rows == n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)))) && (evalues.cols == 1))) + { + std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; + std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return false; + } + return true; +} + +bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index, int high_index) +{ + int n = src.rows, s = sign(high_index); + int right_eigen_pair_count = n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1))); + + if (!((evectors.rows == right_eigen_pair_count) && (evectors.cols == right_eigen_pair_count))) + { + std::cout << endl; std::cout << "Checking sizes of eigen vectors matrix " << evectors << "..." << endl; + std::cout << "Number of rows: " << evectors.rows << " Number of cols: " << evectors.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error (CORE_EIGEN_ERROR_SIZE, MESSAGE_ERROR_SIZE); + return false; + } + + if (!((evalues.rows == right_eigen_pair_count) && (evalues.cols == 1))) + { + std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; + std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error (CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return false; + } + + return true; +} + +void Core_EigenTest::print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff) +{ + switch (NORM_TYPE[norm_idx]) + { + case cv::NORM_L1: {std::cout << "L1"; break;} + case cv::NORM_L2: {std::cout << "L2"; break;} + case cv::NORM_INF: {std::cout << "INF"; break;} + default: break; + } + + cout << "-criteria... " << endl; + cout << "Source size: " << src.rows << " * " << src.cols << endl; + cout << "Difference between original eigen vectors matrix and result: " << diff << endl; + cout << "Maximum allowed difference: " << max_diff << endl; cout << endl; +} + +bool Core_EigenTest::check_orthogonality(const cv::Mat& U) +{ + int type = U.type(); + double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; + cv::Mat UUt; cv::mulTransposed(U, UUt, false); + + cv::Mat E = Mat::eye(U.rows, U.cols, type); + + for (int i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(UUt, E, NORM_TYPE[i]); + if (diff > eps_vec) + { + std::cout << endl; std::cout << "Checking orthogonality of matrix " << U << ": "; + print_information(i, U, diff, eps_vec); + CV_Error(CORE_EIGEN_ERROR_ORTHO, MESSAGE_ERROR_ORTHO); + return false; + } + } + + return true; +} + +bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values) +{ + switch (eigen_values.type()) + { + case CV_32FC1: + { + for (int i = 0; i < (int)(eigen_values.total() - 1); ++i) + if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) + { + std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; + std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl; + std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER); + return false; + } + + break; + } + + case CV_64FC1: + { + for (int i = 0; i < (int)(eigen_values.total() - 1); ++i) + if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) + { + std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; + std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl; + std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in ascending order."); + return false; + } + + break; + } + + default:; + } + + return true; +} + +bool Core_EigenTest::test_pairs(const cv::Mat& src) +{ + int type = src.type(); + double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; + + cv::Mat eigen_values, eigen_vectors; + + cv::eigen(src, true, eigen_values, eigen_vectors); + + if (!check_pair_count(src, eigen_values, eigen_vectors)) return false; + + if (!check_orthogonality (eigen_vectors)) return false; + + if (!check_pairs_order(eigen_values)) return false; + + cv::Mat eigen_vectors_t; cv::transpose(eigen_vectors, eigen_vectors_t); + + cv::Mat src_evec(src.rows, src.cols, type); + src_evec = src*eigen_vectors_t; + + cv::Mat eval_evec(src.rows, src.cols, type); + + switch (type) + { + case CV_32FC1: + { + for (int i = 0; i < src.cols; ++i) + { + cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); + for (int j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); + } + + break; + } + + case CV_64FC1: + { + for (int i = 0; i < src.cols; ++i) + { + cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); + for (int j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); + } + + break; + } + + default:; + } + + cv::Mat disparity = src_evec - eval_evec; + + for (int i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(disparity, NORM_TYPE[i]); + if (diff > eps_vec) + { + std::cout << endl; std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": "; + print_information(i, src, diff, eps_vec); + CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_2); + return false; + } + } + + return true; +} + +bool Core_EigenTest::test_values(const cv::Mat& src) +{ + int type = src.type(); + double eps_val = type == CV_32FC1 ? eps_val_32 : eps_val_64; + + cv::Mat eigen_values_1, eigen_values_2, eigen_vectors; + + if (!test_pairs(src)) return false; + + cv::eigen(src, true, eigen_values_1, eigen_vectors); + cv::eigen(src, false, eigen_values_2, eigen_vectors); + + if (!check_pair_count(src, eigen_values_2)) return false; + + for (int i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(eigen_values_1, eigen_values_2, NORM_TYPE[i]); + if (diff > eps_val) + { + std::cout << endl; std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": "; + print_information(i, src, diff, eps_val); + CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_1); + return false; + } + } + + return true; +} + +bool Core_EigenTest::check_full(int type) +{ + const int MAX_DEGREE = 7; + + srand((unsigned int)time(0)); + + for (int i = 0; i < ntests; ++i) + { + int src_size = (int)(std::pow(2.0, (rand()%MAX_DEGREE)+1.)); + + cv::Mat src(src_size, src_size, type); + + for (int j = 0; j < src.rows; ++j) + for (int k = j; k < src.cols; ++k) + if (type == CV_32FC1) src.at(k, j) = src.at(j, k) = cv::randu(); + else src.at(k, j) = src.at(j, k) = cv::randu(); + + if (!test_values(src)) return false; + } + + return true; +} + +TEST(Core_Eigen, scalar_32) {Core_EigenTest_Scalar_32 test; test.safe_run(); } +TEST(Core_Eigen, scalar_64) {Core_EigenTest_Scalar_64 test; test.safe_run(); } +TEST(Core_Eigen, vector_32) { Core_EigenTest_32 test; test.safe_run(); } +TEST(Core_Eigen, vector_64) { Core_EigenTest_64 test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_io.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_io.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_io.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_io.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,465 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +static SparseMat cvTsGetRandomSparseMat(int dims, const int* sz, int type, + int nzcount, double a, double b, RNG& rng) +{ + SparseMat m(dims, sz, type); + int i, j; + CV_Assert(CV_MAT_CN(type) == 1); + for( i = 0; i < nzcount; i++ ) + { + int idx[CV_MAX_DIM]; + for( j = 0; j < dims; j++ ) + idx[j] = cvtest::randInt(rng) % sz[j]; + double val = cvtest::randReal(rng)*(b - a) + a; + uchar* ptr = m.ptr(idx, true, 0); + if( type == CV_8U ) + *(uchar*)ptr = saturate_cast(val); + else if( type == CV_8S ) + *(schar*)ptr = saturate_cast(val); + else if( type == CV_16U ) + *(ushort*)ptr = saturate_cast(val); + else if( type == CV_16S ) + *(short*)ptr = saturate_cast(val); + else if( type == CV_32S ) + *(int*)ptr = saturate_cast(val); + else if( type == CV_32F ) + *(float*)ptr = saturate_cast(val); + else + *(double*)ptr = saturate_cast(val); + } + + return m; +} + +static bool cvTsCheckSparse(const CvSparseMat* m1, const CvSparseMat* m2, double eps) +{ + CvSparseMatIterator it1; + CvSparseNode* node1; + int depth = CV_MAT_DEPTH(m1->type); + + if( m1->heap->active_count != m2->heap->active_count || + m1->dims != m2->dims || CV_MAT_TYPE(m1->type) != CV_MAT_TYPE(m2->type) ) + return false; + + for( node1 = cvInitSparseMatIterator( m1, &it1 ); + node1 != 0; node1 = cvGetNextSparseNode( &it1 )) + { + uchar* v1 = (uchar*)CV_NODE_VAL(m1,node1); + uchar* v2 = cvPtrND( m2, CV_NODE_IDX(m1,node1), 0, 0, &node1->hashval ); + if( !v2 ) + return false; + if( depth == CV_8U || depth == CV_8S ) + { + if( *v1 != *v2 ) + return false; + } + else if( depth == CV_16U || depth == CV_16S ) + { + if( *(ushort*)v1 != *(ushort*)v2 ) + return false; + } + else if( depth == CV_32S ) + { + if( *(int*)v1 != *(int*)v2 ) + return false; + } + else if( depth == CV_32F ) + { + if( fabs(*(float*)v1 - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) ) + return false; + } + else if( fabs(*(double*)v1 - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) ) + return false; + } + + return true; +} + + +class Core_IOTest : public cvtest::BaseTest +{ +public: + Core_IOTest() {}; +protected: + void run(int) + { + double ranges[][2] = {{0, 256}, {-128, 128}, {0, 65536}, {-32768, 32768}, + {-1000000, 1000000}, {-10, 10}, {-10, 10}}; + RNG& rng = ts->get_rng(); + RNG rng0; + test_case_count = 4; + int progress = 0; + MemStorage storage(cvCreateMemStorage(0)); + + for( int idx = 0; idx < test_case_count; idx++ ) + { + ts->update_context( this, idx, false ); + progress = update_progress( progress, idx, test_case_count, 0 ); + + cvClearMemStorage(storage); + + bool mem = (idx % 4) >= 2; + string filename = tempfile(idx % 2 ? ".yml" : ".xml"); + + FileStorage fs(filename, FileStorage::WRITE + (mem ? FileStorage::MEMORY : 0)); + + int test_int = (int)cvtest::randInt(rng); + double test_real = (cvtest::randInt(rng)%2?1:-1)*exp(cvtest::randReal(rng)*18-9); + string test_string = "vw wv23424rt\"&<>&'@#$@$%$%&%IJUKYILFD@#$@%$&*&() "; + + int depth = cvtest::randInt(rng) % (CV_64F+1); + int cn = cvtest::randInt(rng) % 4 + 1; + Mat test_mat(cvtest::randInt(rng)%30+1, cvtest::randInt(rng)%30+1, CV_MAKETYPE(depth, cn)); + + rng0.fill(test_mat, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); + if( depth >= CV_32F ) + { + exp(test_mat, test_mat); + Mat test_mat_scale(test_mat.size(), test_mat.type()); + rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); + multiply(test_mat, test_mat_scale, test_mat); + } + + CvSeq* seq = cvCreateSeq(test_mat.type(), (int)sizeof(CvSeq), + (int)test_mat.elemSize(), storage); + cvSeqPushMulti(seq, test_mat.data, test_mat.cols*test_mat.rows); + + CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH, + sizeof(CvGraph), sizeof(CvGraphVtx), + sizeof(CvGraphEdge), storage ); + int edges[][2] = {{0,1},{1,2},{2,0},{0,3},{3,4},{4,1}}; + int i, vcount = 5, ecount = 6; + for( i = 0; i < vcount; i++ ) + cvGraphAddVtx(graph); + for( i = 0; i < ecount; i++ ) + { + CvGraphEdge* edge; + cvGraphAddEdge(graph, edges[i][0], edges[i][1], 0, &edge); + edge->weight = (float)(i+1); + } + + depth = cvtest::randInt(rng) % (CV_64F+1); + cn = cvtest::randInt(rng) % 4 + 1; + int sz[] = {cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1}; + MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn)); + + rng0.fill(test_mat_nd, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); + if( depth >= CV_32F ) + { + exp(test_mat_nd, test_mat_nd); + MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type()); + rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); + multiply(test_mat_nd, test_mat_scale, test_mat_nd); + } + + int ssz[] = {cvtest::randInt(rng)%10+1, cvtest::randInt(rng)%10+1, + cvtest::randInt(rng)%10+1,cvtest::randInt(rng)%10+1}; + SparseMat test_sparse_mat = cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1), + cvtest::randInt(rng) % 10000, 0, 100, rng); + + fs << "test_int" << test_int << "test_real" << test_real << "test_string" << test_string; + fs << "test_mat" << test_mat; + fs << "test_mat_nd" << test_mat_nd; + fs << "test_sparse_mat" << test_sparse_mat; + + fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" << + "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]"; + fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:"; + + const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1}; + fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0]))); + + fs << "]" << "}"; + cvWriteComment(*fs, "test comment", 0); + + fs.writeObj("test_seq", seq); + fs.writeObj("test_graph",graph); + CvGraph* graph2 = (CvGraph*)cvClone(graph); + + string content = fs.releaseAndGetString(); + + if(!fs.open(mem ? content : filename, FileStorage::READ + (mem ? FileStorage::MEMORY : 0))) + { + ts->printf( cvtest::TS::LOG, "filename %s can not be read\n", !mem ? filename.c_str() : content.c_str()); + ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); + return; + } + + int real_int = (int)fs["test_int"]; + double real_real = (double)fs["test_real"]; + string real_string = (string)fs["test_string"]; + + if( real_int != test_int || + fabs(real_real - test_real) > DBL_EPSILON*(fabs(test_real)+1) || + real_string != test_string ) + { + ts->printf( cvtest::TS::LOG, "the read scalars are not correct\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + CvMat* m = (CvMat*)fs["test_mat"].readObj(); + CvMat _test_mat = test_mat; + double max_diff = 0; + CvMat stub1, _test_stub1; + cvReshape(m, &stub1, 1, 0); + cvReshape(&_test_mat, &_test_stub1, 1, 0); + vector pt; + + if( !m || !CV_IS_MAT(m) || m->rows != test_mat.rows || m->cols != test_mat.cols || + cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + { + ts->printf( cvtest::TS::LOG, "the read matrix is not correct: (%.20g vs %.20g) at (%d,%d)\n", + cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), + pt[0], pt[1] ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + if( m && CV_IS_MAT(m)) + cvReleaseMat(&m); + + CvMatND* m_nd = (CvMatND*)fs["test_mat_nd"].readObj(); + CvMatND _test_mat_nd = test_mat_nd; + + if( !m_nd || !CV_IS_MATND(m_nd) ) + { + ts->printf( cvtest::TS::LOG, "the read nd-matrix is not correct\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + CvMat stub, _test_stub; + cvGetMat(m_nd, &stub, 0, 1); + cvGetMat(&_test_mat_nd, &_test_stub, 0, 1); + cvReshape(&stub, &stub1, 1, 0); + cvReshape(&_test_stub, &_test_stub1, 1, 0); + + if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || + !CV_ARE_SIZES_EQ(&stub, &_test_stub) || + //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) + cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + { + ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", + cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), + pt[0], pt[1] ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + MatND mat_nd2; + fs["test_mat_nd"] >> mat_nd2; + CvMatND m_nd2 = mat_nd2; + cvGetMat(&m_nd2, &stub, 0, 1); + cvReshape(&stub, &stub1, 1, 0); + + if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || + !CV_ARE_SIZES_EQ(&stub, &_test_stub) || + //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) + cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + { + ts->printf( cvtest::TS::LOG, "C++ method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", + cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[1], pt[0]), + pt[0], pt[1] ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + cvRelease((void**)&m_nd); + + Ptr m_s = (CvSparseMat*)fs["test_sparse_mat"].readObj(); + Ptr _test_sparse_ = (CvSparseMat*)test_sparse_mat; + Ptr _test_sparse = (CvSparseMat*)cvClone(_test_sparse_); + SparseMat m_s2; + fs["test_sparse_mat"] >> m_s2; + Ptr _m_s2 = (CvSparseMat*)m_s2; + + if( !m_s || !CV_IS_SPARSE_MAT(m_s) || + !cvTsCheckSparse(m_s, _test_sparse,0) || + !cvTsCheckSparse(_m_s2, _test_sparse,0)) + { + ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + FileNode tl = fs["test_list"]; + if( tl.type() != FileNode::SEQ || tl.size() != 6 || + fabs((double)tl[0] - 0.0000000000001) >= DBL_EPSILON || + (int)tl[1] != 2 || + fabs((double)tl[2] - CV_PI) >= DBL_EPSILON || + (int)tl[3] != -3435345 || + (string)tl[4] != "2-502 2-029 3egegeg" || + tl[5].type() != FileNode::MAP || tl[5].size() != 3 || + (int)tl[5]["month"] != 12 || + (int)tl[5]["day"] != 31 || + (int)tl[5]["year"] != 1969 ) + { + ts->printf( cvtest::TS::LOG, "the test list is incorrect\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + FileNode tm = fs["test_map"]; + FileNode tm_lbp = tm["lbp"]; + + int real_x = (int)tm["x"]; + int real_y = (int)tm["y"]; + int real_width = (int)tm["width"]; + int real_height = (int)tm["height"]; + + int real_lbp_val = 0; + FileNodeIterator it; + it = tm_lbp.begin(); + real_lbp_val |= (int)*it << 0; + ++it; + real_lbp_val |= (int)*it << 1; + it++; + real_lbp_val |= (int)*it << 2; + it += 1; + real_lbp_val |= (int)*it << 3; + FileNodeIterator it2(it); + it2 += 4; + real_lbp_val |= (int)*it2 << 7; + --it2; + real_lbp_val |= (int)*it2 << 6; + it2--; + real_lbp_val |= (int)*it2 << 5; + it2 -= 1; + real_lbp_val |= (int)*it2 << 4; + it2 += -1; + CV_Assert( it == it2 ); + + if( tm.type() != FileNode::MAP || tm.size() != 5 || + real_x != 1 || + real_y != 2 || + real_width != 100 || + real_height != 200 || + tm_lbp.type() != FileNode::SEQ || + tm_lbp.size() != 8 || + real_lbp_val != 0xb6 ) + { + ts->printf( cvtest::TS::LOG, "the test map is incorrect\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + CvGraph* graph3 = (CvGraph*)fs["test_graph"].readObj(); + if(graph2->active_count != vcount || graph3->active_count != vcount || + graph2->edges->active_count != ecount || graph3->edges->active_count != ecount) + { + ts->printf( cvtest::TS::LOG, "the cloned or read graph have wrong number of vertices or edges\n" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + for( i = 0; i < ecount; i++ ) + { + CvGraphEdge* edge2 = cvFindGraphEdge(graph2, edges[i][0], edges[i][1]); + CvGraphEdge* edge3 = cvFindGraphEdge(graph3, edges[i][0], edges[i][1]); + if( !edge2 || edge2->weight != (float)(i+1) || + !edge3 || edge3->weight != (float)(i+1) ) + { + ts->printf( cvtest::TS::LOG, "the cloned or read graph do not have the edge (%d, %d)\n", edges[i][0], edges[i][1] ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + } + + fs.release(); + if( !mem ) + remove(filename.c_str()); + } + } +}; + +TEST(Core_InputOutput, write_read_consistency) { Core_IOTest test; test.safe_run(); } + + +class CV_MiscIOTest : public cvtest::BaseTest +{ +public: + CV_MiscIOTest() {} + ~CV_MiscIOTest() {} +protected: + void run(int) + { + try + { + string fname = cv::tempfile(".xml"); + FileStorage fs(fname, FileStorage::WRITE); + vector mi, mi2, mi3, mi4; + vector mv, mv2, mv3, mv4; + Mat m(10, 9, CV_32F); + Mat empty; + randu(m, 0, 1); + mi3.push_back(5); + mv3.push_back(m); + fs << "mi" << mi; + fs << "mv" << mv; + fs << "mi3" << mi3; + fs << "mv3" << mv3; + fs << "empty" << empty; + fs.release(); + fs.open(fname, FileStorage::READ); + fs["mi"] >> mi2; + fs["mv"] >> mv2; + fs["mi3"] >> mi4; + fs["mv3"] >> mv4; + fs["empty"] >> empty; + CV_Assert( mi2.empty() ); + CV_Assert( mv2.empty() ); + CV_Assert( norm(mi3, mi4, CV_C) == 0 ); + CV_Assert( mv4.size() == 1 ); + double n = norm(mv3[0], mv4[0], CV_C); + CV_Assert( n == 0 ); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Core_InputOutput, misc) { CV_MiscIOTest test; test.safe_run(); } + +/*class CV_BigMatrixIOTest : public cvtest::BaseTest +{ +public: + CV_BigMatrixIOTest() {} + ~CV_BigMatrixIOTest() {} +protected: + void run(int) + { + try + { + RNG& rng = theRNG(); + int N = 1000, M = 1200000; + Mat mat(M, N, CV_32F); + rng.fill(mat, RNG::UNIFORM, 0, 1); + FileStorage fs(cv::tempfile(".xml"), FileStorage::WRITE); + fs << "mat" << mat; + fs.release(); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Core_InputOutput, huge) { CV_BigMatrixIOTest test; test.safe_run(); } +*/ + +TEST(Core_InputOutput, FileStorage) +{ + std::string file = cv::tempfile(".xml"); + cv::FileStorage f(file, cv::FileStorage::WRITE); + + char arr[66]; + sprintf(arr, "sprintf is hell %d", 666); + EXPECT_NO_THROW(f << arr); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_main.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_main.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("cv") diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_mat.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_mat.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_mat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_mat.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,899 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + + +class Core_ReduceTest : public cvtest::BaseTest +{ +public: + Core_ReduceTest() {}; +protected: + void run( int); + int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim ); + int checkCase( int srcType, int dstType, int dim, Size sz ); + int checkDim( int dim, Size sz ); + int checkSize( Size sz ); +}; + +template +void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim ) +{ + assert( src.channels() == 1 ); + if( dim == 0 ) // row + { + sum.create( 1, src.cols, CV_64FC1 ); + max.create( 1, src.cols, CV_64FC1 ); + min.create( 1, src.cols, CV_64FC1 ); + } + else + { + sum.create( src.rows, 1, CV_64FC1 ); + max.create( src.rows, 1, CV_64FC1 ); + min.create( src.rows, 1, CV_64FC1 ); + } + sum.setTo(Scalar(0)); + max.setTo(Scalar(-DBL_MAX)); + min.setTo(Scalar(DBL_MAX)); + + const Mat_& src_ = src; + Mat_& sum_ = (Mat_&)sum; + Mat_& min_ = (Mat_&)min; + Mat_& max_ = (Mat_&)max; + + if( dim == 0 ) + { + for( int ri = 0; ri < src.rows; ri++ ) + { + for( int ci = 0; ci < src.cols; ci++ ) + { + sum_(0, ci) += src_(ri, ci); + max_(0, ci) = std::max( max_(0, ci), (double)src_(ri, ci) ); + min_(0, ci) = std::min( min_(0, ci), (double)src_(ri, ci) ); + } + } + } + else + { + for( int ci = 0; ci < src.cols; ci++ ) + { + for( int ri = 0; ri < src.rows; ri++ ) + { + sum_(ri, 0) += src_(ri, ci); + max_(ri, 0) = std::max( max_(ri, 0), (double)src_(ri, ci) ); + min_(ri, 0) = std::min( min_(ri, 0), (double)src_(ri, ci) ); + } + } + } + sum.convertTo( avg, CV_64FC1 ); + avg = avg * (1.0 / (dim==0 ? (double)src.rows : (double)src.cols)); +} + +void getMatTypeStr( int type, string& str) +{ + str = type == CV_8UC1 ? "CV_8UC1" : + type == CV_8SC1 ? "CV_8SC1" : + type == CV_16UC1 ? "CV_16UC1" : + type == CV_16SC1 ? "CV_16SC1" : + type == CV_32SC1 ? "CV_32SC1" : + type == CV_32FC1 ? "CV_32FC1" : + type == CV_64FC1 ? "CV_64FC1" : "unsupported matrix type"; +} + +int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim ) +{ + int srcType = src.type(); + bool support = false; + if( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG ) + { + if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) ) + support = true; + if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) ) + support = true; + if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) ) + support = true; + if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) ) + support = true; + if( srcType == CV_64F && dstType == CV_64F) + support = true; + } + else if( opType == CV_REDUCE_MAX ) + { + if( srcType == CV_8U && dstType == CV_8U ) + support = true; + if( srcType == CV_32F && dstType == CV_32F ) + support = true; + if( srcType == CV_64F && dstType == CV_64F ) + support = true; + } + else if( opType == CV_REDUCE_MIN ) + { + if( srcType == CV_8U && dstType == CV_8U) + support = true; + if( srcType == CV_32F && dstType == CV_32F) + support = true; + if( srcType == CV_64F && dstType == CV_64F) + support = true; + } + if( !support ) + return cvtest::TS::OK; + + double eps = 0.0; + if ( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG ) + { + if ( dstType == CV_32F ) + eps = 1.e-5; + else if( dstType == CV_64F ) + eps = 1.e-8; + else if ( dstType == CV_32S ) + eps = 0.6; + } + + assert( opRes.type() == CV_64FC1 ); + Mat _dst, dst, diff; + reduce( src, _dst, dim, opType, dstType ); + _dst.convertTo( dst, CV_64FC1 ); + + absdiff( opRes,dst,diff ); + bool check = false; + if (dstType == CV_32F || dstType == CV_64F) + check = countNonZero(diff>eps*dst) > 0; + else + check = countNonZero(diff>eps) > 0; + if( check ) + { + char msg[100]; + const char* opTypeStr = opType == CV_REDUCE_SUM ? "CV_REDUCE_SUM" : + opType == CV_REDUCE_AVG ? "CV_REDUCE_AVG" : + opType == CV_REDUCE_MAX ? "CV_REDUCE_MAX" : + opType == CV_REDUCE_MIN ? "CV_REDUCE_MIN" : "unknown operation type"; + string srcTypeStr, dstTypeStr; + getMatTypeStr( src.type(), srcTypeStr ); + getMatTypeStr( dstType, dstTypeStr ); + const char* dimStr = dim == 0 ? "ROWS" : "COLS"; + + sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s", + srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr ); + ts->printf( cvtest::TS::LOG, msg ); + return cvtest::TS::FAIL_BAD_ACCURACY; + } + return cvtest::TS::OK; +} + +int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz ) +{ + int code = cvtest::TS::OK, tempCode; + Mat src, sum, avg, max, min; + + src.create( sz, srcType ); + randu( src, Scalar(0), Scalar(100) ); + + if( srcType == CV_8UC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_8SC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_16UC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_16SC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_32SC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_32FC1 ) + testReduce( src, sum, avg, max, min, dim ); + else if( srcType == CV_64FC1 ) + testReduce( src, sum, avg, max, min, dim ); + else + assert( 0 ); + + // 1. sum + tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // 2. avg + tempCode = checkOp( src, dstType, CV_REDUCE_AVG, avg, dim ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // 3. max + tempCode = checkOp( src, dstType, CV_REDUCE_MAX, max, dim ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // 4. min + tempCode = checkOp( src, dstType, CV_REDUCE_MIN, min, dim ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + return code; +} + +int Core_ReduceTest::checkDim( int dim, Size sz ) +{ + int code = cvtest::TS::OK, tempCode; + + // CV_8UC1 + tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // CV_16UC1 + tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // CV_16SC1 + tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // CV_32FC1 + tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + // CV_64FC1 + tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + return code; +} + +int Core_ReduceTest::checkSize( Size sz ) +{ + int code = cvtest::TS::OK, tempCode; + + tempCode = checkDim( 0, sz ); // rows + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkDim( 1, sz ); // cols + code = tempCode != cvtest::TS::OK ? tempCode : code; + + return code; +} + +void Core_ReduceTest::run( int ) +{ + int code = cvtest::TS::OK, tempCode; + + tempCode = checkSize( Size(1,1) ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkSize( Size(1,100) ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkSize( Size(100,1) ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + tempCode = checkSize( Size(1000,500) ); + code = tempCode != cvtest::TS::OK ? tempCode : code; + + ts->set_failed_test_info( code ); +} + + +#define CHECK_C + +class Core_PCATest : public cvtest::BaseTest +{ +public: + Core_PCATest() {} +protected: + void run(int) + { + const Size sz(200, 500); + + double diffPrjEps, diffBackPrjEps, + prjEps, backPrjEps, + evalEps, evecEps; + int maxComponents = 100; + double retainedVariance = 0.95; + Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1); + RNG& rng = ts->get_rng(); + + rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) ); + rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) ); + + PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA; + + // 1. check C++ PCA & ROW + Mat rPrjTestPoints = rPCA.project( rTestPoints ); + Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints ); + + Mat avg(1, sz.width, CV_32FC1 ); + reduce( rPoints, avg, 0, CV_REDUCE_AVG ); + Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), Qt = Q.t(), eval, evec; + Q = Qt * Q; + Q = Q /(float)rPoints.rows; + + eigen( Q, eval, evec ); + /*SVD svd(Q); + evec = svd.vt; + eval = svd.w;*/ + + Mat subEval( maxComponents, 1, eval.type(), eval.data ), + subEvec( maxComponents, evec.cols, evec.type(), evec.data ); + + #ifdef CHECK_C + Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t(); + CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints; + #endif + + // check eigen() + double eigenEps = 1e-6; + double err; + for(int i = 0; i < Q.rows; i++ ) + { + Mat v = evec.row(i).t(); + Mat Qv = Q * v; + + Mat lv = eval.at(i,0) * v; + err = norm( Qv, lv ); + if( err > eigenEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of eigen(); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + } + // check pca eigenvalues + evalEps = 1e-6, evecEps = 1e-3; + err = norm( rPCA.eigenvalues, subEval ); + if( err > evalEps ) + { + ts->printf( cvtest::TS::LOG, "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + // check pca eigenvectors + for(int i = 0; i < subEvec.rows; i++) + { + Mat r0 = rPCA.eigenvectors.row(i); + Mat r1 = subEvec.row(i); + err = norm( r0, r1, CV_L2 ); + if( err > evecEps ) + { + r1 *= -1; + double err2 = norm(r0, r1, CV_L2); + if( err2 > evecEps ) + { + Mat tmp; + absdiff(rPCA.eigenvectors, subEvec, tmp); + double mval = 0; Point mloc; + minMaxLoc(tmp, 0, &mval, 0, &mloc); + + ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->printf( cvtest::TS::LOG, "max diff is %g at (i=%d, j=%d) (%g vs %g)\n", + mval, mloc.y, mloc.x, rPCA.eigenvectors.at(mloc.y, mloc.x), + subEvec.at(mloc.y, mloc.x)); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + } + } + + prjEps = 1.265, backPrjEps = 1.265; + for( int i = 0; i < rTestPoints.rows; i++ ) + { + // check pca project + Mat subEvec_t = subEvec.t(); + Mat prj = rTestPoints.row(i) - avg; prj *= subEvec_t; + err = norm(rPrjTestPoints.row(i), prj, CV_RELATIVE_L2); + if( err > prjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + // check pca backProject + Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg; + err = norm( rBackPrjTestPoints.row(i), backPrj, CV_RELATIVE_L2 ); + if( err > backPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + } + + // 2. check C++ PCA & COL + cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents ); + diffPrjEps = 1, diffBackPrjEps = 1; + Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t()); + err = norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 ); + if( err > diffPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + err = norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), CV_RELATIVE_L2 ); + if( err > diffBackPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + + // 3. check C++ PCA w/retainedVariance + cPCA.computeVar( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, retainedVariance ); + diffPrjEps = 1, diffBackPrjEps = 1; + Mat rvPrjTestPoints = cPCA.project(rTestPoints.t()); + + if( cPCA.eigenvectors.rows > maxComponents) + err = norm(cv::abs(rvPrjTestPoints.rowRange(0,maxComponents)), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 ); + else + err = norm(cv::abs(rvPrjTestPoints), cv::abs(rPrjTestPoints.colRange(0,cPCA.eigenvectors.rows).t()), CV_RELATIVE_L2 ); + + if( err > diffPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); retainedVariance=0.95; err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + err = norm(cPCA.backProject(rvPrjTestPoints), rBackPrjTestPoints.t(), CV_RELATIVE_L2 ); + if( err > diffBackPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); retainedVariance=0.95; err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + + #ifdef CHECK_C + // 4. check C PCA & ROW + _points = rPoints; + _testPoints = rTestPoints; + _avg = avg; + _eval = eval; + _evec = evec; + prjTestPoints.create(rTestPoints.rows, maxComponents, rTestPoints.type() ); + backPrjTestPoints.create(rPoints.size(), rPoints.type() ); + _prjTestPoints = prjTestPoints; + _backPrjTestPoints = backPrjTestPoints; + + cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW ); + cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints ); + cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints ); + + err = norm(prjTestPoints, rPrjTestPoints, CV_RELATIVE_L2); + if( err > diffPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + err = norm(backPrjTestPoints, rBackPrjTestPoints, CV_RELATIVE_L2); + if( err > diffBackPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + + // 5. check C PCA & COL + _points = cPoints; + _testPoints = cTestPoints; + avg = avg.t(); _avg = avg; + eval = eval.t(); _eval = eval; + evec = evec.t(); _evec = evec; + prjTestPoints = prjTestPoints.t(); _prjTestPoints = prjTestPoints; + backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = backPrjTestPoints; + + cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL ); + cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints ); + cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints ); + + err = norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 ); + if( err > diffPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + err = norm(backPrjTestPoints, rBackPrjTestPoints.t(), CV_RELATIVE_L2); + if( err > diffBackPrjEps ) + { + ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + #endif + } +}; + +class Core_ArrayOpTest : public cvtest::BaseTest +{ +public: + Core_ArrayOpTest(); + ~Core_ArrayOpTest(); +protected: + void run(int); +}; + + +Core_ArrayOpTest::Core_ArrayOpTest() +{ +} +Core_ArrayOpTest::~Core_ArrayOpTest() {} + +static string idx2string(const int* idx, int dims) +{ + char buf[256]; + char* ptr = buf; + for( int k = 0; k < dims; k++ ) + { + sprintf(ptr, "%4d ", idx[k]); + ptr += strlen(ptr); + } + ptr[-1] = '\0'; + return string(buf); +} + +static const int* string2idx(const string& s, int* idx, int dims) +{ + const char* ptr = s.c_str(); + for( int k = 0; k < dims; k++ ) + { + int n = 0; + sscanf(ptr, "%d%n", idx + k, &n); + ptr += n; + } + return idx; +} + +static double getValue(SparseMat& M, const int* idx, RNG& rng) +{ + int d = M.dims(); + size_t hv = 0, *phv = 0; + if( (unsigned)rng % 2 ) + { + hv = d == 2 ? M.hash(idx[0], idx[1]) : + d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx); + phv = &hv; + } + + const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) : + d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) : + M.ptr(idx, false, phv); + return !ptr ? 0 : M.type() == CV_32F ? *(float*)ptr : M.type() == CV_64F ? *(double*)ptr : 0; +} + +static double getValue(const CvSparseMat* M, const int* idx) +{ + int type = 0; + const uchar* ptr = cvPtrND(M, idx, &type, 0); + return !ptr ? 0 : type == CV_32F ? *(float*)ptr : type == CV_64F ? *(double*)ptr : 0; +} + +static void eraseValue(SparseMat& M, const int* idx, RNG& rng) +{ + int d = M.dims(); + size_t hv = 0, *phv = 0; + if( (unsigned)rng % 2 ) + { + hv = d == 2 ? M.hash(idx[0], idx[1]) : + d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx); + phv = &hv; + } + + if( d == 2 ) + M.erase(idx[0], idx[1], phv); + else if( d == 3 ) + M.erase(idx[0], idx[1], idx[2], phv); + else + M.erase(idx, phv); +} + +static void eraseValue(CvSparseMat* M, const int* idx) +{ + cvClearND(M, idx); +} + +static void setValue(SparseMat& M, const int* idx, double value, RNG& rng) +{ + int d = M.dims(); + size_t hv = 0, *phv = 0; + if( (unsigned)rng % 2 ) + { + hv = d == 2 ? M.hash(idx[0], idx[1]) : + d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx); + phv = &hv; + } + + uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) : + d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) : + M.ptr(idx, true, phv); + if( M.type() == CV_32F ) + *(float*)ptr = (float)value; + else if( M.type() == CV_64F ) + *(double*)ptr = value; + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + +void Core_ArrayOpTest::run( int /* start_from */) +{ + int errcount = 0; + + // dense matrix operations + { + int sz3[] = {5, 10, 15}; + MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4); + CvMatND matA = A, matB = B; + RNG rng; + rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10)); + rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10)); + + int idx0[] = {3,4,5}, idx1[] = {0, 9, 7}; + float val0 = 130; + Scalar val1(-1000, 30, 3, 8); + cvSetRealND(&matA, idx0, val0); + cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0); + cvSetND(&matB, idx0, val1); + cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1); + Ptr matC = cvCloneMatND(&matB); + + if( A.at(idx0[0], idx0[1], idx0[2]) != val0 || + A.at(idx1[0], idx1[1], idx1[2]) != -val0 || + cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 || + cvGetRealND(&matA, idx1) != -val0 || + + Scalar(B.at(idx0[0], idx0[1], idx0[2])) != val1 || + Scalar(B.at(idx1[0], idx1[1], idx1[2])) != -val1 || + Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 || + Scalar(cvGetND(matC, idx1)) != -val1 ) + { + ts->printf(cvtest::TS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND " + "or the corresponding *Get* functions is not correct\n"); + errcount++; + } + } + + RNG rng; + const int MAX_DIM = 5, MAX_DIM_SZ = 10; + // sparse matrix operations + for( int si = 0; si < 10; si++ ) + { + int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F; + int dims = ((unsigned)rng % MAX_DIM) + 1; + int i, k, size[MAX_DIM]={0}, idx[MAX_DIM]={0}; + vector all_idxs; + vector all_vals; + vector all_vals2; + string sidx, min_sidx, max_sidx; + double min_val=0, max_val=0; + + int p = 1; + for( k = 0; k < dims; k++ ) + { + size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1; + p *= size[k]; + } + SparseMat M( dims, size, depth ); + map M0; + + int nz0 = (unsigned)rng % max(p/5,10); + nz0 = min(max(nz0, 1), p); + all_vals.resize(nz0); + all_vals2.resize(nz0); + Mat_ _all_vals(all_vals), _all_vals2(all_vals2); + rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000)); + if( depth == CV_32F ) + { + Mat _all_vals_f; + _all_vals.convertTo(_all_vals_f, CV_32F); + _all_vals_f.convertTo(_all_vals, CV_64F); + } + _all_vals.convertTo(_all_vals2, _all_vals2.type(), 2); + if( depth == CV_32F ) + { + Mat _all_vals2_f; + _all_vals2.convertTo(_all_vals2_f, CV_32F); + _all_vals2_f.convertTo(_all_vals2, CV_64F); + } + + minMaxLoc(_all_vals, &min_val, &max_val); + double _norm0 = norm(_all_vals, CV_C); + double _norm1 = norm(_all_vals, CV_L1); + double _norm2 = norm(_all_vals, CV_L2); + + for( i = 0; i < nz0; i++ ) + { + for(;;) + { + for( k = 0; k < dims; k++ ) + idx[k] = (unsigned)rng % size[k]; + sidx = idx2string(idx, dims); + if( M0.count(sidx) == 0 ) + break; + } + all_idxs.push_back(sidx); + M0[sidx] = all_vals[i]; + if( all_vals[i] == min_val ) + min_sidx = sidx; + if( all_vals[i] == max_val ) + max_sidx = sidx; + setValue(M, idx, all_vals[i], rng); + double v = getValue(M, idx, rng); + if( v != all_vals[i] ) + { + ts->printf(cvtest::TS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n", + i, sidx.c_str(), all_vals[i], v); + errcount++; + break; + } + } + + Ptr M2 = (CvSparseMat*)M; + MatND Md; + M.copyTo(Md); + SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2); + + int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount(); + double norm0 = norm(M, CV_C); + double norm1 = norm(M, CV_L1); + double norm2 = norm(M, CV_L2); + double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000; + + if( nz1 != nz0 || nz2 != nz0) + { + errcount++; + ts->printf(cvtest::TS::LOG, "%d: The number of non-zero elements before/after converting to/from dense matrix is not correct: %d/%d (while it should be %d)\n", + si, nz1, nz2, nz0 ); + break; + } + + if( fabs(norm0 - _norm0) > fabs(_norm0)*eps || + fabs(norm1 - _norm1) > fabs(_norm1)*eps || + fabs(norm2 - _norm2) > fabs(_norm2)*eps ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n", + si, norm0, norm1, norm2, _norm0, _norm1, _norm2 ); + break; + } + + int n = (unsigned)rng % max(p/5,10); + n = min(max(n, 1), p) + nz0; + + for( i = 0; i < n; i++ ) + { + double val1, val2, val3, val0; + if(i < nz0) + { + sidx = all_idxs[i]; + string2idx(sidx, idx, dims); + val0 = all_vals[i]; + } + else + { + for( k = 0; k < dims; k++ ) + idx[k] = (unsigned)rng % size[k]; + sidx = idx2string(idx, dims); + val0 = M0[sidx]; + } + val1 = getValue(M, idx, rng); + val2 = getValue(M2, idx); + val3 = getValue(M3, idx, rng); + + if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 ); + break; + } + } + + for( i = 0; i < n; i++ ) + { + double val1, val2; + if(i < nz0) + { + sidx = all_idxs[i]; + string2idx(sidx, idx, dims); + } + else + { + for( k = 0; k < dims; k++ ) + idx[k] = (unsigned)rng % size[k]; + sidx = idx2string(idx, dims); + } + eraseValue(M, idx, rng); + eraseValue(M2, idx); + val1 = getValue(M, idx, rng); + val2 = getValue(M2, idx); + if( val1 != 0 || val2 != 0 ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "SparseMat: after deleting M[%s], it is =%g/%g (while it should be 0)\n", sidx.c_str(), val1, val2 ); + break; + } + } + + int nz = (int)M.nzcount(); + if( nz != 0 ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz ); + break; + } + + int idx1[MAX_DIM], idx2[MAX_DIM]; + double val1 = 0, val2 = 0; + M3 = SparseMat(Md); + minMaxLoc(M3, &val1, &val2, idx1, idx2); + string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims); + if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "%d. Sparse: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t" + "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(), + min_val, max_val, min_sidx.c_str(), max_sidx.c_str()); + break; + } + + minMaxIdx(Md, &val1, &val2, idx1, idx2); + s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims); + if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) || + (max_val > 0 && (val2 != max_val || s2 != max_sidx)) ) + { + errcount++; + ts->printf(cvtest::TS::LOG, "%d. Dense: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t" + "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(), + min_val, max_val, min_sidx.c_str(), max_sidx.c_str()); + break; + } + } + + ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT); +} + +TEST(Core_PCA, accuracy) { Core_PCATest test; test.safe_run(); } +TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); } +TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); } + + +TEST(Core_IOArray, submat_assignment) +{ + Mat1f A = Mat1f::zeros(2,2); + Mat1f B = Mat1f::ones(1,3); + + EXPECT_THROW( B.colRange(0,3).copyTo(A.row(0)), cv::Exception ); + + EXPECT_NO_THROW( B.colRange(0,2).copyTo(A.row(0)) ); + + EXPECT_EQ( 1.0f, A(0,0) ); + EXPECT_EQ( 1.0f, A(0,1) ); +} + +void OutputArray_create1(OutputArray m) { m.create(1, 2, CV_32S); } +void OutputArray_create2(OutputArray m) { m.create(1, 3, CV_32F); } + +TEST(Core_IOArray, submat_create) +{ + Mat1f A = Mat1f::zeros(2,2); + + EXPECT_THROW( OutputArray_create1(A.row(0)), cv::Exception ); + EXPECT_THROW( OutputArray_create2(A.row(0)), cv::Exception ); +} + +TEST(Core_Mat, reshape_1942) +{ + cv::Mat A = (cv::Mat_(2,3) << 3.4884074, 1.4159607, 0.78737736, 2.3456569, -0.88010466, 0.3009364); + int cn = 0; + ASSERT_NO_THROW( + cv::Mat_ M = A.reshape(3); + cn = M.channels(); + ); + ASSERT_EQ(1, cn); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_math.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_math.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_math.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_math.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2646 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/////////////////// tests for matrix operations and math functions /////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + +#include "test_precomp.hpp" +#include +#include + +using namespace cv; +using namespace std; + +/// !!! NOTE !!! These tests happily avoid overflow cases & out-of-range arguments +/// so that output arrays contain neigher Inf's nor Nan's. +/// Handling such cases would require special modification of check function +/// (validate_test_results) => TBD. +/// Also, need some logarithmic-scale generation of input data. Right now it is done (in some tests) +/// by generating min/max boundaries for random data in logarimithic scale, but +/// within the same test case all the input array elements are of the same order. + +class Core_MathTest : public cvtest::ArrayTest +{ +public: + typedef cvtest::ArrayTest Base; + Core_MathTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, + vector >& types); + double get_success_error_level( int /*test_case_idx*/, int i, int j ); + bool test_nd; +}; + + +Core_MathTest::Core_MathTest() +{ + optional_mask = false; + + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + + test_nd = false; +} + + +double Core_MathTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + return test_mat[i][j].depth() == CV_32F ? FLT_EPSILON*128 : DBL_EPSILON*1024; +} + + +void Core_MathTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng)%2 + CV_32F; + int cn = cvtest::randInt(rng) % 4 + 1, type = CV_MAKETYPE(depth, cn); + size_t i, j; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + for( i = 0; i < test_array.size(); i++ ) + { + size_t count = test_array[i].size(); + for( j = 0; j < count; j++ ) + types[i][j] = type; + } + test_nd = cvtest::randInt(rng)%3 == 0; +} + + +////////// pow ///////////// + +class Core_PowTest : public Core_MathTest +{ +public: + typedef Core_MathTest Base; + Core_PowTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + double get_success_error_level( int test_case_idx, int i, int j ); + double power; +}; + + +Core_PowTest::Core_PowTest() +{ + power = 0; +} + + +void Core_PowTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % (CV_64F+1); + int cn = cvtest::randInt(rng) % 4 + 1; + size_t i, j; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + depth += depth == CV_8S; + + if( depth < CV_32F || cvtest::randInt(rng)%8 == 0 ) + // integer power + power = (int)(cvtest::randInt(rng)%21 - 10); + else + { + i = cvtest::randInt(rng)%17; + power = i == 16 ? 1./3 : i == 15 ? 0.5 : i == 14 ? -0.5 : cvtest::randReal(rng)*10 - 5; + } + + for( i = 0; i < test_array.size(); i++ ) + { + size_t count = test_array[i].size(); + int type = CV_MAKETYPE(depth, cn); + for( j = 0; j < count; j++ ) + types[i][j] = type; + } + test_nd = cvtest::randInt(rng)%3 == 0; +} + + +double Core_PowTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + if( depth < CV_32F ) + return power == cvRound(power) && power >= 0 ? 0 : 1; + else + return Base::get_success_error_level( test_case_idx, i, j ); +} + + +void Core_PowTest::get_minmax_bounds( int /*i*/, int /*j*/, int type, Scalar& low, Scalar& high ) +{ + double l, u = cvtest::randInt(ts->get_rng())%1000 + 1; + if( power > 0 ) + { + double mval = cvtest::getMaxVal(type); + double u1 = pow(mval,1./power)*2; + u = MIN(u,u1); + } + + l = power == cvRound(power) ? -u : FLT_EPSILON; + low = Scalar::all(l); + high = Scalar::all(u); +} + + +void Core_PowTest::run_func() +{ + if(!test_nd) + { + if( fabs(power-1./3) <= DBL_EPSILON && test_mat[INPUT][0].depth() == CV_32F ) + { + Mat a = test_mat[INPUT][0], b = test_mat[OUTPUT][0]; + + a = a.reshape(1); + b = b.reshape(1); + for( int i = 0; i < a.rows; i++ ) + { + b.at(i,0) = (float)fabs(cvCbrt(a.at(i,0))); + for( int j = 1; j < a.cols; j++ ) + b.at(i,j) = (float)fabs(cv::cubeRoot(a.at(i,j))); + } + } + else + cvPow( test_array[INPUT][0], test_array[OUTPUT][0], power ); + } + else + { + Mat& a = test_mat[INPUT][0]; + Mat& b = test_mat[OUTPUT][0]; + if(power == 0.5) + cv::sqrt(a, b); + else + cv::pow(a, power, b); + } +} + + +inline static int ipow( int a, int power ) +{ + int b = 1; + while( power > 0 ) + { + if( power&1 ) + b *= a, power--; + else + a *= a, power >>= 1; + } + return b; +} + + +inline static double ipow( double a, int power ) +{ + double b = 1.; + while( power > 0 ) + { + if( power&1 ) + b *= a, power--; + else + a *= a, power >>= 1; + } + return b; +} + + +void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + const Mat& a = test_mat[INPUT][0]; + Mat& b = test_mat[REF_OUTPUT][0]; + + int depth = a.depth(); + int ncols = a.cols*a.channels(); + int ipower = cvRound(power), apower = abs(ipower); + int i, j; + + for( i = 0; i < a.rows; i++ ) + { + const uchar* a_data = a.ptr(i); + uchar* b_data = b.ptr(i); + + switch( depth ) + { + case CV_8U: + if( ipower < 0 ) + for( j = 0; j < ncols; j++ ) + { + int val = ((uchar*)a_data)[j]; + ((uchar*)b_data)[j] = (uchar)(val <= 1 ? val : + val == 2 && ipower == -1 ? 1 : 0); + } + else + for( j = 0; j < ncols; j++ ) + { + int val = ((uchar*)a_data)[j]; + val = ipow( val, ipower ); + ((uchar*)b_data)[j] = saturate_cast(val); + } + break; + case CV_8S: + if( ipower < 0 ) + for( j = 0; j < ncols; j++ ) + { + int val = ((char*)a_data)[j]; + ((char*)b_data)[j] = (char)((val&~1)==0 ? val : + val ==-1 ? 1-2*(ipower&1) : + val == 2 && ipower == -1 ? 1 : 0); + } + else + for( j = 0; j < ncols; j++ ) + { + int val = ((char*)a_data)[j]; + val = ipow( val, ipower ); + ((char*)b_data)[j] = saturate_cast(val); + } + break; + case CV_16U: + if( ipower < 0 ) + for( j = 0; j < ncols; j++ ) + { + int val = ((ushort*)a_data)[j]; + ((ushort*)b_data)[j] = (ushort)((val&~1)==0 ? val : + val ==-1 ? 1-2*(ipower&1) : + val == 2 && ipower == -1 ? 1 : 0); + } + else + for( j = 0; j < ncols; j++ ) + { + int val = ((ushort*)a_data)[j]; + val = ipow( val, ipower ); + ((ushort*)b_data)[j] = saturate_cast(val); + } + break; + case CV_16S: + if( ipower < 0 ) + for( j = 0; j < ncols; j++ ) + { + int val = ((short*)a_data)[j]; + ((short*)b_data)[j] = (short)((val&~1)==0 ? val : + val ==-1 ? 1-2*(ipower&1) : + val == 2 && ipower == -1 ? 1 : 0); + } + else + for( j = 0; j < ncols; j++ ) + { + int val = ((short*)a_data)[j]; + val = ipow( val, ipower ); + ((short*)b_data)[j] = saturate_cast(val); + } + break; + case CV_32S: + if( ipower < 0 ) + for( j = 0; j < ncols; j++ ) + { + int val = ((int*)a_data)[j]; + ((int*)b_data)[j] = (val&~1)==0 ? val : + val ==-1 ? 1-2*(ipower&1) : + val == 2 && ipower == -1 ? 1 : 0; + } + else + for( j = 0; j < ncols; j++ ) + { + int val = ((int*)a_data)[j]; + val = ipow( val, ipower ); + ((int*)b_data)[j] = val; + } + break; + case CV_32F: + if( power != ipower ) + for( j = 0; j < ncols; j++ ) + { + double val = ((float*)a_data)[j]; + val = pow( fabs(val), power ); + ((float*)b_data)[j] = (float)val; + } + else + for( j = 0; j < ncols; j++ ) + { + double val = ((float*)a_data)[j]; + if( ipower < 0 ) + val = 1./val; + val = ipow( val, apower ); + ((float*)b_data)[j] = (float)val; + } + break; + case CV_64F: + if( power != ipower ) + for( j = 0; j < ncols; j++ ) + { + double val = ((double*)a_data)[j]; + val = pow( fabs(val), power ); + ((double*)b_data)[j] = (double)val; + } + else + for( j = 0; j < ncols; j++ ) + { + double val = ((double*)a_data)[j]; + if( ipower < 0 ) + val = 1./val; + val = ipow( val, apower ); + ((double*)b_data)[j] = (double)val; + } + break; + } + } +} + + + +///////////////////////////////////////// matrix tests //////////////////////////////////////////// + +class Core_MatrixTest : public cvtest::ArrayTest +{ +public: + typedef cvtest::ArrayTest Base; + Core_MatrixTest( int in_count, int out_count, + bool allow_int, bool scalar_output, int max_cn ); +protected: + void get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + bool allow_int; + bool scalar_output; + int max_cn; +}; + + +Core_MatrixTest::Core_MatrixTest( int in_count, int out_count, + bool _allow_int, bool _scalar_output, int _max_cn ) +: allow_int(_allow_int), scalar_output(_scalar_output), max_cn(_max_cn) +{ + int i; + for( i = 0; i < in_count; i++ ) + test_array[INPUT].push_back(NULL); + + for( i = 0; i < out_count; i++ ) + { + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + } + + element_wise_relative_error = false; +} + + +void Core_MatrixTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % (allow_int ? CV_64F+1 : 2); + int cn = cvtest::randInt(rng) % max_cn + 1; + size_t i, j; + + if( allow_int ) + depth += depth == CV_8S; + else + depth += CV_32F; + + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + for( i = 0; i < test_array.size(); i++ ) + { + size_t count = test_array[i].size(); + int flag = (i == OUTPUT || i == REF_OUTPUT) && scalar_output; + int type = !flag ? CV_MAKETYPE(depth, cn) : CV_64FC1; + + for( j = 0; j < count; j++ ) + { + types[i][j] = type; + if( flag ) + sizes[i][j] = Size( 4, 1 ); + } + } +} + + +double Core_MatrixTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + int input_depth = test_mat[INPUT][0].depth(); + double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 5e-5 : 5e-10; + double output_precision = Base::get_success_error_level( test_case_idx, i, j ); + return MAX(input_precision, output_precision); +} + + +///////////////// Trace ///////////////////// + +class Core_TraceTest : public Core_MatrixTest +{ +public: + Core_TraceTest(); +protected: + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_TraceTest::Core_TraceTest() : Core_MatrixTest( 1, 1, true, true, 4 ) +{ +} + + +void Core_TraceTest::run_func() +{ + test_mat[OUTPUT][0].at(0,0) = cvTrace(test_array[INPUT][0]); +} + + +void Core_TraceTest::prepare_to_validation( int ) +{ + Mat& mat = test_mat[INPUT][0]; + int count = MIN( mat.rows, mat.cols ); + Mat diag(count, 1, mat.type(), mat.data, mat.step + mat.elemSize()); + Scalar r = cvtest::mean(diag); + r *= (double)count; + + test_mat[REF_OUTPUT][0].at(0,0) = r; +} + + +///////// dotproduct ////////// + +class Core_DotProductTest : public Core_MatrixTest +{ +public: + Core_DotProductTest(); +protected: + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_DotProductTest::Core_DotProductTest() : Core_MatrixTest( 2, 1, true, true, 4 ) +{ +} + + +void Core_DotProductTest::run_func() +{ + test_mat[OUTPUT][0].at(0,0) = Scalar(cvDotProduct( test_array[INPUT][0], test_array[INPUT][1] )); +} + + +void Core_DotProductTest::prepare_to_validation( int ) +{ + test_mat[REF_OUTPUT][0].at(0,0) = Scalar(cvtest::crossCorr( test_mat[INPUT][0], test_mat[INPUT][1] )); +} + + +///////// crossproduct ////////// + +class Core_CrossProductTest : public Core_MatrixTest +{ +public: + Core_CrossProductTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ); + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_CrossProductTest::Core_CrossProductTest() : Core_MatrixTest( 2, 1, false, false, 1 ) +{ +} + + +void Core_CrossProductTest::get_test_array_types_and_sizes( int, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % 2 + CV_32F; + int cn = cvtest::randInt(rng) & 1 ? 3 : 1, type = CV_MAKETYPE(depth, cn); + CvSize sz; + + types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = type; + + if( cn == 3 ) + sz = Size(1,1); + else if( cvtest::randInt(rng) & 1 ) + sz = Size(3,1); + else + sz = Size(1,3); + + sizes[INPUT][0] = sizes[INPUT][1] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sz; +} + + +void Core_CrossProductTest::run_func() +{ + cvCrossProduct( test_array[INPUT][0], test_array[INPUT][1], test_array[OUTPUT][0] ); +} + + +void Core_CrossProductTest::prepare_to_validation( int ) +{ + CvScalar a = {{0,0,0,0}}, b = {{0,0,0,0}}, c = {{0,0,0,0}}; + + if( test_mat[INPUT][0].rows > 1 ) + { + a.val[0] = cvGetReal2D( test_array[INPUT][0], 0, 0 ); + a.val[1] = cvGetReal2D( test_array[INPUT][0], 1, 0 ); + a.val[2] = cvGetReal2D( test_array[INPUT][0], 2, 0 ); + + b.val[0] = cvGetReal2D( test_array[INPUT][1], 0, 0 ); + b.val[1] = cvGetReal2D( test_array[INPUT][1], 1, 0 ); + b.val[2] = cvGetReal2D( test_array[INPUT][1], 2, 0 ); + } + else if( test_mat[INPUT][0].cols > 1 ) + { + a.val[0] = cvGetReal1D( test_array[INPUT][0], 0 ); + a.val[1] = cvGetReal1D( test_array[INPUT][0], 1 ); + a.val[2] = cvGetReal1D( test_array[INPUT][0], 2 ); + + b.val[0] = cvGetReal1D( test_array[INPUT][1], 0 ); + b.val[1] = cvGetReal1D( test_array[INPUT][1], 1 ); + b.val[2] = cvGetReal1D( test_array[INPUT][1], 2 ); + } + else + { + a = cvGet1D( test_array[INPUT][0], 0 ); + b = cvGet1D( test_array[INPUT][1], 0 ); + } + + c.val[2] = a.val[0]*b.val[1] - a.val[1]*b.val[0]; + c.val[1] = -a.val[0]*b.val[2] + a.val[2]*b.val[0]; + c.val[0] = a.val[1]*b.val[2] - a.val[2]*b.val[1]; + + if( test_mat[REF_OUTPUT][0].rows > 1 ) + { + cvSetReal2D( test_array[REF_OUTPUT][0], 0, 0, c.val[0] ); + cvSetReal2D( test_array[REF_OUTPUT][0], 1, 0, c.val[1] ); + cvSetReal2D( test_array[REF_OUTPUT][0], 2, 0, c.val[2] ); + } + else if( test_mat[REF_OUTPUT][0].cols > 1 ) + { + cvSetReal1D( test_array[REF_OUTPUT][0], 0, c.val[0] ); + cvSetReal1D( test_array[REF_OUTPUT][0], 1, c.val[1] ); + cvSetReal1D( test_array[REF_OUTPUT][0], 2, c.val[2] ); + } + else + { + cvSet1D( test_array[REF_OUTPUT][0], 0, c ); + } +} + + +///////////////// gemm ///////////////////// + +class Core_GEMMTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_GEMMTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int tabc_flag; + double alpha, beta; +}; + +Core_GEMMTest::Core_GEMMTest() : Core_MatrixTest( 5, 1, false, false, 2 ) +{ + test_case_count = 100; + max_log_array_size = 10; + alpha = beta = 0; +} + + +void Core_GEMMTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + Size sizeA; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + sizeA = sizes[INPUT][0]; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + sizes[INPUT][0] = sizeA; + sizes[INPUT][2] = sizes[INPUT][3] = Size(1,1); + types[INPUT][2] = types[INPUT][3] &= ~CV_MAT_CN_MASK; + + tabc_flag = cvtest::randInt(rng) & 7; + + switch( tabc_flag & (CV_GEMM_A_T|CV_GEMM_B_T) ) + { + case 0: + sizes[INPUT][1].height = sizes[INPUT][0].width; + sizes[OUTPUT][0].height = sizes[INPUT][0].height; + sizes[OUTPUT][0].width = sizes[INPUT][1].width; + break; + case CV_GEMM_B_T: + sizes[INPUT][1].width = sizes[INPUT][0].width; + sizes[OUTPUT][0].height = sizes[INPUT][0].height; + sizes[OUTPUT][0].width = sizes[INPUT][1].height; + break; + case CV_GEMM_A_T: + sizes[INPUT][1].height = sizes[INPUT][0].height; + sizes[OUTPUT][0].height = sizes[INPUT][0].width; + sizes[OUTPUT][0].width = sizes[INPUT][1].width; + break; + case CV_GEMM_A_T | CV_GEMM_B_T: + sizes[INPUT][1].width = sizes[INPUT][0].height; + sizes[OUTPUT][0].height = sizes[INPUT][0].width; + sizes[OUTPUT][0].width = sizes[INPUT][1].height; + break; + } + + sizes[REF_OUTPUT][0] = sizes[OUTPUT][0]; + + if( cvtest::randInt(rng) & 1 ) + sizes[INPUT][4] = Size(0,0); + else if( !(tabc_flag & CV_GEMM_C_T) ) + sizes[INPUT][4] = sizes[OUTPUT][0]; + else + { + sizes[INPUT][4].width = sizes[OUTPUT][0].height; + sizes[INPUT][4].height = sizes[OUTPUT][0].width; + } +} + + +int Core_GEMMTest::prepare_test_case( int test_case_idx ) +{ + int code = Base::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + alpha = cvGetReal2D( test_array[INPUT][2], 0, 0 ); + beta = cvGetReal2D( test_array[INPUT][3], 0, 0 ); + } + return code; +} + + +void Core_GEMMTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = Scalar::all(-10.); + high = Scalar::all(10.); +} + + +void Core_GEMMTest::run_func() +{ + cvGEMM( test_array[INPUT][0], test_array[INPUT][1], alpha, + test_array[INPUT][4], beta, test_array[OUTPUT][0], tabc_flag ); +} + + +void Core_GEMMTest::prepare_to_validation( int ) +{ + cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][1], alpha, + test_array[INPUT][4] ? test_mat[INPUT][4] : Mat(), + beta, test_mat[REF_OUTPUT][0], tabc_flag ); +} + + +///////////////// multransposed ///////////////////// + +class Core_MulTransposedTest : public Core_MatrixTest +{ +public: + Core_MulTransposedTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int order; +}; + + +Core_MulTransposedTest::Core_MulTransposedTest() : Core_MatrixTest( 2, 1, false, false, 1 ) +{ + test_case_count = 100; + order = 0; + test_array[TEMP].push_back(NULL); +} + + +void Core_MulTransposedTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + int src_type = cvtest::randInt(rng) % 5; + int dst_type = cvtest::randInt(rng) % 2; + + src_type = src_type == 0 ? CV_8U : src_type == 1 ? CV_16U : src_type == 2 ? CV_16S : + src_type == 3 ? CV_32F : CV_64F; + dst_type = dst_type == 0 ? CV_32F : CV_64F; + dst_type = MAX( dst_type, src_type ); + + Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( bits & 1 ) + sizes[INPUT][1] = Size(0,0); + else + { + sizes[INPUT][1] = sizes[INPUT][0]; + if( bits & 2 ) + sizes[INPUT][1].height = 1; + if( bits & 4 ) + sizes[INPUT][1].width = 1; + } + + sizes[TEMP][0] = sizes[INPUT][0]; + types[INPUT][0] = src_type; + types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][1] = types[TEMP][0] = dst_type; + + order = (bits & 8) != 0; + sizes[OUTPUT][0].width = sizes[OUTPUT][0].height = order == 0 ? + sizes[INPUT][0].height : sizes[INPUT][0].width; + sizes[REF_OUTPUT][0] = sizes[OUTPUT][0]; +} + + +void Core_MulTransposedTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-10.); + high = cvScalarAll(10.); +} + + +void Core_MulTransposedTest::run_func() +{ + cvMulTransposed( test_array[INPUT][0], test_array[OUTPUT][0], + order, test_array[INPUT][1] ); +} + + +void Core_MulTransposedTest::prepare_to_validation( int ) +{ + const Mat& src = test_mat[INPUT][0]; + Mat delta = test_mat[INPUT][1]; + Mat& temp = test_mat[TEMP][0]; + if( !delta.empty() ) + { + if( delta.rows < src.rows || delta.cols < src.cols ) + { + cv::repeat( delta, src.rows/delta.rows, src.cols/delta.cols, temp); + delta = temp; + } + cvtest::add( src, 1, delta, -1, Scalar::all(0), temp, temp.type()); + } + else + src.convertTo(temp, temp.type()); + + cvtest::gemm( temp, temp, 1., Mat(), 0, test_mat[REF_OUTPUT][0], order == 0 ? GEMM_2_T : GEMM_1_T ); +} + + +///////////////// Transform ///////////////////// + +class Core_TransformTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_TransformTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + + double scale; + bool diagMtx; +}; + + +Core_TransformTest::Core_TransformTest() : Core_MatrixTest( 3, 1, true, false, 4 ) +{ +} + + +void Core_TransformTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + int depth, dst_cn, mat_cols, mattype; + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + mat_cols = CV_MAT_CN(types[INPUT][0]); + depth = CV_MAT_DEPTH(types[INPUT][0]); + dst_cn = cvtest::randInt(rng) % 4 + 1; + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, dst_cn); + + mattype = depth < CV_32S ? CV_32F : depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F; + types[INPUT][1] = mattype; + types[INPUT][2] = CV_MAKETYPE(mattype, dst_cn); + + scale = 1./((cvtest::randInt(rng)%4)*50+1); + + if( bits & 2 ) + { + sizes[INPUT][2] = Size(0,0); + mat_cols += (bits & 4) != 0; + } + else if( bits & 4 ) + sizes[INPUT][2] = Size(1,1); + else + { + if( bits & 8 ) + sizes[INPUT][2] = Size(dst_cn,1); + else + sizes[INPUT][2] = Size(1,dst_cn); + types[INPUT][2] &= ~CV_MAT_CN_MASK; + } + diagMtx = (bits & 16) != 0; + + sizes[INPUT][1] = Size(mat_cols,dst_cn); +} + + +int Core_TransformTest::prepare_test_case( int test_case_idx ) +{ + int code = Base::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + Mat& m = test_mat[INPUT][1]; + cvtest::add(m, scale, m, 0, Scalar::all(0), m, m.type() ); + if(diagMtx) + { + Mat mask = Mat::eye(m.rows, m.cols, CV_8U)*255; + mask = ~mask; + m.setTo(Scalar::all(0), mask); + } + } + return code; +} + + +double Core_TransformTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 1 : depth <= CV_32S ? 9 : Base::get_success_error_level( test_case_idx, i, j ); +} + +void Core_TransformTest::run_func() +{ + CvMat _m = test_mat[INPUT][1], _shift = test_mat[INPUT][2]; + cvTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m, _shift.data.ptr ? &_shift : 0); +} + + +void Core_TransformTest::prepare_to_validation( int ) +{ + Mat transmat = test_mat[INPUT][1]; + Mat shift = test_mat[INPUT][2]; + + cvtest::transform( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], transmat, shift ); +} + + +///////////////// PerspectiveTransform ///////////////////// + +class Core_PerspectiveTransformTest : public Core_MatrixTest +{ +public: + Core_PerspectiveTransformTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_PerspectiveTransformTest::Core_PerspectiveTransformTest() : Core_MatrixTest( 2, 1, false, false, 2 ) +{ +} + + +void Core_PerspectiveTransformTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + int depth, cn, mattype; + Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + cn = CV_MAT_CN(types[INPUT][0]) + 1; + depth = CV_MAT_DEPTH(types[INPUT][0]); + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn); + + mattype = depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F; + types[INPUT][1] = mattype; + sizes[INPUT][1] = Size(cn + 1, cn + 1); +} + + +double Core_PerspectiveTransformTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_32F ? 1e-4 : depth == CV_64F ? 1e-8 : + Core_MatrixTest::get_success_error_level(test_case_idx, i, j); +} + + +void Core_PerspectiveTransformTest::run_func() +{ + CvMat _m = test_mat[INPUT][1]; + cvPerspectiveTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m ); +} + + +static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMat* transmat ) +{ + int i, j, cols; + int cn, depth, mat_depth; + CvMat astub, bstub, *a, *b; + double mat[16]; + + a = cvGetMat( _src, &astub, 0, 0 ); + b = cvGetMat( _dst, &bstub, 0, 0 ); + + cn = CV_MAT_CN(a->type); + depth = CV_MAT_DEPTH(a->type); + mat_depth = CV_MAT_DEPTH(transmat->type); + cols = transmat->cols; + + // prepare cn x (cn + 1) transform matrix + if( mat_depth == CV_32F ) + { + for( i = 0; i < transmat->rows; i++ ) + for( j = 0; j < cols; j++ ) + mat[i*cols + j] = ((float*)(transmat->data.ptr + transmat->step*i))[j]; + } + else + { + assert( mat_depth == CV_64F ); + for( i = 0; i < transmat->rows; i++ ) + for( j = 0; j < cols; j++ ) + mat[i*cols + j] = ((double*)(transmat->data.ptr + transmat->step*i))[j]; + } + + // transform data + cols = a->cols * cn; + vector buf(cols); + + for( i = 0; i < a->rows; i++ ) + { + uchar* src = a->data.ptr + i*a->step; + uchar* dst = b->data.ptr + i*b->step; + + switch( depth ) + { + case CV_32F: + for( j = 0; j < cols; j++ ) + buf[j] = ((float*)src)[j]; + break; + case CV_64F: + for( j = 0; j < cols; j++ ) + buf[j] = ((double*)src)[j]; + break; + default: + assert(0); + } + + switch( cn ) + { + case 2: + for( j = 0; j < cols; j += 2 ) + { + double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + mat[2]; + double t1 = buf[j]*mat[3] + buf[j+1]*mat[4] + mat[5]; + double w = buf[j]*mat[6] + buf[j+1]*mat[7] + mat[8]; + w = w ? 1./w : 0; + buf[j] = t0*w; + buf[j+1] = t1*w; + } + break; + case 3: + for( j = 0; j < cols; j += 3 ) + { + double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + buf[j+2]*mat[2] + mat[3]; + double t1 = buf[j]*mat[4] + buf[j+1]*mat[5] + buf[j+2]*mat[6] + mat[7]; + double t2 = buf[j]*mat[8] + buf[j+1]*mat[9] + buf[j+2]*mat[10] + mat[11]; + double w = buf[j]*mat[12] + buf[j+1]*mat[13] + buf[j+2]*mat[14] + mat[15]; + w = w ? 1./w : 0; + buf[j] = t0*w; + buf[j+1] = t1*w; + buf[j+2] = t2*w; + } + break; + default: + assert(0); + } + + switch( depth ) + { + case CV_32F: + for( j = 0; j < cols; j++ ) + ((float*)dst)[j] = (float)buf[j]; + break; + case CV_64F: + for( j = 0; j < cols; j++ ) + ((double*)dst)[j] = buf[j]; + break; + default: + assert(0); + } + } +} + + +void Core_PerspectiveTransformTest::prepare_to_validation( int ) +{ + CvMat transmat = test_mat[INPUT][1]; + cvTsPerspectiveTransform( test_array[INPUT][0], test_array[REF_OUTPUT][0], &transmat ); +} + +///////////////// Mahalanobis ///////////////////// + +class Core_MahalanobisTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_MahalanobisTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_MahalanobisTest::Core_MahalanobisTest() : Core_MatrixTest( 3, 1, false, true, 1 ) +{ + test_case_count = 100; + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_MahalanobisTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( cvtest::randInt(rng) & 1 ) + sizes[INPUT][0].width = sizes[INPUT][1].width = 1; + else + sizes[INPUT][0].height = sizes[INPUT][1].height = 1; + + sizes[TEMP][0] = sizes[TEMP][1] = sizes[INPUT][0]; + sizes[INPUT][2].width = sizes[INPUT][2].height = sizes[INPUT][0].width + sizes[INPUT][0].height - 1; + sizes[TEMP][2] = sizes[INPUT][2]; + types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0]; +} + +int Core_MahalanobisTest::prepare_test_case( int test_case_idx ) +{ + int code = Base::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + // make sure that the inverted "covariation" matrix is symmetrix and positively defined. + cvtest::gemm( test_mat[INPUT][2], test_mat[INPUT][2], 1., Mat(), 0., test_mat[TEMP][2], GEMM_2_T ); + cvtest::copy( test_mat[TEMP][2], test_mat[INPUT][2] ); + } + + return code; +} + + +void Core_MahalanobisTest::run_func() +{ + test_mat[OUTPUT][0].at(0,0) = + cvRealScalar(cvMahalanobis(test_array[INPUT][0], test_array[INPUT][1], test_array[INPUT][2])); +} + +void Core_MahalanobisTest::prepare_to_validation( int ) +{ + cvtest::add( test_mat[INPUT][0], 1., test_mat[INPUT][1], -1., + Scalar::all(0), test_mat[TEMP][0], test_mat[TEMP][0].type() ); + if( test_mat[INPUT][0].rows == 1 ) + cvtest::gemm( test_mat[TEMP][0], test_mat[INPUT][2], 1., + Mat(), 0., test_mat[TEMP][1], 0 ); + else + cvtest::gemm( test_mat[INPUT][2], test_mat[TEMP][0], 1., + Mat(), 0., test_mat[TEMP][1], 0 ); + + test_mat[REF_OUTPUT][0].at(0,0) = cvRealScalar(sqrt(cvtest::crossCorr(test_mat[TEMP][0], test_mat[TEMP][1]))); +} + + +///////////////// covarmatrix ///////////////////// + +class Core_CovarMatrixTest : public Core_MatrixTest +{ +public: + Core_CovarMatrixTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + vector temp_hdrs; + vector hdr_data; + int flags, t_flag, len, count; + bool are_images; +}; + + +Core_CovarMatrixTest::Core_CovarMatrixTest() : Core_MatrixTest( 1, 1, true, false, 1 ), +flags(0), t_flag(0), are_images(false) +{ + test_case_count = 100; + test_array[INPUT_OUTPUT].push_back(NULL); + test_array[REF_INPUT_OUTPUT].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_CovarMatrixTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + int i, single_matrix; + Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + flags = bits & (CV_COVAR_NORMAL | CV_COVAR_USE_AVG | CV_COVAR_SCALE | CV_COVAR_ROWS ); + single_matrix = flags & CV_COVAR_ROWS; + t_flag = (bits & 256) != 0; + + const int min_count = 2; + + if( !t_flag ) + { + len = sizes[INPUT][0].width; + count = sizes[INPUT][0].height; + count = MAX(count, min_count); + sizes[INPUT][0] = Size(len, count); + } + else + { + len = sizes[INPUT][0].height; + count = sizes[INPUT][0].width; + count = MAX(count, min_count); + sizes[INPUT][0] = Size(count, len); + } + + if( single_matrix && t_flag ) + flags = (flags & ~CV_COVAR_ROWS) | CV_COVAR_COLS; + + if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32S ) + types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK) | CV_32F; + + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = flags & CV_COVAR_NORMAL ? Size(len,len) : Size(count,count); + sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = !t_flag ? Size(len,1) : Size(1,len); + sizes[TEMP][0] = sizes[INPUT][0]; + + types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = + types[OUTPUT][0] = types[REF_OUTPUT][0] = types[TEMP][0] = + CV_MAT_DEPTH(types[INPUT][0]) == CV_64F || (bits & 512) ? CV_64F : CV_32F; + + are_images = (bits & 1024) != 0; + for( i = 0; i < (single_matrix ? 1 : count); i++ ) + temp_hdrs.push_back(NULL); +} + + +int Core_CovarMatrixTest::prepare_test_case( int test_case_idx ) +{ + int code = Core_MatrixTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + int i; + int single_matrix = flags & (CV_COVAR_ROWS|CV_COVAR_COLS); + int hdr_size = are_images ? sizeof(IplImage) : sizeof(CvMat); + + hdr_data.resize(count*hdr_size); + uchar* _hdr_data = &hdr_data[0]; + if( single_matrix ) + { + if( !are_images ) + *((CvMat*)_hdr_data) = test_mat[INPUT][0]; + else + *((IplImage*)_hdr_data) = test_mat[INPUT][0]; + temp_hdrs[0] = _hdr_data; + } + else + for( i = 0; i < count; i++ ) + { + Mat part; + void* ptr = _hdr_data + i*hdr_size; + + if( !t_flag ) + part = test_mat[INPUT][0].row(i); + else + part = test_mat[INPUT][0].col(i); + + if( !are_images ) + *((CvMat*)ptr) = part; + else + *((IplImage*)ptr) = part; + + temp_hdrs[i] = ptr; + } + } + + return code; +} + + +void Core_CovarMatrixTest::run_func() +{ + cvCalcCovarMatrix( (const void**)&temp_hdrs[0], count, + test_array[OUTPUT][0], test_array[INPUT_OUTPUT][0], flags ); +} + + +void Core_CovarMatrixTest::prepare_to_validation( int ) +{ + Mat& avg = test_mat[REF_INPUT_OUTPUT][0]; + double scale = 1.; + + if( !(flags & CV_COVAR_USE_AVG) ) + { + Mat hdrs0 = cvarrToMat(temp_hdrs[0]); + + int i; + avg = Scalar::all(0); + + for( i = 0; i < count; i++ ) + { + Mat vec; + if( flags & CV_COVAR_ROWS ) + vec = hdrs0.row(i); + else if( flags & CV_COVAR_COLS ) + vec = hdrs0.col(i); + else + vec = cvarrToMat(temp_hdrs[i]); + + cvtest::add(avg, 1, vec, 1, Scalar::all(0), avg, avg.type()); + } + + cvtest::add(avg, 1./count, avg, 0., Scalar::all(0), avg, avg.type()); + } + + if( flags & CV_COVAR_SCALE ) + { + scale = 1./count; + } + + Mat& temp0 = test_mat[TEMP][0]; + cv::repeat( avg, temp0.rows/avg.rows, temp0.cols/avg.cols, temp0 ); + cvtest::add( test_mat[INPUT][0], 1, temp0, -1, Scalar::all(0), temp0, temp0.type()); + + cvtest::gemm( temp0, temp0, scale, Mat(), 0., test_mat[REF_OUTPUT][0], + t_flag ^ ((flags & CV_COVAR_NORMAL) != 0) ? CV_GEMM_A_T : CV_GEMM_B_T ); + temp_hdrs.clear(); +} + + +static void cvTsFloodWithZeros( Mat& mat, RNG& rng ) +{ + int k, total = mat.rows*mat.cols, type = mat.type(); + int zero_total = cvtest::randInt(rng) % total; + CV_Assert( type == CV_32FC1 || type == CV_64FC1 ); + + for( k = 0; k < zero_total; k++ ) + { + int i = cvtest::randInt(rng) % mat.rows; + int j = cvtest::randInt(rng) % mat.cols; + + if( type == CV_32FC1 ) + mat.at(i,j) = 0.f; + else + mat.at(i,j) = 0.; + } +} + + +///////////////// determinant ///////////////////// + +class Core_DetTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_DetTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +Core_DetTest::Core_DetTest() : Core_MatrixTest( 1, 1, false, true, 1 ) +{ + test_case_count = 100; + max_log_array_size = 7; + test_array[TEMP].push_back(NULL); +} + + +void Core_DetTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + sizes[INPUT][0].width = sizes[INPUT][0].height = sizes[INPUT][0].height; + sizes[TEMP][0] = sizes[INPUT][0]; + types[TEMP][0] = CV_64FC1; +} + + +void Core_DetTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-2.); + high = cvScalarAll(2.); +} + + +double Core_DetTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-2 : 1e-5; +} + + +int Core_DetTest::prepare_test_case( int test_case_idx ) +{ + int code = Core_MatrixTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() ); + + return code; +} + + +void Core_DetTest::run_func() +{ + test_mat[OUTPUT][0].at(0,0) = cvRealScalar(cvDet(test_array[INPUT][0])); +} + + +// LU method that chooses the optimal in a column pivot element +static double cvTsLU( CvMat* a, CvMat* b=NULL, CvMat* x=NULL, int* rank=0 ) +{ + int i, j, k, N = a->rows, N1 = a->cols, Nm = MIN(N, N1), step = a->step/sizeof(double); + int M = b ? b->cols : 0, b_step = b ? b->step/sizeof(double) : 0; + int x_step = x ? x->step/sizeof(double) : 0; + double *a0 = a->data.db, *b0 = b ? b->data.db : 0; + double *x0 = x ? x->data.db : 0; + double t, det = 1.; + assert( CV_MAT_TYPE(a->type) == CV_64FC1 && + (!b || CV_ARE_TYPES_EQ(a,b)) && (!x || CV_ARE_TYPES_EQ(a,x))); + + for( i = 0; i < Nm; i++ ) + { + double max_val = fabs(a0[i*step + i]); + double *a1, *a2, *b1 = 0, *b2 = 0; + k = i; + + for( j = i+1; j < N; j++ ) + { + t = fabs(a0[j*step + i]); + if( max_val < t ) + { + max_val = t; + k = j; + } + } + + if( k != i ) + { + for( j = i; j < N1; j++ ) + CV_SWAP( a0[i*step + j], a0[k*step + j], t ); + + for( j = 0; j < M; j++ ) + CV_SWAP( b0[i*b_step + j], b0[k*b_step + j], t ); + det = -det; + } + + if( max_val == 0 ) + { + if( rank ) + *rank = i; + return 0.; + } + + a1 = a0 + i*step; + a2 = a1 + step; + b1 = b0 + i*b_step; + b2 = b1 + b_step; + + for( j = i+1; j < N; j++, a2 += step, b2 += b_step ) + { + t = a2[i]/a1[i]; + for( k = i+1; k < N1; k++ ) + a2[k] -= t*a1[k]; + + for( k = 0; k < M; k++ ) + b2[k] -= t*b1[k]; + } + + det *= a1[i]; + } + + if( x ) + { + assert( b ); + + for( i = N-1; i >= 0; i-- ) + { + double* a1 = a0 + i*step; + double* b1 = b0 + i*b_step; + for( j = 0; j < M; j++ ) + { + t = b1[j]; + for( k = i+1; k < N1; k++ ) + t -= a1[k]*x0[k*x_step + j]; + x0[i*x_step + j] = t/a1[i]; + } + } + } + + if( rank ) + *rank = i; + return det; +} + + +void Core_DetTest::prepare_to_validation( int ) +{ + test_mat[INPUT][0].convertTo(test_mat[TEMP][0], test_mat[TEMP][0].type()); + CvMat temp0 = test_mat[TEMP][0]; + test_mat[REF_OUTPUT][0].at(0,0) = cvRealScalar(cvTsLU(&temp0, 0, 0)); +} + + +///////////////// invert ///////////////////// + +class Core_InvertTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_InvertTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int method, rank; + double result; +}; + + +Core_InvertTest::Core_InvertTest() +: Core_MatrixTest( 1, 1, false, false, 1 ), method(0), rank(0), result(0.) +{ + test_case_count = 100; + max_log_array_size = 7; + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_InvertTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height ); + + if( (bits & 3) == 0 ) + { + method = CV_SVD; + if( bits & 4 ) + { + sizes[INPUT][0] = Size(min_size, min_size); + if( bits & 16 ) + method = CV_CHOLESKY; + } + } + else + { + method = CV_LU; + sizes[INPUT][0] = Size(min_size, min_size); + } + + sizes[TEMP][0].width = sizes[INPUT][0].height; + sizes[TEMP][0].height = sizes[INPUT][0].width; + sizes[TEMP][1] = sizes[INPUT][0]; + types[TEMP][0] = types[INPUT][0]; + types[TEMP][1] = CV_64FC1; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(min_size, min_size); +} + + +double Core_InvertTest::get_success_error_level( int /*test_case_idx*/, int, int ) +{ + return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 1e-2 : 1e-6; +} + +int Core_InvertTest::prepare_test_case( int test_case_idx ) +{ + int code = Core_MatrixTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() ); + + if( method == CV_CHOLESKY ) + { + cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][0], 1., + Mat(), 0., test_mat[TEMP][0], CV_GEMM_B_T ); + cvtest::copy( test_mat[TEMP][0], test_mat[INPUT][0] ); + } + } + + return code; +} + + + +void Core_InvertTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-1.); + high = cvScalarAll(1.); +} + + +void Core_InvertTest::run_func() +{ + result = cvInvert(test_array[INPUT][0], test_array[TEMP][0], method); +} + + +static double cvTsSVDet( CvMat* mat, double* ratio ) +{ + int type = CV_MAT_TYPE(mat->type); + int i, nm = MIN( mat->rows, mat->cols ); + CvMat* w = cvCreateMat( nm, 1, type ); + double det = 1.; + + cvSVD( mat, w, 0, 0, 0 ); + + if( type == CV_32FC1 ) + { + for( i = 0; i < nm; i++ ) + det *= w->data.fl[i]; + *ratio = w->data.fl[nm-1] < FLT_EPSILON ? 0 : w->data.fl[nm-1]/w->data.fl[0]; + } + else + { + for( i = 0; i < nm; i++ ) + det *= w->data.db[i]; + *ratio = w->data.db[nm-1] < FLT_EPSILON ? 0 : w->data.db[nm-1]/w->data.db[0]; + } + + cvReleaseMat( &w ); + return det; +} + +void Core_InvertTest::prepare_to_validation( int ) +{ + Mat& input = test_mat[INPUT][0]; + Mat& temp0 = test_mat[TEMP][0]; + Mat& temp1 = test_mat[TEMP][1]; + Mat& dst0 = test_mat[REF_OUTPUT][0]; + Mat& dst = test_mat[OUTPUT][0]; + CvMat _input = input; + double ratio = 0, det = cvTsSVDet( &_input, &ratio ); + double threshold = (input.depth() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000; + + cvtest::convert( input, temp1, temp1.type() ); + + if( det < threshold || + ((method == CV_LU || method == CV_CHOLESKY) && (result == 0 || ratio < threshold)) || + ((method == CV_SVD || method == CV_SVD_SYM) && result < threshold) ) + { + dst = Scalar::all(0); + dst0 = Scalar::all(0); + return; + } + + if( input.rows >= input.cols ) + cvtest::gemm( temp0, input, 1., Mat(), 0., dst, 0 ); + else + cvtest::gemm( input, temp0, 1., Mat(), 0., dst, 0 ); + + cv::setIdentity( dst0, Scalar::all(1) ); +} + + +///////////////// solve ///////////////////// + +class Core_SolveTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_SolveTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int method, rank; + double result; +}; + + +Core_SolveTest::Core_SolveTest() : Core_MatrixTest( 2, 1, false, false, 1 ), method(0), rank(0), result(0.) +{ + test_case_count = 100; + max_log_array_size = 7; + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_SolveTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + CvSize in_sz = sizes[INPUT][0]; + if( in_sz.width > in_sz.height ) + in_sz = cvSize(in_sz.height, in_sz.width); + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + sizes[INPUT][0] = in_sz; + int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height ); + + if( (bits & 3) == 0 ) + { + method = CV_SVD; + if( bits & 4 ) + { + sizes[INPUT][0] = Size(min_size, min_size); + /*if( bits & 8 ) + method = CV_SVD_SYM;*/ + } + } + else + { + method = CV_LU; + sizes[INPUT][0] = Size(min_size, min_size); + } + + sizes[INPUT][1].height = sizes[INPUT][0].height; + sizes[TEMP][0].width = sizes[INPUT][1].width; + sizes[TEMP][0].height = sizes[INPUT][0].width; + sizes[TEMP][1] = sizes[INPUT][0]; + types[TEMP][0] = types[INPUT][0]; + types[TEMP][1] = CV_64FC1; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(sizes[INPUT][1].width, min_size); +} + + +int Core_SolveTest::prepare_test_case( int test_case_idx ) +{ + int code = Core_MatrixTest::prepare_test_case( test_case_idx ); + + /*if( method == CV_SVD_SYM ) + { + cvTsGEMM( test_array[INPUT][0], test_array[INPUT][0], 1., + 0, 0., test_array[TEMP][0], CV_GEMM_B_T ); + cvTsCopy( test_array[TEMP][0], test_array[INPUT][0] ); + }*/ + + return code; +} + + +void Core_SolveTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-1.); + high = cvScalarAll(1.); +} + + +double Core_SolveTest::get_success_error_level( int /*test_case_idx*/, int, int ) +{ + return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 5e-2 : 1e-8; +} + + +void Core_SolveTest::run_func() +{ + result = cvSolve(test_array[INPUT][0], test_array[INPUT][1], test_array[TEMP][0], method); +} + +void Core_SolveTest::prepare_to_validation( int ) +{ + //int rank = test_mat[REF_OUTPUT][0].rows; + Mat& input = test_mat[INPUT][0]; + Mat& dst = test_mat[OUTPUT][0]; + Mat& dst0 = test_mat[REF_OUTPUT][0]; + + if( method == CV_LU ) + { + if( result == 0 ) + { + Mat& temp1 = test_mat[TEMP][1]; + cvtest::convert(input, temp1, temp1.type()); + dst = Scalar::all(0); + CvMat _temp1 = temp1; + double det = cvTsLU( &_temp1, 0, 0 ); + dst0 = Scalar::all(det != 0); + return; + } + + double threshold = (input.type() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000; + CvMat _input = input; + double ratio = 0, det = cvTsSVDet( &_input, &ratio ); + if( det < threshold || ratio < threshold ) + { + dst = Scalar::all(0); + dst0 = Scalar::all(0); + return; + } + } + + Mat* pdst = input.rows <= input.cols ? &test_mat[OUTPUT][0] : &test_mat[INPUT][1]; + + cvtest::gemm( input, test_mat[TEMP][0], 1., test_mat[INPUT][1], -1., *pdst, 0 ); + if( pdst != &dst ) + cvtest::gemm( input, *pdst, 1., Mat(), 0., dst, CV_GEMM_A_T ); + dst0 = Scalar::all(0); +} + + +///////////////// SVD ///////////////////// + +class Core_SVDTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_SVDTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int flags; + bool have_u, have_v, symmetric, compact, vector_w; +}; + + +Core_SVDTest::Core_SVDTest() : +Core_MatrixTest( 1, 4, false, false, 1 ), +flags(0), have_u(false), have_v(false), symmetric(false), compact(false), vector_w(false) +{ + test_case_count = 100; + max_log_array_size = 8; + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_SVDTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int min_size, i, m, n; + + min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height ); + + flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T); + have_u = (bits & 8) != 0; + have_v = (bits & 16) != 0; + symmetric = (bits & 32) != 0; + compact = (bits & 64) != 0; + vector_w = (bits & 128) != 0; + + if( symmetric ) + sizes[INPUT][0] = Size(min_size, min_size); + + m = sizes[INPUT][0].height; + n = sizes[INPUT][0].width; + + if( compact ) + sizes[TEMP][0] = Size(min_size, min_size); + else + sizes[TEMP][0] = sizes[INPUT][0]; + sizes[TEMP][3] = Size(0,0); + + if( vector_w ) + { + sizes[TEMP][3] = sizes[TEMP][0]; + if( bits & 256 ) + sizes[TEMP][0] = Size(1, min_size); + else + sizes[TEMP][0] = Size(min_size, 1); + } + + if( have_u ) + { + sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m); + + if( flags & CV_SVD_U_T ) + CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i ); + } + else + sizes[TEMP][1] = Size(0,0); + + if( have_v ) + { + sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n); + + if( !(flags & CV_SVD_V_T) ) + CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i ); + } + else + sizes[TEMP][2] = Size(0,0); + + types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[TEMP][3] = types[INPUT][0]; + types[OUTPUT][0] = types[OUTPUT][1] = types[OUTPUT][2] = types[INPUT][0]; + types[OUTPUT][3] = CV_8UC1; + sizes[OUTPUT][0] = !have_u || !have_v ? Size(0,0) : sizes[INPUT][0]; + sizes[OUTPUT][1] = !have_u ? Size(0,0) : compact ? Size(min_size,min_size) : Size(m,m); + sizes[OUTPUT][2] = !have_v ? Size(0,0) : compact ? Size(min_size,min_size) : Size(n,n); + sizes[OUTPUT][3] = Size(min_size,1); + + for( i = 0; i < 4; i++ ) + { + sizes[REF_OUTPUT][i] = sizes[OUTPUT][i]; + types[REF_OUTPUT][i] = types[OUTPUT][i]; + } +} + + +int Core_SVDTest::prepare_test_case( int test_case_idx ) +{ + int code = Core_MatrixTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + Mat& input = test_mat[INPUT][0]; + cvTsFloodWithZeros( input, ts->get_rng() ); + + if( symmetric && (have_u || have_v) ) + { + Mat& temp = test_mat[TEMP][have_u ? 1 : 2]; + cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T ); + cvtest::copy( temp, input ); + } + + if( (flags & CV_SVD_MODIFY_A) && test_array[OUTPUT][0] ) + cvtest::copy( input, test_mat[OUTPUT][0] ); + } + + return code; +} + + +void Core_SVDTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-2.); + high = cvScalarAll(2.); +} + +double Core_SVDTest::get_success_error_level( int test_case_idx, int i, int j ) +{ + int input_depth = CV_MAT_DEPTH(cvGetElemType( test_array[INPUT][0] )); + double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 1e-5 : 5e-11; + double output_precision = Base::get_success_error_level( test_case_idx, i, j ); + return MAX(input_precision, output_precision); +} + +void Core_SVDTest::run_func() +{ + CvArr* src = test_array[!(flags & CV_SVD_MODIFY_A) ? INPUT : OUTPUT][0]; + if( !src ) + src = test_array[INPUT][0]; + cvSVD( src, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags ); +} + + +void Core_SVDTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& input = test_mat[INPUT][0]; + int depth = input.depth(); + int i, m = input.rows, n = input.cols, min_size = MIN(m, n); + Mat *src, *dst, *w; + double prev = 0, threshold = depth == CV_32F ? FLT_EPSILON : DBL_EPSILON; + + if( have_u ) + { + src = &test_mat[TEMP][1]; + dst = &test_mat[OUTPUT][1]; + cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T ); + cv::setIdentity( test_mat[REF_OUTPUT][1], Scalar::all(1.) ); + } + + if( have_v ) + { + src = &test_mat[TEMP][2]; + dst = &test_mat[OUTPUT][2]; + cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T ); + cv::setIdentity( test_mat[REF_OUTPUT][2], Scalar::all(1.) ); + } + + w = &test_mat[TEMP][0]; + for( i = 0; i < min_size; i++ ) + { + double normval = 0, aii; + if( w->rows > 1 && w->cols > 1 ) + { + normval = cvtest::norm( w->row(i), NORM_L1 ); + aii = depth == CV_32F ? w->at(i,i) : w->at(i,i); + } + else + { + normval = aii = depth == CV_32F ? w->at(i) : w->at(i); + } + + normval = fabs(normval - aii); + test_mat[OUTPUT][3].at(i) = aii >= 0 && normval < threshold && (i == 0 || aii <= prev); + prev = aii; + } + + test_mat[REF_OUTPUT][3] = Scalar::all(1); + + if( have_u && have_v ) + { + if( vector_w ) + { + test_mat[TEMP][3] = Scalar::all(0); + for( i = 0; i < min_size; i++ ) + { + double val = depth == CV_32F ? w->at(i) : w->at(i); + cvSetReal2D( test_array[TEMP][3], i, i, val ); + } + w = &test_mat[TEMP][3]; + } + + if( m >= n ) + { + cvtest::gemm( test_mat[TEMP][1], *w, 1., Mat(), 0., test_mat[REF_OUTPUT][0], + flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 ); + cvtest::gemm( test_mat[REF_OUTPUT][0], test_mat[TEMP][2], 1., Mat(), 0., + test_mat[OUTPUT][0], flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T ); + } + else + { + cvtest::gemm( *w, test_mat[TEMP][2], 1., Mat(), 0., test_mat[REF_OUTPUT][0], + flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T ); + cvtest::gemm( test_mat[TEMP][1], test_mat[REF_OUTPUT][0], 1., Mat(), 0., + test_mat[OUTPUT][0], flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 ); + } + + cvtest::copy( test_mat[INPUT][0], test_mat[REF_OUTPUT][0] ); + } +} + + + +///////////////// SVBkSb ///////////////////// + +class Core_SVBkSbTest : public Core_MatrixTest +{ +public: + typedef Core_MatrixTest Base; + Core_SVBkSbTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int test_case_idx ); + int flags; + bool have_b, symmetric, compact, vector_w; +}; + + +Core_SVBkSbTest::Core_SVBkSbTest() : Core_MatrixTest( 2, 1, false, false, 1 ), +flags(0), have_b(false), symmetric(false), compact(false), vector_w(false) +{ + test_case_count = 100; + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); + test_array[TEMP].push_back(NULL); +} + + +void Core_SVBkSbTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int bits = cvtest::randInt(rng); + Base::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int min_size, i, m, n; + CvSize b_size; + + min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height ); + + flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T); + have_b = (bits & 16) != 0; + symmetric = (bits & 32) != 0; + compact = (bits & 64) != 0; + vector_w = (bits & 128) != 0; + + if( symmetric ) + sizes[INPUT][0] = Size(min_size, min_size); + + m = sizes[INPUT][0].height; + n = sizes[INPUT][0].width; + + sizes[INPUT][1] = Size(0,0); + b_size = Size(m,m); + if( have_b ) + { + sizes[INPUT][1].height = sizes[INPUT][0].height; + sizes[INPUT][1].width = cvtest::randInt(rng) % 100 + 1; + b_size = sizes[INPUT][1]; + } + + if( compact ) + sizes[TEMP][0] = Size(min_size, min_size); + else + sizes[TEMP][0] = sizes[INPUT][0]; + + if( vector_w ) + { + if( bits & 256 ) + sizes[TEMP][0] = Size(1, min_size); + else + sizes[TEMP][0] = Size(min_size, 1); + } + + sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m); + + if( flags & CV_SVD_U_T ) + CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i ); + + sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n); + + if( !(flags & CV_SVD_V_T) ) + CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i ); + + types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0]; + types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][0]; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size( b_size.width, n ); +} + + +int Core_SVBkSbTest::prepare_test_case( int test_case_idx ) +{ + int code = Base::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + Mat& input = test_mat[INPUT][0]; + cvTsFloodWithZeros( input, ts->get_rng() ); + + if( symmetric ) + { + Mat& temp = test_mat[TEMP][1]; + cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T ); + cvtest::copy( temp, input ); + } + + CvMat _input = input; + cvSVD( &_input, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags ); + } + + return code; +} + + +void Core_SVBkSbTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high ) +{ + low = cvScalarAll(-2.); + high = cvScalarAll(2.); +} + + +double Core_SVBkSbTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-3 : 1e-7; +} + + +void Core_SVBkSbTest::run_func() +{ + cvSVBkSb( test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], + test_array[INPUT][1], test_array[OUTPUT][0], flags ); +} + + +void Core_SVBkSbTest::prepare_to_validation( int ) +{ + Mat& input = test_mat[INPUT][0]; + int i, m = input.rows, n = input.cols, min_size = MIN(m, n); + bool is_float = input.type() == CV_32F; + Size w_size = compact ? Size(min_size,min_size) : Size(m,n); + Mat& w = test_mat[TEMP][0]; + Mat wdb( w_size.height, w_size.width, CV_64FC1 ); + CvMat _w = w, _wdb = wdb; + // use exactly the same threshold as in icvSVD... , + // so the changes in the library and here should be synchronized. + double threshold = cv::sum(w)[0]*(DBL_EPSILON*2);//(is_float ? FLT_EPSILON*10 : DBL_EPSILON*2); + + wdb = Scalar::all(0); + for( i = 0; i < min_size; i++ ) + { + double wii = vector_w ? cvGetReal1D(&_w,i) : cvGetReal2D(&_w,i,i); + cvSetReal2D( &_wdb, i, i, wii > threshold ? 1./wii : 0. ); + } + + Mat u = test_mat[TEMP][1]; + Mat v = test_mat[TEMP][2]; + Mat b = test_mat[INPUT][1]; + + if( is_float ) + { + test_mat[TEMP][1].convertTo(u, CV_64F); + test_mat[TEMP][2].convertTo(v, CV_64F); + if( !b.empty() ) + test_mat[INPUT][1].convertTo(b, CV_64F); + } + + Mat t0, t1; + + if( !b.empty() ) + cvtest::gemm( u, b, 1., Mat(), 0., t0, !(flags & CV_SVD_U_T) ? CV_GEMM_A_T : 0 ); + else if( flags & CV_SVD_U_T ) + cvtest::copy( u, t0 ); + else + cvtest::transpose( u, t0 ); + + cvtest::gemm( wdb, t0, 1, Mat(), 0, t1, 0 ); + + cvtest::gemm( v, t1, 1, Mat(), 0, t0, flags & CV_SVD_V_T ? CV_GEMM_A_T : 0 ); + Mat& dst0 = test_mat[REF_OUTPUT][0]; + t0.convertTo(dst0, dst0.type() ); +} + + +typedef std::complex complex_type; + +struct pred_complex +{ + bool operator() (const complex_type& lhs, const complex_type& rhs) const + { + return fabs(lhs.real() - rhs.real()) > fabs(rhs.real())*FLT_EPSILON ? lhs.real() < rhs.real() : lhs.imag() < rhs.imag(); + } +}; + +struct pred_double +{ + bool operator() (const double& lhs, const double& rhs) const + { + return lhs < rhs; + } +}; + +class Core_SolvePolyTest : public cvtest::BaseTest +{ +public: + Core_SolvePolyTest(); + ~Core_SolvePolyTest(); +protected: + virtual void run( int start_from ); +}; + +Core_SolvePolyTest::Core_SolvePolyTest() {} + +Core_SolvePolyTest::~Core_SolvePolyTest() {} + +void Core_SolvePolyTest::run( int ) +{ + RNG& rng = ts->get_rng(); + int fig = 100; + double range = 50; + double err_eps = 1e-4; + + for (int idx = 0, max_idx = 1000, progress = 0; idx < max_idx; ++idx) + { + progress = update_progress(progress, idx-1, max_idx, 0); + int n = cvtest::randInt(rng) % 13 + 1; + std::vector r(n), ar(n), c(n + 1, 0); + std::vector a(n + 1), u(n * 2), ar1(n), ar2(n); + + int rr_odds = 3; // odds that we get a real root + for (int j = 0; j < n;) + { + if (cvtest::randInt(rng) % rr_odds == 0 || j == n - 1) + r[j++] = cvtest::randReal(rng) * range; + else + { + r[j] = complex_type(cvtest::randReal(rng) * range, + cvtest::randReal(rng) * range + 1); + r[j + 1] = std::conj(r[j]); + j += 2; + } + } + + for (int j = 0, k = 1 << n, jj, kk; j < k; ++j) + { + int p = 0; + complex_type v(1); + for (jj = 0, kk = 1; jj < n && !(j & kk); ++jj, ++p, kk <<= 1) + ; + for (; jj < n; ++jj, kk <<= 1) + { + if (j & kk) + v *= -r[jj]; + else + ++p; + } + c[p] += v; + } + + bool pass = false; + double div = 0, s = 0; + int cubic_case = idx & 1; + for (int maxiter = 100; !pass && maxiter < 10000; maxiter *= 2, cubic_case = (cubic_case + 1) % 2) + { + for (int j = 0; j < n + 1; ++j) + a[j] = c[j].real(); + + CvMat amat, umat; + cvInitMatHeader(&amat, n + 1, 1, CV_64FC1, &a[0]); + cvInitMatHeader(&umat, n, 1, CV_64FC2, &u[0]); + cvSolvePoly(&amat, &umat, maxiter, fig); + + for (int j = 0; j < n; ++j) + ar[j] = complex_type(u[j * 2], u[j * 2 + 1]); + + std::sort(r.begin(), r.end(), pred_complex()); + std::sort(ar.begin(), ar.end(), pred_complex()); + + pass = true; + if( n == 3 ) + { + ar2.resize(n); + cv::Mat _umat2(3, 1, CV_64F, &ar2[0]), umat2 = _umat2; + cvFlip(&amat, &amat, 0); + int nr2; + if( cubic_case == 0 ) + nr2 = cv::solveCubic(cv::Mat(&amat),umat2); + else + nr2 = cv::solveCubic(cv::Mat_(cv::Mat(&amat)), umat2); + cvFlip(&amat, &amat, 0); + if(nr2 > 0) + std::sort(ar2.begin(), ar2.begin()+nr2, pred_double()); + ar2.resize(nr2); + + int nr1 = 0; + for(int j = 0; j < n; j++) + if( fabs(r[j].imag()) < DBL_EPSILON ) + ar1[nr1++] = r[j].real(); + + pass = pass && nr1 == nr2; + if( nr2 > 0 ) + { + div = s = 0; + for(int j = 0; j < nr1; j++) + { + s += fabs(ar1[j]); + div += fabs(ar1[j] - ar2[j]); + } + div /= s; + pass = pass && div < err_eps; + } + } + + div = s = 0; + for (int j = 0; j < n; ++j) + { + s += fabs(r[j].real()) + fabs(r[j].imag()); + div += sqrt(pow(r[j].real() - ar[j].real(), 2) + pow(r[j].imag() - ar[j].imag(), 2)); + } + div /= s; + pass = pass && div < err_eps; + } + + if (!pass) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + ts->printf( cvtest::TS::LOG, "too big diff = %g\n", div ); + + for (size_t j=0;jprintf( cvtest::TS::LOG, "ar2[%d]=%g\n", j, ar2[j]); + ts->printf(cvtest::TS::LOG, "\n"); + + for (size_t j=0;jprintf( cvtest::TS::LOG, "r[%d]=(%g, %g)\n", j, r[j].real(), r[j].imag()); + ts->printf( cvtest::TS::LOG, "\n" ); + for (size_t j=0;jprintf( cvtest::TS::LOG, "ar[%d]=(%g, %g)\n", j, ar[j].real(), ar[j].imag()); + break; + } + } +} + +class Core_CheckRange_Empty : public cvtest::BaseTest +{ +public: + Core_CheckRange_Empty(){} + ~Core_CheckRange_Empty(){} +protected: + virtual void run( int start_from ); +}; + +void Core_CheckRange_Empty::run( int ) +{ + cv::Mat m; + ASSERT_TRUE( cv::checkRange(m) ); +} + +TEST(Core_CheckRange_Empty, accuracy) { Core_CheckRange_Empty test; test.safe_run(); } + +class Core_CheckRange_INT_MAX : public cvtest::BaseTest +{ +public: + Core_CheckRange_INT_MAX(){} + ~Core_CheckRange_INT_MAX(){} +protected: + virtual void run( int start_from ); +}; + +void Core_CheckRange_INT_MAX::run( int ) +{ + cv::Mat m(3, 3, CV_32SC1, cv::Scalar(INT_MAX)); + ASSERT_FALSE( cv::checkRange(m, true, 0, 0, INT_MAX) ); + ASSERT_TRUE( cv::checkRange(m) ); +} + +TEST(Core_CheckRange_INT_MAX, accuracy) { Core_CheckRange_INT_MAX test; test.safe_run(); } + +template class Core_CheckRange : public testing::Test {}; + +TYPED_TEST_CASE_P(Core_CheckRange); + +TYPED_TEST_P(Core_CheckRange, Negative) +{ + double min_bound = 4.5; + double max_bound = 16.0; + + TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); + + cv::Point* bad_pt = new cv::Point(0, 0); + + ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt->x,0); + ASSERT_EQ(bad_pt->y,1); + + delete bad_pt; +} + +TYPED_TEST_P(Core_CheckRange, Positive) +{ + double min_bound = -1; + double max_bound = 16.0; + + TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); + + cv::Point* bad_pt = new cv::Point(0, 0); + + ASSERT_TRUE(checkRange(src, true, bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt->x,0); + ASSERT_EQ(bad_pt->y,0); + + delete bad_pt; +} + +TYPED_TEST_P(Core_CheckRange, Bounds) +{ + double min_bound = 24.5; + double max_bound = 1.0; + + TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); + + cv::Point* bad_pt = new cv::Point(0, 0); + + ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt->x,0); + ASSERT_EQ(bad_pt->y,0); + + delete bad_pt; +} + +TYPED_TEST_P(Core_CheckRange, Zero) +{ + double min_bound = 0.0; + double max_bound = 0.1; + + cv::Mat src = cv::Mat::zeros(3,3, cv::DataDepth::value); + + ASSERT_TRUE( checkRange(src, true, NULL, min_bound, max_bound) ); +} + +REGISTER_TYPED_TEST_CASE_P(Core_CheckRange, Negative, Positive, Bounds, Zero); + +typedef ::testing::Types mat_data_types; +INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Core_CheckRange, mat_data_types); + +TEST(Core_Invert, small) +{ + cv::Mat a = (cv::Mat_(3,3) << 2.42104644730331, 1.81444796521479, -3.98072565304758, 0, 7.08389214348967e-3, 5.55326770986007e-3, 0,0, 7.44556154284261e-3); + //cv::randu(a, -1, 1); + + cv::Mat b = a.t()*a; + cv::Mat c, i = Mat_::eye(3, 3); + cv::invert(b, c, cv::DECOMP_LU); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); + cv::invert(b, c, cv::DECOMP_SVD); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); + cv::invert(b, c, cv::DECOMP_CHOLESKY); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST(Core_CovarMatrix, accuracy) { Core_CovarMatrixTest test; test.safe_run(); } +TEST(Core_CrossProduct, accuracy) { Core_CrossProductTest test; test.safe_run(); } +TEST(Core_Determinant, accuracy) { Core_DetTest test; test.safe_run(); } +TEST(Core_DotProduct, accuracy) { Core_DotProductTest test; test.safe_run(); } +TEST(Core_GEMM, accuracy) { Core_GEMMTest test; test.safe_run(); } +TEST(Core_Invert, accuracy) { Core_InvertTest test; test.safe_run(); } +TEST(Core_Mahalanobis, accuracy) { Core_MahalanobisTest test; test.safe_run(); } +TEST(Core_MulTransposed, accuracy) { Core_MulTransposedTest test; test.safe_run(); } +TEST(Core_Transform, accuracy) { Core_TransformTest test; test.safe_run(); } +TEST(Core_PerspectiveTransform, accuracy) { Core_PerspectiveTransformTest test; test.safe_run(); } +TEST(Core_Pow, accuracy) { Core_PowTest test; test.safe_run(); } +TEST(Core_SolveLinearSystem, accuracy) { Core_SolveTest test; test.safe_run(); } +TEST(Core_SVD, accuracy) { Core_SVDTest test; test.safe_run(); } +TEST(Core_SVBkSb, accuracy) { Core_SVBkSbTest test; test.safe_run(); } +TEST(Core_Trace, accuracy) { Core_TraceTest test; test.safe_run(); } +TEST(Core_SolvePoly, accuracy) { Core_SolvePolyTest test; test.safe_run(); } + + +TEST(Core_SVD, flt) +{ + float a[] = { + 1.23377746e+011f, -7.05490125e+010f, -4.18380882e+010f, -11693456.f, + -39091328.f, 77492224.f, -7.05490125e+010f, 2.36211143e+011f, + -3.51093473e+010f, 70773408.f, -4.83386156e+005f, -129560368.f, + -4.18380882e+010f, -3.51093473e+010f, 9.25311222e+010f, -49052424.f, + 43922752.f, 12176842.f, -11693456.f, 70773408.f, -49052424.f, 8.40836094e+004f, + 5.17475293e+003f, -1.16122949e+004f, -39091328.f, -4.83386156e+005f, + 43922752.f, 5.17475293e+003f, 5.16047969e+004f, 5.68887842e+003f, 77492224.f, + -129560368.f, 12176842.f, -1.16122949e+004f, 5.68887842e+003f, + 1.28060578e+005f + }; + + float b[] = { + 283751232.f, 2.61604198e+009f, -745033216.f, 2.31125625e+005f, + -4.52429188e+005f, -1.37596525e+006f + }; + + Mat A(6, 6, CV_32F, a); + Mat B(6, 1, CV_32F, b); + Mat X, B1; + solve(A, B, X, DECOMP_SVD); + B1 = A*X; + EXPECT_LE(norm(B1, B, NORM_L2 + NORM_RELATIVE), FLT_EPSILON*10); +} + + +// TODO: eigenvv, invsqrt, cbrt, fastarctan, (round, floor, ceil(?)), + + +class CV_KMeansSingularTest : public cvtest::BaseTest +{ +public: + CV_KMeansSingularTest() {} + ~CV_KMeansSingularTest() {} +protected: + void run(int) + { + int i, iter = 0, N = 0, N0 = 0, K = 0, dims = 0; + Mat labels; + try + { + RNG& rng = theRNG(); + const int MAX_DIM=5; + int MAX_POINTS = 100, maxIter = 100; + for( iter = 0; iter < maxIter; iter++ ) + { + ts->update_context(this, iter, true); + dims = rng.uniform(1, MAX_DIM+1); + N = rng.uniform(1, MAX_POINTS+1); + N0 = rng.uniform(1, MAX(N/10, 2)); + K = rng.uniform(1, N+1); + + Mat data0(N0, dims, CV_32F); + rng.fill(data0, RNG::UNIFORM, -1, 1); + + Mat data(N, dims, CV_32F); + for( i = 0; i < N; i++ ) + data0.row(rng.uniform(0, N0)).copyTo(data.row(i)); + + kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0), + 5, KMEANS_PP_CENTERS); + + Mat hist(K, 1, CV_32S, Scalar(0)); + for( i = 0; i < N; i++ ) + { + int l = labels.at(i); + CV_Assert(0 <= l && l < K); + hist.at(l)++; + } + for( i = 0; i < K; i++ ) + CV_Assert( hist.at(i) != 0 ); + } + } + catch(...) + { + ts->printf(cvtest::TS::LOG, + "context: iteration=%d, N=%d, N0=%d, K=%d\n", + iter, N, N0, K); + std::cout << labels << std::endl; + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(); } + +TEST(CovariationMatrixVectorOfMat, accuracy) +{ + unsigned int col_problem_size = 8, row_problem_size = 8, vector_size = 16; + cv::Mat src(vector_size, col_problem_size * row_problem_size, CV_32F); + int singleMatFlags = CV_COVAR_ROWS; + + cv::Mat gold; + cv::Mat goldMean; + cv::randu(src,cv::Scalar(-128), cv::Scalar(128)); + cv::calcCovarMatrix(src,gold,goldMean,singleMatFlags,CV_32F); + std::vector srcVec; + for(size_t i = 0; i < vector_size; i++) + { + srcVec.push_back(src.row(static_cast(i)).reshape(0,col_problem_size)); + } + + cv::Mat actual; + cv::Mat actualMean; + cv::calcCovarMatrix(srcVec, actual, actualMean,singleMatFlags,CV_32F); + + cv::Mat diff; + cv::absdiff(gold, actual, diff); + cv::Scalar s = cv::sum(diff); + ASSERT_EQ(s.dot(s), 0.0); + + cv::Mat meanDiff; + cv::absdiff(goldMean, actualMean.reshape(0,1), meanDiff); + cv::Scalar sDiff = cv::sum(meanDiff); + ASSERT_EQ(sDiff.dot(sDiff), 0.0); +} + +TEST(CovariationMatrixVectorOfMatWithMean, accuracy) +{ + unsigned int col_problem_size = 8, row_problem_size = 8, vector_size = 16; + cv::Mat src(vector_size, col_problem_size * row_problem_size, CV_32F); + int singleMatFlags = CV_COVAR_ROWS | CV_COVAR_USE_AVG; + + cv::Mat gold; + cv::randu(src,cv::Scalar(-128), cv::Scalar(128)); + cv::Mat goldMean; + + cv::reduce(src,goldMean,0 ,CV_REDUCE_AVG, CV_32F); + + cv::calcCovarMatrix(src,gold,goldMean,singleMatFlags,CV_32F); + + std::vector srcVec; + for(size_t i = 0; i < vector_size; i++) + { + srcVec.push_back(src.row(static_cast(i)).reshape(0,col_problem_size)); + } + + cv::Mat actual; + cv::Mat actualMean = goldMean.reshape(0, row_problem_size); + cv::calcCovarMatrix(srcVec, actual, actualMean,singleMatFlags,CV_32F); + + cv::Mat diff; + cv::absdiff(gold, actual, diff); + cv::Scalar s = cv::sum(diff); + ASSERT_EQ(s.dot(s), 0.0); + + cv::Mat meanDiff; + cv::absdiff(goldMean, actualMean.reshape(0,1), meanDiff); + cv::Scalar sDiff = cv::sum(meanDiff); + ASSERT_EQ(sDiff.dot(sDiff), 0.0); +} + +/* End of file. */ + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_misc.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_misc.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_misc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_misc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,50 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +TEST(Core_Drawing, _914) +{ + const int rows = 256; + const int cols = 256; + + Mat img(rows, cols, CV_8UC1, Scalar(255)); + + line(img, Point(0, 10), Point(255, 10), Scalar(0), 2, 4); + line(img, Point(-5, 20), Point(260, 20), Scalar(0), 2, 4); + line(img, Point(10, 0), Point(10, 255), Scalar(0), 2, 4); + + double x0 = 0.0/pow(2.0, -2.0); + double x1 = 255.0/pow(2.0, -2.0); + double y = 30.5/pow(2.0, -2.0); + + line(img, Point(int(x0), int(y)), Point(int(x1), int(y)), Scalar(0), 2, 4, 2); + + int pixelsDrawn = rows*cols - countNonZero(img); + ASSERT_EQ( (3*rows + cols)*3 - 3*9, pixelsDrawn); +} + + +TEST(Core_OutputArraySreate, _1997) +{ + struct local { + static void create(OutputArray arr, Size submatSize, int type) + { + int sizes[] = {submatSize.width, submatSize.height}; + arr.create(sizeof(sizes)/sizeof(sizes[0]), sizes, type); + } + }; + + Mat mat(Size(512, 512), CV_8U); + Size submatSize = Size(256, 256); + + ASSERT_NO_THROW(local::create( mat(Rect(Point(), submatSize)), submatSize, mat.type() )); +} + +TEST(Core_SaturateCast, NegativeNotClipped) +{ + double d = -1.0; + unsigned int val = cv::saturate_cast(d); + + ASSERT_EQ(0xffffffff, val); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_operations.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_operations.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_operations.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_operations.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1216 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +#include +#include +#include +#include +#include +#include + +using namespace cv; +using namespace std; + + +class CV_OperationsTest : public cvtest::BaseTest +{ +public: + CV_OperationsTest(); + ~CV_OperationsTest(); +protected: + void run(int); + + struct test_excep + { + test_excep(const string& _s=string("")) : s(_s) {}; + string s; + }; + + bool SomeMatFunctions(); + bool TestMat(); + template void TestType(Size sz, _Tp value); + bool TestTemplateMat(); + bool TestMatND(); + bool TestSparseMat(); + bool TestVec(); + bool TestMatxMultiplication(); + bool TestSubMatAccess(); + bool TestExp(); + bool TestSVD(); + bool operations1(); + + void checkDiff(const Mat& m1, const Mat& m2, const string& s) + { + if (norm(m1, m2, NORM_INF) != 0) throw test_excep(s); + } + void checkDiffF(const Mat& m1, const Mat& m2, const string& s) + { + if (norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s); + } +}; + +CV_OperationsTest::CV_OperationsTest() +{ +} + +CV_OperationsTest::~CV_OperationsTest() {} + +#define STR(a) STR2(a) +#define STR2(a) #a + +#define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ") != (" #b ") at l." STR(__LINE__)) +#define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ") !=(eps) (" #b ") at l." STR(__LINE__)) + +#if defined _MSC_VER && _MSC_VER < 1400 +#define MSVC_OLD 1 +#else +#define MSVC_OLD 0 +#endif + +template void CV_OperationsTest::TestType(Size sz, _Tp value) +{ + cv::Mat_<_Tp> m(sz); + CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == DataType<_Tp>::depth && + m.channels() == DataType<_Tp>::channels && + m.elemSize() == sizeof(_Tp) && m.step == m.elemSize()*m.cols); + for( int y = 0; y < sz.height; y++ ) + for( int x = 0; x < sz.width; x++ ) + { + m(y,x) = value; + } + + double s = sum(Mat(m).reshape(1))[0]; + CV_Assert( s == (double)sz.width*sz.height ); +} + +bool CV_OperationsTest::TestMat() +{ + try + { + Mat one_3x1(3, 1, CV_32F, Scalar(1.0)); + Mat shi_3x1(3, 1, CV_32F, Scalar(1.2)); + Mat shi_2x1(2, 1, CV_32F, Scalar(-1)); + Scalar shift = Scalar::all(15); + + float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f }; + Mat rot_2x3(2, 3, CV_32F, data); + + Mat res = one_3x1 + shi_3x1 + shi_3x1 + shi_3x1; + res = Mat(Mat(2 * rot_2x3) * res - shi_2x1) + shift; + + Mat tmp, res2; + add(one_3x1, shi_3x1, tmp); + add(tmp, shi_3x1, tmp); + add(tmp, shi_3x1, tmp); + gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0); + add(res2, Mat(2, 1, CV_32F, shift), res2); + + CHECK_DIFF(res, res2); + + Mat mat4x4(4, 4, CV_32F); + randu(mat4x4, Scalar(0), Scalar(10)); + + Mat roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2))); + Mat roi2 = mat4x4(Range(1, 3), Range(1, 3)); + + CHECK_DIFF(roi1, roi2); + CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size()))); + + Mat intMat10(3, 3, CV_32S, Scalar(10)); + Mat intMat11(3, 3, CV_32S, Scalar(11)); + Mat resMat(3, 3, CV_8U, Scalar(255)); + + CHECK_DIFF(resMat, intMat10 == intMat10); + CHECK_DIFF(resMat, intMat10 < intMat11); + CHECK_DIFF(resMat, intMat11 > intMat10); + CHECK_DIFF(resMat, intMat10 <= intMat11); + CHECK_DIFF(resMat, intMat11 >= intMat10); + CHECK_DIFF(resMat, intMat11 != intMat10); + + CHECK_DIFF(resMat, intMat10 == 10.0); + CHECK_DIFF(resMat, 10.0 == intMat10); + CHECK_DIFF(resMat, intMat10 < 11.0); + CHECK_DIFF(resMat, 11.0 > intMat10); + CHECK_DIFF(resMat, 10.0 < intMat11); + CHECK_DIFF(resMat, 11.0 >= intMat10); + CHECK_DIFF(resMat, 10.0 <= intMat11); + CHECK_DIFF(resMat, 10.0 != intMat11); + CHECK_DIFF(resMat, intMat11 != 10.0); + + Mat eye = Mat::eye(3, 3, CV_16S); + Mat maskMat4(3, 3, CV_16S, Scalar(4)); + Mat maskMat1(3, 3, CV_16S, Scalar(1)); + Mat maskMat5(3, 3, CV_16S, Scalar(5)); + Mat maskMat0(3, 3, CV_16S, Scalar(0)); + + CHECK_DIFF(maskMat0, maskMat4 & maskMat1); + CHECK_DIFF(maskMat0, Scalar(1) & maskMat4); + CHECK_DIFF(maskMat0, maskMat4 & Scalar(1)); + + Mat m; + m = maskMat4.clone(); m &= maskMat1; CHECK_DIFF(maskMat0, m); + m = maskMat4.clone(); m &= maskMat1 | maskMat1; CHECK_DIFF(maskMat0, m); + m = maskMat4.clone(); m &= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat0, m); + + m = maskMat4.clone(); m &= Scalar(1); CHECK_DIFF(maskMat0, m); + m = maskMat4.clone(); m |= maskMat1; CHECK_DIFF(maskMat5, m); + m = maskMat5.clone(); m ^= maskMat1; CHECK_DIFF(maskMat4, m); + m = maskMat4.clone(); m |= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat5, m); + m = maskMat5.clone(); m ^= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat4, m); + + m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m); + m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m); + + + + CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1)); + CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1); + CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1)); + CHECK_DIFF(maskMat0, (maskMat1 | maskMat1) & Scalar(4)); + CHECK_DIFF(maskMat0, Scalar(4) & (maskMat1 | maskMat1)); + + CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1)); + CHECK_DIFF(maskMat0, (maskMat4 | maskMat1) ^ maskMat5); + CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ (maskMat4 + maskMat1)); + CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1))); + CHECK_DIFF(maskMat1, Scalar(5) ^ maskMat4); + CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 + maskMat1)); + CHECK_DIFF(maskMat5, Scalar(5) | (maskMat4 + maskMat1)); + CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ Scalar(5)); + + CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1)); + CHECK_DIFF(maskMat5, (maskMat4 ^ maskMat1) | maskMat5); + CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1))); + CHECK_DIFF(maskMat5, (maskMat4 | maskMat4) | Scalar(1)); + CHECK_DIFF(maskMat5, Scalar(1) | (maskMat4 | maskMat4)); + CHECK_DIFF(maskMat5, Scalar(1) | maskMat4); + CHECK_DIFF(maskMat5, (maskMat5 | maskMat5) | (maskMat4 ^ maskMat1)); + + CHECK_DIFF(maskMat1, min(maskMat1, maskMat5)); + CHECK_DIFF(maskMat1, min(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5)); + CHECK_DIFF(maskMat5, max(maskMat1, maskMat5)); + CHECK_DIFF(maskMat5, max(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5)); + + CHECK_DIFF(maskMat1, min(maskMat1, maskMat5 | maskMat5)); + CHECK_DIFF(maskMat1, min(maskMat1 | maskMat1, maskMat5)); + CHECK_DIFF(maskMat5, max(maskMat1 | maskMat1, maskMat5)); + CHECK_DIFF(maskMat5, max(maskMat1, maskMat5 | maskMat5)); + + CHECK_DIFF(~maskMat1, maskMat1 ^ -1); + CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ -1); + + CHECK_DIFF(maskMat1, maskMat4/4.0); + + ///////////////////////////// + + CHECK_DIFF(1.0 - (maskMat5 | maskMat5), -maskMat4); + CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 1.0, maskMat5); + CHECK_DIFF(1.0 + (maskMat4 | maskMat4) * 1.0, maskMat5); + CHECK_DIFF((maskMat5 | maskMat5) * 1.0 - 1.0, maskMat4); + CHECK_DIFF(5.0 - (maskMat4 | maskMat4) * 1.0, maskMat1); + CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 0.5 + 0.5, maskMat5); + CHECK_DIFF(0.5 + ((maskMat4 | maskMat4) * 1.0 + 0.5), maskMat5); + CHECK_DIFF(((maskMat4 | maskMat4) * 1.0 + 2.0) - 1.0, maskMat5); + CHECK_DIFF(5.0 - ((maskMat1 | maskMat1) * 1.0 + 3.0), maskMat1); + CHECK_DIFF( ( (maskMat1 | maskMat1) * 2.0 + 2.0) * 1.25, maskMat5); + CHECK_DIFF( 1.25 * ( (maskMat1 | maskMat1) * 2.0 + 2.0), maskMat5); + CHECK_DIFF( -( (maskMat1 | maskMat1) * (-2.0) + 1.0), maskMat1); + CHECK_DIFF( maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0, maskMat5); + CHECK_DIFF( 1.0 + (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5); + CHECK_DIFF( (maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0) - 1.0, maskMat4); + CHECK_DIFF(5.0 - (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat1); + CHECK_DIFF((maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0)*1.25, maskMat5); + CHECK_DIFF(1.25 * (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5); + CHECK_DIFF(-(maskMat1 * 2.0 + maskMat4 * (-1) + 1.0), maskMat1); + CHECK_DIFF((maskMat1 * 1.0 + maskMat4), maskMat5); + CHECK_DIFF((maskMat4 + maskMat1 * 1.0), maskMat5); + CHECK_DIFF((maskMat1 * 3.0 + 1.0) + maskMat1, maskMat5); + CHECK_DIFF(maskMat1 + (maskMat1 * 3.0 + 1.0), maskMat5); + CHECK_DIFF(maskMat1*4.0 + (maskMat1 | maskMat1), maskMat5); + CHECK_DIFF((maskMat1 | maskMat1) + maskMat1*4.0, maskMat5); + CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1 | maskMat1), maskMat5); + CHECK_DIFF((maskMat1 | maskMat1) + (maskMat1*3.0 + 1.0), maskMat5); + CHECK_DIFF(maskMat1*4.0 + maskMat4*2.0, maskMat1 * 12); + CHECK_DIFF((maskMat1*3.0 + 1.0) + maskMat4*2.0, maskMat1 * 12); + CHECK_DIFF(maskMat4*2.0 + (maskMat1*3.0 + 1.0), maskMat1 * 12); + CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1*2.0 + 2.0), maskMat1 * 8); + + CHECK_DIFF(maskMat5*1.0 - maskMat4, maskMat1); + CHECK_DIFF(maskMat5 - maskMat1 * 4.0, maskMat1); + CHECK_DIFF((maskMat4 * 1.0 + 4.0)- maskMat4, maskMat4); + CHECK_DIFF(maskMat5 - (maskMat1 * 2.0 + 2.0), maskMat1); + CHECK_DIFF(maskMat5*1.0 - (maskMat4 | maskMat4), maskMat1); + CHECK_DIFF((maskMat5 | maskMat5) - maskMat1 * 4.0, maskMat1); + CHECK_DIFF((maskMat4 * 1.0 + 4.0)- (maskMat4 | maskMat4), maskMat4); + CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 * 2.0 + 2.0), maskMat1); + CHECK_DIFF(maskMat1*5.0 - maskMat4 * 1.0, maskMat1); + CHECK_DIFF((maskMat1*5.0 + 3.0)- maskMat4 * 1.0, maskMat4); + CHECK_DIFF(maskMat4 * 2.0 - (maskMat1*4.0 + 3.0), maskMat1); + CHECK_DIFF((maskMat1 * 2.0 + 3.0) - (maskMat1*3.0 + 1.0), maskMat1); + + CHECK_DIFF((maskMat5 - maskMat4)* 4.0, maskMat4); + CHECK_DIFF(4.0 * (maskMat5 - maskMat4), maskMat4); + + CHECK_DIFF(-((maskMat4 | maskMat4) - (maskMat5 | maskMat5)), maskMat1); + + CHECK_DIFF(4.0 * (maskMat1 | maskMat1), maskMat4); + CHECK_DIFF((maskMat4 | maskMat4)/4.0, maskMat1); + +#if !MSVC_OLD + CHECK_DIFF(2.0 * (maskMat1 * 2.0) , maskMat4); +#endif + CHECK_DIFF((maskMat4 / 2.0) / 2.0 , maskMat1); + CHECK_DIFF(-(maskMat4 - maskMat5) , maskMat1); + CHECK_DIFF(-((maskMat4 - maskMat5) * 1.0), maskMat1); + + + ///////////////////////////// + CHECK_DIFF(maskMat4 / maskMat4, maskMat1); + + ///// Element-wise multiplication + + CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat4) * 0.25, maskMat4); + CHECK_DIFF(0.25 * maskMat4.mul(maskMat4), maskMat4); + + ////// Element-wise division + + CHECK_DIFF(maskMat4 / maskMat4, maskMat1); + CHECK_DIFF((maskMat4 & maskMat4) / (maskMat1 * 4), maskMat1); + + CHECK_DIFF((maskMat4 & maskMat4) / maskMat4, maskMat1); + CHECK_DIFF(maskMat4 / (maskMat4 & maskMat4), maskMat1); + CHECK_DIFF((maskMat1 * 4) / maskMat4, maskMat1); + + CHECK_DIFF(maskMat4 / (maskMat1 * 4), maskMat1); + CHECK_DIFF((maskMat4 * 0.5 )/ (maskMat1 * 2), maskMat1); + + CHECK_DIFF(maskMat4 / maskMat4.mul(maskMat1), maskMat1); + CHECK_DIFF((maskMat4 & maskMat4) / maskMat4.mul(maskMat1), maskMat1); + + CHECK_DIFF(4.0 / maskMat4, maskMat1); + CHECK_DIFF(4.0 / (maskMat4 | maskMat4), maskMat1); + CHECK_DIFF(4.0 / (maskMat1 * 4.0), maskMat1); + CHECK_DIFF(4.0 / (maskMat4 / maskMat1), maskMat1); + + m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1); + m = maskMat4.clone(); m/=maskMat4; CHECK_DIFF(m, maskMat1); + m = maskMat4.clone(); m/=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1); + m = maskMat4.clone(); m/=(maskMat4 / maskMat1); CHECK_DIFF(m, maskMat1); + + ///////////////////////////// + float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f}; + Mat mt(3, 3, CV_32F, matrix_data); + Mat mi = mt.inv(); + Mat d1 = Mat::eye(3, 3, CV_32F); + Mat d2 = d1 * 2; + MatExpr mt_tr = mt.t(); + MatExpr mi_tr = mi.t(); + Mat mi2 = mi * 2; + + + CHECK_DIFF_FLT( mi2 * mt, d2 ); + CHECK_DIFF_FLT( mi * mt, d1 ); + CHECK_DIFF_FLT( mt_tr * mi_tr, d1 ); + + m = mi.clone(); m*=mt; CHECK_DIFF_FLT(m, d1); + m = mi.clone(); m*= (2 * mt - mt) ; CHECK_DIFF_FLT(m, d1); + + m = maskMat4.clone(); m+=(maskMat1 * 1.0); CHECK_DIFF(m, maskMat5); + m = maskMat5.clone(); m-=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1); + + m = maskMat1.clone(); m+=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat5); + m = maskMat5.clone(); m-=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat1); +#if !MSVC_OLD + m = mi.clone(); m+=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi + d1 * 4); + m = mi.clone(); m-=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi - d1 * 4); + m = mi.clone(); m*=(mt * 1.0); CHECK_DIFF_FLT(m, d1); + m = mi.clone(); m*=(mt * 1.0 + Mat::eye(m.size(), m.type())); CHECK_DIFF_FLT(m, d1 + mi); + m = mi.clone(); m*=mt_tr.t(); CHECK_DIFF_FLT(m, d1); + + CHECK_DIFF_FLT( (mi * 2) * mt, d2); + CHECK_DIFF_FLT( mi * (2 * mt), d2); + CHECK_DIFF_FLT( mt.t() * mi_tr, d1 ); + CHECK_DIFF_FLT( mt_tr * mi.t(), d1 ); + CHECK_DIFF_FLT( (mi * 0.4) * (mt * 5), d2); + + CHECK_DIFF_FLT( mt.t() * (mi_tr * 2), d2 ); + CHECK_DIFF_FLT( (mt_tr * 2) * mi.t(), d2 ); + + CHECK_DIFF_FLT(mt.t() * mi.t(), d1); + CHECK_DIFF_FLT( (mi * mt) * 2.0, d2); + CHECK_DIFF_FLT( 2.0 * (mi * mt), d2); + CHECK_DIFF_FLT( -(mi * mt), -d1); + + CHECK_DIFF_FLT( (mi * mt) / 2.0, d1 / 2); + + Mat mt_mul_2_plus_1; + gemm(mt, d1, 2, Mat::ones(3, 3, CV_32F), 1, mt_mul_2_plus_1); + + CHECK_DIFF( (mt * 2.0 + 1.0) * mi, mt_mul_2_plus_1 * mi); // (A*alpha + beta)*B + CHECK_DIFF( mi * (mt * 2.0 + 1.0), mi * mt_mul_2_plus_1); // A*(B*alpha + beta) + CHECK_DIFF( (mt * 2.0 + 1.0) * (mi * 2), mt_mul_2_plus_1 * mi2); // (A*alpha + beta)*(B*gamma) + CHECK_DIFF( (mi *2)* (mt * 2.0 + 1.0), mi2 * mt_mul_2_plus_1); // (A*gamma)*(B*alpha + beta) + CHECK_DIFF_FLT( (mt * 2.0 + 1.0) * mi.t(), mt_mul_2_plus_1 * mi_tr); // (A*alpha + beta)*B^t + CHECK_DIFF_FLT( mi.t() * (mt * 2.0 + 1.0), mi_tr * mt_mul_2_plus_1); // A^t*(B*alpha + beta) + + CHECK_DIFF_FLT( (mi * mt + d2)*5, d1 * 3 * 5); + CHECK_DIFF_FLT( mi * mt + d2, d1 * 3); + CHECK_DIFF_FLT( -(mi * mt) + d2, d1); + CHECK_DIFF_FLT( (mi * mt) + d1, d2); + CHECK_DIFF_FLT( d1 + (mi * mt), d2); + CHECK_DIFF_FLT( (mi * mt) - d2, -d1); + CHECK_DIFF_FLT( d2 - (mi * mt), d1); + + CHECK_DIFF_FLT( (mi * mt) + d2 * 0.5, d2); + CHECK_DIFF_FLT( d2 * 0.5 + (mi * mt), d2); + CHECK_DIFF_FLT( (mi * mt) - d1 * 2, -d1); + CHECK_DIFF_FLT( d1 * 2 - (mi * mt), d1); + + CHECK_DIFF_FLT( (mi * mt) + mi.t(), mi_tr + d1); + CHECK_DIFF_FLT( mi.t() + (mi * mt), mi_tr + d1); + CHECK_DIFF_FLT( (mi * mt) - mi.t(), d1 - mi_tr); + CHECK_DIFF_FLT( mi.t() - (mi * mt), mi_tr - d1); + + CHECK_DIFF_FLT( 2.0 *(mi * mt + d2), d1 * 6); + CHECK_DIFF_FLT( -(mi * mt + d2), d1 * -3); + + CHECK_DIFF_FLT(mt.inv() * mt, d1); + + CHECK_DIFF_FLT(mt.inv() * (2*mt - mt), d1); +#endif + } + catch (const test_excep& e) + { + ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str()); + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + +bool CV_OperationsTest::SomeMatFunctions() +{ + try + { + Mat rgba( 10, 10, CV_8UC4, Scalar(1,2,3,4) ); + Mat bgr( rgba.rows, rgba.cols, CV_8UC3 ); + Mat alpha( rgba.rows, rgba.cols, CV_8UC1 ); + Mat out[] = { bgr, alpha }; + // rgba[0] -> bgr[2], rgba[1] -> bgr[1], + // rgba[2] -> bgr[0], rgba[3] -> alpha[0] + int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; + mixChannels( &rgba, 1, out, 2, from_to, 4 ); + + Mat bgr_exp( rgba.size(), CV_8UC3, Scalar(3,2,1)); + Mat alpha_exp( rgba.size(), CV_8UC1, Scalar(4)); + + CHECK_DIFF(bgr_exp, bgr); + CHECK_DIFF(alpha_exp, alpha); + } + catch (const test_excep& e) + { + ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str()); + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; + +} + + +bool CV_OperationsTest::TestSubMatAccess() +{ + try + { + Mat_ T_bs(4,4); + Vec3f cdir(1.f, 1.f, 0.f); + Vec3f ydir(1.f, 0.f, 1.f); + Vec3f fpt(0.1f, 0.7f, 0.2f); + T_bs.setTo(0); + T_bs(Range(0,3),Range(2,3)) = 1.0*Mat(cdir); // wierd OpenCV stuff, need to do multiply + T_bs(Range(0,3),Range(1,2)) = 1.0*Mat(ydir); + T_bs(Range(0,3),Range(0,1)) = 1.0*Mat(cdir.cross(ydir)); + T_bs(Range(0,3),Range(3,4)) = 1.0*Mat(fpt); + T_bs(3,3) = 1.0; + //std::cout << "[Nav Grok] S frame =" << std::endl << T_bs << std::endl; + + // set up display coords, really just the S frame + std::vectorcoords; + + for (int i=0; i<16; i++) + { + coords.push_back(T_bs(i)); + //std::cout << T_bs1(i) << std::endl; + } + CV_Assert( norm(coords, T_bs.reshape(1,1), NORM_INF) == 0 ); + } + catch (const test_excep& e) + { + ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str()); + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + +bool CV_OperationsTest::TestTemplateMat() +{ + try + { + Mat_ one_3x1(3, 1, 1.0f); + Mat_ shi_3x1(3, 1, 1.2f); + Mat_ shi_2x1(2, 1, -2); + Scalar shift = Scalar::all(15); + + float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f }; + Mat_ rot_2x3(2, 3, data); + + Mat_ res = Mat(Mat(2 * rot_2x3) * Mat(one_3x1 + shi_3x1 + shi_3x1 + shi_3x1) - shi_2x1) + shift; + Mat_ resS = rot_2x3 * one_3x1; + + Mat_ tmp, res2, resS2; + add(one_3x1, shi_3x1, tmp); + add(tmp, shi_3x1, tmp); + add(tmp, shi_3x1, tmp); + gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0); + add(res2, Mat(2, 1, CV_32F, shift), res2); + + gemm(rot_2x3, one_3x1, 1, shi_2x1, 0, resS2, 0); + CHECK_DIFF(res, res2); + CHECK_DIFF(resS, resS2); + + + Mat_ mat4x4(4, 4); + randu(mat4x4, Scalar(0), Scalar(10)); + + Mat_ roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2))); + Mat_ roi2 = mat4x4(Range(1, 3), Range(1, 3)); + + CHECK_DIFF(roi1, roi2); + CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size()))); + + Mat_ intMat10(3, 3, 10); + Mat_ intMat11(3, 3, 11); + Mat_ resMat(3, 3, 255); + + CHECK_DIFF(resMat, intMat10 == intMat10); + CHECK_DIFF(resMat, intMat10 < intMat11); + CHECK_DIFF(resMat, intMat11 > intMat10); + CHECK_DIFF(resMat, intMat10 <= intMat11); + CHECK_DIFF(resMat, intMat11 >= intMat10); + + CHECK_DIFF(resMat, intMat10 == 10.0); + CHECK_DIFF(resMat, intMat10 < 11.0); + CHECK_DIFF(resMat, intMat11 > 10.0); + CHECK_DIFF(resMat, intMat10 <= 11.0); + CHECK_DIFF(resMat, intMat11 >= 10.0); + + Mat_ maskMat4(3, 3, 4); + Mat_ maskMat1(3, 3, 1); + Mat_ maskMat5(3, 3, 5); + Mat_ maskMat0(3, 3, (uchar)0); + + CHECK_DIFF(maskMat0, maskMat4 & maskMat1); + CHECK_DIFF(maskMat0, Scalar(1) & maskMat4); + CHECK_DIFF(maskMat0, maskMat4 & Scalar(1)); + + Mat_ m; + m = maskMat4.clone(); m&=maskMat1; CHECK_DIFF(maskMat0, m); + m = maskMat4.clone(); m&=Scalar(1); CHECK_DIFF(maskMat0, m); + + m = maskMat4.clone(); m|=maskMat1; CHECK_DIFF(maskMat5, m); + m = maskMat4.clone(); m^=maskMat1; CHECK_DIFF(maskMat5, m); + + CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1)); + CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1); + CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1)); + + CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1)); + CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1))); + + CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1)); + CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1))); + + CHECK_DIFF(~maskMat1, maskMat1 ^ 0xFF); + CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ 0xFF); + + CHECK_DIFF(maskMat1 + maskMat4, maskMat5); + CHECK_DIFF(maskMat1 + Scalar(4), maskMat5); + CHECK_DIFF(Scalar(4) + maskMat1, maskMat5); + CHECK_DIFF(Scalar(4) + (maskMat1 & maskMat1), maskMat5); + + CHECK_DIFF(maskMat1 + 4.0, maskMat5); + CHECK_DIFF((maskMat1 & 0xFF) + 4.0, maskMat5); + CHECK_DIFF(4.0 + maskMat1, maskMat5); + + m = maskMat4.clone(); m+=Scalar(1); CHECK_DIFF(m, maskMat5); + m = maskMat4.clone(); m+=maskMat1; CHECK_DIFF(m, maskMat5); + m = maskMat4.clone(); m+=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat5); + + CHECK_DIFF(maskMat5 - maskMat1, maskMat4); + CHECK_DIFF(maskMat5 - Scalar(1), maskMat4); + CHECK_DIFF((maskMat5 | maskMat5) - Scalar(1), maskMat4); + CHECK_DIFF(maskMat5 - 1, maskMat4); + CHECK_DIFF((maskMat5 | maskMat5) - 1, maskMat4); + CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 | maskMat1), maskMat4); + + CHECK_DIFF(maskMat1, min(maskMat1, maskMat5)); + CHECK_DIFF(maskMat5, max(maskMat1, maskMat5)); + + m = maskMat5.clone(); m-=Scalar(1); CHECK_DIFF(m, maskMat4); + m = maskMat5.clone(); m-=maskMat1; CHECK_DIFF(m, maskMat4); + m = maskMat5.clone(); m-=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat4); + + m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m); + m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m); + + CHECK_DIFF(maskMat1, maskMat4/4.0); + + Mat_ negf(3, 3, -3.0); + Mat_ posf = -negf; + Mat_ posf2 = posf * 2; + Mat_ negi(3, 3, -3); + + CHECK_DIFF(abs(negf), -negf); + CHECK_DIFF(abs(posf - posf2), -negf); + CHECK_DIFF(abs(negi), -(negi & negi)); + + CHECK_DIFF(5.0 - maskMat4, maskMat1); + + + CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4); + CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4); + + + ////// Element-wise division + + CHECK_DIFF(maskMat4 / maskMat4, maskMat1); + CHECK_DIFF(4.0 / maskMat4, maskMat1); + m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1); + + //////////////////////////////// + + typedef Mat_ TestMat_t; + + const TestMat_t cnegi = negi.clone(); + + TestMat_t::iterator beg = negi.begin(); + TestMat_t::iterator end = negi.end(); + + TestMat_t::const_iterator cbeg = cnegi.begin(); + TestMat_t::const_iterator cend = cnegi.end(); + + int sum = 0; + for(; beg!=end; ++beg) + sum+=*beg; + + for(; cbeg!=cend; ++cbeg) + sum-=*cbeg; + + if (sum != 0) throw test_excep(); + + CHECK_DIFF(negi.col(1), negi.col(2)); + CHECK_DIFF(negi.row(1), negi.row(2)); + CHECK_DIFF(negi.col(1), negi.diag()); + + if (Mat_(1, 1).elemSize1() != sizeof(float)) throw test_excep(); + if (Mat_(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep(); + if (Mat_(1, 1).depth() != CV_32F) throw test_excep(); + if (Mat_(1, 1).depth() != CV_32F) throw test_excep(); + if (Mat_(1, 1).depth() != CV_32S) throw test_excep(); + if (Mat_(1, 1).depth() != CV_64F) throw test_excep(); + if (Mat_(1, 1).depth() != CV_64F) throw test_excep(); + if (Mat_(1, 1).depth() != CV_8S) throw test_excep(); + if (Mat_(1, 1).depth() != CV_16U) throw test_excep(); + if (Mat_(1, 1).channels() != 1) throw test_excep(); + if (Mat_(1, 1).channels() != 2) throw test_excep(); + if (Mat_(1, 1).channels() != 3) throw test_excep(); + if (Mat_(1, 1).channels() != 3) throw test_excep(); + + Mat_ eye = Mat_::zeros(2, 2); CHECK_DIFF(Mat_::zeros(Size(2, 2)), eye); + eye.at(Point(0,0)) = 1; eye.at(1, 1) = 1; + + CHECK_DIFF(Mat_::eye(2, 2), eye); + CHECK_DIFF(eye, Mat_::eye(Size(2,2))); + + Mat_ ones(2, 2, (uchar)1); + CHECK_DIFF(ones, Mat_::ones(Size(2,2))); + CHECK_DIFF(Mat_::ones(2, 2), ones); + + Mat_ pntMat(2, 2, Point2f(1, 0)); + if(pntMat.stepT() != 2) throw test_excep(); + + uchar uchar_data[] = {1, 0, 0, 1}; + + Mat_ matFromData(1, 4, uchar_data); + const Mat_ mat2 = matFromData.clone(); + CHECK_DIFF(matFromData, eye.reshape(1, 1)); + if (matFromData(Point(0,0)) != uchar_data[0])throw test_excep(); + if (mat2(Point(0,0)) != uchar_data[0]) throw test_excep(); + + if (matFromData(0,0) != uchar_data[0])throw test_excep(); + if (mat2(0,0) != uchar_data[0]) throw test_excep(); + + Mat_ rect(eye, Rect(0, 0, 1, 1)); + if (rect.cols != 1 || rect.rows != 1 || rect(0,0) != uchar_data[0]) throw test_excep(); + + //cv::Mat_<_Tp>::adjustROI(int,int,int,int) + //cv::Mat_<_Tp>::cross(const Mat_&) const + //cv::Mat_<_Tp>::Mat_(const vector<_Tp>&,bool) + //cv::Mat_<_Tp>::Mat_(int,int,_Tp*,size_t) + //cv::Mat_<_Tp>::Mat_(int,int,const _Tp&) + //cv::Mat_<_Tp>::Mat_(Size,const _Tp&) + //cv::Mat_<_Tp>::mul(const Mat_<_Tp>&,double) const + //cv::Mat_<_Tp>::mul(const MatExpr_,double,Mat_<_Tp>,MatOp_DivRS_ >,Mat_<_Tp> >&,double) const + //cv::Mat_<_Tp>::mul(const MatExpr_,double,Mat_<_Tp>,MatOp_Scale_ >,Mat_<_Tp> >&,double) const + //cv::Mat_<_Tp>::operator Mat_() const + //cv::Mat_<_Tp>::operator MatExpr_,Mat_<_Tp> >() const + //cv::Mat_<_Tp>::operator()(const Range&,const Range&) const + //cv::Mat_<_Tp>::operator()(const Rect&) const + + //cv::Mat_<_Tp>::operator=(const MatExpr_Base&) + //cv::Mat_<_Tp>::operator[](int) const + + + /////////////////////////////// + + float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f}; + Mat_ mt(3, 3, matrix_data); + Mat_ mi = mt.inv(); + Mat_ d1 = Mat_::eye(3, 3); + Mat_ d2 = d1 * 2; + Mat_ mt_tr = mt.t(); + Mat_ mi_tr = mi.t(); + Mat_ mi2 = mi * 2; + + CHECK_DIFF_FLT( mi2 * mt, d2 ); + CHECK_DIFF_FLT( mi * mt, d1 ); + CHECK_DIFF_FLT( mt_tr * mi_tr, d1 ); + + Mat_ mf; + mf = mi.clone(); mf*=mt; CHECK_DIFF_FLT(mf, d1); + + ////// typedefs ////// + + if (Mat1b(1, 1).elemSize() != sizeof(uchar)) throw test_excep(); + if (Mat2b(1, 1).elemSize() != 2 * sizeof(uchar)) throw test_excep(); + if (Mat3b(1, 1).elemSize() != 3 * sizeof(uchar)) throw test_excep(); + if (Mat1f(1, 1).elemSize() != sizeof(float)) throw test_excep(); + if (Mat2f(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep(); + if (Mat3f(1, 1).elemSize() != 3 * sizeof(float)) throw test_excep(); + if (Mat1f(1, 1).depth() != CV_32F) throw test_excep(); + if (Mat3f(1, 1).depth() != CV_32F) throw test_excep(); + if (Mat3f(1, 1).type() != CV_32FC3) throw test_excep(); + if (Mat1i(1, 1).depth() != CV_32S) throw test_excep(); + if (Mat1d(1, 1).depth() != CV_64F) throw test_excep(); + if (Mat1b(1, 1).depth() != CV_8U) throw test_excep(); + if (Mat3b(1, 1).type() != CV_8UC3) throw test_excep(); + if (Mat1w(1, 1).depth() != CV_16U) throw test_excep(); + if (Mat1s(1, 1).depth() != CV_16S) throw test_excep(); + if (Mat1f(1, 1).channels() != 1) throw test_excep(); + if (Mat1b(1, 1).channels() != 1) throw test_excep(); + if (Mat1i(1, 1).channels() != 1) throw test_excep(); + if (Mat1w(1, 1).channels() != 1) throw test_excep(); + if (Mat1s(1, 1).channels() != 1) throw test_excep(); + if (Mat2f(1, 1).channels() != 2) throw test_excep(); + if (Mat2b(1, 1).channels() != 2) throw test_excep(); + if (Mat2i(1, 1).channels() != 2) throw test_excep(); + if (Mat2w(1, 1).channels() != 2) throw test_excep(); + if (Mat2s(1, 1).channels() != 2) throw test_excep(); + if (Mat3f(1, 1).channels() != 3) throw test_excep(); + if (Mat3b(1, 1).channels() != 3) throw test_excep(); + if (Mat3i(1, 1).channels() != 3) throw test_excep(); + if (Mat3w(1, 1).channels() != 3) throw test_excep(); + if (Mat3s(1, 1).channels() != 3) throw test_excep(); + + vector > mvf, mvf2; + Mat_ mf2; + mvf.push_back(Mat_::ones(4, 3)); + mvf.push_back(Mat_::zeros(4, 3)); + merge(mvf, mf2); + split(mf2, mvf2); + CV_Assert( norm(mvf2[0], mvf[0], CV_C) == 0 && + norm(mvf2[1], mvf[1], CV_C) == 0 ); + + { + Mat a(2,2,CV_32F,1.f); + Mat b(1,2,CV_32F,1.f); + Mat c = (a*b.t()).t(); + CV_Assert( norm(c, CV_L1) == 4. ); + } + + bool badarg_catched = false; + try + { + Mat m1 = Mat::zeros(1, 10, CV_8UC1); + Mat m2 = Mat::zeros(10, 10, CV_8UC3); + m1.copyTo(m2.row(1)); + } + catch(const Exception&) + { + badarg_catched = true; + } + CV_Assert( badarg_catched ); + + Size size(2, 5); + TestType(size, 1.f); + cv::Vec3f val1 = 1.f; + TestType(size, val1); + cv::Matx31f val2 = 1.f; + TestType(size, val2); + cv::Matx41f val3 = 1.f; + TestType(size, val3); + cv::Matx32f val4 = 1.f; + TestType(size, val4); + } + catch (const test_excep& e) + { + ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str()); + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + +bool CV_OperationsTest::TestMatND() +{ + int sizes[] = { 3, 3, 3}; + cv::MatND nd(3, sizes, CV_32F); + + return true; +} + +bool CV_OperationsTest::TestSparseMat() +{ + try + { + int sizes[] = { 10, 10, 10}; + int dims = sizeof(sizes)/sizeof(sizes[0]); + SparseMat mat(dims, sizes, CV_32FC2); + + if (mat.dims() != dims) throw test_excep(); + if (mat.channels() != 2) throw test_excep(); + if (mat.depth() != CV_32F) throw test_excep(); + + SparseMat mat2 = mat.clone(); + } + catch (const test_excep&) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + + +bool CV_OperationsTest::TestMatxMultiplication() +{ + try + { + Matx33f mat(1, 1, 1, 0, 1, 1, 0, 0, 1); // Identity matrix + Point2f pt(3, 4); + Point3f res = mat * pt; // Correctly assumes homogeneous coordinates + + Vec3f res2 = mat*Vec3f(res.x, res.y, res.z); + + if(res.x != 8.0) throw test_excep(); + if(res.y != 5.0) throw test_excep(); + if(res.z != 1.0) throw test_excep(); + + if(res2[0] != 14.0) throw test_excep(); + if(res2[1] != 6.0) throw test_excep(); + if(res2[2] != 1.0) throw test_excep(); + + Matx44f mat44f(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1); + Matx44d mat44d(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1); + Scalar s(4, 3, 2, 1); + Scalar sf = mat44f*s; + Scalar sd = mat44d*s; + + if(sf[0] != 10.0) throw test_excep(); + if(sf[1] != 6.0) throw test_excep(); + if(sf[2] != 3.0) throw test_excep(); + if(sf[3] != 1.0) throw test_excep(); + + if(sd[0] != 10.0) throw test_excep(); + if(sd[1] != 6.0) throw test_excep(); + if(sd[2] != 3.0) throw test_excep(); + if(sd[3] != 1.0) throw test_excep(); + } + catch(const test_excep&) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + return false; + } + return true; +} + + +bool CV_OperationsTest::TestVec() +{ + try + { + cv::Mat hsvImage_f(5, 5, CV_32FC3), hsvImage_b(5, 5, CV_8UC3); + int i = 0,j = 0; + cv::Vec3f a; + + //these compile + cv::Vec3b b = a; + hsvImage_f.at(i,j) = cv::Vec3f((float)i,0,1); + hsvImage_b.at(i,j) = cv::Vec3b(cv::Vec3f((float)i,0,1)); + + //these don't + b = cv::Vec3f(1,0,0); + cv::Vec3b c; + c = cv::Vec3f(0,0,1); + hsvImage_b.at(i,j) = cv::Vec3f((float)i,0,1); + hsvImage_b.at(i,j) = a; + hsvImage_b.at(i,j) = cv::Vec3f(1,2,3); + } + catch(const test_excep&) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + return false; + } + return true; +} + +bool CV_OperationsTest::operations1() +{ + try + { + Point3d p1(1, 1, 1), p2(2, 2, 2), p4(4, 4, 4); + p1*=2; + if (!(p1 == p2)) throw test_excep(); + if (!(p2 * 2 == p4)) throw test_excep(); + if (!(p2 * 2.f == p4)) throw test_excep(); + if (!(p2 * 2.f == p4)) throw test_excep(); + + Point2d pi1(1, 1), pi2(2, 2), pi4(4, 4); + pi1*=2; + if (!(pi1 == pi2)) throw test_excep(); + if (!(pi2 * 2 == pi4)) throw test_excep(); + if (!(pi2 * 2.f == pi4)) throw test_excep(); + if (!(pi2 * 2.f == pi4)) throw test_excep(); + + Vec2d v12(1, 1), v22(2, 2); + v12*=2.0; + if (!(v12 == v22)) throw test_excep(); + + Vec3d v13(1, 1, 1), v23(2, 2, 2); + v13*=2.0; + if (!(v13 == v23)) throw test_excep(); + + Vec4d v14(1, 1, 1, 1), v24(2, 2, 2, 2); + v14*=2.0; + if (!(v14 == v24)) throw test_excep(); + + Size sz(10, 20); + if (sz.area() != 200) throw test_excep(); + if (sz.width != 10 || sz.height != 20) throw test_excep(); + if (((CvSize)sz).width != 10 || ((CvSize)sz).height != 20) throw test_excep(); + + Vec v5d(1, 1, 1, 1, 1); + Vec v6d(1, 1, 1, 1, 1, 1); + Vec v7d(1, 1, 1, 1, 1, 1, 1); + Vec v8d(1, 1, 1, 1, 1, 1, 1, 1); + Vec v9d(1, 1, 1, 1, 1, 1, 1, 1, 1); + Vec v10d(1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + + Vec v10dzero; + for (int ii = 0; ii < 10; ++ii) { + if (!v10dzero[ii] == 0.0) + throw test_excep(); + } + + Mat A(1, 32, CV_32F), B; + for( int i = 0; i < A.cols; i++ ) + A.at(i) = (float)(i <= 12 ? i : 24 - i); + transpose(A, B); + + int minidx[2] = {0, 0}, maxidx[2] = {0, 0}; + double minval = 0, maxval = 0; + minMaxIdx(A, &minval, &maxval, minidx, maxidx); + + if( !(minidx[0] == 0 && minidx[1] == 31 && maxidx[0] == 0 && maxidx[1] == 12 && + minval == -7 && maxval == 12)) + throw test_excep(); + + minMaxIdx(B, &minval, &maxval, minidx, maxidx); + + if( !(minidx[0] == 31 && minidx[1] == 0 && maxidx[0] == 12 && maxidx[1] == 0 && + minval == -7 && maxval == 12)) + throw test_excep(); + + Matx33f b(1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f); + Mat c; + add(Mat::zeros(3, 3, CV_32F), b, c); + CV_Assert( norm(b, c, CV_C) == 0 ); + + add(Mat::zeros(3, 3, CV_64F), b, c, noArray(), c.type()); + CV_Assert( norm(b, c, CV_C) == 0 ); + + add(Mat::zeros(6, 1, CV_64F), 1, c, noArray(), c.type()); + CV_Assert( norm(Matx61f(1.f, 1.f, 1.f, 1.f, 1.f, 1.f), c, CV_C) == 0 ); + + vector pt2d(3); + vector pt3d(2); + + CV_Assert( Mat(pt2d).checkVector(2) == 3 && Mat(pt2d).checkVector(3) < 0 && + Mat(pt3d).checkVector(2) < 0 && Mat(pt3d).checkVector(3) == 2 ); + + Matx44f m44(0.8147f, 0.6324f, 0.9575f, 0.9572f, + 0.9058f, 0.0975f, 0.9649f, 0.4854f, + 0.1270f, 0.2785f, 0.1576f, 0.8003f, + 0.9134f, 0.5469f, 0.9706f, 0.1419f); + double d = determinant(m44); + CV_Assert( fabs(d - (-0.0262)) <= 0.001 ); + + Cv32suf z; + z.i = 0x80000000; + CV_Assert( cvFloor(z.f) == 0 && cvCeil(z.f) == 0 && cvRound(z.f) == 0 ); + } + catch(const test_excep&) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + + +bool CV_OperationsTest::TestExp() +{ + Mat1f tt = Mat1f::ones(4,2); + Mat1f outs; + exp(-tt, outs); + Mat1f tt2 = Mat1f::ones(4,1), outs2; + exp(-tt2, outs2); + return true; +} + + +bool CV_OperationsTest::TestSVD() +{ + try + { + Mat A = (Mat_(3,4) << 1, 2, -1, 4, 2, 4, 3, 5, -1, -2, 6, 7); + Mat x; + SVD::solveZ(A,x); + if( norm(A*x, CV_C) > FLT_EPSILON ) + throw test_excep(); + + SVD svd(A, SVD::FULL_UV); + if( norm(A*svd.vt.row(3).t(), CV_C) > FLT_EPSILON ) + throw test_excep(); + + Mat Dp(3,3,CV_32FC1); + Mat Dc(3,3,CV_32FC1); + Mat Q(3,3,CV_32FC1); + Mat U,Vt,R,T,W; + + Dp.at(0,0)=0.86483884f; Dp.at(0,1)= -0.3077251f; Dp.at(0,2)=-0.55711365f; + Dp.at(1,0)=0.49294353f; Dp.at(1,1)=-0.24209651f; Dp.at(1,2)=-0.25084701f; + Dp.at(2,0)=0; Dp.at(2,1)=0; Dp.at(2,2)=0; + + Dc.at(0,0)=0.75632739f; Dc.at(0,1)= -0.38859656f; Dc.at(0,2)=-0.36773083f; + Dc.at(1,0)=0.9699229f; Dc.at(1,1)=-0.49858192f; Dc.at(1,2)=-0.47134098f; + Dc.at(2,0)=0.10566688f; Dc.at(2,1)=-0.060333252f; Dc.at(2,2)=-0.045333147f; + + Q=Dp*Dc.t(); + SVD decomp; + decomp=SVD(Q); + U=decomp.u; + Vt=decomp.vt; + W=decomp.w; + Mat I = Mat::eye(3, 3, CV_32F); + + if( norm(U*U.t(), I, CV_C) > FLT_EPSILON || + norm(Vt*Vt.t(), I, CV_C) > FLT_EPSILON || + W.at(2) < 0 || W.at(1) < W.at(2) || + W.at(0) < W.at(1) || + norm(U*Mat::diag(W)*Vt, Q, CV_C) > FLT_EPSILON ) + throw test_excep(); + } + catch(const test_excep&) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + +void CV_OperationsTest::run( int /* start_from */) +{ + if (!TestMat()) + return; + + if (!SomeMatFunctions()) + return; + + if (!TestTemplateMat()) + return; + + /* if (!TestMatND()) + return;*/ + + if (!TestSparseMat()) + return; + + if (!TestVec()) + return; + + if (!TestMatxMultiplication()) + return; + + if (!TestSubMatAccess()) + return; + + if (!TestExp()) + return; + + if (!TestSVD()) + return; + + if (!operations1()) + return; + + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Core_Array, expressions) { CV_OperationsTest test; test.safe_run(); } + +class CV_SparseMatTest : public cvtest::BaseTest +{ +public: + CV_SparseMatTest() {} + ~CV_SparseMatTest() {} +protected: + void run(int) + { + try + { + RNG& rng = theRNG(); + const int MAX_DIM=3; + int sizes[MAX_DIM], idx[MAX_DIM]; + for( int iter = 0; iter < 100; iter++ ) + { + ts->printf(cvtest::TS::LOG, "."); + ts->update_context(this, iter, true); + int k, dims = rng.uniform(1, MAX_DIM+1), p = 1; + for( k = 0; k < dims; k++ ) + { + sizes[k] = rng.uniform(1, 30); + p *= sizes[k]; + } + int j, nz = rng.uniform(0, (p+2)/2), nz0 = 0; + SparseMat_ v(dims,sizes); + + CV_Assert( (int)v.nzcount() == 0 ); + + SparseMatIterator_ it = v.begin(); + SparseMatIterator_ it_end = v.end(); + + for( k = 0; it != it_end; ++it, ++k ) + ; + CV_Assert( k == 0 ); + + int sum0 = 0, sum = 0; + for( j = 0; j < nz; j++ ) + { + int val = rng.uniform(1, 100); + for( k = 0; k < dims; k++ ) + idx[k] = rng.uniform(0, sizes[k]); + if( dims == 1 ) + { + CV_Assert( v.ref(idx[0]) == v(idx[0]) ); + } + else if( dims == 2 ) + { + CV_Assert( v.ref(idx[0], idx[1]) == v(idx[0], idx[1]) ); + } + else if( dims == 3 ) + { + CV_Assert( v.ref(idx[0], idx[1], idx[2]) == v(idx[0], idx[1], idx[2]) ); + } + CV_Assert( v.ref(idx) == v(idx) ); + v.ref(idx) += val; + if( v(idx) == val ) + nz0++; + sum0 += val; + } + + CV_Assert( (int)v.nzcount() == nz0 ); + + it = v.begin(); + it_end = v.end(); + + for( k = 0; it != it_end; ++it, ++k ) + sum += *it; + CV_Assert( k == nz0 && sum == sum0 ); + + v.clear(); + CV_Assert( (int)v.nzcount() == 0 ); + + it = v.begin(); + it_end = v.end(); + + for( k = 0; it != it_end; ++it, ++k ) + ; + CV_Assert( k == 0 ); + } + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Core_SparseMat, iterations) { CV_SparseMatTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_precomp.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "test_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_precomp.hpp diffimg-2.0.0/3rdparty/opencv/core/test/test_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,16 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" +#include "opencv2/core/core_c.h" +#include + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/core/test/test_rand.cpp diffimg-2.0.0/3rdparty/opencv/core/test/test_rand.cpp --- diffimg-1.5.0/3rdparty/opencv/core/test/test_rand.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/test/test_rand.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,341 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class Core_RandTest : public cvtest::BaseTest +{ +public: + Core_RandTest(); +protected: + void run(int); + bool check_pdf(const Mat& hist, double scale, int dist_type, + double& refval, double& realval); +}; + + +Core_RandTest::Core_RandTest() +{ +} + +static double chi2_p95(int n) +{ + static float chi2_tab95[] = { + 3.841f, 5.991f, 7.815f, 9.488f, 11.07f, 12.59f, 14.07f, 15.51f, + 16.92f, 18.31f, 19.68f, 21.03f, 21.03f, 22.36f, 23.69f, 25.00f, + 26.30f, 27.59f, 28.87f, 30.14f, 31.41f, 32.67f, 33.92f, 35.17f, + 36.42f, 37.65f, 38.89f, 40.11f, 41.34f, 42.56f, 43.77f }; + static const double xp = 1.64; + CV_Assert(n >= 1); + + if( n <= 30 ) + return chi2_tab95[n-1]; + return n + sqrt((double)2*n)*xp + 0.6666666666666*(xp*xp - 1); +} + +bool Core_RandTest::check_pdf(const Mat& hist, double scale, + int dist_type, double& refval, double& realval) +{ + Mat hist0(hist.size(), CV_32F); + const int* H = (const int*)hist.data; + float* H0 = ((float*)hist0.data); + int i, hsz = hist.cols; + + double sum = 0; + for( i = 0; i < hsz; i++ ) + sum += H[i]; + CV_Assert( fabs(1./sum - scale) < FLT_EPSILON ); + + if( dist_type == CV_RAND_UNI ) + { + float scale0 = (float)(1./hsz); + for( i = 0; i < hsz; i++ ) + H0[i] = scale0; + } + else + { + double sum2 = 0, r = (hsz-1.)/2; + double alpha = 2*sqrt(2.)/r, beta = -alpha*r; + for( i = 0; i < hsz; i++ ) + { + double x = i*alpha + beta; + H0[i] = (float)exp(-x*x); + sum2 += H0[i]; + } + sum2 = 1./sum2; + for( i = 0; i < hsz; i++ ) + H0[i] = (float)(H0[i]*sum2); + } + + double chi2 = 0; + for( i = 0; i < hsz; i++ ) + { + double a = H0[i]; + double b = H[i]*scale; + if( a > DBL_EPSILON ) + chi2 += (a - b)*(a - b)/(a + b); + } + realval = chi2; + + double chi2_pval = chi2_p95(hsz - 1 - (dist_type == CV_RAND_NORMAL ? 2 : 0)); + refval = chi2_pval*0.01; + return realval <= refval; +} + +void Core_RandTest::run( int ) +{ + static int _ranges[][2] = + {{ 0, 256 }, { -128, 128 }, { 0, 65536 }, { -32768, 32768 }, + { -1000000, 1000000 }, { -1000, 1000 }, { -1000, 1000 }}; + + const int MAX_SDIM = 10; + const int N = 2000000; + const int maxSlice = 1000; + const int MAX_HIST_SIZE = 1000; + int progress = 0; + + RNG& rng = ts->get_rng(); + RNG tested_rng = theRNG(); + test_case_count = 200; + + for( int idx = 0; idx < test_case_count; idx++ ) + { + progress = update_progress( progress, idx, test_case_count, 0 ); + ts->update_context( this, idx, false ); + + int depth = cvtest::randInt(rng) % (CV_64F+1); + int c, cn = (cvtest::randInt(rng) % 4) + 1; + int type = CV_MAKETYPE(depth, cn); + int dist_type = cvtest::randInt(rng) % (CV_RAND_NORMAL+1); + int i, k, SZ = N/cn; + Scalar A, B; + + double eps = 1.e-4; + if (depth == CV_64F) + eps = 1.e-7; + + bool do_sphere_test = dist_type == CV_RAND_UNI; + Mat arr[2], hist[4]; + int W[] = {0,0,0,0}; + + arr[0].create(1, SZ, type); + arr[1].create(1, SZ, type); + bool fast_algo = dist_type == CV_RAND_UNI && depth < CV_32F; + + for( c = 0; c < cn; c++ ) + { + int a, b, hsz; + if( dist_type == CV_RAND_UNI ) + { + a = (int)(cvtest::randInt(rng) % (_ranges[depth][1] - + _ranges[depth][0])) + _ranges[depth][0]; + do + { + b = (int)(cvtest::randInt(rng) % (_ranges[depth][1] - + _ranges[depth][0])) + _ranges[depth][0]; + } + while( abs(a-b) <= 1 ); + if( a > b ) + std::swap(a, b); + + unsigned r = (unsigned)(b - a); + fast_algo = fast_algo && r <= 256 && (r & (r-1)) == 0; + hsz = min((unsigned)(b - a), (unsigned)MAX_HIST_SIZE); + do_sphere_test = do_sphere_test && b - a >= 100; + } + else + { + int vrange = _ranges[depth][1] - _ranges[depth][0]; + int meanrange = vrange/16; + int mindiv = MAX(vrange/20, 5); + int maxdiv = MIN(vrange/8, 10000); + + a = cvtest::randInt(rng) % meanrange - meanrange/2 + + (_ranges[depth][0] + _ranges[depth][1])/2; + b = cvtest::randInt(rng) % (maxdiv - mindiv) + mindiv; + hsz = min((unsigned)b*9, (unsigned)MAX_HIST_SIZE); + } + A[c] = a; + B[c] = b; + hist[c].create(1, hsz, CV_32S); + } + + cv::RNG saved_rng = tested_rng; + int maxk = fast_algo ? 0 : 1; + for( k = 0; k <= maxk; k++ ) + { + tested_rng = saved_rng; + int sz = 0, dsz = 0, slice; + for( slice = 0; slice < maxSlice; slice++, sz += dsz ) + { + dsz = slice+1 < maxSlice ? (int)(cvtest::randInt(rng) % (SZ - sz + 1)) : SZ - sz; + Mat aslice = arr[k].colRange(sz, sz + dsz); + tested_rng.fill(aslice, dist_type, A, B); + } + } + + if( maxk >= 1 && norm(arr[0], arr[1], NORM_INF) > eps) + { + ts->printf( cvtest::TS::LOG, "RNG output depends on the array lengths (some generated numbers get lost?)" ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + + for( c = 0; c < cn; c++ ) + { + const uchar* data = arr[0].data; + int* H = hist[c].ptr(); + int HSZ = hist[c].cols; + double minVal = dist_type == CV_RAND_UNI ? A[c] : A[c] - B[c]*4; + double maxVal = dist_type == CV_RAND_UNI ? B[c] : A[c] + B[c]*4; + double scale = HSZ/(maxVal - minVal); + double delta = -minVal*scale; + + hist[c] = Scalar::all(0); + + for( i = c; i < SZ*cn; i += cn ) + { + double val = depth == CV_8U ? ((const uchar*)data)[i] : + depth == CV_8S ? ((const schar*)data)[i] : + depth == CV_16U ? ((const ushort*)data)[i] : + depth == CV_16S ? ((const short*)data)[i] : + depth == CV_32S ? ((const int*)data)[i] : + depth == CV_32F ? ((const float*)data)[i] : + ((const double*)data)[i]; + int ival = cvFloor(val*scale + delta); + if( (unsigned)ival < (unsigned)HSZ ) + { + H[ival]++; + W[c]++; + } + else if( dist_type == CV_RAND_UNI ) + { + if( (minVal <= val && val < maxVal) || (depth >= CV_32F && val == maxVal) ) + { + H[ival < 0 ? 0 : HSZ-1]++; + W[c]++; + } + else + { + putchar('^'); + } + } + } + + if( dist_type == CV_RAND_UNI && W[c] != SZ ) + { + ts->printf( cvtest::TS::LOG, "Uniform RNG gave values out of the range [%g,%g) on channel %d/%d\n", + A[c], B[c], c, cn); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + if( dist_type == CV_RAND_NORMAL && W[c] < SZ*.90) + { + ts->printf( cvtest::TS::LOG, "Normal RNG gave too many values out of the range (%g+4*%g,%g+4*%g) on channel %d/%d\n", + A[c], B[c], A[c], B[c], c, cn); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + double refval = 0, realval = 0; + + if( !check_pdf(hist[c], 1./W[c], dist_type, refval, realval) ) + { + ts->printf( cvtest::TS::LOG, "RNG failed Chi-square test " + "(got %g vs probable maximum %g) on channel %d/%d\n", + realval, refval, c, cn); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + } + + // Monte-Carlo test. Compute volume of SDIM-dimensional sphere + // inscribed in [-1,1]^SDIM cube. + if( do_sphere_test ) + { + int SDIM = cvtest::randInt(rng) % (MAX_SDIM-1) + 2; + int N0 = (SZ*cn/SDIM), n = 0; + double r2 = 0; + const uchar* data = arr[0].data; + double scale[4], delta[4]; + for( c = 0; c < cn; c++ ) + { + scale[c] = 2./(B[c] - A[c]); + delta[c] = -A[c]*scale[c] - 1; + } + + for( i = k = c = 0; i <= SZ*cn - SDIM; i++, k++, c++ ) + { + double val = depth == CV_8U ? ((const uchar*)data)[i] : + depth == CV_8S ? ((const schar*)data)[i] : + depth == CV_16U ? ((const ushort*)data)[i] : + depth == CV_16S ? ((const short*)data)[i] : + depth == CV_32S ? ((const int*)data)[i] : + depth == CV_32F ? ((const float*)data)[i] : ((const double*)data)[i]; + c &= c < cn ? -1 : 0; + val = val*scale[c] + delta[c]; + r2 += val*val; + if( k == SDIM-1 ) + { + n += r2 <= 1; + r2 = 0; + k = -1; + } + } + + double V = ((double)n/N0)*(1 << SDIM); + + // the theoretically computed volume + int sdim = SDIM % 2; + double V0 = sdim + 1; + for( sdim += 2; sdim <= SDIM; sdim += 2 ) + V0 *= 2*CV_PI/sdim; + + if( fabs(V - V0) > 0.3*fabs(V0) ) + { + ts->printf( cvtest::TS::LOG, "RNG failed %d-dim sphere volume test (got %g instead of %g)\n", + SDIM, V, V0); + ts->printf( cvtest::TS::LOG, "depth = %d, N0 = %d\n", depth, N0); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return; + } + } + } +} + +TEST(Core_Rand, quality) { Core_RandTest test; test.safe_run(); } + + +class Core_RandRangeTest : public cvtest::BaseTest +{ +public: + Core_RandRangeTest() {} + ~Core_RandRangeTest() {} +protected: + void run(int) + { + Mat a(Size(1280, 720), CV_8U, Scalar(20)); + Mat af(Size(1280, 720), CV_32F, Scalar(20)); + theRNG().fill(a, RNG::UNIFORM, -DBL_MAX, DBL_MAX); + theRNG().fill(af, RNG::UNIFORM, -DBL_MAX, DBL_MAX); + int n0 = 0, n255 = 0, nx = 0; + int nfmin = 0, nfmax = 0, nfx = 0; + + for( int i = 0; i < a.rows; i++ ) + for( int j = 0; j < a.cols; j++ ) + { + int v = a.at(i,j); + double vf = af.at(i,j); + if( v == 0 ) n0++; + else if( v == 255 ) n255++; + else nx++; + if( vf < FLT_MAX*-0.999f ) nfmin++; + else if( vf > FLT_MAX*0.999f ) nfmax++; + else nfx++; + } + CV_Assert( n0 > nx*2 && n255 > nx*2 ); + CV_Assert( nfmin > nfx*2 && nfmax > nfx*2 ); + } +}; + +TEST(Core_Rand, range) { Core_RandRangeTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/core/version_string.inc diffimg-2.0.0/3rdparty/opencv/core/version_string.inc --- diffimg-1.5.0/3rdparty/opencv/core/version_string.inc 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/core/version_string.inc 2013-05-04 20:06:14.000000000 +0000 @@ -0,0 +1,92 @@ +"\n" +"General configuration for OpenCV 2.4.5 =====================================\n" +" Version control: unknown\n" +"\n" +" Platform:\n" +" Host: Windows 6.1 x86\n" +" CMake: 2.8.8\n" +" CMake generator: Visual Studio 9 2008\n" +" CMake build tool: C:/PROGRA~2/MICROS~1.0/Common7/IDE/devenv.com\n" +" MSVC: 1500\n" +"\n" +" C/C++:\n" +" Built as dynamic libs?: YES\n" +" C++ Compiler: cl\n" +" C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /EHa /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:SSE2 /Oi /fp:fast /wd4251 /MP4 /MD /O2 /Ob2 /D NDEBUG /Zi\n" +" C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /EHa /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:SSE2 /Oi /fp:fast /wd4251 /MP4 /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 \n" +" C Compiler: cl\n" +" C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:SSE2 /Oi /fp:fast /MP4 /MD /O2 /Ob2 /D NDEBUG /Zi\n" +" C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:SSE2 /Oi /fp:fast /MP4 /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 \n" +" Linker flags (Release): /STACK:10000000 /machine:X86 /INCREMENTAL:NO /debug\n" +" Linker flags (Debug): /STACK:10000000 /machine:X86 /debug /INCREMENTAL:YES \n" +" Precompiled headers: YES\n" +"\n" +" OpenCV modules:\n" +" To be built: core imgproc flann highgui features2d calib3d ml video objdetect contrib photo legacy gpu nonfree stitching superres ts videostab\n" +" Disabled: world\n" +" Disabled by dependency: -\n" +" Unavailable: androidcamera java ocl python\n" +"\n" +" GUI: \n" +" QT 4.x: NO\n" +" Win32 UI: YES\n" +" OpenGL support: NO\n" +"\n" +" Media I/O: \n" +" ZLib: build (ver 1.2.7)\n" +" JPEG: build (ver 62)\n" +" PNG: build (ver 1.5.12)\n" +" TIFF: build (ver 42 - 4.0.2)\n" +" JPEG 2000: build (ver 1.900.1)\n" +" OpenEXR: build (ver 1.7.1)\n" +"\n" +" Video I/O:\n" +" Video for Windows: YES\n" +" FFMPEG: YES (prebuilt binaries)\n" +" codec: YES (ver 53.61.100)\n" +" format: YES (ver 53.32.100)\n" +" util: YES (ver 51.35.100)\n" +" swscale: YES (ver 2.1.100)\n" +" gentoo-style: YES\n" +" OpenNI: NO\n" +" OpenNI PrimeSensor Modules: NO\n" +" PvAPI: NO\n" +" GigEVisionSDK: NO\n" +" DirectShow: YES\n" +" Media Foundation: NO\n" +" XIMEA: NO\n" +"\n" +" Other third-party libraries:\n" +" Use IPP: NO\n" +" Use Eigen: NO\n" +" Use TBB: NO\n" +" Use OpenMP: NO\n" +" Use GCD NO\n" +" Use Concurrency NO\n" +" Use C=: NO\n" +" Use Cuda: NO\n" +" Use OpenCL: NO\n" +"\n" +" Python:\n" +" Interpreter: C:/Python27/python2.7.exe (ver 2.7.2)\n" +"\n" +" Java:\n" +" ant: NO\n" +" JNI: NO\n" +" Java tests: YES\n" +"\n" +" Documentation:\n" +" Build Documentation: NO\n" +" Sphinx: NO\n" +" PdfLaTeX compiler: NO\n" +"\n" +" Tests and samples:\n" +" Tests: YES\n" +" Performance tests: YES\n" +" C/C++ Examples: NO\n" +"\n" +" Install path: D:/developpements/opencv-2.4.5/build/install\n" +"\n" +" cvconfig.h is in: D:/developpements/opencv-2.4.5/build\n" +"-----------------------------------------------------------------\n" +"\n" diff -Nru diffimg-1.5.0/3rdparty/opencv/cvconfig.h diffimg-2.0.0/3rdparty/opencv/cvconfig.h --- diffimg-1.5.0/3rdparty/opencv/cvconfig.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/cvconfig.h 2013-05-16 14:06:18.000000000 +0000 @@ -0,0 +1,238 @@ +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if you have `alloca', as a function or macro. */ +/* #undef HAVE_ALLOCA */ + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +/* #undef HAVE_ALLOCA_H */ + +/* Video for Windows support */ +//#define HAVE_VFW + +/* V4L capturing support */ +/* #undef HAVE_CAMV4L */ + +/* V4L2 capturing support */ +/* #undef HAVE_CAMV4L2 */ + +/* V4L2 capturing support in videoio.h */ +/* #undef HAVE_VIDEOIO */ + +/* V4L/V4L2 capturing support via libv4l */ +/* #undef HAVE_LIBV4L */ + +/* Carbon windowing environment */ +/* #undef HAVE_CARBON */ + +/* IEEE1394 capturing support */ +/* #undef HAVE_DC1394 */ + +/* libdc1394 0.9.4 or 0.9.5 */ +/* #undef HAVE_DC1394_095 */ + +/* IEEE1394 capturing support - libdc1394 v2.x */ +/* #undef HAVE_DC1394_2 */ + +/* ffmpeg in Gentoo */ +// #define HAVE_GENTOO_FFMPEG + +/* FFMpeg video library */ +/* #undef HAVE_FFMPEG */ + +/* FFMpeg version flag */ +//#define NEW_FFMPEG + +/* ffmpeg's libswscale */ +//#define HAVE_FFMPEG_SWSCALE + +/* GStreamer multimedia framework */ +/* #undef HAVE_GSTREAMER */ + +/* GTK+ 2.0 Thread support */ +/* #undef HAVE_GTHREAD */ + +/* Win32 UI */ +//#define HAVE_WIN32UI + +/* GTK+ 2.x toolkit */ +/* #undef HAVE_GTK */ + +/* OpenEXR codec */ +/* #undef HAVE_ILMIMF */ +#define HAVE_ILMIMF +#define HAVE_OPENEXR + +/* Apple ImageIO Framework */ +/* #undef HAVE_IMAGEIO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* JPEG-2000 codec */ +/* #undef HAVE_JASPER */ +#define HAVE_JASPER + +/* IJG JPEG codec */ +/* #undef HAVE_JPEG */ +#define HAVE_JPEG + +/* Define to 1 if you have the `dl' library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define to 1 if you have the `gomp' library (-lgomp). */ +/* #undef HAVE_LIBGOMP */ + +/* Define to 1 if you have the `m' library (-lm). */ +/* #undef HAVE_LIBM */ + +/* libpng/png.h needs to be included */ +/* #undef HAVE_LIBPNG_PNG_H */ +#define HAVE_LIBPNG_PNG_H + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +/* #undef HAVE_LIBPTHREAD */ + +/* Define to 1 if you have the `lrint' function. */ +/* #undef HAVE_LRINT */ + +/* PNG codec */ +/* #undef HAVE_PNG */ +#define HAVE_PNG + +/* Define to 1 if you have the `png_get_valid' function. */ +#define HAVE_PNG_GET_VALID + +/* png.h needs to be included */ +#define HAVE_PNG_H + +/* Define to 1 if you have the `png_set_tRNS_to_alpha' function. */ +#define HAVE_PNG_SET_TRNS_TO_ALPHA + +/* QuickTime video libraries */ +/* #undef HAVE_QUICKTIME */ + +/* AVFoundation video libraries */ +/* #undef HAVE_AVFOUNDATION */ + +/* TIFF codec */ +/* #undef HAVE_TIFF */ +#define HAVE_TIFF + +/* Unicap video capture library */ +/* #undef HAVE_UNICAP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Xine video library */ +/* #undef HAVE_XINE */ + +/* OpenNI library */ +/* #undef HAVE_OPENNI */ + +/* LZ77 compression/decompression library (used for PNG) */ +/* #undef HAVE_ZLIB */ +#define HAVE_ZLIB + +/* Intel Integrated Performance Primitives */ +/* #undef HAVE_IPP */ + +/* OpenCV compiled as static or dynamic libs */ +//#define BUILD_SHARED_LIBS + +/* Name of package */ +#define PACKAGE "opencv" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opencvlibrary-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "opencv" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "opencv 2.4.5" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "opencv" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.4.5" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Version number of package */ +#define VERSION "2.4.5" + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Intel Threading Building Blocks */ +/* #undef HAVE_TBB */ + +/* C= */ +/* #undef HAVE_CSTRIPES */ + +/* Eigen Matrix & Linear Algebra Library */ +/* #undef HAVE_EIGEN */ + +/* NVidia Cuda Runtime API*/ +/* #undef HAVE_CUDA */ + +/* NVidia Cuda Fast Fourier Transform (FFT) API*/ +/* #undef HAVE_CUFFT */ + +/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/ +/* #undef HAVE_CUBLAS */ + +/* NVidia Video Decoding API*/ +/* #undef HAVE_NVCUVID */ + +/* Compile for 'real' NVIDIA GPU architectures */ +#define CUDA_ARCH_BIN "" + +/* Compile for 'virtual' NVIDIA PTX architectures */ +#define CUDA_ARCH_PTX "" + +/* NVIDIA GPU features are used */ +#define CUDA_ARCH_FEATURES "" + +/* Create PTX or BIN for 1.0 compute capability */ +/* #undef CUDA_ARCH_BIN_OR_PTX_10 */ + +/* OpenCL Support */ +/* #undef HAVE_OPENCL */ + +/* AMD's OpenCL Fast Fourier Transform Library*/ +/* #undef HAVE_CLAMDFFT */ + +/* AMD's Basic Linear Algebra Subprograms Library*/ +/* #undef HAVE_CLAMDBLAS */ + +/* DirectShow Video Capture library */ +//#define HAVE_DSHOW + +/* Microsoft Media Foundation Capture library */ +/* #undef HAVE_MSMF */ + +/* XIMEA camera support */ +/* #undef HAVE_XIMEA */ + +/* OpenGL support*/ +/* #undef HAVE_OPENGL */ + +/* Clp support */ +/* #undef HAVE_CLP */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/highgui/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/highgui/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,311 @@ +set(the_description "High-level GUI and Media I/O") +ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_androidcamera) + +# ---------------------------------------------------------------------------- +# CMake file for highgui. See root CMakeLists.txt +# Some parts taken from version of Hartmut Seichter, HIT Lab NZ. +# Jose Luis Blanco, 2008 +# ---------------------------------------------------------------------------- + +ocv_clear_vars(GRFMT_LIBS) + +if(WITH_PNG OR WITH_TIFF OR WITH_OPENEXR) + ocv_include_directories(${ZLIB_INCLUDE_DIR}) + list(APPEND GRFMT_LIBS ${ZLIB_LIBRARIES}) +endif() + +if(WITH_JPEG) + add_definitions(-DHAVE_JPEG) + ocv_include_directories(${JPEG_INCLUDE_DIR}) + list(APPEND GRFMT_LIBS ${JPEG_LIBRARIES}) +endif() + +if(WITH_PNG) + add_definitions(-DHAVE_PNG) + add_definitions(${PNG_DEFINITIONS}) + ocv_include_directories(${PNG_INCLUDE_DIR}) + list(APPEND GRFMT_LIBS ${PNG_LIBRARIES}) +endif() + +if(WITH_TIFF) + add_definitions(-DHAVE_TIFF) + ocv_include_directories(${TIFF_INCLUDE_DIR}) + list(APPEND GRFMT_LIBS ${TIFF_LIBRARIES}) +endif() + +if(WITH_JASPER) + add_definitions(-DHAVE_JASPER) + ocv_include_directories(${JASPER_INCLUDE_DIR}) + list(APPEND GRFMT_LIBS ${JASPER_LIBRARIES}) +endif() + +if(WITH_OPENEXR) + add_definitions(-DHAVE_OPENEXR) + include_directories(SYSTEM ${OPENEXR_INCLUDE_PATHS}) + list(APPEND GRFMT_LIBS ${OPENEXR_LIBRARIES}) +endif() + +file(GLOB grfmt_hdrs src/grfmt*.hpp) +file(GLOB grfmt_srcs src/grfmt*.cpp) +list(APPEND grfmt_hdrs src/bitstrm.hpp) +list(APPEND grfmt_srcs src/bitstrm.cpp) + +source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs}) + +set(highgui_hdrs + src/precomp.hpp + src/utils.hpp + src/cap_ffmpeg_impl.hpp + ) + +set(highgui_srcs + src/cap.cpp + src/cap_images.cpp + src/cap_ffmpeg.cpp + src/loadsave.cpp + src/precomp.cpp + src/utils.cpp + src/window.cpp + ) + +file(GLOB highgui_ext_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") + +if(HAVE_QT) + if (HAVE_QT_OPENGL) + set(QT_USE_QTOPENGL TRUE) + endif() + include(${QT_USE_FILE}) + + if(QT_INCLUDE_DIR) + ocv_include_directories(${QT_INCLUDE_DIR}) + endif() + + QT4_ADD_RESOURCES(_RCC_OUTFILES src/window_QT.qrc) + QT4_WRAP_CPP(_MOC_OUTFILES src/window_QT.h) + + list(APPEND HIGHGUI_LIBRARIES ${QT_LIBRARIES} ${QT_QTTEST_LIBRARY}) + list(APPEND highgui_srcs src/window_QT.cpp ${_MOC_OUTFILES} ${_RCC_OUTFILES}) + ocv_check_flag_support(CXX -Wno-missing-declarations _have_flag) + if(${_have_flag}) + set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations) + endif() +elseif(HAVE_WIN32UI) + list(APPEND highgui_srcs src/window_w32.cpp) +elseif(HAVE_GTK) + list(APPEND highgui_srcs src/window_gtk.cpp) +elseif(APPLE) + if(WITH_CARBON) + add_definitions(-DHAVE_CARBON=1) + list(APPEND highgui_srcs src/window_carbon.cpp) + list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime") + elseif(NOT IOS) + add_definitions(-DHAVE_COCOA=1) + list(APPEND highgui_srcs src/window_cocoa.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa") + endif() +endif() + +if(WIN32 AND NOT ARM) + list(APPEND highgui_srcs src/cap_cmu.cpp) +endif() + +if (WIN32 AND HAVE_DSHOW) + list(APPEND highgui_srcs src/cap_dshow.cpp) +endif() + +if (WIN32 AND HAVE_MSMF) + list(APPEND highgui_srcs src/cap_msmf.cpp) +endif() + +if (WIN32 AND HAVE_VFW) + list(APPEND highgui_srcs src/cap_vfw.cpp) +endif() + +if(HAVE_XINE) + list(APPEND highgui_srcs src/cap_xine.cpp) +endif(HAVE_XINE) + +if(HAVE_DC1394_2) + list(APPEND highgui_srcs src/cap_dc1394_v2.cpp) +endif(HAVE_DC1394_2) + +if(HAVE_DC1394) + list(APPEND highgui_srcs src/cap_dc1394.cpp) +endif(HAVE_DC1394) + +if(HAVE_GSTREAMER) + list(APPEND highgui_srcs src/cap_gstreamer.cpp) +endif(HAVE_GSTREAMER) + +if(HAVE_UNICAP) + list(APPEND highgui_srcs src/cap_unicap.cpp) +endif(HAVE_UNICAP) + +if(HAVE_LIBV4L) + list(APPEND highgui_srcs src/cap_libv4l.cpp) +elseif(HAVE_CAMV4L OR HAVE_CAMV4L2 OR HAVE_VIDEOIO) + list(APPEND highgui_srcs src/cap_v4l.cpp) +endif() + +if(HAVE_OPENNI) + list(APPEND highgui_srcs src/cap_openni.cpp) + ocv_include_directories(${OPENNI_INCLUDE_DIR}) + list(APPEND HIGHGUI_LIBRARIES ${OPENNI_LIBRARY}) +endif(HAVE_OPENNI) + +if(HAVE_opencv_androidcamera) + list(APPEND highgui_srcs src/cap_android.cpp) + add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)#TODO: remove this line +endif(HAVE_opencv_androidcamera) + +if(HAVE_XIMEA) + list(APPEND highgui_srcs src/cap_ximea.cpp) + ocv_include_directories(${XIMEA_PATH}) + if(XIMEA_LIBRARY_DIR) + link_directories(${XIMEA_LIBRARY_DIR}) + endif() + list(APPEND HIGHGUI_LIBRARIES m3api) +endif(HAVE_XIMEA) + +if(HAVE_FFMPEG) + if(UNIX AND BZIP2_LIBRARIES) + list(APPEND HIGHGUI_LIBRARIES ${BZIP2_LIBRARIES}) + endif() + if(APPLE) + list(APPEND HIGHGUI_LIBRARIES "-framework VideoDecodeAcceleration" bz2) + endif() +endif(HAVE_FFMPEG) + +if(HAVE_PVAPI) + add_definitions(-DHAVE_PVAPI) + ocv_include_directories(${PVAPI_INCLUDE_PATH}) + set(highgui_srcs src/cap_pvapi.cpp ${highgui_srcs}) + list(APPEND HIGHGUI_LIBRARIES ${PVAPI_LIBRARY}) +endif() + +if(HAVE_GIGE_API) + add_definitions(-DHAVE_GIGE_API) + ocv_include_directories(${GIGEAPI_INCLUDE_PATH}) + set(highgui_srcs src/cap_giganetix.cpp ${highgui_srcs}) + list(APPEND HIGHGUI_LIBRARIES ${GIGEAPI_LIBRARIES}) + list(APPEND highgui_srcs src/cap_giganetix.cpp) +endif(HAVE_GIGE_API) + +if(WITH_IMAGEIO) + add_definitions(-DHAVE_IMAGEIO=1) + if(IOS) + list(APPEND HIGHGUI_LIBRARIES "-framework ImageIO") + endif() +endif(WITH_IMAGEIO) + +if(WITH_AVFOUNDATION) + add_definitions(-DHAVE_AVFOUNDATION=1) + list(APPEND highgui_srcs src/cap_avfoundation.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework AVFoundation" "-framework QuartzCore") +elseif(APPLE) + add_definitions(-DHAVE_QUICKTIME=1) + if(WITH_QUICKTIME) + list(APPEND highgui_srcs src/cap_qt.cpp) + list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime" "-framework CoreFoundation" "-framework QuartzCore") + else() + list(APPEND highgui_srcs src/cap_qtkit.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework QTKit" "-framework QuartzCore" "-framework AppKit") + endif() +endif() + +if(IOS) + add_definitions(-DHAVE_IOS=1) + list(APPEND highgui_srcs src/cap_ios_abstract_camera.mm src/cap_ios_photo_camera.mm src/cap_ios_video_camera.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework Accelerate" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreImage" "-framework CoreMedia" "-framework CoreVideo" "-framework QuartzCore" "-framework AssetsLibrary") +endif() + +if(WIN32) + link_directories("${OpenCV_SOURCE_DIR}/3rdparty/lib") # for ffmpeg wrapper only + include_directories(AFTER SYSTEM "${OpenCV_SOURCE_DIR}/3rdparty/include") # for directshow in VS2005 and multi-monitor support on MinGW +endif() + +if(UNIX) + #these variables are set by CHECK_MODULE macro + foreach(P ${HIGHGUI_INCLUDE_DIRS}) + ocv_include_directories(${P}) + endforeach() + + foreach(P ${HIGHGUI_LIBRARY_DIRS}) + link_directories(${P}) + endforeach() +endif() + +source_group("Src" FILES ${highgui_srcs} ${highgui_hdrs}) +source_group("Include" FILES ${highgui_ext_hdrs}) +ocv_set_module_sources(HEADERS ${highgui_ext_hdrs} SOURCES ${highgui_srcs} ${highgui_hdrs} ${grfmt_srcs} ${grfmt_hdrs}) +ocv_module_include_directories() + +ocv_create_module(${GRFMT_LIBS} ${HIGHGUI_LIBRARIES}) + +if(APPLE) + ocv_check_flag_support(OBJCXX "-fobjc-exceptions" HAVE_OBJC_EXCEPTIONS) + if(HAVE_OBJC_EXCEPTIONS) + foreach(source ${OPENCV_MODULE_${the_module}_SOURCES}) + if("${source}" MATCHES "\\.mm$") + get_source_file_property(flags "${source}" COMPILE_FLAGS) + if(flags) + set(flags "${_flags} -fobjc-exceptions") + else() + set(flags "-fobjc-exceptions") + endif() + + set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}") + endif() + endforeach() + endif() +endif() + +if(BUILD_SHARED_LIBS) + add_definitions(-DHIGHGUI_EXPORTS) +endif() + +if(MSVC) + set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /NODEFAULTLIB:libcmt.lib /DEBUG") +endif() + +#stop automatic dependencies propagation for this module +set_target_properties(${the_module} PROPERTIES LINK_INTERFACE_LIBRARIES "") + +ocv_add_precompiled_headers(${the_module}) +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations) + +if(WIN32 AND WITH_FFMPEG) + #copy ffmpeg dll to the output folder + if(MSVC64 OR MINGW64) + set(FFMPEG_SUFFIX _64) + endif() + + set(ffmpeg_bare_name "opencv_ffmpeg${FFMPEG_SUFFIX}.dll") + set(ffmpeg_bare_name_ver "opencv_ffmpeg${OPENCV_DLLVERSION}${FFMPEG_SUFFIX}.dll") + set(ffmpeg_path "${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/${ffmpeg_bare_name}") + + #if(MSVC AND CMAKE_VERSION VERSION_GREATER "2.8.2") + # add_custom_command(TARGET ${the_module} POST_BUILD + # COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/$/${ffmpeg_bare_name_ver}" + # COMMENT "Copying ${ffmpeg_path} to the output directory") + #else + if(MSVC_IDE) + add_custom_command(TARGET ${the_module} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Release/${ffmpeg_bare_name_ver}" + COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Debug/${ffmpeg_bare_name_ver}" + COMMENT "Copying ${ffmpeg_path} to the output directory") + elseif(MSVC AND (CMAKE_GENERATOR MATCHES "Visual")) + add_custom_command(TARGET ${the_module} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_BUILD_TYPE}/${ffmpeg_bare_name_ver}" + COMMENT "Copying ${ffmpeg_path} to the output directory") + else() + add_custom_command(TARGET ${the_module} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${ffmpeg_bare_name_ver}" + COMMENT "Copying ${ffmpeg_path} to the output directory") + endif() + + install(FILES "${ffmpeg_path}" DESTINATION bin COMPONENT main RENAME "${ffmpeg_bare_name_ver}") +endif() + +ocv_add_accuracy_tests() +ocv_add_perf_tests() diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/doc/highgui.rst diffimg-2.0.0/3rdparty/opencv/highgui/doc/highgui.rst --- diffimg-1.5.0/3rdparty/opencv/highgui/doc/highgui.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/doc/highgui.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,20 @@ +************************************* +highgui. High-level GUI and Media I/O +************************************* + +While OpenCV was designed for use in full-scale +applications and can be used within functionally rich UI frameworks (such as Qt*, WinForms*, or Cocoa*) or without any UI at all, sometimes there it is required to try functionality quickly and visualize the results. This is what the HighGUI module has been designed for. + +It provides easy interface to: + +* Create and manipulate windows that can display images and "remember" their content (no need to handle repaint events from OS). +* Add trackbars to the windows, handle simple mouse events as well as keyboard commands. +* Read and write images to/from disk or memory. +* Read video from camera or file and write video to a file. + +.. toctree:: + :maxdepth: 2 + + user_interface + reading_and_writing_images_and_video + qt_new_functions Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/doc/pics/qtgui.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/doc/pics/qtgui.png differ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/doc/qt_new_functions.rst diffimg-2.0.0/3rdparty/opencv/highgui/doc/qt_new_functions.rst --- diffimg-1.5.0/3rdparty/opencv/highgui/doc/qt_new_functions.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/doc/qt_new_functions.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,338 @@ +Qt New Functions +================ +.. highlight:: cpp + +.. image:: pics/qtgui.png + +This figure explains new functionality implemented with Qt* GUI. The new GUI provides a statusbar, a toolbar, and a control panel. The control panel can have trackbars and buttonbars attached to it. If you cannot see the control panel, press Ctrl+P or right-click any Qt window and select **Display properties window**. + +* + To attach a trackbar, the window name parameter must be NULL. + +* + To attach a buttonbar, a button must be created. + If the last bar attached to the control panel is a buttonbar, the new button is added to the right of the last button. + If the last bar attached to the control panel is a trackbar, or the control panel is empty, a new buttonbar is created. Then, a new button is attached to it. + +See below the example used to generate the figure: :: + + int main(int argc, char *argv[]) + int value = 50; + int value2 = 0; + + cvNamedWindow("main1",CV_WINDOW_NORMAL); + cvNamedWindow("main2",CV_WINDOW_AUTOSIZE | CV_GUI_NORMAL); + + cvCreateTrackbar( "track1", "main1", &value, 255, NULL);//OK tested + char* nameb1 = "button1"; + char* nameb2 = "button2"; + cvCreateButton(nameb1,callbackButton,nameb1,CV_CHECKBOX,1); + + cvCreateButton(nameb2,callbackButton,nameb2,CV_CHECKBOX,0); + cvCreateTrackbar( "track2", NULL, &value2, 255, NULL); + cvCreateButton("button5",callbackButton1,NULL,CV_RADIOBOX,0); + cvCreateButton("button6",callbackButton2,NULL,CV_RADIOBOX,1); + + cvSetMouseCallback( "main2",on_mouse,NULL ); + + IplImage* img1 = cvLoadImage("files/flower.jpg"); + IplImage* img2 = cvCreateImage(cvGetSize(img1),8,3); + CvCapture* video = cvCaptureFromFile("files/hockey.avi"); + IplImage* img3 = cvCreateImage(cvGetSize(cvQueryFrame(video)),8,3); + + while(cvWaitKey(33) != 27) + { + cvAddS(img1,cvScalarAll(value),img2); + cvAddS(cvQueryFrame(video),cvScalarAll(value2),img3); + cvShowImage("main1",img2); + cvShowImage("main2",img3); + } + + cvDestroyAllWindows(); + cvReleaseImage(&img1); + cvReleaseImage(&img2); + cvReleaseImage(&img3); + cvReleaseCapture(&video); + return 0; + } + + +setWindowProperty +--------------------- +Changes parameters of a window dynamically. + +.. ocv:function:: void setWindowProperty( const string& winname, int prop_id, double prop_value ) + +.. ocv:pyfunction:: cv2.setWindowProperty(winname, prop_id, prop_value) -> None + +.. ocv:cfunction:: void cvSetWindowProperty( const char* name, int prop_id, double prop_value ) + + :param name: Name of the window. + + :param prop_id: Window property to edit. The following operation flags are available: + + * **CV_WND_PROP_FULLSCREEN** Change if the window is fullscreen ( ``CV_WINDOW_NORMAL`` or ``CV_WINDOW_FULLSCREEN`` ). + + * **CV_WND_PROP_AUTOSIZE** Change if the window is resizable (``CV_WINDOW_NORMAL`` or ``CV_WINDOW_AUTOSIZE`` ). + + * **CV_WND_PROP_ASPECTRATIO** Change if the aspect ratio of the image is preserved ( ``CV_WINDOW_FREERATIO`` or ``CV_WINDOW_KEEPRATIO`` ). + + + :param prop_value: New value of the window property. The following operation flags are available: + + * **CV_WINDOW_NORMAL** Change the window to normal size or make the window resizable. + + * **CV_WINDOW_AUTOSIZE** Constrain the size by the displayed image. The window is not resizable. + + * **CV_WINDOW_FULLSCREEN** Change the window to fullscreen. + + * **CV_WINDOW_FREERATIO** Make the window resizable without any ratio constraints. + + * **CV_WINDOW_KEEPRATIO** Make the window resizable, but preserve the proportions of the displayed image. + + +The function ``setWindowProperty`` enables changing properties of a window. + +getWindowProperty +--------------------- +Provides parameters of a window. + +.. ocv:function:: double getWindowProperty( const string& winname, int prop_id ) + +.. ocv:pyfunction:: cv2.getWindowProperty(winname, prop_id) -> retval + +.. ocv:cfunction:: double cvGetWindowProperty( const char* name, int prop_id ) + + :param name: Name of the window. + + :param prop_id: Window property to retrieve. The following operation flags are available: + + * **CV_WND_PROP_FULLSCREEN** Change if the window is fullscreen ( ``CV_WINDOW_NORMAL`` or ``CV_WINDOW_FULLSCREEN`` ). + + * **CV_WND_PROP_AUTOSIZE** Change if the window is resizable (``CV_WINDOW_NORMAL`` or ``CV_WINDOW_AUTOSIZE`` ). + + * **CV_WND_PROP_ASPECTRATIO** Change if the aspect ratio of the image is preserved (``CV_WINDOW_FREERATIO`` or ``CV_WINDOW_KEEPRATIO`` ). + + +See +:ocv:func:`setWindowProperty` to know the meaning of the returned values. + +The function ``getWindowProperty`` returns properties of a window. + +fontQt +---------- +Creates the font to draw a text on an image. + +.. ocv:function:: CvFont fontQt(const string& nameFont, int pointSize = -1, Scalar color = Scalar::all(0), int weight = CV_FONT_NORMAL, int style = CV_STYLE_NORMAL, int spacing = 0) + +.. ocv:cfunction:: CvFont cvFontQt(const char* nameFont, int pointSize=-1, CvScalar color=cvScalarAll(0), int weight=CV_FONT_NORMAL, int style=CV_STYLE_NORMAL, int spacing=0) + + :param nameFont: Name of the font. The name should match the name of a system font (such as *Times*). If the font is not found, a default one is used. + + :param pointSize: Size of the font. If not specified, equal zero or negative, the point size of the font is set to a system-dependent default value. Generally, this is 12 points. + + :param color: Color of the font in BGRA where A = 255 is fully transparent. Use the macro ``CV _ RGB`` for simplicity. + + :param weight: Font weight. The following operation flags are available: + + * **CV_FONT_LIGHT** Weight of 25 + + * **CV_FONT_NORMAL** Weight of 50 + + * **CV_FONT_DEMIBOLD** Weight of 63 + + * **CV_FONT_BOLD** Weight of 75 + + * **CV_FONT_BLACK** Weight of 87 + + You can also specify a positive integer for better control. + + :param style: Font style. The following operation flags are available: + + * **CV_STYLE_NORMAL** Normal font + + * **CV_STYLE_ITALIC** Italic font + + * **CV_STYLE_OBLIQUE** Oblique font + + :param spacing: Spacing between characters. It can be negative or positive. + +The function ``fontQt`` creates a ``CvFont`` object. This ``CvFont`` is not compatible with ``putText`` . + +A basic usage of this function is the following: :: + + CvFont font = fontQt(''Times''); + addText( img1, ``Hello World !'', Point(50,50), font); + + +addText +----------- +Creates the font to draw a text on an image. + +.. ocv:function:: void addText( const Mat& img, const string& text, Point org, CvFont font ) + +.. ocv:cfunction:: void cvAddText( const CvArr* img, const char* text, CvPoint org, CvFont * arg2 ) + + :param img: 8-bit 3-channel image where the text should be drawn. + + :param text: Text to write on an image. + + :param org: Point(x,y) where the text should start on an image. + + :param font: Font to use to draw a text. + +The function ``addText`` draws +*text* +on an image +*img* +using a specific font +*font* +(see example :ocv:func:`fontQt` ) + +.. index:: displayOverlay + +displayOverlay +------------------ +Displays a text on a window image as an overlay for a specified duration. + +.. ocv:function:: void displayOverlay( const string& winname, const string& text, int delayms=0 ) + +.. ocv:cfunction:: void cvDisplayOverlay(const char* name, const char* text, int delayms = 0) + + :param name: Name of the window. + + :param text: Overlay text to write on a window image. + + :param delayms: The period (in milliseconds), during which the overlay text is displayed. If this function is called before the previous overlay text timed out, the timer is restarted and the text is updated. If this value is zero, the text never disappears. + +The function ``displayOverlay`` displays useful information/tips on top of the window for a certain amount of time *delayms*. The function does not modify the image, displayed in the window, that is, after the specified delay the original content of the window is restored. + + +displayStatusBar +-------------------- +Displays a text on the window statusbar during the specified period of time. + +.. ocv:function:: void displayStatusBar( const string& winname, const string& text, int delayms=0 ) + +.. ocv:cfunction:: void cvDisplayStatusBar(const char* name, const char* text, int delayms = 0) + + :param name: Name of the window. + + :param text: Text to write on the window statusbar. + + :param delayms: Duration (in milliseconds) to display the text. If this function is called before the previous text timed out, the timer is restarted and the text is updated. If this value is zero, the text never disappears. + +The function ``displayOverlay`` displays useful information/tips on top of the window for a certain amount of time +*delayms* +. This information is displayed on the window statusbar (the window must be created with the ``CV_GUI_EXPANDED`` flags). + +setOpenGlDrawCallback +------------------------ +Sets a callback function to be called to draw on top of displayed image. + +.. ocv:function:: void setOpenGlDrawCallback( const string& winname, OpenGlDrawCallback onOpenGlDraw, void* userdata=0 ) + +.. ocv:cfunction:: void cvSetOpenGlDrawCallback( const char* window_name, CvOpenGlDrawCallback callback, void* userdata=NULL ) + + :param window_name: Name of the window. + + :param onOpenGlDraw: Pointer to the function to be called every frame. This function should be prototyped as ``void Foo(void*)`` . + + :param userdata: Pointer passed to the callback function. *(Optional)* + +The function ``setOpenGlDrawCallback`` can be used to draw 3D data on the window. See the example of callback function below: :: + + void on_opengl(void* param) + { + glLoadIdentity(); + + glTranslated(0.0, 0.0, -1.0); + + glRotatef( 55, 1, 0, 0 ); + glRotatef( 45, 0, 1, 0 ); + glRotatef( 0, 0, 0, 1 ); + + static const int coords[6][4][3] = { + { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } }, + { { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } }, + { { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } }, + { { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } }, + { { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } }, + { { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } } + }; + + for (int i = 0; i < 6; ++i) { + glColor3ub( i*20, 100+i*10, i*42 ); + glBegin(GL_QUADS); + for (int j = 0; j < 4; ++j) { + glVertex3d(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2]); + } + glEnd(); + } + } + + +saveWindowParameters +------------------------ +Saves parameters of the specified window. + +.. ocv:function:: void saveWindowParameters( const string& windowName ) + +.. ocv:cfunction:: void cvSaveWindowParameters(const char* name) + + :param name: Name of the window. + +The function ``saveWindowParameters`` saves size, location, flags, trackbars value, zoom and panning location of the window +``window_name`` . + +loadWindowParameters +------------------------ +Loads parameters of the specified window. + +.. ocv:function:: void loadWindowParameters( const string& windowName ) + +.. ocv:cfunction:: void cvLoadWindowParameters(const char* name) + + :param name: Name of the window. + +The function ``loadWindowParameters`` loads size, location, flags, trackbars value, zoom and panning location of the window +``window_name`` . + +createButton +---------------- +Attaches a button to the control panel. + +.. ocv:function:: int createButton( const string& bar_name, ButtonCallback on_change, void* userdata=NULL, int type=CV_PUSH_BUTTON, bool initial_button_state=0 ) + +.. ocv:cfunction:: int cvCreateButton( const char* button_name=NULL, CvButtonCallback on_change=NULL, void* userdata=NULL, int button_type=CV_PUSH_BUTTON, int initial_button_state=0 ) + + :param button_name: Name of the button. + + :param on_change: Pointer to the function to be called every time the button changes its state. This function should be prototyped as ``void Foo(int state,*void);`` . *state* is the current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button. + + :param userdata: Pointer passed to the callback function. + + :param button_type: Optional type of the button. + + * **CV_PUSH_BUTTON** Push button + + * **CV_CHECKBOX** Checkbox button + + * **CV_RADIOBOX** Radiobox button. The radiobox on the same buttonbar (same line) are exclusive, that is only one can be selected at a time. + + :param initial_button_state: Default state of the button. Use for checkbox and radiobox. Its value could be 0 or 1. *(Optional)* + +The function ``createButton`` attaches a button to the control panel. Each button is added to a buttonbar to the right of the last button. +A new buttonbar is created if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar. + +See below various examples of the ``createButton`` function call: :: + + createButton(NULL,callbackButton);//create a push button "button 0", that will call callbackButton. + createButton("button2",callbackButton,NULL,CV_CHECKBOX,0); + createButton("button3",callbackButton,&value); + createButton("button5",callbackButton1,NULL,CV_RADIOBOX); + createButton("button6",callbackButton2,NULL,CV_PUSH_BUTTON,1); + +.. + + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/doc/reading_and_writing_images_and_video.rst diffimg-2.0.0/3rdparty/opencv/highgui/doc/reading_and_writing_images_and_video.rst --- diffimg-1.5.0/3rdparty/opencv/highgui/doc/reading_and_writing_images_and_video.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/doc/reading_and_writing_images_and_video.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,549 @@ +Reading and Writing Images and Video +==================================== + +.. highlight:: cpp + +imdecode +-------- +Reads an image from a buffer in memory. + +.. ocv:function:: Mat imdecode( InputArray buf, int flags ) + +.. ocv:function:: Mat imdecode( InputArray buf, int flags, Mat* dst ) + +.. ocv:cfunction:: IplImage* cvDecodeImage( const CvMat* buf, int iscolor=CV_LOAD_IMAGE_COLOR) + +.. ocv:cfunction:: CvMat* cvDecodeImageM( const CvMat* buf, int iscolor=CV_LOAD_IMAGE_COLOR) + +.. ocv:pyfunction:: cv2.imdecode(buf, flags) -> retval + + :param buf: Input array or vector of bytes. + + :param flags: The same flags as in :ocv:func:`imread` . + + :param dst: The optional output placeholder for the decoded matrix. It can save the image reallocations when the function is called repeatedly for images of the same size. + +The function reads an image from the specified buffer in the memory. +If the buffer is too short or contains invalid data, the empty matrix/image is returned. + +See +:ocv:func:`imread` for the list of supported formats and flags description. + +.. note:: In the case of color images, the decoded images will have the channels stored in ``B G R`` order. + +imencode +-------- +Encodes an image into a memory buffer. + +.. ocv:function:: bool imencode( const string& ext, InputArray img, vector& buf, const vector& params=vector()) + +.. ocv:cfunction:: CvMat* cvEncodeImage( const char* ext, const CvArr* image, const int* params=0 ) + +.. ocv:pyfunction:: cv2.imencode(ext, img[, params]) -> retval, buf + + :param ext: File extension that defines the output format. + + :param img: Image to be written. + + :param buf: Output buffer resized to fit the compressed image. + + :param params: Format-specific parameters. See :ocv:func:`imwrite` . + +The function compresses the image and stores it in the memory buffer that is resized to fit the result. +See +:ocv:func:`imwrite` for the list of supported formats and flags description. + +.. note:: ``cvEncodeImage`` returns single-row matrix of type ``CV_8UC1`` that contains encoded image as array of bytes. + +imread +------ +Loads an image from a file. + +.. ocv:function:: Mat imread( const string& filename, int flags=1 ) + +.. ocv:pyfunction:: cv2.imread(filename[, flags]) -> retval + +.. ocv:cfunction:: IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ) + +.. ocv:cfunction:: CvMat* cvLoadImageM( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ) + +.. ocv:pyoldfunction:: cv.LoadImage(filename, iscolor=CV_LOAD_IMAGE_COLOR) -> None + +.. ocv:pyoldfunction:: cv.LoadImageM(filename, iscolor=CV_LOAD_IMAGE_COLOR) -> None + + :param filename: Name of file to be loaded. + + :param flags: Flags specifying the color type of a loaded image: + + * CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. + + * CV_LOAD_IMAGE_COLOR - If set, always convert image to the color one + + * CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one + + * **>0** Return a 3-channel color image. + .. note:: In the current implementation the alpha channel, if any, is stripped from the output image. Use negative value if you need the alpha channel. + + * **=0** Return a grayscale image. + + * **<0** Return the loaded image as is (with alpha channel). + +The function ``imread`` loads an image from the specified file and returns it. If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function returns an empty matrix ( ``Mat::data==NULL`` ). Currently, the following file formats are supported: + + * Windows bitmaps - ``*.bmp, *.dib`` (always supported) + + * JPEG files - ``*.jpeg, *.jpg, *.jpe`` (see the *Notes* section) + + * JPEG 2000 files - ``*.jp2`` (see the *Notes* section) + + * Portable Network Graphics - ``*.png`` (see the *Notes* section) + + * Portable image format - ``*.pbm, *.pgm, *.ppm`` (always supported) + + * Sun rasters - ``*.sr, *.ras`` (always supported) + + * TIFF files - ``*.tiff, *.tif`` (see the *Notes* section) + +.. note:: + + * The function determines the type of an image by the content, not by the file extension. + + * On Microsoft Windows* OS and MacOSX*, the codecs shipped with an OpenCV image (libjpeg, libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs, and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware that currently these native image loaders give images with different pixel values because of the color management embedded into MacOSX. + + * On Linux*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for codecs supplied with an OS image. Install the relevant packages (do not forget the development files, for example, "libjpeg-dev", in Debian* and Ubuntu*) to get the codec support or turn on the ``OPENCV_BUILD_3RDPARTY_LIBS`` flag in CMake. + +.. note:: In the case of color images, the decoded images will have the channels stored in ``B G R`` order. + +imwrite +----------- +Saves an image to a specified file. + +.. ocv:function:: bool imwrite( const string& filename, InputArray img, const vector& params=vector() ) + +.. ocv:pyfunction:: cv2.imwrite(filename, img[, params]) -> retval + +.. ocv:cfunction:: int cvSaveImage( const char* filename, const CvArr* image, const int* params=0 ) + +.. ocv:pyoldfunction:: cv.SaveImage(filename, image)-> None + + :param filename: Name of the file. + + :param image: Image to be saved. + + :param params: Format-specific save parameters encoded as pairs ``paramId_1, paramValue_1, paramId_2, paramValue_2, ...`` . The following parameters are currently supported: + + * For JPEG, it can be a quality ( ``CV_IMWRITE_JPEG_QUALITY`` ) from 0 to 100 (the higher is the better). Default value is 95. + + * For PNG, it can be the compression level ( ``CV_IMWRITE_PNG_COMPRESSION`` ) from 0 to 9. A higher value means a smaller size and longer compression time. Default value is 3. + + * For PPM, PGM, or PBM, it can be a binary format flag ( ``CV_IMWRITE_PXM_BINARY`` ), 0 or 1. Default value is 1. + +The function ``imwrite`` saves the image to the specified file. The image format is chosen based on the ``filename`` extension (see +:ocv:func:`imread` for the list of extensions). Only 8-bit (or 16-bit unsigned (``CV_16U``) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function. If the format, depth or channel order is different, use +:ocv:func:`Mat::convertTo` , and +:ocv:func:`cvtColor` to convert it before saving. Or, use the universal XML I/O functions to save the image to XML or YAML format. + +It is possible to store PNG images with an alpha channel using this function. To do this, create 8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535. The sample below shows how to create such a BGRA image and store to PNG file. It also demonstrates how to set custom compression parameters :: + + #include + #include + #include + + using namespace cv; + using namespace std; + + void createAlphaMat(Mat &mat) + { + for (int i = 0; i < mat.rows; ++i) { + for (int j = 0; j < mat.cols; ++j) { + Vec4b& rgba = mat.at(i, j); + rgba[0] = UCHAR_MAX; + rgba[1] = saturate_cast((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); + rgba[2] = saturate_cast((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); + rgba[3] = saturate_cast(0.5 * (rgba[1] + rgba[2])); + } + } + } + + int main(int argv, char **argc) + { + // Create mat with alpha channel + Mat mat(480, 640, CV_8UC4); + createAlphaMat(mat); + + vector compression_params; + compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); + compression_params.push_back(9); + + try { + imwrite("alpha.png", mat, compression_params); + } + catch (runtime_error& ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what()); + return 1; + } + + fprintf(stdout, "Saved PNG file with alpha data.\n"); + return 0; + } + + +VideoCapture +------------ +.. ocv:class:: VideoCapture + +Class for video capturing from video files or cameras. +The class provides C++ API for capturing video from cameras or for reading video files. Here is how the class can be used: :: + + #include "opencv2/opencv.hpp" + + using namespace cv; + + int main(int, char**) + { + VideoCapture cap(0); // open the default camera + if(!cap.isOpened()) // check if we succeeded + return -1; + + Mat edges; + namedWindow("edges",1); + for(;;) + { + Mat frame; + cap >> frame; // get a new frame from camera + cvtColor(frame, edges, CV_BGR2GRAY); + GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); + Canny(edges, edges, 0, 30, 3); + imshow("edges", edges); + if(waitKey(30) >= 0) break; + } + // the camera will be deinitialized automatically in VideoCapture destructor + return 0; + } + + +.. note:: In C API the black-box structure ``CvCapture`` is used instead of ``VideoCapture``. + + +VideoCapture::VideoCapture +------------------------------ +VideoCapture constructors. + +.. ocv:function:: VideoCapture::VideoCapture() + +.. ocv:function:: VideoCapture::VideoCapture(const string& filename) + +.. ocv:function:: VideoCapture::VideoCapture(int device) + +.. ocv:pyfunction:: cv2.VideoCapture() -> +.. ocv:pyfunction:: cv2.VideoCapture(filename) -> +.. ocv:pyfunction:: cv2.VideoCapture(device) -> + +.. ocv:cfunction:: CvCapture* cvCaptureFromCAM( int device ) +.. ocv:pyoldfunction:: cv.CaptureFromCAM(index) -> CvCapture +.. ocv:cfunction:: CvCapture* cvCaptureFromFile( const char* filename ) +.. ocv:pyoldfunction:: cv.CaptureFromFile(filename) -> CvCapture + + :param filename: name of the opened video file + + :param device: id of the opened video capturing device (i.e. a camera index). If there is a single camera connected, just pass 0. + +.. note:: In C API, when you finished working with video, release ``CvCapture`` structure with ``cvReleaseCapture()``, or use ``Ptr`` that calls ``cvReleaseCapture()`` automatically in the destructor. + + +VideoCapture::open +--------------------- +Open video file or a capturing device for video capturing + +.. ocv:function:: bool VideoCapture::open(const string& filename) +.. ocv:function:: bool VideoCapture::open(int device) + +.. ocv:pyfunction:: cv2.VideoCapture.open(filename) -> retval +.. ocv:pyfunction:: cv2.VideoCapture.open(device) -> retval + + :param filename: name of the opened video file + + :param device: id of the opened video capturing device (i.e. a camera index). + +The methods first call :ocv:func:`VideoCapture::release` to close the already opened file or camera. + + +VideoCapture::isOpened +---------------------- +Returns true if video capturing has been initialized already. + +.. ocv:function:: bool VideoCapture::isOpened() + +.. ocv:pyfunction:: cv2.VideoCapture.isOpened() -> retval + +If the previous call to ``VideoCapture`` constructor or ``VideoCapture::open`` succeeded, the method returns true. + +VideoCapture::release +--------------------- +Closes video file or capturing device. + +.. ocv:function:: void VideoCapture::release() + +.. ocv:pyfunction:: cv2.VideoCapture.release() -> None + +.. ocv:cfunction:: void cvReleaseCapture(CvCapture** capture) + +The methods are automatically called by subsequent :ocv:func:`VideoCapture::open` and by ``VideoCapture`` destructor. + +The C function also deallocates memory and clears ``*capture`` pointer. + + +VideoCapture::grab +--------------------- +Grabs the next frame from video file or capturing device. + +.. ocv:function:: bool VideoCapture::grab() + +.. ocv:pyfunction:: cv2.VideoCapture.grab() -> retval + +.. ocv:cfunction:: int cvGrabFrame(CvCapture* capture) + +.. ocv:pyoldfunction:: cv.GrabFrame(capture) -> int + +The methods/functions grab the next frame from video file or camera and return true (non-zero) in the case of success. + +The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call ``VideoCapture::grab()`` for each camera and after that call the slower method ``VideoCapture::retrieve()`` to decode and get frame from each camera. This way the overhead on demosaicing or motion jpeg decompression etc. is eliminated and the retrieved frames from different cameras will be closer in time. + +Also, when a connected camera is multi-head (for example, a stereo camera or a Kinect device), the correct way of retrieving data from it is to call `VideoCapture::grab` first and then call :ocv:func:`VideoCapture::retrieve` one or more times with different values of the ``channel`` parameter. See http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/kinect_maps.cpp + + +VideoCapture::retrieve +---------------------- +Decodes and returns the grabbed video frame. + +.. ocv:function:: bool VideoCapture::retrieve(Mat& image, int channel=0) + +.. ocv:pyfunction:: cv2.VideoCapture.retrieve([image[, channel]]) -> retval, image + +.. ocv:cfunction:: IplImage* cvRetrieveFrame( CvCapture* capture, int streamIdx=0 ) + +.. ocv:pyoldfunction:: cv.RetrieveFrame(capture) -> image + +The methods/functions decode and return the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer. + +.. note:: OpenCV 1.x functions ``cvRetrieveFrame`` and ``cv.RetrieveFrame`` return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using :ocv:cfunc:`cvCloneImage` and then do whatever you want with the copy. + + +VideoCapture::read +---------------------- +Grabs, decodes and returns the next video frame. + +.. ocv:function:: VideoCapture& VideoCapture::operator >> (Mat& image) + +.. ocv:function:: bool VideoCapture::read(Mat& image) + +.. ocv:pyfunction:: cv2.VideoCapture.read([image]) -> retval, image + +.. ocv:cfunction:: IplImage* cvQueryFrame(CvCapture* capture) + +.. ocv:pyoldfunction:: cv.QueryFrame(capture) -> image + +The methods/functions combine :ocv:func:`VideoCapture::grab` and :ocv:func:`VideoCapture::retrieve` in one call. This is the most convenient method for reading video files or capturing data from decode and return the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer. + +.. note:: OpenCV 1.x functions ``cvRetrieveFrame`` and ``cv.RetrieveFrame`` return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using :ocv:cfunc:`cvCloneImage` and then do whatever you want with the copy. + + +VideoCapture::get +--------------------- +Returns the specified ``VideoCapture`` property + +.. ocv:function:: double VideoCapture::get(int propId) + +.. ocv:pyfunction:: cv2.VideoCapture.get(propId) -> retval + +.. ocv:cfunction:: double cvGetCaptureProperty( CvCapture* capture, int property_id ) + +.. ocv:pyoldfunction:: cv.GetCaptureProperty(capture, property_id) -> float + + + :param propId: Property identifier. It can be one of the following: + + * **CV_CAP_PROP_POS_MSEC** Current position of the video file in milliseconds or video capture timestamp. + + * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next. + + * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file: 0 - start of the film, 1 - end of the film. + + * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream. + + * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream. + + * **CV_CAP_PROP_FPS** Frame rate. + + * **CV_CAP_PROP_FOURCC** 4-character code of codec. + + * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file. + + * **CV_CAP_PROP_FORMAT** Format of the Mat objects returned by ``retrieve()`` . + + * **CV_CAP_PROP_MODE** Backend-specific value indicating the current capture mode. + + * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras). + + * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras). + + * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras). + + * **CV_CAP_PROP_HUE** Hue of the image (only for cameras). + + * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras). + + * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras). + + * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB. + + * **CV_CAP_PROP_WHITE_BALANCE** Currently not supported + + * **CV_CAP_PROP_RECTIFICATION** Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently) + + +**Note**: When querying a property that is not supported by the backend used by the ``VideoCapture`` class, value 0 is returned. + +VideoCapture::set +--------------------- +Sets a property in the ``VideoCapture``. + +.. ocv:function:: bool VideoCapture::set( int propId, double value ) + +.. ocv:pyfunction:: cv2.VideoCapture.set(propId, value) -> retval + +.. ocv:cfunction:: int cvSetCaptureProperty( CvCapture* capture, int property_id, double value ) + +.. ocv:pyoldfunction:: cv.SetCaptureProperty(capture, property_id, value) -> retval + + :param propId: Property identifier. It can be one of the following: + + * **CV_CAP_PROP_POS_MSEC** Current position of the video file in milliseconds. + + * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next. + + * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file: 0 - start of the film, 1 - end of the film. + + * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream. + + * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream. + + * **CV_CAP_PROP_FPS** Frame rate. + + * **CV_CAP_PROP_FOURCC** 4-character code of codec. + + * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file. + + * **CV_CAP_PROP_FORMAT** Format of the Mat objects returned by ``retrieve()`` . + + * **CV_CAP_PROP_MODE** Backend-specific value indicating the current capture mode. + + * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras). + + * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras). + + * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras). + + * **CV_CAP_PROP_HUE** Hue of the image (only for cameras). + + * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras). + + * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras). + + * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB. + + * **CV_CAP_PROP_WHITE_BALANCE** Currently unsupported + + * **CV_CAP_PROP_RECTIFICATION** Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently) + + :param value: Value of the property. + + + +VideoWriter +----------- +.. ocv:class:: VideoWriter + +Video writer class. + + + +VideoWriter::VideoWriter +------------------------ +VideoWriter constructors + +.. ocv:function:: VideoWriter::VideoWriter() + +.. ocv:function:: VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true) + +.. ocv:pyfunction:: cv2.VideoWriter([filename, fourcc, fps, frameSize[, isColor]]) -> + +.. ocv:cfunction:: CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 ) +.. ocv:pyoldfunction:: cv.CreateVideoWriter(filename, fourcc, fps, frame_size, is_color=true) -> CvVideoWriter + +.. ocv:pyfunction:: cv2.VideoWriter.isOpened() -> retval +.. ocv:pyfunction:: cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor]) -> retval +.. ocv:pyfunction:: cv2.VideoWriter.write(image) -> None + + :param filename: Name of the output video file. + + :param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M,'1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. List of codes can be obtained at `Video Codecs by FOURCC `_ page. + + :param fps: Framerate of the created video stream. + + :param frameSize: Size of the video frames. + + :param isColor: If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only). + +The constructors/functions initialize video writers. On Linux FFMPEG is used to write videos; on Windows FFMPEG or VFW is used; on MacOSX QTKit is used. + + + +ReleaseVideoWriter +------------------ +Releases the AVI writer. + +.. ocv:cfunction:: void cvReleaseVideoWriter( CvVideoWriter** writer ) + +The function should be called after you finished using ``CvVideoWriter`` opened with :ocv:cfunc:`CreateVideoWriter`. + + +VideoWriter::open +----------------- +Initializes or reinitializes video writer. + +.. ocv:function:: bool VideoWriter::open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true) + +.. ocv:pyfunction:: cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor]) -> retval + +The method opens video writer. Parameters are the same as in the constructor :ocv:func:`VideoWriter::VideoWriter`. + + +VideoWriter::isOpened +--------------------- +Returns true if video writer has been successfully initialized. + +.. ocv:function:: bool VideoWriter::isOpened() + +.. ocv:pyfunction:: cv2.VideoWriter.isOpened() -> retval + + +VideoWriter::write +------------------ +Writes the next video frame + +.. ocv:function:: VideoWriter& VideoWriter::operator << (const Mat& image) + +.. ocv:function:: void VideoWriter::write(const Mat& image) + +.. ocv:pyfunction:: cv2.VideoWriter.write(image) -> None + +.. ocv:cfunction:: int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) +.. ocv:pyoldfunction:: cv.WriteFrame(writer, image)->int + + :param writer: Video writer structure (OpenCV 1.x API) + + :param image: The written frame + +The functions/methods write the specified image to video file. It must have the same size as has been specified when opening the video writer. + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/doc/user_interface.rst diffimg-2.0.0/3rdparty/opencv/highgui/doc/user_interface.rst --- diffimg-1.5.0/3rdparty/opencv/highgui/doc/user_interface.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/doc/user_interface.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,258 @@ +User Interface +============== + +.. highlight:: cpp + +createTrackbar +------------------ +Creates a trackbar and attaches it to the specified window. + +.. ocv:function:: int createTrackbar( const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0) + +.. ocv:cfunction:: int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change=NULL ) + +.. ocv:pyoldfunction:: cv.CreateTrackbar(trackbarName, windowName, value, count, onChange) -> None + + :param trackbarname: Name of the created trackbar. + + :param winname: Name of the window that will be used as a parent of the created trackbar. + + :param value: Optional pointer to an integer variable whose value reflects the position of the slider. Upon creation, the slider position is defined by this variable. + + :param count: Maximal position of the slider. The minimal position is always 0. + + :param onChange: Pointer to the function to be called every time the slider changes position. This function should be prototyped as ``void Foo(int,void*);`` , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only ``value`` is updated. + + :param userdata: User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables. + +The function ``createTrackbar`` creates a trackbar (a slider or range control) with the specified name and range, assigns a variable ``value`` to be a position synchronized with the trackbar and specifies the callback function ``onChange`` to be called on the trackbar position change. The created trackbar is displayed in the specified window ``winname``. + +.. note:: + + **[Qt Backend Only]** ``winname`` can be empty (or NULL) if the trackbar should be attached to the control panel. + +Clicking the label of each trackbar enables editing the trackbar values manually. + +getTrackbarPos +------------------ +Returns the trackbar position. + +.. ocv:function:: int getTrackbarPos( const string& trackbarname, const string& winname ) + +.. ocv:pyfunction:: cv2.getTrackbarPos(trackbarname, winname) -> retval + +.. ocv:cfunction:: int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) + +.. ocv:pyoldfunction:: cv.GetTrackbarPos(trackbarName, windowName) -> retval + + :param trackbarname: Name of the trackbar. + + :param winname: Name of the window that is the parent of the trackbar. + +The function returns the current position of the specified trackbar. + +.. note:: + + **[Qt Backend Only]** ``winname`` can be empty (or NULL) if the trackbar is attached to the control panel. + +imshow +---------- +Displays an image in the specified window. + +.. ocv:function:: void imshow( const string& winname, InputArray mat ) + +.. ocv:pyfunction:: cv2.imshow(winname, mat) -> None + +.. ocv:cfunction:: void cvShowImage( const char* name, const CvArr* image ) + +.. ocv:pyoldfunction:: cv.ShowImage(name, image) -> None + + :param winname: Name of the window. + + :param image: Image to be shown. + +The function ``imshow`` displays an image in the specified window. If the window was created with the ``CV_WINDOW_AUTOSIZE`` flag, the image is shown with its original size. Otherwise, the image is scaled to fit the window. The function may scale the image, depending on its depth: + + * If the image is 8-bit unsigned, it is displayed as is. + + * If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255]. + + * If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255]. + + +namedWindow +--------------- +Creates a window. + +.. ocv:function:: void namedWindow( const string& winname, int flags=WINDOW_AUTOSIZE ) + +.. ocv:pyfunction:: cv2.namedWindow(winname[, flags]) -> None + +.. ocv:cfunction:: int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE ) + +.. ocv:pyoldfunction:: cv.NamedWindow(name, flags=CV_WINDOW_AUTOSIZE)-> None + + :param name: Name of the window in the window caption that may be used as a window identifier. + + :param flags: Flags of the window. Currently the only supported flag is ``CV_WINDOW_AUTOSIZE`` . If this is set, the window size is automatically adjusted to fit the displayed image (see :ocv:func:`imshow` ), and you cannot change the window size manually. + +The function ``namedWindow`` creates a window that can be used as a placeholder for images and trackbars. Created windows are referred to by their names. + +If a window with the same name already exists, the function does nothing. + +You can call :ocv:func:`destroyWindow` or :ocv:func:`destroyAllWindows` to close the window and de-allocate any associated memory usage. For a simple program, you do not really have to call these functions because all the resources and windows of the application are closed automatically by the operating system upon exit. + +.. note:: + + Qt backend supports additional flags: + + * **CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE:** ``CV_WINDOW_NORMAL`` enables you to resize the window, whereas ``CV_WINDOW_AUTOSIZE`` adjusts automatically the window size to fit the displayed image (see :ocv:func:`imshow` ), and you cannot change the window size manually. + + * **CV_WINDOW_FREERATIO or CV_WINDOW_KEEPRATIO:** ``CV_WINDOW_FREERATIO`` adjusts the image with no respect to its ratio, whereas ``CV_WINDOW_KEEPRATIO`` keeps the image ratio. + + * **CV_GUI_NORMAL or CV_GUI_EXPANDED:** ``CV_GUI_NORMAL`` is the old way to draw the window without statusbar and toolbar, whereas ``CV_GUI_EXPANDED`` is a new enhanced GUI. + + By default, ``flags == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED`` + + +destroyWindow +------------- +Destroys a window. + +.. ocv:function:: void destroyWindow( const string& winname ) + +.. ocv:pyfunction:: cv2.destroyWindow(winname) -> None + +.. ocv:cfunction:: void cvDestroyWindow( const char* name ) + +.. ocv:pyoldfunction:: cv.DestroyWindow(name)-> None + + :param winname: Name of the window to be destroyed. + +The function ``destroyWindow`` destroys the window with the given name. + + +destroyAllWindows +----------------- +Destroys all of the HighGUI windows. + +.. ocv:function:: void destroyAllWindows() + +.. ocv:pyfunction:: cv2.destroyAllWindows() -> None + +.. ocv:cfunction:: void cvDestroyAllWindows() + +.. ocv:pyoldfunction:: cv.DestroyAllWindows()-> None + +The function ``destroyAllWindows`` destroys all of the opened HighGUI windows. + + +MoveWindow +---------- +Moves window to the specified position + +.. ocv:function:: void moveWindow( const string& winname, int x, int y ) + +.. ocv:pyfunction:: cv2.moveWindow(winname, x, y) -> None + +.. ocv:cfunction:: void cvMoveWindow( const char* name, int x, int y ) + +.. ocv:pyoldfunction:: cv.MoveWindow(name, x, y)-> None + + :param winname: Window name + + :param x: The new x-coordinate of the window + + :param y: The new y-coordinate of the window + + +ResizeWindow +------------ +Resizes window to the specified size + +.. ocv:function:: void resizeWindow( const string& winname, int width, int height ) + +.. ocv:pyfunction:: cv2.resizeWindow(winname, width, height) -> None + +.. ocv:cfunction:: void cvResizeWindow( const char* name, int width, int height ) + +.. ocv:pyoldfunction:: cv.ResizeWindow(name, width, height)-> None + + :param winname: Window name + + :param width: The new window width + + :param height: The new window height + +.. note:: + + * The specified window size is for the image area. Toolbars are not counted. + + * Only windows created without CV_WINDOW_AUTOSIZE flag can be resized. + + +SetMouseCallback +---------------- +Sets mouse handler for the specified window + +.. ocv:function:: void setMouseCallback( const string& winname, MouseCallback onMouse, void* userdata=0 ) + +.. ocv:cfunction:: void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param=NULL ) + +.. ocv:pyoldfunction:: cv.SetMouseCallback(windowName, onMouse, param=None) -> None + + :param winname: Window name + + :param onMouse: Mouse callback. See OpenCV samples, such as http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/ffilldemo.cpp, on how to specify and use the callback. + + :param userdata: The optional parameter passed to the callback. + + +setTrackbarPos +------------------ +Sets the trackbar position. + +.. ocv:function:: void setTrackbarPos( const string& trackbarname, const string& winname, int pos ) + +.. ocv:pyfunction:: cv2.setTrackbarPos(trackbarname, winname, pos) -> None + +.. ocv:cfunction:: void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) + +.. ocv:pyoldfunction:: cv.SetTrackbarPos(trackbarName, windowName, pos)-> None + + :param trackbarname: Name of the trackbar. + + :param winname: Name of the window that is the parent of trackbar. + + :param pos: New position. + +The function sets the position of the specified trackbar in the specified window. + +.. note:: + + **[Qt Backend Only]** ``winname`` can be empty (or NULL) if the trackbar is attached to the control panel. + +waitKey +----------- +Waits for a pressed key. + +.. ocv:function:: int waitKey(int delay=0) + +.. ocv:pyfunction:: cv2.waitKey([delay]) -> retval + +.. ocv:cfunction:: int cvWaitKey( int delay=0 ) + +.. ocv:pyoldfunction:: cv.WaitKey(delay=0)-> int + + :param delay: Delay in milliseconds. 0 is the special value that means "forever". + +The function ``waitKey`` waits for a key event infinitely (when +:math:`\texttt{delay}\leq 0` ) or for ``delay`` milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the function will not wait exactly ``delay`` ms, it will wait at least ``delay`` ms, depending on what else is running on your computer at that time. It returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed. + +.. note:: + + This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing. + +.. note:: + + The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active. diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/highgui.pro diffimg-2.0.0/3rdparty/opencv/highgui/highgui.pro --- diffimg-1.5.0/3rdparty/opencv/highgui/highgui.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/highgui.pro 2013-05-16 14:11:48.000000000 +0000 @@ -0,0 +1,48 @@ + + +OPENCV_ROOT = $${PWD}/.. + +TEMPLATE = lib +TARGET = opencv_highgui + +#DESTDIR = $${QWT_ROOT}/lib + +CONFIG += staticlib + +HEADERS += include/opencv2/highgui/*.hpp \ + src/grfmt*.hpp \ + src/bitstrm.hpp \ + src/precomp.hpp \ + src/utils.hpp + +# src/cap_ffmpeg_impl.hpp + + +SOURCES += src/grfmt*.cpp \ + src/cap.cpp \ + src/cap_images.cpp \ + src/loadsave.cpp \ + src/bitstrm.cpp \ + src/precomp.cpp \ + src/utils.cpp \ + src/window.cpp + +# src/cap_ffmpeg.cpp + + + +INCLUDEPATH += ./include ./ ../ \ + ../core/include \ + ../imgproc/include \ + ../3rdparty/libtiff \ + ../3rdparty/libpng \ + ../3rdparty/ \ + ../3rdparty/libjasper \ + ../3rdparty/openexr \ + ../3rdparty/openexr/IlmImf \ + ../3rdparty/openexr/Imath \ + ../3rdparty/openexr/Iex \ + ../3rdparty/openexr/Half \ + ../3rdparty/libjpeg \ + ../3rdparty/zlib + \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/cap_ios.h diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/cap_ios.h --- diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/cap_ios.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/cap_ios.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,163 @@ +/* + * cap_ios.h + * For iOS video I/O + * by Eduard Feicho on 29/07/12 + * Copyright 2012. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import +#import +#import +#include "opencv2/core/core.hpp" + +/////////////////////////////////////// CvAbstractCamera ///////////////////////////////////// + +@class CvAbstractCamera; + +@interface CvAbstractCamera : NSObject +{ + AVCaptureSession* captureSession; + AVCaptureConnection* videoCaptureConnection; + AVCaptureVideoPreviewLayer *captureVideoPreviewLayer; + + UIDeviceOrientation currentDeviceOrientation; + + BOOL cameraAvailable; + BOOL captureSessionLoaded; + BOOL running; + BOOL useAVCaptureVideoPreviewLayer; + + AVCaptureDevicePosition defaultAVCaptureDevicePosition; + AVCaptureVideoOrientation defaultAVCaptureVideoOrientation; + NSString *const defaultAVCaptureSessionPreset; + + int defaultFPS; + + UIView* parentView; + + int imageWidth; + int imageHeight; +} + +@property (nonatomic, retain) AVCaptureSession* captureSession; +@property (nonatomic, retain) AVCaptureConnection* videoCaptureConnection; + +@property (nonatomic, readonly) BOOL running; +@property (nonatomic, readonly) BOOL captureSessionLoaded; + +@property (nonatomic, assign) int defaultFPS; +@property (nonatomic, assign) AVCaptureDevicePosition defaultAVCaptureDevicePosition; +@property (nonatomic, assign) AVCaptureVideoOrientation defaultAVCaptureVideoOrientation; +@property (nonatomic, assign) BOOL useAVCaptureVideoPreviewLayer; +@property (nonatomic, strong) NSString *const defaultAVCaptureSessionPreset; + +@property (nonatomic, assign) int imageWidth; +@property (nonatomic, assign) int imageHeight; + +@property (nonatomic, retain) UIView* parentView; + +- (void)start; +- (void)stop; +- (void)switchCameras; + +- (id)initWithParentView:(UIView*)parent; + +- (void)createCaptureOutput; +- (void)createVideoPreviewLayer; +- (void)updateOrientation; + + +@end + +///////////////////////////////// CvVideoCamera /////////////////////////////////////////// + +@class CvVideoCamera; + +@protocol CvVideoCameraDelegate + +#ifdef __cplusplus +// delegate method for processing image frames +- (void)processImage:(cv::Mat&)image; +#endif + +@end + +@interface CvVideoCamera : CvAbstractCamera +{ + AVCaptureVideoDataOutput *videoDataOutput; + + dispatch_queue_t videoDataOutputQueue; + CALayer *customPreviewLayer; + + BOOL grayscaleMode; + + BOOL recordVideo; + AVAssetWriterInput* recordAssetWriterInput; + AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; + AVAssetWriter* recordAssetWriter; + + CMTime lastSampleTime; + +} + +@property (nonatomic, assign) id delegate; +@property (nonatomic, assign) BOOL grayscaleMode; + +@property (nonatomic, assign) BOOL recordVideo; +@property (nonatomic, retain) AVAssetWriterInput* recordAssetWriterInput; +@property (nonatomic, retain) AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; +@property (nonatomic, retain) AVAssetWriter* recordAssetWriter; + +- (void)adjustLayoutToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; +- (void)layoutPreviewLayer; +- (void)saveVideo; +- (NSURL *)videoFileURL; + + +@end + +///////////////////////////////// CvPhotoCamera /////////////////////////////////////////// + +@class CvPhotoCamera; + +@protocol CvPhotoCameraDelegate + +- (void)photoCamera:(CvPhotoCamera*)photoCamera capturedImage:(UIImage *)image; +- (void)photoCameraCancel:(CvPhotoCamera*)photoCamera; + +@end + +@interface CvPhotoCamera : CvAbstractCamera +{ + AVCaptureStillImageOutput *stillImageOutput; +} + +@property (nonatomic, assign) id delegate; + +- (void)takePicture; + +@end diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui.hpp diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,255 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_HIGHGUI_HPP__ +#define __OPENCV_HIGHGUI_HPP__ + +#include "opencv2/core/core.hpp" +#include "opencv2/highgui/highgui_c.h" + +#ifdef __cplusplus + +struct CvCapture; +struct CvVideoWriter; + +namespace cv +{ + +enum { + // Flags for namedWindow + WINDOW_NORMAL = CV_WINDOW_NORMAL, // the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size + WINDOW_AUTOSIZE = CV_WINDOW_AUTOSIZE, // the user cannot resize the window, the size is constrainted by the image displayed + WINDOW_OPENGL = CV_WINDOW_OPENGL, // window with opengl support + + // Flags for set / getWindowProperty + WND_PROP_FULLSCREEN = CV_WND_PROP_FULLSCREEN, // fullscreen property + WND_PROP_AUTOSIZE = CV_WND_PROP_AUTOSIZE, // autosize property + WND_PROP_ASPECT_RATIO = CV_WND_PROP_ASPECTRATIO, // window's aspect ration + WND_PROP_OPENGL = CV_WND_PROP_OPENGL // opengl support +}; + +CV_EXPORTS_W void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE); +CV_EXPORTS_W void destroyWindow(const string& winname); +CV_EXPORTS_W void destroyAllWindows(); + +CV_EXPORTS_W int startWindowThread(); + +CV_EXPORTS_W int waitKey(int delay = 0); + +CV_EXPORTS_W void imshow(const string& winname, InputArray mat); + +CV_EXPORTS_W void resizeWindow(const string& winname, int width, int height); +CV_EXPORTS_W void moveWindow(const string& winname, int x, int y); + +CV_EXPORTS_W void setWindowProperty(const string& winname, int prop_id, double prop_value);//YV +CV_EXPORTS_W double getWindowProperty(const string& winname, int prop_id);//YV + +enum +{ + EVENT_MOUSEMOVE =0, + EVENT_LBUTTONDOWN =1, + EVENT_RBUTTONDOWN =2, + EVENT_MBUTTONDOWN =3, + EVENT_LBUTTONUP =4, + EVENT_RBUTTONUP =5, + EVENT_MBUTTONUP =6, + EVENT_LBUTTONDBLCLK =7, + EVENT_RBUTTONDBLCLK =8, + EVENT_MBUTTONDBLCLK =9 +}; + +enum +{ + EVENT_FLAG_LBUTTON =1, + EVENT_FLAG_RBUTTON =2, + EVENT_FLAG_MBUTTON =4, + EVENT_FLAG_CTRLKEY =8, + EVENT_FLAG_SHIFTKEY =16, + EVENT_FLAG_ALTKEY =32 +}; + +typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata); + +//! assigns callback for mouse events +CV_EXPORTS void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0); + + +typedef void (CV_CDECL *TrackbarCallback)(int pos, void* userdata); + +CV_EXPORTS int createTrackbar(const string& trackbarname, const string& winname, + int* value, int count, + TrackbarCallback onChange = 0, + void* userdata = 0); + +CV_EXPORTS_W int getTrackbarPos(const string& trackbarname, const string& winname); +CV_EXPORTS_W void setTrackbarPos(const string& trackbarname, const string& winname, int pos); + +// OpenGL support + +typedef void (*OpenGlDrawCallback)(void* userdata); +CV_EXPORTS void setOpenGlDrawCallback(const string& winname, OpenGlDrawCallback onOpenGlDraw, void* userdata = 0); + +CV_EXPORTS void setOpenGlContext(const string& winname); + +CV_EXPORTS void updateWindow(const string& winname); + +// < Deperecated +CV_EXPORTS void pointCloudShow(const string& winname, const GlCamera& camera, const GlArrays& arr); +CV_EXPORTS void pointCloudShow(const string& winname, const GlCamera& camera, InputArray points, InputArray colors = noArray()); +// > + +//Only for Qt + +CV_EXPORTS CvFont fontQt(const string& nameFont, int pointSize=-1, + Scalar color=Scalar::all(0), int weight=CV_FONT_NORMAL, + int style=CV_STYLE_NORMAL, int spacing=0); +CV_EXPORTS void addText( const Mat& img, const string& text, Point org, CvFont font); + +CV_EXPORTS void displayOverlay(const string& winname, const string& text, int delayms CV_DEFAULT(0)); +CV_EXPORTS void displayStatusBar(const string& winname, const string& text, int delayms CV_DEFAULT(0)); + +CV_EXPORTS void saveWindowParameters(const string& windowName); +CV_EXPORTS void loadWindowParameters(const string& windowName); +CV_EXPORTS int startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]); +CV_EXPORTS void stopLoop(); + +typedef void (CV_CDECL *ButtonCallback)(int state, void* userdata); +CV_EXPORTS int createButton( const string& bar_name, ButtonCallback on_change, + void* userdata=NULL, int type=CV_PUSH_BUTTON, + bool initial_button_state=0); + +//------------------------- + +enum +{ + // 8bit, color or not + IMREAD_UNCHANGED =-1, + // 8bit, gray + IMREAD_GRAYSCALE =0, + // ?, color + IMREAD_COLOR =1, + // any depth, ? + IMREAD_ANYDEPTH =2, + // ?, any color + IMREAD_ANYCOLOR =4 +}; + +enum +{ + IMWRITE_JPEG_QUALITY =1, + IMWRITE_PNG_COMPRESSION =16, + IMWRITE_PNG_STRATEGY =17, + IMWRITE_PNG_BILEVEL =18, + IMWRITE_PNG_STRATEGY_DEFAULT =0, + IMWRITE_PNG_STRATEGY_FILTERED =1, + IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2, + IMWRITE_PNG_STRATEGY_RLE =3, + IMWRITE_PNG_STRATEGY_FIXED =4, + IMWRITE_PXM_BINARY =32 +}; + +CV_EXPORTS_W Mat imread( const string& filename, int flags=1 ); +CV_EXPORTS_W bool imwrite( const string& filename, InputArray img, + const vector& params=vector()); +CV_EXPORTS_W Mat imdecode( InputArray buf, int flags ); +CV_EXPORTS Mat imdecode( InputArray buf, int flags, Mat* dst ); +CV_EXPORTS_W bool imencode( const string& ext, InputArray img, + CV_OUT vector& buf, + const vector& params=vector()); + +#ifndef CV_NO_VIDEO_CAPTURE_CPP_API + +template<> void CV_EXPORTS Ptr::delete_obj(); +template<> void CV_EXPORTS Ptr::delete_obj(); + +class CV_EXPORTS_W VideoCapture +{ +public: + CV_WRAP VideoCapture(); + CV_WRAP VideoCapture(const string& filename); + CV_WRAP VideoCapture(int device); + + virtual ~VideoCapture(); + CV_WRAP virtual bool open(const string& filename); + CV_WRAP virtual bool open(int device); + CV_WRAP virtual bool isOpened() const; + CV_WRAP virtual void release(); + + CV_WRAP virtual bool grab(); + CV_WRAP virtual bool retrieve(CV_OUT Mat& image, int channel=0); + virtual VideoCapture& operator >> (CV_OUT Mat& image); + CV_WRAP virtual bool read(CV_OUT Mat& image); + + CV_WRAP virtual bool set(int propId, double value); + CV_WRAP virtual double get(int propId); + +protected: + Ptr cap; +}; + + +class CV_EXPORTS_W VideoWriter +{ +public: + CV_WRAP VideoWriter(); + CV_WRAP VideoWriter(const string& filename, int fourcc, double fps, + Size frameSize, bool isColor=true); + + virtual ~VideoWriter(); + CV_WRAP virtual bool open(const string& filename, int fourcc, double fps, + Size frameSize, bool isColor=true); + CV_WRAP virtual bool isOpened() const; + CV_WRAP virtual void release(); + virtual VideoWriter& operator << (const Mat& image); + CV_WRAP virtual void write(const Mat& image); + +protected: + Ptr writer; +}; + +#endif + +} + +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui_c.h diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui_c.h --- diffimg-1.5.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui_c.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/include/opencv2/highgui/highgui_c.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,620 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_HIGHGUI_H__ +#define __OPENCV_HIGHGUI_H__ + +#include "opencv2/core/core_c.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/****************************************************************************************\ +* Basic GUI functions * +\****************************************************************************************/ +//YV +//-----------New for Qt +/* For font */ +enum { CV_FONT_LIGHT = 25,//QFont::Light, + CV_FONT_NORMAL = 50,//QFont::Normal, + CV_FONT_DEMIBOLD = 63,//QFont::DemiBold, + CV_FONT_BOLD = 75,//QFont::Bold, + CV_FONT_BLACK = 87 //QFont::Black +}; + +enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal, + CV_STYLE_ITALIC = 1,//QFont::StyleItalic, + CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique +}; +/* ---------*/ + +//for color cvScalar(blue_component, green_component, red\_component[, alpha_component]) +//and alpha= 0 <-> 0xFF (not transparent <-> transparent) +CVAPI(CvFont) cvFontQt(const char* nameFont, int pointSize CV_DEFAULT(-1), CvScalar color CV_DEFAULT(cvScalarAll(0)), int weight CV_DEFAULT(CV_FONT_NORMAL), int style CV_DEFAULT(CV_STYLE_NORMAL), int spacing CV_DEFAULT(0)); + +CVAPI(void) cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont *arg2); + +CVAPI(void) cvDisplayOverlay(const char* name, const char* text, int delayms CV_DEFAULT(0)); +CVAPI(void) cvDisplayStatusBar(const char* name, const char* text, int delayms CV_DEFAULT(0)); + +CVAPI(void) cvSaveWindowParameters(const char* name); +CVAPI(void) cvLoadWindowParameters(const char* name); +CVAPI(int) cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]); +CVAPI(void) cvStopLoop( void ); + +typedef void (CV_CDECL *CvButtonCallback)(int state, void* userdata); +enum {CV_PUSH_BUTTON = 0, CV_CHECKBOX = 1, CV_RADIOBOX = 2}; +CVAPI(int) cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0)); +//---------------------- + + +/* this function is used to set some external parameters in case of X Window */ +CVAPI(int) cvInitSystem( int argc, char** argv ); + +CVAPI(int) cvStartWindowThread( void ); + +// --------- YV --------- +enum +{ + //These 3 flags are used by cvSet/GetWindowProperty + CV_WND_PROP_FULLSCREEN = 0, //to change/get window's fullscreen property + CV_WND_PROP_AUTOSIZE = 1, //to change/get window's autosize property + CV_WND_PROP_ASPECTRATIO= 2, //to change/get window's aspectratio property + CV_WND_PROP_OPENGL = 3, //to change/get window's opengl support + + //These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_NORMAL = 0x00000000, //the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size + CV_WINDOW_AUTOSIZE = 0x00000001, //the user cannot resize the window, the size is constrainted by the image displayed + CV_WINDOW_OPENGL = 0x00001000, //window with opengl support + + //Those flags are only for Qt + CV_GUI_EXPANDED = 0x00000000, //status bar and tool bar + CV_GUI_NORMAL = 0x00000010, //old fashious way + + //These 3 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_FULLSCREEN = 1,//change the window to fullscreen + CV_WINDOW_FREERATIO = 0x00000100,//the image expends as much as it can (no ratio constraint) + CV_WINDOW_KEEPRATIO = 0x00000000//the ration image is respected. +}; + +/* create window */ +CVAPI(int) cvNamedWindow( const char* name, int flags CV_DEFAULT(CV_WINDOW_AUTOSIZE) ); + +/* Set and Get Property of the window */ +CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value); +CVAPI(double) cvGetWindowProperty(const char* name, int prop_id); + +/* display image within window (highgui windows remember their content) */ +CVAPI(void) cvShowImage( const char* name, const CvArr* image ); + +/* resize/move window */ +CVAPI(void) cvResizeWindow( const char* name, int width, int height ); +CVAPI(void) cvMoveWindow( const char* name, int x, int y ); + + +/* destroy window and all the trackers associated with it */ +CVAPI(void) cvDestroyWindow( const char* name ); + +CVAPI(void) cvDestroyAllWindows(void); + +/* get native window handle (HWND in case of Win32 and Widget in case of X Window) */ +CVAPI(void*) cvGetWindowHandle( const char* name ); + +/* get name of highgui window given its native handle */ +CVAPI(const char*) cvGetWindowName( void* window_handle ); + + +typedef void (CV_CDECL *CvTrackbarCallback)(int pos); + +/* create trackbar and display it on top of given window, set callback */ +CVAPI(int) cvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL)); + +typedef void (CV_CDECL *CvTrackbarCallback2)(int pos, void* userdata); + +CVAPI(int) cvCreateTrackbar2( const char* trackbar_name, const char* window_name, + int* value, int count, CvTrackbarCallback2 on_change, + void* userdata CV_DEFAULT(0)); + +/* retrieve or set trackbar position */ +CVAPI(int) cvGetTrackbarPos( const char* trackbar_name, const char* window_name ); +CVAPI(void) cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ); + +enum +{ + CV_EVENT_MOUSEMOVE =0, + CV_EVENT_LBUTTONDOWN =1, + CV_EVENT_RBUTTONDOWN =2, + CV_EVENT_MBUTTONDOWN =3, + CV_EVENT_LBUTTONUP =4, + CV_EVENT_RBUTTONUP =5, + CV_EVENT_MBUTTONUP =6, + CV_EVENT_LBUTTONDBLCLK =7, + CV_EVENT_RBUTTONDBLCLK =8, + CV_EVENT_MBUTTONDBLCLK =9 +}; + +enum +{ + CV_EVENT_FLAG_LBUTTON =1, + CV_EVENT_FLAG_RBUTTON =2, + CV_EVENT_FLAG_MBUTTON =4, + CV_EVENT_FLAG_CTRLKEY =8, + CV_EVENT_FLAG_SHIFTKEY =16, + CV_EVENT_FLAG_ALTKEY =32 +}; + +typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param); + +/* assign callback for mouse events */ +CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, + void* param CV_DEFAULT(NULL)); + +enum +{ +/* 8bit, color or not */ + CV_LOAD_IMAGE_UNCHANGED =-1, +/* 8bit, gray */ + CV_LOAD_IMAGE_GRAYSCALE =0, +/* ?, color */ + CV_LOAD_IMAGE_COLOR =1, +/* any depth, ? */ + CV_LOAD_IMAGE_ANYDEPTH =2, +/* ?, any color */ + CV_LOAD_IMAGE_ANYCOLOR =4 +}; + +/* load image from file + iscolor can be a combination of above flags where CV_LOAD_IMAGE_UNCHANGED + overrides the other flags + using CV_LOAD_IMAGE_ANYCOLOR alone is equivalent to CV_LOAD_IMAGE_UNCHANGED + unless CV_LOAD_IMAGE_ANYDEPTH is specified images are converted to 8bit +*/ +CVAPI(IplImage*) cvLoadImage( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); +CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); + +enum +{ + CV_IMWRITE_JPEG_QUALITY =1, + CV_IMWRITE_PNG_COMPRESSION =16, + CV_IMWRITE_PNG_STRATEGY =17, + CV_IMWRITE_PNG_BILEVEL =18, + CV_IMWRITE_PNG_STRATEGY_DEFAULT =0, + CV_IMWRITE_PNG_STRATEGY_FILTERED =1, + CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2, + CV_IMWRITE_PNG_STRATEGY_RLE =3, + CV_IMWRITE_PNG_STRATEGY_FIXED =4, + CV_IMWRITE_PXM_BINARY =32 +}; + +/* save image to file */ +CVAPI(int) cvSaveImage( const char* filename, const CvArr* image, + const int* params CV_DEFAULT(0) ); + +/* decode image stored in the buffer */ +CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); +CVAPI(CvMat*) cvDecodeImageM( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); + +/* encode image and store the result as a byte vector (single-row 8uC1 matrix) */ +CVAPI(CvMat*) cvEncodeImage( const char* ext, const CvArr* image, + const int* params CV_DEFAULT(0) ); + +enum +{ + CV_CVTIMG_FLIP =1, + CV_CVTIMG_SWAP_RB =2 +}; + +/* utility function: convert one image to another with optional vertical flip */ +CVAPI(void) cvConvertImage( const CvArr* src, CvArr* dst, int flags CV_DEFAULT(0)); + +/* wait for key event infinitely (delay<=0) or for "delay" milliseconds */ +CVAPI(int) cvWaitKey(int delay CV_DEFAULT(0)); + +// OpenGL support + +typedef void (CV_CDECL *CvOpenGlDrawCallback)(void* userdata); +CVAPI(void) cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata CV_DEFAULT(NULL)); + +CVAPI(void) cvSetOpenGlContext(const char* window_name); +CVAPI(void) cvUpdateWindow(const char* window_name); + + +/****************************************************************************************\ +* Working with Video Files and Cameras * +\****************************************************************************************/ + +/* "black box" capture structure */ +typedef struct CvCapture CvCapture; + +/* start capturing frames from video file */ +CVAPI(CvCapture*) cvCreateFileCapture( const char* filename ); + +enum +{ + CV_CAP_ANY =0, // autodetect + + CV_CAP_MIL =100, // MIL proprietary drivers + + CV_CAP_VFW =200, // platform native + CV_CAP_V4L =200, + CV_CAP_V4L2 =200, + + CV_CAP_FIREWARE =300, // IEEE 1394 drivers + CV_CAP_FIREWIRE =300, + CV_CAP_IEEE1394 =300, + CV_CAP_DC1394 =300, + CV_CAP_CMU1394 =300, + + CV_CAP_STEREO =400, // TYZX proprietary drivers + CV_CAP_TYZX =400, + CV_TYZX_LEFT =400, + CV_TYZX_RIGHT =401, + CV_TYZX_COLOR =402, + CV_TYZX_Z =403, + + CV_CAP_QT =500, // QuickTime + + CV_CAP_UNICAP =600, // Unicap drivers + + CV_CAP_DSHOW =700, // DirectShow (via videoInput) + CV_CAP_MSMF =1400, // Microsoft Media Foundation (via videoInput) + + CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK + + CV_CAP_OPENNI =900, // OpenNI (for Kinect) + CV_CAP_OPENNI_ASUS =910, // OpenNI (for Asus Xtion) + + CV_CAP_ANDROID =1000, // Android + + CV_CAP_XIAPI =1100, // XIMEA Camera API + + CV_CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API) + + CV_CAP_GIGANETIX = 1300 // Smartek Giganetix GigEVisionSDK +}; + +/* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */ +CVAPI(CvCapture*) cvCreateCameraCapture( int index ); + +/* grab a frame, return 1 on success, 0 on fail. + this function is thought to be fast */ +CVAPI(int) cvGrabFrame( CvCapture* capture ); + +/* get the frame grabbed with cvGrabFrame(..) + This function may apply some frame processing like + frame decompression, flipping etc. + !!!DO NOT RELEASE or MODIFY the retrieved frame!!! */ +CVAPI(IplImage*) cvRetrieveFrame( CvCapture* capture, int streamIdx CV_DEFAULT(0) ); + +/* Just a combination of cvGrabFrame and cvRetrieveFrame + !!!DO NOT RELEASE or MODIFY the retrieved frame!!! */ +CVAPI(IplImage*) cvQueryFrame( CvCapture* capture ); + +/* stop capturing/reading and free resources */ +CVAPI(void) cvReleaseCapture( CvCapture** capture ); + +enum +{ + // modes of the controlling registers (can be: auto, manual, auto single push, absolute Latter allowed with any other mode) + // every feature can have only one mode turned on at a time + CV_CAP_PROP_DC1394_OFF = -4, //turn the feature off (not controlled manually nor automatically) + CV_CAP_PROP_DC1394_MODE_MANUAL = -3, //set automatically when a value of the feature is set by the user + CV_CAP_PROP_DC1394_MODE_AUTO = -2, + CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO = -1, + CV_CAP_PROP_POS_MSEC =0, + CV_CAP_PROP_POS_FRAMES =1, + CV_CAP_PROP_POS_AVI_RATIO =2, + CV_CAP_PROP_FRAME_WIDTH =3, + CV_CAP_PROP_FRAME_HEIGHT =4, + CV_CAP_PROP_FPS =5, + CV_CAP_PROP_FOURCC =6, + CV_CAP_PROP_FRAME_COUNT =7, + CV_CAP_PROP_FORMAT =8, + CV_CAP_PROP_MODE =9, + CV_CAP_PROP_BRIGHTNESS =10, + CV_CAP_PROP_CONTRAST =11, + CV_CAP_PROP_SATURATION =12, + CV_CAP_PROP_HUE =13, + CV_CAP_PROP_GAIN =14, + CV_CAP_PROP_EXPOSURE =15, + CV_CAP_PROP_CONVERT_RGB =16, + CV_CAP_PROP_WHITE_BALANCE_BLUE_U =17, + CV_CAP_PROP_RECTIFICATION =18, + CV_CAP_PROP_MONOCROME =19, + CV_CAP_PROP_SHARPNESS =20, + CV_CAP_PROP_AUTO_EXPOSURE =21, // exposure control done by camera, + // user can adjust refernce level + // using this feature + CV_CAP_PROP_GAMMA =22, + CV_CAP_PROP_TEMPERATURE =23, + CV_CAP_PROP_TRIGGER =24, + CV_CAP_PROP_TRIGGER_DELAY =25, + CV_CAP_PROP_WHITE_BALANCE_RED_V =26, + CV_CAP_PROP_ZOOM =27, + CV_CAP_PROP_FOCUS =28, + CV_CAP_PROP_GUID =29, + CV_CAP_PROP_ISO_SPEED =30, + CV_CAP_PROP_MAX_DC1394 =31, + CV_CAP_PROP_BACKLIGHT =32, + CV_CAP_PROP_PAN =33, + CV_CAP_PROP_TILT =34, + CV_CAP_PROP_ROLL =35, + CV_CAP_PROP_IRIS =36, + CV_CAP_PROP_SETTINGS =37, + + CV_CAP_PROP_AUTOGRAB =1024, // property for highgui class CvCapture_Android only + CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING=1025, // readonly, tricky property, returns cpnst char* indeed + CV_CAP_PROP_PREVIEW_FORMAT=1026, // readonly, tricky property, returns cpnst char* indeed + + // OpenNI map generators + CV_CAP_OPENNI_DEPTH_GENERATOR = 1 << 31, + CV_CAP_OPENNI_IMAGE_GENERATOR = 1 << 30, + CV_CAP_OPENNI_GENERATORS_MASK = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_OPENNI_IMAGE_GENERATOR, + + // Properties of cameras available through OpenNI interfaces + CV_CAP_PROP_OPENNI_OUTPUT_MODE = 100, + CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH = 101, // in mm + CV_CAP_PROP_OPENNI_BASELINE = 102, // in mm + CV_CAP_PROP_OPENNI_FOCAL_LENGTH = 103, // in pixels + CV_CAP_PROP_OPENNI_REGISTRATION = 104, // flag + CV_CAP_PROP_OPENNI_REGISTRATION_ON = CV_CAP_PROP_OPENNI_REGISTRATION, // flag that synchronizes the remapping depth map to image map + // by changing depth generator's view point (if the flag is "on") or + // sets this view point to its normal one (if the flag is "off"). + CV_CAP_PROP_OPENNI_APPROX_FRAME_SYNC = 105, + CV_CAP_PROP_OPENNI_MAX_BUFFER_SIZE = 106, + CV_CAP_PROP_OPENNI_CIRCLE_BUFFER = 107, + CV_CAP_PROP_OPENNI_MAX_TIME_DURATION = 108, + + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT = 109, + + CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT, + CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_OUTPUT_MODE, + CV_CAP_OPENNI_DEPTH_GENERATOR_BASELINE = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_BASELINE, + CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_FOCAL_LENGTH, + CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_REGISTRATION, + CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION, + + // Properties of cameras available through GStreamer interface + CV_CAP_GSTREAMER_QUEUE_LENGTH = 200, // default is 1 + CV_CAP_PROP_PVAPI_MULTICASTIP = 300, // ip for anable multicast master mode. 0 for disable multicast + + // Properties of cameras available through XIMEA SDK interface + CV_CAP_PROP_XI_DOWNSAMPLING = 400, // Change image resolution by binning or skipping. + CV_CAP_PROP_XI_DATA_FORMAT = 401, // Output data format. + CV_CAP_PROP_XI_OFFSET_X = 402, // Horizontal offset from the origin to the area of interest (in pixels). + CV_CAP_PROP_XI_OFFSET_Y = 403, // Vertical offset from the origin to the area of interest (in pixels). + CV_CAP_PROP_XI_TRG_SOURCE = 404, // Defines source of trigger. + CV_CAP_PROP_XI_TRG_SOFTWARE = 405, // Generates an internal trigger. PRM_TRG_SOURCE must be set to TRG_SOFTWARE. + CV_CAP_PROP_XI_GPI_SELECTOR = 406, // Selects general purpose input + CV_CAP_PROP_XI_GPI_MODE = 407, // Set general purpose input mode + CV_CAP_PROP_XI_GPI_LEVEL = 408, // Get general purpose level + CV_CAP_PROP_XI_GPO_SELECTOR = 409, // Selects general purpose output + CV_CAP_PROP_XI_GPO_MODE = 410, // Set general purpose output mode + CV_CAP_PROP_XI_LED_SELECTOR = 411, // Selects camera signalling LED + CV_CAP_PROP_XI_LED_MODE = 412, // Define camera signalling LED functionality + CV_CAP_PROP_XI_MANUAL_WB = 413, // Calculates White Balance(must be called during acquisition) + CV_CAP_PROP_XI_AUTO_WB = 414, // Automatic white balance + CV_CAP_PROP_XI_AEAG = 415, // Automatic exposure/gain + CV_CAP_PROP_XI_EXP_PRIORITY = 416, // Exposure priority (0.5 - exposure 50%, gain 50%). + CV_CAP_PROP_XI_AE_MAX_LIMIT = 417, // Maximum limit of exposure in AEAG procedure + CV_CAP_PROP_XI_AG_MAX_LIMIT = 418, // Maximum limit of gain in AEAG procedure + CV_CAP_PROP_XI_AEAG_LEVEL = 419, // Average intensity of output signal AEAG should achieve(in %) + CV_CAP_PROP_XI_TIMEOUT = 420, // Image capture timeout in milliseconds + + // Properties for Android cameras + CV_CAP_PROP_ANDROID_FLASH_MODE = 8001, + CV_CAP_PROP_ANDROID_FOCUS_MODE = 8002, + CV_CAP_PROP_ANDROID_WHITE_BALANCE = 8003, + CV_CAP_PROP_ANDROID_ANTIBANDING = 8004, + CV_CAP_PROP_ANDROID_FOCAL_LENGTH = 8005, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008, + + // Properties of cameras available through AVFOUNDATION interface + CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001, + CV_CAP_PROP_IOS_DEVICE_EXPOSURE = 9002, + CV_CAP_PROP_IOS_DEVICE_FLASH = 9003, + CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE = 9004, + CV_CAP_PROP_IOS_DEVICE_TORCH = 9005 + + // Properties of cameras available through Smartek Giganetix Ethernet Vision interface + /* --- Vladimir Litvinenko (litvinenko.vladimir@gmail.com) --- */ + ,CV_CAP_PROP_GIGA_FRAME_OFFSET_X = 10001, + CV_CAP_PROP_GIGA_FRAME_OFFSET_Y = 10002, + CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX = 10003, + CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX = 10004, + CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH = 10005, + CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006 +}; + +enum +{ + // Data given from depth generator. + CV_CAP_OPENNI_DEPTH_MAP = 0, // Depth values in mm (CV_16UC1) + CV_CAP_OPENNI_POINT_CLOUD_MAP = 1, // XYZ in meters (CV_32FC3) + CV_CAP_OPENNI_DISPARITY_MAP = 2, // Disparity in pixels (CV_8UC1) + CV_CAP_OPENNI_DISPARITY_MAP_32F = 3, // Disparity in pixels (CV_32FC1) + CV_CAP_OPENNI_VALID_DEPTH_MASK = 4, // CV_8UC1 + + // Data given from RGB image generator. + CV_CAP_OPENNI_BGR_IMAGE = 5, + CV_CAP_OPENNI_GRAY_IMAGE = 6 +}; + +// Supported output modes of OpenNI image generator +enum +{ + CV_CAP_OPENNI_VGA_30HZ = 0, + CV_CAP_OPENNI_SXGA_15HZ = 1, + CV_CAP_OPENNI_SXGA_30HZ = 2, + CV_CAP_OPENNI_QVGA_30HZ = 3, + CV_CAP_OPENNI_QVGA_60HZ = 4 +}; + +//supported by Android camera output formats +enum +{ + CV_CAP_ANDROID_COLOR_FRAME_BGR = 0, //BGR + CV_CAP_ANDROID_COLOR_FRAME = CV_CAP_ANDROID_COLOR_FRAME_BGR, + CV_CAP_ANDROID_GREY_FRAME = 1, //Y + CV_CAP_ANDROID_COLOR_FRAME_RGB = 2, + CV_CAP_ANDROID_COLOR_FRAME_BGRA = 3, + CV_CAP_ANDROID_COLOR_FRAME_RGBA = 4 +}; + +// supported Android camera flash modes +enum +{ + CV_CAP_ANDROID_FLASH_MODE_AUTO = 0, + CV_CAP_ANDROID_FLASH_MODE_OFF, + CV_CAP_ANDROID_FLASH_MODE_ON, + CV_CAP_ANDROID_FLASH_MODE_RED_EYE, + CV_CAP_ANDROID_FLASH_MODE_TORCH +}; + +// supported Android camera focus modes +enum +{ + CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0, + CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO, + CV_CAP_ANDROID_FOCUS_MODE_EDOF, + CV_CAP_ANDROID_FOCUS_MODE_FIXED, + CV_CAP_ANDROID_FOCUS_MODE_INFINITY, + CV_CAP_ANDROID_FOCUS_MODE_MACRO +}; + +// supported Android camera white balance modes +enum +{ + CV_CAP_ANDROID_WHITE_BALANCE_AUTO = 0, + CV_CAP_ANDROID_WHITE_BALANCE_CLOUDY_DAYLIGHT, + CV_CAP_ANDROID_WHITE_BALANCE_DAYLIGHT, + CV_CAP_ANDROID_WHITE_BALANCE_FLUORESCENT, + CV_CAP_ANDROID_WHITE_BALANCE_INCANDESCENT, + CV_CAP_ANDROID_WHITE_BALANCE_SHADE, + CV_CAP_ANDROID_WHITE_BALANCE_TWILIGHT, + CV_CAP_ANDROID_WHITE_BALANCE_WARM_FLUORESCENT +}; + +// supported Android camera antibanding modes +enum +{ + CV_CAP_ANDROID_ANTIBANDING_50HZ = 0, + CV_CAP_ANDROID_ANTIBANDING_60HZ, + CV_CAP_ANDROID_ANTIBANDING_AUTO, + CV_CAP_ANDROID_ANTIBANDING_OFF +}; + +/* retrieve or set capture properties */ +CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id ); +CVAPI(int) cvSetCaptureProperty( CvCapture* capture, int property_id, double value ); + +// Return the type of the capturer (eg, CV_CAP_V4W, CV_CAP_UNICAP), which is unknown if created with CV_CAP_ANY +CVAPI(int) cvGetCaptureDomain( CvCapture* capture); + +/* "black box" video file writer structure */ +typedef struct CvVideoWriter CvVideoWriter; + +CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4) +{ + return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24); +} + +#define CV_FOURCC_PROMPT -1 /* Open Codec Selection Dialog (Windows only) */ +#define CV_FOURCC_DEFAULT CV_FOURCC('I', 'Y', 'U', 'V') /* Use default codec for specified filename (Linux only) */ + +/* initialize video file writer */ +CVAPI(CvVideoWriter*) cvCreateVideoWriter( const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color CV_DEFAULT(1)); + +//CVAPI(CvVideoWriter*) cvCreateImageSequenceWriter( const char* filename, +// int is_color CV_DEFAULT(1)); + +/* write frame to video file */ +CVAPI(int) cvWriteFrame( CvVideoWriter* writer, const IplImage* image ); + +/* close video file writer */ +CVAPI(void) cvReleaseVideoWriter( CvVideoWriter** writer ); + +/****************************************************************************************\ +* Obsolete functions/synonyms * +\****************************************************************************************/ + +#define cvCaptureFromFile cvCreateFileCapture +#define cvCaptureFromCAM cvCreateCameraCapture +#define cvCaptureFromAVI cvCaptureFromFile +#define cvCreateAVIWriter cvCreateVideoWriter +#define cvWriteToAVI cvWriteFrame +#define cvAddSearchPath(path) +#define cvvInitSystem cvInitSystem +#define cvvNamedWindow cvNamedWindow +#define cvvShowImage cvShowImage +#define cvvResizeWindow cvResizeWindow +#define cvvDestroyWindow cvDestroyWindow +#define cvvCreateTrackbar cvCreateTrackbar +#define cvvLoadImage(name) cvLoadImage((name),1) +#define cvvSaveImage cvSaveImage +#define cvvAddSearchPath cvAddSearchPath +#define cvvWaitKey(name) cvWaitKey(0) +#define cvvWaitKeyEx(name,delay) cvWaitKey(delay) +#define cvvConvertImage cvConvertImage +#define HG_AUTOSIZE CV_WINDOW_AUTOSIZE +#define set_preprocess_func cvSetPreprocessFuncWin32 +#define set_postprocess_func cvSetPostprocessFuncWin32 + +#if defined WIN32 || defined _WIN32 + +CVAPI(void) cvSetPreprocessFuncWin32_(const void* callback); +CVAPI(void) cvSetPostprocessFuncWin32_(const void* callback); +#define cvSetPreprocessFuncWin32(callback) cvSetPreprocessFuncWin32_((const void*)(callback)) +#define cvSetPostprocessFuncWin32(callback) cvSetPostprocessFuncWin32_((const void*)(callback)) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_input.cpp diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_input.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_input.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_input.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,30 @@ +#include "perf_precomp.hpp" + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + + +typedef perf::TestBaseWithParam VideoCapture_Reading; + +PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_buck_bunny.avi", + "highgui/video/big_buck_bunny.mov", + "highgui/video/big_buck_bunny.mp4", + "highgui/video/big_buck_bunny.mpg", + "highgui/video/big_buck_bunny.wmv" ) ) +{ + string filename = getDataPath(GetParam()); + + VideoCapture cap; + + TEST_CYCLE() cap.open(filename); + + bool dummy = cap.isOpened(); + SANITY_CHECK(dummy); +} + +#endif // BUILD_WITH_VIDEO_INPUT_SUPPORT \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_main.cpp diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_main.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3 @@ +#include "perf_precomp.hpp" + +CV_PERF_TEST_MAIN(highgui) diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_output.cpp diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_output.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_output.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_output.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,34 @@ +#include "perf_precomp.hpp" + +#if BUILD_WITH_VIDEO_OUTPUT_SUPPORT + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple VideoWriter_Writing_t; +typedef perf::TestBaseWithParam VideoWriter_Writing; + +PERF_TEST_P(VideoWriter_Writing, WriteFrame, + testing::Combine( testing::Values( "python/images/QCIF_00.bmp", + "python/images/QCIF_01.bmp", + "python/images/QCIF_02.bmp", + "python/images/QCIF_03.bmp", + "python/images/QCIF_04.bmp", + "python/images/QCIF_05.bmp" ), + testing::Bool())) +{ + string filename = getDataPath(get<0>(GetParam())); + bool isColor = get<1>(GetParam()); + + VideoWriter writer(cv::tempfile(".avi"), CV_FOURCC('X', 'V', 'I', 'D'), 25, cv::Size(640, 480), isColor); + + TEST_CYCLE() { Mat image = imread(filename, 1); writer << image; } + + bool dummy = writer.isOpened(); + SANITY_CHECK(dummy); +} + +#endif // BUILD_WITH_VIDEO_OUTPUT_SUPPORT \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_precomp.cpp diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "perf_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_precomp.hpp diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/perf/perf_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/perf/perf_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,44 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_PERF_PRECOMP_HPP__ +#define __OPENCV_PERF_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" +#include "opencv2/highgui/highgui.hpp" + +#ifdef GTEST_CREATE_SHARED_LIBRARY +#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined +#endif + +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(HAVE_VFW) + /*defined(HAVE_OPENNI) too specialized */ \ + +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 +#endif + +#if /*defined(HAVE_XINE) || */\ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(HAVE_VFW) +# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0 +#endif + + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/bitstrm.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/bitstrm.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/bitstrm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/bitstrm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,582 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "bitstrm.hpp" + +namespace cv +{ + +const int BS_DEF_BLOCK_SIZE = 1<<15; + +bool bsIsBigEndian( void ) +{ + return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0; +} + +///////////////////////// RBaseStream //////////////////////////// + +bool RBaseStream::isOpened() +{ + return m_is_opened; +} + +void RBaseStream::allocate() +{ + if( !m_allocated ) + { + m_start = new uchar[m_block_size]; + m_end = m_start + m_block_size; + m_current = m_end; + m_allocated = true; + } +} + + +RBaseStream::RBaseStream() +{ + m_start = m_end = m_current = 0; + m_file = 0; + m_block_size = BS_DEF_BLOCK_SIZE; + m_is_opened = false; + m_allocated = false; +} + + +RBaseStream::~RBaseStream() +{ + close(); // Close files + release(); // free buffers +} + + +void RBaseStream::readBlock() +{ + setPos( getPos() ); // normalize position + + if( m_file == 0 ) + { + if( m_block_pos == 0 && m_current < m_end ) + return; + throw RBS_THROW_EOS; + } + + fseek( m_file, m_block_pos, SEEK_SET ); + size_t readed = fread( m_start, 1, m_block_size, m_file ); + m_end = m_start + readed; + m_current = m_start; + + if( readed == 0 || m_current >= m_end ) + throw RBS_THROW_EOS; +} + + +bool RBaseStream::open( const string& filename ) +{ + close(); + allocate(); + + m_file = fopen( filename.c_str(), "rb" ); + if( m_file ) + { + m_is_opened = true; + setPos(0); + readBlock(); + } + return m_file != 0; +} + +bool RBaseStream::open( const Mat& buf ) +{ + close(); + if( buf.empty() ) + return false; + CV_Assert(buf.isContinuous()); + m_start = buf.data; + m_end = m_start + buf.cols*buf.rows*buf.elemSize(); + m_allocated = false; + m_is_opened = true; + setPos(0); + + return true; +} + +void RBaseStream::close() +{ + if( m_file ) + { + fclose( m_file ); + m_file = 0; + } + m_is_opened = false; + if( !m_allocated ) + m_start = m_end = m_current = 0; +} + + +void RBaseStream::release() +{ + if( m_allocated ) + delete[] m_start; + m_start = m_end = m_current = 0; + m_allocated = false; +} + + +void RBaseStream::setPos( int pos ) +{ + assert( isOpened() && pos >= 0 ); + + if( !m_file ) + { + m_current = m_start + pos; + m_block_pos = 0; + return; + } + + int offset = pos % m_block_size; + m_block_pos = pos - offset; + m_current = m_start + offset; +} + + +int RBaseStream::getPos() +{ + assert( isOpened() ); + return m_block_pos + (int)(m_current - m_start); +} + +void RBaseStream::skip( int bytes ) +{ + assert( bytes >= 0 ); + m_current += bytes; +} + +///////////////////////// RLByteStream //////////////////////////// + +RLByteStream::~RLByteStream() +{ +} + +int RLByteStream::getByte() +{ + uchar *current = m_current; + int val; + + if( current >= m_end ) + { + readBlock(); + current = m_current; + } + + val = *((uchar*)current); + m_current = current + 1; + return val; +} + + +int RLByteStream::getBytes( void* buffer, int count ) +{ + uchar* data = (uchar*)buffer; + int readed = 0; + assert( count >= 0 ); + + while( count > 0 ) + { + int l; + + for(;;) + { + l = (int)(m_end - m_current); + if( l > count ) l = count; + if( l > 0 ) break; + readBlock(); + } + memcpy( data, m_current, l ); + m_current += l; + data += l; + count -= l; + readed += l; + } + return readed; +} + + +//////////// RLByteStream & RMByteStream s //////////////// + +RMByteStream::~RMByteStream() +{ +} + + +int RLByteStream::getWord() +{ + uchar *current = m_current; + int val; + + if( current+1 < m_end ) + { + val = current[0] + (current[1] << 8); + m_current = current + 2; + } + else + { + val = getByte(); + val|= getByte() << 8; + } + return val; +} + + +int RLByteStream::getDWord() +{ + uchar *current = m_current; + int val; + + if( current+3 < m_end ) + { + val = current[0] + (current[1] << 8) + + (current[2] << 16) + (current[3] << 24); + m_current = current + 4; + } + else + { + val = getByte(); + val |= getByte() << 8; + val |= getByte() << 16; + val |= getByte() << 24; + } + return val; +} + + +int RMByteStream::getWord() +{ + uchar *current = m_current; + int val; + + if( current+1 < m_end ) + { + val = (current[0] << 8) + current[1]; + m_current = current + 2; + } + else + { + val = getByte() << 8; + val|= getByte(); + } + return val; +} + + +int RMByteStream::getDWord() +{ + uchar *current = m_current; + int val; + + if( current+3 < m_end ) + { + val = (current[0] << 24) + (current[1] << 16) + + (current[2] << 8) + current[3]; + m_current = current + 4; + } + else + { + val = getByte() << 24; + val |= getByte() << 16; + val |= getByte() << 8; + val |= getByte(); + } + return val; +} + +/////////////////////////// WBaseStream ///////////////////////////////// + +// WBaseStream - base class for output streams +WBaseStream::WBaseStream() +{ + m_start = m_end = m_current = 0; + m_file = 0; + m_block_size = BS_DEF_BLOCK_SIZE; + m_is_opened = false; + m_buf = 0; +} + + +WBaseStream::~WBaseStream() +{ + close(); + release(); +} + + +bool WBaseStream::isOpened() +{ + return m_is_opened; +} + + +void WBaseStream::allocate() +{ + if( !m_start ) + m_start = new uchar[m_block_size]; + + m_end = m_start + m_block_size; + m_current = m_start; +} + + +void WBaseStream::writeBlock() +{ + int size = (int)(m_current - m_start); + + assert( isOpened() ); + if( size == 0 ) + return; + + if( m_buf ) + { + size_t sz = m_buf->size(); + m_buf->resize( sz + size ); + memcpy( &(*m_buf)[sz], m_start, size ); + } + else + { + fwrite( m_start, 1, size, m_file ); + } + m_current = m_start; + m_block_pos += size; +} + + +bool WBaseStream::open( const string& filename ) +{ + close(); + allocate(); + + m_file = fopen( filename.c_str(), "wb" ); + if( m_file ) + { + m_is_opened = true; + m_block_pos = 0; + m_current = m_start; + } + return m_file != 0; +} + +bool WBaseStream::open( vector& buf ) +{ + close(); + allocate(); + + m_buf = &buf; + m_is_opened = true; + m_block_pos = 0; + m_current = m_start; + + return true; +} + +void WBaseStream::close() +{ + if( m_is_opened ) + writeBlock(); + if( m_file ) + { + fclose( m_file ); + m_file = 0; + } + m_buf = 0; + m_is_opened = false; +} + + +void WBaseStream::release() +{ + if( m_start ) + delete[] m_start; + m_start = m_end = m_current = 0; +} + + +int WBaseStream::getPos() +{ + assert( isOpened() ); + return m_block_pos + (int)(m_current - m_start); +} + + +///////////////////////////// WLByteStream /////////////////////////////////// + +WLByteStream::~WLByteStream() +{ +} + +void WLByteStream::putByte( int val ) +{ + *m_current++ = (uchar)val; + if( m_current >= m_end ) + writeBlock(); +} + + +void WLByteStream::putBytes( const void* buffer, int count ) +{ + uchar* data = (uchar*)buffer; + + assert( data && m_current && count >= 0 ); + + while( count ) + { + int l = (int)(m_end - m_current); + + if( l > count ) + l = count; + + if( l > 0 ) + { + memcpy( m_current, data, l ); + m_current += l; + data += l; + count -= l; + } + if( m_current == m_end ) + writeBlock(); + } +} + + +void WLByteStream::putWord( int val ) +{ + uchar *current = m_current; + + if( current+1 < m_end ) + { + current[0] = (uchar)val; + current[1] = (uchar)(val >> 8); + m_current = current + 2; + if( m_current == m_end ) + writeBlock(); + } + else + { + putByte(val); + putByte(val >> 8); + } +} + + +void WLByteStream::putDWord( int val ) +{ + uchar *current = m_current; + + if( current+3 < m_end ) + { + current[0] = (uchar)val; + current[1] = (uchar)(val >> 8); + current[2] = (uchar)(val >> 16); + current[3] = (uchar)(val >> 24); + m_current = current + 4; + if( m_current == m_end ) + writeBlock(); + } + else + { + putByte(val); + putByte(val >> 8); + putByte(val >> 16); + putByte(val >> 24); + } +} + + +///////////////////////////// WMByteStream /////////////////////////////////// + +WMByteStream::~WMByteStream() +{ +} + + +void WMByteStream::putWord( int val ) +{ + uchar *current = m_current; + + if( current+1 < m_end ) + { + current[0] = (uchar)(val >> 8); + current[1] = (uchar)val; + m_current = current + 2; + if( m_current == m_end ) + writeBlock(); + } + else + { + putByte(val >> 8); + putByte(val); + } +} + + +void WMByteStream::putDWord( int val ) +{ + uchar *current = m_current; + + if( current+3 < m_end ) + { + current[0] = (uchar)(val >> 24); + current[1] = (uchar)(val >> 16); + current[2] = (uchar)(val >> 8); + current[3] = (uchar)val; + m_current = current + 4; + if( m_current == m_end ) + writeBlock(); + } + else + { + putByte(val >> 24); + putByte(val >> 16); + putByte(val >> 8); + putByte(val); + } +} + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/bitstrm.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/bitstrm.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/bitstrm.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/bitstrm.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,182 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _BITSTRM_H_ +#define _BITSTRM_H_ + +#include + +namespace cv +{ + +enum +{ + RBS_THROW_EOS=-123, // exception code + RBS_THROW_FORB=-124, // exception code + RBS_HUFF_FORB=2047, // forrbidden huffman code "value" + RBS_BAD_HEADER=-125, // invalid header +}; + +typedef unsigned long ulong; + +// class RBaseStream - base class for other reading streams. +class RBaseStream +{ +public: + //methods + RBaseStream(); + virtual ~RBaseStream(); + + virtual bool open( const string& filename ); + virtual bool open( const Mat& buf ); + virtual void close(); + bool isOpened(); + void setPos( int pos ); + int getPos(); + void skip( int bytes ); + +protected: + + bool m_allocated; + uchar* m_start; + uchar* m_end; + uchar* m_current; + FILE* m_file; + int m_block_size; + int m_block_pos; + bool m_is_opened; + + virtual void readBlock(); + virtual void release(); + virtual void allocate(); +}; + + +// class RLByteStream - uchar-oriented stream. +// l in prefix means that the least significant uchar of a multi-uchar value goes first +class RLByteStream : public RBaseStream +{ +public: + virtual ~RLByteStream(); + + int getByte(); + int getBytes( void* buffer, int count ); + int getWord(); + int getDWord(); +}; + +// class RMBitStream - uchar-oriented stream. +// m in prefix means that the most significant uchar of a multi-uchar value go first +class RMByteStream : public RLByteStream +{ +public: + virtual ~RMByteStream(); + + int getWord(); + int getDWord(); +}; + +// WBaseStream - base class for output streams +class WBaseStream +{ +public: + //methods + WBaseStream(); + virtual ~WBaseStream(); + + virtual bool open( const string& filename ); + virtual bool open( vector& buf ); + virtual void close(); + bool isOpened(); + int getPos(); + +protected: + + uchar* m_start; + uchar* m_end; + uchar* m_current; + int m_block_size; + int m_block_pos; + FILE* m_file; + bool m_is_opened; + vector* m_buf; + + virtual void writeBlock(); + virtual void release(); + virtual void allocate(); +}; + + +// class WLByteStream - uchar-oriented stream. +// l in prefix means that the least significant uchar of a multi-byte value goes first +class WLByteStream : public WBaseStream +{ +public: + virtual ~WLByteStream(); + + void putByte( int val ); + void putBytes( const void* buffer, int count ); + void putWord( int val ); + void putDWord( int val ); +}; + + +// class WLByteStream - uchar-oriented stream. +// m in prefix means that the least significant uchar of a multi-byte value goes last +class WMByteStream : public WLByteStream +{ +public: + virtual ~WMByteStream(); + void putWord( int val ); + void putDWord( int val ); +}; + +inline unsigned BSWAP(unsigned v) +{ + return (v<<24)|((v&0xff00)<<8)|((v>>8)&0xff00)|((unsigned)v>>24); +} + +bool bsIsBigEndian( void ); + +} + +#endif/*_BITSTRM_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,580 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if defined _M_X64 && defined _MSC_VER && !defined CV_ICC +#pragma optimize("",off) +#pragma warning(disable: 4748) +#endif + +namespace cv +{ + +template<> void Ptr::delete_obj() +{ cvReleaseCapture(&obj); } + +template<> void Ptr::delete_obj() +{ cvReleaseVideoWriter(&obj); } + +} + +/************************* Reading AVIs & Camera data **************************/ + +CV_IMPL void cvReleaseCapture( CvCapture** pcapture ) +{ + if( pcapture && *pcapture ) + { + delete *pcapture; + *pcapture = 0; + } +} + +CV_IMPL IplImage* cvQueryFrame( CvCapture* capture ) +{ + if(!capture) + return 0; + if(!capture->grabFrame()) + return 0; + return capture->retrieveFrame(0); +} + + +CV_IMPL int cvGrabFrame( CvCapture* capture ) +{ + return capture ? capture->grabFrame() : 0; +} + +CV_IMPL IplImage* cvRetrieveFrame( CvCapture* capture, int idx ) +{ + return capture ? capture->retrieveFrame(idx) : 0; +} + +CV_IMPL double cvGetCaptureProperty( CvCapture* capture, int id ) +{ + return capture ? capture->getProperty(id) : 0; +} + +CV_IMPL int cvSetCaptureProperty( CvCapture* capture, int id, double value ) +{ + return capture ? capture->setProperty(id, value) : 0; +} + +CV_IMPL int cvGetCaptureDomain( CvCapture* capture) +{ + return capture ? capture->getCaptureDomain() : 0; +} + + +/** + * Camera dispatching method: index is the camera number. + * If given an index from 0 to 99, it tries to find the first + * API that can access a given camera index. + * Add multiples of 100 to select an API. + */ +CV_IMPL CvCapture * cvCreateCameraCapture (int index) +{ + int domains[] = + { +#ifdef HAVE_DSHOW + CV_CAP_DSHOW, +#endif +#if 1 + CV_CAP_IEEE1394, // identical to CV_CAP_DC1394 +#endif +#ifdef HAVE_TYZX + CV_CAP_STEREO, +#endif +#ifdef HAVE_PVAPI + CV_CAP_PVAPI, +#endif +#if 1 + CV_CAP_VFW, // identical to CV_CAP_V4L +#endif +#ifdef HAVE_MIL + CV_CAP_MIL, +#endif +#ifdef HAVE_QUICKTIME + CV_CAP_QT, +#endif +#ifdef HAVE_UNICAP + CV_CAP_UNICAP, +#endif +#ifdef HAVE_OPENNI + CV_CAP_OPENNI, +#endif +#ifdef HAVE_ANDROID_NATIVE_CAMERA + CV_CAP_ANDROID, +#endif +#ifdef HAVE_XIMEA + CV_CAP_XIAPI, +#endif +#ifdef HAVE_AVFOUNDATION + CV_CAP_AVFOUNDATION, +#endif +#ifdef HAVE_GIGE_API + CV_CAP_GIGANETIX, +#endif + -1 + }; + + // interpret preferred interface (0 = autodetect) + int pref = (index / 100) * 100; + if (pref) + { + domains[0]=pref; + index %= 100; + domains[1]=-1; + } + + // try every possibly installed camera API + for (int i = 0; domains[i] >= 0; i++) + { +#if defined(HAVE_DSHOW) || \ + defined(HAVE_MSMF) || \ + defined(HAVE_TYZX) || \ + defined(HAVE_VFW) || \ + defined(HAVE_LIBV4L) || \ + defined(HAVE_CAMV4L) || \ + defined(HAVE_CAMV4L2) || \ + defined(HAVE_VIDEOIO) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_DC1394_2) || \ + defined(HAVE_DC1394) || \ + defined(HAVE_CMU1394) || \ + defined(HAVE_MIL) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_UNICAP) || \ + defined(HAVE_PVAPI) || \ + defined(HAVE_OPENNI) || \ + defined(HAVE_XIMEA) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_ANDROID_NATIVE_CAMERA) || \ + defined(HAVE_GIGE_API) || \ + (0) + // local variable to memorize the captured device + CvCapture *capture; +#endif + + switch (domains[i]) + { +#ifdef HAVE_MSMF + case CV_CAP_MSMF: + capture = cvCreateCameraCapture_MSMF (index); + if (capture) + return capture; + break; +#endif +#ifdef HAVE_DSHOW + case CV_CAP_DSHOW: + capture = cvCreateCameraCapture_DShow (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_TYZX + case CV_CAP_STEREO: + capture = cvCreateCameraCapture_TYZX (index); + if (capture) + return capture; + break; +#endif + + case CV_CAP_VFW: +#ifdef HAVE_VFW + capture = cvCreateCameraCapture_VFW (index); + if (capture) + return capture; +#endif + +#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO + capture = cvCreateCameraCapture_V4L (index); + if (capture) + return capture; +#endif + +#ifdef HAVE_GSTREAMER + capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, 0); + if (capture) + return capture; + capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0); + if (capture) + return capture; +#endif + break; //CV_CAP_VFW + + case CV_CAP_FIREWIRE: +#ifdef HAVE_DC1394_2 + capture = cvCreateCameraCapture_DC1394_2 (index); + if (capture) + return capture; +#endif + +#ifdef HAVE_DC1394 + capture = cvCreateCameraCapture_DC1394 (index); + if (capture) + return capture; +#endif + +#ifdef HAVE_CMU1394 + capture = cvCreateCameraCapture_CMU (index); + if (capture) + return capture; +#endif + +#if defined(HAVE_GSTREAMER) && 0 + //Re-enable again when gstreamer 1394 support will land in the backend code + capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0); + if (capture) + return capture; +#endif + break; //CV_CAP_FIREWIRE + +#ifdef HAVE_MIL + case CV_CAP_MIL: + capture = cvCreateCameraCapture_MIL (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_QUICKTIME + case CV_CAP_QT: + capture = cvCreateCameraCapture_QT (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_UNICAP + case CV_CAP_UNICAP: + capture = cvCreateCameraCapture_Unicap (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_PVAPI + case CV_CAP_PVAPI: + capture = cvCreateCameraCapture_PvAPI (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_OPENNI + case CV_CAP_OPENNI: + capture = cvCreateCameraCapture_OpenNI (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_ANDROID_NATIVE_CAMERA + case CV_CAP_ANDROID: + capture = cvCreateCameraCapture_Android (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_XIMEA + case CV_CAP_XIAPI: + capture = cvCreateCameraCapture_XIMEA (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_AVFOUNDATION + case CV_CAP_AVFOUNDATION: + capture = cvCreateCameraCapture_AVFoundation (index); + if (capture) + return capture; + break; +#endif + +#ifdef HAVE_GIGE_API + case CV_CAP_GIGANETIX: + capture = cvCreateCameraCapture_Giganetix (index); + if (capture) + return capture; + break; // CV_CAP_GIGANETIX +#endif + } + } + + // failed open a camera + return 0; +} + +/** + * Videoreader dispatching method: it tries to find the first + * API that can access a given filename. + */ +CV_IMPL CvCapture * cvCreateFileCapture (const char * filename) +{ + CvCapture * result = 0; + + if (! result) + result = cvCreateFileCapture_FFMPEG_proxy (filename); + +#ifdef HAVE_XINE + if (! result) + result = cvCreateFileCapture_XINE (filename); +#endif + +#ifdef HAVE_GSTREAMER + if (! result) + result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename); +#endif + +#ifdef HAVE_QUICKTIME + if (! result) + result = cvCreateFileCapture_QT (filename); +#endif + +#ifdef HAVE_AVFOUNDATION + if (! result) + result = cvCreateFileCapture_AVFoundation (filename); +#endif + +#ifdef HAVE_OPENNI + if (! result) + result = cvCreateFileCapture_OpenNI (filename); +#endif + + if (! result) + result = cvCreateFileCapture_Images (filename); + + return result; +} + +/** + * Videowriter dispatching method: it tries to find the first + * API that can write a given stream. + */ +CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ) +{ + //CV_FUNCNAME( "cvCreateVideoWriter" ); + + CvVideoWriter *result = 0; + + if(!fourcc || !fps) + result = cvCreateVideoWriter_Images(filename); + + if(!result) + result = cvCreateVideoWriter_FFMPEG_proxy (filename, fourcc, fps, frameSize, is_color); + +/* #ifdef HAVE_XINE + if(!result) + result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color); + #endif +*/ +#ifdef HAVE_AVFOUNDATION + if (! result) + result = cvCreateVideoWriter_AVFoundation(filename, fourcc, fps, frameSize, is_color); +#endif + +#ifdef HAVE_QUICKTIME + if(!result) + result = cvCreateVideoWriter_QT(filename, fourcc, fps, frameSize, is_color); +#endif + +#ifdef HAVE_GSTREAMER + if (! result) + result = cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color); +#endif + + if(!result) + result = cvCreateVideoWriter_Images(filename); + + return result; +} + +CV_IMPL int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) +{ + return writer ? writer->writeFrame(image) : 0; +} + +CV_IMPL void cvReleaseVideoWriter( CvVideoWriter** pwriter ) +{ + if( pwriter && *pwriter ) + { + delete *pwriter; + *pwriter = 0; + } +} + +namespace cv +{ + +VideoCapture::VideoCapture() +{} + +VideoCapture::VideoCapture(const string& filename) +{ + open(filename); +} + +VideoCapture::VideoCapture(int device) +{ + open(device); +} + +VideoCapture::~VideoCapture() +{ + cap.release(); +} + +bool VideoCapture::open(const string& filename) +{ + if (!isOpened()) + cap = cvCreateFileCapture(filename.c_str()); + return isOpened(); +} + +bool VideoCapture::open(int device) +{ + if (!isOpened()) + cap = cvCreateCameraCapture(device); + return isOpened(); +} + +bool VideoCapture::isOpened() const { return !cap.empty(); } + +void VideoCapture::release() +{ + cap.release(); +} + +bool VideoCapture::grab() +{ + return cvGrabFrame(cap) != 0; +} + +bool VideoCapture::retrieve(Mat& image, int channel) +{ + IplImage* _img = cvRetrieveFrame(cap, channel); + if( !_img ) + { + image.release(); + return false; + } + if(_img->origin == IPL_ORIGIN_TL) + image = Mat(_img); + else + { + Mat temp(_img); + flip(temp, image, 0); + } + return true; +} + +bool VideoCapture::read(Mat& image) +{ + if(grab()) + retrieve(image); + else + image.release(); + return !image.empty(); +} + +VideoCapture& VideoCapture::operator >> (Mat& image) +{ + read(image); + return *this; +} + +bool VideoCapture::set(int propId, double value) +{ + return cvSetCaptureProperty(cap, propId, value) != 0; +} + +double VideoCapture::get(int propId) +{ + return cvGetCaptureProperty(cap, propId); +} + +VideoWriter::VideoWriter() +{} + +VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor) +{ + open(filename, fourcc, fps, frameSize, isColor); +} + +void VideoWriter::release() +{ + writer.release(); +} + +VideoWriter::~VideoWriter() +{ + release(); +} + +bool VideoWriter::open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor) +{ + writer = cvCreateVideoWriter(filename.c_str(), fourcc, fps, frameSize, isColor); + return isOpened(); +} + +bool VideoWriter::isOpened() const +{ + return !writer.empty(); +} + +void VideoWriter::write(const Mat& image) +{ + IplImage _img = image; + cvWriteFrame(writer, &_img); +} + +VideoWriter& VideoWriter::operator << (const Mat& image) +{ + write(image); + return *this; +} + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_android.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_android.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_android.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_android.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,541 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_ANDROID_NATIVE_CAMERA + +#include +#include +#include +#include + +#undef LOG_TAG +#undef LOGD +#undef LOGE +#undef LOGI +#define LOG_TAG "OpenCV::camera" +#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) + +class HighguiAndroidCameraActivity; + +class CvCapture_Android : public CvCapture +{ +public: + CvCapture_Android(int); + virtual ~CvCapture_Android(); + + virtual double getProperty(int propIdx); + virtual bool setProperty(int probIdx, double propVal); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int outputType); + virtual int getCaptureDomain() { return CV_CAP_ANDROID; } + + bool isOpened() const; + +protected: + struct OutputMap + { + public: + cv::Mat mat; + IplImage* getIplImagePtr(); + private: + IplImage iplHeader; + }; + + CameraActivity* m_activity; + + //raw from camera + int m_width; + int m_height; + cv::Mat m_frameYUV420; + cv::Mat m_frameYUV420next; + + enum YUVformat + { + noformat = 0, + yuv420sp, + yvu420sp, + yuvUnknown + }; + + YUVformat m_frameFormat; + + void setFrame(const void* buffer, int bufferSize); + +private: + bool m_isOpened; + bool m_CameraParamsChanged; + + //frames counter for statistics + int m_framesGrabbed; + + //cached converted frames + OutputMap m_frameGray; + OutputMap m_frameColor; + bool m_hasGray; + bool m_hasColor; + + enum CvCapture_Android_DataState { + CVCAPTURE_ANDROID_STATE_NO_FRAME=0, + CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED, + CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED + }; + volatile CvCapture_Android_DataState m_dataState; + + //synchronization + pthread_mutex_t m_nextFrameMutex; + pthread_cond_t m_nextFrameCond; + volatile bool m_waitingNextFrame; + volatile bool m_shouldAutoGrab; + + void prepareCacheForYUV(int width, int height); + bool convertYUV2Grey(int width, int height, const unsigned char* yuv, cv::Mat& resmat); + bool convertYUV2BGR(int width, int height, const unsigned char* yuv, cv::Mat& resmat, bool inRGBorder, bool withAlpha); + + friend class HighguiAndroidCameraActivity; +}; + + +class HighguiAndroidCameraActivity : public CameraActivity +{ +public: + HighguiAndroidCameraActivity(CvCapture_Android* capture) + { + m_capture = capture; + m_framesReceived = 0; + } + + virtual bool onFrameBuffer(void* buffer, int bufferSize) + { + if(isConnected() && buffer != 0 && bufferSize > 0) + { + m_framesReceived++; + if (m_capture->m_waitingNextFrame || m_capture->m_shouldAutoGrab) + { + pthread_mutex_lock(&m_capture->m_nextFrameMutex); + + m_capture->setFrame(buffer, bufferSize); + + pthread_cond_broadcast(&m_capture->m_nextFrameCond); + pthread_mutex_unlock(&m_capture->m_nextFrameMutex); + } + return true; + } + return false; + } + + void LogFramesRate() + { + LOGI("FRAMES received: %d grabbed: %d", m_framesReceived, m_capture->m_framesGrabbed); + } + +private: + CvCapture_Android* m_capture; + int m_framesReceived; +}; + +IplImage* CvCapture_Android::OutputMap::getIplImagePtr() +{ + if( mat.empty() ) + return 0; + + iplHeader = IplImage(mat); + return &iplHeader; +} + +CvCapture_Android::CvCapture_Android(int cameraId) +{ + //defaults + m_width = 0; + m_height = 0; + m_activity = 0; + m_isOpened = false; + // m_frameYUV420 = 0; + // m_frameYUV420next = 0; + m_hasGray = false; + m_hasColor = false; + m_dataState = CVCAPTURE_ANDROID_STATE_NO_FRAME; + m_waitingNextFrame = false; + m_shouldAutoGrab = false; + m_framesGrabbed = 0; + m_CameraParamsChanged = false; + m_frameFormat = noformat; + + //try connect to camera + LOGD("CvCapture_Android::CvCapture_Android(%i)", cameraId); + m_activity = new HighguiAndroidCameraActivity(this); + + if (m_activity == 0) return; + + pthread_mutex_init(&m_nextFrameMutex, NULL); + pthread_cond_init (&m_nextFrameCond, NULL); + + CameraActivity::ErrorCode errcode = m_activity->connect(cameraId); + + if(errcode == CameraActivity::NO_ERROR) + m_isOpened = true; + else + { + LOGE("Native_camera returned opening error: %d", errcode); + delete m_activity; + m_activity = 0; + } +} + +bool CvCapture_Android::isOpened() const +{ + return m_isOpened; +} + +CvCapture_Android::~CvCapture_Android() +{ + if (m_activity) + { + ((HighguiAndroidCameraActivity*)m_activity)->LogFramesRate(); + + pthread_mutex_lock(&m_nextFrameMutex); + + // unsigned char *tmp1=m_frameYUV420; + // unsigned char *tmp2=m_frameYUV420next; + // m_frameYUV420 = 0; + // m_frameYUV420next = 0; + // delete tmp1; + // delete tmp2; + + m_dataState=CVCAPTURE_ANDROID_STATE_NO_FRAME; + pthread_cond_broadcast(&m_nextFrameCond); + + pthread_mutex_unlock(&m_nextFrameMutex); + + //m_activity->disconnect() will be automatically called inside destructor; + delete m_activity; + m_activity = 0; + + pthread_mutex_destroy(&m_nextFrameMutex); + pthread_cond_destroy(&m_nextFrameCond); + } +} + +double CvCapture_Android::getProperty( int propIdx ) +{ + switch ( propIdx ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return (double)m_activity->getFrameWidth(); + case CV_CAP_PROP_FRAME_HEIGHT: + return (double)m_activity->getFrameHeight(); + case CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING); + case CV_CAP_PROP_PREVIEW_FORMAT: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING); + case CV_CAP_PROP_FPS: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FPS); + case CV_CAP_PROP_EXPOSURE: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE); + case CV_CAP_PROP_ANDROID_FLASH_MODE: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE); + case CV_CAP_PROP_ANDROID_FOCUS_MODE: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE); + case CV_CAP_PROP_ANDROID_WHITE_BALANCE: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE); + case CV_CAP_PROP_ANDROID_ANTIBANDING: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING); + case CV_CAP_PROP_ANDROID_FOCAL_LENGTH: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH); + case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR); + case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL); + case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR: + return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR); + default: + CV_Error( CV_StsOutOfRange, "Failed attempt to GET unsupported camera property." ); + break; + } + return -1.0; +} + +bool CvCapture_Android::setProperty( int propIdx, double propValue ) +{ + bool res = false; + if( isOpened() ) + { + switch ( propIdx ) + { + case CV_CAP_PROP_FRAME_WIDTH: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH, propValue); + break; + case CV_CAP_PROP_FRAME_HEIGHT: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT, propValue); + break; + case CV_CAP_PROP_AUTOGRAB: + m_shouldAutoGrab=(propValue != 0); + break; + case CV_CAP_PROP_EXPOSURE: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE, propValue); + break; + case CV_CAP_PROP_ANDROID_FLASH_MODE: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE, propValue); + break; + case CV_CAP_PROP_ANDROID_FOCUS_MODE: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE, propValue); + break; + case CV_CAP_PROP_ANDROID_WHITE_BALANCE: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE, propValue); + break; + case CV_CAP_PROP_ANDROID_ANTIBANDING: + m_activity->setProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING, propValue); + break; + default: + CV_Error( CV_StsOutOfRange, "Failed attempt to SET unsupported camera property." ); + return false; + } + + if (propIdx != CV_CAP_PROP_AUTOGRAB) {// property for highgui class CvCapture_Android only + m_CameraParamsChanged = true; + } + res = true; + } + + return res; +} + +bool CvCapture_Android::grabFrame() +{ + if( !isOpened() ) { + LOGE("CvCapture_Android::grabFrame(): camera is not opened"); + return false; + } + + bool res=false; + pthread_mutex_lock(&m_nextFrameMutex); + if (m_CameraParamsChanged) + { + m_activity->applyProperties(); + m_CameraParamsChanged = false; + m_dataState = CVCAPTURE_ANDROID_STATE_NO_FRAME;//we will wait new frame + } + + if (m_dataState != CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED) + { + m_waitingNextFrame = true; + pthread_cond_wait(&m_nextFrameCond, &m_nextFrameMutex); + } + + if (m_dataState == CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED) + { + //LOGD("CvCapture_Android::grabFrame: get new frame"); + //swap current and new frames + cv::swap(m_frameYUV420, m_frameYUV420next); + + //discard cached frames + m_hasGray = false; + m_hasColor = false; + + m_dataState=CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED; + m_framesGrabbed++; + + res=true; + } else { + LOGE("CvCapture_Android::grabFrame: NO new frame"); + } + + + int res_unlock=pthread_mutex_unlock(&m_nextFrameMutex); + if (res_unlock) { + LOGE("Error in CvCapture_Android::grabFrame: pthread_mutex_unlock returned %d --- probably, this object has been destroyed", res_unlock); + return false; + } + + return res; +} + +IplImage* CvCapture_Android::retrieveFrame( int outputType ) +{ + IplImage* image = NULL; + + cv::Mat m_frameYUV420_ref = m_frameYUV420; + unsigned char *current_frameYUV420=m_frameYUV420_ref.ptr(); + //Attention! all the operations in this function below should occupy less time than the period between two frames from camera + if (NULL != current_frameYUV420) + { + if (m_frameFormat == noformat) + { + union {double prop; const char* name;} u; + u.prop = getProperty(CV_CAP_PROP_PREVIEW_FORMAT); + if (0 == strcmp(u.name, "yuv420sp")) + m_frameFormat = yuv420sp; + else if (0 == strcmp(u.name, "yvu420sp")) + m_frameFormat = yvu420sp; + else + m_frameFormat = yuvUnknown; + } + + switch(outputType) + { + case CV_CAP_ANDROID_GREY_FRAME: + if (!m_hasGray) + if (!(m_hasGray = convertYUV2Grey(m_width, m_height, current_frameYUV420, m_frameGray.mat))) + return NULL; + image = m_frameGray.getIplImagePtr(); + break; + case CV_CAP_ANDROID_COLOR_FRAME_BGR: case CV_CAP_ANDROID_COLOR_FRAME_RGB: + if (!m_hasColor) + if (!(m_hasColor = convertYUV2BGR(m_width, m_height, current_frameYUV420, m_frameColor.mat, outputType == CV_CAP_ANDROID_COLOR_FRAME_RGB, false))) + return NULL; + image = m_frameColor.getIplImagePtr(); + break; + case CV_CAP_ANDROID_COLOR_FRAME_BGRA: case CV_CAP_ANDROID_COLOR_FRAME_RGBA: + if (!m_hasColor) + if (!(m_hasColor = convertYUV2BGR(m_width, m_height, current_frameYUV420, m_frameColor.mat, outputType == CV_CAP_ANDROID_COLOR_FRAME_RGBA, true))) + return NULL; + image = m_frameColor.getIplImagePtr(); + break; + default: + LOGE("Unsupported frame output format: %d", outputType); + CV_Error( CV_StsOutOfRange, "Output frame format is not supported." ); + image = NULL; + break; + } + } + return image; +} + +//Attention: this method should be called inside pthread_mutex_lock(m_nextFrameMutex) only +void CvCapture_Android::setFrame(const void* buffer, int bufferSize) +{ + int width = m_activity->getFrameWidth(); + int height = m_activity->getFrameHeight(); + int expectedSize = (width * height * 3) >> 1; + + if ( expectedSize != bufferSize) + { + LOGE("ERROR reading YUV buffer: width=%d, height=%d, size=%d, receivedSize=%d", width, height, expectedSize, bufferSize); + return; + } + + //allocate memory if needed + prepareCacheForYUV(width, height); + + //copy data + cv::Mat m_frameYUV420next_ref = m_frameYUV420next; + memcpy(m_frameYUV420next_ref.ptr(), buffer, bufferSize); + // LOGD("CvCapture_Android::setFrame -- memcpy is done"); + // ((HighguiAndroidCameraActivity*)m_activity)->LogFramesRate(); + + m_dataState = CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED; + m_waitingNextFrame = false;//set flag that no more frames required at this moment +} + +//Attention: this method should be called inside pthread_mutex_lock(m_nextFrameMutex) only +void CvCapture_Android::prepareCacheForYUV(int width, int height) +{ + if (width != m_width || height != m_height) + { + LOGD("CvCapture_Android::prepareCacheForYUV: Changing size of buffers: from width=%d height=%d to width=%d height=%d", m_width, m_height, width, height); + m_width = width; + m_height = height; + /* + unsigned char *tmp = m_frameYUV420next; + m_frameYUV420next = new unsigned char [width * height * 3 / 2]; + if (tmp != NULL) + { + delete[] tmp; + } + + tmp = m_frameYUV420; + m_frameYUV420 = new unsigned char [width * height * 3 / 2]; + if (tmp != NULL) + { + delete[] tmp; + }*/ + m_frameYUV420.create(height * 3 / 2, width, CV_8UC1); + m_frameYUV420next.create(height * 3 / 2, width, CV_8UC1); + } +} + +bool CvCapture_Android::convertYUV2Grey(int width, int height, const unsigned char* yuv, cv::Mat& resmat) +{ + if (yuv == 0) return false; + if (m_frameFormat != yuv420sp && m_frameFormat != yvu420sp) return false; +#define ALWAYS_COPY_GRAY 0 +#if ALWAYS_COPY_GRAY + resmat.create(height, width, CV_8UC1); + unsigned char* matBuff = resmat.ptr (0); + memcpy(matBuff, yuv, width * height); +#else + resmat = cv::Mat(height, width, CV_8UC1, (void*)yuv); +#endif + return !resmat.empty(); +} + +bool CvCapture_Android::convertYUV2BGR(int width, int height, const unsigned char* yuv, cv::Mat& resmat, bool inRGBorder, bool withAlpha) +{ + if (yuv == 0) return false; + if (m_frameFormat != yuv420sp && m_frameFormat != yvu420sp) return false; + + CV_Assert(width % 2 == 0 && height % 2 == 0); + + cv::Mat src(height*3/2, width, CV_8UC1, (void*)yuv); + + if (m_frameFormat == yuv420sp) + cv::cvtColor(src, resmat, inRGBorder ? CV_YUV420sp2RGB : CV_YUV420sp2BGR, withAlpha ? 4 : 3); + else if (m_frameFormat == yvu420sp) + cv::cvtColor(src, resmat, inRGBorder ? CV_YUV2RGB_NV21 : CV_YUV2BGR_NV12, withAlpha ? 4 : 3); + + return !resmat.empty(); +} + +CvCapture* cvCreateCameraCapture_Android( int cameraId ) +{ + CvCapture_Android* capture = new CvCapture_Android(cameraId); + + if( capture->isOpened() ) + return capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_avfoundation.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_avfoundation.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_avfoundation.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_avfoundation.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1332 @@ +/* + * cap_avfoundation.mm + * For iOS video I/O + * by Xiaochao Yang on 06/15/11 modified from + * cap_qtkit.mm for Nicholas Butko for Mac OS version. + * Copyright 2011. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include +#import +#import + + +//#import + +using namespace std; + +/********************** Declaration of class headers ************************/ + +/***************************************************************************** + * + * CaptureDelegate Declaration. + * + * CaptureDelegate is notified on a separate thread by the OS whenever there + * is a new frame. When "updateImage" is called from the main thread, it + * copies this new frame into an IplImage, but only if this frame has not + * been copied before. When "getOutput" is called from the main thread, + * it gives the last copied IplImage. + * + *****************************************************************************/ + +#define DISABLE_AUTO_RESTART 999 + +@interface CaptureDelegate : NSObject +{ + int newFrame; + CVImageBufferRef mCurrentImageBuffer; + char* imagedata; + IplImage* image; + char* bgr_imagedata; + IplImage* bgr_image; + IplImage* bgr_image_r90; + size_t currSize; +} + +- (void)captureOutput:(AVCaptureOutput *)captureOutput +didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer +fromConnection:(AVCaptureConnection *)connection; + + +- (int)updateImage; +- (IplImage*)getOutput; + +@end + +/***************************************************************************** + * + * CvCaptureCAM Declaration. + * + * CvCaptureCAM is the instantiation of a capture source for cameras. + * + *****************************************************************************/ + +class CvCaptureCAM : public CvCapture { + public: + CvCaptureCAM(int cameraNum = -1) ; + ~CvCaptureCAM(); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual IplImage* queryFrame(); + virtual double getProperty(int property_id); + virtual bool setProperty(int property_id, double value); + virtual int didStart(); + + private: + AVCaptureSession *mCaptureSession; + AVCaptureDeviceInput *mCaptureDeviceInput; + AVCaptureVideoDataOutput *mCaptureDecompressedVideoOutput; + AVCaptureDevice *mCaptureDevice; + CaptureDelegate *capture; + + int startCaptureDevice(int cameraNum); + void stopCaptureDevice(); + + void setWidthHeight(); + bool grabFrame(double timeOut); + + int camNum; + int width; + int height; + int settingWidth; + int settingHeight; + int started; + int disableAutoRestart; +}; + + +/***************************************************************************** + * + * CvCaptureFile Declaration. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +class CvCaptureFile : public CvCapture { + public: + + CvCaptureFile(const char* filename) ; + ~CvCaptureFile(); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual IplImage* queryFrame(); + virtual double getProperty(int property_id); + virtual bool setProperty(int property_id, double value); + virtual int didStart(); + + private: + + AVAssetReader *mMovieReader; + char* imagedata; + IplImage* image; + char* bgr_imagedata; + IplImage* bgr_image; + size_t currSize; + + IplImage* retrieveFramePixelBuffer(); + double getFPS(); + + int movieWidth; + int movieHeight; + double movieFPS; + double currentFPS; + double movieDuration; + int changedPos; + + int started; +}; + + +/***************************************************************************** + * + * CvCaptureFile Declaration. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +class CvVideoWriter_AVFoundation : public CvVideoWriter{ + public: + CvVideoWriter_AVFoundation(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color=1); + ~CvVideoWriter_AVFoundation(); + bool writeFrame(const IplImage* image); + private: + IplImage* argbimage; + + AVAssetWriter *mMovieWriter; + AVAssetWriterInput* mMovieWriterInput; + AVAssetWriterInputPixelBufferAdaptor* mMovieWriterAdaptor; + + unsigned char* imagedata; + NSString* path; + NSString* codec; + NSString* fileType; + double movieFPS; + CvSize movieSize; + int movieColor; + unsigned long frameCount; +}; + + +/****************** Implementation of interface functions ********************/ + + +CvCapture* cvCreateFileCapture_AVFoundation(const char* filename) { + CvCaptureFile *retval = new CvCaptureFile(filename); + + if(retval->didStart()) + return retval; + delete retval; + return NULL; +} + +CvCapture* cvCreateCameraCapture_AVFoundation(int index ) { + + CvCapture* retval = new CvCaptureCAM(index); + if (!((CvCaptureCAM *)retval)->didStart()) + cvReleaseCapture(&retval); + return retval; + +} + +CvVideoWriter* cvCreateVideoWriter_AVFoundation(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color) { + return new CvVideoWriter_AVFoundation(filename, fourcc, fps, frame_size,is_color); +} + +/********************** Implementation of Classes ****************************/ +/***************************************************************************** + * + * CvCaptureCAM Implementation. + * + * CvCaptureCAM is the instantiation of a capture source for cameras. + * + *****************************************************************************/ + +CvCaptureCAM::CvCaptureCAM(int cameraNum) { + mCaptureSession = nil; + mCaptureDeviceInput = nil; + mCaptureDecompressedVideoOutput = nil; + capture = nil; + + width = 0; + height = 0; + settingWidth = 0; + settingHeight = 0; + disableAutoRestart = 0; + + camNum = cameraNum; + + if (!startCaptureDevice(camNum)) { + cout << "Warning, camera failed to properly initialize!" << endl; + started = 0; + } else { + started = 1; + } + +} + +CvCaptureCAM::~CvCaptureCAM() { + stopCaptureDevice(); + //cout << "Cleaned up camera." << endl; +} + +int CvCaptureCAM::didStart() { + return started; +} + + +bool CvCaptureCAM::grabFrame() { + return grabFrame(5); +} + +bool CvCaptureCAM::grabFrame(double timeOut) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + double sleepTime = 0.005; + double total = 0; + + NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:sleepTime]; + while (![capture updateImage] && (total += sleepTime)<=timeOut && + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate:loopUntil]) + loopUntil = [NSDate dateWithTimeIntervalSinceNow:sleepTime]; + + [localpool drain]; + + return total <= timeOut; +} + +IplImage* CvCaptureCAM::retrieveFrame(int) { + return [capture getOutput]; +} + +IplImage* CvCaptureCAM::queryFrame() { + while (!grabFrame()) { + cout << "WARNING: Couldn't grab new frame from camera!!!" << endl; + /* + cout << "Attempting to restart camera; set capture property DISABLE_AUTO_RESTART to disable." << endl; + stopCaptureDevice(); + startCaptureDevice(camNum); + */ + } + return retrieveFrame(0); +} + +void CvCaptureCAM::stopCaptureDevice() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + [mCaptureSession stopRunning]; + + [mCaptureSession release]; + [mCaptureDeviceInput release]; + + [mCaptureDecompressedVideoOutput release]; + [capture release]; + [localpool drain]; + +} + +int CvCaptureCAM::startCaptureDevice(int cameraNum) { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + capture = [[CaptureDelegate alloc] init]; + + AVCaptureDevice *device; + NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + if ([devices count] == 0) { + cout << "AV Foundation didn't find any attached Video Input Devices!" << endl; + [localpool drain]; + return 0; + } + + if (cameraNum >= 0) { + camNum = cameraNum % [devices count]; + if (camNum != cameraNum) { + cout << "Warning: Max Camera Num is " << [devices count]-1 << "; Using camera " << camNum << endl; + } + device = [devices objectAtIndex:camNum]; + } else { + device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] ; + } + mCaptureDevice = device; + //int success; + NSError* error; + + if (device) { + + mCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error] ; + mCaptureSession = [[AVCaptureSession alloc] init] ; + + /* + success = [mCaptureSession addInput:mCaptureDeviceInput]; + + if (!success) { + cout << "AV Foundation failed to start capture session with opened Capture Device" << endl; + [localpool drain]; + return 0; + } + */ + + mCaptureDecompressedVideoOutput = [[AVCaptureVideoDataOutput alloc] init]; + + dispatch_queue_t queue = dispatch_queue_create("cameraQueue", NULL); + [mCaptureDecompressedVideoOutput setSampleBufferDelegate:capture queue:queue]; + dispatch_release(queue); + + + NSDictionary *pixelBufferOptions ; + if (width > 0 && height > 0) { + pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithDouble:1.0*width], (id)kCVPixelBufferWidthKey, + [NSNumber numberWithDouble:1.0*height], (id)kCVPixelBufferHeightKey, + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + } else { + pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + } + + //TODO: add new interface for setting fps and capturing resolution. + [mCaptureDecompressedVideoOutput setVideoSettings:pixelBufferOptions]; + mCaptureDecompressedVideoOutput.alwaysDiscardsLateVideoFrames = YES; + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + mCaptureDecompressedVideoOutput.minFrameDuration = CMTimeMake(1, 30); +#endif + + //Slow. 1280*720 for iPhone4, iPod back camera. 640*480 for front camera + //mCaptureSession.sessionPreset = AVCaptureSessionPresetHigh; // fps ~= 5 slow for OpenCV + + mCaptureSession.sessionPreset = AVCaptureSessionPresetMedium; //480*360 + if (width == 0 ) width = 480; + if (height == 0 ) height = 360; + + [mCaptureSession addInput:mCaptureDeviceInput]; + [mCaptureSession addOutput:mCaptureDecompressedVideoOutput]; + + /* + // Does not work! This is the preferred way (hardware acceleration) to change pixel buffer orientation. + // I'm now using cvtranspose and cvflip instead, which takes cpu cycles. + AVCaptureConnection *connection = [[mCaptureDecompressedVideoOutput connections] objectAtIndex:0]; + if([connection isVideoOrientationSupported]) { + //NSLog(@"Setting pixel buffer orientation"); + connection.videoOrientation = AVCaptureVideoOrientationPortrait; + } + */ + + [mCaptureSession startRunning]; + + grabFrame(60); + [localpool drain]; + return 1; + } + + [localpool drain]; + return 0; +} + +void CvCaptureCAM::setWidthHeight() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + NSDictionary* pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithDouble:1.0*width], (id)kCVPixelBufferWidthKey, + [NSNumber numberWithDouble:1.0*height], (id)kCVPixelBufferHeightKey, + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + + [mCaptureDecompressedVideoOutput setVideoSettings:pixelBufferOptions]; + grabFrame(60); + [localpool drain]; +} + +//added macros into headers in highgui_c.h +/* +#define CV_CAP_PROP_IOS_DEVICE_FOCUS 9001 +#define CV_CAP_PROP_IOS_DEVICE_EXPOSURE 9002 +#define CV_CAP_PROP_IOS_DEVICE_FLASH 9003 +#define CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE 9004 +#define CV_CAP_PROP_IOS_DEVICE_TORCH 9005 +*/ + + +/* +// All available settings are taken from iOS API + +enum { + AVCaptureFlashModeOff = 0, + AVCaptureFlashModeOn = 1, + AVCaptureFlashModeAuto = 2 +}; +typedef NSInteger AVCaptureFlashMode; + +enum { + AVCaptureTorchModeOff = 0, + AVCaptureTorchModeOn = 1, + AVCaptureTorchModeAuto = 2 +}; +typedef NSInteger AVCaptureTorchMode; + +enum { + AVCaptureFocusModeLocked = 0, + AVCaptureFocusModeAutoFocus = 1, + AVCaptureFocusModeContinuousAutoFocus = 2, +}; +typedef NSInteger AVCaptureFocusMode; + +enum { + AVCaptureExposureModeLocked = 0, + AVCaptureExposureModeAutoExpose = 1, + AVCaptureExposureModeContinuousAutoExposure = 2, +}; +typedef NSInteger AVCaptureExposureMode; + +enum { + AVCaptureWhiteBalanceModeLocked = 0, + AVCaptureWhiteBalanceModeAutoWhiteBalance = 1, + AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance = 2, +}; +typedef NSInteger AVCaptureWhiteBalanceMode; +*/ + +double CvCaptureCAM::getProperty(int property_id){ + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + /* + NSArray* connections = [mCaptureDeviceInput connections]; + QTFormatDescription* format = [[connections objectAtIndex:0] formatDescription]; + NSSize s1 = [[format attributeForKey:QTFormatDescriptionVideoCleanApertureDisplaySizeAttribute] sizeValue]; + */ + + NSArray* ports = mCaptureDeviceInput.ports; + CMFormatDescriptionRef format = [[ports objectAtIndex:0] formatDescription]; + CGSize s1 = CMVideoFormatDescriptionGetPresentationDimensions(format, YES, YES); + + int width=(int)s1.width, height=(int)s1.height; + + [localpool drain]; + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + return width; + case CV_CAP_PROP_FRAME_HEIGHT: + return height; + + case CV_CAP_PROP_IOS_DEVICE_FOCUS: + return mCaptureDevice.focusMode; + case CV_CAP_PROP_IOS_DEVICE_EXPOSURE: + return mCaptureDevice.exposureMode; + case CV_CAP_PROP_IOS_DEVICE_FLASH: + return mCaptureDevice.flashMode; + case CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE: + return mCaptureDevice.whiteBalanceMode; + case CV_CAP_PROP_IOS_DEVICE_TORCH: + return mCaptureDevice.torchMode; + + default: + return 0; + } + + +} + +bool CvCaptureCAM::setProperty(int property_id, double value) { + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + width = value; + settingWidth = 1; + if (settingWidth && settingHeight) { + setWidthHeight(); + settingWidth =0; + settingHeight = 0; + } + return true; + + case CV_CAP_PROP_FRAME_HEIGHT: + height = value; + settingHeight = 1; + if (settingWidth && settingHeight) { + setWidthHeight(); + settingWidth =0; + settingHeight = 0; + } + return true; + + case CV_CAP_PROP_IOS_DEVICE_FOCUS: + if ([mCaptureDevice isFocusModeSupported:(int)value]){ + NSError* error = nil; + [mCaptureDevice lockForConfiguration:&error]; + if (error) return false; + [mCaptureDevice setFocusMode:(int)value]; + [mCaptureDevice unlockForConfiguration]; + //NSLog(@"Focus set"); + return true; + }else { + return false; + } + + case CV_CAP_PROP_IOS_DEVICE_EXPOSURE: + if ([mCaptureDevice isExposureModeSupported:(int)value]){ + NSError* error = nil; + [mCaptureDevice lockForConfiguration:&error]; + if (error) return false; + [mCaptureDevice setExposureMode:(int)value]; + [mCaptureDevice unlockForConfiguration]; + //NSLog(@"Exposure set"); + return true; + }else { + return false; + } + + case CV_CAP_PROP_IOS_DEVICE_FLASH: + if ( [mCaptureDevice hasFlash] && [mCaptureDevice isFlashModeSupported:(int)value]){ + NSError* error = nil; + [mCaptureDevice lockForConfiguration:&error]; + if (error) return false; + [mCaptureDevice setFlashMode:(int)value]; + [mCaptureDevice unlockForConfiguration]; + //NSLog(@"Flash mode set"); + return true; + }else { + return false; + } + + case CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE: + if ([mCaptureDevice isWhiteBalanceModeSupported:(int)value]){ + NSError* error = nil; + [mCaptureDevice lockForConfiguration:&error]; + if (error) return false; + [mCaptureDevice setWhiteBalanceMode:(int)value]; + [mCaptureDevice unlockForConfiguration]; + //NSLog(@"White balance set"); + return true; + }else { + return false; + } + + case CV_CAP_PROP_IOS_DEVICE_TORCH: + if ([mCaptureDevice hasFlash] && [mCaptureDevice isTorchModeSupported:(int)value]){ + NSError* error = nil; + [mCaptureDevice lockForConfiguration:&error]; + if (error) return false; + [mCaptureDevice setTorchMode:(int)value]; + [mCaptureDevice unlockForConfiguration]; + //NSLog(@"Torch mode set"); + return true; + }else { + return false; + } + + case DISABLE_AUTO_RESTART: + disableAutoRestart = value; + return 1; + default: + return false; + } +} + + +/***************************************************************************** + * + * CaptureDelegate Implementation. + * + * CaptureDelegate is notified on a separate thread by the OS whenever there + * is a new frame. When "updateImage" is called from the main thread, it + * copies this new frame into an IplImage, but only if this frame has not + * been copied before. When "getOutput" is called from the main thread, + * it gives the last copied IplImage. + * + *****************************************************************************/ + + +@implementation CaptureDelegate + +- (id)init { + [super init]; + newFrame = 0; + imagedata = NULL; + bgr_imagedata = NULL; + currSize = 0; + image = NULL; + bgr_image = NULL; + bgr_image_r90 = NULL; + return self; +} + + +-(void)dealloc { + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + cvReleaseImage(&image); + cvReleaseImage(&bgr_image); + cvReleaseImage(&bgr_image_r90); + [super dealloc]; +} + + + +- (void)captureOutput:(AVCaptureOutput *)captureOutput +didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer +fromConnection:(AVCaptureConnection *)connection{ + + // Failed + // connection.videoOrientation = AVCaptureVideoOrientationPortrait; + + CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); + + CVBufferRetain(imageBuffer); + CVImageBufferRef imageBufferToRelease = mCurrentImageBuffer; + + @synchronized (self) { + + mCurrentImageBuffer = imageBuffer; + newFrame = 1; + } + + CVBufferRelease(imageBufferToRelease); + +} + + +-(IplImage*) getOutput { + //return bgr_image; + return bgr_image_r90; +} + +-(int) updateImage { + if (newFrame==0) return 0; + CVPixelBufferRef pixels; + + @synchronized (self){ + pixels = CVBufferRetain(mCurrentImageBuffer); + newFrame = 0; + } + + CVPixelBufferLockBaseAddress(pixels, 0); + uint32_t* baseaddress = (uint32_t*)CVPixelBufferGetBaseAddress(pixels); + + size_t width = CVPixelBufferGetWidth(pixels); + size_t height = CVPixelBufferGetHeight(pixels); + size_t rowBytes = CVPixelBufferGetBytesPerRow(pixels); + + if (rowBytes != 0) { + + if (currSize != rowBytes*height*sizeof(char)) { + currSize = rowBytes*height*sizeof(char); + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + imagedata = (char*)malloc(currSize); + bgr_imagedata = (char*)malloc(currSize); + } + + memcpy(imagedata, baseaddress, currSize); + + if (image == NULL) { + image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 4); + } + image->width =width; + image->height = height; + image->nChannels = 4; + image->depth = IPL_DEPTH_8U; + image->widthStep = (int)rowBytes; + image->imageData = imagedata; + image->imageSize = currSize; + + if (bgr_image == NULL) { + bgr_image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 3); + } + bgr_image->width =width; + bgr_image->height = height; + bgr_image->nChannels = 3; + bgr_image->depth = IPL_DEPTH_8U; + bgr_image->widthStep = (int)rowBytes; + bgr_image->imageData = bgr_imagedata; + bgr_image->imageSize = currSize; + + cvCvtColor(image, bgr_image, CV_BGRA2BGR); + + // image taken from the buffer is incorrected rotated. I'm using cvTranspose + cvFlip. + // There should be an option in iOS API to rotate the buffer output orientation. + // iOS provides hardware accelerated rotation through AVCaptureConnection class + // I can't get it work. + if (bgr_image_r90 == NULL){ + bgr_image_r90 = cvCreateImage(cvSize(height, width), IPL_DEPTH_8U, 3); + } + cvTranspose(bgr_image, bgr_image_r90); + cvFlip(bgr_image_r90, NULL, 1); + + } + + CVPixelBufferUnlockBaseAddress(pixels, 0); + CVBufferRelease(pixels); + + return 1; +} + +@end + + +/***************************************************************************** + * + * CvCaptureFile Implementation. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +CvCaptureFile::CvCaptureFile(const char* filename) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + mMovieReader = nil; + image = NULL; + bgr_image = NULL; + imagedata = NULL; + bgr_imagedata = NULL; + currSize = 0; + + movieWidth = 0; + movieHeight = 0; + movieFPS = 0; + currentFPS = 0; + movieDuration = 0; + changedPos = 0; + + started = 0; + + AVURLAsset *asset = [AVURLAsset URLAssetWithURL: + [NSURL fileURLWithPath: [NSString stringWithUTF8String:filename]] + options:nil]; + + AVAssetTrack* videoTrack = nil; + NSArray* tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; + if ([tracks count] == 1) + { + videoTrack = [tracks objectAtIndex:0]; + + movieWidth = videoTrack.naturalSize.width; + movieHeight = videoTrack.naturalSize.height; + movieFPS = videoTrack.nominalFrameRate; + + currentFPS = movieFPS; //Debugging !! should be getFPS(); + //Debugging. need to be checked + + // In ms + movieDuration = videoTrack.timeRange.duration.value/videoTrack.timeRange.duration.timescale * 1000; + + started = 1; + NSError* error = nil; + mMovieReader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; + if (error) + NSLog(@"%@", [error localizedDescription]); + + NSDictionary* videoSettings = + [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA] + forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; + + [mMovieReader addOutput:[AVAssetReaderTrackOutput + assetReaderTrackOutputWithTrack:videoTrack + outputSettings:videoSettings]]; + [mMovieReader startReading]; + } + + /* + // Asynchronously open the video in another thread. Always fail. + [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler: + ^{ + // The completion block goes here. + dispatch_async(dispatch_get_main_queue(), + ^{ + AVAssetTrack* ::videoTrack = nil; + NSArray* ::tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; + if ([tracks count] == 1) + { + videoTrack = [tracks objectAtIndex:0]; + + movieWidth = videoTrack.naturalSize.width; + movieHeight = videoTrack.naturalSize.height; + movieFPS = videoTrack.nominalFrameRate; + currentFPS = movieFPS; //Debugging !! should be getFPS(); + //Debugging. need to be checked + movieDuration = videoTrack.timeRange.duration.value/videoTrack.timeRange.duration.timescale * 1000; + started = 1; + + NSError* ::error = nil; + // mMovieReader is a member variable + mMovieReader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; + if (error) + NSLog(@"%@", [error localizedDescription]); + + NSDictionary* ::videoSettings = + [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA] +forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; + +[mMovieReader addOutput:[AVAssetReaderTrackOutput +assetReaderTrackOutputWithTrack:videoTrack +outputSettings:videoSettings]]; +[mMovieReader startReading]; +} +}); + +}]; + */ + +[localpool drain]; +} + +CvCaptureFile::~CvCaptureFile() { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + cvReleaseImage(&image); + cvReleaseImage(&bgr_image); + [mMovieReader release]; + [localpool drain]; +} + +int CvCaptureFile::didStart() { + return started; +} + +bool CvCaptureFile::grabFrame() { + + //everything is done in queryFrame; + currentFPS = movieFPS; + return 1; + + + /* + double t1 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepForward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + if (t2>t1 && !changedPos) { + currentFPS = 1000.0/(t2-t1); + } else { + currentFPS = movieFPS; + } + changedPos = 0; + + */ + +} + + +IplImage* CvCaptureFile::retrieveFramePixelBuffer() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + if (mMovieReader.status != AVAssetReaderStatusReading){ + + return NULL; + } + + + AVAssetReaderTrackOutput * output = [mMovieReader.outputs objectAtIndex:0]; + CMSampleBufferRef sampleBuffer = [output copyNextSampleBuffer]; + if (!sampleBuffer) { + [localpool drain]; + return NULL; + } + CVPixelBufferRef frame = CMSampleBufferGetImageBuffer(sampleBuffer); + CVPixelBufferRef pixels = CVBufferRetain(frame); + + CVPixelBufferLockBaseAddress(pixels, 0); + + uint32_t* baseaddress = (uint32_t*)CVPixelBufferGetBaseAddress(pixels); + size_t width = CVPixelBufferGetWidth(pixels); + size_t height = CVPixelBufferGetHeight(pixels); + size_t rowBytes = CVPixelBufferGetBytesPerRow(pixels); + + if (rowBytes != 0) { + + if (currSize != rowBytes*height*sizeof(char)) { + currSize = rowBytes*height*sizeof(char); + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + imagedata = (char*)malloc(currSize); + bgr_imagedata = (char*)malloc(currSize); + } + + memcpy(imagedata, baseaddress, currSize); + + if (image == NULL) { + image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 4); + } + + image->width =width; + image->height = height; + image->nChannels = 4; + image->depth = IPL_DEPTH_8U; + image->widthStep = rowBytes; + image->imageData = imagedata; + image->imageSize = currSize; + + + if (bgr_image == NULL) { + bgr_image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 3); + } + + bgr_image->width =width; + bgr_image->height = height; + bgr_image->nChannels = 3; + bgr_image->depth = IPL_DEPTH_8U; + bgr_image->widthStep = rowBytes; + bgr_image->imageData = bgr_imagedata; + bgr_image->imageSize = currSize; + + cvCvtColor(image, bgr_image,CV_BGRA2BGR); + + } + + CVPixelBufferUnlockBaseAddress(pixels, 0); + CVBufferRelease(pixels); + CMSampleBufferInvalidate(sampleBuffer); + CFRelease(sampleBuffer); + + [localpool drain]; + return bgr_image; +} + + +IplImage* CvCaptureFile::retrieveFrame(int) { + return retrieveFramePixelBuffer(); +} + +IplImage* CvCaptureFile::queryFrame() { + grabFrame(); + return retrieveFrame(0); +} + +double CvCaptureFile::getFPS() { + + /* + if (mCaptureSession == nil) return 0; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + double now = getProperty(CV_CAP_PROP_POS_MSEC); + double retval = 0; + if (now == 0) { + [mCaptureSession stepForward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepBackward]; + retval = 1000.0 / (t2-now); + } else { + [mCaptureSession stepBackward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepForward]; + retval = 1000.0 / (now-t2); + } + [localpool drain]; + return retval; + */ + return 30.0; //TODO: Debugging +} + +double CvCaptureFile::getProperty(int property_id){ + + /* + if (mCaptureSession == nil) return 0; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + double retval; + QTTime t; + + switch (property_id) { + case CV_CAP_PROP_POS_MSEC: + [[mCaptureSession attributeForKey:QTMovieCurrentTimeAttribute] getValue:&t]; + retval = t.timeValue * 1000.0 / t.timeScale; + break; + case CV_CAP_PROP_POS_FRAMES: + retval = movieFPS * getProperty(CV_CAP_PROP_POS_MSEC) / 1000; + break; + case CV_CAP_PROP_POS_AVI_RATIO: + retval = (getProperty(CV_CAP_PROP_POS_MSEC)) / (movieDuration ); + break; + case CV_CAP_PROP_FRAME_WIDTH: + retval = movieWidth; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + retval = movieHeight; + break; + case CV_CAP_PROP_FPS: + retval = currentFPS; + break; + case CV_CAP_PROP_FOURCC: + default: + retval = 0; + } + + [localpool drain]; + return retval; + */ + return 1.0; //Debugging +} + +bool CvCaptureFile::setProperty(int property_id, double value) { + + /* + if (mCaptureSession == nil) return false; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + bool retval = false; + QTTime t; + + double ms; + + switch (property_id) { + case CV_CAP_PROP_POS_MSEC: + [[mCaptureSession attributeForKey:QTMovieCurrentTimeAttribute] getValue:&t]; + t.timeValue = value * t.timeScale / 1000; + [mCaptureSession setCurrentTime:t]; + changedPos = 1; + retval = true; + break; + case CV_CAP_PROP_POS_FRAMES: + ms = (value*1000.0 -5)/ currentFPS; + retval = setProperty(CV_CAP_PROP_POS_MSEC, ms); + break; + case CV_CAP_PROP_POS_AVI_RATIO: + ms = value * movieDuration; + retval = setProperty(CV_CAP_PROP_POS_MSEC, ms); + break; + case CV_CAP_PROP_FRAME_WIDTH: + //retval = movieWidth; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + //retval = movieHeight; + break; + case CV_CAP_PROP_FPS: + //etval = currentFPS; + break; + case CV_CAP_PROP_FOURCC: + default: + retval = false; + } + + [localpool drain]; + + return retval; + */ + return true; +} + + +/***************************************************************************** + * + * CvVideoWriter Implementation. + * + * CvVideoWriter is the instantiation of a video output class + * + *****************************************************************************/ + + +CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + + frameCount = 0; + movieFPS = fps; + movieSize = frame_size; + movieColor = is_color; + argbimage = cvCreateImage(movieSize, IPL_DEPTH_8U, 4); + path = [[[NSString stringWithCString:filename encoding:NSASCIIStringEncoding] stringByExpandingTildeInPath] retain]; + + + /* + AVFileTypeQuickTimeMovie + UTI for the QuickTime movie file format. + The value of this UTI is com.apple.quicktime-movie. Files are identified with the .mov and .qt extensions. + + AVFileTypeMPEG4 + UTI for the MPEG-4 file format. + The value of this UTI is public.mpeg-4. Files are identified with the .mp4 extension. + + AVFileTypeAppleM4V + UTI for the iTunes video file format. + The value of this UTI is com.apple.mpeg-4-video. Files are identified with the .m4v extension. + + AVFileType3GPP + UTI for the 3GPP file format. + The value of this UTI is public.3gpp. Files are identified with the .3gp, .3gpp, and .sdv extensions. + */ + + NSString *fileExt =[[[path pathExtension] lowercaseString] copy]; + if ([fileExt isEqualToString:@"mov"] || [fileExt isEqualToString:@"qt"]){ + fileType = [AVFileTypeQuickTimeMovie copy]; + }else if ([fileExt isEqualToString:@"mp4"]){ + fileType = [AVFileTypeMPEG4 copy]; + }else if ([fileExt isEqualToString:@"m4v"]){ + fileType = [AVFileTypeAppleM4V copy]; +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + }else if ([fileExt isEqualToString:@"3gp"] || [fileExt isEqualToString:@"3gpp"] || [fileExt isEqualToString:@"sdv"] ){ + fileType = [AVFileType3GPP copy]; +#endif + } else{ + fileType = [AVFileTypeMPEG4 copy]; //default mp4 + } + [fileExt release]; + + char cc[5]; + cc[0] = fourcc & 255; + cc[1] = (fourcc >> 8) & 255; + cc[2] = (fourcc >> 16) & 255; + cc[3] = (fourcc >> 24) & 255; + cc[4] = 0; + int cc2 = CV_FOURCC(cc[0], cc[1], cc[2], cc[3]); + if (cc2!=fourcc) { + cout << "WARNING: Didn't properly encode FourCC. Expected " << fourcc + << " but got " << cc2 << "." << endl; + //exception; + } + + // Two codec supported AVVideoCodecH264 AVVideoCodecJPEG + // On iPhone 3G H264 is not supported. + if (fourcc == CV_FOURCC('J','P','E','G') || fourcc == CV_FOURCC('j','p','e','g') || + fourcc == CV_FOURCC('M','J','P','G') || fourcc == CV_FOURCC('m','j','p','g') ){ + codec = [AVVideoCodecJPEG copy]; // Use JPEG codec if specified, otherwise H264 + }else if(fourcc == CV_FOURCC('H','2','6','4') || fourcc == CV_FOURCC('a','v','c','1')){ + codec = [AVVideoCodecH264 copy]; + }else{ + codec = [AVVideoCodecH264 copy]; // default canonical H264. + + } + + //NSLog(@"Path: %@", path); + + NSError *error = nil; + + + // Make sure the file does not already exist. Necessary to overwirte?? + /* + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:path]){ + [fileManager removeItemAtPath:path error:&error]; + } + */ + + // Wire the writer: + // Supported file types: + // AVFileTypeQuickTimeMovie AVFileTypeMPEG4 AVFileTypeAppleM4V AVFileType3GPP + + mMovieWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:path] + fileType:fileType + error:&error]; + //NSParameterAssert(mMovieWriter); + + NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: + codec, AVVideoCodecKey, + [NSNumber numberWithInt:movieSize.width], AVVideoWidthKey, + [NSNumber numberWithInt:movieSize.height], AVVideoHeightKey, + nil]; + + mMovieWriterInput = [[AVAssetWriterInput + assetWriterInputWithMediaType:AVMediaTypeVideo + outputSettings:videoSettings] retain]; + + //NSParameterAssert(mMovieWriterInput); + //NSParameterAssert([mMovieWriter canAddInput:mMovieWriterInput]); + + [mMovieWriter addInput:mMovieWriterInput]; + + mMovieWriterAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:mMovieWriterInput sourcePixelBufferAttributes:nil]; + + + //Start a session: + [mMovieWriter startWriting]; + [mMovieWriter startSessionAtSourceTime:kCMTimeZero]; + + + if(mMovieWriter.status == AVAssetWriterStatusFailed){ + NSLog(@"%@", [mMovieWriter.error localizedDescription]); + // TODO: error handling, cleanup. Throw execption? + // return; + } + + [localpool drain]; +} + + +CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + [mMovieWriterInput markAsFinished]; + [mMovieWriter finishWriting]; + [mMovieWriter release]; + [mMovieWriterInput release]; + [mMovieWriterAdaptor release]; + [path release]; + [codec release]; + [fileType release]; + cvReleaseImage(&argbimage); + + [localpool drain]; + +} + +bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + // writer status check + if (![mMovieWriterInput isReadyForMoreMediaData] || mMovieWriter.status != AVAssetWriterStatusWriting ) { + NSLog(@"[mMovieWriterInput isReadyForMoreMediaData] Not ready for media data or ..."); + NSLog(@"mMovieWriter.status: %d. Error: %@", mMovieWriter.status, [mMovieWriter.error localizedDescription]); + [localpool drain]; + return false; + } + + BOOL success = FALSE; + + if (iplimage->height!=movieSize.height || iplimage->width!=movieSize.width){ + cout<<"Frame size does not match video size."<nChannels == 3); + cvCvtColor(iplimage, argbimage, CV_BGR2BGRA); + }else{ + //assert(iplimage->nChannels == 1); + cvCvtColor(iplimage, argbimage, CV_GRAY2BGRA); + } + //IplImage -> CGImage conversion + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + NSData *nsData = [NSData dataWithBytes:argbimage->imageData length:argbimage->imageSize]; + CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)nsData); + CGImageRef cgImage = CGImageCreate(argbimage->width, argbimage->height, + argbimage->depth, argbimage->depth * argbimage->nChannels, argbimage->widthStep, + colorSpace, kCGImageAlphaLast|kCGBitmapByteOrderDefault, + provider, NULL, false, kCGRenderingIntentDefault); + + //CGImage -> CVPixelBufferRef coversion + CVPixelBufferRef pixelBuffer = NULL; + CFDataRef cfData = CGDataProviderCopyData(CGImageGetDataProvider(cgImage)); + int status = CVPixelBufferCreateWithBytes(NULL, + movieSize.width, + movieSize.height, + kCVPixelFormatType_32BGRA, + (void*)CFDataGetBytePtr(cfData), + CGImageGetBytesPerRow(cgImage), + NULL, + 0, + NULL, + &pixelBuffer); + if(status == kCVReturnSuccess){ + success = [mMovieWriterAdaptor appendPixelBuffer:pixelBuffer + withPresentationTime:CMTimeMake(frameCount, movieFPS)]; + } + + //cleanup + CGImageRelease(cgImage); + CGDataProviderRelease(provider); + CGColorSpaceRelease(colorSpace); + + [localpool drain]; + + if (success) { + frameCount ++; + //NSLog(@"Frame #%d", frameCount); + return true; + }else{ + NSLog(@"Frame appendPixelBuffer failed."); + return false; + } + +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_cmu.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_cmu.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_cmu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_cmu.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,551 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef WIN32 + +/****************** Capturing video from camera via CMU lib *******************/ + +#ifdef HAVE_CMU1394 + +// This firewire capability added by Philip Gruebele (pgruebele@cox.net). +// For this to work you need to install the CMU firewire DCAM drivers, +// located at http://www-2.cs.cmu.edu/~iwan/1394/. +#include "1394camera.h" + +class CvCaptureCAM_CMU : public CvCapture +{ +public: + CvCaptureCAM_CMU() + { + index = -1; + image = 0; + } + + virtual ~CvCaptureCAM_CMU() + { + close(); + } + + virtual bool open(int cameraId); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + +protected: + C1394Camera* camera(); + CvSize getSize(); + int getDepth(); + int getNChannels(); + + bool setVideoSize(int, int); + bool setMode(int mode); + bool setFrameRate(int rate); + bool setFormat(int format); + + int fps; // 0-5 + int mode; // 0-7 + int format; // 0-2, 7 ? + int index; + IplImage* image; +}; + +// CMU 1394 camera stuff. +// This firewire capability added by Philip Gruebele (pgruebele@cox.net) +// and modified by Roman Stanchak (rstanchak@yahoo.com). +// For this to work you need to install the CMU firewire DCAM drivers, +// located at http://www-2.cs.cmu.edu/~iwan/1394/. +#define CMU_MAX_CAMERAS 20 +int CMU_numCameras = 0; +int CMU_numActiveCameras = 0; +bool CMU_useCameraFlags[CMU_MAX_CAMERAS]; +C1394Camera *CMU_theCamera = 0; + +// stupid defines for mode, format, FPS +#define CV_CAP_IEEE1394_FPS_1_875 0 +#define CV_CAP_IEEE1394_FPS_3_75 1 +#define CV_CAP_IEEE1394_FPS_7_5 2 +#define CV_CAP_IEEE1394_FPS_15 3 +#define CV_CAP_IEEE1394_FPS_30 4 +#define CV_CAP_IEEE1394_FPS_60 5 + +// index by size, color +#define CV_CAP_IEEE1394_COLOR_MONO 0 +#define CV_CAP_IEEE1394_COLOR_MONO16 1 +#define CV_CAP_IEEE1394_COLOR_YUV444 2 +#define CV_CAP_IEEE1394_COLOR_YUV422 3 +#define CV_CAP_IEEE1394_COLOR_YUV411 4 +#define CV_CAP_IEEE1394_COLOR_RGB 5 + +#define CV_CAP_IEEE1394_SIZE_160X120 0 +#define CV_CAP_IEEE1394_SIZE_320X240 1 +#define CV_CAP_IEEE1394_SIZE_640X480 2 +#define CV_CAP_IEEE1394_SIZE_800X600 3 +#define CV_CAP_IEEE1394_SIZE_1024X768 4 +#define CV_CAP_IEEE1394_SIZE_1280X960 5 +#define CV_CAP_IEEE1394_SIZE_1600X1200 6 + +// given color, size, output format +// 1 16 444 422 411 RGB +static char CV_CAP_IEEE1394_FORMAT[7][6] = +{ + {-1, -1, 0, -1, -1, -1}, // 160x120 + {-1, -1, -1, 0, -1, -1}, // 320x240 + { 0, 0, -1, 0, 0, 0}, // 640x480 + { 1, 1, -1, 1, -1, 1}, // 800x600 + { 1, 1, -1, 1, -1, 1}, // 1024x768 + { 2, 2, -1, 2, -1, 2}, // 1280x960 + { 2, 2, -1, 2, -1, 2} // 1600x1200 +}; + +// given color, size, output corresponding mode +static char CV_CAP_IEEE1394_MODE[7][6] = +{ + {-1, -1, 0, -1, -1, -1}, // 160x120 + {-1, -1, -1, 1, -1, -1}, // 320x240 + { 5, 6, -1, 3, 2, 4}, // 640x480 + { 2, 6, -1, 0, -1, 1}, // 800x600 + { 5, 7, -1, 3, -1, 4}, // 1024x768 + { 2, 6, -1, 0, -1, 1}, // 1280x960 + { 5, 7, -1, 3, -1, 4} // 1600x1200 +}; + +// given format, mode, return COLOR +static char CV_CAP_IEEE1394_COLOR[2][8] = +{ + { + CV_CAP_IEEE1394_COLOR_YUV444, + CV_CAP_IEEE1394_COLOR_YUV422, + CV_CAP_IEEE1394_COLOR_YUV411, + CV_CAP_IEEE1394_COLOR_YUV422, + CV_CAP_IEEE1394_COLOR_RGB, + CV_CAP_IEEE1394_COLOR_MONO, + CV_CAP_IEEE1394_COLOR_MONO16 + }, + { + CV_CAP_IEEE1394_COLOR_YUV422, + CV_CAP_IEEE1394_COLOR_RGB, + CV_CAP_IEEE1394_COLOR_MONO, + CV_CAP_IEEE1394_COLOR_YUV422, + CV_CAP_IEEE1394_COLOR_RGB, + CV_CAP_IEEE1394_COLOR_MONO, + CV_CAP_IEEE1394_COLOR_MONO16, + CV_CAP_IEEE1394_COLOR_MONO16 + } +}; + +// convert frame rate to suitable enum +/*static int icvFrameRateToIndex_CMU(double framerate){ + if(framerate > 30) return CV_CAP_IEEE1394_FPS_60; + else if(framerate > 15) return CV_CAP_IEEE1394_FPS_30; + else if(framerate > 7.5) return CV_CAP_IEEE1394_FPS_15; + else if(framerate > 3.75) return CV_CAP_IEEE1394_FPS_7_5; + else if(framerate > 1.875) return CV_CAP_IEEE1394_FPS_3_75; + return CV_CAP_IEEE1394_FPS_1_875; +}*/ + +#if _MSC_VER >= 1200 +#pragma comment(lib,"1394camera.lib") +#endif + +C1394Camera* CvCaptureCAM_CMU::camera() +{ + return CMU_theCamera && index >= 0 ? &CMU_theCamera[index] : 0; +} + +// return the size of the image +CvSize CvCaptureCAM_CMU::getSize() +{ + C1394Camera* cmucam = camera(); + unsigned long width = 0, height = 0; + cmucam->GetVideoFrameDimensions( &width, &height ); + return cvSize((int)width, (int)height); +} + +// return the opencv depth flag corresponding to the camera format +int CvCaptureCAM_CMU::getDepth() +{ + C1394Camera* cmucam = camera(); + int format = cmucam->GetVideoFormat(); + int mode = cmucam->GetVideoMode(); + + // TODO + if( format==7 ) { + assert(0); + return 1; + } + // irrelvant to depth + if( format > 1 ) + format = 1; + + if( CV_CAP_IEEE1394_COLOR[format][mode]==CV_CAP_IEEE1394_COLOR_MONO16 ) + return IPL_DEPTH_16S; + + return IPL_DEPTH_8U; +} + +// return the number of channels for camera +int CvCaptureCAM_CMU::getNChannels() +{ + C1394Camera* cmucam = camera(); + int format = cmucam->GetVideoFormat(); + int mode = cmucam->GetVideoMode(); + + if( format==7 ){ + assert(0); + return 1; + } + + // irrelvant to nchannels + if( format > 1 ) + format = 1; + + switch(CV_CAP_IEEE1394_COLOR[format][mode]){ + case CV_CAP_IEEE1394_COLOR_RGB: + return 3; + case CV_CAP_IEEE1394_COLOR_MONO: + case CV_CAP_IEEE1394_COLOR_MONO16: + return 1; + case CV_CAP_IEEE1394_COLOR_YUV422: + case CV_CAP_IEEE1394_COLOR_YUV444: + case CV_CAP_IEEE1394_COLOR_YUV411: + return 3; + default: + ; + } + return -1; +} + +bool CvCaptureCAM_CMU::open( int _index ) +{ + close(); + + // if first time, then allocate all available cameras + if( CMU_numCameras == 0 ) + { + CMU_numActiveCameras = 0; + CMU_theCamera = new C1394Camera[CMU_MAX_CAMERAS]; + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + // create all cameras + try + { + // create camera0 + if( CMU_theCamera[0].CheckLink() != CAM_SUCCESS ) + throw 1; + + // we have one pin per camera + CMU_numCameras = CMU_theCamera[0].GetNumberCameras(); + + // allocate remaining cameras + for(int i = 1; i < CMU_numCameras && i=0 && !found_format; rate--) + { + for (int color=CV_CAP_IEEE1394_COLOR_RGB; color>=0 && !found_format; color--) + { + for (int size=CV_CAP_IEEE1394_SIZE_1600X1200; size>=0 && !found_format; size--) + { + int format = CV_CAP_IEEE1394_FORMAT[size][color]; + int mode = CV_CAP_IEEE1394_MODE[size][color]; + if (format!=-1 && mode!=-1 && + CMU_theCamera[_index].HasVideoFrameRate(format,mode,rate)) + { + CMU_theCamera[_index].SetVideoFormat(format); + CMU_theCamera[_index].SetVideoMode(mode); + CMU_theCamera[_index].SetVideoFrameRate(rate); + found_format = (CMU_theCamera[_index].StartImageAcquisition() == CAM_SUCCESS); + } + } + } + } + + // try format 7 + if(!found_format){ + CMU_theCamera[_index].SetVideoFormat(7); + CMU_theCamera[_index].SetVideoMode(0); + if(CMU_theCamera[_index].StartImageAcquisition() != CAM_SUCCESS){ + // no format found + throw 9; + } + } + + index = _index; + size = getSize(); + // allocate image frame + image = cvCreateImage( size, 8, 3 ); + cvZero(image); + + // successfully activated camera + CMU_numActiveCameras++; + CMU_useCameraFlags[_index] = true; + } + catch ( int ) + { + return false; + } + + return true; +} + +void CvCaptureCAM_CMU::close() +{ + C1394Camera* cmucam = camera(); + if( cmucam ) + { + cvReleaseImage( &image ); + cmucam->StopImageAcquisition(); + CMU_useCameraFlags[index] = false; + index = -1; + + if( --CMU_numActiveCameras == 0 ) + { + delete[] CMU_theCamera; + CMU_theCamera = 0; + CMU_numCameras = 0; + } + } +} + + +bool CvCaptureCAM_CMU::grabFrame() +{ + C1394Camera* cmucam = camera(); + return cmucam ? cmucam->AcquireImage() == CAM_SUCCESS : false; +} + +/*static void swapRedBlue(IplImage * im) +{ + uchar * ptr = (uchar *) im->imageData; + uchar t; + for(int i=0; iheight; i++){ + ptr = (uchar *) im->imageData+im->widthStep*i; + for(int j=0; jwidth; j++){ + t = ptr[0]; + ptr[0] = ptr[2]; + ptr[2] = t; + ptr+=3; + } + } +}*/ + +IplImage* CvCaptureCAM_CMU::retrieveFrame(int) +{ + C1394Camera* cmucam = camera(); + if( !cmucam ) + return 0; + cmucam->getRGB((uchar*)image->imageData, image->imageSize); + cvConvertImage( image, image, CV_CVTIMG_SWAP_RB ); + return image; +} + + +double CvCaptureCAM_CMU::getProperty( int property_id ) +{ + C1394Camera* cmucam = camera(); + if( !cmucam ) + return 0; + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return image->width; + case CV_CAP_PROP_FRAME_HEIGHT: + return image->height; + case CV_CAP_PROP_FPS: + return cmucam->GetVideoFrameRate(); + case CV_CAP_PROP_MODE: + return cmucam->GetVideoMode(); + case CV_CAP_PROP_FORMAT: + return cmucam->GetVideoFormat(); + } + return 0; +} + +bool CvCaptureCAM_CMU::setVideoSize(int, int) +{ + return false; +} + +bool CvCaptureCAM_CMU::setMode(int mode) +{ + int format; + C1394Camera* cmucam = camera(); + if( !cmucam ) + return false; + format = cmucam->GetVideoFormat(); + if( mode < 0 || mode > 7 || !cmucam->HasVideoMode(format, mode)) + return false; + cmucam->StopImageAcquisition(); + cmucam->SetVideoMode(mode); + cmucam->StartImageAcquisition(); + return true; +} + +bool CvCaptureCAM_CMU::setFrameRate(int rate) +{ + int format, mode; + C1394Camera* cmucam = camera(); + if( !cmucam ) + return false; + mode = cmucam->GetVideoMode(); + format = cmucam->GetVideoFormat(); + if( rate < 0 || rate > 5 || !cmucam->HasVideoFrameRate(format, mode, rate) ) + return false; + cmucam->StopImageAcquisition(); + cmucam->SetVideoFrameRate(rate); + cmucam->StartImageAcquisition(); + return true; +} + +bool CvCaptureCAM_CMU::setFormat(int format) +{ + C1394Camera* cmucam = camera(); + if( !cmucam ) + return false; + if( format < 0 || format > 2 || !cmucam->HasVideoFormat(format) ) + return false; + cmucam->StopImageAcquisition(); + cmucam->SetVideoFormat(format); + cmucam->StartImageAcquisition(); + return true; +} + +bool CvCaptureCAM_CMU::setProperty( int property_id, double value ) +{ + bool retval = false; + int ival = cvRound(value); + C1394Camera* cmucam = camera(); + if( !cmucam ) + return false; + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + case CV_CAP_PROP_FRAME_HEIGHT: + { + int width, height; + if (property_id == CV_CAP_PROP_FRAME_WIDTH) + { + width = ival; + height = width*3/4; + } + else { + height = ival; + width = height*4/3; + } + retval = setVideoSize(width, height); + } + break; + case CV_CAP_PROP_FPS: + retval = setFrameRate(ival); + break; + case CV_CAP_PROP_MODE: + retval = setMode(ival); + break; + case CV_CAP_PROP_FORMAT: + retval = setFormat(ival); + break; + } + + // resize image if its not the right size anymore + CvSize size = getSize(); + if( !image || image->width != size.width || image->height != size.height ) + { + cvReleaseImage( &image ); + image = cvCreateImage( size, 8, 3 ); + } + return retval; +} + +CvCapture * cvCreateCameraCapture_CMU (int index) +{ + CvCaptureCAM_CMU* capture = new CvCaptureCAM_CMU; + if( capture->open(index) ) + return capture; + delete capture; + return 0; +} + +#endif // CMU +#endif // WIN32 diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dc1394.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dc1394.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dc1394.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dc1394.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1121 @@ +/* This is the contributed code: +Firewire and video4linux camera support for highgui + +2003-03-12 Magnus Lundin +lundin@mlu.mine.nu + +THIS EXEPERIMENTAL CODE +Tested on 2.4.19 with 1394, video1394, v4l, dc1394 and raw1394 support + +This set of files adds support for firevre and usb cameras. +First it tries to install a firewire camera, +if that fails it tries a v4l/USB camera + +It has been tested with the motempl sample program + +INSTALLATION +Install OpenCV +Install v4l +Install dc1394 raw1394 - coriander should work with your camera + Backup highgui folder + Copy new files + cd into highgui folder + make clean (cvcap.cpp must be rebuilt) + make + make install + + +The build is controlled by the following entries in the highgui Makefile: + +libhighgui_la_LIBADD = -L/usr/X11R6/lib -lXm -lMrm -lUil -lpng -ljpeg -lz -ltiff -lavcodec -lraw1394 -ldc1394_control +DEFS = -DHAVE_CONFIG_H -DHAVE_DC1394 HAVE_CAMV4L + + +Now it should be possible to use highgui camera functions, works for me. + + +THINGS TO DO +Better ways to select 1394 or v4l camera +Better support for videosize +Format7 + +Comments and changes welcome +/Magnus + +2005-10-19 Roman Stanchak +rstanchak@yahoo.com + +Support added for setting MODE and other DC1394 properties. Also added CONVERT_RGB flag +which indicates whether or not color conversion is performed in cvRetrieveFrame. The default +for CONVERT_RGB=1 for backward compatibility. + +Tested with 2.6.12 with libdc1394-1.0.0, libraw1394-0.10.1 using a Point Grey Flea + +*/ + + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if !defined WIN32 && defined HAVE_DC1394 + +#include +#include +#include +#include + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +#define CV_DC1394_CALL(expr) \ +if((expr)<0){ \ + OPENCV_ERROR(CV_StsInternal, "", "libdc1394 function call returned < 0"); \ +} + +#define DELAY 50000 + +// bpp for 16-bits cameras... this value works for PtGrey DragonFly... +#define MONO16_BPP 8 + +/* should be in pixelformat */ +static void uyv2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels); +static void uyvy2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels); +static void uyyvyy2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels); +static void y2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels); +static void y162bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits); +static void rgb482bgr(const unsigned char *src8, unsigned char *dest, unsigned long long int NumPixels, int bits); + +static const char * videodev[4]={ + "/dev/video1394/0", + "/dev/video1394/1", + "/dev/video1394/2", + "/dev/video1394/3" +}; + +typedef struct CvCaptureCAM_DC1394 +{ + raw1394handle_t handle; + nodeid_t camera_node; + dc1394_cameracapture* camera; + int format; + int mode; + int color_mode; + int frame_rate; + const char * device_name; + IplImage frame; + int convert; + int buffer_is_writeable; // indicates whether frame.imageData is allocated by OpenCV or DC1394 +} +CvCaptureCAM_DC1394; + +static void icvCloseCAM_DC1394( CvCaptureCAM_DC1394* capture ); + +static int icvGrabFrameCAM_DC1394( CvCaptureCAM_DC1394* capture ); +static IplImage* icvRetrieveFrameCAM_DC1394( CvCaptureCAM_DC1394* capture, int ); + +static double icvGetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id ); +static int icvSetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id, double value ); + +// utility functions +static int icvFormatSupportedCAM_DC1394(int format, quadlet_t formats); +static int icvModeSupportedCAM_DC1394(int format, int mode, quadlet_t modes); +static int icvColorMode( int mode ); +static unsigned int icvGetBestFrameRate( CvCaptureCAM_DC1394 * capture, int format, int mode); +static int icvResizeFrame(CvCaptureCAM_DC1394 * capture); + +/*********************** Implementations ***************************************/ +#define MAX_PORTS 3 +#define MAX_CAMERAS 8 +#define NUM_BUFFERS 8 +struct raw1394_portinfo ports[MAX_PORTS]; +static raw1394handle_t handles[MAX_PORTS]; +static int camCount[MAX_PORTS]; +static int numPorts = -1; +static int numCameras = 0; +static nodeid_t *camera_nodes; +struct camnode {dc1394_cameracapture cam;int portnum;} cameras[MAX_CAMERAS]; + +static const int preferred_modes[] += { + // uncomment the following line to test a particular mode: + //FORMAT_VGA_NONCOMPRESSED, MODE_640x480_MONO16, 0, + FORMAT_SVGA_NONCOMPRESSED_2, + MODE_1600x1200_RGB, MODE_1600x1200_YUV422, MODE_1280x960_RGB, MODE_1280x960_YUV422, + MODE_1600x1200_MONO, MODE_1280x960_MONO, MODE_1600x1200_MONO16, MODE_1280x960_MONO16, + FORMAT_SVGA_NONCOMPRESSED_1, + MODE_1024x768_RGB, MODE_1024x768_YUV422, MODE_800x600_RGB, MODE_800x600_YUV422, + MODE_1024x768_MONO, MODE_800x600_MONO, MODE_1024x768_MONO16, MODE_800x600_MONO16, + FORMAT_VGA_NONCOMPRESSED, + MODE_640x480_RGB, MODE_640x480_YUV422, MODE_640x480_YUV411, MODE_320x240_YUV422, + MODE_160x120_YUV444, MODE_640x480_MONO, MODE_640x480_MONO16, + FORMAT_SCALABLE_IMAGE_SIZE, + MODE_FORMAT7_0, MODE_FORMAT7_1, MODE_FORMAT7_2, MODE_FORMAT7_3, + MODE_FORMAT7_4, MODE_FORMAT7_5, MODE_FORMAT7_6, MODE_FORMAT7_7, + 0 +}; + +void icvInitCapture_DC1394(){ + int p; + + raw1394handle_t raw_handle = raw1394_new_handle(); + if( raw_handle == 0 ) { + numPorts = 0; + return; + } + numPorts = raw1394_get_port_info(raw_handle, ports, MAX_PORTS); + raw1394_destroy_handle(raw_handle); + for (p = 0; p < numPorts; p++) { + handles[p] = dc1394_create_handle(p); + if (handles[p]==NULL) { numPorts=-1; return; /*ERROR_CLEANUP_EXIT*/ } + + /* get the camera nodes and describe them as we find them */ + camera_nodes = dc1394_get_camera_nodes(handles[p], &camCount[p], 0); + for (int i=0;i=numCameras) + return 0; + if (index<0) + return 0; + + CvCaptureCAM_DC1394 * pcap = (CvCaptureCAM_DC1394*)cvAlloc(sizeof(*pcap)); + + /* Select a port and camera */ + pcap->device_name = videodev[cameras[index].portnum]; + pcap->handle = handles[cameras[index].portnum]; + pcap->camera = &cameras[index].cam; + + // get supported formats + if (dc1394_query_supported_formats(pcap->handle, pcap->camera->node, &formats)<0) { + fprintf(stderr,"%s:%d: Could not query supported formats\n",__FILE__,__LINE__); + formats=0x0; + } + for (i=0; i < NUM_FORMATS; i++) { + modes[i]=0; + if (icvFormatSupportedCAM_DC1394(i+FORMAT_MIN, formats)){ + if (dc1394_query_supported_modes(pcap->handle, pcap->camera->node, i+FORMAT_MIN, &modes[i])<0) { + fprintf(stderr,"%s:%d: Could not query Format%d modes\n",__FILE__,__LINE__,i); + } + } + } + + pcap->format = 0; + pcap->mode = 0; + pcap->color_mode = 0; + pcap->frame_rate = 0; + + int format_idx = -1; + + // scan the list of preferred modes, and find a supported one + for(i=0; (pcap->mode == 0) && (preferred_modes[i] != 0); i++) { + if((preferred_modes[i] >= FORMAT_MIN) && (preferred_modes[i] <= FORMAT_MAX)) { + pcap->format = preferred_modes[i]; + format_idx = preferred_modes[i] - FORMAT_MIN; + continue; + } + assert(format_idx != -1); + if ( ! icvFormatSupportedCAM_DC1394(pcap->format, formats) ) + continue; + if ( icvModeSupportedCAM_DC1394(pcap->format, preferred_modes[i], modes[format_idx]) ){ + pcap->mode = preferred_modes[i]; + } + } + if (pcap->mode == 0) { + fprintf(stderr,"%s:%d: Could not find a supported mode for this camera\n",__FILE__,__LINE__); + goto ERROR; + } + + pcap->color_mode = icvColorMode( pcap->mode ); + if( pcap->color_mode == -1){ + fprintf(stderr,"%s:%d: ERROR: BPP is Unsupported!!\n",__FILE__,__LINE__); + goto ERROR; + } + + // set frame rate to optimal value given format and mode + pcap->frame_rate = icvGetBestFrameRate(pcap, pcap->format, pcap->mode); + + if (pcap->format!=FORMAT_SCALABLE_IMAGE_SIZE) { // everything except Format 7 + if (dc1394_dma_setup_capture(pcap->handle, pcap->camera->node, index+1 /*channel*/, + pcap->format, pcap->mode, SPEED_400, + pcap->frame_rate, NUM_BUFFERS, +#ifdef HAVE_DC1394_095 + 0 /*do_extra_buffering*/, +#endif + 1 /*DROP_FRAMES*/, + pcap->device_name, pcap->camera) != DC1394_SUCCESS) { + fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__); + goto ERROR; + } + } + else { + if(dc1394_dma_setup_format7_capture(pcap->handle,pcap->camera->node,index+1 /*channel*/, + pcap->mode, SPEED_400, QUERY_FROM_CAMERA, + (unsigned int)QUERY_FROM_CAMERA, (unsigned int)QUERY_FROM_CAMERA, + (unsigned int)QUERY_FROM_CAMERA, (unsigned int)QUERY_FROM_CAMERA, + NUM_BUFFERS, +#ifdef HAVE_DC1394_095 + 0 /*do_extra_buffering*/, +#endif + 1 /*DROP_FRAMES*/, + pcap->device_name, pcap->camera) != DC1394_SUCCESS) { + fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__); + goto ERROR; + } + } + + if (dc1394_start_iso_transmission(pcap->handle, pcap->camera->node)!=DC1394_SUCCESS) { + fprintf(stderr,"%s:%d: Could not start ISO transmission\n",__FILE__,__LINE__); + goto ERROR; + } + + usleep(DELAY); + + dc1394bool_t status; + if (dc1394_get_iso_status(pcap->handle, pcap->camera->node, &status)!=DC1394_SUCCESS) { + fprintf(stderr,"%s:%d: Could get ISO status",__FILE__,__LINE__); + goto ERROR; + } + if (status==DC1394_FALSE) { + fprintf(stderr,"%s:%d: ISO transmission refuses to start",__FILE__,__LINE__); + goto ERROR; + } + + // convert camera image to RGB by default + pcap->convert=1; + + // no image data allocated yet + pcap->buffer_is_writeable = 0; + + memset(&(pcap->frame), 0, sizeof(IplImage)); + icvResizeFrame( pcap ); + return pcap; + +ERROR: + return 0; +}; + +static void icvCloseCAM_DC1394( CvCaptureCAM_DC1394* capture ){ + dc1394_stop_iso_transmission(capture->handle, capture->camera->node); + dc1394_dma_unlisten (capture->handle, capture->camera); + /* Deallocate space for RGBA data */ + if(capture->convert){ + cvFree(&capture->frame.imageData); + } +} + +static int icvGrabFrameCAM_DC1394( CvCaptureCAM_DC1394* capture ){ + // TODO: should this function wait until the next frame is available or return + // immediately ? + float waiting = 0; + do{ + int result = dc1394_dma_single_capture_poll(capture->camera); + if(result==DC1394_SUCCESS){ + return 1; + } + else if(result==DC1394_NO_FRAME){ + usleep(1000000/120); //sleep for at least a 1/2 of the frame rate + waiting += 1.0/120.0; + } + else{ + printf("dc1394_dma_single_capture_poll failed\n"); + return 0; + } + } while(waiting<2); + printf("dc1394_dma_single_capture_poll timed out\n"); + return 0; +} + +static IplImage* icvRetrieveFrameCAM_DC1394( CvCaptureCAM_DC1394* capture, int ){ + if(capture->camera->capture_buffer ) + { + if(capture->convert){ + /* Convert to RGBA */ + unsigned char * src = (unsigned char *)capture->camera->capture_buffer; + unsigned char * dst = (unsigned char *)capture->frame.imageData; + switch (capture->color_mode) { + case COLOR_FORMAT7_RGB8: + //printf("icvRetrieveFrame convert RGB to BGR\n"); + /* Convert RGB to BGR */ + for (int i=0;iframe.imageSize;i+=6) { + dst[i] = src[i+2]; + dst[i+1] = src[i+1]; + dst[i+2] = src[i]; + dst[i+3] = src[i+5]; + dst[i+4] = src[i+4]; + dst[i+5] = src[i+3]; + } + break; + case COLOR_FORMAT7_YUV422: + //printf("icvRetrieveFrame convert YUV422 to BGR %d\n"); + uyvy2bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height); + break; + case COLOR_FORMAT7_MONO8: + //printf("icvRetrieveFrame convert MONO8 to BGR %d\n"); + y2bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height); + break; + case COLOR_FORMAT7_YUV411: + //printf("icvRetrieveFrame convert YUV411 to BGR %d\n"); + uyyvyy2bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height); + break; + case COLOR_FORMAT7_YUV444: + //printf("icvRetrieveFrame convert YUV444 to BGR %d\n"); + uyv2bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height); + break; + case COLOR_FORMAT7_MONO16: + //printf("icvRetrieveFrame convert MONO16 to BGR %d\n"); + y162bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height, MONO16_BPP); + break; + case COLOR_FORMAT7_RGB16: + //printf("icvRetrieveFrame convert RGB16 to BGR %d\n"); + rgb482bgr(src, + dst, + capture->camera->frame_width * capture->camera->frame_height, MONO16_BPP); + break; + default: + fprintf(stderr,"%s:%d: Unsupported color mode %d\n",__FILE__,__LINE__,capture->color_mode); + return 0; + } /* switch (capture->mode) */ + } + else{ + // return raw data + capture->frame.imageData = (char *) capture->camera->capture_buffer; + capture->frame.imageDataOrigin = (char *) capture->camera->capture_buffer; + } + + // TODO: if convert=0, we are not actually done with the buffer + // but this seems to work anyway. + dc1394_dma_done_with_buffer(capture->camera); + + return &capture->frame; + } + return 0; +}; + +static double icvGetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id ){ + int index=-1; + switch ( property_id ) { + case CV_CAP_PROP_CONVERT_RGB: + return capture->convert; + case CV_CAP_PROP_MODE: + return capture->mode; + case CV_CAP_PROP_FORMAT: + return capture->format; + case CV_CAP_PROP_FPS: + CV_DC1394_CALL(dc1394_get_video_framerate(capture->handle, capture->camera->node, + (unsigned int *) &capture->camera->frame_rate)); + switch(capture->camera->frame_rate) { + case FRAMERATE_1_875: + return 1.875; + case FRAMERATE_3_75: + return 3.75; + case FRAMERATE_7_5: + return 7.5; + case FRAMERATE_15: + return 15.; + case FRAMERATE_30: + return 30.; + case FRAMERATE_60: + return 60; +#if NUM_FRAMERATES > 6 + case FRAMERATE_120: + return 120; +#endif +#if NUM_FRAMERATES > 7 + case FRAMERATE_240: + return 240; +#endif + } + default: + index = property_id; // did they pass in a LIBDC1394 feature flag? + break; + } + if(index>=FEATURE_MIN && index<=FEATURE_MAX){ + dc1394bool_t has_feature; + CV_DC1394_CALL( dc1394_is_feature_present(capture->handle, capture->camera->node, + index, &has_feature)); + if(!has_feature){ + CV_WARN("Feature is not supported by this camera"); + } + else{ + unsigned int value; + dc1394_get_feature_value(capture->handle, capture->camera->node, index, &value); + return (double) value; + } + } + + return 0; +}; + +// resize capture->frame appropriately depending on camera and capture settings +static int icvResizeFrame(CvCaptureCAM_DC1394 * capture){ + if(capture->convert){ + // resize if sizes are different, formats are different + // or conversion option has changed + if(capture->camera->frame_width != capture->frame.width || + capture->camera->frame_height != capture->frame.height || + capture->frame.depth != 8 || + capture->frame.nChannels != 3 || + capture->frame.imageData == NULL || + capture->buffer_is_writeable == 0) + { + if(capture->frame.imageData && capture->buffer_is_writeable){ + cvReleaseData( &(capture->frame)); + } + cvInitImageHeader( &capture->frame, cvSize( capture->camera->frame_width, + capture->camera->frame_height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + cvCreateData( &(capture->frame) ); + capture->buffer_is_writeable = 1; + } + + } + else { + // free image data if allocated by opencv + if(capture->buffer_is_writeable){ + cvReleaseData(&(capture->frame)); + } + + // figure out number of channels and bpp + int bpp = 8; + int nch = 3; + int width = capture->camera->frame_width; + int height = capture->camera->frame_height; + double code = CV_FOURCC('B','G','R',0); + switch(capture->color_mode){ + case COLOR_FORMAT7_YUV422: + nch = 2; + code = CV_FOURCC('Y','4','2','2'); + break; + case COLOR_FORMAT7_MONO8: + code = CV_FOURCC('Y',0,0,0); + nch = 1; + break; + case COLOR_FORMAT7_YUV411: + code = CV_FOURCC('Y','4','1','1'); + width *= 2; + nch = 3; //yy[u/v] + break; + case COLOR_FORMAT7_YUV444: + code = CV_FOURCC('Y','U','V',0); + nch = 3; + break; + case COLOR_FORMAT7_MONO16: + code = CV_FOURCC('Y',0,0,0); + bpp = IPL_DEPTH_16S; + nch = 1; + break; + case COLOR_FORMAT7_RGB16: + bpp = IPL_DEPTH_16S; + nch = 3; + break; + default: + break; + } + // reset image header + cvInitImageHeader( &capture->frame,cvSize( width, height ), bpp, nch, IPL_ORIGIN_TL, 4 ); + //assert(capture->frame.imageSize == capture->camera->quadlets_per_frame*4); + capture->buffer_is_writeable = 0; + } + return 1; +} + +// Toggle setting about whether or not RGB color conversion is to be performed +// Allocates/Initializes capture->frame appropriately +int icvSetConvertRGB(CvCaptureCAM_DC1394 * capture, int convert){ + if(convert==capture->convert){ + // no action necessary + return 1; + } + capture->convert = convert; + return icvResizeFrame( capture ); +} + +// given desired format, mode, and modes bitmask from camera, determine if format and mode are supported +static int +icvFormatSupportedCAM_DC1394(int format, quadlet_t formats){ + // formats is a bitmask whose higher order bits indicate whether format is supported + int shift = 31 - (format - FORMAT_MIN); + int mask = 1 << shift; + return (formats & mask) != 0; +} + +// analyze modes bitmask from camera to determine if desired format and mode are supported +static int +icvModeSupportedCAM_DC1394(int format, int mode, quadlet_t modes){ + // modes is a bitmask whose higher order bits indicate whether mode is supported + int format_idx = format - FORMAT_MIN; + int mode_format_min = MODE_FORMAT0_MIN + 32*format_idx; + int shift = 31 - (mode - mode_format_min); + int mask = 0x1 << shift; + return (modes & mask) != 0; +} + +// Setup camera to use given dc1394 mode +static int +icvSetModeCAM_DC1394( CvCaptureCAM_DC1394 * capture, int mode ){ + quadlet_t modes, formats; + //printf("\n"); + + // figure out corrent format for this mode + int format = (mode - MODE_FORMAT0_MIN) / 32 + FORMAT_MIN; + + // get supported formats + if (dc1394_query_supported_formats(capture->handle, capture->camera->node, &formats)<0) { + fprintf(stderr,"%s:%d: Could not query supported formats\n",__FILE__,__LINE__); + return 0; + } + + // is format for requested mode supported ? + if(icvFormatSupportedCAM_DC1394(format, formats)==0){ + return 0; + } + + // get supported modes for requested format + if (dc1394_query_supported_modes(capture->handle, capture->camera->node, format, &modes)<0){ + fprintf(stderr,"%s:%d: Could not query supported modes for format %d\n",__FILE__,__LINE__, capture->format); + return 0; + } + + // is requested mode supported ? + if(! icvModeSupportedCAM_DC1394(format, mode, modes) ){ + return 0; + } + + int color_mode = icvColorMode( mode ); + + if(color_mode == -1){ + return 0; + } + + int frame_rate = icvGetBestFrameRate(capture, format, mode); + + dc1394_dma_unlisten(capture->handle, capture->camera); + if (dc1394_dma_setup_capture(capture->handle, capture->camera->node, capture->camera->channel /*channel*/, + format, mode, SPEED_400, + frame_rate, NUM_BUFFERS, +#ifdef HAVE_DC1394_095 + 0 /*do_extra_buffering*/, +#endif + 1 /*DROP_FRAMES*/, + capture->device_name, capture->camera) != DC1394_SUCCESS) { + fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__); + return 0; + } + dc1394_start_iso_transmission(capture->handle, capture->camera->node); + + capture->frame_rate = frame_rate; + capture->format = format; + capture->mode = mode; + capture->color_mode = color_mode; + + // now fix image size to match new mode + icvResizeFrame( capture ); + return 1; +} + +// query camera for supported frame rates and select fastest for given format and mode +static unsigned int icvGetBestFrameRate( CvCaptureCAM_DC1394 * capture, int format, int mode ){ + quadlet_t framerates; + if (dc1394_query_supported_framerates(capture->handle, capture->camera->node, + format, mode, &framerates)!=DC1394_SUCCESS) + { + fprintf(stderr,"%s:%d: Could not query supported framerates\n",__FILE__,__LINE__); + framerates = 0; + } + + for (int f=FRAMERATE_MAX; f>=FRAMERATE_MIN; f--) { + if (framerates & (0x1<< (31-(f-FRAMERATE_MIN)))) { + return f; + } + } + return 0; +} + +static int +icvSetFrameRateCAM_DC1394( CvCaptureCAM_DC1394 * capture, double value ){ + unsigned int fps=15; + if(capture->format == FORMAT_SCALABLE_IMAGE_SIZE) + return 0; /* format 7 has no fixed framerates */ + if (value==-1){ + fps=icvGetBestFrameRate( capture, capture->format, capture->mode ); + } + else if (value==1.875) + fps=FRAMERATE_1_875; + else if (value==3.75) + fps=FRAMERATE_3_75; + else if (value==7.5) + fps=FRAMERATE_7_5; + else if (value==15) + fps=FRAMERATE_15; + else if (value==30) + fps=FRAMERATE_30; + else if (value==60) + fps=FRAMERATE_60; +#if NUM_FRAMERATES > 6 + else if (value==120) + fps=FRAMERATE_120; +#endif +#if NUM_FRAMERATES > 7 + else if (value==240) + fps=FRAMERATE_240; +#endif + dc1394_set_video_framerate(capture->handle, capture->camera->node,fps); + dc1394_get_video_framerate(capture->handle, capture->camera->node, + (unsigned int *) &capture->camera->frame_rate); + + return fps==(unsigned int) capture->camera->frame_rate; +} + +// for given mode return color format +static int +icvColorMode( int mode ){ + switch(mode) { + case MODE_160x120_YUV444: + return COLOR_FORMAT7_YUV444; + case MODE_320x240_YUV422: + case MODE_640x480_YUV422: + case MODE_800x600_YUV422: + case MODE_1024x768_YUV422: + case MODE_1280x960_YUV422: + case MODE_1600x1200_YUV422: + return COLOR_FORMAT7_YUV422; + case MODE_640x480_YUV411: + return COLOR_FORMAT7_YUV411; + case MODE_640x480_RGB: + case MODE_800x600_RGB: + case MODE_1024x768_RGB: + case MODE_1280x960_RGB: + case MODE_1600x1200_RGB: + return COLOR_FORMAT7_RGB8; + case MODE_640x480_MONO: + case MODE_800x600_MONO: + case MODE_1024x768_MONO: + case MODE_1280x960_MONO: + case MODE_1600x1200_MONO: + return COLOR_FORMAT7_MONO8; + case MODE_640x480_MONO16: + case MODE_800x600_MONO16: + case MODE_1024x768_MONO16: + case MODE_1280x960_MONO16: + case MODE_1600x1200_MONO16: + return COLOR_FORMAT7_MONO16; + case MODE_FORMAT7_0: + case MODE_FORMAT7_1: + case MODE_FORMAT7_2: + case MODE_FORMAT7_3: + case MODE_FORMAT7_4: + case MODE_FORMAT7_5: + case MODE_FORMAT7_6: + case MODE_FORMAT7_7: + fprintf(stderr,"%s:%d: Format7 not yet supported\n",__FILE__,__LINE__); + default: + break; + } + return -1; +} + +// function to set camera properties using dc1394 feature enum +// val == -1 indicates to set this property to 'auto' +static int +icvSetFeatureCAM_DC1394( CvCaptureCAM_DC1394* capture, int feature_id, int val){ + dc1394bool_t isOn = DC1394_FALSE; + dc1394bool_t hasAutoCapability = DC1394_FALSE; + dc1394bool_t isAutoOn = DC1394_FALSE; + unsigned int nval; + unsigned int minval,maxval; + + // Turn the feature on if it is OFF + if( dc1394_is_feature_on(capture->handle, capture->camera->node, feature_id, &isOn) + == DC1394_FAILURE ) { + return 0; + } + if( isOn == DC1394_FALSE ) { + // try to turn it on. + if( dc1394_feature_on_off(capture->handle, capture->camera->node, feature_id, 1) == DC1394_FAILURE ) { + fprintf(stderr, "error turning feature %d on!\n", feature_id); + return 0; + } + } + + // Check if the feature supports auto mode + dc1394_has_auto_mode(capture->handle, capture->camera->node, feature_id, &hasAutoCapability); + if( hasAutoCapability ) { + + // now check if the auto is on. + if( dc1394_is_feature_auto(capture->handle, capture->camera->node, feature_id, &isAutoOn ) == DC1394_FAILURE ) { + fprintf(stderr, "error determining if feature %d has auto on!\n", feature_id); + return 0; + } + } + // Caller requested auto mode, but cannot support it + else if(val==-1){ + fprintf(stderr, "feature %d does not support auto mode\n", feature_id); + return 0; + } + + if(val==-1){ + // if the auto mode isn't enabled, enable it + if( isAutoOn == DC1394_FALSE ) { + if(dc1394_auto_on_off(capture->handle, capture->camera->node, feature_id, 1) == DC1394_FAILURE ) { + fprintf(stderr, "error turning feature %d auto ON!\n", feature_id); + return 0; + } + } + return 1; + } + + // ELSE turn OFF auto and adjust feature manually + if( isAutoOn == DC1394_TRUE ) { + if(dc1394_auto_on_off(capture->handle, capture->camera->node, feature_id, 0) == DC1394_FAILURE ) { + fprintf(stderr, "error turning feature %d auto OFF!\n", feature_id); + return 0; + } + } + + // Clamp val to within feature range + CV_DC1394_CALL( dc1394_get_min_value(capture->handle, capture->camera->node, feature_id, &minval)); + CV_DC1394_CALL( dc1394_get_max_value(capture->handle, capture->camera->node, feature_id, &maxval)); + val = (int)MIN(maxval, MAX((unsigned)val, minval)); + + + if (dc1394_set_feature_value(capture->handle, capture->camera->node, feature_id, val) == + DC1394_FAILURE){ + fprintf(stderr, "error setting feature value\n"); + return 0; + } + if (dc1394_get_feature_value(capture->handle, capture->camera->node, feature_id, &nval) == + DC1394_FAILURE){ + fprintf(stderr, "error setting feature value\n"); + return 0; + } + return nval==(unsigned int)val; + +} + +// cvSetCaptureProperty callback function implementation +static int +icvSetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id, double value ){ + int index=-1; + switch ( property_id ) { + case CV_CAP_PROP_CONVERT_RGB: + return icvSetConvertRGB( capture, value != 0 ); + case CV_CAP_PROP_MODE: + return icvSetModeCAM_DC1394( capture, (int) value ); + case CV_CAP_PROP_FPS: + return icvSetFrameRateCAM_DC1394( capture, value ); + case CV_CAP_PROP_BRIGHTNESS: + index = FEATURE_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + index = FEATURE_GAMMA; + break; + case CV_CAP_PROP_SATURATION: + index = FEATURE_SATURATION; + break; + case CV_CAP_PROP_HUE: + index = FEATURE_HUE; + break; + case CV_CAP_PROP_GAIN: + index = FEATURE_GAIN; + break; + default: + index = property_id; // did they pass in a LIBDC1394 feature flag? + break; + } + if(index>=FEATURE_MIN && index<=FEATURE_MAX){ + return icvSetFeatureCAM_DC1394(capture, index, (int) value); + } + return 0; +}; + +/********************************************************************** + * + * CONVERSION FUNCTIONS TO RGB 24bpp + * + **********************************************************************/ + +/* color conversion functions from Bart Nabbe. *//* corrected by Damien: bad coeficients in YUV2RGB */ +#define YUV2RGB(y, u, v, r, g, b)\ + r = y + ((v*1436) >> 10);\ +g = y - ((u*352 + v*731) >> 10);\ +b = y + ((u*1814) >> 10);\ +r = r < 0 ? 0 : r;\ +g = g < 0 ? 0 : g;\ +b = b < 0 ? 0 : b;\ +r = r > 255 ? 255 : r;\ +g = g > 255 ? 255 : g;\ +b = b > 255 ? 255 : b + + static void +uyv2bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels) +{ + register int i = NumPixels + (NumPixels << 1) - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y, u, v; + register int r, g, b; + + while (i > 0) { + v = src[i--] - 128; + y = src[i--]; + u = src[i--] - 128; + YUV2RGB(y, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + } +} + + static void +uyvy2bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels) +{ + register int i = (NumPixels << 1) - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y0, y1, u, v; + register int r, g, b; + + while (i > 0) { + y1 = src[i--]; + v = src[i--] - 128; + y0 = src[i--]; + u = src[i--] - 128; + YUV2RGB(y1, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + YUV2RGB(y0, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + } +} + + + static void +uyyvyy2bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels) +{ + register int i = NumPixels + (NumPixels >> 1) - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y0, y1, y2, y3, u, v; + register int r, g, b; + + while (i > 0) { + y3 = src[i--]; + y2 = src[i--]; + v = src[i--] - 128; + y1 = src[i--]; + y0 = src[i--]; + u = src[i--] - 128; + YUV2RGB(y3, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + YUV2RGB(y2, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + YUV2RGB(y1, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + YUV2RGB(y0, u, v, r, g, b); + dest[j--] = r; + dest[j--] = g; + dest[j--] = b; + } +} + + static void +y2bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels) +{ + register int i = NumPixels - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y; + + while (i > 0) { + y = src[i--]; + dest[j--] = y; + dest[j--] = y; + dest[j--] = y; + } +} + + static void +y162bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels, int bits) +{ + register int i = (NumPixels << 1) - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y; + + while (i > 0) { + y = src[i--]; + y = (y + (src[i--] << 8)) >> (bits - 8); + dest[j--] = y; + dest[j--] = y; + dest[j--] = y; + } +} + +// this one was in coriander but didn't take bits into account + static void +rgb482bgr(const unsigned char *src, unsigned char *dest, + unsigned long long int NumPixels, int bits) +{ + register int i = (NumPixels << 1) - 1; + register int j = NumPixels + (NumPixels << 1) - 1; + register int y; + + while (i > 0) { + y = src[i--]; + dest[j-2] = (y + (src[i--] << 8)) >> (bits - 8); + j--; + y = src[i--]; + dest[j] = (y + (src[i--] << 8)) >> (bits - 8); + j--; + y = src[i--]; + dest[j+2] = (y + (src[i--] << 8)) >> (bits - 8); + j--; + } +} + + +class CvCaptureCAM_DC1394_CPP : public CvCapture +{ +public: + CvCaptureCAM_DC1394_CPP() { captureDC1394 = 0; } + virtual ~CvCaptureCAM_DC1394_CPP() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc... +protected: + + CvCaptureCAM_DC1394* captureDC1394; +}; + +bool CvCaptureCAM_DC1394_CPP::open( int index ) +{ + close(); + captureDC1394 = icvCaptureFromCAM_DC1394(index); + return captureDC1394 != 0; +} + +void CvCaptureCAM_DC1394_CPP::close() +{ + if( captureDC1394 ) + { + icvCloseCAM_DC1394( captureDC1394 ); + cvFree( &captureDC1394 ); + } +} + +bool CvCaptureCAM_DC1394_CPP::grabFrame() +{ + return captureDC1394 ? icvGrabFrameCAM_DC1394( captureDC1394 ) != 0 : false; +} + +IplImage* CvCaptureCAM_DC1394_CPP::retrieveFrame(int) +{ + return captureDC1394 ? (IplImage*)icvRetrieveFrameCAM_DC1394( captureDC1394, 0 ) : 0; +} + +double CvCaptureCAM_DC1394_CPP::getProperty( int propId ) +{ + return captureDC1394 ? icvGetPropertyCAM_DC1394( captureDC1394, propId ) : 0; +} + +bool CvCaptureCAM_DC1394_CPP::setProperty( int propId, double value ) +{ + return captureDC1394 ? icvSetPropertyCAM_DC1394( captureDC1394, propId, value ) != 0 : false; +} + +CvCapture* cvCreateCameraCapture_DC1394( int index ) +{ + CvCaptureCAM_DC1394_CPP* capture = new CvCaptureCAM_DC1394_CPP; + + if( capture->open( index )) + return capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dc1394_v2.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dc1394_v2.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dc1394_v2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dc1394_v2.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,918 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_DC1394_2 + +#include +#include +#include +#include +#include +#include + +static dc1394error_t adaptBufferStereoLocal(dc1394video_frame_t *in, dc1394video_frame_t *out) +{ + uint32_t bpp; + + // buffer position is not changed. Size is boubled in Y + out->size[0] = in->size[0]; + out->size[1] = in->size[1] * 2; + out->position[0] = in->position[0]; + out->position[1] = in->position[1]; + + // color coding is set to mono8 or raw8. + switch (in->color_coding) + { + case DC1394_COLOR_CODING_RAW16: + out->color_coding = DC1394_COLOR_CODING_RAW8; + break; + case DC1394_COLOR_CODING_MONO16: + case DC1394_COLOR_CODING_YUV422: + out->color_coding = DC1394_COLOR_CODING_MONO8; + break; + default: + return DC1394_INVALID_COLOR_CODING; + } + + // keep the color filter value in all cases. if the format is not raw it will not be further used anyway + out->color_filter = in->color_filter; + + // the output YUV byte order must be already set if the buffer is YUV422 at the output + // if the output is not YUV we don't care about this field. + // Hence nothing to do. + // we always convert to 8bits (at this point) we can safely set this value to 8. + out->data_depth = 8; + + // don't know what to do with stride... >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<< + // out->stride=?? + // the video mode should not change. Color coding and other stuff can be accessed in specific fields of this struct + out->video_mode = in->video_mode; + + // padding is kept: + out->padding_bytes = in->padding_bytes; + + // image bytes changes: >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<< + dc1394_get_color_coding_bit_size(out->color_coding, &bpp); + out->image_bytes = (out->size[0] * out->size[1] * bpp) / 8; + + // total is image_bytes + padding_bytes + out->total_bytes = out->image_bytes + out->padding_bytes; + + // bytes-per-packet and packets_per_frame are internal data that can be kept as is. + out->packet_size = in->packet_size; + out->packets_per_frame = in->packets_per_frame; + + // timestamp, frame_behind, id and camera are copied too: + out->timestamp = in->timestamp; + out->frames_behind = in->frames_behind; + out->camera = in->camera; + out->id = in->id; + + // verify memory allocation: + if (out->total_bytes > out->allocated_image_bytes) + { + free(out->image); + out->image = (uint8_t*)malloc(out->total_bytes * sizeof(uint8_t)); + out->allocated_image_bytes = out->total_bytes; + } + + // Copy padding bytes: + memcpy(&(out->image[out->image_bytes]), &(in->image[in->image_bytes]), out->padding_bytes); + out->little_endian = DC1394_FALSE; // not used before 1.32 is out. + out->data_in_padding = DC1394_FALSE; // not used before 1.32 is out. + return DC1394_SUCCESS; +} + +static dc1394error_t dc1394_deinterlace_stereo_frames_fixed(dc1394video_frame_t *in, + dc1394video_frame_t *out, dc1394stereo_method_t method) +{ + if((in->color_coding == DC1394_COLOR_CODING_RAW16) || + (in->color_coding == DC1394_COLOR_CODING_MONO16) || + (in->color_coding == DC1394_COLOR_CODING_YUV422)) + { + switch (method) + { + + case DC1394_STEREO_METHOD_INTERLACED: + adaptBufferStereoLocal(in, out); +//FIXED by AB: +// dc1394_deinterlace_stereo(in->image, out->image, in->size[0], in->size[1]); + dc1394_deinterlace_stereo(in->image, out->image, out->size[0], out->size[1]); + break; + + case DC1394_STEREO_METHOD_FIELD: + adaptBufferStereoLocal(in, out); + memcpy(out->image, in->image, out->image_bytes); + break; + } + + return DC1394_INVALID_STEREO_METHOD; + } + else + return DC1394_FUNCTION_NOT_SUPPORTED; +} + +static uint32_t getControlRegister(dc1394camera_t *camera, uint64_t offset) +{ + uint32_t value = 0; + dc1394error_t err = dc1394_get_control_register(camera, offset, &value); + + assert(err == DC1394_SUCCESS); + return err == DC1394_SUCCESS ? value : 0xffffffff; +} + +struct CvDC1394 +{ + CvDC1394(); + ~CvDC1394(); + + dc1394_t* dc; + fd_set camFds; +}; + +CvDC1394::CvDC1394() +{ + dc = dc1394_new(); + FD_ZERO(&camFds); +} + +CvDC1394::~CvDC1394() +{ + if (dc) + dc1394_free(dc); + dc = 0; +} + +static CvDC1394 dc1394; + +class CvCaptureCAM_DC1394_v2_CPP : public CvCapture +{ +public: + static int dc1394properties[CV_CAP_PROP_MAX_DC1394]; + CvCaptureCAM_DC1394_v2_CPP(); + virtual ~CvCaptureCAM_DC1394_v2_CPP() + { + close(); + } + + virtual bool open(int index); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc... + + +protected: + virtual bool startCapture(); + virtual bool getVidereCalibrationInfo( char* buf, int bufSize ); + virtual bool initVidereRectifyMaps( const char* info, IplImage* ml[2], IplImage* mr[2] ); + + uint64_t guid; + dc1394camera_t* dcCam; + int isoSpeed; + int videoMode; + int frameWidth, frameHeight; + double fps; + int nDMABufs; + bool started; + int userMode; + + enum { VIDERE = 0x5505 }; + + int cameraId; + bool colorStereo; + dc1394bayer_method_t bayer; + dc1394color_filter_t bayerFilter; + + enum { NIMG = 2 }; + IplImage *img[NIMG]; + dc1394video_frame_t* frameC; + int nimages; + + bool rectify; + bool init_rectify; + IplImage *maps[NIMG][2]; + dc1394featureset_t feature_set; +}; +//mapping CV_CAP_PROP_ to DC1394_FEATUREs +int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CV_CAP_PROP_MAX_DC1394] = { +-1, //no corresponding feature for CV_CAP_PROP_POS_MSEC +-1,-1,-1,-1, +DC1394_FEATURE_FRAME_RATE, //CV_CAP_PROP_FPS - fps can be set for format 7 only! +-1,-1,-1,-1, +DC1394_FEATURE_BRIGHTNESS, //CV_CAP_PROP_BRIGHTNESS 10 +-1, +DC1394_FEATURE_SATURATION, //CV_CAP_PROP_SATURATION +DC1394_FEATURE_HUE, +DC1394_FEATURE_GAIN, +DC1394_FEATURE_SHUTTER, //CV_CAP_PROP_EXPOSURE +-1, //CV_CAP_PROP_CONVERT_RGB +DC1394_FEATURE_WHITE_BALANCE, //corresponds to CV_CAP_PROP_WHITE_BALANCE_BLUE_U and CV_CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set +-1,-1, +DC1394_FEATURE_SHARPNESS, //20 +DC1394_FEATURE_EXPOSURE, //CV_CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard +DC1394_FEATURE_GAMMA, //CV_CAP_PROP_GAMMA +DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE +DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER +DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY +DC1394_FEATURE_WHITE_BALANCE, //CV_CAP_PROP_WHITE_BALANCE_RED_V +DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM +DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS +-1 //CV_CAP_PROP_GUID +}; +CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP() +{ + guid = 0; + dcCam = 0; + isoSpeed = 400; + fps = 15; + nDMABufs = 8; + started = false; + cameraId = 0; + colorStereo = false; + bayer = DC1394_BAYER_METHOD_BILINEAR; + bayerFilter = DC1394_COLOR_FILTER_GRBG; + frameWidth = 640; + frameHeight = 480; + + for (int i = 0; i < NIMG; i++) + img[i] = maps[i][0] = maps[i][1] = 0; + frameC = 0; + nimages = 1; + rectify = false; + userMode = -1; +} + + +bool CvCaptureCAM_DC1394_v2_CPP::startCapture() +{ + int i; + int code = 0; + if (!dcCam) + return false; + if (isoSpeed > 0) + { + code = dc1394_video_set_iso_speed(dcCam, + isoSpeed <= 100 ? DC1394_ISO_SPEED_100 : + isoSpeed <= 200 ? DC1394_ISO_SPEED_200 : + isoSpeed <= 400 ? DC1394_ISO_SPEED_400 : + isoSpeed <= 800 ? DC1394_ISO_SPEED_800 : + isoSpeed == 1600 ? DC1394_ISO_SPEED_1600 : + DC1394_ISO_SPEED_3200); + } + + // should a specific mode be used + if (userMode >= 0) + + { + dc1394video_mode_t wantedMode; + dc1394video_modes_t videoModes; + dc1394_video_get_supported_modes(dcCam, &videoModes); + + //set mode from number, for example the second supported mode, i.e userMode = 1 + + if (userMode < (int)videoModes.num) + { + wantedMode = videoModes.modes[userMode]; + } + + //set modes directly from DC134 constants (from dc1394video_mode_t) + else if ((userMode >= DC1394_VIDEO_MODE_MIN) && (userMode <= DC1394_VIDEO_MODE_MAX )) + { + //search for wanted mode, to check if camera supports it + int j = 0; + while ((j< (int)videoModes.num) && videoModes.modes[j]!=userMode) + { + j++; + } + + if ((int)videoModes.modes[j]==userMode) + { + wantedMode = videoModes.modes[j]; + } + else + { + userMode = -1; // wanted mode not supported, search for best mode + } + } + else + { + userMode = -1; // wanted mode not supported, search for best mode + } + //if userMode is available: set it and update size + if (userMode != -1) + { + code = dc1394_video_set_mode(dcCam, wantedMode); + uint32_t width, height; + dc1394_get_image_size_from_video_mode(dcCam, wantedMode, &width, &height); + frameWidth = (int)width; + frameHeight = (int)height; + } + } + + if (userMode == -1 && (frameWidth > 0 || frameHeight > 0)) + { + dc1394video_mode_t bestMode = (dc1394video_mode_t) - 1; + dc1394video_modes_t videoModes; + dc1394_video_get_supported_modes(dcCam, &videoModes); + for (i = 0; i < (int)videoModes.num; i++) + { + dc1394video_mode_t mode = videoModes.modes[i]; + if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX) + continue; + int pref = -1; + dc1394color_coding_t colorCoding; + dc1394_get_color_coding_from_video_mode(dcCam, mode, &colorCoding); + + uint32_t width, height; + dc1394_get_image_size_from_video_mode(dcCam, mode, &width, &height); + if ((int)width == frameWidth || (int)height == frameHeight) + { + if (colorCoding == DC1394_COLOR_CODING_RGB8 || + colorCoding == DC1394_COLOR_CODING_RAW8) + { + bestMode = mode; + break; + } + + if (colorCoding == DC1394_COLOR_CODING_YUV411 || + colorCoding == DC1394_COLOR_CODING_YUV422 || + (colorCoding == DC1394_COLOR_CODING_YUV444 && + pref < 1)) + { + bestMode = mode; + pref = 1; + break; + } + + if (colorCoding == DC1394_COLOR_CODING_MONO8) + { + bestMode = mode; + pref = 0; + } + } + } + if ((int)bestMode >= 0) + code = dc1394_video_set_mode(dcCam, bestMode); + } + + if (fps > 0) + { + dc1394video_mode_t mode; + dc1394framerates_t framerates; + double minDiff = DBL_MAX; + dc1394framerate_t bestFps = (dc1394framerate_t) - 1; + + dc1394_video_get_mode(dcCam, &mode); + dc1394_video_get_supported_framerates(dcCam, mode, &framerates); + + for (i = 0; i < (int)framerates.num; i++) + { + dc1394framerate_t ifps = framerates.framerates[i]; + double fps1 = (1 << (ifps - DC1394_FRAMERATE_1_875)) * 1.875; + double diff = fabs(fps1 - fps); + if (diff < minDiff) + { + minDiff = diff; + bestFps = ifps; + } + } + if ((int)bestFps >= 0) + code = dc1394_video_set_framerate(dcCam, bestFps); + } + + if (cameraId == VIDERE) + { + bayerFilter = DC1394_COLOR_FILTER_GBRG; + nimages = 2; + uint32_t value = 0; + dc1394_get_control_register(dcCam, 0x50c, &value); + colorStereo = (value & 0x80000000) != 0; + } + + code = dc1394_capture_setup(dcCam, nDMABufs, DC1394_CAPTURE_FLAGS_DEFAULT); + if (code >= 0) + { + FD_SET(dc1394_capture_get_fileno(dcCam), &dc1394.camFds); + dc1394_video_set_transmission(dcCam, DC1394_ON); + if (cameraId == VIDERE) + { + enum { PROC_MODE_OFF, PROC_MODE_NONE, PROC_MODE_TEST, PROC_MODE_RECTIFIED, PROC_MODE_DISPARITY, PROC_MODE_DISPARITY_RAW }; + int procMode = PROC_MODE_RECTIFIED; + usleep(100000); + uint32_t qval1 = 0x08000000 | (0x90 << 16) | ((procMode & 0x7) << 16); + uint32_t qval2 = 0x08000000 | (0x9C << 16); + dc1394_set_control_register(dcCam, 0xFF000, qval1); + dc1394_set_control_register(dcCam, 0xFF000, qval2); + } + started = true; + } + + return code >= 0; +} + +bool CvCaptureCAM_DC1394_v2_CPP::open(int index) +{ + bool result = false; + dc1394camera_list_t* cameraList = 0; + dc1394error_t err; + + close(); + + if (!dc1394.dc) + goto _exit_; + + err = dc1394_camera_enumerate(dc1394.dc, &cameraList); + if (err < 0 || !cameraList || (unsigned)index >= (unsigned)cameraList->num) + goto _exit_; + + guid = cameraList->ids[index].guid; + dcCam = dc1394_camera_new(dc1394.dc, guid); + if (!dcCam) + goto _exit_; + + cameraId = dcCam->vendor_id; + //get all features + if (dc1394_feature_get_all(dcCam,&feature_set) == DC1394_SUCCESS) + result = true; + else + result = false; + +_exit_: + if (cameraList) + dc1394_camera_free_list(cameraList); + + return result; +} + +void CvCaptureCAM_DC1394_v2_CPP::close() +{ + if (dcCam) + { + // check for fileno valid before using + int fileno=dc1394_capture_get_fileno(dcCam); + + if (fileno>=0 && FD_ISSET(fileno, &dc1394.camFds)) + FD_CLR(fileno, &dc1394.camFds); + dc1394_video_set_transmission(dcCam, DC1394_OFF); + dc1394_capture_stop(dcCam); + dc1394_camera_free(dcCam); + dcCam = 0; + started = false; + } + + for (int i = 0; i < NIMG; i++) + { + cvReleaseImage(&img[i]); + cvReleaseImage(&maps[i][0]); + cvReleaseImage(&maps[i][1]); + } + if (frameC) + { + if (frameC->image) + free(frameC->image); + free(frameC); + frameC = 0; + } +} + + +bool CvCaptureCAM_DC1394_v2_CPP::grabFrame() +{ + dc1394capture_policy_t policy = DC1394_CAPTURE_POLICY_WAIT; + bool code = false, isColor; + dc1394video_frame_t *dcFrame = 0, *fs = 0; + int i, nch; + + if (!dcCam || (!started && !startCapture())) + return false; + + dc1394_capture_dequeue(dcCam, policy, &dcFrame); + + if (!dcFrame) + return false; + + if (/*dcFrame->frames_behind > 1 ||*/ dc1394_capture_is_frame_corrupt(dcCam, dcFrame) == DC1394_TRUE) + { + goto _exit_; + } + + isColor = dcFrame->color_coding != DC1394_COLOR_CODING_MONO8 && + dcFrame->color_coding != DC1394_COLOR_CODING_MONO16 && + dcFrame->color_coding != DC1394_COLOR_CODING_MONO16S; + + if (nimages == 2) + { + fs = (dc1394video_frame_t*)calloc(1, sizeof(*fs)); + + //dc1394_deinterlace_stereo_frames(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED); + dc1394_deinterlace_stereo_frames_fixed(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED); + + dc1394_capture_enqueue(dcCam, dcFrame); // release the captured frame as soon as possible + dcFrame = 0; + if (!fs->image) + goto _exit_; + isColor = colorStereo; + } + nch = isColor ? 3 : 1; + + for (i = 0; i < nimages; i++) + { + IplImage fhdr; + dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f; + f.size[1] /= nimages; + f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal + if (isColor) + { + if (!frameC) + frameC = (dc1394video_frame_t*)calloc(1, sizeof(*frameC)); + frameC->color_coding = nch == 3 ? DC1394_COLOR_CODING_RGB8 : DC1394_COLOR_CODING_MONO8; + if (nimages == 1) + { + dc1394_convert_frames(&f, frameC); + dc1394_capture_enqueue(dcCam, dcFrame); + dcFrame = 0; + } + else + { + f.color_filter = bayerFilter; + dc1394_debayer_frames(&f, frameC, bayer); + } + fc = frameC; + } + if (!img[i]) + img[i] = cvCreateImage(cvSize(fc->size[0], fc->size[1]), 8, nch); + cvInitImageHeader(&fhdr, cvSize(fc->size[0], fc->size[1]), 8, nch); + cvSetData(&fhdr, fc->image, fc->size[0]*nch); + + // Swap R&B channels: + if (nch==3) + cvConvertImage(&fhdr,&fhdr,CV_CVTIMG_SWAP_RB); + + if( rectify && cameraId == VIDERE && nimages == 2 ) + { + if( !maps[0][0] || maps[0][0]->width != img[i]->width || maps[0][0]->height != img[i]->height ) + { + CvSize size = cvGetSize(img[i]); + cvReleaseImage(&maps[0][0]); + cvReleaseImage(&maps[0][1]); + cvReleaseImage(&maps[1][0]); + cvReleaseImage(&maps[1][1]); + maps[0][0] = cvCreateImage(size, IPL_DEPTH_16S, 2); + maps[0][1] = cvCreateImage(size, IPL_DEPTH_16S, 1); + maps[1][0] = cvCreateImage(size, IPL_DEPTH_16S, 2); + maps[1][1] = cvCreateImage(size, IPL_DEPTH_16S, 1); + char buf[4*4096]; + if( getVidereCalibrationInfo( buf, (int)sizeof(buf) ) && + initVidereRectifyMaps( buf, maps[0], maps[1] )) + ; + else + rectify = false; + } + cvRemap(&fhdr, img[i], maps[i][0], maps[i][1]); + } + else + cvCopy(&fhdr, img[i]); + } + + code = true; + +_exit_: + if (dcFrame) + dc1394_capture_enqueue(dcCam, dcFrame); + if (fs) + { + if (fs->image) + free(fs->image); + free(fs); + } + + return code; +} + +IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx) +{ + return 0 <= idx && idx < nimages ? img[idx] : 0; +} + +double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) +{ + switch (propId) + { + case CV_CAP_PROP_FRAME_WIDTH: + return frameWidth ? frameWidth : frameHeight*4 / 3; + case CV_CAP_PROP_FRAME_HEIGHT: + return frameHeight ? frameHeight : frameWidth*3 / 4; + case CV_CAP_PROP_FPS: + return fps; + case CV_CAP_PROP_RECTIFICATION: + return rectify ? 1 : 0; + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + if (dc1394_feature_whitebalance_get_value(dcCam, + &feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, + &feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) + return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value; + break; + case CV_CAP_PROP_WHITE_BALANCE_RED_V: + if (dc1394_feature_whitebalance_get_value(dcCam, + &feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, + &feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) + return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value; + break; + case CV_CAP_PROP_GUID: + //the least 32 bits are enough to identify the camera + return (double) (guid & 0x00000000FFFFFFFF); + break; + case CV_CAP_PROP_MODE: + return (double) userMode; + break; + case CV_CAP_PROP_ISO_SPEED: + return (double) isoSpeed; + default: + if (propId FLT_EPSILON; + break; + case CV_CAP_PROP_MODE: + if(started) + return false; + userMode = cvRound(value); + break; + case CV_CAP_PROP_ISO_SPEED: + if(started) + return false; + isoSpeed = cvRound(value); + break; + //The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN : + default: + if (propIdon_off_capable) + && (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_OFF) == DC1394_SUCCESS)) + { + act_feature->is_on=DC1394_OFF; + return true; + } + return false; + } + //try to turn the feature ON, feature can be ON and at the same time it can be not capable to change state to OFF + if ( (act_feature->is_on == DC1394_OFF) && (act_feature->on_off_capable == DC1394_TRUE)) + { + if (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_ON) == DC1394_SUCCESS) + feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_ON; + } + //turn off absolute mode - the actual value will be stored in the value field, + //otherwise it would be stored into CSR (control and status register) absolute value + if (act_feature->absolute_capable + && dc1394_feature_set_absolute_control(dcCam, act_feature->id, DC1394_OFF) !=DC1394_SUCCESS) + return false; + else + act_feature->abs_control=DC1394_OFF; + //set AUTO + if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO) + { + if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS) + return false; + act_feature->current_mode=DC1394_FEATURE_MODE_AUTO; + return true; + } + //set ONE PUSH + if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO) + { + //have to set to manual first, otherwise one push will be ignored (AVT manual 4.3.0 p. 115) + if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS) + return false; + //will change to + act_feature->current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO; + return true; + } + //set the feature to MANUAL mode, + if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS) + return false; + else + act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL; + // if property is one of the white balance features treat it in different way + if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U) + { + if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), act_feature->RV_value)!=DC1394_SUCCESS) + return false; + else + { + act_feature->BU_value = cvRound(value); + return true; + } + } + if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V) + { + if (dc1394_feature_whitebalance_set_value(dcCam, act_feature->BU_value, cvRound(value))!=DC1394_SUCCESS) + return false; + else + { + act_feature->RV_value = cvRound(value); + return true; + } + } + + //first: check boundaries + if (value < act_feature->min) + { + value = act_feature->min; + } + else if (value > act_feature->max) + { + value = act_feature->max; + } + + if (dc1394_feature_set_value(dcCam, act_feature->id, cvRound(value)) == DC1394_SUCCESS) + { + act_feature->value = value; + return true; + } + } + return false; + } + return true; +} + + +bool CvCaptureCAM_DC1394_v2_CPP::getVidereCalibrationInfo( char* buf, int bufSize ) +{ + int pos; + + for( pos = 0; pos < bufSize - 4; pos += 4 ) + { + uint32_t quad = getControlRegister(dcCam, 0xF0800 + pos); + if( quad == 0 || quad == 0xffffffff ) + break; + buf[pos] = (uchar)(quad >> 24); + buf[pos+1] = (uchar)(quad >> 16); + buf[pos+2] = (uchar)(quad >> 8); + buf[pos+3] = (uchar)(quad); + } + + if( pos == 0 ) + return false; + + buf[pos] = '\0'; + return true; +} + + +bool CvCaptureCAM_DC1394_v2_CPP::initVidereRectifyMaps( const char* info, + IplImage* ml[2], IplImage* mr[2] ) +{ + float identity_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + CvMat l_rect = cvMat(3, 3, CV_32F, identity_data), r_rect = l_rect; + float l_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + float r_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + CvMat l_intrinsic = cvMat(3, 3, CV_32F, l_intrinsic_data); + CvMat r_intrinsic = cvMat(3, 3, CV_32F, r_intrinsic_data); + float l_distortion_data[] = {0,0,0,0,0}, r_distortion_data[] = {0,0,0,0,0}; + CvMat l_distortion = cvMat(1, 5, CV_32F, l_distortion_data); + CvMat r_distortion = cvMat(1, 5, CV_32F, r_distortion_data); + IplImage* mx = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1); + IplImage* my = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1); + int k, j; + + for( k = 0; k < 2; k++ ) + { + const char* section_name = k == 0 ? "[left_camera]" : "[right_camera]"; + static const char* param_names[] = { "f ", "fy", "Cx", "Cy" "kappa1", "kappa2", "tau1", "tau2", "kappa3", 0 }; + const char* section_start = strstr( info, section_name ); + CvMat* intrinsic = k == 0 ? &l_intrinsic : &r_intrinsic; + CvMat* distortion = k == 0 ? &l_distortion : &r_distortion; + CvMat* rectification = k == 0 ? &l_rect : &r_rect; + IplImage** dst = k == 0 ? ml : mr; + if( !section_start ) + break; + section_start += strlen(section_name); + for( j = 0; param_names[j] != 0; j++ ) + { + const char* param_value_start = strstr(section_start, param_names[j]); + float val=0; + if(!param_value_start) + break; + sscanf(param_value_start + strlen(param_names[j]), "%f", &val); + if( j < 4 ) + intrinsic->data.fl[j == 0 ? 0 : j == 1 ? 4 : j == 2 ? 2 : 5] = val; + else + distortion->data.fl[j - 4] = val; + } + if( param_names[j] != 0 ) + break; + + // some sanity check for the principal point + if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.1 || + fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.1 ) + { + cvScale( &intrinsic, &intrinsic, 0.5 ); // try the corrected intrinsic matrix for 2x lower resolution + if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.05 || + fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.05 ) + cvScale( &intrinsic, &intrinsic, 2 ); // revert it back if the new variant is not much better + intrinsic->data.fl[8] = 1; + } + + cvInitUndistortRectifyMap( intrinsic, distortion, + rectification, intrinsic, mx, my ); + cvConvertMaps( mx, my, dst[0], dst[1] ); + } + + cvReleaseImage( &mx ); + cvReleaseImage( &my ); + return k >= 2; +} + + +CvCapture* cvCreateCameraCapture_DC1394_2(int index) +{ + CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP; + + if (capture->open(index)) + return capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dshow.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dshow.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_dshow.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_dshow.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3379 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if (defined WIN32 || defined _WIN32) && defined HAVE_DSHOW + +/* + DirectShow-based Video Capturing module is based on + videoInput library by Theodore Watson: + http://muonics.net/school/spring05/videoInput/ + + Below is the original copyright +*/ + +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +//THE SOFTWARE. + +////////////////////////////////////////////////////////// +//Written by Theodore Watson - theo.watson@gmail.com // +//Do whatever you want with this code but if you find // +//a bug or make an improvement I would love to know! // +// // +//Warning This code is experimental // +//use at your own risk :) // +////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +/* Shoutouts + +Thanks to: + + Dillip Kumar Kara for crossbar code. + Zachary Lieberman for getting me into this stuff + and for being so generous with time and code. + The guys at Potion Design for helping me with VC++ + Josh Fisher for being a serious C++ nerd :) + Golan Levin for helping me debug the strangest + and slowest bug in the world! + + And all the people using this library who send in + bugs, suggestions and improvements who keep me working on + the next version - yeah thanks a lot ;) + +*/ +///////////////////////////////////////////////////////// + +#include "precomp.hpp" + +#if defined _MSC_VER && _MSC_VER >= 100 +//'sprintf': name was marked as #pragma deprecated +#pragma warning(disable: 4995) +#endif + +#include +#include +#include +#include +#include +#include + +#include + +//Include Directshow stuff here so we don't worry about needing all the h files. +#if defined _MSC_VER && _MSC_VER >= 1500 +# include "DShow.h" +# include "strmif.h" +# include "Aviriff.h" +# include "dvdmedia.h" +# include "bdaiface.h" +#else +# ifdef _MSC_VER +# define __extension__ + typedef BOOL WINBOOL; +#endif + +#include "dshow/dshow.h" +#include "dshow/dvdmedia.h" +#include "dshow/bdatypes.h" + +interface IEnumPIDMap : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG cRequest, + /* [size_is][out][in] */ PID_MAP *pPIDMap, + /* [out] */ ULONG *pcReceived) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG cRecords) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumPIDMap **ppIEnumPIDMap) = 0; + + virtual ~IEnumPIDMap() {} +}; + +interface IMPEG2PIDMap : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE MapPID( + /* [in] */ ULONG culPID, + /* [in] */ ULONG *pulPID, + /* [in] */ MEDIA_SAMPLE_CONTENT MediaSampleContent) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnmapPID( + /* [in] */ ULONG culPID, + /* [in] */ ULONG *pulPID) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumPIDMap( + /* [out] */ IEnumPIDMap **pIEnumPIDMap) = 0; + + virtual ~IMPEG2PIDMap() {} +}; + +#endif + +//for threading +#include + +//this is for TryEnterCriticalSection +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x400 +#endif + + +/* +MEDIASUBTYPE_I420 : TGUID ='{30323449-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_Y800 : TGUID ='{30303859-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_Y8 : TGUID ='{20203859-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_Y160 : TGUID ='{30363159-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_YV16 : TGUID ='{32315659-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_Y422 : TGUID ='{32323459-0000-0010-8000-00AA00389B71}'; +MEDIASUBTYPE_GREY : TGUID ='{59455247-0000-0010-8000-00AA00389B71}'; +*/ + +#include + +DEFINE_GUID(MEDIASUBTYPE_GREY, 0x59455247, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); +DEFINE_GUID(MEDIASUBTYPE_Y8, 0x20203859, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); +DEFINE_GUID(MEDIASUBTYPE_Y800, 0x30303859, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + +DEFINE_GUID(CLSID_CaptureGraphBuilder2,0xbf87b6e1,0x8c27,0x11d0,0xb3,0xf0,0x00,0xaa,0x00,0x37,0x61,0xc5); +DEFINE_GUID(CLSID_FilterGraph,0xe436ebb3,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(CLSID_NullRenderer,0xc1f400a4,0x3f08,0x11d3,0x9f,0x0b,0x00,0x60,0x08,0x03,0x9e,0x37); +DEFINE_GUID(CLSID_SampleGrabber,0xc1f400a0,0x3f08,0x11d3,0x9f,0x0b,0x00,0x60,0x08,0x03,0x9e,0x37); +DEFINE_GUID(CLSID_SystemDeviceEnum,0x62be5d10,0x60eb,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86); +DEFINE_GUID(CLSID_VideoInputDeviceCategory,0x860bb310,0x5d01,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86); +DEFINE_GUID(FORMAT_VideoInfo,0x05589f80,0xc356,0x11ce,0xbf,0x01,0x00,0xaa,0x00,0x55,0x59,0x5a); +DEFINE_GUID(IID_IAMAnalogVideoDecoder,0xc6e13350,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56); +DEFINE_GUID(IID_IAMCameraControl,0xc6e13370,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56); +DEFINE_GUID(IID_IAMCrossbar,0xc6e13380,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56); +DEFINE_GUID(IID_IAMStreamConfig,0xc6e13340,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56); +DEFINE_GUID(IID_IAMVideoProcAmp,0xc6e13360,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56); +DEFINE_GUID(IID_IBaseFilter,0x56a86895,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(IID_ICaptureGraphBuilder2,0x93e5a4e0,0x2d50,0x11d2,0xab,0xfa,0x00,0xa0,0xc9,0xc6,0xe3,0x8d); +DEFINE_GUID(IID_ICreateDevEnum,0x29840822,0x5b84,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86); +DEFINE_GUID(IID_IGraphBuilder,0x56a868a9,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(IID_IMPEG2PIDMap,0xafb6c2a1,0x2c41,0x11d3,0x8a,0x60,0x00,0x00,0xf8,0x1e,0x0e,0x4a); +DEFINE_GUID(IID_IMediaControl,0x56a868b1,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(IID_IMediaFilter,0x56a86899,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(IID_ISampleGrabber,0x6b652fff,0x11fe,0x4fce,0x92,0xad,0x02,0x66,0xb5,0xd7,0xc7,0x8f); +DEFINE_GUID(LOOK_UPSTREAM_ONLY,0xac798be0,0x98e3,0x11d1,0xb3,0xf1,0x00,0xaa,0x00,0x37,0x61,0xc5); +DEFINE_GUID(MEDIASUBTYPE_AYUV,0x56555941,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_IYUV,0x56555949,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_RGB24,0xe436eb7d,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(MEDIASUBTYPE_RGB32,0xe436eb7e,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(MEDIASUBTYPE_RGB555,0xe436eb7c,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(MEDIASUBTYPE_RGB565,0xe436eb7b,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_GUID(MEDIASUBTYPE_I420,0x49343230,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_UYVY,0x59565955,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_Y211,0x31313259,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_Y411,0x31313459,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_Y41P,0x50313459,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_YUY2,0x32595559,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_YUYV,0x56595559,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_YV12,0x32315659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_YVU9,0x39555659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_YVYU,0x55595659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIASUBTYPE_MJPG,0x47504A4D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); // MGB +DEFINE_GUID(MEDIATYPE_Interleaved,0x73766169,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MEDIATYPE_Video,0x73646976,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(PIN_CATEGORY_CAPTURE,0xfb6c4281,0x0353,0x11d1,0x90,0x5f,0x00,0x00,0xc0,0xcc,0x16,0xba); +DEFINE_GUID(PIN_CATEGORY_PREVIEW,0xfb6c4282,0x0353,0x11d1,0x90,0x5f,0x00,0x00,0xc0,0xcc,0x16,0xba); + +interface ISampleGrabberCB : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE SampleCB( + double SampleTime, + IMediaSample *pSample) = 0; + + virtual HRESULT STDMETHODCALLTYPE BufferCB( + double SampleTime, + BYTE *pBuffer, + LONG BufferLen) = 0; + + virtual ~ISampleGrabberCB() {} +}; + +interface ISampleGrabber : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE SetOneShot( + BOOL OneShot) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetMediaType( + const AM_MEDIA_TYPE *pType) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( + AM_MEDIA_TYPE *pType) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( + BOOL BufferThem) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( + LONG *pBufferSize, + LONG *pBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( + IMediaSample **ppSample) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCallback( + ISampleGrabberCB *pCallback, + LONG WhichMethodToCallback) = 0; + + virtual ~ISampleGrabber() {} +}; + +#ifndef HEADER +#define HEADER(p) (&(((VIDEOINFOHEADER*)(p))->bmiHeader)) +#endif + +//Example Usage +/* + //create a videoInput object + videoInput VI; + + //Prints out a list of available devices and returns num of devices found + int numDevices = VI.listDevices(); + + int device1 = 0; //this could be any deviceID that shows up in listDevices + int device2 = 1; //this could be any deviceID that shows up in listDevices + + //if you want to capture at a different frame rate (default is 30) + //specify it here, you are not guaranteed to get this fps though. + //VI.setIdealFramerate(dev, 60); + + //setup the first device - there are a number of options: + + VI.setupDevice(device1); //setup the first device with the default settings + //VI.setupDevice(device1, VI_COMPOSITE); //or setup device with specific connection type + //VI.setupDevice(device1, 320, 240); //or setup device with specified video size + //VI.setupDevice(device1, 320, 240, VI_COMPOSITE); //or setup device with video size and connection type + + //VI.setFormat(device1, VI_NTSC_M); //if your card doesn't remember what format it should be + //call this with the appropriate format listed above + //NOTE: must be called after setupDevice! + + //optionally setup a second (or third, fourth ...) device - same options as above + VI.setupDevice(device2); + + //As requested width and height can not always be accomodated + //make sure to check the size once the device is setup + + int width = VI.getWidth(device1); + int height = VI.getHeight(device1); + int size = VI.getSize(device1); + + unsigned char * yourBuffer1 = new unsigned char[size]; + unsigned char * yourBuffer2 = new unsigned char[size]; + + //to get the data from the device first check if the data is new + if(VI.isFrameNew(device1)){ + VI.getPixels(device1, yourBuffer1, false, false); //fills pixels as a BGR (for openCV) unsigned char array - no flipping + VI.getPixels(device1, yourBuffer2, true, true); //fills pixels as a RGB (for openGL) unsigned char array - flipping! + } + + //same applies to device2 etc + + //to get a settings dialog for the device + VI.showSettingsWindow(device1); + + + //Shut down devices properly + VI.stopDevice(device1); + VI.stopDevice(device2); +*/ + + +////////////////////////////////////// VARS AND DEFS ////////////////////////////////// + + +//STUFF YOU CAN CHANGE + +//change for verbose debug info +static bool verbose = true; + +//if you need VI to use multi threaded com +//#define VI_COM_MULTI_THREADED + +//STUFF YOU DON'T CHANGE + +//videoInput defines +#define VI_VERSION 0.1995 +#define VI_MAX_CAMERAS 20 +#define VI_NUM_TYPES 20 //MGB +#define VI_NUM_FORMATS 18 //DON'T TOUCH + +//defines for setPhyCon - tuner is not as well supported as composite and s-video +#define VI_COMPOSITE 0 +#define VI_S_VIDEO 1 +#define VI_TUNER 2 +#define VI_USB 3 +#define VI_1394 4 + +//defines for formats +#define VI_NTSC_M 0 +#define VI_PAL_B 1 +#define VI_PAL_D 2 +#define VI_PAL_G 3 +#define VI_PAL_H 4 +#define VI_PAL_I 5 +#define VI_PAL_M 6 +#define VI_PAL_N 7 +#define VI_PAL_NC 8 +#define VI_SECAM_B 9 +#define VI_SECAM_D 10 +#define VI_SECAM_G 11 +#define VI_SECAM_H 12 +#define VI_SECAM_K 13 +#define VI_SECAM_K1 14 +#define VI_SECAM_L 15 +#define VI_NTSC_M_J 16 +#define VI_NTSC_433 17 + + +//allows us to directShow classes here with the includes in the cpp +struct ICaptureGraphBuilder2; +struct IGraphBuilder; +struct IBaseFilter; +struct IAMCrossbar; +struct IMediaControl; +struct ISampleGrabber; +struct IMediaEventEx; +struct IAMStreamConfig; +struct _AMMediaType; +class SampleGrabberCallback; +typedef _AMMediaType AM_MEDIA_TYPE; + +//keeps track of how many instances of VI are being used +//don't touch +//static int comInitCount = 0; + + +//////////////////////////////////////// VIDEO DEVICE /////////////////////////////////// + +class videoDevice{ + + + public: + + videoDevice(); + void setSize(int w, int h); + void NukeDownstream(IBaseFilter *pBF); + void destroyGraph(); + ~videoDevice(); + + int videoSize; + int width; + int height; + + int tryWidth; + int tryHeight; + GUID tryVideoType; + + ICaptureGraphBuilder2 *pCaptureGraph; // Capture graph builder object + IGraphBuilder *pGraph; // Graph builder object + IMediaControl *pControl; // Media control object + IBaseFilter *pVideoInputFilter; // Video Capture filter + IBaseFilter *pGrabberF; + IBaseFilter * pDestFilter; + IAMStreamConfig *streamConf; + ISampleGrabber * pGrabber; // Grabs frame + AM_MEDIA_TYPE * pAmMediaType; + + IMediaEventEx * pMediaEvent; + + GUID videoType; + long formatType; + + SampleGrabberCallback * sgCallback; + + bool tryDiffSize; + bool useCrossbar; + bool readyToCapture; + bool sizeSet; + bool setupStarted; + bool specificFormat; + bool autoReconnect; + int nFramesForReconnect; + unsigned long nFramesRunning; + int connection; + int storeConn; + int myID; + long requestedFrameTime; //ie fps + + char nDeviceName[255]; + WCHAR wDeviceName[255]; + + unsigned char * pixels; + char * pBuffer; + +}; + + + + +////////////////////////////////////// VIDEO INPUT ///////////////////////////////////// + + + +class videoInput{ + + public: + videoInput(); + ~videoInput(); + + //turns off console messages - default is to print messages + static void setVerbose(bool _verbose); + + //Functions in rough order they should be used. + static int listDevices(bool silent = false); + + //needs to be called after listDevices - otherwise returns NULL + static char * getDeviceName(int deviceID); + + //choose to use callback based capture - or single threaded + void setUseCallback(bool useCallback); + + //call before setupDevice + //directshow will try and get the closest possible framerate to what is requested + void setIdealFramerate(int deviceID, int idealFramerate); + + //some devices will stop delivering frames after a while - this method gives you the option to try and reconnect + //to a device if videoInput detects that a device has stopped delivering frames. + //you MUST CALL isFrameNew every app loop for this to have any effect + void setAutoReconnectOnFreeze(int deviceNumber, bool doReconnect, int numMissedFramesBeforeReconnect); + + //Choose one of these five to setup your device + bool setupDevice(int deviceID); + bool setupDevice(int deviceID, int w, int h); + bool setupDeviceFourcc(int deviceID, int w, int h,int fourcc); + + //These two are only for capture cards + //USB and Firewire cameras souldn't specify connection + bool setupDevice(int deviceID, int connection); + bool setupDevice(int deviceID, int w, int h, int connection); + + bool setFourcc(int deviceNumber, int fourcc); + + //If you need to you can set your NTSC/PAL/SECAM + //preference here. if it is available it will be used. + //see #defines above for available formats - eg VI_NTSC_M or VI_PAL_B + //should be called after setupDevice + //can be called multiple times + bool setFormat(int deviceNumber, int format); + + //Tells you when a new frame has arrived - you should call this if you have specified setAutoReconnectOnFreeze to true + bool isFrameNew(int deviceID); + + bool isDeviceSetup(int deviceID); + + //Returns the pixels - flipRedAndBlue toggles RGB/BGR flipping - and you can flip the image too + unsigned char * getPixels(int deviceID, bool flipRedAndBlue = true, bool flipImage = false); + + //Or pass in a buffer for getPixels to fill returns true if successful. + bool getPixels(int id, unsigned char * pixels, bool flipRedAndBlue = true, bool flipImage = false); + + //Launches a pop up settings window + //For some reason in GLUT you have to call it twice each time. + void showSettingsWindow(int deviceID); + + //Manual control over settings thanks..... + //These are experimental for now. + bool setVideoSettingFilter(int deviceID, long Property, long lValue, long Flags = 0, bool useDefaultValue = false); + bool setVideoSettingFilterPct(int deviceID, long Property, float pctValue, long Flags = 0); + bool getVideoSettingFilter(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue); + + bool setVideoSettingCamera(int deviceID, long Property, long lValue, long Flags = 0, bool useDefaultValue = false); + bool setVideoSettingCameraPct(int deviceID, long Property, float pctValue, long Flags = 0); + bool getVideoSettingCamera(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue); + + //bool setVideoSettingCam(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false); + + //get width, height and number of pixels + int getWidth(int deviceID); + int getHeight(int deviceID); + int getSize(int deviceID); + int getFourcc(int deviceID); + double getFPS(int deviceID); + + //completely stops and frees a device + void stopDevice(int deviceID); + + //as above but then sets it up with same settings + bool restartDevice(int deviceID); + + //number of devices available + int devicesFound; + + // mapping from OpenCV CV_CAP_PROP to videoinput/dshow properties + int getVideoPropertyFromCV(int cv_property); + int getCameraPropertyFromCV(int cv_property); + + private: + void setPhyCon(int deviceID, int conn); + void setAttemptCaptureSize(int deviceID, int w, int h,GUID mediaType=MEDIASUBTYPE_RGB24); + bool setup(int deviceID); + void processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip); + int start(int deviceID, videoDevice * VD); + int getDeviceCount(); + void getMediaSubtypeAsString(GUID type, char * typeAsString); + GUID *getMediaSubtypeFromFourcc(int fourcc); + int getFourccFromMediaSubtype(GUID type); + + void getVideoPropertyAsString(int prop, char * propertyAsString); + void getCameraPropertyAsString(int prop, char * propertyAsString); + + HRESULT getDevice(IBaseFilter **pSrcFilter, int deviceID, WCHAR * wDeviceName, char * nDeviceName); + static HRESULT ShowFilterPropertyPages(IBaseFilter *pFilter); + static HRESULT ShowStreamPropertyPages(IAMStreamConfig *pStream); + + HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath); + HRESULT routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter **pVidInFilter, int conType, GUID captureMode); + + //don't touch + static bool comInit(); + static bool comUnInit(); + + int connection; + int callbackSetCount; + bool bCallback; + + GUID CAPTURE_MODE; + + //Extra video subtypes + GUID MEDIASUBTYPE_Y800; + GUID MEDIASUBTYPE_Y8; + GUID MEDIASUBTYPE_GREY; + + videoDevice * VDList[VI_MAX_CAMERAS]; + GUID mediaSubtypes[VI_NUM_TYPES]; + long formatTypes[VI_NUM_FORMATS]; + + static void __cdecl basicThread(void * objPtr); + + static char deviceNames[VI_MAX_CAMERAS][255]; + +}; + +/////////////////////////// HANDY FUNCTIONS ///////////////////////////// + +static void MyFreeMediaType(AM_MEDIA_TYPE& mt){ + if (mt.cbFormat != 0) + { + CoTaskMemFree((PVOID)mt.pbFormat); + mt.cbFormat = 0; + mt.pbFormat = NULL; + } + if (mt.pUnk != NULL) + { + // Unecessary because pUnk should not be used, but safest. + mt.pUnk->Release(); + mt.pUnk = NULL; + } +} + +static void MyDeleteMediaType(AM_MEDIA_TYPE *pmt) +{ + if (pmt != NULL) + { + MyFreeMediaType(*pmt); + CoTaskMemFree(pmt); + } +} + +////////////////////////////// CALLBACK //////////////////////////////// + +//Callback class +class SampleGrabberCallback : public ISampleGrabberCB{ +public: + + //------------------------------------------------ + SampleGrabberCallback(){ + InitializeCriticalSection(&critSection); + freezeCheck = 0; + + + bufferSetup = false; + newFrame = false; + latestBufferLength = 0; + + hEvent = CreateEvent(NULL, true, false, NULL); + } + + + //------------------------------------------------ + virtual ~SampleGrabberCallback(){ + ptrBuffer = NULL; + DeleteCriticalSection(&critSection); + CloseHandle(hEvent); + if(bufferSetup){ + delete[] pixels; + } + } + + + //------------------------------------------------ + bool setupBuffer(int numBytesIn){ + if(bufferSetup){ + return false; + }else{ + numBytes = numBytesIn; + pixels = new unsigned char[numBytes]; + bufferSetup = true; + newFrame = false; + latestBufferLength = 0; + } + return true; + } + + + //------------------------------------------------ + STDMETHODIMP_(ULONG) AddRef() { return 1; } + STDMETHODIMP_(ULONG) Release() { return 2; } + + + //------------------------------------------------ + STDMETHODIMP QueryInterface(REFIID, void **ppvObject){ + *ppvObject = static_cast(this); + return S_OK; + } + + + //This method is meant to have less overhead + //------------------------------------------------ + STDMETHODIMP SampleCB(double , IMediaSample *pSample){ + if(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) return S_OK; + + HRESULT hr = pSample->GetPointer(&ptrBuffer); + + if(hr == S_OK){ + latestBufferLength = pSample->GetActualDataLength(); + if(latestBufferLength == numBytes){ + EnterCriticalSection(&critSection); + memcpy(pixels, ptrBuffer, latestBufferLength); + newFrame = true; + freezeCheck = 1; + LeaveCriticalSection(&critSection); + SetEvent(hEvent); + }else{ + printf("ERROR: SampleCB() - buffer sizes do not match\n"); + } + } + + return S_OK; + } + + + //This method is meant to have more overhead + STDMETHODIMP BufferCB(double, BYTE *, long){ + return E_NOTIMPL; + } + + int freezeCheck; + + int latestBufferLength; + int numBytes; + bool newFrame; + bool bufferSetup; + unsigned char * pixels; + unsigned char * ptrBuffer; + CRITICAL_SECTION critSection; + HANDLE hEvent; +}; + + +////////////////////////////// VIDEO DEVICE //////////////////////////////// + +// ---------------------------------------------------------------------- +// Should this class also be the callback? +// +// ---------------------------------------------------------------------- + +videoDevice::videoDevice(){ + + pCaptureGraph = NULL; // Capture graph builder object + pGraph = NULL; // Graph builder object + pControl = NULL; // Media control object + pVideoInputFilter = NULL; // Video Capture filter + pGrabber = NULL; // Grabs frame + pDestFilter = NULL; // Null Renderer Filter + pGrabberF = NULL; // Grabber Filter + pMediaEvent = NULL; + streamConf = NULL; + pAmMediaType = NULL; + + //This is our callback class that processes the frame. + sgCallback = new SampleGrabberCallback(); + sgCallback->newFrame = false; + + //Default values for capture type + videoType = MEDIASUBTYPE_RGB24; + connection = PhysConn_Video_Composite; + storeConn = 0; + + videoSize = 0; + width = 0; + height = 0; + + tryWidth = 640; + tryHeight = 480; + tryVideoType = MEDIASUBTYPE_RGB24; + nFramesForReconnect= 10000; + nFramesRunning = 0; + myID = -1; + + tryDiffSize = true; + useCrossbar = false; + readyToCapture = false; + sizeSet = false; + setupStarted = false; + specificFormat = false; + autoReconnect = false; + requestedFrameTime = -1; + + memset(wDeviceName, 0, sizeof(WCHAR) * 255); + memset(nDeviceName, 0, sizeof(char) * 255); + +} + + +// ---------------------------------------------------------------------- +// The only place we are doing new +// +// ---------------------------------------------------------------------- + +void videoDevice::setSize(int w, int h){ + if(sizeSet){ + if(verbose)printf("SETUP: Error device size should not be set more than once \n"); + } + else + { + width = w; + height = h; + videoSize = w*h*3; + sizeSet = true; + pixels = new unsigned char[videoSize]; + pBuffer = new char[videoSize]; + + memset(pixels, 0 , videoSize); + sgCallback->setupBuffer(videoSize); + + } +} + + +// ---------------------------------------------------------------------- +// Borrowed from the SDK, use it to take apart the graph from +// the capture device downstream to the null renderer +// ---------------------------------------------------------------------- + +void videoDevice::NukeDownstream(IBaseFilter *pBF){ + IPin *pP, *pTo; + ULONG u; + IEnumPins *pins = NULL; + PIN_INFO pininfo; + HRESULT hr = pBF->EnumPins(&pins); + pins->Reset(); + while (hr == NOERROR) + { + hr = pins->Next(1, &pP, &u); + if (hr == S_OK && pP) + { + pP->ConnectedTo(&pTo); + if (pTo) + { + hr = pTo->QueryPinInfo(&pininfo); + if (hr == NOERROR) + { + if (pininfo.dir == PINDIR_INPUT) + { + NukeDownstream(pininfo.pFilter); + pGraph->Disconnect(pTo); + pGraph->Disconnect(pP); + pGraph->RemoveFilter(pininfo.pFilter); + } + pininfo.pFilter->Release(); + pininfo.pFilter = NULL; + } + pTo->Release(); + } + pP->Release(); + } + } + if (pins) pins->Release(); +} + + +// ---------------------------------------------------------------------- +// Also from SDK +// ---------------------------------------------------------------------- + +void videoDevice::destroyGraph(){ + HRESULT hr = 0; + //int FuncRetval=0; + //int NumFilters=0; + + int i = 0; + while (hr == NOERROR) + { + IEnumFilters * pEnum = 0; + ULONG cFetched; + + // We must get the enumerator again every time because removing a filter from the graph + // invalidates the enumerator. We always get only the first filter from each enumerator. + hr = pGraph->EnumFilters(&pEnum); + if (FAILED(hr)) { if(verbose)printf("SETUP: pGraph->EnumFilters() failed. \n"); return; } + + IBaseFilter * pFilter = NULL; + if (pEnum->Next(1, &pFilter, &cFetched) == S_OK) + { + FILTER_INFO FilterInfo; + memset(&FilterInfo, 0, sizeof(FilterInfo)); + hr = pFilter->QueryFilterInfo(&FilterInfo); + FilterInfo.pGraph->Release(); + + int count = 0; + char buffer[255]; + memset(buffer, 0, 255 * sizeof(char)); + + while( FilterInfo.achName[count] != 0x00 ) + { + buffer[count] = (char)FilterInfo.achName[count]; + count++; + } + + if(verbose)printf("SETUP: removing filter %s...\n", buffer); + hr = pGraph->RemoveFilter(pFilter); + if (FAILED(hr)) { if(verbose)printf("SETUP: pGraph->RemoveFilter() failed. \n"); return; } + if(verbose)printf("SETUP: filter removed %s \n",buffer); + + pFilter->Release(); + pFilter = NULL; + } + else break; + pEnum->Release(); + pEnum = NULL; + i++; + } + + return; +} + + +// ---------------------------------------------------------------------- +// Our deconstructor, attempts to tear down graph and release filters etc +// Does checking to make sure it only is freeing if it needs to +// Probably could be a lot cleaner! :) +// ---------------------------------------------------------------------- + +videoDevice::~videoDevice(){ + + if(setupStarted){ if(verbose)printf("\nSETUP: Disconnecting device %i\n", myID); } + else{ + if(sgCallback){ + sgCallback->Release(); + delete sgCallback; + } + return; + } + + HRESULT HR = NOERROR; + + //Stop the callback and free it + if( (sgCallback) && (pGrabber) ) + { + pGrabber->SetCallback(NULL, 1); + if(verbose)printf("SETUP: freeing Grabber Callback\n"); + sgCallback->Release(); + + //delete our pixels + if(sizeSet){ + delete[] pixels; + delete[] pBuffer; + } + + delete sgCallback; + } + + //Check to see if the graph is running, if so stop it. + if( (pControl) ) + { + HR = pControl->Pause(); + if (FAILED(HR)) if(verbose)printf("ERROR - Could not pause pControl\n"); + + HR = pControl->Stop(); + if (FAILED(HR)) if(verbose)printf("ERROR - Could not stop pControl\n"); + } + + //Disconnect filters from capture device + if( (pVideoInputFilter) )NukeDownstream(pVideoInputFilter); + + //Release and zero pointers to our filters etc + if( (pDestFilter) ){ if(verbose)printf("SETUP: freeing Renderer \n"); + (pDestFilter)->Release(); + (pDestFilter) = 0; + } + if( (pVideoInputFilter) ){ if(verbose)printf("SETUP: freeing Capture Source \n"); + (pVideoInputFilter)->Release(); + (pVideoInputFilter) = 0; + } + if( (pGrabberF) ){ if(verbose)printf("SETUP: freeing Grabber Filter \n"); + (pGrabberF)->Release(); + (pGrabberF) = 0; + } + if( (pGrabber) ){ if(verbose)printf("SETUP: freeing Grabber \n"); + (pGrabber)->Release(); + (pGrabber) = 0; + } + if( (pControl) ){ if(verbose)printf("SETUP: freeing Control \n"); + (pControl)->Release(); + (pControl) = 0; + } + if( (pMediaEvent) ){ if(verbose)printf("SETUP: freeing Media Event \n"); + (pMediaEvent)->Release(); + (pMediaEvent) = 0; + } + if( (streamConf) ){ if(verbose)printf("SETUP: freeing Stream \n"); + (streamConf)->Release(); + (streamConf) = 0; + } + + if( (pAmMediaType) ){ if(verbose)printf("SETUP: freeing Media Type \n"); + MyDeleteMediaType(pAmMediaType); + } + + if((pMediaEvent)){ + if(verbose)printf("SETUP: freeing Media Event \n"); + (pMediaEvent)->Release(); + (pMediaEvent) = 0; + } + + //Destroy the graph + if( (pGraph) )destroyGraph(); + + //Release and zero our capture graph and our main graph + if( (pCaptureGraph) ){ if(verbose)printf("SETUP: freeing Capture Graph \n"); + (pCaptureGraph)->Release(); + (pCaptureGraph) = 0; + } + if( (pGraph) ){ if(verbose)printf("SETUP: freeing Main Graph \n"); + (pGraph)->Release(); + (pGraph) = 0; + } + + //delete our pointers + delete pDestFilter; + delete pVideoInputFilter; + delete pGrabberF; + delete pGrabber; + delete pControl; + delete streamConf; + delete pMediaEvent; + delete pCaptureGraph; + delete pGraph; + + if(verbose)printf("SETUP: Device %i disconnected and freed\n\n",myID); +} + + +////////////////////////////// VIDEO INPUT //////////////////////////////// +//////////////////////////// PUBLIC METHODS /////////////////////////////// + + +// ---------------------------------------------------------------------- +// Constructor - creates instances of videoDevice and adds the various +// media subtypes to check. +// ---------------------------------------------------------------------- + +videoInput::videoInput(){ + //start com + comInit(); + + devicesFound = 0; + callbackSetCount = 0; + bCallback = true; + + //setup a max no of device objects + for(int i=0; i= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return; + + if( idealFramerate > 0 ){ + VDList[deviceNumber]->requestedFrameTime = (unsigned long)(10000000 / idealFramerate); + } +} + + +// ---------------------------------------------------------------------- +// Set the requested framerate - no guarantee you will get this +// +// ---------------------------------------------------------------------- + +void videoInput::setAutoReconnectOnFreeze(int deviceNumber, bool doReconnect, int numMissedFramesBeforeReconnect){ + if(deviceNumber >= VI_MAX_CAMERAS) return; + + VDList[deviceNumber]->autoReconnect = doReconnect; + VDList[deviceNumber]->nFramesForReconnect = numMissedFramesBeforeReconnect; + +} + + +// ---------------------------------------------------------------------- +// Setup a device with the default settings +// +// ---------------------------------------------------------------------- + +bool videoInput::setupDevice(int deviceNumber){ + if(deviceNumber >= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return false; + + if(setup(deviceNumber))return true; + return false; +} + + +// ---------------------------------------------------------------------- +// Setup a device with the default size but specify input type +// +// ---------------------------------------------------------------------- + +bool videoInput::setupDevice(int deviceNumber, int _connection){ + if(deviceNumber >= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return false; + + setPhyCon(deviceNumber, _connection); + if(setup(deviceNumber))return true; + return false; +} + + +// ---------------------------------------------------------------------- +// Setup a device with the default connection but specify size +// +// ---------------------------------------------------------------------- + +bool videoInput::setupDevice(int deviceNumber, int w, int h){ + if(deviceNumber >= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return false; + + setAttemptCaptureSize(deviceNumber,w,h); + if(setup(deviceNumber))return true; + return false; +} + +// ---------------------------------------------------------------------- +// Setup a device with the default connection but specify size and image format +// +// Note: +// Need a new name for this since signature clashes with ",int connection)" +// ---------------------------------------------------------------------- + +bool videoInput::setupDeviceFourcc(int deviceNumber, int w, int h,int fourcc){ + if(deviceNumber >= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return false; + + if ( fourcc != -1 ) { + GUID *mediaType = getMediaSubtypeFromFourcc(fourcc); + if ( mediaType ) { + setAttemptCaptureSize(deviceNumber,w,h,*mediaType); + } + } else { + setAttemptCaptureSize(deviceNumber,w,h); + } + if(setup(deviceNumber))return true; + return false; +} + + +// ---------------------------------------------------------------------- +// Setup a device with specific size and connection +// +// ---------------------------------------------------------------------- + +bool videoInput::setupDevice(int deviceNumber, int w, int h, int _connection){ + if(deviceNumber >= VI_MAX_CAMERAS || VDList[deviceNumber]->readyToCapture) return false; + + setAttemptCaptureSize(deviceNumber,w,h); + setPhyCon(deviceNumber, _connection); + if(setup(deviceNumber))return true; + return false; +} + + +// ---------------------------------------------------------------------- +// Setup the default video format of the device +// Must be called after setup! +// See #define formats in header file (eg VI_NTSC_M ) +// +// ---------------------------------------------------------------------- + +bool videoInput::setFormat(int deviceNumber, int format){ + if(deviceNumber >= VI_MAX_CAMERAS || !VDList[deviceNumber]->readyToCapture) return false; + + bool returnVal = false; + + if(format >= 0 && format < VI_NUM_FORMATS){ + VDList[deviceNumber]->formatType = formatTypes[format]; + VDList[deviceNumber]->specificFormat = true; + + if(VDList[deviceNumber]->specificFormat){ + + HRESULT hr = getDevice(&VDList[deviceNumber]->pVideoInputFilter, deviceNumber, VDList[deviceNumber]->wDeviceName, VDList[deviceNumber]->nDeviceName); + if(hr != S_OK){ + return false; + } + + IAMAnalogVideoDecoder *pVideoDec = NULL; + hr = VDList[deviceNumber]->pCaptureGraph->FindInterface(NULL, &MEDIATYPE_Video, VDList[deviceNumber]->pVideoInputFilter, IID_IAMAnalogVideoDecoder, (void **)&pVideoDec); + + + //in case the settings window some how freed them first + if(VDList[deviceNumber]->pVideoInputFilter)VDList[deviceNumber]->pVideoInputFilter->Release(); + if(VDList[deviceNumber]->pVideoInputFilter)VDList[deviceNumber]->pVideoInputFilter = NULL; + + if(FAILED(hr)){ + printf("SETUP: couldn't set requested format\n"); + }else{ + long lValue = 0; + hr = pVideoDec->get_AvailableTVFormats(&lValue); + if( SUCCEEDED(hr) && (lValue & VDList[deviceNumber]->formatType) ) + { + hr = pVideoDec->put_TVFormat(VDList[deviceNumber]->formatType); + if( FAILED(hr) ){ + printf("SETUP: couldn't set requested format\n"); + }else{ + returnVal = true; + } + } + + pVideoDec->Release(); + pVideoDec = NULL; + } + } + } + + return returnVal; +} + +// ---------------------------------------------------------------------- +// Our static function for returning device names - thanks Peter! +// Must call listDevices first. +// +// ---------------------------------------------------------------------- +char videoInput::deviceNames[VI_MAX_CAMERAS][255]={{0}}; + +char * videoInput::getDeviceName(int deviceID){ + if( deviceID >= VI_MAX_CAMERAS ){ + return NULL; + } + return deviceNames[deviceID]; +} + + +// ---------------------------------------------------------------------- +// Our static function for finding num devices available etc +// +// ---------------------------------------------------------------------- + +int videoInput::listDevices(bool silent){ + + //COM Library Intialization + comInit(); + + if(!silent)printf("\nVIDEOINPUT SPY MODE!\n\n"); + + + ICreateDevEnum *pDevEnum = NULL; + IEnumMoniker *pEnum = NULL; + int deviceCounter = 0; + + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, + CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, + reinterpret_cast(&pDevEnum)); + + + if (SUCCEEDED(hr)) + { + // Create an enumerator for the video capture category. + hr = pDevEnum->CreateClassEnumerator( + CLSID_VideoInputDeviceCategory, + &pEnum, 0); + + if(hr == S_OK){ + + if(!silent)printf("SETUP: Looking For Capture Devices\n"); + IMoniker *pMoniker = NULL; + + while (pEnum->Next(1, &pMoniker, NULL) == S_OK){ + + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, + (void**)(&pPropBag)); + + if (FAILED(hr)){ + pMoniker->Release(); + continue; // Skip this one, maybe the next one will work. + } + + + // Find the description or friendly name. + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"Description", &varName, 0); + + if (FAILED(hr)) hr = pPropBag->Read(L"FriendlyName", &varName, 0); + + if (SUCCEEDED(hr)){ + + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + + int count = 0; + int maxLen = sizeof(deviceNames[0])/sizeof(deviceNames[0][0]) - 2; + while( varName.bstrVal[count] != 0x00 && count < maxLen) { + deviceNames[deviceCounter][count] = (char)varName.bstrVal[count]; + count++; + } + deviceNames[deviceCounter][count] = 0; + + if(!silent)printf("SETUP: %i) %s \n",deviceCounter, deviceNames[deviceCounter]); + } + + pPropBag->Release(); + pPropBag = NULL; + + pMoniker->Release(); + pMoniker = NULL; + + deviceCounter++; + } + + pDevEnum->Release(); + pDevEnum = NULL; + + pEnum->Release(); + pEnum = NULL; + } + + if(!silent)printf("SETUP: %i Device(s) found\n\n", deviceCounter); + } + + comUnInit(); + + return deviceCounter; +} + + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- + +int videoInput::getWidth(int id){ + + if(isDeviceSetup(id)) + { + return VDList[id] ->width; + } + + return 0; + +} + + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- + +int videoInput::getHeight(int id){ + + if(isDeviceSetup(id)) + { + return VDList[id] ->height; + } + + return 0; + +} + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- +int videoInput::getFourcc(int id){ + + if(isDeviceSetup(id)) + { + return getFourccFromMediaSubtype(VDList[id]->videoType); + } + + return 0; + +} + +double videoInput::getFPS(int id){ + + if(isDeviceSetup(id)) + { + double frameTime= VDList[id]->requestedFrameTime; + if (frameTime>0) { + return (10000000.0 / frameTime); + } + } + + return 0; + +} + + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- + +int videoInput::getSize(int id){ + + if(isDeviceSetup(id)) + { + return VDList[id] ->videoSize; + } + + return 0; + +} + + +// ---------------------------------------------------------------------- +// Uses a supplied buffer +// ---------------------------------------------------------------------- + +bool videoInput::getPixels(int id, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage){ + + bool success = false; + + if(isDeviceSetup(id)){ + if(bCallback){ + //callback capture + + DWORD result = WaitForSingleObject(VDList[id]->sgCallback->hEvent, 1000); + if( result != WAIT_OBJECT_0) return false; + + //double paranoia - mutexing with both event and critical section + EnterCriticalSection(&VDList[id]->sgCallback->critSection); + + unsigned char * src = VDList[id]->sgCallback->pixels; + unsigned char * dst = dstBuffer; + int height = VDList[id]->height; + int width = VDList[id]->width; + + processPixels(src, dst, width, height, flipRedAndBlue, flipImage); + VDList[id]->sgCallback->newFrame = false; + + LeaveCriticalSection(&VDList[id]->sgCallback->critSection); + + ResetEvent(VDList[id]->sgCallback->hEvent); + + success = true; + + } + else{ + //regular capture method + long bufferSize = VDList[id]->videoSize; + HRESULT hr = VDList[id]->pGrabber->GetCurrentBuffer(&bufferSize, (long *)VDList[id]->pBuffer); + if(hr==S_OK){ + int numBytes = VDList[id]->videoSize; + if (numBytes == bufferSize){ + + unsigned char * src = (unsigned char * )VDList[id]->pBuffer; + unsigned char * dst = dstBuffer; + int height = VDList[id]->height; + int width = VDList[id]->width; + + processPixels(src, dst, width, height, flipRedAndBlue, flipImage); + success = true; + }else{ + if(verbose)printf("ERROR: GetPixels() - bufferSizes do not match!\n"); + } + }else{ + if(verbose)printf("ERROR: GetPixels() - Unable to grab frame for device %i\n", id); + } + } + } + + return success; +} + + +// ---------------------------------------------------------------------- +// Returns a buffer +// ---------------------------------------------------------------------- +unsigned char * videoInput::getPixels(int id, bool flipRedAndBlue, bool flipImage){ + + if(isDeviceSetup(id)){ + getPixels(id, VDList[id]->pixels, flipRedAndBlue, flipImage); + } + + return VDList[id]->pixels; +} + + + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- +bool videoInput::isFrameNew(int id){ + if(!isDeviceSetup(id)) return false; + if(!bCallback)return true; + + bool result = false; + bool freeze = false; + + //again super paranoia! + EnterCriticalSection(&VDList[id]->sgCallback->critSection); + result = VDList[id]->sgCallback->newFrame; + + //we need to give it some time at the begining to start up so lets check after 400 frames + if(VDList[id]->nFramesRunning > 400 && VDList[id]->sgCallback->freezeCheck > VDList[id]->nFramesForReconnect ){ + freeze = true; + } + + //we increment the freezeCheck var here - the callback resets it to 1 + //so as long as the callback is running this var should never get too high. + //if the callback is not running then this number will get high and trigger the freeze action below + VDList[id]->sgCallback->freezeCheck++; + LeaveCriticalSection(&VDList[id]->sgCallback->critSection); + + VDList[id]->nFramesRunning++; + + if(freeze && VDList[id]->autoReconnect){ + if(verbose)printf("ERROR: Device seems frozen - attempting to reconnect\n"); + if( !restartDevice(VDList[id]->myID) ){ + if(verbose)printf("ERROR: Unable to reconnect to device\n"); + }else{ + if(verbose)printf("SUCCESS: Able to reconnect to device\n"); + } + } + + return result; +} + + +// ---------------------------------------------------------------------- +// +// +// ---------------------------------------------------------------------- + +bool videoInput::isDeviceSetup(int id){ + + if(idreadyToCapture)return true; + else return false; + +} + + +// ---------------------------------------------------------------------- +// Gives us a little pop up window to adjust settings +// We do this in a seperate thread now! +// ---------------------------------------------------------------------- + + +void __cdecl videoInput::basicThread(void * objPtr){ + + //get a reference to the video device + //not a copy as we need to free the filter + videoDevice * vd = *( (videoDevice **)(objPtr) ); + ShowFilterPropertyPages(vd->pVideoInputFilter); + + + + //now we free the filter and make sure it set to NULL + if(vd->pVideoInputFilter)vd->pVideoInputFilter->Release(); + if(vd->pVideoInputFilter)vd->pVideoInputFilter = NULL; + + return; +} + +void videoInput::showSettingsWindow(int id){ + + if(isDeviceSetup(id)){ + //HANDLE myTempThread; + + //we reconnect to the device as we have freed our reference to it + //why have we freed our reference? because there seemed to be an issue + //with some mpeg devices if we didn't + HRESULT hr = getDevice(&VDList[id]->pVideoInputFilter, id, VDList[id]->wDeviceName, VDList[id]->nDeviceName); + if(hr == S_OK){ + //myTempThread = (HANDLE) + _beginthread(basicThread, 0, (void *)&VDList[id]); + } + } +} + + +// Set a video signal setting using IAMVideoProcAmp +bool videoInput::getVideoSettingFilter(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue){ + if( !isDeviceSetup(deviceID) )return false; + + HRESULT hr; + //bool isSuccessful = false; + + videoDevice * VD = VDList[deviceID]; + + hr = getDevice(&VD->pVideoInputFilter, deviceID, VD->wDeviceName, VD->nDeviceName); + if (FAILED(hr)){ + printf("setVideoSetting - getDevice Error\n"); + return false; + } + + IAMVideoProcAmp *pAMVideoProcAmp = NULL; + + hr = VD->pVideoInputFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pAMVideoProcAmp); + if(FAILED(hr)){ + printf("setVideoSetting - QueryInterface Error\n"); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + return false; + } + + char propStr[16]; + getVideoPropertyAsString(Property,propStr); + + if (verbose) printf("Setting video setting %s.\n", propStr); + + pAMVideoProcAmp->GetRange(Property, &min, &max, &SteppingDelta, &defaultValue, &flags); + if (verbose) printf("Range for video setting %s: Min:%ld Max:%ld SteppingDelta:%ld Default:%ld Flags:%ld\n", propStr, min, max, SteppingDelta, defaultValue, flags); + pAMVideoProcAmp->Get(Property, ¤tValue, &flags); + + if(pAMVideoProcAmp)pAMVideoProcAmp->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + + return true; + +} + + +// Set a video signal setting using IAMVideoProcAmp +bool videoInput::setVideoSettingFilterPct(int deviceID, long Property, float pctValue, long Flags){ + if( !isDeviceSetup(deviceID) )return false; + + long min, max, currentValue, flags, defaultValue, stepAmnt; + + if( !getVideoSettingFilter(deviceID, Property, min, max, stepAmnt, currentValue, flags, defaultValue) )return false; + + if(pctValue > 1.0)pctValue = 1.0; + else if(pctValue < 0)pctValue = 0.0; + + float range = (float)max - (float)min; + if(range <= 0)return false; + if(stepAmnt == 0) return false; + + long value = (long)( (float)min + range * pctValue ); + long rasterValue = value; + + //if the range is the stepAmnt then it is just a switch + //so we either set the value to low or high + if( range == stepAmnt ){ + if( pctValue < 0.5)rasterValue = min; + else rasterValue = max; + }else{ + //we need to rasterize the value to the stepping amnt + long mod = value % stepAmnt; + float halfStep = (float)stepAmnt * 0.5f; + if( mod < halfStep ) rasterValue -= mod; + else rasterValue += stepAmnt - mod; + printf("RASTER - pctValue is %f - value is %li - step is %li - mod is %li - rasterValue is %li\n", pctValue, value, stepAmnt, mod, rasterValue); + } + + return setVideoSettingFilter(deviceID, Property, rasterValue, Flags, false); +} + + +// Set a video signal setting using IAMVideoProcAmp +bool videoInput::setVideoSettingFilter(int deviceID, long Property, long lValue, long Flags, bool useDefaultValue){ + if( !isDeviceSetup(deviceID) )return false; + + HRESULT hr; + //bool isSuccessful = false; + + char propStr[16]; + getVideoPropertyAsString(Property,propStr); + + videoDevice * VD = VDList[deviceID]; + + hr = getDevice(&VD->pVideoInputFilter, deviceID, VD->wDeviceName, VD->nDeviceName); + if (FAILED(hr)){ + printf("setVideoSetting - getDevice Error\n"); + return false; + } + + IAMVideoProcAmp *pAMVideoProcAmp = NULL; + + hr = VD->pVideoInputFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pAMVideoProcAmp); + if(FAILED(hr)){ + printf("setVideoSetting - QueryInterface Error\n"); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + return false; + } + + if (verbose) printf("Setting video setting %s.\n", propStr); + long CurrVal, Min, Max, SteppingDelta, Default, CapsFlags, AvailableCapsFlags = 0; + + + pAMVideoProcAmp->GetRange(Property, &Min, &Max, &SteppingDelta, &Default, &AvailableCapsFlags); + if (verbose) printf("Range for video setting %s: Min:%ld Max:%ld SteppingDelta:%ld Default:%ld Flags:%ld\n", propStr, Min, Max, SteppingDelta, Default, AvailableCapsFlags); + pAMVideoProcAmp->Get(Property, &CurrVal, &CapsFlags); + + if (verbose) printf("Current value: %ld Flags %ld (%s)\n", CurrVal, CapsFlags, (CapsFlags == 1 ? "Auto" : (CapsFlags == 2 ? "Manual" : "Unknown"))); + + if (useDefaultValue) { + pAMVideoProcAmp->Set(Property, Default, VideoProcAmp_Flags_Auto); + } + else{ + // Perhaps add a check that lValue and Flags are within the range aquired from GetRange above + pAMVideoProcAmp->Set(Property, lValue, Flags); + } + + if(pAMVideoProcAmp)pAMVideoProcAmp->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + + return true; + +} + + +bool videoInput::setVideoSettingCameraPct(int deviceID, long Property, float pctValue, long Flags){ + if( !isDeviceSetup(deviceID) )return false; + + long min, max, currentValue, flags, defaultValue, stepAmnt; + + if( !getVideoSettingCamera(deviceID, Property, min, max, stepAmnt, currentValue, flags, defaultValue) )return false; + + if(pctValue > 1.0)pctValue = 1.0; + else if(pctValue < 0)pctValue = 0.0; + + float range = (float)max - (float)min; + if(range <= 0)return false; + if(stepAmnt == 0) return false; + + long value = (long)( (float)min + range * pctValue ); + long rasterValue = value; + + //if the range is the stepAmnt then it is just a switch + //so we either set the value to low or high + if( range == stepAmnt ){ + if( pctValue < 0.5)rasterValue = min; + else rasterValue = max; + }else{ + //we need to rasterize the value to the stepping amnt + long mod = value % stepAmnt; + float halfStep = (float)stepAmnt * 0.5f; + if( mod < halfStep ) rasterValue -= mod; + else rasterValue += stepAmnt - mod; + printf("RASTER - pctValue is %f - value is %li - step is %li - mod is %li - rasterValue is %li\n", pctValue, value, stepAmnt, mod, rasterValue); + } + + return setVideoSettingCamera(deviceID, Property, rasterValue, Flags, false); +} + + +bool videoInput::setVideoSettingCamera(int deviceID, long Property, long lValue, long Flags, bool useDefaultValue){ + IAMCameraControl *pIAMCameraControl; + if(isDeviceSetup(deviceID)) + { + HRESULT hr; + hr = getDevice(&VDList[deviceID]->pVideoInputFilter, deviceID, VDList[deviceID]->wDeviceName, VDList[deviceID]->nDeviceName); + + char propStr[16]; + getCameraPropertyAsString(Property,propStr); + + if (verbose) printf("Setting video setting %s.\n", propStr); + hr = VDList[deviceID]->pVideoInputFilter->QueryInterface(IID_IAMCameraControl, (void**)&pIAMCameraControl); + if (FAILED(hr)) { + printf("Error\n"); + return false; + } + else + { + long CurrVal, Min, Max, SteppingDelta, Default, CapsFlags, AvailableCapsFlags; + pIAMCameraControl->GetRange(Property, &Min, &Max, &SteppingDelta, &Default, &AvailableCapsFlags); + if (verbose) printf("Range for video setting %s: Min:%ld Max:%ld SteppingDelta:%ld Default:%ld Flags:%ld\n", propStr, Min, Max, SteppingDelta, Default, AvailableCapsFlags); + pIAMCameraControl->Get(Property, &CurrVal, &CapsFlags); + if (verbose) printf("Current value: %ld Flags %ld (%s)\n", CurrVal, CapsFlags, (CapsFlags == 1 ? "Auto" : (CapsFlags == 2 ? "Manual" : "Unknown"))); + if (useDefaultValue) { + pIAMCameraControl->Set(Property, Default, CameraControl_Flags_Auto); + } + else + { + // Perhaps add a check that lValue and Flags are within the range aquired from GetRange above + pIAMCameraControl->Set(Property, lValue, Flags); + } + pIAMCameraControl->Release(); + return true; + } + } + return false; +} + + + +bool videoInput::getVideoSettingCamera(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue){ + if( !isDeviceSetup(deviceID) )return false; + + HRESULT hr; + //bool isSuccessful = false; + + videoDevice * VD = VDList[deviceID]; + + hr = getDevice(&VD->pVideoInputFilter, deviceID, VD->wDeviceName, VD->nDeviceName); + if (FAILED(hr)){ + printf("setVideoSetting - getDevice Error\n"); + return false; + } + + IAMCameraControl *pIAMCameraControl = NULL; + + hr = VD->pVideoInputFilter->QueryInterface(IID_IAMCameraControl, (void**)&pIAMCameraControl); + if(FAILED(hr)){ + printf("setVideoSetting - QueryInterface Error\n"); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + return false; + } + + char propStr[16]; + getCameraPropertyAsString(Property,propStr); + if (verbose) printf("Setting video setting %s.\n", propStr); + + pIAMCameraControl->GetRange(Property, &min, &max, &SteppingDelta, &defaultValue, &flags); + if (verbose) printf("Range for video setting %s: Min:%ld Max:%ld SteppingDelta:%ld Default:%ld Flags:%ld\n", propStr, min, max, SteppingDelta, defaultValue, flags); + pIAMCameraControl->Get(Property, ¤tValue, &flags); + + if(pIAMCameraControl)pIAMCameraControl->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release(); + if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL; + + return true; + +} + + +// ---------------------------------------------------------------------- +// Shutsdown the device, deletes the object and creates a new object +// so it is ready to be setup again +// ---------------------------------------------------------------------- + +void videoInput::stopDevice(int id){ + if(id < VI_MAX_CAMERAS) + { + delete VDList[id]; + VDList[id] = new videoDevice(); + } + +} + +// ---------------------------------------------------------------------- +// Restarts the device with the same settings it was using +// +// ---------------------------------------------------------------------- + +bool videoInput::restartDevice(int id){ + if(isDeviceSetup(id)) + { + int conn = VDList[id]->storeConn; + int tmpW = VDList[id]->width; + int tmpH = VDList[id]->height; + + bool bFormat = VDList[id]->specificFormat; + long format = VDList[id]->formatType; + + int nReconnect = VDList[id]->nFramesForReconnect; + bool bReconnect = VDList[id]->autoReconnect; + + unsigned long avgFrameTime = VDList[id]->requestedFrameTime; + + stopDevice(id); + + //set our fps if needed + if( avgFrameTime != (unsigned long)-1){ + VDList[id]->requestedFrameTime = avgFrameTime; + } + + if( setupDevice(id, tmpW, tmpH, conn) ){ + //reapply the format - ntsc / pal etc + if( bFormat ){ + setFormat(id, format); + } + if( bReconnect ){ + setAutoReconnectOnFreeze(id, true, nReconnect); + } + return true; + } + } + return false; +} + +// ---------------------------------------------------------------------- +// Shuts down all devices, deletes objects and unitializes com if needed +// +// ---------------------------------------------------------------------- +videoInput::~videoInput(){ + + for(int i = 0; i < VI_MAX_CAMERAS; i++) + { + delete VDList[i]; + } + //Unitialize com + comUnInit(); +} + + +////////////////////////////// VIDEO INPUT //////////////////////////////// +//////////////////////////// PRIVATE METHODS ////////////////////////////// + +// ---------------------------------------------------------------------- +// We only should init com if it hasn't been done so by our apps thread +// Use a static counter to keep track of other times it has been inited +// (do we need to worry about multithreaded apps?) +// ---------------------------------------------------------------------- + +bool videoInput::comInit(){ + /*HRESULT hr = NOERROR; + + //no need for us to start com more than once + if(comInitCount == 0 ){ + + // Initialize the COM library. + //CoInitializeEx so videoInput can run in another thread + #ifdef VI_COM_MULTI_THREADED + hr = CoInitializeEx(NULL,COINIT_MULTITHREADED); + #else + hr = CoInitialize(NULL); + #endif + //this is the only case where there might be a problem + //if another library has started com as single threaded + //and we need it multi-threaded - send warning but don't fail + if( hr == RPC_E_CHANGED_MODE){ + if(verbose)printf("SETUP - COM already setup - threaded VI might not be possible\n"); + } + } + + comInitCount++;*/ + return true; +} + + +// ---------------------------------------------------------------------- +// Same as above but to unitialize com, decreases counter and frees com +// if no one else is using it +// ---------------------------------------------------------------------- + +bool videoInput::comUnInit(){ + /*if(comInitCount > 0)comInitCount--; //decrease the count of instances using com + + if(comInitCount == 0){ + CoUninitialize(); //if there are no instances left - uninitialize com + return true; + } + + return false;*/ + return true; +} + + +// ---------------------------------------------------------------------- +// This is the size we ask for - we might not get it though :) +// +// ---------------------------------------------------------------------- + +void videoInput::setAttemptCaptureSize(int id, int w, int h,GUID mediaType){ + + VDList[id]->tryWidth = w; + VDList[id]->tryHeight = h; + VDList[id]->tryDiffSize = true; + VDList[id]->tryVideoType = mediaType; + +} + +// ---------------------------------------------------------------------- +// Set the connection type +// (maybe move to private?) +// ---------------------------------------------------------------------- + +void videoInput::setPhyCon(int id, int conn){ + + switch(conn){ + + case 0: + VDList[id]->connection = PhysConn_Video_Composite; + break; + case 1: + VDList[id]->connection = PhysConn_Video_SVideo; + break; + case 2: + VDList[id]->connection = PhysConn_Video_Tuner; + break; + case 3: + VDList[id]->connection = PhysConn_Video_USB; + break; + case 4: + VDList[id]->connection = PhysConn_Video_1394; + break; + default: + return; //if it is not these types don't set crossbar + break; + } + + VDList[id]->storeConn = conn; + VDList[id]->useCrossbar = true; +} + + +// ---------------------------------------------------------------------- +// Check that we are not trying to setup a non-existant device +// Then start the graph building! +// ---------------------------------------------------------------------- + +bool videoInput::setup(int deviceNumber){ + devicesFound = getDeviceCount(); + + if(deviceNumber>devicesFound-1) + { + if(verbose)printf("SETUP: device[%i] not found - you have %i devices available\n", deviceNumber, devicesFound); + if(devicesFound>=0) if(verbose)printf("SETUP: this means that the last device you can use is device[%i] \n", devicesFound-1); + return false; + } + + if(VDList[deviceNumber]->readyToCapture) + { + if(verbose)printf("SETUP: can't setup, device %i is currently being used\n",VDList[deviceNumber]->myID); + return false; + } + + HRESULT hr = start(deviceNumber, VDList[deviceNumber]); + if(hr == S_OK)return true; + else return false; +} + + +// ---------------------------------------------------------------------- +// Does both vertical buffer flipping and bgr to rgb swapping +// You have any combination of those. +// ---------------------------------------------------------------------- + +void videoInput::processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip){ + + int widthInBytes = width * 3; + int numBytes = widthInBytes * height; + + if(!bRGB){ + + //int x = 0; + //int y = 0; + + if(bFlip){ + for(int y = 0; y < height; y++){ + memcpy(dst + (y * widthInBytes), src + ( (height -y -1) * widthInBytes), widthInBytes); + } + + }else{ + memcpy(dst, src, numBytes); + } + }else{ + if(bFlip){ + + int x = 0; + int y = (height - 1) * widthInBytes; + src += y; + + for(int i = 0; i < numBytes; i+=3){ + if(x >= width){ + x = 0; + src -= widthInBytes*2; + } + + *dst = *(src+2); + dst++; + + *dst = *(src+1); + dst++; + + *dst = *src; + dst++; + + src+=3; + x++; + } + } + else{ + for(int i = 0; i < numBytes; i+=3){ + *dst = *(src+2); + dst++; + + *dst = *(src+1); + dst++; + + *dst = *src; + dst++; + + src+=3; + } + } + } +} + + +//------------------------------------------------------------------------------------------ +void videoInput::getMediaSubtypeAsString(GUID type, char * typeAsString){ + + char tmpStr[8]; + if( type == MEDIASUBTYPE_RGB24) sprintf(tmpStr, "RGB24"); + else if(type == MEDIASUBTYPE_RGB32) sprintf(tmpStr, "RGB32"); + else if(type == MEDIASUBTYPE_RGB555)sprintf(tmpStr, "RGB555"); + else if(type == MEDIASUBTYPE_RGB565)sprintf(tmpStr, "RGB565"); + else if(type == MEDIASUBTYPE_YUY2) sprintf(tmpStr, "YUY2"); + else if(type == MEDIASUBTYPE_YVYU) sprintf(tmpStr, "YVYU"); + else if(type == MEDIASUBTYPE_YUYV) sprintf(tmpStr, "YUYV"); + else if(type == MEDIASUBTYPE_IYUV) sprintf(tmpStr, "IYUV"); + else if(type == MEDIASUBTYPE_UYVY) sprintf(tmpStr, "UYVY"); + else if(type == MEDIASUBTYPE_YV12) sprintf(tmpStr, "YV12"); + else if(type == MEDIASUBTYPE_YVU9) sprintf(tmpStr, "YVU9"); + else if(type == MEDIASUBTYPE_Y411) sprintf(tmpStr, "Y411"); + else if(type == MEDIASUBTYPE_Y41P) sprintf(tmpStr, "Y41P"); + else if(type == MEDIASUBTYPE_Y211) sprintf(tmpStr, "Y211"); + else if(type == MEDIASUBTYPE_AYUV) sprintf(tmpStr, "AYUV"); + else if(type == MEDIASUBTYPE_MJPG) sprintf(tmpStr, "MJPG"); + else if(type == MEDIASUBTYPE_Y800) sprintf(tmpStr, "Y800"); + else if(type == MEDIASUBTYPE_Y8) sprintf(tmpStr, "Y8"); + else if(type == MEDIASUBTYPE_GREY) sprintf(tmpStr, "GREY"); + else if(type == MEDIASUBTYPE_I420) sprintf(tmpStr, "I420"); + else sprintf(tmpStr, "OTHER"); + + memcpy(typeAsString, tmpStr, sizeof(char)*8); +} + +int videoInput::getFourccFromMediaSubtype(GUID type) { + return type.Data1; +} + +GUID *videoInput::getMediaSubtypeFromFourcc(int fourcc){ + + for (int i=0;istreamConf->GetNumberOfCapabilities(&iCount, &iSize); + + if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) + { + //For each format type RGB24 YUV2 etc + for (int iFormat = 0; iFormat < iCount; iFormat++) + { + VIDEO_STREAM_CONFIG_CAPS scc; + AM_MEDIA_TYPE *pmtConfig; + hr = VD->streamConf->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc); + + if (SUCCEEDED(hr)){ + + //his is how many diff sizes are available for the format + int stepX = scc.OutputGranularityX; + int stepY = scc.OutputGranularityY; + + int tempW = 999999; + int tempH = 999999; + + //Don't want to get stuck in a loop + if(stepX < 1 || stepY < 1) continue; + + //if(verbose)printf("min is %i %i max is %i %i - res is %i %i \n", scc.MinOutputSize.cx, scc.MinOutputSize.cy, scc.MaxOutputSize.cx, scc.MaxOutputSize.cy, stepX, stepY); + //if(verbose)printf("min frame duration is %i max duration is %i\n", scc.MinFrameInterval, scc.MaxFrameInterval); + + bool exactMatch = false; + bool exactMatchX = false; + bool exactMatchY = false; + + for(int x = scc.MinOutputSize.cx; x <= scc.MaxOutputSize.cx; x+= stepX){ + //If we find an exact match + if( widthIn == x ){ + exactMatchX = true; + tempW = x; + } + //Otherwise lets find the closest match based on width + else if( abs(widthIn-x) < abs(widthIn-tempW) ){ + tempW = x; + } + } + + for(int y = scc.MinOutputSize.cy; y <= scc.MaxOutputSize.cy; y+= stepY){ + //If we find an exact match + if( heightIn == y){ + exactMatchY = true; + tempH = y; + } + //Otherwise lets find the closest match based on height + else if( abs(heightIn-y) < abs(heightIn-tempH) ){ + tempH = y; + } + } + + //see if we have an exact match! + if(exactMatchX && exactMatchY){ + //foundClosestMatch = false; + exactMatch = true; + + widthOut = widthIn; + heightOut = heightIn; + mediatypeOut = pmtConfig->subtype; + } + + //otherwise lets see if this filters closest size is the closest + //available. the closest size is determined by the sum difference + //of the widths and heights + else if( abs(widthIn - tempW) + abs(heightIn - tempH) < abs(widthIn - nearW) + abs(heightIn - nearH) ) + { + nearW = tempW; + nearH = tempH; + + widthOut = nearW; + heightOut = nearH; + mediatypeOut = pmtConfig->subtype; + } + + MyDeleteMediaType(pmtConfig); + + //If we have found an exact match no need to search anymore + if(exactMatch)break; + } + } + } + +} + + +//--------------------------------------------------------------------------------------------------- +static bool setSizeAndSubtype(videoDevice * VD, int attemptWidth, int attemptHeight, GUID mediatype){ + VIDEOINFOHEADER *pVih = reinterpret_cast(VD->pAmMediaType->pbFormat); + + //store current size + //int tmpWidth = HEADER(pVih)->biWidth; + //int tmpHeight = HEADER(pVih)->biHeight; + AM_MEDIA_TYPE * tmpType = NULL; + + HRESULT hr = VD->streamConf->GetFormat(&tmpType); + if(hr != S_OK)return false; + + //set new size: + //width and height + HEADER(pVih)->biWidth = attemptWidth; + HEADER(pVih)->biHeight = attemptHeight; + + VD->pAmMediaType->formattype = FORMAT_VideoInfo; + VD->pAmMediaType->majortype = MEDIATYPE_Video; + VD->pAmMediaType->subtype = mediatype; + + //buffer size + VD->pAmMediaType->lSampleSize = attemptWidth*attemptHeight*3; + + //set fps if requested + if( VD->requestedFrameTime != -1){ + pVih->AvgTimePerFrame = VD->requestedFrameTime; + } + + //okay lets try new size + hr = VD->streamConf->SetFormat(VD->pAmMediaType); + if(hr == S_OK){ + if( tmpType != NULL )MyDeleteMediaType(tmpType); + return true; + }else{ + VD->streamConf->SetFormat(tmpType); + if( tmpType != NULL )MyDeleteMediaType(tmpType); + } + + return false; +} + +// ---------------------------------------------------------------------- +// Where all the work happens! +// Attempts to build a graph for the specified device +// ---------------------------------------------------------------------- + +int videoInput::start(int deviceID, videoDevice *VD){ + + HRESULT hr = NOERROR; + VD->myID = deviceID; + VD->setupStarted = true; + CAPTURE_MODE = PIN_CATEGORY_CAPTURE; //Don't worry - it ends up being preview (which is faster) + callbackSetCount = 1; //make sure callback method is not changed after setup called + + if(verbose)printf("SETUP: Setting up device %i\n",deviceID); + + // CREATE THE GRAPH BUILDER // + // Create the filter graph manager and query for interfaces. + hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&VD->pCaptureGraph); + if (FAILED(hr)) // FAILED is a macro that tests the return value + { + if(verbose)printf("ERROR - Could not create the Filter Graph Manager\n"); + return hr; + } + + //FITLER GRAPH MANAGER// + // Create the Filter Graph Manager. + hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void**)&VD->pGraph); + if (FAILED(hr)) + { + if(verbose)printf("ERROR - Could not add the graph builder!\n"); + stopDevice(deviceID); + return hr; + } + + //SET THE FILTERGRAPH// + hr = VD->pCaptureGraph->SetFiltergraph(VD->pGraph); + if (FAILED(hr)) + { + if(verbose)printf("ERROR - Could not set filtergraph\n"); + stopDevice(deviceID); + return hr; + } + + //MEDIA CONTROL (START/STOPS STREAM)// + // Using QueryInterface on the graph builder, + // Get the Media Control object. + hr = VD->pGraph->QueryInterface(IID_IMediaControl, (void **)&VD->pControl); + if (FAILED(hr)) + { + if(verbose)printf("ERROR - Could not create the Media Control object\n"); + stopDevice(deviceID); + return hr; + } + + + //FIND VIDEO DEVICE AND ADD TO GRAPH// + //gets the device specified by the second argument. + hr = getDevice(&VD->pVideoInputFilter, deviceID, VD->wDeviceName, VD->nDeviceName); + + if (SUCCEEDED(hr)){ + if(verbose)printf("SETUP: %s\n", VD->nDeviceName); + hr = VD->pGraph->AddFilter(VD->pVideoInputFilter, VD->wDeviceName); + }else{ + if(verbose)printf("ERROR - Could not find specified video device\n"); + stopDevice(deviceID); + return hr; + } + + //LOOK FOR PREVIEW PIN IF THERE IS NONE THEN WE USE CAPTURE PIN AND THEN SMART TEE TO PREVIEW + IAMStreamConfig *streamConfTest = NULL; + hr = VD->pCaptureGraph->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, VD->pVideoInputFilter, IID_IAMStreamConfig, (void **)&streamConfTest); + if(FAILED(hr)){ + if(verbose)printf("SETUP: Couldn't find preview pin using SmartTee\n"); + }else{ + CAPTURE_MODE = PIN_CATEGORY_PREVIEW; + streamConfTest->Release(); + streamConfTest = NULL; + } + + //CROSSBAR (SELECT PHYSICAL INPUT TYPE)// + //my own function that checks to see if the device can support a crossbar and if so it routes it. + //webcams tend not to have a crossbar so this function will also detect a webcams and not apply the crossbar + if(VD->useCrossbar) + { + if(verbose)printf("SETUP: Checking crossbar\n"); + routeCrossbar(&VD->pCaptureGraph, &VD->pVideoInputFilter, VD->connection, CAPTURE_MODE); + } + + + //we do this because webcams don't have a preview mode + hr = VD->pCaptureGraph->FindInterface(&CAPTURE_MODE, &MEDIATYPE_Video, VD->pVideoInputFilter, IID_IAMStreamConfig, (void **)&VD->streamConf); + if(FAILED(hr)){ + if(verbose)printf("ERROR: Couldn't config the stream!\n"); + stopDevice(deviceID); + return hr; + } + + //NOW LETS DEAL WITH GETTING THE RIGHT SIZE + hr = VD->streamConf->GetFormat(&VD->pAmMediaType); + if(FAILED(hr)){ + if(verbose)printf("ERROR: Couldn't getFormat for pAmMediaType!\n"); + stopDevice(deviceID); + return hr; + } + + VIDEOINFOHEADER *pVih = reinterpret_cast(VD->pAmMediaType->pbFormat); + int currentWidth = HEADER(pVih)->biWidth; + int currentHeight = HEADER(pVih)->biHeight; + + bool customSize = VD->tryDiffSize; + + bool foundSize = false; + + if(customSize){ + if(verbose) printf("SETUP: Default Format is set to %i by %i \n", currentWidth, currentHeight); + + char guidStr[8]; + // try specified format and size + getMediaSubtypeAsString(VD->tryVideoType, guidStr); + if(verbose)printf("SETUP: trying specified format %s @ %i by %i\n", guidStr, VD->tryWidth, VD->tryHeight); + + if( setSizeAndSubtype(VD, VD->tryWidth, VD->tryHeight, VD->tryVideoType) ){ + VD->setSize(VD->tryWidth, VD->tryHeight); + foundSize = true; + } else { + // try specified size with all formats + for(int i = 0; i < VI_NUM_TYPES; i++){ + + getMediaSubtypeAsString(mediaSubtypes[i], guidStr); + + if(verbose)printf("SETUP: trying format %s @ %i by %i\n", guidStr, VD->tryWidth, VD->tryHeight); + if( setSizeAndSubtype(VD, VD->tryWidth, VD->tryHeight, mediaSubtypes[i]) ){ + VD->setSize(VD->tryWidth, VD->tryHeight); + foundSize = true; + break; + } + } + } + + + //if we didn't find the requested size - lets try and find the closest matching size + if( foundSize == false ){ + if( verbose )printf("SETUP: couldn't find requested size - searching for closest matching size\n"); + + int closestWidth = -1; + int closestHeight = -1; + GUID newMediaSubtype; + + findClosestSizeAndSubtype(VD, VD->tryWidth, VD->tryHeight, closestWidth, closestHeight, newMediaSubtype); + + if( closestWidth != -1 && closestHeight != -1){ + getMediaSubtypeAsString(newMediaSubtype, guidStr); + + if(verbose)printf("SETUP: closest supported size is %s @ %i %i\n", guidStr, closestWidth, closestHeight); + if( setSizeAndSubtype(VD, closestWidth, closestHeight, newMediaSubtype) ){ + VD->setSize(closestWidth, closestHeight); + foundSize = true; + } + } + } + } + + //if we didn't specify a custom size or if we did but couldn't find it lets setup with the default settings + if(customSize == false || foundSize == false){ + if( VD->requestedFrameTime != -1 ){ + pVih->AvgTimePerFrame = VD->requestedFrameTime; + hr = VD->streamConf->SetFormat(VD->pAmMediaType); + } + VD->setSize(currentWidth, currentHeight); + } + + //SAMPLE GRABBER (ALLOWS US TO GRAB THE BUFFER)// + // Create the Sample Grabber. + hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)&VD->pGrabberF); + if (FAILED(hr)){ + if(verbose)printf("Could not Create Sample Grabber - CoCreateInstance()\n"); + stopDevice(deviceID); + return hr; + } + + hr = VD->pGraph->AddFilter(VD->pGrabberF, L"Sample Grabber"); + if (FAILED(hr)){ + if(verbose)printf("Could not add Sample Grabber - AddFilter()\n"); + stopDevice(deviceID); + return hr; + } + + hr = VD->pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&VD->pGrabber); + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not query SampleGrabber\n"); + stopDevice(deviceID); + return hr; + } + + + //Set Params - One Shot should be false unless you want to capture just one buffer + hr = VD->pGrabber->SetOneShot(FALSE); + if(bCallback){ + hr = VD->pGrabber->SetBufferSamples(FALSE); + }else{ + hr = VD->pGrabber->SetBufferSamples(TRUE); + } + + if(bCallback){ + //Tell the grabber to use our callback function - 0 is for SampleCB and 1 for BufferCB + //We use SampleCB + hr = VD->pGrabber->SetCallback(VD->sgCallback, 0); + if (FAILED(hr)){ + if(verbose)printf("ERROR: problem setting callback\n"); + stopDevice(deviceID); + return hr; + }else{ + if(verbose)printf("SETUP: Capture callback set\n"); + } + } + + //MEDIA CONVERSION + //Get video properties from the stream's mediatype and apply to the grabber (otherwise we don't get an RGB image) + //zero the media type - lets try this :) - maybe this works? + AM_MEDIA_TYPE mt; + ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE)); + + mt.majortype = MEDIATYPE_Video; + mt.subtype = MEDIASUBTYPE_RGB24; + mt.formattype = FORMAT_VideoInfo; + + //VD->pAmMediaType->subtype = VD->videoType; + hr = VD->pGrabber->SetMediaType(&mt); + + //lets try freeing our stream conf here too + //this will fail if the device is already running + if(VD->streamConf){ + VD->streamConf->Release(); + VD->streamConf = NULL; + }else{ + if(verbose)printf("ERROR: connecting device - prehaps it is already being used?\n"); + stopDevice(deviceID); + return S_FALSE; + } + + + //NULL RENDERER// + //used to give the video stream somewhere to go to. + hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)(&VD->pDestFilter)); + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not create filter - NullRenderer\n"); + stopDevice(deviceID); + return hr; + } + + hr = VD->pGraph->AddFilter(VD->pDestFilter, L"NullRenderer"); + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not add filter - NullRenderer\n"); + stopDevice(deviceID); + return hr; + } + + //RENDER STREAM// + //This is where the stream gets put together. + hr = VD->pCaptureGraph->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, VD->pVideoInputFilter, VD->pGrabberF, VD->pDestFilter); + + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not connect pins - RenderStream()\n"); + stopDevice(deviceID); + return hr; + } + + + //EXP - lets try setting the sync source to null - and make it run as fast as possible + { + IMediaFilter *pMediaFilter = 0; + hr = VD->pGraph->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter); + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not get IID_IMediaFilter interface\n"); + }else{ + pMediaFilter->SetSyncSource(NULL); + pMediaFilter->Release(); + } + } + + + //LETS RUN THE STREAM! + hr = VD->pControl->Run(); + + if (FAILED(hr)){ + if(verbose)printf("ERROR: Could not start graph\n"); + stopDevice(deviceID); + return hr; + } + + + //MAKE SURE THE DEVICE IS SENDING VIDEO BEFORE WE FINISH + if(!bCallback){ + + long bufferSize = VD->videoSize; + + while( hr != S_OK){ + hr = VD->pGrabber->GetCurrentBuffer(&bufferSize, (long *)VD->pBuffer); + Sleep(10); + } + + } + + if(verbose)printf("SETUP: Device is setup and ready to capture.\n\n"); + VD->readyToCapture = true; + + //Release filters - seen someone else do this + //looks like it solved the freezes + + //if we release this then we don't have access to the settings + //we release our video input filter but then reconnect with it + //each time we need to use it + VD->pVideoInputFilter->Release(); + VD->pVideoInputFilter = NULL; + + VD->pGrabberF->Release(); + VD->pGrabberF = NULL; + + VD->pDestFilter->Release(); + VD->pDestFilter = NULL; + + return S_OK; +} + + +// ---------------------------------------------------------------------- +// Returns number of good devices +// +// ---------------------------------------------------------------------- + +int videoInput::getDeviceCount(){ + + + ICreateDevEnum *pDevEnum = NULL; + IEnumMoniker *pEnum = NULL; + int deviceCounter = 0; + + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, + CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, + reinterpret_cast(&pDevEnum)); + + + if (SUCCEEDED(hr)) + { + // Create an enumerator for the video capture category. + hr = pDevEnum->CreateClassEnumerator( + CLSID_VideoInputDeviceCategory, + &pEnum, 0); + + if(hr == S_OK){ + IMoniker *pMoniker = NULL; + while (pEnum->Next(1, &pMoniker, NULL) == S_OK){ + + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, + (void**)(&pPropBag)); + + if (FAILED(hr)){ + pMoniker->Release(); + continue; // Skip this one, maybe the next one will work. + } + + pPropBag->Release(); + pPropBag = NULL; + + pMoniker->Release(); + pMoniker = NULL; + + deviceCounter++; + } + + pEnum->Release(); + pEnum = NULL; + } + + pDevEnum->Release(); + pDevEnum = NULL; + } + return deviceCounter; +} + + +// ---------------------------------------------------------------------- +// Do we need this? +// +// Enumerate all of the video input devices +// Return the filter with a matching friendly name +// ---------------------------------------------------------------------- + +HRESULT videoInput::getDevice(IBaseFilter** gottaFilter, int deviceId, WCHAR * wDeviceName, char * nDeviceName){ + BOOL done = false; + int deviceCounter = 0; + + // Create the System Device Enumerator. + ICreateDevEnum *pSysDevEnum = NULL; + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); + if (FAILED(hr)) + { + return hr; + } + + // Obtain a class enumerator for the video input category. + IEnumMoniker *pEnumCat = NULL; + hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); + + if (hr == S_OK) + { + // Enumerate the monikers. + IMoniker *pMoniker = NULL; + ULONG cFetched; + while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done)) + { + if(deviceCounter == deviceId) + { + // Bind the first moniker to an object + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); + if (SUCCEEDED(hr)) + { + // To retrieve the filter's friendly name, do the following: + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + if (SUCCEEDED(hr)) + { + + //copy the name to nDeviceName & wDeviceName + int count = 0; + while( varName.bstrVal[count] != 0x00 ) { + wDeviceName[count] = varName.bstrVal[count]; + nDeviceName[count] = (char)varName.bstrVal[count]; + count++; + } + + // We found it, so send it back to the caller + hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)gottaFilter); + done = true; + } + VariantClear(&varName); + pPropBag->Release(); + pPropBag = NULL; + pMoniker->Release(); + pMoniker = NULL; + } + } + deviceCounter++; + } + pEnumCat->Release(); + pEnumCat = NULL; + } + pSysDevEnum->Release(); + pSysDevEnum = NULL; + + if (done) { + return hr; // found it, return native error + } else { + return VFW_E_NOT_FOUND; // didn't find it error + } +} + + +// ---------------------------------------------------------------------- +// Show the property pages for a filter +// This is stolen from the DX9 SDK +// ---------------------------------------------------------------------- + +HRESULT videoInput::ShowFilterPropertyPages(IBaseFilter *pFilter){ + + ISpecifyPropertyPages *pProp; + + HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp); + if (SUCCEEDED(hr)) + { + // Get the filter's name and IUnknown pointer. + FILTER_INFO FilterInfo; + hr = pFilter->QueryFilterInfo(&FilterInfo); + IUnknown *pFilterUnk; + pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk); + + // Show the page. + CAUUID caGUID; + pProp->GetPages(&caGUID); + pProp->Release(); + OleCreatePropertyFrame( + NULL, // Parent window + 0, 0, // Reserved + FilterInfo.achName, // Caption for the dialog box + 1, // Number of objects (just the filter) + &pFilterUnk, // Array of object pointers. + caGUID.cElems, // Number of property pages + caGUID.pElems, // Array of property page CLSIDs + 0, // Locale identifier + 0, NULL // Reserved + ); + + // Clean up. + if(pFilterUnk)pFilterUnk->Release(); + if(FilterInfo.pGraph)FilterInfo.pGraph->Release(); + CoTaskMemFree(caGUID.pElems); + } + return hr; +} + +HRESULT videoInput::ShowStreamPropertyPages(IAMStreamConfig * /*pStream*/){ + + HRESULT hr = NOERROR; + return hr; +} + +// ---------------------------------------------------------------------- +// This code was also brazenly stolen from the DX9 SDK +// Pass it a file name in wszPath, and it will save the filter graph to that file. +// ---------------------------------------------------------------------- + +HRESULT videoInput::SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath) { + const WCHAR wszStreamName[] = L"ActiveMovieGraph"; + HRESULT hr; + IStorage *pStorage = NULL; + + // First, create a document file which will hold the GRF file + hr = StgCreateDocfile( + wszPath, + STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + 0, &pStorage); + if(FAILED(hr)) + { + return hr; + } + + // Next, create a stream to store. + IStream *pStream; + hr = pStorage->CreateStream( + wszStreamName, + STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, + 0, 0, &pStream); + if (FAILED(hr)) + { + pStorage->Release(); + return hr; + } + + // The IPersistStream converts a stream into a persistent object. + IPersistStream *pPersist = NULL; + pGraph->QueryInterface(IID_IPersistStream, reinterpret_cast(&pPersist)); + hr = pPersist->Save(pStream, TRUE); + pStream->Release(); + pPersist->Release(); + if (SUCCEEDED(hr)) + { + hr = pStorage->Commit(STGC_DEFAULT); + } + pStorage->Release(); + return hr; +} + + +// ---------------------------------------------------------------------- +// For changing the input types +// +// ---------------------------------------------------------------------- + +HRESULT videoInput::routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter **pVidInFilter, int conType, GUID captureMode){ + + //create local ICaptureGraphBuilder2 + ICaptureGraphBuilder2 *pBuild = NULL; + pBuild = *ppBuild; + + //create local IBaseFilter + IBaseFilter *pVidFilter = NULL; + pVidFilter = * pVidInFilter; + + // Search upstream for a crossbar. + IAMCrossbar *pXBar1 = NULL; + HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidFilter, + IID_IAMCrossbar, (void**)&pXBar1); + if (SUCCEEDED(hr)) + { + + bool foundDevice = false; + + if(verbose)printf("SETUP: You are not a webcam! Setting Crossbar\n"); + pXBar1->Release(); + + IAMCrossbar *Crossbar; + hr = pBuild->FindInterface(&captureMode, &MEDIATYPE_Interleaved, pVidFilter, IID_IAMCrossbar, (void **)&Crossbar); + + if(hr != NOERROR){ + hr = pBuild->FindInterface(&captureMode, &MEDIATYPE_Video, pVidFilter, IID_IAMCrossbar, (void **)&Crossbar); + } + + LONG lInpin, lOutpin; + hr = Crossbar->get_PinCounts(&lOutpin , &lInpin); + + BOOL iPin=TRUE; LONG pIndex=0 , pRIndex=0 , pType=0; + + while( pIndex < lInpin) + { + hr = Crossbar->get_CrossbarPinInfo( iPin , pIndex , &pRIndex , &pType); + + if( pType == conType){ + if(verbose)printf("SETUP: Found Physical Interface"); + + switch(conType){ + + case PhysConn_Video_Composite: + if(verbose)printf(" - Composite\n"); + break; + case PhysConn_Video_SVideo: + if(verbose)printf(" - S-Video\n"); + break; + case PhysConn_Video_Tuner: + if(verbose)printf(" - Tuner\n"); + break; + case PhysConn_Video_USB: + if(verbose)printf(" - USB\n"); + break; + case PhysConn_Video_1394: + if(verbose)printf(" - Firewire\n"); + break; + } + + foundDevice = true; + break; + } + pIndex++; + + } + + if(foundDevice){ + BOOL OPin=FALSE; LONG pOIndex=0 , pORIndex=0 , pOType=0; + while( pOIndex < lOutpin) + { + hr = Crossbar->get_CrossbarPinInfo( OPin , pOIndex , &pORIndex , &pOType); + if( pOType == PhysConn_Video_VideoDecoder) + break; + } + Crossbar->Route(pOIndex,pIndex); + }else{ + if(verbose) printf("SETUP: Didn't find specified Physical Connection type. Using Defualt. \n"); + } + + //we only free the crossbar when we close or restart the device + //we were getting a crash otherwise + //if(Crossbar)Crossbar->Release(); + //if(Crossbar)Crossbar = NULL; + + if(pXBar1)pXBar1->Release(); + if(pXBar1)pXBar1 = NULL; + + }else{ + if(verbose) printf("SETUP: You are a webcam or snazzy firewire cam! No Crossbar needed\n"); + return hr; + } + + return hr; +} + + +/********************* Capturing video from camera via DirectShow *********************/ + +class CvCaptureCAM_DShow : public CvCapture +{ +public: + CvCaptureCAM_DShow(); + virtual ~CvCaptureCAM_DShow(); + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_DSHOW; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + void init(); + + int index, width, height,fourcc; + int widthSet, heightSet; + IplImage* frame; + static videoInput VI; +}; + + +struct SuppressVideoInputMessages +{ + SuppressVideoInputMessages() { videoInput::setVerbose(false); } +}; + +static SuppressVideoInputMessages do_it; +videoInput CvCaptureCAM_DShow::VI; + +CvCaptureCAM_DShow::CvCaptureCAM_DShow() +{ + index = -1; + frame = 0; + width = height = fourcc = -1; + widthSet = heightSet = -1; + CoInitialize(0); +} + +CvCaptureCAM_DShow::~CvCaptureCAM_DShow() +{ + close(); + CoUninitialize(); +} + +void CvCaptureCAM_DShow::close() +{ + if( index >= 0 ) + { + VI.stopDevice(index); + index = -1; + cvReleaseImage(&frame); + } + widthSet = heightSet = width = height = -1; +} + +// Initialize camera input +bool CvCaptureCAM_DShow::open( int _index ) +{ + int try_index = _index; + int devices = 0; + + close(); + devices = VI.listDevices(true); + if (devices == 0) + return false; + try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index); + VI.setupDevice(try_index); + if( !VI.isDeviceSetup(try_index) ) + return false; + index = try_index; + return true; +} + +bool CvCaptureCAM_DShow::grabFrame() +{ + return true; +} + + +IplImage* CvCaptureCAM_DShow::retrieveFrame(int) +{ + if( !frame || VI.getWidth(index) != frame->width || VI.getHeight(index) != frame->height ) + { + if (frame) + cvReleaseImage( &frame ); + int w = VI.getWidth(index), h = VI.getHeight(index); + frame = cvCreateImage( cvSize(w,h), 8, 3 ); + } + + VI.getPixels( index, (uchar*)frame->imageData, false, true ); + return frame; +} + +double CvCaptureCAM_DShow::getProperty( int property_id ) +{ + + long min_value,max_value,stepping_delta,current_value,flags,defaultValue; + + // image format proprrties + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return VI.getWidth(index); + + case CV_CAP_PROP_FRAME_HEIGHT: + return VI.getHeight(index); + + case CV_CAP_PROP_FOURCC: + return VI.getFourcc(index); + + case CV_CAP_PROP_FPS: + return VI.getFPS(index); + } + + // video filter properties + switch( property_id ) + { + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_SHARPNESS: + case CV_CAP_PROP_GAMMA: + case CV_CAP_PROP_MONOCROME: + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + case CV_CAP_PROP_BACKLIGHT: + case CV_CAP_PROP_GAIN: + if (VI.getVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),min_value,max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value; + } + + // camera properties + switch( property_id ) + { + case CV_CAP_PROP_PAN: + case CV_CAP_PROP_TILT: + case CV_CAP_PROP_ROLL: + case CV_CAP_PROP_ZOOM: + case CV_CAP_PROP_EXPOSURE: + case CV_CAP_PROP_IRIS: + case CV_CAP_PROP_FOCUS: + if (VI.getVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),min_value,max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value; + + } + + // unknown parameter or value not available + return -1; +} + +bool CvCaptureCAM_DShow::setProperty( int property_id, double value ) +{ + // image capture properties + bool handled = false; + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + width = cvRound(value); + handled = true; + break; + + case CV_CAP_PROP_FRAME_HEIGHT: + height = cvRound(value); + handled = true; + break; + + case CV_CAP_PROP_FOURCC: + fourcc = (int)(unsigned long)(value); + if ( fourcc == -1 ) { + // following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1 + // TODO - how to create a capture pin dialog + } + handled = true; + break; + + case CV_CAP_PROP_FPS: + int fps = cvRound(value); + if (fps != VI.getFPS(index)) + { + VI.stopDevice(index); + VI.setIdealFramerate(index,fps); + if (widthSet > 0 && heightSet > 0) + VI.setupDevice(index, widthSet, heightSet); + else + VI.setupDevice(index); + } + return VI.isDeviceSetup(index); + + } + + if ( handled ) { + // a stream setting + if( width > 0 && height > 0 ) + { + if( width != VI.getWidth(index) || height != VI.getHeight(index) )//|| fourcc != VI.getFourcc(index) ) + { + int fps = static_cast(VI.getFPS(index)); + VI.stopDevice(index); + VI.setIdealFramerate(index, fps); + VI.setupDeviceFourcc(index, width, height, fourcc); + } + + bool success = VI.isDeviceSetup(index); + if (success) + { + widthSet = width; + heightSet = height; + width = height = fourcc = -1; + } + return success; + } + return true; + } + + // show video/camera filter dialog + if ( property_id == CV_CAP_PROP_SETTINGS ) { + VI.showSettingsWindow(index); + return true; + } + + //video Filter properties + switch( property_id ) + { + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_SHARPNESS: + case CV_CAP_PROP_GAMMA: + case CV_CAP_PROP_MONOCROME: + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + case CV_CAP_PROP_BACKLIGHT: + case CV_CAP_PROP_GAIN: + return VI.setVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),(long)value); + } + + //camera properties + switch( property_id ) + { + case CV_CAP_PROP_PAN: + case CV_CAP_PROP_TILT: + case CV_CAP_PROP_ROLL: + case CV_CAP_PROP_ZOOM: + case CV_CAP_PROP_EXPOSURE: + case CV_CAP_PROP_IRIS: + case CV_CAP_PROP_FOCUS: + return VI.setVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),(long)value); + } + + return false; +} + + +CvCapture* cvCreateCameraCapture_DShow( int index ) +{ + CvCaptureCAM_DShow* capture = new CvCaptureCAM_DShow; + + try + { + if( capture->open( index )) + return capture; + } + catch(...) + { + delete capture; + throw; + } + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,271 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_FFMPEG +#include "cap_ffmpeg_impl.hpp" +#else +#include "cap_ffmpeg_api.hpp" +#endif + +static CvCreateFileCapture_Plugin icvCreateFileCapture_FFMPEG_p = 0; +static CvReleaseCapture_Plugin icvReleaseCapture_FFMPEG_p = 0; +static CvGrabFrame_Plugin icvGrabFrame_FFMPEG_p = 0; +static CvRetrieveFrame_Plugin icvRetrieveFrame_FFMPEG_p = 0; +static CvSetCaptureProperty_Plugin icvSetCaptureProperty_FFMPEG_p = 0; +static CvGetCaptureProperty_Plugin icvGetCaptureProperty_FFMPEG_p = 0; +static CvCreateVideoWriter_Plugin icvCreateVideoWriter_FFMPEG_p = 0; +static CvReleaseVideoWriter_Plugin icvReleaseVideoWriter_FFMPEG_p = 0; +static CvWriteFrame_Plugin icvWriteFrame_FFMPEG_p = 0; + +static cv::Mutex _icvInitFFMPEG_mutex; + +class icvInitFFMPEG +{ +public: + static void Init() + { + cv::AutoLock al(_icvInitFFMPEG_mutex); + static icvInitFFMPEG init; + } + +private: + #if defined WIN32 || defined _WIN32 + HMODULE icvFFOpenCV; + + ~icvInitFFMPEG() + { + if (icvFFOpenCV) + { + FreeLibrary(icvFFOpenCV); + icvFFOpenCV = 0; + } + } + #endif + + icvInitFFMPEG() + { + #if defined WIN32 || defined _WIN32 + const char* module_name = "opencv_ffmpeg" + CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION) + #if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__) + "_64" + #endif + ".dll"; + + icvFFOpenCV = LoadLibrary( module_name ); + if( icvFFOpenCV ) + { + icvCreateFileCapture_FFMPEG_p = + (CvCreateFileCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvCreateFileCapture_FFMPEG"); + icvReleaseCapture_FFMPEG_p = + (CvReleaseCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseCapture_FFMPEG"); + icvGrabFrame_FFMPEG_p = + (CvGrabFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvGrabFrame_FFMPEG"); + icvRetrieveFrame_FFMPEG_p = + (CvRetrieveFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvRetrieveFrame_FFMPEG"); + icvSetCaptureProperty_FFMPEG_p = + (CvSetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvSetCaptureProperty_FFMPEG"); + icvGetCaptureProperty_FFMPEG_p = + (CvGetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvGetCaptureProperty_FFMPEG"); + icvCreateVideoWriter_FFMPEG_p = + (CvCreateVideoWriter_Plugin)GetProcAddress(icvFFOpenCV, "cvCreateVideoWriter_FFMPEG"); + icvReleaseVideoWriter_FFMPEG_p = + (CvReleaseVideoWriter_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseVideoWriter_FFMPEG"); + icvWriteFrame_FFMPEG_p = + (CvWriteFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvWriteFrame_FFMPEG"); + +#if 0 + if( icvCreateFileCapture_FFMPEG_p != 0 && + icvReleaseCapture_FFMPEG_p != 0 && + icvGrabFrame_FFMPEG_p != 0 && + icvRetrieveFrame_FFMPEG_p != 0 && + icvSetCaptureProperty_FFMPEG_p != 0 && + icvGetCaptureProperty_FFMPEG_p != 0 && + icvCreateVideoWriter_FFMPEG_p != 0 && + icvReleaseVideoWriter_FFMPEG_p != 0 && + icvWriteFrame_FFMPEG_p != 0 ) + { + printf("Successfully initialized ffmpeg plugin!\n"); + } + else + { + printf("Failed to load FFMPEG plugin: module handle=%p\n", icvFFOpenCV); + } +#endif + } + #elif defined HAVE_FFMPEG + icvCreateFileCapture_FFMPEG_p = (CvCreateFileCapture_Plugin)cvCreateFileCapture_FFMPEG; + icvReleaseCapture_FFMPEG_p = (CvReleaseCapture_Plugin)cvReleaseCapture_FFMPEG; + icvGrabFrame_FFMPEG_p = (CvGrabFrame_Plugin)cvGrabFrame_FFMPEG; + icvRetrieveFrame_FFMPEG_p = (CvRetrieveFrame_Plugin)cvRetrieveFrame_FFMPEG; + icvSetCaptureProperty_FFMPEG_p = (CvSetCaptureProperty_Plugin)cvSetCaptureProperty_FFMPEG; + icvGetCaptureProperty_FFMPEG_p = (CvGetCaptureProperty_Plugin)cvGetCaptureProperty_FFMPEG; + icvCreateVideoWriter_FFMPEG_p = (CvCreateVideoWriter_Plugin)cvCreateVideoWriter_FFMPEG; + icvReleaseVideoWriter_FFMPEG_p = (CvReleaseVideoWriter_Plugin)cvReleaseVideoWriter_FFMPEG; + icvWriteFrame_FFMPEG_p = (CvWriteFrame_Plugin)cvWriteFrame_FFMPEG; + #endif + } +}; + + +class CvCapture_FFMPEG_proxy : + public CvCapture +{ +public: + CvCapture_FFMPEG_proxy() { ffmpegCapture = 0; } + virtual ~CvCapture_FFMPEG_proxy() { close(); } + + virtual double getProperty(int propId) + { + return ffmpegCapture ? icvGetCaptureProperty_FFMPEG_p(ffmpegCapture, propId) : 0; + } + virtual bool setProperty(int propId, double value) + { + return ffmpegCapture ? icvSetCaptureProperty_FFMPEG_p(ffmpegCapture, propId, value)!=0 : false; + } + virtual bool grabFrame() + { + return ffmpegCapture ? icvGrabFrame_FFMPEG_p(ffmpegCapture)!=0 : false; + } + virtual IplImage* retrieveFrame(int) + { + unsigned char* data = 0; + int step=0, width=0, height=0, cn=0; + + if (!ffmpegCapture || + !icvRetrieveFrame_FFMPEG_p(ffmpegCapture, &data, &step, &width, &height, &cn)) + return 0; + cvInitImageHeader(&frame, cvSize(width, height), 8, cn); + cvSetData(&frame, data, step); + return &frame; + } + virtual bool open( const char* filename ) + { + icvInitFFMPEG::Init(); + close(); + + if( !icvCreateFileCapture_FFMPEG_p ) + return false; + ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename ); + return ffmpegCapture != 0; + } + virtual void close() + { + if( ffmpegCapture && icvReleaseCapture_FFMPEG_p ) + icvReleaseCapture_FFMPEG_p( &ffmpegCapture ); + assert( ffmpegCapture == 0 ); + ffmpegCapture = 0; + } + +protected: + void* ffmpegCapture; + IplImage frame; +}; + + +CvCapture* cvCreateFileCapture_FFMPEG_proxy(const char * filename) +{ + CvCapture_FFMPEG_proxy* result = new CvCapture_FFMPEG_proxy; + if( result->open( filename )) + return result; + delete result; +#ifdef HAVE_VFW + return cvCreateFileCapture_VFW(filename); +#else + return 0; +#endif +} + +class CvVideoWriter_FFMPEG_proxy : + public CvVideoWriter +{ +public: + CvVideoWriter_FFMPEG_proxy() { ffmpegWriter = 0; } + virtual ~CvVideoWriter_FFMPEG_proxy() { close(); } + + virtual bool writeFrame( const IplImage* image ) + { + if(!ffmpegWriter) + return false; + CV_Assert(image->depth == 8); + + return icvWriteFrame_FFMPEG_p(ffmpegWriter, (const uchar*)image->imageData, + image->widthStep, image->width, image->height, image->nChannels, image->origin) !=0; + } + virtual bool open( const char* filename, int fourcc, double fps, CvSize frameSize, bool isColor ) + { + icvInitFFMPEG::Init(); + close(); + if( !icvCreateVideoWriter_FFMPEG_p ) + return false; + ffmpegWriter = icvCreateVideoWriter_FFMPEG_p( filename, fourcc, fps, frameSize.width, frameSize.height, isColor ); + return ffmpegWriter != 0; + } + + virtual void close() + { + if( ffmpegWriter && icvReleaseVideoWriter_FFMPEG_p ) + icvReleaseVideoWriter_FFMPEG_p( &ffmpegWriter ); + assert( ffmpegWriter == 0 ); + ffmpegWriter = 0; + } + +protected: + void* ffmpegWriter; +}; + + +CvVideoWriter* cvCreateVideoWriter_FFMPEG_proxy( const char* filename, int fourcc, + double fps, CvSize frameSize, int isColor ) +{ + CvVideoWriter_FFMPEG_proxy* result = new CvVideoWriter_FFMPEG_proxy; + + if( result->open( filename, fourcc, fps, frameSize, isColor != 0 )) + return result; + delete result; +#ifdef HAVE_VFW + return cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, isColor); + #else + return 0; +#endif +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg_api.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg_api.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg_api.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg_api.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,97 @@ +#ifndef __OPENCV_FFMPEG_H__ +#define __OPENCV_FFMPEG_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined WIN32 || defined _WIN32 +#define OPENCV_FFMPEG_API __declspec(dllexport) +#else +#define OPENCV_FFMPEG_API +#endif + +enum +{ + CV_FFMPEG_CAP_PROP_POS_MSEC=0, + CV_FFMPEG_CAP_PROP_POS_FRAMES=1, + CV_FFMPEG_CAP_PROP_POS_AVI_RATIO=2, + CV_FFMPEG_CAP_PROP_FRAME_WIDTH=3, + CV_FFMPEG_CAP_PROP_FRAME_HEIGHT=4, + CV_FFMPEG_CAP_PROP_FPS=5, + CV_FFMPEG_CAP_PROP_FOURCC=6, + CV_FFMPEG_CAP_PROP_FRAME_COUNT=7 +}; + + +OPENCV_FFMPEG_API struct CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG(const char* filename); +OPENCV_FFMPEG_API struct CvCapture_FFMPEG_2* cvCreateFileCapture_FFMPEG_2(const char* filename); +OPENCV_FFMPEG_API int cvSetCaptureProperty_FFMPEG(struct CvCapture_FFMPEG* cap, + int prop, double value); +OPENCV_FFMPEG_API int cvSetCaptureProperty_FFMPEG_2(struct CvCapture_FFMPEG_2* cap, + int prop, double value); +OPENCV_FFMPEG_API double cvGetCaptureProperty_FFMPEG(struct CvCapture_FFMPEG* cap, int prop); +OPENCV_FFMPEG_API double cvGetCaptureProperty_FFMPEG_2(struct CvCapture_FFMPEG_2* cap, int prop); +OPENCV_FFMPEG_API int cvGrabFrame_FFMPEG(struct CvCapture_FFMPEG* cap); +OPENCV_FFMPEG_API int cvGrabFrame_FFMPEG_2(struct CvCapture_FFMPEG_2* cap); +OPENCV_FFMPEG_API int cvRetrieveFrame_FFMPEG(struct CvCapture_FFMPEG* capture, unsigned char** data, + int* step, int* width, int* height, int* cn); +OPENCV_FFMPEG_API int cvRetrieveFrame_FFMPEG_2(struct CvCapture_FFMPEG_2* capture, unsigned char** data, + int* step, int* width, int* height, int* cn); +OPENCV_FFMPEG_API void cvReleaseCapture_FFMPEG(struct CvCapture_FFMPEG** cap); +OPENCV_FFMPEG_API void cvReleaseCapture_FFMPEG_2(struct CvCapture_FFMPEG_2** cap); +OPENCV_FFMPEG_API struct CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG(const char* filename, + int fourcc, double fps, int width, int height, int isColor ); +OPENCV_FFMPEG_API struct CvVideoWriter_FFMPEG_2* cvCreateVideoWriter_FFMPEG_2(const char* filename, + int fourcc, double fps, int width, int height, int isColor ); + +OPENCV_FFMPEG_API int cvWriteFrame_FFMPEG(struct CvVideoWriter_FFMPEG* writer, const unsigned char* data, + int step, int width, int height, int cn, int origin); + +OPENCV_FFMPEG_API void cvReleaseVideoWriter_FFMPEG(struct CvVideoWriter_FFMPEG** writer); + +typedef void* (*CvCreateFileCapture_Plugin)( const char* filename ); +typedef void* (*CvCreateCameraCapture_Plugin)( int index ); +typedef int (*CvGrabFrame_Plugin)( void* capture_handle ); +typedef int (*CvRetrieveFrame_Plugin)( void* capture_handle, unsigned char** data, int* step, + int* width, int* height, int* cn ); +typedef int (*CvSetCaptureProperty_Plugin)( void* capture_handle, int prop_id, double value ); +typedef double (*CvGetCaptureProperty_Plugin)( void* capture_handle, int prop_id ); +typedef void (*CvReleaseCapture_Plugin)( void** capture_handle ); +typedef void* (*CvCreateVideoWriter_Plugin)( const char* filename, int fourcc, + double fps, int width, int height, int iscolor ); +typedef int (*CvWriteFrame_Plugin)( void* writer_handle, const unsigned char* data, int step, + int width, int height, int cn, int origin); +typedef void (*CvReleaseVideoWriter_Plugin)( void** writer ); + +/* + * For CUDA encoder + */ + +OPENCV_FFMPEG_API struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps); +OPENCV_FFMPEG_API void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream); +OPENCV_FFMPEG_API void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame); + +typedef struct OutputMediaStream_FFMPEG* (*Create_OutputMediaStream_FFMPEG_Plugin)(const char* fileName, int width, int height, double fps); +typedef void (*Release_OutputMediaStream_FFMPEG_Plugin)(struct OutputMediaStream_FFMPEG* stream); +typedef void (*Write_OutputMediaStream_FFMPEG_Plugin)(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame); + +/* + * For CUDA decoder + */ + +OPENCV_FFMPEG_API struct InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height); +OPENCV_FFMPEG_API void release_InputMediaStream_FFMPEG(struct InputMediaStream_FFMPEG* stream); +OPENCV_FFMPEG_API int read_InputMediaStream_FFMPEG(struct InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile); + +typedef struct InputMediaStream_FFMPEG* (*Create_InputMediaStream_FFMPEG_Plugin)(const char* fileName, int* codec, int* chroma_format, int* width, int* height); +typedef void (*Release_InputMediaStream_FFMPEG_Plugin)(struct InputMediaStream_FFMPEG* stream); +typedef int (*Read_InputMediaStream_FFMPEG_Plugin)(struct InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile); + +#ifdef __cplusplus +} +#endif + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg_impl.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg_impl.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ffmpeg_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ffmpeg_impl.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2272 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "cap_ffmpeg_api.hpp" +#include +#include +#include + +#if defined _MSC_VER && _MSC_VER >= 1200 +#pragma warning( disable: 4244 4510 4512 4610 ) +#endif + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ffmpeg_codecs.hpp" + +#include + +#ifdef WIN32 + #define HAVE_FFMPEG_SWSCALE 1 + #include + #include +#else + +#ifndef HAVE_FFMPEG_SWSCALE + #error "libswscale is necessary to build the newer OpenCV ffmpeg wrapper" +#endif + +// if the header path is not specified explicitly, let's deduce it +#if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H + +#if defined(HAVE_GENTOO_FFMPEG) + #define HAVE_LIBAVCODEC_AVCODEC_H 1 + #if defined(HAVE_FFMPEG_SWSCALE) + #define HAVE_LIBSWSCALE_SWSCALE_H 1 + #endif +#elif defined HAVE_FFMPEG + #define HAVE_FFMPEG_AVCODEC_H 1 + #if defined(HAVE_FFMPEG_SWSCALE) + #define HAVE_FFMPEG_SWSCALE_H 1 + #endif +#endif + +#endif + +#if defined(HAVE_FFMPEG_AVCODEC_H) + #include +#endif +#if defined(HAVE_FFMPEG_SWSCALE_H) + #include +#endif + +#if defined(HAVE_LIBAVCODEC_AVCODEC_H) + #include +#endif +#if defined(HAVE_LIBSWSCALE_SWSCALE_H) + #include +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#if defined _MSC_VER && _MSC_VER >= 1200 +#pragma warning( default: 4244 4510 4512 4610 ) +#endif + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +/* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */ +#ifndef PIX_FMT_RGBA32 +#define PIX_FMT_RGBA32 PIX_FMT_RGB32 +#endif + +#define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c ) + +#if defined WIN32 || defined _WIN32 + #include +#elif defined __linux__ || defined __APPLE__ + #include + #include + #include + #include +#endif + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if defined(__APPLE__) +#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL) +#else +#define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE) +#endif + +#ifndef AVERROR_EOF +#define AVERROR_EOF (-MKTAG( 'E','O','F',' ')) +#endif + +#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0) +# define CV_CODEC_ID AVCodecID +# define CV_CODEC(name) AV_##name +#else +# define CV_CODEC_ID CodecID +# define CV_CODEC(name) name +#endif + +static int get_number_of_cpus(void) +{ +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0) + return 1; +#elif defined WIN32 || defined _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + + return (int)sysinfo.dwNumberOfProcessors; +#elif defined __linux__ + return (int)sysconf( _SC_NPROCESSORS_ONLN ); +#elif defined __APPLE__ + int numCPU=0; + int mib[4]; + size_t len = sizeof(numCPU); + + // set the mib for hw.ncpu + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; + + // get the number of CPUs from the system + sysctl(mib, 2, &numCPU, &len, NULL, 0); + + if( numCPU < 1 ) + { + mib[1] = HW_NCPU; + sysctl( mib, 2, &numCPU, &len, NULL, 0 ); + + if( numCPU < 1 ) + numCPU = 1; + } + + return (int)numCPU; +#else + return 1; +#endif +} + + +struct Image_FFMPEG +{ + unsigned char* data; + int step; + int width; + int height; + int cn; +}; + + +inline void _opencv_ffmpeg_free(void** ptr) +{ + if(*ptr) free(*ptr); + *ptr = 0; +} + + +struct CvCapture_FFMPEG +{ + bool open( const char* filename ); + void close(); + + double getProperty(int); + bool setProperty(int, double); + bool grabFrame(); + bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn); + + void init(); + + void seek(int64_t frame_number); + void seek(double sec); + bool slowSeek( int framenumber ); + + int64_t get_total_frames(); + double get_duration_sec(); + double get_fps(); + int get_bitrate(); + + double r2d(AVRational r); + int64_t dts_to_frame_number(int64_t dts); + double dts_to_sec(int64_t dts); + + AVFormatContext * ic; + AVCodec * avcodec; + int video_stream; + AVStream * video_st; + AVFrame * picture; + AVFrame rgb_picture; + int64_t picture_pts; + + AVPacket packet; + Image_FFMPEG frame; + struct SwsContext *img_convert_ctx; + + int64_t frame_number, first_frame_number; + + double eps_zero; +/* + 'filename' contains the filename of the videosource, + 'filename==NULL' indicates that ffmpeg's seek support works + for the particular file. + 'filename!=NULL' indicates that the slow fallback function is used for seeking, + and so the filename is needed to reopen the file on backward seeking. +*/ + char * filename; +}; + +void CvCapture_FFMPEG::init() +{ + ic = 0; + video_stream = -1; + video_st = 0; + picture = 0; + picture_pts = AV_NOPTS_VALUE_; + first_frame_number = -1; + memset( &rgb_picture, 0, sizeof(rgb_picture) ); + memset( &frame, 0, sizeof(frame) ); + filename = 0; + memset(&packet, 0, sizeof(packet)); + av_init_packet(&packet); + img_convert_ctx = 0; + + avcodec = 0; + frame_number = 0; + eps_zero = 0.000025; +} + + +void CvCapture_FFMPEG::close() +{ + if( img_convert_ctx ) + { + sws_freeContext(img_convert_ctx); + img_convert_ctx = 0; + } + + if( picture ) + av_free(picture); + + if( video_st ) + { +#if LIBAVFORMAT_BUILD > 4628 + avcodec_close( video_st->codec ); + +#else + avcodec_close( &(video_st->codec) ); + +#endif + video_st = NULL; + } + + if( ic ) + { +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) + av_close_input_file(ic); +#else + avformat_close_input(&ic); +#endif + + ic = NULL; + } + + if( rgb_picture.data[0] ) + { + free( rgb_picture.data[0] ); + rgb_picture.data[0] = 0; + } + + // free last packet if exist + if (packet.data) { + av_free_packet (&packet); + packet.data = NULL; + } + + init(); +} + + +#ifndef AVSEEK_FLAG_FRAME +#define AVSEEK_FLAG_FRAME 0 +#endif +#ifndef AVSEEK_FLAG_ANY +#define AVSEEK_FLAG_ANY 1 +#endif + +class ImplMutex +{ +public: + ImplMutex() { init(); } + ~ImplMutex() { destroy(); } + + void init(); + void destroy(); + + void lock(); + bool trylock(); + void unlock(); + + struct Impl; +protected: + Impl* impl; + +private: + ImplMutex(const ImplMutex&); + ImplMutex& operator = (const ImplMutex& m); +}; + +#if defined WIN32 || defined _WIN32 || defined WINCE + +struct ImplMutex::Impl +{ + void init() { InitializeCriticalSection(&cs); refcount = 1; } + void destroy() { DeleteCriticalSection(&cs); } + + void lock() { EnterCriticalSection(&cs); } + bool trylock() { return TryEnterCriticalSection(&cs) != 0; } + void unlock() { LeaveCriticalSection(&cs); } + + CRITICAL_SECTION cs; + int refcount; +}; + +#ifndef __GNUC__ +static int _interlockedExchangeAdd(int* addr, int delta) +{ +#if defined _MSC_VER && _MSC_VER >= 1500 + return (int)_InterlockedExchangeAdd((long volatile*)addr, delta); +#else + return (int)InterlockedExchangeAdd((long volatile*)addr, delta); +#endif +} +#endif // __GNUC__ + +#elif defined __APPLE__ + +#include + +struct ImplMutex::Impl +{ + void init() { sl = OS_SPINLOCK_INIT; refcount = 1; } + void destroy() { } + + void lock() { OSSpinLockLock(&sl); } + bool trylock() { return OSSpinLockTry(&sl); } + void unlock() { OSSpinLockUnlock(&sl); } + + OSSpinLock sl; + int refcount; +}; + +#elif defined __linux__ && !defined ANDROID + +struct ImplMutex::Impl +{ + void init() { pthread_spin_init(&sl, 0); refcount = 1; } + void destroy() { pthread_spin_destroy(&sl); } + + void lock() { pthread_spin_lock(&sl); } + bool trylock() { return pthread_spin_trylock(&sl) == 0; } + void unlock() { pthread_spin_unlock(&sl); } + + pthread_spinlock_t sl; + int refcount; +}; + +#else + +struct ImplMutex::Impl +{ + void init() { pthread_mutex_init(&sl, 0); refcount = 1; } + void destroy() { pthread_mutex_destroy(&sl); } + + void lock() { pthread_mutex_lock(&sl); } + bool trylock() { return pthread_mutex_trylock(&sl) == 0; } + void unlock() { pthread_mutex_unlock(&sl); } + + pthread_mutex_t sl; + int refcount; +}; + +#endif + +void ImplMutex::init() +{ + impl = (Impl*)malloc(sizeof(Impl)); + impl->init(); +} +void ImplMutex::destroy() +{ + impl->destroy(); + free(impl); + impl = NULL; +} +void ImplMutex::lock() { impl->lock(); } +void ImplMutex::unlock() { impl->unlock(); } +bool ImplMutex::trylock() { return impl->trylock(); } + +static int LockCallBack(void **mutex, AVLockOp op) +{ + ImplMutex* localMutex = reinterpret_cast(*mutex); + switch (op) + { + case AV_LOCK_CREATE: + localMutex = reinterpret_cast(malloc(sizeof(ImplMutex))); + localMutex->init(); + *mutex = localMutex; + if (!*mutex) + return 1; + break; + + case AV_LOCK_OBTAIN: + localMutex->lock(); + break; + + case AV_LOCK_RELEASE: + localMutex->unlock(); + break; + + case AV_LOCK_DESTROY: + localMutex->destroy(); + free(localMutex); + localMutex = NULL; + break; + } + return 0; +} + +static ImplMutex _mutex; +static bool _initialized = false; + +class InternalFFMpegRegister +{ +public: + InternalFFMpegRegister() + { + _mutex.lock(); + if (!_initialized) + { + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) + avformat_network_init(); + #endif + + /* register all codecs, demux and protocols */ + av_register_all(); + + /* register a callback function for synchronization */ + av_lockmgr_register(&LockCallBack); + + av_log_set_level(AV_LOG_ERROR); + + _initialized = true; + } + _mutex.unlock(); + } + + ~InternalFFMpegRegister() + { + _initialized = false; + av_lockmgr_register(NULL); + } +}; + +static InternalFFMpegRegister _init; + +bool CvCapture_FFMPEG::open( const char* _filename ) +{ + unsigned i; + bool valid = false; + + close(); + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0) + int err = avformat_open_input(&ic, _filename, NULL, NULL); +#else + int err = av_open_input_file(&ic, _filename, NULL, 0, NULL); +#endif + + if (err < 0) + { + CV_WARN("Error opening file"); + goto exit_func; + } + err = +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0) + avformat_find_stream_info(ic, NULL); +#else + av_find_stream_info(ic); +#endif + if (err < 0) + { + CV_WARN("Could not find codec parameters"); + goto exit_func; + } + for(i = 0; i < ic->nb_streams; i++) + { +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext *enc = ic->streams[i]->codec; +#else + AVCodecContext *enc = &ic->streams[i]->codec; +#endif + +//#ifdef FF_API_THREAD_INIT +// avcodec_thread_init(enc, get_number_of_cpus()); +//#else + enc->thread_count = get_number_of_cpus(); +//#endif + +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) +#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO +#endif + + if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) + { + // backup encoder' width/height + int enc_width = enc->width; + int enc_height = enc->height; + + AVCodec *codec = avcodec_find_decoder(enc->codec_id); + if (!codec || +#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) + avcodec_open2(enc, codec, NULL) +#else + avcodec_open(enc, codec) +#endif + < 0) + goto exit_func; + + // checking width/height (since decoder can sometimes alter it, eg. vp6f) + if (enc_width && (enc->width != enc_width)) { enc->width = enc_width; } + if (enc_height && (enc->height != enc_height)) { enc->height = enc_height; } + + video_stream = i; + video_st = ic->streams[i]; + picture = avcodec_alloc_frame(); + + rgb_picture.data[0] = (uint8_t*)malloc( + avpicture_get_size( PIX_FMT_BGR24, + enc->width, enc->height )); + avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0], + PIX_FMT_BGR24, enc->width, enc->height ); + + frame.width = enc->width; + frame.height = enc->height; + frame.cn = 3; + frame.step = rgb_picture.linesize[0]; + frame.data = rgb_picture.data[0]; + break; + } + } + + if(video_stream >= 0) valid = true; + +exit_func: + + if( !valid ) + close(); + + return valid; +} + + +bool CvCapture_FFMPEG::grabFrame() +{ + bool valid = false; + int got_picture; + + int count_errs = 0; + const int max_number_of_attempts = 1 << 16; + + if( !ic || !video_st ) return false; + + if( ic->streams[video_stream]->nb_frames > 0 && + frame_number > ic->streams[video_stream]->nb_frames ) + return false; + + av_free_packet (&packet); + + picture_pts = AV_NOPTS_VALUE_; + + // get the next frame + while (!valid) + { + int ret = av_read_frame(ic, &packet); + if (ret == AVERROR(EAGAIN)) continue; + + /* else if (ret < 0) break; */ + + if( packet.stream_index != video_stream ) + { + av_free_packet (&packet); + count_errs++; + if (count_errs > max_number_of_attempts) + break; + continue; + } + + // Decode video frame + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); + #elif LIBAVFORMAT_BUILD > 4628 + avcodec_decode_video(video_st->codec, + picture, &got_picture, + packet.data, packet.size); + #else + avcodec_decode_video(&video_st->codec, + picture, &got_picture, + packet.data, packet.size); + #endif + + // Did we get a video frame? + if(got_picture) + { + //picture_pts = picture->best_effort_timestamp; + if( picture_pts == AV_NOPTS_VALUE_ ) + picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts; + frame_number++; + valid = true; + } + else + { + count_errs++; + if (count_errs > max_number_of_attempts) + break; + } + + av_free_packet (&packet); + } + + if( valid && first_frame_number < 0 ) + first_frame_number = dts_to_frame_number(picture_pts); + + // return if we have a new picture or not + return valid; +} + + +bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn) +{ + if( !video_st || !picture->data[0] ) + return false; + + avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, + video_st->codec->width, video_st->codec->height); + + if( img_convert_ctx == NULL || + frame.width != video_st->codec->width || + frame.height != video_st->codec->height ) + { + if( img_convert_ctx ) + sws_freeContext(img_convert_ctx); + + frame.width = video_st->codec->width; + frame.height = video_st->codec->height; + + img_convert_ctx = sws_getCachedContext( + NULL, + video_st->codec->width, video_st->codec->height, + video_st->codec->pix_fmt, + video_st->codec->width, video_st->codec->height, + PIX_FMT_BGR24, + SWS_BICUBIC, + NULL, NULL, NULL + ); + + if (img_convert_ctx == NULL) + return false;//CV_Error(0, "Cannot initialize the conversion context!"); + } + + sws_scale( + img_convert_ctx, + picture->data, + picture->linesize, + 0, video_st->codec->height, + rgb_picture.data, + rgb_picture.linesize + ); + + *data = frame.data; + *step = frame.step; + *width = frame.width; + *height = frame.height; + *cn = frame.cn; + + return true; +} + + +double CvCapture_FFMPEG::getProperty( int property_id ) +{ + if( !video_st ) return 0; + + switch( property_id ) + { + case CV_FFMPEG_CAP_PROP_POS_MSEC: + return 1000.0*(double)frame_number/get_fps(); + case CV_FFMPEG_CAP_PROP_POS_FRAMES: + return (double)frame_number; + case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO: + return r2d(ic->streams[video_stream]->time_base); + case CV_FFMPEG_CAP_PROP_FRAME_COUNT: + return (double)get_total_frames(); + case CV_FFMPEG_CAP_PROP_FRAME_WIDTH: + return (double)frame.width; + case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT: + return (double)frame.height; + case CV_FFMPEG_CAP_PROP_FPS: +#if LIBAVCODEC_BUILD > 4753 + return av_q2d(video_st->r_frame_rate); +#else + return (double)video_st->codec.frame_rate + / (double)video_st->codec.frame_rate_base; +#endif + case CV_FFMPEG_CAP_PROP_FOURCC: +#if LIBAVFORMAT_BUILD > 4628 + return (double)video_st->codec->codec_tag; +#else + return (double)video_st->codec.codec_tag; +#endif + default: + break; + } + + return 0; +} + +double CvCapture_FFMPEG::r2d(AVRational r) +{ + return r.num == 0 || r.den == 0 ? 0. : (double)r.num / (double)r.den; +} + +double CvCapture_FFMPEG::get_duration_sec() +{ + double sec = (double)ic->duration / (double)AV_TIME_BASE; + + if (sec < eps_zero) + { + sec = (double)ic->streams[video_stream]->duration * r2d(ic->streams[video_stream]->time_base); + } + + if (sec < eps_zero) + { + sec = (double)ic->streams[video_stream]->duration * r2d(ic->streams[video_stream]->time_base); + } + + return sec; +} + +int CvCapture_FFMPEG::get_bitrate() +{ + return ic->bit_rate; +} + +double CvCapture_FFMPEG::get_fps() +{ + double fps = r2d(ic->streams[video_stream]->r_frame_rate); + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0) + if (fps < eps_zero) + { + fps = r2d(ic->streams[video_stream]->avg_frame_rate); + } +#endif + + if (fps < eps_zero) + { + fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base); + } + + return fps; +} + +int64_t CvCapture_FFMPEG::get_total_frames() +{ + int64_t nbf = ic->streams[video_stream]->nb_frames; + + if (nbf == 0) + { + nbf = (int64_t)floor(get_duration_sec() * get_fps() + 0.5); + } + return nbf; +} + +int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts) +{ + double sec = dts_to_sec(dts); + return (int64_t)(get_fps() * sec + 0.5); +} + +double CvCapture_FFMPEG::dts_to_sec(int64_t dts) +{ + return (double)(dts - ic->streams[video_stream]->start_time) * + r2d(ic->streams[video_stream]->time_base); +} + +void CvCapture_FFMPEG::seek(int64_t _frame_number) +{ + _frame_number = std::min(_frame_number, get_total_frames()); + int delta = 16; + + // if we have not grabbed a single frame before first seek, let's read the first frame + // and get some valuable information during the process + if( first_frame_number < 0 && get_total_frames() > 1 ) + grabFrame(); + + for(;;) + { + int64_t _frame_number_temp = std::max(_frame_number-delta, (int64_t)0); + double sec = (double)_frame_number_temp / get_fps(); + int64_t time_stamp = ic->streams[video_stream]->start_time; + double time_base = r2d(ic->streams[video_stream]->time_base); + time_stamp += (int64_t)(sec / time_base + 0.5); + if (get_total_frames() > 1) av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_BACKWARD); + avcodec_flush_buffers(ic->streams[video_stream]->codec); + if( _frame_number > 0 ) + { + grabFrame(); + + if( _frame_number > 1 ) + { + frame_number = dts_to_frame_number(picture_pts) - first_frame_number; + //printf("_frame_number = %d, frame_number = %d, delta = %d\n", + // (int)_frame_number, (int)frame_number, delta); + + if( frame_number < 0 || frame_number > _frame_number-1 ) + { + if( _frame_number_temp == 0 || delta >= INT_MAX/4 ) + break; + delta = delta < 16 ? delta*2 : delta*3/2; + continue; + } + while( frame_number < _frame_number-1 ) + { + if(!grabFrame()) + break; + } + frame_number++; + break; + } + else + { + frame_number = 1; + break; + } + } + else + { + frame_number = 0; + break; + } + } +} + +void CvCapture_FFMPEG::seek(double sec) +{ + seek((int64_t)(sec * get_fps() + 0.5)); +} + +bool CvCapture_FFMPEG::setProperty( int property_id, double value ) +{ + if( !video_st ) return false; + + switch( property_id ) + { + case CV_FFMPEG_CAP_PROP_POS_MSEC: + case CV_FFMPEG_CAP_PROP_POS_FRAMES: + case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO: + { + switch( property_id ) + { + case CV_FFMPEG_CAP_PROP_POS_FRAMES: + seek((int64_t)value); + break; + + case CV_FFMPEG_CAP_PROP_POS_MSEC: + seek(value/1000.0); + break; + + case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO: + seek((int64_t)(value*ic->duration)); + break; + } + + picture_pts=(int64_t)value; + } + break; + default: + return false; + } + + return true; +} + + +///////////////// FFMPEG CvVideoWriter implementation ////////////////////////// +struct CvVideoWriter_FFMPEG +{ + bool open( const char* filename, int fourcc, + double fps, int width, int height, bool isColor ); + void close(); + bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ); + + void init(); + + AVOutputFormat * fmt; + AVFormatContext * oc; + uint8_t * outbuf; + uint32_t outbuf_size; + FILE * outfile; + AVFrame * picture; + AVFrame * input_picture; + uint8_t * picbuf; + AVStream * video_st; + int input_pix_fmt; + Image_FFMPEG temp_image; + int frame_width, frame_height; + bool ok; + struct SwsContext *img_convert_ctx; +}; + +static const char * icvFFMPEGErrStr(int err) +{ +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + switch(err) { + case AVERROR_BSF_NOT_FOUND: + return "Bitstream filter not found"; + case AVERROR_DECODER_NOT_FOUND: + return "Decoder not found"; + case AVERROR_DEMUXER_NOT_FOUND: + return "Demuxer not found"; + case AVERROR_ENCODER_NOT_FOUND: + return "Encoder not found"; + case AVERROR_EOF: + return "End of file"; + case AVERROR_EXIT: + return "Immediate exit was requested; the called function should not be restarted"; + case AVERROR_FILTER_NOT_FOUND: + return "Filter not found"; + case AVERROR_INVALIDDATA: + return "Invalid data found when processing input"; + case AVERROR_MUXER_NOT_FOUND: + return "Muxer not found"; + case AVERROR_OPTION_NOT_FOUND: + return "Option not found"; + case AVERROR_PATCHWELCOME: + return "Not yet implemented in FFmpeg, patches welcome"; + case AVERROR_PROTOCOL_NOT_FOUND: + return "Protocol not found"; + case AVERROR_STREAM_NOT_FOUND: + return "Stream not found"; + default: + break; + } +#else + switch(err) { + case AVERROR_NUMEXPECTED: + return "Incorrect filename syntax"; + case AVERROR_INVALIDDATA: + return "Invalid data in header"; + case AVERROR_NOFMT: + return "Unknown format"; + case AVERROR_IO: + return "I/O error occurred"; + case AVERROR_NOMEM: + return "Memory allocation error"; + default: + break; + } +#endif + + return "Unspecified error"; +} + +/* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/ +extern "C" { + enum CV_CODEC_ID codec_get_bmp_id(unsigned int tag); +} + +void CvVideoWriter_FFMPEG::init() +{ + fmt = 0; + oc = 0; + outbuf = 0; + outbuf_size = 0; + outfile = 0; + picture = 0; + input_picture = 0; + picbuf = 0; + video_st = 0; + input_pix_fmt = 0; + memset(&temp_image, 0, sizeof(temp_image)); + img_convert_ctx = 0; + frame_width = frame_height = 0; + ok = false; +} + +/** + * the following function is a modified version of code + * found in ffmpeg-0.4.9-pre1/output_example.c + */ +static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc) +{ + AVFrame * picture; + uint8_t * picture_buf; + int size; + + picture = avcodec_alloc_frame(); + if (!picture) + return NULL; + size = avpicture_get_size( (PixelFormat) pix_fmt, width, height); + if(alloc){ + picture_buf = (uint8_t *) malloc(size); + if (!picture_buf) + { + av_free(picture); + return NULL; + } + avpicture_fill((AVPicture *)picture, picture_buf, + (PixelFormat) pix_fmt, width, height); + } + else { + } + return picture; +} + +/* add a video output stream to the container */ +static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, + CV_CODEC_ID codec_id, + int w, int h, int bitrate, + double fps, int pixel_format) +{ + AVCodecContext *c; + AVStream *st; + int frame_rate, frame_rate_base; + AVCodec *codec; + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) + st = avformat_new_stream(oc, 0); +#else + st = av_new_stream(oc, 0); +#endif + + if (!st) { + CV_WARN("Could not allocate stream"); + return NULL; + } + +#if LIBAVFORMAT_BUILD > 4628 + c = st->codec; +#else + c = &(st->codec); +#endif + +#if LIBAVFORMAT_BUILD > 4621 + c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); +#else + c->codec_id = oc->oformat->video_codec; +#endif + + if(codec_id != CV_CODEC(CODEC_ID_NONE)){ + c->codec_id = codec_id; + } + + //if(codec_tag) c->codec_tag=codec_tag; + codec = avcodec_find_encoder(c->codec_id); + + c->codec_type = AVMEDIA_TYPE_VIDEO; + + /* put sample parameters */ + int64_t lbit_rate = (int64_t)bitrate; + lbit_rate += (bitrate / 2); + lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX); + c->bit_rate = lbit_rate; + + // took advice from + // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html + c->qmin = 3; + + /* resolution must be a multiple of two */ + c->width = w; + c->height = h; + + /* time base: this is the fundamental unit of time (in seconds) in terms + of which frame timestamps are represented. for fixed-fps content, + timebase should be 1/framerate and timestamp increments should be + identically 1. */ + frame_rate=(int)(fps+0.5); + frame_rate_base=1; + while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){ + frame_rate_base*=10; + frame_rate=(int)(fps*frame_rate_base + 0.5); + } +#if LIBAVFORMAT_BUILD > 4752 + c->time_base.den = frame_rate; + c->time_base.num = frame_rate_base; + /* adjust time base for supported framerates */ + if(codec && codec->supported_framerates){ + const AVRational *p= codec->supported_framerates; + AVRational req = {frame_rate, frame_rate_base}; + const AVRational *best=NULL; + AVRational best_error= {INT_MAX, 1}; + for(; p->den!=0; p++){ + AVRational error= av_sub_q(req, *p); + if(error.num <0) error.num *= -1; + if(av_cmp_q(error, best_error) < 0){ + best_error= error; + best= p; + } + } + c->time_base.den= best->num; + c->time_base.num= best->den; + } +#else + c->frame_rate = frame_rate; + c->frame_rate_base = frame_rate_base; +#endif + + c->gop_size = 12; /* emit one intra frame every twelve frames at most */ + c->pix_fmt = (PixelFormat) pixel_format; + + if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) { + c->max_b_frames = 2; + } + if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3)){ + /* needed to avoid using macroblocks in which some coeffs overflow + this doesnt happen with normal video, it just happens here as the + motion of the chroma plane doesnt match the luma plane */ + /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */ + c->mb_decision=2; + } +#if LIBAVCODEC_VERSION_INT>0x000409 + // some formats want stream headers to be seperate + if(oc->oformat->flags & AVFMT_GLOBALHEADER) + { + c->flags |= CODEC_FLAG_GLOBAL_HEADER; + } +#endif + + return st; +} + +static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000; + +static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture ) +{ +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext * c = video_st->codec; +#else + AVCodecContext * c = &(video_st->codec); +#endif + int out_size; + int ret = 0; + + if (oc->oformat->flags & AVFMT_RAWPICTURE) { + /* raw video case. The API will change slightly in the near + futur for that */ + AVPacket pkt; + av_init_packet(&pkt); + +#ifndef PKT_FLAG_KEY +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif + + pkt.flags |= PKT_FLAG_KEY; + pkt.stream_index= video_st->index; + pkt.data= (uint8_t *)picture; + pkt.size= sizeof(AVPicture); + + ret = av_write_frame(oc, &pkt); + } else { + /* encode the image */ + out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); + /* if zero size, it means the image was buffered */ + if (out_size > 0) { + AVPacket pkt; + av_init_packet(&pkt); + +#if LIBAVFORMAT_BUILD > 4752 + if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) + pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base); +#else + pkt.pts = c->coded_frame->pts; +#endif + if(c->coded_frame->key_frame) + pkt.flags |= PKT_FLAG_KEY; + pkt.stream_index= video_st->index; + pkt.data= outbuf; + pkt.size= out_size; + + /* write the compressed frame in the media file */ + ret = av_write_frame(oc, &pkt); + } else { + ret = OPENCV_NO_FRAMES_WRITTEN_CODE; + } + } + return ret; +} + +/// write a frame with FFMPEG +bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ) +{ + bool ret = false; + + if( (width & -2) != frame_width || (height & -2) != frame_height || !data ) + return false; + width = frame_width; + height = frame_height; + + // typecast from opaque data type to implemented struct +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext *c = video_st->codec; +#else + AVCodecContext *c = &(video_st->codec); +#endif + +#if LIBAVFORMAT_BUILD < 5231 + // It is not needed in the latest versions of the ffmpeg + if( c->codec_id == CV_CODEC(CODEC_ID_RAWVIDEO) && origin != 1 ) + { + if( !temp_image.data ) + { + temp_image.step = (width*cn + 3) & -4; + temp_image.width = width; + temp_image.height = height; + temp_image.cn = cn; + temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); + } + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn); + data = temp_image.data; + step = temp_image.step; + } +#else + if( width*cn != step ) + { + if( !temp_image.data ) + { + temp_image.step = width*cn; + temp_image.width = width; + temp_image.height = height; + temp_image.cn = cn; + temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); + } + if (origin == 1) + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step); + else + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step); + data = temp_image.data; + step = temp_image.step; + } +#endif + + // check parameters + if (input_pix_fmt == PIX_FMT_BGR24) { + if (cn != 3) { + return false; + } + } + else if (input_pix_fmt == PIX_FMT_GRAY8) { + if (cn != 1) { + return false; + } + } + else { + assert(false); + } + + if ( c->pix_fmt != input_pix_fmt ) { + assert( input_picture ); + // let input_picture point to the raw data buffer of 'image' + avpicture_fill((AVPicture *)input_picture, (uint8_t *) data, + (PixelFormat)input_pix_fmt, width, height); + + if( !img_convert_ctx ) + { + img_convert_ctx = sws_getContext(width, + height, + (PixelFormat)input_pix_fmt, + c->width, + c->height, + c->pix_fmt, + SWS_BICUBIC, + NULL, NULL, NULL); + if( !img_convert_ctx ) + return false; + } + + if ( sws_scale(img_convert_ctx, input_picture->data, + input_picture->linesize, 0, + height, + picture->data, picture->linesize) < 0 ) + return false; + } + else{ + avpicture_fill((AVPicture *)picture, (uint8_t *) data, + (PixelFormat)input_pix_fmt, width, height); + } + + ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0; + + return ret; +} + +/// close video output stream and free associated memory +void CvVideoWriter_FFMPEG::close() +{ + unsigned i; + + // nothing to do if already released + if ( !picture ) + return; + + /* no more frame to compress. The codec has a latency of a few + frames if using B frames, so we get the last frames by + passing the same picture again */ + // TODO -- do we need to account for latency here? + + /* write the trailer, if any */ + if(ok && oc) + { + if( (oc->oformat->flags & AVFMT_RAWPICTURE) == 0 ) + { + for(;;) + { + int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL); + if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 ) + break; + } + } + av_write_trailer(oc); + } + + if( img_convert_ctx ) + { + sws_freeContext(img_convert_ctx); + img_convert_ctx = 0; + } + + // free pictures +#if LIBAVFORMAT_BUILD > 4628 + if( video_st->codec->pix_fmt != input_pix_fmt) +#else + if( video_st->codec.pix_fmt != input_pix_fmt) +#endif + { + if(picture->data[0]) + free(picture->data[0]); + picture->data[0] = 0; + } + av_free(picture); + + if (input_picture) + av_free(input_picture); + + /* close codec */ +#if LIBAVFORMAT_BUILD > 4628 + avcodec_close(video_st->codec); +#else + avcodec_close(&(video_st->codec)); +#endif + + av_free(outbuf); + + /* free the streams */ + for(i = 0; i < oc->nb_streams; i++) + { + av_freep(&oc->streams[i]->codec); + av_freep(&oc->streams[i]); + } + + if (!(fmt->flags & AVFMT_NOFILE)) + { + /* close the output file */ + +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) +#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) + url_fclose(oc->pb); +#else + url_fclose(&oc->pb); +#endif +#else + avio_close(oc->pb); +#endif + + } + + /* free the stream */ + av_free(oc); + + if( temp_image.data ) + { + free(temp_image.data); + temp_image.data = 0; + } + + init(); +} + +/// Create a video writer object that uses FFMPEG +bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + double fps, int width, int height, bool is_color ) +{ + CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_NONE); + int err, codec_pix_fmt; + double bitrate_scale = 1; + + close(); + + // check arguments + if( !filename ) + return false; + if(fps <= 0) + return false; + + // we allow frames of odd width or height, but in this case we truncate + // the rightmost column/the bottom row. Probably, this should be handled more elegantly, + // but some internal functions inside FFMPEG swscale require even width/height. + width &= -2; + height &= -2; + if( width <= 0 || height <= 0 ) + return false; + + /* auto detect the output format from the name and fourcc code. */ + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + fmt = av_guess_format(NULL, filename, NULL); +#else + fmt = guess_format(NULL, filename, NULL); +#endif + + if (!fmt) + return false; + + /* determine optimal pixel format */ + if (is_color) { + input_pix_fmt = PIX_FMT_BGR24; + } + else { + input_pix_fmt = PIX_FMT_GRAY8; + } + + /* Lookup codec_id for given fourcc */ +#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0) + if( (codec_id = codec_get_bmp_id( fourcc )) == CV_CODEC(CODEC_ID_NONE) ) + return false; +#else + const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL}; + if( (codec_id = av_codec_get_id(tags, fourcc)) == CV_CODEC(CODEC_ID_NONE) ) + return false; +#endif + + // alloc memory for context +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + oc = avformat_alloc_context(); +#else + oc = av_alloc_format_context(); +#endif + assert (oc); + + /* set file name */ + oc->oformat = fmt; + snprintf(oc->filename, sizeof(oc->filename), "%s", filename); + + /* set some options */ + oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ + + // set a few optimal pixel formats for lossless codecs of interest.. + switch (codec_id) { +#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) + case CV_CODEC(CODEC_ID_JPEGLS): + // BGR24 or GRAY8 depending on is_color... + codec_pix_fmt = input_pix_fmt; + break; +#endif + case CV_CODEC(CODEC_ID_HUFFYUV): + codec_pix_fmt = PIX_FMT_YUV422P; + break; + case CV_CODEC(CODEC_ID_MJPEG): + case CV_CODEC(CODEC_ID_LJPEG): + codec_pix_fmt = PIX_FMT_YUVJ420P; + bitrate_scale = 3; + break; + case CV_CODEC(CODEC_ID_RAWVIDEO): + codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || + input_pix_fmt == PIX_FMT_GRAY16LE || + input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; + break; + default: + // good for lossy formats, MPEG, etc. + codec_pix_fmt = PIX_FMT_YUV420P; + break; + } + + double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2); + + // TODO -- safe to ignore output audio stream? + video_st = icv_add_video_stream_FFMPEG(oc, codec_id, + width, height, (int)(bitrate + 0.5), + fps, codec_pix_fmt); + + /* set the output parameters (must be done even if no + parameters). */ +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + if (av_set_parameters(oc, NULL) < 0) { + return false; + } +#endif + +#if 0 +#if FF_API_DUMP_FORMAT + dump_format(oc, 0, filename, 1); +#else + av_dump_format(oc, 0, filename, 1); +#endif +#endif + + /* now that all the parameters are set, we can open the audio and + video codecs and allocate the necessary encode buffers */ + if (!video_st){ + return false; + } + + AVCodec *codec; + AVCodecContext *c; + +#if LIBAVFORMAT_BUILD > 4628 + c = (video_st->codec); +#else + c = &(video_st->codec); +#endif + + c->codec_tag = fourcc; + /* find the video encoder */ + codec = avcodec_find_encoder(c->codec_id); + if (!codec) { + fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr( + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + AVERROR_ENCODER_NOT_FOUND + #else + -1 + #endif + )); + return false; + } + + int64_t lbit_rate = (int64_t)c->bit_rate; + lbit_rate += (bitrate / 2); + lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX); + c->bit_rate_tolerance = (int)lbit_rate; + c->bit_rate = (int)lbit_rate; + + /* open the codec */ + if ((err= +#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) + avcodec_open2(c, codec, NULL) +#else + avcodec_open(c, codec) +#endif + ) < 0) { + fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); + return false; + } + + outbuf = NULL; + + if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { + /* allocate output buffer */ + /* assume we will never get codec output with more than 4 bytes per pixel... */ + outbuf_size = width*height*4; + outbuf = (uint8_t *) av_malloc(outbuf_size); + } + + bool need_color_convert; + need_color_convert = (c->pix_fmt != input_pix_fmt); + + /* allocate the encoded raw picture */ + picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); + if (!picture) { + return false; + } + + /* if the output format is not our input format, then a temporary + picture of the input format is needed too. It is then converted + to the required output format */ + input_picture = NULL; + if ( need_color_convert ) { + input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); + if (!input_picture) { + return false; + } + } + + /* open the output file, if needed */ + if (!(fmt->flags & AVFMT_NOFILE)) { +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) +#else + if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) +#endif + { + return false; + } + } + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0) + /* write the stream header, if any */ + err=avformat_write_header(oc, NULL); +#else + err=av_write_header( oc ); +#endif + + if(err < 0) + { + close(); + remove(filename); + return false; + } + frame_width = width; + frame_height = height; + ok = true; + + return true; +} + + + +CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) +{ + CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); + capture->init(); + if( capture->open( filename )) + return capture; + + capture->close(); + free(capture); + return 0; +} + + +void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) +{ + if( capture && *capture ) + { + (*capture)->close(); + free(*capture); + *capture = 0; + } +} + +int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) +{ + return capture->setProperty(prop_id, value); +} + +double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) +{ + return capture->getProperty(prop_id); +} + +int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) +{ + return capture->grabFrame(); +} + +int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) +{ + return capture->retrieveFrame(0, data, step, width, height, cn); +} + +CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, + int width, int height, int isColor ) +{ + CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); + writer->init(); + if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) + return writer; + writer->close(); + free(writer); + return 0; +} + +void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) +{ + if( writer && *writer ) + { + (*writer)->close(); + free(*writer); + *writer = 0; + } +} + + +int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, + const unsigned char* data, int step, + int width, int height, int cn, int origin) +{ + return writer->writeFrame(data, step, width, height, cn, origin); +} + + + +/* + * For CUDA encoder + */ + +struct OutputMediaStream_FFMPEG +{ + bool open(const char* fileName, int width, int height, double fps); + void close(); + + void write(unsigned char* data, int size, int keyFrame); + + // add a video output stream to the container + static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format); + + AVOutputFormat* fmt_; + AVFormatContext* oc_; + AVStream* video_st_; +}; + +void OutputMediaStream_FFMPEG::close() +{ + // no more frame to compress. The codec has a latency of a few + // frames if using B frames, so we get the last frames by + // passing the same picture again + + // TODO -- do we need to account for latency here? + + if (oc_) + { + // write the trailer, if any + av_write_trailer(oc_); + + // free the streams + for (unsigned int i = 0; i < oc_->nb_streams; ++i) + { + av_freep(&oc_->streams[i]->codec); + av_freep(&oc_->streams[i]); + } + + if (!(fmt_->flags & AVFMT_NOFILE) && oc_->pb) + { + // close the output file + + #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) + #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) + url_fclose(oc_->pb); + #else + url_fclose(&oc_->pb); + #endif + #else + avio_close(oc_->pb); + #endif + } + + // free the stream + av_free(oc_); + } +} + +AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format) +{ + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) + AVStream* st = avformat_new_stream(oc, 0); + #else + AVStream* st = av_new_stream(oc, 0); + #endif + if (!st) + return 0; + + #if LIBAVFORMAT_BUILD > 4628 + AVCodecContext* c = st->codec; + #else + AVCodecContext* c = &(st->codec); + #endif + + c->codec_id = codec_id; + c->codec_type = AVMEDIA_TYPE_VIDEO; + + // put sample parameters + unsigned long long lbit_rate = static_cast(bitrate); + lbit_rate += (bitrate / 4); + lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); + c->bit_rate = bitrate; + + // took advice from + // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html + c->qmin = 3; + + // resolution must be a multiple of two + c->width = w; + c->height = h; + + AVCodec* codec = avcodec_find_encoder(c->codec_id); + + // time base: this is the fundamental unit of time (in seconds) in terms + // of which frame timestamps are represented. for fixed-fps content, + // timebase should be 1/framerate and timestamp increments should be + // identically 1 + + int frame_rate = static_cast(fps+0.5); + int frame_rate_base = 1; + while (fabs(static_cast(frame_rate)/frame_rate_base) - fps > 0.001) + { + frame_rate_base *= 10; + frame_rate = static_cast(fps*frame_rate_base + 0.5); + } + c->time_base.den = frame_rate; + c->time_base.num = frame_rate_base; + + #if LIBAVFORMAT_BUILD > 4752 + // adjust time base for supported framerates + if (codec && codec->supported_framerates) + { + AVRational req = {frame_rate, frame_rate_base}; + const AVRational* best = NULL; + AVRational best_error = {INT_MAX, 1}; + + for (const AVRational* p = codec->supported_framerates; p->den!=0; ++p) + { + AVRational error = av_sub_q(req, *p); + + if (error.num < 0) + error.num *= -1; + + if (av_cmp_q(error, best_error) < 0) + { + best_error= error; + best= p; + } + } + + c->time_base.den= best->num; + c->time_base.num= best->den; + } + #endif + + c->gop_size = 12; // emit one intra frame every twelve frames at most + c->pix_fmt = pixel_format; + + if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) + c->max_b_frames = 2; + + if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3)) + { + // needed to avoid using macroblocks in which some coeffs overflow + // this doesnt happen with normal video, it just happens here as the + // motion of the chroma plane doesnt match the luma plane + + // avoid FFMPEG warning 'clipping 1 dct coefficients...' + + c->mb_decision = 2; + } + + #if LIBAVCODEC_VERSION_INT > 0x000409 + // some formats want stream headers to be seperate + if (oc->oformat->flags & AVFMT_GLOBALHEADER) + { + c->flags |= CODEC_FLAG_GLOBAL_HEADER; + } + #endif + + return st; +} + +bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps) +{ + fmt_ = 0; + oc_ = 0; + video_st_ = 0; + + // auto detect the output format from the name and fourcc code + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + fmt_ = av_guess_format(NULL, fileName, NULL); + #else + fmt_ = guess_format(NULL, fileName, NULL); + #endif + if (!fmt_) + return false; + + CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_H264); + + // alloc memory for context + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + oc_ = avformat_alloc_context(); + #else + oc_ = av_alloc_format_context(); + #endif + if (!oc_) + return false; + + // set some options + oc_->oformat = fmt_; + snprintf(oc_->filename, sizeof(oc_->filename), "%s", fileName); + + oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG + + // set a few optimal pixel formats for lossless codecs of interest.. + PixelFormat codec_pix_fmt = PIX_FMT_YUV420P; + int bitrate_scale = 64; + + // TODO -- safe to ignore output audio stream? + video_st_ = addVideoStream(oc_, codec_id, width, height, width * height * bitrate_scale, fps, codec_pix_fmt); + if (!video_st_) + return false; + + // set the output parameters (must be done even if no parameters) + #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + if (av_set_parameters(oc_, NULL) < 0) + return false; + #endif + + // now that all the parameters are set, we can open the audio and + // video codecs and allocate the necessary encode buffers + + #if LIBAVFORMAT_BUILD > 4628 + AVCodecContext* c = (video_st_->codec); + #else + AVCodecContext* c = &(video_st_->codec); + #endif + + c->codec_tag = MKTAG('H', '2', '6', '4'); + c->bit_rate_tolerance = c->bit_rate; + + // open the output file, if needed + if (!(fmt_->flags & AVFMT_NOFILE)) + { + #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + int err = url_fopen(&oc_->pb, fileName, URL_WRONLY); + #else + int err = avio_open(&oc_->pb, fileName, AVIO_FLAG_WRITE); + #endif + + if (err != 0) + return false; + } + + // write the stream header, if any + #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + av_write_header(oc_); + #else + avformat_write_header(oc_, NULL); + #endif + + return true; +} + +void OutputMediaStream_FFMPEG::write(unsigned char* data, int size, int keyFrame) +{ + // if zero size, it means the image was buffered + if (size > 0) + { + AVPacket pkt; + av_init_packet(&pkt); + + if (keyFrame) + pkt.flags |= PKT_FLAG_KEY; + + pkt.stream_index = video_st_->index; + pkt.data = data; + pkt.size = size; + + // write the compressed frame in the media file + av_write_frame(oc_, &pkt); + } +} + +struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps) +{ + OutputMediaStream_FFMPEG* stream = (OutputMediaStream_FFMPEG*) malloc(sizeof(OutputMediaStream_FFMPEG)); + + if (stream->open(fileName, width, height, fps)) + return stream; + + stream->close(); + free(stream); + + return 0; +} + +void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream) +{ + stream->close(); + free(stream); +} + +void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame) +{ + stream->write(data, size, keyFrame); +} + +/* + * For CUDA decoder + */ + +enum +{ + VideoCodec_MPEG1 = 0, + VideoCodec_MPEG2, + VideoCodec_MPEG4, + VideoCodec_VC1, + VideoCodec_H264, + VideoCodec_JPEG, + VideoCodec_H264_SVC, + VideoCodec_H264_MVC, + + // Uncompressed YUV + VideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), // Y,U,V (4:2:0) + VideoCodec_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,V,U (4:2:0) + VideoCodec_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,UV (4:2:0) + VideoCodec_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), // YUYV/YUY2 (4:2:2) + VideoCodec_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')), // UYVY (4:2:2) +}; + +enum +{ + VideoChromaFormat_Monochrome = 0, + VideoChromaFormat_YUV420, + VideoChromaFormat_YUV422, + VideoChromaFormat_YUV444, +}; + +struct InputMediaStream_FFMPEG +{ +public: + bool open(const char* fileName, int* codec, int* chroma_format, int* width, int* height); + void close(); + + bool read(unsigned char** data, int* size, int* endOfFile); + +private: + InputMediaStream_FFMPEG(const InputMediaStream_FFMPEG&); + InputMediaStream_FFMPEG& operator =(const InputMediaStream_FFMPEG&); + + AVFormatContext* ctx_; + int video_stream_id_; + AVPacket pkt_; +}; + +bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height) +{ + int err; + + ctx_ = 0; + video_stream_id_ = -1; + memset(&pkt_, 0, sizeof(AVPacket)); + + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) + avformat_network_init(); + #endif + + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0) + err = avformat_open_input(&ctx_, fileName, 0, 0); + #else + err = av_open_input_file(&ctx_, fileName, 0, 0, 0); + #endif + if (err < 0) + return false; + + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0) + err = avformat_find_stream_info(ctx_, 0); + #else + err = av_find_stream_info(ctx_); + #endif + if (err < 0) + return false; + + for (unsigned int i = 0; i < ctx_->nb_streams; ++i) + { + #if LIBAVFORMAT_BUILD > 4628 + AVCodecContext *enc = ctx_->streams[i]->codec; + #else + AVCodecContext *enc = &ctx_->streams[i]->codec; + #endif + + if (enc->codec_type == AVMEDIA_TYPE_VIDEO) + { + video_stream_id_ = static_cast(i); + + switch (enc->codec_id) + { + case CV_CODEC(CODEC_ID_MPEG1VIDEO): + *codec = ::VideoCodec_MPEG1; + break; + + case CV_CODEC(CODEC_ID_MPEG2VIDEO): + *codec = ::VideoCodec_MPEG2; + break; + + case CV_CODEC(CODEC_ID_MPEG4): + *codec = ::VideoCodec_MPEG4; + break; + + case CV_CODEC(CODEC_ID_VC1): + *codec = ::VideoCodec_VC1; + break; + + case CV_CODEC(CODEC_ID_H264): + *codec = ::VideoCodec_H264; + break; + + default: + return false; + }; + + switch (enc->pix_fmt) + { + case PIX_FMT_YUV420P: + *chroma_format = ::VideoChromaFormat_YUV420; + break; + + case PIX_FMT_YUV422P: + *chroma_format = ::VideoChromaFormat_YUV422; + break; + + case PIX_FMT_YUV444P: + *chroma_format = ::VideoChromaFormat_YUV444; + break; + + default: + return false; + } + + *width = enc->coded_width; + *height = enc->coded_height; + + break; + } + } + + if (video_stream_id_ < 0) + return false; + + av_init_packet(&pkt_); + + return true; +} + +void InputMediaStream_FFMPEG::close() +{ + if (ctx_) + { + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 24, 2) + avformat_close_input(&ctx_); + #else + av_close_input_file(ctx_); + #endif + } + + // free last packet if exist + if (pkt_.data) + av_free_packet(&pkt_); +} + +bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile) +{ + // free last packet if exist + if (pkt_.data) + av_free_packet(&pkt_); + + // get the next frame + for (;;) + { + int ret = av_read_frame(ctx_, &pkt_); + + if (ret == AVERROR(EAGAIN)) + continue; + + if (ret < 0) + { + if (ret == (int)AVERROR_EOF) + *endOfFile = true; + return false; + } + + if (pkt_.stream_index != video_stream_id_) + { + av_free_packet(&pkt_); + continue; + } + + break; + } + + *data = pkt_.data; + *size = pkt_.size; + *endOfFile = false; + + return true; +} + +InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height) +{ + InputMediaStream_FFMPEG* stream = (InputMediaStream_FFMPEG*) malloc(sizeof(InputMediaStream_FFMPEG)); + + if (stream && stream->open(fileName, codec, chroma_format, width, height)) + return stream; + + stream->close(); + free(stream); + + return 0; +} + +void release_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream) +{ + stream->close(); + free(stream); +} + +int read_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile) +{ + return stream->read(data, size, endOfFile); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_giganetix.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_giganetix.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_giganetix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_giganetix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,763 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +// + +// +// The code has been contributed by Vladimir N. Litvinenko on 2012 Jul +// mailto:vladimir.litvinenko@codepaint.ru +// + +#include "precomp.hpp" +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +#define QTGIG_HEARTBEAT_TIME (12000.0) +#define QTGIG_MAX_WAIT_TIME (2.0) +#define QTGIG_IMG_WAIT_TIME (3.0) + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprInitGigEVisionAPI(); + \brief Wrapper to GigEVisionAPI function gige::InitGigEVisionAPI () + \return true -- success + See \a wrprExitGigEVisionAPI + +*/ +bool +wrprInitGigEVisionAPI() +{ + CV_FUNCNAME("wrprInitGigEVisionAPI"); + __BEGIN__; + + try { + gige::InitGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: initialization (InitGigEVisionAPI()) failed.\n"); + } + __END__; + return true; +} + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn void wrprExitGigEVisionAPI() + \brief Wrapper to GigEVisionAPI function gige::ExitGigEVisionAPI () + \return true -- success + See \a wrprInitGigEVisionAPI + +*/ +bool +wrprExitGigEVisionAPI() +{ + CV_FUNCNAME("wrprExitGigEVisionAPI"); + __BEGIN__; + + try { + gige::ExitGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: finalization (ExitGigEVisionAPI()) failed.\n"); + return false; + } + __END__; + return true; +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn gige::IGigEVisionAPI wrprGetGigEVisionAPI() + \brief Wrapper to GigEVisionAPI function gige::GetGigEVisionAPI () + \return item of gige::IGigEVisionAPI type + See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI +*/ +gige::IGigEVisionAPI +wrprGetGigEVisionAPI() +{ + + gige::IGigEVisionAPI b_ret = 0; + + CV_FUNCNAME("wrprGetGigEVisionAPI"); + __BEGIN__; + + try { + b_ret = gige::GetGigEVisionAPI (); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API instance (from GetGigEVisionAPI()) failed.\n"); + } + + __END__; + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler) + \brief Wrapper to GigEVisionAPI function + \param api + \param eventHandler + \return true - succsess, else - false + See \a wrprInitGigEVisionAPI, \a gige::IGigEVisionAPI + +*/ +bool +wrprUnregisterCallback( const gige::IGigEVisionAPI* api, gige::ICallbackEvent* eventHandler) +{ + bool b_ret = api != NULL; + + if(b_ret) b_ret = api->IsValid (); + + CV_FUNCNAME("wrprUnregisterCallback"); + __BEGIN__; + + if(b_ret) + { + if(eventHandler != NULL) + { + try { + b_ret = ((gige::IGigEVisionAPIInterface*)api)->UnregisterCallback (eventHandler); + } catch(...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API unregister callback function (from UnregisterCallback()) failed.\n"); + b_ret = false; + } + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceIsConnect( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::IsConnected() + \param device - selected device + \return true - device connected +*/ +bool +wrprDeviceIsConnect( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceIsConnect"); + __BEGIN__; + + if(b_ret) + { + try { + b_ret = device->IsConnected (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device connection state (from IsConnected()) failed.\n"); + b_ret = false; + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceIsValid( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::Connect() + \param device - selected device + \return true - device valid + +*/ +bool +wrprDeviceIsValid( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceIsConnect"); + __BEGIN__; + + if(b_ret) + { + try { + b_ret = device.IsValid (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device validation state (from IsValid()) failed.\n"); + b_ret = false; + } + } + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/** + \internal + \fn bool wrprDeviceDisconnect ( gige::IDevice& device ) + \brief Wrapper to GigEVisionAPI function IDevice::Disconnect() + \param device - selected device + \return true - device valid + +*/ +bool +wrprDeviceDisconnect ( gige::IDevice& device ) +{ + bool b_ret = device != NULL; + + CV_FUNCNAME("wrprDeviceDisconnect"); + __BEGIN__; + + if(b_ret) + { + try { + device->Disconnect (); + } catch (...) { + CV_ERROR(CV_StsError, "GigEVisionAPI: API device disconnect (from Disconnect()) failed.\n"); + b_ret = false; + } + } + + __END__; + + return (b_ret); +} + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/** + \internal + \class CvCaptureCAM_Giganetix + \brief Capturing video from camera via Smartec Giganetix (use GigEVisualSDK library). +*/ + +class CvCaptureCAM_Giganetix : public CvCapture +{ + public: + CvCaptureCAM_Giganetix(); + virtual ~CvCaptureCAM_Giganetix(); + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() + { + return CV_CAP_GIGANETIX; + } + + bool start (); + bool stop (); + + protected: + + void init (); + void grabImage (); + + gige::IGigEVisionAPI m_api; + bool m_api_on; + gige::IDevice m_device; + bool m_active; + + IplImage* m_raw_image; + UINT32 m_rawImagePixelType; + bool m_monocrome; + +}; +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::init () +{ + m_monocrome = m_active = m_api_on = false; + m_api = 0; + m_device = 0; + m_raw_image = 0; + m_rawImagePixelType = 0; +} + +/*----------------------------------------------------------------------------*/ +CvCaptureCAM_Giganetix::CvCaptureCAM_Giganetix() +{ + init (); + + m_api_on = wrprInitGigEVisionAPI (); + + if(m_api_on) + { + if((m_api = wrprGetGigEVisionAPI ()) != NULL) + { + m_api->SetHeartbeatTime (QTGIG_HEARTBEAT_TIME); + } + } +} + +/*----------------------------------------------------------------------------*/ +CvCaptureCAM_Giganetix::~CvCaptureCAM_Giganetix() +{ + close(); +} +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::close() +{ + stop (); + + (void)wrprDeviceDisconnect(m_device); + + (void)wrprExitGigEVisionAPI (); + + if(m_raw_image) cvReleaseImageHeader(&m_raw_image); + + init (); +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::open( int index ) +{ + bool b_ret = m_api_on; + + CV_FUNCNAME("CvCaptureCAM_Giganetix::open"); + __BEGIN__; + + if(b_ret) + b_ret = m_api.IsValid (); + + if(b_ret ) + { + m_api->FindAllDevices (QTGIG_MAX_WAIT_TIME); + + //TODO - serch device as DevicesList member + gige::DevicesList DevicesList = m_api->GetAllDevices (); + + m_device = 0; + b_ret = false; + + for (int i = 0; i < (int) DevicesList.size() && !b_ret; i++) + { + if((b_ret = i == index)) + { + m_device = DevicesList[i]; + b_ret = m_device->Connect (); + + if(b_ret) + { + b_ret = + m_device->SetStringNodeValue("AcquisitionStatusSelector", "AcquisitionActive") + && + m_device->SetStringNodeValue ("TriggerMode", "Off") + && + m_device->SetStringNodeValue ("AcquisitionMode", "Continuous") + && + m_device->SetIntegerNodeValue ("AcquisitionFrameCount", 20) + ; + } + } + } // for + } + + if(!b_ret) + { + CV_ERROR(CV_StsError, "Giganetix: Error cannot find camera\n"); + close (); + } else { + start (); + } + + __END__; + + return b_ret; +} + +/*----------------------------------------------------------------------------*/ +void +CvCaptureCAM_Giganetix::grabImage () +{ + CV_FUNCNAME("CvCaptureCAM_Giganetix::grabImage"); + __BEGIN__; + + if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device)) + { + if(!m_device->IsBufferEmpty ()) + { + gige::IImageInfo imageInfo; + m_device->GetImageInfo (&imageInfo); + assert(imageInfo.IsValid()); + + if (m_device->GetPendingImagesCount() == 1) + { + UINT32 newPixelType; + UINT32 newWidth, newHeight; + + imageInfo->GetPixelType(newPixelType); + imageInfo->GetSize(newWidth, newHeight); + + //TODO - validation of image exists + bool b_validation = m_raw_image != NULL; + if(b_validation) + { + b_validation = + m_raw_image->imageSize == (int)(imageInfo->GetRawDataSize ()) + && + m_rawImagePixelType == newPixelType; + } else { + if(m_raw_image) cvReleaseImageHeader(&m_raw_image); + } + + m_rawImagePixelType = newPixelType; + m_monocrome = GvspGetBitsPerPixel((GVSP_PIXEL_TYPES)newPixelType) == IPL_DEPTH_8U; + + try { + if (m_monocrome) + { + //TODO - For Mono & Color BayerRGB raw pixel types + if (!b_validation) + { + m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight),IPL_DEPTH_8U,1); + m_raw_image->origin = IPL_ORIGIN_TL; + m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL; + m_raw_image->widthStep = newWidth; + } + // Copy image. + // ::memcpy(m_raw_image->imageData, imageInfo->GetRawData (), imageInfo->GetRawDataSize ()); + + //TODO - Set pointer to image ! + m_raw_image->imageData = (char*)(imageInfo->GetRawData ()); + } + + if (!m_monocrome && newPixelType == GVSP_PIX_RGB8_PACKED) + { + //TODO - 24 bit RGB color image. + if (!b_validation) + { + m_raw_image = cvCreateImageHeader (cvSize((int)newWidth, (int)newHeight), IPL_DEPTH_32F, 3); + m_raw_image->origin = IPL_ORIGIN_TL; + m_raw_image->dataOrder = IPL_DATA_ORDER_PIXEL; + m_raw_image->widthStep = newWidth * 3; + } + m_raw_image->imageData = (char*)(imageInfo->GetRawData ()); + } + } catch (...) { + CV_ERROR(CV_StsError, "Giganetix: failed to queue a buffer on device\n"); + close (); + } + } else { + //TODO - all other pixel types + m_raw_image = 0; + CV_WARN("Giganetix: Undefined image pixel type\n"); + } + m_device->PopImage (imageInfo); + m_device->ClearImageBuffer (); + } + } + + __END__; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::start () +{ + CV_FUNCNAME("CvCaptureCAM_Giganetix::start"); + __BEGIN__; + + m_active = wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device); + + if(m_active) + { + (void)m_device->SetIntegerNodeValue("TLParamsLocked", 1); + (void)m_device->CommandNodeExecute("AcquisitionStart"); + m_active = m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + } + + if(!m_active) + { + CV_ERROR(CV_StsError, "Giganetix: Cannot open camera\n"); + close (); + } + + __END__; + + return m_active; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::stop () +{ + if (!m_active) return true; + + CV_FUNCNAME("CvCaptureCAM_Giganetix::stop"); + __BEGIN__; + + if(wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device)) + { + (void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + + if(m_active) + { + (void)m_device->CommandNodeExecute("AcquisitionStop"); + (void)m_device->SetIntegerNodeValue("TLParamsLocked", 0); + m_device->ClearImageBuffer (); + (void)m_device->GetBooleanNodeValue("AcquisitionStatus", m_active); + } + } + + if(m_active) + { + CV_ERROR(CV_StsError, "Giganetix: Improper closure of the camera\n"); + close (); + } + __END__; + + return !m_active; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::grabFrame() +{ + bool b_ret = + wrprDeviceIsValid(m_device) + && + wrprDeviceIsConnect(m_device); + + if(b_ret) grabImage (); + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +IplImage* +CvCaptureCAM_Giganetix::retrieveFrame(int) +{ + return ( + wrprDeviceIsValid(m_device) && wrprDeviceIsConnect(m_device) ? + m_raw_image : + NULL + ); +} + +/*----------------------------------------------------------------------------*/ +double +CvCaptureCAM_Giganetix::getProperty( int property_id ) +{ + double d_ret = -1.0; + INT64 i; + + if(wrprDeviceIsConnect(m_device)) + { + switch ( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + m_device->GetIntegerNodeValue ("Width", i); + d_ret = i; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + m_device->GetIntegerNodeValue ("Height", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_X: + m_device->GetIntegerNodeValue ("OffsetX", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y: + m_device->GetIntegerNodeValue ("OffsetY", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX: + m_device->GetIntegerNodeValue ("WidthMax", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX: + m_device->GetIntegerNodeValue ("HeightMax", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH: + m_device->GetIntegerNodeValue ("SensorWidth", i); + d_ret = i; + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH: + m_device->GetIntegerNodeValue ("SensorHeight", i); + d_ret = i; + break; + case CV_CAP_PROP_FRAME_COUNT: + m_device->GetIntegerNodeValue ("AcquisitionFrameCount", i); + d_ret = i; + break; + case CV_CAP_PROP_EXPOSURE: + m_device->GetFloatNodeValue ("ExposureTime",d_ret); + break; + case CV_CAP_PROP_GAIN : + m_device->GetFloatNodeValue ("Gain",d_ret); + break; + case CV_CAP_PROP_TRIGGER : + bool b; + m_device->GetBooleanNodeValue ("TriggerMode",b); + d_ret = (double)b; + break; + case CV_CAP_PROP_TRIGGER_DELAY : + m_device->GetFloatNodeValue ("TriggerDelay",d_ret); + break; + default : ; + } + } + + return d_ret; +} + +/*----------------------------------------------------------------------------*/ +bool +CvCaptureCAM_Giganetix::setProperty( int property_id, double value ) +{ + bool b_ret = wrprDeviceIsConnect(m_device); + + if(b_ret) + { + bool b_val = m_active; + + switch ( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("Width", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX: + stop (); + b_ret = m_device->SetIntegerNodeValue ("WidthMax", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("SensorWidth", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_FRAME_HEIGHT: + stop (); + b_ret = m_device->SetIntegerNodeValue ("Height", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX: + stop (); + b_ret = m_device->SetIntegerNodeValue ("HeightMax", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH: + stop (); + b_ret = m_device->SetIntegerNodeValue ("SensorHeight", (INT64)value); + if(b_val) start (); + break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_X: { + INT64 w, wmax, val = (INT64)value; + if((b_ret = m_device->GetIntegerNodeValue ("Width", w))) + if((b_ret = m_device->GetIntegerNodeValue ("WidthMax", wmax))) + b_ret = m_device->SetIntegerNodeValue ("OffsetX", val w > wmax ? wmax - w : val); + } break; + case CV_CAP_PROP_GIGA_FRAME_OFFSET_Y: { + INT64 h, hmax, val = (INT64)value; + if((b_ret = m_device->GetIntegerNodeValue ("Height", h))) + if((b_ret = m_device->GetIntegerNodeValue ("HeightMax", hmax))) + b_ret = m_device->SetIntegerNodeValue ("OffsetY", val h > hmax ? hmax - h : val); + b_ret = m_device->SetIntegerNodeValue ("OffsetY", (INT64)value); + } + break; + case CV_CAP_PROP_EXPOSURE: + b_ret = m_device->SetFloatNodeValue ("ExposureTime",value); + break; + case CV_CAP_PROP_GAIN : + b_ret = m_device->SetFloatNodeValue ("Gain",value); + break; + case CV_CAP_PROP_TRIGGER : + b_ret = m_device->SetBooleanNodeValue ("TriggerMode",(bool)value); + break; + case CV_CAP_PROP_TRIGGER_DELAY : + stop (); + b_ret = m_device->SetFloatNodeValue ("TriggerDelay",value); + if(b_val) start (); + break; + default: + b_ret = false; + } + } + + return b_ret; +} + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +CvCapture* +cvCreateCameraCapture_Giganetix( int index ) +{ + CvCaptureCAM_Giganetix* capture = new CvCaptureCAM_Giganetix; + + if (!(capture->open( index ))) + { + delete capture; + capture = NULL; + } + + return ((CvCapture*)capture); +} + +/*----------------------------------------------------------------------------*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_gstreamer.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_gstreamer.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_gstreamer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_gstreamer.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,777 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2008, 2011, Nils Hasler, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// Author: Nils Hasler +// +// Max-Planck-Institut Informatik +// +// this implementation was inspired by gnash's gstreamer interface + +// +// use GStreamer to read a video +// + +#include "precomp.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +static cv::Mutex gst_initializer_mutex; + +class gst_initializer +{ +public: + static void init() + { + gst_initializer_mutex.lock(); + static gst_initializer init; + gst_initializer_mutex.unlock(); + } +private: + gst_initializer() + { + gst_init(NULL, NULL); + } +}; + +class CvCapture_GStreamer : public CvCapture +{ +public: + CvCapture_GStreamer() { init(); } + virtual ~CvCapture_GStreamer() { close(); } + + virtual bool open( int type, const char* filename ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + +protected: + void init(); + bool reopen(); + void handleMessage(); + void restartPipeline(); + void setFilter(const char*, int, int, int); + void removeFilter(const char *filter); + void static newPad(GstElement *myelement, + GstPad *pad, + gpointer data); + GstElement *pipeline; + GstElement *uridecodebin; + GstElement *color; + GstElement *sink; + + GstBuffer *buffer; + GstCaps *caps; + IplImage *frame; +}; + +void CvCapture_GStreamer::init() +{ + pipeline=0; + frame=0; + buffer=0; + frame=0; + +} + +void CvCapture_GStreamer::handleMessage() +{ + GstBus* bus = gst_element_get_bus(pipeline); + + while(gst_bus_have_pending(bus)) { + GstMessage* msg = gst_bus_pop(bus); + +// printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg)); + + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_STATE_CHANGED: + GstState oldstate, newstate, pendstate; + gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate); +// printf("state changed from %d to %d (%d)\n", oldstate, newstate, pendstate); + break; + case GST_MESSAGE_ERROR: { + GError *err; + gchar *debug; + gst_message_parse_error(msg, &err, &debug); + + fprintf(stderr, "GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n", + gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message); + + g_error_free(err); + g_free(debug); + + gst_element_set_state(pipeline, GST_STATE_NULL); + + break; + } + case GST_MESSAGE_EOS: +// CV_WARN("NetStream has reached the end of the stream."); + + break; + default: +// CV_WARN("unhandled message\n"); + break; + } + + gst_message_unref(msg); + } + + gst_object_unref(GST_OBJECT(bus)); +} + +// +// start the pipeline, grab a buffer, and pause again +// +bool CvCapture_GStreamer::grabFrame() +{ + + if(!pipeline) + return false; + + if(gst_app_sink_is_eos(GST_APP_SINK(sink))) + return false; + + if(buffer) + gst_buffer_unref(buffer); + handleMessage(); + + buffer = gst_app_sink_pull_buffer(GST_APP_SINK(sink)); + if(!buffer) + return false; + + return true; +} + +// +// decode buffer +// +IplImage * CvCapture_GStreamer::retrieveFrame(int) +{ + if(!buffer) + return 0; + + if(!frame) { + gint height, width; + GstCaps *buff_caps = gst_buffer_get_caps(buffer); + assert(gst_caps_get_size(buff_caps) == 1); + GstStructure* structure = gst_caps_get_structure(buff_caps, 0); + + if(!gst_structure_get_int(structure, "width", &width) || + !gst_structure_get_int(structure, "height", &height)) + return 0; + + frame = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 3); + gst_caps_unref(buff_caps); + } + + // no need to memcpy, just use gstreamer's buffer :-) + frame->imageData = (char *)GST_BUFFER_DATA(buffer); + //memcpy (frame->imageData, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE (buffer)); + //gst_buffer_unref(buffer); + //buffer = 0; + return frame; +} + +void CvCapture_GStreamer::restartPipeline() +{ + CV_FUNCNAME("icvRestartPipeline"); + + __BEGIN__; + + printf("restarting pipeline, going to ready\n"); + + if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) == + GST_STATE_CHANGE_FAILURE) { + CV_ERROR(CV_StsError, "GStreamer: unable to start pipeline\n"); + return; + } + + printf("ready, relinking\n"); + + gst_element_unlink(uridecodebin, color); + printf("filtering with %s\n", gst_caps_to_string(caps)); + gst_element_link_filtered(uridecodebin, color, caps); + + printf("relinked, pausing\n"); + + if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + CV_ERROR(CV_StsError, "GStreamer: unable to start pipeline\n"); + return; + } + + printf("state now paused\n"); + + __END__; +} + +void CvCapture_GStreamer::setFilter(const char *property, int type, int v1, int v2) +{ + + if(!caps) { + if(type == G_TYPE_INT) + caps = gst_caps_new_simple("video/x-raw-rgb", property, type, v1, NULL); + else + caps = gst_caps_new_simple("video/x-raw-rgb", property, type, v1, v2, NULL); + } else { + //printf("caps before setting %s\n", gst_caps_to_string(caps)); + if(type == G_TYPE_INT) + gst_caps_set_simple(caps, "video/x-raw-rgb", property, type, v1, NULL); + else + gst_caps_set_simple(caps, "video/x-raw-rgb", property, type, v1, v2, NULL); + } + + restartPipeline(); +} + +void CvCapture_GStreamer::removeFilter(const char *filter) +{ + if(!caps) + return; + + GstStructure *s = gst_caps_get_structure(caps, 0); + gst_structure_remove_field(s, filter); + + restartPipeline(); +} + + +// +// connect uridecodebin dynamically created source pads to colourconverter +// +void CvCapture_GStreamer::newPad(GstElement * /*uridecodebin*/, + GstPad *pad, + gpointer data) +{ + GstPad *sinkpad; + GstElement *color = (GstElement *) data; + + + sinkpad = gst_element_get_static_pad (color, "sink"); + +// printf("linking dynamic pad to colourconverter %p %p\n", uridecodebin, pad); + + gst_pad_link (pad, sinkpad); + + gst_object_unref (sinkpad); +} + +bool CvCapture_GStreamer::open( int type, const char* filename ) +{ + close(); + CV_FUNCNAME("cvCaptureFromCAM_GStreamer"); + + __BEGIN__; + + gst_initializer::init(); + +// if(!isInited) { +// printf("gst_init\n"); +// gst_init (NULL, NULL); + +// gst_debug_set_active(TRUE); +// gst_debug_set_colored(TRUE); +// gst_debug_set_default_threshold(GST_LEVEL_WARNING); + +// isInited = true; +// } + bool stream = false; + bool manualpipeline = false; + char *uri = NULL; + uridecodebin = NULL; + if(type != CV_CAP_GSTREAMER_FILE) { + close(); + return false; + } + + if(!gst_uri_is_valid(filename)) { + uri = realpath(filename, NULL); + stream=false; + if(uri) { + uri = g_filename_to_uri(uri, NULL, NULL); + if(!uri) { + CV_WARN("GStreamer: Error opening file\n"); + close(); + return false; + } + } else { + GError *err = NULL; + //uridecodebin = gst_parse_bin_from_description(filename, FALSE, &err); + uridecodebin = gst_parse_launch(filename, &err); + if(!uridecodebin) { + CV_WARN("GStreamer: Error opening bin\n"); + close(); + return false; + } + stream = true; + manualpipeline = true; + } + } else { + stream = true; + uri = g_strdup(filename); + } + + if(!uridecodebin) { + uridecodebin = gst_element_factory_make ("uridecodebin", NULL); + g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL); + if(!uridecodebin) { + CV_WARN("GStreamer: Failed to create uridecodebin\n"); + close(); + return false; + } + } + + if(manualpipeline) { + GstIterator *it = gst_bin_iterate_sinks(GST_BIN(uridecodebin)); + if(gst_iterator_next(it, (gpointer *)&sink) != GST_ITERATOR_OK) { + CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n"); + return false; + } + + pipeline = uridecodebin; + } else { + pipeline = gst_pipeline_new (NULL); + + color = gst_element_factory_make("ffmpegcolorspace", NULL); + sink = gst_element_factory_make("appsink", NULL); + + gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL); + g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color); + + if(!gst_element_link(color, sink)) { + CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n"); + gst_object_unref(pipeline); + return false; + } + } + + gst_app_sink_set_max_buffers (GST_APP_SINK(sink), 1); + gst_app_sink_set_drop (GST_APP_SINK(sink), stream); + caps = gst_caps_new_simple("video/x-raw-rgb", + "red_mask", G_TYPE_INT, 0x0000FF, + "green_mask", G_TYPE_INT, 0x00FF00, + "blue_mask", G_TYPE_INT, 0xFF0000, + NULL); + gst_app_sink_set_caps(GST_APP_SINK(sink), caps); + gst_caps_unref(caps); + + if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) == + GST_STATE_CHANGE_FAILURE) { + CV_WARN("GStreamer: unable to set pipeline to ready\n"); + gst_object_unref(pipeline); + return false; + } + + if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); + CV_WARN("GStreamer: unable to set pipeline to playing\n"); + gst_object_unref(pipeline); + return false; + } + + + + handleMessage(); + + __END__; + + return true; +} + +// +// +// gstreamer image sequence writer +// +// +class CvVideoWriter_GStreamer : public CvVideoWriter +{ +public: + CvVideoWriter_GStreamer() { init(); } + virtual ~CvVideoWriter_GStreamer() { close(); } + + virtual bool open( const char* filename, int fourcc, + double fps, CvSize frameSize, bool isColor ); + virtual void close(); + virtual bool writeFrame( const IplImage* image ); +protected: + void init(); + std::map encs; + GstElement* source; + GstElement* file; + GstElement* enc; + GstElement* mux; + GstElement* color; + GstBuffer* buffer; + GstElement* pipeline; + int input_pix_fmt; +}; + +void CvVideoWriter_GStreamer::init() +{ + encs[CV_FOURCC('D','R','A','C')]=(char*)"diracenc"; + encs[CV_FOURCC('H','F','Y','U')]=(char*)"ffenc_huffyuv"; + encs[CV_FOURCC('J','P','E','G')]=(char*)"jpegenc"; + encs[CV_FOURCC('M','J','P','G')]=(char*)"jpegenc"; + encs[CV_FOURCC('M','P','1','V')]=(char*)"mpeg2enc"; + encs[CV_FOURCC('M','P','2','V')]=(char*)"mpeg2enc"; + encs[CV_FOURCC('T','H','E','O')]=(char*)"theoraenc"; + encs[CV_FOURCC('V','P','8','0')]=(char*)"vp8enc"; + encs[CV_FOURCC('H','2','6','4')]=(char*)"x264enc"; + encs[CV_FOURCC('X','2','6','4')]=(char*)"x264enc"; + encs[CV_FOURCC('X','V','I','D')]=(char*)"xvidenc"; + encs[CV_FOURCC('F','F','Y','U')]=(char*)"y4menc"; + //encs[CV_FOURCC('H','F','Y','U')]=(char*)"y4menc"; + pipeline=0; + buffer=0; +} +void CvVideoWriter_GStreamer::close() +{ + if (pipeline) { + gst_app_src_end_of_stream(GST_APP_SRC(source)); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (pipeline)); + } +} +bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc, + double fps, CvSize frameSize, bool is_color ) +{ + CV_FUNCNAME("CvVideoWriter_GStreamer::open"); + + __BEGIN__; + //actually doesn't support fourcc parameter and encode an avi with jpegenc + //we need to find a common api between backend to support fourcc for avi + //but also to choose in a common way codec and container format (ogg,dirac,matroska) + // check arguments + + assert (filename); + assert (fps > 0); + assert (frameSize.width > 0 && frameSize.height > 0); + std::map::iterator encit; + encit=encs.find(fourcc); + if (encit==encs.end()) + CV_ERROR( CV_StsUnsupportedFormat,"Gstreamer Opencv backend doesn't support this codec acutally."); +// if(!isInited) { +// gst_init (NULL, NULL); +// isInited = true; +// } + gst_initializer::init(); + close(); + source=gst_element_factory_make("appsrc",NULL); + file=gst_element_factory_make("filesink", NULL); + enc=gst_element_factory_make(encit->second, NULL); + mux=gst_element_factory_make("avimux", NULL); + color = gst_element_factory_make("ffmpegcolorspace", NULL); + if (!enc) + CV_ERROR( CV_StsUnsupportedFormat, "Your version of Gstreamer doesn't support this codec acutally or needed plugin missing."); + g_object_set(G_OBJECT(file), "location", filename, NULL); + pipeline = gst_pipeline_new (NULL); + GstCaps* caps; + if (is_color) { + input_pix_fmt=1; + caps= gst_video_format_new_caps(GST_VIDEO_FORMAT_BGR, + frameSize.width, + frameSize.height, + (int) (fps * 1000), + 1000, + 1, + 1); + } + else { + input_pix_fmt=0; + caps= gst_caps_new_simple("video/x-raw-gray", + "width", G_TYPE_INT, frameSize.width, + "height", G_TYPE_INT, frameSize.height, + "framerate", GST_TYPE_FRACTION, int(fps),1, + "bpp",G_TYPE_INT,8, + "depth",G_TYPE_INT,8, + NULL); + } + gst_app_src_set_caps(GST_APP_SRC(source), caps); + if (fourcc==CV_FOURCC_DEFAULT) { + gst_bin_add_many(GST_BIN(pipeline), source, color,mux, file, NULL); + if(!gst_element_link_many(source,color,enc,mux,file,NULL)) { + CV_ERROR(CV_StsError, "GStreamer: cannot link elements\n"); + } + } + else { + gst_bin_add_many(GST_BIN(pipeline), source, color,enc,mux, file, NULL); + if(!gst_element_link_many(source,color,enc,mux,file,NULL)) { + CV_ERROR(CV_StsError, "GStreamer: cannot link elements\n"); + } + } + + + if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + CV_ERROR(CV_StsError, "GStreamer: cannot put pipeline to play\n"); + } + __END__; + return true; +} +bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image ) +{ + + CV_FUNCNAME("CvVideoWriter_GStreamer::writerFrame"); + + __BEGIN__; + if (input_pix_fmt == 1) { + if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U) { + CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3."); + } + } + else if (input_pix_fmt == 0) { + if (image->nChannels != 1 || image->depth != IPL_DEPTH_8U) { + CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1."); + } + } + else { + assert(false); + } + int size; + size = image->imageSize; + buffer = gst_buffer_new_and_alloc (size); + //gst_buffer_set_data (buffer,(guint8*)image->imageData, size); + memcpy (GST_BUFFER_DATA(buffer),image->imageData, size); + gst_app_src_push_buffer(GST_APP_SRC(source),buffer); + //gst_buffer_unref(buffer); + //buffer = 0; + __END__; + return true; +} +CvVideoWriter* cvCreateVideoWriter_GStreamer(const char* filename, int fourcc, double fps, + CvSize frameSize, int isColor ) +{ + CvVideoWriter_GStreamer* wrt = new CvVideoWriter_GStreamer; + if( wrt->open(filename, fourcc, fps,frameSize, isColor)) + return wrt; + + delete wrt; + return 0; +} + +void CvCapture_GStreamer::close() +{ + if(pipeline) { + gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); + gst_object_unref(GST_OBJECT(pipeline)); + } + if(buffer) + gst_buffer_unref(buffer); + if(frame) { + frame->imageData = 0; + cvReleaseImage(&frame); + } +} + +double CvCapture_GStreamer::getProperty( int propId ) +{ + GstFormat format; + //GstQuery q; + gint64 value; + + if(!pipeline) { + CV_WARN("GStreamer: no pipeline"); + return false; + } + + switch(propId) { + case CV_CAP_PROP_POS_MSEC: + format = GST_FORMAT_TIME; + if(!gst_element_query_position(sink, &format, &value)) { + CV_WARN("GStreamer: unable to query position of stream"); + return false; + } + return value * 1e-6; // nano seconds to milli seconds + case CV_CAP_PROP_POS_FRAMES: + format = GST_FORMAT_DEFAULT; + if(!gst_element_query_position(sink, &format, &value)) { + CV_WARN("GStreamer: unable to query position of stream"); + return false; + } + return value; + case CV_CAP_PROP_POS_AVI_RATIO: + format = GST_FORMAT_PERCENT; + if(!gst_element_query_position(pipeline, &format, &value)) { + CV_WARN("GStreamer: unable to query position of stream"); + return false; + } + return ((double) value) / GST_FORMAT_PERCENT_MAX; + case CV_CAP_PROP_FRAME_WIDTH: + case CV_CAP_PROP_FRAME_HEIGHT: + case CV_CAP_PROP_FPS: + case CV_CAP_PROP_FOURCC: + break; + case CV_CAP_PROP_FRAME_COUNT: + format = GST_FORMAT_DEFAULT; + if(!gst_element_query_duration(pipeline, &format, &value)) { + CV_WARN("GStreamer: unable to query position of stream"); + return false; + } + return value; + case CV_CAP_PROP_FORMAT: + case CV_CAP_PROP_MODE: + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_GAIN: + case CV_CAP_PROP_CONVERT_RGB: + break; + case CV_CAP_GSTREAMER_QUEUE_LENGTH: + if(!sink) { + CV_WARN("GStreamer: there is no sink yet"); + return false; + } + return gst_app_sink_get_max_buffers(GST_APP_SINK(sink)); + default: + CV_WARN("GStreamer: unhandled property"); + break; + } + return false; +} + +bool CvCapture_GStreamer::setProperty( int propId, double value ) +{ + GstFormat format; + GstSeekFlags flags; + + if(!pipeline) { + CV_WARN("GStreamer: no pipeline"); + return false; + } + + switch(propId) { + case CV_CAP_PROP_POS_MSEC: + format = GST_FORMAT_TIME; + flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE); + if(!gst_element_seek_simple(GST_ELEMENT(pipeline), format, + flags, (gint64) (value * GST_MSECOND))) { + CV_WARN("GStreamer: unable to seek"); + } + break; + case CV_CAP_PROP_POS_FRAMES: + format = GST_FORMAT_DEFAULT; + flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE); + if(!gst_element_seek_simple(GST_ELEMENT(pipeline), format, + flags, (gint64) value)) { + CV_WARN("GStreamer: unable to seek"); + } + break; + case CV_CAP_PROP_POS_AVI_RATIO: + format = GST_FORMAT_PERCENT; + flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE); + if(!gst_element_seek_simple(GST_ELEMENT(pipeline), format, + flags, (gint64) (value * GST_FORMAT_PERCENT_MAX))) { + CV_WARN("GStreamer: unable to seek"); + } + break; + case CV_CAP_PROP_FRAME_WIDTH: + if(value > 0) + setFilter("width", G_TYPE_INT, (int) value, 0); + else + removeFilter("width"); + break; + case CV_CAP_PROP_FRAME_HEIGHT: + if(value > 0) + setFilter("height", G_TYPE_INT, (int) value, 0); + else + removeFilter("height"); + break; + case CV_CAP_PROP_FPS: + if(value > 0) { + int num, denom; + num = (int) value; + if(value != num) { // FIXME this supports only fractions x/1 and x/2 + num = (int) (value * 2); + denom = 2; + } else + denom = 1; + + setFilter("framerate", GST_TYPE_FRACTION, num, denom); + } else + removeFilter("framerate"); + break; + case CV_CAP_PROP_FOURCC: + case CV_CAP_PROP_FRAME_COUNT: + case CV_CAP_PROP_FORMAT: + case CV_CAP_PROP_MODE: + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_GAIN: + case CV_CAP_PROP_CONVERT_RGB: + break; + case CV_CAP_GSTREAMER_QUEUE_LENGTH: + if(!sink) + break; + gst_app_sink_set_max_buffers(GST_APP_SINK(sink), (guint) value); + break; + default: + CV_WARN("GStreamer: unhandled property"); + } + return false; +} +CvCapture* cvCreateCapture_GStreamer(int type, const char* filename ) +{ + CvCapture_GStreamer* capture = new CvCapture_GStreamer; + + if( capture->open( type, filename )) + return capture; + + delete capture; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_images.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_images.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_images.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_images.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,364 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2008, Nils Hasler, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// Author: Nils Hasler +// +// Max-Planck-Institut Informatik + +// +// capture video from a sequence of images +// the filename when opening can either be a printf pattern such as +// video%04d.png or the first frame of the sequence i.e. video0001.png +// + +#include "precomp.hpp" +#include + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +#ifndef _MAX_PATH +#define _MAX_PATH 1024 +#endif + +class CvCapture_Images : public CvCapture +{ +public: + CvCapture_Images() + { + filename = 0; + currentframe = firstframe = 0; + length = 0; + frame = 0; + } + + virtual ~CvCapture_Images() + { + close(); + } + + virtual bool open(const char* _filename); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + +protected: + char* filename; // actually a printf-pattern + unsigned currentframe; + unsigned firstframe; // number of first frame + unsigned length; // length of sequence + + IplImage* frame; +}; + + +void CvCapture_Images::close() +{ + if( filename ) + { + free(filename); + filename = 0; + } + currentframe = firstframe = 0; + length = 0; + cvReleaseImage( &frame ); +} + + +bool CvCapture_Images::grabFrame() +{ + char str[_MAX_PATH]; + sprintf(str, filename, firstframe + currentframe); + + cvReleaseImage(&frame); + frame = cvLoadImage(str, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); + if( frame ) + currentframe++; + + return frame != 0; +} + +IplImage* CvCapture_Images::retrieveFrame(int) +{ + return frame; +} + +double CvCapture_Images::getProperty(int id) +{ + switch(id) + { + case CV_CAP_PROP_POS_MSEC: + CV_WARN("collections of images don't have framerates\n"); + return 0; + case CV_CAP_PROP_POS_FRAMES: + return currentframe; + case CV_CAP_PROP_POS_AVI_RATIO: + return (double)currentframe / (double)(length - 1); + case CV_CAP_PROP_FRAME_WIDTH: + return frame ? frame->width : 0; + case CV_CAP_PROP_FRAME_HEIGHT: + return frame ? frame->height : 0; + case CV_CAP_PROP_FPS: + CV_WARN("collections of images don't have framerates\n"); + return 1; + case CV_CAP_PROP_FOURCC: + CV_WARN("collections of images don't have 4-character codes\n"); + return 0; + } + return 0; +} + +bool CvCapture_Images::setProperty(int id, double value) +{ + switch(id) + { + case CV_CAP_PROP_POS_MSEC: + case CV_CAP_PROP_POS_FRAMES: + if(value < 0) { + CV_WARN("seeking to negative positions does not work - clamping\n"); + value = 0; + } + if(value >= length) { + CV_WARN("seeking beyond end of sequence - clamping\n"); + value = length - 1; + } + currentframe = cvRound(value); + return true; + case CV_CAP_PROP_POS_AVI_RATIO: + if(value > 1) { + CV_WARN("seeking beyond end of sequence - clamping\n"); + value = 1; + } else if(value < 0) { + CV_WARN("seeking to negative positions does not work - clamping\n"); + value = 0; + } + currentframe = cvRound((length - 1) * value); + return true; + } + CV_WARN("unknown/unhandled property\n"); + return false; +} + +static char* icvExtractPattern(const char *filename, unsigned *offset) +{ + char *name = (char *)filename; + + if( !filename ) + return 0; + + // check whether this is a valid image sequence filename + char *at = strchr(name, '%'); + if(at) + { + int dummy; + if(sscanf(at + 1, "%ud", &dummy) != 1) + return 0; + name = strdup(filename); + } + else // no pattern filename was given - extract the pattern + { + for(at = name; *at && !isdigit(*at); at++) + ; + + if(!at) + return 0; + + sscanf(at, "%u", offset); + + int size = (int)strlen(filename) + 20; + name = (char *)malloc(size); + strncpy(name, filename, at - filename); + name[at - filename] = 0; + + strcat(name, "%0"); + + int i; + char *extension; + for(i = 0, extension = at; isdigit(at[i]); i++, extension++) + ; + char places[10]; + sprintf(places, "%dd", i); + + strcat(name, places); + strcat(name, extension); + } + + return name; +} + + +bool CvCapture_Images::open(const char * _filename) +{ + unsigned offset = 0; + close(); + + filename = icvExtractPattern(_filename, &offset); + if(!filename) + return false; + + // determine the length of the sequence + length = 0; + char str[_MAX_PATH]; + for(;;) + { + sprintf(str, filename, offset + length); + struct stat s; + if(stat(str, &s)) + { + if(length == 0 && offset == 0) // allow starting with 0 or 1 + { + offset++; + continue; + } + } + + if(!cvHaveImageReader(str)) + break; + + length++; + } + + if(length == 0) + { + close(); + return false; + } + + firstframe = offset; + return true; +} + + +CvCapture* cvCreateFileCapture_Images(const char * filename) +{ + CvCapture_Images* capture = new CvCapture_Images; + + if( capture->open(filename) ) + return capture; + + delete capture; + return 0; +} + +// +// +// image sequence writer +// +// +class CvVideoWriter_Images : public CvVideoWriter +{ +public: + CvVideoWriter_Images() + { + filename = 0; + currentframe = 0; + } + virtual ~CvVideoWriter_Images() { close(); } + + virtual bool open( const char* _filename ); + virtual void close(); + virtual bool writeFrame( const IplImage* ); + +protected: + char* filename; + unsigned currentframe; +}; + +bool CvVideoWriter_Images::writeFrame( const IplImage* image ) +{ + char str[_MAX_PATH]; + sprintf(str, filename, currentframe); + int ret = cvSaveImage(str, image); + + currentframe++; + + return ret > 0; +} + +void CvVideoWriter_Images::close() +{ + if( filename ) + { + free( filename ); + filename = 0; + } + currentframe = 0; +} + + +bool CvVideoWriter_Images::open( const char* _filename ) +{ + unsigned offset = 0; + + close(); + + filename = icvExtractPattern(_filename, &offset); + if(!filename) + return false; + + char str[_MAX_PATH]; + sprintf(str, filename, 0); + if(!cvHaveImageWriter(str)) + { + close(); + return false; + } + + currentframe = offset; + return true; +} + + +CvVideoWriter* cvCreateVideoWriter_Images( const char* filename ) +{ + CvVideoWriter_Images *writer = new CvVideoWriter_Images; + + if( writer->open( filename )) + return writer; + + delete writer; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_abstract_camera.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_abstract_camera.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_abstract_camera.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_abstract_camera.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,408 @@ +/* + * cap_ios_abstract_camera.mm + * For iOS video I/O + * by Eduard Feicho on 29/07/12 + * Copyright 2012. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#import "opencv2/highgui/cap_ios.h" +#include "precomp.hpp" + +#pragma mark - Private Interface + +@interface CvAbstractCamera () + +@property (nonatomic, retain) AVCaptureVideoPreviewLayer* captureVideoPreviewLayer; + +- (void)deviceOrientationDidChange:(NSNotification*)notification; +- (void)startCaptureSession; + +- (void)setDesiredCameraPosition:(AVCaptureDevicePosition)desiredPosition; + +- (void)updateSize; + +@end + + +#pragma mark - Implementation + + +@implementation CvAbstractCamera + + + +#pragma mark Public + +@synthesize imageWidth; +@synthesize imageHeight; + + +@synthesize defaultFPS; +@synthesize defaultAVCaptureDevicePosition; +@synthesize defaultAVCaptureVideoOrientation; +@synthesize defaultAVCaptureSessionPreset; + + + +@synthesize captureSession; +@synthesize captureVideoPreviewLayer; +@synthesize videoCaptureConnection; +@synthesize running; +@synthesize captureSessionLoaded; +@synthesize useAVCaptureVideoPreviewLayer; + +@synthesize parentView; + +#pragma mark - Constructors + +- (id)init; +{ + self = [super init]; + if (self) { + // react to device orientation notifications + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(deviceOrientationDidChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + currentDeviceOrientation = [[UIDevice currentDevice] orientation]; + + + // check if camera available + cameraAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]; + NSLog(@"camera available: %@", (cameraAvailable == YES ? @"YES" : @"NO") ); + + running = NO; + + // set camera default configuration + self.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront; + self.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationLandscapeLeft; + self.defaultFPS = 15; + self.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288; + + self.parentView = nil; + self.useAVCaptureVideoPreviewLayer = NO; + } + return self; +} + + + +- (id)initWithParentView:(UIView*)parent; +{ + self = [super init]; + if (self) { + // react to device orientation notifications + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(deviceOrientationDidChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + currentDeviceOrientation = [[UIDevice currentDevice] orientation]; + + + // check if camera available + cameraAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]; + NSLog(@"camera available: %@", (cameraAvailable == YES ? @"YES" : @"NO") ); + + running = NO; + + // set camera default configuration + self.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront; + self.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationLandscapeLeft; + self.defaultFPS = 15; + self.defaultAVCaptureSessionPreset = AVCaptureSessionPreset640x480; + + self.parentView = parent; + self.useAVCaptureVideoPreviewLayer = YES; + } + return self; +} + + + +- (void)dealloc; +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; +} + + +#pragma mark - Public interface + + +- (void)start; +{ + if (![NSThread isMainThread]) { + NSLog(@"[Camera] Warning: Call start only from main thread"); + [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; + return; + } + + if (running == YES) { + return; + } + running = YES; + + // TOOD update image size data before actually starting (needed for recording) + [self updateSize]; + + if (cameraAvailable) { + [self startCaptureSession]; + } +} + + +- (void)pause; +{ + running = NO; + [self.captureSession stopRunning]; +} + + + +- (void)stop; +{ + running = NO; + + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + + [self.captureSession stopRunning]; + self.captureSession = nil; + self.captureVideoPreviewLayer = nil; + self.videoCaptureConnection = nil; + captureSessionLoaded = NO; +} + + + +// use front/back camera +- (void)switchCameras; +{ + BOOL was_running = self.running; + if (was_running) { + [self stop]; + } + if (self.defaultAVCaptureDevicePosition == AVCaptureDevicePositionFront) { + self.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack; + } else { + self.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront; + } + if (was_running) { + [self start]; + } +} + + + +#pragma mark - Device Orientation Changes + + +- (void)deviceOrientationDidChange:(NSNotification*)notification +{ + UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; + + switch (orientation) + { + case UIDeviceOrientationPortrait: + case UIDeviceOrientationPortraitUpsideDown: + case UIDeviceOrientationLandscapeLeft: + case UIDeviceOrientationLandscapeRight: + currentDeviceOrientation = orientation; + break; + + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + default: + break; + } + NSLog(@"deviceOrientationDidChange: %d", orientation); + + [self updateOrientation]; +} + + + +#pragma mark - Private Interface + +- (void)createCaptureSession; +{ + // set a av capture session preset + self.captureSession = [[AVCaptureSession alloc] init]; + if ([self.captureSession canSetSessionPreset:self.defaultAVCaptureSessionPreset]) { + [self.captureSession setSessionPreset:self.defaultAVCaptureSessionPreset]; + } else if ([self.captureSession canSetSessionPreset:AVCaptureSessionPresetLow]) { + [self.captureSession setSessionPreset:AVCaptureSessionPresetLow]; + } else { + NSLog(@"[Camera] Error: could not set session preset"); + } +} + +- (void)createCaptureDevice; +{ + // setup the device + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + [self setDesiredCameraPosition:self.defaultAVCaptureDevicePosition]; + NSLog(@"[Camera] device connected? %@", device.connected ? @"YES" : @"NO"); + NSLog(@"[Camera] device position %@", (device.position == AVCaptureDevicePositionBack) ? @"back" : @"front"); +} + + +- (void)createVideoPreviewLayer; +{ + self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; + + if ([self.captureVideoPreviewLayer isOrientationSupported]) { + [self.captureVideoPreviewLayer setOrientation:self.defaultAVCaptureVideoOrientation]; + } + + if (parentView != nil) { + self.captureVideoPreviewLayer.frame = self.parentView.bounds; + self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; + [self.parentView.layer addSublayer:self.captureVideoPreviewLayer]; + } + NSLog(@"[Camera] created AVCaptureVideoPreviewLayer"); +} + + + + +- (void)setDesiredCameraPosition:(AVCaptureDevicePosition)desiredPosition; +{ + for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { + if ([device position] == desiredPosition) { + [self.captureSession beginConfiguration]; + + NSError* error; + AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; + if (!input) { + NSLog(@"error creating input %@", [error localizedDescription]); + } + + // support for autofocus + if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.focusMode = AVCaptureFocusModeContinuousAutoFocus; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for autofocos configuration %@", [error localizedDescription]); + } + } + [self.captureSession addInput:input]; + + for (AVCaptureInput *oldInput in self.captureSession.inputs) { + [self.captureSession removeInput:oldInput]; + } + [self.captureSession addInput:input]; + [self.captureSession commitConfiguration]; + + break; + } + } +} + + + +- (void)startCaptureSession +{ + if (!cameraAvailable) { + return; + } + + if (self.captureSessionLoaded == NO) { + [self createCaptureSession]; + [self createCaptureDevice]; + [self createCaptureOutput]; + + // setup preview layer + if (self.useAVCaptureVideoPreviewLayer) { + [self createVideoPreviewLayer]; + } else { + [self createCustomVideoPreview]; + } + + captureSessionLoaded = YES; + } + + [self.captureSession startRunning]; +} + + +- (void)createCaptureOutput; +{ + [NSException raise:NSInternalInconsistencyException + format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]; +} + +- (void)createCustomVideoPreview; +{ + [NSException raise:NSInternalInconsistencyException + format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]; +} + +- (void)updateOrientation; +{ + // nothing to do here +} + + +- (void)updateSize; +{ + if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPresetPhoto]) { + //TODO: find the correct resolution + self.imageWidth = 640; + self.imageHeight = 480; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPresetHigh]) { + //TODO: find the correct resolution + self.imageWidth = 640; + self.imageHeight = 480; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPresetMedium]) { + //TODO: find the correct resolution + self.imageWidth = 640; + self.imageHeight = 480; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPresetLow]) { + //TODO: find the correct resolution + self.imageWidth = 640; + self.imageHeight = 480; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPreset352x288]) { + self.imageWidth = 352; + self.imageHeight = 288; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPreset640x480]) { + self.imageWidth = 640; + self.imageHeight = 480; + } else if ([self.defaultAVCaptureSessionPreset isEqualToString:AVCaptureSessionPreset1280x720]) { + self.imageWidth = 1280; + self.imageHeight = 720; + } else { + self.imageWidth = 640; + self.imageHeight = 480; + } +} + +@end diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_photo_camera.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_photo_camera.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_photo_camera.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_photo_camera.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,165 @@ +/* + * cap_ios_photo_camera.mm + * For iOS video I/O + * by Eduard Feicho on 29/07/12 + * Copyright 2012. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#import "opencv2/highgui/cap_ios.h" +#include "precomp.hpp" + +#pragma mark - Private Interface + + +@interface CvPhotoCamera () + +@property (nonatomic, retain) AVCaptureStillImageOutput* stillImageOutput; + +@end + + + +#pragma mark - Implementation + + +@implementation CvPhotoCamera + + + +#pragma mark Public + +@synthesize stillImageOutput; +@synthesize delegate; + + +#pragma mark - Public interface + + +- (void)takePicture +{ + if (cameraAvailable == NO) { + return; + } + cameraAvailable = NO; + + + [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.videoCaptureConnection + completionHandler: + ^(CMSampleBufferRef imageSampleBuffer, NSError *error) + { + if (error == nil && imageSampleBuffer != NULL) + { + // TODO check + // NSNumber* imageOrientation = [UIImage cgImageOrientationForUIDeviceOrientation:currentDeviceOrientation]; + // CMSetAttachment(imageSampleBuffer, kCGImagePropertyOrientation, imageOrientation, 1); + + NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self.captureSession stopRunning]; + + // Make sure we create objects on the main thread in the main context + UIImage* newImage = [UIImage imageWithData:jpegData]; + + //UIImageOrientation orientation = [newImage imageOrientation]; + + // TODO: only apply rotation, don't scale, since we can set this directly in the camera + /* + switch (orientation) { + case UIImageOrientationUp: + case UIImageOrientationDown: + newImage = [newImage imageWithAppliedRotationAndMaxSize:CGSizeMake(640.0, 480.0)]; + break; + case UIImageOrientationLeft: + case UIImageOrientationRight: + newImage = [newImage imageWithMaxSize:CGSizeMake(640.0, 480.0)]; + default: + break; + } + */ + + // We have captured the image, we can allow the user to take another picture + cameraAvailable = YES; + + NSLog(@"CvPhotoCamera captured image"); + if (self.delegate) { + [self.delegate photoCamera:self capturedImage:newImage]; + } + + [self.captureSession startRunning]; + }); + } + }]; + + +} + +- (void)stop; +{ + [super stop]; + self.stillImageOutput = nil; +} + + +#pragma mark - Private Interface + + +- (void)createStillImageOutput; +{ + // setup still image output with jpeg codec + self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; + NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil]; + [self.stillImageOutput setOutputSettings:outputSettings]; + [self.captureSession addOutput:self.stillImageOutput]; + + for (AVCaptureConnection *connection in self.stillImageOutput.connections) { + for (AVCaptureInputPort *port in [connection inputPorts]) { + if ([port.mediaType isEqual:AVMediaTypeVideo]) { + self.videoCaptureConnection = connection; + break; + } + } + if (self.videoCaptureConnection) { + break; + } + } + NSLog(@"[Camera] still image output created"); +} + + +- (void)createCaptureOutput; +{ + [self createStillImageOutput]; +} + +- (void)createCustomVideoPreview; +{ + //do nothing, always use AVCaptureVideoPreviewLayer +} + + +@end diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_video_camera.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_video_camera.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ios_video_camera.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ios_video_camera.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,585 @@ +/* + * cap_ios_video_camera.mm + * For iOS video I/O + * by Eduard Feicho on 29/07/12 + * Copyright 2012. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "opencv2/highgui/cap_ios.h" +#include "precomp.hpp" + +#import + + +static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; + +#pragma mark - Private Interface + + + + +@interface CvVideoCamera () + +- (void)createVideoDataOutput; +- (void)createVideoFileOutput; + + +@property (nonatomic, retain) CALayer *customPreviewLayer; +@property (nonatomic, retain) AVCaptureVideoDataOutput *videoDataOutput; + +@end + + + +#pragma mark - Implementation + + + +@implementation CvVideoCamera + + + + +@synthesize delegate; +@synthesize grayscaleMode; + +@synthesize customPreviewLayer; +@synthesize videoDataOutput; + +@synthesize recordVideo; +//@synthesize videoFileOutput; +@synthesize recordAssetWriterInput; +@synthesize recordPixelBufferAdaptor; +@synthesize recordAssetWriter; + + + +#pragma mark - Constructors + +- (id)initWithParentView:(UIView*)parent; +{ + self = [super initWithParentView:parent]; + if (self) { + self.useAVCaptureVideoPreviewLayer = NO; + self.recordVideo = NO; + } + return self; +} + + + +#pragma mark - Public interface + + +- (void)start; +{ + [super start]; + + if (self.recordVideo == YES) { + NSError* error; + if ([[NSFileManager defaultManager] fileExistsAtPath:[self videoFileString]]) { + [[NSFileManager defaultManager] removeItemAtPath:[self videoFileString] error:&error]; + } + if (error == nil) { + NSLog(@"[Camera] Delete file %@", [self videoFileString]); + } + } +} + + + +- (void)stop; +{ + [super stop]; + + self.videoDataOutput = nil; + if (videoDataOutputQueue) { + dispatch_release(videoDataOutputQueue); + } + + if (self.recordVideo == YES) { + + if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { + [self.recordAssetWriter finishWriting]; + NSLog(@"[Camera] recording stopped"); + } else { + NSLog(@"[Camera] Recording Error: asset writer status is not writing"); + } + + self.recordAssetWriter = nil; + self.recordAssetWriterInput = nil; + self.recordPixelBufferAdaptor = nil; + } + + [self.customPreviewLayer removeFromSuperlayer]; + self.customPreviewLayer = nil; +} + +// TODO fix +- (void)adjustLayoutToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; +{ + + NSLog(@"layout preview layer"); + if (self.parentView != nil) { + + CALayer* layer = self.customPreviewLayer; + CGRect bounds = self.customPreviewLayer.bounds; + int rotation_angle = 0; + bool flip_bounds = false; + + switch (interfaceOrientation) { + case UIInterfaceOrientationPortrait: + NSLog(@"to Portrait"); + rotation_angle = 270; + break; + case UIInterfaceOrientationPortraitUpsideDown: + rotation_angle = 90; + NSLog(@"to UpsideDown"); + break; + case UIInterfaceOrientationLandscapeLeft: + rotation_angle = 0; + NSLog(@"to LandscapeLeft"); + break; + case UIInterfaceOrientationLandscapeRight: + rotation_angle = 180; + NSLog(@"to LandscapeRight"); + break; + default: + break; // leave the layer in its last known orientation + } + + switch (defaultAVCaptureVideoOrientation) { + case AVCaptureVideoOrientationLandscapeRight: + rotation_angle += 180; + break; + case AVCaptureVideoOrientationPortraitUpsideDown: + rotation_angle += 270; + break; + case AVCaptureVideoOrientationPortrait: + rotation_angle += 90; + case AVCaptureVideoOrientationLandscapeLeft: + break; + default: + break; + } + rotation_angle = rotation_angle % 360; + + if (rotation_angle == 90 || rotation_angle == 270) { + flip_bounds = true; + } + + if (flip_bounds) { + NSLog(@"flip bounds"); + bounds = CGRectMake(0, 0, bounds.size.height, bounds.size.width); + } + + layer.position = CGPointMake(self.parentView.frame.size.width/2., self.parentView.frame.size.height/2.); + self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height); + + layer.affineTransform = CGAffineTransformMakeRotation( DegreesToRadians(rotation_angle) ); + layer.bounds = bounds; + } + +} + +// TODO fix +- (void)layoutPreviewLayer; +{ + NSLog(@"layout preview layer"); + if (self.parentView != nil) { + + CALayer* layer = self.customPreviewLayer; + CGRect bounds = self.customPreviewLayer.bounds; + int rotation_angle = 0; + bool flip_bounds = false; + + switch (currentDeviceOrientation) { + case UIDeviceOrientationPortrait: + rotation_angle = 270; + break; + case UIDeviceOrientationPortraitUpsideDown: + rotation_angle = 90; + break; + case UIDeviceOrientationLandscapeLeft: + NSLog(@"left"); + rotation_angle = 180; + break; + case UIDeviceOrientationLandscapeRight: + NSLog(@"right"); + rotation_angle = 0; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + default: + break; // leave the layer in its last known orientation + } + + switch (defaultAVCaptureVideoOrientation) { + case AVCaptureVideoOrientationLandscapeRight: + rotation_angle += 180; + break; + case AVCaptureVideoOrientationPortraitUpsideDown: + rotation_angle += 270; + break; + case AVCaptureVideoOrientationPortrait: + rotation_angle += 90; + case AVCaptureVideoOrientationLandscapeLeft: + break; + default: + break; + } + rotation_angle = rotation_angle % 360; + + if (rotation_angle == 90 || rotation_angle == 270) { + flip_bounds = true; + } + + if (flip_bounds) { + NSLog(@"flip bounds"); + bounds = CGRectMake(0, 0, bounds.size.height, bounds.size.width); + } + + layer.position = CGPointMake(self.parentView.frame.size.width/2., self.parentView.frame.size.height/2.); + layer.affineTransform = CGAffineTransformMakeRotation( DegreesToRadians(rotation_angle) ); + layer.bounds = bounds; + } + +} + + + + +#pragma mark - Private Interface + + + +- (void)createVideoDataOutput; +{ + // Make a video data output + self.videoDataOutput = [AVCaptureVideoDataOutput new]; + + // In grayscale mode we want YUV (YpCbCr 4:2:0) so we can directly access the graylevel intensity values (Y component) + // In color mode we, BGRA format is used + OSType format = self.grayscaleMode ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_32BGRA; + + self.videoDataOutput.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:format] + forKey:(id)kCVPixelBufferPixelFormatTypeKey]; + + // discard if the data output queue is blocked (as we process the still image) + [self.videoDataOutput setAlwaysDiscardsLateVideoFrames:YES]; + + if ( [self.captureSession canAddOutput:self.videoDataOutput] ) { + [self.captureSession addOutput:self.videoDataOutput]; + } + [[self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo] setEnabled:YES]; + + + // set default FPS + if ([self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].supportsVideoMinFrameDuration) { + [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].videoMinFrameDuration = CMTimeMake(1, self.defaultFPS); + } + if ([self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].supportsVideoMaxFrameDuration) { + [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].videoMaxFrameDuration = CMTimeMake(1, self.defaultFPS); + } + + // set video mirroring for front camera (more intuitive) + if ([self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].supportsVideoMirroring) { + if (self.defaultAVCaptureDevicePosition == AVCaptureDevicePositionFront) { + [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].videoMirrored = YES; + } else { + [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].videoMirrored = NO; + } + } + + // set default video orientation + if ([self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].supportsVideoOrientation) { + [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo].videoOrientation = self.defaultAVCaptureVideoOrientation; + } + + + // create a custom preview layer + self.customPreviewLayer = [CALayer layer]; + self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height); + [self layoutPreviewLayer]; + + // create a serial dispatch queue used for the sample buffer delegate as well as when a still image is captured + // a serial dispatch queue must be used to guarantee that video frames will be delivered in order + // see the header doc for setSampleBufferDelegate:queue: for more information + videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL); + [self.videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue]; + + + NSLog(@"[Camera] created AVCaptureVideoDataOutput at %d FPS", self.defaultFPS); +} + + + +- (void)createVideoFileOutput; +{ + /* Video File Output in H.264, via AVAsserWriter */ + NSLog(@"Create Video with dimensions %dx%d", self.imageWidth, self.imageHeight); + + NSDictionary *outputSettings + = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:self.imageWidth], AVVideoWidthKey, + [NSNumber numberWithInt:self.imageHeight], AVVideoHeightKey, + AVVideoCodecH264, AVVideoCodecKey, + nil + ]; + + + self.recordAssetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings]; + + + int pixelBufferFormat = (self.grayscaleMode == YES) ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_32BGRA; + + self.recordPixelBufferAdaptor = + [[AVAssetWriterInputPixelBufferAdaptor alloc] + initWithAssetWriterInput:self.recordAssetWriterInput + sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:pixelBufferFormat], kCVPixelBufferPixelFormatTypeKey, nil]]; + + NSError* error = nil; + NSLog(@"Create AVAssetWriter with url: %@", [self videoFileURL]); + self.recordAssetWriter = [AVAssetWriter assetWriterWithURL:[self videoFileURL] + fileType:AVFileTypeMPEG4 + error:&error]; + if (error != nil) { + NSLog(@"[Camera] Unable to create AVAssetWriter: %@", error); + } + + [self.recordAssetWriter addInput:self.recordAssetWriterInput]; + self.recordAssetWriterInput.expectsMediaDataInRealTime = YES; + + NSLog(@"[Camera] created AVAssetWriter"); +} + + +- (void)createCaptureOutput; +{ + [self createVideoDataOutput]; + if (self.recordVideo == YES) { + [self createVideoFileOutput]; + } +} + +- (void)createCustomVideoPreview; +{ + [self.parentView.layer addSublayer:self.customPreviewLayer]; +} + + +#pragma mark - Protocol AVCaptureVideoDataOutputSampleBufferDelegate + + +- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection +{ + if (self.delegate) { + + // convert from Core Media to Core Video + CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); + CVPixelBufferLockBaseAddress(imageBuffer, 0); + + void* bufferAddress; + size_t width; + size_t height; + size_t bytesPerRow; + + CGColorSpaceRef colorSpace; + CGContextRef context; + + int format_opencv; + + OSType format = CVPixelBufferGetPixelFormatType(imageBuffer); + if (format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) { + + format_opencv = CV_8UC1; + + bufferAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); + width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0); + height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0); + bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); + + } else { // expect kCVPixelFormatType_32BGRA + + format_opencv = CV_8UC4; + + bufferAddress = CVPixelBufferGetBaseAddress(imageBuffer); + width = CVPixelBufferGetWidth(imageBuffer); + height = CVPixelBufferGetHeight(imageBuffer); + bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); + + } + + // delegate image processing to the delegate + cv::Mat image(height, width, format_opencv, bufferAddress, bytesPerRow); + + cv::Mat* result = NULL; + CGImage* dstImage; + + if ([self.delegate respondsToSelector:@selector(processImage:)]) { + [self.delegate processImage:image]; + } + + // check if matrix data pointer or dimensions were changed by the delegate + bool iOSimage = false; + if (height == image.rows && width == image.cols && format_opencv == image.type() && bufferAddress == image.data && bytesPerRow == image.step) { + iOSimage = true; + } + + + // (create color space, create graphics context, render buffer) + CGBitmapInfo bitmapInfo; + + // basically we decide if it's a grayscale, rgb or rgba image + if (image.channels() == 1) { + colorSpace = CGColorSpaceCreateDeviceGray(); + bitmapInfo = kCGImageAlphaNone; + } else if (image.channels() == 3) { + colorSpace = CGColorSpaceCreateDeviceRGB(); + bitmapInfo = kCGImageAlphaNone; + if (iOSimage) { + bitmapInfo |= kCGBitmapByteOrder32Little; + } else { + bitmapInfo |= kCGBitmapByteOrder32Big; + } + } else { + colorSpace = CGColorSpaceCreateDeviceRGB(); + bitmapInfo = kCGImageAlphaPremultipliedFirst; + if (iOSimage) { + bitmapInfo |= kCGBitmapByteOrder32Little; + } else { + bitmapInfo |= kCGBitmapByteOrder32Big; + } + } + + if (iOSimage) { + context = CGBitmapContextCreate(bufferAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo); + dstImage = CGBitmapContextCreateImage(context); + CGContextRelease(context); + } else { + + NSData *data = [NSData dataWithBytes:image.data length:image.elemSize()*image.total()]; + CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); + + // Creating CGImage from cv::Mat + dstImage = CGImageCreate(image.cols, // width + image.rows, // height + 8, // bits per component + 8 * image.elemSize(), // bits per pixel + image.step, // bytesPerRow + colorSpace, // colorspace + bitmapInfo, // bitmap info + provider, // CGDataProviderRef + NULL, // decode + false, // should interpolate + kCGRenderingIntentDefault // intent + ); + + CGDataProviderRelease(provider); + } + + + // render buffer + dispatch_sync(dispatch_get_main_queue(), ^{ + self.customPreviewLayer.contents = (__bridge id)dstImage; + }); + + + if (self.recordVideo == YES) { + lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); +// CMTimeShow(lastSampleTime); + if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) { + [self.recordAssetWriter startWriting]; + [self.recordAssetWriter startSessionAtSourceTime:lastSampleTime]; + if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) { + NSLog(@"[Camera] Recording Error: asset writer status is not writing: %@", self.recordAssetWriter.error); + return; + } else { + NSLog(@"[Camera] Video recording started"); + } + } + + if (self.recordAssetWriterInput.readyForMoreMediaData) { + if (! [self.recordPixelBufferAdaptor appendPixelBuffer:imageBuffer + withPresentationTime:lastSampleTime] ) { + NSLog(@"Video Writing Error"); + } + } + + } + + + // cleanup + CGImageRelease(dstImage); + + CGColorSpaceRelease(colorSpace); + + CVPixelBufferUnlockBaseAddress(imageBuffer, 0); + } +} + + +- (void)updateOrientation; +{ + NSLog(@"rotate.."); + self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height); + [self layoutPreviewLayer]; +} + + +- (void)saveVideo; +{ + if (self.recordVideo == NO) { + return; + } + + ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; + if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:[self videoFileURL]]) { + [library writeVideoAtPathToSavedPhotosAlbum:[self videoFileURL] + completionBlock:^(NSURL *assetURL, NSError *error){}]; + } +} + + +- (NSURL *)videoFileURL; +{ + NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]; + NSURL *outputURL = [NSURL fileURLWithPath:outputPath]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:outputPath]) { + NSLog(@"file exists"); + } + return outputURL; +} + + + +- (NSString *)videoFileString; +{ + NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]; + return outputPath; +} + +@end diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_libv4l.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_libv4l.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_libv4l.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_libv4l.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1789 @@ +/* This is the contributed code: + +File: cvcap_v4l.cpp +Current Location: ../opencv-0.9.6/otherlibs/highgui + +Original Version: 2003-03-12 Magnus Lundin lundin@mlu.mine.nu +Original Comments: + +ML:This set of files adds support for firevre and usb cameras. +First it tries to install a firewire camera, +if that fails it tries a v4l/USB camera +It has been tested with the motempl sample program + +First Patch: August 24, 2004 Travis Wood TravisOCV@tkwood.com +For Release: OpenCV-Linux Beta4 opencv-0.9.6 +Tested On: LMLBT44 with 8 video inputs +Problems? Post problems/fixes to OpenCV group on groups.yahoo.com +Patched Comments: + +TW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4 +were not working. I have rewritten them so they work for me. At the same time, trying +to keep the original code as ML wrote it as unchanged as possible. No one likes to debug +someone elses code, so I resisted changes as much as possible. I have tried to keep the +same "ideas" where applicable, that is, where I could figure out what the previous author +intended. Some areas I just could not help myself and had to "spiffy-it-up" my way. + +These drivers should work with other V4L frame capture cards other then my bttv +driven frame capture card. + +Re Written driver for standard V4L mode. Tested using LMLBT44 video capture card. +Standard bttv drivers are on the LMLBT44 with up to 8 Inputs. + +This utility was written with the help of the document: +http://pages.cpsc.ucalgary.ca/~sayles/VFL_HowTo +as a general guide for interfacing into the V4l standard. + +Made the index value passed for icvOpenCAM_V4L(index) be the number of the +video device source in the /dev tree. The -1 uses original /dev/video. + +Index Device + 0 /dev/video0 + 1 /dev/video1 + 2 /dev/video2 + 3 /dev/video3 + ... + 7 /dev/video7 +with + -1 /dev/video + +TW: You can select any video source, but this package was limited from the start to only +ONE camera opened at any ONE time. +This is an original program limitation. +If you are interested, I will make my version available to other OpenCV users. The big +difference in mine is you may pass the camera number as part of the cv argument, but this +convention is non standard for current OpenCV calls and the camera number is not currently +passed into the called routine. + +Second Patch: August 28, 2004 Sfuncia Fabio fiblan@yahoo.it +For Release: OpenCV-Linux Beta4 Opencv-0.9.6 + +FS: this patch fix not sequential index of device (unplugged device), and real numCameras. + for -1 index (icvOpenCAM_V4L) i dont use /dev/video but real device available, because + if /dev/video is a link to /dev/video0 and i unplugged device on /dev/video0, /dev/video + is a bad link. I search the first available device with indexList. + +Third Patch: December 9, 2004 Frederic Devernay Frederic.Devernay@inria.fr +For Release: OpenCV-Linux Beta4 Opencv-0.9.6 + +[FD] I modified the following: + - handle YUV420P, YUV420, and YUV411P palettes (for many webcams) without using floating-point + - cvGrabFrame should not wait for the end of the first frame, and should return quickly + (see highgui doc) + - cvRetrieveFrame should in turn wait for the end of frame capture, and should not + trigger the capture of the next frame (the user choses when to do it using GrabFrame) + To get the old behavior, re-call cvRetrieveFrame just after cvGrabFrame. + - having global bufferIndex and FirstCapture variables makes the code non-reentrant + (e.g. when using several cameras), put these in the CvCapture struct. + - according to V4L HowTo, incrementing the buffer index must be done before VIDIOCMCAPTURE. + - the VID_TYPE_SCALES stuff from V4L HowTo is wrong: image size can be changed + even if the hardware does not support scaling (e.g. webcams can have several + resolutions available). Just don't try to set the size at 640x480 if the hardware supports + scaling: open with the default (probably best) image size, and let the user scale it + using SetProperty. + - image size can be changed by two subsequent calls to SetProperty (for width and height) + - bug fix: if the image size changes, realloc the new image only when it is grabbed + - issue errors only when necessary, fix error message formatting. + +Fourth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I modified the following: + - Additional Video4Linux2 support :) + - Use mmap functions (v4l2) + - New methods are internal: + try_palette_v4l2 -> rewrite try_palette for v4l2 + mainloop_v4l2, read_image_v4l2 -> this methods are moved from official v4l2 capture.c example + try_init_v4l -> device v4l initialisation + try_init_v4l2 -> device v4l2 initialisation + autosetup_capture_mode_v4l -> autodetect capture modes for v4l + autosetup_capture_mode_v4l2 -> autodetect capture modes for v4l2 + - Modifications are according with Video4Linux old codes + - Video4Linux handling is automatically if it does not recognize a Video4Linux2 device + - Tested succesful with Logitech Quickcam Express (V4L), Creative Vista (V4L) and Genius VideoCam Notebook (V4L2) + - Correct source lines with compiler warning messages + - Information message from v4l/v4l2 detection + +Fifth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I modified the following: + - SN9C10x chip based webcams support + - New methods are internal: + bayer2rgb24, sonix_decompress -> decoder routines for SN9C10x decoding from Takafumi Mizuno with his pleasure :) + - Tested succesful with Genius VideoCam Notebook (V4L2) + +Sixth Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I added the following: + - Add capture control support (hue, saturation, brightness, contrast, gain) + - Get and change V4L capture controls (hue, saturation, brightness, contrast) + - New method is internal: + icvSetControl -> set capture controls + - Tested succesful with Creative Vista (V4L) + +Seventh Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I added the following: + - Detect, get and change V4L2 capture controls (hue, saturation, brightness, contrast, gain) + - New methods are internal: + v4l2_scan_controls_enumerate_menu, v4l2_scan_controls -> detect capture control intervals + - Tested succesful with Genius VideoCam Notebook (V4L2) + +8th patch: Jan 5, 2006, Olivier.Bornet@idiap.ch +Add support of V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_MJPEG. +With this patch, new webcams of Logitech, like QuickCam Fusion works. +Note: For use these webcams, look at the UVC driver at +http://linux-uvc.berlios.de/ + +9th patch: Mar 4, 2006, Olivier.Bornet@idiap.ch +- try V4L2 before V4L, because some devices are V4L2 by default, + but they try to implement the V4L compatibility layer. + So, I think this is better to support V4L2 before V4L. +- better separation between V4L2 and V4L initialization. (this was needed to support + some drivers working, but not fully with V4L2. (so, we do not know when we + need to switch from V4L2 to V4L. + +10th patch: July 02, 2008, Mikhail Afanasyev fopencv@theamk.com +Fix reliability problems with high-resolution UVC cameras on linux +the symptoms were damaged image and 'Corrupt JPEG data: premature end of data segment' on stderr +- V4L_ABORT_BADJPEG detects JPEG warnings and turns them into errors, so bad images + could be filtered out +- USE_TEMP_BUFFER fixes the main problem (improper buffer management) and + prevents bad images in the first place + +11th patch: Apr 13, 2010, Filipe Almeida filipe.almeida@ist.utl.pt +- Tries to setup all properties first through v4l2_ioctl call. +- Allows seting up all Video4Linux properties through cvSetCaptureProperty instead of only CV_CAP_PROP_BRIGHTNESS, CV_CAP_PROP_CONTRAST, CV_CAP_PROP_SATURATION, CV_CAP_PROP_HUE, CV_CAP_PROP_GAIN and CV_CAP_PROP_EXPOSURE. + +12th patch: Apr 16, 2010, Filipe Almeida filipe.almeida@ist.utl.pt +- CvCaptureCAM_V4L structure cleanup (no longer needs _{min,max,} variables) +- Introduction of v4l2_ctrl_range - minimum and maximum allowed values for v4l controls +- Allows seting up all Video4Linux properties through cvSetCaptureProperty using input values between 0.0 and 1.0 +- Gets v4l properties first through v4l2_ioctl call (ignores capture->is_v4l2_device) +- cvGetCaptureProperty adjusted to support the changes +- Returns device properties to initial values after device closes + +13th patch: Apr 27, 2010, Filipe Almeida filipe.almeida@ist.utl.pt +- Solved problem mmaping the device using uvcvideo driver (use o v4l2_mmap instead of mmap) +make & enjoy! + +14th patch: May 10, 2010, Filipe Almeida filipe.almeida@ist.utl.pt +- Bug #142: Solved/Workaround "setting frame width and height does not work" + There was a problem setting up the size when the input is a v4l2 device + The workaround closes the camera and reopens it with the new definition + Planning for future rewrite of this whole library (July/August 2010) + +15th patch: May 12, 2010, Filipe Almeida filipe.almeida@ist.utl.pt +- Broken compile of library (include "_highgui.h") +*/ + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if !defined WIN32 && defined HAVE_LIBV4L + +#define CLEAR(x) memset (&(x), 0, sizeof (x)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for videodev2.h */ +#include +#include +#include + +#ifdef HAVE_CAMV4L +#include +#endif +#ifdef HAVE_CAMV4L2 +#include +#endif + +#include +#include + +/* Defaults - If your board can do better, set it here. Set for the most common type inputs. */ +#define DEFAULT_V4L_WIDTH 640 +#define DEFAULT_V4L_HEIGHT 480 + +#define CHANNEL_NUMBER 1 +#define MAX_CAMERAS 8 + + +// default and maximum number of V4L buffers, not including last, 'special' buffer +#define MAX_V4L_BUFFERS 10 +#define DEFAULT_V4L_BUFFERS 4 + +// if enabled, copies data from the buffer. this uses a bit more memory, +// but much more reliable for some UVC cameras +#define USE_TEMP_BUFFER + +#define MAX_DEVICE_DRIVER_NAME 80 + +/* Device Capture Objects */ +/* V4L2 structure */ +struct buffer +{ + void * start; + size_t length; +}; +static unsigned int n_buffers = 0; + +/* TODO: Dilemas: */ +/* TODO: Consider drop the use of this data structure and perform ioctl to obtain needed values */ +/* TODO: Consider at program exit return controls to the initial values - See v4l2_free_ranges function */ +/* TODO: Consider at program exit reset the device to default values - See v4l2_free_ranges function */ +typedef struct v4l2_ctrl_range { + __u32 ctrl_id; + __s32 initial_value; + __s32 current_value; + __s32 minimum; + __s32 maximum; + __s32 default_value; +} v4l2_ctrl_range; + +typedef struct CvCaptureCAM_V4L +{ + char* deviceName; + int deviceHandle; + int bufferIndex; + int FirstCapture; + + int width; int height; + + struct video_capability capability; + struct video_window captureWindow; + struct video_picture imageProperties; + struct video_mbuf memoryBuffer; + struct video_mmap *mmaps; + char *memoryMap; + IplImage frame; + + /* V4L2 variables */ + buffer buffers[MAX_V4L_BUFFERS + 1]; + struct v4l2_capability cap; + struct v4l2_input inp; + struct v4l2_format form; + struct v4l2_crop crop; + struct v4l2_cropcap cropcap; + struct v4l2_requestbuffers req; + struct v4l2_jpegcompression compr; + struct v4l2_control control; + enum v4l2_buf_type type; + struct v4l2_queryctrl queryctrl; + struct v4l2_querymenu querymenu; + + /* V4L2 control variables */ + v4l2_ctrl_range** v4l2_ctrl_ranges; + int v4l2_ctrl_count; + + int is_v4l2_device; +} +CvCaptureCAM_V4L; + +static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ); + +static int icvGrabFrameCAM_V4L( CvCaptureCAM_V4L* capture ); +static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int ); +CvCapture* cvCreateCameraCapture_V4L( int index ); + +static double icvGetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id ); +static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id, double value ); + +static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h); + +/*********************** Implementations ***************************************/ + +static int numCameras = 0; +static int indexList = 0; + +// IOCTL handling for V4L2 +#ifdef HAVE_IOCTL_ULONG +static int xioctl( int fd, unsigned long request, void *arg) +#else +static int xioctl( int fd, int request, void *arg) +#endif +{ + + int r; + + + do r = v4l2_ioctl (fd, request, arg); + while (-1 == r && EINTR == errno); + + return r; + +} + + +/* Simple test program: Find number of Video Sources available. + Start from 0 and go to MAX_CAMERAS while checking for the device with that name. + If it fails on the first attempt of /dev/video0, then check if /dev/video is valid. + Returns the global numCameras with the correct value (we hope) */ + +static void icvInitCapture_V4L() { + int deviceHandle; + int CameraNumber; + char deviceName[MAX_DEVICE_DRIVER_NAME]; + + CameraNumber = 0; + while(CameraNumber < MAX_CAMERAS) { + /* Print the CameraNumber at the end of the string with a width of one character */ + sprintf(deviceName, "/dev/video%1d", CameraNumber); + /* Test using an open to see if this new device name really does exists. */ + deviceHandle = open(deviceName, O_RDONLY); + if (deviceHandle != -1) { + /* This device does indeed exist - add it to the total so far */ + // add indexList + indexList|=(1 << CameraNumber); + numCameras++; + } + if (deviceHandle != -1) + close(deviceHandle); + /* Set up to test the next /dev/video source in line */ + CameraNumber++; + } /* End while */ + +}; /* End icvInitCapture_V4L */ + + +static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) + +{ + + // if detect = -1 then unable to open device + // if detect = 0 then detected nothing + // if detect = 1 then V4L device + int detect = 0; + + + // Test device for V4L compability + + /* Test using an open to see if this new device name really does exists. */ + /* No matter what the name - it still must be opened! */ + capture->deviceHandle = v4l1_open(deviceName, O_RDWR); + + + if (capture->deviceHandle == 0) + { + detect = -1; + + icvCloseCAM_V4L(capture); + } + + if (detect == 0) + { + /* Query the newly opened device for its capabilities */ + if (v4l1_ioctl(capture->deviceHandle, VIDIOCGCAP, &capture->capability) < 0) + { + detect = 0; + + icvCloseCAM_V4L(capture); + } + else + { + detect = 1; + } + } + + return detect; + +} + + +static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName) +{ + + // if detect = -1 then unable to open device + // if detect = 0 then detected nothing + // if detect = 1 then V4L2 device + int detect = 0; + + + // Test device for V4L2 compability + + /* Open and test V4L2 device */ + capture->deviceHandle = v4l2_open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0); + + + + if (capture->deviceHandle == 0) + { + detect = -1; + + icvCloseCAM_V4L(capture); + } + + if (detect == 0) + { + CLEAR (capture->cap); + if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap)) + { + detect = 0; + + icvCloseCAM_V4L(capture); + } + else + { + CLEAR (capture->capability); + capture->capability.type = capture->cap.capabilities; + + /* Query channels number */ + if (-1 != xioctl (capture->deviceHandle, VIDIOC_G_INPUT, &capture->capability.channels)) + { + detect = 1; + } + } + } + + return detect; + +} + + +static void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture) +{ +// printf (" Menu items:\n"); + CLEAR (capture->querymenu); + capture->querymenu.id = capture->queryctrl.id; + for (capture->querymenu.index = capture->queryctrl.minimum; + (int)capture->querymenu.index <= capture->queryctrl.maximum; + capture->querymenu.index++) + { + if (0 == xioctl (capture->deviceHandle, VIDIOC_QUERYMENU, + &capture->querymenu)) + { + //printf (" %s\n", capture->querymenu.name); + } else { + perror ("VIDIOC_QUERYMENU"); + } + } +} + +static void v4l2_free_ranges(CvCaptureCAM_V4L* capture) { + int i; + if (capture->v4l2_ctrl_ranges != NULL) { + for (i = 0; i < capture->v4l2_ctrl_count; i++) { + /* Return device to initial values: */ + /* double value = (capture->v4l2_ctrl_ranges[i]->initial_value == 0)?0.0:((float)capture->v4l2_ctrl_ranges[i]->initial_value - capture->v4l2_ctrl_ranges[i]->minimum) / (capture->v4l2_ctrl_ranges[i]->maximum - capture->v4l2_ctrl_ranges[i]->minimum); */ + /* Return device to default values: */ + /* double value = (capture->v4l2_ctrl_ranges[i]->default_value == 0)?0.0:((float)capture->v4l2_ctrl_ranges[i]->default_value - capture->v4l2_ctrl_ranges[i]->minimum + 1) / (capture->v4l2_ctrl_ranges[i]->maximum - capture->v4l2_ctrl_ranges[i]->minimum); */ + + /* icvSetPropertyCAM_V4L(capture, capture->v4l2_ctrl_ranges[i]->ctrl_id, value); */ + free(capture->v4l2_ctrl_ranges[i]); + } + } + free(capture->v4l2_ctrl_ranges); + capture->v4l2_ctrl_count = 0; + capture->v4l2_ctrl_ranges = NULL; +} + +static void v4l2_add_ctrl_range(CvCaptureCAM_V4L* capture, v4l2_control* ctrl) { + v4l2_ctrl_range* range = (v4l2_ctrl_range*)malloc(sizeof(v4l2_ctrl_range)); + range->ctrl_id = ctrl->id; + range->initial_value = ctrl->value; + range->current_value = ctrl->value; + range->minimum = capture->queryctrl.minimum; + range->maximum = capture->queryctrl.maximum; + range->default_value = capture->queryctrl.default_value; + capture->v4l2_ctrl_ranges[capture->v4l2_ctrl_count] = range; + capture->v4l2_ctrl_count += 1; + capture->v4l2_ctrl_ranges = (v4l2_ctrl_range**)realloc((v4l2_ctrl_range**)capture->v4l2_ctrl_ranges, (capture->v4l2_ctrl_count + 1) * sizeof(v4l2_ctrl_range*)); +} + +static int v4l2_get_ctrl_default(CvCaptureCAM_V4L* capture, __u32 id) { + int i; + for (i = 0; i < capture->v4l2_ctrl_count; i++) { + if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { + return capture->v4l2_ctrl_ranges[i]->default_value; + } + } + return -1; +} + +static int v4l2_get_ctrl_min(CvCaptureCAM_V4L* capture, __u32 id) { + int i; + for (i = 0; i < capture->v4l2_ctrl_count; i++) { + if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { + return capture->v4l2_ctrl_ranges[i]->minimum; + } + } + return -1; +} + +static int v4l2_get_ctrl_max(CvCaptureCAM_V4L* capture, __u32 id) { + int i; + for (i = 0; i < capture->v4l2_ctrl_count; i++) { + if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { + return capture->v4l2_ctrl_ranges[i]->maximum; + } + } + return -1; +} + + +static void v4l2_scan_controls(CvCaptureCAM_V4L* capture) { + + __u32 ctrl_id; + struct v4l2_control c; + if (capture->v4l2_ctrl_ranges != NULL) { + v4l2_free_ranges(capture); + } + capture->v4l2_ctrl_ranges = (v4l2_ctrl_range**)malloc(sizeof(v4l2_ctrl_range*)); +#ifdef V4L2_CTRL_FLAG_NEXT_CTRL + /* Try the extended control API first */ + capture->queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; + if(0 == v4l2_ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl)) { + do { + c.id = capture->queryctrl.id; + capture->queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + continue; + } + if (capture->queryctrl.type == V4L2_CTRL_TYPE_MENU) { + v4l2_scan_controls_enumerate_menu(capture); + } + if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && + capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && + capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { + continue; + } + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { + v4l2_add_ctrl_range(capture, &c); + } + + } while(0 == v4l2_ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl)); + } else +#endif + { + /* Check all the standard controls */ + for(ctrl_id=V4L2_CID_BASE; ctrl_idqueryctrl.id = ctrl_id; + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl) == 0) { + if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + continue; + } + if (capture->queryctrl.type == V4L2_CTRL_TYPE_MENU) { + v4l2_scan_controls_enumerate_menu(capture); + } + if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && + capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && + capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { + continue; + } + c.id = ctrl_id; + + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { + v4l2_add_ctrl_range(capture, &c); + } + } + } + + /* Check any custom controls */ + for(ctrl_id=V4L2_CID_PRIVATE_BASE; ; ctrl_id++) { + capture->queryctrl.id = ctrl_id; + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl) == 0) { + if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + continue; + } + + if (capture->queryctrl.type == V4L2_CTRL_TYPE_MENU) { + v4l2_scan_controls_enumerate_menu(capture); + } + + if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && + capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && + capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { + continue; + } + + c.id = ctrl_id; + + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { + v4l2_add_ctrl_range(capture, &c); + } + } else { + break; + } + } + } +} + +static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName) +{ + int detect_v4l2 = 0; + + capture->deviceName = strdup(deviceName); + + detect_v4l2 = try_init_v4l2(capture, deviceName); + + if (detect_v4l2 != 1) { + /* init of the v4l2 device is not OK */ + return -1; + } + + /* starting from here, we assume we are in V4L2 mode */ + capture->is_v4l2_device = 1; + + capture->v4l2_ctrl_ranges = NULL; + capture->v4l2_ctrl_count = 0; + + /* Scan V4L2 controls */ + v4l2_scan_controls(capture); + + if ((capture->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { + /* Nope. */ + fprintf( stderr, "HIGHGUI ERROR: V4L2: device %s is unable to capture video memory.\n",deviceName); + icvCloseCAM_V4L(capture); + return -1; + } + + /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources + have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. + I myself am using a simple NTSC video input capture card that uses the value of 1. + If you are not in North America or have a different video standard, you WILL have to change + the following settings and recompile/reinstall. This set of settings is based on + the most commonly encountered input video source types (like my bttv card) */ + + if(capture->inp.index > 0) { + CLEAR (capture->inp); + capture->inp.index = CHANNEL_NUMBER; + /* Set only channel number to CHANNEL_NUMBER */ + /* V4L2 have a status field from selected video mode */ + if (-1 == xioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp)) + { + fprintf (stderr, "HIGHGUI ERROR: V4L2: Aren't able to set channel number\n"); + icvCloseCAM_V4L (capture); + return -1; + } + } /* End if */ + + /* Find Window info */ + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { + fprintf( stderr, "HIGHGUI ERROR: V4L2: Could not obtain specifics of capture window.\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + /* libv4l will convert from any format to V4L2_PIX_FMT_BGR24 */ + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->form.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; + capture->form.fmt.pix.field = V4L2_FIELD_ANY; + capture->form.fmt.pix.width = capture->width; + capture->form.fmt.pix.height = capture->height; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form)) { + fprintf(stderr, "HIGHGUI ERROR: libv4l unable to ioctl S_FMT\n"); + return -1; + } + + if (V4L2_PIX_FMT_BGR24 != capture->form.fmt.pix.pixelformat) { + fprintf( stderr, "HIGHGUI ERROR: libv4l unable convert to requested pixfmt\n"); + return -1; + } + + /* icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT); */ + + unsigned int min; + + /* Buggy driver paranoia. */ + min = capture->form.fmt.pix.width * 2; + + if (capture->form.fmt.pix.bytesperline < min) + capture->form.fmt.pix.bytesperline = min; + + min = capture->form.fmt.pix.bytesperline * capture->form.fmt.pix.height; + + if (capture->form.fmt.pix.sizeimage < min) + capture->form.fmt.pix.sizeimage = min; + + CLEAR (capture->req); + + unsigned int buffer_number = DEFAULT_V4L_BUFFERS; + + try_again: + + capture->req.count = buffer_number; + capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->req.memory = V4L2_MEMORY_MMAP; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req)) + { + if (EINVAL == errno) + { + fprintf (stderr, "%s does not support memory mapping\n", deviceName); + } else { + perror ("VIDIOC_REQBUFS"); + } + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + + if (capture->req.count < buffer_number) + { + if (buffer_number == 1) + { + fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } else { + buffer_number--; + fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName); + + goto try_again; + } + } + + for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers) + { + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = n_buffers; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) { + perror ("VIDIOC_QUERYBUF"); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + + capture->buffers[n_buffers].length = buf.length; + capture->buffers[n_buffers].start = + v4l2_mmap (NULL /* start anywhere */, + buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, + capture->deviceHandle, buf.m.offset); + + if (MAP_FAILED == capture->buffers[n_buffers].start) { + perror ("mmap"); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + +#ifdef USE_TEMP_BUFFER + if (n_buffers == 0) { + if (capture->buffers[MAX_V4L_BUFFERS].start) { + free(capture->buffers[MAX_V4L_BUFFERS].start); + capture->buffers[MAX_V4L_BUFFERS].start = NULL; + } + + capture->buffers[MAX_V4L_BUFFERS].start = malloc(buf.length); + capture->buffers[MAX_V4L_BUFFERS].length = buf.length; + }; +#endif + } + + /* Set up Image data */ + cvInitImageHeader( &capture->frame, + cvSize( capture->captureWindow.width, + capture->captureWindow.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + /* Allocate space for RGBA data */ + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + + return 1; +}; /* End _capture_V4L2 */ + + +static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName) +{ + int detect_v4l = 0; + + detect_v4l = try_init_v4l(capture, deviceName); + + if ((detect_v4l == -1) + ) + { + fprintf (stderr, "HIGHGUI ERROR: V4L" + ": device %s: Unable to open for READ ONLY\n", deviceName); + + return -1; + } + + if ((detect_v4l <= 0) + ) + { + fprintf (stderr, "HIGHGUI ERROR: V4L" + ": device %s: Unable to query number of channels\n", deviceName); + + return -1; + } + + { + if ((capture->capability.type & VID_TYPE_CAPTURE) == 0) { + /* Nope. */ + fprintf( stderr, "HIGHGUI ERROR: V4L: " + "device %s is unable to capture video memory.\n",deviceName); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + + /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources + have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. + I myself am using a simple NTSC video input capture card that uses the value of 1. + If you are not in North America or have a different video standard, you WILL have to change + the following settings and recompile/reinstall. This set of settings is based on + the most commonly encountered input video source types (like my bttv card) */ + + { + + if(capture->capability.channels>0) { + + struct video_channel selectedChannel; + + selectedChannel.channel=CHANNEL_NUMBER; + if (v4l1_ioctl(capture->deviceHandle, VIDIOCGCHAN , &selectedChannel) != -1) { + /* set the video mode to ( VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM) */ +// selectedChannel.norm = VIDEO_MODE_NTSC; + if (v4l1_ioctl(capture->deviceHandle, VIDIOCSCHAN , &selectedChannel) == -1) { + /* Could not set selected channel - Oh well */ + //printf("\n%d, %s not NTSC capable.\n",selectedChannel.channel, selectedChannel.name); + } /* End if */ + } /* End if */ + } /* End if */ + + } + + { + + if(v4l1_ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: " + "Could not obtain specifics of capture window.\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + { + if(v4l1_ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Unable to determine size of incoming image\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + capture->imageProperties.palette = VIDEO_PALETTE_RGB24; + capture->imageProperties.depth = 24; + if (v4l1_ioctl(capture->deviceHandle, VIDIOCSPICT, &capture->imageProperties) < 0) { + fprintf( stderr, "HIGHGUI ERROR: libv4l unable to ioctl VIDIOCSPICT\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + if (v4l1_ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) { + fprintf( stderr, "HIGHGUI ERROR: libv4l unable to ioctl VIDIOCGPICT\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + if (capture->imageProperties.palette != VIDEO_PALETTE_RGB24) { + fprintf( stderr, "HIGHGUI ERROR: libv4l unable convert to requested pixfmt\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + { + + v4l1_ioctl(capture->deviceHandle, VIDIOCGMBUF, &capture->memoryBuffer); + capture->memoryMap = (char *)v4l1_mmap(0, + capture->memoryBuffer.size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + capture->deviceHandle, + 0); + if (capture->memoryMap == MAP_FAILED) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Mapping Memmory from video source error: %s\n", strerror(errno)); + icvCloseCAM_V4L(capture); + return -1; + } + + /* Set up video_mmap structure pointing to this memory mapped area so each image may be + retrieved from an index value */ + capture->mmaps = (struct video_mmap *) + (malloc(capture->memoryBuffer.frames * sizeof(struct video_mmap))); + if (!capture->mmaps) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not memory map video frames.\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + /* Set up Image data */ + cvInitImageHeader( &capture->frame, + cvSize( capture->captureWindow.width, + capture->captureWindow.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + /* Allocate space for RGBA data */ + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + + return 1; +}; /* End _capture_V4L */ + +static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index) +{ + static int autoindex; + autoindex = 0; + + char deviceName[MAX_DEVICE_DRIVER_NAME]; + + if (!numCameras) + icvInitCapture_V4L(); /* Havent called icvInitCapture yet - do it now! */ + if (!numCameras) + return NULL; /* Are there any /dev/video input sources? */ + + //search index in indexList + if ( (index>-1) && ! ((1 << index) & indexList) ) + { + fprintf( stderr, "HIGHGUI ERROR: V4L: index %d is not correct!\n",index); + return NULL; /* Did someone ask for not correct video source number? */ + } + /* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL + the handles for V4L processing */ + CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L)); + if (!capture) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n"); + return NULL; + } + +#ifdef USE_TEMP_BUFFER + capture->buffers[MAX_V4L_BUFFERS].start = NULL; +#endif + + /* Select camera, or rather, V4L video source */ + if (index<0) { // Asking for the first device available + for (; autoindexFirstCapture = 1; + + /* set the default size */ + capture->width = DEFAULT_V4L_WIDTH; + capture->height = DEFAULT_V4L_HEIGHT; + + if (_capture_V4L2 (capture, deviceName) == -1) { + icvCloseCAM_V4L(capture); + capture->is_v4l2_device = 0; + if (_capture_V4L (capture, deviceName) == -1) { + icvCloseCAM_V4L(capture); + return NULL; + } + } else { + capture->is_v4l2_device = 1; + } + + return capture; +}; /* End icvOpenCAM_V4L */ + +#ifdef HAVE_CAMV4L2 + +static int read_frame_v4l2(CvCaptureCAM_V4L* capture) { + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) { + switch (errno) { + case EAGAIN: + return 0; + + case EIO: + /* Could ignore EIO, see spec. */ + + /* fall through */ + + default: + /* display the error and stop processing */ + perror ("VIDIOC_DQBUF"); + return 1; + } + } + + assert(buf.index < capture->req.count); + +#ifdef USE_TEMP_BUFFER + memcpy(capture->buffers[MAX_V4L_BUFFERS].start, + capture->buffers[buf.index].start, + capture->buffers[MAX_V4L_BUFFERS].length ); + capture->bufferIndex = MAX_V4L_BUFFERS; + //printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n", + // buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused); +#else + capture->bufferIndex = buf.index; +#endif + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) + perror ("VIDIOC_QBUF"); + + return 1; +} + +static void mainloop_v4l2(CvCaptureCAM_V4L* capture) { + unsigned int count; + + count = 1; + + while (count-- > 0) { + for (;;) { + fd_set fds; + struct timeval tv; + int r; + + FD_ZERO (&fds); + FD_SET (capture->deviceHandle, &fds); + + /* Timeout. */ + tv.tv_sec = 10; + tv.tv_usec = 0; + + r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv); + + if (-1 == r) { + if (EINTR == errno) + continue; + + perror ("select"); + } + + if (0 == r) { + fprintf (stderr, "select timeout\n"); + + /* end the infinite loop */ + break; + } + + if (read_frame_v4l2 (capture)) + break; + } + } +} + +static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { + + if (capture->FirstCapture) { + /* Some general initialization must take place the first time through */ + + /* This is just a technicality, but all buffers must be filled up before any + staggered SYNC is applied. SO, filler up. (see V4L HowTo) */ + + if (capture->is_v4l2_device == 1) + { + + for (capture->bufferIndex = 0; + capture->bufferIndex < ((int)capture->req.count); + ++capture->bufferIndex) + { + + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = (unsigned long)capture->bufferIndex; + + if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) { + perror ("VIDIOC_QBUF"); + return 0; + } + } + + /* enable the streaming */ + capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == xioctl (capture->deviceHandle, VIDIOC_STREAMON, + &capture->type)) { + /* error enabling the stream */ + perror ("VIDIOC_STREAMON"); + return 0; + } + } else + { + + for (capture->bufferIndex = 0; + capture->bufferIndex < (capture->memoryBuffer.frames-1); + ++capture->bufferIndex) { + + capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; + capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; + capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; + capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; + + if (v4l1_ioctl(capture->deviceHandle, VIDIOCMCAPTURE, &capture->mmaps[capture->bufferIndex]) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers.\n"); + return 0; + } + } + + } + + /* preparation is ok */ + capture->FirstCapture = 0; + } + + if (capture->is_v4l2_device == 1) + { + + mainloop_v4l2(capture); + + } else + { + + capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; + capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; + capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; + capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; + + if (v4l1_ioctl (capture->deviceHandle, VIDIOCMCAPTURE, + &capture->mmaps[capture->bufferIndex]) == -1) { + /* capture is on the way, so just exit */ + return 1; + } + + ++capture->bufferIndex; + if (capture->bufferIndex == capture->memoryBuffer.frames) { + capture->bufferIndex = 0; + } + + } + + return(1); +} + +static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { + + if (capture->is_v4l2_device == 0) + { + + /* [FD] this really belongs here */ + if (v4l1_ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex].frame) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not SYNC to video stream. %s\n", strerror(errno)); + } + + } + + /* Now get what has already been captured as a IplImage return */ + + /* First, reallocate imageData if the frame size changed */ + + if (capture->is_v4l2_device == 1) + { + + if(((unsigned long)capture->frame.width != capture->form.fmt.pix.width) + || ((unsigned long)capture->frame.height != capture->form.fmt.pix.height)) { + cvFree(&capture->frame.imageData); + cvInitImageHeader( &capture->frame, + cvSize( capture->form.fmt.pix.width, + capture->form.fmt.pix.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + } + + } else + { + + if((capture->frame.width != capture->mmaps[capture->bufferIndex].width) + || (capture->frame.height != capture->mmaps[capture->bufferIndex].height)) { + cvFree(&capture->frame.imageData); + cvInitImageHeader( &capture->frame, + cvSize( capture->captureWindow.width, + capture->captureWindow.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + } + + } + + if (capture->is_v4l2_device == 1) + { + + if(capture->buffers[capture->bufferIndex].start){ + memcpy((char *)capture->frame.imageData, + (char *)capture->buffers[capture->bufferIndex].start, + capture->frame.imageSize); + } + + } else +#endif /* HAVE_CAMV4L2 */ + { + + switch(capture->imageProperties.palette) { + case VIDEO_PALETTE_RGB24: + memcpy((char *)capture->frame.imageData, + (char *)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), + capture->frame.imageSize); + break; + default: + fprintf( stderr, + "HIGHGUI ERROR: V4L: Cannot convert from palette %d to RGB\n", + capture->imageProperties.palette); + return 0; + } + + } + + return(&capture->frame); +} + +/* TODO: review this adaptation */ +static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, + int property_id ) { + char name[32]; + int is_v4l2_device = 0; + /* initialize the control structure */ + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + case CV_CAP_PROP_FRAME_HEIGHT: + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { + /* display an error message, and return an error code */ + perror ("VIDIOC_G_FMT"); + if (v4l1_ioctl (capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) { + fprintf (stderr, "HIGHGUI ERROR: V4L: Unable to determine size of incoming image\n"); + icvCloseCAM_V4L(capture); + return -1; + } else { + int retval = (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->captureWindow.width:capture->captureWindow.height; + return retval / 0xFFFF; + } + } + return (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->form.fmt.pix.width:capture->form.fmt.pix.height; + case CV_CAP_PROP_BRIGHTNESS: + sprintf(name, "Brightness"); + capture->control.id = V4L2_CID_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + sprintf(name, "Contrast"); + capture->control.id = V4L2_CID_CONTRAST; + break; + case CV_CAP_PROP_SATURATION: + sprintf(name, "Saturation"); + capture->control.id = V4L2_CID_SATURATION; + break; + case CV_CAP_PROP_HUE: + sprintf(name, "Hue"); + capture->control.id = V4L2_CID_HUE; + break; + case CV_CAP_PROP_GAIN: + sprintf(name, "Gain"); + capture->control.id = V4L2_CID_GAIN; + break; + case CV_CAP_PROP_EXPOSURE: + sprintf(name, "Exposure"); + capture->control.id = V4L2_CID_EXPOSURE; + break; + default: + sprintf(name, ""); + capture->control.id = property_id; + } + + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) { + /* all went well */ + is_v4l2_device = 1; + } else { + fprintf(stderr, "HIGHGUI ERROR: V4L2: Unable to get property %s(%u) - %s\n", name, capture->control.id, strerror(errno)); + } + + if (is_v4l2_device == 1) { + /* get the min/max values */ + int v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); + int v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); + + if ((v4l2_min == -1) && (v4l2_max == -1)) { + fprintf(stderr, "HIGHGUI ERROR: V4L2: Property %s(%u) not supported by device\n", name, property_id); + return -1; + } + + /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ + return ((float)capture->control.value - v4l2_min) / (v4l2_max - v4l2_min); + + } else { + /* TODO: review this section */ + int retval = -1; + + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + retval = capture->imageProperties.brightness; + break; + case CV_CAP_PROP_CONTRAST: + retval = capture->imageProperties.contrast; + break; + case CV_CAP_PROP_SATURATION: + retval = capture->imageProperties.colour; + break; + case CV_CAP_PROP_HUE: + retval = capture->imageProperties.hue; + break; + case CV_CAP_PROP_GAIN: + fprintf(stderr, "HIGHGUI ERROR: V4L: Gain control in V4L is not supported\n"); + return -1; + break; + case CV_CAP_PROP_EXPOSURE: + fprintf(stderr, "HIGHGUI ERROR: V4L: Exposure control in V4L is not supported\n"); + return -1; + break; + } + + if (retval == -1) { + /* there was a problem */ + return -1; + } + /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ + return float (retval) / 0xFFFF; + } +} + +static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) { + + if (capture->is_v4l2_device == 1) + { + char deviceName[MAX_DEVICE_DRIVER_NAME]; + sprintf(deviceName, "%s", capture->deviceName); + icvCloseCAM_V4L(capture); + _capture_V4L2(capture, deviceName); + + CLEAR (capture->crop); + capture->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->crop.c.left = 0; + capture->crop.c.top = 0; + capture->crop.c.height = h*24; + capture->crop.c.width = w*24; + + /* set the crop area, but don't exit if the device don't support croping */ + xioctl (capture->deviceHandle, VIDIOC_S_CROP, &capture->crop); + + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + /* read the current setting, mainly to retreive the pixelformat information */ + xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form); + + /* set the values we want to change */ + capture->form.fmt.pix.width = w; + capture->form.fmt.pix.height = h; + capture->form.fmt.win.chromakey = 0; + capture->form.fmt.win.field = V4L2_FIELD_ANY; + capture->form.fmt.win.clips = 0; + capture->form.fmt.win.clipcount = 0; + capture->form.fmt.pix.field = V4L2_FIELD_ANY; + + /* ask the device to change the size + * don't test if the set of the size is ok, because some device + * don't allow changing the size, and we will get the real size + * later */ + xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form); + + /* try to set framerate to 30 fps */ + struct v4l2_streamparm setfps; + memset (&setfps, 0, sizeof(struct v4l2_streamparm)); + setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + setfps.parm.capture.timeperframe.numerator = 1; + setfps.parm.capture.timeperframe.denominator = 30; + xioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps); + + /* we need to re-initialize some things, like buffers, because the size has + * changed */ + capture->FirstCapture = 1; + + /* Get window info again, to get the real value */ + if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) + { + fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: Could not obtain specifics of capture window.\n\n"); + + icvCloseCAM_V4L(capture); + + return 0; + } + + return 0; + + } else + { + + if (capture==0) return 0; + if (w>capture->capability.maxwidth) { + w=capture->capability.maxwidth; + } + if (h>capture->capability.maxheight) { + h=capture->capability.maxheight; + } + + capture->captureWindow.width=w; + capture->captureWindow.height=h; + + if (ioctl(capture->deviceHandle, VIDIOCSWIN, &capture->captureWindow) < 0) { + icvCloseCAM_V4L(capture); + return 0; + } + + if (ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) { + icvCloseCAM_V4L(capture); + return 0; + } + + capture->FirstCapture = 1; + + } + + return 0; + +} + +static int icvSetControl (CvCaptureCAM_V4L* capture, int property_id, double value) { + struct v4l2_control c; + __s32 ctrl_value; + char name[32]; + int is_v4l2 = 1; + int v4l2_min = 0; + int v4l2_max = 255; + if (capture->v4l2_ctrl_ranges == NULL) { + v4l2_scan_controls(capture); + } + + CLEAR (capture->control); + CLEAR (capture->queryctrl); + + /* get current values */ + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + sprintf(name, "Brightness"); + capture->control.id = V4L2_CID_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + sprintf(name, "Contrast"); + capture->control.id = V4L2_CID_CONTRAST; + break; + case CV_CAP_PROP_SATURATION: + sprintf(name, "Saturation"); + capture->control.id = V4L2_CID_SATURATION; + break; + case CV_CAP_PROP_HUE: + sprintf(name, "Hue"); + capture->control.id = V4L2_CID_HUE; + break; + case CV_CAP_PROP_GAIN: + sprintf(name, "Gain"); + capture->control.id = V4L2_CID_GAIN; + break; + case CV_CAP_PROP_EXPOSURE: + sprintf(name, "Exposure"); + capture->control.id = V4L2_CID_EXPOSURE; + break; + default: + sprintf(name, ""); + capture->control.id = property_id; + } + + v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); + v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); + + if ((v4l2_min == -1) && (v4l2_max == -1)) { + fprintf(stderr, "HIGHGUI ERROR: V4L: Property %s(%u) not supported by device\n", name, property_id); + return -1; + } + + if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) { + /* all went well */ + } else { + fprintf(stderr, "HIGHGUI ERROR: V4L2: Unable to get property %s(%u) - %s\n", name, capture->control.id, strerror(errno)); + } + + if (v4l2_max != 0) { + double val = value; + if (value < 0.0) { + val = 0.0; + } else if (value > 1.0) { + val = 1.0; + } + ctrl_value = val * (double)(v4l2_max - v4l2_min) + v4l2_min; + } else { + ctrl_value = v4l2_get_ctrl_default(capture, capture->control.id) * (double)(v4l2_max - v4l2_min) + v4l2_min; + } + + /* try and set value as if it was a v4l2 device */ + c.id = capture->control.id; + c.value = ctrl_value; + if (v4l2_ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &c) != 0) { + /* The driver may clamp the value or return ERANGE, ignored here */ + if (errno != ERANGE) { + fprintf(stderr, "HIGHGUI ERROR: V4L2: Failed to set control \"%d\": %s (value %d)\n", c.id, strerror(errno), c.value); + is_v4l2 = 0; + } else { + return 0; + } + } else { + return 0; + } + + if (is_v4l2 == 0) { /* use v4l1_ioctl */ + fprintf(stderr, "HIGHGUI WARNING: Setting property %u through v4l2 failed. Trying with v4l1.\n", c.id); + int v4l_value; + /* scale the value to the wanted integer one */ + v4l_value = (int)(0xFFFF * value); + + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + capture->imageProperties.brightness = v4l_value; + break; + case CV_CAP_PROP_CONTRAST: + capture->imageProperties.contrast = v4l_value; + break; + case CV_CAP_PROP_SATURATION: + capture->imageProperties.colour = v4l_value; + break; + case CV_CAP_PROP_HUE: + capture->imageProperties.hue = v4l_value; + break; + case CV_CAP_PROP_GAIN: + fprintf(stderr, "HIGHGUI ERROR: V4L: Gain control in V4L is not supported\n"); + return -1; + case CV_CAP_PROP_EXPOSURE: + fprintf(stderr, "HIGHGUI ERROR: V4L: Exposure control in V4L is not supported\n"); + return -1; + default: + fprintf(stderr, "HIGHGUI ERROR: V4L: property #%d is not supported\n", property_id); + return -1; + } + + if (v4l1_ioctl(capture->deviceHandle, VIDIOCSPICT, &capture->imageProperties) < 0){ + fprintf(stderr, "HIGHGUI ERROR: V4L: Unable to set video informations\n"); + icvCloseCAM_V4L(capture); + return -1; + } + } + + /* all was OK */ + return 0; +} + +static int icvSetPropertyCAM_V4L(CvCaptureCAM_V4L* capture, int property_id, double value){ + static int width = 0, height = 0; + int retval; + + /* initialization */ + retval = 0; + + /* two subsequent calls setting WIDTH and HEIGHT will change + the video size */ + /* the first one will return an error, though. */ + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + width = cvRound(value); + capture->width = width; + if(width !=0 && height != 0) { + retval = icvSetVideoSize( capture, width, height); + width = height = 0; + } + break; + case CV_CAP_PROP_FRAME_HEIGHT: + height = cvRound(value); + capture->height = height; + if(width !=0 && height != 0) { + retval = icvSetVideoSize( capture, width, height); + width = height = 0; + } + break; + default: + retval = icvSetControl(capture, property_id, value); + } + + /* return the the status */ + return retval; +} + +static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){ + /* Deallocate space - Hopefully, no leaks */ + if (capture) { + v4l2_free_ranges(capture); + if (capture->is_v4l2_device == 0) { + if (capture->mmaps) { + free(capture->mmaps); + } + if (capture->memoryMap) { + v4l1_munmap(capture->memoryMap, capture->memoryBuffer.size); + } + if (capture->deviceHandle != -1) { + v4l1_close(capture->deviceHandle); + } + } else { + capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (xioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) { + perror ("Unable to stop the stream."); + } + for (unsigned int n_buffers2 = 0; n_buffers2 < capture->req.count; ++n_buffers2) { + if (-1 == v4l2_munmap (capture->buffers[n_buffers2].start, capture->buffers[n_buffers2].length)) { + perror ("munmap"); + } + } + + if (capture->deviceHandle != -1) { + v4l2_close(capture->deviceHandle); + } + } + + if (capture->frame.imageData) + cvFree(&capture->frame.imageData); + +#ifdef USE_TEMP_BUFFER + if (capture->buffers[MAX_V4L_BUFFERS].start) { + free(capture->buffers[MAX_V4L_BUFFERS].start); + capture->buffers[MAX_V4L_BUFFERS].start = NULL; + } +#endif + + free(capture->deviceName); + capture->deviceName = NULL; + //v4l2_free_ranges(capture); + //cvFree((void **)capture); + } +}; + + +class CvCaptureCAM_V4L_CPP : CvCapture +{ +public: + CvCaptureCAM_V4L_CPP() { captureV4L = 0; } + virtual ~CvCaptureCAM_V4L_CPP() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); +protected: + + CvCaptureCAM_V4L* captureV4L; +}; + +bool CvCaptureCAM_V4L_CPP::open( int index ) +{ + close(); + captureV4L = icvCaptureFromCAM_V4L(index); + return captureV4L != 0; +} + +void CvCaptureCAM_V4L_CPP::close() +{ + if( captureV4L ) + { + icvCloseCAM_V4L( captureV4L ); + cvFree( &captureV4L ); + } +} + +bool CvCaptureCAM_V4L_CPP::grabFrame() +{ + return captureV4L ? icvGrabFrameCAM_V4L( captureV4L ) != 0 : false; +} + +IplImage* CvCaptureCAM_V4L_CPP::retrieveFrame(int) +{ + return captureV4L ? icvRetrieveFrameCAM_V4L( captureV4L, 0 ) : 0; +} + +double CvCaptureCAM_V4L_CPP::getProperty( int propId ) +{ + return captureV4L ? icvGetPropertyCAM_V4L( captureV4L, propId ) : 0.0; +} + +bool CvCaptureCAM_V4L_CPP::setProperty( int propId, double value ) +{ + return captureV4L ? icvSetPropertyCAM_V4L( captureV4L, propId, value ) != 0 : false; +} + +CvCapture* cvCreateCameraCapture_V4L( int index ) +{ + CvCaptureCAM_V4L_CPP* capture = new CvCaptureCAM_V4L_CPP; + + if( capture->open( index )) + return (CvCapture*)capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_mil.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_mil.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_mil.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_mil.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,219 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "mil.h" + +#if _MSC_VER >= 1200 + #pragma warning( disable: 4711 ) + #pragma comment(lib,"mil.lib") + #pragma comment(lib,"milmet2.lib") +#endif + +#if defined _M_X64 + #pragma optimize("",off) +#endif + +/********************* Capturing video from camera via MIL *********************/ + +struct +{ + MIL_ID MilApplication; + int MilUser; +} g_Mil = {0,0}; //global structure for handling MIL application + +class CvCaptureCAM_MIL : public CvCapture +{ +public: + CvCaptureCAM_MIL() { init(); } + virtual ~CvCaptureCAM_MIL() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double) { return false; } + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_MIL; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + void init(); + + MIL_ID + MilSystem, /* System identifier. */ + MilDisplay, /* Display identifier. */ + MilDigitizer, /* Digitizer identifier. */ + MilImage; /* Image buffer identifier. */ + IplImage* rgb_frame; +}; + + +void CvCaptureCAM_MIL::init() +{ + MilSystem = MilDisplay = MilDigitizer = MilImage = M_NULL; + rgb_frame = 0; +} + +// Initialize camera input +bool CvCaptureCAM_MIL::open( int wIndex ) +{ + close(); + + if( g_Mil.MilApplication == M_NULL ) + { + assert(g_Mil.MilUser == 0); + MappAlloc(M_DEFAULT, &(g_Mil.MilApplication) ); + g_Mil.MilUser = 1; + } + else + { + assert(g_Mil.MilUser>0); + g_Mil.MilUser++; + } + + int dev_table[16] = { M_DEV0, M_DEV1, M_DEV2, M_DEV3, + M_DEV4, M_DEV5, M_DEV6, M_DEV7, + M_DEV8, M_DEV9, M_DEV10, M_DEV11, + M_DEV12, M_DEV13, M_DEV14, M_DEV15 }; + + //set default window size + int w = 320; + int h = 240; + + for( ; wIndex < 16; wIndex++ ) + { + MsysAlloc( M_SYSTEM_SETUP, //we use default system, + //if this does not work + //try to define exact board + //e.g.M_SYSTEM_METEOR,M_SYSTEM_METEOR_II... + dev_table[wIndex], + M_DEFAULT, + &MilSystem ); + + if( MilSystem != M_NULL ) + break; + } + if( MilSystem != M_NULL ) + { + MdigAlloc(MilSystem,M_DEFAULT, + M_CAMERA_SETUP, //default. May be M_NTSC or other + M_DEFAULT,&MilDigitizer); + + rgb_frame = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 3 ); + MdigControl(MilDigitizer, M_GRAB_SCALE, 1.0 / 2); + + /*below line enables getting image vertical orientation + consistent with VFW but it introduces some image corruption + on MeteorII, so we left the image as is*/ + //MdigControl(MilDigitizer, M_GRAB_DIRECTION_Y, M_REVERSE ); + + MilImage = MbufAllocColor(MilSystem, 3, w, h, + 8+M_UNSIGNED, M_IMAGE + M_GRAB, M_NULL); + } + + return MilSystem != M_NULL; +} + +void CvCaptureCAM_MIL::close( CvCaptureCAM_MIL* capture ) +{ + if( MilSystem != M_NULL ) + { + MdigFree( MilDigitizer ); + MbufFree( MilImage ); + MsysFree( MilSystem ); + cvReleaseImage(&rgb_frame ); + + g_Mil.MilUser--; + if(!g_Mil.MilUser) + MappFree(g_Mil.MilApplication); + + MilSystem = M_NULL; + MilDigitizer = M_NULL; + } +} + + +bool CvCaptureCAM_MIL::grabFrame() +{ + if( MilSystem ) + { + MdigGrab(MilDigitizer, MilImage); + return true; + } + return false; +} + + +IplImage* CvCaptureCAM_MIL::retrieveFrame(int) +{ + MbufGetColor(MilImage, M_BGR24+M_PACKED, M_ALL_BAND, (void*)(rgb_frame->imageData)); + return rgb_frame; +} + +double CvCaptureCAM_MIL::getProperty( int property_id ) +{ + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return rgb_frame ? rgb_frame->width : 0; + case CV_CAP_PROP_FRAME_HEIGHT: + return rgb_frame ? rgb_frame->height : 0; + } + return 0; +} + +bool CvCaptureCAM_MIL::setProperty( int, double ) +{ + return false; +} + + +CvCapture* cvCreateCameraCapture_MIL( int index ) +{ + CvCaptureCAM_MIL* capture = new CvCaptureCAM_MIL; + + if( capture->open( index )) + return capture; + + delete capture; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_msmf.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_msmf.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_msmf.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_msmf.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2810 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" +#if (defined WIN32 || defined _WIN32) && defined HAVE_MSMF +/* + Media Foundation-based Video Capturing module is based on + videoInput library by Evgeny Pereguda: + http://www.codeproject.com/Articles/559437/Capturing-of-video-from-web-camera-on-Windows-7-an + Originaly licensed under The Code Project Open License (CPOL) 1.02: + http://www.codeproject.com/info/cpol10.aspx +*/ +#include +#include +#include +#include +#include +#include +#include "Strsafe.h" +#include +#include +#include +#include +#include +#include +#include +#pragma warning(disable:4503) +#pragma comment(lib, "mfplat") +#pragma comment(lib, "mf") +#pragma comment(lib, "mfuuid") +#pragma comment(lib, "Strmiids") +#pragma comment(lib, "MinCore_Downlevel") +struct IMFMediaType; +struct IMFActivate; +struct IMFMediaSource; +struct IMFAttributes; +namespace +{ +template void SafeRelease(T **ppT) +{ + if (*ppT) + { + (*ppT)->Release(); + *ppT = NULL; + } +} + /// Class for printing info into consol +class DebugPrintOut +{ +public: + ~DebugPrintOut(void); + static DebugPrintOut& getInstance(); + void printOut(const wchar_t *format, ...); + void setVerbose(bool state); + bool verbose; +private: + DebugPrintOut(void); +}; +// Structure for collecting info about types of video, which are supported by current video device +struct MediaType +{ + unsigned int MF_MT_FRAME_SIZE; + unsigned int height; + unsigned int width; + unsigned int MF_MT_YUV_MATRIX; + unsigned int MF_MT_VIDEO_LIGHTING; + unsigned int MF_MT_DEFAULT_STRIDE; + unsigned int MF_MT_VIDEO_CHROMA_SITING; + GUID MF_MT_AM_FORMAT_TYPE; + wchar_t *pMF_MT_AM_FORMAT_TYPEName; + unsigned int MF_MT_FIXED_SIZE_SAMPLES; + unsigned int MF_MT_VIDEO_NOMINAL_RANGE; + unsigned int MF_MT_FRAME_RATE; + unsigned int MF_MT_FRAME_RATE_low; + unsigned int MF_MT_PIXEL_ASPECT_RATIO; + unsigned int MF_MT_PIXEL_ASPECT_RATIO_low; + unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT; + unsigned int MF_MT_FRAME_RATE_RANGE_MIN; + unsigned int MF_MT_FRAME_RATE_RANGE_MIN_low; + unsigned int MF_MT_SAMPLE_SIZE; + unsigned int MF_MT_VIDEO_PRIMARIES; + unsigned int MF_MT_INTERLACE_MODE; + unsigned int MF_MT_FRAME_RATE_RANGE_MAX; + unsigned int MF_MT_FRAME_RATE_RANGE_MAX_low; + GUID MF_MT_MAJOR_TYPE; + GUID MF_MT_SUBTYPE; + wchar_t *pMF_MT_MAJOR_TYPEName; + wchar_t *pMF_MT_SUBTYPEName; + MediaType(); + ~MediaType(); + void Clear(); +}; +/// Class for parsing info from IMFMediaType into the local MediaType +class FormatReader +{ +public: + static MediaType Read(IMFMediaType *pType); + ~FormatReader(void); +private: + FormatReader(void); +}; +DWORD WINAPI MainThreadFunction( LPVOID lpParam ); +typedef void(*emergensyStopEventCallback)(int, void *); +typedef unsigned char BYTE; +class RawImage +{ +public: + ~RawImage(void); + // Function of creation of the instance of the class + static long CreateInstance(RawImage **ppRImage,unsigned int size); + void setCopy(const BYTE * pSampleBuffer); + void fastCopy(const BYTE * pSampleBuffer); + unsigned char * getpPixels(); + bool isNew(); + unsigned int getSize(); +private: + bool ri_new; + unsigned int ri_size; + unsigned char *ri_pixels; + RawImage(unsigned int size); +}; +// Class for grabbing image from video stream +class ImageGrabber : public IMFSampleGrabberSinkCallback +{ +public: + ~ImageGrabber(void); + HRESULT initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat); + HRESULT startGrabbing(void); + void stopGrabbing(); + RawImage *getRawImage(); + // Function of creation of the instance of the class + static HRESULT CreateInstance(ImageGrabber **ppIG,unsigned int deviceID); +private: + bool ig_RIE; + bool ig_Close; + long m_cRef; + unsigned int ig_DeviceID; + IMFMediaSource *ig_pSource; + IMFMediaSession *ig_pSession; + IMFTopology *ig_pTopology; + RawImage *ig_RIFirst; + RawImage *ig_RISecond; + RawImage *ig_RIOut; + ImageGrabber(unsigned int deviceID); + HRESULT CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo); + HRESULT AddSourceNode( + IMFTopology *pTopology, + IMFMediaSource *pSource, + IMFPresentationDescriptor *pPD, + IMFStreamDescriptor *pSD, + IMFTopologyNode **ppNode); + HRESULT AddOutputNode( + IMFTopology *pTopology, + IMFActivate *pActivate, + DWORD dwId, + IMFTopologyNode **ppNode); + // IUnknown methods + STDMETHODIMP QueryInterface(REFIID iid, void** ppv); + STDMETHODIMP_(ULONG) AddRef(); + STDMETHODIMP_(ULONG) Release(); + // IMFClockStateSink methods + STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset); + STDMETHODIMP OnClockStop(MFTIME hnsSystemTime); + STDMETHODIMP OnClockPause(MFTIME hnsSystemTime); + STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime); + STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate); + // IMFSampleGrabberSinkCallback methods + STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock); + STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags, + LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer, + DWORD dwSampleSize); + STDMETHODIMP OnShutdown(); +}; +/// Class for controlling of thread of the grabbing raw data from video device +class ImageGrabberThread +{ + friend DWORD WINAPI MainThreadFunction( LPVOID lpParam ); +public: + ~ImageGrabberThread(void); + static HRESULT CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID); + void start(); + void stop(); + void setEmergencyStopEvent(void *userData, void(*func)(int, void *)); + ImageGrabber *getImageGrabber(); +protected: + virtual void run(); +private: + ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID); + HANDLE igt_Handle; + DWORD igt_ThreadIdArray; + ImageGrabber *igt_pImageGrabber; + emergensyStopEventCallback igt_func; + void *igt_userData; + bool igt_stop; + unsigned int igt_DeviceID; +}; +// Structure for collecting info about one parametr of current video device +struct Parametr +{ + long CurrentValue; + long Min; + long Max; + long Step; + long Default; + long Flag; + Parametr(); +}; +// Structure for collecting info about 17 parametrs of current video device +struct CamParametrs +{ + Parametr Brightness; + Parametr Contrast; + Parametr Hue; + Parametr Saturation; + Parametr Sharpness; + Parametr Gamma; + Parametr ColorEnable; + Parametr WhiteBalance; + Parametr BacklightCompensation; + Parametr Gain; + Parametr Pan; + Parametr Tilt; + Parametr Roll; + Parametr Zoom; + Parametr Exposure; + Parametr Iris; + Parametr Focus; +}; +typedef std::wstring String; +typedef std::vector vectorNum; +typedef std::map SUBTYPEMap; +typedef std::map FrameRateMap; +typedef void(*emergensyStopEventCallback)(int, void *); +/// Class for controlling of video device +class videoDevice +{ +public: + videoDevice(void); + ~videoDevice(void); + void closeDevice(); + CamParametrs getParametrs(); + void setParametrs(CamParametrs parametrs); + void setEmergencyStopEvent(void *userData, void(*func)(int, void *)); + long readInfoOfDevice(IMFActivate *pActivate, unsigned int Num); + wchar_t *getName(); + int getCountFormats(); + unsigned int getWidth(); + unsigned int getHeight(); + MediaType getFormat(unsigned int id); + bool setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate = 0); + bool setupDevice(unsigned int id); + bool isDeviceSetup(); + bool isDeviceMediaSource(); + bool isDeviceRawDataSource(); + bool isFrameNew(); + IMFMediaSource *getMediaSource(); + RawImage *getRawImageOut(); +private: + enum typeLock + { + MediaSourceLock, + RawDataLock, + OpenLock + } vd_LockOut; + wchar_t *vd_pFriendlyName; + ImageGrabberThread *vd_pImGrTh; + CamParametrs vd_PrevParametrs; + unsigned int vd_Width; + unsigned int vd_Height; + unsigned int vd_CurrentNumber; + bool vd_IsSetuped; + std::map vd_CaptureFormats; + std::vector vd_CurrentFormats; + IMFMediaSource *vd_pSource; + emergensyStopEventCallback vd_func; + void *vd_userData; + long enumerateCaptureFormats(IMFMediaSource *pSource); + long setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex); + void buildLibraryofTypes(); + int findType(unsigned int size, unsigned int frameRate = 0); + long resetDevice(IMFActivate *pActivate); + long initDevice(); + long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice); +}; +/// Class for managing of list of video devices +class videoDevices +{ +public: + ~videoDevices(void); + long initDevices(IMFAttributes *pAttributes); + static videoDevices& getInstance(); + videoDevice *getDevice(unsigned int i); + unsigned int getCount(); + void clearDevices(); +private: + UINT32 count; + std::vector vds_Devices; + videoDevices(void); +}; +// Class for creating of Media Foundation context +class Media_Foundation +{ +public: + virtual ~Media_Foundation(void); + static Media_Foundation& getInstance(); + bool buildListOfDevices(); +private: + Media_Foundation(void); +}; +/// The only visiable class for controlling of video devices in format singelton +class videoInput +{ +public: + virtual ~videoInput(void); + // Getting of static instance of videoInput class + static videoInput& getInstance(); + // Closing video device with deviceID + void closeDevice(int deviceID); + // Setting callback function for emergency events(for example: removing video device with deviceID) with userData + void setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *)); + // Closing all devices + void closeAllDevices(); + // Getting of parametrs of video device with deviceID + CamParametrs getParametrs(int deviceID); + // Setting of parametrs of video device with deviceID + void setParametrs(int deviceID, CamParametrs parametrs); + // Getting numbers of existence videodevices with listing in consol + unsigned int listDevices(bool silent = false); + // Getting numbers of formats, which are supported by videodevice with deviceID + unsigned int getCountFormats(int deviceID); + // Getting width of image, which is getting from videodevice with deviceID + unsigned int getWidth(int deviceID); + // Getting height of image, which is getting from videodevice with deviceID + unsigned int getHeight(int deviceID); + // Getting name of videodevice with deviceID + wchar_t *getNameVideoDevice(int deviceID); + // Getting interface MediaSource for Media Foundation from videodevice with deviceID + IMFMediaSource *getMediaSource(int deviceID); + // Getting format with id, which is supported by videodevice with deviceID + MediaType getFormat(int deviceID, int unsigned id); + // Checking of existence of the suitable video devices + bool isDevicesAcceable(); + // Checking of using the videodevice with deviceID + bool isDeviceSetup(int deviceID); + // Checking of using MediaSource from videodevice with deviceID + bool isDeviceMediaSource(int deviceID); + // Checking of using Raw Data of pixels from videodevice with deviceID + bool isDeviceRawDataSource(int deviceID); + // Setting of the state of outprinting info in console + static void setVerbose(bool state); + // Initialization of video device with deviceID by media type with id + bool setupDevice(int deviceID, unsigned int id = 0); + // Initialization of video device with deviceID by wisth w, height h and fps idealFramerate + bool setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate = 30); + // Checking of recivig of new frame from video device with deviceID + bool isFrameNew(int deviceID); + // Writing of Raw Data pixels from video device with deviceID with correction of RedAndBlue flipping flipRedAndBlue and vertical flipping flipImage + bool getPixels(int deviceID, unsigned char * pixels, bool flipRedAndBlue = false, bool flipImage = false); +private: + bool accessToDevices; + videoInput(void); + void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip); + void updateListOfDevices(); +}; +DebugPrintOut::DebugPrintOut(void):verbose(true) +{ +} +DebugPrintOut::~DebugPrintOut(void) +{ +} +DebugPrintOut& DebugPrintOut::getInstance() +{ + static DebugPrintOut instance; + return instance; +} +void DebugPrintOut::printOut(const wchar_t *format, ...) +{ + if(verbose) + { + int i = 0; + wchar_t *p = NULL; + va_list args; + va_start(args, format); + if(wcscmp(format, L"%i")) + { + i = va_arg (args, int); + } + if(wcscmp(format, L"%s")) + { + p = va_arg (args, wchar_t *); + } + wprintf(format, i,p); + va_end (args); + } +} +void DebugPrintOut::setVerbose(bool state) +{ + verbose = state; +} +LPCWSTR GetGUIDNameConstNew(const GUID& guid); +HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz); +HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index); +HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out); +unsigned int *GetParametr(GUID guid, MediaType &out) +{ + if(guid == MF_MT_YUV_MATRIX) + return &(out.MF_MT_YUV_MATRIX); + if(guid == MF_MT_VIDEO_LIGHTING) + return &(out.MF_MT_VIDEO_LIGHTING); + if(guid == MF_MT_DEFAULT_STRIDE) + return &(out.MF_MT_DEFAULT_STRIDE); + if(guid == MF_MT_VIDEO_CHROMA_SITING) + return &(out.MF_MT_VIDEO_CHROMA_SITING); + if(guid == MF_MT_VIDEO_NOMINAL_RANGE) + return &(out.MF_MT_VIDEO_NOMINAL_RANGE); + if(guid == MF_MT_ALL_SAMPLES_INDEPENDENT) + return &(out.MF_MT_ALL_SAMPLES_INDEPENDENT); + if(guid == MF_MT_FIXED_SIZE_SAMPLES) + return &(out.MF_MT_FIXED_SIZE_SAMPLES); + if(guid == MF_MT_SAMPLE_SIZE) + return &(out.MF_MT_SAMPLE_SIZE); + if(guid == MF_MT_VIDEO_PRIMARIES) + return &(out.MF_MT_VIDEO_PRIMARIES); + if(guid == MF_MT_INTERLACE_MODE) + return &(out.MF_MT_INTERLACE_MODE); + return NULL; +} +HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &out) +{ + WCHAR *pGuidName = NULL; + WCHAR *pGuidValName = NULL; + GUID guid = { 0 }; + PROPVARIANT var; + PropVariantInit(&var); + HRESULT hr = pAttr->GetItemByIndex(index, &guid, &var); + if (FAILED(hr)) + { + goto done; + } + hr = GetGUIDNameNew(guid, &pGuidName); + if (FAILED(hr)) + { + goto done; + } + hr = SpecialCaseAttributeValueNew(guid, var, out); + unsigned int *p; + if (FAILED(hr)) + { + goto done; + } + if (hr == S_FALSE) + { + switch (var.vt) + { + case VT_UI4: + p = GetParametr(guid, out); + if(p) + { + *p = var.ulVal; + } + break; + case VT_UI8: + break; + case VT_R8: + break; + case VT_CLSID: + if(guid == MF_MT_AM_FORMAT_TYPE) + { + hr = GetGUIDNameNew(*var.puuid, &pGuidValName); + if (SUCCEEDED(hr)) + { + out.MF_MT_AM_FORMAT_TYPE = MF_MT_AM_FORMAT_TYPE; + out.pMF_MT_AM_FORMAT_TYPEName = pGuidValName; + pGuidValName = NULL; + } + } + if(guid == MF_MT_MAJOR_TYPE) + { + hr = GetGUIDNameNew(*var.puuid, &pGuidValName); + if (SUCCEEDED(hr)) + { + out.MF_MT_MAJOR_TYPE = MF_MT_MAJOR_TYPE; + out.pMF_MT_MAJOR_TYPEName = pGuidValName; + pGuidValName = NULL; + } + } + if(guid == MF_MT_SUBTYPE) + { + hr = GetGUIDNameNew(*var.puuid, &pGuidValName); + if (SUCCEEDED(hr)) + { + out.MF_MT_SUBTYPE = MF_MT_SUBTYPE; + out.pMF_MT_SUBTYPEName = pGuidValName; + pGuidValName = NULL; + } + } + break; + case VT_LPWSTR: + break; + case VT_VECTOR | VT_UI1: + break; + case VT_UNKNOWN: + break; + default: + break; + } + } +done: + CoTaskMemFree(pGuidName); + CoTaskMemFree(pGuidValName); + PropVariantClear(&var); + return hr; +} +HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz) +{ + HRESULT hr = S_OK; + WCHAR *pName = NULL; + LPCWSTR pcwsz = GetGUIDNameConstNew(guid); + if (pcwsz) + { + size_t cchLength = 0; + hr = StringCchLengthW(pcwsz, STRSAFE_MAX_CCH, &cchLength); + if (FAILED(hr)) + { + goto done; + } + pName = (WCHAR*)CoTaskMemAlloc((cchLength + 1) * sizeof(WCHAR)); + if (pName == NULL) + { + hr = E_OUTOFMEMORY; + goto done; + } + hr = StringCchCopyW(pName, cchLength + 1, pcwsz); + if (FAILED(hr)) + { + goto done; + } + } + else + { + hr = StringFromCLSID(guid, &pName); + } +done: + if (FAILED(hr)) + { + *ppwsz = NULL; + CoTaskMemFree(pName); + } + else + { + *ppwsz = pName; + } + return hr; +} +void LogUINT32AsUINT64New(const PROPVARIANT& var, UINT32 &uHigh, UINT32 &uLow) +{ + Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow); +} +float OffsetToFloatNew(const MFOffset& offset) +{ + return offset.value + (static_cast(offset.fract) / 65536.0f); +} +HRESULT LogVideoAreaNew(const PROPVARIANT& var) +{ + if (var.caub.cElems < sizeof(MFVideoArea)) + { + return S_OK; + } + return S_OK; +} +HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out) +{ + if (guid == MF_MT_FRAME_SIZE) + { + UINT32 uHigh = 0, uLow = 0; + LogUINT32AsUINT64New(var, uHigh, uLow); + out.width = uHigh; + out.height = uLow; + out.MF_MT_FRAME_SIZE = out.width * out.height; + } + else + if (guid == MF_MT_FRAME_RATE) + { + UINT32 uHigh = 0, uLow = 0; + LogUINT32AsUINT64New(var, uHigh, uLow); + out.MF_MT_FRAME_RATE = uHigh; + out.MF_MT_FRAME_RATE_low = uLow; + } + else + if (guid == MF_MT_FRAME_RATE_RANGE_MAX) + { + UINT32 uHigh = 0, uLow = 0; + LogUINT32AsUINT64New(var, uHigh, uLow); + out.MF_MT_FRAME_RATE_RANGE_MAX = uHigh; + out.MF_MT_FRAME_RATE_RANGE_MAX_low = uLow; + } + else + if (guid == MF_MT_FRAME_RATE_RANGE_MIN) + { + UINT32 uHigh = 0, uLow = 0; + LogUINT32AsUINT64New(var, uHigh, uLow); + out.MF_MT_FRAME_RATE_RANGE_MIN = uHigh; + out.MF_MT_FRAME_RATE_RANGE_MIN_low = uLow; + } + else + if (guid == MF_MT_PIXEL_ASPECT_RATIO) + { + UINT32 uHigh = 0, uLow = 0; + LogUINT32AsUINT64New(var, uHigh, uLow); + out.MF_MT_PIXEL_ASPECT_RATIO = uHigh; + out.MF_MT_PIXEL_ASPECT_RATIO_low = uLow; + } + else + { + return S_FALSE; + } + return S_OK; +} +#ifndef IF_EQUAL_RETURN +#define IF_EQUAL_RETURN(param, val) if(val == param) return L#val +#endif +LPCWSTR GetGUIDNameConstNew(const GUID& guid) +{ + IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE); + IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE); + IF_EQUAL_RETURN(guid, MF_MT_SUBTYPE); + IF_EQUAL_RETURN(guid, MF_MT_ALL_SAMPLES_INDEPENDENT); + IF_EQUAL_RETURN(guid, MF_MT_FIXED_SIZE_SAMPLES); + IF_EQUAL_RETURN(guid, MF_MT_COMPRESSED); + IF_EQUAL_RETURN(guid, MF_MT_SAMPLE_SIZE); + IF_EQUAL_RETURN(guid, MF_MT_WRAPPED_TYPE); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_NUM_CHANNELS); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_SECOND); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_AVG_BYTES_PER_SECOND); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BLOCK_ALIGNMENT); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BITS_PER_SAMPLE); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_VALID_BITS_PER_SAMPLE); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_BLOCK); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_CHANNEL_MASK); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FOLDDOWN_MATRIX); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKREF); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKTARGET); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGREF); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGTARGET); + IF_EQUAL_RETURN(guid, MF_MT_AUDIO_PREFER_WAVEFORMATEX); + IF_EQUAL_RETURN(guid, MF_MT_AAC_PAYLOAD_TYPE); + IF_EQUAL_RETURN(guid, MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION); + IF_EQUAL_RETURN(guid, MF_MT_FRAME_SIZE); + IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE); + IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MAX); + IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MIN); + IF_EQUAL_RETURN(guid, MF_MT_PIXEL_ASPECT_RATIO); + IF_EQUAL_RETURN(guid, MF_MT_DRM_FLAGS); + IF_EQUAL_RETURN(guid, MF_MT_PAD_CONTROL_FLAGS); + IF_EQUAL_RETURN(guid, MF_MT_SOURCE_CONTENT_HINT); + IF_EQUAL_RETURN(guid, MF_MT_VIDEO_CHROMA_SITING); + IF_EQUAL_RETURN(guid, MF_MT_INTERLACE_MODE); + IF_EQUAL_RETURN(guid, MF_MT_TRANSFER_FUNCTION); + IF_EQUAL_RETURN(guid, MF_MT_VIDEO_PRIMARIES); + IF_EQUAL_RETURN(guid, MF_MT_CUSTOM_VIDEO_PRIMARIES); + IF_EQUAL_RETURN(guid, MF_MT_YUV_MATRIX); + IF_EQUAL_RETURN(guid, MF_MT_VIDEO_LIGHTING); + IF_EQUAL_RETURN(guid, MF_MT_VIDEO_NOMINAL_RANGE); + IF_EQUAL_RETURN(guid, MF_MT_GEOMETRIC_APERTURE); + IF_EQUAL_RETURN(guid, MF_MT_MINIMUM_DISPLAY_APERTURE); + IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_APERTURE); + IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_ENABLED); + IF_EQUAL_RETURN(guid, MF_MT_AVG_BITRATE); + IF_EQUAL_RETURN(guid, MF_MT_AVG_BIT_ERROR_RATE); + IF_EQUAL_RETURN(guid, MF_MT_MAX_KEYFRAME_SPACING); + IF_EQUAL_RETURN(guid, MF_MT_DEFAULT_STRIDE); + IF_EQUAL_RETURN(guid, MF_MT_PALETTE); + IF_EQUAL_RETURN(guid, MF_MT_USER_DATA); + IF_EQUAL_RETURN(guid, MF_MT_AM_FORMAT_TYPE); + IF_EQUAL_RETURN(guid, MF_MT_MPEG_START_TIME_CODE); + IF_EQUAL_RETURN(guid, MF_MT_MPEG2_PROFILE); + IF_EQUAL_RETURN(guid, MF_MT_MPEG2_LEVEL); + IF_EQUAL_RETURN(guid, MF_MT_MPEG2_FLAGS); + IF_EQUAL_RETURN(guid, MF_MT_MPEG_SEQUENCE_HEADER); + IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_0); + IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_0); + IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_1); + IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_1); + IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_SRC_PACK); + IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_CTRL_PACK); + IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_HEADER); + IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_FORMAT); + IF_EQUAL_RETURN(guid, MF_MT_IMAGE_LOSS_TOLERANT); + IF_EQUAL_RETURN(guid, MF_MT_MPEG4_SAMPLE_DESCRIPTION); + IF_EQUAL_RETURN(guid, MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY); + IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_4CC); + IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_WAVE_FORMAT_TAG); + // Media types + IF_EQUAL_RETURN(guid, MFMediaType_Audio); + IF_EQUAL_RETURN(guid, MFMediaType_Video); + IF_EQUAL_RETURN(guid, MFMediaType_Protected); + IF_EQUAL_RETURN(guid, MFMediaType_SAMI); + IF_EQUAL_RETURN(guid, MFMediaType_Script); + IF_EQUAL_RETURN(guid, MFMediaType_Image); + IF_EQUAL_RETURN(guid, MFMediaType_HTML); + IF_EQUAL_RETURN(guid, MFMediaType_Binary); + IF_EQUAL_RETURN(guid, MFMediaType_FileTransfer); + IF_EQUAL_RETURN(guid, MFVideoFormat_AI44); // FCC('AI44') + IF_EQUAL_RETURN(guid, MFVideoFormat_ARGB32); // D3DFMT_A8R8G8B8 + IF_EQUAL_RETURN(guid, MFVideoFormat_AYUV); // FCC('AYUV') + IF_EQUAL_RETURN(guid, MFVideoFormat_DV25); // FCC('dv25') + IF_EQUAL_RETURN(guid, MFVideoFormat_DV50); // FCC('dv50') + IF_EQUAL_RETURN(guid, MFVideoFormat_DVH1); // FCC('dvh1') + IF_EQUAL_RETURN(guid, MFVideoFormat_DVSD); // FCC('dvsd') + IF_EQUAL_RETURN(guid, MFVideoFormat_DVSL); // FCC('dvsl') + IF_EQUAL_RETURN(guid, MFVideoFormat_H264); // FCC('H264') + IF_EQUAL_RETURN(guid, MFVideoFormat_I420); // FCC('I420') + IF_EQUAL_RETURN(guid, MFVideoFormat_IYUV); // FCC('IYUV') + IF_EQUAL_RETURN(guid, MFVideoFormat_M4S2); // FCC('M4S2') + IF_EQUAL_RETURN(guid, MFVideoFormat_MJPG); + IF_EQUAL_RETURN(guid, MFVideoFormat_MP43); // FCC('MP43') + IF_EQUAL_RETURN(guid, MFVideoFormat_MP4S); // FCC('MP4S') + IF_EQUAL_RETURN(guid, MFVideoFormat_MP4V); // FCC('MP4V') + IF_EQUAL_RETURN(guid, MFVideoFormat_MPG1); // FCC('MPG1') + IF_EQUAL_RETURN(guid, MFVideoFormat_MSS1); // FCC('MSS1') + IF_EQUAL_RETURN(guid, MFVideoFormat_MSS2); // FCC('MSS2') + IF_EQUAL_RETURN(guid, MFVideoFormat_NV11); // FCC('NV11') + IF_EQUAL_RETURN(guid, MFVideoFormat_NV12); // FCC('NV12') + IF_EQUAL_RETURN(guid, MFVideoFormat_P010); // FCC('P010') + IF_EQUAL_RETURN(guid, MFVideoFormat_P016); // FCC('P016') + IF_EQUAL_RETURN(guid, MFVideoFormat_P210); // FCC('P210') + IF_EQUAL_RETURN(guid, MFVideoFormat_P216); // FCC('P216') + IF_EQUAL_RETURN(guid, MFVideoFormat_RGB24); // D3DFMT_R8G8B8 + IF_EQUAL_RETURN(guid, MFVideoFormat_RGB32); // D3DFMT_X8R8G8B8 + IF_EQUAL_RETURN(guid, MFVideoFormat_RGB555); // D3DFMT_X1R5G5B5 + IF_EQUAL_RETURN(guid, MFVideoFormat_RGB565); // D3DFMT_R5G6B5 + IF_EQUAL_RETURN(guid, MFVideoFormat_RGB8); + IF_EQUAL_RETURN(guid, MFVideoFormat_UYVY); // FCC('UYVY') + IF_EQUAL_RETURN(guid, MFVideoFormat_v210); // FCC('v210') + IF_EQUAL_RETURN(guid, MFVideoFormat_v410); // FCC('v410') + IF_EQUAL_RETURN(guid, MFVideoFormat_WMV1); // FCC('WMV1') + IF_EQUAL_RETURN(guid, MFVideoFormat_WMV2); // FCC('WMV2') + IF_EQUAL_RETURN(guid, MFVideoFormat_WMV3); // FCC('WMV3') + IF_EQUAL_RETURN(guid, MFVideoFormat_WVC1); // FCC('WVC1') + IF_EQUAL_RETURN(guid, MFVideoFormat_Y210); // FCC('Y210') + IF_EQUAL_RETURN(guid, MFVideoFormat_Y216); // FCC('Y216') + IF_EQUAL_RETURN(guid, MFVideoFormat_Y410); // FCC('Y410') + IF_EQUAL_RETURN(guid, MFVideoFormat_Y416); // FCC('Y416') + IF_EQUAL_RETURN(guid, MFVideoFormat_Y41P); + IF_EQUAL_RETURN(guid, MFVideoFormat_Y41T); + IF_EQUAL_RETURN(guid, MFVideoFormat_YUY2); // FCC('YUY2') + IF_EQUAL_RETURN(guid, MFVideoFormat_YV12); // FCC('YV12') + IF_EQUAL_RETURN(guid, MFVideoFormat_YVYU); + IF_EQUAL_RETURN(guid, MFAudioFormat_PCM); // WAVE_FORMAT_PCM + IF_EQUAL_RETURN(guid, MFAudioFormat_Float); // WAVE_FORMAT_IEEE_FLOAT + IF_EQUAL_RETURN(guid, MFAudioFormat_DTS); // WAVE_FORMAT_DTS + IF_EQUAL_RETURN(guid, MFAudioFormat_Dolby_AC3_SPDIF); // WAVE_FORMAT_DOLBY_AC3_SPDIF + IF_EQUAL_RETURN(guid, MFAudioFormat_DRM); // WAVE_FORMAT_DRM + IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV8); // WAVE_FORMAT_WMAUDIO2 + IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV9); // WAVE_FORMAT_WMAUDIO3 + IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudio_Lossless); // WAVE_FORMAT_WMAUDIO_LOSSLESS + IF_EQUAL_RETURN(guid, MFAudioFormat_WMASPDIF); // WAVE_FORMAT_WMASPDIF + IF_EQUAL_RETURN(guid, MFAudioFormat_MSP1); // WAVE_FORMAT_WMAVOICE9 + IF_EQUAL_RETURN(guid, MFAudioFormat_MP3); // WAVE_FORMAT_MPEGLAYER3 + IF_EQUAL_RETURN(guid, MFAudioFormat_MPEG); // WAVE_FORMAT_MPEG + IF_EQUAL_RETURN(guid, MFAudioFormat_AAC); // WAVE_FORMAT_MPEG_HEAAC + IF_EQUAL_RETURN(guid, MFAudioFormat_ADTS); // WAVE_FORMAT_MPEG_ADTS_AAC + return NULL; +} +FormatReader::FormatReader(void) +{ +} +MediaType FormatReader::Read(IMFMediaType *pType) +{ + UINT32 count = 0; + HRESULT hr = S_OK; + MediaType out; + hr = pType->LockStore(); + if (FAILED(hr)) + { + return out; + } + hr = pType->GetCount(&count); + if (FAILED(hr)) + { + return out; + } + for (UINT32 i = 0; i < count; i++) + { + hr = LogAttributeValueByIndexNew(pType, i, out); + if (FAILED(hr)) + { + break; + } + } + hr = pType->UnlockStore(); + if (FAILED(hr)) + { + return out; + } + return out; +} +FormatReader::~FormatReader(void) +{ +} +#define CHECK_HR(x) if (FAILED(x)) { goto done; } +ImageGrabber::ImageGrabber(unsigned int deviceID): m_cRef(1), ig_DeviceID(deviceID), ig_pSource(NULL), ig_pSession(NULL), ig_pTopology(NULL), ig_RIE(true), ig_Close(false) +{ +} +ImageGrabber::~ImageGrabber(void) +{ + if (ig_pSession) + { + ig_pSession->Shutdown(); + } + //SafeRelease(&ig_pSession); + //SafeRelease(&ig_pTopology); + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroing instance of the ImageGrabber class \n", ig_DeviceID); +} +HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat) +{ + IMFActivate *pSinkActivate = NULL; + IMFMediaType *pType = NULL; + IMFPresentationDescriptor *pPD = NULL; + IMFStreamDescriptor *pSD = NULL; + IMFMediaTypeHandler *pHandler = NULL; + IMFMediaType *pCurrentType = NULL; + HRESULT hr = S_OK; + MediaType MT; + // Clean up. + if (ig_pSession) + { + ig_pSession->Shutdown(); + } + SafeRelease(&ig_pSession); + SafeRelease(&ig_pTopology); + ig_pSource = pSource; + hr = pSource->CreatePresentationDescriptor(&pPD); + if (FAILED(hr)) + goto err; + BOOL fSelected; + hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD); + if (FAILED(hr)) + goto err; + hr = pSD->GetMediaTypeHandler(&pHandler); + if (FAILED(hr)) + goto err; + DWORD cTypes = 0; + hr = pHandler->GetMediaTypeCount(&cTypes); + if (FAILED(hr)) + goto err; + if(cTypes > 0) + { + hr = pHandler->GetCurrentMediaType(&pCurrentType); + if (FAILED(hr)) + goto err; + MT = FormatReader::Read(pCurrentType); + } +err: + SafeRelease(&pPD); + SafeRelease(&pSD); + SafeRelease(&pHandler); + SafeRelease(&pCurrentType); + unsigned int sizeRawImage = 0; + if(VideoFormat == MFVideoFormat_RGB24) + { + sizeRawImage = MT.MF_MT_FRAME_SIZE * 3; + } + else if(VideoFormat == MFVideoFormat_RGB32) + { + sizeRawImage = MT.MF_MT_FRAME_SIZE * 4; + } + CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, sizeRawImage)); + CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, sizeRawImage)); + ig_RIOut = ig_RISecond; + // Configure the media type that the Sample Grabber will receive. + // Setting the major and subtype is usually enough for the topology loader + // to resolve the topology. + CHECK_HR(hr = MFCreateMediaType(&pType)); + CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); + CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, VideoFormat)); + // Create the sample grabber sink. + CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType, this, &pSinkActivate)); + // To run as fast as possible, set this attribute (requires Windows 7): + CHECK_HR(hr = pSinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE)); + // Create the Media Session. + CHECK_HR(hr = MFCreateMediaSession(NULL, &ig_pSession)); + // Create the topology. + CHECK_HR(hr = CreateTopology(pSource, pSinkActivate, &ig_pTopology)); +done: + // Clean up. + if (FAILED(hr)) + { + if (ig_pSession) + { + ig_pSession->Shutdown(); + } + SafeRelease(&ig_pSession); + SafeRelease(&ig_pTopology); + } + SafeRelease(&pSinkActivate); + SafeRelease(&pType); + return hr; +} +void ImageGrabber::stopGrabbing() +{ + if(ig_pSession) + ig_pSession->Stop(); + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID); +} +HRESULT ImageGrabber::startGrabbing(void) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + IMFMediaEvent *pEvent = NULL; + PROPVARIANT var; + PropVariantInit(&var); + HRESULT hr = S_OK; + CHECK_HR(hr = ig_pSession->SetTopology(0, ig_pTopology)); + CHECK_HR(hr = ig_pSession->Start(&GUID_NULL, &var)); + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID); + for(;;) + { + HRESULT hrStatus = S_OK; + MediaEventType met; + if(!ig_pSession) break; + hr = ig_pSession->GetEvent(0, &pEvent); + if(!SUCCEEDED(hr)) + { + hr = S_OK; + goto done; + } + hr = pEvent->GetStatus(&hrStatus); + if(!SUCCEEDED(hr)) + { + hr = S_OK; + goto done; + } + hr = pEvent->GetType(&met); + if(!SUCCEEDED(hr)) + { + hr = S_OK; + goto done; + } + if (met == MESessionEnded) + { + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded \n", ig_DeviceID); + ig_pSession->Stop(); + break; + } + if (met == MESessionStopped) + { + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID); + break; + } + if (met == MEVideoCaptureDeviceRemoved) + { + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID); + break; + } + SafeRelease(&pEvent); + } + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID); +done: + SafeRelease(&pEvent); + SafeRelease(&ig_pSession); + SafeRelease(&ig_pTopology); + return hr; +} +HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo) +{ + IMFTopology *pTopology = NULL; + IMFPresentationDescriptor *pPD = NULL; + IMFStreamDescriptor *pSD = NULL; + IMFMediaTypeHandler *pHandler = NULL; + IMFTopologyNode *pNode1 = NULL; + IMFTopologyNode *pNode2 = NULL; + HRESULT hr = S_OK; + DWORD cStreams = 0; + CHECK_HR(hr = MFCreateTopology(&pTopology)); + CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD)); + CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams)); + for (DWORD i = 0; i < cStreams; i++) + { + // In this example, we look for audio streams and connect them to the sink. + BOOL fSelected = FALSE; + GUID majorType; + CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD)); + CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler)); + CHECK_HR(hr = pHandler->GetMajorType(&majorType)); + if (majorType == MFMediaType_Video && fSelected) + { + CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pNode1)); + CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, &pNode2)); + CHECK_HR(hr = pNode1->ConnectOutput(0, pNode2, 0)); + break; + } + else + { + CHECK_HR(hr = pPD->DeselectStream(i)); + } + SafeRelease(&pSD); + SafeRelease(&pHandler); + } + *ppTopo = pTopology; + (*ppTopo)->AddRef(); +done: + SafeRelease(&pTopology); + SafeRelease(&pNode1); + SafeRelease(&pNode2); + SafeRelease(&pPD); + SafeRelease(&pSD); + SafeRelease(&pHandler); + return hr; +} +HRESULT ImageGrabber::AddSourceNode( + IMFTopology *pTopology, // Topology. + IMFMediaSource *pSource, // Media source. + IMFPresentationDescriptor *pPD, // Presentation descriptor. + IMFStreamDescriptor *pSD, // Stream descriptor. + IMFTopologyNode **ppNode) // Receives the node pointer. +{ + IMFTopologyNode *pNode = NULL; + HRESULT hr = S_OK; + CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode)); + CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource)); + CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD)); + CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD)); + CHECK_HR(hr = pTopology->AddNode(pNode)); + // Return the pointer to the caller. + *ppNode = pNode; + (*ppNode)->AddRef(); +done: + SafeRelease(&pNode); + return hr; +} +HRESULT ImageGrabber::AddOutputNode( + IMFTopology *pTopology, // Topology. + IMFActivate *pActivate, // Media sink activation object. + DWORD dwId, // Identifier of the stream sink. + IMFTopologyNode **ppNode) // Receives the node pointer. +{ + IMFTopologyNode *pNode = NULL; + HRESULT hr = S_OK; + CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode)); + CHECK_HR(hr = pNode->SetObject(pActivate)); + CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId)); + CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE)); + CHECK_HR(hr = pTopology->AddNode(pNode)); + // Return the pointer to the caller. + *ppNode = pNode; + (*ppNode)->AddRef(); +done: + SafeRelease(&pNode); + return hr; +} +HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID) +{ + *ppIG = new (std::nothrow) ImageGrabber(deviceID); + if (ppIG == NULL) + { + return E_OUTOFMEMORY; + } + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID); + return S_OK; +} +STDMETHODIMP ImageGrabber::QueryInterface(REFIID riid, void** ppv) +{ + HRESULT hr = E_NOINTERFACE; + *ppv = NULL; + if(riid == IID_IUnknown || riid == IID_IMFSampleGrabberSinkCallback) + { + *ppv = static_cast(this); + hr = S_OK; + } + if(riid == IID_IMFClockStateSink) + { + *ppv = static_cast(this); + hr = S_OK; + } + if(SUCCEEDED(hr)) + { + reinterpret_cast(*ppv)->AddRef(); + } + return hr; +} +STDMETHODIMP_(ULONG) ImageGrabber::AddRef() +{ + return InterlockedIncrement(&m_cRef); +} +STDMETHODIMP_(ULONG) ImageGrabber::Release() +{ + ULONG cRef = InterlockedDecrement(&m_cRef); + if (cRef == 0) + { + delete this; + } + return cRef; +} +STDMETHODIMP ImageGrabber::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) +{ + (void)hnsSystemTime; + (void)llClockStartOffset; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnClockStop(MFTIME hnsSystemTime) +{ + (void)hnsSystemTime; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnClockPause(MFTIME hnsSystemTime) +{ + (void)hnsSystemTime; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnClockRestart(MFTIME hnsSystemTime) +{ + (void)hnsSystemTime; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnClockSetRate(MFTIME hnsSystemTime, float flRate) +{ + (void)flRate; + (void)hnsSystemTime; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnSetPresentationClock(IMFPresentationClock* pClock) +{ + (void)pClock; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags, + LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer, + DWORD dwSampleSize) +{ + (void)guidMajorMediaType; + (void)llSampleTime; + (void)dwSampleFlags; + (void)llSampleDuration; + (void)dwSampleSize; + if(ig_RIE) + { + ig_RIFirst->fastCopy(pSampleBuffer); + ig_RIOut = ig_RIFirst; + } + else + { + ig_RISecond->fastCopy(pSampleBuffer); + ig_RIOut = ig_RISecond; + } + ig_RIE = !ig_RIE; + return S_OK; +} +STDMETHODIMP ImageGrabber::OnShutdown() +{ + return S_OK; +} +RawImage *ImageGrabber::getRawImage() +{ + return ig_RIOut; +} +DWORD WINAPI MainThreadFunction( LPVOID lpParam ) +{ + ImageGrabberThread *pIGT = (ImageGrabberThread *)lpParam; + pIGT->run(); + return 0; +} +HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + *ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID); + if (ppIGT == NULL) + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID); + return E_OUTOFMEMORY; + } + else + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID); + return S_OK; +} +ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID): igt_Handle(NULL), igt_stop(false) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID); + igt_DeviceID = deviceID; + if(SUCCEEDED(hr)) + { + hr = igt_pImageGrabber->initImageGrabber(pSource, MFVideoFormat_RGB24); + if(!SUCCEEDED(hr)) + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID); + } + else + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID); + } + } + else + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i There is a problem with creation of the instance of the ImageGrabber class\n", deviceID); + } +} +void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int, void *)) +{ + if(func) + { + igt_func = func; + igt_userData = userData; + } +} +ImageGrabberThread::~ImageGrabberThread(void) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID); + delete igt_pImageGrabber; +} +void ImageGrabberThread::stop() +{ + igt_stop = true; + if(igt_pImageGrabber) + { + igt_pImageGrabber->stopGrabbing(); + } +} +void ImageGrabberThread::start() +{ + igt_Handle = CreateThread( + NULL, // default security attributes + 0, // use default stack size + MainThreadFunction, // thread function name + this, // argument to thread function + 0, // use default creation flags + &igt_ThreadIdArray); // returns the thread identifier +} +void ImageGrabberThread::run() +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if(igt_pImageGrabber) + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID); + HRESULT hr = igt_pImageGrabber->startGrabbing(); + if(!SUCCEEDED(hr)) + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID); + } + } + else + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID); + } + if(!igt_stop) + { + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID); + if(igt_func) + { + igt_func(igt_DeviceID, igt_userData); + } + } + else + DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID); +} +ImageGrabber *ImageGrabberThread::getImageGrabber() +{ + return igt_pImageGrabber; +} +Media_Foundation::Media_Foundation(void) +{ + HRESULT hr = MFStartup(MF_VERSION); + if(!SUCCEEDED(hr)) + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"MEDIA FOUNDATION: It cannot be created!!!\n"); + } +} +Media_Foundation::~Media_Foundation(void) +{ + HRESULT hr = MFShutdown(); + if(!SUCCEEDED(hr)) + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"MEDIA FOUNDATION: Resources cannot be released\n"); + } +} +bool Media_Foundation::buildListOfDevices() +{ + HRESULT hr = S_OK; + IMFAttributes *pAttributes = NULL; + CoInitialize(NULL); + hr = MFCreateAttributes(&pAttributes, 1); + if (SUCCEEDED(hr)) + { + hr = pAttributes->SetGUID( + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID + ); + } + if (SUCCEEDED(hr)) + { + videoDevices *vDs = &videoDevices::getInstance(); + hr = vDs->initDevices(pAttributes); + } + else + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n"); + } + SafeRelease(&pAttributes); + return (SUCCEEDED(hr)); +} +Media_Foundation& Media_Foundation::getInstance() +{ + static Media_Foundation instance; + return instance; +} +RawImage::RawImage(unsigned int size): ri_new(false), ri_pixels(NULL) +{ + ri_size = size; + ri_pixels = new unsigned char[size]; + memset((void *)ri_pixels,0,ri_size); +} +bool RawImage::isNew() +{ + return ri_new; +} +unsigned int RawImage::getSize() +{ + return ri_size; +} +RawImage::~RawImage(void) +{ + delete []ri_pixels; + ri_pixels = NULL; +} +long RawImage::CreateInstance(RawImage **ppRImage,unsigned int size) +{ + *ppRImage = new (std::nothrow) RawImage(size); + if (ppRImage == NULL) + { + return E_OUTOFMEMORY; + } + return S_OK; +} +void RawImage::setCopy(const BYTE * pSampleBuffer) +{ + memcpy(ri_pixels, pSampleBuffer, ri_size); + ri_new = true; +} +void RawImage::fastCopy(const BYTE * pSampleBuffer) +{ + memcpy(ri_pixels, pSampleBuffer, ri_size); + ri_new = true; +} +unsigned char * RawImage::getpPixels() +{ + ri_new = false; + return ri_pixels; +} +videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL), + vd_Width(0), vd_Height(0), vd_pSource(NULL), vd_func(NULL), vd_userData(NULL) +{ +} +void videoDevice::setParametrs(CamParametrs parametrs) +{ + if(vd_IsSetuped) + { + if(vd_pSource) + { + Parametr *pParametr = (Parametr *)(¶metrs); + Parametr *pPrevParametr = (Parametr *)(&vd_PrevParametrs); + IAMVideoProcAmp *pProcAmp = NULL; + HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp)); + if (SUCCEEDED(hr)) + { + for(unsigned int i = 0; i < 10; i++) + { + if(pPrevParametr[i].CurrentValue != pParametr[i].CurrentValue || pPrevParametr[i].Flag != pParametr[i].Flag) + hr = pProcAmp->Set(VideoProcAmp_Brightness + i, pParametr[i].CurrentValue, pParametr[i].Flag); + } + pProcAmp->Release(); + } + IAMCameraControl *pProcControl = NULL; + hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl)); + if (SUCCEEDED(hr)) + { + for(unsigned int i = 0; i < 7; i++) + { + if(pPrevParametr[10 + i].CurrentValue != pParametr[10 + i].CurrentValue || pPrevParametr[10 + i].Flag != pParametr[10 + i].Flag) + hr = pProcControl->Set(CameraControl_Pan+i, pParametr[10 + i].CurrentValue, pParametr[10 + i].Flag); + } + pProcControl->Release(); + } + vd_PrevParametrs = parametrs; + } + } +} +CamParametrs videoDevice::getParametrs() +{ + CamParametrs out; + if(vd_IsSetuped) + { + if(vd_pSource) + { + Parametr *pParametr = (Parametr *)(&out); + IAMVideoProcAmp *pProcAmp = NULL; + HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp)); + if (SUCCEEDED(hr)) + { + for(unsigned int i = 0; i < 10; i++) + { + Parametr temp; + hr = pProcAmp->GetRange(VideoProcAmp_Brightness+i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag); + if (SUCCEEDED(hr)) + { + temp.CurrentValue = temp.Default; + pParametr[i] = temp; + } + } + pProcAmp->Release(); + } + IAMCameraControl *pProcControl = NULL; + hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl)); + if (SUCCEEDED(hr)) + { + for(unsigned int i = 0; i < 7; i++) + { + Parametr temp; + hr = pProcControl->GetRange(CameraControl_Pan+i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag); + if (SUCCEEDED(hr)) + { + temp.CurrentValue = temp.Default; + pParametr[10 + i] = temp; + } + } + pProcControl->Release(); + } + } + } + return out; +} +long videoDevice::resetDevice(IMFActivate *pActivate) +{ + HRESULT hr = -1; + vd_CurrentFormats.clear(); + if(vd_pFriendlyName) + CoTaskMemFree(vd_pFriendlyName); + vd_pFriendlyName = NULL; + if(pActivate) + { + IMFMediaSource *pSource = NULL; + hr = pActivate->GetAllocatedString( + MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, + &vd_pFriendlyName, + NULL + ); + hr = pActivate->ActivateObject( + __uuidof(IMFMediaSource), + (void**)&pSource + ); + enumerateCaptureFormats(pSource); + buildLibraryofTypes(); + SafeRelease(&pSource); + if(FAILED(hr)) + { + vd_pFriendlyName = NULL; + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber); + } + } + return hr; +} +long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num) +{ + HRESULT hr = -1; + vd_CurrentNumber = Num; + hr = resetDevice(pActivate); + return hr; +} +long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice) +{ + HRESULT hr = S_OK; + IMFActivate **ppDevices = NULL; + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + UINT32 count; + wchar_t *newFriendlyName = NULL; + hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); + if (SUCCEEDED(hr)) + { + if(count > 0) + { + if(count > vd_CurrentNumber) + { + hr = ppDevices[vd_CurrentNumber]->GetAllocatedString( + MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, + &newFriendlyName, + NULL + ); + if (SUCCEEDED(hr)) + { + if(wcscmp(newFriendlyName, vd_pFriendlyName) != 0) + { + DPO->printOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber); + hr = -1; + pDevice = NULL; + } + else + { + *pDevice = ppDevices[vd_CurrentNumber]; + (*pDevice)->AddRef(); + } + } + else + { + DPO->printOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber); + } + } + else + { + DPO->printOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber); + hr = -1; + } + for(UINT32 i = 0; i < count; i++) + { + SafeRelease(&ppDevices[i]); + } + SafeRelease(ppDevices); + } + else + hr = -1; + } + else + { + DPO->printOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber); + } + return hr; +} +long videoDevice::initDevice() +{ + HRESULT hr = -1; + IMFAttributes *pAttributes = NULL; + IMFActivate * vd_pActivate= NULL; + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + CoInitialize(NULL); + hr = MFCreateAttributes(&pAttributes, 1); + if (SUCCEEDED(hr)) + { + hr = pAttributes->SetGUID( + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID + ); + } + if (SUCCEEDED(hr)) + { + hr = checkDevice(pAttributes, &vd_pActivate); + if (SUCCEEDED(hr) && vd_pActivate) + { + SafeRelease(&vd_pSource); + hr = vd_pActivate->ActivateObject( + __uuidof(IMFMediaSource), + (void**)&vd_pSource + ); + if (SUCCEEDED(hr)) + { + } + SafeRelease(&vd_pActivate); + } + else + { + DPO->printOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber); + } + } + else + { + DPO->printOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber); + } + SafeRelease(&pAttributes); + return hr; +} +MediaType videoDevice::getFormat(unsigned int id) +{ + if(id < vd_CurrentFormats.size()) + { + return vd_CurrentFormats[id]; + } + else return MediaType(); +} +int videoDevice::getCountFormats() +{ + return vd_CurrentFormats.size(); +} +void videoDevice::setEmergencyStopEvent(void *userData, void(*func)(int, void *)) +{ + vd_func = func; + vd_userData = userData; +} +void videoDevice::closeDevice() +{ + if(vd_IsSetuped) + { + vd_IsSetuped = false; + vd_pSource->Stop(); + SafeRelease(&vd_pSource); + if(vd_LockOut == RawDataLock) + { + vd_pImGrTh->stop(); + Sleep(500); + delete vd_pImGrTh; + } + vd_pImGrTh = NULL; + vd_LockOut = OpenLock; + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber); + } +} +unsigned int videoDevice::getWidth() +{ + if(vd_IsSetuped) + return vd_Width; + else + return 0; +} +unsigned int videoDevice::getHeight() +{ + if(vd_IsSetuped) + return vd_Height; + else + return 0; +} +IMFMediaSource *videoDevice::getMediaSource() +{ + IMFMediaSource *out = NULL; + if(vd_LockOut == OpenLock) + { + vd_LockOut = MediaSourceLock; + out = vd_pSource; + } + return out; +} +int videoDevice::findType(unsigned int size, unsigned int frameRate) +{ + if(vd_CaptureFormats.size() == 0) + return 0; + FrameRateMap FRM = vd_CaptureFormats[size]; + if(FRM.size() == 0) + return 0; + UINT64 frameRateMax = 0; SUBTYPEMap STMMax; + if(frameRate == 0) + { + std::map::iterator f = FRM.begin(); + for(; f != FRM.end(); f++) + { + if((*f).first >= frameRateMax) + { + frameRateMax = (*f).first; + STMMax = (*f).second; + } + } + } + else + { + std::map::iterator f = FRM.begin(); + for(; f != FRM.end(); f++) + { + if((*f).first >= frameRateMax) + { + if(frameRate > (*f).first) + { + frameRateMax = (*f).first; + STMMax = (*f).second; + } + } + } + } + if(STMMax.size() == 0) + return 0; + std::map::iterator S = STMMax.begin(); + vectorNum VN = (*S).second; + if(VN.size() == 0) + return 0; + return VN[0]; +} +void videoDevice::buildLibraryofTypes() +{ + unsigned int size; + unsigned int framerate; + std::vector::iterator i = vd_CurrentFormats.begin(); + int count = 0; + for(; i != vd_CurrentFormats.end(); i++) + { + size = (*i).MF_MT_FRAME_SIZE; + framerate = (*i).MF_MT_FRAME_RATE; + FrameRateMap FRM = vd_CaptureFormats[size]; + SUBTYPEMap STM = FRM[framerate]; + String subType((*i).pMF_MT_SUBTYPEName); + vectorNum VN = STM[subType]; + VN.push_back(count); + STM[subType] = VN; + FRM[framerate] = STM; + vd_CaptureFormats[size] = FRM; + count++; + } +} +long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex) +{ + IMFPresentationDescriptor *pPD = NULL; + IMFStreamDescriptor *pSD = NULL; + IMFMediaTypeHandler *pHandler = NULL; + IMFMediaType *pType = NULL; + HRESULT hr = pSource->CreatePresentationDescriptor(&pPD); + if (FAILED(hr)) + { + goto done; + } + BOOL fSelected; + hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD); + if (FAILED(hr)) + { + goto done; + } + hr = pSD->GetMediaTypeHandler(&pHandler); + if (FAILED(hr)) + { + goto done; + } + hr = pHandler->GetMediaTypeByIndex((DWORD)dwFormatIndex, &pType); + if (FAILED(hr)) + { + goto done; + } + hr = pHandler->SetCurrentMediaType(pType); +done: + SafeRelease(&pPD); + SafeRelease(&pSD); + SafeRelease(&pHandler); + SafeRelease(&pType); + return hr; +} +bool videoDevice::isDeviceSetup() +{ + return vd_IsSetuped; +} +RawImage * videoDevice::getRawImageOut() +{ + if(!vd_IsSetuped) return NULL; + if(vd_pImGrTh) + return vd_pImGrTh->getImageGrabber()->getRawImage(); + else + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist \n", vd_CurrentNumber); + } + return NULL; +} +bool videoDevice::isFrameNew() +{ + if(!vd_IsSetuped) return false; + if(vd_LockOut == RawDataLock || vd_LockOut == OpenLock) + { + if(vd_LockOut == OpenLock) + { + vd_LockOut = RawDataLock; + HRESULT hr = ImageGrabberThread::CreateInstance(&vd_pImGrTh, vd_pSource, vd_CurrentNumber); + if(FAILED(hr)) + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber); + return false; + } + vd_pImGrTh->setEmergencyStopEvent(vd_userData, vd_func); + vd_pImGrTh->start(); + return true; + } + if(vd_pImGrTh) + return vd_pImGrTh->getImageGrabber()->getRawImage()->isNew(); + } + return false; +} +bool videoDevice::isDeviceMediaSource() +{ + if(vd_LockOut == MediaSourceLock) return true; + return false; +} +bool videoDevice::isDeviceRawDataSource() +{ + if(vd_LockOut == RawDataLock) return true; + return false; +} +bool videoDevice::setupDevice(unsigned int id) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if(!vd_IsSetuped) + { + HRESULT hr = -1; + hr = initDevice(); + if(SUCCEEDED(hr)) + { + vd_Width = vd_CurrentFormats[id].width; + vd_Height = vd_CurrentFormats[id].height; + hr = setDeviceFormat(vd_pSource, (DWORD) id); + vd_IsSetuped = (SUCCEEDED(hr)); + if(vd_IsSetuped) + DPO->printOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber); + vd_PrevParametrs = getParametrs(); + return vd_IsSetuped; + } + else + { + DPO->printOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber); + return false; + } + } + else + { + DPO->printOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber); + return false; + } +} +bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate) +{ + unsigned int id = findType(w * h, idealFramerate); + return setupDevice(id); +} +wchar_t *videoDevice::getName() +{ + return vd_pFriendlyName; +} +videoDevice::~videoDevice(void) +{ + closeDevice(); + SafeRelease(&vd_pSource); + if(vd_pFriendlyName) + CoTaskMemFree(vd_pFriendlyName); +} +long videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource) +{ + IMFPresentationDescriptor *pPD = NULL; + IMFStreamDescriptor *pSD = NULL; + IMFMediaTypeHandler *pHandler = NULL; + IMFMediaType *pType = NULL; + HRESULT hr = pSource->CreatePresentationDescriptor(&pPD); + if (FAILED(hr)) + { + goto done; + } + BOOL fSelected; + hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD); + if (FAILED(hr)) + { + goto done; + } + hr = pSD->GetMediaTypeHandler(&pHandler); + if (FAILED(hr)) + { + goto done; + } + DWORD cTypes = 0; + hr = pHandler->GetMediaTypeCount(&cTypes); + if (FAILED(hr)) + { + goto done; + } + for (DWORD i = 0; i < cTypes; i++) + { + hr = pHandler->GetMediaTypeByIndex(i, &pType); + if (FAILED(hr)) + { + goto done; + } + MediaType MT = FormatReader::Read(pType); + vd_CurrentFormats.push_back(MT); + SafeRelease(&pType); + } +done: + SafeRelease(&pPD); + SafeRelease(&pSD); + SafeRelease(&pHandler); + SafeRelease(&pType); + return hr; +} +videoDevices::videoDevices(void): count(0) +{} +void videoDevices::clearDevices() +{ + std::vector::iterator i = vds_Devices.begin(); + for(; i != vds_Devices.end(); ++i) + delete (*i); + vds_Devices.clear(); +} +videoDevices::~videoDevices(void) +{ + clearDevices(); +} +videoDevice * videoDevices::getDevice(unsigned int i) +{ + if(i >= vds_Devices.size()) + { + return NULL; + } + if(i < 0) + { + return NULL; + } + return vds_Devices[i]; +} +long videoDevices::initDevices(IMFAttributes *pAttributes) +{ + HRESULT hr = S_OK; + IMFActivate **ppDevices = NULL; + clearDevices(); + hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); + if (SUCCEEDED(hr)) + { + if(count > 0) + { + for(UINT32 i = 0; i < count; i++) + { + videoDevice *vd = new videoDevice; + vd->readInfoOfDevice(ppDevices[i], i); + vds_Devices.push_back(vd); + SafeRelease(&ppDevices[i]); + } + SafeRelease(ppDevices); + } + else + hr = -1; + } + else + { + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n"); + } + return hr; +} +size_t videoDevices::getCount() +{ + return vds_Devices.size(); +} +videoDevices& videoDevices::getInstance() +{ + static videoDevices instance; + return instance; +} +Parametr::Parametr() +{ + CurrentValue = 0; + Min = 0; + Max = 0; + Step = 0; + Default = 0; + Flag = 0; +} +MediaType::MediaType() +{ + pMF_MT_AM_FORMAT_TYPEName = NULL; + pMF_MT_MAJOR_TYPEName = NULL; + pMF_MT_SUBTYPEName = NULL; + Clear(); +} +MediaType::~MediaType() +{ + Clear(); +} +void MediaType::Clear() +{ + MF_MT_FRAME_SIZE = 0; + height = 0; + width = 0; + MF_MT_YUV_MATRIX = 0; + MF_MT_VIDEO_LIGHTING = 0; + MF_MT_DEFAULT_STRIDE = 0; + MF_MT_VIDEO_CHROMA_SITING = 0; + MF_MT_FIXED_SIZE_SAMPLES = 0; + MF_MT_VIDEO_NOMINAL_RANGE = 0; + MF_MT_FRAME_RATE = 0; + MF_MT_FRAME_RATE_low = 0; + MF_MT_PIXEL_ASPECT_RATIO = 0; + MF_MT_PIXEL_ASPECT_RATIO_low = 0; + MF_MT_ALL_SAMPLES_INDEPENDENT = 0; + MF_MT_FRAME_RATE_RANGE_MIN = 0; + MF_MT_FRAME_RATE_RANGE_MIN_low = 0; + MF_MT_SAMPLE_SIZE = 0; + MF_MT_VIDEO_PRIMARIES = 0; + MF_MT_INTERLACE_MODE = 0; + MF_MT_FRAME_RATE_RANGE_MAX = 0; + MF_MT_FRAME_RATE_RANGE_MAX_low = 0; + memset(&MF_MT_MAJOR_TYPE, 0, sizeof(GUID)); + memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID)); + memset(&MF_MT_SUBTYPE, 0, sizeof(GUID)); +} +videoInput::videoInput(void): accessToDevices(false) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n"); + updateListOfDevices(); + if(!accessToDevices) + DPO->printOut(L"INITIALIZATION: Ther is not any suitable video device\n"); +} +void videoInput::updateListOfDevices() +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + Media_Foundation *MF = &Media_Foundation::getInstance(); + accessToDevices = MF->buildListOfDevices(); + if(!accessToDevices) + DPO->printOut(L"UPDATING: Ther is not any suitable video device\n"); +} +videoInput::~videoInput(void) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->printOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n"); +} +IMFMediaSource *videoInput::getMediaSource(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + { + IMFMediaSource *out = VD->getMediaSource(); + if(!out) + DPO->printOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID); + return out; + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return NULL; +} +bool videoInput::setupDevice(int deviceID, unsigned int id) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0 ) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + { + bool out = VD->setupDevice(id); + if(!out) + DPO->printOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID); + return out; + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return false; +} +bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0 ) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + { + bool out = VD->setupDevice(w, h, idealFramerate); + if(!out) + DPO->printOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID); + return out; + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID); + } + return false; +} +MediaType videoInput::getFormat(int deviceID, unsigned int id) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return MediaType(); + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->getFormat(id); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return MediaType(); +} +bool videoInput::isDeviceSetup(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->isDeviceSetup(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return false; +} +bool videoInput::isDeviceMediaSource(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->isDeviceMediaSource(); + } + else + { + DPO->printOut(L"Device(s): There is not any suitable video device\n"); + } + return false; +} +bool videoInput::isDeviceRawDataSource(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + { + bool isRaw = VD->isDeviceRawDataSource(); + return isRaw; + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return false; +} +bool videoInput::isFrameNew(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return false; + } + if(accessToDevices) + { + if(!isDeviceSetup(deviceID)) + { + if(isDeviceMediaSource(deviceID)) + return false; + } + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + { + return VD->isFrameNew(); + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return false; +} +unsigned int videoInput::getCountFormats(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return 0; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->getCountFormats(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return 0; +} +void videoInput::closeAllDevices() +{ + videoDevices *VDS = &videoDevices::getInstance(); + for(unsigned int i = 0; i < VDS->getCount(); i++) + closeDevice(i); +} +void videoInput::setParametrs(int deviceID, CamParametrs parametrs) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice *VD = VDS->getDevice(deviceID); + if(VD) + VD->setParametrs(parametrs); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } +} +CamParametrs videoInput::getParametrs(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + CamParametrs out; + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return out; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice *VD = VDS->getDevice(deviceID); + if(VD) + out = VD->getParametrs(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return out; +} +void videoInput::closeDevice(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice *VD = VDS->getDevice(deviceID); + if(VD) + VD->closeDevice(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } +} +unsigned int videoInput::getWidth(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return 0; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->getWidth(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return 0; +} +unsigned int videoInput::getHeight(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return 0; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->getHeight(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return 0; +} +wchar_t *videoInput::getNameVideoDevice(int deviceID) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return NULL; + } + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + return VD->getName(); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return L"Empty"; +} +unsigned int videoInput::listDevices(bool silent) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + int out = 0; + if(accessToDevices) + { + videoDevices *VDS = &videoDevices::getInstance(); + out = VDS->getCount(); + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if(!silent)DPO->printOut(L"\nVIDEOINPUT SPY MODE!\n\n"); + if(!silent)DPO->printOut(L"SETUP: Looking For Capture Devices\n"); + for(int i = 0; i < out; i++) + { + if(!silent)DPO->printOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i)); + } + if(!silent)DPO->printOut(L"SETUP: %i Device(s) found\n\n", out); + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return out; +} +videoInput& videoInput::getInstance() +{ + static videoInput instance; + return instance; +} +bool videoInput::isDevicesAcceable() +{ + return accessToDevices; +} +void videoInput::setVerbose(bool state) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + DPO->setVerbose(state); +} +void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *)) +{ + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return; + } + if(accessToDevices) + { + if(func) + { + videoDevices *VDS = &videoDevices::getInstance(); + videoDevice * VD = VDS->getDevice(deviceID); + if(VD) + VD->setEmergencyStopEvent(userData, func); + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } +} +bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage) +{ + bool success = false; + unsigned int bytes = 3; + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + if (deviceID < 0) + { + DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); + return success; + } + if(accessToDevices) + { + bool isRaw = isDeviceRawDataSource(deviceID); + if(isRaw) + { + videoDevices *VDS = &videoDevices::getInstance(); + DebugPrintOut *DPO = &DebugPrintOut::getInstance(); + RawImage *RIOut = VDS->getDevice(deviceID)->getRawImageOut(); + if(RIOut) + { + unsigned int height = VDS->getDevice(deviceID)->getHeight(); + unsigned int width = VDS->getDevice(deviceID)->getWidth(); + unsigned int size = bytes * width * height; + if(size == RIOut->getSize()) + { + processPixels(RIOut->getpPixels(), dstBuffer, width, height, bytes, flipRedAndBlue, flipImage); + success = true; + } + else + { + DPO->printOut(L"ERROR: GetPixels() - bufferSizes do not match!\n"); + } + } + else + { + DPO->printOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID); + } + } + else + { + DPO->printOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID); + } + } + else + { + DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); + } + return success; +} +void videoInput::processPixels(unsigned char * src, unsigned char * dst, unsigned int width, + unsigned int height, unsigned int bpp, bool bRGB, bool bFlip) +{ + unsigned int widthInBytes = width * bpp; + unsigned int numBytes = widthInBytes * height; + int *dstInt, *srcInt; + if(!bRGB) + { + if(bFlip) + { + for(unsigned int y = 0; y < height; y++) + { + dstInt = (int *)(dst + (y * widthInBytes)); + srcInt = (int *)(src + ( (height -y -1) * widthInBytes)); + memcpy(dstInt, srcInt, widthInBytes); + } + } + else + { + memcpy(dst, src, numBytes); + } + } + else + { + if(bFlip) + { + unsigned int x = 0; + unsigned int y = (height - 1) * widthInBytes; + src += y; + for(unsigned int i = 0; i < numBytes; i+=3) + { + if(x >= width) + { + x = 0; + src -= widthInBytes*2; + } + *dst = *(src+2); + dst++; + *dst = *(src+1); + dst++; + *dst = *src; + dst++; + src+=3; + x++; + } + } + else + { + for(unsigned int i = 0; i < numBytes; i+=3) + { + *dst = *(src+2); + dst++; + *dst = *(src+1); + dst++; + *dst = *src; + dst++; + src+=3; + } + } + } +} +} +/******* Capturing video from camera via Microsoft Media Foundation **********/ +class CvCaptureCAM_MSMF : public CvCapture +{ +public: + CvCaptureCAM_MSMF(); + virtual ~CvCaptureCAM_MSMF(); + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc... +protected: + void init(); + int index, width, height,fourcc; + int widthSet, heightSet; + IplImage* frame; + videoInput VI; +}; +struct SuppressVideoInputMessages +{ + SuppressVideoInputMessages() { videoInput::setVerbose(true); } +}; +static SuppressVideoInputMessages do_it; +CvCaptureCAM_MSMF::CvCaptureCAM_MSMF(): + index(-1), + width(-1), + height(-1), + fourcc(-1), + widthSet(-1), + heightSet(-1), + frame(0), + VI(videoInput::getInstance()) +{ + CoInitialize(0); +} +CvCaptureCAM_MSMF::~CvCaptureCAM_MSMF() +{ + close(); + CoUninitialize(); +} +void CvCaptureCAM_MSMF::close() +{ + if( index >= 0 ) + { + VI.closeDevice(index); + index = -1; + cvReleaseImage(&frame); + } + widthSet = heightSet = width = height = -1; +} +// Initialize camera input +bool CvCaptureCAM_MSMF::open( int _index ) +{ + int try_index = _index; + int devices = 0; + close(); + devices = VI.listDevices(true); + if (devices == 0) + return false; + try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index); + VI.setupDevice(try_index); + if( !VI.isFrameNew(try_index) ) + return false; + index = try_index; + return true; +} +bool CvCaptureCAM_MSMF::grabFrame() +{ + return true; +} +IplImage* CvCaptureCAM_MSMF::retrieveFrame(int) +{ + if( !frame || (int)VI.getWidth(index) != frame->width || (int)VI.getHeight(index) != frame->height ) + { + if (frame) + cvReleaseImage( &frame ); + unsigned int w = VI.getWidth(index), h = VI.getHeight(index); + frame = cvCreateImage( cvSize(w,h), 8, 3 ); + } + VI.getPixels( index, (uchar*)frame->imageData, false, true ); + return frame; +} +double CvCaptureCAM_MSMF::getProperty( int property_id ) +{ + // image format proprrties + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return VI.getWidth(index); + case CV_CAP_PROP_FRAME_HEIGHT: + return VI.getHeight(index); + case CV_CAP_PROP_FOURCC: + // FIXME: implement method in VideoInput back end + //return VI.getFourcc(index); + ; + case CV_CAP_PROP_FPS: + // FIXME: implement method in VideoInput back end + //return VI.getFPS(index); + ; + } + // video filter properties + switch( property_id ) + { + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_SHARPNESS: + case CV_CAP_PROP_GAMMA: + case CV_CAP_PROP_MONOCROME: + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + case CV_CAP_PROP_BACKLIGHT: + case CV_CAP_PROP_GAIN: + // FIXME: implement method in VideoInput back end + // if ( VI.getVideoSettingFilter(index, VI.getVideoPropertyFromCV(property_id), min_value, + // max_value, stepping_delta, current_value, flags,defaultValue) ) + // return (double)current_value; + return 0.; + } + // camera properties + switch( property_id ) + { + case CV_CAP_PROP_PAN: + case CV_CAP_PROP_TILT: + case CV_CAP_PROP_ROLL: + case CV_CAP_PROP_ZOOM: + case CV_CAP_PROP_EXPOSURE: + case CV_CAP_PROP_IRIS: + case CV_CAP_PROP_FOCUS: + // FIXME: implement method in VideoInput back end + // if (VI.getVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),min_value, + // max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value; + return 0.; + } + // unknown parameter or value not available + return -1; +} +bool CvCaptureCAM_MSMF::setProperty( int property_id, double value ) +{ + // image capture properties + bool handled = false; + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + width = cvRound(value); + handled = true; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + height = cvRound(value); + handled = true; + break; + case CV_CAP_PROP_FOURCC: + fourcc = (int)(unsigned long)(value); + if ( fourcc == -1 ) { + // following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1 + // TODO - how to create a capture pin dialog + } + handled = true; + break; + case CV_CAP_PROP_FPS: + // FIXME: implement method in VideoInput back end + // int fps = cvRound(value); + // if (fps != VI.getFPS(index)) + // { + // VI.stopDevice(index); + // VI.setIdealFramerate(index,fps); + // if (widthSet > 0 && heightSet > 0) + // VI.setupDevice(index, widthSet, heightSet); + // else + // VI.setupDevice(index); + // } + // return VI.isDeviceSetup(index); + ; + } + if ( handled ) { + // a stream setting + if( width > 0 && height > 0 ) + { + if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) )//|| fourcc != VI.getFourcc(index) ) + { + // FIXME: implement method in VideoInput back end + // int fps = static_cast(VI.getFPS(index)); + // VI.stopDevice(index); + // VI.setIdealFramerate(index, fps); + // VI.setupDeviceFourcc(index, width, height, fourcc); + } + bool success = VI.isDeviceSetup(index); + if (success) + { + widthSet = width; + heightSet = height; + width = height = fourcc = -1; + } + return success; + } + return true; + } + // show video/camera filter dialog + // FIXME: implement method in VideoInput back end + // if ( property_id == CV_CAP_PROP_SETTINGS ) { + // VI.showSettingsWindow(index); + // return true; + // } + //video Filter properties + switch( property_id ) + { + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_SHARPNESS: + case CV_CAP_PROP_GAMMA: + case CV_CAP_PROP_MONOCROME: + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + case CV_CAP_PROP_BACKLIGHT: + case CV_CAP_PROP_GAIN: + // FIXME: implement method in VideoInput back end + //return VI.setVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),(long)value); + ; + } + //camera properties + switch( property_id ) + { + case CV_CAP_PROP_PAN: + case CV_CAP_PROP_TILT: + case CV_CAP_PROP_ROLL: + case CV_CAP_PROP_ZOOM: + case CV_CAP_PROP_EXPOSURE: + case CV_CAP_PROP_IRIS: + case CV_CAP_PROP_FOCUS: + // FIXME: implement method in VideoInput back end + //return VI.setVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),(long)value); + ; + } + return false; +} +CvCapture* cvCreateCameraCapture_MSMF( int index ) +{ + CvCaptureCAM_MSMF* capture = new CvCaptureCAM_MSMF; + try + { + if( capture->open( index )) + return capture; + } + catch(...) + { + delete capture; + throw; + } + delete capture; + return 0; +} +#endif \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_openni.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_openni.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_openni.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_openni.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1406 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc.hpp" + +#ifdef HAVE_OPENNI + +#if defined TBB_INTERFACE_VERSION && TBB_INTERFACE_VERSION < 5000 +# undef HAVE_TBB +#endif + +#include +#include + +#ifndef i386 +# define i386 0 +#endif +#ifndef __arm__ +# define __arm__ 0 +#endif +#ifndef _ARC +# define _ARC 0 +#endif +#ifndef __APPLE__ +# define __APPLE__ 0 +#endif + +#include "XnCppWrapper.h" + +const std::string XMLConfig = +"" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + " " + "" + "" + "" + "" + "" + "" + "" +"\n"; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class ApproximateSyncGrabber +{ +public: + ApproximateSyncGrabber( xn::Context &_context, + xn::DepthGenerator &_depthGenerator, + xn::ImageGenerator &_imageGenerator, + int _maxBufferSize, bool _isCircleBuffer, int _maxTimeDuration ) : + context(_context), depthGenerator(_depthGenerator), imageGenerator(_imageGenerator), + maxBufferSize(_maxBufferSize), isCircleBuffer(_isCircleBuffer), maxTimeDuration(_maxTimeDuration) + { + task = 0; + + CV_Assert( depthGenerator.IsValid() ); + CV_Assert( imageGenerator.IsValid() ); + } + + void setMaxBufferSize( int _maxBufferSize ) + { + maxBufferSize = _maxBufferSize; +#ifdef HAVE_TBB + task->setMaxBufferSize(); +#endif + } + inline int getMaxBufferSize() const { return maxBufferSize; } + + void setIsCircleBuffer( bool _isCircleBuffer ) { isCircleBuffer = _isCircleBuffer; } + bool getIsCircleBuffer() const { return isCircleBuffer; } + + void setMaxTimeDuration( int _maxTimeDuration ) { maxTimeDuration = _maxTimeDuration; } + int getMaxTimeDuration() const { return maxTimeDuration; } + + bool grab( xn::DepthMetaData& depthMetaData, + xn::ImageMetaData& imageMetaData ) + { + CV_Assert( task ); + + + while( task->grab(depthMetaData, imageMetaData) == false ) + { +#ifndef HAVE_TBB + task->spin(); +#endif + } + return true; + + } + + void start() + { + CV_Assert( depthGenerator.IsValid() ); + CV_Assert( imageGenerator.IsValid() ); +#ifdef HAVE_TBB + task = new( tbb::task::allocate_root() ) TBBApproximateSynchronizerTask( *this ); + tbb::task::enqueue(*task); +#else + task = new ApproximateSynchronizer( *this ); +#endif + } + + void finish() + { +#ifdef HAVE_TBB + if( task ) + tbb::task::destroy( *task ); +#else + task.release(); +#endif + } + + bool isRun() const { return task != 0; } + + xn::Context &context; + xn::DepthGenerator &depthGenerator; + xn::ImageGenerator &imageGenerator; + +private: + int maxBufferSize; + bool isCircleBuffer; + int maxTimeDuration; + + class ApproximateSynchronizerBase + { + public: + ApproximateSynchronizerBase( ApproximateSyncGrabber& _approxSyncGrabber ) : + approxSyncGrabber(_approxSyncGrabber), isDepthFilled(false), isImageFilled(false) + {} + + virtual ~ApproximateSynchronizerBase() {} + + virtual bool isSpinContinue() const = 0; + virtual void pushDepthMetaData( xn::DepthMetaData& depthMetaData ) = 0; + virtual void pushImageMetaData( xn::ImageMetaData& imageMetaData ) = 0; + virtual bool popDepthMetaData( xn::DepthMetaData& depthMetaData ) = 0; + virtual bool popImageMetaData( xn::ImageMetaData& imageMetaData ) = 0; + + void spin() + { + while(isSpinContinue() == true) + { + XnStatus status = approxSyncGrabber.context.WaitAnyUpdateAll(); + if( status != XN_STATUS_OK ) + continue; + + //xn::DepthMetaData depth; + //xn::ImageMetaData image; + approxSyncGrabber.depthGenerator.GetMetaData(depth); + approxSyncGrabber.imageGenerator.GetMetaData(image); + + if( depth.Data() && depth.IsDataNew() ) + pushDepthMetaData( depth ); + + if( image.Data() && image.IsDataNew() ) + pushImageMetaData( image ); + } + } + + virtual bool grab( xn::DepthMetaData& depthMetaData, + xn::ImageMetaData& imageMetaData ) + { + while(1) + { + if( !isDepthFilled ) + isDepthFilled = popDepthMetaData(depth); + if( !isImageFilled ) + isImageFilled = popImageMetaData(image); + + if( !isDepthFilled || !isImageFilled ) + break; + + double timeDiff = 1e-3 * std::abs(static_cast(depth.Timestamp()) - static_cast(image.Timestamp())); + + if( timeDiff <= approxSyncGrabber.maxTimeDuration ) + { + depthMetaData.InitFrom(depth); + imageMetaData.InitFrom(image); + isDepthFilled = isImageFilled = false; + return true; + } + else + { + if( depth.Timestamp() < image.Timestamp() ) + isDepthFilled = false; + else + isImageFilled = false; + } + } + + return false; + } + + protected: + ApproximateSyncGrabber& approxSyncGrabber; + xn::DepthMetaData depth; + xn::ImageMetaData image; + bool isDepthFilled; + bool isImageFilled; + }; + + // If there isn't TBB the synchronization will be executed in the main thread. + class ApproximateSynchronizer: public ApproximateSynchronizerBase + { + public: + ApproximateSynchronizer( ApproximateSyncGrabber& _approxSyncGrabber ) : + ApproximateSynchronizerBase(_approxSyncGrabber) + {} + + virtual bool isSpinContinue() const + { + int maxBufferSize = approxSyncGrabber.getMaxBufferSize(); + return (maxBufferSize <= 0) || (static_cast(depthQueue.size()) < maxBufferSize && + static_cast(imageQueue.size()) < maxBufferSize); // "<" to may push + } + + virtual inline void pushDepthMetaData( xn::DepthMetaData& depthMetaData ) + { + cv::Ptr depthPtr = new xn::DepthMetaData; + depthPtr->CopyFrom(depthMetaData); + depthQueue.push(depthPtr); + } + virtual inline void pushImageMetaData( xn::ImageMetaData& imageMetaData ) + { + cv::Ptr imagePtr = new xn::ImageMetaData; + imagePtr->CopyFrom(imageMetaData); + imageQueue.push(imagePtr); + } + virtual inline bool popDepthMetaData( xn::DepthMetaData& depthMetaData ) + { + if( depthQueue.empty() ) + return false; + + depthMetaData.CopyFrom(*depthQueue.front()); + depthQueue.pop(); + return true; + } + virtual inline bool popImageMetaData( xn::ImageMetaData& imageMetaData ) + { + if( imageQueue.empty() ) + return false; + + imageMetaData.CopyFrom(*imageQueue.front()); + imageQueue.pop(); + return true; + } + + private: + std::queue > depthQueue; + std::queue > imageQueue; + }; + +#ifdef HAVE_TBB + // If there is TBB the synchronization will be executed in own thread. + class TBBApproximateSynchronizer: public ApproximateSynchronizerBase + { + public: + TBBApproximateSynchronizer( ApproximateSyncGrabber& approxSyncGrabber ) : + ApproximateSynchronizerBase(approxSyncGrabber) + { + setMaxBufferSize(); + } + + void setMaxBufferSize() + { + int maxBufferSize = ApproximateSynchronizerBase::approxSyncGrabber.getMaxBufferSize(); + if( maxBufferSize >= 0 ) + { + depthQueue.set_capacity( maxBufferSize ); + imageQueue.set_capacity( maxBufferSize ); + } + } + + virtual inline bool isSpinContinue() const { return true; } + + virtual inline void pushDepthMetaData( xn::DepthMetaData& depthMetaData ) + { + cv::Ptr depthPtr = new xn::DepthMetaData, tmp; + depthPtr->CopyFrom(depthMetaData); + + tbb::mutex mtx; + mtx.lock(); + if( depthQueue.try_push(depthPtr) == false ) + { + if( approxSyncGrabber.getIsCircleBuffer() ) + { + CV_Assert( depthQueue.try_pop(tmp) ); + CV_Assert( depthQueue.try_push(depthPtr) ); + } + } + mtx.unlock(); + } + + virtual inline void pushImageMetaData( xn::ImageMetaData& imageMetaData ) + { + cv::Ptr imagePtr = new xn::ImageMetaData, tmp; + imagePtr->CopyFrom(imageMetaData); + + tbb::mutex mtx; + mtx.lock(); + if( imageQueue.try_push(imagePtr) == false ) + { + if( approxSyncGrabber.getIsCircleBuffer() ) + { + CV_Assert( imageQueue.try_pop(tmp) ); + CV_Assert( imageQueue.try_push(imagePtr) ); + } + } + mtx.unlock(); + } + + virtual inline bool popDepthMetaData( xn::DepthMetaData& depthMetaData ) + { + cv::Ptr depthPtr; + bool isPop = depthQueue.try_pop(depthPtr); + if( isPop ) + depthMetaData.CopyFrom(*depthPtr); + return isPop; + } + virtual inline bool popImageMetaData( xn::ImageMetaData& imageMetaData ) + { + cv::Ptr imagePtr; + bool isPop = imageQueue.try_pop(imagePtr); + if( isPop ) + imageMetaData.CopyFrom(*imagePtr); + return isPop; + } + + private: + tbb::concurrent_bounded_queue > depthQueue; + tbb::concurrent_bounded_queue > imageQueue; + }; + + class TBBApproximateSynchronizerTask: public tbb::task + { + public: + TBBApproximateSynchronizerTask( ApproximateSyncGrabber& approxSyncGrabber ) : + synchronizer(approxSyncGrabber) + {} + + void setMaxBufferSize() + { + synchronizer.setMaxBufferSize(); + } + + bool grab( xn::DepthMetaData& depthMetaData, + xn::ImageMetaData& imageMetaData ) + { + return synchronizer.grab( depthMetaData, imageMetaData ); + } + + private: + tbb::task* execute() + { + synchronizer.spin(); + return 0; + } + TBBApproximateSynchronizer synchronizer; + }; +#endif // HAVE_TBB + +#ifdef HAVE_TBB + TBBApproximateSynchronizerTask* task; +#else + cv::Ptr task; +#endif +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class CvCapture_OpenNI : public CvCapture +{ +public: + enum { DEVICE_DEFAULT=0, DEVICE_MS_KINECT=0, DEVICE_ASUS_XTION=1, DEVICE_MAX=1 }; + + static const int INVALID_PIXEL_VAL = 0; + static const int INVALID_COORDINATE_VAL = 0; + +#ifdef HAVE_TBB + static const int DEFAULT_MAX_BUFFER_SIZE = 8; +#else + static const int DEFAULT_MAX_BUFFER_SIZE = 2; +#endif + static const int DEFAULT_IS_CIRCLE_BUFFER = 0; + static const int DEFAULT_MAX_TIME_DURATION = 20; + + CvCapture_OpenNI(int index=0); + CvCapture_OpenNI(const char * filename); + virtual ~CvCapture_OpenNI(); + + virtual double getProperty(int propIdx); + virtual bool setProperty(int probIdx, double propVal); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int outputType); + + bool isOpened() const; + +protected: + struct OutputMap + { + public: + cv::Mat mat; + IplImage* getIplImagePtr(); + private: + IplImage iplHeader; + }; + + static const int outputMapsTypesCount = 7; + + static XnMapOutputMode defaultMapOutputMode(); + + IplImage* retrieveDepthMap(); + IplImage* retrievePointCloudMap(); + IplImage* retrieveDisparityMap(); + IplImage* retrieveDisparityMap_32F(); + IplImage* retrieveValidDepthMask(); + IplImage* retrieveBGRImage(); + IplImage* retrieveGrayImage(); + + bool readCamerasParams(); + + double getDepthGeneratorProperty(int propIdx); + bool setDepthGeneratorProperty(int propIdx, double propVal); + double getImageGeneratorProperty(int propIdx); + bool setImageGeneratorProperty(int propIdx, double propVal); + double getCommonProperty(int propIdx); + bool setCommonProperty(int propIdx, double propVal); + + // OpenNI context + xn::Context context; + bool isContextOpened; + + xn::ProductionNode productionNode; + + // Data generators with its metadata + xn::DepthGenerator depthGenerator; + xn::DepthMetaData depthMetaData; + + xn::ImageGenerator imageGenerator; + xn::ImageMetaData imageMetaData; + + int maxBufferSize, maxTimeDuration; // for approx sync + bool isCircleBuffer; + cv::Ptr approxSyncGrabber; + + // Cameras settings: + // TODO find in OpenNI function to convert z->disparity and remove fields "baseline" and depthFocalLength_VGA + // Distance between IR projector and IR camera (in meters) + XnDouble baseline; + // Focal length for the IR camera in VGA resolution (in pixels) + XnUInt64 depthFocalLength_VGA; + + // The value for shadow (occluded pixels) + XnUInt64 shadowValue; + // The value for pixels without a valid disparity measurement + XnUInt64 noSampleValue; + + std::vector outputMaps; +}; + +IplImage* CvCapture_OpenNI::OutputMap::getIplImagePtr() +{ + if( mat.empty() ) + return 0; + + iplHeader = IplImage(mat); + return &iplHeader; +} + +bool CvCapture_OpenNI::isOpened() const +{ + return isContextOpened; +} + +XnMapOutputMode CvCapture_OpenNI::defaultMapOutputMode() +{ + XnMapOutputMode mode; + mode.nXRes = XN_VGA_X_RES; + mode.nYRes = XN_VGA_Y_RES; + mode.nFPS = 30; + return mode; +} + +CvCapture_OpenNI::CvCapture_OpenNI( int index ) +{ + int deviceType = DEVICE_DEFAULT; + XnStatus status; + + isContextOpened = false; + maxBufferSize = DEFAULT_MAX_BUFFER_SIZE; + isCircleBuffer = DEFAULT_IS_CIRCLE_BUFFER; + maxTimeDuration = DEFAULT_MAX_TIME_DURATION; + + if( index >= 10 ) + { + deviceType = index / 10; + index %= 10; + } + + if( deviceType > DEVICE_MAX ) + return; + + // Initialize and configure the context. + status = context.Init(); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to initialize the context: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + // Find devices + xn::NodeInfoList devicesList; + status = context.EnumerateProductionTrees( XN_NODE_TYPE_DEVICE, NULL, devicesList, 0 ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate production trees: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + // Chose device according to index + xn::NodeInfoList::Iterator it = devicesList.Begin(); + for( int i = 0; i < index && it!=devicesList.End(); ++i ) it++; + if ( it == devicesList.End() ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed device with index " << index << std::endl; + return; + } + + xn::NodeInfo deviceNode = *it; + status = context.CreateProductionTree( deviceNode, productionNode ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to create production tree: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + xn::ScriptNode scriptNode; + status = context.RunXmlScript( XMLConfig.c_str(), scriptNode ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to run xml script: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + // Associate generators with context. + // enumerate the nodes to find if depth generator is present + xn::NodeInfoList depthList; + status = context.EnumerateExistingNodes( depthList, XN_NODE_TYPE_DEPTH ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate depth generators: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + if( depthList.IsEmpty() ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : The device doesn't have depth generator. Such devices aren't supported now." << std::endl; + return; + } + status = depthGenerator.Create( context ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to create depth generator: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + // enumerate the nodes to find if image generator is present + xn::NodeInfoList imageList; + status = context.EnumerateExistingNodes( imageList, XN_NODE_TYPE_IMAGE ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate image generators: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + if( !imageList.IsEmpty() ) + { + status = imageGenerator.Create( context ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to create image generator: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + } + + // Set map output mode. + if( depthGenerator.IsValid() ) + { + CV_DbgAssert( depthGenerator.SetMapOutputMode(defaultMapOutputMode()) == XN_STATUS_OK ); // xn::DepthGenerator supports VGA only! (Jan 2011) + } + if( imageGenerator.IsValid() ) + { + CV_DbgAssert( imageGenerator.SetMapOutputMode(defaultMapOutputMode()) == XN_STATUS_OK ); + } + + if( deviceType == DEVICE_ASUS_XTION ) + { + //ps/asus specific + imageGenerator.SetIntProperty("InputFormat", 1 /*XN_IO_IMAGE_FORMAT_YUV422*/); + imageGenerator.SetPixelFormat(XN_PIXEL_FORMAT_RGB24); + depthGenerator.SetIntProperty("RegistrationType", 1 /*XN_PROCESSING_HARDWARE*/); + } + + // Start generating data. + status = context.StartGeneratingAll(); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to start generating OpenNI data: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + if( !readCamerasParams() ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Could not read cameras parameters" << std::endl; + return; + } + + outputMaps.resize( outputMapsTypesCount ); + + isContextOpened = true; + + setProperty(CV_CAP_PROP_OPENNI_REGISTRATION, 1.0); +} + +CvCapture_OpenNI::CvCapture_OpenNI(const char * filename) +{ + XnStatus status; + + isContextOpened = false; + maxBufferSize = DEFAULT_MAX_BUFFER_SIZE; + isCircleBuffer = DEFAULT_IS_CIRCLE_BUFFER; + maxTimeDuration = DEFAULT_MAX_TIME_DURATION; + + // Initialize and configure the context. + status = context.Init(); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to initialize the context: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + // Open file + status = context.OpenFileRecording( filename, productionNode ); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to open input file (" << filename << "): " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + + context.FindExistingNode( XN_NODE_TYPE_DEPTH, depthGenerator ); + context.FindExistingNode( XN_NODE_TYPE_IMAGE, imageGenerator ); + + if( !readCamerasParams() ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Could not read cameras parameters" << std::endl; + return; + } + + outputMaps.resize( outputMapsTypesCount ); + + isContextOpened = true; +} + +CvCapture_OpenNI::~CvCapture_OpenNI() +{ + context.StopGeneratingAll(); + context.Release(); +} + +bool CvCapture_OpenNI::readCamerasParams() +{ + XnDouble pixelSize = 0; + if( depthGenerator.GetRealProperty( "ZPPS", pixelSize ) != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::readCamerasParams : Could not read pixel size!" << std::endl; + return false; + } + + // pixel size @ VGA = pixel size @ SXGA x 2 + pixelSize *= 2.0; // in mm + + // focal length of IR camera in pixels for VGA resolution + XnUInt64 zeroPlanDistance; // in mm + if( depthGenerator.GetIntProperty( "ZPD", zeroPlanDistance ) != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::readCamerasParams : Could not read virtual plane distance!" << std::endl; + return false; + } + + if( depthGenerator.GetRealProperty( "LDDIS", baseline ) != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::readCamerasParams : Could not read base line!" << std::endl; + return false; + } + + // baseline from cm -> mm + baseline *= 10; + + // focal length from mm -> pixels (valid for 640x480) + depthFocalLength_VGA = (XnUInt64)((double)zeroPlanDistance / (double)pixelSize); + + if( depthGenerator.GetIntProperty( "ShadowValue", shadowValue ) != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::readCamerasParams : Could not read property \"ShadowValue\"!" << std::endl; + return false; + } + + if( depthGenerator.GetIntProperty("NoSampleValue", noSampleValue ) != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::readCamerasParams : Could not read property \"NoSampleValue\"!" <isRun() ? 1. : 0.; + break; + case CV_CAP_PROP_OPENNI_MAX_BUFFER_SIZE : + propValue = maxBufferSize; + break; + case CV_CAP_PROP_OPENNI_CIRCLE_BUFFER : + propValue = isCircleBuffer ? 1. : 0.; + break; + case CV_CAP_PROP_OPENNI_MAX_TIME_DURATION : + propValue = maxTimeDuration; + break; + default : + { + std::stringstream ss; + ss << "Such parameter (propIdx=" << propIdx << ") isn't supported for getting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return propValue; +} + +bool CvCapture_OpenNI::setCommonProperty( int propIdx, double propValue ) +{ + bool isSet = false; + + switch( propIdx ) + { + // There is a set of properties that correspond to depth generator by default + // (is they are pass without particular generator flag). + case CV_CAP_PROP_OPENNI_REGISTRATION: + isSet = setDepthGeneratorProperty( propIdx, propValue ); + break; + case CV_CAP_PROP_OPENNI_APPROX_FRAME_SYNC : + if( propValue && depthGenerator.IsValid() && imageGenerator.IsValid() ) + { + // start synchronization + if( approxSyncGrabber.empty() ) + { + approxSyncGrabber = new ApproximateSyncGrabber( context, depthGenerator, imageGenerator, maxBufferSize, isCircleBuffer, maxTimeDuration ); + } + else + { + approxSyncGrabber->finish(); + + // update params + approxSyncGrabber->setMaxBufferSize(maxBufferSize); + approxSyncGrabber->setIsCircleBuffer(isCircleBuffer); + approxSyncGrabber->setMaxTimeDuration(maxTimeDuration); + } + approxSyncGrabber->start(); + } + else if( !propValue && !approxSyncGrabber.empty() ) + { + // finish synchronization + approxSyncGrabber->finish(); + } + break; + case CV_CAP_PROP_OPENNI_MAX_BUFFER_SIZE : + maxBufferSize = cvRound(propValue); + if( !approxSyncGrabber.empty() ) + approxSyncGrabber->setMaxBufferSize(maxBufferSize); + break; + case CV_CAP_PROP_OPENNI_CIRCLE_BUFFER : + if( !approxSyncGrabber.empty() ) + approxSyncGrabber->setIsCircleBuffer(isCircleBuffer); + break; + case CV_CAP_PROP_OPENNI_MAX_TIME_DURATION : + maxTimeDuration = cvRound(propValue); + if( !approxSyncGrabber.empty() ) + approxSyncGrabber->setMaxTimeDuration(maxTimeDuration); + break; + default: + { + std::stringstream ss; + ss << "Such parameter (propIdx=" << propIdx << ") isn't supported for setting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return isSet; +} + +double CvCapture_OpenNI::getDepthGeneratorProperty( int propIdx ) +{ + double propValue = 0; + if( !depthGenerator.IsValid() ) + return propValue; + + XnMapOutputMode mode; + + switch( propIdx ) + { + case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT : + CV_DbgAssert( depthGenerator.IsValid() ); + propValue = 1.; + break; + case CV_CAP_PROP_FRAME_WIDTH : + if( depthGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nXRes; + break; + case CV_CAP_PROP_FRAME_HEIGHT : + if( depthGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nYRes; + break; + case CV_CAP_PROP_FPS : + if( depthGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nFPS; + break; + case CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH : + propValue = depthGenerator.GetDeviceMaxDepth(); + break; + case CV_CAP_PROP_OPENNI_BASELINE : + propValue = baseline; + break; + case CV_CAP_PROP_OPENNI_FOCAL_LENGTH : + propValue = (double)depthFocalLength_VGA; + break; + case CV_CAP_PROP_OPENNI_REGISTRATION : + propValue = depthGenerator.GetAlternativeViewPointCap().IsViewPointAs(imageGenerator) ? 1.0 : 0.0; + break; + case CV_CAP_PROP_POS_MSEC : + propValue = depthGenerator.GetTimestamp(); + break; + case CV_CAP_PROP_POS_FRAMES : + propValue = depthGenerator.GetFrameID(); + break; + default : + { + std::stringstream ss; + ss << "Depth generator does not support such parameter (propIdx=" << propIdx << ") for getting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return propValue; +} + +bool CvCapture_OpenNI::setDepthGeneratorProperty( int propIdx, double propValue ) +{ + bool isSet = false; + + CV_Assert( depthGenerator.IsValid() ); + + switch( propIdx ) + { + case CV_CAP_PROP_OPENNI_REGISTRATION: + { + if( propValue != 0.0 ) // "on" + { + // if there isn't image generator (i.e. ASUS XtionPro doesn't have it) + // then the property isn't avaliable + if( imageGenerator.IsValid() ) + { + if( !depthGenerator.GetAlternativeViewPointCap().IsViewPointAs(imageGenerator) ) + { + if( depthGenerator.GetAlternativeViewPointCap().IsViewPointSupported(imageGenerator) ) + { + XnStatus status = depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator); + if( status != XN_STATUS_OK ) + std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : " << xnGetStatusString(status) << std::endl; + else + isSet = true; + } + else + std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : Unsupported viewpoint." << std::endl; + } + else + isSet = true; + } + } + else // "off" + { + XnStatus status = depthGenerator.GetAlternativeViewPointCap().ResetViewPoint(); + if( status != XN_STATUS_OK ) + std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : " << xnGetStatusString(status) << std::endl; + else + isSet = true; + } + } + break; + default: + { + std::stringstream ss; + ss << "Depth generator does not support such parameter (propIdx=" << propIdx << ") for setting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return isSet; +} + +double CvCapture_OpenNI::getImageGeneratorProperty( int propIdx ) +{ + double propValue = 0.; + if( !imageGenerator.IsValid() ) + return propValue; + + XnMapOutputMode mode; + switch( propIdx ) + { + case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT : + CV_DbgAssert( imageGenerator.IsValid() ); + propValue = 1.; + break; + case CV_CAP_PROP_FRAME_WIDTH : + if( imageGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nXRes; + break; + case CV_CAP_PROP_FRAME_HEIGHT : + if( imageGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nYRes; + break; + case CV_CAP_PROP_FPS : + if( imageGenerator.GetMapOutputMode(mode) == XN_STATUS_OK ) + propValue = mode.nFPS; + break; + case CV_CAP_PROP_POS_MSEC : + propValue = imageGenerator.GetTimestamp(); + break; + case CV_CAP_PROP_POS_FRAMES : + propValue = imageGenerator.GetFrameID(); + break; + default : + { + std::stringstream ss; + ss << "Image generator does not support such parameter (propIdx=" << propIdx << ") for getting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return propValue; +} + +bool CvCapture_OpenNI::setImageGeneratorProperty( int propIdx, double propValue ) +{ + bool isSet = false; + if( !imageGenerator.IsValid() ) + return isSet; + + switch( propIdx ) + { + case CV_CAP_PROP_OPENNI_OUTPUT_MODE : + { + XnMapOutputMode mode; + + switch( cvRound(propValue) ) + { + case CV_CAP_OPENNI_VGA_30HZ : + mode.nXRes = XN_VGA_X_RES; + mode.nYRes = XN_VGA_Y_RES; + mode.nFPS = 30; + break; + case CV_CAP_OPENNI_SXGA_15HZ : + mode.nXRes = XN_SXGA_X_RES; + mode.nYRes = XN_SXGA_Y_RES; + mode.nFPS = 15; + break; + case CV_CAP_OPENNI_SXGA_30HZ : + mode.nXRes = XN_SXGA_X_RES; + mode.nYRes = XN_SXGA_Y_RES; + mode.nFPS = 30; + break; + case CV_CAP_OPENNI_QVGA_30HZ : + mode.nXRes = XN_QVGA_X_RES; + mode.nYRes = XN_QVGA_Y_RES; + mode.nFPS = 30; + break; + case CV_CAP_OPENNI_QVGA_60HZ : + mode.nXRes = XN_QVGA_X_RES; + mode.nYRes = XN_QVGA_Y_RES; + mode.nFPS = 60; + break; + default : + CV_Error( CV_StsBadArg, "Unsupported image generator output mode.\n"); + } + + XnStatus status = imageGenerator.SetMapOutputMode( mode ); + if( status != XN_STATUS_OK ) + std::cerr << "CvCapture_OpenNI::setImageGeneratorProperty : " << xnGetStatusString(status) << std::endl; + else + isSet = true; + break; + } + default: + { + std::stringstream ss; + ss << "Image generator does not support such parameter (propIdx=" << propIdx << ") for setting.\n"; + CV_Error( CV_StsBadArg, ss.str().c_str() ); + } + } + + return isSet; +} + +bool CvCapture_OpenNI::grabFrame() +{ + if( !isOpened() ) + return false; + + bool isGrabbed = false; + if( !approxSyncGrabber.empty() && approxSyncGrabber->isRun() ) + { + isGrabbed = approxSyncGrabber->grab( depthMetaData, imageMetaData ); + } + else + { + XnStatus status = context.WaitAndUpdateAll(); + if( status != XN_STATUS_OK ) + return false; + + if( depthGenerator.IsValid() ) + depthGenerator.GetMetaData( depthMetaData ); + if( imageGenerator.IsValid() ) + imageGenerator.GetMetaData( imageMetaData ); + isGrabbed = true; + } + + return isGrabbed; +} + +inline void getDepthMapFromMetaData( const xn::DepthMetaData& depthMetaData, cv::Mat& depthMap, XnUInt64 noSampleValue, XnUInt64 shadowValue ) +{ + int cols = depthMetaData.XRes(); + int rows = depthMetaData.YRes(); + + depthMap.create( rows, cols, CV_16UC1 ); + + const XnDepthPixel* pDepthMap = depthMetaData.Data(); + + // CV_Assert( sizeof(unsigned short) == sizeof(XnDepthPixel) ); + memcpy( depthMap.data, pDepthMap, cols*rows*sizeof(XnDepthPixel) ); + + cv::Mat badMask = (depthMap == (double)noSampleValue) | (depthMap == (double)shadowValue) | (depthMap == 0); + + // mask the pixels with invalid depth + depthMap.setTo( cv::Scalar::all( CvCapture_OpenNI::INVALID_PIXEL_VAL ), badMask ); +} + +IplImage* CvCapture_OpenNI::retrieveDepthMap() +{ + if( !depthMetaData.Data() ) + return 0; + + getDepthMapFromMetaData( depthMetaData, outputMaps[CV_CAP_OPENNI_DEPTH_MAP].mat, noSampleValue, shadowValue ); + + return outputMaps[CV_CAP_OPENNI_DEPTH_MAP].getIplImagePtr(); +} + +IplImage* CvCapture_OpenNI::retrievePointCloudMap() +{ + if( !depthMetaData.Data() ) + return 0; + + cv::Mat depth; + getDepthMapFromMetaData( depthMetaData, depth, noSampleValue, shadowValue ); + + const int badPoint = INVALID_PIXEL_VAL; + const float badCoord = INVALID_COORDINATE_VAL; + int cols = depthMetaData.XRes(), rows = depthMetaData.YRes(); + cv::Mat pointCloud_XYZ( rows, cols, CV_32FC3, cv::Scalar::all(badPoint) ); + + cv::Ptr proj = new XnPoint3D[cols*rows]; + cv::Ptr real = new XnPoint3D[cols*rows]; + for( int y = 0; y < rows; y++ ) + { + for( int x = 0; x < cols; x++ ) + { + int ind = y*cols+x; + proj[ind].X = (float)x; + proj[ind].Y = (float)y; + proj[ind].Z = depth.at(y, x); + } + } + depthGenerator.ConvertProjectiveToRealWorld(cols*rows, proj, real); + + for( int y = 0; y < rows; y++ ) + { + for( int x = 0; x < cols; x++ ) + { + // Check for invalid measurements + if( depth.at(y, x) == badPoint ) // not valid + pointCloud_XYZ.at(y,x) = cv::Point3f( badCoord, badCoord, badCoord ); + else + { + int ind = y*cols+x; + pointCloud_XYZ.at(y,x) = cv::Point3f( real[ind].X*0.001f, real[ind].Y*0.001f, real[ind].Z*0.001f); // from mm to meters + } + } + } + + outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].mat = pointCloud_XYZ; + + return outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].getIplImagePtr(); +} + +static void computeDisparity_32F( const xn::DepthMetaData& depthMetaData, cv::Mat& disp, XnDouble baseline, XnUInt64 F, + XnUInt64 noSampleValue, XnUInt64 shadowValue ) +{ + cv::Mat depth; + getDepthMapFromMetaData( depthMetaData, depth, noSampleValue, shadowValue ); + CV_Assert( depth.type() == CV_16UC1 ); + + + // disparity = baseline * F / z; + + float mult = (float)(baseline /*mm*/ * F /*pixels*/); + + disp.create( depth.size(), CV_32FC1); + disp = cv::Scalar::all( CvCapture_OpenNI::INVALID_PIXEL_VAL ); + for( int y = 0; y < disp.rows; y++ ) + { + for( int x = 0; x < disp.cols; x++ ) + { + unsigned short curDepth = depth.at(y,x); + if( curDepth != CvCapture_OpenNI::INVALID_PIXEL_VAL ) + disp.at(y,x) = mult / curDepth; + } + } +} + +IplImage* CvCapture_OpenNI::retrieveDisparityMap() +{ + if( !depthMetaData.Data() ) + return 0; + + cv::Mat disp32; + computeDisparity_32F( depthMetaData, disp32, baseline, depthFocalLength_VGA, noSampleValue, shadowValue ); + + disp32.convertTo( outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].mat, CV_8UC1 ); + + return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].getIplImagePtr(); +} + +IplImage* CvCapture_OpenNI::retrieveDisparityMap_32F() +{ + if( !depthMetaData.Data() ) + return 0; + + computeDisparity_32F( depthMetaData, outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].mat, baseline, depthFocalLength_VGA, noSampleValue, shadowValue ); + + return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].getIplImagePtr(); +} + +IplImage* CvCapture_OpenNI::retrieveValidDepthMask() +{ + if( !depthMetaData.Data() ) + return 0; + + cv::Mat depth; + getDepthMapFromMetaData( depthMetaData, depth, noSampleValue, shadowValue ); + + outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].mat = depth != CvCapture_OpenNI::INVALID_PIXEL_VAL; + + return outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].getIplImagePtr(); +} + +inline void getBGRImageFromMetaData( const xn::ImageMetaData& imageMetaData, cv::Mat& bgrImage ) +{ + if( imageMetaData.PixelFormat() != XN_PIXEL_FORMAT_RGB24 ) + CV_Error( CV_StsUnsupportedFormat, "Unsupported format of grabbed image\n" ); + + cv::Mat rgbImage( imageMetaData.YRes(), imageMetaData.XRes(), CV_8UC3 ); + const XnRGB24Pixel* pRgbImage = imageMetaData.RGB24Data(); + + // CV_Assert( 3*sizeof(uchar) == sizeof(XnRGB24Pixel) ); + memcpy( rgbImage.data, pRgbImage, rgbImage.total()*sizeof(XnRGB24Pixel) ); + cv::cvtColor( rgbImage, bgrImage, CV_RGB2BGR ); +} + +IplImage* CvCapture_OpenNI::retrieveBGRImage() +{ + if( !imageMetaData.Data() ) + return 0; + + getBGRImageFromMetaData( imageMetaData, outputMaps[CV_CAP_OPENNI_BGR_IMAGE].mat ); + + return outputMaps[CV_CAP_OPENNI_BGR_IMAGE].getIplImagePtr(); +} + +IplImage* CvCapture_OpenNI::retrieveGrayImage() +{ + if( !imageMetaData.Data() ) + return 0; + + CV_Assert( imageMetaData.BytesPerPixel() == 3 ); // RGB + + cv::Mat rgbImage; + getBGRImageFromMetaData( imageMetaData, rgbImage ); + cv::cvtColor( rgbImage, outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].mat, CV_BGR2GRAY ); + + return outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].getIplImagePtr(); +} + +IplImage* CvCapture_OpenNI::retrieveFrame( int outputType ) +{ + IplImage* image = 0; + CV_Assert( outputType < outputMapsTypesCount && outputType >= 0); + + if( outputType == CV_CAP_OPENNI_DEPTH_MAP ) + { + image = retrieveDepthMap(); + } + else if( outputType == CV_CAP_OPENNI_POINT_CLOUD_MAP ) + { + image = retrievePointCloudMap(); + } + else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP ) + { + image = retrieveDisparityMap(); + } + else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP_32F ) + { + image = retrieveDisparityMap_32F(); + } + else if( outputType == CV_CAP_OPENNI_VALID_DEPTH_MASK ) + { + image = retrieveValidDepthMask(); + } + else if( outputType == CV_CAP_OPENNI_BGR_IMAGE ) + { + image = retrieveBGRImage(); + } + else if( outputType == CV_CAP_OPENNI_GRAY_IMAGE ) + { + image = retrieveGrayImage(); + } + + return image; +} + + +CvCapture* cvCreateCameraCapture_OpenNI( int index ) +{ + CvCapture_OpenNI* capture = new CvCapture_OpenNI( index ); + + if( capture->isOpened() ) + return capture; + + delete capture; + return 0; +} + +CvCapture* cvCreateFileCapture_OpenNI( const char* filename ) +{ + CvCapture_OpenNI* capture = new CvCapture_OpenNI( filename ); + + if( capture->isOpened() ) + return capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_pvapi.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_pvapi.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_pvapi.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_pvapi.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,377 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +// + +// +// The code has been contributed by Justin G. Eskesen on 2010 Jan +// + +#include "precomp.hpp" + +#ifdef HAVE_PVAPI +#if !defined WIN32 && !defined _WIN32 && !defined _LINUX +#define _LINUX +#endif + +#if defined(_x64) || defined (__x86_64) || defined (_M_X64) +#define _x64 1 +#elif defined(_x86) || defined(__i386) || defined (_M_IX86) +#define _x86 1 +#endif + +#include +#ifdef WIN32 +# include +#else +# include +#endif + +#include +//#include + +#define MAX_CAMERAS 10 + +/********************* Capturing video from camera via PvAPI *********************/ + +class CvCaptureCAM_PvAPI : public CvCapture +{ +public: + CvCaptureCAM_PvAPI(); + virtual ~CvCaptureCAM_PvAPI() + { + close(); + } + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() + { + return CV_CAP_PVAPI; + } + +protected: +#ifndef WIN32 + virtual void Sleep(unsigned int time); +#endif + + typedef struct + { + unsigned long UID; + tPvHandle Handle; + tPvFrame Frame; + } tCamera; + + IplImage *frame; + IplImage *grayframe; + tCamera Camera; + tPvErr Errcode; + bool monocrome; +}; + + +CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI() +{ + monocrome=false; + memset(&this->Camera, 0, sizeof(this->Camera)); +} + +#ifndef WIN32 +void CvCaptureCAM_PvAPI::Sleep(unsigned int time) +{ + struct timespec t,r; + + t.tv_sec = time / 1000; + t.tv_nsec = (time % 1000) * 1000000; + + while(nanosleep(&t,&r)==-1) + t = r; +} +#endif + +void CvCaptureCAM_PvAPI::close() +{ + // Stop the acquisition & free the camera + PvCommandRun(Camera.Handle, "AcquisitionStop"); + PvCaptureEnd(Camera.Handle); + PvCameraClose(Camera.Handle); + PvUnInitialize(); +} + +// Initialize camera input +bool CvCaptureCAM_PvAPI::open( int index ) +{ + tPvCameraInfo cameraList[MAX_CAMERAS]; + + tPvCameraInfo camInfo; + tPvIpSettings ipSettings; + + + if (PvInitialize()) { + } + //return false; + + Sleep(1000); + + //close(); + + int numCameras=PvCameraList(cameraList, MAX_CAMERAS, NULL); + + if (numCameras <= 0 || index >= numCameras) + return false; + + Camera.UID = cameraList[index].UniqueId; + + if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings)) { + /* + struct in_addr addr; + addr.s_addr = ipSettings.CurrentIpAddress; + printf("Current address:\t%s\n",inet_ntoa(addr)); + addr.s_addr = ipSettings.CurrentIpSubnet; + printf("Current subnet:\t\t%s\n",inet_ntoa(addr)); + addr.s_addr = ipSettings.CurrentIpGateway; + printf("Current gateway:\t%s\n",inet_ntoa(addr)); + */ + } + else { + fprintf(stderr,"ERROR: could not retrieve camera IP settings.\n"); + return false; + } + + + if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess) + { + + //Set Pixel Format to BRG24 to follow conventions + /*Errcode = PvAttrEnumSet(Camera.Handle, "PixelFormat", "Bgr24"); + if (Errcode != ePvErrSuccess) + { + fprintf(stderr, "PvAPI: couldn't set PixelFormat to Bgr24\n"); + return NULL; + } + */ + tPvUint32 frameWidth, frameHeight, frameSize; + unsigned long maxSize; + char pixelFormat[256]; + PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize); + PvAttrUint32Get(Camera.Handle, "Width", &frameWidth); + PvAttrUint32Get(Camera.Handle, "Height", &frameHeight); + PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); + maxSize = 8228; + //PvAttrUint32Get(Camera.Handle,"PacketSize",&maxSize); + if (PvCaptureAdjustPacketSize(Camera.Handle,maxSize)!=ePvErrSuccess) + return false; + if (strcmp(pixelFormat, "Mono8")==0) { + grayframe = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1); + grayframe->widthStep = (int)frameWidth; + frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3); + frame->widthStep = (int)frameWidth*3; + Camera.Frame.ImageBufferSize = frameSize; + Camera.Frame.ImageBuffer = grayframe->imageData; + } + else if (strcmp(pixelFormat, "Mono16")==0) { + grayframe = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1); + grayframe->widthStep = (int)frameWidth; + frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 3); + frame->widthStep = (int)frameWidth*3; + Camera.Frame.ImageBufferSize = frameSize; + Camera.Frame.ImageBuffer = grayframe->imageData; + } + else if (strcmp(pixelFormat, "Bgr24")==0) { + frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3); + frame->widthStep = (int)frameWidth*3; + Camera.Frame.ImageBufferSize = frameSize; + Camera.Frame.ImageBuffer = frame->imageData; + } + else + return false; + // Start the camera + PvCaptureStart(Camera.Handle); + + // Set the camera to capture continuously + if(PvAttrEnumSet(Camera.Handle, "AcquisitionMode", "Continuous")!= ePvErrSuccess) + { + fprintf(stderr,"Could not set Prosilica Acquisition Mode\n"); + return false; + } + + if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess) + { + fprintf(stderr,"Could not start Prosilica acquisition\n"); + return false; + } + + if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess) + { + fprintf(stderr,"Error setting Prosilica trigger to \"Freerun\""); + return false; + } + + return true; + } + fprintf(stderr,"Error cannot open camera\n"); + return false; + +} + +bool CvCaptureCAM_PvAPI::grabFrame() +{ + //if(Camera.Frame.Status != ePvErrUnplugged && Camera.Frame.Status != ePvErrCancelled) + return PvCaptureQueueFrame(Camera.Handle, &(Camera.Frame), NULL) == ePvErrSuccess; +} + + +IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int) +{ + + if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess) { + if (!monocrome) { + cvMerge(grayframe,grayframe,grayframe,NULL,frame); + return frame; + } + return grayframe; + } + else return NULL; +} + +double CvCaptureCAM_PvAPI::getProperty( int property_id ) +{ + tPvUint32 nTemp; + + switch ( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + PvAttrUint32Get(Camera.Handle, "Width", &nTemp); + return (double)nTemp; + case CV_CAP_PROP_FRAME_HEIGHT: + PvAttrUint32Get(Camera.Handle, "Height", &nTemp); + return (double)nTemp; + case CV_CAP_PROP_EXPOSURE: + PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp); + return (double)nTemp; + case CV_CAP_PROP_FPS: + tPvFloat32 nfTemp; + PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp); + return (double)nfTemp; + case CV_CAP_PROP_PVAPI_MULTICASTIP: + char mEnable[2]; + char mIp[11]; + PvAttrEnumGet(Camera.Handle,"MulticastEnable",mEnable,sizeof(mEnable),NULL); + if (strcmp(mEnable, "Off") == 0) { + return -1; + } + else { + long int ip; + int a,b,c,d; + PvAttrStringGet(Camera.Handle, "MulticastIPAddress",mIp,sizeof(mIp),NULL); + sscanf(mIp, "%d.%d.%d.%d", &a, &b, &c, &d); ip = ((a*256 + b)*256 + c)*256 + d; + return (double)ip; + } + } + return -1.0; +} + +bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value ) +{ + switch ( property_id ) + { + /* TODO: Camera works, but IplImage must be modified for the new size + case CV_CAP_PROP_FRAME_WIDTH: + PvAttrUint32Set(Camera.Handle, "Width", (tPvUint32)value); + break; + case CV_CAP_PROP_FRAME_HEIGHT: + PvAttrUint32Set(Camera.Handle, "Heigth", (tPvUint32)value); + break; + */ + case CV_CAP_PROP_MONOCROME: + if (value==1) { + char pixelFormat[256]; + PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); + if ((strcmp(pixelFormat, "Mono8")==0) || strcmp(pixelFormat, "Mono16")==0) { + monocrome=true; + } + else + return false; + } + else + monocrome=false; + break; + case CV_CAP_PROP_EXPOSURE: + if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess)) + break; + else + return false; + case CV_CAP_PROP_PVAPI_MULTICASTIP: + + if (value==-1) { + if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess)) + break; + else + return false; + } + else { + std::string ip=cv::format("%d.%d.%d.%d", ((int)value>>24)&255, ((int)value>>16)&255, ((int)value>>8)&255, (int)value&255); + if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "On")==ePvErrSuccess) && + (PvAttrStringSet(Camera.Handle, "MulticastIPAddress", ip.c_str())==ePvErrSuccess)) + break; + else + return false; + } + default: + return false; + } + return true; +} + + +CvCapture* cvCreateCameraCapture_PvAPI( int index ) +{ + CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI; + + if ( capture->open( index )) + return capture; + + delete capture; + return NULL; +} +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_qt.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_qt.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_qt.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_qt.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1619 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + + +#include "precomp.hpp" + +// Original implementation by Mark Asbach +// Institute of Communications Engineering +// RWTH Aachen University +// +// For implementation details and background see: +// http://developer.apple.com/samplecode/qtframestepper.win/listing1.html +// +// Please note that timing will only be correct for videos that contain a visual track +// that has full length (compared to other tracks) + + +// standard includes +#include +#include + +// Mac OS includes +#include +#include +#include + + +// Global state (did we call EnterMovies?) +static int did_enter_movies = 0; + +// ---------------------------------------------------------------------------------------- +#pragma mark Reading Video Files + +/// Movie state structure for QuickTime movies +typedef struct CvCapture_QT_Movie +{ + Movie myMovie; // movie handle + GWorldPtr myGWorld; // we render into an offscreen GWorld + + CvSize size; // dimensions of the movie + TimeValue movie_start_time; // movies can start at arbitrary times + long number_of_frames; // duration in frames + long next_frame_time; + long next_frame_number; + + IplImage * image_rgb; // will point to the PixMap of myGWorld + IplImage * image_bgr; // will be returned by icvRetrieveFrame_QT() + +} CvCapture_QT_Movie; + + +static int icvOpenFile_QT_Movie (CvCapture_QT_Movie * capture, const char * filename); +static int icvClose_QT_Movie (CvCapture_QT_Movie * capture); +static double icvGetProperty_QT_Movie (CvCapture_QT_Movie * capture, int property_id); +static int icvSetProperty_QT_Movie (CvCapture_QT_Movie * capture, int property_id, double value); +static int icvGrabFrame_QT_Movie (CvCapture_QT_Movie * capture); +static const void * icvRetrieveFrame_QT_Movie (CvCapture_QT_Movie * capture, int); + + +static CvCapture_QT_Movie * icvCaptureFromFile_QT (const char * filename) +{ + static int did_enter_movies = 0; + if (! did_enter_movies) + { + EnterMovies(); + did_enter_movies = 1; + } + + CvCapture_QT_Movie * capture = 0; + + if (filename) + { + capture = (CvCapture_QT_Movie *) cvAlloc (sizeof (*capture)); + memset (capture, 0, sizeof(*capture)); + + if (!icvOpenFile_QT_Movie (capture, filename)) + cvFree( &capture ); + } + + return capture; +} + + + +/** + * convert full path to CFStringRef and open corresponding Movie. Then + * step over 'interesting frame times' to count total number of frames + * for video material with varying frame durations and create offscreen + * GWorld for rendering the movie frames. + * + * @author Mark Asbach + * @date 2005-11-04 + */ +static int icvOpenFile_QT_Movie (CvCapture_QT_Movie * capture, const char * filename) +{ + Rect myRect; + short myResID = 0; + Handle myDataRef = nil; + OSType myDataRefType = 0; + OSErr myErr = noErr; + + + // no old errors please + ClearMoviesStickyError (); + + // initialize pointers to zero + capture->myMovie = 0; + capture->myGWorld = nil; + + // initialize numbers with invalid values + capture->next_frame_time = -1; + capture->next_frame_number = -1; + capture->number_of_frames = -1; + capture->movie_start_time = -1; + capture->size = cvSize (-1,-1); + + + // we would use CFStringCreateWithFileSystemRepresentation (kCFAllocatorDefault, filename) on Mac OS X 10.4 + CFStringRef inPath = CFStringCreateWithCString (kCFAllocatorDefault, filename, kCFStringEncodingISOLatin1); + OPENCV_ASSERT ((inPath != nil), "icvOpenFile_QT_Movie", "couldnt create CFString from a string"); + + // create the data reference + myErr = QTNewDataReferenceFromFullPathCFString (inPath, kQTPOSIXPathStyle, 0, & myDataRef, & myDataRefType); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't create QTNewDataReferenceFromFullPathCFString().\n"); + return 0; + } + + // get the Movie + myErr = NewMovieFromDataRef(& capture->myMovie, newMovieActive | newMovieAsyncOK /* | newMovieIdleImportOK */, + & myResID, myDataRef, myDataRefType); + + // dispose of the data reference handle - we no longer need it + DisposeHandle (myDataRef); + + // if NewMovieFromDataRef failed, we already disposed the DataRef, so just return with an error + if (myErr != noErr) + { + fprintf (stderr, "Couldn't create a NewMovieFromDataRef() - error is %d.\n", myErr); + return 0; + } + + // count the number of video 'frames' in the movie by stepping through all of the + // video 'interesting times', or in other words, the places where the movie displays + // a new video sample. The time between these interesting times is not necessarily constant. + { + OSType whichMediaType = VisualMediaCharacteristic; + TimeValue theTime = -1; + + // find out movie start time + GetMovieNextInterestingTime (capture->myMovie, short (nextTimeMediaSample + nextTimeEdgeOK), + 1, & whichMediaType, TimeValue (0), 0, & theTime, NULL); + if (theTime == -1) + { + fprintf (stderr, "Couldn't inquire first frame time\n"); + return 0; + } + capture->movie_start_time = theTime; + capture->next_frame_time = theTime; + capture->next_frame_number = 0; + + // count all 'interesting times' of the movie + capture->number_of_frames = 0; + while (theTime >= 0) + { + GetMovieNextInterestingTime (capture->myMovie, short (nextTimeMediaSample), + 1, & whichMediaType, theTime, 0, & theTime, NULL); + capture->number_of_frames++; + } + } + + // get the bounding rectangle of the movie + GetMoviesError (); + GetMovieBox (capture->myMovie, & myRect); + capture->size = cvSize (myRect.right - myRect.left, myRect.bottom - myRect.top); + + // create gworld for decompressed image + myErr = QTNewGWorld (& capture->myGWorld, k32ARGBPixelFormat /* k24BGRPixelFormat geht leider nicht */, + & myRect, nil, nil, 0); + OPENCV_ASSERT (myErr == noErr, "icvOpenFile_QT_Movie", "couldnt create QTNewGWorld() for output image"); + SetMovieGWorld (capture->myMovie, capture->myGWorld, nil); + + // build IplImage header that will point to the PixMap of the Movie's GWorld later on + capture->image_rgb = cvCreateImageHeader (capture->size, IPL_DEPTH_8U, 4); + + // create IplImage that hold correctly formatted result + capture->image_bgr = cvCreateImage (capture->size, IPL_DEPTH_8U, 3); + + // okay, that's it - should we wait until the Movie is playable? + return 1; +} + +/** + * dispose of QuickTime Movie and free memory buffers + * + * @author Mark Asbach + * @date 2005-11-04 + */ +static int icvClose_QT_Movie (CvCapture_QT_Movie * capture) +{ + OPENCV_ASSERT (capture, "icvClose_QT_Movie", "'capture' is a NULL-pointer"); + + // deallocate and free resources + if (capture->myMovie) + { + cvReleaseImage (& capture->image_bgr); + cvReleaseImageHeader (& capture->image_rgb); + DisposeGWorld (capture->myGWorld); + DisposeMovie (capture->myMovie); + } + + // okay, that's it + return 1; +} + +/** + * get a capture property + * + * @author Mark Asbach + * @date 2005-11-05 + */ +static double icvGetProperty_QT_Movie (CvCapture_QT_Movie * capture, int property_id) +{ + OPENCV_ASSERT (capture, "icvGetProperty_QT_Movie", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->myMovie, "icvGetProperty_QT_Movie", "invalid Movie handle"); + OPENCV_ASSERT (capture->number_of_frames > 0, "icvGetProperty_QT_Movie", "movie has invalid number of frames"); + OPENCV_ASSERT (capture->movie_start_time >= 0, "icvGetProperty_QT_Movie", "movie has invalid start time"); + + // inquire desired property + switch (property_id) + { + case CV_CAP_PROP_POS_FRAMES: + return (capture->next_frame_number); + + case CV_CAP_PROP_POS_MSEC: + case CV_CAP_PROP_POS_AVI_RATIO: + { + TimeValue position = capture->next_frame_time - capture->movie_start_time; + + if (property_id == CV_CAP_PROP_POS_MSEC) + { + TimeScale timescale = GetMovieTimeScale (capture->myMovie); + return (static_cast (position) * 1000.0 / timescale); + } + else + { + TimeValue duration = GetMovieDuration (capture->myMovie); + return (static_cast (position) / duration); + } + } + break; // never reached + + case CV_CAP_PROP_FRAME_WIDTH: + return static_cast (capture->size.width); + + case CV_CAP_PROP_FRAME_HEIGHT: + return static_cast (capture->size.height); + + case CV_CAP_PROP_FPS: + { + TimeValue duration = GetMovieDuration (capture->myMovie); + TimeScale timescale = GetMovieTimeScale (capture->myMovie); + + return (capture->number_of_frames / (static_cast (duration) / timescale)); + } + + case CV_CAP_PROP_FRAME_COUNT: + return static_cast (capture->number_of_frames); + + case CV_CAP_PROP_FOURCC: // not implemented + case CV_CAP_PROP_FORMAT: // not implemented + case CV_CAP_PROP_MODE: // not implemented + default: + // unhandled or unknown capture property + OPENCV_ERROR (CV_StsBadArg, "icvSetProperty_QT_Movie", "unknown or unhandled property_id"); + return CV_StsBadArg; + } + + return 0; +} + +/** + * set a capture property. With movie files, it is only possible to set the + * position (i.e. jump to a given time or frame number) + * + * @author Mark Asbach + * @date 2005-11-05 + */ +static int icvSetProperty_QT_Movie (CvCapture_QT_Movie * capture, int property_id, double value) +{ + OPENCV_ASSERT (capture, "icvSetProperty_QT_Movie", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->myMovie, "icvSetProperty_QT_Movie", "invalid Movie handle"); + OPENCV_ASSERT (capture->number_of_frames > 0, "icvSetProperty_QT_Movie", "movie has invalid number of frames"); + OPENCV_ASSERT (capture->movie_start_time >= 0, "icvSetProperty_QT_Movie", "movie has invalid start time"); + + // inquire desired property + // + // rework these three points to really work through 'interesting times'. + // with the current implementation, they result in wrong times or wrong frame numbers with content that + // features varying frame durations + switch (property_id) + { + case CV_CAP_PROP_POS_MSEC: + case CV_CAP_PROP_POS_AVI_RATIO: + { + TimeValue destination; + OSType myType = VisualMediaCharacteristic; + OSErr myErr = noErr; + + if (property_id == CV_CAP_PROP_POS_MSEC) + { + TimeScale timescale = GetMovieTimeScale (capture->myMovie); + destination = static_cast (value / 1000.0 * timescale + capture->movie_start_time); + } + else + { + TimeValue duration = GetMovieDuration (capture->myMovie); + destination = static_cast (value * duration + capture->movie_start_time); + } + + // really seek? + if (capture->next_frame_time == destination) + break; + + // seek into which direction? + if (capture->next_frame_time < destination) + { + while (capture->next_frame_time < destination) + { + capture->next_frame_number++; + GetMovieNextInterestingTime (capture->myMovie, nextTimeStep, 1, & myType, capture->next_frame_time, + 1, & capture->next_frame_time, NULL); + myErr = GetMoviesError(); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't go on to GetMovieNextInterestingTime() in icvGrabFrame_QT.\n"); + return 0; + } + } + } + else + { + while (capture->next_frame_time > destination) + { + capture->next_frame_number--; + GetMovieNextInterestingTime (capture->myMovie, nextTimeStep, 1, & myType, capture->next_frame_time, + -1, & capture->next_frame_time, NULL); + myErr = GetMoviesError(); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't go back to GetMovieNextInterestingTime() in icvGrabFrame_QT.\n"); + return 0; + } + } + } + } + break; + + case CV_CAP_PROP_POS_FRAMES: + { + TimeValue destination = static_cast (value); + short direction = (destination > capture->next_frame_number) ? 1 : -1; + OSType myType = VisualMediaCharacteristic; + OSErr myErr = noErr; + + while (destination != capture->next_frame_number) + { + capture->next_frame_number += direction; + GetMovieNextInterestingTime (capture->myMovie, nextTimeStep, 1, & myType, capture->next_frame_time, + direction, & capture->next_frame_time, NULL); + myErr = GetMoviesError(); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't step to desired frame number in icvGrabFrame_QT.\n"); + return 0; + } + } + } + break; + + default: + // unhandled or unknown capture property + OPENCV_ERROR (CV_StsBadArg, "icvSetProperty_QT_Movie", "unknown or unhandled property_id"); + return 0; + } + + // positive result means success + return 1; +} + +/** + * the original meaning of this method is to acquire raw frame data for the next video + * frame but not decompress it. With the QuickTime video reader, this is reduced to + * advance to the current frame time. + * + * @author Mark Asbach + * @date 2005-11-06 + */ +static int icvGrabFrame_QT_Movie (CvCapture_QT_Movie * capture) +{ + OPENCV_ASSERT (capture, "icvGrabFrame_QT_Movie", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->myMovie, "icvGrabFrame_QT_Movie", "invalid Movie handle"); + + TimeValue myCurrTime; + OSType myType = VisualMediaCharacteristic; + OSErr myErr = noErr; + + + // jump to current video sample + SetMovieTimeValue (capture->myMovie, capture->next_frame_time); + myErr = GetMoviesError(); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't SetMovieTimeValue() in icvGrabFrame_QT_Movie.\n"); + return 0; + } + + // where are we now? + myCurrTime = GetMovieTime (capture->myMovie, NULL); + + // increment counters + capture->next_frame_number++; + GetMovieNextInterestingTime (capture->myMovie, nextTimeStep, 1, & myType, myCurrTime, 1, & capture->next_frame_time, NULL); + myErr = GetMoviesError(); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't GetMovieNextInterestingTime() in icvGrabFrame_QT_Movie.\n"); + return 0; + } + + // that's it + return 1; +} + +/** + * render the current frame into an image buffer and convert to OpenCV IplImage + * buffer layout (BGR sampling) + * + * @author Mark Asbach + * @date 2005-11-06 + */ +static const void * icvRetrieveFrame_QT_Movie (CvCapture_QT_Movie * capture, int) +{ + OPENCV_ASSERT (capture, "icvRetrieveFrame_QT_Movie", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->myMovie, "icvRetrieveFrame_QT_Movie", "invalid Movie handle"); + OPENCV_ASSERT (capture->image_rgb, "icvRetrieveFrame_QT_Movie", "invalid source image"); + OPENCV_ASSERT (capture->image_bgr, "icvRetrieveFrame_QT_Movie", "invalid destination image"); + + PixMapHandle myPixMapHandle = nil; + OSErr myErr = noErr; + + + // invalidates the movie's display state so that the Movie Toolbox + // redraws the movie the next time we call MoviesTask + UpdateMovie (capture->myMovie); + myErr = GetMoviesError (); + if (myErr != noErr) + { + fprintf (stderr, "Couldn't UpdateMovie() in icvRetrieveFrame_QT_Movie().\n"); + return 0; + } + + // service active movie (= redraw immediately) + MoviesTask (capture->myMovie, 0L); + myErr = GetMoviesError (); + if (myErr != noErr) + { + fprintf (stderr, "MoviesTask() didn't succeed in icvRetrieveFrame_QT_Movie().\n"); + return 0; + } + + // update IplImage header that points to PixMap of the Movie's GWorld. + // unfortunately, cvCvtColor doesn't know ARGB, the QuickTime pixel format, + // so we pass a modfied address. + // ATTENTION: don't access the last pixel's alpha entry, it's inexistant + myPixMapHandle = GetGWorldPixMap (capture->myGWorld); + LockPixels (myPixMapHandle); + cvSetData (capture->image_rgb, GetPixBaseAddr (myPixMapHandle) + 1, GetPixRowBytes (myPixMapHandle)); + + // covert RGB of GWorld to BGR + cvCvtColor (capture->image_rgb, capture->image_bgr, CV_RGBA2BGR); + + // allow QuickTime to access the buffer again + UnlockPixels (myPixMapHandle); + + // always return the same image pointer + return capture->image_bgr; +} + + +// ---------------------------------------------------------------------------------------- +#pragma mark - +#pragma mark Capturing from Video Cameras + +#ifdef USE_VDIG_VERSION + + /// SequenceGrabber state structure for QuickTime + typedef struct CvCapture_QT_Cam_vdig + { + ComponentInstance grabber; + short channel; + GWorldPtr myGWorld; + PixMapHandle pixmap; + + CvSize size; + long number_of_frames; + + IplImage * image_rgb; // will point to the PixMap of myGWorld + IplImage * image_bgr; // will be returned by icvRetrieveFrame_QT() + + } CvCapture_QT_Cam; + +#else + + typedef struct CvCapture_QT_Cam_barg + { + SeqGrabComponent grabber; + SGChannel channel; + GWorldPtr gworld; + Rect bounds; + ImageSequence sequence; + + volatile bool got_frame; + + CvSize size; + IplImage * image_rgb; // will point to the PixMap of myGWorld + IplImage * image_bgr; // will be returned by icvRetrieveFrame_QT() + + } CvCapture_QT_Cam; + +#endif + +static int icvOpenCamera_QT (CvCapture_QT_Cam * capture, const int index); +static int icvClose_QT_Cam (CvCapture_QT_Cam * capture); +static double icvGetProperty_QT_Cam (CvCapture_QT_Cam * capture, int property_id); +static int icvSetProperty_QT_Cam (CvCapture_QT_Cam * capture, int property_id, double value); +static int icvGrabFrame_QT_Cam (CvCapture_QT_Cam * capture); +static const void * icvRetrieveFrame_QT_Cam (CvCapture_QT_Cam * capture, int); + + +/** + * Initialize memory structure and call method to open camera + * + * @author Mark Asbach + * @date 2006-01-29 + */ +static CvCapture_QT_Cam * icvCaptureFromCam_QT (const int index) +{ + if (! did_enter_movies) + { + EnterMovies(); + did_enter_movies = 1; + } + + CvCapture_QT_Cam * capture = 0; + + if (index >= 0) + { + capture = (CvCapture_QT_Cam *) cvAlloc (sizeof (*capture)); + memset (capture, 0, sizeof(*capture)); + + if (!icvOpenCamera_QT (capture, index)) + cvFree (&capture); + } + + return capture; +} + +/// capture properties currently unimplemented for QuickTime camera interface +static double icvGetProperty_QT_Cam (CvCapture_QT_Cam * capture, int property_id) +{ + assert (0); + return 0; +} + +/// capture properties currently unimplemented for QuickTime camera interface +static int icvSetProperty_QT_Cam (CvCapture_QT_Cam * capture, int property_id, double value) +{ + assert (0); + return 0; +} + +#ifdef USE_VDIG_VERSION +#pragma mark Capturing using VDIG + +/** + * Open a quicktime video grabber component. This could be an attached + * IEEE1394 camera, a web cam, an iSight or digitizer card / video converter. + * + * @author Mark Asbach + * @date 2006-01-29 + */ +static int icvOpenCamera_QT (CvCapture_QT_Cam * capture, const int index) +{ + OPENCV_ASSERT (capture, "icvOpenCamera_QT", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (index >=0, "icvOpenCamera_QT", "camera index is negative"); + + ComponentDescription component_description; + Component component = 0; + int number_of_inputs = 0; + Rect myRect; + ComponentResult result = noErr; + + + // travers all components and count video digitizer channels + component_description.componentType = videoDigitizerComponentType; + component_description.componentSubType = 0L; + component_description.componentManufacturer = 0L; + component_description.componentFlags = 0L; + component_description.componentFlagsMask = 0L; + do + { + // traverse component list + component = FindNextComponent (component, & component_description); + + // found a component? + if (component) + { + // dump component name + #ifndef NDEBUG + ComponentDescription desc; + Handle nameHandle = NewHandleClear (200); + char nameBuffer [255]; + + result = GetComponentInfo (component, & desc, nameHandle, nil, nil); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt GetComponentInfo()"); + OPENCV_ASSERT (*nameHandle, "icvOpenCamera_QT", "No name returned by GetComponentInfo()"); + snprintf (nameBuffer, (**nameHandle) + 1, "%s", (char *) (* nameHandle + 1)); + printf ("- Videodevice: %s\n", nameBuffer); + DisposeHandle (nameHandle); + #endif + + // open component to count number of inputs + capture->grabber = OpenComponent (component); + if (capture->grabber) + { + result = VDGetNumberOfInputs (capture->grabber, & capture->channel); + if (result != noErr) + fprintf (stderr, "Couldnt GetNumberOfInputs: %d\n", (int) result); + else + { + #ifndef NDEBUG + printf (" Number of inputs: %d\n", (int) capture->channel + 1); + #endif + + // add to overall number of inputs + number_of_inputs += capture->channel + 1; + + // did the user select an input that falls into this device's + // range of inputs? Then leave the loop + if (number_of_inputs > index) + { + // calculate relative channel index + capture->channel = index - number_of_inputs + capture->channel + 1; + OPENCV_ASSERT (capture->channel >= 0, "icvOpenCamera_QT", "negative channel number"); + + // dump channel name + #ifndef NDEBUG + char name[256]; + Str255 nameBuffer; + + result = VDGetInputName (capture->grabber, capture->channel, nameBuffer); + OPENCV_ASSERT (result == noErr, "ictOpenCamera_QT", "couldnt GetInputName()"); + snprintf (name, *nameBuffer, "%s", (char *) (nameBuffer + 1)); + printf (" Choosing input %d - %s\n", (int) capture->channel, name); + #endif + + // leave the loop + break; + } + } + + // obviously no inputs of this device/component were needed + CloseComponent (capture->grabber); + } + } + } + while (component); + + // did we find the desired input? + if (! component) + { + fprintf(stderr, "Not enough inputs available - can't choose input %d\n", index); + return 0; + } + + // -- Okay now, we selected the digitizer input, lets set up digitizer destination -- + + ClearMoviesStickyError(); + + // Select the desired input + result = VDSetInput (capture->grabber, capture->channel); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt select video digitizer input"); + + // get the bounding rectangle of the video digitizer + result = VDGetActiveSrcRect (capture->grabber, capture->channel, & myRect); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt create VDGetActiveSrcRect from digitizer"); + myRect.right = 640; myRect.bottom = 480; + capture->size = cvSize (myRect.right - myRect.left, myRect.bottom - myRect.top); + printf ("Source rect is %d, %d -- %d, %d\n", (int) myRect.left, (int) myRect.top, (int) myRect.right, (int) myRect.bottom); + + // create offscreen GWorld + result = QTNewGWorld (& capture->myGWorld, k32ARGBPixelFormat, & myRect, nil, nil, 0); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt create QTNewGWorld() for output image"); + + // get pixmap + capture->pixmap = GetGWorldPixMap (capture->myGWorld); + result = GetMoviesError (); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt get pixmap"); + + // set digitizer rect + result = VDSetDigitizerRect (capture->grabber, & myRect); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt create VDGetActiveSrcRect from digitizer"); + + // set destination of digitized input + result = VDSetPlayThruDestination (capture->grabber, capture->pixmap, & myRect, nil, nil); + printf ("QuickTime error: %d\n", (int) result); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set video destination"); + + // get destination of digitized images + result = VDGetPlayThruDestination (capture->grabber, & capture->pixmap, nil, nil, nil); + printf ("QuickTime error: %d\n", (int) result); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt get video destination"); + OPENCV_ASSERT (capture->pixmap != nil, "icvOpenCamera_QT", "empty set video destination"); + + // get the bounding rectangle of the video digitizer + GetPixBounds (capture->pixmap, & myRect); + capture->size = cvSize (myRect.right - myRect.left, myRect.bottom - myRect.top); + + // build IplImage header that will point to the PixMap of the Movie's GWorld later on + capture->image_rgb = cvCreateImageHeader (capture->size, IPL_DEPTH_8U, 4); + OPENCV_ASSERT (capture->image_rgb, "icvOpenCamera_QT", "couldnt create image header"); + + // create IplImage that hold correctly formatted result + capture->image_bgr = cvCreateImage (capture->size, IPL_DEPTH_8U, 3); + OPENCV_ASSERT (capture->image_bgr, "icvOpenCamera_QT", "couldnt create image"); + + // notify digitizer component, that we well be starting grabbing soon + result = VDCaptureStateChanging (capture->grabber, vdFlagCaptureIsForRecord | vdFlagCaptureStarting | vdFlagCaptureLowLatency); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set capture state"); + + + // yeah, we did it + return 1; +} + +static int icvClose_QT_Cam (CvCapture_QT_Cam * capture) +{ + OPENCV_ASSERT (capture, "icvClose_QT_Cam", "'capture' is a NULL-pointer"); + + ComponentResult result = noErr; + + // notify digitizer component, that we well be stopping grabbing soon + result = VDCaptureStateChanging (capture->grabber, vdFlagCaptureStopping); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set capture state"); + + // release memory + cvReleaseImage (& capture->image_bgr); + cvReleaseImageHeader (& capture->image_rgb); + DisposeGWorld (capture->myGWorld); + CloseComponent (capture->grabber); + + // sucessful + return 1; +} + +static int icvGrabFrame_QT_Cam (CvCapture_QT_Cam * capture) +{ + OPENCV_ASSERT (capture, "icvGrabFrame_QT_Cam", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->grabber, "icvGrabFrame_QT_Cam", "'grabber' is a NULL-pointer"); + + ComponentResult result = noErr; + + // grab one frame + result = VDGrabOneFrame (capture->grabber); + if (result != noErr) + { + fprintf (stderr, "VDGrabOneFrame failed\n"); + return 0; + } + + // successful + return 1; +} + +static const void * icvRetrieveFrame_QT_Cam (CvCapture_QT_Cam * capture, int) +{ + OPENCV_ASSERT (capture, "icvRetrieveFrame_QT_Cam", "'capture' is a NULL-pointer"); + + PixMapHandle myPixMapHandle = nil; + + // update IplImage header that points to PixMap of the Movie's GWorld. + // unfortunately, cvCvtColor doesn't know ARGB, the QuickTime pixel format, + // so we pass a modfied address. + // ATTENTION: don't access the last pixel's alpha entry, it's inexistant + //myPixMapHandle = GetGWorldPixMap (capture->myGWorld); + myPixMapHandle = capture->pixmap; + LockPixels (myPixMapHandle); + cvSetData (capture->image_rgb, GetPixBaseAddr (myPixMapHandle) + 1, GetPixRowBytes (myPixMapHandle)); + + // covert RGB of GWorld to BGR + cvCvtColor (capture->image_rgb, capture->image_bgr, CV_RGBA2BGR); + + // allow QuickTime to access the buffer again + UnlockPixels (myPixMapHandle); + + // always return the same image pointer + return capture->image_bgr; +} + +#else +#pragma mark Capturing using Sequence Grabber + +static OSErr icvDataProc_QT_Cam (SGChannel channel, Ptr raw_data, long len, long *, long, TimeValue, short, long refCon) +{ + CvCapture_QT_Cam * capture = (CvCapture_QT_Cam *) refCon; + CodecFlags ignore; + ComponentResult err = noErr; + + + // we need valid pointers + OPENCV_ASSERT (capture, "icvDataProc_QT_Cam", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->gworld, "icvDataProc_QT_Cam", "'gworld' is a NULL-pointer"); + OPENCV_ASSERT (raw_data, "icvDataProc_QT_Cam", "'raw_data' is a NULL-pointer"); + + // create a decompression sequence the first time + if (capture->sequence == 0) + { + ImageDescriptionHandle description = (ImageDescriptionHandle) NewHandle(0); + + // we need a decompression sequence that fits the raw data coming from the camera + err = SGGetChannelSampleDescription (channel, (Handle) description); + OPENCV_ASSERT (err == noErr, "icvDataProc_QT_Cam", "couldnt get channel sample description"); + + //*************************************************************************************// + //This fixed a bug when Quicktime is called twice to grab a frame (black band bug) - Yannick Verdie 2010 + Rect sourceRect; + sourceRect.top = 0; + sourceRect.left = 0; + sourceRect.right = (**description).width; + sourceRect.bottom = (**description).height; + + MatrixRecord scaleMatrix; + RectMatrix(&scaleMatrix,&sourceRect,&capture->bounds); + + err = DecompressSequenceBegin (&capture->sequence, description, capture->gworld, 0,&capture->bounds,&scaleMatrix, srcCopy, NULL, 0, codecNormalQuality, bestSpeedCodec); + //**************************************************************************************// + + OPENCV_ASSERT (err == noErr, "icvDataProc_QT_Cam", "couldnt begin decompression sequence"); + DisposeHandle ((Handle) description); + } + + // okay, we have a decompression sequence -> decompress! + err = DecompressSequenceFrameS (capture->sequence, raw_data, len, 0, &ignore, nil); + if (err != noErr) + { + fprintf (stderr, "icvDataProc_QT_Cam: couldn't decompress frame - %d\n", (int) err); + return err; + } + + // check if we dropped a frame + /*#ifndef NDEBUG + if (capture->got_frame) + fprintf (stderr, "icvDataProc_QT_Cam: frame was dropped\n"); + #endif*/ + + // everything worked as expected + capture->got_frame = true; + return noErr; +} + + +static int icvOpenCamera_QT (CvCapture_QT_Cam * capture, const int index) +{ + OPENCV_ASSERT (capture, "icvOpenCamera_QT", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (index >= 0, "icvOpenCamera_QT", "camera index is negative"); + + PixMapHandle pixmap = nil; + OSErr result = noErr; + + // open sequence grabber component + capture->grabber = OpenDefaultComponent (SeqGrabComponentType, 0); + OPENCV_ASSERT (capture->grabber, "icvOpenCamera_QT", "couldnt create image"); + + // initialize sequence grabber component + result = SGInitialize (capture->grabber); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt initialize sequence grabber"); + result = SGSetDataRef (capture->grabber, 0, 0, seqGrabDontMakeMovie); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set data reference of sequence grabber"); + + // set up video channel + result = SGNewChannel (capture->grabber, VideoMediaType, & (capture->channel)); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt create new video channel"); + + // select the camera indicated by index + SGDeviceList device_list = 0; + result = SGGetChannelDeviceList (capture->channel, 0, & device_list); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt get channel device list"); + for (int i = 0, current_index = 1; i < (*device_list)->count; i++) + { + SGDeviceName device = (*device_list)->entry[i]; + if (device.flags == 0) + { + if (current_index == index) + { + result = SGSetChannelDevice (capture->channel, device.name); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set the channel video device"); + break; + } + current_index++; + } + } + result = SGDisposeDeviceList (capture->grabber, device_list); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt dispose the channel device list"); + + // query natural camera resolution -- this will be wrong, but will be an upper + // bound on the actual resolution -- the actual resolution is set below + // after starting the frame grabber + result = SGGetSrcVideoBounds (capture->channel, & (capture->bounds)); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set video channel bounds"); + + // create offscreen GWorld + result = QTNewGWorld (& (capture->gworld), k32ARGBPixelFormat, & (capture->bounds), 0, 0, 0); + result = SGSetGWorld (capture->grabber, capture->gworld, 0); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set GWorld for sequence grabber"); + result = SGSetChannelBounds (capture->channel, & (capture->bounds)); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set video channel bounds"); + result = SGSetChannelUsage (capture->channel, seqGrabRecord); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set channel usage"); + + // start recording so we can size + result = SGStartRecord (capture->grabber); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt start recording"); + + // don't know *actual* resolution until now + ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0); + result = SGGetChannelSampleDescription(capture->channel, (Handle)imageDesc); + OPENCV_ASSERT( result == noErr, "icvOpenCamera_QT", "couldn't get image size"); + capture->bounds.right = (**imageDesc).width; + capture->bounds.bottom = (**imageDesc).height; + DisposeHandle ((Handle) imageDesc); + + // stop grabber so that we can reset the parameters to the right size + result = SGStop (capture->grabber); + OPENCV_ASSERT (result == noErr, "icveClose_QT_Cam", "couldnt stop recording"); + + // reset GWorld to correct image size + GWorldPtr tmpgworld; + result = QTNewGWorld( &tmpgworld, k32ARGBPixelFormat, &(capture->bounds), 0, 0, 0); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt create offscreen GWorld"); + result = SGSetGWorld( capture->grabber, tmpgworld, 0); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set GWorld for sequence grabber"); + DisposeGWorld( capture->gworld ); + capture->gworld = tmpgworld; + + result = SGSetChannelBounds (capture->channel, & (capture->bounds)); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set video channel bounds"); + + // allocate images + capture->size = cvSize (capture->bounds.right - capture->bounds.left, capture->bounds.bottom - capture->bounds.top); + + // build IplImage header that points to the PixMap of the Movie's GWorld. + // unfortunately, cvCvtColor doesn't know ARGB, the QuickTime pixel format, + // so we shift the base address by one byte. + // ATTENTION: don't access the last pixel's alpha entry, it's inexistant + capture->image_rgb = cvCreateImageHeader (capture->size, IPL_DEPTH_8U, 4); + OPENCV_ASSERT (capture->image_rgb, "icvOpenCamera_QT", "couldnt create image header"); + pixmap = GetGWorldPixMap (capture->gworld); + OPENCV_ASSERT (pixmap, "icvOpenCamera_QT", "didn't get GWorld PixMap handle"); + LockPixels (pixmap); + cvSetData (capture->image_rgb, GetPixBaseAddr (pixmap) + 1, GetPixRowBytes (pixmap)); + + // create IplImage that hold correctly formatted result + capture->image_bgr = cvCreateImage (capture->size, IPL_DEPTH_8U, 3); + OPENCV_ASSERT (capture->image_bgr, "icvOpenCamera_QT", "couldnt create image"); + + + // tell the sequence grabber to invoke our data proc + result = SGSetDataProc (capture->grabber, NewSGDataUPP (icvDataProc_QT_Cam), (long) capture); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt set data proc"); + + // start recording + result = SGStartRecord (capture->grabber); + OPENCV_ASSERT (result == noErr, "icvOpenCamera_QT", "couldnt start recording"); + + return 1; +} + + +static int icvClose_QT_Cam (CvCapture_QT_Cam * capture) +{ + OPENCV_ASSERT (capture, "icvClose_QT_Cam", "'capture' is a NULL-pointer"); + + OSErr result = noErr; + + + // stop recording + result = SGStop (capture->grabber); + OPENCV_ASSERT (result == noErr, "icveClose_QT_Cam", "couldnt stop recording"); + + // close sequence grabber component + result = CloseComponent (capture->grabber); + OPENCV_ASSERT (result == noErr, "icveClose_QT_Cam", "couldnt close sequence grabber component"); + + // end decompression sequence + CDSequenceEnd (capture->sequence); + + // free memory + cvReleaseImage (& capture->image_bgr); + cvReleaseImageHeader (& capture->image_rgb); + DisposeGWorld (capture->gworld); + + // sucessful + return 1; +} + +static int icvGrabFrame_QT_Cam (CvCapture_QT_Cam * capture) +{ + OPENCV_ASSERT (capture, "icvGrabFrame_QT_Cam", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->grabber, "icvGrabFrame_QT_Cam", "'grabber' is a NULL-pointer"); + + ComponentResult result = noErr; + + + // grab one frame + result = SGIdle (capture->grabber); + if (result != noErr) + { + fprintf (stderr, "SGIdle failed in icvGrabFrame_QT_Cam with error %d\n", (int) result); + return 0; + } + + // successful + return 1; +} + +static const void * icvRetrieveFrame_QT_Cam (CvCapture_QT_Cam * capture, int) +{ + OPENCV_ASSERT (capture, "icvRetrieveFrame_QT_Cam", "'capture' is a NULL-pointer"); + OPENCV_ASSERT (capture->image_rgb, "icvRetrieveFrame_QT_Cam", "invalid source image"); + OPENCV_ASSERT (capture->image_bgr, "icvRetrieveFrame_QT_Cam", "invalid destination image"); + + OSErr myErr = noErr; + + + // service active sequence grabbers (= redraw immediately) + while (! capture->got_frame) + { + myErr = SGIdle (capture->grabber); + if (myErr != noErr) + { + fprintf (stderr, "SGIdle() didn't succeed in icvRetrieveFrame_QT_Cam().\n"); + return 0; + } + } + + // covert RGB of GWorld to BGR + cvCvtColor (capture->image_rgb, capture->image_bgr, CV_RGBA2BGR); + + // reset grabbing status + capture->got_frame = false; + + // always return the same image pointer + return capture->image_bgr; +} + +#endif + + +typedef struct CvVideoWriter_QT { + + DataHandler data_handler; + Movie movie; + Track track; + Media video; + + ICMCompressionSessionRef compression_session_ref; + + TimeValue duration_per_sample; +} CvVideoWriter_QT; + + +static TimeScale const TIME_SCALE = 600; + +static OSStatus icvEncodedFrameOutputCallback( + void* writer, + ICMCompressionSessionRef compression_session_ref, + OSStatus error, + ICMEncodedFrameRef encoded_frame_ref, + void* reserved +); + +static void icvSourceTrackingCallback( + void *source_tracking_ref_con, + ICMSourceTrackingFlags source_tracking_flags, + void *source_frame_ref_con, + void *reserved +); + +static int icvWriteFrame_QT( + CvVideoWriter_QT * video_writer, + const IplImage * image +) { + CVPixelBufferRef pixel_buffer_ref = NULL; + CVReturn retval = + CVPixelBufferCreate( + kCFAllocatorDefault, + image->width, image->height, k24RGBPixelFormat, + NULL /* pixel_buffer_attributes */, + &pixel_buffer_ref + ); + + // convert BGR IPL image to RGB pixel buffer + IplImage* image_rgb = + cvCreateImageHeader( + cvSize( image->width, image->height ), + IPL_DEPTH_8U, + 3 + ); + + retval = CVPixelBufferLockBaseAddress( pixel_buffer_ref, 0 ); + + void* base_address = CVPixelBufferGetBaseAddress( pixel_buffer_ref ); + size_t bytes_per_row = CVPixelBufferGetBytesPerRow( pixel_buffer_ref ); + cvSetData( image_rgb, base_address, bytes_per_row ); + + cvConvertImage( image, image_rgb, CV_CVTIMG_SWAP_RB ); + + retval = CVPixelBufferUnlockBaseAddress( pixel_buffer_ref, 0 ); + + cvReleaseImageHeader( &image_rgb ); + + ICMSourceTrackingCallbackRecord source_tracking_callback_record; + source_tracking_callback_record.sourceTrackingCallback = + icvSourceTrackingCallback; + source_tracking_callback_record.sourceTrackingRefCon = NULL; + + OSStatus status = + ICMCompressionSessionEncodeFrame( + video_writer->compression_session_ref, + pixel_buffer_ref, + 0, + video_writer->duration_per_sample, + kICMValidTime_DisplayDurationIsValid, + NULL, + &source_tracking_callback_record, + static_cast( &pixel_buffer_ref ) + ); + + return 0; +} + +static void icvReleaseVideoWriter_QT( CvVideoWriter_QT ** writer ) { + if ( ( writer != NULL ) && ( *writer != NULL ) ) { + CvVideoWriter_QT* video_writer = *writer; + + // force compression session to complete encoding of outstanding source + // frames + ICMCompressionSessionCompleteFrames( + video_writer->compression_session_ref, TRUE, 0, 0 + ); + + EndMediaEdits( video_writer->video ); + + ICMCompressionSessionRelease( video_writer->compression_session_ref ); + + InsertMediaIntoTrack( + video_writer->track, + 0, + 0, + GetMediaDuration( video_writer->video ), + FixRatio( 1, 1 ) + ); + + UpdateMovieInStorage( video_writer->movie, video_writer->data_handler ); + + CloseMovieStorage( video_writer->data_handler ); + +/* + // export to AVI + Handle data_ref; + OSType data_ref_type; + QTNewDataReferenceFromFullPathCFString( + CFSTR( "/Users/seibert/Desktop/test.avi" ), kQTPOSIXPathStyle, 0, + &data_ref, &data_ref_type + ); + + ConvertMovieToDataRef( video_writer->movie, NULL, data_ref, + data_ref_type, kQTFileTypeAVI, 'TVOD', 0, NULL ); + + DisposeHandle( data_ref ); +*/ + + DisposeMovie( video_writer->movie ); + + cvFree( writer ); + } +} + +static OSStatus icvEncodedFrameOutputCallback( + void* writer, + ICMCompressionSessionRef compression_session_ref, + OSStatus error, + ICMEncodedFrameRef encoded_frame_ref, + void* reserved +) { + CvVideoWriter_QT* video_writer = static_cast( writer ); + + OSStatus err = AddMediaSampleFromEncodedFrame( video_writer->video, + encoded_frame_ref, NULL ); + + return err; +} + +static void icvSourceTrackingCallback( + void *source_tracking_ref_con, + ICMSourceTrackingFlags source_tracking_flags, + void *source_frame_ref_con, + void *reserved +) { + if ( source_tracking_flags & kICMSourceTracking_ReleasedPixelBuffer ) { + CVPixelBufferRelease( + *static_cast( source_frame_ref_con ) + ); + } +} + + +static CvVideoWriter_QT* icvCreateVideoWriter_QT( + const char * filename, + int fourcc, + double fps, + CvSize frame_size, + int is_color +) { + CV_FUNCNAME( "icvCreateVideoWriter" ); + + CvVideoWriter_QT* video_writer = + static_cast( cvAlloc( sizeof( CvVideoWriter_QT ) ) ); + memset( video_writer, 0, sizeof( CvVideoWriter_QT ) ); + + Handle data_ref = NULL; + OSType data_ref_type; + DataHandler data_handler = NULL; + Movie movie = NULL; + ICMCompressionSessionOptionsRef options_ref = NULL; + ICMCompressionSessionRef compression_session_ref = NULL; + CFStringRef out_path = nil; + Track video_track = nil; + Media video = nil; + OSErr err = noErr; + CodecType codecType = kRawCodecType; + + __BEGIN__ + + // validate input arguments + if ( filename == NULL ) { + CV_ERROR( CV_StsBadArg, "Video file name must not be NULL" ); + } + if ( fps <= 0.0 ) { + CV_ERROR( CV_StsBadArg, "FPS must be larger than 0.0" ); + } + if ( ( frame_size.width <= 0 ) || ( frame_size.height <= 0 ) ) { + CV_ERROR( CV_StsBadArg, + "Frame width and height must be larger than 0" ); + } + + // initialize QuickTime + if ( !did_enter_movies ) { + err = EnterMovies(); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Unable to initialize QuickTime" ); + } + did_enter_movies = 1; + } + + // convert the file name into a data reference + out_path = CFStringCreateWithCString( kCFAllocatorDefault, filename, kCFStringEncodingISOLatin1 ); + CV_ASSERT( out_path != nil ); + err = QTNewDataReferenceFromFullPathCFString( out_path, kQTPOSIXPathStyle, + 0, &data_ref, &data_ref_type ); + CFRelease( out_path ); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, + "Cannot create data reference from file name" ); + } + + // create a new movie on disk + err = CreateMovieStorage( data_ref, data_ref_type, 'TVOD', + smCurrentScript, newMovieActive, &data_handler, &movie ); + + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot create movie storage" ); + } + + // create a track with video + video_track = NewMovieTrack (movie, + FixRatio( frame_size.width, 1 ), + FixRatio( frame_size.height, 1 ), + kNoVolume); + err = GetMoviesError(); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot create video track" ); + } + video = NewTrackMedia( video_track, VideoMediaType, TIME_SCALE, nil, 0 ); + err = GetMoviesError(); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot create video media" ); + } + + /*if( fourcc == CV_FOURCC( 'D', 'I', 'B', ' ' )) + codecType = kRawCodecType;*/ + + // start a compression session + err = ICMCompressionSessionOptionsCreate( kCFAllocatorDefault, + &options_ref ); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot create compression session options" ); + } + err = ICMCompressionSessionOptionsSetAllowTemporalCompression( options_ref, + true ); + if ( err != noErr) { + CV_ERROR( CV_StsInternal, "Cannot enable temporal compression" ); + } + err = ICMCompressionSessionOptionsSetAllowFrameReordering( options_ref, + true ); + if ( err != noErr) { + CV_ERROR( CV_StsInternal, "Cannot enable frame reordering" ); + } + + ICMEncodedFrameOutputRecord encoded_frame_output_record; + encoded_frame_output_record.encodedFrameOutputCallback = + icvEncodedFrameOutputCallback; + encoded_frame_output_record.encodedFrameOutputRefCon = + static_cast( video_writer ); + encoded_frame_output_record.frameDataAllocator = NULL; + + err = ICMCompressionSessionCreate( kCFAllocatorDefault, frame_size.width, + frame_size.height, codecType, TIME_SCALE, options_ref, + NULL /*source_pixel_buffer_attributes*/, &encoded_frame_output_record, + &compression_session_ref ); + ICMCompressionSessionOptionsRelease( options_ref ); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot create compression session" ); + } + + err = BeginMediaEdits( video ); + if ( err != noErr ) { + CV_ERROR( CV_StsInternal, "Cannot begin media edits" ); + } + + // fill in the video writer structure + video_writer->data_handler = data_handler; + video_writer->movie = movie; + video_writer->track = video_track; + video_writer->video = video; + video_writer->compression_session_ref = compression_session_ref; + video_writer->duration_per_sample = + static_cast( static_cast( TIME_SCALE ) / fps ); + + __END__ + + // clean up in case of error (unless error processing mode is + // CV_ErrModeLeaf) + if ( err != noErr ) { + if ( options_ref != NULL ) { + ICMCompressionSessionOptionsRelease( options_ref ); + } + if ( compression_session_ref != NULL ) { + ICMCompressionSessionRelease( compression_session_ref ); + } + if ( data_handler != NULL ) { + CloseMovieStorage( data_handler ); + } + if ( movie != NULL ) { + DisposeMovie( movie ); + } + if ( data_ref != NULL ) { + DeleteMovieStorage( data_ref, data_ref_type ); + DisposeHandle( data_ref ); + } + cvFree( reinterpret_cast( &video_writer ) ); + video_writer = NULL; + } + + return video_writer; +} + + +/** +* +* Wrappers for the new C++ CvCapture & CvVideoWriter structures +* +*/ + +class CvCapture_QT_Movie_CPP : public CvCapture +{ +public: + CvCapture_QT_Movie_CPP() { captureQT = 0; } + virtual ~CvCapture_QT_Movie_CPP() { close(); } + + virtual bool open( const char* filename ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_QT; } // Return the type of the capture object: CV_CAP_VFW, etc... +protected: + + CvCapture_QT_Movie* captureQT; +}; + +bool CvCapture_QT_Movie_CPP::open( const char* filename ) +{ + close(); + captureQT = icvCaptureFromFile_QT( filename ); + return captureQT != 0; +} + +void CvCapture_QT_Movie_CPP::close() +{ + if( captureQT ) + { + icvClose_QT_Movie( captureQT ); + cvFree( &captureQT ); + } +} + +bool CvCapture_QT_Movie_CPP::grabFrame() +{ + return captureQT ? icvGrabFrame_QT_Movie( captureQT ) != 0 : false; +} + +IplImage* CvCapture_QT_Movie_CPP::retrieveFrame(int) +{ + return captureQT ? (IplImage*)icvRetrieveFrame_QT_Movie( captureQT, 0 ) : 0; +} + +double CvCapture_QT_Movie_CPP::getProperty( int propId ) +{ + return captureQT ? icvGetProperty_QT_Movie( captureQT, propId ) : 0; +} + +bool CvCapture_QT_Movie_CPP::setProperty( int propId, double value ) +{ + return captureQT ? icvSetProperty_QT_Movie( captureQT, propId, value ) != 0 : false; +} + +CvCapture* cvCreateFileCapture_QT( const char* filename ) +{ + CvCapture_QT_Movie_CPP* capture = new CvCapture_QT_Movie_CPP; + + if( capture->open( filename )) + return capture; + + delete capture; + return 0; +} + + +///////////////////////////////////// + +class CvCapture_QT_Cam_CPP : public CvCapture +{ +public: + CvCapture_QT_Cam_CPP() { captureQT = 0; } + virtual ~CvCapture_QT_Cam_CPP() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_QT; } // Return the type of the capture object: CV_CAP_VFW, etc... +protected: + + CvCapture_QT_Cam* captureQT; +}; + +bool CvCapture_QT_Cam_CPP::open( int index ) +{ + close(); + captureQT = icvCaptureFromCam_QT( index ); + return captureQT != 0; +} + +void CvCapture_QT_Cam_CPP::close() +{ + if( captureQT ) + { + icvClose_QT_Cam( captureQT ); + cvFree( &captureQT ); + } +} + +bool CvCapture_QT_Cam_CPP::grabFrame() +{ + return captureQT ? icvGrabFrame_QT_Cam( captureQT ) != 0 : false; +} + +IplImage* CvCapture_QT_Cam_CPP::retrieveFrame(int) +{ + return captureQT ? (IplImage*)icvRetrieveFrame_QT_Cam( captureQT, 0 ) : 0; +} + +double CvCapture_QT_Cam_CPP::getProperty( int propId ) +{ + return captureQT ? icvGetProperty_QT_Cam( captureQT, propId ) : 0; +} + +bool CvCapture_QT_Cam_CPP::setProperty( int propId, double value ) +{ + return captureQT ? icvSetProperty_QT_Cam( captureQT, propId, value ) != 0 : false; +} + +CvCapture* cvCreateCameraCapture_QT( int index ) +{ + CvCapture_QT_Cam_CPP* capture = new CvCapture_QT_Cam_CPP; + + if( capture->open( index )) + return capture; + + delete capture; + return 0; +} + +///////////////////////////////// + +class CvVideoWriter_QT_CPP : public CvVideoWriter +{ +public: + CvVideoWriter_QT_CPP() { writerQT = 0; } + virtual ~CvVideoWriter_QT_CPP() { close(); } + + virtual bool open( const char* filename, int fourcc, + double fps, CvSize frameSize, bool isColor ); + virtual void close(); + virtual bool writeFrame( const IplImage* ); + +protected: + CvVideoWriter_QT* writerQT; +}; + +bool CvVideoWriter_QT_CPP::open( const char* filename, int fourcc, + double fps, CvSize frameSize, bool isColor ) +{ + close(); + writerQT = icvCreateVideoWriter_QT( filename, fourcc, fps, frameSize, isColor ); + return writerQT != 0; +} + +void CvVideoWriter_QT_CPP::close() +{ + if( writerQT ) + { + icvReleaseVideoWriter_QT( &writerQT ); + writerQT = 0; + } +} + +bool CvVideoWriter_QT_CPP::writeFrame( const IplImage* image ) +{ + if( !writerQT || !image ) + return false; + return icvWriteFrame_QT( writerQT, image ) >= 0; +} + +CvVideoWriter* cvCreateVideoWriter_QT( const char* filename, int fourcc, + double fps, CvSize frameSize, int isColor ) +{ + CvVideoWriter_QT_CPP* writer = new CvVideoWriter_QT_CPP; + if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 )) + return writer; + delete writer; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_qtkit.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_qtkit.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_qtkit.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_qtkit.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1031 @@ +/* + * CvCapture.mm + * + * Created by Nicholas Butko on 11/3/09. + * Copyright 2009. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include +#import + +using namespace std; + +/********************** Declaration of class headers ************************/ + +/***************************************************************************** + * + * CaptureDelegate Declaration. + * + * CaptureDelegate is notified on a separate thread by the OS whenever there + * is a new frame. When "updateImage" is called from the main thread, it + * copies this new frame into an IplImage, but only if this frame has not + * been copied before. When "getOutput" is called from the main thread, + * it gives the last copied IplImage. + * + *****************************************************************************/ + +#ifndef QTKIT_VERSION_7_6_3 +#define QTKIT_VERSION_7_6_3 70603 +#define QTKIT_VERSION_7_0 70000 +#endif + +#ifndef QTKIT_VERSION_MAX_ALLOWED +#define QTKIT_VERSION_MAX_ALLOWED QTKIT_VERSION_7_0 +#endif + +#define DISABLE_AUTO_RESTART 999 + +@interface CaptureDelegate : NSObject +{ + int newFrame; + CVImageBufferRef mCurrentImageBuffer; + char* imagedata; + IplImage* image; + char* bgr_imagedata; + IplImage* bgr_image; + size_t currSize; +} + +- (void)captureOutput:(QTCaptureOutput *)captureOutput + didOutputVideoFrame:(CVImageBufferRef)videoFrame + withSampleBuffer:(QTSampleBuffer *)sampleBuffer + fromConnection:(QTCaptureConnection *)connection; + +- (void)captureOutput:(QTCaptureOutput *)captureOutput +didDropVideoFrameWithSampleBuffer:(QTSampleBuffer *)sampleBuffer + fromConnection:(QTCaptureConnection *)connection; + +- (int)updateImage; +- (IplImage*)getOutput; + +@end + +/***************************************************************************** + * + * CvCaptureCAM Declaration. + * + * CvCaptureCAM is the instantiation of a capture source for cameras. + * + *****************************************************************************/ + +class CvCaptureCAM : public CvCapture { +public: + CvCaptureCAM(int cameraNum = -1) ; + ~CvCaptureCAM(); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual double getProperty(int property_id); + virtual bool setProperty(int property_id, double value); + virtual int didStart(); + + +private: + QTCaptureSession *mCaptureSession; + QTCaptureDeviceInput *mCaptureDeviceInput; + QTCaptureDecompressedVideoOutput *mCaptureDecompressedVideoOutput; + CaptureDelegate* capture; + + int startCaptureDevice(int cameraNum); + void stopCaptureDevice(); + + void setWidthHeight(); + bool grabFrame(double timeOut); + + int camNum; + int width; + int height; + int settingWidth; + int settingHeight; + int started; + int disableAutoRestart; + +}; + + +/***************************************************************************** + * + * CvCaptureFile Declaration. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +class CvCaptureFile : public CvCapture { +public: + CvCaptureFile(const char* filename) ; + ~CvCaptureFile(); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual double getProperty(int property_id); + virtual bool setProperty(int property_id, double value); + virtual int didStart(); + + +private: + QTMovie *mCaptureSession; + + char* imagedata; + IplImage* image; + char* bgr_imagedata; + IplImage* bgr_image; + size_t currSize; + + //IplImage* retrieveFrameBitmap(); + IplImage* retrieveFramePixelBuffer(); + double getFPS(); + + int movieWidth; + int movieHeight; + double movieFPS; + double currentFPS; + double movieDuration; + int changedPos; + + int started; +}; + + +/***************************************************************************** + * + * CvCaptureFile Declaration. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +class CvVideoWriter_QT : public CvVideoWriter{ +public: + CvVideoWriter_QT(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color=1); + ~CvVideoWriter_QT(); + bool writeFrame(const IplImage* image); +private: + IplImage* argbimage; + QTMovie* mMovie; + unsigned char* imagedata; + + NSString* path; + NSString* codec; + double movieFPS; + CvSize movieSize; + int movieColor; +}; + + +/****************** Implementation of interface functions ********************/ + + +CvCapture* cvCreateFileCapture_QT(const char* filename) { + CvCaptureFile *retval = new CvCaptureFile(filename); + + if(retval->didStart()) + return retval; + delete retval; + return NULL; +} + +CvCapture* cvCreateCameraCapture_QT(int index ) { + CvCapture* retval = new CvCaptureCAM(index); + if (!((CvCaptureCAM *)retval)->didStart()) + cvReleaseCapture(&retval); + return retval; +} + +CvVideoWriter* cvCreateVideoWriter_QT(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color) { + return new CvVideoWriter_QT(filename, fourcc, fps, frame_size,is_color); +} + +/********************** Implementation of Classes ****************************/ + +/***************************************************************************** + * + * CvCaptureCAM Implementation. + * + * CvCaptureCAM is the instantiation of a capture source for cameras. + * + *****************************************************************************/ + +CvCaptureCAM::CvCaptureCAM(int cameraNum) { + mCaptureSession = nil; + mCaptureDeviceInput = nil; + mCaptureDecompressedVideoOutput = nil; + capture = nil; + + width = 0; + height = 0; + settingWidth = 0; + settingHeight = 0; + disableAutoRestart = 0; + + camNum = cameraNum; + + if (!startCaptureDevice(camNum)) { + cout << "Warning, camera failed to properly initialize!" << endl; + started = 0; + } else { + started = 1; + } + +} + +CvCaptureCAM::~CvCaptureCAM() { + stopCaptureDevice(); + + cout << "Cleaned up camera." << endl; +} + +int CvCaptureCAM::didStart() { + return started; +} + + +bool CvCaptureCAM::grabFrame() { + return grabFrame(5); +} + +bool CvCaptureCAM::grabFrame(double timeOut) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + double sleepTime = 0.005; + double total = 0; + + NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:sleepTime]; + while (![capture updateImage] && (total += sleepTime)<=timeOut && + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate:loopUntil]) + loopUntil = [NSDate dateWithTimeIntervalSinceNow:sleepTime]; + + [localpool drain]; + + return total <= timeOut; +} + +IplImage* CvCaptureCAM::retrieveFrame(int) { + return [capture getOutput]; +} + +void CvCaptureCAM::stopCaptureDevice() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + [mCaptureSession stopRunning]; + + QTCaptureDevice *device = [mCaptureDeviceInput device]; + if ([device isOpen]) [device close]; + + [mCaptureSession release]; + [mCaptureDeviceInput release]; + + [mCaptureDecompressedVideoOutput setDelegate:mCaptureDecompressedVideoOutput]; + [mCaptureDecompressedVideoOutput release]; + [capture release]; + [localpool drain]; + +} + +int CvCaptureCAM::startCaptureDevice(int cameraNum) { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + capture = [[CaptureDelegate alloc] init]; + + QTCaptureDevice *device; + NSArray* devices = [[[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo] + arrayByAddingObjectsFromArray:[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeMuxed]] retain]; + + if ([devices count] == 0) { + cout << "QTKit didn't find any attached Video Input Devices!" << endl; + [localpool drain]; + return 0; + } + + if (cameraNum >= 0) { + int nCameras = [devices count]; + if( cameraNum < 0 || cameraNum >= nCameras ) + return 0; + device = [devices objectAtIndex:cameraNum] ; + } else { + device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo] ; + } + int success; + NSError* error; + + if (device) { + + success = [device open:&error]; + if (!success) { + cout << "QTKit failed to open a Video Capture Device" << endl; + [localpool drain]; + return 0; + } + + mCaptureDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:device] ; + mCaptureSession = [[QTCaptureSession alloc] init] ; + + success = [mCaptureSession addInput:mCaptureDeviceInput error:&error]; + + if (!success) { + cout << "QTKit failed to start capture session with opened Capture Device" << endl; + [localpool drain]; + return 0; + } + + + mCaptureDecompressedVideoOutput = [[QTCaptureDecompressedVideoOutput alloc] init]; + [mCaptureDecompressedVideoOutput setDelegate:capture]; + NSDictionary *pixelBufferOptions ; + if (width > 0 && height > 0) { + pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithDouble:1.0*width], (id)kCVPixelBufferWidthKey, + [NSNumber numberWithDouble:1.0*height], (id)kCVPixelBufferHeightKey, + //[NSNumber numberWithUnsignedInt:k32BGRAPixelFormat], (id)kCVPixelBufferPixelFormatTypeKey, + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + } else { + pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + } + [mCaptureDecompressedVideoOutput setPixelBufferAttributes:pixelBufferOptions]; + +#if QTKIT_VERSION_MAX_ALLOWED >= QTKIT_VERSION_7_6_3 + [mCaptureDecompressedVideoOutput setAutomaticallyDropsLateVideoFrames:YES]; +#endif + + + success = [mCaptureSession addOutput:mCaptureDecompressedVideoOutput error:&error]; + if (!success) { + cout << "QTKit failed to add Output to Capture Session" << endl; + [localpool drain]; + return 0; + } + + [mCaptureSession startRunning]; + + grabFrame(60); + + return 1; + } + + [localpool drain]; + return 0; +} + +void CvCaptureCAM::setWidthHeight() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + NSDictionary* pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithDouble:1.0*width], (id)kCVPixelBufferWidthKey, + [NSNumber numberWithDouble:1.0*height], (id)kCVPixelBufferHeightKey, + [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], + (id)kCVPixelBufferPixelFormatTypeKey, + nil]; + + [mCaptureDecompressedVideoOutput setPixelBufferAttributes:pixelBufferOptions]; + grabFrame(60); + [localpool drain]; +} + + +double CvCaptureCAM::getProperty(int property_id){ + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + NSArray* connections = [mCaptureDeviceInput connections]; + QTFormatDescription* format = [[connections objectAtIndex:0] formatDescription]; + NSSize s1 = [[format attributeForKey:QTFormatDescriptionVideoCleanApertureDisplaySizeAttribute] sizeValue]; + + int width=s1.width, height=s1.height; + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + return width; + case CV_CAP_PROP_FRAME_HEIGHT: + return height; + default: + return 0; + } + + [localpool drain]; + +} + +bool CvCaptureCAM::setProperty(int property_id, double value) { + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + width = value; + settingWidth = 1; + if (settingWidth && settingHeight) { + setWidthHeight(); + settingWidth =0; + settingHeight = 0; + } + return true; + case CV_CAP_PROP_FRAME_HEIGHT: + height = value; + settingHeight = 1; + if (settingWidth && settingHeight) { + setWidthHeight(); + settingWidth =0; + settingHeight = 0; + } + return true; + case DISABLE_AUTO_RESTART: + disableAutoRestart = value; + return 1; + default: + return false; + } +} + + +/***************************************************************************** + * + * CaptureDelegate Implementation. + * + * CaptureDelegate is notified on a separate thread by the OS whenever there + * is a new frame. When "updateImage" is called from the main thread, it + * copies this new frame into an IplImage, but only if this frame has not + * been copied before. When "getOutput" is called from the main thread, + * it gives the last copied IplImage. + * + *****************************************************************************/ + + +@implementation CaptureDelegate + +- (id)init { + [super init]; + newFrame = 0; + imagedata = NULL; + bgr_imagedata = NULL; + currSize = 0; + image = NULL; + bgr_image = NULL; + return self; +} + + +-(void)dealloc { + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + cvReleaseImage(&image); + cvReleaseImage(&bgr_image); + [super dealloc]; +} + +- (void)captureOutput:(QTCaptureOutput *)captureOutput + didOutputVideoFrame:(CVImageBufferRef)videoFrame + withSampleBuffer:(QTSampleBuffer *)sampleBuffer + fromConnection:(QTCaptureConnection *)connection { + (void)captureOutput; + (void)sampleBuffer; + (void)connection; + + CVBufferRetain(videoFrame); + CVImageBufferRef imageBufferToRelease = mCurrentImageBuffer; + + @synchronized (self) { + + mCurrentImageBuffer = videoFrame; + newFrame = 1; + } + + CVBufferRelease(imageBufferToRelease); + +} +- (void)captureOutput:(QTCaptureOutput *)captureOutput +didDropVideoFrameWithSampleBuffer:(QTSampleBuffer *)sampleBuffer + fromConnection:(QTCaptureConnection *)connection { + (void)captureOutput; + (void)sampleBuffer; + (void)connection; + cout << "Camera dropped frame!" << endl; +} + +-(IplImage*) getOutput { + return bgr_image; +} + +-(int) updateImage { + if (newFrame==0) return 0; + CVPixelBufferRef pixels; + + @synchronized (self){ + pixels = CVBufferRetain(mCurrentImageBuffer); + newFrame = 0; + } + + CVPixelBufferLockBaseAddress(pixels, 0); + uint32_t* baseaddress = (uint32_t*)CVPixelBufferGetBaseAddress(pixels); + + size_t width = CVPixelBufferGetWidth(pixels); + size_t height = CVPixelBufferGetHeight(pixels); + size_t rowBytes = CVPixelBufferGetBytesPerRow(pixels); + + if (rowBytes != 0) { + + if (currSize != rowBytes*height*sizeof(char)) { + currSize = rowBytes*height*sizeof(char); + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + imagedata = (char*)malloc(currSize); + bgr_imagedata = (char*)malloc(currSize); + } + + memcpy(imagedata, baseaddress, currSize); + + if (image == NULL) { + image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 4); + } + image->width =width; + image->height = height; + image->nChannels = 4; + image->depth = IPL_DEPTH_8U; + image->widthStep = rowBytes; + image->imageData = imagedata; + image->imageSize = currSize; + + if (bgr_image == NULL) { + bgr_image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 3); + } + bgr_image->width =width; + bgr_image->height = height; + bgr_image->nChannels = 3; + bgr_image->depth = IPL_DEPTH_8U; + bgr_image->widthStep = rowBytes; + bgr_image->imageData = bgr_imagedata; + bgr_image->imageSize = currSize; + + cvCvtColor(image, bgr_image, CV_BGRA2BGR); + + } + + CVPixelBufferUnlockBaseAddress(pixels, 0); + CVBufferRelease(pixels); + + return 1; +} + +@end + + +/***************************************************************************** + * + * CvCaptureFile Implementation. + * + * CvCaptureFile is the instantiation of a capture source for video files. + * + *****************************************************************************/ + +CvCaptureFile::CvCaptureFile(const char* filename) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + + mCaptureSession = nil; + image = NULL; + bgr_image = NULL; + imagedata = NULL; + bgr_imagedata = NULL; + currSize = 0; + + movieWidth = 0; + movieHeight = 0; + movieFPS = 0; + currentFPS = 0; + movieDuration = 0; + changedPos = 0; + + started = 0; + + NSError* error; + + + mCaptureSession = [[QTMovie movieWithFile:[NSString stringWithCString:filename + encoding:NSASCIIStringEncoding] + error:&error] retain]; + [mCaptureSession setAttribute:[NSNumber numberWithBool:YES] + forKey:QTMovieLoopsAttribute]; + + if (mCaptureSession == nil) { + cout << "WARNING: Couldn't read movie file " << filename << endl; + [localpool drain]; + started = 0; + return; + } + + + [mCaptureSession gotoBeginning]; + + NSSize size = [[mCaptureSession attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]; + + movieWidth = size.width; + movieHeight = size.height; + movieFPS = getFPS(); + currentFPS = movieFPS; + + QTTime t; + + [[mCaptureSession attributeForKey:QTMovieDurationAttribute] getValue:&t]; + movieDuration = (t.timeValue *1000.0 / t.timeScale); + started = 1; + [localpool drain]; + +} + +CvCaptureFile::~CvCaptureFile() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + cvReleaseImage(&image); + cvReleaseImage(&bgr_image); + [mCaptureSession release]; + [localpool drain]; +} + +int CvCaptureFile::didStart() { + return started; +} + +bool CvCaptureFile::grabFrame() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + double t1 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepForward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + if (t2>t1 && !changedPos) { + currentFPS = 1000.0/(t2-t1); + } else { + currentFPS = movieFPS; + } + changedPos = 0; + [localpool drain]; + return 1; +} + + +IplImage* CvCaptureFile::retrieveFramePixelBuffer() { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + + NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: + QTMovieFrameImageTypeCVPixelBufferRef, QTMovieFrameImageType, +#ifdef MAC_OS_X_VERSION_10_6 + [NSNumber numberWithBool:YES], QTMovieFrameImageSessionMode, +#endif + nil]; + CVPixelBufferRef frame = (CVPixelBufferRef)[mCaptureSession frameImageAtTime:[mCaptureSession currentTime] + withAttributes:attributes + error:nil]; + + CVPixelBufferRef pixels = CVBufferRetain(frame); + CVPixelBufferLockBaseAddress(pixels, 0); + + uint32_t* baseaddress = (uint32_t*)CVPixelBufferGetBaseAddress(pixels); + size_t width = CVPixelBufferGetWidth(pixels); + size_t height = CVPixelBufferGetHeight(pixels); + size_t rowBytes = CVPixelBufferGetBytesPerRow(pixels); + + if (rowBytes != 0) { + + if (currSize != rowBytes*height*sizeof(char)) { + currSize = rowBytes*height*sizeof(char); + if (imagedata != NULL) free(imagedata); + if (bgr_imagedata != NULL) free(bgr_imagedata); + imagedata = (char*)malloc(currSize); + bgr_imagedata = (char*)malloc(currSize); + } + + memcpy(imagedata, baseaddress, currSize); + + //ARGB -> BGRA + for (unsigned int i = 0; i < currSize; i+=4) { + char temp = imagedata[i]; + imagedata[i] = imagedata[i+3]; + imagedata[i+3] = temp; + temp = imagedata[i+1]; + imagedata[i+1] = imagedata[i+2]; + imagedata[i+2] = temp; + } + + if (image == NULL) { + image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 4); + } + + image->width =width; + image->height = height; + image->nChannels = 4; + image->depth = IPL_DEPTH_8U; + image->widthStep = rowBytes; + image->imageData = imagedata; + image->imageSize = currSize; + + + if (bgr_image == NULL) { + bgr_image = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 3); + } + + bgr_image->width =width; + bgr_image->height = height; + bgr_image->nChannels = 3; + bgr_image->depth = IPL_DEPTH_8U; + bgr_image->widthStep = rowBytes; + bgr_image->imageData = bgr_imagedata; + bgr_image->imageSize = currSize; + + cvCvtColor(image, bgr_image,CV_BGRA2BGR); + + } + + CVPixelBufferUnlockBaseAddress(pixels, 0); + CVBufferRelease(pixels); + + [localpool drain]; + + return bgr_image; +} + + +IplImage* CvCaptureFile::retrieveFrame(int) { + return retrieveFramePixelBuffer(); +} + +double CvCaptureFile::getFPS() { + if (mCaptureSession == nil) return 0; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + double now = getProperty(CV_CAP_PROP_POS_MSEC); + double retval = 0; + if (now == 0) { + [mCaptureSession stepForward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepBackward]; + retval = 1000.0 / (t2-now); + } else { + [mCaptureSession stepBackward]; + double t2 = getProperty(CV_CAP_PROP_POS_MSEC); + [mCaptureSession stepForward]; + retval = 1000.0 / (now-t2); + } + [localpool drain]; + return retval; +} + +double CvCaptureFile::getProperty(int property_id){ + if (mCaptureSession == nil) return 0; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + double retval; + QTTime t; + + //cerr << "get_prop"< 0) { + QTMedia *media = [[videoTracks objectAtIndex:0] media]; + retval = [[media attributeForKey:QTMediaSampleCountAttribute] longValue]; + } else { + retval = 0; + } + } + break; + case CV_CAP_PROP_FOURCC: + default: + retval = false; + } + + [localpool drain]; + return retval; +} + + +/***************************************************************************** + * + * CvVideoWriter Implementation. + * + * CvVideoWriter is the instantiation of a video output class + * + *****************************************************************************/ + + +CvVideoWriter_QT::CvVideoWriter_QT(const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color) { + + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + movieFPS = fps; + movieSize = frame_size; + movieColor = is_color; + mMovie = nil; + path = [[[NSString stringWithCString:filename encoding:NSASCIIStringEncoding] stringByExpandingTildeInPath] retain]; + + argbimage = cvCreateImage(movieSize, IPL_DEPTH_8U, 4); + + + char cc[5]; + cc[0] = fourcc & 255; + cc[1] = (fourcc >> 8) & 255; + cc[2] = (fourcc >> 16) & 255; + cc[3] = (fourcc >> 24) & 255; + cc[4] = 0; + int cc2 = CV_FOURCC(cc[0], cc[1], cc[2], cc[3]); + if (cc2!=fourcc) { + cout << "WARNING: Didn't properly encode FourCC. Expected " << fourcc + << " but got " << cc2 << "." << endl; + } + + codec = [[NSString stringWithCString:cc encoding:NSASCIIStringEncoding] retain]; + + NSError *error = nil; + if (!mMovie) { + + NSFileManager* files = [NSFileManager defaultManager]; + if ([files fileExistsAtPath:path]) { + if (![files removeItemAtPath:path error:nil]) { + cout << "WARNING: Failed to remove existing file " << [path cStringUsingEncoding:NSASCIIStringEncoding] << endl; + } + } + + mMovie = [[QTMovie alloc] initToWritableFile:path error:&error]; + if (!mMovie) { + cout << "WARNING: Could not create empty movie file container." << endl; + [localpool drain]; + return; + } + } + + [mMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute]; + + [localpool drain]; +} + + +CvVideoWriter_QT::~CvVideoWriter_QT() { + cvReleaseImage(&argbimage); + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + [mMovie release]; + [path release]; + [codec release]; + [localpool drain]; +} + +bool CvVideoWriter_QT::writeFrame(const IplImage* image) { + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + + cvCvtColor(image, argbimage, CV_BGR2BGRA); + + + unsigned char* imagedata = (unsigned char*)argbimage->imageData; + //BGRA --> ARGB + + for (int j = 0; j < argbimage->height; j++) { + int rowstart = argbimage->widthStep * j; + for (int i = rowstart; i < rowstart+argbimage->widthStep; i+=4) { + unsigned char temp = imagedata[i]; + imagedata[i] = 255; + imagedata[i+3] = temp; + temp = imagedata[i+2]; + imagedata[i+2] = imagedata[i+1]; + imagedata[i+1] = temp; + } + } + + NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&imagedata + pixelsWide:movieSize.width + pixelsHigh:movieSize.height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:NSAlphaFirstBitmapFormat + bytesPerRow:argbimage->widthStep + bitsPerPixel:32] ; + + + NSImage* nsimage = [[NSImage alloc] init]; + + [nsimage addRepresentation:imageRep]; + + /* + codecLosslessQuality = 0x00000400, + codecMaxQuality = 0x000003FF, + codecMinQuality = 0x00000000, + codecLowQuality = 0x00000100, + codecNormalQuality = 0x00000200, + codecHighQuality = 0x00000300 + */ + + [mMovie addImage:nsimage forDuration:QTMakeTime(100,100*movieFPS) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys: + codec, QTAddImageCodecType, + //[NSNumber numberWithInt:codecLowQuality], QTAddImageCodecQuality, + [NSNumber numberWithInt:100*movieFPS], QTTrackTimeScaleAttribute,nil]]; + + if (![mMovie updateMovieFile]) { + cout << "Didn't successfully update movie file." << endl; + } + + [imageRep release]; + [nsimage release]; + [localpool drain]; + + return 1; +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_tyzx.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_tyzx.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_tyzx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_tyzx.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,230 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include + +#if _MSC_VER >= 1200 + #pragma comment(lib,"DeepSeaIF.lib") +#endif + + +/****************** Capturing video from TYZX stereo camera *******************/ +/** Initially developed by Roman Stanchak rstanchak@yahoo.com */ + +class CvCaptureCAM_TYZX : public CvCapture +{ +public: + CvCaptureCAM_TYZX() { index = -1; image = 0; } + virtual ~CvCaptureCAM_TYZX() { close(); } + + virtual bool open( int _index ); + virtual void close(); + bool isOpened() { return index >= 0; } + + virtual double getProperty(int); + virtual bool setProperty(int, double) { return false; } + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_TYZX; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + virtual bool allocateImage(); + + int index; + IplImage* image; +} +CvCaptureCAM_TYZX; + +DeepSeaIF * g_tyzx_camera = 0; +int g_tyzx_refcount = 0; + +bool CvCaptureCAM_TYZX::open( int _index ) +{ + close(); + + if(!g_tyzx_camera){ + g_tyzx_camera = new DeepSeaIF; + if(!g_tyzx_camera) return false; + + if(!g_tyzx_camera->initializeSettings(NULL)){ + delete g_tyzx_camera; + return false; + } + + // set initial sensor mode + // TODO is g_tyzx_camera redundant? + g_tyzx_camera->setSensorMode(g_tyzx_camera->getSensorMode()); + + // mm's + g_tyzx_camera->setZUnits((int) 1000); + + g_tyzx_camera->enableLeftColor(true); + g_tyzx_camera->setColorMode(DeepSeaIF::BGRcolor); + g_tyzx_camera->setDoIntensityCrop(true); + g_tyzx_camera->enable8bitImages(true); + if(!g_tyzx_camera->startCapture()){ + return false; + } + g_tyzx_refcount++; + } + index = _index; + return true; +} + +void CvCaptureCAM_TYZX::close() +{ + if( isOpened() ) + { + cvReleaseImage( &image ); + g_tyzx_refcount--; + if(g_tyzx_refcount==0){ + delete g_tyzx_camera; + } + } +} + +bool CvCaptureCAM_TYZX::grabFrame() +{ + return isOpened() && g_tyzx_camera && g_tyzx_camera->grab(); +} + +bool CvCaptureCAM_TYZX::allocateImage() +{ + int depth, nch; + CvSize size; + + // assume we want to resize + cvReleaseImage(&image); + + // figure out size depending on index provided + switch(index){ + case CV_TYZX_RIGHT: + size = cvSize(g_tyzx_camera->intensityWidth(), g_tyzx_camera->intensityHeight()); + depth = 8; + nch = 1; + break; + case CV_TYZX_Z: + size = cvSize(g_tyzx_camera->zWidth(), g_tyzx_camera->zHeight()); + depth = IPL_DEPTH_16S; + nch = 1; + break; + case CV_TYZX_LEFT: + default: + size = cvSize(g_tyzx_camera->intensityWidth(), g_tyzx_camera->intensityHeight()); + depth = 8; + nch = 1; + break; + } + image = cvCreateImage(size, depth, nch); + return image != 0; +} + +/// Copy 'grabbed' image into capture buffer and return it. +IplImage * CvCaptureCAM_TYZX::retrieveFrame(int) +{ + if(!isOpened() || !g_tyzx_camera) return 0; + + if(!image && !alocateImage()) + return 0; + + // copy camera image into buffer. + // tempting to reference TYZX memory directly to avoid copying. + switch (index) + { + case CV_TYZX_RIGHT: + memcpy(image->imageData, g_tyzx_camera->getRImage(), image->imageSize); + break; + case CV_TYZX_Z: + memcpy(image->imageData, g_tyzx_camera->getZImage(), image->imageSize); + break; + case CV_TYZX_LEFT: + default: + memcpy(image->imageData, g_tyzx_camera->getLImage(), image->imageSize); + break; + } + + return image; +} + +double CvCaptureCAM_TYZX::getProperty(int property_id) +{ + CvSize size; + switch(capture->index) + { + case CV_TYZX_LEFT: + size = cvSize(g_tyzx_camera->intensityWidth(), g_tyzx_camera->intensityHeight()); + break; + case CV_TYZX_RIGHT: + size = cvSize(g_tyzx_camera->intensityWidth(), g_tyzx_camera->intensityHeight()); + break; + case CV_TYZX_Z: + size = cvSize(g_tyzx_camera->zWidth(), g_tyzx_camera->zHeight()); + break; + default: + size = cvSize(0,0); + } + + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return size.width; + case CV_CAP_PROP_FRAME_HEIGHT: + return size.height; + } + + return 0; +} + +bool CvCaptureCAM_TYZX::setProperty( int, double ) +{ + return false; +} + +CvCapture * cvCreateCameraCapture_TYZX (int index) +{ + CvCaptureCAM_TYZX * capture = new CvCaptureCAM_TYZX; + if( capture->open(index) ) + return capture; + + delete capture; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_unicap.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_unicap.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_unicap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_unicap.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,331 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2008, Xavier Delacour, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// 2008-04-27 Xavier Delacour + +#include "precomp.hpp" +#include +#include +extern "C" { +#include +} + +#ifdef NDEBUG +#define CV_WARN(message) +#else +#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) +#endif + +struct CvCapture_Unicap : public CvCapture +{ + CvCapture_Unicap() { init(); } + virtual ~CvCapture_Unicap() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_UNICAP; } // Return the type of the capture object: CV_CAP_VFW, etc... + + bool shutdownDevice(); + bool initDevice(); + + void init() + { + device_initialized = false; + desired_format = 0; + desired_size = cvSize(0,0); + convert_rgb = false; + + handle = 0; + memset( &device, 0, sizeof(device) ); + memset( &format_spec, 0, sizeof(format_spec) ); + memset( &format, 0, sizeof(format) ); + memset( &raw_buffer, 0, sizeof(raw_buffer) ); + memset( &buffer, 0, sizeof(buffer) ); + + raw_frame = frame = 0; + } + + bool device_initialized; + + int desired_device; + int desired_format; + CvSize desired_size; + bool convert_rgb; + + unicap_handle_t handle; + unicap_device_t device; + unicap_format_t format_spec; + unicap_format_t format; + unicap_data_buffer_t raw_buffer; + unicap_data_buffer_t buffer; + + IplImage *raw_frame; + IplImage *frame; +}; + +bool CvCapture_Unicap::shutdownDevice() { + bool result = false; + CV_FUNCNAME("CvCapture_Unicap::shutdownDevice"); + __BEGIN__; + + if (!SUCCESS(unicap_stop_capture(handle))) + CV_ERROR(CV_StsError, "unicap: failed to stop capture on device\n"); + + if (!SUCCESS(unicap_close(handle))) + CV_ERROR(CV_StsError, "unicap: failed to close the device\n"); + + cvReleaseImage(&raw_frame); + cvReleaseImage(&frame); + + device_initialized = false; + + result = true; + __END__; + return result; +} + +bool CvCapture_Unicap::initDevice() { + bool result = false; + CV_FUNCNAME("CvCapture_Unicap::initDevice"); + __BEGIN__; + + if (device_initialized && !shutdownDevice()) + return false; + + if(!SUCCESS(unicap_enumerate_devices(NULL, &device, desired_device))) + CV_ERROR(CV_StsError, "unicap: failed to get info for device\n"); + + if(!SUCCESS(unicap_open( &handle, &device))) + CV_ERROR(CV_StsError, "unicap: failed to open device\n"); + + unicap_void_format(&format_spec); + + if (!SUCCESS(unicap_enumerate_formats(handle, &format_spec, &format, desired_format))) { + shutdownDevice(); + CV_ERROR(CV_StsError, "unicap: failed to get video format\n"); + } + + int i; + if (format.sizes) + { + for (i = format.size_count - 1; i > 0; i--) + if (format.sizes[i].width == desired_size.width && + format.sizes[i].height == desired_size.height) + break; + format.size.width = format.sizes[i].width; + format.size.height = format.sizes[i].height; + } + + if (!SUCCESS(unicap_set_format(handle, &format))) { + shutdownDevice(); + CV_ERROR(CV_StsError, "unicap: failed to set video format\n"); + } + + memset(&raw_buffer, 0x0, sizeof(unicap_data_buffer_t)); + raw_frame = cvCreateImage(cvSize(format.size.width, + format.size.height), + 8, format.bpp / 8); + memcpy(&raw_buffer.format, &format, sizeof(raw_buffer.format)); + raw_buffer.data = (unsigned char*)raw_frame->imageData; + raw_buffer.buffer_size = format.size.width * + format.size.height * format.bpp / 8; + + memset(&buffer, 0x0, sizeof(unicap_data_buffer_t)); + memcpy(&buffer.format, &format, sizeof(buffer.format)); + + buffer.format.fourcc = UCIL_FOURCC('B','G','R','3'); + buffer.format.bpp = 24; + // * todo support greyscale output + // buffer.format.fourcc = UCIL_FOURCC('G','R','E','Y'); + // buffer.format.bpp = 8; + + frame = cvCreateImage(cvSize(buffer.format.size.width, + buffer.format.size.height), + 8, buffer.format.bpp / 8); + buffer.data = (unsigned char*)frame->imageData; + buffer.buffer_size = buffer.format.size.width * + buffer.format.size.height * buffer.format.bpp / 8; + + if(!SUCCESS(unicap_start_capture(handle))) { + shutdownDevice(); + CV_ERROR(CV_StsError, "unicap: failed to start capture on device\n"); + } + + device_initialized = true; + result = true; + __END__; + return result; +} + +void CvCapture_Unicap::close() { + if(device_initialized) + shutdownDevice(); +} + +bool CvCapture_Unicap::grabFrame() { + bool result = false; + + CV_FUNCNAME("CvCapture_Unicap::grabFrame"); + __BEGIN__; + + unicap_data_buffer_t *returned_buffer; + + int retry_count = 100; + + while (retry_count--) { + if(!SUCCESS(unicap_queue_buffer(handle, &raw_buffer))) + CV_ERROR(CV_StsError, "unicap: failed to queue a buffer on device\n"); + + if(SUCCESS(unicap_wait_buffer(handle, &returned_buffer))) + { + result = true; + EXIT; + } + + CV_WARN("unicap: failed to wait for buffer on device\n"); + usleep(100 * 1000); + } + + __END__; + return result; +} + +IplImage * CvCapture_Unicap::retrieveFrame(int) { + if (convert_rgb) { + ucil_convert_buffer(&buffer, &raw_buffer); + return frame; + } + return raw_frame; +} + +double CvCapture_Unicap::getProperty(int id) { + switch (id) { + case CV_CAP_PROP_POS_MSEC: break; + case CV_CAP_PROP_POS_FRAMES: break; + case CV_CAP_PROP_POS_AVI_RATIO: break; + case CV_CAP_PROP_FRAME_WIDTH: + return desired_size.width; + case CV_CAP_PROP_FRAME_HEIGHT: + return desired_size.height; + case CV_CAP_PROP_FPS: break; + case CV_CAP_PROP_FOURCC: break; + case CV_CAP_PROP_FRAME_COUNT: break; + case CV_CAP_PROP_FORMAT: + return desired_format; + case CV_CAP_PROP_MODE: break; + case CV_CAP_PROP_BRIGHTNESS: break; + case CV_CAP_PROP_CONTRAST: break; + case CV_CAP_PROP_SATURATION: break; + case CV_CAP_PROP_HUE: break; + case CV_CAP_PROP_GAIN: break; + case CV_CAP_PROP_CONVERT_RGB: + return convert_rgb; + } + + return 0; +} + +bool CvCapture_Unicap::setProperty(int id, double value) { + bool reinit = false; + + switch (id) { + case CV_CAP_PROP_POS_MSEC: break; + case CV_CAP_PROP_POS_FRAMES: break; + case CV_CAP_PROP_POS_AVI_RATIO: break; + case CV_CAP_PROP_FRAME_WIDTH: + desired_size.width = (int)value; + reinit = true; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + desired_size.height = (int)value; + reinit = true; + break; + case CV_CAP_PROP_FPS: break; + case CV_CAP_PROP_FOURCC: break; + case CV_CAP_PROP_FRAME_COUNT: break; + case CV_CAP_PROP_FORMAT: + desired_format = id; + reinit = true; + break; + case CV_CAP_PROP_MODE: break; + case CV_CAP_PROP_BRIGHTNESS: break; + case CV_CAP_PROP_CONTRAST: break; + case CV_CAP_PROP_SATURATION: break; + case CV_CAP_PROP_HUE: break; + case CV_CAP_PROP_GAIN: break; + case CV_CAP_PROP_CONVERT_RGB: + convert_rgb = value != 0; + break; + } + + if (reinit && !initDevice()) + return false; + + return true; +} + +bool CvCapture_Unicap::open(int index) +{ + close(); + device_initialized = false; + + desired_device = index < 0 ? 0 : index; + desired_format = 0; + desired_size = cvSize(320, 240); + convert_rgb = true; + + return initDevice(); +} + + +CvCapture * cvCreateCameraCapture_Unicap(const int index) +{ + CvCapture_Unicap *cap = new CvCapture_Unicap; + if( cap->open(index) ) + return cap; + delete cap; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_v4l.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_v4l.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_v4l.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_v4l.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2917 @@ +/* This is the contributed code: + +File: cvcap_v4l.cpp +Current Location: ../opencv-0.9.6/otherlibs/highgui + +Original Version: 2003-03-12 Magnus Lundin lundin@mlu.mine.nu +Original Comments: + +ML:This set of files adds support for firevre and usb cameras. +First it tries to install a firewire camera, +if that fails it tries a v4l/USB camera +It has been tested with the motempl sample program + +First Patch: August 24, 2004 Travis Wood TravisOCV@tkwood.com +For Release: OpenCV-Linux Beta4 opencv-0.9.6 +Tested On: LMLBT44 with 8 video inputs +Problems? Post problems/fixes to OpenCV group on groups.yahoo.com +Patched Comments: + +TW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4 +were not working. I have rewritten them so they work for me. At the same time, trying +to keep the original code as ML wrote it as unchanged as possible. No one likes to debug +someone elses code, so I resisted changes as much as possible. I have tried to keep the +same "ideas" where applicable, that is, where I could figure out what the previous author +intended. Some areas I just could not help myself and had to "spiffy-it-up" my way. + +These drivers should work with other V4L frame capture cards other then my bttv +driven frame capture card. + +Re Written driver for standard V4L mode. Tested using LMLBT44 video capture card. +Standard bttv drivers are on the LMLBT44 with up to 8 Inputs. + +This utility was written with the help of the document: +http://pages.cpsc.ucalgary.ca/~sayles/VFL_HowTo +as a general guide for interfacing into the V4l standard. + +Made the index value passed for icvOpenCAM_V4L(index) be the number of the +video device source in the /dev tree. The -1 uses original /dev/video. + +Index Device + 0 /dev/video0 + 1 /dev/video1 + 2 /dev/video2 + 3 /dev/video3 + ... + 7 /dev/video7 +with + -1 /dev/video + +TW: You can select any video source, but this package was limited from the start to only +ONE camera opened at any ONE time. +This is an original program limitation. +If you are interested, I will make my version available to other OpenCV users. The big +difference in mine is you may pass the camera number as part of the cv argument, but this +convention is non standard for current OpenCV calls and the camera number is not currently +passed into the called routine. + +Second Patch: August 28, 2004 Sfuncia Fabio fiblan@yahoo.it +For Release: OpenCV-Linux Beta4 Opencv-0.9.6 + +FS: this patch fix not sequential index of device (unplugged device), and real numCameras. + for -1 index (icvOpenCAM_V4L) i dont use /dev/video but real device available, because + if /dev/video is a link to /dev/video0 and i unplugged device on /dev/video0, /dev/video + is a bad link. I search the first available device with indexList. + +Third Patch: December 9, 2004 Frederic Devernay Frederic.Devernay@inria.fr +For Release: OpenCV-Linux Beta4 Opencv-0.9.6 + +[FD] I modified the following: + - handle YUV420P, YUV420, and YUV411P palettes (for many webcams) without using floating-point + - cvGrabFrame should not wait for the end of the first frame, and should return quickly + (see highgui doc) + - cvRetrieveFrame should in turn wait for the end of frame capture, and should not + trigger the capture of the next frame (the user choses when to do it using GrabFrame) + To get the old behavior, re-call cvRetrieveFrame just after cvGrabFrame. + - having global bufferIndex and FirstCapture variables makes the code non-reentrant + (e.g. when using several cameras), put these in the CvCapture struct. + - according to V4L HowTo, incrementing the buffer index must be done before VIDIOCMCAPTURE. + - the VID_TYPE_SCALES stuff from V4L HowTo is wrong: image size can be changed + even if the hardware does not support scaling (e.g. webcams can have several + resolutions available). Just don't try to set the size at 640x480 if the hardware supports + scaling: open with the default (probably best) image size, and let the user scale it + using SetProperty. + - image size can be changed by two subsequent calls to SetProperty (for width and height) + - bug fix: if the image size changes, realloc the new image only when it is grabbed + - issue errors only when necessary, fix error message formatting. + +Fourth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I modified the following: + - Additional Video4Linux2 support :) + - Use mmap functions (v4l2) + - New methods are internal: + try_palette_v4l2 -> rewrite try_palette for v4l2 + mainloop_v4l2, read_image_v4l2 -> this methods are moved from official v4l2 capture.c example + try_init_v4l -> device v4l initialisation + try_init_v4l2 -> device v4l2 initialisation + autosetup_capture_mode_v4l -> autodetect capture modes for v4l + autosetup_capture_mode_v4l2 -> autodetect capture modes for v4l2 + - Modifications are according with Video4Linux old codes + - Video4Linux handling is automatically if it does not recognize a Video4Linux2 device + - Tested succesful with Logitech Quickcam Express (V4L), Creative Vista (V4L) and Genius VideoCam Notebook (V4L2) + - Correct source lines with compiler warning messages + - Information message from v4l/v4l2 detection + +Fifth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I modified the following: + - SN9C10x chip based webcams support + - New methods are internal: + bayer2rgb24, sonix_decompress -> decoder routines for SN9C10x decoding from Takafumi Mizuno with his pleasure :) + - Tested succesful with Genius VideoCam Notebook (V4L2) + +Sixth Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I added the following: + - Add capture control support (hue, saturation, brightness, contrast, gain) + - Get and change V4L capture controls (hue, saturation, brightness, contrast) + - New method is internal: + icvSetControl -> set capture controls + - Tested succesful with Creative Vista (V4L) + +Seventh Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu +For Release: OpenCV-Linux Beta5 OpenCV-0.9.7 + +I added the following: + - Detect, get and change V4L2 capture controls (hue, saturation, brightness, contrast, gain) + - New methods are internal: + v4l2_scan_controls_enumerate_menu, v4l2_scan_controls -> detect capture control intervals + - Tested succesful with Genius VideoCam Notebook (V4L2) + +8th patch: Jan 5, 2006, Olivier.Bornet@idiap.ch +Add support of V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_MJPEG. +With this patch, new webcams of Logitech, like QuickCam Fusion works. +Note: For use these webcams, look at the UVC driver at +http://linux-uvc.berlios.de/ + +9th patch: Mar 4, 2006, Olivier.Bornet@idiap.ch +- try V4L2 before V4L, because some devices are V4L2 by default, + but they try to implement the V4L compatibility layer. + So, I think this is better to support V4L2 before V4L. +- better separation between V4L2 and V4L initialization. (this was needed to support + some drivers working, but not fully with V4L2. (so, we do not know when we + need to switch from V4L2 to V4L. + +10th patch: July 02, 2008, Mikhail Afanasyev fopencv@theamk.com +Fix reliability problems with high-resolution UVC cameras on linux +the symptoms were damaged image and 'Corrupt JPEG data: premature end of data segment' on stderr +- V4L_ABORT_BADJPEG detects JPEG warnings and turns them into errors, so bad images + could be filtered out +- USE_TEMP_BUFFER fixes the main problem (improper buffer management) and + prevents bad images in the first place + + +make & enjoy! + +*/ + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if !defined WIN32 && (defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO) + +#define CLEAR(x) memset (&(x), 0, sizeof (x)) + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CAMV4L +#include +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_CAMV4L2 +#include /* for videodev2.h */ +#include +#endif + +#ifdef HAVE_VIDEOIO +#include +#define HAVE_CAMV4L2 +#endif + +/* Defaults - If your board can do better, set it here. Set for the most common type inputs. */ +#define DEFAULT_V4L_WIDTH 640 +#define DEFAULT_V4L_HEIGHT 480 + +#define CHANNEL_NUMBER 1 +#define MAX_CAMERAS 8 + + +// default and maximum number of V4L buffers, not including last, 'special' buffer +#define MAX_V4L_BUFFERS 10 +#define DEFAULT_V4L_BUFFERS 4 + +// if enabled, then bad JPEG warnings become errors and cause NULL returned instead of image +#define V4L_ABORT_BADJPEG + +#define MAX_DEVICE_DRIVER_NAME 80 + +/* Device Capture Objects */ + +#ifdef HAVE_CAMV4L2 + +/* V4L2 structure */ +struct buffer +{ + void * start; + size_t length; +}; + +static unsigned int n_buffers = 0; + +/* Additional V4L2 pixelformats support for Sonix SN9C10x base webcams */ +#ifndef V4L2_PIX_FMT_SBGGR8 +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ +#endif +#ifndef V4L2_PIX_FMT_SN9C10X +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x cmpr. */ +#endif + +#ifndef V4L2_PIX_FMT_SGBRG +#define V4L2_PIX_FMT_SGBRG v4l2_fourcc('G','B','R','G') /* bayer GBRG GBGB.. RGRG.. */ +#endif + +#endif /* HAVE_CAMV4L2 */ + +enum PALETTE_TYPE { + PALETTE_BGR24 = 1, + PALETTE_YVU420, + PALETTE_YUV411P, + PALETTE_YUYV, + PALETTE_UYVY, + PALETTE_SBGGR8, + PALETTE_SN9C10X, + PALETTE_MJPEG, + PALETTE_SGBRG +}; + +typedef struct CvCaptureCAM_V4L +{ + int deviceHandle; + int bufferIndex; + int FirstCapture; +#ifdef HAVE_CAMV4L + struct video_capability capability; + struct video_window captureWindow; + struct video_picture imageProperties; + struct video_mbuf memoryBuffer; + struct video_mmap *mmaps; +#endif /* HAVE_CAMV4L */ + char *memoryMap; + IplImage frame; + +#ifdef HAVE_CAMV4L2 + enum PALETTE_TYPE palette; + /* V4L2 variables */ + buffer buffers[MAX_V4L_BUFFERS + 1]; + struct v4l2_capability cap; + struct v4l2_input inp; + struct v4l2_format form; + struct v4l2_crop crop; + struct v4l2_cropcap cropcap; + struct v4l2_requestbuffers req; + struct v4l2_control control; + enum v4l2_buf_type type; + struct v4l2_queryctrl queryctrl; + struct v4l2_querymenu querymenu; + + /* V4L2 control variables */ + int v4l2_brightness, v4l2_brightness_min, v4l2_brightness_max; + int v4l2_contrast, v4l2_contrast_min, v4l2_contrast_max; + int v4l2_saturation, v4l2_saturation_min, v4l2_saturation_max; + int v4l2_hue, v4l2_hue_min, v4l2_hue_max; + int v4l2_gain, v4l2_gain_min, v4l2_gain_max; + int v4l2_exposure, v4l2_exposure_min, v4l2_exposure_max; + +#endif /* HAVE_CAMV4L2 */ + +} +CvCaptureCAM_V4L; + +#ifdef HAVE_CAMV4L2 + +int V4L2_SUPPORT = 0; + +#endif /* HAVE_CAMV4L2 */ + +static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ); + +static int icvGrabFrameCAM_V4L( CvCaptureCAM_V4L* capture ); +static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int ); + +static double icvGetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id ); +static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id, double value ); + +static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h); + +/*********************** Implementations ***************************************/ + +static int numCameras = 0; +static int indexList = 0; + +/* Simple test program: Find number of Video Sources available. + Start from 0 and go to MAX_CAMERAS while checking for the device with that name. + If it fails on the first attempt of /dev/video0, then check if /dev/video is valid. + Returns the global numCameras with the correct value (we hope) */ + +static void icvInitCapture_V4L() { + int deviceHandle; + int CameraNumber; + char deviceName[MAX_DEVICE_DRIVER_NAME]; + + CameraNumber = 0; + while(CameraNumber < MAX_CAMERAS) { + /* Print the CameraNumber at the end of the string with a width of one character */ + sprintf(deviceName, "/dev/video%1d", CameraNumber); + /* Test using an open to see if this new device name really does exists. */ + deviceHandle = open(deviceName, O_RDONLY); + if (deviceHandle != -1) { + /* This device does indeed exist - add it to the total so far */ + // add indexList + indexList|=(1 << CameraNumber); + numCameras++; + } + if (deviceHandle != -1) + close(deviceHandle); + /* Set up to test the next /dev/video source in line */ + CameraNumber++; + } /* End while */ + +}; /* End icvInitCapture_V4L */ + +#ifdef HAVE_CAMV4L + +static int +try_palette(int fd, + struct video_picture *cam_pic, + int pal, + int depth) +{ + cam_pic->palette = pal; + cam_pic->depth = depth; + if (ioctl(fd, VIDIOCSPICT, cam_pic) < 0) + return 0; + if (ioctl(fd, VIDIOCGPICT, cam_pic) < 0) + return 0; + if (cam_pic->palette == pal) + return 1; + return 0; +} + +#endif /* HAVE_CAMV4L */ + +#ifdef HAVE_CAMV4L2 + +static int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace) +{ + CLEAR (capture->form); + + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->form.fmt.pix.pixelformat = colorspace; + capture->form.fmt.pix.field = V4L2_FIELD_ANY; + capture->form.fmt.pix.width = DEFAULT_V4L_WIDTH; + capture->form.fmt.pix.height = DEFAULT_V4L_HEIGHT; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form)) + return -1; + + + if (colorspace != capture->form.fmt.pix.pixelformat) + return -1; + else + return 0; +} + +#endif /* HAVE_CAMV4L2 */ + +#ifdef HAVE_CAMV4L + +static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) +{ + + // if detect = -1 then unable to open device + // if detect = 0 then detected nothing + // if detect = 1 then V4L device + int detect = 0; + + + // Test device for V4L compability + + /* Test using an open to see if this new device name really does exists. */ + /* No matter what the name - it still must be opened! */ + capture->deviceHandle = open(deviceName, O_RDWR); + + if (capture->deviceHandle == 0) + { + detect = -1; + + icvCloseCAM_V4L(capture); + } + + if (detect == 0) + { + /* Query the newly opened device for its capabilities */ + if (ioctl(capture->deviceHandle, VIDIOCGCAP, &capture->capability) < 0) + { + detect = 0; + icvCloseCAM_V4L(capture); + } + else + { + detect = 1; + } + } + + return detect; + +} + +#endif /* HAVE_CAMV4L */ + +#ifdef HAVE_CAMV4L2 + +static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName) +{ + // Test device for V4L2 compability + // Return value: + // -1 then unable to open device + // 0 then detected nothing + // 1 then V4L2 device + + int deviceIndex; + + /* Open and test V4L2 device */ + capture->deviceHandle = open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0); + if (-1 == capture->deviceHandle) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 open \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return -1; + } + + CLEAR (capture->cap); + if (-1 == ioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap)) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_QUERYCAP \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; + } + + /* Query channels number */ + if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_INPUT, &deviceIndex)) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_G_INPUT \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; + } + + /* Query information about current input */ + CLEAR (capture->inp); + capture->inp.index = deviceIndex; + if (-1 == ioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp)) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_ENUMINPUT \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; + } + + return 1; + +} + +static int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture) +{ + if (try_palette_v4l2(capture, V4L2_PIX_FMT_BGR24) == 0) + { + capture->palette = PALETTE_BGR24; + } + else + if (try_palette_v4l2(capture, V4L2_PIX_FMT_YVU420) == 0) + { + capture->palette = PALETTE_YVU420; + } + else + if (try_palette_v4l2(capture, V4L2_PIX_FMT_YUV411P) == 0) + { + capture->palette = PALETTE_YUV411P; + } + else + +#ifdef HAVE_JPEG + if (try_palette_v4l2(capture, V4L2_PIX_FMT_MJPEG) == 0 || + try_palette_v4l2(capture, V4L2_PIX_FMT_JPEG) == 0) + { + capture->palette = PALETTE_MJPEG; + } + else +#endif + + if (try_palette_v4l2(capture, V4L2_PIX_FMT_YUYV) == 0) + { + capture->palette = PALETTE_YUYV; + } + else if (try_palette_v4l2(capture, V4L2_PIX_FMT_UYVY) == 0) + { + capture->palette = PALETTE_UYVY; + } + else + if (try_palette_v4l2(capture, V4L2_PIX_FMT_SN9C10X) == 0) + { + capture->palette = PALETTE_SN9C10X; + } else + if (try_palette_v4l2(capture, V4L2_PIX_FMT_SBGGR8) == 0) + { + capture->palette = PALETTE_SBGGR8; + } else + if (try_palette_v4l2(capture, V4L2_PIX_FMT_SGBRG) == 0) + { + capture->palette = PALETTE_SGBRG; + } + else + { + fprintf(stderr, "HIGHGUI ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + return 0; + +} + +#endif /* HAVE_CAMV4L2 */ + +#ifdef HAVE_CAMV4L + +static int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture) +{ + + if(ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Unable to determine size of incoming image\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + /* Yet MORE things that might have to be changes with your frame capture card */ + /* This sets the scale to the center of a 2^16 number */ + if (try_palette(capture->deviceHandle, &capture->imageProperties, VIDEO_PALETTE_RGB24, 24)) { + //printf("negotiated palette RGB24\n"); + } + else if (try_palette(capture->deviceHandle, &capture->imageProperties, VIDEO_PALETTE_YUV420P, 16)) { + //printf("negotiated palette YUV420P\n"); + } + else if (try_palette(capture->deviceHandle, &capture->imageProperties, VIDEO_PALETTE_YUV420, 16)) { + //printf("negotiated palette YUV420\n"); + } + else if (try_palette(capture->deviceHandle, &capture->imageProperties, VIDEO_PALETTE_YUV411P, 16)) { + //printf("negotiated palette YUV420P\n"); + } + else { + fprintf(stderr, "HIGHGUI ERROR: V4L: Pixel format of incoming image is unsupported by OpenCV\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + return 0; + +} + +#endif /* HAVE_CAMV4L */ + +#ifdef HAVE_CAMV4L2 + +static void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture) +{ +// printf (" Menu items:\n"); + CLEAR (capture->querymenu); + capture->querymenu.id = capture->queryctrl.id; + for (capture->querymenu.index = capture->queryctrl.minimum; + (int)capture->querymenu.index <= capture->queryctrl.maximum; + capture->querymenu.index++) + { + if (0 == ioctl (capture->deviceHandle, VIDIOC_QUERYMENU, + &capture->querymenu)) + { +// printf (" %s\n", capture->querymenu.name); + } else { + perror ("VIDIOC_QUERYMENU"); + } + } +} + +static void v4l2_scan_controls(CvCaptureCAM_V4L* capture) +{ + + __u32 ctrl_id; + + for (ctrl_id = V4L2_CID_BASE; + ctrl_id < V4L2_CID_LASTP1; + ctrl_id++) + { + + /* set the id we will query now */ + CLEAR (capture->queryctrl); + capture->queryctrl.id = ctrl_id; + + if (0 == ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, + &capture->queryctrl)) + { + + if (capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + continue; + + if (capture->queryctrl.id == V4L2_CID_BRIGHTNESS) + { + capture->v4l2_brightness = 1; + capture->v4l2_brightness_min = capture->queryctrl.minimum; + capture->v4l2_brightness_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_CONTRAST) + { + capture->v4l2_contrast = 1; + capture->v4l2_contrast_min = capture->queryctrl.minimum; + capture->v4l2_contrast_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_SATURATION) + { + capture->v4l2_saturation = 1; + capture->v4l2_saturation_min = capture->queryctrl.minimum; + capture->v4l2_saturation_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_HUE) + { + capture->v4l2_hue = 1; + capture->v4l2_hue_min = capture->queryctrl.minimum; + capture->v4l2_hue_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_GAIN) + { + capture->v4l2_gain = 1; + capture->v4l2_gain_min = capture->queryctrl.minimum; + capture->v4l2_gain_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_EXPOSURE) + { + capture->v4l2_exposure = 1; + capture->v4l2_exposure_min = capture->queryctrl.minimum; + capture->v4l2_exposure_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.type == V4L2_CTRL_TYPE_MENU) + v4l2_scan_controls_enumerate_menu(capture); + + } else { + + if (errno == EINVAL) + continue; + + perror ("VIDIOC_QUERYCTRL"); + + } + + } + + for (ctrl_id = V4L2_CID_PRIVATE_BASE;;ctrl_id++) + { + + /* set the id we will query now */ + CLEAR (capture->queryctrl); + capture->queryctrl.id = ctrl_id; + + if (0 == ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, + &capture->queryctrl)) + { + + if (capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + continue; + + if (capture->queryctrl.id == V4L2_CID_BRIGHTNESS) + { + capture->v4l2_brightness = 1; + capture->v4l2_brightness_min = capture->queryctrl.minimum; + capture->v4l2_brightness_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_CONTRAST) + { + capture->v4l2_contrast = 1; + capture->v4l2_contrast_min = capture->queryctrl.minimum; + capture->v4l2_contrast_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_SATURATION) + { + capture->v4l2_saturation = 1; + capture->v4l2_saturation_min = capture->queryctrl.minimum; + capture->v4l2_saturation_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_HUE) + { + capture->v4l2_hue = 1; + capture->v4l2_hue_min = capture->queryctrl.minimum; + capture->v4l2_hue_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_GAIN) + { + capture->v4l2_gain = 1; + capture->v4l2_gain_min = capture->queryctrl.minimum; + capture->v4l2_gain_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.id == V4L2_CID_EXPOSURE) + { + capture->v4l2_exposure = 1; + capture->v4l2_exposure_min = capture->queryctrl.minimum; + capture->v4l2_exposure_max = capture->queryctrl.maximum; + } + + if (capture->queryctrl.type == V4L2_CTRL_TYPE_MENU) + v4l2_scan_controls_enumerate_menu(capture); + + } else { + + if (errno == EINVAL) + break; + + perror ("VIDIOC_QUERYCTRL"); + + } + + } + +} + +static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName) +{ + int detect_v4l2 = 0; + + detect_v4l2 = try_init_v4l2(capture, deviceName); + + if (detect_v4l2 != 1) { + /* init of the v4l2 device is not OK */ + return -1; + } + + /* starting from here, we assume we are in V4L2 mode */ + V4L2_SUPPORT = 1; + + /* Init V4L2 control variables */ + capture->v4l2_brightness = 0; + capture->v4l2_contrast = 0; + capture->v4l2_saturation = 0; + capture->v4l2_hue = 0; + capture->v4l2_gain = 0; + capture->v4l2_exposure = 0; + + capture->v4l2_brightness_min = 0; + capture->v4l2_contrast_min = 0; + capture->v4l2_saturation_min = 0; + capture->v4l2_hue_min = 0; + capture->v4l2_gain_min = 0; + capture->v4l2_exposure_min = 0; + + capture->v4l2_brightness_max = 0; + capture->v4l2_contrast_max = 0; + capture->v4l2_saturation_max = 0; + capture->v4l2_hue_max = 0; + capture->v4l2_gain_max = 0; + capture->v4l2_exposure_max = 0; + + /* Scan V4L2 controls */ + v4l2_scan_controls(capture); + + if ((capture->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { + /* Nope. */ + fprintf( stderr, "HIGHGUI ERROR: V4L2: device %s is unable to capture video memory.\n",deviceName); + icvCloseCAM_V4L(capture); + return -1; + } + + /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources + have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. + I myself am using a simple NTSC video input capture card that uses the value of 1. + If you are not in North America or have a different video standard, you WILL have to change + the following settings and recompile/reinstall. This set of settings is based on + the most commonly encountered input video source types (like my bttv card) */ + + if(capture->inp.index > 0) { + CLEAR (capture->inp); + capture->inp.index = CHANNEL_NUMBER; + /* Set only channel number to CHANNEL_NUMBER */ + /* V4L2 have a status field from selected video mode */ + if (-1 == ioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp)) + { + fprintf (stderr, "HIGHGUI ERROR: V4L2: Aren't able to set channel number\n"); + icvCloseCAM_V4L (capture); + return -1; + } + } /* End if */ + + /* Find Window info */ + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { + fprintf( stderr, "HIGHGUI ERROR: V4L2: Could not obtain specifics of capture window.\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + if (V4L2_SUPPORT == 0) + { + } + + if (autosetup_capture_mode_v4l2(capture) == -1) + return -1; + + icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT); + + unsigned int min; + + /* Buggy driver paranoia. */ + min = capture->form.fmt.pix.width * 2; + + if (capture->form.fmt.pix.bytesperline < min) + capture->form.fmt.pix.bytesperline = min; + + min = capture->form.fmt.pix.bytesperline * capture->form.fmt.pix.height; + + if (capture->form.fmt.pix.sizeimage < min) + capture->form.fmt.pix.sizeimage = min; + + CLEAR (capture->req); + + unsigned int buffer_number = DEFAULT_V4L_BUFFERS; + + try_again: + + capture->req.count = buffer_number; + capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->req.memory = V4L2_MEMORY_MMAP; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req)) + { + if (EINVAL == errno) + { + fprintf (stderr, "%s does not support memory mapping\n", deviceName); + } else { + perror ("VIDIOC_REQBUFS"); + } + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + + if (capture->req.count < buffer_number) + { + if (buffer_number == 1) + { + fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } else { + buffer_number--; + fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName); + + goto try_again; + } + } + + for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers) + { + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = n_buffers; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) { + perror ("VIDIOC_QUERYBUF"); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + + capture->buffers[n_buffers].length = buf.length; + capture->buffers[n_buffers].start = + mmap (NULL /* start anywhere */, + buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, + capture->deviceHandle, buf.m.offset); + + if (MAP_FAILED == capture->buffers[n_buffers].start) { + perror ("mmap"); + + /* free capture, and returns an error code */ + icvCloseCAM_V4L (capture); + return -1; + } + + if (n_buffers == 0) { + capture->buffers[MAX_V4L_BUFFERS].start = malloc( buf.length ); + capture->buffers[MAX_V4L_BUFFERS].length = buf.length; + } + } + + /* Set up Image data */ + cvInitImageHeader( &capture->frame, + cvSize( capture->form.fmt.pix.width, + capture->form.fmt.pix.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + /* Allocate space for RGBA data */ + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + + return 1; +}; /* End _capture_V4L2 */ + +#endif /* HAVE_CAMV4L2 */ + +#ifdef HAVE_CAMV4L + +static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName) +{ + int detect_v4l = 0; + + detect_v4l = try_init_v4l(capture, deviceName); + + if ((detect_v4l == -1) + ) + { + fprintf (stderr, "HIGHGUI ERROR: V4L" + ": device %s: Unable to open for READ ONLY\n", deviceName); + + return -1; + } + + if ((detect_v4l <= 0) + ) + { + fprintf (stderr, "HIGHGUI ERROR: V4L" + ": device %s: Unable to query number of channels\n", deviceName); + + return -1; + } + + { + if ((capture->capability.type & VID_TYPE_CAPTURE) == 0) { + /* Nope. */ + fprintf( stderr, "HIGHGUI ERROR: V4L: " + "device %s is unable to capture video memory.\n",deviceName); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + + /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources + have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. + I myself am using a simple NTSC video input capture card that uses the value of 1. + If you are not in North America or have a different video standard, you WILL have to change + the following settings and recompile/reinstall. This set of settings is based on + the most commonly encountered input video source types (like my bttv card) */ + + { + + if(capture->capability.channels>0) { + + struct video_channel selectedChannel; + memset(&selectedChannel, 0, sizeof(selectedChannel)); + + selectedChannel.channel=CHANNEL_NUMBER; + if (ioctl(capture->deviceHandle, VIDIOCGCHAN , &selectedChannel) != -1) { + /* set the video mode to ( VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM) */ +// selectedChannel.norm = VIDEO_MODE_NTSC; + if (ioctl(capture->deviceHandle, VIDIOCSCHAN , &selectedChannel) == -1) { + /* Could not set selected channel - Oh well */ + //printf("\n%d, %s not NTSC capable.\n",selectedChannel.channel, selectedChannel.name); + } /* End if */ + } /* End if */ + } /* End if */ + + } + + { + + if(ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: " + "Could not obtain specifics of capture window.\n\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + { + + if (autosetup_capture_mode_v4l(capture) == -1) + return -1; + + } + + { + + ioctl(capture->deviceHandle, VIDIOCGMBUF, &capture->memoryBuffer); + capture->memoryMap = (char *)mmap(0, + capture->memoryBuffer.size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + capture->deviceHandle, + 0); + if (capture->memoryMap == MAP_FAILED) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Mapping Memmory from video source error: %s\n", strerror(errno)); + icvCloseCAM_V4L(capture); + } + + /* Set up video_mmap structure pointing to this memory mapped area so each image may be + retrieved from an index value */ + capture->mmaps = (struct video_mmap *) + (malloc(capture->memoryBuffer.frames * sizeof(struct video_mmap))); + if (!capture->mmaps) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not memory map video frames.\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + } + + /* Set up Image data */ + cvInitImageHeader( &capture->frame, + cvSize( capture->captureWindow.width, + capture->captureWindow.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + /* Allocate space for RGBA data */ + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + + return 1; +}; /* End _capture_V4L */ + +#endif /* HAVE_CAMV4L */ + +static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index) +{ + static int autoindex; + autoindex = 0; + + char deviceName[MAX_DEVICE_DRIVER_NAME]; + + if (!numCameras) + icvInitCapture_V4L(); /* Havent called icvInitCapture yet - do it now! */ + if (!numCameras) + return NULL; /* Are there any /dev/video input sources? */ + + //search index in indexList + if ( (index>-1) && ! ((1 << index) & indexList) ) + { + fprintf( stderr, "HIGHGUI ERROR: V4L: index %d is not correct!\n",index); + return NULL; /* Did someone ask for not correct video source number? */ + } + /* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL + the handles for V4L processing */ + CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L)); + if (!capture) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n"); + return NULL; + } + /* Select camera, or rather, V4L video source */ + if (index<0) { // Asking for the first device available + for (; autoindexFirstCapture = 1; + +#ifdef HAVE_CAMV4L2 + if (_capture_V4L2 (capture, deviceName) == -1) { + icvCloseCAM_V4L(capture); + V4L2_SUPPORT = 0; +#endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + if (_capture_V4L (capture, deviceName) == -1) { + icvCloseCAM_V4L(capture); + return NULL; + } +#endif /* HAVE_CAMV4L */ +#ifdef HAVE_CAMV4L2 + } else { + V4L2_SUPPORT = 1; + } +#endif /* HAVE_CAMV4L2 */ + + return capture; +}; /* End icvOpenCAM_V4L */ + +#ifdef HAVE_CAMV4L2 + +static int read_frame_v4l2(CvCaptureCAM_V4L* capture) { + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) { + switch (errno) { + case EAGAIN: + return 0; + + case EIO: + if (!(buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) + { + if (ioctl(capture->deviceHandle, VIDIOC_QBUF, &buf) == -1) + { + return 0; + } + } + return 0; + + default: + /* display the error and stop processing */ + perror ("VIDIOC_DQBUF"); + return 1; + } + } + + assert(buf.index < capture->req.count); + + memcpy(capture->buffers[MAX_V4L_BUFFERS].start, + capture->buffers[buf.index].start, + capture->buffers[MAX_V4L_BUFFERS].length ); + capture->bufferIndex = MAX_V4L_BUFFERS; + //printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n", + // buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused); + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) + perror ("VIDIOC_QBUF"); + + return 1; +} + +static void mainloop_v4l2(CvCaptureCAM_V4L* capture) { + unsigned int count; + + count = 1; + + while (count-- > 0) { + for (;;) { + fd_set fds; + struct timeval tv; + int r; + + FD_ZERO (&fds); + FD_SET (capture->deviceHandle, &fds); + + /* Timeout. */ + tv.tv_sec = 10; + tv.tv_usec = 0; + + r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv); + + if (-1 == r) { + if (EINTR == errno) + continue; + + perror ("select"); + } + + if (0 == r) { + fprintf (stderr, "select timeout\n"); + + /* end the infinite loop */ + break; + } + + if (read_frame_v4l2 (capture)) + break; + } + } +} + +#endif /* HAVE_CAMV4L2 */ + +static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { + + if (capture->FirstCapture) { + /* Some general initialization must take place the first time through */ + + /* This is just a technicality, but all buffers must be filled up before any + staggered SYNC is applied. SO, filler up. (see V4L HowTo) */ + +#ifdef HAVE_CAMV4L2 + +#ifdef HAVE_CAMV4L + if (V4L2_SUPPORT == 1) +#endif + { + + for (capture->bufferIndex = 0; + capture->bufferIndex < ((int)capture->req.count); + ++capture->bufferIndex) + { + + struct v4l2_buffer buf; + + CLEAR (buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = (unsigned long)capture->bufferIndex; + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) { + perror ("VIDIOC_QBUF"); + return 0; + } + } + + /* enable the streaming */ + capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == ioctl (capture->deviceHandle, VIDIOC_STREAMON, + &capture->type)) { + /* error enabling the stream */ + perror ("VIDIOC_STREAMON"); + return 0; + } + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + for (capture->bufferIndex = 0; + capture->bufferIndex < (capture->memoryBuffer.frames-1); + ++capture->bufferIndex) { + + capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; + capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; + capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; + capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; + + if (ioctl(capture->deviceHandle, VIDIOCMCAPTURE, &capture->mmaps[capture->bufferIndex]) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers.\n"); + return 0; + } + } + + } +#endif /* HAVE_CAMV4L */ + +#if defined(V4L_ABORT_BADJPEG) && defined(HAVE_CAMV4L2) + if (V4L2_SUPPORT == 1) + { + // skip first frame. it is often bad -- this is unnotied in traditional apps, + // but could be fatal if bad jpeg is enabled + mainloop_v4l2(capture); + } +#endif + + /* preparation is ok */ + capture->FirstCapture = 0; + } + +#ifdef HAVE_CAMV4L2 + + if (V4L2_SUPPORT == 1) + { + + mainloop_v4l2(capture); + + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; + capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; + capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; + capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; + + if (ioctl (capture->deviceHandle, VIDIOCMCAPTURE, + &capture->mmaps[capture->bufferIndex]) == -1) { + /* capture is on the way, so just exit */ + return 1; + } + + ++capture->bufferIndex; + if (capture->bufferIndex == capture->memoryBuffer.frames) { + capture->bufferIndex = 0; + } + + } +#endif /* HAVE_CAMV4L */ + + return(1); +} + +/* + * Turn a YUV4:2:0 block into an RGB block + * + * Video4Linux seems to use the blue, green, red channel + * order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red. + * + * Color space conversion coefficients taken from the excellent + * http://www.inforamp.net/~poynton/ColorFAQ.html + * In his terminology, this is a CCIR 601.1 YCbCr -> RGB. + * Y values are given for all 4 pixels, but the U (Pb) + * and V (Pr) are assumed constant over the 2x2 block. + * + * To avoid floating point arithmetic, the color conversion + * coefficients are scaled into 16.16 fixed-point integers. + * They were determined as follows: + * + * double brightness = 1.0; (0->black; 1->full scale) + * double saturation = 1.0; (0->greyscale; 1->full color) + * double fixScale = brightness * 256 * 256; + * int rvScale = (int)(1.402 * saturation * fixScale); + * int guScale = (int)(-0.344136 * saturation * fixScale); + * int gvScale = (int)(-0.714136 * saturation * fixScale); + * int buScale = (int)(1.772 * saturation * fixScale); + * int yScale = (int)(fixScale); + */ + +/* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */ +#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16))) + +static inline void +move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v, + int rowPixels, unsigned char * rgb) +{ + const int rvScale = 91881; + const int guScale = -22553; + const int gvScale = -46801; + const int buScale = 116129; + const int yScale = 65536; + int r, g, b; + + g = guScale * u + gvScale * v; +// if (force_rgb) { +// r = buScale * u; +// b = rvScale * v; +// } else { + r = rvScale * v; + b = buScale * u; +// } + + yTL *= yScale; yTR *= yScale; + yBL *= yScale; yBR *= yScale; + + /* Write out top two pixels */ + rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); + rgb[2] = LIMIT(r+yTL); + + rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); + rgb[5] = LIMIT(r+yTR); + + /* Skip down to next line to write out bottom two pixels */ + rgb += 3 * rowPixels; + rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL); + rgb[2] = LIMIT(r+yBL); + + rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR); + rgb[5] = LIMIT(r+yBR); +} + +static inline void +move_411_block(int yTL, int yTR, int yBL, int yBR, int u, int v, + int /*rowPixels*/, unsigned char * rgb) +{ + const int rvScale = 91881; + const int guScale = -22553; + const int gvScale = -46801; + const int buScale = 116129; + const int yScale = 65536; + int r, g, b; + + g = guScale * u + gvScale * v; +// if (force_rgb) { +// r = buScale * u; +// b = rvScale * v; +// } else { + r = rvScale * v; + b = buScale * u; +// } + + yTL *= yScale; yTR *= yScale; + yBL *= yScale; yBR *= yScale; + + /* Write out top two first pixels */ + rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); + rgb[2] = LIMIT(r+yTL); + + rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); + rgb[5] = LIMIT(r+yTR); + + /* Write out top two last pixels */ + rgb += 6; + rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL); + rgb[2] = LIMIT(r+yBL); + + rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR); + rgb[5] = LIMIT(r+yBR); +} + +// Consider a YUV420P image of 8x2 pixels. +// +// A plane of Y values A B C D E F G H +// I J K L M N O P +// +// A plane of U values 1 2 3 4 +// A plane of V values 1 2 3 4 .... +// +// The U1/V1 samples correspond to the ABIJ pixels. +// U2/V2 samples correspond to the CDKL pixels. +// +/* Converts from planar YUV420P to RGB24. */ +static void +yuv420p_to_rgb24(int width, int height, + unsigned char *pIn0, unsigned char *pOut0) +{ + const int numpix = width * height; + const int bytes = 24 >> 3; + int i, j, y00, y01, y10, y11, u, v; + unsigned char *pY = pIn0; + unsigned char *pU = pY + numpix; + unsigned char *pV = pU + numpix / 4; + unsigned char *pOut = pOut0; + + for (j = 0; j <= height - 2; j += 2) { + for (i = 0; i <= width - 2; i += 2) { + y00 = *pY; + y01 = *(pY + 1); + y10 = *(pY + width); + y11 = *(pY + width + 1); + u = (*pU++) - 128; + v = (*pV++) - 128; + + move_420_block(y00, y01, y10, y11, u, v, + width, pOut); + + pY += 2; + pOut += 2 * bytes; + + } + pY += width; + pOut += width * bytes; + } +} + +// Consider a YUV420 image of 6x2 pixels. +// +// A B C D U1 U2 +// I J K L V1 V2 +// +// The U1/V1 samples correspond to the ABIJ pixels. +// U2/V2 samples correspond to the CDKL pixels. +// +/* Converts from interlaced YUV420 to RGB24. */ +/* [FD] untested... */ +#ifdef HAVE_CAMV4L +static void +yuv420_to_rgb24(int width, int height, + unsigned char *pIn0, unsigned char *pOut0) +{ + const int bytes = 24 >> 3; + int i, j, y00, y01, y10, y11, u, v; + unsigned char *pY = pIn0; + unsigned char *pU = pY + 4; + unsigned char *pV = pU + width; + unsigned char *pOut = pOut0; + + for (j = 0; j <= height - 2; j += 2) { + for (i = 0; i <= width - 4; i += 4) { + y00 = *pY; + y01 = *(pY + 1); + y10 = *(pY + width); + y11 = *(pY + width + 1); + u = (*pU++) - 128; + v = (*pV++) - 128; + + move_420_block(y00, y01, y10, y11, u, v, + width, pOut); + + pY += 2; + pOut += 2 * bytes; + + y00 = *pY; + y01 = *(pY + 1); + y10 = *(pY + width); + y11 = *(pY + width + 1); + u = (*pU++) - 128; + v = (*pV++) - 128; + + move_420_block(y00, y01, y10, y11, u, v, + width, pOut); + + pY += 4; // skip UV + pOut += 2 * bytes; + + } + pY += width; + pOut += width * bytes; + } +} +#endif //HAVE_CAMV4L + +// Consider a YUV411P image of 8x2 pixels. +// +// A plane of Y values as before. +// +// A plane of U values 1 2 +// 3 4 +// +// A plane of V values 1 2 +// 3 4 +// +// The U1/V1 samples correspond to the ABCD pixels. +// U2/V2 samples correspond to the EFGH pixels. +// +/* Converts from planar YUV411P to RGB24. */ +/* [FD] untested... */ +static void +yuv411p_to_rgb24(int width, int height, + unsigned char *pIn0, unsigned char *pOut0) +{ + const int numpix = width * height; + const int bytes = 24 >> 3; + int i, j, y00, y01, y10, y11, u, v; + unsigned char *pY = pIn0; + unsigned char *pU = pY + numpix; + unsigned char *pV = pU + numpix / 4; + unsigned char *pOut = pOut0; + + for (j = 0; j <= height; j++) { + for (i = 0; i <= width - 4; i += 4) { + y00 = *pY; + y01 = *(pY + 1); + y10 = *(pY + 2); + y11 = *(pY + 3); + u = (*pU++) - 128; + v = (*pV++) - 128; + + move_411_block(y00, y01, y10, y11, u, v, + width, pOut); + + pY += 4; + pOut += 4 * bytes; + + } + } +} + +/* convert from 4:2:2 YUYV interlaced to RGB24 */ +/* based on ccvt_yuyv_bgr32() from camstream */ +#define SAT(c) \ + if (c & (~255)) { if (c < 0) c = 0; else c = 255; } + +#ifdef HAVE_CAMV4L2 +static void +yuyv_to_rgb24 (int width, int height, unsigned char *src, unsigned char *dst) +{ + unsigned char *s; + unsigned char *d; + int l, c; + int r, g, b, cr, cg, cb, y1, y2; + + l = height; + s = src; + d = dst; + while (l--) { + c = width >> 1; + while (c--) { + y1 = *s++; + cb = ((*s - 128) * 454) >> 8; + cg = (*s++ - 128) * 88; + y2 = *s++; + cr = ((*s - 128) * 359) >> 8; + cg = (cg + (*s++ - 128) * 183) >> 8; + + r = y1 + cr; + b = y1 + cb; + g = y1 - cg; + SAT(r); + SAT(g); + SAT(b); + + *d++ = b; + *d++ = g; + *d++ = r; + + r = y2 + cr; + b = y2 + cb; + g = y2 - cg; + SAT(r); + SAT(g); + SAT(b); + + *d++ = b; + *d++ = g; + *d++ = r; + } + } +} + +static void +uyvy_to_rgb24 (int width, int height, unsigned char *src, unsigned char *dst) +{ + unsigned char *s; + unsigned char *d; + int l, c; + int r, g, b, cr, cg, cb, y1, y2; + + l = height; + s = src; + d = dst; + while (l--) { + c = width >> 1; + while (c--) { + cb = ((*s - 128) * 454) >> 8; + cg = (*s++ - 128) * 88; + y1 = *s++; + cr = ((*s - 128) * 359) >> 8; + cg = (cg + (*s++ - 128) * 183) >> 8; + y2 = *s++; + + r = y1 + cr; + b = y1 + cb; + g = y1 - cg; + SAT(r); + SAT(g); + SAT(b); + + *d++ = b; + *d++ = g; + *d++ = r; + + r = y2 + cr; + b = y2 + cb; + g = y2 - cg; + SAT(r); + SAT(g); + SAT(b); + + *d++ = b; + *d++ = g; + *d++ = r; + } + } +} +#endif //HAVE_CAMV4L2 + +#ifdef HAVE_JPEG + +/* convert from mjpeg to rgb24 */ +static bool +mjpeg_to_rgb24 (int width, int height, + unsigned char *src, int length, + unsigned char *dst) +{ + cv::Mat temp=cv::imdecode(cv::Mat(std::vector(src, src + length)), 1); + if( !temp.data || temp.cols != width || temp.rows != height ) + return false; + memcpy(dst, temp.data, width*height*3); + return true; +} + +#endif + +/* + * BAYER2RGB24 ROUTINE TAKEN FROM: + * + * Sonix SN9C10x based webcam basic I/F routines + * Takafumi Mizuno + * + */ + +#ifdef HAVE_CAMV4L2 +static void bayer2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, unsigned char *dst) +{ + long int i; + unsigned char *rawpt, *scanpt; + long int size; + + rawpt = src; + scanpt = dst; + size = WIDTH*HEIGHT; + + for ( i = 0; i < size; i++ ) { + if ( (i/WIDTH) % 2 == 0 ) { + if ( (i % 2) == 0 ) { + /* B */ + if ( (i > WIDTH) && ((i % WIDTH) > 0) ) { + *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+ + *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1)+ + *(rawpt+WIDTH)+*(rawpt-WIDTH))/4; /* G */ + *scanpt++ = *rawpt; /* B */ + } else { + /* first line or left column */ + *scanpt++ = *(rawpt+WIDTH+1); /* R */ + *scanpt++ = (*(rawpt+1)+*(rawpt+WIDTH))/2; /* G */ + *scanpt++ = *rawpt; /* B */ + } + } else { + /* (B)G */ + if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) { + *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* R */ + *scanpt++ = *rawpt; /* G */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */ + } else { + /* first line or right column */ + *scanpt++ = *(rawpt+WIDTH); /* R */ + *scanpt++ = *rawpt; /* G */ + *scanpt++ = *(rawpt-1); /* B */ + } + } + } else { + if ( (i % 2) == 0 ) { + /* G(R) */ + if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) { + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* R */ + *scanpt++ = *rawpt; /* G */ + *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* B */ + } else { + /* bottom line or left column */ + *scanpt++ = *(rawpt+1); /* R */ + *scanpt++ = *rawpt; /* G */ + *scanpt++ = *(rawpt-WIDTH); /* B */ + } + } else { + /* R */ + if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) { + *scanpt++ = *rawpt; /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1)+ + *(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */ + *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+ + *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* B */ + } else { + /* bottom line or right column */ + *scanpt++ = *rawpt; /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt-WIDTH))/2; /* G */ + *scanpt++ = *(rawpt-WIDTH-1); /* B */ + } + } + } + rawpt++; + } + +} + +// SGBRG to RGB24 +// for some reason, red and blue needs to be swapped +// at least for 046d:092f Logitech, Inc. QuickCam Express Plus to work +//see: http://www.siliconimaging.com/RGB%20Bayer.htm +//and 4.6 at http://tldp.org/HOWTO/html_single/libdc1394-HOWTO/ +static void sgbrg2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, unsigned char *dst) +{ + long int i; + unsigned char *rawpt, *scanpt; + long int size; + + rawpt = src; + scanpt = dst; + size = WIDTH*HEIGHT; + + for ( i = 0; i < size; i++ ) + { + if ( (i/WIDTH) % 2 == 0 ) //even row + { + if ( (i % 2) == 0 ) //even pixel + { + if ( (i > WIDTH) && ((i % WIDTH) > 0) ) + { + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-WIDTH) + *(rawpt+WIDTH))/2; /* B */ + } else + { + /* first line or left column */ + + *scanpt++ = *(rawpt+1); /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = *(rawpt+WIDTH); /* B */ + } + } else //odd pixel + { + if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) + { + *scanpt++ = *(rawpt); /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1)+*(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */ + *scanpt++ = (*(rawpt-WIDTH-1) + *(rawpt-WIDTH+1) + *(rawpt+WIDTH-1) + *(rawpt+WIDTH+1))/4; /* B */ + } else + { + /* first line or right column */ + + *scanpt++ = *(rawpt); /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+WIDTH))/2; /* G */ + *scanpt++ = *(rawpt+WIDTH-1); /* B */ + } + } + } else + { //odd row + if ( (i % 2) == 0 ) //even pixel + { + if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) + { + *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+*(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1)+*(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */ + *scanpt++ = *(rawpt); /* B */ + } else + { + /* bottom line or left column */ + + *scanpt++ = *(rawpt-WIDTH+1); /* R */ + *scanpt++ = (*(rawpt+1)+*(rawpt-WIDTH))/2; /* G */ + *scanpt++ = *(rawpt); /* B */ + } + } else + { //odd pixel + if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) + { + *scanpt++ = (*(rawpt-WIDTH)+*(rawpt+WIDTH))/2; /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */ + } else + { + /* bottom line or right column */ + + *scanpt++ = (*(rawpt-WIDTH)); /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-1)); /* B */ + } + } + } + rawpt++; + } +} + +#define CLAMP(x) ((x)<0?0:((x)>255)?255:(x)) + +typedef struct { + int is_abs; + int len; + int val; +} code_table_t; + + +/* local storage */ +static code_table_t table[256]; +static int init_done = 0; + + +/* + sonix_decompress_init + ===================== + pre-calculates a locally stored table for efficient huffman-decoding. + + Each entry at index x in the table represents the codeword + present at the MSB of byte x. + +*/ +static void sonix_decompress_init(void) +{ + int i; + int is_abs, val, len; + + for (i = 0; i < 256; i++) { + is_abs = 0; + val = 0; + len = 0; + if ((i & 0x80) == 0) { + /* code 0 */ + val = 0; + len = 1; + } + else if ((i & 0xE0) == 0x80) { + /* code 100 */ + val = +4; + len = 3; + } + else if ((i & 0xE0) == 0xA0) { + /* code 101 */ + val = -4; + len = 3; + } + else if ((i & 0xF0) == 0xD0) { + /* code 1101 */ + val = +11; + len = 4; + } + else if ((i & 0xF0) == 0xF0) { + /* code 1111 */ + val = -11; + len = 4; + } + else if ((i & 0xF8) == 0xC8) { + /* code 11001 */ + val = +20; + len = 5; + } + else if ((i & 0xFC) == 0xC0) { + /* code 110000 */ + val = -20; + len = 6; + } + else if ((i & 0xFC) == 0xC4) { + /* code 110001xx: unknown */ + val = 0; + len = 8; + } + else if ((i & 0xF0) == 0xE0) { + /* code 1110xxxx */ + is_abs = 1; + val = (i & 0x0F) << 4; + len = 8; + } + table[i].is_abs = is_abs; + table[i].val = val; + table[i].len = len; + } + + init_done = 1; +} + + +/* + sonix_decompress + ================ + decompresses an image encoded by a SN9C101 camera controller chip. + + IN width + height + inp pointer to compressed frame (with header already stripped) + OUT outp pointer to decompressed frame + + Returns 0 if the operation was successful. + Returns <0 if operation failed. + +*/ +static int sonix_decompress(int width, int height, unsigned char *inp, unsigned char *outp) +{ + int row, col; + int val; + int bitpos; + unsigned char code; + unsigned char *addr; + + if (!init_done) { + /* do sonix_decompress_init first! */ + return -1; + } + + bitpos = 0; + for (row = 0; row < height; row++) { + + col = 0; + + + + /* first two pixels in first two rows are stored as raw 8-bit */ + if (row < 2) { + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + bitpos += 8; + *outp++ = code; + + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + bitpos += 8; + *outp++ = code; + + col += 2; + } + + while (col < width) { + /* get bitcode from bitstream */ + addr = inp + (bitpos >> 3); + code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); + + /* update bit position */ + bitpos += table[code].len; + + /* calculate pixel value */ + val = table[code].val; + if (!table[code].is_abs) { + /* value is relative to top and left pixel */ + if (col < 2) { + /* left column: relative to top pixel */ + val += outp[-2*width]; + } + else if (row < 2) { + /* top row: relative to left pixel */ + val += outp[-2]; + } + else { + /* main area: average of left pixel and top pixel */ + val += (outp[-2] + outp[-2*width]) / 2; + } + } + + /* store pixel */ + *outp++ = CLAMP(val); + col++; + } + } + + return 0; +} +#endif //HAVE_CAMV4L2 + +static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { + +#ifdef HAVE_CAMV4L2 + if (V4L2_SUPPORT == 0) +#endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + /* [FD] this really belongs here */ + if (ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex].frame) == -1) { + fprintf( stderr, "HIGHGUI ERROR: V4L: Could not SYNC to video stream. %s\n", strerror(errno)); + } + + } +#endif /* HAVE_CAMV4L */ + + /* Now get what has already been captured as a IplImage return */ + + /* First, reallocate imageData if the frame size changed */ + +#ifdef HAVE_CAMV4L2 + + if (V4L2_SUPPORT == 1) + { + + if(((unsigned long)capture->frame.width != capture->form.fmt.pix.width) + || ((unsigned long)capture->frame.height != capture->form.fmt.pix.height)) { + cvFree(&capture->frame.imageData); + cvInitImageHeader( &capture->frame, + cvSize( capture->form.fmt.pix.width, + capture->form.fmt.pix.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + } + + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + if((capture->frame.width != capture->mmaps[capture->bufferIndex].width) + || (capture->frame.height != capture->mmaps[capture->bufferIndex].height)) { + cvFree(&capture->frame.imageData); + cvInitImageHeader( &capture->frame, + cvSize( capture->captureWindow.width, + capture->captureWindow.height ), + IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); + capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); + } + + } +#endif /* HAVE_CAMV4L */ + +#ifdef HAVE_CAMV4L2 + + if (V4L2_SUPPORT == 1) + { + switch (capture->palette) + { + case PALETTE_BGR24: + memcpy((char *)capture->frame.imageData, + (char *)capture->buffers[capture->bufferIndex].start, + capture->frame.imageSize); + break; + + case PALETTE_YVU420: + yuv420p_to_rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)(capture->buffers[capture->bufferIndex].start), + (unsigned char*)capture->frame.imageData); + break; + + case PALETTE_YUV411P: + yuv411p_to_rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)(capture->buffers[capture->bufferIndex].start), + (unsigned char*)capture->frame.imageData); + break; +#ifdef HAVE_JPEG + case PALETTE_MJPEG: + if (!mjpeg_to_rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)(capture->buffers[capture->bufferIndex] + .start), + capture->buffers[capture->bufferIndex].length, + (unsigned char*)capture->frame.imageData)) + return 0; + break; +#endif + + case PALETTE_YUYV: + yuyv_to_rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)(capture->buffers[capture->bufferIndex].start), + (unsigned char*)capture->frame.imageData); + break; + case PALETTE_UYVY: + uyvy_to_rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)(capture->buffers[capture->bufferIndex].start), + (unsigned char*)capture->frame.imageData); + break; + case PALETTE_SBGGR8: + bayer2rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)capture->buffers[capture->bufferIndex].start, + (unsigned char*)capture->frame.imageData); + break; + + case PALETTE_SN9C10X: + sonix_decompress_init(); + sonix_decompress(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)capture->buffers[capture->bufferIndex].start, + (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start); + + bayer2rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start, + (unsigned char*)capture->frame.imageData); + break; + + case PALETTE_SGBRG: + sgbrg2rgb24(capture->form.fmt.pix.width, + capture->form.fmt.pix.height, + (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start, + (unsigned char*)capture->frame.imageData); + break; + } + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + switch(capture->imageProperties.palette) + { + case VIDEO_PALETTE_RGB24: + memcpy((char *)capture->frame.imageData, + (char *)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), + capture->frame.imageSize); + break; + case VIDEO_PALETTE_YUV420P: + yuv420p_to_rgb24(capture->captureWindow.width, + capture->captureWindow.height, + (unsigned char*)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), + (unsigned char*)capture->frame.imageData); + break; + case VIDEO_PALETTE_YUV420: + yuv420_to_rgb24(capture->captureWindow.width, + capture->captureWindow.height, + (unsigned char*)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), + (unsigned char*)capture->frame.imageData); + break; + case VIDEO_PALETTE_YUV411P: + yuv411p_to_rgb24(capture->captureWindow.width, + capture->captureWindow.height, + (unsigned char*)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), + (unsigned char*)capture->frame.imageData); + break; + default: + fprintf( stderr, + "HIGHGUI ERROR: V4L: Cannot convert from palette %d to RGB\n", + capture->imageProperties.palette); + + return 0; + } + + } +#endif /* HAVE_CAMV4L */ + + return(&capture->frame); +} + +static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, + int property_id ) { + +#ifdef HAVE_CAMV4L2 + +#ifdef HAVE_CAMV4L + if (V4L2_SUPPORT == 1) +#endif + { + + /* default value for min and max */ + int v4l2_min = 0; + int v4l2_max = 255; + + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { + /* display an error message, and return an error code */ + perror ("VIDIOC_G_FMT"); + return -1; + } + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + return capture->form.fmt.pix.width; + case CV_CAP_PROP_FRAME_HEIGHT: + return capture->form.fmt.pix.height; + } + + /* initialize the control structure */ + + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + capture->control.id = V4L2_CID_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + capture->control.id = V4L2_CID_CONTRAST; + break; + case CV_CAP_PROP_SATURATION: + capture->control.id = V4L2_CID_SATURATION; + break; + case CV_CAP_PROP_HUE: + capture->control.id = V4L2_CID_HUE; + break; + case CV_CAP_PROP_GAIN: + capture->control.id = V4L2_CID_GAIN; + break; + case CV_CAP_PROP_EXPOSURE: + capture->control.id = V4L2_CID_EXPOSURE; + break; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L2: getting property #%d is not supported\n", + property_id); + return -1; + } + + if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_CTRL, + &capture->control)) { + + fprintf( stderr, "HIGHGUI ERROR: V4L2: "); + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + fprintf (stderr, "Brightness"); + break; + case CV_CAP_PROP_CONTRAST: + fprintf (stderr, "Contrast"); + break; + case CV_CAP_PROP_SATURATION: + fprintf (stderr, "Saturation"); + break; + case CV_CAP_PROP_HUE: + fprintf (stderr, "Hue"); + break; + case CV_CAP_PROP_GAIN: + fprintf (stderr, "Gain"); + break; + case CV_CAP_PROP_EXPOSURE: + fprintf (stderr, "Exposure"); + break; + } + fprintf (stderr, " is not supported by your device\n"); + + return -1; + } + + /* get the min/max values */ + switch (property_id) { + + case CV_CAP_PROP_BRIGHTNESS: + v4l2_min = capture->v4l2_brightness_min; + v4l2_max = capture->v4l2_brightness_max; + break; + case CV_CAP_PROP_CONTRAST: + v4l2_min = capture->v4l2_contrast_min; + v4l2_max = capture->v4l2_contrast_max; + break; + case CV_CAP_PROP_SATURATION: + v4l2_min = capture->v4l2_saturation_min; + v4l2_max = capture->v4l2_saturation_max; + break; + case CV_CAP_PROP_HUE: + v4l2_min = capture->v4l2_hue_min; + v4l2_max = capture->v4l2_hue_max; + break; + case CV_CAP_PROP_GAIN: + v4l2_min = capture->v4l2_gain_min; + v4l2_max = capture->v4l2_gain_max; + break; + case CV_CAP_PROP_EXPOSURE: + v4l2_min = capture->v4l2_exposure_min; + v4l2_max = capture->v4l2_exposure_max; + break; + } + + /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ + return ((float)capture->control.value - v4l2_min + 1) / (v4l2_max - v4l2_min); + + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + int retval = -1; + + if (ioctl (capture->deviceHandle, + VIDIOCGWIN, &capture->captureWindow) < 0) { + fprintf (stderr, + "HIGHGUI ERROR: V4L: " + "Unable to determine size of incoming image\n"); + icvCloseCAM_V4L(capture); + return -1; + } + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + retval = capture->captureWindow.width; + break; + case CV_CAP_PROP_FRAME_HEIGHT: + retval = capture->captureWindow.height; + break; + case CV_CAP_PROP_BRIGHTNESS: + retval = capture->imageProperties.brightness; + break; + case CV_CAP_PROP_CONTRAST: + retval = capture->imageProperties.contrast; + break; + case CV_CAP_PROP_SATURATION: + retval = capture->imageProperties.colour; + break; + case CV_CAP_PROP_HUE: + retval = capture->imageProperties.hue; + break; + case CV_CAP_PROP_GAIN: + fprintf(stderr, + "HIGHGUI ERROR: V4L: Gain control in V4L is not supported\n"); + return -1; + break; + case CV_CAP_PROP_EXPOSURE: + fprintf(stderr, + "HIGHGUI ERROR: V4L: Exposure control in V4L is not supported\n"); + return -1; + break; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L: getting property #%d is not supported\n", + property_id); + } + + if (retval == -1) { + /* there was a problem */ + return -1; + } + + /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ + return float (retval) / 0xFFFF; + + } +#endif /* HAVE_CAMV4L */ + +}; + +static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) { + +#ifdef HAVE_CAMV4L2 + + if (V4L2_SUPPORT == 1) + { + + CLEAR (capture->cropcap); + capture->cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (ioctl (capture->deviceHandle, VIDIOC_CROPCAP, &capture->cropcap) < 0) { + fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: VIDIOC_CROPCAP\n"); + } else { + + CLEAR (capture->crop); + capture->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + capture->crop.c= capture->cropcap.defrect; + + /* set the crop area, but don't exit if the device don't support croping */ + if (ioctl (capture->deviceHandle, VIDIOC_S_CROP, &capture->crop) < 0) { + fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP\n"); + } + } + + CLEAR (capture->form); + capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + /* read the current setting, mainly to retreive the pixelformat information */ + ioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form); + + /* set the values we want to change */ + capture->form.fmt.pix.width = w; + capture->form.fmt.pix.height = h; + capture->form.fmt.win.chromakey = 0; + capture->form.fmt.win.field = V4L2_FIELD_ANY; + capture->form.fmt.win.clips = 0; + capture->form.fmt.win.clipcount = 0; + capture->form.fmt.pix.field = V4L2_FIELD_ANY; + + /* ask the device to change the size + * don't test if the set of the size is ok, because some device + * don't allow changing the size, and we will get the real size + * later */ + ioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form); + + /* try to set framerate to 30 fps */ + struct v4l2_streamparm setfps; + memset (&setfps, 0, sizeof(struct v4l2_streamparm)); + setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + setfps.parm.capture.timeperframe.numerator = 1; + setfps.parm.capture.timeperframe.denominator = 30; + ioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps); + + /* we need to re-initialize some things, like buffers, because the size has + * changed */ + capture->FirstCapture = 1; + + /* Get window info again, to get the real value */ + if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) + { + fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: Could not obtain specifics of capture window.\n\n"); + + icvCloseCAM_V4L(capture); + + return 0; + } + + return 0; + + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + if (capture==0) return 0; + if (w>capture->capability.maxwidth) { + w=capture->capability.maxwidth; + } + if (h>capture->capability.maxheight) { + h=capture->capability.maxheight; + } + + capture->captureWindow.width=w; + capture->captureWindow.height=h; + + if (ioctl(capture->deviceHandle, VIDIOCSWIN, &capture->captureWindow) < 0) { + icvCloseCAM_V4L(capture); + return 0; + } + + if (ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) { + icvCloseCAM_V4L(capture); + return 0; + } + + capture->FirstCapture = 1; + + } +#endif /* HAVE_CAMV4L */ + + return 0; + +} + +static int icvSetControl (CvCaptureCAM_V4L* capture, + int property_id, double value) { + + /* limitation of the input value */ + if (value < 0.0) { + value = 0.0; + } else if (value > 1.0) { + value = 1.0; + } + +#ifdef HAVE_CAMV4L2 + + if (V4L2_SUPPORT == 1) + { + + /* default value for min and max */ + int v4l2_min = 0; + int v4l2_max = 255; + + /* initialisations */ + CLEAR (capture->control); + + /* set which control we want to set */ + switch (property_id) { + + case CV_CAP_PROP_BRIGHTNESS: + capture->control.id = V4L2_CID_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + capture->control.id = V4L2_CID_CONTRAST; + break; + case CV_CAP_PROP_SATURATION: + capture->control.id = V4L2_CID_SATURATION; + break; + case CV_CAP_PROP_HUE: + capture->control.id = V4L2_CID_HUE; + break; + case CV_CAP_PROP_GAIN: + capture->control.id = V4L2_CID_GAIN; + break; + case CV_CAP_PROP_EXPOSURE: + capture->control.id = V4L2_CID_EXPOSURE; + break; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L2: setting property #%d is not supported\n", + property_id); + return -1; + } + + /* get the min and max values */ + if (-1 == ioctl (capture->deviceHandle, + VIDIOC_G_CTRL, &capture->control)) { +// perror ("VIDIOC_G_CTRL for getting min/max values"); + return -1; + } + + /* get the min/max values */ + switch (property_id) { + + case CV_CAP_PROP_BRIGHTNESS: + v4l2_min = capture->v4l2_brightness_min; + v4l2_max = capture->v4l2_brightness_max; + break; + case CV_CAP_PROP_CONTRAST: + v4l2_min = capture->v4l2_contrast_min; + v4l2_max = capture->v4l2_contrast_max; + break; + case CV_CAP_PROP_SATURATION: + v4l2_min = capture->v4l2_saturation_min; + v4l2_max = capture->v4l2_saturation_max; + break; + case CV_CAP_PROP_HUE: + v4l2_min = capture->v4l2_hue_min; + v4l2_max = capture->v4l2_hue_max; + break; + case CV_CAP_PROP_GAIN: + v4l2_min = capture->v4l2_gain_min; + v4l2_max = capture->v4l2_gain_max; + break; + case CV_CAP_PROP_EXPOSURE: + v4l2_min = capture->v4l2_exposure_min; + v4l2_max = capture->v4l2_exposure_max; + break; + } + + /* initialisations */ + CLEAR (capture->control); + + /* set which control we want to set */ + switch (property_id) { + + case CV_CAP_PROP_BRIGHTNESS: + capture->control.id = V4L2_CID_BRIGHTNESS; + break; + case CV_CAP_PROP_CONTRAST: + capture->control.id = V4L2_CID_CONTRAST; + break; + case CV_CAP_PROP_SATURATION: + capture->control.id = V4L2_CID_SATURATION; + break; + case CV_CAP_PROP_HUE: + capture->control.id = V4L2_CID_HUE; + break; + case CV_CAP_PROP_GAIN: + capture->control.id = V4L2_CID_GAIN; + break; + case CV_CAP_PROP_EXPOSURE: + capture->control.id = V4L2_CID_EXPOSURE; + break; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L2: setting property #%d is not supported\n", + property_id); + return -1; + } + + /* set the value we want to set to the scaled the value */ + capture->control.value = (int)(value * (v4l2_max - v4l2_min) + v4l2_min); + + /* The driver may clamp the value or return ERANGE, ignored here */ + if (-1 == ioctl (capture->deviceHandle, + VIDIOC_S_CTRL, &capture->control) && errno != ERANGE) { + perror ("VIDIOC_S_CTRL"); + return -1; + } + } +#endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + int v4l_value; + + /* scale the value to the wanted integer one */ + v4l_value = (int)(0xFFFF * value); + + switch (property_id) { + case CV_CAP_PROP_BRIGHTNESS: + capture->imageProperties.brightness = v4l_value; + break; + case CV_CAP_PROP_CONTRAST: + capture->imageProperties.contrast = v4l_value; + break; + case CV_CAP_PROP_SATURATION: + capture->imageProperties.colour = v4l_value; + break; + case CV_CAP_PROP_HUE: + capture->imageProperties.hue = v4l_value; + break; + case CV_CAP_PROP_GAIN: + fprintf(stderr, + "HIGHGUI ERROR: V4L: Gain control in V4L is not supported\n"); + return -1; + case CV_CAP_PROP_EXPOSURE: + fprintf(stderr, + "HIGHGUI ERROR: V4L: Exposure control in V4L is not supported\n"); + return -1; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L: property #%d is not supported\n", + property_id); + return -1; + } + + if (ioctl(capture->deviceHandle, VIDIOCSPICT, &capture->imageProperties) + < 0) + { + fprintf(stderr, + "HIGHGUI ERROR: V4L: Unable to set video informations\n"); + icvCloseCAM_V4L(capture); + return -1; + } + } +#endif /* HAVE_CAMV4L */ + + /* all was OK */ + return 0; + +} + +static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, + int property_id, double value ){ + static int width = 0, height = 0; + int retval; + + /* initialization */ + retval = 0; + + /* two subsequent calls setting WIDTH and HEIGHT will change + the video size */ + /* the first one will return an error, though. */ + + switch (property_id) { + case CV_CAP_PROP_FRAME_WIDTH: + width = cvRound(value); + if(width !=0 && height != 0) { + retval = icvSetVideoSize( capture, width, height); + width = height = 0; + } + break; + case CV_CAP_PROP_FRAME_HEIGHT: + height = cvRound(value); + if(width !=0 && height != 0) { + retval = icvSetVideoSize( capture, width, height); + width = height = 0; + } + break; + case CV_CAP_PROP_BRIGHTNESS: + case CV_CAP_PROP_CONTRAST: + case CV_CAP_PROP_SATURATION: + case CV_CAP_PROP_HUE: + case CV_CAP_PROP_GAIN: + case CV_CAP_PROP_EXPOSURE: + retval = icvSetControl(capture, property_id, value); + break; + default: + fprintf(stderr, + "HIGHGUI ERROR: V4L: setting property #%d is not supported\n", + property_id); + } + + /* return the the status */ + return retval; +} + +static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){ + /* Deallocate space - Hopefully, no leaks */ + + if (capture) + { + +#ifdef HAVE_CAMV4L2 + if (V4L2_SUPPORT == 0) +#endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + { + + if (capture->mmaps) + free(capture->mmaps); + if (capture->memoryMap) + munmap(capture->memoryMap, capture->memoryBuffer.size); + + } +#endif /* HAVE_CAMV4L */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L2 + { + capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type)) { + perror ("Unable to stop the stream."); + } + + for (unsigned int n_buffers_ = 0; n_buffers_ < capture->req.count; ++n_buffers_) + { + if (-1 == munmap (capture->buffers[n_buffers_].start, capture->buffers[n_buffers_].length)) { + perror ("munmap"); + } + } + + if (capture->buffers[MAX_V4L_BUFFERS].start) + { + free(capture->buffers[MAX_V4L_BUFFERS].start); + capture->buffers[MAX_V4L_BUFFERS].start = 0; + } + } +#endif /* HAVE_CAMV4L2 */ + + if (capture->deviceHandle != -1) + close(capture->deviceHandle); + + if (capture->frame.imageData) cvFree(&capture->frame.imageData); + //cvFree((void **)capture); + } +}; + + +class CvCaptureCAM_V4L_CPP : CvCapture +{ +public: + CvCaptureCAM_V4L_CPP() { captureV4L = 0; } + virtual ~CvCaptureCAM_V4L_CPP() { close(); } + + virtual bool open( int index ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); +protected: + + CvCaptureCAM_V4L* captureV4L; +}; + +bool CvCaptureCAM_V4L_CPP::open( int index ) +{ + close(); + captureV4L = icvCaptureFromCAM_V4L(index); + return captureV4L != 0; +} + +void CvCaptureCAM_V4L_CPP::close() +{ + if( captureV4L ) + { + icvCloseCAM_V4L( captureV4L ); + cvFree( &captureV4L ); + } +} + +bool CvCaptureCAM_V4L_CPP::grabFrame() +{ + return captureV4L ? icvGrabFrameCAM_V4L( captureV4L ) != 0 : false; +} + +IplImage* CvCaptureCAM_V4L_CPP::retrieveFrame(int) +{ + return captureV4L ? icvRetrieveFrameCAM_V4L( captureV4L, 0 ) : 0; +} + +double CvCaptureCAM_V4L_CPP::getProperty( int propId ) +{ + return captureV4L ? icvGetPropertyCAM_V4L( captureV4L, propId ) : 0.0; +} + +bool CvCaptureCAM_V4L_CPP::setProperty( int propId, double value ) +{ + return captureV4L ? icvSetPropertyCAM_V4L( captureV4L, propId, value ) != 0 : false; +} + +CvCapture* cvCreateCameraCapture_V4L( int index ) +{ + CvCaptureCAM_V4L_CPP* capture = new CvCaptureCAM_V4L_CPP; + + if( capture->open( index )) + return (CvCapture*)capture; + + delete capture; + return 0; +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_vfw.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_vfw.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_vfw.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_vfw.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,721 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#include + +#ifdef __GNUC__ +#define WM_CAP_FIRSTA (WM_USER) +#define capSendMessage(hwnd,m,w,l) (IsWindow(hwnd)?SendMessage(hwnd,m,w,l):0) +#endif + +#if defined _M_X64 && defined _MSC_VER +#pragma optimize("",off) +#pragma warning(disable: 4748) +#endif + +/********************* Capturing video from AVI via VFW ************************/ + +static BITMAPINFOHEADER icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB ) +{ + BITMAPINFOHEADER bmih; + memset( &bmih, 0, sizeof(bmih)); + bmih.biSize = sizeof(bmih); + bmih.biWidth = width; + bmih.biHeight = height; + bmih.biBitCount = (WORD)bpp; + bmih.biCompression = compression; + bmih.biPlanes = 1; + + return bmih; +} + + +static void icvInitCapture_VFW() +{ + static int isInitialized = 0; + if( !isInitialized ) + { + AVIFileInit(); + isInitialized = 1; + } +} + + +class CvCaptureAVI_VFW : public CvCapture +{ +public: + CvCaptureAVI_VFW() + { + CoInitialize(NULL); + init(); + } + + virtual ~CvCaptureAVI_VFW() + { + close(); + CoUninitialize(); + } + + virtual bool open( const char* filename ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + void init(); + + PAVIFILE avifile; + PAVISTREAM avistream; + PGETFRAME getframe; + AVISTREAMINFO aviinfo; + BITMAPINFOHEADER * bmih; + CvSlice film_range; + double fps; + int pos; + IplImage* frame; + CvSize size; +}; + + +void CvCaptureAVI_VFW::init() +{ + avifile = 0; + avistream = 0; + getframe = 0; + memset( &aviinfo, 0, sizeof(aviinfo) ); + bmih = 0; + film_range = cvSlice(0,0); + fps = 0; + pos = 0; + frame = 0; + size = cvSize(0,0); +} + + +void CvCaptureAVI_VFW::close() +{ + if( getframe ) + AVIStreamGetFrameClose( getframe ); + + if( avistream ) + AVIStreamRelease( avistream ); + + if( avifile ) + AVIFileRelease( avifile ); + + if (frame) + cvReleaseImage( &frame ); + + init(); +} + + +bool CvCaptureAVI_VFW::open( const char* filename ) +{ + close(); + icvInitCapture_VFW(); + + if( !filename ) + return false; + + HRESULT hr = AVIFileOpen( &avifile, filename, OF_READ, NULL ); + if( SUCCEEDED(hr)) + { + hr = AVIFileGetStream( avifile, &avistream, streamtypeVIDEO, 0 ); + if( SUCCEEDED(hr)) + { + hr = AVIStreamInfo( avistream, &aviinfo, sizeof(aviinfo)); + if( SUCCEEDED(hr)) + { + size.width = aviinfo.rcFrame.right - aviinfo.rcFrame.left; + size.height = aviinfo.rcFrame.bottom - aviinfo.rcFrame.top; + BITMAPINFOHEADER bmihdr = icvBitmapHeader( size.width, size.height, 24 ); + + film_range.start_index = (int)aviinfo.dwStart; + film_range.end_index = film_range.start_index + (int)aviinfo.dwLength; + fps = (double)aviinfo.dwRate/aviinfo.dwScale; + pos = film_range.start_index; + getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); + if( getframe != 0 ) + return true; + + // Attempt to open as 8-bit AVI. + bmihdr = icvBitmapHeader( size.width, size.height, 8); + getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); + if( getframe != 0 ) + return true; + } + } + } + + close(); + return false; +} + +bool CvCaptureAVI_VFW::grabFrame() +{ + if( avistream ) + bmih = (BITMAPINFOHEADER*)AVIStreamGetFrame( getframe, pos++ ); + return bmih != 0; +} + +IplImage* CvCaptureAVI_VFW::retrieveFrame(int) +{ + if( avistream && bmih ) + { + bool isColor = bmih->biBitCount == 24; + int nChannels = (isColor) ? 3 : 1; + IplImage src; + cvInitImageHeader( &src, cvSize( bmih->biWidth, bmih->biHeight ), + IPL_DEPTH_8U, nChannels, IPL_ORIGIN_BL, 4 ); + + char* dataPtr = (char*)(bmih + 1); + + // Only account for the color map size if we are an 8-bit image and the color map is used + if (!isColor) + { + static int RGBQUAD_SIZE_PER_BYTE = sizeof(RGBQUAD)/sizeof(BYTE); + int offsetFromColormapToData = (int)bmih->biClrUsed*RGBQUAD_SIZE_PER_BYTE; + dataPtr += offsetFromColormapToData; + } + + cvSetData( &src, dataPtr, src.widthStep ); + + if( !frame || frame->width != src.width || frame->height != src.height ) + { + cvReleaseImage( &frame ); + frame = cvCreateImage( cvGetSize(&src), 8, nChannels ); + } + + cvFlip( &src, frame, 0 ); + return frame; + } + + return 0; +} + +double CvCaptureAVI_VFW::getProperty( int property_id ) +{ + switch( property_id ) + { + case CV_CAP_PROP_POS_MSEC: + return cvRound(pos*1000./fps); + case CV_CAP_PROP_POS_FRAMES: + return pos; + case CV_CAP_PROP_POS_AVI_RATIO: + return (pos - film_range.start_index)/ + (film_range.end_index - film_range.start_index + 1e-10); + case CV_CAP_PROP_FRAME_WIDTH: + return size.width; + case CV_CAP_PROP_FRAME_HEIGHT: + return size.height; + case CV_CAP_PROP_FPS: + return fps; + case CV_CAP_PROP_FOURCC: + return aviinfo.fccHandler; + case CV_CAP_PROP_FRAME_COUNT: + return film_range.end_index - film_range.start_index; + } + return 0; +} + +bool CvCaptureAVI_VFW::setProperty( int property_id, double value ) +{ + switch( property_id ) + { + case CV_CAP_PROP_POS_MSEC: + case CV_CAP_PROP_POS_FRAMES: + case CV_CAP_PROP_POS_AVI_RATIO: + { + switch( property_id ) + { + case CV_CAP_PROP_POS_MSEC: + pos = cvRound(value*fps*0.001); + break; + case CV_CAP_PROP_POS_AVI_RATIO: + pos = cvRound(value*(film_range.end_index - + film_range.start_index) + + film_range.start_index); + break; + default: + pos = cvRound(value); + } + if( pos < film_range.start_index ) + pos = film_range.start_index; + if( pos > film_range.end_index ) + pos = film_range.end_index; + } + break; + default: + return false; + } + + return true; +} + +CvCapture* cvCreateFileCapture_VFW (const char* filename) +{ + CvCaptureAVI_VFW* capture = new CvCaptureAVI_VFW; + if( capture->open(filename) ) + return capture; + delete capture; + return 0; +} + + +/********************* Capturing video from camera via VFW *********************/ + +class CvCaptureCAM_VFW : public CvCapture +{ +public: + CvCaptureCAM_VFW() { init(); } + virtual ~CvCaptureCAM_VFW() { close(); } + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double) { return false; } + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + void init(); + void closeHIC(); + static LRESULT PASCAL frameCallback( HWND hWnd, VIDEOHDR* hdr ); + + CAPDRIVERCAPS caps; + HWND capWnd; + VIDEOHDR* hdr; + DWORD fourcc; + HIC hic; + IplImage* frame; +}; + + +void CvCaptureCAM_VFW::init() +{ + memset( &caps, 0, sizeof(caps) ); + capWnd = 0; + hdr = 0; + fourcc = 0; + hic = 0; + frame = 0; +} + +void CvCaptureCAM_VFW::closeHIC() +{ + if( hic ) + { + ICDecompressEnd( hic ); + ICClose( hic ); + hic = 0; + } +} + + +LRESULT PASCAL CvCaptureCAM_VFW::frameCallback( HWND hWnd, VIDEOHDR* hdr ) +{ + CvCaptureCAM_VFW* capture = 0; + + if (!hWnd) return FALSE; + + capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd); + capture->hdr = hdr; + + return (LRESULT)TRUE; +} + + +// Initialize camera input +bool CvCaptureCAM_VFW::open( int wIndex ) +{ + char szDeviceName[80]; + char szDeviceVersion[80]; + HWND hWndC = 0; + + close(); + + if( (unsigned)wIndex >= 10 ) + wIndex = 0; + + for( ; wIndex < 10; wIndex++ ) + { + if( capGetDriverDescription( wIndex, szDeviceName, + sizeof (szDeviceName), szDeviceVersion, + sizeof (szDeviceVersion))) + { + hWndC = capCreateCaptureWindow ( "My Own Capture Window", + WS_POPUP | WS_CHILD, 0, 0, 320, 240, 0, 0); + if( capDriverConnect (hWndC, wIndex)) + break; + DestroyWindow( hWndC ); + hWndC = 0; + } + } + + if( hWndC ) + { + capWnd = hWndC; + hdr = 0; + hic = 0; + fourcc = (DWORD)-1; + + memset( &caps, 0, sizeof(caps)); + capDriverGetCaps( hWndC, &caps, sizeof(caps)); + ::MoveWindow( hWndC, 0, 0, 320, 240, TRUE ); + capSetUserData( hWndC, (size_t)this ); + capSetCallbackOnFrame( hWndC, frameCallback ); + CAPTUREPARMS p; + capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); + p.dwRequestMicroSecPerFrame = 66667/2; + capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); + //capPreview( hWndC, 1 ); + capPreviewScale(hWndC,FALSE); + capPreviewRate(hWndC,1); + } + return capWnd != 0; +} + + +void CvCaptureCAM_VFW::close() +{ + if( capWnd ) + { + capSetCallbackOnFrame( capWnd, NULL ); + capDriverDisconnect( capWnd ); + DestroyWindow( capWnd ); + closeHIC(); + } + cvReleaseImage( &frame ); + init(); +} + + +bool CvCaptureCAM_VFW::grabFrame() +{ + if( capWnd ) + { + SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 ); + return true; + } + return false; +} + + +IplImage* CvCaptureCAM_VFW::retrieveFrame(int) +{ + BITMAPINFO vfmt; + memset( &vfmt, 0, sizeof(vfmt)); + BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader; + int sz, prevWidth, prevHeight; + + if( !capWnd ) + return 0; + + sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt)); + prevWidth = frame ? frame->width : 0; + prevHeight = frame ? frame->height : 0; + + if( !hdr || hdr->lpData == 0 || sz == 0 ) + return 0; + + if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight ) + { + cvReleaseImage( &frame ); + frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 ); + } + + if( vfmt.bmiHeader.biCompression != BI_RGB || + vfmt.bmiHeader.biBitCount != 24 ) + { + BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 ); + + if( hic == 0 || fourcc != vfmt0.biCompression || + prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight ) + { + closeHIC(); + hic = ICOpen( MAKEFOURCC('V','I','D','C'), + vfmt0.biCompression, ICMODE_DECOMPRESS ); + if( hic ) + { + if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK ) + { + closeHIC(); + return 0; + } + } + } + + if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData, + &vfmt1, frame->imageData ) != ICERR_OK ) + { + closeHIC(); + return 0; + } + + cvFlip( frame, frame, 0 ); + } + else + { + IplImage src; + cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight), + IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 ); + cvSetData( &src, hdr->lpData, src.widthStep ); + cvFlip( &src, frame, 0 ); + } + + return frame; +} + + +double CvCaptureCAM_VFW::getProperty( int property_id ) +{ + switch( property_id ) + { + case CV_CAP_PROP_FRAME_WIDTH: + return frame ? frame->width : 0; + case CV_CAP_PROP_FRAME_HEIGHT: + return frame ? frame->height : 0; + case CV_CAP_PROP_FOURCC: + return fourcc; + } + return 0; +} + + +CvCapture* cvCreateCameraCapture_VFW( int index ) +{ + CvCaptureCAM_VFW* capture = new CvCaptureCAM_VFW; + + if( capture->open( index )) + return capture; + + delete capture; + return 0; +} + + +/*************************** writing AVIs ******************************/ + +class CvVideoWriter_VFW : public CvVideoWriter +{ +public: + CvVideoWriter_VFW() { init(); } + virtual ~CvVideoWriter_VFW() { close(); } + + virtual bool open( const char* filename, int fourcc, + double fps, CvSize frameSize, bool isColor ); + virtual void close(); + virtual bool writeFrame( const IplImage* ); + +protected: + void init(); + bool createStreams( CvSize frameSize, bool isColor ); + + PAVIFILE avifile; + PAVISTREAM compressed; + PAVISTREAM uncompressed; + double fps; + IplImage* tempFrame; + long pos; + int fourcc; +}; + + +void CvVideoWriter_VFW::init() +{ + avifile = 0; + compressed = uncompressed = 0; + fps = 0; + tempFrame = 0; + pos = 0; + fourcc = 0; +} + +void CvVideoWriter_VFW::close() +{ + if( uncompressed ) + AVIStreamRelease( uncompressed ); + if( compressed ) + AVIStreamRelease( compressed ); + if( avifile ) + AVIFileRelease( avifile ); + cvReleaseImage( &tempFrame ); + init(); +} + + +// philipg. Made this code capable of writing 8bpp gray scale bitmaps +struct BITMAPINFO_8Bit +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; +}; + + +bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, CvSize frameSize, bool isColor ) +{ + close(); + + icvInitCapture_VFW(); + if( AVIFileOpen( &avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK ) + { + fourcc = _fourcc; + fps = _fps; + if( frameSize.width > 0 && frameSize.height > 0 && + !createStreams( frameSize, isColor ) ) + { + close(); + return false; + } + } + return true; +} + + +bool CvVideoWriter_VFW::createStreams( CvSize frameSize, bool isColor ) +{ + if( !avifile ) + return false; + AVISTREAMINFO aviinfo; + + BITMAPINFO_8Bit bmih; + bmih.bmiHeader = icvBitmapHeader( frameSize.width, frameSize.height, isColor ? 24 : 8 ); + for( int i = 0; i < 256; i++ ) + { + bmih.bmiColors[i].rgbBlue = (BYTE)i; + bmih.bmiColors[i].rgbGreen = (BYTE)i; + bmih.bmiColors[i].rgbRed = (BYTE)i; + bmih.bmiColors[i].rgbReserved = 0; + } + + memset( &aviinfo, 0, sizeof(aviinfo)); + aviinfo.fccType = streamtypeVIDEO; + aviinfo.fccHandler = 0; + // use highest possible accuracy for dwRate/dwScale + aviinfo.dwScale = (DWORD)((double)0x7FFFFFFF / fps); + aviinfo.dwRate = cvRound(fps * aviinfo.dwScale); + aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0; + aviinfo.rcFrame.right = frameSize.width; + aviinfo.rcFrame.bottom = frameSize.height; + + if( AVIFileCreateStream( avifile, &uncompressed, &aviinfo ) == AVIERR_OK ) + { + AVICOMPRESSOPTIONS copts, *pcopts = &copts; + copts.fccType = streamtypeVIDEO; + copts.fccHandler = fourcc != -1 ? fourcc : 0; + copts.dwKeyFrameEvery = 1; + copts.dwQuality = 10000; + copts.dwBytesPerSecond = 0; + copts.dwFlags = AVICOMPRESSF_VALID; + copts.lpFormat = &bmih; + copts.cbFormat = (isColor ? sizeof(BITMAPINFOHEADER) : sizeof(bmih)); + copts.lpParms = 0; + copts.cbParms = 0; + copts.dwInterleaveEvery = 0; + + if( fourcc != -1 || AVISaveOptions( 0, 0, 1, &uncompressed, &pcopts ) == TRUE ) + { + if( AVIMakeCompressedStream( &compressed, uncompressed, pcopts, 0 ) == AVIERR_OK && + AVIStreamSetFormat( compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK ) + { + fps = fps; + fourcc = (int)copts.fccHandler; + frameSize = frameSize; + tempFrame = cvCreateImage( frameSize, 8, (isColor ? 3 : 1) ); + return true; + } + } + } + return false; +} + + +bool CvVideoWriter_VFW::writeFrame( const IplImage* image ) +{ + bool result = false; + CV_FUNCNAME( "CvVideoWriter_VFW::writeFrame" ); + + __BEGIN__; + + if( !image ) + EXIT; + + if( !compressed && !createStreams( cvGetSize(image), image->nChannels > 1 )) + EXIT; + + if( image->width != tempFrame->width || image->height != tempFrame->height ) + CV_ERROR( CV_StsUnmatchedSizes, + "image size is different from the currently set frame size" ); + + if( image->nChannels != tempFrame->nChannels || + image->depth != tempFrame->depth || + image->origin == 0 || + image->widthStep != cvAlign(image->width*image->nChannels*((image->depth & 255)/8), 4)) + { + cvConvertImage( image, tempFrame, image->origin == 0 ? CV_CVTIMG_FLIP : 0 ); + image = (const IplImage*)tempFrame; + } + + result = AVIStreamWrite( compressed, pos++, 1, image->imageData, + image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK; + + __END__; + + return result; +} + +CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc, + double fps, CvSize frameSize, int isColor ) +{ + CvVideoWriter_VFW* writer = new CvVideoWriter_VFW; + if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 )) + return writer; + delete writer; + return 0; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ximea.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ximea.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_ximea.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_ximea.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,299 @@ +#include "precomp.hpp" + +#include "xiApi.h" +#include "xiExt.h" +#include "m3Api.h" + +/**********************************************************************************/ + +class CvCaptureCAM_XIMEA : public CvCapture +{ +public: + CvCaptureCAM_XIMEA() { init(); } + virtual ~CvCaptureCAM_XIMEA() { close(); } + + virtual bool open( int index ); + virtual void close(); + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); + virtual int getCaptureDomain() { return CV_CAP_XIAPI; } // Return the type of the capture object: CV_CAP_VFW, etc... + +protected: + void init(); + void errMsg(const char* msg, int errNum); + IplImage* frame; + + HANDLE hmv; + DWORD numDevices; + XI_IMG image; + int width; + int height; + int format; + int timeout; +}; + +/**********************************************************************************/ + +CvCapture* cvCreateCameraCapture_XIMEA( int index ) +{ + CvCaptureCAM_XIMEA* capture = new CvCaptureCAM_XIMEA; + + if( capture->open( index )) + return capture; + + delete capture; + return 0; +} + +/**********************************************************************************/ +// Enumerate connected devices +void CvCaptureCAM_XIMEA::init() +{ + xiGetNumberDevices( &numDevices); + hmv = NULL; + memset(&image, 0, sizeof(XI_IMG)); +} + + +/**********************************************************************************/ +// Initialize camera input +bool CvCaptureCAM_XIMEA::open( int wIndex ) +{ + int mvret = XI_OK; + + if(numDevices == 0) + return false; + + if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK) + { + errMsg("Open XI_DEVICE failed", mvret); + return false; + } + + // always use auto exposure/gain + mvret = xiSetParamInt( hmv, XI_PRM_AEAG, 1); + if(mvret != XI_OK) goto error; + + // always use auto white ballance + mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1); + if(mvret != XI_OK) goto error; + + mvret = xiGetParamInt( hmv, XI_PRM_WIDTH, &width); + if(mvret != XI_OK) goto error; + + mvret = xiGetParamInt( hmv, XI_PRM_HEIGHT, &height); + if(mvret != XI_OK) goto error; + + // default image format RGB24 + format = XI_RGB24; + mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, format); + if(mvret != XI_OK) goto error; + + // allocate frame buffer for RGB24 image + frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3); + + //default capture timeout 10s + timeout = 10000; + + mvret = xiStartAcquisition(hmv); + if(mvret != XI_OK) + { + errMsg("StartAcquisition XI_DEVICE failed", mvret); + goto error; + } + + return true; + +error: + xiCloseDevice(hmv); + hmv = NULL; + return false; +} + +/**********************************************************************************/ + +void CvCaptureCAM_XIMEA::close() +{ + if(hmv) + { + xiStopAcquisition(hmv); + xiCloseDevice(hmv); + hmv = NULL; + } +} + +/**********************************************************************************/ + +bool CvCaptureCAM_XIMEA::grabFrame() +{ + image.size = sizeof(XI_IMG); + int mvret = xiGetImage( hmv, timeout, &image); + + if(mvret == MM40_ACQUISITION_STOPED) + { + xiStartAcquisition(hmv); + mvret = xiGetImage(hmv, timeout, &image); + } + + if(mvret != XI_OK) + { + errMsg("Error during GetImage", mvret); + return false; + } + + return true; +} + +/**********************************************************************************/ + +IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int) +{ + // update cvImage after format has changed + if( (int)image.width != width || (int)image.height != height || image.frm != (XI_IMG_FORMAT)format) + { + cvReleaseImage(&frame); + switch( image.frm) + { + case XI_MONO8 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break; + case XI_MONO16 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break; + case XI_RGB24 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break; + case XI_RGB32 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break; + default : + return frame; + } + // update global image format + format = image.frm; + width = image.width; + height = image.height; + } + + // copy pixel data + switch( image.frm) + { + case XI_MONO8 : memcpy( frame->imageData, image.bp, image.width*image.height); break; + case XI_MONO16 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break; + case XI_RGB24 : memcpy( frame->imageData, image.bp, image.width*image.height*3); break; + case XI_RGB32 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(DWORD)); break; + default: break; + } + return frame; +} + +/**********************************************************************************/ + +double CvCaptureCAM_XIMEA::getProperty( int property_id ) +{ + if(hmv == NULL) + return 0; + + int ival = 0; + float fval = 0; + + switch( property_id ) + { + // OCV parameters + case CV_CAP_PROP_POS_FRAMES : return (double) image.nframe; + case CV_CAP_PROP_FRAME_WIDTH : xiGetParamInt( hmv, XI_PRM_WIDTH, &ival); return ival; + case CV_CAP_PROP_FRAME_HEIGHT : xiGetParamInt( hmv, XI_PRM_HEIGHT, &ival); return ival; + case CV_CAP_PROP_FPS : xiGetParamFloat( hmv, XI_PRM_FRAMERATE, &fval); return fval; + case CV_CAP_PROP_GAIN : xiGetParamFloat( hmv, XI_PRM_GAIN, &fval); return fval; + case CV_CAP_PROP_EXPOSURE : xiGetParamInt( hmv, XI_PRM_EXPOSURE, &ival); return ival; + + // XIMEA camera properties + case CV_CAP_PROP_XI_DOWNSAMPLING : xiGetParamInt( hmv, XI_PRM_DOWNSAMPLING, &ival); return ival; + case CV_CAP_PROP_XI_DATA_FORMAT : xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &ival); return ival; + case CV_CAP_PROP_XI_OFFSET_X : xiGetParamInt( hmv, XI_PRM_OFFSET_X, &ival); return ival; + case CV_CAP_PROP_XI_OFFSET_Y : xiGetParamInt( hmv, XI_PRM_OFFSET_Y, &ival); return ival; + case CV_CAP_PROP_XI_TRG_SOURCE : xiGetParamInt( hmv, XI_PRM_TRG_SOURCE, &ival); return ival; + case CV_CAP_PROP_XI_GPI_SELECTOR : xiGetParamInt( hmv, XI_PRM_GPI_SELECTOR, &ival); return ival; + case CV_CAP_PROP_XI_GPI_MODE : xiGetParamInt( hmv, XI_PRM_GPI_MODE, &ival); return ival; + case CV_CAP_PROP_XI_GPI_LEVEL : xiGetParamInt( hmv, XI_PRM_GPI_LEVEL, &ival); return ival; + case CV_CAP_PROP_XI_GPO_SELECTOR : xiGetParamInt( hmv, XI_PRM_GPO_SELECTOR, &ival); return ival; + case CV_CAP_PROP_XI_GPO_MODE : xiGetParamInt( hmv, XI_PRM_GPO_MODE, &ival); return ival; + case CV_CAP_PROP_XI_LED_SELECTOR : xiGetParamInt( hmv, XI_PRM_LED_SELECTOR, &ival); return ival; + case CV_CAP_PROP_XI_LED_MODE : xiGetParamInt( hmv, XI_PRM_LED_MODE, &ival); return ival; + case CV_CAP_PROP_XI_AUTO_WB : xiGetParamInt( hmv, XI_PRM_AUTO_WB, &ival); return ival; + case CV_CAP_PROP_XI_AEAG : xiGetParamInt( hmv, XI_PRM_AEAG, &ival); return ival; + case CV_CAP_PROP_XI_EXP_PRIORITY : xiGetParamFloat( hmv, XI_PRM_EXP_PRIORITY, &fval); return fval; + case CV_CAP_PROP_XI_AE_MAX_LIMIT : xiGetParamInt( hmv, XI_PRM_EXP_PRIORITY, &ival); return ival; + case CV_CAP_PROP_XI_AG_MAX_LIMIT : xiGetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, &fval); return fval; + case CV_CAP_PROP_XI_AEAG_LEVEL : xiGetParamInt( hmv, XI_PRM_AEAG_LEVEL, &ival); return ival; + case CV_CAP_PROP_XI_TIMEOUT : return timeout; + + } + return 0; +} + +/**********************************************************************************/ + +bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value ) +{ + int ival = (int) value; + float fval = (float) value; + + int mvret = XI_OK; + + switch(property_id) + { + // OCV parameters + case CV_CAP_PROP_FRAME_WIDTH : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); + if(mvret == XI_OK) width = ival; + break; + case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); + if(mvret == XI_OK) height = ival; + break; + case CV_CAP_PROP_FPS : mvret = xiSetParamFloat( hmv, XI_PRM_FRAMERATE, fval); break; + case CV_CAP_PROP_GAIN : mvret = xiSetParamFloat( hmv, XI_PRM_GAIN, fval); break; + case CV_CAP_PROP_EXPOSURE : mvret = xiSetParamInt( hmv, XI_PRM_EXPOSURE, ival); break; + // XIMEA camera properties + case CV_CAP_PROP_XI_DOWNSAMPLING : mvret = xiSetParamInt( hmv, XI_PRM_DOWNSAMPLING, ival); break; + case CV_CAP_PROP_XI_DATA_FORMAT : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); + if(mvret == XI_OK) format = ival; + break; + case CV_CAP_PROP_XI_OFFSET_X : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_X, ival); break; + case CV_CAP_PROP_XI_OFFSET_Y : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break; + case CV_CAP_PROP_XI_TRG_SOURCE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break; + case CV_CAP_PROP_XI_GPI_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_GPI_SELECTOR, ival); break; + case CV_CAP_PROP_XI_TRG_SOFTWARE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, 1); break; + case CV_CAP_PROP_XI_GPI_MODE : mvret = xiSetParamInt( hmv, XI_PRM_GPI_MODE, ival); break; + case CV_CAP_PROP_XI_GPI_LEVEL : mvret = xiSetParamInt( hmv, XI_PRM_GPI_LEVEL, ival); break; + case CV_CAP_PROP_XI_GPO_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_GPO_SELECTOR, ival); break; + case CV_CAP_PROP_XI_GPO_MODE : mvret = xiSetParamInt( hmv, XI_PRM_GPO_MODE, ival); break; + case CV_CAP_PROP_XI_LED_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_LED_SELECTOR, ival); break; + case CV_CAP_PROP_XI_LED_MODE : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break; + case CV_CAP_PROP_XI_AUTO_WB : mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, ival); break; + case CV_CAP_PROP_XI_MANUAL_WB : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break; + case CV_CAP_PROP_XI_AEAG : mvret = xiSetParamInt( hmv, XI_PRM_AEAG, ival); break; + case CV_CAP_PROP_XI_EXP_PRIORITY : mvret = xiSetParamFloat( hmv, XI_PRM_EXP_PRIORITY, fval); break; + case CV_CAP_PROP_XI_AE_MAX_LIMIT : mvret = xiSetParamInt( hmv, XI_PRM_EXP_PRIORITY, ival); break; + case CV_CAP_PROP_XI_AG_MAX_LIMIT : mvret = xiSetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, fval); break; + case CV_CAP_PROP_XI_AEAG_LEVEL : mvret = xiSetParamInt( hmv, XI_PRM_AEAG_LEVEL, ival); break; + case CV_CAP_PROP_XI_TIMEOUT : timeout = ival; break; + } + + if(mvret != XI_OK) + { + errMsg("Set parameter error", mvret); + return false; + } + else + return true; + +} + +/**********************************************************************************/ + +void CvCaptureCAM_XIMEA::errMsg(const char* msg, int errNum) +{ +#if defined WIN32 || defined _WIN32 + char buf[512]; + sprintf( buf, "%s : %d\n", msg, errNum); + OutputDebugString(buf); +#else + fprintf(stderr, "%s : %d\n", msg, errNum); +#endif +} + +/**********************************************************************************/ \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_xine.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_xine.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/cap_xine.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/cap_xine.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,846 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// Authors: Konstantin Dols +// Mark Asbach +// +// Institute of Communications Engineering +// RWTH Aachen University + + +#include "precomp.hpp" + +// required to enable some functions used here... +#define XINE_ENABLE_EXPERIMENTAL_FEATURES + +#include + +extern "C" +{ +#include + //#include + + // forward declaration from + const char *xine_get_homedir( void ); +} + +typedef struct CvCaptureAVI_XINE +{ + /// method call table + xine_t * xine; + xine_stream_t * stream; + xine_video_port_t * vo_port; + + /// frame returned by xine_get_next_video_frame() + xine_video_frame_t xine_frame; + + IplImage * yuv_frame; + IplImage * bgr_frame; + + /// image dimansions of the input stream. + CvSize size; + + /// framenumber of the last frame received from xine_get_next_video_frame(). + /// note: always keep this value updated !!!! + int frame_number; + + /// framerate of the opened stream + double frame_rate; + + /// duration of a frame in stream + double frame_duration; + + /// indicated if input is seekable + bool seekable; + +} +CvCaptureAVI_XINE; + + +// 4:2:2 interleaved -> BGR +static void icvYUY2toBGR( CvCaptureAVI_XINE * capture ) +{ + uint8_t * v = capture->xine_frame.data; + int offset; + for ( int y = 0; y < capture->yuv_frame->height; y++ ) + { + offset = y * capture->yuv_frame->widthStep; + + for ( int x = 0; x < capture->yuv_frame->width; x++, offset += 3 ) + { + capture->yuv_frame->imageData[ offset + 1 ] = v[ 3 ]; + capture->yuv_frame->imageData[ offset + 2 ] = v[ 1 ]; + if ( x & 1 ) + { + capture->yuv_frame->imageData[ offset ] = v[ 2 ]; + v += 4; + } + else + { + capture->yuv_frame->imageData[ offset ] = v[ 0 ]; + } + } + } + + // convert to BGR + cvCvtColor( capture->yuv_frame, capture->bgr_frame, CV_YCrCb2BGR ); +} + + +// 4:2:0 planary -> BGR +static void icvYV12toBGR( CvCaptureAVI_XINE * capture ) +{ + IplImage * yuv = capture->yuv_frame; + int w_Y = capture->size.width; + int h_Y = capture->size.height; + + int w_UV = w_Y >> 1; + + int size_Y = w_Y * h_Y; + int size_UV = size_Y / 4; + + int line = yuv->widthStep; + + uint8_t * addr_Y = capture->xine_frame.data; + uint8_t * addr_U = addr_Y + size_Y; + uint8_t * addr_V = addr_U + size_UV; + + // YYYY..UU.VV. -> BGRBGRBGR... + for ( int y = 0; y < h_Y; y++ ) + { + int offset = y * line; + for ( int x = 0; x < w_Y; x++, offset += 3 ) + { + /* + if ( x&1 ) + { + addr_U++; addr_V++; + } + */ + int one_zero = x & 1; + addr_U += one_zero; + addr_V += one_zero; + + yuv->imageData[ offset ] = *( addr_Y++ ); + yuv->imageData[ offset + 1 ] = *addr_U; + yuv->imageData[ offset + 2 ] = *addr_V; + } + + if ( y & 1 ) + { + addr_U -= w_UV; + addr_V -= w_UV; + } + } + + /* convert to BGR */ + cvCvtColor( capture->yuv_frame, capture->bgr_frame, CV_YCrCb2BGR ); +} + +static void icvCloseAVI_XINE( CvCaptureAVI_XINE* capture ) +{ + xine_free_video_frame( capture->vo_port, &capture->xine_frame ); + + if ( capture->yuv_frame ) cvReleaseImage( &capture->yuv_frame ); + if ( capture->bgr_frame ) cvReleaseImage( &capture->bgr_frame ); + + xine_close( capture->stream ); + // xine_dispose( capture->stream ); + + if ( capture->vo_port ) xine_close_video_driver( capture->xine, capture->vo_port ); + + xine_exit( capture->xine ); +} + + +/** + * CHECKS IF THE STREAM IN * capture IS SEEKABLE. +**/ +static void icvCheckSeekAVI_XINE( CvCaptureAVI_XINE * capture ) +{ + OPENCV_ASSERT ( capture, "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture->vo_port"); + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE ... start\n" ); +#endif + + // temp. frame for testing. + xine_video_frame_t tmp; + // try to seek to a future frame... + xine_play( capture->stream, 0, 300 ); /* 300msec */ + // try to receive the frame... + xine_get_next_video_frame( capture->vo_port, &tmp ); + // if the framenumber is still 0, we can't use the xine seek functionality + capture->seekable = ( tmp.frame_number != 0 ); + // reset stream + xine_play( capture->stream, 0, 0 ); + // release xine_frame + xine_free_video_frame( capture->vo_port, &tmp ); + +#ifndef NDEBUG + if ( capture->seekable ) + fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE: Input is seekable, using XINE seek implementation.\n" ); + else + fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE: Input is NOT seekable, using fallback function.\n" ); + + fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE ... end\n" ); +#endif +} + + +static int icvOpenAVI_XINE( CvCaptureAVI_XINE* capture, const char* filename ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... start\n" ); +#endif + + char configfile[ 2048 ]; + + capture->xine = xine_new(); + sprintf( configfile, "%s%s", xine_get_homedir(), "/.xine/config" ); + + xine_config_load( capture->xine, configfile ); + xine_init( capture->xine ); + + xine_engine_set_param( capture->xine, 0, 0 ); + capture->vo_port = xine_new_framegrab_video_port( capture->xine ); + if ( capture->vo_port == NULL ) + { + printf( "(ERROR)icvOpenAVI_XINE(): Unable to initialize video driver.\n" ); + return 0; + } + + capture->stream = xine_stream_new( capture->xine, NULL, capture->vo_port ); + + if ( !xine_open( capture->stream, filename ) ) + { + printf( "(ERROR)icvOpenAVI_XINE(): Unable to open source '%s'\n", filename ); + return 0; + } + // reset stream... + xine_play( capture->stream, 0, 0 ); + + + // initialize some internals... + capture->frame_number = 0; + + if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) + { +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... failed!\n" ); +#endif + return 0; + } + + capture->size = cvSize( capture->xine_frame.width, capture->xine_frame.height ); + capture->yuv_frame = cvCreateImage( capture->size, IPL_DEPTH_8U, 3 ); + capture->bgr_frame = cvCreateImage( capture->size, IPL_DEPTH_8U, 3 ); + + xine_free_video_frame( capture->vo_port, &capture->xine_frame ); + capture->xine_frame.data[ 0 ] = 0; + + icvCheckSeekAVI_XINE( capture ); + + capture->frame_duration = xine_get_stream_info( capture->stream, XINE_STREAM_INFO_FRAME_DURATION ) / 90.; + capture->frame_rate = 1000 / capture->frame_duration; + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) frame_duration = %f, framerate = %f\n", capture->frame_duration, capture->frame_rate ); +#endif + + OPENCV_ASSERT ( capture->yuv_frame, + "icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)", "couldn't create yuv frame"); + + OPENCV_ASSERT ( capture->bgr_frame, + "icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)", "couldn't create bgr frame"); + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... end\n" ); +#endif + return 1; +} + + +static int icvGrabFrameAVI_XINE( CvCaptureAVI_XINE* capture ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvGrabFrameAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture"); + OPENCV_ASSERT ( capture->vo_port, + "icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->vo_port"); + + int res = xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ); + + /* always keep internal framenumber updated !!! */ + if ( res ) capture->frame_number++; + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvGrabFrameAVI_XINE ... end\n" ); +#endif + return res; +} + + +static const IplImage* icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE* capture, int ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->vo_port"); + + /* no frame grabbed yet? so let's do it now! */ + int res = 0; + if ( capture->xine_frame.data == 0 ) + { + res = icvGrabFrameAVI_XINE( capture ); + } + else + { + res = 1; + } + + if ( res ) + { + switch ( capture->xine_frame.colorspace ) + { + case XINE_IMGFMT_YV12: icvYV12toBGR( capture ); +#ifndef NDEBUG + printf( "(DEBUG)icvRetrieveFrameAVI_XINE: converted YV12 to BGR.\n" ); +#endif + break; + + case XINE_IMGFMT_YUY2: icvYUY2toBGR( capture ); +#ifndef NDEBUG + printf( "(DEBUG)icvRetrieveFrameAVI_XINE: converted YUY2 to BGR.\n" ); +#endif + break; + case XINE_IMGFMT_XVMC: printf( "(ERROR)icvRetrieveFrameAVI_XINE: XVMC format not supported!\n" ); + break; + + case XINE_IMGFMT_XXMC: printf( "(ERROR)icvRetrieveFrameAVI_XINE: XXMC format not supported!\n" ); + break; + + default: printf( "(ERROR)icvRetrieveFrameAVI_XINE: unknown color/pixel format!\n" ); + } + + /* always release last xine_frame, not needed anymore, but store its frame_number in *capture ! */ + xine_free_video_frame( capture->vo_port, &capture->xine_frame ); + capture->xine_frame.data = 0; + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... end\n" ); +#endif + return capture->bgr_frame; + } + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... failed!\n" ); +#endif + return 0; +} + + +/** + * THIS FUNCTION IS A FALLBACK FUNCTION FOR THE CASE THAT THE XINE SEEK IMPLEMENTATION + * DOESN'T WORK WITH THE ACTUAL INPUT. THIS FUNCTION IS ONLY USED IN THE CASE OF AN EMERGENCY, + * BECAUSE IT IS VERY SLOW ! +**/ +static int icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE* capture, int f ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvRetricvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream ) return 0; + + // no need to seek if we are already there... + if ( f == capture->frame_number ) + { +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... end\n" ); +#endif + return 1; + } + // if the requested position is behind out actual position, + // we just need to read the remaining amount of frames until we are there. + else if ( f > capture->frame_number ) + { + for ( ;capture->frame_number < f;capture->frame_number++ ) + /// un-increment framenumber grabbing failed + if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) + { + capture->frame_number--; + break; + } + else + { + xine_free_video_frame( capture->vo_port, &capture->xine_frame ); + } + } + // otherwise we need to reset the stream and + // start reading frames from the beginning. + else // f < capture->frame_number + { + /// reset stream, should also work with non-seekable input + xine_play( capture->stream, 0, 0 ); + /// read frames until we are at the requested frame + for ( capture->frame_number = 0; capture->frame_number < f; capture->frame_number++ ) + /// un-increment last framenumber if grabbing failed + if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) + { + capture->frame_number--; + break; + } + else + { + xine_free_video_frame( capture->vo_port, &capture->xine_frame ); + } + } + + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... end\n" ); +#endif + return ( f == capture->frame_number ) ? 1 : 0; +} + + +static int icvSeekFrameAVI_XINE( CvCaptureAVI_XINE* capture, int f ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream ) return 0; + + if ( capture->seekable ) + { + + /// use xinelib's seek functionality + int new_time = ( int ) ( ( f + 1 ) * ( float ) capture->frame_duration ); + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) calling xine_play()" ); +#endif + if ( xine_play( capture->stream, 0, new_time ) ) + { +#ifndef NDEBUG + fprintf( stderr, "ok\n" ); + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); +#endif + capture->frame_number = f; + return 1; + } + else + { +#ifndef NDEBUG + fprintf( stderr, "failed\n" ); + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... failed\n" ); +#endif + return 0; + } + } + else + { +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); +#endif + return icvOldSeekFrameAVI_XINE( capture, f ); + } +} + + +static int icvSeekTimeAVI_XINE( CvCaptureAVI_XINE* capture, int t ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekTimeAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekTimeAVI_XINE ... start\n" ); +#endif + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream ) return 0; + + if ( capture->seekable ) + { + /// use xinelib's seek functionality + if ( xine_play( capture->stream, 0, t ) ) + { + capture->frame_number = ( int ) ( ( float ) t * capture->frame_rate / 1000 ); +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); +#endif + return 1; + } + else + { +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... failed!\n" ); +#endif + return 0; + } + } + else + { + int new_frame = ( int ) ( ( float ) t * capture->frame_rate / 1000 ); +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ....end\n" ); +#endif + return icvOldSeekFrameAVI_XINE( capture, new_frame ); + } +} + + +static int icvSeekRatioAVI_XINE( CvCaptureAVI_XINE* capture, double ratio ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->vo_port"); + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream ) return 0; + + /// ratio must be [0..1] + if ( ratio > 1 || ratio < 0 ) return 0; + + if ( capture->seekable ) + { + // TODO: FIX IT, DOESN'T WORK PROPERLY, YET...! + int pos_t, pos_l, length; + xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length ); + fprintf( stderr, "ratio on GetProperty(): %d\n", pos_l ); + + /// use xinelib's seek functionality + if ( xine_play( capture->stream, (int)(ratio*(float)length), 0 ) ) + { + capture->frame_number = ( int ) ( ratio*length / capture->frame_duration ); + } + else + { +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" ); +#endif + return 0; + } + } + else + { + /// TODO: fill it ! + fprintf( stderr, "icvSeekRatioAVI_XINE(): Seek not supported by stream !\n" ); + fprintf( stderr, "icvSeekRatioAVI_XINE(): (seek in stream with NO seek support NOT implemented...yet!)\n" ); +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" ); +#endif + return 0; + } + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... end!\n" ); +#endif + return 1; +} + + +static double icvGetPropertyAVI_XINE( CvCaptureAVI_XINE* capture, int property_id ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); + OPENCV_ASSERT ( capture->xine, + "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->xine"); + OPENCV_ASSERT ( capture->bgr_frame, + "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->bgr_frame"); + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0 + + int pos_t, pos_l, length; + xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length ); + fprintf( stderr, "ratio on GetProperty(): %i\n", pos_l ); + + switch ( property_id ) + { + /// return actual position in msec + case CV_CAP_PROP_POS_MSEC: + if ( !capture->seekable ) + { + fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_MSEC:\n" ); + fprintf( stderr, " Stream is NOT seekable, so position info may NOT be valid !!\n" ); + } + return pos_t; + + /// return actual frame number + case CV_CAP_PROP_POS_FRAMES: + /// we insist the capture->frame_number to be remain updated !!!! + return capture->frame_number; + + /// return actual position ratio in the range [0..1] depending on + /// the total length of the stream and the actual position + case CV_CAP_PROP_POS_AVI_RATIO: + if ( !capture->seekable ) + { + fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_AVI_RATIO:\n" ); + fprintf( stderr, " Stream is NOT seekable, so ratio info may NOT be valid !!\n" ); + } + if ( length == 0 ) break; + else return pos_l / 65535; + + + /// return width of image source + case CV_CAP_PROP_FRAME_WIDTH: + return capture->size.width; + + /// return height of image source + case CV_CAP_PROP_FRAME_HEIGHT: + return capture->size.height; + + /// return framerate of stream + case CV_CAP_PROP_FPS: + if ( !capture->seekable ) + { + fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_FPS:\n" ); + fprintf( stderr, " Stream is NOT seekable, so FPS info may NOT be valid !!\n" ); + } + return capture->frame_rate; + + /// return four-character-code (FOURCC) of source's codec + case CV_CAP_PROP_FOURCC: + return ( double ) xine_get_stream_info( capture->stream, XINE_STREAM_INFO_VIDEO_FOURCC ); + } + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... failed!\n" ); +#endif + + return 0; +} + + +static int icvSetPropertyAVI_XINE( CvCaptureAVI_XINE* capture, + int property_id, double value ) +{ +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE ... start\n" ); +#endif + + OPENCV_ASSERT ( capture, + "icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )", "illegal capture"); + OPENCV_ASSERT ( capture->stream, + "icvGetPropericvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); + OPENCV_ASSERT ( capture->vo_port, + "icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )", "illegal capture->vo_port"); + +// not needed tnx to asserts... + // we need a valid capture context and it's stream to seek through +// if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0 + +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE: seeking to value %f ... ", value ); +#endif + + switch ( property_id ) + { + /// set (seek to) position in msec + case CV_CAP_PROP_POS_MSEC: + return icvSeekTimeAVI_XINE( capture, ( int ) value ); + + /// set (seek to) frame number + case CV_CAP_PROP_POS_FRAMES: + return icvSeekFrameAVI_XINE( capture, ( int ) value ); + + /// set (seek to) position ratio in the range [0..1] depending on + /// the total length of the stream and the actual position + case CV_CAP_PROP_POS_AVI_RATIO: + return icvSeekRatioAVI_XINE( capture, value ); + + default: +#ifndef NDEBUG + fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE ... failed!\n" ); +#endif + + return 0; + } +} + + +static CvCaptureAVI_XINE* icvCaptureFromFile_XINE( const char* filename ) +{ + // construct capture struct + CvCaptureAVI_XINE * capture = ( CvCaptureAVI_XINE* ) cvAlloc ( sizeof ( CvCaptureAVI_XINE ) ); + memset( capture, 0, sizeof ( CvCaptureAVI_XINE ) ); + + // initialize XINE + if ( !icvOpenAVI_XINE( capture, filename ) ) + return 0; + + OPENCV_ASSERT ( capture, + "cvCaptureFromFile_XINE( const char * )", "couldn't create capture"); + + return capture; + +} + + + +class CvCaptureAVI_XINE_CPP : public CvCapture +{ +public: + CvCaptureAVI_XINE_CPP() { captureXINE = 0; } + virtual ~CvCaptureAVI_XINE_CPP() { close(); } + + virtual bool open( const char* filename ); + virtual void close(); + + virtual double getProperty(int); + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual IplImage* retrieveFrame(int); +protected: + + CvCaptureAVI_XINE* captureXINE; +}; + +bool CvCaptureAVI_XINE_CPP::open( const char* filename ) +{ + close(); + captureXINE = icvCaptureFromFile_XINE(filename); + return captureXINE != 0; +} + +void CvCaptureAVI_XINE_CPP::close() +{ + if( captureXINE ) + { + icvCloseAVI_XINE( captureXINE ); + cvFree( &captureXINE ); + } +} + +bool CvCaptureAVI_XINE_CPP::grabFrame() +{ + return captureXINE ? icvGrabFrameAVI_XINE( captureXINE ) != 0 : false; +} + +IplImage* CvCaptureAVI_XINE_CPP::retrieveFrame(int) +{ + return captureXINE ? (IplImage*)icvRetrieveFrameAVI_XINE( captureXINE, 0 ) : 0; +} + +double CvCaptureAVI_XINE_CPP::getProperty( int propId ) +{ + return captureXINE ? icvGetPropertyAVI_XINE( captureXINE, propId ) : 0; +} + +bool CvCaptureAVI_XINE_CPP::setProperty( int propId, double value ) +{ + return captureXINE ? icvSetPropertyAVI_XINE( captureXINE, propId, value ) != 0 : false; +} + +CvCapture* cvCreateFileCapture_XINE(const char* filename) +{ + CvCaptureAVI_XINE_CPP* capture = new CvCaptureAVI_XINE_CPP; + + if( capture->open(filename)) + return capture; + + delete capture; + return 0; +} + + +#undef NDEBUG diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/ffmpeg_codecs.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/ffmpeg_codecs.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/ffmpeg_codecs.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/ffmpeg_codecs.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,259 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(WIN32) || defined(__MINGW32__) +// some versions of FFMPEG assume a C99 compiler, and don't define INT64_C +#include + +// some versions of FFMPEG assume a C99 compiler, and don't define INT64_C +#ifndef INT64_C +#define INT64_C(c) (c##LL) +#endif + +#ifndef UINT64_C +#define UINT64_C(c) (c##ULL) +#endif + +#include +#endif + +#ifdef WIN32 + #include +#else + +// if the header path is not specified explicitly, let's deduce it +#if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H + +#if defined(HAVE_GENTOO_FFMPEG) + #define HAVE_LIBAVFORMAT_AVFORMAT_H 1 +#elif defined HAVE_FFMPEG + #define HAVE_FFMPEG_AVFORMAT_H 1 +#endif + +#if defined(HAVE_FFMPEG_AVFORMAT_H) + #include +#endif + +#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H) + #include +#endif + +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#ifndef MKTAG +#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) +#endif + +// required to look up the correct codec ID depending on the FOURCC code, +// this is just a snipped from the file riff.c from ffmpeg/libavformat +typedef struct AVCodecTag { + int id; + unsigned int tag; +} AVCodecTag; + +const AVCodecTag codec_bmp_tags[] = { + { CODEC_ID_H264, MKTAG('H', '2', '6', '4') }, + { CODEC_ID_H264, MKTAG('h', '2', '6', '4') }, + { CODEC_ID_H264, MKTAG('X', '2', '6', '4') }, + { CODEC_ID_H264, MKTAG('x', '2', '6', '4') }, + { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, + { CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') }, + + { CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, + { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') }, + { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */ + { CODEC_ID_H261, MKTAG('H', '2', '6', '1') }, + + /* added based on MPlayer */ + { CODEC_ID_H263P, MKTAG('U', '2', '6', '3') }, + { CODEC_ID_H263P, MKTAG('v', 'i', 'v', '1') }, + + { CODEC_ID_MPEG4, MKTAG('F', 'M', 'P', '4') }, + { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, + { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0') }, + { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, + { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') }, + { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') }, + { CODEC_ID_MPEG4, MKTAG(0x04, 0, 0, 0) }, /* some broken avi use this */ + + /* added based on MPlayer */ + { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', '1') }, + { CODEC_ID_MPEG4, MKTAG('B', 'L', 'Z', '0') }, + { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, + { CODEC_ID_MPEG4, MKTAG('U', 'M', 'P', '4') }, + { CODEC_ID_MPEG4, MKTAG('W', 'V', '1', 'F') }, + { CODEC_ID_MPEG4, MKTAG('S', 'E', 'D', 'G') }, + + { CODEC_ID_MPEG4, MKTAG('R', 'M', 'P', '4') }, + + { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') }, /* default signature when using MSMPEG4 */ + { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, + + /* added based on MPlayer */ + { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') }, + { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '5') }, + { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '6') }, + { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '4') }, + { CODEC_ID_MSMPEG4V3, MKTAG('A', 'P', '4', '1') }, + { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '1') }, + { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '0') }, + + { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') }, + + /* added based on MPlayer */ + { CODEC_ID_MSMPEG4V2, MKTAG('D', 'I', 'V', '2') }, + + { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') }, + + { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') }, + + /* added based on MPlayer */ + { CODEC_ID_WMV2, MKTAG('W', 'M', 'V', '2') }, + { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'd') }, + { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'd') }, + { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'l') }, + { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '2', '5') }, + { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') }, + { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') }, + { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') }, + { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'P', 'E', 'G') }, + { CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') }, + { CODEC_ID_MPEG1VIDEO, MKTAG('V', 'C', 'R', '2') }, + { CODEC_ID_MPEG1VIDEO, 0x10000001 }, + { CODEC_ID_MPEG2VIDEO, 0x10000002 }, + { CODEC_ID_MPEG2VIDEO, MKTAG('D', 'V', 'R', ' ') }, + { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'M', 'E', 'S') }, + { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') }, + { CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') }, + { CODEC_ID_LJPEG, MKTAG('L', 'J', 'P', 'G') }, + { CODEC_ID_MJPEG, MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */ + { CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */ + { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, + { CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') }, + { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, + { CODEC_ID_HUFFYUV, MKTAG('H', 'F', 'Y', 'U') }, + { CODEC_ID_FFVHUFF, MKTAG('F', 'F', 'V', 'H') }, + { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') }, + { CODEC_ID_RAWVIDEO, 0 }, + { CODEC_ID_RAWVIDEO, MKTAG('I', '4', '2', '0') }, + { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'Y', '2') }, + { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') }, + { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') }, + { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') }, + { CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') }, + { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') }, + { CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') }, + { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') }, + { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') }, + { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, + { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, + { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') }, + { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') }, + { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') }, + { CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') }, + { CODEC_ID_XAN_WC4, MKTAG('X', 'x', 'a', 'n') }, + { CODEC_ID_MSRLE, MKTAG('m', 'r', 'l', 'e') }, + { CODEC_ID_MSRLE, MKTAG(0x1, 0x0, 0x0, 0x0) }, + { CODEC_ID_MSVIDEO1, MKTAG('M', 'S', 'V', 'C') }, + { CODEC_ID_MSVIDEO1, MKTAG('m', 's', 'v', 'c') }, + { CODEC_ID_MSVIDEO1, MKTAG('C', 'R', 'A', 'M') }, + { CODEC_ID_MSVIDEO1, MKTAG('c', 'r', 'a', 'm') }, + { CODEC_ID_MSVIDEO1, MKTAG('W', 'H', 'A', 'M') }, + { CODEC_ID_MSVIDEO1, MKTAG('w', 'h', 'a', 'm') }, + { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, + { CODEC_ID_TRUEMOTION1, MKTAG('D', 'U', 'C', 'K') }, + { CODEC_ID_MSZH, MKTAG('M', 'S', 'Z', 'H') }, + { CODEC_ID_ZLIB, MKTAG('Z', 'L', 'I', 'B') }, + { CODEC_ID_SNOW, MKTAG('S', 'N', 'O', 'W') }, + { CODEC_ID_4XM, MKTAG('4', 'X', 'M', 'V') }, + { CODEC_ID_FLV1, MKTAG('F', 'L', 'V', '1') }, + { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, + { CODEC_ID_TSCC, MKTAG('t', 's', 'c', 'c') }, + { CODEC_ID_ULTI, MKTAG('U', 'L', 'T', 'I') }, + { CODEC_ID_VIXL, MKTAG('V', 'I', 'X', 'L') }, + { CODEC_ID_QPEG, MKTAG('Q', 'P', 'E', 'G') }, + { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') }, + { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') }, + { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') }, + { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') }, + { CODEC_ID_THEORA, MKTAG('t', 'h', 'e', 'o') }, +#if LIBAVCODEC_VERSION_INT>0x000409 + { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') }, + { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') }, + { CODEC_ID_INDEO2, MKTAG('R', 'T', '2', '1') }, + { CODEC_ID_FRAPS, MKTAG('F', 'P', 'S', '1') }, + { CODEC_ID_TRUEMOTION2, MKTAG('T', 'M', '2', '0') }, +#endif +#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) + { CODEC_ID_FLASHSV, MKTAG('F', 'S', 'V', '1') }, + { CODEC_ID_JPEGLS,MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - encoder */ + { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') }, + { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') }, + { CODEC_ID_CSCD, MKTAG('C', 'S', 'C', 'D') }, + { CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') }, + { CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') }, +#endif +#if LIBAVCODEC_VERSION_INT>((51<<16)+(11<<8)+0) + { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, + { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, + { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, + { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, + { CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') }, + { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') }, + { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') }, +#endif +#if LIBAVCODEC_VERSION_INT>=((51<<16)+(49<<8)+0) +// this tag seems not to exist in older versions of FFMPEG + { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, +#endif + { CODEC_ID_NONE, 0 }, +}; Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/1.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/1.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/10.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/10.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/100.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/100.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/101.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/101.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/102.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/102.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/103.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/103.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/104.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/104.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/105.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/105.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/106.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/106.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/107.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/107.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/108.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/108.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/109.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/109.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/11.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/11.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/110.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/110.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/111.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/111.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/112.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/112.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/113.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/113.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/114.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/114.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/115.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/115.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/116.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/116.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/117.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/117.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/118.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/118.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/119.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/119.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/12.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/12.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/120.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/120.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/121.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/121.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/122.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/122.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/123.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/123.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/124.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/124.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/125.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/125.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/126.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/126.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/127.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/127.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/128.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/128.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/129.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/129.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/13.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/13.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/130.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/130.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/131.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/131.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/14.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/14.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/15.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/15.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/16.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/16.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/17.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/17.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/18.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/18.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/19.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/19.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/2.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/2.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/20.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/20.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/21.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/21.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/22.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/22.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/23.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/23.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/24.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/24.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/25.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/25.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/26.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/26.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/27.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/27.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/28.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/28.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/29.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/29.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/3.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/3.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/30.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/30.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/31.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/31.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/32.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/32.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/33.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/33.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/34.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/34.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/35.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/35.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/36.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/36.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/37.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/37.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/38.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/38.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/39.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/39.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/4.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/4.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/40.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/40.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/41.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/41.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/42.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/42.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/43.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/43.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/44.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/44.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/45.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/45.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/46.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/46.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/47.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/47.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/48.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/48.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/49.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/49.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/5.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/5.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/50.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/50.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/51.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/51.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/52.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/52.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/53.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/53.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/54.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/54.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/55.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/55.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/56.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/56.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/57.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/57.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/58.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/58.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/59.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/59.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/6.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/6.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/60.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/60.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/61.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/61.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/62.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/62.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/63.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/63.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/64.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/64.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/65.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/65.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/66.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/66.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/67.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/67.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/68.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/68.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/69.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/69.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/7.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/7.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/70.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/70.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/71.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/71.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/72.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/72.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/73.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/73.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/74.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/74.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/75.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/75.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/76.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/76.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/77.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/77.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/78.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/78.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/79.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/79.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/8.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/8.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/80.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/80.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/81.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/81.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/82.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/82.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/83.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/83.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/84.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/84.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/85.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/85.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/86.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/86.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/87.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/87.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/88.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/88.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/89.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/89.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/9.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/9.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/90.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/90.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/91.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/91.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/92.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/92.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/93.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/93.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/94.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/94.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/95.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/95.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/96.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/96.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/97.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/97.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/98.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/98.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/99.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/48/99.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/1.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/1.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/10.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/10.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/100.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/100.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/101.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/101.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/102.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/102.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/103.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/103.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/104.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/104.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/105.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/105.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/106.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/106.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/107.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/107.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/108.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/108.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/109.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/109.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/11.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/11.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/110.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/110.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/111.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/111.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/112.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/112.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/113.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/113.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/114.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/114.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/115.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/115.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/116.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/116.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/117.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/117.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/118.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/118.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/119.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/119.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/12.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/12.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/120.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/120.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/121.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/121.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/122.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/122.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/123.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/123.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/124.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/124.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/125.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/125.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/126.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/126.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/127.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/127.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/128.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/128.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/129.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/129.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/13.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/13.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/130.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/130.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/131.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/131.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/14.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/14.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/15.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/15.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/16.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/16.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/17.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/17.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/18.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/18.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/19.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/19.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/2.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/2.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/20.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/20.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/21.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/21.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/22.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/22.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/23.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/23.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/24.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/24.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/25.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/25.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/26.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/26.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/27.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/27.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/28.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/28.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/29.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/29.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/3.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/3.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/30.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/30.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/31.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/31.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/32.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/32.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/33.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/33.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/34.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/34.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/35.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/35.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/36.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/36.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/37.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/37.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/38.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/38.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/39.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/39.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/4.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/4.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/40.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/40.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/41.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/41.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/42.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/42.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/43.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/43.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/44.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/44.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/45.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/45.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/46.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/46.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/47.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/47.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/48.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/48.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/49.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/49.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/5.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/5.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/50.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/50.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/51.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/51.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/52.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/52.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/53.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/53.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/54.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/54.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/55.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/55.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/56.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/56.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/57.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/57.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/58.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/58.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/59.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/59.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/6.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/6.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/60.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/60.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/61.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/61.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/62.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/62.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/63.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/63.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/64.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/64.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/65.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/65.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/66.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/66.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/67.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/67.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/68.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/68.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/69.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/69.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/7.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/7.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/70.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/70.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/71.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/71.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/72.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/72.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/73.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/73.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/74.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/74.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/75.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/75.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/76.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/76.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/77.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/77.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/78.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/78.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/79.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/79.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/8.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/8.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/80.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/80.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/81.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/81.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/82.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/82.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/83.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/83.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/84.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/84.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/85.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/85.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/86.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/86.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/87.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/87.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/88.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/88.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/89.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/89.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/9.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/9.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/90.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/90.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/91.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/91.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/92.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/92.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/93.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/93.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/94.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/94.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/95.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/95.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/96.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/96.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/97.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/97.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/98.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/98.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/99.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/64/99.png differ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/README.txt diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/README.txt --- diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/Milky/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/Milky/README.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,19 @@ +From: +http://iconeden.com/icon/milky-a-free-vector-iconset.html + +License Agreement + +This is a legal agreement between you (the downloader) and IconEden.com. On download of any royalty-free icons from our website you agree to the following: + +All of the icons remain the property of IconEden.com. The icons can be used royalty-free by the license for any personal or commercial project including web application, web design, software application, mobile application, documentation, presentation, computer game, advertising, film, video. + +You may modify the icons in shape, color, and/or file format and use the modified icons royalty-free according to the license terms for any personal or commercial product. + +The license does not permit the following uses: + + 1. The icons may not be resold, sublicensed, rented, transferred or otherwise made available for use or detached from a product, software application or web page; + 2. The icons may not be placed on any electronic bulletin board or downloadable format; + +You may not use, or allow anyone else to use the icons to create pornographic, libelous, obscene, or defamatory material. + +All icon files are provided "as is". You agree not to hold IconEden.com liable for any damages that may occur due to use, or inability to use, icons or image data from IconEden.com. \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/stylesheet_trackbar.qss diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/stylesheet_trackbar.qss --- diffimg-1.5.0/3rdparty/opencv/highgui/src/files_Qt/stylesheet_trackbar.qss 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/files_Qt/stylesheet_trackbar.qss 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,58 @@ +/* //from http://thesmithfam.org/blog/2010/03/10/fancy-qslider-stylesheet/ */ + +QSlider::groove:horizontal { +border: 1px solid #bbb; +background: white; +height: 10px; +border-radius: 4px; +} + +QSlider::sub-page:horizontal { +background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, +stop: 0 #66e, stop: 1 #bbf); +background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1, +stop: 0 #bbf, stop: 1 #55f); +border: 1px solid #777; +height: 10px; +border-radius: 4px; +} + +QSlider::add-page:horizontal { +background: #fff; +border: 1px solid #777; +height: 10px; +border-radius: 4px; +} + +QSlider::handle:horizontal { +background: qlineargradient(x1:0, y1:0, x2:1, y2:1, +stop:0 #eee, stop:1 #ccc); +border: 1px solid #777; +width: 13px; +margin-top: -2px; +margin-bottom: -2px; +border-radius: 4px; +} + +QSlider::handle:horizontal:hover { +background: qlineargradient(x1:0, y1:0, x2:1, y2:1, +stop:0 #fff, stop:1 #ddd); +border: 1px solid #444; +border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { +background: #bbb; +border-color: #999; +} + +QSlider::add-page:horizontal:disabled { +background: #eee; +border-color: #999; +} + +QSlider::handle:horizontal:disabled { +background: #eee; +border: 1px solid #aaa; +border-radius: 4px; +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_base.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_base.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_base.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_base.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,137 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#include "grfmt_base.hpp" +#include "bitstrm.hpp" + +namespace cv +{ + +BaseImageDecoder::BaseImageDecoder() +{ + m_width = m_height = 0; + m_type = -1; + m_buf_supported = false; +} + +bool BaseImageDecoder::setSource( const string& filename ) +{ + m_filename = filename; + m_buf.release(); + return true; +} + +bool BaseImageDecoder::setSource( const Mat& buf ) +{ + if( !m_buf_supported ) + return false; + m_filename = string(); + m_buf = buf; + return true; +} + +size_t BaseImageDecoder::signatureLength() const +{ + return m_signature.size(); +} + +bool BaseImageDecoder::checkSignature( const string& signature ) const +{ + size_t len = signatureLength(); + return signature.size() >= len && memcmp( signature.c_str(), m_signature.c_str(), len ) == 0; +} + +ImageDecoder BaseImageDecoder::newDecoder() const +{ + return ImageDecoder(); +} + +BaseImageEncoder::BaseImageEncoder() +{ + m_buf_supported = false; +} + +bool BaseImageEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U; +} + +string BaseImageEncoder::getDescription() const +{ + return m_description; +} + +bool BaseImageEncoder::setDestination( const string& filename ) +{ + m_filename = filename; + m_buf = 0; + return true; +} + +bool BaseImageEncoder::setDestination( vector& buf ) +{ + if( !m_buf_supported ) + return false; + m_buf = &buf; + m_buf->clear(); + m_filename = string(); + return true; +} + +ImageEncoder BaseImageEncoder::newEncoder() const +{ + return ImageEncoder(); +} + +void BaseImageEncoder::throwOnEror() const +{ + if(!m_last_error.empty()) + { + std::string msg = "Raw image encoder error: " + m_last_error; + CV_Error( CV_BadImageSize, msg.c_str() ); + } +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_base.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_base.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_base.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_base.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,117 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_BASE_H_ +#define _GRFMT_BASE_H_ + +#include "utils.hpp" +#include "bitstrm.hpp" + +namespace cv +{ + +class BaseImageDecoder; +class BaseImageEncoder; +typedef Ptr ImageEncoder; +typedef Ptr ImageDecoder; + +///////////////////////////////// base class for decoders //////////////////////// +class BaseImageDecoder +{ +public: + BaseImageDecoder(); + virtual ~BaseImageDecoder() {}; + + int width() const { return m_width; }; + int height() const { return m_height; }; + virtual int type() const { return m_type; }; + + virtual bool setSource( const string& filename ); + virtual bool setSource( const Mat& buf ); + virtual bool readHeader() = 0; + virtual bool readData( Mat& img ) = 0; + + virtual size_t signatureLength() const; + virtual bool checkSignature( const string& signature ) const; + virtual ImageDecoder newDecoder() const; + +protected: + int m_width; // width of the image ( filled by readHeader ) + int m_height; // height of the image ( filled by readHeader ) + int m_type; + string m_filename; + string m_signature; + Mat m_buf; + bool m_buf_supported; +}; + + +///////////////////////////// base class for encoders //////////////////////////// +class BaseImageEncoder +{ +public: + BaseImageEncoder(); + virtual ~BaseImageEncoder() {}; + virtual bool isFormatSupported( int depth ) const; + + virtual bool setDestination( const string& filename ); + virtual bool setDestination( vector& buf ); + virtual bool write( const Mat& img, const vector& params ) = 0; + + virtual string getDescription() const; + virtual ImageEncoder newEncoder() const; + + virtual void throwOnEror() const; + +protected: + string m_description; + + string m_filename; + vector* m_buf; + bool m_buf_supported; + + string m_last_error; +}; + +} + +#endif/*_GRFMT_BASE_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_bmp.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_bmp.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_bmp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_bmp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,566 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "grfmt_bmp.hpp" + +namespace cv +{ + +static const char* fmtSignBmp = "BM"; + +/************************ BMP decoder *****************************/ + +BmpDecoder::BmpDecoder() +{ + m_signature = fmtSignBmp; + m_offset = -1; + m_buf_supported = true; +} + + +BmpDecoder::~BmpDecoder() +{ +} + + +void BmpDecoder::close() +{ + m_strm.close(); +} + +ImageDecoder BmpDecoder::newDecoder() const +{ + return new BmpDecoder; +} + +bool BmpDecoder::readHeader() +{ + bool result = false; + bool iscolor = false; + + if( !m_buf.empty() ) + { + if( !m_strm.open( m_buf ) ) + return false; + } + else if( !m_strm.open( m_filename )) + return false; + + try + { + m_strm.skip( 10 ); + m_offset = m_strm.getDWord(); + + int size = m_strm.getDWord(); + + if( size >= 36 ) + { + m_width = m_strm.getDWord(); + m_height = m_strm.getDWord(); + m_bpp = m_strm.getDWord() >> 16; + m_rle_code = (BmpCompression)m_strm.getDWord(); + m_strm.skip(12); + int clrused = m_strm.getDWord(); + m_strm.skip( size - 36 ); + + if( m_width > 0 && m_height != 0 && + (((m_bpp == 1 || m_bpp == 4 || m_bpp == 8 || + m_bpp == 24 || m_bpp == 32 ) && m_rle_code == BMP_RGB) || + (m_bpp == 16 && (m_rle_code == BMP_RGB || m_rle_code == BMP_BITFIELDS)) || + (m_bpp == 4 && m_rle_code == BMP_RLE4) || + (m_bpp == 8 && m_rle_code == BMP_RLE8))) + { + iscolor = true; + result = true; + + if( m_bpp <= 8 ) + { + memset( m_palette, 0, sizeof(m_palette)); + m_strm.getBytes( m_palette, (clrused == 0? 1<> 16; + m_rle_code = BMP_RGB; + + if( m_width > 0 && m_height != 0 && + (m_bpp == 1 || m_bpp == 4 || m_bpp == 8 || + m_bpp == 24 || m_bpp == 32 )) + { + if( m_bpp <= 8 ) + { + uchar buffer[256*3]; + int j, clrused = 1 << m_bpp; + m_strm.getBytes( buffer, clrused*3 ); + for( j = 0; j < clrused; j++ ) + { + m_palette[j].b = buffer[3*j+0]; + m_palette[j].g = buffer[3*j+1]; + m_palette[j].r = buffer[3*j+2]; + } + } + result = true; + } + } + } + catch(...) + { + } + + m_type = iscolor ? CV_8UC3 : CV_8UC1; + m_origin = m_height > 0 ? IPL_ORIGIN_BL : IPL_ORIGIN_TL; + m_height = std::abs(m_height); + + if( !result ) + { + m_offset = -1; + m_width = m_height = -1; + m_strm.close(); + } + return result; +} + + +bool BmpDecoder::readData( Mat& img ) +{ + uchar* data = img.data; + int step = (int)img.step; + bool color = img.channels() > 1; + uchar gray_palette[256]; + bool result = false; + int src_pitch = ((m_width*(m_bpp != 15 ? m_bpp : 16) + 7)/8 + 3) & -4; + int nch = color ? 3 : 1; + int y, width3 = m_width*nch; + + if( m_offset < 0 || !m_strm.isOpened()) + return false; + + if( m_origin == IPL_ORIGIN_BL ) + { + data += (m_height - 1)*step; + step = -step; + } + + AutoBuffer _src, _bgr; + _src.allocate(src_pitch + 32); + + if( !color ) + { + if( m_bpp <= 8 ) + { + CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp ); + } + _bgr.allocate(m_width*3 + 32); + } + uchar *src = _src, *bgr = _bgr; + + try + { + m_strm.setPos( m_offset ); + + switch( m_bpp ) + { + /************************* 1 BPP ************************/ + case 1: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + FillColorRow1( color ? data : bgr, src, m_width, m_palette ); + if( !color ) + icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1) ); + } + result = true; + break; + + /************************* 4 BPP ************************/ + case 4: + if( m_rle_code == BMP_RGB ) + { + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( color ) + FillColorRow4( data, src, m_width, m_palette ); + else + FillGrayRow4( data, src, m_width, gray_palette ); + } + result = true; + } + else if( m_rle_code == BMP_RLE4 ) // rle4 compression + { + uchar* line_end = data + width3; + y = 0; + + for(;;) + { + int code = m_strm.getWord(); + int len = code & 255; + code >>= 8; + if( len != 0 ) // encoded mode + { + PaletteEntry clr[2]; + uchar gray_clr[2]; + int t = 0; + + clr[0] = m_palette[code >> 4]; + clr[1] = m_palette[code & 15]; + gray_clr[0] = gray_palette[code >> 4]; + gray_clr[1] = gray_palette[code & 15]; + + uchar* end = data + len*nch; + if( end > line_end ) goto decode_rle4_bad; + do + { + if( color ) + WRITE_PIX( data, clr[t] ); + else + *data = gray_clr[t]; + t ^= 1; + } + while( (data += nch) < end ); + } + else if( code > 2 ) // absolute mode + { + if( data + code*nch > line_end ) goto decode_rle4_bad; + m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 ); + if( color ) + data = FillColorRow4( data, src, code, m_palette ); + else + data = FillGrayRow4( data, src, code, gray_palette ); + } + else + { + int x_shift3 = (int)(line_end - data); + int y_shift = m_height - y; + + if( code == 2 ) + { + x_shift3 = m_strm.getByte()*nch; + y_shift = m_strm.getByte(); + } + + len = x_shift3 + ((y_shift * width3) & ((code == 0) - 1)); + + if( color ) + data = FillUniColor( data, line_end, step, width3, + y, m_height, x_shift3, + m_palette[0] ); + else + data = FillUniGray( data, line_end, step, width3, + y, m_height, x_shift3, + gray_palette[0] ); + + if( y >= m_height ) + break; + } + } + + result = true; +decode_rle4_bad: ; + } + break; + + /************************* 8 BPP ************************/ + case 8: + if( m_rle_code == BMP_RGB ) + { + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( color ) + FillColorRow8( data, src, m_width, m_palette ); + else + FillGrayRow8( data, src, m_width, gray_palette ); + } + result = true; + } + else if( m_rle_code == BMP_RLE8 ) // rle8 compression + { + uchar* line_end = data + width3; + int line_end_flag = 0; + y = 0; + + for(;;) + { + int code = m_strm.getWord(); + int len = code & 255; + code >>= 8; + if( len != 0 ) // encoded mode + { + int prev_y = y; + len *= nch; + + if( data + len > line_end ) + goto decode_rle8_bad; + + if( color ) + data = FillUniColor( data, line_end, step, width3, + y, m_height, len, + m_palette[code] ); + else + data = FillUniGray( data, line_end, step, width3, + y, m_height, len, + gray_palette[code] ); + + line_end_flag = y - prev_y; + } + else if( code > 2 ) // absolute mode + { + int prev_y = y; + int code3 = code*nch; + + if( data + code3 > line_end ) + goto decode_rle8_bad; + m_strm.getBytes( src, (code + 1) & -2 ); + if( color ) + data = FillColorRow8( data, src, code, m_palette ); + else + data = FillGrayRow8( data, src, code, gray_palette ); + + line_end_flag = y - prev_y; + } + else + { + int x_shift3 = (int)(line_end - data); + int y_shift = m_height - y; + + if( code || !line_end_flag || x_shift3 < width3 ) + { + if( code == 2 ) + { + x_shift3 = m_strm.getByte()*nch; + y_shift = m_strm.getByte(); + } + + x_shift3 += (y_shift * width3) & ((code == 0) - 1); + + if( y >= m_height ) + break; + + if( color ) + data = FillUniColor( data, line_end, step, width3, + y, m_height, x_shift3, + m_palette[0] ); + else + data = FillUniGray( data, line_end, step, width3, + y, m_height, x_shift3, + gray_palette[0] ); + + if( y >= m_height ) + break; + } + + line_end_flag = 0; + if( y >= m_height ) + break; + } + } + + result = true; +decode_rle8_bad: ; + } + break; + /************************* 15 BPP ************************/ + case 15: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( !color ) + icvCvt_BGR5552Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) ); + else + icvCvt_BGR5552BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) ); + } + result = true; + break; + /************************* 16 BPP ************************/ + case 16: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( !color ) + icvCvt_BGR5652Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) ); + else + icvCvt_BGR5652BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) ); + } + result = true; + break; + /************************* 24 BPP ************************/ + case 24: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if(!color) + icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1) ); + else + memcpy( data, src, m_width*3 ); + } + result = true; + break; + /************************* 32 BPP ************************/ + case 32: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + + if( !color ) + icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1) ); + else + icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1) ); + } + result = true; + break; + default: + assert(0); + } + } + catch(...) + { + } + + return result; +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +BmpEncoder::BmpEncoder() +{ + m_description = "Windows bitmap (*.bmp;*.dib)"; + m_buf_supported = true; +} + + +BmpEncoder::~BmpEncoder() +{ +} + +ImageEncoder BmpEncoder::newEncoder() const +{ + return new BmpEncoder; +} + +bool BmpEncoder::write( const Mat& img, const vector& ) +{ + int width = img.cols, height = img.rows, channels = img.channels(); + int fileStep = (width*channels + 3) & -4; + uchar zeropad[] = "\0\0\0\0"; + WLByteStream strm; + + if( m_buf ) + { + if( !strm.open( *m_buf ) ) + return false; + } + else if( !strm.open( m_filename )) + return false; + + int bitmapHeaderSize = 40; + int paletteSize = channels > 1 ? 0 : 1024; + int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize; + int fileSize = fileStep*height + headerSize; + PaletteEntry palette[256]; + + if( m_buf ) + m_buf->reserve( alignSize(fileSize + 16, 256) ); + + // write signature 'BM' + strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) ); + + // write file header + strm.putDWord( fileSize ); // file size + strm.putDWord( 0 ); + strm.putDWord( headerSize ); + + // write bitmap header + strm.putDWord( bitmapHeaderSize ); + strm.putDWord( width ); + strm.putDWord( height ); + strm.putWord( 1 ); + strm.putWord( channels << 3 ); + strm.putDWord( BMP_RGB ); + strm.putDWord( 0 ); + strm.putDWord( 0 ); + strm.putDWord( 0 ); + strm.putDWord( 0 ); + strm.putDWord( 0 ); + + if( channels == 1 ) + { + FillGrayPalette( palette, 8 ); + strm.putBytes( palette, sizeof(palette)); + } + + width *= channels; + for( int y = height - 1; y >= 0; y-- ) + { + strm.putBytes( img.data + img.step*y, width ); + if( fileStep > width ) + strm.putBytes( zeropad, fileStep - width ); + } + + strm.close(); + return true; +} + +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_bmp.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_bmp.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_bmp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_bmp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,99 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_BMP_H_ +#define _GRFMT_BMP_H_ + +#include "grfmt_base.hpp" + +namespace cv +{ + +enum BmpCompression +{ + BMP_RGB = 0, + BMP_RLE8 = 1, + BMP_RLE4 = 2, + BMP_BITFIELDS = 3 +}; + + +// Windows Bitmap reader +class BmpDecoder : public BaseImageDecoder +{ +public: + + BmpDecoder(); + ~BmpDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + ImageDecoder newDecoder() const; + +protected: + + RLByteStream m_strm; + PaletteEntry m_palette[256]; + int m_origin; + int m_bpp; + int m_offset; + BmpCompression m_rle_code; +}; + + +// ... writer +class BmpEncoder : public BaseImageEncoder +{ +public: + BmpEncoder(); + ~BmpEncoder(); + + bool write( const Mat& img, const vector& params ); + + ImageEncoder newEncoder() const; +}; + +} + +#endif/*_GRFMT_BMP_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_exr.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_exr.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_exr.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_exr.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,741 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_OPENEXR + +#if defined _MSC_VER && _MSC_VER >= 1200 +# pragma warning( disable: 4100 4244 4267 ) +#endif + +#if defined __GNUC__ && defined __APPLE__ +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#include +#include +#include +#include +#include +#include +#include "grfmt_exr.hpp" + +#if defined _WIN32 + +#undef UINT +#define UINT ((Imf::PixelType)0) +#undef HALF +#define HALF ((Imf::PixelType)1) +#undef FLOAT +#define FLOAT ((Imf::PixelType)2) + +#endif + +namespace cv +{ + +/////////////////////// ExrDecoder /////////////////// + +ExrDecoder::ExrDecoder() +{ + m_signature = "\x76\x2f\x31\x01"; + m_file = 0; + m_red = m_green = m_blue = 0; +} + + +ExrDecoder::~ExrDecoder() +{ + close(); +} + + +void ExrDecoder::close() +{ + if( m_file ) + { + delete m_file; + m_file = 0; + } +} + + +int ExrDecoder::type() const +{ + return CV_MAKETYPE((m_isfloat ? CV_32F : CV_32S), m_iscolor ? 3 : 1); +} + + +bool ExrDecoder::readHeader() +{ + bool result = false; + + m_file = new InputFile( m_filename.c_str() ); + + if( !m_file ) // probably paranoid + return false; + + m_datawindow = m_file->header().dataWindow(); + m_width = m_datawindow.max.x - m_datawindow.min.x + 1; + m_height = m_datawindow.max.y - m_datawindow.min.y + 1; + + // the type HALF is converted to 32 bit float + // and the other types supported by OpenEXR are 32 bit anyway + m_bit_depth = 32; + + if( hasChromaticities( m_file->header() )) + m_chroma = chromaticities( m_file->header() ); + + const ChannelList &channels = m_file->header().channels(); + m_red = channels.findChannel( "R" ); + m_green = channels.findChannel( "G" ); + m_blue = channels.findChannel( "B" ); + if( m_red || m_green || m_blue ) + { + m_iscolor = true; + m_ischroma = false; + result = true; + } + else + { + m_green = channels.findChannel( "Y" ); + if( m_green ) + { + m_ischroma = true; + m_red = channels.findChannel( "RY" ); + m_blue = channels.findChannel( "BY" ); + m_iscolor = (m_blue || m_red); + result = true; + } + else + result = false; + } + + if( result ) + { + int uintcnt = 0; + int chcnt = 0; + if( m_red ) + { + chcnt++; + uintcnt += ( m_red->type == UINT ); + } + if( m_green ) + { + chcnt++; + uintcnt += ( m_green->type == UINT ); + } + if( m_blue ) + { + chcnt++; + uintcnt += ( m_blue->type == UINT ); + } + m_type = (chcnt == uintcnt) ? UINT : FLOAT; + + m_isfloat = (m_type == FLOAT); + } + + if( !result ) + close(); + + return result; +} + + +bool ExrDecoder::readData( Mat& img ) +{ + m_native_depth = CV_MAT_DEPTH(type()) == img.depth(); + bool color = img.channels() > 1; + + uchar* data = img.data; + int step = img.step; + bool justcopy = m_native_depth; + bool chromatorgb = false; + bool rgbtogray = false; + bool result = true; + FrameBuffer frame; + int xsample[3] = {1, 1, 1}; + char *buffer; + int xstep; + int ystep; + + xstep = m_native_depth ? 4 : 1; + + if( !m_native_depth || (!color && m_iscolor )) + { + buffer = (char *)new float[ m_width * 3 ]; + ystep = 0; + } + else + { + buffer = (char *)data; + ystep = step; + } + + if( m_ischroma ) + { + if( color ) + { + if( m_iscolor ) + { + if( m_blue ) + { + frame.insert( "BY", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, + 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 )); + xsample[0] = m_blue->ySampling; + } + if( m_green ) + { + frame.insert( "Y", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, + 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + xsample[1] = m_green->ySampling; + } + if( m_red ) + { + frame.insert( "RY", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, + 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 )); + xsample[2] = m_red->ySampling; + } + chromatorgb = true; + } + else + { + frame.insert( "Y", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, + 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + frame.insert( "Y", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, + 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + frame.insert( "Y", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, + 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + xsample[0] = m_green->ySampling; + xsample[1] = m_green->ySampling; + xsample[2] = m_green->ySampling; + } + } + else + { + frame.insert( "Y", Slice( m_type, + buffer - m_datawindow.min.x * 4 - m_datawindow.min.y * ystep, + 4, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + xsample[0] = m_green->ySampling; + } + } + else + { + if( m_blue ) + { + frame.insert( "B", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, + 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 )); + xsample[0] = m_blue->ySampling; + } + if( m_green ) + { + frame.insert( "G", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, + 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); + xsample[1] = m_green->ySampling; + } + if( m_red ) + { + frame.insert( "R", Slice( m_type, + buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, + 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 )); + xsample[2] = m_red->ySampling; + } + if(color == 0) + { + rgbtogray = true; + justcopy = false; + } + } + + m_file->setFrameBuffer( frame ); + if( justcopy ) + { + m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y ); + + if( color ) + { + if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) ) + UpSample( data, 3, step / xstep, xsample[0], m_blue->ySampling ); + if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) + UpSample( data + xstep, 3, step / xstep, xsample[1], m_green->ySampling ); + if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) ) + UpSample( data + 2 * xstep, 3, step / xstep, xsample[2], m_red->ySampling ); + } + else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) + UpSample( data, 1, step / xstep, xsample[0], m_green->ySampling ); + } + else + { + uchar *out = data; + int x, y; + for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ ) + { + m_file->readPixels( y, y ); + + if( rgbtogray ) + { + if( xsample[0] != 1 ) + UpSampleX( (float *)buffer, 3, xsample[0] ); + if( xsample[1] != 1 ) + UpSampleX( (float *)buffer + 4, 3, xsample[1] ); + if( xsample[2] != 1 ) + UpSampleX( (float *)buffer + 8, 3, xsample[2] ); + + RGBToGray( (float *)buffer, (float *)out ); + } + else + { + if( xsample[0] != 1 ) + UpSampleX( (float *)buffer, 3, xsample[0] ); + if( xsample[1] != 1 ) + UpSampleX( (float *)(buffer + 4), 3, xsample[1] ); + if( xsample[2] != 1 ) + UpSampleX( (float *)(buffer + 8), 3, xsample[2] ); + + if( chromatorgb ) + ChromaToBGR( (float *)buffer, 1, step ); + + if( m_type == FLOAT ) + { + float *fi = (float *)buffer; + for( x = 0; x < m_width * 3; x++) + { + int t = cvRound(fi[x]*5); + out[x] = CV_CAST_8U(t); + } + } + else + { + unsigned *ui = (unsigned *)buffer; + for( x = 0; x < m_width * 3; x++) + { + unsigned t = ui[x]; + out[x] = CV_CAST_8U(t); + } + } + } + + out += step; + } + if( color ) + { + if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) ) + UpSampleY( data, 3, step / xstep, m_blue->ySampling ); + if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) + UpSampleY( data + xstep, 3, step / xstep, m_green->ySampling ); + if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) ) + UpSampleY( data + 2 * xstep, 3, step / xstep, m_red->ySampling ); + } + else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) + UpSampleY( data, 1, step / xstep, m_green->ySampling ); + } + + if( chromatorgb ) + ChromaToBGR( (float *)data, m_height, step / xstep ); + + close(); + + return result; +} + +/** +// on entry pixel values are stored packed in the upper left corner of the image +// this functions expands them by duplication to cover the whole image + */ +void ExrDecoder::UpSample( uchar *data, int xstep, int ystep, int xsample, int ysample ) +{ + for( int y = (m_height - 1) / ysample, yre = m_height - ysample; y >= 0; y--, yre -= ysample ) + { + for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample ) + { + for( int i = 0; i < ysample; i++ ) + { + for( int n = 0; n < xsample; n++ ) + { + if( !m_native_depth ) + data[(yre + i) * ystep + (xre + n) * xstep] = data[y * ystep + x * xstep]; + else if( m_type == FLOAT ) + ((float *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((float *)data)[y * ystep + x * xstep]; + else + ((unsigned *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((unsigned *)data)[y * ystep + x * xstep]; + } + } + } + } +} + +/** +// on entry pixel values are stored packed in the upper left corner of the image +// this functions expands them by duplication to cover the whole image + */ +void ExrDecoder::UpSampleX( float *data, int xstep, int xsample ) +{ + for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample ) + { + for( int n = 0; n < xsample; n++ ) + { + if( m_type == FLOAT ) + ((float *)data)[(xre + n) * xstep] = ((float *)data)[x * xstep]; + else + ((unsigned *)data)[(xre + n) * xstep] = ((unsigned *)data)[x * xstep]; + } + } +} + +/** +// on entry pixel values are stored packed in the upper left corner of the image +// this functions expands them by duplication to cover the whole image + */ +void ExrDecoder::UpSampleY( uchar *data, int xstep, int ystep, int ysample ) +{ + for( int y = m_height - ysample, yre = m_height - ysample; y >= 0; y -= ysample, yre -= ysample ) + { + for( int x = 0; x < m_width; x++ ) + { + for( int i = 1; i < ysample; i++ ) + { + if( !m_native_depth ) + data[(yre + i) * ystep + x * xstep] = data[y * ystep + x * xstep]; + else if( m_type == FLOAT ) + ((float *)data)[(yre + i) * ystep + x * xstep] = ((float *)data)[y * ystep + x * xstep]; + else + ((unsigned *)data)[(yre + i) * ystep + x * xstep] = ((unsigned *)data)[y * ystep + x * xstep]; + } + } + } +} + +/** +// algorithm from ImfRgbaYca.cpp + */ +void ExrDecoder::ChromaToBGR( float *data, int numlines, int step ) +{ + for( int y = 0; y < numlines; y++ ) + { + for( int x = 0; x < m_width; x++ ) + { + double b, Y, r; + if( !m_native_depth ) + { + b = ((uchar *)data)[y * step + x * 3]; + Y = ((uchar *)data)[y * step + x * 3 + 1]; + r = ((uchar *)data)[y * step + x * 3 + 2]; + } + else if( m_type == FLOAT ) + { + b = data[y * step + x * 3]; + Y = data[y * step + x * 3 + 1]; + r = data[y * step + x * 3 + 2]; + } + else + { + b = ((unsigned *)data)[y * step + x * 3]; + Y = ((unsigned *)data)[y * step + x * 3 + 1]; + r = ((unsigned *)data)[y * step + x * 3 + 2]; + } + r = (r + 1) * Y; + b = (b + 1) * Y; + Y = (Y - b * m_chroma.blue[1] - r * m_chroma.red[1]) / m_chroma.green[1]; + + if( !m_native_depth ) + { + int t = cvRound(b); + ((uchar *)data)[y * step + x * 3] = CV_CAST_8U(t); + t = cvRound(Y); + ((uchar *)data)[y * step + x * 3 + 1] = CV_CAST_8U(t); + t = cvRound(r); + ((uchar *)data)[y * step + x * 3 + 2] = CV_CAST_8U(t); + } + else if( m_type == FLOAT ) + { + data[y * step + x * 3] = (float)b; + data[y * step + x * 3 + 1] = (float)Y; + data[y * step + x * 3 + 2] = (float)r; + } + else + { + int t = cvRound(b); + ((unsigned *)data)[y * step + x * 3] = (unsigned)MAX(t,0); + t = cvRound(Y); + ((unsigned *)data)[y * step + x * 3 + 1] = (unsigned)MAX(t,0); + t = cvRound(r); + ((unsigned *)data)[y * step + x * 3 + 2] = (unsigned)MAX(t,0); + } + } + } +} + + +/** +// convert one row to gray +*/ +void ExrDecoder::RGBToGray( float *in, float *out ) +{ + if( m_type == FLOAT ) + { + if( m_native_depth ) + { + for( int i = 0, n = 0; i < m_width; i++, n += 3 ) + out[i] = in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0]; + } + else + { + uchar *o = (uchar *)out; + for( int i = 0, n = 0; i < m_width; i++, n += 3 ) + o[i] = (uchar) (in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0]); + } + } + else // UINT + { + if( m_native_depth ) + { + unsigned *ui = (unsigned *)in; + for( int i = 0; i < m_width * 3; i++ ) + ui[i] -= 0x80000000; + int *si = (int *)in; + for( int i = 0, n = 0; i < m_width; i++, n += 3 ) + ((int *)out)[i] = int(si[n] * m_chroma.blue[0] + si[n + 1] * m_chroma.green[0] + si[n + 2] * m_chroma.red[0]); + } + else // how to best convert float to uchar? + { + unsigned *ui = (unsigned *)in; + for( int i = 0, n = 0; i < m_width; i++, n += 3 ) + ((uchar *)out)[i] = uchar((ui[n] * m_chroma.blue[0] + ui[n + 1] * m_chroma.green[0] + ui[n + 2] * m_chroma.red[0]) * (256.0 / 4294967296.0)); + } + } +} + + +ImageDecoder ExrDecoder::newDecoder() const +{ + return new ExrDecoder; +} + +/////////////////////// ExrEncoder /////////////////// + + +ExrEncoder::ExrEncoder() +{ + m_description = "OpenEXR Image files (*.exr)"; +} + + +ExrEncoder::~ExrEncoder() +{ +} + + +bool ExrEncoder::isFormatSupported( int depth ) const +{ + return CV_MAT_DEPTH(depth) >= CV_8U && CV_MAT_DEPTH(depth) < CV_64F; +} + + +// TODO scale appropriately +bool ExrEncoder::write( const Mat& img, const vector& ) +{ + int width = img.cols, height = img.rows; + int depth = img.depth(), channels = img.channels(); + bool result = false; + bool issigned = depth == CV_8S || depth == CV_16S || depth == CV_32S; + bool isfloat = depth == CV_32F || depth == CV_64F; + depth = CV_ELEM_SIZE1(depth)*8; + uchar* data = img.data; + int step = img.step; + + Header header( width, height ); + Imf::PixelType type; + + if(depth == 8) + type = HALF; + else if(isfloat) + type = FLOAT; + else + type = UINT; + + if( channels == 3 ) + { + header.channels().insert( "R", Channel( type )); + header.channels().insert( "G", Channel( type )); + header.channels().insert( "B", Channel( type )); + //printf("bunt\n"); + } + else + { + header.channels().insert( "Y", Channel( type )); + //printf("gray\n"); + } + + OutputFile file( m_filename.c_str(), header ); + + FrameBuffer frame; + + char *buffer; + int bufferstep; + int size; + if( type == FLOAT && depth == 32 ) + { + buffer = (char *)const_cast(data); + bufferstep = step; + size = 4; + } + else if( depth > 16 || type == UINT ) + { + buffer = (char *)new unsigned[width * channels]; + bufferstep = 0; + size = 4; + } + else + { + buffer = (char *)new half[width * channels]; + bufferstep = 0; + size = 2; + } + + //printf("depth %d %s\n", depth, types[type]); + + if( channels == 3 ) + { + frame.insert( "B", Slice( type, buffer, size * 3, bufferstep )); + frame.insert( "G", Slice( type, buffer + size, size * 3, bufferstep )); + frame.insert( "R", Slice( type, buffer + size * 2, size * 3, bufferstep )); + } + else + frame.insert( "Y", Slice( type, buffer, size, bufferstep )); + + file.setFrameBuffer( frame ); + + int offset = issigned ? 1 << (depth - 1) : 0; + + result = true; + if( type == FLOAT && depth == 32 ) + { + try + { + file.writePixels( height ); + } + catch(...) + { + result = false; + } + } + else + { + // int scale = 1 << (32 - depth); + // printf("scale %d\n", scale); + for(int line = 0; line < height; line++) + { + if(type == UINT) + { + unsigned *buf = (unsigned*)buffer; // FIXME 64-bit problems + + if( depth <= 8 ) + { + for(int i = 0; i < width * channels; i++) + buf[i] = data[i] + offset; + } + else if( depth <= 16 ) + { + unsigned short *sd = (unsigned short *)data; + for(int i = 0; i < width * channels; i++) + buf[i] = sd[i] + offset; + } + else + { + int *sd = (int *)data; // FIXME 64-bit problems + for(int i = 0; i < width * channels; i++) + buf[i] = (unsigned) sd[i] + offset; + } + } + else + { + half *buf = (half *)buffer; + + if( depth <= 8 ) + { + for(int i = 0; i < width * channels; i++) + buf[i] = data[i]; + } + else if( depth <= 16 ) + { + unsigned short *sd = (unsigned short *)data; + for(int i = 0; i < width * channels; i++) + buf[i] = sd[i]; + } + } + try + { + file.writePixels( 1 ); + } + catch(...) + { + result = false; + break; + } + data += step; + } + delete[] buffer; + } + + return result; +} + + +ImageEncoder ExrEncoder::newEncoder() const +{ + return new ExrEncoder; +} + +} + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_exr.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_exr.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_exr.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_exr.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,117 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_EXR_H_ +#define _GRFMT_EXR_H_ + +#ifdef HAVE_OPENEXR + +#if defined __GNUC__ && defined __APPLE__ +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#include +#include +#include +#include +#include "grfmt_base.hpp" + +namespace cv +{ + +using namespace Imf; +using namespace Imath; + +/* libpng version only */ + +class ExrDecoder : public BaseImageDecoder +{ +public: + + ExrDecoder(); + ~ExrDecoder(); + + int type() const; + bool readData( Mat& img ); + bool readHeader(); + void close(); + + ImageDecoder newDecoder() const; + +protected: + void UpSample( uchar *data, int xstep, int ystep, int xsample, int ysample ); + void UpSampleX( float *data, int xstep, int xsample ); + void UpSampleY( uchar *data, int xstep, int ystep, int ysample ); + void ChromaToBGR( float *data, int numlines, int step ); + void RGBToGray( float *in, float *out ); + + InputFile *m_file; + Imf::PixelType m_type; + Box2i m_datawindow; + bool m_ischroma; + const Channel *m_red; + const Channel *m_green; + const Channel *m_blue; + Chromaticities m_chroma; + int m_bit_depth; + bool m_native_depth; + bool m_iscolor; + bool m_isfloat; +}; + + +class ExrEncoder : public BaseImageEncoder +{ +public: + ExrEncoder(); + ~ExrEncoder(); + + bool isFormatSupported( int depth ) const; + bool write( const Mat& img, const vector& params ); + ImageEncoder newEncoder() const; +}; + +} + +#endif + +#endif/*_GRFMT_EXR_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_imageio.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_imageio.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_imageio.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_imageio.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,396 @@ +/* + * grfmt_imageio.cpp + * + * + * Created by Morgan Conbere on 5/17/07. + * + */ + +#include "precomp.hpp" + +#ifdef HAVE_IMAGEIO + +#include "grfmt_imageio.hpp" + +namespace cv +{ + +/////////////////////// ImageIODecoder /////////////////// + +ImageIODecoder::ImageIODecoder() +{ + imageRef = NULL; +} + +ImageIODecoder::~ImageIODecoder() +{ + close(); +} + + +void ImageIODecoder::close() +{ + CGImageRelease( imageRef ); + imageRef = NULL; +} + + +size_t ImageIODecoder::signatureLength() const +{ + return 12; +} + +bool ImageIODecoder::checkSignature( const string& signature ) const +{ + // TODO: implement real signature check + return true; +} + +ImageDecoder ImageIODecoder::newDecoder() const +{ + return new ImageIODecoder; +} + +bool ImageIODecoder::readHeader() +{ + CFURLRef imageURLRef; + CGImageSourceRef sourceRef; + // diciu, if ReadHeader is called twice in a row make sure to release the previously allocated imageRef + if (imageRef != NULL) + CGImageRelease(imageRef); + imageRef = NULL; + + imageURLRef = CFURLCreateFromFileSystemRepresentation( NULL, + (const UInt8*)m_filename.c_str(), m_filename.size(), false ); + + sourceRef = CGImageSourceCreateWithURL( imageURLRef, NULL ); + CFRelease( imageURLRef ); + if ( !sourceRef ) + return false; + + imageRef = CGImageSourceCreateImageAtIndex( sourceRef, 0, NULL ); + CFRelease( sourceRef ); + if( !imageRef ) + return false; + + m_width = CGImageGetWidth( imageRef ); + m_height = CGImageGetHeight( imageRef ); + + CGColorSpaceRef colorSpace = CGImageGetColorSpace( imageRef ); + if( !colorSpace ) + return false; + + m_type = CGColorSpaceGetNumberOfComponents( colorSpace ) > 1 ? CV_8UC3 : CV_8UC1; + + return true; +} + + +bool ImageIODecoder::readData( Mat& img ) +{ + uchar* data = img.data; + int step = img.step; + bool color = img.channels() > 1; + int bpp; // Bytes per pixel + int bit_depth = 8; + + // Get Height, Width, and color information + if( !readHeader() ) + return false; + + CGContextRef context = NULL; // The bitmap context + CGColorSpaceRef colorSpace = NULL; + uchar* bitmap = NULL; + CGImageAlphaInfo alphaInfo; + + // CoreGraphics will take care of converting to grayscale and back as long as the + // appropriate colorspace is set + if( color == CV_LOAD_IMAGE_GRAYSCALE ) + { + colorSpace = CGColorSpaceCreateDeviceGray(); + bpp = 1; + alphaInfo = kCGImageAlphaNone; + } + else if( color == CV_LOAD_IMAGE_COLOR ) + { +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + colorSpace = CGColorSpaceCreateDeviceRGB(); +#else + colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear ); +#endif + bpp = 4; /* CG only has 8 and 32 bit color spaces, so we waste a byte */ + alphaInfo = kCGImageAlphaNoneSkipLast; + } + if( !colorSpace ) + return false; + + bitmap = (uchar*)malloc( bpp * m_height * m_width ); + if( !bitmap ) + { + CGColorSpaceRelease( colorSpace ); + return false; + } + + context = CGBitmapContextCreate( (void *)bitmap, + m_width, /* width */ + m_height, /* height */ + bit_depth, /* bit depth */ + bpp * m_width, /* bytes per row */ + colorSpace, /* color space */ + alphaInfo); + + CGColorSpaceRelease( colorSpace ); + if( !context ) + { + free( bitmap ); + return false; + } + + // Copy the image data into the bitmap region + CGRect rect = {{0,0},{m_width,m_height}}; + CGContextDrawImage( context, rect, imageRef ); + + uchar* bitdata = (uchar*)CGBitmapContextGetData( context ); + if( !bitdata ) + { + free( bitmap); + CGContextRelease( context ); + return false; + } + + // Move the bitmap (in RGB) into data (in BGR) + int bitmapIndex = 0; + + if( color == CV_LOAD_IMAGE_COLOR ) + { + uchar * base = data; + + for (int y = 0; y < m_height; y++) + { + uchar * line = base + y * step; + + for (int x = 0; x < m_width; x++) + { + // Blue channel + line[0] = bitdata[bitmapIndex + 2]; + // Green channel + line[1] = bitdata[bitmapIndex + 1]; + // Red channel + line[2] = bitdata[bitmapIndex + 0]; + + line += 3; + bitmapIndex += bpp; + } + } + } + else if( color == CV_LOAD_IMAGE_GRAYSCALE ) + { + for (int y = 0; y < m_height; y++) + memcpy (data + y * step, bitmap + y * m_width, m_width); + } + + free( bitmap ); + CGContextRelease( context ); + return true; +} + + +/////////////////////// ImageIOEncoder /////////////////// + +ImageIOEncoder::ImageIOEncoder() +{ + m_description = "Apple ImageIO (*.bmp;*.dib;*.exr;*.jpeg;*.jpg;*.jpe;*.jp2;*.pdf;*.png;*.tiff;*.tif)"; +} + + +ImageIOEncoder::~ImageIOEncoder() +{ +} + + +ImageEncoder ImageIOEncoder::newEncoder() const +{ + return new ImageIOEncoder; +} + +static +CFStringRef FilenameToUTI( const char* filename ) +{ + const char* ext = filename; + char* ext_buf; + int i; + CFStringRef imageUTI = NULL; + + for(;;) + { + const char* temp = strchr( ext + 1, '.' ); + if( !temp ) break; + ext = temp; + } + + if(!ext) + return NULL; + + ext_buf = (char*)malloc(strlen(ext)+1); + for(i = 0; ext[i] != '\0'; i++) + ext_buf[i] = (char)tolower(ext[i]); + ext_buf[i] = '\0'; + ext = ext_buf; + + if( !strcmp(ext, ".bmp") || !strcmp(ext, ".dib") ) + imageUTI = CFSTR( "com.microsoft.bmp" ); + else if( !strcmp(ext, ".exr") ) + imageUTI = CFSTR( "com.ilm.openexr-image" ); + else if( !strcmp(ext, ".jpeg") || !strcmp(ext, ".jpg") || !strcmp(ext, ".jpe") ) + imageUTI = CFSTR( "public.jpeg" ); + else if( !strcmp(ext, ".jp2") ) + imageUTI = CFSTR( "public.jpeg-2000" ); + else if( !strcmp(ext, ".pdf") ) + imageUTI = CFSTR( "com.adobe.pdf" ); + else if( !strcmp(ext, ".png") ) + imageUTI = CFSTR( "public.png" ); + else if( !strcmp(ext, ".tiff") || !strcmp(ext, ".tif") ) + imageUTI = CFSTR( "public.tiff" ); + + free(ext_buf); + + return imageUTI; +} + + +bool ImageIOEncoder::write( const Mat& img, const vector& params ) +{ + int width = img.cols, height = img.rows; + int _channels = img.channels(); + const uchar* data = img.data; + int step = img.step; + + // Determine the appropriate UTI based on the filename extension + CFStringRef imageUTI = FilenameToUTI( m_filename.c_str() ); + + // Determine the Bytes Per Pixel + int bpp = (_channels == 1) ? 1 : 4; + + // Write the data into a bitmap context + CGContextRef context; + CGColorSpaceRef colorSpace; + uchar* bitmapData = NULL; + + if( bpp == 1 ) { +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + colorSpace = CGColorSpaceCreateDeviceGray(); +#else + colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericGray ); +#endif + } + else if( bpp == 4 ) { +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + colorSpace = CGColorSpaceCreateDeviceRGB(); +#else + colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear ); +#endif + } + if( !colorSpace ) + return false; + + bitmapData = (uchar*)malloc( bpp * height * width ); + if( !bitmapData ) + { + CGColorSpaceRelease( colorSpace ); + return false; + } + + context = CGBitmapContextCreate( bitmapData, + width, + height, + 8, + bpp * width, + colorSpace, + (bpp == 1) ? kCGImageAlphaNone : + kCGImageAlphaNoneSkipLast ); + CGColorSpaceRelease( colorSpace ); + if( !context ) + { + free( bitmapData ); + return false; + } + + // Copy pixel information from data into bitmapData + if (bpp == 4) + { + int bitmapIndex = 0; + const uchar * base = data; + + for (int y = 0; y < height; y++) + { + const uchar * line = base + y * step; + + for (int x = 0; x < width; x++) + { + // Blue channel + bitmapData[bitmapIndex + 2] = line[0]; + // Green channel + bitmapData[bitmapIndex + 1] = line[1]; + // Red channel + bitmapData[bitmapIndex + 0] = line[2]; + + line += 3; + bitmapIndex += bpp; + } + } + } + else if (bpp == 1) + { + for (int y = 0; y < height; y++) + memcpy (bitmapData + y * width, data + y * step, width); + } + + // Turn the bitmap context into an imageRef + CGImageRef imageRef = CGBitmapContextCreateImage( context ); + CGContextRelease( context ); + if( !imageRef ) + { + free( bitmapData ); + return false; + } + + // Write the imageRef to a file based on the UTI + CFURLRef imageURLRef = CFURLCreateFromFileSystemRepresentation( NULL, + (const UInt8*)m_filename.c_str(), m_filename.size(), false ); + if( !imageURLRef ) + { + CGImageRelease( imageRef ); + free( bitmapData ); + return false; + } + + CGImageDestinationRef destRef = CGImageDestinationCreateWithURL( imageURLRef, + imageUTI, + 1, + NULL); + CFRelease( imageURLRef ); + if( !destRef ) + { + CGImageRelease( imageRef ); + free( bitmapData ); + fprintf(stderr, "!destRef\n"); + return false; + } + + CGImageDestinationAddImage(destRef, imageRef, NULL); + if( !CGImageDestinationFinalize(destRef) ) + { + fprintf(stderr, "Finalize failed\n"); + return false; + } + + CFRelease( destRef ); + CGImageRelease( imageRef ); + free( bitmapData ); + + return true; +} + +} + +#endif /* HAVE_IMAGEIO */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_imageio.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_imageio.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_imageio.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_imageio.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,67 @@ +/* + * grfmt_imageio.h + * + * + * Created by Morgan Conbere on 5/17/07. + * + */ + +#ifndef _GRFMT_IMAGEIO_H_ +#define _GRFMT_IMAGEIO_H_ + +#ifdef HAVE_IMAGEIO + +#include "grfmt_base.hpp" +#include + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + +#include +#include + +#else + +#include + +#endif + +namespace cv +{ + +class ImageIODecoder : public BaseImageDecoder +{ +public: + + ImageIODecoder(); + ~ImageIODecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + size_t signatureLength() const; + bool checkSignature( const string& signature ) const; + + ImageDecoder newDecoder() const; + +protected: + + CGImageRef imageRef; +}; + +class ImageIOEncoder : public BaseImageEncoder +{ +public: + ImageIOEncoder(); + ~ImageIOEncoder(); + + bool write( const Mat& img, const vector& params ); + + ImageEncoder newEncoder() const; +}; + +} + +#endif/*HAVE_IMAGEIO*/ + +#endif/*_GRFMT_IMAGEIO_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,655 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "grfmt_jpeg.hpp" + +#ifdef HAVE_JPEG + +#ifdef _MSC_VER +//interaction between '_setjmp' and C++ object destruction is non-portable +#pragma warning(disable: 4611) +#endif + +#include +#include + +#ifdef WIN32 + +#define XMD_H // prevent redefinition of INT32 +#undef FAR // prevent FAR redefinition + +#endif + +#if defined WIN32 && defined __GNUC__ +typedef unsigned char boolean; +#endif + +#undef FALSE +#undef TRUE + +extern "C" { +#include "jpeglib.h" +} + +namespace cv +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4324) //structure was padded due to __declspec(align()) +#endif +struct JpegErrorMgr +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +struct JpegSource +{ + struct jpeg_source_mgr pub; + int skip; +}; + +struct JpegState +{ + jpeg_decompress_struct cinfo; // IJG JPEG codec structure + JpegErrorMgr jerr; // error processing manager state + JpegSource source; // memory buffer source +}; + +/////////////////////// Error processing ///////////////////// + +METHODDEF(void) +stub(j_decompress_ptr) +{ +} + +METHODDEF(boolean) +fill_input_buffer(j_decompress_ptr) +{ + return FALSE; +} + +// emulating memory input stream + +METHODDEF(void) +skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + JpegSource* source = (JpegSource*) cinfo->src; + + if( num_bytes > (long)source->pub.bytes_in_buffer ) + { + // We need to skip more data than we have in the buffer. + // This will force the JPEG library to suspend decoding. + source->skip = (int)(num_bytes - source->pub.bytes_in_buffer); + source->pub.next_input_byte += source->pub.bytes_in_buffer; + source->pub.bytes_in_buffer = 0; + } + else + { + // Skip portion of the buffer + source->pub.bytes_in_buffer -= num_bytes; + source->pub.next_input_byte += num_bytes; + source->skip = 0; + } +} + + +static void jpeg_buffer_src(j_decompress_ptr cinfo, JpegSource* source) +{ + cinfo->src = &source->pub; + + // Prepare for suspending reader + source->pub.init_source = stub; + source->pub.fill_input_buffer = fill_input_buffer; + source->pub.skip_input_data = skip_input_data; + source->pub.resync_to_restart = jpeg_resync_to_restart; + source->pub.term_source = stub; + source->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read + + source->skip = 0; +} + + +METHODDEF(void) +error_exit( j_common_ptr cinfo ) +{ + JpegErrorMgr* err_mgr = (JpegErrorMgr*)(cinfo->err); + + /* Return control to the setjmp point */ + longjmp( err_mgr->setjmp_buffer, 1 ); +} + + +/////////////////////// JpegDecoder /////////////////// + + +JpegDecoder::JpegDecoder() +{ + m_signature = "\xFF\xD8\xFF"; + m_state = 0; + m_f = 0; + m_buf_supported = true; +} + + +JpegDecoder::~JpegDecoder() +{ + close(); +} + + +void JpegDecoder::close() +{ + if( m_state ) + { + JpegState* state = (JpegState*)m_state; + jpeg_destroy_decompress( &state->cinfo ); + delete state; + m_state = 0; + } + + if( m_f ) + { + fclose( m_f ); + m_f = 0; + } + + m_width = m_height = 0; + m_type = -1; +} + +ImageDecoder JpegDecoder::newDecoder() const +{ + return new JpegDecoder; +} + +bool JpegDecoder::readHeader() +{ + bool result = false; + close(); + + JpegState* state = new JpegState; + m_state = state; + state->cinfo.err = jpeg_std_error(&state->jerr.pub); + state->jerr.pub.error_exit = error_exit; + + if( setjmp( state->jerr.setjmp_buffer ) == 0 ) + { + jpeg_create_decompress( &state->cinfo ); + + if( !m_buf.empty() ) + { + jpeg_buffer_src(&state->cinfo, &state->source); + state->source.pub.next_input_byte = m_buf.data; + state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize(); + } + else + { + m_f = fopen( m_filename.c_str(), "rb" ); + if( m_f ) + jpeg_stdio_src( &state->cinfo, m_f ); + } + + if (state->cinfo.src != 0) + { + jpeg_read_header( &state->cinfo, TRUE ); + + m_width = state->cinfo.image_width; + m_height = state->cinfo.image_height; + m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1; + result = true; + } + } + + if( !result ) + close(); + + return result; +} + +/*************************************************************************** + * following code is for supporting MJPEG image files + * based on a message of Laurent Pinchart on the video4linux mailing list + ***************************************************************************/ + +/* JPEG DHT Segment for YCrCb omitted from MJPEG data */ +static +unsigned char my_jpeg_odml_dht[0x1a4] = { + 0xff, 0xc4, 0x01, 0xa2, + + 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + + 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + + 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, + 0x04, 0x00, 0x00, 0x01, 0x7d, + 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, + + 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, + 0x04, 0x00, 0x01, 0x02, 0x77, + 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 +}; + +/* + * Parse the DHT table. + * This code comes from jpeg6b (jdmarker.c). + */ +static +int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht, + JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[]) +{ + unsigned int length = (dht[2] << 8) + dht[3] - 2; + unsigned int pos = 4; + unsigned int count, i; + int index; + + JHUFF_TBL **hufftbl; + unsigned char bits[17]; + unsigned char huffval[256]; + + while (length > 16) + { + bits[0] = 0; + index = dht[pos++]; + count = 0; + for (i = 1; i <= 16; ++i) + { + bits[i] = dht[pos++]; + count += bits[i]; + } + length -= 17; + + if (count > 256 || count > length) + return -1; + + for (i = 0; i < count; ++i) + huffval[i] = dht[pos++]; + length -= count; + + if (index & 0x10) + { + index -= 0x10; + hufftbl = &ac_tables[index]; + } + else + hufftbl = &dc_tables[index]; + + if (index < 0 || index >= NUM_HUFF_TBLS) + return -1; + + if (*hufftbl == NULL) + *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info); + if (*hufftbl == NULL) + return -1; + + memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits); + memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval); + } + + if (length != 0) + return -1; + + return 0; +} + +/*************************************************************************** + * end of code for supportting MJPEG image files + * based on a message of Laurent Pinchart on the video4linux mailing list + ***************************************************************************/ + +bool JpegDecoder::readData( Mat& img ) +{ + bool result = false; + int step = (int)img.step; + bool color = img.channels() > 1; + + if( m_state && m_width && m_height ) + { + jpeg_decompress_struct* cinfo = &((JpegState*)m_state)->cinfo; + JpegErrorMgr* jerr = &((JpegState*)m_state)->jerr; + JSAMPARRAY buffer = 0; + + if( setjmp( jerr->setjmp_buffer ) == 0 ) + { + /* check if this is a mjpeg image format */ + if ( cinfo->ac_huff_tbl_ptrs[0] == NULL && + cinfo->ac_huff_tbl_ptrs[1] == NULL && + cinfo->dc_huff_tbl_ptrs[0] == NULL && + cinfo->dc_huff_tbl_ptrs[1] == NULL ) + { + /* yes, this is a mjpeg image format, so load the correct + huffman table */ + my_jpeg_load_dht( cinfo, + my_jpeg_odml_dht, + cinfo->ac_huff_tbl_ptrs, + cinfo->dc_huff_tbl_ptrs ); + } + + if( color ) + { + if( cinfo->num_components != 4 ) + { + cinfo->out_color_space = JCS_RGB; + cinfo->out_color_components = 3; + } + else + { + cinfo->out_color_space = JCS_CMYK; + cinfo->out_color_components = 4; + } + } + else + { + if( cinfo->num_components != 4 ) + { + cinfo->out_color_space = JCS_GRAYSCALE; + cinfo->out_color_components = 1; + } + else + { + cinfo->out_color_space = JCS_CMYK; + cinfo->out_color_components = 4; + } + } + + jpeg_start_decompress( cinfo ); + + buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, + JPOOL_IMAGE, m_width*4, 1 ); + + uchar* data = img.data; + for( ; m_height--; data += step ) + { + jpeg_read_scanlines( cinfo, buffer, 1 ); + if( color ) + { + if( cinfo->out_color_components == 3 ) + icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, cvSize(m_width,1) ); + else + icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, cvSize(m_width,1) ); + } + else + { + if( cinfo->out_color_components == 1 ) + memcpy( data, buffer[0], m_width ); + else + icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, cvSize(m_width,1) ); + } + } + result = true; + jpeg_finish_decompress( cinfo ); + } + } + + close(); + return result; +} + + +/////////////////////// JpegEncoder /////////////////// + +struct JpegDestination +{ + struct jpeg_destination_mgr pub; + vector *buf, *dst; +}; + +METHODDEF(void) +stub(j_compress_ptr) +{ +} + +METHODDEF(void) +term_destination (j_compress_ptr cinfo) +{ + JpegDestination* dest = (JpegDestination*)cinfo->dest; + size_t sz = dest->dst->size(), bufsz = dest->buf->size() - dest->pub.free_in_buffer; + if( bufsz > 0 ) + { + dest->dst->resize(sz + bufsz); + memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz); + } +} + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + JpegDestination* dest = (JpegDestination*)cinfo->dest; + size_t sz = dest->dst->size(), bufsz = dest->buf->size(); + dest->dst->resize(sz + bufsz); + memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz); + + dest->pub.next_output_byte = &(*dest->buf)[0]; + dest->pub.free_in_buffer = bufsz; + return TRUE; +} + +static void jpeg_buffer_dest(j_compress_ptr cinfo, JpegDestination* destination) +{ + cinfo->dest = &destination->pub; + + destination->pub.init_destination = stub; + destination->pub.empty_output_buffer = empty_output_buffer; + destination->pub.term_destination = term_destination; +} + + +JpegEncoder::JpegEncoder() +{ + m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)"; + m_buf_supported = true; +} + + +JpegEncoder::~JpegEncoder() +{ +} + +ImageEncoder JpegEncoder::newEncoder() const +{ + return new JpegEncoder; +} + +bool JpegEncoder::write( const Mat& img, const vector& params ) +{ + m_last_error.clear(); + + struct fileWrapper + { + FILE* f; + + fileWrapper() : f(0) {} + ~fileWrapper() { if(f) fclose(f); } + }; + bool result = false; + fileWrapper fw; + int width = img.cols, height = img.rows; + + vector out_buf(1 << 12); + AutoBuffer _buffer; + uchar* buffer; + + struct jpeg_compress_struct cinfo; + JpegErrorMgr jerr; + JpegDestination dest; + + jpeg_create_compress(&cinfo); + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = error_exit; + + if( !m_buf ) + { + fw.f = fopen( m_filename.c_str(), "wb" ); + if( !fw.f ) + goto _exit_; + jpeg_stdio_dest( &cinfo, fw.f ); + } + else + { + dest.dst = m_buf; + dest.buf = &out_buf; + + jpeg_buffer_dest( &cinfo, &dest ); + + dest.pub.next_output_byte = &out_buf[0]; + dest.pub.free_in_buffer = out_buf.size(); + } + + if( setjmp( jerr.setjmp_buffer ) == 0 ) + { + cinfo.image_width = width; + cinfo.image_height = height; + + int _channels = img.channels(); + int channels = _channels > 1 ? 3 : 1; + cinfo.input_components = channels; + cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE; + + int quality = 95; + + for( size_t i = 0; i < params.size(); i += 2 ) + { + if( params[i] == CV_IMWRITE_JPEG_QUALITY ) + { + quality = params[i+1]; + quality = MIN(MAX(quality, 0), 100); + } + } + + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, quality, + TRUE /* limit to baseline-JPEG values */ ); + jpeg_start_compress( &cinfo, TRUE ); + + if( channels > 1 ) + _buffer.allocate(width*channels); + buffer = _buffer; + + for( int y = 0; y < height; y++ ) + { + uchar *data = img.data + img.step*y, *ptr = data; + + if( _channels == 3 ) + { + icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) ); + ptr = buffer; + } + else if( _channels == 4 ) + { + icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, cvSize(width,1), 2 ); + ptr = buffer; + } + + jpeg_write_scanlines( &cinfo, &ptr, 1 ); + } + + jpeg_finish_compress( &cinfo ); + result = true; + } + +_exit_: + + if(!result) + { + char jmsg_buf[JMSG_LENGTH_MAX]; + jerr.pub.format_message((j_common_ptr)&cinfo, jmsg_buf); + m_last_error = jmsg_buf; + } + + jpeg_destroy_compress( &cinfo ); + + return result; +} + +} + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,90 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_JPEG_H_ +#define _GRFMT_JPEG_H_ + +#include "grfmt_base.hpp" +#include "bitstrm.hpp" + +#ifdef HAVE_JPEG + +// IJG-based Jpeg codec + +namespace cv +{ + +class JpegDecoder : public BaseImageDecoder +{ +public: + + JpegDecoder(); + virtual ~JpegDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + ImageDecoder newDecoder() const; + +protected: + + FILE* m_f; + void* m_state; +}; + + +class JpegEncoder : public BaseImageEncoder +{ +public: + JpegEncoder(); + virtual ~JpegEncoder(); + + bool write( const Mat& img, const vector& params ); + ImageEncoder newEncoder() const; +}; + +} + +#endif + +#endif/*_GRFMT_JPEG_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,529 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_JASPER + +#include "grfmt_jpeg2000.hpp" + +#ifdef WIN32 +#define JAS_WIN_MSVC_BUILD 1 +#ifdef __GNUC__ +#define HAVE_STDINT_H 1 +#endif +#endif + +#undef PACKAGE +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef VERSION + +#include +// FIXME bad hack +#undef uchar +#undef ulong + +namespace cv +{ + +struct JasperInitializer +{ + JasperInitializer() { jas_init(); } + ~JasperInitializer() { jas_cleanup(); } +}; + +static JasperInitializer initialize_jasper; + + +/////////////////////// Jpeg2KDecoder /////////////////// + +Jpeg2KDecoder::Jpeg2KDecoder() +{ + m_signature = '\0' + string() + '\0' + string() + '\0' + string("\x0cjP \r\n\x87\n"); + m_stream = 0; + m_image = 0; +} + + +Jpeg2KDecoder::~Jpeg2KDecoder() +{ +} + +ImageDecoder Jpeg2KDecoder::newDecoder() const +{ + return new Jpeg2KDecoder; +} + +void Jpeg2KDecoder::close() +{ + if( m_stream ) + { + jas_stream_close( (jas_stream_t*)m_stream ); + m_stream = 0; + } + + if( m_image ) + { + jas_image_destroy( (jas_image_t*)m_image ); + m_image = 0; + } +} + + +bool Jpeg2KDecoder::readHeader() +{ + bool result = false; + + close(); + jas_stream_t* stream = jas_stream_fopen( m_filename.c_str(), "rb" ); + m_stream = stream; + + if( stream ) + { + jas_image_t* image = jas_image_decode( stream, -1, 0 ); + m_image = image; + if( image ) { + m_width = jas_image_width( image ); + m_height = jas_image_height( image ); + + int cntcmpts = 0; // count the known components + int numcmpts = jas_image_numcmpts( image ); + int depth = 0; + for( int i = 0; i < numcmpts; i++ ) + { + int depth_i = jas_image_cmptprec( image, i ); + depth = MAX(depth, depth_i); + if( jas_image_cmpttype( image, i ) > 2 ) + continue; + cntcmpts++; + } + + if( cntcmpts ) + { + m_type = CV_MAKETYPE(depth <= 8 ? CV_8U : CV_16U, cntcmpts > 1 ? 3 : 1); + result = true; + } + } + } + + if( !result ) + close(); + + return result; +} + + +bool Jpeg2KDecoder::readData( Mat& img ) +{ + bool result = false; + int color = img.channels() > 1; + uchar* data = img.data; + int step = (int)img.step; + jas_stream_t* stream = (jas_stream_t*)m_stream; + jas_image_t* image = (jas_image_t*)m_image; + + if( stream && image ) + { + bool convert; + int colorspace; + if( color ) + { + convert = (jas_image_clrspc( image ) != JAS_CLRSPC_SRGB); + colorspace = JAS_CLRSPC_SRGB; + } + else + { + convert = (jas_clrspc_fam( jas_image_clrspc( image ) ) != JAS_CLRSPC_FAM_GRAY); + colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? + } + + // convert to the desired colorspace + if( convert ) + { + jas_cmprof_t *clrprof = jas_cmprof_createfromclrspc( colorspace ); + if( clrprof ) + { + jas_image_t *_img = jas_image_chclrspc( image, clrprof, JAS_CMXFORM_INTENT_RELCLR ); + if( _img ) + { + jas_image_destroy( image ); + m_image = image = _img; + result = true; + } + else + fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); + jas_cmprof_destroy( clrprof ); + } + else + fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); + } + else + result = true; + + if( result ) + { + int ncmpts; + int cmptlut[3]; + if( color ) + { + cmptlut[0] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_B ); + cmptlut[1] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_G ); + cmptlut[2] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_R ); + if( cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[2] < 0 ) + result = false; + ncmpts = 3; + } + else + { + cmptlut[0] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_GRAY_Y ); + if( cmptlut[0] < 0 ) + result = false; + ncmpts = 1; + } + + if( result ) + { + for( int i = 0; i < ncmpts; i++ ) + { + int maxval = 1 << jas_image_cmptprec( image, cmptlut[i] ); + int offset = jas_image_cmptsgnd( image, cmptlut[i] ) ? maxval / 2 : 0; + + int yend = jas_image_cmptbry( image, cmptlut[i] ); + int ystep = jas_image_cmptvstep( image, cmptlut[i] ); + int xend = jas_image_cmptbrx( image, cmptlut[i] ); + int xstep = jas_image_cmpthstep( image, cmptlut[i] ); + + jas_matrix_t *buffer = jas_matrix_create( yend / ystep, xend / xstep ); + if( buffer ) + { + if( !jas_image_readcmpt( image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer )) + { + if( img.depth() == CV_8U ) + result = readComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts ); + else + result = readComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts ); + if( !result ) + { + i = ncmpts; + result = false; + } + } + jas_matrix_destroy( buffer ); + } + } + } + } + else + fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" ); + } + + close(); + + return result; +} + + +bool Jpeg2KDecoder::readComponent8u( uchar *data, void *_buffer, + int step, int cmpt, + int maxval, int offset, int ncmpts ) +{ + jas_matrix_t* buffer = (jas_matrix_t*)_buffer; + jas_image_t* image = (jas_image_t*)m_image; + int xstart = jas_image_cmpttlx( image, cmpt ); + int xend = jas_image_cmptbrx( image, cmpt ); + int xstep = jas_image_cmpthstep( image, cmpt ); + int xoffset = jas_image_tlx( image ); + int ystart = jas_image_cmpttly( image, cmpt ); + int yend = jas_image_cmptbry( image, cmpt ); + int ystep = jas_image_cmptvstep( image, cmpt ); + int yoffset = jas_image_tly( image ); + int x, y, x1, y1, j; + int rshift = cvRound(std::log(maxval/256.)/std::log(2.)); + int lshift = MAX(0, -rshift); + rshift = MAX(0, rshift); + int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset; + + for( y = 0; y < yend - ystart; ) + { + jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); + uchar* dst = data + (y - yoffset) * step - xoffset; + + if( xstep == 1 ) + { + if( maxval == 256 && offset == 0 ) + for( x = 0; x < xend - xstart; x++ ) + { + int pix = pix_row[x]; + dst[x*ncmpts] = CV_CAST_8U(pix); + } + else + for( x = 0; x < xend - xstart; x++ ) + { + int pix = ((pix_row[x] + delta) >> rshift) << lshift; + dst[x*ncmpts] = CV_CAST_8U(pix); + } + } + else if( xstep == 2 && offset == 0 ) + for( x = 0, j = 0; x < xend - xstart; x += 2, j++ ) + { + int pix = ((pix_row[j] + delta) >> rshift) << lshift; + dst[x*ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_8U(pix); + } + else + for( x = 0, j = 0; x < xend - xstart; j++ ) + { + int pix = ((pix_row[j] + delta) >> rshift) << lshift; + pix = CV_CAST_8U(pix); + for( x1 = x + xstep; x < x1; x++ ) + dst[x*ncmpts] = (uchar)pix; + } + y1 = y + ystep; + for( ++y; y < y1; y++, dst += step ) + for( x = 0; x < xend - xstart; x++ ) + dst[x*ncmpts + step] = dst[x*ncmpts]; + } + + return true; +} + + +bool Jpeg2KDecoder::readComponent16u( unsigned short *data, void *_buffer, + int step, int cmpt, + int maxval, int offset, int ncmpts ) +{ + jas_matrix_t* buffer = (jas_matrix_t*)_buffer; + jas_image_t* image = (jas_image_t*)m_image; + int xstart = jas_image_cmpttlx( image, cmpt ); + int xend = jas_image_cmptbrx( image, cmpt ); + int xstep = jas_image_cmpthstep( image, cmpt ); + int xoffset = jas_image_tlx( image ); + int ystart = jas_image_cmpttly( image, cmpt ); + int yend = jas_image_cmptbry( image, cmpt ); + int ystep = jas_image_cmptvstep( image, cmpt ); + int yoffset = jas_image_tly( image ); + int x, y, x1, y1, j; + int rshift = cvRound(std::log(maxval/65536.)/std::log(2.)); + int lshift = MAX(0, -rshift); + rshift = MAX(0, rshift); + int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset; + + for( y = 0; y < yend - ystart; ) + { + jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); + ushort* dst = data + (y - yoffset) * step - xoffset; + + if( xstep == 1 ) + { + if( maxval == 65536 && offset == 0 ) + for( x = 0; x < xend - xstart; x++ ) + { + int pix = pix_row[x]; + dst[x*ncmpts] = CV_CAST_16U(pix); + } + else + for( x = 0; x < xend - xstart; x++ ) + { + int pix = ((pix_row[x] + delta) >> rshift) << lshift; + dst[x*ncmpts] = CV_CAST_16U(pix); + } + } + else if( xstep == 2 && offset == 0 ) + for( x = 0, j = 0; x < xend - xstart; x += 2, j++ ) + { + int pix = ((pix_row[j] + delta) >> rshift) << lshift; + dst[x*ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_16U(pix); + } + else + for( x = 0, j = 0; x < xend - xstart; j++ ) + { + int pix = ((pix_row[j] + delta) >> rshift) << lshift; + pix = CV_CAST_16U(pix); + for( x1 = x + xstep; x < x1; x++ ) + dst[x*ncmpts] = (ushort)pix; + } + y1 = y + ystep; + for( ++y; y < y1; y++, dst += step ) + for( x = 0; x < xend - xstart; x++ ) + dst[x*ncmpts + step] = dst[x*ncmpts]; + } + + return true; +} + + +/////////////////////// Jpeg2KEncoder /////////////////// + + +Jpeg2KEncoder::Jpeg2KEncoder() +{ + m_description = "JPEG-2000 files (*.jp2)"; +} + + +Jpeg2KEncoder::~Jpeg2KEncoder() +{ +} + +ImageEncoder Jpeg2KEncoder::newEncoder() const +{ + return new Jpeg2KEncoder; +} + +bool Jpeg2KEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U || depth == CV_16U; +} + + +bool Jpeg2KEncoder::write( const Mat& _img, const vector& ) +{ + int width = _img.cols, height = _img.rows; + int depth = _img.depth(), channels = _img.channels(); + depth = depth == CV_8U ? 8 : 16; + + if( channels > 3 || channels < 1 ) + return false; + + jas_image_cmptparm_t component_info[3]; + for( int i = 0; i < channels; i++ ) + { + component_info[i].tlx = 0; + component_info[i].tly = 0; + component_info[i].hstep = 1; + component_info[i].vstep = 1; + component_info[i].width = width; + component_info[i].height = height; + component_info[i].prec = depth; + component_info[i].sgnd = 0; + } + jas_image_t *img = jas_image_create( channels, component_info, (channels == 1) ? JAS_CLRSPC_SGRAY : JAS_CLRSPC_SRGB ); + if( !img ) + return false; + + if(channels == 1) + jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_GRAY_Y ); + else + { + jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_RGB_B ); + jas_image_setcmpttype( img, 1, JAS_IMAGE_CT_RGB_G ); + jas_image_setcmpttype( img, 2, JAS_IMAGE_CT_RGB_R ); + } + + bool result; + if( depth == 8 ) + result = writeComponent8u( img, _img ); + else + result = writeComponent16u( img, _img ); + if( result ) + { + jas_stream_t *stream = jas_stream_fopen( m_filename.c_str(), "wb" ); + if( stream ) + { + result = !jas_image_encode( img, stream, jas_image_strtofmt( (char*)"jp2" ), (char*)"" ); + + jas_stream_close( stream ); + } + + } + jas_image_destroy( img ); + + return result; +} + + +bool Jpeg2KEncoder::writeComponent8u( void *__img, const Mat& _img ) +{ + jas_image_t* img = (jas_image_t*)__img; + int w = _img.cols, h = _img.rows, ncmpts = _img.channels(); + jas_matrix_t *row = jas_matrix_create( 1, w ); + if(!row) + return false; + + for( int y = 0; y < h; y++ ) + { + uchar* data = _img.data + _img.step*y; + for( int i = 0; i < ncmpts; i++ ) + { + for( int x = 0; x < w; x++) + jas_matrix_setv( row, x, data[x * ncmpts + i] ); + jas_image_writecmpt( img, i, 0, y, w, 1, row ); + } + } + + jas_matrix_destroy( row ); + return true; +} + + +bool Jpeg2KEncoder::writeComponent16u( void *__img, const Mat& _img ) +{ + jas_image_t* img = (jas_image_t*)__img; + int w = _img.cols, h = _img.rows, ncmpts = _img.channels(); + jas_matrix_t *row = jas_matrix_create( 1, w ); + if(!row) + return false; + + for( int y = 0; y < h; y++ ) + { + uchar* data = _img.data + _img.step*y; + for( int i = 0; i < ncmpts; i++ ) + { + for( int x = 0; x < w; x++) + jas_matrix_setv( row, x, data[x * ncmpts + i] ); + jas_image_writecmpt( img, i, 0, y, w, 1, row ); + } + } + + jas_matrix_destroy( row ); + + return true; +} + +} + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_jpeg2000.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,95 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_JASPER_H_ +#define _GRFMT_JASPER_H_ + +#ifdef HAVE_JASPER + +#include "grfmt_base.hpp" + +namespace cv +{ + +class Jpeg2KDecoder : public BaseImageDecoder +{ +public: + + Jpeg2KDecoder(); + virtual ~Jpeg2KDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + ImageDecoder newDecoder() const; + +protected: + bool readComponent8u( uchar *data, void *buffer, int step, int cmpt, + int maxval, int offset, int ncmpts ); + bool readComponent16u( unsigned short *data, void *buffer, int step, int cmpt, + int maxval, int offset, int ncmpts ); + + void *m_stream; + void *m_image; +}; + + +class Jpeg2KEncoder : public BaseImageEncoder +{ +public: + Jpeg2KEncoder(); + virtual ~Jpeg2KEncoder(); + + bool isFormatSupported( int depth ) const; + bool write( const Mat& img, const vector& params ); + ImageEncoder newEncoder() const; + +protected: + bool writeComponent8u( void *img, const Mat& _img ); + bool writeComponent16u( void *img, const Mat& _img ); +}; + +} + +#endif + +#endif/*_GRFMT_JASPER_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_png.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_png.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_png.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_png.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,435 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_PNG + +/****************************************************************************************\ + This part of the file implements PNG codec on base of libpng library, + in particular, this code is based on example.c from libpng + (see otherlibs/_graphics/readme.txt for copyright notice) + and png2bmp sample from libpng distribution (Copyright (C) 1999-2001 MIYASAKA Masaru) +\****************************************************************************************/ + +#undef HAVE_UNISTD_H //to avoid redefinition +#ifndef _LFS64_LARGEFILE +# define _LFS64_LARGEFILE 0 +#endif +#ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 0 +#endif + +#ifdef HAVE_LIBPNG_PNG_H +#include +#else +#include +#endif +#include + +#include "grfmt_png.hpp" + +#if defined _MSC_VER && _MSC_VER >= 1200 + // interaction between '_setjmp' and C++ object destruction is non-portable + #pragma warning( disable: 4611 ) +#endif + +namespace cv +{ + +/////////////////////// PngDecoder /////////////////// + +PngDecoder::PngDecoder() +{ + m_signature = "\x89\x50\x4e\x47\xd\xa\x1a\xa"; + m_color_type = 0; + m_png_ptr = 0; + m_info_ptr = m_end_info = 0; + m_f = 0; + m_buf_supported = true; + m_buf_pos = 0; +} + + +PngDecoder::~PngDecoder() +{ + close(); +} + +ImageDecoder PngDecoder::newDecoder() const +{ + return new PngDecoder; +} + +void PngDecoder::close() +{ + if( m_f ) + { + fclose( m_f ); + m_f = 0; + } + + if( m_png_ptr ) + { + png_structp png_ptr = (png_structp)m_png_ptr; + png_infop info_ptr = (png_infop)m_info_ptr; + png_infop end_info = (png_infop)m_end_info; + png_destroy_read_struct( &png_ptr, &info_ptr, &end_info ); + m_png_ptr = m_info_ptr = m_end_info = 0; + } +} + + +void PngDecoder::readDataFromBuf( void* _png_ptr, uchar* dst, size_t size ) +{ + png_structp png_ptr = (png_structp)_png_ptr; + PngDecoder* decoder = (PngDecoder*)(png_get_io_ptr(png_ptr)); + CV_Assert( decoder ); + const Mat& buf = decoder->m_buf; + if( decoder->m_buf_pos + size > buf.cols*buf.rows*buf.elemSize() ) + { + png_error(png_ptr, "PNG input buffer is incomplete"); + return; + } + memcpy( dst, &decoder->m_buf.data[decoder->m_buf_pos], size ); + decoder->m_buf_pos += size; +} + +bool PngDecoder::readHeader() +{ + bool result = false; + close(); + + png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + + if( png_ptr ) + { + png_infop info_ptr = png_create_info_struct( png_ptr ); + png_infop end_info = png_create_info_struct( png_ptr ); + + m_png_ptr = png_ptr; + m_info_ptr = info_ptr; + m_end_info = end_info; + m_buf_pos = 0; + + if( info_ptr && end_info ) + { + if( setjmp( png_jmpbuf( png_ptr ) ) == 0 ) + { + if( !m_buf.empty() ) + png_set_read_fn(png_ptr, this, (png_rw_ptr)readDataFromBuf ); + else + { + m_f = fopen( m_filename.c_str(), "rb" ); + if( m_f ) + png_init_io( png_ptr, m_f ); + } + + if( !m_buf.empty() || m_f ) + { + png_uint_32 wdth, hght; + int bit_depth, color_type; + + png_read_info( png_ptr, info_ptr ); + + png_get_IHDR( png_ptr, info_ptr, &wdth, &hght, + &bit_depth, &color_type, 0, 0, 0 ); + + m_width = (int)wdth; + m_height = (int)hght; + m_color_type = color_type; + m_bit_depth = bit_depth; + + if( bit_depth <= 8 || bit_depth == 16 ) + { + switch(color_type) + { + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_PALETTE: + m_type = CV_8UC3; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + m_type = CV_8UC4; + break; + default: + m_type = CV_8UC1; + } + if( bit_depth == 16 ) + m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type)); + result = true; + } + } + } + } + } + + if( !result ) + close(); + + return result; +} + + +bool PngDecoder::readData( Mat& img ) +{ + bool result = false; + AutoBuffer _buffer(m_height); + uchar** buffer = _buffer; + int color = img.channels() > 1; + uchar* data = img.data; + int step = (int)img.step; + + if( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height ) + { + png_structp png_ptr = (png_structp)m_png_ptr; + png_infop info_ptr = (png_infop)m_info_ptr; + png_infop end_info = (png_infop)m_end_info; + + if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 ) + { + int y; + + if( img.depth() == CV_8U && m_bit_depth == 16 ) + png_set_strip_16( png_ptr ); + else if( !isBigEndian() ) + png_set_swap( png_ptr ); + + if(img.channels() < 4) + { + /* observation: png_read_image() writes 400 bytes beyond + * end of data when reading a 400x118 color png + * "mpplus_sand.png". OpenCV crashes even with demo + * programs. Looking at the loaded image I'd say we get 4 + * bytes per pixel instead of 3 bytes per pixel. Test + * indicate that it is a good idea to always ask for + * stripping alpha.. 18.11.2004 Axel Walthelm + */ + png_set_strip_alpha( png_ptr ); + } + + if( m_color_type == PNG_COLOR_TYPE_PALETTE ) + png_set_palette_to_rgb( png_ptr ); + + if( m_color_type == PNG_COLOR_TYPE_GRAY && m_bit_depth < 8 ) +#if (PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE >= 10209) || \ + (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR == 0 && PNG_LIBPNG_VER_RELEASE >= 18) + png_set_expand_gray_1_2_4_to_8( png_ptr ); +#else + png_set_gray_1_2_4_to_8( png_ptr ); +#endif + + if( CV_MAT_CN(m_type) > 1 && color ) + png_set_bgr( png_ptr ); // convert RGB to BGR + else if( color ) + png_set_gray_to_rgb( png_ptr ); // Gray->RGB + else + png_set_rgb_to_gray( png_ptr, 1, 0.299, 0.587 ); // RGB->Gray + + png_read_update_info( png_ptr, info_ptr ); + + for( y = 0; y < m_height; y++ ) + buffer[y] = data + y*step; + + png_read_image( png_ptr, buffer ); + png_read_end( png_ptr, end_info ); + + result = true; + } + } + + close(); + return result; +} + + +/////////////////////// PngEncoder /////////////////// + + +PngEncoder::PngEncoder() +{ + m_description = "Portable Network Graphics files (*.png)"; + m_buf_supported = true; +} + + +PngEncoder::~PngEncoder() +{ +} + + +bool PngEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U || depth == CV_16U; +} + +ImageEncoder PngEncoder::newEncoder() const +{ + return new PngEncoder; +} + + +void PngEncoder::writeDataToBuf(void* _png_ptr, uchar* src, size_t size) +{ + if( size == 0 ) + return; + png_structp png_ptr = (png_structp)_png_ptr; + PngEncoder* encoder = (PngEncoder*)(png_get_io_ptr(png_ptr)); + CV_Assert( encoder && encoder->m_buf ); + size_t cursz = encoder->m_buf->size(); + encoder->m_buf->resize(cursz + size); + memcpy( &(*encoder->m_buf)[cursz], src, size ); +} + + +void PngEncoder::flushBuf(void*) +{ +} + +bool PngEncoder::write( const Mat& img, const vector& params ) +{ + png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + png_infop info_ptr = 0; + FILE* f = 0; + int y, width = img.cols, height = img.rows; + int depth = img.depth(), channels = img.channels(); + bool result = false; + AutoBuffer buffer; + + if( depth != CV_8U && depth != CV_16U ) + return false; + + if( png_ptr ) + { + info_ptr = png_create_info_struct( png_ptr ); + + if( info_ptr ) + { + if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 ) + { + if( m_buf ) + { + png_set_write_fn(png_ptr, this, + (png_rw_ptr)writeDataToBuf, (png_flush_ptr)flushBuf); + } + else + { + f = fopen( m_filename.c_str(), "wb" ); + if( f ) + png_init_io( png_ptr, f ); + } + + int compression_level = -1; // Invalid value to allow setting 0-9 as valid + int compression_strategy = Z_RLE; // Default strategy + bool isBilevel = false; + + for( size_t i = 0; i < params.size(); i += 2 ) + { + if( params[i] == CV_IMWRITE_PNG_COMPRESSION ) + { + compression_level = params[i+1]; + compression_level = MIN(MAX(compression_level, 0), Z_BEST_COMPRESSION); + } + if( params[i] == CV_IMWRITE_PNG_STRATEGY ) + { + compression_strategy = params[i+1]; + compression_strategy = MIN(MAX(compression_strategy, 0), Z_FIXED); + } + if( params[i] == CV_IMWRITE_PNG_BILEVEL ) + { + isBilevel = params[i+1] != 0; + } + } + + if( m_buf || f ) + { + if( compression_level >= 0 ) + { + png_set_compression_level( png_ptr, compression_level ); + } + else + { + // tune parameters for speed + // (see http://wiki.linuxquestions.org/wiki/Libpng) + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB); + png_set_compression_level(png_ptr, Z_BEST_SPEED); + } + png_set_compression_strategy(png_ptr, compression_strategy); + + png_set_IHDR( png_ptr, info_ptr, width, height, depth == CV_8U ? isBilevel?1:8 : 16, + channels == 1 ? PNG_COLOR_TYPE_GRAY : + channels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT ); + + png_write_info( png_ptr, info_ptr ); + + if (isBilevel) + png_set_packing(png_ptr); + + png_set_bgr( png_ptr ); + if( !isBigEndian() ) + png_set_swap( png_ptr ); + + buffer.allocate(height); + for( y = 0; y < height; y++ ) + buffer[y] = img.data + y*img.step; + + png_write_image( png_ptr, buffer ); + png_write_end( png_ptr, info_ptr ); + + result = true; + } + } + } + } + + png_destroy_write_struct( &png_ptr, &info_ptr ); + if(f) fclose( f ); + + return result; +} + +} + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_png.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_png.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_png.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_png.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,101 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_PNG_H_ +#define _GRFMT_PNG_H_ + +#ifdef HAVE_PNG + +#include "grfmt_base.hpp" +#include "bitstrm.hpp" + +namespace cv +{ + +class PngDecoder : public BaseImageDecoder +{ +public: + + PngDecoder(); + virtual ~PngDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + ImageDecoder newDecoder() const; + +protected: + + static void readDataFromBuf(void* png_ptr, uchar* dst, size_t size); + + int m_bit_depth; + void* m_png_ptr; // pointer to decompression structure + void* m_info_ptr; // pointer to image information structure + void* m_end_info; // pointer to one more image information structure + FILE* m_f; + int m_color_type; + size_t m_buf_pos; +}; + + +class PngEncoder : public BaseImageEncoder +{ +public: + PngEncoder(); + virtual ~PngEncoder(); + + bool isFormatSupported( int depth ) const; + bool write( const Mat& img, const vector& params ); + + ImageEncoder newEncoder() const; + +protected: + static void writeDataToBuf(void* png_ptr, uchar* src, size_t size); + static void flushBuf(void* png_ptr); +}; + +} + +#endif + +#endif/*_GRFMT_PNG_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_pxm.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_pxm.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_pxm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_pxm.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,513 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "utils.hpp" +#include "grfmt_pxm.hpp" + +namespace cv +{ + +///////////////////////// P?M reader ////////////////////////////// + +static int ReadNumber( RLByteStream& strm, int maxdigits ) +{ + int code; + int val = 0; + int digits = 0; + + code = strm.getByte(); + + if( !isdigit(code)) + { + do + { + if( code == '#' ) + { + do + { + code = strm.getByte(); + } + while( code != '\n' && code != '\r' ); + } + + code = strm.getByte(); + + while( isspace(code)) + code = strm.getByte(); + } + while( !isdigit( code )); + } + + do + { + val = val*10 + code - '0'; + if( ++digits >= maxdigits ) break; + code = strm.getByte(); + } + while( isdigit(code)); + + return val; +} + + +PxMDecoder::PxMDecoder() +{ + m_offset = -1; + m_buf_supported = true; +} + + +PxMDecoder::~PxMDecoder() +{ + close(); +} + +size_t PxMDecoder::signatureLength() const +{ + return 3; +} + +bool PxMDecoder::checkSignature( const string& signature ) const +{ + return signature.size() >= 3 && signature[0] == 'P' && + '1' <= signature[1] && signature[1] <= '6' && + isspace(signature[2]); +} + +ImageDecoder PxMDecoder::newDecoder() const +{ + return new PxMDecoder; +} + +void PxMDecoder::close() +{ + m_strm.close(); +} + + +bool PxMDecoder::readHeader() +{ + bool result = false; + + if( !m_buf.empty() ) + { + if( !m_strm.open(m_buf) ) + return false; + } + else if( !m_strm.open( m_filename )) + return false; + + try + { + int code = m_strm.getByte(); + if( code != 'P' ) + throw RBS_BAD_HEADER; + + code = m_strm.getByte(); + switch( code ) + { + case '1': case '4': m_bpp = 1; break; + case '2': case '5': m_bpp = 8; break; + case '3': case '6': m_bpp = 24; break; + default: throw RBS_BAD_HEADER; + } + + m_binary = code >= '4'; + m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1; + + m_width = ReadNumber( m_strm, INT_MAX ); + m_height = ReadNumber( m_strm, INT_MAX ); + + m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX ); + if( m_maxval > 65535 ) + throw RBS_BAD_HEADER; + + //if( m_maxval > 255 ) m_binary = false; nonsense + if( m_maxval > 255 ) + m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type)); + + if( m_width > 0 && m_height > 0 && m_maxval > 0 && m_maxval < (1 << 16)) + { + m_offset = m_strm.getPos(); + result = true; + } + } + catch(...) + { + } + + if( !result ) + { + m_offset = -1; + m_width = m_height = -1; + m_strm.close(); + } + return result; +} + + +bool PxMDecoder::readData( Mat& img ) +{ + int color = img.channels() > 1; + uchar* data = img.data; + int step = (int)img.step; + PaletteEntry palette[256]; + bool result = false; + int bit_depth = CV_ELEM_SIZE1(m_type)*8; + int src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8; + int nch = CV_MAT_CN(m_type); + int width3 = m_width*nch; + int i, x, y; + + if( m_offset < 0 || !m_strm.isOpened()) + return false; + + AutoBuffer _src(src_pitch + 32); + uchar* src = _src; + AutoBuffer _gray_palette; + uchar* gray_palette = _gray_palette; + + // create LUT for converting colors + if( bit_depth == 8 ) + { + _gray_palette.allocate(m_maxval + 1); + gray_palette = _gray_palette; + + for( i = 0; i <= m_maxval; i++ ) + gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0)); + + FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 ); + } + + try + { + m_strm.setPos( m_offset ); + + switch( m_bpp ) + { + ////////////////////////// 1 BPP ///////////////////////// + case 1: + if( !m_binary ) + { + for( y = 0; y < m_height; y++, data += step ) + { + for( x = 0; x < m_width; x++ ) + src[x] = ReadNumber( m_strm, 1 ) != 0; + + if( color ) + FillColorRow8( data, src, m_width, palette ); + else + FillGrayRow8( data, src, m_width, gray_palette ); + } + } + else + { + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + + if( color ) + FillColorRow1( data, src, m_width, palette ); + else + FillGrayRow1( data, src, m_width, gray_palette ); + } + } + result = true; + break; + + ////////////////////////// 8 BPP ///////////////////////// + case 8: + case 24: + for( y = 0; y < m_height; y++, data += step ) + { + if( !m_binary ) + { + for( x = 0; x < width3; x++ ) + { + int code = ReadNumber( m_strm, INT_MAX ); + if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval; + if( bit_depth == 8 ) + src[x] = gray_palette[code]; + else + ((ushort *)src)[x] = (ushort)code; + } + } + else + { + m_strm.getBytes( src, src_pitch ); + if( bit_depth == 16 && !isBigEndian() ) + { + for( x = 0; x < width3; x++ ) + { + uchar v = src[x * 2]; + src[x * 2] = src[x * 2 + 1]; + src[x * 2 + 1] = v; + } + } + } + + if( img.depth() == CV_8U && bit_depth == 16 ) + { + for( x = 0; x < width3; x++ ) + { + int v = ((ushort *)src)[x]; + src[x] = (uchar)(v >> 8); + } + } + + if( m_bpp == 8 ) // image has one channel + { + if( color ) + { + if( img.depth() == CV_8U ) { + uchar *d = data, *s = src, *end = src + m_width; + for( ; s < end; d += 3, s++) + d[0] = d[1] = d[2] = *s; + } else { + ushort *d = (ushort *)data, *s = (ushort *)src, *end = ((ushort *)src) + m_width; + for( ; s < end; s++, d += 3) + d[0] = d[1] = d[2] = *s; + } + } + else + memcpy( data, src, m_width*(bit_depth/8) ); + } + else + { + if( color ) + { + if( img.depth() == CV_8U ) + icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, cvSize(m_width,1) ); + else + icvCvt_RGB2BGR_16u_C3R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1) ); + } + else if( img.depth() == CV_8U ) + icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 ); + else + icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1), 3, 2 ); + } + } + result = true; + break; + default: + assert(0); + } + } + catch(...) + { + } + + return result; +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +PxMEncoder::PxMEncoder() +{ + m_description = "Portable image format (*.pbm;*.pgm;*.ppm;*.pxm;*.pnm)"; + m_buf_supported = true; +} + + +PxMEncoder::~PxMEncoder() +{ +} + + +ImageEncoder PxMEncoder::newEncoder() const +{ + return new PxMEncoder; +} + + +bool PxMEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U || depth == CV_16U; +} + + +bool PxMEncoder::write( const Mat& img, const vector& params ) +{ + bool isBinary = true; + + int width = img.cols, height = img.rows; + int _channels = img.channels(), depth = (int)img.elemSize1()*8; + int channels = _channels > 1 ? 3 : 1; + int fileStep = width*(int)img.elemSize(); + int x, y; + + for( size_t i = 0; i < params.size(); i += 2 ) + if( params[i] == CV_IMWRITE_PXM_BINARY ) + isBinary = params[i+1] != 0; + + WLByteStream strm; + + if( m_buf ) + { + if( !strm.open(*m_buf) ) + return false; + int t = CV_MAKETYPE(img.depth(), channels); + m_buf->reserve( alignSize(256 + (isBinary ? fileStep*height : + ((t == CV_8UC1 ? 4 : t == CV_8UC3 ? 4*3+2 : + t == CV_16UC1 ? 6 : 6*3+2)*width+1)*height), 256)); + } + else if( !strm.open(m_filename) ) + return false; + + int lineLength; + int bufferSize = 128; // buffer that should fit a header + + if( isBinary ) + lineLength = width * (int)img.elemSize(); + else + lineLength = (6 * channels + (channels > 1 ? 2 : 0)) * width + 32; + + if( bufferSize < lineLength ) + bufferSize = lineLength; + + AutoBuffer _buffer(bufferSize); + char* buffer = _buffer; + + // write header; + sprintf( buffer, "P%c\n%d %d\n%d\n", + '2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0), + width, height, (1 << depth) - 1 ); + + strm.putBytes( buffer, (int)strlen(buffer) ); + + for( y = 0; y < height; y++ ) + { + uchar* data = img.data + img.step*y; + if( isBinary ) + { + if( _channels == 3 ) + { + if( depth == 8 ) + icvCvt_BGR2RGB_8u_C3R( (uchar*)data, 0, + (uchar*)buffer, 0, cvSize(width,1) ); + else + icvCvt_BGR2RGB_16u_C3R( (ushort*)data, 0, + (ushort*)buffer, 0, cvSize(width,1) ); + } + + // swap endianness if necessary + if( depth == 16 && !isBigEndian() ) + { + if( _channels == 1 ) + memcpy( buffer, data, fileStep ); + for( x = 0; x < width*channels*2; x += 2 ) + { + uchar v = buffer[x]; + buffer[x] = buffer[x + 1]; + buffer[x + 1] = v; + } + } + strm.putBytes( (channels > 1 || depth > 8) ? buffer : (char*)data, fileStep ); + } + else + { + char* ptr = buffer; + + if( channels > 1 ) + { + if( depth == 8 ) + { + for( x = 0; x < width*channels; x += channels ) + { + sprintf( ptr, "% 4d", data[x + 2] ); + ptr += 4; + sprintf( ptr, "% 4d", data[x + 1] ); + ptr += 4; + sprintf( ptr, "% 4d", data[x] ); + ptr += 4; + *ptr++ = ' '; + *ptr++ = ' '; + } + } + else + { + for( x = 0; x < width*channels; x += channels ) + { + sprintf( ptr, "% 6d", ((ushort *)data)[x + 2] ); + ptr += 6; + sprintf( ptr, "% 6d", ((ushort *)data)[x + 1] ); + ptr += 6; + sprintf( ptr, "% 6d", ((ushort *)data)[x] ); + ptr += 6; + *ptr++ = ' '; + *ptr++ = ' '; + } + } + } + else + { + if( depth == 8 ) + { + for( x = 0; x < width; x++ ) + { + sprintf( ptr, "% 4d", data[x] ); + ptr += 4; + } + } + else + { + for( x = 0; x < width; x++ ) + { + sprintf( ptr, "% 6d", ((ushort *)data)[x] ); + ptr += 6; + } + } + } + + *ptr++ = '\n'; + + strm.putBytes( buffer, (int)(ptr - buffer) ); + } + } + + strm.close(); + return true; +} + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_pxm.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_pxm.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_pxm.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_pxm.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,92 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_PxM_H_ +#define _GRFMT_PxM_H_ + +#include "grfmt_base.hpp" +#include "bitstrm.hpp" + +namespace cv +{ + +class PxMDecoder : public BaseImageDecoder +{ +public: + + PxMDecoder(); + virtual ~PxMDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + size_t signatureLength() const; + bool checkSignature( const string& signature ) const; + ImageDecoder newDecoder() const; + +protected: + + RLByteStream m_strm; + PaletteEntry m_palette[256]; + int m_bpp; + int m_offset; + bool m_binary; + int m_maxval; +}; + + +class PxMEncoder : public BaseImageEncoder +{ +public: + PxMEncoder(); + virtual ~PxMEncoder(); + + bool isFormatSupported( int depth ) const; + bool write( const Mat& img, const vector& params ); + + ImageEncoder newEncoder() const; +}; + +} + +#endif/*_GRFMT_PxM_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_sunras.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_sunras.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_sunras.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_sunras.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,425 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "grfmt_sunras.hpp" + +namespace cv +{ + +static const char* fmtSignSunRas = "\x59\xA6\x6A\x95"; + +/************************ Sun Raster reader *****************************/ + +SunRasterDecoder::SunRasterDecoder() +{ + m_offset = -1; + m_signature = fmtSignSunRas; +} + + +SunRasterDecoder::~SunRasterDecoder() +{ +} + +ImageDecoder SunRasterDecoder::newDecoder() const +{ + return new SunRasterDecoder; +} + +void SunRasterDecoder::close() +{ + m_strm.close(); +} + + +bool SunRasterDecoder::readHeader() +{ + bool result = false; + + if( !m_strm.open( m_filename )) return false; + + try + { + m_strm.skip( 4 ); + m_width = m_strm.getDWord(); + m_height = m_strm.getDWord(); + m_bpp = m_strm.getDWord(); + int palSize = 3*(1 << m_bpp); + + m_strm.skip( 4 ); + m_encoding = (SunRasType)m_strm.getDWord(); + m_maptype = (SunRasMapType)m_strm.getDWord(); + m_maplength = m_strm.getDWord(); + + if( m_width > 0 && m_height > 0 && + (m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) && + (m_encoding == RAS_OLD || m_encoding == RAS_STANDARD || + (m_type == RAS_BYTE_ENCODED && m_bpp == 8) || m_type == RAS_FORMAT_RGB) && + ((m_maptype == RMT_NONE && m_maplength == 0) || + (m_maptype == RMT_EQUAL_RGB && m_maplength <= palSize && m_bpp <= 8))) + { + memset( m_palette, 0, sizeof(m_palette)); + + if( m_maplength != 0 ) + { + uchar buffer[256*3]; + + if( m_strm.getBytes( buffer, m_maplength ) == m_maplength ) + { + int i; + palSize = m_maplength/3; + + for( i = 0; i < palSize; i++ ) + { + m_palette[i].b = buffer[i + 2*palSize]; + m_palette[i].g = buffer[i + palSize]; + m_palette[i].r = buffer[i]; + m_palette[i].a = 0; + } + + m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1; + m_offset = m_strm.getPos(); + + assert( m_offset == 32 + m_maplength ); + result = true; + } + } + else + { + m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1; + + if( CV_MAT_CN(m_type) == 1 ) + FillGrayPalette( m_palette, m_bpp ); + + m_offset = m_strm.getPos(); + + assert( m_offset == 32 + m_maplength ); + result = true; + } + } + } + catch(...) + { + } + + if( !result ) + { + m_offset = -1; + m_width = m_height = -1; + m_strm.close(); + } + return result; +} + + +bool SunRasterDecoder::readData( Mat& img ) +{ + int color = img.channels() > 1; + uchar* data = img.data; + int step = (int)img.step; + uchar gray_palette[256]; + bool result = false; + int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2; + int nch = color ? 3 : 1; + int width3 = m_width*nch; + int y; + + if( m_offset < 0 || !m_strm.isOpened()) + return false; + + AutoBuffer _src(src_pitch + 32); + uchar* src = _src; + AutoBuffer _bgr(m_width*3 + 32); + uchar* bgr = _bgr; + + if( !color && m_maptype == RMT_EQUAL_RGB ) + CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp ); + + try + { + m_strm.setPos( m_offset ); + + switch( m_bpp ) + { + /************************* 1 BPP ************************/ + case 1: + if( m_type != RAS_BYTE_ENCODED ) + { + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( color ) + FillColorRow1( data, src, m_width, m_palette ); + else + FillGrayRow1( data, src, m_width, gray_palette ); + } + result = true; + } + else + { + uchar* line_end = src + (m_width*m_bpp + 7)/8; + uchar* tsrc = src; + y = 0; + + for(;;) + { + int max_count = (int)(line_end - tsrc); + int code = 0, len = 0, len1 = 0; + + do + { + code = m_strm.getByte(); + if( code == 0x80 ) + { + len = m_strm.getByte(); + if( len != 0 ) break; + } + tsrc[len1] = (uchar)code; + } + while( ++len1 < max_count ); + + tsrc += len1; + + if( len > 0 ) // encoded mode + { + ++len; + code = m_strm.getByte(); + if( len > line_end - tsrc ) + { + assert(0); + goto bad_decoding_1bpp; + } + + memset( tsrc, code, len ); + tsrc += len; + } + + if( tsrc >= line_end ) + { + tsrc = src; + if( color ) + FillColorRow1( data, src, m_width, m_palette ); + else + FillGrayRow1( data, src, m_width, gray_palette ); + data += step; + if( ++y >= m_height ) break; + } + } + result = true; +bad_decoding_1bpp: + ; + } + break; + /************************* 8 BPP ************************/ + case 8: + if( m_type != RAS_BYTE_ENCODED ) + { + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( src, src_pitch ); + if( color ) + FillColorRow8( data, src, m_width, m_palette ); + else + FillGrayRow8( data, src, m_width, gray_palette ); + } + result = true; + } + else // RLE-encoded + { + uchar* line_end = data + width3; + y = 0; + + for(;;) + { + int max_count = (int)(line_end - data); + int code = 0, len = 0, len1; + uchar* tsrc = src; + + do + { + code = m_strm.getByte(); + if( code == 0x80 ) + { + len = m_strm.getByte(); + if( len != 0 ) break; + } + *tsrc++ = (uchar)code; + } + while( (max_count -= nch) > 0 ); + + len1 = (int)(tsrc - src); + + if( len1 > 0 ) + { + if( color ) + FillColorRow8( data, src, len1, m_palette ); + else + FillGrayRow8( data, src, len1, gray_palette ); + data += len1*nch; + } + + if( len > 0 ) // encoded mode + { + len = (len + 1)*nch; + code = m_strm.getByte(); + + if( color ) + data = FillUniColor( data, line_end, step, width3, + y, m_height, len, + m_palette[code] ); + else + data = FillUniGray( data, line_end, step, width3, + y, m_height, len, + gray_palette[code] ); + if( y >= m_height ) + break; + } + + if( data == line_end ) + { + if( m_strm.getByte() != 0 ) + goto bad_decoding_end; + line_end += step; + data = line_end - width3; + if( ++y >= m_height ) break; + } + } + + result = true; +bad_decoding_end: + ; + } + break; + /************************* 24 BPP ************************/ + case 24: + for( y = 0; y < m_height; y++, data += step ) + { + m_strm.getBytes( color ? data : bgr, src_pitch ); + + if( color ) + { + if( m_type == RAS_FORMAT_RGB ) + icvCvt_RGB2BGR_8u_C3R( data, 0, data, 0, cvSize(m_width,1) ); + } + else + { + icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1), + m_type == RAS_FORMAT_RGB ? 2 : 0 ); + } + } + result = true; + break; + /************************* 32 BPP ************************/ + case 32: + for( y = 0; y < m_height; y++, data += step ) + { + /* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3, + so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */ + m_strm.getBytes( src + 3, src_pitch ); + + if( color ) + icvCvt_BGRA2BGR_8u_C4C3R( src + 4, 0, data, 0, cvSize(m_width,1), + m_type == RAS_FORMAT_RGB ? 2 : 0 ); + else + icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, cvSize(m_width,1), + m_type == RAS_FORMAT_RGB ? 2 : 0 ); + } + result = true; + break; + default: + assert(0); + } + } + catch( ... ) + { + } + + return result; +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +SunRasterEncoder::SunRasterEncoder() +{ + m_description = "Sun raster files (*.sr;*.ras)"; +} + + +ImageEncoder SunRasterEncoder::newEncoder() const +{ + return new SunRasterEncoder; +} + +SunRasterEncoder::~SunRasterEncoder() +{ +} + +bool SunRasterEncoder::write( const Mat& img, const vector& ) +{ + bool result = false; + int y, width = img.cols, height = img.rows, channels = img.channels(); + int fileStep = (width*channels + 1) & -2; + WMByteStream strm; + + if( strm.open(m_filename) ) + { + strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) ); + strm.putDWord( width ); + strm.putDWord( height ); + strm.putDWord( channels*8 ); + strm.putDWord( fileStep*height ); + strm.putDWord( RAS_STANDARD ); + strm.putDWord( RMT_NONE ); + strm.putDWord( 0 ); + + for( y = 0; y < height; y++ ) + strm.putBytes( img.data + img.step*y, fileStep ); + + strm.close(); + result = true; + } + return result; +} + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_sunras.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_sunras.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_sunras.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_sunras.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,105 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_SUNRAS_H_ +#define _GRFMT_SUNRAS_H_ + +#include "grfmt_base.hpp" + +namespace cv +{ + +enum SunRasType +{ + RAS_OLD = 0, + RAS_STANDARD = 1, + RAS_BYTE_ENCODED = 2, /* RLE encoded */ + RAS_FORMAT_RGB = 3 /* RGB instead of BGR */ +}; + +enum SunRasMapType +{ + RMT_NONE = 0, /* direct color encoding */ + RMT_EQUAL_RGB = 1 /* paletted image */ +}; + + +// Sun Raster Reader +class SunRasterDecoder : public BaseImageDecoder +{ +public: + + SunRasterDecoder(); + virtual ~SunRasterDecoder(); + + bool readData( Mat& img ); + bool readHeader(); + void close(); + + ImageDecoder newDecoder() const; + +protected: + + RMByteStream m_strm; + PaletteEntry m_palette[256]; + int m_bpp; + int m_offset; + SunRasType m_encoding; + SunRasMapType m_maptype; + int m_maplength; +}; + + +class SunRasterEncoder : public BaseImageEncoder +{ +public: + SunRasterEncoder(); + virtual ~SunRasterEncoder(); + + bool write( const Mat& img, const vector& params ); + + ImageEncoder newEncoder() const; +}; + +} + +#endif/*_GRFMT_SUNRAS_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_tiff.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_tiff.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_tiff.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_tiff.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,736 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/****************************************************************************************\ + A part of the file implements TIFF reader on base of libtiff library + (see otherlibs/_graphics/readme.txt for copyright notice) +\****************************************************************************************/ + +#include "precomp.hpp" +#include "grfmt_tiff.hpp" + +namespace cv +{ +static const char fmtSignTiffII[] = "II\x2a\x00"; +static const char fmtSignTiffMM[] = "MM\x00\x2a"; + +#ifdef HAVE_TIFF + +#include "tiff.h" +#include "tiffio.h" + +static int grfmt_tiff_err_handler_init = 0; +static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {} + +TiffDecoder::TiffDecoder() +{ + m_tif = 0; + if( !grfmt_tiff_err_handler_init ) + { + grfmt_tiff_err_handler_init = 1; + + TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler ); + TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler ); + } +} + + +void TiffDecoder::close() +{ + if( m_tif ) + { + TIFF* tif = (TIFF*)m_tif; + TIFFClose( tif ); + m_tif = 0; + } +} + +TiffDecoder::~TiffDecoder() +{ + close(); +} + +size_t TiffDecoder::signatureLength() const +{ + return 4; +} + +bool TiffDecoder::checkSignature( const string& signature ) const +{ + return signature.size() >= 4 && + (memcmp(signature.c_str(), fmtSignTiffII, 4) == 0 || + memcmp(signature.c_str(), fmtSignTiffMM, 4) == 0); +} + +ImageDecoder TiffDecoder::newDecoder() const +{ + return new TiffDecoder; +} + +bool TiffDecoder::readHeader() +{ + bool result = false; + + close(); + TIFF* tif = TIFFOpen( m_filename.c_str(), "rb" ); + + if( tif ) + { + int wdth = 0, hght = 0, photometric = 0; + m_tif = tif; + + if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) && + TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) && + TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric )) + { + int bpp=8, ncn = photometric > 1 ? 3 : 1; + TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); + TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); + + m_width = wdth; + m_height = hght; + if( bpp > 8 && + ((photometric != 2 && photometric != 1) || + (ncn != 1 && ncn != 3 && ncn != 4))) + bpp = 8; + + switch(bpp) + { + case 8: + m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? 3 : 1); + break; + case 16: + m_type = CV_MAKETYPE(CV_16U, photometric > 1 ? 3 : 1); + break; + + case 32: + m_type = CV_MAKETYPE(CV_32F, photometric > 1 ? 3 : 1); + break; + case 64: + m_type = CV_MAKETYPE(CV_64F, photometric > 1 ? 3 : 1); + break; + + default: + result = false; + } + result = true; + } + } + + if( !result ) + close(); + + return result; +} + + +bool TiffDecoder::readData( Mat& img ) +{ + bool result = false; + bool color = img.channels() > 1; + uchar* data = img.data; + + if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F ) + return false; + + if( m_tif && m_width && m_height ) + { + TIFF* tif = (TIFF*)m_tif; + int tile_width0 = m_width, tile_height0 = 0; + int x, y, i; + int is_tiled = TIFFIsTiled(tif); + int photometric; + TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ); + int bpp = 8, ncn = photometric > 1 ? 3 : 1; + TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); + TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); + const int bitsPerByte = 8; + int dst_bpp = (int)(img.elemSize1() * bitsPerByte); + + if(dst_bpp == 8) + { + char errmsg[1024]; + if(!TIFFRGBAImageOK( tif, errmsg )) + { + close(); + return false; + } + } + + if( (!is_tiled) || + (is_tiled && + TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) && + TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))) + { + if(!is_tiled) + TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ); + + if( tile_width0 <= 0 ) + tile_width0 = m_width; + + if( tile_height0 <= 0 ) + tile_height0 = m_height; + + AutoBuffer _buffer( size_t(8) * tile_height0*tile_width0); + uchar* buffer = _buffer; + ushort* buffer16 = (ushort*)buffer; + float* buffer32 = (float*)buffer; + double* buffer64 = (double*)buffer; + int tileidx = 0; + + for( y = 0; y < m_height; y += tile_height0, data += img.step*tile_height0 ) + { + int tile_height = tile_height0; + + if( y + tile_height > m_height ) + tile_height = m_height - y; + + for( x = 0; x < m_width; x += tile_width0, tileidx++ ) + { + int tile_width = tile_width0, ok; + + if( x + tile_width > m_width ) + tile_width = m_width - x; + + switch(dst_bpp) + { + case 8: + { + if( !is_tiled ) + ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer ); + else + ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer ); + + if( !ok ) + { + close(); + return false; + } + + for( i = 0; i < tile_height; i++ ) + if( color ) + icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, + data + x*3 + img.step*(tile_height - i - 1), 0, + cvSize(tile_width,1), 2 ); + else + icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, + data + x + img.step*(tile_height - i - 1), 0, + cvSize(tile_width,1), 2 ); + break; + } + + case 16: + { + if( !is_tiled ) + ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; + else + ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; + + if( !ok ) + { + close(); + return false; + } + + for( i = 0; i < tile_height; i++ ) + { + if( color ) + { + if( ncn == 1 ) + { + icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0, + (ushort*)(data + img.step*i) + x*3, 0, + cvSize(tile_width,1) ); + } + else if( ncn == 3 ) + { + icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0, + (ushort*)(data + img.step*i) + x*3, 0, + cvSize(tile_width,1) ); + } + else + { + icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0, + (ushort*)(data + img.step*i) + x*3, 0, + cvSize(tile_width,1), 2 ); + } + } + else + { + if( ncn == 1 ) + { + memcpy((ushort*)(data + img.step*i)+x, + buffer16 + i*tile_width*ncn, + tile_width*sizeof(buffer16[0])); + } + else + { + icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0, + (ushort*)(data + img.step*i) + x, 0, + cvSize(tile_width,1), ncn, 2 ); + } + } + } + break; + } + + case 32: + case 64: + { + if( !is_tiled ) + ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; + else + ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; + + if( !ok || ncn != 1 ) + { + close(); + return false; + } + + for( i = 0; i < tile_height; i++ ) + { + if(dst_bpp == 32) + { + memcpy((float*)(data + img.step*i)+x, + buffer32 + i*tile_width*ncn, + tile_width*sizeof(buffer32[0])); + } + else + { + memcpy((double*)(data + img.step*i)+x, + buffer64 + i*tile_width*ncn, + tile_width*sizeof(buffer64[0])); + } + } + + break; + } + default: + { + close(); + return false; + } + } + } + } + + result = true; + } + } + + close(); + return result; +} + +#endif + +////////////////////////////////////////////////////////////////////////////////////////// + +TiffEncoder::TiffEncoder() +{ + m_description = "TIFF Files (*.tiff;*.tif)"; +#ifdef HAVE_TIFF + m_buf_supported = false; +#else + m_buf_supported = true; +#endif +} + +TiffEncoder::~TiffEncoder() +{ +} + +ImageEncoder TiffEncoder::newEncoder() const +{ + return new TiffEncoder; +} + +bool TiffEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U || depth == CV_16U; +} + +void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag, + TiffFieldType fieldType, + int count, int value ) +{ + strm.putWord( tag ); + strm.putWord( fieldType ); + strm.putDWord( count ); + strm.putDWord( value ); +} + +#ifdef HAVE_TIFF + +static void readParam(const vector& params, int key, int& value) +{ + for(size_t i = 0; i + 1 < params.size(); i += 2) + if(params[i] == key) + { + value = params[i+1]; + break; + } +} + +bool TiffEncoder::writeLibTiff( const Mat& img, const vector& params) +{ + int channels = img.channels(); + int width = img.cols, height = img.rows; + int depth = img.depth(); + + int bitsPerChannel = -1; + switch (depth) + { + case CV_8U: + { + bitsPerChannel = 8; + break; + } + case CV_16U: + { + bitsPerChannel = 16; + break; + } + default: + { + return false; + } + } + + const int bitsPerByte = 8; + size_t fileStep = (width * channels * bitsPerChannel) / bitsPerByte; + + int rowsPerStrip = (int)((1 << 13)/fileStep); + readParam(params, TIFFTAG_ROWSPERSTRIP, rowsPerStrip); + + if( rowsPerStrip < 1 ) + rowsPerStrip = 1; + + if( rowsPerStrip > height ) + rowsPerStrip = height; + + + // do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode. + // http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html + TIFF* pTiffHandle = TIFFOpen(m_filename.c_str(), "w"); + if (!pTiffHandle) + { + return false; + } + + // defaults for now, maybe base them on params in the future + int compression = COMPRESSION_LZW; + int predictor = PREDICTOR_HORIZONTAL; + + readParam(params, TIFFTAG_COMPRESSION, compression); + readParam(params, TIFFTAG_PREDICTOR, predictor); + + int colorspace = channels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK; + + if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width) + || !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height) + || !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel) + || !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression) + || !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace) + || !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels) + || !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) + || !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip) + || !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor) + ) + { + TIFFClose(pTiffHandle); + return false; + } + + // row buffer, because TIFFWriteScanline modifies the original data! + size_t scanlineSize = TIFFScanlineSize(pTiffHandle); + AutoBuffer _buffer(scanlineSize+32); + uchar* buffer = _buffer; + if (!buffer) + { + TIFFClose(pTiffHandle); + return false; + } + + for (int y = 0; y < height; ++y) + { + switch(channels) + { + case 1: + { + memcpy(buffer, img.data + img.step * y, scanlineSize); + break; + } + + case 3: + { + if (depth == CV_8U) + icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); + break; + } + + case 4: + { + if (depth == CV_8U) + icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); + break; + } + + default: + { + TIFFClose(pTiffHandle); + return false; + } + } + + int writeResult = TIFFWriteScanline(pTiffHandle, buffer, y, 0); + if (writeResult != 1) + { + TIFFClose(pTiffHandle); + return false; + } + } + + TIFFClose(pTiffHandle); + return true; +} + +#endif + +#ifdef HAVE_TIFF +bool TiffEncoder::write( const Mat& img, const vector& params) +#else +bool TiffEncoder::write( const Mat& img, const vector& /*params*/) +#endif +{ + int channels = img.channels(); + int width = img.cols, height = img.rows; + int depth = img.depth(); + + if (depth != CV_8U && depth != CV_16U) + return false; + + int bytesPerChannel = depth == CV_8U ? 1 : 2; + int fileStep = width * channels * bytesPerChannel; + + WLByteStream strm; + + if( m_buf ) + { + if( !strm.open(*m_buf) ) + return false; + } + else + { +#ifdef HAVE_TIFF + return writeLibTiff(img, params); +#else + if( !strm.open(m_filename) ) + return false; +#endif + } + + int rowsPerStrip = (1 << 13)/fileStep; + + if( rowsPerStrip < 1 ) + rowsPerStrip = 1; + + if( rowsPerStrip > height ) + rowsPerStrip = height; + + int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip; + + if( m_buf ) + m_buf->reserve( alignSize(stripCount*8 + fileStep*height + 256, 256) ); + +/*#if defined _DEBUG || !defined WIN32 + int uncompressedRowSize = rowsPerStrip * fileStep; +#endif*/ + int directoryOffset = 0; + + AutoBuffer stripOffsets(stripCount); + AutoBuffer stripCounts(stripCount); + AutoBuffer _buffer(fileStep+32); + uchar* buffer = _buffer; + int stripOffsetsOffset = 0; + int stripCountsOffset = 0; + int bitsPerSample = 8 * bytesPerChannel; + int y = 0; + + strm.putBytes( fmtSignTiffII, 4 ); + strm.putDWord( directoryOffset ); + + // write an image data first (the most reasonable way + // for compressed images) + for( i = 0; i < stripCount; i++ ) + { + int limit = y + rowsPerStrip; + + if( limit > height ) + limit = height; + + stripOffsets[i] = strm.getPos(); + + for( ; y < limit; y++ ) + { + if( channels == 3 ) + { + if (depth == CV_8U) + icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); + } + else + { + if( channels == 4 ) + { + if (depth == CV_8U) + icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); + } + } + + strm.putBytes( channels > 1 ? buffer : img.data + img.step*y, fileStep ); + } + + stripCounts[i] = (short)(strm.getPos() - stripOffsets[i]); + /*assert( stripCounts[i] == uncompressedRowSize || + stripCounts[i] < uncompressedRowSize && + i == stripCount - 1);*/ + } + + if( stripCount > 2 ) + { + stripOffsetsOffset = strm.getPos(); + for( i = 0; i < stripCount; i++ ) + strm.putDWord( stripOffsets[i] ); + + stripCountsOffset = strm.getPos(); + for( i = 0; i < stripCount; i++ ) + strm.putWord( stripCounts[i] ); + } + else if(stripCount == 2) + { + stripOffsetsOffset = strm.getPos(); + for (i = 0; i < stripCount; i++) + { + strm.putDWord (stripOffsets [i]); + } + stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16); + } + else + { + stripOffsetsOffset = stripOffsets[0]; + stripCountsOffset = stripCounts[0]; + } + + if( channels > 1 ) + { + int bitsPerSamplePos = strm.getPos(); + strm.putWord(bitsPerSample); + strm.putWord(bitsPerSample); + strm.putWord(bitsPerSample); + if( channels == 4 ) + strm.putWord(bitsPerSample); + bitsPerSample = bitsPerSamplePos; + } + + directoryOffset = strm.getPos(); + + // write header + strm.putWord( 9 ); + + /* warning: specification 5.0 of Tiff want to have tags in + ascending order. This is a non-fatal error, but this cause + warning with some tools. So, keep this in ascending order */ + + writeTag( strm, TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width ); + writeTag( strm, TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height ); + writeTag( strm, TIFF_TAG_BITS_PER_SAMPLE, + TIFF_TYPE_SHORT, channels, bitsPerSample ); + writeTag( strm, TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP ); + writeTag( strm, TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 ); + + writeTag( strm, TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG, + stripCount, stripOffsetsOffset ); + + writeTag( strm, TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels ); + writeTag( strm, TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip ); + + writeTag( strm, TIFF_TAG_STRIP_COUNTS, + stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG, + stripCount, stripCountsOffset ); + + strm.putDWord(0); + strm.close(); + + if( m_buf ) + { + (*m_buf)[4] = (uchar)directoryOffset; + (*m_buf)[5] = (uchar)(directoryOffset >> 8); + (*m_buf)[6] = (uchar)(directoryOffset >> 16); + (*m_buf)[7] = (uchar)(directoryOffset >> 24); + } + else + { + // write directory offset + FILE* f = fopen( m_filename.c_str(), "r+b" ); + buffer[0] = (uchar)directoryOffset; + buffer[1] = (uchar)(directoryOffset >> 8); + buffer[2] = (uchar)(directoryOffset >> 16); + buffer[3] = (uchar)(directoryOffset >> 24); + + fseek( f, 4, SEEK_SET ); + fwrite( buffer, 1, 4, f ); + fclose(f); + } + + return true; +} + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_tiff.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_tiff.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmt_tiff.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmt_tiff.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,136 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMT_TIFF_H_ +#define _GRFMT_TIFF_H_ + +#include "grfmt_base.hpp" + +namespace cv +{ + +// native simple TIFF codec +enum TiffCompression +{ + TIFF_UNCOMP = 1, + TIFF_HUFFMAN = 2, + TIFF_PACKBITS = 32773 +}; + +enum TiffByteOrder +{ + TIFF_ORDER_II = 0x4949, + TIFF_ORDER_MM = 0x4d4d +}; + + +enum TiffTag +{ + TIFF_TAG_WIDTH = 256, + TIFF_TAG_HEIGHT = 257, + TIFF_TAG_BITS_PER_SAMPLE = 258, + TIFF_TAG_COMPRESSION = 259, + TIFF_TAG_PHOTOMETRIC = 262, + TIFF_TAG_STRIP_OFFSETS = 273, + TIFF_TAG_STRIP_COUNTS = 279, + TIFF_TAG_SAMPLES_PER_PIXEL = 277, + TIFF_TAG_ROWS_PER_STRIP = 278, + TIFF_TAG_PLANAR_CONFIG = 284, + TIFF_TAG_COLOR_MAP = 320 +}; + + +enum TiffFieldType +{ + TIFF_TYPE_BYTE = 1, + TIFF_TYPE_SHORT = 3, + TIFF_TYPE_LONG = 4 +}; + + +#ifdef HAVE_TIFF + +// libtiff based TIFF codec + +class TiffDecoder : public BaseImageDecoder +{ +public: + TiffDecoder(); + virtual ~TiffDecoder(); + + bool readHeader(); + bool readData( Mat& img ); + void close(); + + size_t signatureLength() const; + bool checkSignature( const string& signature ) const; + ImageDecoder newDecoder() const; + +protected: + void* m_tif; +}; + +#endif + +// ... and writer +class TiffEncoder : public BaseImageEncoder +{ +public: + TiffEncoder(); + virtual ~TiffEncoder(); + + bool isFormatSupported( int depth ) const; + + bool write( const Mat& img, const vector& params ); + ImageEncoder newEncoder() const; + +protected: + void writeTag( WLByteStream& strm, TiffTag tag, + TiffFieldType fieldType, + int count, int value ); + + bool writeLibTiff( const Mat& img, const vector& params ); +}; + +} + +#endif/*_GRFMT_TIFF_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmts.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmts.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/grfmts.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/grfmts.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,56 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _GRFMTS_H_ +#define _GRFMTS_H_ + +#include "grfmt_base.hpp" +#include "grfmt_imageio.hpp" +#include "grfmt_bmp.hpp" +#include "grfmt_sunras.hpp" +#include "grfmt_jpeg.hpp" +#include "grfmt_pxm.hpp" +#include "grfmt_tiff.hpp" +#include "grfmt_png.hpp" +#include "grfmt_jpeg2000.hpp" +#include "grfmt_exr.hpp" + +#endif/*_GRFMTS_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/loadsave.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/loadsave.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/loadsave.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/loadsave.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,545 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// +// Loading and saving IPL images. +// + +#include "precomp.hpp" +#include "grfmts.hpp" +#undef min +#undef max + +/****************************************************************************************\ +* Image Codecs * +\****************************************************************************************/ +namespace cv +{ + +struct ImageCodecInitializer +{ + ImageCodecInitializer() + { + decoders.push_back( new BmpDecoder ); + encoders.push_back( new BmpEncoder ); + #ifdef HAVE_JPEG + decoders.push_back( new JpegDecoder ); + encoders.push_back( new JpegEncoder ); + #endif + decoders.push_back( new SunRasterDecoder ); + encoders.push_back( new SunRasterEncoder ); + decoders.push_back( new PxMDecoder ); + encoders.push_back( new PxMEncoder ); + #ifdef HAVE_TIFF + decoders.push_back( new TiffDecoder ); + #endif + encoders.push_back( new TiffEncoder ); + #ifdef HAVE_PNG + decoders.push_back( new PngDecoder ); + encoders.push_back( new PngEncoder ); + #endif + #ifdef HAVE_JASPER + decoders.push_back( new Jpeg2KDecoder ); + encoders.push_back( new Jpeg2KEncoder ); + #endif + #ifdef HAVE_OPENEXR + decoders.push_back( new ExrDecoder ); + encoders.push_back( new ExrEncoder ); + #endif + // because it is a generic image I/O API, supporting many formats, + // it should be last in the list. + #ifdef HAVE_IMAGEIO + decoders.push_back( new ImageIODecoder ); + encoders.push_back( new ImageIOEncoder ); + #endif + } + + vector decoders; + vector encoders; +}; + +static ImageCodecInitializer codecs; + +static ImageDecoder findDecoder( const string& filename ) +{ + size_t i, maxlen = 0; + for( i = 0; i < codecs.decoders.size(); i++ ) + { + size_t len = codecs.decoders[i]->signatureLength(); + maxlen = std::max(maxlen, len); + } + + FILE* f= fopen( filename.c_str(), "rb" ); + if( !f ) + return ImageDecoder(); + string signature(maxlen, ' '); + maxlen = fread( &signature[0], 1, maxlen, f ); + fclose(f); + signature = signature.substr(0, maxlen); + + for( i = 0; i < codecs.decoders.size(); i++ ) + { + if( codecs.decoders[i]->checkSignature(signature) ) + return codecs.decoders[i]->newDecoder(); + } + + return ImageDecoder(); +} + +static ImageDecoder findDecoder( const Mat& buf ) +{ + size_t i, maxlen = 0; + + if( buf.rows*buf.cols < 1 || !buf.isContinuous() ) + return ImageDecoder(); + + for( i = 0; i < codecs.decoders.size(); i++ ) + { + size_t len = codecs.decoders[i]->signatureLength(); + maxlen = std::max(maxlen, len); + } + + size_t bufSize = buf.rows*buf.cols*buf.elemSize(); + maxlen = std::min(maxlen, bufSize); + string signature(maxlen, ' '); + memcpy( &signature[0], buf.data, maxlen ); + + for( i = 0; i < codecs.decoders.size(); i++ ) + { + if( codecs.decoders[i]->checkSignature(signature) ) + return codecs.decoders[i]->newDecoder(); + } + + return ImageDecoder(); +} + +static ImageEncoder findEncoder( const string& _ext ) +{ + if( _ext.size() <= 1 ) + return ImageEncoder(); + + const char* ext = strrchr( _ext.c_str(), '.' ); + if( !ext ) + return ImageEncoder(); + int len = 0; + for( ext++; isalnum(ext[len]) && len < 128; len++ ) + ; + + for( size_t i = 0; i < codecs.encoders.size(); i++ ) + { + string description = codecs.encoders[i]->getDescription(); + const char* descr = strchr( description.c_str(), '(' ); + + while( descr ) + { + descr = strchr( descr + 1, '.' ); + if( !descr ) + break; + int j = 0; + for( descr++; isalnum(descr[j]) && j < len; j++ ) + { + int c1 = tolower(ext[j]); + int c2 = tolower(descr[j]); + if( c1 != c2 ) + break; + } + if( j == len && !isalnum(descr[j])) + return codecs.encoders[i]->newEncoder(); + descr += j; + } + } + + return ImageEncoder(); +} + +enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 }; + +static void* +imread_( const string& filename, int flags, int hdrtype, Mat* mat=0 ) +{ + IplImage* image = 0; + CvMat *matrix = 0; + Mat temp, *data = &temp; + + ImageDecoder decoder = findDecoder(filename); + if( decoder.empty() ) + return 0; + decoder->setSource(filename); + if( !decoder->readHeader() ) + return 0; + + CvSize size; + size.width = decoder->width(); + size.height = decoder->height(); + + int type = decoder->type(); + if( flags != -1 ) + { + if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 ) + type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type)); + + if( (flags & CV_LOAD_IMAGE_COLOR) != 0 || + ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) ) + type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3); + else + type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); + } + + if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT ) + { + if( hdrtype == LOAD_CVMAT ) + { + matrix = cvCreateMat( size.height, size.width, type ); + temp = cvarrToMat(matrix); + } + else + { + mat->create( size.height, size.width, type ); + data = mat; + } + } + else + { + image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) ); + temp = cvarrToMat(image); + } + + if( !decoder->readData( *data )) + { + cvReleaseImage( &image ); + cvReleaseMat( &matrix ); + if( mat ) + mat->release(); + return 0; + } + + return hdrtype == LOAD_CVMAT ? (void*)matrix : + hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat; +} + +Mat imread( const string& filename, int flags ) +{ + Mat img; + imread_( filename, flags, LOAD_MAT, &img ); + return img; +} + +static bool imwrite_( const string& filename, const Mat& image, + const vector& params, bool flipv ) +{ + Mat temp; + const Mat* pimage = ℑ + + CV_Assert( image.channels() == 1 || image.channels() == 3 || image.channels() == 4 ); + + ImageEncoder encoder = findEncoder( filename ); + if( encoder.empty() ) + CV_Error( CV_StsError, "could not find a writer for the specified extension" ); + + if( !encoder->isFormatSupported(image.depth()) ) + { + CV_Assert( encoder->isFormatSupported(CV_8U) ); + image.convertTo( temp, CV_8U ); + pimage = &temp; + } + + if( flipv ) + { + flip(*pimage, temp, 0); + pimage = &temp; + } + + encoder->setDestination( filename ); + bool code = encoder->write( *pimage, params ); + + // CV_Assert( code ); + return code; +} + +bool imwrite( const string& filename, InputArray _img, + const vector& params ) +{ + Mat img = _img.getMat(); + return imwrite_(filename, img, params, false); +} + +static void* +imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) +{ + CV_Assert(buf.data && buf.isContinuous()); + IplImage* image = 0; + CvMat *matrix = 0; + Mat temp, *data = &temp; + string filename; + + ImageDecoder decoder = findDecoder(buf); + if( decoder.empty() ) + return 0; + + if( !decoder->setSource(buf) ) + { + filename = tempfile(); + FILE* f = fopen( filename.c_str(), "wb" ); + if( !f ) + return 0; + size_t bufSize = buf.cols*buf.rows*buf.elemSize(); + fwrite( &buf.data[0], 1, bufSize, f ); + fclose(f); + decoder->setSource(filename); + } + + if( !decoder->readHeader() ) + { + if( !filename.empty() ) + remove(filename.c_str()); + return 0; + } + + CvSize size; + size.width = decoder->width(); + size.height = decoder->height(); + + int type = decoder->type(); + if( flags != -1 ) + { + if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 ) + type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type)); + + if( (flags & CV_LOAD_IMAGE_COLOR) != 0 || + ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) ) + type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3); + else + type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); + } + + if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT ) + { + if( hdrtype == LOAD_CVMAT ) + { + matrix = cvCreateMat( size.height, size.width, type ); + temp = cvarrToMat(matrix); + } + else + { + mat->create( size.height, size.width, type ); + data = mat; + } + } + else + { + image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) ); + temp = cvarrToMat(image); + } + + bool code = decoder->readData( *data ); + if( !filename.empty() ) + remove(filename.c_str()); + + if( !code ) + { + cvReleaseImage( &image ); + cvReleaseMat( &matrix ); + if( mat ) + mat->release(); + return 0; + } + + return hdrtype == LOAD_CVMAT ? (void*)matrix : + hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat; +} + + +Mat imdecode( InputArray _buf, int flags ) +{ + Mat buf = _buf.getMat(), img; + imdecode_( buf, flags, LOAD_MAT, &img ); + return img; +} + +Mat imdecode( InputArray _buf, int flags, Mat* dst ) +{ + Mat buf = _buf.getMat(), img; + dst = dst ? dst : &img; + imdecode_( buf, flags, LOAD_MAT, dst ); + return *dst; +} + +bool imencode( const string& ext, InputArray _image, + vector& buf, const vector& params ) +{ + Mat image = _image.getMat(); + + int channels = image.channels(); + CV_Assert( channels == 1 || channels == 3 || channels == 4 ); + + ImageEncoder encoder = findEncoder( ext ); + if( encoder.empty() ) + CV_Error( CV_StsError, "could not find encoder for the specified extension" ); + + if( !encoder->isFormatSupported(image.depth()) ) + { + CV_Assert( encoder->isFormatSupported(CV_8U) ); + Mat temp; + image.convertTo(temp, CV_8U); + image = temp; + } + + bool code; + if( encoder->setDestination(buf) ) + { + code = encoder->write(image, params); + encoder->throwOnEror(); + CV_Assert( code ); + } + else + { + string filename = tempfile(); + code = encoder->setDestination(filename); + CV_Assert( code ); + + code = encoder->write(image, params); + encoder->throwOnEror(); + CV_Assert( code ); + + FILE* f = fopen( filename.c_str(), "rb" ); + CV_Assert(f != 0); + fseek( f, 0, SEEK_END ); + long pos = ftell(f); + buf.resize((size_t)pos); + fseek( f, 0, SEEK_SET ); + buf.resize(fread( &buf[0], 1, buf.size(), f )); + fclose(f); + remove(filename.c_str()); + } + return code; +} + +} + +/****************************************************************************************\ +* HighGUI loading & saving function implementation * +\****************************************************************************************/ + +CV_IMPL int +cvHaveImageReader( const char* filename ) +{ + cv::ImageDecoder decoder = cv::findDecoder(filename); + return !decoder.empty(); +} + +CV_IMPL int cvHaveImageWriter( const char* filename ) +{ + cv::ImageEncoder encoder = cv::findEncoder(filename); + return !encoder.empty(); +} + +CV_IMPL IplImage* +cvLoadImage( const char* filename, int iscolor ) +{ + return (IplImage*)cv::imread_(filename, iscolor, cv::LOAD_IMAGE ); +} + +CV_IMPL CvMat* +cvLoadImageM( const char* filename, int iscolor ) +{ + return (CvMat*)cv::imread_( filename, iscolor, cv::LOAD_CVMAT ); +} + +CV_IMPL int +cvSaveImage( const char* filename, const CvArr* arr, const int* _params ) +{ + int i = 0; + if( _params ) + { + for( ; _params[i] > 0; i += 2 ) + ; + } + return cv::imwrite_(filename, cv::cvarrToMat(arr), + i > 0 ? cv::vector(_params, _params+i) : cv::vector(), + CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL ); +} + +/* decode image stored in the buffer */ +CV_IMPL IplImage* +cvDecodeImage( const CvMat* _buf, int iscolor ) +{ + CV_Assert( _buf && CV_IS_MAT_CONT(_buf->type) ); + cv::Mat buf(1, _buf->rows*_buf->cols*CV_ELEM_SIZE(_buf->type), CV_8U, _buf->data.ptr); + return (IplImage*)cv::imdecode_(buf, iscolor, cv::LOAD_IMAGE ); +} + +CV_IMPL CvMat* +cvDecodeImageM( const CvMat* _buf, int iscolor ) +{ + CV_Assert( _buf && CV_IS_MAT_CONT(_buf->type) ); + cv::Mat buf(1, _buf->rows*_buf->cols*CV_ELEM_SIZE(_buf->type), CV_8U, _buf->data.ptr); + return (CvMat*)cv::imdecode_(buf, iscolor, cv::LOAD_CVMAT ); +} + +CV_IMPL CvMat* +cvEncodeImage( const char* ext, const CvArr* arr, const int* _params ) +{ + int i = 0; + if( _params ) + { + for( ; _params[i] > 0; i += 2 ) + ; + } + cv::Mat img = cv::cvarrToMat(arr); + if( CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL ) + { + cv::Mat temp; + cv::flip(img, temp, 0); + img = temp; + } + cv::vector buf; + + bool code = cv::imencode(ext, img, buf, + i > 0 ? std::vector(_params, _params+i) : std::vector() ); + if( !code ) + return 0; + CvMat* _buf = cvCreateMat(1, (int)buf.size(), CV_8U); + memcpy( _buf->data.ptr, &buf[0], buf.size() ); + + return _buf; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/precomp.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,43 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/precomp.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,239 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __HIGHGUI_H_ +#define __HIGHGUI_H_ + +#include "cvconfig.h" + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/highgui/highgui_c.h" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/core/internal.hpp" + +#include +#include +#include +#include +#include +#include + +#if defined WIN32 || defined WINCE + #include + #undef small + #undef min + #undef max + #undef abs +#endif + +#ifdef HAVE_TEGRA_OPTIMIZATION +#include "opencv2/highgui/highgui_tegra.hpp" +#endif + +/* Errors */ +#define HG_OK 0 /* Don't bet on it! */ +#define HG_BADNAME -1 /* Bad window or file name */ +#define HG_INITFAILED -2 /* Can't initialize HigHGUI */ +#define HG_WCFAILED -3 /* Can't create a window */ +#define HG_NULLPTR -4 /* The null pointer where it should not appear */ +#define HG_BADPARAM -5 + +#define __BEGIN__ __CV_BEGIN__ +#define __END__ __CV_END__ +#define EXIT __CV_EXIT__ + +#define CV_WINDOW_MAGIC_VAL 0x00420042 +#define CV_TRACKBAR_MAGIC_VAL 0x00420043 + +/***************************** CvCapture structure ******************************/ + +struct CvCapture +{ + virtual ~CvCapture() {} + virtual double getProperty(int) { return 0; } + virtual bool setProperty(int, double) { return 0; } + virtual bool grabFrame() { return true; } + virtual IplImage* retrieveFrame(int) { return 0; } + virtual int getCaptureDomain() { return CV_CAP_ANY; } // Return the type of the capture object: CV_CAP_VFW, etc... +}; + +/*************************** CvVideoWriter structure ****************************/ + +struct CvVideoWriter +{ + virtual ~CvVideoWriter() {} + virtual bool writeFrame(const IplImage*) { return false; } +}; + +CvCapture * cvCreateCameraCapture_V4L( int index ); +CvCapture * cvCreateCameraCapture_DC1394( int index ); +CvCapture * cvCreateCameraCapture_DC1394_2( int index ); +CvCapture* cvCreateCameraCapture_MIL( int index ); +CvCapture* cvCreateCameraCapture_Giganetix( int index ); +CvCapture * cvCreateCameraCapture_CMU( int index ); +CV_IMPL CvCapture * cvCreateCameraCapture_TYZX( int index ); +CvCapture* cvCreateFileCapture_Win32( const char* filename ); +CvCapture* cvCreateCameraCapture_VFW( int index ); +CvCapture* cvCreateFileCapture_VFW( const char* filename ); +CvVideoWriter* cvCreateVideoWriter_Win32( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); +CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); +CvCapture* cvCreateCameraCapture_DShow( int index ); +CvCapture* cvCreateCameraCapture_MSMF( int index ); +CvCapture* cvCreateCameraCapture_OpenNI( int index ); +CvCapture* cvCreateFileCapture_OpenNI( const char* filename ); +CvCapture* cvCreateCameraCapture_Android( int index ); +CvCapture* cvCreateCameraCapture_XIMEA( int index ); +CvCapture* cvCreateCameraCapture_AVFoundation(int index); + + +CVAPI(int) cvHaveImageReader(const char* filename); +CVAPI(int) cvHaveImageWriter(const char* filename); + +CvCapture* cvCreateFileCapture_Images(const char* filename); +CvVideoWriter* cvCreateVideoWriter_Images(const char* filename); + +CvCapture* cvCreateFileCapture_XINE (const char* filename); + + + + +#define CV_CAP_GSTREAMER_1394 0 +#define CV_CAP_GSTREAMER_V4L 1 +#define CV_CAP_GSTREAMER_V4L2 2 +#define CV_CAP_GSTREAMER_FILE 3 + +CvCapture* cvCreateCapture_GStreamer(int type, const char *filename); +CvCapture* cvCreateFileCapture_FFMPEG_proxy(const char* filename); + + +CvVideoWriter* cvCreateVideoWriter_FFMPEG_proxy( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); + +CvCapture * cvCreateFileCapture_QT (const char * filename); +CvCapture * cvCreateCameraCapture_QT (const int index); + +CvVideoWriter* cvCreateVideoWriter_QT ( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); + +CvCapture* cvCreateFileCapture_AVFoundation (const char * filename); +CvVideoWriter* cvCreateVideoWriter_AVFoundation( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); + + +CvCapture * cvCreateCameraCapture_Unicap (const int index); +CvCapture * cvCreateCameraCapture_PvAPI (const int index); +CvVideoWriter* cvCreateVideoWriter_GStreamer( const char* filename, int fourcc, + double fps, CvSize frameSize, int is_color ); + +//Yannick Verdie 2010 +void cvSetModeWindow_W32(const char* name, double prop_value); +void cvSetModeWindow_GTK(const char* name, double prop_value); +void cvSetModeWindow_CARBON(const char* name, double prop_value); +void cvSetModeWindow_COCOA(const char* name, double prop_value); + +double cvGetModeWindow_W32(const char* name); +double cvGetModeWindow_GTK(const char* name); +double cvGetModeWindow_CARBON(const char* name); +double cvGetModeWindow_COCOA(const char* name); + +double cvGetPropWindowAutoSize_W32(const char* name); +double cvGetPropWindowAutoSize_GTK(const char* name); + +double cvGetRatioWindow_W32(const char* name); +double cvGetRatioWindow_GTK(const char* name); + +double cvGetOpenGlProp_W32(const char* name); +double cvGetOpenGlProp_GTK(const char* name); + +//for QT +#if defined (HAVE_QT) +double cvGetModeWindow_QT(const char* name); +void cvSetModeWindow_QT(const char* name, double prop_value); + +double cvGetPropWindow_QT(const char* name); +void cvSetPropWindow_QT(const char* name,double prop_value); + +double cvGetRatioWindow_QT(const char* name); +void cvSetRatioWindow_QT(const char* name,double prop_value); + +double cvGetOpenGlProp_QT(const char* name); +#endif + + + +/*namespace cv +{ + +class CV_EXPORTS BaseWindow +{ +public: + BaseWindow(const String& name, int flags=0); + virtual ~BaseWindow(); + virtual void close(); + virtual void show(const Mat& mat); + virtual void resize(Size size); + virtual void move(Point topleft); + virtual Size size() const; + virtual Point topLeft() const; + virtual void setGeometry(Point topLeft, Size size); + virtual void getGeometry(Point& topLeft, Size& size) const; + virtual String getTitle() const; + virtual void setTitle(const String& str); + virtual String getName() const; + virtual void setScaleMode(int mode); + virtual int getScaleMode(); + virtual void setScrollPos(double pos); + virtual double getScrollPos() const; + virtual void setScale(double scale); + virtual double getScale() const; + virtual Point getImageCoords(Point pos) const; + virtual Scalar getPixelValue(Point pos, const String& colorspace=String()) const; + + virtual void addTrackbar( const String& trackbar, int low, int high, int step ); +}; + +typedef Ptr Window; + +}*/ + +#endif /* __HIGHGUI_H_ */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/utils.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/utils.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/utils.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,689 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "utils.hpp" + +#define SCALE 14 +#define cR (int)(0.299*(1 << SCALE) + 0.5) +#define cG (int)(0.587*(1 << SCALE) + 0.5) +#define cB ((1 << SCALE) - cR - cG) + +void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step, + uchar* gray, int gray_step, + CvSize size, int _swap_rb ) +{ + int i; + int swap_rb = _swap_rb ? 2 : 0; + for( ; size.height--; gray += gray_step ) + { + for( i = 0; i < size.width; i++, rgb += 3 ) + { + int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE ); + gray[i] = (uchar)t; + } + + rgb += rgb_step - size.width*3; + } +} + + +void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step, + ushort* gray, int gray_step, + CvSize size, int ncn, int _swap_rb ) +{ + int i; + int swap_rb = _swap_rb ? 2 : 0; + for( ; size.height--; gray += gray_step ) + { + for( i = 0; i < size.width; i++, rgb += ncn ) + { + int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE ); + gray[i] = (ushort)t; + } + + rgb += rgb_step - size.width*ncn; + } +} + + +void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step, + uchar* gray, int gray_step, + CvSize size, int _swap_rb ) +{ + int i; + int swap_rb = _swap_rb ? 2 : 0; + for( ; size.height--; gray += gray_step ) + { + for( i = 0; i < size.width; i++, rgba += 4 ) + { + int t = descale( rgba[swap_rb]*cB + rgba[1]*cG + rgba[swap_rb^2]*cR, SCALE ); + gray[i] = (uchar)t; + } + + rgba += rgba_step - size.width*4; + } +} + + +void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step, + uchar* bgr, int bgr_step, CvSize size ) +{ + int i; + for( ; size.height--; gray += gray_step ) + { + for( i = 0; i < size.width; i++, bgr += 3 ) + { + bgr[0] = bgr[1] = bgr[2] = gray[i]; + } + bgr += bgr_step - size.width*3; + } +} + + +void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step, + ushort* bgr, int bgr_step, CvSize size ) +{ + int i; + for( ; size.height--; gray += gray_step/sizeof(gray[0]) ) + { + for( i = 0; i < size.width; i++, bgr += 3 ) + { + bgr[0] = bgr[1] = bgr[2] = gray[i]; + } + bgr += bgr_step/sizeof(bgr[0]) - size.width*3; + } +} + + +void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step, + uchar* bgr, int bgr_step, + CvSize size, int _swap_rb ) +{ + int i; + int swap_rb = _swap_rb ? 2 : 0; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 ) + { + uchar t0 = bgra[swap_rb], t1 = bgra[1]; + bgr[0] = t0; bgr[1] = t1; + t0 = bgra[swap_rb^2]; bgr[2] = t0; + } + bgr += bgr_step - size.width*3; + bgra += bgra_step - size.width*4; + } +} + + +void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step, + ushort* bgr, int bgr_step, + CvSize size, int _swap_rb ) +{ + int i; + int swap_rb = _swap_rb ? 2 : 0; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 ) + { + ushort t0 = bgra[swap_rb], t1 = bgra[1]; + bgr[0] = t0; bgr[1] = t1; + t0 = bgra[swap_rb^2]; bgr[2] = t0; + } + bgr += bgr_step/sizeof(bgr[0]) - size.width*3; + bgra += bgra_step/sizeof(bgra[0]) - size.width*4; + } +} + + +void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step, + uchar* rgba, int rgba_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 ) + { + uchar t0 = bgra[0], t1 = bgra[1]; + uchar t2 = bgra[2], t3 = bgra[3]; + rgba[0] = t2; rgba[1] = t1; + rgba[2] = t0; rgba[3] = t3; + } + bgra += bgra_step - size.width*4; + rgba += rgba_step - size.width*4; + } +} + +void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step, + ushort* rgba, int rgba_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 ) + { + ushort t0 = bgra[0], t1 = bgra[1]; + ushort t2 = bgra[2], t3 = bgra[3]; + + rgba[0] = t2; rgba[1] = t1; + rgba[2] = t0; rgba[3] = t3; + } + bgra += bgra_step/sizeof(bgra[0]) - size.width*4; + rgba += rgba_step/sizeof(rgba[0]) - size.width*4; + } +} + + +void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step, + uchar* rgb, int rgb_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 ) + { + uchar t0 = bgr[0], t1 = bgr[1], t2 = bgr[2]; + rgb[2] = t0; rgb[1] = t1; rgb[0] = t2; + } + bgr += bgr_step - size.width*3; + rgb += rgb_step - size.width*3; + } +} + + +void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step, + ushort* rgb, int rgb_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 ) + { + ushort t0 = bgr[0], t1 = bgr[1], t2 = bgr[2]; + rgb[2] = t0; rgb[1] = t1; rgb[0] = t2; + } + bgr += bgr_step - size.width*3; + rgb += rgb_step - size.width*3; + } +} + + +typedef unsigned short ushort; + +void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step, + uchar* gray, int gray_step, CvSize size ) +{ + int i; + for( ; size.height--; gray += gray_step, bgr555 += bgr555_step ) + { + for( i = 0; i < size.width; i++ ) + { + int t = descale( ((((ushort*)bgr555)[i] << 3) & 0xf8)*cB + + ((((ushort*)bgr555)[i] >> 2) & 0xf8)*cG + + ((((ushort*)bgr555)[i] >> 7) & 0xf8)*cR, SCALE ); + gray[i] = (uchar)t; + } + } +} + + +void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step, + uchar* gray, int gray_step, CvSize size ) +{ + int i; + for( ; size.height--; gray += gray_step, bgr565 += bgr565_step ) + { + for( i = 0; i < size.width; i++ ) + { + int t = descale( ((((ushort*)bgr565)[i] << 3) & 0xf8)*cB + + ((((ushort*)bgr565)[i] >> 3) & 0xfc)*cG + + ((((ushort*)bgr565)[i] >> 8) & 0xf8)*cR, SCALE ); + gray[i] = (uchar)t; + } + } +} + + +void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step, + uchar* bgr, int bgr_step, CvSize size ) +{ + int i; + for( ; size.height--; bgr555 += bgr555_step ) + { + for( i = 0; i < size.width; i++, bgr += 3 ) + { + int t0 = (((ushort*)bgr555)[i] << 3) & 0xf8; + int t1 = (((ushort*)bgr555)[i] >> 2) & 0xf8; + int t2 = (((ushort*)bgr555)[i] >> 7) & 0xf8; + bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2; + } + bgr += bgr_step - size.width*3; + } +} + + +void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step, + uchar* bgr, int bgr_step, CvSize size ) +{ + int i; + for( ; size.height--; bgr565 += bgr565_step ) + { + for( i = 0; i < size.width; i++, bgr += 3 ) + { + int t0 = (((ushort*)bgr565)[i] << 3) & 0xf8; + int t1 = (((ushort*)bgr565)[i] >> 3) & 0xfc; + int t2 = (((ushort*)bgr565)[i] >> 8) & 0xf8; + bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2; + } + bgr += bgr_step - size.width*3; + } +} + + +void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step, + uchar* bgr, int bgr_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgr += 3, cmyk += 4 ) + { + int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3]; + c = k - ((255 - c)*k>>8); + m = k - ((255 - m)*k>>8); + y = k - ((255 - y)*k>>8); + bgr[2] = (uchar)c; bgr[1] = (uchar)m; bgr[0] = (uchar)y; + } + bgr += bgr_step - size.width*3; + cmyk += cmyk_step - size.width*4; + } +} + + +void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* cmyk, int cmyk_step, + uchar* gray, int gray_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, cmyk += 4 ) + { + int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3]; + c = k - ((255 - c)*k>>8); + m = k - ((255 - m)*k>>8); + y = k - ((255 - y)*k>>8); + int t = descale( y*cB + m*cG + c*cR, SCALE ); + gray[i] = (uchar)t; + } + gray += gray_step; + cmyk += cmyk_step - size.width*4; + } +} + + +void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries ) +{ + int i; + for( i = 0; i < entries; i++ ) + { + icvCvt_BGR2Gray_8u_C3C1R( (uchar*)(palette + i), 0, grayPalette + i, 0, cvSize(1,1) ); + } +} + + +void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative ) +{ + int i, length = 1 << bpp; + int xor_mask = negative ? 255 : 0; + + for( i = 0; i < length; i++ ) + { + int val = (i * 255/(length - 1)) ^ xor_mask; + palette[i].b = palette[i].g = palette[i].r = (uchar)val; + palette[i].a = 0; + } +} + + +bool IsColorPalette( PaletteEntry* palette, int bpp ) +{ + int i, length = 1 << bpp; + + for( i = 0; i < length; i++ ) + { + if( palette[i].b != palette[i].g || + palette[i].b != palette[i].r ) + return true; + } + + return false; +} + + +uchar* FillUniColor( uchar* data, uchar*& line_end, + int step, int width3, + int& y, int height, + int count3, PaletteEntry clr ) +{ + do + { + uchar* end = data + count3; + + if( end > line_end ) + end = line_end; + + count3 -= (int)(end - data); + + for( ; data < end; data += 3 ) + { + WRITE_PIX( data, clr ); + } + + if( data >= line_end ) + { + line_end += step; + data = line_end - width3; + if( ++y >= height ) break; + } + } + while( count3 > 0 ); + + return data; +} + + +uchar* FillUniGray( uchar* data, uchar*& line_end, + int step, int width, + int& y, int height, + int count, uchar clr ) +{ + do + { + uchar* end = data + count; + + if( end > line_end ) + end = line_end; + + count -= (int)(end - data); + + for( ; data < end; data++ ) + { + *data = clr; + } + + if( data >= line_end ) + { + line_end += step; + data = line_end - width; + if( ++y >= height ) break; + } + } + while( count > 0 ); + + return data; +} + + +uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette ) +{ + uchar* end = data + len*3; + while( (data += 3) < end ) + { + *((PaletteEntry*)(data-3)) = palette[*indices++]; + } + PaletteEntry clr = palette[indices[0]]; + WRITE_PIX( data - 3, clr ); + return data; +} + + +uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette ) +{ + int i; + for( i = 0; i < len; i++ ) + { + data[i] = palette[indices[i]]; + } + return data + len; +} + + +uchar* FillColorRow4( uchar* data, uchar* indices, int len, PaletteEntry* palette ) +{ + uchar* end = data + len*3; + + while( (data += 6) < end ) + { + int idx = *indices++; + *((PaletteEntry*)(data-6)) = palette[idx >> 4]; + *((PaletteEntry*)(data-3)) = palette[idx & 15]; + } + + int idx = indices[0]; + PaletteEntry clr = palette[idx >> 4]; + WRITE_PIX( data - 6, clr ); + + if( data == end ) + { + clr = palette[idx & 15]; + WRITE_PIX( data - 3, clr ); + } + return end; +} + + +uchar* FillGrayRow4( uchar* data, uchar* indices, int len, uchar* palette ) +{ + uchar* end = data + len; + while( (data += 2) < end ) + { + int idx = *indices++; + data[-2] = palette[idx >> 4]; + data[-1] = palette[idx & 15]; + } + + int idx = indices[0]; + uchar clr = palette[idx >> 4]; + data[-2] = clr; + + if( data == end ) + { + clr = palette[idx & 15]; + data[-1] = clr; + } + return end; +} + + +uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palette ) +{ + uchar* end = data + len*3; + + while( (data += 24) < end ) + { + int idx = *indices++; + *((PaletteEntry*)(data - 24)) = palette[(idx & 128) != 0]; + *((PaletteEntry*)(data - 21)) = palette[(idx & 64) != 0]; + *((PaletteEntry*)(data - 18)) = palette[(idx & 32) != 0]; + *((PaletteEntry*)(data - 15)) = palette[(idx & 16) != 0]; + *((PaletteEntry*)(data - 12)) = palette[(idx & 8) != 0]; + *((PaletteEntry*)(data - 9)) = palette[(idx & 4) != 0]; + *((PaletteEntry*)(data - 6)) = palette[(idx & 2) != 0]; + *((PaletteEntry*)(data - 3)) = palette[(idx & 1) != 0]; + } + + int idx = indices[0] << 24; + for( data -= 24; data < end; data += 3, idx += idx ) + { + PaletteEntry clr = palette[idx < 0]; + WRITE_PIX( data, clr ); + } + + return data; +} + + +uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette ) +{ + uchar* end = data + len; + + while( (data += 8) < end ) + { + int idx = *indices++; + *((uchar*)(data - 8)) = palette[(idx & 128) != 0]; + *((uchar*)(data - 7)) = palette[(idx & 64) != 0]; + *((uchar*)(data - 6)) = palette[(idx & 32) != 0]; + *((uchar*)(data - 5)) = palette[(idx & 16) != 0]; + *((uchar*)(data - 4)) = palette[(idx & 8) != 0]; + *((uchar*)(data - 3)) = palette[(idx & 4) != 0]; + *((uchar*)(data - 2)) = palette[(idx & 2) != 0]; + *((uchar*)(data - 1)) = palette[(idx & 1) != 0]; + } + + int idx = indices[0] << 24; + for( data -= 8; data < end; data++, idx += idx ) + { + data[0] = palette[idx < 0]; + } + + return data; +} + + +CV_IMPL void +cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags ) +{ + CvMat* temp = 0; + + CV_FUNCNAME( "cvConvertImage" ); + + __BEGIN__; + + CvMat srcstub, *src; + CvMat dststub, *dst; + int src_cn, dst_cn, swap_rb = flags & CV_CVTIMG_SWAP_RB; + + CV_CALL( src = cvGetMat( srcarr, &srcstub )); + CV_CALL( dst = cvGetMat( dstarr, &dststub )); + + src_cn = CV_MAT_CN( src->type ); + dst_cn = CV_MAT_CN( dst->type ); + + if( src_cn != 1 && src_cn != 3 && src_cn != 4 ) + CV_ERROR( CV_BadNumChannels, "Source image must have 1, 3 or 4 channels" ); + + if( CV_MAT_DEPTH( dst->type ) != CV_8U ) + CV_ERROR( CV_BadDepth, "Destination image must be 8u" ); + + if( CV_MAT_CN(dst->type) != 1 && CV_MAT_CN(dst->type) != 3 ) + CV_ERROR( CV_BadNumChannels, "Destination image must have 1 or 3 channels" ); + + if( !CV_ARE_DEPTHS_EQ( src, dst )) + { + int src_depth = CV_MAT_DEPTH(src->type); + double scale = src_depth <= CV_8S ? 1 : src_depth <= CV_32S ? 1./256 : 255; + double shift = src_depth == CV_8S || src_depth == CV_16S ? 128 : 0; + + if( !CV_ARE_CNS_EQ( src, dst )) + { + temp = cvCreateMat( src->height, src->width, + (src->type & CV_MAT_CN_MASK)|(dst->type & CV_MAT_DEPTH_MASK)); + cvConvertScale( src, temp, scale, shift ); + src = temp; + } + else + { + cvConvertScale( src, dst, scale, shift ); + src = dst; + } + } + + if( src_cn != dst_cn || (src_cn == 3 && swap_rb) ) + { + uchar *s = src->data.ptr, *d = dst->data.ptr; + int s_step = src->step, d_step = dst->step; + int code = src_cn*10 + dst_cn; + CvSize size = { src->cols, src->rows }; + + if( CV_IS_MAT_CONT(src->type & dst->type) ) + { + size.width *= size.height; + size.height = 1; + s_step = d_step = CV_STUB_STEP; + } + + switch( code ) + { + case 13: + icvCvt_Gray2BGR_8u_C1C3R( s, s_step, d, d_step, size ); + break; + case 31: + icvCvt_BGR2Gray_8u_C3C1R( s, s_step, d, d_step, size, swap_rb ); + break; + case 33: + assert( swap_rb ); + icvCvt_RGB2BGR_8u_C3R( s, s_step, d, d_step, size ); + break; + case 41: + icvCvt_BGRA2Gray_8u_C4C1R( s, s_step, d, d_step, size, swap_rb ); + break; + case 43: + icvCvt_BGRA2BGR_8u_C4C3R( s, s_step, d, d_step, size, swap_rb ); + break; + default: + CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input/output formats" ); + } + src = dst; + } + + if( flags & CV_CVTIMG_FLIP ) + { + CV_CALL( cvFlip( src, dst, 0 )); + } + else if( src != dst ) + { + CV_CALL( cvCopy( src, dst )); + } + + __END__; + + cvReleaseMat( &temp ); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/utils.hpp diffimg-2.0.0/3rdparty/opencv/highgui/src/utils.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/utils.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/utils.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,128 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +struct PaletteEntry +{ + unsigned char b, g, r, a; +}; + +#define WRITE_PIX( ptr, clr ) \ + (((uchar*)(ptr))[0] = (clr).b, \ + ((uchar*)(ptr))[1] = (clr).g, \ + ((uchar*)(ptr))[2] = (clr).r) + +#define descale(x,n) (((x) + (1 << ((n)-1))) >> (n)) +#define saturate(x) (uchar)(((x) & ~255) == 0 ? (x) : ~((x)>>31)) + +void icvCvt_BGR2Gray_8u_C3C1R( const uchar* bgr, int bgr_step, + uchar* gray, int gray_step, + CvSize size, int swap_rb=0 ); +void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int bgra_step, + uchar* gray, int gray_step, + CvSize size, int swap_rb=0 ); +void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgra, int bgra_step, + ushort* gray, int gray_step, + CvSize size, int ncn, int swap_rb=0 ); + +void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step, + uchar* bgr, int bgr_step, CvSize size ); +void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step, + ushort* bgr, int bgr_step, CvSize size ); + +void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step, + uchar* bgr, int bgr_step, + CvSize size, int swap_rb=0 ); +void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step, + ushort* bgr, int bgr_step, + CvSize size, int _swap_rb ); + +void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step, + uchar* rgb, int rgb_step, CvSize size ); +#define icvCvt_RGB2BGR_8u_C3R icvCvt_BGR2RGB_8u_C3R +void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step, + ushort* rgb, int rgb_step, CvSize size ); +#define icvCvt_RGB2BGR_16u_C3R icvCvt_BGR2RGB_16u_C3R + +void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step, + uchar* rgba, int rgba_step, CvSize size ); +#define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R + +void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step, + ushort* rgba, int rgba_step, CvSize size ); +#define icvCvt_RGBA2BGRA_16u_C4R icvCvt_BGRA2RGBA_16u_C4R + +void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step, + uchar* gray, int gray_step, CvSize size ); +void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step, + uchar* gray, int gray_step, CvSize size ); +void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step, + uchar* bgr, int bgr_step, CvSize size ); +void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step, + uchar* bgr, int bgr_step, CvSize size ); +void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step, + uchar* bgr, int bgr_step, CvSize size ); +void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* ycck, int ycck_step, + uchar* gray, int gray_step, CvSize size ); + +void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative = false ); +bool IsColorPalette( PaletteEntry* palette, int bpp ); +void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries ); +uchar* FillUniColor( uchar* data, uchar*& line_end, int step, int width3, + int& y, int height, int count3, PaletteEntry clr ); +uchar* FillUniGray( uchar* data, uchar*& line_end, int step, int width3, + int& y, int height, int count3, uchar clr ); + +uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette ); +uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette ); +uchar* FillColorRow4( uchar* data, uchar* indices, int len, PaletteEntry* palette ); +uchar* FillGrayRow4( uchar* data, uchar* indices, int len, uchar* palette ); +uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palette ); +uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette ); + +CV_INLINE bool isBigEndian( void ) +{ + return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0; +} + +#endif/*_UTILS_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/window.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,623 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include +#include "opencv2/core/opengl_interop.hpp" + +// in later times, use this file as a dispatcher to implementations like cvcap.cpp + +CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_value) +{ + switch(prop_id) + { + //change between fullscreen or not. + case CV_WND_PROP_FULLSCREEN: + + if (!name || (prop_value!=CV_WINDOW_NORMAL && prop_value!=CV_WINDOW_FULLSCREEN))//bad argument + break; + + #if defined (HAVE_QT) + cvSetModeWindow_QT(name,prop_value); + #elif defined(HAVE_WIN32UI) + cvSetModeWindow_W32(name,prop_value); + #elif defined (HAVE_GTK) + cvSetModeWindow_GTK(name,prop_value); + #elif defined (HAVE_CARBON) + cvSetModeWindow_CARBON(name,prop_value); + #elif defined (HAVE_COCOA) + cvSetModeWindow_COCOA(name,prop_value); + #endif + break; + + case CV_WND_PROP_AUTOSIZE: + #if defined (HAVE_QT) + cvSetPropWindow_QT(name,prop_value); + #endif + break; + + case CV_WND_PROP_ASPECTRATIO: + #if defined (HAVE_QT) + cvSetRatioWindow_QT(name,prop_value); + #endif + break; + + default:; + } +} + +/* return -1 if error */ +CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) +{ + if (!name) + return -1; + + switch(prop_id) + { + case CV_WND_PROP_FULLSCREEN: + + #if defined (HAVE_QT) + return cvGetModeWindow_QT(name); + #elif defined(HAVE_WIN32UI) + return cvGetModeWindow_W32(name); + #elif defined (HAVE_GTK) + return cvGetModeWindow_GTK(name); + #elif defined (HAVE_CARBON) + return cvGetModeWindow_CARBON(name); + #elif defined (HAVE_COCOA) + return cvGetModeWindow_COCOA(name); + #else + return -1; + #endif + break; + + case CV_WND_PROP_AUTOSIZE: + + #if defined (HAVE_QT) + return cvGetPropWindow_QT(name); + #elif defined(HAVE_WIN32UI) + return cvGetPropWindowAutoSize_W32(name); + #elif defined (HAVE_GTK) + return cvGetPropWindowAutoSize_GTK(name); + #else + return -1; + #endif + break; + + case CV_WND_PROP_ASPECTRATIO: + + #if defined (HAVE_QT) + return cvGetRatioWindow_QT(name); + #elif defined(HAVE_WIN32UI) + return cvGetRatioWindow_W32(name); + #elif defined (HAVE_GTK) + return cvGetRatioWindow_GTK(name); + #else + return -1; + #endif + break; + + case CV_WND_PROP_OPENGL: + + #if defined (HAVE_QT) + return cvGetOpenGlProp_QT(name); + #elif defined(HAVE_WIN32UI) + return cvGetOpenGlProp_W32(name); + #elif defined (HAVE_GTK) + return cvGetOpenGlProp_GTK(name); + #else + return -1; + #endif + break; + + default: + return -1; + } +} + +void cv::namedWindow( const string& winname, int flags ) +{ + cvNamedWindow( winname.c_str(), flags ); +} + +void cv::destroyWindow( const string& winname ) +{ + cvDestroyWindow( winname.c_str() ); +} + +void cv::destroyAllWindows() +{ + cvDestroyAllWindows(); +} + +void cv::resizeWindow( const string& winname, int width, int height ) +{ + cvResizeWindow( winname.c_str(), width, height ); +} + +void cv::moveWindow( const string& winname, int x, int y ) +{ + cvMoveWindow( winname.c_str(), x, y ); +} + +void cv::setWindowProperty(const string& winname, int prop_id, double prop_value) +{ + cvSetWindowProperty( winname.c_str(), prop_id, prop_value); +} + +double cv::getWindowProperty(const string& winname, int prop_id) +{ + return cvGetWindowProperty(winname.c_str(), prop_id); +} + +int cv::waitKey(int delay) +{ + return cvWaitKey(delay); +} + +int cv::createTrackbar(const string& trackbarName, const string& winName, + int* value, int count, TrackbarCallback callback, + void* userdata) +{ + return cvCreateTrackbar2(trackbarName.c_str(), winName.c_str(), + value, count, callback, userdata); +} + +void cv::setTrackbarPos( const string& trackbarName, const string& winName, int value ) +{ + cvSetTrackbarPos(trackbarName.c_str(), winName.c_str(), value ); +} + +int cv::getTrackbarPos( const string& trackbarName, const string& winName ) +{ + return cvGetTrackbarPos(trackbarName.c_str(), winName.c_str()); +} + +void cv::setMouseCallback( const string& windowName, MouseCallback onMouse, void* param) +{ + cvSetMouseCallback(windowName.c_str(), onMouse, param); +} + +int cv::startWindowThread() +{ + return cvStartWindowThread(); +} + +// OpenGL support + +void cv::setOpenGlDrawCallback(const string& name, OpenGlDrawCallback callback, void* userdata) +{ + cvSetOpenGlDrawCallback(name.c_str(), callback, userdata); +} + +void cv::setOpenGlContext(const string& windowName) +{ + cvSetOpenGlContext(windowName.c_str()); +} + +void cv::updateWindow(const string& windowName) +{ + cvUpdateWindow(windowName.c_str()); +} + +#ifdef HAVE_OPENGL +namespace +{ + std::map wndTexs; + std::map ownWndTexs; + std::map ownWndBufs; + + void glDrawTextureCallback(void* userdata) + { + cv::ogl::Texture2D* texObj = static_cast(userdata); + + cv::ogl::render(*texObj); + } +} +#endif // HAVE_OPENGL + +void cv::imshow( const string& winname, InputArray _img ) +{ +#ifndef HAVE_OPENGL + Mat img = _img.getMat(); + CvMat c_img = img; + cvShowImage(winname.c_str(), &c_img); +#else + const double useGl = getWindowProperty(winname, WND_PROP_OPENGL); + + if (useGl <= 0) + { + Mat img = _img.getMat(); + CvMat c_img = img; + cvShowImage(winname.c_str(), &c_img); + } + else + { + const double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE); + + if (autoSize > 0) + { + Size size = _img.size(); + resizeWindow(winname, size.width, size.height); + } + + setOpenGlContext(winname); + + if (_img.kind() == _InputArray::OPENGL_TEXTURE) + { + cv::ogl::Texture2D& tex = wndTexs[winname]; + + tex = _img.getOGlTexture2D(); + + tex.setAutoRelease(false); + + setOpenGlDrawCallback(winname, glDrawTextureCallback, &tex); + } + else + { + cv::ogl::Texture2D& tex = ownWndTexs[winname]; + + if (_img.kind() == _InputArray::GPU_MAT) + { + cv::ogl::Buffer& buf = ownWndBufs[winname]; + buf.copyFrom(_img); + buf.setAutoRelease(false); + + tex.copyFrom(buf); + tex.setAutoRelease(false); + } + else + { + tex.copyFrom(_img); + } + + tex.setAutoRelease(false); + + setOpenGlDrawCallback(winname, glDrawTextureCallback, &tex); + } + + updateWindow(winname); + } +#endif +} + +void cv::pointCloudShow(const string&, const GlCamera&, const GlArrays&) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +void cv::pointCloudShow(const string&, const GlCamera&, InputArray, InputArray) +{ + CV_Error(CV_StsNotImplemented, "This function in deprecated, do not use it"); +} + +// Without OpenGL + +#ifndef HAVE_OPENGL + +CV_IMPL void cvSetOpenGlDrawCallback(const char*, CvOpenGlDrawCallback, void*) +{ + CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); +} + +CV_IMPL void cvSetOpenGlContext(const char*) +{ + CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); +} + +CV_IMPL void cvUpdateWindow(const char*) +{ + CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); +} + +#endif // !HAVE_OPENGL + +#if defined (HAVE_QT) + +CvFont cv::fontQt(const string& nameFont, int pointSize, Scalar color, int weight, int style, int /*spacing*/) +{ +return cvFontQt(nameFont.c_str(), pointSize,color,weight, style); +} + +void cv::addText( const Mat& img, const string& text, Point org, CvFont font) +{ + CvMat _img = img; + cvAddText( &_img, text.c_str(), org,&font); +} + +void cv::displayStatusBar(const string& name, const string& text, int delayms) +{ + cvDisplayStatusBar(name.c_str(),text.c_str(), delayms); +} + +void cv::displayOverlay(const string& name, const string& text, int delayms) +{ + cvDisplayOverlay(name.c_str(),text.c_str(), delayms); +} + +int cv::startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]) +{ + return cvStartLoop(pt2Func, argc, argv); +} + +void cv::stopLoop() +{ + cvStopLoop(); +} + +void cv::saveWindowParameters(const string& windowName) +{ + cvSaveWindowParameters(windowName.c_str()); +} + +void cv::loadWindowParameters(const string& windowName) +{ + cvLoadWindowParameters(windowName.c_str()); +} + +int cv::createButton(const string& button_name, ButtonCallback on_change, void* userdata, int button_type , bool initial_button_state ) +{ + return cvCreateButton(button_name.c_str(), on_change, userdata, button_type , initial_button_state ); +} + +#else + +CvFont cv::fontQt(const string&, int, Scalar, int, int, int) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return CvFont(); +} + +void cv::addText( const Mat&, const string&, Point, CvFont) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::displayStatusBar(const string&, const string&, int) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::displayOverlay(const string&, const string&, int ) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +int cv::startLoop(int (*)(int argc, char *argv[]), int , char**) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return 0; +} + +void cv::stopLoop() +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::saveWindowParameters(const string&) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::loadWindowParameters(const string&) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +int cv::createButton(const string&, ButtonCallback, void*, int , bool ) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return 0; +} + +#endif + +#if defined(HAVE_WIN32UI) // see window_w32.cpp +#elif defined (HAVE_GTK) // see window_gtk.cpp +#elif defined (HAVE_COCOA) // see window_carbon.cpp +#elif defined (HAVE_CARBON) +#elif defined (HAVE_QT) //YV see window_QT.cpp + +#else + +// No windowing system present at compile time ;-( +// +// We will build place holders that don't break the API but give an error +// at runtime. This way people can choose to replace an installed HighGUI +// version with a more capable one without a need to recompile dependent +// applications or libraries. + + +#define CV_NO_GUI_ERROR(funcname) \ + cvError( CV_StsError, funcname, \ + "The function is not implemented. " \ + "Rebuild the library with Windows, GTK+ 2.x or Carbon support. "\ + "If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script", \ + __FILE__, __LINE__ ) + + +CV_IMPL int cvNamedWindow( const char*, int ) +{ + CV_NO_GUI_ERROR("cvNamedWindow"); + return -1; +} + +CV_IMPL void cvDestroyWindow( const char* ) +{ + CV_NO_GUI_ERROR( "cvDestroyWindow" ); +} + +CV_IMPL void +cvDestroyAllWindows( void ) +{ + CV_NO_GUI_ERROR( "cvDestroyAllWindows" ); +} + +CV_IMPL void +cvShowImage( const char*, const CvArr* ) +{ + CV_NO_GUI_ERROR( "cvShowImage" ); +} + +CV_IMPL void cvResizeWindow( const char*, int, int ) +{ + CV_NO_GUI_ERROR( "cvResizeWindow" ); +} + +CV_IMPL void cvMoveWindow( const char*, int, int ) +{ + CV_NO_GUI_ERROR( "cvMoveWindow" ); +} + +CV_IMPL int +cvCreateTrackbar( const char*, const char*, + int*, int, CvTrackbarCallback ) +{ + CV_NO_GUI_ERROR( "cvCreateTrackbar" ); + return -1; +} + +CV_IMPL int +cvCreateTrackbar2( const char* /*trackbar_name*/, const char* /*window_name*/, + int* /*val*/, int /*count*/, CvTrackbarCallback2 /*on_notify2*/, + void* /*userdata*/ ) +{ + CV_NO_GUI_ERROR( "cvCreateTrackbar2" ); + return -1; +} + +CV_IMPL void +cvSetMouseCallback( const char*, CvMouseCallback, void* ) +{ + CV_NO_GUI_ERROR( "cvSetMouseCallback" ); +} + +CV_IMPL int cvGetTrackbarPos( const char*, const char* ) +{ + CV_NO_GUI_ERROR( "cvGetTrackbarPos" ); + return -1; +} + +CV_IMPL void cvSetTrackbarPos( const char*, const char*, int ) +{ + CV_NO_GUI_ERROR( "cvSetTrackbarPos" ); +} + +CV_IMPL void* cvGetWindowHandle( const char* ) +{ + CV_NO_GUI_ERROR( "cvGetWindowHandle" ); + return 0; +} + +CV_IMPL const char* cvGetWindowName( void* ) +{ + CV_NO_GUI_ERROR( "cvGetWindowName" ); + return 0; +} + +CV_IMPL int cvWaitKey( int ) +{ + CV_NO_GUI_ERROR( "cvWaitKey" ); + return -1; +} + +CV_IMPL int cvInitSystem( int , char** ) +{ + + CV_NO_GUI_ERROR( "cvInitSystem" ); + return -1; +} + +CV_IMPL int cvStartWindowThread() +{ + + CV_NO_GUI_ERROR( "cvStartWindowThread" ); + return -1; +} + +//-------- Qt --------- +CV_IMPL void cvAddText( const CvArr*, const char*, CvPoint , CvFont* ) +{ + CV_NO_GUI_ERROR("cvAddText"); +} + +CV_IMPL void cvDisplayStatusBar(const char* , const char* , int ) +{ + CV_NO_GUI_ERROR("cvDisplayStatusBar"); +} + +CV_IMPL void cvDisplayOverlay(const char* , const char* , int ) +{ + CV_NO_GUI_ERROR("cvNamedWindow"); +} + +CV_IMPL int cvStartLoop(int (*)(int argc, char *argv[]), int , char* argv[]) +{ + (void)argv; + CV_NO_GUI_ERROR("cvStartLoop"); + return -1; +} + +CV_IMPL void cvStopLoop() +{ + CV_NO_GUI_ERROR("cvStopLoop"); +} + +CV_IMPL void cvSaveWindowParameters(const char* ) +{ + CV_NO_GUI_ERROR("cvSaveWindowParameters"); +} + +// CV_IMPL void cvLoadWindowParameterss(const char* name) +// { +// CV_NO_GUI_ERROR("cvLoadWindowParameters"); +// } + +CV_IMPL int cvCreateButton(const char*, void (*)(int, void*), void*, int, int) +{ + CV_NO_GUI_ERROR("cvCreateButton"); + return -1; +} + + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3234 @@ +//IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. + + +// License Agreement +// For Open Source Computer Vision Library + +//Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +//Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved. +//Third party copyrights are property of their respective owners. + +//Redistribution and use in source and binary forms, with or without modification, +//are permitted provided that the following conditions are met: + +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. + +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. + +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. + +//This software is provided by the copyright holders and contributors "as is" and +//any express or implied warranties, including, but not limited to, the implied +//warranties of merchantability and fitness for a particular purpose are disclaimed. +//In no event shall the Intel Corporation or contributors be liable for any direct, +//indirect, incidental, special, exemplary, or consequential damages +//(including, but not limited to, procurement of substitute goods or services; +//loss of use, data, or profits; or business interruption) however caused +//and on any theory of liability, whether in contract, strict liability, +//or tort (including negligence or otherwise) arising in any way out of +//the use of this software, even if advised of the possibility of such damage. + +//--------------------Google Code 2010 -- Yannick Verdie--------------------// + + +#if defined(HAVE_QT) + +#include + +#include + +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#ifdef HAVE_QT_OPENGL + #ifdef Q_WS_X11 + #include + #endif +#endif + + +//Static and global first +static GuiReceiver *guiMainThread = NULL; +static int parameterSystemC = 1; +static char* parameterSystemV[] = {(char*)""}; +static bool multiThreads = false; +static int last_key = -1; +QWaitCondition key_pressed; +QMutex mutexKey; +static const unsigned int threshold_zoom_img_region = 30; +//the minimum zoom value to start displaying the values in the grid +//that is also the number of pixel per grid + +static CvWinProperties* global_control_panel = NULL; +//end static and global + + +CV_IMPL CvFont cvFontQt(const char* nameFont, int pointSize,CvScalar color,int weight,int style, int spacing) +{ + /* + //nameFont <- only Qt + //CvScalar color <- only Qt (blue_component, green_component, red\_component[, alpha_component]) + int font_face;//<- style in Qt + const int* ascii; + const int* greek; + const int* cyrillic; + float hscale, vscale; + float shear; + int thickness;//<- weight in Qt + float dx;//spacing letter in Qt (0 default) in pixel + int line_type;//<- pointSize in Qt + */ + CvFont f = {nameFont,color,style,NULL,NULL,NULL,0,0,0,weight,spacing,pointSize}; + return f; +} + + +CV_IMPL void cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont* font) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "putText", + Qt::AutoConnection, + Q_ARG(void*, (void*) img), + Q_ARG(QString,QString(text)), + Q_ARG(QPoint, QPoint(org.x,org.y)), + Q_ARG(void*,(void*) font)); +} + + +double cvGetRatioWindow_QT(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + double result = -1; + QMetaObject::invokeMethod(guiMainThread, + "getRatioWindow", + //Qt::DirectConnection, + Qt::AutoConnection, + Q_RETURN_ARG(double, result), + Q_ARG(QString, QString(name))); + + return result; +} + + +void cvSetRatioWindow_QT(const char* name,double prop_value) +{ + + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "setRatioWindow", + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(double, prop_value)); +} + + +double cvGetPropWindow_QT(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + double result = -1; + QMetaObject::invokeMethod(guiMainThread, + "getPropWindow", + //Qt::DirectConnection, + Qt::AutoConnection, + Q_RETURN_ARG(double, result), + Q_ARG(QString, QString(name))); + + return result; +} + + +void cvSetPropWindow_QT(const char* name,double prop_value) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "setPropWindow", + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(double, prop_value)); +} + + +void cvSetModeWindow_QT(const char* name, double prop_value) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "toggleFullScreen", + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(double, prop_value)); +} + + +double cvGetModeWindow_QT(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + double result = -1; + + QMetaObject::invokeMethod(guiMainThread, + "isFullScreen", + Qt::AutoConnection, + Q_RETURN_ARG(double, result), + Q_ARG(QString, QString(name))); + + return result; +} + + +CV_IMPL void cvDisplayOverlay(const char* name, const char* text, int delayms) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "displayInfo", + Qt::AutoConnection, + //Qt::DirectConnection, + Q_ARG(QString, QString(name)), + Q_ARG(QString, QString(text)), + Q_ARG(int, delayms)); +} + + +CV_IMPL void cvSaveWindowParameters(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "saveWindowParameters", + Qt::AutoConnection, + Q_ARG(QString, QString(name))); +} + + +CV_IMPL void cvLoadWindowParameters(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "loadWindowParameters", + Qt::AutoConnection, + Q_ARG(QString, QString(name))); +} + + +CV_IMPL void cvDisplayStatusBar(const char* name, const char* text, int delayms) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "displayStatusBar", + Qt::AutoConnection, + //Qt::DirectConnection, + Q_ARG(QString, QString(name)), + Q_ARG(QString, QString(text)), + Q_ARG(int, delayms)); +} + + +CV_IMPL int cvWaitKey(int delay) +{ + int result = -1; + + if (!guiMainThread) + return result; + + unsigned long delayms = delay <= 0 ? ULONG_MAX : delay; //in milliseconds + + if (multiThreads) + { + mutexKey.lock(); + if (key_pressed.wait(&mutexKey, delayms)) //false if timeout + { + result = last_key; + } + last_key = -1; + mutexKey.unlock(); + } + else + { + //cannot use wait here because events will not be distributed before processEvents (the main eventLoop is broken) + //so I create a Thread for the QTimer + + if (delay > 0) + guiMainThread->timer->start(delay); + + //QMutex dummy; + + while (!guiMainThread->bTimeOut) + { + qApp->processEvents(QEventLoop::AllEvents); + + if (!guiMainThread)//when all the windows are deleted + return result; + + mutexKey.lock(); + if (last_key != -1) + { + result = last_key; + last_key = -1; + guiMainThread->timer->stop(); + //printf("keypressed\n"); + } + mutexKey.unlock(); + + if (result!=-1) + { + break; + } + else + { + /* + * //will not work, I broke the event loop !!!! + dummy.lock(); + QWaitCondition waitCondition; + waitCondition.wait(&dummy, 2); + */ + + //to decrease CPU usage + //sleep 1 millisecond +#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 + Sleep(1); +#else + usleep(1000); +#endif + } + } + + guiMainThread->bTimeOut = false; + } + + return result; +} + + +//Yannick Verdie +//This function is experimental and some functions (such as cvSet/getWindowProperty will not work) +//We recommend not using this function for now +CV_IMPL int cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]) +{ + multiThreads = true; + QFuture future = QtConcurrent::run(pt2Func, argc, argv); + return guiMainThread->start(); +} + + +CV_IMPL void cvStopLoop() +{ + qApp->exit(); +} + + +static CvWindow* icvFindWindowByName(QString name) +{ + CvWindow* window = 0; + + //This is not a very clean way to do the stuff. Indeed, QAction automatically generate toolTil (QLabel) + //that can be grabbed here and crash the code at 'w->param_name==name'. + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (widget->isWindow() && !widget->parentWidget())//is a window without parent + { + CvWinModel* temp = (CvWinModel*) widget; + + if (temp->type == type_CvWindow) + { + CvWindow* w = (CvWindow*) temp; + if (w->windowTitle() == name) + { + window = w; + break; + } + } + } + } + + return window; +} + + +static CvBar* icvFindBarByName(QBoxLayout* layout, QString name_bar, typeBar type) +{ + if (!layout) + return NULL; + + int stop_index = layout->layout()->count(); + + for (int i = 0; i < stop_index; ++i) + { + CvBar* t = (CvBar*) layout->layout()->itemAt(i); + + if (t->type == type && t->name_bar == name_bar) + return t; + } + + return NULL; +} + + +static CvTrackbar* icvFindTrackBarByName(const char* name_trackbar, const char* name_window, QBoxLayout* layout = NULL) +{ + QString nameQt(name_trackbar); + + if (!name_window && global_control_panel) //window name is null and we have a control panel + layout = global_control_panel->myLayout; + + if (!layout) + { + QPointer w = icvFindWindowByName(QLatin1String(name_window)); + + if (!w) + CV_Error(CV_StsNullPtr, "NULL window handler"); + + if (w->param_gui_mode == CV_GUI_NORMAL) + return (CvTrackbar*) icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar); + + if (w->param_gui_mode == CV_GUI_EXPANDED) + { + CvBar* result = icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar); + + if (result) + return (CvTrackbar*) result; + + return (CvTrackbar*) icvFindBarByName(global_control_panel->myLayout, nameQt, type_CvTrackbar); + } + + return NULL; + } + else + { + //layout was specified + return (CvTrackbar*) icvFindBarByName(layout, nameQt, type_CvTrackbar); + } +} + +/* +static CvButtonbar* icvFindButtonBarByName(const char* button_name, QBoxLayout* layout) +{ + QString nameQt(button_name); + return (CvButtonbar*) icvFindBarByName(layout, nameQt, type_CvButtonbar); +} +*/ + +static int icvInitSystem(int* c, char** v) +{ + //"For any GUI application using Qt, there is precisely one QApplication object" + if (!QApplication::instance()) + { + new QApplication(*c, v); + + qDebug() << "init done"; + +#ifdef HAVE_QT_OPENGL + qDebug() << "opengl support available"; +#endif + } + + return 0; +} + + +CV_IMPL int cvInitSystem(int, char**) +{ + icvInitSystem(¶meterSystemC, parameterSystemV); + return 0; +} + + +CV_IMPL int cvNamedWindow(const char* name, int flags) +{ + if (!guiMainThread) + guiMainThread = new GuiReceiver; + + if (multiThreads) + QMetaObject::invokeMethod(guiMainThread, + "createWindow", + Qt::BlockingQueuedConnection, + Q_ARG(QString, QString(name)), + Q_ARG(int, flags)); + else + guiMainThread->createWindow(QString(name), flags); + + return 1; //Dummy value +} + + +CV_IMPL void cvDestroyWindow(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "destroyWindow", + //Qt::BlockingQueuedConnection, + Qt::AutoConnection, + Q_ARG(QString, QString(name))); +} + + +CV_IMPL void cvDestroyAllWindows() +{ + if (!guiMainThread) + return; + + QMetaObject::invokeMethod(guiMainThread, + "destroyAllWindow", + //Qt::BlockingQueuedConnection, + Qt::AutoConnection); +} + + +CV_IMPL void* cvGetWindowHandle(const char* name) +{ + if (!name) + CV_Error( CV_StsNullPtr, "NULL name string" ); + + return (void*) icvFindWindowByName(QLatin1String(name)); +} + + +CV_IMPL const char* cvGetWindowName(void* window_handle) +{ + if( !window_handle ) + CV_Error( CV_StsNullPtr, "NULL window handler" ); + + return ((CvWindow*)window_handle)->windowTitle().toLatin1().data(); +} + + +CV_IMPL void cvMoveWindow(const char* name, int x, int y) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "moveWindow", + //Qt::BlockingQueuedConnection, + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(int, x), + Q_ARG(int, y)); +} + + +CV_IMPL void cvResizeWindow(const char* name, int width, int height) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "resizeWindow", + //Qt::BlockingQueuedConnection, + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(int, width), + Q_ARG(int, height)); +} + + +CV_IMPL int cvCreateTrackbar2(const char* name_bar, const char* window_name, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "addSlider2", + Qt::AutoConnection, + Q_ARG(QString, QString(name_bar)), + Q_ARG(QString, QString(window_name)), + Q_ARG(void*, (void*)val), + Q_ARG(int, count), + Q_ARG(void*, (void*)on_notify), + Q_ARG(void*, (void*)userdata)); + + return 1; //dummy value +} + + +CV_IMPL int cvStartWindowThread() +{ + return 0; +} + + +CV_IMPL int cvCreateTrackbar(const char* name_bar, const char* window_name, int* value, int count, CvTrackbarCallback on_change) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "addSlider", + Qt::AutoConnection, + Q_ARG(QString, QString(name_bar)), + Q_ARG(QString, QString(window_name)), + Q_ARG(void*, (void*)value), + Q_ARG(int, count), + Q_ARG(void*, (void*)on_change)); + + return 1; //dummy value +} + + +CV_IMPL int cvCreateButton(const char* button_name, CvButtonCallback on_change, void* userdata, int button_type, int initial_button_state) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + if (initial_button_state < 0 || initial_button_state > 1) + return 0; + + QMetaObject::invokeMethod(guiMainThread, + "addButton", + Qt::AutoConnection, + Q_ARG(QString, QString(button_name)), + Q_ARG(int, button_type), + Q_ARG(int, initial_button_state), + Q_ARG(void*, (void*)on_change), + Q_ARG(void*, userdata)); + + return 1;//dummy value +} + + +CV_IMPL int cvGetTrackbarPos(const char* name_bar, const char* window_name) +{ + int result = -1; + + QPointer t = icvFindTrackBarByName(name_bar, window_name); + + if (t) + result = t->slider->value(); + + return result; +} + + +CV_IMPL void cvSetTrackbarPos(const char* name_bar, const char* window_name, int pos) +{ + QPointer t = icvFindTrackBarByName(name_bar, window_name); + + if (t) + t->slider->setValue(pos); +} + + +/* assign callback for mouse events */ +CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mouse, void* param) +{ + QPointer w = icvFindWindowByName(QLatin1String(window_name)); + + if (!w) + CV_Error(CV_StsNullPtr, "NULL window handler"); + + w->setMouseCallBack(on_mouse, param); + +} + + +CV_IMPL void cvShowImage(const char* name, const CvArr* arr) +{ + if (!guiMainThread) + guiMainThread = new GuiReceiver; + + QMetaObject::invokeMethod(guiMainThread, + "showImage", + //Qt::BlockingQueuedConnection, + Qt::DirectConnection, + Q_ARG(QString, QString(name)), + Q_ARG(void*, (void*)arr)); +} + + +#ifdef HAVE_QT_OPENGL + +CV_IMPL void cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "setOpenGlDrawCallback", + Qt::AutoConnection, + Q_ARG(QString, QString(window_name)), + Q_ARG(void*, (void*)callback), + Q_ARG(void*, userdata)); +} + + +CV_IMPL void cvSetOpenGlContext(const char* window_name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "setOpenGlContext", + Qt::AutoConnection, + Q_ARG(QString, QString(window_name))); +} + + +CV_IMPL void cvUpdateWindow(const char* window_name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + QMetaObject::invokeMethod(guiMainThread, + "updateWindow", + Qt::AutoConnection, + Q_ARG(QString, QString(window_name))); +} + +#endif + + +double cvGetOpenGlProp_QT(const char* name) +{ + double result = -1; + + if (guiMainThread) + { + QMetaObject::invokeMethod(guiMainThread, + "isOpenGl", + Qt::AutoConnection, + Q_RETURN_ARG(double, result), + Q_ARG(QString, QString(name))); + } + + return result; +} + + +////////////////////////////////////////////////////// +// GuiReceiver + + +GuiReceiver::GuiReceiver() : bTimeOut(false), nb_windows(0) +{ + doesExternalQAppExist = (QApplication::instance() != 0); + icvInitSystem(¶meterSystemC, parameterSystemV); + + timer = new QTimer(this); + QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timeOut())); + timer->setSingleShot(true); +} + + +void GuiReceiver::isLastWindow() +{ + if (--nb_windows <= 0) + { + delete guiMainThread;//delete global_control_panel too + guiMainThread = NULL; + + if (!doesExternalQAppExist) + { + qApp->quit(); + } + } +} + + +GuiReceiver::~GuiReceiver() +{ + if (global_control_panel) + { + delete global_control_panel; + global_control_panel = NULL; + } +} + + +void GuiReceiver::putText(void* arr, QString text, QPoint org, void* arg2) +{ + CV_Assert(arr); + + CvMat* mat, stub; + mat = cvGetMat(arr, &stub); + + int nbChannelOriginImage = cvGetElemType(mat); + if (nbChannelOriginImage != CV_8UC3) return; //for now, font works only with 8UC3 + + QImage qimg(mat->data.ptr, mat->cols, mat->rows, mat->step, QImage::Format_RGB888); + + CvFont* font = (CvFont*)arg2; + + QPainter qp(&qimg); + if (font) + { + QFont f(font->nameFont, font->line_type/*PointSize*/, font->thickness/*weight*/); + f.setStyle((QFont::Style) font->font_face/*style*/); + f.setLetterSpacing(QFont::AbsoluteSpacing, font->dx/*spacing*/); + //cvScalar(blue_component, green_component, red_component[, alpha_component]) + //Qt map non-transparent to 0xFF and transparent to 0 + //OpenCV scalar is the reverse, so 255-font->color.val[3] + qp.setPen(QColor(font->color.val[2], font->color.val[1], font->color.val[0], 255 - font->color.val[3])); + qp.setFont(f); + } + qp.drawText(org, text); + qp.end(); +} + + +void GuiReceiver::saveWindowParameters(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->writeSettings(); +} + + +void GuiReceiver::loadWindowParameters(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->readSettings(); +} + + +double GuiReceiver::getRatioWindow(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return -1; + + return w->getRatio(); +} + + +void GuiReceiver::setRatioWindow(QString name, double arg2) +{ + QPointer w = icvFindWindowByName( name.toLatin1().data() ); + + if (!w) + return; + + int flags = (int) arg2; + + w->setRatio(flags); +} + + +double GuiReceiver::getPropWindow(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return -1; + + return (double) w->getPropWindow(); +} + + +void GuiReceiver::setPropWindow(QString name, double arg2) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return; + + int flags = (int) arg2; + + w->setPropWindow(flags); +} + + +double GuiReceiver::isFullScreen(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return -1; + + return w->isFullScreen() ? CV_WINDOW_FULLSCREEN : CV_WINDOW_NORMAL; +} + + +void GuiReceiver::toggleFullScreen(QString name, double arg2) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return; + + int flags = (int) arg2; + + w->toggleFullScreen(flags); +} + + +void GuiReceiver::createWindow(QString name, int flags) +{ + if (!qApp) + CV_Error(CV_StsNullPtr, "NULL session handler" ); + + // Check the name in the storage + if (icvFindWindowByName(name.toLatin1().data())) + { + return; + } + + nb_windows++; + new CvWindow(name, flags); +} + + +void GuiReceiver::timeOut() +{ + bTimeOut = true; +} + + +void GuiReceiver::displayInfo(QString name, QString text, int delayms) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->displayInfo(text, delayms); +} + + +void GuiReceiver::displayStatusBar(QString name, QString text, int delayms) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->displayStatusBar(text, delayms); +} + + +void GuiReceiver::showImage(QString name, void* arr) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) //as observed in the previous implementation (W32, GTK or Carbon), create a new window is the pointer returned is null + { + cvNamedWindow(name.toLatin1().data()); + w = icvFindWindowByName(name); + } + + if (!w || !arr) + return; // keep silence here. + + if (w->isOpenGl()) + { + CvMat* mat, stub; + + mat = cvGetMat(arr, &stub); + + cv::Mat im(mat); + cv::imshow(name.toStdString(), im); + } + else + { + w->updateImage(arr); + } + + if (w->isHidden()) + w->show(); +} + + +void GuiReceiver::destroyWindow(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + { + w->close(); + + //in not-multiThreads mode, looks like the window is hidden but not deleted + //so I do it manually + //otherwise QApplication do it for me if the exec command was executed (in multiThread mode) + if (!multiThreads) + delete w; + } +} + + +void GuiReceiver::destroyAllWindow() +{ + if (!qApp) + CV_Error(CV_StsNullPtr, "NULL session handler" ); + + if (multiThreads) + { + // WARNING: this could even close windows from an external parent app + //#TODO check externalQAppExists and in case it does, close windows carefully, + // i.e. apply the className-check from below... + qApp->closeAllWindows(); + } + else + { + bool isWidgetDeleted = true; + while(isWidgetDeleted) + { + isWidgetDeleted = false; + QWidgetList list = QApplication::topLevelWidgets(); + for (int i = 0; i < list.count(); i++) + { + QObject *obj = list.at(i); + if (obj->metaObject()->className() == QString("CvWindow")) + { + delete obj; + isWidgetDeleted = true; + break; + } + } + } + } +} + + +void GuiReceiver::moveWindow(QString name, int x, int y) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->move(x, y); +} + + +void GuiReceiver::resizeWindow(QString name, int width, int height) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + { + w->showNormal(); + w->setViewportSize(QSize(width, height)); + } +} + + +void GuiReceiver::enablePropertiesButtonEachWindow() +{ + //For each window, enable window property button + foreach (QWidget* widget, QApplication::topLevelWidgets()) + { + if (widget->isWindow() && !widget->parentWidget()) //is a window without parent + { + CvWinModel* temp = (CvWinModel*) widget; + if (temp->type == type_CvWindow) + { + CvWindow* w = (CvWindow*) widget; + + //active window properties button + w->enablePropertiesButton(); + } + } + } +} + + +void GuiReceiver::addButton(QString button_name, int button_type, int initial_button_state, void* on_change, void* userdata) +{ + if (!global_control_panel) + return; + + QPointer b; + + if (global_control_panel->myLayout->count() == 0) //if that is the first button attach to the control panel, create a new button bar + { + b = CvWindow::createButtonBar(button_name); //the bar has the name of the first button attached to it + enablePropertiesButtonEachWindow(); + + } + else + { + CvBar* lastbar = (CvBar*) global_control_panel->myLayout->itemAt(global_control_panel->myLayout->count() - 1); + + if (lastbar->type == type_CvTrackbar) //if last bar is a trackbar, create a new buttonbar, else, attach to the current bar + b = CvWindow::createButtonBar(button_name); //the bar has the name of the first button attached to it + else + b = (CvButtonbar*) lastbar; + + } + + b->addButton(button_name, (CvButtonCallback) on_change, userdata, button_type, initial_button_state); +} + + +void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, int count, void* on_change, void *userdata) +{ + QBoxLayout *layout = NULL; + QPointer w; + + if (!window_name.isEmpty()) + { + w = icvFindWindowByName(window_name); + + if (!w) + return; + } + else + { + if (global_control_panel) + layout = global_control_panel->myLayout; + } + + QPointer t = icvFindTrackBarByName(bar_name.toLatin1().data(), window_name.toLatin1().data(), layout); + + if (t) //trackbar exists + return; + + if (!value) + CV_Error(CV_StsNullPtr, "NULL value pointer" ); + + if (count <= 0) //count is the max value of the slider, so must be bigger than 0 + CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + + CvWindow::addSlider2(w, bar_name, (int*)value, count, (CvTrackbarCallback2) on_change, userdata); +} + + +void GuiReceiver::addSlider(QString bar_name, QString window_name, void* value, int count, void* on_change) +{ + QBoxLayout *layout = NULL; + QPointer w; + + if (!window_name.isEmpty()) + { + w = icvFindWindowByName(window_name); + + if (!w) + return; + } + else + { + if (global_control_panel) + layout = global_control_panel->myLayout; + } + + QPointer t = icvFindTrackBarByName(bar_name.toLatin1().data(), window_name.toLatin1().data(), layout); + + if (t) //trackbar exists + return; + + if (!value) + CV_Error(CV_StsNullPtr, "NULL value pointer" ); + + if (count <= 0) //count is the max value of the slider, so must be bigger than 0 + CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + + CvWindow::addSlider(w, bar_name, (int*)value, count, (CvTrackbarCallback) on_change); +} + + +int GuiReceiver::start() +{ + return qApp->exec(); +} + + +void GuiReceiver::setOpenGlDrawCallback(QString name, void* callback, void* userdata) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->setOpenGlDrawCallback((CvOpenGlDrawCallback) callback, userdata); +} + +void GuiReceiver::setOpenGlContext(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->makeCurrentOpenGlContext(); +} + +void GuiReceiver::updateWindow(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (w) + w->updateGl(); +} + +double GuiReceiver::isOpenGl(QString name) +{ + double result = -1; + + QPointer w = icvFindWindowByName(name); + + if (w) + result = (double) w->isOpenGl(); + + return result; +} + + +////////////////////////////////////////////////////// +// CvTrackbar + + +CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int _count, CvTrackbarCallback2 on_change, void* data) +{ + callback = NULL; + callback2 = on_change; + userdata = data; + + create(arg, name, value, _count); +} + + +CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int _count, CvTrackbarCallback on_change) +{ + callback = on_change; + callback2 = NULL; + userdata = NULL; + + create(arg, name, value, _count); +} + + +void CvTrackbar::create(CvWindow* arg, QString name, int* value, int _count) +{ + type = type_CvTrackbar; + myparent = arg; + name_bar = name; + setObjectName(name_bar); + dataSlider = value; + + slider = new QSlider(Qt::Horizontal); + slider->setFocusPolicy(Qt::StrongFocus); + slider->setMinimum(0); + slider->setMaximum(_count); + slider->setPageStep(5); + slider->setValue(*value); + slider->setTickPosition(QSlider::TicksBelow); + + + //Change style of the Slider + //slider->setStyleSheet(str_Trackbar_css); + + QFile qss(":/stylesheet-trackbar"); + if (qss.open(QFile::ReadOnly)) + { + slider->setStyleSheet(QLatin1String(qss.readAll())); + qss.close(); + } + + + //this next line does not work if we change the style with a stylesheet, why ? (bug in QT ?) + //slider->setTickPosition(QSlider::TicksBelow); + label = new QPushButton; + label->setFlat(true); + setLabel(slider->value()); + + + QObject::connect(slider, SIGNAL(valueChanged(int)), this, SLOT(update(int))); + + QObject::connect(label, SIGNAL(clicked()), this, SLOT(createDialog())); + + //label->setStyleSheet("QPushButton:disabled {color: black}"); + + addWidget(label, Qt::AlignLeft);//name + value + addWidget(slider, Qt::AlignCenter);//slider +} + + +void CvTrackbar::createDialog() +{ + bool ok = false; + + //crash if I access the values directly and give them to QInputDialog, so do a copy first. + int value = slider->value(); + int step = slider->singleStep(); + int min = slider->minimum(); + int max = slider->maximum(); + + int i = +#if QT_VERSION >= 0x040500 + QInputDialog::getInt +#else + QInputDialog::getInteger +#endif + (this->parentWidget(), + tr("Slider %1").arg(name_bar), + tr("New value:"), + value, + min, + max, + step, + &ok); + + if (ok) + slider->setValue(i); +} + + +void CvTrackbar::update(int myvalue) +{ + setLabel(myvalue); + + *dataSlider = myvalue; + if (callback) + { + callback(myvalue); + return; + } + + if (callback2) + { + callback2(myvalue, userdata); + return; + } +} + + +void CvTrackbar::setLabel(int myvalue) +{ + QString nameNormalized = name_bar.leftJustified( 10, ' ', true ); + QString valueMaximum = QString("%1").arg(slider->maximum()); + QString str = QString("%1 (%2/%3)").arg(nameNormalized).arg(myvalue,valueMaximum.length(),10,QChar('0')).arg(valueMaximum); + label->setText(str); +} + + +////////////////////////////////////////////////////// +// CvButtonbar + + +//here CvButtonbar class +CvButtonbar::CvButtonbar(QWidget* arg, QString arg2) +{ + type = type_CvButtonbar; + myparent = arg; + name_bar = arg2; + setObjectName(name_bar); + + group_button = new QButtonGroup(this); +} + + +void CvButtonbar::setLabel() +{ + QString nameNormalized = name_bar.leftJustified(10, ' ', true); + label->setText(nameNormalized); +} + + +void CvButtonbar::addButton(QString name, CvButtonCallback call, void* userdata, int button_type, int initial_button_state) +{ + QString button_name = name; + + if (button_name == "") + button_name = tr("button %1").arg(this->count()); + + QPointer button; + + if (button_type == CV_PUSH_BUTTON) + button = (QAbstractButton*) new CvPushButton(this, button_name,call, userdata); + + if (button_type == CV_CHECKBOX) + button = (QAbstractButton*) new CvCheckBox(this, button_name,call, userdata, initial_button_state); + + if (button_type == CV_RADIOBOX) + { + button = (QAbstractButton*) new CvRadioButton(this, button_name,call, userdata, initial_button_state); + group_button->addButton(button); + } + + if (button) + { + if (button_type == CV_PUSH_BUTTON) + QObject::connect(button, SIGNAL(clicked(bool)), button, SLOT(callCallBack(bool))); + else + QObject::connect(button, SIGNAL(toggled(bool)), button, SLOT(callCallBack(bool))); + + addWidget(button, Qt::AlignCenter); + } +} + + +////////////////////////////////////////////////////// +// Buttons + + +//buttons here +CvPushButton::CvPushButton(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4) +{ + myparent = arg1; + button_name = arg2; + callback = arg3; + userdata = arg4; + + setObjectName(button_name); + setText(button_name); + + if (isChecked()) + callCallBack(true); +} + + +void CvPushButton::callCallBack(bool checked) +{ + if (callback) + callback(checked, userdata); +} + + +CvCheckBox::CvCheckBox(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4, int initial_button_state) +{ + myparent = arg1; + button_name = arg2; + callback = arg3; + userdata = arg4; + + setObjectName(button_name); + setCheckState((initial_button_state == 1 ? Qt::Checked : Qt::Unchecked)); + setText(button_name); + + if (isChecked()) + callCallBack(true); +} + + +void CvCheckBox::callCallBack(bool checked) +{ + if (callback) + callback(checked, userdata); +} + + +CvRadioButton::CvRadioButton(CvButtonbar* arg1, QString arg2, CvButtonCallback arg3, void* arg4, int initial_button_state) +{ + myparent = arg1; + button_name = arg2; + callback = arg3; + userdata = arg4; + + setObjectName(button_name); + setChecked(initial_button_state); + setText(button_name); + + if (isChecked()) + callCallBack(true); +} + +void CvRadioButton::callCallBack(bool checked) +{ + if (callback) + callback(checked, userdata); +} + + +////////////////////////////////////////////////////// +// CvWinProperties + + +//here CvWinProperties class +CvWinProperties::CvWinProperties(QString name_paraWindow, QObject* /*parent*/) +{ + //setParent(parent); + type = type_CvWinProperties; + setWindowFlags(Qt::Tool); + setContentsMargins(0, 0, 0, 0); + setWindowTitle(name_paraWindow); + setObjectName(name_paraWindow); + resize(100, 50); + + myLayout = new QBoxLayout(QBoxLayout::TopToBottom); + myLayout->setObjectName(QString::fromUtf8("boxLayout")); + myLayout->setContentsMargins(0, 0, 0, 0); + myLayout->setSpacing(0); + myLayout->setMargin(0); + myLayout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(myLayout); + + hide(); +} + + +void CvWinProperties::closeEvent(QCloseEvent* e) +{ + e->accept(); //intersept the close event (not sure I really need it) + //an hide event is also sent. I will intercept it and do some processing +} + + +void CvWinProperties::showEvent(QShowEvent* evnt) +{ + //why -1,-1 ?: do this trick because the first time the code is run, + //no value pos was saved so we let Qt move the window in the middle of its parent (event ignored). + //then hide will save the last position and thus, we want to retreive it (event accepted). + QPoint mypos(-1, -1); + QSettings settings("OpenCV2", windowTitle()); + mypos = settings.value("pos", mypos).toPoint(); + + if (mypos.x() >= 0) + { + move(mypos); + evnt->accept(); + } + else + { + evnt->ignore(); + } +} + + +void CvWinProperties::hideEvent(QHideEvent* evnt) +{ + QSettings settings("OpenCV2", windowTitle()); + settings.setValue("pos", pos()); //there is an offset of 6 pixels (so the window's position is wrong -- why ?) + evnt->accept(); +} + + +CvWinProperties::~CvWinProperties() +{ + //clear the setting pos + QSettings settings("OpenCV2", windowTitle()); + settings.remove("pos"); +} + + +////////////////////////////////////////////////////// +// CvWindow + + +CvWindow::CvWindow(QString name, int arg2) +{ + type = type_CvWindow; + moveToThread(qApp->instance()->thread()); + + param_flags = arg2 & 0x0000000F; + param_gui_mode = arg2 & 0x000000F0; + param_ratio_mode = arg2 & 0x00000F00; + + //setAttribute(Qt::WA_DeleteOnClose); //in other case, does not release memory + setContentsMargins(0, 0, 0, 0); + setWindowTitle(name); + setObjectName(name); + + setFocus( Qt::PopupFocusReason ); //#1695 arrow keys are not recieved without the explicit focus + + resize(400, 300); + setMinimumSize(1, 1); + + //1: create control panel + if (!global_control_panel) + global_control_panel = createParameterWindow(); + + //2: Layouts + createBarLayout(); + createGlobalLayout(); + + //3: my view +#ifndef HAVE_QT_OPENGL + if (arg2 & CV_WINDOW_OPENGL) + CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + mode_display = CV_MODE_NORMAL; +#else + mode_display = arg2 & CV_WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL; + if (mode_display == CV_MODE_OPENGL) + param_gui_mode = CV_GUI_NORMAL; +#endif + createView(); + + //4: shortcuts and actions + //5: toolBar and statusbar + if (param_gui_mode == CV_GUI_EXPANDED) + { + createActions(); + createShortcuts(); + + createToolBar(); + createStatusBar(); + } + + //Now attach everything + if (myToolBar) + myGlobalLayout->addWidget(myToolBar, Qt::AlignCenter); + + myGlobalLayout->addWidget(myView->getWidget(), Qt::AlignCenter); + + myGlobalLayout->addLayout(myBarLayout, Qt::AlignCenter); + + if (myStatusBar) + myGlobalLayout->addWidget(myStatusBar, Qt::AlignCenter); + + setLayout(myGlobalLayout); + show(); +} + + +CvWindow::~CvWindow() +{ + if (guiMainThread) + guiMainThread->isLastWindow(); +} + + +void CvWindow::setMouseCallBack(CvMouseCallback callback, void* param) +{ + myView->setMouseCallBack(callback, param); +} + + +void CvWindow::writeSettings() +{ + //organisation and application's name + QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName()); + + settings.setValue("pos", pos()); + settings.setValue("size", size()); + settings.setValue("mode_resize" ,param_flags); + settings.setValue("mode_gui", param_gui_mode); + + myView->writeSettings(settings); + + icvSaveTrackbars(&settings); + + if (global_control_panel) + { + icvSaveControlPanel(); + settings.setValue("posPanel", global_control_panel->pos()); + } +} + + + +//TODO: load CV_GUI flag (done) and act accordingly (create win property if needed and attach trackbars) +void CvWindow::readSettings() +{ + //organisation and application's name + QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName()); + + QPoint _pos = settings.value("pos", QPoint(200, 200)).toPoint(); + QSize _size = settings.value("size", QSize(400, 400)).toSize(); + + param_flags = settings.value("mode_resize", param_flags).toInt(); + param_gui_mode = settings.value("mode_gui", param_gui_mode).toInt(); + + param_flags = settings.value("mode_resize", param_flags).toInt(); + + myView->readSettings(settings); + + //trackbar here + icvLoadTrackbars(&settings); + + resize(_size); + move(_pos); + + if (global_control_panel) + { + icvLoadControlPanel(); + global_control_panel->move(settings.value("posPanel", global_control_panel->pos()).toPoint()); + } +} + + +double CvWindow::getRatio() +{ + return myView->getRatio(); +} + + +void CvWindow::setRatio(int flags) +{ + myView->setRatio(flags); +} + + +int CvWindow::getPropWindow() +{ + return param_flags; +} + + +void CvWindow::setPropWindow(int flags) +{ + if (param_flags == flags) //nothing to do + return; + + switch(flags) + { + case CV_WINDOW_NORMAL: + myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); + param_flags = flags; + + break; + + case CV_WINDOW_AUTOSIZE: + myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize); + param_flags = flags; + + break; + + default: + ; + } +} + + +void CvWindow::toggleFullScreen(int flags) +{ + if (isFullScreen() && flags == CV_WINDOW_NORMAL) + { + showTools(); + showNormal(); + return; + } + + if (!isFullScreen() && flags == CV_WINDOW_FULLSCREEN) + { + hideTools(); + showFullScreen(); + return; + } +} + + +void CvWindow::updateImage(void* arr) +{ + myView->updateImage(arr); +} + + +void CvWindow::displayInfo(QString text, int delayms) +{ + myView->startDisplayInfo(text, delayms); +} + + +void CvWindow::displayStatusBar(QString text, int delayms) +{ + if (myStatusBar) + myStatusBar->showMessage(text, delayms); +} + + +void CvWindow::enablePropertiesButton() +{ + vect_QActions[9]->setDisabled(false); +} + + +CvButtonbar* CvWindow::createButtonBar(QString name_bar) +{ + QPointer t = new CvButtonbar(global_control_panel, name_bar); + t->setAlignment(Qt::AlignHCenter); + + QPointer myLayout = global_control_panel->myLayout; + + myLayout->insertLayout(myLayout->count(), t); + + return t; +} + + +void CvWindow::addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change) +{ + QPointer t = new CvTrackbar(w, name, value, count, on_change); + t->setAlignment(Qt::AlignHCenter); + + QPointer myLayout; + + if (w) + { + myLayout = w->myBarLayout; + } + else + { + myLayout = global_control_panel->myLayout; + + //if first one, enable control panel + if (myLayout->count() == 0) + guiMainThread->enablePropertiesButtonEachWindow(); + } + + myLayout->insertLayout(myLayout->count(), t); +} + + +void CvWindow::addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* userdata) +{ + QPointer t = new CvTrackbar(w, name, value, count, on_change, userdata); + t->setAlignment(Qt::AlignHCenter); + + QPointer myLayout; + + if (w) + { + myLayout = w->myBarLayout; + } + else + { + myLayout = global_control_panel->myLayout; + + //if first one, enable control panel + if (myLayout->count() == 0) + guiMainThread->enablePropertiesButtonEachWindow(); + } + + myLayout->insertLayout(myLayout->count(), t); +} + + +void CvWindow::setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) +{ + myView->setOpenGlDrawCallback(callback, userdata); +} + + +void CvWindow::makeCurrentOpenGlContext() +{ + myView->makeCurrentOpenGlContext(); +} + + +void CvWindow::updateGl() +{ + myView->updateGl(); +} + + +bool CvWindow::isOpenGl() +{ + return mode_display == CV_MODE_OPENGL; +} + + +void CvWindow::setViewportSize(QSize _size) +{ + myView->getWidget()->resize(_size); + myView->setSize(_size); +} + + +void CvWindow::createBarLayout() +{ + myBarLayout = new QBoxLayout(QBoxLayout::TopToBottom); + myBarLayout->setObjectName(QString::fromUtf8("barLayout")); + myBarLayout->setContentsMargins(0, 0, 0, 0); + myBarLayout->setSpacing(0); + myBarLayout->setMargin(0); +} + + +void CvWindow::createGlobalLayout() +{ + myGlobalLayout = new QBoxLayout(QBoxLayout::TopToBottom); + myGlobalLayout->setObjectName(QString::fromUtf8("boxLayout")); + myGlobalLayout->setContentsMargins(0, 0, 0, 0); + myGlobalLayout->setSpacing(0); + myGlobalLayout->setMargin(0); + setMinimumSize(1, 1); + + if (param_flags == CV_WINDOW_AUTOSIZE) + myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize); + else if (param_flags == CV_WINDOW_NORMAL) + myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); +} + + +void CvWindow::createView() +{ +#ifdef HAVE_QT_OPENGL + if (isOpenGl()) + myView = new OpenGlViewPort(this); + else +#endif + myView = new DefaultViewPort(this, param_ratio_mode); +} + + +void CvWindow::createActions() +{ + vect_QActions.resize(10); + + QWidget* view = myView->getWidget(); + + //if the shortcuts are changed in window_QT.h, we need to update the tooltip manually + vect_QActions[0] = new QAction(QIcon(":/left-icon"), "Panning left (CTRL+arrowLEFT)", this); + vect_QActions[0]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[0], SIGNAL(triggered()), view, SLOT(siftWindowOnLeft())); + + vect_QActions[1] = new QAction(QIcon(":/right-icon"), "Panning right (CTRL+arrowRIGHT)", this); + vect_QActions[1]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[1], SIGNAL(triggered()), view, SLOT(siftWindowOnRight())); + + vect_QActions[2] = new QAction(QIcon(":/up-icon"), "Panning up (CTRL+arrowUP)", this); + vect_QActions[2]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[2], SIGNAL(triggered()), view, SLOT(siftWindowOnUp())); + + vect_QActions[3] = new QAction(QIcon(":/down-icon"), "Panning down (CTRL+arrowDOWN)", this); + vect_QActions[3]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[3], SIGNAL(triggered()), view, SLOT(siftWindowOnDown()) ); + + vect_QActions[4] = new QAction(QIcon(":/zoom_x1-icon"), "Zoom x1 (CTRL+P)", this); + vect_QActions[4]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[4], SIGNAL(triggered()), view, SLOT(resetZoom())); + + vect_QActions[5] = new QAction(QIcon(":/imgRegion-icon"), tr("Zoom x%1 (see label) (CTRL+X)").arg(threshold_zoom_img_region), this); + vect_QActions[5]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[5], SIGNAL(triggered()), view, SLOT(imgRegion())); + + vect_QActions[6] = new QAction(QIcon(":/zoom_in-icon"), "Zoom in (CTRL++)", this); + vect_QActions[6]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[6], SIGNAL(triggered()), view, SLOT(ZoomIn())); + + vect_QActions[7] = new QAction(QIcon(":/zoom_out-icon"), "Zoom out (CTRL+-)", this); + vect_QActions[7]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[7], SIGNAL(triggered()), view, SLOT(ZoomOut())); + + vect_QActions[8] = new QAction(QIcon(":/save-icon"), "Save current image (CTRL+S)", this); + vect_QActions[8]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[8], SIGNAL(triggered()), view, SLOT(saveView())); + + vect_QActions[9] = new QAction(QIcon(":/properties-icon"), "Display properties window (CTRL+P)", this); + vect_QActions[9]->setIconVisibleInMenu(true); + QObject::connect(vect_QActions[9], SIGNAL(triggered()), this, SLOT(displayPropertiesWin())); + + if (global_control_panel->myLayout->count() == 0) + vect_QActions[9]->setDisabled(true); +} + + +void CvWindow::createShortcuts() +{ + vect_QShortcuts.resize(10); + + QWidget* view = myView->getWidget(); + + vect_QShortcuts[0] = new QShortcut(shortcut_panning_left, this); + QObject::connect(vect_QShortcuts[0], SIGNAL(activated()), view, SLOT(siftWindowOnLeft())); + + vect_QShortcuts[1] = new QShortcut(shortcut_panning_right, this); + QObject::connect(vect_QShortcuts[1], SIGNAL(activated()), view, SLOT(siftWindowOnRight())); + + vect_QShortcuts[2] = new QShortcut(shortcut_panning_up, this); + QObject::connect(vect_QShortcuts[2], SIGNAL(activated()), view, SLOT(siftWindowOnUp())); + + vect_QShortcuts[3] = new QShortcut(shortcut_panning_down, this); + QObject::connect(vect_QShortcuts[3], SIGNAL(activated()), view, SLOT(siftWindowOnDown())); + + vect_QShortcuts[4] = new QShortcut(shortcut_zoom_normal, this); + QObject::connect(vect_QShortcuts[4], SIGNAL(activated()), view, SLOT(resetZoom())); + + vect_QShortcuts[5] = new QShortcut(shortcut_zoom_imgRegion, this); + QObject::connect(vect_QShortcuts[5], SIGNAL(activated()), view, SLOT(imgRegion())); + + vect_QShortcuts[6] = new QShortcut(shortcut_zoom_in, this); + QObject::connect(vect_QShortcuts[6], SIGNAL(activated()), view, SLOT(ZoomIn())); + + vect_QShortcuts[7] = new QShortcut(shortcut_zoom_out, this); + QObject::connect(vect_QShortcuts[7], SIGNAL(activated()), view, SLOT(ZoomOut())); + + vect_QShortcuts[8] = new QShortcut(shortcut_save_img, this); + QObject::connect(vect_QShortcuts[8], SIGNAL(activated()), view, SLOT(saveView())); + + vect_QShortcuts[9] = new QShortcut(shortcut_properties_win, this); + QObject::connect(vect_QShortcuts[9], SIGNAL(activated()), this, SLOT(displayPropertiesWin())); +} + + +void CvWindow::createToolBar() +{ + myToolBar = new QToolBar(this); + myToolBar->setFloatable(false); //is not a window + myToolBar->setFixedHeight(28); + myToolBar->setMinimumWidth(1); + + foreach (QAction *a, vect_QActions) + myToolBar->addAction(a); +} + + +void CvWindow::createStatusBar() +{ + myStatusBar = new QStatusBar(this); + myStatusBar->setSizeGripEnabled(false); + myStatusBar->setFixedHeight(20); + myStatusBar->setMinimumWidth(1); + myStatusBar_msg = new QLabel; + + //I comment this because if we change the style, myview (the picture) + //will not be the correct size anymore (will lost 2 pixel because of the borders) + + //myStatusBar_msg->setFrameStyle(QFrame::Raised); + + myStatusBar_msg->setAlignment(Qt::AlignHCenter); + myStatusBar->addWidget(myStatusBar_msg); +} + + +void CvWindow::hideTools() +{ + if (myToolBar) + myToolBar->hide(); + + if (myStatusBar) + myStatusBar->hide(); + + if (global_control_panel) + global_control_panel->hide(); +} + + +void CvWindow::showTools() +{ + if (myToolBar) + myToolBar->show(); + + if (myStatusBar) + myStatusBar->show(); +} + + +CvWinProperties* CvWindow::createParameterWindow() +{ + QString name_paraWindow = QFileInfo(QApplication::applicationFilePath()).fileName() + " settings"; + + CvWinProperties* result = new CvWinProperties(name_paraWindow, guiMainThread); + + return result; +} + + +void CvWindow::displayPropertiesWin() +{ + if (global_control_panel->isHidden()) + global_control_panel->show(); + else + global_control_panel->hide(); +} + + +//Need more test here ! +void CvWindow::keyPressEvent(QKeyEvent *evnt) +{ + //see http://doc.trolltech.com/4.6/qt.html#Key-enum + int key = evnt->key(); + + Qt::Key qtkey = static_cast(key); + char asciiCode = QTest::keyToAscii(qtkey); + if (asciiCode != 0) + key = static_cast(asciiCode); + else + key = evnt->nativeVirtualKey(); //same codes as returned by GTK-based backend + + //control plus (Z, +, -, up, down, left, right) are used for zoom/panning functions + if (evnt->modifiers() != Qt::ControlModifier) + { + mutexKey.lock(); + last_key = key; + mutexKey.unlock(); + key_pressed.wakeAll(); + //evnt->accept(); + } + + QWidget::keyPressEvent(evnt); +} + + +void CvWindow::icvLoadControlPanel() +{ + QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName() + " control panel"); + + int bsize = settings.beginReadArray("bars"); + + if (bsize == global_control_panel->myLayout->layout()->count()) + { + for (int i = 0; i < bsize; ++i) + { + CvBar* t = (CvBar*) global_control_panel->myLayout->layout()->itemAt(i); + settings.setArrayIndex(i); + if (t->type == type_CvTrackbar) + { + if (t->name_bar == settings.value("namebar").toString()) + { + ((CvTrackbar*)t)->slider->setValue(settings.value("valuebar").toInt()); + } + } + if (t->type == type_CvButtonbar) + { + int subsize = settings.beginReadArray(QString("buttonbar")+i); + + if ( subsize == ((CvButtonbar*)t)->layout()->count() ) + icvLoadButtonbar((CvButtonbar*)t,&settings); + + settings.endArray(); + } + } + } + + settings.endArray(); +} + + +void CvWindow::icvSaveControlPanel() +{ + QSettings settings("OpenCV2", QFileInfo(QApplication::applicationFilePath()).fileName()+" control panel"); + + settings.beginWriteArray("bars"); + + for (int i = 0; i < global_control_panel->myLayout->layout()->count(); ++i) + { + CvBar* t = (CvBar*) global_control_panel->myLayout->layout()->itemAt(i); + settings.setArrayIndex(i); + if (t->type == type_CvTrackbar) + { + settings.setValue("namebar", QString(t->name_bar)); + settings.setValue("valuebar",((CvTrackbar*)t)->slider->value()); + } + if (t->type == type_CvButtonbar) + { + settings.beginWriteArray(QString("buttonbar")+i); + icvSaveButtonbar((CvButtonbar*)t,&settings); + settings.endArray(); + } + } + + settings.endArray(); +} + + +void CvWindow::icvSaveButtonbar(CvButtonbar* b, QSettings* settings) +{ + for (int i = 0, count = b->layout()->count(); i < count; ++i) + { + settings->setArrayIndex(i); + + QWidget* temp = (QWidget*) b->layout()->itemAt(i)->widget(); + QString myclass(QLatin1String(temp->metaObject()->className())); + + if (myclass == "CvPushButton") + { + CvPushButton* button = (CvPushButton*) temp; + settings->setValue("namebutton", button->text()); + settings->setValue("valuebutton", int(button->isChecked())); + } + else if (myclass == "CvCheckBox") + { + CvCheckBox* button = (CvCheckBox*) temp; + settings->setValue("namebutton", button->text()); + settings->setValue("valuebutton", int(button->isChecked())); + } + else if (myclass == "CvRadioButton") + { + CvRadioButton* button = (CvRadioButton*) temp; + settings->setValue("namebutton", button->text()); + settings->setValue("valuebutton", int(button->isChecked())); + } + } +} + + +void CvWindow::icvLoadButtonbar(CvButtonbar* b, QSettings* settings) +{ + for (int i = 0, count = b->layout()->count(); i < count; ++i) + { + settings->setArrayIndex(i); + + QWidget* temp = (QWidget*) b->layout()->itemAt(i)->widget(); + QString myclass(QLatin1String(temp->metaObject()->className())); + + if (myclass == "CvPushButton") + { + CvPushButton* button = (CvPushButton*) temp; + + if (button->text() == settings->value("namebutton").toString()) + button->setChecked(settings->value("valuebutton").toInt()); + } + else if (myclass == "CvCheckBox") + { + CvCheckBox* button = (CvCheckBox*) temp; + + if (button->text() == settings->value("namebutton").toString()) + button->setChecked(settings->value("valuebutton").toInt()); + } + else if (myclass == "CvRadioButton") + { + CvRadioButton* button = (CvRadioButton*) temp; + + if (button->text() == settings->value("namebutton").toString()) + button->setChecked(settings->value("valuebutton").toInt()); + } + + } +} + + +void CvWindow::icvLoadTrackbars(QSettings* settings) +{ + int bsize = settings->beginReadArray("trackbars"); + + //trackbar are saved in the same order, so no need to use icvFindTrackbarByName + + if (myBarLayout->layout()->count() == bsize) //if not the same number, the window saved and loaded is not the same (nb trackbar not equal) + { + for (int i = 0; i < bsize; ++i) + { + settings->setArrayIndex(i); + + CvTrackbar* t = (CvTrackbar*) myBarLayout->layout()->itemAt(i); + + if (t->name_bar == settings->value("name").toString()) + t->slider->setValue(settings->value("value").toInt()); + + } + } + + settings->endArray(); +} + + +void CvWindow::icvSaveTrackbars(QSettings* settings) +{ + settings->beginWriteArray("trackbars"); + + for (int i = 0; i < myBarLayout->layout()->count(); ++i) + { + settings->setArrayIndex(i); + + CvTrackbar* t = (CvTrackbar*) myBarLayout->layout()->itemAt(i); + + settings->setValue("name", t->name_bar); + settings->setValue("value", t->slider->value()); + } + + settings->endArray(); +} + + +////////////////////////////////////////////////////// +// DefaultViewPort + + +DefaultViewPort::DefaultViewPort(CvWindow* arg, int arg2) : QGraphicsView(arg), image2Draw_mat(0) +{ + centralWidget = arg; + param_keepRatio = arg2; + + setContentsMargins(0, 0, 0, 0); + setMinimumSize(1, 1); + setAlignment(Qt::AlignHCenter); + + setObjectName(QString::fromUtf8("graphicsView")); + + timerDisplay = new QTimer(this); + timerDisplay->setSingleShot(true); + connect(timerDisplay, SIGNAL(timeout()), this, SLOT(stopDisplayInfo())); + + drawInfo = false; + positionGrabbing = QPointF(0, 0); + positionCorners = QRect(0, 0, size().width(), size().height()); + + on_mouse = 0; + on_mouse_param = 0; + mouseCoordinate = QPoint(-1, -1); + + //no border + setStyleSheet( "QGraphicsView { border-style: none; }" ); + + image2Draw_mat = cvCreateMat(viewport()->height(), viewport()->width(), CV_8UC3); + cvZero(image2Draw_mat); + + nbChannelOriginImage = 0; + + setInteractive(false); + setMouseTracking(true); //receive mouse event everytime +} + + +DefaultViewPort::~DefaultViewPort() +{ + if (image2Draw_mat) + cvReleaseMat(&image2Draw_mat); +} + + +QWidget* DefaultViewPort::getWidget() +{ + return this; +} + + +void DefaultViewPort::setMouseCallBack(CvMouseCallback m, void* param) +{ + on_mouse = m; + + on_mouse_param = param; +} + +void DefaultViewPort::writeSettings(QSettings& settings) +{ + settings.setValue("matrix_view.m11", param_matrixWorld.m11()); + settings.setValue("matrix_view.m12", param_matrixWorld.m12()); + settings.setValue("matrix_view.m13", param_matrixWorld.m13()); + settings.setValue("matrix_view.m21", param_matrixWorld.m21()); + settings.setValue("matrix_view.m22", param_matrixWorld.m22()); + settings.setValue("matrix_view.m23", param_matrixWorld.m23()); + settings.setValue("matrix_view.m31", param_matrixWorld.m31()); + settings.setValue("matrix_view.m32", param_matrixWorld.m32()); + settings.setValue("matrix_view.m33", param_matrixWorld.m33()); +} + + +void DefaultViewPort::readSettings(QSettings& settings) +{ + qreal m11 = settings.value("matrix_view.m11", param_matrixWorld.m11()).toDouble(); + qreal m12 = settings.value("matrix_view.m12", param_matrixWorld.m12()).toDouble(); + qreal m13 = settings.value("matrix_view.m13", param_matrixWorld.m13()).toDouble(); + qreal m21 = settings.value("matrix_view.m21", param_matrixWorld.m21()).toDouble(); + qreal m22 = settings.value("matrix_view.m22", param_matrixWorld.m22()).toDouble(); + qreal m23 = settings.value("matrix_view.m23", param_matrixWorld.m23()).toDouble(); + qreal m31 = settings.value("matrix_view.m31", param_matrixWorld.m31()).toDouble(); + qreal m32 = settings.value("matrix_view.m32", param_matrixWorld.m32()).toDouble(); + qreal m33 = settings.value("matrix_view.m33", param_matrixWorld.m33()).toDouble(); + + param_matrixWorld = QTransform(m11, m12, m13, m21, m22, m23, m31, m32, m33); +} + + +double DefaultViewPort::getRatio() +{ + return param_keepRatio; +} + + +void DefaultViewPort::setRatio(int flags) +{ + if (getRatio() == flags) //nothing to do + return; + + //if valid flags + if (flags == CV_WINDOW_FREERATIO || flags == CV_WINDOW_KEEPRATIO) + { + centralWidget->param_ratio_mode = flags; + param_keepRatio = flags; + updateGeometry(); + viewport()->update(); + } +} + + +void DefaultViewPort::updateImage(const CvArr* arr) +{ + CV_Assert(arr); + + CvMat* mat, stub; + int origin = 0; + + if (CV_IS_IMAGE_HDR(arr)) + origin = ((IplImage*)arr)->origin; + + mat = cvGetMat(arr, &stub); + + if (!image2Draw_mat || !CV_ARE_SIZES_EQ(image2Draw_mat, mat)) + { + if (image2Draw_mat) + cvReleaseMat(&image2Draw_mat); + + //the image in ipl (to do a deep copy with cvCvtColor) + image2Draw_mat = cvCreateMat(mat->rows, mat->cols, CV_8UC3); + image2Draw_qt = QImage(image2Draw_mat->data.ptr, image2Draw_mat->cols, image2Draw_mat->rows, image2Draw_mat->step, QImage::Format_RGB888); + + //use to compute mouse coordinate, I need to update the ratio here and in resizeEvent + ratioX = width() / float(image2Draw_mat->cols); + ratioY = height() / float(image2Draw_mat->rows); + + updateGeometry(); + } + + nbChannelOriginImage = cvGetElemType(mat); + + cvConvertImage(mat, image2Draw_mat, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB); + + viewport()->update(); +} + + +void DefaultViewPort::startDisplayInfo(QString text, int delayms) +{ + if (timerDisplay->isActive()) + stopDisplayInfo(); + + infoText = text; + if (delayms > 0) timerDisplay->start(delayms); + drawInfo = true; +} + + +void DefaultViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback /*callback*/, void* /*userdata*/) +{ + CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); +} + + +void DefaultViewPort::makeCurrentOpenGlContext() +{ + CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); +} + + +void DefaultViewPort::updateGl() +{ + CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); +} + + +//Note: move 2 percent of the window +void DefaultViewPort::siftWindowOnLeft() +{ + float delta = 2 * width() / (100.0 * param_matrixWorld.m11()); + moveView(QPointF(delta, 0)); +} + + +//Note: move 2 percent of the window +void DefaultViewPort::siftWindowOnRight() +{ + float delta = -2 * width() / (100.0 * param_matrixWorld.m11()); + moveView(QPointF(delta, 0)); +} + + +//Note: move 2 percent of the window +void DefaultViewPort::siftWindowOnUp() +{ + float delta = 2 * height() / (100.0 * param_matrixWorld.m11()); + moveView(QPointF(0, delta)); +} + + +//Note: move 2 percent of the window +void DefaultViewPort::siftWindowOnDown() +{ + float delta = -2 * height() / (100.0 * param_matrixWorld.m11()); + moveView(QPointF(0, delta)); +} + + +void DefaultViewPort::imgRegion() +{ + scaleView((threshold_zoom_img_region / param_matrixWorld.m11() - 1) * 5, QPointF(size().width() / 2, size().height() / 2)); +} + + +void DefaultViewPort::resetZoom() +{ + param_matrixWorld.reset(); + controlImagePosition(); +} + + +void DefaultViewPort::ZoomIn() +{ + scaleView(0.5, QPointF(size().width() / 2, size().height() / 2)); +} + + +void DefaultViewPort::ZoomOut() +{ + scaleView(-0.5, QPointF(size().width() / 2, size().height() / 2)); +} + + +//can save as JPG, JPEG, BMP, PNG +void DefaultViewPort::saveView() +{ + QDate date_d = QDate::currentDate(); + QString date_s = date_d.toString("dd.MM.yyyy"); + QString name_s = centralWidget->windowTitle() + "_screenshot_" + date_s; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File %1").arg(name_s), name_s + ".png", tr("Images (*.png *.jpg *.bmp *.jpeg)")); + + if (!fileName.isEmpty()) //save the picture + { + QString extension = fileName.right(3); + + // (no need anymore) create the image resized to receive the 'screenshot' + // image2Draw_qt_resized = QImage(viewport()->width(), viewport()->height(),QImage::Format_RGB888); + + QPainter saveimage(&image2Draw_qt_resized); + this->render(&saveimage); + + // Save it.. + if (QString::compare(extension, "png", Qt::CaseInsensitive) == 0) + { + image2Draw_qt_resized.save(fileName, "PNG"); + return; + } + + if (QString::compare(extension, "jpg", Qt::CaseInsensitive) == 0) + { + image2Draw_qt_resized.save(fileName, "JPG"); + return; + } + + if (QString::compare(extension, "bmp", Qt::CaseInsensitive) == 0) + { + image2Draw_qt_resized.save(fileName, "BMP"); + return; + } + + if (QString::compare(extension, "jpeg", Qt::CaseInsensitive) == 0) + { + image2Draw_qt_resized.save(fileName, "JPEG"); + return; + } + + CV_Error(CV_StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG"); + } +} + + +void DefaultViewPort::contextMenuEvent(QContextMenuEvent* evnt) +{ + if (centralWidget->vect_QActions.size() > 0) + { + QMenu menu(this); + + foreach (QAction *a, centralWidget->vect_QActions) + menu.addAction(a); + + menu.exec(evnt->globalPos()); + } +} + + +void DefaultViewPort::resizeEvent(QResizeEvent* evnt) +{ + controlImagePosition(); + + //use to compute mouse coordinate, I need to update the ratio here and in resizeEvent + ratioX = width() / float(image2Draw_mat->cols); + ratioY = height() / float(image2Draw_mat->rows); + + if (param_keepRatio == CV_WINDOW_KEEPRATIO)//to keep the same aspect ratio + { + QSize newSize = QSize(image2Draw_mat->cols, image2Draw_mat->rows); + newSize.scale(evnt->size(), Qt::KeepAspectRatio); + + //imageWidth/imageHeight = newWidth/newHeight +/- epsilon + //ratioX = ratioY +/- epsilon + //||ratioX - ratioY|| = epsilon + if (fabs(ratioX - ratioY) * 100 > ratioX) //avoid infinity loop / epsilon = 1% of ratioX + { + resize(newSize); + + //move to the middle + //newSize get the delta offset to place the picture in the middle of its parent + newSize = (evnt->size() - newSize) / 2; + + //if the toolbar is displayed, avoid drawing myview on top of it + if (centralWidget->myToolBar) + if(!centralWidget->myToolBar->isHidden()) + newSize += QSize(0, centralWidget->myToolBar->height()); + + move(newSize.width(), newSize.height()); + } + } + + return QGraphicsView::resizeEvent(evnt); +} + + +void DefaultViewPort::wheelEvent(QWheelEvent* evnt) +{ + scaleView(evnt->delta() / 240.0, evnt->pos()); + viewport()->update(); +} + + +void DefaultViewPort::mousePressEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + //icvmouseHandler: pass parameters for cv_event, flags + icvmouseHandler(evnt, mouse_down, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + if (param_matrixWorld.m11()>1) + { + setCursor(Qt::ClosedHandCursor); + positionGrabbing = evnt->pos(); + } + + QWidget::mousePressEvent(evnt); +} + + +void DefaultViewPort::mouseReleaseEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + //icvmouseHandler: pass parameters for cv_event, flags + icvmouseHandler(evnt, mouse_up, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + if (param_matrixWorld.m11()>1) + setCursor(Qt::OpenHandCursor); + + QWidget::mouseReleaseEvent(evnt); +} + + +void DefaultViewPort::mouseDoubleClickEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + //icvmouseHandler: pass parameters for cv_event, flags + icvmouseHandler(evnt, mouse_dbclick, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + QWidget::mouseDoubleClickEvent(evnt); +} + + +void DefaultViewPort::mouseMoveEvent(QMouseEvent* evnt) +{ + int cv_event = CV_EVENT_MOUSEMOVE, flags = 0; + QPoint pt = evnt->pos(); + + //icvmouseHandler: pass parameters for cv_event, flags + icvmouseHandler(evnt, mouse_move, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + if (param_matrixWorld.m11() > 1 && evnt->buttons() == Qt::LeftButton) + { + QPointF dxy = (pt - positionGrabbing)/param_matrixWorld.m11(); + positionGrabbing = evnt->pos(); + moveView(dxy); + } + + //I update the statusbar here because if the user does a cvWaitkey(0) (like with inpaint.cpp) + //the status bar will only be repaint when a click occurs. + if (centralWidget->myStatusBar) + viewport()->update(); + + QWidget::mouseMoveEvent(evnt); +} + + +void DefaultViewPort::paintEvent(QPaintEvent* evnt) +{ + QPainter myPainter(viewport()); + myPainter.setWorldTransform(param_matrixWorld); + + draw2D(&myPainter); + + //Now disable matrixWorld for overlay display + myPainter.setWorldMatrixEnabled(false); + + //in mode zoom/panning + if (param_matrixWorld.m11() > 1) + { + if (param_matrixWorld.m11() >= threshold_zoom_img_region) + { + if (centralWidget->param_flags == CV_WINDOW_NORMAL) + startDisplayInfo("WARNING: The values displayed are the resized image's values. If you want the original image's values, use CV_WINDOW_AUTOSIZE", 1000); + + drawImgRegion(&myPainter); + } + + drawViewOverview(&myPainter); + } + + //for information overlay + if (drawInfo) + drawInstructions(&myPainter); + + //for statusbar + if (centralWidget->myStatusBar) + drawStatusBar(); + + QGraphicsView::paintEvent(evnt); +} + + +void DefaultViewPort::stopDisplayInfo() +{ + timerDisplay->stop(); + drawInfo = false; +} + + +inline bool DefaultViewPort::isSameSize(IplImage* img1, IplImage* img2) +{ + return img1->width == img2->width && img1->height == img2->height; +} + + +void DefaultViewPort::controlImagePosition() +{ + qreal left, top, right, bottom; + + //after check top-left, bottom right corner to avoid getting "out" during zoom/panning + param_matrixWorld.map(0,0,&left,&top); + + if (left > 0) + { + param_matrixWorld.translate(-left,0); + left = 0; + } + if (top > 0) + { + param_matrixWorld.translate(0,-top); + top = 0; + } + //------- + + QSize sizeImage = size(); + param_matrixWorld.map(sizeImage.width(),sizeImage.height(),&right,&bottom); + if (right < sizeImage.width()) + { + param_matrixWorld.translate(sizeImage.width()-right,0); + right = sizeImage.width(); + } + if (bottom < sizeImage.height()) + { + param_matrixWorld.translate(0,sizeImage.height()-bottom); + bottom = sizeImage.height(); + } + + //save corner position + positionCorners.setTopLeft(QPoint(left,top)); + positionCorners.setBottomRight(QPoint(right,bottom)); + //save also the inv matrix + matrixWorld_inv = param_matrixWorld.inverted(); + + //viewport()->update(); +} + +void DefaultViewPort::moveView(QPointF delta) +{ + param_matrixWorld.translate(delta.x(),delta.y()); + controlImagePosition(); + viewport()->update(); +} + +//factor is -0.5 (zoom out) or 0.5 (zoom in) +void DefaultViewPort::scaleView(qreal factor,QPointF center) +{ + factor/=5;//-0.1 <-> 0.1 + factor+=1;//0.9 <-> 1.1 + + //limit zoom out --- + if (param_matrixWorld.m11()==1 && factor < 1) + return; + + if (param_matrixWorld.m11()*factor<1) + factor = 1/param_matrixWorld.m11(); + + + //limit zoom int --- + if (param_matrixWorld.m11()>100 && factor > 1) + return; + + //inverse the transform + int a, b; + matrixWorld_inv.map(center.x(),center.y(),&a,&b); + + param_matrixWorld.translate(a-factor*a,b-factor*b); + param_matrixWorld.scale(factor,factor); + + controlImagePosition(); + + //display new zoom + if (centralWidget->myStatusBar) + centralWidget->displayStatusBar(tr("Zoom: %1%").arg(param_matrixWorld.m11()*100),1000); + + if (param_matrixWorld.m11()>1) + setCursor(Qt::OpenHandCursor); + else + unsetCursor(); +} + + +//up, down, dclick, move +void DefaultViewPort::icvmouseHandler(QMouseEvent *evnt, type_mouse_event category, int &cv_event, int &flags) +{ + Qt::KeyboardModifiers modifiers = evnt->modifiers(); + Qt::MouseButtons buttons = evnt->buttons(); + + flags = 0; + if(modifiers & Qt::ShiftModifier) + flags |= CV_EVENT_FLAG_SHIFTKEY; + if(modifiers & Qt::ControlModifier) + flags |= CV_EVENT_FLAG_CTRLKEY; + if(modifiers & Qt::AltModifier) + flags |= CV_EVENT_FLAG_ALTKEY; + + if(buttons & Qt::LeftButton) + flags |= CV_EVENT_FLAG_LBUTTON; + if(buttons & Qt::RightButton) + flags |= CV_EVENT_FLAG_RBUTTON; + if(buttons & Qt::MidButton) + flags |= CV_EVENT_FLAG_MBUTTON; + + cv_event = CV_EVENT_MOUSEMOVE; + switch(evnt->button()) + { + case Qt::LeftButton: + cv_event = tableMouseButtons[category][0]; + flags |= CV_EVENT_FLAG_LBUTTON; + break; + case Qt::RightButton: + cv_event = tableMouseButtons[category][1]; + flags |= CV_EVENT_FLAG_RBUTTON; + break; + case Qt::MidButton: + cv_event = tableMouseButtons[category][2]; + flags |= CV_EVENT_FLAG_MBUTTON; + break; + default:; + } +} + + +void DefaultViewPort::icvmouseProcessing(QPointF pt, int cv_event, int flags) +{ + //to convert mouse coordinate + qreal pfx, pfy; + matrixWorld_inv.map(pt.x(),pt.y(),&pfx,&pfy); + + mouseCoordinate.rx()=floor(pfx/ratioX); + mouseCoordinate.ry()=floor(pfy/ratioY); + + if (on_mouse) + on_mouse( cv_event, mouseCoordinate.x(), + mouseCoordinate.y(), flags, on_mouse_param ); +} + + +QSize DefaultViewPort::sizeHint() const +{ + if(image2Draw_mat) + return QSize(image2Draw_mat->cols, image2Draw_mat->rows); + else + return QGraphicsView::sizeHint(); +} + + +void DefaultViewPort::draw2D(QPainter *painter) +{ + image2Draw_qt = QImage(image2Draw_mat->data.ptr, image2Draw_mat->cols, image2Draw_mat->rows,image2Draw_mat->step,QImage::Format_RGB888); + painter->drawImage(QRect(0,0,viewport()->width(),viewport()->height()), image2Draw_qt, QRect(0,0, image2Draw_qt.width(), image2Draw_qt.height()) ); +} + +//only if CV_8UC1 or CV_8UC3 +void DefaultViewPort::drawStatusBar() +{ + if (nbChannelOriginImage!=CV_8UC1 && nbChannelOriginImage!=CV_8UC3) + return; + + if (mouseCoordinate.x()>=0 && + mouseCoordinate.y()>=0 && + mouseCoordinate.x()=0 && mouseCoordinate.y()>=0) + { + QRgb rgbValue = image2Draw_qt.pixel(mouseCoordinate); + + if (nbChannelOriginImage==CV_8UC3 ) + { + centralWidget->myStatusBar_msg->setText(tr("(x=%1, y=%2) ~ ") + .arg(mouseCoordinate.x()) + .arg(mouseCoordinate.y())+ + tr("R:%3 ").arg(qRed(rgbValue))+//.arg(value.val[0])+ + tr("G:%4 ").arg(qGreen(rgbValue))+//.arg(value.val[1])+ + tr("B:%5").arg(qBlue(rgbValue))//.arg(value.val[2]) + ); + } + + if (nbChannelOriginImage==CV_8UC1) + { + //all the channel have the same value (because of cvconvertimage), so only the r channel is dsplayed + centralWidget->myStatusBar_msg->setText(tr("(x=%1, y=%2) ~ ") + .arg(mouseCoordinate.x()) + .arg(mouseCoordinate.y())+ + tr("L:%3 ").arg(qRed(rgbValue)) + ); + } + } +} + +//accept only CV_8UC1 and CV_8UC8 image for now +void DefaultViewPort::drawImgRegion(QPainter *painter) +{ + + if (nbChannelOriginImage!=CV_8UC1 && nbChannelOriginImage!=CV_8UC3) + return; + + qreal offsetX = param_matrixWorld.dx()/param_matrixWorld.m11(); + offsetX = offsetX - floor(offsetX); + qreal offsetY = param_matrixWorld.dy()/param_matrixWorld.m11(); + offsetY = offsetY - floor(offsetY); + + QSize view = size(); + QVarLengthArray linesX; + for (qreal _x = offsetX*param_matrixWorld.m11(); _x < view.width(); _x += param_matrixWorld.m11() ) + linesX.append(QLineF(_x, 0, _x, view.height())); + + QVarLengthArray linesY; + for (qreal _y = offsetY*param_matrixWorld.m11(); _y < view.height(); _y += param_matrixWorld.m11() ) + linesY.append(QLineF(0, _y, view.width(), _y)); + + + QFont f = painter->font(); + int original_font_size = f.pointSize(); + //change font size + //f.setPointSize(4+(param_matrixWorld.m11()-threshold_zoom_img_region)/5); + f.setPixelSize(10+(param_matrixWorld.m11()-threshold_zoom_img_region)/5); + painter->setFont(f); + QString val; + QRgb rgbValue; + + QPointF point1;//sorry, I do not know how to name it + QPointF point2;//idem + + for (int j=-1;j= 0 && point2.y() >= 0) + rgbValue = image2Draw_qt_resized.pixel(QPoint(point2.x(),point2.y())); + else + rgbValue = qRgb(0,0,0); + + if (nbChannelOriginImage==CV_8UC3) + { + //for debug + /* + val = tr("%1 %2").arg(point2.x()).arg(point2.y()); + painter->setPen(QPen(Qt::black, 1)); + painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/2), + Qt::AlignCenter, val); + */ + + val = tr("%1").arg(qRed(rgbValue)); + painter->setPen(QPen(Qt::red, 1)); + painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/3), + Qt::AlignCenter, val); + + val = tr("%1").arg(qGreen(rgbValue)); + painter->setPen(QPen(Qt::green, 1)); + painter->drawText(QRect(point1.x(),point1.y()+param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3), + Qt::AlignCenter, val); + + val = tr("%1").arg(qBlue(rgbValue)); + painter->setPen(QPen(Qt::blue, 1)); + painter->drawText(QRect(point1.x(),point1.y()+2*param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3), + Qt::AlignCenter, val); + + } + + if (nbChannelOriginImage==CV_8UC1) + { + + val = tr("%1").arg(qRed(rgbValue)); + painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()), + Qt::AlignCenter, val); + } + } + + painter->setPen(QPen(Qt::black, 1)); + painter->drawLines(linesX.data(), linesX.size()); + painter->drawLines(linesY.data(), linesY.size()); + + //restore font size + f.setPointSize(original_font_size); + painter->setFont(f); + +} + +void DefaultViewPort::drawViewOverview(QPainter *painter) +{ + QSize viewSize = size(); + viewSize.scale ( 100, 100,Qt::KeepAspectRatio ); + + const int margin = 5; + + //draw the image's location + painter->setBrush(QColor(0, 0, 0, 127)); + painter->setPen(Qt::darkGreen); + painter->drawRect(QRect(width()-viewSize.width()-margin, 0,viewSize.width(),viewSize.height())); + + //daw the view's location inside the image + qreal ratioSize = 1/param_matrixWorld.m11(); + qreal ratioWindow = (qreal)(viewSize.height())/(qreal)(size().height()); + painter->setPen(Qt::darkBlue); + painter->drawRect(QRectF(width()-viewSize.width()-positionCorners.left()*ratioSize*ratioWindow-margin, + -positionCorners.top()*ratioSize*ratioWindow, + (viewSize.width()-1)*ratioSize, + (viewSize.height()-1)*ratioSize) + ); +} + +void DefaultViewPort::drawInstructions(QPainter *painter) +{ + QFontMetrics metrics = QFontMetrics(font()); + int border = qMax(4, metrics.leading()); + + QRect qrect = metrics.boundingRect(0, 0, width() - 2*border, int(height()*0.125), + Qt::AlignCenter | Qt::TextWordWrap, infoText); + painter->setRenderHint(QPainter::TextAntialiasing); + painter->fillRect(QRect(0, 0, width(), qrect.height() + 2*border), + QColor(0, 0, 0, 127)); + painter->setPen(Qt::white); + painter->fillRect(QRect(0, 0, width(), qrect.height() + 2*border), + QColor(0, 0, 0, 127)); + + painter->drawText((width() - qrect.width())/2, border, + qrect.width(), qrect.height(), + Qt::AlignCenter | Qt::TextWordWrap, infoText); +} + + +void DefaultViewPort::setSize(QSize /*size_*/) +{ +} + + +////////////////////////////////////////////////////// +// OpenGlViewPort + +#ifdef HAVE_QT_OPENGL + +OpenGlViewPort::OpenGlViewPort(QWidget* _parent) : QGLWidget(_parent), size(-1, -1) +{ + mouseCallback = 0; + mouseData = 0; + + glDrawCallback = 0; + glDrawData = 0; +} + +OpenGlViewPort::~OpenGlViewPort() +{ +} + +QWidget* OpenGlViewPort::getWidget() +{ + return this; +} + +void OpenGlViewPort::setMouseCallBack(CvMouseCallback callback, void* param) +{ + mouseCallback = callback; + mouseData = param; +} + +void OpenGlViewPort::writeSettings(QSettings& /*settings*/) +{ +} + +void OpenGlViewPort::readSettings(QSettings& /*settings*/) +{ +} + +double OpenGlViewPort::getRatio() +{ + return (double)width() / height(); +} + +void OpenGlViewPort::setRatio(int /*flags*/) +{ +} + +void OpenGlViewPort::updateImage(const CvArr* /*arr*/) +{ +} + +void OpenGlViewPort::startDisplayInfo(QString /*text*/, int /*delayms*/) +{ +} + +void OpenGlViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) +{ + glDrawCallback = callback; + glDrawData = userdata; +} + +void OpenGlViewPort::makeCurrentOpenGlContext() +{ + makeCurrent(); +} + +void OpenGlViewPort::updateGl() +{ + QGLWidget::updateGL(); +} + +void OpenGlViewPort::initializeGL() +{ + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +} + +void OpenGlViewPort::resizeGL(int w, int h) +{ + glViewport(0, 0, w, h); +} + +void OpenGlViewPort::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (glDrawCallback) + glDrawCallback(glDrawData); +} + +void OpenGlViewPort::mousePressEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + icvmouseHandler(evnt, mouse_down, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + QGLWidget::mousePressEvent(evnt); +} + + +void OpenGlViewPort::mouseReleaseEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + icvmouseHandler(evnt, mouse_up, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + QGLWidget::mouseReleaseEvent(evnt); +} + + +void OpenGlViewPort::mouseDoubleClickEvent(QMouseEvent* evnt) +{ + int cv_event = -1, flags = 0; + QPoint pt = evnt->pos(); + + icvmouseHandler(evnt, mouse_dbclick, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + QGLWidget::mouseDoubleClickEvent(evnt); +} + + +void OpenGlViewPort::mouseMoveEvent(QMouseEvent* evnt) +{ + int cv_event = CV_EVENT_MOUSEMOVE, flags = 0; + QPoint pt = evnt->pos(); + + //icvmouseHandler: pass parameters for cv_event, flags + icvmouseHandler(evnt, mouse_move, cv_event, flags); + icvmouseProcessing(QPointF(pt), cv_event, flags); + + QGLWidget::mouseMoveEvent(evnt); +} + +void OpenGlViewPort::icvmouseHandler(QMouseEvent* evnt, type_mouse_event category, int& cv_event, int& flags) +{ + Qt::KeyboardModifiers modifiers = evnt->modifiers(); + Qt::MouseButtons buttons = evnt->buttons(); + + flags = 0; + if (modifiers & Qt::ShiftModifier) + flags |= CV_EVENT_FLAG_SHIFTKEY; + if (modifiers & Qt::ControlModifier) + flags |= CV_EVENT_FLAG_CTRLKEY; + if (modifiers & Qt::AltModifier) + flags |= CV_EVENT_FLAG_ALTKEY; + + if (buttons & Qt::LeftButton) + flags |= CV_EVENT_FLAG_LBUTTON; + if (buttons & Qt::RightButton) + flags |= CV_EVENT_FLAG_RBUTTON; + if (buttons & Qt::MidButton) + flags |= CV_EVENT_FLAG_MBUTTON; + + cv_event = CV_EVENT_MOUSEMOVE; + switch (evnt->button()) + { + case Qt::LeftButton: + cv_event = tableMouseButtons[category][0]; + flags |= CV_EVENT_FLAG_LBUTTON; + break; + + case Qt::RightButton: + cv_event = tableMouseButtons[category][1]; + flags |= CV_EVENT_FLAG_RBUTTON; + break; + + case Qt::MidButton: + cv_event = tableMouseButtons[category][2]; + flags |= CV_EVENT_FLAG_MBUTTON; + break; + + default: + ; + } +} + + +void OpenGlViewPort::icvmouseProcessing(QPointF pt, int cv_event, int flags) +{ + if (mouseCallback) + mouseCallback(cv_event, pt.x(), pt.y(), flags, mouseData); +} + + +QSize OpenGlViewPort::sizeHint() const +{ + if (size.width() > 0 && size.height() > 0) + return size; + + return QGLWidget::sizeHint(); +} + +void OpenGlViewPort::setSize(QSize size_) +{ + size = size_; + updateGeometry(); +} + +#endif + +#endif // HAVE_QT diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.h diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.h --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,564 @@ +//IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. + + +// License Agreement +// For Open Source Computer Vision Library + +//Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +//Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved. +//Third party copyrights are property of their respective owners. + +//Redistribution and use in source and binary forms, with or without modification, +//are permitted provided that the following conditions are met: + +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. + +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. + +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. + +//This software is provided by the copyright holders and contributors "as is" and +//any express or implied warranties, including, but not limited to, the implied +//warranties of merchantability and fitness for a particular purpose are disclaimed. +//In no event shall the Intel Corporation or contributors be liable for any direct, +//indirect, incidental, special, exemplary, or consequential damages +//(including, but not limited to, procurement of substitute goods or services; +//loss of use, data, or profits; or business interruption) however caused +//and on any theory of liability, whether in contract, strict liability, +//or tort (including negligence or otherwise) arising in any way out of +//the use of this software, even if advised of the possibility of such damage. + +//--------------------Google Code 2010 -- Yannick Verdie--------------------// +#ifndef __OPENCV_HIGHGUI_QT_H__ +#define __OPENCV_HIGHGUI_QT_H__ + +#include "precomp.hpp" + +#if defined( HAVE_QT_OPENGL ) +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//start private enum +enum { CV_MODE_NORMAL = 0, CV_MODE_OPENGL = 1 }; + +//we can change the keyboard shortcuts from here ! +enum { shortcut_zoom_normal = Qt::CTRL + Qt::Key_Z, + shortcut_zoom_imgRegion = Qt::CTRL + Qt::Key_X, + shortcut_save_img = Qt::CTRL + Qt::Key_S, + shortcut_properties_win = Qt::CTRL + Qt::Key_P, + shortcut_zoom_in = Qt::CTRL + Qt::Key_Plus,//QKeySequence(QKeySequence::ZoomIn), + shortcut_zoom_out = Qt::CTRL + Qt::Key_Minus,//QKeySequence(QKeySequence::ZoomOut), + shortcut_panning_left = Qt::CTRL + Qt::Key_Left, + shortcut_panning_right = Qt::CTRL + Qt::Key_Right, + shortcut_panning_up = Qt::CTRL + Qt::Key_Up, + shortcut_panning_down = Qt::CTRL + Qt::Key_Down + }; + +//end enum + +class CvWindow; +class ViewPort; + + +class GuiReceiver : public QObject +{ + Q_OBJECT + +public: + GuiReceiver(); + ~GuiReceiver(); + + int start(); + void isLastWindow(); + + bool bTimeOut; + QTimer* timer; + +public slots: + void createWindow( QString name, int flags = 0 ); + void destroyWindow(QString name); + void destroyAllWindow(); + void addSlider(QString trackbar_name, QString window_name, void* value, int count, void* on_change); + void addSlider2(QString trackbar_name, QString window_name, void* value, int count, void* on_change, void *userdata); + void moveWindow(QString name, int x, int y); + void resizeWindow(QString name, int width, int height); + void showImage(QString name, void* arr); + void displayInfo( QString name, QString text, int delayms ); + void displayStatusBar( QString name, QString text, int delayms ); + void timeOut(); + void toggleFullScreen(QString name, double flags ); + double isFullScreen(QString name); + double getPropWindow(QString name); + void setPropWindow(QString name, double flags ); + double getRatioWindow(QString name); + void setRatioWindow(QString name, double arg2 ); + void saveWindowParameters(QString name); + void loadWindowParameters(QString name); + void putText(void* arg1, QString text, QPoint org, void* font); + void addButton(QString button_name, int button_type, int initial_button_state , void* on_change, void* userdata); + void enablePropertiesButtonEachWindow(); + + void setOpenGlDrawCallback(QString name, void* callback, void* userdata); + void setOpenGlContext(QString name); + void updateWindow(QString name); + double isOpenGl(QString name); + +private: + int nb_windows; + bool doesExternalQAppExist; +}; + + +enum typeBar { type_CvTrackbar = 0, type_CvButtonbar = 1 }; +class CvBar : public QHBoxLayout +{ +public: + typeBar type; + QString name_bar; + QPointer myparent; +}; + + +class CvButtonbar : public CvBar +{ + Q_OBJECT +public: + CvButtonbar(QWidget* arg, QString bar_name); + + void addButton(QString button_name, CvButtonCallback call, void* userdata, int button_type, int initial_button_state); + +private: + void setLabel(); + + QPointer label; + QPointer group_button; +}; + + +class CvPushButton : public QPushButton +{ + Q_OBJECT +public: + CvPushButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata); + +private: + CvButtonbar* myparent; + QString button_name ; + CvButtonCallback callback; + void* userdata; + +private slots: + void callCallBack(bool); +}; + + +class CvCheckBox : public QCheckBox +{ + Q_OBJECT +public: + CvCheckBox(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state); + +private: + CvButtonbar* myparent; + QString button_name ; + CvButtonCallback callback; + void* userdata; + +private slots: + void callCallBack(bool); +}; + + +class CvRadioButton : public QRadioButton +{ + Q_OBJECT +public: + CvRadioButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state); + +private: + CvButtonbar* myparent; + QString button_name ; + CvButtonCallback callback; + void* userdata; + +private slots: + void callCallBack(bool); +}; + + +class CvTrackbar : public CvBar +{ + Q_OBJECT +public: + CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback on_change); + CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* data); + + QPointer slider; + +private slots: + void createDialog(); + void update(int myvalue); + +private: + void setLabel(int myvalue); + void create(CvWindow* arg, QString name, int* value, int count); + QString createLabel(); + QPointer label; + CvTrackbarCallback callback; + CvTrackbarCallback2 callback2;//look like it is use by python binding + int* dataSlider; + void* userdata; +}; + +//Both are top level window, so that a way to differenciate them. +//if (obj->metaObject ()->className () == "CvWindow") does not give me robust result + +enum typeWindow { type_CvWindow = 1, type_CvWinProperties = 2 }; +class CvWinModel : public QWidget +{ +public: +typeWindow type; +}; + + +class CvWinProperties : public CvWinModel +{ + Q_OBJECT +public: + CvWinProperties(QString name, QObject* parent); + ~CvWinProperties(); + QPointer myLayout; + +private: + void closeEvent ( QCloseEvent * e ); + void showEvent ( QShowEvent * event ) ; + void hideEvent ( QHideEvent * event ) ; +}; + + +class CvWindow : public CvWinModel +{ + Q_OBJECT +public: + CvWindow(QString arg2, int flag = CV_WINDOW_NORMAL); + ~CvWindow(); + + void setMouseCallBack(CvMouseCallback m, void* param); + + void writeSettings(); + void readSettings(); + + double getRatio(); + void setRatio(int flags); + + int getPropWindow(); + void setPropWindow(int flags); + + void toggleFullScreen(int flags); + + void updateImage(void* arr); + + void displayInfo(QString text, int delayms); + void displayStatusBar(QString text, int delayms); + + void enablePropertiesButton(); + + static CvButtonbar* createButtonBar(QString bar_name); + + static void addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL)); + static void addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(0)); + + void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); + void makeCurrentOpenGlContext(); + void updateGl(); + bool isOpenGl(); + + void setViewportSize(QSize size); + + //parameters (will be save/load) + int param_flags; + int param_gui_mode; + int param_ratio_mode; + + QPointer myGlobalLayout; //All the widget (toolbar, view, LayoutBar, ...) are attached to it + QPointer myBarLayout; + + QVector vect_QActions; + + QPointer myStatusBar; + QPointer myToolBar; + QPointer myStatusBar_msg; + +protected: + virtual void keyPressEvent(QKeyEvent* event); + +private: + + int mode_display; //opengl or native + ViewPort* myView; + + QVector vect_QShortcuts; + + void icvLoadTrackbars(QSettings *settings); + void icvSaveTrackbars(QSettings *settings); + void icvLoadControlPanel(); + void icvSaveControlPanel(); + void icvLoadButtonbar(CvButtonbar* t,QSettings *settings); + void icvSaveButtonbar(CvButtonbar* t,QSettings *settings); + + void createActions(); + void createShortcuts(); + void createToolBar(); + void createView(); + void createStatusBar(); + void createGlobalLayout(); + void createBarLayout(); + CvWinProperties* createParameterWindow(); + + void hideTools(); + void showTools(); + QSize getAvailableSize(); + +private slots: + void displayPropertiesWin(); +}; + + +enum type_mouse_event { mouse_up = 0, mouse_down = 1, mouse_dbclick = 2, mouse_move = 3 }; +static const int tableMouseButtons[][3]={ + {CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP}, //mouse_up + {CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN}, //mouse_down + {CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK}, //mouse_dbclick + {CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE} //mouse_move +}; + + +class ViewPort +{ +public: + virtual ~ViewPort() {} + + virtual QWidget* getWidget() = 0; + + virtual void setMouseCallBack(CvMouseCallback callback, void* param) = 0; + + virtual void writeSettings(QSettings& settings) = 0; + virtual void readSettings(QSettings& settings) = 0; + + virtual double getRatio() = 0; + virtual void setRatio(int flags) = 0; + + virtual void updateImage(const CvArr* arr) = 0; + + virtual void startDisplayInfo(QString text, int delayms) = 0; + + virtual void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) = 0; + virtual void makeCurrentOpenGlContext() = 0; + virtual void updateGl() = 0; + + virtual void setSize(QSize size_) = 0; +}; + + + +#ifdef HAVE_QT_OPENGL + +class OpenGlViewPort : public QGLWidget, public ViewPort +{ +public: + explicit OpenGlViewPort(QWidget* parent); + ~OpenGlViewPort(); + + QWidget* getWidget(); + + void setMouseCallBack(CvMouseCallback callback, void* param); + + void writeSettings(QSettings& settings); + void readSettings(QSettings& settings); + + double getRatio(); + void setRatio(int flags); + + void updateImage(const CvArr* arr); + + void startDisplayInfo(QString text, int delayms); + + void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); + void makeCurrentOpenGlContext(); + void updateGl(); + + void setSize(QSize size_); + +protected: + void initializeGL(); + void resizeGL(int w, int h); + void paintGL(); + + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void mouseDoubleClickEvent(QMouseEvent* event); + + QSize sizeHint() const; + +private: + QSize size; + + CvMouseCallback mouseCallback; + void* mouseData; + + CvOpenGlDrawCallback glDrawCallback; + void* glDrawData; + + void icvmouseHandler(QMouseEvent* event, type_mouse_event category, int& cv_event, int& flags); + void icvmouseProcessing(QPointF pt, int cv_event, int flags); +}; + +#endif // HAVE_QT_OPENGL + + +class DefaultViewPort : public QGraphicsView, public ViewPort +{ + Q_OBJECT + +public: + DefaultViewPort(CvWindow* centralWidget, int arg2); + ~DefaultViewPort(); + + QWidget* getWidget(); + + void setMouseCallBack(CvMouseCallback callback, void* param); + + void writeSettings(QSettings& settings); + void readSettings(QSettings& settings); + + double getRatio(); + void setRatio(int flags); + + void updateImage(const CvArr* arr); + + void startDisplayInfo(QString text, int delayms); + + void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); + void makeCurrentOpenGlContext(); + void updateGl(); + + void setSize(QSize size_); + +public slots: + //reference: + //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming + //http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html + + void siftWindowOnLeft(); + void siftWindowOnRight(); + void siftWindowOnUp() ; + void siftWindowOnDown(); + + void resetZoom(); + void imgRegion(); + void ZoomIn(); + void ZoomOut(); + + void saveView(); + +protected: + void contextMenuEvent(QContextMenuEvent* event); + void resizeEvent(QResizeEvent* event); + void paintEvent(QPaintEvent* paintEventInfo); + void wheelEvent(QWheelEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void mouseDoubleClickEvent(QMouseEvent* event); + +private: + int param_keepRatio; + + //parameters (will be save/load) + QTransform param_matrixWorld; + + CvMat* image2Draw_mat; + QImage image2Draw_qt; + QImage image2Draw_qt_resized; + int nbChannelOriginImage; + + //for mouse callback + CvMouseCallback on_mouse; + void* on_mouse_param; + + + void scaleView(qreal scaleFactor, QPointF center); + void moveView(QPointF delta); + + QPoint mouseCoordinate; + QPointF positionGrabbing; + QRect positionCorners; + QTransform matrixWorld_inv; + float ratioX, ratioY; + + bool isSameSize(IplImage* img1,IplImage* img2); + + QSize sizeHint() const; + QPointer centralWidget; + QPointer timerDisplay; + bool drawInfo; + QString infoText; + QRectF target; + + void drawInstructions(QPainter *painter); + void drawViewOverview(QPainter *painter); + void drawImgRegion(QPainter *painter); + void draw2D(QPainter *painter); + void drawStatusBar(); + void controlImagePosition(); + void icvmouseHandler(QMouseEvent *event, type_mouse_event category, int &cv_event, int &flags); + void icvmouseProcessing(QPointF pt, int cv_event, int flags); + +private slots: + void stopDisplayInfo(); +}; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.qrc diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.qrc --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_QT.qrc 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_QT.qrc 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,15 @@ + + + files_Qt/Milky/48/28.png + files_Qt/Milky/48/23.png + files_Qt/Milky/48/19.png + files_Qt/Milky/48/24.png + files_Qt/Milky/48/27.png + files_Qt/Milky/48/61.png + files_Qt/Milky/48/106.png + files_Qt/Milky/48/107.png + files_Qt/Milky/48/7.png + files_Qt/Milky/48/38.png + files_Qt/stylesheet_trackbar.qss + + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_carbon.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/window_carbon.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_carbon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_carbon.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1100 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#include +#include //YV + +#include +#include +#include + +//#define MS_TO_TICKS(a) a*3/50 + +#define LABELWIDTH 64 +#define INTERWIDGETSPACE 16 +#define WIDGETHEIGHT 32 +#define NO_KEY -1 + +struct CvWindow; + +typedef struct CvTrackbar +{ + int signature; + + ControlRef trackbar; + ControlRef label; + + char* name; + CvTrackbar* next; + CvWindow* parent; + int* data; + int pos; + int maxval; + int labelSize;//Yannick Verdie + CvTrackbarCallback notify; + CvTrackbarCallback2 notify2; + void* userdata; +} +CvTrackbar; + + +typedef struct CvWindow +{ + int signature; + + char* name; + CvWindow* prev; + CvWindow* next; + + WindowRef window; + WindowRef oldwindow;//YV + CGImageRef imageRef; + int imageWidth;//FD + int imageHeight;//FD + + CvMat* image; + CvMat* dst_image; + int converted; + int last_key; + int flags; + int status;//YV + Ptr restoreState;//YV + + CvMouseCallback on_mouse; + void* on_mouse_param; + + struct { + int pos; + int rows; + CvTrackbar* first; + } + toolbar; + int trackbarheight; +} +CvWindow; + +static CvWindow* hg_windows = 0; + +#define Assert(exp) \ +if( !(exp) ) \ +{ \ + printf("Assertion: %s %s: %d\n", #exp, __FILE__, __LINE__);\ + assert(exp); \ +} + +static int wasInitialized = 0; +static char lastKey = NO_KEY; +OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData); +static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData); + +static const EventTypeSpec applicationKeyboardEvents[] = +{ + { kEventClassKeyboard, kEventRawKeyDown }, +}; + +CV_IMPL int cvInitSystem( int argc, char** argv ) +{ + OSErr err = noErr; + if( !wasInitialized ) + { + + hg_windows = 0; + err = InstallApplicationEventHandler(NewEventHandlerUPP( keyHandler),GetEventTypeCount(applicationKeyboardEvents),applicationKeyboardEvents,NULL,NULL); + if (err != noErr) + { + fprintf(stderr,"InstallApplicationEventHandler was not ok\n"); + } + wasInitialized = 1; + } + + return 0; +} + +// TODO: implement missing functionality +CV_IMPL int cvStartWindowThread() +{ + return 0; +} + +static int icvCountTrackbarInWindow( const CvWindow* window) +{ + CvTrackbar* trackbar = window->toolbar.first; + int count = 0; + while (trackbar != 0) { + count++; + trackbar = trackbar->next; + } + return count; +} + +static CvTrackbar* icvTrackbarByHandle( void * handle ) +{ + CvWindow* window = hg_windows; + CvTrackbar* trackbar = NULL; + while( window != 0 && window->window != handle) { + trackbar = window->toolbar.first; + while (trackbar != 0 && trackbar->trackbar != handle) + trackbar = trackbar->next; + if (trackbar != 0 && trackbar->trackbar == handle) + break; + window = window->next; + } + return trackbar; +} + +static CvWindow* icvWindowByHandle( void * handle ) +{ + CvWindow* window = hg_windows; + + while( window != 0 && window->window != handle) + window = window->next; + + return window; +} + +CV_IMPL CvWindow * icvFindWindowByName( const char* name) +{ + CvWindow* window = hg_windows; + while( window != 0 && strcmp(name, window->name) != 0 ) + window = window->next; + + return window; +} + +static CvTrackbar* icvFindTrackbarByName( const CvWindow* window, const char* name ) +{ + CvTrackbar* trackbar = window->toolbar.first; + + while (trackbar != 0 && strcmp( trackbar->name, name ) != 0) + trackbar = trackbar->next; + + return trackbar; +} + +//FD +/* draw image to frame */ +static void icvDrawImage( CvWindow* window ) +{ + Assert( window != 0 ); + if( window->imageRef == 0 ) return; + + CGContextRef myContext; + CGRect rect; + Rect portrect; + int width = window->imageWidth; + int height = window->imageHeight; + + GetWindowPortBounds(window->window, &portrect); + + if(!( window->flags & CV_WINDOW_AUTOSIZE) ) //YV + { + CGPoint origin = {0,0}; + CGSize size = {portrect.right-portrect.left, portrect.bottom-portrect.top-window->trackbarheight}; + rect.origin = origin; rect.size = size; + } + else + { + CGPoint origin = {0, portrect.bottom - height - window->trackbarheight}; + CGSize size = {width, height}; + rect.origin = origin; rect.size = size; + } + + /* To be sybnchronous we are using this, better would be to susbcribe to the draw event and process whenever requested, we might save SOME CPU cycles*/ + SetPortWindowPort (window->window); + QDBeginCGContext (GetWindowPort (window->window), &myContext); + CGContextSetInterpolationQuality (myContext, kCGInterpolationLow); + CGContextDrawImage(myContext,rect,window->imageRef); + CGContextFlush(myContext);// 4 + QDEndCGContext (GetWindowPort(window->window), &myContext);// 5 +} + +//FD +/* update imageRef */ +static void icvPutImage( CvWindow* window ) +{ + Assert( window != 0 ); + if( window->image == 0 ) return; + + CGColorSpaceRef colorspace = NULL; + CGDataProviderRef provider = NULL; + int width = window->imageWidth = window->image->cols; + int height = window->imageHeight = window->image->rows; + + colorspace = CGColorSpaceCreateDeviceRGB(); + + int size = 8; + int nbChannels = 3; + + provider = CGDataProviderCreateWithData(NULL, window->image->data.ptr, width * height , NULL ); + + if (window->imageRef != NULL){ + CGImageRelease(window->imageRef); + window->imageRef = NULL; + } + + window->imageRef = CGImageCreate( width, height, size , size*nbChannels , window->image->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault ); + icvDrawImage( window ); + + /* release the provider's memory */ + CGDataProviderRelease( provider ); +} + +static void icvUpdateWindowSize( const CvWindow* window ) +{ + int width = 0, height = 240; /* init à al taille de base de l'image*/ + Rect globalBounds; + + GetWindowBounds(window->window, kWindowContentRgn, &globalBounds); + + int minWidth = 320; + + if( window->image ) { + width = MAX(MAX(window->image->width, width), minWidth); + height = window->image->height; + } else + width = minWidth; + + height += window->trackbarheight; + + //height +=WIDGETHEIGHT; /* 32 pixels are spearating tracbars from the video display */ + + globalBounds.right = globalBounds.left + width; + globalBounds.bottom = globalBounds.top + height; + SetWindowBounds(window->window, kWindowContentRgn, &globalBounds); +} + +static void icvDeleteWindow( CvWindow* window ) +{ + CvTrackbar* trackbar; + + if( window->prev ) + window->prev->next = window->next; + else + hg_windows = window->next; + + if( window->next ) + window->next->prev = window->prev; + + window->prev = window->next = 0; + + cvReleaseMat( &window->image ); + cvReleaseMat( &window->dst_image ); + + for( trackbar = window->toolbar.first; trackbar != 0; ) + { + CvTrackbar* next = trackbar->next; + cvFree( (void**)&trackbar ); + trackbar = next; + } + + if (window->imageRef != NULL) + CGImageRelease(window->imageRef); + + DisposeWindow (window->window);//YV + + cvFree( (void**)&window ); +} + + +CV_IMPL void cvDestroyWindow( const char* name) +{ + CV_FUNCNAME( "cvDestroyWindow" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + EXIT; + + icvDeleteWindow( window ); + + __END__; +} + + +CV_IMPL void cvDestroyAllWindows( void ) +{ + while( hg_windows ) + { + CvWindow* window = hg_windows; + icvDeleteWindow( window ); + } +} + + +CV_IMPL void cvShowImage( const char* name, const CvArr* arr) +{ + CV_FUNCNAME( "cvShowImage" ); + + __BEGIN__; + + CvWindow* window; + int origin = 0; + int resize = 0; + CvMat stub, *image; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + { + cvNamedWindow(name, 1); + window = icvFindWindowByName(name); + } + + if( !window || !arr ) + EXIT; // keep silence here. + + if( CV_IS_IMAGE_HDR( arr )) + origin = ((IplImage*)arr)->origin; + + CV_CALL( image = cvGetMat( arr, &stub )); + + /* + if( !window->image ) + cvResizeWindow( name, image->cols, image->rows ); + */ + + if( window->image && + !CV_ARE_SIZES_EQ(window->image, image) ) { + if ( ! (window->flags & CV_WINDOW_AUTOSIZE) )//FD + resize = 1; + cvReleaseMat( &window->image ); + } + + if( !window->image ) { + resize = 1;//FD + window->image = cvCreateMat( image->rows, image->cols, CV_8UC3 ); + } + + cvConvertImage( image, window->image, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB ); + icvPutImage( window ); + if ( resize )//FD + icvUpdateWindowSize( window ); + + __END__; +} + +CV_IMPL void cvResizeWindow( const char* name, int width, int height) +{ + CV_FUNCNAME( "cvResizeWindow" ); + + __BEGIN__; + + CvWindow* window; + //CvTrackbar* trackbar; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + SizeWindow(window->window, width, height, true); + + __END__; +} + +CV_IMPL void cvMoveWindow( const char* name, int x, int y) +{ + CV_FUNCNAME( "cvMoveWindow" ); + + __BEGIN__; + + CvWindow* window; + //CvTrackbar* trackbar; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + MoveWindow(window->window, x, y, true); + + __END__; +} + +void TrackbarActionProcPtr (ControlRef theControl, ControlPartCode partCode) +{ + CvTrackbar * trackbar = icvTrackbarByHandle (theControl); + + if (trackbar == NULL) + { + fprintf(stderr,"Error getting trackbar\n"); + return; + } + else + { + int pos = GetControl32BitValue (theControl); + if ( trackbar->data ) + *trackbar->data = pos; + if ( trackbar->notify ) + trackbar->notify(pos); + else if ( trackbar->notify2 ) + trackbar->notify2(pos, trackbar->userdata); + + //--------YV--------------------------- + CFStringEncoding encoding = kCFStringEncodingASCII; + CFAllocatorRef alloc_default = kCFAllocatorDefault; // = NULL; + + char valueinchar[20]; + sprintf(valueinchar, " (%d)", *trackbar->data); + + // create an empty CFMutableString + CFIndex maxLength = 256; + CFMutableStringRef cfstring = CFStringCreateMutable(alloc_default,maxLength); + + // append some c strings into it. + CFStringAppendCString(cfstring,trackbar->name,encoding); + CFStringAppendCString(cfstring,valueinchar,encoding); + + SetControlData(trackbar->label, kControlEntireControl,kControlStaticTextCFStringTag, sizeof(cfstring), &cfstring); + DrawControls(trackbar->parent->window); + //----------------------------------------- + } +} + + +static int icvCreateTrackbar (const char* trackbar_name, + const char* window_name, + int* val, int count, + CvTrackbarCallback on_notify, + CvTrackbarCallback2 on_notify2, + void* userdata) +{ + int result = 0; + + CV_FUNCNAME( "icvCreateTrackbar" ); + __BEGIN__; + + /*char slider_name[32];*/ + CvWindow* window = 0; + CvTrackbar* trackbar = 0; + Rect stboundsRect; + ControlRef outControl; + ControlRef stoutControl; + Rect bounds; + + if( !window_name || !trackbar_name ) + CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" ); + + if( count <= 0 ) + CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + + window = icvFindWindowByName(window_name); + if( !window ) + EXIT; + + trackbar = icvFindTrackbarByName(window,trackbar_name); + if( !trackbar ) + { + int len = strlen(trackbar_name); + trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1); + memset( trackbar, 0, sizeof(*trackbar)); + trackbar->signature = CV_TRACKBAR_MAGIC_VAL; + trackbar->name = (char*)(trackbar+1); + memcpy( trackbar->name, trackbar_name, len + 1 ); + trackbar->parent = window; + trackbar->next = window->toolbar.first; + window->toolbar.first = trackbar; + + if( val ) + { + int value = *val; + if( value < 0 ) + value = 0; + if( value > count ) + value = count; + trackbar->pos = value; + trackbar->data = val; + } + + trackbar->maxval = count; + + //----------- YV ---------------------- + //get nb of digits + int nbDigit = 0; + while((count/=10)>10){ + nbDigit++; + } + + //pad size maxvalue in pixel + Point qdSize; + char valueinchar[strlen(trackbar_name)+1 +1 +1+nbDigit+1];//lenght+\n +space +(+nbDigit+) + sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->maxval); + SInt16 baseline; + CFStringRef text = CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII); + GetThemeTextDimensions( text, kThemeCurrentPortFont, kThemeStateActive, false, &qdSize, &baseline ); + trackbar->labelSize = qdSize.h; + //-------------------------------------- + + int c = icvCountTrackbarInWindow(window); + + GetWindowBounds(window->window,kWindowContentRgn,&bounds); + + stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE; + stboundsRect.left = INTERWIDGETSPACE; + stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT; + stboundsRect.right = stboundsRect.left+LABELWIDTH; + + //fprintf(stdout,"create trackabar bounds (%d %d %d %d)\n",stboundsRect.top,stboundsRect.left,stboundsRect.bottom,stboundsRect.right); + //----------- YV ---------------------- + sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->pos); + CreateStaticTextControl (window->window,&stboundsRect,CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII),NULL,&stoutControl); + //-------------------------------------- + + stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE; + stboundsRect.left = INTERWIDGETSPACE*2+LABELWIDTH; + stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT; + stboundsRect.right = bounds.right-INTERWIDGETSPACE; + + CreateSliderControl (window->window,&stboundsRect, trackbar->pos,0,trackbar->maxval,kControlSliderLiveFeedback,0,true,NewControlActionUPP(TrackbarActionProcPtr),&outControl); + + bounds.bottom += INTERWIDGETSPACE + WIDGETHEIGHT; + SetControlVisibility (outControl,true,true); + SetControlVisibility (stoutControl,true,true); + + trackbar->trackbar = outControl; + trackbar->label = stoutControl; + if (c == 1) + window->trackbarheight = INTERWIDGETSPACE*2 + WIDGETHEIGHT; + else + window->trackbarheight += INTERWIDGETSPACE + WIDGETHEIGHT; + icvUpdateWindowSize( window ); + } + + trackbar->notify = on_notify; + trackbar->notify2 = on_notify2; + trackbar->userdata = userdata; + + result = 1; + + __END__; + return result; +} + + +CV_IMPL int cvCreateTrackbar (const char* trackbar_name, + const char* window_name, + int* val, int count, + CvTrackbarCallback on_notify) +{ + return icvCreateTrackbar(trackbar_name, window_name, val, count, on_notify, 0, 0); +} + + +CV_IMPL int cvCreateTrackbar2(const char* trackbar_name, + const char* window_name, + int* val, int count, + CvTrackbarCallback2 on_notify2, + void* userdata) +{ + return icvCreateTrackbar(trackbar_name, window_name, val, + count, 0, on_notify2, userdata); +} + + +CV_IMPL void +cvSetMouseCallback( const char* name, CvMouseCallback function, void* info) +{ + CvWindow* window = icvFindWindowByName( name ); + if (window != NULL) + { + window->on_mouse = function; + window->on_mouse_param = info; + } + else + { + fprintf(stdout,"Error with cvSetMouseCallback. Window not found : %s\n",name); + } +} + + CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) +{ + int pos = -1; + + CV_FUNCNAME( "cvGetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + pos = trackbar->pos; + + __END__; + + return pos; +} + +CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) +{ + CV_FUNCNAME( "cvSetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + { + if( pos < 0 ) + pos = 0; + + if( pos > trackbar->maxval ) + pos = trackbar->maxval; + + // Set new value and redraw the trackbar + SetControlValue( trackbar->trackbar, pos ); + Draw1Control( trackbar->trackbar ); + } + + __END__; + return ; +} + +CV_IMPL void* cvGetWindowHandle( const char* name ) +{ + WindowRef result = 0; + + __BEGIN__; + + CvWindow* window; + window = icvFindWindowByName( name ); + if (window != NULL) + result = window->window; + else + result = NULL; + + __END__; + + return result; +} + + +CV_IMPL const char* cvGetWindowName( void* window_handle ) +{ + const char* window_name = ""; + + CV_FUNCNAME( "cvGetWindowName" ); + + __BEGIN__; + + CvWindow* window; + + if( window_handle == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + window = icvWindowByHandle(window_handle ); + if( window ) + window_name = window->name; + + __END__; + + return window_name; +} + +double cvGetModeWindow_CARBON(const char* name)//YV +{ + double result = -1; + + CV_FUNCNAME( "cvGetModeWindow_QT" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + result = window->status; + + __END__; + return result; +} + +void cvSetModeWindow_CARBON( const char* name, double prop_value)//Yannick Verdie +{ + OSStatus err = noErr; + + + CV_FUNCNAME( "cvSetModeWindow_QT" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set + EXIT; + + if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) + { + err = EndFullScreen(window->restoreState,0); + if (err != noErr) + fprintf(stdout,"Error EndFullScreen\n"); + window->window = window->oldwindow; + ShowWindow( window->window ); + + window->status=CV_WINDOW_NORMAL; + EXIT; + } + + if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) + { + GDHandle device; + err = GetWindowGreatestAreaDevice(window->window, kWindowTitleBarRgn, &device, NULL); + if (err != noErr) + fprintf(stdout,"Error GetWindowGreatestAreaDevice\n"); + + HideWindow(window->window); + window->oldwindow = window->window; + err = BeginFullScreen(&(window->restoreState), device, 0, 0, &window->window, 0, fullScreenAllowEvents | fullScreenDontSwitchMonitorResolution); + if (err != noErr) + fprintf(stdout,"Error BeginFullScreen\n"); + + window->status=CV_WINDOW_FULLSCREEN; + EXIT; + } + + __END__; +} + +CV_IMPL int cvNamedWindow( const char* name, int flags ) +{ + int result = 0; + CV_FUNCNAME( "cvNamedWindow" ); + if (!wasInitialized) + cvInitSystem(0, NULL); + + // to be able to display a window, we need to be a 'faceful' application + // http://lists.apple.com/archives/carbon-dev/2005/Jun/msg01414.html + static bool switched_to_faceful = false; + if (! switched_to_faceful) + { + ProcessSerialNumber psn = { 0, kCurrentProcess }; + OSStatus ret = TransformProcessType (&psn, kProcessTransformToForegroundApplication ); + + if (ret == noErr) + { + SetFrontProcess( &psn ); + switched_to_faceful = true; + } + else + { + fprintf(stderr, "Failed to tranform process type: %d\n", (int) ret); + fflush (stderr); + } + } + + __BEGIN__; + + WindowRef outWindow = NULL; + OSStatus err = noErr; + Rect contentBounds = {100,100,320,440}; + + CvWindow* window; + UInt wAttributes = 0; + + int len; + + const EventTypeSpec genericWindowEventHandler[] = { + { kEventClassMouse, kEventMouseMoved}, + { kEventClassMouse, kEventMouseDragged}, + { kEventClassMouse, kEventMouseUp}, + { kEventClassMouse, kEventMouseDown}, + { kEventClassWindow, kEventWindowClose }, + { kEventClassWindow, kEventWindowBoundsChanged }//FD + }; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + if( icvFindWindowByName( name ) != 0 ){ + result = 1; + EXIT; + } + len = strlen(name); + CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); + memset( window, 0, sizeof(*window)); + window->name = (char*)(window + 1); + memcpy( window->name, name, len + 1 ); + window->flags = flags; + window->status = CV_WINDOW_NORMAL;//YV + window->signature = CV_WINDOW_MAGIC_VAL; + window->image = 0; + window->last_key = 0; + window->on_mouse = 0; + window->on_mouse_param = 0; + + window->next = hg_windows; + window->prev = 0; + if( hg_windows ) + hg_windows->prev = window; + hg_windows = window; + wAttributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute; + + + if (window->flags & CV_WINDOW_AUTOSIZE)//Yannick verdie, remove the handler at the bottom-right position of the window in AUTORESIZE mode + { + wAttributes = 0; + wAttributes = kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute; + } + + err = CreateNewWindow ( kDocumentWindowClass,wAttributes,&contentBounds,&outWindow); + if (err != noErr) + fprintf(stderr,"Error while creating the window\n"); + + SetWindowTitleWithCFString(outWindow,CFStringCreateWithCString(NULL,name,kCFStringEncodingASCII)); + if (err != noErr) + fprintf(stdout,"Error SetWindowTitleWithCFString\n"); + + window->window = outWindow; + window->oldwindow = 0;//YV + + err = InstallWindowEventHandler(outWindow, NewEventHandlerUPP(windowEventHandler), GetEventTypeCount(genericWindowEventHandler), genericWindowEventHandler, outWindow, NULL); + + ShowWindow( outWindow ); + result = 1; + + __END__; + return result; +} + +static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData) +{ + CvWindow* window = NULL; + UInt32 eventKind, eventClass; + OSErr err = noErr; + int event = 0; + UInt32 count = 0; + HIPoint point = {0,0}; + EventMouseButton eventMouseButton = 0;//FD + UInt32 modifiers;//FD + + WindowRef theWindow = (WindowRef)inUserData; + if (theWindow == NULL) + return eventNotHandledErr; + window = icvWindowByHandle(theWindow); + if ( window == NULL) + return eventNotHandledErr; + + eventKind = GetEventKind(theEvent); + eventClass = GetEventClass(theEvent); + + switch (eventClass) { + case kEventClassMouse : { + switch (eventKind){ + case kEventMouseUp : + case kEventMouseDown : + case kEventMouseMoved : + case kEventMouseDragged : { + err = CallNextEventHandler(nextHandler, theEvent); + if (err != eventNotHandledErr) + return err; + err = GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(eventMouseButton), NULL, &eventMouseButton); + err = GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers); + err = GetEventParameter(theEvent,kEventParamClickCount,typeUInt32,NULL,sizeof(UInt32),NULL,&count); + if (err == noErr){ + if (count >1) event += 6; + } else { + event = CV_EVENT_MOUSEMOVE; + } + + if (eventKind == kEventMouseUp) + event +=4; + if (eventKind == kEventMouseDown) + event +=1; + + unsigned int flags = 0; + + err = GetEventParameter(theEvent, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point); + if (eventKind != kEventMouseMoved){ + switch(eventMouseButton){ + case kEventMouseButtonPrimary: + if (modifiers & controlKey){ + flags += CV_EVENT_FLAG_RBUTTON; + event += 1; + } else { + flags += CV_EVENT_FLAG_LBUTTON; + } + break; + case kEventMouseButtonSecondary: + flags += CV_EVENT_FLAG_RBUTTON; + event += 1; + break; + case kEventMouseButtonTertiary: + flags += CV_EVENT_FLAG_MBUTTON; + event += 2; + break; + } + } + + if (modifiers&controlKey) flags += CV_EVENT_FLAG_CTRLKEY; + if (modifiers&shiftKey) flags += CV_EVENT_FLAG_SHIFTKEY; + if (modifiers& cmdKey ) flags += CV_EVENT_FLAG_ALTKEY; + + if (window->on_mouse != NULL){ + int lx,ly; + Rect structure, content; + GetWindowBounds(theWindow, kWindowStructureRgn, &structure); + GetWindowBounds(theWindow, kWindowContentRgn, &content); + lx = (int)point.x - content.left + structure.left; + ly = (int)point.y - window->trackbarheight - content.top + structure.top; /* minus la taille des trackbars */ + if (window->flags & CV_WINDOW_AUTOSIZE) {//FD + //printf("was %d,%d\n", lx, ly); + /* scale the mouse coordinates */ + lx = lx * window->imageWidth / (content.right - content.left); + ly = ly * window->imageHeight / (content.bottom - content.top - window->trackbarheight); + } + + if (lx>0 && ly >0){ /* a remettre dans les coordonnées locale */ + window->on_mouse (event, lx, ly, flags, window->on_mouse_param); + return noErr; + } + } + } + default : return eventNotHandledErr; + } + } + case kEventClassWindow : {//FD + switch (eventKind){ + case kEventWindowBoundsChanged : + { + /* resize the trackbars */ + CvTrackbar *t; + Rect bounds; + GetWindowBounds(window->window,kWindowContentRgn,&bounds); + for ( t = window->toolbar.first; t != 0; t = t->next ) + SizeControl(t->trackbar,bounds.right - bounds.left - INTERWIDGETSPACE*3 - LABELWIDTH , WIDGETHEIGHT); + } + /* redraw the image */ + icvDrawImage(window); + break; + default : + return eventNotHandledErr; + } + } + default: + return eventNotHandledErr; + } + + return eventNotHandledErr; +} + +OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData) +{ + UInt32 eventKind; + UInt32 eventClass; + OSErr err = noErr; + + eventKind = GetEventKind (theEvent); + eventClass = GetEventClass (theEvent); + err = GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(lastKey), NULL, &lastKey); + if (err != noErr) + lastKey = NO_KEY; + + return noErr; +} + +CV_IMPL int cvWaitKey (int maxWait) +{ + EventRecord theEvent; + + // wait at least for one event (to allow mouse, etc. processing), exit if maxWait milliseconds passed (nullEvent) + UInt32 start = TickCount(); + int iters=0; + do + { + // remaining time until maxWait is over + UInt32 wait = EventTimeToTicks (maxWait / 1000.0) - (TickCount() - start); + if ((int)wait <= 0) + { + if( maxWait > 0 && iters > 0 ) + break; + wait = 1; + } + iters++; + WaitNextEvent (everyEvent, &theEvent, maxWait > 0 ? wait : kDurationForever, NULL); + } + while (lastKey == NO_KEY && theEvent.what != nullEvent); + + int key = lastKey; + lastKey = NO_KEY; + return key; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_cocoa.mm diffimg-2.0.0/3rdparty/opencv/highgui/src/window_cocoa.mm --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_cocoa.mm 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_cocoa.mm 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,942 @@ +/* The file is the modified version of window_cocoa.mm from opencv-cocoa project by Andre Cohen */ + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +#import + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +/*** begin IPhone OS Stubs ***/ +// When highgui functions are referred to on iPhone OS, they will fail silently. +CV_IMPL int cvInitSystem( int argc, char** argv) { return 0;} +CV_IMPL int cvStartWindowThread(){ return 0; } +CV_IMPL void cvDestroyWindow( const char* name) {} +CV_IMPL void cvDestroyAllWindows( void ) {} +CV_IMPL void cvShowImage( const char* name, const CvArr* arr) {} +CV_IMPL void cvResizeWindow( const char* name, int width, int height) {} +CV_IMPL void cvMoveWindow( const char* name, int x, int y){} +CV_IMPL int cvCreateTrackbar (const char* trackbar_name,const char* window_name, + int* val, int count, CvTrackbarCallback on_notify) {return 0;} +CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,const char* window_name, + int* val, int count, CvTrackbarCallback2 on_notify2, void* userdata) {return 0;} +CV_IMPL void cvSetMouseCallback( const char* name, CvMouseCallback function, void* info) {} +CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) {return 0;} +CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) {} +CV_IMPL void* cvGetWindowHandle( const char* name ) {return NULL;} +CV_IMPL const char* cvGetWindowName( void* window_handle ) {return NULL;} +CV_IMPL int cvNamedWindow( const char* name, int flags ) {return 0; } +CV_IMPL int cvWaitKey (int maxWait) {return 0;} +//*** end IphoneOS Stubs ***/ +#else + +#import + +#include +using namespace std; + +const int TOP_BORDER = 7; +const int MIN_SLIDER_WIDTH=200; + +static NSApplication *application = nil; +static NSAutoreleasePool *pool = nil; +static NSMutableDictionary *windows = nil; +static bool wasInitialized = false; + +@interface CVView : NSView { + NSImage *image; +} +@property(retain) NSImage *image; +- (void)setImageData:(CvArr *)arr; +@end + +@interface CVSlider : NSView { + NSSlider *slider; + NSTextField *name; + int *value; + void *userData; + CvTrackbarCallback callback; + CvTrackbarCallback2 callback2; +} +@property(retain) NSSlider *slider; +@property(retain) NSTextField *name; +@property(assign) int *value; +@property(assign) void *userData; +@property(assign) CvTrackbarCallback callback; +@property(assign) CvTrackbarCallback2 callback2; +@end + +@interface CVWindow : NSWindow { + NSMutableDictionary *sliders; + CvMouseCallback mouseCallback; + void *mouseParam; + BOOL autosize; + BOOL firstContent; + int status; +} +@property(assign) CvMouseCallback mouseCallback; +@property(assign) void *mouseParam; +@property(assign) BOOL autosize; +@property(assign) BOOL firstContent; +@property(retain) NSMutableDictionary *sliders; +@property(readwrite) int status; +- (CVView *)contentView; +- (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags; +- (void)cvMouseEvent:(NSEvent *)event; +- (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback; +@end + +/*static void icvCocoaCleanup(void) +{ + //cout << "icvCocoaCleanup" << endl; + if( application ) + { + cvDestroyAllWindows(); + //[application terminate:nil]; + application = 0; + [pool release]; + } +}*/ + +CV_IMPL int cvInitSystem( int , char** ) +{ + //cout << "cvInitSystem" << endl; + wasInitialized = true; + + pool = [[NSAutoreleasePool alloc] init]; + application = [NSApplication sharedApplication]; + windows = [[NSMutableDictionary alloc] init]; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#ifndef NSAppKitVersionNumber10_5 +#define NSAppKitVersionNumber10_5 949 +#endif + if( floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5 ) + [application setActivationPolicy:0/*NSApplicationActivationPolicyRegular*/]; +#endif + //[application finishLaunching]; + //atexit(icvCocoaCleanup); + + return 0; +} + +static CVWindow *cvGetWindow(const char *name) { + //cout << "cvGetWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + NSString *cvname = [NSString stringWithFormat:@"%s", name]; + CVWindow* retval = (CVWindow*) [windows valueForKey:cvname] ; + //cout << "retain count: " << [retval retainCount] << endl; + //retval = [retval retain]; + //cout << "retain count: " << [retval retainCount] << endl; + [localpool drain]; + //cout << "retain count: " << [retval retainCount] << endl; + return retval; +} + +CV_IMPL int cvStartWindowThread() +{ + //cout << "cvStartWindowThread" << endl; + return 0; +} + +CV_IMPL void cvDestroyWindow( const char* name) +{ + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + //cout << "cvDestroyWindow" << endl; + CVWindow *window = cvGetWindow(name); + if(window) { + [window close]; + [windows removeObjectForKey:[NSString stringWithFormat:@"%s", name]]; + } + [localpool drain]; +} + + +CV_IMPL void cvDestroyAllWindows( void ) +{ + //cout << "cvDestroyAllWindows" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + NSDictionary* list = [NSDictionary dictionaryWithDictionary:windows]; + for(NSString *key in list) { + cvDestroyWindow([key cStringUsingEncoding:NSASCIIStringEncoding]); + } + [localpool drain]; +} + + +CV_IMPL void cvShowImage( const char* name, const CvArr* arr) +{ + //cout << "cvShowImage" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CVWindow *window = cvGetWindow(name); + if(!window) + { + cvNamedWindow(name, CV_WINDOW_AUTOSIZE); + window = cvGetWindow(name); + } + + if(window) + { + bool empty = [[window contentView] image] == nil; + NSRect rect = [window frame]; + NSRect vrectOld = [[window contentView] frame]; + + [[window contentView] setImageData:(CvArr *)arr]; + if([window autosize] || [window firstContent] || empty) + { + //Set new view size considering sliders (reserve height and min width) + NSRect vrectNew = vrectOld; + int slider_height = 0; + for(NSString *key in [window sliders]) { + slider_height += [[[window sliders] valueForKey:key] frame].size.height; + } + vrectNew.size.height = [[[window contentView] image] size].height + slider_height; + vrectNew.size.width = std::max([[[window contentView] image] size].width, MIN_SLIDER_WIDTH); + [[window contentView] setFrameSize:vrectNew.size]; //adjust sliders to fit new window size + + rect.size.width += vrectNew.size.width - vrectOld.size.width; + rect.size.height += vrectNew.size.height - vrectOld.size.height; + rect.origin.y -= vrectNew.size.height - vrectOld.size.height; + + [window setFrame:rect display:YES]; + } + else + [window display]; + [window setFirstContent:NO]; + } + [localpool drain]; +} + +CV_IMPL void cvResizeWindow( const char* name, int width, int height) +{ + + //cout << "cvResizeWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CVWindow *window = cvGetWindow(name); + if(window) { + NSRect frame = [window frame]; + frame.size.width = width; + frame.size.height = height; + [window setFrame:frame display:YES]; + } + [localpool drain]; +} + +CV_IMPL void cvMoveWindow( const char* name, int x, int y) +{ + + CV_FUNCNAME("cvMoveWindow"); + __BEGIN__; + + NSAutoreleasePool* localpool1 = [[NSAutoreleasePool alloc] init]; + CVWindow *window = nil; + + if(name == NULL) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + //cout << "cvMoveWindow"<< endl; + window = cvGetWindow(name); + if(window) { + y = [[window screen] frame].size.height - y; + [window setFrameTopLeftPoint:NSMakePoint(x, y)]; + } + [localpool1 drain]; + + __END__; +} + +CV_IMPL int cvCreateTrackbar (const char* trackbar_name, + const char* window_name, + int* val, int count, + CvTrackbarCallback on_notify) +{ + CV_FUNCNAME("cvCreateTrackbar"); + + + int result = 0; + CVWindow *window = nil; + NSAutoreleasePool* localpool2 = nil; + + __BEGIN__; + if (localpool2 != nil) [localpool2 drain]; + localpool2 = [[NSAutoreleasePool alloc] init]; + + if(window_name == NULL) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + //cout << "cvCreateTrackbar" << endl ; + window = cvGetWindow(window_name); + if(window) { + [window createSliderWithName:trackbar_name + maxValue:count + value:val + callback:on_notify]; + result = 1; + } + [localpool2 drain]; + __END__; + return result; +} + + +CV_IMPL int cvCreateTrackbar2(const char* trackbar_name, + const char* window_name, + int* val, int count, + CvTrackbarCallback2 on_notify2, + void* userdata) +{ + //cout <<"cvCreateTrackbar2" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + int res = cvCreateTrackbar(trackbar_name, window_name, val, count, NULL); + if(res) { + CVSlider *slider = [[cvGetWindow(window_name) sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; + [slider setCallback2:on_notify2]; + [slider setUserData:userdata]; + } + [localpool drain]; + return res; +} + + +CV_IMPL void +cvSetMouseCallback( const char* name, CvMouseCallback function, void* info) +{ + CV_FUNCNAME("cvSetMouseCallback"); + + CVWindow *window = nil; + NSAutoreleasePool* localpool3 = nil; + __BEGIN__; + //cout << "cvSetMouseCallback" << endl; + + if (localpool3 != nil) [localpool3 drain]; + localpool3 = [[NSAutoreleasePool alloc] init]; + + if(name == NULL) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + window = cvGetWindow(name); + if(window) { + [window setMouseCallback:function]; + [window setMouseParam:info]; + } + [localpool3 drain]; + + __END__; +} + + CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) +{ + CV_FUNCNAME("cvGetTrackbarPos"); + + CVWindow *window = nil; + int pos = -1; + NSAutoreleasePool* localpool4 = nil; + __BEGIN__; + + //cout << "cvGetTrackbarPos" << endl; + if(trackbar_name == NULL || window_name == NULL) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + if (localpool4 != nil) [localpool4 drain]; + localpool4 = [[NSAutoreleasePool alloc] init]; + + window = cvGetWindow(window_name); + if(window) { + CVSlider *slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; + if(slider) { + pos = [[slider slider] intValue]; + } + } + [localpool4 drain]; + __END__; + return pos; +} + +CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) +{ + CV_FUNCNAME("cvSetTrackbarPos"); + + CVWindow *window = nil; + CVSlider *slider = nil; + NSAutoreleasePool* localpool5 = nil; + + __BEGIN__; + //cout << "cvSetTrackbarPos" << endl; + if(trackbar_name == NULL || window_name == NULL) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + if(pos < 0) + CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + + if (localpool5 != nil) [localpool5 drain]; + localpool5 = [[NSAutoreleasePool alloc] init]; + + window = cvGetWindow(window_name); + if(window) { + slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; + if(slider) { + [[slider slider] setIntValue:pos]; + } + } + [localpool5 drain]; + + __END__; +} + +CV_IMPL void* cvGetWindowHandle( const char* name ) +{ + //cout << "cvGetWindowHandle" << endl; + return cvGetWindow(name); +} + + +CV_IMPL const char* cvGetWindowName( void* window_handle ) +{ + //cout << "cvGetWindowName" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + for(NSString *key in windows) { + if([windows valueForKey:key] == window_handle) { + [localpool drain]; + return [key UTF8String]; + } + } + [localpool drain]; + return 0; +} + +CV_IMPL int cvNamedWindow( const char* name, int flags ) +{ + if( !wasInitialized ) + cvInitSystem(0, 0); + + //cout << "cvNamedWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CVWindow *window = cvGetWindow(name); + if( window ) + { + [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)]; + [localpool drain]; + return 0; + } + + NSScreen* mainDisplay = [NSScreen mainScreen]; + + NSString *windowName = [NSString stringWithFormat:@"%s", name]; + NSUInteger showResize = (flags == CV_WINDOW_AUTOSIZE) ? 0: NSResizableWindowMask ; + NSUInteger styleMask = NSTitledWindowMask|NSMiniaturizableWindowMask|showResize; + CGFloat windowWidth = [NSWindow minFrameWidthWithTitle:windowName styleMask:styleMask]; + NSRect initContentRect = NSMakeRect(0, 0, windowWidth, 0); + if (mainDisplay) { + NSRect dispFrame = [mainDisplay visibleFrame]; + initContentRect.origin.y = dispFrame.size.height-20; + } + + + window = [[CVWindow alloc] initWithContentRect:initContentRect + styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|showResize + backing:NSBackingStoreBuffered + defer:YES + screen:mainDisplay]; + + [window setFrameTopLeftPoint:initContentRect.origin]; + + [window setFirstContent:YES]; + + [window setContentView:[[CVView alloc] init]]; + + [window setHasShadow:YES]; + [window setAcceptsMouseMovedEvents:YES]; + [window useOptimizedDrawing:YES]; + [window setTitle:windowName]; + [window makeKeyAndOrderFront:nil]; + + [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)]; + + [windows setValue:window forKey:windowName]; + + [localpool drain]; + return [windows count]-1; +} + +CV_IMPL int cvWaitKey (int maxWait) +{ + //cout << "cvWaitKey" << endl; + int returnCode = -1; + NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init]; + double start = [[NSDate date] timeIntervalSince1970]; + + while(true) { + if(([[NSDate date] timeIntervalSince1970] - start) * 1000 >= maxWait && maxWait>0) + break; + + //event = [application currentEvent]; + [localpool drain]; + localpool = [[NSAutoreleasePool alloc] init]; + + NSEvent *event = + [application + nextEventMatchingMask:NSAnyEventMask + untilDate://[NSDate dateWithTimeIntervalSinceNow: 1./100] + [NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + if([event type] == NSKeyDown) { + returnCode = [[event characters] characterAtIndex:0]; + break; + } + + [application sendEvent:event]; + [application updateWindows]; + + [NSThread sleepForTimeInterval:1/100.]; + } + [localpool drain]; + + return returnCode; +} + +double cvGetModeWindow_COCOA( const char* name ) +{ + double result = -1; + CVWindow *window = nil; + + CV_FUNCNAME( "cvGetModeWindow_COCOA" ); + + __BEGIN__; + if( name == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + } + + window = cvGetWindow( name ); + if ( window == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL window" ); + } + + result = window.status; + + __END__; + return result; +} + +void cvSetModeWindow_COCOA( const char* name, double prop_value ) +{ + CVWindow *window = nil; + NSDictionary *fullscreenOptions = nil; + NSAutoreleasePool* localpool = nil; + + CV_FUNCNAME( "cvSetModeWindow_COCOA" ); + + __BEGIN__; + if( name == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + } + + window = cvGetWindow(name); + if ( window == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL window" ); + } + + if ( [window autosize] ) + { + return; + } + + localpool = [[NSAutoreleasePool alloc] init]; + + fullscreenOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSFullScreenModeSetting]; + if ( [[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_NORMAL ) + { + [[window contentView] exitFullScreenModeWithOptions:fullscreenOptions]; + window.status=CV_WINDOW_NORMAL; + } + else if( ![[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_FULLSCREEN ) + { + [[window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:fullscreenOptions]; + window.status=CV_WINDOW_FULLSCREEN; + } + + [localpool drain]; + + __END__; +} + +@implementation CVWindow + +@synthesize mouseCallback; +@synthesize mouseParam; +@synthesize autosize; +@synthesize firstContent; +@synthesize sliders; +@synthesize status; + +- (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags { + (void)event; + //cout << "cvSendMouseEvent" << endl; + NSPoint mp = [NSEvent mouseLocation]; + //NSRect visible = [[self contentView] frame]; + mp = [self convertScreenToBase: mp]; + double viewHeight = [self contentView].frame.size.height; + double viewWidth = [self contentView].frame.size.width; + CVWindow *window = (CVWindow *)[[self contentView] window]; + for(NSString *key in [window sliders]) { + NSSlider *slider = [[window sliders] valueForKey:key]; + viewHeight = std::min(viewHeight, (double)([slider frame].origin.y)); + } + viewHeight -= TOP_BORDER; + mp.y = viewHeight - mp.y; + + NSImage* image = ((CVView*)[self contentView]).image; + NSSize imageSize = [image size]; + mp.x = mp.x * imageSize.width / std::max(viewWidth, 1.); + mp.y = mp.y * imageSize.height / std::max(viewHeight, 1.); + + if( mp.x >= 0 && mp.y >= 0 && mp.x < imageSize.width && mp.y < imageSize.height ) + mouseCallback(type, mp.x, mp.y, flags, mouseParam); +} + +- (void)cvMouseEvent:(NSEvent *)event { + //cout << "cvMouseEvent" << endl; + if(!mouseCallback) + return; + + int flags = 0; + if([event modifierFlags] & NSShiftKeyMask) flags |= CV_EVENT_FLAG_SHIFTKEY; + if([event modifierFlags] & NSControlKeyMask) flags |= CV_EVENT_FLAG_CTRLKEY; + if([event modifierFlags] & NSAlternateKeyMask) flags |= CV_EVENT_FLAG_ALTKEY; + + if([event type] == NSLeftMouseDown) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONDOWN flags:flags | CV_EVENT_FLAG_LBUTTON];} + if([event type] == NSLeftMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONUP flags:flags | CV_EVENT_FLAG_LBUTTON];} + if([event type] == NSRightMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONDOWN flags:flags | CV_EVENT_FLAG_RBUTTON];} + if([event type] == NSRightMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONUP flags:flags | CV_EVENT_FLAG_RBUTTON];} + if([event type] == NSOtherMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONDOWN flags:flags];} + if([event type] == NSOtherMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONUP flags:flags];} + if([event type] == NSMouseMoved) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags];} + if([event type] == NSLeftMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_LBUTTON];} + if([event type] == NSRightMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_RBUTTON];} + if([event type] == NSOtherMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_MBUTTON];} +} +- (void)keyDown:(NSEvent *)theEvent { + //cout << "keyDown" << endl; + [super keyDown:theEvent]; +} +- (void)rightMouseDragged:(NSEvent *)theEvent { + //cout << "rightMouseDragged" << endl ; + [self cvMouseEvent:theEvent]; +} +- (void)rightMouseUp:(NSEvent *)theEvent { + //cout << "rightMouseUp" << endl; + [self cvMouseEvent:theEvent]; +} +- (void)rightMouseDown:(NSEvent *)theEvent { + // Does not seem to work? + //cout << "rightMouseDown" << endl; + [self cvMouseEvent:theEvent]; +} +- (void)mouseMoved:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)otherMouseDragged:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)otherMouseUp:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)otherMouseDown:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)mouseDragged:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)mouseUp:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} +- (void)mouseDown:(NSEvent *)theEvent { + [self cvMouseEvent:theEvent]; +} + +- (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback { + //cout << "createSliderWithName" << endl; + if(sliders == nil) + sliders = [[NSMutableDictionary alloc] init]; + + NSString *cvname = [NSString stringWithFormat:@"%s", name]; + + // Avoid overwriting slider + if([sliders valueForKey:cvname]!=nil) + return; + + // Create slider + CVSlider *slider = [[CVSlider alloc] init]; + [[slider name] setStringValue:cvname]; + [[slider slider] setMaxValue:max]; + [[slider slider] setMinValue:0]; + [[slider slider] setNumberOfTickMarks:(max+1)]; + [[slider slider] setAllowsTickMarkValuesOnly:YES]; + if(value) + { + [[slider slider] setIntValue:*value]; + [slider setValue:value]; + } + if(callback) + [slider setCallback:callback]; + + // Save slider + [sliders setValue:slider forKey:cvname]; + [[self contentView] addSubview:slider]; + + + //update contentView size to contain sliders + NSSize viewSize=[[self contentView] frame].size, + sliderSize=[slider frame].size; + viewSize.height += sliderSize.height; + viewSize.width = std::max(viewSize.width, MIN_SLIDER_WIDTH); + + // Update slider sizes + [[self contentView] setFrameSize:viewSize]; + [[self contentView] setNeedsDisplay:YES]; + + //update window size to contain sliders + NSRect rect = [self frame]; + rect.size.height += [slider frame].size.height; + rect.size.width = std::max(rect.size.width, MIN_SLIDER_WIDTH); + [self setFrame:rect display:YES]; + + + +} + +- (CVView *)contentView { + return (CVView*)[super contentView]; +} + +@end + +@implementation CVView + +@synthesize image; + +- (id)init { + //cout << "CVView init" << endl; + [super init]; + image = [[NSImage alloc] init]; + return self; +} + +- (void)setImageData:(CvArr *)arr { + //cout << "setImageData" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CvMat *arrMat, *cvimage, stub; + + arrMat = cvGetMat(arr, &stub); + + cvimage = cvCreateMat(arrMat->rows, arrMat->cols, CV_8UC3); + cvConvertImage(arrMat, cvimage, CV_CVTIMG_SWAP_RB); + + /*CGColorSpaceRef colorspace = NULL; + CGDataProviderRef provider = NULL; + int width = cvimage->width; + int height = cvimage->height; + + colorspace = CGColorSpaceCreateDeviceRGB(); + + int size = 8; + int nbChannels = 3; + + provider = CGDataProviderCreateWithData(NULL, cvimage->data.ptr, width * height , NULL ); + + CGImageRef imageRef = CGImageCreate(width, height, size , size*nbChannels , cvimage->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault); + + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:imageRef]; + if(image) { + [image release]; + }*/ + + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:cvimage->width + pixelsHigh:cvimage->height + bitsPerSample:8 + samplesPerPixel:3 + hasAlpha:NO + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:(cvimage->width * 4) + bitsPerPixel:32]; + + int pixelCount = cvimage->width * cvimage->height; + unsigned char *src = cvimage->data.ptr; + unsigned char *dst = [bitmap bitmapData]; + + for( int i = 0; i < pixelCount; i++ ) + { + dst[i * 4 + 0] = src[i * 3 + 0]; + dst[i * 4 + 1] = src[i * 3 + 1]; + dst[i * 4 + 2] = src[i * 3 + 2]; + } + + if( image ) + [image release]; + + image = [[NSImage alloc] init]; + [image addRepresentation:bitmap]; + [bitmap release]; + + /*CGColorSpaceRelease(colorspace); + CGDataProviderRelease(provider); + CGImageRelease(imageRef);*/ + cvReleaseMat(&cvimage); + [localpool drain]; + + [self setNeedsDisplay:YES]; + +} + +- (void)setFrameSize:(NSSize)size { + //cout << "setFrameSize" << endl; + [super setFrameSize:size]; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + int height = size.height; + + CVWindow *cvwindow = (CVWindow *)[self window]; + for(NSString *key in [cvwindow sliders]) { + NSSlider *slider = [[cvwindow sliders] valueForKey:key]; + NSRect r = [slider frame]; + r.origin.y = height - r.size.height; + r.size.width = [[cvwindow contentView] frame].size.width; + [slider setFrame:r]; + height -= r.size.height; + } + [localpool drain]; +} + +- (void)drawRect:(NSRect)rect { + //cout << "drawRect" << endl; + [super drawRect:rect]; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CVWindow *cvwindow = (CVWindow *)[self window]; + int height = 0; + if ([cvwindow respondsToSelector:@selector(sliders)]) { + for(NSString *key in [cvwindow sliders]) { + height += [[[cvwindow sliders] valueForKey:key] frame].size.height; + } + } + + + NSRect imageRect = {{0,0}, {[image size].width, [image size].height}}; + + if(image != nil) { + [image drawInRect: imageRect + fromRect: NSZeroRect + operation: NSCompositeSourceOver + fraction: 1.0]; + } + [localpool release]; + +} + +@end + +@implementation CVSlider + +@synthesize slider; +@synthesize name; +@synthesize value; +@synthesize userData; +@synthesize callback; +@synthesize callback2; + +- (id)init { + [super init]; + + callback = NULL; + value = NULL; + userData = NULL; + + [self setFrame:NSMakeRect(0,0,200,30)]; + + name = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 0,110, 25)]; + [name setEditable:NO]; + [name setSelectable:NO]; + [name setBezeled:NO]; + [name setBordered:NO]; + [name setDrawsBackground:NO]; + [[name cell] setLineBreakMode:NSLineBreakByTruncatingTail]; + [self addSubview:name]; + + slider = [[NSSlider alloc] initWithFrame:NSMakeRect(120, 0, 70, 25)]; + [slider setAutoresizingMask:NSViewWidthSizable]; + [slider setMinValue:0]; + [slider setMaxValue:100]; + [slider setContinuous:YES]; + [slider setTarget:self]; + [slider setAction:@selector(sliderChanged:)]; + [self addSubview:slider]; + + [self setAutoresizingMask:NSViewWidthSizable]; + + //[self setFrame:NSMakeRect(12, 0, 100, 30)]; + + return self; +} + +- (void)sliderChanged:(NSNotification *)notification { + (void)notification; + int pos = [slider intValue]; + if(value) + *value = pos; + if(callback) + callback(pos); + if(callback2) + callback2(pos, userData); +} + +@end + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_gtk.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/window_gtk.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_gtk.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_gtk.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1641 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifndef WIN32 + +#ifdef HAVE_GTK + +#include "gtk/gtk.h" +#include "gdk/gdkkeysyms.h" +#include + +#ifdef HAVE_OPENGL + #include + #include + #include +#endif + +// TODO Fix the initial window size when flags=0. Right now the initial window is by default +// 320x240 size. A better default would be actual size of the image. Problem +// is determining desired window size with trackbars while still allowing resizing. +// +// Gnome Totem source may be of use here, see bacon_video_widget_set_scale_ratio +// in totem/src/backend/bacon-video-widget-xine.c + +//////////////////////////////////////////////////////////// +// CvImageWidget GTK Widget Public API +//////////////////////////////////////////////////////////// +typedef struct _CvImageWidget CvImageWidget; +typedef struct _CvImageWidgetClass CvImageWidgetClass; + +struct _CvImageWidget { + GtkWidget widget; + CvMat * original_image; + CvMat * scaled_image; + int flags; +}; + +struct _CvImageWidgetClass +{ + GtkWidgetClass parent_class; +}; + + +/** Allocate new image viewer widget */ +GtkWidget* cvImageWidgetNew (int flags); + +/** Set the image to display in the widget */ +void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr); + +// standard GTK object macros +#define CV_IMAGE_WIDGET(obj) GTK_CHECK_CAST (obj, cvImageWidget_get_type (), CvImageWidget) +#define CV_IMAGE_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cvImageWidget_get_type (), CvImageWidgetClass) +#define CV_IS_IMAGE_WIDGET(obj) GTK_CHECK_TYPE (obj, cvImageWidget_get_type ()) + +///////////////////////////////////////////////////////////////////////////// +// Private API //////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +GtkType cvImageWidget_get_type (void); + +static GtkWidgetClass * parent_class = NULL; + +// flag to help size initial window +#define CV_WINDOW_NO_IMAGE 2 + +void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr){ + CvMat * mat, stub; + int origin=0; + + //printf("cvImageWidgetSetImage\n"); + + if( CV_IS_IMAGE_HDR( arr )) + origin = ((IplImage*)arr)->origin; + + mat = cvGetMat(arr, &stub); + + if(widget->original_image && !CV_ARE_SIZES_EQ(mat, widget->original_image)){ + cvReleaseMat( &widget->original_image ); + } + if(!widget->original_image){ + widget->original_image = cvCreateMat( mat->rows, mat->cols, CV_8UC3 ); + gtk_widget_queue_resize( GTK_WIDGET( widget ) ); + } + cvConvertImage( mat, widget->original_image, + (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB ); + if(widget->scaled_image){ + cvResize( widget->original_image, widget->scaled_image, CV_INTER_AREA ); + } + + // window does not refresh without this + gtk_widget_queue_draw( GTK_WIDGET(widget) ); +} + +GtkWidget* +cvImageWidgetNew (int flags) +{ + CvImageWidget *image_widget; + + image_widget = CV_IMAGE_WIDGET( gtk_type_new (cvImageWidget_get_type ()) ); + image_widget->original_image = 0; + image_widget->scaled_image = 0; + image_widget->flags = flags | CV_WINDOW_NO_IMAGE; + + return GTK_WIDGET (image_widget); +} + +static void +cvImageWidget_realize (GtkWidget *widget) +{ + GdkWindowAttr attributes; + gint attributes_mask; + + //printf("cvImageWidget_realize\n"); + g_return_if_fail (widget != NULL); + g_return_if_fail (CV_IS_IMAGE_WIDGET (widget)); + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.event_mask = gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask); + + widget->style = gtk_style_attach (widget->style, widget->window); + + gdk_window_set_user_data (widget->window, widget); + + gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE); +} + +static CvSize cvImageWidget_calc_size( int im_width, int im_height, int max_width, int max_height ){ + float aspect = (float)im_width/(float)im_height; + float max_aspect = (float)max_width/(float)max_height; + if(aspect > max_aspect){ + return cvSize( max_width, cvRound(max_width/aspect) ); + } + return cvSize( cvRound(max_height*aspect), max_height ); +} + +static void +cvImageWidget_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); + + //printf("cvImageWidget_size_request "); + // the case the first time cvShowImage called or when AUTOSIZE + if( image_widget->original_image && + ((image_widget->flags & CV_WINDOW_AUTOSIZE) || + (image_widget->flags & CV_WINDOW_NO_IMAGE))) + { + //printf("original "); + requisition->width = image_widget->original_image->cols; + requisition->height = image_widget->original_image->rows; + } + // default case + else if(image_widget->scaled_image){ + //printf("scaled "); + requisition->width = image_widget->scaled_image->cols; + requisition->height = image_widget->scaled_image->rows; + } + // the case before cvShowImage called + else{ + //printf("default "); + requisition->width = 320; + requisition->height = 240; + } + //printf("%d %d\n",requisition->width, requisition->height); +} + +static void cvImageWidget_set_size(GtkWidget * widget, int max_width, int max_height){ + CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); + + //printf("cvImageWidget_set_size %d %d\n", max_width, max_height); + + // don't allow to set the size + if(image_widget->flags & CV_WINDOW_AUTOSIZE) return; + if(!image_widget->original_image) return; + + CvSize scaled_image_size = cvImageWidget_calc_size( image_widget->original_image->cols, + image_widget->original_image->rows, max_width, max_height ); + + if( image_widget->scaled_image && + ( image_widget->scaled_image->cols != scaled_image_size.width || + image_widget->scaled_image->rows != scaled_image_size.height )) + { + cvReleaseMat( &image_widget->scaled_image ); + } + if( !image_widget->scaled_image ){ + image_widget->scaled_image = cvCreateMat( scaled_image_size.height, scaled_image_size.width, CV_8UC3 ); + + + } + assert( image_widget->scaled_image ); +} + +static void +cvImageWidget_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + CvImageWidget *image_widget; + + //printf("cvImageWidget_size_allocate\n"); + g_return_if_fail (widget != NULL); + g_return_if_fail (CV_IS_IMAGE_WIDGET (widget)); + g_return_if_fail (allocation != NULL); + + widget->allocation = *allocation; + image_widget = CV_IMAGE_WIDGET (widget); + + + if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && image_widget->original_image ){ + // (re) allocated scaled image + if( image_widget->flags & CV_WINDOW_NO_IMAGE ){ + cvImageWidget_set_size( widget, image_widget->original_image->cols, + image_widget->original_image->rows); + } + else{ + cvImageWidget_set_size( widget, allocation->width, allocation->height ); + } + cvResize( image_widget->original_image, image_widget->scaled_image, CV_INTER_AREA ); + } + + if (GTK_WIDGET_REALIZED (widget)) + { + image_widget = CV_IMAGE_WIDGET (widget); + + if( image_widget->original_image && + ((image_widget->flags & CV_WINDOW_AUTOSIZE) || + (image_widget->flags & CV_WINDOW_NO_IMAGE)) ) + { + widget->allocation.width = image_widget->original_image->cols; + widget->allocation.height = image_widget->original_image->rows; + gdk_window_move_resize( widget->window, allocation->x, allocation->y, + image_widget->original_image->cols, image_widget->original_image->rows ); + if(image_widget->flags & CV_WINDOW_NO_IMAGE){ + image_widget->flags &= ~CV_WINDOW_NO_IMAGE; + gtk_widget_queue_resize( GTK_WIDGET(widget) ); + } + } + else{ + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height ); + + } + } +} + +static void +cvImageWidget_destroy (GtkObject *object) +{ + CvImageWidget *image_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (CV_IS_IMAGE_WIDGET (object)); + + image_widget = CV_IMAGE_WIDGET (object); + + cvReleaseMat( &image_widget->scaled_image ); + cvReleaseMat( &image_widget->original_image ); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void cvImageWidget_class_init (CvImageWidgetClass * klass) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GtkObjectClass*) klass; + widget_class = (GtkWidgetClass*) klass; + + parent_class = GTK_WIDGET_CLASS( gtk_type_class (gtk_widget_get_type ()) ); + + object_class->destroy = cvImageWidget_destroy; + + widget_class->realize = cvImageWidget_realize; + widget_class->size_request = cvImageWidget_size_request; + widget_class->size_allocate = cvImageWidget_size_allocate; + widget_class->button_press_event = NULL; + widget_class->button_release_event = NULL; + widget_class->motion_notify_event = NULL; +} + +static void +cvImageWidget_init (CvImageWidget *image_widget) +{ + image_widget->original_image=0; + image_widget->scaled_image=0; + image_widget->flags=0; +} + +GtkType cvImageWidget_get_type (void){ + static GtkType image_type = 0; + + if (!image_type) + { + static const GtkTypeInfo image_info = + { + (gchar*)"CvImageWidget", + sizeof (CvImageWidget), + sizeof (CvImageWidgetClass), + (GtkClassInitFunc) cvImageWidget_class_init, + (GtkObjectInitFunc) cvImageWidget_init, + /* reserved_1 */ NULL, + /* reserved_1 */ NULL, + (GtkClassInitFunc) NULL + }; + + image_type = gtk_type_unique (GTK_TYPE_WIDGET, &image_info); + } + + return image_type; +} +///////////////////////////////////////////////////////////////////////////// +// End CvImageWidget +///////////////////////////////////////////////////////////////////////////// + + +struct CvWindow; + +typedef struct CvTrackbar +{ + int signature; + GtkWidget* widget; + char* name; + CvTrackbar* next; + CvWindow* parent; + int* data; + int pos; + int maxval; + CvTrackbarCallback notify; + CvTrackbarCallback2 notify2; + void* userdata; +} +CvTrackbar; + + +typedef struct CvWindow +{ + int signature; + GtkWidget* widget; + GtkWidget* frame; + GtkWidget* paned; + char* name; + CvWindow* prev; + CvWindow* next; + + int last_key; + int flags; + int status;//0 normal, 1 fullscreen (YV) + + CvMouseCallback on_mouse; + void* on_mouse_param; + + struct + { + int pos; + int rows; + CvTrackbar* first; + } + toolbar; + +#ifdef HAVE_OPENGL + bool useGl; + + CvOpenGlDrawCallback glDrawCallback; + void* glDrawData; +#endif +} +CvWindow; + + +static gboolean icvOnClose( GtkWidget* widget, GdkEvent* event, gpointer user_data ); +static gboolean icvOnKeyPress( GtkWidget* widget, GdkEventKey* event, gpointer user_data ); +static void icvOnTrackbar( GtkWidget* widget, gpointer user_data ); +static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_data ); + +#ifdef HAVE_GTHREAD +int thread_started=0; +static gpointer icvWindowThreadLoop(); +GMutex* last_key_mutex; +GCond* cond_have_key; +GMutex* window_mutex; +GThread* window_thread; +GtkWidget* cvTopLevelWidget = 0; +#endif + +static int last_key = -1; +static CvWindow* hg_windows = 0; + +CV_IMPL int cvInitSystem( int argc, char** argv ) +{ + static int wasInitialized = 0; + + // check initialization status + if( !wasInitialized ) + { + hg_windows = 0; + + gtk_disable_setlocale(); + gtk_init( &argc, &argv ); + + #ifdef HAVE_OPENGL + gtk_gl_init(&argc, &argv); + #endif + + wasInitialized = 1; + } + + return 0; +} + +CV_IMPL int cvStartWindowThread(){ +#ifdef HAVE_GTHREAD + cvInitSystem(0,NULL); + if (!thread_started) { + if (!g_thread_supported ()) { + /* the GThread system wasn't inited, so init it */ + g_thread_init(NULL); + } + + // this mutex protects the window resources + window_mutex = g_mutex_new(); + + // protects the 'last key pressed' variable + last_key_mutex = g_mutex_new(); + + // conditional that indicates a key has been pressed + cond_have_key = g_cond_new(); + + // this is the window update thread + window_thread = g_thread_create((GThreadFunc) icvWindowThreadLoop, + NULL, TRUE, NULL); + } + thread_started = window_thread!=NULL; + return thread_started; +#else + return 0; +#endif +} + +#ifdef HAVE_GTHREAD +gpointer icvWindowThreadLoop(){ + while(1){ + g_mutex_lock(window_mutex); + gtk_main_iteration_do(FALSE); + g_mutex_unlock(window_mutex); + + // little sleep + g_usleep(500); + + g_thread_yield(); + } + return NULL; +} + +#define CV_LOCK_MUTEX() \ +if(thread_started && g_thread_self()!=window_thread){ g_mutex_lock( window_mutex ); } else { } + +#define CV_UNLOCK_MUTEX() \ +if(thread_started && g_thread_self()!=window_thread){ g_mutex_unlock( window_mutex); } else { } + +#else +#define CV_LOCK_MUTEX() +#define CV_UNLOCK_MUTEX() +#endif + +static CvWindow* icvFindWindowByName( const char* name ) +{ + CvWindow* window = hg_windows; + while( window != 0 && strcmp(name, window->name) != 0 ) + window = window->next; + + return window; +} + +static CvWindow* icvWindowByWidget( GtkWidget* widget ) +{ + CvWindow* window = hg_windows; + + while( window != 0 && window->widget != widget && + window->frame != widget && window->paned != widget ) + window = window->next; + + return window; +} + +double cvGetModeWindow_GTK(const char* name)//YV +{ + double result = -1; + + CV_FUNCNAME( "cvGetModeWindow_GTK" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + CV_LOCK_MUTEX(); + result = window->status; + CV_UNLOCK_MUTEX(); + + __END__; + return result; +} + + +void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie +{ + + CV_FUNCNAME( "cvSetModeWindow_GTK" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set + EXIT; + + //so easy to do fullscreen here, Linux rocks ! + + if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) + { + CV_LOCK_MUTEX(); + gtk_window_unfullscreen(GTK_WINDOW(window->frame)); + window->status=CV_WINDOW_NORMAL; + CV_UNLOCK_MUTEX(); + EXIT; + } + + if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) + { + CV_LOCK_MUTEX(); + gtk_window_fullscreen(GTK_WINDOW(window->frame)); + window->status=CV_WINDOW_FULLSCREEN; + CV_UNLOCK_MUTEX(); + EXIT; + } + + __END__; +} + + +double cvGetPropWindowAutoSize_GTK(const char* name) +{ + double result = -1; + + CV_FUNCNAME( "cvGetPropWindowAutoSize_GTK" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = window->flags & CV_WINDOW_AUTOSIZE; + + __END__; + + return result; +} + +double cvGetRatioWindow_GTK(const char* name) +{ + double result = -1; + + CV_FUNCNAME( "cvGetRatioWindow_GTK" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = static_cast(window->widget->allocation.width) / window->widget->allocation.height; + + __END__; + + return result; +} + +double cvGetOpenGlProp_GTK(const char* name) +{ + double result = -1; + +#ifdef HAVE_OPENGL + CV_FUNCNAME( "cvGetOpenGlProp_GTK" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = window->useGl; + + __END__; +#else + (void)name; +#endif + + return result; +} + + +// OpenGL support + +#ifdef HAVE_OPENGL + +namespace +{ + void createGlContext(CvWindow* window) + { + GdkGLConfig* glconfig; + + CV_FUNCNAME( "createGlContext" ); + + __BEGIN__; + + // Try double-buffered visual + glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); + if (!glconfig) + CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + + // Set OpenGL-capability to the widget + if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + + window->useGl = true; + + __END__; + } + + void drawGl(CvWindow* window) + { + CV_FUNCNAME( "drawGl" ); + + __BEGIN__; + + GdkGLContext* glcontext = gtk_widget_get_gl_context(window->widget); + GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget); + + if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + glViewport(0, 0, window->widget->allocation.width, window->widget->allocation.height); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (window->glDrawCallback) + window->glDrawCallback(window->glDrawData); + + if (gdk_gl_drawable_is_double_buffered (gldrawable)) + gdk_gl_drawable_swap_buffers(gldrawable); + else + glFlush(); + + gdk_gl_drawable_gl_end(gldrawable); + + __END__; + } +} + +#endif // HAVE_OPENGL + + +static gboolean cvImageWidget_expose(GtkWidget* widget, GdkEventExpose* event, gpointer data) +{ +#ifdef HAVE_OPENGL + CvWindow* window = (CvWindow*)data; + + if (window->useGl) + { + drawGl(window); + return TRUE; + } +#else + (void)data; +#endif + + CvImageWidget *image_widget; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (CV_IS_IMAGE_WIDGET (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + if (event->count > 0) + return FALSE; + + image_widget = CV_IMAGE_WIDGET (widget); + + gdk_window_clear_area (widget->window, + 0, 0, + widget->allocation.width, + widget->allocation.height); + if( image_widget->scaled_image ){ + // center image in available region + int x0 = (widget->allocation.width - image_widget->scaled_image->cols)/2; + int y0 = (widget->allocation.height - image_widget->scaled_image->rows)/2; + + gdk_draw_rgb_image( widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], + x0, y0, MIN(image_widget->scaled_image->cols, widget->allocation.width), + MIN(image_widget->scaled_image->rows, widget->allocation.height), + GDK_RGB_DITHER_MAX, image_widget->scaled_image->data.ptr, image_widget->scaled_image->step ); + } + else if( image_widget->original_image ){ + gdk_draw_rgb_image( widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], + 0, 0, + MIN(image_widget->original_image->cols, widget->allocation.width), + MIN(image_widget->original_image->rows, widget->allocation.height), + GDK_RGB_DITHER_MAX, image_widget->original_image->data.ptr, image_widget->original_image->step ); + } + return TRUE; +} + +CV_IMPL int cvNamedWindow( const char* name, int flags ) +{ + int result = 0; + CV_FUNCNAME( "cvNamedWindow" ); + + __BEGIN__; + + CvWindow* window; + int len; + + cvInitSystem(1,(char**)&name); + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + // Check the name in the storage + if( icvFindWindowByName( name ) != 0 ) + { + result = 1; + EXIT; + } + + len = strlen(name); + CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); + memset( window, 0, sizeof(*window)); + window->name = (char*)(window + 1); + memcpy( window->name, name, len + 1 ); + window->flags = flags; + window->signature = CV_WINDOW_MAGIC_VAL; + window->last_key = 0; + window->on_mouse = 0; + window->on_mouse_param = 0; + memset( &window->toolbar, 0, sizeof(window->toolbar)); + window->next = hg_windows; + window->prev = 0; + window->status = CV_WINDOW_NORMAL;//YV + + CV_LOCK_MUTEX(); + + window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + + window->paned = gtk_vbox_new( FALSE, 0 ); + window->widget = cvImageWidgetNew( flags ); + gtk_box_pack_end( GTK_BOX(window->paned), window->widget, TRUE, TRUE, 0 ); + gtk_widget_show( window->widget ); + gtk_container_add( GTK_CONTAINER(window->frame), window->paned ); + gtk_widget_show( window->paned ); + +#ifndef HAVE_OPENGL + if (flags & CV_WINDOW_OPENGL) + CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); +#else + if (flags & CV_WINDOW_OPENGL) + createGlContext(window); + + window->glDrawCallback = 0; + window->glDrawData = 0; +#endif + + // + // configure event handlers + // TODO -- move this to CvImageWidget ? + gtk_signal_connect( GTK_OBJECT(window->frame), "key-press-event", + GTK_SIGNAL_FUNC(icvOnKeyPress), window ); + gtk_signal_connect( GTK_OBJECT(window->widget), "button-press-event", + GTK_SIGNAL_FUNC(icvOnMouse), window ); + gtk_signal_connect( GTK_OBJECT(window->widget), "button-release-event", + GTK_SIGNAL_FUNC(icvOnMouse), window ); + gtk_signal_connect( GTK_OBJECT(window->widget), "motion-notify-event", + GTK_SIGNAL_FUNC(icvOnMouse), window ); + gtk_signal_connect( GTK_OBJECT(window->frame), "delete-event", + GTK_SIGNAL_FUNC(icvOnClose), window ); + gtk_signal_connect( GTK_OBJECT(window->widget), "expose-event", + GTK_SIGNAL_FUNC(cvImageWidget_expose), window ); + + gtk_widget_add_events (window->widget, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK) ; + + gtk_widget_show( window->frame ); + gtk_window_set_title( GTK_WINDOW(window->frame), name ); + + if( hg_windows ) + hg_windows->prev = window; + hg_windows = window; + + gtk_window_set_resizable( GTK_WINDOW(window->frame), (flags & CV_WINDOW_AUTOSIZE) == 0 ); + + + // allow window to be resized + if( (flags & CV_WINDOW_AUTOSIZE)==0 ){ + GdkGeometry geometry; + geometry.min_width = 50; + geometry.min_height = 50; + gtk_window_set_geometry_hints( GTK_WINDOW( window->frame ), GTK_WIDGET( window->widget ), + &geometry, (GdkWindowHints) (GDK_HINT_MIN_SIZE)); + } + + CV_UNLOCK_MUTEX(); + +#ifdef HAVE_OPENGL + if (window->useGl) + cvSetOpenGlContext(name); +#endif + + result = 1; + __END__; + + return result; +} + + +#ifdef HAVE_OPENGL + +CV_IMPL void cvSetOpenGlContext(const char* name) +{ + CvWindow* window; + GdkGLContext* glcontext; + GdkGLDrawable* gldrawable; + + CV_FUNCNAME( "cvSetOpenGlContext" ); + + __BEGIN__; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + if (!window->useGl) + CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + + glcontext = gtk_widget_get_gl_context(window->widget); + gldrawable = gtk_widget_get_gl_drawable(window->widget); + + if (!gdk_gl_drawable_make_current(gldrawable, glcontext)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + __END__; +} + +CV_IMPL void cvUpdateWindow(const char* name) +{ + CV_FUNCNAME( "cvUpdateWindow" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; + + // window does not refresh without this + gtk_widget_queue_draw( GTK_WIDGET(window->widget) ); + + __END__; +} + +CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata) +{ + CvWindow* window; + + CV_FUNCNAME( "cvCreateOpenGLCallback" ); + + __BEGIN__; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + EXIT; + + if (!window->useGl) + CV_ERROR( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + + window->glDrawCallback = callback; + window->glDrawData = userdata; + + __END__; +} + +#endif // HAVE_OPENGL + + + + +static void icvDeleteWindow( CvWindow* window ) +{ + CvTrackbar* trackbar; + + if( window->prev ) + window->prev->next = window->next; + else + hg_windows = window->next; + + if( window->next ) + window->next->prev = window->prev; + + window->prev = window->next = 0; + + gtk_widget_destroy( window->frame ); + + for( trackbar = window->toolbar.first; trackbar != 0; ) + { + CvTrackbar* next = trackbar->next; + cvFree( &trackbar ); + trackbar = next; + } + + cvFree( &window ); +#ifdef HAVE_GTHREAD + // if last window, send key press signal + // to jump out of any waiting cvWaitKey's + if(hg_windows==0 && thread_started){ + g_cond_broadcast(cond_have_key); + } +#endif +} + + +CV_IMPL void cvDestroyWindow( const char* name ) +{ + CV_FUNCNAME( "cvDestroyWindow" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + EXIT; + + // note that it is possible for the update thread to run this function + // if there is a call to cvShowImage in a mouse callback + // (this would produce a deadlock on window_mutex) + CV_LOCK_MUTEX(); + + icvDeleteWindow( window ); + + CV_UNLOCK_MUTEX(); + + __END__; +} + + +CV_IMPL void +cvDestroyAllWindows( void ) +{ + CV_LOCK_MUTEX(); + + while( hg_windows ) + { + CvWindow* window = hg_windows; + icvDeleteWindow( window ); + } + CV_UNLOCK_MUTEX(); +} + +// CvSize icvCalcOptimalWindowSize( CvWindow * window, CvSize new_image_size){ +// CvSize window_size; +// GtkWidget * toplevel = gtk_widget_get_toplevel( window->frame ); +// gdk_drawable_get_size( GDK_DRAWABLE(toplevel->window), +// &window_size.width, &window_size.height ); + +// window_size.width = window_size.width + new_image_size.width - window->widget->allocation.width; +// window_size.height = window_size.height + new_image_size.height - window->widget->allocation.height; + +// return window_size; +// } + +CV_IMPL void +cvShowImage( const char* name, const CvArr* arr ) +{ + CV_FUNCNAME( "cvShowImage" ); + + __BEGIN__; + + CvWindow* window; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + CV_LOCK_MUTEX(); + + window = icvFindWindowByName(name); + if(!window) + { + cvNamedWindow(name, 1); + window = icvFindWindowByName(name); + } + + if( window && arr ) + { + #ifdef HAVE_OPENGL + if (window->useGl) + { + CvMat stub; + CvMat* mat = cvGetMat(arr, &stub); + cv::Mat im(mat); + cv::imshow(name, im); + return; + } + #endif + + CvImageWidget * image_widget = CV_IMAGE_WIDGET( window->widget ); + cvImageWidgetSetImage( image_widget, arr ); + } + + CV_UNLOCK_MUTEX(); + + __END__; +} + +CV_IMPL void cvResizeWindow(const char* name, int width, int height ) +{ + CV_FUNCNAME( "cvResizeWindow" ); + + __BEGIN__; + + CvWindow* window; + CvImageWidget * image_widget; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + image_widget = CV_IMAGE_WIDGET( window->widget ); + //if(image_widget->flags & CV_WINDOW_AUTOSIZE) + //EXIT; + + CV_LOCK_MUTEX(); + + gtk_window_set_resizable( GTK_WINDOW(window->frame), 1 ); + gtk_window_resize( GTK_WINDOW(window->frame), width, height ); + + // disable initial resize since presumably user wants to keep + // this window size + image_widget->flags &= ~CV_WINDOW_NO_IMAGE; + + CV_UNLOCK_MUTEX(); + + __END__; +} + + +CV_IMPL void cvMoveWindow( const char* name, int x, int y ) +{ + CV_FUNCNAME( "cvMoveWindow" ); + + __BEGIN__; + + CvWindow* window; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + CV_LOCK_MUTEX(); + + gtk_window_move( GTK_WINDOW(window->frame), x, y ); + + CV_UNLOCK_MUTEX(); + + __END__; +} + + +static CvTrackbar* +icvFindTrackbarByName( const CvWindow* window, const char* name ) +{ + CvTrackbar* trackbar = window->toolbar.first; + + for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next ) + ; + + return trackbar; +} + +static int +icvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify, + CvTrackbarCallback2 on_notify2, void* userdata ) +{ + int result = 0; + + CV_FUNCNAME( "icvCreateTrackbar" ); + + __BEGIN__; + + /*char slider_name[32];*/ + CvWindow* window = 0; + CvTrackbar* trackbar = 0; + + if( !window_name || !trackbar_name ) + CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" ); + + if( count <= 0 ) + CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + + window = icvFindWindowByName(window_name); + if( !window ) + EXIT; + + trackbar = icvFindTrackbarByName(window,trackbar_name); + + CV_LOCK_MUTEX(); + + if( !trackbar ) + { + int len = strlen(trackbar_name); + trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1); + memset( trackbar, 0, sizeof(*trackbar)); + trackbar->signature = CV_TRACKBAR_MAGIC_VAL; + trackbar->name = (char*)(trackbar+1); + memcpy( trackbar->name, trackbar_name, len + 1 ); + trackbar->parent = window; + trackbar->next = window->toolbar.first; + window->toolbar.first = trackbar; + + GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 ); + GtkWidget* hscale_label = gtk_label_new( trackbar_name ); + GtkWidget* hscale = gtk_hscale_new_with_range( 0, count, 1 ); + gtk_range_set_update_policy( GTK_RANGE(hscale), GTK_UPDATE_CONTINUOUS ); + gtk_scale_set_digits( GTK_SCALE(hscale), 0 ); + //gtk_scale_set_value_pos( hscale, GTK_POS_TOP ); + gtk_scale_set_draw_value( GTK_SCALE(hscale), TRUE ); + + trackbar->widget = hscale; + gtk_box_pack_start( GTK_BOX(hscale_box), hscale_label, FALSE, FALSE, 5 ); + gtk_widget_show( hscale_label ); + gtk_box_pack_start( GTK_BOX(hscale_box), hscale, TRUE, TRUE, 5 ); + gtk_widget_show( hscale ); + gtk_box_pack_start( GTK_BOX(window->paned), hscale_box, FALSE, FALSE, 5 ); + gtk_widget_show( hscale_box ); + + } + + if( val ) + { + int value = *val; + if( value < 0 ) + value = 0; + if( value > count ) + value = count; + gtk_range_set_value( GTK_RANGE(trackbar->widget), value ); + trackbar->pos = value; + trackbar->data = val; + } + + trackbar->maxval = count; + trackbar->notify = on_notify; + trackbar->notify2 = on_notify2; + trackbar->userdata = userdata; + gtk_signal_connect( GTK_OBJECT(trackbar->widget), "value-changed", + GTK_SIGNAL_FUNC(icvOnTrackbar), trackbar ); + + // queue a widget resize to trigger a window resize to + // compensate for the addition of trackbars + gtk_widget_queue_resize( GTK_WIDGET(window->widget) ); + + + CV_UNLOCK_MUTEX(); + + result = 1; + + __END__; + + return result; +} + + +CV_IMPL int +cvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify ) +{ + return icvCreateTrackbar(trackbar_name, window_name, val, count, + on_notify, 0, 0); +} + + +CV_IMPL int +cvCreateTrackbar2( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback2 on_notify2, + void* userdata ) +{ + return icvCreateTrackbar(trackbar_name, window_name, val, count, + 0, on_notify2, userdata); +} + + +CV_IMPL void +cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) +{ + CV_FUNCNAME( "cvSetMouseCallback" ); + + __BEGIN__; + + CvWindow* window = 0; + + if( !window_name ) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + window = icvFindWindowByName(window_name); + if( !window ) + EXIT; + + window->on_mouse = on_mouse; + window->on_mouse_param = param; + + __END__; +} + + +CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) +{ + int pos = -1; + + CV_FUNCNAME( "cvGetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + pos = trackbar->pos; + + __END__; + + return pos; +} + + +CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) +{ + CV_FUNCNAME( "cvSetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + { + if( pos < 0 ) + pos = 0; + + if( pos > trackbar->maxval ) + pos = trackbar->maxval; + } + + CV_LOCK_MUTEX(); + + gtk_range_set_value( GTK_RANGE(trackbar->widget), pos ); + + CV_UNLOCK_MUTEX(); + + __END__; +} + + +CV_IMPL void* cvGetWindowHandle( const char* window_name ) +{ + void* widget = 0; + + CV_FUNCNAME( "cvGetWindowHandle" ); + + __BEGIN__; + + CvWindow* window; + + if( window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + widget = (void*)window->widget; + + __END__; + + return widget; +} + + +CV_IMPL const char* cvGetWindowName( void* window_handle ) +{ + const char* window_name = ""; + + CV_FUNCNAME( "cvGetWindowName" ); + + __BEGIN__; + + CvWindow* window; + + if( window_handle == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + window = icvWindowByWidget( (GtkWidget*)window_handle ); + if( window ) + window_name = window->name; + + __END__; + + return window_name; +} + +static gboolean icvOnKeyPress( GtkWidget * /*widget*/, + GdkEventKey* event, gpointer /*user_data*/ ) +{ + int code = 0; + + switch( event->keyval ) + { + case GDK_Escape: + code = 27; + break; + case GDK_Return: + case GDK_Linefeed: + code = '\n'; + break; + case GDK_Tab: + code = '\t'; + break; + default: + code = event->keyval; + } + + code |= event->state << 16; + +#ifdef HAVE_GTHREAD + if(thread_started) g_mutex_lock(last_key_mutex); +#endif + + last_key = code; + +#ifdef HAVE_GTHREAD + if(thread_started){ + // signal any waiting threads + g_cond_broadcast(cond_have_key); + g_mutex_unlock(last_key_mutex); + } +#endif + + return FALSE; +} + + +static void icvOnTrackbar( GtkWidget* widget, gpointer user_data ) +{ + int pos = cvRound( gtk_range_get_value(GTK_RANGE(widget))); + CvTrackbar* trackbar = (CvTrackbar*)user_data; + + if( trackbar && trackbar->signature == CV_TRACKBAR_MAGIC_VAL && + trackbar->widget == widget ) + { + trackbar->pos = pos; + if( trackbar->data ) + *trackbar->data = pos; + if( trackbar->notify2 ) + trackbar->notify2(pos, trackbar->userdata); + else if( trackbar->notify ) + trackbar->notify(pos); + } +} + +static gboolean icvOnClose( GtkWidget* widget, GdkEvent* /*event*/, gpointer user_data ) +{ + CvWindow* window = (CvWindow*)user_data; + if( window->signature == CV_WINDOW_MAGIC_VAL && + window->frame == widget ) + { + icvDeleteWindow(window); + } + return TRUE; +} + + +static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_data ) +{ + // TODO move this logic to CvImageWidget + CvWindow* window = (CvWindow*)user_data; + CvPoint2D32f pt32f = {-1., -1.}; + CvPoint pt = {-1,-1}; + int cv_event = -1, state = 0; + CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); + + if( window->signature != CV_WINDOW_MAGIC_VAL || + window->widget != widget || !window->widget || + !window->on_mouse /*|| !image_widget->original_image*/) + return FALSE; + + if( event->type == GDK_MOTION_NOTIFY ) + { + GdkEventMotion* event_motion = (GdkEventMotion*)event; + + cv_event = CV_EVENT_MOUSEMOVE; + pt32f.x = cvRound(event_motion->x); + pt32f.y = cvRound(event_motion->y); + state = event_motion->state; + } + else if( event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE || + event->type == GDK_2BUTTON_PRESS ) + { + GdkEventButton* event_button = (GdkEventButton*)event; + pt32f.x = cvRound(event_button->x); + pt32f.y = cvRound(event_button->y); + + + if( event_button->type == GDK_BUTTON_PRESS ) + { + cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDOWN : + event_button->button == 2 ? CV_EVENT_MBUTTONDOWN : + event_button->button == 3 ? CV_EVENT_RBUTTONDOWN : 0; + } + else if( event_button->type == GDK_BUTTON_RELEASE ) + { + cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONUP : + event_button->button == 2 ? CV_EVENT_MBUTTONUP : + event_button->button == 3 ? CV_EVENT_RBUTTONUP : 0; + } + else if( event_button->type == GDK_2BUTTON_PRESS ) + { + cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDBLCLK : + event_button->button == 2 ? CV_EVENT_MBUTTONDBLCLK : + event_button->button == 3 ? CV_EVENT_RBUTTONDBLCLK : 0; + } + state = event_button->state; + } + + if( cv_event >= 0 ){ + // scale point if image is scaled + if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && + image_widget->original_image && + image_widget->scaled_image ){ + // image origin is not necessarily at (0,0) + int x0 = (widget->allocation.width - image_widget->scaled_image->cols)/2; + int y0 = (widget->allocation.height - image_widget->scaled_image->rows)/2; + pt.x = cvRound( ((pt32f.x-x0)*image_widget->original_image->cols)/ + image_widget->scaled_image->cols ); + pt.y = cvRound( ((pt32f.y-y0)*image_widget->original_image->rows)/ + image_widget->scaled_image->rows ); + } + else{ + pt = cvPointFrom32f( pt32f ); + } + +// if((unsigned)pt.x < (unsigned)(image_widget->original_image->width) && +// (unsigned)pt.y < (unsigned)(image_widget->original_image->height) ) + { + int flags = (state & GDK_SHIFT_MASK ? CV_EVENT_FLAG_SHIFTKEY : 0) | + (state & GDK_CONTROL_MASK ? CV_EVENT_FLAG_CTRLKEY : 0) | + (state & (GDK_MOD1_MASK|GDK_MOD2_MASK) ? CV_EVENT_FLAG_ALTKEY : 0) | + (state & GDK_BUTTON1_MASK ? CV_EVENT_FLAG_LBUTTON : 0) | + (state & GDK_BUTTON2_MASK ? CV_EVENT_FLAG_MBUTTON : 0) | + (state & GDK_BUTTON3_MASK ? CV_EVENT_FLAG_RBUTTON : 0); + window->on_mouse( cv_event, pt.x, pt.y, flags, window->on_mouse_param ); + } + } + + return FALSE; + } + + +static gboolean icvAlarm( gpointer user_data ) +{ + *(int*)user_data = 1; + return FALSE; +} + + +CV_IMPL int cvWaitKey( int delay ) +{ +#ifdef HAVE_GTHREAD + if(thread_started && g_thread_self()!=window_thread){ + gboolean expired; + int my_last_key; + + // wait for signal or timeout if delay > 0 + if(delay>0){ + GTimeVal timer; + g_get_current_time(&timer); + g_time_val_add(&timer, delay*1000); + expired = !g_cond_timed_wait(cond_have_key, last_key_mutex, &timer); + } + else{ + g_cond_wait(cond_have_key, last_key_mutex); + expired=false; + } + my_last_key = last_key; + g_mutex_unlock(last_key_mutex); + if(expired || hg_windows==0){ + return -1; + } + return my_last_key; + } + else{ +#endif + int expired = 0; + guint timer = 0; + if( delay > 0 ) + timer = g_timeout_add( delay, icvAlarm, &expired ); + last_key = -1; + while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && hg_windows != 0 ) + ; + + if( delay > 0 && !expired ) + g_source_remove(timer); +#ifdef HAVE_GTHREAD + } +#endif + return last_key; +} + + +#endif // HAVE_GTK +#endif // WIN32 + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/src/window_w32.cpp diffimg-2.0.0/3rdparty/opencv/highgui/src/window_w32.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/src/window_w32.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/src/window_w32.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2170 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#if defined WIN32 || defined _WIN32 + +#define COMPILE_MULTIMON_STUBS // Required for multi-monitor support +#ifndef _MULTIMON_USE_SECURE_CRT +# define _MULTIMON_USE_SECURE_CRT 0 // some MinGW platforms have no strncpy_s +#endif + +#if defined SM_CMONITORS && !defined MONITOR_DEFAULTTONEAREST +# define MONITOR_DEFAULTTONULL 0x00000000 +# define MONITOR_DEFAULTTOPRIMARY 0x00000001 +# define MONITOR_DEFAULTTONEAREST 0x00000002 +# define MONITORINFOF_PRIMARY 0x00000001 +#endif +#ifndef __inout +# define __inout +#endif + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +#endif +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_OPENGL +#include +#include +#include +#include +#include "opencv2/highgui/highgui.hpp" +#include +#endif + +static const char* trackbar_text = +" "; + +#if defined _M_X64 || defined __x86_64 + +#define icvGetWindowLongPtr GetWindowLongPtr +#define icvSetWindowLongPtr( hwnd, id, ptr ) SetWindowLongPtr( hwnd, id, (LONG_PTR)(ptr) ) +#define icvGetClassLongPtr GetClassLongPtr + +#define CV_USERDATA GWLP_USERDATA +#define CV_WNDPROC GWLP_WNDPROC +#define CV_HCURSOR GCLP_HCURSOR +#define CV_HBRBACKGROUND GCLP_HBRBACKGROUND + +#else + +#define icvGetWindowLongPtr GetWindowLong +#define icvSetWindowLongPtr( hwnd, id, ptr ) SetWindowLong( hwnd, id, (size_t)ptr ) +#define icvGetClassLongPtr GetClassLong + +#define CV_USERDATA GWL_USERDATA +#define CV_WNDPROC GWL_WNDPROC +#define CV_HCURSOR GCL_HCURSOR +#define CV_HBRBACKGROUND GCL_HBRBACKGROUND + +#endif + +static void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin ) +{ + assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); + + BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); + + memset( bmih, 0, sizeof(*bmih)); + bmih->biSize = sizeof(BITMAPINFOHEADER); + bmih->biWidth = width; + bmih->biHeight = origin ? abs(height) : -abs(height); + bmih->biPlanes = 1; + bmih->biBitCount = (unsigned short)bpp; + bmih->biCompression = BI_RGB; + + if( bpp == 8 ) + { + RGBQUAD* palette = bmi->bmiColors; + int i; + for( i = 0; i < 256; i++ ) + { + palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; + palette[i].rgbReserved = 0; + } + } +} + +struct CvWindow; + +typedef struct CvTrackbar +{ + int signature; + HWND hwnd; + char* name; + CvTrackbar* next; + CvWindow* parent; + HWND buddy; + int* data; + int pos; + int maxval; + void (*notify)(int); + void (*notify2)(int, void*); + void* userdata; + int id; +} +CvTrackbar; + + +typedef struct CvWindow +{ + int signature; + HWND hwnd; + char* name; + CvWindow* prev; + CvWindow* next; + HWND frame; + + HDC dc; + HGDIOBJ image; + int last_key; + int flags; + int status;//0 normal, 1 fullscreen (YV) + + CvMouseCallback on_mouse; + void* on_mouse_param; + + struct + { + HWND toolbar; + int pos; + int rows; + WNDPROC toolBarProc; + CvTrackbar* first; + } + toolbar; + + int width; + int height; + + // OpenGL support + +#ifdef HAVE_OPENGL + bool useGl; + HGLRC hGLRC; + + CvOpenGlDrawCallback glDrawCallback; + void* glDrawData; +#endif +} +CvWindow; + +#define HG_BUDDY_WIDTH 130 + +#ifndef TBIF_SIZE + #define TBIF_SIZE 0x40 +#endif + +#ifndef TB_SETBUTTONINFO + #define TB_SETBUTTONINFO (WM_USER + 66) +#endif + +#ifndef TBM_GETTOOLTIPS + #define TBM_GETTOOLTIPS (WM_USER + 30) +#endif + +static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void icvUpdateWindowPos( CvWindow* window ); + +static CvWindow* hg_windows = 0; + +typedef int (CV_CDECL * CvWin32WindowCallback)(HWND, UINT, WPARAM, LPARAM, int*); +static CvWin32WindowCallback hg_on_preprocess = 0, hg_on_postprocess = 0; +static HINSTANCE hg_hinstance = 0; + +static const char* highGUIclassName = "HighGUI class"; +static const char* mainHighGUIclassName = "Main HighGUI class"; + +static void icvCleanupHighgui() +{ + cvDestroyAllWindows(); + UnregisterClass(highGUIclassName, hg_hinstance); + UnregisterClass(mainHighGUIclassName, hg_hinstance); +} + +CV_IMPL int cvInitSystem( int, char** ) +{ + static int wasInitialized = 0; + + // check initialization status + if( !wasInitialized ) + { + // Initialize the stogare + hg_windows = 0; + + // Register the class + WNDCLASS wndc; + wndc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wndc.lpfnWndProc = WindowProc; + wndc.cbClsExtra = 0; + wndc.cbWndExtra = 0; + wndc.hInstance = hg_hinstance; + wndc.lpszClassName = highGUIclassName; + wndc.lpszMenuName = highGUIclassName; + wndc.hIcon = LoadIcon(0, IDI_APPLICATION); + wndc.hCursor = (HCURSOR)LoadCursor(0, (LPSTR)(size_t)IDC_CROSS ); + wndc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + + RegisterClass(&wndc); + + wndc.lpszClassName = mainHighGUIclassName; + wndc.lpszMenuName = mainHighGUIclassName; + wndc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + wndc.lpfnWndProc = MainWindowProc; + + RegisterClass(&wndc); + atexit( icvCleanupHighgui ); + + wasInitialized = 1; + } + + return 0; +} + +CV_IMPL int cvStartWindowThread(){ + return 0; +} + +static CvWindow* icvFindWindowByName( const char* name ) +{ + CvWindow* window = hg_windows; + + for( ; window != 0 && strcmp( name, window->name) != 0; window = window->next ) + ; + + return window; +} + + +static CvWindow* icvWindowByHWND( HWND hwnd ) +{ + CvWindow* window = (CvWindow*)icvGetWindowLongPtr( hwnd, CV_USERDATA ); + return window != 0 && hg_windows != 0 && + window->signature == CV_WINDOW_MAGIC_VAL ? window : 0; +} + + +static CvTrackbar* icvTrackbarByHWND( HWND hwnd ) +{ + CvTrackbar* trackbar = (CvTrackbar*)icvGetWindowLongPtr( hwnd, CV_USERDATA ); + return trackbar != 0 && trackbar->signature == CV_TRACKBAR_MAGIC_VAL && + trackbar->hwnd == hwnd ? trackbar : 0; +} + + +static const char* icvWindowPosRootKey = "Software\\OpenCV\\HighGUI\\Windows\\"; + +// Window positions saving/loading added by Philip Gruebele. +//pgruebele@cox.net +// Restores the window position from the registry saved position. +static void +icvLoadWindowPos( const char* name, CvRect& rect ) +{ + HKEY hkey; + char szKey[1024]; + strcpy( szKey, icvWindowPosRootKey ); + strcat( szKey, name ); + + rect.x = rect.y = CW_USEDEFAULT; + rect.width = rect.height = 320; + + if( RegOpenKeyEx(HKEY_CURRENT_USER,szKey,0,KEY_QUERY_VALUE,&hkey) == ERROR_SUCCESS ) + { + // Yes we are installed. + DWORD dwType = 0; + DWORD dwSize = sizeof(int); + + RegQueryValueEx(hkey, "Left", NULL, &dwType, (BYTE*)&rect.x, &dwSize); + RegQueryValueEx(hkey, "Top", NULL, &dwType, (BYTE*)&rect.y, &dwSize); + RegQueryValueEx(hkey, "Width", NULL, &dwType, (BYTE*)&rect.width, &dwSize); + RegQueryValueEx(hkey, "Height", NULL, &dwType, (BYTE*)&rect.height, &dwSize); + + if( rect.x != (int)CW_USEDEFAULT && (rect.x < -200 || rect.x > 3000) ) + rect.x = 100; + if( rect.y != (int)CW_USEDEFAULT && (rect.y < -200 || rect.y > 3000) ) + rect.y = 100; + + if( rect.width != (int)CW_USEDEFAULT && (rect.width < 0 || rect.width > 3000) ) + rect.width = 100; + if( rect.height != (int)CW_USEDEFAULT && (rect.height < 0 || rect.height > 3000) ) + rect.height = 100; + + RegCloseKey(hkey); + } +} + + +// Window positions saving/loading added by Philip Gruebele. +//pgruebele@cox.net +// philipg. Saves the window position in the registry +static void +icvSaveWindowPos( const char* name, CvRect rect ) +{ + static const DWORD MAX_RECORD_COUNT = 100; + HKEY hkey; + char szKey[1024]; + char rootKey[1024]; + strcpy( szKey, icvWindowPosRootKey ); + strcat( szKey, name ); + + if( RegOpenKeyEx( HKEY_CURRENT_USER,szKey,0,KEY_READ,&hkey) != ERROR_SUCCESS ) + { + HKEY hroot; + DWORD count = 0; + FILETIME oldestTime = { UINT_MAX, UINT_MAX }; + char oldestKey[1024]; + char currentKey[1024]; + + strcpy( rootKey, icvWindowPosRootKey ); + rootKey[strlen(rootKey)-1] = '\0'; + if( RegCreateKeyEx(HKEY_CURRENT_USER, rootKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ+KEY_WRITE, 0, &hroot, NULL) != ERROR_SUCCESS ) + //RegOpenKeyEx( HKEY_CURRENT_USER,rootKey,0,KEY_READ,&hroot) != ERROR_SUCCESS ) + return; + + for(;;) + { + DWORD csize = sizeof(currentKey); + FILETIME accesstime = { 0, 0 }; + LONG code = RegEnumKeyEx( hroot, count, currentKey, &csize, NULL, NULL, NULL, &accesstime ); + if( code != ERROR_SUCCESS && code != ERROR_MORE_DATA ) + break; + count++; + if( oldestTime.dwHighDateTime > accesstime.dwHighDateTime || + (oldestTime.dwHighDateTime == accesstime.dwHighDateTime && + oldestTime.dwLowDateTime > accesstime.dwLowDateTime) ) + { + oldestTime = accesstime; + strcpy( oldestKey, currentKey ); + } + } + + if( count >= MAX_RECORD_COUNT ) + RegDeleteKey( hroot, oldestKey ); + RegCloseKey( hroot ); + + if( RegCreateKeyEx(HKEY_CURRENT_USER,szKey,0,NULL,REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkey, NULL) != ERROR_SUCCESS ) + return; + } + else + { + RegCloseKey( hkey ); + if( RegOpenKeyEx( HKEY_CURRENT_USER,szKey,0,KEY_WRITE,&hkey) != ERROR_SUCCESS ) + return; + } + + RegSetValueEx(hkey, "Left", 0, REG_DWORD, (BYTE*)&rect.x, sizeof(rect.x)); + RegSetValueEx(hkey, "Top", 0, REG_DWORD, (BYTE*)&rect.y, sizeof(rect.y)); + RegSetValueEx(hkey, "Width", 0, REG_DWORD, (BYTE*)&rect.width, sizeof(rect.width)); + RegSetValueEx(hkey, "Height", 0, REG_DWORD, (BYTE*)&rect.height, sizeof(rect.height)); + RegCloseKey(hkey); +} + +double cvGetModeWindow_W32(const char* name)//YV +{ + double result = -1; + + CV_FUNCNAME( "cvGetModeWindow_W32" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = window->status; + + __END__; + return result; +} + +void cvSetModeWindow_W32( const char* name, double prop_value)//Yannick Verdie +{ + CV_FUNCNAME( "cvSetModeWindow_W32" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set + EXIT; + + { + DWORD dwStyle = (DWORD)GetWindowLongPtr(window->frame, GWL_STYLE); + CvRect position; + + if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) + { + icvLoadWindowPos(window->name,position ); + SetWindowLongPtr(window->frame, GWL_STYLE, dwStyle | WS_CAPTION | WS_THICKFRAME); + + SetWindowPos(window->frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); + window->status=CV_WINDOW_NORMAL; + + EXIT; + } + + if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) + { + //save dimension + RECT rect; + GetWindowRect(window->frame, &rect); + CvRect RectCV = cvRect(rect.left, rect.top,rect.right - rect.left, rect.bottom - rect.top); + icvSaveWindowPos(window->name,RectCV ); + + //Look at coordinate for fullscreen + HMONITOR hMonitor; + MONITORINFO mi; + hMonitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); + + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + + //fullscreen + position.x=mi.rcMonitor.left;position.y=mi.rcMonitor.top; + position.width=mi.rcMonitor.right - mi.rcMonitor.left;position.height=mi.rcMonitor.bottom - mi.rcMonitor.top; + SetWindowLongPtr(window->frame, GWL_STYLE, dwStyle & ~WS_CAPTION & ~WS_THICKFRAME); + + SetWindowPos(window->frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); + window->status=CV_WINDOW_FULLSCREEN; + + EXIT; + } + } + + __END__; +} + +double cvGetPropWindowAutoSize_W32(const char* name) +{ + double result = -1; + + CV_FUNCNAME( "cvSetCloseCallback" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = window->flags & CV_WINDOW_AUTOSIZE; + + __END__; + + return result; +} + +double cvGetRatioWindow_W32(const char* name) +{ + double result = -1; + + CV_FUNCNAME( "cvGetRatioWindow_W32" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = static_cast(window->width) / window->height; + + __END__; + + return result; +} + +double cvGetOpenGlProp_W32(const char* name) +{ + double result = -1; + +#ifdef HAVE_OPENGL + CV_FUNCNAME( "cvGetOpenGlProp_W32" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + result = window->useGl; + + __END__; +#endif + (void)name; + + return result; +} + + +// OpenGL support + +#ifdef HAVE_OPENGL + +namespace +{ + void createGlContext(HWND hWnd, HDC& hGLDC, HGLRC& hGLRC, bool& useGl) + { + CV_FUNCNAME( "createGlContext" ); + + __BEGIN__; + + useGl = false; + + int PixelFormat; + + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 32, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 32, // 32 Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + hGLDC = GetDC(hWnd); + if (!hGLDC) + CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + + PixelFormat = ChoosePixelFormat(hGLDC, &pfd); + if (!PixelFormat) + CV_ERROR( CV_OpenGlApiCallError, "Can't Find A Suitable PixelFormat" ); + + if (!SetPixelFormat(hGLDC, PixelFormat, &pfd)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Set The PixelFormat" ); + + hGLRC = wglCreateContext(hGLDC); + if (!hGLRC) + CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Rendering Context" ); + + if (!wglMakeCurrent(hGLDC, hGLRC)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + useGl = true; + + __END__; + } + + void releaseGlContext(CvWindow* window) + { + //CV_FUNCNAME( "releaseGlContext" ); + + __BEGIN__; + + if (window->hGLRC) + { + wglDeleteContext(window->hGLRC); + window->hGLRC = NULL; + } + + if (window->dc) + { + ReleaseDC(window->hwnd, window->dc); + window->dc = NULL; + } + + window->useGl = false; + + __END__; + } + + void drawGl(CvWindow* window) + { + CV_FUNCNAME( "drawGl" ); + + __BEGIN__; + + if (!wglMakeCurrent(window->dc, window->hGLRC)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (window->glDrawCallback) + window->glDrawCallback(window->glDrawData); + + if (!SwapBuffers(window->dc)) + CV_ERROR( CV_OpenGlApiCallError, "Can't swap OpenGL buffers" ); + + __END__; + } + + void resizeGl(CvWindow* window) + { + CV_FUNCNAME( "resizeGl" ); + + __BEGIN__; + + if (!wglMakeCurrent(window->dc, window->hGLRC)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + glViewport(0, 0, window->width, window->height); + + __END__; + } +} + +#endif // HAVE_OPENGL + + +CV_IMPL int cvNamedWindow( const char* name, int flags ) +{ + int result = 0; + CV_FUNCNAME( "cvNamedWindow" ); + + __BEGIN__; + + HWND hWnd, mainhWnd; + CvWindow* window; + DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; + int len; + CvRect rect; +#ifdef HAVE_OPENGL + bool useGl; + HDC hGLDC; + HGLRC hGLRC; +#endif + + cvInitSystem(0,0); + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + // Check the name in the storage + window = icvFindWindowByName( name ); + if (window != 0) + { + result = 1; + EXIT; + } + + if( !(flags & CV_WINDOW_AUTOSIZE))//YV add border in order to resize the window + defStyle |= WS_SIZEBOX; + + icvLoadWindowPos( name, rect ); + + mainhWnd = CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED, + rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0 ); + if( !mainhWnd ) + CV_ERROR( CV_StsError, "Frame window can not be created" ); + + ShowWindow(mainhWnd, SW_SHOW); + + //YV- remove one border by changing the style + hWnd = CreateWindow("HighGUI class", "", (defStyle & ~WS_SIZEBOX) | WS_CHILD, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd, 0, hg_hinstance, 0); + if( !hWnd ) + CV_ERROR( CV_StsError, "Frame window can not be created" ); + +#ifndef HAVE_OPENGL + if (flags & CV_WINDOW_OPENGL) + CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); +#else + useGl = false; + hGLDC = 0; + hGLRC = 0; + + if (flags & CV_WINDOW_OPENGL) + createGlContext(hWnd, hGLDC, hGLRC, useGl); +#endif + + ShowWindow(hWnd, SW_SHOW); + + len = (int)strlen(name); + CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); + + window->signature = CV_WINDOW_MAGIC_VAL; + window->hwnd = hWnd; + window->frame = mainhWnd; + window->name = (char*)(window + 1); + memcpy( window->name, name, len + 1 ); + window->flags = flags; + window->image = 0; + +#ifndef HAVE_OPENGL + window->dc = CreateCompatibleDC(0); +#else + if (!useGl) + { + window->dc = CreateCompatibleDC(0); + window->hGLRC = 0; + window->useGl = false; + } + else + { + window->dc = hGLDC; + window->hGLRC = hGLRC; + window->useGl = true; + } + + window->glDrawCallback = 0; + window->glDrawData = 0; +#endif + + window->last_key = 0; + window->status = CV_WINDOW_NORMAL;//YV + + window->on_mouse = 0; + window->on_mouse_param = 0; + + memset( &window->toolbar, 0, sizeof(window->toolbar)); + + window->next = hg_windows; + window->prev = 0; + if( hg_windows ) + hg_windows->prev = window; + hg_windows = window; + icvSetWindowLongPtr( hWnd, CV_USERDATA, window ); + icvSetWindowLongPtr( mainhWnd, CV_USERDATA, window ); + + // Recalculate window pos + icvUpdateWindowPos( window ); + + result = 1; + __END__; + + return result; +} + +#ifdef HAVE_OPENGL + +CV_IMPL void cvSetOpenGlContext(const char* name) +{ + CV_FUNCNAME( "cvSetOpenGlContext" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + if (!window->useGl) + CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + + if (!wglMakeCurrent(window->dc, window->hGLRC)) + CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + + __END__; +} + +CV_IMPL void cvUpdateWindow(const char* name) +{ + CV_FUNCNAME( "cvUpdateWindow" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if (!window) + EXIT; + + InvalidateRect(window->hwnd, 0, 0); + + __END__; +} + +CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata) +{ + CV_FUNCNAME( "cvCreateOpenGLCallback" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + EXIT; + + if (!window->useGl) + CV_ERROR( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + + window->glDrawCallback = callback; + window->glDrawData = userdata; + + __END__; +} + +#endif // HAVE_OPENGL + +static void icvRemoveWindow( CvWindow* window ) +{ + CvTrackbar* trackbar = NULL; + RECT wrect={0,0,0,0}; + +#ifdef HAVE_OPENGL + if (window->useGl) + releaseGlContext(window); +#endif + + if( window->frame ) + GetWindowRect( window->frame, &wrect ); + if( window->name ) + icvSaveWindowPos( window->name, cvRect(wrect.left, wrect.top, + wrect.right-wrect.left, wrect.bottom-wrect.top) ); + + if( window->hwnd ) + icvSetWindowLongPtr( window->hwnd, CV_USERDATA, 0 ); + if( window->frame ) + icvSetWindowLongPtr( window->frame, CV_USERDATA, 0 ); + + if( window->toolbar.toolbar ) + icvSetWindowLongPtr(window->toolbar.toolbar, CV_USERDATA, 0); + + if( window->prev ) + window->prev->next = window->next; + else + hg_windows = window->next; + + if( window->next ) + window->next->prev = window->prev; + + window->prev = window->next = 0; + + if( window->dc && window->image ) + DeleteObject(SelectObject(window->dc,window->image)); + + if( window->dc ) + DeleteDC(window->dc); + + for( trackbar = window->toolbar.first; trackbar != 0; ) + { + CvTrackbar* next = trackbar->next; + if( trackbar->hwnd ) + { + icvSetWindowLongPtr( trackbar->hwnd, CV_USERDATA, 0 ); + cvFree( &trackbar ); + } + trackbar = next; + } + + cvFree( &window ); +} + + +CV_IMPL void cvDestroyWindow( const char* name ) +{ + CV_FUNCNAME( "cvDestroyWindow" ); + + __BEGIN__; + + CvWindow* window; + HWND mainhWnd; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + EXIT; + + mainhWnd = window->frame; + + SendMessage(window->hwnd, WM_CLOSE, 0, 0); + SendMessage( mainhWnd, WM_CLOSE, 0, 0); + // Do NOT call _remove_window -- CvWindow list will be updated automatically ... + + __END__; +} + + +static void icvScreenToClient( HWND hwnd, RECT* rect ) +{ + POINT p; + p.x = rect->left; + p.y = rect->top; + ScreenToClient(hwnd, &p); + OffsetRect( rect, p.x - rect->left, p.y - rect->top ); +} + + +/* Calculatess the window coordinates relative to the upper left corner of the mainhWnd window */ +static RECT icvCalcWindowRect( CvWindow* window ) +{ + const int gutter = 1; + RECT crect, trect, rect; + + assert(window); + + GetClientRect(window->frame, &crect); + if(window->toolbar.toolbar) + { + GetWindowRect(window->toolbar.toolbar, &trect); + icvScreenToClient(window->frame, &trect); + SubtractRect( &rect, &crect, &trect); + } + else + rect = crect; + + rect.top += gutter; + rect.left += gutter; + rect.bottom -= gutter; + rect.right -= gutter; + + return rect; +} + +// returns TRUE if there is a problem such as ERROR_IO_PENDING. +static bool icvGetBitmapData( CvWindow* window, SIZE* size, int* channels, void** data ) +{ + BITMAP bmp; + GdiFlush(); + HGDIOBJ h = GetCurrentObject( window->dc, OBJ_BITMAP ); + if( size ) + size->cx = size->cy = 0; + if( data ) + *data = 0; + + if (h == NULL) + return true; + if (GetObject(h, sizeof(bmp), &bmp) == 0) + return true; + + if( size ) + { + size->cx = abs(bmp.bmWidth); + size->cy = abs(bmp.bmHeight); + } + + if( channels ) + *channels = bmp.bmBitsPixel/8; + + if( data ) + *data = bmp.bmBits; + + return false; +} + + +static void icvUpdateWindowPos( CvWindow* window ) +{ + RECT rect; + assert(window); + + if( (window->flags & CV_WINDOW_AUTOSIZE) && window->image ) + { + int i; + SIZE size = {0,0}; + icvGetBitmapData( window, &size, 0, 0 ); + + // Repeat two times because after the first resizing of the mainhWnd window + // toolbar may resize too + for(i = 0; i < (window->toolbar.toolbar ? 2 : 1); i++) + { + RECT rmw, rw = icvCalcWindowRect(window ); + MoveWindow(window->hwnd, rw.left, rw.top, + rw.right - rw.left + 1, rw.bottom - rw.top + 1, FALSE); + GetClientRect(window->hwnd, &rw); + GetWindowRect(window->frame, &rmw); + // Resize the mainhWnd window in order to make the bitmap fit into the child window + MoveWindow(window->frame, rmw.left, rmw.top, + rmw.right - rmw.left + size.cx - rw.right + rw.left, + rmw.bottom - rmw.top + size.cy - rw.bottom + rw.top, TRUE ); + } + } + + rect = icvCalcWindowRect(window); + MoveWindow(window->hwnd, rect.left, rect.top, + rect.right - rect.left + 1, + rect.bottom - rect.top + 1, TRUE ); +} + +CV_IMPL void +cvShowImage( const char* name, const CvArr* arr ) +{ + CV_FUNCNAME( "cvShowImage" ); + + __BEGIN__; + + CvWindow* window; + SIZE size = { 0, 0 }; + int channels = 0; + void* dst_ptr = 0; + const int channels0 = 3; + int origin = 0; + CvMat stub, dst, *image; + bool changed_size = false; // philipg + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + { + #ifndef HAVE_OPENGL + cvNamedWindow(name, CV_WINDOW_AUTOSIZE); + #else + cvNamedWindow(name, CV_WINDOW_AUTOSIZE | CV_WINDOW_OPENGL); + #endif + + window = icvFindWindowByName(name); + } + + if( !window || !arr ) + EXIT; // keep silence here. + + if( CV_IS_IMAGE_HDR( arr )) + origin = ((IplImage*)arr)->origin; + + CV_CALL( image = cvGetMat( arr, &stub )); + +#ifdef HAVE_OPENGL + if (window->useGl) + { + cv::Mat im(image); + cv::imshow(name, im); + return; + } +#endif + + if (window->image) + // if there is something wrong with these system calls, we cannot display image... + if (icvGetBitmapData( window, &size, &channels, &dst_ptr )) + return; + + if( size.cx != image->width || size.cy != image->height || channels != channels0 ) + { + changed_size = true; + + uchar buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)]; + BITMAPINFO* binfo = (BITMAPINFO*)buffer; + + DeleteObject( SelectObject( window->dc, window->image )); + window->image = 0; + + size.cx = image->width; + size.cy = image->height; + channels = channels0; + + FillBitmapInfo( binfo, size.cx, size.cy, channels*8, 1 ); + + window->image = SelectObject( window->dc, CreateDIBSection(window->dc, binfo, + DIB_RGB_COLORS, &dst_ptr, 0, 0)); + } + + cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3, + dst_ptr, (size.cx * channels + 3) & -4 ); + cvConvertImage( image, &dst, origin == 0 ? CV_CVTIMG_FLIP : 0 ); + + // ony resize window if needed + if (changed_size) + icvUpdateWindowPos(window); + InvalidateRect(window->hwnd, 0, 0); + // philipg: this is not needed and just slows things down +// UpdateWindow(window->hwnd); + + __END__; +} + +#if 0 +CV_IMPL void +cvShowImageHWND(HWND w_hWnd, const CvArr* arr) +{ + CV_FUNCNAME( "cvShowImageHWND" ); + + __BEGIN__; + + SIZE size = { 0, 0 }; + int channels = 0; + void* dst_ptr = 0; + const int channels0 = 3; + int origin = 0; + CvMat stub, dst, *image; + bool changed_size = false; + BITMAPINFO tempbinfo; + HDC hdc = NULL; + + if( !arr ) + EXIT; + if( !w_hWnd ) + EXIT; + + hdc = GetDC(w_hWnd); + + if( CV_IS_IMAGE_HDR( arr ) ) + origin = ((IplImage*)arr)->origin; + + CV_CALL( image = cvGetMat( arr, &stub ) ); + + if ( hdc ) + { + //GetBitmapData + BITMAP bmp; + GdiFlush(); + HGDIOBJ h = GetCurrentObject( hdc, OBJ_BITMAP ); + + if (h == NULL) + EXIT; + if (GetObject(h, sizeof(bmp), &bmp) == 0) //GetObject(): returns size of object, 0 if error + EXIT; + + channels = bmp.bmBitsPixel/8; + dst_ptr = bmp.bmBits; + } + + if( size.cx != image->width || size.cy != image->height || channels != channels0 ) + { + changed_size = true; + + uchar buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)]; + BITMAPINFO* binfo = (BITMAPINFO*)buffer; + + BOOL bDeleteObj = DeleteObject(GetCurrentObject(hdc, OBJ_BITMAP)); + CV_Assert( FALSE != bDeleteObj ); + + size.cx = image->width; + size.cy = image->height; + channels = channels0; + + FillBitmapInfo( binfo, size.cx, size.cy, channels*8, 1 ); + + SelectObject( hdc, CreateDIBSection( hdc, binfo, DIB_RGB_COLORS, &dst_ptr, 0, 0)); + } + + cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx * channels + 3) & -4 ); + cvConvertImage( image, &dst, origin == 0 ? CV_CVTIMG_FLIP : 0 ); + + // Image stretching to fit the window + RECT rect; + GetClientRect(w_hWnd, &rect); + StretchDIBits( hdc, 0, 0, rect.right, rect.bottom, 0, 0, image->width, image->height, dst_ptr, &tempbinfo, DIB_RGB_COLORS, SRCCOPY ); + + // ony resize window if needed + InvalidateRect(w_hWnd, 0, 0); + + __END__; +} +#endif + +CV_IMPL void cvResizeWindow(const char* name, int width, int height ) +{ + CV_FUNCNAME( "cvResizeWindow" ); + + __BEGIN__; + + int i; + CvWindow* window; + RECT rmw, rw, rect; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + // Repeat two times because after the first resizing of the mainhWnd window + // toolbar may resize too + for(i = 0; i < (window->toolbar.toolbar ? 2 : 1); i++) + { + rw = icvCalcWindowRect(window); + MoveWindow(window->hwnd, rw.left, rw.top, + rw.right - rw.left + 1, rw.bottom - rw.top + 1, FALSE); + GetClientRect(window->hwnd, &rw); + GetWindowRect(window->frame, &rmw); + // Resize the mainhWnd window in order to make the bitmap fit into the child window + MoveWindow(window->frame, rmw.left, rmw.top, + rmw.right - rmw.left + width - rw.right + rw.left, + rmw.bottom - rmw.top + height - rw.bottom + rw.top, TRUE); + } + + rect = icvCalcWindowRect(window); + MoveWindow(window->hwnd, rect.left, rect.top, + rect.right - rect.left + 1, rect.bottom - rect.top + 1, TRUE); + + __END__; +} + + +CV_IMPL void cvMoveWindow( const char* name, int x, int y ) +{ + CV_FUNCNAME( "cvMoveWindow" ); + + __BEGIN__; + + CvWindow* window; + RECT rect; + + if( !name ) + CV_ERROR( CV_StsNullPtr, "NULL name" ); + + window = icvFindWindowByName(name); + if(!window) + EXIT; + + GetWindowRect( window->frame, &rect ); + MoveWindow( window->frame, x, y, rect.right - rect.left, rect.bottom - rect.top, TRUE); + + __END__; +} + + +static LRESULT CALLBACK +MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + CvWindow* window = icvWindowByHWND( hwnd ); + if( !window ) + return DefWindowProc(hwnd, uMsg, wParam, lParam); + + switch(uMsg) + { + case WM_DESTROY: + + icvRemoveWindow(window); + // Do nothing!!! + //PostQuitMessage(0); + break; + + case WM_GETMINMAXINFO: + if( !(window->flags & CV_WINDOW_AUTOSIZE) ) + { + MINMAXINFO* minmax = (MINMAXINFO*)lParam; + RECT rect; + LRESULT retval = DefWindowProc(hwnd, uMsg, wParam, lParam); + + minmax->ptMinTrackSize.y = 100; + minmax->ptMinTrackSize.x = 100; + + if( window->toolbar.first ) + { + GetWindowRect( window->toolbar.first->hwnd, &rect ); + minmax->ptMinTrackSize.y += window->toolbar.rows*(rect.bottom - rect.top); + minmax->ptMinTrackSize.x = MAX(rect.right - rect.left + HG_BUDDY_WIDTH, HG_BUDDY_WIDTH*2); + } + return retval; + } + break; + + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS* pos = (WINDOWPOS*)lParam; + + // Update the toolbar pos/size + if(window->toolbar.toolbar) + { + RECT rect; + GetWindowRect(window->toolbar.toolbar, &rect); + MoveWindow(window->toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE); + } + + if(!(window->flags & CV_WINDOW_AUTOSIZE)) + icvUpdateWindowPos(window); + + break; + } + + case WM_WINDOWPOSCHANGING: + { + // Snap window to screen edges with multi-monitor support. // Adi Shavit + LPWINDOWPOS pos = (LPWINDOWPOS)lParam; + + RECT rect; + GetWindowRect(window->frame, &rect); + + HMONITOR hMonitor; + hMonitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + + const int SNAP_DISTANCE = 15; + + if (abs(pos->x - mi.rcMonitor.left) <= SNAP_DISTANCE) + pos->x = mi.rcMonitor.left; // snap to left edge + else + if (abs(pos->x + pos->cx - mi.rcMonitor.right) <= SNAP_DISTANCE) + pos->x = mi.rcMonitor.right - pos->cx; // snap to right edge + + if (abs(pos->y - mi.rcMonitor.top) <= SNAP_DISTANCE) + pos->y = mi.rcMonitor.top; // snap to top edge + else + if (abs(pos->y + pos->cy - mi.rcMonitor.bottom) <= SNAP_DISTANCE) + pos->y = mi.rcMonitor.bottom - pos->cy; // snap to bottom edge + } + + case WM_ACTIVATE: + if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) + SetFocus(window->hwnd); + break; + + case WM_ERASEBKGND: + { + RECT cr, tr, wrc; + HRGN rgn, rgn1, rgn2; + int ret; + HDC hdc = (HDC)wParam; + GetWindowRect(window->hwnd, &cr); + icvScreenToClient(window->frame, &cr); + if(window->toolbar.toolbar) + { + GetWindowRect(window->toolbar.toolbar, &tr); + icvScreenToClient(window->frame, &tr); + } + else + tr.left = tr.top = tr.right = tr.bottom = 0; + + GetClientRect(window->frame, &wrc); + + rgn = CreateRectRgn(0, 0, wrc.right, wrc.bottom); + rgn1 = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom); + rgn2 = CreateRectRgn(tr.left, tr.top, tr.right, tr.bottom); + ret = CombineRgn(rgn, rgn, rgn1, RGN_DIFF); + ret = CombineRgn(rgn, rgn, rgn2, RGN_DIFF); + + if(ret != NULLREGION && ret != ERROR) + FillRgn(hdc, rgn, (HBRUSH)icvGetClassLongPtr(hwnd, CV_HBRBACKGROUND)); + + DeleteObject(rgn); + DeleteObject(rgn1); + DeleteObject(rgn2); + } + return 1; + } + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + +static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + CvWindow* window = icvWindowByHWND(hwnd); + if( !window ) + // This window is not mentioned in HighGUI storage + // Actually, this should be error except for the case of calls to CreateWindow + return DefWindowProc(hwnd, uMsg, wParam, lParam); + + // Process the message + switch(uMsg) + { + case WM_WINDOWPOSCHANGING: + { + LPWINDOWPOS pos = (LPWINDOWPOS)lParam; + RECT rect = icvCalcWindowRect(window); + pos->x = rect.left; + pos->y = rect.top; + pos->cx = rect.right - rect.left + 1; + pos->cy = rect.bottom - rect.top + 1; + } + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_MOUSEMOVE: + if( window->on_mouse ) + { + POINT pt; + RECT rect; + SIZE size = {0,0}; + + int flags = (wParam & MK_LBUTTON ? CV_EVENT_FLAG_LBUTTON : 0)| + (wParam & MK_RBUTTON ? CV_EVENT_FLAG_RBUTTON : 0)| + (wParam & MK_MBUTTON ? CV_EVENT_FLAG_MBUTTON : 0)| + (wParam & MK_CONTROL ? CV_EVENT_FLAG_CTRLKEY : 0)| + (wParam & MK_SHIFT ? CV_EVENT_FLAG_SHIFTKEY : 0)| + (GetKeyState(VK_MENU) < 0 ? CV_EVENT_FLAG_ALTKEY : 0); + int event = uMsg == WM_LBUTTONDOWN ? CV_EVENT_LBUTTONDOWN : + uMsg == WM_RBUTTONDOWN ? CV_EVENT_RBUTTONDOWN : + uMsg == WM_MBUTTONDOWN ? CV_EVENT_MBUTTONDOWN : + uMsg == WM_LBUTTONUP ? CV_EVENT_LBUTTONUP : + uMsg == WM_RBUTTONUP ? CV_EVENT_RBUTTONUP : + uMsg == WM_MBUTTONUP ? CV_EVENT_MBUTTONUP : + uMsg == WM_LBUTTONDBLCLK ? CV_EVENT_LBUTTONDBLCLK : + uMsg == WM_RBUTTONDBLCLK ? CV_EVENT_RBUTTONDBLCLK : + uMsg == WM_MBUTTONDBLCLK ? CV_EVENT_MBUTTONDBLCLK : + CV_EVENT_MOUSEMOVE; + if( uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN ) + SetCapture( hwnd ); + if( uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP ) + ReleaseCapture(); + + pt.x = LOWORD( lParam ); + pt.y = HIWORD( lParam ); + + GetClientRect( window->hwnd, &rect ); + icvGetBitmapData( window, &size, 0, 0 ); + + window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1), + pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags, + window->on_mouse_param ); + } + break; + + case WM_PAINT: + if(window->image != 0) + { + int nchannels = 3; + SIZE size = {0,0}; + PAINTSTRUCT paint; + HDC hdc; + RGBQUAD table[256]; + + // Determine the bitmap's dimensions + icvGetBitmapData( window, &size, &nchannels, 0 ); + + hdc = BeginPaint(hwnd, &paint); + SetStretchBltMode(hdc, COLORONCOLOR); + + if( nchannels == 1 ) + { + int i; + for(i = 0; i < 256; i++) + { + table[i].rgbBlue = (unsigned char)i; + table[i].rgbGreen = (unsigned char)i; + table[i].rgbRed = (unsigned char)i; + } + SetDIBColorTable(window->dc, 0, 255, table); + } + + if(window->flags & CV_WINDOW_AUTOSIZE) + { + BitBlt( hdc, 0, 0, size.cx, size.cy, window->dc, 0, 0, SRCCOPY ); + } + else + { + RECT rect; + GetClientRect(window->hwnd, &rect); + StretchBlt( hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, + window->dc, 0, 0, size.cx, size.cy, SRCCOPY ); + } + //DeleteDC(hdc); + EndPaint(hwnd, &paint); + } +#ifdef HAVE_OPENGL + else if(window->useGl) + { + drawGl(window); + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } +#endif + else + { + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; + + case WM_ERASEBKGND: + if(window->image) + return 0; + break; + + case WM_DESTROY: + + icvRemoveWindow(window); + // Do nothing!!! + //PostQuitMessage(0); + break; + + case WM_SETCURSOR: + SetCursor((HCURSOR)icvGetClassLongPtr(hwnd, CV_HCURSOR)); + return 0; + + case WM_KEYDOWN: + window->last_key = (int)wParam; + return 0; + + case WM_SIZE: + window->width = LOWORD(lParam); + window->height = HIWORD(lParam); + +#ifdef HAVE_OPENGL + if (window->useGl) + resizeGl(window); +#endif + } + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + +static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT ret; + + if( hg_on_preprocess ) + { + int was_processed = 0; + int rethg = hg_on_preprocess(hwnd, uMsg, wParam, lParam, &was_processed); + if( was_processed ) + return rethg; + } + ret = HighGUIProc(hwnd, uMsg, wParam, lParam); + + if(hg_on_postprocess) + { + int was_processed = 0; + int rethg = hg_on_postprocess(hwnd, uMsg, wParam, lParam, &was_processed); + if( was_processed ) + return rethg; + } + + return ret; +} + + +static void icvUpdateTrackbar( CvTrackbar* trackbar, int pos ) +{ + const int max_name_len = 10; + const char* suffix = ""; + char pos_text[32]; + int name_len; + + if( trackbar->data ) + *trackbar->data = pos; + + if( trackbar->pos != pos ) + { + trackbar->pos = pos; + if( trackbar->notify2 ) + trackbar->notify2(pos, trackbar->userdata); + if( trackbar->notify ) + trackbar->notify(pos); + + name_len = (int)strlen(trackbar->name); + + if( name_len > max_name_len ) + { + int start_len = max_name_len*2/3; + int end_len = max_name_len - start_len - 2; + memcpy( pos_text, trackbar->name, start_len ); + memcpy( pos_text + start_len, "...", 3 ); + memcpy( pos_text + start_len + 3, trackbar->name + name_len - end_len, end_len + 1 ); + } + else + { + memcpy( pos_text, trackbar->name, name_len + 1); + } + + sprintf( pos_text + strlen(pos_text), "%s: %d\n", suffix, pos ); + SetWindowText( trackbar->buddy, pos_text ); + } +} + + +static LRESULT CALLBACK HGToolbarProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + CvWindow* window = icvWindowByHWND( hwnd ); + if(!window) + return DefWindowProc(hwnd, uMsg, wParam, lParam); + + // Control messages processing + switch(uMsg) + { + // Slider processing + case WM_HSCROLL: + { + HWND slider = (HWND)lParam; + int pos = (int)SendMessage(slider, TBM_GETPOS, 0, 0); + CvTrackbar* trackbar = icvTrackbarByHWND( slider ); + + if( trackbar ) + { + if( trackbar->pos != pos ) + icvUpdateTrackbar( trackbar, pos ); + } + + SetFocus( window->hwnd ); + return 0; + } + + case WM_NCCALCSIZE: + { + LRESULT ret = CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); + int rows = (int)SendMessage(hwnd, TB_GETROWS, 0, 0); + + if(window->toolbar.rows != rows) + { + SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + CvTrackbar* trackbar = window->toolbar.first; + + for( ; trackbar != 0; trackbar = trackbar->next ) + { + RECT rect; + SendMessage(window->toolbar.toolbar, TB_GETITEMRECT, + (WPARAM)trackbar->id, (LPARAM)&rect); + MoveWindow(trackbar->hwnd, rect.left + HG_BUDDY_WIDTH, rect.top, + rect.right - rect.left - HG_BUDDY_WIDTH, + rect.bottom - rect.top, FALSE); + MoveWindow(trackbar->buddy, rect.left, rect.top, + HG_BUDDY_WIDTH, rect.bottom - rect.top, FALSE); + } + window->toolbar.rows = rows; + } + return ret; + } + } + + return CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); +} + + +CV_IMPL void +cvDestroyAllWindows(void) +{ + CvWindow* window = hg_windows; + + while( window ) + { + HWND mainhWnd = window->frame; + HWND hwnd = window->hwnd; + window = window->next; + + SendMessage( hwnd, WM_CLOSE, 0, 0 ); + SendMessage( mainhWnd, WM_CLOSE, 0, 0 ); + } +} + + +CV_IMPL int +cvWaitKey( int delay ) +{ + int time0 = GetTickCount(); + + for(;;) + { + CvWindow* window; + MSG message; + int is_processed = 0; + + if( (delay > 0 && abs((int)(GetTickCount() - time0)) >= delay) || hg_windows == 0 ) + return -1; + + if( delay <= 0 ) + GetMessage(&message, 0, 0, 0); + else if( PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE ) + { + Sleep(1); + continue; + } + + for( window = hg_windows; window != 0 && is_processed == 0; window = window->next ) + { + if( window->hwnd == message.hwnd || window->frame == message.hwnd ) + { + is_processed = 1; + switch(message.message) + { + case WM_DESTROY: + case WM_CHAR: + DispatchMessage(&message); + return (int)message.wParam; + + case WM_SYSKEYDOWN: + if( message.wParam == VK_F10 ) + { + is_processed = 1; + return (int)(message.wParam << 16); + } + break; + + case WM_KEYDOWN: + TranslateMessage(&message); + if( (message.wParam >= VK_F1 && message.wParam <= VK_F24) || + message.wParam == VK_HOME || message.wParam == VK_END || + message.wParam == VK_UP || message.wParam == VK_DOWN || + message.wParam == VK_LEFT || message.wParam == VK_RIGHT || + message.wParam == VK_INSERT || message.wParam == VK_DELETE || + message.wParam == VK_PRIOR || message.wParam == VK_NEXT ) + { + DispatchMessage(&message); + is_processed = 1; + return (int)(message.wParam << 16); + } + default: + DispatchMessage(&message); + is_processed = 1; + break; + } + } + } + + if( !is_processed ) + { + TranslateMessage(&message); + DispatchMessage(&message); + } + } +} + + +static CvTrackbar* +icvFindTrackbarByName( const CvWindow* window, const char* name ) +{ + CvTrackbar* trackbar = window->toolbar.first; + + for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next ) + ; + + return trackbar; +} + + +typedef struct +{ + UINT cbSize; + DWORD dwMask; + int idCommand; + int iImage; + BYTE fsState; + BYTE fsStyle; + WORD cx; + DWORD lParam; + LPSTR pszText; + int cchText; +} +ButtonInfo; + + +static int +icvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify, + CvTrackbarCallback2 on_notify2, void* userdata ) +{ + int result = 0; + + CV_FUNCNAME( "icvCreateTrackbar" ); + + __BEGIN__; + + char slider_name[32]; + CvWindow* window = 0; + CvTrackbar* trackbar = 0; + int pos = 0; + + if( !window_name || !trackbar_name ) + CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" ); + + if( count <= 0 ) + CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + + window = icvFindWindowByName(window_name); + if( !window ) + EXIT; + + trackbar = icvFindTrackbarByName(window,trackbar_name); + if( !trackbar ) + { + TBBUTTON tbs; + ButtonInfo tbis; + RECT rect; + int bcount; + int len = (int)strlen( trackbar_name ); + + // create toolbar if it is not created yet + if( !window->toolbar.toolbar ) + { + const int default_height = 30; + + window->toolbar.toolbar = CreateToolbarEx( + window->frame, WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE, + 1, 0, 0, 0, 0, 0, 16, 20, 16, 16, sizeof(TBBUTTON)); + GetClientRect(window->frame, &rect); + MoveWindow( window->toolbar.toolbar, 0, 0, + rect.right - rect.left, default_height, TRUE); + SendMessage(window->toolbar.toolbar, TB_AUTOSIZE, 0, 0); + ShowWindow(window->toolbar.toolbar, SW_SHOW); + + window->toolbar.first = 0; + window->toolbar.pos = 0; + window->toolbar.rows = 0; + window->toolbar.toolBarProc = + (WNDPROC)icvGetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC); + + icvUpdateWindowPos(window); + + // Subclassing from toolbar + icvSetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC, HGToolbarProc); + icvSetWindowLongPtr(window->toolbar.toolbar, CV_USERDATA, window); + } + + /* Retrieve current buttons count */ + bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + + if(bcount > 1) + { + /* If this is not the first button then we need to + separate it from the previous one */ + tbs.iBitmap = 0; + tbs.idCommand = bcount; // Set button id to it's number + tbs.iString = 0; + tbs.fsStyle = TBSTYLE_SEP; + tbs.fsState = TBSTATE_ENABLED; + SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); + + // Retrieve current buttons count + bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + } + + /* Add a button which we're going to cover with the slider */ + tbs.iBitmap = 0; + tbs.idCommand = bcount; // Set button id to it's number + tbs.fsState = TBSTATE_ENABLED; +#if 0/*!defined WIN64 && !defined EM64T*/ + tbs.fsStyle = 0; + tbs.iString = 0; +#else + +#ifndef TBSTYLE_AUTOSIZE +#define TBSTYLE_AUTOSIZE 0x0010 +#endif + +#ifndef TBSTYLE_GROUP +#define TBSTYLE_GROUP 0x0004 +#endif + //tbs.fsStyle = TBSTYLE_AUTOSIZE; + tbs.fsStyle = TBSTYLE_GROUP; + tbs.iString = (INT_PTR)trackbar_text; +#endif + SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); + + /* Adjust button size to the slider */ + tbis.cbSize = sizeof(tbis); + tbis.dwMask = TBIF_SIZE; + + GetClientRect(window->hwnd, &rect); + tbis.cx = (unsigned short)(rect.right - rect.left); + + SendMessage(window->toolbar.toolbar, TB_SETBUTTONINFO, + (WPARAM)tbs.idCommand, (LPARAM)&tbis); + + /* Get button pos */ + SendMessage(window->toolbar.toolbar, TB_GETITEMRECT, + (WPARAM)tbs.idCommand, (LPARAM)&rect); + + /* Create a slider */ + trackbar = (CvTrackbar*)cvAlloc( sizeof(CvTrackbar) + len + 1 ); + trackbar->signature = CV_TRACKBAR_MAGIC_VAL; + trackbar->notify = 0; + trackbar->notify2 = 0; + trackbar->parent = window; + trackbar->pos = 0; + trackbar->data = 0; + trackbar->id = bcount; + trackbar->next = window->toolbar.first; + trackbar->name = (char*)(trackbar + 1); + memcpy( trackbar->name, trackbar_name, len + 1 ); + window->toolbar.first = trackbar; + + sprintf(slider_name, "Trackbar%p", val); + trackbar->hwnd = CreateWindowEx(0, TRACKBAR_CLASS, slider_name, + WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS | + TBS_FIXEDLENGTH | TBS_HORZ | TBS_BOTTOM, + rect.left + HG_BUDDY_WIDTH, rect.top, + rect.right - rect.left - HG_BUDDY_WIDTH, + rect.bottom - rect.top, window->toolbar.toolbar, + (HMENU)(size_t)bcount, hg_hinstance, 0); + + sprintf(slider_name,"Buddy%p", val); + trackbar->buddy = CreateWindowEx(0, "STATIC", slider_name, + WS_CHILD | SS_RIGHT, + rect.left, rect.top, + HG_BUDDY_WIDTH, rect.bottom - rect.top, + window->toolbar.toolbar, 0, hg_hinstance, 0); + + icvSetWindowLongPtr( trackbar->hwnd, CV_USERDATA, trackbar ); + + /* Minimize the number of rows */ + SendMessage( window->toolbar.toolbar, TB_SETROWS, + MAKEWPARAM(1, FALSE), (LPARAM)&rect ); + } + else + { + trackbar->data = 0; + trackbar->notify = 0; + trackbar->notify2 = 0; + } + + trackbar->maxval = count; + + /* Adjust slider parameters */ + SendMessage(trackbar->hwnd, TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)0); + SendMessage(trackbar->hwnd, TBM_SETRANGEMAX, (WPARAM)TRUE, (LPARAM)count); + SendMessage(trackbar->hwnd, TBM_SETTICFREQ, (WPARAM)1, (LPARAM)0 ); + if( val ) + pos = *val; + + SendMessage(trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos ); + SendMessage(window->toolbar.toolbar, TB_AUTOSIZE, 0, 0); + + trackbar->pos = -1; + icvUpdateTrackbar( trackbar, pos ); + ShowWindow( trackbar->buddy, SW_SHOW ); + ShowWindow( trackbar->hwnd, SW_SHOW ); + + trackbar->notify = on_notify; + trackbar->notify2 = on_notify2; + trackbar->userdata = userdata; + trackbar->data = val; + + /* Resize the window to reflect the toolbar resizing*/ + icvUpdateWindowPos(window); + + result = 1; + + __END__; + + return result; +} + +CV_IMPL int +cvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify ) +{ + return icvCreateTrackbar( trackbar_name, window_name, val, count, + on_notify, 0, 0 ); +} + +CV_IMPL int +cvCreateTrackbar2( const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback2 on_notify2, + void* userdata ) +{ + return icvCreateTrackbar( trackbar_name, window_name, val, count, + 0, on_notify2, userdata ); +} + +CV_IMPL void +cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) +{ + CV_FUNCNAME( "cvSetMouseCallback" ); + + __BEGIN__; + + CvWindow* window = 0; + + if( !window_name ) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + window = icvFindWindowByName(window_name); + if( !window ) + EXIT; + + window->on_mouse = on_mouse; + window->on_mouse_param = param; + + __END__; +} + + +CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) +{ + int pos = -1; + + CV_FUNCNAME( "cvGetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + pos = trackbar->pos; + + __END__; + + return pos; +} + + +CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) +{ + CV_FUNCNAME( "cvSetTrackbarPos" ); + + __BEGIN__; + + CvWindow* window; + CvTrackbar* trackbar = 0; + + if( trackbar_name == 0 || window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + trackbar = icvFindTrackbarByName( window, trackbar_name ); + + if( trackbar ) + { + if( pos < 0 ) + pos = 0; + + if( pos > trackbar->maxval ) + pos = trackbar->maxval; + + SendMessage( trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos ); + icvUpdateTrackbar( trackbar, pos ); + } + + __END__; +} + + +CV_IMPL void* cvGetWindowHandle( const char* window_name ) +{ + void* hwnd = 0; + + CV_FUNCNAME( "cvGetWindowHandle" ); + + __BEGIN__; + + CvWindow* window; + + if( window_name == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL window name" ); + + window = icvFindWindowByName( window_name ); + if( window ) + hwnd = (void*)window->hwnd; + + __END__; + + return hwnd; +} + + +CV_IMPL const char* cvGetWindowName( void* window_handle ) +{ + const char* window_name = ""; + + CV_FUNCNAME( "cvGetWindowName" ); + + __BEGIN__; + + CvWindow* window; + + if( window_handle == 0 ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + window = icvWindowByHWND( (HWND)window_handle ); + if( window ) + window_name = window->name; + + __END__; + + return window_name; +} + + +CV_IMPL void +cvSetPreprocessFuncWin32_(const void* callback) +{ + hg_on_preprocess = (CvWin32WindowCallback)callback; +} + +CV_IMPL void +cvSetPostprocessFuncWin32_(const void* callback) +{ + hg_on_postprocess = (CvWin32WindowCallback)callback; +} + +#endif //WIN32 diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_drawing.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_drawing.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_drawing.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_drawing.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,446 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace cv; + +//#define DRAW_TEST_IMAGE + +class CV_DrawingTest : public cvtest::BaseTest +{ +public: + CV_DrawingTest(){} +protected: + void run( int ); + virtual void draw( Mat& img ) = 0; + virtual int checkLineIterator( Mat& img) = 0; +}; + +void CV_DrawingTest::run( int ) +{ + Mat testImg, valImg; + const string fname = "drawing/image.png"; + string path = ts->get_data_path(), filename; + filename = path + fname; + + draw( testImg ); + + valImg = imread( filename ); + if( valImg.empty() ) + { + imwrite( filename, testImg ); + //ts->printf( ts->LOG, "test image can not be read"); + //ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + } + else + { + float err = (float)norm( testImg, valImg, CV_RELATIVE_L1 ); + float Eps = 0.9f; + if( err > Eps) + { + ts->printf( ts->LOG, "CV_RELATIVE_L1 between testImg and valImg is equal %f (larger than %f)\n", err, Eps ); + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + } + else + { + ts->set_failed_test_info(checkLineIterator( testImg )); + } + } + ts->set_failed_test_info(cvtest::TS::OK); +} + +class CV_DrawingTest_CPP : public CV_DrawingTest +{ +public: + CV_DrawingTest_CPP() {} +protected: + virtual void draw( Mat& img ); + virtual int checkLineIterator( Mat& img); +}; + +void CV_DrawingTest_CPP::draw( Mat& img ) +{ + Size imgSize( 600, 400 ); + img.create( imgSize, CV_8UC3 ); + + vector polyline(4); + polyline[0] = Point(0, 0); + polyline[1] = Point(imgSize.width, 0); + polyline[2] = Point(imgSize.width, imgSize.height); + polyline[3] = Point(0, imgSize.height); + const Point* pts = &polyline[0]; + int n = (int)polyline.size(); + fillPoly( img, &pts, &n, 1, Scalar::all(255) ); + + Point p1(1,1), p2(3,3); + if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) ) + circle( img, Point(300,100), 40, Scalar(0,0,255), 3 ); // draw + + p2 = Point(3,imgSize.height+1000); + if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) ) + circle( img, Point(500,300), 50, cvColorToScalar(255,CV_8UC3), 5, 8, 1 ); // draw + + p1 = Point(imgSize.width,1), p2 = Point(imgSize.width,3); + if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) ) + circle( img, Point(390,100), 10, Scalar(0,0,255), 3 ); // not draw + + p1 = Point(imgSize.width-1,1), p2 = Point(imgSize.width,3); + if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) ) + ellipse( img, Point(390,100), Size(20,30), 60, 0, 220.0, Scalar(0,200,0), 4 ); //draw + + ellipse( img, RotatedRect(Point(100,200),Size(200,100),160), Scalar(200,200,255), 5 ); + + polyline.clear(); + ellipse2Poly( Point(430,180), Size(100,150), 30, 0, 150, 20, polyline ); + pts = &polyline[0]; + n = (int)polyline.size(); + polylines( img, &pts, &n, 1, false, Scalar(0,0,150), 4, CV_AA ); + n = 0; + for( vector::const_iterator it = polyline.begin(); n < (int)polyline.size()-1; ++it, n++ ) + { + line( img, *it, *(it+1), Scalar(50,250,100)); + } + + polyline.clear(); + ellipse2Poly( Point(500,300), Size(50,80), 0, 0, 180, 10, polyline ); + pts = &polyline[0]; + n = (int)polyline.size(); + polylines( img, &pts, &n, 1, true, Scalar(100,200,100), 20 ); + fillConvexPoly( img, pts, n, Scalar(0, 80, 0) ); + + polyline.resize(8); + // external rectengular + polyline[0] = Point(0, 0); + polyline[1] = Point(80, 0); + polyline[2] = Point(80, 80); + polyline[3] = Point(0, 80); + // internal rectangular + polyline[4] = Point(20, 20); + polyline[5] = Point(60, 20); + polyline[6] = Point(60, 60); + polyline[7] = Point(20, 60); + const Point* ppts[] = {&polyline[0], &polyline[0]+4}; + int pn[] = {4, 4}; + fillPoly( img, ppts, pn, 2, Scalar(100, 100, 0), 8, 0, Point(500, 20) ); + + rectangle( img, Point(0, 300), Point(50, 398), Scalar(0,0,255) ); + + string text1 = "OpenCV"; + int baseline = 0, thickness = 3, fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX; + float fontScale = 2; + Size textSize = getTextSize( text1, fontFace, fontScale, thickness, &baseline); + baseline += thickness; + Point textOrg((img.cols - textSize.width)/2, (img.rows + textSize.height)/2); + rectangle(img, textOrg + Point(0, baseline), textOrg + Point(textSize.width, -textSize.height), Scalar(0,0,255)); + line(img, textOrg + Point(0, thickness), textOrg + Point(textSize.width, thickness), Scalar(0, 0, 255)); + putText(img, text1, textOrg, fontFace, fontScale, Scalar(150,0,150), thickness, 8); + + string text2 = "abcdefghijklmnopqrstuvwxyz1234567890"; + Scalar color(200,0,0); + fontScale = 0.5, thickness = 1; + int dist = 5; + + textSize = getTextSize( text2, FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline); + textOrg = Point(5,5)+Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, CV_AA); + + fontScale = 1; + textSize = getTextSize( text2, FONT_HERSHEY_PLAIN, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_PLAIN, fontScale, color, thickness, CV_AA); + + fontScale = 0.5; + textSize = getTextSize( text2, FONT_HERSHEY_DUPLEX, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_DUPLEX, fontScale, color, thickness, CV_AA); + + textSize = getTextSize( text2, FONT_HERSHEY_COMPLEX, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX, fontScale, color, thickness, CV_AA); + + textSize = getTextSize( text2, FONT_HERSHEY_TRIPLEX, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_TRIPLEX, fontScale, color, thickness, CV_AA); + + fontScale = 1; + textSize = getTextSize( text2, FONT_HERSHEY_COMPLEX_SMALL, fontScale, thickness, &baseline); + textOrg += Point(0,180) + Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX_SMALL, fontScale, color, thickness, CV_AA); + + textSize = getTextSize( text2, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, color, thickness, CV_AA); + + textSize = getTextSize( text2, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, color, thickness, CV_AA); + + dist = 15, fontScale = 0.5; + textSize = getTextSize( text2, FONT_ITALIC, fontScale, thickness, &baseline); + textOrg += Point(0,textSize.height+dist); + putText(img, text2, textOrg, FONT_ITALIC, fontScale, color, thickness, CV_AA); +} + +int CV_DrawingTest_CPP::checkLineIterator( Mat& img ) +{ + LineIterator it( img, Point(0,300), Point(1000, 300) ); + for(int i = 0; i < it.count; ++it, i++ ) + { + Vec3b v = (Vec3b)(*(*it)) - img.at(300,i); + float err = (float)norm( v ); + if( err != 0 ) + { + ts->printf( ts->LOG, "LineIterator works incorrect" ); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + } + } + ts->set_failed_test_info(cvtest::TS::OK); + return 0; +} + +class CV_DrawingTest_C : public CV_DrawingTest +{ +public: + CV_DrawingTest_C() {} +protected: + virtual void draw( Mat& img ); + virtual int checkLineIterator( Mat& img); +}; + +void CV_DrawingTest_C::draw( Mat& _img ) +{ + CvSize imgSize = cvSize(600, 400); + _img.create( imgSize, CV_8UC3 ); + CvMat img = _img; + + vector polyline(4); + polyline[0] = cvPoint(0, 0); + polyline[1] = cvPoint(imgSize.width, 0); + polyline[2] = cvPoint(imgSize.width, imgSize.height); + polyline[3] = cvPoint(0, imgSize.height); + CvPoint* pts = &polyline[0]; + int n = (int)polyline.size(); + cvFillPoly( &img, &pts, &n, 1, cvScalar(255,255,255) ); + + CvPoint p1 = cvPoint(1,1), p2 = cvPoint(3,3); + if( cvClipLine(imgSize, &p1, &p2) ) + cvCircle( &img, cvPoint(300,100), 40, cvScalar(0,0,255), 3 ); // draw + + p1 = cvPoint(1,1), p2 = cvPoint(3,imgSize.height+1000); + if( cvClipLine(imgSize, &p1, &p2) ) + cvCircle( &img, cvPoint(500,300), 50, cvScalar(255,0,0), 5, 8, 1 ); // draw + + p1 = cvPoint(imgSize.width,1), p2 = cvPoint(imgSize.width,3); + if( cvClipLine(imgSize, &p1, &p2) ) + cvCircle( &img, cvPoint(390,100), 10, cvScalar(0,0,255), 3 ); // not draw + + p1 = Point(imgSize.width-1,1), p2 = Point(imgSize.width,3); + if( cvClipLine(imgSize, &p1, &p2) ) + cvEllipse( &img, cvPoint(390,100), cvSize(20,30), 60, 0, 220.0, cvScalar(0,200,0), 4 ); //draw + + CvBox2D box; + box.center.x = 100; + box.center.y = 200; + box.size.width = 200; + box.size.height = 100; + box.angle = 160; + cvEllipseBox( &img, box, Scalar(200,200,255), 5 ); + + polyline.resize(9); + pts = &polyline[0]; + n = (int)polyline.size(); + assert( cvEllipse2Poly( cvPoint(430,180), cvSize(100,150), 30, 0, 150, &polyline[0], 20 ) == n ); + cvPolyLine( &img, &pts, &n, 1, false, cvScalar(0,0,150), 4, CV_AA ); + n = 0; + for( vector::const_iterator it = polyline.begin(); n < (int)polyline.size()-1; ++it, n++ ) + { + cvLine( &img, *it, *(it+1), cvScalar(50,250,100) ); + } + + polyline.resize(19); + pts = &polyline[0]; + n = (int)polyline.size(); + assert( cvEllipse2Poly( cvPoint(500,300), cvSize(50,80), 0, 0, 180, &polyline[0], 10 ) == n ); + cvPolyLine( &img, &pts, &n, 1, true, Scalar(100,200,100), 20 ); + cvFillConvexPoly( &img, pts, n, cvScalar(0, 80, 0) ); + + polyline.resize(8); + // external rectengular + polyline[0] = cvPoint(500, 20); + polyline[1] = cvPoint(580, 20); + polyline[2] = cvPoint(580, 100); + polyline[3] = cvPoint(500, 100); + // internal rectangular + polyline[4] = cvPoint(520, 40); + polyline[5] = cvPoint(560, 40); + polyline[6] = cvPoint(560, 80); + polyline[7] = cvPoint(520, 80); + CvPoint* ppts[] = {&polyline[0], &polyline[0]+4}; + int pn[] = {4, 4}; + cvFillPoly( &img, ppts, pn, 2, cvScalar(100, 100, 0), 8, 0 ); + + cvRectangle( &img, cvPoint(0, 300), cvPoint(50, 398), cvScalar(0,0,255) ); + + string text1 = "OpenCV"; + CvFont font; + cvInitFont( &font, FONT_HERSHEY_SCRIPT_SIMPLEX, 2, 2, 0, 3 ); + int baseline = 0; + CvSize textSize; + cvGetTextSize( text1.c_str(), &font, &textSize, &baseline ); + baseline += font.thickness; + CvPoint textOrg = cvPoint((imgSize.width - textSize.width)/2, (imgSize.height + textSize.height)/2); + cvRectangle( &img, cvPoint( textOrg.x, textOrg.y + baseline), + cvPoint(textOrg.x + textSize.width, textOrg.y - textSize.height), cvScalar(0,0,255)); + cvLine( &img, cvPoint(textOrg.x, textOrg.y + font.thickness), + cvPoint(textOrg.x + textSize.width, textOrg.y + font.thickness), cvScalar(0, 0, 255)); + cvPutText( &img, text1.c_str(), textOrg, &font, cvScalar(150,0,150) ); + + int dist = 5; + string text2 = "abcdefghijklmnopqrstuvwxyz1234567890"; + CvScalar color = cvScalar(200,0,0); + cvInitFont( &font, FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(5, 5+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_PLAIN, 1, 1, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_DUPLEX, 0.5, 0.5, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_TRIPLEX, 0.5, 0.5, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_COMPLEX_SMALL, 1, 1, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist + 180); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_SCRIPT_SIMPLEX, 1, 1, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + cvInitFont( &font, FONT_HERSHEY_SCRIPT_COMPLEX, 1, 1, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); + + dist = 15; + cvInitFont( &font, FONT_ITALIC, 0.5, 0.5, 0, 1, CV_AA ); + cvGetTextSize( text2.c_str(), &font, &textSize, &baseline ); + textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist); + cvPutText(&img, text2.c_str(), textOrg, &font, color ); +} + +int CV_DrawingTest_C::checkLineIterator( Mat& _img ) +{ + CvLineIterator it; + CvMat img = _img; + int count = cvInitLineIterator( &img, cvPoint(0,300), cvPoint(1000, 300), &it ); + for(int i = 0; i < count; i++ ) + { + Vec3b v = (Vec3b)(*(it.ptr)) - _img.at(300,i); + float err = (float)norm( v ); + if( err != 0 ) + { + ts->printf( ts->LOG, "CvLineIterator works incorrect" ); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + } + CV_NEXT_LINE_POINT(it); + } + ts->set_failed_test_info(cvtest::TS::OK); + return 0; +} + +#ifdef HAVE_JPEG +TEST(Highgui_Drawing, cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); } +TEST(Highgui_Drawing, c_regression) { CV_DrawingTest_C test; test.safe_run(); } +#endif + +class CV_FillConvexPolyTest : public cvtest::BaseTest +{ +public: + CV_FillConvexPolyTest() {} + ~CV_FillConvexPolyTest() {} +protected: + void run(int) + { + vector line1; + vector line2; + + line1.push_back(Point(1, 1)); + line1.push_back(Point(5, 1)); + line1.push_back(Point(5, 8)); + line1.push_back(Point(1, 8)); + + line2.push_back(Point(2, 2)); + line2.push_back(Point(10, 2)); + line2.push_back(Point(10, 16)); + line2.push_back(Point(2, 16)); + + Mat gray0(10,10,CV_8U, Scalar(0)); + fillConvexPoly(gray0, line1, Scalar(255), 8, 0); + int nz1 = countNonZero(gray0); + + fillConvexPoly(gray0, line2, Scalar(0), 8, 1); + int nz2 = countNonZero(gray0)/255; + + CV_Assert( nz1 == 40 && nz2 == 0 ); + } +}; + +TEST(Highgui_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_ffmpeg.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_ffmpeg.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_ffmpeg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_ffmpeg.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,398 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace cv; + +#ifdef HAVE_FFMPEG + +#include "ffmpeg_codecs.hpp" + +using namespace std; + +class CV_FFmpegWriteBigVideoTest : public cvtest::BaseTest +{ +public: + void run(int) + { + const int img_r = 4096; + const int img_c = 4096; + const double fps0 = 15; + const double time_sec = 1; + + const size_t n = sizeof(codec_bmp_tags)/sizeof(codec_bmp_tags[0]); + + bool created = false; + + for (size_t j = 0; j < n; ++j) + { + stringstream s; s << codec_bmp_tags[j].tag; + int tag = codec_bmp_tags[j].tag; + + if( tag != MKTAG('H', '2', '6', '3') && + tag != MKTAG('H', '2', '6', '1') && + //tag != MKTAG('D', 'I', 'V', 'X') && + tag != MKTAG('D', 'X', '5', '0') && + tag != MKTAG('X', 'V', 'I', 'D') && + tag != MKTAG('m', 'p', '4', 'v') && + //tag != MKTAG('D', 'I', 'V', '3') && + //tag != MKTAG('W', 'M', 'V', '1') && + //tag != MKTAG('W', 'M', 'V', '2') && + tag != MKTAG('M', 'P', 'E', 'G') && + tag != MKTAG('M', 'J', 'P', 'G') && + //tag != MKTAG('j', 'p', 'e', 'g') && + tag != 0 && + tag != MKTAG('I', '4', '2', '0') && + //tag != MKTAG('Y', 'U', 'Y', '2') && + tag != MKTAG('F', 'L', 'V', '1') ) + continue; + + const string filename = "output_"+s.str()+".avi"; + + try + { + double fps = fps0; + Size frame_s = Size(img_c, img_r); + + if( tag == CV_FOURCC('H', '2', '6', '1') ) + frame_s = Size(352, 288); + else if( tag == CV_FOURCC('H', '2', '6', '3') ) + frame_s = Size(704, 576); + /*else if( tag == CV_FOURCC('M', 'J', 'P', 'G') || + tag == CV_FOURCC('j', 'p', 'e', 'g') ) + frame_s = Size(1920, 1080);*/ + + if( tag == CV_FOURCC('M', 'P', 'E', 'G') ) + fps = 25; + + VideoWriter writer(filename, tag, fps, frame_s); + + if (writer.isOpened() == false) + { + ts->printf(ts->LOG, "\n\nFile name: %s\n", filename.c_str()); + ts->printf(ts->LOG, "Codec id: %d Codec tag: %c%c%c%c\n", j, + tag & 255, (tag >> 8) & 255, (tag >> 16) & 255, (tag >> 24) & 255); + ts->printf(ts->LOG, "Error: cannot create video file."); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + } + else + { + Mat img(frame_s, CV_8UC3, Scalar::all(0)); + const int coeff = cvRound(min(frame_s.width, frame_s.height)/(fps0 * time_sec)); + + for (int i = 0 ; i < static_cast(fps * time_sec); i++ ) + { + //circle(img, Point2i(img_c / 2, img_r / 2), min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2); + rectangle(img, Point2i(coeff * i, coeff * i), Point2i(coeff * (i + 1), coeff * (i + 1)), + Scalar::all(255 * (1.0 - static_cast(i) / (fps * time_sec * 2) )), -1); + writer << img; + } + + if (!created) created = true; + else remove(filename.c_str()); + } + } + catch(...) + { + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + } + ts->set_failed_test_info(cvtest::TS::OK); + + } + } +}; + +TEST(Highgui_Video, ffmpeg_writebig) { CV_FFmpegWriteBigVideoTest test; test.safe_run(); } + +class CV_FFmpegReadImageTest : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + string filename = ts->get_data_path() + "../cv/features2d/tsukuba.png"; + VideoCapture cap(filename); + Mat img0 = imread(filename, 1); + Mat img, img_next; + cap >> img; + cap >> img_next; + + CV_Assert( !img0.empty() && !img.empty() && img_next.empty() ); + + double diff = norm(img0, img, CV_C); + CV_Assert( diff == 0 ); + } + catch(...) + { + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + } + ts->set_failed_test_info(cvtest::TS::OK); + } +}; + +TEST(Highgui_Video, ffmpeg_image) { CV_FFmpegReadImageTest test; test.safe_run(); } + +#endif + +#if defined(HAVE_FFMPEG) + +//////////////////////////////// Parallel VideoWriters and VideoCaptures //////////////////////////////////// + +class CreateVideoWriterInvoker : + public ParallelLoopBody +{ +public: + const static Size FrameSize; + static std::string TmpDirectory; + + CreateVideoWriterInvoker(std::vector& _writers, std::vector& _files) : + ParallelLoopBody(), writers(&_writers), files(&_files) + { + } + + virtual void operator() (const Range& range) const + { + for (int i = range.start; i != range.end; ++i) + { + std::ostringstream stream; + stream << i << ".avi"; + std::string fileName = tempfile(stream.str().c_str()); + + files->operator[](i) = fileName; + writers->operator[](i) = new VideoWriter(fileName, CV_FOURCC('X','V','I','D'), 25.0f, FrameSize); + + CV_Assert(writers->operator[](i)->isOpened()); + } + } + +private: + std::vector* writers; + std::vector* files; +}; + +std::string CreateVideoWriterInvoker::TmpDirectory; +const Size CreateVideoWriterInvoker::FrameSize(1020, 900); + +class WriteVideo_Invoker : + public ParallelLoopBody +{ +public: + enum { FrameCount = 300 }; + + static const Scalar ObjectColor; + static const Point Center; + + WriteVideo_Invoker(const std::vector& _writers) : + ParallelLoopBody(), writers(&_writers) + { + } + + static void GenerateFrame(Mat& frame, unsigned int i) + { + frame = Scalar::all(i % 255); + + std::string text = to_string(i); + putText(frame, text, Point(50, Center.y), FONT_HERSHEY_SIMPLEX, 5.0, ObjectColor, 5, CV_AA); + circle(frame, Center, i + 2, ObjectColor, 2, CV_AA); + } + + virtual void operator() (const Range& range) const + { + for (int j = range.start; j < range.end; ++j) + { + VideoWriter* writer = writers->operator[](j); + CV_Assert(writer != NULL); + CV_Assert(writer->isOpened()); + + Mat frame(CreateVideoWriterInvoker::FrameSize, CV_8UC3); + for (unsigned int i = 0; i < FrameCount; ++i) + { + GenerateFrame(frame, i); + writer->operator<< (frame); + } + } + } + +protected: + static std::string to_string(unsigned int i) + { + std::stringstream stream(std::ios::out); + stream << "frame #" << i; + return stream.str(); + } + +private: + const std::vector* writers; +}; + +const Scalar WriteVideo_Invoker::ObjectColor(Scalar::all(0)); +const Point WriteVideo_Invoker::Center(CreateVideoWriterInvoker::FrameSize.height / 2, + CreateVideoWriterInvoker::FrameSize.width / 2); + +class CreateVideoCaptureInvoker : + public ParallelLoopBody +{ +public: + CreateVideoCaptureInvoker(std::vector& _readers, const std::vector& _files) : + ParallelLoopBody(), readers(&_readers), files(&_files) + { + } + + virtual void operator() (const Range& range) const + { + for (int i = range.start; i != range.end; ++i) + { + readers->operator[](i) = new VideoCapture(files->operator[](i)); + CV_Assert(readers->operator[](i)->isOpened()); + } + } +private: + std::vector* readers; + const std::vector* files; +}; + +class ReadImageAndTest : + public ParallelLoopBody +{ +public: + ReadImageAndTest(const std::vector& _readers, cvtest::TS* _ts) : + ParallelLoopBody(), readers(&_readers), ts(_ts) + { + } + + virtual void operator() (const Range& range) const + { + for (int j = range.start; j < range.end; ++j) + { + VideoCapture* capture = readers->operator[](j); + CV_Assert(capture != NULL); + CV_Assert(capture->isOpened()); + + const static double eps = 23.0; + unsigned int frameCount = static_cast(capture->get(CV_CAP_PROP_FRAME_COUNT)); + CV_Assert(frameCount == WriteVideo_Invoker::FrameCount); + Mat reference(CreateVideoWriterInvoker::FrameSize, CV_8UC3); + + for (unsigned int i = 0; i < frameCount && next; ++i) + { + Mat actual; + (*capture) >> actual; + + WriteVideo_Invoker::GenerateFrame(reference, i); + + EXPECT_EQ(reference.cols, actual.cols); + EXPECT_EQ(reference.rows, actual.rows); + EXPECT_EQ(reference.depth(), actual.depth()); + EXPECT_EQ(reference.channels(), actual.channels()); + + double psnr = PSNR(actual, reference); + if (psnr < eps) + { + #define SUM cvtest::TS::SUMMARY + ts->printf(SUM, "\nPSNR: %lf\n", psnr); + ts->printf(SUM, "Video #: %d\n", range.start); + ts->printf(SUM, "Frame #: %d\n", i); + #undef SUM + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + ts->set_gtest_status(); + + Mat diff; + absdiff(actual, reference, diff); + + EXPECT_EQ(countNonZero(diff.reshape(1) > 1), 0); + + next = false; + } + } + } + } + + static bool next; + +private: + const std::vector* readers; + cvtest::TS* ts; +}; + +bool ReadImageAndTest::next; + +TEST(Highgui_Video_parallel_writers_and_readers, accuracy) +{ + const unsigned int threadsCount = 4; + cvtest::TS* ts = cvtest::TS::ptr(); + + // creating VideoWriters + std::vector writers(threadsCount); + Range range(0, threadsCount); + std::vector files(threadsCount); + CreateVideoWriterInvoker invoker1(writers, files); + parallel_for_(range, invoker1); + + // write a video + parallel_for_(range, WriteVideo_Invoker(writers)); + + // deleting the writers + for (std::vector::iterator i = writers.begin(), end = writers.end(); i != end; ++i) + delete *i; + writers.clear(); + + std::vector readers(threadsCount); + CreateVideoCaptureInvoker invoker2(readers, files); + parallel_for_(range, invoker2); + + ReadImageAndTest::next = true; + + parallel_for_(range, ReadImageAndTest(readers, ts)); + + // deleting tmp video files + for (std::vector::const_iterator i = files.begin(), end = files.end(); i != end; ++i) + { + int code = remove(i->c_str()); + if (code == 1) + std::cerr << "Couldn't delete " << *i << std::endl; + } +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_fourcc.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_fourcc.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_fourcc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_fourcc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,115 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +#undef DEFINE_GUID +#define DEFINE_GUID(n, fourcc, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) fourcc, + +unsigned long allfourcc[] = { + +DEFINE_GUID(MEDIASUBTYPE_GREY, 0x59455247, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71) +DEFINE_GUID(MEDIASUBTYPE_Y8, 0x20203859, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71) +DEFINE_GUID(MEDIASUBTYPE_Y800, 0x30303859, 0x0000, 0x0010, 0x80, 0x00, + 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71) + +DEFINE_GUID(CLSID_CaptureGraphBuilder2,0xbf87b6e1,0x8c27,0x11d0,0xb3,0xf0,0x00,0xaa,0x00,0x37,0x61,0xc5) +DEFINE_GUID(CLSID_FilterGraph,0xe436ebb3,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(CLSID_NullRenderer,0xc1f400a4,0x3f08,0x11d3,0x9f,0x0b,0x00,0x60,0x08,0x03,0x9e,0x37) +DEFINE_GUID(CLSID_SampleGrabber,0xc1f400a0,0x3f08,0x11d3,0x9f,0x0b,0x00,0x60,0x08,0x03,0x9e,0x37) +DEFINE_GUID(CLSID_SystemDeviceEnum,0x62be5d10,0x60eb,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86) +DEFINE_GUID(CLSID_VideoInputDeviceCategory,0x860bb310,0x5d01,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86) +DEFINE_GUID(FORMAT_VideoInfo,0x05589f80,0xc356,0x11ce,0xbf,0x01,0x00,0xaa,0x00,0x55,0x59,0x5a) +DEFINE_GUID(IID_IAMAnalogVideoDecoder,0xc6e13350,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56) +DEFINE_GUID(IID_IAMCameraControl,0xc6e13370,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56) +DEFINE_GUID(IID_IAMCrossbar,0xc6e13380,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56) +DEFINE_GUID(IID_IAMStreamConfig,0xc6e13340,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56) +DEFINE_GUID(IID_IAMVideoProcAmp,0xc6e13360,0x30ac,0x11d0,0xa1,0x8c,0x00,0xa0,0xc9,0x11,0x89,0x56) +DEFINE_GUID(IID_IBaseFilter,0x56a86895,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(IID_ICaptureGraphBuilder2,0x93e5a4e0,0x2d50,0x11d2,0xab,0xfa,0x00,0xa0,0xc9,0xc6,0xe3,0x8d) +DEFINE_GUID(IID_ICreateDevEnum,0x29840822,0x5b84,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86) +DEFINE_GUID(IID_IGraphBuilder,0x56a868a9,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(IID_IMPEG2PIDMap,0xafb6c2a1,0x2c41,0x11d3,0x8a,0x60,0x00,0x00,0xf8,0x1e,0x0e,0x4a) +DEFINE_GUID(IID_IMediaControl,0x56a868b1,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(IID_IMediaFilter,0x56a86899,0x0ad4,0x11ce,0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(IID_ISampleGrabber,0x6b652fff,0x11fe,0x4fce,0x92,0xad,0x02,0x66,0xb5,0xd7,0xc7,0x8f) +DEFINE_GUID(LOOK_UPSTREAM_ONLY,0xac798be0,0x98e3,0x11d1,0xb3,0xf1,0x00,0xaa,0x00,0x37,0x61,0xc5) +DEFINE_GUID(MEDIASUBTYPE_AYUV,0x56555941,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_IYUV,0x56555949,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_RGB24,0xe436eb7d,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(MEDIASUBTYPE_RGB32,0xe436eb7e,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(MEDIASUBTYPE_RGB555,0xe436eb7c,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(MEDIASUBTYPE_RGB565,0xe436eb7b,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70) +DEFINE_GUID(MEDIASUBTYPE_I420,0x49343230,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_UYVY,0x59565955,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_Y211,0x31313259,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_Y411,0x31313459,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_Y41P,0x50313459,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_YUY2,0x32595559,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_YUYV,0x56595559,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_YV12,0x32315659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_YVU9,0x39555659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_YVYU,0x55595659,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIASUBTYPE_MJPG,0x47504A4D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71) // MGB +DEFINE_GUID(MEDIATYPE_Interleaved,0x73766169,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(MEDIATYPE_Video,0x73646976,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71) +DEFINE_GUID(PIN_CATEGORY_CAPTURE,0xfb6c4281,0x0353,0x11d1,0x90,0x5f,0x00,0x00,0xc0,0xcc,0x16,0xba) +DEFINE_GUID(PIN_CATEGORY_PREVIEW,0xfb6c4282,0x0353,0x11d1,0x90,0x5f,0x00,0x00,0xc0,0xcc,0x16,0xba) + +0}; + + +TEST(Highgui_dshow, fourcc_conversion) +{ + for(int i = 0; allfourcc[i]; ++i) + { + unsigned long fourcc = allfourcc[i]; + + double paramValue = fourcc; + int fourccFromParam = (int)(unsigned long)(paramValue); + + EXPECT_EQ(fourcc, (unsigned long)(unsigned)fourccFromParam); + } +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_framecount.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_framecount.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_framecount.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_framecount.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,114 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" +#include + +using namespace cv; +using namespace std; + +class CV_FramecountTest: public cvtest::BaseTest +{ +public: + void run(int); +}; + +void CV_FramecountTest::run(int) +{ + const int time_sec = 5, fps = 25; + + const string ext[] = {"avi", "mov", "mp4"}; + + const size_t n = sizeof(ext)/sizeof(ext[0]); + + const string src_dir = ts->get_data_path(); + + ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + Ptr cap; + + for (size_t i = 0; i < n; ++i) + { + string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + + cap = cvCreateFileCapture(file_path.c_str()); + if (cap.empty()) + { + ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + ts->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + //cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 0); + IplImage* frame; int FrameCount = 0; + + for(;;) + { + frame = cvQueryFrame(cap); + if( !frame ) + break; + FrameCount++; + } + + int framecount = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT); + + ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n"\ + "\nName: big_buck_bunny.%s\nActual frame count: %d\n"\ + "Frame count computed in the cycle of queries of frames: %d\n"\ + "Frame count returned by cvGetCaptureProperty function: %d\n", + i+1, ext[i].c_str(), time_sec*fps, FrameCount, framecount); + + if( (FrameCount != cvRound(time_sec*fps) || + FrameCount != framecount) && ext[i] != "mpg" ) + { + ts->printf(cvtest::TS::LOG, "FAILED\n"); + ts->printf(cvtest::TS::LOG, "\nError: actual frame count and returned frame count are not matched.\n"); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + return; + } + } +} +#if BUILD_WITH_VIDEO_INPUT_SUPPORT && defined HAVE_FFMPEG +TEST(Highgui_Video, framecount) {CV_FramecountTest test; test.safe_run();} +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_grfmt.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_grfmt.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_grfmt.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_grfmt.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,330 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace cv; +using namespace std; + + +class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + ts->printf(cvtest::TS::LOG, "start reading big image\n"); + Mat img = imread(string(ts->get_data_path()) + "readwrite/read.png"); + ts->printf(cvtest::TS::LOG, "finish reading big image\n"); + if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + ts->printf(cvtest::TS::LOG, "start writing big image\n"); + imwrite(cv::tempfile(".png"), img); + ts->printf(cvtest::TS::LOG, "finish writing big image\n"); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + } + ts->set_failed_test_info(cvtest::TS::OK); + } +}; + +string ext_from_int(int ext) +{ +#ifdef HAVE_PNG + if (ext == 0) return ".png"; +#endif + if (ext == 1) return ".bmp"; + if (ext == 2) return ".pgm"; +#ifdef HAVE_TIFF + if (ext == 3) return ".tiff"; +#endif + return ""; +} + +class CV_GrfmtWriteSequenceImageTest : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + const int img_r = 640; + const int img_c = 480; + + for (int k = 1; k <= 5; ++k) + { + for (int ext = 0; ext < 4; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff + { + if(ext_from_int(ext).empty()) + continue; + for (int num_channels = 1; num_channels <= 3; num_channels+=2) + { + ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str()); + Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); + circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); + + string img_path = cv::tempfile(ext_from_int(ext).c_str()); + ts->printf(ts->LOG, "writing image : %s\n", img_path.c_str()); + imwrite(img_path, img); + + ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str()); + Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED); + + if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); + + CV_Assert(img.size() == img_test.size()); + CV_Assert(img.type() == img_test.type()); + + double n = norm(img, img_test); + if ( n > 1.0) + { + ts->printf(ts->LOG, "norm = %f \n", n); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + } + } + } + +#ifdef HAVE_JPEG + for (int num_channels = 1; num_channels <= 3; num_channels+=2) + { + // jpeg + ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ".jpg"); + Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); + circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); + + string filename = cv::tempfile(".jpg"); + imwrite(filename, img); + img = imread(filename, CV_LOAD_IMAGE_UNCHANGED); + + filename = string(ts->get_data_path() + "readwrite/test_" + char(k + 48) + "_c" + char(num_channels + 48) + ".jpg"); + ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str()); + Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED); + + if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); + + CV_Assert(img.size() == img_test.size()); + CV_Assert(img.type() == img_test.type()); + + double n = norm(img, img_test); + if ( n > 1.0) + { + ts->printf(ts->LOG, "norm = %f \n", n); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + } + } +#endif + +#ifdef HAVE_TIFF + for (int num_channels = 1; num_channels <= 3; num_channels+=2) + { + // tiff + ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_16U, num_channels, ".tiff"); + Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0)); + circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); + + string filename = cv::tempfile(".tiff"); + imwrite(filename, img); + ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str()); + Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED); + + if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); + + CV_Assert(img.size() == img_test.size()); + + ts->printf(ts->LOG, "img : %d ; %d \n", img.channels(), img.depth()); + ts->printf(ts->LOG, "img_test : %d ; %d \n", img_test.channels(), img_test.depth()); + + CV_Assert(img.type() == img_test.type()); + + + double n = norm(img, img_test); + if ( n > 1.0) + { + ts->printf(ts->LOG, "norm = %f \n", n); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + } + } +#endif + } + } + catch(const cv::Exception & e) + { + ts->printf(ts->LOG, "Exception: %s\n" , e.what()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + } + } +}; + +class CV_GrfmtReadBMPRLE8Test : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + Mat rle = imread(string(ts->get_data_path()) + "readwrite/rle8.bmp"); + Mat bmp = imread(string(ts->get_data_path()) + "readwrite/ordinary.bmp"); + if (norm(rle-bmp)>1.e-10) + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + } + ts->set_failed_test_info(cvtest::TS::OK); + } +}; + + +#ifdef HAVE_PNG +TEST(Highgui_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); } +#endif + +TEST(Highgui_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); } + +TEST(Highgui_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); } + +#ifdef HAVE_PNG +class CV_GrfmtPNGEncodeTest : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + vector buff; + Mat im = Mat::zeros(1000,1000, CV_8U); + //randu(im, 0, 256); + vector param; + param.push_back(CV_IMWRITE_PNG_COMPRESSION); + param.push_back(3); //default(3) 0-9. + cv::imencode(".png" ,im ,buff, param); + + // hangs + Mat im2 = imdecode(buff,CV_LOAD_IMAGE_ANYDEPTH); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + } + ts->set_failed_test_info(cvtest::TS::OK); + } +}; + +TEST(Highgui_Image, encode_png) { CV_GrfmtPNGEncodeTest test; test.safe_run(); } + +TEST(Highgui_ImreadVSCvtColor, regression) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + + const int MAX_MEAN_DIFF = 1; + const int MAX_ABS_DIFF = 10; + + string imgName = string(ts.get_data_path()) + "/../cv/shared/lena.png"; + Mat original_image = imread(imgName); + Mat gray_by_codec = imread(imgName, 0); + Mat gray_by_cvt; + + cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY); + + Mat diff; + absdiff(gray_by_codec, gray_by_cvt, diff); + + double actual_avg_diff = (double)mean(diff)[0]; + double actual_maxval, actual_minval; + minMaxLoc(diff, &actual_minval, &actual_maxval); + //printf("actual avg = %g, actual maxdiff = %g, npixels = %d\n", actual_avg_diff, actual_maxval, (int)diff.total()); + + EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF); + EXPECT_LT(actual_maxval, MAX_ABS_DIFF); +} +#endif + +#ifdef HAVE_JPEG +TEST(Highgui_Jpeg, encode_empty) +{ + cv::Mat img; + std::vector jpegImg; + + ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception); +} +#endif + + +#ifdef HAVE_TIFF + +// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h +#define uint64 uint64_hack_ +#define int64 int64_hack_ +#include "tiff.h" + +TEST(Highgui_Tiff, decode_tile16384x16384) +{ + // see issue #2161 + cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0)); + string file3 = cv::tempfile(".tiff"); + string file4 = cv::tempfile(".tiff"); + + std::vector params; + params.push_back(TIFFTAG_ROWSPERSTRIP); + params.push_back(big.rows); + cv::imwrite(file4, big, params); + cv::imwrite(file3, big.colRange(0, big.cols - 1), params); + big.release(); + + try + { + cv::imread(file3); + EXPECT_NO_THROW(cv::imread(file4)); + } + catch(const std::bad_alloc&) + { + // have no enough memory + } + + remove(file3.c_str()); + remove(file4.c_str()); +} +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_gui.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_gui.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_gui.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_gui.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,93 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +#if defined HAVE_GTK || defined HAVE_QT || defined HAVE_WIN32UI || defined HAVE_CARBON || defined HAVE_COCOA + +using namespace cv; +using namespace std; + +class CV_HighGuiOnlyGuiTest : public cvtest::BaseTest +{ +protected: + void run(int); +}; + +void Foo(int /*k*/, void* /*z*/) {} + +void CV_HighGuiOnlyGuiTest::run( int /*start_from */) +{ + ts->printf(ts->LOG, "GUI 0\n"); + cvDestroyAllWindows(); + + ts->printf(ts->LOG, "GUI 1\n"); + namedWindow("Win"); + + ts->printf(ts->LOG, "GUI 2\n"); + Mat m(256, 256, CV_8U); + m = Scalar(128); + + ts->printf(ts->LOG, "GUI 3\n"); + imshow("Win", m); + + ts->printf(ts->LOG, "GUI 4\n"); + int value = 50; + + ts->printf(ts->LOG, "GUI 5\n"); + createTrackbar( "trackbar", "Win", &value, 100, Foo, &value); + + ts->printf(ts->LOG, "GUI 6\n"); + getTrackbarPos( "trackbar", "Win" ); + + ts->printf(ts->LOG, "GUI 7\n"); + waitKey(500); + + ts->printf(ts->LOG, "GUI 8\n"); + cvDestroyAllWindows(); + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Highgui_GUI, regression) { CV_HighGuiOnlyGuiTest test; test.safe_run(); } + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_main.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_main.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,4 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("highgui") + diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_positioning.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_positioning.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_positioning.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_positioning.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,223 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" +#include + +using namespace cv; +using namespace std; + +class CV_VideoPositioningTest: public cvtest::BaseTest +{ +public: + enum {PROGRESSIVE, RANDOM}; + + CV_VideoPositioningTest(); + ~CV_VideoPositioningTest(); + virtual void run(int) = 0; + +protected: + vector idx; + void run_test(int method); + +private: + void generate_idx_seq(CvCapture *cap, int method); +}; + +class CV_VideoProgressivePositioningTest: public CV_VideoPositioningTest +{ +public: + CV_VideoProgressivePositioningTest() : CV_VideoPositioningTest() {}; + ~CV_VideoProgressivePositioningTest(); + void run(int); +}; + +class CV_VideoRandomPositioningTest: public CV_VideoPositioningTest +{ +public: + CV_VideoRandomPositioningTest(): CV_VideoPositioningTest() {}; + ~CV_VideoRandomPositioningTest(); + void run(int); +}; + +CV_VideoPositioningTest::CV_VideoPositioningTest() {} +CV_VideoPositioningTest::~CV_VideoPositioningTest() {} +CV_VideoProgressivePositioningTest::~CV_VideoProgressivePositioningTest() {} +CV_VideoRandomPositioningTest::~CV_VideoRandomPositioningTest() {} + +void CV_VideoPositioningTest::generate_idx_seq(CvCapture* cap, int method) +{ + idx.clear(); + int N = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT); + switch(method) + { + case PROGRESSIVE: + { + int pos = 1, step = 20; + do + { + idx.push_back(pos); + pos += step; + } + while (pos <= N); + break; + } + case RANDOM: + { + RNG rng(N); + idx.clear(); + for( int i = 0; i < N-1; i++ ) + idx.push_back(rng.uniform(0, N)); + idx.push_back(N-1); + std::swap(idx.at(rng.uniform(0, N-1)), idx.at(N-1)); + break; + } + default:break; + } +} + +void CV_VideoPositioningTest::run_test(int method) +{ + const string& src_dir = ts->get_data_path(); + + ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + const string ext[] = {"avi", "mov", "mp4", "mpg"}; + + int n = (int)(sizeof(ext)/sizeof(ext[0])); + + int failed_videos = 0; + + for (int i = 0; i < n; ++i) + { + // skip random positioning test in plain mpegs + if( method == RANDOM && ext[i] == "mpg" ) + continue; + string file_path = src_dir + "video/big_buck_bunny." + ext[i]; + + ts->printf(cvtest::TS::LOG, "\nReading video file in %s...\n", file_path.c_str()); + + CvCapture* cap = cvCreateFileCapture(file_path.c_str()); + + if (!cap) + { + ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + ts->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + failed_videos++; continue; + } + + cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 0); + + generate_idx_seq(cap, method); + + int N = (int)idx.size(), failed_frames = 0, failed_positions = 0, failed_iterations = 0; + + for (int j = 0; j < N; ++j) + { + bool flag = false; + + cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, idx.at(j)); + + /* IplImage* frame = cvRetrieveFrame(cap); + + if (!frame) + { + if (!failed_frames) + { + ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\n", i+1, ext[i].c_str()); + } + failed_frames++; + ts->printf(cvtest::TS::LOG, "\nIteration: %d\n\nError: cannot read a frame with index %d.\n", j, idx.at(j)); + ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + flag = !flag; + } */ + + int val = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES); + + if (idx.at(j) != val) + { + if (!(failed_frames||failed_positions)) + { + ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\n", i+1, ext[i].c_str()); + } + failed_positions++; + if (!failed_frames) + { + ts->printf(cvtest::TS::LOG, "\nIteration: %d\n", j); + } + ts->printf(cvtest::TS::LOG, "Required pos: %d\nReturned pos: %d\n", idx.at(j), val); + ts->printf(cvtest::TS::LOG, "Error: required and returned positions are not matched.\n"); + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); + flag = true; + } + + if (flag) + { + failed_iterations++; + failed_videos++; + break; + } + } + + cvReleaseCapture(&cap); + } + + ts->printf(cvtest::TS::LOG, "\nSuccessfull experiments: %d (%d%%)\n", n-failed_videos, 100*(n-failed_videos)/n); + ts->printf(cvtest::TS::LOG, "Failed experiments: %d (%d%%)\n", failed_videos, 100*failed_videos/n); +} + +void CV_VideoProgressivePositioningTest::run(int) +{ + run_test(PROGRESSIVE); +} + +void CV_VideoRandomPositioningTest::run(int) +{ + run_test(RANDOM); +} + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT && defined HAVE_FFMPEG +TEST (Highgui_Video, seek_progressive) { CV_VideoProgressivePositioningTest test; test.safe_run(); } +TEST (Highgui_Video, seek_random) { CV_VideoRandomPositioningTest test; test.safe_run(); } +#endif \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_precomp.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "test_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_precomp.hpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,85 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#ifdef HAVE_CVCONFIG_H +# include "cvconfig.h" +#endif + +#include "opencv2/ts/ts.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include + +#if defined(HAVE_DSHOW) || \ + defined(HAVE_TYZX) || \ + defined(HAVE_VFW) || \ + defined(HAVE_LIBV4L) || \ + (defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2)) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_DC1394_2) || \ + defined(HAVE_DC1394) || \ + defined(HAVE_CMU1394) || \ + defined(HAVE_MIL) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_UNICAP) || \ + defined(HAVE_PVAPI) || \ + defined(HAVE_OPENNI) || \ + defined(HAVE_XIMEA) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_GIGE_API) || \ + (0) + //defined(HAVE_ANDROID_NATIVE_CAMERA) || - enable after #1193 +# define BUILD_WITH_CAMERA_SUPPORT 1 +#else +# define BUILD_WITH_CAMERA_SUPPORT 0 +#endif + +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_AVFOUNDATION) || \ + /*defined(HAVE_OPENNI) || too specialized */ \ + defined(HAVE_FFMPEG) +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 +#endif + +#if /*defined(HAVE_XINE) || */\ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) +# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1 +#else +# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0 +#endif + +namespace cvtest +{ + +string fourccToString(int fourcc); + +struct VideoFormat +{ + VideoFormat() { fourcc = -1; } + VideoFormat(const string& _ext, int _fourcc) : ext(_ext), fourcc(_fourcc) {} + bool empty() const { return ext.empty(); } + + string ext; + int fourcc; +}; + +extern const VideoFormat g_specific_fmt_list[]; + +} + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_video_io.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_video_io.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_video_io.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_video_io.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,529 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace cv; +using namespace std; + +namespace cvtest +{ + +string fourccToString(int fourcc) +{ + return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); +} + +const VideoFormat g_specific_fmt_list[] = +{ + VideoFormat("avi", CV_FOURCC('X', 'V', 'I', 'D')), + VideoFormat("avi", CV_FOURCC('M', 'P', 'E', 'G')), + VideoFormat("avi", CV_FOURCC('M', 'J', 'P', 'G')), + //VideoFormat("avi", CV_FOURCC('I', 'Y', 'U', 'V')), + VideoFormat("mkv", CV_FOURCC('X', 'V', 'I', 'D')), + VideoFormat("mkv", CV_FOURCC('M', 'P', 'E', 'G')), + VideoFormat("mkv", CV_FOURCC('M', 'J', 'P', 'G')), + + VideoFormat("mov", CV_FOURCC('m', 'p', '4', 'v')), + VideoFormat() +}; + +} + +class CV_HighGuiTest : public cvtest::BaseTest +{ +protected: + void ImageTest(const string& dir); + void VideoTest (const string& dir, const cvtest::VideoFormat& fmt); + void SpecificImageTest (const string& dir); + void SpecificVideoTest (const string& dir, const cvtest::VideoFormat& fmt); + + CV_HighGuiTest() {} + ~CV_HighGuiTest() {} + virtual void run(int) = 0; +}; + +class CV_ImageTest : public CV_HighGuiTest +{ +public: + CV_ImageTest() {} + ~CV_ImageTest() {} + void run(int); +}; + +class CV_SpecificImageTest : public CV_HighGuiTest +{ +public: + CV_SpecificImageTest() {} + ~CV_SpecificImageTest() {} + void run(int); +}; + +class CV_VideoTest : public CV_HighGuiTest +{ +public: + CV_VideoTest() {} + ~CV_VideoTest() {} + void run(int); +}; + +class CV_SpecificVideoTest : public CV_HighGuiTest +{ +public: + CV_SpecificVideoTest() {} + ~CV_SpecificVideoTest() {} + void run(int); +}; + + +void CV_HighGuiTest::ImageTest(const string& dir) +{ + string _name = dir + string("../cv/shared/baboon.png"); + ts->printf(ts->LOG, "reading image : %s\n", _name.c_str()); + + Mat image = imread(_name); + image.convertTo(image, CV_8UC3); + + if (image.empty()) + { + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + return; + } + + const string exts[] = { +#ifdef HAVE_PNG + "png", +#endif +#ifdef HAVE_TIFF + "tiff", +#endif +#ifdef HAVE_JPEG + "jpg", +#endif +#ifdef HAVE_JASPER + "jp2", +#endif +#if 0 /*defined HAVE_OPENEXR && !defined __APPLE__*/ + "exr", +#endif + "bmp", + "ppm", + "ras" + }; + const size_t ext_num = sizeof(exts)/sizeof(exts[0]); + + for(size_t i = 0; i < ext_num; ++i) + { + string ext = exts[i]; + string full_name = cv::tempfile(ext.c_str()); + ts->printf(ts->LOG, " full_name : %s\n", full_name.c_str()); + + imwrite(full_name, image); + + Mat loaded = imread(full_name); + if (loaded.empty()) + { + ts->printf(ts->LOG, "Reading failed at fmt=%s\n", ext.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + const double thresDbell = 20; + double psnr = PSNR(loaded, image); + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Reading image from file: too big difference (=%g) with fmt=%s\n", psnr, ext.c_str()); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + continue; + } + + vector from_file; + + FILE *f = fopen(full_name.c_str(), "rb"); + fseek(f, 0, SEEK_END); + long len = ftell(f); + from_file.resize((size_t)len); + fseek(f, 0, SEEK_SET); + from_file.resize(fread(&from_file[0], 1, from_file.size(), f)); + fclose(f); + + vector buf; + imencode("." + exts[i], image, buf); + + if (buf != from_file) + { + ts->printf(ts->LOG, "Encoding failed with fmt=%s\n", ext.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + Mat buf_loaded = imdecode(Mat(buf), 1); + + if (buf_loaded.empty()) + { + ts->printf(ts->LOG, "Decoding failed with fmt=%s\n", ext.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + psnr = PSNR(buf_loaded, image); + + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Decoding image from memory: too small PSNR (=%gdb) with fmt=%s\n", psnr, ext.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + } + + ts->printf(ts->LOG, "end test function : ImagesTest \n"); + ts->set_failed_test_info(ts->OK); +} + + +void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt) +{ + string src_file = dir + "../cv/shared/video_for_test.avi"; + string tmp_name = cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str()); + + ts->printf(ts->LOG, "reading video : %s and converting it to %s\n", src_file.c_str(), tmp_name.c_str()); + + CvCapture* cap = cvCaptureFromFile(src_file.c_str()); + + if (!cap) + { + ts->set_failed_test_info(ts->FAIL_MISMATCH); + return; + } + + CvVideoWriter* writer = 0; + vector frames; + + for(;;) + { + IplImage * img = cvQueryFrame( cap ); + + if (!img) + break; + + frames.push_back(Mat(img).clone()); + + if (writer == 0) + { + writer = cvCreateVideoWriter(tmp_name.c_str(), fmt.fourcc, 24, cvGetSize(img)); + if (writer == 0) + { + ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n", + cvtest::fourccToString(fmt.fourcc).c_str()); + cvReleaseCapture( &cap ); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + return; + } + } + + cvWriteFrame(writer, img); + } + + cvReleaseVideoWriter( &writer ); + cvReleaseCapture( &cap ); + + CvCapture *saved = cvCaptureFromFile(tmp_name.c_str()); + if (!saved) + { + ts->set_failed_test_info(ts->FAIL_MISMATCH); + return; + } + + const double thresDbell = 20; + + for(int i = 0;; i++) + { + IplImage* ipl1 = cvQueryFrame( saved ); + + if (!ipl1) + break; + + Mat img = frames[i]; + Mat img1(ipl1); + + double psnr = PSNR(img1, img); + if (psnr < thresDbell) + { + printf("Too low psnr = %gdb\n", psnr); + // imwrite("img.png", img); + // imwrite("img1.png", img1); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + break; + } + } + + cvReleaseCapture( &saved ); + + ts->printf(ts->LOG, "end test function : ImagesVideo \n"); +} + +void CV_HighGuiTest::SpecificImageTest(const string& dir) +{ + const size_t IMAGE_COUNT = 10; + + for (size_t i = 0; i < IMAGE_COUNT; ++i) + { + stringstream s; s << i; + string file_path = dir+"../python/images/QCIF_0"+s.str()+".bmp"; + Mat image = imread(file_path); + + if (image.empty()) + { + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + return; + } + + resize(image, image, Size(968, 757), 0.0, 0.0, INTER_CUBIC); + + stringstream s_digit; s_digit << i; + + string full_name = cv::tempfile((s_digit.str() + ".bmp").c_str()); + ts->printf(ts->LOG, " full_name : %s\n", full_name.c_str()); + + imwrite(full_name, image); + + Mat loaded = imread(full_name); + if (loaded.empty()) + { + ts->printf(ts->LOG, "Reading failed at fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + const double thresDbell = 20; + double psnr = PSNR(loaded, image); + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Reading image from file: too big difference (=%g) with fmt=bmp\n", psnr); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + continue; + } + + vector from_file; + + FILE *f = fopen(full_name.c_str(), "rb"); + fseek(f, 0, SEEK_END); + long len = ftell(f); + from_file.resize((size_t)len); + fseek(f, 0, SEEK_SET); + from_file.resize(fread(&from_file[0], 1, from_file.size(), f)); + fclose(f); + + vector buf; + imencode(".bmp", image, buf); + + if (buf != from_file) + { + ts->printf(ts->LOG, "Encoding failed with fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + Mat buf_loaded = imdecode(Mat(buf), 1); + + if (buf_loaded.empty()) + { + ts->printf(ts->LOG, "Decoding failed with fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + psnr = PSNR(buf_loaded, image); + + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Decoding image from memory: too small PSNR (=%gdb) with fmt=bmp\n", psnr); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + } + + ts->printf(ts->LOG, "end test function : SpecificImageTest \n"); + ts->set_failed_test_info(ts->OK); +} + + +void CV_HighGuiTest::SpecificVideoTest(const string& dir, const cvtest::VideoFormat& fmt) +{ + string ext = fmt.ext; + int fourcc = fmt.fourcc; + + string fourcc_str = cvtest::fourccToString(fourcc); + const string video_file = cv::tempfile((fourcc_str + "." + ext).c_str()); + + Size frame_size(968 & -2, 757 & -2); + VideoWriter writer(video_file, fourcc, 25, frame_size, true); + + if (!writer.isOpened()) + { + // call it repeatedly for easier debugging + VideoWriter writer2(video_file, fourcc, 25, frame_size, true); + ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); + ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + return; + } + + const size_t IMAGE_COUNT = 30; + vector images; + + for( size_t i = 0; i < IMAGE_COUNT; ++i ) + { + string file_path = format("%s../python/images/QCIF_%02d.bmp", dir.c_str(), i); + Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR); + + if (img.empty()) + { + ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); + ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", file_path.c_str()); + ts->printf(ts->LOG, "Continue creating the video file...\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); + break; + } + + for (int k = 0; k < img.rows; ++k) + for (int l = 0; l < img.cols; ++l) + if (img.at(k, l) == Vec3b::all(0)) + img.at(k, l) = Vec3b(0, 255, 0); + else img.at(k, l) = Vec3b(0, 0, 255); + + resize(img, img, frame_size, 0.0, 0.0, INTER_CUBIC); + + images.push_back(img); + writer << img; + } + + writer.release(); + VideoCapture cap(video_file); + + size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT); + + if (FRAME_COUNT != IMAGE_COUNT ) + { + ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); + ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); + ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n"); + ts->printf(ts->LOG, "Continue checking...\n"); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + return; + } + + for (int i = 0; (size_t)i < FRAME_COUNT; i++) + { + Mat frame; cap >> frame; + if (frame.empty()) + { + ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); + ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); + ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1); + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + break; + } + + Mat img = images[i]; + + const double thresDbell = 40; + double psnr = PSNR(img, frame); + + if (psnr > thresDbell) + { + ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Frame index: %d\n", i+1); + ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); + ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell); + ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); + break; + } + } +} + +void CV_ImageTest::run(int) +{ + ImageTest(ts->get_data_path()); +} + +void CV_SpecificImageTest::run(int) +{ + SpecificImageTest(ts->get_data_path()); +} + +void CV_VideoTest::run(int) +{ + for (int i = 0; ; ++i) + { + const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i]; + if( fmt.empty() ) + break; + VideoTest(ts->get_data_path(), fmt); + } +} + +void CV_SpecificVideoTest::run(int) +{ + for (int i = 0; ; ++i) + { + const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i]; + if( fmt.empty() ) + break; + SpecificVideoTest(ts->get_data_path(), fmt); + } +} + +#ifdef HAVE_JPEG +TEST(Highgui_Image, regression) { CV_ImageTest test; test.safe_run(); } +#endif + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT && !defined(__APPLE__) +TEST(Highgui_Video, regression) { CV_VideoTest test; test.safe_run(); } +TEST(Highgui_Video, write_read) { CV_SpecificVideoTest test; test.safe_run(); } +#endif + +TEST(Highgui_Image, write_read) { CV_SpecificImageTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/highgui/test/test_video_pos.cpp diffimg-2.0.0/3rdparty/opencv/highgui/test/test_video_pos.cpp --- diffimg-1.5.0/3rdparty/opencv/highgui/test/test_video_pos.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/highgui/test/test_video_pos.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,178 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// + // + // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + // + // By downloading, copying, installing or using the software you agree to this license. + // If you do not agree to this license, do not download, install, + // copy or use the software. + // + // + // License Agreement + // For Open Source Computer Vision Library + // + // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. + // Copyright (C) 2009, Willow Garage Inc., all rights reserved. + // Third party copyrights are property of their respective owners. + // + // Redistribution and use in source and binary forms, with or without modification, + // are permitted provided that the following conditions are met: + // + // * Redistribution's of source code must retain the above copyright notice, + // this list of conditions and the following disclaimer. + // + // * Redistribution's in binary form must reproduce the above copyright notice, + // this list of conditions and the following disclaimer in the documentation + // and/or other materials provided with the distribution. + // + // * The name of the copyright holders may not be used to endorse or promote products + // derived from this software without specific prior written permission. + // + // This software is provided by the copyright holders and contributors "as is" and + // any express or implied warranties, including, but not limited to, the implied + // warranties of merchantability and fitness for a particular purpose are disclaimed. + // In no event shall the Intel Corporation or contributors be liable for any direct, + // indirect, incidental, special, exemplary, or consequential damages + // (including, but not limited to, procurement of substitute goods or services; + // loss of use, data, or profits; or business interruption) however caused + // and on any theory of liability, whether in contract, strict liability, + // or tort (including negligence or otherwise) arising in any way out of + // the use of this software, even if advised of the possibility of such damage. + // + //M*/ + +#include "test_precomp.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace cv; +using namespace std; + +class CV_PositioningTest : public cvtest::BaseTest +{ +public: + CV_PositioningTest() + { + framesize = Size(640, 480); + } + + Mat drawFrame(int i) + { + Mat mat = Mat::zeros(framesize, CV_8UC3); + + mat = Scalar(fabs(cos(i*0.08)*255), fabs(sin(i*0.05)*255), i); + putText(mat, format("%03d", i), Point(10, 350), 0, 10, Scalar(128, 255, 255), 15); + return mat; + } + + string getFilename(const cvtest::VideoFormat& fmt) + { + return cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str()); + } + + bool CreateTestVideo(const cvtest::VideoFormat& fmt, int framecount, string filename) + { + VideoWriter writer(filename, fmt.fourcc, 25, framesize, true); + if( !writer.isOpened() ) + return false; + + for (int i = 0; i < framecount; ++i) + { + Mat img = drawFrame(i); + writer << img; + } + return true; + } + + void run(int) + { + int n_frames = 100; + + for( int testcase = 0; ; testcase++ ) + { + const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[testcase]; + if( fmt.empty() ) + break; + string filename = getFilename(fmt); + ts->printf(ts->LOG, "\nFile: %s\n", filename.c_str()); + + if( !CreateTestVideo(fmt, n_frames, filename) ) + { + ts->printf(ts->LOG, "\nError: cannot create video file"); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + return; + } + + VideoCapture cap(filename); + + if (!cap.isOpened()) + { + ts->printf(ts->LOG, "\nError: cannot read video file."); + ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); + return; + } + + int N0 = (int)cap.get(CV_CAP_PROP_FRAME_COUNT); + cap.set(CV_CAP_PROP_POS_FRAMES, 0); + int N = (int)cap.get(CV_CAP_PROP_FRAME_COUNT); + + if (N != n_frames || N != N0) + { + ts->printf(ts->LOG, "\nError: returned frame count (N0=%d, N=%d) is different from the reference number %d\n", N0, N, n_frames); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + return; + } + + for (int k = 0; k < N; ++k) + { + int idx = theRNG().uniform(0, N); + + if( !cap.set(CV_CAP_PROP_POS_FRAMES, idx) ) + { + ts->printf(ts->LOG, "\nError: cannot seek to frame %d.\n", idx); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + return; + } + + int idx1 = (int)cap.get(CV_CAP_PROP_POS_FRAMES); + + Mat img; cap >> img; + Mat img0 = drawFrame(idx); + + if( idx != idx1 ) + { + ts->printf(ts->LOG, "\nError: the current position (%d) after seek is different from specified (%d)\n", + idx1, idx); + ts->printf(ts->LOG, "Saving both frames ...\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + // imwrite("opencv_test_highgui_postest_actual.png", img); + // imwrite("opencv_test_highgui_postest_expected.png", img0); + return; + } + + if (img.empty()) + { + ts->printf(ts->LOG, "\nError: cannot read a frame at position %d.\n", idx); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + return; + } + + double err = PSNR(img, img0); + + if( err < 20 ) + { + ts->printf(ts->LOG, "The frame read after positioning to %d is incorrect (PSNR=%g)\n", idx, err); + ts->printf(ts->LOG, "Saving both frames ...\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + // imwrite("opencv_test_highgui_postest_actual.png", img); + // imwrite("opencv_test_highgui_postest_expected.png", img0); + return; + } + } + } + } + + Size framesize; +}; + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT && defined HAVE_FFMPEG +TEST(Highgui_Video, seek_random_synthetic) { CV_PositioningTest test; test.safe_run(); } +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/imgproc/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/imgproc/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,2 @@ +set(the_description "Image Processing") +ocv_define_module(imgproc opencv_core) diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/feature_detection.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/feature_detection.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/feature_detection.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/feature_detection.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,548 @@ +Feature Detection +================= + +.. highlight:: cpp + + + +Canny +--------- +Finds edges in an image using the [Canny86]_ algorithm. + +.. ocv:function:: void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false ) + +.. ocv:pyfunction:: cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]) -> edges + +.. ocv:cfunction:: void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.Canny(image, edges, threshold1, threshold2, aperture_size=3) -> None + + :param image: single-channel 8-bit input image. + + :param edges: output edge map; it has the same size and type as ``image`` . + + :param threshold1: first threshold for the hysteresis procedure. + + :param threshold2: second threshold for the hysteresis procedure. + + :param apertureSize: aperture size for the :ocv:func:`Sobel` operator. + + :param L2gradient: a flag, indicating whether a more accurate :math:`L_2` norm :math:`=\sqrt{(dI/dx)^2 + (dI/dy)^2}` should be used to calculate the image gradient magnitude ( ``L2gradient=true`` ), or whether the default :math:`L_1` norm :math:`=|dI/dx|+|dI/dy|` is enough ( ``L2gradient=false`` ). + +The function finds edges in the input image ``image`` and marks them in the output map ``edges`` using the Canny algorithm. The smallest value between ``threshold1`` and ``threshold2`` is used for edge linking. The largest value is used to find initial segments of strong edges. See +http://en.wikipedia.org/wiki/Canny_edge_detector + + + +cornerEigenValsAndVecs +---------------------- +Calculates eigenvalues and eigenvectors of image blocks for corner detection. + +.. ocv:function:: void cornerEigenValsAndVecs( InputArray src, OutputArray dst, int blockSize, int ksize, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.cornerEigenValsAndVecs(src, blockSize, ksize[, dst[, borderType]]) -> dst + +.. ocv:cfunction:: void cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv, int block_size, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.CornerEigenValsAndVecs(image, eigenvv, blockSize, aperture_size=3) -> None + + :param src: Input single-channel 8-bit or floating-point image. + + :param dst: Image to store the results. It has the same size as ``src`` and the type ``CV_32FC(6)`` . + + :param blockSize: Neighborhood size (see details below). + + :param ksize: Aperture parameter for the :ocv:func:`Sobel` operator. + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` . + +For every pixel +:math:`p` , the function ``cornerEigenValsAndVecs`` considers a ``blockSize`` :math:`\times` ``blockSize`` neighborhood +:math:`S(p)` . It calculates the covariation matrix of derivatives over the neighborhood as: + +.. math:: + + M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}(dI/dx dI/dy)^2 \\ \sum _{S(p)}(dI/dx dI/dy)^2 & \sum _{S(p)}(dI/dy)^2 \end{bmatrix} + +where the derivatives are computed using the +:ocv:func:`Sobel` operator. + +After that, it finds eigenvectors and eigenvalues of +:math:`M` and stores them in the destination image as +:math:`(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)` where + +* :math:`\lambda_1, \lambda_2` are the non-sorted eigenvalues of :math:`M` + +* :math:`x_1, y_1` are the eigenvectors corresponding to :math:`\lambda_1` + +* :math:`x_2, y_2` are the eigenvectors corresponding to :math:`\lambda_2` + +The output of the function can be used for robust edge or corner detection. + +.. seealso:: + + :ocv:func:`cornerMinEigenVal`, + :ocv:func:`cornerHarris`, + :ocv:func:`preCornerDetect` + + + +cornerHarris +------------ +Harris edge detector. + +.. ocv:function:: void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]]) -> dst + +.. ocv:cfunction:: void cvCornerHarris( const CvArr* image, CvArr* harris_responce, int block_size, int aperture_size=3, double k=0.04 ) + +.. ocv:pyoldfunction:: cv.CornerHarris(image, harris_dst, blockSize, aperture_size=3, k=0.04) -> None + + :param src: Input single-channel 8-bit or floating-point image. + + :param dst: Image to store the Harris detector responses. It has the type ``CV_32FC1`` and the same size as ``src`` . + + :param blockSize: Neighborhood size (see the details on :ocv:func:`cornerEigenValsAndVecs` ). + + :param ksize: Aperture parameter for the :ocv:func:`Sobel` operator. + + :param k: Harris detector free parameter. See the formula below. + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` . + +The function runs the Harris edge detector on the image. Similarly to +:ocv:func:`cornerMinEigenVal` and +:ocv:func:`cornerEigenValsAndVecs` , for each pixel +:math:`(x, y)` it calculates a +:math:`2\times2` gradient covariance matrix +:math:`M^{(x,y)}` over a +:math:`\texttt{blockSize} \times \texttt{blockSize}` neighborhood. Then, it computes the following characteristic: + +.. math:: + + \texttt{dst} (x,y) = \mathrm{det} M^{(x,y)} - k \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2 + +Corners in the image can be found as the local maxima of this response map. + + + +cornerMinEigenVal +----------------- +Calculates the minimal eigenvalue of gradient matrices for corner detection. + +.. ocv:function:: void cornerMinEigenVal( InputArray src, OutputArray dst, int blockSize, int ksize=3, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.cornerMinEigenVal(src, blockSize[, dst[, ksize[, borderType]]]) -> dst + +.. ocv:cfunction:: void cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, int block_size, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.CornerMinEigenVal(image, eigenval, blockSize, aperture_size=3) -> None + + :param src: Input single-channel 8-bit or floating-point image. + + :param dst: Image to store the minimal eigenvalues. It has the type ``CV_32FC1`` and the same size as ``src`` . + + :param blockSize: Neighborhood size (see the details on :ocv:func:`cornerEigenValsAndVecs` ). + + :param ksize: Aperture parameter for the :ocv:func:`Sobel` operator. + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` . + +The function is similar to +:ocv:func:`cornerEigenValsAndVecs` but it calculates and stores only the minimal eigenvalue of the covariance matrix of derivatives, that is, +:math:`\min(\lambda_1, \lambda_2)` in terms of the formulae in the +:ocv:func:`cornerEigenValsAndVecs` description. + + + +cornerSubPix +---------------- +Refines the corner locations. + +.. ocv:function:: void cornerSubPix( InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria ) + +.. ocv:pyfunction:: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria) -> None + +.. ocv:cfunction:: void cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, int count, CvSize win, CvSize zero_zone, CvTermCriteria criteria ) + +.. ocv:pyoldfunction:: cv.FindCornerSubPix(image, corners, win, zero_zone, criteria) -> corners + + :param image: Input image. + + :param corners: Initial coordinates of the input corners and refined coordinates provided for output. + + :param winSize: Half of the side length of the search window. For example, if ``winSize=Size(5,5)`` , then a :math:`5*2+1 \times 5*2+1 = 11 \times 11` search window is used. + + :param zeroZone: Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such a size. + + :param criteria: Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after ``criteria.maxCount`` iterations or when the corner position moves by less than ``criteria.epsilon`` on some iteration. + +The function iterates to find the sub-pixel accurate location of corners or radial saddle points, as shown on the figure below. + +.. image:: pics/cornersubpix.png + +Sub-pixel accurate corner locator is based on the observation that every vector from the center +:math:`q` to a point +:math:`p` located within a neighborhood of +:math:`q` is orthogonal to the image gradient at +:math:`p` subject to image and measurement noise. Consider the expression: + +.. math:: + + \epsilon _i = {DI_{p_i}}^T \cdot (q - p_i) + +where +:math:`{DI_{p_i}}` is an image gradient at one of the points +:math:`p_i` in a neighborhood of +:math:`q` . The value of +:math:`q` is to be found so that +:math:`\epsilon_i` is minimized. A system of equations may be set up with +:math:`\epsilon_i` set to zero: + +.. math:: + + \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i) + +where the gradients are summed within a neighborhood ("search window") of +:math:`q` . Calling the first gradient term +:math:`G` and the second gradient term +:math:`b` gives: + +.. math:: + + q = G^{-1} \cdot b + +The algorithm sets the center of the neighborhood window at this new center +:math:`q` and then iterates until the center stays within a set threshold. + + + +goodFeaturesToTrack +------------------- +Determines strong corners on an image. + +.. ocv:function:: void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04 ) + +.. ocv:pyfunction:: cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]]) -> corners + +.. ocv:cfunction:: void cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, CvArr* temp_image, CvPoint2D32f* corners, int* corner_count, double quality_level, double min_distance, const CvArr* mask=NULL, int block_size=3, int use_harris=0, double k=0.04 ) + +.. ocv:pyoldfunction:: cv.GoodFeaturesToTrack(image, eigImage, tempImage, cornerCount, qualityLevel, minDistance, mask=None, blockSize=3, useHarris=0, k=0.04) -> cornerCount + + :param image: Input 8-bit or floating-point 32-bit, single-channel image. + + :param eig_image: The parameter is ignored. + + :param temp_image: The parameter is ignored. + + :param corners: Output vector of detected corners. + + :param maxCorners: Maximum number of corners to return. If there are more corners than are found, the strongest of them is returned. + + :param qualityLevel: Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue (see :ocv:func:`cornerMinEigenVal` ) or the Harris function response (see :ocv:func:`cornerHarris` ). The corners with the quality measure less than the product are rejected. For example, if the best corner has the quality measure = 1500, and the ``qualityLevel=0.01`` , then all the corners with the quality measure less than 15 are rejected. + + :param minDistance: Minimum possible Euclidean distance between the returned corners. + + :param mask: Optional region of interest. If the image is not empty (it needs to have the type ``CV_8UC1`` and the same size as ``image`` ), it specifies the region in which the corners are detected. + + :param blockSize: Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See :ocv:func:`cornerEigenValsAndVecs` . + + :param useHarrisDetector: Parameter indicating whether to use a Harris detector (see :ocv:func:`cornerHarris`) or :ocv:func:`cornerMinEigenVal`. + + :param k: Free parameter of the Harris detector. + +The function finds the most prominent corners in the image or in the specified image region, as described in [Shi94]_: + +#. + Function calculates the corner quality measure at every source image pixel using the + :ocv:func:`cornerMinEigenVal` or + :ocv:func:`cornerHarris` . + +#. + Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are retained). + +#. + The corners with the minimal eigenvalue less than + :math:`\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)` are rejected. + +#. + The remaining corners are sorted by the quality measure in the descending order. + +#. + Function throws away each corner for which there is a stronger corner at a distance less than ``maxDistance``. + +The function can be used to initialize a point-based tracker of an object. + +.. note:: If the function is called with different values ``A`` and ``B`` of the parameter ``qualityLevel`` , and ``A`` > {B}, the vector of returned corners with ``qualityLevel=A`` will be the prefix of the output vector with ``qualityLevel=B`` . + +.. seealso:: + + :ocv:func:`cornerMinEigenVal`, + :ocv:func:`cornerHarris`, + :ocv:func:`calcOpticalFlowPyrLK`, + :ocv:func:`estimateRigidTransform`, + + +HoughCircles +------------ +Finds circles in a grayscale image using the Hough transform. + +.. ocv:function:: void HoughCircles( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 ) + +.. ocv:cfunction:: CvSeq* cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1=100, double param2=100, int min_radius=0, int max_radius=0 ) + +.. ocv:pyfunction:: cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles + + :param image: 8-bit, single-channel, grayscale input image. + + :param circles: Output vector of found circles. Each vector is encoded as a 3-element floating-point vector :math:`(x, y, radius)` . + + :param circle_storage: In C function this is a memory storage that will contain the output sequence of found circles. + + :param method: Detection method to use. Currently, the only implemented method is ``CV_HOUGH_GRADIENT`` , which is basically *21HT* , described in [Yuen90]_. + + :param dp: Inverse ratio of the accumulator resolution to the image resolution. For example, if ``dp=1`` , the accumulator has the same resolution as the input image. If ``dp=2`` , the accumulator has half as big width and height. + + :param minDist: Minimum distance between the centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed. + + :param param1: First method-specific parameter. In case of ``CV_HOUGH_GRADIENT`` , it is the higher threshold of the two passed to the :ocv:func:`Canny` edge detector (the lower one is twice smaller). + + :param param2: Second method-specific parameter. In case of ``CV_HOUGH_GRADIENT`` , it is the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first. + + :param minRadius: Minimum circle radius. + + :param maxRadius: Maximum circle radius. + +The function finds circles in a grayscale image using a modification of the Hough transform. + +Example: :: + + #include + #include + #include + + using namespace cv; + + int main(int argc, char** argv) + { + Mat img, gray; + if( argc != 2 && !(img=imread(argv[1], 1)).data) + return -1; + cvtColor(img, gray, CV_BGR2GRAY); + // smooth it, otherwise a lot of false circles may be detected + GaussianBlur( gray, gray, Size(9, 9), 2, 2 ); + vector circles; + HoughCircles(gray, circles, CV_HOUGH_GRADIENT, + 2, gray->rows/4, 200, 100 ); + for( size_t i = 0; i < circles.size(); i++ ) + { + Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); + int radius = cvRound(circles[i][2]); + // draw the circle center + circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 ); + // draw the circle outline + circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 ); + } + namedWindow( "circles", 1 ); + imshow( "circles", img ); + return 0; + } + +.. note:: Usually the function detects the centers of circles well. However, it may fail to find correct radii. You can assist to the function by specifying the radius range ( ``minRadius`` and ``maxRadius`` ) if you know it. Or, you may ignore the returned radius, use only the center, and find the correct radius using an additional procedure. + +.. seealso:: + + :ocv:func:`fitEllipse`, + :ocv:func:`minEnclosingCircle` + + +HoughLines +---------- +Finds lines in a binary image using the standard Hough transform. + +.. ocv:function:: void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 ) + +.. ocv:pyfunction:: cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn]]]) -> lines + +.. ocv:cfunction:: CvSeq* cvHoughLines2( CvArr* image, void* line_storage, int method, double rho, double theta, int threshold, double param1=0, double param2=0 ) + +.. ocv:pyoldfunction:: cv.HoughLines2(image, storage, method, rho, theta, threshold, param1=0, param2=0)-> lines + + :param image: 8-bit, single-channel binary source image. The image may be modified by the function. + + :param lines: Output vector of lines. Each line is represented by a two-element vector :math:`(\rho, \theta)` . :math:`\rho` is the distance from the coordinate origin :math:`(0,0)` (top-left corner of the image). :math:`\theta` is the line rotation angle in radians ( :math:`0 \sim \textrm{vertical line}, \pi/2 \sim \textrm{horizontal line}` ). + + :param rho: Distance resolution of the accumulator in pixels. + + :param theta: Angle resolution of the accumulator in radians. + + :param threshold: Accumulator threshold parameter. Only those lines are returned that get enough votes ( :math:`>\texttt{threshold}` ). + + :param srn: For the multi-scale Hough transform, it is a divisor for the distance resolution ``rho`` . The coarse accumulator distance resolution is ``rho`` and the accurate accumulator resolution is ``rho/srn`` . If both ``srn=0`` and ``stn=0`` , the classical Hough transform is used. Otherwise, both these parameters should be positive. + + :param stn: For the multi-scale Hough transform, it is a divisor for the distance resolution ``theta``. + + :param method: One of the following Hough transform variants: + + * **CV_HOUGH_STANDARD** classical or standard Hough transform. Every line is represented by two floating-point numbers :math:`(\rho, \theta)` , where :math:`\rho` is a distance between (0,0) point and the line, and :math:`\theta` is the angle between x-axis and the normal to the line. Thus, the matrix must be (the created sequence will be) of ``CV_32FC2`` type + + + * **CV_HOUGH_PROBABILISTIC** probabilistic Hough transform (more efficient in case if the picture contains a few long linear segments). It returns line segments rather than the whole line. Each segment is represented by starting and ending points, and the matrix must be (the created sequence will be) of the ``CV_32SC4`` type. + + * **CV_HOUGH_MULTI_SCALE** multi-scale variant of the classical Hough transform. The lines are encoded the same way as ``CV_HOUGH_STANDARD``. + + + :param param1: First method-dependent parameter: + + * For the classical Hough transform, it is not used (0). + + * For the probabilistic Hough transform, it is the minimum line length. + + * For the multi-scale Hough transform, it is ``srn``. + + :param param2: Second method-dependent parameter: + + * For the classical Hough transform, it is not used (0). + + * For the probabilistic Hough transform, it is the maximum gap between line segments lying on the same line to treat them as a single line segment (that is, to join them). + + * For the multi-scale Hough transform, it is ``stn``. + +The function implements the standard or standard multi-scale Hough transform algorithm for line detection. See http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm for a good explanation of Hough transform. +See also the example in :ocv:func:`HoughLinesP` description. + +HoughLinesP +----------- +Finds line segments in a binary image using the probabilistic Hough transform. + +.. ocv:function:: void HoughLinesP( InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 ) + +.. ocv:pyfunction:: cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]) -> lines + + :param image: 8-bit, single-channel binary source image. The image may be modified by the function. + + :param lines: Output vector of lines. Each line is represented by a 4-element vector :math:`(x_1, y_1, x_2, y_2)` , where :math:`(x_1,y_1)` and :math:`(x_2, y_2)` are the ending points of each detected line segment. + + :param rho: Distance resolution of the accumulator in pixels. + + :param theta: Angle resolution of the accumulator in radians. + + :param threshold: Accumulator threshold parameter. Only those lines are returned that get enough votes ( :math:`>\texttt{threshold}` ). + + :param minLineLength: Minimum line length. Line segments shorter than that are rejected. + + :param maxLineGap: Maximum allowed gap between points on the same line to link them. + +The function implements the probabilistic Hough transform algorithm for line detection, described in +[Matas00]_. See the line detection example below: :: + + /* This is a standalone program. Pass an image name as the first parameter + of the program. Switch between standard and probabilistic Hough transform + by changing "#if 1" to "#if 0" and back */ + #include + #include + #include + + using namespace cv; + + int main(int argc, char** argv) + { + Mat src, dst, color_dst; + if( argc != 2 || !(src=imread(argv[1], 0)).data) + return -1; + + Canny( src, dst, 50, 200, 3 ); + cvtColor( dst, color_dst, CV_GRAY2BGR ); + + #if 0 + vector lines; + HoughLines( dst, lines, 1, CV_PI/180, 100 ); + + for( size_t i = 0; i < lines.size(); i++ ) + { + float rho = lines[i][0]; + float theta = lines[i][1]; + double a = cos(theta), b = sin(theta); + double x0 = a*rho, y0 = b*rho; + Point pt1(cvRound(x0 + 1000*(-b)), + cvRound(y0 + 1000*(a))); + Point pt2(cvRound(x0 - 1000*(-b)), + cvRound(y0 - 1000*(a))); + line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 ); + } + #else + vector lines; + HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 ); + for( size_t i = 0; i < lines.size(); i++ ) + { + line( color_dst, Point(lines[i][0], lines[i][1]), + Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 ); + } + #endif + namedWindow( "Source", 1 ); + imshow( "Source", src ); + + namedWindow( "Detected Lines", 1 ); + imshow( "Detected Lines", color_dst ); + + waitKey(0); + return 0; + } + +This is a sample picture the function parameters have been tuned for: + +.. image:: pics/building.jpg + +And this is the output of the above program in case of the probabilistic Hough transform: + +.. image:: pics/houghp.png + + + +preCornerDetect +--------------- +Calculates a feature map for corner detection. + +.. ocv:function:: void preCornerDetect( InputArray src, OutputArray dst, int ksize, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.preCornerDetect(src, ksize[, dst[, borderType]]) -> dst + +.. ocv:cfunction:: void cvPreCornerDetect( const CvArr* image, CvArr* corners, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.PreCornerDetect(image, corners, apertureSize=3)-> None + + :param src: Source single-channel 8-bit of floating-point image. + + :param dst: Output image that has the type ``CV_32F`` and the same size as ``src`` . + + :param ksize: Aperture size of the :ocv:func:`Sobel` . + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` . + +The function calculates the complex spatial derivative-based function of the source image + +.. math:: + + \texttt{dst} = (D_x \texttt{src} )^2 \cdot D_{yy} \texttt{src} + (D_y \texttt{src} )^2 \cdot D_{xx} \texttt{src} - 2 D_x \texttt{src} \cdot D_y \texttt{src} \cdot D_{xy} \texttt{src} + +where +:math:`D_x`,:math:`D_y` are the first image derivatives, +:math:`D_{xx}`,:math:`D_{yy}` are the second image derivatives, and +:math:`D_{xy}` is the mixed derivative. + +The corners can be found as local maximums of the functions, as shown below: :: + + Mat corners, dilated_corners; + preCornerDetect(image, corners, 3); + // dilation with 3x3 rectangular structuring element + dilate(corners, dilated_corners, Mat(), 1); + Mat corner_mask = corners == dilated_corners; + +.. [Canny86] J. Canny. *A Computational Approach to Edge Detection*, IEEE Trans. on Pattern Analysis and Machine Intelligence, 8(6), pp. 679-698 (1986). + +.. [Matas00] Matas, J. and Galambos, C. and Kittler, J.V., *Robust Detection of Lines Using the Progressive Probabilistic Hough Transform*. CVIU 78 1, pp 119-137 (2000) + +.. [Shi94] J. Shi and C. Tomasi. *Good Features to Track*. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994. + +.. [Yuen90] Yuen, H. K. and Princen, J. and Illingworth, J. and Kittler, J., *Comparative study of Hough transform methods for circle finding*. Image Vision Comput. 8 1, pp 71–77 (1990) diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/filtering.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/filtering.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/filtering.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/filtering.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1624 @@ +Image Filtering +=============== + +.. highlight:: cpp + +Functions and classes described in this section are used to perform various linear or non-linear filtering operations on 2D images (represented as +:ocv:func:`Mat`'s). It means that for each pixel location +:math:`(x,y)` in the source image (normally, rectangular), its neighborhood is considered and used to compute the response. In case of a linear filter, it is a weighted sum of pixel values. In case of morphological operations, it is the minimum or maximum values, and so on. The computed response is stored in the destination image at the same location +:math:`(x,y)` . It means that the output image will be of the same size as the input image. Normally, the functions support multi-channel arrays, in which case every channel is processed independently. Therefore, the output image will also have the same number of channels as the input one. + +Another common feature of the functions and classes described in this section is that, unlike simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For example, if you want to smooth an image using a Gaussian +:math:`3 \times 3` filter, then, when processing the left-most pixels in each row, you need pixels to the left of them, that is, outside of the image. You can let these pixels be the same as the left-most image pixels ("replicated border" extrapolation method), or assume that all the non-existing pixels are zeros ("constant border" extrapolation method), and so on. +OpenCV enables you to specify the extrapolation method. For details, see the function :ocv:func:`borderInterpolate` and discussion of the ``borderType`` parameter in the section and various functions below. :: + + /* + Various border types, image boundaries are denoted with '|' + + * BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh + * BORDER_REFLECT: fedcba|abcdefgh|hgfedcb + * BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba + * BORDER_WRAP: cdefgh|abcdefgh|abcdefg + * BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i' + */ + +BaseColumnFilter +---------------- +.. ocv:class:: BaseColumnFilter + +Base class for filters with single-column kernels. :: + + class BaseColumnFilter + { + public: + virtual ~BaseColumnFilter(); + + // To be overriden by the user. + // + // runs a filtering operation on the set of rows, + // "dstcount + ksize - 1" rows on input, + // "dstcount" rows on output, + // each input and output row has "width" elements + // the filtered rows are written into "dst" buffer. + virtual void operator()(const uchar** src, uchar* dst, int dststep, + int dstcount, int width) = 0; + // resets the filter state (may be needed for IIR filters) + virtual void reset(); + + int ksize; // the aperture size + int anchor; // position of the anchor point, + // normally not used during the processing + }; + + +The class ``BaseColumnFilter`` is a base class for filtering data using single-column kernels. Filtering does not have to be a linear operation. In general, it could be written as follows: + +.. math:: + + \texttt{dst} (x,y) = F( \texttt{src} [y](x), \; \texttt{src} [y+1](x), \; ..., \; \texttt{src} [y+ \texttt{ksize} -1](x) + +where +:math:`F` is a filtering function but, as it is represented as a class, it can produce any side effects, memorize previously processed data, and so on. The class only defines an interface and is not used directly. Instead, there are several functions in OpenCV (and you can add more) that return pointers to the derived classes that implement specific filtering operations. Those pointers are then passed to the +:ocv:class:`FilterEngine` constructor. While the filtering operation interface uses the ``uchar`` type, a particular implementation is not limited to 8-bit data. + +.. seealso:: + + :ocv:class:`BaseRowFilter`, + :ocv:class:`BaseFilter`, + :ocv:class:`FilterEngine`, + :ocv:func:`getColumnSumFilter`, + :ocv:func:`getLinearColumnFilter`, + :ocv:func:`getMorphologyColumnFilter` + + +BaseFilter +---------- +.. ocv:class:: BaseFilter + +Base class for 2D image filters. :: + + class BaseFilter + { + public: + virtual ~BaseFilter(); + + // To be overriden by the user. + // + // runs a filtering operation on the set of rows, + // "dstcount + ksize.height - 1" rows on input, + // "dstcount" rows on output, + // each input row has "(width + ksize.width-1)*cn" elements + // each output row has "width*cn" elements. + // the filtered rows are written into "dst" buffer. + virtual void operator()(const uchar** src, uchar* dst, int dststep, + int dstcount, int width, int cn) = 0; + // resets the filter state (may be needed for IIR filters) + virtual void reset(); + Size ksize; + Point anchor; + }; + + +The class ``BaseFilter`` is a base class for filtering data using 2D kernels. Filtering does not have to be a linear operation. In general, it could be written as follows: + +.. math:: + + \begin{array}{l} \texttt{dst} (x,y) = F( \texttt{src} [y](x), \; \texttt{src} [y](x+1), \; ..., \; \texttt{src} [y](x+ \texttt{ksize.width} -1), \\ \texttt{src} [y+1](x), \; \texttt{src} [y+1](x+1), \; ..., \; \texttt{src} [y+1](x+ \texttt{ksize.width} -1), \\ ......................................................................................... \\ \texttt{src} [y+ \texttt{ksize.height-1} ](x), \\ \texttt{src} [y+ \texttt{ksize.height-1} ](x+1), \\ ... + \texttt{src} [y+ \texttt{ksize.height-1} ](x+ \texttt{ksize.width} -1)) + \end{array} + +where +:math:`F` is a filtering function. The class only defines an interface and is not used directly. Instead, there are several functions in OpenCV (and you can add more) that return pointers to the derived classes that implement specific filtering operations. Those pointers are then passed to the +:ocv:class:`FilterEngine` constructor. While the filtering operation interface uses the ``uchar`` type, a particular implementation is not limited to 8-bit data. + +.. seealso:: + + :ocv:class:`BaseColumnFilter`, + :ocv:class:`BaseRowFilter`, + :ocv:class:`FilterEngine`, + :ocv:func:`getLinearFilter`, + :ocv:func:`getMorphologyFilter` + + + +BaseRowFilter +------------- +.. ocv:class:: BaseRowFilter + +Base class for filters with single-row kernels. :: + + class BaseRowFilter + { + public: + virtual ~BaseRowFilter(); + + // To be overriden by the user. + // + // runs filtering operation on the single input row + // of "width" element, each element is has "cn" channels. + // the filtered row is written into "dst" buffer. + virtual void operator()(const uchar* src, uchar* dst, + int width, int cn) = 0; + int ksize, anchor; + }; + + +The class ``BaseRowFilter`` is a base class for filtering data using single-row kernels. Filtering does not have to be a linear operation. In general, it could be written as follows: + +.. math:: + + \texttt{dst} (x,y) = F( \texttt{src} [y](x), \; \texttt{src} [y](x+1), \; ..., \; \texttt{src} [y](x+ \texttt{ksize.width} -1)) + +where +:math:`F` is a filtering function. The class only defines an interface and is not used directly. Instead, there are several functions in OpenCV (and you can add more) that return pointers to the derived classes that implement specific filtering operations. Those pointers are then passed to the +:ocv:class:`FilterEngine` constructor. While the filtering operation interface uses the ``uchar`` type, a particular implementation is not limited to 8-bit data. + +.. seealso:: + + :ocv:class:`BaseColumnFilter`, + :ocv:class:`BaseFilter`, + :ocv:class:`FilterEngine`, + :ocv:func:`getLinearRowFilter`, + :ocv:func:`getMorphologyRowFilter`, + :ocv:func:`getRowSumFilter` + + + +FilterEngine +------------ +.. ocv:class:: FilterEngine + +Generic image filtering class. :: + + class FilterEngine + { + public: + // empty constructor + FilterEngine(); + // builds a 2D non-separable filter (!_filter2D.empty()) or + // a separable filter (!_rowFilter.empty() && !_columnFilter.empty()) + // the input data type will be "srcType", the output data type will be "dstType", + // the intermediate data type is "bufType". + // _rowBorderType and _columnBorderType determine how the image + // will be extrapolated beyond the image boundaries. + // _borderValue is only used when _rowBorderType and/or _columnBorderType + // == BORDER_CONSTANT + FilterEngine(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType=BORDER_REPLICATE, + int _columnBorderType=-1, // use _rowBorderType by default + const Scalar& _borderValue=Scalar()); + virtual ~FilterEngine(); + // separate function for the engine initialization + void init(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1, + const Scalar& _borderValue=Scalar()); + // starts filtering of the ROI in an image of size "wholeSize". + // returns the starting y-position in the source image. + virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1); + // alternative form of start that takes the image + // itself instead of "wholeSize". Set isolated to true to pretend that + // there are no real pixels outside of the ROI + // (so that the pixels are extrapolated using the specified border modes) + virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1), + bool isolated=false, int maxBufRows=-1); + // processes the next portion of the source image, + // "srcCount" rows starting from "src" and + // stores the results in "dst". + // returns the number of produced rows + virtual int proceed(const uchar* src, int srcStep, int srcCount, + uchar* dst, int dstStep); + // higher-level function that processes the whole + // ROI or the whole image with a single call + virtual void apply( const Mat& src, Mat& dst, + const Rect& srcRoi=Rect(0,0,-1,-1), + Point dstOfs=Point(0,0), + bool isolated=false); + bool isSeparable() const { return filter2D.empty(); } + // how many rows from the input image are not yet processed + int remainingInputRows() const; + // how many output rows are not yet produced + int remainingOutputRows() const; + ... + // the starting and the ending rows in the source image + int startY, endY; + + // pointers to the filters + Ptr filter2D; + Ptr rowFilter; + Ptr columnFilter; + }; + + +The class ``FilterEngine`` can be used to apply an arbitrary filtering operation to an image. +It contains all the necessary intermediate buffers, computes extrapolated values +of the "virtual" pixels outside of the image, and so on. Pointers to the initialized ``FilterEngine`` instances +are returned by various ``create*Filter`` functions (see below) and they are used inside high-level functions such as +:ocv:func:`filter2D`, +:ocv:func:`erode`, +:ocv:func:`dilate`, and others. Thus, the class plays a key role in many of OpenCV filtering functions. + +This class makes it easier to combine filtering operations with other operations, such as color space conversions, thresholding, arithmetic operations, and others. By combining several operations together you can get much better performance because your data will stay in cache. For example, see below the implementation of the Laplace operator for floating-point images, which is a simplified implementation of +:ocv:func:`Laplacian` : :: + + void laplace_f(const Mat& src, Mat& dst) + { + CV_Assert( src.type() == CV_32F ); + dst.create(src.size(), src.type()); + + // get the derivative and smooth kernels for d2I/dx2. + // for d2I/dy2 consider using the same kernels, just swapped + Mat kd, ks; + getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); + + // process 10 source rows at once + int DELTA = std::min(10, src.rows); + Ptr Fxx = createSeparableLinearFilter(src.type(), + dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); + Ptr Fyy = createSeparableLinearFilter(src.type(), + dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); + + int y = Fxx->start(src), dsty = 0, dy = 0; + Fyy->start(src); + const uchar* sptr = src.data + y*src.step; + + // allocate the buffers for the spatial image derivatives; + // the buffers need to have more than DELTA rows, because at the + // last iteration the output may take max(kd.rows-1,ks.rows-1) + // rows more than the input. + Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() ); + Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() ); + + // inside the loop always pass DELTA rows to the filter + // (note that the "proceed" method takes care of possibe overflow, since + // it was given the actual image height in the "start" method) + // on output you can get: + // * < DELTA rows (initial buffer accumulation stage) + // * = DELTA rows (settled state in the middle) + // * > DELTA rows (when the input image is over, generate + // "virtual" rows using the border mode and filter them) + // this variable number of output rows is dy. + // dsty is the current output row. + // sptr is the pointer to the first input row in the portion to process + for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy ) + { + Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step ); + dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step ); + if( dy > 0 ) + { + Mat dstripe = dst.rowRange(dsty, dsty + dy); + add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe); + } + } + } + + +If you do not need that much control of the filtering process, you can simply use the ``FilterEngine::apply`` method. The method is implemented as follows: :: + + void FilterEngine::apply(const Mat& src, Mat& dst, + const Rect& srcRoi, Point dstOfs, bool isolated) + { + // check matrix types + CV_Assert( src.type() == srcType && dst.type() == dstType ); + + // handle the "whole image" case + Rect _srcRoi = srcRoi; + if( _srcRoi == Rect(0,0,-1,-1) ) + _srcRoi = Rect(0,0,src.cols,src.rows); + + // check if the destination ROI is inside dst. + // and FilterEngine::start will check if the source ROI is inside src. + CV_Assert( dstOfs.x >= 0 && dstOfs.y >= 0 && + dstOfs.x + _srcRoi.width <= dst.cols && + dstOfs.y + _srcRoi.height <= dst.rows ); + + // start filtering + int y = start(src, _srcRoi, isolated); + + // process the whole ROI. Note that "endY - startY" is the total number + // of the source rows to process + // (including the possible rows outside of srcRoi but inside the source image) + proceed( src.data + y*src.step, + (int)src.step, endY - startY, + dst.data + dstOfs.y*dst.step + + dstOfs.x*dst.elemSize(), (int)dst.step ); + } + + +Unlike the earlier versions of OpenCV, now the filtering operations fully support the notion of image ROI, that is, pixels outside of the ROI but inside the image can be used in the filtering operations. For example, you can take a ROI of a single pixel and filter it. This will be a filter response at that particular pixel. However, it is possible to emulate the old behavior by passing ``isolated=false`` to ``FilterEngine::start`` or ``FilterEngine::apply`` . You can pass the ROI explicitly to ``FilterEngine::apply`` or construct new matrix headers: :: + + // compute dI/dx derivative at src(x,y) + + // method 1: + // form a matrix header for a single value + float val1 = 0; + Mat dst1(1,1,CV_32F,&val1); + + Ptr Fx = createDerivFilter(CV_32F, CV_32F, + 1, 0, 3, BORDER_REFLECT_101); + Fx->apply(src, Rect(x,y,1,1), Point(), dst1); + + // method 2: + // form a matrix header for a single value + float val2 = 0; + Mat dst2(1,1,CV_32F,&val2); + + Mat pix_roi(src, Rect(x,y,1,1)); + Sobel(pix_roi, dst2, dst2.type(), 1, 0, 3, 1, 0, BORDER_REFLECT_101); + + printf("method1 = + + +Explore the data types. As it was mentioned in the +:ocv:class:`BaseFilter` description, the specific filters can process data of any type, despite that ``Base*Filter::operator()`` only takes ``uchar`` pointers and no information about the actual types. To make it all work, the following rules are used: + +* + In case of separable filtering, ``FilterEngine::rowFilter`` is applied first. It transforms the input image data (of type ``srcType`` ) to the intermediate results stored in the internal buffers (of type ``bufType`` ). Then, these intermediate results are processed as + *single-channel data* + with ``FilterEngine::columnFilter`` and stored in the output image (of type ``dstType`` ). Thus, the input type for ``rowFilter`` is ``srcType`` and the output type is ``bufType`` . The input type for ``columnFilter`` is ``CV_MAT_DEPTH(bufType)`` and the output type is ``CV_MAT_DEPTH(dstType)`` . + +* + In case of non-separable filtering, ``bufType`` must be the same as ``srcType`` . The source data is copied to the temporary buffer, if needed, and then just passed to ``FilterEngine::filter2D`` . That is, the input type for ``filter2D`` is ``srcType`` (= ``bufType`` ) and the output type is ``dstType`` . + +.. seealso:: + + :ocv:class:`BaseColumnFilter`, + :ocv:class:`BaseFilter`, + :ocv:class:`BaseRowFilter`, + :ocv:func:`createBoxFilter`, + :ocv:func:`createDerivFilter`, + :ocv:func:`createGaussianFilter`, + :ocv:func:`createLinearFilter`, + :ocv:func:`createMorphologyFilter`, + :ocv:func:`createSeparableLinearFilter` + + + +bilateralFilter +------------------- +Applies the bilateral filter to an image. + +.. ocv:function:: void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) -> dst + + :param src: Source 8-bit or floating-point, 1-channel or 3-channel image. + + :param dst: Destination image of the same size and type as ``src`` . + + :param d: Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed from ``sigmaSpace`` . + + :param sigmaColor: Filter sigma in the color space. A larger value of the parameter means that farther colors within the pixel neighborhood (see ``sigmaSpace`` ) will be mixed together, resulting in larger areas of semi-equal color. + + :param sigmaSpace: Filter sigma in the coordinate space. A larger value of the parameter means that farther pixels will influence each other as long as their colors are close enough (see ``sigmaColor`` ). When ``d>0`` , it specifies the neighborhood size regardless of ``sigmaSpace`` . Otherwise, ``d`` is proportional to ``sigmaSpace`` . + +The function applies bilateral filtering to the input image, as described in +http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html +``bilateralFilter`` can reduce unwanted noise very well while keeping edges fairly sharp. However, it is very slow compared to most filters. + +*Sigma values*: For simplicity, you can set the 2 sigma values to be the same. If they are small (< 10), the filter will not have much effect, whereas if they are large (> 150), they will have a very strong effect, making the image look "cartoonish". + +*Filter size*: Large filters (d > 5) are very slow, so it is recommended to use d=5 for real-time applications, and perhaps d=9 for offline applications that need heavy noise filtering. + +This filter does not work inplace. + + + + +blur +---- +Blurs an image using the normalized box filter. + +.. ocv:function:: void blur( InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.blur(src, ksize[, dst[, anchor[, borderType]]]) -> dst + + :param src: input image; it can have any number of channels, which are processed independently, but the depth should be ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F`` or ``CV_64F``. + + :param dst: output image of the same size and type as ``src``. + + :param ksize: blurring kernel size. + + :param anchor: anchor point; default value ``Point(-1,-1)`` means that the anchor is at the kernel center. + + :param borderType: border mode used to extrapolate pixels outside of the image. + +The function smoothes an image using the kernel: + +.. math:: + + \texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix} + +The call ``blur(src, dst, ksize, anchor, borderType)`` is equivalent to ``boxFilter(src, dst, src.type(), anchor, true, borderType)`` . + +.. seealso:: + + :ocv:func:`boxFilter`, + :ocv:func:`bilateralFilter`, + :ocv:func:`GaussianBlur`, + :ocv:func:`medianBlur` + + +borderInterpolate +----------------- +Computes the source location of an extrapolated pixel. + +.. ocv:function:: int borderInterpolate( int p, int len, int borderType ) + +.. ocv:pyfunction:: cv2.borderInterpolate(p, len, borderType) -> retval + + :param p: 0-based coordinate of the extrapolated pixel along one of the axes, likely <0 or >= ``len`` . + + :param len: Length of the array along the corresponding axis. + + :param borderType: Border type, one of the ``BORDER_*`` , except for ``BORDER_TRANSPARENT`` and ``BORDER_ISOLATED`` . When ``borderType==BORDER_CONSTANT`` , the function always returns -1, regardless of ``p`` and ``len`` . + +The function computes and returns the coordinate of a donor pixel corresponding to the specified extrapolated pixel when using the specified extrapolation border mode. For example, if you use ``BORDER_WRAP`` mode in the horizontal direction, ``BORDER_REFLECT_101`` in the vertical direction and want to compute value of the "virtual" pixel ``Point(-5, 100)`` in a floating-point image ``img`` , it looks like: :: + + float val = img.at(borderInterpolate(100, img.rows, BORDER_REFLECT_101), + borderInterpolate(-5, img.cols, BORDER_WRAP)); + + +Normally, the function is not called directly. It is used inside +:ocv:class:`FilterEngine` and +:ocv:func:`copyMakeBorder` to compute tables for quick extrapolation. + +.. seealso:: + + :ocv:class:`FilterEngine`, + :ocv:func:`copyMakeBorder` + + + +boxFilter +--------- +Blurs an image using the box filter. + +.. ocv:function:: void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]]) -> dst + + :param src: input image. + + :param dst: output image of the same size and type as ``src``. + + :param ddepth: the output image depth (-1 to use ``src.depth()``). + + :param ksize: blurring kernel size. + + :param anchor: anchor point; default value ``Point(-1,-1)`` means that the anchor is at the kernel center. + + :param normalize: flag, specifying whether the kernel is normalized by its area or not. + + :param borderType: border mode used to extrapolate pixels outside of the image. + +The function smoothes an image using the kernel: + +.. math:: + + \texttt{K} = \alpha \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix} + +where + +.. math:: + + \alpha = \fork{\frac{1}{\texttt{ksize.width*ksize.height}}}{when \texttt{normalize=true}}{1}{otherwise} + +Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives (used in dense optical flow algorithms, and so on). If you need to compute pixel sums over variable-size windows, use :ocv:func:`integral` . + +.. seealso:: + + :ocv:func:`blur`, + :ocv:func:`bilateralFilter`, + :ocv:func:`GaussianBlur`, + :ocv:func:`medianBlur`, + :ocv:func:`integral` + + + +buildPyramid +------------ +Constructs the Gaussian pyramid for an image. + +.. ocv:function:: void buildPyramid( InputArray src, OutputArrayOfArrays dst, int maxlevel, int borderType=BORDER_DEFAULT ) + + :param src: Source image. Check :ocv:func:`pyrDown` for the list of supported types. + + :param dst: Destination vector of ``maxlevel+1`` images of the same type as ``src`` . ``dst[0]`` will be the same as ``src`` . ``dst[1]`` is the next pyramid layer, a smoothed and down-sized ``src`` , and so on. + + :param maxlevel: 0-based index of the last (the smallest) pyramid layer. It must be non-negative. + +The function constructs a vector of images and builds the Gaussian pyramid by recursively applying +:ocv:func:`pyrDown` to the previously built pyramid layers, starting from ``dst[0]==src`` . + + + +copyMakeBorder +-------------- +Forms a border around an image. + +.. ocv:function:: void copyMakeBorder( InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value=Scalar() ) + +.. ocv:pyfunction:: cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) -> dst + +.. ocv:cfunction:: void cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset, int bordertype, CvScalar value=cvScalarAll(0) ) +.. ocv:pyoldfunction:: cv.CopyMakeBorder(src, dst, offset, bordertype, value=(0, 0, 0, 0))-> None + + :param src: Source image. + + :param dst: Destination image of the same type as ``src`` and the size ``Size(src.cols+left+right, src.rows+top+bottom)`` . + + :param top: + + :param bottom: + + :param left: + + :param right: Parameter specifying how many pixels in each direction from the source image rectangle to extrapolate. For example, ``top=1, bottom=1, left=1, right=1`` mean that 1 pixel-wide border needs to be built. + + :param borderType: Border type. See :ocv:func:`borderInterpolate` for details. + + :param value: Border value if ``borderType==BORDER_CONSTANT`` . + +The function copies the source image into the middle of the destination image. The areas to the left, to the right, above and below the copied source image will be filled with extrapolated pixels. This is not what +:ocv:class:`FilterEngine` or filtering functions based on it do (they extrapolate pixels on-fly), but what other more complex functions, including your own, may do to simplify image boundary handling. + +The function supports the mode when ``src`` is already in the middle of ``dst`` . In this case, the function does not copy ``src`` itself but simply constructs the border, for example: :: + + // let border be the same in all directions + int border=2; + // constructs a larger image to fit both the image and the border + Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth()); + // select the middle part of it w/o copying data + Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows)); + // convert image from RGB to grayscale + cvtColor(rgb, gray, CV_RGB2GRAY); + // form a border in-place + copyMakeBorder(gray, gray_buf, border, border, + border, border, BORDER_REPLICATE); + // now do some custom filtering ... + ... + + +.. note:: + + When the source image is a part (ROI) of a bigger image, the function will try to use the pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as if ``src`` was not a ROI, use ``borderType | BORDER_ISOLATED``. + +.. seealso:: + + :ocv:func:`borderInterpolate` + + +createBoxFilter +------------------- +Returns a box filter engine. + +.. ocv:function:: Ptr createBoxFilter( int srcType, int dstType, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT) + +.. ocv:function:: Ptr getRowSumFilter(int srcType, int sumType, int ksize, int anchor=-1) + +.. ocv:function:: Ptr getColumnSumFilter(int sumType, int dstType, int ksize, int anchor=-1, double scale=1) + + :param srcType: Source image type. + + :param sumType: Intermediate horizontal sum type that must have as many channels as ``srcType`` . + + :param dstType: Destination image type that must have as many channels as ``srcType`` . + + :param ksize: Aperture size. + + :param anchor: Anchor position with the kernel. Negative values mean that the anchor is at the kernel center. + + :param normalize: Flag specifying whether the sums are normalized or not. See :ocv:func:`boxFilter` for details. + + :param scale: Another way to specify normalization in lower-level ``getColumnSumFilter`` . + + :param borderType: Border type to use. See :ocv:func:`borderInterpolate` . + +The function is a convenience function that retrieves the horizontal sum primitive filter with +:ocv:func:`getRowSumFilter` , vertical sum filter with +:ocv:func:`getColumnSumFilter` , constructs new +:ocv:class:`FilterEngine` , and passes both of the primitive filters there. The constructed filter engine can be used for image filtering with normalized or unnormalized box filter. + +The function itself is used by +:ocv:func:`blur` and +:ocv:func:`boxFilter` . + +.. seealso:: + + :ocv:class:`FilterEngine`, + :ocv:func:`blur`, + :ocv:func:`boxFilter` + + + +createDerivFilter +--------------------- +Returns an engine for computing image derivatives. + +.. ocv:function:: Ptr createDerivFilter( int srcType, int dstType, int dx, int dy, int ksize, int borderType=BORDER_DEFAULT ) + + :param srcType: Source image type. + + :param dstType: Destination image type that must have as many channels as ``srcType`` . + + :param dx: Derivative order in respect of x. + + :param dy: Derivative order in respect of y. + + :param ksize: Aperture size See :ocv:func:`getDerivKernels` . + + :param borderType: Border type to use. See :ocv:func:`borderInterpolate` . + +The function :ocv:func:`createDerivFilter` is a small convenience function that retrieves linear filter coefficients for computing image derivatives using +:ocv:func:`getDerivKernels` and then creates a separable linear filter with +:ocv:func:`createSeparableLinearFilter` . The function is used by +:ocv:func:`Sobel` and +:ocv:func:`Scharr` . + +.. seealso:: + + :ocv:func:`createSeparableLinearFilter`, + :ocv:func:`getDerivKernels`, + :ocv:func:`Scharr`, + :ocv:func:`Sobel` + + + +createGaussianFilter +------------------------ +Returns an engine for smoothing images with the Gaussian filter. + +.. ocv:function:: Ptr createGaussianFilter( int type, Size ksize, double sigma1, double sigma2=0, int borderType=BORDER_DEFAULT ) + + :param type: Source and destination image type. + + :param ksize: Aperture size. See :ocv:func:`getGaussianKernel` . + + :param sigma1: Gaussian sigma in the horizontal direction. See :ocv:func:`getGaussianKernel` . + + :param sigma2: Gaussian sigma in the vertical direction. If 0, then :math:`\texttt{sigma2}\leftarrow\texttt{sigma1}` . + + :param borderType: Border type to use. See :ocv:func:`borderInterpolate` . + +The function :ocv:func:`createGaussianFilter` computes Gaussian kernel coefficients and then returns a separable linear filter for that kernel. The function is used by +:ocv:func:`GaussianBlur` . Note that while the function takes just one data type, both for input and output, you can pass this limitation by calling +:ocv:func:`getGaussianKernel` and then +:ocv:func:`createSeparableLinearFilter` directly. + +.. seealso:: + + :ocv:func:`createSeparableLinearFilter`, + :ocv:func:`getGaussianKernel`, + :ocv:func:`GaussianBlur` + + + +createLinearFilter +---------------------- +Creates a non-separable linear filter engine. + +.. ocv:function:: Ptr createLinearFilter( int srcType, int dstType, InputArray kernel, Point _anchor=Point(-1,-1), double delta=0, int rowBorderType=BORDER_DEFAULT, int columnBorderType=-1, const Scalar& borderValue=Scalar() ) + +.. ocv:function:: Ptr getLinearFilter(int srcType, int dstType, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int bits=0) + + :param srcType: Source image type. + + :param dstType: Destination image type that must have as many channels as ``srcType`` . + + :param kernel: 2D array of filter coefficients. + + :param anchor: Anchor point within the kernel. Special value ``Point(-1,-1)`` means that the anchor is at the kernel center. + + :param delta: Value added to the filtered results before storing them. + + :param bits: Number of the fractional bits. The parameter is used when the kernel is an integer matrix representing fixed-point filter coefficients. + + :param rowBorderType: Pixel extrapolation method in the vertical direction. For details, see :ocv:func:`borderInterpolate`. + + :param columnBorderType: Pixel extrapolation method in the horizontal direction. + + :param borderValue: Border value used in case of a constant border. + +The function returns a pointer to a 2D linear filter for the specified kernel, the source array type, and the destination array type. The function is a higher-level function that calls ``getLinearFilter`` and passes the retrieved 2D filter to the +:ocv:class:`FilterEngine` constructor. + +.. seealso:: + + :ocv:func:`createSeparableLinearFilter`, + :ocv:class:`FilterEngine`, + :ocv:func:`filter2D` + + +createMorphologyFilter +-------------------------- +Creates an engine for non-separable morphological operations. + +.. ocv:function:: Ptr createMorphologyFilter( int op, int type, InputArray kernel, Point anchor=Point(-1,-1), int rowBorderType=BORDER_CONSTANT, int columnBorderType=-1, const Scalar& borderValue=morphologyDefaultBorderValue() ) + +.. ocv:function:: Ptr getMorphologyFilter( int op, int type, InputArray kernel, Point anchor=Point(-1,-1) ) + +.. ocv:function:: Ptr getMorphologyRowFilter( int op, int type, int ksize, int anchor=-1 ) + +.. ocv:function:: Ptr getMorphologyColumnFilter( int op, int type, int ksize, int anchor=-1 ) + +.. ocv:function:: Scalar morphologyDefaultBorderValue() + + :param op: Morphology operation ID, ``MORPH_ERODE`` or ``MORPH_DILATE`` . + + :param type: Input/output image type. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``. + + :param kernel: 2D 8-bit structuring element for a morphological operation. Non-zero elements indicate the pixels that belong to the element. + + :param ksize: Horizontal or vertical structuring element size for separable morphological operations. + + :param anchor: Anchor position within the structuring element. Negative values mean that the anchor is at the kernel center. + + :param rowBorderType: Pixel extrapolation method in the vertical direction. For details, see :ocv:func:`borderInterpolate`. + + :param columnBorderType: Pixel extrapolation method in the horizontal direction. + + :param borderValue: Border value in case of a constant border. The default value, \ ``morphologyDefaultBorderValue`` , has a special meaning. It is transformed :math:`+\inf` for the erosion and to :math:`-\inf` for the dilation, which means that the minimum (maximum) is effectively computed only over the pixels that are inside the image. + +The functions construct primitive morphological filtering operations or a filter engine based on them. Normally it is enough to use +:ocv:func:`createMorphologyFilter` or even higher-level +:ocv:func:`erode`, +:ocv:func:`dilate` , or +:ocv:func:`morphologyEx` . +Note that +:ocv:func:`createMorphologyFilter` analyzes the structuring element shape and builds a separable morphological filter engine when the structuring element is square. + +.. seealso:: + + :ocv:func:`erode`, + :ocv:func:`dilate`, + :ocv:func:`morphologyEx`, + :ocv:class:`FilterEngine` + + +createSeparableLinearFilter +------------------------------- +Creates an engine for a separable linear filter. + +.. ocv:function:: Ptr createSeparableLinearFilter( int srcType, int dstType, InputArray rowKernel, InputArray columnKernel, Point anchor=Point(-1,-1), double delta=0, int rowBorderType=BORDER_DEFAULT, int columnBorderType=-1, const Scalar& borderValue=Scalar() ) + +.. ocv:function:: Ptr getLinearColumnFilter( int bufType, int dstType, InputArray kernel, int anchor, int symmetryType, double delta=0, int bits=0 ) + +.. ocv:function:: Ptr getLinearRowFilter( int srcType, int bufType, InputArray kernel, int anchor, int symmetryType ) + + :param srcType: Source array type. + + :param dstType: Destination image type that must have as many channels as ``srcType`` . + + :param bufType: Intermediate buffer type that must have as many channels as ``srcType`` . + + :param rowKernel: Coefficients for filtering each row. + + :param columnKernel: Coefficients for filtering each column. + + :param anchor: Anchor position within the kernel. Negative values mean that anchor is positioned at the aperture center. + + :param delta: Value added to the filtered results before storing them. + + :param bits: Number of the fractional bits. The parameter is used when the kernel is an integer matrix representing fixed-point filter coefficients. + + :param rowBorderType: Pixel extrapolation method in the vertical direction. For details, see :ocv:func:`borderInterpolate`. + + :param columnBorderType: Pixel extrapolation method in the horizontal direction. + + :param borderValue: Border value used in case of a constant border. + + :param symmetryType: Type of each row and column kernel. See :ocv:func:`getKernelType` . + +The functions construct primitive separable linear filtering operations or a filter engine based on them. Normally it is enough to use +:ocv:func:`createSeparableLinearFilter` or even higher-level +:ocv:func:`sepFilter2D` . The function +:ocv:func:`createMorphologyFilter` is smart enough to figure out the ``symmetryType`` for each of the two kernels, the intermediate ``bufType`` and, if filtering can be done in integer arithmetics, the number of ``bits`` to encode the filter coefficients. If it does not work for you, it is possible to call ``getLinearColumnFilter``,``getLinearRowFilter`` directly and then pass them to the +:ocv:class:`FilterEngine` constructor. + +.. seealso:: + + :ocv:func:`sepFilter2D`, + :ocv:func:`createLinearFilter`, + :ocv:class:`FilterEngine`, + :ocv:func:`getKernelType` + + +dilate +------ +Dilates an image by using a specific structuring element. + +.. ocv:function:: void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ) + +.. ocv:pyfunction:: cv2.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst + +.. ocv:cfunction:: void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 ) +.. ocv:pyoldfunction:: cv.Dilate(src, dst, element=None, iterations=1)-> None + + :param src: input image; the number of channels can be arbitrary, but the depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``. + + :param dst: output image of the same size and type as ``src``. + + :param element: structuring element used for dilation; if ``element=Mat()`` , a ``3 x 3`` rectangular structuring element is used. + + :param anchor: position of the anchor within the element; default value ``(-1, -1)`` means that the anchor is at the element center. + + :param iterations: number of times dilation is applied. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + + :param borderValue: border value in case of a constant border (see :ocv:func:`createMorphologyFilter` for details). + +The function dilates the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the maximum is taken: + +.. math:: + + \texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y') + +The function supports the in-place mode. Dilation can be applied several ( ``iterations`` ) times. In case of multi-channel images, each channel is processed independently. + +.. seealso:: + + :ocv:func:`erode`, + :ocv:func:`morphologyEx`, + :ocv:func:`createMorphologyFilter` + + +erode +----- +Erodes an image by using a specific structuring element. + +.. ocv:function:: void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ) + +.. ocv:pyfunction:: cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst + +.. ocv:cfunction:: void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1) +.. ocv:pyoldfunction:: cv.Erode(src, dst, element=None, iterations=1)-> None + + :param src: input image; the number of channels can be arbitrary, but the depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``. + + :param dst: output image of the same size and type as ``src``. + + :param element: structuring element used for erosion; if ``element=Mat()`` , a ``3 x 3`` rectangular structuring element is used. + + :param anchor: position of the anchor within the element; default value ``(-1, -1)`` means that the anchor is at the element center. + + :param iterations: number of times erosion is applied. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + + :param borderValue: border value in case of a constant border (see :ocv:func:`createMorphologyFilter` for details). + +The function erodes the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the minimum is taken: + +.. math:: + + \texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y') + +The function supports the in-place mode. Erosion can be applied several ( ``iterations`` ) times. In case of multi-channel images, each channel is processed independently. + +.. seealso:: + + :ocv:func:`dilate`, + :ocv:func:`morphologyEx`, + :ocv:func:`createMorphologyFilter` + + + +filter2D +-------- +Convolves an image with the kernel. + +.. ocv:function:: void filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]) -> dst + +.. ocv:cfunction:: void cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1,-1) ) + +.. ocv:pyoldfunction:: cv.Filter2D(src, dst, kernel, anchor=(-1, -1))-> None + + :param src: input image. + + :param dst: output image of the same size and the same number of channels as ``src``. + + + :param ddepth: desired depth of the destination image; if it is negative, it will be the same as ``src.depth()``; the following combinations of ``src.depth()`` and ``ddepth`` are supported: + * ``src.depth()`` = ``CV_8U``, ``ddepth`` = -1/``CV_16S``/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_16U``/``CV_16S``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_32F``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_64F``, ``ddepth`` = -1/``CV_64F`` + + when ``ddepth=-1``, the output image will have the same depth as the source. + + :param kernel: convolution kernel (or rather a correlation kernel), a single-channel floating point matrix; if you want to apply different kernels to different channels, split the image into separate color planes using :ocv:func:`split` and process them individually. + + :param anchor: anchor of the kernel that indicates the relative position of a filtered point within the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor is at the kernel center. + + :param delta: optional value added to the filtered pixels before storing them in ``dst``. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + +The function applies an arbitrary linear filter to an image. In-place operation is supported. When the aperture is partially outside the image, the function interpolates outlier pixel values according to the specified border mode. + +The function does actually compute correlation, not the convolution: + +.. math:: + + \texttt{dst} (x,y) = \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} } \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} ) + +That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip the kernel using +:ocv:func:`flip` and set the new anchor to ``(kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)`` . + +The function uses the DFT-based algorithm in case of sufficiently large kernels (~``11 x 11`` or larger) and the direct algorithm (that uses the engine retrieved by :ocv:func:`createLinearFilter` ) for small kernels. + +.. seealso:: + + :ocv:func:`sepFilter2D`, + :ocv:func:`createLinearFilter`, + :ocv:func:`dft`, + :ocv:func:`matchTemplate` + + + +GaussianBlur +------------ +Blurs an image using a Gaussian filter. + +.. ocv:function:: void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) -> dst + + :param src: input image; the image can have any number of channels, which are processed independently, but the depth should be ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F`` or ``CV_64F``. + + :param dst: output image of the same size and type as ``src``. + + :param ksize: Gaussian kernel size. ``ksize.width`` and ``ksize.height`` can differ but they both must be positive and odd. Or, they can be zero's and then they are computed from ``sigma*`` . + + :param sigmaX: Gaussian kernel standard deviation in X direction. + + :param sigmaY: Gaussian kernel standard deviation in Y direction; if ``sigmaY`` is zero, it is set to be equal to ``sigmaX``, if both sigmas are zeros, they are computed from ``ksize.width`` and ``ksize.height`` , respectively (see :ocv:func:`getGaussianKernel` for details); to fully control the result regardless of possible future modifications of all this semantics, it is recommended to specify all of ``ksize``, ``sigmaX``, and ``sigmaY``. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + +The function convolves the source image with the specified Gaussian kernel. In-place filtering is supported. + +.. seealso:: + + :ocv:func:`sepFilter2D`, + :ocv:func:`filter2D`, + :ocv:func:`blur`, + :ocv:func:`boxFilter`, + :ocv:func:`bilateralFilter`, + :ocv:func:`medianBlur` + + +getDerivKernels +--------------- +Returns filter coefficients for computing spatial image derivatives. + +.. ocv:function:: void getDerivKernels( OutputArray kx, OutputArray ky, int dx, int dy, int ksize, bool normalize=false, int ktype=CV_32F ) + +.. ocv:pyfunction:: cv2.getDerivKernels(dx, dy, ksize[, kx[, ky[, normalize[, ktype]]]]) -> kx, ky + + :param kx: Output matrix of row filter coefficients. It has the type ``ktype`` . + + :param ky: Output matrix of column filter coefficients. It has the type ``ktype`` . + + :param dx: Derivative order in respect of x. + + :param dy: Derivative order in respect of y. + + :param ksize: Aperture size. It can be ``CV_SCHARR`` , 1, 3, 5, or 7. + + :param normalize: Flag indicating whether to normalize (scale down) the filter coefficients or not. Theoretically, the coefficients should have the denominator :math:`=2^{ksize*2-dx-dy-2}` . If you are going to filter floating-point images, you are likely to use the normalized kernels. But if you compute derivatives of an 8-bit image, store the results in a 16-bit image, and wish to preserve all the fractional bits, you may want to set ``normalize=false`` . + + :param ktype: Type of filter coefficients. It can be ``CV_32f`` or ``CV_64F`` . + +The function computes and returns the filter coefficients for spatial image derivatives. When ``ksize=CV_SCHARR`` , the Scharr +:math:`3 \times 3` kernels are generated (see +:ocv:func:`Scharr` ). Otherwise, Sobel kernels are generated (see +:ocv:func:`Sobel` ). The filters are normally passed to +:ocv:func:`sepFilter2D` or to +:ocv:func:`createSeparableLinearFilter` . + + + +getGaussianKernel +----------------- +Returns Gaussian filter coefficients. + +.. ocv:function:: Mat getGaussianKernel( int ksize, double sigma, int ktype=CV_64F ) + +.. ocv:pyfunction:: cv2.getGaussianKernel(ksize, sigma[, ktype]) -> retval + + :param ksize: Aperture size. It should be odd ( :math:`\texttt{ksize} \mod 2 = 1` ) and positive. + + :param sigma: Gaussian standard deviation. If it is non-positive, it is computed from ``ksize`` as \ ``sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8`` . + :param ktype: Type of filter coefficients. It can be ``CV_32f`` or ``CV_64F`` . + +The function computes and returns the +:math:`\texttt{ksize} \times 1` matrix of Gaussian filter coefficients: + +.. math:: + + G_i= \alpha *e^{-(i-( \texttt{ksize} -1)/2)^2/(2* \texttt{sigma} )^2}, + +where +:math:`i=0..\texttt{ksize}-1` and +:math:`\alpha` is the scale factor chosen so that +:math:`\sum_i G_i=1`. + +Two of such generated kernels can be passed to +:ocv:func:`sepFilter2D` or to +:ocv:func:`createSeparableLinearFilter`. Those functions automatically recognize smoothing kernels (a symmetrical kernel with sum of weights equal to 1) and handle them accordingly. You may also use the higher-level +:ocv:func:`GaussianBlur`. + +.. seealso:: + + :ocv:func:`sepFilter2D`, + :ocv:func:`createSeparableLinearFilter`, + :ocv:func:`getDerivKernels`, + :ocv:func:`getStructuringElement`, + :ocv:func:`GaussianBlur` + + + +getKernelType +------------- +Returns the kernel type. + +.. ocv:function:: int getKernelType(InputArray kernel, Point anchor) + + :param kernel: 1D array of the kernel coefficients to analyze. + + :param anchor: Anchor position within the kernel. + +The function analyzes the kernel coefficients and returns the corresponding kernel type: + + * **KERNEL_GENERAL** The kernel is generic. It is used when there is no any type of symmetry or other properties. + + * **KERNEL_SYMMETRICAL** The kernel is symmetrical: :math:`\texttt{kernel}_i == \texttt{kernel}_{ksize-i-1}` , and the anchor is at the center. + + * **KERNEL_ASYMMETRICAL** The kernel is asymmetrical: :math:`\texttt{kernel}_i == -\texttt{kernel}_{ksize-i-1}` , and the anchor is at the center. + + * **KERNEL_SMOOTH** All the kernel elements are non-negative and summed to 1. For example, the Gaussian kernel is both smooth kernel and symmetrical, so the function returns ``KERNEL_SMOOTH | KERNEL_SYMMETRICAL`` . + * **KERNEL_INTEGER** All the kernel coefficients are integer numbers. This flag can be combined with ``KERNEL_SYMMETRICAL`` or ``KERNEL_ASYMMETRICAL`` . + + + +getStructuringElement +--------------------- +Returns a structuring element of the specified size and shape for morphological operations. + +.. ocv:function:: Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1)) + +.. ocv:pyfunction:: cv2.getStructuringElement(shape, ksize[, anchor]) -> retval + +.. ocv:cfunction:: IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchor_x, int anchor_y, int shape, int* values=NULL ) + +.. ocv:pyoldfunction:: cv.CreateStructuringElementEx(cols, rows, anchorX, anchorY, shape, values=None)-> kernel + + :param shape: Element shape that could be one of the following: + + * **MORPH_RECT** - a rectangular structuring element: + + .. math:: + + E_{ij}=1 + + * **MORPH_ELLIPSE** - an elliptic structuring element, that is, a filled ellipse inscribed into the rectangle ``Rect(0, 0, esize.width, 0.esize.height)`` + + * **MORPH_CROSS** - a cross-shaped structuring element: + + .. math:: + + E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise} + + * **CV_SHAPE_CUSTOM** - custom structuring element (OpenCV 1.x API) + + :param ksize: Size of the structuring element. + + :param cols: Width of the structuring element + + :param rows: Height of the structuring element + + :param anchor: Anchor position within the element. The default value :math:`(-1, -1)` means that the anchor is at the center. Note that only the shape of a cross-shaped element depends on the anchor position. In other cases the anchor just regulates how much the result of the morphological operation is shifted. + + :param anchor_x: x-coordinate of the anchor + + :param anchor_y: y-coordinate of the anchor + + :param values: integer array of ``cols``*``rows`` elements that specifies the custom shape of the structuring element, when ``shape=CV_SHAPE_CUSTOM``. + +The function constructs and returns the structuring element that can be further passed to +:ocv:func:`createMorphologyFilter`, +:ocv:func:`erode`, +:ocv:func:`dilate` or +:ocv:func:`morphologyEx` . But you can also construct an arbitrary binary mask yourself and use it as the structuring element. + +.. note:: When using OpenCV 1.x C API, the created structuring element ``IplConvKernel* element`` must be released in the end using ``cvReleaseStructuringElement(&element)``. + + +medianBlur +---------- +Blurs an image using the median filter. + +.. ocv:function:: void medianBlur( InputArray src, OutputArray dst, int ksize ) + +.. ocv:pyfunction:: cv2.medianBlur(src, ksize[, dst]) -> dst + + :param src: input 1-, 3-, or 4-channel image; when ``ksize`` is 3 or 5, the image depth should be ``CV_8U``, ``CV_16U``, or ``CV_32F``, for larger aperture sizes, it can only be ``CV_8U``. + + :param dst: destination array of the same size and type as ``src``. + + :param ksize: aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ... + +The function smoothes an image using the median filter with the +:math:`\texttt{ksize} \times \texttt{ksize}` aperture. Each channel of a multi-channel image is processed independently. In-place operation is supported. + +.. seealso:: + + :ocv:func:`bilateralFilter`, + :ocv:func:`blur`, + :ocv:func:`boxFilter`, + :ocv:func:`GaussianBlur` + + + +morphologyEx +------------ +Performs advanced morphological transformations. + +.. ocv:function:: void morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ) + +.. ocv:pyfunction:: cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst + +.. ocv:cfunction:: void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, int iterations=1 ) +.. ocv:pyoldfunction:: cv.MorphologyEx(src, dst, temp, element, operation, iterations=1)-> None + + :param src: Source image. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``. + + :param dst: Destination image of the same size and type as ``src`` . + + :param element: Structuring element. + + :param op: Type of a morphological operation that can be one of the following: + + * **MORPH_OPEN** - an opening operation + + * **MORPH_CLOSE** - a closing operation + + * **MORPH_GRADIENT** - a morphological gradient + + * **MORPH_TOPHAT** - "top hat" + + * **MORPH_BLACKHAT** - "black hat" + + :param iterations: Number of times erosion and dilation are applied. + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` for details. + + :param borderValue: Border value in case of a constant border. The default value has a special meaning. See :ocv:func:`createMorphologyFilter` for details. + +The function can perform advanced morphological transformations using an erosion and dilation as basic operations. + +Opening operation: + +.. math:: + + \texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} )) + +Closing operation: + +.. math:: + + \texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} )) + +Morphological gradient: + +.. math:: + + \texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} ) + +"Top hat": + +.. math:: + + \texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} ) + +"Black hat": + +.. math:: + + \texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src} + +Any of the operations can be done in-place. In case of multi-channel images, each channel is processed independently. + +.. seealso:: + + :ocv:func:`dilate`, + :ocv:func:`erode`, + :ocv:func:`createMorphologyFilter` + + +Laplacian +--------- +Calculates the Laplacian of an image. + +.. ocv:function:: void Laplacian( InputArray src, OutputArray dst, int ddepth, int ksize=1, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]]) -> dst + +.. ocv:cfunction:: void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.Laplace(src, dst, apertureSize=3) -> None + + :param src: Source image. + + :param dst: Destination image of the same size and the same number of channels as ``src`` . + + :param ddepth: Desired depth of the destination image. + + :param ksize: Aperture size used to compute the second-derivative filters. See :ocv:func:`getDerivKernels` for details. The size must be positive and odd. + + :param scale: Optional scale factor for the computed Laplacian values. By default, no scaling is applied. See :ocv:func:`getDerivKernels` for details. + + :param delta: Optional delta value that is added to the results prior to storing them in ``dst`` . + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` for details. + +The function calculates the Laplacian of the source image by adding up the second x and y derivatives calculated using the Sobel operator: + +.. math:: + + \texttt{dst} = \Delta \texttt{src} = \frac{\partial^2 \texttt{src}}{\partial x^2} + \frac{\partial^2 \texttt{src}}{\partial y^2} + +This is done when ``ksize > 1`` . When ``ksize == 1`` , the Laplacian is computed by filtering the image with the following +:math:`3 \times 3` aperture: + +.. math:: + + \vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0} + +.. seealso:: + + :ocv:func:`Sobel`, + :ocv:func:`Scharr` + + + +pyrDown +------- +Blurs an image and downsamples it. + +.. ocv:function:: void pyrDown( InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.pyrDown(src[, dst[, dstsize[, borderType]]]) -> dst + +.. ocv:cfunction:: void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ) + +.. ocv:pyoldfunction:: cv.PyrDown(src, dst, filter=CV_GAUSSIAN_5X5) -> None + + :param src: input image. + + :param dst: output image; it has the specified size and the same type as ``src``. + + :param dstsize: size of the output image; by default, it is computed as ``Size((src.cols+1)/2, (src.rows+1)/2)``, but in any case, the following conditions should be satisfied: + + .. math:: + + \begin{array}{l} + | \texttt{dstsize.width} *2-src.cols| \leq 2 \\ | \texttt{dstsize.height} *2-src.rows| \leq 2 \end{array} + +The function performs the downsampling step of the Gaussian pyramid construction. First, it convolves the source image with the kernel: + +.. math:: + + \frac{1}{256} \begin{bmatrix} 1 & 4 & 6 & 4 & 1 \\ 4 & 16 & 24 & 16 & 4 \\ 6 & 24 & 36 & 24 & 6 \\ 4 & 16 & 24 & 16 & 4 \\ 1 & 4 & 6 & 4 & 1 \end{bmatrix} + +Then, it downsamples the image by rejecting even rows and columns. + + + +pyrUp +----- +Upsamples an image and then blurs it. + +.. ocv:function:: void pyrUp( InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.pyrUp(src[, dst[, dstsize[, borderType]]]) -> dst + +.. ocv:cfunction:: cvPyrUp( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ) + +.. ocv:pyoldfunction:: cv.PyrUp(src, dst, filter=CV_GAUSSIAN_5X5) -> None + + :param src: input image. + + :param dst: output image. It has the specified size and the same type as ``src`` . + + :param dstsize: size of the output image; by default, it is computed as ``Size(src.cols*2, (src.rows*2)``, but in any case, the following conditions should be satisfied: + + .. math:: + + \begin{array}{l} + | \texttt{dstsize.width} -src.cols*2| \leq ( \texttt{dstsize.width} \mod 2) \\ | \texttt{dstsize.height} -src.rows*2| \leq ( \texttt{dstsize.height} \mod 2) \end{array} + +The function performs the upsampling step of the Gaussian pyramid construction, though it can actually be used to construct the Laplacian pyramid. First, it upsamples the source image by injecting even zero rows and columns and then convolves the result with the same kernel as in +:ocv:func:`pyrDown` multiplied by 4. + + +pyrMeanShiftFiltering +--------------------- +Performs initial step of meanshift segmentation of an image. + +.. ocv:function:: void pyrMeanShiftFiltering( InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteria termcrit=TermCriteria( TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) ) + +.. ocv:pyfunction:: cv2.pyrMeanShiftFiltering(src, sp, sr[, dst[, maxLevel[, termcrit]]]) -> dst + +.. ocv:cfunction:: void cvPyrMeanShiftFiltering( const CvArr* src, CvArr* dst, double sp, double sr, int max_level=1, CvTermCriteria termcrit= cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1)) + +.. ocv:pyoldfunction:: cv.PyrMeanShiftFiltering(src, dst, sp, sr, max_level=1, termcrit=(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 5, 1)) -> None + + :param src: The source 8-bit, 3-channel image. + + :param dst: The destination image of the same format and the same size as the source. + + :param sp: The spatial window radius. + + :param sr: The color window radius. + + :param maxLevel: Maximum level of the pyramid for the segmentation. + + :param termcrit: Termination criteria: when to stop meanshift iterations. + + +The function implements the filtering stage of meanshift segmentation, that is, the output of the function is the filtered "posterized" image with color gradients and fine-grain texture flattened. At every pixel +``(X,Y)`` of the input image (or down-sized input image, see below) the function executes meanshift +iterations, that is, the pixel ``(X,Y)`` neighborhood in the joint space-color hyperspace is considered: + + .. math:: + + (x,y): X- \texttt{sp} \le x \le X+ \texttt{sp} , Y- \texttt{sp} \le y \le Y+ \texttt{sp} , ||(R,G,B)-(r,g,b)|| \le \texttt{sr} + + +where ``(R,G,B)`` and ``(r,g,b)`` are the vectors of color components at ``(X,Y)`` and ``(x,y)``, respectively (though, the algorithm does not depend on the color space used, so any 3-component color space can be used instead). Over the neighborhood the average spatial value ``(X',Y')`` and average color vector ``(R',G',B')`` are found and they act as the neighborhood center on the next iteration: + + .. math:: + + (X,Y)~(X',Y'), (R,G,B)~(R',G',B'). + +After the iterations over, the color components of the initial pixel (that is, the pixel from where the iterations started) are set to the final value (average color at the last iteration): + + .. math:: + + I(X,Y) <- (R*,G*,B*) + +When ``maxLevel > 0``, the gaussian pyramid of ``maxLevel+1`` levels is built, and the above procedure is run on the smallest layer first. After that, the results are propagated to the larger layer and the iterations are run again only on those pixels where the layer colors differ by more than ``sr`` from the lower-resolution layer of the pyramid. That makes boundaries of color regions sharper. Note that the results will be actually different from the ones obtained by running the meanshift procedure on the whole original image (i.e. when ``maxLevel==0``). + + +sepFilter2D +----------- +Applies a separable linear filter to an image. + +.. ocv:function:: void sepFilter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernelX, InputArray kernelY, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.sepFilter2D(src, ddepth, kernelX, kernelY[, dst[, anchor[, delta[, borderType]]]]) -> dst + + :param src: Source image. + + :param dst: Destination image of the same size and the same number of channels as ``src`` . + + :param ddepth: Destination image depth. The following combination of ``src.depth()`` and ``ddepth`` are supported: + * ``src.depth()`` = ``CV_8U``, ``ddepth`` = -1/``CV_16S``/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_16U``/``CV_16S``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_32F``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_64F``, ``ddepth`` = -1/``CV_64F`` + + when ``ddepth=-1``, the destination image will have the same depth as the source. + + :param kernelX: Coefficients for filtering each row. + + :param kernelY: Coefficients for filtering each column. + + :param anchor: Anchor position within the kernel. The default value :math:`(-1, 1)` means that the anchor is at the kernel center. + + :param delta: Value added to the filtered results before storing them. + + :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` for details. + +The function applies a separable linear filter to the image. That is, first, every row of ``src`` is filtered with the 1D kernel ``kernelX`` . Then, every column of the result is filtered with the 1D kernel ``kernelY`` . The final result shifted by ``delta`` is stored in ``dst`` . + +.. seealso:: + + :ocv:func:`createSeparableLinearFilter`, + :ocv:func:`filter2D`, + :ocv:func:`Sobel`, + :ocv:func:`GaussianBlur`, + :ocv:func:`boxFilter`, + :ocv:func:`blur` + + +Smooth +------ +Smooths the image in one of several ways. + +.. ocv:cfunction:: void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int size1=3, int size2=0, double sigma1=0, double sigma2=0 ) + +.. ocv:pyoldfunction:: cv.Smooth(src, dst, smoothtype=CV_GAUSSIAN, param1=3, param2=0, param3=0, param4=0)-> None + + :param src: The source image + + :param dst: The destination image + + :param smoothtype: Type of the smoothing: + + * **CV_BLUR_NO_SCALE** linear convolution with :math:`\texttt{size1}\times\texttt{size2}` box kernel (all 1's). If you want to smooth different pixels with different-size box kernels, you can use the integral image that is computed using :ocv:func:`integral` + + + * **CV_BLUR** linear convolution with :math:`\texttt{size1}\times\texttt{size2}` box kernel (all 1's) with subsequent scaling by :math:`1/(\texttt{size1}\cdot\texttt{size2})` + + + * **CV_GAUSSIAN** linear convolution with a :math:`\texttt{size1}\times\texttt{size2}` Gaussian kernel + + + * **CV_MEDIAN** median filter with a :math:`\texttt{size1}\times\texttt{size1}` square aperture + + + * **CV_BILATERAL** bilateral filter with a :math:`\texttt{size1}\times\texttt{size1}` square aperture, color sigma= ``sigma1`` and spatial sigma= ``sigma2`` . If ``size1=0`` , the aperture square side is set to ``cvRound(sigma2*1.5)*2+1`` . Information about bilateral filtering can be found at http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html + + + :param size1: The first parameter of the smoothing operation, the aperture width. Must be a positive odd number (1, 3, 5, ...) + + :param size2: The second parameter of the smoothing operation, the aperture height. Ignored by ``CV_MEDIAN`` and ``CV_BILATERAL`` methods. In the case of simple scaled/non-scaled and Gaussian blur if ``size2`` is zero, it is set to ``size1`` . Otherwise it must be a positive odd number. + + :param sigma1: In the case of a Gaussian parameter this parameter may specify Gaussian :math:`\sigma` (standard deviation). If it is zero, it is calculated from the kernel size: + + .. math:: + + \sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{size1} for horizontal kernel} \\ \mbox{\texttt{size2} for vertical kernel} \end{array} + + Using standard sigma for small kernels ( :math:`3\times 3` to :math:`7\times 7` ) gives better speed. If ``sigma1`` is not zero, while ``size1`` and ``size2`` are zeros, the kernel size is calculated from the sigma (to provide accurate enough operation). + +The function smooths an image using one of several methods. Every of the methods has some features and restrictions listed below: + + * Blur with no scaling works with single-channel images only and supports accumulation of 8-bit to 16-bit format (similar to :ocv:func:`Sobel` and :ocv:func:`Laplacian`) and 32-bit floating point to 32-bit floating-point format. + + * Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images. These two methods can process images in-place. + + * Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images in-place. + +.. note:: The function is now obsolete. Use :ocv:func:`GaussianBlur`, :ocv:func:`blur`, :ocv:func:`medianBlur` or :ocv:func:`bilateralFilter`. + + +Sobel +----- +Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. + +.. ocv:function:: void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) -> dst + +.. ocv:cfunction:: void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 ) + +.. ocv:pyoldfunction:: cv.Sobel(src, dst, xorder, yorder, apertureSize=3)-> None + + :param src: input image. + + :param dst: output image of the same size and the same number of channels as ``src`` . + + :param ddepth: output image depth; the following combinations of ``src.depth()`` and ``ddepth`` are supported: + * ``src.depth()`` = ``CV_8U``, ``ddepth`` = -1/``CV_16S``/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_16U``/``CV_16S``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_32F``, ``ddepth`` = -1/``CV_32F``/``CV_64F`` + * ``src.depth()`` = ``CV_64F``, ``ddepth`` = -1/``CV_64F`` + + when ``ddepth=-1``, the destination image will have the same depth as the source; in the case of 8-bit input images it will result in truncated derivatives. + + :param xorder: order of the derivative x. + + :param yorder: order of the derivative y. + + :param ksize: size of the extended Sobel kernel; it must be 1, 3, 5, or 7. + + :param scale: optional scale factor for the computed derivative values; by default, no scaling is applied (see :ocv:func:`getDerivKernels` for details). + + :param delta: optional delta value that is added to the results prior to storing them in ``dst``. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + +In all cases except one, the +:math:`\texttt{ksize} \times +\texttt{ksize}` separable kernel is used to calculate the +derivative. When +:math:`\texttt{ksize = 1}` , the +:math:`3 \times 1` or +:math:`1 \times 3` kernel is used (that is, no Gaussian smoothing is done). ``ksize = 1`` can only be used for the first or the second x- or y- derivatives. + +There is also the special value ``ksize = CV_SCHARR`` (-1) that corresponds to the +:math:`3\times3` Scharr +filter that may give more accurate results than the +:math:`3\times3` Sobel. The Scharr aperture is + +.. math:: + + \vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3} + +for the x-derivative, or transposed for the y-derivative. + +The function calculates an image derivative by convolving the image with the appropriate kernel: + +.. math:: + + \texttt{dst} = \frac{\partial^{xorder+yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}} + +The Sobel operators combine Gaussian smoothing and differentiation, +so the result is more or less resistant to the noise. Most often, +the function is called with ( ``xorder`` = 1, ``yorder`` = 0, ``ksize`` = 3) or ( ``xorder`` = 0, ``yorder`` = 1, ``ksize`` = 3) to calculate the first x- or y- image +derivative. The first case corresponds to a kernel of: + +.. math:: + + \vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1} + +The second case corresponds to a kernel of: + +.. math:: + + \vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1} + +.. seealso:: + + :ocv:func:`Scharr`, + :ocv:func:`Laplacian`, + :ocv:func:`sepFilter2D`, + :ocv:func:`filter2D`, + :ocv:func:`GaussianBlur`, + :ocv:func:`cartToPolar` + + + +Scharr +------ +Calculates the first x- or y- image derivative using Scharr operator. + +.. ocv:function:: void Scharr( InputArray src, OutputArray dst, int ddepth, int dx, int dy, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ) + +.. ocv:pyfunction:: cv2.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]) -> dst + + :param src: input image. + + :param dst: output image of the same size and the same number of channels as ``src``. + + :param ddepth: output image depth (see :ocv:func:`Sobel` for the list of supported combination of ``src.depth()`` and ``ddepth``). + + :param dx: order of the derivative x. + + :param dy: order of the derivative y. + + :param scale: optional scale factor for the computed derivative values; by default, no scaling is applied (see :ocv:func:`getDerivKernels` for details). + + :param delta: optional delta value that is added to the results prior to storing them in ``dst``. + + :param borderType: pixel extrapolation method (see :ocv:func:`borderInterpolate` for details). + +The function computes the first x- or y- spatial image derivative using the Scharr operator. The call + +.. math:: + + \texttt{Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)} + +is equivalent to + +.. math:: + + \texttt{Sobel(src, dst, ddepth, dx, dy, CV\_SCHARR, scale, delta, borderType)} . + +.. seealso:: + + :ocv:func:`cartToPolar` + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/geometric_transformations.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/geometric_transformations.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/geometric_transformations.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/geometric_transformations.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,706 @@ +Geometric Image Transformations +=============================== +.. highlight:: cpp + +The functions in this section perform various geometrical transformations of 2D images. They do not change the image content but deform the pixel grid and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel :math:`(x, y)` of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value: + +.. math:: + + \texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y)) + +In case when you specify the forward mapping +:math:`\left: \texttt{src} \rightarrow \texttt{dst}` , the OpenCV functions first compute the corresponding inverse mapping +:math:`\left: \texttt{dst} \rightarrow \texttt{src}` and then use the above formula. + +The actual implementations of the geometrical transformations, from the most generic +:ocv:func:`remap` and to the simplest and the fastest +:ocv:func:`resize` , need to solve two main problems with the above formula: + +* + Extrapolation of non-existing pixels. Similarly to the filtering functions described in the previous section, for some + :math:`(x,y)` , either one of + :math:`f_x(x,y)` , or + :math:`f_y(x,y)` , or both of them may fall outside of the image. In this case, an extrapolation method needs to be used. OpenCV provides the same selection of extrapolation methods as in the filtering functions. In addition, it provides the method ``BORDER_TRANSPARENT`` . This means that the corresponding pixels in the destination image will not be modified at all. + +* + Interpolation of pixel values. Usually + :math:`f_x(x,y)` and + :math:`f_y(x,y)` are floating-point numbers. This means that + :math:`\left` can be either an affine or perspective transformation, or radial lens distortion correction, and so on. So, a pixel value at fractional coordinates needs to be retrieved. In the simplest case, the coordinates can be just rounded to the nearest integer coordinates and the corresponding pixel can be used. This is called a nearest-neighbor interpolation. However, a better result can be achieved by using more sophisticated `interpolation methods `_ + , where a polynomial function is fit into some neighborhood of the computed pixel + :math:`(f_x(x,y), f_y(x,y))` , and then the value of the polynomial at + :math:`(f_x(x,y), f_y(x,y))` is taken as the interpolated pixel value. In OpenCV, you can choose between several interpolation methods. See + :ocv:func:`resize` for details. + +convertMaps +----------- +Converts image transformation maps from one representation to another. + +.. ocv:function:: void convertMaps( InputArray map1, InputArray map2, OutputArray dstmap1, OutputArray dstmap2, int dstmap1type, bool nninterpolation=false ) + +.. ocv:pyfunction:: cv2.convertMaps(map1, map2, dstmap1type[, dstmap1[, dstmap2[, nninterpolation]]]) -> dstmap1, dstmap2 + + :param map1: The first input map of type ``CV_16SC2`` , ``CV_32FC1`` , or ``CV_32FC2`` . + + :param map2: The second input map of type ``CV_16UC1`` , ``CV_32FC1`` , or none (empty matrix), respectively. + + :param dstmap1: The first output map that has the type ``dstmap1type`` and the same size as ``src`` . + + :param dstmap2: The second output map. + + :param dstmap1type: Type of the first output map that should be ``CV_16SC2`` , ``CV_32FC1`` , or ``CV_32FC2`` . + + :param nninterpolation: Flag indicating whether the fixed-point maps are used for the nearest-neighbor or for a more complex interpolation. + +The function converts a pair of maps for +:ocv:func:`remap` from one representation to another. The following options ( ``(map1.type(), map2.type())`` :math:`\rightarrow` ``(dstmap1.type(), dstmap2.type())`` ) are supported: + +* + :math:`\texttt{(CV\_32FC1, CV\_32FC1)} \rightarrow \texttt{(CV\_16SC2, CV\_16UC1)}` . This is the most frequently used conversion operation, in which the original floating-point maps (see + :ocv:func:`remap` ) are converted to a more compact and much faster fixed-point representation. The first output array contains the rounded coordinates and the second array (created only when ``nninterpolation=false`` ) contains indices in the interpolation tables. + +* + :math:`\texttt{(CV\_32FC2)} \rightarrow \texttt{(CV\_16SC2, CV\_16UC1)}` . The same as above but the original maps are stored in one 2-channel matrix. + +* + Reverse conversion. Obviously, the reconstructed floating-point maps will not be exactly the same as the originals. + +.. seealso:: + + :ocv:func:`remap`, + :ocv:func:`undistort`, + :ocv:func:`initUndistortRectifyMap` + + + +getAffineTransform +---------------------- +Calculates an affine transform from three pairs of the corresponding points. + +.. ocv:function:: Mat getAffineTransform( InputArray src, InputArray dst ) + +.. ocv:function:: Mat getAffineTransform( const Point2f src[], const Point2f dst[] ) + +.. ocv:pyfunction:: cv2.getAffineTransform(src, dst) -> retval + +.. ocv:cfunction:: CvMat* cvGetAffineTransform( const CvPoint2D32f * src, const CvPoint2D32f * dst, CvMat * map_matrix ) + +.. ocv:pyoldfunction:: cv.GetAffineTransform(src, dst, mapMatrix)-> None + + :param src: Coordinates of triangle vertices in the source image. + + :param dst: Coordinates of the corresponding triangle vertices in the destination image. + +The function calculates the :math:`2 \times 3` matrix of an affine transform so that: + +.. math:: + + \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{map\_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} + +where + +.. math:: + + dst(i)=(x'_i,y'_i), + src(i)=(x_i, y_i), + i=0,1,2 + +.. seealso:: + + :ocv:func:`warpAffine`, + :ocv:func:`transform` + + + +getPerspectiveTransform +--------------------------- +Calculates a perspective transform from four pairs of the corresponding points. + +.. ocv:function:: Mat getPerspectiveTransform( InputArray src, InputArray dst ) + +.. ocv:function:: Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] ) + +.. ocv:pyfunction:: cv2.getPerspectiveTransform(src, dst) -> retval + +.. ocv:cfunction:: CvMat* cvGetPerspectiveTransform( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* map_matrix ) + +.. ocv:pyoldfunction:: cv.GetPerspectiveTransform(src, dst, mapMatrix)-> None + + :param src: Coordinates of quadrangle vertices in the source image. + + :param dst: Coordinates of the corresponding quadrangle vertices in the destination image. + +The function calculates the :math:`3 \times 3` matrix of a perspective transform so that: + +.. math:: + + \begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map\_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} + +where + +.. math:: + + dst(i)=(x'_i,y'_i), + src(i)=(x_i, y_i), + i=0,1,2,3 + +.. seealso:: + + :ocv:func:`findHomography`, + :ocv:func:`warpPerspective`, + :ocv:func:`perspectiveTransform` + + +getRectSubPix +----------------- +Retrieves a pixel rectangle from an image with sub-pixel accuracy. + +.. ocv:function:: void getRectSubPix( InputArray image, Size patchSize, Point2f center, OutputArray patch, int patchType=-1 ) + +.. ocv:pyfunction:: cv2.getRectSubPix(image, patchSize, center[, patch[, patchType]]) -> patch + +.. ocv:cfunction:: void cvGetRectSubPix( const CvArr* src, CvArr* dst, CvPoint2D32f center ) +.. ocv:pyoldfunction:: cv.GetRectSubPix(src, dst, center)-> None + + :param src: Source image. + + :param patchSize: Size of the extracted patch. + + :param center: Floating point coordinates of the center of the extracted rectangle within the source image. The center must be inside the image. + + :param dst: Extracted patch that has the size ``patchSize`` and the same number of channels as ``src`` . + + :param patchType: Depth of the extracted pixels. By default, they have the same depth as ``src`` . + +The function ``getRectSubPix`` extracts pixels from ``src`` : + +.. math:: + + dst(x, y) = src(x + \texttt{center.x} - ( \texttt{dst.cols} -1)*0.5, y + \texttt{center.y} - ( \texttt{dst.rows} -1)*0.5) + +where the values of the pixels at non-integer coordinates are retrieved +using bilinear interpolation. Every channel of multi-channel +images is processed independently. While the center of the rectangle +must be inside the image, parts of the rectangle may be +outside. In this case, the replication border mode (see +:ocv:func:`borderInterpolate` ) is used to extrapolate +the pixel values outside of the image. + +.. seealso:: + + :ocv:func:`warpAffine`, + :ocv:func:`warpPerspective` + + +getRotationMatrix2D +----------------------- +Calculates an affine matrix of 2D rotation. + +.. ocv:function:: Mat getRotationMatrix2D( Point2f center, double angle, double scale ) + +.. ocv:pyfunction:: cv2.getRotationMatrix2D(center, angle, scale) -> retval + +.. ocv:cfunction:: CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix ) + +.. ocv:pyoldfunction:: cv.GetRotationMatrix2D(center, angle, scale, mapMatrix)-> None + + :param center: Center of the rotation in the source image. + + :param angle: Rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner). + + :param scale: Isotropic scale factor. + + :param map_matrix: The output affine transformation, 2x3 floating-point matrix. + +The function calculates the following matrix: + +.. math:: + + \begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix} + +where + +.. math:: + + \begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array} + +The transformation maps the rotation center to itself. If this is not the target, adjust the shift. + +.. seealso:: + + :ocv:func:`getAffineTransform`, + :ocv:func:`warpAffine`, + :ocv:func:`transform` + + + +invertAffineTransform +------------------------- +Inverts an affine transformation. + +.. ocv:function:: void invertAffineTransform(InputArray M, OutputArray iM) + +.. ocv:pyfunction:: cv2.invertAffineTransform(M[, iM]) -> iM + + :param M: Original affine transformation. + + :param iM: Output reverse affine transformation. + +The function computes an inverse affine transformation represented by +:math:`2 \times 3` matrix ``M`` : + +.. math:: + + \begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \end{bmatrix} + +The result is also a +:math:`2 \times 3` matrix of the same type as ``M`` . + + + +LogPolar +-------- +Remaps an image to log-polar space. + +.. ocv:cfunction:: void cvLogPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double M, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ) + +.. ocv:pyoldfunction:: cv.LogPolar(src, dst, center, M, flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS)-> None + + :param src: Source image + + :param dst: Destination image + + :param center: The transformation center; where the output precision is maximal + + :param M: Magnitude scale parameter. See below + + :param flags: A combination of interpolation methods and the following optional flags: + + * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero + + * **CV_WARP_INVERSE_MAP** See below + +The function ``cvLogPolar`` transforms the source image using the following transformation: + + * + Forward transformation (``CV_WARP_INVERSE_MAP`` is not set): + + .. math:: + + dst( \phi , \rho ) = src(x,y) + + + * + Inverse transformation (``CV_WARP_INVERSE_MAP`` is set): + + .. math:: + + dst(x,y) = src( \phi , \rho ) + + +where + + .. math:: + + \rho = M \cdot \log{\sqrt{x^2 + y^2}} , \phi =atan(y/x) + + +The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth. The function can not operate in-place. + + +remap +----- +Applies a generic geometrical transformation to an image. + +.. ocv:function:: void remap( InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()) + +.. ocv:pyfunction:: cv2.remap(src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]]) -> dst + +.. ocv:cfunction:: void cvRemap( const CvArr* src, CvArr* dst, const CvArr* mapx, const CvArr* mapy, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) +.. ocv:pyoldfunction:: cv.Remap(src, dst, mapx, mapy, flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0, 0, 0, 0))-> None + + :param src: Source image. + + :param dst: Destination image. It has the same size as ``map1`` and the same type as ``src`` . + :param map1: The first map of either ``(x,y)`` points or just ``x`` values having the type ``CV_16SC2`` , ``CV_32FC1`` , or ``CV_32FC2`` . See :ocv:func:`convertMaps` for details on converting a floating point representation to fixed-point for speed. + + :param map2: The second map of ``y`` values having the type ``CV_16UC1`` , ``CV_32FC1`` , or none (empty map if ``map1`` is ``(x,y)`` points), respectively. + + :param interpolation: Interpolation method (see :ocv:func:`resize` ). The method ``INTER_AREA`` is not supported by this function. + + :param borderMode: Pixel extrapolation method (see :ocv:func:`borderInterpolate` ). When \ ``borderMode=BORDER_TRANSPARENT`` , it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function. + + :param borderValue: Value used in case of a constant border. By default, it is 0. + +The function ``remap`` transforms the source image using the specified map: + +.. math:: + + \texttt{dst} (x,y) = \texttt{src} (map_x(x,y),map_y(x,y)) + +where values of pixels with non-integer coordinates are computed using one of available interpolation methods. +:math:`map_x` and +:math:`map_y` can be encoded as separate floating-point maps in +:math:`map_1` and +:math:`map_2` respectively, or interleaved floating-point maps of +:math:`(x,y)` in +:math:`map_1` , or +fixed-point maps created by using +:ocv:func:`convertMaps` . The reason you might want to convert from floating to fixed-point +representations of a map is that they can yield much faster (~2x) remapping operations. In the converted case, +:math:`map_1` contains pairs ``(cvFloor(x), cvFloor(y))`` and +:math:`map_2` contains indices in a table of interpolation coefficients. + +This function cannot operate in-place. + + + +resize +------ +Resizes an image. + +.. ocv:function:: void resize( InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR ) + +.. ocv:pyfunction:: cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst + +.. ocv:cfunction:: void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR ) +.. ocv:pyoldfunction:: cv.Resize(src, dst, interpolation=CV_INTER_LINEAR)-> None + + :param src: input image. + + :param dst: output image; it has the size ``dsize`` (when it is non-zero) or the size computed from ``src.size()``, ``fx``, and ``fy``; the type of ``dst`` is the same as of ``src``. + + :param dsize: output image size; if it equals zero, it is computed as: + + .. math:: + + \texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))} + + + Either ``dsize`` or both ``fx`` and ``fy`` must be non-zero. + + :param fx: scale factor along the horizontal axis; when it equals 0, it is computed as + + .. math:: + + \texttt{(double)dsize.width/src.cols} + + :param fy: scale factor along the vertical axis; when it equals 0, it is computed as + + .. math:: + + \texttt{(double)dsize.height/src.rows} + + :param interpolation: interpolation method: + + * **INTER_NEAREST** - a nearest-neighbor interpolation + + * **INTER_LINEAR** - a bilinear interpolation (used by default) + + * **INTER_AREA** - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the ``INTER_NEAREST`` method. + + * **INTER_CUBIC** - a bicubic interpolation over 4x4 pixel neighborhood + + * **INTER_LANCZOS4** - a Lanczos interpolation over 8x8 pixel neighborhood + +The function ``resize`` resizes the image ``src`` down to or up to the specified size. +Note that the initial ``dst`` type or size are not taken into account. Instead, the size and type are derived from the ``src``,``dsize``,``fx`` , and ``fy`` . If you want to resize ``src`` so that it fits the pre-created ``dst`` , you may call the function as follows: :: + + // explicitly specify dsize=dst.size(); fx and fy will be computed from that. + resize(src, dst, dst.size(), 0, 0, interpolation); + + +If you want to decimate the image by factor of 2 in each direction, you can call the function this way: :: + + // specify fx and fy and let the function compute the destination image size. + resize(src, dst, Size(), 0.5, 0.5, interpolation); + +To shrink an image, it will generally look best with CV_INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with CV_INTER_CUBIC (slow) or CV_INTER_LINEAR (faster but still looks OK). + +.. seealso:: + + :ocv:func:`warpAffine`, + :ocv:func:`warpPerspective`, + :ocv:func:`remap` + + +warpAffine +---------- +Applies an affine transformation to an image. + +.. ocv:function:: void warpAffine( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()) + +.. ocv:pyfunction:: cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) -> dst + +.. ocv:cfunction:: void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) + +.. ocv:pyoldfunction:: cv.WarpAffine(src, dst, mapMatrix, flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0, 0, 0, 0))-> None + +.. ocv:cfunction:: void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix ) + +.. ocv:pyoldfunction:: cv.GetQuadrangleSubPix(src, dst, mapMatrix)-> None + + :param src: input image. + + :param dst: output image that has the size ``dsize`` and the same type as ``src`` . + + :param M: :math:`2\times 3` transformation matrix. + + :param dsize: size of the output image. + + :param flags: combination of interpolation methods (see :ocv:func:`resize` ) and the optional flag ``WARP_INVERSE_MAP`` that means that ``M`` is the inverse transformation ( :math:`\texttt{dst}\rightarrow\texttt{src}` ). + + :param borderMode: pixel extrapolation method (see :ocv:func:`borderInterpolate`); when \ ``borderMode=BORDER_TRANSPARENT`` , it means that the pixels in the destination image corresponding to the "outliers" in the source image are not modified by the function. + + :param borderValue: value used in case of a constant border; by default, it is 0. + +The function ``warpAffine`` transforms the source image using the specified matrix: + +.. math:: + + \texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23}) + +when the flag ``WARP_INVERSE_MAP`` is set. Otherwise, the transformation is first inverted with +:ocv:func:`invertAffineTransform` and then put in the formula above instead of ``M`` . +The function cannot operate in-place. + +.. seealso:: + + :ocv:func:`warpPerspective`, + :ocv:func:`resize`, + :ocv:func:`remap`, + :ocv:func:`getRectSubPix`, + :ocv:func:`transform` + + +.. note:: ``cvGetQuadrangleSubPix`` is similar to ``cvWarpAffine``, but the outliers are extrapolated using replication border mode. + +warpPerspective +--------------- +Applies a perspective transformation to an image. + +.. ocv:function:: void warpPerspective( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()) + +.. ocv:pyfunction:: cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) -> dst + +.. ocv:cfunction:: void cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) + +.. ocv:pyoldfunction:: cv.WarpPerspective(src, dst, mapMatrix, flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0, 0, 0, 0))-> None + + :param src: input image. + + :param dst: output image that has the size ``dsize`` and the same type as ``src`` . + + :param M: :math:`3\times 3` transformation matrix. + + :param dsize: size of the output image. + + :param flags: combination of interpolation methods (``INTER_LINEAR`` or ``INTER_NEAREST``) and the optional flag ``WARP_INVERSE_MAP``, that sets ``M`` as the inverse transformation ( :math:`\texttt{dst}\rightarrow\texttt{src}` ). + + :param borderMode: pixel extrapolation method (``BORDER_CONSTANT`` or ``BORDER_REPLICATE``). + + :param borderValue: value used in case of a constant border; by default, it equals 0. + +The function ``warpPerspective`` transforms the source image using the specified matrix: + +.. math:: + + \texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} , + \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right ) + +when the flag ``WARP_INVERSE_MAP`` is set. Otherwise, the transformation is first inverted with +:ocv:func:`invert` and then put in the formula above instead of ``M`` . +The function cannot operate in-place. + +.. seealso:: + + :ocv:func:`warpAffine`, + :ocv:func:`resize`, + :ocv:func:`remap`, + :ocv:func:`getRectSubPix`, + :ocv:func:`perspectiveTransform` + + + + +initUndistortRectifyMap +----------------------- +Computes the undistortion and rectification transformation map. + +.. ocv:function:: void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2 ) + +.. ocv:pyfunction:: cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]]) -> map1, map2 + +.. ocv:cfunction:: void cvInitUndistortRectifyMap( const CvMat* camera_matrix, const CvMat* dist_coeffs, const CvMat * R, const CvMat* new_camera_matrix, CvArr* mapx, CvArr* mapy ) +.. ocv:cfunction:: void cvInitUndistortMap( const CvMat* camera_matrix, const CvMat* distortion_coeffs, CvArr* mapx, CvArr* mapy ) + +.. ocv:pyoldfunction:: cv.InitUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, map1, map2)-> None +.. ocv:pyoldfunction:: cv.InitUndistortMap(cameraMatrix, distCoeffs, map1, map2)-> None + + :param cameraMatrix: Input camera matrix :math:`A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . + + :param distCoeffs: Input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5, or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. + + :param R: Optional rectification transformation in the object space (3x3 matrix). ``R1`` or ``R2`` , computed by :ocv:func:`stereoRectify` can be passed here. If the matrix is empty, the identity transformation is assumed. In ``cvInitUndistortMap`` R assumed to be an identity matrix. + + :param newCameraMatrix: New camera matrix :math:`A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}` . + + :param size: Undistorted image size. + + :param m1type: Type of the first output map that can be ``CV_32FC1`` or ``CV_16SC2`` . See :ocv:func:`convertMaps` for details. + + :param map1: The first output map. + + :param map2: The second output map. + +The function computes the joint undistortion and rectification transformation and represents the result in the form of maps for +:ocv:func:`remap` . The undistorted image looks like original, as if it is captured with a camera using the camera matrix ``=newCameraMatrix`` and zero distortion. In case of a monocular camera, ``newCameraMatrix`` is usually equal to ``cameraMatrix`` , or it can be computed by +:ocv:func:`getOptimalNewCameraMatrix` for a better control over scaling. In case of a stereo camera, ``newCameraMatrix`` is normally set to ``P1`` or ``P2`` computed by +:ocv:func:`stereoRectify` . + +Also, this new camera is oriented differently in the coordinate space, according to ``R`` . That, for example, helps to align two heads of a stereo camera so that the epipolar lines on both images become horizontal and have the same y- coordinate (in case of a horizontally aligned stereo camera). + +The function actually builds the maps for the inverse mapping algorithm that is used by +:ocv:func:`remap` . That is, for each pixel +:math:`(u, v)` in the destination (corrected and rectified) image, the function computes the corresponding coordinates in the source image (that is, in the original image from camera). The following process is applied: + +.. math:: + + \begin{array}{l} x \leftarrow (u - {c'}_x)/{f'}_x \\ y \leftarrow (v - {c'}_y)/{f'}_y \\{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\ x' \leftarrow X/W \\ y' \leftarrow Y/W \\ x" \leftarrow x' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + 2p_1 x' y' + p_2(r^2 + 2 x'^2) \\ y" \leftarrow y' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' \\ map_x(u,v) \leftarrow x" f_x + c_x \\ map_y(u,v) \leftarrow y" f_y + c_y \end{array} + +where +:math:`(k_1, k_2, p_1, p_2[, k_3])` are the distortion coefficients. + +In case of a stereo camera, this function is called twice: once for each camera head, after +:ocv:func:`stereoRectify` , which in its turn is called after +:ocv:func:`stereoCalibrate` . But if the stereo camera was not calibrated, it is still possible to compute the rectification transformations directly from the fundamental matrix using +:ocv:func:`stereoRectifyUncalibrated` . For each camera, the function computes homography ``H`` as the rectification transformation in a pixel domain, not a rotation matrix ``R`` in 3D space. ``R`` can be computed from ``H`` as + +.. math:: + + \texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix} + +where ``cameraMatrix`` can be chosen arbitrarily. + + + + +getDefaultNewCameraMatrix +------------------------- +Returns the default new camera matrix. + +.. ocv:function:: Mat getDefaultNewCameraMatrix(InputArray cameraMatrix, Size imgsize=Size(), bool centerPrincipalPoint=false ) + +.. ocv:pyfunction:: cv2.getDefaultNewCameraMatrix(cameraMatrix[, imgsize[, centerPrincipalPoint]]) -> retval + + :param cameraMatrix: Input camera matrix. + + :param imgsize: Camera view image size in pixels. + + :param centerPrincipalPoint: Location of the principal point in the new camera matrix. The parameter indicates whether this location should be at the image center or not. + +The function returns the camera matrix that is either an exact copy of the input ``cameraMatrix`` (when ``centerPrinicipalPoint=false`` ), or the modified one (when ``centerPrincipalPoint=true``). + +In the latter case, the new camera matrix will be: + +.. math:: + + \begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} , + +where +:math:`f_x` and +:math:`f_y` are +:math:`(0,0)` and +:math:`(1,1)` elements of ``cameraMatrix`` , respectively. + +By default, the undistortion functions in OpenCV (see +:ocv:func:`initUndistortRectifyMap`, +:ocv:func:`undistort`) do not move the principal point. However, when you work with stereo, it is important to move the principal points in both views to the same y-coordinate (which is required by most of stereo correspondence algorithms), and may be to the same x-coordinate too. So, you can form the new camera matrix for each view where the principal points are located at the center. + + + + +undistort +------------- +Transforms an image to compensate for lens distortion. + +.. ocv:function:: void undistort( InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray() ) + +.. ocv:pyfunction:: cv2.undistort(src, cameraMatrix, distCoeffs[, dst[, newCameraMatrix]]) -> dst + +.. ocv:cfunction:: void cvUndistort2( const CvArr* src, CvArr* dst, const CvMat* camera_matrix, const CvMat* distortion_coeffs, const CvMat* new_camera_matrix=0 ) + +.. ocv:pyoldfunction:: cv.Undistort2(src, dst, cameraMatrix, distCoeffs)-> None + + :param src: Input (distorted) image. + + :param dst: Output (corrected) image that has the same size and type as ``src`` . + + :param cameraMatrix: Input camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . + + :param distCoeffs: Input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5, or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. + + :param newCameraMatrix: Camera matrix of the distorted image. By default, it is the same as ``cameraMatrix`` but you may additionally scale and shift the result by using a different matrix. + +The function transforms an image to compensate radial and tangential lens distortion. + +The function is simply a combination of +:ocv:func:`initUndistortRectifyMap` (with unity ``R`` ) and +:ocv:func:`remap` (with bilinear interpolation). See the former function for details of the transformation being performed. + +Those pixels in the destination image, for which there is no correspondent pixels in the source image, are filled with zeros (black color). + +A particular subset of the source image that will be visible in the corrected image can be regulated by ``newCameraMatrix`` . You can use +:ocv:func:`getOptimalNewCameraMatrix` to compute the appropriate ``newCameraMatrix`` depending on your requirements. + +The camera matrix and the distortion parameters can be determined using +:ocv:func:`calibrateCamera` . If the resolution of images is different from the resolution used at the calibration stage, +:math:`f_x, f_y, c_x` and +:math:`c_y` need to be scaled accordingly, while the distortion coefficients remain the same. + + + + +undistortPoints +------------------- +Computes the ideal point coordinates from the observed point coordinates. + +.. ocv:function:: void undistortPoints( InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray R=noArray(), InputArray P=noArray()) + +.. ocv:cfunction:: void cvUndistortPoints( const CvMat* src, CvMat* dst, const CvMat* camera_matrix, const CvMat* dist_coeffs, const CvMat* R=0, const CvMat* P=0 ) +.. ocv:pyoldfunction:: cv.UndistortPoints(src, dst, cameraMatrix, distCoeffs, R=None, P=None)-> None + + :param src: Observed point coordinates, 1xN or Nx1 2-channel (CV_32FC2 or CV_64FC2). + + :param dst: Output ideal point coordinates after undistortion and reverse perspective transformation. If matrix ``P`` is identity or omitted, ``dst`` will contain normalized point coordinates. + + :param cameraMatrix: Camera matrix :math:`\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . + + :param distCoeffs: Input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5, or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. + + :param R: Rectification transformation in the object space (3x3 matrix). ``R1`` or ``R2`` computed by :ocv:func:`stereoRectify` can be passed here. If the matrix is empty, the identity transformation is used. + + :param P: New camera matrix (3x3) or new projection matrix (3x4). ``P1`` or ``P2`` computed by :ocv:func:`stereoRectify` can be passed here. If the matrix is empty, the identity new camera matrix is used. + +The function is similar to +:ocv:func:`undistort` and +:ocv:func:`initUndistortRectifyMap` but it operates on a sparse set of points instead of a raster image. Also the function performs a reverse transformation to +:ocv:func:`projectPoints` . In case of a 3D object, it does not reconstruct its 3D coordinates, but for a planar object, it does, up to a translation vector, if the proper ``R`` is specified. :: + + // (u,v) is the input point, (u', v') is the output point + // camera_matrix=[fx 0 cx; 0 fy cy; 0 0 1] + // P=[fx' 0 cx' tx; 0 fy' cy' ty; 0 0 1 tz] + x" = (u - cx)/fx + y" = (v - cy)/fy + (x',y') = undistort(x",y",dist_coeffs) + [X,Y,W]T = R*[x' y' 1]T + x = X/W, y = Y/W + // only performed if P=[fx' 0 cx' [tx]; 0 fy' cy' [ty]; 0 0 1 [tz]] is specified + u' = x*fx' + cx' + v' = y*fy' + cy', + +where ``undistort()`` is an approximate iterative algorithm that estimates the normalized original point coordinates out of the normalized distorted point coordinates ("normalized" means that the coordinates do not depend on the camera matrix). + +The function can be used for both a stereo camera head or a monocular camera (when R is empty). + + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/histograms.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/histograms.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/histograms.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/histograms.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,506 @@ +Histograms +========== + +.. highlight:: cpp + + + +calcHist +------------ +Calculates a histogram of a set of arrays. + +.. ocv:function:: void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false ) + +.. ocv:function:: void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false ) + +.. ocv:pyfunction:: cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist + +.. ocv:cfunction:: void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL ) +.. ocv:pyoldfunction:: cv.CalcHist(image, hist, accumulate=0, mask=None)-> None + + :param images: Source arrays. They all should have the same depth, ``CV_8U`` or ``CV_32F`` , and the same size. Each of them can have an arbitrary number of channels. + + :param nimages: Number of source images. + + :param channels: List of the ``dims`` channels used to compute the histogram. The first array channels are numerated from 0 to ``images[0].channels()-1`` , the second array channels are counted from ``images[0].channels()`` to ``images[0].channels() + images[1].channels()-1``, and so on. + + :param mask: Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size as ``images[i]`` . The non-zero mask elements mark the array elements counted in the histogram. + + :param hist: Output histogram, which is a dense or sparse ``dims`` -dimensional array. + + :param dims: Histogram dimensionality that must be positive and not greater than ``CV_MAX_DIMS`` (equal to 32 in the current OpenCV version). + + :param histSize: Array of histogram sizes in each dimension. + + :param ranges: Array of the ``dims`` arrays of the histogram bin boundaries in each dimension. When the histogram is uniform ( ``uniform`` =true), then for each dimension ``i`` it is enough to specify the lower (inclusive) boundary :math:`L_0` of the 0-th histogram bin and the upper (exclusive) boundary :math:`U_{\texttt{histSize}[i]-1}` for the last histogram bin ``histSize[i]-1`` . That is, in case of a uniform histogram each of ``ranges[i]`` is an array of 2 elements. When the histogram is not uniform ( ``uniform=false`` ), then each of ``ranges[i]`` contains ``histSize[i]+1`` elements: :math:`L_0, U_0=L_1, U_1=L_2, ..., U_{\texttt{histSize[i]}-2}=L_{\texttt{histSize[i]}-1}, U_{\texttt{histSize[i]}-1}` . The array elements, that are not between :math:`L_0` and :math:`U_{\texttt{histSize[i]}-1}` , are not counted in the histogram. + + :param uniform: Flag indicating whether the histogram is uniform or not (see above). + + :param accumulate: Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time. + +The functions ``calcHist`` calculate the histogram of one or more +arrays. The elements of a tuple used to increment +a histogram bin are taken from the corresponding +input arrays at the same location. The sample below shows how to compute a 2D Hue-Saturation histogram for a color image. :: + + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + Mat src, hsv; + if( argc != 2 || !(src=imread(argv[1], 1)).data ) + return -1; + + cvtColor(src, hsv, CV_BGR2HSV); + + // Quantize the hue to 30 levels + // and the saturation to 32 levels + int hbins = 30, sbins = 32; + int histSize[] = {hbins, sbins}; + // hue varies from 0 to 179, see cvtColor + float hranges[] = { 0, 180 }; + // saturation varies from 0 (black-gray-white) to + // 255 (pure spectrum color) + float sranges[] = { 0, 256 }; + const float* ranges[] = { hranges, sranges }; + MatND hist; + // we compute the histogram from the 0-th and 1-st channels + int channels[] = {0, 1}; + + calcHist( &hsv, 1, channels, Mat(), // do not use mask + hist, 2, histSize, ranges, + true, // the histogram is uniform + false ); + double maxVal=0; + minMaxLoc(hist, 0, &maxVal, 0, 0); + + int scale = 10; + Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3); + + for( int h = 0; h < hbins; h++ ) + for( int s = 0; s < sbins; s++ ) + { + float binVal = hist.at(h, s); + int intensity = cvRound(binVal*255/maxVal); + rectangle( histImg, Point(h*scale, s*scale), + Point( (h+1)*scale - 1, (s+1)*scale - 1), + Scalar::all(intensity), + CV_FILLED ); + } + + namedWindow( "Source", 1 ); + imshow( "Source", src ); + + namedWindow( "H-S Histogram", 1 ); + imshow( "H-S Histogram", histImg ); + waitKey(); + } + + + + +calcBackProject +------------------- +Calculates the back projection of a histogram. + +.. ocv:function:: void calcBackProject( const Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true ) + +.. ocv:function:: void calcBackProject( const Mat* images, int nimages, const int* channels, const SparseMat& hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true ) + +.. ocv:pyfunction:: cv2.calcBackProject(images, channels, hist, ranges, scale[, dst]) -> dst + +.. ocv:cfunction:: void cvCalcBackProject( IplImage** image, CvArr* backProject, const CvHistogram* hist ) +.. ocv:pyoldfunction:: cv.CalcBackProject(image, back_project, hist) -> None + + :param images: Source arrays. They all should have the same depth, ``CV_8U`` or ``CV_32F`` , and the same size. Each of them can have an arbitrary number of channels. + + :param nimages: Number of source images. + + :param channels: The list of channels used to compute the back projection. The number of channels must match the histogram dimensionality. The first array channels are numerated from 0 to ``images[0].channels()-1`` , the second array channels are counted from ``images[0].channels()`` to ``images[0].channels() + images[1].channels()-1``, and so on. + + :param hist: Input histogram that can be dense or sparse. + + :param backProject: Destination back projection array that is a single-channel array of the same size and depth as ``images[0]`` . + + :param ranges: Array of arrays of the histogram bin boundaries in each dimension. See :ocv:func:`calcHist` . + + :param scale: Optional scale factor for the output back projection. + + :param uniform: Flag indicating whether the histogram is uniform or not (see above). + +The functions ``calcBackProject`` calculate the back project of the histogram. That is, similarly to ``calcHist`` , at each location ``(x, y)`` the function collects the values from the selected channels in the input images and finds the corresponding histogram bin. But instead of incrementing it, the function reads the bin value, scales it by ``scale`` , and stores in ``backProject(x,y)`` . In terms of statistics, the function computes probability of each element value in respect with the empirical probability distribution represented by the histogram. See how, for example, you can find and track a bright-colored object in a scene: + +#. + Before tracking, show the object to the camera so that it covers almost the whole frame. Calculate a hue histogram. The histogram may have strong maximums, corresponding to the dominant colors in the object. + +#. + When tracking, calculate a back projection of a hue plane of each input video frame using that pre-computed histogram. Threshold the back projection to suppress weak colors. It may also make sense to suppress pixels with non-sufficient color saturation and too dark or too bright pixels. + +#. + Find connected components in the resulting picture and choose, for example, the largest component. + +This is an approximate algorithm of the +:ocv:func:`CamShift` color object tracker. + +.. seealso:: :ocv:func:`calcHist` +.. _compareHist: + +compareHist +----------- +Compares two histograms. + +.. ocv:function:: double compareHist( InputArray H1, InputArray H2, int method ) + +.. ocv:function:: double compareHist( const SparseMat& H1, const SparseMat& H2, int method ) + +.. ocv:pyfunction:: cv2.compareHist(H1, H2, method) -> retval + +.. ocv:cfunction:: double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method ) +.. ocv:pyoldfunction:: cv.CompareHist(hist1, hist2, method)->float + + :param H1: First compared histogram. + + :param H2: Second compared histogram of the same size as ``H1`` . + + :param method: Comparison method that could be one of the following: + + * **CV_COMP_CORREL** Correlation + + * **CV_COMP_CHISQR** Chi-Square + + * **CV_COMP_INTERSECT** Intersection + + * **CV_COMP_BHATTACHARYYA** Bhattacharyya distance + + * **CV_COMP_HELLINGER** Synonym for ``CV_COMP_BHATTACHARYYA`` + +The functions ``compareHist`` compare two dense or two sparse histograms using the specified method: + +* Correlation (``method=CV_COMP_CORREL``) + + .. math:: + + d(H_1,H_2) = \frac{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}} + + where + + .. math:: + + \bar{H_k} = \frac{1}{N} \sum _J H_k(J) + + and + :math:`N` is a total number of histogram bins. + +* Chi-Square (``method=CV_COMP_CHISQR``) + + .. math:: + + d(H_1,H_2) = \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)} + +* Intersection (``method=CV_COMP_INTERSECT``) + + .. math:: + + d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I)) + +* Bhattacharyya distance (``method=CV_COMP_BHATTACHARYYA`` or ``method=CV_COMP_HELLINGER``). In fact, OpenCV computes Hellinger distance, which is related to Bhattacharyya coefficient. + + .. math:: + + d(H_1,H_2) = \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}} + +The function returns +:math:`d(H_1, H_2)` . + +While the function works well with 1-, 2-, 3-dimensional dense histograms, it may not be suitable for high-dimensional sparse histograms. In such histograms, because of aliasing and sampling problems, the coordinates of non-zero histogram bins can slightly shift. To compare such histograms or more general sparse configurations of weighted points, consider using the +:ocv:func:`EMD` function. + + + + +EMD +------ +Computes the "minimal work" distance between two weighted point configurations. + +.. ocv:function:: float EMD( InputArray signature1, InputArray signature2, int distType, InputArray cost=noArray(), float* lowerBound=0, OutputArray flow=noArray() ) + +.. ocv:cfunction:: float cvCalcEMD2( const CvArr* signature1, const CvArr* signature2, int distance_type, CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL, CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL ) + +.. ocv:pyoldfunction:: cv.CalcEMD2(signature1, signature2, distance_type, distance_func=None, cost_matrix=None, flow=None, lower_bound=None, userdata=None) -> float + + :param signature1: First signature, a :math:`\texttt{size1}\times \texttt{dims}+1` floating-point matrix. Each row stores the point weight followed by the point coordinates. The matrix is allowed to have a single column (weights only) if the user-defined cost matrix is used. + + :param signature2: Second signature of the same format as ``signature1`` , though the number of rows may be different. The total weights may be different. In this case an extra "dummy" point is added to either ``signature1`` or ``signature2`` . + + :param distType: Used metric. ``CV_DIST_L1, CV_DIST_L2`` , and ``CV_DIST_C`` stand for one of the standard metrics. ``CV_DIST_USER`` means that a pre-calculated cost matrix ``cost`` is used. + + :param distance_func: Custom distance function supported by the old interface. ``CvDistanceFunction`` is defined as: :: + + typedef float (CV_CDECL * CvDistanceFunction)( const float* a, + const float* b, void* userdata ); + + where ``a`` and ``b`` are point coordinates and ``userdata`` is the same as the last parameter. + + :param cost: User-defined :math:`\texttt{size1}\times \texttt{size2}` cost matrix. Also, if a cost matrix is used, lower boundary ``lowerBound`` cannot be calculated because it needs a metric function. + + :param lowerBound: Optional input/output parameter: lower boundary of a distance between the two signatures that is a distance between mass centers. The lower boundary may not be calculated if the user-defined cost matrix is used, the total weights of point configurations are not equal, or if the signatures consist of weights only (the signature matrices have a single column). You **must** initialize ``*lowerBound`` . If the calculated distance between mass centers is greater or equal to ``*lowerBound`` (it means that the signatures are far enough), the function does not calculate EMD. In any case ``*lowerBound`` is set to the calculated distance between mass centers on return. Thus, if you want to calculate both distance between mass centers and EMD, ``*lowerBound`` should be set to 0. + + :param flow: Resultant :math:`\texttt{size1} \times \texttt{size2}` flow matrix: :math:`\texttt{flow}_{i,j}` is a flow from :math:`i` -th point of ``signature1`` to :math:`j` -th point of ``signature2`` . + + :param userdata: Optional pointer directly passed to the custom distance function. + +The function computes the earth mover distance and/or a lower boundary of the distance between the two weighted point configurations. One of the applications described in [RubnerSept98]_ is multi-dimensional histogram comparison for image retrieval. EMD is a transportation problem that is solved using some modification of a simplex algorithm, thus the complexity is exponential in the worst case, though, on average it is much faster. In the case of a real metric the lower boundary can be calculated even faster (using linear-time algorithm) and it can be used to determine roughly whether the two signatures are far enough so that they cannot relate to the same object. + + +equalizeHist +---------------- +Equalizes the histogram of a grayscale image. + +.. ocv:function:: void equalizeHist( InputArray src, OutputArray dst ) + +.. ocv:pyfunction:: cv2.equalizeHist(src[, dst]) -> dst + +.. ocv:cfunction:: void cvEqualizeHist( const CvArr* src, CvArr* dst ) + + :param src: Source 8-bit single channel image. + + :param dst: Destination image of the same size and type as ``src`` . + +The function equalizes the histogram of the input image using the following algorithm: + +#. + Calculate the histogram + :math:`H` for ``src`` . + +#. + Normalize the histogram so that the sum of histogram bins is 255. + +#. + Compute the integral of the histogram: + + .. math:: + + H'_i = \sum _{0 \le j < i} H(j) + +#. + Transform the image using + :math:`H'` as a look-up table: + :math:`\texttt{dst}(x,y) = H'(\texttt{src}(x,y))` + +The algorithm normalizes the brightness and increases the contrast of the image. + + +Extra Histogram Functions (C API) +--------------------------------- + +The rest of the section describes additional C functions operating on ``CvHistogram``. + +CalcBackProjectPatch +-------------------- +Locates a template within an image by using a histogram comparison. + +.. ocv:cfunction:: void cvCalcBackProjectPatch( IplImage** images, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, double factor ) + +.. ocv:pyoldfunction:: cv.CalcBackProjectPatch(images, dst, patch_size, hist, method, factor)-> None + + :param images: Source images (though, you may pass CvMat** as well). + + :param dst: Destination image. + + :param patch_size: Size of the patch slid though the source image. + + :param hist: Histogram. + + :param method: Comparison method passed to :ocv:cfunc:`CompareHist` (see the function description). + + :param factor: Normalization factor for histograms that affects the normalization scale of the destination image. Pass 1 if not sure. + +The function calculates the back projection by comparing histograms of the source image patches with the given histogram. The function is similar to :ocv:func:`matchTemplate`, but instead of comparing the raster patch with all its possible positions within the search window, the function ``CalcBackProjectPatch`` compares histograms. See the algorithm diagram below: + +.. image:: pics/backprojectpatch.png + + +CalcProbDensity +--------------- +Divides one histogram by another. + +.. ocv:cfunction:: void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dst_hist, double scale=255 ) + +.. ocv:pyoldfunction:: cv.CalcProbDensity(hist1, hist2, dst_hist, scale=255) -> None + + :param hist1: First histogram (the divisor). + + :param hist2: Second histogram. + + :param dst_hist: Destination histogram. + + :param scale: Scale factor for the destination histogram. + +The function calculates the object probability density from two histograms as: + +.. math:: + + \texttt{disthist} (I)= \forkthree{0}{if $\texttt{hist1}(I)=0$}{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$} + + +ClearHist +--------- +Clears the histogram. + +.. ocv:cfunction:: void cvClearHist( CvHistogram* hist ) +.. ocv:pyoldfunction:: cv.ClearHist(hist)-> None + + :param hist: Histogram. + +The function sets all of the histogram bins to 0 in case of a dense histogram and removes all histogram bins in case of a sparse array. + + +CopyHist +-------- +Copies a histogram. + +.. ocv:cfunction:: void cvCopyHist( const CvHistogram* src, CvHistogram** dst ) + + :param src: Source histogram. + + :param dst: Pointer to the destination histogram. + +The function makes a copy of the histogram. If the second histogram pointer ``*dst`` is NULL, a new histogram of the same size as ``src`` is created. Otherwise, both histograms must have equal types and sizes. Then the function copies the bin values of the source histogram to the destination histogram and sets the same bin value ranges as in ``src``. + +.. _createhist: + +CreateHist +---------- +Creates a histogram. + +.. ocv:cfunction:: CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 ) + +.. ocv:pyoldfunction:: cv.CreateHist(dims, type, ranges=None, uniform=1) -> hist + + :param dims: Number of histogram dimensions. + + :param sizes: Array of the histogram dimension sizes. + + :param type: Histogram representation format. ``CV_HIST_ARRAY`` means that the histogram data is represented as a multi-dimensional dense array CvMatND. ``CV_HIST_SPARSE`` means that histogram data is represented as a multi-dimensional sparse array ``CvSparseMat``. + + :param ranges: Array of ranges for the histogram bins. Its meaning depends on the ``uniform`` parameter value. The ranges are used when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s). + + :param uniform: Uniformity flag. If not zero, the histogram has evenly + spaced bins and for every :math:`0<=i (min_value, max_value, min_idx, max_idx) + + :param hist: Histogram. + + :param min_value: Pointer to the minimum value of the histogram. + + :param max_value: Pointer to the maximum value of the histogram. + + :param min_idx: Pointer to the array of coordinates for the minimum. + + :param max_idx: Pointer to the array of coordinates for the maximum. + +The function finds the minimum and maximum histogram bins and their positions. All of output arguments are optional. Among several extremas with the same value the ones with the minimum index (in the lexicographical order) are returned. In case of several maximums or minimums, the earliest in the lexicographical order (extrema locations) is returned. + + +MakeHistHeaderForArray +---------------------- +Makes a histogram out of an array. + +.. ocv:cfunction:: CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist, float* data, float** ranges=NULL, int uniform=1 ) + + :param dims: Number of the histogram dimensions. + + :param sizes: Array of the histogram dimension sizes. + + :param hist: Histogram header initialized by the function. + + :param data: Array used to store histogram bins. + + :param ranges: Histogram bin ranges. See :ocv:cfunc:`CreateHist` for details. + + :param uniform: Uniformity flag. See :ocv:cfunc:`CreateHist` for details. + +The function initializes the histogram, whose header and bins are allocated by the user. :ocv:cfunc:`ReleaseHist` does not need to be called afterwards. Only dense histograms can be initialized this way. The function returns ``hist``. + +NormalizeHist +------------- +Normalizes the histogram. + +.. ocv:cfunction:: void cvNormalizeHist( CvHistogram* hist, double factor ) +.. ocv:pyoldfunction:: cv.NormalizeHist(hist, factor)-> None + + :param hist: Pointer to the histogram. + + :param factor: Normalization factor. + +The function normalizes the histogram bins by scaling them so that the sum of the bins becomes equal to ``factor``. + + +ReleaseHist +----------- +Releases the histogram. + +.. ocv:cfunction:: void cvReleaseHist( CvHistogram** hist ) + + :param hist: Double pointer to the released histogram. + +The function releases the histogram (header and the data). The pointer to the histogram is cleared by the function. If ``*hist`` pointer is already ``NULL``, the function does nothing. + + +SetHistBinRanges +---------------- +Sets the bounds of the histogram bins. + +.. ocv:cfunction:: void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 ) + + :param hist: Histogram. + + :param ranges: Array of bin ranges arrays. See :ocv:cfunc:`CreateHist` for details. + + :param uniform: Uniformity flag. See :ocv:cfunc:`CreateHist` for details. + +This is a standalone function for setting bin ranges in the histogram. For a more detailed description of the parameters ``ranges`` and ``uniform``, see the :ocv:cfunc:`CalcHist` function that can initialize the ranges as well. Ranges for the histogram bins must be set before the histogram is calculated or the backproject of the histogram is calculated. + + +ThreshHist +---------- +Thresholds the histogram. + +.. ocv:cfunction:: void cvThreshHist( CvHistogram* hist, double threshold ) +.. ocv:pyoldfunction:: cv.ThreshHist(hist, threshold) -> None + + :param hist: Pointer to the histogram. + + :param threshold: Threshold level. + +The function clears histogram bins that are below the specified threshold. + + +.. [RubnerSept98] Y. Rubner. C. Tomasi, L.J. Guibas. *The Earth Mover’s Distance as a Metric for Image Retrieval*. Technical Report STAN-CS-TN-98-86, Department of Computer Science, Stanford University, September 1998. diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/imgproc.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/imgproc.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/imgproc.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/imgproc.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,17 @@ +************************* +imgproc. Image Processing +************************* + +.. highlight:: cpp + +.. toctree:: + :maxdepth: 2 + + filtering + geometric_transformations + miscellaneous_transformations + histograms + structural_analysis_and_shape_descriptors + motion_analysis_and_object_tracking + feature_detection + object_detection diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/miscellaneous_transformations.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/miscellaneous_transformations.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/miscellaneous_transformations.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/miscellaneous_transformations.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,795 @@ +Miscellaneous Image Transformations +=================================== + +.. highlight:: cpp + + +adaptiveThreshold +--------------------- +Applies an adaptive threshold to an array. + +.. ocv:function:: void adaptiveThreshold( InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C ) + +.. ocv:pyfunction:: cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst + +.. ocv:cfunction:: void cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value, int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C, int threshold_type=CV_THRESH_BINARY, int block_size=3, double param1=5 ) + +.. ocv:pyoldfunction:: cv.AdaptiveThreshold(src, dst, maxValue, adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C, thresholdType=CV_THRESH_BINARY, blockSize=3, param1=5)-> None + + :param src: Source 8-bit single-channel image. + + :param dst: Destination image of the same size and the same type as ``src`` . + + :param maxValue: Non-zero value assigned to the pixels for which the condition is satisfied. See the details below. + + :param adaptiveMethod: Adaptive thresholding algorithm to use, ``ADAPTIVE_THRESH_MEAN_C`` or ``ADAPTIVE_THRESH_GAUSSIAN_C`` . See the details below. + + :param thresholdType: Thresholding type that must be either ``THRESH_BINARY`` or ``THRESH_BINARY_INV`` . + + :param blockSize: Size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on. + + :param C: Constant subtracted from the mean or weighted mean (see the details below). Normally, it is positive but may be zero or negative as well. + +The function transforms a grayscale image to a binary image according to the formulae: + + * **THRESH_BINARY** + + .. math:: + + dst(x,y) = \fork{\texttt{maxValue}}{if $src(x,y) > T(x,y)$}{0}{otherwise} + + * **THRESH_BINARY_INV** + + .. math:: + + dst(x,y) = \fork{0}{if $src(x,y) > T(x,y)$}{\texttt{maxValue}}{otherwise} + +where +:math:`T(x,y)` is a threshold calculated individually for each pixel. + +* + For the method ``ADAPTIVE_THRESH_MEAN_C`` , the threshold value + :math:`T(x,y)` is a mean of the + :math:`\texttt{blockSize} \times \texttt{blockSize}` neighborhood of + :math:`(x, y)` minus ``C`` . + +* + For the method ``ADAPTIVE_THRESH_GAUSSIAN_C`` , the threshold value + :math:`T(x, y)` is a weighted sum (cross-correlation with a Gaussian window) of the + :math:`\texttt{blockSize} \times \texttt{blockSize}` neighborhood of + :math:`(x, y)` minus ``C`` . The default sigma (standard deviation) is used for the specified ``blockSize`` . See + :ocv:func:`getGaussianKernel` . + +The function can process the image in-place. + +.. seealso:: + + :ocv:func:`threshold`, + :ocv:func:`blur`, + :ocv:func:`GaussianBlur` + + + +cvtColor +-------- +Converts an image from one color space to another. + +.. ocv:function:: void cvtColor( InputArray src, OutputArray dst, int code, int dstCn=0 ) + +.. ocv:pyfunction:: cv2.cvtColor(src, code[, dst[, dstCn]]) -> dst + +.. ocv:cfunction:: void cvCvtColor( const CvArr* src, CvArr* dst, int code ) +.. ocv:pyoldfunction:: cv.CvtColor(src, dst, code)-> None + + :param src: input image: 8-bit unsigned, 16-bit unsigned ( ``CV_16UC...`` ), or single-precision floating-point. + + :param dst: output image of the same size and depth as ``src``. + + :param code: color space conversion code (see the description below). + + :param dstCn: number of channels in the destination image; if the parameter is 0, the number of the channels is derived automatically from ``src`` and ``code`` . + +The function converts an input image from one color +space to another. In case of a transformation to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). +Note that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on. + +The conventional ranges for R, G, and B channel values are: + +* + 0 to 255 for ``CV_8U`` images + +* + 0 to 65535 for ``CV_16U`` images + +* + 0 to 1 for ``CV_32F`` images + +In case of linear transformations, the range does not matter. +But in case of a non-linear transformation, an input RGB image should be normalized to the proper value range to get the correct results, for example, for RGB +:math:`\rightarrow` L*u*v* transformation. For example, if you have a 32-bit floating-point image directly converted from an 8-bit image without any scaling, then it will have the 0..255 value range instead of 0..1 assumed by the function. So, before calling ``cvtColor`` , you need first to scale the image down: :: + + img *= 1./255; + cvtColor(img, img, CV_BGR2Luv); + +If you use ``cvtColor`` with 8-bit images, the conversion will have some information lost. For many applications, this will not be noticeable but it is recommended to use 32-bit images in applications that need the full range of colors or that convert an image before an operation and then convert back. + +The function can do the following transformations: + +* + Transformations within RGB space like adding/removing the alpha channel, reversing the channel order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion to/from grayscale using: + + .. math:: + + \text{RGB[A] to Gray:} \quad Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B + + and + + .. math:: + + \text{Gray to RGB[A]:} \quad R \leftarrow Y, G \leftarrow Y, B \leftarrow Y, A \leftarrow 0 + + The conversion from a RGB image to gray is done with: + + :: + + cvtColor(src, bwsrc, CV_RGB2GRAY); + + .. + + More advanced channel reordering can also be done with + :ocv:func:`mixChannels` . + +* + RGB + :math:`\leftrightarrow` CIE XYZ.Rec 709 with D65 white point ( ``CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB`` ): + + .. math:: + + \begin{bmatrix} X \\ Y \\ Z + \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227 + \end{bmatrix} \cdot \begin{bmatrix} R \\ G \\ B + \end{bmatrix} + + .. math:: + + \begin{bmatrix} R \\ G \\ B + \end{bmatrix} \leftarrow \begin{bmatrix} 3.240479 & -1.53715 & -0.498535 \\ -0.969256 & 1.875991 & 0.041556 \\ 0.055648 & -0.204043 & 1.057311 + \end{bmatrix} \cdot \begin{bmatrix} X \\ Y \\ Z + \end{bmatrix} + + :math:`X`, :math:`Y` and + :math:`Z` cover the whole value range (in case of floating-point images, + :math:`Z` may exceed 1). + +* + RGB + :math:`\leftrightarrow` YCrCb JPEG (or YCC) ( ``CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB`` ) + + .. math:: + + Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B + + .. math:: + + Cr \leftarrow (R-Y) \cdot 0.713 + delta + + .. math:: + + Cb \leftarrow (B-Y) \cdot 0.564 + delta + + .. math:: + + R \leftarrow Y + 1.403 \cdot (Cr - delta) + + .. math:: + + G \leftarrow Y - 0.714 \cdot (Cr - delta) - 0.344 \cdot (Cb - delta) + + .. math:: + + B \leftarrow Y + 1.773 \cdot (Cb - delta) + + where + + .. math:: + + delta = \left \{ \begin{array}{l l} 128 & \mbox{for 8-bit images} \\ 32768 & \mbox{for 16-bit images} \\ 0.5 & \mbox{for floating-point images} \end{array} \right . + + Y, Cr, and Cb cover the whole value range. + +* + RGB :math:`\leftrightarrow` HSV ( ``CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB`` ) + In case of 8-bit and 16-bit images, + R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. + + .. math:: + + V \leftarrow max(R,G,B) + + .. math:: + + S \leftarrow \fork{\frac{V-min(R,G,B)}{V}}{if $V \neq 0$}{0}{otherwise} + + .. math:: + + H \leftarrow \forkthree{{60(G - B)}/{(V-min(R,G,B))}}{if $V=R$}{{120+60(B - R)}/{(V-min(R,G,B))}}{if $V=G$}{{240+60(R - G)}/{(V-min(R,G,B))}}{if $V=B$} + + If + :math:`H<0` then + :math:`H \leftarrow H+360` . On output + :math:`0 \leq V \leq 1`, :math:`0 \leq S \leq 1`, :math:`0 \leq H \leq 360` . + + The values are then converted to the destination data type: + + * 8-bit images + + .. math:: + + V \leftarrow 255 V, S \leftarrow 255 S, H \leftarrow H/2 \text{(to fit to 0 to 255)} + + * 16-bit images (currently not supported) + + .. math:: + + V <- 65535 V, S <- 65535 S, H <- H + + * 32-bit images + H, S, and V are left as is + +* + RGB :math:`\leftrightarrow` HLS ( ``CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB`` ). + In case of 8-bit and 16-bit images, + R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. + + .. math:: + + V_{max} \leftarrow {max}(R,G,B) + + .. math:: + + V_{min} \leftarrow {min}(R,G,B) + + .. math:: + + L \leftarrow \frac{V_{max} + V_{min}}{2} + + .. math:: + + S \leftarrow \fork { \frac{V_{max} - V_{min}}{V_{max} + V_{min}} }{if $L < 0.5$ } + { \frac{V_{max} - V_{min}}{2 - (V_{max} + V_{min})} }{if $L \ge 0.5$ } + + .. math:: + + H \leftarrow \forkthree {{60(G - B)}/{S}}{if $V_{max}=R$ } + {{120+60(B - R)}/{S}}{if $V_{max}=G$ } + {{240+60(R - G)}/{S}}{if $V_{max}=B$ } + + If + :math:`H<0` then + :math:`H \leftarrow H+360` . On output + :math:`0 \leq L \leq 1`, :math:`0 \leq S \leq 1`, :math:`0 \leq H \leq 360` . + + The values are then converted to the destination data type: + + * 8-bit images + + .. math:: + + V \leftarrow 255 \cdot V, S \leftarrow 255 \cdot S, H \leftarrow H/2 \; \text{(to fit to 0 to 255)} + + * 16-bit images (currently not supported) + + .. math:: + + V <- 65535 \cdot V, S <- 65535 \cdot S, H <- H + + * 32-bit images + H, S, V are left as is + +* + RGB :math:`\leftrightarrow` CIE L*a*b* ( ``CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB`` ). + In case of 8-bit and 16-bit images, + R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. + + .. math:: + + \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} + + .. math:: + + X \leftarrow X/X_n, \text{where} X_n = 0.950456 + + .. math:: + + Z \leftarrow Z/Z_n, \text{where} Z_n = 1.088754 + + .. math:: + + L \leftarrow \fork{116*Y^{1/3}-16}{for $Y>0.008856$}{903.3*Y}{for $Y \le 0.008856$} + + .. math:: + + a \leftarrow 500 (f(X)-f(Y)) + delta + + .. math:: + + b \leftarrow 200 (f(Y)-f(Z)) + delta + + where + + .. math:: + + f(t)= \fork{t^{1/3}}{for $t>0.008856$}{7.787 t+16/116}{for $t\leq 0.008856$} + + and + + .. math:: + + delta = \fork{128}{for 8-bit images}{0}{for floating-point images} + + This outputs + :math:`0 \leq L \leq 100`, :math:`-127 \leq a \leq 127`, :math:`-127 \leq b \leq 127` . The values are then converted to the destination data type: + + * 8-bit images + + .. math:: + + L \leftarrow L*255/100, \; a \leftarrow a + 128, \; b \leftarrow b + 128 + + * 16-bit images + (currently not supported) + + * 32-bit images + L, a, and b are left as is + +* + RGB :math:`\leftrightarrow` CIE L*u*v* ( ``CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB`` ). + In case of 8-bit and 16-bit images, + R, G, and B are converted to the floating-point format and scaled to fit 0 to 1 range. + + .. math:: + + \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} + + .. math:: + + L \leftarrow \fork{116 Y^{1/3}}{for $Y>0.008856$}{903.3 Y}{for $Y\leq 0.008856$} + + .. math:: + + u' \leftarrow 4*X/(X + 15*Y + 3 Z) + + .. math:: + + v' \leftarrow 9*Y/(X + 15*Y + 3 Z) + + .. math:: + + u \leftarrow 13*L*(u' - u_n) \quad \text{where} \quad u_n=0.19793943 + + .. math:: + + v \leftarrow 13*L*(v' - v_n) \quad \text{where} \quad v_n=0.46831096 + + This outputs + :math:`0 \leq L \leq 100`, :math:`-134 \leq u \leq 220`, :math:`-140 \leq v \leq 122` . + + The values are then converted to the destination data type: + + * 8-bit images + + .. math:: + + L \leftarrow 255/100 L, \; u \leftarrow 255/354 (u + 134), \; v \leftarrow 255/256 (v + 140) + + * 16-bit images + (currently not supported) + + * 32-bit images + L, u, and v are left as is + + The above formulae for converting RGB to/from various color spaces have been taken from multiple sources on the web, primarily from the Charles Poynton site + http://www.poynton.com/ColorFAQ.html + +* + Bayer :math:`\rightarrow` RGB ( ``CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB`` ). The Bayer pattern is widely used in CCD and CMOS cameras. It enables you to get color pictures from a single plane where R,G, and B pixels (sensors of a particular component) are interleaved as follows: + + .. image:: pics/bayer.png + + The output RGB components of a pixel are interpolated from 1, 2, or + 4 neighbors of the pixel having the same color. There are several + modifications of the above pattern that can be achieved by shifting + the pattern one pixel left and/or one pixel up. The two letters + :math:`C_1` and + :math:`C_2` in the conversion constants ``CV_Bayer`` :math:`C_1 C_2` ``2BGR`` and ``CV_Bayer`` :math:`C_1 C_2` ``2RGB`` indicate the particular pattern + type. These are components from the second row, second and third + columns, respectively. For example, the above pattern has a very + popular "BG" type. + + +distanceTransform +----------------- +Calculates the distance to the closest zero pixel for each pixel of the source image. + +.. ocv:function:: void distanceTransform( InputArray src, OutputArray dst, int distanceType, int maskSize ) + +.. ocv:function:: void distanceTransform( InputArray src, OutputArray dst, OutputArray labels, int distanceType, int maskSize, int labelType=DIST_LABEL_CCOMP ) + +.. ocv:pyfunction:: cv2.distanceTransform(src, distanceType, maskSize[, dst]) -> dst + +.. ocv:cfunction:: void cvDistTransform( const CvArr* src, CvArr* dst, int distance_type=CV_DIST_L2, int mask_size=3, const float* mask=NULL, CvArr* labels=NULL, int labelType=CV_DIST_LABEL_CCOMP ) + +.. ocv:pyoldfunction:: cv.DistTransform(src, dst, distance_type=CV_DIST_L2, mask_size=3, mask=None, labels=None) -> None + + :param src: 8-bit, single-channel (binary) source image. + + :param dst: Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as ``src`` . + + :param distanceType: Type of distance. It can be ``CV_DIST_L1, CV_DIST_L2`` , or ``CV_DIST_C`` . + + :param maskSize: Size of the distance transform mask. It can be 3, 5, or ``CV_DIST_MASK_PRECISE`` (the latter option is only supported by the first function). In case of the ``CV_DIST_L1`` or ``CV_DIST_C`` distance type, the parameter is forced to 3 because a :math:`3\times 3` mask gives the same result as :math:`5\times 5` or any larger aperture. + + :param labels: Optional output 2D array of labels (the discrete Voronoi diagram). It has the type ``CV_32SC1`` and the same size as ``src`` . See the details below. + + :param labelType: Type of the label array to build. If ``labelType==DIST_LABEL_CCOMP`` then each connected component of zeros in ``src`` (as well as all the non-zero pixels closest to the connected component) will be assigned the same label. If ``labelType==DIST_LABEL_PIXEL`` then each zero pixel (and all the non-zero pixels closest to it) gets its own label. + +The functions ``distanceTransform`` calculate the approximate or precise +distance from every binary image pixel to the nearest zero pixel. +For zero image pixels, the distance will obviously be zero. + +When ``maskSize == CV_DIST_MASK_PRECISE`` and ``distanceType == CV_DIST_L2`` , the function runs the algorithm described in [Felzenszwalb04]_. This algorithm is parallelized with the TBB library. + +In other cases, the algorithm +[Borgefors86]_ +is used. This means that +for a pixel the function finds the shortest path to the nearest zero pixel +consisting of basic shifts: horizontal, +vertical, diagonal, or knight's move (the latest is available for a +:math:`5\times 5` mask). The overall distance is calculated as a sum of these +basic distances. Since the distance function should be symmetric, +all of the horizontal and vertical shifts must have the same cost (denoted as ``a`` ), all the diagonal shifts must have the +same cost (denoted as ``b`` ), and all knight's moves must have +the same cost (denoted as ``c`` ). For the ``CV_DIST_C`` and ``CV_DIST_L1`` types, the distance is calculated precisely, +whereas for ``CV_DIST_L2`` (Euclidean distance) the distance +can be calculated only with a relative error (a +:math:`5\times 5` mask +gives more accurate results). For ``a``,``b`` , and ``c`` , OpenCV uses the values suggested in the original paper: + +.. table:: + + ============== =================== ====================== + ``CV_DIST_C`` :math:`(3\times 3)` a = 1, b = 1 \ + ============== =================== ====================== + ``CV_DIST_L1`` :math:`(3\times 3)` a = 1, b = 2 \ + ``CV_DIST_L2`` :math:`(3\times 3)` a=0.955, b=1.3693 \ + ``CV_DIST_L2`` :math:`(5\times 5)` a=1, b=1.4, c=2.1969 \ + ============== =================== ====================== + +Typically, for a fast, coarse distance estimation ``CV_DIST_L2``, a +:math:`3\times 3` mask is used. For a more accurate distance estimation ``CV_DIST_L2`` , a +:math:`5\times 5` mask or the precise algorithm is used. +Note that both the precise and the approximate algorithms are linear on the number of pixels. + +The second variant of the function does not only compute the minimum distance for each pixel +:math:`(x, y)` but also identifies the nearest connected +component consisting of zero pixels (``labelType==DIST_LABEL_CCOMP``) or the nearest zero pixel (``labelType==DIST_LABEL_PIXEL``). Index of the component/pixel is stored in +:math:`\texttt{labels}(x, y)` . +When ``labelType==DIST_LABEL_CCOMP``, the function automatically finds connected components of zero pixels in the input image and marks them with distinct labels. When ``labelType==DIST_LABEL_CCOMP``, the function scans through the input image and marks all the zero pixels with distinct labels. + +In this mode, the complexity is still linear. +That is, the function provides a very fast way to compute the Voronoi diagram for a binary image. +Currently, the second variant can use only the approximate distance transform algorithm, i.e. ``maskSize=CV_DIST_MASK_PRECISE`` is not supported yet. + +floodFill +--------- +Fills a connected component with the given color. + +.. ocv:function:: int floodFill( InputOutputArray image, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 ) + +.. ocv:function:: int floodFill( InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 ) + +.. ocv:pyfunction:: cv2.floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]]) -> retval, rect + +.. ocv:cfunction:: void cvFloodFill( CvArr* image, CvPoint seed_point, CvScalar new_val, CvScalar lo_diff=cvScalarAll(0), CvScalar up_diff=cvScalarAll(0), CvConnectedComp* comp=NULL, int flags=4, CvArr* mask=NULL ) +.. ocv:pyoldfunction:: cv.FloodFill(image, seed_point, new_val, lo_diff=(0, 0, 0, 0), up_diff=(0, 0, 0, 0), flags=4, mask=None)-> comp + + :param image: Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the function unless the ``FLOODFILL_MASK_ONLY`` flag is set in the second variant of the function. See the details below. + + :param mask: (For the second function only) Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller. The function uses and updates the mask, so you take responsibility of initializing the ``mask`` content. Flood-filling cannot go across non-zero pixels in the mask. For example, an edge detector output can be used as a mask to stop filling at edges. It is possible to use the same mask in multiple calls to the function to make sure the filled area does not overlap. + + .. note:: Since the mask is larger than the filled image, a pixel :math:`(x, y)` in ``image`` corresponds to the pixel :math:`(x+1, y+1)` in the ``mask`` . + + :param seedPoint: Starting point. + + :param newVal: New value of the repainted domain pixels. + + :param loDiff: Maximal lower brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. + + :param upDiff: Maximal upper brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. + + :param rect: Optional output parameter set by the function to the minimum bounding rectangle of the repainted domain. + + :param flags: Operation flags. Lower bits contain a connectivity value, 4 (default) or 8, used within the function. Connectivity determines which neighbors of a pixel are considered. Upper bits can be 0 or a combination of the following flags: + + * **FLOODFILL_FIXED_RANGE** If set, the difference between the current pixel and seed pixel is considered. Otherwise, the difference between neighbor pixels is considered (that is, the range is floating). + + * **FLOODFILL_MASK_ONLY** If set, the function does not change the image ( ``newVal`` is ignored), but fills the mask. The flag can be used for the second variant only. + +The functions ``floodFill`` fill a connected component starting from the seed point with the specified color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The pixel at +:math:`(x,y)` is considered to belong to the repainted domain if: + +* + .. math:: + + \texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x',y')+ \texttt{upDiff} + + in case of a grayscale image and floating range + +* + + .. math:: + + \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)+ \texttt{upDiff} + + in case of a grayscale image and fixed range + +* + + .. math:: + + \texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r, + + .. math:: + + \texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g + + and + + .. math:: + + \texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b + + in case of a color image and floating range + + +* + + .. math:: + + \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r+ \texttt{upDiff} _r, + + .. math:: + + \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g+ \texttt{upDiff} _g + + and + + .. math:: + + \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b+ \texttt{upDiff} _b + + in case of a color image and fixed range + +where +:math:`src(x',y')` is the value of one of pixel neighbors that is already known to belong to the component. That is, to be added to the connected component, a color/brightness of the pixel should be close enough to: + +* + Color/brightness of one of its neighbors that already belong to the connected component in case of a floating range. + +* + Color/brightness of the seed point in case of a fixed range. + +Use these functions to either mark a connected component with the specified color in-place, or build a mask and then extract the contour, or copy the region to another image, and so on. Various modes of the function are demonstrated in the ``floodfill.cpp`` sample. + +.. seealso:: :ocv:func:`findContours` + + + +integral +-------- +Calculates the integral of an image. + +.. ocv:function:: void integral( InputArray src, OutputArray sum, int sdepth=-1 ) + +.. ocv:function:: void integral( InputArray src, OutputArray sum, OutputArray sqsum, int sdepth=-1 ) + +.. ocv:function:: void integral( InputArray src, OutputArray sum, OutputArray sqsum, OutputArray tilted, int sdepth=-1 ) + +.. ocv:pyfunction:: cv2.integral(src[, sum[, sdepth]]) -> sum + +.. ocv:pyfunction:: cv2.integral2(src[, sum[, sqsum[, sdepth]]]) -> sum, sqsum + +.. ocv:pyfunction:: cv2.integral3(src[, sum[, sqsum[, tilted[, sdepth]]]]) -> sum, sqsum, tilted + +.. ocv:cfunction:: void cvIntegral( const CvArr* image, CvArr* sum, CvArr* sqsum=NULL, CvArr* tilted_sum=NULL ) + +.. ocv:pyoldfunction:: cv.Integral(image, sum, sqsum=None, tiltedSum=None)-> None + + :param image: input image as :math:`W \times H`, 8-bit or floating-point (32f or 64f). + + :param sum: integral image as :math:`(W+1)\times (H+1)` , 32-bit integer or floating-point (32f or 64f). + + :param sqsum: integral image for squared pixel values; it is :math:`(W+1)\times (H+1)`, double-precision floating-point (64f) array. + + :param tilted: integral for the image rotated by 45 degrees; it is :math:`(W+1)\times (H+1)` array with the same data type as ``sum``. + + :param sdepth: desired depth of the integral and the tilted integral images, ``CV_32S``, ``CV_32F``, or ``CV_64F``. + +The functions calculate one or more integral images for the source image as follows: + +.. math:: + + \texttt{sum} (X,Y) = \sum _{x retval, dst + +.. ocv:cfunction:: double cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ) + +.. ocv:pyoldfunction:: cv.Threshold(src, dst, threshold, maxValue, thresholdType)-> None + + :param src: input array (single-channel, 8-bit or 32-bit floating point). + + :param dst: output array of the same size and type as ``src``. + + :param thresh: threshold value. + + :param maxval: maximum value to use with the ``THRESH_BINARY`` and ``THRESH_BINARY_INV`` thresholding types. + + :param type: thresholding type (see the details below). + +The function applies fixed-level thresholding +to a single-channel array. The function is typically used to get a +bi-level (binary) image out of a grayscale image ( +:ocv:func:`compare` could +be also used for this purpose) or for removing a noise, that is, filtering +out pixels with too small or too large values. There are several +types of thresholding supported by the function. They are determined by ``type`` : + + * **THRESH_BINARY** + + .. math:: + + \texttt{dst} (x,y) = \fork{\texttt{maxval}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise} + + * **THRESH_BINARY_INV** + + .. math:: + + \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{maxval}}{otherwise} + + * **THRESH_TRUNC** + + .. math:: + + \texttt{dst} (x,y) = \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise} + + * **THRESH_TOZERO** + + .. math:: + + \texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise} + + * **THRESH_TOZERO_INV** + + .. math:: + + \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise} + +Also, the special value ``THRESH_OTSU`` may be combined with +one of the above values. In this case, the function determines the optimal threshold +value using the Otsu's algorithm and uses it instead of the specified ``thresh`` . +The function returns the computed threshold value. +Currently, the Otsu's method is implemented only for 8-bit images. + + +.. image:: pics/threshold.png + +.. seealso:: + + :ocv:func:`adaptiveThreshold`, + :ocv:func:`findContours`, + :ocv:func:`compare`, + :ocv:func:`min`, + :ocv:func:`max` + + +watershed +--------- +Performs a marker-based image segmentation using the watershed algorithm. + +.. ocv:function:: void watershed( InputArray image, InputOutputArray markers ) + +.. ocv:cfunction:: void cvWatershed( const CvArr* image, CvArr* markers ) + +.. ocv:pyfunction:: cv2.watershed(image, markers) -> None + + :param image: Input 8-bit 3-channel image. + + :param markers: Input/output 32-bit single-channel image (map) of markers. It should have the same size as ``image`` . + +The function implements one of the variants of watershed, non-parametric marker-based segmentation algorithm, described in [Meyer92]_. + +Before passing the image to the function, you have to roughly outline the desired regions in the image ``markers`` with positive (``>0``) indices. So, every region is represented as one or more connected components with the pixel values 1, 2, 3, and so on. Such markers can be retrieved from a binary mask using :ocv:func:`findContours` and :ocv:func:`drawContours` (see the ``watershed.cpp`` demo). The markers are "seeds" of the future image regions. All the other pixels in ``markers`` , whose relation to the outlined regions is not known and should be defined by the algorithm, should be set to 0's. In the function output, each pixel in markers is set to a value of the "seed" components or to -1 at boundaries between the regions. + +Visual demonstration and usage example of the function can be found in the OpenCV samples directory (see the ``watershed.cpp`` demo). + +.. note:: Any two neighbor connected components are not necessarily separated by a watershed boundary (-1's pixels); for example, they can touch each other in the initial marker image passed to the function. + +.. seealso:: :ocv:func:`findContours` + +grabCut +------- +Runs the GrabCut algorithm. + +.. ocv:function:: void grabCut( InputArray img, InputOutputArray mask, Rect rect, InputOutputArray bgdModel, InputOutputArray fgdModel, int iterCount, int mode=GC_EVAL ) + +.. ocv:pyfunction:: cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) -> None + + :param img: Input 8-bit 3-channel image. + + :param mask: Input/output 8-bit single-channel mask. The mask is initialized by the function when ``mode`` is set to ``GC_INIT_WITH_RECT``. Its elements may have one of following values: + + * **GC_BGD** defines an obvious background pixels. + + * **GC_FGD** defines an obvious foreground (object) pixel. + + * **GC_PR_BGD** defines a possible background pixel. + + * **GC_PR_BGD** defines a possible foreground pixel. + + :param rect: ROI containing a segmented object. The pixels outside of the ROI are marked as "obvious background". The parameter is only used when ``mode==GC_INIT_WITH_RECT`` . + + :param bgdModel: Temporary array for the background model. Do not modify it while you are processing the same image. + + :param fgdModel: Temporary arrays for the foreground model. Do not modify it while you are processing the same image. + + :param iterCount: Number of iterations the algorithm should make before returning the result. Note that the result can be refined with further calls with ``mode==GC_INIT_WITH_MASK`` or ``mode==GC_EVAL`` . + + :param mode: Operation mode that could be one of the following: + + * **GC_INIT_WITH_RECT** The function initializes the state and the mask using the provided rectangle. After that it runs ``iterCount`` iterations of the algorithm. + + * **GC_INIT_WITH_MASK** The function initializes the state using the provided mask. Note that ``GC_INIT_WITH_RECT`` and ``GC_INIT_WITH_MASK`` can be combined. Then, all the pixels outside of the ROI are automatically initialized with ``GC_BGD`` . + + * **GC_EVAL** The value means that the algorithm should just resume. + +The function implements the `GrabCut image segmentation algorithm `_. +See the sample ``grabcut.cpp`` to learn how to use the function. + +.. [Borgefors86] Borgefors, Gunilla, *Distance transformations in digital images*. Comput. Vision Graph. Image Process. 34 3, pp 344–371 (1986) + +.. [Felzenszwalb04] Felzenszwalb, Pedro F. and Huttenlocher, Daniel P. *Distance Transforms of Sampled Functions*, TR2004-1963, TR2004-1963 (2004) + +.. [Meyer92] Meyer, F. *Color Image Segmentation*, ICIP92, 1992 + +.. [Telea04] Alexandru Telea, *An Image Inpainting Technique Based on the Fast Marching Method*. Journal of Graphics, GPU, and Game Tools 9 1, pp 23-34 (2004) diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/motion_analysis_and_object_tracking.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/motion_analysis_and_object_tracking.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/motion_analysis_and_object_tracking.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/motion_analysis_and_object_tracking.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,222 @@ +Motion Analysis and Object Tracking +=================================== + +.. highlight:: cpp + +accumulate +-------------- +Adds an image to the accumulator. + +.. ocv:function:: void accumulate( InputArray src, InputOutputArray dst, InputArray mask=noArray() ) + +.. ocv:pyfunction:: cv2.accumulate(src, dst[, mask]) -> None + +.. ocv:cfunction:: void cvAcc( const CvArr* image, CvArr* sum, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.Acc(image, sum, mask=None) -> None + + :param src: Input image as 1- or 3-channel, 8-bit or 32-bit floating point. + + :param dst: Accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point. + + :param mask: Optional operation mask. + +The function adds ``src`` or some of its elements to ``dst`` : + +.. math:: + + \texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 + +The function supports multi-channel images. Each channel is processed independently. + +The functions ``accumulate*`` can be used, for example, to collect statistics of a scene background viewed by a still camera and for the further foreground-background segmentation. + +.. seealso:: + + :ocv:func:`accumulateSquare`, + :ocv:func:`accumulateProduct`, + :ocv:func:`accumulateWeighted` + + + +accumulateSquare +-------------------- +Adds the square of a source image to the accumulator. + +.. ocv:function:: void accumulateSquare( InputArray src, InputOutputArray dst, InputArray mask=noArray() ) + +.. ocv:pyfunction:: cv2.accumulateSquare(src, dst[, mask]) -> None + +.. ocv:cfunction:: void cvSquareAcc( const CvArr* image, CvArr* sqsum, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.SquareAcc(image, sqsum, mask=None) -> None + + :param src: Input image as 1- or 3-channel, 8-bit or 32-bit floating point. + + :param dst: Accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point. + + :param mask: Optional operation mask. + +The function adds the input image ``src`` or its selected region, raised to a power of 2, to the accumulator ``dst`` : + +.. math:: + + \texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src} (x,y)^2 \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 + +The function supports multi-channel images. Each channel is processed independently. + +.. seealso:: + + :ocv:func:`accumulateSquare`, + :ocv:func:`accumulateProduct`, + :ocv:func:`accumulateWeighted` + + + +accumulateProduct +--------------------- +Adds the per-element product of two input images to the accumulator. + +.. ocv:function:: void accumulateProduct( InputArray src1, InputArray src2, InputOutputArray dst, InputArray mask=noArray() ) + +.. ocv:pyfunction:: cv2.accumulateProduct(src1, src2, dst[, mask]) -> None + +.. ocv:cfunction:: void cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc, const CvArr* mask=NULL ) + +.. ocv:pyoldfunction:: cv.MultiplyAcc(image1, image2, acc, mask=None)-> None + + :param src1: First input image, 1- or 3-channel, 8-bit or 32-bit floating point. + + :param src2: Second input image of the same type and the same size as ``src1`` . + + :param dst: Accumulator with the same number of channels as input images, 32-bit or 64-bit floating-point. + + :param mask: Optional operation mask. + +The function adds the product of two images or their selected regions to the accumulator ``dst`` : + +.. math:: + + \texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src1} (x,y) \cdot \texttt{src2} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 + +The function supports multi-channel images. Each channel is processed independently. + +.. seealso:: + + :ocv:func:`accumulate`, + :ocv:func:`accumulateSquare`, + :ocv:func:`accumulateWeighted` + + + +accumulateWeighted +---------------------- +Updates a running average. + +.. ocv:function:: void accumulateWeighted( InputArray src, InputOutputArray dst, double alpha, InputArray mask=noArray() ) + +.. ocv:pyfunction:: cv2.accumulateWeighted(src, dst, alpha[, mask]) -> None + +.. ocv:cfunction:: void cvRunningAvg( const CvArr* image, CvArr* acc, double alpha, const CvArr* mask=NULL ) +.. ocv:pyoldfunction:: cv.RunningAvg(image, acc, alpha, mask=None)-> None + + :param src: Input image as 1- or 3-channel, 8-bit or 32-bit floating point. + + :param dst: Accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point. + + :param alpha: Weight of the input image. + + :param mask: Optional operation mask. + +The function calculates the weighted sum of the input image ``src`` and the accumulator ``dst`` so that ``dst`` becomes a running average of a frame sequence: + +.. math:: + + \texttt{dst} (x,y) \leftarrow (1- \texttt{alpha} ) \cdot \texttt{dst} (x,y) + \texttt{alpha} \cdot \texttt{src} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 + +That is, ``alpha`` regulates the update speed (how fast the accumulator "forgets" about earlier images). +The function supports multi-channel images. Each channel is processed independently. + +.. seealso:: + + :ocv:func:`accumulate`, + :ocv:func:`accumulateSquare`, + :ocv:func:`accumulateProduct` + + + +phaseCorrelate +-------------- +The function is used to detect translational shifts that occur between two images. The operation takes advantage of the Fourier shift theorem for detecting the translational shift in the frequency domain. It can be used for fast image registration as well as motion estimation. For more information please see http://en.wikipedia.org/wiki/Phase\_correlation . + +Calculates the cross-power spectrum of two supplied source arrays. The arrays are padded if needed with :ocv:func:`getOptimalDFTSize`. + +.. ocv:function:: Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray()) + +.. ocv:function:: Point2d phaseCorrelateRes(InputArray src1, InputArray src2, InputArray window, double* response = 0) + + :param src1: Source floating point array (CV_32FC1 or CV_64FC1) + :param src2: Source floating point array (CV_32FC1 or CV_64FC1) + :param window: Floating point array with windowing coefficients to reduce edge effects (optional). + :param response: Signal power within the 5x5 centroid around the peak, between 0 and 1 (optional). + +Return value: detected phase shift (sub-pixel) between the two arrays. + +The function performs the following equations + +* First it applies a Hanning window (see http://en.wikipedia.org/wiki/Hann\_function) to each image to remove possible edge effects. This window is cached until the array size changes to speed up processing time. + +* Next it computes the forward DFTs of each source array: + + .. math:: + + \mathbf{G}_a = \mathcal{F}\{src_1\}, \; \mathbf{G}_b = \mathcal{F}\{src_2\} + + where + :math:`\mathcal{F}` is the forward DFT. + +* It then computes the cross-power spectrum of each frequency domain array: + + .. math:: + + R = \frac{ \mathbf{G}_a \mathbf{G}_b^*}{|\mathbf{G}_a \mathbf{G}_b^*|} + +* Next the cross-correlation is converted back into the time domain via the inverse DFT: + + .. math:: + + r = \mathcal{F}^{-1}\{R\} + +* Finally, it computes the peak location and computes a 5x5 weighted centroid around the peak to achieve sub-pixel accuracy. + + .. math:: + + (\Delta x, \Delta y) = \texttt{weightedCentroid} \{\arg \max_{(x, y)}\{r\}\} + +* If non-zero, the response parameter is computed as the sum of the elements of r within the 5x5 centroid around the peak location. It is normalized to a maximum of 1 (meaning there is a single peak) and will be smaller when there are multiple peaks. + +.. seealso:: + :ocv:func:`dft`, + :ocv:func:`getOptimalDFTSize`, + :ocv:func:`idft`, + :ocv:func:`mulSpectrums` + :ocv:func:`createHanningWindow` + +createHanningWindow +------------------------------- +This function computes a Hanning window coefficients in two dimensions. See http://en.wikipedia.org/wiki/Hann\_function and http://en.wikipedia.org/wiki/Window\_function for more information. + +.. ocv:function:: void createHanningWindow(OutputArray dst, Size winSize, int type) + + :param dst: Destination array to place Hann coefficients in + :param winSize: The window size specifications + :param type: Created array type + +An example is shown below: :: + + // create hanning window of size 100x100 and type CV_32F + Mat hann; + createHanningWindow(hann, Size(100, 100), CV_32F); + +.. seealso:: + :ocv:func:`phaseCorrelate` diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/object_detection.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/object_detection.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/object_detection.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/object_detection.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,76 @@ +Object Detection +================ + +.. highlight:: cpp + +matchTemplate +----------------- +Compares a template against overlapped image regions. + +.. ocv:function:: void matchTemplate( InputArray image, InputArray templ, OutputArray result, int method ) + +.. ocv:pyfunction:: cv2.matchTemplate(image, templ, method[, result]) -> result + +.. ocv:cfunction:: void cvMatchTemplate( const CvArr* image, const CvArr* templ, CvArr* result, int method ) +.. ocv:pyoldfunction:: cv.MatchTemplate(image, templ, result, method)-> None + + :param image: Image where the search is running. It must be 8-bit or 32-bit floating-point. + + :param templ: Searched template. It must be not greater than the source image and have the same data type. + + :param result: Map of comparison results. It must be single-channel 32-bit floating-point. If ``image`` is :math:`W \times H` and ``templ`` is :math:`w \times h` , then ``result`` is :math:`(W-w+1) \times (H-h+1)` . + + :param method: Parameter specifying the comparison method (see below). + +The function slides through ``image`` , compares the +overlapped patches of size +:math:`w \times h` against ``templ`` using the specified method and stores the comparison results in ``result`` . Here are the formulae for the available comparison +methods ( +:math:`I` denotes ``image``, :math:`T` ``template``, :math:`R` ``result`` ). The summation is done over template and/or the +image patch: +:math:`x' = 0...w-1, y' = 0...h-1` +* method=CV\_TM\_SQDIFF + + .. math:: + + R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2 + +* method=CV\_TM\_SQDIFF\_NORMED + + .. math:: + + R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} + +* method=CV\_TM\_CCORR + + .. math:: + + R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y')) + +* method=CV\_TM\_CCORR\_NORMED + + .. math:: + + R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} + +* method=CV\_TM\_CCOEFF + + .. math:: + + R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) + + where + + .. math:: + + \begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array} + +* method=CV\_TM\_CCOEFF\_NORMED + + .. math:: + + R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} } + +After the function finishes the comparison, the best matches can be found as global minimums (when ``CV_TM_SQDIFF`` was used) or maximums (when ``CV_TM_CCORR`` or ``CV_TM_CCOEFF`` was used) using the +:ocv:func:`minMaxLoc` function. In case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels and separate mean values are used for each channel. That is, the function can take a color template and a color image. The result will still be a single-channel image, which is easier to analyze. + Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/backprojectpatch.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/backprojectpatch.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/bayer.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/bayer.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/boundingrect.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/boundingrect.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/building.jpg and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/building.jpg differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/contoursecarea.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/contoursecarea.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/cornersubpix.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/cornersubpix.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/defects.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/defects.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/houghp.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/houghp.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/integral.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/integral.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/inv_logpolar.jpg and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/inv_logpolar.jpg differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/logpolar.jpg and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/logpolar.jpg differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/minareabox.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/minareabox.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/pointpolygon.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/pointpolygon.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/quadedge.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/quadedge.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/subdiv.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/subdiv.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/opencv/imgproc/doc/pics/threshold.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/opencv/imgproc/doc/pics/threshold.png differ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/doc/structural_analysis_and_shape_descriptors.rst diffimg-2.0.0/3rdparty/opencv/imgproc/doc/structural_analysis_and_shape_descriptors.rst --- diffimg-1.5.0/3rdparty/opencv/imgproc/doc/structural_analysis_and_shape_descriptors.rst 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/doc/structural_analysis_and_shape_descriptors.rst 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,717 @@ +Structural Analysis and Shape Descriptors +========================================= + +.. highlight:: cpp + +moments +----------- +Calculates all of the moments up to the third order of a polygon or rasterized shape. + +.. ocv:function:: Moments moments( InputArray array, bool binaryImage=false ) + +.. ocv:pyfunction:: cv2.moments(array[, binaryImage]) -> retval + +.. ocv:cfunction:: void cvMoments( const CvArr* arr, CvMoments* moments, int binary=0 ) + +.. ocv:pyoldfunction:: cv.Moments(arr, binary=0) -> moments + + :param array: Raster image (single-channel, 8-bit or floating-point 2D array) or an array ( :math:`1 \times N` or :math:`N \times 1` ) of 2D points (``Point`` or ``Point2f`` ). + + :param binaryImage: If it is true, all non-zero image pixels are treated as 1's. The parameter is used for images only. + + :param moments: Output moments. + +The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The results are returned in the structure ``Moments`` defined as: :: + + class Moments + { + public: + Moments(); + Moments(double m00, double m10, double m01, double m20, double m11, + double m02, double m30, double m21, double m12, double m03 ); + Moments( const CvMoments& moments ); + operator CvMoments() const; + + // spatial moments + double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; + // central moments + double mu20, mu11, mu02, mu30, mu21, mu12, mu03; + // central normalized moments + double nu20, nu11, nu02, nu30, nu21, nu12, nu03; + } + +In case of a raster image, the spatial moments :math:`\texttt{Moments::m}_{ji}` are computed as: + +.. math:: + + \texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right ) + +The central moments +:math:`\texttt{Moments::mu}_{ji}` are computed as: + +.. math:: + + \texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right ) + +where +:math:`(\bar{x}, \bar{y})` is the mass center: + +.. math:: + + \bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}} + +The normalized central moments +:math:`\texttt{Moments::nu}_{ij}` are computed as: + +.. math:: + + \texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} . + +.. note:: + + :math:`\texttt{mu}_{00}=\texttt{m}_{00}`, + :math:`\texttt{nu}_{00}=1` + :math:`\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0` , hence the values are not stored. + +The moments of a contour are defined in the same way but computed using the Green's formula (see http://en.wikipedia.org/wiki/Green_theorem). So, due to a limited raster resolution, the moments computed for a contour are slightly different from the moments computed for the same rasterized contour. + +.. note:: + + Since the contour moments are computed using Green formula, you may get seemingly odd results for contours with self-intersections, e.g. a zero area (``m00``) for butterfly-shaped contours. + +.. seealso:: + + :ocv:func:`contourArea`, + :ocv:func:`arcLength` + + + +HuMoments +------------- +Calculates seven Hu invariants. + +.. ocv:function:: void HuMoments( const Moments& m, OutputArray hu ) + +.. ocv:function:: void HuMoments( const Moments& moments, double hu[7] ) + +.. ocv:pyfunction:: cv2.HuMoments(m[, hu]) -> hu + +.. ocv:cfunction:: void cvGetHuMoments( CvMoments* moments, CvHuMoments* hu_moments ) + +.. ocv:pyoldfunction:: cv.GetHuMoments(moments) -> hu + + :param moments: Input moments computed with :ocv:func:`moments` . + :param hu: Output Hu invariants. + +The function calculates seven Hu invariants (introduced in [Hu62]_; see also +http://en.wikipedia.org/wiki/Image_moment) defined as: + +.. math:: + + \begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array} + +where +:math:`\eta_{ji}` stands for +:math:`\texttt{Moments::nu}_{ji}` . + +These values are proved to be invariants to the image scale, rotation, and reflection except the seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of infinite image resolution. In case of raster images, the computed Hu invariants for the original and transformed images are a bit different. + +.. seealso:: :ocv:func:`matchShapes` + + +findContours +---------------- +Finds contours in a binary image. + +.. ocv:function:: void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point()) + +.. ocv:function:: void findContours( InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset=Point()) + +.. ocv:pyfunction:: cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy + +.. ocv:cfunction:: int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) ) + +.. ocv:pyoldfunction:: cv.FindContours(image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0)) -> contours + + :param image: Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as ``binary`` . You can use :ocv:func:`compare` , :ocv:func:`inRange` , :ocv:func:`threshold` , :ocv:func:`adaptiveThreshold` , :ocv:func:`Canny` , and others to create a binary image out of a grayscale or color one. The function modifies the ``image`` while extracting the contours. + + :param contours: Detected contours. Each contour is stored as a vector of points. + + :param hierarchy: Optional output vector, containing information about the image topology. It has as many elements as the number of contours. For each i-th contour ``contours[i]`` , the elements ``hierarchy[i][0]`` , ``hiearchy[i][1]`` , ``hiearchy[i][2]`` , and ``hiearchy[i][3]`` are set to 0-based indices in ``contours`` of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour ``i`` there are no next, previous, parent, or nested contours, the corresponding elements of ``hierarchy[i]`` will be negative. + + :param mode: Contour retrieval mode (if you use Python see also a note below). + + * **CV_RETR_EXTERNAL** retrieves only the extreme outer contours. It sets ``hierarchy[i][2]=hierarchy[i][3]=-1`` for all the contours. + + * **CV_RETR_LIST** retrieves all of the contours without establishing any hierarchical relationships. + + * **CV_RETR_CCOMP** retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level. + + * **CV_RETR_TREE** retrieves all of the contours and reconstructs a full hierarchy of nested contours. This full hierarchy is built and shown in the OpenCV ``contours.c`` demo. + + :param method: Contour approximation method (if you use Python see also a note below). + + * **CV_CHAIN_APPROX_NONE** stores absolutely all the contour points. That is, any 2 subsequent points ``(x1,y1)`` and ``(x2,y2)`` of the contour will be either horizontal, vertical or diagonal neighbors, that is, ``max(abs(x1-x2),abs(y2-y1))==1``. + + * **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points. + + * **CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS** applies one of the flavors of the Teh-Chin chain approximation algorithm. See [TehChin89]_ for details. + + :param offset: Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context. + +The function retrieves contours from the binary image using the algorithm +[Suzuki85]_. The contours are a useful tool for shape analysis and object detection and recognition. See ``squares.c`` in the OpenCV sample directory. + +.. note:: Source ``image`` is modified by this function. Also, the function does not take into account 1-pixel border of the image (it's filled with 0's and used for neighbor analysis in the algorithm), therefore the contours touching the image border will be clipped. + +.. note:: If you use the new Python interface then the ``CV_`` prefix has to be omitted in contour retrieval mode and contour approximation method parameters (for example, use ``cv2.RETR_LIST`` and ``cv2.CHAIN_APPROX_NONE`` parameters). If you use the old Python interface then these parameters have the ``CV_`` prefix (for example, use ``cv.CV_RETR_LIST`` and ``cv.CV_CHAIN_APPROX_NONE``). + +drawContours +---------------- +Draws contours outlines or filled contours. + +.. ocv:function:: void drawContours( InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() ) + +.. ocv:pyfunction:: cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> None + +.. ocv:cfunction:: void cvDrawContours( CvArr *img, CvSeq* contour, CvScalar externalColor, CvScalar holeColor, int maxLevel, int thickness=1, int lineType=8 ) +.. ocv:pyoldfunction:: cv.DrawContours(img, contour, external_color, hole_color, max_level, thickness=1, lineType=8, offset=(0, 0))-> None + + :param image: Destination image. + + :param contours: All the input contours. Each contour is stored as a point vector. + + :param contourIdx: Parameter indicating a contour to draw. If it is negative, all the contours are drawn. + + :param color: Color of the contours. + + :param thickness: Thickness of lines the contours are drawn with. If it is negative (for example, ``thickness=CV_FILLED`` ), the contour interiors are + drawn. + + :param lineType: Line connectivity. See :ocv:func:`line` for details. + + :param hierarchy: Optional information about hierarchy. It is only needed if you want to draw only some of the contours (see ``maxLevel`` ). + + :param maxLevel: Maximal level for drawn contours. If it is 0, only + the specified contour is drawn. If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This parameter is only taken into account when there is ``hierarchy`` available. + + :param offset: Optional contour shift parameter. Shift all the drawn contours by the specified :math:`\texttt{offset}=(dx,dy)` . + + :param contour: Pointer to the first contour. + + :param externalColor: Color of external contours. + + :param holeColor: Color of internal contours (holes). + +The function draws contour outlines in the image if +:math:`\texttt{thickness} \ge 0` or fills the area bounded by the contours if +:math:`\texttt{thickness}<0` . The example below shows how to retrieve connected components from the binary image and label them: :: + + #include "cv.h" + #include "highgui.h" + + using namespace cv; + + int main( int argc, char** argv ) + { + Mat src; + // the first command-line parameter must be a filename of the binary + // (black-n-white) image + if( argc != 2 || !(src=imread(argv[1], 0)).data) + return -1; + + Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3); + + src = src > 1; + namedWindow( "Source", 1 ); + imshow( "Source", src ); + + vector > contours; + vector hierarchy; + + findContours( src, contours, hierarchy, + CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); + + // iterate through all the top-level contours, + // draw each connected component with its own random color + int idx = 0; + for( ; idx >= 0; idx = hierarchy[idx][0] ) + { + Scalar color( rand()&255, rand()&255, rand()&255 ); + drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy ); + } + + namedWindow( "Components", 1 ); + imshow( "Components", dst ); + waitKey(0); + } + + + +approxPolyDP +---------------- +Approximates a polygonal curve(s) with the specified precision. + +.. ocv:function:: void approxPolyDP( InputArray curve, OutputArray approxCurve, double epsilon, bool closed ) + +.. ocv:pyfunction:: cv2.approxPolyDP(curve, epsilon, closed[, approxCurve]) -> approxCurve + +.. ocv:cfunction:: CvSeq* cvApproxPoly( const void* src_seq, int header_size, CvMemStorage* storage, int method, double eps, int recursive=0 ) + + :param curve: Input vector of a 2D point stored in: + + * ``std::vector`` or ``Mat`` (C++ interface) + + * ``Nx2`` numpy array (Python interface) + + * ``CvSeq`` or `` ``CvMat`` (C interface) + + :param approxCurve: Result of the approximation. The type should match the type of the input curve. In case of C interface the approximated curve is stored in the memory storage and pointer to it is returned. + + :param epsilon: Parameter specifying the approximation accuracy. This is the maximum distance between the original curve and its approximation. + + :param closed: If true, the approximated curve is closed (its first and last vertices are connected). Otherwise, it is not closed. + + :param header_size: Header size of the approximated curve. Normally, ``sizeof(CvContour)`` is used. + + :param storage: Memory storage where the approximated curve is stored. + + :param method: Contour approximation algorithm. Only ``CV_POLY_APPROX_DP`` is supported. + + :param recursive: Recursion flag. If it is non-zero and ``curve`` is ``CvSeq*``, the function ``cvApproxPoly`` approximates all the contours accessible from ``curve`` by ``h_next`` and ``v_next`` links. + +The functions ``approxPolyDP`` approximate a curve or a polygon with another curve/polygon with less vertices so that the distance between them is less or equal to the specified precision. It uses the Douglas-Peucker algorithm +http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm + +See http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/contours.cpp for the function usage model. + + +ApproxChains +------------- +Approximates Freeman chain(s) with a polygonal curve. + +.. ocv:cfunction:: CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0 ) + +.. ocv:pyoldfunction:: cv.ApproxChains(src_seq, storage, method=CV_CHAIN_APPROX_SIMPLE, parameter=0, minimal_perimeter=0, recursive=0)-> contours + + :param src_seq: Pointer to the approximated Freeman chain that can refer to other chains. + + :param storage: Storage location for the resulting polylines. + + :param method: Approximation method (see the description of the function :ocv:cfunc:`FindContours` ). + + :param parameter: Method parameter (not used now). + + :param minimal_perimeter: Approximates only those contours whose perimeters are not less than ``minimal_perimeter`` . Other chains are removed from the resulting structure. + + :param recursive: Recursion flag. If it is non-zero, the function approximates all chains that can be obtained from ``chain`` by using the ``h_next`` or ``v_next`` links. Otherwise, the single input chain is approximated. + +This is a standalone contour approximation routine, not represented in the new interface. When :ocv:cfunc:`FindContours` retrieves contours as Freeman chains, it calls the function to get approximated contours, represented as polygons. + + +arcLength +------------- +Calculates a contour perimeter or a curve length. + +.. ocv:function:: double arcLength( InputArray curve, bool closed ) + +.. ocv:pyfunction:: cv2.arcLength(curve, closed) -> retval + +.. ocv:cfunction:: double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 ) + +.. ocv:pyoldfunction:: cv.ArcLength(curve, slice=CV_WHOLE_SEQ, isClosed=-1) -> float + + :param curve: Input vector of 2D points, stored in ``std::vector`` or ``Mat``. + + :param closed: Flag indicating whether the curve is closed or not. + +The function computes a curve length or a closed contour perimeter. + + + +boundingRect +---------------- +Calculates the up-right bounding rectangle of a point set. + +.. ocv:function:: Rect boundingRect( InputArray points ) + +.. ocv:pyfunction:: cv2.boundingRect(points) -> retval + +.. ocv:cfunction:: CvRect cvBoundingRect( CvArr* points, int update=0 ) +.. ocv:pyoldfunction:: cv.BoundingRect(points, update=0)-> CvRect + + :param points: Input 2D point set, stored in ``std::vector`` or ``Mat``. + +The function calculates and returns the minimal up-right bounding rectangle for the specified point set. + + + + +contourArea +--------------- +Calculates a contour area. + +.. ocv:function:: double contourArea( InputArray contour, bool oriented=false ) + +.. ocv:pyfunction:: cv2.contourArea(contour[, oriented]) -> retval + +.. ocv:cfunction:: double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ, int oriented=0 ) + +.. ocv:pyoldfunction:: cv.ContourArea(contour, slice=CV_WHOLE_SEQ) -> float + + :param contour: Input vector of 2D points (contour vertices), stored in ``std::vector`` or ``Mat``. + + :param oriented: Oriented area flag. If it is true, the function returns a signed area value, depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can determine orientation of a contour by taking the sign of an area. By default, the parameter is ``false``, which means that the absolute value is returned. + +The function computes a contour area. Similarly to +:ocv:func:`moments` , the area is computed using the Green formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using +:ocv:func:`drawContours` or +:ocv:func:`fillPoly` , can be different. +Also, the function will most certainly give a wrong results for contours with self-intersections. + +Example: :: + + vector contour; + contour.push_back(Point2f(0, 0)); + contour.push_back(Point2f(10, 0)); + contour.push_back(Point2f(10, 10)); + contour.push_back(Point2f(5, 4)); + + double area0 = contourArea(contour); + vector approx; + approxPolyDP(contour, approx, 5, true); + double area1 = contourArea(approx); + + cout << "area0 =" << area0 << endl << + "area1 =" << area1 << endl << + "approx poly vertices" << approx.size() << endl; + + + +convexHull +-------------- +Finds the convex hull of a point set. + +.. ocv:function:: void convexHull( InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true ) + +.. ocv:pyfunction:: cv2.convexHull(points[, hull[, clockwise[, returnPoints]]]) -> hull + +.. ocv:cfunction:: CvSeq* cvConvexHull2( const CvArr* input, void* hull_storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0 ) + +.. ocv:pyoldfunction:: cv.ConvexHull2(points, storage, orientation=CV_CLOCKWISE, return_points=0) -> convexHull + + :param points: Input 2D point set, stored in ``std::vector`` or ``Mat``. + + :param hull: Output convex hull. It is either an integer vector of indices or vector of points. In the first case, the ``hull`` elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original point set). In the second case, ``hull`` elements are the convex hull points themselves. + + :param hull_storage: Output memory storage in the old API (``cvConvexHull2`` returns a sequence containing the convex hull points or their indices). + + :param clockwise: Orientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The usual screen coordinate system is assumed so that the origin is at the top-left corner, x axis is oriented to the right, and y axis is oriented downwards. + + :param orientation: Convex hull orientation parameter in the old API, ``CV_CLOCKWISE`` or ``CV_COUNTERCLOCKWISE``. + + :param returnPoints: Operation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points. When the output array is ``std::vector``, the flag is ignored, and the output depends on the type of the vector: ``std::vector`` implies ``returnPoints=true``, ``std::vector`` implies ``returnPoints=false``. + +The functions find the convex hull of a 2D point set using the Sklansky's algorithm +[Sklansky82]_ +that has +*O(N logN)* complexity in the current implementation. See the OpenCV sample ``convexhull.cpp`` that demonstrates the usage of different function variants. + + +convexityDefects +---------------- +Finds the convexity defects of a contour. + +.. ocv:function:: void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ) + +.. ocv:pyfunction:: cv2.convexityDefects(contour, convexhull[, convexityDefects]) -> convexityDefects + +.. ocv:cfunction:: CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL ) + +.. ocv:pyoldfunction:: cv.ConvexityDefects(contour, convexhull, storage)-> convexityDefects + + :param contour: Input contour. + + :param convexhull: Convex hull obtained using :ocv:func:`convexHull` that should contain indices of the contour points that make the hull. + + :param convexityDefects: The output vector of convexity defects. In C++ and the new Python/Java interface each convexity defect is represented as 4-element integer vector (a.k.a. ``cv::Vec4i``): ``(start_index, end_index, farthest_pt_index, fixpt_depth)``, where indices are 0-based indices in the original contour of the convexity defect beginning, end and the farthest point, and ``fixpt_depth`` is fixed-point approximation (with 8 fractional bits) of the distance between the farthest contour point and the hull. That is, to get the floating-point value of the depth will be ``fixpt_depth/256.0``. In C interface convexity defect is represented by ``CvConvexityDefect`` structure - see below. + + :param storage: Container for the output sequence of convexity defects. If it is NULL, the contour or hull (in that order) storage is used. + +The function finds all convexity defects of the input contour and returns a sequence of the ``CvConvexityDefect`` structures, where ``CvConvexityDetect`` is defined as: :: + + struct CvConvexityDefect + { + CvPoint* start; // point of the contour where the defect begins + CvPoint* end; // point of the contour where the defect ends + CvPoint* depth_point; // the farthest from the convex hull point within the defect + float depth; // distance between the farthest point and the convex hull + }; + +The figure below displays convexity defects of a hand contour: + +.. image:: pics/defects.png + +fitEllipse +-------------- +Fits an ellipse around a set of 2D points. + +.. ocv:function:: RotatedRect fitEllipse( InputArray points ) + +.. ocv:pyfunction:: cv2.fitEllipse(points) -> retval + +.. ocv:cfunction:: CvBox2D cvFitEllipse2( const CvArr* points ) +.. ocv:pyoldfunction:: cv.FitEllipse2(points)-> Box2D + + :param points: Input 2D point set, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface) + + * ``CvSeq*`` or ``CvMat*`` (C interface) + + * Nx2 numpy array (Python interface) + +The function calculates the ellipse that fits (in a least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed. The algorithm [Fitzgibbon95]_ is used. + +fitLine +----------- +Fits a line to a 2D or 3D point set. + +.. ocv:function:: void fitLine( InputArray points, OutputArray line, int distType, double param, double reps, double aeps ) + +.. ocv:pyfunction:: cv2.fitLine(points, distType, param, reps, aeps[, line]) -> line + +.. ocv:cfunction:: void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line ) + +.. ocv:pyoldfunction:: cv.FitLine(points, dist_type, param, reps, aeps) -> line + + :param points: Input vector of 2D or 3D points, stored in ``std::vector<>`` or ``Mat``. + + :param line: Output line parameters. In case of 2D fitting, it should be a vector of 4 elements (like ``Vec4f``) - ``(vx, vy, x0, y0)``, where ``(vx, vy)`` is a normalized vector collinear to the line and ``(x0, y0)`` is a point on the line. In case of 3D fitting, it should be a vector of 6 elements (like ``Vec6f``) - ``(vx, vy, vz, x0, y0, z0)``, where ``(vx, vy, vz)`` is a normalized vector collinear to the line and ``(x0, y0, z0)`` is a point on the line. + + :param distType: Distance used by the M-estimator (see the discussion below). + + :param param: Numerical parameter ( ``C`` ) for some types of distances. If it is 0, an optimal value is chosen. + + :param reps: Sufficient accuracy for the radius (distance between the coordinate origin and the line). + + :param aeps: Sufficient accuracy for the angle. 0.01 would be a good default value for ``reps`` and ``aeps``. + +The function ``fitLine`` fits a line to a 2D or 3D point set by minimizing +:math:`\sum_i \rho(r_i)` where +:math:`r_i` is a distance between the +:math:`i^{th}` point, the line and +:math:`\rho(r)` is a distance function, one of the following: + +* distType=CV\_DIST\_L2 + + .. math:: + + \rho (r) = r^2/2 \quad \text{(the simplest and the fastest least-squares method)} + +* distType=CV\_DIST\_L1 + + .. math:: + + \rho (r) = r + +* distType=CV\_DIST\_L12 + + .. math:: + + \rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1) + +* distType=CV\_DIST\_FAIR + + .. math:: + + \rho \left (r \right ) = C^2 \cdot \left ( \frac{r}{C} - \log{\left(1 + \frac{r}{C}\right)} \right ) \quad \text{where} \quad C=1.3998 + +* distType=CV\_DIST\_WELSCH + + .. math:: + + \rho \left (r \right ) = \frac{C^2}{2} \cdot \left ( 1 - \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right ) \quad \text{where} \quad C=2.9846 + +* distType=CV\_DIST\_HUBER + + .. math:: + + \rho (r) = \fork{r^2/2}{if $r < C$}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345 + +The algorithm is based on the M-estimator ( +http://en.wikipedia.org/wiki/M-estimator +) technique that iteratively fits the line using the weighted least-squares algorithm. After each iteration the weights +:math:`w_i` are adjusted to be inversely proportional to +:math:`\rho(r_i)` . + + + +isContourConvex +------------------- +Tests a contour convexity. + +.. ocv:function:: bool isContourConvex( InputArray contour ) + +.. ocv:pyfunction:: cv2.isContourConvex(contour) -> retval + +.. ocv:cfunction:: int cvCheckContourConvexity( const CvArr* contour ) +.. ocv:pyoldfunction:: cv.CheckContourConvexity(contour)-> int + + :param contour: Input vector of 2D points, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface) + + * ``CvSeq*`` or ``CvMat*`` (C interface) + + * Nx2 numpy array (Python interface) + +The function tests whether the input contour is convex or not. The contour must be simple, that is, without self-intersections. Otherwise, the function output is undefined. + + + +minAreaRect +--------------- +Finds a rotated rectangle of the minimum area enclosing the input 2D point set. + +.. ocv:function:: RotatedRect minAreaRect( InputArray points ) + +.. ocv:pyfunction:: cv2.minAreaRect(points) -> retval + +.. ocv:cfunction:: CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL ) + +.. ocv:pyoldfunction:: cv.MinAreaRect2(points, storage=None) -> Box2D + + :param points: Input vector of 2D points, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface) + + * ``CvSeq*`` or ``CvMat*`` (C interface) + + * Nx2 numpy array (Python interface) + +The function calculates and returns the minimum-area bounding rectangle (possibly rotated) for a specified point set. See the OpenCV sample ``minarea.cpp`` . + + + +minEnclosingCircle +---------------------- +Finds a circle of the minimum area enclosing a 2D point set. + +.. ocv:function:: void minEnclosingCircle( InputArray points, Point2f& center, float& radius ) + +.. ocv:pyfunction:: cv2.minEnclosingCircle(points) -> center, radius + +.. ocv:cfunction:: int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius ) + +.. ocv:pyoldfunction:: cv.MinEnclosingCircle(points)-> (int, center, radius) + + :param points: Input vector of 2D points, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface) + + * ``CvSeq*`` or ``CvMat*`` (C interface) + + * Nx2 numpy array (Python interface) + + :param center: Output center of the circle. + + :param radius: Output radius of the circle. + +The function finds the minimal enclosing circle of a 2D point set using an iterative algorithm. See the OpenCV sample ``minarea.cpp`` . + + + +matchShapes +--------------- +Compares two shapes. + +.. ocv:function:: double matchShapes( InputArray contour1, InputArray contour2, int method, double parameter ) + +.. ocv:pyfunction:: cv2.matchShapes(contour1, contour2, method, parameter) -> retval + +.. ocv:cfunction:: double cvMatchShapes( const void* object1, const void* object2, int method, double parameter=0 ) +.. ocv:pyoldfunction:: cv.MatchShapes(object1, object2, method, parameter=0) -> float + + :param object1: First contour or grayscale image. + + :param object2: Second contour or grayscale image. + + :param method: Comparison method: ``CV_CONTOURS_MATCH_I1`` , \ ``CV_CONTOURS_MATCH_I2`` \ + or ``CV_CONTOURS_MATCH_I3`` (see the details below). + + :param parameter: Method-specific parameter (not supported now). + +The function compares two shapes. All three implemented methods use the Hu invariants (see +:ocv:func:`HuMoments` ) as follows ( +:math:`A` denotes ``object1``,:math:`B` denotes ``object2`` ): + +* method=CV_CONTOURS_MATCH_I1 + + .. math:: + + I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right | + +* method=CV_CONTOURS_MATCH_I2 + + .. math:: + + I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right | + +* method=CV_CONTOURS_MATCH_I3 + + .. math:: + + I_3(A,B) = \max _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| } + +where + +.. math:: + + \begin{array}{l} m^A_i = \mathrm{sign} (h^A_i) \cdot \log{h^A_i} \\ m^B_i = \mathrm{sign} (h^B_i) \cdot \log{h^B_i} \end{array} + +and +:math:`h^A_i, h^B_i` are the Hu moments of +:math:`A` and +:math:`B` , respectively. + + + +pointPolygonTest +-------------------- +Performs a point-in-contour test. + +.. ocv:function:: double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist ) + +.. ocv:pyfunction:: cv2.pointPolygonTest(contour, pt, measureDist) -> retval + +.. ocv:cfunction:: double cvPointPolygonTest( const CvArr* contour, CvPoint2D32f pt, int measure_dist ) +.. ocv:pyoldfunction:: cv.PointPolygonTest(contour, pt, measure_dist) -> float + + :param contour: Input contour. + + :param pt: Point tested against the contour. + + :param measureDist: If true, the function estimates the signed distance from the point to the nearest contour edge. Otherwise, the function only checks if the point is inside a contour or not. + +The function determines whether the +point is inside a contour, outside, or lies on an edge (or coincides +with a vertex). It returns positive (inside), negative (outside), or zero (on an edge) value, +correspondingly. When ``measureDist=false`` , the return value +is +1, -1, and 0, respectively. Otherwise, the return value +is a signed distance between the point and the nearest contour +edge. + +See below a sample output of the function where each image pixel is tested against the contour. + +.. image:: pics/pointpolygon.png + +.. [Fitzgibbon95] Andrew W. Fitzgibbon, R.B.Fisher. *A Buyer's Guide to Conic Fitting*. Proc.5th British Machine Vision Conference, Birmingham, pp. 513-522, 1995. + +.. [Hu62] M. Hu. *Visual Pattern Recognition by Moment Invariants*, IRE Transactions on Information Theory, 8:2, pp. 179-187, 1962. + +.. [Sklansky82] Sklansky, J., *Finding the Convex Hull of a Simple Polygon*. PRL 1 $number, pp 79-83 (1982) + +.. [Suzuki85] Suzuki, S. and Abe, K., *Topological Structural Analysis of Digitized Binary Images by Border Following*. CVGIP 30 1, pp 32-46 (1985) + +.. [TehChin89] Teh, C.H. and Chin, R.T., *On the Detection of Dominant Points on Digital Curve*. PAMI 11 8, pp 859-872 (1989) diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/imgproc.pro diffimg-2.0.0/3rdparty/opencv/imgproc/imgproc.pro --- diffimg-1.5.0/3rdparty/opencv/imgproc/imgproc.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/imgproc.pro 2013-05-06 13:21:12.000000000 +0000 @@ -0,0 +1,17 @@ + + +OPENCV_ROOT = $${PWD}/.. + +TEMPLATE = lib +TARGET = opencv_imgproc + +#DESTDIR = $${QWT_ROOT}/lib + +CONFIG += staticlib + +HEADERS += include/opencv2/imgproc/*.hpp + + +SOURCES += src/*.cpp + +INCLUDEPATH += ./include ./ ../ ../core/include \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc.hpp diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc.hpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,1299 @@ +/*! \file imgproc.hpp + \brief The Image Processing + */ + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_IMGPROC_HPP__ +#define __OPENCV_IMGPROC_HPP__ + +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/types_c.h" + +#ifdef __cplusplus + +/*! \namespace cv + Namespace where all the C++ OpenCV functionality resides + */ +namespace cv +{ + +//! various border interpolation methods +enum { BORDER_REPLICATE=IPL_BORDER_REPLICATE, BORDER_CONSTANT=IPL_BORDER_CONSTANT, + BORDER_REFLECT=IPL_BORDER_REFLECT, BORDER_WRAP=IPL_BORDER_WRAP, + BORDER_REFLECT_101=IPL_BORDER_REFLECT_101, BORDER_REFLECT101=BORDER_REFLECT_101, + BORDER_TRANSPARENT=IPL_BORDER_TRANSPARENT, + BORDER_DEFAULT=BORDER_REFLECT_101, BORDER_ISOLATED=16 }; + +//! 1D interpolation function: returns coordinate of the "donor" pixel for the specified location p. +CV_EXPORTS_W int borderInterpolate( int p, int len, int borderType ); + +/*! + The Base Class for 1D or Row-wise Filters + + This is the base class for linear or non-linear filters that process 1D data. + In particular, such filters are used for the "horizontal" filtering parts in separable filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. +*/ +class CV_EXPORTS BaseRowFilter +{ +public: + //! the default constructor + BaseRowFilter(); + //! the destructor + virtual ~BaseRowFilter(); + //! the filtering operator. Must be overrided in the derived classes. The horizontal border interpolation is done outside of the class. + virtual void operator()(const uchar* src, uchar* dst, + int width, int cn) = 0; + int ksize, anchor; +}; + + +/*! + The Base Class for Column-wise Filters + + This is the base class for linear or non-linear filters that process columns of 2D arrays. + Such filters are used for the "vertical" filtering parts in separable filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Unlike cv::BaseRowFilter, cv::BaseColumnFilter may have some context information, + i.e. box filter keeps the sliding sum of elements. To reset the state BaseColumnFilter::reset() + must be called (e.g. the method is called by cv::FilterEngine) + */ +class CV_EXPORTS BaseColumnFilter +{ +public: + //! the default constructor + BaseColumnFilter(); + //! the destructor + virtual ~BaseColumnFilter(); + //! the filtering operator. Must be overrided in the derived classes. The vertical border interpolation is done outside of the class. + virtual void operator()(const uchar** src, uchar* dst, int dststep, + int dstcount, int width) = 0; + //! resets the internal buffers, if any + virtual void reset(); + int ksize, anchor; +}; + +/*! + The Base Class for Non-Separable 2D Filters. + + This is the base class for linear or non-linear 2D filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Similar to cv::BaseColumnFilter, the class may have some context information, + that should be reset using BaseFilter::reset() method before processing the new array. +*/ +class CV_EXPORTS BaseFilter +{ +public: + //! the default constructor + BaseFilter(); + //! the destructor + virtual ~BaseFilter(); + //! the filtering operator. The horizontal and the vertical border interpolation is done outside of the class. + virtual void operator()(const uchar** src, uchar* dst, int dststep, + int dstcount, int width, int cn) = 0; + //! resets the internal buffers, if any + virtual void reset(); + Size ksize; + Point anchor; +}; + +/*! + The Main Class for Image Filtering. + + The class can be used to apply an arbitrary filtering operation to an image. + It contains all the necessary intermediate buffers, it computes extrapolated values + of the "virtual" pixels outside of the image etc. + Pointers to the initialized cv::FilterEngine instances + are returned by various OpenCV functions, such as cv::createSeparableLinearFilter(), + cv::createLinearFilter(), cv::createGaussianFilter(), cv::createDerivFilter(), + cv::createBoxFilter() and cv::createMorphologyFilter(). + + Using the class you can process large images by parts and build complex pipelines + that include filtering as some of the stages. If all you need is to apply some pre-defined + filtering operation, you may use cv::filter2D(), cv::erode(), cv::dilate() etc. + functions that create FilterEngine internally. + + Here is the example on how to use the class to implement Laplacian operator, which is the sum of + second-order derivatives. More complex variant for different types is implemented in cv::Laplacian(). + + \code + void laplace_f(const Mat& src, Mat& dst) + { + CV_Assert( src.type() == CV_32F ); + // make sure the destination array has the proper size and type + dst.create(src.size(), src.type()); + + // get the derivative and smooth kernels for d2I/dx2. + // for d2I/dy2 we could use the same kernels, just swapped + Mat kd, ks; + getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); + + // let's process 10 source rows at once + int DELTA = std::min(10, src.rows); + Ptr Fxx = createSeparableLinearFilter(src.type(), + dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); + Ptr Fyy = createSeparableLinearFilter(src.type(), + dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); + + int y = Fxx->start(src), dsty = 0, dy = 0; + Fyy->start(src); + const uchar* sptr = src.data + y*src.step; + + // allocate the buffers for the spatial image derivatives; + // the buffers need to have more than DELTA rows, because at the + // last iteration the output may take max(kd.rows-1,ks.rows-1) + // rows more than the input. + Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() ); + Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() ); + + // inside the loop we always pass DELTA rows to the filter + // (note that the "proceed" method takes care of possibe overflow, since + // it was given the actual image height in the "start" method) + // on output we can get: + // * < DELTA rows (the initial buffer accumulation stage) + // * = DELTA rows (settled state in the middle) + // * > DELTA rows (then the input image is over, but we generate + // "virtual" rows using the border mode and filter them) + // this variable number of output rows is dy. + // dsty is the current output row. + // sptr is the pointer to the first input row in the portion to process + for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy ) + { + Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step ); + dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step ); + if( dy > 0 ) + { + Mat dstripe = dst.rowRange(dsty, dsty + dy); + add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe); + } + } + } + \endcode +*/ +class CV_EXPORTS FilterEngine +{ +public: + //! the default constructor + FilterEngine(); + //! the full constructor. Either _filter2D or both _rowFilter and _columnFilter must be non-empty. + FilterEngine(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType=BORDER_REPLICATE, + int _columnBorderType=-1, + const Scalar& _borderValue=Scalar()); + //! the destructor + virtual ~FilterEngine(); + //! reinitializes the engine. The previously assigned filters are released. + void init(const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int srcType, int dstType, int bufType, + int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1, + const Scalar& _borderValue=Scalar()); + //! starts filtering of the specified ROI of an image of size wholeSize. + virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1); + //! starts filtering of the specified ROI of the specified image. + virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1), + bool isolated=false, int maxBufRows=-1); + //! processes the next srcCount rows of the image. + virtual int proceed(const uchar* src, int srcStep, int srcCount, + uchar* dst, int dstStep); + //! applies filter to the specified ROI of the image. if srcRoi=(0,0,-1,-1), the whole image is filtered. + virtual void apply( const Mat& src, Mat& dst, + const Rect& srcRoi=Rect(0,0,-1,-1), + Point dstOfs=Point(0,0), + bool isolated=false); + //! returns true if the filter is separable + bool isSeparable() const { return (const BaseFilter*)filter2D == 0; } + //! returns the number + int remainingInputRows() const; + int remainingOutputRows() const; + + int srcType, dstType, bufType; + Size ksize; + Point anchor; + int maxWidth; + Size wholeSize; + Rect roi; + int dx1, dx2; + int rowBorderType, columnBorderType; + vector borderTab; + int borderElemSize; + vector ringBuf; + vector srcRow; + vector constBorderValue; + vector constBorderRow; + int bufStep, startY, startY0, endY, rowCount, dstY; + vector rows; + + Ptr filter2D; + Ptr rowFilter; + Ptr columnFilter; +}; + +//! type of the kernel +enum { KERNEL_GENERAL=0, KERNEL_SYMMETRICAL=1, KERNEL_ASYMMETRICAL=2, + KERNEL_SMOOTH=4, KERNEL_INTEGER=8 }; + +//! returns type (one of KERNEL_*) of 1D or 2D kernel specified by its coefficients. +CV_EXPORTS int getKernelType(InputArray kernel, Point anchor); + +//! returns the primitive row filter with the specified kernel +CV_EXPORTS Ptr getLinearRowFilter(int srcType, int bufType, + InputArray kernel, int anchor, + int symmetryType); + +//! returns the primitive column filter with the specified kernel +CV_EXPORTS Ptr getLinearColumnFilter(int bufType, int dstType, + InputArray kernel, int anchor, + int symmetryType, double delta=0, + int bits=0); + +//! returns 2D filter with the specified kernel +CV_EXPORTS Ptr getLinearFilter(int srcType, int dstType, + InputArray kernel, + Point anchor=Point(-1,-1), + double delta=0, int bits=0); + +//! returns the separable linear filter engine +CV_EXPORTS Ptr createSeparableLinearFilter(int srcType, int dstType, + InputArray rowKernel, InputArray columnKernel, + Point anchor=Point(-1,-1), double delta=0, + int rowBorderType=BORDER_DEFAULT, + int columnBorderType=-1, + const Scalar& borderValue=Scalar()); + +//! returns the non-separable linear filter engine +CV_EXPORTS Ptr createLinearFilter(int srcType, int dstType, + InputArray kernel, Point _anchor=Point(-1,-1), + double delta=0, int rowBorderType=BORDER_DEFAULT, + int columnBorderType=-1, const Scalar& borderValue=Scalar()); + +//! returns the Gaussian kernel with the specified parameters +CV_EXPORTS_W Mat getGaussianKernel( int ksize, double sigma, int ktype=CV_64F ); + +//! returns the Gaussian filter engine +CV_EXPORTS Ptr createGaussianFilter( int type, Size ksize, + double sigma1, double sigma2=0, + int borderType=BORDER_DEFAULT); +//! initializes kernels of the generalized Sobel operator +CV_EXPORTS_W void getDerivKernels( OutputArray kx, OutputArray ky, + int dx, int dy, int ksize, + bool normalize=false, int ktype=CV_32F ); +//! returns filter engine for the generalized Sobel operator +CV_EXPORTS Ptr createDerivFilter( int srcType, int dstType, + int dx, int dy, int ksize, + int borderType=BORDER_DEFAULT ); +//! returns horizontal 1D box filter +CV_EXPORTS Ptr getRowSumFilter(int srcType, int sumType, + int ksize, int anchor=-1); +//! returns vertical 1D box filter +CV_EXPORTS Ptr getColumnSumFilter( int sumType, int dstType, + int ksize, int anchor=-1, + double scale=1); +//! returns box filter engine +CV_EXPORTS Ptr createBoxFilter( int srcType, int dstType, Size ksize, + Point anchor=Point(-1,-1), + bool normalize=true, + int borderType=BORDER_DEFAULT); + +//! returns the Gabor kernel with the specified parameters +CV_EXPORTS_W Mat getGaborKernel( Size ksize, double sigma, double theta, double lambd, + double gamma, double psi=CV_PI*0.5, int ktype=CV_64F ); + +//! type of morphological operation +enum { MORPH_ERODE=CV_MOP_ERODE, MORPH_DILATE=CV_MOP_DILATE, + MORPH_OPEN=CV_MOP_OPEN, MORPH_CLOSE=CV_MOP_CLOSE, + MORPH_GRADIENT=CV_MOP_GRADIENT, MORPH_TOPHAT=CV_MOP_TOPHAT, + MORPH_BLACKHAT=CV_MOP_BLACKHAT }; + +//! returns horizontal 1D morphological filter +CV_EXPORTS Ptr getMorphologyRowFilter(int op, int type, int ksize, int anchor=-1); +//! returns vertical 1D morphological filter +CV_EXPORTS Ptr getMorphologyColumnFilter(int op, int type, int ksize, int anchor=-1); +//! returns 2D morphological filter +CV_EXPORTS Ptr getMorphologyFilter(int op, int type, InputArray kernel, + Point anchor=Point(-1,-1)); + +//! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation. +static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); } + +//! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported. +CV_EXPORTS Ptr createMorphologyFilter(int op, int type, InputArray kernel, + Point anchor=Point(-1,-1), int rowBorderType=BORDER_CONSTANT, + int columnBorderType=-1, + const Scalar& borderValue=morphologyDefaultBorderValue()); + +//! shape of the structuring element +enum { MORPH_RECT=0, MORPH_CROSS=1, MORPH_ELLIPSE=2 }; +//! returns structuring element of the specified shape and size +CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1)); + +template<> CV_EXPORTS void Ptr::delete_obj(); + +//! copies 2D array to a larger destination array with extrapolation of the outer part of src using the specified border mode +CV_EXPORTS_W void copyMakeBorder( InputArray src, OutputArray dst, + int top, int bottom, int left, int right, + int borderType, const Scalar& value=Scalar() ); + +//! smooths the image using median filter. +CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize ); +//! smooths the image using Gaussian filter. +CV_EXPORTS_W void GaussianBlur( InputArray src, + OutputArray dst, Size ksize, + double sigmaX, double sigmaY=0, + int borderType=BORDER_DEFAULT ); +//! smooths the image using bilateral filter +CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d, + double sigmaColor, double sigmaSpace, + int borderType=BORDER_DEFAULT ); +//! smooths the image using the box filter. Each pixel is processed in O(1) time +CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, + Size ksize, Point anchor=Point(-1,-1), + bool normalize=true, + int borderType=BORDER_DEFAULT ); +//! a synonym for normalized box filter +CV_EXPORTS_W void blur( InputArray src, OutputArray dst, + Size ksize, Point anchor=Point(-1,-1), + int borderType=BORDER_DEFAULT ); + +//! applies non-separable 2D linear filter to the image +CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernel, Point anchor=Point(-1,-1), + double delta=0, int borderType=BORDER_DEFAULT ); + +//! applies separable 2D linear filter to the image +CV_EXPORTS_W void sepFilter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernelX, InputArray kernelY, + Point anchor=Point(-1,-1), + double delta=0, int borderType=BORDER_DEFAULT ); + +//! applies generalized Sobel operator to the image +CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, int ksize=3, + double scale=1, double delta=0, + int borderType=BORDER_DEFAULT ); + +//! applies the vertical or horizontal Scharr operator to the image +CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, double scale=1, double delta=0, + int borderType=BORDER_DEFAULT ); + +//! applies Laplacian operator to the image +CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth, + int ksize=1, double scale=1, double delta=0, + int borderType=BORDER_DEFAULT ); + +//! applies Canny edge detector and produces the edge map. +CV_EXPORTS_W void Canny( InputArray image, OutputArray edges, + double threshold1, double threshold2, + int apertureSize=3, bool L2gradient=false ); + +//! computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria +CV_EXPORTS_W void cornerMinEigenVal( InputArray src, OutputArray dst, + int blockSize, int ksize=3, + int borderType=BORDER_DEFAULT ); + +//! computes Harris cornerness criteria at each image pixel +CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize, + int ksize, double k, + int borderType=BORDER_DEFAULT ); + +// low-level function for computing eigenvalues and eigenvectors of 2x2 matrices +CV_EXPORTS void eigen2x2( const float* a, float* e, int n ); + +//! computes both eigenvalues and the eigenvectors of 2x2 derivative covariation matrix at each pixel. The output is stored as 6-channel matrix. +CV_EXPORTS_W void cornerEigenValsAndVecs( InputArray src, OutputArray dst, + int blockSize, int ksize, + int borderType=BORDER_DEFAULT ); + +//! computes another complex cornerness criteria at each pixel +CV_EXPORTS_W void preCornerDetect( InputArray src, OutputArray dst, int ksize, + int borderType=BORDER_DEFAULT ); + +//! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria +CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners, + Size winSize, Size zeroZone, + TermCriteria criteria ); + +//! finds the strong enough corners where the cornerMinEigenVal() or cornerHarris() report the local maxima +CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, + int maxCorners, double qualityLevel, double minDistance, + InputArray mask=noArray(), int blockSize=3, + bool useHarrisDetector=false, double k=0.04 ); + +//! finds lines in the black-n-white image using the standard or pyramid Hough transform +CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double srn=0, double stn=0 ); + +//! finds line segments in the black-n-white image using probabalistic Hough transform +CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double minLineLength=0, double maxLineGap=0 ); + +//! finds circles in the grayscale image using 2+1 gradient Hough transform +CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles, + int method, double dp, double minDist, + double param1=100, double param2=100, + int minRadius=0, int maxRadius=0 ); + +enum +{ + GHT_POSITION = 0, + GHT_SCALE = 1, + GHT_ROTATION = 2 +}; + +//! finds arbitrary template in the grayscale image using Generalized Hough Transform +//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122. +//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038. +class CV_EXPORTS GeneralizedHough : public Algorithm +{ +public: + static Ptr create(int method); + + virtual ~GeneralizedHough(); + + //! set template to search + void setTemplate(InputArray templ, int cannyThreshold = 100, Point templCenter = Point(-1, -1)); + void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)); + + //! find template on image + void detect(InputArray image, OutputArray positions, OutputArray votes = cv::noArray(), int cannyThreshold = 100); + void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray votes = cv::noArray()); + + void release(); + +protected: + virtual void setTemplateImpl(const Mat& edges, const Mat& dx, const Mat& dy, Point templCenter) = 0; + virtual void detectImpl(const Mat& edges, const Mat& dx, const Mat& dy, OutputArray positions, OutputArray votes) = 0; + virtual void releaseImpl() = 0; + +private: + Mat edges_, dx_, dy_; +}; + +//! erodes the image (applies the local minimum operator) +CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel, + Point anchor=Point(-1,-1), int iterations=1, + int borderType=BORDER_CONSTANT, + const Scalar& borderValue=morphologyDefaultBorderValue() ); + +//! dilates the image (applies the local maximum operator) +CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel, + Point anchor=Point(-1,-1), int iterations=1, + int borderType=BORDER_CONSTANT, + const Scalar& borderValue=morphologyDefaultBorderValue() ); + +//! applies an advanced morphological operation to the image +CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst, + int op, InputArray kernel, + Point anchor=Point(-1,-1), int iterations=1, + int borderType=BORDER_CONSTANT, + const Scalar& borderValue=morphologyDefaultBorderValue() ); + +//! interpolation algorithm +enum +{ + INTER_NEAREST=CV_INTER_NN, //!< nearest neighbor interpolation + INTER_LINEAR=CV_INTER_LINEAR, //!< bilinear interpolation + INTER_CUBIC=CV_INTER_CUBIC, //!< bicubic interpolation + INTER_AREA=CV_INTER_AREA, //!< area-based (or super) interpolation + INTER_LANCZOS4=CV_INTER_LANCZOS4, //!< Lanczos interpolation over 8x8 neighborhood + INTER_MAX=7, + WARP_INVERSE_MAP=CV_WARP_INVERSE_MAP +}; + +//! resizes the image +CV_EXPORTS_W void resize( InputArray src, OutputArray dst, + Size dsize, double fx=0, double fy=0, + int interpolation=INTER_LINEAR ); + +//! warps the image using affine transformation +CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags=INTER_LINEAR, + int borderMode=BORDER_CONSTANT, + const Scalar& borderValue=Scalar()); + +//! warps the image using perspective transformation +CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags=INTER_LINEAR, + int borderMode=BORDER_CONSTANT, + const Scalar& borderValue=Scalar()); + +enum +{ + INTER_BITS=5, INTER_BITS2=INTER_BITS*2, + INTER_TAB_SIZE=(1< CV_EXPORTS void Ptr::delete_obj(); + +//! computes the joint dense histogram for a set of images. +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + OutputArray hist, int dims, const int* histSize, + const float** ranges, bool uniform=true, bool accumulate=false ); + +//! computes the joint sparse histogram for a set of images. +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + SparseMat& hist, int dims, + const int* histSize, const float** ranges, + bool uniform=true, bool accumulate=false ); + +CV_EXPORTS_W void calcHist( InputArrayOfArrays images, + const vector& channels, + InputArray mask, OutputArray hist, + const vector& histSize, + const vector& ranges, + bool accumulate=false ); + +//! computes back projection for the set of images +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, InputArray hist, + OutputArray backProject, const float** ranges, + double scale=1, bool uniform=true ); + +//! computes back projection for the set of images +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, const SparseMat& hist, + OutputArray backProject, const float** ranges, + double scale=1, bool uniform=true ); + +CV_EXPORTS_W void calcBackProject( InputArrayOfArrays images, const vector& channels, + InputArray hist, OutputArray dst, + const vector& ranges, + double scale ); + +/*CV_EXPORTS void calcBackProjectPatch( const Mat* images, int nimages, const int* channels, + InputArray hist, OutputArray dst, Size patchSize, + int method, double factor=1 ); + +CV_EXPORTS_W void calcBackProjectPatch( InputArrayOfArrays images, const vector& channels, + InputArray hist, OutputArray dst, Size patchSize, + int method, double factor=1 );*/ + +//! compares two histograms stored in dense arrays +CV_EXPORTS_W double compareHist( InputArray H1, InputArray H2, int method ); + +//! compares two histograms stored in sparse arrays +CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method ); + +//! normalizes the grayscale image brightness and contrast by normalizing its histogram +CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst ); + +class CV_EXPORTS CLAHE : public Algorithm +{ +public: + virtual void apply(InputArray src, OutputArray dst) = 0; + + virtual void setClipLimit(double clipLimit) = 0; + virtual double getClipLimit() const = 0; + + virtual void setTilesGridSize(Size tileGridSize) = 0; + virtual Size getTilesGridSize() const = 0; + + virtual void collectGarbage() = 0; +}; +CV_EXPORTS Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); + +CV_EXPORTS float EMD( InputArray signature1, InputArray signature2, + int distType, InputArray cost=noArray(), + float* lowerBound=0, OutputArray flow=noArray() ); + +//! segments the image using watershed algorithm +CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers ); + +//! filters image using meanshift algorithm +CV_EXPORTS_W void pyrMeanShiftFiltering( InputArray src, OutputArray dst, + double sp, double sr, int maxLevel=1, + TermCriteria termcrit=TermCriteria( + TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) ); + +//! class of the pixel in GrabCut algorithm +enum +{ + GC_BGD = 0, //!< background + GC_FGD = 1, //!< foreground + GC_PR_BGD = 2, //!< most probably background + GC_PR_FGD = 3 //!< most probably foreground +}; + +//! GrabCut algorithm flags +enum +{ + GC_INIT_WITH_RECT = 0, + GC_INIT_WITH_MASK = 1, + GC_EVAL = 2 +}; + +//! segments the image using GrabCut algorithm +CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect, + InputOutputArray bgdModel, InputOutputArray fgdModel, + int iterCount, int mode = GC_EVAL ); + +enum +{ + DIST_LABEL_CCOMP = 0, + DIST_LABEL_PIXEL = 1 +}; + +//! builds the discrete Voronoi diagram +CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst, + OutputArray labels, int distanceType, int maskSize, + int labelType=DIST_LABEL_CCOMP ); + +//! computes the distance transform map +CV_EXPORTS_W void distanceTransform( InputArray src, OutputArray dst, + int distanceType, int maskSize ); + +enum { FLOODFILL_FIXED_RANGE = 1 << 16, FLOODFILL_MASK_ONLY = 1 << 17 }; + +//! fills the semi-uniform image region starting from the specified seed point +CV_EXPORTS int floodFill( InputOutputArray image, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, + Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), + int flags=4 ); + +//! fills the semi-uniform image region and/or the mask starting from the specified seed point +CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, + Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), + int flags=4 ); + + +enum +{ + COLOR_BGR2BGRA =0, + COLOR_RGB2RGBA =COLOR_BGR2BGRA, + + COLOR_BGRA2BGR =1, + COLOR_RGBA2RGB =COLOR_BGRA2BGR, + + COLOR_BGR2RGBA =2, + COLOR_RGB2BGRA =COLOR_BGR2RGBA, + + COLOR_RGBA2BGR =3, + COLOR_BGRA2RGB =COLOR_RGBA2BGR, + + COLOR_BGR2RGB =4, + COLOR_RGB2BGR =COLOR_BGR2RGB, + + COLOR_BGRA2RGBA =5, + COLOR_RGBA2BGRA =COLOR_BGRA2RGBA, + + COLOR_BGR2GRAY =6, + COLOR_RGB2GRAY =7, + COLOR_GRAY2BGR =8, + COLOR_GRAY2RGB =COLOR_GRAY2BGR, + COLOR_GRAY2BGRA =9, + COLOR_GRAY2RGBA =COLOR_GRAY2BGRA, + COLOR_BGRA2GRAY =10, + COLOR_RGBA2GRAY =11, + + COLOR_BGR2BGR565 =12, + COLOR_RGB2BGR565 =13, + COLOR_BGR5652BGR =14, + COLOR_BGR5652RGB =15, + COLOR_BGRA2BGR565 =16, + COLOR_RGBA2BGR565 =17, + COLOR_BGR5652BGRA =18, + COLOR_BGR5652RGBA =19, + + COLOR_GRAY2BGR565 =20, + COLOR_BGR5652GRAY =21, + + COLOR_BGR2BGR555 =22, + COLOR_RGB2BGR555 =23, + COLOR_BGR5552BGR =24, + COLOR_BGR5552RGB =25, + COLOR_BGRA2BGR555 =26, + COLOR_RGBA2BGR555 =27, + COLOR_BGR5552BGRA =28, + COLOR_BGR5552RGBA =29, + + COLOR_GRAY2BGR555 =30, + COLOR_BGR5552GRAY =31, + + COLOR_BGR2XYZ =32, + COLOR_RGB2XYZ =33, + COLOR_XYZ2BGR =34, + COLOR_XYZ2RGB =35, + + COLOR_BGR2YCrCb =36, + COLOR_RGB2YCrCb =37, + COLOR_YCrCb2BGR =38, + COLOR_YCrCb2RGB =39, + + COLOR_BGR2HSV =40, + COLOR_RGB2HSV =41, + + COLOR_BGR2Lab =44, + COLOR_RGB2Lab =45, + + COLOR_BayerBG2BGR =46, + COLOR_BayerGB2BGR =47, + COLOR_BayerRG2BGR =48, + COLOR_BayerGR2BGR =49, + + COLOR_BayerBG2RGB =COLOR_BayerRG2BGR, + COLOR_BayerGB2RGB =COLOR_BayerGR2BGR, + COLOR_BayerRG2RGB =COLOR_BayerBG2BGR, + COLOR_BayerGR2RGB =COLOR_BayerGB2BGR, + + COLOR_BGR2Luv =50, + COLOR_RGB2Luv =51, + COLOR_BGR2HLS =52, + COLOR_RGB2HLS =53, + + COLOR_HSV2BGR =54, + COLOR_HSV2RGB =55, + + COLOR_Lab2BGR =56, + COLOR_Lab2RGB =57, + COLOR_Luv2BGR =58, + COLOR_Luv2RGB =59, + COLOR_HLS2BGR =60, + COLOR_HLS2RGB =61, + + COLOR_BayerBG2BGR_VNG =62, + COLOR_BayerGB2BGR_VNG =63, + COLOR_BayerRG2BGR_VNG =64, + COLOR_BayerGR2BGR_VNG =65, + + COLOR_BayerBG2RGB_VNG =COLOR_BayerRG2BGR_VNG, + COLOR_BayerGB2RGB_VNG =COLOR_BayerGR2BGR_VNG, + COLOR_BayerRG2RGB_VNG =COLOR_BayerBG2BGR_VNG, + COLOR_BayerGR2RGB_VNG =COLOR_BayerGB2BGR_VNG, + + COLOR_BGR2HSV_FULL = 66, + COLOR_RGB2HSV_FULL = 67, + COLOR_BGR2HLS_FULL = 68, + COLOR_RGB2HLS_FULL = 69, + + COLOR_HSV2BGR_FULL = 70, + COLOR_HSV2RGB_FULL = 71, + COLOR_HLS2BGR_FULL = 72, + COLOR_HLS2RGB_FULL = 73, + + COLOR_LBGR2Lab = 74, + COLOR_LRGB2Lab = 75, + COLOR_LBGR2Luv = 76, + COLOR_LRGB2Luv = 77, + + COLOR_Lab2LBGR = 78, + COLOR_Lab2LRGB = 79, + COLOR_Luv2LBGR = 80, + COLOR_Luv2LRGB = 81, + + COLOR_BGR2YUV = 82, + COLOR_RGB2YUV = 83, + COLOR_YUV2BGR = 84, + COLOR_YUV2RGB = 85, + + COLOR_BayerBG2GRAY = 86, + COLOR_BayerGB2GRAY = 87, + COLOR_BayerRG2GRAY = 88, + COLOR_BayerGR2GRAY = 89, + + //YUV 4:2:0 formats family + COLOR_YUV2RGB_NV12 = 90, + COLOR_YUV2BGR_NV12 = 91, + COLOR_YUV2RGB_NV21 = 92, + COLOR_YUV2BGR_NV21 = 93, + COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21, + COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21, + + COLOR_YUV2RGBA_NV12 = 94, + COLOR_YUV2BGRA_NV12 = 95, + COLOR_YUV2RGBA_NV21 = 96, + COLOR_YUV2BGRA_NV21 = 97, + COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21, + COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21, + + COLOR_YUV2RGB_YV12 = 98, + COLOR_YUV2BGR_YV12 = 99, + COLOR_YUV2RGB_IYUV = 100, + COLOR_YUV2BGR_IYUV = 101, + COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV, + COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV, + COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12, + COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12, + + COLOR_YUV2RGBA_YV12 = 102, + COLOR_YUV2BGRA_YV12 = 103, + COLOR_YUV2RGBA_IYUV = 104, + COLOR_YUV2BGRA_IYUV = 105, + COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV, + COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV, + COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12, + COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12, + + COLOR_YUV2GRAY_420 = 106, + COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420, + COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420, + COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420, + + //YUV 4:2:2 formats family + COLOR_YUV2RGB_UYVY = 107, + COLOR_YUV2BGR_UYVY = 108, + //COLOR_YUV2RGB_VYUY = 109, + //COLOR_YUV2BGR_VYUY = 110, + COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY, + COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY, + + COLOR_YUV2RGBA_UYVY = 111, + COLOR_YUV2BGRA_UYVY = 112, + //COLOR_YUV2RGBA_VYUY = 113, + //COLOR_YUV2BGRA_VYUY = 114, + COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY, + COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY, + + COLOR_YUV2RGB_YUY2 = 115, + COLOR_YUV2BGR_YUY2 = 116, + COLOR_YUV2RGB_YVYU = 117, + COLOR_YUV2BGR_YVYU = 118, + COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2, + COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2, + + COLOR_YUV2RGBA_YUY2 = 119, + COLOR_YUV2BGRA_YUY2 = 120, + COLOR_YUV2RGBA_YVYU = 121, + COLOR_YUV2BGRA_YVYU = 122, + COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2, + COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2, + + COLOR_YUV2GRAY_UYVY = 123, + COLOR_YUV2GRAY_YUY2 = 124, + //COLOR_YUV2GRAY_VYUY = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2, + + // alpha premultiplication + COLOR_RGBA2mRGBA = 125, + COLOR_mRGBA2RGBA = 126, + + COLOR_RGB2YUV_I420 = 127, + COLOR_BGR2YUV_I420 = 128, + COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420, + COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420, + + COLOR_RGBA2YUV_I420 = 129, + COLOR_BGRA2YUV_I420 = 130, + COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420, + COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420, + COLOR_RGB2YUV_YV12 = 131, + COLOR_BGR2YUV_YV12 = 132, + COLOR_RGBA2YUV_YV12 = 133, + COLOR_BGRA2YUV_YV12 = 134, + + COLOR_COLORCVT_MAX = 135 +}; + + +//! converts image from one color space to another +CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn=0 ); + +//! raster image moments +class CV_EXPORTS_W_MAP Moments +{ +public: + //! the default constructor + Moments(); + //! the full constructor + Moments(double m00, double m10, double m01, double m20, double m11, + double m02, double m30, double m21, double m12, double m03 ); + //! the conversion from CvMoments + Moments( const CvMoments& moments ); + //! the conversion to CvMoments + operator CvMoments() const; + + //! spatial moments + CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; + //! central moments + CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03; + //! central normalized moments + CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03; +}; + +//! computes moments of the rasterized shape or a vector of points +CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage=false ); + +//! computes 7 Hu invariants from the moments +CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] ); +CV_EXPORTS_W void HuMoments( const Moments& m, CV_OUT OutputArray hu ); + +//! type of the template matching operation +enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 }; + +//! computes the proximity map for the raster template and the image where the template is searched for +CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ, + OutputArray result, int method ); + +//! mode of the contour retrieval algorithm +enum +{ + RETR_EXTERNAL=CV_RETR_EXTERNAL, //!< retrieve only the most external (top-level) contours + RETR_LIST=CV_RETR_LIST, //!< retrieve all the contours without any hierarchical information + RETR_CCOMP=CV_RETR_CCOMP, //!< retrieve the connected components (that can possibly be nested) + RETR_TREE=CV_RETR_TREE, //!< retrieve all the contours and the whole hierarchy + RETR_FLOODFILL=CV_RETR_FLOODFILL +}; + +//! the contour approximation algorithm +enum +{ + CHAIN_APPROX_NONE=CV_CHAIN_APPROX_NONE, + CHAIN_APPROX_SIMPLE=CV_CHAIN_APPROX_SIMPLE, + CHAIN_APPROX_TC89_L1=CV_CHAIN_APPROX_TC89_L1, + CHAIN_APPROX_TC89_KCOS=CV_CHAIN_APPROX_TC89_KCOS +}; + +//! retrieves contours and the hierarchical information from black-n-white image. +CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours, + OutputArray hierarchy, int mode, + int method, Point offset=Point()); + +//! retrieves contours from black-n-white image. +CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours, + int mode, int method, Point offset=Point()); + +//! draws contours in the image +CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours, + int contourIdx, const Scalar& color, + int thickness=1, int lineType=8, + InputArray hierarchy=noArray(), + int maxLevel=INT_MAX, Point offset=Point() ); + +//! approximates contour or a curve using Douglas-Peucker algorithm +CV_EXPORTS_W void approxPolyDP( InputArray curve, + OutputArray approxCurve, + double epsilon, bool closed ); + +//! computes the contour perimeter (closed=true) or a curve length +CV_EXPORTS_W double arcLength( InputArray curve, bool closed ); +//! computes the bounding rectangle for a contour +CV_EXPORTS_W Rect boundingRect( InputArray points ); +//! computes the contour area +CV_EXPORTS_W double contourArea( InputArray contour, bool oriented=false ); +//! computes the minimal rotated rectangle for a set of points +CV_EXPORTS_W RotatedRect minAreaRect( InputArray points ); +//! computes the minimal enclosing circle for a set of points +CV_EXPORTS_W void minEnclosingCircle( InputArray points, + CV_OUT Point2f& center, CV_OUT float& radius ); +//! matches two contours using one of the available algorithms +CV_EXPORTS_W double matchShapes( InputArray contour1, InputArray contour2, + int method, double parameter ); +//! computes convex hull for a set of 2D points. +CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull, + bool clockwise=false, bool returnPoints=true ); +//! computes the contour convexity defects +CV_EXPORTS_W void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); + +//! returns true if the contour is convex. Does not support contours with self-intersection +CV_EXPORTS_W bool isContourConvex( InputArray contour ); + +//! finds intersection of two convex polygons +CV_EXPORTS_W float intersectConvexConvex( InputArray _p1, InputArray _p2, + OutputArray _p12, bool handleNested=true ); + +//! fits ellipse to the set of 2D points +CV_EXPORTS_W RotatedRect fitEllipse( InputArray points ); + +//! fits line to the set of 2D points using M-estimator algorithm +CV_EXPORTS_W void fitLine( InputArray points, OutputArray line, int distType, + double param, double reps, double aeps ); +//! checks if the point is inside the contour. Optionally computes the signed distance from the point to the contour boundary +CV_EXPORTS_W double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist ); + + +class CV_EXPORTS_W Subdiv2D +{ +public: + enum + { + PTLOC_ERROR = -2, + PTLOC_OUTSIDE_RECT = -1, + PTLOC_INSIDE = 0, + PTLOC_VERTEX = 1, + PTLOC_ON_EDGE = 2 + }; + + enum + { + NEXT_AROUND_ORG = 0x00, + NEXT_AROUND_DST = 0x22, + PREV_AROUND_ORG = 0x11, + PREV_AROUND_DST = 0x33, + NEXT_AROUND_LEFT = 0x13, + NEXT_AROUND_RIGHT = 0x31, + PREV_AROUND_LEFT = 0x20, + PREV_AROUND_RIGHT = 0x02 + }; + + CV_WRAP Subdiv2D(); + CV_WRAP Subdiv2D(Rect rect); + CV_WRAP void initDelaunay(Rect rect); + + CV_WRAP int insert(Point2f pt); + CV_WRAP void insert(const vector& ptvec); + CV_WRAP int locate(Point2f pt, CV_OUT int& edge, CV_OUT int& vertex); + + CV_WRAP int findNearest(Point2f pt, CV_OUT Point2f* nearestPt=0); + CV_WRAP void getEdgeList(CV_OUT vector& edgeList) const; + CV_WRAP void getTriangleList(CV_OUT vector& triangleList) const; + CV_WRAP void getVoronoiFacetList(const vector& idx, CV_OUT vector >& facetList, + CV_OUT vector& facetCenters); + + CV_WRAP Point2f getVertex(int vertex, CV_OUT int* firstEdge=0) const; + + CV_WRAP int getEdge( int edge, int nextEdgeType ) const; + CV_WRAP int nextEdge(int edge) const; + CV_WRAP int rotateEdge(int edge, int rotate) const; + CV_WRAP int symEdge(int edge) const; + CV_WRAP int edgeOrg(int edge, CV_OUT Point2f* orgpt=0) const; + CV_WRAP int edgeDst(int edge, CV_OUT Point2f* dstpt=0) const; + +protected: + int newEdge(); + void deleteEdge(int edge); + int newPoint(Point2f pt, bool isvirtual, int firstEdge=0); + void deletePoint(int vtx); + void setEdgePoints( int edge, int orgPt, int dstPt ); + void splice( int edgeA, int edgeB ); + int connectEdges( int edgeA, int edgeB ); + void swapEdges( int edge ); + int isRightOf(Point2f pt, int edge) const; + void calcVoronoi(); + void clearVoronoi(); + void checkSubdiv() const; + + struct CV_EXPORTS Vertex + { + Vertex(); + Vertex(Point2f pt, bool _isvirtual, int _firstEdge=0); + bool isvirtual() const; + bool isfree() const; + int firstEdge; + int type; + Point2f pt; + }; + struct CV_EXPORTS QuadEdge + { + QuadEdge(); + QuadEdge(int edgeidx); + bool isfree() const; + int next[4]; + int pt[4]; + }; + + vector vtx; + vector qedges; + int freeQEdge; + int freePoint; + bool validGeometry; + + int recentEdge; + Point2f topLeft; + Point2f bottomRight; +}; + +} + +#endif /* __cplusplus */ + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc_c.h diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc_c.h --- diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc_c.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/imgproc_c.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,623 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_IMGPROC_IMGPROC_C_H__ +#define __OPENCV_IMGPROC_IMGPROC_C_H__ + +#include "opencv2/core/core_c.h" +#include "opencv2/imgproc/types_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************** Background statistics accumulation *****************************/ + +/* Adds image to accumulator */ +CVAPI(void) cvAcc( const CvArr* image, CvArr* sum, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Adds squared image to accumulator */ +CVAPI(void) cvSquareAcc( const CvArr* image, CvArr* sqsum, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Adds a product of two images to accumulator */ +CVAPI(void) cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc, + const CvArr* mask CV_DEFAULT(NULL) ); + +/* Adds image to accumulator with weights: acc = acc*(1-alpha) + image*alpha */ +CVAPI(void) cvRunningAvg( const CvArr* image, CvArr* acc, double alpha, + const CvArr* mask CV_DEFAULT(NULL) ); + +/****************************************************************************************\ +* Image Processing * +\****************************************************************************************/ + +/* Copies source 2D array inside of the larger destination array and + makes a border of the specified type (IPL_BORDER_*) around the copied area. */ +CVAPI(void) cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset, + int bordertype, CvScalar value CV_DEFAULT(cvScalarAll(0))); + +/* Smoothes array (removes noise) */ +CVAPI(void) cvSmooth( const CvArr* src, CvArr* dst, + int smoothtype CV_DEFAULT(CV_GAUSSIAN), + int size1 CV_DEFAULT(3), + int size2 CV_DEFAULT(0), + double sigma1 CV_DEFAULT(0), + double sigma2 CV_DEFAULT(0)); + +/* Convolves the image with the kernel */ +CVAPI(void) cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, + CvPoint anchor CV_DEFAULT(cvPoint(-1,-1))); + +/* Finds integral image: SUM(X,Y) = sum(x. + After that sum of histogram bins is equal to */ +CVAPI(void) cvNormalizeHist( CvHistogram* hist, double factor ); + + +/* Clear all histogram bins that are below the threshold */ +CVAPI(void) cvThreshHist( CvHistogram* hist, double threshold ); + + +/* Compares two histogram */ +CVAPI(double) cvCompareHist( const CvHistogram* hist1, + const CvHistogram* hist2, + int method); + +/* Copies one histogram to another. Destination histogram is created if + the destination pointer is NULL */ +CVAPI(void) cvCopyHist( const CvHistogram* src, CvHistogram** dst ); + + +/* Calculates bayesian probabilistic histograms + (each or src and dst is an array of histograms */ +CVAPI(void) cvCalcBayesianProb( CvHistogram** src, int number, + CvHistogram** dst); + +/* Calculates array histogram */ +CVAPI(void) cvCalcArrHist( CvArr** arr, CvHistogram* hist, + int accumulate CV_DEFAULT(0), + const CvArr* mask CV_DEFAULT(NULL) ); + +CV_INLINE void cvCalcHist( IplImage** image, CvHistogram* hist, + int accumulate CV_DEFAULT(0), + const CvArr* mask CV_DEFAULT(NULL) ) +{ + cvCalcArrHist( (CvArr**)image, hist, accumulate, mask ); +} + +/* Calculates back project */ +CVAPI(void) cvCalcArrBackProject( CvArr** image, CvArr* dst, + const CvHistogram* hist ); +#define cvCalcBackProject(image, dst, hist) cvCalcArrBackProject((CvArr**)image, dst, hist) + + +/* Does some sort of template matching but compares histograms of + template and each window location */ +CVAPI(void) cvCalcArrBackProjectPatch( CvArr** image, CvArr* dst, CvSize range, + CvHistogram* hist, int method, + double factor ); +#define cvCalcBackProjectPatch( image, dst, range, hist, method, factor ) \ + cvCalcArrBackProjectPatch( (CvArr**)image, dst, range, hist, method, factor ) + + +/* calculates probabilistic density (divides one histogram by another) */ +CVAPI(void) cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, + CvHistogram* dst_hist, double scale CV_DEFAULT(255) ); + +/* equalizes histogram of 8-bit single-channel image */ +CVAPI(void) cvEqualizeHist( const CvArr* src, CvArr* dst ); + + +/* Applies distance transform to binary image */ +CVAPI(void) cvDistTransform( const CvArr* src, CvArr* dst, + int distance_type CV_DEFAULT(CV_DIST_L2), + int mask_size CV_DEFAULT(3), + const float* mask CV_DEFAULT(NULL), + CvArr* labels CV_DEFAULT(NULL), + int labelType CV_DEFAULT(CV_DIST_LABEL_CCOMP)); + + +/* Applies fixed-level threshold to grayscale image. + This is a basic operation applied before retrieving contours */ +CVAPI(double) cvThreshold( const CvArr* src, CvArr* dst, + double threshold, double max_value, + int threshold_type ); + +/* Applies adaptive threshold to grayscale image. + The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and + CV_ADAPTIVE_THRESH_GAUSSIAN_C are: + neighborhood size (3, 5, 7 etc.), + and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...) */ +CVAPI(void) cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value, + int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C), + int threshold_type CV_DEFAULT(CV_THRESH_BINARY), + int block_size CV_DEFAULT(3), + double param1 CV_DEFAULT(5)); + +/* Fills the connected component until the color difference gets large enough */ +CVAPI(void) cvFloodFill( CvArr* image, CvPoint seed_point, + CvScalar new_val, CvScalar lo_diff CV_DEFAULT(cvScalarAll(0)), + CvScalar up_diff CV_DEFAULT(cvScalarAll(0)), + CvConnectedComp* comp CV_DEFAULT(NULL), + int flags CV_DEFAULT(4), + CvArr* mask CV_DEFAULT(NULL)); + +/****************************************************************************************\ +* Feature detection * +\****************************************************************************************/ + +/* Runs canny edge detector */ +CVAPI(void) cvCanny( const CvArr* image, CvArr* edges, double threshold1, + double threshold2, int aperture_size CV_DEFAULT(3) ); + +/* Calculates constraint image for corner detection + Dx^2 * Dyy + Dxx * Dy^2 - 2 * Dx * Dy * Dxy. + Applying threshold to the result gives coordinates of corners */ +CVAPI(void) cvPreCornerDetect( const CvArr* image, CvArr* corners, + int aperture_size CV_DEFAULT(3) ); + +/* Calculates eigen values and vectors of 2x2 + gradient covariation matrix at every image pixel */ +CVAPI(void) cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv, + int block_size, int aperture_size CV_DEFAULT(3) ); + +/* Calculates minimal eigenvalue for 2x2 gradient covariation matrix at + every image pixel */ +CVAPI(void) cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, + int block_size, int aperture_size CV_DEFAULT(3) ); + +/* Harris corner detector: + Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel */ +CVAPI(void) cvCornerHarris( const CvArr* image, CvArr* harris_responce, + int block_size, int aperture_size CV_DEFAULT(3), + double k CV_DEFAULT(0.04) ); + +/* Adjust corner position using some sort of gradient search */ +CVAPI(void) cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, + int count, CvSize win, CvSize zero_zone, + CvTermCriteria criteria ); + +/* Finds a sparse set of points within the selected region + that seem to be easy to track */ +CVAPI(void) cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, + CvArr* temp_image, CvPoint2D32f* corners, + int* corner_count, double quality_level, + double min_distance, + const CvArr* mask CV_DEFAULT(NULL), + int block_size CV_DEFAULT(3), + int use_harris CV_DEFAULT(0), + double k CV_DEFAULT(0.04) ); + +/* Finds lines on binary image using one of several methods. + line_storage is either memory storage or 1 x CvMat, its + number of columns is changed by the function. + method is one of CV_HOUGH_*; + rho, theta and threshold are used for each of those methods; + param1 ~ line length, param2 ~ line gap - for probabilistic, + param1 ~ srn, param2 ~ stn - for multi-scale */ +CVAPI(CvSeq*) cvHoughLines2( CvArr* image, void* line_storage, int method, + double rho, double theta, int threshold, + double param1 CV_DEFAULT(0), double param2 CV_DEFAULT(0)); + +/* Finds circles in the image */ +CVAPI(CvSeq*) cvHoughCircles( CvArr* image, void* circle_storage, + int method, double dp, double min_dist, + double param1 CV_DEFAULT(100), + double param2 CV_DEFAULT(100), + int min_radius CV_DEFAULT(0), + int max_radius CV_DEFAULT(0)); + +/* Fits a line into set of 2d or 3d points in a robust way (M-estimator technique) */ +CVAPI(void) cvFitLine( const CvArr* points, int dist_type, double param, + double reps, double aeps, float* line ); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/types_c.h diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/types_c.h --- diffimg-1.5.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/types_c.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/include/opencv2/imgproc/types_c.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,640 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_IMGPROC_TYPES_C_H__ +#define __OPENCV_IMGPROC_TYPES_C_H__ + +#include "opencv2/core/core_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Connected component structure */ +typedef struct CvConnectedComp +{ + double area; /* area of the connected component */ + CvScalar value; /* average color of the connected component */ + CvRect rect; /* ROI of the component */ + CvSeq* contour; /* optional component boundary + (the contour might have child contours corresponding to the holes)*/ +} +CvConnectedComp; + +/* Image smooth methods */ +enum +{ + CV_BLUR_NO_SCALE =0, + CV_BLUR =1, + CV_GAUSSIAN =2, + CV_MEDIAN =3, + CV_BILATERAL =4 +}; + +/* Filters used in pyramid decomposition */ +enum +{ + CV_GAUSSIAN_5x5 = 7 +}; + +/* Special filters */ +enum +{ + CV_SCHARR =-1, + CV_MAX_SOBEL_KSIZE =7 +}; + +/* Constants for color conversion */ +enum +{ + CV_BGR2BGRA =0, + CV_RGB2RGBA =CV_BGR2BGRA, + + CV_BGRA2BGR =1, + CV_RGBA2RGB =CV_BGRA2BGR, + + CV_BGR2RGBA =2, + CV_RGB2BGRA =CV_BGR2RGBA, + + CV_RGBA2BGR =3, + CV_BGRA2RGB =CV_RGBA2BGR, + + CV_BGR2RGB =4, + CV_RGB2BGR =CV_BGR2RGB, + + CV_BGRA2RGBA =5, + CV_RGBA2BGRA =CV_BGRA2RGBA, + + CV_BGR2GRAY =6, + CV_RGB2GRAY =7, + CV_GRAY2BGR =8, + CV_GRAY2RGB =CV_GRAY2BGR, + CV_GRAY2BGRA =9, + CV_GRAY2RGBA =CV_GRAY2BGRA, + CV_BGRA2GRAY =10, + CV_RGBA2GRAY =11, + + CV_BGR2BGR565 =12, + CV_RGB2BGR565 =13, + CV_BGR5652BGR =14, + CV_BGR5652RGB =15, + CV_BGRA2BGR565 =16, + CV_RGBA2BGR565 =17, + CV_BGR5652BGRA =18, + CV_BGR5652RGBA =19, + + CV_GRAY2BGR565 =20, + CV_BGR5652GRAY =21, + + CV_BGR2BGR555 =22, + CV_RGB2BGR555 =23, + CV_BGR5552BGR =24, + CV_BGR5552RGB =25, + CV_BGRA2BGR555 =26, + CV_RGBA2BGR555 =27, + CV_BGR5552BGRA =28, + CV_BGR5552RGBA =29, + + CV_GRAY2BGR555 =30, + CV_BGR5552GRAY =31, + + CV_BGR2XYZ =32, + CV_RGB2XYZ =33, + CV_XYZ2BGR =34, + CV_XYZ2RGB =35, + + CV_BGR2YCrCb =36, + CV_RGB2YCrCb =37, + CV_YCrCb2BGR =38, + CV_YCrCb2RGB =39, + + CV_BGR2HSV =40, + CV_RGB2HSV =41, + + CV_BGR2Lab =44, + CV_RGB2Lab =45, + + CV_BayerBG2BGR =46, + CV_BayerGB2BGR =47, + CV_BayerRG2BGR =48, + CV_BayerGR2BGR =49, + + CV_BayerBG2RGB =CV_BayerRG2BGR, + CV_BayerGB2RGB =CV_BayerGR2BGR, + CV_BayerRG2RGB =CV_BayerBG2BGR, + CV_BayerGR2RGB =CV_BayerGB2BGR, + + CV_BGR2Luv =50, + CV_RGB2Luv =51, + CV_BGR2HLS =52, + CV_RGB2HLS =53, + + CV_HSV2BGR =54, + CV_HSV2RGB =55, + + CV_Lab2BGR =56, + CV_Lab2RGB =57, + CV_Luv2BGR =58, + CV_Luv2RGB =59, + CV_HLS2BGR =60, + CV_HLS2RGB =61, + + CV_BayerBG2BGR_VNG =62, + CV_BayerGB2BGR_VNG =63, + CV_BayerRG2BGR_VNG =64, + CV_BayerGR2BGR_VNG =65, + + CV_BayerBG2RGB_VNG =CV_BayerRG2BGR_VNG, + CV_BayerGB2RGB_VNG =CV_BayerGR2BGR_VNG, + CV_BayerRG2RGB_VNG =CV_BayerBG2BGR_VNG, + CV_BayerGR2RGB_VNG =CV_BayerGB2BGR_VNG, + + CV_BGR2HSV_FULL = 66, + CV_RGB2HSV_FULL = 67, + CV_BGR2HLS_FULL = 68, + CV_RGB2HLS_FULL = 69, + + CV_HSV2BGR_FULL = 70, + CV_HSV2RGB_FULL = 71, + CV_HLS2BGR_FULL = 72, + CV_HLS2RGB_FULL = 73, + + CV_LBGR2Lab = 74, + CV_LRGB2Lab = 75, + CV_LBGR2Luv = 76, + CV_LRGB2Luv = 77, + + CV_Lab2LBGR = 78, + CV_Lab2LRGB = 79, + CV_Luv2LBGR = 80, + CV_Luv2LRGB = 81, + + CV_BGR2YUV = 82, + CV_RGB2YUV = 83, + CV_YUV2BGR = 84, + CV_YUV2RGB = 85, + + CV_BayerBG2GRAY = 86, + CV_BayerGB2GRAY = 87, + CV_BayerRG2GRAY = 88, + CV_BayerGR2GRAY = 89, + + //YUV 4:2:0 formats family + CV_YUV2RGB_NV12 = 90, + CV_YUV2BGR_NV12 = 91, + CV_YUV2RGB_NV21 = 92, + CV_YUV2BGR_NV21 = 93, + CV_YUV420sp2RGB = CV_YUV2RGB_NV21, + CV_YUV420sp2BGR = CV_YUV2BGR_NV21, + + CV_YUV2RGBA_NV12 = 94, + CV_YUV2BGRA_NV12 = 95, + CV_YUV2RGBA_NV21 = 96, + CV_YUV2BGRA_NV21 = 97, + CV_YUV420sp2RGBA = CV_YUV2RGBA_NV21, + CV_YUV420sp2BGRA = CV_YUV2BGRA_NV21, + + CV_YUV2RGB_YV12 = 98, + CV_YUV2BGR_YV12 = 99, + CV_YUV2RGB_IYUV = 100, + CV_YUV2BGR_IYUV = 101, + CV_YUV2RGB_I420 = CV_YUV2RGB_IYUV, + CV_YUV2BGR_I420 = CV_YUV2BGR_IYUV, + CV_YUV420p2RGB = CV_YUV2RGB_YV12, + CV_YUV420p2BGR = CV_YUV2BGR_YV12, + + CV_YUV2RGBA_YV12 = 102, + CV_YUV2BGRA_YV12 = 103, + CV_YUV2RGBA_IYUV = 104, + CV_YUV2BGRA_IYUV = 105, + CV_YUV2RGBA_I420 = CV_YUV2RGBA_IYUV, + CV_YUV2BGRA_I420 = CV_YUV2BGRA_IYUV, + CV_YUV420p2RGBA = CV_YUV2RGBA_YV12, + CV_YUV420p2BGRA = CV_YUV2BGRA_YV12, + + CV_YUV2GRAY_420 = 106, + CV_YUV2GRAY_NV21 = CV_YUV2GRAY_420, + CV_YUV2GRAY_NV12 = CV_YUV2GRAY_420, + CV_YUV2GRAY_YV12 = CV_YUV2GRAY_420, + CV_YUV2GRAY_IYUV = CV_YUV2GRAY_420, + CV_YUV2GRAY_I420 = CV_YUV2GRAY_420, + CV_YUV420sp2GRAY = CV_YUV2GRAY_420, + CV_YUV420p2GRAY = CV_YUV2GRAY_420, + + //YUV 4:2:2 formats family + CV_YUV2RGB_UYVY = 107, + CV_YUV2BGR_UYVY = 108, + //CV_YUV2RGB_VYUY = 109, + //CV_YUV2BGR_VYUY = 110, + CV_YUV2RGB_Y422 = CV_YUV2RGB_UYVY, + CV_YUV2BGR_Y422 = CV_YUV2BGR_UYVY, + CV_YUV2RGB_UYNV = CV_YUV2RGB_UYVY, + CV_YUV2BGR_UYNV = CV_YUV2BGR_UYVY, + + CV_YUV2RGBA_UYVY = 111, + CV_YUV2BGRA_UYVY = 112, + //CV_YUV2RGBA_VYUY = 113, + //CV_YUV2BGRA_VYUY = 114, + CV_YUV2RGBA_Y422 = CV_YUV2RGBA_UYVY, + CV_YUV2BGRA_Y422 = CV_YUV2BGRA_UYVY, + CV_YUV2RGBA_UYNV = CV_YUV2RGBA_UYVY, + CV_YUV2BGRA_UYNV = CV_YUV2BGRA_UYVY, + + CV_YUV2RGB_YUY2 = 115, + CV_YUV2BGR_YUY2 = 116, + CV_YUV2RGB_YVYU = 117, + CV_YUV2BGR_YVYU = 118, + CV_YUV2RGB_YUYV = CV_YUV2RGB_YUY2, + CV_YUV2BGR_YUYV = CV_YUV2BGR_YUY2, + CV_YUV2RGB_YUNV = CV_YUV2RGB_YUY2, + CV_YUV2BGR_YUNV = CV_YUV2BGR_YUY2, + + CV_YUV2RGBA_YUY2 = 119, + CV_YUV2BGRA_YUY2 = 120, + CV_YUV2RGBA_YVYU = 121, + CV_YUV2BGRA_YVYU = 122, + CV_YUV2RGBA_YUYV = CV_YUV2RGBA_YUY2, + CV_YUV2BGRA_YUYV = CV_YUV2BGRA_YUY2, + CV_YUV2RGBA_YUNV = CV_YUV2RGBA_YUY2, + CV_YUV2BGRA_YUNV = CV_YUV2BGRA_YUY2, + + CV_YUV2GRAY_UYVY = 123, + CV_YUV2GRAY_YUY2 = 124, + //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY, + CV_YUV2GRAY_Y422 = CV_YUV2GRAY_UYVY, + CV_YUV2GRAY_UYNV = CV_YUV2GRAY_UYVY, + CV_YUV2GRAY_YVYU = CV_YUV2GRAY_YUY2, + CV_YUV2GRAY_YUYV = CV_YUV2GRAY_YUY2, + CV_YUV2GRAY_YUNV = CV_YUV2GRAY_YUY2, + + // alpha premultiplication + CV_RGBA2mRGBA = 125, + CV_mRGBA2RGBA = 126, + + CV_RGB2YUV_I420 = 127, + CV_BGR2YUV_I420 = 128, + CV_RGB2YUV_IYUV = CV_RGB2YUV_I420, + CV_BGR2YUV_IYUV = CV_BGR2YUV_I420, + + CV_RGBA2YUV_I420 = 129, + CV_BGRA2YUV_I420 = 130, + CV_RGBA2YUV_IYUV = CV_RGBA2YUV_I420, + CV_BGRA2YUV_IYUV = CV_BGRA2YUV_I420, + CV_RGB2YUV_YV12 = 131, + CV_BGR2YUV_YV12 = 132, + CV_RGBA2YUV_YV12 = 133, + CV_BGRA2YUV_YV12 = 134, + + CV_COLORCVT_MAX = 135 +}; + + +/* Sub-pixel interpolation methods */ +enum +{ + CV_INTER_NN =0, + CV_INTER_LINEAR =1, + CV_INTER_CUBIC =2, + CV_INTER_AREA =3, + CV_INTER_LANCZOS4 =4 +}; + +/* ... and other image warping flags */ +enum +{ + CV_WARP_FILL_OUTLIERS =8, + CV_WARP_INVERSE_MAP =16 +}; + +/* Shapes of a structuring element for morphological operations */ +enum +{ + CV_SHAPE_RECT =0, + CV_SHAPE_CROSS =1, + CV_SHAPE_ELLIPSE =2, + CV_SHAPE_CUSTOM =100 +}; + +/* Morphological operations */ +enum +{ + CV_MOP_ERODE =0, + CV_MOP_DILATE =1, + CV_MOP_OPEN =2, + CV_MOP_CLOSE =3, + CV_MOP_GRADIENT =4, + CV_MOP_TOPHAT =5, + CV_MOP_BLACKHAT =6 +}; + +/* Spatial and central moments */ +typedef struct CvMoments +{ + double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; /* spatial moments */ + double mu20, mu11, mu02, mu30, mu21, mu12, mu03; /* central moments */ + double inv_sqrt_m00; /* m00 != 0 ? 1/sqrt(m00) : 0 */ +} +CvMoments; + +/* Hu invariants */ +typedef struct CvHuMoments +{ + double hu1, hu2, hu3, hu4, hu5, hu6, hu7; /* Hu invariants */ +} +CvHuMoments; + +/* Template matching methods */ +enum +{ + CV_TM_SQDIFF =0, + CV_TM_SQDIFF_NORMED =1, + CV_TM_CCORR =2, + CV_TM_CCORR_NORMED =3, + CV_TM_CCOEFF =4, + CV_TM_CCOEFF_NORMED =5 +}; + +typedef float (CV_CDECL * CvDistanceFunction)( const float* a, const float* b, void* user_param ); + +/* Contour retrieval modes */ +enum +{ + CV_RETR_EXTERNAL=0, + CV_RETR_LIST=1, + CV_RETR_CCOMP=2, + CV_RETR_TREE=3, + CV_RETR_FLOODFILL=4 +}; + +/* Contour approximation methods */ +enum +{ + CV_CHAIN_CODE=0, + CV_CHAIN_APPROX_NONE=1, + CV_CHAIN_APPROX_SIMPLE=2, + CV_CHAIN_APPROX_TC89_L1=3, + CV_CHAIN_APPROX_TC89_KCOS=4, + CV_LINK_RUNS=5 +}; + +/* +Internal structure that is used for sequental retrieving contours from the image. +It supports both hierarchical and plane variants of Suzuki algorithm. +*/ +typedef struct _CvContourScanner* CvContourScanner; + +/* Freeman chain reader state */ +typedef struct CvChainPtReader +{ + CV_SEQ_READER_FIELDS() + char code; + CvPoint pt; + schar deltas[8][2]; +} +CvChainPtReader; + +/* initializes 8-element array for fast access to 3x3 neighborhood of a pixel */ +#define CV_INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)) + + +/****************************************************************************************\ +* Planar subdivisions * +\****************************************************************************************/ + +typedef size_t CvSubdiv2DEdge; + +#define CV_QUADEDGE2D_FIELDS() \ + int flags; \ + struct CvSubdiv2DPoint* pt[4]; \ + CvSubdiv2DEdge next[4]; + +#define CV_SUBDIV2D_POINT_FIELDS()\ + int flags; \ + CvSubdiv2DEdge first; \ + CvPoint2D32f pt; \ + int id; + +#define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30) + +typedef struct CvQuadEdge2D +{ + CV_QUADEDGE2D_FIELDS() +} +CvQuadEdge2D; + +typedef struct CvSubdiv2DPoint +{ + CV_SUBDIV2D_POINT_FIELDS() +} +CvSubdiv2DPoint; + +#define CV_SUBDIV2D_FIELDS() \ + CV_GRAPH_FIELDS() \ + int quad_edges; \ + int is_geometry_valid; \ + CvSubdiv2DEdge recent_edge; \ + CvPoint2D32f topleft; \ + CvPoint2D32f bottomright; + +typedef struct CvSubdiv2D +{ + CV_SUBDIV2D_FIELDS() +} +CvSubdiv2D; + + +typedef enum CvSubdiv2DPointLocation +{ + CV_PTLOC_ERROR = -2, + CV_PTLOC_OUTSIDE_RECT = -1, + CV_PTLOC_INSIDE = 0, + CV_PTLOC_VERTEX = 1, + CV_PTLOC_ON_EDGE = 2 +} +CvSubdiv2DPointLocation; + +typedef enum CvNextEdgeType +{ + CV_NEXT_AROUND_ORG = 0x00, + CV_NEXT_AROUND_DST = 0x22, + CV_PREV_AROUND_ORG = 0x11, + CV_PREV_AROUND_DST = 0x33, + CV_NEXT_AROUND_LEFT = 0x13, + CV_NEXT_AROUND_RIGHT = 0x31, + CV_PREV_AROUND_LEFT = 0x20, + CV_PREV_AROUND_RIGHT = 0x02 +} +CvNextEdgeType; + +/* get the next edge with the same origin point (counterwise) */ +#define CV_SUBDIV2D_NEXT_EDGE( edge ) (((CvQuadEdge2D*)((edge) & ~3))->next[(edge)&3]) + + +/* Contour approximation algorithms */ +enum +{ + CV_POLY_APPROX_DP = 0 +}; + +/* Shape matching methods */ +enum +{ + CV_CONTOURS_MATCH_I1 =1, + CV_CONTOURS_MATCH_I2 =2, + CV_CONTOURS_MATCH_I3 =3 +}; + +/* Shape orientation */ +enum +{ + CV_CLOCKWISE =1, + CV_COUNTER_CLOCKWISE =2 +}; + + +/* Convexity defect */ +typedef struct CvConvexityDefect +{ + CvPoint* start; /* point of the contour where the defect begins */ + CvPoint* end; /* point of the contour where the defect ends */ + CvPoint* depth_point; /* the farthest from the convex hull point within the defect */ + float depth; /* distance between the farthest point and the convex hull */ +} CvConvexityDefect; + + +/* Histogram comparison methods */ +enum +{ + CV_COMP_CORREL =0, + CV_COMP_CHISQR =1, + CV_COMP_INTERSECT =2, + CV_COMP_BHATTACHARYYA =3, + CV_COMP_HELLINGER =CV_COMP_BHATTACHARYYA +}; + +/* Mask size for distance transform */ +enum +{ + CV_DIST_MASK_3 =3, + CV_DIST_MASK_5 =5, + CV_DIST_MASK_PRECISE =0 +}; + +/* Content of output label array: connected components or pixels */ +enum +{ + CV_DIST_LABEL_CCOMP = 0, + CV_DIST_LABEL_PIXEL = 1 +}; + +/* Distance types for Distance Transform and M-estimators */ +enum +{ + CV_DIST_USER =-1, /* User defined distance */ + CV_DIST_L1 =1, /* distance = |x1-x2| + |y1-y2| */ + CV_DIST_L2 =2, /* the simple euclidean distance */ + CV_DIST_C =3, /* distance = max(|x1-x2|,|y1-y2|) */ + CV_DIST_L12 =4, /* L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */ + CV_DIST_FAIR =5, /* distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */ + CV_DIST_WELSCH =6, /* distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */ + CV_DIST_HUBER =7 /* distance = |x| threshold ? max_value : 0 */ + CV_THRESH_BINARY_INV =1, /* value = value > threshold ? 0 : max_value */ + CV_THRESH_TRUNC =2, /* value = value > threshold ? threshold : value */ + CV_THRESH_TOZERO =3, /* value = value > threshold ? value : 0 */ + CV_THRESH_TOZERO_INV =4, /* value = value > threshold ? 0 : value */ + CV_THRESH_MASK =7, + CV_THRESH_OTSU =8 /* use Otsu algorithm to choose the optimal threshold value; + combine the flag with one of the above CV_THRESH_* values */ +}; + +/* Adaptive threshold methods */ +enum +{ + CV_ADAPTIVE_THRESH_MEAN_C =0, + CV_ADAPTIVE_THRESH_GAUSSIAN_C =1 +}; + +/* FloodFill flags */ +enum +{ + CV_FLOODFILL_FIXED_RANGE =(1 << 16), + CV_FLOODFILL_MASK_ONLY =(1 << 17) +}; + + +/* Canny edge detector flags */ +enum +{ + CV_CANNY_L2_GRADIENT =(1 << 31) +}; + +/* Variants of a Hough transform */ +enum +{ + CV_HOUGH_STANDARD =0, + CV_HOUGH_PROBABILISTIC =1, + CV_HOUGH_MULTI_SCALE =2, + CV_HOUGH_GRADIENT =3 +}; + + +/* Fast search data structures */ +struct CvFeatureTree; +struct CvLSH; +struct CvLSHOperations; + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_bilateral.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_bilateral.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_bilateral.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_bilateral.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,38 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(Mat_Type, CV_8UC1, CV_8UC3, CV_32FC1, CV_32FC3) + +typedef TestBaseWithParam< tr1::tuple > TestBilateralFilter; + +PERF_TEST_P( TestBilateralFilter, BilateralFilter, + Combine( + Values( szVGA, sz1080p ), // image size + Values( 3, 5 ), // d + ValuesIn( Mat_Type::all() ) // image type + ) +) +{ + Size sz; + int d, type; + const double sigmaColor = 1., sigmaSpace = 1.; + + sz = get<0>(GetParam()); + d = get<1>(GetParam()); + type = get<2>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).out(dst).time(20); + + TEST_CYCLE() bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, BORDER_DEFAULT); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_blur.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_blur.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_blur.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_blur.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,205 @@ +#include "perf_precomp.hpp" +#include "opencv2/core/internal.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Size_MatType_kSize_t; +typedef perf::TestBaseWithParam Size_MatType_kSize; + +PERF_TEST_P(Size_MatType_kSize, medianBlur, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), + testing::Values(3, 5) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + int ksize = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + if (CV_MAT_DEPTH(type) > CV_16S || CV_MAT_CN(type) > 1) + declare.time(15); + + TEST_CYCLE() medianBlur(src, dst, ksize); + + SANITY_CHECK(dst); +} + +CV_ENUM(BorderType3x3, BORDER_REPLICATE, BORDER_CONSTANT) +CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT101) + +typedef std::tr1::tuple Size_MatType_BorderType3x3_t; +typedef perf::TestBaseWithParam Size_MatType_BorderType3x3; + +typedef std::tr1::tuple Size_MatType_BorderType_t; +typedef perf::TestBaseWithParam Size_MatType_BorderType; + +PERF_TEST_P(Size_MatType_BorderType3x3, gaussianBlur3x3, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType3x3 btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() GaussianBlur(src, dst, Size(3,3), 0, 0, btype); + + SANITY_CHECK(dst, 1); +} + +PERF_TEST_P(Size_MatType_BorderType3x3, blur3x3, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType3x3 btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() blur(src, dst, Size(3,3), Point(-1,-1), btype); + + SANITY_CHECK(dst, 1); +} + +PERF_TEST_P(Size_MatType_BorderType, blur16x16, + testing::Combine( + testing::Values(szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() blur(src, dst, Size(16,16), Point(-1,-1), btype); + + SANITY_CHECK(dst, 1e-3); +} + +PERF_TEST_P(Size_MatType_BorderType3x3, box3x3, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_32FC3), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType3x3 btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() boxFilter(src, dst, -1, Size(3,3), Point(-1,-1), false, btype); + + SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_BorderType3x3, box3x3_inplace, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_32FC3), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType3x3 btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + while(next()) + { + src.copyTo(dst); + startTimer(); + boxFilter(dst, dst, -1, Size(3,3), Point(-1,-1), false, btype); + stopTimer(); + } + + SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE); +} + +PERF_TEST_P(Size_MatType_BorderType, gaussianBlur5x5, + testing::Combine( + testing::Values(szODD, szQVGA, szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() GaussianBlur(src, dst, Size(5,5), 0, 0, btype); + + SANITY_CHECK(dst, 1e-3); +} + +PERF_TEST_P(Size_MatType_BorderType, blur5x5, + testing::Combine( + testing::Values(szVGA, sz720p), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1, CV_32FC3), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int type = get<1>(GetParam()); + BorderType btype = get<2>(GetParam()); + + Mat src(size, type); + Mat dst(size, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() blur(src, dst, Size(5,5), Point(-1,-1), btype); + + SANITY_CHECK(dst, 1); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_canny.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_canny.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_canny.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_canny.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,37 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple > Img_Aperture_L2_thresholds_t; +typedef perf::TestBaseWithParam Img_Aperture_L2_thresholds; + +PERF_TEST_P(Img_Aperture_L2_thresholds, canny, + testing::Combine( + testing::Values( "cv/shared/lena.png", "stitching/b1.png", "cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png" ), + testing::Values( 3, 5 ), + testing::Bool(), + testing::Values( make_tuple(50.0, 100.0), make_tuple(0.0, 50.0), make_tuple(100.0, 120.0) ) + ) + ) +{ + String filename = getDataPath(get<0>(GetParam())); + int aperture = get<1>(GetParam()); + bool useL2 = get<2>(GetParam()); + double thresh_low = get<0>(get<3>(GetParam())); + double thresh_high = get<1>(get<3>(GetParam())); + + Mat img = imread(filename, IMREAD_GRAYSCALE); + if (img.empty()) + FAIL() << "Unable to load source image " << filename; + Mat edges(img.size(), img.type()); + + declare.in(img).out(edges); + + TEST_CYCLE() Canny(img, edges, thresh_low, thresh_high, aperture, useL2); + + SANITY_CHECK(edges); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cornerEigenValsAndVecs.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cornerEigenValsAndVecs.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cornerEigenValsAndVecs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cornerEigenValsAndVecs.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,40 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT_101) + +typedef std::tr1::tuple Img_BlockSize_ApertureSize_BorderType_t; +typedef perf::TestBaseWithParam Img_BlockSize_ApertureSize_BorderType; + +PERF_TEST_P(Img_BlockSize_ApertureSize_BorderType, cornerEigenValsAndVecs, + testing::Combine( + testing::Values( "stitching/a1.png", "cv/shared/pic5.png"), + testing::Values( 3, 5 ), + testing::Values( 3, 5 ), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + String filename = getDataPath(get<0>(GetParam())); + int blockSize = get<1>(GetParam()); + int apertureSize = get<2>(GetParam()); + BorderType borderType = get<3>(GetParam()); + + Mat src = imread(filename, IMREAD_GRAYSCALE); + if (src.empty()) + FAIL() << "Unable to load source image" << filename; + + Mat dst; + + TEST_CYCLE() cornerEigenValsAndVecs(src, dst, blockSize, apertureSize, borderType); + + Mat l1; + extractChannel(dst, l1, 0); + + SANITY_CHECK(l1, 2e-5); +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cornerHarris.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cornerHarris.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cornerHarris.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cornerHarris.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,39 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT_101) + +typedef std::tr1::tuple Img_BlockSize_ApertureSize_k_BorderType_t; +typedef perf::TestBaseWithParam Img_BlockSize_ApertureSize_k_BorderType; + +PERF_TEST_P(Img_BlockSize_ApertureSize_k_BorderType, cornerHarris, + testing::Combine( + testing::Values( "stitching/a1.png", "cv/shared/pic5.png"), + testing::Values( 3, 5 ), + testing::Values( 3, 5 ), + testing::Values( 0.04, 0.1 ), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + String filename = getDataPath(get<0>(GetParam())); + int blockSize = get<1>(GetParam()); + int apertureSize = get<2>(GetParam()); + double k = get<3>(GetParam()); + BorderType borderType = get<4>(GetParam()); + + Mat src = imread(filename, IMREAD_GRAYSCALE); + if (src.empty()) + FAIL() << "Unable to load source image" << filename; + + Mat dst; + + TEST_CYCLE() cornerHarris(src, dst, blockSize, apertureSize, k, borderType); + + SANITY_CHECK(dst, 2e-5); +} \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cvt_color.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cvt_color.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_cvt_color.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_cvt_color.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,340 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +//extra color conversions supported implicitly +enum +{ + CX_BGRA2HLS = CV_COLORCVT_MAX + CV_BGR2HLS, + CX_BGRA2HLS_FULL = CV_COLORCVT_MAX + CV_BGR2HLS_FULL, + CX_BGRA2HSV = CV_COLORCVT_MAX + CV_BGR2HSV, + CX_BGRA2HSV_FULL = CV_COLORCVT_MAX + CV_BGR2HSV_FULL, + CX_BGRA2Lab = CV_COLORCVT_MAX + CV_BGR2Lab, + CX_BGRA2Luv = CV_COLORCVT_MAX + CV_BGR2Luv, + CX_BGRA2XYZ = CV_COLORCVT_MAX + CV_BGR2XYZ, + CX_BGRA2YCrCb = CV_COLORCVT_MAX + CV_BGR2YCrCb, + CX_BGRA2YUV = CV_COLORCVT_MAX + CV_BGR2YUV, + CX_HLS2BGRA = CV_COLORCVT_MAX + CV_HLS2BGR, + CX_HLS2BGRA_FULL = CV_COLORCVT_MAX + CV_HLS2BGR_FULL, + CX_HLS2RGBA = CV_COLORCVT_MAX + CV_HLS2RGB, + CX_HLS2RGBA_FULL = CV_COLORCVT_MAX + CV_HLS2RGB_FULL, + CX_HSV2BGRA = CV_COLORCVT_MAX + CV_HSV2BGR, + CX_HSV2BGRA_FULL = CV_COLORCVT_MAX + CV_HSV2BGR_FULL, + CX_HSV2RGBA = CV_COLORCVT_MAX + CV_HSV2RGB, + CX_HSV2RGBA_FULL = CV_COLORCVT_MAX + CV_HSV2RGB_FULL, + CX_Lab2BGRA = CV_COLORCVT_MAX + CV_Lab2BGR, + CX_Lab2LBGRA = CV_COLORCVT_MAX + CV_Lab2LBGR, + CX_Lab2LRGBA = CV_COLORCVT_MAX + CV_Lab2LRGB, + CX_Lab2RGBA = CV_COLORCVT_MAX + CV_Lab2RGB, + CX_LBGRA2Lab = CV_COLORCVT_MAX + CV_LBGR2Lab, + CX_LBGRA2Luv = CV_COLORCVT_MAX + CV_LBGR2Luv, + CX_LRGBA2Lab = CV_COLORCVT_MAX + CV_LRGB2Lab, + CX_LRGBA2Luv = CV_COLORCVT_MAX + CV_LRGB2Luv, + CX_Luv2BGRA = CV_COLORCVT_MAX + CV_Luv2BGR, + CX_Luv2LBGRA = CV_COLORCVT_MAX + CV_Luv2LBGR, + CX_Luv2LRGBA = CV_COLORCVT_MAX + CV_Luv2LRGB, + CX_Luv2RGBA = CV_COLORCVT_MAX + CV_Luv2RGB, + CX_RGBA2HLS = CV_COLORCVT_MAX + CV_RGB2HLS, + CX_RGBA2HLS_FULL = CV_COLORCVT_MAX + CV_RGB2HLS_FULL, + CX_RGBA2HSV = CV_COLORCVT_MAX + CV_RGB2HSV, + CX_RGBA2HSV_FULL = CV_COLORCVT_MAX + CV_RGB2HSV_FULL, + CX_RGBA2Lab = CV_COLORCVT_MAX + CV_RGB2Lab, + CX_RGBA2Luv = CV_COLORCVT_MAX + CV_RGB2Luv, + CX_RGBA2XYZ = CV_COLORCVT_MAX + CV_RGB2XYZ, + CX_RGBA2YCrCb = CV_COLORCVT_MAX + CV_RGB2YCrCb, + CX_RGBA2YUV = CV_COLORCVT_MAX + CV_RGB2YUV, + CX_XYZ2BGRA = CV_COLORCVT_MAX + CV_XYZ2BGR, + CX_XYZ2RGBA = CV_COLORCVT_MAX + CV_XYZ2RGB, + CX_YCrCb2BGRA = CV_COLORCVT_MAX + CV_YCrCb2BGR, + CX_YCrCb2RGBA = CV_COLORCVT_MAX + CV_YCrCb2RGB, + CX_YUV2BGRA = CV_COLORCVT_MAX + CV_YUV2BGR, + CX_YUV2RGBA = CV_COLORCVT_MAX + CV_YUV2RGB +}; + +CV_ENUM(CvtMode, + CV_BGR2BGR555, CV_BGR2BGR565, CV_BGR2BGRA, CV_BGR2GRAY, + CV_BGR2HLS, CV_BGR2HLS_FULL, CV_BGR2HSV, CV_BGR2HSV_FULL, + CV_BGR2Lab, CV_BGR2Luv, CV_BGR2RGB, CV_BGR2RGBA, CV_BGR2XYZ, + CV_BGR2YCrCb, CV_BGR2YUV, CV_BGR5552BGR, CV_BGR5552BGRA, + + CV_BGR5552GRAY, CV_BGR5552RGB, CV_BGR5552RGBA, CV_BGR5652BGR, + CV_BGR5652BGRA, CV_BGR5652GRAY, CV_BGR5652RGB, CV_BGR5652RGBA, + + CV_BGRA2BGR, CV_BGRA2BGR555, CV_BGRA2BGR565, CV_BGRA2GRAY, CV_BGRA2RGBA, + CX_BGRA2HLS, CX_BGRA2HLS_FULL, CX_BGRA2HSV, CX_BGRA2HSV_FULL, + CX_BGRA2Lab, CX_BGRA2Luv, CX_BGRA2XYZ, + CX_BGRA2YCrCb, CX_BGRA2YUV, + + CV_GRAY2BGR, CV_GRAY2BGR555, CV_GRAY2BGR565, CV_GRAY2BGRA, + + CV_HLS2BGR, CV_HLS2BGR_FULL, CV_HLS2RGB, CV_HLS2RGB_FULL, + CX_HLS2BGRA, CX_HLS2BGRA_FULL, CX_HLS2RGBA, CX_HLS2RGBA_FULL, + + CV_HSV2BGR, CV_HSV2BGR_FULL, CV_HSV2RGB, CV_HSV2RGB_FULL, + CX_HSV2BGRA, CX_HSV2BGRA_FULL, CX_HSV2RGBA, CX_HSV2RGBA_FULL, + + CV_Lab2BGR, CV_Lab2LBGR, CV_Lab2LRGB, CV_Lab2RGB, + CX_Lab2BGRA, CX_Lab2LBGRA, CX_Lab2LRGBA, CX_Lab2RGBA, + + CV_LBGR2Lab, CV_LBGR2Luv, CV_LRGB2Lab, CV_LRGB2Luv, + CX_LBGRA2Lab, CX_LBGRA2Luv, CX_LRGBA2Lab, CX_LRGBA2Luv, + + CV_Luv2BGR, CV_Luv2LBGR, CV_Luv2LRGB, CV_Luv2RGB, + CX_Luv2BGRA, CX_Luv2LBGRA, CX_Luv2LRGBA, CX_Luv2RGBA, + + CV_RGB2BGR555, CV_RGB2BGR565, CV_RGB2GRAY, + CV_RGB2HLS, CV_RGB2HLS_FULL, CV_RGB2HSV, CV_RGB2HSV_FULL, + CV_RGB2Lab, CV_RGB2Luv, CV_RGB2XYZ, CV_RGB2YCrCb, CV_RGB2YUV, + + CV_RGBA2BGR, CV_RGBA2BGR555, CV_RGBA2BGR565, CV_RGBA2GRAY, + CX_RGBA2HLS, CX_RGBA2HLS_FULL, CX_RGBA2HSV, CX_RGBA2HSV_FULL, + CX_RGBA2Lab, CX_RGBA2Luv, CX_RGBA2XYZ, + CX_RGBA2YCrCb, CX_RGBA2YUV, + + CV_XYZ2BGR, CV_XYZ2RGB, CX_XYZ2BGRA, CX_XYZ2RGBA, + + CV_YCrCb2BGR, CV_YCrCb2RGB, CX_YCrCb2BGRA, CX_YCrCb2RGBA, + CV_YUV2BGR, CV_YUV2RGB, CX_YUV2BGRA, CX_YUV2RGBA + ) + + +CV_ENUM(CvtModeBayer, + CV_BayerBG2BGR, CV_BayerBG2BGR_VNG, CV_BayerBG2GRAY, + CV_BayerGB2BGR, CV_BayerGB2BGR_VNG, CV_BayerGB2GRAY, + CV_BayerGR2BGR, CV_BayerGR2BGR_VNG, CV_BayerGR2GRAY, + CV_BayerRG2BGR, CV_BayerRG2BGR_VNG, CV_BayerRG2GRAY + ) + + +CV_ENUM(CvtMode2, CV_YUV2BGR_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGB_NV12, CV_YUV2RGBA_NV12, CV_YUV2BGR_NV21, CV_YUV2BGRA_NV21, CV_YUV2RGB_NV21, CV_YUV2RGBA_NV21, + CV_YUV2BGR_YV12, CV_YUV2BGRA_YV12, CV_YUV2RGB_YV12, CV_YUV2RGBA_YV12, CV_YUV2BGR_IYUV, CV_YUV2BGRA_IYUV, CV_YUV2RGB_IYUV, CV_YUV2RGBA_IYUV, + COLOR_YUV2GRAY_420, CV_YUV2RGB_UYVY, CV_YUV2BGR_UYVY, CV_YUV2RGBA_UYVY, CV_YUV2BGRA_UYVY, CV_YUV2RGB_YUY2, CV_YUV2BGR_YUY2, CV_YUV2RGB_YVYU, + CV_YUV2BGR_YVYU, CV_YUV2RGBA_YUY2, CV_YUV2BGRA_YUY2, CV_YUV2RGBA_YVYU, CV_YUV2BGRA_YVYU) + +CV_ENUM(CvtMode3, CV_RGB2YUV_IYUV, CV_BGR2YUV_IYUV, CV_RGBA2YUV_IYUV, CV_BGRA2YUV_IYUV, + CV_RGB2YUV_YV12, CV_BGR2YUV_YV12, CV_RGBA2YUV_YV12, CV_BGRA2YUV_YV12) + +struct ChPair +{ + ChPair(int _scn, int _dcn): scn(_scn), dcn(_dcn) {} + int scn, dcn; +}; + +ChPair getConversionInfo(int cvtMode) +{ + switch(cvtMode) + { + case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: + case CV_BayerGR2GRAY: case CV_BayerRG2GRAY: + case CV_YUV2GRAY_420: + return ChPair(1,1); + case CV_GRAY2BGR555: case CV_GRAY2BGR565: + return ChPair(1,2); + case CV_BayerBG2BGR: case CV_BayerBG2BGR_VNG: + case CV_BayerGB2BGR: case CV_BayerGB2BGR_VNG: + case CV_BayerGR2BGR: case CV_BayerGR2BGR_VNG: + case CV_BayerRG2BGR: case CV_BayerRG2BGR_VNG: + case CV_GRAY2BGR: + case CV_YUV2BGR_NV12: case CV_YUV2RGB_NV12: + case CV_YUV2BGR_NV21: case CV_YUV2RGB_NV21: + case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: + case CV_YUV2BGR_IYUV: case CV_YUV2RGB_IYUV: + return ChPair(1,3); + case CV_GRAY2BGRA: + case CV_YUV2BGRA_NV12: case CV_YUV2RGBA_NV12: + case CV_YUV2BGRA_NV21: case CV_YUV2RGBA_NV21: + case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12: + case CV_YUV2BGRA_IYUV: case CV_YUV2RGBA_IYUV: + return ChPair(1,4); + case CV_BGR5552GRAY: case CV_BGR5652GRAY: + return ChPair(2,1); + case CV_BGR5552BGR: case CV_BGR5552RGB: + case CV_BGR5652BGR: case CV_BGR5652RGB: + case CV_YUV2RGB_UYVY: case CV_YUV2BGR_UYVY: + case CV_YUV2RGBA_UYVY: case CV_YUV2BGRA_UYVY: + case CV_YUV2RGB_YUY2: case CV_YUV2BGR_YUY2: + case CV_YUV2RGB_YVYU: case CV_YUV2BGR_YVYU: + case CV_YUV2RGBA_YUY2: case CV_YUV2BGRA_YUY2: + case CV_YUV2RGBA_YVYU: case CV_YUV2BGRA_YVYU: + return ChPair(2,3); + case CV_BGR5552BGRA: case CV_BGR5552RGBA: + case CV_BGR5652BGRA: case CV_BGR5652RGBA: + return ChPair(2,4); + case CV_BGR2GRAY: case CV_RGB2GRAY: + case CV_RGB2YUV_IYUV: case CV_RGB2YUV_YV12: + case CV_BGR2YUV_IYUV: case CV_BGR2YUV_YV12: + return ChPair(3,1); + case CV_BGR2BGR555: case CV_BGR2BGR565: + case CV_RGB2BGR555: case CV_RGB2BGR565: + return ChPair(3,2); + case CV_BGR2HLS: case CV_BGR2HLS_FULL: + case CV_BGR2HSV: case CV_BGR2HSV_FULL: + case CV_BGR2Lab: case CV_BGR2Luv: + case CV_BGR2RGB: case CV_BGR2XYZ: + case CV_BGR2YCrCb: case CV_BGR2YUV: + case CV_HLS2BGR: case CV_HLS2BGR_FULL: + case CV_HLS2RGB: case CV_HLS2RGB_FULL: + case CV_HSV2BGR: case CV_HSV2BGR_FULL: + case CV_HSV2RGB: case CV_HSV2RGB_FULL: + case CV_Lab2BGR: case CV_Lab2LBGR: + case CV_Lab2LRGB: case CV_Lab2RGB: + case CV_LBGR2Lab: case CV_LBGR2Luv: + case CV_LRGB2Lab: case CV_LRGB2Luv: + case CV_Luv2BGR: case CV_Luv2LBGR: + case CV_Luv2LRGB: case CV_Luv2RGB: + case CV_RGB2HLS: case CV_RGB2HLS_FULL: + case CV_RGB2HSV: case CV_RGB2HSV_FULL: + case CV_RGB2Lab: case CV_RGB2Luv: + case CV_RGB2XYZ: case CV_RGB2YCrCb: + case CV_RGB2YUV: case CV_XYZ2BGR: + case CV_XYZ2RGB: case CV_YCrCb2BGR: + case CV_YCrCb2RGB: case CV_YUV2BGR: + case CV_YUV2RGB: + return ChPair(3,3); + case CV_BGR2BGRA: case CV_BGR2RGBA: + case CX_HLS2BGRA: case CX_HLS2BGRA_FULL: + case CX_HLS2RGBA: case CX_HLS2RGBA_FULL: + case CX_HSV2BGRA: case CX_HSV2BGRA_FULL: + case CX_HSV2RGBA: case CX_HSV2RGBA_FULL: + case CX_Lab2BGRA: case CX_Lab2LBGRA: + case CX_Lab2LRGBA: case CX_Lab2RGBA: + case CX_Luv2BGRA: case CX_Luv2LBGRA: + case CX_Luv2LRGBA: case CX_Luv2RGBA: + case CX_XYZ2BGRA: case CX_XYZ2RGBA: + case CX_YCrCb2BGRA: case CX_YCrCb2RGBA: + case CX_YUV2BGRA: case CX_YUV2RGBA: + return ChPair(3,4); + case CV_BGRA2GRAY: case CV_RGBA2GRAY: + case CV_RGBA2YUV_IYUV: case CV_RGBA2YUV_YV12: + case CV_BGRA2YUV_IYUV: case CV_BGRA2YUV_YV12: + return ChPair(4,1); + case CV_BGRA2BGR555: case CV_BGRA2BGR565: + case CV_RGBA2BGR555: case CV_RGBA2BGR565: + return ChPair(4,2); + case CV_BGRA2BGR: case CX_BGRA2HLS: + case CX_BGRA2HLS_FULL: case CX_BGRA2HSV: + case CX_BGRA2HSV_FULL: case CX_BGRA2Lab: + case CX_BGRA2Luv: case CX_BGRA2XYZ: + case CX_BGRA2YCrCb: case CX_BGRA2YUV: + case CX_LBGRA2Lab: case CX_LBGRA2Luv: + case CX_LRGBA2Lab: case CX_LRGBA2Luv: + case CV_RGBA2BGR: case CX_RGBA2HLS: + case CX_RGBA2HLS_FULL: case CX_RGBA2HSV: + case CX_RGBA2HSV_FULL: case CX_RGBA2Lab: + case CX_RGBA2Luv: case CX_RGBA2XYZ: + case CX_RGBA2YCrCb: case CX_RGBA2YUV: + return ChPair(4,3); + case CV_BGRA2RGBA: + return ChPair(4,4); + default: + ADD_FAILURE() << "Unknown conversion type"; + break; + }; + return ChPair(0,0); +} + +typedef std::tr1::tuple Size_CvtMode_t; +typedef perf::TestBaseWithParam Size_CvtMode; + +PERF_TEST_P(Size_CvtMode, cvtColor8u, + testing::Combine( + testing::Values(::perf::szODD, ::perf::szVGA, ::perf::sz1080p), + testing::ValuesIn(CvtMode::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int mode = get<1>(GetParam()); + ChPair ch = getConversionInfo(mode); + mode %= CV_COLORCVT_MAX; + + Mat src(sz, CV_8UC(ch.scn)); + Mat dst(sz, CV_8UC(ch.dcn)); + + declare.time(100); + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn); + + SANITY_CHECK(dst, 1); +} + +typedef std::tr1::tuple Size_CvtMode_Bayer_t; +typedef perf::TestBaseWithParam Size_CvtMode_Bayer; + +PERF_TEST_P(Size_CvtMode_Bayer, cvtColorBayer8u, + testing::Combine( + testing::Values(::perf::szODD, ::perf::szVGA), + testing::ValuesIn(CvtModeBayer::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int mode = get<1>(GetParam()); + ChPair ch = getConversionInfo(mode); + mode %= CV_COLORCVT_MAX; + + Mat src(sz, CV_8UC(ch.scn)); + Mat dst(sz, CV_8UC(ch.dcn)); + + declare.time(100); + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn); + + SANITY_CHECK(dst, 1); +} + +typedef std::tr1::tuple Size_CvtMode2_t; +typedef perf::TestBaseWithParam Size_CvtMode2; + +PERF_TEST_P(Size_CvtMode2, cvtColorYUV420, + testing::Combine( + testing::Values(szVGA, sz1080p, Size(130, 60)), + testing::ValuesIn(CvtMode2::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int mode = get<1>(GetParam()); + ChPair ch = getConversionInfo(mode); + + Mat src(sz.height + sz.height / 2, sz.width, CV_8UC(ch.scn)); + Mat dst(sz, CV_8UC(ch.dcn)); + + declare.in(src, WARMUP_RNG).out(dst); + + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) cvtColor(src, dst, mode, ch.dcn); + + SANITY_CHECK(dst, 1); +} + +typedef std::tr1::tuple Size_CvtMode3_t; +typedef perf::TestBaseWithParam Size_CvtMode3; + +PERF_TEST_P(Size_CvtMode3, cvtColorRGB2YUV420p, + testing::Combine( + testing::Values(szVGA, sz720p, sz1080p, Size(130, 60)), + testing::ValuesIn(CvtMode3::all()) + ) + ) +{ + Size sz = get<0>(GetParam()); + int mode = get<1>(GetParam()); + ChPair ch = getConversionInfo(mode); + + Mat src(sz, CV_8UC(ch.scn)); + Mat dst(sz.height + sz.height / 2, sz.width, CV_8UC(ch.dcn)); + + declare.time(100); + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn); + + SANITY_CHECK(dst, 1); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_distanceTransform.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_distanceTransform.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_distanceTransform.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_distanceTransform.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,23 @@ +/*#include "perf_precomp.hpp" +#include "distransform.cpp" + +using namespace std; +using namespace cv; +using namespace perf; + +typedef perf::TestBaseWithParam Size_DistanceTransform; + +PERF_TEST_P(Size_DistanceTransform, icvTrueDistTrans, testing::Values(TYPICAL_MAT_SIZES)) +{ + Size size = GetParam(); + Mat src(size, CV_8UC1); + Mat dst(size, CV_32FC1); + CvMat srcStub = src; + CvMat dstStub = dst; + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() icvTrueDistTrans(&srcStub, &dstStub); + + SANITY_CHECK(dst, 1); +}*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_filter2d.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_filter2d.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_filter2d.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_filter2d.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,76 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + + +CV_ENUM(BorderMode, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT_101); + +typedef TestBaseWithParam< tr1::tuple > TestFilter2d; +typedef TestBaseWithParam< tr1::tuple > Image_KernelSize; + +PERF_TEST_P( TestFilter2d, Filter2d, + Combine( + Values( Size(320, 240), sz1080p ), + Values( 3, 5 ), + ValuesIn( BorderMode::all() ) + ) +) +{ + Size sz; + int borderMode, kSize; + sz = get<0>(GetParam()); + kSize = get<1>(GetParam()); + borderMode = get<2>(GetParam()); + + Mat src(sz, CV_8UC4); + Mat dst(sz, CV_8UC4); + + Mat kernel(kSize, kSize, CV_32FC1); + randu(kernel, -3, 10); + double s = fabs( sum(kernel)[0] ); + if(s > 1e-3) kernel /= s; + + declare.in(src, WARMUP_RNG).out(dst).time(20); + + TEST_CYCLE() filter2D(src, dst, CV_8UC4, kernel, Point(1, 1), 0., borderMode); + + SANITY_CHECK(dst, 1); +} + +PERF_TEST_P( Image_KernelSize, GaborFilter2d, + Combine( + Values("stitching/a1.png", "cv/shared/pic5.png"), + Values(16, 32, 64) ) + ) +{ + String fileName = getDataPath(get<0>(GetParam())); + Mat sourceImage = imread(fileName, IMREAD_GRAYSCALE); + if( sourceImage.empty() ) + { + FAIL() << "Unable to load source image" << fileName; + } + + int kernelSize = get<1>(GetParam()); + double sigma = 4; + double lambda = 11; + double theta = 47; + double gamma = 0.5; + Mat gaborKernel = getGaborKernel(Size(kernelSize, kernelSize), sigma, theta, lambda, gamma); + Mat filteredImage; + + declare.in(sourceImage); + + TEST_CYCLE() + { + filter2D(sourceImage, filteredImage, CV_32F, gaborKernel); + } + + SANITY_CHECK(filteredImage, 1e-3); +} + + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_goodFeaturesToTrack.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_goodFeaturesToTrack.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_goodFeaturesToTrack.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_goodFeaturesToTrack.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,41 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Image_MaxCorners_QualityLevel_MinDistance_BlockSize_UseHarris_t; +typedef perf::TestBaseWithParam Image_MaxCorners_QualityLevel_MinDistance_BlockSize_UseHarris; + +PERF_TEST_P(Image_MaxCorners_QualityLevel_MinDistance_BlockSize_UseHarris, goodFeaturesToTrack, + testing::Combine( + testing::Values( "stitching/a1.png", "cv/shared/pic5.png"), + testing::Values( 100, 500 ), + testing::Values( 0.1, 0.01 ), + testing::Values( 3, 5 ), + testing::Bool() + ) + ) +{ + String filename = getDataPath(get<0>(GetParam())); + int maxCorners = get<1>(GetParam()); + double qualityLevel = get<2>(GetParam()); + int blockSize = get<3>(GetParam()); + bool useHarrisDetector = get<4>(GetParam()); + + Mat image = imread(filename, IMREAD_GRAYSCALE); + if (image.empty()) + FAIL() << "Unable to load source image" << filename; + + std::vector corners; + + double minDistance = 1; + TEST_CYCLE() goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, noArray(), blockSize, useHarrisDetector); + + if (corners.size() > 50) + corners.erase(corners.begin() + 50, corners.end()); + + SANITY_CHECK(corners); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_histogram.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_histogram.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_histogram.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_histogram.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,139 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef tr1::tuple Size_Source_t; +typedef TestBaseWithParam Size_Source; +typedef TestBaseWithParam MatSize; + +static const float rangeHight = 256.0f; +static const float rangeLow = 0.0f; + +PERF_TEST_P(Size_Source, calcHist1d, + testing::Combine(testing::Values(sz3MP, sz5MP), + testing::Values(CV_8U, CV_16U, CV_32F) ) + ) +{ + Size size = get<0>(GetParam()); + MatType type = get<1>(GetParam()); + Mat source(size.height, size.width, type); + Mat hist; + int channels [] = {0}; + int histSize [] = {256}; + int dims = 1; + int numberOfImages = 1; + + const float r[] = {rangeLow, rangeHight}; + const float* ranges[] = {r}; + + randu(source, rangeLow, rangeHight); + + declare.in(source); + + TEST_CYCLE() + { + calcHist(&source, numberOfImages, channels, Mat(), hist, dims, histSize, ranges); + } + + SANITY_CHECK(hist); +} + +PERF_TEST_P(Size_Source, calcHist2d, + testing::Combine(testing::Values(sz3MP, sz5MP), + testing::Values(CV_8UC2, CV_16UC2, CV_32FC2) ) + ) +{ + Size size = get<0>(GetParam()); + MatType type = get<1>(GetParam()); + Mat source(size.height, size.width, type); + Mat hist; + int channels [] = {0, 1}; + int histSize [] = {256, 256}; + int dims = 2; + int numberOfImages = 1; + + const float r[] = {rangeLow, rangeHight}; + const float* ranges[] = {r, r}; + + randu(source, rangeLow, rangeHight); + + declare.in(source); + TEST_CYCLE() + { + calcHist(&source, numberOfImages, channels, Mat(), hist, dims, histSize, ranges); + } + + SANITY_CHECK(hist); +} + +PERF_TEST_P(Size_Source, calcHist3d, + testing::Combine(testing::Values(sz3MP, sz5MP), + testing::Values(CV_8UC3, CV_16UC3, CV_32FC3) ) + ) +{ + Size size = get<0>(GetParam()); + MatType type = get<1>(GetParam()); + Mat hist; + int channels [] = {0, 1, 2}; + int histSize [] = {32, 32, 32}; + int dims = 3; + int numberOfImages = 1; + Mat source(size.height, size.width, type); + + const float r[] = {rangeLow, rangeHight}; + const float* ranges[] = {r, r, r}; + + randu(source, rangeLow, rangeHight); + + declare.in(source); + TEST_CYCLE() + { + calcHist(&source, numberOfImages, channels, Mat(), hist, dims, histSize, ranges); + } + + SANITY_CHECK(hist); +} + +PERF_TEST_P(MatSize, equalizeHist, + testing::Values(TYPICAL_MAT_SIZES) + ) +{ + Size size = GetParam(); + Mat source(size.height, size.width, CV_8U); + Mat destination; + declare.in(source, WARMUP_RNG); + + TEST_CYCLE() + { + equalizeHist(source, destination); + } + + SANITY_CHECK(destination); +} + +typedef tr1::tuple Sz_ClipLimit_t; +typedef TestBaseWithParam Sz_ClipLimit; + +PERF_TEST_P(Sz_ClipLimit, CLAHE, + testing::Combine(testing::Values(::perf::szVGA, ::perf::sz720p, ::perf::sz1080p), + testing::Values(0.0, 40.0)) + ) +{ + const Size size = get<0>(GetParam()); + const double clipLimit = get<1>(GetParam()); + + Mat src(size, CV_8UC1); + declare.in(src, WARMUP_RNG); + + Ptr clahe = createCLAHE(clipLimit); + Mat dst; + + TEST_CYCLE() clahe->apply(src, dst); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_houghLines.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_houghLines.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_houghLines.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_houghLines.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,40 @@ +#include "perf_precomp.hpp" + +#include "cmath" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Image_RhoStep_ThetaStep_Threshold_t; +typedef perf::TestBaseWithParam Image_RhoStep_ThetaStep_Threshold; + +PERF_TEST_P(Image_RhoStep_ThetaStep_Threshold, HoughLines, + testing::Combine( + testing::Values( "cv/shared/pic5.png", "stitching/a1.png" ), + testing::Values( 1, 10 ), + testing::Values( 0.01, 0.1 ), + testing::Values( 300, 500 ) + ) + ) +{ + String filename = getDataPath(get<0>(GetParam())); + double rhoStep = get<1>(GetParam()); + double thetaStep = get<2>(GetParam()); + int threshold = get<3>(GetParam()); + + Mat image = imread(filename, IMREAD_GRAYSCALE); + if (image.empty()) + FAIL() << "Unable to load source image" << filename; + + Canny(image, image, 0, 0); + + Mat lines; + declare.time(60); + + TEST_CYCLE() HoughLines(image, lines, rhoStep, thetaStep, threshold); + + SANITY_CHECK(lines); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_integral.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_integral.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_integral.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_integral.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,84 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Size_MatType_OutMatDepth_t; +typedef perf::TestBaseWithParam Size_MatType_OutMatDepth; + +PERF_TEST_P(Size_MatType_OutMatDepth, integral, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(CV_8UC1, CV_8UC4), + testing::Values(CV_32S, CV_32F, CV_64F) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int sdepth = get<2>(GetParam()); + + Mat src(sz, matType); + Mat sum(sz, sdepth); + + declare.in(src, WARMUP_RNG).out(sum); + + TEST_CYCLE() integral(src, sum, sdepth); + + SANITY_CHECK(sum, 1e-6); +} + +PERF_TEST_P(Size_MatType_OutMatDepth, integral_sqsum, + testing::Combine( + testing::Values(::perf::szVGA, ::perf::sz1080p), + testing::Values(CV_8UC1, CV_8UC4), + testing::Values(CV_32S, CV_32F) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int sdepth = get<2>(GetParam()); + + Mat src(sz, matType); + Mat sum(sz, sdepth); + Mat sqsum(sz, sdepth); + + declare.in(src, WARMUP_RNG).out(sum, sqsum); + declare.time(100); + + TEST_CYCLE() integral(src, sum, sqsum, sdepth); + + SANITY_CHECK(sum, 1e-6); + SANITY_CHECK(sqsum, 1e-6); +} + +PERF_TEST_P( Size_MatType_OutMatDepth, integral_sqsum_tilted, + testing::Combine( + testing::Values( ::perf::szVGA, ::perf::szODD , ::perf::sz1080p ), + testing::Values( CV_8UC1, CV_8UC4 ), + testing::Values( CV_32S, CV_32F ) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + int sdepth = get<2>(GetParam()); + + Mat src(sz, matType); + Mat sum(sz, sdepth); + Mat sqsum(sz, sdepth); + Mat tilted(sz, sdepth); + + declare.in(src, WARMUP_RNG).out(sum, sqsum, tilted); + declare.time(100); + + TEST_CYCLE() integral(src, sum, sqsum, tilted, sdepth); + + SANITY_CHECK(sum, 1e-6); + SANITY_CHECK(sqsum, 1e-6); + SANITY_CHECK(tilted, 1e-6, tilted.depth() > CV_32S ? ERROR_RELATIVE : ERROR_ABSOLUTE); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_main.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_main.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3 @@ +#include "perf_precomp.hpp" + +CV_PERF_TEST_MAIN(imgproc) diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_matchTemplate.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_matchTemplate.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_matchTemplate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_matchTemplate.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,83 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(MethodType, CV_TM_SQDIFF, CV_TM_SQDIFF_NORMED, CV_TM_CCORR, CV_TM_CCORR_NORMED, CV_TM_CCOEFF, CV_TM_CCOEFF_NORMED) + +typedef std::tr1::tuple ImgSize_TmplSize_Method_t; +typedef perf::TestBaseWithParam ImgSize_TmplSize_Method; + +PERF_TEST_P(ImgSize_TmplSize_Method, matchTemplateSmall, + testing::Combine( + testing::Values(szSmall128, cv::Size(320, 240), + cv::Size(640, 480), cv::Size(800, 600), + cv::Size(1024, 768), cv::Size(1280, 1024)), + testing::Values(cv::Size(12, 12), cv::Size(28, 9), + cv::Size(8, 30), cv::Size(16, 16)), + testing::ValuesIn(MethodType::all()) + ) + ) +{ + Size imgSz = get<0>(GetParam()); + Size tmplSz = get<1>(GetParam()); + int method = get<2>(GetParam()); + + Mat img(imgSz, CV_8UC1); + Mat tmpl(tmplSz, CV_8UC1); + Mat result(imgSz - tmplSz + Size(1,1), CV_32F); + + declare + .in(img, WARMUP_RNG) + .in(tmpl, WARMUP_RNG) + .out(result) + .time(30); + + TEST_CYCLE() matchTemplate(img, tmpl, result, method); + + bool isNormed = + method == CV_TM_CCORR_NORMED || + method == CV_TM_SQDIFF_NORMED || + method == CV_TM_CCOEFF_NORMED; + double eps = isNormed ? 1e-6 + : 255 * 255 * tmpl.total() * 1e-6; + + SANITY_CHECK(result, eps); +} + +PERF_TEST_P(ImgSize_TmplSize_Method, matchTemplateBig, + testing::Combine( + testing::Values(cv::Size(1280, 1024)), + testing::Values(cv::Size(1260, 1000), cv::Size(1261, 1013)), + testing::ValuesIn(MethodType::all()) + ) + ) +{ + Size imgSz = get<0>(GetParam()); + Size tmplSz = get<1>(GetParam()); + int method = get<2>(GetParam()); + + Mat img(imgSz, CV_8UC1); + Mat tmpl(tmplSz, CV_8UC1); + Mat result(imgSz - tmplSz + Size(1,1), CV_32F); + + declare + .in(img, WARMUP_RNG) + .in(tmpl, WARMUP_RNG) + .out(result) + .time(30); + + TEST_CYCLE() matchTemplate(img, tmpl, result, method); + + bool isNormed = + method == CV_TM_CCORR_NORMED || + method == CV_TM_SQDIFF_NORMED || + method == CV_TM_CCOEFF_NORMED; + double eps = isNormed ? 1e-6 + : 255 * 255 * tmpl.total() * 1e-6; + + SANITY_CHECK(result, eps); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_morph.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_morph.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_morph.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_morph.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,40 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_TYPES_MORPH CV_8UC1, CV_8UC4 +#define TYPICAL_MATS_MORPH testing::Combine(SZ_ALL_GA, testing::Values(TYPICAL_MAT_TYPES_MORPH)) + +PERF_TEST_P(Size_MatType, erode, TYPICAL_MATS_MORPH) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() erode(src, dst, noArray()); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType, dilate, TYPICAL_MATS_MORPH) +{ + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() dilate(src, dst, noArray()); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_precomp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "perf_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_precomp.hpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,20 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_PERF_PRECOMP_HPP__ +#define __OPENCV_PERF_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" + +#ifdef GTEST_CREATE_SHARED_LIBRARY +#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_pyramids.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_pyramids.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_pyramids.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_pyramids.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,45 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +PERF_TEST_P(Size_MatType, pyrDown, testing::Combine( + testing::Values(sz1080p, sz720p, szVGA, szQVGA, szODD), + testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3, CV_16SC4) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + Mat dst((sz.height + 1)/2, (sz.width + 1)/2, matType); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() pyrDown(src, dst); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType, pyrUp, testing::Combine( + testing::Values(sz720p, szVGA, szQVGA, szODD), + testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3, CV_16SC4) + ) + ) +{ + Size sz = get<0>(GetParam()); + int matType = get<1>(GetParam()); + + Mat src(sz, matType); + Mat dst(sz.height*2, sz.width*2, matType); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() pyrUp(src, dst); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_remap.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_remap.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_remap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_remap.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,69 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(InterType, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_LANCZOS4) + +typedef TestBaseWithParam< tr1::tuple > TestRemap; + +PERF_TEST_P( TestRemap, Remap, + Combine( + Values( szVGA, sz1080p ), + Values( CV_16UC1, CV_16SC1, CV_32FC1 ), + Values( CV_16SC2, CV_32FC1, CV_32FC2 ), + ValuesIn( InterType::all() ) + ) +) +{ + Size sz; + int src_type, map1_type, inter_type; + + sz = get<0>(GetParam()); + src_type = get<1>(GetParam()); + map1_type = get<2>(GetParam()); + inter_type = get<3>(GetParam()); + + Mat src(sz, src_type), dst(sz, src_type), map1(sz, map1_type), map2; + if (map1_type == CV_32FC1) + map2.create(sz, CV_32FC1); + else if (inter_type != INTER_NEAREST && map1_type == CV_16SC2) + { + map2.create(sz, CV_16UC1); + map2 = Scalar::all(0); + } + + RNG rng; + rng.fill(src, RNG::UNIFORM, 0, 256); + + for (int j = 0; j < map1.rows; ++j) + for (int i = 0; i < map1.cols; ++i) + switch (map1_type) + { + case CV_32FC1: + map1.at(j, i) = static_cast(src.cols - i - 1); + map2.at(j, i) = static_cast(j); + break; + case CV_32FC2: + map1.at(j, i)[0] = static_cast(src.cols - i - 1); + map1.at(j, i)[1] = static_cast(j); + break; + case CV_16SC2: + map1.at(j, i)[0] = static_cast(src.cols - i - 1); + map1.at(j, i)[1] = static_cast(j); + break; + default: + CV_Assert(0); + } + + + declare.in(src, WARMUP_RNG).out(dst).time(20); + + TEST_CYCLE() remap(src, dst, map1, map2, inter_type); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_resize.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_resize.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_resize.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_resize.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,121 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef tr1::tuple MatInfo_Size_Size_t; +typedef TestBaseWithParam MatInfo_Size_Size; + +PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear, + testing::Values( + MatInfo_Size_Size_t(CV_8UC1, szVGA, szqHD), + MatInfo_Size_Size_t(CV_8UC1, szVGA, sz720p), + MatInfo_Size_Size_t(CV_8UC4, szVGA, sz720p) + ) + ) +{ + int matType = get<0>(GetParam()); + Size from = get<1>(GetParam()); + Size to = get<2>(GetParam()); + + cv::Mat src(from, matType), dst(to, matType); + cvtest::fillGradient(src); + declare.in(src).out(dst); + + TEST_CYCLE() resize(src, dst, to); + +#ifdef ANDROID + SANITY_CHECK(dst, 5); +#else + SANITY_CHECK(dst, 1 + 1e-6); +#endif +} + +PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear, + testing::Values( + MatInfo_Size_Size_t(CV_8UC1, szVGA, szQVGA), + MatInfo_Size_Size_t(CV_8UC4, szqHD, szVGA), + MatInfo_Size_Size_t(CV_8UC1, sz720p, Size(120 * sz720p.width / sz720p.height, 120)),//face detection min_face_size = 20% + MatInfo_Size_Size_t(CV_8UC4, sz720p, szVGA), + MatInfo_Size_Size_t(CV_8UC4, sz720p, szQVGA) + ) + ) +{ + int matType = get<0>(GetParam()); + Size from = get<1>(GetParam()); + Size to = get<2>(GetParam()); + + cv::Mat src(from, matType), dst(to, matType); + cvtest::fillGradient(src); + declare.in(src).out(dst); + + TEST_CYCLE() resize(src, dst, to); + +#ifdef ANDROID + SANITY_CHECK(dst, 5); +#else + SANITY_CHECK(dst, 1 + 1e-6); +#endif +} + + +typedef tr1::tuple MatInfo_Size_Scale_t; +typedef TestBaseWithParam MatInfo_Size_Scale; + +PERF_TEST_P(MatInfo_Size_Scale, ResizeAreaFast, + testing::Combine( + testing::Values(CV_8UC1, CV_8UC4), + testing::Values(szVGA, szqHD, sz720p, sz1080p), + testing::Values(2) + ) + ) +{ + int matType = get<0>(GetParam()); + Size from = get<1>(GetParam()); + int scale = get<2>(GetParam()); + + from.width = (from.width/scale)*scale; + from.height = (from.height/scale)*scale; + + cv::Mat src(from, matType); + cv::Mat dst(from.height / scale, from.width / scale, matType); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() resize(src, dst, dst.size(), 0, 0, INTER_AREA); + + //difference equal to 1 is allowed because of different possible rounding modes: round-to-nearest vs bankers' rounding + SANITY_CHECK(dst, 1); +} + + +typedef TestBaseWithParam > MatInfo_Size_Scale_Area; + +PERF_TEST_P(MatInfo_Size_Scale_Area, ResizeArea, + testing::Combine( + testing::Values(CV_8UC1, CV_8UC4), + testing::Values(szVGA, szqHD, sz720p), + testing::Values(2.4, 3.4, 1.3) + ) + ) +{ + int matType = get<0>(GetParam()); + Size from = get<1>(GetParam()); + double scale = get<2>(GetParam()); + + cv::Mat src(from, matType); + + Size to(cvRound(from.width * scale), cvRound(from.height * scale)); + cv::Mat dst(to, matType); + + declare.in(src, WARMUP_RNG).out(dst); + declare.time(100); + + TEST_CYCLE() resize(src, dst, dst.size(), 0, 0, INTER_AREA); + + //difference equal to 1 is allowed because of different possible rounding modes: round-to-nearest vs bankers' rounding + SANITY_CHECK(dst, 1); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_sepfilters.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_sepfilters.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_sepfilters.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_sepfilters.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,244 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +#define FILTER_SRC_SIZES szODD, szQVGA, szVGA + +CV_ENUM(BorderType3x3, BORDER_REPLICATE, BORDER_CONSTANT) +CV_ENUM(BorderType3x3ROI, BORDER_DEFAULT, BORDER_REPLICATE|BORDER_ISOLATED, BORDER_CONSTANT|BORDER_ISOLATED) + +CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT101) +CV_ENUM(BorderTypeROI, BORDER_DEFAULT, BORDER_REPLICATE|BORDER_ISOLATED, BORDER_CONSTANT|BORDER_ISOLATED, BORDER_REFLECT|BORDER_ISOLATED, BORDER_REFLECT101|BORDER_ISOLATED) + +typedef std::tr1::tuple, BorderType3x3> Size_MatType_dx_dy_Border3x3_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border3x3; + +typedef std::tr1::tuple, BorderType3x3ROI> Size_MatType_dx_dy_Border3x3ROI_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border3x3ROI; + +typedef std::tr1::tuple, BorderType> Size_MatType_dx_dy_Border5x5_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border5x5; + +typedef std::tr1::tuple, BorderTypeROI> Size_MatType_dx_dy_Border5x5ROI_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border5x5ROI; + + +/**************** Sobel ********************/ + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0), make_tuple(2, 2)), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, 3, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0), make_tuple(2, 2)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, 3, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border5x5, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0)), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, 5, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border5x5ROI, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0)), + testing::ValuesIn(BorderTypeROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderTypeROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, 5, 1, 0, border); + + SANITY_CHECK(dst); +} + +/**************** Scharr ********************/ + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, scharrFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() Scharr(src, dst, ddepth, dx, dy, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, scharrFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE() Scharr(src, dst, ddepth, dx, dy, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, scharrViaSobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, -1, 1, 0, border); + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, scharrViaSobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE() Sobel(src, dst, ddepth, dx, dy, -1, 1, 0, border); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_threshold.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_threshold.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_threshold.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_threshold.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,91 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(ThreshType, THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV) + +typedef std::tr1::tuple Size_MatType_ThreshType_t; +typedef perf::TestBaseWithParam Size_MatType_ThreshType; + +PERF_TEST_P(Size_MatType_ThreshType, threshold, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::Values(CV_8UC1, CV_16SC1), + testing::ValuesIn(ThreshType::all()) + ) + ) +{ + + Size sz = get<0>(GetParam()); + int type = get<1>(GetParam()); + ThreshType threshType = get<2>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + double thresh = theRNG().uniform(1, 254); + double maxval = theRNG().uniform(1, 254); + + declare.in(src, WARMUP_RNG).out(dst); + + int runs = (sz.width <= 640) ? 8 : 1; + TEST_CYCLE_MULTIRUN(runs) threshold(src, dst, thresh, maxval, threshType); + + SANITY_CHECK(dst); +} + +typedef perf::TestBaseWithParam Size_Only; + +PERF_TEST_P(Size_Only, threshold_otsu, testing::Values(TYPICAL_MAT_SIZES)) +{ + Size sz = GetParam(); + + Mat src(sz, CV_8UC1); + Mat dst(sz, CV_8UC1); + + double maxval = theRNG().uniform(1, 254); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() threshold(src, dst, 0, maxval, THRESH_BINARY|THRESH_OTSU); + + SANITY_CHECK(dst); +} + +CV_ENUM(AdaptThreshType, THRESH_BINARY, THRESH_BINARY_INV) +CV_ENUM(AdaptThreshMethod, ADAPTIVE_THRESH_MEAN_C, ADAPTIVE_THRESH_GAUSSIAN_C) + +typedef std::tr1::tuple Size_AdaptThreshType_AdaptThreshMethod_BlockSize_t; +typedef perf::TestBaseWithParam Size_AdaptThreshType_AdaptThreshMethod_BlockSize; + +PERF_TEST_P(Size_AdaptThreshType_AdaptThreshMethod_BlockSize, adaptiveThreshold, + testing::Combine( + testing::Values(TYPICAL_MAT_SIZES), + testing::ValuesIn(AdaptThreshType::all()), + testing::ValuesIn(AdaptThreshMethod::all()), + testing::Values(3, 5) + ) + ) +{ + Size sz = get<0>(GetParam()); + AdaptThreshType adaptThreshType = get<1>(GetParam()); + AdaptThreshMethod adaptThreshMethod = get<2>(GetParam()); + int blockSize = get<3>(GetParam()); + + double maxValue = theRNG().uniform(1, 254); + double C = 10.0; + + int type = CV_8UC1; + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE() adaptiveThreshold(src, dst, maxValue, adaptThreshMethod, adaptThreshType, blockSize, C); + + SANITY_CHECK(dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_warp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_warp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/perf/perf_warp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/perf/perf_warp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,224 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + +enum{HALF_SIZE=0, UPSIDE_DOWN, REFLECTION_X, REFLECTION_BOTH}; + +CV_ENUM(BorderMode, BORDER_CONSTANT, BORDER_REPLICATE) +CV_ENUM(InterType, INTER_NEAREST, INTER_LINEAR) +CV_ENUM(RemapMode, HALF_SIZE, UPSIDE_DOWN, REFLECTION_X, REFLECTION_BOTH) + +typedef TestBaseWithParam< tr1::tuple > TestWarpAffine; +typedef TestBaseWithParam< tr1::tuple > TestWarpPerspective; +typedef TestBaseWithParam< tr1::tuple > TestWarpPerspectiveNear_t; +typedef TestBaseWithParam< tr1::tuple > TestRemap; + +void update_map(const Mat& src, Mat& map_x, Mat& map_y, const int remapMode ); + +PERF_TEST_P( TestWarpAffine, WarpAffine, + Combine( + Values( szVGA, sz720p, sz1080p ), + ValuesIn( InterType::all() ), + ValuesIn( BorderMode::all() ) + ) +) +{ + Size sz, szSrc(512, 512); + int borderMode, interType; + sz = get<0>(GetParam()); + interType = get<1>(GetParam()); + borderMode = get<2>(GetParam()); + Scalar borderColor = Scalar::all(150); + + Mat src(szSrc,CV_8UC4), dst(sz, CV_8UC4); + cvtest::fillGradient(src); + if(borderMode == BORDER_CONSTANT) cvtest::smoothBorder(src, borderColor, 1); + Mat warpMat = getRotationMatrix2D(Point2f(src.cols/2.f, src.rows/2.f), 30., 2.2); + declare.in(src).out(dst); + + TEST_CYCLE() warpAffine( src, dst, warpMat, sz, interType, borderMode, borderColor ); + +#ifdef ANDROID + SANITY_CHECK(dst, interType==INTER_LINEAR? 5 : 10); +#else + SANITY_CHECK(dst, 1); +#endif +} + +PERF_TEST_P( TestWarpPerspective, WarpPerspective, + Combine( + Values( szVGA, sz720p, sz1080p ), + ValuesIn( InterType::all() ), + ValuesIn( BorderMode::all() ) + ) +) +{ + Size sz, szSrc(512, 512); + int borderMode, interType; + sz = get<0>(GetParam()); + interType = get<1>(GetParam()); + borderMode = get<2>(GetParam()); + Scalar borderColor = Scalar::all(150); + + Mat src(szSrc,CV_8UC4), dst(sz, CV_8UC4); + cvtest::fillGradient(src); + if(borderMode == BORDER_CONSTANT) cvtest::smoothBorder(src, borderColor, 1); + Mat rotMat = getRotationMatrix2D(Point2f(src.cols/2.f, src.rows/2.f), 30., 2.2); + Mat warpMat(3, 3, CV_64FC1); + for(int r=0; r<2; r++) + for(int c=0; c<3; c++) + warpMat.at(r, c) = rotMat.at(r, c); + warpMat.at(2, 0) = .3/sz.width; + warpMat.at(2, 1) = .3/sz.height; + warpMat.at(2, 2) = 1; + + declare.in(src).out(dst); + + TEST_CYCLE() warpPerspective( src, dst, warpMat, sz, interType, borderMode, borderColor ); + +#ifdef ANDROID + SANITY_CHECK(dst, interType==INTER_LINEAR? 5 : 10); +#else + SANITY_CHECK(dst, 1); +#endif +} + +PERF_TEST_P( TestWarpPerspectiveNear_t, WarpPerspectiveNear, + Combine( + Values( Size(640,480), Size(1920,1080), Size(2592,1944) ), + ValuesIn( InterType::all() ), + ValuesIn( BorderMode::all() ), + Values( CV_8UC1, CV_8UC4 ) + ) + ) +{ + Size size; + int borderMode, interType, type; + size = get<0>(GetParam()); + interType = get<1>(GetParam()); + borderMode = get<2>(GetParam()); + type = get<3>(GetParam()); + Scalar borderColor = Scalar::all(150); + + Mat src(size, type), dst(size, type); + cvtest::fillGradient(src); + if(borderMode == BORDER_CONSTANT) cvtest::smoothBorder(src, borderColor, 1); + int shift = static_cast(src.cols*0.04); + Mat srcVertices = (Mat_(1, 4) << Vec2f(0, 0), + Vec2f(static_cast(size.width-1), 0), + Vec2f(static_cast(size.width-1), static_cast(size.height-1)), + Vec2f(0, static_cast(size.height-1))); + Mat dstVertices = (Mat_(1, 4) << Vec2f(0, static_cast(shift)), + Vec2f(static_cast(size.width-shift/2), 0), + Vec2f(static_cast(size.width-shift), static_cast(size.height-shift)), + Vec2f(static_cast(shift/2), static_cast(size.height-1))); + Mat warpMat = getPerspectiveTransform(srcVertices, dstVertices); + + declare.in(src).out(dst); + declare.time(100); + + TEST_CYCLE() + { + warpPerspective( src, dst, warpMat, size, interType, borderMode, borderColor ); + } + +#ifdef ANDROID + SANITY_CHECK(dst, interType==INTER_LINEAR? 5 : 10); +#else + SANITY_CHECK(dst, 1); +#endif +} + +PERF_TEST_P( TestRemap, remap, + Combine( + Values( TYPICAL_MAT_TYPES ), + Values( szVGA, sz720p, sz1080p ), + ValuesIn( InterType::all() ), + ValuesIn( BorderMode::all() ), + ValuesIn( RemapMode::all() ) + ) + ) +{ + int type = get<0>(GetParam()); + Size size = get<1>(GetParam()); + int interpolationType = get<2>(GetParam()); + int borderMode = get<3>(GetParam()); + int remapMode = get<4>(GetParam()); + unsigned int height = size.height; + unsigned int width = size.width; + Mat source(height, width, type); + Mat destination; + Mat map_x(height, width, CV_32F); + Mat map_y(height, width, CV_32F); + + declare.in(source, WARMUP_RNG); + + update_map(source, map_x, map_y, remapMode); + + TEST_CYCLE() + { + remap(source, destination, map_x, map_y, interpolationType, borderMode); + } + + SANITY_CHECK(destination, 1); +} + +void update_map(const Mat& src, Mat& map_x, Mat& map_y, const int remapMode ) +{ + for( int j = 0; j < src.rows; j++ ) + { + for( int i = 0; i < src.cols; i++ ) + { + switch( remapMode ) + { + case HALF_SIZE: + if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ) + { + map_x.at(j,i) = 2*( i - src.cols*0.25f ) + 0.5f ; + map_y.at(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ; + } + else + { + map_x.at(j,i) = 0 ; + map_y.at(j,i) = 0 ; + } + break; + case UPSIDE_DOWN: + map_x.at(j,i) = static_cast(i) ; + map_y.at(j,i) = static_cast(src.rows - j) ; + break; + case REFLECTION_X: + map_x.at(j,i) = static_cast(src.cols - i) ; + map_y.at(j,i) = static_cast(j) ; + break; + case REFLECTION_BOTH: + map_x.at(j,i) = static_cast(src.cols - i) ; + map_y.at(j,i) = static_cast(src.rows - j) ; + break; + } // end of switch + } + } +} + +PERF_TEST(Transform, getPerspectiveTransform) +{ + unsigned int size = 8; + Mat source(1, size/2, CV_32FC2); + Mat destination(1, size/2, CV_32FC2); + Mat transformCoefficient; + + declare.in(source, destination, WARMUP_RNG); + + TEST_CYCLE() + { + transformCoefficient = getPerspectiveTransform(source, destination); + } + + SANITY_CHECK(transformCoefficient, 1e-5); +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/_geom.h diffimg-2.0.0/3rdparty/opencv/imgproc/src/_geom.h --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/_geom.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/_geom.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,72 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _CV_GEOM_H_ +#define _CV_GEOM_H_ + +/* Finds distance between two points */ +CV_INLINE float icvDistanceL2_32f( CvPoint2D32f pt1, CvPoint2D32f pt2 ) +{ + float dx = pt2.x - pt1.x; + float dy = pt2.y - pt1.y; + + return std::sqrt( dx*dx + dy*dy ); +} + + +int icvIntersectLines( double x1, double dx1, double y1, double dy1, + double x2, double dx2, double y2, double dy2, + double* t2 ); + + +void icvCreateCenterNormalLine( CvSubdiv2DEdge edge, double* a, double* b, double* c ); + +void icvIntersectLines3( double* a0, double* b0, double* c0, + double* a1, double* b1, double* c1, + CvPoint2D32f* point ); + + +/* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */ +CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, CvMemStorage* storage, int method ); + +#endif /*_IPCVGEOM_H_*/ + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/_list.h diffimg-2.0.0/3rdparty/opencv/imgproc/src/_list.h --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/_list.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/_list.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,374 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _CV_LIST_H_ +#define _CV_LIST_H_ + +#include +#include + +#define CV_FORCE_INLINE CV_INLINE + +#if !defined(_LIST_INLINE) +#define _LIST_INLINE CV_FORCE_INLINE +#endif /*_LIST_INLINE*/ + +#if defined DECLARE_LIST +#if defined _MSC_VER && _MSC_VER >= 1200 + #pragma warning("DECLARE_LIST macro is already defined!") +#endif +#endif /*DECLARE_LIST*/ + +static const long default_size = 10; +static const long default_inc_size = 10; + +struct _pos +{ + void* m_pos; +#ifdef _DEBUG + struct _list* m_list; +#endif /*_DEBUG*/ +}; +typedef struct _pos CVPOS; +struct _list +{ + void* m_buffer; + void* m_first_buffer; + long m_buf_size; /* The size of the buffer */ + long m_size; /* The number of elements */ + CVPOS m_head; + CVPOS m_tail; + CVPOS m_head_free; +}; + +typedef struct _list _CVLIST; + +#define DECLARE_LIST(type, prefix)\ + /* Basic element of a list*/\ + struct prefix##element_##type\ + {\ + struct prefix##element_##type* m_prev;\ + struct prefix##element_##type* m_next;\ + type m_data;\ + };\ + typedef struct prefix##element_##type ELEMENT_##type;\ + /* Initialization and destruction*/\ + _LIST_INLINE _CVLIST* prefix##create_list_##type(long);\ + _LIST_INLINE void prefix##destroy_list_##type(_CVLIST*);\ + /* Access functions*/\ + _LIST_INLINE CVPOS prefix##get_head_pos_##type(_CVLIST*);\ + _LIST_INLINE CVPOS prefix##get_tail_pos_##type(_CVLIST*);\ + _LIST_INLINE type* prefix##get_next_##type(CVPOS*);\ + _LIST_INLINE type* prefix##get_prev_##type(CVPOS*);\ + _LIST_INLINE int prefix##is_pos_##type(CVPOS pos);\ + /* Modification functions*/\ + _LIST_INLINE void prefix##clear_list_##type(_CVLIST*);\ + _LIST_INLINE CVPOS prefix##add_head_##type(_CVLIST*, type*);\ + _LIST_INLINE CVPOS prefix##add_tail_##type(_CVLIST*, type*);\ + _LIST_INLINE void prefix##remove_head_##type(_CVLIST*);\ + _LIST_INLINE void prefix##remove_tail_##type(_CVLIST*);\ + _LIST_INLINE CVPOS prefix##insert_before_##type(_CVLIST*, CVPOS, type*);\ + _LIST_INLINE CVPOS prefix##insert_after_##type(_CVLIST*, CVPOS, type*);\ + _LIST_INLINE void prefix##remove_at_##type(_CVLIST*, CVPOS);\ + _LIST_INLINE void prefix##set_##type(CVPOS, type*);\ + _LIST_INLINE type* prefix##get_##type(CVPOS);\ + /* Statistics functions*/\ + _LIST_INLINE int prefix##get_count_##type(_CVLIST*); + +/* This macro finds a space for a new element and puts in into 'element' pointer */ +#define INSERT_NEW(element_type, l, element)\ + l->m_size++;\ + if(l->m_head_free.m_pos != NULL)\ + {\ + element = (element_type*)(l->m_head_free.m_pos);\ + if(element->m_next != NULL)\ + {\ + element->m_next->m_prev = NULL;\ + l->m_head_free.m_pos = element->m_next;\ + }\ + else\ + {\ + l->m_head_free.m_pos = NULL;\ + }\ + }\ + else\ + {\ + if(l->m_buf_size < l->m_size && l->m_head_free.m_pos == NULL)\ + {\ + *(void**)l->m_buffer = cvAlloc(l->m_buf_size*sizeof(element_type) + sizeof(void*));\ + l->m_buffer = *(void**)l->m_buffer;\ + *(void**)l->m_buffer = NULL;\ + element = (element_type*)((char*)l->m_buffer + sizeof(void*));\ + }\ + else\ + {\ + element = (element_type*)((char*)l->m_buffer + sizeof(void*)) + l->m_size - 1;\ + }\ + } + +/* This macro adds 'element' to the list of free elements*/ +#define INSERT_FREE(element_type, l, element)\ + if(l->m_head_free.m_pos != NULL)\ + {\ + ((element_type*)l->m_head_free.m_pos)->m_prev = element;\ + }\ + element->m_next = ((element_type*)l->m_head_free.m_pos);\ + l->m_head_free.m_pos = element; + + +/*#define GET_FIRST_FREE(l) ((ELEMENT_##type*)(l->m_head_free.m_pos))*/ + +#define IMPLEMENT_LIST(type, prefix)\ +_CVLIST* prefix##create_list_##type(long size)\ +{\ + _CVLIST* pl = (_CVLIST*)cvAlloc(sizeof(_CVLIST));\ + pl->m_buf_size = size > 0 ? size : default_size;\ + pl->m_first_buffer = cvAlloc(pl->m_buf_size*sizeof(ELEMENT_##type) + sizeof(void*));\ + pl->m_buffer = pl->m_first_buffer;\ + *(void**)pl->m_buffer = NULL;\ + pl->m_size = 0;\ + pl->m_head.m_pos = NULL;\ + pl->m_tail.m_pos = NULL;\ + pl->m_head_free.m_pos = NULL;\ + return pl;\ +}\ +void prefix##destroy_list_##type(_CVLIST* l)\ +{\ + void* cur = l->m_first_buffer;\ + void* next;\ + while(cur)\ + {\ + next = *(void**)cur;\ + cvFree(&cur);\ + cur = next;\ + }\ + cvFree(&l);\ +}\ +CVPOS prefix##get_head_pos_##type(_CVLIST* l)\ +{\ + return l->m_head;\ +}\ +CVPOS prefix##get_tail_pos_##type(_CVLIST* l)\ +{\ + return l->m_tail;\ +}\ +type* prefix##get_next_##type(CVPOS* pos)\ +{\ + if(pos->m_pos)\ + {\ + ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\ + pos->m_pos = element->m_next;\ + return &element->m_data;\ + }\ + else\ + {\ + return NULL;\ + }\ +}\ +type* prefix##get_prev_##type(CVPOS* pos)\ +{\ + if(pos->m_pos)\ + {\ + ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\ + pos->m_pos = element->m_prev;\ + return &element->m_data;\ + }\ + else\ + {\ + return NULL;\ + }\ +}\ +int prefix##is_pos_##type(CVPOS pos)\ +{\ + return !!pos.m_pos;\ +}\ +void prefix##clear_list_##type(_CVLIST* l)\ +{\ + l->m_head.m_pos = NULL;\ + l->m_tail.m_pos = NULL;\ + l->m_size = 0;\ + l->m_head_free.m_pos = NULL;\ +}\ +CVPOS prefix##add_head_##type(_CVLIST* l, type* data)\ +{\ + ELEMENT_##type* element;\ + INSERT_NEW(ELEMENT_##type, l, element);\ + element->m_prev = NULL;\ + element->m_next = (ELEMENT_##type*)(l->m_head.m_pos);\ + memcpy(&(element->m_data), data, sizeof(*data));\ + if(element->m_next)\ + {\ + element->m_next->m_prev = element;\ + }\ + else\ + {\ + l->m_tail.m_pos = element;\ + }\ + l->m_head.m_pos = element;\ + return l->m_head;\ +}\ +CVPOS prefix##add_tail_##type(_CVLIST* l, type* data)\ +{\ + ELEMENT_##type* element;\ + INSERT_NEW(ELEMENT_##type, l, element);\ + element->m_next = NULL;\ + element->m_prev = (ELEMENT_##type*)(l->m_tail.m_pos);\ + memcpy(&(element->m_data), data, sizeof(*data));\ + if(element->m_prev)\ + {\ + element->m_prev->m_next = element;\ + }\ + else\ + {\ + l->m_head.m_pos = element;\ + }\ + l->m_tail.m_pos = element;\ + return l->m_tail;\ +}\ +void prefix##remove_head_##type(_CVLIST* l)\ +{\ + ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_head.m_pos));\ + if(element->m_next != NULL)\ + {\ + element->m_next->m_prev = NULL;\ + }\ + l->m_head.m_pos = element->m_next;\ + INSERT_FREE(ELEMENT_##type, l, element);\ + l->m_size--;\ +}\ +void prefix##remove_tail_##type(_CVLIST* l)\ +{\ + ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_tail.m_pos));\ + if(element->m_prev != NULL)\ + {\ + element->m_prev->m_next = NULL;\ + }\ + l->m_tail.m_pos = element->m_prev;\ + INSERT_FREE(ELEMENT_##type, l, element);\ + l->m_size--;\ +}\ +CVPOS prefix##insert_after_##type(_CVLIST* l, CVPOS pos, type* data)\ +{\ + ELEMENT_##type* element;\ + ELEMENT_##type* before;\ + CVPOS newpos;\ + INSERT_NEW(ELEMENT_##type, l, element);\ + memcpy(&(element->m_data), data, sizeof(*data));\ + before = (ELEMENT_##type*)pos.m_pos;\ + element->m_prev = before;\ + element->m_next = before->m_next;\ + before->m_next = element;\ + if(element->m_next != NULL)\ + element->m_next->m_prev = element;\ + else\ + l->m_tail.m_pos = element;\ + newpos.m_pos = element;\ + return newpos;\ +}\ +CVPOS prefix##insert_before_##type(_CVLIST* l, CVPOS pos, type* data)\ +{\ + ELEMENT_##type* element;\ + ELEMENT_##type* after;\ + CVPOS newpos;\ + INSERT_NEW(ELEMENT_##type, l, element);\ + memcpy(&(element->m_data), data, sizeof(*data));\ + after = (ELEMENT_##type*)pos.m_pos;\ + element->m_prev = after->m_prev;\ + element->m_next = after;\ + after->m_prev = element;\ + if(element->m_prev != NULL)\ + element->m_prev->m_next = element;\ + else\ + l->m_head.m_pos = element;\ + newpos.m_pos = element;\ + return newpos;\ +}\ +void prefix##remove_at_##type(_CVLIST* l, CVPOS pos)\ +{\ + ELEMENT_##type* element = ((ELEMENT_##type*)pos.m_pos);\ + if(element->m_prev != NULL)\ + {\ + element->m_prev->m_next = element->m_next;\ + }\ + else\ + {\ + l->m_head.m_pos = element->m_next;\ + }\ + if(element->m_next != NULL)\ + {\ + element->m_next->m_prev = element->m_prev;\ + }\ + else\ + {\ + l->m_tail.m_pos = element->m_prev;\ + }\ + INSERT_FREE(ELEMENT_##type, l, element);\ + l->m_size--;\ +}\ +void prefix##set_##type(CVPOS pos, type* data)\ +{\ + ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\ + memcpy(&(element->m_data), data, sizeof(*data));\ +}\ +type* prefix##get_##type(CVPOS pos)\ +{\ + ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\ + return &(element->m_data);\ +}\ +int prefix##get_count_##type(_CVLIST* list)\ +{\ + return list->m_size;\ +} + +#define DECLARE_AND_IMPLEMENT_LIST(type, prefix)\ + DECLARE_LIST(type, prefix)\ + IMPLEMENT_LIST(type, prefix) + +typedef struct __index +{ + int value; + float rho, theta; +} +_index; + +DECLARE_LIST( _index, h_ ) + +#endif/*_CV_LIST_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/accum.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/accum.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/accum.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/accum.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,485 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +/ +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +template void +acc_( const T* src, AT* dst, const uchar* mask, int len, int cn ) +{ + int i = 0; + + if( !mask ) + { + len *= cn; + #if CV_ENABLE_UNROLLED + for( ; i <= len - 4; i += 4 ) + { + AT t0, t1; + t0 = src[i] + dst[i]; + t1 = src[i+1] + dst[i+1]; + dst[i] = t0; dst[i+1] = t1; + + t0 = src[i+2] + dst[i+2]; + t1 = src[i+3] + dst[i+3]; + dst[i+2] = t0; dst[i+3] = t1; + } + #endif + for( ; i < len; i++ ) + dst[i] += src[i]; + } + else if( cn == 1 ) + { + for( ; i < len; i++ ) + { + if( mask[i] ) + dst[i] += src[i]; + } + } + else if( cn == 3 ) + { + for( ; i < len; i++, src += 3, dst += 3 ) + { + if( mask[i] ) + { + AT t0 = src[0] + dst[0]; + AT t1 = src[1] + dst[1]; + AT t2 = src[2] + dst[2]; + + dst[0] = t0; dst[1] = t1; dst[2] = t2; + } + } + } + else + { + for( ; i < len; i++, src += cn, dst += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + dst[k] += src[k]; + } + } +} + + +template void +accSqr_( const T* src, AT* dst, const uchar* mask, int len, int cn ) +{ + int i = 0; + + if( !mask ) + { + len *= cn; + #if CV_ENABLE_UNROLLED + for( ; i <= len - 4; i += 4 ) + { + AT t0, t1; + t0 = (AT)src[i]*src[i] + dst[i]; + t1 = (AT)src[i+1]*src[i+1] + dst[i+1]; + dst[i] = t0; dst[i+1] = t1; + + t0 = (AT)src[i+2]*src[i+2] + dst[i+2]; + t1 = (AT)src[i+3]*src[i+3] + dst[i+3]; + dst[i+2] = t0; dst[i+3] = t1; + } + #endif + for( ; i < len; i++ ) + dst[i] += (AT)src[i]*src[i]; + } + else if( cn == 1 ) + { + for( ; i < len; i++ ) + { + if( mask[i] ) + dst[i] += (AT)src[i]*src[i]; + } + } + else if( cn == 3 ) + { + for( ; i < len; i++, src += 3, dst += 3 ) + { + if( mask[i] ) + { + AT t0 = (AT)src[0]*src[0] + dst[0]; + AT t1 = (AT)src[1]*src[1] + dst[1]; + AT t2 = (AT)src[2]*src[2] + dst[2]; + + dst[0] = t0; dst[1] = t1; dst[2] = t2; + } + } + } + else + { + for( ; i < len; i++, src += cn, dst += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + dst[k] += (AT)src[k]*src[k]; + } + } +} + + +template void +accProd_( const T* src1, const T* src2, AT* dst, const uchar* mask, int len, int cn ) +{ + int i = 0; + + if( !mask ) + { + len *= cn; + #if CV_ENABLE_UNROLLED + for( ; i <= len - 4; i += 4 ) + { + AT t0, t1; + t0 = (AT)src1[i]*src2[i] + dst[i]; + t1 = (AT)src1[i+1]*src2[i+1] + dst[i+1]; + dst[i] = t0; dst[i+1] = t1; + + t0 = (AT)src1[i+2]*src2[i+2] + dst[i+2]; + t1 = (AT)src1[i+3]*src2[i+3] + dst[i+3]; + dst[i+2] = t0; dst[i+3] = t1; + } + #endif + for( ; i < len; i++ ) + dst[i] += (AT)src1[i]*src2[i]; + } + else if( cn == 1 ) + { + for( ; i < len; i++ ) + { + if( mask[i] ) + dst[i] += (AT)src1[i]*src2[i]; + } + } + else if( cn == 3 ) + { + for( ; i < len; i++, src1 += 3, src2 += 3, dst += 3 ) + { + if( mask[i] ) + { + AT t0 = (AT)src1[0]*src2[0] + dst[0]; + AT t1 = (AT)src1[1]*src2[1] + dst[1]; + AT t2 = (AT)src1[2]*src2[2] + dst[2]; + + dst[0] = t0; dst[1] = t1; dst[2] = t2; + } + } + } + else + { + for( ; i < len; i++, src1 += cn, src2 += cn, dst += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + dst[k] += (AT)src1[k]*src2[k]; + } + } +} + + +template void +accW_( const T* src, AT* dst, const uchar* mask, int len, int cn, double alpha ) +{ + AT a = (AT)alpha, b = 1 - a; + int i = 0; + + if( !mask ) + { + len *= cn; + #if CV_ENABLE_UNROLLED + for( ; i <= len - 4; i += 4 ) + { + AT t0, t1; + t0 = src[i]*a + dst[i]*b; + t1 = src[i+1]*a + dst[i+1]*b; + dst[i] = t0; dst[i+1] = t1; + + t0 = src[i+2]*a + dst[i+2]*b; + t1 = src[i+3]*a + dst[i+3]*b; + dst[i+2] = t0; dst[i+3] = t1; + } + #endif + for( ; i < len; i++ ) + dst[i] = src[i]*a + dst[i]*b; + } + else if( cn == 1 ) + { + for( ; i < len; i++ ) + { + if( mask[i] ) + dst[i] = src[i]*a + dst[i]*b; + } + } + else if( cn == 3 ) + { + for( ; i < len; i++, src += 3, dst += 3 ) + { + if( mask[i] ) + { + AT t0 = src[0]*a + dst[0]*b; + AT t1 = src[1]*a + dst[1]*b; + AT t2 = src[2]*a + dst[2]*b; + + dst[0] = t0; dst[1] = t1; dst[2] = t2; + } + } + } + else + { + for( ; i < len; i++, src += cn, dst += cn ) + if( mask[i] ) + { + for( int k = 0; k < cn; k++ ) + dst[k] = src[k]*a + dst[k]*b; + } + } +} + + +#define DEF_ACC_FUNCS(suffix, type, acctype) \ +static void acc_##suffix(const type* src, acctype* dst, \ + const uchar* mask, int len, int cn) \ +{ acc_(src, dst, mask, len, cn); } \ +\ +static void accSqr_##suffix(const type* src, acctype* dst, \ + const uchar* mask, int len, int cn) \ +{ accSqr_(src, dst, mask, len, cn); } \ +\ +static void accProd_##suffix(const type* src1, const type* src2, \ + acctype* dst, const uchar* mask, int len, int cn) \ +{ accProd_(src1, src2, dst, mask, len, cn); } \ +\ +static void accW_##suffix(const type* src, acctype* dst, \ + const uchar* mask, int len, int cn, double alpha) \ +{ accW_(src, dst, mask, len, cn, alpha); } + + +DEF_ACC_FUNCS(8u32f, uchar, float) +DEF_ACC_FUNCS(8u64f, uchar, double) +DEF_ACC_FUNCS(16u32f, ushort, float) +DEF_ACC_FUNCS(16u64f, ushort, double) +DEF_ACC_FUNCS(32f, float, float) +DEF_ACC_FUNCS(32f64f, float, double) +DEF_ACC_FUNCS(64f, double, double) + + +typedef void (*AccFunc)(const uchar*, uchar*, const uchar*, int, int); +typedef void (*AccProdFunc)(const uchar*, const uchar*, uchar*, const uchar*, int, int); +typedef void (*AccWFunc)(const uchar*, uchar*, const uchar*, int, int, double); + +static AccFunc accTab[] = +{ + (AccFunc)acc_8u32f, (AccFunc)acc_8u64f, + (AccFunc)acc_16u32f, (AccFunc)acc_16u64f, + (AccFunc)acc_32f, (AccFunc)acc_32f64f, + (AccFunc)acc_64f +}; + +static AccFunc accSqrTab[] = +{ + (AccFunc)accSqr_8u32f, (AccFunc)accSqr_8u64f, + (AccFunc)accSqr_16u32f, (AccFunc)accSqr_16u64f, + (AccFunc)accSqr_32f, (AccFunc)accSqr_32f64f, + (AccFunc)accSqr_64f +}; + +static AccProdFunc accProdTab[] = +{ + (AccProdFunc)accProd_8u32f, (AccProdFunc)accProd_8u64f, + (AccProdFunc)accProd_16u32f, (AccProdFunc)accProd_16u64f, + (AccProdFunc)accProd_32f, (AccProdFunc)accProd_32f64f, + (AccProdFunc)accProd_64f +}; + +static AccWFunc accWTab[] = +{ + (AccWFunc)accW_8u32f, (AccWFunc)accW_8u64f, + (AccWFunc)accW_16u32f, (AccWFunc)accW_16u64f, + (AccWFunc)accW_32f, (AccWFunc)accW_32f64f, + (AccWFunc)accW_64f +}; + +inline int getAccTabIdx(int sdepth, int ddepth) +{ + return sdepth == CV_8U && ddepth == CV_32F ? 0 : + sdepth == CV_8U && ddepth == CV_64F ? 1 : + sdepth == CV_16U && ddepth == CV_32F ? 2 : + sdepth == CV_16U && ddepth == CV_64F ? 3 : + sdepth == CV_32F && ddepth == CV_32F ? 4 : + sdepth == CV_32F && ddepth == CV_64F ? 5 : + sdepth == CV_64F && ddepth == CV_64F ? 6 : -1; +} + +} + +void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask ) +{ + Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat(); + int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels(); + + CV_Assert( dst.size == src.size && dst.channels() == cn ); + CV_Assert( mask.empty() || (mask.size == src.size && mask.type() == CV_8U) ); + + int fidx = getAccTabIdx(sdepth, ddepth); + AccFunc func = fidx >= 0 ? accTab[fidx] : 0; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, &mask, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], ptrs[1], ptrs[2], len, cn); +} + + +void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _mask ) +{ + Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat(); + int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels(); + + CV_Assert( dst.size == src.size && dst.channels() == cn ); + CV_Assert( mask.empty() || (mask.size == src.size && mask.type() == CV_8U) ); + + int fidx = getAccTabIdx(sdepth, ddepth); + AccFunc func = fidx >= 0 ? accSqrTab[fidx] : 0; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, &mask, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], ptrs[1], ptrs[2], len, cn); +} + +void cv::accumulateProduct( InputArray _src1, InputArray _src2, + InputOutputArray _dst, InputArray _mask ) +{ + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat(); + int sdepth = src1.depth(), ddepth = dst.depth(), cn = src1.channels(); + + CV_Assert( src2.size && src1.size && src2.type() == src1.type() ); + CV_Assert( dst.size == src1.size && dst.channels() == cn ); + CV_Assert( mask.empty() || (mask.size == src1.size && mask.type() == CV_8U) ); + + int fidx = getAccTabIdx(sdepth, ddepth); + AccProdFunc func = fidx >= 0 ? accProdTab[fidx] : 0; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src1, &src2, &dst, &mask, 0}; + uchar* ptrs[4]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], ptrs[1], ptrs[2], ptrs[3], len, cn); +} + + +void cv::accumulateWeighted( InputArray _src, InputOutputArray _dst, + double alpha, InputArray _mask ) +{ + Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat(); + int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels(); + + CV_Assert( dst.size == src.size && dst.channels() == cn ); + CV_Assert( mask.empty() || (mask.size == src.size && mask.type() == CV_8U) ); + + int fidx = getAccTabIdx(sdepth, ddepth); + AccWFunc func = fidx >= 0 ? accWTab[fidx] : 0; + CV_Assert( func != 0 ); + + const Mat* arrays[] = {&src, &dst, &mask, 0}; + uchar* ptrs[3]; + NAryMatIterator it(arrays, ptrs); + int len = (int)it.size; + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + func(ptrs[0], ptrs[1], ptrs[2], len, cn, alpha); +} + + +CV_IMPL void +cvAcc( const void* arr, void* sumarr, const void* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::accumulate( src, dst, mask ); +} + +CV_IMPL void +cvSquareAcc( const void* arr, void* sumarr, const void* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::accumulateSquare( src, dst, mask ); +} + +CV_IMPL void +cvMultiplyAcc( const void* arr1, const void* arr2, + void* sumarr, const void* maskarr ) +{ + cv::Mat src1 = cv::cvarrToMat(arr1), src2 = cv::cvarrToMat(arr2); + cv::Mat dst = cv::cvarrToMat(sumarr), mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::accumulateProduct( src1, src2, dst, mask ); +} + +CV_IMPL void +cvRunningAvg( const void* arr, void* sumarr, double alpha, const void* maskarr ) +{ + cv::Mat src = cv::cvarrToMat(arr), dst = cv::cvarrToMat(sumarr), mask; + if( maskarr ) + mask = cv::cvarrToMat(maskarr); + cv::accumulateWeighted( src, dst, alpha, mask ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/approx.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/approx.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/approx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/approx.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,807 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +/****************************************************************************************\ +* Chain Approximation * +\****************************************************************************************/ + +typedef struct _CvPtInfo +{ + CvPoint pt; + int k; /* support region */ + int s; /* curvature value */ + struct _CvPtInfo *next; +} +_CvPtInfo; + + +/* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */ +CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, + CvMemStorage* storage, int method ) +{ + static const int abs_diff[] = { 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1 }; + + cv::AutoBuffer<_CvPtInfo> buf(chain->total + 8); + + _CvPtInfo temp; + _CvPtInfo *array = buf, *first = 0, *current = 0, *prev_current = 0; + int i, j, i1, i2, s, len; + int count = chain->total; + + CvChainPtReader reader; + CvSeqWriter writer; + CvPoint pt = chain->origin; + + CV_Assert( CV_IS_SEQ_CHAIN_CONTOUR( chain )); + CV_Assert( header_size >= (int)sizeof(CvContour) ); + + cvStartWriteSeq( (chain->flags & ~CV_SEQ_ELTYPE_MASK) | CV_SEQ_ELTYPE_POINT, + header_size, sizeof( CvPoint ), storage, &writer ); + + if( chain->total == 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + return cvEndWriteSeq( &writer ); + } + + cvStartReadChainPoints( chain, &reader ); + + temp.next = 0; + current = &temp; + + /* Pass 0. + Restores all the digital curve points from the chain code. + Removes the points (from the resultant polygon) + that have zero 1-curvature */ + for( i = 0; i < count; i++ ) + { + int prev_code = *reader.prev_elem; + + reader.prev_elem = reader.ptr; + CV_READ_CHAIN_POINT( pt, reader ); + + /* calc 1-curvature */ + s = abs_diff[reader.code - prev_code + 7]; + + if( method <= CV_CHAIN_APPROX_SIMPLE ) + { + if( method == CV_CHAIN_APPROX_NONE || s != 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + } + else + { + if( s != 0 ) + current = current->next = array + i; + array[i].s = s; + array[i].pt = pt; + } + } + + //assert( pt.x == chain->origin.x && pt.y == chain->origin.y ); + + if( method <= CV_CHAIN_APPROX_SIMPLE ) + return cvEndWriteSeq( &writer ); + + current->next = 0; + + len = i; + current = temp.next; + + assert( current ); + + /* Pass 1. + Determines support region for all the remained points */ + do + { + CvPoint pt0; + int k, l = 0, d_num = 0; + + i = (int)(current - array); + pt0 = array[i].pt; + + /* determine support region */ + for( k = 1;; k++ ) + { + int lk, dk_num; + int dx, dy; + Cv32suf d; + + assert( k <= len ); + + /* calc indices */ + i1 = i - k; + i1 += i1 < 0 ? len : 0; + i2 = i + k; + i2 -= i2 >= len ? len : 0; + + dx = array[i2].pt.x - array[i1].pt.x; + dy = array[i2].pt.y - array[i1].pt.y; + + /* distance between p_(i - k) and p_(i + k) */ + lk = dx * dx + dy * dy; + + /* distance between p_i and the line (p_(i-k), p_(i+k)) */ + dk_num = (pt0.x - array[i1].pt.x) * dy - (pt0.y - array[i1].pt.y) * dx; + d.f = (float) (((double) d_num) * lk - ((double) dk_num) * l); + + if( k > 1 && (l >= lk || ((d_num > 0 && d.i <= 0) || (d_num < 0 && d.i >= 0)))) + break; + + d_num = dk_num; + l = lk; + } + + current->k = --k; + + /* determine cosine curvature if it should be used */ + if( method == CV_CHAIN_APPROX_TC89_KCOS ) + { + /* calc k-cosine curvature */ + for( j = k, s = 0; j > 0; j-- ) + { + double temp_num; + int dx1, dy1, dx2, dy2; + Cv32suf sk; + + i1 = i - j; + i1 += i1 < 0 ? len : 0; + i2 = i + j; + i2 -= i2 >= len ? len : 0; + + dx1 = array[i1].pt.x - pt0.x; + dy1 = array[i1].pt.y - pt0.y; + dx2 = array[i2].pt.x - pt0.x; + dy2 = array[i2].pt.y - pt0.y; + + if( (dx1 | dy1) == 0 || (dx2 | dy2) == 0 ) + break; + + temp_num = dx1 * dx2 + dy1 * dy2; + temp_num = + (float) (temp_num / + sqrt( ((double)dx1 * dx1 + (double)dy1 * dy1) * + ((double)dx2 * dx2 + (double)dy2 * dy2) )); + sk.f = (float) (temp_num + 1.1); + + assert( 0 <= sk.f && sk.f <= 2.2 ); + if( j < k && sk.i <= s ) + break; + + s = sk.i; + } + current->s = s; + } + current = current->next; + } + while( current != 0 ); + + prev_current = &temp; + current = temp.next; + + /* Pass 2. + Performs non-maxima supression */ + do + { + int k2 = current->k >> 1; + + s = current->s; + i = (int)(current - array); + + for( j = 1; j <= k2; j++ ) + { + i2 = i - j; + i2 += i2 < 0 ? len : 0; + + if( array[i2].s > s ) + break; + + i2 = i + j; + i2 -= i2 >= len ? len : 0; + + if( array[i2].s > s ) + break; + } + + if( j <= k2 ) /* exclude point */ + { + prev_current->next = current->next; + current->s = 0; /* "clear" point */ + } + else + prev_current = current; + current = current->next; + } + while( current != 0 ); + + /* Pass 3. + Removes non-dominant points with 1-length support region */ + current = temp.next; + assert( current ); + prev_current = &temp; + + do + { + if( current->k == 1 ) + { + s = current->s; + i = (int)(current - array); + + i1 = i - 1; + i1 += i1 < 0 ? len : 0; + + i2 = i + 1; + i2 -= i2 >= len ? len : 0; + + if( s <= array[i1].s || s <= array[i2].s ) + { + prev_current->next = current->next; + current->s = 0; + } + else + prev_current = current; + } + else + prev_current = current; + current = current->next; + } + while( current != 0 ); + + if( method == CV_CHAIN_APPROX_TC89_KCOS ) + goto copy_vect; + + /* Pass 4. + Cleans remained couples of points */ + assert( temp.next ); + + if( array[0].s != 0 && array[len - 1].s != 0 ) /* specific case */ + { + for( i1 = 1; i1 < len && array[i1].s != 0; i1++ ) + { + array[i1 - 1].s = 0; + } + if( i1 == len ) + goto copy_vect; /* all points survived */ + i1--; + + for( i2 = len - 2; i2 > 0 && array[i2].s != 0; i2-- ) + { + array[i2].next = 0; + array[i2 + 1].s = 0; + } + i2++; + + if( i1 == 0 && i2 == len - 1 ) /* only two points */ + { + i1 = (int)(array[0].next - array); + array[len] = array[0]; /* move to the end */ + array[len].next = 0; + array[len - 1].next = array + len; + } + temp.next = array + i1; + } + + current = temp.next; + first = prev_current = &temp; + count = 1; + + /* do last pass */ + do + { + if( current->next == 0 || current->next - current != 1 ) + { + if( count >= 2 ) + { + if( count == 2 ) + { + int s1 = prev_current->s; + int s2 = current->s; + + if( s1 > s2 || (s1 == s2 && prev_current->k <= current->k) ) + /* remove second */ + prev_current->next = current->next; + else + /* remove first */ + first->next = current; + } + else + first->next->next = current; + } + first = current; + count = 1; + } + else + count++; + prev_current = current; + current = current->next; + } + while( current != 0 ); + +copy_vect: + + // gather points + current = temp.next; + assert( current ); + + do + { + CV_WRITE_SEQ_ELEM( current->pt, writer ); + current = current->next; + } + while( current != 0 ); + + return cvEndWriteSeq( &writer ); +} + + +/*Applies some approximation algorithm to chain-coded contour(s) and + converts it/them to polygonal representation */ +CV_IMPL CvSeq* +cvApproxChains( CvSeq* src_seq, + CvMemStorage* storage, + int method, + double /*parameter*/, + int minimal_perimeter, + int recursive ) +{ + CvSeq *prev_contour = 0, *parent = 0; + CvSeq *dst_seq = 0; + + if( !src_seq || !storage ) + CV_Error( CV_StsNullPtr, "" ); + if( method > CV_CHAIN_APPROX_TC89_KCOS || method <= 0 || minimal_perimeter < 0 ) + CV_Error( CV_StsOutOfRange, "" ); + + while( src_seq != 0 ) + { + int len = src_seq->total; + + if( len >= minimal_perimeter ) + { + CvSeq *contour = 0; + + switch( method ) + { + case CV_CHAIN_APPROX_NONE: + case CV_CHAIN_APPROX_SIMPLE: + case CV_CHAIN_APPROX_TC89_L1: + case CV_CHAIN_APPROX_TC89_KCOS: + contour = icvApproximateChainTC89( (CvChain *) src_seq, sizeof( CvContour ), storage, method ); + break; + default: + CV_Error( CV_StsOutOfRange, "" ); + } + + if( contour->total > 0 ) + { + cvBoundingRect( contour, 1 ); + + contour->v_prev = parent; + contour->h_prev = prev_contour; + + if( prev_contour ) + prev_contour->h_next = contour; + else if( parent ) + parent->v_next = contour; + prev_contour = contour; + if( !dst_seq ) + dst_seq = prev_contour; + } + else /* if resultant contour has zero length, skip it */ + { + len = -1; + } + } + + if( !recursive ) + break; + + if( src_seq->v_next && len >= minimal_perimeter ) + { + assert( prev_contour != 0 ); + parent = prev_contour; + prev_contour = 0; + src_seq = src_seq->v_next; + } + else + { + while( src_seq->h_next == 0 ) + { + src_seq = src_seq->v_prev; + if( src_seq == 0 ) + break; + prev_contour = parent; + if( parent ) + parent = parent->v_prev; + } + if( src_seq ) + src_seq = src_seq->h_next; + } + } + + return dst_seq; +} + + +/****************************************************************************************\ +* Polygonal Approximation * +\****************************************************************************************/ + +/* Ramer-Douglas-Peucker algorithm for polygon simplification */ + +/* the version for integer point coordinates */ +template static CvSeq* +icvApproxPolyDP( CvSeq* src_contour, int header_size, + CvMemStorage* storage, double eps ) +{ + typedef cv::Point_ PT; + int init_iters = 3; + CvSlice slice = {0, 0}, right_slice = {0, 0}; + CvSeqReader reader, reader2; + CvSeqWriter writer; + PT start_pt(-1000000, -1000000), end_pt(0, 0), pt(0,0); + int i = 0, j, count = src_contour->total, new_count; + int is_closed = CV_IS_SEQ_CLOSED( src_contour ); + bool le_eps = false; + CvMemStorage* temp_storage = 0; + CvSeq* stack = 0; + CvSeq* dst_contour; + + assert( CV_SEQ_ELTYPE(src_contour) == cv::DataType::type ); + cvStartWriteSeq( src_contour->flags, header_size, sizeof(pt), storage, &writer ); + + if( src_contour->total == 0 ) + return cvEndWriteSeq( &writer ); + + temp_storage = cvCreateChildMemStorage( storage ); + + assert( src_contour->first != 0 ); + stack = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvSlice), temp_storage ); + eps *= eps; + cvStartReadSeq( src_contour, &reader, 0 ); + + if( !is_closed ) + { + right_slice.start_index = count; + end_pt = *(PT*)(reader.ptr); + start_pt = *(PT*)cvGetSeqElem( src_contour, -1 ); + + if( start_pt.x != end_pt.x || start_pt.y != end_pt.y ) + { + slice.start_index = 0; + slice.end_index = count - 1; + cvSeqPush( stack, &slice ); + } + else + { + is_closed = 1; + init_iters = 1; + } + } + + if( is_closed ) + { + /* 1. Find approximately two farthest points of the contour */ + right_slice.start_index = 0; + + for( i = 0; i < init_iters; i++ ) + { + double dist, max_dist = 0; + cvSetSeqReaderPos( &reader, right_slice.start_index, 1 ); + CV_READ_SEQ_ELEM( start_pt, reader ); /* read the first point */ + + for( j = 1; j < count; j++ ) + { + double dx, dy; + + CV_READ_SEQ_ELEM( pt, reader ); + dx = pt.x - start_pt.x; + dy = pt.y - start_pt.y; + + dist = dx * dx + dy * dy; + + if( dist > max_dist ) + { + max_dist = dist; + right_slice.start_index = j; + } + } + + le_eps = max_dist <= eps; + } + + /* 2. initialize the stack */ + if( !le_eps ) + { + slice.start_index = cvGetSeqReaderPos( &reader ); + slice.end_index = right_slice.start_index += slice.start_index; + + right_slice.start_index -= right_slice.start_index >= count ? count : 0; + right_slice.end_index = slice.start_index; + if( right_slice.end_index < right_slice.start_index ) + right_slice.end_index += count; + + cvSeqPush( stack, &right_slice ); + cvSeqPush( stack, &slice ); + } + else + CV_WRITE_SEQ_ELEM( start_pt, writer ); + } + + /* 3. run recursive process */ + while( stack->total != 0 ) + { + cvSeqPop( stack, &slice ); + + cvSetSeqReaderPos( &reader, slice.end_index ); + CV_READ_SEQ_ELEM( end_pt, reader ); + + cvSetSeqReaderPos( &reader, slice.start_index ); + CV_READ_SEQ_ELEM( start_pt, reader ); + + if( slice.end_index > slice.start_index + 1 ) + { + double dx, dy, dist, max_dist = 0; + + dx = end_pt.x - start_pt.x; + dy = end_pt.y - start_pt.y; + + assert( dx != 0 || dy != 0 ); + + for( i = slice.start_index + 1; i < slice.end_index; i++ ) + { + CV_READ_SEQ_ELEM( pt, reader ); + dist = fabs((pt.y - start_pt.y) * dx - (pt.x - start_pt.x) * dy); + + if( dist > max_dist ) + { + max_dist = dist; + right_slice.start_index = i; + } + } + + le_eps = max_dist * max_dist <= eps * (dx * dx + dy * dy); + } + else + { + assert( slice.end_index > slice.start_index ); + le_eps = true; + /* read starting point */ + cvSetSeqReaderPos( &reader, slice.start_index ); + CV_READ_SEQ_ELEM( start_pt, reader ); + } + + if( le_eps ) + { + CV_WRITE_SEQ_ELEM( start_pt, writer ); + } + else + { + right_slice.end_index = slice.end_index; + slice.end_index = right_slice.start_index; + cvSeqPush( stack, &right_slice ); + cvSeqPush( stack, &slice ); + } + } + + is_closed = CV_IS_SEQ_CLOSED( src_contour ); + if( !is_closed ) + CV_WRITE_SEQ_ELEM( end_pt, writer ); + + dst_contour = cvEndWriteSeq( &writer ); + + // last stage: do final clean-up of the approximated contour - + // remove extra points on the [almost] stright lines. + + cvStartReadSeq( dst_contour, &reader, is_closed ); + CV_READ_SEQ_ELEM( start_pt, reader ); + + reader2 = reader; + CV_READ_SEQ_ELEM( pt, reader ); + + new_count = count = dst_contour->total; + for( i = !is_closed; i < count - !is_closed && new_count > 2; i++ ) + { + double dx, dy, dist, successive_inner_product; + CV_READ_SEQ_ELEM( end_pt, reader ); + + dx = end_pt.x - start_pt.x; + dy = end_pt.y - start_pt.y; + dist = fabs((pt.x - start_pt.x)*dy - (pt.y - start_pt.y)*dx); + successive_inner_product = (pt.x - start_pt.x) * (end_pt.x - pt.x) + + (pt.y - start_pt.y) * (end_pt.y - pt.y); + + if( dist * dist <= 0.5*eps*(dx*dx + dy*dy) && dx != 0 && dy != 0 && + successive_inner_product >= 0 ) + { + new_count--; + *((PT*)reader2.ptr) = start_pt = end_pt; + CV_NEXT_SEQ_ELEM( sizeof(pt), reader2 ); + CV_READ_SEQ_ELEM( pt, reader ); + i++; + continue; + } + *((PT*)reader2.ptr) = start_pt = pt; + CV_NEXT_SEQ_ELEM( sizeof(pt), reader2 ); + pt = end_pt; + } + + if( !is_closed ) + *((PT*)reader2.ptr) = pt; + + if( new_count < count ) + cvSeqPopMulti( dst_contour, 0, count - new_count ); + + cvReleaseMemStorage( &temp_storage ); + return dst_contour; +} + + +CV_IMPL CvSeq* +cvApproxPoly( const void* array, int header_size, + CvMemStorage* storage, int method, + double parameter, int parameter2 ) +{ + CvSeq* dst_seq = 0; + CvSeq *prev_contour = 0, *parent = 0; + CvContour contour_header; + CvSeq* src_seq = 0; + CvSeqBlock block; + int recursive = 0; + + if( CV_IS_SEQ( array )) + { + src_seq = (CvSeq*)array; + if( !CV_IS_SEQ_POLYLINE( src_seq )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + + recursive = parameter2; + + if( !storage ) + storage = src_seq->storage; + } + else + { + src_seq = cvPointSeqFromMat( + CV_SEQ_KIND_CURVE | (parameter2 ? CV_SEQ_FLAG_CLOSED : 0), + array, &contour_header, &block ); + } + + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer " ); + + if( header_size < 0 ) + CV_Error( CV_StsOutOfRange, "header_size is negative. " + "Pass 0 to make the destination header_size == input header_size" ); + + if( header_size == 0 ) + header_size = src_seq->header_size; + + if( !CV_IS_SEQ_POLYLINE( src_seq )) + { + if( CV_IS_SEQ_CHAIN( src_seq )) + { + CV_Error( CV_StsBadArg, "Input curves are not polygonal. " + "Use cvApproxChains first" ); + } + else + { + CV_Error( CV_StsBadArg, "Input curves have uknown type" ); + } + } + + if( header_size == 0 ) + header_size = src_seq->header_size; + + if( header_size < (int)sizeof(CvContour) ) + CV_Error( CV_StsBadSize, "New header size must be non-less than sizeof(CvContour)" ); + + if( method != CV_POLY_APPROX_DP ) + CV_Error( CV_StsOutOfRange, "Unknown approximation method" ); + + while( src_seq != 0 ) + { + CvSeq *contour = 0; + + switch (method) + { + case CV_POLY_APPROX_DP: + if( parameter < 0 ) + CV_Error( CV_StsOutOfRange, "Accuracy must be non-negative" ); + + if( CV_SEQ_ELTYPE(src_seq) == CV_32SC2 ) + contour = icvApproxPolyDP( src_seq, header_size, storage, parameter ); + else + contour = icvApproxPolyDP( src_seq, header_size, storage, parameter ); + break; + default: + assert(0); + CV_Error( CV_StsBadArg, "Invalid approximation method" ); + } + + assert( contour ); + + if( header_size >= (int)sizeof(CvContour)) + cvBoundingRect( contour, 1 ); + + contour->v_prev = parent; + contour->h_prev = prev_contour; + + if( prev_contour ) + prev_contour->h_next = contour; + else if( parent ) + parent->v_next = contour; + prev_contour = contour; + if( !dst_seq ) + dst_seq = prev_contour; + + if( !recursive ) + break; + + if( src_seq->v_next ) + { + assert( prev_contour != 0 ); + parent = prev_contour; + prev_contour = 0; + src_seq = src_seq->v_next; + } + else + { + while( src_seq->h_next == 0 ) + { + src_seq = src_seq->v_prev; + if( src_seq == 0 ) + break; + prev_contour = parent; + if( parent ) + parent = parent->v_prev; + } + if( src_seq ) + src_seq = src_seq->h_next; + } + } + + return dst_seq; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/canny.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/canny.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/canny.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/canny.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,288 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +void cv::Canny( InputArray _src, OutputArray _dst, + double low_thresh, double high_thresh, + int aperture_size, bool L2gradient ) +{ + Mat src = _src.getMat(); + CV_Assert( src.depth() == CV_8U ); + + _dst.create(src.size(), CV_8U); + Mat dst = _dst.getMat(); + + if (!L2gradient && (aperture_size & CV_CANNY_L2_GRADIENT) == CV_CANNY_L2_GRADIENT) + { + //backward compatibility + aperture_size &= ~CV_CANNY_L2_GRADIENT; + L2gradient = true; + } + + if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7))) + CV_Error(CV_StsBadFlag, ""); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::canny(src, dst, low_thresh, high_thresh, aperture_size, L2gradient)) + return; +#endif + + const int cn = src.channels(); + cv::Mat dx(src.rows, src.cols, CV_16SC(cn)); + cv::Mat dy(src.rows, src.cols, CV_16SC(cn)); + + cv::Sobel(src, dx, CV_16S, 1, 0, aperture_size, 1, 0, cv::BORDER_REPLICATE); + cv::Sobel(src, dy, CV_16S, 0, 1, aperture_size, 1, 0, cv::BORDER_REPLICATE); + + if (low_thresh > high_thresh) + std::swap(low_thresh, high_thresh); + + if (L2gradient) + { + low_thresh = std::min(32767.0, low_thresh); + high_thresh = std::min(32767.0, high_thresh); + + if (low_thresh > 0) low_thresh *= low_thresh; + if (high_thresh > 0) high_thresh *= high_thresh; + } + int low = cvFloor(low_thresh); + int high = cvFloor(high_thresh); + + ptrdiff_t mapstep = src.cols + 2; + cv::AutoBuffer buffer((src.cols+2)*(src.rows+2) + cn * mapstep * 3 * sizeof(int)); + + int* mag_buf[3]; + mag_buf[0] = (int*)(uchar*)buffer; + mag_buf[1] = mag_buf[0] + mapstep*cn; + mag_buf[2] = mag_buf[1] + mapstep*cn; + memset(mag_buf[0], 0, /* cn* */mapstep*sizeof(int)); + + uchar* map = (uchar*)(mag_buf[2] + mapstep*cn); + memset(map, 1, mapstep); + memset(map + mapstep*(src.rows + 1), 1, mapstep); + + int maxsize = std::max(1 << 10, src.cols * src.rows / 10); + std::vector stack(maxsize); + uchar **stack_top = &stack[0]; + uchar **stack_bottom = &stack[0]; + + /* sector numbers + (Top-Left Origin) + + 1 2 3 + * * * + * * * + 0*******0 + * * * + * * * + 3 2 1 + */ + + #define CANNY_PUSH(d) *(d) = uchar(2), *stack_top++ = (d) + #define CANNY_POP(d) (d) = *--stack_top + + // calculate magnitude and angle of gradient, perform non-maxima supression. + // fill the map with one of the following values: + // 0 - the pixel might belong to an edge + // 1 - the pixel can not belong to an edge + // 2 - the pixel does belong to an edge + for (int i = 0; i <= src.rows; i++) + { + int* _norm = mag_buf[(i > 0) + 1] + 1; + if (i < src.rows) + { + short* _dx = dx.ptr(i); + short* _dy = dy.ptr(i); + + if (!L2gradient) + { + for (int j = 0; j < src.cols*cn; j++) + _norm[j] = std::abs(int(_dx[j])) + std::abs(int(_dy[j])); + } + else + { + for (int j = 0; j < src.cols*cn; j++) + _norm[j] = int(_dx[j])*_dx[j] + int(_dy[j])*_dy[j]; + } + + if (cn > 1) + { + for(int j = 0, jn = 0; j < src.cols; ++j, jn += cn) + { + int maxIdx = jn; + for(int k = 1; k < cn; ++k) + if(_norm[jn + k] > _norm[maxIdx]) maxIdx = jn + k; + _norm[j] = _norm[maxIdx]; + _dx[j] = _dx[maxIdx]; + _dy[j] = _dy[maxIdx]; + } + } + _norm[-1] = _norm[src.cols] = 0; + } + else + memset(_norm-1, 0, /* cn* */mapstep*sizeof(int)); + + // at the very beginning we do not have a complete ring + // buffer of 3 magnitude rows for non-maxima suppression + if (i == 0) + continue; + + uchar* _map = map + mapstep*i + 1; + _map[-1] = _map[src.cols] = 1; + + int* _mag = mag_buf[1] + 1; // take the central row + ptrdiff_t magstep1 = mag_buf[2] - mag_buf[1]; + ptrdiff_t magstep2 = mag_buf[0] - mag_buf[1]; + + const short* _x = dx.ptr(i-1); + const short* _y = dy.ptr(i-1); + + if ((stack_top - stack_bottom) + src.cols > maxsize) + { + int sz = (int)(stack_top - stack_bottom); + maxsize = maxsize * 3/2; + stack.resize(maxsize); + stack_bottom = &stack[0]; + stack_top = stack_bottom + sz; + } + + int prev_flag = 0; + for (int j = 0; j < src.cols; j++) + { + #define CANNY_SHIFT 15 + const int TG22 = (int)(0.4142135623730950488016887242097*(1< low) + { + int xs = _x[j]; + int ys = _y[j]; + int x = std::abs(xs); + int y = std::abs(ys) << CANNY_SHIFT; + + int tg22x = x * TG22; + + if (y < tg22x) + { + if (m > _mag[j-1] && m >= _mag[j+1]) goto __ocv_canny_push; + } + else + { + int tg67x = tg22x + (x << (CANNY_SHIFT+1)); + if (y > tg67x) + { + if (m > _mag[j+magstep2] && m >= _mag[j+magstep1]) goto __ocv_canny_push; + } + else + { + int s = (xs ^ ys) < 0 ? -1 : 1; + if (m > _mag[j+magstep2-s] && m > _mag[j+magstep1+s]) goto __ocv_canny_push; + } + } + } + prev_flag = 0; + _map[j] = uchar(1); + continue; +__ocv_canny_push: + if (!prev_flag && m > high && _map[j-mapstep] != 2) + { + CANNY_PUSH(_map + j); + prev_flag = 1; + } + else + _map[j] = 0; + } + + // scroll the ring buffer + _mag = mag_buf[0]; + mag_buf[0] = mag_buf[1]; + mag_buf[1] = mag_buf[2]; + mag_buf[2] = _mag; + } + + // now track the edges (hysteresis thresholding) + while (stack_top > stack_bottom) + { + uchar* m; + if ((stack_top - stack_bottom) + 8 > maxsize) + { + int sz = (int)(stack_top - stack_bottom); + maxsize = maxsize * 3/2; + stack.resize(maxsize); + stack_bottom = &stack[0]; + stack_top = stack_bottom + sz; + } + + CANNY_POP(m); + + if (!m[-1]) CANNY_PUSH(m - 1); + if (!m[1]) CANNY_PUSH(m + 1); + if (!m[-mapstep-1]) CANNY_PUSH(m - mapstep - 1); + if (!m[-mapstep]) CANNY_PUSH(m - mapstep); + if (!m[-mapstep+1]) CANNY_PUSH(m - mapstep + 1); + if (!m[mapstep-1]) CANNY_PUSH(m + mapstep - 1); + if (!m[mapstep]) CANNY_PUSH(m + mapstep); + if (!m[mapstep+1]) CANNY_PUSH(m + mapstep + 1); + } + + // the final pass, form the final image + const uchar* pmap = map + mapstep + 1; + uchar* pdst = dst.ptr(); + for (int i = 0; i < src.rows; i++, pmap += mapstep, pdst += dst.step) + { + for (int j = 0; j < src.cols; j++) + pdst[j] = (uchar)-(pmap[j] >> 1); + } +} + +void cvCanny( const CvArr* image, CvArr* edges, double threshold1, + double threshold2, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(image), dst = cv::cvarrToMat(edges); + CV_Assert( src.size == dst.size && src.depth() == CV_8U && dst.type() == CV_8U ); + + cv::Canny(src, dst, threshold1, threshold2, aperture_size & 255, + (aperture_size & CV_CANNY_L2_GRADIENT) != 0); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/color.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/color.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/color.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/color.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3928 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/********************************* COPYRIGHT NOTICE *******************************\ + The function for RGB to Lab conversion is based on the MATLAB script + RGB2Lab.m translated by Mark Ruzon from C code by Yossi Rubner, 23 September 1997. + See the page [http://vision.stanford.edu/~ruzon/software/rgblab.html] +\**********************************************************************************/ + +/********************************* COPYRIGHT NOTICE *******************************\ + Original code for Bayer->BGR/RGB conversion is provided by Dirk Schaefer + from MD-Mathematische Dienste GmbH. Below is the copyright notice: + + IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + By downloading, copying, installing or using the software you agree + to this license. If you do not agree to this license, do not download, + install, copy or use the software. + + Contributors License Agreement: + + Copyright (c) 2002, + MD-Mathematische Dienste GmbH + Im Defdahl 5-10 + 44141 Dortmund + Germany + www.md-it.de + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain + the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + The name of Contributor may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. +\**********************************************************************************/ + +#include "precomp.hpp" +#include +#include + +namespace cv +{ + +// computes cubic spline coefficients for a function: (xi=i, yi=f[i]), i=0..n +template static void splineBuild(const _Tp* f, int n, _Tp* tab) +{ + _Tp cn = 0; + int i; + tab[0] = tab[1] = (_Tp)0; + + for(i = 1; i < n-1; i++) + { + _Tp t = 3*(f[i+1] - 2*f[i] + f[i-1]); + _Tp l = 1/(4 - tab[(i-1)*4]); + tab[i*4] = l; tab[i*4+1] = (t - tab[(i-1)*4+1])*l; + } + + for(i = n-1; i >= 0; i--) + { + _Tp c = tab[i*4+1] - tab[i*4]*cn; + _Tp b = f[i+1] - f[i] - (cn + c*2)*(_Tp)0.3333333333333333; + _Tp d = (cn - c)*(_Tp)0.3333333333333333; + tab[i*4] = f[i]; tab[i*4+1] = b; + tab[i*4+2] = c; tab[i*4+3] = d; + cn = c; + } +} + +// interpolates value of a function at x, 0 <= x <= n using a cubic spline. +template static inline _Tp splineInterpolate(_Tp x, const _Tp* tab, int n) +{ + // don't touch this function without urgent need - some versions of gcc fail to inline it correctly + int ix = std::min(std::max(int(x), 0), n-1); + x -= ix; + tab += ix*4; + return ((tab[3]*x + tab[2])*x + tab[1])*x + tab[0]; +} + + +template struct ColorChannel +{ + typedef float worktype_f; + static _Tp max() { return std::numeric_limits<_Tp>::max(); } + static _Tp half() { return (_Tp)(max()/2 + 1); } +}; + +template<> struct ColorChannel +{ + typedef float worktype_f; + static float max() { return 1.f; } + static float half() { return 0.5f; } +}; + +/*template<> struct ColorChannel +{ + typedef double worktype_f; + static double max() { return 1.; } + static double half() { return 0.5; } +};*/ + + +///////////////////////////// Top-level template function //////////////////////////////// + +template +class CvtColorLoop_Invoker : public ParallelLoopBody +{ + typedef typename Cvt::channel_type _Tp; +public: + + CvtColorLoop_Invoker(const Mat& _src, Mat& _dst, const Cvt& _cvt) : + ParallelLoopBody(), src(_src), dst(_dst), cvt(_cvt) + { + } + + virtual void operator()(const Range& range) const + { + const uchar* yS = src.ptr(range.start); + uchar* yD = dst.ptr(range.start); + + for( int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step ) + cvt((const _Tp*)yS, (_Tp*)yD, src.cols); + } + +private: + const Mat& src; + Mat& dst; + const Cvt& cvt; + + const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&); +}; + +template +void CvtColorLoop(const Mat& src, Mat& dst, const Cvt& cvt) +{ + parallel_for_(Range(0, src.rows), CvtColorLoop_Invoker(src, dst, cvt), src.total()/(double)(1<<16) ); +} + +////////////////// Various 3/4-channel to 3/4-channel RGB transformations ///////////////// + +template struct RGB2RGB +{ + typedef _Tp channel_type; + + RGB2RGB(int _srccn, int _dstcn, int _blueIdx) : srccn(_srccn), dstcn(_dstcn), blueIdx(_blueIdx) {} + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn, dcn = dstcn, bidx = blueIdx; + if( dcn == 3 ) + { + n *= 3; + for( int i = 0; i < n; i += 3, src += scn ) + { + _Tp t0 = src[bidx], t1 = src[1], t2 = src[bidx ^ 2]; + dst[i] = t0; dst[i+1] = t1; dst[i+2] = t2; + } + } + else if( scn == 3 ) + { + n *= 3; + _Tp alpha = ColorChannel<_Tp>::max(); + for( int i = 0; i < n; i += 3, dst += 4 ) + { + _Tp t0 = src[i], t1 = src[i+1], t2 = src[i+2]; + dst[bidx] = t0; dst[1] = t1; dst[bidx^2] = t2; dst[3] = alpha; + } + } + else + { + n *= 4; + for( int i = 0; i < n; i += 4 ) + { + _Tp t0 = src[i], t1 = src[i+1], t2 = src[i+2], t3 = src[i+3]; + dst[i] = t2; dst[i+1] = t1; dst[i+2] = t0; dst[i+3] = t3; + } + } + } + + int srccn, dstcn, blueIdx; +}; + +/////////// Transforming 16-bit (565 or 555) RGB to/from 24/32-bit (888[8]) RGB ////////// + +struct RGB5x52RGB +{ + typedef uchar channel_type; + + RGB5x52RGB(int _dstcn, int _blueIdx, int _greenBits) + : dstcn(_dstcn), blueIdx(_blueIdx), greenBits(_greenBits) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int dcn = dstcn, bidx = blueIdx; + if( greenBits == 6 ) + for( int i = 0; i < n; i++, dst += dcn ) + { + unsigned t = ((const ushort*)src)[i]; + dst[bidx] = (uchar)(t << 3); + dst[1] = (uchar)((t >> 3) & ~3); + dst[bidx ^ 2] = (uchar)((t >> 8) & ~7); + if( dcn == 4 ) + dst[3] = 255; + } + else + for( int i = 0; i < n; i++, dst += dcn ) + { + unsigned t = ((const ushort*)src)[i]; + dst[bidx] = (uchar)(t << 3); + dst[1] = (uchar)((t >> 2) & ~7); + dst[bidx ^ 2] = (uchar)((t >> 7) & ~7); + if( dcn == 4 ) + dst[3] = t & 0x8000 ? 255 : 0; + } + } + + int dstcn, blueIdx, greenBits; +}; + + +struct RGB2RGB5x5 +{ + typedef uchar channel_type; + + RGB2RGB5x5(int _srccn, int _blueIdx, int _greenBits) + : srccn(_srccn), blueIdx(_blueIdx), greenBits(_greenBits) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int scn = srccn, bidx = blueIdx; + if( greenBits == 6 ) + for( int i = 0; i < n; i++, src += scn ) + { + ((ushort*)dst)[i] = (ushort)((src[bidx] >> 3)|((src[1]&~3) << 3)|((src[bidx^2]&~7) << 8)); + } + else if( scn == 3 ) + for( int i = 0; i < n; i++, src += 3 ) + { + ((ushort*)dst)[i] = (ushort)((src[bidx] >> 3)|((src[1]&~7) << 2)|((src[bidx^2]&~7) << 7)); + } + else + for( int i = 0; i < n; i++, src += 4 ) + { + ((ushort*)dst)[i] = (ushort)((src[bidx] >> 3)|((src[1]&~7) << 2)| + ((src[bidx^2]&~7) << 7)|(src[3] ? 0x8000 : 0)); + } + } + + int srccn, blueIdx, greenBits; +}; + +///////////////////////////////// Color to/from Grayscale //////////////////////////////// + +template +struct Gray2RGB +{ + typedef _Tp channel_type; + + Gray2RGB(int _dstcn) : dstcn(_dstcn) {} + void operator()(const _Tp* src, _Tp* dst, int n) const + { + if( dstcn == 3 ) + for( int i = 0; i < n; i++, dst += 3 ) + { + dst[0] = dst[1] = dst[2] = src[i]; + } + else + { + _Tp alpha = ColorChannel<_Tp>::max(); + for( int i = 0; i < n; i++, dst += 4 ) + { + dst[0] = dst[1] = dst[2] = src[i]; + dst[3] = alpha; + } + } + } + + int dstcn; +}; + + +struct Gray2RGB5x5 +{ + typedef uchar channel_type; + + Gray2RGB5x5(int _greenBits) : greenBits(_greenBits) {} + void operator()(const uchar* src, uchar* dst, int n) const + { + if( greenBits == 6 ) + for( int i = 0; i < n; i++ ) + { + int t = src[i]; + ((ushort*)dst)[i] = (ushort)((t >> 3)|((t & ~3) << 3)|((t & ~7) << 8)); + } + else + for( int i = 0; i < n; i++ ) + { + int t = src[i] >> 3; + ((ushort*)dst)[i] = (ushort)(t|(t << 5)|(t << 10)); + } + } + int greenBits; +}; + + +#undef R2Y +#undef G2Y +#undef B2Y + +enum +{ + yuv_shift = 14, + xyz_shift = 12, + R2Y = 4899, + G2Y = 9617, + B2Y = 1868, + BLOCK_SIZE = 256 +}; + + +struct RGB5x52Gray +{ + typedef uchar channel_type; + + RGB5x52Gray(int _greenBits) : greenBits(_greenBits) {} + void operator()(const uchar* src, uchar* dst, int n) const + { + if( greenBits == 6 ) + for( int i = 0; i < n; i++ ) + { + int t = ((ushort*)src)[i]; + dst[i] = (uchar)CV_DESCALE(((t << 3) & 0xf8)*B2Y + + ((t >> 3) & 0xfc)*G2Y + + ((t >> 8) & 0xf8)*R2Y, yuv_shift); + } + else + for( int i = 0; i < n; i++ ) + { + int t = ((ushort*)src)[i]; + dst[i] = (uchar)CV_DESCALE(((t << 3) & 0xf8)*B2Y + + ((t >> 2) & 0xf8)*G2Y + + ((t >> 7) & 0xf8)*R2Y, yuv_shift); + } + } + int greenBits; +}; + + +template struct RGB2Gray +{ + typedef _Tp channel_type; + + RGB2Gray(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn) + { + static const float coeffs0[] = { 0.299f, 0.587f, 0.114f }; + memcpy( coeffs, _coeffs ? _coeffs : coeffs0, 3*sizeof(coeffs[0]) ); + if(blueIdx == 0) + std::swap(coeffs[0], coeffs[2]); + } + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn; + float cb = coeffs[0], cg = coeffs[1], cr = coeffs[2]; + for(int i = 0; i < n; i++, src += scn) + dst[i] = saturate_cast<_Tp>(src[0]*cb + src[1]*cg + src[2]*cr); + } + int srccn; + float coeffs[3]; +}; + + +template<> struct RGB2Gray +{ + typedef uchar channel_type; + + RGB2Gray(int _srccn, int blueIdx, const int* coeffs) : srccn(_srccn) + { + const int coeffs0[] = { R2Y, G2Y, B2Y }; + if(!coeffs) coeffs = coeffs0; + + int b = 0, g = 0, r = (1 << (yuv_shift-1)); + int db = coeffs[blueIdx^2], dg = coeffs[1], dr = coeffs[blueIdx]; + + for( int i = 0; i < 256; i++, b += db, g += dg, r += dr ) + { + tab[i] = b; + tab[i+256] = g; + tab[i+512] = r; + } + } + void operator()(const uchar* src, uchar* dst, int n) const + { + int scn = srccn; + const int* _tab = tab; + for(int i = 0; i < n; i++, src += scn) + dst[i] = (uchar)((_tab[src[0]] + _tab[src[1]+256] + _tab[src[2]+512]) >> yuv_shift); + } + int srccn; + int tab[256*3]; +}; + + +template<> struct RGB2Gray +{ + typedef ushort channel_type; + + RGB2Gray(int _srccn, int blueIdx, const int* _coeffs) : srccn(_srccn) + { + static const int coeffs0[] = { R2Y, G2Y, B2Y }; + memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 3*sizeof(coeffs[0])); + if( blueIdx == 0 ) + std::swap(coeffs[0], coeffs[2]); + } + + void operator()(const ushort* src, ushort* dst, int n) const + { + int scn = srccn, cb = coeffs[0], cg = coeffs[1], cr = coeffs[2]; + for(int i = 0; i < n; i++, src += scn) + dst[i] = (ushort)CV_DESCALE((unsigned)(src[0]*cb + src[1]*cg + src[2]*cr), yuv_shift); + } + int srccn; + int coeffs[3]; +}; + + +///////////////////////////////////// RGB <-> YCrCb ////////////////////////////////////// + +template struct RGB2YCrCb_f +{ + typedef _Tp channel_type; + + RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx) + { + static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f}; + memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0])); + if(blueIdx==0) std::swap(coeffs[0], coeffs[2]); + } + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn, bidx = blueIdx; + const _Tp delta = ColorChannel<_Tp>::half(); + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4]; + n *= 3; + for(int i = 0; i < n; i += 3, src += scn) + { + _Tp Y = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2); + _Tp Cr = saturate_cast<_Tp>((src[bidx^2] - Y)*C3 + delta); + _Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta); + dst[i] = Y; dst[i+1] = Cr; dst[i+2] = Cb; + } + } + int srccn, blueIdx; + float coeffs[5]; +}; + + +template struct RGB2YCrCb_i +{ + typedef _Tp channel_type; + + RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs) + : srccn(_srccn), blueIdx(_blueIdx) + { + static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241}; + memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0])); + if(blueIdx==0) std::swap(coeffs[0], coeffs[2]); + } + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn, bidx = blueIdx; + int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4]; + int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift); + n *= 3; + for(int i = 0; i < n; i += 3, src += scn) + { + int Y = CV_DESCALE(src[0]*C0 + src[1]*C1 + src[2]*C2, yuv_shift); + int Cr = CV_DESCALE((src[bidx^2] - Y)*C3 + delta, yuv_shift); + int Cb = CV_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift); + dst[i] = saturate_cast<_Tp>(Y); + dst[i+1] = saturate_cast<_Tp>(Cr); + dst[i+2] = saturate_cast<_Tp>(Cb); + } + } + int srccn, blueIdx; + int coeffs[5]; +}; + + +template struct YCrCb2RGB_f +{ + typedef _Tp channel_type; + + YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs) + : dstcn(_dstcn), blueIdx(_blueIdx) + { + static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f}; + memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0])); + } + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int dcn = dstcn, bidx = blueIdx; + const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max(); + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3]; + n *= 3; + for(int i = 0; i < n; i += 3, dst += dcn) + { + _Tp Y = src[i]; + _Tp Cr = src[i+1]; + _Tp Cb = src[i+2]; + + _Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3); + _Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1); + _Tp r = saturate_cast<_Tp>(Y + (Cr - delta)*C0); + + dst[bidx] = b; dst[1] = g; dst[bidx^2] = r; + if( dcn == 4 ) + dst[3] = alpha; + } + } + int dstcn, blueIdx; + float coeffs[4]; +}; + + +template struct YCrCb2RGB_i +{ + typedef _Tp channel_type; + + YCrCb2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs) + : dstcn(_dstcn), blueIdx(_blueIdx) + { + static const int coeffs0[] = {22987, -11698, -5636, 29049}; + memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0])); + } + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int dcn = dstcn, bidx = blueIdx; + const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max(); + int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3]; + n *= 3; + for(int i = 0; i < n; i += 3, dst += dcn) + { + _Tp Y = src[i]; + _Tp Cr = src[i+1]; + _Tp Cb = src[i+2]; + + int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift); + int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift); + int r = Y + CV_DESCALE((Cr - delta)*C0, yuv_shift); + + dst[bidx] = saturate_cast<_Tp>(b); + dst[1] = saturate_cast<_Tp>(g); + dst[bidx^2] = saturate_cast<_Tp>(r); + if( dcn == 4 ) + dst[3] = alpha; + } + } + int dstcn, blueIdx; + int coeffs[4]; +}; + + +////////////////////////////////////// RGB <-> XYZ /////////////////////////////////////// + +static const float sRGB2XYZ_D65[] = +{ + 0.412453f, 0.357580f, 0.180423f, + 0.212671f, 0.715160f, 0.072169f, + 0.019334f, 0.119193f, 0.950227f +}; + +static const float XYZ2sRGB_D65[] = +{ + 3.240479f, -1.53715f, -0.498535f, + -0.969256f, 1.875991f, 0.041556f, + 0.055648f, -0.204043f, 1.057311f +}; + +template struct RGB2XYZ_f +{ + typedef _Tp channel_type; + + RGB2XYZ_f(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn) + { + memcpy(coeffs, _coeffs ? _coeffs : sRGB2XYZ_D65, 9*sizeof(coeffs[0])); + if(blueIdx == 0) + { + std::swap(coeffs[0], coeffs[2]); + std::swap(coeffs[3], coeffs[5]); + std::swap(coeffs[6], coeffs[8]); + } + } + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn; + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + + n *= 3; + for(int i = 0; i < n; i += 3, src += scn) + { + _Tp X = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2); + _Tp Y = saturate_cast<_Tp>(src[0]*C3 + src[1]*C4 + src[2]*C5); + _Tp Z = saturate_cast<_Tp>(src[0]*C6 + src[1]*C7 + src[2]*C8); + dst[i] = X; dst[i+1] = Y; dst[i+2] = Z; + } + } + int srccn; + float coeffs[9]; +}; + + +template struct RGB2XYZ_i +{ + typedef _Tp channel_type; + + RGB2XYZ_i(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn) + { + static const int coeffs0[] = + { + 1689, 1465, 739, + 871, 2929, 296, + 79, 488, 3892 + }; + for( int i = 0; i < 9; i++ ) + coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << xyz_shift)) : coeffs0[i]; + if(blueIdx == 0) + { + std::swap(coeffs[0], coeffs[2]); + std::swap(coeffs[3], coeffs[5]); + std::swap(coeffs[6], coeffs[8]); + } + } + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int scn = srccn; + int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + n *= 3; + for(int i = 0; i < n; i += 3, src += scn) + { + int X = CV_DESCALE(src[0]*C0 + src[1]*C1 + src[2]*C2, xyz_shift); + int Y = CV_DESCALE(src[0]*C3 + src[1]*C4 + src[2]*C5, xyz_shift); + int Z = CV_DESCALE(src[0]*C6 + src[1]*C7 + src[2]*C8, xyz_shift); + dst[i] = saturate_cast<_Tp>(X); dst[i+1] = saturate_cast<_Tp>(Y); + dst[i+2] = saturate_cast<_Tp>(Z); + } + } + int srccn; + int coeffs[9]; +}; + + +template struct XYZ2RGB_f +{ + typedef _Tp channel_type; + + XYZ2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs) + : dstcn(_dstcn), blueIdx(_blueIdx) + { + memcpy(coeffs, _coeffs ? _coeffs : XYZ2sRGB_D65, 9*sizeof(coeffs[0])); + if(blueIdx == 0) + { + std::swap(coeffs[0], coeffs[6]); + std::swap(coeffs[1], coeffs[7]); + std::swap(coeffs[2], coeffs[8]); + } + } + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int dcn = dstcn; + _Tp alpha = ColorChannel<_Tp>::max(); + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + n *= 3; + for(int i = 0; i < n; i += 3, dst += dcn) + { + _Tp B = saturate_cast<_Tp>(src[i]*C0 + src[i+1]*C1 + src[i+2]*C2); + _Tp G = saturate_cast<_Tp>(src[i]*C3 + src[i+1]*C4 + src[i+2]*C5); + _Tp R = saturate_cast<_Tp>(src[i]*C6 + src[i+1]*C7 + src[i+2]*C8); + dst[0] = B; dst[1] = G; dst[2] = R; + if( dcn == 4 ) + dst[3] = alpha; + } + } + int dstcn, blueIdx; + float coeffs[9]; +}; + + +template struct XYZ2RGB_i +{ + typedef _Tp channel_type; + + XYZ2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs) + : dstcn(_dstcn), blueIdx(_blueIdx) + { + static const int coeffs0[] = + { + 13273, -6296, -2042, + -3970, 7684, 170, + 228, -836, 4331 + }; + for(int i = 0; i < 9; i++) + coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << xyz_shift)) : coeffs0[i]; + + if(blueIdx == 0) + { + std::swap(coeffs[0], coeffs[6]); + std::swap(coeffs[1], coeffs[7]); + std::swap(coeffs[2], coeffs[8]); + } + } + void operator()(const _Tp* src, _Tp* dst, int n) const + { + int dcn = dstcn; + _Tp alpha = ColorChannel<_Tp>::max(); + int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + n *= 3; + for(int i = 0; i < n; i += 3, dst += dcn) + { + int B = CV_DESCALE(src[i]*C0 + src[i+1]*C1 + src[i+2]*C2, xyz_shift); + int G = CV_DESCALE(src[i]*C3 + src[i+1]*C4 + src[i+2]*C5, xyz_shift); + int R = CV_DESCALE(src[i]*C6 + src[i+1]*C7 + src[i+2]*C8, xyz_shift); + dst[0] = saturate_cast<_Tp>(B); dst[1] = saturate_cast<_Tp>(G); + dst[2] = saturate_cast<_Tp>(R); + if( dcn == 4 ) + dst[3] = alpha; + } + } + int dstcn, blueIdx; + int coeffs[9]; +}; + + +////////////////////////////////////// RGB <-> HSV /////////////////////////////////////// + + +struct RGB2HSV_b +{ + typedef uchar channel_type; + + RGB2HSV_b(int _srccn, int _blueIdx, int _hrange) + : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) + { + CV_Assert( hrange == 180 || hrange == 256 ); + } + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, bidx = blueIdx, scn = srccn; + const int hsv_shift = 12; + + static int sdiv_table[256]; + static int hdiv_table180[256]; + static int hdiv_table256[256]; + static volatile bool initialized = false; + + int hr = hrange; + const int* hdiv_table = hr == 180 ? hdiv_table180 : hdiv_table256; + n *= 3; + + if( !initialized ) + { + sdiv_table[0] = hdiv_table180[0] = hdiv_table256[0] = 0; + for( i = 1; i < 256; i++ ) + { + sdiv_table[i] = saturate_cast((255 << hsv_shift)/(1.*i)); + hdiv_table180[i] = saturate_cast((180 << hsv_shift)/(6.*i)); + hdiv_table256[i] = saturate_cast((256 << hsv_shift)/(6.*i)); + } + initialized = true; + } + + for( i = 0; i < n; i += 3, src += scn ) + { + int b = src[bidx], g = src[1], r = src[bidx^2]; + int h, s, v = b; + int vmin = b, diff; + int vr, vg; + + CV_CALC_MAX_8U( v, g ); + CV_CALC_MAX_8U( v, r ); + CV_CALC_MIN_8U( vmin, g ); + CV_CALC_MIN_8U( vmin, r ); + + diff = v - vmin; + vr = v == r ? -1 : 0; + vg = v == g ? -1 : 0; + + s = (diff * sdiv_table[v] + (1 << (hsv_shift-1))) >> hsv_shift; + h = (vr & (g - b)) + + (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff)))); + h = (h * hdiv_table[diff] + (1 << (hsv_shift-1))) >> hsv_shift; + h += h < 0 ? hr : 0; + + dst[i] = saturate_cast(h); + dst[i+1] = (uchar)s; + dst[i+2] = (uchar)v; + } + } + + int srccn, blueIdx, hrange; +}; + + +struct RGB2HSV_f +{ + typedef float channel_type; + + RGB2HSV_f(int _srccn, int _blueIdx, float _hrange) + : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) {} + + void operator()(const float* src, float* dst, int n) const + { + int i, bidx = blueIdx, scn = srccn; + float hscale = hrange*(1.f/360.f); + n *= 3; + + for( i = 0; i < n; i += 3, src += scn ) + { + float b = src[bidx], g = src[1], r = src[bidx^2]; + float h, s, v; + + float vmin, diff; + + v = vmin = r; + if( v < g ) v = g; + if( v < b ) v = b; + if( vmin > g ) vmin = g; + if( vmin > b ) vmin = b; + + diff = v - vmin; + s = diff/(float)(fabs(v) + FLT_EPSILON); + diff = (float)(60./(diff + FLT_EPSILON)); + if( v == r ) + h = (g - b)*diff; + else if( v == g ) + h = (b - r)*diff + 120.f; + else + h = (r - g)*diff + 240.f; + + if( h < 0 ) h += 360.f; + + dst[i] = h*hscale; + dst[i+1] = s; + dst[i+2] = v; + } + } + + int srccn, blueIdx; + float hrange; +}; + + +struct HSV2RGB_f +{ + typedef float channel_type; + + HSV2RGB_f(int _dstcn, int _blueIdx, float _hrange) + : dstcn(_dstcn), blueIdx(_blueIdx), hscale(6.f/_hrange) {} + + void operator()(const float* src, float* dst, int n) const + { + int i, bidx = blueIdx, dcn = dstcn; + float _hscale = hscale; + float alpha = ColorChannel::max(); + n *= 3; + + for( i = 0; i < n; i += 3, dst += dcn ) + { + float h = src[i], s = src[i+1], v = src[i+2]; + float b, g, r; + + if( s == 0 ) + b = g = r = v; + else + { + static const int sector_data[][3]= + {{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}}; + float tab[4]; + int sector; + h *= _hscale; + if( h < 0 ) + do h += 6; while( h < 0 ); + else if( h >= 6 ) + do h -= 6; while( h >= 6 ); + sector = cvFloor(h); + h -= sector; + if( (unsigned)sector >= 6u ) + { + sector = 0; + h = 0.f; + } + + tab[0] = v; + tab[1] = v*(1.f - s); + tab[2] = v*(1.f - s*h); + tab[3] = v*(1.f - s*(1.f - h)); + + b = tab[sector_data[sector][0]]; + g = tab[sector_data[sector][1]]; + r = tab[sector_data[sector][2]]; + } + + dst[bidx] = b; + dst[1] = g; + dst[bidx^2] = r; + if( dcn == 4 ) + dst[3] = alpha; + } + } + + int dstcn, blueIdx; + float hscale; +}; + + +struct HSV2RGB_b +{ + typedef uchar channel_type; + + HSV2RGB_b(int _dstcn, int _blueIdx, int _hrange) + : dstcn(_dstcn), cvt(3, _blueIdx, (float)_hrange) + {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, dcn = dstcn; + uchar alpha = ColorChannel::max(); + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3 ) + { + buf[j] = src[j]; + buf[j+1] = src[j+1]*(1.f/255.f); + buf[j+2] = src[j+2]*(1.f/255.f); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3, dst += dcn ) + { + dst[0] = saturate_cast(buf[j]*255.f); + dst[1] = saturate_cast(buf[j+1]*255.f); + dst[2] = saturate_cast(buf[j+2]*255.f); + if( dcn == 4 ) + dst[3] = alpha; + } + } + } + + int dstcn; + HSV2RGB_f cvt; +}; + + +///////////////////////////////////// RGB <-> HLS //////////////////////////////////////// + +struct RGB2HLS_f +{ + typedef float channel_type; + + RGB2HLS_f(int _srccn, int _blueIdx, float _hrange) + : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) {} + + void operator()(const float* src, float* dst, int n) const + { + int i, bidx = blueIdx, scn = srccn; + float hscale = hrange*(1.f/360.f); + n *= 3; + + for( i = 0; i < n; i += 3, src += scn ) + { + float b = src[bidx], g = src[1], r = src[bidx^2]; + float h = 0.f, s = 0.f, l; + float vmin, vmax, diff; + + vmax = vmin = r; + if( vmax < g ) vmax = g; + if( vmax < b ) vmax = b; + if( vmin > g ) vmin = g; + if( vmin > b ) vmin = b; + + diff = vmax - vmin; + l = (vmax + vmin)*0.5f; + + if( diff > FLT_EPSILON ) + { + s = l < 0.5f ? diff/(vmax + vmin) : diff/(2 - vmax - vmin); + diff = 60.f/diff; + + if( vmax == r ) + h = (g - b)*diff; + else if( vmax == g ) + h = (b - r)*diff + 120.f; + else + h = (r - g)*diff + 240.f; + + if( h < 0.f ) h += 360.f; + } + + dst[i] = h*hscale; + dst[i+1] = l; + dst[i+2] = s; + } + } + + int srccn, blueIdx; + float hrange; +}; + + +struct RGB2HLS_b +{ + typedef uchar channel_type; + + RGB2HLS_b(int _srccn, int _blueIdx, int _hrange) + : srccn(_srccn), cvt(3, _blueIdx, (float)_hrange) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, scn = srccn; + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, dst += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3, src += scn ) + { + buf[j] = src[0]*(1.f/255.f); + buf[j+1] = src[1]*(1.f/255.f); + buf[j+2] = src[2]*(1.f/255.f); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3 ) + { + dst[j] = saturate_cast(buf[j]); + dst[j+1] = saturate_cast(buf[j+1]*255.f); + dst[j+2] = saturate_cast(buf[j+2]*255.f); + } + } + } + + int srccn; + RGB2HLS_f cvt; +}; + + +struct HLS2RGB_f +{ + typedef float channel_type; + + HLS2RGB_f(int _dstcn, int _blueIdx, float _hrange) + : dstcn(_dstcn), blueIdx(_blueIdx), hscale(6.f/_hrange) {} + + void operator()(const float* src, float* dst, int n) const + { + int i, bidx = blueIdx, dcn = dstcn; + float _hscale = hscale; + float alpha = ColorChannel::max(); + n *= 3; + + for( i = 0; i < n; i += 3, dst += dcn ) + { + float h = src[i], l = src[i+1], s = src[i+2]; + float b, g, r; + + if( s == 0 ) + b = g = r = l; + else + { + static const int sector_data[][3]= + {{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}}; + float tab[4]; + int sector; + + float p2 = l <= 0.5f ? l*(1 + s) : l + s - l*s; + float p1 = 2*l - p2; + + h *= _hscale; + if( h < 0 ) + do h += 6; while( h < 0 ); + else if( h >= 6 ) + do h -= 6; while( h >= 6 ); + + assert( 0 <= h && h < 6 ); + sector = cvFloor(h); + h -= sector; + + tab[0] = p2; + tab[1] = p1; + tab[2] = p1 + (p2 - p1)*(1-h); + tab[3] = p1 + (p2 - p1)*h; + + b = tab[sector_data[sector][0]]; + g = tab[sector_data[sector][1]]; + r = tab[sector_data[sector][2]]; + } + + dst[bidx] = b; + dst[1] = g; + dst[bidx^2] = r; + if( dcn == 4 ) + dst[3] = alpha; + } + } + + int dstcn, blueIdx; + float hscale; +}; + + +struct HLS2RGB_b +{ + typedef uchar channel_type; + + HLS2RGB_b(int _dstcn, int _blueIdx, int _hrange) + : dstcn(_dstcn), cvt(3, _blueIdx, (float)_hrange) + {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, dcn = dstcn; + uchar alpha = ColorChannel::max(); + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3 ) + { + buf[j] = src[j]; + buf[j+1] = src[j+1]*(1.f/255.f); + buf[j+2] = src[j+2]*(1.f/255.f); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3, dst += dcn ) + { + dst[0] = saturate_cast(buf[j]*255.f); + dst[1] = saturate_cast(buf[j+1]*255.f); + dst[2] = saturate_cast(buf[j+2]*255.f); + if( dcn == 4 ) + dst[3] = alpha; + } + } + } + + int dstcn; + HLS2RGB_f cvt; +}; + + +///////////////////////////////////// RGB <-> L*a*b* ///////////////////////////////////// + +static const float D65[] = { 0.950456f, 1.f, 1.088754f }; + +enum { LAB_CBRT_TAB_SIZE = 1024, GAMMA_TAB_SIZE = 1024 }; +static float LabCbrtTab[LAB_CBRT_TAB_SIZE*4]; +static const float LabCbrtTabScale = LAB_CBRT_TAB_SIZE/1.5f; + +static float sRGBGammaTab[GAMMA_TAB_SIZE*4], sRGBInvGammaTab[GAMMA_TAB_SIZE*4]; +static const float GammaTabScale = (float)GAMMA_TAB_SIZE; + +static ushort sRGBGammaTab_b[256], linearGammaTab_b[256]; +#undef lab_shift +#define lab_shift xyz_shift +#define gamma_shift 3 +#define lab_shift2 (lab_shift + gamma_shift) +#define LAB_CBRT_TAB_SIZE_B (256*3/2*(1<(255.f*(1 << gamma_shift)*(x <= 0.04045f ? x*(1.f/12.92f) : (float)pow((double)(x + 0.055)*(1./1.055), 2.4))); + linearGammaTab_b[i] = (ushort)(i*(1 << gamma_shift)); + } + + for(i = 0; i < LAB_CBRT_TAB_SIZE_B; i++) + { + float x = i*(1.f/(255.f*(1 << gamma_shift))); + LabCbrtTab_b[i] = saturate_cast((1 << lab_shift2)*(x < 0.008856f ? x*7.787f + 0.13793103448275862f : cvCbrt(x))); + } + initialized = true; + } +} + +struct RGB2Lab_b +{ + typedef uchar channel_type; + + RGB2Lab_b(int _srccn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb) + : srccn(_srccn), srgb(_srgb) + { + static volatile int _3 = 3; + initLabTabs(); + + if(!_coeffs) _coeffs = sRGB2XYZ_D65; + if(!_whitept) _whitept = D65; + float scale[] = + { + (1 << lab_shift)/_whitept[0], + (float)(1 << lab_shift), + (1 << lab_shift)/_whitept[2] + }; + + for( int i = 0; i < _3; i++ ) + { + coeffs[i*3+(blueIdx^2)] = cvRound(_coeffs[i*3]*scale[i]); + coeffs[i*3+1] = cvRound(_coeffs[i*3+1]*scale[i]); + coeffs[i*3+blueIdx] = cvRound(_coeffs[i*3+2]*scale[i]); + + CV_Assert( coeffs[i] >= 0 && coeffs[i*3+1] >= 0 && coeffs[i*3+2] >= 0 && + coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 2*(1 << lab_shift) ); + } + } + + void operator()(const uchar* src, uchar* dst, int n) const + { + const int Lscale = (116*255+50)/100; + const int Lshift = -((16*255*(1 << lab_shift2) + 50)/100); + const ushort* tab = srgb ? sRGBGammaTab_b : linearGammaTab_b; + int i, scn = srccn; + int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + n *= 3; + + for( i = 0; i < n; i += 3, src += scn ) + { + int R = tab[src[0]], G = tab[src[1]], B = tab[src[2]]; + int fX = LabCbrtTab_b[CV_DESCALE(R*C0 + G*C1 + B*C2, lab_shift)]; + int fY = LabCbrtTab_b[CV_DESCALE(R*C3 + G*C4 + B*C5, lab_shift)]; + int fZ = LabCbrtTab_b[CV_DESCALE(R*C6 + G*C7 + B*C8, lab_shift)]; + + int L = CV_DESCALE( Lscale*fY + Lshift, lab_shift2 ); + int a = CV_DESCALE( 500*(fX - fY) + 128*(1 << lab_shift2), lab_shift2 ); + int b = CV_DESCALE( 200*(fY - fZ) + 128*(1 << lab_shift2), lab_shift2 ); + + dst[i] = saturate_cast(L); + dst[i+1] = saturate_cast(a); + dst[i+2] = saturate_cast(b); + } + } + + int srccn; + int coeffs[9]; + bool srgb; +}; + + +#define clip(value) \ + value < 0.0f ? 0.0f : value > 1.0f ? 1.0f : value; + +struct RGB2Lab_f +{ + typedef float channel_type; + + RGB2Lab_f(int _srccn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb) + : srccn(_srccn), srgb(_srgb) + { + volatile int _3 = 3; + initLabTabs(); + + if (!_coeffs) + _coeffs = sRGB2XYZ_D65; + if (!_whitept) + _whitept = D65; + + float scale[] = { 1.0f / _whitept[0], 1.0f, 1.0f / _whitept[2] }; + + for( int i = 0; i < _3; i++ ) + { + int j = i * 3; + coeffs[j + (blueIdx ^ 2)] = _coeffs[j] * scale[i]; + coeffs[j + 1] = _coeffs[j + 1] * scale[i]; + coeffs[j + blueIdx] = _coeffs[j + 2] * scale[i]; + + CV_Assert( coeffs[j] >= 0 && coeffs[j + 1] >= 0 && coeffs[j + 2] >= 0 && + coeffs[j] + coeffs[j + 1] + coeffs[j + 2] < 1.5f*LabCbrtTabScale ); + } + } + + void operator()(const float* src, float* dst, int n) const + { + int i, scn = srccn; + float gscale = GammaTabScale; + const float* gammaTab = srgb ? sRGBGammaTab : 0; + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + n *= 3; + + static const float _1_3 = 1.0f / 3.0f; + static const float _a = 16.0f / 116.0f; + for (i = 0; i < n; i += 3, src += scn ) + { + float R = clip(src[0]); + float G = clip(src[1]); + float B = clip(src[2]); + +// CV_Assert(R >= 0.0f && R <= 1.0f); +// CV_Assert(G >= 0.0f && G <= 1.0f); +// CV_Assert(B >= 0.0f && B <= 1.0f); + + if (gammaTab) + { + R = splineInterpolate(R * gscale, gammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G * gscale, gammaTab, GAMMA_TAB_SIZE); + B = splineInterpolate(B * gscale, gammaTab, GAMMA_TAB_SIZE); + } + float X = R*C0 + G*C1 + B*C2; + float Y = R*C3 + G*C4 + B*C5; + float Z = R*C6 + G*C7 + B*C8; + + float FX = X > 0.008856f ? pow(X, _1_3) : (7.787f * X + _a); + float FY = Y > 0.008856f ? pow(Y, _1_3) : (7.787f * Y + _a); + float FZ = Z > 0.008856f ? pow(Z, _1_3) : (7.787f * Z + _a); + + float L = Y > 0.008856f ? (116.f * FY - 16.f) : (903.3f * Y); + float a = 500.f * (FX - FY); + float b = 200.f * (FY - FZ); + + dst[i] = L; + dst[i + 1] = a; + dst[i + 2] = b; + } + } + + int srccn; + float coeffs[9]; + bool srgb; +}; + +struct Lab2RGB_f +{ + typedef float channel_type; + + Lab2RGB_f( int _dstcn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb ) + : dstcn(_dstcn), srgb(_srgb), blueInd(blueIdx) + { + initLabTabs(); + + if(!_coeffs) + _coeffs = XYZ2sRGB_D65; + if(!_whitept) + _whitept = D65; + + for( int i = 0; i < 3; i++ ) + { + coeffs[i+(blueIdx^2)*3] = _coeffs[i]*_whitept[i]; + coeffs[i+3] = _coeffs[i+3]*_whitept[i]; + coeffs[i+blueIdx*3] = _coeffs[i+6]*_whitept[i]; + } + } + + void operator()(const float* src, float* dst, int n) const + { + int i, dcn = dstcn; + const float* gammaTab = srgb ? sRGBInvGammaTab : 0; + float gscale = GammaTabScale; + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + float alpha = ColorChannel::max(); + n *= 3; + + static const float lThresh = 0.008856f * 903.3f; + static const float fThresh = 7.787f * 0.008856f + 16.0f / 116.0f; + for (i = 0; i < n; i += 3, dst += dcn) + { + float li = src[i]; + float ai = src[i + 1]; + float bi = src[i + 2]; + + float y, fy; + if (li <= lThresh) + { + y = li / 903.3f; + fy = 7.787f * y + 16.0f / 116.0f; + } + else + { + fy = (li + 16.0f) / 116.0f; + y = fy * fy * fy; + } + + float fxz[] = { ai / 500.0f + fy, fy - bi / 200.0f }; + + for (int j = 0; j < 2; j++) + if (fxz[j] <= fThresh) + fxz[j] = (fxz[j] - 16.0f / 116.0f) / 7.787f; + else + fxz[j] = fxz[j] * fxz[j] * fxz[j]; + + + float x = fxz[0], z = fxz[1]; + float ro = clip(C0 * x + C1 * y + C2 * z); + float go = clip(C3 * x + C4 * y + C5 * z); + float bo = clip(C6 * x + C7 * y + C8 * z); + +// CV_Assert(ro >= 0.0f && ro <= 1.0f); +// CV_Assert(go >= 0.0f && go <= 1.0f); +// CV_Assert(bo >= 0.0f && bo <= 1.0f); + + if (gammaTab) + { + ro = splineInterpolate(ro * gscale, gammaTab, GAMMA_TAB_SIZE); + go = splineInterpolate(go * gscale, gammaTab, GAMMA_TAB_SIZE); + bo = splineInterpolate(bo * gscale, gammaTab, GAMMA_TAB_SIZE); + } + + dst[0] = ro, dst[1] = go, dst[2] = bo; + if( dcn == 4 ) + dst[3] = alpha; + } + } + + int dstcn; + float coeffs[9]; + bool srgb; + int blueInd; +}; + +#undef clip + +struct Lab2RGB_b +{ + typedef uchar channel_type; + + Lab2RGB_b( int _dstcn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb ) + : dstcn(_dstcn), cvt(3, blueIdx, _coeffs, _whitept, _srgb ) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, dcn = dstcn; + uchar alpha = ColorChannel::max(); + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3 ) + { + buf[j] = src[j]*(100.f/255.f); + buf[j+1] = (float)(src[j+1] - 128); + buf[j+2] = (float)(src[j+2] - 128); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3, dst += dcn ) + { + dst[0] = saturate_cast(buf[j]*255.f); + dst[1] = saturate_cast(buf[j+1]*255.f); + dst[2] = saturate_cast(buf[j+2]*255.f); + if( dcn == 4 ) + dst[3] = alpha; + } + } + } + + int dstcn; + Lab2RGB_f cvt; +}; + + +///////////////////////////////////// RGB <-> L*u*v* ///////////////////////////////////// + +struct RGB2Luv_f +{ + typedef float channel_type; + + RGB2Luv_f( int _srccn, int blueIdx, const float* _coeffs, + const float* whitept, bool _srgb ) + : srccn(_srccn), srgb(_srgb) + { + volatile int i; + initLabTabs(); + + if(!_coeffs) _coeffs = sRGB2XYZ_D65; + if(!whitept) whitept = D65; + + for( i = 0; i < 3; i++ ) + { + coeffs[i*3] = _coeffs[i*3]; + coeffs[i*3+1] = _coeffs[i*3+1]; + coeffs[i*3+2] = _coeffs[i*3+2]; + if( blueIdx == 0 ) + std::swap(coeffs[i*3], coeffs[i*3+2]); + CV_Assert( coeffs[i*3] >= 0 && coeffs[i*3+1] >= 0 && coeffs[i*3+2] >= 0 && + coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 1.5f ); + } + + float d = 1.f/(whitept[0] + whitept[1]*15 + whitept[2]*3); + un = 4*whitept[0]*d; + vn = 9*whitept[1]*d; + + CV_Assert(whitept[1] == 1.f); + } + + void operator()(const float* src, float* dst, int n) const + { + int i, scn = srccn; + float gscale = GammaTabScale; + const float* gammaTab = srgb ? sRGBGammaTab : 0; + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + float _un = 13*un, _vn = 13*vn; + n *= 3; + + for( i = 0; i < n; i += 3, src += scn ) + { + float R = src[0], G = src[1], B = src[2]; + if( gammaTab ) + { + R = splineInterpolate(R*gscale, gammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE); + B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE); + } + + float X = R*C0 + G*C1 + B*C2; + float Y = R*C3 + G*C4 + B*C5; + float Z = R*C6 + G*C7 + B*C8; + + float L = splineInterpolate(Y*LabCbrtTabScale, LabCbrtTab, LAB_CBRT_TAB_SIZE); + L = 116.f*L - 16.f; + + float d = (4*13) / std::max(X + 15 * Y + 3 * Z, FLT_EPSILON); + float u = L*(X*d - _un); + float v = L*((9*0.25f)*Y*d - _vn); + + dst[i] = L; dst[i+1] = u; dst[i+2] = v; + } + } + + int srccn; + float coeffs[9], un, vn; + bool srgb; +}; + + +struct Luv2RGB_f +{ + typedef float channel_type; + + Luv2RGB_f( int _dstcn, int blueIdx, const float* _coeffs, + const float* whitept, bool _srgb ) + : dstcn(_dstcn), srgb(_srgb) + { + initLabTabs(); + + if(!_coeffs) _coeffs = XYZ2sRGB_D65; + if(!whitept) whitept = D65; + + for( int i = 0; i < 3; i++ ) + { + coeffs[i+(blueIdx^2)*3] = _coeffs[i]; + coeffs[i+3] = _coeffs[i+3]; + coeffs[i+blueIdx*3] = _coeffs[i+6]; + } + + float d = 1.f/(whitept[0] + whitept[1]*15 + whitept[2]*3); + un = 4*whitept[0]*d; + vn = 9*whitept[1]*d; + + CV_Assert(whitept[1] == 1.f); + } + + void operator()(const float* src, float* dst, int n) const + { + int i, dcn = dstcn; + const float* gammaTab = srgb ? sRGBInvGammaTab : 0; + float gscale = GammaTabScale; + float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + float alpha = ColorChannel::max(); + float _un = un, _vn = vn; + n *= 3; + + for( i = 0; i < n; i += 3, dst += dcn ) + { + float L = src[i], u = src[i+1], v = src[i+2], d, X, Y, Z; + Y = (L + 16.f) * (1.f/116.f); + Y = Y*Y*Y; + d = (1.f/13.f)/L; + u = u*d + _un; + v = v*d + _vn; + float iv = 1.f/v; + X = 2.25f * u * Y * iv ; + Z = (12 - 3 * u - 20 * v) * Y * 0.25f * iv; + + float R = X*C0 + Y*C1 + Z*C2; + float G = X*C3 + Y*C4 + Z*C5; + float B = X*C6 + Y*C7 + Z*C8; + + if( gammaTab ) + { + R = splineInterpolate(R*gscale, gammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE); + B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE); + } + + dst[0] = R; dst[1] = G; dst[2] = B; + if( dcn == 4 ) + dst[3] = alpha; + } + } + + int dstcn; + float coeffs[9], un, vn; + bool srgb; +}; + + +struct RGB2Luv_b +{ + typedef uchar channel_type; + + RGB2Luv_b( int _srccn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb ) + : srccn(_srccn), cvt(3, blueIdx, _coeffs, _whitept, _srgb) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, scn = srccn; + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, dst += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3, src += scn ) + { + buf[j] = src[0]*(1.f/255.f); + buf[j+1] = (float)(src[1]*(1.f/255.f)); + buf[j+2] = (float)(src[2]*(1.f/255.f)); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3 ) + { + dst[j] = saturate_cast(buf[j]*2.55f); + dst[j+1] = saturate_cast(buf[j+1]*0.72033898305084743f + 96.525423728813564f); + dst[j+2] = saturate_cast(buf[j+2]*0.99609375f + 139.453125f); + } + } + } + + int srccn; + RGB2Luv_f cvt; +}; + + +struct Luv2RGB_b +{ + typedef uchar channel_type; + + Luv2RGB_b( int _dstcn, int blueIdx, const float* _coeffs, + const float* _whitept, bool _srgb ) + : dstcn(_dstcn), cvt(3, blueIdx, _coeffs, _whitept, _srgb ) {} + + void operator()(const uchar* src, uchar* dst, int n) const + { + int i, j, dcn = dstcn; + uchar alpha = ColorChannel::max(); + float buf[3*BLOCK_SIZE]; + + for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 ) + { + int dn = std::min(n - i, (int)BLOCK_SIZE); + + for( j = 0; j < dn*3; j += 3 ) + { + buf[j] = src[j]*(100.f/255.f); + buf[j+1] = (float)(src[j+1]*1.388235294117647f - 134.f); + buf[j+2] = (float)(src[j+2]*1.003921568627451f - 140.f); + } + cvt(buf, buf, dn); + + for( j = 0; j < dn*3; j += 3, dst += dcn ) + { + dst[0] = saturate_cast(buf[j]*255.f); + dst[1] = saturate_cast(buf[j+1]*255.f); + dst[2] = saturate_cast(buf[j+2]*255.f); + if( dcn == 4 ) + dst[3] = alpha; + } + } + } + + int dstcn; + Luv2RGB_f cvt; +}; + + +//////////////////////////// Bayer Pattern -> RGB conversion ///////////////////////////// + +template +class SIMDBayerStubInterpolator_ +{ +public: + int bayer2Gray(const T*, int, T*, int, int, int, int) const + { + return 0; + } + + int bayer2RGB(const T*, int, T*, int, int) const + { + return 0; + } +}; + +#if CV_SSE2 +class SIMDBayerInterpolator_8u +{ +public: + SIMDBayerInterpolator_8u() + { + use_simd = checkHardwareSupport(CV_CPU_SSE2); + } + + int bayer2Gray(const uchar* bayer, int bayer_step, uchar* dst, + int width, int bcoeff, int gcoeff, int rcoeff) const + { + if( !use_simd ) + return 0; + + __m128i _b2y = _mm_set1_epi16((short)(rcoeff*2)); + __m128i _g2y = _mm_set1_epi16((short)(gcoeff*2)); + __m128i _r2y = _mm_set1_epi16((short)(bcoeff*2)); + const uchar* bayer_end = bayer + width; + + for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); + __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); + __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); + + __m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 7), + _mm_srli_epi16(_mm_slli_epi16(r2, 8), 7)); + __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); + b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1); + + __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 7), _mm_srli_epi16(r2, 7)); + __m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 7); + g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); + g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2); + + r0 = _mm_srli_epi16(r1, 8); + r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 2); + r0 = _mm_slli_epi16(r0, 3); + + g0 = _mm_add_epi16(_mm_mulhi_epi16(b0, _b2y), _mm_mulhi_epi16(g0, _g2y)); + g1 = _mm_add_epi16(_mm_mulhi_epi16(b1, _b2y), _mm_mulhi_epi16(g1, _g2y)); + g0 = _mm_add_epi16(g0, _mm_mulhi_epi16(r0, _r2y)); + g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(r1, _r2y)); + g0 = _mm_srli_epi16(g0, 2); + g1 = _mm_srli_epi16(g1, 2); + g0 = _mm_packus_epi16(g0, g0); + g1 = _mm_packus_epi16(g1, g1); + g0 = _mm_unpacklo_epi8(g0, g1); + _mm_storeu_si128((__m128i*)dst, g0); + } + + return (int)(bayer - (bayer_end - width)); + } + + int bayer2RGB(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const + { + if( !use_simd ) + return 0; + /* + B G B G | B G B G | B G B G | B G B G + G R G R | G R G R | G R G R | G R G R + B G B G | B G B G | B G B G | B G B G + */ + __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2); + __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128(); + __m128i masklo = _mm_set1_epi16(0x00ff); + const uchar* bayer_end = bayer + width; + + for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); + __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); + __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); + + __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo)); + __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); + b1 = _mm_srli_si128(b1, 2); + b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1); + b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2); + b0 = _mm_packus_epi16(b0, b1); + + __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8)); + __m128i g1 = _mm_and_si128(r1, masklo); + g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); + g1 = _mm_srli_si128(g1, 2); + g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2); + g0 = _mm_packus_epi16(g0, g1); + + r0 = _mm_srli_epi16(r1, 8); + r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2)); + r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1); + r0 = _mm_packus_epi16(r0, r1); + + b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask); + b0 = _mm_xor_si128(b0, b1); + r0 = _mm_xor_si128(r0, b1); + + // b1 g1 b1 g1 ... + b1 = _mm_unpackhi_epi8(b0, g0); + // b0 g0 b2 g2 b4 g4 .... + b0 = _mm_unpacklo_epi8(b0, g0); + + // r1 0 r3 0 ... + r1 = _mm_unpackhi_epi8(r0, z); + // r0 0 r2 0 r4 0 ... + r0 = _mm_unpacklo_epi8(r0, z); + + // 0 b0 g0 r0 0 b2 g2 r2 0 ... + g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1); + // 0 b8 g8 r8 0 b10 g10 r10 0 ... + g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1); + + // b1 g1 r1 0 b3 g3 r3 .... + r0 = _mm_unpacklo_epi16(b1, r1); + // b9 g9 r9 0 ... + r1 = _mm_unpackhi_epi16(b1, r1); + + b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1); + b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1); + + _mm_storel_epi64((__m128i*)(dst-1+0), b0); + _mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8)); + _mm_storel_epi64((__m128i*)(dst-1+6*2), b1); + _mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8)); + + g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1); + g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1); + + _mm_storel_epi64((__m128i*)(dst-1+6*4), g0); + _mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8)); + + _mm_storel_epi64((__m128i*)(dst-1+6*6), g1); + } + + return (int)(bayer - (bayer_end - width)); + } + + bool use_simd; +}; +#else +typedef SIMDBayerStubInterpolator_ SIMDBayerInterpolator_8u; +#endif + +template +static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code ) +{ + SIMDInterpolator vecOp; + const int R2Y = 4899; + const int G2Y = 9617; + const int B2Y = 1868; + const int SHIFT = 14; + + const T* bayer0 = (const T*)srcmat.data; + int bayer_step = (int)(srcmat.step/sizeof(T)); + T* dst0 = (T*)dstmat.data; + int dst_step = (int)(dstmat.step/sizeof(T)); + Size size = srcmat.size(); + int bcoeff = B2Y, rcoeff = R2Y; + int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY; + bool brow = true; + + if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY ) + { + brow = false; + std::swap(bcoeff, rcoeff); + } + + dst0 += dst_step + 1; + size.height -= 2; + size.width -= 2; + + for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) + { + unsigned t0, t1, t2; + const T* bayer = bayer0; + T* dst = dst0; + const T* bayer_end = bayer + size.width; + + if( size.width <= 0 ) + { + dst[-1] = dst[size.width] = 0; + continue; + } + + if( start_with_green ) + { + t0 = (bayer[1] + bayer[bayer_step*2+1])*rcoeff; + t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff; + t2 = bayer[bayer_step+1]*(2*G2Y); + + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1); + bayer++; + dst++; + } + + int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff); + bayer += delta; + dst += delta; + + for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; + t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y; + t2 = bayer[bayer_step+1]*(4*bcoeff); + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2); + + t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff; + t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff; + t2 = bayer[bayer_step+2]*(2*G2Y); + dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1); + } + + if( bayer < bayer_end ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; + t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y; + t2 = bayer[bayer_step+1]*(4*bcoeff); + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2); + bayer++; + dst++; + } + + dst0[-1] = dst0[0]; + dst0[size.width] = dst0[size.width-1]; + + brow = !brow; + std::swap(bcoeff, rcoeff); + start_with_green = !start_with_green; + } + + size = dstmat.size(); + dst0 = (T*)dstmat.data; + if( size.height > 2 ) + for( int i = 0; i < size.width; i++ ) + { + dst0[i] = dst0[i + dst_step]; + dst0[i + (size.height-1)*dst_step] = dst0[i + (size.height-2)*dst_step]; + } + else + for( int i = 0; i < size.width; i++ ) + { + dst0[i] = dst0[i + (size.height-1)*dst_step] = 0; + } +} + +template +static void Bayer2RGB_( const Mat& srcmat, Mat& dstmat, int code ) +{ + SIMDInterpolator vecOp; + const T* bayer0 = (const T*)srcmat.data; + int bayer_step = (int)(srcmat.step/sizeof(T)); + T* dst0 = (T*)dstmat.data; + int dst_step = (int)(dstmat.step/sizeof(T)); + Size size = srcmat.size(); + int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1; + int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR; + + dst0 += dst_step + 3 + 1; + size.height -= 2; + size.width -= 2; + + for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) + { + int t0, t1; + const T* bayer = bayer0; + T* dst = dst0; + const T* bayer_end = bayer + size.width; + + if( size.width <= 0 ) + { + dst[-4] = dst[-3] = dst[-2] = dst[size.width*3-1] = + dst[size.width*3] = dst[size.width*3+1] = 0; + continue; + } + + if( start_with_green ) + { + t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1; + t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1; + dst[-blue] = (T)t0; + dst[0] = bayer[bayer_step+1]; + dst[blue] = (T)t1; + bayer++; + dst += 3; + } + + int delta = vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue); + bayer += delta; + dst += delta*3; + + if( blue > 0 ) + { + for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + bayer[bayer_step*2+2] + 2) >> 2; + t1 = (bayer[1] + bayer[bayer_step] + + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; + dst[-1] = (T)t0; + dst[0] = (T)t1; + dst[1] = bayer[bayer_step+1]; + + t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; + t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; + dst[2] = (T)t0; + dst[3] = bayer[bayer_step+2]; + dst[4] = (T)t1; + } + } + else + { + for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + bayer[bayer_step*2+2] + 2) >> 2; + t1 = (bayer[1] + bayer[bayer_step] + + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; + dst[1] = (T)t0; + dst[0] = (T)t1; + dst[-1] = bayer[bayer_step+1]; + + t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; + t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; + dst[4] = (T)t0; + dst[3] = bayer[bayer_step+2]; + dst[2] = (T)t1; + } + } + + if( bayer < bayer_end ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + bayer[bayer_step*2+2] + 2) >> 2; + t1 = (bayer[1] + bayer[bayer_step] + + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; + dst[-blue] = (T)t0; + dst[0] = (T)t1; + dst[blue] = bayer[bayer_step+1]; + bayer++; + dst += 3; + } + + dst0[-4] = dst0[-1]; + dst0[-3] = dst0[0]; + dst0[-2] = dst0[1]; + dst0[size.width*3-1] = dst0[size.width*3-4]; + dst0[size.width*3] = dst0[size.width*3-3]; + dst0[size.width*3+1] = dst0[size.width*3-2]; + + blue = -blue; + start_with_green = !start_with_green; + } + + size = dstmat.size(); + dst0 = (T*)dstmat.data; + if( size.height > 2 ) + for( int i = 0; i < size.width*3; i++ ) + { + dst0[i] = dst0[i + dst_step]; + dst0[i + (size.height-1)*dst_step] = dst0[i + (size.height-2)*dst_step]; + } + else + for( int i = 0; i < size.width*3; i++ ) + { + dst0[i] = dst0[i + (size.height-1)*dst_step] = 0; + } +} + + +/////////////////// Demosaicing using Variable Number of Gradients /////////////////////// + +static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code ) +{ + const uchar* bayer = srcmat.data; + int bstep = (int)srcmat.step; + uchar* dst = dstmat.data; + int dststep = (int)dstmat.step; + Size size = srcmat.size(); + + int blueIdx = code == CV_BayerBG2BGR_VNG || code == CV_BayerGB2BGR_VNG ? 0 : 2; + bool greenCell0 = code != CV_BayerBG2BGR_VNG && code != CV_BayerRG2BGR_VNG; + + // for too small images use the simple interpolation algorithm + if( MIN(size.width, size.height) < 8 ) + { + Bayer2RGB_( srcmat, dstmat, code ); + return; + } + + const int brows = 3, bcn = 7; + int N = size.width, N2 = N*2, N3 = N*3, N4 = N*4, N5 = N*5, N6 = N*6, N7 = N*7; + int i, bufstep = N7*bcn; + cv::AutoBuffer _buf(bufstep*brows); + ushort* buf = (ushort*)_buf; + + bayer += bstep*2; + +#if CV_SSE2 + bool haveSSE = cv::checkHardwareSupport(CV_CPU_SSE2); + #define _mm_absdiff_epu16(a,b) _mm_adds_epu16(_mm_subs_epu16(a, b), _mm_subs_epu16(b, a)) +#endif + + for( int y = 2; y < size.height - 4; y++ ) + { + uchar* dstrow = dst + dststep*y + 6; + const uchar* srow; + + for( int dy = (y == 2 ? -1 : 1); dy <= 1; dy++ ) + { + ushort* brow = buf + ((y + dy - 1)%brows)*bufstep + 1; + srow = bayer + (y+dy)*bstep + 1; + + for( i = 0; i < bcn; i++ ) + brow[N*i-1] = brow[(N-2) + N*i] = 0; + + i = 1; + +#if CV_SSE2 + if( haveSSE ) + { + __m128i z = _mm_setzero_si128(); + for( ; i <= N-9; i += 8, srow += 8, brow += 8 ) + { + __m128i s1, s2, s3, s4, s6, s7, s8, s9; + + s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1-bstep)),z); + s2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-bstep)),z); + s3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1-bstep)),z); + + s4 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1)),z); + s6 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1)),z); + + s7 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1+bstep)),z); + s8 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+bstep)),z); + s9 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1+bstep)),z); + + __m128i b0, b1, b2, b3, b4, b5, b6; + + b0 = _mm_adds_epu16(_mm_slli_epi16(_mm_absdiff_epu16(s2,s8),1), + _mm_adds_epu16(_mm_absdiff_epu16(s1, s7), + _mm_absdiff_epu16(s3, s9))); + b1 = _mm_adds_epu16(_mm_slli_epi16(_mm_absdiff_epu16(s4,s6),1), + _mm_adds_epu16(_mm_absdiff_epu16(s1, s3), + _mm_absdiff_epu16(s7, s9))); + b2 = _mm_slli_epi16(_mm_absdiff_epu16(s3,s7),1); + b3 = _mm_slli_epi16(_mm_absdiff_epu16(s1,s9),1); + + _mm_storeu_si128((__m128i*)brow, b0); + _mm_storeu_si128((__m128i*)(brow + N), b1); + _mm_storeu_si128((__m128i*)(brow + N2), b2); + _mm_storeu_si128((__m128i*)(brow + N3), b3); + + b4 = _mm_adds_epu16(b2,_mm_adds_epu16(_mm_absdiff_epu16(s2, s4), + _mm_absdiff_epu16(s6, s8))); + b5 = _mm_adds_epu16(b3,_mm_adds_epu16(_mm_absdiff_epu16(s2, s6), + _mm_absdiff_epu16(s4, s8))); + b6 = _mm_adds_epu16(_mm_adds_epu16(s2, s4), _mm_adds_epu16(s6, s8)); + b6 = _mm_srli_epi16(b6, 1); + + _mm_storeu_si128((__m128i*)(brow + N4), b4); + _mm_storeu_si128((__m128i*)(brow + N5), b5); + _mm_storeu_si128((__m128i*)(brow + N6), b6); + } + } +#endif + + for( ; i < N-1; i++, srow++, brow++ ) + { + brow[0] = (ushort)(std::abs(srow[-1-bstep] - srow[-1+bstep]) + + std::abs(srow[-bstep] - srow[+bstep])*2 + + std::abs(srow[1-bstep] - srow[1+bstep])); + brow[N] = (ushort)(std::abs(srow[-1-bstep] - srow[1-bstep]) + + std::abs(srow[-1] - srow[1])*2 + + std::abs(srow[-1+bstep] - srow[1+bstep])); + brow[N2] = (ushort)(std::abs(srow[+1-bstep] - srow[-1+bstep])*2); + brow[N3] = (ushort)(std::abs(srow[-1-bstep] - srow[1+bstep])*2); + brow[N4] = (ushort)(brow[N2] + std::abs(srow[-bstep] - srow[-1]) + + std::abs(srow[+bstep] - srow[1])); + brow[N5] = (ushort)(brow[N3] + std::abs(srow[-bstep] - srow[1]) + + std::abs(srow[+bstep] - srow[-1])); + brow[N6] = (ushort)((srow[-bstep] + srow[-1] + srow[1] + srow[+bstep])>>1); + } + } + + const ushort* brow0 = buf + ((y - 2) % brows)*bufstep + 2; + const ushort* brow1 = buf + ((y - 1) % brows)*bufstep + 2; + const ushort* brow2 = buf + (y % brows)*bufstep + 2; + static const float scale[] = { 0.f, 0.5f, 0.25f, 0.1666666666667f, 0.125f, 0.1f, 0.08333333333f, 0.0714286f, 0.0625f }; + srow = bayer + y*bstep + 2; + bool greenCell = greenCell0; + + i = 2; +#if CV_SSE2 + int limit = !haveSSE ? N-2 : greenCell ? std::min(3, N-2) : 2; +#else + int limit = N - 2; +#endif + + do + { + for( ; i < limit; i++, srow++, brow0++, brow1++, brow2++, dstrow += 3 ) + { + int gradN = brow0[0] + brow1[0]; + int gradS = brow1[0] + brow2[0]; + int gradW = brow1[N-1] + brow1[N]; + int gradE = brow1[N] + brow1[N+1]; + int minGrad = std::min(std::min(std::min(gradN, gradS), gradW), gradE); + int maxGrad = std::max(std::max(std::max(gradN, gradS), gradW), gradE); + int R, G, B; + + if( !greenCell ) + { + int gradNE = brow0[N4+1] + brow1[N4]; + int gradSW = brow1[N4] + brow2[N4-1]; + int gradNW = brow0[N5-1] + brow1[N5]; + int gradSE = brow1[N5] + brow2[N5+1]; + + minGrad = std::min(std::min(std::min(std::min(minGrad, gradNE), gradSW), gradNW), gradSE); + maxGrad = std::max(std::max(std::max(std::max(maxGrad, gradNE), gradSW), gradNW), gradSE); + int T = minGrad + MAX(maxGrad/2, 1); + + int Rs = 0, Gs = 0, Bs = 0, ng = 0; + if( gradN < T ) + { + Rs += srow[-bstep*2] + srow[0]; + Gs += srow[-bstep]*2; + Bs += srow[-bstep-1] + srow[-bstep+1]; + ng++; + } + if( gradS < T ) + { + Rs += srow[bstep*2] + srow[0]; + Gs += srow[bstep]*2; + Bs += srow[bstep-1] + srow[bstep+1]; + ng++; + } + if( gradW < T ) + { + Rs += srow[-2] + srow[0]; + Gs += srow[-1]*2; + Bs += srow[-bstep-1] + srow[bstep-1]; + ng++; + } + if( gradE < T ) + { + Rs += srow[2] + srow[0]; + Gs += srow[1]*2; + Bs += srow[-bstep+1] + srow[bstep+1]; + ng++; + } + if( gradNE < T ) + { + Rs += srow[-bstep*2+2] + srow[0]; + Gs += brow0[N6+1]; + Bs += srow[-bstep+1]*2; + ng++; + } + if( gradSW < T ) + { + Rs += srow[bstep*2-2] + srow[0]; + Gs += brow2[N6-1]; + Bs += srow[bstep-1]*2; + ng++; + } + if( gradNW < T ) + { + Rs += srow[-bstep*2-2] + srow[0]; + Gs += brow0[N6-1]; + Bs += srow[-bstep+1]*2; + ng++; + } + if( gradSE < T ) + { + Rs += srow[bstep*2+2] + srow[0]; + Gs += brow2[N6+1]; + Bs += srow[-bstep+1]*2; + ng++; + } + R = srow[0]; + G = R + cvRound((Gs - Rs)*scale[ng]); + B = R + cvRound((Bs - Rs)*scale[ng]); + } + else + { + int gradNE = brow0[N2] + brow0[N2+1] + brow1[N2] + brow1[N2+1]; + int gradSW = brow1[N2] + brow1[N2-1] + brow2[N2] + brow2[N2-1]; + int gradNW = brow0[N3] + brow0[N3-1] + brow1[N3] + brow1[N3-1]; + int gradSE = brow1[N3] + brow1[N3+1] + brow2[N3] + brow2[N3+1]; + + minGrad = std::min(std::min(std::min(std::min(minGrad, gradNE), gradSW), gradNW), gradSE); + maxGrad = std::max(std::max(std::max(std::max(maxGrad, gradNE), gradSW), gradNW), gradSE); + int T = minGrad + MAX(maxGrad/2, 1); + + int Rs = 0, Gs = 0, Bs = 0, ng = 0; + if( gradN < T ) + { + Rs += srow[-bstep*2-1] + srow[-bstep*2+1]; + Gs += srow[-bstep*2] + srow[0]; + Bs += srow[-bstep]*2; + ng++; + } + if( gradS < T ) + { + Rs += srow[bstep*2-1] + srow[bstep*2+1]; + Gs += srow[bstep*2] + srow[0]; + Bs += srow[bstep]*2; + ng++; + } + if( gradW < T ) + { + Rs += srow[-1]*2; + Gs += srow[-2] + srow[0]; + Bs += srow[-bstep-2]+srow[bstep-2]; + ng++; + } + if( gradE < T ) + { + Rs += srow[1]*2; + Gs += srow[2] + srow[0]; + Bs += srow[-bstep+2]+srow[bstep+2]; + ng++; + } + if( gradNE < T ) + { + Rs += srow[-bstep*2+1] + srow[1]; + Gs += srow[-bstep+1]*2; + Bs += srow[-bstep] + srow[-bstep+2]; + ng++; + } + if( gradSW < T ) + { + Rs += srow[bstep*2-1] + srow[-1]; + Gs += srow[bstep-1]*2; + Bs += srow[bstep] + srow[bstep-2]; + ng++; + } + if( gradNW < T ) + { + Rs += srow[-bstep*2-1] + srow[-1]; + Gs += srow[-bstep-1]*2; + Bs += srow[-bstep-2]+srow[-bstep]; + ng++; + } + if( gradSE < T ) + { + Rs += srow[bstep*2+1] + srow[1]; + Gs += srow[bstep+1]*2; + Bs += srow[bstep+2]+srow[bstep]; + ng++; + } + G = srow[0]; + R = G + cvRound((Rs - Gs)*scale[ng]); + B = G + cvRound((Bs - Gs)*scale[ng]); + } + dstrow[blueIdx] = CV_CAST_8U(B); + dstrow[1] = CV_CAST_8U(G); + dstrow[blueIdx^2] = CV_CAST_8U(R); + greenCell = !greenCell; + } + +#if CV_SSE2 + if( !haveSSE ) + break; + + __m128i emask = _mm_set1_epi32(0x0000ffff), + omask = _mm_set1_epi32(0xffff0000), + z = _mm_setzero_si128(), + one = _mm_set1_epi16(1); + __m128 _0_5 = _mm_set1_ps(0.5f); + + #define _mm_merge_epi16(a, b) _mm_or_si128(_mm_and_si128(a, emask), _mm_and_si128(b, omask)) //(aA_aA_aA_aA) * (bB_bB_bB_bB) => (bA_bA_bA_bA) + #define _mm_cvtloepi16_ps(a) _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(a,a), 16)) //(1,2,3,4,5,6,7,8) => (1f,2f,3f,4f) + #define _mm_cvthiepi16_ps(a) _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(a,a), 16)) //(1,2,3,4,5,6,7,8) => (5f,6f,7f,8f) + #define _mm_loadl_u8_s16(ptr, offset) _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)((ptr) + (offset))), z) //load 8 uchars to 8 shorts + + // process 8 pixels at once + for( ; i <= N - 10; i += 8, srow += 8, brow0 += 8, brow1 += 8, brow2 += 8 ) + { + //int gradN = brow0[0] + brow1[0]; + __m128i gradN = _mm_adds_epi16(_mm_loadu_si128((__m128i*)brow0), _mm_loadu_si128((__m128i*)brow1)); + + //int gradS = brow1[0] + brow2[0]; + __m128i gradS = _mm_adds_epi16(_mm_loadu_si128((__m128i*)brow1), _mm_loadu_si128((__m128i*)brow2)); + + //int gradW = brow1[N-1] + brow1[N]; + __m128i gradW = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N-1)), _mm_loadu_si128((__m128i*)(brow1+N))); + + //int gradE = brow1[N+1] + brow1[N]; + __m128i gradE = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N+1)), _mm_loadu_si128((__m128i*)(brow1+N))); + + //int minGrad = std::min(std::min(std::min(gradN, gradS), gradW), gradE); + //int maxGrad = std::max(std::max(std::max(gradN, gradS), gradW), gradE); + __m128i minGrad = _mm_min_epi16(_mm_min_epi16(gradN, gradS), _mm_min_epi16(gradW, gradE)); + __m128i maxGrad = _mm_max_epi16(_mm_max_epi16(gradN, gradS), _mm_max_epi16(gradW, gradE)); + + __m128i grad0, grad1; + + //int gradNE = brow0[N4+1] + brow1[N4]; + //int gradNE = brow0[N2] + brow0[N2+1] + brow1[N2] + brow1[N2+1]; + grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N4+1)), _mm_loadu_si128((__m128i*)(brow1+N4))); + grad1 = _mm_adds_epi16( _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N2)), _mm_loadu_si128((__m128i*)(brow0+N2+1))), + _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N2)), _mm_loadu_si128((__m128i*)(brow1+N2+1)))); + __m128i gradNE = _mm_merge_epi16(grad0, grad1); + + //int gradSW = brow1[N4] + brow2[N4-1]; + //int gradSW = brow1[N2] + brow1[N2-1] + brow2[N2] + brow2[N2-1]; + grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N4-1)), _mm_loadu_si128((__m128i*)(brow1+N4))); + grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N2)), _mm_loadu_si128((__m128i*)(brow2+N2-1))), + _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N2)), _mm_loadu_si128((__m128i*)(brow1+N2-1)))); + __m128i gradSW = _mm_merge_epi16(grad0, grad1); + + minGrad = _mm_min_epi16(_mm_min_epi16(minGrad, gradNE), gradSW); + maxGrad = _mm_max_epi16(_mm_max_epi16(maxGrad, gradNE), gradSW); + + //int gradNW = brow0[N5-1] + brow1[N5]; + //int gradNW = brow0[N3] + brow0[N3-1] + brow1[N3] + brow1[N3-1]; + grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N5-1)), _mm_loadu_si128((__m128i*)(brow1+N5))); + grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N3)), _mm_loadu_si128((__m128i*)(brow0+N3-1))), + _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N3)), _mm_loadu_si128((__m128i*)(brow1+N3-1)))); + __m128i gradNW = _mm_merge_epi16(grad0, grad1); + + //int gradSE = brow1[N5] + brow2[N5+1]; + //int gradSE = brow1[N3] + brow1[N3+1] + brow2[N3] + brow2[N3+1]; + grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N5+1)), _mm_loadu_si128((__m128i*)(brow1+N5))); + grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N3)), _mm_loadu_si128((__m128i*)(brow2+N3+1))), + _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N3)), _mm_loadu_si128((__m128i*)(brow1+N3+1)))); + __m128i gradSE = _mm_merge_epi16(grad0, grad1); + + minGrad = _mm_min_epi16(_mm_min_epi16(minGrad, gradNW), gradSE); + maxGrad = _mm_max_epi16(_mm_max_epi16(maxGrad, gradNW), gradSE); + + //int T = minGrad + maxGrad/2; + __m128i T = _mm_adds_epi16(_mm_max_epi16(_mm_srli_epi16(maxGrad, 1), one), minGrad); + + __m128i RGs = z, GRs = z, Bs = z, ng = z; + + __m128i x0 = _mm_loadl_u8_s16(srow, +0 ); + __m128i x1 = _mm_loadl_u8_s16(srow, -1 - bstep ); + __m128i x2 = _mm_loadl_u8_s16(srow, -1 - bstep*2); + __m128i x3 = _mm_loadl_u8_s16(srow, - bstep ); + __m128i x4 = _mm_loadl_u8_s16(srow, +1 - bstep*2); + __m128i x5 = _mm_loadl_u8_s16(srow, +1 - bstep ); + __m128i x6 = _mm_loadl_u8_s16(srow, +2 - bstep ); + __m128i x7 = _mm_loadl_u8_s16(srow, +1 ); + __m128i x8 = _mm_loadl_u8_s16(srow, +2 + bstep ); + __m128i x9 = _mm_loadl_u8_s16(srow, +1 + bstep ); + __m128i x10 = _mm_loadl_u8_s16(srow, +1 + bstep*2); + __m128i x11 = _mm_loadl_u8_s16(srow, + bstep ); + __m128i x12 = _mm_loadl_u8_s16(srow, -1 + bstep*2); + __m128i x13 = _mm_loadl_u8_s16(srow, -1 + bstep ); + __m128i x14 = _mm_loadl_u8_s16(srow, -2 + bstep ); + __m128i x15 = _mm_loadl_u8_s16(srow, -1 ); + __m128i x16 = _mm_loadl_u8_s16(srow, -2 - bstep ); + + __m128i t0, t1, mask; + + // gradN *********************************************** + mask = _mm_cmpgt_epi16(T, gradN); // mask = T>gradN + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradN) + + t0 = _mm_slli_epi16(x3, 1); // srow[-bstep]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -bstep*2), x0); // srow[-bstep*2] + srow[0] + + // RGs += (srow[-bstep*2] + srow[0]) * (T>gradN) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(t1, mask)); + // GRs += {srow[-bstep]*2; (srow[-bstep*2-1] + srow[-bstep*2+1])} * (T>gradN) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(t0, _mm_adds_epi16(x2,x4)), mask)); + // Bs += {(srow[-bstep-1]+srow[-bstep+1]); srow[-bstep]*2 } * (T>gradN) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x1,x5), t0), mask)); + + // gradNE ********************************************** + mask = _mm_cmpgt_epi16(T, gradNE); // mask = T>gradNE + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradNE) + + t0 = _mm_slli_epi16(x5, 1); // srow[-bstep+1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -bstep*2+2), x0); // srow[-bstep*2+2] + srow[0] + + // RGs += {(srow[-bstep*2+2] + srow[0]); srow[-bstep+1]*2} * (T>gradNE) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(_mm_merge_epi16(t1, t0), mask)); + // GRs += {brow0[N6+1]; (srow[-bstep*2+1] + srow[1])} * (T>gradNE) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow0+N6+1)), _mm_adds_epi16(x4,x7)), mask)); + // Bs += {srow[-bstep+1]*2; (srow[-bstep] + srow[-bstep+2])} * (T>gradNE) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(t0,_mm_adds_epi16(x3,x6)), mask)); + + // gradE *********************************************** + mask = _mm_cmpgt_epi16(T, gradE); // mask = T>gradE + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradE) + + t0 = _mm_slli_epi16(x7, 1); // srow[1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, 2), x0); // srow[2] + srow[0] + + // RGs += (srow[2] + srow[0]) * (T>gradE) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(t1, mask)); + // GRs += (srow[1]*2) * (T>gradE) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(t0, mask)); + // Bs += {(srow[-bstep+1]+srow[bstep+1]); (srow[-bstep+2]+srow[bstep+2])} * (T>gradE) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x5,x9), _mm_adds_epi16(x6,x8)), mask)); + + // gradSE ********************************************** + mask = _mm_cmpgt_epi16(T, gradSE); // mask = T>gradSE + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradSE) + + t0 = _mm_slli_epi16(x9, 1); // srow[bstep+1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, bstep*2+2), x0); // srow[bstep*2+2] + srow[0] + + // RGs += {(srow[bstep*2+2] + srow[0]); srow[bstep+1]*2} * (T>gradSE) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(_mm_merge_epi16(t1, t0), mask)); + // GRs += {brow2[N6+1]; (srow[1]+srow[bstep*2+1])} * (T>gradSE) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow2+N6+1)), _mm_adds_epi16(x7,x10)), mask)); + // Bs += {srow[-bstep+1]*2; (srow[bstep+2]+srow[bstep])} * (T>gradSE) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_slli_epi16(x5, 1), _mm_adds_epi16(x8,x11)), mask)); + + // gradS *********************************************** + mask = _mm_cmpgt_epi16(T, gradS); // mask = T>gradS + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradS) + + t0 = _mm_slli_epi16(x11, 1); // srow[bstep]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow,bstep*2), x0); // srow[bstep*2]+srow[0] + + // RGs += (srow[bstep*2]+srow[0]) * (T>gradS) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(t1, mask)); + // GRs += {srow[bstep]*2; (srow[bstep*2+1]+srow[bstep*2-1])} * (T>gradS) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(t0, _mm_adds_epi16(x10,x12)), mask)); + // Bs += {(srow[bstep+1]+srow[bstep-1]); srow[bstep]*2} * (T>gradS) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x9,x13), t0), mask)); + + // gradSW ********************************************** + mask = _mm_cmpgt_epi16(T, gradSW); // mask = T>gradSW + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradSW) + + t0 = _mm_slli_epi16(x13, 1); // srow[bstep-1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, bstep*2-2), x0); // srow[bstep*2-2]+srow[0] + + // RGs += {(srow[bstep*2-2]+srow[0]); srow[bstep-1]*2} * (T>gradSW) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(_mm_merge_epi16(t1, t0), mask)); + // GRs += {brow2[N6-1]; (srow[bstep*2-1]+srow[-1])} * (T>gradSW) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow2+N6-1)), _mm_adds_epi16(x12,x15)), mask)); + // Bs += {srow[bstep-1]*2; (srow[bstep]+srow[bstep-2])} * (T>gradSW) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(t0,_mm_adds_epi16(x11,x14)), mask)); + + // gradW *********************************************** + mask = _mm_cmpgt_epi16(T, gradW); // mask = T>gradW + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradW) + + t0 = _mm_slli_epi16(x15, 1); // srow[-1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -2), x0); // srow[-2]+srow[0] + + // RGs += (srow[-2]+srow[0]) * (T>gradW) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(t1, mask)); + // GRs += (srow[-1]*2) * (T>gradW) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(t0, mask)); + // Bs += {(srow[-bstep-1]+srow[bstep-1]); (srow[bstep-2]+srow[-bstep-2])} * (T>gradW) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x1,x13), _mm_adds_epi16(x14,x16)), mask)); + + // gradNW ********************************************** + mask = _mm_cmpgt_epi16(T, gradNW); // mask = T>gradNW + ng = _mm_sub_epi16(ng, mask); // ng += (T>gradNW) + + t0 = _mm_slli_epi16(x1, 1); // srow[-bstep-1]*2 + t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow,-bstep*2-2), x0); // srow[-bstep*2-2]+srow[0] + + // RGs += {(srow[-bstep*2-2]+srow[0]); srow[-bstep-1]*2} * (T>gradNW) + RGs = _mm_adds_epi16(RGs, _mm_and_si128(_mm_merge_epi16(t1, t0), mask)); + // GRs += {brow0[N6-1]; (srow[-bstep*2-1]+srow[-1])} * (T>gradNW) + GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow0+N6-1)), _mm_adds_epi16(x2,x15)), mask)); + // Bs += {srow[-bstep-1]*2; (srow[-bstep]+srow[-bstep-2])} * (T>gradNW) + Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_slli_epi16(x5, 1),_mm_adds_epi16(x3,x16)), mask)); + + __m128 ngf0 = _mm_div_ps(_0_5, _mm_cvtloepi16_ps(ng)); + __m128 ngf1 = _mm_div_ps(_0_5, _mm_cvthiepi16_ps(ng)); + + // now interpolate r, g & b + t0 = _mm_subs_epi16(GRs, RGs); + t1 = _mm_subs_epi16(Bs, RGs); + + t0 = _mm_add_epi16(x0, _mm_packs_epi32( + _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtloepi16_ps(t0), ngf0)), + _mm_cvtps_epi32(_mm_mul_ps(_mm_cvthiepi16_ps(t0), ngf1)))); + + t1 = _mm_add_epi16(x0, _mm_packs_epi32( + _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtloepi16_ps(t1), ngf0)), + _mm_cvtps_epi32(_mm_mul_ps(_mm_cvthiepi16_ps(t1), ngf1)))); + + x1 = _mm_merge_epi16(x0, t0); + x2 = _mm_merge_epi16(t0, x0); + + uchar R[8], G[8], B[8]; + + _mm_storel_epi64(blueIdx ? (__m128i*)B : (__m128i*)R, _mm_packus_epi16(x1, z)); + _mm_storel_epi64((__m128i*)G, _mm_packus_epi16(x2, z)); + _mm_storel_epi64(blueIdx ? (__m128i*)R : (__m128i*)B, _mm_packus_epi16(t1, z)); + + for( int j = 0; j < 8; j++, dstrow += 3 ) + { + dstrow[0] = B[j]; dstrow[1] = G[j]; dstrow[2] = R[j]; + } + } +#endif + + limit = N - 2; + } + while( i < N - 2 ); + + for( i = 0; i < 6; i++ ) + { + dst[dststep*y + 5 - i] = dst[dststep*y + 8 - i]; + dst[dststep*y + (N - 2)*3 + i] = dst[dststep*y + (N - 3)*3 + i]; + } + + greenCell0 = !greenCell0; + blueIdx ^= 2; + } + + for( i = 0; i < size.width*3; i++ ) + { + dst[i] = dst[i + dststep] = dst[i + dststep*2]; + dst[i + dststep*(size.height-4)] = + dst[i + dststep*(size.height-3)] = + dst[i + dststep*(size.height-2)] = + dst[i + dststep*(size.height-1)] = dst[i + dststep*(size.height-5)]; + } +} + +///////////////////////////////////// YUV420 -> RGB ///////////////////////////////////// + +const int ITUR_BT_601_CY = 1220542; +const int ITUR_BT_601_CUB = 2116026; +const int ITUR_BT_601_CUG = -409993; +const int ITUR_BT_601_CVG = -852492; +const int ITUR_BT_601_CVR = 1673527; +const int ITUR_BT_601_SHIFT = 20; + +// Coefficients for RGB to YUV420p conversion +const int ITUR_BT_601_CRY = 269484; +const int ITUR_BT_601_CGY = 528482; +const int ITUR_BT_601_CBY = 102760; +const int ITUR_BT_601_CRU = -155188; +const int ITUR_BT_601_CGU = -305135; +const int ITUR_BT_601_CBU = 460324; +const int ITUR_BT_601_CGV = -385875; +const int ITUR_BT_601_CBV = -74448; + +template +struct YUV420sp2RGB888Invoker +{ + Mat* dst; + const uchar* my1, *muv; + int width, stride; + + YUV420sp2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv) + : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {} + + void operator()(const BlockedRange& range) const + { + int rangeBegin = range.begin() * 2; + int rangeEnd = range.end() * 2; + + //R = 1.164(Y - 16) + 1.596(V - 128) + //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) + //B = 1.164(Y - 16) + 2.018(U - 128) + + //R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20 + //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20 + //B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20 + + const uchar* y1 = my1 + rangeBegin * stride, *uv = muv + rangeBegin * stride / 2; + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(tegra::cvtYUV4202RGB(bIdx, uIdx, 3, y1, uv, stride, dst->ptr(rangeBegin), dst->step, rangeEnd - rangeBegin, dst->cols)) + return; +#endif + + for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, uv += stride) + { + uchar* row1 = dst->ptr(j); + uchar* row2 = dst->ptr(j + 1); + const uchar* y2 = y1 + stride; + + for (int i = 0; i < width; i += 2, row1 += 6, row2 += 6) + { + int u = int(uv[i + 0 + uIdx]) - 128; + int v = int(uv[i + 1 - uIdx]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(y1[i]) - 16) * ITUR_BT_601_CY; + row1[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row1[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row1[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + + int y01 = std::max(0, int(y1[i + 1]) - 16) * ITUR_BT_601_CY; + row1[5-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row1[4] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row1[3+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + + int y10 = std::max(0, int(y2[i]) - 16) * ITUR_BT_601_CY; + row2[2-bIdx] = saturate_cast((y10 + ruv) >> ITUR_BT_601_SHIFT); + row2[1] = saturate_cast((y10 + guv) >> ITUR_BT_601_SHIFT); + row2[bIdx] = saturate_cast((y10 + buv) >> ITUR_BT_601_SHIFT); + + int y11 = std::max(0, int(y2[i + 1]) - 16) * ITUR_BT_601_CY; + row2[5-bIdx] = saturate_cast((y11 + ruv) >> ITUR_BT_601_SHIFT); + row2[4] = saturate_cast((y11 + guv) >> ITUR_BT_601_SHIFT); + row2[3+bIdx] = saturate_cast((y11 + buv) >> ITUR_BT_601_SHIFT); + } + } + } +}; + +template +struct YUV420sp2RGBA8888Invoker +{ + Mat* dst; + const uchar* my1, *muv; + int width, stride; + + YUV420sp2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv) + : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {} + + void operator()(const BlockedRange& range) const + { + int rangeBegin = range.begin() * 2; + int rangeEnd = range.end() * 2; + + //R = 1.164(Y - 16) + 1.596(V - 128) + //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) + //B = 1.164(Y - 16) + 2.018(U - 128) + + //R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20 + //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20 + //B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20 + + const uchar* y1 = my1 + rangeBegin * stride, *uv = muv + rangeBegin * stride / 2; + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(tegra::cvtYUV4202RGB(bIdx, uIdx, 4, y1, uv, stride, dst->ptr(rangeBegin), dst->step, rangeEnd - rangeBegin, dst->cols)) + return; +#endif + + for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, uv += stride) + { + uchar* row1 = dst->ptr(j); + uchar* row2 = dst->ptr(j + 1); + const uchar* y2 = y1 + stride; + + for (int i = 0; i < width; i += 2, row1 += 8, row2 += 8) + { + int u = int(uv[i + 0 + uIdx]) - 128; + int v = int(uv[i + 1 - uIdx]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(y1[i]) - 16) * ITUR_BT_601_CY; + row1[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row1[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row1[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + row1[3] = uchar(0xff); + + int y01 = std::max(0, int(y1[i + 1]) - 16) * ITUR_BT_601_CY; + row1[6-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row1[5] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row1[4+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + row1[7] = uchar(0xff); + + int y10 = std::max(0, int(y2[i]) - 16) * ITUR_BT_601_CY; + row2[2-bIdx] = saturate_cast((y10 + ruv) >> ITUR_BT_601_SHIFT); + row2[1] = saturate_cast((y10 + guv) >> ITUR_BT_601_SHIFT); + row2[bIdx] = saturate_cast((y10 + buv) >> ITUR_BT_601_SHIFT); + row2[3] = uchar(0xff); + + int y11 = std::max(0, int(y2[i + 1]) - 16) * ITUR_BT_601_CY; + row2[6-bIdx] = saturate_cast((y11 + ruv) >> ITUR_BT_601_SHIFT); + row2[5] = saturate_cast((y11 + guv) >> ITUR_BT_601_SHIFT); + row2[4+bIdx] = saturate_cast((y11 + buv) >> ITUR_BT_601_SHIFT); + row2[7] = uchar(0xff); + } + } + } +}; + +template +struct YUV420p2RGB888Invoker +{ + Mat* dst; + const uchar* my1, *mu, *mv; + int width, stride; + int ustepIdx, vstepIdx; + + YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) + : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} + + void operator()(const BlockedRange& range) const + { + const int rangeBegin = range.begin() * 2; + const int rangeEnd = range.end() * 2; + + size_t uvsteps[2] = {width/2, stride - width/2}; + int usIdx = ustepIdx, vsIdx = vstepIdx; + + const uchar* y1 = my1 + rangeBegin * stride; + const uchar* u1 = mu + (range.begin() / 2) * stride; + const uchar* v1 = mv + (range.begin() / 2) * stride; + + if(range.begin() % 2 == 1) + { + u1 += uvsteps[(usIdx++) & 1]; + v1 += uvsteps[(vsIdx++) & 1]; + } + + for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1]) + { + uchar* row1 = dst->ptr(j); + uchar* row2 = dst->ptr(j + 1); + const uchar* y2 = y1 + stride; + + for (int i = 0; i < width / 2; i += 1, row1 += 6, row2 += 6) + { + int u = int(u1[i]) - 128; + int v = int(v1[i]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(y1[2 * i]) - 16) * ITUR_BT_601_CY; + row1[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row1[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row1[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + + int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * ITUR_BT_601_CY; + row1[5-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row1[4] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row1[3+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + + int y10 = std::max(0, int(y2[2 * i]) - 16) * ITUR_BT_601_CY; + row2[2-bIdx] = saturate_cast((y10 + ruv) >> ITUR_BT_601_SHIFT); + row2[1] = saturate_cast((y10 + guv) >> ITUR_BT_601_SHIFT); + row2[bIdx] = saturate_cast((y10 + buv) >> ITUR_BT_601_SHIFT); + + int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * ITUR_BT_601_CY; + row2[5-bIdx] = saturate_cast((y11 + ruv) >> ITUR_BT_601_SHIFT); + row2[4] = saturate_cast((y11 + guv) >> ITUR_BT_601_SHIFT); + row2[3+bIdx] = saturate_cast((y11 + buv) >> ITUR_BT_601_SHIFT); + } + } + } +}; + +template +struct YUV420p2RGBA8888Invoker +{ + Mat* dst; + const uchar* my1, *mu, *mv; + int width, stride; + int ustepIdx, vstepIdx; + + YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) + : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} + + void operator()(const BlockedRange& range) const + { + int rangeBegin = range.begin() * 2; + int rangeEnd = range.end() * 2; + + size_t uvsteps[2] = {width/2, stride - width/2}; + int usIdx = ustepIdx, vsIdx = vstepIdx; + + const uchar* y1 = my1 + rangeBegin * stride; + const uchar* u1 = mu + (range.begin() / 2) * stride; + const uchar* v1 = mv + (range.begin() / 2) * stride; + + if(range.begin() % 2 == 1) + { + u1 += uvsteps[(usIdx++) & 1]; + v1 += uvsteps[(vsIdx++) & 1]; + } + + for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1]) + { + uchar* row1 = dst->ptr(j); + uchar* row2 = dst->ptr(j + 1); + const uchar* y2 = y1 + stride; + + for (int i = 0; i < width / 2; i += 1, row1 += 8, row2 += 8) + { + int u = int(u1[i]) - 128; + int v = int(v1[i]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(y1[2 * i]) - 16) * ITUR_BT_601_CY; + row1[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row1[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row1[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + row1[3] = uchar(0xff); + + int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * ITUR_BT_601_CY; + row1[6-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row1[5] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row1[4+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + row1[7] = uchar(0xff); + + int y10 = std::max(0, int(y2[2 * i]) - 16) * ITUR_BT_601_CY; + row2[2-bIdx] = saturate_cast((y10 + ruv) >> ITUR_BT_601_SHIFT); + row2[1] = saturate_cast((y10 + guv) >> ITUR_BT_601_SHIFT); + row2[bIdx] = saturate_cast((y10 + buv) >> ITUR_BT_601_SHIFT); + row2[3] = uchar(0xff); + + int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * ITUR_BT_601_CY; + row2[6-bIdx] = saturate_cast((y11 + ruv) >> ITUR_BT_601_SHIFT); + row2[5] = saturate_cast((y11 + guv) >> ITUR_BT_601_SHIFT); + row2[4+bIdx] = saturate_cast((y11 + buv) >> ITUR_BT_601_SHIFT); + row2[7] = uchar(0xff); + } + } + } +}; + +#define MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION (320*240) + +template +inline void cvtYUV420sp2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv) +{ + YUV420sp2RGB888Invoker converter(&_dst, _stride, _y1, _uv); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows/2), converter); + else +#endif + converter(BlockedRange(0, _dst.rows/2)); +} + +template +inline void cvtYUV420sp2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv) +{ + YUV420sp2RGBA8888Invoker converter(&_dst, _stride, _y1, _uv); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows/2), converter); + else +#endif + converter(BlockedRange(0, _dst.rows/2)); +} + +template +inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) +{ + YUV420p2RGB888Invoker converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows/2), converter); + else +#endif + converter(BlockedRange(0, _dst.rows/2)); +} + +template +inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) +{ + YUV420p2RGBA8888Invoker converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows/2), converter); + else +#endif + converter(BlockedRange(0, _dst.rows/2)); +} + +///////////////////////////////////// RGB -> YUV420p ///////////////////////////////////// + +template +struct RGB888toYUV420pInvoker: public ParallelLoopBody +{ + RGB888toYUV420pInvoker( const Mat& src, Mat* dst, const int uIdx ) + : src_(src), + dst_(dst), + uIdx_(uIdx) { } + + void operator()(const Range& rowRange) const + { + const int w = src_.cols; + const int h = src_.rows; + + const int cn = src_.channels(); + for( int i = rowRange.start; i < rowRange.end; i++ ) + { + const uchar* row0 = src_.ptr(2 * i); + const uchar* row1 = src_.ptr(2 * i + 1); + + uchar* y = dst_->ptr(2*i); + uchar* u = dst_->ptr(h + i/2) + (i % 2) * (w/2); + uchar* v = dst_->ptr(h + (i + h/2)/2) + ((i + h/2) % 2) * (w/2); + if( uIdx_ == 2 ) std::swap(u, v); + + for( int j = 0, k = 0; j < w * cn; j += 2 * cn, k++ ) + { + int r00 = row0[2-bIdx + j]; int g00 = row0[1 + j]; int b00 = row0[bIdx + j]; + int r01 = row0[2-bIdx + cn + j]; int g01 = row0[1 + cn + j]; int b01 = row0[bIdx + cn + j]; + int r10 = row1[2-bIdx + j]; int g10 = row1[1 + j]; int b10 = row1[bIdx + j]; + int r11 = row1[2-bIdx + cn + j]; int g11 = row1[1 + cn + j]; int b11 = row1[bIdx + cn + j]; + + const int shifted16 = (16 << ITUR_BT_601_SHIFT); + const int halfShift = (1 << (ITUR_BT_601_SHIFT - 1)); + int y00 = ITUR_BT_601_CRY * r00 + ITUR_BT_601_CGY * g00 + ITUR_BT_601_CBY * b00 + halfShift + shifted16; + int y01 = ITUR_BT_601_CRY * r01 + ITUR_BT_601_CGY * g01 + ITUR_BT_601_CBY * b01 + halfShift + shifted16; + int y10 = ITUR_BT_601_CRY * r10 + ITUR_BT_601_CGY * g10 + ITUR_BT_601_CBY * b10 + halfShift + shifted16; + int y11 = ITUR_BT_601_CRY * r11 + ITUR_BT_601_CGY * g11 + ITUR_BT_601_CBY * b11 + halfShift + shifted16; + + y[2*k + 0] = saturate_cast(y00 >> ITUR_BT_601_SHIFT); + y[2*k + 1] = saturate_cast(y01 >> ITUR_BT_601_SHIFT); + y[2*k + dst_->step + 0] = saturate_cast(y10 >> ITUR_BT_601_SHIFT); + y[2*k + dst_->step + 1] = saturate_cast(y11 >> ITUR_BT_601_SHIFT); + + const int shifted128 = (128 << ITUR_BT_601_SHIFT); + int u00 = ITUR_BT_601_CRU * r00 + ITUR_BT_601_CGU * g00 + ITUR_BT_601_CBU * b00 + halfShift + shifted128; + int v00 = ITUR_BT_601_CBU * r00 + ITUR_BT_601_CGV * g00 + ITUR_BT_601_CBV * b00 + halfShift + shifted128; + + u[k] = saturate_cast(u00 >> ITUR_BT_601_SHIFT); + v[k] = saturate_cast(v00 >> ITUR_BT_601_SHIFT); + } + } + } + + static bool isFit( const Mat& src ) + { + return (src.total() >= 320*240); + } + +private: + RGB888toYUV420pInvoker& operator=(const RGB888toYUV420pInvoker&); + + const Mat& src_; + Mat* const dst_; + const int uIdx_; +}; + +template +static void cvtRGBtoYUV420p(const Mat& src, Mat& dst) +{ + RGB888toYUV420pInvoker colorConverter(src, &dst, uIdx); + if( RGB888toYUV420pInvoker::isFit(src) ) + parallel_for_(Range(0, src.rows/2), colorConverter); + else + colorConverter(Range(0, src.rows/2)); +} + +///////////////////////////////////// YUV422 -> RGB ///////////////////////////////////// + +template +struct YUV422toRGB888Invoker +{ + Mat* dst; + const uchar* src; + int width, stride; + + YUV422toRGB888Invoker(Mat* _dst, int _stride, const uchar* _yuv) + : dst(_dst), src(_yuv), width(_dst->cols), stride(_stride) {} + + void operator()(const BlockedRange& range) const + { + int rangeBegin = range.begin(); + int rangeEnd = range.end(); + + const int uidx = 1 - yIdx + uIdx * 2; + const int vidx = (2 + uidx) % 4; + const uchar* yuv_src = src + rangeBegin * stride; + + for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += stride) + { + uchar* row = dst->ptr(j); + + for (int i = 0; i < 2 * width; i += 4, row += 6) + { + int u = int(yuv_src[i + uidx]) - 128; + int v = int(yuv_src[i + vidx]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * ITUR_BT_601_CY; + row[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + + int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * ITUR_BT_601_CY; + row[5-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row[4] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row[3+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + } + } + } +}; + +template +struct YUV422toRGBA8888Invoker +{ + Mat* dst; + const uchar* src; + int width, stride; + + YUV422toRGBA8888Invoker(Mat* _dst, int _stride, const uchar* _yuv) + : dst(_dst), src(_yuv), width(_dst->cols), stride(_stride) {} + + void operator()(const BlockedRange& range) const + { + int rangeBegin = range.begin(); + int rangeEnd = range.end(); + + const int uidx = 1 - yIdx + uIdx * 2; + const int vidx = (2 + uidx) % 4; + const uchar* yuv_src = src + rangeBegin * stride; + + for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += stride) + { + uchar* row = dst->ptr(j); + + for (int i = 0; i < 2 * width; i += 4, row += 8) + { + int u = int(yuv_src[i + uidx]) - 128; + int v = int(yuv_src[i + vidx]) - 128; + + int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v; + int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u; + int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u; + + int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * ITUR_BT_601_CY; + row[2-bIdx] = saturate_cast((y00 + ruv) >> ITUR_BT_601_SHIFT); + row[1] = saturate_cast((y00 + guv) >> ITUR_BT_601_SHIFT); + row[bIdx] = saturate_cast((y00 + buv) >> ITUR_BT_601_SHIFT); + row[3] = uchar(0xff); + + int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * ITUR_BT_601_CY; + row[6-bIdx] = saturate_cast((y01 + ruv) >> ITUR_BT_601_SHIFT); + row[5] = saturate_cast((y01 + guv) >> ITUR_BT_601_SHIFT); + row[4+bIdx] = saturate_cast((y01 + buv) >> ITUR_BT_601_SHIFT); + row[7] = uchar(0xff); + } + } + } +}; + +#define MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION (320*240) + +template +inline void cvtYUV422toRGB(Mat& _dst, int _stride, const uchar* _yuv) +{ + YUV422toRGB888Invoker converter(&_dst, _stride, _yuv); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows), converter); + else +#endif + converter(BlockedRange(0, _dst.rows)); +} + +template +inline void cvtYUV422toRGBA(Mat& _dst, int _stride, const uchar* _yuv) +{ + YUV422toRGBA8888Invoker converter(&_dst, _stride, _yuv); +#ifdef HAVE_TBB + if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) + parallel_for(BlockedRange(0, _dst.rows), converter); + else +#endif + converter(BlockedRange(0, _dst.rows)); +} + +/////////////////////////// RGBA <-> mRGBA (alpha premultiplied) ////////////// + +template +struct RGBA2mRGBA +{ + typedef _Tp channel_type; + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + _Tp max_val = ColorChannel<_Tp>::max(); + _Tp half_val = ColorChannel<_Tp>::half(); + for( int i = 0; i < n; i++ ) + { + _Tp v0 = *src++; + _Tp v1 = *src++; + _Tp v2 = *src++; + _Tp v3 = *src++; + + *dst++ = (v0 * v3 + half_val) / max_val; + *dst++ = (v1 * v3 + half_val) / max_val; + *dst++ = (v2 * v3 + half_val) / max_val; + *dst++ = v3; + } + } +}; + + +template +struct mRGBA2RGBA +{ + typedef _Tp channel_type; + + void operator()(const _Tp* src, _Tp* dst, int n) const + { + _Tp max_val = ColorChannel<_Tp>::max(); + for( int i = 0; i < n; i++ ) + { + _Tp v0 = *src++; + _Tp v1 = *src++; + _Tp v2 = *src++; + _Tp v3 = *src++; + _Tp v3_half = v3 / 2; + + *dst++ = (v3==0)? 0 : (v0 * max_val + v3_half) / v3; + *dst++ = (v3==0)? 0 : (v1 * max_val + v3_half) / v3; + *dst++ = (v3==0)? 0 : (v2 * max_val + v3_half) / v3; + *dst++ = v3; + } + } +}; + +}//namespace cv + +////////////////////////////////////////////////////////////////////////////////////////// +// The main function // +////////////////////////////////////////////////////////////////////////////////////////// + +void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) +{ + Mat src = _src.getMat(), dst; + Size sz = src.size(); + int scn = src.channels(), depth = src.depth(), bidx; + + CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F ); + + switch( code ) + { + case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR: + case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: + CV_Assert( scn == 3 || scn == 4 ); + dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3; + bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2; + + _dst.create( sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { +#ifdef HAVE_TEGRA_OPTIMIZATION + if(!tegra::cvtBGR2RGB(src, dst, bidx)) +#endif + CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); + } + else if( depth == CV_16U ) + CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); + else + CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); + break; + + case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555: + case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555: + CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); + _dst.create(sz, CV_8UC2); + dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(code == CV_BGR2BGR565 || code == CV_BGRA2BGR565 || code == CV_RGB2BGR565 || code == CV_RGBA2BGR565) + if(tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2)) + break; +#endif + + CvtColorLoop(src, dst, RGB2RGB5x5(scn, + code == CV_BGR2BGR565 || code == CV_BGR2BGR555 || + code == CV_BGRA2BGR565 || code == CV_BGRA2BGR555 ? 0 : 2, + code == CV_BGR2BGR565 || code == CV_RGB2BGR565 || + code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5 // green bits + )); + break; + + case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB: + case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA: + if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3; + CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U ); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + CvtColorLoop(src, dst, RGB5x52RGB(dcn, + code == CV_BGR5652BGR || code == CV_BGR5552BGR || + code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2, // blue idx + code == CV_BGR5652BGR || code == CV_BGR5652RGB || + code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5 // green bits + )); + break; + + case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: + CV_Assert( scn == 3 || scn == 4 ); + _dst.create(sz, CV_MAKETYPE(depth, 1)); + dst = _dst.getMat(); + + bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2; + + if( depth == CV_8U ) + { +#ifdef HAVE_TEGRA_OPTIMIZATION + if(!tegra::cvtRGB2Gray(src, dst, bidx)) +#endif + CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); + } + else if( depth == CV_16U ) + CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); + else + CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); + break; + + case CV_BGR5652GRAY: case CV_BGR5552GRAY: + CV_Assert( scn == 2 && depth == CV_8U ); + _dst.create(sz, CV_8UC1); + dst = _dst.getMat(); + + CvtColorLoop(src, dst, RGB5x52Gray(code == CV_BGR5652GRAY ? 6 : 5)); + break; + + case CV_GRAY2BGR: case CV_GRAY2BGRA: + if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3; + CV_Assert( scn == 1 && (dcn == 3 || dcn == 4)); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { +#ifdef HAVE_TEGRA_OPTIMIZATION + if(!tegra::cvtGray2RGB(src, dst)) +#endif + CvtColorLoop(src, dst, Gray2RGB(dcn)); + } + else if( depth == CV_16U ) + CvtColorLoop(src, dst, Gray2RGB(dcn)); + else + CvtColorLoop(src, dst, Gray2RGB(dcn)); + break; + + case CV_GRAY2BGR565: case CV_GRAY2BGR555: + CV_Assert( scn == 1 && depth == CV_8U ); + _dst.create(sz, CV_8UC2); + dst = _dst.getMat(); + + CvtColorLoop(src, dst, Gray2RGB5x5(code == CV_GRAY2BGR565 ? 6 : 5)); + break; + + case CV_BGR2YCrCb: case CV_RGB2YCrCb: + case CV_BGR2YUV: case CV_RGB2YUV: + { + CV_Assert( scn == 3 || scn == 4 ); + bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2; + static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; + static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 }; + const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f; + const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { +#ifdef HAVE_TEGRA_OPTIMIZATION + if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb(src, dst, bidx)) + break; +#endif + CvtColorLoop(src, dst, RGB2YCrCb_i(scn, bidx, coeffs_i)); + } + else if( depth == CV_16U ) + CvtColorLoop(src, dst, RGB2YCrCb_i(scn, bidx, coeffs_i)); + else + CvtColorLoop(src, dst, RGB2YCrCb_f(scn, bidx, coeffs_f)); + } + break; + + case CV_YCrCb2BGR: case CV_YCrCb2RGB: + case CV_YUV2BGR: case CV_YUV2RGB: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); + bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2; + static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; + static const int yuv_i[] = { 33292, -6472, -9519, 18678 }; + const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f; + const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + CvtColorLoop(src, dst, YCrCb2RGB_i(dcn, bidx, coeffs_i)); + else if( depth == CV_16U ) + CvtColorLoop(src, dst, YCrCb2RGB_i(dcn, bidx, coeffs_i)); + else + CvtColorLoop(src, dst, YCrCb2RGB_f(dcn, bidx, coeffs_f)); + } + break; + + case CV_BGR2XYZ: case CV_RGB2XYZ: + CV_Assert( scn == 3 || scn == 4 ); + bidx = code == CV_BGR2XYZ ? 0 : 2; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + CvtColorLoop(src, dst, RGB2XYZ_i(scn, bidx, 0)); + else if( depth == CV_16U ) + CvtColorLoop(src, dst, RGB2XYZ_i(scn, bidx, 0)); + else + CvtColorLoop(src, dst, RGB2XYZ_f(scn, bidx, 0)); + break; + + case CV_XYZ2BGR: case CV_XYZ2RGB: + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); + bidx = code == CV_XYZ2BGR ? 0 : 2; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + CvtColorLoop(src, dst, XYZ2RGB_i(dcn, bidx, 0)); + else if( depth == CV_16U ) + CvtColorLoop(src, dst, XYZ2RGB_i(dcn, bidx, 0)); + else + CvtColorLoop(src, dst, XYZ2RGB_f(dcn, bidx, 0)); + break; + + case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: + case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: + { + CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); + bidx = code == CV_BGR2HSV || code == CV_BGR2HLS || + code == CV_BGR2HSV_FULL || code == CV_BGR2HLS_FULL ? 0 : 2; + int hrange = depth == CV_32F ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV || + code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 256; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( code == CV_BGR2HSV || code == CV_RGB2HSV || + code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL ) + { +#ifdef HAVE_TEGRA_OPTIMIZATION + if(tegra::cvtRGB2HSV(src, dst, bidx, hrange)) + break; +#endif + if( depth == CV_8U ) + CvtColorLoop(src, dst, RGB2HSV_b(scn, bidx, hrange)); + else + CvtColorLoop(src, dst, RGB2HSV_f(scn, bidx, (float)hrange)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, RGB2HLS_b(scn, bidx, hrange)); + else + CvtColorLoop(src, dst, RGB2HLS_f(scn, bidx, (float)hrange)); + } + } + break; + + case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: + case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); + bidx = code == CV_HSV2BGR || code == CV_HLS2BGR || + code == CV_HSV2BGR_FULL || code == CV_HLS2BGR_FULL ? 0 : 2; + int hrange = depth == CV_32F ? 360 : code == CV_HSV2BGR || code == CV_HSV2RGB || + code == CV_HLS2BGR || code == CV_HLS2RGB ? 180 : 255; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( code == CV_HSV2BGR || code == CV_HSV2RGB || + code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL ) + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, HSV2RGB_b(dcn, bidx, hrange)); + else + CvtColorLoop(src, dst, HSV2RGB_f(dcn, bidx, (float)hrange)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, HLS2RGB_b(dcn, bidx, hrange)); + else + CvtColorLoop(src, dst, HLS2RGB_f(dcn, bidx, (float)hrange)); + } + } + break; + + case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: + case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv: + { + CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); + bidx = code == CV_BGR2Lab || code == CV_BGR2Luv || + code == CV_LBGR2Lab || code == CV_LBGR2Luv ? 0 : 2; + bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab || + code == CV_BGR2Luv || code == CV_RGB2Luv; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( code == CV_BGR2Lab || code == CV_RGB2Lab || + code == CV_LBGR2Lab || code == CV_LRGB2Lab ) + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, RGB2Lab_b(scn, bidx, 0, 0, srgb)); + else + CvtColorLoop(src, dst, RGB2Lab_f(scn, bidx, 0, 0, srgb)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, RGB2Luv_b(scn, bidx, 0, 0, srgb)); + else + CvtColorLoop(src, dst, RGB2Luv_f(scn, bidx, 0, 0, srgb)); + } + } + break; + + case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: + case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); + bidx = code == CV_Lab2BGR || code == CV_Luv2BGR || + code == CV_Lab2LBGR || code == CV_Luv2LBGR ? 0 : 2; + bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB || + code == CV_Luv2BGR || code == CV_Luv2RGB; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( code == CV_Lab2BGR || code == CV_Lab2RGB || + code == CV_Lab2LBGR || code == CV_Lab2LRGB ) + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, Lab2RGB_b(dcn, bidx, 0, 0, srgb)); + else + CvtColorLoop(src, dst, Lab2RGB_f(dcn, bidx, 0, 0, srgb)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src, dst, Luv2RGB_b(dcn, bidx, 0, 0, srgb)); + else + CvtColorLoop(src, dst, Luv2RGB_f(dcn, bidx, 0, 0, srgb)); + } + } + break; + + case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY: + if(dcn <= 0) dcn = 1; + CV_Assert( scn == 1 && dcn == 1 ); + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + Bayer2Gray_(src, dst, code); + else if( depth == CV_16U ) + Bayer2Gray_ >(src, dst, code); + else + CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); + break; + + case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR: + case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG: + { + if (dcn <= 0) + dcn = 3; + CV_Assert( scn == 1 && dcn == 3 ); + + _dst.create(sz, CV_MAKE_TYPE(depth, dcn)); + Mat dst_ = _dst.getMat(); + + if( code == CV_BayerBG2BGR || code == CV_BayerGB2BGR || + code == CV_BayerRG2BGR || code == CV_BayerGR2BGR ) + { + if( depth == CV_8U ) + Bayer2RGB_(src, dst_, code); + else if( depth == CV_16U ) + Bayer2RGB_ >(src, dst_, code); + else + CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); + } + else + { + CV_Assert( depth == CV_8U ); + Bayer2RGB_VNG_8u(src, dst_, code); + } + } + break; + case CV_YUV2BGR_NV21: case CV_YUV2RGB_NV21: case CV_YUV2BGR_NV12: case CV_YUV2RGB_NV12: + case CV_YUV2BGRA_NV21: case CV_YUV2RGBA_NV21: case CV_YUV2BGRA_NV12: case CV_YUV2RGBA_NV12: + { + // http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples + // http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples + + if (dcn <= 0) dcn = (code==CV_YUV420sp2BGRA || code==CV_YUV420sp2RGBA || code==CV_YUV2BGRA_NV12 || code==CV_YUV2RGBA_NV12) ? 4 : 3; + const int bIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2BGR_NV12 || code==CV_YUV2BGRA_NV12) ? 0 : 2; + const int uIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0; + + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + + Size dstSz(sz.width, sz.height * 2 / 3); + _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + int srcstep = (int)src.step; + const uchar* y = src.ptr(); + const uchar* uv = y + srcstep * dstSz.height; + + switch(dcn*100 + bIdx * 10 + uIdx) + { + case 300: cvtYUV420sp2RGB<0, 0> (dst, srcstep, y, uv); break; + case 301: cvtYUV420sp2RGB<0, 1> (dst, srcstep, y, uv); break; + case 320: cvtYUV420sp2RGB<2, 0> (dst, srcstep, y, uv); break; + case 321: cvtYUV420sp2RGB<2, 1> (dst, srcstep, y, uv); break; + case 400: cvtYUV420sp2RGBA<0, 0>(dst, srcstep, y, uv); break; + case 401: cvtYUV420sp2RGBA<0, 1>(dst, srcstep, y, uv); break; + case 420: cvtYUV420sp2RGBA<2, 0>(dst, srcstep, y, uv); break; + case 421: cvtYUV420sp2RGBA<2, 1>(dst, srcstep, y, uv); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; + } + break; + case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12: + case CV_YUV2BGR_IYUV: case CV_YUV2RGB_IYUV: case CV_YUV2BGRA_IYUV: case CV_YUV2RGBA_IYUV: + { + //http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes. + //http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes + + if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3; + const int bIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2BGR_IYUV || code==CV_YUV2BGRA_IYUV) ? 0 : 2; + const int uIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0; + + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + + Size dstSz(sz.width, sz.height * 2 / 3); + _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + int srcstep = (int)src.step; + const uchar* y = src.ptr(); + const uchar* u = y + srcstep * dstSz.height; + const uchar* v = y + srcstep * (dstSz.height + dstSz.height/4) + (dstSz.width/2) * ((dstSz.height % 4)/2); + + int ustepIdx = 0; + int vstepIdx = dstSz.height % 4 == 2 ? 1 : 0; + + if(uIdx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); }; + + switch(dcn*10 + bIdx) + { + case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; + case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; + case 40: cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; + case 42: cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; + } + break; + case CV_YUV2GRAY_420: + { + if (dcn <= 0) dcn = 1; + + CV_Assert( dcn == 1 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + + Size dstSz(sz.width, sz.height * 2 / 3); + _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + src(Range(0, dstSz.height), Range::all()).copyTo(dst); + } + break; + case CV_RGB2YUV_YV12: case CV_BGR2YUV_YV12: case CV_RGBA2YUV_YV12: case CV_BGRA2YUV_YV12: + case CV_RGB2YUV_IYUV: case CV_BGR2YUV_IYUV: case CV_RGBA2YUV_IYUV: case CV_BGRA2YUV_IYUV: + { + if (dcn <= 0) dcn = 1; + const int bIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_BGR2YUV_YV12 || code == CV_BGRA2YUV_YV12) ? 0 : 2; + const int uIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_RGB2YUV_IYUV || code == CV_RGBA2YUV_IYUV) ? 1 : 2; + + CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); + CV_Assert( dcn == 1 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 ); + + Size dstSz(sz.width, sz.height / 2 * 3); + _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + switch(bIdx + uIdx*10) + { + case 10: cvtRGBtoYUV420p<0, 1>(src, dst); break; + case 12: cvtRGBtoYUV420p<2, 1>(src, dst); break; + case 20: cvtRGBtoYUV420p<0, 2>(src, dst); break; + case 22: cvtRGBtoYUV420p<2, 2>(src, dst); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; + } + break; + case CV_YUV2RGB_UYVY: case CV_YUV2BGR_UYVY: case CV_YUV2RGBA_UYVY: case CV_YUV2BGRA_UYVY: + case CV_YUV2RGB_YUY2: case CV_YUV2BGR_YUY2: case CV_YUV2RGB_YVYU: case CV_YUV2BGR_YVYU: + case CV_YUV2RGBA_YUY2: case CV_YUV2BGRA_YUY2: case CV_YUV2RGBA_YVYU: case CV_YUV2BGRA_YVYU: + { + //http://www.fourcc.org/yuv.php#UYVY + //http://www.fourcc.org/yuv.php#YUY2 + //http://www.fourcc.org/yuv.php#YVYU + + if (dcn <= 0) dcn = (code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2RGBA_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 4 : 3; + const int bIdx = (code==CV_YUV2BGR_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2BGR_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2BGR_YVYU || code==CV_YUV2BGRA_YVYU) ? 0 : 2; + const int ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0; + const int uIdx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0; + + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( scn == 2 && depth == CV_8U ); + + _dst.create(sz, CV_8UC(dcn)); + dst = _dst.getMat(); + + switch(dcn*1000 + bIdx*100 + uIdx*10 + ycn) + { + case 3000: cvtYUV422toRGB<0,0,0>(dst, (int)src.step, src.ptr()); break; + case 3001: cvtYUV422toRGB<0,0,1>(dst, (int)src.step, src.ptr()); break; + case 3010: cvtYUV422toRGB<0,1,0>(dst, (int)src.step, src.ptr()); break; + case 3011: cvtYUV422toRGB<0,1,1>(dst, (int)src.step, src.ptr()); break; + case 3200: cvtYUV422toRGB<2,0,0>(dst, (int)src.step, src.ptr()); break; + case 3201: cvtYUV422toRGB<2,0,1>(dst, (int)src.step, src.ptr()); break; + case 3210: cvtYUV422toRGB<2,1,0>(dst, (int)src.step, src.ptr()); break; + case 3211: cvtYUV422toRGB<2,1,1>(dst, (int)src.step, src.ptr()); break; + case 4000: cvtYUV422toRGBA<0,0,0>(dst, (int)src.step, src.ptr()); break; + case 4001: cvtYUV422toRGBA<0,0,1>(dst, (int)src.step, src.ptr()); break; + case 4010: cvtYUV422toRGBA<0,1,0>(dst, (int)src.step, src.ptr()); break; + case 4011: cvtYUV422toRGBA<0,1,1>(dst, (int)src.step, src.ptr()); break; + case 4200: cvtYUV422toRGBA<2,0,0>(dst, (int)src.step, src.ptr()); break; + case 4201: cvtYUV422toRGBA<2,0,1>(dst, (int)src.step, src.ptr()); break; + case 4210: cvtYUV422toRGBA<2,1,0>(dst, (int)src.step, src.ptr()); break; + case 4211: cvtYUV422toRGBA<2,1,1>(dst, (int)src.step, src.ptr()); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; + } + break; + case CV_YUV2GRAY_UYVY: case CV_YUV2GRAY_YUY2: + { + if (dcn <= 0) dcn = 1; + + CV_Assert( dcn == 1 ); + CV_Assert( scn == 2 && depth == CV_8U ); + + extractChannel(_src, _dst, code == CV_YUV2GRAY_UYVY ? 1 : 0); + } + break; + case CV_RGBA2mRGBA: + { + if (dcn <= 0) dcn = 4; + CV_Assert( scn == 4 && dcn == 4 ); + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { + CvtColorLoop(src, dst, RGBA2mRGBA()); + } else { + CV_Error( CV_StsBadArg, "Unsupported image depth" ); + } + } + break; + case CV_mRGBA2RGBA: + { + if (dcn <= 0) dcn = 4; + CV_Assert( scn == 4 && dcn == 4 ); + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { + CvtColorLoop(src, dst, mRGBA2RGBA()); + } else { + CV_Error( CV_StsBadArg, "Unsupported image depth" ); + } + } + break; + default: + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + } +} + +CV_IMPL void +cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0; + CV_Assert( src.depth() == dst.depth() ); + + cv::cvtColor(src, dst, code, dst.channels()); + CV_Assert( dst.data == dst0.data ); +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/contours.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/contours.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/contours.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/contours.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2057 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +/* initializes 8-element array for fast access to 3x3 neighborhood of a pixel */ +#define CV_INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)) + +static const CvPoint icvCodeDeltas[8] = + { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} }; + +CV_IMPL void +cvStartReadChainPoints( CvChain * chain, CvChainPtReader * reader ) +{ + int i; + + if( !chain || !reader ) + CV_Error( CV_StsNullPtr, "" ); + + if( chain->elem_size != 1 || chain->header_size < (int)sizeof(CvChain)) + CV_Error( CV_StsBadSize, "" ); + + cvStartReadSeq( (CvSeq *) chain, (CvSeqReader *) reader, 0 ); + + reader->pt = chain->origin; + for( i = 0; i < 8; i++ ) + { + reader->deltas[i][0] = (schar) icvCodeDeltas[i].x; + reader->deltas[i][1] = (schar) icvCodeDeltas[i].y; + } +} + + +/* retrieves next point of the chain curve and updates reader */ +CV_IMPL CvPoint +cvReadChainPoint( CvChainPtReader * reader ) +{ + schar *ptr; + int code; + CvPoint pt = { 0, 0 }; + + if( !reader ) + CV_Error( CV_StsNullPtr, "" ); + + pt = reader->pt; + + ptr = reader->ptr; + if( ptr ) + { + code = *ptr++; + + if( ptr >= reader->block_max ) + { + cvChangeSeqBlock( (CvSeqReader *) reader, 1 ); + ptr = reader->ptr; + } + + reader->ptr = ptr; + reader->code = (schar)code; + assert( (code & ~7) == 0 ); + reader->pt.x = pt.x + icvCodeDeltas[code].x; + reader->pt.y = pt.y + icvCodeDeltas[code].y; + } + + return pt; +} + + +/****************************************************************************************\ +* Raster->Chain Tree (Suzuki algorithms) * +\****************************************************************************************/ + +typedef struct _CvContourInfo +{ + int flags; + struct _CvContourInfo *next; /* next contour with the same mark value */ + struct _CvContourInfo *parent; /* information about parent contour */ + CvSeq *contour; /* corresponding contour (may be 0, if rejected) */ + CvRect rect; /* bounding rectangle */ + CvPoint origin; /* origin point (where the contour was traced from) */ + int is_hole; /* hole flag */ +} +_CvContourInfo; + + +/* + Structure that is used for sequental retrieving contours from the image. + It supports both hierarchical and plane variants of Suzuki algorithm. +*/ +typedef struct _CvContourScanner +{ + CvMemStorage *storage1; /* contains fetched contours */ + CvMemStorage *storage2; /* contains approximated contours + (!=storage1 if approx_method2 != approx_method1) */ + CvMemStorage *cinfo_storage; /* contains _CvContourInfo nodes */ + CvSet *cinfo_set; /* set of _CvContourInfo nodes */ + CvMemStoragePos initial_pos; /* starting storage pos */ + CvMemStoragePos backup_pos; /* beginning of the latest approx. contour */ + CvMemStoragePos backup_pos2; /* ending of the latest approx. contour */ + schar *img0; /* image origin */ + schar *img; /* current image row */ + int img_step; /* image step */ + CvSize img_size; /* ROI size */ + CvPoint offset; /* ROI offset: coordinates, added to each contour point */ + CvPoint pt; /* current scanner position */ + CvPoint lnbd; /* position of the last met contour */ + int nbd; /* current mark val */ + _CvContourInfo *l_cinfo; /* information about latest approx. contour */ + _CvContourInfo cinfo_temp; /* temporary var which is used in simple modes */ + _CvContourInfo frame_info; /* information about frame */ + CvSeq frame; /* frame itself */ + int approx_method1; /* approx method when tracing */ + int approx_method2; /* final approx method */ + int mode; /* contour scanning mode: + 0 - external only + 1 - all the contours w/o any hierarchy + 2 - connected components (i.e. two-level structure - + external contours and holes), + 3 - full hierarchy; + 4 - connected components of a multi-level image + */ + int subst_flag; + int seq_type1; /* type of fetched contours */ + int header_size1; /* hdr size of fetched contours */ + int elem_size1; /* elem size of fetched contours */ + int seq_type2; /* */ + int header_size2; /* the same for approx. contours */ + int elem_size2; /* */ + _CvContourInfo *cinfo_table[128]; +} +_CvContourScanner; + +#define _CV_FIND_CONTOURS_FLAGS_EXTERNAL_ONLY 1 +#define _CV_FIND_CONTOURS_FLAGS_HIERARCHIC 2 + +/* + Initializes scanner structure. + Prepare image for scanning ( clear borders and convert all pixels to 0-1. +*/ +CV_IMPL CvContourScanner +cvStartFindContours( void* _img, CvMemStorage* storage, + int header_size, int mode, + int method, CvPoint offset ) +{ + if( !storage ) + CV_Error( CV_StsNullPtr, "" ); + + CvMat stub, *mat = cvGetMat( _img, &stub ); + + if( CV_MAT_TYPE(mat->type) == CV_32SC1 && mode == CV_RETR_CCOMP ) + mode = CV_RETR_FLOODFILL; + + if( !((CV_IS_MASK_ARR( mat ) && mode < CV_RETR_FLOODFILL) || + (CV_MAT_TYPE(mat->type) == CV_32SC1 && mode == CV_RETR_FLOODFILL)) ) + CV_Error( CV_StsUnsupportedFormat, "[Start]FindContours support only 8uC1 and 32sC1 images" ); + + CvSize size = cvSize( mat->width, mat->height ); + int step = mat->step; + uchar* img = (uchar*)(mat->data.ptr); + + if( method < 0 || method > CV_CHAIN_APPROX_TC89_KCOS ) + CV_Error( CV_StsOutOfRange, "" ); + + if( header_size < (int) (method == CV_CHAIN_CODE ? sizeof( CvChain ) : sizeof( CvContour ))) + CV_Error( CV_StsBadSize, "" ); + + CvContourScanner scanner = (CvContourScanner)cvAlloc( sizeof( *scanner )); + memset( scanner, 0, sizeof(*scanner) ); + + scanner->storage1 = scanner->storage2 = storage; + scanner->img0 = (schar *) img; + scanner->img = (schar *) (img + step); + scanner->img_step = step; + scanner->img_size.width = size.width - 1; /* exclude rightest column */ + scanner->img_size.height = size.height - 1; /* exclude bottomost row */ + scanner->mode = mode; + scanner->offset = offset; + scanner->pt.x = scanner->pt.y = 1; + scanner->lnbd.x = 0; + scanner->lnbd.y = 1; + scanner->nbd = 2; + scanner->mode = (int) mode; + scanner->frame_info.contour = &(scanner->frame); + scanner->frame_info.is_hole = 1; + scanner->frame_info.next = 0; + scanner->frame_info.parent = 0; + scanner->frame_info.rect = cvRect( 0, 0, size.width, size.height ); + scanner->l_cinfo = 0; + scanner->subst_flag = 0; + + scanner->frame.flags = CV_SEQ_FLAG_HOLE; + + scanner->approx_method2 = scanner->approx_method1 = method; + + if( method == CV_CHAIN_APPROX_TC89_L1 || method == CV_CHAIN_APPROX_TC89_KCOS ) + scanner->approx_method1 = CV_CHAIN_CODE; + + if( scanner->approx_method1 == CV_CHAIN_CODE ) + { + scanner->seq_type1 = CV_SEQ_CHAIN_CONTOUR; + scanner->header_size1 = scanner->approx_method1 == scanner->approx_method2 ? + header_size : sizeof( CvChain ); + scanner->elem_size1 = sizeof( char ); + } + else + { + scanner->seq_type1 = CV_SEQ_POLYGON; + scanner->header_size1 = scanner->approx_method1 == scanner->approx_method2 ? + header_size : sizeof( CvContour ); + scanner->elem_size1 = sizeof( CvPoint ); + } + + scanner->header_size2 = header_size; + + if( scanner->approx_method2 == CV_CHAIN_CODE ) + { + scanner->seq_type2 = scanner->seq_type1; + scanner->elem_size2 = scanner->elem_size1; + } + else + { + scanner->seq_type2 = CV_SEQ_POLYGON; + scanner->elem_size2 = sizeof( CvPoint ); + } + + scanner->seq_type1 = scanner->approx_method1 == CV_CHAIN_CODE ? + CV_SEQ_CHAIN_CONTOUR : CV_SEQ_POLYGON; + + scanner->seq_type2 = scanner->approx_method2 == CV_CHAIN_CODE ? + CV_SEQ_CHAIN_CONTOUR : CV_SEQ_POLYGON; + + cvSaveMemStoragePos( storage, &(scanner->initial_pos) ); + + if( method > CV_CHAIN_APPROX_SIMPLE ) + { + scanner->storage1 = cvCreateChildMemStorage( scanner->storage2 ); + } + + if( mode > CV_RETR_LIST ) + { + scanner->cinfo_storage = cvCreateChildMemStorage( scanner->storage2 ); + scanner->cinfo_set = cvCreateSet( 0, sizeof( CvSet ), sizeof( _CvContourInfo ), + scanner->cinfo_storage ); + } + + /* make zero borders */ + int esz = CV_ELEM_SIZE(mat->type); + memset( img, 0, size.width*esz ); + memset( img + step * (size.height - 1), 0, size.width*esz ); + + img += step; + for( int y = 1; y < size.height - 1; y++, img += step ) + { + for( int k = 0; k < esz; k++ ) + img[k] = img[(size.width - 1)*esz + k] = (schar)0; + } + + /* converts all pixels to 0 or 1 */ + if( CV_MAT_TYPE(mat->type) != CV_32S ) + cvThreshold( mat, mat, 0, 1, CV_THRESH_BINARY ); + + return scanner; +} + +/* + Final stage of contour processing. + Three variants possible: + 1. Contour, which was retrieved using border following, is added to + the contour tree. It is the case when the icvSubstituteContour function + was not called after retrieving the contour. + + 2. New contour, assigned by icvSubstituteContour function, is added to the + tree. The retrieved contour itself is removed from the storage. + Here two cases are possible: + 2a. If one deals with plane variant of algorithm + (hierarchical strucutre is not reconstructed), + the contour is removed completely. + 2b. In hierarchical case, the header of the contour is not removed. + It's marked as "link to contour" and h_next pointer of it is set to + new, substituting contour. + + 3. The similar to 2, but when NULL pointer was assigned by + icvSubstituteContour function. In this case, the function removes + retrieved contour completely if plane case and + leaves header if hierarchical (but doesn't mark header as "link"). + ------------------------------------------------------------------------ + The 1st variant can be used to retrieve and store all the contours from the image + (with optional convertion from chains to contours using some approximation from + restriced set of methods). Some characteristics of contour can be computed in the + same pass. + + The usage scheme can look like: + + icvContourScanner scanner; + CvMemStorage* contour_storage; + CvSeq* first_contour; + CvStatus result; + + ... + + icvCreateMemStorage( &contour_storage, block_size/0 ); + + ... + + cvStartFindContours + ( img, contour_storage, + header_size, approx_method, + [external_only,] + &scanner ); + + for(;;) + { + [CvSeq* contour;] + result = icvFindNextContour( &scanner, &contour/0 ); + + if( result != CV_OK ) break; + + // calculate some characteristics + ... + } + + if( result < 0 ) goto error_processing; + + cvEndFindContours( &scanner, &first_contour ); + ... + + ----------------------------------------------------------------- + + Second variant is more complex and can be used when someone wants store not + the retrieved contours but transformed ones. (e.g. approximated with some + non-default algorithm ). + + The scheme can be the as following: + + icvContourScanner scanner; + CvMemStorage* contour_storage; + CvMemStorage* temp_storage; + CvSeq* first_contour; + CvStatus result; + + ... + + icvCreateMemStorage( &contour_storage, block_size/0 ); + icvCreateMemStorage( &temp_storage, block_size/0 ); + + ... + + icvStartFindContours8uC1R + ( , temp_storage, + header_size, approx_method, + [retrival_mode], + &scanner ); + + for(;;) + { + CvSeq* temp_contour; + CvSeq* new_contour; + result = icvFindNextContour( scanner, &temp_contour ); + + if( result != CV_OK ) break; + + ( temp_contour, contour_storage, + &new_contour, ); + + icvSubstituteContour( scanner, new_contour ); + ... + } + + if( result < 0 ) goto error_processing; + + cvEndFindContours( &scanner, &first_contour ); + ... + + ---------------------------------------------------------------------------- + Third method to retrieve contours may be applied if contours are irrelevant + themselves but some characteristics of them are used only. + The usage is similar to second except slightly different internal loop + + for(;;) + { + CvSeq* temp_contour; + result = icvFindNextContour( &scanner, &temp_contour ); + + if( result != CV_OK ) break; + + // calculate some characteristics of temp_contour + + icvSubstituteContour( scanner, 0 ); + ... + } + + new_storage variable is not needed here. + + Note, that the second and the third methods can interleave. I.e. it is possible to + retain contours that satisfy with some criteria and reject others. + In hierarchic case the resulting tree is the part of original tree with + some nodes absent. But in the resulting tree the contour1 is a child + (may be indirect) of contour2 iff in the original tree the contour1 + is a child (may be indirect) of contour2. +*/ +static void +icvEndProcessContour( CvContourScanner scanner ) +{ + _CvContourInfo *l_cinfo = scanner->l_cinfo; + + if( l_cinfo ) + { + if( scanner->subst_flag ) + { + CvMemStoragePos temp; + + cvSaveMemStoragePos( scanner->storage2, &temp ); + + if( temp.top == scanner->backup_pos2.top && + temp.free_space == scanner->backup_pos2.free_space ) + { + cvRestoreMemStoragePos( scanner->storage2, &scanner->backup_pos ); + } + scanner->subst_flag = 0; + } + + if( l_cinfo->contour ) + { + cvInsertNodeIntoTree( l_cinfo->contour, l_cinfo->parent->contour, + &(scanner->frame) ); + } + scanner->l_cinfo = 0; + } +} + +/* replaces one contour with another */ +CV_IMPL void +cvSubstituteContour( CvContourScanner scanner, CvSeq * new_contour ) +{ + _CvContourInfo *l_cinfo; + + if( !scanner ) + CV_Error( CV_StsNullPtr, "" ); + + l_cinfo = scanner->l_cinfo; + if( l_cinfo && l_cinfo->contour && l_cinfo->contour != new_contour ) + { + l_cinfo->contour = new_contour; + scanner->subst_flag = 1; + } +} + + +/* + marks domain border with +/- and stores the contour into CvSeq. + method: + <0 - chain + ==0 - direct + >0 - simple approximation +*/ +static void +icvFetchContour( schar *ptr, + int step, + CvPoint pt, + CvSeq* contour, + int _method ) +{ + const schar nbd = 2; + int deltas[16]; + CvSeqWriter writer; + schar *i0 = ptr, *i1, *i3, *i4 = 0; + int prev_s = -1, s, s_end; + int method = _method - 1; + + assert( (unsigned) _method <= CV_CHAIN_APPROX_SIMPLE ); + + /* initialize local state */ + CV_INIT_3X3_DELTAS( deltas, step, 1 ); + memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); + + /* initialize writer */ + cvStartAppendToSeq( contour, &writer ); + + if( method < 0 ) + ((CvChain *) contour)->origin = pt; + + s_end = s = CV_IS_SEQ_HOLE( contour ) ? 0 : 4; + + do + { + s = (s - 1) & 7; + i1 = i0 + deltas[s]; + if( *i1 != 0 ) + break; + } + while( s != s_end ); + + if( s == s_end ) /* single pixel domain */ + { + *i0 = (schar) (nbd | -128); + if( method >= 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + } + else + { + i3 = i0; + prev_s = s ^ 4; + + /* follow border */ + for( ;; ) + { + s_end = s; + + for( ;; ) + { + i4 = i3 + deltas[++s]; + if( *i4 != 0 ) + break; + } + s &= 7; + + /* check "right" bound */ + if( (unsigned) (s - 1) < (unsigned) s_end ) + { + *i3 = (schar) (nbd | -128); + } + else if( *i3 == 1 ) + { + *i3 = nbd; + } + + if( method < 0 ) + { + schar _s = (schar) s; + + CV_WRITE_SEQ_ELEM( _s, writer ); + } + else + { + if( s != prev_s || method == 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + prev_s = s; + } + + pt.x += icvCodeDeltas[s].x; + pt.y += icvCodeDeltas[s].y; + + } + + if( i4 == i0 && i3 == i1 ) + break; + + i3 = i4; + s = (s + 4) & 7; + } /* end of border following loop */ + } + + cvEndWriteSeq( &writer ); + + if( _method != CV_CHAIN_CODE ) + cvBoundingRect( contour, 1 ); + + assert( (writer.seq->total == 0 && writer.seq->first == 0) || + writer.seq->total > writer.seq->first->count || + (writer.seq->first->prev == writer.seq->first && + writer.seq->first->next == writer.seq->first) ); +} + + + +/* + trace contour until certain point is met. + returns 1 if met, 0 else. +*/ +static int +icvTraceContour( schar *ptr, int step, schar *stop_ptr, int is_hole ) +{ + int deltas[16]; + schar *i0 = ptr, *i1, *i3, *i4; + int s, s_end; + + /* initialize local state */ + CV_INIT_3X3_DELTAS( deltas, step, 1 ); + memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); + + assert( (*i0 & -2) != 0 ); + + s_end = s = is_hole ? 0 : 4; + + do + { + s = (s - 1) & 7; + i1 = i0 + deltas[s]; + if( *i1 != 0 ) + break; + } + while( s != s_end ); + + i3 = i0; + + /* check single pixel domain */ + if( s != s_end ) + { + /* follow border */ + for( ;; ) + { + s_end = s; + + for( ;; ) + { + i4 = i3 + deltas[++s]; + if( *i4 != 0 ) + break; + } + + if( i3 == stop_ptr || (i4 == i0 && i3 == i1) ) + break; + + i3 = i4; + s = (s + 4) & 7; + } /* end of border following loop */ + } + return i3 == stop_ptr; +} + + +static void +icvFetchContourEx( schar* ptr, + int step, + CvPoint pt, + CvSeq* contour, + int _method, + int nbd, + CvRect* _rect ) +{ + int deltas[16]; + CvSeqWriter writer; + schar *i0 = ptr, *i1, *i3, *i4; + CvRect rect; + int prev_s = -1, s, s_end; + int method = _method - 1; + + assert( (unsigned) _method <= CV_CHAIN_APPROX_SIMPLE ); + assert( 1 < nbd && nbd < 128 ); + + /* initialize local state */ + CV_INIT_3X3_DELTAS( deltas, step, 1 ); + memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); + + /* initialize writer */ + cvStartAppendToSeq( contour, &writer ); + + if( method < 0 ) + ((CvChain *)contour)->origin = pt; + + rect.x = rect.width = pt.x; + rect.y = rect.height = pt.y; + + s_end = s = CV_IS_SEQ_HOLE( contour ) ? 0 : 4; + + do + { + s = (s - 1) & 7; + i1 = i0 + deltas[s]; + if( *i1 != 0 ) + break; + } + while( s != s_end ); + + if( s == s_end ) /* single pixel domain */ + { + *i0 = (schar) (nbd | 0x80); + if( method >= 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + } + else + { + i3 = i0; + + prev_s = s ^ 4; + + /* follow border */ + for( ;; ) + { + s_end = s; + + for( ;; ) + { + i4 = i3 + deltas[++s]; + if( *i4 != 0 ) + break; + } + s &= 7; + + /* check "right" bound */ + if( (unsigned) (s - 1) < (unsigned) s_end ) + { + *i3 = (schar) (nbd | 0x80); + } + else if( *i3 == 1 ) + { + *i3 = (schar) nbd; + } + + if( method < 0 ) + { + schar _s = (schar) s; + CV_WRITE_SEQ_ELEM( _s, writer ); + } + else if( s != prev_s || method == 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + + if( s != prev_s ) + { + /* update bounds */ + if( pt.x < rect.x ) + rect.x = pt.x; + else if( pt.x > rect.width ) + rect.width = pt.x; + + if( pt.y < rect.y ) + rect.y = pt.y; + else if( pt.y > rect.height ) + rect.height = pt.y; + } + + prev_s = s; + pt.x += icvCodeDeltas[s].x; + pt.y += icvCodeDeltas[s].y; + + if( i4 == i0 && i3 == i1 ) break; + + i3 = i4; + s = (s + 4) & 7; + } /* end of border following loop */ + } + + rect.width -= rect.x - 1; + rect.height -= rect.y - 1; + + cvEndWriteSeq( &writer ); + + if( _method != CV_CHAIN_CODE ) + ((CvContour*)contour)->rect = rect; + + assert( (writer.seq->total == 0 && writer.seq->first == 0) || + writer.seq->total > writer.seq->first->count || + (writer.seq->first->prev == writer.seq->first && + writer.seq->first->next == writer.seq->first) ); + + if( _rect ) *_rect = rect; +} + + +static int +icvTraceContour_32s( int *ptr, int step, int *stop_ptr, int is_hole ) +{ + int deltas[16]; + int *i0 = ptr, *i1, *i3, *i4; + int s, s_end; + const int right_flag = INT_MIN; + const int new_flag = (int)((unsigned)INT_MIN >> 1); + const int value_mask = ~(right_flag | new_flag); + const int ccomp_val = *i0 & value_mask; + + /* initialize local state */ + CV_INIT_3X3_DELTAS( deltas, step, 1 ); + memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); + + s_end = s = is_hole ? 0 : 4; + + do + { + s = (s - 1) & 7; + i1 = i0 + deltas[s]; + if( (*i1 & value_mask) == ccomp_val ) + break; + } + while( s != s_end ); + + i3 = i0; + + /* check single pixel domain */ + if( s != s_end ) + { + /* follow border */ + for( ;; ) + { + s_end = s; + + for( ;; ) + { + i4 = i3 + deltas[++s]; + if( (*i4 & value_mask) == ccomp_val ) + break; + } + + if( i3 == stop_ptr || (i4 == i0 && i3 == i1) ) + break; + + i3 = i4; + s = (s + 4) & 7; + } /* end of border following loop */ + } + return i3 == stop_ptr; +} + + +static void +icvFetchContourEx_32s( int* ptr, + int step, + CvPoint pt, + CvSeq* contour, + int _method, + CvRect* _rect ) +{ + int deltas[16]; + CvSeqWriter writer; + int *i0 = ptr, *i1, *i3, *i4; + CvRect rect; + int prev_s = -1, s, s_end; + int method = _method - 1; + const int right_flag = INT_MIN; + const int new_flag = (int)((unsigned)INT_MIN >> 1); + const int value_mask = ~(right_flag | new_flag); + const int ccomp_val = *i0 & value_mask; + const int nbd0 = ccomp_val | new_flag; + const int nbd1 = nbd0 | right_flag; + + assert( (unsigned) _method <= CV_CHAIN_APPROX_SIMPLE ); + + /* initialize local state */ + CV_INIT_3X3_DELTAS( deltas, step, 1 ); + memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); + + /* initialize writer */ + cvStartAppendToSeq( contour, &writer ); + + if( method < 0 ) + ((CvChain *)contour)->origin = pt; + + rect.x = rect.width = pt.x; + rect.y = rect.height = pt.y; + + s_end = s = CV_IS_SEQ_HOLE( contour ) ? 0 : 4; + + do + { + s = (s - 1) & 7; + i1 = i0 + deltas[s]; + if( (*i1 & value_mask) == ccomp_val ) + break; + } + while( s != s_end ); + + if( s == s_end ) /* single pixel domain */ + { + *i0 = nbd1; + if( method >= 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + } + else + { + i3 = i0; + prev_s = s ^ 4; + + /* follow border */ + for( ;; ) + { + s_end = s; + + for( ;; ) + { + i4 = i3 + deltas[++s]; + if( (*i4 & value_mask) == ccomp_val ) + break; + } + s &= 7; + + /* check "right" bound */ + if( (unsigned) (s - 1) < (unsigned) s_end ) + { + *i3 = nbd1; + } + else if( *i3 == ccomp_val ) + { + *i3 = nbd0; + } + + if( method < 0 ) + { + schar _s = (schar) s; + CV_WRITE_SEQ_ELEM( _s, writer ); + } + else if( s != prev_s || method == 0 ) + { + CV_WRITE_SEQ_ELEM( pt, writer ); + } + + if( s != prev_s ) + { + /* update bounds */ + if( pt.x < rect.x ) + rect.x = pt.x; + else if( pt.x > rect.width ) + rect.width = pt.x; + + if( pt.y < rect.y ) + rect.y = pt.y; + else if( pt.y > rect.height ) + rect.height = pt.y; + } + + prev_s = s; + pt.x += icvCodeDeltas[s].x; + pt.y += icvCodeDeltas[s].y; + + if( i4 == i0 && i3 == i1 ) break; + + i3 = i4; + s = (s + 4) & 7; + } /* end of border following loop */ + } + + rect.width -= rect.x - 1; + rect.height -= rect.y - 1; + + cvEndWriteSeq( &writer ); + + if( _method != CV_CHAIN_CODE ) + ((CvContour*)contour)->rect = rect; + + assert( (writer.seq->total == 0 && writer.seq->first == 0) || + writer.seq->total > writer.seq->first->count || + (writer.seq->first->prev == writer.seq->first && + writer.seq->first->next == writer.seq->first) ); + + if( _rect ) *_rect = rect; +} + + +CvSeq * +cvFindNextContour( CvContourScanner scanner ) +{ + if( !scanner ) + CV_Error( CV_StsNullPtr, "" ); + icvEndProcessContour( scanner ); + + /* initialize local state */ + schar* img0 = scanner->img0; + schar* img = scanner->img; + int step = scanner->img_step; + int step_i = step / sizeof(int); + int x = scanner->pt.x; + int y = scanner->pt.y; + int width = scanner->img_size.width; + int height = scanner->img_size.height; + int mode = scanner->mode; + CvPoint lnbd = scanner->lnbd; + int nbd = scanner->nbd; + int prev = img[x - 1]; + int new_mask = -2; + + if( mode == CV_RETR_FLOODFILL ) + { + prev = ((int*)img)[x - 1]; + new_mask = INT_MIN >> 1; + } + + for( ; y < height; y++, img += step ) + { + int* img0_i = 0; + int* img_i = 0; + int p = 0; + + if( mode == CV_RETR_FLOODFILL ) + { + img0_i = (int*)img0; + img_i = (int*)img; + } + + for( ; x < width; x++ ) + { + if( img_i ) + { + for( ; x < width && ((p = img_i[x]) == prev || (p & ~new_mask) == (prev & ~new_mask)); x++ ) + prev = p; + } + else + { + for( ; x < width && (p = img[x]) == prev; x++ ) + ; + } + + if( x >= width ) + break; + + { + _CvContourInfo *par_info = 0; + _CvContourInfo *l_cinfo = 0; + CvSeq *seq = 0; + int is_hole = 0; + CvPoint origin; + + /* if not external contour */ + if( (!img_i && !(prev == 0 && p == 1)) || + (img_i && !(((prev & new_mask) != 0 || prev == 0) && (p & new_mask) == 0)) ) + { + /* check hole */ + if( (!img_i && (p != 0 || prev < 1)) || + (img_i && ((prev & new_mask) != 0 || (p & new_mask) != 0))) + goto resume_scan; + + if( prev & new_mask ) + { + lnbd.x = x - 1; + } + is_hole = 1; + } + + if( mode == 0 && (is_hole || img0[lnbd.y * step + lnbd.x] > 0) ) + goto resume_scan; + + origin.y = y; + origin.x = x - is_hole; + + /* find contour parent */ + if( mode <= 1 || (!is_hole && (mode == CV_RETR_CCOMP || mode == CV_RETR_FLOODFILL)) || lnbd.x <= 0 ) + { + par_info = &(scanner->frame_info); + } + else + { + int lval = (img0_i ? + img0_i[lnbd.y * step_i + lnbd.x] : + (int)img0[lnbd.y * step + lnbd.x]) & 0x7f; + _CvContourInfo *cur = scanner->cinfo_table[lval]; + + /* find the first bounding contour */ + while( cur ) + { + if( (unsigned) (lnbd.x - cur->rect.x) < (unsigned) cur->rect.width && + (unsigned) (lnbd.y - cur->rect.y) < (unsigned) cur->rect.height ) + { + if( par_info ) + { + if( (img0_i && + icvTraceContour_32s( img0_i + par_info->origin.y * step_i + + par_info->origin.x, step_i, img_i + lnbd.x, + par_info->is_hole ) > 0) || + (!img0_i && + icvTraceContour( img0 + par_info->origin.y * step + + par_info->origin.x, step, img + lnbd.x, + par_info->is_hole ) > 0) ) + break; + } + par_info = cur; + } + cur = cur->next; + } + + assert( par_info != 0 ); + + /* if current contour is a hole and previous contour is a hole or + current contour is external and previous contour is external then + the parent of the contour is the parent of the previous contour else + the parent is the previous contour itself. */ + if( par_info->is_hole == is_hole ) + { + par_info = par_info->parent; + /* every contour must have a parent + (at least, the frame of the image) */ + if( !par_info ) + par_info = &(scanner->frame_info); + } + + /* hole flag of the parent must differ from the flag of the contour */ + assert( par_info->is_hole != is_hole ); + if( par_info->contour == 0 ) /* removed contour */ + goto resume_scan; + } + + lnbd.x = x - is_hole; + + cvSaveMemStoragePos( scanner->storage2, &(scanner->backup_pos) ); + + seq = cvCreateSeq( scanner->seq_type1, scanner->header_size1, + scanner->elem_size1, scanner->storage1 ); + seq->flags |= is_hole ? CV_SEQ_FLAG_HOLE : 0; + + /* initialize header */ + if( mode <= 1 ) + { + l_cinfo = &(scanner->cinfo_temp); + icvFetchContour( img + x - is_hole, step, + cvPoint( origin.x + scanner->offset.x, + origin.y + scanner->offset.y), + seq, scanner->approx_method1 ); + } + else + { + union { _CvContourInfo* ci; CvSetElem* se; } v; + v.ci = l_cinfo; + cvSetAdd( scanner->cinfo_set, 0, &v.se ); + l_cinfo = v.ci; + int lval; + + if( img_i ) + { + lval = img_i[x - is_hole] & 127; + icvFetchContourEx_32s(img_i + x - is_hole, step_i, + cvPoint( origin.x + scanner->offset.x, + origin.y + scanner->offset.y), + seq, scanner->approx_method1, + &(l_cinfo->rect) ); + } + else + { + lval = nbd; + // change nbd + nbd = (nbd + 1) & 127; + nbd += nbd == 0 ? 3 : 0; + icvFetchContourEx( img + x - is_hole, step, + cvPoint( origin.x + scanner->offset.x, + origin.y + scanner->offset.y), + seq, scanner->approx_method1, + lval, &(l_cinfo->rect) ); + } + l_cinfo->rect.x -= scanner->offset.x; + l_cinfo->rect.y -= scanner->offset.y; + + l_cinfo->next = scanner->cinfo_table[lval]; + scanner->cinfo_table[lval] = l_cinfo; + } + + l_cinfo->is_hole = is_hole; + l_cinfo->contour = seq; + l_cinfo->origin = origin; + l_cinfo->parent = par_info; + + if( scanner->approx_method1 != scanner->approx_method2 ) + { + l_cinfo->contour = icvApproximateChainTC89( (CvChain *) seq, + scanner->header_size2, + scanner->storage2, + scanner->approx_method2 ); + cvClearMemStorage( scanner->storage1 ); + } + + l_cinfo->contour->v_prev = l_cinfo->parent->contour; + + if( par_info->contour == 0 ) + { + l_cinfo->contour = 0; + if( scanner->storage1 == scanner->storage2 ) + { + cvRestoreMemStoragePos( scanner->storage1, &(scanner->backup_pos) ); + } + else + { + cvClearMemStorage( scanner->storage1 ); + } + p = img[x]; + goto resume_scan; + } + + cvSaveMemStoragePos( scanner->storage2, &(scanner->backup_pos2) ); + scanner->l_cinfo = l_cinfo; + scanner->pt.x = !img_i ? x + 1 : x + 1 - is_hole; + scanner->pt.y = y; + scanner->lnbd = lnbd; + scanner->img = (schar *) img; + scanner->nbd = nbd; + return l_cinfo->contour; + + resume_scan: + + prev = p; + /* update lnbd */ + if( prev & -2 ) + { + lnbd.x = x; + } + } /* end of prev != p */ + } /* end of loop on x */ + + lnbd.x = 0; + lnbd.y = y + 1; + x = 1; + prev = 0; + } /* end of loop on y */ + + return 0; +} + + +/* + The function add to tree the last retrieved/substituted contour, + releases temp_storage, restores state of dst_storage (if needed), and + returns pointer to root of the contour tree */ +CV_IMPL CvSeq * +cvEndFindContours( CvContourScanner * _scanner ) +{ + CvContourScanner scanner; + CvSeq *first = 0; + + if( !_scanner ) + CV_Error( CV_StsNullPtr, "" ); + scanner = *_scanner; + + if( scanner ) + { + icvEndProcessContour( scanner ); + + if( scanner->storage1 != scanner->storage2 ) + cvReleaseMemStorage( &(scanner->storage1) ); + + if( scanner->cinfo_storage ) + cvReleaseMemStorage( &(scanner->cinfo_storage) ); + + first = scanner->frame.v_next; + cvFree( _scanner ); + } + + return first; +} + + +#define ICV_SINGLE 0 +#define ICV_CONNECTING_ABOVE 1 +#define ICV_CONNECTING_BELOW -1 +#define ICV_IS_COMPONENT_POINT(val) ((val) != 0) + +#define CV_GET_WRITTEN_ELEM( writer ) ((writer).ptr - (writer).seq->elem_size) + +typedef struct CvLinkedRunPoint +{ + struct CvLinkedRunPoint* link; + struct CvLinkedRunPoint* next; + CvPoint pt; +} +CvLinkedRunPoint; + + +static int +icvFindContoursInInterval( const CvArr* src, + /*int minValue, int maxValue,*/ + CvMemStorage* storage, + CvSeq** result, + int contourHeaderSize ) +{ + int count = 0; + cv::Ptr storage00; + cv::Ptr storage01; + CvSeq* first = 0; + + int i, j, k, n; + + uchar* src_data = 0; + int img_step = 0; + CvSize img_size; + + int connect_flag; + int lower_total; + int upper_total; + int all_total; + + CvSeq* runs; + CvLinkedRunPoint tmp; + CvLinkedRunPoint* tmp_prev; + CvLinkedRunPoint* upper_line = 0; + CvLinkedRunPoint* lower_line = 0; + CvLinkedRunPoint* last_elem; + + CvLinkedRunPoint* upper_run = 0; + CvLinkedRunPoint* lower_run = 0; + CvLinkedRunPoint* prev_point = 0; + + CvSeqWriter writer_ext; + CvSeqWriter writer_int; + CvSeqWriter writer; + CvSeqReader reader; + + CvSeq* external_contours; + CvSeq* internal_contours; + CvSeq* prev = 0; + + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + + if( !result ) + CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + + if( contourHeaderSize < (int)sizeof(CvContour)) + CV_Error( CV_StsBadSize, "Contour header size must be >= sizeof(CvContour)" ); + + storage00 = cvCreateChildMemStorage(storage); + storage01 = cvCreateChildMemStorage(storage); + + CvMat stub, *mat; + + mat = cvGetMat( src, &stub ); + if( !CV_IS_MASK_ARR(mat)) + CV_Error( CV_StsBadArg, "Input array must be 8uC1 or 8sC1" ); + src_data = mat->data.ptr; + img_step = mat->step; + img_size = cvGetMatSize( mat ); + + // Create temporary sequences + runs = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvLinkedRunPoint), storage00 ); + cvStartAppendToSeq( runs, &writer ); + + cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_ext ); + cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_int ); + + tmp_prev = &(tmp); + tmp_prev->next = 0; + tmp_prev->link = 0; + + // First line. None of runs is binded + tmp.pt.y = 0; + i = 0; + CV_WRITE_SEQ_ELEM( tmp, writer ); + upper_line = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer ); + + tmp_prev = upper_line; + for( j = 0; j < img_size.width; ) + { + for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ ) + ; + if( j == img_size.width ) + break; + + tmp.pt.x = j; + CV_WRITE_SEQ_ELEM( tmp, writer ); + tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer ); + tmp_prev = tmp_prev->next; + + for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ ) + ; + + tmp.pt.x = j-1; + CV_WRITE_SEQ_ELEM( tmp, writer ); + tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer ); + tmp_prev->link = tmp_prev->next; + // First point of contour + CV_WRITE_SEQ_ELEM( tmp_prev, writer_ext ); + tmp_prev = tmp_prev->next; + } + cvFlushSeqWriter( &writer ); + upper_line = upper_line->next; + upper_total = runs->total - 1; + last_elem = tmp_prev; + tmp_prev->next = 0; + + for( i = 1; i < img_size.height; i++ ) + { +//------// Find runs in next line + src_data += img_step; + tmp.pt.y = i; + all_total = runs->total; + for( j = 0; j < img_size.width; ) + { + for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ ) + ; + if( j == img_size.width ) break; + + tmp.pt.x = j; + CV_WRITE_SEQ_ELEM( tmp, writer ); + tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer ); + tmp_prev = tmp_prev->next; + + for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ ) + ; + + tmp.pt.x = j-1; + CV_WRITE_SEQ_ELEM( tmp, writer ); + tmp_prev = tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer ); + }//j + cvFlushSeqWriter( &writer ); + lower_line = last_elem->next; + lower_total = runs->total - all_total; + last_elem = tmp_prev; + tmp_prev->next = 0; +//------// +//------// Find links between runs of lower_line and upper_line + upper_run = upper_line; + lower_run = lower_line; + connect_flag = ICV_SINGLE; + + for( k = 0, n = 0; k < upper_total/2 && n < lower_total/2; ) + { + switch( connect_flag ) + { + case ICV_SINGLE: + if( upper_run->next->pt.x < lower_run->next->pt.x ) + { + if( upper_run->next->pt.x >= lower_run->pt.x -1 ) + { + lower_run->link = upper_run; + connect_flag = ICV_CONNECTING_ABOVE; + prev_point = upper_run->next; + } + else + upper_run->next->link = upper_run; + k++; + upper_run = upper_run->next->next; + } + else + { + if( upper_run->pt.x <= lower_run->next->pt.x +1 ) + { + lower_run->link = upper_run; + connect_flag = ICV_CONNECTING_BELOW; + prev_point = lower_run->next; + } + else + { + lower_run->link = lower_run->next; + // First point of contour + CV_WRITE_SEQ_ELEM( lower_run, writer_ext ); + } + n++; + lower_run = lower_run->next->next; + } + break; + case ICV_CONNECTING_ABOVE: + if( upper_run->pt.x > lower_run->next->pt.x +1 ) + { + prev_point->link = lower_run->next; + connect_flag = ICV_SINGLE; + n++; + lower_run = lower_run->next->next; + } + else + { + prev_point->link = upper_run; + if( upper_run->next->pt.x < lower_run->next->pt.x ) + { + k++; + prev_point = upper_run->next; + upper_run = upper_run->next->next; + } + else + { + connect_flag = ICV_CONNECTING_BELOW; + prev_point = lower_run->next; + n++; + lower_run = lower_run->next->next; + } + } + break; + case ICV_CONNECTING_BELOW: + if( lower_run->pt.x > upper_run->next->pt.x +1 ) + { + upper_run->next->link = prev_point; + connect_flag = ICV_SINGLE; + k++; + upper_run = upper_run->next->next; + } + else + { + // First point of contour + CV_WRITE_SEQ_ELEM( lower_run, writer_int ); + + lower_run->link = prev_point; + if( lower_run->next->pt.x < upper_run->next->pt.x ) + { + n++; + prev_point = lower_run->next; + lower_run = lower_run->next->next; + } + else + { + connect_flag = ICV_CONNECTING_ABOVE; + k++; + prev_point = upper_run->next; + upper_run = upper_run->next->next; + } + } + break; + } + }// k, n + + for( ; n < lower_total/2; n++ ) + { + if( connect_flag != ICV_SINGLE ) + { + prev_point->link = lower_run->next; + connect_flag = ICV_SINGLE; + lower_run = lower_run->next->next; + continue; + } + lower_run->link = lower_run->next; + + //First point of contour + CV_WRITE_SEQ_ELEM( lower_run, writer_ext ); + + lower_run = lower_run->next->next; + } + + for( ; k < upper_total/2; k++ ) + { + if( connect_flag != ICV_SINGLE ) + { + upper_run->next->link = prev_point; + connect_flag = ICV_SINGLE; + upper_run = upper_run->next->next; + continue; + } + upper_run->next->link = upper_run; + upper_run = upper_run->next->next; + } + upper_line = lower_line; + upper_total = lower_total; + }//i + + upper_run = upper_line; + + //the last line of image + for( k = 0; k < upper_total/2; k++ ) + { + upper_run->next->link = upper_run; + upper_run = upper_run->next->next; + } + +//------// +//------//Find end read contours + external_contours = cvEndWriteSeq( &writer_ext ); + internal_contours = cvEndWriteSeq( &writer_int ); + + for( k = 0; k < 2; k++ ) + { + CvSeq* contours = k == 0 ? external_contours : internal_contours; + + cvStartReadSeq( contours, &reader ); + + for( j = 0; j < contours->total; j++, count++ ) + { + CvLinkedRunPoint* p_temp; + CvLinkedRunPoint* p00; + CvLinkedRunPoint* p01; + CvSeq* contour; + + CV_READ_SEQ_ELEM( p00, reader ); + p01 = p00; + + if( !p00->link ) + continue; + + cvStartWriteSeq( CV_SEQ_ELTYPE_POINT | CV_SEQ_POLYLINE | CV_SEQ_FLAG_CLOSED, + contourHeaderSize, sizeof(CvPoint), storage, &writer ); + do + { + CV_WRITE_SEQ_ELEM( p00->pt, writer ); + p_temp = p00; + p00 = p00->link; + p_temp->link = 0; + } + while( p00 != p01 ); + + contour = cvEndWriteSeq( &writer ); + cvBoundingRect( contour, 1 ); + + if( k != 0 ) + contour->flags |= CV_SEQ_FLAG_HOLE; + + if( !first ) + prev = first = contour; + else + { + contour->h_prev = prev; + prev = prev->h_next = contour; + } + } + } + + if( !first ) + count = -1; + + if( result ) + *result = first; + + return count; +} + + + +/*F/////////////////////////////////////////////////////////////////////////////////////// +// Name: cvFindContours +// Purpose: +// Finds all the contours on the bi-level image. +// Context: +// Parameters: +// img - source image. +// Non-zero pixels are considered as 1-pixels +// and zero pixels as 0-pixels. +// step - full width of source image in bytes. +// size - width and height of the image in pixels +// storage - pointer to storage where will the output contours be placed. +// header_size - header size of resulting contours +// mode - mode of contour retrieval. +// method - method of approximation that is applied to contours +// first_contour - pointer to first contour pointer +// Returns: +// CV_OK or error code +// Notes: +//F*/ +CV_IMPL int +cvFindContours( void* img, CvMemStorage* storage, + CvSeq** firstContour, int cntHeaderSize, + int mode, + int method, CvPoint offset ) +{ + CvContourScanner scanner = 0; + CvSeq *contour = 0; + int count = -1; + + if( !firstContour ) + CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + + *firstContour = 0; + + if( method == CV_LINK_RUNS ) + { + if( offset.x != 0 || offset.y != 0 ) + CV_Error( CV_StsOutOfRange, + "Nonzero offset is not supported in CV_LINK_RUNS yet" ); + + count = icvFindContoursInInterval( img, storage, firstContour, cntHeaderSize ); + } + else + { + try + { + scanner = cvStartFindContours( img, storage, cntHeaderSize, mode, method, offset ); + + do + { + count++; + contour = cvFindNextContour( scanner ); + } + while( contour != 0 ); + } + catch(...) + { + if( scanner ) + cvEndFindContours(&scanner); + throw; + } + + *firstContour = cvEndFindContours( &scanner ); + } + + return count; +} + +void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours, + OutputArray _hierarchy, int mode, int method, Point offset ) +{ + Mat image = _image.getMat(); + MemStorage storage(cvCreateMemStorage()); + CvMat _cimage = image; + CvSeq* _ccontours = 0; + if( _hierarchy.needed() ) + _hierarchy.clear(); + cvFindContours(&_cimage, storage, &_ccontours, sizeof(CvContour), mode, method, offset); + if( !_ccontours ) + { + _contours.clear(); + return; + } + Seq all_contours(cvTreeToNodeSeq( _ccontours, sizeof(CvSeq), storage )); + int i, total = (int)all_contours.size(); + _contours.create(total, 1, 0, -1, true); + SeqIterator it = all_contours.begin(); + for( i = 0; i < total; i++, ++it ) + { + CvSeq* c = *it; + ((CvContour*)c)->color = (int)i; + _contours.create((int)c->total, 1, CV_32SC2, i, true); + Mat ci = _contours.getMat(i); + CV_Assert( ci.isContinuous() ); + cvCvtSeqToArray(c, ci.data); + } + + if( _hierarchy.needed() ) + { + _hierarchy.create(1, total, CV_32SC4, -1, true); + Vec4i* hierarchy = _hierarchy.getMat().ptr(); + + it = all_contours.begin(); + for( i = 0; i < total; i++, ++it ) + { + CvSeq* c = *it; + int h_next = c->h_next ? ((CvContour*)c->h_next)->color : -1; + int h_prev = c->h_prev ? ((CvContour*)c->h_prev)->color : -1; + int v_next = c->v_next ? ((CvContour*)c->v_next)->color : -1; + int v_prev = c->v_prev ? ((CvContour*)c->v_prev)->color : -1; + hierarchy[i] = Vec4i(h_next, h_prev, v_next, v_prev); + } + } +} + +void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours, + int mode, int method, Point offset) +{ + findContours(_image, _contours, noArray(), mode, method, offset); +} + +namespace cv +{ + +static void addChildContour(InputArrayOfArrays contours, + size_t ncontours, + const Vec4i* hierarchy, + int i, vector& seq, + vector& block) +{ + for( ; i >= 0; i = hierarchy[i][0] ) + { + Mat ci = contours.getMat(i); + cvMakeSeqHeaderForArray(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point), + !ci.empty() ? (void*)ci.data : 0, (int)ci.total(), + &seq[i], &block[i] ); + + int h_next = hierarchy[i][0], h_prev = hierarchy[i][1], + v_next = hierarchy[i][2], v_prev = hierarchy[i][3]; + seq[i].h_next = (size_t)h_next < ncontours ? &seq[h_next] : 0; + seq[i].h_prev = (size_t)h_prev < ncontours ? &seq[h_prev] : 0; + seq[i].v_next = (size_t)v_next < ncontours ? &seq[v_next] : 0; + seq[i].v_prev = (size_t)v_prev < ncontours ? &seq[v_prev] : 0; + + if( v_next >= 0 ) + addChildContour(contours, ncontours, hierarchy, v_next, seq, block); + } +} + +} + +void cv::drawContours( InputOutputArray _image, InputArrayOfArrays _contours, + int contourIdx, const Scalar& color, int thickness, + int lineType, InputArray _hierarchy, + int maxLevel, Point offset ) +{ + Mat image = _image.getMat(), hierarchy = _hierarchy.getMat(); + CvMat _cimage = image; + + size_t ncontours = _contours.total(); + size_t i = 0, first = 0, last = ncontours; + vector seq; + vector block; + + if( !last ) + return; + + seq.resize(last); + block.resize(last); + + for( i = first; i < last; i++ ) + seq[i].first = 0; + + if( contourIdx >= 0 ) + { + CV_Assert( 0 <= contourIdx && contourIdx < (int)last ); + first = contourIdx; + last = contourIdx + 1; + } + + for( i = first; i < last; i++ ) + { + Mat ci = _contours.getMat((int)i); + if( ci.empty() ) + continue; + int npoints = ci.checkVector(2, CV_32S); + CV_Assert( npoints > 0 ); + cvMakeSeqHeaderForArray( CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point), + ci.data, npoints, &seq[i], &block[i] ); + } + + if( hierarchy.empty() || maxLevel == 0 ) + for( i = first; i < last; i++ ) + { + seq[i].h_next = i < last-1 ? &seq[i+1] : 0; + seq[i].h_prev = i > first ? &seq[i-1] : 0; + } + else + { + size_t count = last - first; + CV_Assert(hierarchy.total() == ncontours && hierarchy.type() == CV_32SC4 ); + const Vec4i* h = hierarchy.ptr(); + + if( count == ncontours ) + { + for( i = first; i < last; i++ ) + { + int h_next = h[i][0], h_prev = h[i][1], + v_next = h[i][2], v_prev = h[i][3]; + seq[i].h_next = (size_t)h_next < count ? &seq[h_next] : 0; + seq[i].h_prev = (size_t)h_prev < count ? &seq[h_prev] : 0; + seq[i].v_next = (size_t)v_next < count ? &seq[v_next] : 0; + seq[i].v_prev = (size_t)v_prev < count ? &seq[v_prev] : 0; + } + } + else + { + int child = h[first][2]; + if( child >= 0 ) + { + addChildContour(_contours, ncontours, h, child, seq, block); + seq[first].v_next = &seq[child]; + } + } + } + + cvDrawContours( &_cimage, &seq[first], color, color, contourIdx >= 0 ? + -maxLevel : maxLevel, thickness, lineType, offset ); +} + + +void cv::approxPolyDP( InputArray _curve, OutputArray _approxCurve, + double epsilon, bool closed ) +{ + Mat curve = _curve.getMat(); + int npoints = curve.checkVector(2), depth = curve.depth(); + CV_Assert( npoints >= 0 && (depth == CV_32S || depth == CV_32F)); + CvMat _ccurve = curve; + MemStorage storage(cvCreateMemStorage()); + CvSeq* result = cvApproxPoly(&_ccurve, sizeof(CvContour), storage, CV_POLY_APPROX_DP, epsilon, closed); + if( result->total > 0 ) + { + _approxCurve.create(result->total, 1, CV_MAKETYPE(curve.depth(), 2), -1, true); + cvCvtSeqToArray(result, _approxCurve.getMat().data ); + } +} + + +double cv::arcLength( InputArray _curve, bool closed ) +{ + Mat curve = _curve.getMat(); + CV_Assert(curve.checkVector(2) >= 0 && (curve.depth() == CV_32F || curve.depth() == CV_32S)); + CvMat _ccurve = curve; + return cvArcLength(&_ccurve, CV_WHOLE_SEQ, closed); +} + + +cv::Rect cv::boundingRect( InputArray _points ) +{ + Mat points = _points.getMat(); + CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S)); + CvMat _cpoints = points; + return cvBoundingRect(&_cpoints, 0); +} + + +double cv::contourArea( InputArray _contour, bool oriented ) +{ + Mat contour = _contour.getMat(); + CV_Assert(contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S)); + CvMat _ccontour = contour; + return cvContourArea(&_ccontour, CV_WHOLE_SEQ, oriented); +} + + +cv::RotatedRect cv::minAreaRect( InputArray _points ) +{ + Mat points = _points.getMat(); + CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S)); + CvMat _cpoints = points; + return cvMinAreaRect2(&_cpoints, 0); +} + + +void cv::minEnclosingCircle( InputArray _points, + Point2f& center, float& radius ) +{ + Mat points = _points.getMat(); + CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S)); + CvMat _cpoints = points; + cvMinEnclosingCircle( &_cpoints, (CvPoint2D32f*)¢er, &radius ); +} + + +double cv::matchShapes( InputArray _contour1, + InputArray _contour2, + int method, double parameter ) +{ + Mat contour1 = _contour1.getMat(), contour2 = _contour2.getMat(); + CV_Assert(contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && + (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && + contour1.depth() == contour2.depth()); + + CvMat c1 = Mat(contour1), c2 = Mat(contour2); + return cvMatchShapes(&c1, &c2, method, parameter); +} + + +void cv::convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints ) +{ + Mat points = _points.getMat(); + int nelems = points.checkVector(2), depth = points.depth(); + CV_Assert(nelems >= 0 && (depth == CV_32F || depth == CV_32S)); + + if( nelems == 0 ) + { + _hull.release(); + return; + } + + returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S; + Mat hull(nelems, 1, returnPoints ? CV_MAKETYPE(depth, 2) : CV_32S); + CvMat _cpoints = points, _chull = hull; + cvConvexHull2(&_cpoints, &_chull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, returnPoints); + _hull.create(_chull.rows, 1, hull.type(), -1, true); + Mat dhull = _hull.getMat(), shull(dhull.size(), dhull.type(), hull.data); + shull.copyTo(dhull); +} + + +void cv::convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects ) +{ + Mat points = _points.getMat(); + int ptnum = points.checkVector(2, CV_32S); + CV_Assert( ptnum > 3 ); + Mat hull = _hull.getMat(); + CV_Assert( hull.checkVector(1, CV_32S) > 2 ); + Ptr storage = cvCreateMemStorage(); + + CvMat c_points = points, c_hull = hull; + CvSeq* seq = cvConvexityDefects(&c_points, &c_hull, storage); + int i, n = seq->total; + + if( n == 0 ) + { + _defects.release(); + return; + } + + _defects.create(n, 1, CV_32SC4); + Mat defects = _defects.getMat(); + + SeqIterator it = Seq(seq).begin(); + CvPoint* ptorg = (CvPoint*)points.data; + + for( i = 0; i < n; i++, ++it ) + { + CvConvexityDefect& d = *it; + int idx0 = (int)(d.start - ptorg); + int idx1 = (int)(d.end - ptorg); + int idx2 = (int)(d.depth_point - ptorg); + CV_Assert( 0 <= idx0 && idx0 < ptnum ); + CV_Assert( 0 <= idx1 && idx1 < ptnum ); + CV_Assert( 0 <= idx2 && idx2 < ptnum ); + CV_Assert( d.depth >= 0 ); + int idepth = cvRound(d.depth*256); + defects.at(i) = Vec4i(idx0, idx1, idx2, idepth); + } +} + + +bool cv::isContourConvex( InputArray _contour ) +{ + Mat contour = _contour.getMat(); + CV_Assert(contour.checkVector(2) >= 0 && + (contour.depth() == CV_32F || contour.depth() == CV_32S)); + CvMat c = Mat(contour); + return cvCheckContourConvexity(&c) > 0; +} + +cv::RotatedRect cv::fitEllipse( InputArray _points ) +{ + Mat points = _points.getMat(); + CV_Assert(points.checkVector(2) >= 0 && + (points.depth() == CV_32F || points.depth() == CV_32S)); + CvMat _cpoints = points; + return cvFitEllipse2(&_cpoints); +} + + +void cv::fitLine( InputArray _points, OutputArray _line, int distType, + double param, double reps, double aeps ) +{ + Mat points = _points.getMat(); + + bool is3d = points.checkVector(3) >= 0; + bool is2d = points.checkVector(2) >= 0; + + CV_Assert( (is2d || is3d) && (points.depth() == CV_32F || points.depth() == CV_32S) ); + CvMat _cpoints = points.reshape(2 + (int)is3d); + float line[6]; + cvFitLine(&_cpoints, distType, param, reps, aeps, &line[0]); + + int out_size = (is2d)?( (is3d)? (points.channels() * points.rows * 2) : 4 ): 6; + + _line.create(out_size, 1, CV_32F, -1, true); + Mat l = _line.getMat(); + CV_Assert( l.isContinuous() ); + memcpy( l.data, line, out_size * sizeof(line[0]) ); +} + + +double cv::pointPolygonTest( InputArray _contour, + Point2f pt, bool measureDist ) +{ + Mat contour = _contour.getMat(); + CV_Assert(contour.checkVector(2) >= 0 && + (contour.depth() == CV_32F || contour.depth() == CV_32S)); + CvMat c = Mat(contour); + return cvPointPolygonTest( &c, pt, measureDist ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/convhull.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/convhull.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/convhull.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/convhull.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,815 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +static int +icvSklansky_32s( CvPoint** array, int start, int end, int* stack, int nsign, int sign2 ) +{ + int incr = end > start ? 1 : -1; + /* prepare first triangle */ + int pprev = start, pcur = pprev + incr, pnext = pcur + incr; + int stacksize = 3; + + if( start == end || + (array[start]->x == array[end]->x && + array[start]->y == array[end]->y) ) + { + stack[0] = start; + return 1; + } + + stack[0] = pprev; + stack[1] = pcur; + stack[2] = pnext; + + end += incr; /* make end = afterend */ + + while( pnext != end ) + { + /* check the angle p1,p2,p3 */ + int cury = array[pcur]->y; + int nexty = array[pnext]->y; + int by = nexty - cury; + + if( CV_SIGN(by) != nsign ) + { + int ax = array[pcur]->x - array[pprev]->x; + int bx = array[pnext]->x - array[pcur]->x; + int ay = cury - array[pprev]->y; + int convexity = ay*bx - ax*by;/* if >0 then convex angle */ + + if( CV_SIGN(convexity) == sign2 && (ax != 0 || ay != 0) ) + { + pprev = pcur; + pcur = pnext; + pnext += incr; + stack[stacksize] = pnext; + stacksize++; + } + else + { + if( pprev == start ) + { + pcur = pnext; + stack[1] = pcur; + pnext += incr; + stack[2] = pnext; + } + else + { + stack[stacksize-2] = pnext; + pcur = pprev; + pprev = stack[stacksize-4]; + stacksize--; + } + } + } + else + { + pnext += incr; + stack[stacksize-1] = pnext; + } + } + + return --stacksize; +} + + +static int +icvSklansky_32f( CvPoint2D32f** array, int start, int end, int* stack, int nsign, int sign2 ) +{ + int incr = end > start ? 1 : -1; + /* prepare first triangle */ + int pprev = start, pcur = pprev + incr, pnext = pcur + incr; + int stacksize = 3; + + if( start == end || + (array[start]->x == array[end]->x && + array[start]->y == array[end]->y) ) + { + stack[0] = start; + return 1; + } + + stack[0] = pprev; + stack[1] = pcur; + stack[2] = pnext; + + end += incr; /* make end = afterend */ + + while( pnext != end ) + { + /* check the angle p1,p2,p3 */ + float cury = array[pcur]->y; + float nexty = array[pnext]->y; + float by = nexty - cury; + + if( CV_SIGN( by ) != nsign ) + { + float ax = array[pcur]->x - array[pprev]->x; + float bx = array[pnext]->x - array[pcur]->x; + float ay = cury - array[pprev]->y; + float convexity = ay*bx - ax*by;/* if >0 then convex angle */ + + if( CV_SIGN( convexity ) == sign2 && (ax != 0 || ay != 0) ) + { + pprev = pcur; + pcur = pnext; + pnext += incr; + stack[stacksize] = pnext; + stacksize++; + } + else + { + if( pprev == start ) + { + pcur = pnext; + stack[1] = pcur; + pnext += incr; + stack[2] = pnext; + + } + else + { + stack[stacksize-2] = pnext; + pcur = pprev; + pprev = stack[stacksize-4]; + stacksize--; + } + } + } + else + { + pnext += incr; + stack[stacksize-1] = pnext; + } + } + + return --stacksize; +} + +typedef int (*sklansky_func)( CvPoint** points, int start, int end, + int* stack, int sign, int sign2 ); + +#define cmp_pts( pt1, pt2 ) \ + ((pt1)->x < (pt2)->x || ((pt1)->x <= (pt2)->x && (pt1)->y < (pt2)->y)) +static CV_IMPLEMENT_QSORT( icvSortPointsByPointers_32s, CvPoint*, cmp_pts ) +static CV_IMPLEMENT_QSORT( icvSortPointsByPointers_32f, CvPoint2D32f*, cmp_pts ) + +static void +icvCalcAndWritePtIndices( CvPoint** pointer, int* stack, int start, int end, + CvSeq* ptseq, CvSeqWriter* writer ) +{ + int i, incr = start < end ? 1 : -1; + int idx, first_idx = ptseq->first->start_index; + + for( i = start; i != end; i += incr ) + { + CvPoint* ptr = (CvPoint*)pointer[stack[i]]; + CvSeqBlock* block = ptseq->first; + while( (unsigned)(idx = (int)(ptr - (CvPoint*)block->data)) >= (unsigned)block->count ) + { + block = block->next; + if( block == ptseq->first ) + CV_Error( CV_StsError, "Internal error" ); + } + idx += block->start_index - first_idx; + CV_WRITE_SEQ_ELEM( idx, *writer ); + } +} + + +CV_IMPL CvSeq* +cvConvexHull2( const CvArr* array, void* hull_storage, + int orientation, int return_points ) +{ + union { CvContour* c; CvSeq* s; } hull; + cv::AutoBuffer _pointer; + CvPoint** pointer; + CvPoint2D32f** pointerf = 0; + cv::AutoBuffer _stack; + int* stack; + + hull.s = 0; + + CvMat* mat = 0; + CvSeqReader reader; + CvSeqWriter writer; + CvContour contour_header; + union { CvContour c; CvSeq s; } hull_header; + CvSeqBlock block, hullblock; + CvSeq* ptseq = 0; + CvSeq* hullseq = 0; + int is_float; + int* t_stack; + int t_count; + int i, miny_ind = 0, maxy_ind = 0, total; + int hulltype; + int stop_idx; + sklansky_func sklansky; + + if( CV_IS_SEQ( array )) + { + ptseq = (CvSeq*)array; + if( !CV_IS_SEQ_POINT_SET( ptseq )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + if( hull_storage == 0 ) + hull_storage = ptseq->storage; + } + else + { + ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block ); + } + + if( CV_IS_STORAGE( hull_storage )) + { + if( return_points ) + { + hullseq = cvCreateSeq( + CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE(ptseq)| + CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX, + sizeof(CvContour), sizeof(CvPoint),(CvMemStorage*)hull_storage ); + } + else + { + hullseq = cvCreateSeq( + CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_PPOINT| + CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX, + sizeof(CvContour), sizeof(CvPoint*), (CvMemStorage*)hull_storage ); + } + } + else + { + if( !CV_IS_MAT( hull_storage )) + CV_Error(CV_StsBadArg, "Destination must be valid memory storage or matrix"); + + mat = (CvMat*)hull_storage; + + if( (mat->cols != 1 && mat->rows != 1) || !CV_IS_MAT_CONT(mat->type)) + CV_Error( CV_StsBadArg, + "The hull matrix should be continuous and have a single row or a single column" ); + + if( mat->cols + mat->rows - 1 < ptseq->total ) + CV_Error( CV_StsBadSize, "The hull matrix size might be not enough to fit the hull" ); + + if( CV_MAT_TYPE(mat->type) != CV_SEQ_ELTYPE(ptseq) && + CV_MAT_TYPE(mat->type) != CV_32SC1 ) + CV_Error( CV_StsUnsupportedFormat, + "The hull matrix must have the same type as input or 32sC1 (integers)" ); + + hullseq = cvMakeSeqHeaderForArray( + CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED, + sizeof(contour_header), CV_ELEM_SIZE(mat->type), mat->data.ptr, + mat->cols + mat->rows - 1, &hull_header.s, &hullblock ); + + cvClearSeq( hullseq ); + } + + total = ptseq->total; + if( total == 0 ) + { + if( mat ) + CV_Error( CV_StsBadSize, + "Point sequence can not be empty if the output is matrix" ); + return hull.s; + } + + cvStartAppendToSeq( hullseq, &writer ); + + is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2; + hulltype = CV_SEQ_ELTYPE(hullseq); + sklansky = !is_float ? (sklansky_func)icvSklansky_32s : + (sklansky_func)icvSklansky_32f; + + _pointer.allocate( ptseq->total ); + _stack.allocate( ptseq->total + 2); + pointer = _pointer; + pointerf = (CvPoint2D32f**)pointer; + stack = _stack; + + cvStartReadSeq( ptseq, &reader ); + + for( i = 0; i < total; i++ ) + { + pointer[i] = (CvPoint*)reader.ptr; + CV_NEXT_SEQ_ELEM( ptseq->elem_size, reader ); + } + + // sort the point set by x-coordinate, find min and max y + if( !is_float ) + { + icvSortPointsByPointers_32s( pointer, total, 0 ); + for( i = 1; i < total; i++ ) + { + int y = pointer[i]->y; + if( pointer[miny_ind]->y > y ) + miny_ind = i; + if( pointer[maxy_ind]->y < y ) + maxy_ind = i; + } + } + else + { + icvSortPointsByPointers_32f( pointerf, total, 0 ); + for( i = 1; i < total; i++ ) + { + float y = pointerf[i]->y; + if( pointerf[miny_ind]->y > y ) + miny_ind = i; + if( pointerf[maxy_ind]->y < y ) + maxy_ind = i; + } + } + + if( pointer[0]->x == pointer[total-1]->x && + pointer[0]->y == pointer[total-1]->y ) + { + if( hulltype == CV_SEQ_ELTYPE_PPOINT ) + { + CV_WRITE_SEQ_ELEM( pointer[0], writer ); + } + else if( hulltype == CV_SEQ_ELTYPE_INDEX ) + { + int index = 0; + CV_WRITE_SEQ_ELEM( index, writer ); + } + else + { + CvPoint pt = pointer[0][0]; + CV_WRITE_SEQ_ELEM( pt, writer ); + } + goto finish_hull; + } + + /*upper half */ + { + int *tl_stack = stack; + int tl_count = sklansky( pointer, 0, maxy_ind, tl_stack, -1, 1 ); + int *tr_stack = tl_stack + tl_count; + int tr_count = sklansky( pointer, ptseq->total - 1, maxy_ind, tr_stack, -1, -1 ); + + /* gather upper part of convex hull to output */ + if( orientation == CV_COUNTER_CLOCKWISE ) + { + CV_SWAP( tl_stack, tr_stack, t_stack ); + CV_SWAP( tl_count, tr_count, t_count ); + } + + if( hulltype == CV_SEQ_ELTYPE_PPOINT ) + { + for( i = 0; i < tl_count - 1; i++ ) + CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]], writer ); + + for( i = tr_count - 1; i > 0; i-- ) + CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]], writer ); + } + else if( hulltype == CV_SEQ_ELTYPE_INDEX ) + { + icvCalcAndWritePtIndices( pointer, tl_stack, 0, tl_count-1, ptseq, &writer ); + icvCalcAndWritePtIndices( pointer, tr_stack, tr_count-1, 0, ptseq, &writer ); + } + else + { + for( i = 0; i < tl_count - 1; i++ ) + CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]][0], writer ); + + for( i = tr_count - 1; i > 0; i-- ) + CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]][0], writer ); + } + stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1; + } + + /* lower half */ + { + int *bl_stack = stack; + int bl_count = sklansky( pointer, 0, miny_ind, bl_stack, 1, -1 ); + int *br_stack = stack + bl_count; + int br_count = sklansky( pointer, ptseq->total - 1, miny_ind, br_stack, 1, 1 ); + + if( orientation != CV_COUNTER_CLOCKWISE ) + { + CV_SWAP( bl_stack, br_stack, t_stack ); + CV_SWAP( bl_count, br_count, t_count ); + } + + if( stop_idx >= 0 ) + { + int check_idx = bl_count > 2 ? bl_stack[1] : + bl_count + br_count > 2 ? br_stack[2-bl_count] : -1; + if( check_idx == stop_idx || (check_idx >= 0 && + pointer[check_idx]->x == pointer[stop_idx]->x && + pointer[check_idx]->y == pointer[stop_idx]->y) ) + { + /* if all the points lie on the same line, then + the bottom part of the convex hull is the mirrored top part + (except the exteme points).*/ + bl_count = MIN( bl_count, 2 ); + br_count = MIN( br_count, 2 ); + } + } + + if( hulltype == CV_SEQ_ELTYPE_PPOINT ) + { + for( i = 0; i < bl_count - 1; i++ ) + CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]], writer ); + + for( i = br_count - 1; i > 0; i-- ) + CV_WRITE_SEQ_ELEM( pointer[br_stack[i]], writer ); + } + else if( hulltype == CV_SEQ_ELTYPE_INDEX ) + { + icvCalcAndWritePtIndices( pointer, bl_stack, 0, bl_count-1, ptseq, &writer ); + icvCalcAndWritePtIndices( pointer, br_stack, br_count-1, 0, ptseq, &writer ); + } + else + { + for( i = 0; i < bl_count - 1; i++ ) + CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]][0], writer ); + + for( i = br_count - 1; i > 0; i-- ) + CV_WRITE_SEQ_ELEM( pointer[br_stack[i]][0], writer ); + } + } + +finish_hull: + cvEndWriteSeq( &writer ); + + if( mat ) + { + if( mat->rows > mat->cols ) + mat->rows = hullseq->total; + else + mat->cols = hullseq->total; + } + else + { + hull.s = hullseq; + hull.c->rect = cvBoundingRect( ptseq, + ptseq->header_size < (int)sizeof(CvContour) || + &ptseq->flags == &contour_header.flags ); + + /*if( ptseq != (CvSeq*)&contour_header ) + hullseq->v_prev = ptseq;*/ + } + + return hull.s; +} + + +/* contour must be a simple polygon */ +/* it must have more than 3 points */ +CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, + const CvArr* hullarray, + CvMemStorage* storage ) +{ + CvSeq* defects = 0; + + int i, index; + CvPoint* hull_cur; + + /* is orientation of hull different from contour one */ + int rev_orientation; + + CvContour contour_header; + union { CvContour c; CvSeq s; } hull_header; + CvSeqBlock block, hullblock; + CvSeq *ptseq = (CvSeq*)array, *hull = (CvSeq*)hullarray; + + CvSeqReader hull_reader; + CvSeqReader ptseq_reader; + CvSeqWriter writer; + int is_index; + + if( CV_IS_SEQ( ptseq )) + { + if( !CV_IS_SEQ_POINT_SET( ptseq )) + CV_Error( CV_StsUnsupportedFormat, + "Input sequence is not a sequence of points" ); + if( !storage ) + storage = ptseq->storage; + } + else + { + ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block ); + } + + if( CV_SEQ_ELTYPE( ptseq ) != CV_32SC2 ) + CV_Error( CV_StsUnsupportedFormat, "Floating-point coordinates are not supported here" ); + + if( CV_IS_SEQ( hull )) + { + int hulltype = CV_SEQ_ELTYPE( hull ); + if( hulltype != CV_SEQ_ELTYPE_PPOINT && hulltype != CV_SEQ_ELTYPE_INDEX ) + CV_Error( CV_StsUnsupportedFormat, + "Convex hull must represented as a sequence " + "of indices or sequence of pointers" ); + if( !storage ) + storage = hull->storage; + } + else + { + CvMat* mat = (CvMat*)hull; + + if( !CV_IS_MAT( hull )) + CV_Error(CV_StsBadArg, "Convex hull is neither sequence nor matrix"); + + if( (mat->cols != 1 && mat->rows != 1) || + !CV_IS_MAT_CONT(mat->type) || CV_MAT_TYPE(mat->type) != CV_32SC1 ) + CV_Error( CV_StsBadArg, + "The matrix should be 1-dimensional and continuous array of int's" ); + + if( mat->cols + mat->rows - 1 > ptseq->total ) + CV_Error( CV_StsBadSize, "Convex hull is larger than the point sequence" ); + + hull = cvMakeSeqHeaderForArray( + CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED, + sizeof(CvContour), CV_ELEM_SIZE(mat->type), mat->data.ptr, + mat->cols + mat->rows - 1, &hull_header.s, &hullblock ); + } + + is_index = CV_SEQ_ELTYPE(hull) == CV_SEQ_ELTYPE_INDEX; + + if( !storage ) + CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + + defects = cvCreateSeq( CV_SEQ_KIND_GENERIC, sizeof(CvSeq), sizeof(CvConvexityDefect), storage ); + + if( ptseq->total < 4 || hull->total < 3) + { + //CV_ERROR( CV_StsBadSize, + // "point seq size must be >= 4, convex hull size must be >= 3" ); + return defects; + } + + /* recognize co-orientation of ptseq and its hull */ + { + int sign = 0; + int index1, index2, index3; + + if( !is_index ) + { + CvPoint* pos = *CV_SEQ_ELEM( hull, CvPoint*, 0 ); + index1 = cvSeqElemIdx( ptseq, pos ); + + pos = *CV_SEQ_ELEM( hull, CvPoint*, 1 ); + index2 = cvSeqElemIdx( ptseq, pos ); + + pos = *CV_SEQ_ELEM( hull, CvPoint*, 2 ); + index3 = cvSeqElemIdx( ptseq, pos ); + } + else + { + index1 = *CV_SEQ_ELEM( hull, int, 0 ); + index2 = *CV_SEQ_ELEM( hull, int, 1 ); + index3 = *CV_SEQ_ELEM( hull, int, 2 ); + } + + sign += (index2 > index1) ? 1 : 0; + sign += (index3 > index2) ? 1 : 0; + sign += (index1 > index3) ? 1 : 0; + + rev_orientation = (sign == 2) ? 0 : 1; + } + + cvStartReadSeq( ptseq, &ptseq_reader, 0 ); + cvStartReadSeq( hull, &hull_reader, rev_orientation ); + + if( !is_index ) + { + hull_cur = *(CvPoint**)hull_reader.prev_elem; + index = cvSeqElemIdx( ptseq, (char*)hull_cur, 0 ); + } + else + { + index = *(int*)hull_reader.prev_elem; + hull_cur = CV_GET_SEQ_ELEM( CvPoint, ptseq, index ); + } + cvSetSeqReaderPos( &ptseq_reader, index ); + cvStartAppendToSeq( defects, &writer ); + + /* cycle through ptseq and hull with computing defects */ + for( i = 0; i < hull->total; i++ ) + { + CvConvexityDefect defect; + int is_defect = 0; + double dx0, dy0; + double depth = 0, scale; + CvPoint* hull_next; + + if( !is_index ) + hull_next = *(CvPoint**)hull_reader.ptr; + else + { + int t = *(int*)hull_reader.ptr; + hull_next = CV_GET_SEQ_ELEM( CvPoint, ptseq, t ); + } + + dx0 = (double)hull_next->x - (double)hull_cur->x; + dy0 = (double)hull_next->y - (double)hull_cur->y; + assert( dx0 != 0 || dy0 != 0 ); + scale = 1./sqrt(dx0*dx0 + dy0*dy0); + + defect.start = hull_cur; + defect.end = hull_next; + + for(;;) + { + /* go through ptseq to achieve next hull point */ + CV_NEXT_SEQ_ELEM( sizeof(CvPoint), ptseq_reader ); + + if( ptseq_reader.ptr == (schar*)hull_next ) + break; + else + { + CvPoint* cur = (CvPoint*)ptseq_reader.ptr; + + /* compute distance from current point to hull edge */ + double dx = (double)cur->x - (double)hull_cur->x; + double dy = (double)cur->y - (double)hull_cur->y; + + /* compute depth */ + double dist = fabs(-dy0*dx + dx0*dy) * scale; + + if( dist > depth ) + { + depth = dist; + defect.depth_point = cur; + defect.depth = (float)depth; + is_defect = 1; + } + } + } + if( is_defect ) + { + CV_WRITE_SEQ_ELEM( defect, writer ); + } + + hull_cur = hull_next; + if( rev_orientation ) + { + CV_PREV_SEQ_ELEM( hull->elem_size, hull_reader ); + } + else + { + CV_NEXT_SEQ_ELEM( hull->elem_size, hull_reader ); + } + } + + return cvEndWriteSeq( &writer ); +} + + +CV_IMPL int +cvCheckContourConvexity( const CvArr* array ) +{ + int flag = -1; + + int i; + int orientation = 0; + CvSeqReader reader; + CvContour contour_header; + CvSeqBlock block; + CvSeq* contour = (CvSeq*)array; + + if( CV_IS_SEQ(contour) ) + { + if( !CV_IS_SEQ_POINT_SET(contour)) + CV_Error( CV_StsUnsupportedFormat, + "Input sequence must be polygon (closed 2d curve)" ); + } + else + { + contour = cvPointSeqFromMat(CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CLOSED, array, &contour_header, &block ); + } + + if( contour->total == 0 ) + return -1; + + cvStartReadSeq( contour, &reader, 0 ); + flag = 1; + + if( CV_SEQ_ELTYPE( contour ) == CV_32SC2 ) + { + CvPoint *prev_pt = (CvPoint*)reader.prev_elem; + CvPoint *cur_pt = (CvPoint*)reader.ptr; + + int dx0 = cur_pt->x - prev_pt->x; + int dy0 = cur_pt->y - prev_pt->y; + + for( i = 0; i < contour->total; i++ ) + { + int dxdy0, dydx0; + int dx, dy; + + /*int orient; */ + CV_NEXT_SEQ_ELEM( sizeof(CvPoint), reader ); + prev_pt = cur_pt; + cur_pt = (CvPoint *) reader.ptr; + + dx = cur_pt->x - prev_pt->x; + dy = cur_pt->y - prev_pt->y; + dxdy0 = dx * dy0; + dydx0 = dy * dx0; + + /* find orientation */ + /*orient = -dy0 * dx + dx0 * dy; + orientation |= (orient > 0) ? 1 : 2; + */ + orientation |= (dydx0 > dxdy0) ? 1 : ((dydx0 < dxdy0) ? 2 : 3); + + if( orientation == 3 ) + { + flag = 0; + break; + } + + dx0 = dx; + dy0 = dy; + } + } + else + { + CV_Assert( CV_SEQ_ELTYPE(contour) == CV_32FC2 ); + + CvPoint2D32f *prev_pt = (CvPoint2D32f*)reader.prev_elem; + CvPoint2D32f *cur_pt = (CvPoint2D32f*)reader.ptr; + + float dx0 = cur_pt->x - prev_pt->x; + float dy0 = cur_pt->y - prev_pt->y; + + for( i = 0; i < contour->total; i++ ) + { + float dxdy0, dydx0; + float dx, dy; + + /*int orient; */ + CV_NEXT_SEQ_ELEM( sizeof(CvPoint2D32f), reader ); + prev_pt = cur_pt; + cur_pt = (CvPoint2D32f*) reader.ptr; + + dx = cur_pt->x - prev_pt->x; + dy = cur_pt->y - prev_pt->y; + dxdy0 = dx * dy0; + dydx0 = dy * dx0; + + /* find orientation */ + /*orient = -dy0 * dx + dx0 * dy; + orientation |= (orient > 0) ? 1 : 2; + */ + orientation |= (dydx0 > dxdy0) ? 1 : ((dydx0 < dxdy0) ? 2 : 3); + + if( orientation == 3 ) + { + flag = 0; + break; + } + + dx0 = dx; + dy0 = dy; + } + } + + return flag; +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/corner.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/corner.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/corner.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/corner.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,422 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include + + +namespace cv +{ + +static void +calcMinEigenVal( const Mat& _cov, Mat& _dst ) +{ + int i, j; + Size size = _cov.size(); +#if CV_SSE + volatile bool simd = checkHardwareSupport(CV_CPU_SSE); +#endif + + if( _cov.isContinuous() && _dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + + for( i = 0; i < size.height; i++ ) + { + const float* cov = (const float*)(_cov.data + _cov.step*i); + float* dst = (float*)(_dst.data + _dst.step*i); + j = 0; + #if CV_SSE + if( simd ) + { + __m128 half = _mm_set1_ps(0.5f); + for( ; j <= size.width - 5; j += 4 ) + { + __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x + __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x + __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x + __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x + __m128 a, b, c, t; + t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1 + c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x + b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3 + c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3 + a = _mm_movelh_ps(t, b); + b = _mm_movehl_ps(b, t); + a = _mm_mul_ps(a, half); + c = _mm_mul_ps(c, half); + t = _mm_sub_ps(a, c); + t = _mm_add_ps(_mm_mul_ps(t, t), _mm_mul_ps(b,b)); + a = _mm_sub_ps(_mm_add_ps(a, c), _mm_sqrt_ps(t)); + _mm_storeu_ps(dst + j, a); + } + } + #endif + for( ; j < size.width; j++ ) + { + float a = cov[j*3]*0.5f; + float b = cov[j*3+1]; + float c = cov[j*3+2]*0.5f; + dst[j] = (float)((a + c) - std::sqrt((a - c)*(a - c) + b*b)); + } + } +} + + +static void +calcHarris( const Mat& _cov, Mat& _dst, double k ) +{ + int i, j; + Size size = _cov.size(); +#if CV_SSE + volatile bool simd = checkHardwareSupport(CV_CPU_SSE); +#endif + + if( _cov.isContinuous() && _dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + + for( i = 0; i < size.height; i++ ) + { + const float* cov = (const float*)(_cov.data + _cov.step*i); + float* dst = (float*)(_dst.data + _dst.step*i); + j = 0; + + #if CV_SSE + if( simd ) + { + __m128 k4 = _mm_set1_ps((float)k); + for( ; j <= size.width - 5; j += 4 ) + { + __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x + __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x + __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x + __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x + __m128 a, b, c, t; + t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1 + c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x + b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3 + c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3 + a = _mm_movelh_ps(t, b); + b = _mm_movehl_ps(b, t); + t = _mm_add_ps(a, c); + a = _mm_sub_ps(_mm_mul_ps(a, c), _mm_mul_ps(b, b)); + t = _mm_mul_ps(_mm_mul_ps(k4, t), t); + a = _mm_sub_ps(a, t); + _mm_storeu_ps(dst + j, a); + } + } + #endif + + for( ; j < size.width; j++ ) + { + float a = cov[j*3]; + float b = cov[j*3+1]; + float c = cov[j*3+2]; + dst[j] = (float)(a*c - b*b - k*(a + c)*(a + c)); + } + } +} + + +void eigen2x2( const float* cov, float* dst, int n ) +{ + for( int j = 0; j < n; j++ ) + { + double a = cov[j*3]; + double b = cov[j*3+1]; + double c = cov[j*3+2]; + + double u = (a + c)*0.5; + double v = std::sqrt((a - c)*(a - c)*0.25 + b*b); + double l1 = u + v; + double l2 = u - v; + + double x = b; + double y = l1 - a; + double e = fabs(x); + + if( e + fabs(y) < 1e-4 ) + { + y = b; + x = l1 - c; + e = fabs(x); + if( e + fabs(y) < 1e-4 ) + { + e = 1./(e + fabs(y) + FLT_EPSILON); + x *= e, y *= e; + } + } + + double d = 1./std::sqrt(x*x + y*y + DBL_EPSILON); + dst[6*j] = (float)l1; + dst[6*j + 2] = (float)(x*d); + dst[6*j + 3] = (float)(y*d); + + x = b; + y = l2 - a; + e = fabs(x); + + if( e + fabs(y) < 1e-4 ) + { + y = b; + x = l2 - c; + e = fabs(x); + if( e + fabs(y) < 1e-4 ) + { + e = 1./(e + fabs(y) + FLT_EPSILON); + x *= e, y *= e; + } + } + + d = 1./std::sqrt(x*x + y*y + DBL_EPSILON); + dst[6*j + 1] = (float)l2; + dst[6*j + 4] = (float)(x*d); + dst[6*j + 5] = (float)(y*d); + } +} + +static void +calcEigenValsVecs( const Mat& _cov, Mat& _dst ) +{ + Size size = _cov.size(); + if( _cov.isContinuous() && _dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + + for( int i = 0; i < size.height; i++ ) + { + const float* cov = (const float*)(_cov.data + _cov.step*i); + float* dst = (float*)(_dst.data + _dst.step*i); + + eigen2x2(cov, dst, size.width); + } +} + + +enum { MINEIGENVAL=0, HARRIS=1, EIGENVALSVECS=2 }; + + +static void +cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size, + int aperture_size, int op_type, double k=0., + int borderType=BORDER_DEFAULT ) +{ +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::cornerEigenValsVecs(src, eigenv, block_size, aperture_size, op_type, k, borderType)) + return; +#endif + + int depth = src.depth(); + double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size; + if( aperture_size < 0 ) + scale *= 2.; + if( depth == CV_8U ) + scale *= 255.; + scale = 1./scale; + + CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); + + Mat Dx, Dy; + if( aperture_size > 0 ) + { + Sobel( src, Dx, CV_32F, 1, 0, aperture_size, scale, 0, borderType ); + Sobel( src, Dy, CV_32F, 0, 1, aperture_size, scale, 0, borderType ); + } + else + { + Scharr( src, Dx, CV_32F, 1, 0, scale, 0, borderType ); + Scharr( src, Dy, CV_32F, 0, 1, scale, 0, borderType ); + } + + Size size = src.size(); + Mat cov( size, CV_32FC3 ); + int i, j; + + for( i = 0; i < size.height; i++ ) + { + float* cov_data = (float*)(cov.data + i*cov.step); + const float* dxdata = (const float*)(Dx.data + i*Dx.step); + const float* dydata = (const float*)(Dy.data + i*Dy.step); + + for( j = 0; j < size.width; j++ ) + { + float dx = dxdata[j]; + float dy = dydata[j]; + + cov_data[j*3] = dx*dx; + cov_data[j*3+1] = dx*dy; + cov_data[j*3+2] = dy*dy; + } + } + + boxFilter(cov, cov, cov.depth(), Size(block_size, block_size), + Point(-1,-1), false, borderType ); + + if( op_type == MINEIGENVAL ) + calcMinEigenVal( cov, eigenv ); + else if( op_type == HARRIS ) + calcHarris( cov, eigenv, k ); + else if( op_type == EIGENVALSVECS ) + calcEigenValsVecs( cov, eigenv ); +} + +} + +void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType ) +{ + Mat src = _src.getMat(); + _dst.create( src.size(), CV_32F ); + Mat dst = _dst.getMat(); + cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType ); +} + + +void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType ) +{ + Mat src = _src.getMat(); + _dst.create( src.size(), CV_32F ); + Mat dst = _dst.getMat(); + cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType ); +} + + +void cv::cornerEigenValsAndVecs( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType ) +{ + Mat src = _src.getMat(); + Size dsz = _dst.size(); + int dtype = _dst.type(); + + if( dsz.height != src.rows || dsz.width*CV_MAT_CN(dtype) != src.cols*6 || CV_MAT_DEPTH(dtype) != CV_32F ) + _dst.create( src.size(), CV_32FC(6) ); + Mat dst = _dst.getMat(); + cornerEigenValsVecs( src, dst, blockSize, ksize, EIGENVALSVECS, 0, borderType ); +} + + +void cv::preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int borderType ) +{ + Mat Dx, Dy, D2x, D2y, Dxy, src = _src.getMat(); + + CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); + _dst.create( src.size(), CV_32F ); + Mat dst = _dst.getMat(); + + Sobel( src, Dx, CV_32F, 1, 0, ksize, 1, 0, borderType ); + Sobel( src, Dy, CV_32F, 0, 1, ksize, 1, 0, borderType ); + Sobel( src, D2x, CV_32F, 2, 0, ksize, 1, 0, borderType ); + Sobel( src, D2y, CV_32F, 0, 2, ksize, 1, 0, borderType ); + Sobel( src, Dxy, CV_32F, 1, 1, ksize, 1, 0, borderType ); + + double factor = 1 << (ksize - 1); + if( src.depth() == CV_8U ) + factor *= 255; + factor = 1./(factor * factor * factor); + + Size size = src.size(); + int i, j; + for( i = 0; i < size.height; i++ ) + { + float* dstdata = (float*)(dst.data + i*dst.step); + const float* dxdata = (const float*)(Dx.data + i*Dx.step); + const float* dydata = (const float*)(Dy.data + i*Dy.step); + const float* d2xdata = (const float*)(D2x.data + i*D2x.step); + const float* d2ydata = (const float*)(D2y.data + i*D2y.step); + const float* dxydata = (const float*)(Dxy.data + i*Dxy.step); + + for( j = 0; j < size.width; j++ ) + { + float dx = dxdata[j]; + float dy = dydata[j]; + dstdata[j] = (float)(factor*(dx*dx*d2ydata[j] + dy*dy*d2xdata[j] - 2*dx*dy*dxydata[j])); + } + } +} + +CV_IMPL void +cvCornerMinEigenVal( const CvArr* srcarr, CvArr* dstarr, + int block_size, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 ); + cv::cornerMinEigenVal( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE ); +} + +CV_IMPL void +cvCornerHarris( const CvArr* srcarr, CvArr* dstarr, + int block_size, int aperture_size, double k ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 ); + cv::cornerHarris( src, dst, block_size, aperture_size, k, cv::BORDER_REPLICATE ); +} + + +CV_IMPL void +cvCornerEigenValsAndVecs( const void* srcarr, void* dstarr, + int block_size, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.rows == dst.rows && src.cols*6 == dst.cols*dst.channels() && dst.depth() == CV_32F ); + cv::cornerEigenValsAndVecs( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE ); +} + + +CV_IMPL void +cvPreCornerDetect( const void* srcarr, void* dstarr, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 ); + cv::preCornerDetect( src, dst, aperture_size, cv::BORDER_REPLICATE ); +} + +/* End of file */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/cornersubpix.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/cornersubpix.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/cornersubpix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/cornersubpix.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,265 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +CV_IMPL void +cvFindCornerSubPix( const void* srcarr, CvPoint2D32f* corners, + int count, CvSize win, CvSize zeroZone, + CvTermCriteria criteria ) +{ + cv::AutoBuffer buffer; + + const int MAX_ITERS = 100; + const float drv[] = { -1.f, 0.f, 1.f }; + float *maskX; + float *maskY; + float *mask; + float *src_buffer; + float *gx_buffer; + float *gy_buffer; + int win_w = win.width * 2 + 1, win_h = win.height * 2 + 1; + int win_rect_size = (win_w + 4) * (win_h + 4); + double coeff; + CvSize size, src_buf_size; + int i, j, k, pt_i; + int max_iters = 10; + double eps = 0; + + CvMat stub, *src = (CvMat*)srcarr; + src = cvGetMat( srcarr, &stub ); + + if( CV_MAT_TYPE( src->type ) != CV_8UC1 ) + CV_Error( CV_StsUnsupportedFormat, "The source image must be 8-bit single-channel (CV_8UC1)" ); + + if( !corners ) + CV_Error( CV_StsNullPtr, "" ); + + if( count < 0 ) + CV_Error( CV_StsBadSize, "" ); + + if( count == 0 ) + return; + + if( win.width <= 0 || win.height <= 0 ) + CV_Error( CV_StsBadSize, "" ); + + size = cvGetMatSize( src ); + + if( size.width < win_w + 4 || size.height < win_h + 4 ) + CV_Error( CV_StsBadSize, "" ); + + /* initialize variables, controlling loop termination */ + switch( criteria.type ) + { + case CV_TERMCRIT_ITER: + eps = 0.f; + max_iters = criteria.max_iter; + break; + case CV_TERMCRIT_EPS: + eps = criteria.epsilon; + max_iters = MAX_ITERS; + break; + case CV_TERMCRIT_ITER | CV_TERMCRIT_EPS: + eps = criteria.epsilon; + max_iters = criteria.max_iter; + break; + default: + assert( 0 ); + CV_Error( CV_StsBadFlag, "" ); + } + + eps = MAX( eps, 0 ); + eps *= eps; /* use square of error in comparsion operations. */ + + max_iters = MAX( max_iters, 1 ); + max_iters = MIN( max_iters, MAX_ITERS ); + + buffer.allocate( win_rect_size * 5 + win_w + win_h + 32 ); + + /* assign pointers */ + maskX = buffer; + maskY = maskX + win_w + 4; + mask = maskY + win_h + 4; + src_buffer = mask + win_w * win_h; + gx_buffer = src_buffer + win_rect_size; + gy_buffer = gx_buffer + win_rect_size; + + coeff = 1. / (win.width * win.width); + + /* calculate mask */ + for( i = -win.width, k = 0; i <= win.width; i++, k++ ) + { + maskX[k] = (float)exp( -i * i * coeff ); + } + + if( win.width == win.height ) + { + maskY = maskX; + } + else + { + coeff = 1. / (win.height * win.height); + for( i = -win.height, k = 0; i <= win.height; i++, k++ ) + { + maskY[k] = (float) exp( -i * i * coeff ); + } + } + + for( i = 0; i < win_h; i++ ) + { + for( j = 0; j < win_w; j++ ) + { + mask[i * win_w + j] = maskX[j] * maskY[i]; + } + } + + + /* make zero_zone */ + if( zeroZone.width >= 0 && zeroZone.height >= 0 && + zeroZone.width * 2 + 1 < win_w && zeroZone.height * 2 + 1 < win_h ) + { + for( i = win.height - zeroZone.height; i <= win.height + zeroZone.height; i++ ) + { + for( j = win.width - zeroZone.width; j <= win.width + zeroZone.width; j++ ) + { + mask[i * win_w + j] = 0; + } + } + } + + /* set sizes of image rectangles, used in convolutions */ + src_buf_size.width = win_w + 2; + src_buf_size.height = win_h + 2; + + /* do optimization loop for all the points */ + for( pt_i = 0; pt_i < count; pt_i++ ) + { + CvPoint2D32f cT = corners[pt_i], cI = cT; + int iter = 0; + double err; + + do + { + CvPoint2D32f cI2; + double a, b, c, bb1, bb2; + + IPPI_CALL( icvGetRectSubPix_8u32f_C1R( (uchar*)src->data.ptr, src->step, size, + src_buffer, (win_w + 2) * sizeof( src_buffer[0] ), + cvSize( win_w + 2, win_h + 2 ), cI )); + + /* calc derivatives */ + icvSepConvSmall3_32f( src_buffer+src_buf_size.width, src_buf_size.width * sizeof(src_buffer[0]), + gx_buffer, win_w * sizeof(gx_buffer[0]), + src_buf_size, drv, NULL, NULL ); + icvSepConvSmall3_32f( src_buffer+1, src_buf_size.width * sizeof(src_buffer[0]), + gy_buffer, win_w * sizeof(gy_buffer[0]), + src_buf_size, NULL, drv, NULL ); + + a = b = c = bb1 = bb2 = 0; + + /* process gradient */ + for( i = 0, k = 0; i < win_h; i++ ) + { + double py = i - win.height; + + for( j = 0; j < win_w; j++, k++ ) + { + double m = mask[k]; + double tgx = gx_buffer[k]; + double tgy = gy_buffer[k]; + double gxx = tgx * tgx * m; + double gxy = tgx * tgy * m; + double gyy = tgy * tgy * m; + double px = j - win.width; + + a += gxx; + b += gxy; + c += gyy; + + bb1 += gxx * px + gxy * py; + bb2 += gxy * px + gyy * py; + } + } + + double det=a*c-b*b; + if( fabs( det ) > DBL_EPSILON*DBL_EPSILON ) + { + // 2x2 matrix inversion + double scale=1.0/det; + cI2.x = (float)(cI.x + c*scale*bb1 - b*scale*bb2); + cI2.y = (float)(cI.y - b*scale*bb1 + a*scale*bb2); + } + else + { + cI2 = cI; + } + + err = (cI2.x - cI.x) * (cI2.x - cI.x) + (cI2.y - cI.y) * (cI2.y - cI.y); + cI = cI2; + } + while( ++iter < max_iters && err > eps ); + + /* if new point is too far from initial, it means poor convergence. + leave initial point as the result */ + if( fabs( cI.x - cT.x ) > win.width || fabs( cI.y - cT.y ) > win.height ) + { + cI = cT; + } + + corners[pt_i] = cI; /* store result */ + } +} + +void cv::cornerSubPix( InputArray _image, InputOutputArray _corners, + Size winSize, Size zeroZone, + TermCriteria criteria ) +{ + Mat corners = _corners.getMat(); + int ncorners = corners.checkVector(2); + CV_Assert( ncorners >= 0 && corners.depth() == CV_32F ); + Mat image = _image.getMat(); + CvMat c_image = image; + + cvFindCornerSubPix( &c_image, (CvPoint2D32f*)corners.data, ncorners, + winSize, zeroZone, criteria ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/deriv.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/deriv.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/deriv.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/deriv.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,670 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) +static IppStatus sts = ippInit(); +#endif +/****************************************************************************************/ + +/* lightweight convolution with 3x3 kernel */ +void icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step, + CvSize src_size, const float* kx, const float* ky, float* buffer ) +{ + int dst_width, buffer_step = 0; + int x, y; + bool fast_kx = true, fast_ky = true; + + assert( src && dst && src_size.width > 2 && src_size.height > 2 && + (src_step & 3) == 0 && (dst_step & 3) == 0 && + (kx || ky) && (buffer || !kx || !ky)); + + src_step /= sizeof(src[0]); + dst_step /= sizeof(dst[0]); + + dst_width = src_size.width - 2; + + if( !kx ) + { + /* set vars, so that vertical convolution + will write results into destination ROI and + horizontal convolution won't run */ + src_size.width = dst_width; + buffer_step = dst_step; + buffer = dst; + dst_width = 0; + } + else + fast_kx = kx[1] == 0.f && kx[0] == -kx[2] && kx[0] == -1.f; + + assert( src_step >= src_size.width && dst_step >= dst_width ); + + src_size.height -= 2; + if( !ky ) + { + /* set vars, so that vertical convolution won't run and + horizontal convolution will write results into destination ROI */ + src_size.height += 2; + buffer_step = src_step; + buffer = src; + src_size.width = 0; + } + else + fast_ky = ky[1] == 0.f && ky[0] == -ky[2] && ky[0] == -1.f; + + for( y = 0; y < src_size.height; y++, src += src_step, + dst += dst_step, + buffer += buffer_step ) + { + float* src2 = src + src_step; + float* src3 = src + src_step*2; + if( fast_ky ) + for( x = 0; x < src_size.width; x++ ) + { + buffer[x] = (float)(src3[x] - src[x]); + } + else + for( x = 0; x < src_size.width; x++ ) + { + buffer[x] = (float)(ky[0]*src[x] + ky[1]*src2[x] + ky[2]*src3[x]); + } + + if( fast_kx ) + for( x = 0; x < dst_width; x++ ) + { + dst[x] = (float)(buffer[x+2] - buffer[x]); + } + else + for( x = 0; x < dst_width; x++ ) + { + dst[x] = (float)(kx[0]*buffer[x] + kx[1]*buffer[x+1] + kx[2]*buffer[x+2]); + } + } +} + + +/****************************************************************************************\ + Sobel & Scharr Derivative Filters +\****************************************************************************************/ + +namespace cv +{ + +static void getScharrKernels( OutputArray _kx, OutputArray _ky, + int dx, int dy, bool normalize, int ktype ) +{ + const int ksize = 3; + + CV_Assert( ktype == CV_32F || ktype == CV_64F ); + _kx.create(ksize, 1, ktype, -1, true); + _ky.create(ksize, 1, ktype, -1, true); + Mat kx = _kx.getMat(); + Mat ky = _ky.getMat(); + + CV_Assert( dx >= 0 && dy >= 0 && dx+dy == 1 ); + + for( int k = 0; k < 2; k++ ) + { + Mat* kernel = k == 0 ? &kx : &ky; + int order = k == 0 ? dx : dy; + int kerI[3]; + + if( order == 0 ) + kerI[0] = 3, kerI[1] = 10, kerI[2] = 3; + else if( order == 1 ) + kerI[0] = -1, kerI[1] = 0, kerI[2] = 1; + + Mat temp(kernel->rows, kernel->cols, CV_32S, &kerI[0]); + double scale = !normalize || order == 1 ? 1. : 1./32; + temp.convertTo(*kernel, ktype, scale); + } +} + + +static void getSobelKernels( OutputArray _kx, OutputArray _ky, + int dx, int dy, int _ksize, bool normalize, int ktype ) +{ + int i, j, ksizeX = _ksize, ksizeY = _ksize; + if( ksizeX == 1 && dx > 0 ) + ksizeX = 3; + if( ksizeY == 1 && dy > 0 ) + ksizeY = 3; + + CV_Assert( ktype == CV_32F || ktype == CV_64F ); + + _kx.create(ksizeX, 1, ktype, -1, true); + _ky.create(ksizeY, 1, ktype, -1, true); + Mat kx = _kx.getMat(); + Mat ky = _ky.getMat(); + + if( _ksize % 2 == 0 || _ksize > 31 ) + CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" ); + vector kerI(std::max(ksizeX, ksizeY) + 1); + + CV_Assert( dx >= 0 && dy >= 0 && dx+dy > 0 ); + + for( int k = 0; k < 2; k++ ) + { + Mat* kernel = k == 0 ? &kx : &ky; + int order = k == 0 ? dx : dy; + int ksize = k == 0 ? ksizeX : ksizeY; + + CV_Assert( ksize > order ); + + if( ksize == 1 ) + kerI[0] = 1; + else if( ksize == 3 ) + { + if( order == 0 ) + kerI[0] = 1, kerI[1] = 2, kerI[2] = 1; + else if( order == 1 ) + kerI[0] = -1, kerI[1] = 0, kerI[2] = 1; + else + kerI[0] = 1, kerI[1] = -2, kerI[2] = 1; + } + else + { + int oldval, newval; + kerI[0] = 1; + for( i = 0; i < ksize; i++ ) + kerI[i+1] = 0; + + for( i = 0; i < ksize - order - 1; i++ ) + { + oldval = kerI[0]; + for( j = 1; j <= ksize; j++ ) + { + newval = kerI[j]+kerI[j-1]; + kerI[j-1] = oldval; + oldval = newval; + } + } + + for( i = 0; i < order; i++ ) + { + oldval = -kerI[0]; + for( j = 1; j <= ksize; j++ ) + { + newval = kerI[j-1] - kerI[j]; + kerI[j-1] = oldval; + oldval = newval; + } + } + } + + Mat temp(kernel->rows, kernel->cols, CV_32S, &kerI[0]); + double scale = !normalize ? 1. : 1./(1 << (ksize-order-1)); + temp.convertTo(*kernel, ktype, scale); + } +} + +} + +void cv::getDerivKernels( OutputArray kx, OutputArray ky, int dx, int dy, + int ksize, bool normalize, int ktype ) +{ + if( ksize <= 0 ) + getScharrKernels( kx, ky, dx, dy, normalize, ktype ); + else + getSobelKernels( kx, ky, dx, dy, ksize, normalize, ktype ); +} + + +cv::Ptr cv::createDerivFilter(int srcType, int dstType, + int dx, int dy, int ksize, int borderType ) +{ + Mat kx, ky; + getDerivKernels( kx, ky, dx, dy, ksize, false, CV_32F ); + return createSeparableLinearFilter(srcType, dstType, + kx, ky, Point(-1,-1), 0, borderType ); +} + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + +namespace cv +{ + +static bool IPPDerivScharr(const Mat& src, Mat& dst, int ddepth, int dx, int dy, double scale) +{ + int bufSize = 0; + cv::AutoBuffer buffer; + IppiSize roi = ippiSize(src.cols, src.rows); + + if( ddepth < 0 ) + ddepth = src.depth(); + + dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + + switch(src.type()) + { + case CV_8U: + { + if(scale != 1) + return false; + + switch(dst.type()) + { + case CV_16S: + { + if((dx == 1) && (dy == 0)) + { + ippiFilterScharrVertGetBufferSize_8u16s_C1R(roi,&bufSize); + buffer.allocate(bufSize); + + ippiFilterScharrVertBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, roi, ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + + return true; + } + + if((dx == 0) && (dy == 1)) + { + ippiFilterScharrHorizGetBufferSize_8u16s_C1R(roi,&bufSize); + buffer.allocate(bufSize); + + ippiFilterScharrHorizBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, roi, ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + + return true; + } + } + + default: + return false; + } + } + + case CV_32F: + { + switch(dst.type()) + { + case CV_32F: + if((dx == 1) && (dy == 0)) + { + ippiFilterScharrVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows),&bufSize); + buffer.allocate(bufSize); + + ippiFilterScharrVertBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + /* IPP is fast, so MulC produce very little perf degradation */ + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f*)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + + if((dx == 0) && (dy == 1)) + { + ippiFilterScharrHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows),&bufSize); + buffer.allocate(bufSize); + + ippiFilterScharrHorizBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + + default: + return false; + } + } + + default: + return false; + } +} + + +static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int ksize, double scale) +{ + int bufSize = 0; + cv::AutoBuffer buffer; + + if(ksize == 3 || ksize == 5) + { + if( ddepth < 0 ) + ddepth = src.depth(); + + if(src.type() == CV_8U && dst.type() == CV_16S && scale == 1) + { + if((dx == 1) && (dy == 0)) + { + ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelNegVertBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + return true; + } + + if((dx == 0) && (dy == 1)) + { + ippiFilterSobelHorizGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelHorizBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + + return true; + } + + if((dx == 2) && (dy == 0)) + { + ippiFilterSobelVertSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelVertSecondBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + + return true; + } + + if((dx == 0) && (dy == 2)) + { + ippiFilterSobelHorizSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelHorizSecondBorder_8u16s_C1R((const Ipp8u*)src.data, src.step, + (Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + + return true; + } + } + + if(src.type() == CV_32F && dst.type() == CV_32F) + { + if((dx == 1) && (dy == 0)) + { + ippiFilterSobelNegVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelNegVertBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + + if((dx == 0) && (dy == 1)) + { + ippiFilterSobelHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelHorizBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + + if((dx == 2) && (dy == 0)) + { + ippiFilterSobelVertSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelVertSecondBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + + if((dx == 0) && (dy == 2)) + { + ippiFilterSobelHorizSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize); + buffer.allocate(bufSize); + + ippiFilterSobelHorizSecondBorder_32f_C1R((const Ipp32f*)src.data, src.step, + (Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer); + if(scale != 1) + ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows)); + + return true; + } + } + } + + if(ksize <= 0) + return IPPDerivScharr(src, dst, ddepth, dx, dy, scale); + + return false; +} + +} + +#endif + +void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, + int ksize, double scale, double delta, int borderType ) +{ + Mat src = _src.getMat(); + if (ddepth < 0) + ddepth = src.depth(); + _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (scale == 1.0 && delta == 0) + { + if (ksize == 3 && tegra::sobel3x3(src, dst, dx, dy, borderType)) + return; + if (ksize == -1 && tegra::scharr(src, dst, dx, dy, borderType)) + return; + } +#endif + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1) + { + if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale)) + return; + } +#endif + int ktype = std::max(CV_32F, std::max(ddepth, src.depth())); + + Mat kx, ky; + getDerivKernels( kx, ky, dx, dy, ksize, false, ktype ); + if( scale != 1 ) + { + // usually the smoothing part is the slowest to compute, + // so try to scale it instead of the faster differenciating part + if( dx == 0 ) + kx *= scale; + else + ky *= scale; + } + sepFilter2D( src, dst, ddepth, kx, ky, Point(-1,-1), delta, borderType ); +} + + +void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, + double scale, double delta, int borderType ) +{ + Mat src = _src.getMat(); + if (ddepth < 0) + ddepth = src.depth(); + _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (scale == 1.0 && delta == 0) + if (tegra::scharr(src, dst, dx, dy, borderType)) + return; +#endif + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1) + { + if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale)) + return; + } +#endif + int ktype = std::max(CV_32F, std::max(ddepth, src.depth())); + + Mat kx, ky; + getScharrKernels( kx, ky, dx, dy, false, ktype ); + if( scale != 1 ) + { + // usually the smoothing part is the slowest to compute, + // so try to scale it instead of the faster differenciating part + if( dx == 0 ) + kx *= scale; + else + ky *= scale; + } + sepFilter2D( src, dst, ddepth, kx, ky, Point(-1,-1), delta, borderType ); +} + + +void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize, + double scale, double delta, int borderType ) +{ + Mat src = _src.getMat(); + if (ddepth < 0) + ddepth = src.depth(); + _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (scale == 1.0 && delta == 0) + { + if (ksize == 1 && tegra::laplace1(src, dst, borderType)) + return; + if (ksize == 3 && tegra::laplace3(src, dst, borderType)) + return; + if (ksize == 5 && tegra::laplace5(src, dst, borderType)) + return; + } +#endif + + if( ksize == 1 || ksize == 3 ) + { + float K[2][9] = + {{0, 1, 0, 1, -4, 1, 0, 1, 0}, + {2, 0, 2, 0, -8, 0, 2, 0, 2}}; + Mat kernel(3, 3, CV_32F, K[ksize == 3]); + if( scale != 1 ) + kernel *= scale; + filter2D( src, dst, ddepth, kernel, Point(-1,-1), delta, borderType ); + } + else + { + const size_t STRIPE_SIZE = 1 << 14; + + int depth = src.depth(); + int ktype = std::max(CV_32F, std::max(ddepth, depth)); + int wdepth = depth == CV_8U && ksize <= 5 ? CV_16S : depth <= CV_32F ? CV_32F : CV_64F; + int wtype = CV_MAKETYPE(wdepth, src.channels()); + Mat kd, ks; + getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); + if( ddepth < 0 ) + ddepth = src.depth(); + int dtype = CV_MAKETYPE(ddepth, src.channels()); + + int dy0 = std::min(std::max((int)(STRIPE_SIZE/(getElemSize(src.type())*src.cols)), 1), src.rows); + Ptr fx = createSeparableLinearFilter(src.type(), + wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); + Ptr fy = createSeparableLinearFilter(src.type(), + wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); + + int y = fx->start(src), dsty = 0, dy = 0; + fy->start(src); + const uchar* sptr = src.data + y*src.step; + + Mat d2x( dy0 + kd.rows - 1, src.cols, wtype ); + Mat d2y( dy0 + kd.rows - 1, src.cols, wtype ); + + for( ; dsty < src.rows; sptr += dy0*src.step, dsty += dy ) + { + fx->proceed( sptr, (int)src.step, dy0, d2x.data, (int)d2x.step ); + dy = fy->proceed( sptr, (int)src.step, dy0, d2y.data, (int)d2y.step ); + if( dy > 0 ) + { + Mat dstripe = dst.rowRange(dsty, dsty + dy); + d2x.rows = d2y.rows = dy; // modify the headers, which should work + d2x += d2y; + d2x.convertTo( dstripe, dtype, scale, delta ); + } + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +CV_IMPL void +cvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size() == dst.size() && src.channels() == dst.channels() ); + + cv::Sobel( src, dst, dst.depth(), dx, dy, aperture_size, 1, 0, cv::BORDER_REPLICATE ); + if( CV_IS_IMAGE(srcarr) && ((IplImage*)srcarr)->origin && dy % 2 != 0 ) + dst *= -1; +} + + +CV_IMPL void +cvLaplace( const void* srcarr, void* dstarr, int aperture_size ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( src.size() == dst.size() && src.channels() == dst.channels() ); + + cv::Laplacian( src, dst, dst.depth(), aperture_size, 1, 0, cv::BORDER_REPLICATE ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/distransform.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/distransform.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/distransform.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/distransform.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,849 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +#define ICV_DIST_SHIFT 16 +#define ICV_INIT_DIST0 (INT_MAX >> 2) + +static CvStatus +icvInitTopBottom( int* temp, int tempstep, CvSize size, int border ) +{ + int i, j; + for( i = 0; i < border; i++ ) + { + int* ttop = (int*)(temp + i*tempstep); + int* tbottom = (int*)(temp + (size.height + border*2 - i - 1)*tempstep); + + for( j = 0; j < size.width + border*2; j++ ) + { + ttop[j] = ICV_INIT_DIST0; + tbottom[j] = ICV_INIT_DIST0; + } + } + + return CV_OK; +} + + +static CvStatus CV_STDCALL +icvDistanceTransform_3x3_C1R( const uchar* src, int srcstep, int* temp, + int step, float* dist, int dststep, CvSize size, const float* metrics ) +{ + const int BORDER = 1; + int i, j; + const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); + const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); + const float scale = 1.f/(1 << ICV_DIST_SHIFT); + + srcstep /= sizeof(src[0]); + step /= sizeof(temp[0]); + dststep /= sizeof(dist[0]); + + icvInitTopBottom( temp, step, size, BORDER ); + + // forward pass + for( i = 0; i < size.height; i++ ) + { + const uchar* s = src + i*srcstep; + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + + for( j = 0; j < BORDER; j++ ) + tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; + + for( j = 0; j < size.width; j++ ) + { + if( !s[j] ) + tmp[j] = 0; + else + { + int t0 = tmp[j-step-1] + DIAG_DIST; + int t = tmp[j-step] + HV_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step+1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-1] + HV_DIST; + if( t0 > t ) t0 = t; + tmp[j] = t0; + } + } + } + + // backward pass + for( i = size.height - 1; i >= 0; i-- ) + { + float* d = (float*)(dist + i*dststep); + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + + for( j = size.width - 1; j >= 0; j-- ) + { + int t0 = tmp[j]; + if( t0 > HV_DIST ) + { + int t = tmp[j+step+1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step] + HV_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step-1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+1] + HV_DIST; + if( t0 > t ) t0 = t; + tmp[j] = t0; + } + d[j] = (float)(t0 * scale); + } + } + + return CV_OK; +} + + +static CvStatus CV_STDCALL +icvDistanceTransform_5x5_C1R( const uchar* src, int srcstep, int* temp, + int step, float* dist, int dststep, CvSize size, const float* metrics ) +{ + const int BORDER = 2; + int i, j; + const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); + const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); + const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], ICV_DIST_SHIFT ); + const float scale = 1.f/(1 << ICV_DIST_SHIFT); + + srcstep /= sizeof(src[0]); + step /= sizeof(temp[0]); + dststep /= sizeof(dist[0]); + + icvInitTopBottom( temp, step, size, BORDER ); + + // forward pass + for( i = 0; i < size.height; i++ ) + { + const uchar* s = src + i*srcstep; + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + + for( j = 0; j < BORDER; j++ ) + tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; + + for( j = 0; j < size.width; j++ ) + { + if( !s[j] ) + tmp[j] = 0; + else + { + int t0 = tmp[j-step*2-1] + LONG_DIST; + int t = tmp[j-step*2+1] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step-2] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step-1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step] + HV_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step+1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-step+2] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j-1] + HV_DIST; + if( t0 > t ) t0 = t; + tmp[j] = t0; + } + } + } + + // backward pass + for( i = size.height - 1; i >= 0; i-- ) + { + float* d = (float*)(dist + i*dststep); + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + + for( j = size.width - 1; j >= 0; j-- ) + { + int t0 = tmp[j]; + if( t0 > HV_DIST ) + { + int t = tmp[j+step*2+1] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step*2-1] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step+2] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step+1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step] + HV_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step-1] + DIAG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+step-2] + LONG_DIST; + if( t0 > t ) t0 = t; + t = tmp[j+1] + HV_DIST; + if( t0 > t ) t0 = t; + tmp[j] = t0; + } + d[j] = (float)(t0 * scale); + } + } + + return CV_OK; +} + + +static CvStatus CV_STDCALL +icvDistanceTransformEx_5x5_C1R( const uchar* src, int srcstep, int* temp, + int step, float* dist, int dststep, int* labels, int lstep, + CvSize size, const float* metrics ) +{ + const int BORDER = 2; + + int i, j; + const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); + const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); + const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], ICV_DIST_SHIFT ); + const float scale = 1.f/(1 << ICV_DIST_SHIFT); + + srcstep /= sizeof(src[0]); + step /= sizeof(temp[0]); + dststep /= sizeof(dist[0]); + lstep /= sizeof(labels[0]); + + icvInitTopBottom( temp, step, size, BORDER ); + + // forward pass + for( i = 0; i < size.height; i++ ) + { + const uchar* s = src + i*srcstep; + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + int* lls = (int*)(labels + i*lstep); + + for( j = 0; j < BORDER; j++ ) + tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; + + for( j = 0; j < size.width; j++ ) + { + if( !s[j] ) + { + tmp[j] = 0; + //assert( lls[j] != 0 ); + } + else + { + int t0 = ICV_INIT_DIST0, t; + int l0 = 0; + + t = tmp[j-step*2-1] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep*2-1]; + } + t = tmp[j-step*2+1] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep*2+1]; + } + t = tmp[j-step-2] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep-2]; + } + t = tmp[j-step-1] + DIAG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep-1]; + } + t = tmp[j-step] + HV_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep]; + } + t = tmp[j-step+1] + DIAG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep+1]; + } + t = tmp[j-step+2] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-lstep+2]; + } + t = tmp[j-1] + HV_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j-1]; + } + + tmp[j] = t0; + lls[j] = l0; + } + } + } + + // backward pass + for( i = size.height - 1; i >= 0; i-- ) + { + float* d = (float*)(dist + i*dststep); + int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; + int* lls = (int*)(labels + i*lstep); + + for( j = size.width - 1; j >= 0; j-- ) + { + int t0 = tmp[j]; + int l0 = lls[j]; + if( t0 > HV_DIST ) + { + int t = tmp[j+step*2+1] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep*2+1]; + } + t = tmp[j+step*2-1] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep*2-1]; + } + t = tmp[j+step+2] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep+2]; + } + t = tmp[j+step+1] + DIAG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep+1]; + } + t = tmp[j+step] + HV_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep]; + } + t = tmp[j+step-1] + DIAG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep-1]; + } + t = tmp[j+step-2] + LONG_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+lstep-2]; + } + t = tmp[j+1] + HV_DIST; + if( t0 > t ) + { + t0 = t; + l0 = lls[j+1]; + } + tmp[j] = t0; + lls[j] = l0; + } + d[j] = (float)(t0 * scale); + } + } + + return CV_OK; +} + + +static CvStatus +icvGetDistanceTransformMask( int maskType, float *metrics ) +{ + if( !metrics ) + return CV_NULLPTR_ERR; + + switch (maskType) + { + case 30: + metrics[0] = 1.0f; + metrics[1] = 1.0f; + break; + + case 31: + metrics[0] = 1.0f; + metrics[1] = 2.0f; + break; + + case 32: + metrics[0] = 0.955f; + metrics[1] = 1.3693f; + break; + + case 50: + metrics[0] = 1.0f; + metrics[1] = 1.0f; + metrics[2] = 2.0f; + break; + + case 51: + metrics[0] = 1.0f; + metrics[1] = 2.0f; + metrics[2] = 3.0f; + break; + + case 52: + metrics[0] = 1.0f; + metrics[1] = 1.4f; + metrics[2] = 2.1969f; + break; + default: + return CV_BADRANGE_ERR; + } + + return CV_OK; +} + +namespace cv +{ + +struct DTColumnInvoker +{ + DTColumnInvoker( const CvMat* _src, CvMat* _dst, const int* _sat_tab, const float* _sqr_tab) + { + src = _src; + dst = _dst; + sat_tab = _sat_tab + src->rows*2 + 1; + sqr_tab = _sqr_tab; + } + + void operator()( const BlockedRange& range ) const + { + int i, i1 = range.begin(), i2 = range.end(); + int m = src->rows; + size_t sstep = src->step, dstep = dst->step/sizeof(float); + AutoBuffer _d(m); + int* d = _d; + + for( i = i1; i < i2; i++ ) + { + const uchar* sptr = src->data.ptr + i + (m-1)*sstep; + float* dptr = dst->data.fl + i; + int j, dist = m-1; + + for( j = m-1; j >= 0; j--, sptr -= sstep ) + { + dist = (dist + 1) & (sptr[0] == 0 ? 0 : -1); + d[j] = dist; + } + + dist = m-1; + for( j = 0; j < m; j++, dptr += dstep ) + { + dist = dist + 1 - sat_tab[dist - d[j]]; + d[j] = dist; + dptr[0] = sqr_tab[dist]; + } + } + } + + const CvMat* src; + CvMat* dst; + const int* sat_tab; + const float* sqr_tab; +}; + + +struct DTRowInvoker +{ + DTRowInvoker( CvMat* _dst, const float* _sqr_tab, const float* _inv_tab ) + { + dst = _dst; + sqr_tab = _sqr_tab; + inv_tab = _inv_tab; + } + + void operator()( const BlockedRange& range ) const + { + const float inf = 1e15f; + int i, i1 = range.begin(), i2 = range.end(); + int n = dst->cols; + AutoBuffer _buf((n+2)*2*sizeof(float) + (n+2)*sizeof(int)); + float* f = (float*)(uchar*)_buf; + float* z = f + n; + int* v = alignPtr((int*)(z + n + 1), sizeof(int)); + + for( i = i1; i < i2; i++ ) + { + float* d = (float*)(dst->data.ptr + i*dst->step); + int p, q, k; + + v[0] = 0; + z[0] = -inf; + z[1] = inf; + f[0] = d[0]; + + for( q = 1, k = 0; q < n; q++ ) + { + float fq = d[q]; + f[q] = fq; + + for(;;k--) + { + p = v[k]; + float s = (fq + sqr_tab[q] - d[p] - sqr_tab[p])*inv_tab[q - p]; + if( s > z[k] ) + { + k++; + v[k] = q; + z[k] = s; + z[k+1] = inf; + break; + } + } + } + + for( q = 0, k = 0; q < n; q++ ) + { + while( z[k+1] < q ) + k++; + p = v[k]; + d[q] = std::sqrt(sqr_tab[std::abs(q - p)] + f[p]); + } + } + } + + CvMat* dst; + const float* sqr_tab; + const float* inv_tab; +}; + +} + +static void +icvTrueDistTrans( const CvMat* src, CvMat* dst ) +{ + const float inf = 1e15f; + + if( !CV_ARE_SIZES_EQ( src, dst )) + CV_Error( CV_StsUnmatchedSizes, "" ); + + if( CV_MAT_TYPE(src->type) != CV_8UC1 || + CV_MAT_TYPE(dst->type) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, + "The input image must have 8uC1 type and the output one must have 32fC1 type" ); + + int i, m = src->rows, n = src->cols; + + cv::AutoBuffer _buf(std::max(m*2*sizeof(float) + (m*3+1)*sizeof(int), n*2*sizeof(float))); + // stage 1: compute 1d distance transform of each column + float* sqr_tab = (float*)(uchar*)_buf; + int* sat_tab = cv::alignPtr((int*)(sqr_tab + m*2), sizeof(int)); + int shift = m*2; + + for( i = 0; i < m; i++ ) + sqr_tab[i] = (float)(i*i); + for( i = m; i < m*2; i++ ) + sqr_tab[i] = inf; + for( i = 0; i < shift; i++ ) + sat_tab[i] = 0; + for( ; i <= m*3; i++ ) + sat_tab[i] = i - shift; + + cv::parallel_for(cv::BlockedRange(0, n), cv::DTColumnInvoker(src, dst, sat_tab, sqr_tab)); + + // stage 2: compute modified distance transform for each row + float* inv_tab = sqr_tab + n; + + inv_tab[0] = sqr_tab[0] = 0.f; + for( i = 1; i < n; i++ ) + { + inv_tab[i] = (float)(0.5/i); + sqr_tab[i] = (float)(i*i); + } + + cv::parallel_for(cv::BlockedRange(0, m), cv::DTRowInvoker(dst, sqr_tab, inv_tab)); +} + + +/*********************************** IPP functions *********************************/ + +typedef CvStatus (CV_STDCALL * CvIPPDistTransFunc)( const uchar* src, int srcstep, + void* dst, int dststep, + CvSize size, const void* metrics ); + +typedef CvStatus (CV_STDCALL * CvIPPDistTransFunc2)( uchar* src, int srcstep, + CvSize size, const int* metrics ); + +/***********************************************************************************/ + +typedef CvStatus (CV_STDCALL * CvDistTransFunc)( const uchar* src, int srcstep, + int* temp, int tempstep, + float* dst, int dststep, + CvSize size, const float* metrics ); + + +/****************************************************************************************\ + Non-inplace and Inplace 8u->8u Distance Transform for CityBlock (a.k.a. L1) metric + (C) 2006 by Jay Stavinzky. +\****************************************************************************************/ + +//BEGIN ATS ADDITION +/* 8-bit grayscale distance transform function */ +static void +icvDistanceATS_L1_8u( const CvMat* src, CvMat* dst ) +{ + int width = src->cols, height = src->rows; + + int a; + uchar lut[256]; + int x, y; + + const uchar *sbase = src->data.ptr; + uchar *dbase = dst->data.ptr; + int srcstep = src->step; + int dststep = dst->step; + + CV_Assert( CV_IS_MASK_ARR( src ) && CV_MAT_TYPE( dst->type ) == CV_8UC1 ); + CV_Assert( CV_ARE_SIZES_EQ( src, dst )); + + ////////////////////// forward scan //////////////////////// + for( x = 0; x < 256; x++ ) + lut[x] = CV_CAST_8U(x+1); + + //init first pixel to max (we're going to be skipping it) + dbase[0] = (uchar)(sbase[0] == 0 ? 0 : 255); + + //first row (scan west only, skip first pixel) + for( x = 1; x < width; x++ ) + dbase[x] = (uchar)(sbase[x] == 0 ? 0 : lut[dbase[x-1]]); + + for( y = 1; y < height; y++ ) + { + sbase += srcstep; + dbase += dststep; + + //for left edge, scan north only + a = sbase[0] == 0 ? 0 : lut[dbase[-dststep]]; + dbase[0] = (uchar)a; + + for( x = 1; x < width; x++ ) + { + a = sbase[x] == 0 ? 0 : lut[MIN(a, dbase[x - dststep])]; + dbase[x] = (uchar)a; + } + } + + ////////////////////// backward scan /////////////////////// + + a = dbase[width-1]; + + // do last row east pixel scan here (skip bottom right pixel) + for( x = width - 2; x >= 0; x-- ) + { + a = lut[a]; + dbase[x] = (uchar)(CV_CALC_MIN_8U(a, dbase[x])); + } + + // right edge is the only error case + for( y = height - 2; y >= 0; y-- ) + { + dbase -= dststep; + + // do right edge + a = lut[dbase[width-1+dststep]]; + dbase[width-1] = (uchar)(MIN(a, dbase[width-1])); + + for( x = width - 2; x >= 0; x-- ) + { + int b = dbase[x+dststep]; + a = lut[MIN(a, b)]; + dbase[x] = (uchar)(MIN(a, dbase[x])); + } + } +} +//END ATS ADDITION + + +/* Wrapper function for distance transform group */ +CV_IMPL void +cvDistTransform( const void* srcarr, void* dstarr, + int distType, int maskSize, + const float *mask, + void* labelsarr, int labelType ) +{ + float _mask[5] = {0}; + CvMat srcstub, *src = (CvMat*)srcarr; + CvMat dststub, *dst = (CvMat*)dstarr; + CvMat lstub, *labels = (CvMat*)labelsarr; + + src = cvGetMat( src, &srcstub ); + dst = cvGetMat( dst, &dststub ); + + if( !CV_IS_MASK_ARR( src ) || (CV_MAT_TYPE( dst->type ) != CV_32FC1 && + (CV_MAT_TYPE(dst->type) != CV_8UC1 || distType != CV_DIST_L1 || labels)) ) + CV_Error( CV_StsUnsupportedFormat, + "source image must be 8uC1 and the distance map must be 32fC1 " + "(or 8uC1 in case of simple L1 distance transform)" ); + + if( !CV_ARE_SIZES_EQ( src, dst )) + CV_Error( CV_StsUnmatchedSizes, "the source and the destination images must be of the same size" ); + + if( maskSize != CV_DIST_MASK_3 && maskSize != CV_DIST_MASK_5 && maskSize != CV_DIST_MASK_PRECISE ) + CV_Error( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (presize)" ); + + if( distType == CV_DIST_C || distType == CV_DIST_L1 ) + maskSize = !labels ? CV_DIST_MASK_3 : CV_DIST_MASK_5; + else if( distType == CV_DIST_L2 && labels ) + maskSize = CV_DIST_MASK_5; + + if( maskSize == CV_DIST_MASK_PRECISE ) + { + icvTrueDistTrans( src, dst ); + return; + } + + if( labels ) + { + labels = cvGetMat( labels, &lstub ); + if( CV_MAT_TYPE( labels->type ) != CV_32SC1 ) + CV_Error( CV_StsUnsupportedFormat, "the output array of labels must be 32sC1" ); + + if( !CV_ARE_SIZES_EQ( labels, dst )) + CV_Error( CV_StsUnmatchedSizes, "the array of labels has a different size" ); + + if( maskSize == CV_DIST_MASK_3 ) + CV_Error( CV_StsNotImplemented, + "3x3 mask can not be used for \"labeled\" distance transform. Use 5x5 mask" ); + } + + if( distType == CV_DIST_C || distType == CV_DIST_L1 || distType == CV_DIST_L2 ) + { + icvGetDistanceTransformMask( (distType == CV_DIST_C ? 0 : + distType == CV_DIST_L1 ? 1 : 2) + maskSize*10, _mask ); + } + else if( distType == CV_DIST_USER ) + { + if( !mask ) + CV_Error( CV_StsNullPtr, "" ); + + memcpy( _mask, mask, (maskSize/2 + 1)*sizeof(float)); + } + + CvSize size = cvGetMatSize(src); + + if( CV_MAT_TYPE(dst->type) == CV_8UC1 ) + { + icvDistanceATS_L1_8u( src, dst ); + } + else + { + int border = maskSize == CV_DIST_MASK_3 ? 1 : 2; + cv::Ptr temp = cvCreateMat( size.height + border*2, size.width + border*2, CV_32SC1 ); + + if( !labels ) + { + CvDistTransFunc func = maskSize == CV_DIST_MASK_3 ? + icvDistanceTransform_3x3_C1R : + icvDistanceTransform_5x5_C1R; + + func( src->data.ptr, src->step, temp->data.i, temp->step, + dst->data.fl, dst->step, size, _mask ); + } + else + { + cvZero( labels ); + + if( labelType == CV_DIST_LABEL_CCOMP ) + { + CvSeq *contours = 0; + cv::Ptr st = cvCreateMemStorage(); + cv::Ptr src_copy = cvCreateMat( size.height+border*2, size.width+border*2, src->type ); + cvCopyMakeBorder(src, src_copy, cvPoint(border, border), IPL_BORDER_CONSTANT, cvScalarAll(255)); + cvCmpS( src_copy, 0, src_copy, CV_CMP_EQ ); + cvFindContours( src_copy, st, &contours, sizeof(CvContour), + CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(-border, -border)); + + for( int label = 1; contours != 0; contours = contours->h_next, label++ ) + { + CvScalar area_color = cvScalarAll(label); + cvDrawContours( labels, contours, area_color, area_color, -255, -1, 8 ); + } + } + else + { + int k = 1; + for( int i = 0; i < src->rows; i++ ) + { + const uchar* srcptr = src->data.ptr + src->step*i; + int* labelptr = (int*)(labels->data.ptr + labels->step*i); + + for( int j = 0; j < src->cols; j++ ) + if( srcptr[j] == 0 ) + labelptr[j] = k++; + } + } + + icvDistanceTransformEx_5x5_C1R( src->data.ptr, src->step, temp->data.i, temp->step, + dst->data.fl, dst->step, labels->data.i, labels->step, size, _mask ); + } + } +} + +void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labels, + int distanceType, int maskSize, int labelType ) +{ + Mat src = _src.getMat(); + _dst.create(src.size(), CV_32F); + _labels.create(src.size(), CV_32S); + CvMat c_src = src, c_dst = _dst.getMat(), c_labels = _labels.getMat(); + cvDistTransform(&c_src, &c_dst, distanceType, maskSize, 0, &c_labels, labelType); +} + +void cv::distanceTransform( InputArray _src, OutputArray _dst, + int distanceType, int maskSize ) +{ + Mat src = _src.getMat(); + _dst.create(src.size(), CV_32F); + Mat dst = _dst.getMat(); + CvMat c_src = src, c_dst = _dst.getMat(); + cvDistTransform(&c_src, &c_dst, distanceType, maskSize, 0, 0, -1); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/emd.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/emd.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/emd.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/emd.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1162 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* + Partially based on Yossi Rubner code: + ========================================================================= + emd.c + + Last update: 3/14/98 + + An implementation of the Earth Movers Distance. + Based of the solution for the Transportation problem as described in + "Introduction to Mathematical Programming" by F. S. Hillier and + G. J. Lieberman, McGraw-Hill, 1990. + + Copyright (C) 1998 Yossi Rubner + Computer Science Department, Stanford University + E-Mail: rubner@cs.stanford.edu URL: http://vision.stanford.edu/~rubner + ========================================================================== +*/ +#include "precomp.hpp" + +#define MAX_ITERATIONS 500 +#define CV_EMD_INF ((float)1e20) +#define CV_EMD_EPS ((float)1e-5) + +/* CvNode1D is used for lists, representing 1D sparse array */ +typedef struct CvNode1D +{ + float val; + struct CvNode1D *next; +} +CvNode1D; + +/* CvNode2D is used for lists, representing 2D sparse matrix */ +typedef struct CvNode2D +{ + float val; + struct CvNode2D *next[2]; /* next row & next column */ + int i, j; +} +CvNode2D; + + +typedef struct CvEMDState +{ + int ssize, dsize; + + float **cost; + CvNode2D *_x; + CvNode2D *end_x; + CvNode2D *enter_x; + char **is_x; + + CvNode2D **rows_x; + CvNode2D **cols_x; + + CvNode1D *u; + CvNode1D *v; + + int* idx1; + int* idx2; + + /* find_loop buffers */ + CvNode2D **loop; + char *is_used; + + /* russel buffers */ + float *s; + float *d; + float **delta; + + float weight, max_cost; + char *buffer; +} +CvEMDState; + +/* static function declaration */ +static int icvInitEMD( const float *signature1, int size1, + const float *signature2, int size2, + int dims, CvDistanceFunction dist_func, void *user_param, + const float* cost, int cost_step, + CvEMDState * state, float *lower_bound, + cv::AutoBuffer& _buffer ); + +static int icvFindBasicVariables( float **cost, char **is_x, + CvNode1D * u, CvNode1D * v, int ssize, int dsize ); + +static float icvIsOptimal( float **cost, char **is_x, + CvNode1D * u, CvNode1D * v, + int ssize, int dsize, CvNode2D * enter_x ); + +static void icvRussel( CvEMDState * state ); + + +static bool icvNewSolution( CvEMDState * state ); +static int icvFindLoop( CvEMDState * state ); + +static void icvAddBasicVariable( CvEMDState * state, + int min_i, int min_j, + CvNode1D * prev_u_min_i, + CvNode1D * prev_v_min_j, + CvNode1D * u_head ); + +static float icvDistL2( const float *x, const float *y, void *user_param ); +static float icvDistL1( const float *x, const float *y, void *user_param ); +static float icvDistC( const float *x, const float *y, void *user_param ); + +/* The main function */ +CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, + const CvArr* signature_arr2, + int dist_type, + CvDistanceFunction dist_func, + const CvArr* cost_matrix, + CvArr* flow_matrix, + float *lower_bound, + void *user_param ) +{ + cv::AutoBuffer local_buf; + CvEMDState state; + float emd = 0; + + memset( &state, 0, sizeof(state)); + + double total_cost = 0; + int result = 0; + float eps, min_delta; + CvNode2D *xp = 0; + CvMat sign_stub1, *signature1 = (CvMat*)signature_arr1; + CvMat sign_stub2, *signature2 = (CvMat*)signature_arr2; + CvMat cost_stub, *cost = &cost_stub; + CvMat flow_stub, *flow = (CvMat*)flow_matrix; + int dims, size1, size2; + + signature1 = cvGetMat( signature1, &sign_stub1 ); + signature2 = cvGetMat( signature2, &sign_stub2 ); + + if( signature1->cols != signature2->cols ) + CV_Error( CV_StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" ); + + dims = signature1->cols - 1; + size1 = signature1->rows; + size2 = signature2->rows; + + if( !CV_ARE_TYPES_EQ( signature1, signature2 )) + CV_Error( CV_StsUnmatchedFormats, "The array must have equal types" ); + + if( CV_MAT_TYPE( signature1->type ) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, "The signatures must be 32fC1" ); + + if( flow ) + { + flow = cvGetMat( flow, &flow_stub ); + + if( flow->rows != size1 || flow->cols != size2 ) + CV_Error( CV_StsUnmatchedSizes, + "The flow matrix size does not match to the signatures' sizes" ); + + if( CV_MAT_TYPE( flow->type ) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, "The flow matrix must be 32fC1" ); + } + + cost->data.fl = 0; + cost->step = 0; + + if( dist_type < 0 ) + { + if( cost_matrix ) + { + if( dist_func ) + CV_Error( CV_StsBadArg, + "Only one of cost matrix or distance function should be non-NULL in case of user-defined distance" ); + + if( lower_bound ) + CV_Error( CV_StsBadArg, + "The lower boundary can not be calculated if the cost matrix is used" ); + + cost = cvGetMat( cost_matrix, &cost_stub ); + if( cost->rows != size1 || cost->cols != size2 ) + CV_Error( CV_StsUnmatchedSizes, + "The cost matrix size does not match to the signatures' sizes" ); + + if( CV_MAT_TYPE( cost->type ) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, "The cost matrix must be 32fC1" ); + } + else if( !dist_func ) + CV_Error( CV_StsNullPtr, "In case of user-defined distance Distance function is undefined" ); + } + else + { + if( dims == 0 ) + CV_Error( CV_StsBadSize, + "Number of dimensions can be 0 only if a user-defined metric is used" ); + user_param = (void *) (size_t)dims; + switch (dist_type) + { + case CV_DIST_L1: + dist_func = icvDistL1; + break; + case CV_DIST_L2: + dist_func = icvDistL2; + break; + case CV_DIST_C: + dist_func = icvDistC; + break; + default: + CV_Error( CV_StsBadFlag, "Bad or unsupported metric type" ); + } + } + + result = icvInitEMD( signature1->data.fl, size1, + signature2->data.fl, size2, + dims, dist_func, user_param, + cost->data.fl, cost->step, + &state, lower_bound, local_buf ); + + if( result > 0 && lower_bound ) + { + emd = *lower_bound; + return emd; + } + + eps = CV_EMD_EPS * state.max_cost; + + /* if ssize = 1 or dsize = 1 then we are done, else ... */ + if( state.ssize > 1 && state.dsize > 1 ) + { + int itr; + + for( itr = 1; itr < MAX_ITERATIONS; itr++ ) + { + /* find basic variables */ + result = icvFindBasicVariables( state.cost, state.is_x, + state.u, state.v, state.ssize, state.dsize ); + if( result < 0 ) + break; + + /* check for optimality */ + min_delta = icvIsOptimal( state.cost, state.is_x, + state.u, state.v, + state.ssize, state.dsize, state.enter_x ); + + if( min_delta == CV_EMD_INF ) + CV_Error( CV_StsNoConv, "" ); + + /* if no negative deltamin, we found the optimal solution */ + if( min_delta >= -eps ) + break; + + /* improve solution */ + if(!icvNewSolution( &state )) + CV_Error( CV_StsNoConv, "" ); + } + } + + /* compute the total flow */ + for( xp = state._x; xp < state.end_x; xp++ ) + { + float val = xp->val; + int i = xp->i; + int j = xp->j; + + if( xp == state.enter_x ) + continue; + + int ci = state.idx1[i]; + int cj = state.idx2[j]; + + if( ci >= 0 && cj >= 0 ) + { + total_cost += (double)val * state.cost[i][j]; + if( flow ) + ((float*)(flow->data.ptr + flow->step*ci))[cj] = val; + } + } + + emd = (float) (total_cost / state.weight); + return emd; +} + + +/************************************************************************************\ +* initialize structure, allocate buffers and generate initial golution * +\************************************************************************************/ +static int icvInitEMD( const float* signature1, int size1, + const float* signature2, int size2, + int dims, CvDistanceFunction dist_func, void* user_param, + const float* cost, int cost_step, + CvEMDState* state, float* lower_bound, + cv::AutoBuffer& _buffer ) +{ + float s_sum = 0, d_sum = 0, diff; + int i, j; + int ssize = 0, dsize = 0; + int equal_sums = 1; + int buffer_size; + float max_cost = 0; + char *buffer, *buffer_end; + + memset( state, 0, sizeof( *state )); + assert( cost_step % sizeof(float) == 0 ); + cost_step /= sizeof(float); + + /* calculate buffer size */ + buffer_size = (size1+1) * (size2+1) * (sizeof( float ) + /* cost */ + sizeof( char ) + /* is_x */ + sizeof( float )) + /* delta matrix */ + (size1 + size2 + 2) * (sizeof( CvNode2D ) + /* _x */ + sizeof( CvNode2D * ) + /* cols_x & rows_x */ + sizeof( CvNode1D ) + /* u & v */ + sizeof( float ) + /* s & d */ + sizeof( int ) + sizeof(CvNode2D*)) + /* idx1 & idx2 */ + (size1+1) * (sizeof( float * ) + sizeof( char * ) + /* rows pointers for */ + sizeof( float * )) + 256; /* cost, is_x and delta */ + + if( buffer_size < (int) (dims * 2 * sizeof( float ))) + { + buffer_size = dims * 2 * sizeof( float ); + } + + /* allocate buffers */ + _buffer.allocate(buffer_size); + + state->buffer = buffer = _buffer; + buffer_end = buffer + buffer_size; + + state->idx1 = (int*) buffer; + buffer += (size1 + 1) * sizeof( int ); + + state->idx2 = (int*) buffer; + buffer += (size2 + 1) * sizeof( int ); + + state->s = (float *) buffer; + buffer += (size1 + 1) * sizeof( float ); + + state->d = (float *) buffer; + buffer += (size2 + 1) * sizeof( float ); + + /* sum up the supply and demand */ + for( i = 0; i < size1; i++ ) + { + float weight = signature1[i * (dims + 1)]; + + if( weight > 0 ) + { + s_sum += weight; + state->s[ssize] = weight; + state->idx1[ssize++] = i; + + } + else if( weight < 0 ) + CV_Error(CV_StsOutOfRange, ""); + } + + for( i = 0; i < size2; i++ ) + { + float weight = signature2[i * (dims + 1)]; + + if( weight > 0 ) + { + d_sum += weight; + state->d[dsize] = weight; + state->idx2[dsize++] = i; + } + else if( weight < 0 ) + CV_Error(CV_StsOutOfRange, ""); + } + + if( ssize == 0 || dsize == 0 ) + CV_Error(CV_StsOutOfRange, ""); + + /* if supply different than the demand, add a zero-cost dummy cluster */ + diff = s_sum - d_sum; + if( fabs( diff ) >= CV_EMD_EPS * s_sum ) + { + equal_sums = 0; + if( diff < 0 ) + { + state->s[ssize] = -diff; + state->idx1[ssize++] = -1; + } + else + { + state->d[dsize] = diff; + state->idx2[dsize++] = -1; + } + } + + state->ssize = ssize; + state->dsize = dsize; + state->weight = s_sum > d_sum ? s_sum : d_sum; + + if( lower_bound && equal_sums ) /* check lower bound */ + { + int sz1 = size1 * (dims + 1), sz2 = size2 * (dims + 1); + float lb = 0; + + float* xs = (float *) buffer; + float* xd = xs + dims; + + memset( xs, 0, dims*sizeof(xs[0])); + memset( xd, 0, dims*sizeof(xd[0])); + + for( j = 0; j < sz1; j += dims + 1 ) + { + float weight = signature1[j]; + for( i = 0; i < dims; i++ ) + xs[i] += signature1[j + i + 1] * weight; + } + + for( j = 0; j < sz2; j += dims + 1 ) + { + float weight = signature2[j]; + for( i = 0; i < dims; i++ ) + xd[i] += signature2[j + i + 1] * weight; + } + + lb = dist_func( xs, xd, user_param ) / state->weight; + i = *lower_bound <= lb; + *lower_bound = lb; + if( i ) + return 1; + } + + /* assign pointers */ + state->is_used = (char *) buffer; + /* init delta matrix */ + state->delta = (float **) buffer; + buffer += ssize * sizeof( float * ); + + for( i = 0; i < ssize; i++ ) + { + state->delta[i] = (float *) buffer; + buffer += dsize * sizeof( float ); + } + + state->loop = (CvNode2D **) buffer; + buffer += (ssize + dsize + 1) * sizeof(CvNode2D*); + + state->_x = state->end_x = (CvNode2D *) buffer; + buffer += (ssize + dsize) * sizeof( CvNode2D ); + + /* init cost matrix */ + state->cost = (float **) buffer; + buffer += ssize * sizeof( float * ); + + /* compute the distance matrix */ + for( i = 0; i < ssize; i++ ) + { + int ci = state->idx1[i]; + + state->cost[i] = (float *) buffer; + buffer += dsize * sizeof( float ); + + if( ci >= 0 ) + { + for( j = 0; j < dsize; j++ ) + { + int cj = state->idx2[j]; + if( cj < 0 ) + state->cost[i][j] = 0; + else + { + float val; + if( dist_func ) + { + val = dist_func( signature1 + ci * (dims + 1) + 1, + signature2 + cj * (dims + 1) + 1, + user_param ); + } + else + { + assert( cost ); + val = cost[cost_step*ci + cj]; + } + state->cost[i][j] = val; + if( max_cost < val ) + max_cost = val; + } + } + } + else + { + for( j = 0; j < dsize; j++ ) + state->cost[i][j] = 0; + } + } + + state->max_cost = max_cost; + + memset( buffer, 0, buffer_end - buffer ); + + state->rows_x = (CvNode2D **) buffer; + buffer += ssize * sizeof( CvNode2D * ); + + state->cols_x = (CvNode2D **) buffer; + buffer += dsize * sizeof( CvNode2D * ); + + state->u = (CvNode1D *) buffer; + buffer += ssize * sizeof( CvNode1D ); + + state->v = (CvNode1D *) buffer; + buffer += dsize * sizeof( CvNode1D ); + + /* init is_x matrix */ + state->is_x = (char **) buffer; + buffer += ssize * sizeof( char * ); + + for( i = 0; i < ssize; i++ ) + { + state->is_x[i] = buffer; + buffer += dsize; + } + + assert( buffer <= buffer_end ); + + icvRussel( state ); + + state->enter_x = (state->end_x)++; + return 0; +} + + +/****************************************************************************************\ +* icvFindBasicVariables * +\****************************************************************************************/ +static int icvFindBasicVariables( float **cost, char **is_x, + CvNode1D * u, CvNode1D * v, int ssize, int dsize ) +{ + int i, j, found; + int u_cfound, v_cfound; + CvNode1D u0_head, u1_head, *cur_u, *prev_u; + CvNode1D v0_head, v1_head, *cur_v, *prev_v; + + /* initialize the rows list (u) and the columns list (v) */ + u0_head.next = u; + for( i = 0; i < ssize; i++ ) + { + u[i].next = u + i + 1; + } + u[ssize - 1].next = 0; + u1_head.next = 0; + + v0_head.next = ssize > 1 ? v + 1 : 0; + for( i = 1; i < dsize; i++ ) + { + v[i].next = v + i + 1; + } + v[dsize - 1].next = 0; + v1_head.next = 0; + + /* there are ssize+dsize variables but only ssize+dsize-1 independent equations, + so set v[0]=0 */ + v[0].val = 0; + v1_head.next = v; + v1_head.next->next = 0; + + /* loop until all variables are found */ + u_cfound = v_cfound = 0; + while( u_cfound < ssize || v_cfound < dsize ) + { + found = 0; + if( v_cfound < dsize ) + { + /* loop over all marked columns */ + prev_v = &v1_head; + + for( found |= (cur_v = v1_head.next) != 0; cur_v != 0; cur_v = cur_v->next ) + { + float cur_v_val = cur_v->val; + + j = (int)(cur_v - v); + /* find the variables in column j */ + prev_u = &u0_head; + for( cur_u = u0_head.next; cur_u != 0; ) + { + i = (int)(cur_u - u); + if( is_x[i][j] ) + { + /* compute u[i] */ + cur_u->val = cost[i][j] - cur_v_val; + /* ...and add it to the marked list */ + prev_u->next = cur_u->next; + cur_u->next = u1_head.next; + u1_head.next = cur_u; + cur_u = prev_u->next; + } + else + { + prev_u = cur_u; + cur_u = cur_u->next; + } + } + prev_v->next = cur_v->next; + v_cfound++; + } + } + + if( u_cfound < ssize ) + { + /* loop over all marked rows */ + prev_u = &u1_head; + for( found |= (cur_u = u1_head.next) != 0; cur_u != 0; cur_u = cur_u->next ) + { + float cur_u_val = cur_u->val; + float *_cost; + char *_is_x; + + i = (int)(cur_u - u); + _cost = cost[i]; + _is_x = is_x[i]; + /* find the variables in rows i */ + prev_v = &v0_head; + for( cur_v = v0_head.next; cur_v != 0; ) + { + j = (int)(cur_v - v); + if( _is_x[j] ) + { + /* compute v[j] */ + cur_v->val = _cost[j] - cur_u_val; + /* ...and add it to the marked list */ + prev_v->next = cur_v->next; + cur_v->next = v1_head.next; + v1_head.next = cur_v; + cur_v = prev_v->next; + } + else + { + prev_v = cur_v; + cur_v = cur_v->next; + } + } + prev_u->next = cur_u->next; + u_cfound++; + } + } + + if( !found ) + return -1; + } + + return 0; +} + + +/****************************************************************************************\ +* icvIsOptimal * +\****************************************************************************************/ +static float +icvIsOptimal( float **cost, char **is_x, + CvNode1D * u, CvNode1D * v, int ssize, int dsize, CvNode2D * enter_x ) +{ + float delta, min_delta = CV_EMD_INF; + int i, j, min_i = 0, min_j = 0; + + /* find the minimal cij-ui-vj over all i,j */ + for( i = 0; i < ssize; i++ ) + { + float u_val = u[i].val; + float *_cost = cost[i]; + char *_is_x = is_x[i]; + + for( j = 0; j < dsize; j++ ) + { + if( !_is_x[j] ) + { + delta = _cost[j] - u_val - v[j].val; + if( min_delta > delta ) + { + min_delta = delta; + min_i = i; + min_j = j; + } + } + } + } + + enter_x->i = min_i; + enter_x->j = min_j; + + return min_delta; +} + +/****************************************************************************************\ +* icvNewSolution * +\****************************************************************************************/ +static bool +icvNewSolution( CvEMDState * state ) +{ + int i, j; + float min_val = CV_EMD_INF; + int steps; + CvNode2D head, *cur_x, *next_x, *leave_x = 0; + CvNode2D *enter_x = state->enter_x; + CvNode2D **loop = state->loop; + + /* enter the new basic variable */ + i = enter_x->i; + j = enter_x->j; + state->is_x[i][j] = 1; + enter_x->next[0] = state->rows_x[i]; + enter_x->next[1] = state->cols_x[j]; + enter_x->val = 0; + state->rows_x[i] = enter_x; + state->cols_x[j] = enter_x; + + /* find a chain reaction */ + steps = icvFindLoop( state ); + + if( steps == 0 ) + return false; + + /* find the largest value in the loop */ + for( i = 1; i < steps; i += 2 ) + { + float temp = loop[i]->val; + + if( min_val > temp ) + { + leave_x = loop[i]; + min_val = temp; + } + } + + /* update the loop */ + for( i = 0; i < steps; i += 2 ) + { + float temp0 = loop[i]->val + min_val; + float temp1 = loop[i + 1]->val - min_val; + + loop[i]->val = temp0; + loop[i + 1]->val = temp1; + } + + /* remove the leaving basic variable */ + i = leave_x->i; + j = leave_x->j; + state->is_x[i][j] = 0; + + head.next[0] = state->rows_x[i]; + cur_x = &head; + while( (next_x = cur_x->next[0]) != leave_x ) + { + cur_x = next_x; + assert( cur_x ); + } + cur_x->next[0] = next_x->next[0]; + state->rows_x[i] = head.next[0]; + + head.next[1] = state->cols_x[j]; + cur_x = &head; + while( (next_x = cur_x->next[1]) != leave_x ) + { + cur_x = next_x; + assert( cur_x ); + } + cur_x->next[1] = next_x->next[1]; + state->cols_x[j] = head.next[1]; + + /* set enter_x to be the new empty slot */ + state->enter_x = leave_x; + + return true; +} + + + +/****************************************************************************************\ +* icvFindLoop * +\****************************************************************************************/ +static int +icvFindLoop( CvEMDState * state ) +{ + int i, steps = 1; + CvNode2D *new_x; + CvNode2D **loop = state->loop; + CvNode2D *enter_x = state->enter_x, *_x = state->_x; + char *is_used = state->is_used; + + memset( is_used, 0, state->ssize + state->dsize ); + + new_x = loop[0] = enter_x; + is_used[enter_x - _x] = 1; + steps = 1; + + do + { + if( (steps & 1) == 1 ) + { + /* find an unused x in the row */ + new_x = state->rows_x[new_x->i]; + while( new_x != 0 && is_used[new_x - _x] ) + new_x = new_x->next[0]; + } + else + { + /* find an unused x in the column, or the entering x */ + new_x = state->cols_x[new_x->j]; + while( new_x != 0 && is_used[new_x - _x] && new_x != enter_x ) + new_x = new_x->next[1]; + if( new_x == enter_x ) + break; + } + + if( new_x != 0 ) /* found the next x */ + { + /* add x to the loop */ + loop[steps++] = new_x; + is_used[new_x - _x] = 1; + } + else /* didn't find the next x */ + { + /* backtrack */ + do + { + i = steps & 1; + new_x = loop[steps - 1]; + do + { + new_x = new_x->next[i]; + } + while( new_x != 0 && is_used[new_x - _x] ); + + if( new_x == 0 ) + { + is_used[loop[--steps] - _x] = 0; + } + } + while( new_x == 0 && steps > 0 ); + + is_used[loop[steps - 1] - _x] = 0; + loop[steps - 1] = new_x; + is_used[new_x - _x] = 1; + } + } + while( steps > 0 ); + + return steps; +} + + + +/****************************************************************************************\ +* icvRussel * +\****************************************************************************************/ +static void +icvRussel( CvEMDState * state ) +{ + int i, j, min_i = -1, min_j = -1; + float min_delta, diff; + CvNode1D u_head, *cur_u, *prev_u; + CvNode1D v_head, *cur_v, *prev_v; + CvNode1D *prev_u_min_i = 0, *prev_v_min_j = 0, *remember; + CvNode1D *u = state->u, *v = state->v; + int ssize = state->ssize, dsize = state->dsize; + float eps = CV_EMD_EPS * state->max_cost; + float **cost = state->cost; + float **delta = state->delta; + + /* initialize the rows list (ur), and the columns list (vr) */ + u_head.next = u; + for( i = 0; i < ssize; i++ ) + { + u[i].next = u + i + 1; + } + u[ssize - 1].next = 0; + + v_head.next = v; + for( i = 0; i < dsize; i++ ) + { + v[i].val = -CV_EMD_INF; + v[i].next = v + i + 1; + } + v[dsize - 1].next = 0; + + /* find the maximum row and column values (ur[i] and vr[j]) */ + for( i = 0; i < ssize; i++ ) + { + float u_val = -CV_EMD_INF; + float *cost_row = cost[i]; + + for( j = 0; j < dsize; j++ ) + { + float temp = cost_row[j]; + + if( u_val < temp ) + u_val = temp; + if( v[j].val < temp ) + v[j].val = temp; + } + u[i].val = u_val; + } + + /* compute the delta matrix */ + for( i = 0; i < ssize; i++ ) + { + float u_val = u[i].val; + float *delta_row = delta[i]; + float *cost_row = cost[i]; + + for( j = 0; j < dsize; j++ ) + { + delta_row[j] = cost_row[j] - u_val - v[j].val; + } + } + + /* find the basic variables */ + do + { + /* find the smallest delta[i][j] */ + min_i = -1; + min_delta = CV_EMD_INF; + prev_u = &u_head; + for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next ) + { + i = (int)(cur_u - u); + float *delta_row = delta[i]; + + prev_v = &v_head; + for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next ) + { + j = (int)(cur_v - v); + if( min_delta > delta_row[j] ) + { + min_delta = delta_row[j]; + min_i = i; + min_j = j; + prev_u_min_i = prev_u; + prev_v_min_j = prev_v; + } + prev_v = cur_v; + } + prev_u = cur_u; + } + + if( min_i < 0 ) + break; + + /* add x[min_i][min_j] to the basis, and adjust supplies and cost */ + remember = prev_u_min_i->next; + icvAddBasicVariable( state, min_i, min_j, prev_u_min_i, prev_v_min_j, &u_head ); + + /* update the necessary delta[][] */ + if( remember == prev_u_min_i->next ) /* line min_i was deleted */ + { + for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next ) + { + j = (int)(cur_v - v); + if( cur_v->val == cost[min_i][j] ) /* column j needs updating */ + { + float max_val = -CV_EMD_INF; + + /* find the new maximum value in the column */ + for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next ) + { + float temp = cost[cur_u - u][j]; + + if( max_val < temp ) + max_val = temp; + } + + /* if needed, adjust the relevant delta[*][j] */ + diff = max_val - cur_v->val; + cur_v->val = max_val; + if( fabs( diff ) < eps ) + { + for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next ) + delta[cur_u - u][j] += diff; + } + } + } + } + else /* column min_j was deleted */ + { + for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next ) + { + i = (int)(cur_u - u); + if( cur_u->val == cost[i][min_j] ) /* row i needs updating */ + { + float max_val = -CV_EMD_INF; + + /* find the new maximum value in the row */ + for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next ) + { + float temp = cost[i][cur_v - v]; + + if( max_val < temp ) + max_val = temp; + } + + /* if needed, adjust the relevant delta[i][*] */ + diff = max_val - cur_u->val; + cur_u->val = max_val; + + if( fabs( diff ) < eps ) + { + for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next ) + delta[i][cur_v - v] += diff; + } + } + } + } + } + while( u_head.next != 0 || v_head.next != 0 ); +} + + + +/****************************************************************************************\ +* icvAddBasicVariable * +\****************************************************************************************/ +static void +icvAddBasicVariable( CvEMDState * state, + int min_i, int min_j, + CvNode1D * prev_u_min_i, CvNode1D * prev_v_min_j, CvNode1D * u_head ) +{ + float temp; + CvNode2D *end_x = state->end_x; + + if( state->s[min_i] < state->d[min_j] + state->weight * CV_EMD_EPS ) + { /* supply exhausted */ + temp = state->s[min_i]; + state->s[min_i] = 0; + state->d[min_j] -= temp; + } + else /* demand exhausted */ + { + temp = state->d[min_j]; + state->d[min_j] = 0; + state->s[min_i] -= temp; + } + + /* x(min_i,min_j) is a basic variable */ + state->is_x[min_i][min_j] = 1; + + end_x->val = temp; + end_x->i = min_i; + end_x->j = min_j; + end_x->next[0] = state->rows_x[min_i]; + end_x->next[1] = state->cols_x[min_j]; + state->rows_x[min_i] = end_x; + state->cols_x[min_j] = end_x; + state->end_x = end_x + 1; + + /* delete supply row only if the empty, and if not last row */ + if( state->s[min_i] == 0 && u_head->next->next != 0 ) + prev_u_min_i->next = prev_u_min_i->next->next; /* remove row from list */ + else + prev_v_min_j->next = prev_v_min_j->next->next; /* remove column from list */ +} + + +/****************************************************************************************\ +* standard metrics * +\****************************************************************************************/ +static float +icvDistL1( const float *x, const float *y, void *user_param ) +{ + int i, dims = (int)(size_t)user_param; + double s = 0; + + for( i = 0; i < dims; i++ ) + { + double t = x[i] - y[i]; + + s += fabs( t ); + } + return (float)s; +} + +static float +icvDistL2( const float *x, const float *y, void *user_param ) +{ + int i, dims = (int)(size_t)user_param; + double s = 0; + + for( i = 0; i < dims; i++ ) + { + double t = x[i] - y[i]; + + s += t * t; + } + return cvSqrt( (float)s ); +} + +static float +icvDistC( const float *x, const float *y, void *user_param ) +{ + int i, dims = (int)(size_t)user_param; + double s = 0; + + for( i = 0; i < dims; i++ ) + { + double t = fabs( x[i] - y[i] ); + + if( s < t ) + s = t; + } + return (float)s; +} + + +float cv::EMD( InputArray _signature1, InputArray _signature2, + int distType, InputArray _cost, + float* lowerBound, OutputArray _flow ) +{ + Mat signature1 = _signature1.getMat(), signature2 = _signature2.getMat(); + Mat cost = _cost.getMat(), flow; + + CvMat _csignature1 = signature1; + CvMat _csignature2 = signature2; + CvMat _ccost = cost, _cflow; + if( _flow.needed() ) + { + _flow.create(signature1.rows, signature2.rows, CV_32F); + flow = _flow.getMat(); + _cflow = flow; + } + + return cvCalcEMD2( &_csignature1, &_csignature2, distType, 0, cost.empty() ? 0 : &_ccost, + _flow.needed() ? &_cflow : 0, lowerBound, 0 ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/featureselect.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/featureselect.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/featureselect.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/featureselect.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,242 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" +#include +#include + +namespace cv +{ + +template struct greaterThanPtr +{ + bool operator()(const T* a, const T* b) const { return *a > *b; } +}; + +} + +void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, + int maxCorners, double qualityLevel, double minDistance, + InputArray _mask, int blockSize, + bool useHarrisDetector, double harrisK ) +{ + Mat image = _image.getMat(), mask = _mask.getMat(); + + CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 ); + CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) ); + + Mat eig, tmp; + if( useHarrisDetector ) + cornerHarris( image, eig, blockSize, 3, harrisK ); + else + cornerMinEigenVal( image, eig, blockSize, 3 ); + + double maxVal = 0; + minMaxLoc( eig, 0, &maxVal, 0, 0, mask ); + threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO ); + dilate( eig, tmp, Mat()); + + Size imgsize = image.size(); + + vector tmpCorners; + + // collect list of pointers to features - put them into temporary image + for( int y = 1; y < imgsize.height - 1; y++ ) + { + const float* eig_data = (const float*)eig.ptr(y); + const float* tmp_data = (const float*)tmp.ptr(y); + const uchar* mask_data = mask.data ? mask.ptr(y) : 0; + + for( int x = 1; x < imgsize.width - 1; x++ ) + { + float val = eig_data[x]; + if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) ) + tmpCorners.push_back(eig_data + x); + } + } + + sort( tmpCorners, greaterThanPtr() ); + vector corners; + size_t i, j, total = tmpCorners.size(), ncorners = 0; + + if(minDistance >= 1) + { + // Partition the image into larger grids + int w = image.cols; + int h = image.rows; + + const int cell_size = cvRound(minDistance); + const int grid_width = (w + cell_size - 1) / cell_size; + const int grid_height = (h + cell_size - 1) / cell_size; + + std::vector > grid(grid_width*grid_height); + + minDistance *= minDistance; + + for( i = 0; i < total; i++ ) + { + int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); + int y = (int)(ofs / eig.step); + int x = (int)((ofs - y*eig.step)/sizeof(float)); + + bool good = true; + + int x_cell = x / cell_size; + int y_cell = y / cell_size; + + int x1 = x_cell - 1; + int y1 = y_cell - 1; + int x2 = x_cell + 1; + int y2 = y_cell + 1; + + // boundary check + x1 = std::max(0, x1); + y1 = std::max(0, y1); + x2 = std::min(grid_width-1, x2); + y2 = std::min(grid_height-1, y2); + + for( int yy = y1; yy <= y2; yy++ ) + { + for( int xx = x1; xx <= x2; xx++ ) + { + vector &m = grid[yy*grid_width + xx]; + + if( m.size() ) + { + for(j = 0; j < m.size(); j++) + { + float dx = x - m[j].x; + float dy = y - m[j].y; + + if( dx*dx + dy*dy < minDistance ) + { + good = false; + goto break_out; + } + } + } + } + } + + break_out: + + if(good) + { + // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n", + // i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c); + grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); + + corners.push_back(Point2f((float)x, (float)y)); + ++ncorners; + + if( maxCorners > 0 && (int)ncorners == maxCorners ) + break; + } + } + } + else + { + for( i = 0; i < total; i++ ) + { + int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); + int y = (int)(ofs / eig.step); + int x = (int)((ofs - y*eig.step)/sizeof(float)); + + corners.push_back(Point2f((float)x, (float)y)); + ++ncorners; + if( maxCorners > 0 && (int)ncorners == maxCorners ) + break; + } + } + + Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F); + + /* + for( i = 0; i < total; i++ ) + { + int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); + int y = (int)(ofs / eig.step); + int x = (int)((ofs - y*eig.step)/sizeof(float)); + + if( minDistance > 0 ) + { + for( j = 0; j < ncorners; j++ ) + { + float dx = x - corners[j].x; + float dy = y - corners[j].y; + if( dx*dx + dy*dy < minDistance ) + break; + } + if( j < ncorners ) + continue; + } + + corners.push_back(Point2f((float)x, (float)y)); + ++ncorners; + if( maxCorners > 0 && (int)ncorners == maxCorners ) + break; + } +*/ +} + +CV_IMPL void +cvGoodFeaturesToTrack( const void* _image, void*, void*, + CvPoint2D32f* _corners, int *_corner_count, + double quality_level, double min_distance, + const void* _maskImage, int block_size, + int use_harris, double harris_k ) +{ + cv::Mat image = cv::cvarrToMat(_image), mask; + cv::vector corners; + + if( _maskImage ) + mask = cv::cvarrToMat(_maskImage); + + CV_Assert( _corners && _corner_count ); + cv::goodFeaturesToTrack( image, corners, *_corner_count, quality_level, + min_distance, mask, block_size, use_harris != 0, harris_k ); + + size_t i, ncorners = corners.size(); + for( i = 0; i < ncorners; i++ ) + _corners[i] = corners[i]; + *_corner_count = (int)ncorners; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/filter.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/filter.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/filter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/filter.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3306 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/****************************************************************************************\ + Base Image Filter +\****************************************************************************************/ + +/* + Various border types, image boundaries are denoted with '|' + + * BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh + * BORDER_REFLECT: fedcba|abcdefgh|hgfedcb + * BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba + * BORDER_WRAP: cdefgh|abcdefgh|abcdefg + * BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i' + */ +int cv::borderInterpolate( int p, int len, int borderType ) +{ + if( (unsigned)p < (unsigned)len ) + ; + else if( borderType == BORDER_REPLICATE ) + p = p < 0 ? 0 : len - 1; + else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 ) + { + int delta = borderType == BORDER_REFLECT_101; + if( len == 1 ) + return 0; + do + { + if( p < 0 ) + p = -p - 1 + delta; + else + p = len - 1 - (p - len) - delta; + } + while( (unsigned)p >= (unsigned)len ); + } + else if( borderType == BORDER_WRAP ) + { + if( p < 0 ) + p -= ((p-len+1)/len)*len; + if( p >= len ) + p %= len; + } + else if( borderType == BORDER_CONSTANT ) + p = -1; + else + CV_Error( CV_StsBadArg, "Unknown/unsupported border type" ); + return p; +} + + +namespace cv +{ + +BaseRowFilter::BaseRowFilter() { ksize = anchor = -1; } +BaseRowFilter::~BaseRowFilter() {} + +BaseColumnFilter::BaseColumnFilter() { ksize = anchor = -1; } +BaseColumnFilter::~BaseColumnFilter() {} +void BaseColumnFilter::reset() {} + +BaseFilter::BaseFilter() { ksize = Size(-1,-1); anchor = Point(-1,-1); } +BaseFilter::~BaseFilter() {} +void BaseFilter::reset() {} + +FilterEngine::FilterEngine() +{ + srcType = dstType = bufType = -1; + rowBorderType = columnBorderType = BORDER_REPLICATE; + bufStep = startY = startY0 = endY = rowCount = dstY = 0; + maxWidth = 0; + + wholeSize = Size(-1,-1); +} + + +FilterEngine::FilterEngine( const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int _srcType, int _dstType, int _bufType, + int _rowBorderType, int _columnBorderType, + const Scalar& _borderValue ) +{ + init(_filter2D, _rowFilter, _columnFilter, _srcType, _dstType, _bufType, + _rowBorderType, _columnBorderType, _borderValue); +} + +FilterEngine::~FilterEngine() +{ +} + + +void FilterEngine::init( const Ptr& _filter2D, + const Ptr& _rowFilter, + const Ptr& _columnFilter, + int _srcType, int _dstType, int _bufType, + int _rowBorderType, int _columnBorderType, + const Scalar& _borderValue ) +{ + _srcType = CV_MAT_TYPE(_srcType); + _bufType = CV_MAT_TYPE(_bufType); + _dstType = CV_MAT_TYPE(_dstType); + + srcType = _srcType; + int srcElemSize = (int)getElemSize(srcType); + dstType = _dstType; + bufType = _bufType; + + filter2D = _filter2D; + rowFilter = _rowFilter; + columnFilter = _columnFilter; + + if( _columnBorderType < 0 ) + _columnBorderType = _rowBorderType; + + rowBorderType = _rowBorderType; + columnBorderType = _columnBorderType; + + CV_Assert( columnBorderType != BORDER_WRAP ); + + if( isSeparable() ) + { + CV_Assert( !rowFilter.empty() && !columnFilter.empty() ); + ksize = Size(rowFilter->ksize, columnFilter->ksize); + anchor = Point(rowFilter->anchor, columnFilter->anchor); + } + else + { + CV_Assert( bufType == srcType ); + ksize = filter2D->ksize; + anchor = filter2D->anchor; + } + + CV_Assert( 0 <= anchor.x && anchor.x < ksize.width && + 0 <= anchor.y && anchor.y < ksize.height ); + + borderElemSize = srcElemSize/(CV_MAT_DEPTH(srcType) >= CV_32S ? sizeof(int) : 1); + int borderLength = std::max(ksize.width - 1, 1); + borderTab.resize(borderLength*borderElemSize); + + maxWidth = bufStep = 0; + constBorderRow.clear(); + + if( rowBorderType == BORDER_CONSTANT || columnBorderType == BORDER_CONSTANT ) + { + constBorderValue.resize(srcElemSize*borderLength); + int srcType1 = CV_MAKETYPE(CV_MAT_DEPTH(srcType), MIN(CV_MAT_CN(srcType), 4)); + scalarToRawData(_borderValue, &constBorderValue[0], srcType1, + borderLength*CV_MAT_CN(srcType)); + } + + wholeSize = Size(-1,-1); +} + +static const int VEC_ALIGN = CV_MALLOC_ALIGN; + +int FilterEngine::start(Size _wholeSize, Rect _roi, int _maxBufRows) +{ + int i, j; + + wholeSize = _wholeSize; + roi = _roi; + CV_Assert( roi.x >= 0 && roi.y >= 0 && roi.width >= 0 && roi.height >= 0 && + roi.x + roi.width <= wholeSize.width && + roi.y + roi.height <= wholeSize.height ); + + int esz = (int)getElemSize(srcType); + int bufElemSize = (int)getElemSize(bufType); + const uchar* constVal = !constBorderValue.empty() ? &constBorderValue[0] : 0; + + if( _maxBufRows < 0 ) + _maxBufRows = ksize.height + 3; + _maxBufRows = std::max(_maxBufRows, std::max(anchor.y, ksize.height-anchor.y-1)*2+1); + + if( maxWidth < roi.width || _maxBufRows != (int)rows.size() ) + { + rows.resize(_maxBufRows); + maxWidth = std::max(maxWidth, roi.width); + int cn = CV_MAT_CN(srcType); + srcRow.resize(esz*(maxWidth + ksize.width - 1)); + if( columnBorderType == BORDER_CONSTANT ) + { + constBorderRow.resize(getElemSize(bufType)*(maxWidth + ksize.width - 1 + VEC_ALIGN)); + uchar *dst = alignPtr(&constBorderRow[0], VEC_ALIGN), *tdst; + int n = (int)constBorderValue.size(), N; + N = (maxWidth + ksize.width - 1)*esz; + tdst = isSeparable() ? &srcRow[0] : dst; + + for( i = 0; i < N; i += n ) + { + n = std::min( n, N - i ); + for(j = 0; j < n; j++) + tdst[i+j] = constVal[j]; + } + + if( isSeparable() ) + (*rowFilter)(&srcRow[0], dst, maxWidth, cn); + } + + int maxBufStep = bufElemSize*(int)alignSize(maxWidth + + (!isSeparable() ? ksize.width - 1 : 0),VEC_ALIGN); + ringBuf.resize(maxBufStep*rows.size()+VEC_ALIGN); + } + + // adjust bufstep so that the used part of the ring buffer stays compact in memory + bufStep = bufElemSize*(int)alignSize(roi.width + (!isSeparable() ? ksize.width - 1 : 0),16); + + dx1 = std::max(anchor.x - roi.x, 0); + dx2 = std::max(ksize.width - anchor.x - 1 + roi.x + roi.width - wholeSize.width, 0); + + // recompute border tables + if( dx1 > 0 || dx2 > 0 ) + { + if( rowBorderType == BORDER_CONSTANT ) + { + int nr = isSeparable() ? 1 : (int)rows.size(); + for( i = 0; i < nr; i++ ) + { + uchar* dst = isSeparable() ? &srcRow[0] : alignPtr(&ringBuf[0],VEC_ALIGN) + bufStep*i; + memcpy( dst, constVal, dx1*esz ); + memcpy( dst + (roi.width + ksize.width - 1 - dx2)*esz, constVal, dx2*esz ); + } + } + else + { + int xofs1 = std::min(roi.x, anchor.x) - roi.x; + + int btab_esz = borderElemSize, wholeWidth = wholeSize.width; + int* btab = (int*)&borderTab[0]; + + for( i = 0; i < dx1; i++ ) + { + int p0 = (borderInterpolate(i-dx1, wholeWidth, rowBorderType) + xofs1)*btab_esz; + for( j = 0; j < btab_esz; j++ ) + btab[i*btab_esz + j] = p0 + j; + } + + for( i = 0; i < dx2; i++ ) + { + int p0 = (borderInterpolate(wholeWidth + i, wholeWidth, rowBorderType) + xofs1)*btab_esz; + for( j = 0; j < btab_esz; j++ ) + btab[(i + dx1)*btab_esz + j] = p0 + j; + } + } + } + + rowCount = dstY = 0; + startY = startY0 = std::max(roi.y - anchor.y, 0); + endY = std::min(roi.y + roi.height + ksize.height - anchor.y - 1, wholeSize.height); + if( !columnFilter.empty() ) + columnFilter->reset(); + if( !filter2D.empty() ) + filter2D->reset(); + + return startY; +} + + +int FilterEngine::start(const Mat& src, const Rect& _srcRoi, + bool isolated, int maxBufRows) +{ + Rect srcRoi = _srcRoi; + + if( srcRoi == Rect(0,0,-1,-1) ) + srcRoi = Rect(0,0,src.cols,src.rows); + + CV_Assert( srcRoi.x >= 0 && srcRoi.y >= 0 && + srcRoi.width >= 0 && srcRoi.height >= 0 && + srcRoi.x + srcRoi.width <= src.cols && + srcRoi.y + srcRoi.height <= src.rows ); + + Point ofs; + Size wsz(src.cols, src.rows); + if( !isolated ) + src.locateROI( wsz, ofs ); + start( wsz, srcRoi + ofs, maxBufRows ); + + return startY - ofs.y; +} + + +int FilterEngine::remainingInputRows() const +{ + return endY - startY - rowCount; +} + +int FilterEngine::remainingOutputRows() const +{ + return roi.height - dstY; +} + +int FilterEngine::proceed( const uchar* src, int srcstep, int count, + uchar* dst, int dststep ) +{ + CV_Assert( wholeSize.width > 0 && wholeSize.height > 0 ); + + const int *btab = &borderTab[0]; + int esz = (int)getElemSize(srcType), btab_esz = borderElemSize; + uchar** brows = &rows[0]; + int bufRows = (int)rows.size(); + int cn = CV_MAT_CN(bufType); + int width = roi.width, kwidth = ksize.width; + int kheight = ksize.height, ay = anchor.y; + int _dx1 = dx1, _dx2 = dx2; + int width1 = roi.width + kwidth - 1; + int xofs1 = std::min(roi.x, anchor.x); + bool isSep = isSeparable(); + bool makeBorder = (_dx1 > 0 || _dx2 > 0) && rowBorderType != BORDER_CONSTANT; + int dy = 0, i = 0; + + src -= xofs1*esz; + count = std::min(count, remainingInputRows()); + + CV_Assert( src && dst && count > 0 ); + + for(;; dst += dststep*i, dy += i) + { + int dcount = bufRows - ay - startY - rowCount + roi.y; + dcount = dcount > 0 ? dcount : bufRows - kheight + 1; + dcount = std::min(dcount, count); + count -= dcount; + for( ; dcount-- > 0; src += srcstep ) + { + int bi = (startY - startY0 + rowCount) % bufRows; + uchar* brow = alignPtr(&ringBuf[0], VEC_ALIGN) + bi*bufStep; + uchar* row = isSep ? &srcRow[0] : brow; + + if( ++rowCount > bufRows ) + { + --rowCount; + ++startY; + } + + memcpy( row + _dx1*esz, src, (width1 - _dx2 - _dx1)*esz ); + + if( makeBorder ) + { + if( btab_esz*(int)sizeof(int) == esz ) + { + const int* isrc = (const int*)src; + int* irow = (int*)row; + + for( i = 0; i < _dx1*btab_esz; i++ ) + irow[i] = isrc[btab[i]]; + for( i = 0; i < _dx2*btab_esz; i++ ) + irow[i + (width1 - _dx2)*btab_esz] = isrc[btab[i+_dx1*btab_esz]]; + } + else + { + for( i = 0; i < _dx1*esz; i++ ) + row[i] = src[btab[i]]; + for( i = 0; i < _dx2*esz; i++ ) + row[i + (width1 - _dx2)*esz] = src[btab[i+_dx1*esz]]; + } + } + + if( isSep ) + (*rowFilter)(row, brow, width, CV_MAT_CN(srcType)); + } + + int max_i = std::min(bufRows, roi.height - (dstY + dy) + (kheight - 1)); + for( i = 0; i < max_i; i++ ) + { + int srcY = borderInterpolate(dstY + dy + i + roi.y - ay, + wholeSize.height, columnBorderType); + if( srcY < 0 ) // can happen only with constant border type + brows[i] = alignPtr(&constBorderRow[0], VEC_ALIGN); + else + { + CV_Assert( srcY >= startY ); + if( srcY >= startY + rowCount ) + break; + int bi = (srcY - startY0) % bufRows; + brows[i] = alignPtr(&ringBuf[0], VEC_ALIGN) + bi*bufStep; + } + } + if( i < kheight ) + break; + i -= kheight - 1; + if( isSeparable() ) + (*columnFilter)((const uchar**)brows, dst, dststep, i, roi.width*cn); + else + (*filter2D)((const uchar**)brows, dst, dststep, i, roi.width, cn); + } + + dstY += dy; + CV_Assert( dstY <= roi.height ); + return dy; +} + + +void FilterEngine::apply(const Mat& src, Mat& dst, + const Rect& _srcRoi, Point dstOfs, bool isolated) +{ + CV_Assert( src.type() == srcType && dst.type() == dstType ); + + Rect srcRoi = _srcRoi; + if( srcRoi == Rect(0,0,-1,-1) ) + srcRoi = Rect(0,0,src.cols,src.rows); + + if( srcRoi.area() == 0 ) + return; + + CV_Assert( dstOfs.x >= 0 && dstOfs.y >= 0 && + dstOfs.x + srcRoi.width <= dst.cols && + dstOfs.y + srcRoi.height <= dst.rows ); + + int y = start(src, srcRoi, isolated); + proceed( src.data + y*src.step, (int)src.step, endY - startY, + dst.data + dstOfs.y*dst.step + dstOfs.x*dst.elemSize(), (int)dst.step ); +} + +} + +/****************************************************************************************\ +* Separable linear filter * +\****************************************************************************************/ + +int cv::getKernelType(InputArray filter_kernel, Point anchor) +{ + Mat _kernel = filter_kernel.getMat(); + CV_Assert( _kernel.channels() == 1 ); + int i, sz = _kernel.rows*_kernel.cols; + + Mat kernel; + _kernel.convertTo(kernel, CV_64F); + + const double* coeffs = (double*)kernel.data; + double sum = 0; + int type = KERNEL_SMOOTH + KERNEL_INTEGER; + if( (_kernel.rows == 1 || _kernel.cols == 1) && + anchor.x*2 + 1 == _kernel.cols && + anchor.y*2 + 1 == _kernel.rows ) + type |= (KERNEL_SYMMETRICAL + KERNEL_ASYMMETRICAL); + + for( i = 0; i < sz; i++ ) + { + double a = coeffs[i], b = coeffs[sz - i - 1]; + if( a != b ) + type &= ~KERNEL_SYMMETRICAL; + if( a != -b ) + type &= ~KERNEL_ASYMMETRICAL; + if( a < 0 ) + type &= ~KERNEL_SMOOTH; + if( a != saturate_cast(a) ) + type &= ~KERNEL_INTEGER; + sum += a; + } + + if( fabs(sum - 1) > FLT_EPSILON*(fabs(sum) + 1) ) + type &= ~KERNEL_SMOOTH; + return type; +} + + +namespace cv +{ + +struct RowNoVec +{ + RowNoVec() {} + RowNoVec(const Mat&) {} + int operator()(const uchar*, uchar*, int, int) const { return 0; } +}; + +struct ColumnNoVec +{ + ColumnNoVec() {} + ColumnNoVec(const Mat&, int, int, double) {} + int operator()(const uchar**, uchar*, int) const { return 0; } +}; + +struct SymmRowSmallNoVec +{ + SymmRowSmallNoVec() {} + SymmRowSmallNoVec(const Mat&, int) {} + int operator()(const uchar*, uchar*, int, int) const { return 0; } +}; + +struct SymmColumnSmallNoVec +{ + SymmColumnSmallNoVec() {} + SymmColumnSmallNoVec(const Mat&, int, int, double) {} + int operator()(const uchar**, uchar*, int) const { return 0; } +}; + +struct FilterNoVec +{ + FilterNoVec() {} + FilterNoVec(const Mat&, int, double) {} + int operator()(const uchar**, uchar*, int) const { return 0; } +}; + + +#if CV_SSE2 + +///////////////////////////////////// 8u-16s & 8u-8u ////////////////////////////////// + +struct RowVec_8u32s +{ + RowVec_8u32s() { smallValues = false; } + RowVec_8u32s( const Mat& _kernel ) + { + kernel = _kernel; + smallValues = true; + int k, ksize = kernel.rows + kernel.cols - 1; + for( k = 0; k < ksize; k++ ) + { + int v = ((const int*)kernel.data)[k]; + if( v < SHRT_MIN || v > SHRT_MAX ) + { + smallValues = false; + break; + } + } + } + + int operator()(const uchar* _src, uchar* _dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int i = 0, k, _ksize = kernel.rows + kernel.cols - 1; + int* dst = (int*)_dst; + const int* _kx = (const int*)kernel.data; + width *= cn; + + if( smallValues ) + { + for( ; i <= width - 16; i += 16 ) + { + const uchar* src = _src + i; + __m128i f, z = _mm_setzero_si128(), s0 = z, s1 = z, s2 = z, s3 = z; + __m128i x0, x1, x2, x3; + + for( k = 0; k < _ksize; k++, src += cn ) + { + f = _mm_cvtsi32_si128(_kx[k]); + f = _mm_shuffle_epi32(f, 0); + f = _mm_packs_epi32(f, f); + + x0 = _mm_loadu_si128((const __m128i*)src); + x2 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + x1 = _mm_mulhi_epi16(x0, f); + x3 = _mm_mulhi_epi16(x2, f); + x0 = _mm_mullo_epi16(x0, f); + x2 = _mm_mullo_epi16(x2, f); + + s0 = _mm_add_epi32(s0, _mm_unpacklo_epi16(x0, x1)); + s1 = _mm_add_epi32(s1, _mm_unpackhi_epi16(x0, x1)); + s2 = _mm_add_epi32(s2, _mm_unpacklo_epi16(x2, x3)); + s3 = _mm_add_epi32(s3, _mm_unpackhi_epi16(x2, x3)); + } + + _mm_store_si128((__m128i*)(dst + i), s0); + _mm_store_si128((__m128i*)(dst + i + 4), s1); + _mm_store_si128((__m128i*)(dst + i + 8), s2); + _mm_store_si128((__m128i*)(dst + i + 12), s3); + } + + for( ; i <= width - 4; i += 4 ) + { + const uchar* src = _src + i; + __m128i f, z = _mm_setzero_si128(), s0 = z, x0, x1; + + for( k = 0; k < _ksize; k++, src += cn ) + { + f = _mm_cvtsi32_si128(_kx[k]); + f = _mm_shuffle_epi32(f, 0); + f = _mm_packs_epi32(f, f); + + x0 = _mm_cvtsi32_si128(*(const int*)src); + x0 = _mm_unpacklo_epi8(x0, z); + x1 = _mm_mulhi_epi16(x0, f); + x0 = _mm_mullo_epi16(x0, f); + s0 = _mm_add_epi32(s0, _mm_unpacklo_epi16(x0, x1)); + } + _mm_store_si128((__m128i*)(dst + i), s0); + } + } + return i; + } + + Mat kernel; + bool smallValues; +}; + + +struct SymmRowSmallVec_8u32s +{ + SymmRowSmallVec_8u32s() { smallValues = false; } + SymmRowSmallVec_8u32s( const Mat& _kernel, int _symmetryType ) + { + kernel = _kernel; + symmetryType = _symmetryType; + smallValues = true; + int k, ksize = kernel.rows + kernel.cols - 1; + for( k = 0; k < ksize; k++ ) + { + int v = ((const int*)kernel.data)[k]; + if( v < SHRT_MIN || v > SHRT_MAX ) + { + smallValues = false; + break; + } + } + } + + int operator()(const uchar* src, uchar* _dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int i = 0, j, k, _ksize = kernel.rows + kernel.cols - 1; + int* dst = (int*)_dst; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const int* kx = (const int*)kernel.data + _ksize/2; + if( !smallValues ) + return 0; + + src += (_ksize/2)*cn; + width *= cn; + + __m128i z = _mm_setzero_si128(); + if( symmetrical ) + { + if( _ksize == 1 ) + return 0; + if( _ksize == 3 ) + { + if( kx[0] == 2 && kx[1] == 1 ) + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_si128((__m128i*)(src - cn)); + x1 = _mm_loadu_si128((__m128i*)src); + x2 = _mm_loadu_si128((__m128i*)(src + cn)); + y0 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + y1 = _mm_unpackhi_epi8(x1, z); + x1 = _mm_unpacklo_epi8(x1, z); + y2 = _mm_unpackhi_epi8(x2, z); + x2 = _mm_unpacklo_epi8(x2, z); + x0 = _mm_add_epi16(x0, _mm_add_epi16(_mm_add_epi16(x1, x1), x2)); + y0 = _mm_add_epi16(y0, _mm_add_epi16(_mm_add_epi16(y1, y1), y2)); + _mm_store_si128((__m128i*)(dst + i), _mm_unpacklo_epi16(x0, z)); + _mm_store_si128((__m128i*)(dst + i + 4), _mm_unpackhi_epi16(x0, z)); + _mm_store_si128((__m128i*)(dst + i + 8), _mm_unpacklo_epi16(y0, z)); + _mm_store_si128((__m128i*)(dst + i + 12), _mm_unpackhi_epi16(y0, z)); + } + else if( kx[0] == -2 && kx[1] == 1 ) + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_si128((__m128i*)(src - cn)); + x1 = _mm_loadu_si128((__m128i*)src); + x2 = _mm_loadu_si128((__m128i*)(src + cn)); + y0 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + y1 = _mm_unpackhi_epi8(x1, z); + x1 = _mm_unpacklo_epi8(x1, z); + y2 = _mm_unpackhi_epi8(x2, z); + x2 = _mm_unpacklo_epi8(x2, z); + x0 = _mm_add_epi16(x0, _mm_sub_epi16(x2, _mm_add_epi16(x1, x1))); + y0 = _mm_add_epi16(y0, _mm_sub_epi16(y2, _mm_add_epi16(y1, y1))); + _mm_store_si128((__m128i*)(dst + i), _mm_srai_epi32(_mm_unpacklo_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 4), _mm_srai_epi32(_mm_unpackhi_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 8), _mm_srai_epi32(_mm_unpacklo_epi16(y0, y0),16)); + _mm_store_si128((__m128i*)(dst + i + 12), _mm_srai_epi32(_mm_unpackhi_epi16(y0, y0),16)); + } + else + { + __m128i k0 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[0]), 0), + k1 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[1]), 0); + k0 = _mm_packs_epi32(k0, k0); + k1 = _mm_packs_epi32(k1, k1); + + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, t0, t1, z0, z1, z2, z3; + x0 = _mm_loadu_si128((__m128i*)(src - cn)); + x1 = _mm_loadu_si128((__m128i*)src); + x2 = _mm_loadu_si128((__m128i*)(src + cn)); + y0 = _mm_add_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x2, z)); + x0 = _mm_add_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x2, z)); + y1 = _mm_unpackhi_epi8(x1, z); + x1 = _mm_unpacklo_epi8(x1, z); + + t1 = _mm_mulhi_epi16(x1, k0); + t0 = _mm_mullo_epi16(x1, k0); + x2 = _mm_mulhi_epi16(x0, k1); + x0 = _mm_mullo_epi16(x0, k1); + z0 = _mm_unpacklo_epi16(t0, t1); + z1 = _mm_unpackhi_epi16(t0, t1); + z0 = _mm_add_epi32(z0, _mm_unpacklo_epi16(x0, x2)); + z1 = _mm_add_epi32(z1, _mm_unpackhi_epi16(x0, x2)); + + t1 = _mm_mulhi_epi16(y1, k0); + t0 = _mm_mullo_epi16(y1, k0); + y1 = _mm_mulhi_epi16(y0, k1); + y0 = _mm_mullo_epi16(y0, k1); + z2 = _mm_unpacklo_epi16(t0, t1); + z3 = _mm_unpackhi_epi16(t0, t1); + z2 = _mm_add_epi32(z2, _mm_unpacklo_epi16(y0, y1)); + z3 = _mm_add_epi32(z3, _mm_unpackhi_epi16(y0, y1)); + _mm_store_si128((__m128i*)(dst + i), z0); + _mm_store_si128((__m128i*)(dst + i + 4), z1); + _mm_store_si128((__m128i*)(dst + i + 8), z2); + _mm_store_si128((__m128i*)(dst + i + 12), z3); + } + } + } + else if( _ksize == 5 ) + { + if( kx[0] == -2 && kx[1] == 0 && kx[2] == 1 ) + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_si128((__m128i*)(src - cn*2)); + x1 = _mm_loadu_si128((__m128i*)src); + x2 = _mm_loadu_si128((__m128i*)(src + cn*2)); + y0 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + y1 = _mm_unpackhi_epi8(x1, z); + x1 = _mm_unpacklo_epi8(x1, z); + y2 = _mm_unpackhi_epi8(x2, z); + x2 = _mm_unpacklo_epi8(x2, z); + x0 = _mm_add_epi16(x0, _mm_sub_epi16(x2, _mm_add_epi16(x1, x1))); + y0 = _mm_add_epi16(y0, _mm_sub_epi16(y2, _mm_add_epi16(y1, y1))); + _mm_store_si128((__m128i*)(dst + i), _mm_srai_epi32(_mm_unpacklo_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 4), _mm_srai_epi32(_mm_unpackhi_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 8), _mm_srai_epi32(_mm_unpacklo_epi16(y0, y0),16)); + _mm_store_si128((__m128i*)(dst + i + 12), _mm_srai_epi32(_mm_unpackhi_epi16(y0, y0),16)); + } + else + { + __m128i k0 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[0]), 0), + k1 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[1]), 0), + k2 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[2]), 0); + k0 = _mm_packs_epi32(k0, k0); + k1 = _mm_packs_epi32(k1, k1); + k2 = _mm_packs_epi32(k2, k2); + + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, t0, t1, z0, z1, z2, z3; + x0 = _mm_loadu_si128((__m128i*)(src - cn)); + x1 = _mm_loadu_si128((__m128i*)src); + x2 = _mm_loadu_si128((__m128i*)(src + cn)); + y0 = _mm_add_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x2, z)); + x0 = _mm_add_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x2, z)); + y1 = _mm_unpackhi_epi8(x1, z); + x1 = _mm_unpacklo_epi8(x1, z); + + t1 = _mm_mulhi_epi16(x1, k0); + t0 = _mm_mullo_epi16(x1, k0); + x2 = _mm_mulhi_epi16(x0, k1); + x0 = _mm_mullo_epi16(x0, k1); + z0 = _mm_unpacklo_epi16(t0, t1); + z1 = _mm_unpackhi_epi16(t0, t1); + z0 = _mm_add_epi32(z0, _mm_unpacklo_epi16(x0, x2)); + z1 = _mm_add_epi32(z1, _mm_unpackhi_epi16(x0, x2)); + + t1 = _mm_mulhi_epi16(y1, k0); + t0 = _mm_mullo_epi16(y1, k0); + y1 = _mm_mulhi_epi16(y0, k1); + y0 = _mm_mullo_epi16(y0, k1); + z2 = _mm_unpacklo_epi16(t0, t1); + z3 = _mm_unpackhi_epi16(t0, t1); + z2 = _mm_add_epi32(z2, _mm_unpacklo_epi16(y0, y1)); + z3 = _mm_add_epi32(z3, _mm_unpackhi_epi16(y0, y1)); + + x0 = _mm_loadu_si128((__m128i*)(src - cn*2)); + x1 = _mm_loadu_si128((__m128i*)(src + cn*2)); + y1 = _mm_add_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x1, z)); + y0 = _mm_add_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x1, z)); + + t1 = _mm_mulhi_epi16(y0, k2); + t0 = _mm_mullo_epi16(y0, k2); + y0 = _mm_mullo_epi16(y1, k2); + y1 = _mm_mulhi_epi16(y1, k2); + z0 = _mm_add_epi32(z0, _mm_unpacklo_epi16(t0, t1)); + z1 = _mm_add_epi32(z1, _mm_unpackhi_epi16(t0, t1)); + z2 = _mm_add_epi32(z2, _mm_unpacklo_epi16(y0, y1)); + z3 = _mm_add_epi32(z3, _mm_unpackhi_epi16(y0, y1)); + + _mm_store_si128((__m128i*)(dst + i), z0); + _mm_store_si128((__m128i*)(dst + i + 4), z1); + _mm_store_si128((__m128i*)(dst + i + 8), z2); + _mm_store_si128((__m128i*)(dst + i + 12), z3); + } + } + } + } + else + { + if( _ksize == 3 ) + { + if( kx[0] == 0 && kx[1] == 1 ) + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, y0; + x0 = _mm_loadu_si128((__m128i*)(src + cn)); + x1 = _mm_loadu_si128((__m128i*)(src - cn)); + y0 = _mm_sub_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x1, z)); + x0 = _mm_sub_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x1, z)); + _mm_store_si128((__m128i*)(dst + i), _mm_srai_epi32(_mm_unpacklo_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 4), _mm_srai_epi32(_mm_unpackhi_epi16(x0, x0),16)); + _mm_store_si128((__m128i*)(dst + i + 8), _mm_srai_epi32(_mm_unpacklo_epi16(y0, y0),16)); + _mm_store_si128((__m128i*)(dst + i + 12), _mm_srai_epi32(_mm_unpackhi_epi16(y0, y0),16)); + } + else + { + __m128i k1 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[1]), 0); + k1 = _mm_packs_epi32(k1, k1); + + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, y0, y1, z0, z1, z2, z3; + x0 = _mm_loadu_si128((__m128i*)(src + cn)); + x1 = _mm_loadu_si128((__m128i*)(src - cn)); + y0 = _mm_sub_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x1, z)); + x0 = _mm_sub_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x1, z)); + + x1 = _mm_mulhi_epi16(x0, k1); + x0 = _mm_mullo_epi16(x0, k1); + z0 = _mm_unpacklo_epi16(x0, x1); + z1 = _mm_unpackhi_epi16(x0, x1); + + y1 = _mm_mulhi_epi16(y0, k1); + y0 = _mm_mullo_epi16(y0, k1); + z2 = _mm_unpacklo_epi16(y0, y1); + z3 = _mm_unpackhi_epi16(y0, y1); + _mm_store_si128((__m128i*)(dst + i), z0); + _mm_store_si128((__m128i*)(dst + i + 4), z1); + _mm_store_si128((__m128i*)(dst + i + 8), z2); + _mm_store_si128((__m128i*)(dst + i + 12), z3); + } + } + } + else if( _ksize == 5 ) + { + __m128i k0 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[0]), 0), + k1 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[1]), 0), + k2 = _mm_shuffle_epi32(_mm_cvtsi32_si128(kx[2]), 0); + k0 = _mm_packs_epi32(k0, k0); + k1 = _mm_packs_epi32(k1, k1); + k2 = _mm_packs_epi32(k2, k2); + + for( ; i <= width - 16; i += 16, src += 16 ) + { + __m128i x0, x1, x2, y0, y1, t0, t1, z0, z1, z2, z3; + x0 = _mm_loadu_si128((__m128i*)(src + cn)); + x2 = _mm_loadu_si128((__m128i*)(src - cn)); + y0 = _mm_sub_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x2, z)); + x0 = _mm_sub_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x2, z)); + + x2 = _mm_mulhi_epi16(x0, k1); + x0 = _mm_mullo_epi16(x0, k1); + z0 = _mm_unpacklo_epi16(x0, x2); + z1 = _mm_unpackhi_epi16(x0, x2); + y1 = _mm_mulhi_epi16(y0, k1); + y0 = _mm_mullo_epi16(y0, k1); + z2 = _mm_unpacklo_epi16(y0, y1); + z3 = _mm_unpackhi_epi16(y0, y1); + + x0 = _mm_loadu_si128((__m128i*)(src + cn*2)); + x1 = _mm_loadu_si128((__m128i*)(src - cn*2)); + y1 = _mm_sub_epi16(_mm_unpackhi_epi8(x0, z), _mm_unpackhi_epi8(x1, z)); + y0 = _mm_sub_epi16(_mm_unpacklo_epi8(x0, z), _mm_unpacklo_epi8(x1, z)); + + t1 = _mm_mulhi_epi16(y0, k2); + t0 = _mm_mullo_epi16(y0, k2); + y0 = _mm_mullo_epi16(y1, k2); + y1 = _mm_mulhi_epi16(y1, k2); + z0 = _mm_add_epi32(z0, _mm_unpacklo_epi16(t0, t1)); + z1 = _mm_add_epi32(z1, _mm_unpackhi_epi16(t0, t1)); + z2 = _mm_add_epi32(z2, _mm_unpacklo_epi16(y0, y1)); + z3 = _mm_add_epi32(z3, _mm_unpackhi_epi16(y0, y1)); + + _mm_store_si128((__m128i*)(dst + i), z0); + _mm_store_si128((__m128i*)(dst + i + 4), z1); + _mm_store_si128((__m128i*)(dst + i + 8), z2); + _mm_store_si128((__m128i*)(dst + i + 12), z3); + } + } + } + + src -= (_ksize/2)*cn; + kx -= _ksize/2; + for( ; i <= width - 4; i += 4, src += 4 ) + { + __m128i f, s0 = z, x0, x1; + + for( k = j = 0; k < _ksize; k++, j += cn ) + { + f = _mm_cvtsi32_si128(kx[k]); + f = _mm_shuffle_epi32(f, 0); + f = _mm_packs_epi32(f, f); + + x0 = _mm_cvtsi32_si128(*(const int*)(src + j)); + x0 = _mm_unpacklo_epi8(x0, z); + x1 = _mm_mulhi_epi16(x0, f); + x0 = _mm_mullo_epi16(x0, f); + s0 = _mm_add_epi32(s0, _mm_unpacklo_epi16(x0, x1)); + } + _mm_store_si128((__m128i*)(dst + i), s0); + } + + return i; + } + + Mat kernel; + int symmetryType; + bool smallValues; +}; + + +struct SymmColumnVec_32s8u +{ + SymmColumnVec_32s8u() { symmetryType=0; } + SymmColumnVec_32s8u(const Mat& _kernel, int _symmetryType, int _bits, double _delta) + { + symmetryType = _symmetryType; + _kernel.convertTo(kernel, CV_32F, 1./(1 << _bits), 0); + delta = (float)(_delta/(1 << _bits)); + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + } + + int operator()(const uchar** _src, uchar* dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int ksize2 = (kernel.rows + kernel.cols - 1)/2; + const float* ky = (const float*)kernel.data + ksize2; + int i = 0, k; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const int** src = (const int**)_src; + const __m128i *S, *S2; + __m128 d4 = _mm_set1_ps(delta); + + if( symmetrical ) + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128 s0, s1, s2, s3; + __m128i x0, x1; + S = (const __m128i*)(src[0] + i); + s0 = _mm_cvtepi32_ps(_mm_load_si128(S)); + s1 = _mm_cvtepi32_ps(_mm_load_si128(S+1)); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + s1 = _mm_add_ps(_mm_mul_ps(s1, f), d4); + s2 = _mm_cvtepi32_ps(_mm_load_si128(S+2)); + s3 = _mm_cvtepi32_ps(_mm_load_si128(S+3)); + s2 = _mm_add_ps(_mm_mul_ps(s2, f), d4); + s3 = _mm_add_ps(_mm_mul_ps(s3, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + S = (const __m128i*)(src[k] + i); + S2 = (const __m128i*)(src[-k] + i); + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_add_epi32(_mm_load_si128(S), _mm_load_si128(S2)); + x1 = _mm_add_epi32(_mm_load_si128(S+1), _mm_load_si128(S2+1)); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(_mm_cvtepi32_ps(x1), f)); + x0 = _mm_add_epi32(_mm_load_si128(S+2), _mm_load_si128(S2+2)); + x1 = _mm_add_epi32(_mm_load_si128(S+3), _mm_load_si128(S2+3)); + s2 = _mm_add_ps(s2, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(_mm_cvtepi32_ps(x1), f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + x1 = _mm_packs_epi32(_mm_cvtps_epi32(s2), _mm_cvtps_epi32(s3)); + x0 = _mm_packus_epi16(x0, x1); + _mm_storeu_si128((__m128i*)(dst + i), x0); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128i x0; + __m128 s0 = _mm_cvtepi32_ps(_mm_load_si128((const __m128i*)(src[0] + i))); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + S = (const __m128i*)(src[k] + i); + S2 = (const __m128i*)(src[-k] + i); + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_add_epi32(_mm_load_si128(S), _mm_load_si128(S2)); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + } + + x0 = _mm_cvtps_epi32(s0); + x0 = _mm_packs_epi32(x0, x0); + x0 = _mm_packus_epi16(x0, x0); + *(int*)(dst + i) = _mm_cvtsi128_si32(x0); + } + } + else + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f, s0 = d4, s1 = d4, s2 = d4, s3 = d4; + __m128i x0, x1; + + for( k = 1; k <= ksize2; k++ ) + { + S = (const __m128i*)(src[k] + i); + S2 = (const __m128i*)(src[-k] + i); + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_epi32(_mm_load_si128(S), _mm_load_si128(S2)); + x1 = _mm_sub_epi32(_mm_load_si128(S+1), _mm_load_si128(S2+1)); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(_mm_cvtepi32_ps(x1), f)); + x0 = _mm_sub_epi32(_mm_load_si128(S+2), _mm_load_si128(S2+2)); + x1 = _mm_sub_epi32(_mm_load_si128(S+3), _mm_load_si128(S2+3)); + s2 = _mm_add_ps(s2, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(_mm_cvtepi32_ps(x1), f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + x1 = _mm_packs_epi32(_mm_cvtps_epi32(s2), _mm_cvtps_epi32(s3)); + x0 = _mm_packus_epi16(x0, x1); + _mm_storeu_si128((__m128i*)(dst + i), x0); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f, s0 = d4; + __m128i x0; + + for( k = 1; k <= ksize2; k++ ) + { + S = (const __m128i*)(src[k] + i); + S2 = (const __m128i*)(src[-k] + i); + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_epi32(_mm_load_si128(S), _mm_load_si128(S2)); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0), f)); + } + + x0 = _mm_cvtps_epi32(s0); + x0 = _mm_packs_epi32(x0, x0); + x0 = _mm_packus_epi16(x0, x0); + *(int*)(dst + i) = _mm_cvtsi128_si32(x0); + } + } + + return i; + } + + int symmetryType; + float delta; + Mat kernel; +}; + + +struct SymmColumnSmallVec_32s16s +{ + SymmColumnSmallVec_32s16s() { symmetryType=0; } + SymmColumnSmallVec_32s16s(const Mat& _kernel, int _symmetryType, int _bits, double _delta) + { + symmetryType = _symmetryType; + _kernel.convertTo(kernel, CV_32F, 1./(1 << _bits), 0); + delta = (float)(_delta/(1 << _bits)); + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + } + + int operator()(const uchar** _src, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int ksize2 = (kernel.rows + kernel.cols - 1)/2; + const float* ky = (const float*)kernel.data + ksize2; + int i = 0; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const int** src = (const int**)_src; + const int *S0 = src[-1], *S1 = src[0], *S2 = src[1]; + short* dst = (short*)_dst; + __m128 df4 = _mm_set1_ps(delta); + __m128i d4 = _mm_cvtps_epi32(df4); + + if( symmetrical ) + { + if( ky[0] == 2 && ky[1] == 1 ) + { + for( ; i <= width - 8; i += 8 ) + { + __m128i s0, s1, s2, s3, s4, s5; + s0 = _mm_load_si128((__m128i*)(S0 + i)); + s1 = _mm_load_si128((__m128i*)(S0 + i + 4)); + s2 = _mm_load_si128((__m128i*)(S1 + i)); + s3 = _mm_load_si128((__m128i*)(S1 + i + 4)); + s4 = _mm_load_si128((__m128i*)(S2 + i)); + s5 = _mm_load_si128((__m128i*)(S2 + i + 4)); + s0 = _mm_add_epi32(s0, _mm_add_epi32(s4, _mm_add_epi32(s2, s2))); + s1 = _mm_add_epi32(s1, _mm_add_epi32(s5, _mm_add_epi32(s3, s3))); + s0 = _mm_add_epi32(s0, d4); + s1 = _mm_add_epi32(s1, d4); + _mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0, s1)); + } + } + else if( ky[0] == -2 && ky[1] == 1 ) + { + for( ; i <= width - 8; i += 8 ) + { + __m128i s0, s1, s2, s3, s4, s5; + s0 = _mm_load_si128((__m128i*)(S0 + i)); + s1 = _mm_load_si128((__m128i*)(S0 + i + 4)); + s2 = _mm_load_si128((__m128i*)(S1 + i)); + s3 = _mm_load_si128((__m128i*)(S1 + i + 4)); + s4 = _mm_load_si128((__m128i*)(S2 + i)); + s5 = _mm_load_si128((__m128i*)(S2 + i + 4)); + s0 = _mm_add_epi32(s0, _mm_sub_epi32(s4, _mm_add_epi32(s2, s2))); + s1 = _mm_add_epi32(s1, _mm_sub_epi32(s5, _mm_add_epi32(s3, s3))); + s0 = _mm_add_epi32(s0, d4); + s1 = _mm_add_epi32(s1, d4); + _mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0, s1)); + } + } + else + { + __m128 k0 = _mm_set1_ps(ky[0]), k1 = _mm_set1_ps(ky[1]); + for( ; i <= width - 8; i += 8 ) + { + __m128 s0, s1; + s0 = _mm_cvtepi32_ps(_mm_load_si128((__m128i*)(S1 + i))); + s1 = _mm_cvtepi32_ps(_mm_load_si128((__m128i*)(S1 + i + 4))); + s0 = _mm_add_ps(_mm_mul_ps(s0, k0), df4); + s1 = _mm_add_ps(_mm_mul_ps(s1, k0), df4); + __m128i x0, x1; + x0 = _mm_add_epi32(_mm_load_si128((__m128i*)(S0 + i)), + _mm_load_si128((__m128i*)(S2 + i))); + x1 = _mm_add_epi32(_mm_load_si128((__m128i*)(S0 + i + 4)), + _mm_load_si128((__m128i*)(S2 + i + 4))); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0),k1)); + s1 = _mm_add_ps(s1, _mm_mul_ps(_mm_cvtepi32_ps(x1),k1)); + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + _mm_storeu_si128((__m128i*)(dst + i), x0); + } + } + } + else + { + if( fabs(ky[1]) == 1 && ky[1] == -ky[-1] ) + { + if( ky[1] < 0 ) + std::swap(S0, S2); + for( ; i <= width - 8; i += 8 ) + { + __m128i s0, s1, s2, s3; + s0 = _mm_load_si128((__m128i*)(S2 + i)); + s1 = _mm_load_si128((__m128i*)(S2 + i + 4)); + s2 = _mm_load_si128((__m128i*)(S0 + i)); + s3 = _mm_load_si128((__m128i*)(S0 + i + 4)); + s0 = _mm_add_epi32(_mm_sub_epi32(s0, s2), d4); + s1 = _mm_add_epi32(_mm_sub_epi32(s1, s3), d4); + _mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0, s1)); + } + } + else + { + __m128 k1 = _mm_set1_ps(ky[1]); + for( ; i <= width - 8; i += 8 ) + { + __m128 s0 = df4, s1 = df4; + __m128i x0, x1; + x0 = _mm_sub_epi32(_mm_load_si128((__m128i*)(S0 + i)), + _mm_load_si128((__m128i*)(S2 + i))); + x1 = _mm_sub_epi32(_mm_load_si128((__m128i*)(S0 + i + 4)), + _mm_load_si128((__m128i*)(S2 + i + 4))); + s0 = _mm_add_ps(s0, _mm_mul_ps(_mm_cvtepi32_ps(x0),k1)); + s1 = _mm_add_ps(s1, _mm_mul_ps(_mm_cvtepi32_ps(x1),k1)); + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + _mm_storeu_si128((__m128i*)(dst + i), x0); + } + } + } + + return i; + } + + int symmetryType; + float delta; + Mat kernel; +}; + + +/////////////////////////////////////// 16s ////////////////////////////////// + +struct RowVec_16s32f +{ + RowVec_16s32f() {} + RowVec_16s32f( const Mat& _kernel ) + { + kernel = _kernel; + sse2_supported = checkHardwareSupport(CV_CPU_SSE2); + } + + int operator()(const uchar* _src, uchar* _dst, int width, int cn) const + { + if( !sse2_supported ) + return 0; + + int i = 0, k, _ksize = kernel.rows + kernel.cols - 1; + float* dst = (float*)_dst; + const float* _kx = (const float*)kernel.data; + width *= cn; + + for( ; i <= width - 8; i += 8 ) + { + const short* src = (const short*)_src + i; + __m128 f, s0 = _mm_setzero_ps(), s1 = s0, x0, x1; + for( k = 0; k < _ksize; k++, src += cn ) + { + f = _mm_load_ss(_kx+k); + f = _mm_shuffle_ps(f, f, 0); + + __m128i x0i = _mm_loadu_si128((const __m128i*)src); + __m128i x1i = _mm_srai_epi32(_mm_unpackhi_epi16(x0i, x0i), 16); + x0i = _mm_srai_epi32(_mm_unpacklo_epi16(x0i, x0i), 16); + x0 = _mm_cvtepi32_ps(x0i); + x1 = _mm_cvtepi32_ps(x1i); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + } + _mm_store_ps(dst + i, s0); + _mm_store_ps(dst + i + 4, s1); + } + return i; + } + + Mat kernel; + bool sse2_supported; +}; + + +struct SymmColumnVec_32f16s +{ + SymmColumnVec_32f16s() { symmetryType=0; } + SymmColumnVec_32f16s(const Mat& _kernel, int _symmetryType, int, double _delta) + { + symmetryType = _symmetryType; + kernel = _kernel; + delta = (float)_delta; + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + sse2_supported = checkHardwareSupport(CV_CPU_SSE2); + } + + int operator()(const uchar** _src, uchar* _dst, int width) const + { + if( !sse2_supported ) + return 0; + + int ksize2 = (kernel.rows + kernel.cols - 1)/2; + const float* ky = (const float*)kernel.data + ksize2; + int i = 0, k; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const float** src = (const float**)_src; + const float *S, *S2; + short* dst = (short*)_dst; + __m128 d4 = _mm_set1_ps(delta); + + if( symmetrical ) + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128 s0, s1, s2, s3; + __m128 x0, x1; + S = src[0] + i; + s0 = _mm_load_ps(S); + s1 = _mm_load_ps(S+4); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + s1 = _mm_add_ps(_mm_mul_ps(s1, f), d4); + s2 = _mm_load_ps(S+8); + s3 = _mm_load_ps(S+12); + s2 = _mm_add_ps(_mm_mul_ps(s2, f), d4); + s3 = _mm_add_ps(_mm_mul_ps(s3, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + S = src[k] + i; + S2 = src[-k] + i; + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_add_ps(_mm_load_ps(S), _mm_load_ps(S2)); + x1 = _mm_add_ps(_mm_load_ps(S+4), _mm_load_ps(S2+4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + x0 = _mm_add_ps(_mm_load_ps(S+8), _mm_load_ps(S2+8)); + x1 = _mm_add_ps(_mm_load_ps(S+12), _mm_load_ps(S2+12)); + s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f)); + } + + __m128i s0i = _mm_cvtps_epi32(s0); + __m128i s1i = _mm_cvtps_epi32(s1); + __m128i s2i = _mm_cvtps_epi32(s2); + __m128i s3i = _mm_cvtps_epi32(s3); + + _mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0i, s1i)); + _mm_storeu_si128((__m128i*)(dst + i + 8), _mm_packs_epi32(s2i, s3i)); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128 x0, s0 = _mm_load_ps(src[0] + i); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + S = src[k] + i; + S2 = src[-k] + i; + x0 = _mm_add_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + } + + __m128i s0i = _mm_cvtps_epi32(s0); + _mm_storel_epi64((__m128i*)(dst + i), _mm_packs_epi32(s0i, s0i)); + } + } + else + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f, s0 = d4, s1 = d4, s2 = d4, s3 = d4; + __m128 x0, x1; + S = src[0] + i; + + for( k = 1; k <= ksize2; k++ ) + { + S = src[k] + i; + S2 = src[-k] + i; + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_ps(_mm_load_ps(S), _mm_load_ps(S2)); + x1 = _mm_sub_ps(_mm_load_ps(S+4), _mm_load_ps(S2+4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + x0 = _mm_sub_ps(_mm_load_ps(S+8), _mm_load_ps(S2+8)); + x1 = _mm_sub_ps(_mm_load_ps(S+12), _mm_load_ps(S2+12)); + s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f)); + } + + __m128i s0i = _mm_cvtps_epi32(s0); + __m128i s1i = _mm_cvtps_epi32(s1); + __m128i s2i = _mm_cvtps_epi32(s2); + __m128i s3i = _mm_cvtps_epi32(s3); + + _mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0i, s1i)); + _mm_storeu_si128((__m128i*)(dst + i + 8), _mm_packs_epi32(s2i, s3i)); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f, x0, s0 = d4; + + for( k = 1; k <= ksize2; k++ ) + { + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + } + + __m128i s0i = _mm_cvtps_epi32(s0); + _mm_storel_epi64((__m128i*)(dst + i), _mm_packs_epi32(s0i, s0i)); + } + } + + return i; + } + + int symmetryType; + float delta; + Mat kernel; + bool sse2_supported; +}; + + +/////////////////////////////////////// 32f ////////////////////////////////// + +struct RowVec_32f +{ + RowVec_32f() {} + RowVec_32f( const Mat& _kernel ) + { + kernel = _kernel; + } + + int operator()(const uchar* _src, uchar* _dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int i = 0, k, _ksize = kernel.rows + kernel.cols - 1; + float* dst = (float*)_dst; + const float* _kx = (const float*)kernel.data; + width *= cn; + + for( ; i <= width - 8; i += 8 ) + { + const float* src = (const float*)_src + i; + __m128 f, s0 = _mm_setzero_ps(), s1 = s0, x0, x1; + for( k = 0; k < _ksize; k++, src += cn ) + { + f = _mm_load_ss(_kx+k); + f = _mm_shuffle_ps(f, f, 0); + + x0 = _mm_loadu_ps(src); + x1 = _mm_loadu_ps(src + 4); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + } + _mm_store_ps(dst + i, s0); + _mm_store_ps(dst + i + 4, s1); + } + return i; + } + + Mat kernel; +}; + + +struct SymmRowSmallVec_32f +{ + SymmRowSmallVec_32f() {} + SymmRowSmallVec_32f( const Mat& _kernel, int _symmetryType ) + { + kernel = _kernel; + symmetryType = _symmetryType; + } + + int operator()(const uchar* _src, uchar* _dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int i = 0, _ksize = kernel.rows + kernel.cols - 1; + float* dst = (float*)_dst; + const float* src = (const float*)_src + (_ksize/2)*cn; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const float* kx = (const float*)kernel.data + _ksize/2; + width *= cn; + + if( symmetrical ) + { + if( _ksize == 1 ) + return 0; + if( _ksize == 3 ) + { + if( kx[0] == 2 && kx[1] == 1 ) + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_ps(src - cn); + x1 = _mm_loadu_ps(src); + x2 = _mm_loadu_ps(src + cn); + y0 = _mm_loadu_ps(src - cn + 4); + y1 = _mm_loadu_ps(src + 4); + y2 = _mm_loadu_ps(src + cn + 4); + x0 = _mm_add_ps(x0, _mm_add_ps(_mm_add_ps(x1, x1), x2)); + y0 = _mm_add_ps(y0, _mm_add_ps(_mm_add_ps(y1, y1), y2)); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + else if( kx[0] == -2 && kx[1] == 1 ) + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_ps(src - cn); + x1 = _mm_loadu_ps(src); + x2 = _mm_loadu_ps(src + cn); + y0 = _mm_loadu_ps(src - cn + 4); + y1 = _mm_loadu_ps(src + 4); + y2 = _mm_loadu_ps(src + cn + 4); + x0 = _mm_add_ps(x0, _mm_sub_ps(x2, _mm_add_ps(x1, x1))); + y0 = _mm_add_ps(y0, _mm_sub_ps(y2, _mm_add_ps(y1, y1))); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + else + { + __m128 k0 = _mm_set1_ps(kx[0]), k1 = _mm_set1_ps(kx[1]); + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_ps(src - cn); + x1 = _mm_loadu_ps(src); + x2 = _mm_loadu_ps(src + cn); + y0 = _mm_loadu_ps(src - cn + 4); + y1 = _mm_loadu_ps(src + 4); + y2 = _mm_loadu_ps(src + cn + 4); + + x0 = _mm_mul_ps(_mm_add_ps(x0, x2), k1); + y0 = _mm_mul_ps(_mm_add_ps(y0, y2), k1); + x0 = _mm_add_ps(x0, _mm_mul_ps(x1, k0)); + y0 = _mm_add_ps(y0, _mm_mul_ps(y1, k0)); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + } + } + else if( _ksize == 5 ) + { + if( kx[0] == -2 && kx[1] == 0 && kx[2] == 1 ) + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_ps(src - cn*2); + x1 = _mm_loadu_ps(src); + x2 = _mm_loadu_ps(src + cn*2); + y0 = _mm_loadu_ps(src - cn*2 + 4); + y1 = _mm_loadu_ps(src + 4); + y2 = _mm_loadu_ps(src + cn*2 + 4); + x0 = _mm_add_ps(x0, _mm_sub_ps(x2, _mm_add_ps(x1, x1))); + y0 = _mm_add_ps(y0, _mm_sub_ps(y2, _mm_add_ps(y1, y1))); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + else + { + __m128 k0 = _mm_set1_ps(kx[0]), k1 = _mm_set1_ps(kx[1]), k2 = _mm_set1_ps(kx[2]); + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_ps(src - cn); + x1 = _mm_loadu_ps(src); + x2 = _mm_loadu_ps(src + cn); + y0 = _mm_loadu_ps(src - cn + 4); + y1 = _mm_loadu_ps(src + 4); + y2 = _mm_loadu_ps(src + cn + 4); + + x0 = _mm_mul_ps(_mm_add_ps(x0, x2), k1); + y0 = _mm_mul_ps(_mm_add_ps(y0, y2), k1); + x0 = _mm_add_ps(x0, _mm_mul_ps(x1, k0)); + y0 = _mm_add_ps(y0, _mm_mul_ps(y1, k0)); + + x2 = _mm_add_ps(_mm_loadu_ps(src + cn*2), _mm_loadu_ps(src - cn*2)); + y2 = _mm_add_ps(_mm_loadu_ps(src + cn*2 + 4), _mm_loadu_ps(src - cn*2 + 4)); + x0 = _mm_add_ps(x0, _mm_mul_ps(x2, k2)); + y0 = _mm_add_ps(y0, _mm_mul_ps(y2, k2)); + + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + } + } + } + else + { + if( _ksize == 3 ) + { + if( kx[0] == 0 && kx[1] == 1 ) + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x2, y0, y2; + x0 = _mm_loadu_ps(src + cn); + x2 = _mm_loadu_ps(src - cn); + y0 = _mm_loadu_ps(src + cn + 4); + y2 = _mm_loadu_ps(src - cn + 4); + x0 = _mm_sub_ps(x0, x2); + y0 = _mm_sub_ps(y0, y2); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + else + { + __m128 k1 = _mm_set1_ps(kx[1]); + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x2, y0, y2; + x0 = _mm_loadu_ps(src + cn); + x2 = _mm_loadu_ps(src - cn); + y0 = _mm_loadu_ps(src + cn + 4); + y2 = _mm_loadu_ps(src - cn + 4); + + x0 = _mm_mul_ps(_mm_sub_ps(x0, x2), k1); + y0 = _mm_mul_ps(_mm_sub_ps(y0, y2), k1); + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + } + } + else if( _ksize == 5 ) + { + __m128 k1 = _mm_set1_ps(kx[1]), k2 = _mm_set1_ps(kx[2]); + for( ; i <= width - 8; i += 8, src += 8 ) + { + __m128 x0, x2, y0, y2; + x0 = _mm_loadu_ps(src + cn); + x2 = _mm_loadu_ps(src - cn); + y0 = _mm_loadu_ps(src + cn + 4); + y2 = _mm_loadu_ps(src - cn + 4); + + x0 = _mm_mul_ps(_mm_sub_ps(x0, x2), k1); + y0 = _mm_mul_ps(_mm_sub_ps(y0, y2), k1); + + x2 = _mm_sub_ps(_mm_loadu_ps(src + cn*2), _mm_loadu_ps(src - cn*2)); + y2 = _mm_sub_ps(_mm_loadu_ps(src + cn*2 + 4), _mm_loadu_ps(src - cn*2 + 4)); + x0 = _mm_add_ps(x0, _mm_mul_ps(x2, k2)); + y0 = _mm_add_ps(y0, _mm_mul_ps(y2, k2)); + + _mm_store_ps(dst + i, x0); + _mm_store_ps(dst + i + 4, y0); + } + } + } + + return i; + } + + Mat kernel; + int symmetryType; +}; + + +struct SymmColumnVec_32f +{ + SymmColumnVec_32f() { symmetryType=0; } + SymmColumnVec_32f(const Mat& _kernel, int _symmetryType, int, double _delta) + { + symmetryType = _symmetryType; + kernel = _kernel; + delta = (float)_delta; + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + } + + int operator()(const uchar** _src, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int ksize2 = (kernel.rows + kernel.cols - 1)/2; + const float* ky = (const float*)kernel.data + ksize2; + int i = 0, k; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const float** src = (const float**)_src; + const float *S, *S2; + float* dst = (float*)_dst; + __m128 d4 = _mm_set1_ps(delta); + + if( symmetrical ) + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128 s0, s1, s2, s3; + __m128 x0, x1; + S = src[0] + i; + s0 = _mm_load_ps(S); + s1 = _mm_load_ps(S+4); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + s1 = _mm_add_ps(_mm_mul_ps(s1, f), d4); + s2 = _mm_load_ps(S+8); + s3 = _mm_load_ps(S+12); + s2 = _mm_add_ps(_mm_mul_ps(s2, f), d4); + s3 = _mm_add_ps(_mm_mul_ps(s3, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + S = src[k] + i; + S2 = src[-k] + i; + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_add_ps(_mm_load_ps(S), _mm_load_ps(S2)); + x1 = _mm_add_ps(_mm_load_ps(S+4), _mm_load_ps(S2+4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + x0 = _mm_add_ps(_mm_load_ps(S+8), _mm_load_ps(S2+8)); + x1 = _mm_add_ps(_mm_load_ps(S+12), _mm_load_ps(S2+12)); + s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f)); + } + + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + _mm_storeu_ps(dst + i + 8, s2); + _mm_storeu_ps(dst + i + 12, s3); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f = _mm_load_ss(ky); + f = _mm_shuffle_ps(f, f, 0); + __m128 x0, s0 = _mm_load_ps(src[0] + i); + s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4); + + for( k = 1; k <= ksize2; k++ ) + { + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + S = src[k] + i; + S2 = src[-k] + i; + x0 = _mm_add_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + } + + _mm_storeu_ps(dst + i, s0); + } + } + else + { + for( ; i <= width - 16; i += 16 ) + { + __m128 f, s0 = d4, s1 = d4, s2 = d4, s3 = d4; + __m128 x0, x1; + S = src[0] + i; + + for( k = 1; k <= ksize2; k++ ) + { + S = src[k] + i; + S2 = src[-k] + i; + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_ps(_mm_load_ps(S), _mm_load_ps(S2)); + x1 = _mm_sub_ps(_mm_load_ps(S+4), _mm_load_ps(S2+4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1, f)); + x0 = _mm_sub_ps(_mm_load_ps(S+8), _mm_load_ps(S2+8)); + x1 = _mm_sub_ps(_mm_load_ps(S+12), _mm_load_ps(S2+12)); + s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f)); + } + + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + _mm_storeu_ps(dst + i + 8, s2); + _mm_storeu_ps(dst + i + 12, s3); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 f, x0, s0 = d4; + + for( k = 1; k <= ksize2; k++ ) + { + f = _mm_load_ss(ky+k); + f = _mm_shuffle_ps(f, f, 0); + x0 = _mm_sub_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f)); + } + + _mm_storeu_ps(dst + i, s0); + } + } + + return i; + } + + int symmetryType; + float delta; + Mat kernel; +}; + + +struct SymmColumnSmallVec_32f +{ + SymmColumnSmallVec_32f() { symmetryType=0; } + SymmColumnSmallVec_32f(const Mat& _kernel, int _symmetryType, int, double _delta) + { + symmetryType = _symmetryType; + kernel = _kernel; + delta = (float)_delta; + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + } + + int operator()(const uchar** _src, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int ksize2 = (kernel.rows + kernel.cols - 1)/2; + const float* ky = (const float*)kernel.data + ksize2; + int i = 0; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + const float** src = (const float**)_src; + const float *S0 = src[-1], *S1 = src[0], *S2 = src[1]; + float* dst = (float*)_dst; + __m128 d4 = _mm_set1_ps(delta); + + if( symmetrical ) + { + if( ky[0] == 2 && ky[1] == 1 ) + { + for( ; i <= width - 8; i += 8 ) + { + __m128 s0, s1, s2, s3, s4, s5; + s0 = _mm_load_ps(S0 + i); + s1 = _mm_load_ps(S0 + i + 4); + s2 = _mm_load_ps(S1 + i); + s3 = _mm_load_ps(S1 + i + 4); + s4 = _mm_load_ps(S2 + i); + s5 = _mm_load_ps(S2 + i + 4); + s0 = _mm_add_ps(s0, _mm_add_ps(s4, _mm_add_ps(s2, s2))); + s1 = _mm_add_ps(s1, _mm_add_ps(s5, _mm_add_ps(s3, s3))); + s0 = _mm_add_ps(s0, d4); + s1 = _mm_add_ps(s1, d4); + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + } + } + else if( ky[0] == -2 && ky[1] == 1 ) + { + for( ; i <= width - 8; i += 8 ) + { + __m128 s0, s1, s2, s3, s4, s5; + s0 = _mm_load_ps(S0 + i); + s1 = _mm_load_ps(S0 + i + 4); + s2 = _mm_load_ps(S1 + i); + s3 = _mm_load_ps(S1 + i + 4); + s4 = _mm_load_ps(S2 + i); + s5 = _mm_load_ps(S2 + i + 4); + s0 = _mm_add_ps(s0, _mm_sub_ps(s4, _mm_add_ps(s2, s2))); + s1 = _mm_add_ps(s1, _mm_sub_ps(s5, _mm_add_ps(s3, s3))); + s0 = _mm_add_ps(s0, d4); + s1 = _mm_add_ps(s1, d4); + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + } + } + else + { + __m128 k0 = _mm_set1_ps(ky[0]), k1 = _mm_set1_ps(ky[1]); + for( ; i <= width - 8; i += 8 ) + { + __m128 s0, s1, x0, x1; + s0 = _mm_load_ps(S1 + i); + s1 = _mm_load_ps(S1 + i + 4); + s0 = _mm_add_ps(_mm_mul_ps(s0, k0), d4); + s1 = _mm_add_ps(_mm_mul_ps(s1, k0), d4); + x0 = _mm_add_ps(_mm_load_ps(S0 + i), _mm_load_ps(S2 + i)); + x1 = _mm_add_ps(_mm_load_ps(S0 + i + 4), _mm_load_ps(S2 + i + 4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0,k1)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1,k1)); + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + } + } + } + else + { + if( fabs(ky[1]) == 1 && ky[1] == -ky[-1] ) + { + if( ky[1] < 0 ) + std::swap(S0, S2); + for( ; i <= width - 8; i += 8 ) + { + __m128 s0, s1, s2, s3; + s0 = _mm_load_ps(S2 + i); + s1 = _mm_load_ps(S2 + i + 4); + s2 = _mm_load_ps(S0 + i); + s3 = _mm_load_ps(S0 + i + 4); + s0 = _mm_add_ps(_mm_sub_ps(s0, s2), d4); + s1 = _mm_add_ps(_mm_sub_ps(s1, s3), d4); + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + } + } + else + { + __m128 k1 = _mm_set1_ps(ky[1]); + for( ; i <= width - 8; i += 8 ) + { + __m128 s0 = d4, s1 = d4, x0, x1; + x0 = _mm_sub_ps(_mm_load_ps(S2 + i), _mm_load_ps(S0 + i)); + x1 = _mm_sub_ps(_mm_load_ps(S2 + i + 4), _mm_load_ps(S0 + i + 4)); + s0 = _mm_add_ps(s0, _mm_mul_ps(x0,k1)); + s1 = _mm_add_ps(s1, _mm_mul_ps(x1,k1)); + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + } + } + } + + return i; + } + + int symmetryType; + float delta; + Mat kernel; +}; + + +/////////////////////////////// non-separable filters /////////////////////////////// + +///////////////////////////////// 8u<->8u, 8u<->16s ///////////////////////////////// + +struct FilterVec_8u +{ + FilterVec_8u() {} + FilterVec_8u(const Mat& _kernel, int _bits, double _delta) + { + Mat kernel; + _kernel.convertTo(kernel, CV_32F, 1./(1 << _bits), 0); + delta = (float)(_delta/(1 << _bits)); + vector coords; + preprocess2DKernel(kernel, coords, coeffs); + _nz = (int)coords.size(); + } + + int operator()(const uchar** src, uchar* dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const float* kf = (const float*)&coeffs[0]; + int i = 0, k, nz = _nz; + __m128 d4 = _mm_set1_ps(delta); + + for( ; i <= width - 16; i += 16 ) + { + __m128 s0 = d4, s1 = d4, s2 = d4, s3 = d4; + __m128i x0, x1, z = _mm_setzero_si128(); + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0, t1; + f = _mm_shuffle_ps(f, f, 0); + + x0 = _mm_loadu_si128((const __m128i*)(src[k] + i)); + x1 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x0, z)); + t1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(x0, z)); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(t1, f)); + + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x1, z)); + t1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(x1, z)); + s2 = _mm_add_ps(s2, _mm_mul_ps(t0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(t1, f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + x1 = _mm_packs_epi32(_mm_cvtps_epi32(s2), _mm_cvtps_epi32(s3)); + x0 = _mm_packus_epi16(x0, x1); + _mm_storeu_si128((__m128i*)(dst + i), x0); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 s0 = d4; + __m128i x0, z = _mm_setzero_si128(); + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0; + f = _mm_shuffle_ps(f, f, 0); + + x0 = _mm_cvtsi32_si128(*(const int*)(src[k] + i)); + x0 = _mm_unpacklo_epi8(x0, z); + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x0, z)); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), z); + x0 = _mm_packus_epi16(x0, x0); + *(int*)(dst + i) = _mm_cvtsi128_si32(x0); + } + + return i; + } + + int _nz; + vector coeffs; + float delta; +}; + + +struct FilterVec_8u16s +{ + FilterVec_8u16s() {} + FilterVec_8u16s(const Mat& _kernel, int _bits, double _delta) + { + Mat kernel; + _kernel.convertTo(kernel, CV_32F, 1./(1 << _bits), 0); + delta = (float)(_delta/(1 << _bits)); + vector coords; + preprocess2DKernel(kernel, coords, coeffs); + _nz = (int)coords.size(); + } + + int operator()(const uchar** src, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const float* kf = (const float*)&coeffs[0]; + short* dst = (short*)_dst; + int i = 0, k, nz = _nz; + __m128 d4 = _mm_set1_ps(delta); + + for( ; i <= width - 16; i += 16 ) + { + __m128 s0 = d4, s1 = d4, s2 = d4, s3 = d4; + __m128i x0, x1, z = _mm_setzero_si128(); + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0, t1; + f = _mm_shuffle_ps(f, f, 0); + + x0 = _mm_loadu_si128((const __m128i*)(src[k] + i)); + x1 = _mm_unpackhi_epi8(x0, z); + x0 = _mm_unpacklo_epi8(x0, z); + + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x0, z)); + t1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(x0, z)); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(t1, f)); + + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x1, z)); + t1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(x1, z)); + s2 = _mm_add_ps(s2, _mm_mul_ps(t0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(t1, f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), _mm_cvtps_epi32(s1)); + x1 = _mm_packs_epi32(_mm_cvtps_epi32(s2), _mm_cvtps_epi32(s3)); + _mm_storeu_si128((__m128i*)(dst + i), x0); + _mm_storeu_si128((__m128i*)(dst + i + 8), x1); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 s0 = d4; + __m128i x0, z = _mm_setzero_si128(); + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0; + f = _mm_shuffle_ps(f, f, 0); + + x0 = _mm_cvtsi32_si128(*(const int*)(src[k] + i)); + x0 = _mm_unpacklo_epi8(x0, z); + t0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(x0, z)); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + } + + x0 = _mm_packs_epi32(_mm_cvtps_epi32(s0), z); + _mm_storel_epi64((__m128i*)(dst + i), x0); + } + + return i; + } + + int _nz; + vector coeffs; + float delta; +}; + + +struct FilterVec_32f +{ + FilterVec_32f() {} + FilterVec_32f(const Mat& _kernel, int, double _delta) + { + delta = (float)_delta; + vector coords; + preprocess2DKernel(_kernel, coords, coeffs); + _nz = (int)coords.size(); + } + + int operator()(const uchar** _src, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + const float* kf = (const float*)&coeffs[0]; + const float** src = (const float**)_src; + float* dst = (float*)_dst; + int i = 0, k, nz = _nz; + __m128 d4 = _mm_set1_ps(delta); + + for( ; i <= width - 16; i += 16 ) + { + __m128 s0 = d4, s1 = d4, s2 = d4, s3 = d4; + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0, t1; + f = _mm_shuffle_ps(f, f, 0); + const float* S = src[k] + i; + + t0 = _mm_loadu_ps(S); + t1 = _mm_loadu_ps(S + 4); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + s1 = _mm_add_ps(s1, _mm_mul_ps(t1, f)); + + t0 = _mm_loadu_ps(S + 8); + t1 = _mm_loadu_ps(S + 12); + s2 = _mm_add_ps(s2, _mm_mul_ps(t0, f)); + s3 = _mm_add_ps(s3, _mm_mul_ps(t1, f)); + } + + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + _mm_storeu_ps(dst + i + 8, s2); + _mm_storeu_ps(dst + i + 12, s3); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 s0 = d4; + + for( k = 0; k < nz; k++ ) + { + __m128 f = _mm_load_ss(kf+k), t0; + f = _mm_shuffle_ps(f, f, 0); + t0 = _mm_loadu_ps(src[k] + i); + s0 = _mm_add_ps(s0, _mm_mul_ps(t0, f)); + } + _mm_storeu_ps(dst + i, s0); + } + + return i; + } + + int _nz; + vector coeffs; + float delta; +}; + + +#else + +typedef RowNoVec RowVec_8u32s; +typedef RowNoVec RowVec_16s32f; +typedef RowNoVec RowVec_32f; +typedef SymmRowSmallNoVec SymmRowSmallVec_8u32s; +typedef SymmRowSmallNoVec SymmRowSmallVec_32f; +typedef ColumnNoVec SymmColumnVec_32s8u; +typedef ColumnNoVec SymmColumnVec_32f16s; +typedef ColumnNoVec SymmColumnVec_32f; +typedef SymmColumnSmallNoVec SymmColumnSmallVec_32s16s; +typedef SymmColumnSmallNoVec SymmColumnSmallVec_32f; +typedef FilterNoVec FilterVec_8u; +typedef FilterNoVec FilterVec_8u16s; +typedef FilterNoVec FilterVec_32f; + +#endif + + +template struct RowFilter : public BaseRowFilter +{ + RowFilter( const Mat& _kernel, int _anchor, const VecOp& _vecOp=VecOp() ) + { + if( _kernel.isContinuous() ) + kernel = _kernel; + else + _kernel.copyTo(kernel); + anchor = _anchor; + ksize = kernel.rows + kernel.cols - 1; + CV_Assert( kernel.type() == DataType
::type && + (kernel.rows == 1 || kernel.cols == 1)); + vecOp = _vecOp; + } + + void operator()(const uchar* src, uchar* dst, int width, int cn) + { + int _ksize = ksize; + const DT* kx = (const DT*)kernel.data; + const ST* S; + DT* D = (DT*)dst; + int i, k; + + i = vecOp(src, dst, width, cn); + width *= cn; + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + S = (const ST*)src + i; + DT f = kx[0]; + DT s0 = f*S[0], s1 = f*S[1], s2 = f*S[2], s3 = f*S[3]; + + for( k = 1; k < _ksize; k++ ) + { + S += cn; + f = kx[k]; + s0 += f*S[0]; s1 += f*S[1]; + s2 += f*S[2]; s3 += f*S[3]; + } + + D[i] = s0; D[i+1] = s1; + D[i+2] = s2; D[i+3] = s3; + } + #endif + for( ; i < width; i++ ) + { + S = (const ST*)src + i; + DT s0 = kx[0]*S[0]; + for( k = 1; k < _ksize; k++ ) + { + S += cn; + s0 += kx[k]*S[0]; + } + D[i] = s0; + } + } + + Mat kernel; + VecOp vecOp; +}; + + +template struct SymmRowSmallFilter : + public RowFilter +{ + SymmRowSmallFilter( const Mat& _kernel, int _anchor, int _symmetryType, + const VecOp& _vecOp = VecOp()) + : RowFilter( _kernel, _anchor, _vecOp ) + { + symmetryType = _symmetryType; + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 && this->ksize <= 5 ); + } + + void operator()(const uchar* src, uchar* dst, int width, int cn) + { + int ksize2 = this->ksize/2, ksize2n = ksize2*cn; + const DT* kx = (const DT*)this->kernel.data + ksize2; + bool symmetrical = (this->symmetryType & KERNEL_SYMMETRICAL) != 0; + DT* D = (DT*)dst; + int i = this->vecOp(src, dst, width, cn), j, k; + const ST* S = (const ST*)src + i + ksize2n; + width *= cn; + + if( symmetrical ) + { + if( this->ksize == 1 && kx[0] == 1 ) + { + for( ; i <= width - 2; i += 2 ) + { + DT s0 = S[i], s1 = S[i+1]; + D[i] = s0; D[i+1] = s1; + } + S += i; + } + else if( this->ksize == 3 ) + { + if( kx[0] == 2 && kx[1] == 1 ) + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = S[-cn] + S[0]*2 + S[cn], s1 = S[1-cn] + S[1]*2 + S[1+cn]; + D[i] = s0; D[i+1] = s1; + } + else if( kx[0] == -2 && kx[1] == 1 ) + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = S[-cn] - S[0]*2 + S[cn], s1 = S[1-cn] - S[1]*2 + S[1+cn]; + D[i] = s0; D[i+1] = s1; + } + else + { + DT k0 = kx[0], k1 = kx[1]; + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = S[0]*k0 + (S[-cn] + S[cn])*k1, s1 = S[1]*k0 + (S[1-cn] + S[1+cn])*k1; + D[i] = s0; D[i+1] = s1; + } + } + } + else if( this->ksize == 5 ) + { + DT k0 = kx[0], k1 = kx[1], k2 = kx[2]; + if( k0 == -2 && k1 == 0 && k2 == 1 ) + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = -2*S[0] + S[-cn*2] + S[cn*2]; + DT s1 = -2*S[1] + S[1-cn*2] + S[1+cn*2]; + D[i] = s0; D[i+1] = s1; + } + else + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = S[0]*k0 + (S[-cn] + S[cn])*k1 + (S[-cn*2] + S[cn*2])*k2; + DT s1 = S[1]*k0 + (S[1-cn] + S[1+cn])*k1 + (S[1-cn*2] + S[1+cn*2])*k2; + D[i] = s0; D[i+1] = s1; + } + } + + for( ; i < width; i++, S++ ) + { + DT s0 = kx[0]*S[0]; + for( k = 1, j = cn; k <= ksize2; k++, j += cn ) + s0 += kx[k]*(S[j] + S[-j]); + D[i] = s0; + } + } + else + { + if( this->ksize == 3 ) + { + if( kx[0] == 0 && kx[1] == 1 ) + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = S[cn] - S[-cn], s1 = S[1+cn] - S[1-cn]; + D[i] = s0; D[i+1] = s1; + } + else + { + DT k1 = kx[1]; + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = (S[cn] - S[-cn])*k1, s1 = (S[1+cn] - S[1-cn])*k1; + D[i] = s0; D[i+1] = s1; + } + } + } + else if( this->ksize == 5 ) + { + DT k1 = kx[1], k2 = kx[2]; + for( ; i <= width - 2; i += 2, S += 2 ) + { + DT s0 = (S[cn] - S[-cn])*k1 + (S[cn*2] - S[-cn*2])*k2; + DT s1 = (S[1+cn] - S[1-cn])*k1 + (S[1+cn*2] - S[1-cn*2])*k2; + D[i] = s0; D[i+1] = s1; + } + } + + for( ; i < width; i++, S++ ) + { + DT s0 = kx[0]*S[0]; + for( k = 1, j = cn; k <= ksize2; k++, j += cn ) + s0 += kx[k]*(S[j] - S[-j]); + D[i] = s0; + } + } + } + + int symmetryType; +}; + + +template struct ColumnFilter : public BaseColumnFilter +{ + typedef typename CastOp::type1 ST; + typedef typename CastOp::rtype DT; + + ColumnFilter( const Mat& _kernel, int _anchor, + double _delta, const CastOp& _castOp=CastOp(), + const VecOp& _vecOp=VecOp() ) + { + if( _kernel.isContinuous() ) + kernel = _kernel; + else + _kernel.copyTo(kernel); + anchor = _anchor; + ksize = kernel.rows + kernel.cols - 1; + delta = saturate_cast(_delta); + castOp0 = _castOp; + vecOp = _vecOp; + CV_Assert( kernel.type() == DataType::type && + (kernel.rows == 1 || kernel.cols == 1)); + } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + const ST* ky = (const ST*)kernel.data; + ST _delta = delta; + int _ksize = ksize; + int i, k; + CastOp castOp = castOp0; + + for( ; count--; dst += dststep, src++ ) + { + DT* D = (DT*)dst; + i = vecOp(src, dst, width); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST f = ky[0]; + const ST* S = (const ST*)src[0] + i; + ST s0 = f*S[0] + _delta, s1 = f*S[1] + _delta, + s2 = f*S[2] + _delta, s3 = f*S[3] + _delta; + + for( k = 1; k < _ksize; k++ ) + { + S = (const ST*)src[k] + i; f = ky[k]; + s0 += f*S[0]; s1 += f*S[1]; + s2 += f*S[2]; s3 += f*S[3]; + } + + D[i] = castOp(s0); D[i+1] = castOp(s1); + D[i+2] = castOp(s2); D[i+3] = castOp(s3); + } + #endif + for( ; i < width; i++ ) + { + ST s0 = ky[0]*((const ST*)src[0])[i] + _delta; + for( k = 1; k < _ksize; k++ ) + s0 += ky[k]*((const ST*)src[k])[i]; + D[i] = castOp(s0); + } + } + } + + Mat kernel; + CastOp castOp0; + VecOp vecOp; + ST delta; +}; + + +template struct SymmColumnFilter : public ColumnFilter +{ + typedef typename CastOp::type1 ST; + typedef typename CastOp::rtype DT; + + SymmColumnFilter( const Mat& _kernel, int _anchor, + double _delta, int _symmetryType, + const CastOp& _castOp=CastOp(), + const VecOp& _vecOp=VecOp()) + : ColumnFilter( _kernel, _anchor, _delta, _castOp, _vecOp ) + { + symmetryType = _symmetryType; + CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 ); + } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int ksize2 = this->ksize/2; + const ST* ky = (const ST*)this->kernel.data + ksize2; + int i, k; + bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0; + ST _delta = this->delta; + CastOp castOp = this->castOp0; + src += ksize2; + + if( symmetrical ) + { + for( ; count--; dst += dststep, src++ ) + { + DT* D = (DT*)dst; + i = (this->vecOp)(src, dst, width); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST f = ky[0]; + const ST* S = (const ST*)src[0] + i, *S2; + ST s0 = f*S[0] + _delta, s1 = f*S[1] + _delta, + s2 = f*S[2] + _delta, s3 = f*S[3] + _delta; + + for( k = 1; k <= ksize2; k++ ) + { + S = (const ST*)src[k] + i; + S2 = (const ST*)src[-k] + i; + f = ky[k]; + s0 += f*(S[0] + S2[0]); + s1 += f*(S[1] + S2[1]); + s2 += f*(S[2] + S2[2]); + s3 += f*(S[3] + S2[3]); + } + + D[i] = castOp(s0); D[i+1] = castOp(s1); + D[i+2] = castOp(s2); D[i+3] = castOp(s3); + } + #endif + for( ; i < width; i++ ) + { + ST s0 = ky[0]*((const ST*)src[0])[i] + _delta; + for( k = 1; k <= ksize2; k++ ) + s0 += ky[k]*(((const ST*)src[k])[i] + ((const ST*)src[-k])[i]); + D[i] = castOp(s0); + } + } + } + else + { + for( ; count--; dst += dststep, src++ ) + { + DT* D = (DT*)dst; + i = this->vecOp(src, dst, width); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST f = ky[0]; + const ST *S, *S2; + ST s0 = _delta, s1 = _delta, s2 = _delta, s3 = _delta; + + for( k = 1; k <= ksize2; k++ ) + { + S = (const ST*)src[k] + i; + S2 = (const ST*)src[-k] + i; + f = ky[k]; + s0 += f*(S[0] - S2[0]); + s1 += f*(S[1] - S2[1]); + s2 += f*(S[2] - S2[2]); + s3 += f*(S[3] - S2[3]); + } + + D[i] = castOp(s0); D[i+1] = castOp(s1); + D[i+2] = castOp(s2); D[i+3] = castOp(s3); + } + #endif + for( ; i < width; i++ ) + { + ST s0 = _delta; + for( k = 1; k <= ksize2; k++ ) + s0 += ky[k]*(((const ST*)src[k])[i] - ((const ST*)src[-k])[i]); + D[i] = castOp(s0); + } + } + } + } + + int symmetryType; +}; + + +template +struct SymmColumnSmallFilter : public SymmColumnFilter +{ + typedef typename CastOp::type1 ST; + typedef typename CastOp::rtype DT; + + SymmColumnSmallFilter( const Mat& _kernel, int _anchor, + double _delta, int _symmetryType, + const CastOp& _castOp=CastOp(), + const VecOp& _vecOp=VecOp()) + : SymmColumnFilter( _kernel, _anchor, _delta, _symmetryType, _castOp, _vecOp ) + { + CV_Assert( this->ksize == 3 ); + } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int ksize2 = this->ksize/2; + const ST* ky = (const ST*)this->kernel.data + ksize2; + int i; + bool symmetrical = (this->symmetryType & KERNEL_SYMMETRICAL) != 0; + bool is_1_2_1 = ky[0] == 1 && ky[1] == 2; + bool is_1_m2_1 = ky[0] == 1 && ky[1] == -2; + bool is_m1_0_1 = ky[1] == 1 || ky[1] == -1; + ST f0 = ky[0], f1 = ky[1]; + ST _delta = this->delta; + CastOp castOp = this->castOp0; + src += ksize2; + + for( ; count--; dst += dststep, src++ ) + { + DT* D = (DT*)dst; + i = (this->vecOp)(src, dst, width); + const ST* S0 = (const ST*)src[-1]; + const ST* S1 = (const ST*)src[0]; + const ST* S2 = (const ST*)src[1]; + + if( symmetrical ) + { + if( is_1_2_1 ) + { + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta; + ST s1 = S0[i+1] + S1[i+1]*2 + S2[i+1] + _delta; + D[i] = castOp(s0); + D[i+1] = castOp(s1); + + s0 = S0[i+2] + S1[i+2]*2 + S2[i+2] + _delta; + s1 = S0[i+3] + S1[i+3]*2 + S2[i+3] + _delta; + D[i+2] = castOp(s0); + D[i+3] = castOp(s1); + } + #else + for( ; i < width; i ++ ) + { + ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta; + D[i] = castOp(s0); + } + #endif + } + else if( is_1_m2_1 ) + { + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta; + ST s1 = S0[i+1] - S1[i+1]*2 + S2[i+1] + _delta; + D[i] = castOp(s0); + D[i+1] = castOp(s1); + + s0 = S0[i+2] - S1[i+2]*2 + S2[i+2] + _delta; + s1 = S0[i+3] - S1[i+3]*2 + S2[i+3] + _delta; + D[i+2] = castOp(s0); + D[i+3] = castOp(s1); + } + #else + for( ; i < width; i ++ ) + { + ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta; + D[i] = castOp(s0); + } + #endif + } + else + { + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta; + ST s1 = (S0[i+1] + S2[i+1])*f1 + S1[i+1]*f0 + _delta; + D[i] = castOp(s0); + D[i+1] = castOp(s1); + + s0 = (S0[i+2] + S2[i+2])*f1 + S1[i+2]*f0 + _delta; + s1 = (S0[i+3] + S2[i+3])*f1 + S1[i+3]*f0 + _delta; + D[i+2] = castOp(s0); + D[i+3] = castOp(s1); + } + #else + for( ; i < width; i ++ ) + { + ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta; + D[i] = castOp(s0); + } + #endif + } + for( ; i < width; i++ ) + D[i] = castOp((S0[i] + S2[i])*f1 + S1[i]*f0 + _delta); + } + else + { + if( is_m1_0_1 ) + { + if( f1 < 0 ) + std::swap(S0, S2); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST s0 = S2[i] - S0[i] + _delta; + ST s1 = S2[i+1] - S0[i+1] + _delta; + D[i] = castOp(s0); + D[i+1] = castOp(s1); + + s0 = S2[i+2] - S0[i+2] + _delta; + s1 = S2[i+3] - S0[i+3] + _delta; + D[i+2] = castOp(s0); + D[i+3] = castOp(s1); + } + #else + for( ; i < width; i ++ ) + { + ST s0 = S2[i] - S0[i] + _delta; + D[i] = castOp(s0); + } + #endif + if( f1 < 0 ) + std::swap(S0, S2); + } + else + { + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + ST s0 = (S2[i] - S0[i])*f1 + _delta; + ST s1 = (S2[i+1] - S0[i+1])*f1 + _delta; + D[i] = castOp(s0); + D[i+1] = castOp(s1); + + s0 = (S2[i+2] - S0[i+2])*f1 + _delta; + s1 = (S2[i+3] - S0[i+3])*f1 + _delta; + D[i+2] = castOp(s0); + D[i+3] = castOp(s1); + } + #endif + } + + for( ; i < width; i++ ) + D[i] = castOp((S2[i] - S0[i])*f1 + _delta); + } + } + } +}; + +template struct Cast +{ + typedef ST type1; + typedef DT rtype; + + DT operator()(ST val) const { return saturate_cast
(val); } +}; + +template struct FixedPtCast +{ + typedef ST type1; + typedef DT rtype; + enum { SHIFT = bits, DELTA = 1 << (bits-1) }; + + DT operator()(ST val) const { return saturate_cast
((val + DELTA)>>SHIFT); } +}; + +template struct FixedPtCastEx +{ + typedef ST type1; + typedef DT rtype; + + FixedPtCastEx() : SHIFT(0), DELTA(0) {} + FixedPtCastEx(int bits) : SHIFT(bits), DELTA(bits ? 1 << (bits-1) : 0) {} + DT operator()(ST val) const { return saturate_cast
((val + DELTA)>>SHIFT); } + int SHIFT, DELTA; +}; + +} + +cv::Ptr cv::getLinearRowFilter( int srcType, int bufType, + InputArray _kernel, int anchor, + int symmetryType ) +{ + Mat kernel = _kernel.getMat(); + int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(bufType); + int cn = CV_MAT_CN(srcType); + CV_Assert( cn == CV_MAT_CN(bufType) && + ddepth >= std::max(sdepth, CV_32S) && + kernel.type() == ddepth ); + int ksize = kernel.rows + kernel.cols - 1; + + if( (symmetryType & (KERNEL_SYMMETRICAL|KERNEL_ASYMMETRICAL)) != 0 && ksize <= 5 ) + { + if( sdepth == CV_8U && ddepth == CV_32S ) + return Ptr(new SymmRowSmallFilter + (kernel, anchor, symmetryType, SymmRowSmallVec_8u32s(kernel, symmetryType))); + if( sdepth == CV_32F && ddepth == CV_32F ) + return Ptr(new SymmRowSmallFilter + (kernel, anchor, symmetryType, SymmRowSmallVec_32f(kernel, symmetryType))); + } + + if( sdepth == CV_8U && ddepth == CV_32S ) + return Ptr(new RowFilter + (kernel, anchor, RowVec_8u32s(kernel))); + if( sdepth == CV_8U && ddepth == CV_32F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_8U && ddepth == CV_64F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_16U && ddepth == CV_32F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_16U && ddepth == CV_64F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_16S && ddepth == CV_32F ) + return Ptr(new RowFilter + (kernel, anchor, RowVec_16s32f(kernel))); + if( sdepth == CV_16S && ddepth == CV_64F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_32F && ddepth == CV_32F ) + return Ptr(new RowFilter + (kernel, anchor, RowVec_32f(kernel))); + if( sdepth == CV_32F && ddepth == CV_64F ) + return Ptr(new RowFilter(kernel, anchor)); + if( sdepth == CV_64F && ddepth == CV_64F ) + return Ptr(new RowFilter(kernel, anchor)); + + CV_Error_( CV_StsNotImplemented, + ("Unsupported combination of source format (=%d), and buffer format (=%d)", + srcType, bufType)); + + return Ptr(0); +} + + +cv::Ptr cv::getLinearColumnFilter( int bufType, int dstType, + InputArray _kernel, int anchor, + int symmetryType, double delta, + int bits ) +{ + Mat kernel = _kernel.getMat(); + int sdepth = CV_MAT_DEPTH(bufType), ddepth = CV_MAT_DEPTH(dstType); + int cn = CV_MAT_CN(dstType); + CV_Assert( cn == CV_MAT_CN(bufType) && + sdepth >= std::max(ddepth, CV_32S) && + kernel.type() == sdepth ); + + if( !(symmetryType & (KERNEL_SYMMETRICAL|KERNEL_ASYMMETRICAL)) ) + { + if( ddepth == CV_8U && sdepth == CV_32S ) + return Ptr(new ColumnFilter, ColumnNoVec> + (kernel, anchor, delta, FixedPtCastEx(bits))); + if( ddepth == CV_8U && sdepth == CV_32F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_8U && sdepth == CV_64F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_16U && sdepth == CV_32F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_16U && sdepth == CV_64F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_16S && sdepth == CV_32F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_16S && sdepth == CV_64F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_32F && sdepth == CV_32F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + if( ddepth == CV_64F && sdepth == CV_64F ) + return Ptr(new ColumnFilter, ColumnNoVec>(kernel, anchor, delta)); + } + else + { + int ksize = kernel.rows + kernel.cols - 1; + if( ksize == 3 ) + { + if( ddepth == CV_8U && sdepth == CV_32S ) + return Ptr(new SymmColumnSmallFilter< + FixedPtCastEx, SymmColumnVec_32s8u> + (kernel, anchor, delta, symmetryType, FixedPtCastEx(bits), + SymmColumnVec_32s8u(kernel, symmetryType, bits, delta))); + if( ddepth == CV_16S && sdepth == CV_32S && bits == 0 ) + return Ptr(new SymmColumnSmallFilter, + SymmColumnSmallVec_32s16s>(kernel, anchor, delta, symmetryType, + Cast(), SymmColumnSmallVec_32s16s(kernel, symmetryType, bits, delta))); + if( ddepth == CV_32F && sdepth == CV_32F ) + return Ptr(new SymmColumnSmallFilter< + Cast,SymmColumnSmallVec_32f> + (kernel, anchor, delta, symmetryType, Cast(), + SymmColumnSmallVec_32f(kernel, symmetryType, 0, delta))); + } + if( ddepth == CV_8U && sdepth == CV_32S ) + return Ptr(new SymmColumnFilter, SymmColumnVec_32s8u> + (kernel, anchor, delta, symmetryType, FixedPtCastEx(bits), + SymmColumnVec_32s8u(kernel, symmetryType, bits, delta))); + if( ddepth == CV_8U && sdepth == CV_32F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_8U && sdepth == CV_64F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_16U && sdepth == CV_32F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_16U && sdepth == CV_64F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_16S && sdepth == CV_32S ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_16S && sdepth == CV_32F ) + return Ptr(new SymmColumnFilter, SymmColumnVec_32f16s> + (kernel, anchor, delta, symmetryType, Cast(), + SymmColumnVec_32f16s(kernel, symmetryType, 0, delta))); + if( ddepth == CV_16S && sdepth == CV_64F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + if( ddepth == CV_32F && sdepth == CV_32F ) + return Ptr(new SymmColumnFilter, SymmColumnVec_32f> + (kernel, anchor, delta, symmetryType, Cast(), + SymmColumnVec_32f(kernel, symmetryType, 0, delta))); + if( ddepth == CV_64F && sdepth == CV_64F ) + return Ptr(new SymmColumnFilter, ColumnNoVec> + (kernel, anchor, delta, symmetryType)); + } + + CV_Error_( CV_StsNotImplemented, + ("Unsupported combination of buffer format (=%d), and destination format (=%d)", + bufType, dstType)); + + return Ptr(0); +} + + +cv::Ptr cv::createSeparableLinearFilter( + int _srcType, int _dstType, + InputArray __rowKernel, InputArray __columnKernel, + Point _anchor, double _delta, + int _rowBorderType, int _columnBorderType, + const Scalar& _borderValue ) +{ + Mat _rowKernel = __rowKernel.getMat(), _columnKernel = __columnKernel.getMat(); + _srcType = CV_MAT_TYPE(_srcType); + _dstType = CV_MAT_TYPE(_dstType); + int sdepth = CV_MAT_DEPTH(_srcType), ddepth = CV_MAT_DEPTH(_dstType); + int cn = CV_MAT_CN(_srcType); + CV_Assert( cn == CV_MAT_CN(_dstType) ); + int rsize = _rowKernel.rows + _rowKernel.cols - 1; + int csize = _columnKernel.rows + _columnKernel.cols - 1; + if( _anchor.x < 0 ) + _anchor.x = rsize/2; + if( _anchor.y < 0 ) + _anchor.y = csize/2; + int rtype = getKernelType(_rowKernel, + _rowKernel.rows == 1 ? Point(_anchor.x, 0) : Point(0, _anchor.x)); + int ctype = getKernelType(_columnKernel, + _columnKernel.rows == 1 ? Point(_anchor.y, 0) : Point(0, _anchor.y)); + Mat rowKernel, columnKernel; + + int bdepth = std::max(CV_32F,std::max(sdepth, ddepth)); + int bits = 0; + + if( sdepth == CV_8U && + ((rtype == KERNEL_SMOOTH+KERNEL_SYMMETRICAL && + ctype == KERNEL_SMOOTH+KERNEL_SYMMETRICAL && + ddepth == CV_8U) || + ((rtype & (KERNEL_SYMMETRICAL+KERNEL_ASYMMETRICAL)) && + (ctype & (KERNEL_SYMMETRICAL+KERNEL_ASYMMETRICAL)) && + (rtype & ctype & KERNEL_INTEGER) && + ddepth == CV_16S)) ) + { + bdepth = CV_32S; + bits = ddepth == CV_8U ? 8 : 0; + _rowKernel.convertTo( rowKernel, CV_32S, 1 << bits ); + _columnKernel.convertTo( columnKernel, CV_32S, 1 << bits ); + bits *= 2; + _delta *= (1 << bits); + } + else + { + if( _rowKernel.type() != bdepth ) + _rowKernel.convertTo( rowKernel, bdepth ); + else + rowKernel = _rowKernel; + if( _columnKernel.type() != bdepth ) + _columnKernel.convertTo( columnKernel, bdepth ); + else + columnKernel = _columnKernel; + } + + int _bufType = CV_MAKETYPE(bdepth, cn); + Ptr _rowFilter = getLinearRowFilter( + _srcType, _bufType, rowKernel, _anchor.x, rtype); + Ptr _columnFilter = getLinearColumnFilter( + _bufType, _dstType, columnKernel, _anchor.y, ctype, _delta, bits ); + + return Ptr( new FilterEngine(Ptr(0), _rowFilter, _columnFilter, + _srcType, _dstType, _bufType, _rowBorderType, _columnBorderType, _borderValue )); +} + + +/****************************************************************************************\ +* Non-separable linear filter * +\****************************************************************************************/ + +namespace cv +{ + +void preprocess2DKernel( const Mat& kernel, vector& coords, vector& coeffs ) +{ + int i, j, k, nz = countNonZero(kernel), ktype = kernel.type(); + if(nz == 0) + nz = 1; + CV_Assert( ktype == CV_8U || ktype == CV_32S || ktype == CV_32F || ktype == CV_64F ); + coords.resize(nz); + coeffs.resize(nz*getElemSize(ktype)); + uchar* _coeffs = &coeffs[0]; + + for( i = k = 0; i < kernel.rows; i++ ) + { + const uchar* krow = kernel.data + kernel.step*i; + for( j = 0; j < kernel.cols; j++ ) + { + if( ktype == CV_8U ) + { + uchar val = krow[j]; + if( val == 0 ) + continue; + coords[k] = Point(j,i); + _coeffs[k++] = val; + } + else if( ktype == CV_32S ) + { + int val = ((const int*)krow)[j]; + if( val == 0 ) + continue; + coords[k] = Point(j,i); + ((int*)_coeffs)[k++] = val; + } + else if( ktype == CV_32F ) + { + float val = ((const float*)krow)[j]; + if( val == 0 ) + continue; + coords[k] = Point(j,i); + ((float*)_coeffs)[k++] = val; + } + else + { + double val = ((const double*)krow)[j]; + if( val == 0 ) + continue; + coords[k] = Point(j,i); + ((double*)_coeffs)[k++] = val; + } + } + } +} + + +template struct Filter2D : public BaseFilter +{ + typedef typename CastOp::type1 KT; + typedef typename CastOp::rtype DT; + + Filter2D( const Mat& _kernel, Point _anchor, + double _delta, const CastOp& _castOp=CastOp(), + const VecOp& _vecOp=VecOp() ) + { + anchor = _anchor; + ksize = _kernel.size(); + delta = saturate_cast(_delta); + castOp0 = _castOp; + vecOp = _vecOp; + CV_Assert( _kernel.type() == DataType::type ); + preprocess2DKernel( _kernel, coords, coeffs ); + ptrs.resize( coords.size() ); + } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width, int cn) + { + KT _delta = delta; + const Point* pt = &coords[0]; + const KT* kf = (const KT*)&coeffs[0]; + const ST** kp = (const ST**)&ptrs[0]; + int i, k, nz = (int)coords.size(); + CastOp castOp = castOp0; + + width *= cn; + for( ; count > 0; count--, dst += dststep, src++ ) + { + DT* D = (DT*)dst; + + for( k = 0; k < nz; k++ ) + kp[k] = (const ST*)src[pt[k].y] + pt[k].x*cn; + + i = vecOp((const uchar**)kp, dst, width); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + KT s0 = _delta, s1 = _delta, s2 = _delta, s3 = _delta; + + for( k = 0; k < nz; k++ ) + { + const ST* sptr = kp[k] + i; + KT f = kf[k]; + s0 += f*sptr[0]; + s1 += f*sptr[1]; + s2 += f*sptr[2]; + s3 += f*sptr[3]; + } + + D[i] = castOp(s0); D[i+1] = castOp(s1); + D[i+2] = castOp(s2); D[i+3] = castOp(s3); + } + #endif + for( ; i < width; i++ ) + { + KT s0 = _delta; + for( k = 0; k < nz; k++ ) + s0 += kf[k]*kp[k][i]; + D[i] = castOp(s0); + } + } + } + + vector coords; + vector coeffs; + vector ptrs; + KT delta; + CastOp castOp0; + VecOp vecOp; +}; + +} + +cv::Ptr cv::getLinearFilter(int srcType, int dstType, + InputArray filter_kernel, Point anchor, + double delta, int bits) +{ + Mat _kernel = filter_kernel.getMat(); + int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(dstType); + int cn = CV_MAT_CN(srcType), kdepth = _kernel.depth(); + CV_Assert( cn == CV_MAT_CN(dstType) && ddepth >= sdepth ); + + anchor = normalizeAnchor(anchor, _kernel.size()); + + /*if( sdepth == CV_8U && ddepth == CV_8U && kdepth == CV_32S ) + return Ptr(new Filter2D, FilterVec_8u> + (_kernel, anchor, delta, FixedPtCastEx(bits), + FilterVec_8u(_kernel, bits, delta))); + if( sdepth == CV_8U && ddepth == CV_16S && kdepth == CV_32S ) + return Ptr(new Filter2D, FilterVec_8u16s> + (_kernel, anchor, delta, FixedPtCastEx(bits), + FilterVec_8u16s(_kernel, bits, delta)));*/ + + kdepth = sdepth == CV_64F || ddepth == CV_64F ? CV_64F : CV_32F; + Mat kernel; + if( _kernel.type() == kdepth ) + kernel = _kernel; + else + _kernel.convertTo(kernel, kdepth, _kernel.type() == CV_32S ? 1./(1 << bits) : 1.); + + if( sdepth == CV_8U && ddepth == CV_8U ) + return Ptr(new Filter2D, FilterVec_8u> + (kernel, anchor, delta, Cast(), FilterVec_8u(kernel, 0, delta))); + if( sdepth == CV_8U && ddepth == CV_16U ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_8U && ddepth == CV_16S ) + return Ptr(new Filter2D, FilterVec_8u16s> + (kernel, anchor, delta, Cast(), FilterVec_8u16s(kernel, 0, delta))); + if( sdepth == CV_8U && ddepth == CV_32F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_8U && ddepth == CV_64F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + + if( sdepth == CV_16U && ddepth == CV_16U ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_16U && ddepth == CV_32F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_16U && ddepth == CV_64F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + + if( sdepth == CV_16S && ddepth == CV_16S ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_16S && ddepth == CV_32F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + if( sdepth == CV_16S && ddepth == CV_64F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + + if( sdepth == CV_32F && ddepth == CV_32F ) + return Ptr(new Filter2D, FilterVec_32f> + (kernel, anchor, delta, Cast(), FilterVec_32f(kernel, 0, delta))); + if( sdepth == CV_64F && ddepth == CV_64F ) + return Ptr(new Filter2D, FilterNoVec>(kernel, anchor, delta)); + + CV_Error_( CV_StsNotImplemented, + ("Unsupported combination of source format (=%d), and destination format (=%d)", + srcType, dstType)); + + return Ptr(0); +} + + +cv::Ptr cv::createLinearFilter( int _srcType, int _dstType, + InputArray filter_kernel, + Point _anchor, double _delta, + int _rowBorderType, int _columnBorderType, + const Scalar& _borderValue ) +{ + Mat _kernel = filter_kernel.getMat(); + _srcType = CV_MAT_TYPE(_srcType); + _dstType = CV_MAT_TYPE(_dstType); + int cn = CV_MAT_CN(_srcType); + CV_Assert( cn == CV_MAT_CN(_dstType) ); + + Mat kernel = _kernel; + int bits = 0; + + /*int sdepth = CV_MAT_DEPTH(_srcType), ddepth = CV_MAT_DEPTH(_dstType); + int ktype = _kernel.depth() == CV_32S ? KERNEL_INTEGER : getKernelType(_kernel, _anchor); + if( sdepth == CV_8U && (ddepth == CV_8U || ddepth == CV_16S) && + _kernel.rows*_kernel.cols <= (1 << 10) ) + { + bits = (ktype & KERNEL_INTEGER) ? 0 : 11; + _kernel.convertTo(kernel, CV_32S, 1 << bits); + }*/ + + Ptr _filter2D = getLinearFilter(_srcType, _dstType, + kernel, _anchor, _delta, bits); + + return Ptr(new FilterEngine(_filter2D, Ptr(0), + Ptr(0), _srcType, _dstType, _srcType, + _rowBorderType, _columnBorderType, _borderValue )); +} + + +void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth, + InputArray _kernel, Point anchor, + double delta, int borderType ) +{ + Mat src = _src.getMat(), kernel = _kernel.getMat(); + + if( ddepth < 0 ) + ddepth = src.depth(); + +#if CV_SSE2 + int dft_filter_size = ((src.depth() == CV_8U && (ddepth == CV_8U || ddepth == CV_16S)) || + (src.depth() == CV_32F && ddepth == CV_32F)) && checkHardwareSupport(CV_CPU_SSE3)? 130 : 50; +#else + int dft_filter_size = 50; +#endif + + _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + Mat dst = _dst.getMat(); + anchor = normalizeAnchor(anchor, kernel.size()); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if( tegra::filter2D(src, dst, kernel, anchor, delta, borderType) ) + return; +#endif + + if( kernel.cols*kernel.rows >= dft_filter_size ) + { + Mat temp; + if( src.data != dst.data ) + temp = dst; + else + temp.create(dst.size(), dst.type()); + crossCorr( src, kernel, temp, src.size(), + CV_MAKETYPE(ddepth, src.channels()), + anchor, delta, borderType ); + if( temp.data != dst.data ) + temp.copyTo(dst); + return; + } + + Ptr f = createLinearFilter(src.type(), dst.type(), kernel, + anchor, delta, borderType & ~BORDER_ISOLATED ); + f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 ); +} + + +void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth, + InputArray _kernelX, InputArray _kernelY, Point anchor, + double delta, int borderType ) +{ + Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat(); + + if( ddepth < 0 ) + ddepth = src.depth(); + + _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); + Mat dst = _dst.getMat(); + + Ptr f = createSeparableLinearFilter(src.type(), + dst.type(), kernelX, kernelY, anchor, delta, borderType & ~BORDER_ISOLATED ); + f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 ); +} + + +CV_IMPL void +cvFilter2D( const CvArr* srcarr, CvArr* dstarr, const CvMat* _kernel, CvPoint anchor ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + cv::Mat kernel = cv::cvarrToMat(_kernel); + + CV_Assert( src.size() == dst.size() && src.channels() == dst.channels() ); + + cv::filter2D( src, dst, dst.depth(), kernel, anchor, 0, cv::BORDER_REPLICATE ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/floodfill.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/floodfill.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/floodfill.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/floodfill.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,649 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +typedef struct CvFFillSegment +{ + ushort y; + ushort l; + ushort r; + ushort prevl; + ushort prevr; + short dir; +} +CvFFillSegment; + +#define UP 1 +#define DOWN -1 + +#define ICV_PUSH( Y, L, R, PREV_L, PREV_R, DIR ) \ +{ \ + tail->y = (ushort)(Y); \ + tail->l = (ushort)(L); \ + tail->r = (ushort)(R); \ + tail->prevl = (ushort)(PREV_L); \ + tail->prevr = (ushort)(PREV_R); \ + tail->dir = (short)(DIR); \ + if( ++tail == buffer_end ) \ + { \ + buffer->resize(buffer->size() * 2); \ + tail = &buffer->front() + (tail - head); \ + head = &buffer->front(); \ + buffer_end = head + buffer->size(); \ + } \ +} + +#define ICV_POP( Y, L, R, PREV_L, PREV_R, DIR ) \ +{ \ + --tail; \ + Y = tail->y; \ + L = tail->l; \ + R = tail->r; \ + PREV_L = tail->prevl; \ + PREV_R = tail->prevr; \ + DIR = tail->dir; \ +} + +/****************************************************************************************\ +* Simple Floodfill (repainting single-color connected component) * +\****************************************************************************************/ + +template +static void +icvFloodFill_CnIR( uchar* pImage, int step, CvSize roi, CvPoint seed, + _Tp newVal, CvConnectedComp* region, int flags, + std::vector* buffer ) +{ + typedef typename cv::DataType<_Tp>::channel_type _CTp; + _Tp* img = (_Tp*)(pImage + step * seed.y); + int i, L, R; + int area = 0; + int XMin, XMax, YMin = seed.y, YMax = seed.y; + int _8_connectivity = (flags & 255) == 8; + CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); + + L = R = XMin = XMax = seed.x; + + _Tp val0 = img[L]; + img[L] = newVal; + + while( ++R < roi.width && img[R] == val0 ) + img[R] = newVal; + + while( --L >= 0 && img[L] == val0 ) + img[L] = newVal; + + XMax = --R; + XMin = ++L; + + ICV_PUSH( seed.y, L, R, R + 1, R, UP ); + + while( head != tail ) + { + int k, YC, PL, PR, dir; + ICV_POP( YC, L, R, PL, PR, dir ); + + int data[][3] = + { + {-dir, L - _8_connectivity, R + _8_connectivity}, + {dir, L - _8_connectivity, PL - 1}, + {dir, PR + 1, R + _8_connectivity} + }; + + if( region ) + { + area += R - L + 1; + + if( XMax < R ) XMax = R; + if( XMin > L ) XMin = L; + if( YMax < YC ) YMax = YC; + if( YMin > YC ) YMin = YC; + } + + for( k = 0; k < 3; k++ ) + { + dir = data[k][0]; + img = (_Tp*)(pImage + (YC + dir) * step); + int left = data[k][1]; + int right = data[k][2]; + + if( (unsigned)(YC + dir) >= (unsigned)roi.height ) + continue; + + for( i = left; i <= right; i++ ) + { + if( (unsigned)i < (unsigned)roi.width && img[i] == val0 ) + { + int j = i; + img[i] = newVal; + while( --j >= 0 && img[j] == val0 ) + img[j] = newVal; + + while( ++i < roi.width && img[i] == val0 ) + img[i] = newVal; + + ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); + } + } + } + } + + if( region ) + { + region->area = area; + region->rect.x = XMin; + region->rect.y = YMin; + region->rect.width = XMax - XMin + 1; + region->rect.height = YMax - YMin + 1; + region->value = cv::Scalar(newVal); + } +} + +/****************************************************************************************\ +* Gradient Floodfill * +\****************************************************************************************/ + +struct Diff8uC1 +{ + Diff8uC1(uchar _lo, uchar _up) : lo(_lo), interval(_lo + _up) {} + bool operator()(const uchar* a, const uchar* b) const + { return (unsigned)(a[0] - b[0] + lo) <= interval; } + unsigned lo, interval; +}; + +struct Diff8uC3 +{ + Diff8uC3(cv::Vec3b _lo, cv::Vec3b _up) + { + for( int k = 0; k < 3; k++ ) + lo[k] = _lo[k], interval[k] = _lo[k] + _up[k]; + } + bool operator()(const cv::Vec3b* a, const cv::Vec3b* b) const + { + return (unsigned)(a[0][0] - b[0][0] + lo[0]) <= interval[0] && + (unsigned)(a[0][1] - b[0][1] + lo[1]) <= interval[1] && + (unsigned)(a[0][2] - b[0][2] + lo[2]) <= interval[2]; + } + unsigned lo[3], interval[3]; +}; + +template +struct DiffC1 +{ + DiffC1(_Tp _lo, _Tp _up) : lo(-_lo), up(_up) {} + bool operator()(const _Tp* a, const _Tp* b) const + { + _Tp d = a[0] - b[0]; + return lo <= d && d <= up; + } + _Tp lo, up; +}; + +template +struct DiffC3 +{ + DiffC3(_Tp _lo, _Tp _up) : lo(-_lo), up(_up) {} + bool operator()(const _Tp* a, const _Tp* b) const + { + _Tp d = *a - *b; + return lo[0] <= d[0] && d[0] <= up[0] && + lo[1] <= d[1] && d[1] <= up[1] && + lo[2] <= d[2] && d[2] <= up[2]; + } + _Tp lo, up; +}; + +typedef DiffC1 Diff32sC1; +typedef DiffC3 Diff32sC3; +typedef DiffC1 Diff32fC1; +typedef DiffC3 Diff32fC3; + +static cv::Vec3i& operator += (cv::Vec3i& a, const cv::Vec3b& b) +{ + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + return a; +} + +template +static void +icvFloodFillGrad_CnIR( uchar* pImage, int step, uchar* pMask, int maskStep, + CvSize /*roi*/, CvPoint seed, _Tp newVal, Diff diff, + CvConnectedComp* region, int flags, + std::vector* buffer ) +{ + typedef typename cv::DataType<_Tp>::channel_type _CTp; + _Tp* img = (_Tp*)(pImage + step*seed.y); + uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y; + int i, L, R; + int area = 0; + _WTp sum = _WTp((typename cv::DataType<_Tp>::channel_type)0); + int XMin, XMax, YMin = seed.y, YMax = seed.y; + int _8_connectivity = (flags & 255) == 8; + int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE; + int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0; + uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1); + CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); + + L = R = seed.x; + if( mask[L] ) + return; + + mask[L] = newMaskVal; + _Tp val0 = img[L]; + + if( fixedRange ) + { + while( !mask[R + 1] && diff( img + (R+1), &val0 )) + mask[++R] = newMaskVal; + + while( !mask[L - 1] && diff( img + (L-1), &val0 )) + mask[--L] = newMaskVal; + } + else + { + while( !mask[R + 1] && diff( img + (R+1), img + R )) + mask[++R] = newMaskVal; + + while( !mask[L - 1] && diff( img + (L-1), img + L )) + mask[--L] = newMaskVal; + } + + XMax = R; + XMin = L; + + ICV_PUSH( seed.y, L, R, R + 1, R, UP ); + + while( head != tail ) + { + int k, YC, PL, PR, dir; + ICV_POP( YC, L, R, PL, PR, dir ); + + int data[][3] = + { + {-dir, L - _8_connectivity, R + _8_connectivity}, + {dir, L - _8_connectivity, PL - 1}, + {dir, PR + 1, R + _8_connectivity} + }; + + unsigned length = (unsigned)(R-L); + + if( region ) + { + area += (int)length + 1; + + if( XMax < R ) XMax = R; + if( XMin > L ) XMin = L; + if( YMax < YC ) YMax = YC; + if( YMin > YC ) YMin = YC; + } + + for( k = 0; k < 3; k++ ) + { + dir = data[k][0]; + img = (_Tp*)(pImage + (YC + dir) * step); + _Tp* img1 = (_Tp*)(pImage + YC * step); + mask = pMask + (YC + dir) * maskStep; + int left = data[k][1]; + int right = data[k][2]; + + if( fixedRange ) + for( i = left; i <= right; i++ ) + { + if( !mask[i] && diff( img + i, &val0 )) + { + int j = i; + mask[i] = newMaskVal; + while( !mask[--j] && diff( img + j, &val0 )) + mask[j] = newMaskVal; + + while( !mask[++i] && diff( img + i, &val0 )) + mask[i] = newMaskVal; + + ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); + } + } + else if( !_8_connectivity ) + for( i = left; i <= right; i++ ) + { + if( !mask[i] && diff( img + i, img1 + i )) + { + int j = i; + mask[i] = newMaskVal; + while( !mask[--j] && diff( img + j, img + (j+1) )) + mask[j] = newMaskVal; + + while( !mask[++i] && + (diff( img + i, img + (i-1) ) || + (diff( img + i, img1 + i) && i <= R))) + mask[i] = newMaskVal; + + ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); + } + } + else + for( i = left; i <= right; i++ ) + { + int idx; + _Tp val; + + if( !mask[i] && + (((val = img[i], + (unsigned)(idx = i-L-1) <= length) && + diff( &val, img1 + (i-1))) || + ((unsigned)(++idx) <= length && + diff( &val, img1 + i )) || + ((unsigned)(++idx) <= length && + diff( &val, img1 + (i+1) )))) + { + int j = i; + mask[i] = newMaskVal; + while( !mask[--j] && diff( img + j, img + (j+1) )) + mask[j] = newMaskVal; + + while( !mask[++i] && + ((val = img[i], + diff( &val, img + (i-1) )) || + (((unsigned)(idx = i-L-1) <= length && + diff( &val, img1 + (i-1) ))) || + ((unsigned)(++idx) <= length && + diff( &val, img1 + i )) || + ((unsigned)(++idx) <= length && + diff( &val, img1 + (i+1) )))) + mask[i] = newMaskVal; + + ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); + } + } + } + + img = (_Tp*)(pImage + YC * step); + if( fillImage ) + for( i = L; i <= R; i++ ) + img[i] = newVal; + else if( region ) + for( i = L; i <= R; i++ ) + sum += img[i]; + } + + if( region ) + { + region->area = area; + region->rect.x = XMin; + region->rect.y = YMin; + region->rect.width = XMax - XMin + 1; + region->rect.height = YMax - YMin + 1; + + if( fillImage ) + region->value = cv::Scalar(newVal); + else + { + double iarea = area ? 1./area : 0; + region->value = cv::Scalar(sum*iarea); + } + } +} + + +/****************************************************************************************\ +* External Functions * +\****************************************************************************************/ + +typedef void (*CvFloodFillFunc)( + void* img, int step, CvSize size, CvPoint seed, void* newval, + CvConnectedComp* comp, int flags, void* buffer, int cn ); + +typedef void (*CvFloodFillGradFunc)( + void* img, int step, uchar* mask, int maskStep, CvSize size, + CvPoint seed, void* newval, void* d_lw, void* d_up, void* ccomp, + int flags, void* buffer, int cn ); + +CV_IMPL void +cvFloodFill( CvArr* arr, CvPoint seed_point, + CvScalar newVal, CvScalar lo_diff, CvScalar up_diff, + CvConnectedComp* comp, int flags, CvArr* maskarr ) +{ + cv::Ptr tempMask; + std::vector buffer; + + if( comp ) + memset( comp, 0, sizeof(*comp) ); + + int i, type, depth, cn, is_simple; + int buffer_size, connectivity = flags & 255; + union { + uchar b[4]; + int i[4]; + float f[4]; + double _[4]; + } nv_buf; + nv_buf._[0] = nv_buf._[1] = nv_buf._[2] = nv_buf._[3] = 0; + + struct { cv::Vec3b b; cv::Vec3i i; cv::Vec3f f; } ld_buf, ud_buf; + CvMat stub, *img = cvGetMat(arr, &stub); + CvMat maskstub, *mask = (CvMat*)maskarr; + CvSize size; + + type = CV_MAT_TYPE( img->type ); + depth = CV_MAT_DEPTH(type); + cn = CV_MAT_CN(type); + + if( connectivity == 0 ) + connectivity = 4; + else if( connectivity != 4 && connectivity != 8 ) + CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); + + is_simple = mask == 0 && (flags & CV_FLOODFILL_MASK_ONLY) == 0; + + for( i = 0; i < cn; i++ ) + { + if( lo_diff.val[i] < 0 || up_diff.val[i] < 0 ) + CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); + is_simple &= fabs(lo_diff.val[i]) < DBL_EPSILON && fabs(up_diff.val[i]) < DBL_EPSILON; + } + + size = cvGetMatSize( img ); + + if( (unsigned)seed_point.x >= (unsigned)size.width || + (unsigned)seed_point.y >= (unsigned)size.height ) + CV_Error( CV_StsOutOfRange, "Seed point is outside of image" ); + + cvScalarToRawData( &newVal, &nv_buf, type, 0 ); + buffer_size = MAX( size.width, size.height ) * 2; + buffer.resize( buffer_size ); + + if( is_simple ) + { + int elem_size = CV_ELEM_SIZE(type); + const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x; + + for(i = 0; i < elem_size; i++) + if (seed_ptr[i] != nv_buf.b[i]) + break; + + if (i != elem_size) + { + if( type == CV_8UC1 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.b[0], + comp, flags, &buffer); + else if( type == CV_8UC3 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3b(nv_buf.b), + comp, flags, &buffer); + else if( type == CV_32SC1 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.i[0], + comp, flags, &buffer); + else if( type == CV_32FC1 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.f[0], + comp, flags, &buffer); + else if( type == CV_32SC3 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3i(nv_buf.i), + comp, flags, &buffer); + else if( type == CV_32FC3 ) + icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3f(nv_buf.f), + comp, flags, &buffer); + else + CV_Error( CV_StsUnsupportedFormat, "" ); + return; + } + } + + if( !mask ) + { + /* created mask will be 8-byte aligned */ + tempMask = cvCreateMat( size.height + 2, (size.width + 9) & -8, CV_8UC1 ); + mask = tempMask; + } + else + { + mask = cvGetMat( mask, &maskstub ); + if( !CV_IS_MASK_ARR( mask )) + CV_Error( CV_StsBadMask, "" ); + + if( mask->width != size.width + 2 || mask->height != size.height + 2 ) + CV_Error( CV_StsUnmatchedSizes, "mask must be 2 pixel wider " + "and 2 pixel taller than filled image" ); + } + + int width = tempMask ? mask->step : size.width + 2; + uchar* mask_row = mask->data.ptr + mask->step; + memset( mask_row - mask->step, 1, width ); + + for( i = 1; i <= size.height; i++, mask_row += mask->step ) + { + if( tempMask ) + memset( mask_row, 0, width ); + mask_row[0] = mask_row[size.width+1] = (uchar)1; + } + memset( mask_row, 1, width ); + + if( depth == CV_8U ) + for( i = 0; i < cn; i++ ) + { + int t = cvFloor(lo_diff.val[i]); + ld_buf.b[i] = CV_CAST_8U(t); + t = cvFloor(up_diff.val[i]); + ud_buf.b[i] = CV_CAST_8U(t); + } + else if( depth == CV_32S ) + for( i = 0; i < cn; i++ ) + { + int t = cvFloor(lo_diff.val[i]); + ld_buf.i[i] = t; + t = cvFloor(up_diff.val[i]); + ud_buf.i[i] = t; + } + else if( depth == CV_32F ) + for( i = 0; i < cn; i++ ) + { + ld_buf.f[i] = (float)lo_diff.val[i]; + ud_buf.f[i] = (float)up_diff.val[i]; + } + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + if( type == CV_8UC1 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, nv_buf.b[0], + Diff8uC1(ld_buf.b[0], ud_buf.b[0]), + comp, flags, &buffer); + else if( type == CV_8UC3 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, cv::Vec3b(nv_buf.b), + Diff8uC3(ld_buf.b, ud_buf.b), + comp, flags, &buffer); + else if( type == CV_32SC1 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, nv_buf.i[0], + Diff32sC1(ld_buf.i[0], ud_buf.i[0]), + comp, flags, &buffer); + else if( type == CV_32SC3 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, cv::Vec3i(nv_buf.i), + Diff32sC3(ld_buf.i, ud_buf.i), + comp, flags, &buffer); + else if( type == CV_32FC1 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, nv_buf.f[0], + Diff32fC1(ld_buf.f[0], ud_buf.f[0]), + comp, flags, &buffer); + else if( type == CV_32FC3 ) + icvFloodFillGrad_CnIR( + img->data.ptr, img->step, mask->data.ptr, mask->step, + size, seed_point, cv::Vec3f(nv_buf.f), + Diff32fC3(ld_buf.f, ud_buf.f), + comp, flags, &buffer); + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +int cv::floodFill( InputOutputArray _image, Point seedPoint, + Scalar newVal, Rect* rect, + Scalar loDiff, Scalar upDiff, int flags ) +{ + CvConnectedComp ccomp; + CvMat c_image = _image.getMat(); + cvFloodFill(&c_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, 0); + if( rect ) + *rect = ccomp.rect; + return cvRound(ccomp.area); +} + +int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, + Point seedPoint, Scalar newVal, Rect* rect, + Scalar loDiff, Scalar upDiff, int flags ) +{ + CvConnectedComp ccomp; + CvMat c_image = _image.getMat(), c_mask = _mask.getMat(); + cvFloodFill(&c_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, c_mask.data.ptr ? &c_mask : 0); + if( rect ) + *rect = ccomp.rect; + return cvRound(ccomp.area); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/gabor.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/gabor.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/gabor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/gabor.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/* + Gabor filters and such. To be greatly extended to have full texture analysis. + For the formulas and the explanation of the parameters see: + http://en.wikipedia.org/wiki/Gabor_filter +*/ + +cv::Mat cv::getGaborKernel( Size ksize, double sigma, double theta, + double lambd, double gamma, double psi, int ktype ) +{ + double sigma_x = sigma; + double sigma_y = sigma/gamma; + int nstds = 3; + int xmin, xmax, ymin, ymax; + double c = cos(theta), s = sin(theta); + + if( ksize.width > 0 ) + xmax = ksize.width/2; + else + xmax = cvRound(std::max(fabs(nstds*sigma_x*c), fabs(nstds*sigma_y*s))); + + if( ksize.height > 0 ) + ymax = ksize.height/2; + else + ymax = cvRound(std::max(fabs(nstds*sigma_x*s), fabs(nstds*sigma_y*c))); + + xmin = -xmax; + ymin = -ymax; + + CV_Assert( ktype == CV_32F || ktype == CV_64F ); + + Mat kernel(ymax - ymin + 1, xmax - xmin + 1, ktype); + double scale = 1; + double ex = -0.5/(sigma_x*sigma_x); + double ey = -0.5/(sigma_y*sigma_y); + double cscale = CV_PI*2/lambd; + + for( int y = ymin; y <= ymax; y++ ) + for( int x = xmin; x <= xmax; x++ ) + { + double xr = x*c + y*s; + double yr = -x*s + y*c; + + double v = scale*exp(ex*xr*xr + ey*yr*yr)*cos(cscale*xr + psi); + if( ktype == CV_32F ) + kernel.at(ymax - y, xmax - x) = (float)v; + else + kernel.at(ymax - y, xmax - x) = v; + } + + return kernel; +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/gcgraph.hpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/gcgraph.hpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/gcgraph.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/gcgraph.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,385 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef _CV_GCGRAPH_H_ +#define _CV_GCGRAPH_H_ + +template class GCGraph +{ +public: + GCGraph(); + GCGraph( unsigned int vtxCount, unsigned int edgeCount ); + ~GCGraph(); + void create( unsigned int vtxCount, unsigned int edgeCount ); + int addVtx(); + void addEdges( int i, int j, TWeight w, TWeight revw ); + void addTermWeights( int i, TWeight sourceW, TWeight sinkW ); + TWeight maxFlow(); + bool inSourceSegment( int i ); +private: + class Vtx + { + public: + Vtx *next; // initialized and used in maxFlow() only + int parent; + int first; + int ts; + int dist; + TWeight weight; + uchar t; + }; + class Edge + { + public: + int dst; + int next; + TWeight weight; + }; + + std::vector vtcs; + std::vector edges; + TWeight flow; +}; + +template +GCGraph::GCGraph() +{ + flow = 0; +} +template +GCGraph::GCGraph( unsigned int vtxCount, unsigned int edgeCount ) +{ + create( vtxCount, edgeCount ); +} +template +GCGraph::~GCGraph() +{ +} +template +void GCGraph::create( unsigned int vtxCount, unsigned int edgeCount ) +{ + vtcs.reserve( vtxCount ); + edges.reserve( edgeCount + 2 ); + flow = 0; +} + +template +int GCGraph::addVtx() +{ + Vtx v; + memset( &v, 0, sizeof(Vtx)); + vtcs.push_back(v); + return (int)vtcs.size() - 1; +} + +template +void GCGraph::addEdges( int i, int j, TWeight w, TWeight revw ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + CV_Assert( j>=0 && j<(int)vtcs.size() ); + CV_Assert( w>=0 && revw>=0 ); + CV_Assert( i != j ); + + if( !edges.size() ) + edges.resize( 2 ); + + Edge fromI, toI; + fromI.dst = j; + fromI.next = vtcs[i].first; + fromI.weight = w; + vtcs[i].first = (int)edges.size(); + edges.push_back( fromI ); + + toI.dst = i; + toI.next = vtcs[j].first; + toI.weight = revw; + vtcs[j].first = (int)edges.size(); + edges.push_back( toI ); +} + +template +void GCGraph::addTermWeights( int i, TWeight sourceW, TWeight sinkW ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + + TWeight dw = vtcs[i].weight; + if( dw > 0 ) + sourceW += dw; + else + sinkW -= dw; + flow += (sourceW < sinkW) ? sourceW : sinkW; + vtcs[i].weight = sourceW - sinkW; +} + +template +TWeight GCGraph::maxFlow() +{ + const int TERMINAL = -1, ORPHAN = -2; + Vtx stub, *nilNode = &stub, *first = nilNode, *last = nilNode; + int curr_ts = 0; + stub.next = nilNode; + Vtx *vtxPtr = &vtcs[0]; + Edge *edgePtr = &edges[0]; + + std::vector orphans; + + // initialize the active queue and the graph vertices + for( int i = 0; i < (int)vtcs.size(); i++ ) + { + Vtx* v = vtxPtr + i; + v->ts = 0; + if( v->weight != 0 ) + { + last = last->next = v; + v->dist = 1; + v->parent = TERMINAL; + v->t = v->weight < 0; + } + else + v->parent = 0; + } + first = first->next; + last->next = nilNode; + nilNode->next = 0; + + // run the search-path -> augment-graph -> restore-trees loop + for(;;) + { + Vtx* v, *u; + int e0 = -1, ei = 0, ej = 0; + TWeight minWeight, weight; + uchar vt; + + // grow S & T search trees, find an edge connecting them + while( first != nilNode ) + { + v = first; + if( v->parent ) + { + vt = v->t; + for( ei = v->first; ei != 0; ei = edgePtr[ei].next ) + { + if( edgePtr[ei^vt].weight == 0 ) + continue; + u = vtxPtr+edgePtr[ei].dst; + if( !u->parent ) + { + u->t = vt; + u->parent = ei ^ 1; + u->ts = v->ts; + u->dist = v->dist + 1; + if( !u->next ) + { + u->next = nilNode; + last = last->next = u; + } + continue; + } + + if( u->t != vt ) + { + e0 = ei ^ vt; + break; + } + + if( u->dist > v->dist+1 && u->ts <= v->ts ) + { + // reassign the parent + u->parent = ei ^ 1; + u->ts = v->ts; + u->dist = v->dist + 1; + } + } + if( e0 > 0 ) + break; + } + // exclude the vertex from the active list + first = first->next; + v->next = 0; + } + + if( e0 <= 0 ) + break; + + // find the minimum edge weight along the path + minWeight = edgePtr[e0].weight; + assert( minWeight > 0 ); + // k = 1: source tree, k = 0: destination tree + for( int k = 1; k >= 0; k-- ) + { + for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst ) + { + if( (ei = v->parent) < 0 ) + break; + weight = edgePtr[ei^k].weight; + minWeight = MIN(minWeight, weight); + assert( minWeight > 0 ); + } + weight = fabs(v->weight); + minWeight = MIN(minWeight, weight); + assert( minWeight > 0 ); + } + + // modify weights of the edges along the path and collect orphans + edgePtr[e0].weight -= minWeight; + edgePtr[e0^1].weight += minWeight; + flow += minWeight; + + // k = 1: source tree, k = 0: destination tree + for( int k = 1; k >= 0; k-- ) + { + for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst ) + { + if( (ei = v->parent) < 0 ) + break; + edgePtr[ei^(k^1)].weight += minWeight; + if( (edgePtr[ei^k].weight -= minWeight) == 0 ) + { + orphans.push_back(v); + v->parent = ORPHAN; + } + } + + v->weight = v->weight + minWeight*(1-k*2); + if( v->weight == 0 ) + { + orphans.push_back(v); + v->parent = ORPHAN; + } + } + + // restore the search trees by finding new parents for the orphans + curr_ts++; + while( !orphans.empty() ) + { + Vtx* v2 = orphans.back(); + orphans.pop_back(); + + int d, minDist = INT_MAX; + e0 = 0; + vt = v2->t; + + for( ei = v2->first; ei != 0; ei = edgePtr[ei].next ) + { + if( edgePtr[ei^(vt^1)].weight == 0 ) + continue; + u = vtxPtr+edgePtr[ei].dst; + if( u->t != vt || u->parent == 0 ) + continue; + // compute the distance to the tree root + for( d = 0;; ) + { + if( u->ts == curr_ts ) + { + d += u->dist; + break; + } + ej = u->parent; + d++; + if( ej < 0 ) + { + if( ej == ORPHAN ) + d = INT_MAX-1; + else + { + u->ts = curr_ts; + u->dist = 1; + } + break; + } + u = vtxPtr+edgePtr[ej].dst; + } + + // update the distance + if( ++d < INT_MAX ) + { + if( d < minDist ) + { + minDist = d; + e0 = ei; + } + for( u = vtxPtr+edgePtr[ei].dst; u->ts != curr_ts; u = vtxPtr+edgePtr[u->parent].dst ) + { + u->ts = curr_ts; + u->dist = --d; + } + } + } + + if( (v2->parent = e0) > 0 ) + { + v2->ts = curr_ts; + v2->dist = minDist; + continue; + } + + /* no parent is found */ + v2->ts = 0; + for( ei = v2->first; ei != 0; ei = edgePtr[ei].next ) + { + u = vtxPtr+edgePtr[ei].dst; + ej = u->parent; + if( u->t != vt || !ej ) + continue; + if( edgePtr[ei^(vt^1)].weight && !u->next ) + { + u->next = nilNode; + last = last->next = u; + } + if( ej > 0 && vtxPtr+edgePtr[ej].dst == v2 ) + { + orphans.push_back(u); + u->parent = ORPHAN; + } + } + } + } + return flow; +} + +template +bool GCGraph::inSourceSegment( int i ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + return vtcs[i].t == 0; +}; + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/generalized_hough.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/generalized_hough.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/generalized_hough.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/generalized_hough.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1290 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include + +using namespace std; +using namespace cv; + +namespace +{ + ///////////////////////////////////// + // Common + + template void releaseVector(vector& v) + { + vector empty; + empty.swap(v); + } + + double toRad(double a) + { + return a * CV_PI / 180.0; + } + + bool notNull(float v) + { + return fabs(v) > numeric_limits::epsilon(); + } + + class GHT_Pos : public GeneralizedHough + { + public: + GHT_Pos(); + + protected: + void setTemplateImpl(const Mat& edges, const Mat& dx, const Mat& dy, Point templCenter); + void detectImpl(const Mat& edges, const Mat& dx, const Mat& dy, OutputArray positions, OutputArray votes); + void releaseImpl(); + + virtual void processTempl() = 0; + virtual void processImage() = 0; + + void filterMinDist(); + void convertTo(OutputArray positions, OutputArray votes); + + double minDist; + + Size templSize; + Point templCenter; + Mat templEdges; + Mat templDx; + Mat templDy; + + Size imageSize; + Mat imageEdges; + Mat imageDx; + Mat imageDy; + + vector posOutBuf; + vector voteOutBuf; + }; + + GHT_Pos::GHT_Pos() + { + minDist = 1.0; + } + + void GHT_Pos::setTemplateImpl(const Mat& edges, const Mat& dx, const Mat& dy, Point templCenter_) + { + templSize = edges.size(); + templCenter = templCenter_; + edges.copyTo(templEdges); + dx.copyTo(templDx); + dy.copyTo(templDy); + + processTempl(); + } + + void GHT_Pos::detectImpl(const Mat& edges, const Mat& dx, const Mat& dy, OutputArray positions, OutputArray votes) + { + imageSize = edges.size(); + edges.copyTo(imageEdges); + dx.copyTo(imageDx); + dy.copyTo(imageDy); + + posOutBuf.clear(); + voteOutBuf.clear(); + + processImage(); + + if (!posOutBuf.empty()) + { + if (minDist > 1) + filterMinDist(); + convertTo(positions, votes); + } + else + { + positions.release(); + if (votes.needed()) + votes.release(); + } + } + + void GHT_Pos::releaseImpl() + { + templSize = Size(); + templCenter = Point(-1, -1); + templEdges.release(); + templDx.release(); + templDy.release(); + + imageSize = Size(); + imageEdges.release(); + imageDx.release(); + imageDy.release(); + + releaseVector(posOutBuf); + releaseVector(voteOutBuf); + } + + #define votes_cmp_gt(l1, l2) (aux[l1][0] > aux[l2][0]) + static CV_IMPLEMENT_QSORT_EX( sortIndexies, size_t, votes_cmp_gt, const Vec3i* ) + + void GHT_Pos::filterMinDist() + { + size_t oldSize = posOutBuf.size(); + const bool hasVotes = !voteOutBuf.empty(); + + CV_Assert(!hasVotes || voteOutBuf.size() == oldSize); + + vector oldPosBuf(posOutBuf); + vector oldVoteBuf(voteOutBuf); + + vector indexies(oldSize); + for (size_t i = 0; i < oldSize; ++i) + indexies[i] = i; + sortIndexies(&indexies[0], oldSize, &oldVoteBuf[0]); + + posOutBuf.clear(); + voteOutBuf.clear(); + + const int cellSize = cvRound(minDist); + const int gridWidth = (imageSize.width + cellSize - 1) / cellSize; + const int gridHeight = (imageSize.height + cellSize - 1) / cellSize; + + vector< vector > grid(gridWidth * gridHeight); + + const double minDist2 = minDist * minDist; + + for (size_t i = 0; i < oldSize; ++i) + { + const size_t ind = indexies[i]; + + Point2f p(oldPosBuf[ind][0], oldPosBuf[ind][1]); + + bool good = true; + + const int xCell = static_cast(p.x / cellSize); + const int yCell = static_cast(p.y / cellSize); + + int x1 = xCell - 1; + int y1 = yCell - 1; + int x2 = xCell + 1; + int y2 = yCell + 1; + + // boundary check + x1 = std::max(0, x1); + y1 = std::max(0, y1); + x2 = std::min(gridWidth - 1, x2); + y2 = std::min(gridHeight - 1, y2); + + for (int yy = y1; yy <= y2; ++yy) + { + for (int xx = x1; xx <= x2; ++xx) + { + const vector& m = grid[yy * gridWidth + xx]; + + for(size_t j = 0; j < m.size(); ++j) + { + const Point2f d = p - m[j]; + + if (d.ddot(d) < minDist2) + { + good = false; + goto break_out; + } + } + } + } + + break_out: + + if(good) + { + grid[yCell * gridWidth + xCell].push_back(p); + + posOutBuf.push_back(oldPosBuf[ind]); + if (hasVotes) + voteOutBuf.push_back(oldVoteBuf[ind]); + } + } + } + + void GHT_Pos::convertTo(OutputArray _positions, OutputArray _votes) + { + const int total = static_cast(posOutBuf.size()); + const bool hasVotes = !voteOutBuf.empty(); + + CV_Assert(!hasVotes || voteOutBuf.size() == posOutBuf.size()); + + _positions.create(1, total, CV_32FC4); + Mat positions = _positions.getMat(); + Mat(1, total, CV_32FC4, &posOutBuf[0]).copyTo(positions); + + if (_votes.needed()) + { + if (!hasVotes) + _votes.release(); + else + { + _votes.create(1, total, CV_32SC3); + Mat votes = _votes.getMat(); + Mat(1, total, CV_32SC3, &voteOutBuf[0]).copyTo(votes); + } + } + } + + ///////////////////////////////////// + // POSITION Ballard + + class GHT_Ballard_Pos : public GHT_Pos + { + public: + AlgorithmInfo* info() const; + + GHT_Ballard_Pos(); + + protected: + void releaseImpl(); + + void processTempl(); + void processImage(); + + virtual void calcHist(); + virtual void findPosInHist(); + + int levels; + int votesThreshold; + double dp; + + vector< vector > r_table; + Mat hist; + }; + + CV_INIT_ALGORITHM(GHT_Ballard_Pos, "GeneralizedHough.POSITION", + obj.info()->addParam(obj, "minDist", obj.minDist, false, 0, 0, + "Minimum distance between the centers of the detected objects."); + obj.info()->addParam(obj, "levels", obj.levels, false, 0, 0, + "R-Table levels."); + obj.info()->addParam(obj, "votesThreshold", obj.votesThreshold, false, 0, 0, + "The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected."); + obj.info()->addParam(obj, "dp", obj.dp, false, 0, 0, + "Inverse ratio of the accumulator resolution to the image resolution.")); + + GHT_Ballard_Pos::GHT_Ballard_Pos() + { + levels = 360; + votesThreshold = 100; + dp = 1.0; + } + + void GHT_Ballard_Pos::releaseImpl() + { + GHT_Pos::releaseImpl(); + + releaseVector(r_table); + hist.release(); + } + + void GHT_Ballard_Pos::processTempl() + { + CV_Assert(templEdges.type() == CV_8UC1); + CV_Assert(templDx.type() == CV_32FC1 && templDx.size() == templSize); + CV_Assert(templDy.type() == templDx.type() && templDy.size() == templSize); + CV_Assert(levels > 0); + + const double thetaScale = levels / 360.0; + + r_table.resize(levels + 1); + for_each(r_table.begin(), r_table.end(), mem_fun_ref(&vector::clear)); + + for (int y = 0; y < templSize.height; ++y) + { + const uchar* edgesRow = templEdges.ptr(y); + const float* dxRow = templDx.ptr(y); + const float* dyRow = templDy.ptr(y); + + for (int x = 0; x < templSize.width; ++x) + { + const Point p(x, y); + + if (edgesRow[x] && (notNull(dyRow[x]) || notNull(dxRow[x]))) + { + const float theta = fastAtan2(dyRow[x], dxRow[x]); + const int n = cvRound(theta * thetaScale); + r_table[n].push_back(p - templCenter); + } + } + } + } + + void GHT_Ballard_Pos::processImage() + { + calcHist(); + findPosInHist(); + } + + void GHT_Ballard_Pos::calcHist() + { + CV_Assert(imageEdges.type() == CV_8UC1); + CV_Assert(imageDx.type() == CV_32FC1 && imageDx.size() == imageSize); + CV_Assert(imageDy.type() == imageDx.type() && imageDy.size() == imageSize); + CV_Assert(levels > 0 && r_table.size() == static_cast(levels + 1)); + CV_Assert(dp > 0.0); + + const double thetaScale = levels / 360.0; + const double idp = 1.0 / dp; + + hist.create(cvCeil(imageSize.height * idp) + 2, cvCeil(imageSize.width * idp) + 2, CV_32SC1); + hist.setTo(0); + + const int rows = hist.rows - 2; + const int cols = hist.cols - 2; + + for (int y = 0; y < imageSize.height; ++y) + { + const uchar* edgesRow = imageEdges.ptr(y); + const float* dxRow = imageDx.ptr(y); + const float* dyRow = imageDy.ptr(y); + + for (int x = 0; x < imageSize.width; ++x) + { + const Point p(x, y); + + if (edgesRow[x] && (notNull(dyRow[x]) || notNull(dxRow[x]))) + { + const float theta = fastAtan2(dyRow[x], dxRow[x]); + const int n = cvRound(theta * thetaScale); + + const vector& r_row = r_table[n]; + + for (size_t j = 0; j < r_row.size(); ++j) + { + Point c = p - r_row[j]; + + c.x = cvRound(c.x * idp); + c.y = cvRound(c.y * idp); + + if (c.x >= 0 && c.x < cols && c.y >= 0 && c.y < rows) + ++hist.at(c.y + 1, c.x + 1); + } + } + } + } + } + + void GHT_Ballard_Pos::findPosInHist() + { + CV_Assert(votesThreshold > 0); + + const int histRows = hist.rows - 2; + const int histCols = hist.cols - 2; + + for(int y = 0; y < histRows; ++y) + { + const int* prevRow = hist.ptr(y); + const int* curRow = hist.ptr(y + 1); + const int* nextRow = hist.ptr(y + 2); + + for(int x = 0; x < histCols; ++x) + { + const int votes = curRow[x + 1]; + + if (votes > votesThreshold && votes > curRow[x] && votes >= curRow[x + 2] && votes > prevRow[x + 1] && votes >= nextRow[x + 1]) + { + posOutBuf.push_back(Vec4f(static_cast(x * dp), static_cast(y * dp), 1.0f, 0.0f)); + voteOutBuf.push_back(Vec3i(votes, 0, 0)); + } + } + } + } + + ///////////////////////////////////// + // POSITION & SCALE + + class GHT_Ballard_PosScale : public GHT_Ballard_Pos + { + public: + AlgorithmInfo* info() const; + + GHT_Ballard_PosScale(); + + protected: + void calcHist(); + void findPosInHist(); + + double minScale; + double maxScale; + double scaleStep; + + class Worker; + friend class Worker; + }; + + CV_INIT_ALGORITHM(GHT_Ballard_PosScale, "GeneralizedHough.POSITION_SCALE", + obj.info()->addParam(obj, "minDist", obj.minDist, false, 0, 0, + "Minimum distance between the centers of the detected objects."); + obj.info()->addParam(obj, "levels", obj.levels, false, 0, 0, + "R-Table levels."); + obj.info()->addParam(obj, "votesThreshold", obj.votesThreshold, false, 0, 0, + "The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected."); + obj.info()->addParam(obj, "dp", obj.dp, false, 0, 0, + "Inverse ratio of the accumulator resolution to the image resolution."); + obj.info()->addParam(obj, "minScale", obj.minScale, false, 0, 0, + "Minimal scale to detect."); + obj.info()->addParam(obj, "maxScale", obj.maxScale, false, 0, 0, + "Maximal scale to detect."); + obj.info()->addParam(obj, "scaleStep", obj.scaleStep, false, 0, 0, + "Scale step.")); + + GHT_Ballard_PosScale::GHT_Ballard_PosScale() + { + minScale = 0.5; + maxScale = 2.0; + scaleStep = 0.05; + } + + class GHT_Ballard_PosScale::Worker : public ParallelLoopBody + { + public: + explicit Worker(GHT_Ballard_PosScale* base_) : base(base_) {} + + void operator ()(const Range& range) const; + + private: + GHT_Ballard_PosScale* base; + }; + + void GHT_Ballard_PosScale::Worker::operator ()(const Range& range) const + { + const double thetaScale = base->levels / 360.0; + const double idp = 1.0 / base->dp; + + for (int s = range.start; s < range.end; ++s) + { + const double scale = base->minScale + s * base->scaleStep; + + Mat curHist(base->hist.size[1], base->hist.size[2], CV_32SC1, base->hist.ptr(s + 1), base->hist.step[1]); + + for (int y = 0; y < base->imageSize.height; ++y) + { + const uchar* edgesRow = base->imageEdges.ptr(y); + const float* dxRow = base->imageDx.ptr(y); + const float* dyRow = base->imageDy.ptr(y); + + for (int x = 0; x < base->imageSize.width; ++x) + { + const Point2d p(x, y); + + if (edgesRow[x] && (notNull(dyRow[x]) || notNull(dxRow[x]))) + { + const float theta = fastAtan2(dyRow[x], dxRow[x]); + const int n = cvRound(theta * thetaScale); + + const vector& r_row = base->r_table[n]; + + for (size_t j = 0; j < r_row.size(); ++j) + { + Point2d d = r_row[j]; + Point2d c = p - d * scale; + + c.x *= idp; + c.y *= idp; + + if (c.x >= 0 && c.x < base->hist.size[2] - 2 && c.y >= 0 && c.y < base->hist.size[1] - 2) + ++curHist.at(cvRound(c.y + 1), cvRound(c.x + 1)); + } + } + } + } + } + } + + void GHT_Ballard_PosScale::calcHist() + { + CV_Assert(imageEdges.type() == CV_8UC1); + CV_Assert(imageDx.type() == CV_32FC1 && imageDx.size() == imageSize); + CV_Assert(imageDy.type() == imageDx.type() && imageDy.size() == imageSize); + CV_Assert(levels > 0 && r_table.size() == static_cast(levels + 1)); + CV_Assert(dp > 0.0); + CV_Assert(minScale > 0.0 && minScale < maxScale); + CV_Assert(scaleStep > 0.0); + + const double idp = 1.0 / dp; + const int scaleRange = cvCeil((maxScale - minScale) / scaleStep); + + const int sizes[] = {scaleRange + 2, cvCeil(imageSize.height * idp) + 2, cvCeil(imageSize.width * idp) + 2}; + hist.create(3, sizes, CV_32SC1); + hist.setTo(0); + + parallel_for_(Range(0, scaleRange), Worker(this)); + } + + void GHT_Ballard_PosScale::findPosInHist() + { + CV_Assert(votesThreshold > 0); + + const int scaleRange = hist.size[0] - 2; + const int histRows = hist.size[1] - 2; + const int histCols = hist.size[2] - 2; + + for (int s = 0; s < scaleRange; ++s) + { + const float scale = static_cast(minScale + s * scaleStep); + + const Mat prevHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(s), hist.step[1]); + const Mat curHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(s + 1), hist.step[1]); + const Mat nextHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(s + 2), hist.step[1]); + + for(int y = 0; y < histRows; ++y) + { + const int* prevHistRow = prevHist.ptr(y + 1); + const int* prevRow = curHist.ptr(y); + const int* curRow = curHist.ptr(y + 1); + const int* nextRow = curHist.ptr(y + 2); + const int* nextHistRow = nextHist.ptr(y + 1); + + for(int x = 0; x < histCols; ++x) + { + const int votes = curRow[x + 1]; + + if (votes > votesThreshold && + votes > curRow[x] && + votes >= curRow[x + 2] && + votes > prevRow[x + 1] && + votes >= nextRow[x + 1] && + votes > prevHistRow[x + 1] && + votes >= nextHistRow[x + 1]) + { + posOutBuf.push_back(Vec4f(static_cast(x * dp), static_cast(y * dp), scale, 0.0f)); + voteOutBuf.push_back(Vec3i(votes, votes, 0)); + } + } + } + } + } + + ///////////////////////////////////// + // POSITION & ROTATION + + class GHT_Ballard_PosRotation : public GHT_Ballard_Pos + { + public: + AlgorithmInfo* info() const; + + GHT_Ballard_PosRotation(); + + protected: + void calcHist(); + void findPosInHist(); + + double minAngle; + double maxAngle; + double angleStep; + + class Worker; + friend class Worker; + }; + + CV_INIT_ALGORITHM(GHT_Ballard_PosRotation, "GeneralizedHough.POSITION_ROTATION", + obj.info()->addParam(obj, "minDist", obj.minDist, false, 0, 0, + "Minimum distance between the centers of the detected objects."); + obj.info()->addParam(obj, "levels", obj.levels, false, 0, 0, + "R-Table levels."); + obj.info()->addParam(obj, "votesThreshold", obj.votesThreshold, false, 0, 0, + "The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected."); + obj.info()->addParam(obj, "dp", obj.dp, false, 0, 0, + "Inverse ratio of the accumulator resolution to the image resolution."); + obj.info()->addParam(obj, "minAngle", obj.minAngle, false, 0, 0, + "Minimal rotation angle to detect in degrees."); + obj.info()->addParam(obj, "maxAngle", obj.maxAngle, false, 0, 0, + "Maximal rotation angle to detect in degrees."); + obj.info()->addParam(obj, "angleStep", obj.angleStep, false, 0, 0, + "Angle step in degrees.")); + + GHT_Ballard_PosRotation::GHT_Ballard_PosRotation() + { + minAngle = 0.0; + maxAngle = 360.0; + angleStep = 1.0; + } + + class GHT_Ballard_PosRotation::Worker : public ParallelLoopBody + { + public: + explicit Worker(GHT_Ballard_PosRotation* base_) : base(base_) {} + + void operator ()(const Range& range) const; + + private: + GHT_Ballard_PosRotation* base; + }; + + void GHT_Ballard_PosRotation::Worker::operator ()(const Range& range) const + { + const double thetaScale = base->levels / 360.0; + const double idp = 1.0 / base->dp; + + for (int a = range.start; a < range.end; ++a) + { + const double angle = base->minAngle + a * base->angleStep; + + const double sinA = ::sin(toRad(angle)); + const double cosA = ::cos(toRad(angle)); + + Mat curHist(base->hist.size[1], base->hist.size[2], CV_32SC1, base->hist.ptr(a + 1), base->hist.step[1]); + + for (int y = 0; y < base->imageSize.height; ++y) + { + const uchar* edgesRow = base->imageEdges.ptr(y); + const float* dxRow = base->imageDx.ptr(y); + const float* dyRow = base->imageDy.ptr(y); + + for (int x = 0; x < base->imageSize.width; ++x) + { + const Point2d p(x, y); + + if (edgesRow[x] && (notNull(dyRow[x]) || notNull(dxRow[x]))) + { + double theta = fastAtan2(dyRow[x], dxRow[x]) - angle; + if (theta < 0) + theta += 360.0; + const int n = cvRound(theta * thetaScale); + + const vector& r_row = base->r_table[n]; + + for (size_t j = 0; j < r_row.size(); ++j) + { + Point2d d = r_row[j]; + Point2d c = p - Point2d(d.x * cosA - d.y * sinA, d.x * sinA + d.y * cosA); + + c.x *= idp; + c.y *= idp; + + if (c.x >= 0 && c.x < base->hist.size[2] - 2 && c.y >= 0 && c.y < base->hist.size[1] - 2) + ++curHist.at(cvRound(c.y + 1), cvRound(c.x + 1)); + } + } + } + } + } + } + + void GHT_Ballard_PosRotation::calcHist() + { + CV_Assert(imageEdges.type() == CV_8UC1); + CV_Assert(imageDx.type() == CV_32FC1 && imageDx.size() == imageSize); + CV_Assert(imageDy.type() == imageDx.type() && imageDy.size() == imageSize); + CV_Assert(levels > 0 && r_table.size() == static_cast(levels + 1)); + CV_Assert(dp > 0.0); + CV_Assert(minAngle >= 0.0 && minAngle < maxAngle && maxAngle <= 360.0); + CV_Assert(angleStep > 0.0 && angleStep < 360.0); + + const double idp = 1.0 / dp; + const int angleRange = cvCeil((maxAngle - minAngle) / angleStep); + + const int sizes[] = {angleRange + 2, cvCeil(imageSize.height * idp) + 2, cvCeil(imageSize.width * idp) + 2}; + hist.create(3, sizes, CV_32SC1); + hist.setTo(0); + + parallel_for_(Range(0, angleRange), Worker(this)); + } + + void GHT_Ballard_PosRotation::findPosInHist() + { + CV_Assert(votesThreshold > 0); + + const int angleRange = hist.size[0] - 2; + const int histRows = hist.size[1] - 2; + const int histCols = hist.size[2] - 2; + + for (int a = 0; a < angleRange; ++a) + { + const float angle = static_cast(minAngle + a * angleStep); + + const Mat prevHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(a), hist.step[1]); + const Mat curHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(a + 1), hist.step[1]); + const Mat nextHist(histRows + 2, histCols + 2, CV_32SC1, hist.ptr(a + 2), hist.step[1]); + + for(int y = 0; y < histRows; ++y) + { + const int* prevHistRow = prevHist.ptr(y + 1); + const int* prevRow = curHist.ptr(y); + const int* curRow = curHist.ptr(y + 1); + const int* nextRow = curHist.ptr(y + 2); + const int* nextHistRow = nextHist.ptr(y + 1); + + for(int x = 0; x < histCols; ++x) + { + const int votes = curRow[x + 1]; + + if (votes > votesThreshold && + votes > curRow[x] && + votes >= curRow[x + 2] && + votes > prevRow[x + 1] && + votes >= nextRow[x + 1] && + votes > prevHistRow[x + 1] && + votes >= nextHistRow[x + 1]) + { + posOutBuf.push_back(Vec4f(static_cast(x * dp), static_cast(y * dp), 1.0f, angle)); + voteOutBuf.push_back(Vec3i(votes, 0, votes)); + } + } + } + } + } + + ///////////////////////////////////////// + // POSITION & SCALE & ROTATION + + double clampAngle(double a) + { + double res = a; + + while (res > 360.0) + res -= 360.0; + while (res < 0) + res += 360.0; + + return res; + } + + bool angleEq(double a, double b, double eps = 1.0) + { + return (fabs(clampAngle(a - b)) <= eps); + } + + class GHT_Guil_Full : public GHT_Pos + { + public: + AlgorithmInfo* info() const; + + GHT_Guil_Full(); + + protected: + void releaseImpl(); + + void processTempl(); + void processImage(); + + struct ContourPoint + { + Point2d pos; + double theta; + }; + + struct Feature + { + ContourPoint p1; + ContourPoint p2; + + double alpha12; + double d12; + + Point2d r1; + Point2d r2; + }; + + void buildFeatureList(const Mat& edges, const Mat& dx, const Mat& dy, vector< vector >& features, Point2d center = Point2d()); + void getContourPoints(const Mat& edges, const Mat& dx, const Mat& dy, vector& points); + + void calcOrientation(); + void calcScale(double angle); + void calcPosition(double angle, int angleVotes, double scale, int scaleVotes); + + int maxSize; + double xi; + int levels; + double angleEpsilon; + + double minAngle; + double maxAngle; + double angleStep; + int angleThresh; + + double minScale; + double maxScale; + double scaleStep; + int scaleThresh; + + double dp; + int posThresh; + + vector< vector > templFeatures; + vector< vector > imageFeatures; + + vector< pair > angles; + vector< pair > scales; + }; + + CV_INIT_ALGORITHM(GHT_Guil_Full, "GeneralizedHough.POSITION_SCALE_ROTATION", + obj.info()->addParam(obj, "minDist", obj.minDist, false, 0, 0, + "Minimum distance between the centers of the detected objects."); + obj.info()->addParam(obj, "maxSize", obj.maxSize, false, 0, 0, + "Maximal size of inner buffers."); + obj.info()->addParam(obj, "xi", obj.xi, false, 0, 0, + "Angle difference in degrees between two points in feature."); + obj.info()->addParam(obj, "levels", obj.levels, false, 0, 0, + "Feature table levels."); + obj.info()->addParam(obj, "angleEpsilon", obj.angleEpsilon, false, 0, 0, + "Maximal difference between angles that treated as equal."); + obj.info()->addParam(obj, "minAngle", obj.minAngle, false, 0, 0, + "Minimal rotation angle to detect in degrees."); + obj.info()->addParam(obj, "maxAngle", obj.maxAngle, false, 0, 0, + "Maximal rotation angle to detect in degrees."); + obj.info()->addParam(obj, "angleStep", obj.angleStep, false, 0, 0, + "Angle step in degrees."); + obj.info()->addParam(obj, "angleThresh", obj.angleThresh, false, 0, 0, + "Angle threshold."); + obj.info()->addParam(obj, "minScale", obj.minScale, false, 0, 0, + "Minimal scale to detect."); + obj.info()->addParam(obj, "maxScale", obj.maxScale, false, 0, 0, + "Maximal scale to detect."); + obj.info()->addParam(obj, "scaleStep", obj.scaleStep, false, 0, 0, + "Scale step."); + obj.info()->addParam(obj, "scaleThresh", obj.scaleThresh, false, 0, 0, + "Scale threshold."); + obj.info()->addParam(obj, "dp", obj.dp, false, 0, 0, + "Inverse ratio of the accumulator resolution to the image resolution."); + obj.info()->addParam(obj, "posThresh", obj.posThresh, false, 0, 0, + "Position threshold.")); + + GHT_Guil_Full::GHT_Guil_Full() + { + maxSize = 1000; + xi = 90.0; + levels = 360; + angleEpsilon = 1.0; + + minAngle = 0.0; + maxAngle = 360.0; + angleStep = 1.0; + angleThresh = 15000; + + minScale = 0.5; + maxScale = 2.0; + scaleStep = 0.05; + scaleThresh = 1000; + + dp = 1.0; + posThresh = 100; + } + + void GHT_Guil_Full::releaseImpl() + { + GHT_Pos::releaseImpl(); + + releaseVector(templFeatures); + releaseVector(imageFeatures); + + releaseVector(angles); + releaseVector(scales); + } + + void GHT_Guil_Full::processTempl() + { + buildFeatureList(templEdges, templDx, templDy, templFeatures, templCenter); + } + + void GHT_Guil_Full::processImage() + { + buildFeatureList(imageEdges, imageDx, imageDy, imageFeatures); + + calcOrientation(); + + for (size_t i = 0; i < angles.size(); ++i) + { + const double angle = angles[i].first; + const int angleVotes = angles[i].second; + + calcScale(angle); + + for (size_t j = 0; j < scales.size(); ++j) + { + const double scale = scales[j].first; + const int scaleVotes = scales[j].second; + + calcPosition(angle, angleVotes, scale, scaleVotes); + } + } + } + + void GHT_Guil_Full::buildFeatureList(const Mat& edges, const Mat& dx, const Mat& dy, vector< vector >& features, Point2d center) + { + CV_Assert(levels > 0); + + const double maxDist = sqrt((double) templSize.width * templSize.width + templSize.height * templSize.height) * maxScale; + + const double alphaScale = levels / 360.0; + + vector points; + getContourPoints(edges, dx, dy, points); + + features.resize(levels + 1); + for_each(features.begin(), features.end(), mem_fun_ref(&vector::clear)); + for_each(features.begin(), features.end(), bind2nd(mem_fun_ref(&vector::reserve), maxSize)); + + for (size_t i = 0; i < points.size(); ++i) + { + ContourPoint p1 = points[i]; + + for (size_t j = 0; j < points.size(); ++j) + { + ContourPoint p2 = points[j]; + + if (angleEq(p1.theta - p2.theta, xi, angleEpsilon)) + { + const Point2d d = p1.pos - p2.pos; + + Feature f; + + f.p1 = p1; + f.p2 = p2; + + f.alpha12 = clampAngle(fastAtan2((float)d.y, (float)d.x) - p1.theta); + f.d12 = norm(d); + + if (f.d12 > maxDist) + continue; + + f.r1 = p1.pos - center; + f.r2 = p2.pos - center; + + const int n = cvRound(f.alpha12 * alphaScale); + + if (features[n].size() < static_cast(maxSize)) + features[n].push_back(f); + } + } + } + } + + void GHT_Guil_Full::getContourPoints(const Mat& edges, const Mat& dx, const Mat& dy, vector& points) + { + CV_Assert(edges.type() == CV_8UC1); + CV_Assert(dx.type() == CV_32FC1 && dx.size == edges.size); + CV_Assert(dy.type() == dx.type() && dy.size == edges.size); + + points.clear(); + points.reserve(edges.size().area()); + + for (int y = 0; y < edges.rows; ++y) + { + const uchar* edgesRow = edges.ptr(y); + const float* dxRow = dx.ptr(y); + const float* dyRow = dy.ptr(y); + + for (int x = 0; x < edges.cols; ++x) + { + if (edgesRow[x] && (notNull(dyRow[x]) || notNull(dxRow[x]))) + { + ContourPoint p; + + p.pos = Point2d(x, y); + p.theta = fastAtan2(dyRow[x], dxRow[x]); + + points.push_back(p); + } + } + } + } + + void GHT_Guil_Full::calcOrientation() + { + CV_Assert(levels > 0); + CV_Assert(templFeatures.size() == static_cast(levels + 1)); + CV_Assert(imageFeatures.size() == templFeatures.size()); + CV_Assert(minAngle >= 0.0 && minAngle < maxAngle && maxAngle <= 360.0); + CV_Assert(angleStep > 0.0 && angleStep < 360.0); + CV_Assert(angleThresh > 0); + + const double iAngleStep = 1.0 / angleStep; + const int angleRange = cvCeil((maxAngle - minAngle) * iAngleStep); + + vector OHist(angleRange + 1, 0); + for (int i = 0; i <= levels; ++i) + { + const vector& templRow = templFeatures[i]; + const vector& imageRow = imageFeatures[i]; + + for (size_t j = 0; j < templRow.size(); ++j) + { + Feature templF = templRow[j]; + + for (size_t k = 0; k < imageRow.size(); ++k) + { + Feature imF = imageRow[k]; + + const double angle = clampAngle(imF.p1.theta - templF.p1.theta); + if (angle >= minAngle && angle <= maxAngle) + { + const int n = cvRound((angle - minAngle) * iAngleStep); + ++OHist[n]; + } + } + } + } + + angles.clear(); + + for (int n = 0; n < angleRange; ++n) + { + if (OHist[n] >= angleThresh) + { + const double angle = minAngle + n * angleStep; + angles.push_back(make_pair(angle, OHist[n])); + } + } + } + + void GHT_Guil_Full::calcScale(double angle) + { + CV_Assert(levels > 0); + CV_Assert(templFeatures.size() == static_cast(levels + 1)); + CV_Assert(imageFeatures.size() == templFeatures.size()); + CV_Assert(minScale > 0.0 && minScale < maxScale); + CV_Assert(scaleStep > 0.0); + CV_Assert(scaleThresh > 0); + + const double iScaleStep = 1.0 / scaleStep; + const int scaleRange = cvCeil((maxScale - minScale) * iScaleStep); + + vector SHist(scaleRange + 1, 0); + + for (int i = 0; i <= levels; ++i) + { + const vector& templRow = templFeatures[i]; + const vector& imageRow = imageFeatures[i]; + + for (size_t j = 0; j < templRow.size(); ++j) + { + Feature templF = templRow[j]; + + templF.p1.theta += angle; + + for (size_t k = 0; k < imageRow.size(); ++k) + { + Feature imF = imageRow[k]; + + if (angleEq(imF.p1.theta, templF.p1.theta, angleEpsilon)) + { + const double scale = imF.d12 / templF.d12; + if (scale >= minScale && scale <= maxScale) + { + const int s = cvRound((scale - minScale) * iScaleStep); + ++SHist[s]; + } + } + } + } + } + + scales.clear(); + + for (int s = 0; s < scaleRange; ++s) + { + if (SHist[s] >= scaleThresh) + { + const double scale = minScale + s * scaleStep; + scales.push_back(make_pair(scale, SHist[s])); + } + } + } + + void GHT_Guil_Full::calcPosition(double angle, int angleVotes, double scale, int scaleVotes) + { + CV_Assert(levels > 0); + CV_Assert(templFeatures.size() == static_cast(levels + 1)); + CV_Assert(imageFeatures.size() == templFeatures.size()); + CV_Assert(dp > 0.0); + CV_Assert(posThresh > 0); + + const double sinVal = sin(toRad(angle)); + const double cosVal = cos(toRad(angle)); + const double idp = 1.0 / dp; + + const int histRows = cvCeil(imageSize.height * idp); + const int histCols = cvCeil(imageSize.width * idp); + + Mat DHist(histRows + 2, histCols + 2, CV_32SC1, Scalar::all(0)); + + for (int i = 0; i <= levels; ++i) + { + const vector& templRow = templFeatures[i]; + const vector& imageRow = imageFeatures[i]; + + for (size_t j = 0; j < templRow.size(); ++j) + { + Feature templF = templRow[j]; + + templF.p1.theta += angle; + + templF.r1 *= scale; + templF.r2 *= scale; + + templF.r1 = Point2d(cosVal * templF.r1.x - sinVal * templF.r1.y, sinVal * templF.r1.x + cosVal * templF.r1.y); + templF.r2 = Point2d(cosVal * templF.r2.x - sinVal * templF.r2.y, sinVal * templF.r2.x + cosVal * templF.r2.y); + + for (size_t k = 0; k < imageRow.size(); ++k) + { + Feature imF = imageRow[k]; + + if (angleEq(imF.p1.theta, templF.p1.theta, angleEpsilon)) + { + Point2d c1, c2; + + c1 = imF.p1.pos - templF.r1; + c1 *= idp; + + c2 = imF.p2.pos - templF.r2; + c2 *= idp; + + if (fabs(c1.x - c2.x) > 1 || fabs(c1.y - c2.y) > 1) + continue; + + if (c1.y >= 0 && c1.y < histRows && c1.x >= 0 && c1.x < histCols) + ++DHist.at(cvRound(c1.y) + 1, cvRound(c1.x) + 1); + } + } + } + } + + for(int y = 0; y < histRows; ++y) + { + const int* prevRow = DHist.ptr(y); + const int* curRow = DHist.ptr(y + 1); + const int* nextRow = DHist.ptr(y + 2); + + for(int x = 0; x < histCols; ++x) + { + const int votes = curRow[x + 1]; + + if (votes > posThresh && votes > curRow[x] && votes >= curRow[x + 2] && votes > prevRow[x + 1] && votes >= nextRow[x + 1]) + { + posOutBuf.push_back(Vec4f(static_cast(x * dp), static_cast(y * dp), static_cast(scale), static_cast(angle))); + voteOutBuf.push_back(Vec3i(votes, scaleVotes, angleVotes)); + } + } + } + } +} + +Ptr cv::GeneralizedHough::create(int method) +{ + switch (method) + { + case GHT_POSITION: + CV_Assert( !GHT_Ballard_Pos_info_auto.name().empty() ); + return new GHT_Ballard_Pos(); + + case (GHT_POSITION | GHT_SCALE): + CV_Assert( !GHT_Ballard_PosScale_info_auto.name().empty() ); + return new GHT_Ballard_PosScale(); + + case (GHT_POSITION | GHT_ROTATION): + CV_Assert( !GHT_Ballard_PosRotation_info_auto.name().empty() ); + return new GHT_Ballard_PosRotation(); + + case (GHT_POSITION | GHT_SCALE | GHT_ROTATION): + CV_Assert( !GHT_Guil_Full_info_auto.name().empty() ); + return new GHT_Guil_Full(); + } + + CV_Error(CV_StsBadArg, "Unsupported method"); + return Ptr(); +} + +cv::GeneralizedHough::~GeneralizedHough() +{ +} + +void cv::GeneralizedHough::setTemplate(InputArray _templ, int cannyThreshold, Point templCenter) +{ + Mat templ = _templ.getMat(); + + CV_Assert(templ.type() == CV_8UC1); + CV_Assert(cannyThreshold > 0); + + Canny(templ, edges_, cannyThreshold / 2, cannyThreshold); + Sobel(templ, dx_, CV_32F, 1, 0); + Sobel(templ, dy_, CV_32F, 0, 1); + + if (templCenter == Point(-1, -1)) + templCenter = Point(templ.cols / 2, templ.rows / 2); + + setTemplateImpl(edges_, dx_, dy_, templCenter); +} + +void cv::GeneralizedHough::setTemplate(InputArray _edges, InputArray _dx, InputArray _dy, Point templCenter) +{ + Mat edges = _edges.getMat(); + Mat dx = _dx.getMat(); + Mat dy = _dy.getMat(); + + if (templCenter == Point(-1, -1)) + templCenter = Point(edges.cols / 2, edges.rows / 2); + + setTemplateImpl(edges, dx, dy, templCenter); +} + +void cv::GeneralizedHough::detect(InputArray _image, OutputArray positions, OutputArray votes, int cannyThreshold) +{ + Mat image = _image.getMat(); + + CV_Assert(image.type() == CV_8UC1); + CV_Assert(cannyThreshold > 0); + + Canny(image, edges_, cannyThreshold / 2, cannyThreshold); + Sobel(image, dx_, CV_32F, 1, 0); + Sobel(image, dy_, CV_32F, 0, 1); + + detectImpl(edges_, dx_, dy_, positions, votes); +} + +void cv::GeneralizedHough::detect(InputArray _edges, InputArray _dx, InputArray _dy, OutputArray positions, OutputArray votes) +{ + cv::Mat edges = _edges.getMat(); + cv::Mat dx = _dx.getMat(); + cv::Mat dy = _dy.getMat(); + + detectImpl(edges, dx, dy, positions, votes); +} + +void cv::GeneralizedHough::release() +{ + edges_.release(); + dx_.release(); + dy_.release(); + releaseImpl(); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/geometry.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/geometry.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/geometry.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/geometry.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,774 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + + +CV_IMPL CvRect +cvMaxRect( const CvRect* rect1, const CvRect* rect2 ) +{ + if( rect1 && rect2 ) + { + CvRect max_rect; + int a, b; + + max_rect.x = a = rect1->x; + b = rect2->x; + if( max_rect.x > b ) + max_rect.x = b; + + max_rect.width = a += rect1->width; + b += rect2->width; + + if( max_rect.width < b ) + max_rect.width = b; + max_rect.width -= max_rect.x; + + max_rect.y = a = rect1->y; + b = rect2->y; + if( max_rect.y > b ) + max_rect.y = b; + + max_rect.height = a += rect1->height; + b += rect2->height; + + if( max_rect.height < b ) + max_rect.height = b; + max_rect.height -= max_rect.y; + return max_rect; + } + else if( rect1 ) + return *rect1; + else if( rect2 ) + return *rect2; + else + return cvRect(0,0,0,0); +} + + +CV_IMPL void +cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) +{ + if( !pt ) + CV_Error( CV_StsNullPtr, "NULL vertex array pointer" ); + cv::RotatedRect(box).points((cv::Point2f*)pt); +} + + +int +icvIntersectLines( double x1, double dx1, double y1, double dy1, + double x2, double dx2, double y2, double dy2, double *t2 ) +{ + double d = dx1 * dy2 - dx2 * dy1; + int result = -1; + + if( d != 0 ) + { + *t2 = ((x2 - x1) * dy1 - (y2 - y1) * dx1) / d; + result = 0; + } + return result; +} + + +void +icvIntersectLines3( double *a0, double *b0, double *c0, + double *a1, double *b1, double *c1, CvPoint2D32f * point ) +{ + double det = a0[0] * b1[0] - a1[0] * b0[0]; + + if( det != 0 ) + { + det = 1. / det; + point->x = (float) ((b0[0] * c1[0] - b1[0] * c0[0]) * det); + point->y = (float) ((a1[0] * c0[0] - a0[0] * c1[0]) * det); + } + else + { + point->x = point->y = FLT_MAX; + } +} + + +CV_IMPL double +cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) +{ + double result = 0; + + CvSeqBlock block; + CvContour header; + CvSeq* contour = (CvSeq*)_contour; + CvSeqReader reader; + int i, total, counter = 0; + int is_float; + double min_dist_num = FLT_MAX, min_dist_denom = 1; + CvPoint ip = {0,0}; + + if( !CV_IS_SEQ(contour) ) + { + contour = cvPointSeqFromMat( CV_SEQ_KIND_CURVE + CV_SEQ_FLAG_CLOSED, + _contour, &header, &block ); + } + else if( CV_IS_SEQ_POINT_SET(contour) ) + { + if( contour->header_size == sizeof(CvContour) && !measure_dist ) + { + CvRect r = ((CvContour*)contour)->rect; + if( pt.x < r.x || pt.y < r.y || + pt.x >= r.x + r.width || pt.y >= r.y + r.height ) + return -1; + } + } + else if( CV_IS_SEQ_CHAIN(contour) ) + { + CV_Error( CV_StsBadArg, + "Chains are not supported. Convert them to polygonal representation using cvApproxChains()" ); + } + else + CV_Error( CV_StsBadArg, "Input contour is neither a valid sequence nor a matrix" ); + + total = contour->total; + is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2; + cvStartReadSeq( contour, &reader, -1 ); + + if( !is_float && !measure_dist && (ip.x = cvRound(pt.x)) == pt.x && (ip.y = cvRound(pt.y)) == pt.y ) + { + // the fastest "pure integer" branch + CvPoint v0, v; + CV_READ_SEQ_ELEM( v, reader ); + + for( i = 0; i < total; i++ ) + { + int dist; + v0 = v; + CV_READ_SEQ_ELEM( v, reader ); + + if( (v0.y <= ip.y && v.y <= ip.y) || + (v0.y > ip.y && v.y > ip.y) || + (v0.x < ip.x && v.x < ip.x) ) + { + if( ip.y == v.y && (ip.x == v.x || (ip.y == v0.y && + ((v0.x <= ip.x && ip.x <= v.x) || (v.x <= ip.x && ip.x <= v0.x)))) ) + return 0; + continue; + } + + dist = (ip.y - v0.y)*(v.x - v0.x) - (ip.x - v0.x)*(v.y - v0.y); + if( dist == 0 ) + return 0; + if( v.y < v0.y ) + dist = -dist; + counter += dist > 0; + } + + result = counter % 2 == 0 ? -1 : 1; + } + else + { + CvPoint2D32f v0, v; + CvPoint iv; + + if( is_float ) + { + CV_READ_SEQ_ELEM( v, reader ); + } + else + { + CV_READ_SEQ_ELEM( iv, reader ); + v = cvPointTo32f( iv ); + } + + if( !measure_dist ) + { + for( i = 0; i < total; i++ ) + { + double dist; + v0 = v; + if( is_float ) + { + CV_READ_SEQ_ELEM( v, reader ); + } + else + { + CV_READ_SEQ_ELEM( iv, reader ); + v = cvPointTo32f( iv ); + } + + if( (v0.y <= pt.y && v.y <= pt.y) || + (v0.y > pt.y && v.y > pt.y) || + (v0.x < pt.x && v.x < pt.x) ) + { + if( pt.y == v.y && (pt.x == v.x || (pt.y == v0.y && + ((v0.x <= pt.x && pt.x <= v.x) || (v.x <= pt.x && pt.x <= v0.x)))) ) + return 0; + continue; + } + + dist = (double)(pt.y - v0.y)*(v.x - v0.x) - (double)(pt.x - v0.x)*(v.y - v0.y); + if( dist == 0 ) + return 0; + if( v.y < v0.y ) + dist = -dist; + counter += dist > 0; + } + + result = counter % 2 == 0 ? -1 : 1; + } + else + { + for( i = 0; i < total; i++ ) + { + double dx, dy, dx1, dy1, dx2, dy2, dist_num, dist_denom = 1; + + v0 = v; + if( is_float ) + { + CV_READ_SEQ_ELEM( v, reader ); + } + else + { + CV_READ_SEQ_ELEM( iv, reader ); + v = cvPointTo32f( iv ); + } + + dx = v.x - v0.x; dy = v.y - v0.y; + dx1 = pt.x - v0.x; dy1 = pt.y - v0.y; + dx2 = pt.x - v.x; dy2 = pt.y - v.y; + + if( dx1*dx + dy1*dy <= 0 ) + dist_num = dx1*dx1 + dy1*dy1; + else if( dx2*dx + dy2*dy >= 0 ) + dist_num = dx2*dx2 + dy2*dy2; + else + { + dist_num = (dy1*dx - dx1*dy); + dist_num *= dist_num; + dist_denom = dx*dx + dy*dy; + } + + if( dist_num*min_dist_denom < min_dist_num*dist_denom ) + { + min_dist_num = dist_num; + min_dist_denom = dist_denom; + if( min_dist_num == 0 ) + break; + } + + if( (v0.y <= pt.y && v.y <= pt.y) || + (v0.y > pt.y && v.y > pt.y) || + (v0.x < pt.x && v.x < pt.x) ) + continue; + + dist_num = dy1*dx - dx1*dy; + if( dy < 0 ) + dist_num = -dist_num; + counter += dist_num > 0; + } + + result = sqrt(min_dist_num/min_dist_denom); + if( counter % 2 == 0 ) + result = -result; + } + } + + return result; +} + + +/* + This code is described in "Computational Geometry in C" (Second Edition), + Chapter 7. It is not written to be comprehensible without the + explanation in that book. + + Written by Joseph O'Rourke. + Last modified: December 1997 + Questions to orourke@cs.smith.edu. + -------------------------------------------------------------------- + This code is Copyright 1997 by Joseph O'Rourke. It may be freely + redistributed in its entirety provided that this copyright notice is + not removed. + -------------------------------------------------------------------- + */ + +namespace cv +{ +typedef enum { Pin, Qin, Unknown } tInFlag; + +static int areaSign( Point2f a, Point2f b, Point2f c ) +{ + static const double eps = 1e-5; + double area2 = (b.x - a.x) * (double)(c.y - a.y) - (c.x - a.x ) * (double)(b.y - a.y); + return area2 > eps ? 1 : area2 < -eps ? -1 : 0; +} + +//--------------------------------------------------------------------- +// Returns true iff point c lies on the closed segement ab. +// Assumes it is already known that abc are collinear. +//--------------------------------------------------------------------- +static bool between( Point2f a, Point2f b, Point2f c ) +{ + Point2f ba, ca; + + // If ab not vertical, check betweenness on x; else on y. + if ( a.x != b.x ) + return ((a.x <= c.x) && (c.x <= b.x)) || + ((a.x >= c.x) && (c.x >= b.x)); + else + return ((a.y <= c.y) && (c.y <= b.y)) || + ((a.y >= c.y) && (c.y >= b.y)); +} + +static char parallelInt( Point2f a, Point2f b, Point2f c, Point2f d, Point2f& p, Point2f& q ) +{ + char code = 'e'; + if( areaSign(a, b, c) != 0 ) + code = '0'; + else if( between(a, b, c) && between(a, b, d)) + p = c, q = d; + else if( between(c, d, a) && between(c, d, b)) + p = a, q = b; + else if( between(a, b, c) && between(c, d, b)) + p = c, q = b; + else if( between(a, b, c) && between(c, d, a)) + p = c, q = a; + else if( between(a, b, d) && between(c, d, b)) + p = d, q = b; + else if( between(a, b, d) && between(c, d, a)) + p = d, q = a; + else + code = '0'; + return code; +} + +//--------------------------------------------------------------------- +// segSegInt: Finds the point of intersection p between two closed +// segments ab and cd. Returns p and a char with the following meaning: +// 'e': The segments collinearly overlap, sharing a point. +// 'v': An endpoint (vertex) of one segment is on the other segment, +// but 'e' doesn't hold. +// '1': The segments intersect properly (i.e., they share a point and +// neither 'v' nor 'e' holds). +// '0': The segments do not intersect (i.e., they share no points). +// Note that two collinear segments that share just one point, an endpoint +// of each, returns 'e' rather than 'v' as one might expect. +//--------------------------------------------------------------------- +static char segSegInt( Point2f a, Point2f b, Point2f c, Point2f d, Point2f& p, Point2f& q ) +{ + double s, t; // The two parameters of the parametric eqns. + double num, denom; // Numerator and denoninator of equations. + char code = '?'; // Return char characterizing intersection. + + denom = a.x * (double)( d.y - c.y ) + + b.x * (double)( c.y - d.y ) + + d.x * (double)( b.y - a.y ) + + c.x * (double)( a.y - b.y ); + + // If denom is zero, then segments are parallel: handle separately. + if (denom == 0.0) + return parallelInt(a, b, c, d, p, q); + + num = a.x * (double)( d.y - c.y ) + + c.x * (double)( a.y - d.y ) + + d.x * (double)( c.y - a.y ); + if ( (num == 0.0) || (num == denom) ) code = 'v'; + s = num / denom; + + num = -( a.x * (double)( c.y - b.y ) + + b.x * (double)( a.y - c.y ) + + c.x * (double)( b.y - a.y ) ); + if ( (num == 0.0) || (num == denom) ) code = 'v'; + t = num / denom; + + if ( (0.0 < s) && (s < 1.0) && + (0.0 < t) && (t < 1.0) ) + code = '1'; + else if ( (0.0 > s) || (s > 1.0) || + (0.0 > t) || (t > 1.0) ) + code = '0'; + + p.x = (float)(a.x + s*(b.x - a.x)); + p.y = (float)(a.y + s*(b.y - a.y)); + + return code; +} + +static tInFlag inOut( Point2f p, tInFlag inflag, int aHB, int bHA, Point2f*& result ) +{ + if( p != result[-1] ) + *result++ = p; + // Update inflag. + return aHB > 0 ? Pin : bHA > 0 ? Qin : inflag; +} + +//--------------------------------------------------------------------- +// Advances and prints out an inside vertex if appropriate. +//--------------------------------------------------------------------- +static int advance( int a, int *aa, int n, bool inside, Point2f v, Point2f*& result ) +{ + if( inside && v != result[-1] ) + *result++ = v; + (*aa)++; + return (a+1) % n; +} + +static void addSharedSeg( Point2f p, Point2f q, Point2f*& result ) +{ + if( p != result[-1] ) + *result++ = p; + if( q != result[-1] ) + *result++ = q; +} + + +static int intersectConvexConvex_( const Point2f* P, int n, const Point2f* Q, int m, + Point2f* result, float* _area ) +{ + Point2f* result0 = result; + // P has n vertices, Q has m vertices. + int a=0, b=0; // indices on P and Q (resp.) + Point2f Origin(0,0); + tInFlag inflag=Unknown; // {Pin, Qin, Unknown}: which inside + int aa=0, ba=0; // # advances on a & b indices (after 1st inter.) + bool FirstPoint=true;// Is this the first point? (used to initialize). + Point2f p0; // The first point. + *result++ = Point2f(FLT_MAX, FLT_MAX); + + do + { + // Computations of key variables. + int a1 = (a + n - 1) % n; // a-1, b-1 (resp.) + int b1 = (b + m - 1) % m; + + Point2f A = P[a] - P[a1], B = Q[b] - Q[b1]; // directed edges on P and Q (resp.) + + int cross = areaSign( Origin, A, B ); // sign of z-component of A x B + int aHB = areaSign( Q[b1], Q[b], P[a] ); // a in H(b). + int bHA = areaSign( P[a1], P[a], Q[b] ); // b in H(A); + + // If A & B intersect, update inflag. + Point2f p, q; + int code = segSegInt( P[a1], P[a], Q[b1], Q[b], p, q ); + if( code == '1' || code == 'v' ) + { + if( inflag == Unknown && FirstPoint ) + { + aa = ba = 0; + FirstPoint = false; + p0 = p; + *result++ = p; + } + inflag = inOut( p, inflag, aHB, bHA, result ); + } + + //-----Advance rules----- + + // Special case: A & B overlap and oppositely oriented. + if( code == 'e' && A.ddot(B) < 0 ) + { + addSharedSeg( p, q, result ); + return (int)(result - result0); + } + + // Special case: A & B parallel and separated. + if( cross == 0 && aHB < 0 && bHA < 0 ) + return (int)(result - result0); + + // Special case: A & B collinear. + else if ( cross == 0 && aHB == 0 && bHA == 0 ) { + // Advance but do not output point. + if ( inflag == Pin ) + b = advance( b, &ba, m, inflag == Qin, Q[b], result ); + else + a = advance( a, &aa, n, inflag == Pin, P[a], result ); + } + + // Generic cases. + else if( cross >= 0 ) + { + if( bHA > 0) + a = advance( a, &aa, n, inflag == Pin, P[a], result ); + else + b = advance( b, &ba, m, inflag == Qin, Q[b], result ); + } + else + { + if( aHB > 0) + b = advance( b, &ba, m, inflag == Qin, Q[b], result ); + else + a = advance( a, &aa, n, inflag == Pin, P[a], result ); + } + // Quit when both adv. indices have cycled, or one has cycled twice. + } + while ( ((aa < n) || (ba < m)) && (aa < 2*n) && (ba < 2*m) ); + + // Deal with special cases: not implemented. + if( inflag == Unknown ) + { + // The boundaries of P and Q do not cross. + // ... + } + + int i, nr = (int)(result - result0); + double area = 0; + Point2f prev = result0[nr-1]; + for( i = 1; i < nr; i++ ) + { + result0[i-1] = result0[i]; + area += (double)prev.x*result0[i].y - (double)prev.y*result0[i].x; + prev = result0[i]; + } + + *_area = (float)(area*0.5); + + if( result0[nr-2] == result0[0] && nr > 1 ) + nr--; + return nr-1; +} + +} + +float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p12, bool handleNested ) +{ + Mat p1 = _p1.getMat(), p2 = _p2.getMat(); + CV_Assert( p1.depth() == CV_32S || p1.depth() == CV_32F ); + CV_Assert( p2.depth() == CV_32S || p2.depth() == CV_32F ); + + int n = p1.checkVector(2, p1.depth(), true); + int m = p2.checkVector(2, p2.depth(), true); + + CV_Assert( n >= 0 && m >= 0 ); + + if( n < 2 || m < 2 ) + { + _p12.release(); + return 0.f; + } + + AutoBuffer _result(n*2 + m*2 + 1); + Point2f *fp1 = _result, *fp2 = fp1 + n; + Point2f* result = fp2 + m; + int orientation = 0; + + for( int k = 1; k <= 2; k++ ) + { + Mat& p = k == 1 ? p1 : p2; + int len = k == 1 ? n : m; + Point2f* dst = k == 1 ? fp1 : fp2; + + Mat temp(p.size(), CV_MAKETYPE(CV_32F, p.channels()), dst); + p.convertTo(temp, CV_32F); + CV_Assert( temp.ptr() == dst ); + Point2f diff0 = dst[0] - dst[len-1]; + for( int i = 1; i < len; i++ ) + { + double s = diff0.cross(dst[i] - dst[i-1]); + if( s != 0 ) + { + if( s < 0 ) + { + orientation++; + flip( temp, temp, temp.rows > 1 ? 0 : 1 ); + } + break; + } + } + } + + float area = 0.f; + int nr = intersectConvexConvex_(fp1, n, fp2, m, result, &area); + if( nr == 0 ) + { + if( !handleNested ) + { + _p12.release(); + return 0.f; + } + + if( pointPolygonTest(_InputArray(fp1, n), fp2[0], false) >= 0 ) + { + result = fp2; + nr = m; + } + else if( pointPolygonTest(_InputArray(fp2, n), fp1[0], false) >= 0 ) + { + result = fp1; + nr = n; + } + else + { + _p12.release(); + return 0.f; + } + area = (float)contourArea(_InputArray(result, nr), false); + } + + if( _p12.needed() ) + { + Mat temp(nr, 1, CV_32FC2, result); + // if both input contours were reflected, + // let's orient the result as the input vectors + if( orientation == 2 ) + flip(temp, temp, 0); + + temp.copyTo(_p12); + } + return (float)fabs(area); +} + +/* +static void testConvConv() +{ + static const int P1[] = + { + 0, 0, + 100, 0, + 100, 100, + 0, 100, + }; + + static const int Q1[] = + { + 100, 80, + 50, 80, + 50, 50, + 100, 50 + }; + + static const int P2[] = + { + 0, 0, + 200, 0, + 200, 100, + 100, 200, + 0, 100 + }; + + static const int Q2[] = + { + 100, 100, + 300, 100, + 300, 200, + 100, 200 + }; + + static const int P3[] = + { + 0, 0, + 100, 0, + 100, 100, + 0, 100 + }; + + static const int Q3[] = + { + 50, 50, + 150, 50, + 150, 150, + 50, 150 + }; + + static const int P4[] = + { + 0, 160, + 50, 80, + 130, 0, + 190, 20, + 240, 100, + 240, 260, + 190, 290, + 130, 320, + 70, 320, + 30, 290 + }; + + static const int Q4[] = + { + 160, -30, + 280, 160, + 160, 320, + 0, 220, + 30, 100 + }; + + static const void* PQs[] = + { + P1, Q1, P2, Q2, P3, Q3, P4, Q4 + }; + + static const int lens[] = + { + CV_DIM(P1), CV_DIM(Q1), + CV_DIM(P2), CV_DIM(Q2), + CV_DIM(P3), CV_DIM(Q3), + CV_DIM(P4), CV_DIM(Q4) + }; + + Mat img(800, 800, CV_8UC3); + + for( int i = 0; i < CV_DIM(PQs)/2; i++ ) + { + Mat Pm = Mat(lens[i*2]/2, 1, CV_32SC2, (void*)PQs[i*2]) + Scalar(100, 100); + Mat Qm = Mat(lens[i*2+1]/2, 1, CV_32SC2, (void*)PQs[i*2+1]) + Scalar(100, 100); + Point* P = Pm.ptr(); + Point* Q = Qm.ptr(); + + flip(Pm, Pm, 0); + flip(Qm, Qm, 0); + + Mat Rm; + intersectConvexConvex(Pm, Qm, Rm); + std::cout << Rm << std::endl << std::endl; + + img = Scalar::all(0); + + polylines(img, Pm, true, Scalar(0,255,0), 1, CV_AA, 0); + polylines(img, Qm, true, Scalar(0,0,255), 1, CV_AA, 0); + Mat temp; + Rm.convertTo(temp, CV_32S, 256); + polylines(img, temp, true, Scalar(128, 255, 255), 3, CV_AA, 8); + + namedWindow("test", 1); + imshow("test", img); + waitKey(); + } +} +*/ + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/grabcut.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/grabcut.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/grabcut.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/grabcut.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,575 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "gcgraph.hpp" +#include + +using namespace cv; + +/* +This is implementation of image segmentation algorithm GrabCut described in +"GrabCut — Interactive Foreground Extraction using Iterated Graph Cuts". +Carsten Rother, Vladimir Kolmogorov, Andrew Blake. + */ + +/* + GMM - Gaussian Mixture Model +*/ +class GMM +{ +public: + static const int componentsCount = 5; + + GMM( Mat& _model ); + double operator()( const Vec3d color ) const; + double operator()( int ci, const Vec3d color ) const; + int whichComponent( const Vec3d color ) const; + + void initLearning(); + void addSample( int ci, const Vec3d color ); + void endLearning(); + +private: + void calcInverseCovAndDeterm( int ci ); + Mat model; + double* coefs; + double* mean; + double* cov; + + double inverseCovs[componentsCount][3][3]; + double covDeterms[componentsCount]; + + double sums[componentsCount][3]; + double prods[componentsCount][3][3]; + int sampleCounts[componentsCount]; + int totalSampleCount; +}; + +GMM::GMM( Mat& _model ) +{ + const int modelSize = 3/*mean*/ + 9/*covariance*/ + 1/*component weight*/; + if( _model.empty() ) + { + _model.create( 1, modelSize*componentsCount, CV_64FC1 ); + _model.setTo(Scalar(0)); + } + else if( (_model.type() != CV_64FC1) || (_model.rows != 1) || (_model.cols != modelSize*componentsCount) ) + CV_Error( CV_StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" ); + + model = _model; + + coefs = model.ptr(0); + mean = coefs + componentsCount; + cov = mean + 3*componentsCount; + + for( int ci = 0; ci < componentsCount; ci++ ) + if( coefs[ci] > 0 ) + calcInverseCovAndDeterm( ci ); +} + +double GMM::operator()( const Vec3d color ) const +{ + double res = 0; + for( int ci = 0; ci < componentsCount; ci++ ) + res += coefs[ci] * (*this)(ci, color ); + return res; +} + +double GMM::operator()( int ci, const Vec3d color ) const +{ + double res = 0; + if( coefs[ci] > 0 ) + { + CV_Assert( covDeterms[ci] > std::numeric_limits::epsilon() ); + Vec3d diff = color; + double* m = mean + 3*ci; + diff[0] -= m[0]; diff[1] -= m[1]; diff[2] -= m[2]; + double mult = diff[0]*(diff[0]*inverseCovs[ci][0][0] + diff[1]*inverseCovs[ci][1][0] + diff[2]*inverseCovs[ci][2][0]) + + diff[1]*(diff[0]*inverseCovs[ci][0][1] + diff[1]*inverseCovs[ci][1][1] + diff[2]*inverseCovs[ci][2][1]) + + diff[2]*(diff[0]*inverseCovs[ci][0][2] + diff[1]*inverseCovs[ci][1][2] + diff[2]*inverseCovs[ci][2][2]); + res = 1.0f/sqrt(covDeterms[ci]) * exp(-0.5f*mult); + } + return res; +} + +int GMM::whichComponent( const Vec3d color ) const +{ + int k = 0; + double max = 0; + + for( int ci = 0; ci < componentsCount; ci++ ) + { + double p = (*this)( ci, color ); + if( p > max ) + { + k = ci; + max = p; + } + } + return k; +} + +void GMM::initLearning() +{ + for( int ci = 0; ci < componentsCount; ci++) + { + sums[ci][0] = sums[ci][1] = sums[ci][2] = 0; + prods[ci][0][0] = prods[ci][0][1] = prods[ci][0][2] = 0; + prods[ci][1][0] = prods[ci][1][1] = prods[ci][1][2] = 0; + prods[ci][2][0] = prods[ci][2][1] = prods[ci][2][2] = 0; + sampleCounts[ci] = 0; + } + totalSampleCount = 0; +} + +void GMM::addSample( int ci, const Vec3d color ) +{ + sums[ci][0] += color[0]; sums[ci][1] += color[1]; sums[ci][2] += color[2]; + prods[ci][0][0] += color[0]*color[0]; prods[ci][0][1] += color[0]*color[1]; prods[ci][0][2] += color[0]*color[2]; + prods[ci][1][0] += color[1]*color[0]; prods[ci][1][1] += color[1]*color[1]; prods[ci][1][2] += color[1]*color[2]; + prods[ci][2][0] += color[2]*color[0]; prods[ci][2][1] += color[2]*color[1]; prods[ci][2][2] += color[2]*color[2]; + sampleCounts[ci]++; + totalSampleCount++; +} + +void GMM::endLearning() +{ + const double variance = 0.01; + for( int ci = 0; ci < componentsCount; ci++ ) + { + int n = sampleCounts[ci]; + if( n == 0 ) + coefs[ci] = 0; + else + { + coefs[ci] = (double)n/totalSampleCount; + + double* m = mean + 3*ci; + m[0] = sums[ci][0]/n; m[1] = sums[ci][1]/n; m[2] = sums[ci][2]/n; + + double* c = cov + 9*ci; + c[0] = prods[ci][0][0]/n - m[0]*m[0]; c[1] = prods[ci][0][1]/n - m[0]*m[1]; c[2] = prods[ci][0][2]/n - m[0]*m[2]; + c[3] = prods[ci][1][0]/n - m[1]*m[0]; c[4] = prods[ci][1][1]/n - m[1]*m[1]; c[5] = prods[ci][1][2]/n - m[1]*m[2]; + c[6] = prods[ci][2][0]/n - m[2]*m[0]; c[7] = prods[ci][2][1]/n - m[2]*m[1]; c[8] = prods[ci][2][2]/n - m[2]*m[2]; + + double dtrm = c[0]*(c[4]*c[8]-c[5]*c[7]) - c[1]*(c[3]*c[8]-c[5]*c[6]) + c[2]*(c[3]*c[7]-c[4]*c[6]); + if( dtrm <= std::numeric_limits::epsilon() ) + { + // Adds the white noise to avoid singular covariance matrix. + c[0] += variance; + c[4] += variance; + c[8] += variance; + } + + calcInverseCovAndDeterm(ci); + } + } +} + +void GMM::calcInverseCovAndDeterm( int ci ) +{ + if( coefs[ci] > 0 ) + { + double *c = cov + 9*ci; + double dtrm = + covDeterms[ci] = c[0]*(c[4]*c[8]-c[5]*c[7]) - c[1]*(c[3]*c[8]-c[5]*c[6]) + c[2]*(c[3]*c[7]-c[4]*c[6]); + + CV_Assert( dtrm > std::numeric_limits::epsilon() ); + inverseCovs[ci][0][0] = (c[4]*c[8] - c[5]*c[7]) / dtrm; + inverseCovs[ci][1][0] = -(c[3]*c[8] - c[5]*c[6]) / dtrm; + inverseCovs[ci][2][0] = (c[3]*c[7] - c[4]*c[6]) / dtrm; + inverseCovs[ci][0][1] = -(c[1]*c[8] - c[2]*c[7]) / dtrm; + inverseCovs[ci][1][1] = (c[0]*c[8] - c[2]*c[6]) / dtrm; + inverseCovs[ci][2][1] = -(c[0]*c[7] - c[1]*c[6]) / dtrm; + inverseCovs[ci][0][2] = (c[1]*c[5] - c[2]*c[4]) / dtrm; + inverseCovs[ci][1][2] = -(c[0]*c[5] - c[2]*c[3]) / dtrm; + inverseCovs[ci][2][2] = (c[0]*c[4] - c[1]*c[3]) / dtrm; + } +} + +/* + Calculate beta - parameter of GrabCut algorithm. + beta = 1/(2*avg(sqr(||color[i] - color[j]||))) +*/ +static double calcBeta( const Mat& img ) +{ + double beta = 0; + for( int y = 0; y < img.rows; y++ ) + { + for( int x = 0; x < img.cols; x++ ) + { + Vec3d color = img.at(y,x); + if( x>0 ) // left + { + Vec3d diff = color - (Vec3d)img.at(y,x-1); + beta += diff.dot(diff); + } + if( y>0 && x>0 ) // upleft + { + Vec3d diff = color - (Vec3d)img.at(y-1,x-1); + beta += diff.dot(diff); + } + if( y>0 ) // up + { + Vec3d diff = color - (Vec3d)img.at(y-1,x); + beta += diff.dot(diff); + } + if( y>0 && x(y-1,x+1); + beta += diff.dot(diff); + } + } + } + if( beta <= std::numeric_limits::epsilon() ) + beta = 0; + else + beta = 1.f / (2 * beta/(4*img.cols*img.rows - 3*img.cols - 3*img.rows + 2) ); + + return beta; +} + +/* + Calculate weights of noterminal vertices of graph. + beta and gamma - parameters of GrabCut algorithm. + */ +static void calcNWeights( const Mat& img, Mat& leftW, Mat& upleftW, Mat& upW, Mat& uprightW, double beta, double gamma ) +{ + const double gammaDivSqrt2 = gamma / std::sqrt(2.0f); + leftW.create( img.rows, img.cols, CV_64FC1 ); + upleftW.create( img.rows, img.cols, CV_64FC1 ); + upW.create( img.rows, img.cols, CV_64FC1 ); + uprightW.create( img.rows, img.cols, CV_64FC1 ); + for( int y = 0; y < img.rows; y++ ) + { + for( int x = 0; x < img.cols; x++ ) + { + Vec3d color = img.at(y,x); + if( x-1>=0 ) // left + { + Vec3d diff = color - (Vec3d)img.at(y,x-1); + leftW.at(y,x) = gamma * exp(-beta*diff.dot(diff)); + } + else + leftW.at(y,x) = 0; + if( x-1>=0 && y-1>=0 ) // upleft + { + Vec3d diff = color - (Vec3d)img.at(y-1,x-1); + upleftW.at(y,x) = gammaDivSqrt2 * exp(-beta*diff.dot(diff)); + } + else + upleftW.at(y,x) = 0; + if( y-1>=0 ) // up + { + Vec3d diff = color - (Vec3d)img.at(y-1,x); + upW.at(y,x) = gamma * exp(-beta*diff.dot(diff)); + } + else + upW.at(y,x) = 0; + if( x+1=0 ) // upright + { + Vec3d diff = color - (Vec3d)img.at(y-1,x+1); + uprightW.at(y,x) = gammaDivSqrt2 * exp(-beta*diff.dot(diff)); + } + else + uprightW.at(y,x) = 0; + } + } +} + +/* + Check size, type and element values of mask matrix. + */ +static void checkMask( const Mat& img, const Mat& mask ) +{ + if( mask.empty() ) + CV_Error( CV_StsBadArg, "mask is empty" ); + if( mask.type() != CV_8UC1 ) + CV_Error( CV_StsBadArg, "mask must have CV_8UC1 type" ); + if( mask.cols != img.cols || mask.rows != img.rows ) + CV_Error( CV_StsBadArg, "mask must have as many rows and cols as img" ); + for( int y = 0; y < mask.rows; y++ ) + { + for( int x = 0; x < mask.cols; x++ ) + { + uchar val = mask.at(y,x); + if( val!=GC_BGD && val!=GC_FGD && val!=GC_PR_BGD && val!=GC_PR_FGD ) + CV_Error( CV_StsBadArg, "mask element value must be equel" + "GC_BGD or GC_FGD or GC_PR_BGD or GC_PR_FGD" ); + } + } +} + +/* + Initialize mask using rectangular. +*/ +static void initMaskWithRect( Mat& mask, Size imgSize, Rect rect ) +{ + mask.create( imgSize, CV_8UC1 ); + mask.setTo( GC_BGD ); + + rect.x = max(0, rect.x); + rect.y = max(0, rect.y); + rect.width = min(rect.width, imgSize.width-rect.x); + rect.height = min(rect.height, imgSize.height-rect.y); + + (mask(rect)).setTo( Scalar(GC_PR_FGD) ); +} + +/* + Initialize GMM background and foreground models using kmeans algorithm. +*/ +static void initGMMs( const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM ) +{ + const int kMeansItCount = 10; + const int kMeansType = KMEANS_PP_CENTERS; + + Mat bgdLabels, fgdLabels; + vector bgdSamples, fgdSamples; + Point p; + for( p.y = 0; p.y < img.rows; p.y++ ) + { + for( p.x = 0; p.x < img.cols; p.x++ ) + { + if( mask.at(p) == GC_BGD || mask.at(p) == GC_PR_BGD ) + bgdSamples.push_back( (Vec3f)img.at(p) ); + else // GC_FGD | GC_PR_FGD + fgdSamples.push_back( (Vec3f)img.at(p) ); + } + } + CV_Assert( !bgdSamples.empty() && !fgdSamples.empty() ); + Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_32FC1, &bgdSamples[0][0] ); + kmeans( _bgdSamples, GMM::componentsCount, bgdLabels, + TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); + Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_32FC1, &fgdSamples[0][0] ); + kmeans( _fgdSamples, GMM::componentsCount, fgdLabels, + TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType ); + + bgdGMM.initLearning(); + for( int i = 0; i < (int)bgdSamples.size(); i++ ) + bgdGMM.addSample( bgdLabels.at(i,0), bgdSamples[i] ); + bgdGMM.endLearning(); + + fgdGMM.initLearning(); + for( int i = 0; i < (int)fgdSamples.size(); i++ ) + fgdGMM.addSample( fgdLabels.at(i,0), fgdSamples[i] ); + fgdGMM.endLearning(); +} + +/* + Assign GMMs components for each pixel. +*/ +static void assignGMMsComponents( const Mat& img, const Mat& mask, const GMM& bgdGMM, const GMM& fgdGMM, Mat& compIdxs ) +{ + Point p; + for( p.y = 0; p.y < img.rows; p.y++ ) + { + for( p.x = 0; p.x < img.cols; p.x++ ) + { + Vec3d color = img.at(p); + compIdxs.at(p) = mask.at(p) == GC_BGD || mask.at(p) == GC_PR_BGD ? + bgdGMM.whichComponent(color) : fgdGMM.whichComponent(color); + } + } +} + +/* + Learn GMMs parameters. +*/ +static void learnGMMs( const Mat& img, const Mat& mask, const Mat& compIdxs, GMM& bgdGMM, GMM& fgdGMM ) +{ + bgdGMM.initLearning(); + fgdGMM.initLearning(); + Point p; + for( int ci = 0; ci < GMM::componentsCount; ci++ ) + { + for( p.y = 0; p.y < img.rows; p.y++ ) + { + for( p.x = 0; p.x < img.cols; p.x++ ) + { + if( compIdxs.at(p) == ci ) + { + if( mask.at(p) == GC_BGD || mask.at(p) == GC_PR_BGD ) + bgdGMM.addSample( ci, img.at(p) ); + else + fgdGMM.addSample( ci, img.at(p) ); + } + } + } + } + bgdGMM.endLearning(); + fgdGMM.endLearning(); +} + +/* + Construct GCGraph +*/ +static void constructGCGraph( const Mat& img, const Mat& mask, const GMM& bgdGMM, const GMM& fgdGMM, double lambda, + const Mat& leftW, const Mat& upleftW, const Mat& upW, const Mat& uprightW, + GCGraph& graph ) +{ + int vtxCount = img.cols*img.rows, + edgeCount = 2*(4*img.cols*img.rows - 3*(img.cols + img.rows) + 2); + graph.create(vtxCount, edgeCount); + Point p; + for( p.y = 0; p.y < img.rows; p.y++ ) + { + for( p.x = 0; p.x < img.cols; p.x++) + { + // add node + int vtxIdx = graph.addVtx(); + Vec3b color = img.at(p); + + // set t-weights + double fromSource, toSink; + if( mask.at(p) == GC_PR_BGD || mask.at(p) == GC_PR_FGD ) + { + fromSource = -log( bgdGMM(color) ); + toSink = -log( fgdGMM(color) ); + } + else if( mask.at(p) == GC_BGD ) + { + fromSource = 0; + toSink = lambda; + } + else // GC_FGD + { + fromSource = lambda; + toSink = 0; + } + graph.addTermWeights( vtxIdx, fromSource, toSink ); + + // set n-weights + if( p.x>0 ) + { + double w = leftW.at(p); + graph.addEdges( vtxIdx, vtxIdx-1, w, w ); + } + if( p.x>0 && p.y>0 ) + { + double w = upleftW.at(p); + graph.addEdges( vtxIdx, vtxIdx-img.cols-1, w, w ); + } + if( p.y>0 ) + { + double w = upW.at(p); + graph.addEdges( vtxIdx, vtxIdx-img.cols, w, w ); + } + if( p.x0 ) + { + double w = uprightW.at(p); + graph.addEdges( vtxIdx, vtxIdx-img.cols+1, w, w ); + } + } + } +} + +/* + Estimate segmentation using MaxFlow algorithm +*/ +static void estimateSegmentation( GCGraph& graph, Mat& mask ) +{ + graph.maxFlow(); + Point p; + for( p.y = 0; p.y < mask.rows; p.y++ ) + { + for( p.x = 0; p.x < mask.cols; p.x++ ) + { + if( mask.at(p) == GC_PR_BGD || mask.at(p) == GC_PR_FGD ) + { + if( graph.inSourceSegment( p.y*mask.cols+p.x /*vertex index*/ ) ) + mask.at(p) = GC_PR_FGD; + else + mask.at(p) = GC_PR_BGD; + } + } + } +} + +void cv::grabCut( InputArray _img, InputOutputArray _mask, Rect rect, + InputOutputArray _bgdModel, InputOutputArray _fgdModel, + int iterCount, int mode ) +{ + Mat img = _img.getMat(); + Mat& mask = _mask.getMatRef(); + Mat& bgdModel = _bgdModel.getMatRef(); + Mat& fgdModel = _fgdModel.getMatRef(); + + if( img.empty() ) + CV_Error( CV_StsBadArg, "image is empty" ); + if( img.type() != CV_8UC3 ) + CV_Error( CV_StsBadArg, "image mush have CV_8UC3 type" ); + + GMM bgdGMM( bgdModel ), fgdGMM( fgdModel ); + Mat compIdxs( img.size(), CV_32SC1 ); + + if( mode == GC_INIT_WITH_RECT || mode == GC_INIT_WITH_MASK ) + { + if( mode == GC_INIT_WITH_RECT ) + initMaskWithRect( mask, img.size(), rect ); + else // flag == GC_INIT_WITH_MASK + checkMask( img, mask ); + initGMMs( img, mask, bgdGMM, fgdGMM ); + } + + if( iterCount <= 0) + return; + + if( mode == GC_EVAL ) + checkMask( img, mask ); + + const double gamma = 50; + const double lambda = 9*gamma; + const double beta = calcBeta( img ); + + Mat leftW, upleftW, upW, uprightW; + calcNWeights( img, leftW, upleftW, upW, uprightW, beta, gamma ); + + for( int i = 0; i < iterCount; i++ ) + { + GCGraph graph; + assignGMMsComponents( img, mask, bgdGMM, fgdGMM, compIdxs ); + learnGMMs( img, mask, compIdxs, bgdGMM, fgdGMM ); + constructGCGraph(img, mask, bgdGMM, fgdGMM, lambda, leftW, upleftW, upW, uprightW, graph ); + estimateSegmentation( graph, mask ); + } +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/histogram.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/histogram.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/histogram.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/histogram.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3635 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +namespace cv +{ + +template<> void Ptr::delete_obj() +{ cvReleaseHist(&obj); } + + +////////////////// Helper functions ////////////////////// + +static const size_t OUT_OF_RANGE = (size_t)1 << (sizeof(size_t)*8 - 2); + +static void +calcHistLookupTables_8u( const Mat& hist, const SparseMat& shist, + int dims, const float** ranges, const double* uniranges, + bool uniform, bool issparse, vector& _tab ) +{ + const int low = 0, high = 256; + int i, j; + _tab.resize((high-low)*dims); + size_t* tab = &_tab[0]; + + if( uniform ) + { + for( i = 0; i < dims; i++ ) + { + double a = uniranges[i*2]; + double b = uniranges[i*2+1]; + int sz = !issparse ? hist.size[i] : shist.size(i); + size_t step = !issparse ? hist.step[i] : 1; + + for( j = low; j < high; j++ ) + { + int idx = cvFloor(j*a + b); + size_t written_idx; + if( (unsigned)idx < (unsigned)sz ) + written_idx = idx*step; + else + written_idx = OUT_OF_RANGE; + + tab[i*(high - low) + j - low] = written_idx; + } + } + } + else + { + for( i = 0; i < dims; i++ ) + { + int limit = std::min(cvCeil(ranges[i][0]), high); + int idx = -1, sz = !issparse ? hist.size[i] : shist.size(i); + size_t written_idx = OUT_OF_RANGE; + size_t step = !issparse ? hist.step[i] : 1; + + for(j = low;;) + { + for( ; j < limit; j++ ) + tab[i*(high - low) + j - low] = written_idx; + + if( (unsigned)(++idx) < (unsigned)sz ) + { + limit = std::min(cvCeil(ranges[i][idx+1]), high); + written_idx = idx*step; + } + else + { + for( ; j < high; j++ ) + tab[i*(high - low) + j - low] = OUT_OF_RANGE; + break; + } + } + } + } +} + + +static void histPrepareImages( const Mat* images, int nimages, const int* channels, + const Mat& mask, int dims, const int* histSize, + const float** ranges, bool uniform, + vector& ptrs, vector& deltas, + Size& imsize, vector& uniranges ) +{ + int i, j, c; + CV_Assert( channels != 0 || nimages == dims ); + + imsize = images[0].size(); + int depth = images[0].depth(), esz1 = (int)images[0].elemSize1(); + bool isContinuous = true; + + ptrs.resize(dims + 1); + deltas.resize((dims + 1)*2); + + for( i = 0; i < dims; i++ ) + { + if(!channels) + { + j = i; + c = 0; + CV_Assert( images[j].channels() == 1 ); + } + else + { + c = channels[i]; + CV_Assert( c >= 0 ); + for( j = 0; j < nimages; c -= images[j].channels(), j++ ) + if( c < images[j].channels() ) + break; + CV_Assert( j < nimages ); + } + + CV_Assert( images[j].size() == imsize && images[j].depth() == depth ); + if( !images[j].isContinuous() ) + isContinuous = false; + ptrs[i] = images[j].data + c*esz1; + deltas[i*2] = images[j].channels(); + deltas[i*2+1] = (int)(images[j].step/esz1 - imsize.width*deltas[i*2]); + } + + if( mask.data ) + { + CV_Assert( mask.size() == imsize && mask.channels() == 1 ); + isContinuous = isContinuous && mask.isContinuous(); + ptrs[dims] = mask.data; + deltas[dims*2] = 1; + deltas[dims*2 + 1] = (int)(mask.step/mask.elemSize1()); + } + +#ifndef HAVE_TBB + if( isContinuous ) + { + imsize.width *= imsize.height; + imsize.height = 1; + } +#endif + + if( !ranges ) + { + CV_Assert( depth == CV_8U ); + + uniranges.resize( dims*2 ); + for( i = 0; i < dims; i++ ) + { + uniranges[i*2] = histSize[i]/256.; + uniranges[i*2+1] = 0; + } + } + else if( uniform ) + { + uniranges.resize( dims*2 ); + for( i = 0; i < dims; i++ ) + { + CV_Assert( ranges[i] && ranges[i][0] < ranges[i][1] ); + double low = ranges[i][0], high = ranges[i][1]; + double t = histSize[i]/(high - low); + uniranges[i*2] = t; + uniranges[i*2+1] = -t*low; + } + } + else + { + for( i = 0; i < dims; i++ ) + { + size_t n = histSize[i]; + for(size_t k = 0; k < n; k++ ) + CV_Assert( ranges[i][k] < ranges[i][k+1] ); + } + } +} + + +////////////////////////////////// C A L C U L A T E H I S T O G R A M //////////////////////////////////// +#ifdef HAVE_TBB +enum {one = 1, two, three}; // array elements number + +template +class calcHist1D_Invoker +{ +public: + calcHist1D_Invoker( const vector& _ptrs, const vector& _deltas, + Mat& hist, const double* _uniranges, int sz, int dims, + Size& imageSize ) + : mask_(_ptrs[dims]), + mstep_(_deltas[dims*2 + 1]), + imageWidth_(imageSize.width), + histogramSize_(hist.size()), histogramType_(hist.type()), + globalHistogram_((tbb::atomic*)hist.data) + { + p_[0] = ((T**)&_ptrs[0])[0]; + step_[0] = (&_deltas[0])[1]; + d_[0] = (&_deltas[0])[0]; + a_[0] = (&_uniranges[0])[0]; + b_[0] = (&_uniranges[0])[1]; + size_[0] = sz; + } + + void operator()( const BlockedRange& range ) const + { + T* p0 = p_[0] + range.begin() * (step_[0] + imageWidth_*d_[0]); + uchar* mask = mask_ + range.begin()*mstep_; + + for( int row = range.begin(); row < range.end(); row++, p0 += step_[0] ) + { + if( !mask_ ) + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0] ) + { + int idx = cvFloor(*p0*a_[0] + b_[0]); + if( (unsigned)idx < (unsigned)size_[0] ) + { + globalHistogram_[idx].fetch_and_add(1); + } + } + } + else + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0] ) + { + if( mask[x] ) + { + int idx = cvFloor(*p0*a_[0] + b_[0]); + if( (unsigned)idx < (unsigned)size_[0] ) + { + globalHistogram_[idx].fetch_and_add(1); + } + } + } + mask += mstep_; + } + } + } + +private: + T* p_[one]; + uchar* mask_; + int step_[one]; + int d_[one]; + int mstep_; + double a_[one]; + double b_[one]; + int size_[one]; + int imageWidth_; + Size histogramSize_; + int histogramType_; + tbb::atomic* globalHistogram_; +}; + +template +class calcHist2D_Invoker +{ +public: + calcHist2D_Invoker( const vector& _ptrs, const vector& _deltas, + Mat& hist, const double* _uniranges, const int* size, + int dims, Size& imageSize, size_t* hstep ) + : mask_(_ptrs[dims]), + mstep_(_deltas[dims*2 + 1]), + imageWidth_(imageSize.width), + histogramSize_(hist.size()), histogramType_(hist.type()), + globalHistogram_(hist.data) + { + p_[0] = ((T**)&_ptrs[0])[0]; p_[1] = ((T**)&_ptrs[0])[1]; + step_[0] = (&_deltas[0])[1]; step_[1] = (&_deltas[0])[3]; + d_[0] = (&_deltas[0])[0]; d_[1] = (&_deltas[0])[2]; + a_[0] = (&_uniranges[0])[0]; a_[1] = (&_uniranges[0])[2]; + b_[0] = (&_uniranges[0])[1]; b_[1] = (&_uniranges[0])[3]; + size_[0] = size[0]; size_[1] = size[1]; + hstep_[0] = hstep[0]; + } + + void operator()(const BlockedRange& range) const + { + T* p0 = p_[0] + range.begin()*(step_[0] + imageWidth_*d_[0]); + T* p1 = p_[1] + range.begin()*(step_[1] + imageWidth_*d_[1]); + uchar* mask = mask_ + range.begin()*mstep_; + + for( int row = range.begin(); row < range.end(); row++, p0 += step_[0], p1 += step_[1] ) + { + if( !mask_ ) + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1] ) + { + int idx0 = cvFloor(*p0*a_[0] + b_[0]); + int idx1 = cvFloor(*p1*a_[1] + b_[1]); + if( (unsigned)idx0 < (unsigned)size_[0] && (unsigned)idx1 < (unsigned)size_[1] ) + ( (tbb::atomic*)(globalHistogram_ + hstep_[0]*idx0) )[idx1].fetch_and_add(1); + } + } + else + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1] ) + { + if( mask[x] ) + { + int idx0 = cvFloor(*p0*a_[0] + b_[0]); + int idx1 = cvFloor(*p1*a_[1] + b_[1]); + if( (unsigned)idx0 < (unsigned)size_[0] && (unsigned)idx1 < (unsigned)size_[1] ) + ((tbb::atomic*)(globalHistogram_ + hstep_[0]*idx0))[idx1].fetch_and_add(1); + } + } + mask += mstep_; + } + } + } + +private: + T* p_[two]; + uchar* mask_; + int step_[two]; + int d_[two]; + int mstep_; + double a_[two]; + double b_[two]; + int size_[two]; + const int imageWidth_; + size_t hstep_[one]; + Size histogramSize_; + int histogramType_; + uchar* globalHistogram_; +}; + + +template +class calcHist3D_Invoker +{ +public: + calcHist3D_Invoker( const vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, const double* uniranges, int _dims, + size_t* hstep, int* size ) + : mask_(_ptrs[_dims]), + mstep_(_deltas[_dims*2 + 1]), + imageWidth_(imsize.width), + globalHistogram_(hist.data) + { + p_[0] = ((T**)&_ptrs[0])[0]; p_[1] = ((T**)&_ptrs[0])[1]; p_[2] = ((T**)&_ptrs[0])[2]; + step_[0] = (&_deltas[0])[1]; step_[1] = (&_deltas[0])[3]; step_[2] = (&_deltas[0])[5]; + d_[0] = (&_deltas[0])[0]; d_[1] = (&_deltas[0])[2]; d_[2] = (&_deltas[0])[4]; + a_[0] = uniranges[0]; a_[1] = uniranges[2]; a_[2] = uniranges[4]; + b_[0] = uniranges[1]; b_[1] = uniranges[3]; b_[2] = uniranges[5]; + size_[0] = size[0]; size_[1] = size[1]; size_[2] = size[2]; + hstep_[0] = hstep[0]; hstep_[1] = hstep[1]; + } + + void operator()( const BlockedRange& range ) const + { + T* p0 = p_[0] + range.begin()*(imageWidth_*d_[0] + step_[0]); + T* p1 = p_[1] + range.begin()*(imageWidth_*d_[1] + step_[1]); + T* p2 = p_[2] + range.begin()*(imageWidth_*d_[2] + step_[2]); + uchar* mask = mask_ + range.begin()*mstep_; + + for( int i = range.begin(); i < range.end(); i++, p0 += step_[0], p1 += step_[1], p2 += step_[2] ) + { + if( !mask_ ) + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) + { + int idx0 = cvFloor(*p0*a_[0] + b_[0]); + int idx1 = cvFloor(*p1*a_[1] + b_[1]); + int idx2 = cvFloor(*p2*a_[2] + b_[2]); + if( (unsigned)idx0 < (unsigned)size_[0] && + (unsigned)idx1 < (unsigned)size_[1] && + (unsigned)idx2 < (unsigned)size_[2] ) + { + ( (tbb::atomic*)(globalHistogram_ + hstep_[0]*idx0 + hstep_[1]*idx1) )[idx2].fetch_and_add(1); + } + } + } + else + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) + { + if( mask[x] ) + { + int idx0 = cvFloor(*p0*a_[0] + b_[0]); + int idx1 = cvFloor(*p1*a_[1] + b_[1]); + int idx2 = cvFloor(*p2*a_[2] + b_[2]); + if( (unsigned)idx0 < (unsigned)size_[0] && + (unsigned)idx1 < (unsigned)size_[1] && + (unsigned)idx2 < (unsigned)size_[2] ) + { + ( (tbb::atomic*)(globalHistogram_ + hstep_[0]*idx0 + hstep_[1]*idx1) )[idx2].fetch_and_add(1); + } + } + } + mask += mstep_; + } + } + } + + static bool isFit( const Mat& histogram, const Size imageSize ) + { + return ( imageSize.width * imageSize.height >= 320*240 + && histogram.total() >= 8*8*8 ); + } + +private: + T* p_[three]; + uchar* mask_; + int step_[three]; + int d_[three]; + const int mstep_; + double a_[three]; + double b_[three]; + int size_[three]; + int imageWidth_; + size_t hstep_[two]; + uchar* globalHistogram_; +}; + +class CalcHist1D_8uInvoker +{ +public: + CalcHist1D_8uInvoker( const vector& ptrs, const vector& deltas, + Size imsize, Mat& hist, int dims, const vector& tab, + tbb::mutex* lock ) + : mask_(ptrs[dims]), + mstep_(deltas[dims*2 + 1]), + imageWidth_(imsize.width), + imageSize_(imsize), + histSize_(hist.size()), histType_(hist.type()), + tab_((size_t*)&tab[0]), + histogramWriteLock_(lock), + globalHistogram_(hist.data) + { + p_[0] = (&ptrs[0])[0]; + step_[0] = (&deltas[0])[1]; + d_[0] = (&deltas[0])[0]; + } + + void operator()( const BlockedRange& range ) const + { + int localHistogram[256] = { 0, }; + uchar* mask = mask_; + uchar* p0 = p_[0]; + int x; + tbb::mutex::scoped_lock lock; + + if( !mask_ ) + { + int n = (imageWidth_ - 4) / 4 + 1; + int tail = imageWidth_ - n*4; + + int xN = 4*n; + p0 += (xN*d_[0] + tail*d_[0] + step_[0]) * range.begin(); + } + else + { + p0 += (imageWidth_*d_[0] + step_[0]) * range.begin(); + mask += mstep_*range.begin(); + } + + for( int i = range.begin(); i < range.end(); i++, p0 += step_[0] ) + { + if( !mask_ ) + { + if( d_[0] == 1 ) + { + for( x = 0; x <= imageWidth_ - 4; x += 4 ) + { + int t0 = p0[x], t1 = p0[x+1]; + localHistogram[t0]++; localHistogram[t1]++; + t0 = p0[x+2]; t1 = p0[x+3]; + localHistogram[t0]++; localHistogram[t1]++; + } + p0 += x; + } + else + { + for( x = 0; x <= imageWidth_ - 4; x += 4 ) + { + int t0 = p0[0], t1 = p0[d_[0]]; + localHistogram[t0]++; localHistogram[t1]++; + p0 += d_[0]*2; + t0 = p0[0]; t1 = p0[d_[0]]; + localHistogram[t0]++; localHistogram[t1]++; + p0 += d_[0]*2; + } + } + + for( ; x < imageWidth_; x++, p0 += d_[0] ) + { + localHistogram[*p0]++; + } + } + else + { + for( x = 0; x < imageWidth_; x++, p0 += d_[0] ) + { + if( mask[x] ) + { + localHistogram[*p0]++; + } + } + mask += mstep_; + } + } + + lock.acquire(*histogramWriteLock_); + for(int i = 0; i < 256; i++ ) + { + size_t hidx = tab_[i]; + if( hidx < OUT_OF_RANGE ) + { + *(int*)((globalHistogram_ + hidx)) += localHistogram[i]; + } + } + lock.release(); + } + + static bool isFit( const Mat& histogram, const Size imageSize ) + { + return ( histogram.total() >= 8 + && imageSize.width * imageSize.height >= 160*120 ); + } + +private: + uchar* p_[one]; + uchar* mask_; + int mstep_; + int step_[one]; + int d_[one]; + int imageWidth_; + Size imageSize_; + Size histSize_; + int histType_; + size_t* tab_; + tbb::mutex* histogramWriteLock_; + uchar* globalHistogram_; +}; + +class CalcHist2D_8uInvoker +{ +public: + CalcHist2D_8uInvoker( const vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, const vector& _tab, + tbb::mutex* lock ) + : mask_(_ptrs[dims]), + mstep_(_deltas[dims*2 + 1]), + imageWidth_(imsize.width), + histSize_(hist.size()), histType_(hist.type()), + tab_((size_t*)&_tab[0]), + histogramWriteLock_(lock), + globalHistogram_(hist.data) + { + p_[0] = (uchar*)(&_ptrs[0])[0]; p_[1] = (uchar*)(&_ptrs[0])[1]; + step_[0] = (&_deltas[0])[1]; step_[1] = (&_deltas[0])[3]; + d_[0] = (&_deltas[0])[0]; d_[1] = (&_deltas[0])[2]; + } + + void operator()( const BlockedRange& range ) const + { + uchar* p0 = p_[0] + range.begin()*(step_[0] + imageWidth_*d_[0]); + uchar* p1 = p_[1] + range.begin()*(step_[1] + imageWidth_*d_[1]); + uchar* mask = mask_ + range.begin()*mstep_; + + Mat localHist = Mat::zeros(histSize_, histType_); + uchar* localHistData = localHist.data; + tbb::mutex::scoped_lock lock; + + for(int i = range.begin(); i < range.end(); i++, p0 += step_[0], p1 += step_[1]) + { + if( !mask_ ) + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1] ) + { + size_t idx = tab_[*p0] + tab_[*p1 + 256]; + if( idx < OUT_OF_RANGE ) + { + ++*(int*)(localHistData + idx); + } + } + } + else + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1] ) + { + size_t idx; + if( mask[x] && (idx = tab_[*p0] + tab_[*p1 + 256]) < OUT_OF_RANGE ) + { + ++*(int*)(localHistData + idx); + } + } + mask += mstep_; + } + } + + lock.acquire(*histogramWriteLock_); + for(int i = 0; i < histSize_.width*histSize_.height; i++) + { + ((int*)globalHistogram_)[i] += ((int*)localHistData)[i]; + } + lock.release(); + } + + static bool isFit( const Mat& histogram, const Size imageSize ) + { + return ( (histogram.total() > 4*4 && histogram.total() <= 116*116 + && imageSize.width * imageSize.height >= 320*240) + || (histogram.total() > 116*116 && imageSize.width * imageSize.height >= 1280*720) ); + } + +private: + uchar* p_[two]; + uchar* mask_; + int step_[two]; + int d_[two]; + int mstep_; + int imageWidth_; + Size histSize_; + int histType_; + size_t* tab_; + tbb::mutex* histogramWriteLock_; + uchar* globalHistogram_; +}; + +class CalcHist3D_8uInvoker +{ +public: + CalcHist3D_8uInvoker( const vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, const vector& tab ) + : mask_(_ptrs[dims]), + mstep_(_deltas[dims*2 + 1]), + histogramSize_(hist.size.p), histogramType_(hist.type()), + imageWidth_(imsize.width), + tab_((size_t*)&tab[0]), + globalHistogram_(hist.data) + { + p_[0] = (uchar*)(&_ptrs[0])[0]; p_[1] = (uchar*)(&_ptrs[0])[1]; p_[2] = (uchar*)(&_ptrs[0])[2]; + step_[0] = (&_deltas[0])[1]; step_[1] = (&_deltas[0])[3]; step_[2] = (&_deltas[0])[5]; + d_[0] = (&_deltas[0])[0]; d_[1] = (&_deltas[0])[2]; d_[2] = (&_deltas[0])[4]; + } + + void operator()( const BlockedRange& range ) const + { + uchar* p0 = p_[0] + range.begin()*(step_[0] + imageWidth_*d_[0]); + uchar* p1 = p_[1] + range.begin()*(step_[1] + imageWidth_*d_[1]); + uchar* p2 = p_[2] + range.begin()*(step_[2] + imageWidth_*d_[2]); + uchar* mask = mask_ + range.begin()*mstep_; + + for(int i = range.begin(); i < range.end(); i++, p0 += step_[0], p1 += step_[1], p2 += step_[2] ) + { + if( !mask_ ) + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) + { + size_t idx = tab_[*p0] + tab_[*p1 + 256] + tab_[*p2 + 512]; + if( idx < OUT_OF_RANGE ) + { + ( *(tbb::atomic*)(globalHistogram_ + idx) ).fetch_and_add(1); + } + } + } + else + { + for( int x = 0; x < imageWidth_; x++, p0 += d_[0], p1 += d_[1], p2 += d_[2] ) + { + size_t idx; + if( mask[x] && (idx = tab_[*p0] + tab_[*p1 + 256] + tab_[*p2 + 512]) < OUT_OF_RANGE ) + { + (*(tbb::atomic*)(globalHistogram_ + idx)).fetch_and_add(1); + } + } + mask += mstep_; + } + } + } + + static bool isFit( const Mat& histogram, const Size imageSize ) + { + return ( histogram.total() >= 128*128*128 + && imageSize.width * imageSize.width >= 320*240 ); + } + +private: + uchar* p_[three]; + uchar* mask_; + int mstep_; + int step_[three]; + int d_[three]; + int* histogramSize_; + int histogramType_; + int imageWidth_; + size_t* tab_; + uchar* globalHistogram_; +}; + +static void +callCalcHist2D_8u( vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, vector& _tab ) +{ + int grainSize = imsize.height / tbb::task_scheduler_init::default_num_threads(); + tbb::mutex histogramWriteLock; + + CalcHist2D_8uInvoker body(_ptrs, _deltas, imsize, hist, dims, _tab, &histogramWriteLock); + parallel_for(BlockedRange(0, imsize.height, grainSize), body); +} + +static void +callCalcHist3D_8u( vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, vector& _tab ) +{ + CalcHist3D_8uInvoker body(_ptrs, _deltas, imsize, hist, dims, _tab); + parallel_for(BlockedRange(0, imsize.height), body); +} +#endif + +template static void +calcHist_( vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, const float** _ranges, + const double* _uniranges, bool uniform ) +{ + T** ptrs = (T**)&_ptrs[0]; + const int* deltas = &_deltas[0]; + uchar* H = hist.data; + int i, x; + const uchar* mask = _ptrs[dims]; + int mstep = _deltas[dims*2 + 1]; + int size[CV_MAX_DIM]; + size_t hstep[CV_MAX_DIM]; + + for( i = 0; i < dims; i++ ) + { + size[i] = hist.size[i]; + hstep[i] = hist.step[i]; + } + + if( uniform ) + { + const double* uniranges = &_uniranges[0]; + + if( dims == 1 ) + { +#ifdef HAVE_TBB + calcHist1D_Invoker body(_ptrs, _deltas, hist, _uniranges, size[0], dims, imsize); + parallel_for(BlockedRange(0, imsize.height), body); + return; +#endif + double a = uniranges[0], b = uniranges[1]; + int sz = size[0], d0 = deltas[0], step0 = deltas[1]; + const T* p0 = (const T*)ptrs[0]; + + for( ; imsize.height--; p0 += step0, mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++, p0 += d0 ) + { + int idx = cvFloor(*p0*a + b); + if( (unsigned)idx < (unsigned)sz ) + ((int*)H)[idx]++; + } + else + for( x = 0; x < imsize.width; x++, p0 += d0 ) + if( mask[x] ) + { + int idx = cvFloor(*p0*a + b); + if( (unsigned)idx < (unsigned)sz ) + ((int*)H)[idx]++; + } + } + } + else if( dims == 2 ) + { +#ifdef HAVE_TBB + calcHist2D_Invoker body(_ptrs, _deltas, hist, _uniranges, size, dims, imsize, hstep); + parallel_for(BlockedRange(0, imsize.height), body); + return; +#endif + double a0 = uniranges[0], b0 = uniranges[1], a1 = uniranges[2], b1 = uniranges[3]; + int sz0 = size[0], sz1 = size[1]; + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3]; + size_t hstep0 = hstep[0]; + const T* p0 = (const T*)ptrs[0]; + const T* p1 = (const T*)ptrs[1]; + + for( ; imsize.height--; p0 += step0, p1 += step1, mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + if( (unsigned)idx0 < (unsigned)sz0 && (unsigned)idx1 < (unsigned)sz1 ) + ((int*)(H + hstep0*idx0))[idx1]++; + } + else + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + if( mask[x] ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + if( (unsigned)idx0 < (unsigned)sz0 && (unsigned)idx1 < (unsigned)sz1 ) + ((int*)(H + hstep0*idx0))[idx1]++; + } + } + } + else if( dims == 3 ) + { +#ifdef HAVE_TBB + if( calcHist3D_Invoker::isFit(hist, imsize) ) + { + calcHist3D_Invoker body(_ptrs, _deltas, imsize, hist, uniranges, dims, hstep, size); + parallel_for(BlockedRange(0, imsize.height), body); + return; + } +#endif + double a0 = uniranges[0], b0 = uniranges[1], + a1 = uniranges[2], b1 = uniranges[3], + a2 = uniranges[4], b2 = uniranges[5]; + int sz0 = size[0], sz1 = size[1], sz2 = size[2]; + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3], + d2 = deltas[4], step2 = deltas[5]; + size_t hstep0 = hstep[0], hstep1 = hstep[1]; + const T* p0 = (const T*)ptrs[0]; + const T* p1 = (const T*)ptrs[1]; + const T* p2 = (const T*)ptrs[2]; + + for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + int idx2 = cvFloor(*p2*a2 + b2); + if( (unsigned)idx0 < (unsigned)sz0 && + (unsigned)idx1 < (unsigned)sz1 && + (unsigned)idx2 < (unsigned)sz2 ) + ((int*)(H + hstep0*idx0 + hstep1*idx1))[idx2]++; + } + else + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + if( mask[x] ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + int idx2 = cvFloor(*p2*a2 + b2); + if( (unsigned)idx0 < (unsigned)sz0 && + (unsigned)idx1 < (unsigned)sz1 && + (unsigned)idx2 < (unsigned)sz2 ) + ((int*)(H + hstep0*idx0 + hstep1*idx1))[idx2]++; + } + } + } + else + { + for( ; imsize.height--; mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + for( i = 0; i < dims; i++ ) + { + int idx = cvFloor(*ptrs[i]*uniranges[i*2] + uniranges[i*2+1]); + if( (unsigned)idx >= (unsigned)size[i] ) + break; + ptrs[i] += deltas[i*2]; + Hptr += idx*hstep[i]; + } + + if( i == dims ) + ++*((int*)Hptr); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + else + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + i = 0; + if( mask[x] ) + for( ; i < dims; i++ ) + { + int idx = cvFloor(*ptrs[i]*uniranges[i*2] + uniranges[i*2+1]); + if( (unsigned)idx >= (unsigned)size[i] ) + break; + ptrs[i] += deltas[i*2]; + Hptr += idx*hstep[i]; + } + + if( i == dims ) + ++*((int*)Hptr); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } + } + else + { + // non-uniform histogram + const float* ranges[CV_MAX_DIM]; + for( i = 0; i < dims; i++ ) + ranges[i] = &_ranges[i][0]; + + for( ; imsize.height--; mask += mstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + i = 0; + + if( !mask || mask[x] ) + for( ; i < dims; i++ ) + { + float v = (float)*ptrs[i]; + const float* R = ranges[i]; + int idx = -1, sz = size[i]; + + while( v >= R[idx+1] && ++idx < sz ) + ; // nop + + if( (unsigned)idx >= (unsigned)sz ) + break; + + ptrs[i] += deltas[i*2]; + Hptr += idx*hstep[i]; + } + + if( i == dims ) + ++*((int*)Hptr); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + + +static void +calcHist_8u( vector& _ptrs, const vector& _deltas, + Size imsize, Mat& hist, int dims, const float** _ranges, + const double* _uniranges, bool uniform ) +{ + uchar** ptrs = &_ptrs[0]; + const int* deltas = &_deltas[0]; + uchar* H = hist.data; + int x; + const uchar* mask = _ptrs[dims]; + int mstep = _deltas[dims*2 + 1]; + vector _tab; + + calcHistLookupTables_8u( hist, SparseMat(), dims, _ranges, _uniranges, uniform, false, _tab ); + const size_t* tab = &_tab[0]; + + if( dims == 1 ) + { +#ifdef HAVE_TBB + if( CalcHist1D_8uInvoker::isFit(hist, imsize) ) + { + int treadsNumber = tbb::task_scheduler_init::default_num_threads(); + int grainSize = imsize.height/treadsNumber; + tbb::mutex histogramWriteLock; + + CalcHist1D_8uInvoker body(_ptrs, _deltas, imsize, hist, dims, _tab, &histogramWriteLock); + parallel_for(BlockedRange(0, imsize.height, grainSize), body); + return; + } +#endif + int d0 = deltas[0], step0 = deltas[1]; + int matH[256] = { 0, }; + const uchar* p0 = (const uchar*)ptrs[0]; + + for( ; imsize.height--; p0 += step0, mask += mstep ) + { + if( !mask ) + { + if( d0 == 1 ) + { + for( x = 0; x <= imsize.width - 4; x += 4 ) + { + int t0 = p0[x], t1 = p0[x+1]; + matH[t0]++; matH[t1]++; + t0 = p0[x+2]; t1 = p0[x+3]; + matH[t0]++; matH[t1]++; + } + p0 += x; + } + else + for( x = 0; x <= imsize.width - 4; x += 4 ) + { + int t0 = p0[0], t1 = p0[d0]; + matH[t0]++; matH[t1]++; + p0 += d0*2; + t0 = p0[0]; t1 = p0[d0]; + matH[t0]++; matH[t1]++; + p0 += d0*2; + } + + for( ; x < imsize.width; x++, p0 += d0 ) + matH[*p0]++; + } + else + for( x = 0; x < imsize.width; x++, p0 += d0 ) + if( mask[x] ) + matH[*p0]++; + } + + for(int i = 0; i < 256; i++ ) + { + size_t hidx = tab[i]; + if( hidx < OUT_OF_RANGE ) + *(int*)(H + hidx) += matH[i]; + } + } + else if( dims == 2 ) + { +#ifdef HAVE_TBB + if( CalcHist2D_8uInvoker::isFit(hist, imsize) ) + { + callCalcHist2D_8u(_ptrs, _deltas, imsize, hist, dims, _tab); + return; + } +#endif + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3]; + const uchar* p0 = (const uchar*)ptrs[0]; + const uchar* p1 = (const uchar*)ptrs[1]; + + for( ; imsize.height--; p0 += step0, p1 += step1, mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + { + size_t idx = tab[*p0] + tab[*p1 + 256]; + if( idx < OUT_OF_RANGE ) + ++*(int*)(H + idx); + } + else + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + { + size_t idx; + if( mask[x] && (idx = tab[*p0] + tab[*p1 + 256]) < OUT_OF_RANGE ) + ++*(int*)(H + idx); + } + } + } + else if( dims == 3 ) + { +#ifdef HAVE_TBB + if( CalcHist3D_8uInvoker::isFit(hist, imsize) ) + { + callCalcHist3D_8u(_ptrs, _deltas, imsize, hist, dims, _tab); + return; + } +#endif + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3], + d2 = deltas[4], step2 = deltas[5]; + + const uchar* p0 = (const uchar*)ptrs[0]; + const uchar* p1 = (const uchar*)ptrs[1]; + const uchar* p2 = (const uchar*)ptrs[2]; + + for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + { + size_t idx = tab[*p0] + tab[*p1 + 256] + tab[*p2 + 512]; + if( idx < OUT_OF_RANGE ) + ++*(int*)(H + idx); + } + else + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + { + size_t idx; + if( mask[x] && (idx = tab[*p0] + tab[*p1 + 256] + tab[*p2 + 512]) < OUT_OF_RANGE ) + ++*(int*)(H + idx); + } + } + } + else + { + for( ; imsize.height--; mask += mstep ) + { + if( !mask ) + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + int i = 0; + for( ; i < dims; i++ ) + { + size_t idx = tab[*ptrs[i] + i*256]; + if( idx >= OUT_OF_RANGE ) + break; + Hptr += idx; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + ++*((int*)Hptr); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + else + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + int i = 0; + if( mask[x] ) + for( ; i < dims; i++ ) + { + size_t idx = tab[*ptrs[i] + i*256]; + if( idx >= OUT_OF_RANGE ) + break; + Hptr += idx; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + ++*((int*)Hptr); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + for(int i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + +} + +void cv::calcHist( const Mat* images, int nimages, const int* channels, + InputArray _mask, OutputArray _hist, int dims, const int* histSize, + const float** ranges, bool uniform, bool accumulate ) +{ + Mat mask = _mask.getMat(); + + CV_Assert(dims > 0 && histSize); + + uchar* histdata = _hist.getMat().data; + _hist.create(dims, histSize, CV_32F); + Mat hist = _hist.getMat(), ihist = hist; + ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S; + + if( !accumulate || histdata != hist.data ) + hist = Scalar(0.); + else + hist.convertTo(ihist, CV_32S); + + vector ptrs; + vector deltas; + vector uniranges; + Size imsize; + + CV_Assert( !mask.data || mask.type() == CV_8UC1 ); + histPrepareImages( images, nimages, channels, mask, dims, hist.size, ranges, + uniform, ptrs, deltas, imsize, uniranges ); + const double* _uniranges = uniform ? &uniranges[0] : 0; + + int depth = images[0].depth(); + + if( depth == CV_8U ) + calcHist_8u(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform ); + else if( depth == CV_16U ) + calcHist_(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform ); + else if( depth == CV_32F ) + calcHist_(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform ); + else + CV_Error(CV_StsUnsupportedFormat, ""); + + ihist.convertTo(hist, CV_32F); +} + + +namespace cv +{ + +template static void +calcSparseHist_( vector& _ptrs, const vector& _deltas, + Size imsize, SparseMat& hist, int dims, const float** _ranges, + const double* _uniranges, bool uniform ) +{ + T** ptrs = (T**)&_ptrs[0]; + const int* deltas = &_deltas[0]; + int i, x; + const uchar* mask = _ptrs[dims]; + int mstep = _deltas[dims*2 + 1]; + const int* size = hist.hdr->size; + int idx[CV_MAX_DIM]; + + if( uniform ) + { + const double* uniranges = &_uniranges[0]; + + for( ; imsize.height--; mask += mstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + i = 0; + if( !mask || mask[x] ) + for( ; i < dims; i++ ) + { + idx[i] = cvFloor(*ptrs[i]*uniranges[i*2] + uniranges[i*2+1]); + if( (unsigned)idx[i] >= (unsigned)size[i] ) + break; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + ++*(int*)hist.ptr(idx, true); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } + else + { + // non-uniform histogram + const float* ranges[CV_MAX_DIM]; + for( i = 0; i < dims; i++ ) + ranges[i] = &_ranges[i][0]; + + for( ; imsize.height--; mask += mstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + i = 0; + + if( !mask || mask[x] ) + for( ; i < dims; i++ ) + { + float v = (float)*ptrs[i]; + const float* R = ranges[i]; + int j = -1, sz = size[i]; + + while( v >= R[j+1] && ++j < sz ) + ; // nop + + if( (unsigned)j >= (unsigned)sz ) + break; + ptrs[i] += deltas[i*2]; + idx[i] = j; + } + + if( i == dims ) + ++*(int*)hist.ptr(idx, true); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + + +static void +calcSparseHist_8u( vector& _ptrs, const vector& _deltas, + Size imsize, SparseMat& hist, int dims, const float** _ranges, + const double* _uniranges, bool uniform ) +{ + uchar** ptrs = (uchar**)&_ptrs[0]; + const int* deltas = &_deltas[0]; + int x; + const uchar* mask = _ptrs[dims]; + int mstep = _deltas[dims*2 + 1]; + int idx[CV_MAX_DIM]; + vector _tab; + + calcHistLookupTables_8u( Mat(), hist, dims, _ranges, _uniranges, uniform, true, _tab ); + const size_t* tab = &_tab[0]; + + for( ; imsize.height--; mask += mstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + int i = 0; + if( !mask || mask[x] ) + for( ; i < dims; i++ ) + { + size_t hidx = tab[*ptrs[i] + i*256]; + if( hidx >= OUT_OF_RANGE ) + break; + ptrs[i] += deltas[i*2]; + idx[i] = (int)hidx; + } + + if( i == dims ) + ++*(int*)hist.ptr(idx,true); + else + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + for(int i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } +} + + +static void calcHist( const Mat* images, int nimages, const int* channels, + const Mat& mask, SparseMat& hist, int dims, const int* histSize, + const float** ranges, bool uniform, bool accumulate, bool keepInt ) +{ + size_t i, N; + + if( !accumulate ) + hist.create(dims, histSize, CV_32F); + else + { + SparseMatIterator it = hist.begin(); + for( i = 0, N = hist.nzcount(); i < N; i++, ++it ) + { + Cv32suf* val = (Cv32suf*)it.ptr; + val->i = cvRound(val->f); + } + } + + vector ptrs; + vector deltas; + vector uniranges; + Size imsize; + + CV_Assert( !mask.data || mask.type() == CV_8UC1 ); + histPrepareImages( images, nimages, channels, mask, dims, hist.hdr->size, ranges, + uniform, ptrs, deltas, imsize, uniranges ); + const double* _uniranges = uniform ? &uniranges[0] : 0; + + int depth = images[0].depth(); + if( depth == CV_8U ) + calcSparseHist_8u(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform ); + else if( depth == CV_16U ) + calcSparseHist_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform ); + else if( depth == CV_32F ) + calcSparseHist_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform ); + else + CV_Error(CV_StsUnsupportedFormat, ""); + + if( !keepInt ) + { + SparseMatIterator it = hist.begin(); + for( i = 0, N = hist.nzcount(); i < N; i++, ++it ) + { + Cv32suf* val = (Cv32suf*)it.ptr; + val->f = (float)val->i; + } + } +} + +} + +void cv::calcHist( const Mat* images, int nimages, const int* channels, + InputArray _mask, SparseMat& hist, int dims, const int* histSize, + const float** ranges, bool uniform, bool accumulate ) +{ + Mat mask = _mask.getMat(); + calcHist( images, nimages, channels, mask, hist, dims, histSize, + ranges, uniform, accumulate, false ); +} + + +void cv::calcHist( InputArrayOfArrays images, const vector& channels, + InputArray mask, OutputArray hist, + const vector& histSize, + const vector& ranges, + bool accumulate ) +{ + int i, dims = (int)histSize.size(), rsz = (int)ranges.size(), csz = (int)channels.size(); + int nimages = (int)images.total(); + + CV_Assert(nimages > 0 && dims > 0); + CV_Assert(rsz == dims*2 || (rsz == 0 && images.depth(0) == CV_8U)); + CV_Assert(csz == 0 || csz == dims); + float* _ranges[CV_MAX_DIM]; + if( rsz > 0 ) + { + for( i = 0; i < rsz/2; i++ ) + _ranges[i] = (float*)&ranges[i*2]; + } + + AutoBuffer buf(nimages); + for( i = 0; i < nimages; i++ ) + buf[i] = images.getMat(i); + + calcHist(&buf[0], nimages, csz ? &channels[0] : 0, + mask, hist, dims, &histSize[0], rsz ? (const float**)_ranges : 0, + true, accumulate); +} + + +/////////////////////////////////////// B A C K P R O J E C T //////////////////////////////////// + +namespace cv +{ + +template static void +calcBackProj_( vector& _ptrs, const vector& _deltas, + Size imsize, const Mat& hist, int dims, const float** _ranges, + const double* _uniranges, float scale, bool uniform ) +{ + T** ptrs = (T**)&_ptrs[0]; + const int* deltas = &_deltas[0]; + uchar* H = hist.data; + int i, x; + BT* bproj = (BT*)_ptrs[dims]; + int bpstep = _deltas[dims*2 + 1]; + int size[CV_MAX_DIM]; + size_t hstep[CV_MAX_DIM]; + + for( i = 0; i < dims; i++ ) + { + size[i] = hist.size[i]; + hstep[i] = hist.step[i]; + } + + if( uniform ) + { + const double* uniranges = &_uniranges[0]; + + if( dims == 1 ) + { + double a = uniranges[0], b = uniranges[1]; + int sz = size[0], d0 = deltas[0], step0 = deltas[1]; + const T* p0 = (const T*)ptrs[0]; + + for( ; imsize.height--; p0 += step0, bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++, p0 += d0 ) + { + int idx = cvFloor(*p0*a + b); + bproj[x] = (unsigned)idx < (unsigned)sz ? saturate_cast(((float*)H)[idx]*scale) : 0; + } + } + } + else if( dims == 2 ) + { + double a0 = uniranges[0], b0 = uniranges[1], + a1 = uniranges[2], b1 = uniranges[3]; + int sz0 = size[0], sz1 = size[1]; + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3]; + size_t hstep0 = hstep[0]; + const T* p0 = (const T*)ptrs[0]; + const T* p1 = (const T*)ptrs[1]; + + for( ; imsize.height--; p0 += step0, p1 += step1, bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + bproj[x] = (unsigned)idx0 < (unsigned)sz0 && + (unsigned)idx1 < (unsigned)sz1 ? + saturate_cast(((float*)(H + hstep0*idx0))[idx1]*scale) : 0; + } + } + } + else if( dims == 3 ) + { + double a0 = uniranges[0], b0 = uniranges[1], + a1 = uniranges[2], b1 = uniranges[3], + a2 = uniranges[4], b2 = uniranges[5]; + int sz0 = size[0], sz1 = size[1], sz2 = size[2]; + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3], + d2 = deltas[4], step2 = deltas[5]; + size_t hstep0 = hstep[0], hstep1 = hstep[1]; + const T* p0 = (const T*)ptrs[0]; + const T* p1 = (const T*)ptrs[1]; + const T* p2 = (const T*)ptrs[2]; + + for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + { + int idx0 = cvFloor(*p0*a0 + b0); + int idx1 = cvFloor(*p1*a1 + b1); + int idx2 = cvFloor(*p2*a2 + b2); + bproj[x] = (unsigned)idx0 < (unsigned)sz0 && + (unsigned)idx1 < (unsigned)sz1 && + (unsigned)idx2 < (unsigned)sz2 ? + saturate_cast(((float*)(H + hstep0*idx0 + hstep1*idx1))[idx2]*scale) : 0; + } + } + } + else + { + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + for( i = 0; i < dims; i++ ) + { + int idx = cvFloor(*ptrs[i]*uniranges[i*2] + uniranges[i*2+1]); + if( (unsigned)idx >= (unsigned)size[i] || (_ranges && *ptrs[i] >= _ranges[i][1])) + break; + ptrs[i] += deltas[i*2]; + Hptr += idx*hstep[i]; + } + + if( i == dims ) + bproj[x] = saturate_cast(*(float*)Hptr*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } + } + else + { + // non-uniform histogram + const float* ranges[CV_MAX_DIM]; + for( i = 0; i < dims; i++ ) + ranges[i] = &_ranges[i][0]; + + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + for( i = 0; i < dims; i++ ) + { + float v = (float)*ptrs[i]; + const float* R = ranges[i]; + int idx = -1, sz = size[i]; + + while( v >= R[idx+1] && ++idx < sz ) + ; // nop + + if( (unsigned)idx >= (unsigned)sz ) + break; + + ptrs[i] += deltas[i*2]; + Hptr += idx*hstep[i]; + } + + if( i == dims ) + bproj[x] = saturate_cast(*(float*)Hptr*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + + +static void +calcBackProj_8u( vector& _ptrs, const vector& _deltas, + Size imsize, const Mat& hist, int dims, const float** _ranges, + const double* _uniranges, float scale, bool uniform ) +{ + uchar** ptrs = &_ptrs[0]; + const int* deltas = &_deltas[0]; + uchar* H = hist.data; + int i, x; + uchar* bproj = _ptrs[dims]; + int bpstep = _deltas[dims*2 + 1]; + vector _tab; + + calcHistLookupTables_8u( hist, SparseMat(), dims, _ranges, _uniranges, uniform, false, _tab ); + const size_t* tab = &_tab[0]; + + if( dims == 1 ) + { + int d0 = deltas[0], step0 = deltas[1]; + uchar matH[256] = {0}; + const uchar* p0 = (const uchar*)ptrs[0]; + + for( i = 0; i < 256; i++ ) + { + size_t hidx = tab[i]; + if( hidx < OUT_OF_RANGE ) + matH[i] = saturate_cast(*(float*)(H + hidx)*scale); + } + + for( ; imsize.height--; p0 += step0, bproj += bpstep ) + { + if( d0 == 1 ) + { + for( x = 0; x <= imsize.width - 4; x += 4 ) + { + uchar t0 = matH[p0[x]], t1 = matH[p0[x+1]]; + bproj[x] = t0; bproj[x+1] = t1; + t0 = matH[p0[x+2]]; t1 = matH[p0[x+3]]; + bproj[x+2] = t0; bproj[x+3] = t1; + } + p0 += x; + } + else + for( x = 0; x <= imsize.width - 4; x += 4 ) + { + uchar t0 = matH[p0[0]], t1 = matH[p0[d0]]; + bproj[x] = t0; bproj[x+1] = t1; + p0 += d0*2; + t0 = matH[p0[0]]; t1 = matH[p0[d0]]; + bproj[x+2] = t0; bproj[x+3] = t1; + p0 += d0*2; + } + + for( ; x < imsize.width; x++, p0 += d0 ) + bproj[x] = matH[*p0]; + } + } + else if( dims == 2 ) + { + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3]; + const uchar* p0 = (const uchar*)ptrs[0]; + const uchar* p1 = (const uchar*)ptrs[1]; + + for( ; imsize.height--; p0 += step0, p1 += step1, bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 ) + { + size_t idx = tab[*p0] + tab[*p1 + 256]; + bproj[x] = idx < OUT_OF_RANGE ? saturate_cast(*(float*)(H + idx)*scale) : 0; + } + } + } + else if( dims == 3 ) + { + int d0 = deltas[0], step0 = deltas[1], + d1 = deltas[2], step1 = deltas[3], + d2 = deltas[4], step2 = deltas[5]; + const uchar* p0 = (const uchar*)ptrs[0]; + const uchar* p1 = (const uchar*)ptrs[1]; + const uchar* p2 = (const uchar*)ptrs[2]; + + for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 ) + { + size_t idx = tab[*p0] + tab[*p1 + 256] + tab[*p2 + 512]; + bproj[x] = idx < OUT_OF_RANGE ? saturate_cast(*(float*)(H + idx)*scale) : 0; + } + } + } + else + { + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + uchar* Hptr = H; + for( i = 0; i < dims; i++ ) + { + size_t idx = tab[*ptrs[i] + i*256]; + if( idx >= OUT_OF_RANGE ) + break; + ptrs[i] += deltas[i*2]; + Hptr += idx; + } + + if( i == dims ) + bproj[x] = saturate_cast(*(float*)Hptr*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + +} + +void cv::calcBackProject( const Mat* images, int nimages, const int* channels, + InputArray _hist, OutputArray _backProject, + const float** ranges, double scale, bool uniform ) +{ + Mat hist = _hist.getMat(); + vector ptrs; + vector deltas; + vector uniranges; + Size imsize; + int dims = hist.dims == 2 && hist.size[1] == 1 ? 1 : hist.dims; + + CV_Assert( dims > 0 && hist.data ); + _backProject.create( images[0].size(), images[0].depth() ); + Mat backProject = _backProject.getMat(); + histPrepareImages( images, nimages, channels, backProject, dims, hist.size, ranges, + uniform, ptrs, deltas, imsize, uniranges ); + const double* _uniranges = uniform ? &uniranges[0] : 0; + + int depth = images[0].depth(); + if( depth == CV_8U ) + calcBackProj_8u(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform); + else if( depth == CV_16U ) + calcBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); + else if( depth == CV_32F ) + calcBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +namespace cv +{ + +template static void +calcSparseBackProj_( vector& _ptrs, const vector& _deltas, + Size imsize, const SparseMat& hist, int dims, const float** _ranges, + const double* _uniranges, float scale, bool uniform ) +{ + T** ptrs = (T**)&_ptrs[0]; + const int* deltas = &_deltas[0]; + int i, x; + BT* bproj = (BT*)_ptrs[dims]; + int bpstep = _deltas[dims*2 + 1]; + const int* size = hist.hdr->size; + int idx[CV_MAX_DIM]; + const SparseMat_& hist_ = (const SparseMat_&)hist; + + if( uniform ) + { + const double* uniranges = &_uniranges[0]; + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + for( i = 0; i < dims; i++ ) + { + idx[i] = cvFloor(*ptrs[i]*uniranges[i*2] + uniranges[i*2+1]); + if( (unsigned)idx[i] >= (unsigned)size[i] ) + break; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + bproj[x] = saturate_cast(hist_(idx)*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } + else + { + // non-uniform histogram + const float* ranges[CV_MAX_DIM]; + for( i = 0; i < dims; i++ ) + ranges[i] = &_ranges[i][0]; + + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + for( i = 0; i < dims; i++ ) + { + float v = (float)*ptrs[i]; + const float* R = ranges[i]; + int j = -1, sz = size[i]; + + while( v >= R[j+1] && ++j < sz ) + ; // nop + + if( (unsigned)j >= (unsigned)sz ) + break; + idx[i] = j; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + bproj[x] = saturate_cast(hist_(idx)*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } + } +} + + +static void +calcSparseBackProj_8u( vector& _ptrs, const vector& _deltas, + Size imsize, const SparseMat& hist, int dims, const float** _ranges, + const double* _uniranges, float scale, bool uniform ) +{ + uchar** ptrs = &_ptrs[0]; + const int* deltas = &_deltas[0]; + int i, x; + uchar* bproj = _ptrs[dims]; + int bpstep = _deltas[dims*2 + 1]; + vector _tab; + int idx[CV_MAX_DIM]; + + calcHistLookupTables_8u( Mat(), hist, dims, _ranges, _uniranges, uniform, true, _tab ); + const size_t* tab = &_tab[0]; + + for( ; imsize.height--; bproj += bpstep ) + { + for( x = 0; x < imsize.width; x++ ) + { + for( i = 0; i < dims; i++ ) + { + size_t hidx = tab[*ptrs[i] + i*256]; + if( hidx >= OUT_OF_RANGE ) + break; + idx[i] = (int)hidx; + ptrs[i] += deltas[i*2]; + } + + if( i == dims ) + bproj[x] = saturate_cast(hist.value(idx)*scale); + else + { + bproj[x] = 0; + for( ; i < dims; i++ ) + ptrs[i] += deltas[i*2]; + } + } + for( i = 0; i < dims; i++ ) + ptrs[i] += deltas[i*2 + 1]; + } +} + +} + +void cv::calcBackProject( const Mat* images, int nimages, const int* channels, + const SparseMat& hist, OutputArray _backProject, + const float** ranges, double scale, bool uniform ) +{ + vector ptrs; + vector deltas; + vector uniranges; + Size imsize; + int dims = hist.dims(); + + CV_Assert( dims > 0 ); + _backProject.create( images[0].size(), images[0].depth() ); + Mat backProject = _backProject.getMat(); + histPrepareImages( images, nimages, channels, backProject, + dims, hist.hdr->size, ranges, + uniform, ptrs, deltas, imsize, uniranges ); + const double* _uniranges = uniform ? &uniranges[0] : 0; + + int depth = images[0].depth(); + if( depth == CV_8U ) + calcSparseBackProj_8u(ptrs, deltas, imsize, hist, dims, ranges, + _uniranges, (float)scale, uniform); + else if( depth == CV_16U ) + calcSparseBackProj_(ptrs, deltas, imsize, hist, dims, ranges, + _uniranges, (float)scale, uniform ); + else if( depth == CV_32F ) + calcSparseBackProj_(ptrs, deltas, imsize, hist, dims, ranges, + _uniranges, (float)scale, uniform ); + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +void cv::calcBackProject( InputArrayOfArrays images, const vector& channels, + InputArray hist, OutputArray dst, + const vector& ranges, + double scale ) +{ + Mat H0 = hist.getMat(), H; + int hcn = H0.channels(); + if( hcn > 1 ) + { + CV_Assert( H0.isContinuous() ); + int hsz[CV_CN_MAX+1]; + memcpy(hsz, &H0.size[0], H0.dims*sizeof(hsz[0])); + hsz[H0.dims] = hcn; + H = Mat(H0.dims+1, hsz, H0.depth(), H0.data); + } + else + H = H0; + bool _1d = H.rows == 1 || H.cols == 1; + int i, dims = H.dims, rsz = (int)ranges.size(), csz = (int)channels.size(); + int nimages = (int)images.total(); + CV_Assert(nimages > 0); + CV_Assert(rsz == dims*2 || (rsz == 2 && _1d) || (rsz == 0 && images.depth(0) == CV_8U)); + CV_Assert(csz == 0 || csz == dims || (csz == 1 && _1d)); + float* _ranges[CV_MAX_DIM]; + if( rsz > 0 ) + { + for( i = 0; i < rsz/2; i++ ) + _ranges[i] = (float*)&ranges[i*2]; + } + + AutoBuffer buf(nimages); + for( i = 0; i < nimages; i++ ) + buf[i] = images.getMat(i); + + calcBackProject(&buf[0], nimages, csz ? &channels[0] : 0, + hist, dst, rsz ? (const float**)_ranges : 0, scale, true); +} + + +////////////////// C O M P A R E H I S T O G R A M S //////////////////////// + +double cv::compareHist( InputArray _H1, InputArray _H2, int method ) +{ + Mat H1 = _H1.getMat(), H2 = _H2.getMat(); + const Mat* arrays[] = {&H1, &H2, 0}; + Mat planes[2]; + NAryMatIterator it(arrays, planes); + double result = 0; + int j, len = (int)it.size; + + CV_Assert( H1.type() == H2.type() && H1.type() == CV_32F ); + + double s1 = 0, s2 = 0, s11 = 0, s12 = 0, s22 = 0; + + CV_Assert( it.planes[0].isContinuous() && it.planes[1].isContinuous() ); + + for( size_t i = 0; i < it.nplanes; i++, ++it ) + { + const float* h1 = (const float*)it.planes[0].data; + const float* h2 = (const float*)it.planes[1].data; + len = it.planes[0].rows*it.planes[0].cols; + + if( method == CV_COMP_CHISQR ) + { + for( j = 0; j < len; j++ ) + { + double a = h1[j] - h2[j]; + double b = h1[j]; + if( fabs(b) > DBL_EPSILON ) + result += a*a/b; + } + } + else if( method == CV_COMP_CORREL ) + { + for( j = 0; j < len; j++ ) + { + double a = h1[j]; + double b = h2[j]; + + s12 += a*b; + s1 += a; + s11 += a*a; + s2 += b; + s22 += b*b; + } + } + else if( method == CV_COMP_INTERSECT ) + { + for( j = 0; j < len; j++ ) + result += std::min(h1[j], h2[j]); + } + else if( method == CV_COMP_BHATTACHARYYA ) + { + for( j = 0; j < len; j++ ) + { + double a = h1[j]; + double b = h2[j]; + result += std::sqrt(a*b); + s1 += a; + s2 += b; + } + } + else + CV_Error( CV_StsBadArg, "Unknown comparison method" ); + } + + if( method == CV_COMP_CORREL ) + { + size_t total = H1.total(); + double scale = 1./total; + double num = s12 - s1*s2*scale; + double denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale); + result = std::abs(denom2) > DBL_EPSILON ? num/std::sqrt(denom2) : 1.; + } + else if( method == CV_COMP_BHATTACHARYYA ) + { + s1 *= s2; + s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.; + result = std::sqrt(std::max(1. - result*s1, 0.)); + } + + return result; +} + + +double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method ) +{ + double result = 0; + int i, dims = H1.dims(); + + CV_Assert( dims > 0 && dims == H2.dims() && H1.type() == H2.type() && H1.type() == CV_32F ); + for( i = 0; i < dims; i++ ) + CV_Assert( H1.size(i) == H2.size(i) ); + + const SparseMat *PH1 = &H1, *PH2 = &H2; + if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR ) + std::swap(PH1, PH2); + + SparseMatConstIterator it = PH1->begin(); + int N1 = (int)PH1->nzcount(), N2 = (int)PH2->nzcount(); + + if( method == CV_COMP_CHISQR ) + { + for( i = 0; i < N1; i++, ++it ) + { + float v1 = it.value(); + const SparseMat::Node* node = it.node(); + float v2 = PH2->value(node->idx, (size_t*)&node->hashval); + double a = v1 - v2; + double b = v1; + if( fabs(b) > DBL_EPSILON ) + result += a*a/b; + } + } + else if( method == CV_COMP_CORREL ) + { + double s1 = 0, s2 = 0, s11 = 0, s12 = 0, s22 = 0; + + for( i = 0; i < N1; i++, ++it ) + { + double v1 = it.value(); + const SparseMat::Node* node = it.node(); + s12 += v1*PH2->value(node->idx, (size_t*)&node->hashval); + s1 += v1; + s11 += v1*v1; + } + + it = PH2->begin(); + for( i = 0; i < N2; i++, ++it ) + { + double v2 = it.value(); + s2 += v2; + s22 += v2*v2; + } + + size_t total = 1; + for( i = 0; i < H1.dims(); i++ ) + total *= H1.size(i); + double scale = 1./total; + double num = s12 - s1*s2*scale; + double denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale); + result = std::abs(denom2) > DBL_EPSILON ? num/std::sqrt(denom2) : 1.; + } + else if( method == CV_COMP_INTERSECT ) + { + for( i = 0; i < N1; i++, ++it ) + { + float v1 = it.value(); + const SparseMat::Node* node = it.node(); + float v2 = PH2->value(node->idx, (size_t*)&node->hashval); + if( v2 ) + result += std::min(v1, v2); + } + } + else if( method == CV_COMP_BHATTACHARYYA ) + { + double s1 = 0, s2 = 0; + + for( i = 0; i < N1; i++, ++it ) + { + double v1 = it.value(); + const SparseMat::Node* node = it.node(); + double v2 = PH2->value(node->idx, (size_t*)&node->hashval); + result += std::sqrt(v1*v2); + s1 += v1; + } + + it = PH2->begin(); + for( i = 0; i < N2; i++, ++it ) + s2 += it.value(); + + s1 *= s2; + s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.; + result = std::sqrt(std::max(1. - result*s1, 0.)); + } + else + CV_Error( CV_StsBadArg, "Unknown comparison method" ); + + return result; +} + + +const int CV_HIST_DEFAULT_TYPE = CV_32F; + +/* Creates new histogram */ +CvHistogram * +cvCreateHist( int dims, int *sizes, CvHistType type, float** ranges, int uniform ) +{ + CvHistogram *hist = 0; + + if( (unsigned)dims > CV_MAX_DIM ) + CV_Error( CV_BadOrder, "Number of dimensions is out of range" ); + + if( !sizes ) + CV_Error( CV_HeaderIsNull, "Null pointer" ); + + hist = (CvHistogram *)cvAlloc( sizeof( CvHistogram )); + hist->type = CV_HIST_MAGIC_VAL + ((int)type & 1); + if (uniform) hist->type|= CV_HIST_UNIFORM_FLAG; + hist->thresh2 = 0; + hist->bins = 0; + if( type == CV_HIST_ARRAY ) + { + hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes, + CV_HIST_DEFAULT_TYPE ); + cvCreateData( hist->bins ); + } + else if( type == CV_HIST_SPARSE ) + hist->bins = cvCreateSparseMat( dims, sizes, CV_HIST_DEFAULT_TYPE ); + else + CV_Error( CV_StsBadArg, "Invalid histogram type" ); + + if( ranges ) + cvSetHistBinRanges( hist, ranges, uniform ); + + return hist; +} + + +/* Creates histogram wrapping header for given array */ +CV_IMPL CvHistogram* +cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist, + float *data, float **ranges, int uniform ) +{ + if( !hist ) + CV_Error( CV_StsNullPtr, "Null histogram header pointer" ); + + if( !data ) + CV_Error( CV_StsNullPtr, "Null data pointer" ); + + hist->thresh2 = 0; + hist->type = CV_HIST_MAGIC_VAL; + hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes, CV_HIST_DEFAULT_TYPE, data ); + + if( ranges ) + { + if( !uniform ) + CV_Error( CV_StsBadArg, "Only uniform bin ranges can be used here " + "(to avoid memory allocation)" ); + cvSetHistBinRanges( hist, ranges, uniform ); + } + + return hist; +} + + +CV_IMPL void +cvReleaseHist( CvHistogram **hist ) +{ + if( !hist ) + CV_Error( CV_StsNullPtr, "" ); + + if( *hist ) + { + CvHistogram* temp = *hist; + + if( !CV_IS_HIST(temp)) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + *hist = 0; + + if( CV_IS_SPARSE_HIST( temp )) + cvReleaseSparseMat( (CvSparseMat**)&temp->bins ); + else + { + cvReleaseData( temp->bins ); + temp->bins = 0; + } + + if( temp->thresh2 ) + cvFree( &temp->thresh2 ); + cvFree( &temp ); + } +} + +CV_IMPL void +cvClearHist( CvHistogram *hist ) +{ + if( !CV_IS_HIST(hist) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + cvZero( hist->bins ); +} + + +// Clears histogram bins that are below than threshold +CV_IMPL void +cvThreshHist( CvHistogram* hist, double thresh ) +{ + if( !CV_IS_HIST(hist) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + + if( !CV_IS_SPARSE_MAT(hist->bins) ) + { + CvMat mat; + cvGetMat( hist->bins, &mat, 0, 1 ); + cvThreshold( &mat, &mat, thresh, 0, CV_THRESH_TOZERO ); + } + else + { + CvSparseMat* mat = (CvSparseMat*)hist->bins; + CvSparseMatIterator iterator; + CvSparseNode *node; + + for( node = cvInitSparseMatIterator( mat, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + float* val = (float*)CV_NODE_VAL( mat, node ); + if( *val <= thresh ) + *val = 0; + } + } +} + + +// Normalizes histogram (make sum of the histogram bins == factor) +CV_IMPL void +cvNormalizeHist( CvHistogram* hist, double factor ) +{ + double sum = 0; + + if( !CV_IS_HIST(hist) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + + if( !CV_IS_SPARSE_HIST(hist) ) + { + CvMat mat; + cvGetMat( hist->bins, &mat, 0, 1 ); + sum = cvSum( &mat ).val[0]; + if( fabs(sum) < DBL_EPSILON ) + sum = 1; + cvScale( &mat, &mat, factor/sum, 0 ); + } + else + { + CvSparseMat* mat = (CvSparseMat*)hist->bins; + CvSparseMatIterator iterator; + CvSparseNode *node; + float scale; + + for( node = cvInitSparseMatIterator( mat, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + sum += *(float*)CV_NODE_VAL(mat,node); + } + + if( fabs(sum) < DBL_EPSILON ) + sum = 1; + scale = (float)(factor/sum); + + for( node = cvInitSparseMatIterator( mat, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + *(float*)CV_NODE_VAL(mat,node) *= scale; + } + } +} + + +// Retrieves histogram global min, max and their positions +CV_IMPL void +cvGetMinMaxHistValue( const CvHistogram* hist, + float *value_min, float* value_max, + int* idx_min, int* idx_max ) +{ + double minVal, maxVal; + int dims, size[CV_MAX_DIM]; + + if( !CV_IS_HIST(hist) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + + dims = cvGetDims( hist->bins, size ); + + if( !CV_IS_SPARSE_HIST(hist) ) + { + CvMat mat; + CvPoint minPt, maxPt; + + cvGetMat( hist->bins, &mat, 0, 1 ); + cvMinMaxLoc( &mat, &minVal, &maxVal, &minPt, &maxPt ); + + if( dims == 1 ) + { + if( idx_min ) + *idx_min = minPt.y + minPt.x; + if( idx_max ) + *idx_max = maxPt.y + maxPt.x; + } + else if( dims == 2 ) + { + if( idx_min ) + idx_min[0] = minPt.y, idx_min[1] = minPt.x; + if( idx_max ) + idx_max[0] = maxPt.y, idx_max[1] = maxPt.x; + } + else if( idx_min || idx_max ) + { + int imin = minPt.y*mat.cols + minPt.x; + int imax = maxPt.y*mat.cols + maxPt.x; + + for(int i = dims - 1; i >= 0; i-- ) + { + if( idx_min ) + { + int t = imin / size[i]; + idx_min[i] = imin - t*size[i]; + imin = t; + } + + if( idx_max ) + { + int t = imax / size[i]; + idx_max[i] = imax - t*size[i]; + imax = t; + } + } + } + } + else + { + CvSparseMat* mat = (CvSparseMat*)hist->bins; + CvSparseMatIterator iterator; + CvSparseNode *node; + int minv = INT_MAX; + int maxv = INT_MIN; + CvSparseNode* minNode = 0; + CvSparseNode* maxNode = 0; + const int *_idx_min = 0, *_idx_max = 0; + Cv32suf m; + + for( node = cvInitSparseMatIterator( mat, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + int value = *(int*)CV_NODE_VAL(mat,node); + value = CV_TOGGLE_FLT(value); + if( value < minv ) + { + minv = value; + minNode = node; + } + + if( value > maxv ) + { + maxv = value; + maxNode = node; + } + } + + if( minNode ) + { + _idx_min = CV_NODE_IDX(mat,minNode); + _idx_max = CV_NODE_IDX(mat,maxNode); + m.i = CV_TOGGLE_FLT(minv); minVal = m.f; + m.i = CV_TOGGLE_FLT(maxv); maxVal = m.f; + } + else + { + minVal = maxVal = 0; + } + + for(int i = 0; i < dims; i++ ) + { + if( idx_min ) + idx_min[i] = _idx_min ? _idx_min[i] : -1; + if( idx_max ) + idx_max[i] = _idx_max ? _idx_max[i] : -1; + } + } + + if( value_min ) + *value_min = (float)minVal; + + if( value_max ) + *value_max = (float)maxVal; +} + + +// Compares two histograms using one of a few methods +CV_IMPL double +cvCompareHist( const CvHistogram* hist1, + const CvHistogram* hist2, + int method ) +{ + int i; + int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1; + + if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) ) + CV_Error( CV_StsBadArg, "Invalid histogram header[s]" ); + + if( CV_IS_SPARSE_MAT(hist1->bins) != CV_IS_SPARSE_MAT(hist2->bins)) + CV_Error(CV_StsUnmatchedFormats, "One of histograms is sparse and other is not"); + + if( !CV_IS_SPARSE_MAT(hist1->bins) ) + { + cv::Mat H1((const CvMatND*)hist1->bins), H2((const CvMatND*)hist2->bins); + return cv::compareHist(H1, H2, method); + } + + int dims1 = cvGetDims( hist1->bins, size1 ); + int dims2 = cvGetDims( hist2->bins, size2 ); + + if( dims1 != dims2 ) + CV_Error( CV_StsUnmatchedSizes, + "The histograms have different numbers of dimensions" ); + + for( i = 0; i < dims1; i++ ) + { + if( size1[i] != size2[i] ) + CV_Error( CV_StsUnmatchedSizes, "The histograms have different sizes" ); + total *= size1[i]; + } + + double result = 0; + CvSparseMat* mat1 = (CvSparseMat*)(hist1->bins); + CvSparseMat* mat2 = (CvSparseMat*)(hist2->bins); + CvSparseMatIterator iterator; + CvSparseNode *node1, *node2; + + if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR ) + { + CvSparseMat* t; + CV_SWAP( mat1, mat2, t ); + } + + if( method == CV_COMP_CHISQR ) + { + for( node1 = cvInitSparseMatIterator( mat1, &iterator ); + node1 != 0; node1 = cvGetNextSparseNode( &iterator )) + { + double v1 = *(float*)CV_NODE_VAL(mat1,node1); + uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), 0, 0, &node1->hashval ); + double v2 = node2_data ? *(float*)node2_data : 0.f; + double a = v1 - v2; + double b = v1; + if( fabs(b) > DBL_EPSILON ) + result += a*a/b; + } + } + else if( method == CV_COMP_CORREL ) + { + double s1 = 0, s11 = 0; + double s2 = 0, s22 = 0; + double s12 = 0; + double num, denom2, scale = 1./total; + + for( node1 = cvInitSparseMatIterator( mat1, &iterator ); + node1 != 0; node1 = cvGetNextSparseNode( &iterator )) + { + double v1 = *(float*)CV_NODE_VAL(mat1,node1); + uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), + 0, 0, &node1->hashval ); + if( node2_data ) + { + double v2 = *(float*)node2_data; + s12 += v1*v2; + } + s1 += v1; + s11 += v1*v1; + } + + for( node2 = cvInitSparseMatIterator( mat2, &iterator ); + node2 != 0; node2 = cvGetNextSparseNode( &iterator )) + { + double v2 = *(float*)CV_NODE_VAL(mat2,node2); + s2 += v2; + s22 += v2*v2; + } + + num = s12 - s1*s2*scale; + denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale); + result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1; + } + else if( method == CV_COMP_INTERSECT ) + { + for( node1 = cvInitSparseMatIterator( mat1, &iterator ); + node1 != 0; node1 = cvGetNextSparseNode( &iterator )) + { + float v1 = *(float*)CV_NODE_VAL(mat1,node1); + uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), + 0, 0, &node1->hashval ); + if( node2_data ) + { + float v2 = *(float*)node2_data; + if( v1 <= v2 ) + result += v1; + else + result += v2; + } + } + } + else if( method == CV_COMP_BHATTACHARYYA ) + { + double s1 = 0, s2 = 0; + + for( node1 = cvInitSparseMatIterator( mat1, &iterator ); + node1 != 0; node1 = cvGetNextSparseNode( &iterator )) + { + double v1 = *(float*)CV_NODE_VAL(mat1,node1); + uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), + 0, 0, &node1->hashval ); + s1 += v1; + if( node2_data ) + { + double v2 = *(float*)node2_data; + result += sqrt(v1 * v2); + } + } + + for( node1 = cvInitSparseMatIterator( mat2, &iterator ); + node1 != 0; node1 = cvGetNextSparseNode( &iterator )) + { + double v2 = *(float*)CV_NODE_VAL(mat2,node1); + s2 += v2; + } + + s1 *= s2; + s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.; + result = 1. - result*s1; + result = sqrt(MAX(result,0.)); + } + else + CV_Error( CV_StsBadArg, "Unknown comparison method" ); + + return result; +} + +// copies one histogram to another +CV_IMPL void +cvCopyHist( const CvHistogram* src, CvHistogram** _dst ) +{ + if( !_dst ) + CV_Error( CV_StsNullPtr, "Destination double pointer is NULL" ); + + CvHistogram* dst = *_dst; + + if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) ) + CV_Error( CV_StsBadArg, "Invalid histogram header[s]" ); + + bool eq = false; + int size1[CV_MAX_DIM]; + bool is_sparse = CV_IS_SPARSE_MAT(src->bins); + int dims1 = cvGetDims( src->bins, size1 ); + + if( dst && (is_sparse == CV_IS_SPARSE_MAT(dst->bins))) + { + int size2[CV_MAX_DIM]; + int dims2 = cvGetDims( dst->bins, size2 ); + + if( dims1 == dims2 ) + { + int i; + + for( i = 0; i < dims1; i++ ) + { + if( size1[i] != size2[i] ) + break; + } + + eq = (i == dims1); + } + } + + if( !eq ) + { + cvReleaseHist( _dst ); + dst = cvCreateHist( dims1, size1, !is_sparse ? CV_HIST_ARRAY : CV_HIST_SPARSE, 0, 0 ); + *_dst = dst; + } + + if( CV_HIST_HAS_RANGES( src )) + { + float* ranges[CV_MAX_DIM]; + float** thresh = 0; + + if( CV_IS_UNIFORM_HIST( src )) + { + for( int i = 0; i < dims1; i++ ) + ranges[i] = (float*)src->thresh[i]; + + thresh = ranges; + } + else + { + thresh = src->thresh2; + } + + cvSetHistBinRanges( dst, thresh, CV_IS_UNIFORM_HIST(src)); + } + + cvCopy( src->bins, dst->bins ); +} + + +// Sets a value range for every histogram bin +CV_IMPL void +cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) +{ + int dims, size[CV_MAX_DIM], total = 0; + int i, j; + + if( !ranges ) + CV_Error( CV_StsNullPtr, "NULL ranges pointer" ); + + if( !CV_IS_HIST(hist) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + + dims = cvGetDims( hist->bins, size ); + for( i = 0; i < dims; i++ ) + total += size[i]+1; + + if( uniform ) + { + for( i = 0; i < dims; i++ ) + { + if( !ranges[i] ) + CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + hist->thresh[i][0] = ranges[i][0]; + hist->thresh[i][1] = ranges[i][1]; + } + + hist->type |= CV_HIST_UNIFORM_FLAG + CV_HIST_RANGES_FLAG; + } + else + { + float* dim_ranges; + + if( !hist->thresh2 ) + { + hist->thresh2 = (float**)cvAlloc( + dims*sizeof(hist->thresh2[0])+ + total*sizeof(hist->thresh2[0][0])); + } + dim_ranges = (float*)(hist->thresh2 + dims); + + for( i = 0; i < dims; i++ ) + { + float val0 = -FLT_MAX; + + if( !ranges[i] ) + CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + + for( j = 0; j <= size[i]; j++ ) + { + float val = ranges[i][j]; + if( val <= val0 ) + CV_Error(CV_StsOutOfRange, "Bin ranges should go in ascenting order"); + val0 = dim_ranges[j] = val; + } + + hist->thresh2[i] = dim_ranges; + dim_ranges += size[i] + 1; + } + + hist->type |= CV_HIST_RANGES_FLAG; + hist->type &= ~CV_HIST_UNIFORM_FLAG; + } +} + + +CV_IMPL void +cvCalcArrHist( CvArr** img, CvHistogram* hist, int accumulate, const CvArr* mask ) +{ + if( !CV_IS_HIST(hist)) + CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + + if( !img ) + CV_Error( CV_StsNullPtr, "Null double array pointer" ); + + int size[CV_MAX_DIM]; + int i, dims = cvGetDims( hist->bins, size); + bool uniform = CV_IS_UNIFORM_HIST(hist); + + cv::vector images(dims); + for( i = 0; i < dims; i++ ) + images[i] = cv::cvarrToMat(img[i]); + + cv::Mat _mask; + if( mask ) + _mask = cv::cvarrToMat(mask); + + const float* uranges[CV_MAX_DIM] = {0}; + const float** ranges = 0; + + if( hist->type & CV_HIST_RANGES_FLAG ) + { + ranges = (const float**)hist->thresh2; + if( uniform ) + { + for( i = 0; i < dims; i++ ) + uranges[i] = &hist->thresh[i][0]; + ranges = uranges; + } + } + + if( !CV_IS_SPARSE_HIST(hist) ) + { + cv::Mat H((const CvMatND*)hist->bins); + cv::calcHist( &images[0], (int)images.size(), 0, _mask, + H, cvGetDims(hist->bins), H.size, ranges, uniform, accumulate != 0 ); + } + else + { + CvSparseMat* sparsemat = (CvSparseMat*)hist->bins; + + if( !accumulate ) + cvZero( hist->bins ); + cv::SparseMat sH(sparsemat); + cv::calcHist( &images[0], (int)images.size(), 0, _mask, sH, sH.dims(), + sH.dims() > 0 ? sH.hdr->size : 0, ranges, uniform, accumulate != 0, true ); + + if( accumulate ) + cvZero( sparsemat ); + + cv::SparseMatConstIterator it = sH.begin(); + int nz = (int)sH.nzcount(); + for( i = 0; i < nz; i++, ++it ) + *(float*)cvPtrND(sparsemat, it.node()->idx, 0, -2) = (float)*(const int*)it.ptr; + } +} + + +CV_IMPL void +cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist ) +{ + if( !CV_IS_HIST(hist)) + CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + + if( !img ) + CV_Error( CV_StsNullPtr, "Null double array pointer" ); + + int size[CV_MAX_DIM]; + int i, dims = cvGetDims( hist->bins, size ); + + bool uniform = CV_IS_UNIFORM_HIST(hist); + const float* uranges[CV_MAX_DIM] = {0}; + const float** ranges = 0; + + if( hist->type & CV_HIST_RANGES_FLAG ) + { + ranges = (const float**)hist->thresh2; + if( uniform ) + { + for( i = 0; i < dims; i++ ) + uranges[i] = &hist->thresh[i][0]; + ranges = uranges; + } + } + + cv::vector images(dims); + for( i = 0; i < dims; i++ ) + images[i] = cv::cvarrToMat(img[i]); + + cv::Mat _dst = cv::cvarrToMat(dst); + + CV_Assert( _dst.size() == images[0].size() && _dst.depth() == images[0].depth() ); + + if( !CV_IS_SPARSE_HIST(hist) ) + { + cv::Mat H((const CvMatND*)hist->bins); + cv::calcBackProject( &images[0], (int)images.size(), + 0, H, _dst, ranges, 1, uniform ); + } + else + { + cv::SparseMat sH((const CvSparseMat*)hist->bins); + cv::calcBackProject( &images[0], (int)images.size(), + 0, sH, _dst, ranges, 1, uniform ); + } +} + + +////////////////////// B A C K P R O J E C T P A T C H ///////////////////////// + +CV_IMPL void +cvCalcArrBackProjectPatch( CvArr** arr, CvArr* dst, CvSize patch_size, CvHistogram* hist, + int method, double norm_factor ) +{ + CvHistogram* model = 0; + + IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM]; + IplROI roi; + CvMat dststub, *dstmat; + int i, dims; + int x, y; + CvSize size; + + if( !CV_IS_HIST(hist)) + CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + + if( !arr ) + CV_Error( CV_StsNullPtr, "Null double array pointer" ); + + if( norm_factor <= 0 ) + CV_Error( CV_StsOutOfRange, + "Bad normalization factor (set it to 1.0 if unsure)" ); + + if( patch_size.width <= 0 || patch_size.height <= 0 ) + CV_Error( CV_StsBadSize, "The patch width and height must be positive" ); + + dims = cvGetDims( hist->bins ); + cvNormalizeHist( hist, norm_factor ); + + for( i = 0; i < dims; i++ ) + { + CvMat stub, *mat; + mat = cvGetMat( arr[i], &stub, 0, 0 ); + img[i] = cvGetImage( mat, &imgstub[i] ); + img[i]->roi = &roi; + } + + dstmat = cvGetMat( dst, &dststub, 0, 0 ); + if( CV_MAT_TYPE( dstmat->type ) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, "Resultant image must have 32fC1 type" ); + + if( dstmat->cols != img[0]->width - patch_size.width + 1 || + dstmat->rows != img[0]->height - patch_size.height + 1 ) + CV_Error( CV_StsUnmatchedSizes, + "The output map must be (W-w+1 x H-h+1), " + "where the input images are (W x H) each and the patch is (w x h)" ); + + cvCopyHist( hist, &model ); + + size = cvGetMatSize(dstmat); + roi.coi = 0; + roi.width = patch_size.width; + roi.height = patch_size.height; + + for( y = 0; y < size.height; y++ ) + { + for( x = 0; x < size.width; x++ ) + { + double result; + roi.xOffset = x; + roi.yOffset = y; + + cvCalcHist( img, model ); + cvNormalizeHist( model, norm_factor ); + result = cvCompareHist( model, hist, method ); + CV_MAT_ELEM( *dstmat, float, y, x ) = (float)result; + } + } + + cvReleaseHist( &model ); +} + + +// Calculates Bayes probabilistic histograms +CV_IMPL void +cvCalcBayesianProb( CvHistogram** src, int count, CvHistogram** dst ) +{ + int i; + + if( !src || !dst ) + CV_Error( CV_StsNullPtr, "NULL histogram array pointer" ); + + if( count < 2 ) + CV_Error( CV_StsOutOfRange, "Too small number of histograms" ); + + for( i = 0; i < count; i++ ) + { + if( !CV_IS_HIST(src[i]) || !CV_IS_HIST(dst[i]) ) + CV_Error( CV_StsBadArg, "Invalid histogram header" ); + + if( !CV_IS_MATND(src[i]->bins) || !CV_IS_MATND(dst[i]->bins) ) + CV_Error( CV_StsBadArg, "The function supports dense histograms only" ); + } + + cvZero( dst[0]->bins ); + // dst[0] = src[0] + ... + src[count-1] + for( i = 0; i < count; i++ ) + cvAdd( src[i]->bins, dst[0]->bins, dst[0]->bins ); + + cvDiv( 0, dst[0]->bins, dst[0]->bins ); + + // dst[i] = src[i]*(1/dst[0]) + for( i = count - 1; i >= 0; i-- ) + cvMul( src[i]->bins, dst[0]->bins, dst[i]->bins ); +} + + +CV_IMPL void +cvCalcProbDensity( const CvHistogram* hist, const CvHistogram* hist_mask, + CvHistogram* hist_dens, double scale ) +{ + if( scale <= 0 ) + CV_Error( CV_StsOutOfRange, "scale must be positive" ); + + if( !CV_IS_HIST(hist) || !CV_IS_HIST(hist_mask) || !CV_IS_HIST(hist_dens) ) + CV_Error( CV_StsBadArg, "Invalid histogram pointer[s]" ); + + { + CvArr* arrs[] = { hist->bins, hist_mask->bins, hist_dens->bins }; + CvMatND stubs[3]; + CvNArrayIterator iterator; + + cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ); + + if( CV_MAT_TYPE(iterator.hdr[0]->type) != CV_32FC1 ) + CV_Error( CV_StsUnsupportedFormat, "All histograms must have 32fC1 type" ); + + do + { + const float* srcdata = (const float*)(iterator.ptr[0]); + const float* maskdata = (const float*)(iterator.ptr[1]); + float* dstdata = (float*)(iterator.ptr[2]); + int i; + + for( i = 0; i < iterator.size.width; i++ ) + { + float s = srcdata[i]; + float m = maskdata[i]; + if( s > FLT_EPSILON ) + if( m <= s ) + dstdata[i] = (float)(m*scale/s); + else + dstdata[i] = (float)scale; + else + dstdata[i] = (float)0; + } + } + while( cvNextNArraySlice( &iterator )); + } +} + +class EqualizeHistCalcHist_Invoker +{ +public: + enum {HIST_SZ = 256}; + +#ifdef HAVE_TBB + typedef tbb::mutex* MutextPtr; +#else + typedef void* MutextPtr; +#endif + + EqualizeHistCalcHist_Invoker(cv::Mat& src, int* histogram, MutextPtr histogramLock) + : src_(src), globalHistogram_(histogram), histogramLock_(histogramLock) + { } + + void operator()( const cv::BlockedRange& rowRange ) const + { + int localHistogram[HIST_SZ] = {0, }; + + const size_t sstep = src_.step; + + int width = src_.cols; + int height = rowRange.end() - rowRange.begin(); + + if (src_.isContinuous()) + { + width *= height; + height = 1; + } + + for (const uchar* ptr = src_.ptr(rowRange.begin()); height--; ptr += sstep) + { + int x = 0; + for (; x <= width - 4; x += 4) + { + int t0 = ptr[x], t1 = ptr[x+1]; + localHistogram[t0]++; localHistogram[t1]++; + t0 = ptr[x+2]; t1 = ptr[x+3]; + localHistogram[t0]++; localHistogram[t1]++; + } + + for (; x < width; ++x) + localHistogram[ptr[x]]++; + } + +#ifdef HAVE_TBB + tbb::mutex::scoped_lock lock(*histogramLock_); +#endif + + for( int i = 0; i < HIST_SZ; i++ ) + globalHistogram_[i] += localHistogram[i]; + } + + static bool isWorthParallel( const cv::Mat& src ) + { +#ifdef HAVE_TBB + return ( src.total() >= 640*480 ); +#else + (void)src; + return false; +#endif + } + +private: + EqualizeHistCalcHist_Invoker& operator=(const EqualizeHistCalcHist_Invoker&); + + cv::Mat& src_; + int* globalHistogram_; + MutextPtr histogramLock_; +}; + +class EqualizeHistLut_Invoker +{ +public: + EqualizeHistLut_Invoker( cv::Mat& src, cv::Mat& dst, int* lut ) + : src_(src), + dst_(dst), + lut_(lut) + { } + + void operator()( const cv::BlockedRange& rowRange ) const + { + const size_t sstep = src_.step; + const size_t dstep = dst_.step; + + int width = src_.cols; + int height = rowRange.end() - rowRange.begin(); + int* lut = lut_; + + if (src_.isContinuous() && dst_.isContinuous()) + { + width *= height; + height = 1; + } + + const uchar* sptr = src_.ptr(rowRange.begin()); + uchar* dptr = dst_.ptr(rowRange.begin()); + + for (; height--; sptr += sstep, dptr += dstep) + { + int x = 0; + for (; x <= width - 4; x += 4) + { + int v0 = sptr[x]; + int v1 = sptr[x+1]; + int x0 = lut[v0]; + int x1 = lut[v1]; + dptr[x] = (uchar)x0; + dptr[x+1] = (uchar)x1; + + v0 = sptr[x+2]; + v1 = sptr[x+3]; + x0 = lut[v0]; + x1 = lut[v1]; + dptr[x+2] = (uchar)x0; + dptr[x+3] = (uchar)x1; + } + + for (; x < width; ++x) + dptr[x] = (uchar)lut[sptr[x]]; + } + } + + static bool isWorthParallel( const cv::Mat& src ) + { +#ifdef HAVE_TBB + return ( src.total() >= 640*480 ); +#else + (void)src; + return false; +#endif + } + +private: + EqualizeHistLut_Invoker& operator=(const EqualizeHistLut_Invoker&); + + cv::Mat& src_; + cv::Mat& dst_; + int* lut_; +}; + +CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr ) +{ + cv::equalizeHist(cv::cvarrToMat(srcarr), cv::cvarrToMat(dstarr)); +} + +void cv::equalizeHist( InputArray _src, OutputArray _dst ) +{ + Mat src = _src.getMat(); + CV_Assert( src.type() == CV_8UC1 ); + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if(src.empty()) + return; + +#ifdef HAVE_TBB + tbb::mutex histogramLockInstance; + EqualizeHistCalcHist_Invoker::MutextPtr histogramLock = &histogramLockInstance; +#else + EqualizeHistCalcHist_Invoker::MutextPtr histogramLock = 0; +#endif + + const int hist_sz = EqualizeHistCalcHist_Invoker::HIST_SZ; + int hist[hist_sz] = {0,}; + int lut[hist_sz]; + + EqualizeHistCalcHist_Invoker calcBody(src, hist, histogramLock); + EqualizeHistLut_Invoker lutBody(src, dst, lut); + cv::BlockedRange heightRange(0, src.rows); + + if(EqualizeHistCalcHist_Invoker::isWorthParallel(src)) + parallel_for(heightRange, calcBody); + else + calcBody(heightRange); + + int i = 0; + while (!hist[i]) ++i; + + int total = (int)src.total(); + if (hist[i] == total) + { + dst.setTo(i); + return; + } + + float scale = (hist_sz - 1.f)/(total - hist[i]); + int sum = 0; + + for (lut[i++] = 0; i < hist_sz; ++i) + { + sum += hist[i]; + lut[i] = saturate_cast(sum * scale); + } + + if(EqualizeHistLut_Invoker::isWorthParallel(src)) + parallel_for(heightRange, lutBody); + else + lutBody(heightRange); +} + +// ---------------------------------------------------------------------- +// CLAHE + +namespace +{ + class CLAHE_CalcLut_Body : public cv::ParallelLoopBody + { + public: + CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY, int clipLimit, float lutScale) : + src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY), clipLimit_(clipLimit), lutScale_(lutScale) + { + } + + void operator ()(const cv::Range& range) const; + + private: + cv::Mat src_; + mutable cv::Mat lut_; + + cv::Size tileSize_; + int tilesX_; + int tilesY_; + int clipLimit_; + float lutScale_; + }; + + void CLAHE_CalcLut_Body::operator ()(const cv::Range& range) const + { + const int histSize = 256; + + uchar* tileLut = lut_.ptr(range.start); + const size_t lut_step = lut_.step; + + for (int k = range.start; k < range.end; ++k, tileLut += lut_step) + { + const int ty = k / tilesX_; + const int tx = k % tilesX_; + + // retrieve tile submatrix + + cv::Rect tileROI; + tileROI.x = tx * tileSize_.width; + tileROI.y = ty * tileSize_.height; + tileROI.width = tileSize_.width; + tileROI.height = tileSize_.height; + + const cv::Mat tile = src_(tileROI); + + // calc histogram + + int tileHist[histSize] = {0, }; + + int height = tileROI.height; + const size_t sstep = tile.step; + for (const uchar* ptr = tile.ptr(0); height--; ptr += sstep) + { + int x = 0; + for (; x <= tileROI.width - 4; x += 4) + { + int t0 = ptr[x], t1 = ptr[x+1]; + tileHist[t0]++; tileHist[t1]++; + t0 = ptr[x+2]; t1 = ptr[x+3]; + tileHist[t0]++; tileHist[t1]++; + } + + for (; x < tileROI.width; ++x) + tileHist[ptr[x]]++; + } + + // clip histogram + + if (clipLimit_ > 0) + { + // how many pixels were clipped + int clipped = 0; + for (int i = 0; i < histSize; ++i) + { + if (tileHist[i] > clipLimit_) + { + clipped += tileHist[i] - clipLimit_; + tileHist[i] = clipLimit_; + } + } + + // redistribute clipped pixels + int redistBatch = clipped / histSize; + int residual = clipped - redistBatch * histSize; + + for (int i = 0; i < histSize; ++i) + tileHist[i] += redistBatch; + + for (int i = 0; i < residual; ++i) + tileHist[i]++; + } + + // calc Lut + + int sum = 0; + for (int i = 0; i < histSize; ++i) + { + sum += tileHist[i]; + tileLut[i] = cv::saturate_cast(sum * lutScale_); + } + } + } + + class CLAHE_Interpolation_Body : public cv::ParallelLoopBody + { + public: + CLAHE_Interpolation_Body(const cv::Mat& src, cv::Mat& dst, const cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY) : + src_(src), dst_(dst), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY) + { + } + + void operator ()(const cv::Range& range) const; + + private: + cv::Mat src_; + mutable cv::Mat dst_; + cv::Mat lut_; + + cv::Size tileSize_; + int tilesX_; + int tilesY_; + }; + + void CLAHE_Interpolation_Body::operator ()(const cv::Range& range) const + { + const size_t lut_step = lut_.step; + + for (int y = range.start; y < range.end; ++y) + { + const uchar* srcRow = src_.ptr(y); + uchar* dstRow = dst_.ptr(y); + + const float tyf = (static_cast(y) / tileSize_.height) - 0.5f; + + int ty1 = cvFloor(tyf); + int ty2 = ty1 + 1; + + const float ya = tyf - ty1; + + ty1 = std::max(ty1, 0); + ty2 = std::min(ty2, tilesY_ - 1); + + const uchar* lutPlane1 = lut_.ptr(ty1 * tilesX_); + const uchar* lutPlane2 = lut_.ptr(ty2 * tilesX_); + + for (int x = 0; x < src_.cols; ++x) + { + const float txf = (static_cast(x) / tileSize_.width) - 0.5f; + + int tx1 = cvFloor(txf); + int tx2 = tx1 + 1; + + const float xa = txf - tx1; + + tx1 = std::max(tx1, 0); + tx2 = std::min(tx2, tilesX_ - 1); + + const int srcVal = srcRow[x]; + + const size_t ind1 = tx1 * lut_step + srcVal; + const size_t ind2 = tx2 * lut_step + srcVal; + + float res = 0; + + res += lutPlane1[ind1] * ((1.0f - xa) * (1.0f - ya)); + res += lutPlane1[ind2] * ((xa) * (1.0f - ya)); + res += lutPlane2[ind1] * ((1.0f - xa) * (ya)); + res += lutPlane2[ind2] * ((xa) * (ya)); + + dstRow[x] = cv::saturate_cast(res); + } + } + } + + class CLAHE_Impl : public cv::CLAHE + { + public: + CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8); + + cv::AlgorithmInfo* info() const; + + void apply(cv::InputArray src, cv::OutputArray dst); + + void setClipLimit(double clipLimit); + double getClipLimit() const; + + void setTilesGridSize(cv::Size tileGridSize); + cv::Size getTilesGridSize() const; + + void collectGarbage(); + + private: + double clipLimit_; + int tilesX_; + int tilesY_; + + cv::Mat srcExt_; + cv::Mat lut_; + }; + + CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) : + clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY) + { + } + + CV_INIT_ALGORITHM(CLAHE_Impl, "CLAHE", + obj.info()->addParam(obj, "clipLimit", obj.clipLimit_); + obj.info()->addParam(obj, "tilesX", obj.tilesX_); + obj.info()->addParam(obj, "tilesY", obj.tilesY_)) + + void CLAHE_Impl::apply(cv::InputArray _src, cv::OutputArray _dst) + { + cv::Mat src = _src.getMat(); + + CV_Assert( src.type() == CV_8UC1 ); + + _dst.create( src.size(), src.type() ); + cv::Mat dst = _dst.getMat(); + + const int histSize = 256; + + lut_.create(tilesX_ * tilesY_, histSize, CV_8UC1); + + cv::Size tileSize; + cv::Mat srcForLut; + + if (src.cols % tilesX_ == 0 && src.rows % tilesY_ == 0) + { + tileSize = cv::Size(src.cols / tilesX_, src.rows / tilesY_); + srcForLut = src; + } + else + { + cv::copyMakeBorder(src, srcExt_, 0, tilesY_ - (src.rows % tilesY_), 0, tilesX_ - (src.cols % tilesX_), cv::BORDER_REFLECT_101); + + tileSize = cv::Size(srcExt_.cols / tilesX_, srcExt_.rows / tilesY_); + srcForLut = srcExt_; + } + + const int tileSizeTotal = tileSize.area(); + const float lutScale = static_cast(histSize - 1) / tileSizeTotal; + + int clipLimit = 0; + if (clipLimit_ > 0.0) + { + clipLimit = static_cast(clipLimit_ * tileSizeTotal / histSize); + clipLimit = std::max(clipLimit, 1); + } + + CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, tilesY_, clipLimit, lutScale); + cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), calcLutBody); + + CLAHE_Interpolation_Body interpolationBody(src, dst, lut_, tileSize, tilesX_, tilesY_); + cv::parallel_for_(cv::Range(0, src.rows), interpolationBody); + } + + void CLAHE_Impl::setClipLimit(double clipLimit) + { + clipLimit_ = clipLimit; + } + + double CLAHE_Impl::getClipLimit() const + { + return clipLimit_; + } + + void CLAHE_Impl::setTilesGridSize(cv::Size tileGridSize) + { + tilesX_ = tileGridSize.width; + tilesY_ = tileGridSize.height; + } + + cv::Size CLAHE_Impl::getTilesGridSize() const + { + return cv::Size(tilesX_, tilesY_); + } + + void CLAHE_Impl::collectGarbage() + { + srcExt_.release(); + lut_.release(); + } +} + +cv::Ptr cv::createCLAHE(double clipLimit, cv::Size tileGridSize) +{ + return new CLAHE_Impl(clipLimit, tileGridSize.width, tileGridSize.height); +} + +// ---------------------------------------------------------------------- + +/* Implementation of RTTI and Generic Functions for CvHistogram */ +#define CV_TYPE_NAME_HIST "opencv-hist" + +static int icvIsHist( const void * ptr ) +{ + return CV_IS_HIST( ((CvHistogram*)ptr) ); +} + +static CvHistogram * icvCloneHist( const CvHistogram * src ) +{ + CvHistogram * dst=NULL; + cvCopyHist(src, &dst); + return dst; +} + +static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ) +{ + CvHistogram * h = 0; + int type = 0; + int is_uniform = 0; + int have_ranges = 0; + + h = (CvHistogram *)cvAlloc( sizeof(CvHistogram) ); + + type = cvReadIntByName( fs, node, "type", 0 ); + is_uniform = cvReadIntByName( fs, node, "is_uniform", 0 ); + have_ranges = cvReadIntByName( fs, node, "have_ranges", 0 ); + h->type = CV_HIST_MAGIC_VAL | type | + (is_uniform ? CV_HIST_UNIFORM_FLAG : 0) | + (have_ranges ? CV_HIST_RANGES_FLAG : 0); + + if(type == CV_HIST_ARRAY) + { + // read histogram bins + CvMatND* mat = (CvMatND*)cvReadByName( fs, node, "mat" ); + int i, sizes[CV_MAX_DIM]; + + if(!CV_IS_MATND(mat)) + CV_Error( CV_StsError, "Expected CvMatND"); + + for(i=0; idims; i++) + sizes[i] = mat->dim[i].size; + + cvInitMatNDHeader( &(h->mat), mat->dims, sizes, mat->type, mat->data.ptr ); + h->bins = &(h->mat); + + // take ownership of refcount pointer as well + h->mat.refcount = mat->refcount; + + // increase refcount so freeing temp header doesn't free data + cvIncRefData( mat ); + + // free temporary header + cvReleaseMatND( &mat ); + } + else + { + h->bins = cvReadByName( fs, node, "bins" ); + if(!CV_IS_SPARSE_MAT(h->bins)){ + CV_Error( CV_StsError, "Unknown Histogram type"); + } + } + + // read thresholds + if(have_ranges) + { + int i, dims, size[CV_MAX_DIM], total = 0; + CvSeqReader reader; + CvFileNode * thresh_node; + + dims = cvGetDims( h->bins, size ); + for( i = 0; i < dims; i++ ) + total += size[i]+1; + + thresh_node = cvGetFileNodeByName( fs, node, "thresh" ); + if(!thresh_node) + CV_Error( CV_StsError, "'thresh' node is missing"); + cvStartReadRawData( fs, thresh_node, &reader ); + + if(is_uniform) + { + for(i=0; ithresh[i], "f" ); + h->thresh2 = NULL; + } + else + { + float* dim_ranges; + h->thresh2 = (float**)cvAlloc( + dims*sizeof(h->thresh2[0])+ + total*sizeof(h->thresh2[0][0])); + dim_ranges = (float*)(h->thresh2 + dims); + for(i=0; i < dims; i++) + { + h->thresh2[i] = dim_ranges; + cvReadRawDataSlice( fs, &reader, size[i]+1, dim_ranges, "f" ); + dim_ranges += size[i] + 1; + } + } + } + + return h; +} + +static void icvWriteHist( CvFileStorage* fs, const char* name, + const void* struct_ptr, CvAttrList /*attributes*/ ) +{ + const CvHistogram * hist = (const CvHistogram *) struct_ptr; + int sizes[CV_MAX_DIM]; + int dims; + int i; + int is_uniform, have_ranges; + + cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_HIST ); + + is_uniform = (CV_IS_UNIFORM_HIST(hist) ? 1 : 0); + have_ranges = (hist->type & CV_HIST_RANGES_FLAG ? 1 : 0); + + cvWriteInt( fs, "type", (hist->type & 1) ); + cvWriteInt( fs, "is_uniform", is_uniform ); + cvWriteInt( fs, "have_ranges", have_ranges ); + if(!CV_IS_SPARSE_HIST(hist)) + cvWrite( fs, "mat", &(hist->mat) ); + else + cvWrite( fs, "bins", hist->bins ); + + // write thresholds + if(have_ranges){ + dims = cvGetDims( hist->bins, sizes ); + cvStartWriteStruct( fs, "thresh", CV_NODE_SEQ + CV_NODE_FLOW ); + if(is_uniform){ + for(i=0; ithresh[i], 2, "f" ); + } + } + else{ + for(i=0; ithresh2[i], sizes[i]+1, "f" ); + } + } + cvEndWriteStruct( fs ); + } + + cvEndWriteStruct( fs ); +} + + +CvType hist_type( CV_TYPE_NAME_HIST, icvIsHist, (CvReleaseFunc)cvReleaseHist, + icvReadHist, icvWriteHist, (CvCloneFunc)icvCloneHist ); + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/hough.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/hough.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/hough.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/hough.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1143 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include "_list.h" + +#define halfPi ((float)(CV_PI*0.5)) +#define Pi ((float)CV_PI) +#define a0 0 /*-4.172325e-7f*/ /*(-(float)0x7)/((float)0x1000000); */ +#define a1 1.000025f /*((float)0x1922253)/((float)0x1000000)*2/Pi; */ +#define a2 -2.652905e-4f /*(-(float)0x2ae6)/((float)0x1000000)*4/(Pi*Pi); */ +#define a3 -0.165624f /*(-(float)0xa45511)/((float)0x1000000)*8/(Pi*Pi*Pi); */ +#define a4 -1.964532e-3f /*(-(float)0x30fd3)/((float)0x1000000)*16/(Pi*Pi*Pi*Pi); */ +#define a5 1.02575e-2f /*((float)0x191cac)/((float)0x1000000)*32/(Pi*Pi*Pi*Pi*Pi); */ +#define a6 -9.580378e-4f /*(-(float)0x3af27)/((float)0x1000000)*64/(Pi*Pi*Pi*Pi*Pi*Pi); */ + +#define _sin(x) ((((((a6*(x) + a5)*(x) + a4)*(x) + a3)*(x) + a2)*(x) + a1)*(x) + a0) +#define _cos(x) _sin(halfPi - (x)) + +/****************************************************************************************\ +* Classical Hough Transform * +\****************************************************************************************/ + +typedef struct CvLinePolar +{ + float rho; + float angle; +} +CvLinePolar; + +/*=====================================================================================*/ + +#define hough_cmp_gt(l1,l2) (aux[l1] > aux[l2]) + +static CV_IMPLEMENT_QSORT_EX( icvHoughSortDescent32s, int, hough_cmp_gt, const int* ) + +/* +Here image is an input raster; +step is it's step; size characterizes it's ROI; +rho and theta are discretization steps (in pixels and radians correspondingly). +threshold is the minimum number of pixels in the feature for it +to be a candidate for line. lines is the output +array of (rho, theta) pairs. linesMax is the buffer size (number of pairs). +Functions return the actual number of found lines. +*/ +static void +icvHoughLinesStandard( const CvMat* img, float rho, float theta, + int threshold, CvSeq *lines, int linesMax ) +{ + cv::AutoBuffer _accum, _sort_buf; + cv::AutoBuffer _tabSin, _tabCos; + + const uchar* image; + int step, width, height; + int numangle, numrho; + int total = 0; + int i, j; + float irho = 1 / rho; + double scale; + + CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 ); + + image = img->data.ptr; + step = img->step; + width = img->cols; + height = img->rows; + + numangle = cvRound(CV_PI / theta); + numrho = cvRound(((width + height) * 2 + 1) / rho); + + _accum.allocate((numangle+2) * (numrho+2)); + _sort_buf.allocate(numangle * numrho); + _tabSin.allocate(numangle); + _tabCos.allocate(numangle); + int *accum = _accum, *sort_buf = _sort_buf; + float *tabSin = _tabSin, *tabCos = _tabCos; + + memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) ); + + float ang = 0; + for(int n = 0; n < numangle; ang += theta, n++ ) + { + tabSin[n] = (float)(sin((double)ang) * irho); + tabCos[n] = (float)(cos((double)ang) * irho); + } + + // stage 1. fill accumulator + for( i = 0; i < height; i++ ) + for( j = 0; j < width; j++ ) + { + if( image[i * step + j] != 0 ) + for(int n = 0; n < numangle; n++ ) + { + int r = cvRound( j * tabCos[n] + i * tabSin[n] ); + r += (numrho - 1) / 2; + accum[(n+1) * (numrho+2) + r+1]++; + } + } + + // stage 2. find local maximums + for(int r = 0; r < numrho; r++ ) + for(int n = 0; n < numangle; n++ ) + { + int base = (n+1) * (numrho+2) + r+1; + if( accum[base] > threshold && + accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] && + accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] ) + sort_buf[total++] = base; + } + + // stage 3. sort the detected lines by accumulator value + icvHoughSortDescent32s( sort_buf, total, accum ); + + // stage 4. store the first min(total,linesMax) lines to the output buffer + linesMax = MIN(linesMax, total); + scale = 1./(numrho+2); + for( i = 0; i < linesMax; i++ ) + { + CvLinePolar line; + int idx = sort_buf[i]; + int n = cvFloor(idx*scale) - 1; + int r = idx - (n+1)*(numrho+2) - 1; + line.rho = (r - (numrho - 1)*0.5f) * rho; + line.angle = n * theta; + cvSeqPush( lines, &line ); + } +} + + +/****************************************************************************************\ +* Multi-Scale variant of Classical Hough Transform * +\****************************************************************************************/ + +//DECLARE_AND_IMPLEMENT_LIST( _index, h_ ); +IMPLEMENT_LIST( _index, h_ ) + +static void +icvHoughLinesSDiv( const CvMat* img, + float rho, float theta, int threshold, + int srn, int stn, + CvSeq* lines, int linesMax ) +{ + std::vector _caccum, _buffer; + std::vector _sinTable; + std::vector _x, _y; + float* sinTable; + int *x, *y; + uchar *caccum, *buffer; + _CVLIST* list = 0; + +#define _POINT(row, column)\ + (image_src[(row)*step+(column)]) + + uchar *mcaccum = 0; + int rn, tn; /* number of rho and theta discrete values */ + int index, i; + int ri, ti, ti1, ti0; + int row, col; + float r, t; /* Current rho and theta */ + float rv; /* Some temporary rho value */ + float irho; + float itheta; + float srho, stheta; + float isrho, istheta; + + const uchar* image_src; + int w, h, step; + int fn = 0; + float xc, yc; + + const float d2r = (float)(Pi / 180); + int sfn = srn * stn; + int fi; + int count; + int cmax = 0; + + CVPOS pos; + _index *pindex; + _index vi; + + CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 ); + CV_Assert( linesMax > 0 && rho > 0 && theta > 0 ); + + threshold = MIN( threshold, 255 ); + + image_src = img->data.ptr; + step = img->step; + w = img->cols; + h = img->rows; + + irho = 1 / rho; + itheta = 1 / theta; + srho = rho / srn; + stheta = theta / stn; + isrho = 1 / srho; + istheta = 1 / stheta; + + rn = cvFloor( sqrt( (double)w * w + (double)h * h ) * irho ); + tn = cvFloor( 2 * Pi * itheta ); + + list = h_create_list__index( linesMax < 1000 ? linesMax : 1000 ); + vi.value = threshold; + vi.rho = -1; + h_add_head__index( list, &vi ); + + /* Precalculating sin */ + _sinTable.resize( 5 * tn * stn ); + sinTable = &_sinTable[0]; + + for( index = 0; index < 5 * tn * stn; index++ ) + sinTable[index] = (float)cos( stheta * index * 0.2f ); + + _caccum.resize(rn * tn); + caccum = &_caccum[0]; + memset( caccum, 0, rn * tn * sizeof( caccum[0] )); + + /* Counting all feature pixels */ + for( row = 0; row < h; row++ ) + for( col = 0; col < w; col++ ) + fn += _POINT( row, col ) != 0; + + _x.resize(fn); + _y.resize(fn); + x = &_x[0]; + y = &_y[0]; + + /* Full Hough Transform (it's accumulator update part) */ + fi = 0; + for( row = 0; row < h; row++ ) + { + for( col = 0; col < w; col++ ) + { + if( _POINT( row, col )) + { + int halftn; + float r0; + float scale_factor; + int iprev = -1; + float phi, phi1; + float theta_it; /* Value of theta for iterating */ + + /* Remember the feature point */ + x[fi] = col; + y[fi] = row; + fi++; + + yc = (float) row + 0.5f; + xc = (float) col + 0.5f; + + /* Update the accumulator */ + t = (float) fabs( cvFastArctan( yc, xc ) * d2r ); + r = (float) sqrt( (double)xc * xc + (double)yc * yc ); + r0 = r * irho; + ti0 = cvFloor( (t + Pi / 2) * itheta ); + + caccum[ti0]++; + + theta_it = rho / r; + theta_it = theta_it < theta ? theta_it : theta; + scale_factor = theta_it * itheta; + halftn = cvFloor( Pi / theta_it ); + for( ti1 = 1, phi = theta_it - halfPi, phi1 = (theta_it + t) * itheta; + ti1 < halftn; ti1++, phi += theta_it, phi1 += scale_factor ) + { + rv = r0 * _cos( phi ); + i = cvFloor( rv ) * tn; + i += cvFloor( phi1 ); + assert( i >= 0 ); + assert( i < rn * tn ); + caccum[i] = (uchar) (caccum[i] + ((i ^ iprev) != 0)); + iprev = i; + if( cmax < caccum[i] ) + cmax = caccum[i]; + } + } + } + } + + /* Starting additional analysis */ + count = 0; + for( ri = 0; ri < rn; ri++ ) + { + for( ti = 0; ti < tn; ti++ ) + { + if( caccum[ri * tn + ti] > threshold ) + { + count++; + } + } + } + + if( count * 100 > rn * tn ) + { + icvHoughLinesStandard( img, rho, theta, threshold, lines, linesMax ); + return; + } + + _buffer.resize(srn * stn + 2); + buffer = &_buffer[0]; + mcaccum = buffer + 1; + + count = 0; + for( ri = 0; ri < rn; ri++ ) + { + for( ti = 0; ti < tn; ti++ ) + { + if( caccum[ri * tn + ti] > threshold ) + { + count++; + memset( mcaccum, 0, sfn * sizeof( uchar )); + + for( index = 0; index < fn; index++ ) + { + int ti2; + float r0; + + yc = (float) y[index] + 0.5f; + xc = (float) x[index] + 0.5f; + + /* Update the accumulator */ + t = (float) fabs( cvFastArctan( yc, xc ) * d2r ); + r = (float) sqrt( (double)xc * xc + (double)yc * yc ) * isrho; + ti0 = cvFloor( (t + Pi * 0.5f) * istheta ); + ti2 = (ti * stn - ti0) * 5; + r0 = (float) ri *srn; + + for( ti1 = 0 /*, phi = ti*theta - Pi/2 - t */ ; ti1 < stn; ti1++, ti2 += 5 + /*phi += stheta */ ) + { + /*rv = r*_cos(phi) - r0; */ + rv = r * sinTable[(int) (abs( ti2 ))] - r0; + i = cvFloor( rv ) * stn + ti1; + + i = CV_IMAX( i, -1 ); + i = CV_IMIN( i, sfn ); + mcaccum[i]++; + assert( i >= -1 ); + assert( i <= sfn ); + } + } + + /* Find peaks in maccum... */ + for( index = 0; index < sfn; index++ ) + { + i = 0; + pos = h_get_tail_pos__index( list ); + if( h_get_prev__index( &pos )->value < mcaccum[index] ) + { + vi.value = mcaccum[index]; + vi.rho = index / stn * srho + ri * rho; + vi.theta = index % stn * stheta + ti * theta - halfPi; + while( h_is_pos__index( pos )) + { + if( h_get__index( pos )->value > mcaccum[index] ) + { + h_insert_after__index( list, pos, &vi ); + if( h_get_count__index( list ) > linesMax ) + { + h_remove_tail__index( list ); + } + break; + } + h_get_prev__index( &pos ); + } + if( !h_is_pos__index( pos )) + { + h_add_head__index( list, &vi ); + if( h_get_count__index( list ) > linesMax ) + { + h_remove_tail__index( list ); + } + } + } + } + } + } + } + + pos = h_get_head_pos__index( list ); + if( h_get_count__index( list ) == 1 ) + { + if( h_get__index( pos )->rho < 0 ) + { + h_clear_list__index( list ); + } + } + else + { + while( h_is_pos__index( pos )) + { + CvLinePolar line; + pindex = h_get__index( pos ); + if( pindex->rho < 0 ) + { + /* This should be the last element... */ + h_get_next__index( &pos ); + assert( !h_is_pos__index( pos )); + break; + } + line.rho = pindex->rho; + line.angle = pindex->theta; + cvSeqPush( lines, &line ); + + if( lines->total >= linesMax ) + break; + h_get_next__index( &pos ); + } + } + + h_destroy_list__index(list); +} + + +/****************************************************************************************\ +* Probabilistic Hough Transform * +\****************************************************************************************/ + +static void +icvHoughLinesProbabilistic( CvMat* image, + float rho, float theta, int threshold, + int lineLength, int lineGap, + CvSeq *lines, int linesMax ) +{ + cv::Mat accum, mask; + cv::vector trigtab; + cv::MemStorage storage(cvCreateMemStorage(0)); + + CvSeq* seq; + CvSeqWriter writer; + int width, height; + int numangle, numrho; + float ang; + int r, n, count; + CvPoint pt; + float irho = 1 / rho; + CvRNG rng = cvRNG(-1); + const float* ttab; + uchar* mdata0; + + CV_Assert( CV_IS_MAT(image) && CV_MAT_TYPE(image->type) == CV_8UC1 ); + + width = image->cols; + height = image->rows; + + numangle = cvRound(CV_PI / theta); + numrho = cvRound(((width + height) * 2 + 1) / rho); + + accum.create( numangle, numrho, CV_32SC1 ); + mask.create( height, width, CV_8UC1 ); + trigtab.resize(numangle*2); + accum = cv::Scalar(0); + + for( ang = 0, n = 0; n < numangle; ang += theta, n++ ) + { + trigtab[n*2] = (float)(cos(ang) * irho); + trigtab[n*2+1] = (float)(sin(ang) * irho); + } + ttab = &trigtab[0]; + mdata0 = mask.data; + + cvStartWriteSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage, &writer ); + + // stage 1. collect non-zero image points + for( pt.y = 0, count = 0; pt.y < height; pt.y++ ) + { + const uchar* data = image->data.ptr + pt.y*image->step; + uchar* mdata = mdata0 + pt.y*width; + for( pt.x = 0; pt.x < width; pt.x++ ) + { + if( data[pt.x] ) + { + mdata[pt.x] = (uchar)1; + CV_WRITE_SEQ_ELEM( pt, writer ); + } + else + mdata[pt.x] = 0; + } + } + + seq = cvEndWriteSeq( &writer ); + count = seq->total; + + // stage 2. process all the points in random order + for( ; count > 0; count-- ) + { + // choose random point out of the remaining ones + int idx = cvRandInt(&rng) % count; + int max_val = threshold-1, max_n = 0; + CvPoint* point = (CvPoint*)cvGetSeqElem( seq, idx ); + CvPoint line_end[2] = {{0,0}, {0,0}}; + float a, b; + int* adata = (int*)accum.data; + int i, j, k, x0, y0, dx0, dy0, xflag; + int good_line; + const int shift = 16; + + i = point->y; + j = point->x; + + // "remove" it by overriding it with the last element + *point = *(CvPoint*)cvGetSeqElem( seq, count-1 ); + + // check if it has been excluded already (i.e. belongs to some other line) + if( !mdata0[i*width + j] ) + continue; + + // update accumulator, find the most probable line + for( n = 0; n < numangle; n++, adata += numrho ) + { + r = cvRound( j * ttab[n*2] + i * ttab[n*2+1] ); + r += (numrho - 1) / 2; + int val = ++adata[r]; + if( max_val < val ) + { + max_val = val; + max_n = n; + } + } + + // if it is too "weak" candidate, continue with another point + if( max_val < threshold ) + continue; + + // from the current point walk in each direction + // along the found line and extract the line segment + a = -ttab[max_n*2+1]; + b = ttab[max_n*2]; + x0 = j; + y0 = i; + if( fabs(a) > fabs(b) ) + { + xflag = 1; + dx0 = a > 0 ? 1 : -1; + dy0 = cvRound( b*(1 << shift)/fabs(a) ); + y0 = (y0 << shift) + (1 << (shift-1)); + } + else + { + xflag = 0; + dy0 = b > 0 ? 1 : -1; + dx0 = cvRound( a*(1 << shift)/fabs(b) ); + x0 = (x0 << shift) + (1 << (shift-1)); + } + + for( k = 0; k < 2; k++ ) + { + int gap = 0, x = x0, y = y0, dx = dx0, dy = dy0; + + if( k > 0 ) + dx = -dx, dy = -dy; + + // walk along the line using fixed-point arithmetics, + // stop at the image border or in case of too big gap + for( ;; x += dx, y += dy ) + { + uchar* mdata; + int i1, j1; + + if( xflag ) + { + j1 = x; + i1 = y >> shift; + } + else + { + j1 = x >> shift; + i1 = y; + } + + if( j1 < 0 || j1 >= width || i1 < 0 || i1 >= height ) + break; + + mdata = mdata0 + i1*width + j1; + + // for each non-zero point: + // update line end, + // clear the mask element + // reset the gap + if( *mdata ) + { + gap = 0; + line_end[k].y = i1; + line_end[k].x = j1; + } + else if( ++gap > lineGap ) + break; + } + } + + good_line = abs(line_end[1].x - line_end[0].x) >= lineLength || + abs(line_end[1].y - line_end[0].y) >= lineLength; + + for( k = 0; k < 2; k++ ) + { + int x = x0, y = y0, dx = dx0, dy = dy0; + + if( k > 0 ) + dx = -dx, dy = -dy; + + // walk along the line using fixed-point arithmetics, + // stop at the image border or in case of too big gap + for( ;; x += dx, y += dy ) + { + uchar* mdata; + int i1, j1; + + if( xflag ) + { + j1 = x; + i1 = y >> shift; + } + else + { + j1 = x >> shift; + i1 = y; + } + + mdata = mdata0 + i1*width + j1; + + // for each non-zero point: + // update line end, + // clear the mask element + // reset the gap + if( *mdata ) + { + if( good_line ) + { + adata = (int*)accum.data; + for( n = 0; n < numangle; n++, adata += numrho ) + { + r = cvRound( j1 * ttab[n*2] + i1 * ttab[n*2+1] ); + r += (numrho - 1) / 2; + adata[r]--; + } + } + *mdata = 0; + } + + if( i1 == line_end[k].y && j1 == line_end[k].x ) + break; + } + } + + if( good_line ) + { + CvRect lr = { line_end[0].x, line_end[0].y, line_end[1].x, line_end[1].y }; + cvSeqPush( lines, &lr ); + if( lines->total >= linesMax ) + return; + } + } +} + +/* Wrapper function for standard hough transform */ +CV_IMPL CvSeq* +cvHoughLines2( CvArr* src_image, void* lineStorage, int method, + double rho, double theta, int threshold, + double param1, double param2 ) +{ + CvSeq* result = 0; + + CvMat stub, *img = (CvMat*)src_image; + CvMat* mat = 0; + CvSeq* lines = 0; + CvSeq lines_header; + CvSeqBlock lines_block; + int lineType, elemSize; + int linesMax = INT_MAX; + int iparam1, iparam2; + + img = cvGetMat( img, &stub ); + + if( !CV_IS_MASK_ARR(img)) + CV_Error( CV_StsBadArg, "The source image must be 8-bit, single-channel" ); + + if( !lineStorage ) + CV_Error( CV_StsNullPtr, "NULL destination" ); + + if( rho <= 0 || theta <= 0 || threshold <= 0 ) + CV_Error( CV_StsOutOfRange, "rho, theta and threshold must be positive" ); + + if( method != CV_HOUGH_PROBABILISTIC ) + { + lineType = CV_32FC2; + elemSize = sizeof(float)*2; + } + else + { + lineType = CV_32SC4; + elemSize = sizeof(int)*4; + } + + if( CV_IS_STORAGE( lineStorage )) + { + lines = cvCreateSeq( lineType, sizeof(CvSeq), elemSize, (CvMemStorage*)lineStorage ); + } + else if( CV_IS_MAT( lineStorage )) + { + mat = (CvMat*)lineStorage; + + if( !CV_IS_MAT_CONT( mat->type ) || (mat->rows != 1 && mat->cols != 1) ) + CV_Error( CV_StsBadArg, + "The destination matrix should be continuous and have a single row or a single column" ); + + if( CV_MAT_TYPE( mat->type ) != lineType ) + CV_Error( CV_StsBadArg, + "The destination matrix data type is inappropriate, see the manual" ); + + lines = cvMakeSeqHeaderForArray( lineType, sizeof(CvSeq), elemSize, mat->data.ptr, + mat->rows + mat->cols - 1, &lines_header, &lines_block ); + linesMax = lines->total; + cvClearSeq( lines ); + } + else + CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); + + iparam1 = cvRound(param1); + iparam2 = cvRound(param2); + + switch( method ) + { + case CV_HOUGH_STANDARD: + icvHoughLinesStandard( img, (float)rho, + (float)theta, threshold, lines, linesMax ); + break; + case CV_HOUGH_MULTI_SCALE: + icvHoughLinesSDiv( img, (float)rho, (float)theta, + threshold, iparam1, iparam2, lines, linesMax ); + break; + case CV_HOUGH_PROBABILISTIC: + icvHoughLinesProbabilistic( img, (float)rho, (float)theta, + threshold, iparam1, iparam2, lines, linesMax ); + break; + default: + CV_Error( CV_StsBadArg, "Unrecognized method id" ); + } + + if( mat ) + { + if( mat->cols > mat->rows ) + mat->cols = lines->total; + else + mat->rows = lines->total; + } + else + result = lines; + + return result; +} + + +/****************************************************************************************\ +* Circle Detection * +\****************************************************************************************/ + +static void +icvHoughCirclesGradient( CvMat* img, float dp, float min_dist, + int min_radius, int max_radius, + int canny_threshold, int acc_threshold, + CvSeq* circles, int circles_max ) +{ + const int SHIFT = 10, ONE = 1 << SHIFT; + cv::Ptr dx, dy; + cv::Ptr edges, accum, dist_buf; + std::vector sort_buf; + cv::Ptr storage; + + int x, y, i, j, k, center_count, nz_count; + float min_radius2 = (float)min_radius*min_radius; + float max_radius2 = (float)max_radius*max_radius; + int rows, cols, arows, acols; + int astep, *adata; + float* ddata; + CvSeq *nz, *centers; + float idp, dr; + CvSeqReader reader; + + edges = cvCreateMat( img->rows, img->cols, CV_8UC1 ); + cvCanny( img, edges, MAX(canny_threshold/2,1), canny_threshold, 3 ); + + dx = cvCreateMat( img->rows, img->cols, CV_16SC1 ); + dy = cvCreateMat( img->rows, img->cols, CV_16SC1 ); + cvSobel( img, dx, 1, 0, 3 ); + cvSobel( img, dy, 0, 1, 3 ); + + if( dp < 1.f ) + dp = 1.f; + idp = 1.f/dp; + accum = cvCreateMat( cvCeil(img->rows*idp)+2, cvCeil(img->cols*idp)+2, CV_32SC1 ); + cvZero(accum); + + storage = cvCreateMemStorage(); + nz = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); + centers = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); + + rows = img->rows; + cols = img->cols; + arows = accum->rows - 2; + acols = accum->cols - 2; + adata = accum->data.i; + astep = accum->step/sizeof(adata[0]); + // Accumulate circle evidence for each edge pixel + for( y = 0; y < rows; y++ ) + { + const uchar* edges_row = edges->data.ptr + y*edges->step; + const short* dx_row = (const short*)(dx->data.ptr + y*dx->step); + const short* dy_row = (const short*)(dy->data.ptr + y*dy->step); + + for( x = 0; x < cols; x++ ) + { + float vx, vy; + int sx, sy, x0, y0, x1, y1, r; + CvPoint pt; + + vx = dx_row[x]; + vy = dy_row[x]; + + if( !edges_row[x] || (vx == 0 && vy == 0) ) + continue; + + float mag = sqrt(vx*vx+vy*vy); + assert( mag >= 1 ); + sx = cvRound((vx*idp)*ONE/mag); + sy = cvRound((vy*idp)*ONE/mag); + + x0 = cvRound((x*idp)*ONE); + y0 = cvRound((y*idp)*ONE); + // Step from min_radius to max_radius in both directions of the gradient + for(int k1 = 0; k1 < 2; k1++ ) + { + x1 = x0 + min_radius * sx; + y1 = y0 + min_radius * sy; + + for( r = min_radius; r <= max_radius; x1 += sx, y1 += sy, r++ ) + { + int x2 = x1 >> SHIFT, y2 = y1 >> SHIFT; + if( (unsigned)x2 >= (unsigned)acols || + (unsigned)y2 >= (unsigned)arows ) + break; + adata[y2*astep + x2]++; + } + + sx = -sx; sy = -sy; + } + + pt.x = x; pt.y = y; + cvSeqPush( nz, &pt ); + } + } + + nz_count = nz->total; + if( !nz_count ) + return; + //Find possible circle centers + for( y = 1; y < arows - 1; y++ ) + { + for( x = 1; x < acols - 1; x++ ) + { + int base = y*(acols+2) + x; + if( adata[base] > acc_threshold && + adata[base] > adata[base-1] && adata[base] > adata[base+1] && + adata[base] > adata[base-acols-2] && adata[base] > adata[base+acols+2] ) + cvSeqPush(centers, &base); + } + } + + center_count = centers->total; + if( !center_count ) + return; + + sort_buf.resize( MAX(center_count,nz_count) ); + cvCvtSeqToArray( centers, &sort_buf[0] ); + + icvHoughSortDescent32s( &sort_buf[0], center_count, adata ); + cvClearSeq( centers ); + cvSeqPushMulti( centers, &sort_buf[0], center_count ); + + dist_buf = cvCreateMat( 1, nz_count, CV_32FC1 ); + ddata = dist_buf->data.fl; + + dr = dp; + min_dist = MAX( min_dist, dp ); + min_dist *= min_dist; + // For each found possible center + // Estimate radius and check support + for( i = 0; i < centers->total; i++ ) + { + int ofs = *(int*)cvGetSeqElem( centers, i ); + y = ofs/(acols+2); + x = ofs - (y)*(acols+2); + //Calculate circle's center in pixels + float cx = (float)((x + 0.5f)*dp), cy = (float)(( y + 0.5f )*dp); + float start_dist, dist_sum; + float r_best = 0; + int max_count = 0; + // Check distance with previously detected circles + for( j = 0; j < circles->total; j++ ) + { + float* c = (float*)cvGetSeqElem( circles, j ); + if( (c[0] - cx)*(c[0] - cx) + (c[1] - cy)*(c[1] - cy) < min_dist ) + break; + } + + if( j < circles->total ) + continue; + // Estimate best radius + cvStartReadSeq( nz, &reader ); + for( j = k = 0; j < nz_count; j++ ) + { + CvPoint pt; + float _dx, _dy, _r2; + CV_READ_SEQ_ELEM( pt, reader ); + _dx = cx - pt.x; _dy = cy - pt.y; + _r2 = _dx*_dx + _dy*_dy; + if(min_radius2 <= _r2 && _r2 <= max_radius2 ) + { + ddata[k] = _r2; + sort_buf[k] = k; + k++; + } + } + + int nz_count1 = k, start_idx = nz_count1 - 1; + if( nz_count1 == 0 ) + continue; + dist_buf->cols = nz_count1; + cvPow( dist_buf, dist_buf, 0.5 ); + icvHoughSortDescent32s( &sort_buf[0], nz_count1, (int*)ddata ); + + dist_sum = start_dist = ddata[sort_buf[nz_count1-1]]; + for( j = nz_count1 - 2; j >= 0; j-- ) + { + float d = ddata[sort_buf[j]]; + + if( d > max_radius ) + break; + + if( d - start_dist > dr ) + { + float r_cur = ddata[sort_buf[(j + start_idx)/2]]; + if( (start_idx - j)*r_best >= max_count*r_cur || + (r_best < FLT_EPSILON && start_idx - j >= max_count) ) + { + r_best = r_cur; + max_count = start_idx - j; + } + start_dist = d; + start_idx = j; + dist_sum = 0; + } + dist_sum += d; + } + // Check if the circle has enough support + if( max_count > acc_threshold ) + { + float c[3]; + c[0] = cx; + c[1] = cy; + c[2] = (float)r_best; + cvSeqPush( circles, c ); + if( circles->total > circles_max ) + return; + } + } +} + +CV_IMPL CvSeq* +cvHoughCircles( CvArr* src_image, void* circle_storage, + int method, double dp, double min_dist, + double param1, double param2, + int min_radius, int max_radius ) +{ + CvSeq* result = 0; + + CvMat stub, *img = (CvMat*)src_image; + CvMat* mat = 0; + CvSeq* circles = 0; + CvSeq circles_header; + CvSeqBlock circles_block; + int circles_max = INT_MAX; + int canny_threshold = cvRound(param1); + int acc_threshold = cvRound(param2); + + img = cvGetMat( img, &stub ); + + if( !CV_IS_MASK_ARR(img)) + CV_Error( CV_StsBadArg, "The source image must be 8-bit, single-channel" ); + + if( !circle_storage ) + CV_Error( CV_StsNullPtr, "NULL destination" ); + + if( dp <= 0 || min_dist <= 0 || canny_threshold <= 0 || acc_threshold <= 0 ) + CV_Error( CV_StsOutOfRange, "dp, min_dist, canny_threshold and acc_threshold must be all positive numbers" ); + + min_radius = MAX( min_radius, 0 ); + if( max_radius <= 0 ) + max_radius = MAX( img->rows, img->cols ); + else if( max_radius <= min_radius ) + max_radius = min_radius + 2; + + if( CV_IS_STORAGE( circle_storage )) + { + circles = cvCreateSeq( CV_32FC3, sizeof(CvSeq), + sizeof(float)*3, (CvMemStorage*)circle_storage ); + } + else if( CV_IS_MAT( circle_storage )) + { + mat = (CvMat*)circle_storage; + + if( !CV_IS_MAT_CONT( mat->type ) || (mat->rows != 1 && mat->cols != 1) || + CV_MAT_TYPE(mat->type) != CV_32FC3 ) + CV_Error( CV_StsBadArg, + "The destination matrix should be continuous and have a single row or a single column" ); + + circles = cvMakeSeqHeaderForArray( CV_32FC3, sizeof(CvSeq), sizeof(float)*3, + mat->data.ptr, mat->rows + mat->cols - 1, &circles_header, &circles_block ); + circles_max = circles->total; + cvClearSeq( circles ); + } + else + CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); + + switch( method ) + { + case CV_HOUGH_GRADIENT: + icvHoughCirclesGradient( img, (float)dp, (float)min_dist, + min_radius, max_radius, canny_threshold, + acc_threshold, circles, circles_max ); + break; + default: + CV_Error( CV_StsBadArg, "Unrecognized method id" ); + } + + if( mat ) + { + if( mat->cols > mat->rows ) + mat->cols = circles->total; + else + mat->rows = circles->total; + } + else + result = circles; + + return result; +} + + +namespace cv +{ + +const int STORAGE_SIZE = 1 << 12; + +static void seqToMat(const CvSeq* seq, OutputArray _arr) +{ + if( seq && seq->total > 0 ) + { + _arr.create(1, seq->total, seq->flags, -1, true); + Mat arr = _arr.getMat(); + cvCvtSeqToArray(seq, arr.data); + } + else + _arr.release(); +} + +} + +void cv::HoughLines( InputArray _image, OutputArray _lines, + double rho, double theta, int threshold, + double srn, double stn ) +{ + Ptr storage = cvCreateMemStorage(STORAGE_SIZE); + Mat image = _image.getMat(); + CvMat c_image = image; + CvSeq* seq = cvHoughLines2( &c_image, storage, srn == 0 && stn == 0 ? + CV_HOUGH_STANDARD : CV_HOUGH_MULTI_SCALE, + rho, theta, threshold, srn, stn ); + seqToMat(seq, _lines); +} + +void cv::HoughLinesP( InputArray _image, OutputArray _lines, + double rho, double theta, int threshold, + double minLineLength, double maxGap ) +{ + Ptr storage = cvCreateMemStorage(STORAGE_SIZE); + Mat image = _image.getMat(); + CvMat c_image = image; + CvSeq* seq = cvHoughLines2( &c_image, storage, CV_HOUGH_PROBABILISTIC, + rho, theta, threshold, minLineLength, maxGap ); + seqToMat(seq, _lines); +} + +void cv::HoughCircles( InputArray _image, OutputArray _circles, + int method, double dp, double min_dist, + double param1, double param2, + int minRadius, int maxRadius ) +{ + Ptr storage = cvCreateMemStorage(STORAGE_SIZE); + Mat image = _image.getMat(); + CvMat c_image = image; + CvSeq* seq = cvHoughCircles( &c_image, storage, method, + dp, min_dist, param1, param2, minRadius, maxRadius ); + seqToMat(seq, _circles); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/imgwarp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/imgwarp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/imgwarp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/imgwarp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3935 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Geometrical transforms on images and matrices: rotation, zoom etc. +// +// */ + +#include "precomp.hpp" +#include +#include + +namespace cv +{ + +/************** interpolation formulas and tables ***************/ + +const int INTER_RESIZE_COEF_BITS=11; +const int INTER_RESIZE_COEF_SCALE=1 << INTER_RESIZE_COEF_BITS; + +const int INTER_REMAP_COEF_BITS=15; +const int INTER_REMAP_COEF_SCALE=1 << INTER_REMAP_COEF_BITS; + +static uchar NNDeltaTab_i[INTER_TAB_SIZE2][2]; + +static float BilinearTab_f[INTER_TAB_SIZE2][2][2]; +static short BilinearTab_i[INTER_TAB_SIZE2][2][2]; + +#if CV_SSE2 +static short BilinearTab_iC4_buf[INTER_TAB_SIZE2+2][2][8]; +static short (*BilinearTab_iC4)[2][8] = (short (*)[2][8])alignPtr(BilinearTab_iC4_buf, 16); +#endif + +static float BicubicTab_f[INTER_TAB_SIZE2][4][4]; +static short BicubicTab_i[INTER_TAB_SIZE2][4][4]; + +static float Lanczos4Tab_f[INTER_TAB_SIZE2][8][8]; +static short Lanczos4Tab_i[INTER_TAB_SIZE2][8][8]; + +static inline void interpolateLinear( float x, float* coeffs ) +{ + coeffs[0] = 1.f - x; + coeffs[1] = x; +} + +static inline void interpolateCubic( float x, float* coeffs ) +{ + const float A = -0.75f; + + coeffs[0] = ((A*(x + 1) - 5*A)*(x + 1) + 8*A)*(x + 1) - 4*A; + coeffs[1] = ((A + 2)*x - (A + 3))*x*x + 1; + coeffs[2] = ((A + 2)*(1 - x) - (A + 3))*(1 - x)*(1 - x) + 1; + coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2]; +} + +static inline void interpolateLanczos4( float x, float* coeffs ) +{ + static const double s45 = 0.70710678118654752440084436210485; + static const double cs[][2]= + {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}}; + + if( x < FLT_EPSILON ) + { + for( int i = 0; i < 8; i++ ) + coeffs[i] = 0; + coeffs[3] = 1; + return; + } + + float sum = 0; + double y0=-(x+3)*CV_PI*0.25, s0 = sin(y0), c0=cos(y0); + for(int i = 0; i < 8; i++ ) + { + double y = -(x+3-i)*CV_PI*0.25; + coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y)); + sum += coeffs[i]; + } + + sum = 1.f/sum; + for(int i = 0; i < 8; i++ ) + coeffs[i] *= sum; +} + +static void initInterTab1D(int method, float* tab, int tabsz) +{ + float scale = 1.f/tabsz; + if( method == INTER_LINEAR ) + { + for( int i = 0; i < tabsz; i++, tab += 2 ) + interpolateLinear( i*scale, tab ); + } + else if( method == INTER_CUBIC ) + { + for( int i = 0; i < tabsz; i++, tab += 4 ) + interpolateCubic( i*scale, tab ); + } + else if( method == INTER_LANCZOS4 ) + { + for( int i = 0; i < tabsz; i++, tab += 8 ) + interpolateLanczos4( i*scale, tab ); + } + else + CV_Error( CV_StsBadArg, "Unknown interpolation method" ); +} + + +static const void* initInterTab2D( int method, bool fixpt ) +{ + static bool inittab[INTER_MAX+1] = {false}; + float* tab = 0; + short* itab = 0; + int ksize = 0; + if( method == INTER_LINEAR ) + tab = BilinearTab_f[0][0], itab = BilinearTab_i[0][0], ksize=2; + else if( method == INTER_CUBIC ) + tab = BicubicTab_f[0][0], itab = BicubicTab_i[0][0], ksize=4; + else if( method == INTER_LANCZOS4 ) + tab = Lanczos4Tab_f[0][0], itab = Lanczos4Tab_i[0][0], ksize=8; + else + CV_Error( CV_StsBadArg, "Unknown/unsupported interpolation type" ); + + if( !inittab[method] ) + { + AutoBuffer _tab(8*INTER_TAB_SIZE); + int i, j, k1, k2; + initInterTab1D(method, _tab, INTER_TAB_SIZE); + for( i = 0; i < INTER_TAB_SIZE; i++ ) + for( j = 0; j < INTER_TAB_SIZE; j++, tab += ksize*ksize, itab += ksize*ksize ) + { + int isum = 0; + NNDeltaTab_i[i*INTER_TAB_SIZE+j][0] = j < INTER_TAB_SIZE/2; + NNDeltaTab_i[i*INTER_TAB_SIZE+j][1] = i < INTER_TAB_SIZE/2; + + for( k1 = 0; k1 < ksize; k1++ ) + { + float vy = _tab[i*ksize + k1]; + for( k2 = 0; k2 < ksize; k2++ ) + { + float v = vy*_tab[j*ksize + k2]; + tab[k1*ksize + k2] = v; + isum += itab[k1*ksize + k2] = saturate_cast(v*INTER_REMAP_COEF_SCALE); + } + } + + if( isum != INTER_REMAP_COEF_SCALE ) + { + int diff = isum - INTER_REMAP_COEF_SCALE; + int ksize2 = ksize/2, Mk1=ksize2, Mk2=ksize2, mk1=ksize2, mk2=ksize2; + for( k1 = ksize2; k1 < ksize2+2; k1++ ) + for( k2 = ksize2; k2 < ksize2+2; k2++ ) + { + if( itab[k1*ksize+k2] < itab[mk1*ksize+mk2] ) + mk1 = k1, mk2 = k2; + else if( itab[k1*ksize+k2] > itab[Mk1*ksize+Mk2] ) + Mk1 = k1, Mk2 = k2; + } + if( diff < 0 ) + itab[Mk1*ksize + Mk2] = (short)(itab[Mk1*ksize + Mk2] - diff); + else + itab[mk1*ksize + mk2] = (short)(itab[mk1*ksize + mk2] - diff); + } + } + tab -= INTER_TAB_SIZE2*ksize*ksize; + itab -= INTER_TAB_SIZE2*ksize*ksize; +#if CV_SSE2 + if( method == INTER_LINEAR ) + { + for( i = 0; i < INTER_TAB_SIZE2; i++ ) + for( j = 0; j < 4; j++ ) + { + BilinearTab_iC4[i][0][j*2] = BilinearTab_i[i][0][0]; + BilinearTab_iC4[i][0][j*2+1] = BilinearTab_i[i][0][1]; + BilinearTab_iC4[i][1][j*2] = BilinearTab_i[i][1][0]; + BilinearTab_iC4[i][1][j*2+1] = BilinearTab_i[i][1][1]; + } + } +#endif + inittab[method] = true; + } + return fixpt ? (const void*)itab : (const void*)tab; +} + +#ifndef __MINGW32__ +static bool initAllInterTab2D() +{ + return initInterTab2D( INTER_LINEAR, false ) && + initInterTab2D( INTER_LINEAR, true ) && + initInterTab2D( INTER_CUBIC, false ) && + initInterTab2D( INTER_CUBIC, true ) && + initInterTab2D( INTER_LANCZOS4, false ) && + initInterTab2D( INTER_LANCZOS4, true ); +} + +static volatile bool doInitAllInterTab2D = initAllInterTab2D(); +#endif + +template struct Cast +{ + typedef ST type1; + typedef DT rtype; + + DT operator()(ST val) const { return saturate_cast
(val); } +}; + +template struct FixedPtCast +{ + typedef ST type1; + typedef DT rtype; + enum { SHIFT = bits, DELTA = 1 << (bits-1) }; + + DT operator()(ST val) const { return saturate_cast
((val + DELTA)>>SHIFT); } +}; + +/****************************************************************************************\ +* Resize * +\****************************************************************************************/ + +class resizeNNInvoker : + public ParallelLoopBody +{ +public: + resizeNNInvoker(const Mat& _src, Mat &_dst, int *_x_ofs, int _pix_size4, double _ify) : + ParallelLoopBody(), src(_src), dst(_dst), x_ofs(_x_ofs), pix_size4(_pix_size4), + ify(_ify) + { + } + + virtual void operator() (const Range& range) const + { + Size ssize = src.size(), dsize = dst.size(); + int y, x, pix_size = (int)src.elemSize(); + + for( y = range.start; y < range.end; y++ ) + { + uchar* D = dst.data + dst.step*y; + int sy = std::min(cvFloor(y*ify), ssize.height-1); + const uchar* S = src.data + src.step*sy; + + switch( pix_size ) + { + case 1: + for( x = 0; x <= dsize.width - 2; x += 2 ) + { + uchar t0 = S[x_ofs[x]]; + uchar t1 = S[x_ofs[x+1]]; + D[x] = t0; + D[x+1] = t1; + } + + for( ; x < dsize.width; x++ ) + D[x] = S[x_ofs[x]]; + break; + case 2: + for( x = 0; x < dsize.width; x++ ) + *(ushort*)(D + x*2) = *(ushort*)(S + x_ofs[x]); + break; + case 3: + for( x = 0; x < dsize.width; x++, D += 3 ) + { + const uchar* _tS = S + x_ofs[x]; + D[0] = _tS[0]; D[1] = _tS[1]; D[2] = _tS[2]; + } + break; + case 4: + for( x = 0; x < dsize.width; x++ ) + *(int*)(D + x*4) = *(int*)(S + x_ofs[x]); + break; + case 6: + for( x = 0; x < dsize.width; x++, D += 6 ) + { + const ushort* _tS = (const ushort*)(S + x_ofs[x]); + ushort* _tD = (ushort*)D; + _tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2]; + } + break; + case 8: + for( x = 0; x < dsize.width; x++, D += 8 ) + { + const int* _tS = (const int*)(S + x_ofs[x]); + int* _tD = (int*)D; + _tD[0] = _tS[0]; _tD[1] = _tS[1]; + } + break; + case 12: + for( x = 0; x < dsize.width; x++, D += 12 ) + { + const int* _tS = (const int*)(S + x_ofs[x]); + int* _tD = (int*)D; + _tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2]; + } + break; + default: + for( x = 0; x < dsize.width; x++, D += pix_size ) + { + const int* _tS = (const int*)(S + x_ofs[x]); + int* _tD = (int*)D; + for( int k = 0; k < pix_size4; k++ ) + _tD[k] = _tS[k]; + } + } + } + } + +private: + const Mat src; + Mat dst; + int* x_ofs, pix_size4; + double ify; + + resizeNNInvoker(const resizeNNInvoker&); + resizeNNInvoker& operator=(const resizeNNInvoker&); +}; + +static void +resizeNN( const Mat& src, Mat& dst, double fx, double fy ) +{ + Size ssize = src.size(), dsize = dst.size(); + AutoBuffer _x_ofs(dsize.width); + int* x_ofs = _x_ofs; + int pix_size = (int)src.elemSize(); + int pix_size4 = (int)(pix_size / sizeof(int)); + double ifx = 1./fx, ify = 1./fy; + int x; + + for( x = 0; x < dsize.width; x++ ) + { + int sx = cvFloor(x*ifx); + x_ofs[x] = std::min(sx, ssize.width-1)*pix_size; + } + + Range range(0, dsize.height); + resizeNNInvoker invoker(src, dst, x_ofs, pix_size4, ify); + parallel_for_(range, invoker, dst.total()/(double)(1<<16)); +} + + +struct VResizeNoVec +{ + int operator()(const uchar**, uchar*, const uchar*, int ) const { return 0; } +}; + +struct HResizeNoVec +{ + int operator()(const uchar**, uchar**, int, const int*, + const uchar*, int, int, int, int, int) const { return 0; } +}; + +#if CV_SSE2 + +struct VResizeLinearVec_32s8u +{ + int operator()(const uchar** _src, uchar* dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const int** src = (const int**)_src; + const short* beta = (const short*)_beta; + const int *S0 = src[0], *S1 = src[1]; + int x = 0; + __m128i b0 = _mm_set1_epi16(beta[0]), b1 = _mm_set1_epi16(beta[1]); + __m128i delta = _mm_set1_epi16(2); + + if( (((size_t)S0|(size_t)S1)&15) == 0 ) + for( ; x <= width - 16; x += 16 ) + { + __m128i x0, x1, x2, y0, y1, y2; + x0 = _mm_load_si128((const __m128i*)(S0 + x)); + x1 = _mm_load_si128((const __m128i*)(S0 + x + 4)); + y0 = _mm_load_si128((const __m128i*)(S1 + x)); + y1 = _mm_load_si128((const __m128i*)(S1 + x + 4)); + x0 = _mm_packs_epi32(_mm_srai_epi32(x0, 4), _mm_srai_epi32(x1, 4)); + y0 = _mm_packs_epi32(_mm_srai_epi32(y0, 4), _mm_srai_epi32(y1, 4)); + + x1 = _mm_load_si128((const __m128i*)(S0 + x + 8)); + x2 = _mm_load_si128((const __m128i*)(S0 + x + 12)); + y1 = _mm_load_si128((const __m128i*)(S1 + x + 8)); + y2 = _mm_load_si128((const __m128i*)(S1 + x + 12)); + x1 = _mm_packs_epi32(_mm_srai_epi32(x1, 4), _mm_srai_epi32(x2, 4)); + y1 = _mm_packs_epi32(_mm_srai_epi32(y1, 4), _mm_srai_epi32(y2, 4)); + + x0 = _mm_adds_epi16(_mm_mulhi_epi16( x0, b0 ), _mm_mulhi_epi16( y0, b1 )); + x1 = _mm_adds_epi16(_mm_mulhi_epi16( x1, b0 ), _mm_mulhi_epi16( y1, b1 )); + + x0 = _mm_srai_epi16(_mm_adds_epi16(x0, delta), 2); + x1 = _mm_srai_epi16(_mm_adds_epi16(x1, delta), 2); + _mm_storeu_si128( (__m128i*)(dst + x), _mm_packus_epi16(x0, x1)); + } + else + for( ; x <= width - 16; x += 16 ) + { + __m128i x0, x1, x2, y0, y1, y2; + x0 = _mm_loadu_si128((const __m128i*)(S0 + x)); + x1 = _mm_loadu_si128((const __m128i*)(S0 + x + 4)); + y0 = _mm_loadu_si128((const __m128i*)(S1 + x)); + y1 = _mm_loadu_si128((const __m128i*)(S1 + x + 4)); + x0 = _mm_packs_epi32(_mm_srai_epi32(x0, 4), _mm_srai_epi32(x1, 4)); + y0 = _mm_packs_epi32(_mm_srai_epi32(y0, 4), _mm_srai_epi32(y1, 4)); + + x1 = _mm_loadu_si128((const __m128i*)(S0 + x + 8)); + x2 = _mm_loadu_si128((const __m128i*)(S0 + x + 12)); + y1 = _mm_loadu_si128((const __m128i*)(S1 + x + 8)); + y2 = _mm_loadu_si128((const __m128i*)(S1 + x + 12)); + x1 = _mm_packs_epi32(_mm_srai_epi32(x1, 4), _mm_srai_epi32(x2, 4)); + y1 = _mm_packs_epi32(_mm_srai_epi32(y1, 4), _mm_srai_epi32(y2, 4)); + + x0 = _mm_adds_epi16(_mm_mulhi_epi16( x0, b0 ), _mm_mulhi_epi16( y0, b1 )); + x1 = _mm_adds_epi16(_mm_mulhi_epi16( x1, b0 ), _mm_mulhi_epi16( y1, b1 )); + + x0 = _mm_srai_epi16(_mm_adds_epi16(x0, delta), 2); + x1 = _mm_srai_epi16(_mm_adds_epi16(x1, delta), 2); + _mm_storeu_si128( (__m128i*)(dst + x), _mm_packus_epi16(x0, x1)); + } + + for( ; x < width - 4; x += 4 ) + { + __m128i x0, y0; + x0 = _mm_srai_epi32(_mm_loadu_si128((const __m128i*)(S0 + x)), 4); + y0 = _mm_srai_epi32(_mm_loadu_si128((const __m128i*)(S1 + x)), 4); + x0 = _mm_packs_epi32(x0, x0); + y0 = _mm_packs_epi32(y0, y0); + x0 = _mm_adds_epi16(_mm_mulhi_epi16(x0, b0), _mm_mulhi_epi16(y0, b1)); + x0 = _mm_srai_epi16(_mm_adds_epi16(x0, delta), 2); + x0 = _mm_packus_epi16(x0, x0); + *(int*)(dst + x) = _mm_cvtsi128_si32(x0); + } + + return x; + } +}; + + +template struct VResizeLinearVec_32f16 +{ + int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const float** src = (const float**)_src; + const float* beta = (const float*)_beta; + const float *S0 = src[0], *S1 = src[1]; + ushort* dst = (ushort*)_dst; + int x = 0; + + __m128 b0 = _mm_set1_ps(beta[0]), b1 = _mm_set1_ps(beta[1]); + __m128i preshift = _mm_set1_epi32(shiftval); + __m128i postshift = _mm_set1_epi16((short)shiftval); + + if( (((size_t)S0|(size_t)S1)&15) == 0 ) + for( ; x <= width - 16; x += 16 ) + { + __m128 x0, x1, y0, y1; + __m128i t0, t1, t2; + x0 = _mm_load_ps(S0 + x); + x1 = _mm_load_ps(S0 + x + 4); + y0 = _mm_load_ps(S1 + x); + y1 = _mm_load_ps(S1 + x + 4); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + t0 = _mm_add_epi32(_mm_cvtps_epi32(x0), preshift); + t2 = _mm_add_epi32(_mm_cvtps_epi32(x1), preshift); + t0 = _mm_add_epi16(_mm_packs_epi32(t0, t2), postshift); + + x0 = _mm_load_ps(S0 + x + 8); + x1 = _mm_load_ps(S0 + x + 12); + y0 = _mm_load_ps(S1 + x + 8); + y1 = _mm_load_ps(S1 + x + 12); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + t1 = _mm_add_epi32(_mm_cvtps_epi32(x0), preshift); + t2 = _mm_add_epi32(_mm_cvtps_epi32(x1), preshift); + t1 = _mm_add_epi16(_mm_packs_epi32(t1, t2), postshift); + + _mm_storeu_si128( (__m128i*)(dst + x), t0); + _mm_storeu_si128( (__m128i*)(dst + x + 8), t1); + } + else + for( ; x <= width - 16; x += 16 ) + { + __m128 x0, x1, y0, y1; + __m128i t0, t1, t2; + x0 = _mm_loadu_ps(S0 + x); + x1 = _mm_loadu_ps(S0 + x + 4); + y0 = _mm_loadu_ps(S1 + x); + y1 = _mm_loadu_ps(S1 + x + 4); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + t0 = _mm_add_epi32(_mm_cvtps_epi32(x0), preshift); + t2 = _mm_add_epi32(_mm_cvtps_epi32(x1), preshift); + t0 = _mm_add_epi16(_mm_packs_epi32(t0, t2), postshift); + + x0 = _mm_loadu_ps(S0 + x + 8); + x1 = _mm_loadu_ps(S0 + x + 12); + y0 = _mm_loadu_ps(S1 + x + 8); + y1 = _mm_loadu_ps(S1 + x + 12); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + t1 = _mm_add_epi32(_mm_cvtps_epi32(x0), preshift); + t2 = _mm_add_epi32(_mm_cvtps_epi32(x1), preshift); + t1 = _mm_add_epi16(_mm_packs_epi32(t1, t2), postshift); + + _mm_storeu_si128( (__m128i*)(dst + x), t0); + _mm_storeu_si128( (__m128i*)(dst + x + 8), t1); + } + + for( ; x < width - 4; x += 4 ) + { + __m128 x0, y0; + __m128i t0; + x0 = _mm_loadu_ps(S0 + x); + y0 = _mm_loadu_ps(S1 + x); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + t0 = _mm_add_epi32(_mm_cvtps_epi32(x0), preshift); + t0 = _mm_add_epi16(_mm_packs_epi32(t0, t0), postshift); + _mm_storel_epi64( (__m128i*)(dst + x), t0); + } + + return x; + } +}; + +typedef VResizeLinearVec_32f16 VResizeLinearVec_32f16u; +typedef VResizeLinearVec_32f16<0> VResizeLinearVec_32f16s; + +struct VResizeLinearVec_32f +{ + int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + const float** src = (const float**)_src; + const float* beta = (const float*)_beta; + const float *S0 = src[0], *S1 = src[1]; + float* dst = (float*)_dst; + int x = 0; + + __m128 b0 = _mm_set1_ps(beta[0]), b1 = _mm_set1_ps(beta[1]); + + if( (((size_t)S0|(size_t)S1)&15) == 0 ) + for( ; x <= width - 8; x += 8 ) + { + __m128 x0, x1, y0, y1; + x0 = _mm_load_ps(S0 + x); + x1 = _mm_load_ps(S0 + x + 4); + y0 = _mm_load_ps(S1 + x); + y1 = _mm_load_ps(S1 + x + 4); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + + _mm_storeu_ps( dst + x, x0); + _mm_storeu_ps( dst + x + 4, x1); + } + else + for( ; x <= width - 8; x += 8 ) + { + __m128 x0, x1, y0, y1; + x0 = _mm_loadu_ps(S0 + x); + x1 = _mm_loadu_ps(S0 + x + 4); + y0 = _mm_loadu_ps(S1 + x); + y1 = _mm_loadu_ps(S1 + x + 4); + + x0 = _mm_add_ps(_mm_mul_ps(x0, b0), _mm_mul_ps(y0, b1)); + x1 = _mm_add_ps(_mm_mul_ps(x1, b0), _mm_mul_ps(y1, b1)); + + _mm_storeu_ps( dst + x, x0); + _mm_storeu_ps( dst + x + 4, x1); + } + + return x; + } +}; + + +struct VResizeCubicVec_32s8u +{ + int operator()(const uchar** _src, uchar* dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const int** src = (const int**)_src; + const short* beta = (const short*)_beta; + const int *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; + int x = 0; + float scale = 1.f/(INTER_RESIZE_COEF_SCALE*INTER_RESIZE_COEF_SCALE); + __m128 b0 = _mm_set1_ps(beta[0]*scale), b1 = _mm_set1_ps(beta[1]*scale), + b2 = _mm_set1_ps(beta[2]*scale), b3 = _mm_set1_ps(beta[3]*scale); + + if( (((size_t)S0|(size_t)S1|(size_t)S2|(size_t)S3)&15) == 0 ) + for( ; x <= width - 8; x += 8 ) + { + __m128i x0, x1, y0, y1; + __m128 s0, s1, f0, f1; + x0 = _mm_load_si128((const __m128i*)(S0 + x)); + x1 = _mm_load_si128((const __m128i*)(S0 + x + 4)); + y0 = _mm_load_si128((const __m128i*)(S1 + x)); + y1 = _mm_load_si128((const __m128i*)(S1 + x + 4)); + + s0 = _mm_mul_ps(_mm_cvtepi32_ps(x0), b0); + s1 = _mm_mul_ps(_mm_cvtepi32_ps(x1), b0); + f0 = _mm_mul_ps(_mm_cvtepi32_ps(y0), b1); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(y1), b1); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + + x0 = _mm_load_si128((const __m128i*)(S2 + x)); + x1 = _mm_load_si128((const __m128i*)(S2 + x + 4)); + y0 = _mm_load_si128((const __m128i*)(S3 + x)); + y1 = _mm_load_si128((const __m128i*)(S3 + x + 4)); + + f0 = _mm_mul_ps(_mm_cvtepi32_ps(x0), b2); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(x1), b2); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + f0 = _mm_mul_ps(_mm_cvtepi32_ps(y0), b3); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(y1), b3); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + + x0 = _mm_cvtps_epi32(s0); + x1 = _mm_cvtps_epi32(s1); + + x0 = _mm_packs_epi32(x0, x1); + _mm_storel_epi64( (__m128i*)(dst + x), _mm_packus_epi16(x0, x0)); + } + else + for( ; x <= width - 8; x += 8 ) + { + __m128i x0, x1, y0, y1; + __m128 s0, s1, f0, f1; + x0 = _mm_loadu_si128((const __m128i*)(S0 + x)); + x1 = _mm_loadu_si128((const __m128i*)(S0 + x + 4)); + y0 = _mm_loadu_si128((const __m128i*)(S1 + x)); + y1 = _mm_loadu_si128((const __m128i*)(S1 + x + 4)); + + s0 = _mm_mul_ps(_mm_cvtepi32_ps(x0), b0); + s1 = _mm_mul_ps(_mm_cvtepi32_ps(x1), b0); + f0 = _mm_mul_ps(_mm_cvtepi32_ps(y0), b1); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(y1), b1); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + + x0 = _mm_loadu_si128((const __m128i*)(S2 + x)); + x1 = _mm_loadu_si128((const __m128i*)(S2 + x + 4)); + y0 = _mm_loadu_si128((const __m128i*)(S3 + x)); + y1 = _mm_loadu_si128((const __m128i*)(S3 + x + 4)); + + f0 = _mm_mul_ps(_mm_cvtepi32_ps(x0), b2); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(x1), b2); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + f0 = _mm_mul_ps(_mm_cvtepi32_ps(y0), b3); + f1 = _mm_mul_ps(_mm_cvtepi32_ps(y1), b3); + s0 = _mm_add_ps(s0, f0); + s1 = _mm_add_ps(s1, f1); + + x0 = _mm_cvtps_epi32(s0); + x1 = _mm_cvtps_epi32(s1); + + x0 = _mm_packs_epi32(x0, x1); + _mm_storel_epi64( (__m128i*)(dst + x), _mm_packus_epi16(x0, x0)); + } + + return x; + } +}; + + +template struct VResizeCubicVec_32f16 +{ + int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const float** src = (const float**)_src; + const float* beta = (const float*)_beta; + const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; + ushort* dst = (ushort*)_dst; + int x = 0; + __m128 b0 = _mm_set1_ps(beta[0]), b1 = _mm_set1_ps(beta[1]), + b2 = _mm_set1_ps(beta[2]), b3 = _mm_set1_ps(beta[3]); + __m128i preshift = _mm_set1_epi32(shiftval); + __m128i postshift = _mm_set1_epi16((short)shiftval); + + for( ; x <= width - 8; x += 8 ) + { + __m128 x0, x1, y0, y1, s0, s1; + __m128i t0, t1; + x0 = _mm_loadu_ps(S0 + x); + x1 = _mm_loadu_ps(S0 + x + 4); + y0 = _mm_loadu_ps(S1 + x); + y1 = _mm_loadu_ps(S1 + x + 4); + + s0 = _mm_mul_ps(x0, b0); + s1 = _mm_mul_ps(x1, b0); + y0 = _mm_mul_ps(y0, b1); + y1 = _mm_mul_ps(y1, b1); + s0 = _mm_add_ps(s0, y0); + s1 = _mm_add_ps(s1, y1); + + x0 = _mm_loadu_ps(S2 + x); + x1 = _mm_loadu_ps(S2 + x + 4); + y0 = _mm_loadu_ps(S3 + x); + y1 = _mm_loadu_ps(S3 + x + 4); + + x0 = _mm_mul_ps(x0, b2); + x1 = _mm_mul_ps(x1, b2); + y0 = _mm_mul_ps(y0, b3); + y1 = _mm_mul_ps(y1, b3); + s0 = _mm_add_ps(s0, x0); + s1 = _mm_add_ps(s1, x1); + s0 = _mm_add_ps(s0, y0); + s1 = _mm_add_ps(s1, y1); + + t0 = _mm_add_epi32(_mm_cvtps_epi32(s0), preshift); + t1 = _mm_add_epi32(_mm_cvtps_epi32(s1), preshift); + + t0 = _mm_add_epi16(_mm_packs_epi32(t0, t1), postshift); + _mm_storeu_si128( (__m128i*)(dst + x), t0); + } + + return x; + } +}; + +typedef VResizeCubicVec_32f16 VResizeCubicVec_32f16u; +typedef VResizeCubicVec_32f16<0> VResizeCubicVec_32f16s; + +struct VResizeCubicVec_32f +{ + int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + const float** src = (const float**)_src; + const float* beta = (const float*)_beta; + const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; + float* dst = (float*)_dst; + int x = 0; + __m128 b0 = _mm_set1_ps(beta[0]), b1 = _mm_set1_ps(beta[1]), + b2 = _mm_set1_ps(beta[2]), b3 = _mm_set1_ps(beta[3]); + + for( ; x <= width - 8; x += 8 ) + { + __m128 x0, x1, y0, y1, s0, s1; + x0 = _mm_loadu_ps(S0 + x); + x1 = _mm_loadu_ps(S0 + x + 4); + y0 = _mm_loadu_ps(S1 + x); + y1 = _mm_loadu_ps(S1 + x + 4); + + s0 = _mm_mul_ps(x0, b0); + s1 = _mm_mul_ps(x1, b0); + y0 = _mm_mul_ps(y0, b1); + y1 = _mm_mul_ps(y1, b1); + s0 = _mm_add_ps(s0, y0); + s1 = _mm_add_ps(s1, y1); + + x0 = _mm_loadu_ps(S2 + x); + x1 = _mm_loadu_ps(S2 + x + 4); + y0 = _mm_loadu_ps(S3 + x); + y1 = _mm_loadu_ps(S3 + x + 4); + + x0 = _mm_mul_ps(x0, b2); + x1 = _mm_mul_ps(x1, b2); + y0 = _mm_mul_ps(y0, b3); + y1 = _mm_mul_ps(y1, b3); + s0 = _mm_add_ps(s0, x0); + s1 = _mm_add_ps(s1, x1); + s0 = _mm_add_ps(s0, y0); + s1 = _mm_add_ps(s1, y1); + + _mm_storeu_ps( dst + x, s0); + _mm_storeu_ps( dst + x + 4, s1); + } + + return x; + } +}; + +#else + +typedef VResizeNoVec VResizeLinearVec_32s8u; +typedef VResizeNoVec VResizeLinearVec_32f16u; +typedef VResizeNoVec VResizeLinearVec_32f16s; +typedef VResizeNoVec VResizeLinearVec_32f; + +typedef VResizeNoVec VResizeCubicVec_32s8u; +typedef VResizeNoVec VResizeCubicVec_32f16u; +typedef VResizeNoVec VResizeCubicVec_32f16s; +typedef VResizeNoVec VResizeCubicVec_32f; + +#endif + +typedef HResizeNoVec HResizeLinearVec_8u32s; +typedef HResizeNoVec HResizeLinearVec_16u32f; +typedef HResizeNoVec HResizeLinearVec_16s32f; +typedef HResizeNoVec HResizeLinearVec_32f; +typedef HResizeNoVec HResizeLinearVec_64f; + + +template +struct HResizeLinear +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const T** src, WT** dst, int count, + const int* xofs, const AT* alpha, + int swidth, int dwidth, int cn, int xmin, int xmax ) const + { + int dx, k; + VecOp vecOp; + + int dx0 = vecOp((const uchar**)src, (uchar**)dst, count, + xofs, (const uchar*)alpha, swidth, dwidth, cn, xmin, xmax ); + + for( k = 0; k <= count - 2; k++ ) + { + const T *S0 = src[k], *S1 = src[k+1]; + WT *D0 = dst[k], *D1 = dst[k+1]; + for( dx = dx0; dx < xmax; dx++ ) + { + int sx = xofs[dx]; + WT a0 = alpha[dx*2], a1 = alpha[dx*2+1]; + WT t0 = S0[sx]*a0 + S0[sx + cn]*a1; + WT t1 = S1[sx]*a0 + S1[sx + cn]*a1; + D0[dx] = t0; D1[dx] = t1; + } + + for( ; dx < dwidth; dx++ ) + { + int sx = xofs[dx]; + D0[dx] = WT(S0[sx]*ONE); D1[dx] = WT(S1[sx]*ONE); + } + } + + for( ; k < count; k++ ) + { + const T *S = src[k]; + WT *D = dst[k]; + for( dx = 0; dx < xmax; dx++ ) + { + int sx = xofs[dx]; + D[dx] = S[sx]*alpha[dx*2] + S[sx+cn]*alpha[dx*2+1]; + } + + for( ; dx < dwidth; dx++ ) + D[dx] = WT(S[xofs[dx]]*ONE); + } + } +}; + + +template +struct VResizeLinear +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const WT** src, T* dst, const AT* beta, int width ) const + { + WT b0 = beta[0], b1 = beta[1]; + const WT *S0 = src[0], *S1 = src[1]; + CastOp castOp; + VecOp vecOp; + + int x = vecOp((const uchar**)src, (uchar*)dst, (const uchar*)beta, width); + #if CV_ENABLE_UNROLLED + for( ; x <= width - 4; x += 4 ) + { + WT t0, t1; + t0 = S0[x]*b0 + S1[x]*b1; + t1 = S0[x+1]*b0 + S1[x+1]*b1; + dst[x] = castOp(t0); dst[x+1] = castOp(t1); + t0 = S0[x+2]*b0 + S1[x+2]*b1; + t1 = S0[x+3]*b0 + S1[x+3]*b1; + dst[x+2] = castOp(t0); dst[x+3] = castOp(t1); + } + #endif + for( ; x < width; x++ ) + dst[x] = castOp(S0[x]*b0 + S1[x]*b1); + } +}; + +template<> +struct VResizeLinear, VResizeLinearVec_32s8u> +{ + typedef uchar value_type; + typedef int buf_type; + typedef short alpha_type; + + void operator()(const buf_type** src, value_type* dst, const alpha_type* beta, int width ) const + { + alpha_type b0 = beta[0], b1 = beta[1]; + const buf_type *S0 = src[0], *S1 = src[1]; + VResizeLinearVec_32s8u vecOp; + + int x = vecOp((const uchar**)src, (uchar*)dst, (const uchar*)beta, width); + #if CV_ENABLE_UNROLLED + for( ; x <= width - 4; x += 4 ) + { + dst[x+0] = uchar(( ((b0 * (S0[x+0] >> 4)) >> 16) + ((b1 * (S1[x+0] >> 4)) >> 16) + 2)>>2); + dst[x+1] = uchar(( ((b0 * (S0[x+1] >> 4)) >> 16) + ((b1 * (S1[x+1] >> 4)) >> 16) + 2)>>2); + dst[x+2] = uchar(( ((b0 * (S0[x+2] >> 4)) >> 16) + ((b1 * (S1[x+2] >> 4)) >> 16) + 2)>>2); + dst[x+3] = uchar(( ((b0 * (S0[x+3] >> 4)) >> 16) + ((b1 * (S1[x+3] >> 4)) >> 16) + 2)>>2); + } + #endif + for( ; x < width; x++ ) + dst[x] = uchar(( ((b0 * (S0[x] >> 4)) >> 16) + ((b1 * (S1[x] >> 4)) >> 16) + 2)>>2); + } +}; + + +template +struct HResizeCubic +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const T** src, WT** dst, int count, + const int* xofs, const AT* alpha, + int swidth, int dwidth, int cn, int xmin, int xmax ) const + { + for( int k = 0; k < count; k++ ) + { + const T *S = src[k]; + WT *D = dst[k]; + int dx = 0, limit = xmin; + for(;;) + { + for( ; dx < limit; dx++, alpha += 4 ) + { + int j, sx = xofs[dx] - cn; + WT v = 0; + for( j = 0; j < 4; j++ ) + { + int sxj = sx + j*cn; + if( (unsigned)sxj >= (unsigned)swidth ) + { + while( sxj < 0 ) + sxj += cn; + while( sxj >= swidth ) + sxj -= cn; + } + v += S[sxj]*alpha[j]; + } + D[dx] = v; + } + if( limit == dwidth ) + break; + for( ; dx < xmax; dx++, alpha += 4 ) + { + int sx = xofs[dx]; + D[dx] = S[sx-cn]*alpha[0] + S[sx]*alpha[1] + + S[sx+cn]*alpha[2] + S[sx+cn*2]*alpha[3]; + } + limit = dwidth; + } + alpha -= dwidth*4; + } + } +}; + + +template +struct VResizeCubic +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const WT** src, T* dst, const AT* beta, int width ) const + { + WT b0 = beta[0], b1 = beta[1], b2 = beta[2], b3 = beta[3]; + const WT *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; + CastOp castOp; + VecOp vecOp; + + int x = vecOp((const uchar**)src, (uchar*)dst, (const uchar*)beta, width); + for( ; x < width; x++ ) + dst[x] = castOp(S0[x]*b0 + S1[x]*b1 + S2[x]*b2 + S3[x]*b3); + } +}; + + +template +struct HResizeLanczos4 +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const T** src, WT** dst, int count, + const int* xofs, const AT* alpha, + int swidth, int dwidth, int cn, int xmin, int xmax ) const + { + for( int k = 0; k < count; k++ ) + { + const T *S = src[k]; + WT *D = dst[k]; + int dx = 0, limit = xmin; + for(;;) + { + for( ; dx < limit; dx++, alpha += 8 ) + { + int j, sx = xofs[dx] - cn*3; + WT v = 0; + for( j = 0; j < 8; j++ ) + { + int sxj = sx + j*cn; + if( (unsigned)sxj >= (unsigned)swidth ) + { + while( sxj < 0 ) + sxj += cn; + while( sxj >= swidth ) + sxj -= cn; + } + v += S[sxj]*alpha[j]; + } + D[dx] = v; + } + if( limit == dwidth ) + break; + for( ; dx < xmax; dx++, alpha += 8 ) + { + int sx = xofs[dx]; + D[dx] = S[sx-cn*3]*alpha[0] + S[sx-cn*2]*alpha[1] + + S[sx-cn]*alpha[2] + S[sx]*alpha[3] + + S[sx+cn]*alpha[4] + S[sx+cn*2]*alpha[5] + + S[sx+cn*3]*alpha[6] + S[sx+cn*4]*alpha[7]; + } + limit = dwidth; + } + alpha -= dwidth*8; + } + } +}; + + +template +struct VResizeLanczos4 +{ + typedef T value_type; + typedef WT buf_type; + typedef AT alpha_type; + + void operator()(const WT** src, T* dst, const AT* beta, int width ) const + { + CastOp castOp; + VecOp vecOp; + int k, x = vecOp((const uchar**)src, (uchar*)dst, (const uchar*)beta, width); + #if CV_ENABLE_UNROLLED + for( ; x <= width - 4; x += 4 ) + { + WT b = beta[0]; + const WT* S = src[0]; + WT s0 = S[x]*b, s1 = S[x+1]*b, s2 = S[x+2]*b, s3 = S[x+3]*b; + + for( k = 1; k < 8; k++ ) + { + b = beta[k]; S = src[k]; + s0 += S[x]*b; s1 += S[x+1]*b; + s2 += S[x+2]*b; s3 += S[x+3]*b; + } + + dst[x] = castOp(s0); dst[x+1] = castOp(s1); + dst[x+2] = castOp(s2); dst[x+3] = castOp(s3); + } + #endif + for( ; x < width; x++ ) + { + dst[x] = castOp(src[0][x]*beta[0] + src[1][x]*beta[1] + + src[2][x]*beta[2] + src[3][x]*beta[3] + src[4][x]*beta[4] + + src[5][x]*beta[5] + src[6][x]*beta[6] + src[7][x]*beta[7]); + } + } +}; + + +static inline int clip(int x, int a, int b) +{ + return x >= a ? (x < b ? x : b-1) : a; +} + +static const int MAX_ESIZE=16; + +template +class resizeGeneric_Invoker : + public ParallelLoopBody +{ +public: + typedef typename HResize::value_type T; + typedef typename HResize::buf_type WT; + typedef typename HResize::alpha_type AT; + + resizeGeneric_Invoker(const Mat& _src, Mat &_dst, const int *_xofs, const int *_yofs, + const AT* _alpha, const AT* __beta, const Size& _ssize, const Size &_dsize, + int _ksize, int _xmin, int _xmax) : + ParallelLoopBody(), src(_src), dst(_dst), xofs(_xofs), yofs(_yofs), + alpha(_alpha), _beta(__beta), ssize(_ssize), dsize(_dsize), + ksize(_ksize), xmin(_xmin), xmax(_xmax) + { + } + + virtual void operator() (const Range& range) const + { + int dy, cn = src.channels(); + HResize hresize; + VResize vresize; + + int bufstep = (int)alignSize(dsize.width, 16); + AutoBuffer _buffer(bufstep*ksize); + const T* srows[MAX_ESIZE]={0}; + WT* rows[MAX_ESIZE]={0}; + int prev_sy[MAX_ESIZE]; + + for(int k = 0; k < ksize; k++ ) + { + prev_sy[k] = -1; + rows[k] = (WT*)_buffer + bufstep*k; + } + + const AT* beta = _beta + ksize * range.start; + + for( dy = range.start; dy < range.end; dy++, beta += ksize ) + { + int sy0 = yofs[dy], k0=ksize, k1=0, ksize2 = ksize/2; + + for(int k = 0; k < ksize; k++ ) + { + int sy = clip(sy0 - ksize2 + 1 + k, 0, ssize.height); + for( k1 = std::max(k1, k); k1 < ksize; k1++ ) + { + if( sy == prev_sy[k1] ) // if the sy-th row has been computed already, reuse it. + { + if( k1 > k ) + memcpy( rows[k], rows[k1], bufstep*sizeof(rows[0][0]) ); + break; + } + } + if( k1 == ksize ) + k0 = std::min(k0, k); // remember the first row that needs to be computed + srows[k] = (T*)(src.data + src.step*sy); + prev_sy[k] = sy; + } + + if( k0 < ksize ) + hresize( (const T**)(srows + k0), (WT**)(rows + k0), ksize - k0, xofs, (const AT*)(alpha), + ssize.width, dsize.width, cn, xmin, xmax ); + vresize( (const WT**)rows, (T*)(dst.data + dst.step*dy), beta, dsize.width ); + } + } + +private: + Mat src; + Mat dst; + const int* xofs, *yofs; + const AT* alpha, *_beta; + Size ssize, dsize; + int ksize, xmin, xmax; +}; + +template +static void resizeGeneric_( const Mat& src, Mat& dst, + const int* xofs, const void* _alpha, + const int* yofs, const void* _beta, + int xmin, int xmax, int ksize ) +{ + typedef typename HResize::value_type T; + typedef typename HResize::buf_type WT; + typedef typename HResize::alpha_type AT; + + const AT* beta = (const AT*)_beta; + Size ssize = src.size(), dsize = dst.size(); + int cn = src.channels(); + ssize.width *= cn; + dsize.width *= cn; + xmin *= cn; + xmax *= cn; + // image resize is a separable operation. In case of not too strong + + Range range(0, dsize.height); + resizeGeneric_Invoker invoker(src, dst, xofs, yofs, (const AT*)_alpha, beta, + ssize, dsize, ksize, xmin, xmax); + parallel_for_(range, invoker, dst.total()/(double)(1<<16)); +} + +template +struct ResizeAreaFastNoVec +{ + ResizeAreaFastNoVec(int /*_scale_x*/, int /*_scale_y*/, + int /*_cn*/, int /*_step*//*, const int**/ /*_ofs*/) { } + int operator() (const T* /*S*/, T* /*D*/, int /*w*/) const { return 0; } +}; + +template +struct ResizeAreaFastVec +{ + ResizeAreaFastVec(int _scale_x, int _scale_y, int _cn, int _step/*, const int* _ofs*/) : + scale_x(_scale_x), scale_y(_scale_y), cn(_cn), step(_step)/*, ofs(_ofs)*/ + { + fast_mode = scale_x == 2 && scale_y == 2 && (cn == 1 || cn == 3 || cn == 4); + } + + int operator() (const T* S, T* D, int w) const + { + if( !fast_mode ) + return 0; + + const T* nextS = (const T*)((const uchar*)S + step); + int dx = 0; + + if (cn == 1) + for( ; dx < w; ++dx ) + { + int index = dx*2; + D[dx] = (T)((S[index] + S[index+1] + nextS[index] + nextS[index+1] + 2) >> 2); + } + else if (cn == 3) + for( ; dx < w; dx += 3 ) + { + int index = dx*2; + D[dx] = (T)((S[index] + S[index+3] + nextS[index] + nextS[index+3] + 2) >> 2); + D[dx+1] = (T)((S[index+1] + S[index+4] + nextS[index+1] + nextS[index+4] + 2) >> 2); + D[dx+2] = (T)((S[index+2] + S[index+5] + nextS[index+2] + nextS[index+5] + 2) >> 2); + } + else + { + assert(cn == 4); + for( ; dx < w; dx += 4 ) + { + int index = dx*2; + D[dx] = (T)((S[index] + S[index+4] + nextS[index] + nextS[index+4] + 2) >> 2); + D[dx+1] = (T)((S[index+1] + S[index+5] + nextS[index+1] + nextS[index+5] + 2) >> 2); + D[dx+2] = (T)((S[index+2] + S[index+6] + nextS[index+2] + nextS[index+6] + 2) >> 2); + D[dx+3] = (T)((S[index+3] + S[index+7] + nextS[index+3] + nextS[index+7] + 2) >> 2); + } + } + + return dx; + } + +private: + int scale_x, scale_y; + int cn; + bool fast_mode; + int step; +}; + +template +class resizeAreaFast_Invoker : + public ParallelLoopBody +{ +public: + resizeAreaFast_Invoker(const Mat &_src, Mat &_dst, + int _scale_x, int _scale_y, const int* _ofs, const int* _xofs) : + ParallelLoopBody(), src(_src), dst(_dst), scale_x(_scale_x), + scale_y(_scale_y), ofs(_ofs), xofs(_xofs) + { + } + + virtual void operator() (const Range& range) const + { + Size ssize = src.size(), dsize = dst.size(); + int cn = src.channels(); + int area = scale_x*scale_y; + float scale = 1.f/(area); + int dwidth1 = (ssize.width/scale_x)*cn; + dsize.width *= cn; + ssize.width *= cn; + int dy, dx, k = 0; + + VecOp vop(scale_x, scale_y, src.channels(), (int)src.step/*, area_ofs*/); + + for( dy = range.start; dy < range.end; dy++ ) + { + T* D = (T*)(dst.data + dst.step*dy); + int sy0 = dy*scale_y; + int w = sy0 + scale_y <= ssize.height ? dwidth1 : 0; + + if( sy0 >= ssize.height ) + { + for( dx = 0; dx < dsize.width; dx++ ) + D[dx] = 0; + continue; + } + + dx = vop((const T*)(src.data + src.step * sy0), D, w); + for( ; dx < w; dx++ ) + { + const T* S = (const T*)(src.data + src.step * sy0) + xofs[dx]; + WT sum = 0; + k = 0; + #if CV_ENABLE_UNROLLED + for( ; k <= area - 4; k += 4 ) + sum += S[ofs[k]] + S[ofs[k+1]] + S[ofs[k+2]] + S[ofs[k+3]]; + #endif + for( ; k < area; k++ ) + sum += S[ofs[k]]; + + D[dx] = saturate_cast(sum * scale); + } + + for( ; dx < dsize.width; dx++ ) + { + WT sum = 0; + int count = 0, sx0 = xofs[dx]; + if( sx0 >= ssize.width ) + D[dx] = 0; + + for( int sy = 0; sy < scale_y; sy++ ) + { + if( sy0 + sy >= ssize.height ) + break; + const T* S = (const T*)(src.data + src.step*(sy0 + sy)) + sx0; + for( int sx = 0; sx < scale_x*cn; sx += cn ) + { + if( sx0 + sx >= ssize.width ) + break; + sum += S[sx]; + count++; + } + } + + D[dx] = saturate_cast((float)sum/count); + } + } + } + +private: + Mat src; + Mat dst; + int scale_x, scale_y; + const int *ofs, *xofs; +}; + +template +static void resizeAreaFast_( const Mat& src, Mat& dst, const int* ofs, const int* xofs, + int scale_x, int scale_y ) +{ + Range range(0, dst.rows); + resizeAreaFast_Invoker invoker(src, dst, scale_x, + scale_y, ofs, xofs); + parallel_for_(range, invoker, dst.total()/(double)(1<<16)); +} + +struct DecimateAlpha +{ + int si, di; + float alpha; +}; + + +template class ResizeArea_Invoker : + public ParallelLoopBody +{ +public: + ResizeArea_Invoker( const Mat& _src, Mat& _dst, + const DecimateAlpha* _xtab, int _xtab_size, + const DecimateAlpha* _ytab, int _ytab_size, + const int* _tabofs ) + { + src = &_src; + dst = &_dst; + xtab0 = _xtab; + xtab_size0 = _xtab_size; + ytab = _ytab; + ytab_size = _ytab_size; + tabofs = _tabofs; + } + + virtual void operator() (const Range& range) const + { + Size dsize = dst->size(); + int cn = dst->channels(); + dsize.width *= cn; + AutoBuffer _buffer(dsize.width*2); + const DecimateAlpha* xtab = xtab0; + int xtab_size = xtab_size0; + WT *buf = _buffer, *sum = buf + dsize.width; + int j_start = tabofs[range.start], j_end = tabofs[range.end], j, k, dx, prev_dy = ytab[j_start].di; + + for( dx = 0; dx < dsize.width; dx++ ) + sum[dx] = (WT)0; + + for( j = j_start; j < j_end; j++ ) + { + WT beta = ytab[j].alpha; + int dy = ytab[j].di; + int sy = ytab[j].si; + + { + const T* S = (const T*)(src->data + src->step*sy); + for( dx = 0; dx < dsize.width; dx++ ) + buf[dx] = (WT)0; + + if( cn == 1 ) + for( k = 0; k < xtab_size; k++ ) + { + int dxn = xtab[k].di; + WT alpha = xtab[k].alpha; + buf[dxn] += S[xtab[k].si]*alpha; + } + else if( cn == 2 ) + for( k = 0; k < xtab_size; k++ ) + { + int sxn = xtab[k].si; + int dxn = xtab[k].di; + WT alpha = xtab[k].alpha; + WT t0 = buf[dxn] + S[sxn]*alpha; + WT t1 = buf[dxn+1] + S[sxn+1]*alpha; + buf[dxn] = t0; buf[dxn+1] = t1; + } + else if( cn == 3 ) + for( k = 0; k < xtab_size; k++ ) + { + int sxn = xtab[k].si; + int dxn = xtab[k].di; + WT alpha = xtab[k].alpha; + WT t0 = buf[dxn] + S[sxn]*alpha; + WT t1 = buf[dxn+1] + S[sxn+1]*alpha; + WT t2 = buf[dxn+2] + S[sxn+2]*alpha; + buf[dxn] = t0; buf[dxn+1] = t1; buf[dxn+2] = t2; + } + else if( cn == 4 ) + { + for( k = 0; k < xtab_size; k++ ) + { + int sxn = xtab[k].si; + int dxn = xtab[k].di; + WT alpha = xtab[k].alpha; + WT t0 = buf[dxn] + S[sxn]*alpha; + WT t1 = buf[dxn+1] + S[sxn+1]*alpha; + buf[dxn] = t0; buf[dxn+1] = t1; + t0 = buf[dxn+2] + S[sxn+2]*alpha; + t1 = buf[dxn+3] + S[sxn+3]*alpha; + buf[dxn+2] = t0; buf[dxn+3] = t1; + } + } + else + { + for( k = 0; k < xtab_size; k++ ) + { + int sxn = xtab[k].si; + int dxn = xtab[k].di; + WT alpha = xtab[k].alpha; + for( int c = 0; c < cn; c++ ) + buf[dxn + c] += S[sxn + c]*alpha; + } + } + } + + if( dy != prev_dy ) + { + T* D = (T*)(dst->data + dst->step*prev_dy); + + for( dx = 0; dx < dsize.width; dx++ ) + { + D[dx] = saturate_cast(sum[dx]); + sum[dx] = beta*buf[dx]; + } + prev_dy = dy; + } + else + { + for( dx = 0; dx < dsize.width; dx++ ) + sum[dx] += beta*buf[dx]; + } + } + + { + T* D = (T*)(dst->data + dst->step*prev_dy); + for( dx = 0; dx < dsize.width; dx++ ) + D[dx] = saturate_cast(sum[dx]); + } + } + +private: + const Mat* src; + Mat* dst; + const DecimateAlpha* xtab0; + const DecimateAlpha* ytab; + int xtab_size0, ytab_size; + const int* tabofs; +}; + + +template +static void resizeArea_( const Mat& src, Mat& dst, + const DecimateAlpha* xtab, int xtab_size, + const DecimateAlpha* ytab, int ytab_size, + const int* tabofs ) +{ + parallel_for_(Range(0, dst.rows), + ResizeArea_Invoker(src, dst, xtab, xtab_size, ytab, ytab_size, tabofs), + dst.total()/((double)(1 << 16))); +} + + +typedef void (*ResizeFunc)( const Mat& src, Mat& dst, + const int* xofs, const void* alpha, + const int* yofs, const void* beta, + int xmin, int xmax, int ksize ); + +typedef void (*ResizeAreaFastFunc)( const Mat& src, Mat& dst, + const int* ofs, const int *xofs, + int scale_x, int scale_y ); + +typedef void (*ResizeAreaFunc)( const Mat& src, Mat& dst, + const DecimateAlpha* xtab, int xtab_size, + const DecimateAlpha* ytab, int ytab_size, + const int* yofs); + + +static int computeResizeAreaTab( int ssize, int dsize, int cn, double scale, DecimateAlpha* tab ) +{ + int k = 0; + for(int dx = 0; dx < dsize; dx++ ) + { + double fsx1 = dx * scale; + double fsx2 = fsx1 + scale; + double cellWidth = min(scale, ssize - fsx1); + + int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2); + + sx2 = std::min(sx2, ssize - 1); + sx1 = std::min(sx1, sx2); + + if( sx1 - fsx1 > 1e-3 ) + { + assert( k < ssize*2 ); + tab[k].di = dx * cn; + tab[k].si = (sx1 - 1) * cn; + tab[k++].alpha = (float)((sx1 - fsx1) / cellWidth); + } + + for(int sx = sx1; sx < sx2; sx++ ) + { + assert( k < ssize*2 ); + tab[k].di = dx * cn; + tab[k].si = sx * cn; + tab[k++].alpha = float(1.0 / cellWidth); + } + + if( fsx2 - sx2 > 1e-3 ) + { + assert( k < ssize*2 ); + tab[k].di = dx * cn; + tab[k].si = sx2 * cn; + tab[k++].alpha = (float)(min(min(fsx2 - sx2, 1.), cellWidth) / cellWidth); + } + } + return k; +} + + +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +void cv::resize( InputArray _src, OutputArray _dst, Size dsize, + double inv_scale_x, double inv_scale_y, int interpolation ) +{ + static ResizeFunc linear_tab[] = + { + resizeGeneric_< + HResizeLinear, + VResizeLinear, + VResizeLinearVec_32s8u> >, + 0, + resizeGeneric_< + HResizeLinear, + VResizeLinear, + VResizeLinearVec_32f16u> >, + resizeGeneric_< + HResizeLinear, + VResizeLinear, + VResizeLinearVec_32f16s> >, + 0, + resizeGeneric_< + HResizeLinear, + VResizeLinear, + VResizeLinearVec_32f> >, + resizeGeneric_< + HResizeLinear, + VResizeLinear, + VResizeNoVec> >, + 0 + }; + + static ResizeFunc cubic_tab[] = + { + resizeGeneric_< + HResizeCubic, + VResizeCubic, + VResizeCubicVec_32s8u> >, + 0, + resizeGeneric_< + HResizeCubic, + VResizeCubic, + VResizeCubicVec_32f16u> >, + resizeGeneric_< + HResizeCubic, + VResizeCubic, + VResizeCubicVec_32f16s> >, + 0, + resizeGeneric_< + HResizeCubic, + VResizeCubic, + VResizeCubicVec_32f> >, + resizeGeneric_< + HResizeCubic, + VResizeCubic, + VResizeNoVec> >, + 0 + }; + + static ResizeFunc lanczos4_tab[] = + { + resizeGeneric_, + VResizeLanczos4, + VResizeNoVec> >, + 0, + resizeGeneric_, + VResizeLanczos4, + VResizeNoVec> >, + resizeGeneric_, + VResizeLanczos4, + VResizeNoVec> >, + 0, + resizeGeneric_, + VResizeLanczos4, + VResizeNoVec> >, + resizeGeneric_, + VResizeLanczos4, + VResizeNoVec> >, + 0 + }; + + static ResizeAreaFastFunc areafast_tab[] = + { + resizeAreaFast_ >, + 0, + resizeAreaFast_ >, + resizeAreaFast_ >, + 0, + resizeAreaFast_ >, + resizeAreaFast_ >, + 0 + }; + + static ResizeAreaFunc area_tab[] = + { + resizeArea_, 0, resizeArea_, + resizeArea_, 0, resizeArea_, + resizeArea_, 0 + }; + + Mat src = _src.getMat(); + Size ssize = src.size(); + + CV_Assert( ssize.area() > 0 ); + CV_Assert( dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0) ); + if( !dsize.area() ) + { + dsize = Size(saturate_cast(src.cols*inv_scale_x), + saturate_cast(src.rows*inv_scale_y)); + CV_Assert( dsize.area() ); + } + else + { + inv_scale_x = (double)dsize.width/src.cols; + inv_scale_y = (double)dsize.height/src.rows; + } + _dst.create(dsize, src.type()); + Mat dst = _dst.getMat(); + + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::resize(src, dst, (float)inv_scale_x, (float)inv_scale_y, interpolation)) + return; +#endif + + int depth = src.depth(), cn = src.channels(); + double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y; + int k, sx, sy, dx, dy; + + if( interpolation == INTER_NEAREST ) + { + resizeNN( src, dst, inv_scale_x, inv_scale_y ); + return; + } + + { + int iscale_x = saturate_cast(scale_x); + int iscale_y = saturate_cast(scale_y); + + bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON && + std::abs(scale_y - iscale_y) < DBL_EPSILON; + + // in case of scale_x && scale_y is equal to 2 + // INTER_AREA (fast) also is equal to INTER_LINEAR + if( interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 ) + { + interpolation = INTER_AREA; + } + + // true "area" interpolation is only implemented for the case (scale_x <= 1 && scale_y <= 1). + // In other cases it is emulated using some variant of bilinear interpolation + if( interpolation == INTER_AREA && scale_x >= 1 && scale_y >= 1 ) + { + if( is_area_fast ) + { + int area = iscale_x*iscale_y; + size_t srcstep = src.step / src.elemSize1(); + AutoBuffer _ofs(area + dsize.width*cn); + int* ofs = _ofs; + int* xofs = ofs + area; + ResizeAreaFastFunc func = areafast_tab[depth]; + CV_Assert( func != 0 ); + + for( sy = 0, k = 0; sy < iscale_y; sy++ ) + for( sx = 0; sx < iscale_x; sx++ ) + ofs[k++] = (int)(sy*srcstep + sx*cn); + + for( dx = 0; dx < dsize.width; dx++ ) + { + int j = dx * cn; + sx = iscale_x * j; + for( k = 0; k < cn; k++ ) + xofs[j + k] = sx + k; + } + + func( src, dst, ofs, xofs, iscale_x, iscale_y ); + return; + } + + ResizeAreaFunc func = area_tab[depth]; + CV_Assert( func != 0 && cn <= 4 ); + + AutoBuffer _xytab((ssize.width + ssize.height)*2); + DecimateAlpha* xtab = _xytab, *ytab = xtab + ssize.width*2; + + int xtab_size = computeResizeAreaTab(ssize.width, dsize.width, cn, scale_x, xtab); + int ytab_size = computeResizeAreaTab(ssize.height, dsize.height, 1, scale_y, ytab); + + AutoBuffer _tabofs(dsize.height + 1); + int* tabofs = _tabofs; + for( k = 0, dy = 0; k < ytab_size; k++ ) + { + if( k == 0 || ytab[k].di != ytab[k-1].di ) + { + assert( ytab[k].di == dy ); + tabofs[dy++] = k; + } + } + tabofs[dy] = ytab_size; + + func( src, dst, xtab, xtab_size, ytab, ytab_size, tabofs ); + return; + } + } + + int xmin = 0, xmax = dsize.width, width = dsize.width*cn; + bool area_mode = interpolation == INTER_AREA; + bool fixpt = depth == CV_8U; + float fx, fy; + ResizeFunc func=0; + int ksize=0, ksize2; + if( interpolation == INTER_CUBIC ) + ksize = 4, func = cubic_tab[depth]; + else if( interpolation == INTER_LANCZOS4 ) + ksize = 8, func = lanczos4_tab[depth]; + else if( interpolation == INTER_LINEAR || interpolation == INTER_AREA ) + ksize = 2, func = linear_tab[depth]; + else + CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + ksize2 = ksize/2; + + CV_Assert( func != 0 ); + + AutoBuffer _buffer((width + dsize.height)*(sizeof(int) + sizeof(float)*ksize)); + int* xofs = (int*)(uchar*)_buffer; + int* yofs = xofs + width; + float* alpha = (float*)(yofs + dsize.height); + short* ialpha = (short*)alpha; + float* beta = alpha + width*ksize; + short* ibeta = ialpha + width*ksize; + float cbuf[MAX_ESIZE]; + + for( dx = 0; dx < dsize.width; dx++ ) + { + if( !area_mode ) + { + fx = (float)((dx+0.5)*scale_x - 0.5); + sx = cvFloor(fx); + fx -= sx; + } + else + { + sx = cvFloor(dx*scale_x); + fx = (float)((dx+1) - (sx+1)*inv_scale_x); + fx = fx <= 0 ? 0.f : fx - cvFloor(fx); + } + + if( sx < ksize2-1 ) + { + xmin = dx+1; + if( sx < 0 ) + fx = 0, sx = 0; + } + + if( sx + ksize2 >= ssize.width ) + { + xmax = std::min( xmax, dx ); + if( sx >= ssize.width-1 ) + fx = 0, sx = ssize.width-1; + } + + for( k = 0, sx *= cn; k < cn; k++ ) + xofs[dx*cn + k] = sx + k; + + if( interpolation == INTER_CUBIC ) + interpolateCubic( fx, cbuf ); + else if( interpolation == INTER_LANCZOS4 ) + interpolateLanczos4( fx, cbuf ); + else + { + cbuf[0] = 1.f - fx; + cbuf[1] = fx; + } + if( fixpt ) + { + for( k = 0; k < ksize; k++ ) + ialpha[dx*cn*ksize + k] = saturate_cast(cbuf[k]*INTER_RESIZE_COEF_SCALE); + for( ; k < cn*ksize; k++ ) + ialpha[dx*cn*ksize + k] = ialpha[dx*cn*ksize + k - ksize]; + } + else + { + for( k = 0; k < ksize; k++ ) + alpha[dx*cn*ksize + k] = cbuf[k]; + for( ; k < cn*ksize; k++ ) + alpha[dx*cn*ksize + k] = alpha[dx*cn*ksize + k - ksize]; + } + } + + for( dy = 0; dy < dsize.height; dy++ ) + { + if( !area_mode ) + { + fy = (float)((dy+0.5)*scale_y - 0.5); + sy = cvFloor(fy); + fy -= sy; + } + else + { + sy = cvFloor(dy*scale_y); + fy = (float)((dy+1) - (sy+1)*inv_scale_y); + fy = fy <= 0 ? 0.f : fy - cvFloor(fy); + } + + yofs[dy] = sy; + if( interpolation == INTER_CUBIC ) + interpolateCubic( fy, cbuf ); + else if( interpolation == INTER_LANCZOS4 ) + interpolateLanczos4( fy, cbuf ); + else + { + cbuf[0] = 1.f - fy; + cbuf[1] = fy; + } + + if( fixpt ) + { + for( k = 0; k < ksize; k++ ) + ibeta[dy*ksize + k] = saturate_cast(cbuf[k]*INTER_RESIZE_COEF_SCALE); + } + else + { + for( k = 0; k < ksize; k++ ) + beta[dy*ksize + k] = cbuf[k]; + } + } + + func( src, dst, xofs, fixpt ? (void*)ialpha : (void*)alpha, yofs, + fixpt ? (void*)ibeta : (void*)beta, xmin, xmax, ksize ); +} + + +/****************************************************************************************\ +* General warping (affine, perspective, remap) * +\****************************************************************************************/ + +namespace cv +{ + +template +static void remapNearest( const Mat& _src, Mat& _dst, const Mat& _xy, + int borderType, const Scalar& _borderValue ) +{ + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + const T* S0 = (const T*)_src.data; + size_t sstep = _src.step/sizeof(S0[0]); + Scalar_ cval(saturate_cast(_borderValue[0]), + saturate_cast(_borderValue[1]), + saturate_cast(_borderValue[2]), + saturate_cast(_borderValue[3])); + int dx, dy; + + unsigned width1 = ssize.width, height1 = ssize.height; + + if( _dst.isContinuous() && _xy.isContinuous() ) + { + dsize.width *= dsize.height; + dsize.height = 1; + } + + for( dy = 0; dy < dsize.height; dy++ ) + { + T* D = (T*)(_dst.data + _dst.step*dy); + const short* XY = (const short*)(_xy.data + _xy.step*dy); + + if( cn == 1 ) + { + for( dx = 0; dx < dsize.width; dx++ ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + if( (unsigned)sx < width1 && (unsigned)sy < height1 ) + D[dx] = S0[sy*sstep + sx]; + else + { + if( borderType == BORDER_REPLICATE ) + { + sx = clip(sx, 0, ssize.width); + sy = clip(sy, 0, ssize.height); + D[dx] = S0[sy*sstep + sx]; + } + else if( borderType == BORDER_CONSTANT ) + D[dx] = cval[0]; + else if( borderType != BORDER_TRANSPARENT ) + { + sx = borderInterpolate(sx, ssize.width, borderType); + sy = borderInterpolate(sy, ssize.height, borderType); + D[dx] = S0[sy*sstep + sx]; + } + } + } + } + else + { + for( dx = 0; dx < dsize.width; dx++, D += cn ) + { + int sx = XY[dx*2], sy = XY[dx*2+1], k; + const T *S; + if( (unsigned)sx < width1 && (unsigned)sy < height1 ) + { + if( cn == 3 ) + { + S = S0 + sy*sstep + sx*3; + D[0] = S[0], D[1] = S[1], D[2] = S[2]; + } + else if( cn == 4 ) + { + S = S0 + sy*sstep + sx*4; + D[0] = S[0], D[1] = S[1], D[2] = S[2], D[3] = S[3]; + } + else + { + S = S0 + sy*sstep + sx*cn; + for( k = 0; k < cn; k++ ) + D[k] = S[k]; + } + } + else if( borderType != BORDER_TRANSPARENT ) + { + if( borderType == BORDER_REPLICATE ) + { + sx = clip(sx, 0, ssize.width); + sy = clip(sy, 0, ssize.height); + S = S0 + sy*sstep + sx*cn; + } + else if( borderType == BORDER_CONSTANT ) + S = &cval[0]; + else + { + sx = borderInterpolate(sx, ssize.width, borderType); + sy = borderInterpolate(sy, ssize.height, borderType); + S = S0 + sy*sstep + sx*cn; + } + for( k = 0; k < cn; k++ ) + D[k] = S[k]; + } + } + } + } +} + + +struct RemapNoVec +{ + int operator()( const Mat&, void*, const short*, const ushort*, + const void*, int ) const { return 0; } +}; + +#if CV_SSE2 + +struct RemapVec_8u +{ + int operator()( const Mat& _src, void* _dst, const short* XY, + const ushort* FXY, const void* _wtab, int width ) const + { + int cn = _src.channels(); + + if( (cn != 1 && cn != 3 && cn != 4) || !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + const uchar *S0 = _src.data, *S1 = _src.data + _src.step; + const short* wtab = cn == 1 ? (const short*)_wtab : &BilinearTab_iC4[0][0][0]; + uchar* D = (uchar*)_dst; + int x = 0, sstep = (int)_src.step; + __m128i delta = _mm_set1_epi32(INTER_REMAP_COEF_SCALE/2); + __m128i xy2ofs = _mm_set1_epi32(cn + (sstep << 16)); + __m128i z = _mm_setzero_si128(); + int CV_DECL_ALIGNED(16) iofs0[4], iofs1[4]; + + if( cn == 1 ) + { + for( ; x <= width - 8; x += 8 ) + { + __m128i xy0 = _mm_loadu_si128( (const __m128i*)(XY + x*2)); + __m128i xy1 = _mm_loadu_si128( (const __m128i*)(XY + x*2 + 8)); + __m128i v0, v1, v2, v3, a0, a1, b0, b1; + unsigned i0, i1; + + xy0 = _mm_madd_epi16( xy0, xy2ofs ); + xy1 = _mm_madd_epi16( xy1, xy2ofs ); + _mm_store_si128( (__m128i*)iofs0, xy0 ); + _mm_store_si128( (__m128i*)iofs1, xy1 ); + + i0 = *(ushort*)(S0 + iofs0[0]) + (*(ushort*)(S0 + iofs0[1]) << 16); + i1 = *(ushort*)(S0 + iofs0[2]) + (*(ushort*)(S0 + iofs0[3]) << 16); + v0 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1)); + i0 = *(ushort*)(S1 + iofs0[0]) + (*(ushort*)(S1 + iofs0[1]) << 16); + i1 = *(ushort*)(S1 + iofs0[2]) + (*(ushort*)(S1 + iofs0[3]) << 16); + v1 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1)); + v0 = _mm_unpacklo_epi8(v0, z); + v1 = _mm_unpacklo_epi8(v1, z); + + a0 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)(wtab+FXY[x]*4)), + _mm_loadl_epi64((__m128i*)(wtab+FXY[x+1]*4))); + a1 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)(wtab+FXY[x+2]*4)), + _mm_loadl_epi64((__m128i*)(wtab+FXY[x+3]*4))); + b0 = _mm_unpacklo_epi64(a0, a1); + b1 = _mm_unpackhi_epi64(a0, a1); + v0 = _mm_madd_epi16(v0, b0); + v1 = _mm_madd_epi16(v1, b1); + v0 = _mm_add_epi32(_mm_add_epi32(v0, v1), delta); + + i0 = *(ushort*)(S0 + iofs1[0]) + (*(ushort*)(S0 + iofs1[1]) << 16); + i1 = *(ushort*)(S0 + iofs1[2]) + (*(ushort*)(S0 + iofs1[3]) << 16); + v2 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1)); + i0 = *(ushort*)(S1 + iofs1[0]) + (*(ushort*)(S1 + iofs1[1]) << 16); + i1 = *(ushort*)(S1 + iofs1[2]) + (*(ushort*)(S1 + iofs1[3]) << 16); + v3 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1)); + v2 = _mm_unpacklo_epi8(v2, z); + v3 = _mm_unpacklo_epi8(v3, z); + + a0 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)(wtab+FXY[x+4]*4)), + _mm_loadl_epi64((__m128i*)(wtab+FXY[x+5]*4))); + a1 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)(wtab+FXY[x+6]*4)), + _mm_loadl_epi64((__m128i*)(wtab+FXY[x+7]*4))); + b0 = _mm_unpacklo_epi64(a0, a1); + b1 = _mm_unpackhi_epi64(a0, a1); + v2 = _mm_madd_epi16(v2, b0); + v3 = _mm_madd_epi16(v3, b1); + v2 = _mm_add_epi32(_mm_add_epi32(v2, v3), delta); + + v0 = _mm_srai_epi32(v0, INTER_REMAP_COEF_BITS); + v2 = _mm_srai_epi32(v2, INTER_REMAP_COEF_BITS); + v0 = _mm_packus_epi16(_mm_packs_epi32(v0, v2), z); + _mm_storel_epi64( (__m128i*)(D + x), v0 ); + } + } + else if( cn == 3 ) + { + for( ; x <= width - 5; x += 4, D += 12 ) + { + __m128i xy0 = _mm_loadu_si128( (const __m128i*)(XY + x*2)); + __m128i u0, v0, u1, v1; + + xy0 = _mm_madd_epi16( xy0, xy2ofs ); + _mm_store_si128( (__m128i*)iofs0, xy0 ); + const __m128i *w0, *w1; + w0 = (const __m128i*)(wtab + FXY[x]*16); + w1 = (const __m128i*)(wtab + FXY[x+1]*16); + + u0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[0])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[0] + 3))); + v0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[0])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[0] + 3))); + u1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[1])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[1] + 3))); + v1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[1])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[1] + 3))); + u0 = _mm_unpacklo_epi8(u0, z); + v0 = _mm_unpacklo_epi8(v0, z); + u1 = _mm_unpacklo_epi8(u1, z); + v1 = _mm_unpacklo_epi8(v1, z); + u0 = _mm_add_epi32(_mm_madd_epi16(u0, w0[0]), _mm_madd_epi16(v0, w0[1])); + u1 = _mm_add_epi32(_mm_madd_epi16(u1, w1[0]), _mm_madd_epi16(v1, w1[1])); + u0 = _mm_srai_epi32(_mm_add_epi32(u0, delta), INTER_REMAP_COEF_BITS); + u1 = _mm_srai_epi32(_mm_add_epi32(u1, delta), INTER_REMAP_COEF_BITS); + u0 = _mm_slli_si128(u0, 4); + u0 = _mm_packs_epi32(u0, u1); + u0 = _mm_packus_epi16(u0, u0); + _mm_storel_epi64((__m128i*)D, _mm_srli_si128(u0,1)); + + w0 = (const __m128i*)(wtab + FXY[x+2]*16); + w1 = (const __m128i*)(wtab + FXY[x+3]*16); + + u0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[2])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[2] + 3))); + v0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[2])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[2] + 3))); + u1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[3])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[3] + 3))); + v1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[3])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[3] + 3))); + u0 = _mm_unpacklo_epi8(u0, z); + v0 = _mm_unpacklo_epi8(v0, z); + u1 = _mm_unpacklo_epi8(u1, z); + v1 = _mm_unpacklo_epi8(v1, z); + u0 = _mm_add_epi32(_mm_madd_epi16(u0, w0[0]), _mm_madd_epi16(v0, w0[1])); + u1 = _mm_add_epi32(_mm_madd_epi16(u1, w1[0]), _mm_madd_epi16(v1, w1[1])); + u0 = _mm_srai_epi32(_mm_add_epi32(u0, delta), INTER_REMAP_COEF_BITS); + u1 = _mm_srai_epi32(_mm_add_epi32(u1, delta), INTER_REMAP_COEF_BITS); + u0 = _mm_slli_si128(u0, 4); + u0 = _mm_packs_epi32(u0, u1); + u0 = _mm_packus_epi16(u0, u0); + _mm_storel_epi64((__m128i*)(D + 6), _mm_srli_si128(u0,1)); + } + } + else if( cn == 4 ) + { + for( ; x <= width - 4; x += 4, D += 16 ) + { + __m128i xy0 = _mm_loadu_si128( (const __m128i*)(XY + x*2)); + __m128i u0, v0, u1, v1; + + xy0 = _mm_madd_epi16( xy0, xy2ofs ); + _mm_store_si128( (__m128i*)iofs0, xy0 ); + const __m128i *w0, *w1; + w0 = (const __m128i*)(wtab + FXY[x]*16); + w1 = (const __m128i*)(wtab + FXY[x+1]*16); + + u0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[0])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[0] + 4))); + v0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[0])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[0] + 4))); + u1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[1])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[1] + 4))); + v1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[1])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[1] + 4))); + u0 = _mm_unpacklo_epi8(u0, z); + v0 = _mm_unpacklo_epi8(v0, z); + u1 = _mm_unpacklo_epi8(u1, z); + v1 = _mm_unpacklo_epi8(v1, z); + u0 = _mm_add_epi32(_mm_madd_epi16(u0, w0[0]), _mm_madd_epi16(v0, w0[1])); + u1 = _mm_add_epi32(_mm_madd_epi16(u1, w1[0]), _mm_madd_epi16(v1, w1[1])); + u0 = _mm_srai_epi32(_mm_add_epi32(u0, delta), INTER_REMAP_COEF_BITS); + u1 = _mm_srai_epi32(_mm_add_epi32(u1, delta), INTER_REMAP_COEF_BITS); + u0 = _mm_packs_epi32(u0, u1); + u0 = _mm_packus_epi16(u0, u0); + _mm_storel_epi64((__m128i*)D, u0); + + w0 = (const __m128i*)(wtab + FXY[x+2]*16); + w1 = (const __m128i*)(wtab + FXY[x+3]*16); + + u0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[2])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[2] + 4))); + v0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[2])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[2] + 4))); + u1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S0 + iofs0[3])), + _mm_cvtsi32_si128(*(int*)(S0 + iofs0[3] + 4))); + v1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(int*)(S1 + iofs0[3])), + _mm_cvtsi32_si128(*(int*)(S1 + iofs0[3] + 4))); + u0 = _mm_unpacklo_epi8(u0, z); + v0 = _mm_unpacklo_epi8(v0, z); + u1 = _mm_unpacklo_epi8(u1, z); + v1 = _mm_unpacklo_epi8(v1, z); + u0 = _mm_add_epi32(_mm_madd_epi16(u0, w0[0]), _mm_madd_epi16(v0, w0[1])); + u1 = _mm_add_epi32(_mm_madd_epi16(u1, w1[0]), _mm_madd_epi16(v1, w1[1])); + u0 = _mm_srai_epi32(_mm_add_epi32(u0, delta), INTER_REMAP_COEF_BITS); + u1 = _mm_srai_epi32(_mm_add_epi32(u1, delta), INTER_REMAP_COEF_BITS); + u0 = _mm_packs_epi32(u0, u1); + u0 = _mm_packus_epi16(u0, u0); + _mm_storel_epi64((__m128i*)(D + 8), u0); + } + } + + return x; + } +}; + +#else + +typedef RemapNoVec RemapVec_8u; + +#endif + + +template +static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, + const Mat& _fxy, const void* _wtab, + int borderType, const Scalar& _borderValue ) +{ + typedef typename CastOp::rtype T; + typedef typename CastOp::type1 WT; + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + const AT* wtab = (const AT*)_wtab; + const T* S0 = (const T*)_src.data; + size_t sstep = _src.step/sizeof(S0[0]); + Scalar_ cval(saturate_cast(_borderValue[0]), + saturate_cast(_borderValue[1]), + saturate_cast(_borderValue[2]), + saturate_cast(_borderValue[3])); + int dx, dy; + CastOp castOp; + VecOp vecOp; + + unsigned width1 = std::max(ssize.width-1, 0), height1 = std::max(ssize.height-1, 0); + CV_Assert( cn <= 4 && ssize.area() > 0 ); +#if CV_SSE2 + if( _src.type() == CV_8UC3 ) + width1 = std::max(ssize.width-2, 0); +#endif + + for( dy = 0; dy < dsize.height; dy++ ) + { + T* D = (T*)(_dst.data + _dst.step*dy); + const short* XY = (const short*)(_xy.data + _xy.step*dy); + const ushort* FXY = (const ushort*)(_fxy.data + _fxy.step*dy); + int X0 = 0; + bool prevInlier = false; + + for( dx = 0; dx <= dsize.width; dx++ ) + { + bool curInlier = dx < dsize.width ? + (unsigned)XY[dx*2] < width1 && + (unsigned)XY[dx*2+1] < height1 : !prevInlier; + if( curInlier == prevInlier ) + continue; + + int X1 = dx; + dx = X0; + X0 = X1; + prevInlier = curInlier; + + if( !curInlier ) + { + int len = vecOp( _src, D, XY + dx*2, FXY + dx, wtab, X1 - dx ); + D += len*cn; + dx += len; + + if( cn == 1 ) + { + for( ; dx < X1; dx++, D++ ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx; + *D = castOp(WT(S[0]*w[0] + S[1]*w[1] + S[sstep]*w[2] + S[sstep+1]*w[3])); + } + } + else if( cn == 2 ) + for( ; dx < X1; dx++, D += 2 ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx*2; + WT t0 = S[0]*w[0] + S[2]*w[1] + S[sstep]*w[2] + S[sstep+2]*w[3]; + WT t1 = S[1]*w[0] + S[3]*w[1] + S[sstep+1]*w[2] + S[sstep+3]*w[3]; + D[0] = castOp(t0); D[1] = castOp(t1); + } + else if( cn == 3 ) + for( ; dx < X1; dx++, D += 3 ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx*3; + WT t0 = S[0]*w[0] + S[3]*w[1] + S[sstep]*w[2] + S[sstep+3]*w[3]; + WT t1 = S[1]*w[0] + S[4]*w[1] + S[sstep+1]*w[2] + S[sstep+4]*w[3]; + WT t2 = S[2]*w[0] + S[5]*w[1] + S[sstep+2]*w[2] + S[sstep+5]*w[3]; + D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2); + } + else + for( ; dx < X1; dx++, D += 4 ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx*4; + WT t0 = S[0]*w[0] + S[4]*w[1] + S[sstep]*w[2] + S[sstep+4]*w[3]; + WT t1 = S[1]*w[0] + S[5]*w[1] + S[sstep+1]*w[2] + S[sstep+5]*w[3]; + D[0] = castOp(t0); D[1] = castOp(t1); + t0 = S[2]*w[0] + S[6]*w[1] + S[sstep+2]*w[2] + S[sstep+6]*w[3]; + t1 = S[3]*w[0] + S[7]*w[1] + S[sstep+3]*w[2] + S[sstep+7]*w[3]; + D[2] = castOp(t0); D[3] = castOp(t1); + } + } + else + { + if( borderType == BORDER_TRANSPARENT && cn != 3 ) + { + D += (X1 - dx)*cn; + dx = X1; + continue; + } + + if( cn == 1 ) + for( ; dx < X1; dx++, D++ ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + if( borderType == BORDER_CONSTANT && + (sx >= ssize.width || sx+1 < 0 || + sy >= ssize.height || sy+1 < 0) ) + { + D[0] = cval[0]; + } + else + { + int sx0, sx1, sy0, sy1; + T v0, v1, v2, v3; + const AT* w = wtab + FXY[dx]*4; + if( borderType == BORDER_REPLICATE ) + { + sx0 = clip(sx, 0, ssize.width); + sx1 = clip(sx+1, 0, ssize.width); + sy0 = clip(sy, 0, ssize.height); + sy1 = clip(sy+1, 0, ssize.height); + v0 = S0[sy0*sstep + sx0]; + v1 = S0[sy0*sstep + sx1]; + v2 = S0[sy1*sstep + sx0]; + v3 = S0[sy1*sstep + sx1]; + } + else + { + sx0 = borderInterpolate(sx, ssize.width, borderType); + sx1 = borderInterpolate(sx+1, ssize.width, borderType); + sy0 = borderInterpolate(sy, ssize.height, borderType); + sy1 = borderInterpolate(sy+1, ssize.height, borderType); + v0 = sx0 >= 0 && sy0 >= 0 ? S0[sy0*sstep + sx0] : cval[0]; + v1 = sx1 >= 0 && sy0 >= 0 ? S0[sy0*sstep + sx1] : cval[0]; + v2 = sx0 >= 0 && sy1 >= 0 ? S0[sy1*sstep + sx0] : cval[0]; + v3 = sx1 >= 0 && sy1 >= 0 ? S0[sy1*sstep + sx1] : cval[0]; + } + D[0] = castOp(WT(v0*w[0] + v1*w[1] + v2*w[2] + v3*w[3])); + } + } + else + for( ; dx < X1; dx++, D += cn ) + { + int sx = XY[dx*2], sy = XY[dx*2+1], k; + if( borderType == BORDER_CONSTANT && + (sx >= ssize.width || sx+1 < 0 || + sy >= ssize.height || sy+1 < 0) ) + { + for( k = 0; k < cn; k++ ) + D[k] = cval[k]; + } + else + { + int sx0, sx1, sy0, sy1; + const T *v0, *v1, *v2, *v3; + const AT* w = wtab + FXY[dx]*4; + if( borderType == BORDER_REPLICATE ) + { + sx0 = clip(sx, 0, ssize.width); + sx1 = clip(sx+1, 0, ssize.width); + sy0 = clip(sy, 0, ssize.height); + sy1 = clip(sy+1, 0, ssize.height); + v0 = S0 + sy0*sstep + sx0*cn; + v1 = S0 + sy0*sstep + sx1*cn; + v2 = S0 + sy1*sstep + sx0*cn; + v3 = S0 + sy1*sstep + sx1*cn; + } + else if( borderType == BORDER_TRANSPARENT && + ((unsigned)sx >= (unsigned)(ssize.width-1) || + (unsigned)sy >= (unsigned)(ssize.height-1))) + continue; + else + { + sx0 = borderInterpolate(sx, ssize.width, borderType); + sx1 = borderInterpolate(sx+1, ssize.width, borderType); + sy0 = borderInterpolate(sy, ssize.height, borderType); + sy1 = borderInterpolate(sy+1, ssize.height, borderType); + v0 = sx0 >= 0 && sy0 >= 0 ? S0 + sy0*sstep + sx0*cn : &cval[0]; + v1 = sx1 >= 0 && sy0 >= 0 ? S0 + sy0*sstep + sx1*cn : &cval[0]; + v2 = sx0 >= 0 && sy1 >= 0 ? S0 + sy1*sstep + sx0*cn : &cval[0]; + v3 = sx1 >= 0 && sy1 >= 0 ? S0 + sy1*sstep + sx1*cn : &cval[0]; + } + for( k = 0; k < cn; k++ ) + D[k] = castOp(WT(v0[k]*w[0] + v1[k]*w[1] + v2[k]*w[2] + v3[k]*w[3])); + } + } + } + } + } +} + + +template +static void remapBicubic( const Mat& _src, Mat& _dst, const Mat& _xy, + const Mat& _fxy, const void* _wtab, + int borderType, const Scalar& _borderValue ) +{ + typedef typename CastOp::rtype T; + typedef typename CastOp::type1 WT; + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + const AT* wtab = (const AT*)_wtab; + const T* S0 = (const T*)_src.data; + size_t sstep = _src.step/sizeof(S0[0]); + Scalar_ cval(saturate_cast(_borderValue[0]), + saturate_cast(_borderValue[1]), + saturate_cast(_borderValue[2]), + saturate_cast(_borderValue[3])); + int dx, dy; + CastOp castOp; + int borderType1 = borderType != BORDER_TRANSPARENT ? borderType : BORDER_REFLECT_101; + + unsigned width1 = std::max(ssize.width-3, 0), height1 = std::max(ssize.height-3, 0); + + if( _dst.isContinuous() && _xy.isContinuous() && _fxy.isContinuous() ) + { + dsize.width *= dsize.height; + dsize.height = 1; + } + + for( dy = 0; dy < dsize.height; dy++ ) + { + T* D = (T*)(_dst.data + _dst.step*dy); + const short* XY = (const short*)(_xy.data + _xy.step*dy); + const ushort* FXY = (const ushort*)(_fxy.data + _fxy.step*dy); + + for( dx = 0; dx < dsize.width; dx++, D += cn ) + { + int sx = XY[dx*2]-1, sy = XY[dx*2+1]-1; + const AT* w = wtab + FXY[dx]*16; + int i, k; + if( (unsigned)sx < width1 && (unsigned)sy < height1 ) + { + const T* S = S0 + sy*sstep + sx*cn; + for( k = 0; k < cn; k++ ) + { + WT sum = S[0]*w[0] + S[cn]*w[1] + S[cn*2]*w[2] + S[cn*3]*w[3]; + S += sstep; + sum += S[0]*w[4] + S[cn]*w[5] + S[cn*2]*w[6] + S[cn*3]*w[7]; + S += sstep; + sum += S[0]*w[8] + S[cn]*w[9] + S[cn*2]*w[10] + S[cn*3]*w[11]; + S += sstep; + sum += S[0]*w[12] + S[cn]*w[13] + S[cn*2]*w[14] + S[cn*3]*w[15]; + S += 1 - sstep*3; + D[k] = castOp(sum); + } + } + else + { + int x[4], y[4]; + if( borderType == BORDER_TRANSPARENT && + ((unsigned)(sx+1) >= (unsigned)ssize.width || + (unsigned)(sy+1) >= (unsigned)ssize.height) ) + continue; + + if( borderType1 == BORDER_CONSTANT && + (sx >= ssize.width || sx+4 <= 0 || + sy >= ssize.height || sy+4 <= 0)) + { + for( k = 0; k < cn; k++ ) + D[k] = cval[k]; + continue; + } + + for( i = 0; i < 4; i++ ) + { + x[i] = borderInterpolate(sx + i, ssize.width, borderType1)*cn; + y[i] = borderInterpolate(sy + i, ssize.height, borderType1); + } + + for( k = 0; k < cn; k++, S0++, w -= 16 ) + { + WT cv = cval[k], sum = cv*ONE; + for( i = 0; i < 4; i++, w += 4 ) + { + int yi = y[i]; + const T* S = S0 + yi*sstep; + if( yi < 0 ) + continue; + if( x[0] >= 0 ) + sum += (S[x[0]] - cv)*w[0]; + if( x[1] >= 0 ) + sum += (S[x[1]] - cv)*w[1]; + if( x[2] >= 0 ) + sum += (S[x[2]] - cv)*w[2]; + if( x[3] >= 0 ) + sum += (S[x[3]] - cv)*w[3]; + } + D[k] = castOp(sum); + } + S0 -= cn; + } + } + } +} + + +template +static void remapLanczos4( const Mat& _src, Mat& _dst, const Mat& _xy, + const Mat& _fxy, const void* _wtab, + int borderType, const Scalar& _borderValue ) +{ + typedef typename CastOp::rtype T; + typedef typename CastOp::type1 WT; + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + const AT* wtab = (const AT*)_wtab; + const T* S0 = (const T*)_src.data; + size_t sstep = _src.step/sizeof(S0[0]); + Scalar_ cval(saturate_cast(_borderValue[0]), + saturate_cast(_borderValue[1]), + saturate_cast(_borderValue[2]), + saturate_cast(_borderValue[3])); + int dx, dy; + CastOp castOp; + int borderType1 = borderType != BORDER_TRANSPARENT ? borderType : BORDER_REFLECT_101; + + unsigned width1 = std::max(ssize.width-7, 0), height1 = std::max(ssize.height-7, 0); + + if( _dst.isContinuous() && _xy.isContinuous() && _fxy.isContinuous() ) + { + dsize.width *= dsize.height; + dsize.height = 1; + } + + for( dy = 0; dy < dsize.height; dy++ ) + { + T* D = (T*)(_dst.data + _dst.step*dy); + const short* XY = (const short*)(_xy.data + _xy.step*dy); + const ushort* FXY = (const ushort*)(_fxy.data + _fxy.step*dy); + + for( dx = 0; dx < dsize.width; dx++, D += cn ) + { + int sx = XY[dx*2]-3, sy = XY[dx*2+1]-3; + const AT* w = wtab + FXY[dx]*64; + const T* S = S0 + sy*sstep + sx*cn; + int i, k; + if( (unsigned)sx < width1 && (unsigned)sy < height1 ) + { + for( k = 0; k < cn; k++ ) + { + WT sum = 0; + for( int r = 0; r < 8; r++, S += sstep, w += 8 ) + sum += S[0]*w[0] + S[cn]*w[1] + S[cn*2]*w[2] + S[cn*3]*w[3] + + S[cn*4]*w[4] + S[cn*5]*w[5] + S[cn*6]*w[6] + S[cn*7]*w[7]; + w -= 64; + S -= sstep*8 - 1; + D[k] = castOp(sum); + } + } + else + { + int x[8], y[8]; + if( borderType == BORDER_TRANSPARENT && + ((unsigned)(sx+3) >= (unsigned)ssize.width || + (unsigned)(sy+3) >= (unsigned)ssize.height) ) + continue; + + if( borderType1 == BORDER_CONSTANT && + (sx >= ssize.width || sx+8 <= 0 || + sy >= ssize.height || sy+8 <= 0)) + { + for( k = 0; k < cn; k++ ) + D[k] = cval[k]; + continue; + } + + for( i = 0; i < 8; i++ ) + { + x[i] = borderInterpolate(sx + i, ssize.width, borderType1)*cn; + y[i] = borderInterpolate(sy + i, ssize.height, borderType1); + } + + for( k = 0; k < cn; k++, S0++, w -= 64 ) + { + WT cv = cval[k], sum = cv*ONE; + for( i = 0; i < 8; i++, w += 8 ) + { + int yi = y[i]; + const T* S1 = S0 + yi*sstep; + if( yi < 0 ) + continue; + if( x[0] >= 0 ) + sum += (S1[x[0]] - cv)*w[0]; + if( x[1] >= 0 ) + sum += (S1[x[1]] - cv)*w[1]; + if( x[2] >= 0 ) + sum += (S1[x[2]] - cv)*w[2]; + if( x[3] >= 0 ) + sum += (S1[x[3]] - cv)*w[3]; + if( x[4] >= 0 ) + sum += (S1[x[4]] - cv)*w[4]; + if( x[5] >= 0 ) + sum += (S1[x[5]] - cv)*w[5]; + if( x[6] >= 0 ) + sum += (S1[x[6]] - cv)*w[6]; + if( x[7] >= 0 ) + sum += (S1[x[7]] - cv)*w[7]; + } + D[k] = castOp(sum); + } + S0 -= cn; + } + } + } +} + + +typedef void (*RemapNNFunc)(const Mat& _src, Mat& _dst, const Mat& _xy, + int borderType, const Scalar& _borderValue ); + +typedef void (*RemapFunc)(const Mat& _src, Mat& _dst, const Mat& _xy, + const Mat& _fxy, const void* _wtab, + int borderType, const Scalar& _borderValue); + +class RemapInvoker : + public ParallelLoopBody +{ +public: + RemapInvoker(const Mat& _src, Mat& _dst, const Mat *_m1, + const Mat *_m2, int _interpolation, int _borderType, const Scalar &_borderValue, + int _planar_input, RemapNNFunc _nnfunc, RemapFunc _ifunc, const void *_ctab) : + ParallelLoopBody(), src(&_src), dst(&_dst), m1(_m1), m2(_m2), + interpolation(_interpolation), borderType(_borderType), borderValue(_borderValue), + planar_input(_planar_input), nnfunc(_nnfunc), ifunc(_ifunc), ctab(_ctab) + { + } + + virtual void operator() (const Range& range) const + { + int x, y, x1, y1; + const int buf_size = 1 << 14; + int brows0 = std::min(128, dst->rows), map_depth = m1->depth(); + int bcols0 = std::min(buf_size/brows0, dst->cols); + brows0 = std::min(buf_size/bcols0, dst->rows); + #if CV_SSE2 + bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); + #endif + + Mat _bufxy(brows0, bcols0, CV_16SC2), _bufa; + if( !nnfunc ) + _bufa.create(brows0, bcols0, CV_16UC1); + + for( y = range.start; y < range.end; y += brows0 ) + { + for( x = 0; x < dst->cols; x += bcols0 ) + { + int brows = std::min(brows0, range.end - y); + int bcols = std::min(bcols0, dst->cols - x); + Mat dpart(*dst, Rect(x, y, bcols, brows)); + Mat bufxy(_bufxy, Rect(0, 0, bcols, brows)); + + if( nnfunc ) + { + if( m1->type() == CV_16SC2 && !m2->data ) // the data is already in the right format + bufxy = (*m1)(Rect(x, y, bcols, brows)); + else if( map_depth != CV_32F ) + { + for( y1 = 0; y1 < brows; y1++ ) + { + short* XY = (short*)(bufxy.data + bufxy.step*y1); + const short* sXY = (const short*)(m1->data + m1->step*(y+y1)) + x*2; + const ushort* sA = (const ushort*)(m2->data + m2->step*(y+y1)) + x; + + for( x1 = 0; x1 < bcols; x1++ ) + { + int a = sA[x1] & (INTER_TAB_SIZE2-1); + XY[x1*2] = sXY[x1*2] + NNDeltaTab_i[a][0]; + XY[x1*2+1] = sXY[x1*2+1] + NNDeltaTab_i[a][1]; + } + } + } + else if( !planar_input ) + (*m1)(Rect(x, y, bcols, brows)).convertTo(bufxy, bufxy.depth()); + else + { + for( y1 = 0; y1 < brows; y1++ ) + { + short* XY = (short*)(bufxy.data + bufxy.step*y1); + const float* sX = (const float*)(m1->data + m1->step*(y+y1)) + x; + const float* sY = (const float*)(m2->data + m2->step*(y+y1)) + x; + x1 = 0; + + #if CV_SSE2 + if( useSIMD ) + { + for( ; x1 <= bcols - 8; x1 += 8 ) + { + __m128 fx0 = _mm_loadu_ps(sX + x1); + __m128 fx1 = _mm_loadu_ps(sX + x1 + 4); + __m128 fy0 = _mm_loadu_ps(sY + x1); + __m128 fy1 = _mm_loadu_ps(sY + x1 + 4); + __m128i ix0 = _mm_cvtps_epi32(fx0); + __m128i ix1 = _mm_cvtps_epi32(fx1); + __m128i iy0 = _mm_cvtps_epi32(fy0); + __m128i iy1 = _mm_cvtps_epi32(fy1); + ix0 = _mm_packs_epi32(ix0, ix1); + iy0 = _mm_packs_epi32(iy0, iy1); + ix1 = _mm_unpacklo_epi16(ix0, iy0); + iy1 = _mm_unpackhi_epi16(ix0, iy0); + _mm_storeu_si128((__m128i*)(XY + x1*2), ix1); + _mm_storeu_si128((__m128i*)(XY + x1*2 + 8), iy1); + } + } + #endif + + for( ; x1 < bcols; x1++ ) + { + XY[x1*2] = saturate_cast(sX[x1]); + XY[x1*2+1] = saturate_cast(sY[x1]); + } + } + } + nnfunc( *src, dpart, bufxy, borderType, borderValue ); + continue; + } + + Mat bufa(_bufa, Rect(0, 0, bcols, brows)); + for( y1 = 0; y1 < brows; y1++ ) + { + short* XY = (short*)(bufxy.data + bufxy.step*y1); + ushort* A = (ushort*)(bufa.data + bufa.step*y1); + + if( m1->type() == CV_16SC2 && (m2->type() == CV_16UC1 || m2->type() == CV_16SC1) ) + { + bufxy = (*m1)(Rect(x, y, bcols, brows)); + bufa = (*m2)(Rect(x, y, bcols, brows)); + } + else if( planar_input ) + { + const float* sX = (const float*)(m1->data + m1->step*(y+y1)) + x; + const float* sY = (const float*)(m2->data + m2->step*(y+y1)) + x; + + x1 = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128 scale = _mm_set1_ps((float)INTER_TAB_SIZE); + __m128i mask = _mm_set1_epi32(INTER_TAB_SIZE-1); + for( ; x1 <= bcols - 8; x1 += 8 ) + { + __m128 fx0 = _mm_loadu_ps(sX + x1); + __m128 fx1 = _mm_loadu_ps(sX + x1 + 4); + __m128 fy0 = _mm_loadu_ps(sY + x1); + __m128 fy1 = _mm_loadu_ps(sY + x1 + 4); + __m128i ix0 = _mm_cvtps_epi32(_mm_mul_ps(fx0, scale)); + __m128i ix1 = _mm_cvtps_epi32(_mm_mul_ps(fx1, scale)); + __m128i iy0 = _mm_cvtps_epi32(_mm_mul_ps(fy0, scale)); + __m128i iy1 = _mm_cvtps_epi32(_mm_mul_ps(fy1, scale)); + __m128i mx0 = _mm_and_si128(ix0, mask); + __m128i mx1 = _mm_and_si128(ix1, mask); + __m128i my0 = _mm_and_si128(iy0, mask); + __m128i my1 = _mm_and_si128(iy1, mask); + mx0 = _mm_packs_epi32(mx0, mx1); + my0 = _mm_packs_epi32(my0, my1); + my0 = _mm_slli_epi16(my0, INTER_BITS); + mx0 = _mm_or_si128(mx0, my0); + _mm_storeu_si128((__m128i*)(A + x1), mx0); + ix0 = _mm_srai_epi32(ix0, INTER_BITS); + ix1 = _mm_srai_epi32(ix1, INTER_BITS); + iy0 = _mm_srai_epi32(iy0, INTER_BITS); + iy1 = _mm_srai_epi32(iy1, INTER_BITS); + ix0 = _mm_packs_epi32(ix0, ix1); + iy0 = _mm_packs_epi32(iy0, iy1); + ix1 = _mm_unpacklo_epi16(ix0, iy0); + iy1 = _mm_unpackhi_epi16(ix0, iy0); + _mm_storeu_si128((__m128i*)(XY + x1*2), ix1); + _mm_storeu_si128((__m128i*)(XY + x1*2 + 8), iy1); + } + } + #endif + + for( ; x1 < bcols; x1++ ) + { + int sx = cvRound(sX[x1]*INTER_TAB_SIZE); + int sy = cvRound(sY[x1]*INTER_TAB_SIZE); + int v = (sy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE-1)); + XY[x1*2] = (short)(sx >> INTER_BITS); + XY[x1*2+1] = (short)(sy >> INTER_BITS); + A[x1] = (ushort)v; + } + } + else + { + const float* sXY = (const float*)(m1->data + m1->step*(y+y1)) + x*2; + + for( x1 = 0; x1 < bcols; x1++ ) + { + int sx = cvRound(sXY[x1*2]*INTER_TAB_SIZE); + int sy = cvRound(sXY[x1*2+1]*INTER_TAB_SIZE); + int v = (sy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE-1)); + XY[x1*2] = (short)(sx >> INTER_BITS); + XY[x1*2+1] = (short)(sy >> INTER_BITS); + A[x1] = (ushort)v; + } + } + } + ifunc(*src, dpart, bufxy, bufa, ctab, borderType, borderValue); + } + } + } + +private: + const Mat* src; + Mat* dst; + const Mat *m1, *m2; + int interpolation, borderType; + Scalar borderValue; + int planar_input; + RemapNNFunc nnfunc; + RemapFunc ifunc; + const void *ctab; +}; + +} + +void cv::remap( InputArray _src, OutputArray _dst, + InputArray _map1, InputArray _map2, + int interpolation, int borderType, const Scalar& borderValue ) +{ + static RemapNNFunc nn_tab[] = + { + remapNearest, remapNearest, remapNearest, remapNearest, + remapNearest, remapNearest, remapNearest, 0 + }; + + static RemapFunc linear_tab[] = + { + remapBilinear, RemapVec_8u, short>, 0, + remapBilinear, RemapNoVec, float>, + remapBilinear, RemapNoVec, float>, 0, + remapBilinear, RemapNoVec, float>, + remapBilinear, RemapNoVec, float>, 0 + }; + + static RemapFunc cubic_tab[] = + { + remapBicubic, short, INTER_REMAP_COEF_SCALE>, 0, + remapBicubic, float, 1>, + remapBicubic, float, 1>, 0, + remapBicubic, float, 1>, + remapBicubic, float, 1>, 0 + }; + + static RemapFunc lanczos4_tab[] = + { + remapLanczos4, short, INTER_REMAP_COEF_SCALE>, 0, + remapLanczos4, float, 1>, + remapLanczos4, float, 1>, 0, + remapLanczos4, float, 1>, + remapLanczos4, float, 1>, 0 + }; + + Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat(); + + CV_Assert( map1.size().area() > 0 ); + CV_Assert( !map2.data || (map2.size() == map1.size())); + + _dst.create( map1.size(), src.type() ); + Mat dst = _dst.getMat(); + if( dst.data == src.data ) + src = src.clone(); + + int depth = src.depth(); + RemapNNFunc nnfunc = 0; + RemapFunc ifunc = 0; + const void* ctab = 0; + bool fixpt = depth == CV_8U; + bool planar_input = false; + + if( interpolation == INTER_NEAREST ) + { + nnfunc = nn_tab[depth]; + CV_Assert( nnfunc != 0 ); + } + else + { + if( interpolation == INTER_AREA ) + interpolation = INTER_LINEAR; + + if( interpolation == INTER_LINEAR ) + ifunc = linear_tab[depth]; + else if( interpolation == INTER_CUBIC ) + ifunc = cubic_tab[depth]; + else if( interpolation == INTER_LANCZOS4 ) + ifunc = lanczos4_tab[depth]; + else + CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Assert( ifunc != 0 ); + ctab = initInterTab2D( interpolation, fixpt ); + } + + const Mat *m1 = &map1, *m2 = &map2; + + if( (map1.type() == CV_16SC2 && (map2.type() == CV_16UC1 || map2.type() == CV_16SC1 || !map2.data)) || + (map2.type() == CV_16SC2 && (map1.type() == CV_16UC1 || map1.type() == CV_16SC1 || !map1.data)) ) + { + if( map1.type() != CV_16SC2 ) + std::swap(m1, m2); + } + else + { + CV_Assert( ((map1.type() == CV_32FC2 || map1.type() == CV_16SC2) && !map2.data) || + (map1.type() == CV_32FC1 && map2.type() == CV_32FC1) ); + planar_input = map1.channels() == 1; + } + + RemapInvoker invoker(src, dst, m1, m2, interpolation, + borderType, borderValue, planar_input, nnfunc, ifunc, + ctab); + parallel_for_(Range(0, dst.rows), invoker, dst.total()/(double)(1<<16)); +} + + +void cv::convertMaps( InputArray _map1, InputArray _map2, + OutputArray _dstmap1, OutputArray _dstmap2, + int dstm1type, bool nninterpolate ) +{ + Mat map1 = _map1.getMat(), map2 = _map2.getMat(), dstmap1, dstmap2; + Size size = map1.size(); + const Mat *m1 = &map1, *m2 = &map2; + int m1type = m1->type(), m2type = m2->type(); + + CV_Assert( (m1type == CV_16SC2 && (nninterpolate || m2type == CV_16UC1 || m2type == CV_16SC1)) || + (m2type == CV_16SC2 && (nninterpolate || m1type == CV_16UC1 || m1type == CV_16SC1)) || + (m1type == CV_32FC1 && m2type == CV_32FC1) || + (m1type == CV_32FC2 && !m2->data) ); + + if( m2type == CV_16SC2 ) + { + std::swap( m1, m2 ); + std::swap( m1type, m2type ); + } + + if( dstm1type <= 0 ) + dstm1type = m1type == CV_16SC2 ? CV_32FC2 : CV_16SC2; + CV_Assert( dstm1type == CV_16SC2 || dstm1type == CV_32FC1 || dstm1type == CV_32FC2 ); + _dstmap1.create( size, dstm1type ); + dstmap1 = _dstmap1.getMat(); + + if( !nninterpolate && dstm1type != CV_32FC2 ) + { + _dstmap2.create( size, dstm1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 ); + dstmap2 = _dstmap2.getMat(); + } + else + _dstmap2.release(); + + if( m1type == dstm1type || (nninterpolate && + ((m1type == CV_16SC2 && dstm1type == CV_32FC2) || + (m1type == CV_32FC2 && dstm1type == CV_16SC2))) ) + { + m1->convertTo( dstmap1, dstmap1.type() ); + if( dstmap2.data && dstmap2.type() == m2->type() ) + m2->copyTo( dstmap2 ); + return; + } + + if( m1type == CV_32FC1 && dstm1type == CV_32FC2 ) + { + Mat vdata[] = { *m1, *m2 }; + merge( vdata, 2, dstmap1 ); + return; + } + + if( m1type == CV_32FC2 && dstm1type == CV_32FC1 ) + { + Mat mv[] = { dstmap1, dstmap2 }; + split( *m1, mv ); + return; + } + + if( m1->isContinuous() && (!m2->data || m2->isContinuous()) && + dstmap1.isContinuous() && (!dstmap2.data || dstmap2.isContinuous()) ) + { + size.width *= size.height; + size.height = 1; + } + + const float scale = 1.f/INTER_TAB_SIZE; + int x, y; + for( y = 0; y < size.height; y++ ) + { + const float* src1f = (const float*)(m1->data + m1->step*y); + const float* src2f = (const float*)(m2->data + m2->step*y); + const short* src1 = (const short*)src1f; + const ushort* src2 = (const ushort*)src2f; + + float* dst1f = (float*)(dstmap1.data + dstmap1.step*y); + float* dst2f = (float*)(dstmap2.data + dstmap2.step*y); + short* dst1 = (short*)dst1f; + ushort* dst2 = (ushort*)dst2f; + + if( m1type == CV_32FC1 && dstm1type == CV_16SC2 ) + { + if( nninterpolate ) + for( x = 0; x < size.width; x++ ) + { + dst1[x*2] = saturate_cast(src1f[x]); + dst1[x*2+1] = saturate_cast(src2f[x]); + } + else + for( x = 0; x < size.width; x++ ) + { + int ix = saturate_cast(src1f[x]*INTER_TAB_SIZE); + int iy = saturate_cast(src2f[x]*INTER_TAB_SIZE); + dst1[x*2] = (short)(ix >> INTER_BITS); + dst1[x*2+1] = (short)(iy >> INTER_BITS); + dst2[x] = (ushort)((iy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (ix & (INTER_TAB_SIZE-1))); + } + } + else if( m1type == CV_32FC2 && dstm1type == CV_16SC2 ) + { + if( nninterpolate ) + for( x = 0; x < size.width; x++ ) + { + dst1[x*2] = saturate_cast(src1f[x*2]); + dst1[x*2+1] = saturate_cast(src1f[x*2+1]); + } + else + for( x = 0; x < size.width; x++ ) + { + int ix = saturate_cast(src1f[x*2]*INTER_TAB_SIZE); + int iy = saturate_cast(src1f[x*2+1]*INTER_TAB_SIZE); + dst1[x*2] = (short)(ix >> INTER_BITS); + dst1[x*2+1] = (short)(iy >> INTER_BITS); + dst2[x] = (ushort)((iy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (ix & (INTER_TAB_SIZE-1))); + } + } + else if( m1type == CV_16SC2 && dstm1type == CV_32FC1 ) + { + for( x = 0; x < size.width; x++ ) + { + int fxy = src2 ? src2[x] : 0; + dst1f[x] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale; + dst2f[x] = src1[x*2+1] + (fxy >> INTER_BITS)*scale; + } + } + else if( m1type == CV_16SC2 && dstm1type == CV_32FC2 ) + { + for( x = 0; x < size.width; x++ ) + { + int fxy = src2 ? src2[x] : 0; + dst1f[x*2] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale; + dst1f[x*2+1] = src1[x*2+1] + (fxy >> INTER_BITS)*scale; + } + } + else + CV_Error( CV_StsNotImplemented, "Unsupported combination of input/output matrices" ); + } +} + + +namespace cv +{ + +class warpAffineInvoker : + public ParallelLoopBody +{ +public: + warpAffineInvoker(const Mat &_src, Mat &_dst, int _interpolation, int _borderType, + const Scalar &_borderValue, int *_adelta, int *_bdelta, double *_M) : + ParallelLoopBody(), src(_src), dst(_dst), interpolation(_interpolation), + borderType(_borderType), borderValue(_borderValue), adelta(_adelta), bdelta(_bdelta), + M(_M) + { + } + + virtual void operator() (const Range& range) const + { + const int BLOCK_SZ = 64; + short XY[BLOCK_SZ*BLOCK_SZ*2], A[BLOCK_SZ*BLOCK_SZ]; + const int AB_BITS = MAX(10, (int)INTER_BITS); + const int AB_SCALE = 1 << AB_BITS; + int round_delta = interpolation == INTER_NEAREST ? AB_SCALE/2 : AB_SCALE/INTER_TAB_SIZE/2, x, y, x1, y1; + #if CV_SSE2 + bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); + #endif + + int bh0 = std::min(BLOCK_SZ/2, dst.rows); + int bw0 = std::min(BLOCK_SZ*BLOCK_SZ/bh0, dst.cols); + bh0 = std::min(BLOCK_SZ*BLOCK_SZ/bw0, dst.rows); + + for( y = range.start; y < range.end; y += bh0 ) + { + for( x = 0; x < dst.cols; x += bw0 ) + { + int bw = std::min( bw0, dst.cols - x); + int bh = std::min( bh0, range.end - y); + + Mat _XY(bh, bw, CV_16SC2, XY), matA; + Mat dpart(dst, Rect(x, y, bw, bh)); + + for( y1 = 0; y1 < bh; y1++ ) + { + short* xy = XY + y1*bw*2; + int X0 = saturate_cast((M[1]*(y + y1) + M[2])*AB_SCALE) + round_delta; + int Y0 = saturate_cast((M[4]*(y + y1) + M[5])*AB_SCALE) + round_delta; + + if( interpolation == INTER_NEAREST ) + for( x1 = 0; x1 < bw; x1++ ) + { + int X = (X0 + adelta[x+x1]) >> AB_BITS; + int Y = (Y0 + bdelta[x+x1]) >> AB_BITS; + xy[x1*2] = saturate_cast(X); + xy[x1*2+1] = saturate_cast(Y); + } + else + { + short* alpha = A + y1*bw; + x1 = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i fxy_mask = _mm_set1_epi32(INTER_TAB_SIZE - 1); + __m128i XX = _mm_set1_epi32(X0), YY = _mm_set1_epi32(Y0); + for( ; x1 <= bw - 8; x1 += 8 ) + { + __m128i tx0, tx1, ty0, ty1; + tx0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(adelta + x + x1)), XX); + ty0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(bdelta + x + x1)), YY); + tx1 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(adelta + x + x1 + 4)), XX); + ty1 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(bdelta + x + x1 + 4)), YY); + + tx0 = _mm_srai_epi32(tx0, AB_BITS - INTER_BITS); + ty0 = _mm_srai_epi32(ty0, AB_BITS - INTER_BITS); + tx1 = _mm_srai_epi32(tx1, AB_BITS - INTER_BITS); + ty1 = _mm_srai_epi32(ty1, AB_BITS - INTER_BITS); + + __m128i fx_ = _mm_packs_epi32(_mm_and_si128(tx0, fxy_mask), + _mm_and_si128(tx1, fxy_mask)); + __m128i fy_ = _mm_packs_epi32(_mm_and_si128(ty0, fxy_mask), + _mm_and_si128(ty1, fxy_mask)); + tx0 = _mm_packs_epi32(_mm_srai_epi32(tx0, INTER_BITS), + _mm_srai_epi32(tx1, INTER_BITS)); + ty0 = _mm_packs_epi32(_mm_srai_epi32(ty0, INTER_BITS), + _mm_srai_epi32(ty1, INTER_BITS)); + fx_ = _mm_adds_epi16(fx_, _mm_slli_epi16(fy_, INTER_BITS)); + + _mm_storeu_si128((__m128i*)(xy + x1*2), _mm_unpacklo_epi16(tx0, ty0)); + _mm_storeu_si128((__m128i*)(xy + x1*2 + 8), _mm_unpackhi_epi16(tx0, ty0)); + _mm_storeu_si128((__m128i*)(alpha + x1), fx_); + } + } + #endif + for( ; x1 < bw; x1++ ) + { + int X = (X0 + adelta[x+x1]) >> (AB_BITS - INTER_BITS); + int Y = (Y0 + bdelta[x+x1]) >> (AB_BITS - INTER_BITS); + xy[x1*2] = saturate_cast(X >> INTER_BITS); + xy[x1*2+1] = saturate_cast(Y >> INTER_BITS); + alpha[x1] = (short)((Y & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + + (X & (INTER_TAB_SIZE-1))); + } + } + } + + if( interpolation == INTER_NEAREST ) + remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue ); + else + { + Mat _matA(bh, bw, CV_16U, A); + remap( src, dpart, _XY, _matA, interpolation, borderType, borderValue ); + } + } + } + } + +private: + Mat src; + Mat dst; + int interpolation, borderType; + Scalar borderValue; + int *adelta, *bdelta; + double *M; +}; + +} + + +void cv::warpAffine( InputArray _src, OutputArray _dst, + InputArray _M0, Size dsize, + int flags, int borderType, const Scalar& borderValue ) +{ + Mat src = _src.getMat(), M0 = _M0.getMat(); + _dst.create( dsize.area() == 0 ? src.size() : dsize, src.type() ); + Mat dst = _dst.getMat(); + CV_Assert( src.cols > 0 && src.rows > 0 ); + if( dst.data == src.data ) + src = src.clone(); + + double M[6]; + Mat matM(2, 3, CV_64F, M); + int interpolation = flags & INTER_MAX; + if( interpolation == INTER_AREA ) + interpolation = INTER_LINEAR; + + CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3 ); + M0.convertTo(matM, matM.type()); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if( tegra::warpAffine(src, dst, M, flags, borderType, borderValue) ) + return; +#endif + + if( !(flags & WARP_INVERSE_MAP) ) + { + double D = M[0]*M[4] - M[1]*M[3]; + D = D != 0 ? 1./D : 0; + double A11 = M[4]*D, A22=M[0]*D; + M[0] = A11; M[1] *= -D; + M[3] *= -D; M[4] = A22; + double b1 = -M[0]*M[2] - M[1]*M[5]; + double b2 = -M[3]*M[2] - M[4]*M[5]; + M[2] = b1; M[5] = b2; + } + + int x; + AutoBuffer _abdelta(dst.cols*2); + int* adelta = &_abdelta[0], *bdelta = adelta + dst.cols; + const int AB_BITS = MAX(10, (int)INTER_BITS); + const int AB_SCALE = 1 << AB_BITS; + + for( x = 0; x < dst.cols; x++ ) + { + adelta[x] = saturate_cast(M[0]*x*AB_SCALE); + bdelta[x] = saturate_cast(M[3]*x*AB_SCALE); + } + + Range range(0, dst.rows); + warpAffineInvoker invoker(src, dst, interpolation, borderType, + borderValue, adelta, bdelta, M); + parallel_for_(range, invoker, dst.total()/(double)(1<<16)); +} + + +namespace cv +{ + +class warpPerspectiveInvoker : + public ParallelLoopBody +{ +public: + + warpPerspectiveInvoker(const Mat &_src, Mat &_dst, double *_M, int _interpolation, + int _borderType, const Scalar &_borderValue) : + ParallelLoopBody(), src(_src), dst(_dst), M(_M), interpolation(_interpolation), + borderType(_borderType), borderValue(_borderValue) + { + } + + virtual void operator() (const Range& range) const + { + const int BLOCK_SZ = 32; + short XY[BLOCK_SZ*BLOCK_SZ*2], A[BLOCK_SZ*BLOCK_SZ]; + int x, y, x1, y1, width = dst.cols, height = dst.rows; + + int bh0 = std::min(BLOCK_SZ/2, height); + int bw0 = std::min(BLOCK_SZ*BLOCK_SZ/bh0, width); + bh0 = std::min(BLOCK_SZ*BLOCK_SZ/bw0, height); + + for( y = range.start; y < range.end; y += bh0 ) + { + for( x = 0; x < width; x += bw0 ) + { + int bw = std::min( bw0, width - x); + int bh = std::min( bh0, range.end - y); // height + + Mat _XY(bh, bw, CV_16SC2, XY), matA; + Mat dpart(dst, Rect(x, y, bw, bh)); + + for( y1 = 0; y1 < bh; y1++ ) + { + short* xy = XY + y1*bw*2; + double X0 = M[0]*x + M[1]*(y + y1) + M[2]; + double Y0 = M[3]*x + M[4]*(y + y1) + M[5]; + double W0 = M[6]*x + M[7]*(y + y1) + M[8]; + + if( interpolation == INTER_NEAREST ) + for( x1 = 0; x1 < bw; x1++ ) + { + double W = W0 + M[6]*x1; + W = W ? 1./W : 0; + double fX = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0]*x1)*W)); + double fY = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3]*x1)*W)); + int X = saturate_cast(fX); + int Y = saturate_cast(fY); + + xy[x1*2] = saturate_cast(X); + xy[x1*2+1] = saturate_cast(Y); + } + else + { + short* alpha = A + y1*bw; + for( x1 = 0; x1 < bw; x1++ ) + { + double W = W0 + M[6]*x1; + W = W ? INTER_TAB_SIZE/W : 0; + double fX = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0]*x1)*W)); + double fY = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3]*x1)*W)); + int X = saturate_cast(fX); + int Y = saturate_cast(fY); + + xy[x1*2] = saturate_cast(X >> INTER_BITS); + xy[x1*2+1] = saturate_cast(Y >> INTER_BITS); + alpha[x1] = (short)((Y & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + + (X & (INTER_TAB_SIZE-1))); + } + } + } + + if( interpolation == INTER_NEAREST ) + remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue ); + else + { + Mat _matA(bh, bw, CV_16U, A); + remap( src, dpart, _XY, _matA, interpolation, borderType, borderValue ); + } + } + } + } + +private: + Mat src; + Mat dst; + double* M; + int interpolation, borderType; + Scalar borderValue; +}; + +} + +void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0, + Size dsize, int flags, int borderType, const Scalar& borderValue ) +{ + Mat src = _src.getMat(), M0 = _M0.getMat(); + _dst.create( dsize.area() == 0 ? src.size() : dsize, src.type() ); + Mat dst = _dst.getMat(); + + CV_Assert( src.cols > 0 && src.rows > 0 ); + if( dst.data == src.data ) + src = src.clone(); + + double M[9]; + Mat matM(3, 3, CV_64F, M); + int interpolation = flags & INTER_MAX; + if( interpolation == INTER_AREA ) + interpolation = INTER_LINEAR; + + CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 3 && M0.cols == 3 ); + M0.convertTo(matM, matM.type()); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if( tegra::warpPerspective(src, dst, M, flags, borderType, borderValue) ) + return; +#endif + + if( !(flags & WARP_INVERSE_MAP) ) + invert(matM, matM); + + Range range(0, dst.rows); + warpPerspectiveInvoker invoker(src, dst, M, interpolation, borderType, borderValue); + parallel_for_(range, invoker, dst.total()/(double)(1<<16)); +} + + +cv::Mat cv::getRotationMatrix2D( Point2f center, double angle, double scale ) +{ + angle *= CV_PI/180; + double alpha = cos(angle)*scale; + double beta = sin(angle)*scale; + + Mat M(2, 3, CV_64F); + double* m = (double*)M.data; + + m[0] = alpha; + m[1] = beta; + m[2] = (1-alpha)*center.x - beta*center.y; + m[3] = -beta; + m[4] = alpha; + m[5] = beta*center.x + (1-alpha)*center.y; + + return M; +} + +/* Calculates coefficients of perspective transformation + * which maps (xi,yi) to (ui,vi), (i=1,2,3,4): + * + * c00*xi + c01*yi + c02 + * ui = --------------------- + * c20*xi + c21*yi + c22 + * + * c10*xi + c11*yi + c12 + * vi = --------------------- + * c20*xi + c21*yi + c22 + * + * Coefficients are calculated by solving linear system: + * / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\ + * | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1| + * | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2| + * | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|, + * | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0| + * | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1| + * | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2| + * \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/ + * + * where: + * cij - matrix coefficients, c22 = 1 + */ +cv::Mat cv::getPerspectiveTransform( const Point2f src[], const Point2f dst[] ) +{ + Mat M(3, 3, CV_64F), X(8, 1, CV_64F, M.data); + double a[8][8], b[8]; + Mat A(8, 8, CV_64F, a), B(8, 1, CV_64F, b); + + for( int i = 0; i < 4; ++i ) + { + a[i][0] = a[i+4][3] = src[i].x; + a[i][1] = a[i+4][4] = src[i].y; + a[i][2] = a[i+4][5] = 1; + a[i][3] = a[i][4] = a[i][5] = + a[i+4][0] = a[i+4][1] = a[i+4][2] = 0; + a[i][6] = -src[i].x*dst[i].x; + a[i][7] = -src[i].y*dst[i].x; + a[i+4][6] = -src[i].x*dst[i].y; + a[i+4][7] = -src[i].y*dst[i].y; + b[i] = dst[i].x; + b[i+4] = dst[i].y; + } + + solve( A, B, X, DECOMP_SVD ); + ((double*)M.data)[8] = 1.; + + return M; +} + +/* Calculates coefficients of affine transformation + * which maps (xi,yi) to (ui,vi), (i=1,2,3): + * + * ui = c00*xi + c01*yi + c02 + * + * vi = c10*xi + c11*yi + c12 + * + * Coefficients are calculated by solving linear system: + * / x0 y0 1 0 0 0 \ /c00\ /u0\ + * | x1 y1 1 0 0 0 | |c01| |u1| + * | x2 y2 1 0 0 0 | |c02| |u2| + * | 0 0 0 x0 y0 1 | |c10| |v0| + * | 0 0 0 x1 y1 1 | |c11| |v1| + * \ 0 0 0 x2 y2 1 / |c12| |v2| + * + * where: + * cij - matrix coefficients + */ + +cv::Mat cv::getAffineTransform( const Point2f src[], const Point2f dst[] ) +{ + Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.data); + double a[6*6], b[6]; + Mat A(6, 6, CV_64F, a), B(6, 1, CV_64F, b); + + for( int i = 0; i < 3; i++ ) + { + int j = i*12; + int k = i*12+6; + a[j] = a[k+3] = src[i].x; + a[j+1] = a[k+4] = src[i].y; + a[j+2] = a[k+5] = 1; + a[j+3] = a[j+4] = a[j+5] = 0; + a[k] = a[k+1] = a[k+2] = 0; + b[i*2] = dst[i].x; + b[i*2+1] = dst[i].y; + } + + solve( A, B, X ); + return M; +} + +void cv::invertAffineTransform(InputArray _matM, OutputArray __iM) +{ + Mat matM = _matM.getMat(); + CV_Assert(matM.rows == 2 && matM.cols == 3); + __iM.create(2, 3, matM.type()); + Mat _iM = __iM.getMat(); + + if( matM.type() == CV_32F ) + { + const float* M = (const float*)matM.data; + float* iM = (float*)_iM.data; + int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0])); + + double D = M[0]*M[step+1] - M[1]*M[step]; + D = D != 0 ? 1./D : 0; + double A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D; + double b1 = -A11*M[2] - A12*M[step+2]; + double b2 = -A21*M[2] - A22*M[step+2]; + + iM[0] = (float)A11; iM[1] = (float)A12; iM[2] = (float)b1; + iM[istep] = (float)A21; iM[istep+1] = (float)A22; iM[istep+2] = (float)b2; + } + else if( matM.type() == CV_64F ) + { + const double* M = (const double*)matM.data; + double* iM = (double*)_iM.data; + int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0])); + + double D = M[0]*M[step+1] - M[1]*M[step]; + D = D != 0 ? 1./D : 0; + double A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D; + double b1 = -A11*M[2] - A12*M[step+2]; + double b2 = -A21*M[2] - A22*M[step+2]; + + iM[0] = A11; iM[1] = A12; iM[2] = b1; + iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2; + } + else + CV_Error( CV_StsUnsupportedFormat, "" ); +} + +cv::Mat cv::getPerspectiveTransform(InputArray _src, InputArray _dst) +{ + Mat src = _src.getMat(), dst = _dst.getMat(); + CV_Assert(src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4); + return getPerspectiveTransform((const Point2f*)src.data, (const Point2f*)dst.data); +} + +cv::Mat cv::getAffineTransform(InputArray _src, InputArray _dst) +{ + Mat src = _src.getMat(), dst = _dst.getMat(); + CV_Assert(src.checkVector(2, CV_32F) == 3 && dst.checkVector(2, CV_32F) == 3); + return getAffineTransform((const Point2f*)src.data, (const Point2f*)dst.data); +} + +CV_IMPL void +cvResize( const CvArr* srcarr, CvArr* dstarr, int method ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + CV_Assert( src.type() == dst.type() ); + cv::resize( src, dst, dst.size(), (double)dst.cols/src.cols, + (double)dst.rows/src.rows, method ); +} + + +CV_IMPL void +cvWarpAffine( const CvArr* srcarr, CvArr* dstarr, const CvMat* marr, + int flags, CvScalar fillval ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + cv::Mat matrix = cv::cvarrToMat(marr); + CV_Assert( src.type() == dst.type() ); + cv::warpAffine( src, dst, matrix, dst.size(), flags, + (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + fillval ); +} + +CV_IMPL void +cvWarpPerspective( const CvArr* srcarr, CvArr* dstarr, const CvMat* marr, + int flags, CvScalar fillval ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + cv::Mat matrix = cv::cvarrToMat(marr); + CV_Assert( src.type() == dst.type() ); + cv::warpPerspective( src, dst, matrix, dst.size(), flags, + (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + fillval ); +} + +CV_IMPL void +cvRemap( const CvArr* srcarr, CvArr* dstarr, + const CvArr* _mapx, const CvArr* _mapy, + int flags, CvScalar fillval ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), dst0 = dst; + cv::Mat mapx = cv::cvarrToMat(_mapx), mapy = cv::cvarrToMat(_mapy); + CV_Assert( src.type() == dst.type() && dst.size() == mapx.size() ); + cv::remap( src, dst, mapx, mapy, flags & cv::INTER_MAX, + (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + fillval ); + CV_Assert( dst0.data == dst.data ); +} + + +CV_IMPL CvMat* +cv2DRotationMatrix( CvPoint2D32f center, double angle, + double scale, CvMat* matrix ) +{ + cv::Mat M0 = cv::cvarrToMat(matrix), M = cv::getRotationMatrix2D(center, angle, scale); + CV_Assert( M.size() == M0.size() ); + M.convertTo(M0, M0.type()); + return matrix; +} + + +CV_IMPL CvMat* +cvGetPerspectiveTransform( const CvPoint2D32f* src, + const CvPoint2D32f* dst, + CvMat* matrix ) +{ + cv::Mat M0 = cv::cvarrToMat(matrix), + M = cv::getPerspectiveTransform((const cv::Point2f*)src, (const cv::Point2f*)dst); + CV_Assert( M.size() == M0.size() ); + M.convertTo(M0, M0.type()); + return matrix; +} + + +CV_IMPL CvMat* +cvGetAffineTransform( const CvPoint2D32f* src, + const CvPoint2D32f* dst, + CvMat* matrix ) +{ + cv::Mat M0 = cv::cvarrToMat(matrix), + M = cv::getAffineTransform((const cv::Point2f*)src, (const cv::Point2f*)dst); + CV_Assert( M.size() == M0.size() ); + M.convertTo(M0, M0.type()); + return matrix; +} + + +CV_IMPL void +cvConvertMaps( const CvArr* arr1, const CvArr* arr2, CvArr* dstarr1, CvArr* dstarr2 ) +{ + cv::Mat map1 = cv::cvarrToMat(arr1), map2; + cv::Mat dstmap1 = cv::cvarrToMat(dstarr1), dstmap2; + + if( arr2 ) + map2 = cv::cvarrToMat(arr2); + if( dstarr2 ) + { + dstmap2 = cv::cvarrToMat(dstarr2); + if( dstmap2.type() == CV_16SC1 ) + dstmap2 = cv::Mat(dstmap2.size(), CV_16UC1, dstmap2.data, dstmap2.step); + } + + cv::convertMaps( map1, map2, dstmap1, dstmap2, dstmap1.type(), false ); +} + +/****************************************************************************************\ +* Log-Polar Transform * +\****************************************************************************************/ + +/* now it is done via Remap; more correct implementation should use + some super-sampling technique outside of the "fovea" circle */ +CV_IMPL void +cvLogPolar( const CvArr* srcarr, CvArr* dstarr, + CvPoint2D32f center, double M, int flags ) +{ + cv::Ptr mapx, mapy; + + CvMat srcstub, *src = cvGetMat(srcarr, &srcstub); + CvMat dststub, *dst = cvGetMat(dstarr, &dststub); + CvSize ssize, dsize; + + if( !CV_ARE_TYPES_EQ( src, dst )) + CV_Error( CV_StsUnmatchedFormats, "" ); + + if( M <= 0 ) + CV_Error( CV_StsOutOfRange, "M should be >0" ); + + ssize = cvGetMatSize(src); + dsize = cvGetMatSize(dst); + + mapx = cvCreateMat( dsize.height, dsize.width, CV_32F ); + mapy = cvCreateMat( dsize.height, dsize.width, CV_32F ); + + if( !(flags & CV_WARP_INVERSE_MAP) ) + { + int phi, rho; + cv::AutoBuffer _exp_tab(dsize.width); + double* exp_tab = _exp_tab; + + for( rho = 0; rho < dst->width; rho++ ) + exp_tab[rho] = std::exp(rho/M); + + for( phi = 0; phi < dsize.height; phi++ ) + { + double cp = cos(phi*2*CV_PI/dsize.height); + double sp = sin(phi*2*CV_PI/dsize.height); + float* mx = (float*)(mapx->data.ptr + phi*mapx->step); + float* my = (float*)(mapy->data.ptr + phi*mapy->step); + + for( rho = 0; rho < dsize.width; rho++ ) + { + double r = exp_tab[rho]; + double x = r*cp + center.x; + double y = r*sp + center.y; + + mx[rho] = (float)x; + my[rho] = (float)y; + } + } + } + else + { + int x, y; + CvMat bufx, bufy, bufp, bufa; + double ascale = ssize.height/(2*CV_PI); + cv::AutoBuffer _buf(4*dsize.width); + float* buf = _buf; + + bufx = cvMat( 1, dsize.width, CV_32F, buf ); + bufy = cvMat( 1, dsize.width, CV_32F, buf + dsize.width ); + bufp = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*2 ); + bufa = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*3 ); + + for( x = 0; x < dsize.width; x++ ) + bufx.data.fl[x] = (float)x - center.x; + + for( y = 0; y < dsize.height; y++ ) + { + float* mx = (float*)(mapx->data.ptr + y*mapx->step); + float* my = (float*)(mapy->data.ptr + y*mapy->step); + + for( x = 0; x < dsize.width; x++ ) + bufy.data.fl[x] = (float)y - center.y; + +#if 1 + cvCartToPolar( &bufx, &bufy, &bufp, &bufa ); + + for( x = 0; x < dsize.width; x++ ) + bufp.data.fl[x] += 1.f; + + cvLog( &bufp, &bufp ); + + for( x = 0; x < dsize.width; x++ ) + { + double rho = bufp.data.fl[x]*M; + double phi = bufa.data.fl[x]*ascale; + + mx[x] = (float)rho; + my[x] = (float)phi; + } +#else + for( x = 0; x < dsize.width; x++ ) + { + double xx = bufx.data.fl[x]; + double yy = bufy.data.fl[x]; + + double p = log(sqrt(xx*xx + yy*yy) + 1.)*M; + double a = atan2(yy,xx); + if( a < 0 ) + a = 2*CV_PI + a; + a *= ascale; + + mx[x] = (float)p; + my[x] = (float)a; + } +#endif + } + } + + cvRemap( src, dst, mapx, mapy, flags, cvScalarAll(0) ); +} + + +/**************************************************************************************** + Linear-Polar Transform + J.L. Blanco, Apr 2009 + ****************************************************************************************/ +CV_IMPL +void cvLinearPolar( const CvArr* srcarr, CvArr* dstarr, + CvPoint2D32f center, double maxRadius, int flags ) +{ + cv::Ptr mapx, mapy; + + CvMat srcstub, *src = (CvMat*)srcarr; + CvMat dststub, *dst = (CvMat*)dstarr; + CvSize ssize, dsize; + + src = cvGetMat( srcarr, &srcstub,0,0 ); + dst = cvGetMat( dstarr, &dststub,0,0 ); + + if( !CV_ARE_TYPES_EQ( src, dst )) + CV_Error( CV_StsUnmatchedFormats, "" ); + + ssize.width = src->cols; + ssize.height = src->rows; + dsize.width = dst->cols; + dsize.height = dst->rows; + + mapx = cvCreateMat( dsize.height, dsize.width, CV_32F ); + mapy = cvCreateMat( dsize.height, dsize.width, CV_32F ); + + if( !(flags & CV_WARP_INVERSE_MAP) ) + { + int phi, rho; + + for( phi = 0; phi < dsize.height; phi++ ) + { + double cp = cos(phi*2*CV_PI/dsize.height); + double sp = sin(phi*2*CV_PI/dsize.height); + float* mx = (float*)(mapx->data.ptr + phi*mapx->step); + float* my = (float*)(mapy->data.ptr + phi*mapy->step); + + for( rho = 0; rho < dsize.width; rho++ ) + { + double r = maxRadius*(rho+1)/dsize.width; + double x = r*cp + center.x; + double y = r*sp + center.y; + + mx[rho] = (float)x; + my[rho] = (float)y; + } + } + } + else + { + int x, y; + CvMat bufx, bufy, bufp, bufa; + const double ascale = ssize.height/(2*CV_PI); + const double pscale = ssize.width/maxRadius; + + cv::AutoBuffer _buf(4*dsize.width); + float* buf = _buf; + + bufx = cvMat( 1, dsize.width, CV_32F, buf ); + bufy = cvMat( 1, dsize.width, CV_32F, buf + dsize.width ); + bufp = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*2 ); + bufa = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*3 ); + + for( x = 0; x < dsize.width; x++ ) + bufx.data.fl[x] = (float)x - center.x; + + for( y = 0; y < dsize.height; y++ ) + { + float* mx = (float*)(mapx->data.ptr + y*mapx->step); + float* my = (float*)(mapy->data.ptr + y*mapy->step); + + for( x = 0; x < dsize.width; x++ ) + bufy.data.fl[x] = (float)y - center.y; + + cvCartToPolar( &bufx, &bufy, &bufp, &bufa, 0 ); + + for( x = 0; x < dsize.width; x++ ) + bufp.data.fl[x] += 1.f; + + for( x = 0; x < dsize.width; x++ ) + { + double rho = bufp.data.fl[x]*pscale; + double phi = bufa.data.fl[x]*ascale; + mx[x] = (float)rho; + my[x] = (float)phi; + } + } + } + + cvRemap( src, dst, mapx, mapy, flags, cvScalarAll(0) ); +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/linefit.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/linefit.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/linefit.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/linefit.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,719 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +static const double eps = 1e-6; + +static CvStatus +icvFitLine2D_wods( CvPoint2D32f * points, int _count, float *weights, float *line ) +{ + double x = 0, y = 0, x2 = 0, y2 = 0, xy = 0, w = 0; + double dx2, dy2, dxy; + int i; + int count = _count; + float t; + + /* Calculating the average of x and y... */ + + if( weights == 0 ) + { + for( i = 0; i < count; i += 1 ) + { + x += points[i].x; + y += points[i].y; + x2 += points[i].x * points[i].x; + y2 += points[i].y * points[i].y; + xy += points[i].x * points[i].y; + } + w = (float) count; + } + else + { + for( i = 0; i < count; i += 1 ) + { + x += weights[i] * points[i].x; + y += weights[i] * points[i].y; + x2 += weights[i] * points[i].x * points[i].x; + y2 += weights[i] * points[i].y * points[i].y; + xy += weights[i] * points[i].x * points[i].y; + w += weights[i]; + } + } + + x /= w; + y /= w; + x2 /= w; + y2 /= w; + xy /= w; + + dx2 = x2 - x * x; + dy2 = y2 - y * y; + dxy = xy - x * y; + + t = (float) atan2( 2 * dxy, dx2 - dy2 ) / 2; + line[0] = (float) cos( t ); + line[1] = (float) sin( t ); + + line[2] = (float) x; + line[3] = (float) y; + + return CV_NO_ERR; +} + +static CvStatus +icvFitLine3D_wods( CvPoint3D32f * points, int count, float *weights, float *line ) +{ + int i; + float w0 = 0; + float x0 = 0, y0 = 0, z0 = 0; + float x2 = 0, y2 = 0, z2 = 0, xy = 0, yz = 0, xz = 0; + float dx2, dy2, dz2, dxy, dxz, dyz; + float *v; + float n; + float det[9], evc[9], evl[3]; + + memset( evl, 0, 3*sizeof(evl[0])); + memset( evc, 0, 9*sizeof(evl[0])); + + if( weights ) + { + for( i = 0; i < count; i++ ) + { + float x = points[i].x; + float y = points[i].y; + float z = points[i].z; + float w = weights[i]; + + + x2 += x * x * w; + xy += x * y * w; + xz += x * z * w; + y2 += y * y * w; + yz += y * z * w; + z2 += z * z * w; + x0 += x * w; + y0 += y * w; + z0 += z * w; + w0 += w; + } + } + else + { + for( i = 0; i < count; i++ ) + { + float x = points[i].x; + float y = points[i].y; + float z = points[i].z; + + x2 += x * x; + xy += x * y; + xz += x * z; + y2 += y * y; + yz += y * z; + z2 += z * z; + x0 += x; + y0 += y; + z0 += z; + } + w0 = (float) count; + } + + x2 /= w0; + xy /= w0; + xz /= w0; + y2 /= w0; + yz /= w0; + z2 /= w0; + + x0 /= w0; + y0 /= w0; + z0 /= w0; + + dx2 = x2 - x0 * x0; + dxy = xy - x0 * y0; + dxz = xz - x0 * z0; + dy2 = y2 - y0 * y0; + dyz = yz - y0 * z0; + dz2 = z2 - z0 * z0; + + det[0] = dz2 + dy2; + det[1] = -dxy; + det[2] = -dxz; + det[3] = det[1]; + det[4] = dx2 + dz2; + det[5] = -dyz; + det[6] = det[2]; + det[7] = det[5]; + det[8] = dy2 + dx2; + + /* Searching for a eigenvector of det corresponding to the minimal eigenvalue */ +#if 1 + { + CvMat _det = cvMat( 3, 3, CV_32F, det ); + CvMat _evc = cvMat( 3, 3, CV_32F, evc ); + CvMat _evl = cvMat( 3, 1, CV_32F, evl ); + cvEigenVV( &_det, &_evc, &_evl, 0 ); + i = evl[0] < evl[1] ? (evl[0] < evl[2] ? 0 : 2) : (evl[1] < evl[2] ? 1 : 2); + } +#else + { + CvMat _det = cvMat( 3, 3, CV_32F, det ); + CvMat _evc = cvMat( 3, 3, CV_32F, evc ); + CvMat _evl = cvMat( 1, 3, CV_32F, evl ); + + cvSVD( &_det, &_evl, &_evc, 0, CV_SVD_MODIFY_A+CV_SVD_U_T ); + } + i = 2; +#endif + v = &evc[i * 3]; + n = (float) sqrt( (double)v[0] * v[0] + (double)v[1] * v[1] + (double)v[2] * v[2] ); + n = (float)MAX(n, eps); + line[0] = v[0] / n; + line[1] = v[1] / n; + line[2] = v[2] / n; + line[3] = x0; + line[4] = y0; + line[5] = z0; + + return CV_NO_ERR; +} + +static double +icvCalcDist2D( CvPoint2D32f * points, int count, float *_line, float *dist ) +{ + int j; + float px = _line[2], py = _line[3]; + float nx = _line[1], ny = -_line[0]; + double sum_dist = 0.; + + for( j = 0; j < count; j++ ) + { + float x, y; + + x = points[j].x - px; + y = points[j].y - py; + + dist[j] = (float) fabs( nx * x + ny * y ); + sum_dist += dist[j]; + } + + return sum_dist; +} + +static double +icvCalcDist3D( CvPoint3D32f * points, int count, float *_line, float *dist ) +{ + int j; + float px = _line[3], py = _line[4], pz = _line[5]; + float vx = _line[0], vy = _line[1], vz = _line[2]; + double sum_dist = 0.; + + for( j = 0; j < count; j++ ) + { + float x, y, z; + double p1, p2, p3; + + x = points[j].x - px; + y = points[j].y - py; + z = points[j].z - pz; + + p1 = vy * z - vz * y; + p2 = vz * x - vx * z; + p3 = vx * y - vy * x; + + dist[j] = (float) sqrt( p1*p1 + p2*p2 + p3*p3 ); + sum_dist += dist[j]; + } + + return sum_dist; +} + +static void +icvWeightL1( float *d, int count, float *w ) +{ + int i; + + for( i = 0; i < count; i++ ) + { + double t = fabs( (double) d[i] ); + w[i] = (float)(1. / MAX(t, eps)); + } +} + +static void +icvWeightL12( float *d, int count, float *w ) +{ + int i; + + for( i = 0; i < count; i++ ) + { + w[i] = 1.0f / (float) sqrt( 1 + (double) (d[i] * d[i] * 0.5) ); + } +} + + +static void +icvWeightHuber( float *d, int count, float *w, float _c ) +{ + int i; + const float c = _c <= 0 ? 1.345f : _c; + + for( i = 0; i < count; i++ ) + { + if( d[i] < c ) + w[i] = 1.0f; + else + w[i] = c/d[i]; + } +} + + +static void +icvWeightFair( float *d, int count, float *w, float _c ) +{ + int i; + const float c = _c == 0 ? 1 / 1.3998f : 1 / _c; + + for( i = 0; i < count; i++ ) + { + w[i] = 1 / (1 + d[i] * c); + } +} + +static void +icvWeightWelsch( float *d, int count, float *w, float _c ) +{ + int i; + const float c = _c == 0 ? 1 / 2.9846f : 1 / _c; + + for( i = 0; i < count; i++ ) + { + w[i] = (float) exp( -d[i] * d[i] * c * c ); + } +} + + +/* Takes an array of 2D points, type of distance (including user-defined +distance specified by callbacks, fills the array of four floats with line +parameters A, B, C, D, where (A, B) is the normalized direction vector, +(C, D) is the point that belongs to the line. */ + +static CvStatus icvFitLine2D( CvPoint2D32f * points, int count, int dist, + float _param, float reps, float aeps, float *line ) +{ + double EPS = count*FLT_EPSILON; + void (*calc_weights) (float *, int, float *) = 0; + void (*calc_weights_param) (float *, int, float *, float) = 0; + float *w; /* weights */ + float *r; /* square distances */ + int i, j, k; + float _line[6], _lineprev[6]; + float rdelta = reps != 0 ? reps : 1.0f; + float adelta = aeps != 0 ? aeps : 0.01f; + double min_err = DBL_MAX, err = 0; + CvRNG rng = cvRNG(-1); + + memset( line, 0, 4*sizeof(line[0]) ); + + switch (dist) + { + case CV_DIST_L2: + return icvFitLine2D_wods( points, count, 0, line ); + + case CV_DIST_L1: + calc_weights = icvWeightL1; + break; + + case CV_DIST_L12: + calc_weights = icvWeightL12; + break; + + case CV_DIST_FAIR: + calc_weights_param = icvWeightFair; + break; + + case CV_DIST_WELSCH: + calc_weights_param = icvWeightWelsch; + break; + + case CV_DIST_HUBER: + calc_weights_param = icvWeightHuber; + break; + + /*case CV_DIST_USER: + calc_weights = (void ( * )(float *, int, float *)) _PFP.fp; + break;*/ + + default: + return CV_BADFACTOR_ERR; + } + + w = (float *) cvAlloc( count * sizeof( float )); + r = (float *) cvAlloc( count * sizeof( float )); + + for( k = 0; k < 20; k++ ) + { + int first = 1; + for( i = 0; i < count; i++ ) + w[i] = 0.f; + + for( i = 0; i < MIN(count,10); ) + { + j = cvRandInt(&rng) % count; + if( w[j] < FLT_EPSILON ) + { + w[j] = 1.f; + i++; + } + } + + icvFitLine2D_wods( points, count, w, _line ); + for( i = 0; i < 30; i++ ) + { + double sum_w = 0; + + if( first ) + { + first = 0; + } + else + { + double t = _line[0] * _lineprev[0] + _line[1] * _lineprev[1]; + t = MAX(t,-1.); + t = MIN(t,1.); + if( fabs(acos(t)) < adelta ) + { + float x, y, d; + + x = (float) fabs( _line[2] - _lineprev[2] ); + y = (float) fabs( _line[3] - _lineprev[3] ); + + d = x > y ? x : y; + if( d < rdelta ) + break; + } + } + /* calculate distances */ + err = icvCalcDist2D( points, count, _line, r ); + if( err < EPS ) + break; + + /* calculate weights */ + if( calc_weights ) + calc_weights( r, count, w ); + else + calc_weights_param( r, count, w, _param ); + + for( j = 0; j < count; j++ ) + sum_w += w[j]; + + if( fabs(sum_w) > FLT_EPSILON ) + { + sum_w = 1./sum_w; + for( j = 0; j < count; j++ ) + w[j] = (float)(w[j]*sum_w); + } + else + { + for( j = 0; j < count; j++ ) + w[j] = 1.f; + } + + /* save the line parameters */ + memcpy( _lineprev, _line, 4 * sizeof( float )); + + /* Run again... */ + icvFitLine2D_wods( points, count, w, _line ); + } + + if( err < min_err ) + { + min_err = err; + memcpy( line, _line, 4 * sizeof(line[0])); + if( err < EPS ) + break; + } + } + + cvFree( &w ); + cvFree( &r ); + return CV_OK; +} + + +/* Takes an array of 3D points, type of distance (including user-defined +distance specified by callbacks, fills the array of four floats with line +parameters A, B, C, D, E, F, where (A, B, C) is the normalized direction vector, +(D, E, F) is the point that belongs to the line. */ + +static CvStatus +icvFitLine3D( CvPoint3D32f * points, int count, int dist, + float _param, float reps, float aeps, float *line ) +{ + double EPS = count*FLT_EPSILON; + void (*calc_weights) (float *, int, float *) = 0; + void (*calc_weights_param) (float *, int, float *, float) = 0; + float *w; /* weights */ + float *r; /* square distances */ + int i, j, k; + float _line[6]={0,0,0,0,0,0}, _lineprev[6]={0,0,0,0,0,0}; + float rdelta = reps != 0 ? reps : 1.0f; + float adelta = aeps != 0 ? aeps : 0.01f; + double min_err = DBL_MAX, err = 0; + CvRNG rng = cvRNG(-1); + + switch (dist) + { + case CV_DIST_L2: + return icvFitLine3D_wods( points, count, 0, line ); + + case CV_DIST_L1: + calc_weights = icvWeightL1; + break; + + case CV_DIST_L12: + calc_weights = icvWeightL12; + break; + + case CV_DIST_FAIR: + calc_weights_param = icvWeightFair; + break; + + case CV_DIST_WELSCH: + calc_weights_param = icvWeightWelsch; + break; + + case CV_DIST_HUBER: + calc_weights_param = icvWeightHuber; + break; + + /*case CV_DIST_USER: + _PFP.p = param; + calc_weights = (void ( * )(float *, int, float *)) _PFP.fp; + break;*/ + + default: + return CV_BADFACTOR_ERR; + } + + w = (float *) cvAlloc( count * sizeof( float )); + r = (float *) cvAlloc( count * sizeof( float )); + + for( k = 0; k < 20; k++ ) + { + int first = 1; + for( i = 0; i < count; i++ ) + w[i] = 0.f; + + for( i = 0; i < MIN(count,10); ) + { + j = cvRandInt(&rng) % count; + if( w[j] < FLT_EPSILON ) + { + w[j] = 1.f; + i++; + } + } + + icvFitLine3D_wods( points, count, w, _line ); + for( i = 0; i < 30; i++ ) + { + double sum_w = 0; + + if( first ) + { + first = 0; + } + else + { + double t = _line[0] * _lineprev[0] + _line[1] * _lineprev[1] + _line[2] * _lineprev[2]; + t = MAX(t,-1.); + t = MIN(t,1.); + if( fabs(acos(t)) < adelta ) + { + float x, y, z, ax, ay, az, dx, dy, dz, d; + + x = _line[3] - _lineprev[3]; + y = _line[4] - _lineprev[4]; + z = _line[5] - _lineprev[5]; + ax = _line[0] - _lineprev[0]; + ay = _line[1] - _lineprev[1]; + az = _line[2] - _lineprev[2]; + dx = (float) fabs( y * az - z * ay ); + dy = (float) fabs( z * ax - x * az ); + dz = (float) fabs( x * ay - y * ax ); + + d = dx > dy ? (dx > dz ? dx : dz) : (dy > dz ? dy : dz); + if( d < rdelta ) + break; + } + } + /* calculate distances */ + if( icvCalcDist3D( points, count, _line, r ) < FLT_EPSILON*count ) + break; + + /* calculate weights */ + if( calc_weights ) + calc_weights( r, count, w ); + else + calc_weights_param( r, count, w, _param ); + + for( j = 0; j < count; j++ ) + sum_w += w[j]; + + if( fabs(sum_w) > FLT_EPSILON ) + { + sum_w = 1./sum_w; + for( j = 0; j < count; j++ ) + w[j] = (float)(w[j]*sum_w); + } + else + { + for( j = 0; j < count; j++ ) + w[j] = 1.f; + } + + /* save the line parameters */ + memcpy( _lineprev, _line, 6 * sizeof( float )); + + /* Run again... */ + icvFitLine3D_wods( points, count, w, _line ); + } + + if( err < min_err ) + { + min_err = err; + memcpy( line, _line, 6 * sizeof(line[0])); + if( err < EPS ) + break; + } + } + + // Return... + cvFree( &w ); + cvFree( &r ); + return CV_OK; +} + + +CV_IMPL void +cvFitLine( const CvArr* array, int dist, double param, + double reps, double aeps, float *line ) +{ + cv::AutoBuffer buffer; + + schar* points = 0; + union { CvContour contour; CvSeq seq; } header; + CvSeqBlock block; + CvSeq* ptseq = (CvSeq*)array; + int type; + + if( !line ) + CV_Error( CV_StsNullPtr, "NULL pointer to line parameters" ); + + if( CV_IS_SEQ(ptseq) ) + { + type = CV_SEQ_ELTYPE(ptseq); + if( ptseq->total == 0 ) + CV_Error( CV_StsBadSize, "The sequence has no points" ); + if( (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) || + CV_ELEM_SIZE(type) != ptseq->elem_size ) + CV_Error( CV_StsUnsupportedFormat, + "Input sequence must consist of 2d points or 3d points" ); + } + else + { + CvMat* mat = (CvMat*)array; + type = CV_MAT_TYPE(mat->type); + if( !CV_IS_MAT(mat)) + CV_Error( CV_StsBadArg, "Input array is not a sequence nor matrix" ); + + if( !CV_IS_MAT_CONT(mat->type) || + (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) || + (mat->width != 1 && mat->height != 1)) + CV_Error( CV_StsBadArg, + "Input array must be 1d continuous array of 2d or 3d points" ); + + ptseq = cvMakeSeqHeaderForArray( + CV_SEQ_KIND_GENERIC|type, sizeof(CvContour), CV_ELEM_SIZE(type), mat->data.ptr, + mat->width + mat->height - 1, &header.seq, &block ); + } + + if( reps < 0 || aeps < 0 ) + CV_Error( CV_StsOutOfRange, "Both reps and aeps must be non-negative" ); + + if( CV_MAT_DEPTH(type) == CV_32F && ptseq->first->next == ptseq->first ) + { + /* no need to copy data in this case */ + points = ptseq->first->data; + } + else + { + buffer.allocate(ptseq->total*CV_ELEM_SIZE(type)); + points = buffer; + cvCvtSeqToArray( ptseq, points, CV_WHOLE_SEQ ); + + if( CV_MAT_DEPTH(type) != CV_32F ) + { + int i, total = ptseq->total*CV_MAT_CN(type); + assert( CV_MAT_DEPTH(type) == CV_32S ); + + for( i = 0; i < total; i++ ) + ((float*)points)[i] = (float)((int*)points)[i]; + } + } + + if( dist == CV_DIST_USER ) + CV_Error( CV_StsBadArg, "User-defined distance is not allowed" ); + + if( CV_MAT_CN(type) == 2 ) + { + IPPI_CALL( icvFitLine2D( (CvPoint2D32f*)points, ptseq->total, + dist, (float)param, (float)reps, (float)aeps, line )); + } + else + { + IPPI_CALL( icvFitLine3D( (CvPoint3D32f*)points, ptseq->total, + dist, (float)param, (float)reps, (float)aeps, line )); + } +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/matchcontours.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/matchcontours.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/matchcontours.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/matchcontours.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,198 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +/*F/////////////////////////////////////////////////////////////////////////////////////// +// Name: cvMatchContours +// Purpose: +// Calculates matching of the two contours +// Context: +// Parameters: +// contour_1 - pointer to the first input contour object. +// contour_2 - pointer to the second input contour object. +// method - method for the matching calculation +// (now CV_IPPI_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or +// CV_CONTOURS_MATCH_I3 only ) +// rezult - output calculated measure +// +//F*/ +CV_IMPL double +cvMatchShapes( const void* contour1, const void* contour2, + int method, double /*parameter*/ ) +{ + CvMoments moments; + CvHuMoments huMoments; + double ma[7], mb[7]; + int i, sma, smb; + double eps = 1.e-5; + double mmm; + double result = 0; + + if( !contour1 || !contour2 ) + CV_Error( CV_StsNullPtr, "" ); + + // calculate moments of the first shape + cvMoments( contour1, &moments ); + cvGetHuMoments( &moments, &huMoments ); + + ma[0] = huMoments.hu1; + ma[1] = huMoments.hu2; + ma[2] = huMoments.hu3; + ma[3] = huMoments.hu4; + ma[4] = huMoments.hu5; + ma[5] = huMoments.hu6; + ma[6] = huMoments.hu7; + + + // calculate moments of the second shape + cvMoments( contour2, &moments ); + cvGetHuMoments( &moments, &huMoments ); + + mb[0] = huMoments.hu1; + mb[1] = huMoments.hu2; + mb[2] = huMoments.hu3; + mb[3] = huMoments.hu4; + mb[4] = huMoments.hu5; + mb[5] = huMoments.hu6; + mb[6] = huMoments.hu7; + + switch (method) + { + case 1: + { + for( i = 0; i < 7; i++ ) + { + double ama = fabs( ma[i] ); + double amb = fabs( mb[i] ); + + if( ma[i] > 0 ) + sma = 1; + else if( ma[i] < 0 ) + sma = -1; + else + sma = 0; + if( mb[i] > 0 ) + smb = 1; + else if( mb[i] < 0 ) + smb = -1; + else + smb = 0; + + if( ama > eps && amb > eps ) + { + ama = 1. / (sma * log10( ama )); + amb = 1. / (smb * log10( amb )); + result += fabs( -ama + amb ); + } + } + break; + } + + case 2: + { + for( i = 0; i < 7; i++ ) + { + double ama = fabs( ma[i] ); + double amb = fabs( mb[i] ); + + if( ma[i] > 0 ) + sma = 1; + else if( ma[i] < 0 ) + sma = -1; + else + sma = 0; + if( mb[i] > 0 ) + smb = 1; + else if( mb[i] < 0 ) + smb = -1; + else + smb = 0; + + if( ama > eps && amb > eps ) + { + ama = sma * log10( ama ); + amb = smb * log10( amb ); + result += fabs( -ama + amb ); + } + } + break; + } + + case 3: + { + for( i = 0; i < 7; i++ ) + { + double ama = fabs( ma[i] ); + double amb = fabs( mb[i] ); + + if( ma[i] > 0 ) + sma = 1; + else if( ma[i] < 0 ) + sma = -1; + else + sma = 0; + if( mb[i] > 0 ) + smb = 1; + else if( mb[i] < 0 ) + smb = -1; + else + smb = 0; + + if( ama > eps && amb > eps ) + { + ama = sma * log10( ama ); + amb = smb * log10( amb ); + mmm = fabs( (ama - amb) / ama ); + if( result < mmm ) + result = mmm; + } + } + break; + } + default: + CV_Error( CV_StsBadArg, "Unknown comparison method" ); + } + + return result; +} + + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/moments.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/moments.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/moments.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/moments.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,651 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +// The function calculates center of gravity and the central second order moments +static void icvCompleteMomentState( CvMoments* moments ) +{ + double cx = 0, cy = 0; + double mu20, mu11, mu02; + + assert( moments != 0 ); + moments->inv_sqrt_m00 = 0; + + if( fabs(moments->m00) > DBL_EPSILON ) + { + double inv_m00 = 1. / moments->m00; + cx = moments->m10 * inv_m00; + cy = moments->m01 * inv_m00; + moments->inv_sqrt_m00 = std::sqrt( fabs(inv_m00) ); + } + + // mu20 = m20 - m10*cx + mu20 = moments->m20 - moments->m10 * cx; + // mu11 = m11 - m10*cy + mu11 = moments->m11 - moments->m10 * cy; + // mu02 = m02 - m01*cy + mu02 = moments->m02 - moments->m01 * cy; + + moments->mu20 = mu20; + moments->mu11 = mu11; + moments->mu02 = mu02; + + // mu30 = m30 - cx*(3*mu20 + cx*m10) + moments->mu30 = moments->m30 - cx * (3 * mu20 + cx * moments->m10); + mu11 += mu11; + // mu21 = m21 - cx*(2*mu11 + cx*m01) - cy*mu20 + moments->mu21 = moments->m21 - cx * (mu11 + cx * moments->m01) - cy * mu20; + // mu12 = m12 - cy*(2*mu11 + cy*m10) - cx*mu02 + moments->mu12 = moments->m12 - cy * (mu11 + cy * moments->m10) - cx * mu02; + // mu03 = m03 - cy*(3*mu02 + cy*m01) + moments->mu03 = moments->m03 - cy * (3 * mu02 + cy * moments->m01); +} + + +static void icvContourMoments( CvSeq* contour, CvMoments* moments ) +{ + int is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2; + + if( contour->total ) + { + CvSeqReader reader; + double a00, a10, a01, a20, a11, a02, a30, a21, a12, a03; + double xi, yi, xi2, yi2, xi_1, yi_1, xi_12, yi_12, dxy, xii_1, yii_1; + int lpt = contour->total; + + a00 = a10 = a01 = a20 = a11 = a02 = a30 = a21 = a12 = a03 = 0; + + cvStartReadSeq( contour, &reader, 0 ); + + if( !is_float ) + { + xi_1 = ((CvPoint*)(reader.ptr))->x; + yi_1 = ((CvPoint*)(reader.ptr))->y; + } + else + { + xi_1 = ((CvPoint2D32f*)(reader.ptr))->x; + yi_1 = ((CvPoint2D32f*)(reader.ptr))->y; + } + CV_NEXT_SEQ_ELEM( contour->elem_size, reader ); + + xi_12 = xi_1 * xi_1; + yi_12 = yi_1 * yi_1; + + while( lpt-- > 0 ) + { + if( !is_float ) + { + xi = ((CvPoint*)(reader.ptr))->x; + yi = ((CvPoint*)(reader.ptr))->y; + } + else + { + xi = ((CvPoint2D32f*)(reader.ptr))->x; + yi = ((CvPoint2D32f*)(reader.ptr))->y; + } + CV_NEXT_SEQ_ELEM( contour->elem_size, reader ); + + xi2 = xi * xi; + yi2 = yi * yi; + dxy = xi_1 * yi - xi * yi_1; + xii_1 = xi_1 + xi; + yii_1 = yi_1 + yi; + + a00 += dxy; + a10 += dxy * xii_1; + a01 += dxy * yii_1; + a20 += dxy * (xi_1 * xii_1 + xi2); + a11 += dxy * (xi_1 * (yii_1 + yi_1) + xi * (yii_1 + yi)); + a02 += dxy * (yi_1 * yii_1 + yi2); + a30 += dxy * xii_1 * (xi_12 + xi2); + a03 += dxy * yii_1 * (yi_12 + yi2); + a21 += + dxy * (xi_12 * (3 * yi_1 + yi) + 2 * xi * xi_1 * yii_1 + + xi2 * (yi_1 + 3 * yi)); + a12 += + dxy * (yi_12 * (3 * xi_1 + xi) + 2 * yi * yi_1 * xii_1 + + yi2 * (xi_1 + 3 * xi)); + + xi_1 = xi; + yi_1 = yi; + xi_12 = xi2; + yi_12 = yi2; + } + + double db1_2, db1_6, db1_12, db1_24, db1_20, db1_60; + + if( fabs(a00) > FLT_EPSILON ) + { + if( a00 > 0 ) + { + db1_2 = 0.5; + db1_6 = 0.16666666666666666666666666666667; + db1_12 = 0.083333333333333333333333333333333; + db1_24 = 0.041666666666666666666666666666667; + db1_20 = 0.05; + db1_60 = 0.016666666666666666666666666666667; + } + else + { + db1_2 = -0.5; + db1_6 = -0.16666666666666666666666666666667; + db1_12 = -0.083333333333333333333333333333333; + db1_24 = -0.041666666666666666666666666666667; + db1_20 = -0.05; + db1_60 = -0.016666666666666666666666666666667; + } + + // spatial moments + moments->m00 = a00 * db1_2; + moments->m10 = a10 * db1_6; + moments->m01 = a01 * db1_6; + moments->m20 = a20 * db1_12; + moments->m11 = a11 * db1_24; + moments->m02 = a02 * db1_12; + moments->m30 = a30 * db1_20; + moments->m21 = a21 * db1_60; + moments->m12 = a12 * db1_60; + moments->m03 = a03 * db1_20; + + icvCompleteMomentState( moments ); + } + } +} + + +/****************************************************************************************\ +* Spatial Raster Moments * +\****************************************************************************************/ + +template +static void momentsInTile( const cv::Mat& img, double* moments ) +{ + cv::Size size = img.size(); + int x, y; + MT mom[10] = {0,0,0,0,0,0,0,0,0,0}; + + for( y = 0; y < size.height; y++ ) + { + const T* ptr = (const T*)(img.data + y*img.step); + WT x0 = 0, x1 = 0, x2 = 0; + MT x3 = 0; + + for( x = 0; x < size.width; x++ ) + { + WT p = ptr[x]; + WT xp = x * p, xxp; + + x0 += p; + x1 += xp; + xxp = xp * x; + x2 += xxp; + x3 += xxp * x; + } + + WT py = y * x0, sy = y*y; + + mom[9] += ((MT)py) * sy; // m03 + mom[8] += ((MT)x1) * sy; // m12 + mom[7] += ((MT)x2) * y; // m21 + mom[6] += x3; // m30 + mom[5] += x0 * sy; // m02 + mom[4] += x1 * y; // m11 + mom[3] += x2; // m20 + mom[2] += py; // m01 + mom[1] += x1; // m10 + mom[0] += x0; // m00 + } + + for( x = 0; x < 10; x++ ) + moments[x] = (double)mom[x]; +} + + +#if CV_SSE2 + +template<> void momentsInTile( const cv::Mat& img, double* moments ) +{ + typedef uchar T; + typedef int WT; + typedef int MT; + cv::Size size = img.size(); + int y; + MT mom[10] = {0,0,0,0,0,0,0,0,0,0}; + bool useSIMD = cv::checkHardwareSupport(CV_CPU_SSE2); + + for( y = 0; y < size.height; y++ ) + { + const T* ptr = img.ptr(y); + int x0 = 0, x1 = 0, x2 = 0, x3 = 0, x = 0; + + if( useSIMD ) + { + __m128i qx_init = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); + __m128i dx = _mm_set1_epi16(8); + __m128i z = _mm_setzero_si128(), qx0 = z, qx1 = z, qx2 = z, qx3 = z, qx = qx_init; + + for( ; x <= size.width - 8; x += 8 ) + { + __m128i p = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(ptr + x)), z); + qx0 = _mm_add_epi32(qx0, _mm_sad_epu8(p, z)); + __m128i px = _mm_mullo_epi16(p, qx); + __m128i sx = _mm_mullo_epi16(qx, qx); + qx1 = _mm_add_epi32(qx1, _mm_madd_epi16(p, qx)); + qx2 = _mm_add_epi32(qx2, _mm_madd_epi16(p, sx)); + qx3 = _mm_add_epi32(qx3, _mm_madd_epi16(px, sx)); + + qx = _mm_add_epi16(qx, dx); + } + int CV_DECL_ALIGNED(16) buf[4]; + _mm_store_si128((__m128i*)buf, qx0); + x0 = buf[0] + buf[1] + buf[2] + buf[3]; + _mm_store_si128((__m128i*)buf, qx1); + x1 = buf[0] + buf[1] + buf[2] + buf[3]; + _mm_store_si128((__m128i*)buf, qx2); + x2 = buf[0] + buf[1] + buf[2] + buf[3]; + _mm_store_si128((__m128i*)buf, qx3); + x3 = buf[0] + buf[1] + buf[2] + buf[3]; + } + + for( ; x < size.width; x++ ) + { + WT p = ptr[x]; + WT xp = x * p, xxp; + + x0 += p; + x1 += xp; + xxp = xp * x; + x2 += xxp; + x3 += xxp * x; + } + + WT py = y * x0, sy = y*y; + + mom[9] += ((MT)py) * sy; // m03 + mom[8] += ((MT)x1) * sy; // m12 + mom[7] += ((MT)x2) * y; // m21 + mom[6] += x3; // m30 + mom[5] += x0 * sy; // m02 + mom[4] += x1 * y; // m11 + mom[3] += x2; // m20 + mom[2] += py; // m01 + mom[1] += x1; // m10 + mom[0] += x0; // m00 + } + + for(int x = 0; x < 10; x++ ) + moments[x] = (double)mom[x]; +} + +#endif + +typedef void (*CvMomentsInTileFunc)(const cv::Mat& img, double* moments); + +CV_IMPL void cvMoments( const void* array, CvMoments* moments, int binary ) +{ + const int TILE_SIZE = 32; + int type, depth, cn, coi = 0; + CvMat stub, *mat = (CvMat*)array; + CvMomentsInTileFunc func = 0; + CvContour contourHeader; + CvSeq* contour = 0; + CvSeqBlock block; + double buf[TILE_SIZE*TILE_SIZE]; + uchar nzbuf[TILE_SIZE*TILE_SIZE]; + + if( CV_IS_SEQ( array )) + { + contour = (CvSeq*)array; + if( !CV_IS_SEQ_POINT_SET( contour )) + CV_Error( CV_StsBadArg, "The passed sequence is not a valid contour" ); + } + + if( !moments ) + CV_Error( CV_StsNullPtr, "" ); + + memset( moments, 0, sizeof(*moments)); + + if( !contour ) + { + mat = cvGetMat( mat, &stub, &coi ); + type = CV_MAT_TYPE( mat->type ); + + if( type == CV_32SC2 || type == CV_32FC2 ) + { + contour = cvPointSeqFromMat( + CV_SEQ_KIND_CURVE | CV_SEQ_FLAG_CLOSED, + mat, &contourHeader, &block ); + } + } + + if( contour ) + { + icvContourMoments( contour, moments ); + return; + } + + type = CV_MAT_TYPE( mat->type ); + depth = CV_MAT_DEPTH( type ); + cn = CV_MAT_CN( type ); + + cv::Size size = cvGetMatSize( mat ); + + if( cn > 1 && coi == 0 ) + CV_Error( CV_StsBadArg, "Invalid image type" ); + + if( size.width <= 0 || size.height <= 0 ) + return; + + if( binary || depth == CV_8U ) + func = momentsInTile; + else if( depth == CV_16U ) + func = momentsInTile; + else if( depth == CV_16S ) + func = momentsInTile; + else if( depth == CV_32F ) + func = momentsInTile; + else if( depth == CV_64F ) + func = momentsInTile; + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + cv::Mat src0(mat); + + for( int y = 0; y < size.height; y += TILE_SIZE ) + { + cv::Size tileSize; + tileSize.height = std::min(TILE_SIZE, size.height - y); + + for( int x = 0; x < size.width; x += TILE_SIZE ) + { + tileSize.width = std::min(TILE_SIZE, size.width - x); + cv::Mat src(src0, cv::Rect(x, y, tileSize.width, tileSize.height)); + + if( coi > 0 ) + { + cv::Mat tmp(tileSize, depth, buf); + int pairs[] = {coi-1, 0}; + cv::mixChannels(&src, 1, &tmp, 1, pairs, 1); + src = tmp; + } + if( binary ) + { + cv::Mat tmp(tileSize, CV_8U, nzbuf); + cv::compare( src, 0, tmp, CV_CMP_NE ); + src = tmp; + } + + double mom[10]; + func( src, mom ); + + if(binary) + { + double s = 1./255; + for( int k = 0; k < 10; k++ ) + mom[k] *= s; + } + + double xm = x * mom[0], ym = y * mom[0]; + + // accumulate moments computed in each tile + + // + m00 ( = m00' ) + moments->m00 += mom[0]; + + // + m10 ( = m10' + x*m00' ) + moments->m10 += mom[1] + xm; + + // + m01 ( = m01' + y*m00' ) + moments->m01 += mom[2] + ym; + + // + m20 ( = m20' + 2*x*m10' + x*x*m00' ) + moments->m20 += mom[3] + x * (mom[1] * 2 + xm); + + // + m11 ( = m11' + x*m01' + y*m10' + x*y*m00' ) + moments->m11 += mom[4] + x * (mom[2] + ym) + y * mom[1]; + + // + m02 ( = m02' + 2*y*m01' + y*y*m00' ) + moments->m02 += mom[5] + y * (mom[2] * 2 + ym); + + // + m30 ( = m30' + 3*x*m20' + 3*x*x*m10' + x*x*x*m00' ) + moments->m30 += mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm)); + + // + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20') + moments->m21 += mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3]; + + // + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02') + moments->m12 += mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5]; + + // + m03 ( = m03' + 3*y*m02' + 3*y*y*m01' + y*y*y*m00' ) + moments->m03 += mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym)); + } + } + + icvCompleteMomentState( moments ); +} + + +CV_IMPL void cvGetHuMoments( CvMoments * mState, CvHuMoments * HuState ) +{ + if( !mState || !HuState ) + CV_Error( CV_StsNullPtr, "" ); + + double m00s = mState->inv_sqrt_m00, m00 = m00s * m00s, s2 = m00 * m00, s3 = s2 * m00s; + + double nu20 = mState->mu20 * s2, + nu11 = mState->mu11 * s2, + nu02 = mState->mu02 * s2, + nu30 = mState->mu30 * s3, + nu21 = mState->mu21 * s3, nu12 = mState->mu12 * s3, nu03 = mState->mu03 * s3; + + double t0 = nu30 + nu12; + double t1 = nu21 + nu03; + + double q0 = t0 * t0, q1 = t1 * t1; + + double n4 = 4 * nu11; + double s = nu20 + nu02; + double d = nu20 - nu02; + + HuState->hu1 = s; + HuState->hu2 = d * d + n4 * nu11; + HuState->hu4 = q0 + q1; + HuState->hu6 = d * (q0 - q1) + n4 * t0 * t1; + + t0 *= q0 - 3 * q1; + t1 *= 3 * q0 - q1; + + q0 = nu30 - 3 * nu12; + q1 = 3 * nu21 - nu03; + + HuState->hu3 = q0 * q0 + q1 * q1; + HuState->hu5 = q0 * t0 + q1 * t1; + HuState->hu7 = q1 * t0 - q0 * t1; +} + + +CV_IMPL double cvGetSpatialMoment( CvMoments * moments, int x_order, int y_order ) +{ + int order = x_order + y_order; + + if( !moments ) + CV_Error( CV_StsNullPtr, "" ); + if( (x_order | y_order) < 0 || order > 3 ) + CV_Error( CV_StsOutOfRange, "" ); + + return (&(moments->m00))[order + (order >> 1) + (order > 2) * 2 + y_order]; +} + + +CV_IMPL double cvGetCentralMoment( CvMoments * moments, int x_order, int y_order ) +{ + int order = x_order + y_order; + + if( !moments ) + CV_Error( CV_StsNullPtr, "" ); + if( (x_order | y_order) < 0 || order > 3 ) + CV_Error( CV_StsOutOfRange, "" ); + + return order >= 2 ? (&(moments->m00))[4 + order * 3 + y_order] : + order == 0 ? moments->m00 : 0; +} + + +CV_IMPL double cvGetNormalizedCentralMoment( CvMoments * moments, int x_order, int y_order ) +{ + int order = x_order + y_order; + + double mu = cvGetCentralMoment( moments, x_order, y_order ); + double m00s = moments->inv_sqrt_m00; + + while( --order >= 0 ) + mu *= m00s; + return mu * m00s * m00s; +} + + +namespace cv +{ + +Moments::Moments() +{ + m00 = m10 = m01 = m20 = m11 = m02 = m30 = m21 = m12 = m03 = + mu20 = mu11 = mu02 = mu30 = mu21 = mu12 = mu03 = + nu20 = nu11 = nu02 = nu30 = nu21 = nu12 = nu03 = 0.; +} + +Moments::Moments( double _m00, double _m10, double _m01, double _m20, double _m11, + double _m02, double _m30, double _m21, double _m12, double _m03 ) +{ + m00 = _m00; m10 = _m10; m01 = _m01; + m20 = _m20; m11 = _m11; m02 = _m02; + m30 = _m30; m21 = _m21; m12 = _m12; m03 = _m03; + + double cx = 0, cy = 0, inv_m00 = 0; + if( std::abs(m00) > DBL_EPSILON ) + { + inv_m00 = 1./m00; + cx = m10*inv_m00; cy = m01*inv_m00; + } + + mu20 = m20 - m10*cx; + mu11 = m11 - m10*cy; + mu02 = m02 - m01*cy; + + mu30 = m30 - cx*(3*mu20 + cx*m10); + mu21 = m21 - cx*(2*mu11 + cx*m01) - cy*mu20; + mu12 = m12 - cy*(2*mu11 + cy*m10) - cx*mu02; + mu03 = m03 - cy*(3*mu02 + cy*m01); + + double inv_sqrt_m00 = std::sqrt(std::abs(inv_m00)); + double s2 = inv_m00*inv_m00, s3 = s2*inv_sqrt_m00; + + nu20 = mu20*s2; nu11 = mu11*s2; nu02 = mu02*s2; + nu30 = mu30*s3; nu21 = mu21*s3; nu12 = mu12*s3; nu03 = mu03*s3; +} + +Moments::Moments( const CvMoments& m ) +{ + *this = Moments(m.m00, m.m10, m.m01, m.m20, m.m11, m.m02, m.m30, m.m21, m.m12, m.m03); +} + +Moments::operator CvMoments() const +{ + CvMoments m; + m.m00 = m00; m.m10 = m10; m.m01 = m01; + m.m20 = m20; m.m11 = m11; m.m02 = m02; + m.m30 = m30; m.m21 = m21; m.m12 = m12; m.m03 = m03; + m.mu20 = mu20; m.mu11 = mu11; m.mu02 = mu02; + m.mu30 = mu30; m.mu21 = mu21; m.mu12 = mu12; m.mu03 = mu03; + double am00 = std::abs(m00); + m.inv_sqrt_m00 = am00 > DBL_EPSILON ? 1./std::sqrt(am00) : 0; + + return m; +} + +} + +cv::Moments cv::moments( InputArray _array, bool binaryImage ) +{ + CvMoments om; + Mat arr = _array.getMat(); + CvMat c_array = arr; + cvMoments(&c_array, &om, binaryImage); + return om; +} + +void cv::HuMoments( const Moments& m, double hu[7] ) +{ + double t0 = m.nu30 + m.nu12; + double t1 = m.nu21 + m.nu03; + + double q0 = t0 * t0, q1 = t1 * t1; + + double n4 = 4 * m.nu11; + double s = m.nu20 + m.nu02; + double d = m.nu20 - m.nu02; + + hu[0] = s; + hu[1] = d * d + n4 * m.nu11; + hu[3] = q0 + q1; + hu[5] = d * (q0 - q1) + n4 * t0 * t1; + + t0 *= q0 - 3 * q1; + t1 *= 3 * q0 - q1; + + q0 = m.nu30 - 3 * m.nu12; + q1 = 3 * m.nu21 - m.nu03; + + hu[2] = q0 * q0 + q1 * q1; + hu[4] = q0 * t0 + q1 * t1; + hu[6] = q1 * t0 - q0 * t1; +} + +void cv::HuMoments( const Moments& m, OutputArray _hu ) +{ + _hu.create(7, 1, CV_64F); + Mat hu = _hu.getMat(); + CV_Assert( hu.isContinuous() ); + HuMoments(m, (double*)hu.data); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/morph.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/morph.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/morph.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/morph.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1370 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include +#include + +/****************************************************************************************\ + Basic Morphological Operations: Erosion & Dilation +\****************************************************************************************/ + +namespace cv +{ + +template struct MinOp +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator ()(const T a, const T b) const { return std::min(a, b); } +}; + +template struct MaxOp +{ + typedef T type1; + typedef T type2; + typedef T rtype; + T operator ()(const T a, const T b) const { return std::max(a, b); } +}; + +#undef CV_MIN_8U +#undef CV_MAX_8U +#define CV_MIN_8U(a,b) ((a) - CV_FAST_CAST_8U((a) - (b))) +#define CV_MAX_8U(a,b) ((a) + CV_FAST_CAST_8U((b) - (a))) + +template<> inline uchar MinOp::operator ()(const uchar a, const uchar b) const { return CV_MIN_8U(a, b); } +template<> inline uchar MaxOp::operator ()(const uchar a, const uchar b) const { return CV_MAX_8U(a, b); } + +struct MorphRowNoVec +{ + MorphRowNoVec(int, int) {} + int operator()(const uchar*, uchar*, int, int) const { return 0; } +}; + +struct MorphColumnNoVec +{ + MorphColumnNoVec(int, int) {} + int operator()(const uchar**, uchar*, int, int, int) const { return 0; } +}; + +struct MorphNoVec +{ + int operator()(uchar**, int, uchar*, int) const { return 0; } +}; + +#if CV_SSE2 + +template struct MorphRowIVec +{ + enum { ESZ = VecUpdate::ESZ }; + + MorphRowIVec(int _ksize, int _anchor) : ksize(_ksize), anchor(_anchor) {} + int operator()(const uchar* src, uchar* dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + cn *= ESZ; + int i, k, _ksize = ksize*cn; + width = (width & -4)*cn; + VecUpdate updateOp; + + for( i = 0; i <= width - 16; i += 16 ) + { + __m128i s = _mm_loadu_si128((const __m128i*)(src + i)); + for( k = cn; k < _ksize; k += cn ) + { + __m128i x = _mm_loadu_si128((const __m128i*)(src + i + k)); + s = updateOp(s, x); + } + _mm_storeu_si128((__m128i*)(dst + i), s); + } + + for( ; i < width; i += 4 ) + { + __m128i s = _mm_cvtsi32_si128(*(const int*)(src + i)); + for( k = cn; k < _ksize; k += cn ) + { + __m128i x = _mm_cvtsi32_si128(*(const int*)(src + i + k)); + s = updateOp(s, x); + } + *(int*)(dst + i) = _mm_cvtsi128_si32(s); + } + + return i/ESZ; + } + + int ksize, anchor; +}; + + +template struct MorphRowFVec +{ + MorphRowFVec(int _ksize, int _anchor) : ksize(_ksize), anchor(_anchor) {} + int operator()(const uchar* src, uchar* dst, int width, int cn) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int i, k, _ksize = ksize*cn; + width = (width & -4)*cn; + VecUpdate updateOp; + + for( i = 0; i < width; i += 4 ) + { + __m128 s = _mm_loadu_ps((const float*)src + i); + for( k = cn; k < _ksize; k += cn ) + { + __m128 x = _mm_loadu_ps((const float*)src + i + k); + s = updateOp(s, x); + } + _mm_storeu_ps((float*)dst + i, s); + } + + return i; + } + + int ksize, anchor; +}; + + +template struct MorphColumnIVec +{ + enum { ESZ = VecUpdate::ESZ }; + + MorphColumnIVec(int _ksize, int _anchor) : ksize(_ksize), anchor(_anchor) {} + int operator()(const uchar** src, uchar* dst, int dststep, int count, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int i = 0, k, _ksize = ksize; + width *= ESZ; + VecUpdate updateOp; + + for( i = 0; i < count + ksize - 1; i++ ) + CV_Assert( ((size_t)src[i] & 15) == 0 ); + + for( ; _ksize > 1 && count > 1; count -= 2, dst += dststep*2, src += 2 ) + { + for( i = 0; i <= width - 32; i += 32 ) + { + const uchar* sptr = src[1] + i; + __m128i s0 = _mm_load_si128((const __m128i*)sptr); + __m128i s1 = _mm_load_si128((const __m128i*)(sptr + 16)); + __m128i x0, x1; + + for( k = 2; k < _ksize; k++ ) + { + sptr = src[k] + i; + x0 = _mm_load_si128((const __m128i*)sptr); + x1 = _mm_load_si128((const __m128i*)(sptr + 16)); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + } + + sptr = src[0] + i; + x0 = _mm_load_si128((const __m128i*)sptr); + x1 = _mm_load_si128((const __m128i*)(sptr + 16)); + _mm_storeu_si128((__m128i*)(dst + i), updateOp(s0, x0)); + _mm_storeu_si128((__m128i*)(dst + i + 16), updateOp(s1, x1)); + + sptr = src[k] + i; + x0 = _mm_load_si128((const __m128i*)sptr); + x1 = _mm_load_si128((const __m128i*)(sptr + 16)); + _mm_storeu_si128((__m128i*)(dst + dststep + i), updateOp(s0, x0)); + _mm_storeu_si128((__m128i*)(dst + dststep + i + 16), updateOp(s1, x1)); + } + + for( ; i <= width - 8; i += 8 ) + { + __m128i s0 = _mm_loadl_epi64((const __m128i*)(src[1] + i)), x0; + + for( k = 2; k < _ksize; k++ ) + { + x0 = _mm_loadl_epi64((const __m128i*)(src[k] + i)); + s0 = updateOp(s0, x0); + } + + x0 = _mm_loadl_epi64((const __m128i*)(src[0] + i)); + _mm_storel_epi64((__m128i*)(dst + i), updateOp(s0, x0)); + x0 = _mm_loadl_epi64((const __m128i*)(src[k] + i)); + _mm_storel_epi64((__m128i*)(dst + dststep + i), updateOp(s0, x0)); + } + } + + for( ; count > 0; count--, dst += dststep, src++ ) + { + for( i = 0; i <= width - 32; i += 32 ) + { + const uchar* sptr = src[0] + i; + __m128i s0 = _mm_load_si128((const __m128i*)sptr); + __m128i s1 = _mm_load_si128((const __m128i*)(sptr + 16)); + __m128i x0, x1; + + for( k = 1; k < _ksize; k++ ) + { + sptr = src[k] + i; + x0 = _mm_load_si128((const __m128i*)sptr); + x1 = _mm_load_si128((const __m128i*)(sptr + 16)); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + } + _mm_storeu_si128((__m128i*)(dst + i), s0); + _mm_storeu_si128((__m128i*)(dst + i + 16), s1); + } + + for( ; i <= width - 8; i += 8 ) + { + __m128i s0 = _mm_loadl_epi64((const __m128i*)(src[0] + i)), x0; + + for( k = 1; k < _ksize; k++ ) + { + x0 = _mm_loadl_epi64((const __m128i*)(src[k] + i)); + s0 = updateOp(s0, x0); + } + _mm_storel_epi64((__m128i*)(dst + i), s0); + } + } + + return i/ESZ; + } + + int ksize, anchor; +}; + + +template struct MorphColumnFVec +{ + MorphColumnFVec(int _ksize, int _anchor) : ksize(_ksize), anchor(_anchor) {} + int operator()(const uchar** _src, uchar* _dst, int dststep, int count, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int i = 0, k, _ksize = ksize; + VecUpdate updateOp; + + for( i = 0; i < count + ksize - 1; i++ ) + CV_Assert( ((size_t)_src[i] & 15) == 0 ); + + const float** src = (const float**)_src; + float* dst = (float*)_dst; + dststep /= sizeof(dst[0]); + + for( ; _ksize > 1 && count > 1; count -= 2, dst += dststep*2, src += 2 ) + { + for( i = 0; i <= width - 16; i += 16 ) + { + const float* sptr = src[1] + i; + __m128 s0 = _mm_load_ps(sptr); + __m128 s1 = _mm_load_ps(sptr + 4); + __m128 s2 = _mm_load_ps(sptr + 8); + __m128 s3 = _mm_load_ps(sptr + 12); + __m128 x0, x1, x2, x3; + + for( k = 2; k < _ksize; k++ ) + { + sptr = src[k] + i; + x0 = _mm_load_ps(sptr); + x1 = _mm_load_ps(sptr + 4); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + x2 = _mm_load_ps(sptr + 8); + x3 = _mm_load_ps(sptr + 12); + s2 = updateOp(s2, x2); + s3 = updateOp(s3, x3); + } + + sptr = src[0] + i; + x0 = _mm_load_ps(sptr); + x1 = _mm_load_ps(sptr + 4); + x2 = _mm_load_ps(sptr + 8); + x3 = _mm_load_ps(sptr + 12); + _mm_storeu_ps(dst + i, updateOp(s0, x0)); + _mm_storeu_ps(dst + i + 4, updateOp(s1, x1)); + _mm_storeu_ps(dst + i + 8, updateOp(s2, x2)); + _mm_storeu_ps(dst + i + 12, updateOp(s3, x3)); + + sptr = src[k] + i; + x0 = _mm_load_ps(sptr); + x1 = _mm_load_ps(sptr + 4); + x2 = _mm_load_ps(sptr + 8); + x3 = _mm_load_ps(sptr + 12); + _mm_storeu_ps(dst + dststep + i, updateOp(s0, x0)); + _mm_storeu_ps(dst + dststep + i + 4, updateOp(s1, x1)); + _mm_storeu_ps(dst + dststep + i + 8, updateOp(s2, x2)); + _mm_storeu_ps(dst + dststep + i + 12, updateOp(s3, x3)); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 s0 = _mm_load_ps(src[1] + i), x0; + + for( k = 2; k < _ksize; k++ ) + { + x0 = _mm_load_ps(src[k] + i); + s0 = updateOp(s0, x0); + } + + x0 = _mm_load_ps(src[0] + i); + _mm_storeu_ps(dst + i, updateOp(s0, x0)); + x0 = _mm_load_ps(src[k] + i); + _mm_storeu_ps(dst + dststep + i, updateOp(s0, x0)); + } + } + + for( ; count > 0; count--, dst += dststep, src++ ) + { + for( i = 0; i <= width - 16; i += 16 ) + { + const float* sptr = src[0] + i; + __m128 s0 = _mm_load_ps(sptr); + __m128 s1 = _mm_load_ps(sptr + 4); + __m128 s2 = _mm_load_ps(sptr + 8); + __m128 s3 = _mm_load_ps(sptr + 12); + __m128 x0, x1, x2, x3; + + for( k = 1; k < _ksize; k++ ) + { + sptr = src[k] + i; + x0 = _mm_load_ps(sptr); + x1 = _mm_load_ps(sptr + 4); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + x2 = _mm_load_ps(sptr + 8); + x3 = _mm_load_ps(sptr + 12); + s2 = updateOp(s2, x2); + s3 = updateOp(s3, x3); + } + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + _mm_storeu_ps(dst + i + 8, s2); + _mm_storeu_ps(dst + i + 12, s3); + } + + for( i = 0; i <= width - 4; i += 4 ) + { + __m128 s0 = _mm_load_ps(src[0] + i), x0; + for( k = 1; k < _ksize; k++ ) + { + x0 = _mm_load_ps(src[k] + i); + s0 = updateOp(s0, x0); + } + _mm_storeu_ps(dst + i, s0); + } + } + + return i; + } + + int ksize, anchor; +}; + + +template struct MorphIVec +{ + enum { ESZ = VecUpdate::ESZ }; + + int operator()(uchar** src, int nz, uchar* dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int i, k; + width *= ESZ; + VecUpdate updateOp; + + for( i = 0; i <= width - 32; i += 32 ) + { + const uchar* sptr = src[0] + i; + __m128i s0 = _mm_loadu_si128((const __m128i*)sptr); + __m128i s1 = _mm_loadu_si128((const __m128i*)(sptr + 16)); + __m128i x0, x1; + + for( k = 1; k < nz; k++ ) + { + sptr = src[k] + i; + x0 = _mm_loadu_si128((const __m128i*)sptr); + x1 = _mm_loadu_si128((const __m128i*)(sptr + 16)); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + } + _mm_storeu_si128((__m128i*)(dst + i), s0); + _mm_storeu_si128((__m128i*)(dst + i + 16), s1); + } + + for( ; i <= width - 8; i += 8 ) + { + __m128i s0 = _mm_loadl_epi64((const __m128i*)(src[0] + i)), x0; + + for( k = 1; k < nz; k++ ) + { + x0 = _mm_loadl_epi64((const __m128i*)(src[k] + i)); + s0 = updateOp(s0, x0); + } + _mm_storel_epi64((__m128i*)(dst + i), s0); + } + + return i/ESZ; + } +}; + + +template struct MorphFVec +{ + int operator()(uchar** _src, int nz, uchar* _dst, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + const float** src = (const float**)_src; + float* dst = (float*)_dst; + int i, k; + VecUpdate updateOp; + + for( i = 0; i <= width - 16; i += 16 ) + { + const float* sptr = src[0] + i; + __m128 s0 = _mm_loadu_ps(sptr); + __m128 s1 = _mm_loadu_ps(sptr + 4); + __m128 s2 = _mm_loadu_ps(sptr + 8); + __m128 s3 = _mm_loadu_ps(sptr + 12); + __m128 x0, x1, x2, x3; + + for( k = 1; k < nz; k++ ) + { + sptr = src[k] + i; + x0 = _mm_loadu_ps(sptr); + x1 = _mm_loadu_ps(sptr + 4); + x2 = _mm_loadu_ps(sptr + 8); + x3 = _mm_loadu_ps(sptr + 12); + s0 = updateOp(s0, x0); + s1 = updateOp(s1, x1); + s2 = updateOp(s2, x2); + s3 = updateOp(s3, x3); + } + _mm_storeu_ps(dst + i, s0); + _mm_storeu_ps(dst + i + 4, s1); + _mm_storeu_ps(dst + i + 8, s2); + _mm_storeu_ps(dst + i + 12, s3); + } + + for( ; i <= width - 4; i += 4 ) + { + __m128 s0 = _mm_loadu_ps(src[0] + i), x0; + + for( k = 1; k < nz; k++ ) + { + x0 = _mm_loadu_ps(src[k] + i); + s0 = updateOp(s0, x0); + } + _mm_storeu_ps(dst + i, s0); + } + + for( ; i < width; i++ ) + { + __m128 s0 = _mm_load_ss(src[0] + i), x0; + + for( k = 1; k < nz; k++ ) + { + x0 = _mm_load_ss(src[k] + i); + s0 = updateOp(s0, x0); + } + _mm_store_ss(dst + i, s0); + } + + return i; + } +}; + +struct VMin8u +{ + enum { ESZ = 1 }; + __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_min_epu8(a,b); } +}; +struct VMax8u +{ + enum { ESZ = 1 }; + __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_max_epu8(a,b); } +}; +struct VMin16u +{ + enum { ESZ = 2 }; + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_subs_epu16(a,_mm_subs_epu16(a,b)); } +}; +struct VMax16u +{ + enum { ESZ = 2 }; + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_adds_epu16(_mm_subs_epu16(a,b), b); } +}; +struct VMin16s +{ + enum { ESZ = 2 }; + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_min_epi16(a, b); } +}; +struct VMax16s +{ + enum { ESZ = 2 }; + __m128i operator()(const __m128i& a, const __m128i& b) const + { return _mm_max_epi16(a, b); } +}; +struct VMin32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_min_ps(a,b); }}; +struct VMax32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_max_ps(a,b); }}; + +typedef MorphRowIVec ErodeRowVec8u; +typedef MorphRowIVec DilateRowVec8u; +typedef MorphRowIVec ErodeRowVec16u; +typedef MorphRowIVec DilateRowVec16u; +typedef MorphRowIVec ErodeRowVec16s; +typedef MorphRowIVec DilateRowVec16s; +typedef MorphRowFVec ErodeRowVec32f; +typedef MorphRowFVec DilateRowVec32f; + +typedef MorphColumnIVec ErodeColumnVec8u; +typedef MorphColumnIVec DilateColumnVec8u; +typedef MorphColumnIVec ErodeColumnVec16u; +typedef MorphColumnIVec DilateColumnVec16u; +typedef MorphColumnIVec ErodeColumnVec16s; +typedef MorphColumnIVec DilateColumnVec16s; +typedef MorphColumnFVec ErodeColumnVec32f; +typedef MorphColumnFVec DilateColumnVec32f; + +typedef MorphIVec ErodeVec8u; +typedef MorphIVec DilateVec8u; +typedef MorphIVec ErodeVec16u; +typedef MorphIVec DilateVec16u; +typedef MorphIVec ErodeVec16s; +typedef MorphIVec DilateVec16s; +typedef MorphFVec ErodeVec32f; +typedef MorphFVec DilateVec32f; + +#else + +#ifdef HAVE_TEGRA_OPTIMIZATION +using tegra::ErodeRowVec8u; +using tegra::DilateRowVec8u; + +using tegra::ErodeColumnVec8u; +using tegra::DilateColumnVec8u; +#else +typedef MorphRowNoVec ErodeRowVec8u; +typedef MorphRowNoVec DilateRowVec8u; + +typedef MorphColumnNoVec ErodeColumnVec8u; +typedef MorphColumnNoVec DilateColumnVec8u; +#endif + +typedef MorphRowNoVec ErodeRowVec16u; +typedef MorphRowNoVec DilateRowVec16u; +typedef MorphRowNoVec ErodeRowVec16s; +typedef MorphRowNoVec DilateRowVec16s; +typedef MorphRowNoVec ErodeRowVec32f; +typedef MorphRowNoVec DilateRowVec32f; + +typedef MorphColumnNoVec ErodeColumnVec16u; +typedef MorphColumnNoVec DilateColumnVec16u; +typedef MorphColumnNoVec ErodeColumnVec16s; +typedef MorphColumnNoVec DilateColumnVec16s; +typedef MorphColumnNoVec ErodeColumnVec32f; +typedef MorphColumnNoVec DilateColumnVec32f; + +typedef MorphNoVec ErodeVec8u; +typedef MorphNoVec DilateVec8u; +typedef MorphNoVec ErodeVec16u; +typedef MorphNoVec DilateVec16u; +typedef MorphNoVec ErodeVec16s; +typedef MorphNoVec DilateVec16s; +typedef MorphNoVec ErodeVec32f; +typedef MorphNoVec DilateVec32f; + +#endif + +typedef MorphRowNoVec ErodeRowVec64f; +typedef MorphRowNoVec DilateRowVec64f; +typedef MorphColumnNoVec ErodeColumnVec64f; +typedef MorphColumnNoVec DilateColumnVec64f; +typedef MorphNoVec ErodeVec64f; +typedef MorphNoVec DilateVec64f; + + +template struct MorphRowFilter : public BaseRowFilter +{ + typedef typename Op::rtype T; + + MorphRowFilter( int _ksize, int _anchor ) : vecOp(_ksize, _anchor) + { + ksize = _ksize; + anchor = _anchor; + } + + void operator()(const uchar* src, uchar* dst, int width, int cn) + { + int i, j, k, _ksize = ksize*cn; + const T* S = (const T*)src; + Op op; + T* D = (T*)dst; + + if( _ksize == cn ) + { + for( i = 0; i < width*cn; i++ ) + D[i] = S[i]; + return; + } + + int i0 = vecOp(src, dst, width, cn); + width *= cn; + + for( k = 0; k < cn; k++, S++, D++ ) + { + for( i = i0; i <= width - cn*2; i += cn*2 ) + { + const T* s = S + i; + T m = s[cn]; + for( j = cn*2; j < _ksize; j += cn ) + m = op(m, s[j]); + D[i] = op(m, s[0]); + D[i+cn] = op(m, s[j]); + } + + for( ; i < width; i += cn ) + { + const T* s = S + i; + T m = s[0]; + for( j = cn; j < _ksize; j += cn ) + m = op(m, s[j]); + D[i] = m; + } + } + } + + VecOp vecOp; +}; + + +template struct MorphColumnFilter : public BaseColumnFilter +{ + typedef typename Op::rtype T; + + MorphColumnFilter( int _ksize, int _anchor ) : vecOp(_ksize, _anchor) + { + ksize = _ksize; + anchor = _anchor; + } + + void operator()(const uchar** _src, uchar* dst, int dststep, int count, int width) + { + int i, k, _ksize = ksize; + const T** src = (const T**)_src; + T* D = (T*)dst; + Op op; + + int i0 = vecOp(_src, dst, dststep, count, width); + dststep /= sizeof(D[0]); + + for( ; _ksize > 1 && count > 1; count -= 2, D += dststep*2, src += 2 ) + { + i = i0; + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + const T* sptr = src[1] + i; + T s0 = sptr[0], s1 = sptr[1], s2 = sptr[2], s3 = sptr[3]; + + for( k = 2; k < _ksize; k++ ) + { + sptr = src[k] + i; + s0 = op(s0, sptr[0]); s1 = op(s1, sptr[1]); + s2 = op(s2, sptr[2]); s3 = op(s3, sptr[3]); + } + + sptr = src[0] + i; + D[i] = op(s0, sptr[0]); + D[i+1] = op(s1, sptr[1]); + D[i+2] = op(s2, sptr[2]); + D[i+3] = op(s3, sptr[3]); + + sptr = src[k] + i; + D[i+dststep] = op(s0, sptr[0]); + D[i+dststep+1] = op(s1, sptr[1]); + D[i+dststep+2] = op(s2, sptr[2]); + D[i+dststep+3] = op(s3, sptr[3]); + } + #endif + for( ; i < width; i++ ) + { + T s0 = src[1][i]; + + for( k = 2; k < _ksize; k++ ) + s0 = op(s0, src[k][i]); + + D[i] = op(s0, src[0][i]); + D[i+dststep] = op(s0, src[k][i]); + } + } + + for( ; count > 0; count--, D += dststep, src++ ) + { + i = i0; + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + const T* sptr = src[0] + i; + T s0 = sptr[0], s1 = sptr[1], s2 = sptr[2], s3 = sptr[3]; + + for( k = 1; k < _ksize; k++ ) + { + sptr = src[k] + i; + s0 = op(s0, sptr[0]); s1 = op(s1, sptr[1]); + s2 = op(s2, sptr[2]); s3 = op(s3, sptr[3]); + } + + D[i] = s0; D[i+1] = s1; + D[i+2] = s2; D[i+3] = s3; + } + #endif + for( ; i < width; i++ ) + { + T s0 = src[0][i]; + for( k = 1; k < _ksize; k++ ) + s0 = op(s0, src[k][i]); + D[i] = s0; + } + } + } + + VecOp vecOp; +}; + + +template struct MorphFilter : BaseFilter +{ + typedef typename Op::rtype T; + + MorphFilter( const Mat& _kernel, Point _anchor ) + { + anchor = _anchor; + ksize = _kernel.size(); + CV_Assert( _kernel.type() == CV_8U ); + + vector coeffs; // we do not really the values of non-zero + // kernel elements, just their locations + preprocess2DKernel( _kernel, coords, coeffs ); + ptrs.resize( coords.size() ); + } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width, int cn) + { + const Point* pt = &coords[0]; + const T** kp = (const T**)&ptrs[0]; + int i, k, nz = (int)coords.size(); + Op op; + + width *= cn; + for( ; count > 0; count--, dst += dststep, src++ ) + { + T* D = (T*)dst; + + for( k = 0; k < nz; k++ ) + kp[k] = (const T*)src[pt[k].y] + pt[k].x*cn; + + i = vecOp(&ptrs[0], nz, dst, width); + #if CV_ENABLE_UNROLLED + for( ; i <= width - 4; i += 4 ) + { + const T* sptr = kp[0] + i; + T s0 = sptr[0], s1 = sptr[1], s2 = sptr[2], s3 = sptr[3]; + + for( k = 1; k < nz; k++ ) + { + sptr = kp[k] + i; + s0 = op(s0, sptr[0]); s1 = op(s1, sptr[1]); + s2 = op(s2, sptr[2]); s3 = op(s3, sptr[3]); + } + + D[i] = s0; D[i+1] = s1; + D[i+2] = s2; D[i+3] = s3; + } + #endif + for( ; i < width; i++ ) + { + T s0 = kp[0][i]; + for( k = 1; k < nz; k++ ) + s0 = op(s0, kp[k][i]); + D[i] = s0; + } + } + } + + vector coords; + vector ptrs; + VecOp vecOp; +}; + +} + +/////////////////////////////////// External Interface ///////////////////////////////////// + +cv::Ptr cv::getMorphologyRowFilter(int op, int type, int ksize, int anchor) +{ + int depth = CV_MAT_DEPTH(type); + if( anchor < 0 ) + anchor = ksize/2; + CV_Assert( op == MORPH_ERODE || op == MORPH_DILATE ); + if( op == MORPH_ERODE ) + { + if( depth == CV_8U ) + return Ptr(new MorphRowFilter, + ErodeRowVec8u>(ksize, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphRowFilter, + ErodeRowVec16u>(ksize, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphRowFilter, + ErodeRowVec16s>(ksize, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphRowFilter, + ErodeRowVec32f>(ksize, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphRowFilter, + ErodeRowVec64f>(ksize, anchor)); + } + else + { + if( depth == CV_8U ) + return Ptr(new MorphRowFilter, + DilateRowVec8u>(ksize, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphRowFilter, + DilateRowVec16u>(ksize, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphRowFilter, + DilateRowVec16s>(ksize, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphRowFilter, + DilateRowVec32f>(ksize, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphRowFilter, + DilateRowVec64f>(ksize, anchor)); + } + + CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + return Ptr(0); +} + +cv::Ptr cv::getMorphologyColumnFilter(int op, int type, int ksize, int anchor) +{ + int depth = CV_MAT_DEPTH(type); + if( anchor < 0 ) + anchor = ksize/2; + CV_Assert( op == MORPH_ERODE || op == MORPH_DILATE ); + if( op == MORPH_ERODE ) + { + if( depth == CV_8U ) + return Ptr(new MorphColumnFilter, + ErodeColumnVec8u>(ksize, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphColumnFilter, + ErodeColumnVec16u>(ksize, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphColumnFilter, + ErodeColumnVec16s>(ksize, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphColumnFilter, + ErodeColumnVec32f>(ksize, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphColumnFilter, + ErodeColumnVec64f>(ksize, anchor)); + } + else + { + if( depth == CV_8U ) + return Ptr(new MorphColumnFilter, + DilateColumnVec8u>(ksize, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphColumnFilter, + DilateColumnVec16u>(ksize, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphColumnFilter, + DilateColumnVec16s>(ksize, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphColumnFilter, + DilateColumnVec32f>(ksize, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphColumnFilter, + DilateColumnVec64f>(ksize, anchor)); + } + + CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + return Ptr(0); +} + + +cv::Ptr cv::getMorphologyFilter(int op, int type, InputArray _kernel, Point anchor) +{ + Mat kernel = _kernel.getMat(); + int depth = CV_MAT_DEPTH(type); + anchor = normalizeAnchor(anchor, kernel.size()); + CV_Assert( op == MORPH_ERODE || op == MORPH_DILATE ); + if( op == MORPH_ERODE ) + { + if( depth == CV_8U ) + return Ptr(new MorphFilter, ErodeVec8u>(kernel, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphFilter, ErodeVec16u>(kernel, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphFilter, ErodeVec16s>(kernel, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphFilter, ErodeVec32f>(kernel, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphFilter, ErodeVec64f>(kernel, anchor)); + } + else + { + if( depth == CV_8U ) + return Ptr(new MorphFilter, DilateVec8u>(kernel, anchor)); + if( depth == CV_16U ) + return Ptr(new MorphFilter, DilateVec16u>(kernel, anchor)); + if( depth == CV_16S ) + return Ptr(new MorphFilter, DilateVec16s>(kernel, anchor)); + if( depth == CV_32F ) + return Ptr(new MorphFilter, DilateVec32f>(kernel, anchor)); + if( depth == CV_64F ) + return Ptr(new MorphFilter, DilateVec64f>(kernel, anchor)); + } + + CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + return Ptr(0); +} + + +cv::Ptr cv::createMorphologyFilter( int op, int type, InputArray _kernel, + Point anchor, int _rowBorderType, int _columnBorderType, + const Scalar& _borderValue ) +{ + Mat kernel = _kernel.getMat(); + anchor = normalizeAnchor(anchor, kernel.size()); + + Ptr rowFilter; + Ptr columnFilter; + Ptr filter2D; + + if( countNonZero(kernel) == kernel.rows*kernel.cols ) + { + // rectangular structuring element + rowFilter = getMorphologyRowFilter(op, type, kernel.cols, anchor.x); + columnFilter = getMorphologyColumnFilter(op, type, kernel.rows, anchor.y); + } + else + filter2D = getMorphologyFilter(op, type, kernel, anchor); + + Scalar borderValue = _borderValue; + if( (_rowBorderType == BORDER_CONSTANT || _columnBorderType == BORDER_CONSTANT) && + borderValue == morphologyDefaultBorderValue() ) + { + int depth = CV_MAT_DEPTH(type); + CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_16S || + depth == CV_32F || depth == CV_64F ); + if( op == MORPH_ERODE ) + borderValue = Scalar::all( depth == CV_8U ? (double)UCHAR_MAX : + depth == CV_16U ? (double)USHRT_MAX : + depth == CV_16S ? (double)SHRT_MAX : + depth == CV_32F ? (double)FLT_MAX : DBL_MAX); + else + borderValue = Scalar::all( depth == CV_8U || depth == CV_16U ? + 0. : + depth == CV_16S ? (double)SHRT_MIN : + depth == CV_32F ? (double)-FLT_MAX : -DBL_MAX); + } + + return Ptr(new FilterEngine(filter2D, rowFilter, columnFilter, + type, type, type, _rowBorderType, _columnBorderType, borderValue )); +} + + +cv::Mat cv::getStructuringElement(int shape, Size ksize, Point anchor) +{ + int i, j; + int r = 0, c = 0; + double inv_r2 = 0; + + CV_Assert( shape == MORPH_RECT || shape == MORPH_CROSS || shape == MORPH_ELLIPSE ); + + anchor = normalizeAnchor(anchor, ksize); + + if( ksize == Size(1,1) ) + shape = MORPH_RECT; + + if( shape == MORPH_ELLIPSE ) + { + r = ksize.height/2; + c = ksize.width/2; + inv_r2 = r ? 1./((double)r*r) : 0; + } + + Mat elem(ksize, CV_8U); + + for( i = 0; i < ksize.height; i++ ) + { + uchar* ptr = elem.data + i*elem.step; + int j1 = 0, j2 = 0; + + if( shape == MORPH_RECT || (shape == MORPH_CROSS && i == anchor.y) ) + j2 = ksize.width; + else if( shape == MORPH_CROSS ) + j1 = anchor.x, j2 = j1 + 1; + else + { + int dy = i - r; + if( std::abs(dy) <= r ) + { + int dx = saturate_cast(c*std::sqrt((r*r - dy*dy)*inv_r2)); + j1 = std::max( c - dx, 0 ); + j2 = std::min( c + dx + 1, ksize.width ); + } + } + + for( j = 0; j < j1; j++ ) + ptr[j] = 0; + for( ; j < j2; j++ ) + ptr[j] = 1; + for( ; j < ksize.width; j++ ) + ptr[j] = 0; + } + + return elem; +} + +namespace cv +{ + +class MorphologyRunner +{ +public: + MorphologyRunner(Mat _src, Mat _dst, int _nStripes, int _iterations, + int _op, Mat _kernel, Point _anchor, + int _rowBorderType, int _columnBorderType, const Scalar& _borderValue) : + borderValue(_borderValue) + { + src = _src; + dst = _dst; + + nStripes = _nStripes; + iterations = _iterations; + + op = _op; + kernel = _kernel; + anchor = _anchor; + rowBorderType = _rowBorderType; + columnBorderType = _columnBorderType; + } + + void operator () ( const BlockedRange& range ) const + { + int row0 = min(cvRound(range.begin() * src.rows / nStripes), src.rows); + int row1 = min(cvRound(range.end() * src.rows / nStripes), src.rows); + + /*if(0) + printf("Size = (%d, %d), range[%d,%d), row0 = %d, row1 = %d\n", + src.rows, src.cols, range.begin(), range.end(), row0, row1);*/ + + Mat srcStripe = src.rowRange(row0, row1); + Mat dstStripe = dst.rowRange(row0, row1); + + Ptr f = createMorphologyFilter(op, src.type(), kernel, anchor, + rowBorderType, columnBorderType, borderValue ); + + f->apply( srcStripe, dstStripe ); + for( int i = 1; i < iterations; i++ ) + f->apply( dstStripe, dstStripe ); + } + +private: + Mat src; + Mat dst; + int nStripes; + int iterations; + + int op; + Mat kernel; + Point anchor; + int rowBorderType; + int columnBorderType; + Scalar borderValue; +}; + +static void morphOp( int op, InputArray _src, OutputArray _dst, + InputArray _kernel, + Point anchor, int iterations, + int borderType, const Scalar& borderValue ) +{ + Mat src = _src.getMat(), kernel = _kernel.getMat(); + Size ksize = kernel.data ? kernel.size() : Size(3,3); + anchor = normalizeAnchor(anchor, ksize); + + CV_Assert( anchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( iterations == 0 || kernel.rows*kernel.cols == 1 ) + { + src.copyTo(dst); + return; + } + + if( !kernel.data ) + { + kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2)); + anchor = Point(iterations, iterations); + iterations = 1; + } + else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols ) + { + anchor = Point(anchor.x*iterations, anchor.y*iterations); + kernel = getStructuringElement(MORPH_RECT, + Size(ksize.width + (iterations-1)*(ksize.width-1), + ksize.height + (iterations-1)*(ksize.height-1)), + anchor); + iterations = 1; + } + + int nStripes = 1; +#if defined HAVE_TBB && defined HAVE_TEGRA_OPTIMIZATION + if (src.data != dst.data && iterations == 1 && //NOTE: threads are not used for inplace processing + (borderType & BORDER_ISOLATED) == 0 && //TODO: check border types + src.rows >= 64 ) //NOTE: just heuristics + nStripes = 4; +#endif + + parallel_for(BlockedRange(0, nStripes), + MorphologyRunner(src, dst, nStripes, iterations, op, kernel, anchor, borderType, borderType, borderValue)); + + //Ptr f = createMorphologyFilter(op, src.type(), + // kernel, anchor, borderType, borderType, borderValue ); + + //f->apply( src, dst ); + //for( int i = 1; i < iterations; i++ ) + // f->apply( dst, dst ); +} + +template<> void Ptr::delete_obj() +{ cvReleaseStructuringElement(&obj); } + +} + +void cv::erode( InputArray src, OutputArray dst, InputArray kernel, + Point anchor, int iterations, + int borderType, const Scalar& borderValue ) +{ + morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue ); +} + + +void cv::dilate( InputArray src, OutputArray dst, InputArray kernel, + Point anchor, int iterations, + int borderType, const Scalar& borderValue ) +{ + morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue ); +} + + +void cv::morphologyEx( InputArray _src, OutputArray _dst, int op, + InputArray kernel, Point anchor, int iterations, + int borderType, const Scalar& borderValue ) +{ + Mat src = _src.getMat(), temp; + _dst.create(src.size(), src.type()); + Mat dst = _dst.getMat(); + + switch( op ) + { + case MORPH_ERODE: + erode( src, dst, kernel, anchor, iterations, borderType, borderValue ); + break; + case MORPH_DILATE: + dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); + break; + case MORPH_OPEN: + erode( src, dst, kernel, anchor, iterations, borderType, borderValue ); + dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue ); + break; + case CV_MOP_CLOSE: + dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); + erode( dst, dst, kernel, anchor, iterations, borderType, borderValue ); + break; + case CV_MOP_GRADIENT: + erode( src, temp, kernel, anchor, iterations, borderType, borderValue ); + dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); + dst -= temp; + break; + case CV_MOP_TOPHAT: + if( src.data != dst.data ) + temp = dst; + erode( src, temp, kernel, anchor, iterations, borderType, borderValue ); + dilate( temp, temp, kernel, anchor, iterations, borderType, borderValue ); + dst = src - temp; + break; + case CV_MOP_BLACKHAT: + if( src.data != dst.data ) + temp = dst; + dilate( src, temp, kernel, anchor, iterations, borderType, borderValue ); + erode( temp, temp, kernel, anchor, iterations, borderType, borderValue ); + dst = temp - src; + break; + default: + CV_Error( CV_StsBadArg, "unknown morphological operation" ); + } +} + +CV_IMPL IplConvKernel * +cvCreateStructuringElementEx( int cols, int rows, + int anchorX, int anchorY, + int shape, int *values ) +{ + cv::Size ksize = cv::Size(cols, rows); + cv::Point anchor = cv::Point(anchorX, anchorY); + CV_Assert( cols > 0 && rows > 0 && anchor.inside(cv::Rect(0,0,cols,rows)) && + (shape != CV_SHAPE_CUSTOM || values != 0)); + + int i, size = rows * cols; + int element_size = sizeof(IplConvKernel) + size*sizeof(int); + IplConvKernel *element = (IplConvKernel*)cvAlloc(element_size + 32); + + element->nCols = cols; + element->nRows = rows; + element->anchorX = anchorX; + element->anchorY = anchorY; + element->nShiftR = shape < CV_SHAPE_ELLIPSE ? shape : CV_SHAPE_CUSTOM; + element->values = (int*)(element + 1); + + if( shape == CV_SHAPE_CUSTOM ) + { + for( i = 0; i < size; i++ ) + element->values[i] = values[i]; + } + else + { + cv::Mat elem = cv::getStructuringElement(shape, ksize, anchor); + for( i = 0; i < size; i++ ) + element->values[i] = elem.data[i]; + } + + return element; +} + + +CV_IMPL void +cvReleaseStructuringElement( IplConvKernel ** element ) +{ + if( !element ) + CV_Error( CV_StsNullPtr, "" ); + cvFree( element ); +} + + +static void convertConvKernel( const IplConvKernel* src, cv::Mat& dst, cv::Point& anchor ) +{ + if(!src) + { + anchor = cv::Point(1,1); + dst.release(); + return; + } + anchor = cv::Point(src->anchorX, src->anchorY); + dst.create(src->nRows, src->nCols, CV_8U); + + int i, size = src->nRows*src->nCols; + for( i = 0; i < size; i++ ) + dst.data[i] = (uchar)src->values[i]; +} + + +CV_IMPL void +cvErode( const CvArr* srcarr, CvArr* dstarr, IplConvKernel* element, int iterations ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), kernel; + CV_Assert( src.size() == dst.size() && src.type() == dst.type() ); + cv::Point anchor; + convertConvKernel( element, kernel, anchor ); + cv::erode( src, dst, kernel, anchor, iterations, cv::BORDER_REPLICATE ); +} + + +CV_IMPL void +cvDilate( const CvArr* srcarr, CvArr* dstarr, IplConvKernel* element, int iterations ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), kernel; + CV_Assert( src.size() == dst.size() && src.type() == dst.type() ); + cv::Point anchor; + convertConvKernel( element, kernel, anchor ); + cv::dilate( src, dst, kernel, anchor, iterations, cv::BORDER_REPLICATE ); +} + + +CV_IMPL void +cvMorphologyEx( const void* srcarr, void* dstarr, void*, + IplConvKernel* element, int op, int iterations ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), kernel; + CV_Assert( src.size() == dst.size() && src.type() == dst.type() ); + cv::Point anchor; + IplConvKernel* temp_element = NULL; + if (!element) + { + temp_element = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT); + } else { + temp_element = element; + } + convertConvKernel( temp_element, kernel, anchor ); + if (!element) + { + cvReleaseStructuringElement(&temp_element); + } + cv::morphologyEx( src, dst, op, kernel, anchor, iterations, cv::BORDER_REPLICATE ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/phasecorr.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/phasecorr.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/phasecorr.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/phasecorr.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,615 @@ +/********************************************************************* + * Software License Agreement (BSD License) + * + * Copyright (c) 2008-2011, William Lucas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Willow Garage nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************/ + +#include "precomp.hpp" +#include + +namespace cv +{ + +static void magSpectrums( InputArray _src, OutputArray _dst) +{ + Mat src = _src.getMat(); + int depth = src.depth(), cn = src.channels(), type = src.type(); + int rows = src.rows, cols = src.cols; + int j, k; + + CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 ); + + if(src.depth() == CV_32F) + _dst.create( src.rows, src.cols, CV_32FC1 ); + else + _dst.create( src.rows, src.cols, CV_64FC1 ); + + Mat dst = _dst.getMat(); + dst.setTo(0);//Mat elements are not equal to zero by default! + + bool is_1d = (rows == 1 || (cols == 1 && src.isContinuous() && dst.isContinuous())); + + if( is_1d ) + cols = cols + rows - 1, rows = 1; + + int ncols = cols*cn; + int j0 = cn == 1; + int j1 = ncols - (cols % 2 == 0 && cn == 1); + + if( depth == CV_32F ) + { + const float* dataSrc = (const float*)src.data; + float* dataDst = (float*)dst.data; + + size_t stepSrc = src.step/sizeof(dataSrc[0]); + size_t stepDst = dst.step/sizeof(dataDst[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataSrc += cols - 1, dataDst += cols - 1; + dataDst[0] = dataSrc[0]*dataSrc[0]; + if( rows % 2 == 0 ) + dataDst[(rows-1)*stepDst] = dataSrc[(rows-1)*stepSrc]*dataSrc[(rows-1)*stepSrc]; + + for( j = 1; j <= rows - 2; j += 2 ) + { + dataDst[j*stepDst] = (float)std::sqrt((double)dataSrc[j*stepSrc]*dataSrc[j*stepSrc] + + (double)dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc]); + } + + if( k == 1 ) + dataSrc -= cols - 1, dataDst -= cols - 1; + } + } + + for( ; rows--; dataSrc += stepSrc, dataDst += stepDst ) + { + if( is_1d && cn == 1 ) + { + dataDst[0] = dataSrc[0]*dataSrc[0]; + if( cols % 2 == 0 ) + dataDst[j1] = dataSrc[j1]*dataSrc[j1]; + } + + for( j = j0; j < j1; j += 2 ) + { + dataDst[j] = (float)std::sqrt((double)dataSrc[j]*dataSrc[j] + (double)dataSrc[j+1]*dataSrc[j+1]); + } + } + } + else + { + const double* dataSrc = (const double*)src.data; + double* dataDst = (double*)dst.data; + + size_t stepSrc = src.step/sizeof(dataSrc[0]); + size_t stepDst = dst.step/sizeof(dataDst[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataSrc += cols - 1, dataDst += cols - 1; + dataDst[0] = dataSrc[0]*dataSrc[0]; + if( rows % 2 == 0 ) + dataDst[(rows-1)*stepDst] = dataSrc[(rows-1)*stepSrc]*dataSrc[(rows-1)*stepSrc]; + + for( j = 1; j <= rows - 2; j += 2 ) + { + dataDst[j*stepDst] = std::sqrt(dataSrc[j*stepSrc]*dataSrc[j*stepSrc] + + dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc]); + } + + if( k == 1 ) + dataSrc -= cols - 1, dataDst -= cols - 1; + } + } + + for( ; rows--; dataSrc += stepSrc, dataDst += stepDst ) + { + if( is_1d && cn == 1 ) + { + dataDst[0] = dataSrc[0]*dataSrc[0]; + if( cols % 2 == 0 ) + dataDst[j1] = dataSrc[j1]*dataSrc[j1]; + } + + for( j = j0; j < j1; j += 2 ) + { + dataDst[j] = std::sqrt(dataSrc[j]*dataSrc[j] + dataSrc[j+1]*dataSrc[j+1]); + } + } + } +} + +static void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB) +{ + Mat srcA = _srcA.getMat(), srcB = _srcB.getMat(); + int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type(); + int rows = srcA.rows, cols = srcA.cols; + int j, k; + + CV_Assert( type == srcB.type() && srcA.size() == srcB.size() ); + CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 ); + + _dst.create( srcA.rows, srcA.cols, type ); + Mat dst = _dst.getMat(); + + bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 && + srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous())); + + if( is_1d && !(flags & DFT_ROWS) ) + cols = cols + rows - 1, rows = 1; + + int ncols = cols*cn; + int j0 = cn == 1; + int j1 = ncols - (cols % 2 == 0 && cn == 1); + + if( depth == CV_32F ) + { + const float* dataA = (const float*)srcA.data; + const float* dataB = (const float*)srcB.data; + float* dataC = (float*)dst.data; + float eps = FLT_EPSILON; // prevent div0 problems + + size_t stepA = srcA.step/sizeof(dataA[0]); + size_t stepB = srcB.step/sizeof(dataB[0]); + size_t stepC = dst.step/sizeof(dataC[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; + dataC[0] = dataA[0] / (dataB[0] + eps); + if( rows % 2 == 0 ) + dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps); + if( !conjB ) + for( j = 1; j <= rows - 2; j += 2 ) + { + double denom = (double)dataB[j*stepB]*dataB[j*stepB] + + (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps; + + double re = (double)dataA[j*stepA]*dataB[j*stepB] + + (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + + double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] - + (double)dataA[j*stepA]*dataB[(j+1)*stepB]; + + dataC[j*stepC] = (float)(re / denom); + dataC[(j+1)*stepC] = (float)(im / denom); + } + else + for( j = 1; j <= rows - 2; j += 2 ) + { + + double denom = (double)dataB[j*stepB]*dataB[j*stepB] + + (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps; + + double re = (double)dataA[j*stepA]*dataB[j*stepB] - + (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + + double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] + + (double)dataA[j*stepA]*dataB[(j+1)*stepB]; + + dataC[j*stepC] = (float)(re / denom); + dataC[(j+1)*stepC] = (float)(im / denom); + } + if( k == 1 ) + dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; + } + } + + for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) + { + if( is_1d && cn == 1 ) + { + dataC[0] = dataA[0] / (dataB[0] + eps); + if( cols % 2 == 0 ) + dataC[j1] = dataA[j1] / (dataB[j1] + eps); + } + + if( !conjB ) + for( j = j0; j < j1; j += 2 ) + { + double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps); + double re = (double)(dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]); + double im = (double)(dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]); + dataC[j] = (float)(re / denom); + dataC[j+1] = (float)(im / denom); + } + else + for( j = j0; j < j1; j += 2 ) + { + double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps); + double re = (double)(dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]); + double im = (double)(dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]); + dataC[j] = (float)(re / denom); + dataC[j+1] = (float)(im / denom); + } + } + } + else + { + const double* dataA = (const double*)srcA.data; + const double* dataB = (const double*)srcB.data; + double* dataC = (double*)dst.data; + double eps = DBL_EPSILON; // prevent div0 problems + + size_t stepA = srcA.step/sizeof(dataA[0]); + size_t stepB = srcB.step/sizeof(dataB[0]); + size_t stepC = dst.step/sizeof(dataC[0]); + + if( !is_1d && cn == 1 ) + { + for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) + { + if( k == 1 ) + dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; + dataC[0] = dataA[0] / (dataB[0] + eps); + if( rows % 2 == 0 ) + dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps); + if( !conjB ) + for( j = 1; j <= rows - 2; j += 2 ) + { + double denom = dataB[j*stepB]*dataB[j*stepB] + + dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps; + + double re = dataA[j*stepA]*dataB[j*stepB] + + dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + + double im = dataA[(j+1)*stepA]*dataB[j*stepB] - + dataA[j*stepA]*dataB[(j+1)*stepB]; + + dataC[j*stepC] = re / denom; + dataC[(j+1)*stepC] = im / denom; + } + else + for( j = 1; j <= rows - 2; j += 2 ) + { + double denom = dataB[j*stepB]*dataB[j*stepB] + + dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps; + + double re = dataA[j*stepA]*dataB[j*stepB] - + dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; + + double im = dataA[(j+1)*stepA]*dataB[j*stepB] + + dataA[j*stepA]*dataB[(j+1)*stepB]; + + dataC[j*stepC] = re / denom; + dataC[(j+1)*stepC] = im / denom; + } + if( k == 1 ) + dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; + } + } + + for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) + { + if( is_1d && cn == 1 ) + { + dataC[0] = dataA[0] / (dataB[0] + eps); + if( cols % 2 == 0 ) + dataC[j1] = dataA[j1] / (dataB[j1] + eps); + } + + if( !conjB ) + for( j = j0; j < j1; j += 2 ) + { + double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps; + double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]; + double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]; + dataC[j] = re / denom; + dataC[j+1] = im / denom; + } + else + for( j = j0; j < j1; j += 2 ) + { + double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps; + double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]; + double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]; + dataC[j] = re / denom; + dataC[j+1] = im / denom; + } + } + } + +} + +static void fftShift(InputOutputArray _out) +{ + Mat out = _out.getMat(); + + if(out.rows == 1 && out.cols == 1) + { + // trivially shifted. + return; + } + + vector planes; + split(out, planes); + + int xMid = out.cols >> 1; + int yMid = out.rows >> 1; + + bool is_1d = xMid == 0 || yMid == 0; + + if(is_1d) + { + xMid = xMid + yMid; + + for(size_t i = 0; i < planes.size(); i++) + { + Mat tmp; + Mat half0(planes[i], Rect(0, 0, xMid, 1)); + Mat half1(planes[i], Rect(xMid, 0, xMid, 1)); + + half0.copyTo(tmp); + half1.copyTo(half0); + tmp.copyTo(half1); + } + } + else + { + for(size_t i = 0; i < planes.size(); i++) + { + // perform quadrant swaps... + Mat tmp; + Mat q0(planes[i], Rect(0, 0, xMid, yMid)); + Mat q1(planes[i], Rect(xMid, 0, xMid, yMid)); + Mat q2(planes[i], Rect(0, yMid, xMid, yMid)); + Mat q3(planes[i], Rect(xMid, yMid, xMid, yMid)); + + q0.copyTo(tmp); + q3.copyTo(q0); + tmp.copyTo(q3); + + q1.copyTo(tmp); + q2.copyTo(q1); + tmp.copyTo(q2); + } + } + + merge(planes, out); +} + +static Point2d weightedCentroid(InputArray _src, cv::Point peakLocation, cv::Size weightBoxSize, double* response) +{ + Mat src = _src.getMat(); + + int type = src.type(); + CV_Assert( type == CV_32FC1 || type == CV_64FC1 ); + + int minr = peakLocation.y - (weightBoxSize.height >> 1); + int maxr = peakLocation.y + (weightBoxSize.height >> 1); + int minc = peakLocation.x - (weightBoxSize.width >> 1); + int maxc = peakLocation.x + (weightBoxSize.width >> 1); + + Point2d centroid; + double sumIntensity = 0.0; + + // clamp the values to min and max if needed. + if(minr < 0) + { + minr = 0; + } + + if(minc < 0) + { + minc = 0; + } + + if(maxr > src.rows - 1) + { + maxr = src.rows - 1; + } + + if(maxc > src.cols - 1) + { + maxc = src.cols - 1; + } + + if(type == CV_32FC1) + { + const float* dataIn = (const float*)src.data; + dataIn += minr*src.cols; + for(int y = minr; y <= maxr; y++) + { + for(int x = minc; x <= maxc; x++) + { + centroid.x += (double)x*dataIn[x]; + centroid.y += (double)y*dataIn[x]; + sumIntensity += (double)dataIn[x]; + } + + dataIn += src.cols; + } + } + else + { + const double* dataIn = (const double*)src.data; + dataIn += minr*src.cols; + for(int y = minr; y <= maxr; y++) + { + for(int x = minc; x <= maxc; x++) + { + centroid.x += (double)x*dataIn[x]; + centroid.y += (double)y*dataIn[x]; + sumIntensity += dataIn[x]; + } + + dataIn += src.cols; + } + } + + if(response) + *response = sumIntensity; + + sumIntensity += DBL_EPSILON; // prevent div0 problems... + + centroid.x /= sumIntensity; + centroid.y /= sumIntensity; + + return centroid; +} + +} + +cv::Point2d cv::phaseCorrelateRes(InputArray _src1, InputArray _src2, InputArray _window, double* response) +{ + Mat src1 = _src1.getMat(); + Mat src2 = _src2.getMat(); + Mat window = _window.getMat(); + + CV_Assert( src1.type() == src2.type()); + CV_Assert( src1.type() == CV_32FC1 || src1.type() == CV_64FC1 ); + CV_Assert( src1.size == src2.size); + + if(!window.empty()) + { + CV_Assert( src1.type() == window.type()); + CV_Assert( src1.size == window.size); + } + + int M = getOptimalDFTSize(src1.rows); + int N = getOptimalDFTSize(src1.cols); + + Mat padded1, padded2, paddedWin; + + if(M != src1.rows || N != src1.cols) + { + copyMakeBorder(src1, padded1, 0, M - src1.rows, 0, N - src1.cols, BORDER_CONSTANT, Scalar::all(0)); + copyMakeBorder(src2, padded2, 0, M - src2.rows, 0, N - src2.cols, BORDER_CONSTANT, Scalar::all(0)); + + if(!window.empty()) + { + copyMakeBorder(window, paddedWin, 0, M - window.rows, 0, N - window.cols, BORDER_CONSTANT, Scalar::all(0)); + } + } + else + { + padded1 = src1; + padded2 = src2; + paddedWin = window; + } + + Mat FFT1, FFT2, P, Pm, C; + + // perform window multiplication if available + if(!paddedWin.empty()) + { + // apply window to both images before proceeding... + multiply(paddedWin, padded1, padded1); + multiply(paddedWin, padded2, padded2); + } + + // execute phase correlation equation + // Reference: http://en.wikipedia.org/wiki/Phase_correlation + dft(padded1, FFT1, DFT_REAL_OUTPUT); + dft(padded2, FFT2, DFT_REAL_OUTPUT); + + mulSpectrums(FFT1, FFT2, P, 0, true); + + magSpectrums(P, Pm); + divSpectrums(P, Pm, C, 0, false); // FF* / |FF*| (phase correlation equation completed here...) + + idft(C, C); // gives us the nice peak shift location... + + fftShift(C); // shift the energy to the center of the frame. + + // locate the highest peak + Point peakLoc; + minMaxLoc(C, NULL, NULL, NULL, &peakLoc); + + // get the phase shift with sub-pixel accuracy, 5x5 window seems about right here... + Point2d t; + t = weightedCentroid(C, peakLoc, Size(5, 5), response); + + // max response is M*N (not exactly, might be slightly larger due to rounding errors) + if(response) + *response /= M*N; + + // adjust shift relative to image center... + Point2d center((double)padded1.cols / 2.0, (double)padded1.rows / 2.0); + + return (center - t); +} + +cv::Point2d cv::phaseCorrelate(InputArray _src1, InputArray _src2, InputArray _window) +{ + return phaseCorrelateRes(_src1, _src2, _window, 0); +} + +void cv::createHanningWindow(OutputArray _dst, cv::Size winSize, int type) +{ + CV_Assert( type == CV_32FC1 || type == CV_64FC1 ); + + _dst.create(winSize, type); + Mat dst = _dst.getMat(); + + int rows = dst.rows; + int cols = dst.cols; + + if(dst.depth() == CV_32F) + { + for(int i = 0; i < rows; i++) + { + float* dstData = dst.ptr(i); + double wr = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)i / (double)(rows - 1))); + for(int j = 0; j < cols; j++) + { + double wc = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)j / (double)(cols - 1))); + dstData[j] = (float)(wr * wc); + } + } + } + else + { + for(int i = 0; i < rows; i++) + { + double* dstData = dst.ptr(i); + double wr = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)i / (double)(rows - 1))); + for(int j = 0; j < cols; j++) + { + double wc = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)j / (double)(cols - 1))); + dstData[j] = wr * wc; + } + } + } + + // perform batch sqrt for SSE performance gains + cv::sqrt(dst, dst); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/precomp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,44 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/precomp.hpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,156 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_PRECOMP_H__ +#define __OPENCV_PRECOMP_H__ + +#ifdef HAVE_CVCONFIG_H +#include "cvconfig.h" +#endif + +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/core/internal.hpp" +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_TEGRA_OPTIMIZATION +#include "opencv2/imgproc/imgproc_tegra.hpp" +#else +#define GET_OPTIMIZED(func) (func) +#endif + +/* helper tables */ +extern const uchar icvSaturate8u_cv[]; +#define CV_FAST_CAST_8U(t) (assert(-256 <= (t) || (t) <= 512), icvSaturate8u_cv[(t)+256]) +#define CV_CALC_MIN_8U(a,b) (a) -= CV_FAST_CAST_8U((a) - (b)) +#define CV_CALC_MAX_8U(a,b) (a) += CV_FAST_CAST_8U((b) - (a)) + +// -256.f ... 511.f +extern const float icv8x32fTab_cv[]; +#define CV_8TO32F(x) icv8x32fTab_cv[(x)+256] + +// (-128.f)^2 ... (255.f)^2 +extern const float icv8x32fSqrTab[]; +#define CV_8TO32F_SQR(x) icv8x32fSqrTab[(x)+128] + +namespace cv +{ + +static inline Point normalizeAnchor( Point anchor, Size ksize ) +{ + if( anchor.x == -1 ) + anchor.x = ksize.width/2; + if( anchor.y == -1 ) + anchor.y = ksize.height/2; + CV_Assert( anchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); + return anchor; +} + +void preprocess2DKernel( const Mat& kernel, vector& coords, vector& coeffs ); +void crossCorr( const Mat& src, const Mat& templ, Mat& dst, + Size corrsize, int ctype, + Point anchor=Point(0,0), double delta=0, + int borderType=BORDER_REFLECT_101 ); + +} + +typedef struct CvPyramid +{ + uchar **ptr; + CvSize *sz; + double *rate; + int *step; + uchar *state; + int level; +} +CvPyramid; + +#define CV_COPY( dst, src, len, idx ) \ + for( (idx) = 0; (idx) < (len); (idx)++) (dst)[idx] = (src)[idx] + +#define CV_SET( dst, val, len, idx ) \ + for( (idx) = 0; (idx) < (len); (idx)++) (dst)[idx] = (val) + +/* performs convolution of 2d floating-point array with 3x1, 1x3 or separable 3x3 mask */ +void icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step, + CvSize src_size, const float* kx, const float* ky, float* buffer ); + +#undef CV_CALC_MIN +#define CV_CALC_MIN(a, b) if((a) > (b)) (a) = (b) + +#undef CV_CALC_MAX +#define CV_CALC_MAX(a, b) if((a) < (b)) (a) = (b) + +CvStatus CV_STDCALL +icvCopyReplicateBorder_8u( const uchar* src, int srcstep, CvSize srcroi, + uchar* dst, int dststep, CvSize dstroi, + int left, int right, int cn, const uchar* value = 0 ); + +CvStatus CV_STDCALL icvGetRectSubPix_8u_C1R +( const uchar* src, int src_step, CvSize src_size, + uchar* dst, int dst_step, CvSize win_size, CvPoint2D32f center ); +CvStatus CV_STDCALL icvGetRectSubPix_8u32f_C1R +( const uchar* src, int src_step, CvSize src_size, + float* dst, int dst_step, CvSize win_size, CvPoint2D32f center ); +CvStatus CV_STDCALL icvGetRectSubPix_32f_C1R +( const float* src, int src_step, CvSize src_size, + float* dst, int dst_step, CvSize win_size, CvPoint2D32f center ); + +CvStatus CV_STDCALL icvGetQuadrangleSubPix_8u_C1R +( const uchar* src, int src_step, CvSize src_size, + uchar* dst, int dst_step, CvSize win_size, const float *matrix ); +CvStatus CV_STDCALL icvGetQuadrangleSubPix_8u32f_C1R +( const uchar* src, int src_step, CvSize src_size, + float* dst, int dst_step, CvSize win_size, const float *matrix ); +CvStatus CV_STDCALL icvGetQuadrangleSubPix_32f_C1R +( const float* src, int src_step, CvSize src_size, + float* dst, int dst_step, CvSize win_size, const float *matrix ); + +#include "_geom.h" + +#endif /*__OPENCV_CV_INTERNAL_H_*/ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/pyramids.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/pyramids.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/pyramids.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/pyramids.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,580 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +template struct FixPtCast +{ + typedef int type1; + typedef T rtype; + rtype operator ()(type1 arg) const { return (T)((arg + (1 << (shift-1))) >> shift); } +}; + +template struct FltCast +{ + typedef T type1; + typedef T rtype; + rtype operator ()(type1 arg) const { return arg*(T)(1./(1 << shift)); } +}; + +template struct NoVec +{ + int operator()(T1**, T2*, int, int) const { return 0; } +}; + +#if CV_SSE2 + +struct PyrDownVec_32s8u +{ + int operator()(int** src, uchar* dst, int, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE2) ) + return 0; + + int x = 0; + const int *row0 = src[0], *row1 = src[1], *row2 = src[2], *row3 = src[3], *row4 = src[4]; + __m128i delta = _mm_set1_epi16(128); + + for( ; x <= width - 16; x += 16 ) + { + __m128i r0, r1, r2, r3, r4, t0, t1; + r0 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row0 + x)), + _mm_load_si128((const __m128i*)(row0 + x + 4))); + r1 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row1 + x)), + _mm_load_si128((const __m128i*)(row1 + x + 4))); + r2 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row2 + x)), + _mm_load_si128((const __m128i*)(row2 + x + 4))); + r3 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row3 + x)), + _mm_load_si128((const __m128i*)(row3 + x + 4))); + r4 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row4 + x)), + _mm_load_si128((const __m128i*)(row4 + x + 4))); + r0 = _mm_add_epi16(r0, r4); + r1 = _mm_add_epi16(_mm_add_epi16(r1, r3), r2); + r0 = _mm_add_epi16(r0, _mm_add_epi16(r2, r2)); + t0 = _mm_add_epi16(r0, _mm_slli_epi16(r1, 2)); + r0 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row0 + x + 8)), + _mm_load_si128((const __m128i*)(row0 + x + 12))); + r1 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row1 + x + 8)), + _mm_load_si128((const __m128i*)(row1 + x + 12))); + r2 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row2 + x + 8)), + _mm_load_si128((const __m128i*)(row2 + x + 12))); + r3 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row3 + x + 8)), + _mm_load_si128((const __m128i*)(row3 + x + 12))); + r4 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row4 + x + 8)), + _mm_load_si128((const __m128i*)(row4 + x + 12))); + r0 = _mm_add_epi16(r0, r4); + r1 = _mm_add_epi16(_mm_add_epi16(r1, r3), r2); + r0 = _mm_add_epi16(r0, _mm_add_epi16(r2, r2)); + t1 = _mm_add_epi16(r0, _mm_slli_epi16(r1, 2)); + t0 = _mm_srli_epi16(_mm_add_epi16(t0, delta), 8); + t1 = _mm_srli_epi16(_mm_add_epi16(t1, delta), 8); + _mm_storeu_si128((__m128i*)(dst + x), _mm_packus_epi16(t0, t1)); + } + + for( ; x <= width - 4; x += 4 ) + { + __m128i r0, r1, r2, r3, r4, z = _mm_setzero_si128(); + r0 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row0 + x)), z); + r1 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row1 + x)), z); + r2 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row2 + x)), z); + r3 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row3 + x)), z); + r4 = _mm_packs_epi32(_mm_load_si128((const __m128i*)(row4 + x)), z); + r0 = _mm_add_epi16(r0, r4); + r1 = _mm_add_epi16(_mm_add_epi16(r1, r3), r2); + r0 = _mm_add_epi16(r0, _mm_add_epi16(r2, r2)); + r0 = _mm_add_epi16(r0, _mm_slli_epi16(r1, 2)); + r0 = _mm_srli_epi16(_mm_add_epi16(r0, delta), 8); + *(int*)(dst + x) = _mm_cvtsi128_si32(_mm_packus_epi16(r0, r0)); + } + + return x; + } +}; + +struct PyrDownVec_32f +{ + int operator()(float** src, float* dst, int, int width) const + { + if( !checkHardwareSupport(CV_CPU_SSE) ) + return 0; + + int x = 0; + const float *row0 = src[0], *row1 = src[1], *row2 = src[2], *row3 = src[3], *row4 = src[4]; + __m128 _4 = _mm_set1_ps(4.f), _scale = _mm_set1_ps(1.f/256); + for( ; x <= width - 8; x += 8 ) + { + __m128 r0, r1, r2, r3, r4, t0, t1; + r0 = _mm_load_ps(row0 + x); + r1 = _mm_load_ps(row1 + x); + r2 = _mm_load_ps(row2 + x); + r3 = _mm_load_ps(row3 + x); + r4 = _mm_load_ps(row4 + x); + r0 = _mm_add_ps(r0, r4); + r1 = _mm_add_ps(_mm_add_ps(r1, r3), r2); + r0 = _mm_add_ps(r0, _mm_add_ps(r2, r2)); + t0 = _mm_add_ps(r0, _mm_mul_ps(r1, _4)); + + r0 = _mm_load_ps(row0 + x + 4); + r1 = _mm_load_ps(row1 + x + 4); + r2 = _mm_load_ps(row2 + x + 4); + r3 = _mm_load_ps(row3 + x + 4); + r4 = _mm_load_ps(row4 + x + 4); + r0 = _mm_add_ps(r0, r4); + r1 = _mm_add_ps(_mm_add_ps(r1, r3), r2); + r0 = _mm_add_ps(r0, _mm_add_ps(r2, r2)); + t1 = _mm_add_ps(r0, _mm_mul_ps(r1, _4)); + + t0 = _mm_mul_ps(t0, _scale); + t1 = _mm_mul_ps(t1, _scale); + + _mm_storeu_ps(dst + x, t0); + _mm_storeu_ps(dst + x + 4, t1); + } + + return x; + } +}; + +#else + +typedef NoVec PyrDownVec_32s8u; +typedef NoVec PyrDownVec_32f; + +#endif + +template void +pyrDown_( const Mat& _src, Mat& _dst, int borderType ) +{ + const int PD_SZ = 5; + typedef typename CastOp::type1 WT; + typedef typename CastOp::rtype T; + + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + int bufstep = (int)alignSize(dsize.width*cn, 16); + AutoBuffer _buf(bufstep*PD_SZ + 16); + WT* buf = alignPtr((WT*)_buf, 16); + int tabL[CV_CN_MAX*(PD_SZ+2)], tabR[CV_CN_MAX*(PD_SZ+2)]; + AutoBuffer _tabM(dsize.width*cn); + int* tabM = _tabM; + WT* rows[PD_SZ]; + CastOp castOp; + VecOp vecOp; + + CV_Assert( std::abs(dsize.width*2 - ssize.width) <= 2 && + std::abs(dsize.height*2 - ssize.height) <= 2 ); + int k, x, sy0 = -PD_SZ/2, sy = sy0, width0 = std::min((ssize.width-PD_SZ/2-1)/2 + 1, dsize.width); + + for( x = 0; x <= PD_SZ+1; x++ ) + { + int sx0 = borderInterpolate(x - PD_SZ/2, ssize.width, borderType)*cn; + int sx1 = borderInterpolate(x + width0*2 - PD_SZ/2, ssize.width, borderType)*cn; + for( k = 0; k < cn; k++ ) + { + tabL[x*cn + k] = sx0 + k; + tabR[x*cn + k] = sx1 + k; + } + } + + ssize.width *= cn; + dsize.width *= cn; + width0 *= cn; + + for( x = 0; x < dsize.width; x++ ) + tabM[x] = (x/cn)*2*cn + x % cn; + + for( int y = 0; y < dsize.height; y++ ) + { + T* dst = (T*)(_dst.data + _dst.step*y); + WT *row0, *row1, *row2, *row3, *row4; + + // fill the ring buffer (horizontal convolution and decimation) + for( ; sy <= y*2 + 2; sy++ ) + { + WT* row = buf + ((sy - sy0) % PD_SZ)*bufstep; + int _sy = borderInterpolate(sy, ssize.height, borderType); + const T* src = (const T*)(_src.data + _src.step*_sy); + int limit = cn; + const int* tab = tabL; + + for( x = 0;;) + { + for( ; x < limit; x++ ) + { + row[x] = src[tab[x+cn*2]]*6 + (src[tab[x+cn]] + src[tab[x+cn*3]])*4 + + src[tab[x]] + src[tab[x+cn*4]]; + } + + if( x == dsize.width ) + break; + + if( cn == 1 ) + { + for( ; x < width0; x++ ) + row[x] = src[x*2]*6 + (src[x*2 - 1] + src[x*2 + 1])*4 + + src[x*2 - 2] + src[x*2 + 2]; + } + else if( cn == 3 ) + { + for( ; x < width0; x += 3 ) + { + const T* s = src + x*2; + WT t0 = s[0]*6 + (s[-3] + s[3])*4 + s[-6] + s[6]; + WT t1 = s[1]*6 + (s[-2] + s[4])*4 + s[-5] + s[7]; + WT t2 = s[2]*6 + (s[-1] + s[5])*4 + s[-4] + s[8]; + row[x] = t0; row[x+1] = t1; row[x+2] = t2; + } + } + else if( cn == 4 ) + { + for( ; x < width0; x += 4 ) + { + const T* s = src + x*2; + WT t0 = s[0]*6 + (s[-4] + s[4])*4 + s[-8] + s[8]; + WT t1 = s[1]*6 + (s[-3] + s[5])*4 + s[-7] + s[9]; + row[x] = t0; row[x+1] = t1; + t0 = s[2]*6 + (s[-2] + s[6])*4 + s[-6] + s[10]; + t1 = s[3]*6 + (s[-1] + s[7])*4 + s[-5] + s[11]; + row[x+2] = t0; row[x+3] = t1; + } + } + else + { + for( ; x < width0; x++ ) + { + int sx = tabM[x]; + row[x] = src[sx]*6 + (src[sx - cn] + src[sx + cn])*4 + + src[sx - cn*2] + src[sx + cn*2]; + } + } + + limit = dsize.width; + tab = tabR - x; + } + } + + // do vertical convolution and decimation and write the result to the destination image + for( k = 0; k < PD_SZ; k++ ) + rows[k] = buf + ((y*2 - PD_SZ/2 + k - sy0) % PD_SZ)*bufstep; + row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; row3 = rows[3]; row4 = rows[4]; + + x = vecOp(rows, dst, (int)_dst.step, dsize.width); + for( ; x < dsize.width; x++ ) + dst[x] = castOp(row2[x]*6 + (row1[x] + row3[x])*4 + row0[x] + row4[x]); + } +} + + +template void +pyrUp_( const Mat& _src, Mat& _dst, int) +{ + const int PU_SZ = 3; + typedef typename CastOp::type1 WT; + typedef typename CastOp::rtype T; + + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(); + int bufstep = (int)alignSize((dsize.width+1)*cn, 16); + AutoBuffer _buf(bufstep*PU_SZ + 16); + WT* buf = alignPtr((WT*)_buf, 16); + AutoBuffer _dtab(ssize.width*cn); + int* dtab = _dtab; + WT* rows[PU_SZ]; + CastOp castOp; + VecOp vecOp; + + CV_Assert( std::abs(dsize.width - ssize.width*2) == dsize.width % 2 && + std::abs(dsize.height - ssize.height*2) == dsize.height % 2); + int k, x, sy0 = -PU_SZ/2, sy = sy0; + + ssize.width *= cn; + dsize.width *= cn; + + for( x = 0; x < ssize.width; x++ ) + dtab[x] = (x/cn)*2*cn + x % cn; + + for( int y = 0; y < ssize.height; y++ ) + { + T* dst0 = (T*)(_dst.data + _dst.step*y*2); + T* dst1 = (T*)(_dst.data + _dst.step*(y*2+1)); + WT *row0, *row1, *row2; + + if( y*2+1 >= dsize.height ) + dst1 = dst0; + + // fill the ring buffer (horizontal convolution and decimation) + for( ; sy <= y + 1; sy++ ) + { + WT* row = buf + ((sy - sy0) % PU_SZ)*bufstep; + int _sy = borderInterpolate(sy*2, dsize.height, BORDER_REFLECT_101)/2; + const T* src = (const T*)(_src.data + _src.step*_sy); + + if( ssize.width == cn ) + { + for( x = 0; x < cn; x++ ) + row[x] = row[x + cn] = src[x]*8; + continue; + } + + for( x = 0; x < cn; x++ ) + { + int dx = dtab[x]; + WT t0 = src[x]*6 + src[x + cn]*2; + WT t1 = (src[x] + src[x + cn])*4; + row[dx] = t0; row[dx + cn] = t1; + dx = dtab[ssize.width - cn + x]; + int sx = ssize.width - cn + x; + t0 = src[sx - cn] + src[sx]*7; + t1 = src[sx]*8; + row[dx] = t0; row[dx + cn] = t1; + } + + for( x = cn; x < ssize.width - cn; x++ ) + { + int dx = dtab[x]; + WT t0 = src[x-cn] + src[x]*6 + src[x+cn]; + WT t1 = (src[x] + src[x+cn])*4; + row[dx] = t0; + row[dx+cn] = t1; + } + } + + // do vertical convolution and decimation and write the result to the destination image + for( k = 0; k < PU_SZ; k++ ) + rows[k] = buf + ((y - PU_SZ/2 + k - sy0) % PU_SZ)*bufstep; + row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; + + x = vecOp(rows, dst0, (int)_dst.step, dsize.width); + for( ; x < dsize.width; x++ ) + { + T t1 = castOp((row1[x] + row2[x])*4); + T t0 = castOp(row0[x] + row1[x]*6 + row2[x]); + dst1[x] = t1; dst0[x] = t0; + } + } +} + +typedef void (*PyrFunc)(const Mat&, Mat&, int); + +} + +void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType ) +{ + Mat src = _src.getMat(); + Size dsz = _dsz == Size() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz; + _dst.create( dsz, src.type() ); + Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(borderType == BORDER_DEFAULT && tegra::pyrDown(src, dst)) + return; +#endif + + int depth = src.depth(); + PyrFunc func = 0; + if( depth == CV_8U ) + func = pyrDown_, PyrDownVec_32s8u>; + else if( depth == CV_16S ) + func = pyrDown_, NoVec >; + else if( depth == CV_16U ) + func = pyrDown_, NoVec >; + else if( depth == CV_32F ) + func = pyrDown_, PyrDownVec_32f>; + else if( depth == CV_64F ) + func = pyrDown_, NoVec >; + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + func( src, dst, borderType ); +} + +void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType ) +{ + Mat src = _src.getMat(); + Size dsz = _dsz == Size() ? Size(src.cols*2, src.rows*2) : _dsz; + _dst.create( dsz, src.type() ); + Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(borderType == BORDER_DEFAULT && tegra::pyrUp(src, dst)) + return; +#endif + + int depth = src.depth(); + PyrFunc func = 0; + if( depth == CV_8U ) + func = pyrUp_, NoVec >; + else if( depth == CV_16S ) + func = pyrUp_, NoVec >; + else if( depth == CV_16U ) + func = pyrUp_, NoVec >; + else if( depth == CV_32F ) + func = pyrUp_, NoVec >; + else if( depth == CV_64F ) + func = pyrUp_, NoVec >; + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + func( src, dst, borderType ); +} + +void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel, int borderType ) +{ + Mat src = _src.getMat(); + _dst.create( maxlevel + 1, 1, 0 ); + _dst.getMatRef(0) = src; + for( int i = 1; i <= maxlevel; i++ ) + pyrDown( _dst.getMatRef(i-1), _dst.getMatRef(i), Size(), borderType ); +} + +CV_IMPL void cvPyrDown( const void* srcarr, void* dstarr, int _filter ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( _filter == CV_GAUSSIAN_5x5 && src.type() == dst.type()); + cv::pyrDown( src, dst, dst.size() ); +} + +CV_IMPL void cvPyrUp( const void* srcarr, void* dstarr, int _filter ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + + CV_Assert( _filter == CV_GAUSSIAN_5x5 && src.type() == dst.type()); + cv::pyrUp( src, dst, dst.size() ); +} + + +CV_IMPL void +cvReleasePyramid( CvMat*** _pyramid, int extra_layers ) +{ + if( !_pyramid ) + CV_Error( CV_StsNullPtr, "" ); + + if( *_pyramid ) + for( int i = 0; i <= extra_layers; i++ ) + cvReleaseMat( &(*_pyramid)[i] ); + + cvFree( _pyramid ); +} + + +CV_IMPL CvMat** +cvCreatePyramid( const CvArr* srcarr, int extra_layers, double rate, + const CvSize* layer_sizes, CvArr* bufarr, + int calc, int filter ) +{ + const float eps = 0.1f; + uchar* ptr = 0; + + CvMat stub, *src = cvGetMat( srcarr, &stub ); + + if( extra_layers < 0 ) + CV_Error( CV_StsOutOfRange, "The number of extra layers must be non negative" ); + + int i, layer_step, elem_size = CV_ELEM_SIZE(src->type); + CvSize layer_size, size = cvGetMatSize(src); + + if( bufarr ) + { + CvMat bstub, *buf; + int bufsize = 0; + + buf = cvGetMat( bufarr, &bstub ); + bufsize = buf->rows*buf->cols*CV_ELEM_SIZE(buf->type); + layer_size = size; + for( i = 1; i <= extra_layers; i++ ) + { + if( !layer_sizes ) + { + layer_size.width = cvRound(layer_size.width*rate+eps); + layer_size.height = cvRound(layer_size.height*rate+eps); + } + else + layer_size = layer_sizes[i-1]; + layer_step = layer_size.width*elem_size; + bufsize -= layer_step*layer_size.height; + } + + if( bufsize < 0 ) + CV_Error( CV_StsOutOfRange, "The buffer is too small to fit the pyramid" ); + ptr = buf->data.ptr; + } + + CvMat** pyramid = (CvMat**)cvAlloc( (extra_layers+1)*sizeof(pyramid[0]) ); + memset( pyramid, 0, (extra_layers+1)*sizeof(pyramid[0]) ); + + pyramid[0] = cvCreateMatHeader( size.height, size.width, src->type ); + cvSetData( pyramid[0], src->data.ptr, src->step ); + layer_size = size; + + for( i = 1; i <= extra_layers; i++ ) + { + if( !layer_sizes ) + { + layer_size.width = cvRound(layer_size.width*rate + eps); + layer_size.height = cvRound(layer_size.height*rate + eps); + } + else + layer_size = layer_sizes[i]; + + if( bufarr ) + { + pyramid[i] = cvCreateMatHeader( layer_size.height, layer_size.width, src->type ); + layer_step = layer_size.width*elem_size; + cvSetData( pyramid[i], ptr, layer_step ); + ptr += layer_step*layer_size.height; + } + else + pyramid[i] = cvCreateMat( layer_size.height, layer_size.width, src->type ); + + if( calc ) + cvPyrDown( pyramid[i-1], pyramid[i], filter ); + //cvResize( pyramid[i-1], pyramid[i], CV_INTER_LINEAR ); + } + + return pyramid; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/rotcalipers.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/rotcalipers.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/rotcalipers.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/rotcalipers.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,441 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +typedef struct +{ + int bottom; + int left; + float height; + float width; + float base_a; + float base_b; +} +icvMinAreaState; + +#define CV_CALIPERS_MAXHEIGHT 0 +#define CV_CALIPERS_MINAREARECT 1 +#define CV_CALIPERS_MAXDIST 2 + +/*F/////////////////////////////////////////////////////////////////////////////////////// +// Name: icvRotatingCalipers +// Purpose: +// Rotating calipers algorithm with some applications +// +// Context: +// Parameters: +// points - convex hull vertices ( any orientation ) +// n - number of vertices +// mode - concrete application of algorithm +// can be CV_CALIPERS_MAXDIST or +// CV_CALIPERS_MINAREARECT +// left, bottom, right, top - indexes of extremal points +// out - output info. +// In case CV_CALIPERS_MAXDIST it points to float value - +// maximal height of polygon. +// In case CV_CALIPERS_MINAREARECT +// ((CvPoint2D32f*)out)[0] - corner +// ((CvPoint2D32f*)out)[1] - vector1 +// ((CvPoint2D32f*)out)[0] - corner2 +// +// ^ +// | +// vector2 | +// | +// |____________\ +// corner / +// vector1 +// +// Returns: +// Notes: +//F*/ + +/* we will use usual cartesian coordinates */ +static void +icvRotatingCalipers( CvPoint2D32f* points, int n, int mode, float* out ) +{ + float minarea = FLT_MAX; + float max_dist = 0; + char buffer[32] = {}; + int i, k; + CvPoint2D32f* vect = (CvPoint2D32f*)cvAlloc( n * sizeof(vect[0]) ); + float* inv_vect_length = (float*)cvAlloc( n * sizeof(inv_vect_length[0]) ); + int left = 0, bottom = 0, right = 0, top = 0; + int seq[4] = { -1, -1, -1, -1 }; + + /* rotating calipers sides will always have coordinates + (a,b) (-b,a) (-a,-b) (b, -a) + */ + /* this is a first base bector (a,b) initialized by (1,0) */ + float orientation = 0; + float base_a; + float base_b = 0; + + float left_x, right_x, top_y, bottom_y; + CvPoint2D32f pt0 = points[0]; + + left_x = right_x = pt0.x; + top_y = bottom_y = pt0.y; + + for( i = 0; i < n; i++ ) + { + double dx, dy; + + if( pt0.x < left_x ) + left_x = pt0.x, left = i; + + if( pt0.x > right_x ) + right_x = pt0.x, right = i; + + if( pt0.y > top_y ) + top_y = pt0.y, top = i; + + if( pt0.y < bottom_y ) + bottom_y = pt0.y, bottom = i; + + CvPoint2D32f pt = points[(i+1) & (i+1 < n ? -1 : 0)]; + + dx = pt.x - pt0.x; + dy = pt.y - pt0.y; + + vect[i].x = (float)dx; + vect[i].y = (float)dy; + inv_vect_length[i] = (float)(1./sqrt(dx*dx + dy*dy)); + + pt0 = pt; + } + + //cvbInvSqrt( inv_vect_length, inv_vect_length, n ); + + /* find convex hull orientation */ + { + double ax = vect[n-1].x; + double ay = vect[n-1].y; + + for( i = 0; i < n; i++ ) + { + double bx = vect[i].x; + double by = vect[i].y; + + double convexity = ax * by - ay * bx; + + if( convexity != 0 ) + { + orientation = (convexity > 0) ? 1.f : (-1.f); + break; + } + ax = bx; + ay = by; + } + assert( orientation != 0 ); + } + base_a = orientation; + +/*****************************************************************************************/ +/* init calipers position */ + seq[0] = bottom; + seq[1] = right; + seq[2] = top; + seq[3] = left; +/*****************************************************************************************/ +/* Main loop - evaluate angles and rotate calipers */ + + /* all of edges will be checked while rotating calipers by 90 degrees */ + for( k = 0; k < n; k++ ) + { + /* sinus of minimal angle */ + /*float sinus;*/ + + /* compute cosine of angle between calipers side and polygon edge */ + /* dp - dot product */ + float dp0 = base_a * vect[seq[0]].x + base_b * vect[seq[0]].y; + float dp1 = -base_b * vect[seq[1]].x + base_a * vect[seq[1]].y; + float dp2 = -base_a * vect[seq[2]].x - base_b * vect[seq[2]].y; + float dp3 = base_b * vect[seq[3]].x - base_a * vect[seq[3]].y; + + float cosalpha = dp0 * inv_vect_length[seq[0]]; + float maxcos = cosalpha; + + /* number of calipers edges, that has minimal angle with edge */ + int main_element = 0; + + /* choose minimal angle */ + cosalpha = dp1 * inv_vect_length[seq[1]]; + maxcos = (cosalpha > maxcos) ? (main_element = 1, cosalpha) : maxcos; + cosalpha = dp2 * inv_vect_length[seq[2]]; + maxcos = (cosalpha > maxcos) ? (main_element = 2, cosalpha) : maxcos; + cosalpha = dp3 * inv_vect_length[seq[3]]; + maxcos = (cosalpha > maxcos) ? (main_element = 3, cosalpha) : maxcos; + + /*rotate calipers*/ + { + //get next base + int pindex = seq[main_element]; + float lead_x = vect[pindex].x*inv_vect_length[pindex]; + float lead_y = vect[pindex].y*inv_vect_length[pindex]; + switch( main_element ) + { + case 0: + base_a = lead_x; + base_b = lead_y; + break; + case 1: + base_a = lead_y; + base_b = -lead_x; + break; + case 2: + base_a = -lead_x; + base_b = -lead_y; + break; + case 3: + base_a = -lead_y; + base_b = lead_x; + break; + default: assert(0); + } + } + /* change base point of main edge */ + seq[main_element] += 1; + seq[main_element] = (seq[main_element] == n) ? 0 : seq[main_element]; + + + switch (mode) + { + case CV_CALIPERS_MAXHEIGHT: + { + /* now main element lies on edge alligned to calipers side */ + + /* find opposite element i.e. transform */ + /* 0->2, 1->3, 2->0, 3->1 */ + int opposite_el = main_element ^ 2; + + float dx = points[seq[opposite_el]].x - points[seq[main_element]].x; + float dy = points[seq[opposite_el]].y - points[seq[main_element]].y; + float dist; + + if( main_element & 1 ) + dist = (float)fabs(dx * base_a + dy * base_b); + else + dist = (float)fabs(dx * (-base_b) + dy * base_a); + + if( dist > max_dist ) + max_dist = dist; + + break; + } + case CV_CALIPERS_MINAREARECT: + /* find area of rectangle */ + { + float height; + float area; + + /* find vector left-right */ + float dx = points[seq[1]].x - points[seq[3]].x; + float dy = points[seq[1]].y - points[seq[3]].y; + + /* dotproduct */ + float width = dx * base_a + dy * base_b; + + /* find vector left-right */ + dx = points[seq[2]].x - points[seq[0]].x; + dy = points[seq[2]].y - points[seq[0]].y; + + /* dotproduct */ + height = -dx * base_b + dy * base_a; + + area = width * height; + if( area <= minarea ) + { + float *buf = (float *) buffer; + + minarea = area; + /* leftist point */ + ((int *) buf)[0] = seq[3]; + buf[1] = base_a; + buf[2] = width; + buf[3] = base_b; + buf[4] = height; + /* bottom point */ + ((int *) buf)[5] = seq[0]; + buf[6] = area; + } + break; + } + } /*switch */ + } /* for */ + + switch (mode) + { + case CV_CALIPERS_MINAREARECT: + { + float *buf = (float *) buffer; + + float A1 = buf[1]; + float B1 = buf[3]; + + float A2 = -buf[3]; + float B2 = buf[1]; + + float C1 = A1 * points[((int *) buf)[0]].x + points[((int *) buf)[0]].y * B1; + float C2 = A2 * points[((int *) buf)[5]].x + points[((int *) buf)[5]].y * B2; + + float idet = 1.f / (A1 * B2 - A2 * B1); + + float px = (C1 * B2 - C2 * B1) * idet; + float py = (A1 * C2 - A2 * C1) * idet; + + out[0] = px; + out[1] = py; + + out[2] = A1 * buf[2]; + out[3] = B1 * buf[2]; + + out[4] = A2 * buf[4]; + out[5] = B2 * buf[4]; + } + break; + case CV_CALIPERS_MAXHEIGHT: + { + out[0] = max_dist; + } + break; + } + + cvFree( &vect ); + cvFree( &inv_vect_length ); +} + + +CV_IMPL CvBox2D +cvMinAreaRect2( const CvArr* array, CvMemStorage* storage ) +{ + cv::Ptr temp_storage; + CvBox2D box; + cv::AutoBuffer _points; + CvPoint2D32f* points; + + memset(&box, 0, sizeof(box)); + + int i, n; + CvSeqReader reader; + CvContour contour_header; + CvSeqBlock block; + CvSeq* ptseq = (CvSeq*)array; + CvPoint2D32f out[3]; + + if( CV_IS_SEQ(ptseq) ) + { + if( !CV_IS_SEQ_POINT_SET(ptseq) && + (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE || + CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT )) + CV_Error( CV_StsUnsupportedFormat, + "Input sequence must consist of 2d points or pointers to 2d points" ); + if( !storage ) + storage = ptseq->storage; + } + else + { + ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block ); + } + + if( storage ) + { + temp_storage = cvCreateChildMemStorage( storage ); + } + else + { + temp_storage = cvCreateMemStorage(1 << 10); + } + + ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 ); + n = ptseq->total; + + _points.allocate(n); + points = _points; + cvStartReadSeq( ptseq, &reader ); + + if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 ) + { + for( i = 0; i < n; i++ ) + { + CvPoint pt; + CV_READ_SEQ_ELEM( pt, reader ); + points[i].x = (float)pt.x; + points[i].y = (float)pt.y; + } + } + else + { + for( i = 0; i < n; i++ ) + { + CV_READ_SEQ_ELEM( points[i], reader ); + } + } + + if( n > 2 ) + { + icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out ); + box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f; + box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f; + box.size.width = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); + box.size.height = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); + box.angle = (float)atan2( (double)out[1].y, (double)out[1].x ); + } + else if( n == 2 ) + { + box.center.x = (points[0].x + points[1].x)*0.5f; + box.center.y = (points[0].y + points[1].y)*0.5f; + double dx = points[1].x - points[0].x; + double dy = points[1].y - points[0].y; + box.size.width = (float)sqrt(dx*dx + dy*dy); + box.size.height = 0; + box.angle = (float)atan2( dy, dx ); + } + else + { + if( n == 1 ) + box.center = points[0]; + } + + box.angle = (float)(box.angle*180/CV_PI); + return box; +} + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/samplers.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/samplers.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/samplers.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/samplers.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,882 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/**************************************************************************************\ +* line samplers * +\**************************************************************************************/ + +CV_IMPL int +cvSampleLine( const void* img, CvPoint pt1, CvPoint pt2, + void* _buffer, int connectivity ) +{ + int count = -1; + + int i, coi = 0, pix_size; + CvMat stub, *mat = cvGetMat( img, &stub, &coi ); + CvLineIterator iterator; + uchar* buffer = (uchar*)_buffer; + + if( coi != 0 ) + CV_Error( CV_BadCOI, "" ); + + if( !buffer ) + CV_Error( CV_StsNullPtr, "" ); + + count = cvInitLineIterator( mat, pt1, pt2, &iterator, connectivity ); + + pix_size = CV_ELEM_SIZE(mat->type); + for( i = 0; i < count; i++ ) + { + for( int j = 0; j < pix_size; j++ ) + buffer[j] = iterator.ptr[j]; + buffer += pix_size; + CV_NEXT_LINE_POINT( iterator ); + } + + return count; +} + + +static const void* +icvAdjustRect( const void* srcptr, int src_step, int pix_size, + CvSize src_size, CvSize win_size, + CvPoint ip, CvRect* pRect ) +{ + CvRect rect; + const char* src = (const char*)srcptr; + + if( ip.x >= 0 ) + { + src += ip.x*pix_size; + rect.x = 0; + } + else + { + rect.x = -ip.x; + if( rect.x > win_size.width ) + rect.x = win_size.width; + } + + if( ip.x + win_size.width < src_size.width ) + rect.width = win_size.width; + else + { + rect.width = src_size.width - ip.x - 1; + if( rect.width < 0 ) + { + src += rect.width*pix_size; + rect.width = 0; + } + assert( rect.width <= win_size.width ); + } + + if( ip.y >= 0 ) + { + src += ip.y * src_step; + rect.y = 0; + } + else + rect.y = -ip.y; + + if( ip.y + win_size.height < src_size.height ) + rect.height = win_size.height; + else + { + rect.height = src_size.height - ip.y - 1; + if( rect.height < 0 ) + { + src += rect.height*src_step; + rect.height = 0; + } + } + + *pRect = rect; + return src - rect.x*pix_size; +} + + +#define ICV_DEF_GET_RECT_SUB_PIX_FUNC( flavor, srctype, dsttype, worktype, \ + cast_macro, scale_macro, cast_macro2 )\ +CvStatus CV_STDCALL icvGetRectSubPix_##flavor##_C1R \ +( const srctype* src, int src_step, CvSize src_size, \ + dsttype* dst, int dst_step, CvSize win_size, CvPoint2D32f center ) \ +{ \ + CvPoint ip; \ + worktype a11, a12, a21, a22, b1, b2; \ + float a, b; \ + int i, j; \ + \ + center.x -= (win_size.width-1)*0.5f; \ + center.y -= (win_size.height-1)*0.5f; \ + \ + ip.x = cvFloor( center.x ); \ + ip.y = cvFloor( center.y ); \ + \ + a = center.x - ip.x; \ + b = center.y - ip.y; \ + a11 = scale_macro((1.f-a)*(1.f-b)); \ + a12 = scale_macro(a*(1.f-b)); \ + a21 = scale_macro((1.f-a)*b); \ + a22 = scale_macro(a*b); \ + b1 = scale_macro(1.f - b); \ + b2 = scale_macro(b); \ + \ + src_step /= sizeof(src[0]); \ + dst_step /= sizeof(dst[0]); \ + \ + if( 0 <= ip.x && ip.x + win_size.width < src_size.width && \ + 0 <= ip.y && ip.y + win_size.height < src_size.height ) \ + { \ + /* extracted rectangle is totally inside the image */ \ + src += ip.y * src_step + ip.x; \ + \ + for( i = 0; i < win_size.height; i++, src += src_step, \ + dst += dst_step ) \ + { \ + for( j = 0; j <= win_size.width - 2; j += 2 ) \ + { \ + worktype s0 = cast_macro(src[j])*a11 + \ + cast_macro(src[j+1])*a12 + \ + cast_macro(src[j+src_step])*a21 + \ + cast_macro(src[j+src_step+1])*a22; \ + worktype s1 = cast_macro(src[j+1])*a11 + \ + cast_macro(src[j+2])*a12 + \ + cast_macro(src[j+src_step+1])*a21 + \ + cast_macro(src[j+src_step+2])*a22; \ + \ + dst[j] = (dsttype)cast_macro2(s0); \ + dst[j+1] = (dsttype)cast_macro2(s1); \ + } \ + \ + for( ; j < win_size.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[j])*a11 + \ + cast_macro(src[j+1])*a12 + \ + cast_macro(src[j+src_step])*a21 + \ + cast_macro(src[j+src_step+1])*a22; \ + \ + dst[j] = (dsttype)cast_macro2(s0); \ + } \ + } \ + } \ + else \ + { \ + CvRect r; \ + \ + src = (const srctype*)icvAdjustRect( src, src_step*sizeof(*src), \ + sizeof(*src), src_size, win_size,ip, &r); \ + \ + for( i = 0; i < win_size.height; i++, dst += dst_step ) \ + { \ + const srctype *src2 = src + src_step; \ + \ + if( i < r.y || i >= r.height ) \ + src2 -= src_step; \ + \ + for( j = 0; j < r.x; j++ ) \ + { \ + worktype s0 = cast_macro(src[r.x])*b1 + \ + cast_macro(src2[r.x])*b2; \ + \ + dst[j] = (dsttype)cast_macro2(s0); \ + } \ + \ + for( ; j < r.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[j])*a11 + \ + cast_macro(src[j+1])*a12 + \ + cast_macro(src2[j])*a21 + \ + cast_macro(src2[j+1])*a22; \ + \ + dst[j] = (dsttype)cast_macro2(s0); \ + } \ + \ + for( ; j < win_size.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[r.width])*b1 + \ + cast_macro(src2[r.width])*b2; \ + \ + dst[j] = (dsttype)cast_macro2(s0); \ + } \ + \ + if( i < r.height ) \ + src = src2; \ + } \ + } \ + \ + return CV_OK; \ +} + + +#define ICV_DEF_GET_RECT_SUB_PIX_FUNC_C3( flavor, srctype, dsttype, worktype, \ + cast_macro, scale_macro, mul_macro )\ +static CvStatus CV_STDCALL icvGetRectSubPix_##flavor##_C3R \ +( const srctype* src, int src_step, CvSize src_size, \ + dsttype* dst, int dst_step, CvSize win_size, CvPoint2D32f center ) \ +{ \ + CvPoint ip; \ + worktype a, b; \ + int i, j; \ + \ + center.x -= (win_size.width-1)*0.5f; \ + center.y -= (win_size.height-1)*0.5f; \ + \ + ip.x = cvFloor( center.x ); \ + ip.y = cvFloor( center.y ); \ + \ + a = scale_macro( center.x - ip.x ); \ + b = scale_macro( center.y - ip.y ); \ + \ + src_step /= sizeof( src[0] ); \ + dst_step /= sizeof( dst[0] ); \ + \ + if( 0 <= ip.x && ip.x + win_size.width < src_size.width && \ + 0 <= ip.y && ip.y + win_size.height < src_size.height ) \ + { \ + /* extracted rectangle is totally inside the image */ \ + src += ip.y * src_step + ip.x*3; \ + \ + for( i = 0; i < win_size.height; i++, src += src_step, \ + dst += dst_step ) \ + { \ + for( j = 0; j < win_size.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[j*3]); \ + worktype s1 = cast_macro(src[j*3 + src_step]); \ + s0 += mul_macro( a, (cast_macro(src[j*3+3]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src[j*3+3+src_step]) - s1));\ + dst[j*3] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[j*3+1]); \ + s1 = cast_macro(src[j*3+1 + src_step]); \ + s0 += mul_macro( a, (cast_macro(src[j*3+4]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src[j*3+4+src_step]) - s1));\ + dst[j*3+1] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[j*3+2]); \ + s1 = cast_macro(src[j*3+2 + src_step]); \ + s0 += mul_macro( a, (cast_macro(src[j*3+5]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src[j*3+5+src_step]) - s1));\ + dst[j*3+2] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + } \ + } \ + } \ + else \ + { \ + CvRect r; \ + \ + src = (const srctype*)icvAdjustRect( src, src_step*sizeof(*src), \ + sizeof(*src)*3, src_size, win_size, ip, &r ); \ + \ + for( i = 0; i < win_size.height; i++, dst += dst_step ) \ + { \ + const srctype *src2 = src + src_step; \ + \ + if( i < r.y || i >= r.height ) \ + src2 -= src_step; \ + \ + for( j = 0; j < r.x; j++ ) \ + { \ + worktype s0 = cast_macro(src[r.x*3]); \ + worktype s1 = cast_macro(src2[r.x*3]); \ + dst[j*3] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[r.x*3+1]); \ + s1 = cast_macro(src2[r.x*3+1]); \ + dst[j*3+1] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[r.x*3+2]); \ + s1 = cast_macro(src2[r.x*3+2]); \ + dst[j*3+2] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + } \ + \ + for( ; j < r.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[j*3]); \ + worktype s1 = cast_macro(src2[j*3]); \ + s0 += mul_macro( a, (cast_macro(src[j*3 + 3]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src2[j*3 + 3]) - s1)); \ + dst[j*3] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[j*3+1]); \ + s1 = cast_macro(src2[j*3+1]); \ + s0 += mul_macro( a, (cast_macro(src[j*3 + 4]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src2[j*3 + 4]) - s1)); \ + dst[j*3+1] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[j*3+2]); \ + s1 = cast_macro(src2[j*3+2]); \ + s0 += mul_macro( a, (cast_macro(src[j*3 + 5]) - s0)); \ + s1 += mul_macro( a, (cast_macro(src2[j*3 + 5]) - s1)); \ + dst[j*3+2] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + } \ + \ + for( ; j < win_size.width; j++ ) \ + { \ + worktype s0 = cast_macro(src[r.width*3]); \ + worktype s1 = cast_macro(src2[r.width*3]); \ + dst[j*3] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[r.width*3+1]); \ + s1 = cast_macro(src2[r.width*3+1]); \ + dst[j*3+1] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + \ + s0 = cast_macro(src[r.width*3+2]); \ + s1 = cast_macro(src2[r.width*3+2]); \ + dst[j*3+2] = (dsttype)(s0 + mul_macro( b, (s1 - s0))); \ + } \ + \ + if( i < r.height ) \ + src = src2; \ + } \ + } \ + \ + return CV_OK; \ +} + + + +CvStatus CV_STDCALL icvGetRectSubPix_8u32f_C1R +( const uchar* src, int src_step, CvSize src_size, + float* dst, int dst_step, CvSize win_size, CvPoint2D32f center ) +{ + CvPoint ip; + float a12, a22, b1, b2; + float a, b; + double s = 0; + int i, j; + + center.x -= (win_size.width-1)*0.5f; + center.y -= (win_size.height-1)*0.5f; + + ip.x = cvFloor( center.x ); + ip.y = cvFloor( center.y ); + + if( win_size.width <= 0 || win_size.height <= 0 ) + return CV_BADRANGE_ERR; + + a = center.x - ip.x; + b = center.y - ip.y; + a = MAX(a,0.0001f); + a12 = a*(1.f-b); + a22 = a*b; + b1 = 1.f - b; + b2 = b; + s = (1. - a)/a; + + src_step /= sizeof(src[0]); + dst_step /= sizeof(dst[0]); + + if( 0 <= ip.x && ip.x + win_size.width < src_size.width && + 0 <= ip.y && ip.y + win_size.height < src_size.height ) + { + // extracted rectangle is totally inside the image + src += ip.y * src_step + ip.x; + +#if 0 + if( icvCopySubpix_8u32f_C1R_p && + icvCopySubpix_8u32f_C1R_p( src, src_step, dst, + dst_step*sizeof(dst[0]), win_size, a, b ) >= 0 ) + return CV_OK; +#endif + + for( ; win_size.height--; src += src_step, dst += dst_step ) + { + float prev = (1 - a)*(b1*CV_8TO32F(src[0]) + b2*CV_8TO32F(src[src_step])); + for( j = 0; j < win_size.width; j++ ) + { + float t = a12*CV_8TO32F(src[j+1]) + a22*CV_8TO32F(src[j+1+src_step]); + dst[j] = prev + t; + prev = (float)(t*s); + } + } + } + else + { + CvRect r; + + src = (const uchar*)icvAdjustRect( src, src_step*sizeof(*src), + sizeof(*src), src_size, win_size,ip, &r); + + for( i = 0; i < win_size.height; i++, dst += dst_step ) + { + const uchar *src2 = src + src_step; + + if( i < r.y || i >= r.height ) + src2 -= src_step; + + for( j = 0; j < r.x; j++ ) + { + float s0 = CV_8TO32F(src[r.x])*b1 + + CV_8TO32F(src2[r.x])*b2; + + dst[j] = (float)(s0); + } + + if( j < r.width ) + { + float prev = (1 - a)*(b1*CV_8TO32F(src[j]) + b2*CV_8TO32F(src2[j])); + + for( ; j < r.width; j++ ) + { + float t = a12*CV_8TO32F(src[j+1]) + a22*CV_8TO32F(src2[j+1]); + dst[j] = prev + t; + prev = (float)(t*s); + } + } + + for( ; j < win_size.width; j++ ) + { + float s0 = CV_8TO32F(src[r.width])*b1 + + CV_8TO32F(src2[r.width])*b2; + + dst[j] = (float)(s0); + } + + if( i < r.height ) + src = src2; + } + } + + return CV_OK; +} + + + +#define ICV_SHIFT 16 +#define ICV_SCALE(x) cvRound((x)*(1 << ICV_SHIFT)) +#define ICV_MUL_SCALE(x,y) (((x)*(y) + (1 << (ICV_SHIFT-1))) >> ICV_SHIFT) +#define ICV_DESCALE(x) (((x)+(1 << (ICV_SHIFT-1))) >> ICV_SHIFT) + +/*icvCopySubpix_8u_C1R_t icvCopySubpix_8u_C1R_p = 0; +icvCopySubpix_8u32f_C1R_t icvCopySubpix_8u32f_C1R_p = 0; +icvCopySubpix_32f_C1R_t icvCopySubpix_32f_C1R_p = 0;*/ + +ICV_DEF_GET_RECT_SUB_PIX_FUNC( 8u, uchar, uchar, int, CV_NOP, ICV_SCALE, ICV_DESCALE ) +//ICV_DEF_GET_RECT_SUB_PIX_FUNC( 8u32f, uchar, float, float, CV_8TO32F, CV_NOP, CV_NOP ) +ICV_DEF_GET_RECT_SUB_PIX_FUNC( 32f, float, float, float, CV_NOP, CV_NOP, CV_NOP ) + +ICV_DEF_GET_RECT_SUB_PIX_FUNC_C3( 8u, uchar, uchar, int, CV_NOP, ICV_SCALE, ICV_MUL_SCALE ) +ICV_DEF_GET_RECT_SUB_PIX_FUNC_C3( 8u32f, uchar, float, float, CV_8TO32F, CV_NOP, CV_MUL ) +ICV_DEF_GET_RECT_SUB_PIX_FUNC_C3( 32f, float, float, float, CV_NOP, CV_NOP, CV_MUL ) + + +#define ICV_DEF_INIT_SUBPIX_TAB( FUNCNAME, FLAG ) \ +static void icvInit##FUNCNAME##FLAG##Table( CvFuncTable* tab ) \ +{ \ + tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u_##FLAG; \ + tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_##FLAG; \ + \ + tab->fn_2d[1] = (void*)icv##FUNCNAME##_8u32f_##FLAG; \ +} + + +ICV_DEF_INIT_SUBPIX_TAB( GetRectSubPix, C1R ) +ICV_DEF_INIT_SUBPIX_TAB( GetRectSubPix, C3R ) + +typedef CvStatus (CV_STDCALL *CvGetRectSubPixFunc)( const void* src, int src_step, + CvSize src_size, void* dst, + int dst_step, CvSize win_size, + CvPoint2D32f center ); + +CV_IMPL void +cvGetRectSubPix( const void* srcarr, void* dstarr, CvPoint2D32f center ) +{ + static CvFuncTable gr_tab[2]; + static int inittab = 0; + + CvMat srcstub, *src = (CvMat*)srcarr; + CvMat dststub, *dst = (CvMat*)dstarr; + CvSize src_size, dst_size; + CvGetRectSubPixFunc func; + int cn, src_step, dst_step; + + if( !inittab ) + { + icvInitGetRectSubPixC1RTable( gr_tab + 0 ); + icvInitGetRectSubPixC3RTable( gr_tab + 1 ); + inittab = 1; + } + + if( !CV_IS_MAT(src)) + src = cvGetMat( src, &srcstub ); + + if( !CV_IS_MAT(dst)) + dst = cvGetMat( dst, &dststub ); + + cn = CV_MAT_CN( src->type ); + + if( (cn != 1 && cn != 3) || !CV_ARE_CNS_EQ( src, dst )) + CV_Error( CV_StsUnsupportedFormat, "" ); + + src_size = cvGetMatSize( src ); + dst_size = cvGetMatSize( dst ); + src_step = src->step ? src->step : CV_STUB_STEP; + dst_step = dst->step ? dst->step : CV_STUB_STEP; + + //if( dst_size.width > src_size.width || dst_size.height > src_size.height ) + // CV_ERROR( CV_StsBadSize, "destination ROI must be smaller than source ROI" ); + + if( CV_ARE_DEPTHS_EQ( src, dst )) + { + func = (CvGetRectSubPixFunc)(gr_tab[cn != 1].fn_2d[CV_MAT_DEPTH(src->type)]); + } + else + { + if( CV_MAT_DEPTH( src->type ) != CV_8U || CV_MAT_DEPTH( dst->type ) != CV_32F ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + func = (CvGetRectSubPixFunc)(gr_tab[cn != 1].fn_2d[1]); + } + + if( !func ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + IPPI_CALL( func( src->data.ptr, src_step, src_size, + dst->data.ptr, dst_step, dst_size, center )); +} + + +#define ICV_32F8U(x) ((uchar)cvRound(x)) + +#define ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC( flavor, srctype, dsttype, \ + worktype, cast_macro, cvt ) \ +CvStatus CV_STDCALL \ +icvGetQuadrangleSubPix_##flavor##_C1R \ +( const srctype * src, int src_step, CvSize src_size, \ + dsttype *dst, int dst_step, CvSize win_size, const float *matrix ) \ +{ \ + int x, y; \ + double dx = (win_size.width - 1)*0.5; \ + double dy = (win_size.height - 1)*0.5; \ + double A11 = matrix[0], A12 = matrix[1], A13 = matrix[2]-A11*dx-A12*dy; \ + double A21 = matrix[3], A22 = matrix[4], A23 = matrix[5]-A21*dx-A22*dy; \ + \ + src_step /= sizeof(srctype); \ + dst_step /= sizeof(dsttype); \ + \ + for( y = 0; y < win_size.height; y++, dst += dst_step ) \ + { \ + double xs = A12*y + A13; \ + double ys = A22*y + A23; \ + double xe = A11*(win_size.width-1) + A12*y + A13; \ + double ye = A21*(win_size.width-1) + A22*y + A23; \ + \ + if( (unsigned)(cvFloor(xs)-1) < (unsigned)(src_size.width - 3) && \ + (unsigned)(cvFloor(ys)-1) < (unsigned)(src_size.height - 3) && \ + (unsigned)(cvFloor(xe)-1) < (unsigned)(src_size.width - 3) && \ + (unsigned)(cvFloor(ye)-1) < (unsigned)(src_size.height - 3)) \ + { \ + for( x = 0; x < win_size.width; x++ ) \ + { \ + int ixs = cvFloor( xs ); \ + int iys = cvFloor( ys ); \ + const srctype *ptr = src + src_step*iys + ixs; \ + double a = xs - ixs, b = ys - iys, a1 = 1.f - a; \ + worktype p0 = cvt(ptr[0])*a1 + cvt(ptr[1])*a; \ + worktype p1 = cvt(ptr[src_step])*a1 + cvt(ptr[src_step+1])*a;\ + xs += A11; \ + ys += A21; \ + \ + dst[x] = cast_macro(p0 + b * (p1 - p0)); \ + } \ + } \ + else \ + { \ + for( x = 0; x < win_size.width; x++ ) \ + { \ + int ixs = cvFloor( xs ), iys = cvFloor( ys ); \ + double a = xs - ixs, b = ys - iys, a1 = 1.f - a; \ + const srctype *ptr0, *ptr1; \ + worktype p0, p1; \ + xs += A11; ys += A21; \ + \ + if( (unsigned)iys < (unsigned)(src_size.height-1) ) \ + ptr0 = src + src_step*iys, ptr1 = ptr0 + src_step; \ + else \ + ptr0 = ptr1 = src + (iys < 0 ? 0 : src_size.height-1)*src_step; \ + \ + if( (unsigned)ixs < (unsigned)(src_size.width-1) ) \ + { \ + p0 = cvt(ptr0[ixs])*a1 + cvt(ptr0[ixs+1])*a; \ + p1 = cvt(ptr1[ixs])*a1 + cvt(ptr1[ixs+1])*a; \ + } \ + else \ + { \ + ixs = ixs < 0 ? 0 : src_size.width - 1; \ + p0 = cvt(ptr0[ixs]); p1 = cvt(ptr1[ixs]); \ + } \ + dst[x] = cast_macro(p0 + b * (p1 - p0)); \ + } \ + } \ + } \ + \ + return CV_OK; \ +} + + +#define ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC_C3( flavor, srctype, dsttype, \ + worktype, cast_macro, cvt ) \ +static CvStatus CV_STDCALL \ +icvGetQuadrangleSubPix_##flavor##_C3R \ +( const srctype * src, int src_step, CvSize src_size, \ + dsttype *dst, int dst_step, CvSize win_size, const float *matrix ) \ +{ \ + int x, y; \ + double dx = (win_size.width - 1)*0.5; \ + double dy = (win_size.height - 1)*0.5; \ + double A11 = matrix[0], A12 = matrix[1], A13 = matrix[2]-A11*dx-A12*dy; \ + double A21 = matrix[3], A22 = matrix[4], A23 = matrix[5]-A21*dx-A22*dy; \ + \ + src_step /= sizeof(srctype); \ + dst_step /= sizeof(dsttype); \ + \ + for( y = 0; y < win_size.height; y++, dst += dst_step ) \ + { \ + double xs = A12*y + A13; \ + double ys = A22*y + A23; \ + double xe = A11*(win_size.width-1) + A12*y + A13; \ + double ye = A21*(win_size.width-1) + A22*y + A23; \ + \ + if( (unsigned)(cvFloor(xs)-1) < (unsigned)(src_size.width - 3) && \ + (unsigned)(cvFloor(ys)-1) < (unsigned)(src_size.height - 3) && \ + (unsigned)(cvFloor(xe)-1) < (unsigned)(src_size.width - 3) && \ + (unsigned)(cvFloor(ye)-1) < (unsigned)(src_size.height - 3)) \ + { \ + for( x = 0; x < win_size.width; x++ ) \ + { \ + int ixs = cvFloor( xs ); \ + int iys = cvFloor( ys ); \ + const srctype *ptr = src + src_step*iys + ixs*3; \ + double a = xs - ixs, b = ys - iys, a1 = 1.f - a; \ + worktype p0, p1; \ + xs += A11; \ + ys += A21; \ + \ + p0 = cvt(ptr[0])*a1 + cvt(ptr[3])*a; \ + p1 = cvt(ptr[src_step])*a1 + cvt(ptr[src_step+3])*a; \ + dst[x*3] = cast_macro(p0 + b * (p1 - p0)); \ + \ + p0 = cvt(ptr[1])*a1 + cvt(ptr[4])*a; \ + p1 = cvt(ptr[src_step+1])*a1 + cvt(ptr[src_step+4])*a; \ + dst[x*3+1] = cast_macro(p0 + b * (p1 - p0)); \ + \ + p0 = cvt(ptr[2])*a1 + cvt(ptr[5])*a; \ + p1 = cvt(ptr[src_step+2])*a1 + cvt(ptr[src_step+5])*a; \ + dst[x*3+2] = cast_macro(p0 + b * (p1 - p0)); \ + } \ + } \ + else \ + { \ + for( x = 0; x < win_size.width; x++ ) \ + { \ + int ixs = cvFloor(xs), iys = cvFloor(ys); \ + double a = xs - ixs, b = ys - iys; \ + const srctype *ptr0, *ptr1; \ + xs += A11; ys += A21; \ + \ + if( (unsigned)iys < (unsigned)(src_size.height-1) ) \ + ptr0 = src + src_step*iys, ptr1 = ptr0 + src_step; \ + else \ + ptr0 = ptr1 = src + (iys < 0 ? 0 : src_size.height-1)*src_step; \ + \ + if( (unsigned)ixs < (unsigned)(src_size.width - 1) ) \ + { \ + double a1 = 1.f - a; \ + worktype p0, p1; \ + ptr0 += ixs*3; ptr1 += ixs*3; \ + p0 = cvt(ptr0[0])*a1 + cvt(ptr0[3])*a; \ + p1 = cvt(ptr1[0])*a1 + cvt(ptr1[3])*a; \ + dst[x*3] = cast_macro(p0 + b * (p1 - p0)); \ + \ + p0 = cvt(ptr0[1])*a1 + cvt(ptr0[4])*a; \ + p1 = cvt(ptr1[1])*a1 + cvt(ptr1[4])*a; \ + dst[x*3+1] = cast_macro(p0 + b * (p1 - p0)); \ + \ + p0 = cvt(ptr0[2])*a1 + cvt(ptr0[5])*a; \ + p1 = cvt(ptr1[2])*a1 + cvt(ptr1[5])*a; \ + dst[x*3+2] = cast_macro(p0 + b * (p1 - p0)); \ + } \ + else \ + { \ + double b1 = 1.f - b; \ + ixs = ixs < 0 ? 0 : src_size.width - 1; \ + ptr0 += ixs*3; ptr1 += ixs*3; \ + \ + dst[x*3] = cast_macro(cvt(ptr0[0])*b1 + cvt(ptr1[0])*b);\ + dst[x*3+1]=cast_macro(cvt(ptr0[1])*b1 + cvt(ptr1[1])*b);\ + dst[x*3+2]=cast_macro(cvt(ptr0[2])*b1 + cvt(ptr1[2])*b);\ + } \ + } \ + } \ + } \ + \ + return CV_OK; \ +} + + +/*#define srctype uchar +#define dsttype uchar +#define worktype float +#define cvt CV_8TO32F +#define cast_macro ICV_32F8U + +#undef srctype +#undef dsttype +#undef worktype +#undef cvt +#undef cast_macro*/ + +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC( 8u, uchar, uchar, double, ICV_32F8U, CV_8TO32F ) +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC( 32f, float, float, double, CV_CAST_32F, CV_NOP ) +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC( 8u32f, uchar, float, double, CV_CAST_32F, CV_8TO32F ) + +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC_C3( 8u, uchar, uchar, double, ICV_32F8U, CV_8TO32F ) +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC_C3( 32f, float, float, double, CV_CAST_32F, CV_NOP ) +ICV_DEF_GET_QUADRANGLE_SUB_PIX_FUNC_C3( 8u32f, uchar, float, double, CV_CAST_32F, CV_8TO32F ) + +ICV_DEF_INIT_SUBPIX_TAB( GetQuadrangleSubPix, C1R ) +ICV_DEF_INIT_SUBPIX_TAB( GetQuadrangleSubPix, C3R ) + +typedef CvStatus (CV_STDCALL *CvGetQuadrangleSubPixFunc)( + const void* src, int src_step, + CvSize src_size, void* dst, + int dst_step, CvSize win_size, + const float* matrix ); + +CV_IMPL void +cvGetQuadrangleSubPix( const void* srcarr, void* dstarr, const CvMat* mat ) +{ + static CvFuncTable gq_tab[2]; + static int inittab = 0; + + CvMat srcstub, *src = (CvMat*)srcarr; + CvMat dststub, *dst = (CvMat*)dstarr; + CvSize src_size, dst_size; + CvGetQuadrangleSubPixFunc func; + float m[6]; + int k, cn; + + if( !inittab ) + { + icvInitGetQuadrangleSubPixC1RTable( gq_tab + 0 ); + icvInitGetQuadrangleSubPixC3RTable( gq_tab + 1 ); + inittab = 1; + } + + if( !CV_IS_MAT(src)) + src = cvGetMat( src, &srcstub ); + + if( !CV_IS_MAT(dst)) + dst = cvGetMat( dst, &dststub ); + + if( !CV_IS_MAT(mat)) + CV_Error( CV_StsBadArg, "map matrix is not valid" ); + + cn = CV_MAT_CN( src->type ); + + if( (cn != 1 && cn != 3) || !CV_ARE_CNS_EQ( src, dst )) + CV_Error( CV_StsUnsupportedFormat, "" ); + + src_size = cvGetMatSize( src ); + dst_size = cvGetMatSize( dst ); + + /*if( dst_size.width > src_size.width || dst_size.height > src_size.height ) + CV_ERROR( CV_StsBadSize, "destination ROI must not be larger than source ROI" );*/ + + if( mat->rows != 2 || mat->cols != 3 ) + CV_Error( CV_StsBadArg, + "Transformation matrix must be 2x3" ); + + if( CV_MAT_TYPE( mat->type ) == CV_32FC1 ) + { + for( k = 0; k < 3; k++ ) + { + m[k] = mat->data.fl[k]; + m[3 + k] = ((float*)(mat->data.ptr + mat->step))[k]; + } + } + else if( CV_MAT_TYPE( mat->type ) == CV_64FC1 ) + { + for( k = 0; k < 3; k++ ) + { + m[k] = (float)mat->data.db[k]; + m[3 + k] = (float)((double*)(mat->data.ptr + mat->step))[k]; + } + } + else + CV_Error( CV_StsUnsupportedFormat, + "The transformation matrix should have 32fC1 or 64fC1 type" ); + + if( CV_ARE_DEPTHS_EQ( src, dst )) + { + func = (CvGetQuadrangleSubPixFunc)(gq_tab[cn != 1].fn_2d[CV_MAT_DEPTH(src->type)]); + } + else + { + if( CV_MAT_DEPTH( src->type ) != CV_8U || CV_MAT_DEPTH( dst->type ) != CV_32F ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + func = (CvGetQuadrangleSubPixFunc)(gq_tab[cn != 1].fn_2d[1]); + } + + if( !func ) + CV_Error( CV_StsUnsupportedFormat, "" ); + + IPPI_CALL( func( src->data.ptr, src->step, src_size, + dst->data.ptr, dst->step, dst_size, m )); +} + + +void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center, + OutputArray _patch, int patchType ) +{ + Mat image = _image.getMat(); + _patch.create(patchSize, patchType < 0 ? image.type() : + CV_MAKETYPE(CV_MAT_DEPTH(patchType),image.channels())); + Mat patch = _patch.getMat(); + CvMat _cimage = image, _cpatch = patch; + cvGetRectSubPix(&_cimage, &_cpatch, center); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/segmentation.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/segmentation.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/segmentation.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/segmentation.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,541 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/****************************************************************************************\ +* Watershed * +\****************************************************************************************/ + +typedef struct CvWSNode +{ + struct CvWSNode* next; + int mask_ofs; + int img_ofs; +} +CvWSNode; + +typedef struct CvWSQueue +{ + CvWSNode* first; + CvWSNode* last; +} +CvWSQueue; + +static CvWSNode* +icvAllocWSNodes( CvMemStorage* storage ) +{ + CvWSNode* n = 0; + + int i, count = (storage->block_size - sizeof(CvMemBlock))/sizeof(*n) - 1; + + n = (CvWSNode*)cvMemStorageAlloc( storage, count*sizeof(*n) ); + for( i = 0; i < count-1; i++ ) + n[i].next = n + i + 1; + n[count-1].next = 0; + + return n; +} + + +CV_IMPL void +cvWatershed( const CvArr* srcarr, CvArr* dstarr ) +{ + const int IN_QUEUE = -2; + const int WSHED = -1; + const int NQ = 256; + cv::Ptr storage; + + CvMat sstub, *src; + CvMat dstub, *dst; + CvSize size; + CvWSNode* free_node = 0, *node; + CvWSQueue q[NQ]; + int active_queue; + int i, j; + int db, dg, dr; + int* mask; + uchar* img; + int mstep, istep; + int subs_tab[513]; + + // MAX(a,b) = b + MAX(a-b,0) + #define ws_max(a,b) ((b) + subs_tab[(a)-(b)+NQ]) + // MIN(a,b) = a - MAX(a-b,0) + #define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ]) + + #define ws_push(idx,mofs,iofs) \ + { \ + if( !free_node ) \ + free_node = icvAllocWSNodes( storage );\ + node = free_node; \ + free_node = free_node->next;\ + node->next = 0; \ + node->mask_ofs = mofs; \ + node->img_ofs = iofs; \ + if( q[idx].last ) \ + q[idx].last->next=node; \ + else \ + q[idx].first = node; \ + q[idx].last = node; \ + } + + #define ws_pop(idx,mofs,iofs) \ + { \ + node = q[idx].first; \ + q[idx].first = node->next; \ + if( !node->next ) \ + q[idx].last = 0; \ + node->next = free_node; \ + free_node = node; \ + mofs = node->mask_ofs; \ + iofs = node->img_ofs; \ + } + + #define c_diff(ptr1,ptr2,diff) \ + { \ + db = abs((ptr1)[0] - (ptr2)[0]);\ + dg = abs((ptr1)[1] - (ptr2)[1]);\ + dr = abs((ptr1)[2] - (ptr2)[2]);\ + diff = ws_max(db,dg); \ + diff = ws_max(diff,dr); \ + assert( 0 <= diff && diff <= 255 ); \ + } + + src = cvGetMat( srcarr, &sstub ); + dst = cvGetMat( dstarr, &dstub ); + + if( CV_MAT_TYPE(src->type) != CV_8UC3 ) + CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel input images are supported" ); + + if( CV_MAT_TYPE(dst->type) != CV_32SC1 ) + CV_Error( CV_StsUnsupportedFormat, + "Only 32-bit, 1-channel output images are supported" ); + + if( !CV_ARE_SIZES_EQ( src, dst )) + CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); + + size = cvGetMatSize(src); + storage = cvCreateMemStorage(); + + istep = src->step; + img = src->data.ptr; + mstep = dst->step / sizeof(mask[0]); + mask = dst->data.i; + + memset( q, 0, NQ*sizeof(q[0]) ); + + for( i = 0; i < 256; i++ ) + subs_tab[i] = 0; + for( i = 256; i <= 512; i++ ) + subs_tab[i] = i - 256; + + // draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels + for( j = 0; j < size.width; j++ ) + mask[j] = mask[j + mstep*(size.height-1)] = WSHED; + + // initial phase: put all the neighbor pixels of each marker to the ordered queue - + // determine the initial boundaries of the basins + for( i = 1; i < size.height-1; i++ ) + { + img += istep; mask += mstep; + mask[0] = mask[size.width-1] = WSHED; + + for( j = 1; j < size.width-1; j++ ) + { + int* m = mask + j; + if( m[0] < 0 ) m[0] = 0; + if( m[0] == 0 && (m[-1] > 0 || m[1] > 0 || m[-mstep] > 0 || m[mstep] > 0) ) + { + uchar* ptr = img + j*3; + int idx = 256, t; + if( m[-1] > 0 ) + c_diff( ptr, ptr - 3, idx ); + if( m[1] > 0 ) + { + c_diff( ptr, ptr + 3, t ); + idx = ws_min( idx, t ); + } + if( m[-mstep] > 0 ) + { + c_diff( ptr, ptr - istep, t ); + idx = ws_min( idx, t ); + } + if( m[mstep] > 0 ) + { + c_diff( ptr, ptr + istep, t ); + idx = ws_min( idx, t ); + } + assert( 0 <= idx && idx <= 255 ); + ws_push( idx, i*mstep + j, i*istep + j*3 ); + m[0] = IN_QUEUE; + } + } + } + + // find the first non-empty queue + for( i = 0; i < NQ; i++ ) + if( q[i].first ) + break; + + // if there is no markers, exit immediately + if( i == NQ ) + return; + + active_queue = i; + img = src->data.ptr; + mask = dst->data.i; + + // recursively fill the basins + for(;;) + { + int mofs, iofs; + int lab = 0, t; + int* m; + uchar* ptr; + + if( q[active_queue].first == 0 ) + { + for( i = active_queue+1; i < NQ; i++ ) + if( q[i].first ) + break; + if( i == NQ ) + break; + active_queue = i; + } + + ws_pop( active_queue, mofs, iofs ); + + m = mask + mofs; + ptr = img + iofs; + t = m[-1]; + if( t > 0 ) lab = t; + t = m[1]; + if( t > 0 ) + { + if( lab == 0 ) lab = t; + else if( t != lab ) lab = WSHED; + } + t = m[-mstep]; + if( t > 0 ) + { + if( lab == 0 ) lab = t; + else if( t != lab ) lab = WSHED; + } + t = m[mstep]; + if( t > 0 ) + { + if( lab == 0 ) lab = t; + else if( t != lab ) lab = WSHED; + } + assert( lab != 0 ); + m[0] = lab; + if( lab == WSHED ) + continue; + + if( m[-1] == 0 ) + { + c_diff( ptr, ptr - 3, t ); + ws_push( t, mofs - 1, iofs - 3 ); + active_queue = ws_min( active_queue, t ); + m[-1] = IN_QUEUE; + } + if( m[1] == 0 ) + { + c_diff( ptr, ptr + 3, t ); + ws_push( t, mofs + 1, iofs + 3 ); + active_queue = ws_min( active_queue, t ); + m[1] = IN_QUEUE; + } + if( m[-mstep] == 0 ) + { + c_diff( ptr, ptr - istep, t ); + ws_push( t, mofs - mstep, iofs - istep ); + active_queue = ws_min( active_queue, t ); + m[-mstep] = IN_QUEUE; + } + if( m[mstep] == 0 ) + { + c_diff( ptr, ptr + istep, t ); + ws_push( t, mofs + mstep, iofs + istep ); + active_queue = ws_min( active_queue, t ); + m[mstep] = IN_QUEUE; + } + } +} + + +void cv::watershed( InputArray _src, InputOutputArray markers ) +{ + Mat src = _src.getMat(); + CvMat c_src = _src.getMat(), c_markers = markers.getMat(); + cvWatershed( &c_src, &c_markers ); +} + + +/****************************************************************************************\ +* Meanshift * +\****************************************************************************************/ + +CV_IMPL void +cvPyrMeanShiftFiltering( const CvArr* srcarr, CvArr* dstarr, + double sp0, double sr, int max_level, + CvTermCriteria termcrit ) +{ + const int cn = 3; + const int MAX_LEVELS = 8; + + if( (unsigned)max_level > (unsigned)MAX_LEVELS ) + CV_Error( CV_StsOutOfRange, "The number of pyramid levels is too large or negative" ); + + std::vector src_pyramid(max_level+1); + std::vector dst_pyramid(max_level+1); + cv::Mat mask0; + int i, j, level; + //uchar* submask = 0; + + #define cdiff(ofs0) (tab[c0-dptr[ofs0]+255] + \ + tab[c1-dptr[(ofs0)+1]+255] + tab[c2-dptr[(ofs0)+2]+255] >= isr22) + + double sr2 = sr * sr; + int isr2 = cvRound(sr2), isr22 = MAX(isr2,16); + int tab[768]; + cv::Mat src0 = cv::cvarrToMat(srcarr); + cv::Mat dst0 = cv::cvarrToMat(dstarr); + + if( src0.type() != CV_8UC3 ) + CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); + + if( src0.type() != dst0.type() ) + CV_Error( CV_StsUnmatchedFormats, "The input and output images must have the same type" ); + + if( src0.size() != dst0.size() ) + CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); + + if( !(termcrit.type & CV_TERMCRIT_ITER) ) + termcrit.max_iter = 5; + termcrit.max_iter = MAX(termcrit.max_iter,1); + termcrit.max_iter = MIN(termcrit.max_iter,100); + if( !(termcrit.type & CV_TERMCRIT_EPS) ) + termcrit.epsilon = 1.f; + termcrit.epsilon = MAX(termcrit.epsilon, 0.f); + + for( i = 0; i < 768; i++ ) + tab[i] = (i - 255)*(i - 255); + + // 1. construct pyramid + src_pyramid[0] = src0; + dst_pyramid[0] = dst0; + for( level = 1; level <= max_level; level++ ) + { + src_pyramid[level].create( (src_pyramid[level-1].rows+1)/2, + (src_pyramid[level-1].cols+1)/2, src_pyramid[level-1].type() ); + dst_pyramid[level].create( src_pyramid[level].rows, + src_pyramid[level].cols, src_pyramid[level].type() ); + cv::pyrDown( src_pyramid[level-1], src_pyramid[level], src_pyramid[level].size() ); + //CV_CALL( cvResize( src_pyramid[level-1], src_pyramid[level], CV_INTER_AREA )); + } + + mask0.create(src0.rows, src0.cols, CV_8UC1); + //CV_CALL( submask = (uchar*)cvAlloc( (sp+2)*(sp+2) )); + + // 2. apply meanshift, starting from the pyramid top (i.e. the smallest layer) + for( level = max_level; level >= 0; level-- ) + { + cv::Mat src = src_pyramid[level]; + cv::Size size = src.size(); + uchar* sptr = src.data; + int sstep = (int)src.step; + uchar* mask = 0; + int mstep = 0; + uchar* dptr; + int dstep; + float sp = (float)(sp0 / (1 << level)); + sp = MAX( sp, 1 ); + + if( level < max_level ) + { + cv::Size size1 = dst_pyramid[level+1].size(); + cv::Mat m( size.height, size.width, CV_8UC1, mask0.data ); + dstep = (int)dst_pyramid[level+1].step; + dptr = dst_pyramid[level+1].data + dstep + cn; + mstep = (int)m.step; + mask = m.data + mstep; + //cvResize( dst_pyramid[level+1], dst_pyramid[level], CV_INTER_CUBIC ); + cv::pyrUp( dst_pyramid[level+1], dst_pyramid[level], dst_pyramid[level].size() ); + m.setTo(cv::Scalar::all(0)); + + for( i = 1; i < size1.height-1; i++, dptr += dstep - (size1.width-2)*3, mask += mstep*2 ) + { + for( j = 1; j < size1.width-1; j++, dptr += cn ) + { + int c0 = dptr[0], c1 = dptr[1], c2 = dptr[2]; + mask[j*2 - 1] = cdiff(-3) || cdiff(3) || cdiff(-dstep-3) || cdiff(-dstep) || + cdiff(-dstep+3) || cdiff(dstep-3) || cdiff(dstep) || cdiff(dstep+3); + } + } + + cv::dilate( m, m, cv::Mat() ); + mask = m.data; + } + + dptr = dst_pyramid[level].data; + dstep = (int)dst_pyramid[level].step; + + for( i = 0; i < size.height; i++, sptr += sstep - size.width*3, + dptr += dstep - size.width*3, + mask += mstep ) + { + for( j = 0; j < size.width; j++, sptr += 3, dptr += 3 ) + { + int x0 = j, y0 = i, x1, y1, iter; + int c0, c1, c2; + + if( mask && !mask[j] ) + continue; + + c0 = sptr[0], c1 = sptr[1], c2 = sptr[2]; + + // iterate meanshift procedure + for( iter = 0; iter < termcrit.max_iter; iter++ ) + { + uchar* ptr; + int x, y, count = 0; + int minx, miny, maxx, maxy; + int s0 = 0, s1 = 0, s2 = 0, sx = 0, sy = 0; + double icount; + int stop_flag; + + //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp) + minx = cvRound(x0 - sp); minx = MAX(minx, 0); + miny = cvRound(y0 - sp); miny = MAX(miny, 0); + maxx = cvRound(x0 + sp); maxx = MIN(maxx, size.width-1); + maxy = cvRound(y0 + sp); maxy = MIN(maxy, size.height-1); + ptr = sptr + (miny - i)*sstep + (minx - j)*3; + + for( y = miny; y <= maxy; y++, ptr += sstep - (maxx-minx+1)*3 ) + { + int row_count = 0; + x = minx; + #if CV_ENABLE_UNROLLED + for( ; x + 3 <= maxx; x += 4, ptr += 12 ) + { + int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2]; + if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) + { + s0 += t0; s1 += t1; s2 += t2; + sx += x; row_count++; + } + t0 = ptr[3], t1 = ptr[4], t2 = ptr[5]; + if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) + { + s0 += t0; s1 += t1; s2 += t2; + sx += x+1; row_count++; + } + t0 = ptr[6], t1 = ptr[7], t2 = ptr[8]; + if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) + { + s0 += t0; s1 += t1; s2 += t2; + sx += x+2; row_count++; + } + t0 = ptr[9], t1 = ptr[10], t2 = ptr[11]; + if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) + { + s0 += t0; s1 += t1; s2 += t2; + sx += x+3; row_count++; + } + } + #endif + for( ; x <= maxx; x++, ptr += 3 ) + { + int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2]; + if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) + { + s0 += t0; s1 += t1; s2 += t2; + sx += x; row_count++; + } + } + count += row_count; + sy += y*row_count; + } + + if( count == 0 ) + break; + + icount = 1./count; + x1 = cvRound(sx*icount); + y1 = cvRound(sy*icount); + s0 = cvRound(s0*icount); + s1 = cvRound(s1*icount); + s2 = cvRound(s2*icount); + + stop_flag = (x0 == x1 && y0 == y1) || abs(x1-x0) + abs(y1-y0) + + tab[s0 - c0 + 255] + tab[s1 - c1 + 255] + + tab[s2 - c2 + 255] <= termcrit.epsilon; + + x0 = x1; y0 = y1; + c0 = s0; c1 = s1; c2 = s2; + + if( stop_flag ) + break; + } + + dptr[0] = (uchar)c0; + dptr[1] = (uchar)c1; + dptr[2] = (uchar)c2; + } + } + } +} + +void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, + double sp, double sr, int maxLevel, + TermCriteria termcrit ) +{ + Mat src = _src.getMat(); + + if( src.empty() ) + return; + + _dst.create( src.size(), src.type() ); + CvMat c_src = src, c_dst = _dst.getMat(); + cvPyrMeanShiftFiltering( &c_src, &c_dst, sp, sr, maxLevel, termcrit ); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/shapedescr.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/shapedescr.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/shapedescr.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/shapedescr.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1186 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +/* calculates length of a curve (e.g. contour perimeter) */ +CV_IMPL double +cvArcLength( const void *array, CvSlice slice, int is_closed ) +{ + double perimeter = 0; + + int i, j = 0, count; + const int N = 16; + float buf[N]; + CvMat buffer = cvMat( 1, N, CV_32F, buf ); + CvSeqReader reader; + CvContour contour_header; + CvSeq* contour = 0; + CvSeqBlock block; + + if( CV_IS_SEQ( array )) + { + contour = (CvSeq*)array; + if( !CV_IS_SEQ_POLYLINE( contour )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + if( is_closed < 0 ) + is_closed = CV_IS_SEQ_CLOSED( contour ); + } + else + { + is_closed = is_closed > 0; + contour = cvPointSeqFromMat( + CV_SEQ_KIND_CURVE | (is_closed ? CV_SEQ_FLAG_CLOSED : 0), + array, &contour_header, &block ); + } + + if( contour->total > 1 ) + { + int is_float = CV_SEQ_ELTYPE( contour ) == CV_32FC2; + + cvStartReadSeq( contour, &reader, 0 ); + cvSetSeqReaderPos( &reader, slice.start_index ); + count = cvSliceLength( slice, contour ); + + count -= !is_closed && count == contour->total; + + /* scroll the reader by 1 point */ + reader.prev_elem = reader.ptr; + CV_NEXT_SEQ_ELEM( sizeof(CvPoint), reader ); + + for( i = 0; i < count; i++ ) + { + float dx, dy; + + if( !is_float ) + { + CvPoint* pt = (CvPoint*)reader.ptr; + CvPoint* prev_pt = (CvPoint*)reader.prev_elem; + + dx = (float)pt->x - (float)prev_pt->x; + dy = (float)pt->y - (float)prev_pt->y; + } + else + { + CvPoint2D32f* pt = (CvPoint2D32f*)reader.ptr; + CvPoint2D32f* prev_pt = (CvPoint2D32f*)reader.prev_elem; + + dx = pt->x - prev_pt->x; + dy = pt->y - prev_pt->y; + } + + reader.prev_elem = reader.ptr; + CV_NEXT_SEQ_ELEM( contour->elem_size, reader ); + // Bugfix by Axel at rubico.com 2010-03-22, affects closed slices only + // wraparound not handled by CV_NEXT_SEQ_ELEM + if( is_closed && i == count - 2 ) + cvSetSeqReaderPos( &reader, slice.start_index ); + + buffer.data.fl[j] = dx * dx + dy * dy; + if( ++j == N || i == count - 1 ) + { + buffer.cols = j; + cvPow( &buffer, &buffer, 0.5 ); + for( ; j > 0; j-- ) + perimeter += buffer.data.fl[j-1]; + } + } + } + + return perimeter; +} + + +static CvStatus +icvFindCircle( CvPoint2D32f pt0, CvPoint2D32f pt1, + CvPoint2D32f pt2, CvPoint2D32f * center, float *radius ) +{ + double x1 = (pt0.x + pt1.x) * 0.5; + double dy1 = pt0.x - pt1.x; + double x2 = (pt1.x + pt2.x) * 0.5; + double dy2 = pt1.x - pt2.x; + double y1 = (pt0.y + pt1.y) * 0.5; + double dx1 = pt1.y - pt0.y; + double y2 = (pt1.y + pt2.y) * 0.5; + double dx2 = pt2.y - pt1.y; + double t = 0; + + CvStatus result = CV_OK; + + if( icvIntersectLines( x1, dx1, y1, dy1, x2, dx2, y2, dy2, &t ) >= 0 ) + { + center->x = (float) (x2 + dx2 * t); + center->y = (float) (y2 + dy2 * t); + *radius = (float) icvDistanceL2_32f( *center, pt0 ); + } + else + { + center->x = center->y = 0.f; + radius = 0; + result = CV_NOTDEFINED_ERR; + } + + return result; +} + + +CV_INLINE double icvIsPtInCircle( CvPoint2D32f pt, CvPoint2D32f center, float radius ) +{ + double dx = pt.x - center.x; + double dy = pt.y - center.y; + return (double)radius*radius - dx*dx - dy*dy; +} + + +static int +icvFindEnslosingCicle4pts_32f( CvPoint2D32f * pts, CvPoint2D32f * _center, float *_radius ) +{ + int shuffles[4][4] = { {0, 1, 2, 3}, {0, 1, 3, 2}, {2, 3, 0, 1}, {2, 3, 1, 0} }; + + int idxs[4] = { 0, 1, 2, 3 }; + int i, j, k = 1, mi = 0; + float max_dist = 0; + CvPoint2D32f center; + CvPoint2D32f min_center; + float radius, min_radius = FLT_MAX; + CvPoint2D32f res_pts[4]; + + center = min_center = pts[0]; + radius = 1.f; + + for( i = 0; i < 4; i++ ) + for( j = i + 1; j < 4; j++ ) + { + float dist = icvDistanceL2_32f( pts[i], pts[j] ); + + if( max_dist < dist ) + { + max_dist = dist; + idxs[0] = i; + idxs[1] = j; + } + } + + if( max_dist == 0 ) + goto function_exit; + + k = 2; + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < k; j++ ) + if( i == idxs[j] ) + break; + if( j == k ) + idxs[k++] = i; + } + + center = cvPoint2D32f( (pts[idxs[0]].x + pts[idxs[1]].x)*0.5f, + (pts[idxs[0]].y + pts[idxs[1]].y)*0.5f ); + radius = (float)(icvDistanceL2_32f( pts[idxs[0]], center )*1.03); + if( radius < 1.f ) + radius = 1.f; + + if( icvIsPtInCircle( pts[idxs[2]], center, radius ) >= 0 && + icvIsPtInCircle( pts[idxs[3]], center, radius ) >= 0 ) + { + k = 2; //rand()%2+2; + } + else + { + mi = -1; + for( i = 0; i < 4; i++ ) + { + if( icvFindCircle( pts[shuffles[i][0]], pts[shuffles[i][1]], + pts[shuffles[i][2]], ¢er, &radius ) >= 0 ) + { + radius *= 1.03f; + if( radius < 2.f ) + radius = 2.f; + + if( icvIsPtInCircle( pts[shuffles[i][3]], center, radius ) >= 0 && + min_radius > radius ) + { + min_radius = radius; + min_center = center; + mi = i; + } + } + } + assert( mi >= 0 ); + if( mi < 0 ) + mi = 0; + k = 3; + center = min_center; + radius = min_radius; + for( i = 0; i < 4; i++ ) + idxs[i] = shuffles[mi][i]; + } + + function_exit: + + *_center = center; + *_radius = radius; + + /* reorder output points */ + for( i = 0; i < 4; i++ ) + res_pts[i] = pts[idxs[i]]; + + for( i = 0; i < 4; i++ ) + { + pts[i] = res_pts[i]; + assert( icvIsPtInCircle( pts[i], center, radius ) >= 0 ); + } + + return k; +} + + +CV_IMPL int +cvMinEnclosingCircle( const void* array, CvPoint2D32f * _center, float *_radius ) +{ + const int max_iters = 100; + const float eps = FLT_EPSILON*2; + CvPoint2D32f center = { 0, 0 }; + float radius = 0; + int result = 0; + + if( _center ) + _center->x = _center->y = 0.f; + if( _radius ) + *_radius = 0; + + CvSeqReader reader; + int k, count; + CvPoint2D32f pts[8]; + CvContour contour_header; + CvSeqBlock block; + CvSeq* sequence = 0; + int is_float; + + if( !_center || !_radius ) + CV_Error( CV_StsNullPtr, "Null center or radius pointers" ); + + if( CV_IS_SEQ(array) ) + { + sequence = (CvSeq*)array; + if( !CV_IS_SEQ_POINT_SET( sequence )) + CV_Error( CV_StsBadArg, "The passed sequence is not a valid contour" ); + } + else + { + sequence = cvPointSeqFromMat( + CV_SEQ_KIND_GENERIC, array, &contour_header, &block ); + } + + if( sequence->total <= 0 ) + CV_Error( CV_StsBadSize, "" ); + + cvStartReadSeq( sequence, &reader, 0 ); + + count = sequence->total; + is_float = CV_SEQ_ELTYPE(sequence) == CV_32FC2; + + if( !is_float ) + { + CvPoint *pt_left, *pt_right, *pt_top, *pt_bottom; + CvPoint pt; + pt_left = pt_right = pt_top = pt_bottom = (CvPoint *)(reader.ptr); + CV_READ_SEQ_ELEM( pt, reader ); + + for(int i = 1; i < count; i++ ) + { + CvPoint* pt_ptr = (CvPoint*)reader.ptr; + CV_READ_SEQ_ELEM( pt, reader ); + + if( pt.x < pt_left->x ) + pt_left = pt_ptr; + if( pt.x > pt_right->x ) + pt_right = pt_ptr; + if( pt.y < pt_top->y ) + pt_top = pt_ptr; + if( pt.y > pt_bottom->y ) + pt_bottom = pt_ptr; + } + + pts[0] = cvPointTo32f( *pt_left ); + pts[1] = cvPointTo32f( *pt_right ); + pts[2] = cvPointTo32f( *pt_top ); + pts[3] = cvPointTo32f( *pt_bottom ); + } + else + { + CvPoint2D32f *pt_left, *pt_right, *pt_top, *pt_bottom; + CvPoint2D32f pt; + pt_left = pt_right = pt_top = pt_bottom = (CvPoint2D32f *) (reader.ptr); + CV_READ_SEQ_ELEM( pt, reader ); + + for(int i = 1; i < count; i++ ) + { + CvPoint2D32f* pt_ptr = (CvPoint2D32f*)reader.ptr; + CV_READ_SEQ_ELEM( pt, reader ); + + if( pt.x < pt_left->x ) + pt_left = pt_ptr; + if( pt.x > pt_right->x ) + pt_right = pt_ptr; + if( pt.y < pt_top->y ) + pt_top = pt_ptr; + if( pt.y > pt_bottom->y ) + pt_bottom = pt_ptr; + } + + pts[0] = *pt_left; + pts[1] = *pt_right; + pts[2] = *pt_top; + pts[3] = *pt_bottom; + } + + for( k = 0; k < max_iters; k++ ) + { + double min_delta = 0, delta; + CvPoint2D32f ptfl, farAway = { 0, 0}; + /*only for first iteration because the alg is repared at the loop's foot*/ + if(k==0) + icvFindEnslosingCicle4pts_32f( pts, ¢er, &radius ); + + cvStartReadSeq( sequence, &reader, 0 ); + + for(int i = 0; i < count; i++ ) + { + if( !is_float ) + { + ptfl.x = (float)((CvPoint*)reader.ptr)->x; + ptfl.y = (float)((CvPoint*)reader.ptr)->y; + } + else + { + ptfl = *(CvPoint2D32f*)reader.ptr; + } + CV_NEXT_SEQ_ELEM( sequence->elem_size, reader ); + + delta = icvIsPtInCircle( ptfl, center, radius ); + if( delta < min_delta ) + { + min_delta = delta; + farAway = ptfl; + } + } + result = min_delta >= 0; + if( result ) + break; + + CvPoint2D32f ptsCopy[4]; + /* find good replacement partner for the point which is at most far away, + starting with the one that lays in the actual circle (i=3) */ + for(int i = 3; i >=0; i-- ) + { + for(int j = 0; j < 4; j++ ) + { + ptsCopy[j]=(i != j)? pts[j]: farAway; + } + + icvFindEnslosingCicle4pts_32f(ptsCopy, ¢er, &radius ); + if( icvIsPtInCircle( pts[i], center, radius )>=0){ // replaced one again in the new circle? + pts[i] = farAway; + break; + } + } + } + + if( !result ) + { + cvStartReadSeq( sequence, &reader, 0 ); + radius = 0.f; + + for(int i = 0; i < count; i++ ) + { + CvPoint2D32f ptfl; + float t, dx, dy; + + if( !is_float ) + { + ptfl.x = (float)((CvPoint*)reader.ptr)->x; + ptfl.y = (float)((CvPoint*)reader.ptr)->y; + } + else + { + ptfl = *(CvPoint2D32f*)reader.ptr; + } + + CV_NEXT_SEQ_ELEM( sequence->elem_size, reader ); + dx = center.x - ptfl.x; + dy = center.y - ptfl.y; + t = dx*dx + dy*dy; + radius = MAX(radius,t); + } + + radius = (float)(sqrt(radius)*(1 + eps)); + result = 1; + } + + *_center = center; + *_radius = radius; + + return result; +} + + +/* area of a whole sequence */ +static CvStatus +icvContourArea( const CvSeq* contour, double *area ) +{ + if( contour->total ) + { + CvSeqReader reader; + int lpt = contour->total; + double a00 = 0, xi_1, yi_1; + int is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2; + + cvStartReadSeq( contour, &reader, 0 ); + + if( !is_float ) + { + xi_1 = ((CvPoint*)(reader.ptr))->x; + yi_1 = ((CvPoint*)(reader.ptr))->y; + } + else + { + xi_1 = ((CvPoint2D32f*)(reader.ptr))->x; + yi_1 = ((CvPoint2D32f*)(reader.ptr))->y; + } + CV_NEXT_SEQ_ELEM( contour->elem_size, reader ); + + while( lpt-- > 0 ) + { + double dxy, xi, yi; + + if( !is_float ) + { + xi = ((CvPoint*)(reader.ptr))->x; + yi = ((CvPoint*)(reader.ptr))->y; + } + else + { + xi = ((CvPoint2D32f*)(reader.ptr))->x; + yi = ((CvPoint2D32f*)(reader.ptr))->y; + } + CV_NEXT_SEQ_ELEM( contour->elem_size, reader ); + + dxy = xi_1 * yi - xi * yi_1; + a00 += dxy; + xi_1 = xi; + yi_1 = yi; + } + + *area = a00 * 0.5; + } + else + *area = 0; + + return CV_OK; +} + + +/****************************************************************************************\ + + copy data from one buffer to other buffer + +\****************************************************************************************/ + +static CvStatus +icvMemCopy( double **buf1, double **buf2, double **buf3, int *b_max ) +{ + int bb; + + if( (*buf1 == NULL && *buf2 == NULL) || *buf3 == NULL ) + return CV_NULLPTR_ERR; + + bb = *b_max; + if( *buf2 == NULL ) + { + *b_max = 2 * (*b_max); + *buf2 = (double *)cvAlloc( (*b_max) * sizeof( double )); + + if( *buf2 == NULL ) + return CV_OUTOFMEM_ERR; + + memcpy( *buf2, *buf3, bb * sizeof( double )); + + *buf3 = *buf2; + cvFree( buf1 ); + *buf1 = NULL; + } + else + { + *b_max = 2 * (*b_max); + *buf1 = (double *) cvAlloc( (*b_max) * sizeof( double )); + + if( *buf1 == NULL ) + return CV_OUTOFMEM_ERR; + + memcpy( *buf1, *buf3, bb * sizeof( double )); + + *buf3 = *buf1; + cvFree( buf2 ); + *buf2 = NULL; + } + return CV_OK; +} + + +/* area of a contour sector */ +static CvStatus icvContourSecArea( CvSeq * contour, CvSlice slice, double *area ) +{ + CvPoint pt; /* pointer to points */ + CvPoint pt_s, pt_e; /* first and last points */ + CvSeqReader reader; /* points reader of contour */ + + int p_max = 2, p_ind; + int lpt, flag, i; + double a00; /* unnormalized moments m00 */ + double xi, yi, xi_1, yi_1, x0, y0, dxy, sk, sk1, t; + double x_s, y_s, nx, ny, dx, dy, du, dv; + double eps = 1.e-5; + double *p_are1, *p_are2, *p_are; + + assert( contour != NULL ); + + if( contour == NULL ) + return CV_NULLPTR_ERR; + + if( !CV_IS_SEQ_POINT_SET( contour )) + return CV_BADFLAG_ERR; + + lpt = cvSliceLength( slice, contour ); + /*if( n2 >= n1 ) + lpt = n2 - n1 + 1; + else + lpt = contour->total - n1 + n2 + 1;*/ + + if( contour->total && lpt > 2 ) + { + a00 = x0 = y0 = xi_1 = yi_1 = 0; + sk1 = 0; + flag = 0; + dxy = 0; + p_are1 = (double *) cvAlloc( p_max * sizeof( double )); + + if( p_are1 == NULL ) + return CV_OUTOFMEM_ERR; + + p_are = p_are1; + p_are2 = NULL; + + cvStartReadSeq( contour, &reader, 0 ); + cvSetSeqReaderPos( &reader, slice.start_index ); + CV_READ_SEQ_ELEM( pt_s, reader ); + p_ind = 0; + cvSetSeqReaderPos( &reader, slice.end_index ); + CV_READ_SEQ_ELEM( pt_e, reader ); + +/* normal coefficients */ + nx = pt_s.y - pt_e.y; + ny = pt_e.x - pt_s.x; + cvSetSeqReaderPos( &reader, slice.start_index ); + + while( lpt-- > 0 ) + { + CV_READ_SEQ_ELEM( pt, reader ); + + if( flag == 0 ) + { + xi_1 = (double) pt.x; + yi_1 = (double) pt.y; + x0 = xi_1; + y0 = yi_1; + sk1 = 0; + flag = 1; + } + else + { + xi = (double) pt.x; + yi = (double) pt.y; + +/**************** edges intersection examination **************************/ + sk = nx * (xi - pt_s.x) + ny * (yi - pt_s.y); + if( (fabs( sk ) < eps && lpt > 0) || sk * sk1 < -eps ) + { + if( fabs( sk ) < eps ) + { + dxy = xi_1 * yi - xi * yi_1; + a00 = a00 + dxy; + dxy = xi * y0 - x0 * yi; + a00 = a00 + dxy; + + if( p_ind >= p_max ) + icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); + + p_are[p_ind] = a00 / 2.; + p_ind++; + a00 = 0; + sk1 = 0; + x0 = xi; + y0 = yi; + dxy = 0; + } + else + { +/* define intersection point */ + dv = yi - yi_1; + du = xi - xi_1; + dx = ny; + dy = -nx; + if( fabs( du ) > eps ) + t = ((yi_1 - pt_s.y) * du + dv * (pt_s.x - xi_1)) / + (du * dy - dx * dv); + else + t = (xi_1 - pt_s.x) / dx; + if( t > eps && t < 1 - eps ) + { + x_s = pt_s.x + t * dx; + y_s = pt_s.y + t * dy; + dxy = xi_1 * y_s - x_s * yi_1; + a00 += dxy; + dxy = x_s * y0 - x0 * y_s; + a00 += dxy; + if( p_ind >= p_max ) + icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); + + p_are[p_ind] = a00 / 2.; + p_ind++; + + a00 = 0; + sk1 = 0; + x0 = x_s; + y0 = y_s; + dxy = x_s * yi - xi * y_s; + } + } + } + else + dxy = xi_1 * yi - xi * yi_1; + + a00 += dxy; + xi_1 = xi; + yi_1 = yi; + sk1 = sk; + + } + } + + xi = x0; + yi = y0; + dxy = xi_1 * yi - xi * yi_1; + + a00 += dxy; + + if( p_ind >= p_max ) + icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); + + p_are[p_ind] = a00 / 2.; + p_ind++; + +/* common area calculation */ + *area = 0; + for( i = 0; i < p_ind; i++ ) + (*area) += fabs( p_are[i] ); + + if( p_are1 != NULL ) + cvFree( &p_are1 ); + else if( p_are2 != NULL ) + cvFree( &p_are2 ); + + return CV_OK; + } + else + return CV_BADSIZE_ERR; +} + + +/* external contour area function */ +CV_IMPL double +cvContourArea( const void *array, CvSlice slice, int oriented ) +{ + double area = 0; + + CvContour contour_header; + CvSeq* contour = 0; + CvSeqBlock block; + + if( CV_IS_SEQ( array )) + { + contour = (CvSeq*)array; + if( !CV_IS_SEQ_POLYLINE( contour )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + } + else + { + contour = cvPointSeqFromMat( CV_SEQ_KIND_CURVE, array, &contour_header, &block ); + } + + if( cvSliceLength( slice, contour ) == contour->total ) + { + IPPI_CALL( icvContourArea( contour, &area )); + } + else + { + if( CV_SEQ_ELTYPE( contour ) != CV_32SC2 ) + CV_Error( CV_StsUnsupportedFormat, + "Only curves with integer coordinates are supported in case of contour slice" ); + IPPI_CALL( icvContourSecArea( contour, slice, &area )); + } + + return oriented ? area : fabs(area); +} + + +CV_IMPL CvBox2D +cvFitEllipse2( const CvArr* array ) +{ + CvBox2D box; + cv::AutoBuffer Ad, bd; + memset( &box, 0, sizeof(box)); + + CvContour contour_header; + CvSeq* ptseq = 0; + CvSeqBlock block; + int n; + + if( CV_IS_SEQ( array )) + { + ptseq = (CvSeq*)array; + if( !CV_IS_SEQ_POINT_SET( ptseq )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + } + else + { + ptseq = cvPointSeqFromMat(CV_SEQ_KIND_GENERIC, array, &contour_header, &block); + } + + n = ptseq->total; + if( n < 5 ) + CV_Error( CV_StsBadSize, "Number of points should be >= 5" ); + + /* + * New fitellipse algorithm, contributed by Dr. Daniel Weiss + */ + CvPoint2D32f c = {0,0}; + double gfp[5], rp[5], t; + CvMat A, b, x; + const double min_eps = 1e-6; + int i, is_float; + CvSeqReader reader; + + Ad.allocate(n*5); + bd.allocate(n); + + // first fit for parameters A - E + A = cvMat( n, 5, CV_64F, Ad ); + b = cvMat( n, 1, CV_64F, bd ); + x = cvMat( 5, 1, CV_64F, gfp ); + + cvStartReadSeq( ptseq, &reader ); + is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2; + + for( i = 0; i < n; i++ ) + { + CvPoint2D32f p; + if( is_float ) + p = *(CvPoint2D32f*)(reader.ptr); + else + { + p.x = (float)((int*)reader.ptr)[0]; + p.y = (float)((int*)reader.ptr)[1]; + } + CV_NEXT_SEQ_ELEM( sizeof(p), reader ); + c.x += p.x; + c.y += p.y; + } + c.x /= n; + c.y /= n; + + for( i = 0; i < n; i++ ) + { + CvPoint2D32f p; + if( is_float ) + p = *(CvPoint2D32f*)(reader.ptr); + else + { + p.x = (float)((int*)reader.ptr)[0]; + p.y = (float)((int*)reader.ptr)[1]; + } + CV_NEXT_SEQ_ELEM( sizeof(p), reader ); + p.x -= c.x; + p.y -= c.y; + + bd[i] = 10000.0; // 1.0? + Ad[i*5] = -(double)p.x * p.x; // A - C signs inverted as proposed by APP + Ad[i*5 + 1] = -(double)p.y * p.y; + Ad[i*5 + 2] = -(double)p.x * p.y; + Ad[i*5 + 3] = p.x; + Ad[i*5 + 4] = p.y; + } + + cvSolve( &A, &b, &x, CV_SVD ); + + // now use general-form parameters A - E to find the ellipse center: + // differentiate general form wrt x/y to get two equations for cx and cy + A = cvMat( 2, 2, CV_64F, Ad ); + b = cvMat( 2, 1, CV_64F, bd ); + x = cvMat( 2, 1, CV_64F, rp ); + Ad[0] = 2 * gfp[0]; + Ad[1] = Ad[2] = gfp[2]; + Ad[3] = 2 * gfp[1]; + bd[0] = gfp[3]; + bd[1] = gfp[4]; + cvSolve( &A, &b, &x, CV_SVD ); + + // re-fit for parameters A - C with those center coordinates + A = cvMat( n, 3, CV_64F, Ad ); + b = cvMat( n, 1, CV_64F, bd ); + x = cvMat( 3, 1, CV_64F, gfp ); + for( i = 0; i < n; i++ ) + { + CvPoint2D32f p; + if( is_float ) + p = *(CvPoint2D32f*)(reader.ptr); + else + { + p.x = (float)((int*)reader.ptr)[0]; + p.y = (float)((int*)reader.ptr)[1]; + } + CV_NEXT_SEQ_ELEM( sizeof(p), reader ); + p.x -= c.x; + p.y -= c.y; + bd[i] = 1.0; + Ad[i * 3] = (p.x - rp[0]) * (p.x - rp[0]); + Ad[i * 3 + 1] = (p.y - rp[1]) * (p.y - rp[1]); + Ad[i * 3 + 2] = (p.x - rp[0]) * (p.y - rp[1]); + } + cvSolve(&A, &b, &x, CV_SVD); + + // store angle and radii + rp[4] = -0.5 * atan2(gfp[2], gfp[1] - gfp[0]); // convert from APP angle usage + t = sin(-2.0 * rp[4]); + if( fabs(t) > fabs(gfp[2])*min_eps ) + t = gfp[2]/t; + else + t = gfp[1] - gfp[0]; + rp[2] = fabs(gfp[0] + gfp[1] - t); + if( rp[2] > min_eps ) + rp[2] = sqrt(2.0 / rp[2]); + rp[3] = fabs(gfp[0] + gfp[1] + t); + if( rp[3] > min_eps ) + rp[3] = sqrt(2.0 / rp[3]); + + box.center.x = (float)rp[0] + c.x; + box.center.y = (float)rp[1] + c.y; + box.size.width = (float)(rp[2]*2); + box.size.height = (float)(rp[3]*2); + if( box.size.width > box.size.height ) + { + float tmp; + CV_SWAP( box.size.width, box.size.height, tmp ); + box.angle = (float)(90 + rp[4]*180/CV_PI); + } + if( box.angle < -180 ) + box.angle += 360; + if( box.angle > 360 ) + box.angle -= 360; + + return box; +} + + +/* Calculates bounding rectagnle of a point set or retrieves already calculated */ +CV_IMPL CvRect +cvBoundingRect( CvArr* array, int update ) +{ + CvSeqReader reader; + CvRect rect = { 0, 0, 0, 0 }; + CvContour contour_header; + CvSeq* ptseq = 0; + CvSeqBlock block; + + CvMat stub, *mat = 0; + int xmin = 0, ymin = 0, xmax = -1, ymax = -1, i, j, k; + int calculate = update; + + if( CV_IS_SEQ( array )) + { + ptseq = (CvSeq*)array; + if( !CV_IS_SEQ_POINT_SET( ptseq )) + CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + + if( ptseq->header_size < (int)sizeof(CvContour)) + { + update = 0; + calculate = 1; + } + } + else + { + mat = cvGetMat( array, &stub ); + if( CV_MAT_TYPE(mat->type) == CV_32SC2 || + CV_MAT_TYPE(mat->type) == CV_32FC2 ) + { + ptseq = cvPointSeqFromMat(CV_SEQ_KIND_GENERIC, mat, &contour_header, &block); + mat = 0; + } + else if( CV_MAT_TYPE(mat->type) != CV_8UC1 && + CV_MAT_TYPE(mat->type) != CV_8SC1 ) + CV_Error( CV_StsUnsupportedFormat, + "The image/matrix format is not supported by the function" ); + update = 0; + calculate = 1; + } + + if( !calculate ) + return ((CvContour*)ptseq)->rect; + + if( mat ) + { + CvSize size = cvGetMatSize(mat); + xmin = size.width; + ymin = -1; + + for( i = 0; i < size.height; i++ ) + { + uchar* _ptr = mat->data.ptr + i*mat->step; + uchar* ptr = (uchar*)cvAlignPtr(_ptr, 4); + int have_nz = 0, k_min, offset = (int)(ptr - _ptr); + j = 0; + offset = MIN(offset, size.width); + for( ; j < offset; j++ ) + if( _ptr[j] ) + { + have_nz = 1; + break; + } + if( j < offset ) + { + if( j < xmin ) + xmin = j; + if( j > xmax ) + xmax = j; + } + if( offset < size.width ) + { + xmin -= offset; + xmax -= offset; + size.width -= offset; + j = 0; + for( ; j <= xmin - 4; j += 4 ) + if( *((int*)(ptr+j)) ) + break; + for( ; j < xmin; j++ ) + if( ptr[j] ) + { + xmin = j; + if( j > xmax ) + xmax = j; + have_nz = 1; + break; + } + k_min = MAX(j-1, xmax); + k = size.width - 1; + for( ; k > k_min && (k&3) != 3; k-- ) + if( ptr[k] ) + break; + if( k > k_min && (k&3) == 3 ) + { + for( ; k > k_min+3; k -= 4 ) + if( *((int*)(ptr+k-3)) ) + break; + } + for( ; k > k_min; k-- ) + if( ptr[k] ) + { + xmax = k; + have_nz = 1; + break; + } + if( !have_nz ) + { + j &= ~3; + for( ; j <= k - 3; j += 4 ) + if( *((int*)(ptr+j)) ) + break; + for( ; j <= k; j++ ) + if( ptr[j] ) + { + have_nz = 1; + break; + } + } + xmin += offset; + xmax += offset; + size.width += offset; + } + if( have_nz ) + { + if( ymin < 0 ) + ymin = i; + ymax = i; + } + } + + if( xmin >= size.width ) + xmin = ymin = 0; + } + else if( ptseq->total ) + { + int is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2; + cvStartReadSeq( ptseq, &reader, 0 ); + CvPoint pt; + CV_READ_SEQ_ELEM( pt, reader ); + #if CV_SSE4_2 + if(cv::checkHardwareSupport(CV_CPU_SSE4_2)) + { + if( !is_float ) + { + __m128i minval, maxval; + minval = maxval = _mm_loadl_epi64((const __m128i*)(&pt)); //min[0]=pt.x, min[1]=pt.y + + for( i = 1; i < ptseq->total; i++) + { + __m128i ptXY = _mm_loadl_epi64((const __m128i*)(reader.ptr)); + CV_NEXT_SEQ_ELEM(sizeof(pt), reader); + minval = _mm_min_epi32(ptXY, minval); + maxval = _mm_max_epi32(ptXY, maxval); + } + xmin = _mm_cvtsi128_si32(minval); + ymin = _mm_cvtsi128_si32(_mm_srli_si128(minval, 4)); + xmax = _mm_cvtsi128_si32(maxval); + ymax = _mm_cvtsi128_si32(_mm_srli_si128(maxval, 4)); + } + else + { + __m128 minvalf, maxvalf, z = _mm_setzero_ps(), ptXY = _mm_setzero_ps(); + minvalf = maxvalf = _mm_loadl_pi(z, (const __m64*)(&pt)); + + for( i = 1; i < ptseq->total; i++ ) + { + ptXY = _mm_loadl_pi(ptXY, (const __m64*)reader.ptr); + CV_NEXT_SEQ_ELEM(sizeof(pt), reader); + + minvalf = _mm_min_ps(minvalf, ptXY); + maxvalf = _mm_max_ps(maxvalf, ptXY); + } + + float xyminf[2], xymaxf[2]; + _mm_storel_pi((__m64*)xyminf, minvalf); + _mm_storel_pi((__m64*)xymaxf, maxvalf); + xmin = cvFloor(xyminf[0]); + ymin = cvFloor(xyminf[1]); + xmax = cvFloor(xymaxf[0]); + ymax = cvFloor(xymaxf[1]); + } + } + else + #endif + { + if( !is_float ) + { + xmin = xmax = pt.x; + ymin = ymax = pt.y; + + for( i = 1; i < ptseq->total; i++ ) + { + CV_READ_SEQ_ELEM( pt, reader ); + + if( xmin > pt.x ) + xmin = pt.x; + + if( xmax < pt.x ) + xmax = pt.x; + + if( ymin > pt.y ) + ymin = pt.y; + + if( ymax < pt.y ) + ymax = pt.y; + } + } + else + { + Cv32suf v; + // init values + xmin = xmax = CV_TOGGLE_FLT(pt.x); + ymin = ymax = CV_TOGGLE_FLT(pt.y); + + for( i = 1; i < ptseq->total; i++ ) + { + CV_READ_SEQ_ELEM( pt, reader ); + pt.x = CV_TOGGLE_FLT(pt.x); + pt.y = CV_TOGGLE_FLT(pt.y); + + if( xmin > pt.x ) + xmin = pt.x; + + if( xmax < pt.x ) + xmax = pt.x; + + if( ymin > pt.y ) + ymin = pt.y; + + if( ymax < pt.y ) + ymax = pt.y; + } + + v.i = CV_TOGGLE_FLT(xmin); xmin = cvFloor(v.f); + v.i = CV_TOGGLE_FLT(ymin); ymin = cvFloor(v.f); + // because right and bottom sides of the bounding rectangle are not inclusive + // (note +1 in width and height calculation below), cvFloor is used here instead of cvCeil + v.i = CV_TOGGLE_FLT(xmax); xmax = cvFloor(v.f); + v.i = CV_TOGGLE_FLT(ymax); ymax = cvFloor(v.f); + } + } + rect.x = xmin; + rect.y = ymin; + rect.width = xmax - xmin + 1; + rect.height = ymax - ymin + 1; + } + if( update ) + ((CvContour*)ptseq)->rect = rect; + return rect; +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/smooth.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/smooth.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/smooth.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/smooth.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2242 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +/* + * This file includes the code, contributed by Simon Perreault + * (the function icvMedianBlur_8u_O1) + * + * Constant-time median filtering -- http://nomis80.org/ctmf.html + * Copyright (C) 2006 Simon Perreault + * + * Contact: + * Laboratoire de vision et systemes numeriques + * Pavillon Adrien-Pouliot + * Universite Laval + * Sainte-Foy, Quebec, Canada + * G1K 7P4 + * + * perreaul@gel.ulaval.ca + */ + +namespace cv +{ + +/****************************************************************************************\ + Box Filter +\****************************************************************************************/ + +template struct RowSum : public BaseRowFilter +{ + RowSum( int _ksize, int _anchor ) + { + ksize = _ksize; + anchor = _anchor; + } + + void operator()(const uchar* src, uchar* dst, int width, int cn) + { + const T* S = (const T*)src; + ST* D = (ST*)dst; + int i = 0, k, ksz_cn = ksize*cn; + + width = (width - 1)*cn; + for( k = 0; k < cn; k++, S++, D++ ) + { + ST s = 0; + for( i = 0; i < ksz_cn; i += cn ) + s += S[i]; + D[0] = s; + for( i = 0; i < width; i += cn ) + { + s += S[i + ksz_cn] - S[i]; + D[i+cn] = s; + } + } + } +}; + + +template struct ColumnSum : public BaseColumnFilter +{ + ColumnSum( int _ksize, int _anchor, double _scale ) + { + ksize = _ksize; + anchor = _anchor; + scale = _scale; + sumCount = 0; + } + + void reset() { sumCount = 0; } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int i; + ST* SUM; + bool haveScale = scale != 1; + double _scale = scale; + + if( width != (int)sum.size() ) + { + sum.resize(width); + sumCount = 0; + } + + SUM = &sum[0]; + if( sumCount == 0 ) + { + for( i = 0; i < width; i++ ) + SUM[i] = 0; + for( ; sumCount < ksize - 1; sumCount++, src++ ) + { + const ST* Sp = (const ST*)src[0]; + for( i = 0; i <= width - 2; i += 2 ) + { + ST s0 = SUM[i] + Sp[i], s1 = SUM[i+1] + Sp[i+1]; + SUM[i] = s0; SUM[i+1] = s1; + } + + for( ; i < width; i++ ) + SUM[i] += Sp[i]; + } + } + else + { + CV_Assert( sumCount == ksize-1 ); + src += ksize-1; + } + + for( ; count--; src++ ) + { + const ST* Sp = (const ST*)src[0]; + const ST* Sm = (const ST*)src[1-ksize]; + T* D = (T*)dst; + if( haveScale ) + { + for( i = 0; i <= width - 2; i += 2 ) + { + ST s0 = SUM[i] + Sp[i], s1 = SUM[i+1] + Sp[i+1]; + D[i] = saturate_cast(s0*_scale); + D[i+1] = saturate_cast(s1*_scale); + s0 -= Sm[i]; s1 -= Sm[i+1]; + SUM[i] = s0; SUM[i+1] = s1; + } + + for( ; i < width; i++ ) + { + ST s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0*_scale); + SUM[i] = s0 - Sm[i]; + } + } + else + { + for( i = 0; i <= width - 2; i += 2 ) + { + ST s0 = SUM[i] + Sp[i], s1 = SUM[i+1] + Sp[i+1]; + D[i] = saturate_cast(s0); + D[i+1] = saturate_cast(s1); + s0 -= Sm[i]; s1 -= Sm[i+1]; + SUM[i] = s0; SUM[i+1] = s1; + } + + for( ; i < width; i++ ) + { + ST s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0); + SUM[i] = s0 - Sm[i]; + } + } + dst += dststep; + } + } + + double scale; + int sumCount; + vector sum; +}; + + +template<> struct ColumnSum : public BaseColumnFilter +{ + ColumnSum( int _ksize, int _anchor, double _scale ) + { + ksize = _ksize; + anchor = _anchor; + scale = _scale; + sumCount = 0; + } + + void reset() { sumCount = 0; } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int i; + int* SUM; + bool haveScale = scale != 1; + double _scale = scale; + + #if CV_SSE2 + bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); + #endif + + if( width != (int)sum.size() ) + { + sum.resize(width); + sumCount = 0; + } + + SUM = &sum[0]; + if( sumCount == 0 ) + { + memset((void*)SUM, 0, width*sizeof(int)); + for( ; sumCount < ksize - 1; sumCount++, src++ ) + { + const int* Sp = (const int*)src[0]; + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + for( ; i < width-4; i+=4 ) + { + __m128i _sum = _mm_loadu_si128((const __m128i*)(SUM+i)); + __m128i _sp = _mm_loadu_si128((const __m128i*)(Sp+i)); + _mm_storeu_si128((__m128i*)(SUM+i),_mm_add_epi32(_sum, _sp)); + } + } + #endif + for( ; i < width; i++ ) + SUM[i] += Sp[i]; + } + } + else + { + CV_Assert( sumCount == ksize-1 ); + src += ksize-1; + } + + for( ; count--; src++ ) + { + const int* Sp = (const int*)src[0]; + const int* Sm = (const int*)src[1-ksize]; + uchar* D = (uchar*)dst; + if( haveScale ) + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + const __m128 scale4 = _mm_set1_ps((float)_scale); + for( ; i < width-8; i+=8 ) + { + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _sm1 = _mm_loadu_si128((const __m128i*)(Sm+i+4)); + + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + __m128i _s01 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i+4)), + _mm_loadu_si128((const __m128i*)(Sp+i+4))); + + __m128i _s0T = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s0))); + __m128i _s0T1 = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s01))); + + _s0T = _mm_packs_epi32(_s0T, _s0T1); + + _mm_storel_epi64((__m128i*)(D+i), _mm_packus_epi16(_s0T, _s0T)); + + _mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm)); + _mm_storeu_si128((__m128i*)(SUM+i+4),_mm_sub_epi32(_s01,_sm1)); + } + } + #endif + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0*_scale); + SUM[i] = s0 - Sm[i]; + } + } + else + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + for( ; i < width-8; i+=8 ) + { + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _sm1 = _mm_loadu_si128((const __m128i*)(Sm+i+4)); + + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + __m128i _s01 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i+4)), + _mm_loadu_si128((const __m128i*)(Sp+i+4))); + + __m128i _s0T = _mm_packs_epi32(_s0, _s01); + + _mm_storel_epi64((__m128i*)(D+i), _mm_packus_epi16(_s0T, _s0T)); + + _mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm)); + _mm_storeu_si128((__m128i*)(SUM+i+4),_mm_sub_epi32(_s01,_sm1)); + } + } + #endif + + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0); + SUM[i] = s0 - Sm[i]; + } + } + dst += dststep; + } + } + + double scale; + int sumCount; + vector sum; +}; + +template<> struct ColumnSum : public BaseColumnFilter +{ + ColumnSum( int _ksize, int _anchor, double _scale ) + { + ksize = _ksize; + anchor = _anchor; + scale = _scale; + sumCount = 0; + } + + void reset() { sumCount = 0; } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int i; + int* SUM; + bool haveScale = scale != 1; + double _scale = scale; + + #if CV_SSE2 + bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); + #endif + + if( width != (int)sum.size() ) + { + sum.resize(width); + sumCount = 0; + } + SUM = &sum[0]; + if( sumCount == 0 ) + { + memset((void*)SUM, 0, width*sizeof(int)); + for( ; sumCount < ksize - 1; sumCount++, src++ ) + { + const int* Sp = (const int*)src[0]; + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + for( ; i < width-4; i+=4 ) + { + __m128i _sum = _mm_loadu_si128((const __m128i*)(SUM+i)); + __m128i _sp = _mm_loadu_si128((const __m128i*)(Sp+i)); + _mm_storeu_si128((__m128i*)(SUM+i),_mm_add_epi32(_sum, _sp)); + } + } + #endif + for( ; i < width; i++ ) + SUM[i] += Sp[i]; + } + } + else + { + CV_Assert( sumCount == ksize-1 ); + src += ksize-1; + } + + for( ; count--; src++ ) + { + const int* Sp = (const int*)src[0]; + const int* Sm = (const int*)src[1-ksize]; + short* D = (short*)dst; + if( haveScale ) + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + const __m128 scale4 = _mm_set1_ps((float)_scale); + for( ; i < width-8; i+=8 ) + { + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _sm1 = _mm_loadu_si128((const __m128i*)(Sm+i+4)); + + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + __m128i _s01 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i+4)), + _mm_loadu_si128((const __m128i*)(Sp+i+4))); + + __m128i _s0T = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s0))); + __m128i _s0T1 = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s01))); + + _mm_storeu_si128((__m128i*)(D+i), _mm_packs_epi32(_s0T, _s0T1)); + + _mm_storeu_si128((__m128i*)(SUM+i),_mm_sub_epi32(_s0,_sm)); + _mm_storeu_si128((__m128i*)(SUM+i+4), _mm_sub_epi32(_s01,_sm1)); + } + } + #endif + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0*_scale); + SUM[i] = s0 - Sm[i]; + } + } + else + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + for( ; i < width-8; i+=8 ) + { + + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _sm1 = _mm_loadu_si128((const __m128i*)(Sm+i+4)); + + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + __m128i _s01 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i+4)), + _mm_loadu_si128((const __m128i*)(Sp+i+4))); + + _mm_storeu_si128((__m128i*)(D+i), _mm_packs_epi32(_s0, _s01)); + + _mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm)); + _mm_storeu_si128((__m128i*)(SUM+i+4),_mm_sub_epi32(_s01,_sm1)); + } + } + #endif + + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0); + SUM[i] = s0 - Sm[i]; + } + } + dst += dststep; + } + } + + double scale; + int sumCount; + vector sum; +}; + + +template<> struct ColumnSum : public BaseColumnFilter +{ + ColumnSum( int _ksize, int _anchor, double _scale ) + { + ksize = _ksize; + anchor = _anchor; + scale = _scale; + sumCount = 0; + } + + void reset() { sumCount = 0; } + + void operator()(const uchar** src, uchar* dst, int dststep, int count, int width) + { + int i; + int* SUM; + bool haveScale = scale != 1; + double _scale = scale; + #if CV_SSE2 + bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); + #endif + + if( width != (int)sum.size() ) + { + sum.resize(width); + sumCount = 0; + } + SUM = &sum[0]; + if( sumCount == 0 ) + { + memset((void*)SUM, 0, width*sizeof(int)); + for( ; sumCount < ksize - 1; sumCount++, src++ ) + { + const int* Sp = (const int*)src[0]; + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + for( ; i < width-4; i+=4 ) + { + __m128i _sum = _mm_loadu_si128((const __m128i*)(SUM+i)); + __m128i _sp = _mm_loadu_si128((const __m128i*)(Sp+i)); + _mm_storeu_si128((__m128i*)(SUM+i), _mm_add_epi32(_sum, _sp)); + } + } + #endif + for( ; i < width; i++ ) + SUM[i] += Sp[i]; + } + } + else + { + CV_Assert( sumCount == ksize-1 ); + src += ksize-1; + } + + for( ; count--; src++ ) + { + const int* Sp = (const int*)src[0]; + const int* Sm = (const int*)src[1-ksize]; + ushort* D = (ushort*)dst; + if( haveScale ) + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + const __m128 scale4 = _mm_set1_ps((float)_scale); + const __m128i delta0 = _mm_set1_epi32(0x8000); + const __m128i delta1 = _mm_set1_epi32(0x80008000); + + for( ; i < width-4; i+=4) + { + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + + __m128i _res = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s0))); + + _res = _mm_sub_epi32(_res, delta0); + _res = _mm_add_epi16(_mm_packs_epi32(_res, _res), delta1); + + _mm_storel_epi64((__m128i*)(D+i), _res); + _mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm)); + } + } + #endif + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0*_scale); + SUM[i] = s0 - Sm[i]; + } + } + else + { + i = 0; + #if CV_SSE2 + if(haveSSE2) + { + const __m128i delta0 = _mm_set1_epi32(0x8000); + const __m128i delta1 = _mm_set1_epi32(0x80008000); + + for( ; i < width-4; i+=4 ) + { + __m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i)); + __m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)), + _mm_loadu_si128((const __m128i*)(Sp+i))); + + __m128i _res = _mm_sub_epi32(_s0, delta0); + _res = _mm_add_epi16(_mm_packs_epi32(_res, _res), delta1); + + _mm_storel_epi64((__m128i*)(D+i), _res); + _mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm)); + } + } + #endif + + for( ; i < width; i++ ) + { + int s0 = SUM[i] + Sp[i]; + D[i] = saturate_cast(s0); + SUM[i] = s0 - Sm[i]; + } + } + dst += dststep; + } + } + + double scale; + int sumCount; + vector sum; +}; + + +} + +cv::Ptr cv::getRowSumFilter(int srcType, int sumType, int ksize, int anchor) +{ + int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(sumType); + CV_Assert( CV_MAT_CN(sumType) == CV_MAT_CN(srcType) ); + + if( anchor < 0 ) + anchor = ksize/2; + + if( sdepth == CV_8U && ddepth == CV_32S ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_8U && ddepth == CV_64F ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_16U && ddepth == CV_32S ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_16U && ddepth == CV_64F ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_16S && ddepth == CV_32S ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_32S && ddepth == CV_32S ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_16S && ddepth == CV_64F ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_32F && ddepth == CV_64F ) + return Ptr(new RowSum(ksize, anchor)); + if( sdepth == CV_64F && ddepth == CV_64F ) + return Ptr(new RowSum(ksize, anchor)); + + CV_Error_( CV_StsNotImplemented, + ("Unsupported combination of source format (=%d), and buffer format (=%d)", + srcType, sumType)); + + return Ptr(0); +} + + +cv::Ptr cv::getColumnSumFilter(int sumType, int dstType, int ksize, + int anchor, double scale) +{ + int sdepth = CV_MAT_DEPTH(sumType), ddepth = CV_MAT_DEPTH(dstType); + CV_Assert( CV_MAT_CN(sumType) == CV_MAT_CN(dstType) ); + + if( anchor < 0 ) + anchor = ksize/2; + + if( ddepth == CV_8U && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_8U && sdepth == CV_64F ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_16U && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_16U && sdepth == CV_64F ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_16S && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_16S && sdepth == CV_64F ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_32S && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_32F && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_32F && sdepth == CV_64F ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_64F && sdepth == CV_32S ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + if( ddepth == CV_64F && sdepth == CV_64F ) + return Ptr(new ColumnSum(ksize, anchor, scale)); + + CV_Error_( CV_StsNotImplemented, + ("Unsupported combination of sum format (=%d), and destination format (=%d)", + sumType, dstType)); + + return Ptr(0); +} + + +cv::Ptr cv::createBoxFilter( int srcType, int dstType, Size ksize, + Point anchor, bool normalize, int borderType ) +{ + int sdepth = CV_MAT_DEPTH(srcType); + int cn = CV_MAT_CN(srcType), sumType = CV_64F; + if( sdepth <= CV_32S && (!normalize || + ksize.width*ksize.height <= (sdepth == CV_8U ? (1<<23) : + sdepth == CV_16U ? (1 << 15) : (1 << 16))) ) + sumType = CV_32S; + sumType = CV_MAKETYPE( sumType, cn ); + + Ptr rowFilter = getRowSumFilter(srcType, sumType, ksize.width, anchor.x ); + Ptr columnFilter = getColumnSumFilter(sumType, + dstType, ksize.height, anchor.y, normalize ? 1./(ksize.width*ksize.height) : 1); + + return Ptr(new FilterEngine(Ptr(0), rowFilter, columnFilter, + srcType, dstType, sumType, borderType )); +} + + +void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth, + Size ksize, Point anchor, + bool normalize, int borderType ) +{ + Mat src = _src.getMat(); + int sdepth = src.depth(), cn = src.channels(); + if( ddepth < 0 ) + ddepth = sdepth; + _dst.create( src.size(), CV_MAKETYPE(ddepth, cn) ); + Mat dst = _dst.getMat(); + if( borderType != BORDER_CONSTANT && normalize ) + { + if( src.rows == 1 ) + ksize.height = 1; + if( src.cols == 1 ) + ksize.width = 1; + } +#ifdef HAVE_TEGRA_OPTIMIZATION + if ( tegra::box(src, dst, ksize, anchor, normalize, borderType) ) + return; +#endif + + Ptr f = createBoxFilter( src.type(), dst.type(), + ksize, anchor, normalize, borderType ); + f->apply( src, dst ); +} + +void cv::blur( InputArray src, OutputArray dst, + Size ksize, Point anchor, int borderType ) +{ + boxFilter( src, dst, -1, ksize, anchor, true, borderType ); +} + +/****************************************************************************************\ + Gaussian Blur +\****************************************************************************************/ + +cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype ) +{ + const int SMALL_GAUSSIAN_SIZE = 7; + static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] = + { + {1.f}, + {0.25f, 0.5f, 0.25f}, + {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f}, + {0.03125f, 0.109375f, 0.21875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f} + }; + + const float* fixed_kernel = n % 2 == 1 && n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ? + small_gaussian_tab[n>>1] : 0; + + CV_Assert( ktype == CV_32F || ktype == CV_64F ); + Mat kernel(n, 1, ktype); + float* cf = (float*)kernel.data; + double* cd = (double*)kernel.data; + + double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8; + double scale2X = -0.5/(sigmaX*sigmaX); + double sum = 0; + + int i; + for( i = 0; i < n; i++ ) + { + double x = i - (n-1)*0.5; + double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x); + if( ktype == CV_32F ) + { + cf[i] = (float)t; + sum += cf[i]; + } + else + { + cd[i] = t; + sum += cd[i]; + } + } + + sum = 1./sum; + for( i = 0; i < n; i++ ) + { + if( ktype == CV_32F ) + cf[i] = (float)(cf[i]*sum); + else + cd[i] *= sum; + } + + return kernel; +} + + +cv::Ptr cv::createGaussianFilter( int type, Size ksize, + double sigma1, double sigma2, + int borderType ) +{ + int depth = CV_MAT_DEPTH(type); + if( sigma2 <= 0 ) + sigma2 = sigma1; + + // automatic detection of kernel size from sigma + if( ksize.width <= 0 && sigma1 > 0 ) + ksize.width = cvRound(sigma1*(depth == CV_8U ? 3 : 4)*2 + 1)|1; + if( ksize.height <= 0 && sigma2 > 0 ) + ksize.height = cvRound(sigma2*(depth == CV_8U ? 3 : 4)*2 + 1)|1; + + CV_Assert( ksize.width > 0 && ksize.width % 2 == 1 && + ksize.height > 0 && ksize.height % 2 == 1 ); + + sigma1 = std::max( sigma1, 0. ); + sigma2 = std::max( sigma2, 0. ); + + Mat kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) ); + Mat ky; + if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON ) + ky = kx; + else + ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) ); + + return createSeparableLinearFilter( type, type, kx, ky, Point(-1,-1), 0, borderType ); +} + + +void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize, + double sigma1, double sigma2, + int borderType ) +{ + Mat src = _src.getMat(); + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( borderType != BORDER_CONSTANT ) + { + if( src.rows == 1 ) + ksize.height = 1; + if( src.cols == 1 ) + ksize.width = 1; + } + + if( ksize.width == 1 && ksize.height == 1 ) + { + src.copyTo(dst); + return; + } + +#ifdef HAVE_TEGRA_OPTIMIZATION + if(sigma1 == 0 && sigma2 == 0 && tegra::gaussian(src, dst, ksize, borderType)) + return; +#endif + + Ptr f = createGaussianFilter( src.type(), ksize, sigma1, sigma2, borderType ); + f->apply( src, dst ); +} + + +/****************************************************************************************\ + Median Filter +\****************************************************************************************/ + +namespace cv +{ +typedef ushort HT; + +/** + * This structure represents a two-tier histogram. The first tier (known as the + * "coarse" level) is 4 bit wide and the second tier (known as the "fine" level) + * is 8 bit wide. Pixels inserted in the fine level also get inserted into the + * coarse bucket designated by the 4 MSBs of the fine bucket value. + * + * The structure is aligned on 16 bits, which is a prerequisite for SIMD + * instructions. Each bucket is 16 bit wide, which means that extra care must be + * taken to prevent overflow. + */ +typedef struct +{ + HT coarse[16]; + HT fine[16][16]; +} Histogram; + + +#if CV_SSE2 +#define MEDIAN_HAVE_SIMD 1 + +static inline void histogram_add_simd( const HT x[16], HT y[16] ) +{ + const __m128i* rx = (const __m128i*)x; + __m128i* ry = (__m128i*)y; + __m128i r0 = _mm_add_epi16(_mm_load_si128(ry+0),_mm_load_si128(rx+0)); + __m128i r1 = _mm_add_epi16(_mm_load_si128(ry+1),_mm_load_si128(rx+1)); + _mm_store_si128(ry+0, r0); + _mm_store_si128(ry+1, r1); +} + +static inline void histogram_sub_simd( const HT x[16], HT y[16] ) +{ + const __m128i* rx = (const __m128i*)x; + __m128i* ry = (__m128i*)y; + __m128i r0 = _mm_sub_epi16(_mm_load_si128(ry+0),_mm_load_si128(rx+0)); + __m128i r1 = _mm_sub_epi16(_mm_load_si128(ry+1),_mm_load_si128(rx+1)); + _mm_store_si128(ry+0, r0); + _mm_store_si128(ry+1, r1); +} + +#else +#define MEDIAN_HAVE_SIMD 0 +#endif + + +static inline void histogram_add( const HT x[16], HT y[16] ) +{ + int i; + for( i = 0; i < 16; ++i ) + y[i] = (HT)(y[i] + x[i]); +} + +static inline void histogram_sub( const HT x[16], HT y[16] ) +{ + int i; + for( i = 0; i < 16; ++i ) + y[i] = (HT)(y[i] - x[i]); +} + +static inline void histogram_muladd( int a, const HT x[16], + HT y[16] ) +{ + for( int i = 0; i < 16; ++i ) + y[i] = (HT)(y[i] + a * x[i]); +} + +static void +medianBlur_8u_O1( const Mat& _src, Mat& _dst, int ksize ) +{ +/** + * HOP is short for Histogram OPeration. This macro makes an operation \a op on + * histogram \a h for pixel value \a x. It takes care of handling both levels. + */ +#define HOP(h,x,op) \ + h.coarse[x>>4] op, \ + *((HT*)h.fine + x) op + +#define COP(c,j,x,op) \ + h_coarse[ 16*(n*c+j) + (x>>4) ] op, \ + h_fine[ 16 * (n*(16*c+(x>>4)) + j) + (x & 0xF) ] op + + int cn = _dst.channels(), m = _dst.rows, r = (ksize-1)/2; + size_t sstep = _src.step, dstep = _dst.step; + Histogram CV_DECL_ALIGNED(16) H[4]; + HT CV_DECL_ALIGNED(16) luc[4][16]; + + int STRIPE_SIZE = std::min( _dst.cols, 512/cn ); + + vector _h_coarse(1 * 16 * (STRIPE_SIZE + 2*r) * cn + 16); + vector _h_fine(16 * 16 * (STRIPE_SIZE + 2*r) * cn + 16); + HT* h_coarse = alignPtr(&_h_coarse[0], 16); + HT* h_fine = alignPtr(&_h_fine[0], 16); +#if MEDIAN_HAVE_SIMD + volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); +#endif + + for( int x = 0; x < _dst.cols; x += STRIPE_SIZE ) + { + int i, j, k, c, n = std::min(_dst.cols - x, STRIPE_SIZE) + r*2; + const uchar* src = _src.data + x*cn; + uchar* dst = _dst.data + (x - r)*cn; + + memset( h_coarse, 0, 16*n*cn*sizeof(h_coarse[0]) ); + memset( h_fine, 0, 16*16*n*cn*sizeof(h_fine[0]) ); + + // First row initialization + for( c = 0; c < cn; c++ ) + { + for( j = 0; j < n; j++ ) + COP( c, j, src[cn*j+c], += (cv::HT)(r+2) ); + + for( i = 1; i < r; i++ ) + { + const uchar* p = src + sstep*std::min(i, m-1); + for ( j = 0; j < n; j++ ) + COP( c, j, p[cn*j+c], ++ ); + } + } + + for( i = 0; i < m; i++ ) + { + const uchar* p0 = src + sstep * std::max( 0, i-r-1 ); + const uchar* p1 = src + sstep * std::min( m-1, i+r ); + + memset( H, 0, cn*sizeof(H[0]) ); + memset( luc, 0, cn*sizeof(luc[0]) ); + for( c = 0; c < cn; c++ ) + { + // Update column histograms for the entire row. + for( j = 0; j < n; j++ ) + { + COP( c, j, p0[j*cn + c], -- ); + COP( c, j, p1[j*cn + c], ++ ); + } + + // First column initialization + for( k = 0; k < 16; ++k ) + histogram_muladd( 2*r+1, &h_fine[16*n*(16*c+k)], &H[c].fine[k][0] ); + + #if MEDIAN_HAVE_SIMD + if( useSIMD ) + { + for( j = 0; j < 2*r; ++j ) + histogram_add_simd( &h_coarse[16*(n*c+j)], H[c].coarse ); + + for( j = r; j < n-r; j++ ) + { + int t = 2*r*r + 2*r, b, sum = 0; + HT* segment; + + histogram_add_simd( &h_coarse[16*(n*c + std::min(j+r,n-1))], H[c].coarse ); + + // Find median at coarse level + for ( k = 0; k < 16 ; ++k ) + { + sum += H[c].coarse[k]; + if ( sum > t ) + { + sum -= H[c].coarse[k]; + break; + } + } + assert( k < 16 ); + + /* Update corresponding histogram segment */ + if ( luc[c][k] <= j-r ) + { + memset( &H[c].fine[k], 0, 16 * sizeof(HT) ); + for ( luc[c][k] = cv::HT(j-r); luc[c][k] < MIN(j+r+1,n); ++luc[c][k] ) + histogram_add_simd( &h_fine[16*(n*(16*c+k)+luc[c][k])], H[c].fine[k] ); + + if ( luc[c][k] < j+r+1 ) + { + histogram_muladd( j+r+1 - n, &h_fine[16*(n*(16*c+k)+(n-1))], &H[c].fine[k][0] ); + luc[c][k] = (HT)(j+r+1); + } + } + else + { + for ( ; luc[c][k] < j+r+1; ++luc[c][k] ) + { + histogram_sub_simd( &h_fine[16*(n*(16*c+k)+MAX(luc[c][k]-2*r-1,0))], H[c].fine[k] ); + histogram_add_simd( &h_fine[16*(n*(16*c+k)+MIN(luc[c][k],n-1))], H[c].fine[k] ); + } + } + + histogram_sub_simd( &h_coarse[16*(n*c+MAX(j-r,0))], H[c].coarse ); + + /* Find median in segment */ + segment = H[c].fine[k]; + for ( b = 0; b < 16 ; b++ ) + { + sum += segment[b]; + if ( sum > t ) + { + dst[dstep*i+cn*j+c] = (uchar)(16*k + b); + break; + } + } + assert( b < 16 ); + } + } + else + #endif + { + for( j = 0; j < 2*r; ++j ) + histogram_add( &h_coarse[16*(n*c+j)], H[c].coarse ); + + for( j = r; j < n-r; j++ ) + { + int t = 2*r*r + 2*r, b, sum = 0; + HT* segment; + + histogram_add( &h_coarse[16*(n*c + std::min(j+r,n-1))], H[c].coarse ); + + // Find median at coarse level + for ( k = 0; k < 16 ; ++k ) + { + sum += H[c].coarse[k]; + if ( sum > t ) + { + sum -= H[c].coarse[k]; + break; + } + } + assert( k < 16 ); + + /* Update corresponding histogram segment */ + if ( luc[c][k] <= j-r ) + { + memset( &H[c].fine[k], 0, 16 * sizeof(HT) ); + for ( luc[c][k] = cv::HT(j-r); luc[c][k] < MIN(j+r+1,n); ++luc[c][k] ) + histogram_add( &h_fine[16*(n*(16*c+k)+luc[c][k])], H[c].fine[k] ); + + if ( luc[c][k] < j+r+1 ) + { + histogram_muladd( j+r+1 - n, &h_fine[16*(n*(16*c+k)+(n-1))], &H[c].fine[k][0] ); + luc[c][k] = (HT)(j+r+1); + } + } + else + { + for ( ; luc[c][k] < j+r+1; ++luc[c][k] ) + { + histogram_sub( &h_fine[16*(n*(16*c+k)+MAX(luc[c][k]-2*r-1,0))], H[c].fine[k] ); + histogram_add( &h_fine[16*(n*(16*c+k)+MIN(luc[c][k],n-1))], H[c].fine[k] ); + } + } + + histogram_sub( &h_coarse[16*(n*c+MAX(j-r,0))], H[c].coarse ); + + /* Find median in segment */ + segment = H[c].fine[k]; + for ( b = 0; b < 16 ; b++ ) + { + sum += segment[b]; + if ( sum > t ) + { + dst[dstep*i+cn*j+c] = (uchar)(16*k + b); + break; + } + } + assert( b < 16 ); + } + } + } + } + } + +#undef HOP +#undef COP +} + +static void +medianBlur_8u_Om( const Mat& _src, Mat& _dst, int m ) +{ + #define N 16 + int zone0[4][N]; + int zone1[4][N*N]; + int x, y; + int n2 = m*m/2; + Size size = _dst.size(); + const uchar* src = _src.data; + uchar* dst = _dst.data; + int src_step = (int)_src.step, dst_step = (int)_dst.step; + int cn = _src.channels(); + const uchar* src_max = src + size.height*src_step; + + #define UPDATE_ACC01( pix, cn, op ) \ + { \ + int p = (pix); \ + zone1[cn][p] op; \ + zone0[cn][p >> 4] op; \ + } + + //CV_Assert( size.height >= nx && size.width >= nx ); + for( x = 0; x < size.width; x++, src += cn, dst += cn ) + { + uchar* dst_cur = dst; + const uchar* src_top = src; + const uchar* src_bottom = src; + int k, c; + int src_step1 = src_step, dst_step1 = dst_step; + + if( x % 2 != 0 ) + { + src_bottom = src_top += src_step*(size.height-1); + dst_cur += dst_step*(size.height-1); + src_step1 = -src_step1; + dst_step1 = -dst_step1; + } + + // init accumulator + memset( zone0, 0, sizeof(zone0[0])*cn ); + memset( zone1, 0, sizeof(zone1[0])*cn ); + + for( y = 0; y <= m/2; y++ ) + { + for( c = 0; c < cn; c++ ) + { + if( y > 0 ) + { + for( k = 0; k < m*cn; k += cn ) + UPDATE_ACC01( src_bottom[k+c], c, ++ ); + } + else + { + for( k = 0; k < m*cn; k += cn ) + UPDATE_ACC01( src_bottom[k+c], c, += m/2+1 ); + } + } + + if( (src_step1 > 0 && y < size.height-1) || + (src_step1 < 0 && size.height-y-1 > 0) ) + src_bottom += src_step1; + } + + for( y = 0; y < size.height; y++, dst_cur += dst_step1 ) + { + // find median + for( c = 0; c < cn; c++ ) + { + int s = 0; + for( k = 0; ; k++ ) + { + int t = s + zone0[c][k]; + if( t > n2 ) break; + s = t; + } + + for( k *= N; ;k++ ) + { + s += zone1[c][k]; + if( s > n2 ) break; + } + + dst_cur[c] = (uchar)k; + } + + if( y+1 == size.height ) + break; + + if( cn == 1 ) + { + for( k = 0; k < m; k++ ) + { + int p = src_top[k]; + int q = src_bottom[k]; + zone1[0][p]--; + zone0[0][p>>4]--; + zone1[0][q]++; + zone0[0][q>>4]++; + } + } + else if( cn == 3 ) + { + for( k = 0; k < m*3; k += 3 ) + { + UPDATE_ACC01( src_top[k], 0, -- ); + UPDATE_ACC01( src_top[k+1], 1, -- ); + UPDATE_ACC01( src_top[k+2], 2, -- ); + + UPDATE_ACC01( src_bottom[k], 0, ++ ); + UPDATE_ACC01( src_bottom[k+1], 1, ++ ); + UPDATE_ACC01( src_bottom[k+2], 2, ++ ); + } + } + else + { + assert( cn == 4 ); + for( k = 0; k < m*4; k += 4 ) + { + UPDATE_ACC01( src_top[k], 0, -- ); + UPDATE_ACC01( src_top[k+1], 1, -- ); + UPDATE_ACC01( src_top[k+2], 2, -- ); + UPDATE_ACC01( src_top[k+3], 3, -- ); + + UPDATE_ACC01( src_bottom[k], 0, ++ ); + UPDATE_ACC01( src_bottom[k+1], 1, ++ ); + UPDATE_ACC01( src_bottom[k+2], 2, ++ ); + UPDATE_ACC01( src_bottom[k+3], 3, ++ ); + } + } + + if( (src_step1 > 0 && src_bottom + src_step1 < src_max) || + (src_step1 < 0 && src_bottom + src_step1 >= src) ) + src_bottom += src_step1; + + if( y >= m/2 ) + src_top += src_step1; + } + } +#undef N +#undef UPDATE_ACC +} + + +struct MinMax8u +{ + typedef uchar value_type; + typedef int arg_type; + enum { SIZE = 1 }; + arg_type load(const uchar* ptr) { return *ptr; } + void store(uchar* ptr, arg_type val) { *ptr = (uchar)val; } + void operator()(arg_type& a, arg_type& b) const + { + int t = CV_FAST_CAST_8U(a - b); + b += t; a -= t; + } +}; + +struct MinMax16u +{ + typedef ushort value_type; + typedef int arg_type; + enum { SIZE = 1 }; + arg_type load(const ushort* ptr) { return *ptr; } + void store(ushort* ptr, arg_type val) { *ptr = (ushort)val; } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = std::min(a, b); + b = std::max(b, t); + } +}; + +struct MinMax16s +{ + typedef short value_type; + typedef int arg_type; + enum { SIZE = 1 }; + arg_type load(const short* ptr) { return *ptr; } + void store(short* ptr, arg_type val) { *ptr = (short)val; } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = std::min(a, b); + b = std::max(b, t); + } +}; + +struct MinMax32f +{ + typedef float value_type; + typedef float arg_type; + enum { SIZE = 1 }; + arg_type load(const float* ptr) { return *ptr; } + void store(float* ptr, arg_type val) { *ptr = val; } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = std::min(a, b); + b = std::max(b, t); + } +}; + +#if CV_SSE2 + +struct MinMaxVec8u +{ + typedef uchar value_type; + typedef __m128i arg_type; + enum { SIZE = 16 }; + arg_type load(const uchar* ptr) { return _mm_loadu_si128((const __m128i*)ptr); } + void store(uchar* ptr, arg_type val) { _mm_storeu_si128((__m128i*)ptr, val); } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = _mm_min_epu8(a, b); + b = _mm_max_epu8(b, t); + } +}; + + +struct MinMaxVec16u +{ + typedef ushort value_type; + typedef __m128i arg_type; + enum { SIZE = 8 }; + arg_type load(const ushort* ptr) { return _mm_loadu_si128((const __m128i*)ptr); } + void store(ushort* ptr, arg_type val) { _mm_storeu_si128((__m128i*)ptr, val); } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = _mm_subs_epu16(a, b); + a = _mm_subs_epu16(a, t); + b = _mm_adds_epu16(b, t); + } +}; + + +struct MinMaxVec16s +{ + typedef short value_type; + typedef __m128i arg_type; + enum { SIZE = 8 }; + arg_type load(const short* ptr) { return _mm_loadu_si128((const __m128i*)ptr); } + void store(short* ptr, arg_type val) { _mm_storeu_si128((__m128i*)ptr, val); } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = _mm_min_epi16(a, b); + b = _mm_max_epi16(b, t); + } +}; + + +struct MinMaxVec32f +{ + typedef float value_type; + typedef __m128 arg_type; + enum { SIZE = 4 }; + arg_type load(const float* ptr) { return _mm_loadu_ps(ptr); } + void store(float* ptr, arg_type val) { _mm_storeu_ps(ptr, val); } + void operator()(arg_type& a, arg_type& b) const + { + arg_type t = a; + a = _mm_min_ps(a, b); + b = _mm_max_ps(b, t); + } +}; + + +#else + +typedef MinMax8u MinMaxVec8u; +typedef MinMax16u MinMaxVec16u; +typedef MinMax16s MinMaxVec16s; +typedef MinMax32f MinMaxVec32f; + +#endif + +template +static void +medianBlur_SortNet( const Mat& _src, Mat& _dst, int m ) +{ + typedef typename Op::value_type T; + typedef typename Op::arg_type WT; + typedef typename VecOp::arg_type VT; + + const T* src = (const T*)_src.data; + T* dst = (T*)_dst.data; + int sstep = (int)(_src.step/sizeof(T)); + int dstep = (int)(_dst.step/sizeof(T)); + Size size = _dst.size(); + int i, j, k, cn = _src.channels(); + Op op; + VecOp vop; + volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); + + if( m == 3 ) + { + if( size.width == 1 || size.height == 1 ) + { + int len = size.width + size.height - 1; + int sdelta = size.height == 1 ? cn : sstep; + int sdelta0 = size.height == 1 ? 0 : sstep - cn; + int ddelta = size.height == 1 ? cn : dstep; + + for( i = 0; i < len; i++, src += sdelta0, dst += ddelta ) + for( j = 0; j < cn; j++, src++ ) + { + WT p0 = src[i > 0 ? -sdelta : 0]; + WT p1 = src[0]; + WT p2 = src[i < len - 1 ? sdelta : 0]; + + op(p0, p1); op(p1, p2); op(p0, p1); + dst[j] = (T)p1; + } + return; + } + + size.width *= cn; + for( i = 0; i < size.height; i++, dst += dstep ) + { + const T* row0 = src + std::max(i - 1, 0)*sstep; + const T* row1 = src + i*sstep; + const T* row2 = src + std::min(i + 1, size.height-1)*sstep; + int limit = useSIMD ? cn : size.width; + + for(j = 0;; ) + { + for( ; j < limit; j++ ) + { + int j0 = j >= cn ? j - cn : j; + int j2 = j < size.width - cn ? j + cn : j; + WT p0 = row0[j0], p1 = row0[j], p2 = row0[j2]; + WT p3 = row1[j0], p4 = row1[j], p5 = row1[j2]; + WT p6 = row2[j0], p7 = row2[j], p8 = row2[j2]; + + op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1); + op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5); + op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7); + op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7); + op(p4, p2); op(p6, p4); op(p4, p2); + dst[j] = (T)p4; + } + + if( limit == size.width ) + break; + + for( ; j <= size.width - VecOp::SIZE - cn; j += VecOp::SIZE ) + { + VT p0 = vop.load(row0+j-cn), p1 = vop.load(row0+j), p2 = vop.load(row0+j+cn); + VT p3 = vop.load(row1+j-cn), p4 = vop.load(row1+j), p5 = vop.load(row1+j+cn); + VT p6 = vop.load(row2+j-cn), p7 = vop.load(row2+j), p8 = vop.load(row2+j+cn); + + vop(p1, p2); vop(p4, p5); vop(p7, p8); vop(p0, p1); + vop(p3, p4); vop(p6, p7); vop(p1, p2); vop(p4, p5); + vop(p7, p8); vop(p0, p3); vop(p5, p8); vop(p4, p7); + vop(p3, p6); vop(p1, p4); vop(p2, p5); vop(p4, p7); + vop(p4, p2); vop(p6, p4); vop(p4, p2); + vop.store(dst+j, p4); + } + + limit = size.width; + } + } + } + else if( m == 5 ) + { + if( size.width == 1 || size.height == 1 ) + { + int len = size.width + size.height - 1; + int sdelta = size.height == 1 ? cn : sstep; + int sdelta0 = size.height == 1 ? 0 : sstep - cn; + int ddelta = size.height == 1 ? cn : dstep; + + for( i = 0; i < len; i++, src += sdelta0, dst += ddelta ) + for( j = 0; j < cn; j++, src++ ) + { + int i1 = i > 0 ? -sdelta : 0; + int i0 = i > 1 ? -sdelta*2 : i1; + int i3 = i < len-1 ? sdelta : 0; + int i4 = i < len-2 ? sdelta*2 : i3; + WT p0 = src[i0], p1 = src[i1], p2 = src[0], p3 = src[i3], p4 = src[i4]; + + op(p0, p1); op(p3, p4); op(p2, p3); op(p3, p4); op(p0, p2); + op(p2, p4); op(p1, p3); op(p1, p2); + dst[j] = (T)p2; + } + return; + } + + size.width *= cn; + for( i = 0; i < size.height; i++, dst += dstep ) + { + const T* row[5]; + row[0] = src + std::max(i - 2, 0)*sstep; + row[1] = src + std::max(i - 1, 0)*sstep; + row[2] = src + i*sstep; + row[3] = src + std::min(i + 1, size.height-1)*sstep; + row[4] = src + std::min(i + 2, size.height-1)*sstep; + int limit = useSIMD ? cn*2 : size.width; + + for(j = 0;; ) + { + for( ; j < limit; j++ ) + { + WT p[25]; + int j1 = j >= cn ? j - cn : j; + int j0 = j >= cn*2 ? j - cn*2 : j1; + int j3 = j < size.width - cn ? j + cn : j; + int j4 = j < size.width - cn*2 ? j + cn*2 : j3; + for( k = 0; k < 5; k++ ) + { + const T* rowk = row[k]; + p[k*5] = rowk[j0]; p[k*5+1] = rowk[j1]; + p[k*5+2] = rowk[j]; p[k*5+3] = rowk[j3]; + p[k*5+4] = rowk[j4]; + } + + op(p[1], p[2]); op(p[0], p[1]); op(p[1], p[2]); op(p[4], p[5]); op(p[3], p[4]); + op(p[4], p[5]); op(p[0], p[3]); op(p[2], p[5]); op(p[2], p[3]); op(p[1], p[4]); + op(p[1], p[2]); op(p[3], p[4]); op(p[7], p[8]); op(p[6], p[7]); op(p[7], p[8]); + op(p[10], p[11]); op(p[9], p[10]); op(p[10], p[11]); op(p[6], p[9]); op(p[8], p[11]); + op(p[8], p[9]); op(p[7], p[10]); op(p[7], p[8]); op(p[9], p[10]); op(p[0], p[6]); + op(p[4], p[10]); op(p[4], p[6]); op(p[2], p[8]); op(p[2], p[4]); op(p[6], p[8]); + op(p[1], p[7]); op(p[5], p[11]); op(p[5], p[7]); op(p[3], p[9]); op(p[3], p[5]); + op(p[7], p[9]); op(p[1], p[2]); op(p[3], p[4]); op(p[5], p[6]); op(p[7], p[8]); + op(p[9], p[10]); op(p[13], p[14]); op(p[12], p[13]); op(p[13], p[14]); op(p[16], p[17]); + op(p[15], p[16]); op(p[16], p[17]); op(p[12], p[15]); op(p[14], p[17]); op(p[14], p[15]); + op(p[13], p[16]); op(p[13], p[14]); op(p[15], p[16]); op(p[19], p[20]); op(p[18], p[19]); + op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[21], p[23]); op(p[22], p[24]); + op(p[22], p[23]); op(p[18], p[21]); op(p[20], p[23]); op(p[20], p[21]); op(p[19], p[22]); + op(p[22], p[24]); op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[12], p[18]); + op(p[16], p[22]); op(p[16], p[18]); op(p[14], p[20]); op(p[20], p[24]); op(p[14], p[16]); + op(p[18], p[20]); op(p[22], p[24]); op(p[13], p[19]); op(p[17], p[23]); op(p[17], p[19]); + op(p[15], p[21]); op(p[15], p[17]); op(p[19], p[21]); op(p[13], p[14]); op(p[15], p[16]); + op(p[17], p[18]); op(p[19], p[20]); op(p[21], p[22]); op(p[23], p[24]); op(p[0], p[12]); + op(p[8], p[20]); op(p[8], p[12]); op(p[4], p[16]); op(p[16], p[24]); op(p[12], p[16]); + op(p[2], p[14]); op(p[10], p[22]); op(p[10], p[14]); op(p[6], p[18]); op(p[6], p[10]); + op(p[10], p[12]); op(p[1], p[13]); op(p[9], p[21]); op(p[9], p[13]); op(p[5], p[17]); + op(p[13], p[17]); op(p[3], p[15]); op(p[11], p[23]); op(p[11], p[15]); op(p[7], p[19]); + op(p[7], p[11]); op(p[11], p[13]); op(p[11], p[12]); + dst[j] = (T)p[12]; + } + + if( limit == size.width ) + break; + + for( ; j <= size.width - VecOp::SIZE - cn*2; j += VecOp::SIZE ) + { + VT p[25]; + for( k = 0; k < 5; k++ ) + { + const T* rowk = row[k]; + p[k*5] = vop.load(rowk+j-cn*2); p[k*5+1] = vop.load(rowk+j-cn); + p[k*5+2] = vop.load(rowk+j); p[k*5+3] = vop.load(rowk+j+cn); + p[k*5+4] = vop.load(rowk+j+cn*2); + } + + vop(p[1], p[2]); vop(p[0], p[1]); vop(p[1], p[2]); vop(p[4], p[5]); vop(p[3], p[4]); + vop(p[4], p[5]); vop(p[0], p[3]); vop(p[2], p[5]); vop(p[2], p[3]); vop(p[1], p[4]); + vop(p[1], p[2]); vop(p[3], p[4]); vop(p[7], p[8]); vop(p[6], p[7]); vop(p[7], p[8]); + vop(p[10], p[11]); vop(p[9], p[10]); vop(p[10], p[11]); vop(p[6], p[9]); vop(p[8], p[11]); + vop(p[8], p[9]); vop(p[7], p[10]); vop(p[7], p[8]); vop(p[9], p[10]); vop(p[0], p[6]); + vop(p[4], p[10]); vop(p[4], p[6]); vop(p[2], p[8]); vop(p[2], p[4]); vop(p[6], p[8]); + vop(p[1], p[7]); vop(p[5], p[11]); vop(p[5], p[7]); vop(p[3], p[9]); vop(p[3], p[5]); + vop(p[7], p[9]); vop(p[1], p[2]); vop(p[3], p[4]); vop(p[5], p[6]); vop(p[7], p[8]); + vop(p[9], p[10]); vop(p[13], p[14]); vop(p[12], p[13]); vop(p[13], p[14]); vop(p[16], p[17]); + vop(p[15], p[16]); vop(p[16], p[17]); vop(p[12], p[15]); vop(p[14], p[17]); vop(p[14], p[15]); + vop(p[13], p[16]); vop(p[13], p[14]); vop(p[15], p[16]); vop(p[19], p[20]); vop(p[18], p[19]); + vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[21], p[23]); vop(p[22], p[24]); + vop(p[22], p[23]); vop(p[18], p[21]); vop(p[20], p[23]); vop(p[20], p[21]); vop(p[19], p[22]); + vop(p[22], p[24]); vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[12], p[18]); + vop(p[16], p[22]); vop(p[16], p[18]); vop(p[14], p[20]); vop(p[20], p[24]); vop(p[14], p[16]); + vop(p[18], p[20]); vop(p[22], p[24]); vop(p[13], p[19]); vop(p[17], p[23]); vop(p[17], p[19]); + vop(p[15], p[21]); vop(p[15], p[17]); vop(p[19], p[21]); vop(p[13], p[14]); vop(p[15], p[16]); + vop(p[17], p[18]); vop(p[19], p[20]); vop(p[21], p[22]); vop(p[23], p[24]); vop(p[0], p[12]); + vop(p[8], p[20]); vop(p[8], p[12]); vop(p[4], p[16]); vop(p[16], p[24]); vop(p[12], p[16]); + vop(p[2], p[14]); vop(p[10], p[22]); vop(p[10], p[14]); vop(p[6], p[18]); vop(p[6], p[10]); + vop(p[10], p[12]); vop(p[1], p[13]); vop(p[9], p[21]); vop(p[9], p[13]); vop(p[5], p[17]); + vop(p[13], p[17]); vop(p[3], p[15]); vop(p[11], p[23]); vop(p[11], p[15]); vop(p[7], p[19]); + vop(p[7], p[11]); vop(p[11], p[13]); vop(p[11], p[12]); + vop.store(dst+j, p[12]); + } + + limit = size.width; + } + } + } +} + +} + +void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize ) +{ + Mat src0 = _src0.getMat(); + _dst.create( src0.size(), src0.type() ); + Mat dst = _dst.getMat(); + + if( ksize <= 1 ) + { + src0.copyTo(dst); + return; + } + + CV_Assert( ksize % 2 == 1 ); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::medianBlur(src0, dst, ksize)) + return; +#endif + + bool useSortNet = ksize == 3 || (ksize == 5 +#if !CV_SSE2 + && src0.depth() > CV_8U +#endif + ); + + Mat src; + if( useSortNet ) + { + if( dst.data != src0.data ) + src = src0; + else + src0.copyTo(src); + + if( src.depth() == CV_8U ) + medianBlur_SortNet( src, dst, ksize ); + else if( src.depth() == CV_16U ) + medianBlur_SortNet( src, dst, ksize ); + else if( src.depth() == CV_16S ) + medianBlur_SortNet( src, dst, ksize ); + else if( src.depth() == CV_32F ) + medianBlur_SortNet( src, dst, ksize ); + else + CV_Error(CV_StsUnsupportedFormat, ""); + + return; + } + else + { + cv::copyMakeBorder( src0, src, 0, 0, ksize/2, ksize/2, BORDER_REPLICATE ); + + int cn = src0.channels(); + CV_Assert( src.depth() == CV_8U && (cn == 1 || cn == 3 || cn == 4) ); + + double img_size_mp = (double)(src0.total())/(1 << 20); + if( ksize <= 3 + (img_size_mp < 1 ? 12 : img_size_mp < 4 ? 6 : 2)*(MEDIAN_HAVE_SIMD && checkHardwareSupport(CV_CPU_SSE2) ? 1 : 3)) + medianBlur_8u_Om( src, dst, ksize ); + else + medianBlur_8u_O1( src, dst, ksize ); + } +} + +/****************************************************************************************\ + Bilateral Filtering +\****************************************************************************************/ + +namespace cv +{ + +class BilateralFilter_8u_Invoker : + public ParallelLoopBody +{ +public: + BilateralFilter_8u_Invoker(Mat& _dest, const Mat& _temp, int _radius, int _maxk, + int* _space_ofs, float *_space_weight, float *_color_weight) : + temp(&_temp), dest(&_dest), radius(_radius), + maxk(_maxk), space_ofs(_space_ofs), space_weight(_space_weight), color_weight(_color_weight) + { + } + + virtual void operator() (const Range& range) const + { + int i, j, cn = dest->channels(), k; + Size size = dest->size(); + #if CV_SSE3 + int CV_DECL_ALIGNED(16) buf[4]; + float CV_DECL_ALIGNED(16) bufSum[4]; + static const int CV_DECL_ALIGNED(16) bufSignMask[] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + bool haveSSE3 = checkHardwareSupport(CV_CPU_SSE3); + #endif + + for( i = range.start; i < range.end; i++ ) + { + const uchar* sptr = temp->ptr(i+radius) + radius*cn; + uchar* dptr = dest->ptr(i); + + if( cn == 1 ) + { + for( j = 0; j < size.width; j++ ) + { + float sum = 0, wsum = 0; + int val0 = sptr[j]; + k = 0; + #if CV_SSE3 + if( haveSSE3 ) + { + __m128 _val0 = _mm_set1_ps(static_cast(val0)); + const __m128 _signMask = _mm_load_ps((const float*)bufSignMask); + + for( ; k <= maxk - 4; k += 4 ) + { + __m128 _valF = _mm_set_ps(sptr[j + space_ofs[k+3]], sptr[j + space_ofs[k+2]], + sptr[j + space_ofs[k+1]], sptr[j + space_ofs[k]]); + + __m128 _val = _mm_andnot_ps(_signMask, _mm_sub_ps(_valF, _val0)); + _mm_store_si128((__m128i*)buf, _mm_cvtps_epi32(_val)); + + __m128 _cw = _mm_set_ps(color_weight[buf[3]],color_weight[buf[2]], + color_weight[buf[1]],color_weight[buf[0]]); + __m128 _sw = _mm_loadu_ps(space_weight+k); + __m128 _w = _mm_mul_ps(_cw, _sw); + _cw = _mm_mul_ps(_w, _valF); + + _sw = _mm_hadd_ps(_w, _cw); + _sw = _mm_hadd_ps(_sw, _sw); + _mm_storel_pi((__m64*)bufSum, _sw); + + sum += bufSum[1]; + wsum += bufSum[0]; + } + } + #endif + for( ; k < maxk; k++ ) + { + int val = sptr[j + space_ofs[k]]; + float w = space_weight[k]*color_weight[std::abs(val - val0)]; + sum += val*w; + wsum += w; + } + // overflow is not possible here => there is no need to use CV_CAST_8U + dptr[j] = (uchar)cvRound(sum/wsum); + } + } + else + { + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) + { + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + k = 0; + #if CV_SSE3 + if( haveSSE3 ) + { + const __m128 _b0 = _mm_set1_ps(static_cast(b0)); + const __m128 _g0 = _mm_set1_ps(static_cast(g0)); + const __m128 _r0 = _mm_set1_ps(static_cast(r0)); + const __m128 _signMask = _mm_load_ps((const float*)bufSignMask); + + for( ; k <= maxk - 4; k += 4 ) + { + const uchar* sptr_k = sptr + j + space_ofs[k]; + const uchar* sptr_k1 = sptr + j + space_ofs[k+1]; + const uchar* sptr_k2 = sptr + j + space_ofs[k+2]; + const uchar* sptr_k3 = sptr + j + space_ofs[k+3]; + + __m128 _b = _mm_set_ps(sptr_k3[0],sptr_k2[0],sptr_k1[0],sptr_k[0]); + __m128 _g = _mm_set_ps(sptr_k3[1],sptr_k2[1],sptr_k1[1],sptr_k[1]); + __m128 _r = _mm_set_ps(sptr_k3[2],sptr_k2[2],sptr_k1[2],sptr_k[2]); + + __m128 bt = _mm_andnot_ps(_signMask, _mm_sub_ps(_b,_b0)); + __m128 gt = _mm_andnot_ps(_signMask, _mm_sub_ps(_g,_g0)); + __m128 rt = _mm_andnot_ps(_signMask, _mm_sub_ps(_r,_r0)); + + bt =_mm_add_ps(rt, _mm_add_ps(bt, gt)); + _mm_store_si128((__m128i*)buf, _mm_cvtps_epi32(bt)); + + __m128 _w = _mm_set_ps(color_weight[buf[3]],color_weight[buf[2]], + color_weight[buf[1]],color_weight[buf[0]]); + __m128 _sw = _mm_loadu_ps(space_weight+k); + + _w = _mm_mul_ps(_w,_sw); + _b = _mm_mul_ps(_b, _w); + _g = _mm_mul_ps(_g, _w); + _r = _mm_mul_ps(_r, _w); + + _w = _mm_hadd_ps(_w, _b); + _g = _mm_hadd_ps(_g, _r); + + _w = _mm_hadd_ps(_w, _g); + _mm_store_ps(bufSum, _w); + + wsum += bufSum[0]; + sum_b += bufSum[1]; + sum_g += bufSum[2]; + sum_r += bufSum[3]; + } + } + #endif + + for( ; k < maxk; k++ ) + { + const uchar* sptr_k = sptr + j + space_ofs[k]; + int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float w = space_weight[k]*color_weight[std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0)]; + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = cvRound(sum_b*wsum); + g0 = cvRound(sum_g*wsum); + r0 = cvRound(sum_r*wsum); + dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0; + } + } + } + } + +private: + const Mat *temp; + Mat *dest; + int radius, maxk, *space_ofs; + float *space_weight, *color_weight; +}; + +static void +bilateralFilter_8u( const Mat& src, Mat& dst, int d, + double sigma_color, double sigma_space, + int borderType ) +{ + + int cn = src.channels(); + int i, j, maxk, radius; + Size size = src.size(); + + CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) && + src.type() == dst.type() && src.size() == dst.size() && + src.data != dst.data ); + + if( sigma_color <= 0 ) + sigma_color = 1; + if( sigma_space <= 0 ) + sigma_space = 1; + + double gauss_color_coeff = -0.5/(sigma_color*sigma_color); + double gauss_space_coeff = -0.5/(sigma_space*sigma_space); + + if( d <= 0 ) + radius = cvRound(sigma_space*1.5); + else + radius = d/2; + radius = MAX(radius, 1); + d = radius*2 + 1; + + Mat temp; + copyMakeBorder( src, temp, radius, radius, radius, radius, borderType ); + + vector _color_weight(cn*256); + vector _space_weight(d*d); + vector _space_ofs(d*d); + float* color_weight = &_color_weight[0]; + float* space_weight = &_space_weight[0]; + int* space_ofs = &_space_ofs[0]; + + // initialize color-related bilateral filter coefficients + + for( i = 0; i < 256*cn; i++ ) + color_weight[i] = (float)std::exp(i*i*gauss_color_coeff); + + // initialize space-related bilateral filter coefficients + for( i = -radius, maxk = 0; i <= radius; i++ ) + { + j = -radius; + + for( ;j <= radius; j++ ) + { + double r = std::sqrt((double)i*i + (double)j*j); + if( r > radius ) + continue; + space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); + space_ofs[maxk++] = (int)(i*temp.step + j*cn); + } + } + + BilateralFilter_8u_Invoker body(dst, temp, radius, maxk, space_ofs, space_weight, color_weight); + parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16)); +} + + +class BilateralFilter_32f_Invoker : + public ParallelLoopBody +{ +public: + + BilateralFilter_32f_Invoker(int _cn, int _radius, int _maxk, int *_space_ofs, + const Mat& _temp, Mat& _dest, float _scale_index, float *_space_weight, float *_expLUT) : + cn(_cn), radius(_radius), maxk(_maxk), space_ofs(_space_ofs), + temp(&_temp), dest(&_dest), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT) + { + } + + virtual void operator() (const Range& range) const + { + int i, j, k; + Size size = dest->size(); + #if CV_SSE3 + int CV_DECL_ALIGNED(16) idxBuf[4]; + float CV_DECL_ALIGNED(16) bufSum32[4]; + static const int CV_DECL_ALIGNED(16) bufSignMask[] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + bool haveSSE3 = checkHardwareSupport(CV_CPU_SSE3); + #endif + + for( i = range.start; i < range.end; i++ ) + { + const float* sptr = temp->ptr(i+radius) + radius*cn; + float* dptr = dest->ptr(i); + + if( cn == 1 ) + { + for( j = 0; j < size.width; j++ ) + { + float sum = 0, wsum = 0; + float val0 = sptr[j]; + k = 0; + #if CV_SSE3 + if( haveSSE3 ) + { + const __m128 _val0 = _mm_set1_ps(sptr[j]); + const __m128 _scale_index = _mm_set1_ps(scale_index); + const __m128 _signMask = _mm_load_ps((const float*)bufSignMask); + + for( ; k <= maxk - 4 ; k += 4 ) + { + __m128 _sw = _mm_loadu_ps(space_weight + k); + __m128 _val = _mm_set_ps(sptr[j + space_ofs[k+3]], sptr[j + space_ofs[k+2]], + sptr[j + space_ofs[k+1]], sptr[j + space_ofs[k]]); + __m128 _alpha = _mm_mul_ps(_mm_andnot_ps( _signMask, _mm_sub_ps(_val,_val0)), _scale_index); + + __m128i _idx = _mm_cvtps_epi32(_alpha); + _mm_store_si128((__m128i*)idxBuf, _idx); + _alpha = _mm_sub_ps(_alpha, _mm_cvtepi32_ps(_idx)); + + __m128 _explut = _mm_set_ps(expLUT[idxBuf[3]], expLUT[idxBuf[2]], + expLUT[idxBuf[1]], expLUT[idxBuf[0]]); + __m128 _explut1 = _mm_set_ps(expLUT[idxBuf[3]+1], expLUT[idxBuf[2]+1], + expLUT[idxBuf[1]+1], expLUT[idxBuf[0]+1]); + + __m128 _w = _mm_mul_ps(_sw, _mm_add_ps(_explut, _mm_mul_ps(_alpha, _mm_sub_ps(_explut1, _explut)))); + _val = _mm_mul_ps(_w, _val); + + _sw = _mm_hadd_ps(_w, _val); + _sw = _mm_hadd_ps(_sw, _sw); + _mm_storel_pi((__m64*)bufSum32, _sw); + + sum += bufSum32[1]; + wsum += bufSum32[0]; + } + } + #endif + + for( ; k < maxk; k++ ) + { + float val = sptr[j + space_ofs[k]]; + float alpha = (float)(std::abs(val - val0)*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum += val*w; + wsum += w; + } + dptr[j] = (float)(sum/wsum); + } + } + else + { + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) + { + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + k = 0; + #if CV_SSE3 + if( haveSSE3 ) + { + const __m128 _b0 = _mm_set1_ps(b0); + const __m128 _g0 = _mm_set1_ps(g0); + const __m128 _r0 = _mm_set1_ps(r0); + const __m128 _scale_index = _mm_set1_ps(scale_index); + const __m128 _signMask = _mm_load_ps((const float*)bufSignMask); + + for( ; k <= maxk-4; k += 4 ) + { + __m128 _sw = _mm_loadu_ps(space_weight + k); + + const float* sptr_k = sptr + j + space_ofs[k]; + const float* sptr_k1 = sptr + j + space_ofs[k+1]; + const float* sptr_k2 = sptr + j + space_ofs[k+2]; + const float* sptr_k3 = sptr + j + space_ofs[k+3]; + + __m128 _b = _mm_set_ps(sptr_k3[0], sptr_k2[0], sptr_k1[0], sptr_k[0]); + __m128 _g = _mm_set_ps(sptr_k3[1], sptr_k2[1], sptr_k1[1], sptr_k[1]); + __m128 _r = _mm_set_ps(sptr_k3[2], sptr_k2[2], sptr_k1[2], sptr_k[2]); + + __m128 _bt = _mm_andnot_ps(_signMask,_mm_sub_ps(_b,_b0)); + __m128 _gt = _mm_andnot_ps(_signMask,_mm_sub_ps(_g,_g0)); + __m128 _rt = _mm_andnot_ps(_signMask,_mm_sub_ps(_r,_r0)); + + __m128 _alpha = _mm_mul_ps(_scale_index, _mm_add_ps(_rt,_mm_add_ps(_bt, _gt))); + + __m128i _idx = _mm_cvtps_epi32(_alpha); + _mm_store_si128((__m128i*)idxBuf, _idx); + _alpha = _mm_sub_ps(_alpha, _mm_cvtepi32_ps(_idx)); + + __m128 _explut = _mm_set_ps(expLUT[idxBuf[3]], expLUT[idxBuf[2]], expLUT[idxBuf[1]], expLUT[idxBuf[0]]); + __m128 _explut1 = _mm_set_ps(expLUT[idxBuf[3]+1], expLUT[idxBuf[2]+1], expLUT[idxBuf[1]+1], expLUT[idxBuf[0]+1]); + + __m128 _w = _mm_mul_ps(_sw, _mm_add_ps(_explut, _mm_mul_ps(_alpha, _mm_sub_ps(_explut1, _explut)))); + + _b = _mm_mul_ps(_b, _w); + _g = _mm_mul_ps(_g, _w); + _r = _mm_mul_ps(_r, _w); + + _w = _mm_hadd_ps(_w, _b); + _g = _mm_hadd_ps(_g, _r); + + _w = _mm_hadd_ps(_w, _g); + _mm_store_ps(bufSum32, _w); + + wsum += bufSum32[0]; + sum_b += bufSum32[1]; + sum_g += bufSum32[2]; + sum_r += bufSum32[3]; + } + + } + #endif + + for(; k < maxk; k++ ) + { + const float* sptr_k = sptr + j + space_ofs[k]; + float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float alpha = (float)((std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0))*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = sum_b*wsum; + g0 = sum_g*wsum; + r0 = sum_r*wsum; + dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0; + } + } + } + } + +private: + int cn, radius, maxk, *space_ofs; + const Mat* temp; + Mat *dest; + float scale_index, *space_weight, *expLUT; +}; + + +static void +bilateralFilter_32f( const Mat& src, Mat& dst, int d, + double sigma_color, double sigma_space, + int borderType ) +{ + int cn = src.channels(); + int i, j, maxk, radius; + double minValSrc=-1, maxValSrc=1; + const int kExpNumBinsPerChannel = 1 << 12; + int kExpNumBins = 0; + float lastExpVal = 1.f; + float len, scale_index; + Size size = src.size(); + + CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) && + src.type() == dst.type() && src.size() == dst.size() && + src.data != dst.data ); + + if( sigma_color <= 0 ) + sigma_color = 1; + if( sigma_space <= 0 ) + sigma_space = 1; + + double gauss_color_coeff = -0.5/(sigma_color*sigma_color); + double gauss_space_coeff = -0.5/(sigma_space*sigma_space); + + if( d <= 0 ) + radius = cvRound(sigma_space*1.5); + else + radius = d/2; + radius = MAX(radius, 1); + d = radius*2 + 1; + // compute the min/max range for the input image (even if multichannel) + + minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc ); + if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON) + { + src.copyTo(dst); + return; + } + + // temporary copy of the image with borders for easy processing + Mat temp; + copyMakeBorder( src, temp, radius, radius, radius, radius, borderType ); + const double insteadNaNValue = -5. * sigma_color; + patchNaNs( temp, insteadNaNValue ); // this replacement of NaNs makes the assumption that depth values are nonnegative + // TODO: make insteadNaNValue avalible in the outside function interface to control the cases breaking the assumption + // allocate lookup tables + vector _space_weight(d*d); + vector _space_ofs(d*d); + float* space_weight = &_space_weight[0]; + int* space_ofs = &_space_ofs[0]; + + // assign a length which is slightly more than needed + len = (float)(maxValSrc - minValSrc) * cn; + kExpNumBins = kExpNumBinsPerChannel * cn; + vector _expLUT(kExpNumBins+2); + float* expLUT = &_expLUT[0]; + + scale_index = kExpNumBins/len; + + // initialize the exp LUT + for( i = 0; i < kExpNumBins+2; i++ ) + { + if( lastExpVal > 0.f ) + { + double val = i / scale_index; + expLUT[i] = (float)std::exp(val * val * gauss_color_coeff); + lastExpVal = expLUT[i]; + } + else + expLUT[i] = 0.f; + } + + // initialize space-related bilateral filter coefficients + for( i = -radius, maxk = 0; i <= radius; i++ ) + for( j = -radius; j <= radius; j++ ) + { + double r = std::sqrt((double)i*i + (double)j*j); + if( r > radius ) + continue; + space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); + space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn); + } + + // parallel_for usage + + BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT); + parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16)); +} + +} + +void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d, + double sigmaColor, double sigmaSpace, + int borderType ) +{ + Mat src = _src.getMat(); + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( src.depth() == CV_8U ) + bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType ); + else if( src.depth() == CV_32F ) + bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType ); + else + CV_Error( CV_StsUnsupportedFormat, + "Bilateral filtering is only implemented for 8u and 32f images" ); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +CV_IMPL void +cvSmooth( const void* srcarr, void* dstarr, int smooth_type, + int param1, int param2, double param3, double param4 ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0; + + CV_Assert( dst.size() == src.size() && + (smooth_type == CV_BLUR_NO_SCALE || dst.type() == src.type()) ); + + if( param2 <= 0 ) + param2 = param1; + + if( smooth_type == CV_BLUR || smooth_type == CV_BLUR_NO_SCALE ) + cv::boxFilter( src, dst, dst.depth(), cv::Size(param1, param2), cv::Point(-1,-1), + smooth_type == CV_BLUR, cv::BORDER_REPLICATE ); + else if( smooth_type == CV_GAUSSIAN ) + cv::GaussianBlur( src, dst, cv::Size(param1, param2), param3, param4, cv::BORDER_REPLICATE ); + else if( smooth_type == CV_MEDIAN ) + cv::medianBlur( src, dst, param1 ); + else + cv::bilateralFilter( src, dst, param1, param3, param4, cv::BORDER_REPLICATE ); + + if( dst.data != dst0.data ) + CV_Error( CV_StsUnmatchedFormats, "The destination image does not have the proper type" ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/subdivision2d.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/subdivision2d.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/subdivision2d.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/subdivision2d.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,827 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "precomp.hpp" + +namespace cv +{ + +int Subdiv2D::nextEdge(int edge) const +{ + CV_DbgAssert((size_t)(edge >> 2) < qedges.size()); + return qedges[edge >> 2].next[edge & 3]; +} + +int Subdiv2D::rotateEdge(int edge, int rotate) const +{ + return (edge & ~3) + ((edge + rotate) & 3); +} + +int Subdiv2D::symEdge(int edge) const +{ + return edge ^ 2; +} + +int Subdiv2D::getEdge(int edge, int nextEdgeType) const +{ + CV_DbgAssert((size_t)(edge >> 2) < qedges.size()); + edge = qedges[edge >> 2].next[(edge + nextEdgeType) & 3]; + return (edge & ~3) + ((edge + (nextEdgeType >> 4)) & 3); +} + +int Subdiv2D::edgeOrg(int edge, CV_OUT Point2f* orgpt) const +{ + CV_DbgAssert((size_t)(edge >> 2) < qedges.size()); + int vidx = qedges[edge >> 2].pt[edge & 3]; + if( orgpt ) + { + CV_DbgAssert((size_t)vidx < vtx.size()); + *orgpt = vtx[vidx].pt; + } + return vidx; +} + +int Subdiv2D::edgeDst(int edge, CV_OUT Point2f* dstpt) const +{ + CV_DbgAssert((size_t)(edge >> 2) < qedges.size()); + int vidx = qedges[edge >> 2].pt[(edge + 2) & 3]; + if( dstpt ) + { + CV_DbgAssert((size_t)vidx < vtx.size()); + *dstpt = vtx[vidx].pt; + } + return vidx; +} + + +Point2f Subdiv2D::getVertex(int vertex, CV_OUT int* firstEdge) const +{ + CV_DbgAssert((size_t)vertex < vtx.size()); + if( firstEdge ) + *firstEdge = vtx[vertex].firstEdge; + return vtx[vertex].pt; +} + + +Subdiv2D::Subdiv2D() +{ + validGeometry = false; + freeQEdge = 0; + freePoint = 0; + recentEdge = 0; +} + +Subdiv2D::Subdiv2D(Rect rect) +{ + validGeometry = false; + freeQEdge = 0; + freePoint = 0; + recentEdge = 0; + + initDelaunay(rect); +} + + +Subdiv2D::QuadEdge::QuadEdge() +{ + next[0] = next[1] = next[2] = next[3] = 0; + pt[0] = pt[1] = pt[2] = pt[3] = 0; +} + +Subdiv2D::QuadEdge::QuadEdge(int edgeidx) +{ + CV_DbgAssert((edgeidx & 3) == 0); + next[0] = edgeidx; + next[1] = edgeidx+3; + next[2] = edgeidx+2; + next[3] = edgeidx+1; + + pt[0] = pt[1] = pt[2] = pt[3] = 0; +} + +bool Subdiv2D::QuadEdge::isfree() const +{ + return next[0] <= 0; +} + +Subdiv2D::Vertex::Vertex() +{ + firstEdge = 0; + type = -1; +} + +Subdiv2D::Vertex::Vertex(Point2f _pt, bool _isvirtual, int _firstEdge) +{ + firstEdge = _firstEdge; + type = (int)_isvirtual; + pt = _pt; +} + +bool Subdiv2D::Vertex::isvirtual() const +{ + return type > 0; +} + +bool Subdiv2D::Vertex::isfree() const +{ + return type < 0; +} + +void Subdiv2D::splice( int edgeA, int edgeB ) +{ + int& a_next = qedges[edgeA >> 2].next[edgeA & 3]; + int& b_next = qedges[edgeB >> 2].next[edgeB & 3]; + int a_rot = rotateEdge(a_next, 1); + int b_rot = rotateEdge(b_next, 1); + int& a_rot_next = qedges[a_rot >> 2].next[a_rot & 3]; + int& b_rot_next = qedges[b_rot >> 2].next[b_rot & 3]; + std::swap(a_next, b_next); + std::swap(a_rot_next, b_rot_next); +} + +void Subdiv2D::setEdgePoints(int edge, int orgPt, int dstPt) +{ + qedges[edge >> 2].pt[edge & 3] = orgPt; + qedges[edge >> 2].pt[(edge + 2) & 3] = dstPt; + vtx[orgPt].firstEdge = edge; + vtx[dstPt].firstEdge = edge ^ 2; +} + +int Subdiv2D::connectEdges( int edgeA, int edgeB ) +{ + int edge = newEdge(); + + splice(edge, getEdge(edgeA, NEXT_AROUND_LEFT)); + splice(symEdge(edge), edgeB); + + setEdgePoints(edge, edgeDst(edgeA), edgeOrg(edgeB)); + return edge; +} + +void Subdiv2D::swapEdges( int edge ) +{ + int sedge = symEdge(edge); + int a = getEdge(edge, PREV_AROUND_ORG); + int b = getEdge(sedge, PREV_AROUND_ORG); + + splice(edge, a); + splice(sedge, b); + + setEdgePoints(edge, edgeDst(a), edgeDst(b)); + + splice(edge, getEdge(a, NEXT_AROUND_LEFT)); + splice(sedge, getEdge(b, NEXT_AROUND_LEFT)); +} + +static double triangleArea( Point2f a, Point2f b, Point2f c ) +{ + return ((double)b.x - a.x) * ((double)c.y - a.y) - ((double)b.y - a.y) * ((double)c.x - a.x); +} + +int Subdiv2D::isRightOf(Point2f pt, int edge) const +{ + Point2f org, dst; + edgeOrg(edge, &org); + edgeDst(edge, &dst); + double cw_area = triangleArea( pt, dst, org ); + + return (cw_area > 0) - (cw_area < 0); +} + +int Subdiv2D::newEdge() +{ + if( freeQEdge <= 0 ) + { + qedges.push_back(QuadEdge()); + freeQEdge = (int)(qedges.size()-1); + } + int edge = freeQEdge*4; + freeQEdge = qedges[edge >> 2].next[1]; + qedges[edge >> 2] = QuadEdge(edge); + return edge; +} + +void Subdiv2D::deleteEdge(int edge) +{ + CV_DbgAssert((size_t)(edge >> 2) < (size_t)qedges.size()); + splice( edge, getEdge(edge, PREV_AROUND_ORG) ); + int sedge = symEdge(edge); + splice(sedge, getEdge(sedge, PREV_AROUND_ORG) ); + + edge >>= 2; + qedges[edge].next[0] = 0; + qedges[edge].next[1] = freeQEdge; + freeQEdge = edge; +} + +int Subdiv2D::newPoint(Point2f pt, bool isvirtual, int firstEdge) +{ + if( freePoint == 0 ) + { + vtx.push_back(Vertex()); + freePoint = (int)(vtx.size()-1); + } + int vidx = freePoint; + freePoint = vtx[vidx].firstEdge; + vtx[vidx] = Vertex(pt, isvirtual, firstEdge); + + return vidx; +} + +void Subdiv2D::deletePoint(int vidx) +{ + CV_DbgAssert( (size_t)vidx < vtx.size() ); + vtx[vidx].firstEdge = freePoint; + vtx[vidx].type = -1; + freePoint = vidx; +} + +int Subdiv2D::locate(Point2f pt, int& _edge, int& _vertex) +{ + int vertex = 0; + + int i, maxEdges = (int)(qedges.size() * 4); + + if( qedges.size() < (size_t)4 ) + CV_Error( CV_StsError, "Subdivision is empty" ); + + if( pt.x < topLeft.x || pt.y < topLeft.y || pt.x >= bottomRight.x || pt.y >= bottomRight.y ) + CV_Error( CV_StsOutOfRange, "" ); + + int edge = recentEdge; + CV_Assert(edge > 0); + + int location = PTLOC_ERROR; + + int right_of_curr = isRightOf(pt, edge); + if( right_of_curr > 0 ) + { + edge = symEdge(edge); + right_of_curr = -right_of_curr; + } + + for( i = 0; i < maxEdges; i++ ) + { + int onext_edge = nextEdge( edge ); + int dprev_edge = getEdge( edge, PREV_AROUND_DST ); + + int right_of_onext = isRightOf( pt, onext_edge ); + int right_of_dprev = isRightOf( pt, dprev_edge ); + + if( right_of_dprev > 0 ) + { + if( right_of_onext > 0 || (right_of_onext == 0 && right_of_curr == 0) ) + { + location = PTLOC_INSIDE; + break; + } + else + { + right_of_curr = right_of_onext; + edge = onext_edge; + } + } + else + { + if( right_of_onext > 0 ) + { + if( right_of_dprev == 0 && right_of_curr == 0 ) + { + location = PTLOC_INSIDE; + break; + } + else + { + right_of_curr = right_of_dprev; + edge = dprev_edge; + } + } + else if( right_of_curr == 0 && + isRightOf( vtx[edgeDst(onext_edge)].pt, edge ) >= 0 ) + { + edge = symEdge( edge ); + } + else + { + right_of_curr = right_of_onext; + edge = onext_edge; + } + } + } + + recentEdge = edge; + + if( location == PTLOC_INSIDE ) + { + Point2f org_pt, dst_pt; + edgeOrg(edge, &org_pt); + edgeDst(edge, &dst_pt); + + double t1 = fabs( pt.x - org_pt.x ); + t1 += fabs( pt.y - org_pt.y ); + double t2 = fabs( pt.x - dst_pt.x ); + t2 += fabs( pt.y - dst_pt.y ); + double t3 = fabs( org_pt.x - dst_pt.x ); + t3 += fabs( org_pt.y - dst_pt.y ); + + if( t1 < FLT_EPSILON ) + { + location = PTLOC_VERTEX; + vertex = edgeOrg( edge ); + edge = 0; + } + else if( t2 < FLT_EPSILON ) + { + location = PTLOC_VERTEX; + vertex = edgeDst( edge ); + edge = 0; + } + else if( (t1 < t3 || t2 < t3) && + fabs( triangleArea( pt, org_pt, dst_pt )) < FLT_EPSILON ) + { + location = PTLOC_ON_EDGE; + vertex = 0; + } + } + + if( location == PTLOC_ERROR ) + { + edge = 0; + vertex = 0; + } + + _edge = edge; + _vertex = vertex; + + return location; +} + + +inline int +isPtInCircle3( Point2f pt, Point2f a, Point2f b, Point2f c) +{ + const double eps = FLT_EPSILON*0.125; + double val = ((double)a.x * a.x + (double)a.y * a.y) * triangleArea( b, c, pt ); + val -= ((double)b.x * b.x + (double)b.y * b.y) * triangleArea( a, c, pt ); + val += ((double)c.x * c.x + (double)c.y * c.y) * triangleArea( a, b, pt ); + val -= ((double)pt.x * pt.x + (double)pt.y * pt.y) * triangleArea( a, b, c ); + + return val > eps ? 1 : val < -eps ? -1 : 0; +} + + +int Subdiv2D::insert(Point2f pt) +{ + int curr_point = 0, curr_edge = 0, deleted_edge = 0; + int location = locate( pt, curr_edge, curr_point ); + + if( location == PTLOC_ERROR ) + CV_Error( CV_StsBadSize, "" ); + + if( location == PTLOC_OUTSIDE_RECT ) + CV_Error( CV_StsOutOfRange, "" ); + + if( location == PTLOC_VERTEX ) + return curr_point; + + if( location == PTLOC_ON_EDGE ) + { + deleted_edge = curr_edge; + recentEdge = curr_edge = getEdge( curr_edge, PREV_AROUND_ORG ); + deleteEdge(deleted_edge); + } + else if( location == PTLOC_INSIDE ) + ; + else + CV_Error_(CV_StsError, ("Subdiv2D::locate returned invalid location = %d", location) ); + + assert( curr_edge != 0 ); + validGeometry = false; + + curr_point = newPoint(pt, false); + int base_edge = newEdge(); + int first_point = edgeOrg(curr_edge); + setEdgePoints(base_edge, first_point, curr_point); + splice(base_edge, curr_edge); + + do + { + base_edge = connectEdges( curr_edge, symEdge(base_edge) ); + curr_edge = getEdge(base_edge, PREV_AROUND_ORG); + } + while( edgeDst(curr_edge) != first_point ); + + curr_edge = getEdge( base_edge, PREV_AROUND_ORG ); + + int i, max_edges = (int)(qedges.size()*4); + + for( i = 0; i < max_edges; i++ ) + { + int temp_dst = 0, curr_org = 0, curr_dst = 0; + int temp_edge = getEdge( curr_edge, PREV_AROUND_ORG ); + + temp_dst = edgeDst( temp_edge ); + curr_org = edgeOrg( curr_edge ); + curr_dst = edgeDst( curr_edge ); + + if( isRightOf( vtx[temp_dst].pt, curr_edge ) > 0 && + isPtInCircle3( vtx[curr_org].pt, vtx[temp_dst].pt, + vtx[curr_dst].pt, vtx[curr_point].pt ) < 0 ) + { + swapEdges( curr_edge ); + curr_edge = getEdge( curr_edge, PREV_AROUND_ORG ); + } + else if( curr_org == first_point ) + break; + else + curr_edge = getEdge( nextEdge( curr_edge ), PREV_AROUND_LEFT ); + } + + return curr_point; +} + +void Subdiv2D::insert(const vector& ptvec) +{ + for( size_t i = 0; i < ptvec.size(); i++ ) + insert(ptvec[i]); +} + +void Subdiv2D::initDelaunay( Rect rect ) +{ + float big_coord = 3.f * MAX( rect.width, rect.height ); + float rx = (float)rect.x; + float ry = (float)rect.y; + + vtx.clear(); + qedges.clear(); + + recentEdge = 0; + validGeometry = false; + + topLeft = Point2f( rx, ry ); + bottomRight = Point2f( rx + rect.width, ry + rect.height ); + + Point2f ppA( rx + big_coord, ry ); + Point2f ppB( rx, ry + big_coord ); + Point2f ppC( rx - big_coord, ry - big_coord ); + + vtx.push_back(Vertex()); + qedges.push_back(QuadEdge()); + + freeQEdge = 0; + freePoint = 0; + + int pA = newPoint(ppA, false); + int pB = newPoint(ppB, false); + int pC = newPoint(ppC, false); + + int edge_AB = newEdge(); + int edge_BC = newEdge(); + int edge_CA = newEdge(); + + setEdgePoints( edge_AB, pA, pB ); + setEdgePoints( edge_BC, pB, pC ); + setEdgePoints( edge_CA, pC, pA ); + + splice( edge_AB, symEdge( edge_CA )); + splice( edge_BC, symEdge( edge_AB )); + splice( edge_CA, symEdge( edge_BC )); + + recentEdge = edge_AB; +} + + +void Subdiv2D::clearVoronoi() +{ + size_t i, total = qedges.size(); + + for( i = 0; i < total; i++ ) + qedges[i].pt[1] = qedges[i].pt[3] = 0; + + total = vtx.size(); + for( i = 0; i < total; i++ ) + { + if( vtx[i].isvirtual() ) + deletePoint((int)i); + } + + validGeometry = false; +} + + +static Point2f computeVoronoiPoint(Point2f org0, Point2f dst0, Point2f org1, Point2f dst1) +{ + double a0 = dst0.x - org0.x; + double b0 = dst0.y - org0.y; + double c0 = -0.5*(a0 * (dst0.x + org0.x) + b0 * (dst0.y + org0.y)); + + double a1 = dst1.x - org1.x; + double b1 = dst1.y - org1.y; + double c1 = -0.5*(a1 * (dst1.x + org1.x) + b1 * (dst1.y + org1.y)); + + double det = a0 * b1 - a1 * b0; + + if( det != 0 ) + { + det = 1. / det; + return Point2f((float) ((b0 * c1 - b1 * c0) * det), + (float) ((a1 * c0 - a0 * c1) * det)); + } + + return Point2f(FLT_MAX, FLT_MAX); +} + + +void Subdiv2D::calcVoronoi() +{ + // check if it is already calculated + if( validGeometry ) + return; + + clearVoronoi(); + int i, total = (int)qedges.size(); + + // loop through all quad-edges, except for the first 3 (#1, #2, #3 - 0 is reserved for "NULL" pointer) + for( i = 4; i < total; i++ ) + { + QuadEdge& quadedge = qedges[i]; + + if( quadedge.isfree() ) + continue; + + int edge0 = (int)(i*4); + Point2f org0, dst0, org1, dst1; + + if( !quadedge.pt[3] ) + { + int edge1 = getEdge( edge0, NEXT_AROUND_LEFT ); + int edge2 = getEdge( edge1, NEXT_AROUND_LEFT ); + + edgeOrg(edge0, &org0); + edgeDst(edge0, &dst0); + edgeOrg(edge1, &org1); + edgeDst(edge1, &dst1); + + Point2f virt_point = computeVoronoiPoint(org0, dst0, org1, dst1); + + if( fabs( virt_point.x ) < FLT_MAX * 0.5 && + fabs( virt_point.y ) < FLT_MAX * 0.5 ) + { + quadedge.pt[3] = qedges[edge1 >> 2].pt[3 - (edge1 & 2)] = + qedges[edge2 >> 2].pt[3 - (edge2 & 2)] = newPoint(virt_point, true); + } + } + + if( !quadedge.pt[1] ) + { + int edge1 = getEdge( edge0, NEXT_AROUND_RIGHT ); + int edge2 = getEdge( edge1, NEXT_AROUND_RIGHT ); + + edgeOrg(edge0, &org0); + edgeDst(edge0, &dst0); + edgeOrg(edge1, &org1); + edgeDst(edge1, &dst1); + + Point2f virt_point = computeVoronoiPoint(org0, dst0, org1, dst1); + + if( fabs( virt_point.x ) < FLT_MAX * 0.5 && + fabs( virt_point.y ) < FLT_MAX * 0.5 ) + { + quadedge.pt[1] = qedges[edge1 >> 2].pt[1 + (edge1 & 2)] = + qedges[edge2 >> 2].pt[1 + (edge2 & 2)] = newPoint(virt_point, true); + } + } + } + + validGeometry = true; +} + + +static int +isRightOf2( const Point2f& pt, const Point2f& org, const Point2f& diff ) +{ + double cw_area = ((double)org.x - pt.x)*diff.y - ((double)org.y - pt.y)*diff.x; + return (cw_area > 0) - (cw_area < 0); +} + + +int Subdiv2D::findNearest(Point2f pt, Point2f* nearestPt) +{ + if( !validGeometry ) + calcVoronoi(); + + int vertex = 0, edge = 0; + int loc = locate( pt, edge, vertex ); + + if( loc != PTLOC_ON_EDGE && loc != PTLOC_INSIDE ) + return vertex; + + vertex = 0; + + Point2f start; + edgeOrg(edge, &start); + Point2f diff = pt - start; + + edge = rotateEdge(edge, 1); + + int i, total = (int)vtx.size(); + + for( i = 0; i < total; i++ ) + { + Point2f t; + + for(;;) + { + CV_Assert( edgeDst(edge, &t) > 0 ); + if( isRightOf2( t, start, diff ) >= 0 ) + break; + + edge = getEdge( edge, NEXT_AROUND_LEFT ); + } + + for(;;) + { + CV_Assert( edgeOrg( edge, &t ) > 0 ); + + if( isRightOf2( t, start, diff ) < 0 ) + break; + + edge = getEdge( edge, PREV_AROUND_LEFT ); + } + + Point2f tempDiff; + edgeDst(edge, &tempDiff); + edgeOrg(edge, &t); + tempDiff -= t; + + if( isRightOf2( pt, t, tempDiff ) >= 0 ) + { + vertex = edgeOrg(rotateEdge( edge, 3 )); + break; + } + + edge = symEdge( edge ); + } + + if( nearestPt && vertex > 0 ) + *nearestPt = vtx[vertex].pt; + + return vertex; +} + +void Subdiv2D::getEdgeList(vector& edgeList) const +{ + edgeList.clear(); + + for( size_t i = 4; i < qedges.size(); i++ ) + { + if( qedges[i].isfree() ) + continue; + if( qedges[i].pt[0] > 0 && qedges[i].pt[2] > 0 ) + { + Point2f org = vtx[qedges[i].pt[0]].pt; + Point2f dst = vtx[qedges[i].pt[2]].pt; + edgeList.push_back(Vec4f(org.x, org.y, dst.x, dst.y)); + } + } +} + +void Subdiv2D::getTriangleList(vector& triangleList) const +{ + triangleList.clear(); + int i, total = (int)(qedges.size()*4); + vector edgemask(total, false); + + for( i = 4; i < total; i += 2 ) + { + if( edgemask[i] ) + continue; + Point2f a, b, c; + int edge = i; + edgeOrg(edge, &a); + edgemask[edge] = true; + edge = getEdge(edge, NEXT_AROUND_LEFT); + edgeOrg(edge, &b); + edgemask[edge] = true; + edge = getEdge(edge, NEXT_AROUND_LEFT); + edgeOrg(edge, &c); + edgemask[edge] = true; + triangleList.push_back(Vec6f(a.x, a.y, b.x, b.y, c.x, c.y)); + } +} + +void Subdiv2D::getVoronoiFacetList(const vector& idx, + CV_OUT vector >& facetList, + CV_OUT vector& facetCenters) +{ + calcVoronoi(); + facetList.clear(); + facetCenters.clear(); + + vector buf; + + size_t i, total; + if( idx.empty() ) + i = 4, total = vtx.size(); + else + i = 0, total = idx.size(); + + for( ; i < total; i++ ) + { + int k = idx.empty() ? (int)i : idx[i]; + + if( vtx[k].isfree() || vtx[k].isvirtual() ) + continue; + int edge = rotateEdge(vtx[k].firstEdge, 1), t = edge; + + // gather points + buf.clear(); + do + { + buf.push_back(vtx[edgeOrg(t)].pt); + t = getEdge( t, NEXT_AROUND_LEFT ); + } + while( t != edge ); + + facetList.push_back(buf); + facetCenters.push_back(vtx[k].pt); + } +} + + +void Subdiv2D::checkSubdiv() const +{ + int i, j, total = (int)qedges.size(); + + for( i = 0; i < total; i++ ) + { + const QuadEdge& qe = qedges[i]; + + if( qe.isfree() ) + continue; + + for( j = 0; j < 4; j++ ) + { + int e = (int)(i*4 + j); + int o_next = nextEdge(e); + int o_prev = getEdge(e, PREV_AROUND_ORG ); + int d_prev = getEdge(e, PREV_AROUND_DST ); + int d_next = getEdge(e, NEXT_AROUND_DST ); + + // check points + CV_Assert( edgeOrg(e) == edgeOrg(o_next)); + CV_Assert( edgeOrg(e) == edgeOrg(o_prev)); + CV_Assert( edgeDst(e) == edgeDst(d_next)); + CV_Assert( edgeDst(e) == edgeDst(d_prev)); + + if( j % 2 == 0 ) + { + CV_Assert( edgeDst(o_next) == edgeOrg(d_prev)); + CV_Assert( edgeDst(o_prev) == edgeOrg(d_next)); + CV_Assert( getEdge(getEdge(getEdge(e,NEXT_AROUND_LEFT),NEXT_AROUND_LEFT),NEXT_AROUND_LEFT) == e ); + CV_Assert( getEdge(getEdge(getEdge(e,NEXT_AROUND_RIGHT),NEXT_AROUND_RIGHT),NEXT_AROUND_RIGHT) == e); + } + } + } +} + +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/sumpixels.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/sumpixels.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/sumpixels.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/sumpixels.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,309 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +template +void integral_( const T* src, size_t _srcstep, ST* sum, size_t _sumstep, + QT* sqsum, size_t _sqsumstep, ST* tilted, size_t _tiltedstep, + Size size, int cn ) +{ + int x, y, k; + + int srcstep = (int)(_srcstep/sizeof(T)); + int sumstep = (int)(_sumstep/sizeof(ST)); + int tiltedstep = (int)(_tiltedstep/sizeof(ST)); + int sqsumstep = (int)(_sqsumstep/sizeof(QT)); + + size.width *= cn; + + memset( sum, 0, (size.width+cn)*sizeof(sum[0])); + sum += sumstep + cn; + + if( sqsum ) + { + memset( sqsum, 0, (size.width+cn)*sizeof(sqsum[0])); + sqsum += sqsumstep + cn; + } + + if( tilted ) + { + memset( tilted, 0, (size.width+cn)*sizeof(tilted[0])); + tilted += tiltedstep + cn; + } + + if( sqsum == 0 && tilted == 0 ) + { + for( y = 0; y < size.height; y++, src += srcstep - cn, sum += sumstep - cn ) + { + for( k = 0; k < cn; k++, src++, sum++ ) + { + ST s = sum[-cn] = 0; + for( x = 0; x < size.width; x += cn ) + { + s += src[x]; + sum[x] = sum[x - sumstep] + s; + } + } + } + } + else if( tilted == 0 ) + { + for( y = 0; y < size.height; y++, src += srcstep - cn, + sum += sumstep - cn, sqsum += sqsumstep - cn ) + { + for( k = 0; k < cn; k++, src++, sum++, sqsum++ ) + { + ST s = sum[-cn] = 0; + QT sq = sqsum[-cn] = 0; + for( x = 0; x < size.width; x += cn ) + { + T it = src[x]; + s += it; + sq += (QT)it*it; + ST t = sum[x - sumstep] + s; + QT tq = sqsum[x - sqsumstep] + sq; + sum[x] = t; + sqsum[x] = tq; + } + } + } + } + else + { + AutoBuffer _buf(size.width+cn); + ST* buf = _buf; + ST s; + QT sq; + for( k = 0; k < cn; k++, src++, sum++, tilted++, buf++ ) + { + sum[-cn] = tilted[-cn] = 0; + + for( x = 0, s = 0, sq = 0; x < size.width; x += cn ) + { + T it = src[x]; + buf[x] = tilted[x] = it; + s += it; + sq += (QT)it*it; + sum[x] = s; + if( sqsum ) + sqsum[x] = sq; + } + + if( size.width == cn ) + buf[cn] = 0; + + if( sqsum ) + { + sqsum[-cn] = 0; + sqsum++; + } + } + + for( y = 1; y < size.height; y++ ) + { + src += srcstep - cn; + sum += sumstep - cn; + tilted += tiltedstep - cn; + buf += -cn; + + if( sqsum ) + sqsum += sqsumstep - cn; + + for( k = 0; k < cn; k++, src++, sum++, tilted++, buf++ ) + { + T it = src[0]; + ST t0 = s = it; + QT tq0 = sq = (QT)it*it; + + sum[-cn] = 0; + if( sqsum ) + sqsum[-cn] = 0; + tilted[-cn] = tilted[-tiltedstep]; + + sum[0] = sum[-sumstep] + t0; + if( sqsum ) + sqsum[0] = sqsum[-sqsumstep] + tq0; + tilted[0] = tilted[-tiltedstep] + t0 + buf[cn]; + + for( x = cn; x < size.width - cn; x += cn ) + { + ST t1 = buf[x]; + buf[x - cn] = t1 + t0; + t0 = it = src[x]; + tq0 = (QT)it*it; + s += t0; + sq += tq0; + sum[x] = sum[x - sumstep] + s; + if( sqsum ) + sqsum[x] = sqsum[x - sqsumstep] + sq; + t1 += buf[x + cn] + t0 + tilted[x - tiltedstep - cn]; + tilted[x] = t1; + } + + if( size.width > cn ) + { + ST t1 = buf[x]; + buf[x - cn] = t1 + t0; + t0 = it = src[x]; + tq0 = (QT)it*it; + s += t0; + sq += tq0; + sum[x] = sum[x - sumstep] + s; + if( sqsum ) + sqsum[x] = sqsum[x - sqsumstep] + sq; + tilted[x] = t0 + t1 + tilted[x - tiltedstep - cn]; + buf[x] = t0; + } + + if( sqsum ) + sqsum++; + } + } + } +} + + +#define DEF_INTEGRAL_FUNC(suffix, T, ST, QT) \ +static void integral_##suffix( T* src, size_t srcstep, ST* sum, size_t sumstep, QT* sqsum, size_t sqsumstep, \ + ST* tilted, size_t tiltedstep, Size size, int cn ) \ +{ integral_(src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tiltedstep, size, cn); } + +DEF_INTEGRAL_FUNC(8u32s, uchar, int, double) +DEF_INTEGRAL_FUNC(8u32f, uchar, float, double) +DEF_INTEGRAL_FUNC(8u64f, uchar, double, double) +DEF_INTEGRAL_FUNC(32f, float, float, double) +DEF_INTEGRAL_FUNC(32f64f, float, double, double) +DEF_INTEGRAL_FUNC(64f, double, double, double) + +typedef void (*IntegralFunc)(const uchar* src, size_t srcstep, uchar* sum, size_t sumstep, + uchar* sqsum, size_t sqsumstep, uchar* tilted, size_t tstep, + Size size, int cn ); + +} + + +void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, OutputArray _tilted, int sdepth ) +{ + Mat src = _src.getMat(), sum, sqsum, tilted; + int depth = src.depth(), cn = src.channels(); + Size isize(src.cols + 1, src.rows+1); + + if( sdepth <= 0 ) + sdepth = depth == CV_8U ? CV_32S : CV_64F; + sdepth = CV_MAT_DEPTH(sdepth); + _sum.create( isize, CV_MAKETYPE(sdepth, cn) ); + sum = _sum.getMat(); + + if( _tilted.needed() ) + { + _tilted.create( isize, CV_MAKETYPE(sdepth, cn) ); + tilted = _tilted.getMat(); + } + + if( _sqsum.needed() ) + { + _sqsum.create( isize, CV_MAKETYPE(CV_64F, cn) ); + sqsum = _sqsum.getMat(); + } + + IntegralFunc func = 0; + + if( depth == CV_8U && sdepth == CV_32S ) + func = (IntegralFunc)GET_OPTIMIZED(integral_8u32s); + else if( depth == CV_8U && sdepth == CV_32F ) + func = (IntegralFunc)integral_8u32f; + else if( depth == CV_8U && sdepth == CV_64F ) + func = (IntegralFunc)integral_8u64f; + else if( depth == CV_32F && sdepth == CV_32F ) + func = (IntegralFunc)integral_32f; + else if( depth == CV_32F && sdepth == CV_64F ) + func = (IntegralFunc)integral_32f64f; + else if( depth == CV_64F && sdepth == CV_64F ) + func = (IntegralFunc)integral_64f; + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + func( src.data, src.step, sum.data, sum.step, sqsum.data, sqsum.step, + tilted.data, tilted.step, src.size(), cn ); +} + +void cv::integral( InputArray src, OutputArray sum, int sdepth ) +{ + integral( src, sum, noArray(), noArray(), sdepth ); +} + +void cv::integral( InputArray src, OutputArray sum, OutputArray sqsum, int sdepth ) +{ + integral( src, sum, sqsum, noArray(), sdepth ); +} + + +CV_IMPL void +cvIntegral( const CvArr* image, CvArr* sumImage, + CvArr* sumSqImage, CvArr* tiltedSumImage ) +{ + cv::Mat src = cv::cvarrToMat(image), sum = cv::cvarrToMat(sumImage), sum0 = sum; + cv::Mat sqsum0, sqsum, tilted0, tilted; + cv::Mat *psqsum = 0, *ptilted = 0; + + if( sumSqImage ) + { + sqsum0 = sqsum = cv::cvarrToMat(sumSqImage); + psqsum = &sqsum; + } + + if( tiltedSumImage ) + { + tilted0 = tilted = cv::cvarrToMat(tiltedSumImage); + ptilted = &tilted; + } + cv::integral( src, sum, psqsum ? cv::_OutputArray(*psqsum) : cv::_OutputArray(), + ptilted ? cv::_OutputArray(*ptilted) : cv::_OutputArray(), sum.depth() ); + + CV_Assert( sum.data == sum0.data && sqsum.data == sqsum0.data && tilted.data == tilted0.data ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/tables.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/tables.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/tables.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/tables.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,214 @@ +/* //////////////////////////////////////////////////////////////////// +// +// CvMat helper tables +// +// */ + +#include "precomp.hpp" + +const float icv8x32fTab_cv[] = +{ + -256.f, -255.f, -254.f, -253.f, -252.f, -251.f, -250.f, -249.f, + -248.f, -247.f, -246.f, -245.f, -244.f, -243.f, -242.f, -241.f, + -240.f, -239.f, -238.f, -237.f, -236.f, -235.f, -234.f, -233.f, + -232.f, -231.f, -230.f, -229.f, -228.f, -227.f, -226.f, -225.f, + -224.f, -223.f, -222.f, -221.f, -220.f, -219.f, -218.f, -217.f, + -216.f, -215.f, -214.f, -213.f, -212.f, -211.f, -210.f, -209.f, + -208.f, -207.f, -206.f, -205.f, -204.f, -203.f, -202.f, -201.f, + -200.f, -199.f, -198.f, -197.f, -196.f, -195.f, -194.f, -193.f, + -192.f, -191.f, -190.f, -189.f, -188.f, -187.f, -186.f, -185.f, + -184.f, -183.f, -182.f, -181.f, -180.f, -179.f, -178.f, -177.f, + -176.f, -175.f, -174.f, -173.f, -172.f, -171.f, -170.f, -169.f, + -168.f, -167.f, -166.f, -165.f, -164.f, -163.f, -162.f, -161.f, + -160.f, -159.f, -158.f, -157.f, -156.f, -155.f, -154.f, -153.f, + -152.f, -151.f, -150.f, -149.f, -148.f, -147.f, -146.f, -145.f, + -144.f, -143.f, -142.f, -141.f, -140.f, -139.f, -138.f, -137.f, + -136.f, -135.f, -134.f, -133.f, -132.f, -131.f, -130.f, -129.f, + -128.f, -127.f, -126.f, -125.f, -124.f, -123.f, -122.f, -121.f, + -120.f, -119.f, -118.f, -117.f, -116.f, -115.f, -114.f, -113.f, + -112.f, -111.f, -110.f, -109.f, -108.f, -107.f, -106.f, -105.f, + -104.f, -103.f, -102.f, -101.f, -100.f, -99.f, -98.f, -97.f, + -96.f, -95.f, -94.f, -93.f, -92.f, -91.f, -90.f, -89.f, + -88.f, -87.f, -86.f, -85.f, -84.f, -83.f, -82.f, -81.f, + -80.f, -79.f, -78.f, -77.f, -76.f, -75.f, -74.f, -73.f, + -72.f, -71.f, -70.f, -69.f, -68.f, -67.f, -66.f, -65.f, + -64.f, -63.f, -62.f, -61.f, -60.f, -59.f, -58.f, -57.f, + -56.f, -55.f, -54.f, -53.f, -52.f, -51.f, -50.f, -49.f, + -48.f, -47.f, -46.f, -45.f, -44.f, -43.f, -42.f, -41.f, + -40.f, -39.f, -38.f, -37.f, -36.f, -35.f, -34.f, -33.f, + -32.f, -31.f, -30.f, -29.f, -28.f, -27.f, -26.f, -25.f, + -24.f, -23.f, -22.f, -21.f, -20.f, -19.f, -18.f, -17.f, + -16.f, -15.f, -14.f, -13.f, -12.f, -11.f, -10.f, -9.f, + -8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, + 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, + 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f, + 16.f, 17.f, 18.f, 19.f, 20.f, 21.f, 22.f, 23.f, + 24.f, 25.f, 26.f, 27.f, 28.f, 29.f, 30.f, 31.f, + 32.f, 33.f, 34.f, 35.f, 36.f, 37.f, 38.f, 39.f, + 40.f, 41.f, 42.f, 43.f, 44.f, 45.f, 46.f, 47.f, + 48.f, 49.f, 50.f, 51.f, 52.f, 53.f, 54.f, 55.f, + 56.f, 57.f, 58.f, 59.f, 60.f, 61.f, 62.f, 63.f, + 64.f, 65.f, 66.f, 67.f, 68.f, 69.f, 70.f, 71.f, + 72.f, 73.f, 74.f, 75.f, 76.f, 77.f, 78.f, 79.f, + 80.f, 81.f, 82.f, 83.f, 84.f, 85.f, 86.f, 87.f, + 88.f, 89.f, 90.f, 91.f, 92.f, 93.f, 94.f, 95.f, + 96.f, 97.f, 98.f, 99.f, 100.f, 101.f, 102.f, 103.f, + 104.f, 105.f, 106.f, 107.f, 108.f, 109.f, 110.f, 111.f, + 112.f, 113.f, 114.f, 115.f, 116.f, 117.f, 118.f, 119.f, + 120.f, 121.f, 122.f, 123.f, 124.f, 125.f, 126.f, 127.f, + 128.f, 129.f, 130.f, 131.f, 132.f, 133.f, 134.f, 135.f, + 136.f, 137.f, 138.f, 139.f, 140.f, 141.f, 142.f, 143.f, + 144.f, 145.f, 146.f, 147.f, 148.f, 149.f, 150.f, 151.f, + 152.f, 153.f, 154.f, 155.f, 156.f, 157.f, 158.f, 159.f, + 160.f, 161.f, 162.f, 163.f, 164.f, 165.f, 166.f, 167.f, + 168.f, 169.f, 170.f, 171.f, 172.f, 173.f, 174.f, 175.f, + 176.f, 177.f, 178.f, 179.f, 180.f, 181.f, 182.f, 183.f, + 184.f, 185.f, 186.f, 187.f, 188.f, 189.f, 190.f, 191.f, + 192.f, 193.f, 194.f, 195.f, 196.f, 197.f, 198.f, 199.f, + 200.f, 201.f, 202.f, 203.f, 204.f, 205.f, 206.f, 207.f, + 208.f, 209.f, 210.f, 211.f, 212.f, 213.f, 214.f, 215.f, + 216.f, 217.f, 218.f, 219.f, 220.f, 221.f, 222.f, 223.f, + 224.f, 225.f, 226.f, 227.f, 228.f, 229.f, 230.f, 231.f, + 232.f, 233.f, 234.f, 235.f, 236.f, 237.f, 238.f, 239.f, + 240.f, 241.f, 242.f, 243.f, 244.f, 245.f, 246.f, 247.f, + 248.f, 249.f, 250.f, 251.f, 252.f, 253.f, 254.f, 255.f, + 256.f, 257.f, 258.f, 259.f, 260.f, 261.f, 262.f, 263.f, + 264.f, 265.f, 266.f, 267.f, 268.f, 269.f, 270.f, 271.f, + 272.f, 273.f, 274.f, 275.f, 276.f, 277.f, 278.f, 279.f, + 280.f, 281.f, 282.f, 283.f, 284.f, 285.f, 286.f, 287.f, + 288.f, 289.f, 290.f, 291.f, 292.f, 293.f, 294.f, 295.f, + 296.f, 297.f, 298.f, 299.f, 300.f, 301.f, 302.f, 303.f, + 304.f, 305.f, 306.f, 307.f, 308.f, 309.f, 310.f, 311.f, + 312.f, 313.f, 314.f, 315.f, 316.f, 317.f, 318.f, 319.f, + 320.f, 321.f, 322.f, 323.f, 324.f, 325.f, 326.f, 327.f, + 328.f, 329.f, 330.f, 331.f, 332.f, 333.f, 334.f, 335.f, + 336.f, 337.f, 338.f, 339.f, 340.f, 341.f, 342.f, 343.f, + 344.f, 345.f, 346.f, 347.f, 348.f, 349.f, 350.f, 351.f, + 352.f, 353.f, 354.f, 355.f, 356.f, 357.f, 358.f, 359.f, + 360.f, 361.f, 362.f, 363.f, 364.f, 365.f, 366.f, 367.f, + 368.f, 369.f, 370.f, 371.f, 372.f, 373.f, 374.f, 375.f, + 376.f, 377.f, 378.f, 379.f, 380.f, 381.f, 382.f, 383.f, + 384.f, 385.f, 386.f, 387.f, 388.f, 389.f, 390.f, 391.f, + 392.f, 393.f, 394.f, 395.f, 396.f, 397.f, 398.f, 399.f, + 400.f, 401.f, 402.f, 403.f, 404.f, 405.f, 406.f, 407.f, + 408.f, 409.f, 410.f, 411.f, 412.f, 413.f, 414.f, 415.f, + 416.f, 417.f, 418.f, 419.f, 420.f, 421.f, 422.f, 423.f, + 424.f, 425.f, 426.f, 427.f, 428.f, 429.f, 430.f, 431.f, + 432.f, 433.f, 434.f, 435.f, 436.f, 437.f, 438.f, 439.f, + 440.f, 441.f, 442.f, 443.f, 444.f, 445.f, 446.f, 447.f, + 448.f, 449.f, 450.f, 451.f, 452.f, 453.f, 454.f, 455.f, + 456.f, 457.f, 458.f, 459.f, 460.f, 461.f, 462.f, 463.f, + 464.f, 465.f, 466.f, 467.f, 468.f, 469.f, 470.f, 471.f, + 472.f, 473.f, 474.f, 475.f, 476.f, 477.f, 478.f, 479.f, + 480.f, 481.f, 482.f, 483.f, 484.f, 485.f, 486.f, 487.f, + 488.f, 489.f, 490.f, 491.f, 492.f, 493.f, 494.f, 495.f, + 496.f, 497.f, 498.f, 499.f, 500.f, 501.f, 502.f, 503.f, + 504.f, 505.f, 506.f, 507.f, 508.f, 509.f, 510.f, 511.f, +}; + +const float icv8x32fSqrTab[] = +{ + 16384.f, 16129.f, 15876.f, 15625.f, 15376.f, 15129.f, 14884.f, 14641.f, + 14400.f, 14161.f, 13924.f, 13689.f, 13456.f, 13225.f, 12996.f, 12769.f, + 12544.f, 12321.f, 12100.f, 11881.f, 11664.f, 11449.f, 11236.f, 11025.f, + 10816.f, 10609.f, 10404.f, 10201.f, 10000.f, 9801.f, 9604.f, 9409.f, + 9216.f, 9025.f, 8836.f, 8649.f, 8464.f, 8281.f, 8100.f, 7921.f, + 7744.f, 7569.f, 7396.f, 7225.f, 7056.f, 6889.f, 6724.f, 6561.f, + 6400.f, 6241.f, 6084.f, 5929.f, 5776.f, 5625.f, 5476.f, 5329.f, + 5184.f, 5041.f, 4900.f, 4761.f, 4624.f, 4489.f, 4356.f, 4225.f, + 4096.f, 3969.f, 3844.f, 3721.f, 3600.f, 3481.f, 3364.f, 3249.f, + 3136.f, 3025.f, 2916.f, 2809.f, 2704.f, 2601.f, 2500.f, 2401.f, + 2304.f, 2209.f, 2116.f, 2025.f, 1936.f, 1849.f, 1764.f, 1681.f, + 1600.f, 1521.f, 1444.f, 1369.f, 1296.f, 1225.f, 1156.f, 1089.f, + 1024.f, 961.f, 900.f, 841.f, 784.f, 729.f, 676.f, 625.f, + 576.f, 529.f, 484.f, 441.f, 400.f, 361.f, 324.f, 289.f, + 256.f, 225.f, 196.f, 169.f, 144.f, 121.f, 100.f, 81.f, + 64.f, 49.f, 36.f, 25.f, 16.f, 9.f, 4.f, 1.f, + 0.f, 1.f, 4.f, 9.f, 16.f, 25.f, 36.f, 49.f, + 64.f, 81.f, 100.f, 121.f, 144.f, 169.f, 196.f, 225.f, + 256.f, 289.f, 324.f, 361.f, 400.f, 441.f, 484.f, 529.f, + 576.f, 625.f, 676.f, 729.f, 784.f, 841.f, 900.f, 961.f, + 1024.f, 1089.f, 1156.f, 1225.f, 1296.f, 1369.f, 1444.f, 1521.f, + 1600.f, 1681.f, 1764.f, 1849.f, 1936.f, 2025.f, 2116.f, 2209.f, + 2304.f, 2401.f, 2500.f, 2601.f, 2704.f, 2809.f, 2916.f, 3025.f, + 3136.f, 3249.f, 3364.f, 3481.f, 3600.f, 3721.f, 3844.f, 3969.f, + 4096.f, 4225.f, 4356.f, 4489.f, 4624.f, 4761.f, 4900.f, 5041.f, + 5184.f, 5329.f, 5476.f, 5625.f, 5776.f, 5929.f, 6084.f, 6241.f, + 6400.f, 6561.f, 6724.f, 6889.f, 7056.f, 7225.f, 7396.f, 7569.f, + 7744.f, 7921.f, 8100.f, 8281.f, 8464.f, 8649.f, 8836.f, 9025.f, + 9216.f, 9409.f, 9604.f, 9801.f, 10000.f, 10201.f, 10404.f, 10609.f, + 10816.f, 11025.f, 11236.f, 11449.f, 11664.f, 11881.f, 12100.f, 12321.f, + 12544.f, 12769.f, 12996.f, 13225.f, 13456.f, 13689.f, 13924.f, 14161.f, + 14400.f, 14641.f, 14884.f, 15129.f, 15376.f, 15625.f, 15876.f, 16129.f, + 16384.f, 16641.f, 16900.f, 17161.f, 17424.f, 17689.f, 17956.f, 18225.f, + 18496.f, 18769.f, 19044.f, 19321.f, 19600.f, 19881.f, 20164.f, 20449.f, + 20736.f, 21025.f, 21316.f, 21609.f, 21904.f, 22201.f, 22500.f, 22801.f, + 23104.f, 23409.f, 23716.f, 24025.f, 24336.f, 24649.f, 24964.f, 25281.f, + 25600.f, 25921.f, 26244.f, 26569.f, 26896.f, 27225.f, 27556.f, 27889.f, + 28224.f, 28561.f, 28900.f, 29241.f, 29584.f, 29929.f, 30276.f, 30625.f, + 30976.f, 31329.f, 31684.f, 32041.f, 32400.f, 32761.f, 33124.f, 33489.f, + 33856.f, 34225.f, 34596.f, 34969.f, 35344.f, 35721.f, 36100.f, 36481.f, + 36864.f, 37249.f, 37636.f, 38025.f, 38416.f, 38809.f, 39204.f, 39601.f, + 40000.f, 40401.f, 40804.f, 41209.f, 41616.f, 42025.f, 42436.f, 42849.f, + 43264.f, 43681.f, 44100.f, 44521.f, 44944.f, 45369.f, 45796.f, 46225.f, + 46656.f, 47089.f, 47524.f, 47961.f, 48400.f, 48841.f, 49284.f, 49729.f, + 50176.f, 50625.f, 51076.f, 51529.f, 51984.f, 52441.f, 52900.f, 53361.f, + 53824.f, 54289.f, 54756.f, 55225.f, 55696.f, 56169.f, 56644.f, 57121.f, + 57600.f, 58081.f, 58564.f, 59049.f, 59536.f, 60025.f, 60516.f, 61009.f, + 61504.f, 62001.f, 62500.f, 63001.f, 63504.f, 64009.f, 64516.f, 65025.f +}; + +const uchar icvSaturate8u_cv[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255 +}; + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/templmatch.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/templmatch.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/templmatch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/templmatch.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,388 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, + Size corrsize, int ctype, + Point anchor, double delta, int borderType ) +{ + const double blockScale = 4.5; + const int minBlockSize = 256; + std::vector buf; + + Mat templ = _templ; + int depth = img.depth(), cn = img.channels(); + int tdepth = templ.depth(), tcn = templ.channels(); + int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype); + + CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 ); + + if( depth != tdepth && tdepth != std::max(CV_32F, depth) ) + { + _templ.convertTo(templ, std::max(CV_32F, depth)); + tdepth = templ.depth(); + } + + CV_Assert( depth == tdepth || tdepth == CV_32F); + CV_Assert( corrsize.height <= img.rows + templ.rows - 1 && + corrsize.width <= img.cols + templ.cols - 1 ); + + CV_Assert( ccn == 1 || delta == 0 ); + + corr.create(corrsize, ctype); + + int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth); + Size blocksize, dftsize; + + blocksize.width = cvRound(templ.cols*blockScale); + blocksize.width = std::max( blocksize.width, minBlockSize - templ.cols + 1 ); + blocksize.width = std::min( blocksize.width, corr.cols ); + blocksize.height = cvRound(templ.rows*blockScale); + blocksize.height = std::max( blocksize.height, minBlockSize - templ.rows + 1 ); + blocksize.height = std::min( blocksize.height, corr.rows ); + + dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2); + dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1); + if( dftsize.width <= 0 || dftsize.height <= 0 ) + CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); + + // recompute block size + blocksize.width = dftsize.width - templ.cols + 1; + blocksize.width = MIN( blocksize.width, corr.cols ); + blocksize.height = dftsize.height - templ.rows + 1; + blocksize.height = MIN( blocksize.height, corr.rows ); + + Mat dftTempl( dftsize.height*tcn, dftsize.width, maxDepth ); + Mat dftImg( dftsize, maxDepth ); + + int i, k, bufSize = 0; + if( tcn > 1 && tdepth != maxDepth ) + bufSize = templ.cols*templ.rows*CV_ELEM_SIZE(tdepth); + + if( cn > 1 && depth != maxDepth ) + bufSize = std::max( bufSize, (blocksize.width + templ.cols - 1)* + (blocksize.height + templ.rows - 1)*CV_ELEM_SIZE(depth)); + + if( (ccn > 1 || cn > 1) && cdepth != maxDepth ) + bufSize = std::max( bufSize, blocksize.width*blocksize.height*CV_ELEM_SIZE(cdepth)); + + buf.resize(bufSize); + + // compute DFT of each template plane + for( k = 0; k < tcn; k++ ) + { + int yofs = k*dftsize.height; + Mat src = templ; + Mat dst(dftTempl, Rect(0, yofs, dftsize.width, dftsize.height)); + Mat dst1(dftTempl, Rect(0, yofs, templ.cols, templ.rows)); + + if( tcn > 1 ) + { + src = tdepth == maxDepth ? dst1 : Mat(templ.size(), tdepth, &buf[0]); + int pairs[] = {k, 0}; + mixChannels(&templ, 1, &src, 1, pairs, 1); + } + + if( dst1.data != src.data ) + src.convertTo(dst1, dst1.depth()); + + if( dst.cols > templ.cols ) + { + Mat part(dst, Range(0, templ.rows), Range(templ.cols, dst.cols)); + part = Scalar::all(0); + } + dft(dst, dst, 0, templ.rows); + } + + int tileCountX = (corr.cols + blocksize.width - 1)/blocksize.width; + int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height; + int tileCount = tileCountX * tileCountY; + + Size wholeSize = img.size(); + Point roiofs(0,0); + Mat img0 = img; + + if( !(borderType & BORDER_ISOLATED) ) + { + img.locateROI(wholeSize, roiofs); + img0.adjustROI(roiofs.y, wholeSize.height-img.rows-roiofs.y, + roiofs.x, wholeSize.width-img.cols-roiofs.x); + } + borderType |= BORDER_ISOLATED; + + // calculate correlation by blocks + for( i = 0; i < tileCount; i++ ) + { + int x = (i%tileCountX)*blocksize.width; + int y = (i/tileCountX)*blocksize.height; + + Size bsz(std::min(blocksize.width, corr.cols - x), + std::min(blocksize.height, corr.rows - y)); + Size dsz(bsz.width + templ.cols - 1, bsz.height + templ.rows - 1); + int x0 = x - anchor.x + roiofs.x, y0 = y - anchor.y + roiofs.y; + int x1 = std::max(0, x0), y1 = std::max(0, y0); + int x2 = std::min(img0.cols, x0 + dsz.width); + int y2 = std::min(img0.rows, y0 + dsz.height); + Mat src0(img0, Range(y1, y2), Range(x1, x2)); + Mat dst(dftImg, Rect(0, 0, dsz.width, dsz.height)); + Mat dst1(dftImg, Rect(x1-x0, y1-y0, x2-x1, y2-y1)); + Mat cdst(corr, Rect(x, y, bsz.width, bsz.height)); + + for( k = 0; k < cn; k++ ) + { + Mat src = src0; + dftImg = Scalar::all(0); + + if( cn > 1 ) + { + src = depth == maxDepth ? dst1 : Mat(y2-y1, x2-x1, depth, &buf[0]); + int pairs[] = {k, 0}; + mixChannels(&src0, 1, &src, 1, pairs, 1); + } + + if( dst1.data != src.data ) + src.convertTo(dst1, dst1.depth()); + + if( x2 - x1 < dsz.width || y2 - y1 < dsz.height ) + copyMakeBorder(dst1, dst, y1-y0, dst.rows-dst1.rows-(y1-y0), + x1-x0, dst.cols-dst1.cols-(x1-x0), borderType); + + dft( dftImg, dftImg, 0, dsz.height ); + Mat dftTempl1(dftTempl, Rect(0, tcn > 1 ? k*dftsize.height : 0, + dftsize.width, dftsize.height)); + mulSpectrums(dftImg, dftTempl1, dftImg, 0, true); + dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height ); + + src = dftImg(Rect(0, 0, bsz.width, bsz.height)); + + if( ccn > 1 ) + { + if( cdepth != maxDepth ) + { + Mat plane(bsz, cdepth, &buf[0]); + src.convertTo(plane, cdepth, 1, delta); + src = plane; + } + int pairs[] = {0, k}; + mixChannels(&src, 1, &cdst, 1, pairs, 1); + } + else + { + if( k == 0 ) + src.convertTo(cdst, cdepth, 1, delta); + else + { + if( maxDepth != cdepth ) + { + Mat plane(bsz, cdepth, &buf[0]); + src.convertTo(plane, cdepth); + src = plane; + } + add(src, cdst, cdst); + } + } + } + } +} + +} + +/*****************************************************************************************/ + +void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method ) +{ + CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED ); + + int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 : + method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2; + bool isNormed = method == CV_TM_CCORR_NORMED || + method == CV_TM_SQDIFF_NORMED || + method == CV_TM_CCOEFF_NORMED; + + Mat img = _img.getMat(), templ = _templ.getMat(); + if( img.rows < templ.rows || img.cols < templ.cols ) + std::swap(img, templ); + + CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) && + img.type() == templ.type() ); + + Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1); + _result.create(corrSize, CV_32F); + Mat result = _result.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::matchTemplate(img, templ, result, method)) + return; +#endif + + int cn = img.channels(); + crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0); + + if( method == CV_TM_CCORR ) + return; + + double invArea = 1./((double)templ.rows * templ.cols); + + Mat sum, sqsum; + Scalar templMean, templSdv; + double *q0 = 0, *q1 = 0, *q2 = 0, *q3 = 0; + double templNorm = 0, templSum2 = 0; + + if( method == CV_TM_CCOEFF ) + { + integral(img, sum, CV_64F); + templMean = mean(templ); + } + else + { + integral(img, sum, sqsum, CV_64F); + meanStdDev( templ, templMean, templSdv ); + + templNorm = CV_SQR(templSdv[0]) + CV_SQR(templSdv[1]) + + CV_SQR(templSdv[2]) + CV_SQR(templSdv[3]); + + if( templNorm < DBL_EPSILON && method == CV_TM_CCOEFF_NORMED ) + { + result = Scalar::all(1); + return; + } + + templSum2 = templNorm + + CV_SQR(templMean[0]) + CV_SQR(templMean[1]) + + CV_SQR(templMean[2]) + CV_SQR(templMean[3]); + + if( numType != 1 ) + { + templMean = Scalar::all(0); + templNorm = templSum2; + } + + templSum2 /= invArea; + templNorm = sqrt(templNorm); + templNorm /= sqrt(invArea); // care of accuracy here + + q0 = (double*)sqsum.data; + q1 = q0 + templ.cols*cn; + q2 = (double*)(sqsum.data + templ.rows*sqsum.step); + q3 = q2 + templ.cols*cn; + } + + double* p0 = (double*)sum.data; + double* p1 = p0 + templ.cols*cn; + double* p2 = (double*)(sum.data + templ.rows*sum.step); + double* p3 = p2 + templ.cols*cn; + + int sumstep = sum.data ? (int)(sum.step / sizeof(double)) : 0; + int sqstep = sqsum.data ? (int)(sqsum.step / sizeof(double)) : 0; + + int i, j, k; + + for( i = 0; i < result.rows; i++ ) + { + float* rrow = (float*)(result.data + i*result.step); + int idx = i * sumstep; + int idx2 = i * sqstep; + + for( j = 0; j < result.cols; j++, idx += cn, idx2 += cn ) + { + double num = rrow[j], t; + double wndMean2 = 0, wndSum2 = 0; + + if( numType == 1 ) + { + for( k = 0; k < cn; k++ ) + { + t = p0[idx+k] - p1[idx+k] - p2[idx+k] + p3[idx+k]; + wndMean2 += CV_SQR(t); + num -= t*templMean[k]; + } + + wndMean2 *= invArea; + } + + if( isNormed || numType == 2 ) + { + for( k = 0; k < cn; k++ ) + { + t = q0[idx2+k] - q1[idx2+k] - q2[idx2+k] + q3[idx2+k]; + wndSum2 += t; + } + + if( numType == 2 ) + { + num = wndSum2 - 2*num + templSum2; + num = MAX(num, 0.); + } + } + + if( isNormed ) + { + t = sqrt(MAX(wndSum2 - wndMean2,0))*templNorm; + if( fabs(num) < t ) + num /= t; + else if( fabs(num) < t*1.125 ) + num = num > 0 ? 1 : -1; + else + num = method != CV_TM_SQDIFF_NORMED ? 0 : 1; + } + + rrow[j] = (float)num; + } + } +} + + +CV_IMPL void +cvMatchTemplate( const CvArr* _img, const CvArr* _templ, CvArr* _result, int method ) +{ + cv::Mat img = cv::cvarrToMat(_img), templ = cv::cvarrToMat(_templ), + result = cv::cvarrToMat(_result); + CV_Assert( result.size() == cv::Size(std::abs(img.cols - templ.cols) + 1, + std::abs(img.rows - templ.rows) + 1) && + result.type() == CV_32F ); + matchTemplate(img, templ, result, method); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/thresh.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/thresh.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/thresh.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/thresh.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,877 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv +{ + +static void +thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type ) +{ + int i, j, j_scalar = 0; + uchar tab[256]; + Size roi = _src.size(); + roi.width *= _src.channels(); + + if( _src.isContinuous() && _dst.isContinuous() ) + { + roi.width *= roi.height; + roi.height = 1; + } + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::thresh_8u(_src, _dst, roi.width, roi.height, thresh, maxval, type)) + return; +#endif + + switch( type ) + { + case THRESH_BINARY: + for( i = 0; i <= thresh; i++ ) + tab[i] = 0; + for( ; i < 256; i++ ) + tab[i] = maxval; + break; + case THRESH_BINARY_INV: + for( i = 0; i <= thresh; i++ ) + tab[i] = maxval; + for( ; i < 256; i++ ) + tab[i] = 0; + break; + case THRESH_TRUNC: + for( i = 0; i <= thresh; i++ ) + tab[i] = (uchar)i; + for( ; i < 256; i++ ) + tab[i] = thresh; + break; + case THRESH_TOZERO: + for( i = 0; i <= thresh; i++ ) + tab[i] = 0; + for( ; i < 256; i++ ) + tab[i] = (uchar)i; + break; + case THRESH_TOZERO_INV: + for( i = 0; i <= thresh; i++ ) + tab[i] = (uchar)i; + for( ; i < 256; i++ ) + tab[i] = 0; + break; + default: + CV_Error( CV_StsBadArg, "Unknown threshold type" ); + } + +#if CV_SSE2 + if( checkHardwareSupport(CV_CPU_SSE2) ) + { + __m128i _x80 = _mm_set1_epi8('\x80'); + __m128i thresh_u = _mm_set1_epi8(thresh); + __m128i thresh_s = _mm_set1_epi8(thresh ^ 0x80); + __m128i maxval_ = _mm_set1_epi8(maxval); + j_scalar = roi.width & -8; + + for( i = 0; i < roi.height; i++ ) + { + const uchar* src = (const uchar*)(_src.data + _src.step*i); + uchar* dst = (uchar*)(_dst.data + _dst.step*i); + + switch( type ) + { + case THRESH_BINARY: + for( j = 0; j <= roi.width - 32; j += 32 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 16) ); + v0 = _mm_cmpgt_epi8( _mm_xor_si128(v0, _x80), thresh_s ); + v1 = _mm_cmpgt_epi8( _mm_xor_si128(v1, _x80), thresh_s ); + v0 = _mm_and_si128( v0, maxval_ ); + v1 = _mm_and_si128( v1, maxval_ ); + _mm_storeu_si128( (__m128i*)(dst + j), v0 ); + _mm_storeu_si128( (__m128i*)(dst + j + 16), v1 ); + } + + for( ; j <= roi.width - 8; j += 8 ) + { + __m128i v0 = _mm_loadl_epi64( (const __m128i*)(src + j) ); + v0 = _mm_cmpgt_epi8( _mm_xor_si128(v0, _x80), thresh_s ); + v0 = _mm_and_si128( v0, maxval_ ); + _mm_storel_epi64( (__m128i*)(dst + j), v0 ); + } + break; + + case THRESH_BINARY_INV: + for( j = 0; j <= roi.width - 32; j += 32 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 16) ); + v0 = _mm_cmpgt_epi8( _mm_xor_si128(v0, _x80), thresh_s ); + v1 = _mm_cmpgt_epi8( _mm_xor_si128(v1, _x80), thresh_s ); + v0 = _mm_andnot_si128( v0, maxval_ ); + v1 = _mm_andnot_si128( v1, maxval_ ); + _mm_storeu_si128( (__m128i*)(dst + j), v0 ); + _mm_storeu_si128( (__m128i*)(dst + j + 16), v1 ); + } + + for( ; j <= roi.width - 8; j += 8 ) + { + __m128i v0 = _mm_loadl_epi64( (const __m128i*)(src + j) ); + v0 = _mm_cmpgt_epi8( _mm_xor_si128(v0, _x80), thresh_s ); + v0 = _mm_andnot_si128( v0, maxval_ ); + _mm_storel_epi64( (__m128i*)(dst + j), v0 ); + } + break; + + case THRESH_TRUNC: + for( j = 0; j <= roi.width - 32; j += 32 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 16) ); + v0 = _mm_subs_epu8( v0, _mm_subs_epu8( v0, thresh_u )); + v1 = _mm_subs_epu8( v1, _mm_subs_epu8( v1, thresh_u )); + _mm_storeu_si128( (__m128i*)(dst + j), v0 ); + _mm_storeu_si128( (__m128i*)(dst + j + 16), v1 ); + } + + for( ; j <= roi.width - 8; j += 8 ) + { + __m128i v0 = _mm_loadl_epi64( (const __m128i*)(src + j) ); + v0 = _mm_subs_epu8( v0, _mm_subs_epu8( v0, thresh_u )); + _mm_storel_epi64( (__m128i*)(dst + j), v0 ); + } + break; + + case THRESH_TOZERO: + for( j = 0; j <= roi.width - 32; j += 32 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 16) ); + v0 = _mm_and_si128( v0, _mm_cmpgt_epi8(_mm_xor_si128(v0, _x80), thresh_s )); + v1 = _mm_and_si128( v1, _mm_cmpgt_epi8(_mm_xor_si128(v1, _x80), thresh_s )); + _mm_storeu_si128( (__m128i*)(dst + j), v0 ); + _mm_storeu_si128( (__m128i*)(dst + j + 16), v1 ); + } + + for( ; j <= roi.width - 8; j += 8 ) + { + __m128i v0 = _mm_loadl_epi64( (const __m128i*)(src + j) ); + v0 = _mm_and_si128( v0, _mm_cmpgt_epi8(_mm_xor_si128(v0, _x80), thresh_s )); + _mm_storel_epi64( (__m128i*)(dst + j), v0 ); + } + break; + + case THRESH_TOZERO_INV: + for( j = 0; j <= roi.width - 32; j += 32 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 16) ); + v0 = _mm_andnot_si128( _mm_cmpgt_epi8(_mm_xor_si128(v0, _x80), thresh_s ), v0 ); + v1 = _mm_andnot_si128( _mm_cmpgt_epi8(_mm_xor_si128(v1, _x80), thresh_s ), v1 ); + _mm_storeu_si128( (__m128i*)(dst + j), v0 ); + _mm_storeu_si128( (__m128i*)(dst + j + 16), v1 ); + } + + for( ; j <= roi.width - 8; j += 8 ) + { + __m128i v0 = _mm_loadl_epi64( (const __m128i*)(src + j) ); + v0 = _mm_andnot_si128( _mm_cmpgt_epi8(_mm_xor_si128(v0, _x80), thresh_s ), v0 ); + _mm_storel_epi64( (__m128i*)(dst + j), v0 ); + } + break; + } + } + } +#endif + + if( j_scalar < roi.width ) + { + for( i = 0; i < roi.height; i++ ) + { + const uchar* src = (const uchar*)(_src.data + _src.step*i); + uchar* dst = (uchar*)(_dst.data + _dst.step*i); + j = j_scalar; +#if CV_ENABLE_UNROLLED + for( ; j <= roi.width - 4; j += 4 ) + { + uchar t0 = tab[src[j]]; + uchar t1 = tab[src[j+1]]; + + dst[j] = t0; + dst[j+1] = t1; + + t0 = tab[src[j+2]]; + t1 = tab[src[j+3]]; + + dst[j+2] = t0; + dst[j+3] = t1; + } +#endif + for( ; j < roi.width; j++ ) + dst[j] = tab[src[j]]; + } + } +} + + +static void +thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type ) +{ + int i, j; + Size roi = _src.size(); + roi.width *= _src.channels(); + const short* src = (const short*)_src.data; + short* dst = (short*)_dst.data; + size_t src_step = _src.step/sizeof(src[0]); + size_t dst_step = _dst.step/sizeof(dst[0]); + +#if CV_SSE2 + volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE); +#endif + + if( _src.isContinuous() && _dst.isContinuous() ) + { + roi.width *= roi.height; + roi.height = 1; + } + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::thresh_16s(_src, _dst, roi.width, roi.height, thresh, maxval, type)) + return; +#endif + + switch( type ) + { + case THRESH_BINARY: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i thresh8 = _mm_set1_epi16(thresh), maxval8 = _mm_set1_epi16(maxval); + for( ; j <= roi.width - 16; j += 16 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); + v0 = _mm_cmpgt_epi16( v0, thresh8 ); + v1 = _mm_cmpgt_epi16( v1, thresh8 ); + v0 = _mm_and_si128( v0, maxval8 ); + v1 = _mm_and_si128( v1, maxval8 ); + _mm_storeu_si128((__m128i*)(dst + j), v0 ); + _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); + } + } + #endif + + for( ; j < roi.width; j++ ) + dst[j] = src[j] > thresh ? maxval : 0; + } + break; + + case THRESH_BINARY_INV: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i thresh8 = _mm_set1_epi16(thresh), maxval8 = _mm_set1_epi16(maxval); + for( ; j <= roi.width - 16; j += 16 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); + v0 = _mm_cmpgt_epi16( v0, thresh8 ); + v1 = _mm_cmpgt_epi16( v1, thresh8 ); + v0 = _mm_andnot_si128( v0, maxval8 ); + v1 = _mm_andnot_si128( v1, maxval8 ); + _mm_storeu_si128((__m128i*)(dst + j), v0 ); + _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); + } + } + #endif + + for( ; j < roi.width; j++ ) + dst[j] = src[j] <= thresh ? maxval : 0; + } + break; + + case THRESH_TRUNC: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i thresh8 = _mm_set1_epi16(thresh); + for( ; j <= roi.width - 16; j += 16 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); + v0 = _mm_min_epi16( v0, thresh8 ); + v1 = _mm_min_epi16( v1, thresh8 ); + _mm_storeu_si128((__m128i*)(dst + j), v0 ); + _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); + } + } + #endif + + for( ; j < roi.width; j++ ) + dst[j] = std::min(src[j], thresh); + } + break; + + case THRESH_TOZERO: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i thresh8 = _mm_set1_epi16(thresh); + for( ; j <= roi.width - 16; j += 16 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); + v0 = _mm_and_si128(v0, _mm_cmpgt_epi16(v0, thresh8)); + v1 = _mm_and_si128(v1, _mm_cmpgt_epi16(v1, thresh8)); + _mm_storeu_si128((__m128i*)(dst + j), v0 ); + _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); + } + } + #endif + + for( ; j < roi.width; j++ ) + { + short v = src[j]; + dst[j] = v > thresh ? v : 0; + } + } + break; + + case THRESH_TOZERO_INV: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; + #if CV_SSE2 + if( useSIMD ) + { + __m128i thresh8 = _mm_set1_epi16(thresh); + for( ; j <= roi.width - 16; j += 16 ) + { + __m128i v0, v1; + v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); + v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); + v0 = _mm_andnot_si128(_mm_cmpgt_epi16(v0, thresh8), v0); + v1 = _mm_andnot_si128(_mm_cmpgt_epi16(v1, thresh8), v1); + _mm_storeu_si128((__m128i*)(dst + j), v0 ); + _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); + } + } + #endif + for( ; j < roi.width; j++ ) + { + short v = src[j]; + dst[j] = v <= thresh ? v : 0; + } + } + break; + default: + return CV_Error( CV_StsBadArg, "" ); + } +} + + +static void +thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type ) +{ + int i, j; + Size roi = _src.size(); + roi.width *= _src.channels(); + const float* src = (const float*)_src.data; + float* dst = (float*)_dst.data; + size_t src_step = _src.step/sizeof(src[0]); + size_t dst_step = _dst.step/sizeof(dst[0]); + +#if CV_SSE2 + volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE); +#endif + + if( _src.isContinuous() && _dst.isContinuous() ) + { + roi.width *= roi.height; + roi.height = 1; + } + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::thresh_32f(_src, _dst, roi.width, roi.height, thresh, maxval, type)) + return; +#endif + + switch( type ) + { + case THRESH_BINARY: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; +#if CV_SSE2 + if( useSIMD ) + { + __m128 thresh4 = _mm_set1_ps(thresh), maxval4 = _mm_set1_ps(maxval); + for( ; j <= roi.width - 8; j += 8 ) + { + __m128 v0, v1; + v0 = _mm_loadu_ps( src + j ); + v1 = _mm_loadu_ps( src + j + 4 ); + v0 = _mm_cmpgt_ps( v0, thresh4 ); + v1 = _mm_cmpgt_ps( v1, thresh4 ); + v0 = _mm_and_ps( v0, maxval4 ); + v1 = _mm_and_ps( v1, maxval4 ); + _mm_storeu_ps( dst + j, v0 ); + _mm_storeu_ps( dst + j + 4, v1 ); + } + } +#endif + + for( ; j < roi.width; j++ ) + dst[j] = src[j] > thresh ? maxval : 0; + } + break; + + case THRESH_BINARY_INV: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; +#if CV_SSE2 + if( useSIMD ) + { + __m128 thresh4 = _mm_set1_ps(thresh), maxval4 = _mm_set1_ps(maxval); + for( ; j <= roi.width - 8; j += 8 ) + { + __m128 v0, v1; + v0 = _mm_loadu_ps( src + j ); + v1 = _mm_loadu_ps( src + j + 4 ); + v0 = _mm_cmple_ps( v0, thresh4 ); + v1 = _mm_cmple_ps( v1, thresh4 ); + v0 = _mm_and_ps( v0, maxval4 ); + v1 = _mm_and_ps( v1, maxval4 ); + _mm_storeu_ps( dst + j, v0 ); + _mm_storeu_ps( dst + j + 4, v1 ); + } + } +#endif + + for( ; j < roi.width; j++ ) + dst[j] = src[j] <= thresh ? maxval : 0; + } + break; + + case THRESH_TRUNC: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; +#if CV_SSE2 + if( useSIMD ) + { + __m128 thresh4 = _mm_set1_ps(thresh); + for( ; j <= roi.width - 8; j += 8 ) + { + __m128 v0, v1; + v0 = _mm_loadu_ps( src + j ); + v1 = _mm_loadu_ps( src + j + 4 ); + v0 = _mm_min_ps( v0, thresh4 ); + v1 = _mm_min_ps( v1, thresh4 ); + _mm_storeu_ps( dst + j, v0 ); + _mm_storeu_ps( dst + j + 4, v1 ); + } + } +#endif + + for( ; j < roi.width; j++ ) + dst[j] = std::min(src[j], thresh); + } + break; + + case THRESH_TOZERO: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; +#if CV_SSE2 + if( useSIMD ) + { + __m128 thresh4 = _mm_set1_ps(thresh); + for( ; j <= roi.width - 8; j += 8 ) + { + __m128 v0, v1; + v0 = _mm_loadu_ps( src + j ); + v1 = _mm_loadu_ps( src + j + 4 ); + v0 = _mm_and_ps(v0, _mm_cmpgt_ps(v0, thresh4)); + v1 = _mm_and_ps(v1, _mm_cmpgt_ps(v1, thresh4)); + _mm_storeu_ps( dst + j, v0 ); + _mm_storeu_ps( dst + j + 4, v1 ); + } + } +#endif + + for( ; j < roi.width; j++ ) + { + float v = src[j]; + dst[j] = v > thresh ? v : 0; + } + } + break; + + case THRESH_TOZERO_INV: + for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) + { + j = 0; +#if CV_SSE2 + if( useSIMD ) + { + __m128 thresh4 = _mm_set1_ps(thresh); + for( ; j <= roi.width - 8; j += 8 ) + { + __m128 v0, v1; + v0 = _mm_loadu_ps( src + j ); + v1 = _mm_loadu_ps( src + j + 4 ); + v0 = _mm_and_ps(v0, _mm_cmple_ps(v0, thresh4)); + v1 = _mm_and_ps(v1, _mm_cmple_ps(v1, thresh4)); + _mm_storeu_ps( dst + j, v0 ); + _mm_storeu_ps( dst + j + 4, v1 ); + } + } +#endif + for( ; j < roi.width; j++ ) + { + float v = src[j]; + dst[j] = v <= thresh ? v : 0; + } + } + break; + default: + return CV_Error( CV_StsBadArg, "" ); + } +} + + +static double +getThreshVal_Otsu_8u( const Mat& _src ) +{ + Size size = _src.size(); + if( _src.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + const int N = 256; + int i, j, h[N] = {0}; + for( i = 0; i < size.height; i++ ) + { + const uchar* src = _src.data + _src.step*i; + j = 0; + #if CV_ENABLE_UNROLLED + for( ; j <= size.width - 4; j += 4 ) + { + int v0 = src[j], v1 = src[j+1]; + h[v0]++; h[v1]++; + v0 = src[j+2]; v1 = src[j+3]; + h[v0]++; h[v1]++; + } + #endif + for( ; j < size.width; j++ ) + h[src[j]]++; + } + + double mu = 0, scale = 1./(size.width*size.height); + for( i = 0; i < N; i++ ) + mu += i*(double)h[i]; + + mu *= scale; + double mu1 = 0, q1 = 0; + double max_sigma = 0, max_val = 0; + + for( i = 0; i < N; i++ ) + { + double p_i, q2, mu2, sigma; + + p_i = h[i]*scale; + mu1 *= q1; + q1 += p_i; + q2 = 1. - q1; + + if( std::min(q1,q2) < FLT_EPSILON || std::max(q1,q2) > 1. - FLT_EPSILON ) + continue; + + mu1 = (mu1 + i*p_i)/q1; + mu2 = (mu - q1*mu1)/q2; + sigma = q1*q2*(mu1 - mu2)*(mu1 - mu2); + if( sigma > max_sigma ) + { + max_sigma = sigma; + max_val = i; + } + } + + return max_val; +} + +class ThresholdRunner : public ParallelLoopBody +{ +public: + ThresholdRunner(Mat _src, Mat _dst, double _thresh, double _maxval, int _thresholdType) + { + src = _src; + dst = _dst; + + thresh = _thresh; + maxval = _maxval; + thresholdType = _thresholdType; + } + + void operator () ( const Range& range ) const + { + int row0 = range.start; + int row1 = range.end; + + Mat srcStripe = src.rowRange(row0, row1); + Mat dstStripe = dst.rowRange(row0, row1); + + if (srcStripe.depth() == CV_8U) + { + thresh_8u( srcStripe, dstStripe, (uchar)thresh, (uchar)maxval, thresholdType ); + } + else if( srcStripe.depth() == CV_16S ) + { + thresh_16s( srcStripe, dstStripe, (short)thresh, (short)maxval, thresholdType ); + } + else if( srcStripe.depth() == CV_32F ) + { + thresh_32f( srcStripe, dstStripe, (float)thresh, (float)maxval, thresholdType ); + } + } + +private: + Mat src; + Mat dst; + int nStripes; + + double thresh; + double maxval; + int thresholdType; +}; + +} + +double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type ) +{ + Mat src = _src.getMat(); + bool use_otsu = (type & THRESH_OTSU) != 0; + type &= THRESH_MASK; + + if( use_otsu ) + { + CV_Assert( src.type() == CV_8UC1 ); + thresh = getThreshVal_Otsu_8u(src); + } + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( src.depth() == CV_8U ) + { + int ithresh = cvFloor(thresh); + thresh = ithresh; + int imaxval = cvRound(maxval); + if( type == THRESH_TRUNC ) + imaxval = ithresh; + imaxval = saturate_cast(imaxval); + + if( ithresh < 0 || ithresh >= 255 ) + { + if( type == THRESH_BINARY || type == THRESH_BINARY_INV || + ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < 0) || + (type == THRESH_TOZERO && ithresh >= 255) ) + { + int v = type == THRESH_BINARY ? (ithresh >= 255 ? 0 : imaxval) : + type == THRESH_BINARY_INV ? (ithresh >= 255 ? imaxval : 0) : + /*type == THRESH_TRUNC ? imaxval :*/ 0; + dst.setTo(v); + } + else + src.copyTo(dst); + return thresh; + } + thresh = ithresh; + maxval = imaxval; + } + else if( src.depth() == CV_16S ) + { + int ithresh = cvFloor(thresh); + thresh = ithresh; + int imaxval = cvRound(maxval); + if( type == THRESH_TRUNC ) + imaxval = ithresh; + imaxval = saturate_cast(imaxval); + + if( ithresh < SHRT_MIN || ithresh >= SHRT_MAX ) + { + if( type == THRESH_BINARY || type == THRESH_BINARY_INV || + ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < SHRT_MIN) || + (type == THRESH_TOZERO && ithresh >= SHRT_MAX) ) + { + int v = type == THRESH_BINARY ? (ithresh >= SHRT_MAX ? 0 : imaxval) : + type == THRESH_BINARY_INV ? (ithresh >= SHRT_MAX ? imaxval : 0) : + /*type == THRESH_TRUNC ? imaxval :*/ 0; + dst.setTo(v); + } + else + src.copyTo(dst); + return thresh; + } + thresh = ithresh; + maxval = imaxval; + } + else if( src.depth() == CV_32F ) + ; + else + CV_Error( CV_StsUnsupportedFormat, "" ); + + parallel_for_(Range(0, dst.rows), + ThresholdRunner(src, dst, thresh, maxval, type), + dst.total()/(double)(1<<16)); + return thresh; +} + + +void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, + int method, int type, int blockSize, double delta ) +{ + Mat src = _src.getMat(); + CV_Assert( src.type() == CV_8UC1 ); + CV_Assert( blockSize % 2 == 1 && blockSize > 1 ); + Size size = src.size(); + + _dst.create( size, src.type() ); + Mat dst = _dst.getMat(); + + if( maxValue < 0 ) + { + dst = Scalar(0); + return; + } + + Mat mean; + + if( src.data != dst.data ) + mean = dst; + + if( method == ADAPTIVE_THRESH_MEAN_C ) + boxFilter( src, mean, src.type(), Size(blockSize, blockSize), + Point(-1,-1), true, BORDER_REPLICATE ); + else if( method == ADAPTIVE_THRESH_GAUSSIAN_C ) + GaussianBlur( src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE ); + else + CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive threshold method" ); + + int i, j; + uchar imaxval = saturate_cast(maxValue); + int idelta = type == THRESH_BINARY ? cvCeil(delta) : cvFloor(delta); + uchar tab[768]; + + if( type == CV_THRESH_BINARY ) + for( i = 0; i < 768; i++ ) + tab[i] = (uchar)(i - 255 > -idelta ? imaxval : 0); + else if( type == CV_THRESH_BINARY_INV ) + for( i = 0; i < 768; i++ ) + tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0); + else + CV_Error( CV_StsBadFlag, "Unknown/unsupported threshold type" ); + + if( src.isContinuous() && mean.isContinuous() && dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + + for( i = 0; i < size.height; i++ ) + { + const uchar* sdata = src.data + src.step*i; + const uchar* mdata = mean.data + mean.step*i; + uchar* ddata = dst.data + dst.step*i; + + for( j = 0; j < size.width; j++ ) + ddata[j] = tab[sdata[j] - mdata[j] + 255]; + } +} + +CV_IMPL double +cvThreshold( const void* srcarr, void* dstarr, double thresh, double maxval, int type ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), dst0 = dst; + + CV_Assert( src.size == dst.size && src.channels() == dst.channels() && + (src.depth() == dst.depth() || dst.depth() == CV_8U)); + + thresh = cv::threshold( src, dst, thresh, maxval, type ); + if( dst0.data != dst.data ) + dst.convertTo( dst0, dst0.depth() ); + return thresh; +} + + +CV_IMPL void +cvAdaptiveThreshold( const void *srcIm, void *dstIm, double maxValue, + int method, int type, int blockSize, double delta ) +{ + cv::Mat src = cv::cvarrToMat(srcIm), dst = cv::cvarrToMat(dstIm); + CV_Assert( src.size == dst.size && src.type() == dst.type() ); + cv::adaptiveThreshold( src, dst, maxValue, method, type, blockSize, delta ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/undistort.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/undistort.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/undistort.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/undistort.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,572 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +cv::Mat cv::getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize, + bool centerPrincipalPoint ) +{ + Mat cameraMatrix = _cameraMatrix.getMat(); + if( !centerPrincipalPoint && cameraMatrix.type() == CV_64F ) + return cameraMatrix; + + Mat newCameraMatrix; + cameraMatrix.convertTo(newCameraMatrix, CV_64F); + if( centerPrincipalPoint ) + { + ((double*)newCameraMatrix.data)[2] = (imgsize.width-1)*0.5; + ((double*)newCameraMatrix.data)[5] = (imgsize.height-1)*0.5; + } + return newCameraMatrix; +} + +void cv::initUndistortRectifyMap( InputArray _cameraMatrix, InputArray _distCoeffs, + InputArray _matR, InputArray _newCameraMatrix, + Size size, int m1type, OutputArray _map1, OutputArray _map2 ) +{ + Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); + Mat matR = _matR.getMat(), newCameraMatrix = _newCameraMatrix.getMat(); + + if( m1type <= 0 ) + m1type = CV_16SC2; + CV_Assert( m1type == CV_16SC2 || m1type == CV_32FC1 || m1type == CV_32FC2 ); + _map1.create( size, m1type ); + Mat map1 = _map1.getMat(), map2; + if( m1type != CV_32FC2 ) + { + _map2.create( size, m1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 ); + map2 = _map2.getMat(); + } + else + _map2.release(); + + Mat_ R = Mat_::eye(3, 3); + Mat_ A = Mat_(cameraMatrix), Ar; + + if( newCameraMatrix.data ) + Ar = Mat_(newCameraMatrix); + else + Ar = getDefaultNewCameraMatrix( A, size, true ); + + if( matR.data ) + R = Mat_(matR); + + if( distCoeffs.data ) + distCoeffs = Mat_(distCoeffs); + else + { + distCoeffs.create(8, 1, CV_64F); + distCoeffs = 0.; + } + + CV_Assert( A.size() == Size(3,3) && A.size() == R.size() ); + CV_Assert( Ar.size() == Size(3,3) || Ar.size() == Size(4, 3)); + Mat_ iR = (Ar.colRange(0,3)*R).inv(DECOMP_LU); + const double* ir = &iR(0,0); + + double u0 = A(0, 2), v0 = A(1, 2); + double fx = A(0, 0), fy = A(1, 1); + + CV_Assert( distCoeffs.size() == Size(1, 4) || distCoeffs.size() == Size(4, 1) || + distCoeffs.size() == Size(1, 5) || distCoeffs.size() == Size(5, 1) || + distCoeffs.size() == Size(1, 8) || distCoeffs.size() == Size(8, 1)); + + if( distCoeffs.rows != 1 && !distCoeffs.isContinuous() ) + distCoeffs = distCoeffs.t(); + + double k1 = ((double*)distCoeffs.data)[0]; + double k2 = ((double*)distCoeffs.data)[1]; + double p1 = ((double*)distCoeffs.data)[2]; + double p2 = ((double*)distCoeffs.data)[3]; + double k3 = distCoeffs.cols + distCoeffs.rows - 1 >= 5 ? ((double*)distCoeffs.data)[4] : 0.; + double k4 = distCoeffs.cols + distCoeffs.rows - 1 >= 8 ? ((double*)distCoeffs.data)[5] : 0.; + double k5 = distCoeffs.cols + distCoeffs.rows - 1 >= 8 ? ((double*)distCoeffs.data)[6] : 0.; + double k6 = distCoeffs.cols + distCoeffs.rows - 1 >= 8 ? ((double*)distCoeffs.data)[7] : 0.; + + for( int i = 0; i < size.height; i++ ) + { + float* m1f = (float*)(map1.data + map1.step*i); + float* m2f = (float*)(map2.data + map2.step*i); + short* m1 = (short*)m1f; + ushort* m2 = (ushort*)m2f; + double _x = i*ir[1] + ir[2], _y = i*ir[4] + ir[5], _w = i*ir[7] + ir[8]; + + for( int j = 0; j < size.width; j++, _x += ir[0], _y += ir[3], _w += ir[6] ) + { + double w = 1./_w, x = _x*w, y = _y*w; + double x2 = x*x, y2 = y*y; + double r2 = x2 + y2, _2xy = 2*x*y; + double kr = (1 + ((k3*r2 + k2)*r2 + k1)*r2)/(1 + ((k6*r2 + k5)*r2 + k4)*r2); + double u = fx*(x*kr + p1*_2xy + p2*(r2 + 2*x2)) + u0; + double v = fy*(y*kr + p1*(r2 + 2*y2) + p2*_2xy) + v0; + if( m1type == CV_16SC2 ) + { + int iu = saturate_cast(u*INTER_TAB_SIZE); + int iv = saturate_cast(v*INTER_TAB_SIZE); + m1[j*2] = (short)(iu >> INTER_BITS); + m1[j*2+1] = (short)(iv >> INTER_BITS); + m2[j] = (ushort)((iv & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (iu & (INTER_TAB_SIZE-1))); + } + else if( m1type == CV_32FC1 ) + { + m1f[j] = (float)u; + m2f[j] = (float)v; + } + else + { + m1f[j*2] = (float)u; + m1f[j*2+1] = (float)v; + } + } + } +} + + +void cv::undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix, + InputArray _distCoeffs, InputArray _newCameraMatrix ) +{ + Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat(); + Mat distCoeffs = _distCoeffs.getMat(), newCameraMatrix = _newCameraMatrix.getMat(); + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + CV_Assert( dst.data != src.data ); + + int stripe_size0 = std::min(std::max(1, (1 << 12) / std::max(src.cols, 1)), src.rows); + Mat map1(stripe_size0, src.cols, CV_16SC2), map2(stripe_size0, src.cols, CV_16UC1); + + Mat_ A, Ar, I = Mat_::eye(3,3); + + cameraMatrix.convertTo(A, CV_64F); + if( distCoeffs.data ) + distCoeffs = Mat_(distCoeffs); + else + { + distCoeffs.create(5, 1, CV_64F); + distCoeffs = 0.; + } + + if( newCameraMatrix.data ) + newCameraMatrix.convertTo(Ar, CV_64F); + else + A.copyTo(Ar); + + double v0 = Ar(1, 2); + for( int y = 0; y < src.rows; y += stripe_size0 ) + { + int stripe_size = std::min( stripe_size0, src.rows - y ); + Ar(1, 2) = v0 - y; + Mat map1_part = map1.rowRange(0, stripe_size), + map2_part = map2.rowRange(0, stripe_size), + dst_part = dst.rowRange(y, y + stripe_size); + + initUndistortRectifyMap( A, distCoeffs, I, Ar, Size(src.cols, stripe_size), + map1_part.type(), map1_part, map2_part ); + remap( src, dst_part, map1_part, map2_part, INTER_LINEAR, BORDER_CONSTANT ); + } +} + + +CV_IMPL void +cvUndistort2( const CvArr* srcarr, CvArr* dstarr, const CvMat* Aarr, const CvMat* dist_coeffs, const CvMat* newAarr ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr), dst0 = dst; + cv::Mat A = cv::cvarrToMat(Aarr), distCoeffs = cv::cvarrToMat(dist_coeffs), newA; + if( newAarr ) + newA = cv::cvarrToMat(newAarr); + + CV_Assert( src.size() == dst.size() && src.type() == dst.type() ); + cv::undistort( src, dst, A, distCoeffs, newA ); +} + + +CV_IMPL void cvInitUndistortMap( const CvMat* Aarr, const CvMat* dist_coeffs, + CvArr* mapxarr, CvArr* mapyarr ) +{ + cv::Mat A = cv::cvarrToMat(Aarr), distCoeffs = cv::cvarrToMat(dist_coeffs); + cv::Mat mapx = cv::cvarrToMat(mapxarr), mapy, mapx0 = mapx, mapy0; + + if( mapyarr ) + mapy0 = mapy = cv::cvarrToMat(mapyarr); + + cv::initUndistortRectifyMap( A, distCoeffs, cv::Mat(), A, + mapx.size(), mapx.type(), mapx, mapy ); + CV_Assert( mapx0.data == mapx.data && mapy0.data == mapy.data ); +} + +void +cvInitUndistortRectifyMap( const CvMat* Aarr, const CvMat* dist_coeffs, + const CvMat *Rarr, const CvMat* ArArr, CvArr* mapxarr, CvArr* mapyarr ) +{ + cv::Mat A = cv::cvarrToMat(Aarr), distCoeffs, R, Ar; + cv::Mat mapx = cv::cvarrToMat(mapxarr), mapy, mapx0 = mapx, mapy0; + + if( mapyarr ) + mapy0 = mapy = cv::cvarrToMat(mapyarr); + + if( dist_coeffs ) + distCoeffs = cv::cvarrToMat(dist_coeffs); + if( Rarr ) + R = cv::cvarrToMat(Rarr); + if( ArArr ) + Ar = cv::cvarrToMat(ArArr); + + cv::initUndistortRectifyMap( A, distCoeffs, R, Ar, mapx.size(), mapx.type(), mapx, mapy ); + CV_Assert( mapx0.data == mapx.data && mapy0.data == mapy.data ); +} + + +void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix, + const CvMat* _distCoeffs, + const CvMat* matR, const CvMat* matP ) +{ + double A[3][3], RR[3][3], k[8]={0,0,0,0,0,0,0,0}, fx, fy, ifx, ify, cx, cy; + CvMat matA=cvMat(3, 3, CV_64F, A), _Dk; + CvMat _RR=cvMat(3, 3, CV_64F, RR); + const CvPoint2D32f* srcf; + const CvPoint2D64f* srcd; + CvPoint2D32f* dstf; + CvPoint2D64f* dstd; + int stype, dtype; + int sstep, dstep; + int i, j, n, iters = 1; + + CV_Assert( CV_IS_MAT(_src) && CV_IS_MAT(_dst) && + (_src->rows == 1 || _src->cols == 1) && + (_dst->rows == 1 || _dst->cols == 1) && + _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && + (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && + (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2)); + + CV_Assert( CV_IS_MAT(_cameraMatrix) && + _cameraMatrix->rows == 3 && _cameraMatrix->cols == 3 ); + + cvConvert( _cameraMatrix, &matA ); + + if( _distCoeffs ) + { + CV_Assert( CV_IS_MAT(_distCoeffs) && + (_distCoeffs->rows == 1 || _distCoeffs->cols == 1) && + (_distCoeffs->rows*_distCoeffs->cols == 4 || + _distCoeffs->rows*_distCoeffs->cols == 5 || + _distCoeffs->rows*_distCoeffs->cols == 8)); + + _Dk = cvMat( _distCoeffs->rows, _distCoeffs->cols, + CV_MAKETYPE(CV_64F,CV_MAT_CN(_distCoeffs->type)), k); + + cvConvert( _distCoeffs, &_Dk ); + iters = 5; + } + + if( matR ) + { + CV_Assert( CV_IS_MAT(matR) && matR->rows == 3 && matR->cols == 3 ); + cvConvert( matR, &_RR ); + } + else + cvSetIdentity(&_RR); + + if( matP ) + { + double PP[3][3]; + CvMat _P3x3, _PP=cvMat(3, 3, CV_64F, PP); + CV_Assert( CV_IS_MAT(matP) && matP->rows == 3 && (matP->cols == 3 || matP->cols == 4)); + cvConvert( cvGetCols(matP, &_P3x3, 0, 3), &_PP ); + cvMatMul( &_PP, &_RR, &_RR ); + } + + srcf = (const CvPoint2D32f*)_src->data.ptr; + srcd = (const CvPoint2D64f*)_src->data.ptr; + dstf = (CvPoint2D32f*)_dst->data.ptr; + dstd = (CvPoint2D64f*)_dst->data.ptr; + stype = CV_MAT_TYPE(_src->type); + dtype = CV_MAT_TYPE(_dst->type); + sstep = _src->rows == 1 ? 1 : _src->step/CV_ELEM_SIZE(stype); + dstep = _dst->rows == 1 ? 1 : _dst->step/CV_ELEM_SIZE(dtype); + + n = _src->rows + _src->cols - 1; + + fx = A[0][0]; + fy = A[1][1]; + ifx = 1./fx; + ify = 1./fy; + cx = A[0][2]; + cy = A[1][2]; + + for( i = 0; i < n; i++ ) + { + double x, y, x0, y0; + if( stype == CV_32FC2 ) + { + x = srcf[i*sstep].x; + y = srcf[i*sstep].y; + } + else + { + x = srcd[i*sstep].x; + y = srcd[i*sstep].y; + } + + x0 = x = (x - cx)*ifx; + y0 = y = (y - cy)*ify; + + // compensate distortion iteratively + for( j = 0; j < iters; j++ ) + { + double r2 = x*x + y*y; + double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2); + double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x); + double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y; + x = (x0 - deltaX)*icdist; + y = (y0 - deltaY)*icdist; + } + + double xx = RR[0][0]*x + RR[0][1]*y + RR[0][2]; + double yy = RR[1][0]*x + RR[1][1]*y + RR[1][2]; + double ww = 1./(RR[2][0]*x + RR[2][1]*y + RR[2][2]); + x = xx*ww; + y = yy*ww; + + if( dtype == CV_32FC2 ) + { + dstf[i*dstep].x = (float)x; + dstf[i*dstep].y = (float)y; + } + else + { + dstd[i*dstep].x = x; + dstd[i*dstep].y = y; + } + } +} + + +void cv::undistortPoints( InputArray _src, OutputArray _dst, + InputArray _cameraMatrix, + InputArray _distCoeffs, + InputArray _Rmat, + InputArray _Pmat ) +{ + Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat(); + Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat(); + + CV_Assert( src.isContinuous() && (src.depth() == CV_32F || src.depth() == CV_64F) && + ((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2)); + + _dst.create(src.size(), src.type(), -1, true); + Mat dst = _dst.getMat(); + + CvMat _csrc = src, _cdst = dst, _ccameraMatrix = cameraMatrix; + CvMat matR, matP, _cdistCoeffs, *pR=0, *pP=0, *pD=0; + if( R.data ) + pR = &(matR = R); + if( P.data ) + pP = &(matP = P); + if( distCoeffs.data ) + pD = &(_cdistCoeffs = distCoeffs); + cvUndistortPoints(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP); +} + +namespace cv +{ + +static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int projType) +{ + double x = p.x, y = p.y; + double beta = 1 + 2*alpha; + double v = x*x + y*y + 1, iv = 1/v; + double u = sqrt(beta*v + alpha*alpha); + + double k = (u - alpha)*iv; + double kv = (v*beta/u - (u - alpha)*2)*iv*iv; + double kx = kv*x, ky = kv*y; + + if( projType == PROJ_SPHERICAL_ORTHO ) + { + if(J) + *J = Vec4d(kx*x + k, kx*y, ky*x, ky*y + k); + return Point2f((float)(x*k), (float)(y*k)); + } + if( projType == PROJ_SPHERICAL_EQRECT ) + { + // equirectangular + double iR = 1/(alpha + 1); + double x1 = std::max(std::min(x*k*iR, 1.), -1.); + double y1 = std::max(std::min(y*k*iR, 1.), -1.); + + if(J) + { + double fx1 = iR/sqrt(1 - x1*x1); + double fy1 = iR/sqrt(1 - y1*y1); + *J = Vec4d(fx1*(kx*x + k), fx1*ky*x, fy1*kx*y, fy1*(ky*y + k)); + } + return Point2f((float)asin(x1), (float)asin(y1)); + } + CV_Error(CV_StsBadArg, "Unknown projection type"); + return Point2f(); +} + + +static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType) +{ + static int avgiter = 0, avgn = 0; + + double eps = 1e-12; + Vec2d p(_p.x, _p.y), q(_p.x, _p.y), err; + Vec4d J; + int i, maxiter = 5; + + for( i = 0; i < maxiter; i++ ) + { + Point2f p1 = mapPointSpherical(Point2f((float)q[0], (float)q[1]), alpha, &J, projType); + err = Vec2d(p1.x, p1.y) - p; + if( err[0]*err[0] + err[1]*err[1] < eps ) + break; + + Vec4d JtJ(J[0]*J[0] + J[2]*J[2], J[0]*J[1] + J[2]*J[3], + J[0]*J[1] + J[2]*J[3], J[1]*J[1] + J[3]*J[3]); + double d = JtJ[0]*JtJ[3] - JtJ[1]*JtJ[2]; + d = d ? 1./d : 0; + Vec4d iJtJ(JtJ[3]*d, -JtJ[1]*d, -JtJ[2]*d, JtJ[0]*d); + Vec2d JtErr(J[0]*err[0] + J[2]*err[1], J[1]*err[0] + J[3]*err[1]); + + q -= Vec2d(iJtJ[0]*JtErr[0] + iJtJ[1]*JtErr[1], iJtJ[2]*JtErr[0] + iJtJ[3]*JtErr[1]); + //Matx22d J(kx*x + k, kx*y, ky*x, ky*y + k); + //q -= Vec2d((J.t()*J).inv()*(J.t()*err)); + } + + if( i < maxiter ) + { + avgiter += i; + avgn++; + if( avgn == 1500 ) + printf("avg iters = %g\n", (double)avgiter/avgn); + } + + return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX); +} + +} + +float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0, + Size imageSize, int destImageWidth, int m1type, + OutputArray _map1, OutputArray _map2, int projType, double _alpha ) +{ + Mat cameraMatrix0 = _cameraMatrix0.getMat(), distCoeffs0 = _distCoeffs0.getMat(); + double k[8] = {0,0,0,0,0,0,0,0}, M[9]={0,0,0,0,0,0,0,0,0}; + Mat distCoeffs(distCoeffs0.rows, distCoeffs0.cols, CV_MAKETYPE(CV_64F,distCoeffs0.channels()), k); + Mat cameraMatrix(3,3,CV_64F,M); + Point2f scenter((float)cameraMatrix.at(0,2), (float)cameraMatrix.at(1,2)); + Point2f dcenter((destImageWidth-1)*0.5f, 0.f); + float xmin = FLT_MAX, xmax = -FLT_MAX, ymin = FLT_MAX, ymax = -FLT_MAX; + int N = 9; + std::vector uvec(1), vvec(1); + Mat I = Mat::eye(3,3,CV_64F); + float alpha = (float)_alpha; + + int ndcoeffs = distCoeffs0.cols*distCoeffs0.rows*distCoeffs0.channels(); + CV_Assert((distCoeffs0.cols == 1 || distCoeffs0.rows == 1) && + (ndcoeffs == 4 || ndcoeffs == 5 || ndcoeffs == 8)); + CV_Assert(cameraMatrix0.size() == Size(3,3)); + distCoeffs0.convertTo(distCoeffs,CV_64F); + cameraMatrix0.convertTo(cameraMatrix,CV_64F); + + alpha = std::min(alpha, 0.999f); + + for( int i = 0; i < N; i++ ) + for( int j = 0; j < N; j++ ) + { + Point2f p((float)j*imageSize.width/(N-1), (float)i*imageSize.height/(N-1)); + uvec[0] = p; + undistortPoints(uvec, vvec, cameraMatrix, distCoeffs, I, I); + Point2f q = mapPointSpherical(vvec[0], alpha, 0, projType); + if( xmin > q.x ) xmin = q.x; + if( xmax < q.x ) xmax = q.x; + if( ymin > q.y ) ymin = q.y; + if( ymax < q.y ) ymax = q.y; + } + + float scale = (float)std::min(dcenter.x/fabs(xmax), dcenter.x/fabs(xmin)); + Size dsize(destImageWidth, cvCeil(std::max(scale*fabs(ymin)*2, scale*fabs(ymax)*2))); + dcenter.y = (dsize.height - 1)*0.5f; + + Mat mapxy(dsize, CV_32FC2); + double k1 = k[0], k2 = k[1], k3 = k[2], p1 = k[3], p2 = k[4], k4 = k[5], k5 = k[6], k6 = k[7]; + double fx = cameraMatrix.at(0,0), fy = cameraMatrix.at(1,1), cx = scenter.x, cy = scenter.y; + + for( int y = 0; y < dsize.height; y++ ) + { + Point2f* mxy = mapxy.ptr(y); + for( int x = 0; x < dsize.width; x++ ) + { + Point2f p = (Point2f((float)x, (float)y) - dcenter)*(1.f/scale); + Point2f q = invMapPointSpherical(p, alpha, projType); + if( q.x <= -FLT_MAX && q.y <= -FLT_MAX ) + { + mxy[x] = Point2f(-1.f, -1.f); + continue; + } + double x2 = q.x*q.x, y2 = q.y*q.y; + double r2 = x2 + y2, _2xy = 2*q.x*q.y; + double kr = 1 + ((k3*r2 + k2)*r2 + k1)*r2/(1 + ((k6*r2 + k5)*r2 + k4)*r2); + double u = fx*(q.x*kr + p1*_2xy + p2*(r2 + 2*x2)) + cx; + double v = fy*(q.y*kr + p1*(r2 + 2*y2) + p2*_2xy) + cy; + + mxy[x] = Point2f((float)u, (float)v); + } + } + + if(m1type == CV_32FC2) + { + _map1.create(mapxy.size(), mapxy.type()); + Mat map1 = _map1.getMat(); + mapxy.copyTo(map1); + _map2.release(); + } + else + convertMaps(mapxy, Mat(), _map1, _map2, m1type, false); + + return scale; +} + +/* End of file */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/src/utils.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/src/utils.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/src/utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/src/utils.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,280 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +CV_IMPL CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr, + CvContour* contour_header, CvSeqBlock* block ) +{ + CV_Assert( arr != 0 && contour_header != 0 && block != 0 ); + + int eltype; + CvMat hdr; + CvMat* mat = (CvMat*)arr; + + if( !CV_IS_MAT( mat )) + CV_Error( CV_StsBadArg, "Input array is not a valid matrix" ); + + if( CV_MAT_CN(mat->type) == 1 && mat->width == 2 ) + mat = cvReshape(mat, &hdr, 2); + + eltype = CV_MAT_TYPE( mat->type ); + if( eltype != CV_32SC2 && eltype != CV_32FC2 ) + CV_Error( CV_StsUnsupportedFormat, + "The matrix can not be converted to point sequence because of " + "inappropriate element type" ); + + if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type)) + CV_Error( CV_StsBadArg, + "The matrix converted to point sequence must be " + "1-dimensional and continuous" ); + + cvMakeSeqHeaderForArray( + (seq_kind & (CV_SEQ_KIND_MASK|CV_SEQ_FLAG_CLOSED)) | eltype, + sizeof(CvContour), CV_ELEM_SIZE(eltype), mat->data.ptr, + mat->width*mat->height, (CvSeq*)contour_header, block ); + + return (CvSeq*)contour_header; +} + +namespace cv +{ + +static void copyMakeBorder_8u( const uchar* src, size_t srcstep, Size srcroi, + uchar* dst, size_t dststep, Size dstroi, + int top, int left, int cn, int borderType ) +{ + const int isz = (int)sizeof(int); + int i, j, k, elemSize = 1; + bool intMode = false; + + if( (cn | srcstep | dststep | (size_t)src | (size_t)dst) % isz == 0 ) + { + cn /= isz; + elemSize = isz; + intMode = true; + } + + AutoBuffer _tab((dstroi.width - srcroi.width)*cn); + int* tab = _tab; + int right = dstroi.width - srcroi.width - left; + int bottom = dstroi.height - srcroi.height - top; + + for( i = 0; i < left; i++ ) + { + j = borderInterpolate(i - left, srcroi.width, borderType)*cn; + for( k = 0; k < cn; k++ ) + tab[i*cn + k] = j + k; + } + + for( i = 0; i < right; i++ ) + { + j = borderInterpolate(srcroi.width + i, srcroi.width, borderType)*cn; + for( k = 0; k < cn; k++ ) + tab[(i+left)*cn + k] = j + k; + } + + srcroi.width *= cn; + dstroi.width *= cn; + left *= cn; + right *= cn; + + uchar* dstInner = dst + dststep*top + left*elemSize; + + for( i = 0; i < srcroi.height; i++, dstInner += dststep, src += srcstep ) + { + if( dstInner != src ) + memcpy(dstInner, src, srcroi.width*elemSize); + + if( intMode ) + { + const int* isrc = (int*)src; + int* idstInner = (int*)dstInner; + for( j = 0; j < left; j++ ) + idstInner[j - left] = isrc[tab[j]]; + for( j = 0; j < right; j++ ) + idstInner[j + srcroi.width] = isrc[tab[j + left]]; + } + else + { + for( j = 0; j < left; j++ ) + dstInner[j - left] = src[tab[j]]; + for( j = 0; j < right; j++ ) + dstInner[j + srcroi.width] = src[tab[j + left]]; + } + } + + dstroi.width *= elemSize; + dst += dststep*top; + + for( i = 0; i < top; i++ ) + { + j = borderInterpolate(i - top, srcroi.height, borderType); + memcpy(dst + (i - top)*dststep, dst + j*dststep, dstroi.width); + } + + for( i = 0; i < bottom; i++ ) + { + j = borderInterpolate(i + srcroi.height, srcroi.height, borderType); + memcpy(dst + (i + srcroi.height)*dststep, dst + j*dststep, dstroi.width); + } +} + + +static void copyMakeConstBorder_8u( const uchar* src, size_t srcstep, Size srcroi, + uchar* dst, size_t dststep, Size dstroi, + int top, int left, int cn, const uchar* value ) +{ + int i, j; + AutoBuffer _constBuf(dstroi.width*cn); + uchar* constBuf = _constBuf; + int right = dstroi.width - srcroi.width - left; + int bottom = dstroi.height - srcroi.height - top; + + for( i = 0; i < dstroi.width; i++ ) + { + for( j = 0; j < cn; j++ ) + constBuf[i*cn + j] = value[j]; + } + + srcroi.width *= cn; + dstroi.width *= cn; + left *= cn; + right *= cn; + + uchar* dstInner = dst + dststep*top + left; + + for( i = 0; i < srcroi.height; i++, dstInner += dststep, src += srcstep ) + { + if( dstInner != src ) + memcpy( dstInner, src, srcroi.width ); + memcpy( dstInner - left, constBuf, left ); + memcpy( dstInner + srcroi.width, constBuf, right ); + } + + dst += dststep*top; + + for( i = 0; i < top; i++ ) + memcpy(dst + (i - top)*dststep, constBuf, dstroi.width); + + for( i = 0; i < bottom; i++ ) + memcpy(dst + (i + srcroi.height)*dststep, constBuf, dstroi.width); +} + +} + +void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom, + int left, int right, int borderType, const Scalar& value ) +{ + Mat src = _src.getMat(); + CV_Assert( top >= 0 && bottom >= 0 && left >= 0 && right >= 0 ); + + if( src.isSubmatrix() && (borderType & BORDER_ISOLATED) == 0 ) + { + Size wholeSize; + Point ofs; + src.locateROI(wholeSize, ofs); + int dtop = std::min(ofs.y, top); + int dbottom = std::min(wholeSize.height - src.rows - ofs.y, bottom); + int dleft = std::min(ofs.x, left); + int dright = std::min(wholeSize.width - src.cols - ofs.x, right); + src.adjustROI(dtop, dbottom, dleft, dright); + top -= dtop; + left -= dleft; + bottom -= dbottom; + right -= dright; + } + + _dst.create( src.rows + top + bottom, src.cols + left + right, src.type() ); + Mat dst = _dst.getMat(); + + if(top == 0 && left == 0 && bottom == 0 && right == 0) + { + if(src.data != dst.data || src.step != dst.step) + src.copyTo(dst); + return; + } + + borderType &= ~BORDER_ISOLATED; + + if( borderType != BORDER_CONSTANT ) + copyMakeBorder_8u( src.data, src.step, src.size(), + dst.data, dst.step, dst.size(), + top, left, (int)src.elemSize(), borderType ); + else + { + int cn = src.channels(), cn1 = cn; + AutoBuffer buf(cn); + if( cn > 4 ) + { + CV_Assert( value[0] == value[1] && value[0] == value[2] && value[0] == value[3] ); + cn1 = 1; + } + scalarToRawData(value, buf, CV_MAKETYPE(src.depth(), cn1), cn); + copyMakeConstBorder_8u( src.data, src.step, src.size(), + dst.data, dst.step, dst.size(), + top, left, (int)src.elemSize(), (uchar*)(double*)buf ); + } +} + + +double cv::PSNR(InputArray _src1, InputArray _src2) +{ + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + CV_Assert( src1.depth() == CV_8U ); + double diff = std::sqrt(norm(src1, src2, NORM_L2SQR)/(src1.total()*src1.channels())); + return 20*log10(255./(diff+DBL_EPSILON)); +} + + +CV_IMPL void +cvCopyMakeBorder( const CvArr* srcarr, CvArr* dstarr, CvPoint offset, + int borderType, CvScalar value ) +{ + cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); + int left = offset.x, right = dst.cols - src.cols - left; + int top = offset.y, bottom = dst.rows - src.rows - top; + + CV_Assert( dst.type() == src.type() ); + cv::copyMakeBorder( src, dst, top, bottom, left, right, borderType, value ); +} + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_approxpoly.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_approxpoly.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_approxpoly.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_approxpoly.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,359 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include + +using namespace cv; +using namespace std; + +// +// TODO!!!: +// check_slice (and/or check) seem(s) to be broken, or this is a bug in function +// (or its inability to handle possible self-intersections in the generated contours). +// +// At least, if // return TotalErrors; +// is uncommented in check_slice, the test fails easily. +// So, now (and it looks like since 0.9.6) +// we only check that the set of vertices of the approximated polygon is +// a subset of vertices of the original contour. +// + +class CV_ApproxPolyTest : public cvtest::BaseTest +{ +public: + CV_ApproxPolyTest(); + ~CV_ApproxPolyTest(); + void clear(); + //int write_default_params(CvFileStorage* fs); + +protected: + //int read_params( CvFileStorage* fs ); + + int check_slice( CvPoint StartPt, CvPoint EndPt, + CvSeqReader* SrcReader, float Eps, + int* j, int Count ); + int check( CvSeq* SrcSeq, CvSeq* DstSeq, float Eps ); + + bool get_contour( int /*type*/, CvSeq** Seq, int* d, + CvMemStorage* storage ); + + void run(int); +}; + + +CV_ApproxPolyTest::CV_ApproxPolyTest() +{ +} + + +CV_ApproxPolyTest::~CV_ApproxPolyTest() +{ + clear(); +} + + +void CV_ApproxPolyTest::clear() +{ + cvtest::BaseTest::clear(); +} + + +/*int CV_ApproxPolyTest::write_default_params( CvFileStorage* fs ) +{ + cvtest::BaseTest::write_default_params( fs ); + if( ts->get_testing_mode() != cvtest::TS::TIMING_MODE ) + { + write_param( fs, "test_case_count", test_case_count ); + } + return 0; +} + + +int CV_ApproxPolyTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::BaseTest::read_params( fs ); + if( code < 0 ) + return code; + + test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count ); + min_log_size = cvtest::clipInt( min_log_size, 1, 10 ); + return 0; +}*/ + + +bool CV_ApproxPolyTest::get_contour( int /*type*/, CvSeq** Seq, int* d, + CvMemStorage* storage ) +{ + RNG& rng = ts->get_rng(); + int max_x = INT_MIN, max_y = INT_MIN, min_x = INT_MAX, min_y = INT_MAX; + int i; + CvSeq* seq; + int total = cvtest::randInt(rng) % 1000 + 1; + CvPoint center; + int radius, angle; + double deg_to_rad = CV_PI/180.; + CvPoint pt; + + center.x = cvtest::randInt( rng ) % 1000; + center.y = cvtest::randInt( rng ) % 1000; + radius = cvtest::randInt( rng ) % 1000; + angle = cvtest::randInt( rng ) % 360; + + seq = cvCreateSeq( CV_SEQ_POLYGON, sizeof(CvContour), sizeof(CvPoint), storage ); + + for( i = 0; i < total; i++ ) + { + int d_radius = cvtest::randInt( rng ) % 10 - 5; + int d_angle = 360/total;//cvtest::randInt( rng ) % 10 - 5; + pt.x = cvRound( center.x + radius*cos(angle*deg_to_rad)); + pt.y = cvRound( center.x - radius*sin(angle*deg_to_rad)); + radius += d_radius; + angle += d_angle; + cvSeqPush( seq, &pt ); + + max_x = MAX( max_x, pt.x ); + max_y = MAX( max_y, pt.y ); + + min_x = MIN( min_x, pt.x ); + min_y = MIN( min_y, pt.y ); + } + + *d = (max_x - min_x)*(max_x - min_x) + (max_y - min_y)*(max_y - min_y); + *Seq = seq; + return true; +} + + +int CV_ApproxPolyTest::check_slice( CvPoint StartPt, CvPoint EndPt, + CvSeqReader* SrcReader, float Eps, + int* _j, int Count ) +{ + /////////// + CvPoint Pt; + /////////// + bool flag; + double dy,dx; + double A,B,C; + double Sq; + double sin_a = 0; + double cos_a = 0; + double d = 0; + double dist; + /////////// + int j, TotalErrors = 0; + + //////////////////////////////// + if( SrcReader == NULL ) + { + assert( false ); + return 0; + } + + ///////// init line //////////// + flag = true; + + dx = (double)StartPt.x - (double)EndPt.x; + dy = (double)StartPt.y - (double)EndPt.y; + + if( ( dx == 0 ) && ( dy == 0 ) ) flag = false; + else + { + A = -dy; + B = dx; + C = dy * (double)StartPt.x - dx * (double)StartPt.y; + Sq = sqrt( A*A + B*B ); + + sin_a = B/Sq; + cos_a = A/Sq; + d = C/Sq; + } + + /////// find start point and check distance //////// + for( j = *_j; j < Count; j++ ) + { + CV_READ_SEQ_ELEM( Pt, *SrcReader ); + if( StartPt.x == Pt.x && StartPt.y == Pt.y ) break; + else + { + if( flag ) dist = sin_a * Pt.y + cos_a * Pt.x - d; + else dist = sqrt( (double)(EndPt.y - Pt.y)*(EndPt.y - Pt.y) + (EndPt.x - Pt.x)*(EndPt.x - Pt.x) ); + if( dist > Eps ) TotalErrors++; + } + } + + *_j = j; + + //return TotalErrors; + return 0; +} + + +int CV_ApproxPolyTest::check( CvSeq* SrcSeq, CvSeq* DstSeq, float Eps ) +{ + ////////// + CvSeqReader DstReader; + CvSeqReader SrcReader; + CvPoint StartPt, EndPt; + /////////// + int TotalErrors = 0; + /////////// + int Count; + int i,j; + + assert( SrcSeq && DstSeq ); + + ////////// init //////////////////// + Count = SrcSeq->total; + + cvStartReadSeq( DstSeq, &DstReader, 0 ); + cvStartReadSeq( SrcSeq, &SrcReader, 0 ); + + CV_READ_SEQ_ELEM( StartPt, DstReader ); + for( i = 0 ; i < Count ; ) + { + CV_READ_SEQ_ELEM( EndPt, SrcReader ); + i++; + if( StartPt.x == EndPt.x && StartPt.y == EndPt.y ) break; + } + + ///////// start //////////////// + for( i = 1, j = 0 ; i <= DstSeq->total ; ) + { + ///////// read slice //////////// + EndPt.x = StartPt.x; + EndPt.y = StartPt.y; + CV_READ_SEQ_ELEM( StartPt, DstReader ); + i++; + + TotalErrors += check_slice( StartPt, EndPt, &SrcReader, Eps, &j, Count ); + + if( j > Count ) + { + TotalErrors++; + return TotalErrors; + } //if( !flag ) + + } // for( int i = 0 ; i < DstSeq->total ; i++ ) + + return TotalErrors; +} + + +//extern CvTestContourGenerator cvTsTestContours[]; + +void CV_ApproxPolyTest::run( int /*start_from*/ ) +{ + int code = cvtest::TS::OK; + CvMemStorage* storage = 0; + ////////////// Variables //////////////// + int IntervalsCount = 10; + /////////// + //CvTestContourGenerator Cont; + CvSeq* SrcSeq = NULL; + CvSeq* DstSeq; + int iDiam; + float dDiam, Eps, EpsStep; + + for( int i = 0; i < 30; i++ ) + { + CvMemStoragePos pos; + + ts->update_context( this, i, false ); + + ///////////////////// init contour ///////// + dDiam = 0; + while( sqrt(dDiam) / IntervalsCount == 0 ) + { + if( storage != 0 ) + cvReleaseMemStorage(&storage); + + storage = cvCreateMemStorage( 0 ); + if( get_contour( 0, &SrcSeq, &iDiam, storage ) ) + dDiam = (float)iDiam; + } + dDiam = (float)sqrt( dDiam ); + + storage = SrcSeq->storage; + + ////////////////// test ///////////// + EpsStep = dDiam / IntervalsCount ; + for( Eps = EpsStep ; Eps < dDiam ; Eps += EpsStep ) + { + cvSaveMemStoragePos( storage, &pos ); + + ////////// call function //////////// + DstSeq = cvApproxPoly( SrcSeq, SrcSeq->header_size, storage, + CV_POLY_APPROX_DP, Eps ); + + if( DstSeq == NULL ) + { + ts->printf( cvtest::TS::LOG, + "cvApproxPoly returned NULL for contour #%d, espilon = %g\n", i, Eps ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } // if( DstSeq == NULL ) + + code = check( SrcSeq, DstSeq, Eps ); + if( code != 0 ) + { + ts->printf( cvtest::TS::LOG, + "Incorrect result for the contour #%d approximated with epsilon=%g\n", i, Eps ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + cvRestoreMemStoragePos( storage, &pos ); + } // for( Eps = EpsStep ; Eps <= Diam ; Eps += EpsStep ) + + ///////////// free memory /////////////////// + cvReleaseMemStorage(&storage); + } // for( int i = 0; NULL != ( Cont = Contours[i] ) ; i++ ) + +_exit_: + cvReleaseMemStorage(&storage); + + if( code < 0 ) + ts->set_failed_test_info( code ); +} + +TEST(Imgproc_ApproxPoly, accuracy) { CV_ApproxPolyTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_bilateral_filter.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_bilateral_filter.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_bilateral_filter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_bilateral_filter.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,290 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; + +namespace cvtest +{ + class CV_BilateralFilterTest : + public cvtest::BaseTest + { + public: + enum + { + MAX_WIDTH = 1920, MIN_WIDTH = 1, + MAX_HEIGHT = 1080, MIN_HEIGHT = 1 + }; + + CV_BilateralFilterTest(); + ~CV_BilateralFilterTest(); + + protected: + virtual void run_func(); + virtual int prepare_test_case(int test_case_index); + virtual int validate_test_results(int test_case_index); + + private: + void reference_bilateral_filter(const Mat& src, Mat& dst, int d, double sigma_color, + double sigma_space, int borderType = BORDER_DEFAULT); + + int getRandInt(RNG& rng, int min_value, int max_value) const; + + double _sigma_color; + double _sigma_space; + + Mat _src; + Mat _parallel_dst; + int _d; + }; + + CV_BilateralFilterTest::CV_BilateralFilterTest() : + cvtest::BaseTest(), _src(), _parallel_dst(), _d() + { + test_case_count = 1000; + } + + CV_BilateralFilterTest::~CV_BilateralFilterTest() + { + } + + int CV_BilateralFilterTest::getRandInt(RNG& rng, int min_value, int max_value) const + { + double rand_value = rng.uniform(log((double)min_value), log((double)max_value + 1)); + return cvRound(exp((double)rand_value)); + } + + void CV_BilateralFilterTest::reference_bilateral_filter(const Mat &src, Mat &dst, int d, + double sigma_color, double sigma_space, int borderType) + { + int cn = src.channels(); + int i, j, k, maxk, radius; + double minValSrc = -1, maxValSrc = 1; + const int kExpNumBinsPerChannel = 1 << 12; + int kExpNumBins = 0; + float lastExpVal = 1.f; + float len, scale_index; + Size size = src.size(); + + dst.create(size, src.type()); + + CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) && + src.type() == dst.type() && src.size() == dst.size() && + src.data != dst.data ); + + if( sigma_color <= 0 ) + sigma_color = 1; + if( sigma_space <= 0 ) + sigma_space = 1; + + double gauss_color_coeff = -0.5/(sigma_color*sigma_color); + double gauss_space_coeff = -0.5/(sigma_space*sigma_space); + + if( d <= 0 ) + radius = cvRound(sigma_space*1.5); + else + radius = d/2; + radius = MAX(radius, 1); + d = radius*2 + 1; + // compute the min/max range for the input image (even if multichannel) + + minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc ); + if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON) + { + src.copyTo(dst); + return; + } + + // temporary copy of the image with borders for easy processing + Mat temp; + copyMakeBorder( src, temp, radius, radius, radius, radius, borderType ); + patchNaNs(temp); + + // allocate lookup tables + vector _space_weight(d*d); + vector _space_ofs(d*d); + float* space_weight = &_space_weight[0]; + int* space_ofs = &_space_ofs[0]; + + // assign a length which is slightly more than needed + len = (float)(maxValSrc - minValSrc) * cn; + kExpNumBins = kExpNumBinsPerChannel * cn; + vector _expLUT(kExpNumBins+2); + float* expLUT = &_expLUT[0]; + + scale_index = kExpNumBins/len; + + // initialize the exp LUT + for( i = 0; i < kExpNumBins+2; i++ ) + { + if( lastExpVal > 0.f ) + { + double val = i / scale_index; + expLUT[i] = (float)std::exp(val * val * gauss_color_coeff); + lastExpVal = expLUT[i]; + } + else + expLUT[i] = 0.f; + } + + // initialize space-related bilateral filter coefficients + for( i = -radius, maxk = 0; i <= radius; i++ ) + for( j = -radius; j <= radius; j++ ) + { + double r = std::sqrt((double)i*i + (double)j*j); + if( r > radius ) + continue; + space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); + space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn); + } + + for( i = 0; i < size.height; i++ ) + { + const float* sptr = (const float*)(temp.data + (i+radius)*temp.step) + radius*cn; + float* dptr = (float*)(dst.data + i*dst.step); + + if( cn == 1 ) + { + for( j = 0; j < size.width; j++ ) + { + float sum = 0, wsum = 0; + float val0 = sptr[j]; + for( k = 0; k < maxk; k++ ) + { + float val = sptr[j + space_ofs[k]]; + float alpha = (float)(std::abs(val - val0)*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum += val*w; + wsum += w; + } + dptr[j] = (float)(sum/wsum); + } + } + else + { + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) + { + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + for( k = 0; k < maxk; k++ ) + { + const float* sptr_k = sptr + j + space_ofs[k]; + float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float alpha = (float)((std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0))*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = sum_b*wsum; + g0 = sum_g*wsum; + r0 = sum_r*wsum; + dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0; + } + } + } + } + + int CV_BilateralFilterTest::prepare_test_case(int /* test_case_index */) + { + const static int types[] = { CV_32FC1, CV_32FC3, CV_8UC1, CV_8UC3 }; + RNG& rng = ts->get_rng(); + Size size(getRandInt(rng, MIN_WIDTH, MAX_WIDTH), getRandInt(rng, MIN_HEIGHT, MAX_HEIGHT)); + int type = types[rng(sizeof(types) / sizeof(types[0]))]; + + _d = rng.uniform(0., 1.) > 0.5 ? 5 : 3; + + _src.create(size, type); + + rng.fill(_src, RNG::UNIFORM, 0, 256); + + _sigma_color = _sigma_space = 1.; + + return 1; + } + + int CV_BilateralFilterTest::validate_test_results(int test_case_index) + { + static const double eps = 1; + + Mat reference_dst, reference_src; + if (_src.depth() == CV_32F) + reference_bilateral_filter(_src, reference_dst, _d, _sigma_color, _sigma_space); + else + { + int type = _src.type(); + _src.convertTo(reference_src, CV_32F); + reference_bilateral_filter(reference_src, reference_dst, _d, _sigma_color, _sigma_space); + reference_dst.convertTo(reference_dst, type); + } + + double e = norm(reference_dst, _parallel_dst); + if (e > eps) + { + ts->printf(cvtest::TS::CONSOLE, "actual error: %g, expected: %g", e, eps); + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + } + else + ts->set_failed_test_info(cvtest::TS::OK); + + return BaseTest::validate_test_results(test_case_index); + } + + void CV_BilateralFilterTest::run_func() + { + bilateralFilter(_src, _parallel_dst, _d, _sigma_color, _sigma_space); + } + + TEST(Imgproc_BilateralFilter, accuracy) + { + CV_BilateralFilterTest test; + test.safe_run(); + } + +} // end of namespace cvtest diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_boundingrect.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_boundingrect.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_boundingrect.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_boundingrect.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,144 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include + +#define IMGPROC_BOUNDINGRECT_ERROR_DIFF 1 + +#define MESSAGE_ERROR_DIFF "Bounding rectangle found by boundingRect function is incorrect." + +using namespace cv; +using namespace std; + +class CV_BoundingRectTest: public cvtest::ArrayTest +{ +public: + CV_BoundingRectTest(); + ~CV_BoundingRectTest(); + +protected: + void run (int); + +private: + template void generate_src_points(vector >& src, int n); + template cv::Rect get_bounding_rect(const vector > src); + template bool checking_function_work(vector >& src, int type); +}; + +CV_BoundingRectTest::CV_BoundingRectTest() {} +CV_BoundingRectTest::~CV_BoundingRectTest() {} + +template void CV_BoundingRectTest::generate_src_points(vector >& src, int n) +{ + src.clear(); + for (int i = 0; i < n; ++i) + src.push_back(Point_(cv::randu(), cv::randu())); +} + +template cv::Rect CV_BoundingRectTest::get_bounding_rect(const vector > src) +{ + int n = (int)src.size(); + T min_w = std::numeric_limits::max(), max_w = std::numeric_limits::min(); + T min_h = min_w, max_h = max_w; + + for (int i = 0; i < n; ++i) + { + min_w = std::min(src.at(i).x, min_w); + max_w = std::max(src.at(i).x, max_w); + min_h = std::min(src.at(i).y, min_h); + max_h = std::max(src.at(i).y, max_h); + } + + return Rect((int)min_w, (int)min_h, (int)max_w-(int)min_w + 1, (int)max_h-(int)min_h + 1); +} + +template bool CV_BoundingRectTest::checking_function_work(vector >& src, int type) +{ + const int MAX_COUNT_OF_POINTS = 1000; + const int N = 10000; + + for (int k = 0; k < N; ++k) + { + + RNG& rng = ts->get_rng(); + + int n = rng.next()%MAX_COUNT_OF_POINTS + 1; + + generate_src_points (src, n); + + cv::Rect right = get_bounding_rect (src); + + cv::Rect rect[2] = { boundingRect(src), boundingRect(Mat(src)) }; + + for (int i = 0; i < 2; ++i) if (rect[i] != right) + { + cout << endl; cout << "Checking for the work of boundingRect function..." << endl; + cout << "Type of src points: "; + switch (type) + { + case 0: {cout << "INT"; break;} + case 1: {cout << "FLOAT"; break;} + default: break; + } + cout << endl; + cout << "Src points are stored as "; if (i == 0) cout << "VECTOR" << endl; else cout << "MAT" << endl; + cout << "Number of points: " << n << endl; + cout << "Right rect (x, y, w, h): [" << right.x << ", " << right.y << ", " << right.width << ", " << right.height << "]" << endl; + cout << "Result rect (x, y, w, h): [" << rect[i].x << ", " << rect[i].y << ", " << rect[i].width << ", " << rect[i].height << "]" << endl; + cout << endl; + CV_Error(IMGPROC_BOUNDINGRECT_ERROR_DIFF, MESSAGE_ERROR_DIFF); + return false; + } + + } + + return true; +} + +void CV_BoundingRectTest::run(int) +{ + vector src_veci; if (!checking_function_work(src_veci, 0)) return; + vector src_vecf; checking_function_work(src_vecf, 1); +} + +TEST (Imgproc_BoundingRect, accuracy) { CV_BoundingRectTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_canny.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_canny.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_canny.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_canny.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,287 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_CannyTest : public cvtest::ArrayTest +{ +public: + CV_CannyTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + int prepare_test_case( int test_case_idx ); + void run_func(); + void prepare_to_validation( int ); + int validate_test_results( int /*test_case_idx*/ ); + + int aperture_size; + bool use_true_gradient; + double threshold1, threshold2; + bool test_cpp; +}; + + +CV_CannyTest::CV_CannyTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + element_wise_relative_error = true; + aperture_size = 0; + use_true_gradient = false; + threshold1 = threshold2 = 0; + + test_cpp = false; +} + + +void CV_CannyTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + double thresh_range; + + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_8U; + + aperture_size = cvtest::randInt(rng) % 2 ? 5 : 3; + thresh_range = aperture_size == 3 ? 300 : 1000; + + threshold1 = cvtest::randReal(rng)*thresh_range; + threshold2 = cvtest::randReal(rng)*thresh_range*0.3; + + if( cvtest::randInt(rng) % 2 ) + CV_SWAP( threshold1, threshold2, thresh_range ); + + use_true_gradient = cvtest::randInt(rng) % 2 != 0; + test_cpp = (cvtest::randInt(rng) & 256) == 0; +} + + +int CV_CannyTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + Mat& src = test_mat[INPUT][0]; + GaussianBlur(src, src, Size(11, 11), 5, 5); + } + + return code; +} + + +double CV_CannyTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 0; +} + + +void CV_CannyTest::run_func() +{ + if(!test_cpp) + cvCanny( test_array[INPUT][0], test_array[OUTPUT][0], threshold1, threshold2, + aperture_size + (use_true_gradient ? CV_CANNY_L2_GRADIENT : 0)); + else + { + cv::Mat _out = cv::cvarrToMat(test_array[OUTPUT][0]); + cv::Canny(cv::cvarrToMat(test_array[INPUT][0]), _out, threshold1, threshold2, + aperture_size + (use_true_gradient ? CV_CANNY_L2_GRADIENT : 0)); + } +} + + +static void +cannyFollow( int x, int y, float lowThreshold, const Mat& mag, Mat& dst ) +{ + static const int ofs[][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}}; + int i; + + dst.at(y, x) = (uchar)255; + + for( i = 0; i < 8; i++ ) + { + int x1 = x + ofs[i][0]; + int y1 = y + ofs[i][1]; + if( (unsigned)x1 < (unsigned)mag.cols && + (unsigned)y1 < (unsigned)mag.rows && + mag.at(y1, x1) > lowThreshold && + !dst.at(y1, x1) ) + cannyFollow( x1, y1, lowThreshold, mag, dst ); + } +} + + +static void +test_Canny( const Mat& src, Mat& dst, + double threshold1, double threshold2, + int aperture_size, bool use_true_gradient ) +{ + int m = aperture_size; + Point anchor(m/2, m/2); + const double tan_pi_8 = tan(CV_PI/8.); + const double tan_3pi_8 = tan(CV_PI*3/8); + float lowThreshold = (float)MIN(threshold1, threshold2); + float highThreshold = (float)MAX(threshold1, threshold2); + + int x, y, width = src.cols, height = src.rows; + + Mat dxkernel = cvtest::calcSobelKernel2D( 1, 0, m, 0 ); + Mat dykernel = cvtest::calcSobelKernel2D( 0, 1, m, 0 ); + Mat dx, dy, mag(height, width, CV_32F); + cvtest::filter2D(src, dx, CV_16S, dxkernel, anchor, 0, BORDER_REPLICATE); + cvtest::filter2D(src, dy, CV_16S, dykernel, anchor, 0, BORDER_REPLICATE); + + // calc gradient magnitude + for( y = 0; y < height; y++ ) + { + for( x = 0; x < width; x++ ) + { + int dxval = dx.at(y, x), dyval = dy.at(y, x); + mag.at(y, x) = use_true_gradient ? + (float)sqrt((double)(dxval*dxval + dyval*dyval)) : + (float)(fabs((double)dxval) + fabs((double)dyval)); + } + } + + // calc gradient direction, do nonmaxima suppression + for( y = 0; y < height; y++ ) + { + for( x = 0; x < width; x++ ) + { + + float a = mag.at(y, x), b = 0, c = 0; + int y1 = 0, y2 = 0, x1 = 0, x2 = 0; + + if( a <= lowThreshold ) + continue; + + int dxval = dx.at(y, x); + int dyval = dy.at(y, x); + + double tg = dxval ? (double)dyval/dxval : DBL_MAX*CV_SIGN(dyval); + + if( fabs(tg) < tan_pi_8 ) + { + y1 = y2 = y; x1 = x + 1; x2 = x - 1; + } + else if( tan_pi_8 <= tg && tg <= tan_3pi_8 ) + { + y1 = y + 1; y2 = y - 1; x1 = x + 1; x2 = x - 1; + } + else if( -tan_3pi_8 <= tg && tg <= -tan_pi_8 ) + { + y1 = y - 1; y2 = y + 1; x1 = x + 1; x2 = x - 1; + } + else + { + assert( fabs(tg) > tan_3pi_8 ); + x1 = x2 = x; y1 = y + 1; y2 = y - 1; + } + + if( (unsigned)y1 < (unsigned)height && (unsigned)x1 < (unsigned)width ) + b = (float)fabs(mag.at(y1, x1)); + + if( (unsigned)y2 < (unsigned)height && (unsigned)x2 < (unsigned)width ) + c = (float)fabs(mag.at(y2, x2)); + + if( (a > b || (a == b && ((x1 == x+1 && y1 == y) || (x1 == x && y1 == y+1)))) && a > c ) + ; + else + mag.at(y, x) = -a; + } + } + + dst = Scalar::all(0); + + // hysteresis threshold + for( y = 0; y < height; y++ ) + { + for( x = 0; x < width; x++ ) + if( mag.at(y, x) > highThreshold && !dst.at(y, x) ) + cannyFollow( x, y, lowThreshold, mag, dst ); + } +} + + +void CV_CannyTest::prepare_to_validation( int ) +{ + Mat src = test_mat[INPUT][0], dst = test_mat[REF_OUTPUT][0]; + test_Canny( src, dst, threshold1, threshold2, aperture_size, use_true_gradient ); +} + + +int CV_CannyTest::validate_test_results( int test_case_idx ) +{ + int code = cvtest::TS::OK, nz0; + prepare_to_validation(test_case_idx); + + double err = cvtest::norm(test_mat[OUTPUT][0], test_mat[REF_OUTPUT][0], CV_L1); + if( err == 0 ) + return code; + + if( err != cvRound(err) || cvRound(err)%255 != 0 ) + { + ts->printf( cvtest::TS::LOG, "Some of the pixels, produced by Canny, are not 0's or 255's; the difference is %g\n", err ); + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + return code; + } + + nz0 = cvRound(cvtest::norm(test_mat[REF_OUTPUT][0], CV_L1)/255); + err = (err/255/MAX(nz0,100))*100; + if( err > 1 ) + { + ts->printf( cvtest::TS::LOG, "Too high percentage of non-matching edge pixels = %g%%\n", err); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + } + + return code; +} + +TEST(Imgproc_Canny, accuracy) { CV_CannyTest test; test.safe_run(); } + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_color.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_color.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_color.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_color.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1953 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +/////////////////////////// base test class for color transformations ///////////////////////// + +class CV_ColorCvtBaseTest : public cvtest::ArrayTest +{ +public: + CV_ColorCvtBaseTest( bool custom_inv_transform, bool allow_32f, bool allow_16u ); + +protected: + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + + // input --- fwd_transform -> ref_output[0] + virtual void convert_forward( const Mat& src, Mat& dst ); + // ref_output[0] --- inv_transform ---> ref_output[1] (or input -- copy --> ref_output[1]) + virtual void convert_backward( const Mat& src, const Mat& dst, Mat& dst2 ); + + // called from default implementation of convert_forward + virtual void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + + // called from default implementation of convert_backward + virtual void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); + + const char* fwd_code_str; + const char* inv_code_str; + + void run_func(); + bool allow_16u, allow_32f; + int blue_idx; + bool inplace; + bool custom_inv_transform; + int fwd_code, inv_code; + bool test_cpp; + int hue_range; +}; + + +CV_ColorCvtBaseTest::CV_ColorCvtBaseTest( bool _custom_inv_transform, bool _allow_32f, bool _allow_16u ) +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + allow_16u = _allow_16u; + allow_32f = _allow_32f; + custom_inv_transform = _custom_inv_transform; + fwd_code = inv_code = -1; + element_wise_relative_error = false; + + fwd_code_str = inv_code_str = 0; + + test_cpp = false; + hue_range = 0; +} + + +void CV_ColorCvtBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + if( i == INPUT ) + { + int depth = CV_MAT_DEPTH(type); + low = Scalar::all(0.); + high = Scalar::all( depth == CV_8U ? 256 : depth == CV_16U ? 65536 : 1. ); + } +} + + +void CV_ColorCvtBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth, cn; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( allow_16u && allow_32f ) + { + depth = cvtest::randInt(rng) % 3; + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F; + } + else if( allow_16u || allow_32f ) + { + depth = cvtest::randInt(rng) % 2; + depth = depth == 0 ? CV_8U : allow_16u ? CV_16U : CV_32F; + } + else + depth = CV_8U; + + cn = (cvtest::randInt(rng) & 1) + 3; + blue_idx = cvtest::randInt(rng) & 1 ? 2 : 0; + + types[INPUT][0] = CV_MAKETYPE(depth, cn); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, 3); + if( test_array[OUTPUT].size() > 1 ) + types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_MAKETYPE(depth, cn); + + inplace = cn == 3 && cvtest::randInt(rng) % 2 != 0; + test_cpp = (cvtest::randInt(rng) & 256) == 0; +} + + +int CV_ColorCvtBaseTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 && inplace ) + cvtest::copy( test_mat[INPUT][0], test_mat[OUTPUT][0] ); + return code; +} + +void CV_ColorCvtBaseTest::run_func() +{ + CvArr* out0 = test_array[OUTPUT][0]; + cv::Mat _out0 = cv::cvarrToMat(out0), _out1 = cv::cvarrToMat(test_array[OUTPUT][1]); + + if(!test_cpp) + cvCvtColor( inplace ? out0 : test_array[INPUT][0], out0, fwd_code ); + else + cv::cvtColor( cv::cvarrToMat(inplace ? out0 : test_array[INPUT][0]), _out0, fwd_code, _out0.channels()); + + if( inplace ) + { + cvCopy( out0, test_array[OUTPUT][1] ); + out0 = test_array[OUTPUT][1]; + } + if(!test_cpp) + cvCvtColor( out0, test_array[OUTPUT][1], inv_code ); + else + cv::cvtColor(cv::cvarrToMat(out0), _out1, inv_code, _out1.channels()); +} + + +void CV_ColorCvtBaseTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + convert_forward( test_mat[INPUT][0], test_mat[REF_OUTPUT][0] ); + convert_backward( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], + test_mat[REF_OUTPUT][1] ); + int depth = test_mat[REF_OUTPUT][0].depth(); + if( depth == CV_8U && hue_range ) + { + for( int y = 0; y < test_mat[REF_OUTPUT][0].rows; y++ ) + { + uchar* h0 = test_mat[REF_OUTPUT][0].ptr(y); + uchar* h = test_mat[OUTPUT][0].ptr(y); + + for( int x = 0; x < test_mat[REF_OUTPUT][0].cols; x++, h0 += 3, h += 3 ) + { + if( abs(*h - *h0) >= hue_range-1 && (*h <= 1 || *h0 <= 1) ) + *h = *h0 = 0; + } + } + } +} + + +void CV_ColorCvtBaseTest::convert_forward( const Mat& src, Mat& dst ) +{ + const float c8u = 0.0039215686274509803f; // 1./255 + const float c16u = 1.5259021896696422e-005f; // 1./65535 + int depth = src.depth(); + int cn = src.channels(), dst_cn = dst.channels(); + int cols = src.cols, dst_cols_n = dst.cols*dst_cn; + vector _src_buf(src.cols*3); + vector _dst_buf(dst.cols*3); + float* src_buf = &_src_buf[0]; + float* dst_buf = &_dst_buf[0]; + int i, j; + + assert( (cn == 3 || cn == 4) && (dst_cn == 3 || dst_cn == 1) ); + + for( i = 0; i < src.rows; i++ ) + { + switch( depth ) + { + case CV_8U: + { + const uchar* src_row = src.ptr(i); + uchar* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + src_buf[j*3] = src_row[j*cn + blue_idx]*c8u; + src_buf[j*3+1] = src_row[j*cn + 1]*c8u; + src_buf[j*3+2] = src_row[j*cn + (blue_idx^2)]*c8u; + } + + convert_row_bgr2abc_32f_c3( src_buf, dst_buf, cols ); + + for( j = 0; j < dst_cols_n; j++ ) + { + int t = cvRound( dst_buf[j] ); + dst_row[j] = saturate_cast(t); + } + } + break; + case CV_16U: + { + const ushort* src_row = src.ptr(i); + ushort* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + src_buf[j*3] = src_row[j*cn + blue_idx]*c16u; + src_buf[j*3+1] = src_row[j*cn + 1]*c16u; + src_buf[j*3+2] = src_row[j*cn + (blue_idx^2)]*c16u; + } + + convert_row_bgr2abc_32f_c3( src_buf, dst_buf, cols ); + + for( j = 0; j < dst_cols_n; j++ ) + { + int t = cvRound( dst_buf[j] ); + dst_row[j] = saturate_cast(t); + } + } + break; + case CV_32F: + { + const float* src_row = src.ptr(i); + float* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + src_buf[j*3] = src_row[j*cn + blue_idx]; + src_buf[j*3+1] = src_row[j*cn + 1]; + src_buf[j*3+2] = src_row[j*cn + (blue_idx^2)]; + } + + convert_row_bgr2abc_32f_c3( src_buf, dst_row, cols ); + } + break; + default: + assert(0); + } + } +} + + +void CV_ColorCvtBaseTest::convert_row_bgr2abc_32f_c3( const float* /*src_row*/, + float* /*dst_row*/, int /*n*/ ) +{ +} + + +void CV_ColorCvtBaseTest::convert_row_abc2bgr_32f_c3( const float* /*src_row*/, + float* /*dst_row*/, int /*n*/ ) +{ +} + + +void CV_ColorCvtBaseTest::convert_backward( const Mat& src, const Mat& dst, Mat& dst2 ) +{ + if( custom_inv_transform ) + { + int depth = src.depth(); + int src_cn = dst.channels(), cn = dst2.channels(); + int cols_n = src.cols*src_cn, dst_cols = dst.cols; + vector _src_buf(src.cols*3); + vector _dst_buf(dst.cols*3); + float* src_buf = &_src_buf[0]; + float* dst_buf = &_dst_buf[0]; + int i, j; + + assert( cn == 3 || cn == 4 ); + + for( i = 0; i < src.rows; i++ ) + { + switch( depth ) + { + case CV_8U: + { + const uchar* src_row = dst.ptr(i); + uchar* dst_row = dst2.ptr(i); + + for( j = 0; j < cols_n; j++ ) + src_buf[j] = src_row[j]; + + convert_row_abc2bgr_32f_c3( src_buf, dst_buf, dst_cols ); + + for( j = 0; j < dst_cols; j++ ) + { + int b = cvRound( dst_buf[j*3]*255. ); + int g = cvRound( dst_buf[j*3+1]*255. ); + int r = cvRound( dst_buf[j*3+2]*255. ); + dst_row[j*cn + blue_idx] = saturate_cast(b); + dst_row[j*cn + 1] = saturate_cast(g); + dst_row[j*cn + (blue_idx^2)] = saturate_cast(r); + if( cn == 4 ) + dst_row[j*cn + 3] = 255; + } + } + break; + case CV_16U: + { + const ushort* src_row = dst.ptr(i); + ushort* dst_row = dst2.ptr(i); + + for( j = 0; j < cols_n; j++ ) + src_buf[j] = src_row[j]; + + convert_row_abc2bgr_32f_c3( src_buf, dst_buf, dst_cols ); + + for( j = 0; j < dst_cols; j++ ) + { + int b = cvRound( dst_buf[j*3]*65535. ); + int g = cvRound( dst_buf[j*3+1]*65535. ); + int r = cvRound( dst_buf[j*3+2]*65535. ); + dst_row[j*cn + blue_idx] = saturate_cast(b); + dst_row[j*cn + 1] = saturate_cast(g); + dst_row[j*cn + (blue_idx^2)] = saturate_cast(r); + if( cn == 4 ) + dst_row[j*cn + 3] = 65535; + } + } + break; + case CV_32F: + { + const float* src_row = dst.ptr(i); + float* dst_row = dst2.ptr(i); + + convert_row_abc2bgr_32f_c3( src_row, dst_buf, dst_cols ); + + for( j = 0; j < dst_cols; j++ ) + { + float b = dst_buf[j*3]; + float g = dst_buf[j*3+1]; + float r = dst_buf[j*3+2]; + dst_row[j*cn + blue_idx] = b; + dst_row[j*cn + 1] = g; + dst_row[j*cn + (blue_idx^2)] = r; + if( cn == 4 ) + dst_row[j*cn + 3] = 1.f; + } + } + break; + default: + assert(0); + } + } + } + else + { + int i, j, k; + int elem_size = (int)src.elemSize(), elem_size1 = (int)src.elemSize1(); + int width_n = src.cols*elem_size; + + for( i = 0; i < src.rows; i++ ) + { + memcpy( dst2.ptr(i), src.ptr(i), width_n ); + if( src.channels() == 4 ) + { + // clear the alpha channel + uchar* ptr = dst2.ptr(i) + elem_size1*3; + for( j = 0; j < width_n; j += elem_size ) + { + for( k = 0; k < elem_size1; k++ ) + ptr[j + k] = 0; + } + } + } + } +} + + +#undef INIT_FWD_INV_CODES +#define INIT_FWD_INV_CODES( fwd, inv ) \ + fwd_code = CV_##fwd; inv_code = CV_##inv; \ + fwd_code_str = #fwd; inv_code_str = #inv + +//// rgb <=> gray +class CV_ColorGrayTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorGrayTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_ColorGrayTest::CV_ColorGrayTest() : CV_ColorCvtBaseTest( true, true, true ) +{ + INIT_FWD_INV_CODES( BGR2GRAY, GRAY2BGR ); +} + + +void CV_ColorGrayTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int cn = CV_MAT_CN(types[INPUT][0]); + types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][0] & CV_MAT_DEPTH_MASK; + inplace = false; + + if( cn == 3 ) + { + if( blue_idx == 0 ) + fwd_code = CV_BGR2GRAY, inv_code = CV_GRAY2BGR; + else + fwd_code = CV_RGB2GRAY, inv_code = CV_GRAY2RGB; + } + else + { + if( blue_idx == 0 ) + fwd_code = CV_BGRA2GRAY, inv_code = CV_GRAY2BGRA; + else + fwd_code = CV_RGBA2GRAY, inv_code = CV_GRAY2RGBA; + } +} + + +double CV_ColorGrayTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? 2 : depth == CV_16U ? 16 : 1e-5; +} + + +void CV_ColorGrayTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + double scale = depth == CV_8U ? 255 : depth == CV_16U ? 65535 : 1; + double cr = 0.299*scale; + double cg = 0.587*scale; + double cb = 0.114*scale; + int j; + + for( j = 0; j < n; j++ ) + dst_row[j] = (float)(src_row[j*3]*cb + src_row[j*3+1]*cg + src_row[j*3+2]*cr); +} + + +void CV_ColorGrayTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int j, depth = test_mat[INPUT][0].depth(); + float scale = depth == CV_8U ? (1.f/255) : depth == CV_16U ? 1.f/65535 : 1.f; + for( j = 0; j < n; j++ ) + dst_row[j*3] = dst_row[j*3+1] = dst_row[j*3+2] = src_row[j]*scale; +} + + +//// rgb <=> ycrcb +class CV_ColorYCrCbTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorYCrCbTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorYCrCbTest::CV_ColorYCrCbTest() : CV_ColorCvtBaseTest( true, true, true ) +{ + INIT_FWD_INV_CODES( BGR2YCrCb, YCrCb2BGR ); +} + + +void CV_ColorYCrCbTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( blue_idx == 0 ) + fwd_code = CV_BGR2YCrCb, inv_code = CV_YCrCb2BGR; + else + fwd_code = CV_RGB2YCrCb, inv_code = CV_YCrCb2RGB; +} + + +double CV_ColorYCrCbTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? 2 : depth == CV_16U ? 32 : 1e-3; +} + + +void CV_ColorYCrCbTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + double scale = depth == CV_8U ? 255 : depth == CV_16U ? 65535 : 1; + double bias = depth == CV_8U ? 128 : depth == CV_16U ? 32768 : 0.5; + + double M[] = { 0.299, 0.587, 0.114, + 0.49981, -0.41853, -0.08128, + -0.16864, -0.33107, 0.49970 }; + int j; + for( j = 0; j < 9; j++ ) + M[j] *= scale; + + for( j = 0; j < n*3; j += 3 ) + { + double r = src_row[j+2]; + double g = src_row[j+1]; + double b = src_row[j]; + double y = M[0]*r + M[1]*g + M[2]*b; + double cr = M[3]*r + M[4]*g + M[5]*b + bias; + double cb = M[6]*r + M[7]*g + M[8]*b + bias; + dst_row[j] = (float)y; + dst_row[j+1] = (float)cr; + dst_row[j+2] = (float)cb; + } +} + + +void CV_ColorYCrCbTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + double bias = depth == CV_8U ? 128 : depth == CV_16U ? 32768 : 0.5; + double scale = depth == CV_8U ? 1./255 : depth == CV_16U ? 1./65535 : 1; + double M[] = { 1, 1.40252, 0, + 1, -0.71440, -0.34434, + 1, 0, 1.77305 }; + int j; + for( j = 0; j < 9; j++ ) + M[j] *= scale; + + for( j = 0; j < n*3; j += 3 ) + { + double y = src_row[j]; + double cr = src_row[j+1] - bias; + double cb = src_row[j+2] - bias; + double r = M[0]*y + M[1]*cr + M[2]*cb; + double g = M[3]*y + M[4]*cr + M[5]*cb; + double b = M[6]*y + M[7]*cr + M[8]*cb; + dst_row[j] = (float)b; + dst_row[j+1] = (float)g; + dst_row[j+2] = (float)r; + } +} + + +//// rgb <=> hsv +class CV_ColorHSVTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorHSVTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorHSVTest::CV_ColorHSVTest() : CV_ColorCvtBaseTest( true, true, false ) +{ + INIT_FWD_INV_CODES( BGR2HSV, HSV2BGR ); + hue_range = 180; +} + + +void CV_ColorHSVTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + RNG& rng = ts->get_rng(); + + bool full_hrange = (rng.next() & 256) != 0; + if( full_hrange ) + { + if( blue_idx == 0 ) + fwd_code = CV_BGR2HSV_FULL, inv_code = CV_HSV2BGR_FULL; + else + fwd_code = CV_RGB2HSV_FULL, inv_code = CV_HSV2RGB_FULL; + hue_range = 256; + } + else + { + if( blue_idx == 0 ) + fwd_code = CV_BGR2HSV, inv_code = CV_HSV2BGR; + else + fwd_code = CV_RGB2HSV, inv_code = CV_HSV2RGB; + hue_range = 180; + } +} + + +double CV_ColorHSVTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? (j == 0 ? 4 : 16) : depth == CV_16U ? 32 : 1e-3; +} + + +void CV_ColorHSVTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float h_scale = depth == CV_8U ? hue_range*30.f/180 : 60.f; + float scale = depth == CV_8U ? 255.f : depth == CV_16U ? 65535.f : 1.f; + int j; + + for( j = 0; j < n*3; j += 3 ) + { + float r = src_row[j+2]; + float g = src_row[j+1]; + float b = src_row[j]; + float vmin = MIN(r,g); + float v = MAX(r,g); + float s, h, diff; + vmin = MIN(vmin,b); + v = MAX(v,b); + diff = v - vmin; + if( diff == 0 ) + s = h = 0; + else + { + s = diff/(v + FLT_EPSILON); + diff = 1.f/diff; + + h = r == v ? (g - b)*diff : + g == v ? 2 + (b - r)*diff : 4 + (r - g)*diff; + + if( h < 0 ) + h += 6; + } + + dst_row[j] = h*h_scale; + dst_row[j+1] = s*scale; + dst_row[j+2] = v*scale; + } +} + +// taken from http://www.cs.rit.edu/~ncs/color/t_convert.html +void CV_ColorHSVTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float h_scale = depth == CV_8U ? 180/(hue_range*30.f) : 1.f/60; + float scale = depth == CV_8U ? 1.f/255 : depth == CV_16U ? 1.f/65535 : 1; + int j; + + for( j = 0; j < n*3; j += 3 ) + { + float h = src_row[j]*h_scale; + float s = src_row[j+1]*scale; + float v = src_row[j+2]*scale; + float r = v, g = v, b = v; + + if( h < 0 ) + h += 6; + else if( h >= 6 ) + h -= 6; + + if( s != 0 ) + { + int i = cvFloor(h); + float f = h - i; + float p = v*(1 - s); + float q = v*(1 - s*f); + float t = v*(1 - s*(1 - f)); + + if( i == 0 ) + r = v, g = t, b = p; + else if( i == 1 ) + r = q, g = v, b = p; + else if( i == 2 ) + r = p, g = v, b = t; + else if( i == 3 ) + r = p, g = q, b = v; + else if( i == 4 ) + r = t, g = p, b = v; + else + r = v, g = p, b = q; + } + + dst_row[j] = b; + dst_row[j+1] = g; + dst_row[j+2] = r; + } +} + + +//// rgb <=> hls +class CV_ColorHLSTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorHLSTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorHLSTest::CV_ColorHLSTest() : CV_ColorCvtBaseTest( true, true, false ) +{ + INIT_FWD_INV_CODES( BGR2HLS, HLS2BGR ); + hue_range = 180; +} + + +void CV_ColorHLSTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( blue_idx == 0 ) + fwd_code = CV_BGR2HLS, inv_code = CV_HLS2BGR; + else + fwd_code = CV_RGB2HLS, inv_code = CV_HLS2RGB; +} + + +double CV_ColorHLSTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? (j == 0 ? 4 : 16) : depth == CV_16U ? 32 : 1e-4; +} + + +void CV_ColorHLSTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float h_scale = depth == CV_8U ? 30.f : 60.f; + float scale = depth == CV_8U ? 255.f : depth == CV_16U ? 65535.f : 1.f; + int j; + + for( j = 0; j < n*3; j += 3 ) + { + float r = src_row[j+2]; + float g = src_row[j+1]; + float b = src_row[j]; + float vmin = MIN(r,g); + float v = MAX(r,g); + float s, h, l, diff; + vmin = MIN(vmin,b); + v = MAX(v,b); + diff = v - vmin; + + if( diff == 0 ) + s = h = 0, l = v; + else + { + l = (v + vmin)*0.5f; + s = l <= 0.5f ? diff / (v + vmin) : diff / (2 - v - vmin); + diff = 1.f/diff; + + h = r == v ? (g - b)*diff : + g == v ? 2 + (b - r)*diff : 4 + (r - g)*diff; + + if( h < 0 ) + h += 6; + } + + dst_row[j] = h*h_scale; + dst_row[j+1] = l*scale; + dst_row[j+2] = s*scale; + } +} + + +void CV_ColorHLSTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float h_scale = depth == CV_8U ? 1.f/30 : 1.f/60; + float scale = depth == CV_8U ? 1.f/255 : depth == CV_16U ? 1.f/65535 : 1; + int j; + + for( j = 0; j < n*3; j += 3 ) + { + float h = src_row[j]*h_scale; + float l = src_row[j+1]*scale; + float s = src_row[j+2]*scale; + float r = l, g = l, b = l; + + if( h < 0 ) + h += 6; + else if( h >= 6 ) + h -= 6; + + if( s != 0 ) + { + float m2 = l <= 0.5f ? l*(1.f + s) : l + s - l*s; + float m1 = 2*l - m2; + float h1 = h + 2; + + if( h1 >= 6 ) + h1 -= 6; + if( h1 < 1 ) + r = m1 + (m2 - m1)*h1; + else if( h1 < 3 ) + r = m2; + else if( h1 < 4 ) + r = m1 + (m2 - m1)*(4 - h1); + else + r = m1; + + h1 = h; + + if( h1 < 1 ) + g = m1 + (m2 - m1)*h1; + else if( h1 < 3 ) + g = m2; + else if( h1 < 4 ) + g = m1 + (m2 - m1)*(4 - h1); + else + g = m1; + + h1 = h - 2; + if( h1 < 0 ) + h1 += 6; + + if( h1 < 1 ) + b = m1 + (m2 - m1)*h1; + else if( h1 < 3 ) + b = m2; + else if( h1 < 4 ) + b = m1 + (m2 - m1)*(4 - h1); + else + b = m1; + } + + dst_row[j] = b; + dst_row[j+1] = g; + dst_row[j+2] = r; + } +} + + +static const double RGB2XYZ[] = +{ + 0.412453, 0.357580, 0.180423, + 0.212671, 0.715160, 0.072169, + 0.019334, 0.119193, 0.950227 +}; + + +static const double XYZ2RGB[] = +{ + 3.240479, -1.53715, -0.498535, + -0.969256, 1.875991, 0.041556, + 0.055648, -0.204043, 1.057311 +}; + +static const float Xn = 0.950456f; +static const float Zn = 1.088754f; + + +//// rgb <=> xyz +class CV_ColorXYZTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorXYZTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorXYZTest::CV_ColorXYZTest() : CV_ColorCvtBaseTest( true, true, true ) +{ + INIT_FWD_INV_CODES( BGR2XYZ, XYZ2BGR ); +} + + +void CV_ColorXYZTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( blue_idx == 0 ) + fwd_code = CV_BGR2XYZ, inv_code = CV_XYZ2BGR; + else + fwd_code = CV_RGB2XYZ, inv_code = CV_XYZ2RGB; +} + + +double CV_ColorXYZTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? (j == 0 ? 2 : 8) : depth == CV_16U ? (j == 0 ? 64 : 128) : 1e-1; +} + + +void CV_ColorXYZTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + double scale = depth == CV_8U ? 255 : depth == CV_16U ? 65535 : 1; + + double M[9]; + int j; + for( j = 0; j < 9; j++ ) + M[j] = RGB2XYZ[j]*scale; + + for( j = 0; j < n*3; j += 3 ) + { + double r = src_row[j+2]; + double g = src_row[j+1]; + double b = src_row[j]; + double x = M[0]*r + M[1]*g + M[2]*b; + double y = M[3]*r + M[4]*g + M[5]*b; + double z = M[6]*r + M[7]*g + M[8]*b; + dst_row[j] = (float)x; + dst_row[j+1] = (float)y; + dst_row[j+2] = (float)z; + } +} + + +void CV_ColorXYZTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + double scale = depth == CV_8U ? 1./255 : depth == CV_16U ? 1./65535 : 1; + + double M[9]; + int j; + for( j = 0; j < 9; j++ ) + M[j] = XYZ2RGB[j]*scale; + + for( j = 0; j < n*3; j += 3 ) + { + double x = src_row[j]; + double y = src_row[j+1]; + double z = src_row[j+2]; + double r = M[0]*x + M[1]*y + M[2]*z; + double g = M[3]*x + M[4]*y + M[5]*z; + double b = M[6]*x + M[7]*y + M[8]*z; + dst_row[j] = (float)b; + dst_row[j+1] = (float)g; + dst_row[j+2] = (float)r; + } +} + + +//// rgb <=> L*a*b* +class CV_ColorLabTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorLabTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorLabTest::CV_ColorLabTest() : CV_ColorCvtBaseTest( true, true, false ) +{ + INIT_FWD_INV_CODES( BGR2Lab, Lab2BGR ); +} + + +void CV_ColorLabTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( blue_idx == 0 ) + fwd_code = CV_LBGR2Lab, inv_code = CV_Lab2LBGR; + else + fwd_code = CV_LRGB2Lab, inv_code = CV_Lab2LRGB; +} + + +double CV_ColorLabTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 32 : 1e-3; +} + + +static const double _1_3 = 0.333333333333; +const static float _1_3f = static_cast(_1_3); + + +void CV_ColorLabTest::convert_row_bgr2abc_32f_c3(const float* src_row, float* dst_row, int n) +{ + int depth = test_mat[INPUT][0].depth(); + float Lscale = depth == CV_8U ? 255.f/100.f : depth == CV_16U ? 65535.f/100.f : 1.f; + float ab_bias = depth == CV_8U ? 128.f : depth == CV_16U ? 32768.f : 0.f; + float M[9]; + + for (int j = 0; j < 9; j++ ) + M[j] = (float)RGB2XYZ[j]; + + for (int x = 0; x < n*3; x += 3) + { + float R = src_row[x + 2]; + float G = src_row[x + 1]; + float B = src_row[x]; + + float X = (R * M[0] + G * M[1] + B * M[2]) / Xn; + float Y = R * M[3] + G * M[4] + B * M[5]; + float Z = (R * M[6] + G * M[7] + B * M[8]) / Zn; + float fX = X > 0.008856f ? pow(X, _1_3f) : + (7.787f * X + 16.f / 116.f); + float fZ = Z > 0.008856f ? pow(Z, _1_3f): + (7.787f * Z + 16.f / 116.f); + + float L = 0.0f, fY = 0.0f; + if (Y > 0.008856f) + { + fY = pow(Y, _1_3f); + L = 116.f * fY - 16.f; + } + else + { + fY = 7.787f * Y + 16.f / 116.f; + L = 903.3f * Y; + } + + float a = 500.f * (fX - fY); + float b = 200.f * (fY - fZ); + + dst_row[x] = L * Lscale; + dst_row[x + 1] = a + ab_bias; + dst_row[x + 2] = b + ab_bias; + } +} + +void CV_ColorLabTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float Lscale = depth == CV_8U ? 100.f/255.f : depth == CV_16U ? 100.f/65535.f : 1.f; + float ab_bias = depth == CV_8U ? 128.f : depth == CV_16U ? 32768.f : 0.f; + float M[9]; + + for(int j = 0; j < 9; j++ ) + M[j] = (float)XYZ2RGB[j]; + + static const float lthresh = 903.3f * 0.008856f; + static const float thresh = 7.787f * 0.008856f + 16.0f / 116.0f; + for (int x = 0, end = n * 3; x < end; x += 3) + { + float L = src_row[x] * Lscale; + float a = src_row[x + 1] - ab_bias; + float b = src_row[x + 2] - ab_bias; + + float FY = 0.0f, Y = 0.0f; + if (L <= lthresh) + { + Y = L / 903.3f; + FY = 7.787f * Y + 16.0f / 116.0f; + } + else + { + FY = (L + 16.0f) / 116.0f; + Y = FY * FY * FY; + } + + float FX = a / 500.0f + FY; + float FZ = FY - b / 200.0f; + + float FXZ[] = { FX, FZ }; + for (int k = 0; k < 2; ++k) + { + if (FXZ[k] <= thresh) + FXZ[k] = (FXZ[k] - 16.0f / 116.0f) / 7.787f; + else + FXZ[k] = FXZ[k] * FXZ[k] * FXZ[k]; + } + float X = FXZ[0] * Xn; + float Z = FXZ[1] * Zn; + + float R = M[0] * X + M[1] * Y + M[2] * Z; + float G = M[3] * X + M[4] * Y + M[5] * Z; + float B = M[6] * X + M[7] * Y + M[8] * Z; + + dst_row[x] = B; + dst_row[x + 1] = G; + dst_row[x + 2] = R; + } +} + + +//// rgb <=> L*u*v* +class CV_ColorLuvTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorLuvTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ); + void convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ); +}; + + +CV_ColorLuvTest::CV_ColorLuvTest() : CV_ColorCvtBaseTest( true, true, false ) +{ + INIT_FWD_INV_CODES( BGR2Luv, Luv2BGR ); +} + + +void CV_ColorLuvTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + if( blue_idx == 0 ) + fwd_code = CV_LBGR2Luv, inv_code = CV_Luv2LBGR; + else + fwd_code = CV_LRGB2Luv, inv_code = CV_Luv2LRGB; +} + + +double CV_ColorLuvTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_8U ? 48 : depth == CV_16U ? 32 : 5e-2; +} + + +void CV_ColorLuvTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float Lscale = depth == CV_8U ? 255.f/100.f : depth == CV_16U ? 65535.f/100.f : 1.f; + int j; + + float M[9]; + float un = 4.f*Xn/(Xn + 15.f*1.f + 3*Zn); + float vn = 9.f*1.f/(Xn + 15.f*1.f + 3*Zn); + float u_scale = 1.f, u_bias = 0.f; + float v_scale = 1.f, v_bias = 0.f; + + for( j = 0; j < 9; j++ ) + M[j] = (float)RGB2XYZ[j]; + + if( depth == CV_8U ) + { + u_scale = 0.720338983f; + u_bias = 96.5254237f; + v_scale = 0.99609375f; + v_bias = 139.453125f; + } + + for( j = 0; j < n*3; j += 3 ) + { + float r = src_row[j+2]; + float g = src_row[j+1]; + float b = src_row[j]; + + float X = r*M[0] + g*M[1] + b*M[2]; + float Y = r*M[3] + g*M[4] + b*M[5]; + float Z = r*M[6] + g*M[7] + b*M[8]; + float d = X + 15*Y + 3*Z, L, u, v; + + if( d == 0 ) + L = u = v = 0; + else + { + if( Y > 0.008856f ) + L = (float)(116.*pow((double)Y,_1_3) - 16.); + else + L = 903.3f * Y; + + d = 1.f/d; + u = 13*L*(4*X*d - un); + v = 13*L*(9*Y*d - vn); + } + dst_row[j] = L*Lscale; + dst_row[j+1] = u*u_scale + u_bias; + dst_row[j+2] = v*v_scale + v_bias; + } +} + + +void CV_ColorLuvTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n ) +{ + int depth = test_mat[INPUT][0].depth(); + float Lscale = depth == CV_8U ? 100.f/255.f : depth == CV_16U ? 100.f/65535.f : 1.f; + int j; + float M[9]; + float un = 4.f*Xn/(Xn + 15.f*1.f + 3*Zn); + float vn = 9.f*1.f/(Xn + 15.f*1.f + 3*Zn); + float u_scale = 1.f, u_bias = 0.f; + float v_scale = 1.f, v_bias = 0.f; + + for( j = 0; j < 9; j++ ) + M[j] = (float)XYZ2RGB[j]; + + if( depth == CV_8U ) + { + u_scale = 1.f/0.720338983f; + u_bias = 96.5254237f; + v_scale = 1.f/0.99609375f; + v_bias = 139.453125f; + } + + for( j = 0; j < n*3; j += 3 ) + { + float L = src_row[j]*Lscale; + float u = (src_row[j+1] - u_bias)*u_scale; + float v = (src_row[j+2] - v_bias)*v_scale; + float X, Y, Z; + + if( L >= 8 ) + { + Y = (L + 16.f)*(1.f/116.f); + Y = Y*Y*Y; + } + else + { + Y = L * (1.f/903.3f); + if( L == 0 ) + L = 0.001f; + } + + u = u/(13*L) + un; + v = v/(13*L) + vn; + + X = -9*Y*u/((u - 4)*v - u*v); + Z = (9*Y - 15*v*Y - v*X)/(3*v); + + float r = M[0]*X + M[1]*Y + M[2]*Z; + float g = M[3]*X + M[4]*Y + M[5]*Z; + float b = M[6]*X + M[7]*Y + M[8]*Z; + + dst_row[j] = b; + dst_row[j+1] = g; + dst_row[j+2] = r; + } +} + + +//// rgb <=> another rgb +class CV_ColorRGBTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorRGBTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void convert_forward( const Mat& src, Mat& dst ); + void convert_backward( const Mat& src, const Mat& dst, Mat& dst2 ); + int dst_bits; +}; + + +CV_ColorRGBTest::CV_ColorRGBTest() : CV_ColorCvtBaseTest( true, true, true ) +{ + dst_bits = 0; +} + + +void CV_ColorRGBTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int cn = CV_MAT_CN(types[INPUT][0]); + + dst_bits = 24; + + if( cvtest::randInt(rng) % 3 == 0 ) + { + types[INPUT][0] = types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_MAKETYPE(CV_8U,cn); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(CV_8U,2); + if( cvtest::randInt(rng) & 1 ) + { + if( blue_idx == 0 ) + fwd_code = CV_BGR2BGR565, inv_code = CV_BGR5652BGR; + else + fwd_code = CV_RGB2BGR565, inv_code = CV_BGR5652RGB; + dst_bits = 16; + } + else + { + if( blue_idx == 0 ) + fwd_code = CV_BGR2BGR555, inv_code = CV_BGR5552BGR; + else + fwd_code = CV_RGB2BGR555, inv_code = CV_BGR5552RGB; + dst_bits = 15; + } + } + else + { + if( cn == 3 ) + { + fwd_code = CV_RGB2BGR, inv_code = CV_BGR2RGB; + blue_idx = 2; + } + else if( blue_idx == 0 ) + fwd_code = CV_BGRA2BGR, inv_code = CV_BGR2BGRA; + else + fwd_code = CV_RGBA2BGR, inv_code = CV_BGR2RGBA; + } + + if( CV_MAT_CN(types[INPUT][0]) != CV_MAT_CN(types[OUTPUT][0]) ) + inplace = false; +} + + +double CV_ColorRGBTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 0; +} + + +void CV_ColorRGBTest::convert_forward( const Mat& src, Mat& dst ) +{ + int depth = src.depth(), cn = src.channels(); +/*#if defined _DEBUG || defined DEBUG + int dst_cn = CV_MAT_CN(dst->type); +#endif*/ + int i, j, cols = src.cols; + int g_rshift = dst_bits == 16 ? 2 : 3; + int r_lshift = dst_bits == 16 ? 11 : 10; + + //assert( (cn == 3 || cn == 4) && (dst_cn == 3 || (dst_cn == 2 && depth == CV_8U)) ); + + for( i = 0; i < src.rows; i++ ) + { + switch( depth ) + { + case CV_8U: + { + const uchar* src_row = src.ptr(i); + uchar* dst_row = dst.ptr(i); + + if( dst_bits == 24 ) + { + for( j = 0; j < cols; j++ ) + { + uchar b = src_row[j*cn + blue_idx]; + uchar g = src_row[j*cn + 1]; + uchar r = src_row[j*cn + (blue_idx^2)]; + dst_row[j*3] = b; + dst_row[j*3+1] = g; + dst_row[j*3+2] = r; + } + } + else + { + for( j = 0; j < cols; j++ ) + { + int b = src_row[j*cn + blue_idx] >> 3; + int g = src_row[j*cn + 1] >> g_rshift; + int r = src_row[j*cn + (blue_idx^2)] >> 3; + ((ushort*)dst_row)[j] = (ushort)(b | (g << 5) | (r << r_lshift)); + if( cn == 4 && src_row[j*4+3] ) + ((ushort*)dst_row)[j] |= 1 << (r_lshift+5); + } + } + } + break; + case CV_16U: + { + const ushort* src_row = src.ptr(i); + ushort* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + ushort b = src_row[j*cn + blue_idx]; + ushort g = src_row[j*cn + 1]; + ushort r = src_row[j*cn + (blue_idx^2)]; + dst_row[j*3] = b; + dst_row[j*3+1] = g; + dst_row[j*3+2] = r; + } + } + break; + case CV_32F: + { + const float* src_row = src.ptr(i); + float* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + float b = src_row[j*cn + blue_idx]; + float g = src_row[j*cn + 1]; + float r = src_row[j*cn + (blue_idx^2)]; + dst_row[j*3] = b; + dst_row[j*3+1] = g; + dst_row[j*3+2] = r; + } + } + break; + default: + assert(0); + } + } +} + + +void CV_ColorRGBTest::convert_backward( const Mat& /*src*/, const Mat& src, Mat& dst ) +{ + int depth = src.depth(), cn = dst.channels(); +/*#if defined _DEBUG || defined DEBUG + int src_cn = CV_MAT_CN(src->type); +#endif*/ + int i, j, cols = src.cols; + int g_lshift = dst_bits == 16 ? 2 : 3; + int r_rshift = dst_bits == 16 ? 11 : 10; + + //assert( (cn == 3 || cn == 4) && (src_cn == 3 || (src_cn == 2 && depth == CV_8U)) ); + + for( i = 0; i < src.rows; i++ ) + { + switch( depth ) + { + case CV_8U: + { + const uchar* src_row = src.ptr(i); + uchar* dst_row = dst.ptr(i); + + if( dst_bits == 24 ) + { + for( j = 0; j < cols; j++ ) + { + uchar b = src_row[j*3]; + uchar g = src_row[j*3 + 1]; + uchar r = src_row[j*3 + 2]; + + dst_row[j*cn + blue_idx] = b; + dst_row[j*cn + 1] = g; + dst_row[j*cn + (blue_idx^2)] = r; + + if( cn == 4 ) + dst_row[j*cn + 3] = 255; + } + } + else + { + for( j = 0; j < cols; j++ ) + { + ushort val = ((ushort*)src_row)[j]; + uchar b = (uchar)(val << 3); + uchar g = (uchar)((val >> 5) << g_lshift); + uchar r = (uchar)((val >> r_rshift) << 3); + + dst_row[j*cn + blue_idx] = b; + dst_row[j*cn + 1] = g; + dst_row[j*cn + (blue_idx^2)] = r; + + if( cn == 4 ) + { + uchar alpha = r_rshift == 11 || (val & 0x8000) != 0 ? 255 : 0; + dst_row[j*cn + 3] = alpha; + } + } + } + } + break; + case CV_16U: + { + const ushort* src_row = src.ptr(i); + ushort* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + ushort b = src_row[j*3]; + ushort g = src_row[j*3 + 1]; + ushort r = src_row[j*3 + 2]; + + dst_row[j*cn + blue_idx] = b; + dst_row[j*cn + 1] = g; + dst_row[j*cn + (blue_idx^2)] = r; + + if( cn == 4 ) + dst_row[j*cn + 3] = 65535; + } + } + break; + case CV_32F: + { + const float* src_row = src.ptr(i); + float* dst_row = dst.ptr(i); + + for( j = 0; j < cols; j++ ) + { + float b = src_row[j*3]; + float g = src_row[j*3 + 1]; + float r = src_row[j*3 + 2]; + + dst_row[j*cn + blue_idx] = b; + dst_row[j*cn + 1] = g; + dst_row[j*cn + (blue_idx^2)] = r; + + if( cn == 4 ) + dst_row[j*cn + 3] = 1.f; + } + } + break; + default: + assert(0); + } + } +} + + +//// rgb <=> bayer + +class CV_ColorBayerTest : public CV_ColorCvtBaseTest +{ +public: + CV_ColorBayerTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int test_case_idx ); +}; + + +CV_ColorBayerTest::CV_ColorBayerTest() : CV_ColorCvtBaseTest( false, false, true ) +{ + test_array[OUTPUT].pop_back(); + test_array[REF_OUTPUT].pop_back(); + + fwd_code_str = "BayerBG2BGR"; + inv_code_str = ""; + fwd_code = CV_BayerBG2BGR; + inv_code = -1; +} + + +void CV_ColorBayerTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_ColorCvtBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + types[INPUT][0] = CV_MAT_DEPTH(types[INPUT][0]); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(CV_MAT_DEPTH(types[INPUT][0]), 3); + inplace = false; + + fwd_code = cvtest::randInt(rng)%4 + CV_BayerBG2BGR; +} + + +double CV_ColorBayerTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 1; +} + + +void CV_ColorBayerTest::run_func() +{ + if(!test_cpp) + cvCvtColor( test_array[INPUT][0], test_array[OUTPUT][0], fwd_code ); + else + { + cv::Mat _out = cv::cvarrToMat(test_array[OUTPUT][0]); + cv::cvtColor(cv::cvarrToMat(test_array[INPUT][0]), _out, fwd_code, _out.channels()); + } +} + + +template +static void bayer2BGR_(const Mat& src, Mat& dst, int code) +{ + int i, j, cols = src.cols - 2; + int bi = 0; + int step = (int)(src.step/sizeof(T)); + + if( code == CV_BayerRG2BGR || code == CV_BayerGR2BGR ) + bi ^= 2; + + for( i = 1; i < src.rows - 1; i++ ) + { + const T* ptr = src.ptr(i) + 1; + T* dst_row = dst.ptr(i) + 3; + int save_code = code; + if( cols <= 0 ) + { + dst_row[-3] = dst_row[-2] = dst_row[-1] = 0; + dst_row[cols*3] = dst_row[cols*3+1] = dst_row[cols*3+2] = 0; + continue; + } + + for( j = 0; j < cols; j++ ) + { + int b, g, r; + if( !(code & 1) ) + { + b = ptr[j]; + g = (ptr[j-1] + ptr[j+1] + ptr[j-step] + ptr[j+step])>>2; + r = (ptr[j-step-1] + ptr[j-step+1] + ptr[j+step-1] + ptr[j+step+1]) >> 2; + } + else + { + b = (ptr[j-1] + ptr[j+1]) >> 1; + g = ptr[j]; + r = (ptr[j-step] + ptr[j+step]) >> 1; + } + code ^= 1; + dst_row[j*3 + bi] = (T)b; + dst_row[j*3 + 1] = (T)g; + dst_row[j*3 + (bi^2)] = (T)r; + } + + dst_row[-3] = dst_row[0]; + dst_row[-2] = dst_row[1]; + dst_row[-1] = dst_row[2]; + dst_row[cols*3] = dst_row[cols*3-3]; + dst_row[cols*3+1] = dst_row[cols*3-2]; + dst_row[cols*3+2] = dst_row[cols*3-1]; + + code = save_code ^ 1; + bi ^= 2; + } + + if( src.rows <= 2 ) + { + memset( dst.ptr(), 0, (cols+2)*3*sizeof(T) ); + memset( dst.ptr(dst.rows-1), 0, (cols+2)*3*sizeof(T) ); + } + else + { + T* top_row = dst.ptr(); + T* bottom_row = dst.ptr(dst.rows-1); + int dstep = (int)(dst.step/sizeof(T)); + + for( j = 0; j < (cols+2)*3; j++ ) + { + top_row[j] = top_row[j + dstep]; + bottom_row[j] = bottom_row[j - dstep]; + } + } +} + + +void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + const Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_OUTPUT][0]; + int depth = src.depth(); + if( depth == CV_8U ) + bayer2BGR_(src, dst, fwd_code); + else if( depth == CV_16U ) + bayer2BGR_(src, dst, fwd_code); + else + CV_Error(CV_StsUnsupportedFormat, ""); +} + + +///////////////////////////////////////////////////////////////////////////////////////////////// + +TEST(Imgproc_ColorGray, accuracy) { CV_ColorGrayTest test; test.safe_run(); } +TEST(Imgproc_ColorYCrCb, accuracy) { CV_ColorYCrCbTest test; test.safe_run(); } +TEST(Imgproc_ColorHSV, accuracy) { CV_ColorHSVTest test; test.safe_run(); } +TEST(Imgproc_ColorHLS, accuracy) { CV_ColorHLSTest test; test.safe_run(); } +TEST(Imgproc_ColorXYZ, accuracy) { CV_ColorXYZTest test; test.safe_run(); } +TEST(Imgproc_ColorLab, accuracy) { CV_ColorLabTest test; test.safe_run(); } +TEST(Imgproc_ColorLuv, accuracy) { CV_ColorLuvTest test; test.safe_run(); } +TEST(Imgproc_ColorRGB, accuracy) { CV_ColorRGBTest test; test.safe_run(); } +TEST(Imgproc_ColorBayer, accuracy) { CV_ColorBayerTest test; test.safe_run(); } + +TEST(Imgproc_ColorBayer, regression) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + + Mat given = imread(string(ts.get_data_path()) + "/cvtcolor/bayer_input.png", CV_LOAD_IMAGE_GRAYSCALE); + Mat gold = imread(string(ts.get_data_path()) + "/cvtcolor/bayer_gold.png", CV_LOAD_IMAGE_UNCHANGED); + Mat result; + + cvtColor(given, result, CV_BayerBG2GRAY); + + EXPECT_EQ(gold.type(), result.type()); + EXPECT_EQ(gold.cols, result.cols); + EXPECT_EQ(gold.rows, result.rows); + + Mat diff; + absdiff(gold, result, diff); + + EXPECT_EQ(0, countNonZero(diff.reshape(1) > 1)); +} + +TEST(Imgproc_ColorBayerVNG, regression) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + + Mat given = imread(string(ts.get_data_path()) + "/cvtcolor/bayer_input.png", CV_LOAD_IMAGE_GRAYSCALE); + string goldfname = string(ts.get_data_path()) + "/cvtcolor/bayerVNG_gold.png"; + Mat gold = imread(goldfname, CV_LOAD_IMAGE_UNCHANGED); + Mat result; + + CV_Assert(given.data != NULL); + + cvtColor(given, result, CV_BayerBG2BGR_VNG, 3); + + if (gold.empty()) + imwrite(goldfname, result); + else + { + EXPECT_EQ(gold.type(), result.type()); + EXPECT_EQ(gold.cols, result.cols); + EXPECT_EQ(gold.rows, result.rows); + + Mat diff; + absdiff(gold, result, diff); + + EXPECT_EQ(0, countNonZero(diff.reshape(1) > 1)); + } +} + +TEST(Imgproc_ColorBayerVNG_Strict, regression) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + const char pattern[][3] = { "bg", "gb", "rg", "gr" }; + const std::string image_name = "lena.png"; + const std::string parent_path = string(ts.get_data_path()) + "/cvtcolor_strict/"; + + Mat src, dst, bayer, reference; + std::string full_path = parent_path + image_name; + src = imread(full_path, CV_LOAD_IMAGE_UNCHANGED); + Size ssize = src.size(); + + if (src.data == NULL) + { + ts.set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); + ts.printf(cvtest::TS::SUMMARY, "No input image\n"); + ts.set_gtest_status(); + return; + } + + int type = -1; + for (int i = 0; i < 4; ++i) + { + // creating Bayer pattern + bayer.create(ssize, CV_MAKETYPE(src.depth(), 1)); + + if (!strcmp(pattern[i], "bg")) + { + for (int y = 0; y < ssize.height; ++y) + for (int x = 0; x < ssize.width; ++x) + { + if ((x + y) % 2) + bayer.at(y, x) = src.at(y, x)[1]; + else if (x % 2) + bayer.at(y, x) = src.at(y, x)[0]; + else + bayer.at(y, x) = src.at(y, x)[2]; + } + type = CV_BayerBG2BGR_VNG; + } + else if (!strcmp(pattern[i], "gb")) + { + for (int y = 0; y < ssize.height; ++y) + for (int x = 0; x < ssize.width; ++x) + { + if ((x + y) % 2 == 0) + bayer.at(y, x) = src.at(y, x)[1]; + else if (x % 2 == 0) + bayer.at(y, x) = src.at(y, x)[0]; + else + bayer.at(y, x) = src.at(y, x)[2]; + } + type = CV_BayerGB2BGR_VNG; + } + else if (!strcmp(pattern[i], "rg")) + { + for (int y = 0; y < ssize.height; ++y) + for (int x = 0; x < ssize.width; ++x) + { + if ((x + y) % 2) + bayer.at(y, x) = src.at(y, x)[1]; + else if (x % 2 == 0) + bayer.at(y, x) = src.at(y, x)[0]; + else + bayer.at(y, x) = src.at(y, x)[2]; + } + type = CV_BayerRG2BGR_VNG; + } + else + { + for (int y = 0; y < ssize.height; ++y) + for (int x = 0; x < ssize.width; ++x) + { + if ((x + y) % 2 == 0) + bayer.at(y, x) = src.at(y, x)[1]; + else if (x % 2) + bayer.at(y, x) = src.at(y, x)[0]; + else + bayer.at(y, x) = src.at(y, x)[2]; + } + type = CV_BayerGR2BGR_VNG; + } + + // calculating a dst image + cvtColor(bayer, dst, type); + + // reading a reference image + full_path = parent_path + pattern[i] + image_name; + reference = imread(full_path, CV_LOAD_IMAGE_UNCHANGED); + if (reference.data == NULL) + { + imwrite(full_path, dst); + continue; + } + + if (reference.depth() != dst.depth() || reference.channels() != dst.channels() || + reference.size() != dst.size()) + { + ts.set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + ts.printf(cvtest::TS::SUMMARY, "\nReference channels: %d\n" + "Actual channels: %d\n", reference.channels(), dst.channels()); + ts.printf(cvtest::TS::SUMMARY, "\nReference depth: %d\n" + "Actual depth: %d\n", reference.depth(), dst.depth()); + ts.printf(cvtest::TS::SUMMARY, "\nReference rows: %d\n" + "Actual rows: %d\n", reference.rows, dst.rows); + ts.printf(cvtest::TS::SUMMARY, "\nReference cols: %d\n" + "Actual cols: %d\n", reference.cols, dst.cols); + ts.set_gtest_status(); + + return; + } + + Mat diff; + absdiff(reference, dst, diff); + + int nonZero = countNonZero(diff.reshape(1) > 1); + if (nonZero != 0) + { + ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + ts.printf(cvtest::TS::SUMMARY, "\nCount non zero in absdiff: %d\n", nonZero); + ts.set_gtest_status(); + return; + } + } +} + + +void GetTestMatrix(Mat& src) +{ + Size ssize(1000, 1000); + src.create(ssize, CV_32FC3); + int szm = ssize.width - 1; + float pi2 = 2 * 3.1415f; + // Generate a pretty test image + for (int i = 0; i < ssize.height; i++) + { + for (int j = 0; j < ssize.width; j++) + { + float b = (1 + cos((szm - i) * (szm - j) * pi2 / (10 * float(szm)))) / 2; + float g = (1 + cos((szm - i) * j * pi2 / (10 * float(szm)))) / 2; + float r = (1 + sin(i * j * pi2 / (10 * float(szm)))) / 2; + + // The following lines aren't necessary, but just to prove that + // the BGR values all lie in [0,1]... + if (b < 0) b = 0; else if (b > 1) b = 1; + if (g < 0) g = 0; else if (g > 1) g = 1; + if (r < 0) r = 0; else if (r > 1) r = 1; + src.at(i, j) = cv::Vec3f(b, g, r); + } + } +} + +void validate_result(const Mat& reference, const Mat& actual, const Mat& src = Mat(), int mode = -1) +{ + cvtest::TS* ts = cvtest::TS::ptr(); + Size ssize = reference.size(); + + int cn = reference.channels(); + ssize.width *= cn; + bool next = true; + + for (int y = 0; y < ssize.height && next; ++y) + { + const float* rD = reference.ptr(y); + const float* D = actual.ptr(y); + for (int x = 0; x < ssize.width && next; ++x) + if (fabs(rD[x] - D[x]) > 0.0001f) + { + next = false; + ts->printf(cvtest::TS::SUMMARY, "Error in: (%d, %d)\n", x / cn, y); + ts->printf(cvtest::TS::SUMMARY, "Reference value: %f\n", rD[x]); + ts->printf(cvtest::TS::SUMMARY, "Actual value: %f\n", D[x]); + if (!src.empty()) + ts->printf(cvtest::TS::SUMMARY, "Src value: %f\n", src.ptr(y)[x]); + ts->printf(cvtest::TS::SUMMARY, "Size: (%d, %d)\n", reference.rows, reference.cols); + + if (mode >= 0) + { + cv::Mat lab; + cv::cvtColor(src, lab, mode); + std::cout << "lab: " << lab(cv::Rect(y, x / cn, 1, 1)) << std::endl; + } + std::cout << "src: " << src(cv::Rect(y, x / cn, 1, 1)) << std::endl; + + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + ts->set_gtest_status(); + } + } +} + +TEST(Imgproc_ColorLab_Full, accuracy) +{ + Mat src; + GetTestMatrix(src); + Mat reference(src.size(), CV_32FC3); + Size ssize = src.size(); + CV_Assert(ssize.width == ssize.height); + + RNG& rng = cvtest::TS::ptr()->get_rng(); + int blueInd = rng.uniform(0., 1.) > 0.5 ? 0 : 2; + bool srgb = rng.uniform(0., 1.) > 0.5; + + // Convert test image to LAB + cv::Mat lab; + int forward_code = blueInd ? srgb ? CV_BGR2Lab : CV_LBGR2Lab : srgb ? CV_RGB2Lab : CV_LRGB2Lab; + int inverse_code = blueInd ? srgb ? CV_Lab2BGR : CV_Lab2LBGR : srgb ? CV_Lab2RGB : CV_Lab2LRGB; + cv::cvtColor(src, lab, forward_code); + // Convert LAB image back to BGR(RGB) + cv::Mat recons; + cv::cvtColor(lab, recons, inverse_code); + + validate_result(src, recons, src, forward_code); + +// src *= 255.0f; +// recons *= 255.0f; + +// imshow("Test", src); +// imshow("OpenCV", recons); +// waitKey(); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_contours.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_contours.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_contours.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_contours.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,393 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_FindContourTest : public cvtest::BaseTest +{ +public: + enum { NUM_IMG = 4 }; + + CV_FindContourTest(); + ~CV_FindContourTest(); + void clear(); + +protected: + int read_params( CvFileStorage* fs ); + int prepare_test_case( int test_case_idx ); + int validate_test_results( int test_case_idx ); + void run_func(); + + int min_blob_size, max_blob_size; + int blob_count, max_log_blob_count; + int retr_mode, approx_method; + + int min_log_img_size, max_log_img_size; + CvSize img_size; + int count, count2; + + IplImage* img[NUM_IMG]; + CvMemStorage* storage; + CvSeq *contours, *contours2, *chain; +}; + + +CV_FindContourTest::CV_FindContourTest() +{ + int i; + + test_case_count = 300; + min_blob_size = 1; + max_blob_size = 50; + max_log_blob_count = 10; + + min_log_img_size = 3; + max_log_img_size = 10; + + for( i = 0; i < NUM_IMG; i++ ) + img[i] = 0; + + storage = 0; +} + + +CV_FindContourTest::~CV_FindContourTest() +{ + clear(); +} + + +void CV_FindContourTest::clear() +{ + int i; + + cvtest::BaseTest::clear(); + + for( i = 0; i < NUM_IMG; i++ ) + cvReleaseImage( &img[i] ); + + cvReleaseMemStorage( &storage ); +} + + +int CV_FindContourTest::read_params( CvFileStorage* fs ) +{ + int t; + int code = cvtest::BaseTest::read_params( fs ); + + if( code < 0 ) + return code; + + min_blob_size = cvReadInt( find_param( fs, "min_blob_size" ), min_blob_size ); + max_blob_size = cvReadInt( find_param( fs, "max_blob_size" ), max_blob_size ); + max_log_blob_count = cvReadInt( find_param( fs, "max_log_blob_count" ), max_log_blob_count ); + min_log_img_size = cvReadInt( find_param( fs, "min_log_img_size" ), min_log_img_size ); + max_log_img_size = cvReadInt( find_param( fs, "max_log_img_size" ), max_log_img_size ); + + min_blob_size = cvtest::clipInt( min_blob_size, 1, 100 ); + max_blob_size = cvtest::clipInt( max_blob_size, 1, 100 ); + + if( min_blob_size > max_blob_size ) + CV_SWAP( min_blob_size, max_blob_size, t ); + + max_log_blob_count = cvtest::clipInt( max_log_blob_count, 1, 10 ); + + min_log_img_size = cvtest::clipInt( min_log_img_size, 1, 10 ); + max_log_img_size = cvtest::clipInt( max_log_img_size, 1, 10 ); + + if( min_log_img_size > max_log_img_size ) + CV_SWAP( min_log_img_size, max_log_img_size, t ); + + return 0; +} + + +static void +cvTsGenerateBlobImage( IplImage* img, int min_blob_size, int max_blob_size, + int blob_count, int min_brightness, int max_brightness, + RNG& rng ) +{ + int i; + CvSize size; + + assert( img->depth == IPL_DEPTH_8U && img->nChannels == 1 ); + + cvZero( img ); + + // keep the border clear + cvSetImageROI( img, cvRect(1,1,img->width-2,img->height-2) ); + size = cvGetSize( img ); + + for( i = 0; i < blob_count; i++ ) + { + CvPoint center; + CvSize axes; + int angle = cvtest::randInt(rng) % 180; + int brightness = cvtest::randInt(rng) % + (max_brightness - min_brightness) + min_brightness; + center.x = cvtest::randInt(rng) % size.width; + center.y = cvtest::randInt(rng) % size.height; + + axes.width = (cvtest::randInt(rng) % + (max_blob_size - min_blob_size) + min_blob_size + 1)/2; + axes.height = (cvtest::randInt(rng) % + (max_blob_size - min_blob_size) + min_blob_size + 1)/2; + + cvEllipse( img, center, axes, angle, 0, 360, cvScalar(brightness), CV_FILLED ); + } + + cvResetImageROI( img ); +} + + +static void +cvTsMarkContours( IplImage* img, int val ) +{ + int i, j; + int step = img->widthStep; + + assert( img->depth == IPL_DEPTH_8U && img->nChannels == 1 && (val&1) != 0); + + for( i = 1; i < img->height - 1; i++ ) + for( j = 1; j < img->width - 1; j++ ) + { + uchar* t = (uchar*)(img->imageData + img->widthStep*i + j); + if( *t == 1 && (t[-step] == 0 || t[-1] == 0 || t[1] == 0 || t[step] == 0)) + *t = (uchar)val; + } + + cvThreshold( img, img, val - 2, val, CV_THRESH_BINARY ); +} + + +int CV_FindContourTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + const int min_brightness = 0, max_brightness = 2; + int i, code = cvtest::BaseTest::prepare_test_case( test_case_idx ); + + if( code < 0 ) + return code; + + clear(); + + blob_count = cvRound(exp(cvtest::randReal(rng)*max_log_blob_count*CV_LOG2)); + + img_size.width = cvRound(exp((cvtest::randReal(rng)* + (max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2)); + img_size.height = cvRound(exp((cvtest::randReal(rng)* + (max_log_img_size - min_log_img_size) + min_log_img_size)*CV_LOG2)); + + approx_method = cvtest::randInt( rng ) % 4 + 1; + retr_mode = cvtest::randInt( rng ) % 4; + + storage = cvCreateMemStorage( 1 << 10 ); + + for( i = 0; i < NUM_IMG; i++ ) + img[i] = cvCreateImage( img_size, 8, 1 ); + + cvTsGenerateBlobImage( img[0], min_blob_size, max_blob_size, + blob_count, min_brightness, max_brightness, rng ); + + cvCopy( img[0], img[1] ); + cvCopy( img[0], img[2] ); + + cvTsMarkContours( img[1], 255 ); + + return 1; +} + + +void CV_FindContourTest::run_func() +{ + contours = contours2 = chain = 0; + count = cvFindContours( img[2], storage, &contours, sizeof(CvContour), retr_mode, approx_method ); + + cvZero( img[3] ); + + if( contours && retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 ) + cvDrawContours( img[3], contours, cvScalar(255), cvScalar(255), INT_MAX, -1 ); + + cvCopy( img[0], img[2] ); + + count2 = cvFindContours( img[2], storage, &chain, sizeof(CvChain), retr_mode, CV_CHAIN_CODE ); + + if( chain ) + contours2 = cvApproxChains( chain, storage, approx_method, 0, 0, 1 ); + + cvZero( img[2] ); + + if( contours && retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 ) + cvDrawContours( img[2], contours2, cvScalar(255), cvScalar(255), INT_MAX ); +} + + +// the whole testing is done here, run_func() is not utilized in this test +int CV_FindContourTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + + cvCmpS( img[0], 0, img[0], CV_CMP_GT ); + + if( count != count2 ) + { + ts->printf( cvtest::TS::LOG, "The number of contours retrieved with different " + "approximation methods is not the same\n" + "(%d contour(s) for method %d vs %d contour(s) for method %d)\n", + count, approx_method, count2, CV_CHAIN_CODE ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + + if( retr_mode != CV_RETR_EXTERNAL && approx_method < CV_CHAIN_APPROX_TC89_L1 ) + { + Mat _img[4]; + for( int i = 0; i < 4; i++ ) + _img[i] = cvarrToMat(img[i]); + + code = cvtest::cmpEps2(ts, _img[0], _img[3], 0, true, "Comparing original image with the map of filled contours" ); + + if( code < 0 ) + goto _exit_; + + code = cvtest::cmpEps2( ts, _img[1], _img[2], 0, true, + "Comparing contour outline vs manually produced edge map" ); + + if( code < 0 ) + goto _exit_; + } + + if( contours ) + { + CvTreeNodeIterator iterator1; + CvTreeNodeIterator iterator2; + int count3; + + for(int i = 0; i < 2; i++ ) + { + CvTreeNodeIterator iterator; + cvInitTreeNodeIterator( &iterator, i == 0 ? contours : contours2, INT_MAX ); + + for( count3 = 0; cvNextTreeNode( &iterator ) != 0; count3++ ) + ; + + if( count3 != count ) + { + ts->printf( cvtest::TS::LOG, + "The returned number of retrieved contours (using the approx_method = %d) does not match\n" + "to the actual number of contours in the tree/list (returned %d, actual %d)\n", + i == 0 ? approx_method : 0, count, count3 ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + } + + cvInitTreeNodeIterator( &iterator1, contours, INT_MAX ); + cvInitTreeNodeIterator( &iterator2, contours2, INT_MAX ); + + for( count3 = 0; count3 < count; count3++ ) + { + CvSeq* seq1 = (CvSeq*)cvNextTreeNode( &iterator1 ); + CvSeq* seq2 = (CvSeq*)cvNextTreeNode( &iterator2 ); + CvSeqReader reader1; + CvSeqReader reader2; + + if( !seq1 || !seq2 ) + { + ts->printf( cvtest::TS::LOG, + "There are NULL pointers in the original contour tree or the " + "tree produced by cvApproxChains\n" ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + + cvStartReadSeq( seq1, &reader1 ); + cvStartReadSeq( seq2, &reader2 ); + + if( seq1->total != seq2->total ) + { + ts->printf( cvtest::TS::LOG, + "The original contour #%d has %d points, while the corresponding contour has %d point\n", + count3, seq1->total, seq2->total ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + + for(int i = 0; i < seq1->total; i++ ) + { + CvPoint pt1; + CvPoint pt2; + + CV_READ_SEQ_ELEM( pt1, reader1 ); + CV_READ_SEQ_ELEM( pt2, reader2 ); + + if( pt1.x != pt2.x || pt1.y != pt2.y ) + { + ts->printf( cvtest::TS::LOG, + "The point #%d in the contour #%d is different from the corresponding point " + "in the approximated chain ((%d,%d) vs (%d,%d)", count3, i, pt1.x, pt1.y, pt2.x, pt2.y ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + } + } + } + +_exit_: + if( code < 0 ) + { +#if 0 + cvNamedWindow( "test", 0 ); + cvShowImage( "test", img[0] ); + cvWaitKey(); +#endif + ts->set_failed_test_info( code ); + } + + return code; +} + + +TEST(Imgproc_FindContours, accuracy) { CV_FindContourTest test; test.safe_run(); } + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_convhull.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_convhull.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_convhull.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_convhull.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1703 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +/*static int +cvTsPointConvexPolygon( CvPoint2D32f pt, CvPoint2D32f* v, int n ) +{ + CvPoint2D32f v0 = v[n-1]; + int i, sign = 0; + + for( i = 0; i < n; i++ ) + { + CvPoint2D32f v1 = v[i]; + float dx = pt.x - v0.x, dy = pt.y - v0.y; + float dx1 = v1.x - v0.x, dy1 = v1.y - v0.y; + double t = (double)dx*dy1 - (double)dx1*dy; + if( fabs(t) > DBL_EPSILON ) + { + if( t*sign < 0 ) + break; + if( sign == 0 ) + sign = t < 0 ? -1 : 1; + } + else if( fabs(dx) + fabs(dy) < DBL_EPSILON ) + return i+1; + v0 = v1; + } + + return i < n ? -1 : 0; +}*/ + +CV_INLINE double +cvTsDist( CvPoint2D32f a, CvPoint2D32f b ) +{ + double dx = a.x - b.x; + double dy = a.y - b.y; + return sqrt(dx*dx + dy*dy); +} + +CV_INLINE double +cvTsPtLineDist( CvPoint2D32f pt, CvPoint2D32f a, CvPoint2D32f b ) +{ + double d0 = cvTsDist( pt, a ), d1; + double dd = cvTsDist( a, b ); + if( dd < FLT_EPSILON ) + return d0; + d1 = cvTsDist( pt, b ); + dd = fabs((double)(pt.x - a.x)*(b.y - a.y) - (double)(pt.y - a.y)*(b.x - a.x))/dd; + d0 = MIN( d0, d1 ); + return MIN( d0, dd ); +} + +static double +cvTsPointPolygonTest( CvPoint2D32f pt, const CvPoint2D32f* vv, int n, int* _idx=0, int* _on_edge=0 ) +{ + int i; + CvPoint2D32f v = vv[n-1], v0; + double min_dist_num = FLT_MAX, min_dist_denom = 1; + int min_dist_idx = -1, min_on_edge = 0; + int counter = 0; + double result; + + for( i = 0; i < n; i++ ) + { + double dx, dy, dx1, dy1, dx2, dy2, dist_num, dist_denom = 1; + int on_edge = 0, idx = i; + + v0 = v; v = vv[i]; + dx = v.x - v0.x; dy = v.y - v0.y; + dx1 = pt.x - v0.x; dy1 = pt.y - v0.y; + dx2 = pt.x - v.x; dy2 = pt.y - v.y; + + if( dx2*dx + dy2*dy >= 0 ) + dist_num = dx2*dx2 + dy2*dy2; + else if( dx1*dx + dy1*dy <= 0 ) + { + dist_num = dx1*dx1 + dy1*dy1; + idx = i - 1; + if( idx < 0 ) idx = n-1; + } + else + { + dist_num = (dy1*dx - dx1*dy); + dist_num *= dist_num; + dist_denom = dx*dx + dy*dy; + on_edge = 1; + } + + if( dist_num*min_dist_denom < min_dist_num*dist_denom ) + { + min_dist_num = dist_num; + min_dist_denom = dist_denom; + min_dist_idx = idx; + min_on_edge = on_edge; + if( min_dist_num == 0 ) + break; + } + + if( (v0.y <= pt.y && v.y <= pt.y) || + (v0.y > pt.y && v.y > pt.y) || + (v0.x < pt.x && v.x < pt.x) ) + continue; + + dist_num = dy1*dx - dx1*dy; + if( dy < 0 ) + dist_num = -dist_num; + counter += dist_num > 0; + } + + result = sqrt(min_dist_num/min_dist_denom); + if( counter % 2 == 0 ) + result = -result; + + if( _idx ) + *_idx = min_dist_idx; + if( _on_edge ) + *_on_edge = min_on_edge; + + return result; +} + + +/****************************************************************************************\ +* Base class for shape descriptor tests * +\****************************************************************************************/ + +class CV_BaseShapeDescrTest : public cvtest::BaseTest +{ +public: + CV_BaseShapeDescrTest(); + virtual ~CV_BaseShapeDescrTest(); + void clear(); + +protected: + int read_params( CvFileStorage* fs ); + void run_func(void); + int prepare_test_case( int test_case_idx ); + int validate_test_results( int test_case_idx ); + virtual void generate_point_set( void* points ); + virtual void extract_points(); + + int min_log_size; + int max_log_size; + int dims; + bool enable_flt_points; + + CvMemStorage* storage; + CvSeq* points1; + CvMat* points2; + void* points; + void* result; + double low_high_range; + CvScalar low, high; + + bool test_cpp; +}; + + +CV_BaseShapeDescrTest::CV_BaseShapeDescrTest() +{ + points1 = 0; + points2 = 0; + points = 0; + storage = 0; + test_case_count = 500; + min_log_size = 0; + max_log_size = 10; + low = high = cvScalarAll(0); + low_high_range = 50; + dims = 2; + enable_flt_points = true; + + test_cpp = false; +} + + +CV_BaseShapeDescrTest::~CV_BaseShapeDescrTest() +{ + clear(); +} + + +void CV_BaseShapeDescrTest::clear() +{ + cvtest::BaseTest::clear(); + cvReleaseMemStorage( &storage ); + cvReleaseMat( &points2 ); + points1 = 0; + points = 0; +} + + +int CV_BaseShapeDescrTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::BaseTest::read_params( fs ); + if( code < 0 ) + return code; + + test_case_count = cvReadInt( find_param( fs, "struct_count" ), test_case_count ); + min_log_size = cvReadInt( find_param( fs, "min_log_size" ), min_log_size ); + max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size ); + + min_log_size = cvtest::clipInt( min_log_size, 0, 8 ); + max_log_size = cvtest::clipInt( max_log_size, 0, 10 ); + if( min_log_size > max_log_size ) + { + int t; + CV_SWAP( min_log_size, max_log_size, t ); + } + + return 0; +} + + +void CV_BaseShapeDescrTest::generate_point_set( void* pointsSet ) +{ + RNG& rng = ts->get_rng(); + int i, k, n, total, point_type; + CvSeqReader reader; + uchar* data = 0; + double a[4], b[4]; + + for( k = 0; k < 4; k++ ) + { + a[k] = high.val[k] - low.val[k]; + b[k] = low.val[k]; + } + memset( &reader, 0, sizeof(reader) ); + + if( CV_IS_SEQ(pointsSet) ) + { + CvSeq* ptseq = (CvSeq*)pointsSet; + total = ptseq->total; + point_type = CV_SEQ_ELTYPE(ptseq); + cvStartReadSeq( ptseq, &reader ); + } + else + { + CvMat* ptm = (CvMat*)pointsSet; + assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) ); + total = ptm->rows + ptm->cols - 1; + point_type = CV_MAT_TYPE(ptm->type); + data = ptm->data.ptr; + } + + n = CV_MAT_CN(point_type); + point_type = CV_MAT_DEPTH(point_type); + + assert( (point_type == CV_32S || point_type == CV_32F) && n <= 4 ); + + for( i = 0; i < total; i++ ) + { + int* pi; + float* pf; + if( reader.ptr ) + { + pi = (int*)reader.ptr; + pf = (float*)reader.ptr; + CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); + } + else + { + pi = (int*)data + i*n; + pf = (float*)data + i*n; + } + if( point_type == CV_32S ) + for( k = 0; k < n; k++ ) + pi[k] = cvRound(cvtest::randReal(rng)*a[k] + b[k]); + else + for( k = 0; k < n; k++ ) + pf[k] = (float)(cvtest::randReal(rng)*a[k] + b[k]); + } +} + + +int CV_BaseShapeDescrTest::prepare_test_case( int test_case_idx ) +{ + int size; + int use_storage = 0; + int point_type; + int i; + RNG& rng = ts->get_rng(); + + cvtest::BaseTest::prepare_test_case( test_case_idx ); + + clear(); + size = cvRound( exp((cvtest::randReal(rng) * (max_log_size - min_log_size) + min_log_size)*CV_LOG2) ); + use_storage = cvtest::randInt(rng) % 2; + point_type = CV_MAKETYPE(cvtest::randInt(rng) % + (enable_flt_points ? 2 : 1) ? CV_32F : CV_32S, dims); + + if( use_storage ) + { + storage = cvCreateMemStorage( (cvtest::randInt(rng)%10 + 1)*1024 ); + points1 = cvCreateSeq( point_type, sizeof(CvSeq), CV_ELEM_SIZE(point_type), storage ); + cvSeqPushMulti( points1, 0, size ); + points = points1; + } + else + { + int rows = 1, cols = size; + if( cvtest::randInt(rng) % 2 ) + rows = size, cols = 1; + + points2 = cvCreateMat( rows, cols, point_type ); + points = points2; + } + + for( i = 0; i < 4; i++ ) + { + low.val[i] = (cvtest::randReal(rng)-0.5)*low_high_range*2; + high.val[i] = (cvtest::randReal(rng)-0.5)*low_high_range*2; + if( low.val[i] > high.val[i] ) + { + double t; + CV_SWAP( low.val[i], high.val[i], t ); + } + if( high.val[i] < low.val[i] + 1 ) + high.val[i] += 1; + } + + generate_point_set( points ); + + test_cpp = (cvtest::randInt(rng) & 16) == 0; + return 1; +} + + +void CV_BaseShapeDescrTest::extract_points() +{ + if( points1 ) + { + points2 = cvCreateMat( 1, points1->total, CV_SEQ_ELTYPE(points1) ); + cvCvtSeqToArray( points1, points2->data.ptr ); + } + + if( CV_MAT_DEPTH(points2->type) != CV_32F && enable_flt_points ) + { + CvMat tmp = cvMat( points2->rows, points2->cols, + (points2->type & ~CV_MAT_DEPTH_MASK) | CV_32F, points2->data.ptr ); + cvConvert( points2, &tmp ); + } +} + + +void CV_BaseShapeDescrTest::run_func(void) +{ +} + + +int CV_BaseShapeDescrTest::validate_test_results( int /*test_case_idx*/ ) +{ + extract_points(); + return 0; +} + + +/****************************************************************************************\ +* Convex Hull Test * +\****************************************************************************************/ + +class CV_ConvHullTest : public CV_BaseShapeDescrTest +{ +public: + CV_ConvHullTest(); + virtual ~CV_ConvHullTest(); + void clear(); + +protected: + void run_func(void); + int prepare_test_case( int test_case_idx ); + int validate_test_results( int test_case_idx ); + + CvSeq* hull1; + CvMat* hull2; + void* hull_storage; + int orientation; + int return_points; +}; + + +CV_ConvHullTest::CV_ConvHullTest() +{ + hull1 = 0; + hull2 = 0; + hull_storage = 0; + orientation = return_points = 0; +} + + +CV_ConvHullTest::~CV_ConvHullTest() +{ + clear(); +} + + +void CV_ConvHullTest::clear() +{ + CV_BaseShapeDescrTest::clear(); + cvReleaseMat( &hull2 ); + hull1 = 0; + hull_storage = 0; +} + + +int CV_ConvHullTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::prepare_test_case( test_case_idx ); + int use_storage_for_hull = 0; + RNG& rng = ts->get_rng(); + + if( code <= 0 ) + return code; + + orientation = cvtest::randInt(rng) % 2 ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE; + return_points = cvtest::randInt(rng) % 2; + + use_storage_for_hull = (cvtest::randInt(rng) % 2) && !test_cpp; + if( use_storage_for_hull ) + { + if( !storage ) + storage = cvCreateMemStorage( (cvtest::randInt(rng)%10 + 1)*1024 ); + hull_storage = storage; + } + else + { + int rows, cols; + int sz = points1 ? points1->total : points2->cols + points2->rows - 1; + int point_type = points1 ? CV_SEQ_ELTYPE(points1) : CV_MAT_TYPE(points2->type); + + if( cvtest::randInt(rng) % 2 ) + rows = sz, cols = 1; + else + rows = 1, cols = sz; + + hull2 = cvCreateMat( rows, cols, return_points ? point_type : CV_32SC1 ); + hull_storage = hull2; + } + + return code; +} + + +void CV_ConvHullTest::run_func() +{ + if(!test_cpp) + hull1 = cvConvexHull2( points, hull_storage, orientation, return_points ); + else + { + cv::Mat _points = cv::cvarrToMat(points); + bool clockwise = orientation == CV_CLOCKWISE; + size_t n = 0; + if( !return_points ) + { + std::vector _hull; + cv::convexHull(_points, _hull, clockwise); + n = _hull.size(); + memcpy(hull2->data.ptr, &_hull[0], n*sizeof(_hull[0])); + } + else if(_points.type() == CV_32SC2) + { + std::vector _hull; + cv::convexHull(_points, _hull, clockwise); + n = _hull.size(); + memcpy(hull2->data.ptr, &_hull[0], n*sizeof(_hull[0])); + } + else if(_points.type() == CV_32FC2) + { + std::vector _hull; + cv::convexHull(_points, _hull, clockwise); + n = _hull.size(); + memcpy(hull2->data.ptr, &_hull[0], n*sizeof(_hull[0])); + } + if(hull2->rows > hull2->cols) + hull2->rows = (int)n; + else + hull2->cols = (int)n; + } +} + + +int CV_ConvHullTest::validate_test_results( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + CvMat* hull = 0; + CvMat* mask = 0; + int i, point_count, hull_count; + CvPoint2D32f *p, *h; + CvSeq header, hheader, *ptseq, *hseq; + CvSeqBlock block, hblock; + + if( points1 ) + ptseq = points1; + else + ptseq = cvMakeSeqHeaderForArray( CV_MAT_TYPE(points2->type), + sizeof(CvSeq), CV_ELEM_SIZE(points2->type), points2->data.ptr, + points2->rows + points2->cols - 1, &header, &block ); + point_count = ptseq->total; + p = (CvPoint2D32f*)(points2->data.ptr); + + if( hull1 ) + hseq = hull1; + else + hseq = cvMakeSeqHeaderForArray( CV_MAT_TYPE(hull2->type), + sizeof(CvSeq), CV_ELEM_SIZE(hull2->type), hull2->data.ptr, + hull2->rows + hull2->cols - 1, &hheader, &hblock ); + hull_count = hseq->total; + hull = cvCreateMat( 1, hull_count, CV_32FC2 ); + mask = cvCreateMat( 1, hull_count, CV_8UC1 ); + cvZero( mask ); + h = (CvPoint2D32f*)(hull->data.ptr); + + // extract convex hull points + if( return_points ) + { + cvCvtSeqToArray( hseq, hull->data.ptr ); + if( CV_SEQ_ELTYPE(hseq) != CV_32FC2 ) + { + CvMat tmp = cvMat( hull->rows, hull->cols, CV_32SC2, hull->data.ptr ); + cvConvert( &tmp, hull ); + } + } + else + { + CvSeqReader reader; + cvStartReadSeq( hseq, &reader ); + + for( i = 0; i < hull_count; i++ ) + { + schar* ptr = reader.ptr; + int idx; + CV_NEXT_SEQ_ELEM( hseq->elem_size, reader ); + + if( hull1 ) + idx = cvSeqElemIdx( ptseq, *(uchar**)ptr ); + else + idx = *(int*)ptr; + + if( idx < 0 || idx >= point_count ) + { + ts->printf( cvtest::TS::LOG, "Invalid convex hull point #%d\n", i ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + h[i] = p[idx]; + } + } + + // check that the convex hull is a convex polygon + if( hull_count >= 3 ) + { + CvPoint2D32f pt0 = h[hull_count-1]; + for( i = 0; i < hull_count; i++ ) + { + int j = i+1; + CvPoint2D32f pt1 = h[i], pt2 = h[j < hull_count ? j : 0]; + float dx0 = pt1.x - pt0.x, dy0 = pt1.y - pt0.y; + float dx1 = pt2.x - pt1.x, dy1 = pt2.y - pt1.y; + double t = (double)dx0*dy1 - (double)dx1*dy0; + if( (t < 0) ^ (orientation != CV_COUNTER_CLOCKWISE) ) + { + ts->printf( cvtest::TS::LOG, "The convex hull is not convex or has a wrong orientation (vtx %d)\n", i ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + pt0 = pt1; + } + } + + // check that all the points are inside the hull or on the hull edge + // and at least hull_point points are at the hull vertices + for( i = 0; i < point_count; i++ ) + { + int idx = 0, on_edge = 0; + double pptresult = cvTsPointPolygonTest( p[i], h, hull_count, &idx, &on_edge ); + + if( pptresult < 0 ) + { + ts->printf( cvtest::TS::LOG, "The point #%d is outside of the convex hull\n", i ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + if( pptresult < FLT_EPSILON && !on_edge ) + mask->data.ptr[idx] = (uchar)1; + } + + if( cvNorm( mask, 0, CV_L1 ) != hull_count ) + { + ts->printf( cvtest::TS::LOG, "Not every convex hull vertex coincides with some input point\n" ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + +_exit_: + + cvReleaseMat( &hull ); + cvReleaseMat( &mask ); + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +/****************************************************************************************\ +* MinAreaRect Test * +\****************************************************************************************/ + +class CV_MinAreaRectTest : public CV_BaseShapeDescrTest +{ +public: + CV_MinAreaRectTest(); + +protected: + void run_func(void); + int validate_test_results( int test_case_idx ); + + CvBox2D box; + CvPoint2D32f box_pt[4]; +}; + + +CV_MinAreaRectTest::CV_MinAreaRectTest() +{ +} + + +void CV_MinAreaRectTest::run_func() +{ + if(!test_cpp) + { + box = cvMinAreaRect2( points, storage ); + cvBoxPoints( box, box_pt ); + } + else + { + cv::RotatedRect r = cv::minAreaRect(cv::cvarrToMat(points)); + box = (CvBox2D)r; + r.points((cv::Point2f*)box_pt); + } +} + + +int CV_MinAreaRectTest::validate_test_results( int test_case_idx ) +{ + double eps = 1e-1; + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + int i, j, point_count = points2->rows + points2->cols - 1; + CvPoint2D32f *p = (CvPoint2D32f*)(points2->data.ptr); + int mask[] = {0,0,0,0}; + + // check that the bounding box is a rotated rectangle: + // 1. diagonals should be equal + // 2. they must intersect in their middle points + { + double d0 = cvTsDist( box_pt[0], box_pt[2] ); + double d1 = cvTsDist( box_pt[1], box_pt[3] ); + + double x0 = (box_pt[0].x + box_pt[2].x)*0.5; + double y0 = (box_pt[0].y + box_pt[2].y)*0.5; + double x1 = (box_pt[1].x + box_pt[3].x)*0.5; + double y1 = (box_pt[1].y + box_pt[3].y)*0.5; + + if( fabs(d0 - d1) + fabs(x0 - x1) + fabs(y0 - y1) > eps*MAX(d0,d1) ) + { + ts->printf( cvtest::TS::LOG, "The bounding box is not a rectangle\n" ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + } + +#if 0 + { + int n = 4; + double a = 8, c = 8, b = 100, d = 150; + CvPoint bp[4], *bpp = bp; + cvNamedWindow( "test", 1 ); + IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); + cvZero(img); + for( i = 0; i < point_count; i++ ) + cvCircle(img,cvPoint(cvRound(p[i].x*a+b),cvRound(p[i].y*c+d)), 3, CV_RGB(0,255,0), -1 ); + for( i = 0; i < n; i++ ) + bp[i] = cvPoint(cvRound(box_pt[i].x*a+b),cvRound(box_pt[i].y*c+d)); + cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, CV_AA, 0 ); + cvShowImage( "test", img ); + cvWaitKey(); + cvReleaseImage(&img); + } +#endif + + // check that the box includes all the points + // and there is at least one point at (or very close to) every box side + for( i = 0; i < point_count; i++ ) + { + int idx = 0, on_edge = 0; + double pptresult = cvTsPointPolygonTest( p[i], box_pt, 4, &idx, &on_edge ); + if( pptresult < -eps ) + { + ts->printf( cvtest::TS::LOG, "The point #%d is outside of the box\n", i ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + if( pptresult < eps ) + { + for( j = 0; j < 4; j++ ) + { + double d = cvTsPtLineDist( p[i], box_pt[(j-1)&3], box_pt[j] ); + if( d < eps ) + mask[j] = (uchar)1; + } + } + } + + if( mask[0] + mask[1] + mask[2] + mask[3] != 4 ) + { + ts->printf( cvtest::TS::LOG, "Not every box side has a point nearby\n" ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + +_exit_: + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +/****************************************************************************************\ +* MinEnclosingCircle Test * +\****************************************************************************************/ + +class CV_MinCircleTest : public CV_BaseShapeDescrTest +{ +public: + CV_MinCircleTest(); + +protected: + void run_func(void); + int validate_test_results( int test_case_idx ); + + CvPoint2D32f center; + float radius; +}; + + +CV_MinCircleTest::CV_MinCircleTest() +{ +} + + +void CV_MinCircleTest::run_func() +{ + if(!test_cpp) + cvMinEnclosingCircle( points, ¢er, &radius ); + else + { + cv::Point2f tmpcenter; + cv::minEnclosingCircle(cv::cvarrToMat(points), tmpcenter, radius); + center = tmpcenter; + } +} + + +int CV_MinCircleTest::validate_test_results( int test_case_idx ) +{ + double eps = 1.03; + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + int i, j = 0, point_count = points2->rows + points2->cols - 1; + CvPoint2D32f *p = (CvPoint2D32f*)(points2->data.ptr); + CvPoint2D32f v[3]; + +#if 0 + { + double a = 2, b = 200, d = 400; + cvNamedWindow( "test", 1 ); + IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); + cvZero(img); + for( i = 0; i < point_count; i++ ) + cvCircle(img,cvPoint(cvRound(p[i].x*a+b),cvRound(p[i].y*a+d)), 3, CV_RGB(0,255,0), -1 ); + cvCircle( img, cvPoint(cvRound(center.x*a+b),cvRound(center.y*a+d)), + cvRound(radius*a), CV_RGB(255,255,0), 1 ); + cvShowImage( "test", img ); + cvWaitKey(); + cvReleaseImage(&img); + } +#endif + + // check that the circle contains all the points inside and + // remember at most 3 points that are close to the boundary + for( i = 0; i < point_count; i++ ) + { + double d = cvTsDist( p[i], center ); + if( d > radius ) + { + ts->printf( cvtest::TS::LOG, "The point #%d is outside of the circle\n", i ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + if( radius - d < eps*radius && j < 3 ) + v[j++] = p[i]; + } + + if( point_count >= 2 && (j < 2 || (j == 2 && cvTsDist(v[0],v[1]) < (radius-1)*2/eps)) ) + { + ts->printf( cvtest::TS::LOG, + "There should be at at least 3 points near the circle boundary or 2 points on the diameter\n" ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + +_exit_: + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +/****************************************************************************************\ +* Perimeter Test * +\****************************************************************************************/ + +class CV_PerimeterTest : public CV_BaseShapeDescrTest +{ +public: + CV_PerimeterTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + CvSlice slice; + int is_closed; + double result; +}; + + +CV_PerimeterTest::CV_PerimeterTest() +{ +} + + +int CV_PerimeterTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::prepare_test_case( test_case_idx ); + RNG& rng = ts->get_rng(); + int total; + + if( code < 0 ) + return code; + + is_closed = cvtest::randInt(rng) % 2; + + if( points1 ) + { + points1->flags |= CV_SEQ_KIND_CURVE; + if( is_closed ) + points1->flags |= CV_SEQ_FLAG_CLOSED; + total = points1->total; + } + else + total = points2->cols + points2->rows - 1; + + if( (cvtest::randInt(rng) % 3) && !test_cpp ) + { + slice.start_index = cvtest::randInt(rng) % total; + slice.end_index = cvtest::randInt(rng) % total; + } + else + slice = CV_WHOLE_SEQ; + + return 1; +} + + +void CV_PerimeterTest::run_func() +{ + if(!test_cpp) + result = cvArcLength( points, slice, points1 ? -1 : is_closed ); + else + result = cv::arcLength(cv::cvarrToMat(points), + !points1 ? is_closed != 0 : (points1->flags & CV_SEQ_FLAG_CLOSED) != 0); +} + + +int CV_PerimeterTest::validate_test_results( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + int i, len = slice.end_index - slice.start_index, total = points2->cols + points2->rows - 1; + double result0 = 0; + CvPoint2D32f prev_pt, pt, *ptr; + + if( len < 0 ) + len += total; + + len = MIN( len, total ); + //len -= !is_closed && len == total; + + ptr = (CvPoint2D32f*)points2->data.fl; + prev_pt = ptr[(is_closed ? slice.start_index+len-1 : slice.start_index) % total]; + + for( i = 0; i < len + (len < total && (!is_closed || len==1)); i++ ) + { + pt = ptr[(i + slice.start_index) % total]; + double dx = pt.x - prev_pt.x, dy = pt.y - prev_pt.y; + result0 += sqrt(dx*dx + dy*dy); + prev_pt = pt; + } + + if( cvIsNaN(result) || cvIsInf(result) ) + { + ts->printf( cvtest::TS::LOG, "cvArcLength() returned invalid value (%g)\n", result ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + else if( fabs(result - result0) > FLT_EPSILON*100*result0 ) + { + ts->printf( cvtest::TS::LOG, "The function returned %g, while the correct result is %g\n", result, result0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +/****************************************************************************************\ +* FitEllipse Test * +\****************************************************************************************/ + +class CV_FitEllipseTest : public CV_BaseShapeDescrTest +{ +public: + CV_FitEllipseTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void generate_point_set( void* points ); + void run_func(void); + int validate_test_results( int test_case_idx ); + CvBox2D box0, box; + double min_ellipse_size, max_noise; +}; + + +CV_FitEllipseTest::CV_FitEllipseTest() +{ + min_log_size = 5; // for robust ellipse fitting a dozen of points is needed at least + max_log_size = 10; + min_ellipse_size = 10; + max_noise = 0.05; +} + + +void CV_FitEllipseTest::generate_point_set( void* pointsSet ) +{ + RNG& rng = ts->get_rng(); + int i, total, point_type; + CvSeqReader reader; + uchar* data = 0; + double a, b; + + box0.center.x = (float)((low.val[0] + high.val[0])*0.5); + box0.center.y = (float)((low.val[1] + high.val[1])*0.5); + box0.size.width = (float)(MAX(high.val[0] - low.val[0], min_ellipse_size)*2); + box0.size.height = (float)(MAX(high.val[1] - low.val[1], min_ellipse_size)*2); + box0.angle = (float)(cvtest::randReal(rng)*180); + a = cos(box0.angle*CV_PI/180.); + b = sin(box0.angle*CV_PI/180.); + + if( box0.size.width > box0.size.height ) + { + float t; + CV_SWAP( box0.size.width, box0.size.height, t ); + } + memset( &reader, 0, sizeof(reader) ); + + if( CV_IS_SEQ(pointsSet) ) + { + CvSeq* ptseq = (CvSeq*)pointsSet; + total = ptseq->total; + point_type = CV_SEQ_ELTYPE(ptseq); + cvStartReadSeq( ptseq, &reader ); + } + else + { + CvMat* ptm = (CvMat*)pointsSet; + assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) ); + total = ptm->rows + ptm->cols - 1; + point_type = CV_MAT_TYPE(ptm->type); + data = ptm->data.ptr; + } + + assert( point_type == CV_32SC2 || point_type == CV_32FC2 ); + + for( i = 0; i < total; i++ ) + { + CvPoint* pp; + CvPoint2D32f p; + double angle = cvtest::randReal(rng)*CV_PI*2; + double x = box0.size.height*0.5*(cos(angle) + (cvtest::randReal(rng)-0.5)*2*max_noise); + double y = box0.size.width*0.5*(sin(angle) + (cvtest::randReal(rng)-0.5)*2*max_noise); + p.x = (float)(box0.center.x + a*x + b*y); + p.y = (float)(box0.center.y - b*x + a*y); + + if( reader.ptr ) + { + pp = (CvPoint*)reader.ptr; + CV_NEXT_SEQ_ELEM( sizeof(*pp), reader ); + } + else + pp = ((CvPoint*)data) + i; + if( point_type == CV_32SC2 ) + { + pp->x = cvRound(p.x); + pp->y = cvRound(p.y); + } + else + *(CvPoint2D32f*)pp = p; + } +} + + +int CV_FitEllipseTest::prepare_test_case( int test_case_idx ) +{ + min_log_size = MAX(min_log_size,4); + max_log_size = MAX(min_log_size,max_log_size); + return CV_BaseShapeDescrTest::prepare_test_case( test_case_idx ); +} + + +void CV_FitEllipseTest::run_func() +{ + if(!test_cpp) + box = cvFitEllipse2( points ); + else + box = (CvBox2D)cv::fitEllipse(cv::cvarrToMat(points)); +} + + +int CV_FitEllipseTest::validate_test_results( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + double diff_angle; + + if( cvIsNaN(box.center.x) || cvIsInf(box.center.x) || + cvIsNaN(box.center.y) || cvIsInf(box.center.y) || + cvIsNaN(box.size.width) || cvIsInf(box.size.width) || + cvIsNaN(box.size.height) || cvIsInf(box.size.height) || + cvIsNaN(box.angle) || cvIsInf(box.angle) ) + { + ts->printf( cvtest::TS::LOG, "Some of the computed ellipse parameters are invalid (x=%g,y=%g,w=%g,h=%g,angle=%g)\n", + box.center.x, box.center.y, box.size.width, box.size.height, box.angle ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + + box.angle = (float)(90-box.angle); + if( box.angle < 0 ) + box.angle += 360; + if( box.angle > 360 ) + box.angle -= 360; + + if( fabs(box.center.x - box0.center.x) > 3 || + fabs(box.center.y - box0.center.y) > 3 || + fabs(box.size.width - box0.size.width) > 0.1*fabs(box0.size.width) || + fabs(box.size.height - box0.size.height) > 0.1*fabs(box0.size.height) ) + { + ts->printf( cvtest::TS::LOG, "The computed ellipse center and/or size are incorrect:\n\t" + "(x=%.1f,y=%.1f,w=%.1f,h=%.1f), while it should be (x=%.1f,y=%.1f,w=%.1f,h=%.1f)\n", + box.center.x, box.center.y, box.size.width, box.size.height, + box0.center.x, box0.center.y, box0.size.width, box0.size.height ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + diff_angle = fabs(box0.angle - box.angle); + diff_angle = MIN( diff_angle, fabs(diff_angle - 360)); + diff_angle = MIN( diff_angle, fabs(diff_angle - 180)); + + if( box0.size.height >= 1.3*box0.size.width && diff_angle > 30 ) + { + ts->printf( cvtest::TS::LOG, "Incorrect ellipse angle (=%1.f, should be %1.f)\n", + box.angle, box0.angle ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + +_exit_: + +#if 0 + if( code < 0 ) + { + cvNamedWindow( "test", 0 ); + IplImage* img = cvCreateImage( cvSize(cvRound(low_high_range*4), + cvRound(low_high_range*4)), 8, 3 ); + cvZero( img ); + + box.center.x += (float)low_high_range*2; + box.center.y += (float)low_high_range*2; + cvEllipseBox( img, box, CV_RGB(255,0,0), 3, 8 ); + + for( int i = 0; i < points2->rows + points2->cols - 1; i++ ) + { + CvPoint pt; + pt.x = cvRound(points2->data.fl[i*2] + low_high_range*2); + pt.y = cvRound(points2->data.fl[i*2+1] + low_high_range*2); + cvCircle( img, pt, 1, CV_RGB(255,255,255), -1, 8 ); + } + + cvShowImage( "test", img ); + cvReleaseImage( &img ); + cvWaitKey(0); + } +#endif + + if( code < 0 ) + { + ts->set_failed_test_info( code ); + } + return code; +} + + +class CV_FitEllipseSmallTest : public cvtest::BaseTest +{ +public: + CV_FitEllipseSmallTest() {} + ~CV_FitEllipseSmallTest() {} +protected: + void run(int) + { + Size sz(50, 50); + vector > c; + c.push_back(vector()); + int scale = 1; + Point ofs = Point(0,0);//sz.width/2, sz.height/2) - Point(4,4)*scale; + c[0].push_back(Point(2, 0)*scale+ofs); + c[0].push_back(Point(0, 2)*scale+ofs); + c[0].push_back(Point(0, 6)*scale+ofs); + c[0].push_back(Point(2, 8)*scale+ofs); + c[0].push_back(Point(6, 8)*scale+ofs); + c[0].push_back(Point(8, 6)*scale+ofs); + c[0].push_back(Point(8, 2)*scale+ofs); + c[0].push_back(Point(6, 0)*scale+ofs); + + RotatedRect e = fitEllipse(c[0]); + CV_Assert( fabs(e.center.x - 4) <= 1. && + fabs(e.center.y - 4) <= 1. && + fabs(e.size.width - 9) <= 1. && + fabs(e.size.height - 9) <= 1. ); + } +}; + +/****************************************************************************************\ +* FitLine Test * +\****************************************************************************************/ + +class CV_FitLineTest : public CV_BaseShapeDescrTest +{ +public: + CV_FitLineTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void generate_point_set( void* points ); + void run_func(void); + int validate_test_results( int test_case_idx ); + double max_noise; + float line[6], line0[6]; + int dist_type; + double reps, aeps; +}; + + +CV_FitLineTest::CV_FitLineTest() +{ + min_log_size = 5; // for robust ellipse fitting a dozen of points is needed at least + max_log_size = 10; + max_noise = 0.05; +} + + +void CV_FitLineTest::generate_point_set( void* pointsSet ) +{ + RNG& rng = ts->get_rng(); + int i, k, n, total, point_type; + CvSeqReader reader; + uchar* data = 0; + double s = 0; + + n = dims; + for( k = 0; k < n; k++ ) + { + line0[k+n] = (float)((low.val[k] + high.val[k])*0.5); + line0[k] = (float)(high.val[k] - low.val[k]); + if( cvtest::randInt(rng) % 2 ) + line0[k] = -line0[k]; + s += (double)line0[k]*line0[k]; + } + + s = 1./sqrt(s); + for( k = 0; k < n; k++ ) + line0[k] = (float)(line0[k]*s); + + memset( &reader, 0, sizeof(reader) ); + + if( CV_IS_SEQ(pointsSet) ) + { + CvSeq* ptseq = (CvSeq*)pointsSet; + total = ptseq->total; + point_type = CV_MAT_DEPTH(CV_SEQ_ELTYPE(ptseq)); + cvStartReadSeq( ptseq, &reader ); + } + else + { + CvMat* ptm = (CvMat*)pointsSet; + assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) ); + total = ptm->rows + ptm->cols - 1; + point_type = CV_MAT_DEPTH(CV_MAT_TYPE(ptm->type)); + data = ptm->data.ptr; + } + + for( i = 0; i < total; i++ ) + { + int* pi; + float* pf; + float p[4], t; + if( reader.ptr ) + { + pi = (int*)reader.ptr; + pf = (float*)reader.ptr; + CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); + } + else + { + pi = (int*)data + i*n; + pf = (float*)data + i*n; + } + + t = (float)((cvtest::randReal(rng)-0.5)*low_high_range*2); + + for( k = 0; k < n; k++ ) + p[k] = (float)((cvtest::randReal(rng)-0.5)*max_noise*2 + t*line0[k] + line0[k+n]); + + if( point_type == CV_32S ) + for( k = 0; k < n; k++ ) + pi[k] = cvRound(p[k]); + else + for( k = 0; k < n; k++ ) + pf[k] = p[k]; + } +} + + +int CV_FitLineTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + dims = cvtest::randInt(rng) % 2 + 2; + min_log_size = MAX(min_log_size,5); + max_log_size = MAX(min_log_size,max_log_size); + int code = CV_BaseShapeDescrTest::prepare_test_case( test_case_idx ); + dist_type = cvtest::randInt(rng) % 6 + 1; + dist_type += dist_type == CV_DIST_C; + reps = 0.1; aeps = 0.01; + return code; +} + + +void CV_FitLineTest::run_func() +{ + if(!test_cpp) + cvFitLine( points, dist_type, 0, reps, aeps, line ); + else if(dims == 2) + cv::fitLine(cv::cvarrToMat(points), (cv::Vec4f&)line[0], dist_type, 0, reps, aeps); + else + cv::fitLine(cv::cvarrToMat(points), (cv::Vec6f&)line[0], dist_type, 0, reps, aeps); +} + + +int CV_FitLineTest::validate_test_results( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + int k, max_k = 0; + double vec_diff = 0, t; + + for( k = 0; k < dims*2; k++ ) + { + if( cvIsNaN(line[k]) || cvIsInf(line[k]) ) + { + ts->printf( cvtest::TS::LOG, "Some of the computed line parameters are invalid (line[%d]=%g)\n", + k, line[k] ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + goto _exit_; + } + } + + if( fabs(line0[1]) > fabs(line0[0]) ) + max_k = 1; + if( fabs(line0[dims-1]) > fabs(line0[max_k]) ) + max_k = dims-1; + if( line0[max_k] < 0 ) + for( k = 0; k < dims; k++ ) + line0[k] = -line0[k]; + if( line[max_k] < 0 ) + for( k = 0; k < dims; k++ ) + line[k] = -line[k]; + + for( k = 0; k < dims; k++ ) + { + double dt = line[k] - line0[k]; + vec_diff += dt*dt; + } + + if( sqrt(vec_diff) > 0.05 ) + { + if( dims == 2 ) + ts->printf( cvtest::TS::LOG, + "The computed line vector (%.2f,%.2f) is different from the actual (%.2f,%.2f)\n", + line[0], line[1], line0[0], line0[1] ); + else + ts->printf( cvtest::TS::LOG, + "The computed line vector (%.2f,%.2f,%.2f) is different from the actual (%.2f,%.2f,%.2f)\n", + line[0], line[1], line[2], line0[0], line0[1], line0[2] ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + + t = (line[max_k+dims] - line0[max_k+dims])/line0[max_k]; + for( k = 0; k < dims; k++ ) + { + double p = line0[k+dims] + t*line0[k] - line[k+dims]; + vec_diff += p*p; + } + + if( sqrt(vec_diff) > 1*MAX(fabs(t),1) ) + { + if( dims == 2 ) + ts->printf( cvtest::TS::LOG, + "The computed line point (%.2f,%.2f) is too far from the actual line\n", + line[2]+line0[2], line[3]+line0[3] ); + else + ts->printf( cvtest::TS::LOG, + "The computed line point (%.2f,%.2f,%.2f) is too far from the actual line\n", + line[3]+line0[3], line[4]+line0[4], line[5]+line0[5] ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + goto _exit_; + } + +_exit_: + + if( code < 0 ) + { + ts->set_failed_test_info( code ); + } + return code; +} + + +/****************************************************************************************\ +* ContourMoments Test * +\****************************************************************************************/ + + +static void +cvTsGenerateTousledBlob( CvPoint2D32f center, CvSize2D32f axes, + double max_r_scale, double angle, CvArr* points, RNG& rng ) +{ + int i, total, point_type; + uchar* data = 0; + CvSeqReader reader; + memset( &reader, 0, sizeof(reader) ); + + if( CV_IS_SEQ(points) ) + { + CvSeq* ptseq = (CvSeq*)points; + total = ptseq->total; + point_type = CV_SEQ_ELTYPE(ptseq); + cvStartReadSeq( ptseq, &reader ); + } + else + { + CvMat* ptm = (CvMat*)points; + assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) ); + total = ptm->rows + ptm->cols - 1; + point_type = CV_MAT_TYPE(ptm->type); + data = ptm->data.ptr; + } + + assert( point_type == CV_32SC2 || point_type == CV_32FC2 ); + + for( i = 0; i < total; i++ ) + { + CvPoint* pp; + CvPoint2D32f p; + + double phi0 = 2*CV_PI*i/total; + double phi = CV_PI*angle/180.; + double t = cvtest::randReal(rng)*max_r_scale + (1 - max_r_scale); + double ta = axes.height*t; + double tb = axes.width*t; + double c0 = cos(phi0)*ta, s0 = sin(phi0)*tb; + double c = cos(phi), s = sin(phi); + p.x = (float)(c0*c - s0*s + center.x); + p.y = (float)(c0*s + s0*c + center.y); + + if( reader.ptr ) + { + pp = (CvPoint*)reader.ptr; + CV_NEXT_SEQ_ELEM( sizeof(*pp), reader ); + } + else + pp = ((CvPoint*)data) + i; + + if( point_type == CV_32SC2 ) + { + pp->x = cvRound(p.x); + pp->y = cvRound(p.y); + } + else + *(CvPoint2D32f*)pp = p; + } +} + + +class CV_ContourMomentsTest : public CV_BaseShapeDescrTest +{ +public: + CV_ContourMomentsTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void generate_point_set( void* points ); + void run_func(void); + int validate_test_results( int test_case_idx ); + CvMoments moments0, moments; + double area0, area; + CvSize2D32f axes; + CvPoint2D32f center; + int max_max_r_scale; + double max_r_scale, angle; + CvSize img_size; +}; + + +CV_ContourMomentsTest::CV_ContourMomentsTest() +{ + min_log_size = 3; + max_log_size = 8; + max_max_r_scale = 15; + low_high_range = 200; + enable_flt_points = false; +} + + +void CV_ContourMomentsTest::generate_point_set( void* pointsSet ) +{ + RNG& rng = ts->get_rng(); + float max_sz; + + axes.width = (float)((cvtest::randReal(rng)*0.9 + 0.1)*low_high_range); + axes.height = (float)((cvtest::randReal(rng)*0.9 + 0.1)*low_high_range); + max_sz = MAX(axes.width, axes.height); + + img_size.width = img_size.height = cvRound(low_high_range*2.2); + + center.x = (float)(img_size.width*0.5 + (cvtest::randReal(rng)-0.5)*(img_size.width - max_sz*2)*0.8); + center.y = (float)(img_size.height*0.5 + (cvtest::randReal(rng)-0.5)*(img_size.height - max_sz*2)*0.8); + + assert( 0 < center.x - max_sz && center.x + max_sz < img_size.width && + 0 < center.y - max_sz && center.y + max_sz < img_size.height ); + + max_r_scale = cvtest::randReal(rng)*max_max_r_scale*0.01; + angle = cvtest::randReal(rng)*360; + + cvTsGenerateTousledBlob( center, axes, max_r_scale, angle, pointsSet, rng ); + + if( points1 ) + points1->flags = CV_SEQ_MAGIC_VAL + CV_SEQ_POLYGON; +} + + +int CV_ContourMomentsTest::prepare_test_case( int test_case_idx ) +{ + min_log_size = MAX(min_log_size,3); + max_log_size = MIN(max_log_size,8); + max_log_size = MAX(min_log_size,max_log_size); + int code = CV_BaseShapeDescrTest::prepare_test_case( test_case_idx ); + return code; +} + + +void CV_ContourMomentsTest::run_func() +{ + if(!test_cpp) + { + cvMoments( points, &moments ); + area = cvContourArea( points ); + } + else + { + moments = (CvMoments)cv::moments(cv::cvarrToMat(points)); + area = cv::contourArea(cv::cvarrToMat(points)); + } +} + + +int CV_ContourMomentsTest::validate_test_results( int test_case_idx ) +{ + int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx ); + int i, n = (int)(sizeof(moments)/sizeof(moments.inv_sqrt_m00)); + CvMat* img = cvCreateMat( img_size.height, img_size.width, CV_8UC1 ); + CvPoint* pt = (CvPoint*)points2->data.i; + int count = points2->cols + points2->rows - 1; + double max_v0 = 0; + + cvZero(img); + cvFillPoly( img, &pt, &count, 1, cvScalarAll(1)); + cvMoments( img, &moments0 ); + + for( i = 0; i < n; i++ ) + { + double t = fabs((&moments0.m00)[i]); + max_v0 = MAX(max_v0, t); + } + + for( i = 0; i <= n; i++ ) + { + double v = i < n ? (&moments.m00)[i] : area; + double v0 = i < n ? (&moments0.m00)[i] : moments0.m00; + + if( cvIsNaN(v) || cvIsInf(v) ) + { + ts->printf( cvtest::TS::LOG, + "The contour %s is invalid (=%g)\n", i < n ? "moment" : "area", v ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + break; + } + + if( fabs(v - v0) > 0.1*max_v0 ) + { + ts->printf( cvtest::TS::LOG, + "The computed contour %s is %g, while it should be %g\n", + i < n ? "moment" : "area", v, v0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + break; + } + } + + if( code < 0 ) + { +#if 0 + cvCmpS( img, 0, img, CV_CMP_GT ); + cvNamedWindow( "test", 1 ); + cvShowImage( "test", img ); + cvWaitKey(); +#endif + ts->set_failed_test_info( code ); + } + + cvReleaseMat( &img ); + return code; +} + + +////////////////////////////////////// Perimeter/Area/Slice test /////////////////////////////////// + +class CV_PerimeterAreaSliceTest : public cvtest::BaseTest +{ +public: + CV_PerimeterAreaSliceTest(); + ~CV_PerimeterAreaSliceTest(); +protected: + void run(int); +}; + +CV_PerimeterAreaSliceTest::CV_PerimeterAreaSliceTest() +{ +} +CV_PerimeterAreaSliceTest::~CV_PerimeterAreaSliceTest() {} + +void CV_PerimeterAreaSliceTest::run( int ) +{ + Ptr storage = cvCreateMemStorage(); + RNG& rng = theRNG(); + const double min_r = 90, max_r = 120; + + for( int i = 0; i < 100; i++ ) + { + ts->update_context( this, i, true ); + int n = rng.uniform(3, 30); + cvClearMemStorage(storage); + CvSeq* contour = cvCreateSeq(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(CvPoint), storage); + double dphi = CV_PI*2/n; + CvPoint center; + center.x = rng.uniform(cvCeil(max_r), cvFloor(640-max_r)); + center.y = rng.uniform(cvCeil(max_r), cvFloor(480-max_r)); + + for( int j = 0; j < n; j++ ) + { + CvPoint pt; + double r = rng.uniform(min_r, max_r); + double phi = j*dphi; + pt.x = cvRound(center.x + r*cos(phi)); + pt.y = cvRound(center.y - r*sin(phi)); + cvSeqPush(contour, &pt); + } + + CvSlice slice; + for(;;) + { + slice.start_index = rng.uniform(-n/2, 3*n/2); + slice.end_index = rng.uniform(-n/2, 3*n/2); + int len = cvSliceLength(slice, contour); + if( len > 2 ) + break; + } + CvSeq *cslice = cvSeqSlice(contour, slice); + /*printf( "%d. (%d, %d) of %d, length = %d, length1 = %d\n", + i, slice.start_index, slice.end_index, + contour->total, cvSliceLength(slice, contour), cslice->total ); + + double area0 = cvContourArea(cslice); + double area1 = cvContourArea(contour, slice); + if( area0 != area1 ) + { + ts->printf(cvtest::TS::LOG, + "The contour area slice is computed differently (%g vs %g)\n", area0, area1 ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + }*/ + + double len0 = cvArcLength(cslice, CV_WHOLE_SEQ, 1); + double len1 = cvArcLength(contour, slice, 1); + if( len0 != len1 ) + { + ts->printf(cvtest::TS::LOG, + "The contour arc length is computed differently (%g vs %g)\n", len0, len1 ); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + return; + } + } + ts->set_failed_test_info(cvtest::TS::OK); +} + + +TEST(Imgproc_ConvexHull, accuracy) { CV_ConvHullTest test; test.safe_run(); } +TEST(Imgproc_MinAreaRect, accuracy) { CV_MinAreaRectTest test; test.safe_run(); } +TEST(Imgproc_MinCircle, accuracy) { CV_MinCircleTest test; test.safe_run(); } +TEST(Imgproc_ContourPerimeter, accuracy) { CV_PerimeterTest test; test.safe_run(); } +TEST(Imgproc_FitEllipse, accuracy) { CV_FitEllipseTest test; test.safe_run(); } +TEST(Imgproc_FitLine, accuracy) { CV_FitLineTest test; test.safe_run(); } +TEST(Imgproc_ContourMoments, accuracy) { CV_ContourMomentsTest test; test.safe_run(); } +TEST(Imgproc_ContourPerimeterSlice, accuracy) { CV_PerimeterAreaSliceTest test; test.safe_run(); } +TEST(Imgproc_FitEllipse, small) { CV_FitEllipseSmallTest test; test.safe_run(); } + +/* End of file. */ + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_cvtyuv.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_cvtyuv.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_cvtyuv.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_cvtyuv.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,708 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +#undef RGB +#undef YUV + +typedef Vec3b YUV; +typedef Vec3b RGB; + +int countOfDifferencies(const Mat& gold, const Mat& result, int maxAllowedDifference = 1) +{ + Mat diff; + absdiff(gold, result, diff); + return countNonZero(diff.reshape(1) > maxAllowedDifference); +} + +class YUVreader +{ +public: + virtual ~YUVreader() {} + virtual YUV read(const Mat& yuv, int row, int col) = 0; + virtual int channels() = 0; + virtual Size size(Size imgSize) = 0; + + virtual bool requiresEvenHeight() { return true; } + virtual bool requiresEvenWidth() { return true; } + + static YUVreader* getReader(int code); +}; + +class RGBreader +{ +public: + virtual ~RGBreader() {} + virtual RGB read(const Mat& rgb, int row, int col) = 0; + virtual int channels() = 0; + + static RGBreader* getReader(int code); +}; + +class RGBwriter +{ +public: + virtual ~RGBwriter() {} + + virtual void write(Mat& rgb, int row, int col, const RGB& val) = 0; + virtual int channels() = 0; + + static RGBwriter* getWriter(int code); +}; + +class GRAYwriter +{ +public: + virtual ~GRAYwriter() {} + + virtual void write(Mat& gray, int row, int col, const uchar& val) + { + gray.at(row, col) = val; + } + + virtual int channels() { return 1; } + + static GRAYwriter* getWriter(int code); +}; + +class YUVwriter +{ +public: + virtual ~YUVwriter() {} + + virtual void write(Mat& yuv, int row, int col, const YUV& val) = 0; + virtual int channels() = 0; + virtual Size size(Size imgSize) = 0; + + virtual bool requiresEvenHeight() { return true; } + virtual bool requiresEvenWidth() { return true; } + + static YUVwriter* getWriter(int code); +}; + +class RGB888Writer : public RGBwriter +{ + void write(Mat& rgb, int row, int col, const RGB& val) + { + rgb.at(row, col) = val; + } + + int channels() { return 3; } +}; + +class BGR888Writer : public RGBwriter +{ + void write(Mat& rgb, int row, int col, const RGB& val) + { + Vec3b tmp(val[2], val[1], val[0]); + rgb.at(row, col) = tmp; + } + + int channels() { return 3; } +}; + +class RGBA8888Writer : public RGBwriter +{ + void write(Mat& rgb, int row, int col, const RGB& val) + { + Vec4b tmp(val[0], val[1], val[2], 255); + rgb.at(row, col) = tmp; + } + + int channels() { return 4; } +}; + +class BGRA8888Writer : public RGBwriter +{ + void write(Mat& rgb, int row, int col, const RGB& val) + { + Vec4b tmp(val[2], val[1], val[0], 255); + rgb.at(row, col) = tmp; + } + + int channels() { return 4; } +}; + +class YUV420pWriter: public YUVwriter +{ + int channels() { return 1; } + Size size(Size imgSize) { return Size(imgSize.width, imgSize.height + imgSize.height/2); } +}; + +class YV12Writer: public YUV420pWriter +{ + void write(Mat& yuv, int row, int col, const YUV& val) + { + int h = yuv.rows * 2 / 3; + + yuv.ptr(row)[col] = val[0]; + if( row % 2 == 0 && col % 2 == 0 ) + { + yuv.ptr(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)] = val[2]; + yuv.ptr(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)] = val[1]; + } + } +}; + +class I420Writer: public YUV420pWriter +{ + void write(Mat& yuv, int row, int col, const YUV& val) + { + int h = yuv.rows * 2 / 3; + + yuv.ptr(row)[col] = val[0]; + if( row % 2 == 0 && col % 2 == 0 ) + { + yuv.ptr(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)] = val[1]; + yuv.ptr(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)] = val[2]; + } + } +}; + +class YUV420Reader: public YUVreader +{ + int channels() { return 1; } + Size size(Size imgSize) { return Size(imgSize.width, imgSize.height * 3 / 2); } +}; + +class YUV422Reader: public YUVreader +{ + int channels() { return 2; } + Size size(Size imgSize) { return imgSize; } + bool requiresEvenHeight() { return false; } +}; + +class NV21Reader: public YUV420Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + uchar y = yuv.ptr(row)[col]; + uchar u = yuv.ptr(yuv.rows * 2 / 3 + row/2)[(col/2)*2 + 1]; + uchar v = yuv.ptr(yuv.rows * 2 / 3 + row/2)[(col/2)*2]; + + return YUV(y, u, v); + } +}; + + +struct NV12Reader: public YUV420Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + uchar y = yuv.ptr(row)[col]; + uchar u = yuv.ptr(yuv.rows * 2 / 3 + row/2)[(col/2)*2]; + uchar v = yuv.ptr(yuv.rows * 2 / 3 + row/2)[(col/2)*2 + 1]; + + return YUV(y, u, v); + } +}; + +class YV12Reader: public YUV420Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + int h = yuv.rows * 2 / 3; + uchar y = yuv.ptr(row)[col]; + uchar u = yuv.ptr(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)]; + uchar v = yuv.ptr(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)]; + + return YUV(y, u, v); + } +}; + +class IYUVReader: public YUV420Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + int h = yuv.rows * 2 / 3; + uchar y = yuv.ptr(row)[col]; + uchar u = yuv.ptr(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)]; + uchar v = yuv.ptr(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)]; + + return YUV(y, u, v); + } +}; + +class UYVYReader: public YUV422Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + uchar y = yuv.ptr(row)[col][1]; + uchar u = yuv.ptr(row)[(col/2)*2][0]; + uchar v = yuv.ptr(row)[(col/2)*2 + 1][0]; + + return YUV(y, u, v); + } +}; + +class YUY2Reader: public YUV422Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + uchar y = yuv.ptr(row)[col][0]; + uchar u = yuv.ptr(row)[(col/2)*2][1]; + uchar v = yuv.ptr(row)[(col/2)*2 + 1][1]; + + return YUV(y, u, v); + } +}; + +class YVYUReader: public YUV422Reader +{ + YUV read(const Mat& yuv, int row, int col) + { + uchar y = yuv.ptr(row)[col][0]; + uchar u = yuv.ptr(row)[(col/2)*2 + 1][1]; + uchar v = yuv.ptr(row)[(col/2)*2][1]; + + return YUV(y, u, v); + } +}; + +class YUV888Reader : public YUVreader +{ + YUV read(const Mat& yuv, int row, int col) + { + return yuv.at(row, col); + } + + int channels() { return 3; } + Size size(Size imgSize) { return imgSize; } + bool requiresEvenHeight() { return false; } + bool requiresEvenWidth() { return false; } +}; + +class RGB888Reader : public RGBreader +{ + RGB read(const Mat& rgb, int row, int col) + { + return rgb.at(row, col); + } + + int channels() { return 3; } +}; + +class BGR888Reader : public RGBreader +{ + RGB read(const Mat& rgb, int row, int col) + { + RGB tmp = rgb.at(row, col); + return RGB(tmp[2], tmp[1], tmp[0]); + } + + int channels() { return 3; } +}; + +class RGBA8888Reader : public RGBreader +{ + RGB read(const Mat& rgb, int row, int col) + { + Vec4b rgba = rgb.at(row, col); + return RGB(rgba[0], rgba[1], rgba[2]); + } + + int channels() { return 4; } +}; + +class BGRA8888Reader : public RGBreader +{ + RGB read(const Mat& rgb, int row, int col) + { + Vec4b rgba = rgb.at(row, col); + return RGB(rgba[2], rgba[1], rgba[0]); + } + + int channels() { return 4; } +}; + +class YUV2RGB_Converter +{ +public: + RGB convert(YUV yuv) + { + int y = std::max(0, yuv[0] - 16); + int u = yuv[1] - 128; + int v = yuv[2] - 128; + uchar r = saturate_cast(1.164f * y + 1.596f * v); + uchar g = saturate_cast(1.164f * y - 0.813f * v - 0.391f * u); + uchar b = saturate_cast(1.164f * y + 2.018f * u); + + return RGB(r, g, b); + } +}; + +class YUV2GRAY_Converter +{ +public: + uchar convert(YUV yuv) + { + return yuv[0]; + } +}; + +class RGB2YUV_Converter +{ +public: + YUV convert(RGB rgb) + { + int r = rgb[0]; + int g = rgb[1]; + int b = rgb[2]; + + uchar y = saturate_cast((int)( 0.257f*r + 0.504f*g + 0.098f*b + 0.5f) + 16); + uchar u = saturate_cast((int)(-0.148f*r - 0.291f*g + 0.439f*b + 0.5f) + 128); + uchar v = saturate_cast((int)( 0.439f*r - 0.368f*g - 0.071f*b + 0.5f) + 128); + + return YUV(y, u, v); + } +}; + +YUVreader* YUVreader::getReader(int code) +{ + switch(code) + { + case CV_YUV2RGB_NV12: + case CV_YUV2BGR_NV12: + case CV_YUV2RGBA_NV12: + case CV_YUV2BGRA_NV12: + return new NV12Reader(); + case CV_YUV2RGB_NV21: + case CV_YUV2BGR_NV21: + case CV_YUV2RGBA_NV21: + case CV_YUV2BGRA_NV21: + return new NV21Reader(); + case CV_YUV2RGB_YV12: + case CV_YUV2BGR_YV12: + case CV_YUV2RGBA_YV12: + case CV_YUV2BGRA_YV12: + return new YV12Reader(); + case CV_YUV2RGB_IYUV: + case CV_YUV2BGR_IYUV: + case CV_YUV2RGBA_IYUV: + case CV_YUV2BGRA_IYUV: + return new IYUVReader(); + case CV_YUV2RGB_UYVY: + case CV_YUV2BGR_UYVY: + case CV_YUV2RGBA_UYVY: + case CV_YUV2BGRA_UYVY: + return new UYVYReader(); + //case CV_YUV2RGB_VYUY = 109, + //case CV_YUV2BGR_VYUY = 110, + //case CV_YUV2RGBA_VYUY = 113, + //case CV_YUV2BGRA_VYUY = 114, + // return ?? + case CV_YUV2RGB_YUY2: + case CV_YUV2BGR_YUY2: + case CV_YUV2RGBA_YUY2: + case CV_YUV2BGRA_YUY2: + return new YUY2Reader(); + case CV_YUV2RGB_YVYU: + case CV_YUV2BGR_YVYU: + case CV_YUV2RGBA_YVYU: + case CV_YUV2BGRA_YVYU: + return new YVYUReader(); + case CV_YUV2GRAY_420: + return new NV21Reader(); + case CV_YUV2GRAY_UYVY: + return new UYVYReader(); + case CV_YUV2GRAY_YUY2: + return new YUY2Reader(); + case CV_YUV2BGR: + case CV_YUV2RGB: + return new YUV888Reader(); + default: + return 0; + } +} + +RGBreader* RGBreader::getReader(int code) +{ + switch(code) + { + case CV_RGB2YUV_YV12: + case CV_RGB2YUV_I420: + return new RGB888Reader(); + case CV_BGR2YUV_YV12: + case CV_BGR2YUV_I420: + return new BGR888Reader(); + case CV_RGBA2YUV_I420: + case CV_RGBA2YUV_YV12: + return new RGBA8888Reader(); + case CV_BGRA2YUV_YV12: + case CV_BGRA2YUV_I420: + return new BGRA8888Reader(); + default: + return 0; + }; +} + +RGBwriter* RGBwriter::getWriter(int code) +{ + switch(code) + { + case CV_YUV2RGB_NV12: + case CV_YUV2RGB_NV21: + case CV_YUV2RGB_YV12: + case CV_YUV2RGB_IYUV: + case CV_YUV2RGB_UYVY: + //case CV_YUV2RGB_VYUY: + case CV_YUV2RGB_YUY2: + case CV_YUV2RGB_YVYU: + case CV_YUV2RGB: + return new RGB888Writer(); + case CV_YUV2BGR_NV12: + case CV_YUV2BGR_NV21: + case CV_YUV2BGR_YV12: + case CV_YUV2BGR_IYUV: + case CV_YUV2BGR_UYVY: + //case CV_YUV2BGR_VYUY: + case CV_YUV2BGR_YUY2: + case CV_YUV2BGR_YVYU: + case CV_YUV2BGR: + return new BGR888Writer(); + case CV_YUV2RGBA_NV12: + case CV_YUV2RGBA_NV21: + case CV_YUV2RGBA_YV12: + case CV_YUV2RGBA_IYUV: + case CV_YUV2RGBA_UYVY: + //case CV_YUV2RGBA_VYUY: + case CV_YUV2RGBA_YUY2: + case CV_YUV2RGBA_YVYU: + return new RGBA8888Writer(); + case CV_YUV2BGRA_NV12: + case CV_YUV2BGRA_NV21: + case CV_YUV2BGRA_YV12: + case CV_YUV2BGRA_IYUV: + case CV_YUV2BGRA_UYVY: + //case CV_YUV2BGRA_VYUY: + case CV_YUV2BGRA_YUY2: + case CV_YUV2BGRA_YVYU: + return new BGRA8888Writer(); + default: + return 0; + }; +} + +GRAYwriter* GRAYwriter::getWriter(int code) +{ + switch(code) + { + case CV_YUV2GRAY_420: + case CV_YUV2GRAY_UYVY: + case CV_YUV2GRAY_YUY2: + return new GRAYwriter(); + default: + return 0; + } +} + +YUVwriter* YUVwriter::getWriter(int code) +{ + switch(code) + { + case CV_RGB2YUV_YV12: + case CV_BGR2YUV_YV12: + case CV_RGBA2YUV_YV12: + case CV_BGRA2YUV_YV12: + return new YV12Writer(); + case CV_RGB2YUV_I420: + case CV_BGR2YUV_I420: + case CV_RGBA2YUV_I420: + case CV_BGRA2YUV_I420: + return new I420Writer(); + default: + return 0; + }; +} + +template +void referenceYUV2RGB(const Mat& yuv, Mat& rgb, YUVreader* yuvReader, RGBwriter* rgbWriter) +{ + convertor cvt; + + for(int row = 0; row < rgb.rows; ++row) + for(int col = 0; col < rgb.cols; ++col) + rgbWriter->write(rgb, row, col, cvt.convert(yuvReader->read(yuv, row, col))); +} + +template +void referenceYUV2GRAY(const Mat& yuv, Mat& rgb, YUVreader* yuvReader, GRAYwriter* grayWriter) +{ + convertor cvt; + + for(int row = 0; row < rgb.rows; ++row) + for(int col = 0; col < rgb.cols; ++col) + grayWriter->write(rgb, row, col, cvt.convert(yuvReader->read(yuv, row, col))); +} + +template +void referenceRGB2YUV(const Mat& rgb, Mat& yuv, RGBreader* rgbReader, YUVwriter* yuvWriter) +{ + convertor cvt; + + for(int row = 0; row < rgb.rows; ++row) + for(int col = 0; col < rgb.cols; ++col) + yuvWriter->write(yuv, row, col, cvt.convert(rgbReader->read(rgb, row, col))); +} + +struct ConversionYUV +{ + ConversionYUV( const int code ) + { + yuvReader_ = YUVreader :: getReader(code); + yuvWriter_ = YUVwriter :: getWriter(code); + rgbReader_ = RGBreader :: getReader(code); + rgbWriter_ = RGBwriter :: getWriter(code); + grayWriter_ = GRAYwriter:: getWriter(code); + } + + int getDcn() + { + return (rgbWriter_ != 0) ? rgbWriter_->channels() : ((grayWriter_ != 0) ? grayWriter_->channels() : yuvWriter_->channels()); + } + + int getScn() + { + return (yuvReader_ != 0) ? yuvReader_->channels() : rgbReader_->channels(); + } + + Size getSrcSize( const Size& imgSize ) + { + return (yuvReader_ != 0) ? yuvReader_->size(imgSize) : imgSize; + } + + Size getDstSize( const Size& imgSize ) + { + return (yuvWriter_ != 0) ? yuvWriter_->size(imgSize) : imgSize; + } + + bool requiresEvenHeight() + { + return (yuvReader_ != 0) ? yuvReader_->requiresEvenHeight() : ((yuvWriter_ != 0) ? yuvWriter_->requiresEvenHeight() : false); + } + + bool requiresEvenWidth() + { + return (yuvReader_ != 0) ? yuvReader_->requiresEvenWidth() : ((yuvWriter_ != 0) ? yuvWriter_->requiresEvenWidth() : false); + } + + YUVreader* yuvReader_; + YUVwriter* yuvWriter_; + RGBreader* rgbReader_; + RGBwriter* rgbWriter_; + GRAYwriter* grayWriter_; +}; + +CV_ENUM(YUVCVTS, CV_YUV2RGB_NV12, CV_YUV2BGR_NV12, CV_YUV2RGB_NV21, CV_YUV2BGR_NV21, + CV_YUV2RGBA_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGBA_NV21, CV_YUV2BGRA_NV21, + CV_YUV2RGB_YV12, CV_YUV2BGR_YV12, CV_YUV2RGB_IYUV, CV_YUV2BGR_IYUV, + CV_YUV2RGBA_YV12, CV_YUV2BGRA_YV12, CV_YUV2RGBA_IYUV, CV_YUV2BGRA_IYUV, + CV_YUV2RGB_UYVY, CV_YUV2BGR_UYVY, CV_YUV2RGBA_UYVY, CV_YUV2BGRA_UYVY, + CV_YUV2RGB_YUY2, CV_YUV2BGR_YUY2, CV_YUV2RGB_YVYU, CV_YUV2BGR_YVYU, + CV_YUV2RGBA_YUY2, CV_YUV2BGRA_YUY2, CV_YUV2RGBA_YVYU, CV_YUV2BGRA_YVYU, + CV_YUV2GRAY_420, CV_YUV2GRAY_UYVY, CV_YUV2GRAY_YUY2, + CV_YUV2BGR, CV_YUV2RGB, CV_RGB2YUV_YV12, CV_BGR2YUV_YV12, CV_RGBA2YUV_YV12, + CV_BGRA2YUV_YV12, CV_RGB2YUV_I420, CV_BGR2YUV_I420, CV_RGBA2YUV_I420, CV_BGRA2YUV_I420); + +typedef ::testing::TestWithParam Imgproc_ColorYUV; + +TEST_P(Imgproc_ColorYUV, accuracy) +{ + int code = GetParam(); + RNG& random = theRNG(); + + ConversionYUV cvt(code); + + const int scn = cvt.getScn(); + const int dcn = cvt.getDcn(); + for(int iter = 0; iter < 30; ++iter) + { + Size sz(random.uniform(1, 641), random.uniform(1, 481)); + + if(cvt.requiresEvenWidth()) sz.width += sz.width % 2; + if(cvt.requiresEvenHeight()) sz.height += sz.height % 2; + + Size srcSize = cvt.getSrcSize(sz); + Mat src = Mat(srcSize.height, srcSize.width * scn, CV_8UC1).reshape(scn); + + Size dstSize = cvt.getDstSize(sz); + Mat dst = Mat(dstSize.height, dstSize.width * dcn, CV_8UC1).reshape(dcn); + Mat gold(dstSize, CV_8UC(dcn)); + + random.fill(src, RNG::UNIFORM, 0, 256); + + if(cvt.rgbWriter_) + referenceYUV2RGB (src, gold, cvt.yuvReader_, cvt.rgbWriter_); + else if(cvt.grayWriter_) + referenceYUV2GRAY(src, gold, cvt.yuvReader_, cvt.grayWriter_); + else if(cvt.yuvWriter_) + referenceRGB2YUV (src, gold, cvt.rgbReader_, cvt.yuvWriter_); + + cv::cvtColor(src, dst, code, -1); + + EXPECT_EQ(0, countOfDifferencies(gold, dst)); + } +} + +TEST_P(Imgproc_ColorYUV, roi_accuracy) +{ + int code = GetParam(); + RNG& random = theRNG(); + + ConversionYUV cvt(code); + + const int scn = cvt.getScn(); + const int dcn = cvt.getDcn(); + for(int iter = 0; iter < 30; ++iter) + { + Size sz(random.uniform(1, 641), random.uniform(1, 481)); + + if(cvt.requiresEvenWidth()) sz.width += sz.width % 2; + if(cvt.requiresEvenHeight()) sz.height += sz.height % 2; + + int roi_offset_top = random.uniform(0, 6); + int roi_offset_bottom = random.uniform(0, 6); + int roi_offset_left = random.uniform(0, 6); + int roi_offset_right = random.uniform(0, 6); + + Size srcSize = cvt.getSrcSize(sz); + Mat src_full(srcSize.height + roi_offset_top + roi_offset_bottom, srcSize.width + roi_offset_left + roi_offset_right, CV_8UC(scn)); + + Size dstSize = cvt.getDstSize(sz); + Mat dst_full(dstSize.height + roi_offset_left + roi_offset_right, dstSize.width + roi_offset_top + roi_offset_bottom, CV_8UC(dcn), Scalar::all(0)); + Mat gold_full(dst_full.size(), CV_8UC(dcn), Scalar::all(0)); + + random.fill(src_full, RNG::UNIFORM, 0, 256); + + Mat src = src_full(Range(roi_offset_top, roi_offset_top + srcSize.height), Range(roi_offset_left, roi_offset_left + srcSize.width)); + Mat dst = dst_full(Range(roi_offset_left, roi_offset_left + dstSize.height), Range(roi_offset_top, roi_offset_top + dstSize.width)); + Mat gold = gold_full(Range(roi_offset_left, roi_offset_left + dstSize.height), Range(roi_offset_top, roi_offset_top + dstSize.width)); + + if(cvt.rgbWriter_) + referenceYUV2RGB (src, gold, cvt.yuvReader_, cvt.rgbWriter_); + else if(cvt.grayWriter_) + referenceYUV2GRAY(src, gold, cvt.yuvReader_, cvt.grayWriter_); + else if(cvt.yuvWriter_) + referenceRGB2YUV (src, gold, cvt.rgbReader_, cvt.yuvWriter_); + + cv::cvtColor(src, dst, code, -1); + + EXPECT_EQ(0, countOfDifferencies(gold_full, dst_full)); + } +} + +INSTANTIATE_TEST_CASE_P(cvt420, Imgproc_ColorYUV, + ::testing::Values((int)CV_YUV2RGB_NV12, (int)CV_YUV2BGR_NV12, (int)CV_YUV2RGB_NV21, (int)CV_YUV2BGR_NV21, + (int)CV_YUV2RGBA_NV12, (int)CV_YUV2BGRA_NV12, (int)CV_YUV2RGBA_NV21, (int)CV_YUV2BGRA_NV21, + (int)CV_YUV2RGB_YV12, (int)CV_YUV2BGR_YV12, (int)CV_YUV2RGB_IYUV, (int)CV_YUV2BGR_IYUV, + (int)CV_YUV2RGBA_YV12, (int)CV_YUV2BGRA_YV12, (int)CV_YUV2RGBA_IYUV, (int)CV_YUV2BGRA_IYUV, + (int)CV_YUV2GRAY_420, (int)CV_RGB2YUV_YV12, (int)CV_BGR2YUV_YV12, (int)CV_RGBA2YUV_YV12, + (int)CV_BGRA2YUV_YV12, (int)CV_RGB2YUV_I420, (int)CV_BGR2YUV_I420, (int)CV_RGBA2YUV_I420, + (int)CV_BGRA2YUV_I420)); + +INSTANTIATE_TEST_CASE_P(cvt422, Imgproc_ColorYUV, + ::testing::Values((int)CV_YUV2RGB_UYVY, (int)CV_YUV2BGR_UYVY, (int)CV_YUV2RGBA_UYVY, (int)CV_YUV2BGRA_UYVY, + (int)CV_YUV2RGB_YUY2, (int)CV_YUV2BGR_YUY2, (int)CV_YUV2RGB_YVYU, (int)CV_YUV2BGR_YVYU, + (int)CV_YUV2RGBA_YUY2, (int)CV_YUV2BGRA_YUY2, (int)CV_YUV2RGBA_YVYU, (int)CV_YUV2BGRA_YVYU, + (int)CV_YUV2GRAY_UYVY, (int)CV_YUV2GRAY_YUY2)); diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_distancetransform.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_distancetransform.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_distancetransform.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_distancetransform.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,297 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_DisTransTest : public cvtest::ArrayTest +{ +public: + CV_DisTransTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int ); + + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + int prepare_test_case( int test_case_idx ); + + int mask_size; + int dist_type; + int fill_labels; + float mask[3]; +}; + + +CV_DisTransTest::CV_DisTransTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + optional_mask = false; + element_wise_relative_error = true; +} + + +void CV_DisTransTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + types[INPUT][0] = CV_8UC1; + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_32FC1; + types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_32SC1; + + if( cvtest::randInt(rng) & 1 ) + { + mask_size = 3; + dist_type = cvtest::randInt(rng) % 4; + dist_type = dist_type == 0 ? CV_DIST_C : dist_type == 1 ? CV_DIST_L1 : + dist_type == 2 ? CV_DIST_L2 : CV_DIST_USER; + } + else + { + mask_size = 5; + dist_type = cvtest::randInt(rng) % 10; + dist_type = dist_type == 0 ? CV_DIST_C : dist_type == 1 ? CV_DIST_L1 : + dist_type < 6 ? CV_DIST_L2 : CV_DIST_USER; + } + + // for now, check only the "labeled" distance transform mode + fill_labels = 0; + + if( !fill_labels ) + sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(0,0); + + if( dist_type == CV_DIST_USER ) + { + mask[0] = (float)(1.1 - cvtest::randReal(rng)*0.2); + mask[1] = (float)(1.9 - cvtest::randReal(rng)*0.8); + mask[2] = (float)(3. - cvtest::randReal(rng)); + } +} + + +double CV_DisTransTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + Size sz = test_mat[INPUT][0].size(); + return dist_type == CV_DIST_C || dist_type == CV_DIST_L1 ? 0 : 0.01*MAX(sz.width, sz.height); +} + + +void CV_DisTransTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + if( i == INPUT && CV_MAT_DEPTH(type) == CV_8U ) + { + low = Scalar::all(0); + high = Scalar::all(10); + } +} + +int CV_DisTransTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + // the function's response to an "all-nonzeros" image is not determined, + // so put at least one zero point + Mat& mat = test_mat[INPUT][0]; + RNG& rng = ts->get_rng(); + int i = cvtest::randInt(rng) % mat.rows; + int j = cvtest::randInt(rng) % mat.cols; + mat.at(i,j) = 0; + } + + return code; +} + + +void CV_DisTransTest::run_func() +{ + cvDistTransform( test_array[INPUT][0], test_array[OUTPUT][0], dist_type, mask_size, + dist_type == CV_DIST_USER ? mask : 0, test_array[OUTPUT][1] ); +} + + +static void +cvTsDistTransform( const CvMat* _src, CvMat* _dst, int dist_type, + int mask_size, float* _mask, CvMat* /*_labels*/ ) +{ + int i, j, k; + int width = _src->cols, height = _src->rows; + const float init_val = 1e6; + float mask[3]; + CvMat* temp; + int ofs[16]; + float delta[16]; + int tstep, count; + + assert( mask_size == 3 || mask_size == 5 ); + + if( dist_type == CV_DIST_USER ) + memcpy( mask, _mask, sizeof(mask) ); + else if( dist_type == CV_DIST_C ) + { + mask_size = 3; + mask[0] = mask[1] = 1.f; + } + else if( dist_type == CV_DIST_L1 ) + { + mask_size = 3; + mask[0] = 1.f; + mask[1] = 2.f; + } + else if( mask_size == 3 ) + { + mask[0] = 0.955f; + mask[1] = 1.3693f; + } + else + { + mask[0] = 1.0f; + mask[1] = 1.4f; + mask[2] = 2.1969f; + } + + temp = cvCreateMat( height + mask_size-1, width + mask_size-1, CV_32F ); + tstep = temp->step / sizeof(float); + + if( mask_size == 3 ) + { + count = 4; + ofs[0] = -1; delta[0] = mask[0]; + ofs[1] = -tstep-1; delta[1] = mask[1]; + ofs[2] = -tstep; delta[2] = mask[0]; + ofs[3] = -tstep+1; delta[3] = mask[1]; + } + else + { + count = 8; + ofs[0] = -1; delta[0] = mask[0]; + ofs[1] = -tstep-2; delta[1] = mask[2]; + ofs[2] = -tstep-1; delta[2] = mask[1]; + ofs[3] = -tstep; delta[3] = mask[0]; + ofs[4] = -tstep+1; delta[4] = mask[1]; + ofs[5] = -tstep+2; delta[5] = mask[2]; + ofs[6] = -tstep*2-1; delta[6] = mask[2]; + ofs[7] = -tstep*2+1; delta[7] = mask[2]; + } + + for( i = 0; i < mask_size/2; i++ ) + { + float* t0 = (float*)(temp->data.ptr + i*temp->step); + float* t1 = (float*)(temp->data.ptr + (temp->rows - i - 1)*temp->step); + + for( j = 0; j < width + mask_size - 1; j++ ) + t0[j] = t1[j] = init_val; + } + + for( i = 0; i < height; i++ ) + { + uchar* s = _src->data.ptr + i*_src->step; + float* tmp = (float*)(temp->data.ptr + temp->step*(i + (mask_size/2))) + (mask_size/2); + + for( j = 0; j < mask_size/2; j++ ) + tmp[-j-1] = tmp[j + width] = init_val; + + for( j = 0; j < width; j++ ) + { + if( s[j] == 0 ) + tmp[j] = 0; + else + { + float min_dist = init_val; + for( k = 0; k < count; k++ ) + { + float t = tmp[j+ofs[k]] + delta[k]; + if( min_dist > t ) + min_dist = t; + } + tmp[j] = min_dist; + } + } + } + + for( i = height - 1; i >= 0; i-- ) + { + float* d = (float*)(_dst->data.ptr + i*_dst->step); + float* tmp = (float*)(temp->data.ptr + temp->step*(i + (mask_size/2))) + (mask_size/2); + + for( j = width - 1; j >= 0; j-- ) + { + float min_dist = tmp[j]; + if( min_dist > mask[0] ) + { + for( k = 0; k < count; k++ ) + { + float t = tmp[j-ofs[k]] + delta[k]; + if( min_dist > t ) + min_dist = t; + } + tmp[j] = min_dist; + } + d[j] = min_dist; + } + } + + cvReleaseMat( &temp ); +} + + +void CV_DisTransTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + CvMat _input = test_mat[INPUT][0], _output = test_mat[REF_OUTPUT][0]; + + cvTsDistTransform( &_input, &_output, dist_type, mask_size, mask, 0 ); +} + + +TEST(Imgproc_DistanceTransform, accuracy) { CV_DisTransTest test; test.safe_run(); } + + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_emd.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_emd.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_emd.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_emd.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,95 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +/*////////////////////// emd_test /////////////////////////*/ + +class CV_EMDTest : public cvtest::BaseTest +{ +public: + CV_EMDTest(); +protected: + void run(int); +}; + + +CV_EMDTest::CV_EMDTest() +{ +} + +void CV_EMDTest::run( int ) +{ + int code = cvtest::TS::OK; + const double success_error_level = 1e-6; + #define M 10000 + double emd0 = 2460./210; + static float cost[] = + { + 16, 16, 13, 22, 17, + 14, 14, 13, 19, 15, + 19, 19, 20, 23, M, + M , 0, M, 0, 0 + }; + static float w1[] = { 50, 60, 50, 50 }, + w2[] = { 30, 20, 70, 30, 60 }; + Mat _w1(4, 1, CV_32F, w1); + Mat _w2(5, 1, CV_32F, w2); + Mat _cost(_w1.rows, _w2.rows, CV_32F, cost); + + float emd = EMD( _w1, _w2, -1, _cost ); + if( fabs( emd - emd0 ) > success_error_level*emd0 ) + { + ts->printf( cvtest::TS::LOG, + "The computed distance is %.2f, while it should be %.2f\n", emd, emd0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + + if( code < 0 ) + ts->set_failed_test_info( code ); +} + +TEST(Imgproc_EMD, regression) { CV_EMDTest test; test.safe_run(); } + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_filter.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_filter.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_filter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_filter.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1889 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_FilterBaseTest : public cvtest::ArrayTest +{ +public: + CV_FilterBaseTest( bool _fp_kernel ); + +protected: + int prepare_test_case( int test_case_idx ); + int read_params( CvFileStorage* fs ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + CvSize aperture_size; + CvPoint anchor; + int max_aperture_size; + bool fp_kernel; + bool inplace; + int border; +}; + + +CV_FilterBaseTest::CV_FilterBaseTest( bool _fp_kernel ) : fp_kernel(_fp_kernel) +{ + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + max_aperture_size = 13; + inplace = false; + aperture_size = cvSize(0,0); + anchor = cvPoint(0,0); + element_wise_relative_error = false; +} + + +int CV_FilterBaseTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::ArrayTest::read_params( fs ); + if( code < 0 ) + return code; + + max_aperture_size = cvReadInt( find_param( fs, "max_aperture_size" ), max_aperture_size ); + max_aperture_size = cvtest::clipInt( max_aperture_size, 1, 100 ); + + return code; +} + + +void CV_FilterBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + if( i == INPUT ) + { + if( j == 1 ) + { + if( fp_kernel ) + { + RNG& rng = ts->get_rng(); + double val = exp( cvtest::randReal(rng)*10 - 4 ); + low = Scalar::all(-val); + high = Scalar::all(val); + } + else + { + low = Scalar::all(0); + high = Scalar::all(2); + } + } + else if( CV_MAT_DEPTH(type) == CV_16U ) + { + low = Scalar::all(0.); + high = Scalar::all(40000.); + } + else if( CV_MAT_DEPTH(type) == CV_32F ) + { + low = Scalar::all(-10.); + high = Scalar::all(10.); + } + } +} + + +void CV_FilterBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % CV_32F; + int cn = cvtest::randInt(rng) % 3 + 1; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + depth += depth == CV_8S; + cn += cn == 2; + + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn); + + aperture_size.width = cvtest::randInt(rng) % max_aperture_size + 1; + aperture_size.height = cvtest::randInt(rng) % max_aperture_size + 1; + anchor.x = cvtest::randInt(rng) % aperture_size.width; + anchor.y = cvtest::randInt(rng) % aperture_size.height; + + types[INPUT][1] = fp_kernel ? CV_32FC1 : CV_8UC1; + sizes[INPUT][1] = aperture_size; + + inplace = cvtest::randInt(rng) % 2 != 0; + border = BORDER_REPLICATE; +} + + +int CV_FilterBaseTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + if( inplace && test_mat[INPUT][0].type() == test_mat[OUTPUT][0].type()) + cvtest::copy( test_mat[INPUT][0], test_mat[OUTPUT][0] ); + else + inplace = false; + } + return code; +} + + +///////////////////////// + +class CV_MorphologyBaseTest : public CV_FilterBaseTest +{ +public: + CV_MorphologyBaseTest(); + +protected: + void prepare_to_validation( int test_case_idx ); + int prepare_test_case( int test_case_idx ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + int optype, optype_min, optype_max; + int shape; + IplConvKernel* element; +}; + + +CV_MorphologyBaseTest::CV_MorphologyBaseTest() : CV_FilterBaseTest( false ) +{ + shape = -1; + element = 0; + optype = optype_min = optype_max = -1; +} + + +void CV_MorphologyBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_FilterBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng) % 4; + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : depth == 2 ? CV_16S : CV_32F; + int cn = CV_MAT_CN(types[INPUT][0]); + + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn); + shape = cvtest::randInt(rng) % 4; + if( shape >= 3 ) + shape = CV_SHAPE_CUSTOM; + else + sizes[INPUT][1] = cvSize(0,0); + optype = cvtest::randInt(rng) % (optype_max - optype_min + 1) + optype_min; +} + + +double CV_MorphologyBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return test_mat[INPUT][0].depth() < CV_32F || + (optype == CV_MOP_ERODE || optype == CV_MOP_DILATE || + optype == CV_MOP_OPEN || optype == CV_MOP_CLOSE) ? 0 : 1e-5; +} + + +int CV_MorphologyBaseTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_FilterBaseTest::prepare_test_case( test_case_idx ); + vector eldata; + + if( code <= 0 ) + return code; + + if( shape == CV_SHAPE_CUSTOM ) + { + eldata.resize(aperture_size.width*aperture_size.height); + uchar* src = test_mat[INPUT][1].data; + int srcstep = (int)test_mat[INPUT][1].step; + int i, j, nonzero = 0; + + for( i = 0; i < aperture_size.height; i++ ) + { + for( j = 0; j < aperture_size.width; j++ ) + { + eldata[i*aperture_size.width + j] = src[i*srcstep + j]; + nonzero += src[i*srcstep + j] != 0; + } + } + + if( nonzero == 0 ) + eldata[anchor.y*aperture_size.width + anchor.x] = 1; + } + + cvReleaseStructuringElement( &element ); + element = cvCreateStructuringElementEx( aperture_size.width, aperture_size.height, + anchor.x, anchor.y, shape, eldata.empty() ? 0 : &eldata[0] ); + return code; +} + + +void CV_MorphologyBaseTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0], &dst = test_mat[REF_OUTPUT][0]; + Mat _ielement(element->nRows, element->nCols, CV_32S, element->values); + Mat _element; + _ielement.convertTo(_element, CV_8U); + Point _anchor(element->anchorX, element->anchorY); + int _border = BORDER_REPLICATE; + + if( optype == CV_MOP_ERODE ) + { + cvtest::erode( src, dst, _element, _anchor, _border ); + } + else if( optype == CV_MOP_DILATE ) + { + cvtest::dilate( src, dst, _element, _anchor, _border ); + } + else + { + Mat temp; + if( optype == CV_MOP_OPEN ) + { + cvtest::erode( src, temp, _element, _anchor, _border ); + cvtest::dilate( temp, dst, _element, _anchor, _border ); + } + else if( optype == CV_MOP_CLOSE ) + { + cvtest::dilate( src, temp, _element, _anchor, _border ); + cvtest::erode( temp, dst, _element, _anchor, _border ); + } + else if( optype == CV_MOP_GRADIENT ) + { + cvtest::erode( src, temp, _element, _anchor, _border ); + cvtest::dilate( src, dst, _element, _anchor, _border ); + cvtest::add( dst, 1, temp, -1, Scalar::all(0), dst, dst.type() ); + } + else if( optype == CV_MOP_TOPHAT ) + { + cvtest::erode( src, temp, _element, _anchor, _border ); + cvtest::dilate( temp, dst, _element, _anchor, _border ); + cvtest::add( src, 1, dst, -1, Scalar::all(0), dst, dst.type() ); + } + else if( optype == CV_MOP_BLACKHAT ) + { + cvtest::dilate( src, temp, _element, _anchor, _border ); + cvtest::erode( temp, dst, _element, _anchor, _border ); + cvtest::add( dst, 1, src, -1, Scalar::all(0), dst, dst.type() ); + } + else + CV_Error( CV_StsBadArg, "Unknown operation" ); + } + + cvReleaseStructuringElement( &element ); +} + + +/////////////// erode /////////////// + +class CV_ErodeTest : public CV_MorphologyBaseTest +{ +public: + CV_ErodeTest(); +protected: + void run_func(); +}; + + +CV_ErodeTest::CV_ErodeTest() +{ + optype_min = optype_max = CV_MOP_ERODE; +} + + +void CV_ErodeTest::run_func() +{ + cvErode( inplace ? test_array[OUTPUT][0] : test_array[INPUT][0], + test_array[OUTPUT][0], element, 1 ); +} + + +/////////////// dilate /////////////// + +class CV_DilateTest : public CV_MorphologyBaseTest +{ +public: + CV_DilateTest(); +protected: + void run_func(); +}; + + +CV_DilateTest::CV_DilateTest() +{ + optype_min = optype_max = CV_MOP_DILATE; +} + + +void CV_DilateTest::run_func() +{ + cvDilate( inplace ? test_array[OUTPUT][0] : test_array[INPUT][0], + test_array[OUTPUT][0], element, 1 ); +} + +/////////////// morphEx /////////////// + +class CV_MorphExTest : public CV_MorphologyBaseTest +{ +public: + CV_MorphExTest(); +protected: + void run_func(); +}; + + +CV_MorphExTest::CV_MorphExTest() +{ + optype_min = CV_MOP_ERODE; + optype_max = CV_MOP_BLACKHAT; +} + + +void CV_MorphExTest::run_func() +{ + cvMorphologyEx( test_array[inplace ? OUTPUT : INPUT][0], + test_array[OUTPUT][0], 0, element, optype, 1 ); +} + +/////////////// generic filter /////////////// + +class CV_FilterTest : public CV_FilterBaseTest +{ +public: + CV_FilterTest(); + +protected: + void prepare_to_validation( int test_case_idx ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_FilterTest::CV_FilterTest() : CV_FilterBaseTest( true ) +{ +} + + +void CV_FilterTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + CV_FilterBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng)%3; + int cn = CV_MAT_CN(types[INPUT][0]); + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F; + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn); +} + + +double CV_FilterTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 2 : depth <= CV_32S ? 32 : + depth == CV_32F ? 1e-4 : 1e-10; +} + + +void CV_FilterTest::run_func() +{ + CvMat kernel = test_mat[INPUT][1]; + cvFilter2D( test_array[inplace ? OUTPUT : INPUT][0], + test_array[OUTPUT][0], &kernel, anchor ); +} + + +void CV_FilterTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + cvtest::filter2D( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].type(), + test_mat[INPUT][1], anchor, 0, BORDER_REPLICATE ); +} + + +//////////////////////// + +class CV_DerivBaseTest : public CV_FilterBaseTest +{ +public: + CV_DerivBaseTest(); +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + int _aperture_size; +}; + + +CV_DerivBaseTest::CV_DerivBaseTest() : CV_FilterBaseTest( true ) +{ + max_aperture_size = 7; +} + + +void CV_DerivBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_FilterBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng) % 2; + depth = depth == 0 ? CV_8U : CV_32F; + types[INPUT][0] = CV_MAKETYPE(depth,1); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth==CV_8U?CV_16S:CV_32F,1); + _aperture_size = (cvtest::randInt(rng)%5)*2 - 1; + sizes[INPUT][1] = aperture_size = cvSize(_aperture_size, _aperture_size); +} + + +double CV_DerivBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 2 : 5e-4; +} + + +/////////////// sobel /////////////// + +class CV_SobelTest : public CV_DerivBaseTest +{ +public: + CV_SobelTest(); + +protected: + void prepare_to_validation( int test_case_idx ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ); + int dx, dy, origin; +}; + + +CV_SobelTest::CV_SobelTest() {} + + +void CV_SobelTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_DerivBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int max_d = _aperture_size > 0 ? 2 : 1; + origin = cvtest::randInt(rng) % 2; + dx = cvtest::randInt(rng) % (max_d + 1); + dy = cvtest::randInt(rng) % (max_d + 1 - dx); + if( dx == 0 && dy == 0 ) + dx = 1; + if( cvtest::randInt(rng) % 2 ) + { + int t; + CV_SWAP( dx, dy, t ); + } + + if( _aperture_size < 0 ) + aperture_size = cvSize(3, 3); + else if( _aperture_size == 1 ) + { + if( dx == 0 ) + aperture_size = cvSize(1, 3); + else if( dy == 0 ) + aperture_size = cvSize(3, 1); + else + { + _aperture_size = 3; + aperture_size = cvSize(3, 3); + } + } + else + aperture_size = cvSize(_aperture_size, _aperture_size); + + sizes[INPUT][1] = aperture_size; + anchor.x = aperture_size.width / 2; + anchor.y = aperture_size.height / 2; +} + + +void CV_SobelTest::run_func() +{ + cvSobel( test_array[inplace ? OUTPUT : INPUT][0], + test_array[OUTPUT][0], dx, dy, _aperture_size ); + /*cv::Sobel( test_mat[inplace ? OUTPUT : INPUT][0], + test_mat[OUTPUT][0], test_mat[OUTPUT][0].depth(), + dx, dy, _aperture_size, 1, 0, border );*/ +} + + +void CV_SobelTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat kernel = cvtest::calcSobelKernel2D( dx, dy, _aperture_size, 0 ); + cvtest::filter2D( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].depth(), + kernel, anchor, 0, BORDER_REPLICATE); +} + + +/////////////// laplace /////////////// + +class CV_LaplaceTest : public CV_DerivBaseTest +{ +public: + CV_LaplaceTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int test_case_idx ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); +}; + + +CV_LaplaceTest::CV_LaplaceTest() +{ +} + + +void CV_LaplaceTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + CV_DerivBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + if( _aperture_size <= 1 ) + { + if( _aperture_size < 0 ) + _aperture_size = 1; + aperture_size = cvSize(3, 3); + } + else + aperture_size = cvSize(_aperture_size, _aperture_size); + + sizes[INPUT][1] = aperture_size; + anchor.x = aperture_size.width / 2; + anchor.y = aperture_size.height / 2; +} + + +void CV_LaplaceTest::run_func() +{ + cvLaplace( test_array[inplace ? OUTPUT : INPUT][0], + test_array[OUTPUT][0], _aperture_size ); +} + + +int CV_LaplaceTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_DerivBaseTest::prepare_test_case( test_case_idx ); + return _aperture_size < 0 ? 0 : code; +} + + +void CV_LaplaceTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat kernel = cvtest::calcLaplaceKernel2D( _aperture_size ); + cvtest::filter2D( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].depth(), + kernel, anchor, 0, BORDER_REPLICATE ); +} + + +//////////////////////////////////////////////////////////// + +class CV_SmoothBaseTest : public CV_FilterBaseTest +{ +public: + CV_SmoothBaseTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + const char* smooth_type; +}; + + +CV_SmoothBaseTest::CV_SmoothBaseTest() : CV_FilterBaseTest( true ) +{ + smooth_type = ""; +} + + +void CV_SmoothBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_FilterBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng) % 2; + int cn = CV_MAT_CN(types[INPUT][0]); + depth = depth == 0 ? CV_8U : CV_32F; + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn); + anchor.x = cvtest::randInt(rng)%(max_aperture_size/2+1); + anchor.y = cvtest::randInt(rng)%(max_aperture_size/2+1); + aperture_size.width = anchor.x*2 + 1; + aperture_size.height = anchor.y*2 + 1; + sizes[INPUT][1] = aperture_size; +} + + +double CV_SmoothBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 1 : 1e-5; +} + + +/////////////// blur /////////////// + +class CV_BlurTest : public CV_SmoothBaseTest +{ +public: + CV_BlurTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int test_case_idx ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + bool normalize; +}; + + +CV_BlurTest::CV_BlurTest() +{ +} + + +void CV_BlurTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_SmoothBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng) % 4; + int cn = (cvtest::randInt(rng) % 4) + 1; + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : depth == 2 ? CV_16S : CV_32F; + types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][0] = CV_MAKETYPE(depth, cn); + normalize = cvtest::randInt(rng) % 2 != 0; + if( !normalize ) + { + types[INPUT][0] = CV_MAKETYPE(depth, 1); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth==CV_8U?CV_16S:CV_32F,1); + } +} + + +void CV_BlurTest::run_func() +{ + cvSmooth( inplace ? test_array[OUTPUT][0] : test_array[INPUT][0], + test_array[OUTPUT][0], normalize ? CV_BLUR : CV_BLUR_NO_SCALE, + aperture_size.width, aperture_size.height ); +} + + +int CV_BlurTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_SmoothBaseTest::prepare_test_case( test_case_idx ); + return code > 0 && !normalize && test_mat[INPUT][0].channels() > 1 ? 0 : code; +} + + +void CV_BlurTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat kernel(aperture_size, CV_64F); + kernel.setTo(Scalar::all(normalize ? 1./(aperture_size.width*aperture_size.height) : 1.)); + cvtest::filter2D( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].depth(), + kernel, anchor, 0, BORDER_REPLICATE ); +} + + +/////////////// gaussian /////////////// + +class CV_GaussianBlurTest : public CV_SmoothBaseTest +{ +public: + CV_GaussianBlurTest(); + +protected: + void prepare_to_validation( int test_case_idx ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ); + double sigma; + int param1, param2; +}; + + +CV_GaussianBlurTest::CV_GaussianBlurTest() : CV_SmoothBaseTest() +{ + sigma = 0.; + smooth_type = "Gaussian"; +} + + +double CV_GaussianBlurTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 8 : 1e-5; +} + + +void CV_GaussianBlurTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int kernel_case = cvtest::randInt(rng) % 2; + CV_SmoothBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + anchor = cvPoint(aperture_size.width/2,aperture_size.height/2); + + sigma = exp(cvtest::randReal(rng)*5-2); + param1 = aperture_size.width; + param2 = aperture_size.height; + + if( kernel_case == 0 ) + sigma = 0.; +} + +void CV_GaussianBlurTest::run_func() +{ + cvSmooth( test_array[inplace ? OUTPUT : INPUT][0], + test_array[OUTPUT][0], CV_GAUSSIAN, + param1, param2, sigma, sigma ); +} + + +// !!! Copied from cvSmooth, if the code is changed in cvSmooth, +// make sure to update this one too. +#define SMALL_GAUSSIAN_SIZE 7 +static void +calcGaussianKernel( int n, double sigma, vector& kernel ) +{ + static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] = + { + {1.f}, + {0.25f, 0.5f, 0.25f}, + {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f}, + {0.03125, 0.109375, 0.21875, 0.28125, 0.21875, 0.109375, 0.03125} + }; + + kernel.resize(n); + if( n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ) + { + assert( n%2 == 1 ); + memcpy( &kernel[0], small_gaussian_tab[n>>1], n*sizeof(kernel[0])); + } + else + { + double sigmaX = sigma > 0 ? sigma : (n/2 - 1)*0.3 + 0.8; + double scale2X = -0.5/(sigmaX*sigmaX); + double sum = 1.; + int i; + sum = kernel[n/2] = 1.f; + + for( i = 1; i <= n/2; i++ ) + { + kernel[n/2+i] = kernel[n/2-i] = (float)exp(scale2X*i*i); + sum += kernel[n/2+i]*2; + } + + sum = 1./sum; + for( i = 0; i <= n/2; i++ ) + kernel[n/2+i] = kernel[n/2-i] = (float)(kernel[n/2+i]*sum); + } +} + + +static Mat calcGaussianKernel2D( Size ksize, double sigma ) +{ + vector kx, ky; + Mat kernel(ksize, CV_32F); + + calcGaussianKernel( kernel.cols, sigma, kx ); + calcGaussianKernel( kernel.rows, sigma, ky ); + + for( int i = 0; i < kernel.rows; i++ ) + for( int j = 0; j < kernel.cols; j++ ) + kernel.at(i, j) = kx[j]*ky[i]; + return kernel; +} + + +void CV_GaussianBlurTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat kernel = calcGaussianKernel2D( aperture_size, sigma ); + cvtest::filter2D( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].depth(), + kernel, anchor, 0, border & ~BORDER_ISOLATED ); +} + + +/////////////// median /////////////// + +class CV_MedianBlurTest : public CV_SmoothBaseTest +{ +public: + CV_MedianBlurTest(); + +protected: + void prepare_to_validation( int test_case_idx ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); +}; + + +CV_MedianBlurTest::CV_MedianBlurTest() +{ + smooth_type = "Median"; +} + + +void CV_MedianBlurTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + CV_SmoothBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = CV_8U; + int cn = CV_MAT_CN(types[INPUT][0]); + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn); + types[INPUT][1] = CV_MAKETYPE(depth,1); + + aperture_size.height = aperture_size.width; + anchor.x = anchor.y = aperture_size.width / 2; + sizes[INPUT][1] = cvSize(aperture_size.width,aperture_size.height); + + sizes[OUTPUT][0] = sizes[INPUT][0]; + sizes[REF_OUTPUT][0] = sizes[INPUT][0]; + + inplace = false; + border = BORDER_REPLICATE | BORDER_ISOLATED; +} + + +double CV_MedianBlurTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 0; +} + + +void CV_MedianBlurTest::run_func() +{ + cvSmooth( test_array[INPUT][0], test_array[OUTPUT][0], + CV_MEDIAN, aperture_size.width ); +} + + +struct median_pair +{ + int col; + int val; + median_pair() {}; + median_pair( int _col, int _val ) : col(_col), val(_val) {}; +}; + + +static void test_medianFilter( const Mat& src, Mat& dst, int m ) +{ + int i, j, k, l, m2 = m*m, n; + vector col_buf(m+1); + vector _buf0(m*m+1), _buf1(m*m+1); + median_pair *buf0 = &_buf0[0], *buf1 = &_buf1[0]; + int step = (int)(src.step/src.elemSize()); + + assert( src.rows == dst.rows + m - 1 && src.cols == dst.cols + m - 1 && + src.type() == dst.type() && src.type() == CV_8UC1 ); + + for( i = 0; i < dst.rows; i++ ) + { + uchar* dst1 = dst.ptr(i); + for( k = 0; k < m; k++ ) + { + const uchar* src1 = src.ptr(i+k); + for( j = 0; j < m-1; j++ ) + *buf0++ = median_pair(j, src1[j]); + } + + n = m2 - m; + buf0 -= n; + for( k = n-1; k > 0; k-- ) + { + int f = 0; + for( j = 0; j < k; j++ ) + { + if( buf0[j].val > buf0[j+1].val ) + { + median_pair t; + CV_SWAP( buf0[j], buf0[j+1], t ); + f = 1; + } + } + if( !f ) + break; + } + + for( j = 0; j < dst.cols; j++ ) + { + int ins_col = j + m - 1; + int del_col = j - 1; + const uchar* src1 = src.ptr(i) + ins_col; + for( k = 0; k < m; k++, src1 += step ) + { + col_buf[k] = src1[0]; + for( l = k-1; l >= 0; l-- ) + { + int t; + if( col_buf[l] < col_buf[l+1] ) + break; + CV_SWAP( col_buf[l], col_buf[l+1], t ); + } + } + + col_buf[m] = INT_MAX; + + for( k = 0, l = 0; k < n; ) + { + if( buf0[k].col == del_col ) + k++; + else if( buf0[k].val < col_buf[l] ) + *buf1++ = buf0[k++]; + else + { + assert( col_buf[l] < INT_MAX ); + *buf1++ = median_pair(ins_col,col_buf[l++]); + } + } + + for( ; l < m; l++ ) + *buf1++ = median_pair(ins_col,col_buf[l]); + + if( del_col < 0 ) + n += m; + buf1 -= n; + assert( n == m2 ); + dst1[j] = (uchar)buf1[n/2].val; + median_pair* tbuf; + CV_SWAP( buf0, buf1, tbuf ); + } + } +} + + +void CV_MedianBlurTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + // CV_SmoothBaseTest::prepare_to_validation( test_case_idx ); + const Mat& src0 = test_mat[INPUT][0]; + Mat& dst0 = test_mat[REF_OUTPUT][0]; + int i, cn = src0.channels(); + int m = aperture_size.width; + Mat src(src0.rows + m - 1, src0.cols + m - 1, src0.depth()); + Mat dst; + if( cn == 1 ) + dst = dst0; + else + dst.create(src0.size(), src0.depth()); + + for( i = 0; i < cn; i++ ) + { + Mat ptr = src0; + if( cn > 1 ) + { + cvtest::extract( src0, dst, i ); + ptr = dst; + } + cvtest::copyMakeBorder( ptr, src, m/2, m/2, m/2, m/2, border & ~BORDER_ISOLATED ); + test_medianFilter( src, dst, m ); + if( cn > 1 ) + cvtest::insert( dst, dst0, i ); + } +} + + +/////////////// pyramid tests /////////////// + +class CV_PyramidBaseTest : public CV_FilterBaseTest +{ +public: + CV_PyramidBaseTest( bool downsample ); + +protected: + double get_success_error_level( int test_case_idx, int i, int j ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + bool downsample; + Mat kernel; +}; + + +CV_PyramidBaseTest::CV_PyramidBaseTest( bool _downsample ) : CV_FilterBaseTest(true) +{ + static float kdata[] = { 1.f, 4.f, 6.f, 4.f, 1.f }; + downsample = _downsample; + Mat kernel1d(1, 5, CV_32F, kdata); + kernel = (kernel1d.t()*kernel1d)*((downsample ? 1 : 4)/256.); +} + + +double CV_PyramidBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth < CV_32F ? 1 : 1e-5; +} + + +void CV_PyramidBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + const int channels[] = {1, 3, 4}; + const int depthes[] = {CV_8U, CV_16S, CV_16U, CV_32F}; + + RNG& rng = ts->get_rng(); + CvSize sz; + CV_FilterBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + int depth = depthes[cvtest::randInt(rng) % (sizeof(depthes)/sizeof(depthes[0]))]; + int cn = channels[cvtest::randInt(rng) % (sizeof(channels)/sizeof(channels[0]))]; + + aperture_size = cvSize(5,5); + anchor = cvPoint(aperture_size.width/2, aperture_size.height/2); + + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn); + + sz.width = MAX( sizes[INPUT][0].width/2, 1 ); + sz.height = MAX( sizes[INPUT][0].height/2, 1 ); + + if( downsample ) + { + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sz; + sz.width *= 2; + sz.height *= 2; + sizes[INPUT][0] = sz; + } + else + { + sizes[INPUT][0] = sz; + sz.width *= 2; + sz.height *= 2; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sz; + } + + sizes[INPUT][1] = aperture_size; + inplace = false; +} + + +/////// pyrdown //////// + +class CV_PyramidDownTest : public CV_PyramidBaseTest +{ +public: + CV_PyramidDownTest(); + +protected: + void run_func(); + void prepare_to_validation( int ); +}; + + +CV_PyramidDownTest::CV_PyramidDownTest() : CV_PyramidBaseTest( true ) +{ +} + + +void CV_PyramidDownTest::run_func() +{ + cvPyrDown( test_array[INPUT][0], test_array[OUTPUT][0], CV_GAUSSIAN_5x5 ); +} + + +void CV_PyramidDownTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0], &dst = test_mat[REF_OUTPUT][0]; + Mat temp; + cvtest::filter2D(src, temp, src.depth(), + kernel, Point(kernel.cols/2, kernel.rows/2), + 0, BORDER_REFLECT_101); + + size_t elem_size = temp.elemSize(); + size_t ncols = dst.cols*elem_size; + + for( int i = 0; i < dst.rows; i++ ) + { + const uchar* src_row = temp.ptr(i*2); + uchar* dst_row = dst.ptr(i); + + for( size_t j = 0; j < ncols; j += elem_size ) + { + for( size_t k = 0; k < elem_size; k++ ) + dst_row[j+k] = src_row[j*2+k]; + } + } +} + + +/////// pyrup //////// + +class CV_PyramidUpTest : public CV_PyramidBaseTest +{ +public: + CV_PyramidUpTest(); + +protected: + void run_func(); + void prepare_to_validation( int ); +}; + + +CV_PyramidUpTest::CV_PyramidUpTest() : CV_PyramidBaseTest( false ) +{ +} + + +void CV_PyramidUpTest::run_func() +{ + cvPyrUp( test_array[INPUT][0], test_array[OUTPUT][0], CV_GAUSSIAN_5x5 ); +} + + +void CV_PyramidUpTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0], &dst = test_mat[REF_OUTPUT][0]; + Mat temp(dst.size(), dst.type()); + + size_t elem_size = src.elemSize(); + size_t ncols = src.cols*elem_size; + + for( int i = 0; i < src.rows; i++ ) + { + const uchar* src_row = src.ptr(i); + uchar* dst_row = temp.ptr(i*2); + + if( i*2 + 1 < temp.rows ) + memset( temp.ptr(i*2+1), 0, temp.cols*elem_size ); + for( size_t j = 0; j < ncols; j += elem_size ) + { + for( size_t k = 0; k < elem_size; k++ ) + { + dst_row[j*2+k] = src_row[j+k]; + dst_row[j*2+k+elem_size] = 0; + } + } + } + + cvtest::filter2D(temp, dst, dst.depth(), + kernel, Point(kernel.cols/2, kernel.rows/2), + 0, BORDER_REFLECT_101); +} + + +//////////////////////// feature selection ////////////////////////// + +class CV_FeatureSelBaseTest : public cvtest::ArrayTest +{ +public: + CV_FeatureSelBaseTest( int width_factor ); + +protected: + int read_params( CvFileStorage* fs ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + int aperture_size, block_size; + int max_aperture_size; + int max_block_size; + int width_factor; +}; + + +CV_FeatureSelBaseTest::CV_FeatureSelBaseTest( int _width_factor ) +{ + max_aperture_size = 7; + max_block_size = 21; + // 1 input, 1 output, temp arrays are allocated in the reference functions + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + element_wise_relative_error = false; + width_factor = _width_factor; +} + + +int CV_FeatureSelBaseTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::BaseTest::read_params( fs ); + if( code < 0 ) + return code; + + max_aperture_size = cvReadInt( find_param( fs, "max_aperture_size" ), max_aperture_size ); + max_aperture_size = cvtest::clipInt( max_aperture_size, 1, 9 ); + max_block_size = cvReadInt( find_param( fs, "max_block_size" ), max_block_size ); + max_block_size = cvtest::clipInt( max_aperture_size, 1, 100 ); + + return code; +} + + +double CV_FeatureSelBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth <= CV_8S ? 3e-2 : depth == CV_32F ? 1e-3 : 1e-10; +} + + +void CV_FeatureSelBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + if( i == INPUT && CV_MAT_DEPTH(type) == CV_32F ) + { + low = Scalar::all(-10.); + high = Scalar::all(10.); + } +} + + +void CV_FeatureSelBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng) % 2, asz; + + depth = depth == 0 ? CV_8U : CV_32F; + types[INPUT][0] = depth; + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_32FC1; + + aperture_size = (cvtest::randInt(rng) % (max_aperture_size+2) - 1) | 1; + if( aperture_size == 1 ) + aperture_size = 3; + if( depth == CV_8U ) + aperture_size = MIN( aperture_size, 5 ); + block_size = (cvtest::randInt(rng) % max_block_size + 1) | 1; + if( block_size <= 3 ) + block_size = 3; + asz = aperture_size > 0 ? aperture_size : 3; + + sizes[INPUT][0].width = MAX( sizes[INPUT][0].width, asz + block_size ); + sizes[INPUT][0].height = MAX( sizes[INPUT][0].height, asz + block_size ); + sizes[OUTPUT][0].height = sizes[REF_OUTPUT][0].height = sizes[INPUT][0].height; + sizes[OUTPUT][0].width = sizes[REF_OUTPUT][0].width = sizes[INPUT][0].width*width_factor; +} + + +static void +test_cornerEigenValsVecs( const Mat& src, Mat& eigenv, Mat& ocv_eigenv, + int block_size, int _aperture_size, int mode ) +{ + int i, j; + int aperture_size = _aperture_size < 0 ? 3 : _aperture_size; + Point anchor( aperture_size/2, aperture_size/2 ); + + CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); + CV_Assert( eigenv.type() == CV_32FC1 ); + CV_Assert( src.rows == eigenv.rows && + ((mode > 0 && src.cols == eigenv.cols) || + (mode == 0 && src.cols*6 == eigenv.cols)) ); + + int type = src.type(); + int ftype = CV_32FC1; + double kernel_scale = type != ftype ? 1./255 : 1; + + Mat dx2, dy2, dxdy(src.size(), CV_32F), kernel; + + kernel = cvtest::calcSobelKernel2D( 1, 0, _aperture_size ); + cvtest::filter2D( src, dx2, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE ); + kernel = cvtest::calcSobelKernel2D( 0, 1, _aperture_size ); + cvtest::filter2D( src, dy2, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE ); + + double denom = (1 << (aperture_size-1))*block_size; + denom = denom * denom; + if( _aperture_size < 0 ) + denom *= 4; + denom = 1./denom; + + for( i = 0; i < src.rows; i++ ) + { + float* dxdyp = dxdy.ptr(i); + float* dx2p = dx2.ptr(i); + float* dy2p = dy2.ptr(i); + + for( j = 0; j < src.cols; j++ ) + { + double xval = dx2p[j], yval = dy2p[j]; + dxdyp[j] = (float)(xval*yval*denom); + dx2p[j] = (float)(xval*xval*denom); + dy2p[j] = (float)(yval*yval*denom); + } + } + + kernel = Mat::ones(block_size, block_size, CV_32F); + anchor = Point(block_size/2, block_size/2); + + cvtest::filter2D( dx2, dx2, ftype, kernel, anchor, 0, BORDER_REPLICATE ); + cvtest::filter2D( dy2, dy2, ftype, kernel, anchor, 0, BORDER_REPLICATE ); + cvtest::filter2D( dxdy, dxdy, ftype, kernel, anchor, 0, BORDER_REPLICATE ); + + if( mode == 0 ) + { + for( i = 0; i < src.rows; i++ ) + { + float* eigenvp = eigenv.ptr(i); + float* ocv_eigenvp = ocv_eigenv.ptr(i); + const float* dxdyp = dxdy.ptr(i); + const float* dx2p = dx2.ptr(i); + const float* dy2p = dy2.ptr(i); + + for( j = 0; j < src.cols; j++ ) + { + double a = dx2p[j], b = dxdyp[j], c = dy2p[j]; + double d = sqrt((a-c)*(a-c) + 4*b*b); + double l1 = 0.5*(a + c + d); + double l2 = 0.5*(a + c - d); + double x1, y1, x2, y2, s; + + if( fabs(a - l1) + fabs(b) >= 1e-3 ) + x1 = b, y1 = l1 - a; + else + x1 = l1 - c, y1 = b; + s = 1./(sqrt(x1*x1+y1*y1)+DBL_EPSILON); + x1 *= s; y1 *= s; + + if( fabs(a - l2) + fabs(b) >= 1e-3 ) + x2 = b, y2 = l2 - a; + else + x2 = l2 - c, y2 = b; + s = 1./(sqrt(x2*x2+y2*y2)+DBL_EPSILON); + x2 *= s; y2 *= s; + + /* the orientation of eigen vectors might be inversed relative to OpenCV function, + which is normal */ + if( (fabs(x1) >= fabs(y1) && ocv_eigenvp[j*6+2]*x1 < 0) || + (fabs(x1) < fabs(y1) && ocv_eigenvp[j*6+3]*y1 < 0) ) + x1 = -x1, y1 = -y1; + + if( (fabs(x2) >= fabs(y2) && ocv_eigenvp[j*6+4]*x2 < 0) || + (fabs(x2) < fabs(y2) && ocv_eigenvp[j*6+5]*y2 < 0) ) + x2 = -x2, y2 = -y2; + + eigenvp[j*6] = (float)l1; + eigenvp[j*6+1] = (float)l2; + eigenvp[j*6+2] = (float)x1; + eigenvp[j*6+3] = (float)y1; + eigenvp[j*6+4] = (float)x2; + eigenvp[j*6+5] = (float)y2; + } + } + } + else if( mode == 1 ) + { + for( i = 0; i < src.rows; i++ ) + { + float* eigenvp = eigenv.ptr(i); + const float* dxdyp = dxdy.ptr(i); + const float* dx2p = dx2.ptr(i); + const float* dy2p = dy2.ptr(i); + + for( j = 0; j < src.cols; j++ ) + { + double a = dx2p[j], b = dxdyp[j], c = dy2p[j]; + double d = sqrt((a-c)*(a-c) + 4*b*b); + eigenvp[j] = (float)(0.5*(a + c - d)); + } + } + } +} + + +// min eigenval +class CV_MinEigenValTest : public CV_FeatureSelBaseTest +{ +public: + CV_MinEigenValTest(); + +protected: + void run_func(); + void prepare_to_validation( int ); +}; + + +CV_MinEigenValTest::CV_MinEigenValTest() : CV_FeatureSelBaseTest( 1 ) +{ +} + + +void CV_MinEigenValTest::run_func() +{ + cvCornerMinEigenVal( test_array[INPUT][0], test_array[OUTPUT][0], + block_size, aperture_size ); +} + + +void CV_MinEigenValTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + test_cornerEigenValsVecs( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], + test_mat[OUTPUT][0], block_size, aperture_size, 1 ); +} + + +// eigenval's & vec's +class CV_EigenValVecTest : public CV_FeatureSelBaseTest +{ +public: + CV_EigenValVecTest(); + +protected: + void run_func(); + void prepare_to_validation( int ); +}; + + +CV_EigenValVecTest::CV_EigenValVecTest() : CV_FeatureSelBaseTest( 6 ) +{ +} + + +void CV_EigenValVecTest::run_func() +{ + cvCornerEigenValsAndVecs( test_array[INPUT][0], test_array[OUTPUT][0], + block_size, aperture_size ); +} + + +void CV_EigenValVecTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + test_cornerEigenValsVecs( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], + test_mat[OUTPUT][0], block_size, aperture_size, 0 ); +} + + +// precornerdetect +class CV_PreCornerDetectTest : public CV_FeatureSelBaseTest +{ +public: + CV_PreCornerDetectTest(); + +protected: + void run_func(); + void prepare_to_validation( int ); + int prepare_test_case( int ); +}; + + +CV_PreCornerDetectTest::CV_PreCornerDetectTest() : CV_FeatureSelBaseTest( 1 ) +{ +} + + +void CV_PreCornerDetectTest::run_func() +{ + cvPreCornerDetect( test_array[INPUT][0], test_array[OUTPUT][0], aperture_size ); +} + + +int CV_PreCornerDetectTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_FeatureSelBaseTest::prepare_test_case( test_case_idx ); + if( aperture_size < 0 ) + aperture_size = 3; + return code; +} + + +void CV_PreCornerDetectTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + /*cvTsCornerEigenValsVecs( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], + block_size, aperture_size, 0 );*/ + const Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_OUTPUT][0]; + + int type = src.type(), ftype = CV_32FC1; + Point anchor(aperture_size/2, aperture_size/2); + + double kernel_scale = type != ftype ? 1./255 : 1.; + + Mat dx, dy, d2x, d2y, dxy, kernel; + + kernel = cvtest::calcSobelKernel2D(1, 0, aperture_size); + cvtest::filter2D(src, dx, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE); + kernel = cvtest::calcSobelKernel2D(2, 0, aperture_size); + cvtest::filter2D(src, d2x, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE); + kernel = cvtest::calcSobelKernel2D(0, 1, aperture_size); + cvtest::filter2D(src, dy, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE); + kernel = cvtest::calcSobelKernel2D(0, 2, aperture_size); + cvtest::filter2D(src, d2y, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE); + kernel = cvtest::calcSobelKernel2D(1, 1, aperture_size); + cvtest::filter2D(src, dxy, ftype, kernel*kernel_scale, anchor, 0, BORDER_REPLICATE); + + double denom = 1 << (aperture_size-1); + denom = denom * denom * denom; + denom = 1./denom; + + for( int i = 0; i < src.rows; i++ ) + { + const float* _dx = dx.ptr(i); + const float* _dy = dy.ptr(i); + const float* _d2x = d2x.ptr(i); + const float* _d2y = d2y.ptr(i); + const float* _dxy = dxy.ptr(i); + float* corner = dst.ptr(i); + + for( int j = 0; j < src.cols; j++ ) + { + double x = _dx[j]; + double y = _dy[j]; + + corner[j] = (float)(denom*(x*x*_d2y[j] + y*y*_d2x[j] - 2*x*y*_dxy[j])); + } + } +} + + +///////// integral ///////// + +class CV_IntegralTest : public cvtest::ArrayTest +{ +public: + CV_IntegralTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int ); + + int prepare_test_case( int test_case_idx ); +}; + + +CV_IntegralTest::CV_IntegralTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + element_wise_relative_error = true; +} + + +void CV_IntegralTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + int depth = CV_MAT_DEPTH(type); + if( depth == CV_32F ) + { + low = Scalar::all(-10.); + high = Scalar::all(10.); + } +} + + +void CV_IntegralTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % 2, sum_depth; + int cn = cvtest::randInt(rng) % 3 + 1; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + Size sum_size; + + depth = depth == 0 ? CV_8U : CV_32F; + cn += cn == 2; + int b = (cvtest::randInt(rng) & 1) != 0; + sum_depth = depth == CV_8U && b ? CV_32S : b ? CV_32F : CV_64F; + + types[INPUT][0] = CV_MAKETYPE(depth,cn); + types[OUTPUT][0] = types[REF_OUTPUT][0] = + types[OUTPUT][2] = types[REF_OUTPUT][2] = CV_MAKETYPE(sum_depth, cn); + types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_MAKETYPE(CV_64F, cn); + + sum_size.width = sizes[INPUT][0].width + 1; + sum_size.height = sizes[INPUT][0].height + 1; + + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sum_size; + sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = + sizes[OUTPUT][2] = sizes[REF_OUTPUT][2] = Size(0,0); + + if( cvtest::randInt(rng) % 3 > 0 ) + { + sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = sum_size; + if( cvtest::randInt(rng) % 2 > 0 ) + sizes[REF_OUTPUT][2] = sizes[OUTPUT][2] = sum_size; + } +} + + +double CV_IntegralTest::get_success_error_level( int, int i, int j ) +{ + int depth = test_mat[i][j].depth(); + return depth == CV_32S ? 0 : depth == CV_64F ? FLT_EPSILON : 5e-3; +} + + +int CV_IntegralTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + return code > 0 && ((test_array[OUTPUT][2] && test_mat[OUTPUT][2].channels() > 1) || + test_mat[OUTPUT][0].depth() < test_mat[INPUT][0].depth()) ? 0 : code; +} + + +void CV_IntegralTest::run_func() +{ + cvIntegral( test_array[INPUT][0], test_array[OUTPUT][0], + test_array[OUTPUT][1], test_array[OUTPUT][2] ); +} + + +static void test_integral( const Mat& img, Mat* sum, Mat* sqsum, Mat* tilted ) +{ + CV_Assert( img.depth() == CV_32F ); + + sum->create(img.rows+1, img.cols+1, CV_64F); + if( sqsum ) + sqsum->create(img.rows+1, img.cols+1, CV_64F); + if( tilted ) + tilted->create(img.rows+1, img.cols+1, CV_64F); + + const float* data = img.ptr(); + double* sdata = sum->ptr(); + double* sqdata = sqsum ? sqsum->ptr() : 0; + double* tdata = tilted ? tilted->ptr() : 0; + int step = (int)(img.step/sizeof(data[0])); + int sstep = (int)(sum->step/sizeof(sdata[0])); + int sqstep = sqsum ? (int)(sqsum->step/sizeof(sqdata[0])) : 0; + int tstep = tilted ? (int)(tilted->step/sizeof(tdata[0])) : 0; + Size size = img.size(); + + memset( sdata, 0, (size.width+1)*sizeof(sdata[0]) ); + if( sqsum ) + memset( sqdata, 0, (size.width+1)*sizeof(sqdata[0]) ); + if( tilted ) + memset( tdata, 0, (size.width+1)*sizeof(tdata[0]) ); + + for( ; size.height--; data += step ) + { + double s = 0, sq = 0; + int x; + sdata += sstep; + sqdata += sqstep; + tdata += tstep; + + for( x = 0; x <= size.width; x++ ) + { + double t = x > 0 ? data[x-1] : 0, ts = t; + s += t; + sq += t*t; + + sdata[x] = s + sdata[x - sstep]; + if( sqdata ) + sqdata[x] = sq + sqdata[x - sqstep]; + + if( !tdata ) + continue; + + if( x == 0 ) + ts += tdata[-tstep+1]; + else + { + ts += tdata[x-tstep-1]; + if( data > img.ptr() ) + { + ts += data[x-step-1]; + if( x < size.width ) + ts += tdata[x-tstep+1] - tdata[x-tstep*2]; + } + } + + tdata[x] = ts; + } + } +} + + +void CV_IntegralTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0]; + int cn = src.channels(); + + Mat* sum0 = &test_mat[REF_OUTPUT][0]; + Mat* sqsum0 = test_array[REF_OUTPUT][1] ? &test_mat[REF_OUTPUT][1] : 0; + Mat* tsum0 = test_array[REF_OUTPUT][2] ? &test_mat[REF_OUTPUT][2] : 0; + + Mat plane, srcf, psum, psqsum, ptsum, psum2, psqsum2, ptsum2; + if( cn == 1 ) + { + plane = src; + psum2 = *sum0; + psqsum2 = sqsum0 ? *sqsum0 : Mat(); + ptsum2 = tsum0 ? *tsum0 : Mat(); + } + + for( int i = 0; i < cn; i++ ) + { + if( cn > 1 ) + cvtest::extract(src, plane, i); + plane.convertTo(srcf, CV_32F); + + test_integral( srcf, &psum, sqsum0 ? &psqsum : 0, tsum0 ? &ptsum : 0 ); + psum.convertTo(psum2, sum0->depth()); + if( sqsum0 ) + psqsum.convertTo(psqsum2, sqsum0->depth()); + if( tsum0 ) + ptsum.convertTo(ptsum2, tsum0->depth()); + + if( cn > 1 ) + { + cvtest::insert(psum2, *sum0, i); + if( sqsum0 ) + cvtest::insert(psqsum2, *sqsum0, i); + if( tsum0 ) + cvtest::insert(ptsum2, *tsum0, i); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////// + +TEST(Imgproc_Erode, accuracy) { CV_ErodeTest test; test.safe_run(); } +TEST(Imgproc_Dilate, accuracy) { CV_DilateTest test; test.safe_run(); } +TEST(Imgproc_MorphologyEx, accuracy) { CV_MorphExTest test; test.safe_run(); } +TEST(Imgproc_Filter2D, accuracy) { CV_FilterTest test; test.safe_run(); } +TEST(Imgproc_Sobel, accuracy) { CV_SobelTest test; test.safe_run(); } +TEST(Imgproc_Laplace, accuracy) { CV_LaplaceTest test; test.safe_run(); } +TEST(Imgproc_Blur, accuracy) { CV_BlurTest test; test.safe_run(); } +TEST(Imgproc_GaussianBlur, accuracy) { CV_GaussianBlurTest test; test.safe_run(); } +TEST(Imgproc_MedianBlur, accuracy) { CV_MedianBlurTest test; test.safe_run(); } +TEST(Imgproc_PyramidDown, accuracy) { CV_PyramidDownTest test; test.safe_run(); } +TEST(Imgproc_PyramidUp, accuracy) { CV_PyramidUpTest test; test.safe_run(); } +TEST(Imgproc_MinEigenVal, accuracy) { CV_MinEigenValTest test; test.safe_run(); } +TEST(Imgproc_EigenValsVecs, accuracy) { CV_EigenValVecTest test; test.safe_run(); } +TEST(Imgproc_PreCornerDetect, accuracy) { CV_PreCornerDetectTest test; test.safe_run(); } +TEST(Imgproc_Integral, accuracy) { CV_IntegralTest test; test.safe_run(); } + +////////////////////////////////////////////////////////////////////////////////// + +class CV_FilterSupportedFormatsTest : public cvtest::BaseTest +{ +public: + CV_FilterSupportedFormatsTest() {} + ~CV_FilterSupportedFormatsTest() {} +protected: + void run(int) + { + const int depths[][2] = + { + {CV_8U, CV_8U}, + {CV_8U, CV_16U}, + {CV_8U, CV_16S}, + {CV_8U, CV_32F}, + {CV_8U, CV_64F}, + {CV_16U, CV_16U}, + {CV_16U, CV_32F}, + {CV_16U, CV_64F}, + {CV_16S, CV_16S}, + {CV_16S, CV_32F}, + {CV_16S, CV_64F}, + {CV_32F, CV_32F}, + {CV_64F, CV_64F}, + {-1, -1} + }; + + int i = 0; + volatile int fidx = -1; + try + { + // use some "odd" size to do yet another smoke + // testing of the non-SIMD loop tails + Size sz(163, 117); + Mat small_kernel(5, 5, CV_32F), big_kernel(21, 21, CV_32F); + Mat kernelX(11, 1, CV_32F), kernelY(7, 1, CV_32F); + Mat symkernelX(11, 1, CV_32F), symkernelY(7, 1, CV_32F); + randu(small_kernel, -10, 10); + randu(big_kernel, -1, 1); + randu(kernelX, -1, 1); + randu(kernelY, -1, 1); + flip(kernelX, symkernelX, 0); + symkernelX += kernelX; + flip(kernelY, symkernelY, 0); + symkernelY += kernelY; + + Mat elem_ellipse = getStructuringElement(MORPH_ELLIPSE, Size(7, 7)); + Mat elem_rect = getStructuringElement(MORPH_RECT, Size(7, 7)); + + for( i = 0; depths[i][0] >= 0; i++ ) + { + int sdepth = depths[i][0]; + int ddepth = depths[i][1]; + Mat src(sz, CV_MAKETYPE(sdepth, 5)), dst; + randu(src, 0, 100); + // non-separable filtering with a small kernel + fidx = 0; + filter2D(src, dst, ddepth, small_kernel); + fidx++; + filter2D(src, dst, ddepth, big_kernel); + fidx++; + sepFilter2D(src, dst, ddepth, kernelX, kernelY); + fidx++; + sepFilter2D(src, dst, ddepth, symkernelX, symkernelY); + fidx++; + Sobel(src, dst, ddepth, 2, 0, 5); + fidx++; + Scharr(src, dst, ddepth, 0, 1); + if( sdepth != ddepth ) + continue; + fidx++; + GaussianBlur(src, dst, Size(5, 5), 1.2, 1.2); + fidx++; + blur(src, dst, Size(11, 11)); + fidx++; + morphologyEx(src, dst, MORPH_GRADIENT, elem_ellipse); + fidx++; + morphologyEx(src, dst, MORPH_GRADIENT, elem_rect); + } + } + catch(...) + { + ts->printf(cvtest::TS::LOG, "Combination of depths %d => %d in %s is not supported (yet it should be)", + depths[i][0], depths[i][1], + fidx == 0 ? "filter2D (small kernel)" : + fidx == 1 ? "filter2D (large kernel)" : + fidx == 2 ? "sepFilter2D" : + fidx == 3 ? "sepFilter2D (symmetrical/asymmetrical kernel)" : + fidx == 4 ? "Sobel" : + fidx == 5 ? "Scharr" : + fidx == 6 ? "GaussianBlur" : + fidx == 7 ? "blur" : + fidx == 8 || fidx == 9 ? "morphologyEx" : + "unknown???"); + + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Imgproc_Filtering, supportedFormats) { CV_FilterSupportedFormatsTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_floodfill.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_floodfill.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_floodfill.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_floodfill.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,522 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_FloodFillTest : public cvtest::ArrayTest +{ +public: + CV_FloodFillTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int ); + + void fill_array( int test_case_idx, int i, int j, Mat& arr ); + + /*int write_default_params(CvFileStorage* fs); + void get_timing_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types + CvSize** whole_sizes, bool *are_images ); + void print_timing_params( int test_case_idx, char* ptr, int params_left );*/ + CvPoint seed_pt; + CvScalar new_val; + CvScalar l_diff, u_diff; + int connectivity; + bool use_mask, mask_only; + int range_type; + int new_mask_val; + bool test_cpp; +}; + + +CV_FloodFillTest::CV_FloodFillTest() +{ + test_array[INPUT_OUTPUT].push_back(NULL); + test_array[INPUT_OUTPUT].push_back(NULL); + test_array[REF_INPUT_OUTPUT].push_back(NULL); + test_array[REF_INPUT_OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + optional_mask = false; + element_wise_relative_error = true; + + test_cpp = false; +} + + +void CV_FloodFillTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, + vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth, cn; + int i; + double buff[8]; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + + depth = cvtest::randInt(rng) % 3; + depth = depth == 0 ? CV_8U : depth == 1 ? CV_32S : CV_32F; + cn = cvtest::randInt(rng) & 1 ? 3 : 1; + + use_mask = (cvtest::randInt(rng) & 1) != 0; + connectivity = (cvtest::randInt(rng) & 1) ? 4 : 8; + mask_only = use_mask && (cvtest::randInt(rng) & 1) != 0; + new_mask_val = cvtest::randInt(rng) & 255; + range_type = cvtest::randInt(rng) % 3; + + types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn); + types[INPUT_OUTPUT][1] = types[REF_INPUT_OUTPUT][1] = CV_8UC1; + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(9,1); + + if( !use_mask ) + sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(0,0); + else + { + CvSize sz = sizes[INPUT_OUTPUT][0]; + sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(sz.width+2,sz.height+2); + } + + seed_pt.x = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].width; + seed_pt.y = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].height; + + if( range_type == 0 ) + l_diff = u_diff = Scalar::all(0.); + else + { + Mat m( 1, 8, CV_16S, buff ); + rng.fill( m, RNG::NORMAL, Scalar::all(0), Scalar::all(32) ); + for( i = 0; i < 4; i++ ) + { + l_diff.val[i] = fabs(m.at(i)/16.); + u_diff.val[i] = fabs(m.at(i+4)/16.); + } + } + + new_val = Scalar::all(0.); + for( i = 0; i < cn; i++ ) + new_val.val[i] = cvtest::randReal(rng)*255; + + test_cpp = (cvtest::randInt(rng) & 256) == 0; +} + + +double CV_FloodFillTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) +{ + return i == OUTPUT ? FLT_EPSILON : j == 0 ? FLT_EPSILON : 0; +} + + +void CV_FloodFillTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + RNG& rng = ts->get_rng(); + + if( i != INPUT && i != INPUT_OUTPUT ) + { + cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); + return; + } + + if( j == 0 ) + { + Mat tmp = arr; + Scalar m = Scalar::all(128); + Scalar s = Scalar::all(10); + + if( arr.depth() == CV_32FC1 ) + tmp.create(arr.size(), CV_MAKETYPE(CV_8U, arr.channels())); + + if( range_type == 0 ) + s = Scalar::all(2); + + rng.fill(tmp, RNG::NORMAL, m, s ); + if( arr.data != tmp.data ) + cvtest::convert(tmp, arr, arr.type()); + } + else + { + Scalar l = Scalar::all(-2); + Scalar u = Scalar::all(2); + cvtest::randUni(rng, arr, l, u ); + rectangle( arr, Point(0,0), Point(arr.cols-1,arr.rows-1), Scalar::all(1), 1, 8, 0 ); + } +} + + +void CV_FloodFillTest::run_func() +{ + int flags = connectivity + (mask_only ? CV_FLOODFILL_MASK_ONLY : 0) + + (range_type == 1 ? CV_FLOODFILL_FIXED_RANGE : 0) + (new_mask_val << 8); + double* odata = test_mat[OUTPUT][0].ptr(); + + if(!test_cpp) + { + CvConnectedComp comp; + cvFloodFill( test_array[INPUT_OUTPUT][0], seed_pt, new_val, l_diff, u_diff, &comp, + flags, test_array[INPUT_OUTPUT][1] ); + odata[0] = comp.area; + odata[1] = comp.rect.x; + odata[2] = comp.rect.y; + odata[3] = comp.rect.width; + odata[4] = comp.rect.height; + odata[5] = comp.value.val[0]; + odata[6] = comp.value.val[1]; + odata[7] = comp.value.val[2]; + odata[8] = comp.value.val[3]; + } + else + { + cv::Mat img = cv::cvarrToMat(test_array[INPUT_OUTPUT][0]), + mask = test_array[INPUT_OUTPUT][1] ? cv::cvarrToMat(test_array[INPUT_OUTPUT][1]) : cv::Mat(); + cv::Rect rect; + int area; + if( !mask.data ) + area = cv::floodFill( img, seed_pt, new_val, &rect, l_diff, u_diff, flags ); + else + area = cv::floodFill( img, mask, seed_pt, new_val, &rect, l_diff, u_diff, flags ); + odata[0] = area; + odata[1] = rect.x; + odata[2] = rect.y; + odata[3] = rect.width; + odata[4] = rect.height; + odata[5] = odata[6] = odata[7] = odata[8] = 0; + } +} + + +typedef struct ff_offset_pair_t +{ + int mofs, iofs; +} +ff_offset_pair_t; + +static void +cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val, + CvScalar l_diff, CvScalar u_diff, CvMat* _mask, + double* comp, int connectivity, int range_type, + int new_mask_val, bool mask_only ) +{ + CvMemStorage* st = cvCreateMemStorage(); + ff_offset_pair_t p0, p; + CvSeq* seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(p0), st ); + CvMat* tmp = _img; + CvMat* mask; + CvRect r = cvRect( 0, 0, -1, -1 ); + int area = 0; + int i, j; + ushort* m; + float* img; + int mstep, step; + int cn = CV_MAT_CN(_img->type); + int mdelta[8], idelta[8], ncount; + int cols = _img->cols, rows = _img->rows; + int u0 = 0, u1 = 0, u2 = 0; + double s0 = 0, s1 = 0, s2 = 0; + + if( CV_MAT_DEPTH(_img->type) == CV_8U || CV_MAT_DEPTH(_img->type) == CV_32S ) + { + tmp = cvCreateMat( rows, cols, CV_MAKETYPE(CV_32F,CV_MAT_CN(_img->type)) ); + cvTsConvert(_img, tmp); + } + + mask = cvCreateMat( rows + 2, cols + 2, CV_16UC1 ); + + if( _mask ) + cvTsConvert( _mask, mask ); + else + { + cvTsZero( mask ); + cvRectangle( mask, cvPoint(0,0), cvPoint(mask->cols-1,mask->rows-1), Scalar::all(1.), 1, 8, 0 ); + } + + new_mask_val = (new_mask_val != 0 ? new_mask_val : 1) << 8; + + m = (ushort*)(mask->data.ptr + mask->step) + 1; + mstep = mask->step / sizeof(m[0]); + img = tmp->data.fl; + step = tmp->step / sizeof(img[0]); + + p0.mofs = seed_pt.y*mstep + seed_pt.x; + p0.iofs = seed_pt.y*step + seed_pt.x*cn; + + if( m[p0.mofs] ) + goto _exit_; + + cvSeqPush( seq, &p0 ); + m[p0.mofs] = (ushort)new_mask_val; + + if( connectivity == 4 ) + { + ncount = 4; + mdelta[0] = -mstep; idelta[0] = -step; + mdelta[1] = -1; idelta[1] = -cn; + mdelta[2] = 1; idelta[2] = cn; + mdelta[3] = mstep; idelta[3] = step; + } + else + { + ncount = 8; + mdelta[0] = -mstep-1; mdelta[1] = -mstep; mdelta[2] = -mstep+1; + idelta[0] = -step-cn; idelta[1] = -step; idelta[2] = -step+cn; + + mdelta[3] = -1; mdelta[4] = 1; + idelta[3] = -cn; idelta[4] = cn; + + mdelta[5] = mstep-1; mdelta[6] = mstep; mdelta[7] = mstep+1; + idelta[5] = step-cn; idelta[6] = step; idelta[7] = step+cn; + } + + if( cn == 1 ) + { + float a0 = (float)-l_diff.val[0]; + float b0 = (float)u_diff.val[0]; + + s0 = img[p0.iofs]; + + if( range_type < 2 ) + { + a0 += (float)s0; b0 += (float)s0; + } + + while( seq->total ) + { + cvSeqPop( seq, &p0 ); + float a = a0, b = b0; + float* ptr = img + p0.iofs; + ushort* mptr = m + p0.mofs; + + if( range_type == 2 ) + a += ptr[0], b += ptr[0]; + + for( i = 0; i < ncount; i++ ) + { + int md = mdelta[i], id = idelta[i]; + float v; + if( !mptr[md] && a <= (v = ptr[id]) && v <= b ) + { + mptr[md] = (ushort)new_mask_val; + p.mofs = p0.mofs + md; + p.iofs = p0.iofs + id; + cvSeqPush( seq, &p ); + } + } + } + } + else + { + float a0 = (float)-l_diff.val[0]; + float a1 = (float)-l_diff.val[1]; + float a2 = (float)-l_diff.val[2]; + float b0 = (float)u_diff.val[0]; + float b1 = (float)u_diff.val[1]; + float b2 = (float)u_diff.val[2]; + + s0 = img[p0.iofs]; + s1 = img[p0.iofs + 1]; + s2 = img[p0.iofs + 2]; + + if( range_type < 2 ) + { + a0 += (float)s0; b0 += (float)s0; + a1 += (float)s1; b1 += (float)s1; + a2 += (float)s2; b2 += (float)s2; + } + + while( seq->total ) + { + cvSeqPop( seq, &p0 ); + float _a0 = a0, _a1 = a1, _a2 = a2; + float _b0 = b0, _b1 = b1, _b2 = b2; + float* ptr = img + p0.iofs; + ushort* mptr = m + p0.mofs; + + if( range_type == 2 ) + { + _a0 += ptr[0]; _b0 += ptr[0]; + _a1 += ptr[1]; _b1 += ptr[1]; + _a2 += ptr[2]; _b2 += ptr[2]; + } + + for( i = 0; i < ncount; i++ ) + { + int md = mdelta[i], id = idelta[i]; + float v; + if( !mptr[md] && + _a0 <= (v = ptr[id]) && v <= _b0 && + _a1 <= (v = ptr[id+1]) && v <= _b1 && + _a2 <= (v = ptr[id+2]) && v <= _b2 ) + { + mptr[md] = (ushort)new_mask_val; + p.mofs = p0.mofs + md; + p.iofs = p0.iofs + id; + cvSeqPush( seq, &p ); + } + } + } + } + + r.x = r.width = seed_pt.x; + r.y = r.height = seed_pt.y; + + if( !mask_only ) + { + s0 = new_val.val[0]; + s1 = new_val.val[1]; + s2 = new_val.val[2]; + + if( tmp != _img ) + { + u0 = saturate_cast(s0); + u1 = saturate_cast(s1); + u2 = saturate_cast(s2); + + s0 = u0; + s1 = u1; + s2 = u2; + } + } + else + s0 = s1 = s2 = 0; + + new_mask_val >>= 8; + + for( i = 0; i < rows; i++ ) + { + float* ptr = img + i*step; + ushort* mptr = m + i*mstep; + uchar* dmptr = _mask ? _mask->data.ptr + (i+1)*_mask->step + 1 : 0; + double area0 = area; + + for( j = 0; j < cols; j++ ) + { + if( mptr[j] > 255 ) + { + if( dmptr ) + dmptr[j] = (uchar)new_mask_val; + if( !mask_only ) + { + if( cn == 1 ) + ptr[j] = (float)s0; + else + { + ptr[j*3] = (float)s0; + ptr[j*3+1] = (float)s1; + ptr[j*3+2] = (float)s2; + } + } + else + { + if( cn == 1 ) + s0 += ptr[j]; + else + { + s0 += ptr[j*3]; + s1 += ptr[j*3+1]; + s2 += ptr[j*3+2]; + } + } + + area++; + if( r.x > j ) + r.x = j; + if( r.width < j ) + r.width = j; + } + } + + if( area != area0 ) + { + if( r.y > i ) + r.y = i; + if( r.height < i ) + r.height = i; + } + } + +_exit_: + cvReleaseMat( &mask ); + if( tmp != _img ) + { + if( !mask_only ) + cvTsConvert(tmp, _img); + cvReleaseMat( &tmp ); + } + + comp[0] = area; + comp[1] = r.x; + comp[2] = r.y; + comp[3] = r.width - r.x + 1; + comp[4] = r.height - r.y + 1; + if( mask_only ) + { + double t = area ? 1./area : 0; + s0 *= t; + s1 *= t; + s2 *= t; + } + comp[5] = s0; + comp[6] = s1; + comp[7] = s2; + comp[8] = 0; +} + + +void CV_FloodFillTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + double* comp = test_mat[REF_OUTPUT][0].ptr(); + CvMat _input = test_mat[REF_INPUT_OUTPUT][0]; + CvMat _mask = test_mat[REF_INPUT_OUTPUT][1]; + cvTsFloodFill( &_input, seed_pt, new_val, l_diff, u_diff, + _mask.data.ptr ? &_mask : 0, + comp, connectivity, range_type, + new_mask_val, mask_only ); + if(test_cpp) + comp[5] = comp[6] = comp[7] = comp[8] = 0; +} + +TEST(Imgproc_FloodFill, accuracy) { CV_FloodFillTest test; test.safe_run(); } + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_grabcut.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_grabcut.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_grabcut.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_grabcut.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,172 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +#include +#include + +using namespace std; +using namespace cv; + +class CV_GrabcutTest : public cvtest::BaseTest +{ +public: + CV_GrabcutTest(); + ~CV_GrabcutTest(); +protected: + bool verify(const Mat& mask, const Mat& exp); + void run(int); +}; + +CV_GrabcutTest::CV_GrabcutTest() {} +CV_GrabcutTest::~CV_GrabcutTest() {} + +bool CV_GrabcutTest::verify(const Mat& mask, const Mat& exp) +{ + const float maxDiffRatio = 0.005f; + int expArea = countNonZero( exp ); + int nonIntersectArea = countNonZero( mask != exp ); + + float curRatio = (float)nonIntersectArea / (float)expArea; + ts->printf( cvtest::TS::LOG, "nonIntersectArea/expArea = %f\n", curRatio ); + return curRatio < maxDiffRatio; +} + +void CV_GrabcutTest::run( int /* start_from */) +{ + cvtest::DefaultRngAuto defRng; + + Mat img = imread(string(ts->get_data_path()) + "shared/airplane.png"); + Mat mask_prob = imread(string(ts->get_data_path()) + "grabcut/mask_prob.png", 0); + Mat exp_mask1 = imread(string(ts->get_data_path()) + "grabcut/exp_mask1.png", 0); + Mat exp_mask2 = imread(string(ts->get_data_path()) + "grabcut/exp_mask2.png", 0); + + if (img.empty() || (!mask_prob.empty() && img.size() != mask_prob.size()) || + (!exp_mask1.empty() && img.size() != exp_mask1.size()) || + (!exp_mask2.empty() && img.size() != exp_mask2.size()) ) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); + return; + } + + Rect rect(Point(24, 126), Point(483, 294)); + Mat exp_bgdModel, exp_fgdModel; + + Mat mask; + mask = Scalar(0); + Mat bgdModel, fgdModel; + grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_RECT ); + grabCut( img, mask, rect, bgdModel, fgdModel, 2, GC_EVAL ); + + // Multiply images by 255 for more visuality of test data. + if( mask_prob.empty() ) + { + mask.copyTo( mask_prob ); + imwrite(string(ts->get_data_path()) + "grabcut/mask_prob.png", mask_prob); + } + if( exp_mask1.empty() ) + { + exp_mask1 = (mask & 1) * 255; + imwrite(string(ts->get_data_path()) + "grabcut/exp_mask1.png", exp_mask1); + } + + if (!verify((mask & 1) * 255, exp_mask1)) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return; + } + + mask = mask_prob; + bgdModel.release(); + fgdModel.release(); + rect = Rect(); + grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_MASK ); + grabCut( img, mask, rect, bgdModel, fgdModel, 1, GC_EVAL ); + + if( exp_mask2.empty() ) + { + exp_mask2 = (mask & 1) * 255; + imwrite(string(ts->get_data_path()) + "grabcut/exp_mask2.png", exp_mask2); + } + + if (!verify((mask & 1) * 255, exp_mask2)) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return; + } + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Imgproc_GrabCut, regression) { CV_GrabcutTest test; test.safe_run(); } + +TEST(Imgproc_GrabCut, repeatability) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + + Mat image_1 = imread(string(ts.get_data_path()) + "grabcut/image1652.ppm", CV_LOAD_IMAGE_COLOR); + Mat mask_1 = imread(string(ts.get_data_path()) + "grabcut/mask1652.ppm", CV_LOAD_IMAGE_GRAYSCALE); + Rect roi_1(0, 0, 150, 150); + + Mat image_2 = image_1.clone(); + Mat mask_2 = mask_1.clone(); + Rect roi_2 = roi_1; + + Mat image_3 = image_1.clone(); + Mat mask_3 = mask_1.clone(); + Rect roi_3 = roi_1; + + Mat bgdModel_1, fgdModel_1; + Mat bgdModel_2, fgdModel_2; + Mat bgdModel_3, fgdModel_3; + + theRNG().state = 12378213; + grabCut(image_1, mask_1, roi_1, bgdModel_1, fgdModel_1, 1, GC_INIT_WITH_MASK); + theRNG().state = 12378213; + grabCut(image_2, mask_2, roi_2, bgdModel_2, fgdModel_2, 1, GC_INIT_WITH_MASK); + theRNG().state = 12378213; + grabCut(image_3, mask_3, roi_3, bgdModel_3, fgdModel_3, 1, GC_INIT_WITH_MASK); + + EXPECT_EQ(0, countNonZero(mask_1 != mask_2)); + EXPECT_EQ(0, countNonZero(mask_1 != mask_3)); + EXPECT_EQ(0, countNonZero(mask_2 != mask_3)); +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_histograms.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_histograms.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_histograms.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_histograms.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1837 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_BaseHistTest : public cvtest::BaseTest +{ +public: + enum { MAX_HIST = 12 }; + + CV_BaseHistTest(); + ~CV_BaseHistTest(); + void clear(); + +protected: + int read_params( CvFileStorage* fs ); + void run_func(void); + int prepare_test_case( int test_case_idx ); + int validate_test_results( int test_case_idx ); + virtual void init_hist( int test_case_idx, int i ); + + virtual void get_hist_params( int test_case_idx ); + virtual float** get_hist_ranges( int test_case_idx ); + + int max_log_size; + int max_cdims; + int cdims; + int dims[CV_MAX_DIM]; + int total_size; + int hist_type; + int hist_count; + int uniform; + int gen_random_hist; + double gen_hist_max_val, gen_hist_sparse_nz_ratio; + + int init_ranges; + int img_type; + int img_max_log_size; + double low, high, range_delta; + CvSize img_size; + + vector hist; + vector _ranges; + vector ranges; + bool test_cpp; +}; + + +CV_BaseHistTest::CV_BaseHistTest() +{ + test_case_count = 100; + max_log_size = 20; + img_max_log_size = 8; + max_cdims = 6; + hist_count = 1; + init_ranges = 0; + gen_random_hist = 0; + gen_hist_max_val = 100; + + test_cpp = false; +} + + +CV_BaseHistTest::~CV_BaseHistTest() +{ + clear(); +} + + +void CV_BaseHistTest::clear() +{ + cvtest::BaseTest::clear(); + for( size_t i = 0; i < hist.size(); i++ ) + cvReleaseHist( &hist[i] ); +} + + +int CV_BaseHistTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::BaseTest::read_params( fs ); + if( code < 0 ) + return code; + + test_case_count = cvReadInt( find_param( fs, "struct_count" ), test_case_count ); + max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size ); + max_log_size = cvtest::clipInt( max_log_size, 1, 20 ); + img_max_log_size = cvReadInt( find_param( fs, "max_log_array_size" ), img_max_log_size ); + img_max_log_size = cvtest::clipInt( img_max_log_size, 1, 9 ); + + max_cdims = cvReadInt( find_param( fs, "max_cdims" ), max_cdims ); + max_cdims = cvtest::clipInt( max_cdims, 1, 6 ); + + return 0; +} + + +void CV_BaseHistTest::get_hist_params( int /*test_case_idx*/ ) +{ + RNG& rng = ts->get_rng(); + int i, max_dim_size, max_ni_dim_size = 31; + double hist_size; + + cdims = cvtest::randInt(rng) % max_cdims + 1; + hist_size = exp(cvtest::randReal(rng)*max_log_size*CV_LOG2); + max_dim_size = cvRound(pow(hist_size,1./cdims)); + total_size = 1; + uniform = cvtest::randInt(rng) % 2; + hist_type = cvtest::randInt(rng) % 2 ? CV_HIST_SPARSE : CV_HIST_ARRAY; + + for( i = 0; i < cdims; i++ ) + { + dims[i] = cvtest::randInt(rng) % (max_dim_size + 2) + 2; + if( !uniform ) + dims[i] = MIN(dims[i], max_ni_dim_size); + total_size *= dims[i]; + } + + img_type = cvtest::randInt(rng) % 2 ? CV_32F : CV_8U; + img_size.width = cvRound( exp(cvtest::randReal(rng) * img_max_log_size * CV_LOG2) ); + img_size.height = cvRound( exp(cvtest::randReal(rng) * img_max_log_size * CV_LOG2) ); + + if( img_type < CV_32F ) + { + low = cvtest::getMinVal(img_type); + high = cvtest::getMaxVal(img_type); + } + else + { + high = 1000; + low = -high; + } + + range_delta = (cvtest::randInt(rng) % 2)*(high-low)*0.05; +} + + +float** CV_BaseHistTest::get_hist_ranges( int /*test_case_idx*/ ) +{ + double _low = low + range_delta, _high = high - range_delta; + + if( !init_ranges ) + return 0; + + ranges.resize(cdims); + + if( uniform ) + { + _ranges.resize(cdims*2); + for( int i = 0; i < cdims; i++ ) + { + _ranges[i*2] = (float)_low; + _ranges[i*2+1] = (float)_high; + ranges[i] = &_ranges[i*2]; + } + } + else + { + int i, dims_sum = 0, ofs = 0; + for( i = 0; i < cdims; i++ ) + dims_sum += dims[i] + 1; + _ranges.resize(dims_sum); + + for( i = 0; i < cdims; i++ ) + { + int j, n = dims[i]; + // generate logarithmic scale + double delta, q, val; + for( j = 0; j < 10; j++ ) + { + q = 1. + (j+1)*0.1; + if( (pow(q,(double)n)-1)/(q-1.) >= _high-_low ) + break; + } + + if( j == 0 ) + { + delta = (_high-_low)/n; + q = 1.; + } + else + { + q = 1 + j*0.1; + delta = cvFloor((_high-_low)*(q-1)/(pow(q,(double)n) - 1)); + delta = MAX(delta, 1.); + } + val = _low; + + for( j = 0; j <= n; j++ ) + { + _ranges[j+ofs] = (float)MIN(val,_high); + val += delta; + delta *= q; + } + ranges[i] = &_ranges[ofs]; + ofs += n + 1; + } + } + + return &ranges[0]; +} + + +void CV_BaseHistTest::init_hist( int /*test_case_idx*/, int hist_i ) +{ + if( gen_random_hist ) + { + RNG& rng = ts->get_rng(); + + if( hist_type == CV_HIST_ARRAY ) + { + Mat h = cvarrToMat(hist[hist_i]->bins); + cvtest::randUni(rng, h, Scalar::all(0), Scalar::all(gen_hist_max_val) ); + } + else + { + CvArr* arr = hist[hist_i]->bins; + int i, j, totalSize = 1, nz_count; + int idx[CV_MAX_DIM]; + for( i = 0; i < cdims; i++ ) + totalSize *= dims[i]; + + nz_count = cvtest::randInt(rng) % MAX( totalSize/4, 100 ); + nz_count = MIN( nz_count, totalSize ); + + // a zero number of non-zero elements should be allowed + for( i = 0; i < nz_count; i++ ) + { + for( j = 0; j < cdims; j++ ) + idx[j] = cvtest::randInt(rng) % dims[j]; + cvSetRealND(arr, idx, cvtest::randReal(rng)*gen_hist_max_val); + } + } + } +} + + +int CV_BaseHistTest::prepare_test_case( int test_case_idx ) +{ + int i; + float** r; + + clear(); + + cvtest::BaseTest::prepare_test_case( test_case_idx ); + get_hist_params( test_case_idx ); + r = get_hist_ranges( test_case_idx ); + hist.resize(hist_count); + + for( i = 0; i < hist_count; i++ ) + { + hist[i] = cvCreateHist( cdims, dims, hist_type, r, uniform ); + init_hist( test_case_idx, i ); + } + test_cpp = (cvtest::randInt(ts->get_rng()) % 2) != 0; + + return 1; +} + + +void CV_BaseHistTest::run_func(void) +{ +} + + +int CV_BaseHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + return 0; +} + + +////////////// testing operation for reading/writing individual histogram bins ////////////// + +class CV_QueryHistTest : public CV_BaseHistTest +{ +public: + CV_QueryHistTest(); + ~CV_QueryHistTest(); + void clear(); + +protected: + void run_func(void); + int prepare_test_case( int test_case_idx ); + int validate_test_results( int test_case_idx ); + void init_hist( int test_case_idx, int i ); + + CvMat* indices; + CvMat* values; + CvMat* values0; +}; + + + +CV_QueryHistTest::CV_QueryHistTest() +{ + hist_count = 1; + indices = 0; + values = 0; + values0 = 0; +} + + +CV_QueryHistTest::~CV_QueryHistTest() +{ + clear(); +} + + +void CV_QueryHistTest::clear() +{ + cvReleaseMat( &indices ); + cvReleaseMat( &values ); + cvReleaseMat( &values0 ); + CV_BaseHistTest::clear(); +} + + +void CV_QueryHistTest::init_hist( int /*test_case_idx*/, int i ) +{ + if( hist_type == CV_HIST_ARRAY ) + cvZero( hist[i]->bins ); +} + + +int CV_QueryHistTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + int i, j, iters; + float default_value = 0.f; + RNG& rng = ts->get_rng(); + CvMat* bit_mask = 0; + int* idx; + + iters = (cvtest::randInt(rng) % MAX(total_size/10,100)) + 1; + iters = MIN( iters, total_size*9/10 + 1 ); + + indices = cvCreateMat( 1, iters*cdims, CV_32S ); + values = cvCreateMat( 1, iters, CV_32F ); + values0 = cvCreateMat( 1, iters, CV_32F ); + idx = indices->data.i; + + //printf( "total_size = %d, cdims = %d, iters = %d\n", total_size, cdims, iters ); + + bit_mask = cvCreateMat( 1, (total_size + 7)/8, CV_8U ); + cvZero( bit_mask ); + + #define GET_BIT(n) (bit_mask->data.ptr[(n)/8] & (1 << ((n)&7))) + #define SET_BIT(n) bit_mask->data.ptr[(n)/8] |= (1 << ((n)&7)) + + // set random histogram bins' values to the linear indices of the bins + for( i = 0; i < iters; i++ ) + { + int lin_idx = 0; + for( j = 0; j < cdims; j++ ) + { + int t = cvtest::randInt(rng) % dims[j]; + idx[i*cdims + j] = t; + lin_idx = lin_idx*dims[j] + t; + } + + if( cvtest::randInt(rng) % 8 || GET_BIT(lin_idx) ) + { + values0->data.fl[i] = (float)(lin_idx+1); + SET_BIT(lin_idx); + } + else + // some histogram bins will not be initialized intentionally, + // they should be equal to the default value + values0->data.fl[i] = default_value; + } + + // do the second pass to make values0 consistent with bit_mask + for( i = 0; i < iters; i++ ) + { + int lin_idx = 0; + for( j = 0; j < cdims; j++ ) + lin_idx = lin_idx*dims[j] + idx[i*cdims + j]; + + if( GET_BIT(lin_idx) ) + values0->data.fl[i] = (float)(lin_idx+1); + } + + cvReleaseMat( &bit_mask ); + } + + return code; +} + + +void CV_QueryHistTest::run_func(void) +{ + int i, iters = values->cols; + CvArr* h = hist[0]->bins; + const int* idx = indices->data.i; + float* val = values->data.fl; + float default_value = 0.f; + + // stage 1: write bins + if( cdims == 1 ) + for( i = 0; i < iters; i++ ) + { + float v0 = values0->data.fl[i]; + if( fabs(v0 - default_value) < FLT_EPSILON ) + continue; + if( !(i % 2) ) + { + if( !(i % 4) ) + cvSetReal1D( h, idx[i], v0 ); + else + *(float*)cvPtr1D( h, idx[i] ) = v0; + } + else + cvSetRealND( h, idx+i, v0 ); + } + else if( cdims == 2 ) + for( i = 0; i < iters; i++ ) + { + float v0 = values0->data.fl[i]; + if( fabs(v0 - default_value) < FLT_EPSILON ) + continue; + if( !(i % 2) ) + { + if( !(i % 4) ) + cvSetReal2D( h, idx[i*2], idx[i*2+1], v0 ); + else + *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] ) = v0; + } + else + cvSetRealND( h, idx+i*2, v0 ); + } + else if( cdims == 3 ) + for( i = 0; i < iters; i++ ) + { + float v0 = values0->data.fl[i]; + if( fabs(v0 - default_value) < FLT_EPSILON ) + continue; + if( !(i % 2) ) + { + if( !(i % 4) ) + cvSetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2], v0 ); + else + *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ) = v0; + } + else + cvSetRealND( h, idx+i*3, v0 ); + } + else + for( i = 0; i < iters; i++ ) + { + float v0 = values0->data.fl[i]; + if( fabs(v0 - default_value) < FLT_EPSILON ) + continue; + if( !(i % 2) ) + cvSetRealND( h, idx+i*cdims, v0 ); + else + *(float*)cvPtrND( h, idx+i*cdims ) = v0; + } + + // stage 2: read bins + if( cdims == 1 ) + for( i = 0; i < iters; i++ ) + { + if( !(i % 2) ) + val[i] = *(float*)cvPtr1D( h, idx[i] ); + else + val[i] = (float)cvGetReal1D( h, idx[i] ); + } + else if( cdims == 2 ) + for( i = 0; i < iters; i++ ) + { + if( !(i % 2) ) + val[i] = *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] ); + else + val[i] = (float)cvGetReal2D( h, idx[i*2], idx[i*2+1] ); + } + else if( cdims == 3 ) + for( i = 0; i < iters; i++ ) + { + if( !(i % 2) ) + val[i] = *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ); + else + val[i] = (float)cvGetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ); + } + else + for( i = 0; i < iters; i++ ) + { + if( !(i % 2) ) + val[i] = *(float*)cvPtrND( h, idx+i*cdims ); + else + val[i] = (float)cvGetRealND( h, idx+i*cdims ); + } +} + + +int CV_QueryHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + int i, j, iters = values->cols; + + for( i = 0; i < iters; i++ ) + { + float v = values->data.fl[i], v0 = values0->data.fl[i]; + + if( cvIsNaN(v) || cvIsInf(v) ) + { + ts->printf( cvtest::TS::LOG, "The bin #%d has invalid value\n", i ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + else if( fabs(v - v0) > FLT_EPSILON ) + { + ts->printf( cvtest::TS::LOG, "The bin #%d = %g, while it should be %g\n", i, v, v0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + + if( code < 0 ) + { + ts->printf( cvtest::TS::LOG, "The bin index = (" ); + for( j = 0; j < cdims; j++ ) + ts->printf( cvtest::TS::LOG, "%d%s", indices->data.i[i*cdims + j], + j < cdims-1 ? ", " : ")\n" ); + break; + } + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +////////////// cvGetMinMaxHistValue ////////////// + +class CV_MinMaxHistTest : public CV_BaseHistTest +{ +public: + CV_MinMaxHistTest(); + +protected: + void run_func(void); + void init_hist(int, int); + int validate_test_results( int test_case_idx ); + int min_idx[CV_MAX_DIM], max_idx[CV_MAX_DIM]; + float min_val, max_val; + int min_idx0[CV_MAX_DIM], max_idx0[CV_MAX_DIM]; + float min_val0, max_val0; +}; + + + +CV_MinMaxHistTest::CV_MinMaxHistTest() +{ + hist_count = 1; + gen_random_hist = 1; +} + + +void CV_MinMaxHistTest::init_hist(int test_case_idx, int hist_i) +{ + int i, eq = 1; + RNG& rng = ts->get_rng(); + CV_BaseHistTest::init_hist( test_case_idx, hist_i ); + + for(;;) + { + for( i = 0; i < cdims; i++ ) + { + min_idx0[i] = cvtest::randInt(rng) % dims[i]; + max_idx0[i] = cvtest::randInt(rng) % dims[i]; + eq &= min_idx0[i] == max_idx0[i]; + } + if( !eq || total_size == 1 ) + break; + } + + min_val0 = (float)(-cvtest::randReal(rng)*10 - FLT_EPSILON); + max_val0 = (float)(cvtest::randReal(rng)*10 + FLT_EPSILON + gen_hist_max_val); + + if( total_size == 1 ) + min_val0 = max_val0; + + cvSetRealND( hist[0]->bins, min_idx0, min_val0 ); + cvSetRealND( hist[0]->bins, max_idx0, max_val0 ); +} + + +void CV_MinMaxHistTest::run_func(void) +{ + if( hist_type != CV_HIST_ARRAY && test_cpp ) + { + cv::SparseMat h((CvSparseMat*)hist[0]->bins); + double _min_val = 0, _max_val = 0; + cv::minMaxLoc(h, &_min_val, &_max_val, min_idx, max_idx ); + min_val = (float)_min_val; + max_val = (float)_max_val; + } + else + cvGetMinMaxHistValue( hist[0], &min_val, &max_val, min_idx, max_idx ); +} + + +int CV_MinMaxHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + + if( cvIsNaN(min_val) || cvIsInf(min_val) || + cvIsNaN(max_val) || cvIsInf(max_val) ) + { + ts->printf( cvtest::TS::LOG, + "The extrema histogram bin values are invalid (min = %g, max = %g)\n", min_val, max_val ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + else if( fabs(min_val - min_val0) > FLT_EPSILON || + fabs(max_val - max_val0) > FLT_EPSILON ) + { + ts->printf( cvtest::TS::LOG, + "The extrema histogram bin values are incorrect: (min = %g, should be = %g), (max = %g, should be = %g)\n", + min_val, min_val0, max_val, max_val0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + else + { + int i; + for( i = 0; i < cdims; i++ ) + { + if( min_idx[i] != min_idx0[i] || max_idx[i] != max_idx0[i] ) + { + ts->printf( cvtest::TS::LOG, + "The %d-th coordinates of extrema histogram bin values are incorrect: " + "(min = %d, should be = %d), (max = %d, should be = %d)\n", + i, min_idx[i], min_idx0[i], max_idx[i], max_idx0[i] ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + } + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +////////////// cvNormalizeHist ////////////// + +class CV_NormHistTest : public CV_BaseHistTest +{ +public: + CV_NormHistTest(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + double factor; +}; + + + +CV_NormHistTest::CV_NormHistTest() +{ + hist_count = 1; + gen_random_hist = 1; + factor = 0; +} + + +int CV_NormHistTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + RNG& rng = ts->get_rng(); + factor = cvtest::randReal(rng)*10 + 0.1; + if( hist_type == CV_HIST_SPARSE && + ((CvSparseMat*)hist[0]->bins)->heap->active_count == 0 ) + factor = 0; + } + + return code; +} + + +void CV_NormHistTest::run_func(void) +{ + if( hist_type != CV_HIST_ARRAY && test_cpp ) + { + cv::SparseMat h((CvSparseMat*)hist[0]->bins); + cv::normalize(h, h, factor, CV_L1); + cvReleaseSparseMat((CvSparseMat**)&hist[0]->bins); + hist[0]->bins = (CvSparseMat*)h; + } + else + cvNormalizeHist( hist[0], factor ); +} + + +int CV_NormHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + double sum = 0; + + if( hist_type == CV_HIST_ARRAY ) + { + int i; + const float* ptr = (float*)cvPtr1D( hist[0]->bins, 0 ); + + for( i = 0; i < total_size; i++ ) + sum += ptr[i]; + } + else + { + CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins; + CvSparseMatIterator iterator; + CvSparseNode *node; + + for( node = cvInitSparseMatIterator( sparse, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator )) + { + sum += *(float*)CV_NODE_VAL(sparse,node); + } + } + + if( cvIsNaN(sum) || cvIsInf(sum) ) + { + ts->printf( cvtest::TS::LOG, + "The normalized histogram has invalid sum =%g\n", sum ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + else if( fabs(sum - factor) > FLT_EPSILON*10*fabs(factor) ) + { + ts->printf( cvtest::TS::LOG, + "The normalized histogram has incorrect sum =%g, while it should be =%g\n", sum, factor ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +////////////// cvThreshHist ////////////// + +class CV_ThreshHistTest : public CV_BaseHistTest +{ +public: + CV_ThreshHistTest(); + ~CV_ThreshHistTest(); + void clear(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + CvMat* indices; + CvMat* values; + int orig_nz_count; + + double threshold; +}; + + + +CV_ThreshHistTest::CV_ThreshHistTest() +{ + hist_count = 1; + gen_random_hist = 1; + threshold = 0; + indices = values = 0; +} + + +CV_ThreshHistTest::~CV_ThreshHistTest() +{ + clear(); +} + + +void CV_ThreshHistTest::clear() +{ + cvReleaseMat( &indices ); + cvReleaseMat( &values ); + CV_BaseHistTest::clear(); +} + + +int CV_ThreshHistTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + RNG& rng = ts->get_rng(); + threshold = cvtest::randReal(rng)*gen_hist_max_val; + + if( hist_type == CV_HIST_ARRAY ) + { + orig_nz_count = total_size; + + values = cvCreateMat( 1, total_size, CV_32F ); + memcpy( values->data.fl, cvPtr1D( hist[0]->bins, 0 ), total_size*sizeof(float) ); + } + else + { + CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins; + CvSparseMatIterator iterator; + CvSparseNode* node; + int i, k; + + orig_nz_count = sparse->heap->active_count; + + values = cvCreateMat( 1, orig_nz_count+1, CV_32F ); + indices = cvCreateMat( 1, (orig_nz_count+1)*cdims, CV_32S ); + + for( node = cvInitSparseMatIterator( sparse, &iterator ), i = 0; + node != 0; node = cvGetNextSparseNode( &iterator ), i++ ) + { + const int* idx = CV_NODE_IDX(sparse,node); + + OPENCV_ASSERT( i < orig_nz_count, "CV_ThreshHistTest::prepare_test_case", "Buffer overflow" ); + + values->data.fl[i] = *(float*)CV_NODE_VAL(sparse,node); + for( k = 0; k < cdims; k++ ) + indices->data.i[i*cdims + k] = idx[k]; + } + + OPENCV_ASSERT( i == orig_nz_count, "Unmatched buffer size", + "CV_ThreshHistTest::prepare_test_case" ); + } + } + + return code; +} + + +void CV_ThreshHistTest::run_func(void) +{ + cvThreshHist( hist[0], threshold ); +} + + +int CV_ThreshHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + int i; + float* ptr0 = values->data.fl; + float* ptr = 0; + CvSparseMat* sparse = 0; + + if( hist_type == CV_HIST_ARRAY ) + ptr = (float*)cvPtr1D( hist[0]->bins, 0 ); + else + sparse = (CvSparseMat*)hist[0]->bins; + + if( code > 0 ) + { + for( i = 0; i < orig_nz_count; i++ ) + { + float v0 = ptr0[i], v; + + if( hist_type == CV_HIST_ARRAY ) + v = ptr[i]; + else + { + v = (float)cvGetRealND( sparse, indices->data.i + i*cdims ); + cvClearND( sparse, indices->data.i + i*cdims ); + } + + if( v0 <= threshold ) v0 = 0.f; + if( cvIsNaN(v) || cvIsInf(v) ) + { + ts->printf( cvtest::TS::LOG, "The %d-th bin is invalid (=%g)\n", i, v ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + break; + } + else if( fabs(v0 - v) > FLT_EPSILON*10*fabs(v0) ) + { + ts->printf( cvtest::TS::LOG, "The %d-th bin is incorrect (=%g, should be =%g)\n", i, v, v0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + break; + } + } + } + + if( code > 0 && hist_type == CV_HIST_SPARSE ) + { + if( sparse->heap->active_count > 0 ) + { + ts->printf( cvtest::TS::LOG, + "There some extra histogram bins in the sparse histogram after the thresholding\n" ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + } + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +////////////// cvCompareHist ////////////// + +class CV_CompareHistTest : public CV_BaseHistTest +{ +public: + enum { MAX_METHOD = 4 }; + + CV_CompareHistTest(); +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + double result[MAX_METHOD+1]; +}; + + + +CV_CompareHistTest::CV_CompareHistTest() +{ + hist_count = 2; + gen_random_hist = 1; +} + + +int CV_CompareHistTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + return code; +} + + +void CV_CompareHistTest::run_func(void) +{ + int k; + if( hist_type != CV_HIST_ARRAY && test_cpp ) + { + cv::SparseMat h0((CvSparseMat*)hist[0]->bins); + cv::SparseMat h1((CvSparseMat*)hist[1]->bins); + for( k = 0; k < MAX_METHOD; k++ ) + result[k] = cv::compareHist(h0, h1, k); + } + else + for( k = 0; k < MAX_METHOD; k++ ) + result[k] = cvCompareHist( hist[0], hist[1], k ); +} + + +int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + int i; + double result0[MAX_METHOD+1]; + double s0 = 0, s1 = 0, sq0 = 0, sq1 = 0, t; + + for( i = 0; i < MAX_METHOD; i++ ) + result0[i] = 0; + + if( hist_type == CV_HIST_ARRAY ) + { + float* ptr0 = (float*)cvPtr1D( hist[0]->bins, 0 ); + float* ptr1 = (float*)cvPtr1D( hist[1]->bins, 0 ); + + for( i = 0; i < total_size; i++ ) + { + double v0 = ptr0[i], v1 = ptr1[i]; + result0[CV_COMP_CORREL] += v0*v1; + result0[CV_COMP_INTERSECT] += MIN(v0,v1); + if( fabs(v0) > DBL_EPSILON ) + result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0; + s0 += v0; + s1 += v1; + sq0 += v0*v0; + sq1 += v1*v1; + result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1); + } + } + else + { + CvSparseMat* sparse0 = (CvSparseMat*)hist[0]->bins; + CvSparseMat* sparse1 = (CvSparseMat*)hist[1]->bins; + CvSparseMatIterator iterator; + CvSparseNode* node; + + for( node = cvInitSparseMatIterator( sparse0, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator ) ) + { + const int* idx = CV_NODE_IDX(sparse0, node); + double v0 = *(float*)CV_NODE_VAL(sparse0, node); + double v1 = (float)cvGetRealND(sparse1, idx); + + result0[CV_COMP_CORREL] += v0*v1; + result0[CV_COMP_INTERSECT] += MIN(v0,v1); + if( fabs(v0) > DBL_EPSILON ) + result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0; + s0 += v0; + sq0 += v0*v0; + result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1); + } + + for( node = cvInitSparseMatIterator( sparse1, &iterator ); + node != 0; node = cvGetNextSparseNode( &iterator ) ) + { + double v1 = *(float*)CV_NODE_VAL(sparse1, node); + s1 += v1; + sq1 += v1*v1; + } + } + + t = (sq0 - s0*s0/total_size)*(sq1 - s1*s1/total_size); + result0[CV_COMP_CORREL] = fabs(t) > DBL_EPSILON ? + (result0[CV_COMP_CORREL] - s0*s1/total_size)/sqrt(t) : 1; + + s1 *= s0; + s0 = result0[CV_COMP_BHATTACHARYYA]; + s0 = 1. - s0*(s1 > FLT_EPSILON ? 1./sqrt(s1) : 1.); + result0[CV_COMP_BHATTACHARYYA] = sqrt(MAX(s0,0.)); + + for( i = 0; i < MAX_METHOD; i++ ) + { + double v = result[i], v0 = result0[i]; + const char* method_name = + i == CV_COMP_CHISQR ? "Chi-Square" : + i == CV_COMP_CORREL ? "Correlation" : + i == CV_COMP_INTERSECT ? "Intersection" : + i == CV_COMP_BHATTACHARYYA ? "Bhattacharyya" : "Unknown"; + + if( cvIsNaN(v) || cvIsInf(v) ) + { + ts->printf( cvtest::TS::LOG, "The comparison result using the method #%d (%s) is invalid (=%g)\n", + i, method_name, v ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + break; + } + else if( fabs(v0 - v) > FLT_EPSILON*10*MAX(fabs(v0),0.1) ) + { + ts->printf( cvtest::TS::LOG, "The comparison result using the method #%d (%s)\n\tis inaccurate (=%g, should be =%g)\n", + i, method_name, v, v0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + break; + } + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +////////////// cvCalcHist ////////////// + +class CV_CalcHistTest : public CV_BaseHistTest +{ +public: + CV_CalcHistTest(); + ~CV_CalcHistTest(); + void clear(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + IplImage* images[CV_MAX_DIM+1]; + int channels[CV_MAX_DIM+1]; +}; + + + +CV_CalcHistTest::CV_CalcHistTest() +{ + int i; + + hist_count = 2; + gen_random_hist = 0; + init_ranges = 1; + + for( i = 0; i <= CV_MAX_DIM; i++ ) + { + images[i] = 0; + channels[i] = 0; + } +} + + +CV_CalcHistTest::~CV_CalcHistTest() +{ + clear(); +} + + +void CV_CalcHistTest::clear() +{ + int i; + + for( i = 0; i <= CV_MAX_DIM; i++ ) + cvReleaseImage( &images[i] ); + + CV_BaseHistTest::clear(); +} + + +int CV_CalcHistTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + RNG& rng = ts->get_rng(); + int i; + + for( i = 0; i <= CV_MAX_DIM; i++ ) + { + if( i < cdims ) + { + int nch = 1; //cvtest::randInt(rng) % 3 + 1; + images[i] = cvCreateImage( img_size, + img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch ); + channels[i] = cvtest::randInt(rng) % nch; + Mat images_i = cvarrToMat(images[i]); + + cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) ); + } + else if( i == CV_MAX_DIM && cvtest::randInt(rng) % 2 ) + { + // create mask + images[i] = cvCreateImage( img_size, IPL_DEPTH_8U, 1 ); + Mat images_i = cvarrToMat(images[i]); + + // make ~25% pixels in the mask non-zero + cvtest::randUni( rng, images_i, Scalar::all(-2), Scalar::all(2) ); + } + } + } + + return code; +} + + +void CV_CalcHistTest::run_func(void) +{ + cvCalcHist( images, hist[0], 0, images[CV_MAX_DIM] ); +} + + +static void +cvTsCalcHist( IplImage** _images, CvHistogram* hist, IplImage* _mask, int* channels ) +{ + int x, y, k, cdims; + union + { + float* fl; + uchar* ptr; + } + plane[CV_MAX_DIM]; + int nch[CV_MAX_DIM]; + int dims[CV_MAX_DIM]; + int uniform = CV_IS_UNIFORM_HIST(hist); + CvSize img_size = cvGetSize(_images[0]); + CvMat images[CV_MAX_DIM], mask = cvMat(1,1,CV_8U); + int img_depth = _images[0]->depth; + + cdims = cvGetDims( hist->bins, dims ); + + cvZero( hist->bins ); + + for( k = 0; k < cdims; k++ ) + { + cvGetMat( _images[k], &images[k] ); + nch[k] = _images[k]->nChannels; + } + + if( _mask ) + cvGetMat( _mask, &mask ); + + for( y = 0; y < img_size.height; y++ ) + { + const uchar* mptr = _mask ? &CV_MAT_ELEM(mask, uchar, y, 0 ) : 0; + + if( img_depth == IPL_DEPTH_8U ) + for( k = 0; k < cdims; k++ ) + plane[k].ptr = &CV_MAT_ELEM(images[k], uchar, y, 0 ) + channels[k]; + else + for( k = 0; k < cdims; k++ ) + plane[k].fl = &CV_MAT_ELEM(images[k], float, y, 0 ) + channels[k]; + + for( x = 0; x < img_size.width; x++ ) + { + float val[CV_MAX_DIM]; + int idx[CV_MAX_DIM]; + + if( mptr && !mptr[x] ) + continue; + if( img_depth == IPL_DEPTH_8U ) + for( k = 0; k < cdims; k++ ) + val[k] = plane[k].ptr[x*nch[k]]; + else + for( k = 0; k < cdims; k++ ) + val[k] = plane[k].fl[x*nch[k]]; + + idx[cdims-1] = -1; + + if( uniform ) + { + for( k = 0; k < cdims; k++ ) + { + double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1]; + idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo)); + if( idx[k] < 0 || idx[k] >= dims[k] ) + break; + } + } + else + { + for( k = 0; k < cdims; k++ ) + { + float v = val[k]; + float* t = hist->thresh2[k]; + int j, n = dims[k]; + + for( j = 0; j <= n; j++ ) + if( v < t[j] ) + break; + if( j <= 0 || j > n ) + break; + idx[k] = j-1; + } + } + + if( k < cdims ) + continue; + + (*(float*)cvPtrND( hist->bins, idx ))++; + } + } +} + + +int CV_CalcHistTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + double diff; + cvTsCalcHist( images, hist[1], images[CV_MAX_DIM], channels ); + diff = cvCompareHist( hist[0], hist[1], CV_COMP_CHISQR ); + if( diff > DBL_EPSILON ) + { + ts->printf( cvtest::TS::LOG, "The histogram does not match to the reference one\n" ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + + +CV_CalcHistTest hist_calc_test; + + + +////////////// cvCalcBackProject ////////////// + +class CV_CalcBackProjectTest : public CV_BaseHistTest +{ +public: + CV_CalcBackProjectTest(); + ~CV_CalcBackProjectTest(); + void clear(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + IplImage* images[CV_MAX_DIM+3]; + int channels[CV_MAX_DIM+3]; +}; + + + +CV_CalcBackProjectTest::CV_CalcBackProjectTest() +{ + int i; + + hist_count = 1; + gen_random_hist = 0; + init_ranges = 1; + + for( i = 0; i < CV_MAX_DIM+3; i++ ) + { + images[i] = 0; + channels[i] = 0; + } +} + + +CV_CalcBackProjectTest::~CV_CalcBackProjectTest() +{ + clear(); +} + + +void CV_CalcBackProjectTest::clear() +{ + int i; + + for( i = 0; i < CV_MAX_DIM+3; i++ ) + cvReleaseImage( &images[i] ); + + CV_BaseHistTest::clear(); +} + + +int CV_CalcBackProjectTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + RNG& rng = ts->get_rng(); + int i, j, n, img_len = img_size.width*img_size.height; + + for( i = 0; i < CV_MAX_DIM + 3; i++ ) + { + if( i < cdims ) + { + int nch = 1; //cvtest::randInt(rng) % 3 + 1; + images[i] = cvCreateImage( img_size, + img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch ); + channels[i] = cvtest::randInt(rng) % nch; + + Mat images_i = cvarrToMat(images[i]); + cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) ); + } + else if( i == CV_MAX_DIM && cvtest::randInt(rng) % 2 ) + { + // create mask + images[i] = cvCreateImage( img_size, IPL_DEPTH_8U, 1 ); + Mat images_i = cvarrToMat(images[i]); + // make ~25% pixels in the mask non-zero + cvtest::randUni( rng, images_i, Scalar::all(-2), Scalar::all(2) ); + } + else if( i > CV_MAX_DIM ) + { + images[i] = cvCreateImage( img_size, images[0]->depth, 1 ); + } + } + + cvTsCalcHist( images, hist[0], images[CV_MAX_DIM], channels ); + + // now modify the images a bit to add some zeros go to the backprojection + n = cvtest::randInt(rng) % (img_len/20+1); + for( i = 0; i < cdims; i++ ) + { + char* data = images[i]->imageData; + for( j = 0; j < n; j++ ) + { + int idx = cvtest::randInt(rng) % img_len; + double val = cvtest::randReal(rng)*(high - low) + low; + + if( img_type == CV_8U ) + ((uchar*)data)[idx] = (uchar)cvRound(val); + else + ((float*)data)[idx] = (float)val; + } + } + } + + return code; +} + + +void CV_CalcBackProjectTest::run_func(void) +{ + cvCalcBackProject( images, images[CV_MAX_DIM+1], hist[0] ); +} + + +static void +cvTsCalcBackProject( IplImage** images, IplImage* dst, CvHistogram* hist, int* channels ) +{ + int x, y, k, cdims; + union + { + float* fl; + uchar* ptr; + } + plane[CV_MAX_DIM]; + int nch[CV_MAX_DIM]; + int dims[CV_MAX_DIM]; + int uniform = CV_IS_UNIFORM_HIST(hist); + CvSize img_size = cvGetSize(images[0]); + int img_depth = images[0]->depth; + + cdims = cvGetDims( hist->bins, dims ); + + for( k = 0; k < cdims; k++ ) + nch[k] = images[k]->nChannels; + + for( y = 0; y < img_size.height; y++ ) + { + if( img_depth == IPL_DEPTH_8U ) + for( k = 0; k < cdims; k++ ) + plane[k].ptr = &CV_IMAGE_ELEM(images[k], uchar, y, 0 ) + channels[k]; + else + for( k = 0; k < cdims; k++ ) + plane[k].fl = &CV_IMAGE_ELEM(images[k], float, y, 0 ) + channels[k]; + + for( x = 0; x < img_size.width; x++ ) + { + float val[CV_MAX_DIM]; + float bin_val = 0; + int idx[CV_MAX_DIM]; + + if( img_depth == IPL_DEPTH_8U ) + for( k = 0; k < cdims; k++ ) + val[k] = plane[k].ptr[x*nch[k]]; + else + for( k = 0; k < cdims; k++ ) + val[k] = plane[k].fl[x*nch[k]]; + idx[cdims-1] = -1; + + if( uniform ) + { + for( k = 0; k < cdims; k++ ) + { + double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1]; + idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo)); + if( idx[k] < 0 || idx[k] >= dims[k] ) + break; + } + } + else + { + for( k = 0; k < cdims; k++ ) + { + float v = val[k]; + float* t = hist->thresh2[k]; + int j, n = dims[k]; + + for( j = 0; j <= n; j++ ) + if( v < t[j] ) + break; + if( j <= 0 || j > n ) + break; + idx[k] = j-1; + } + } + + if( k == cdims ) + bin_val = (float)cvGetRealND( hist->bins, idx ); + + if( img_depth == IPL_DEPTH_8U ) + { + int t = cvRound(bin_val); + CV_IMAGE_ELEM( dst, uchar, y, x ) = saturate_cast(t); + } + else + CV_IMAGE_ELEM( dst, float, y, x ) = bin_val; + } + } +} + + +int CV_CalcBackProjectTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + + cvTsCalcBackProject( images, images[CV_MAX_DIM+2], hist[0], channels ); + Mat a = cvarrToMat(images[CV_MAX_DIM+1]), b = cvarrToMat(images[CV_MAX_DIM+2]); + double threshold = a.depth() == CV_8U ? 2 : FLT_EPSILON; + code = cvtest::cmpEps2( ts, a, b, threshold, true, "Back project image" ); + + if( code < 0 ) + ts->set_failed_test_info( code ); + + return code; +} + + +////////////// cvCalcBackProjectPatch ////////////// + +class CV_CalcBackProjectPatchTest : public CV_BaseHistTest +{ +public: + CV_CalcBackProjectPatchTest(); + ~CV_CalcBackProjectPatchTest(); + void clear(); + +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + IplImage* images[CV_MAX_DIM+2]; + int channels[CV_MAX_DIM+2]; + + CvSize patch_size; + double factor; + int method; +}; + + + +CV_CalcBackProjectPatchTest::CV_CalcBackProjectPatchTest() +{ + int i; + + hist_count = 1; + gen_random_hist = 0; + init_ranges = 1; + img_max_log_size = 6; + + for( i = 0; i < CV_MAX_DIM+2; i++ ) + { + images[i] = 0; + channels[i] = 0; + } +} + + +CV_CalcBackProjectPatchTest::~CV_CalcBackProjectPatchTest() +{ + clear(); +} + + +void CV_CalcBackProjectPatchTest::clear() +{ + int i; + + for( i = 0; i < CV_MAX_DIM+2; i++ ) + cvReleaseImage( &images[i] ); + + CV_BaseHistTest::clear(); +} + + +int CV_CalcBackProjectPatchTest::prepare_test_case( int test_case_idx ) +{ + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + if( code > 0 ) + { + RNG& rng = ts->get_rng(); + int i, j, n, img_len = img_size.width*img_size.height; + + patch_size.width = cvtest::randInt(rng) % img_size.width + 1; + patch_size.height = cvtest::randInt(rng) % img_size.height + 1; + patch_size.width = MIN( patch_size.width, 30 ); + patch_size.height = MIN( patch_size.height, 30 ); + + factor = 1.; + method = cvtest::randInt(rng) % CV_CompareHistTest::MAX_METHOD; + + for( i = 0; i < CV_MAX_DIM + 2; i++ ) + { + if( i < cdims ) + { + int nch = 1; //cvtest::randInt(rng) % 3 + 1; + images[i] = cvCreateImage( img_size, + img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch ); + channels[i] = cvtest::randInt(rng) % nch; + + Mat images_i = cvarrToMat(images[i]); + cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) ); + } + else if( i >= CV_MAX_DIM ) + { + images[i] = cvCreateImage( + cvSize(img_size.width - patch_size.width + 1, + img_size.height - patch_size.height + 1), + IPL_DEPTH_32F, 1 ); + } + } + + cvTsCalcHist( images, hist[0], 0, channels ); + cvNormalizeHist( hist[0], factor ); + + // now modify the images a bit + n = cvtest::randInt(rng) % (img_len/10+1); + for( i = 0; i < cdims; i++ ) + { + char* data = images[i]->imageData; + for( j = 0; j < n; j++ ) + { + int idx = cvtest::randInt(rng) % img_len; + double val = cvtest::randReal(rng)*(high - low) + low; + + if( img_type == CV_8U ) + ((uchar*)data)[idx] = (uchar)cvRound(val); + else + ((float*)data)[idx] = (float)val; + } + } + } + + return code; +} + + +void CV_CalcBackProjectPatchTest::run_func(void) +{ + cvCalcBackProjectPatch( images, images[CV_MAX_DIM], patch_size, hist[0], method, factor ); +} + + +static void +cvTsCalcBackProjectPatch( IplImage** images, IplImage* dst, CvSize patch_size, + CvHistogram* hist, int method, + double factor, int* channels ) +{ + CvHistogram* model = 0; + + IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM]; + IplROI roi; + int i, dims; + int x, y; + CvSize size = cvGetSize(dst); + + dims = cvGetDims( hist->bins ); + cvCopyHist( hist, &model ); + cvNormalizeHist( hist, factor ); + cvZero( dst ); + + for( i = 0; i < dims; i++ ) + { + CvMat stub, *mat; + mat = cvGetMat( images[i], &stub, 0, 0 ); + img[i] = cvGetImage( mat, &imgstub[i] ); + img[i]->roi = &roi; + } + + roi.coi = 0; + + for( y = 0; y < size.height; y++ ) + { + for( x = 0; x < size.width; x++ ) + { + double result; + + roi.xOffset = x; + roi.yOffset = y; + roi.width = patch_size.width; + roi.height = patch_size.height; + + cvTsCalcHist( img, model, 0, channels ); + cvNormalizeHist( model, factor ); + result = cvCompareHist( model, hist, method ); + CV_IMAGE_ELEM( dst, float, y, x ) = (float)result; + } + } + + cvReleaseHist( &model ); +} + + +int CV_CalcBackProjectPatchTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + double err_level = 5e-3; + + cvTsCalcBackProjectPatch( images, images[CV_MAX_DIM+1], + patch_size, hist[0], method, factor, channels ); + + Mat a = cvarrToMat(images[CV_MAX_DIM]), b = cvarrToMat(images[CV_MAX_DIM+1]); + code = cvtest::cmpEps2( ts, a, b, err_level, true, "BackProjectPatch result" ); + + if( code < 0 ) + ts->set_failed_test_info( code ); + + return code; +} + + +////////////// cvCalcBayesianProb ////////////// + +class CV_BayesianProbTest : public CV_BaseHistTest +{ +public: + enum { MAX_METHOD = 4 }; + + CV_BayesianProbTest(); +protected: + int prepare_test_case( int test_case_idx ); + void run_func(void); + int validate_test_results( int test_case_idx ); + void init_hist( int test_case_idx, int i ); + void get_hist_params( int test_case_idx ); +}; + + + +CV_BayesianProbTest::CV_BayesianProbTest() +{ + hist_count = CV_MAX_DIM; + gen_random_hist = 1; +} + + +void CV_BayesianProbTest::get_hist_params( int test_case_idx ) +{ + CV_BaseHistTest::get_hist_params( test_case_idx ); + hist_type = CV_HIST_ARRAY; +} + + +void CV_BayesianProbTest::init_hist( int test_case_idx, int hist_i ) +{ + if( hist_i < hist_count/2 ) + CV_BaseHistTest::init_hist( test_case_idx, hist_i ); +} + + +int CV_BayesianProbTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + + hist_count = (cvtest::randInt(rng) % (MAX_HIST/2-1) + 2)*2; + hist_count = MIN( hist_count, MAX_HIST ); + int code = CV_BaseHistTest::prepare_test_case( test_case_idx ); + + return code; +} + + +void CV_BayesianProbTest::run_func(void) +{ + cvCalcBayesianProb( &hist[0], hist_count/2, &hist[hist_count/2] ); +} + + +int CV_BayesianProbTest::validate_test_results( int /*test_case_idx*/ ) +{ + int code = cvtest::TS::OK; + int i, j, n = hist_count/2; + double s[CV_MAX_DIM]; + const double err_level = 1e-5; + + for( i = 0; i < total_size; i++ ) + { + double sum = 0; + for( j = 0; j < n; j++ ) + { + double v = hist[j]->mat.data.fl[i]; + sum += v; + s[j] = v; + } + sum = sum > DBL_EPSILON ? 1./sum : 0; + + for( j = 0; j < n; j++ ) + { + double v0 = s[j]*sum; + double v = hist[j+n]->mat.data.fl[i]; + + if( cvIsNaN(v) || cvIsInf(v) ) + { + ts->printf( cvtest::TS::LOG, + "The element #%d in the destination histogram #%d is invalid (=%g)\n", + i, j, v ); + code = cvtest::TS::FAIL_INVALID_OUTPUT; + break; + } + else if( fabs(v0 - v) > err_level*fabs(v0) ) + { + ts->printf( cvtest::TS::LOG, + "The element #%d in the destination histogram #%d is inaccurate (=%g, should be =%g)\n", + i, j, v, v0 ); + code = cvtest::TS::FAIL_BAD_ACCURACY; + break; + } + } + if( j < n ) + break; + } + + if( code < 0 ) + ts->set_failed_test_info( code ); + return code; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST(Imgproc_Hist_Calc, accuracy) { CV_CalcHistTest test; test.safe_run(); } +TEST(Imgproc_Hist_Query, accuracy) { CV_QueryHistTest test; test.safe_run(); } + +TEST(Imgproc_Hist_Compare, accuracy) { CV_CompareHistTest test; test.safe_run(); } +TEST(Imgproc_Hist_Threshold, accuracy) { CV_ThreshHistTest test; test.safe_run(); } +TEST(Imgproc_Hist_Normalize, accuracy) { CV_NormHistTest test; test.safe_run(); } +TEST(Imgproc_Hist_MinMaxVal, accuracy) { CV_MinMaxHistTest test; test.safe_run(); } + +TEST(Imgproc_Hist_CalcBackProject, accuracy) { CV_CalcBackProjectTest test; test.safe_run(); } +TEST(Imgproc_Hist_CalcBackProjectPatch, accuracy) { CV_CalcBackProjectPatchTest test; test.safe_run(); } +TEST(Imgproc_Hist_BayesianProb, accuracy) { CV_BayesianProbTest test; test.safe_run(); } + +/* End Of File */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_houghLines.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_houghLines.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_houghLines.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_houghLines.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,149 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_HoughLinesTest : public cvtest::BaseTest +{ +public: + enum {STANDART = 0, PROBABILISTIC}; + CV_HoughLinesTest() {} + ~CV_HoughLinesTest() {} +protected: + void run_test(int type); +}; + +class CV_StandartHoughLinesTest : public CV_HoughLinesTest +{ +public: + CV_StandartHoughLinesTest() {} + ~CV_StandartHoughLinesTest() {} + virtual void run(int); +}; + +class CV_ProbabilisticHoughLinesTest : public CV_HoughLinesTest +{ +public: + CV_ProbabilisticHoughLinesTest() {} + ~CV_ProbabilisticHoughLinesTest() {} + virtual void run(int); +}; + +void CV_StandartHoughLinesTest::run(int) +{ + run_test(STANDART); +} + +void CV_ProbabilisticHoughLinesTest::run(int) +{ + run_test(PROBABILISTIC); +} + +void CV_HoughLinesTest::run_test(int type) +{ + Mat src = imread(string(ts->get_data_path()) + "shared/pic1.png"); + if (src.empty()) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + string xml; + if (type == STANDART) + xml = string(ts->get_data_path()) + "imgproc/HoughLines.xml"; + else if (type == PROBABILISTIC) + xml = string(ts->get_data_path()) + "imgproc/HoughLinesP.xml"; + else + { + ts->printf(cvtest::TS::LOG, "Error: unknown HoughLines algorithm type.\n"); + ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC); + return; + } + + Mat dst; + Canny(src, dst, 50, 200, 3); + + Mat lines; + if (type == STANDART) + HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0); + else if (type == PROBABILISTIC) + HoughLinesP(dst, lines, 1, CV_PI/180, 100, 0, 0); + + FileStorage fs(xml, FileStorage::READ); + if (!fs.isOpened()) + { + fs.open(xml, FileStorage::WRITE); + if (!fs.isOpened()) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + fs << "exp_lines" << lines; + fs.release(); + fs.open(xml, FileStorage::READ); + if (!fs.isOpened()) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + } + + Mat exp_lines; + read( fs["exp_lines"], exp_lines, Mat() ); + fs.release(); + + if ( exp_lines.size != lines.size || norm(exp_lines, lines, NORM_INF) > 1e-4 ) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return; + } + + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Imgproc_HoughLines, regression) { CV_StandartHoughLinesTest test; test.safe_run(); } + +TEST(Imgproc_HoughLinesP, regression) { CV_ProbabilisticHoughLinesTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_imgwarp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_imgwarp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_imgwarp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_imgwarp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1548 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_ImgWarpBaseTest : public cvtest::ArrayTest +{ +public: + CV_ImgWarpBaseTest( bool warp_matrix ); + +protected: + int read_params( CvFileStorage* fs ); + int prepare_test_case( int test_case_idx ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + void fill_array( int test_case_idx, int i, int j, Mat& arr ); + + int interpolation; + int max_interpolation; + double spatial_scale_zoom, spatial_scale_decimate; +}; + + +CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix ) +{ + test_array[INPUT].push_back(NULL); + if( warp_matrix ) + test_array[INPUT].push_back(NULL); + test_array[INPUT_OUTPUT].push_back(NULL); + test_array[REF_INPUT_OUTPUT].push_back(NULL); + max_interpolation = 5; + interpolation = 0; + element_wise_relative_error = false; + spatial_scale_zoom = 0.01; + spatial_scale_decimate = 0.005; +} + + +int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::ArrayTest::read_params( fs ); + return code; +} + + +void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + if( CV_MAT_DEPTH(type) == CV_32F ) + { + low = Scalar::all(-10.); + high = Scalar::all(10); + } +} + + +void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % 3; + int cn = cvtest::randInt(rng) % 3 + 1; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F; + cn += cn == 2; + + types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn); + if( test_array[INPUT].size() > 1 ) + types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1; + + interpolation = cvtest::randInt(rng) % max_interpolation; +} + + +void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + if( i != INPUT || j != 0 ) + cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); +} + +int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + Mat& img = test_mat[INPUT][0]; + int i, j, cols = img.cols; + int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); + double scale = depth == CV_16U ? 1000. : 255.*0.5; + double space_scale = spatial_scale_decimate; + vector buffer(img.cols*cn); + + if( code <= 0 ) + return code; + + if( test_mat[INPUT_OUTPUT][0].cols >= img.cols && + test_mat[INPUT_OUTPUT][0].rows >= img.rows ) + space_scale = spatial_scale_zoom; + + for( i = 0; i < img.rows; i++ ) + { + uchar* ptr = img.ptr(i); + switch( cn ) + { + case 1: + for( j = 0; j < cols; j++ ) + buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale); + break; + case 2: + for( j = 0; j < cols; j++ ) + { + buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale); + buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale); + } + break; + case 3: + for( j = 0; j < cols; j++ ) + { + buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale); + buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale); + buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale); + } + break; + case 4: + for( j = 0; j < cols; j++ ) + { + buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale); + buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale); + buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale); + buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale); + } + break; + default: + assert(0); + } + + /*switch( depth ) + { + case CV_8U: + for( j = 0; j < cols*cn; j++ ) + ptr[j] = (uchar)cvRound(buffer[j]); + break; + case CV_16U: + for( j = 0; j < cols*cn; j++ ) + ((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]); + break; + case CV_32F: + for( j = 0; j < cols*cn; j++ ) + ((float*)ptr)[j] = (float)buffer[j]; + break; + default: + assert(0); + }*/ + cv::Mat src(1, cols*cn, CV_32F, &buffer[0]); + cv::Mat dst(1, cols*cn, depth, ptr); + src.convertTo(dst, dst.type()); + } + + return code; +} + + +///////////////////////// + +class CV_ResizeTest : public CV_ImgWarpBaseTest +{ +public: + CV_ResizeTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_ResizeTest::CV_ResizeTest() : CV_ImgWarpBaseTest( false ) +{ +} + + +void CV_ResizeTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + CvSize sz; + + sz.width = (cvtest::randInt(rng) % sizes[INPUT][0].width) + 1; + sz.height = (cvtest::randInt(rng) % sizes[INPUT][0].height) + 1; + + if( cvtest::randInt(rng) & 1 ) + { + int xfactor = cvtest::randInt(rng) % 10 + 1; + int yfactor = cvtest::randInt(rng) % 10 + 1; + + if( cvtest::randInt(rng) & 1 ) + yfactor = xfactor; + + sz.width = sizes[INPUT][0].width / xfactor; + sz.width = MAX(sz.width,1); + sz.height = sizes[INPUT][0].height / yfactor; + sz.height = MAX(sz.height,1); + sizes[INPUT][0].width = sz.width * xfactor; + sizes[INPUT][0].height = sz.height * yfactor; + } + + if( cvtest::randInt(rng) & 1 ) + sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sz; + else + { + sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sizes[INPUT][0]; + sizes[INPUT][0] = sz; + } + if( interpolation == 4 && + (MIN(sizes[INPUT][0].width,sizes[INPUT_OUTPUT][0].width) < 4 || + MIN(sizes[INPUT][0].height,sizes[INPUT_OUTPUT][0].height) < 4)) + interpolation = 2; +} + + +void CV_ResizeTest::run_func() +{ + cvResize( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], interpolation ); +} + + +double CV_ResizeTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 1e-1; +} + + +void CV_ResizeTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + CvMat _src = test_mat[INPUT][0], _dst = test_mat[REF_INPUT_OUTPUT][0]; + CvMat *src = &_src, *dst = &_dst; + int i, j, k; + CvMat* x_idx = cvCreateMat( 1, dst->cols, CV_32SC1 ); + CvMat* y_idx = cvCreateMat( 1, dst->rows, CV_32SC1 ); + int* x_tab = x_idx->data.i; + int elem_size = CV_ELEM_SIZE(src->type); + int drows = dst->rows, dcols = dst->cols; + + if( interpolation == CV_INTER_NN ) + { + for( j = 0; j < dcols; j++ ) + { + int t = (j*src->cols*2 + MIN(src->cols,dcols) - 1)/(dcols*2); + t -= t >= src->cols; + x_idx->data.i[j] = t*elem_size; + } + + for( j = 0; j < drows; j++ ) + { + int t = (j*src->rows*2 + MIN(src->rows,drows) - 1)/(drows*2); + t -= t >= src->rows; + y_idx->data.i[j] = t; + } + } + else + { + double scale_x = (double)src->cols/dcols; + double scale_y = (double)src->rows/drows; + + for( j = 0; j < dcols; j++ ) + { + double f = ((j+0.5)*scale_x - 0.5); + i = cvRound(f); + x_idx->data.i[j] = (i < 0 ? 0 : i >= src->cols ? src->cols - 1 : i)*elem_size; + } + + for( j = 0; j < drows; j++ ) + { + double f = ((j+0.5)*scale_y - 0.5); + i = cvRound(f); + y_idx->data.i[j] = i < 0 ? 0 : i >= src->rows ? src->rows - 1 : i; + } + } + + for( i = 0; i < drows; i++ ) + { + uchar* dptr = dst->data.ptr + dst->step*i; + const uchar* sptr0 = src->data.ptr + src->step*y_idx->data.i[i]; + + for( j = 0; j < dcols; j++, dptr += elem_size ) + { + const uchar* sptr = sptr0 + x_tab[j]; + for( k = 0; k < elem_size; k++ ) + dptr[k] = sptr[k]; + } + } + + cvReleaseMat( &x_idx ); + cvReleaseMat( &y_idx ); +} + + +///////////////////////// + +static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy, + Mat* mask=0, int interpolation=CV_INTER_LINEAR ) +{ + int x, y, k; + int drows = dst.rows, dcols = dst.cols; + int srows = src.rows, scols = src.cols; + uchar* sptr0 = src.data; + int depth = src.depth(), cn = src.channels(); + int elem_size = (int)src.elemSize(); + int step = (int)(src.step / CV_ELEM_SIZE(depth)); + int delta; + + if( interpolation != CV_INTER_CUBIC ) + { + delta = 0; + scols -= 1; srows -= 1; + } + else + { + delta = 1; + scols = MAX(scols - 3, 0); + srows = MAX(srows - 3, 0); + } + + int scols1 = MAX(scols - 2, 0); + int srows1 = MAX(srows - 2, 0); + + if( mask ) + *mask = Scalar::all(0); + + for( y = 0; y < drows; y++ ) + { + uchar* dptr = dst.ptr(y); + const float* mx = mapx.ptr(y); + const float* my = mapy.ptr(y); + uchar* m = mask ? mask->ptr(y) : 0; + + for( x = 0; x < dcols; x++, dptr += elem_size ) + { + float xs = mx[x]; + float ys = my[x]; + int ixs = cvFloor(xs); + int iys = cvFloor(ys); + + if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 || + (unsigned)(iys - delta - 1) >= (unsigned)srows1 ) + { + if( m ) + m[x] = 1; + if( (unsigned)(ixs - delta) >= (unsigned)scols || + (unsigned)(iys - delta) >= (unsigned)srows ) + continue; + } + + xs -= ixs; + ys -= iys; + + switch( depth ) + { + case CV_8U: + { + const uchar* sptr = sptr0 + iys*step + ixs*cn; + for( k = 0; k < cn; k++ ) + { + float v00 = sptr[k]; + float v01 = sptr[cn + k]; + float v10 = sptr[step + k]; + float v11 = sptr[step + cn + k]; + + v00 = v00 + xs*(v01 - v00); + v10 = v10 + xs*(v11 - v10); + v00 = v00 + ys*(v10 - v00); + dptr[k] = (uchar)cvRound(v00); + } + } + break; + case CV_16U: + { + const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn; + for( k = 0; k < cn; k++ ) + { + float v00 = sptr[k]; + float v01 = sptr[cn + k]; + float v10 = sptr[step + k]; + float v11 = sptr[step + cn + k]; + + v00 = v00 + xs*(v01 - v00); + v10 = v10 + xs*(v11 - v10); + v00 = v00 + ys*(v10 - v00); + ((ushort*)dptr)[k] = (ushort)cvRound(v00); + } + } + break; + case CV_32F: + { + const float* sptr = (const float*)sptr0 + iys*step + ixs*cn; + for( k = 0; k < cn; k++ ) + { + float v00 = sptr[k]; + float v01 = sptr[cn + k]; + float v10 = sptr[step + k]; + float v11 = sptr[step + cn + k]; + + v00 = v00 + xs*(v01 - v00); + v10 = v10 + xs*(v11 - v10); + v00 = v00 + ys*(v10 - v00); + ((float*)dptr)[k] = (float)v00; + } + } + break; + default: + assert(0); + } + } + } +} + +///////////////////////// + +class CV_WarpAffineTest : public CV_ImgWarpBaseTest +{ +public: + CV_WarpAffineTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_WarpAffineTest::CV_WarpAffineTest() : CV_ImgWarpBaseTest( true ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + spatial_scale_decimate = spatial_scale_zoom; +} + + +void CV_WarpAffineTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + CvSize sz = sizes[INPUT][0]; + // run for the second time to get output of a different size + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + sizes[INPUT][0] = sz; + sizes[INPUT][1] = cvSize( 3, 2 ); +} + + +void CV_WarpAffineTest::run_func() +{ + CvMat mtx = test_mat[INPUT][1]; + cvWarpAffine( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx, interpolation ); +} + + +double CV_WarpAffineTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2; +} + + +int CV_WarpAffineTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); + const Mat& src = test_mat[INPUT][0]; + const Mat& dst = test_mat[INPUT_OUTPUT][0]; + Mat& mat = test_mat[INPUT][1]; + CvPoint2D32f center; + double scale, angle; + + if( code <= 0 ) + return code; + + double buffer[6]; + Mat tmp( 2, 3, mat.type(), buffer ); + + center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols); + center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows); + angle = cvtest::randReal(rng)*360; + scale = ((double)dst.rows/src.rows + (double)dst.cols/src.cols)*0.5; + getRotationMatrix2D(center, angle, scale).convertTo(mat, mat.depth()); + rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(1.), Scalar::all(0.01) ); + cv::max(tmp, 0.9, tmp); + cv::min(tmp, 1.1, tmp); + cv::multiply(tmp, mat, mat, 1.); + + return code; +} + + +void CV_WarpAffineTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + const Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_INPUT_OUTPUT][0]; + Mat& dst0 = test_mat[INPUT_OUTPUT][0]; + Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F); + double m[6]; + Mat srcAb, dstAb( 2, 3, CV_64FC1, m ); + + //cvInvert( &tM, &M, CV_LU ); + // [R|t] -> [R^-1 | -(R^-1)*t] + test_mat[INPUT][1].convertTo( srcAb, CV_64F ); + Mat A = srcAb.colRange(0, 2); + Mat b = srcAb.col(2); + Mat invA = dstAb.colRange(0, 2); + Mat invAb = dstAb.col(2); + cv::invert(A, invA, CV_SVD); + cv::gemm(invA, b, -1, Mat(), 0, invAb); + + for( int y = 0; y < dst.rows; y++ ) + for( int x = 0; x < dst.cols; x++ ) + { + mapx.at(y, x) = (float)(x*m[0] + y*m[1] + m[2]); + mapy.at(y, x) = (float)(x*m[3] + y*m[4] + m[5]); + } + + Mat mask( dst.size(), CV_8U ); + test_remap( src, dst, mapx, mapy, &mask ); + dst.setTo(Scalar::all(0), mask); + dst0.setTo(Scalar::all(0), mask); +} + + +///////////////////////// + +class CV_WarpPerspectiveTest : public CV_ImgWarpBaseTest +{ +public: + CV_WarpPerspectiveTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_WarpPerspectiveTest::CV_WarpPerspectiveTest() : CV_ImgWarpBaseTest( true ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + spatial_scale_decimate = spatial_scale_zoom; +} + + +void CV_WarpPerspectiveTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + CvSize sz = sizes[INPUT][0]; + // run for the second time to get output of a different size + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + sizes[INPUT][0] = sz; + sizes[INPUT][1] = cvSize( 3, 3 ); +} + + +void CV_WarpPerspectiveTest::run_func() +{ + CvMat mtx = test_mat[INPUT][1]; + cvWarpPerspective( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx, interpolation ); +} + + +double CV_WarpPerspectiveTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2; +} + + +int CV_WarpPerspectiveTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); + const CvMat& src = test_mat[INPUT][0]; + const CvMat& dst = test_mat[INPUT_OUTPUT][0]; + Mat& mat = test_mat[INPUT][1]; + Point2f s[4], d[4]; + int i; + + if( code <= 0 ) + return code; + + s[0] = Point2f(0,0); + d[0] = Point2f(0,0); + s[1] = Point2f(src.cols-1.f,0); + d[1] = Point2f(dst.cols-1.f,0); + s[2] = Point2f(src.cols-1.f,src.rows-1.f); + d[2] = Point2f(dst.cols-1.f,dst.rows-1.f); + s[3] = Point2f(0,src.rows-1.f); + d[3] = Point2f(0,dst.rows-1.f); + + float bufer[16]; + Mat tmp( 1, 16, CV_32FC1, bufer ); + + rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(0.), Scalar::all(0.1) ); + + for( i = 0; i < 4; i++ ) + { + s[i].x += bufer[i*4]*src.cols/2; + s[i].y += bufer[i*4+1]*src.rows/2; + d[i].x += bufer[i*4+2]*dst.cols/2; + d[i].y += bufer[i*4+3]*dst.rows/2; + } + + cv::getPerspectiveTransform( s, d ).convertTo( mat, mat.depth() ); + return code; +} + + +void CV_WarpPerspectiveTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_INPUT_OUTPUT][0]; + Mat& dst0 = test_mat[INPUT_OUTPUT][0]; + Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F); + double m[9]; + Mat srcM, dstM(3, 3, CV_64F, m); + + //cvInvert( &tM, &M, CV_LU ); + // [R|t] -> [R^-1 | -(R^-1)*t] + test_mat[INPUT][1].convertTo( srcM, CV_64F ); + cv::invert(srcM, dstM, CV_SVD); + + for( int y = 0; y < dst.rows; y++ ) + { + for( int x = 0; x < dst.cols; x++ ) + { + double xs = x*m[0] + y*m[1] + m[2]; + double ys = x*m[3] + y*m[4] + m[5]; + double ds = x*m[6] + y*m[7] + m[8]; + + ds = ds ? 1./ds : 0; + xs *= ds; + ys *= ds; + + mapx.at(y, x) = (float)xs; + mapy.at(y, x) = (float)ys; + } + } + + Mat mask( dst.size(), CV_8U ); + test_remap( src, dst, mapx, mapy, &mask ); + dst.setTo(Scalar::all(0), mask); + dst0.setTo(Scalar::all(0), mask); +} + + +///////////////////////// + +class CV_RemapTest : public CV_ImgWarpBaseTest +{ +public: + CV_RemapTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); + void fill_array( int test_case_idx, int i, int j, Mat& arr ); +}; + + +CV_RemapTest::CV_RemapTest() : CV_ImgWarpBaseTest( false ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + + spatial_scale_decimate = spatial_scale_zoom; +} + + +void CV_RemapTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + types[INPUT][1] = types[INPUT][2] = CV_32FC1; + interpolation = CV_INTER_LINEAR; +} + + +void CV_RemapTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + if( i != INPUT ) + CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr ); +} + + +void CV_RemapTest::run_func() +{ + cvRemap( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], + test_array[INPUT][1], test_array[INPUT][2], interpolation ); +} + + +double CV_RemapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2; +} + + +int CV_RemapTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); + const Mat& src = test_mat[INPUT][0]; + double a[9] = {0,0,0,0,0,0,0,0,1}, k[4]; + Mat _a( 3, 3, CV_64F, a ); + Mat _k( 4, 1, CV_64F, k ); + double sz = MAX(src.rows, src.cols); + + if( code <= 0 ) + return code; + + double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; + a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); + a[4] = aspect_ratio*a[0]; + k[0] = cvtest::randReal(rng)*0.06 - 0.03; + k[1] = cvtest::randReal(rng)*0.06 - 0.03; + if( k[0]*k[1] > 0 ) + k[1] = -k[1]; + k[2] = cvtest::randReal(rng)*0.004 - 0.002; + k[3] = cvtest::randReal(rng)*0.004 - 0.002; + + cvtest::initUndistortMap( _a, _k, test_mat[INPUT][1].size(), test_mat[INPUT][1], test_mat[INPUT][2] ); + return code; +} + + +void CV_RemapTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& dst = test_mat[REF_INPUT_OUTPUT][0]; + Mat& dst0 = test_mat[INPUT_OUTPUT][0]; + Mat mask( dst.size(), CV_8U ); + test_remap(test_mat[INPUT][0], dst, test_mat[INPUT][1], + test_mat[INPUT][2], &mask, interpolation ); + dst.setTo(Scalar::all(0), mask); + dst0.setTo(Scalar::all(0), mask); +} + + +////////////////////////////// undistort ///////////////////////////////// + +class CV_UndistortTest : public CV_ImgWarpBaseTest +{ +public: + CV_UndistortTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); + void fill_array( int test_case_idx, int i, int j, Mat& arr ); + +private: + bool useCPlus; + cv::Mat input0; + cv::Mat input1; + cv::Mat input2; + cv::Mat input_new_cam; + cv::Mat input_output; + + bool zero_new_cam; + bool zero_distortion; +}; + + +CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + + spatial_scale_decimate = spatial_scale_zoom; +} + + +void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int type = types[INPUT][0]; + type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) ); + types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type; + types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + sizes[INPUT][1] = cvSize(3,3); + sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4); + types[INPUT][3] = types[INPUT][1]; + sizes[INPUT][3] = sizes[INPUT][1]; + interpolation = CV_INTER_LINEAR; +} + + +void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + if( i != INPUT ) + CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr ); +} + + +void CV_UndistortTest::run_func() +{ + if (!useCPlus) + { + CvMat a = test_mat[INPUT][1], k = test_mat[INPUT][2]; + cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k); + } + else + { + if (zero_distortion) + { + cv::undistort(input0,input_output,input1,cv::Mat()); + } + else + { + cv::undistort(input0,input_output,input1,input2); + } + } +} + + +double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2; +} + + +int CV_UndistortTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); + + const Mat& src = test_mat[INPUT][0]; + double k[4], a[9] = {0,0,0,0,0,0,0,0,1}; + double new_cam[9] = {0,0,0,0,0,0,0,0,1}; + double sz = MAX(src.rows, src.cols); + + Mat& _new_cam0 = test_mat[INPUT][3]; + Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam); + Mat& _a0 = test_mat[INPUT][1]; + Mat _a(3,3,CV_64F,a); + Mat& _k0 = test_mat[INPUT][2]; + Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k); + + if( code <= 0 ) + return code; + + double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; + a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); + a[4] = aspect_ratio*a[0]; + k[0] = cvtest::randReal(rng)*0.06 - 0.03; + k[1] = cvtest::randReal(rng)*0.06 - 0.03; + if( k[0]*k[1] > 0 ) + k[1] = -k[1]; + if( cvtest::randInt(rng)%4 != 0 ) + { + k[2] = cvtest::randReal(rng)*0.004 - 0.002; + k[3] = cvtest::randReal(rng)*0.004 - 0.002; + } + else + k[2] = k[3] = 0; + + new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10% + new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10% + new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15% + new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15% + + _a.convertTo(_a0, _a0.depth()); + + zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true; + _k.convertTo(_k0, _k0.depth()); + + zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true; + _new_cam.convertTo(_new_cam0, _new_cam0.depth()); + + //Testing C++ code + useCPlus = ((cvtest::randInt(rng) % 2)!=0); + if (useCPlus) + { + input0 = test_mat[INPUT][0]; + input1 = test_mat[INPUT][1]; + input2 = test_mat[INPUT][2]; + input_new_cam = test_mat[INPUT][3]; + } + + return code; +} + + +void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + if (useCPlus) + { + Mat& output = test_mat[INPUT_OUTPUT][0]; + input_output.convertTo(output, output.type()); + } + Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_INPUT_OUTPUT][0]; + Mat& dst0 = test_mat[INPUT_OUTPUT][0]; + Mat mapx, mapy; + cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy ); + Mat mask( dst.size(), CV_8U ); + test_remap( src, dst, mapx, mapy, &mask, interpolation ); + dst.setTo(Scalar::all(0), mask); + dst0.setTo(Scalar::all(0), mask); +} + + +class CV_UndistortMapTest : public cvtest::ArrayTest +{ +public: + CV_UndistortMapTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); + void fill_array( int test_case_idx, int i, int j, Mat& arr ); + +private: + bool dualChannel; +}; + + +CV_UndistortMapTest::CV_UndistortMapTest() +{ + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + + element_wise_relative_error = false; +} + + +void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + + CvSize sz = sizes[OUTPUT][0]; + types[INPUT][0] = types[INPUT][1] = depth; + dualChannel = cvtest::randInt(rng)%2 == 0; + types[OUTPUT][0] = types[OUTPUT][1] = + types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F; + sizes[INPUT][0] = cvSize(3,3); + sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4); + + sz.width = MAX(sz.width,16); + sz.height = MAX(sz.height,16); + sizes[OUTPUT][0] = sizes[OUTPUT][1] = + sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz; +} + + +void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + if( i != INPUT ) + cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); +} + + +void CV_UndistortMapTest::run_func() +{ + CvMat a = test_mat[INPUT][0], k = test_mat[INPUT][1]; + + if (!dualChannel ) + cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] ); + else + cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 ); +} + + +double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 1e-3; +} + + +int CV_UndistortMapTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + const Mat& mapx = test_mat[OUTPUT][0]; + double k[4], a[9] = {0,0,0,0,0,0,0,0,1}; + double sz = MAX(mapx.rows, mapx.cols); + Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1]; + Mat _a(3,3,CV_64F,a); + Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k); + + if( code <= 0 ) + return code; + + double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; + a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); + a[4] = aspect_ratio*a[0]; + k[0] = cvtest::randReal(rng)*0.06 - 0.03; + k[1] = cvtest::randReal(rng)*0.06 - 0.03; + if( k[0]*k[1] > 0 ) + k[1] = -k[1]; + k[2] = cvtest::randReal(rng)*0.004 - 0.002; + k[3] = cvtest::randReal(rng)*0.004 - 0.002; + + _a.convertTo(_a0, _a0.depth()); + _k.convertTo(_k0, _k0.depth()); + + if (dualChannel) + { + test_mat[REF_OUTPUT][1] = Scalar::all(0); + test_mat[OUTPUT][1] = Scalar::all(0); + } + + return code; +} + + +void CV_UndistortMapTest::prepare_to_validation( int ) +{ + Mat mapx, mapy; + cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy ); + if( !dualChannel ) + { + mapx.copyTo(test_mat[REF_OUTPUT][0]); + mapy.copyTo(test_mat[REF_OUTPUT][1]); + } + else + { + Mat p[2] = {mapx, mapy}; + cv::merge(p, 2, test_mat[REF_OUTPUT][0]); + } +} + +////////////////////////////// GetRectSubPix ///////////////////////////////// + +static void +test_getQuadrangeSubPix( const Mat& src, Mat& dst, double* a ) +{ + int sstep = (int)(src.step / sizeof(float)); + int scols = src.cols, srows = src.rows; + + CV_Assert( src.depth() == CV_32F && src.type() == dst.type() ); + + int cn = dst.channels(); + + for( int y = 0; y < dst.rows; y++ ) + for( int x = 0; x < dst.cols; x++ ) + { + float* d = dst.ptr(y) + x*cn; + float sx = (float)(a[0]*x + a[1]*y + a[2]); + float sy = (float)(a[3]*x + a[4]*y + a[5]); + int ix = cvFloor(sx), iy = cvFloor(sy); + int dx = cn, dy = sstep; + const float* s; + sx -= ix; sy -= iy; + + if( (unsigned)ix >= (unsigned)(scols-1) ) + ix = ix < 0 ? 0 : scols - 1, sx = 0, dx = 0; + if( (unsigned)iy >= (unsigned)(srows-1) ) + iy = iy < 0 ? 0 : srows - 1, sy = 0, dy = 0; + + s = src.ptr(iy) + ix*cn; + for( int k = 0; k < cn; k++, s++ ) + { + float t0 = s[0] + sx*(s[dx] - s[0]); + float t1 = s[dy] + sx*(s[dy + dx] - s[dy]); + d[k] = t0 + sy*(t1 - t0); + } + } +} + + +class CV_GetRectSubPixTest : public CV_ImgWarpBaseTest +{ +public: + CV_GetRectSubPixTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); + void fill_array( int test_case_idx, int i, int j, Mat& arr ); + + CvPoint2D32f center; + bool test_cpp; +}; + + +CV_GetRectSubPixTest::CV_GetRectSubPixTest() : CV_ImgWarpBaseTest( false ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + spatial_scale_decimate = spatial_scale_zoom; + test_cpp = false; +} + + +void CV_GetRectSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int src_depth = cvtest::randInt(rng) % 2, dst_depth; + int cn = cvtest::randInt(rng) % 2 ? 3 : 1; + CvSize src_size, dst_size; + + dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F; + if( src_depth < CV_32F && cvtest::randInt(rng) % 2 ) + dst_depth = CV_32F; + + types[INPUT][0] = CV_MAKETYPE(src_depth,cn); + types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn); + + src_size = sizes[INPUT][0]; + dst_size.width = cvRound(sqrt(cvtest::randReal(rng)*src_size.width) + 1); + dst_size.height = cvRound(sqrt(cvtest::randReal(rng)*src_size.height) + 1); + dst_size.width = MIN(dst_size.width,src_size.width); + dst_size.height = MIN(dst_size.width,src_size.height); + sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dst_size; + + center.x = (float)(cvtest::randReal(rng)*src_size.width); + center.y = (float)(cvtest::randReal(rng)*src_size.height); + interpolation = CV_INTER_LINEAR; + + test_cpp = (cvtest::randInt(rng) & 256) == 0; +} + + +void CV_GetRectSubPixTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +{ + if( i != INPUT ) + CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr ); +} + + +void CV_GetRectSubPixTest::run_func() +{ + if(!test_cpp) + cvGetRectSubPix( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], center ); + else + { + cv::Mat _out = cv::cvarrToMat(test_array[INPUT_OUTPUT][0]); + cv::getRectSubPix( cv::cvarrToMat(test_array[INPUT][0]), _out.size(), center, _out, _out.type()); + } +} + + +double CV_GetRectSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int in_depth = test_mat[INPUT][0].depth(); + int out_depth = test_mat[INPUT_OUTPUT][0].depth(); + + return in_depth >= CV_32F ? 1e-3 : out_depth >= CV_32F ? 1e-2 : 1; +} + + +int CV_GetRectSubPixTest::prepare_test_case( int test_case_idx ) +{ + return CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); +} + + +void CV_GetRectSubPixTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src0 = test_mat[INPUT][0]; + Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0]; + Mat src = src0, dst = dst0; + int ftype = CV_MAKETYPE(CV_32F,src0.channels()); + double a[] = { 1, 0, center.x - dst.cols*0.5 + 0.5, + 0, 1, center.y - dst.rows*0.5 + 0.5 }; + if( src.depth() != CV_32F ) + src0.convertTo(src, CV_32F); + + if( dst.depth() != CV_32F ) + dst.create(dst0.size(), ftype); + + test_getQuadrangeSubPix( src, dst, a ); + + if( dst.data != dst0.data ) + dst.convertTo(dst0, dst0.depth()); +} + + +class CV_GetQuadSubPixTest : public CV_ImgWarpBaseTest +{ +public: + CV_GetQuadSubPixTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void run_func(); + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + double get_success_error_level( int test_case_idx, int i, int j ); +}; + + +CV_GetQuadSubPixTest::CV_GetQuadSubPixTest() : CV_ImgWarpBaseTest( true ) +{ + //spatial_scale_zoom = spatial_scale_decimate; + spatial_scale_decimate = spatial_scale_zoom; +} + + +void CV_GetQuadSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + int min_size = 4; + CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + CvSize sz = sizes[INPUT][0], dsz; + RNG& rng = ts->get_rng(); + int msz, src_depth = cvtest::randInt(rng) % 2, dst_depth; + int cn = cvtest::randInt(rng) % 2 ? 3 : 1; + + dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F; + if( src_depth < CV_32F && cvtest::randInt(rng) % 2 ) + dst_depth = CV_32F; + + types[INPUT][0] = CV_MAKETYPE(src_depth,cn); + types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn); + + sz.width = MAX(sz.width,min_size); + sz.height = MAX(sz.height,min_size); + sizes[INPUT][0] = sz; + msz = MIN( sz.width, sz.height ); + + dsz.width = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1); + dsz.height = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1); + dsz.width = MIN(dsz.width,msz); + dsz.height = MIN(dsz.width,msz); + dsz.width = MAX(dsz.width,min_size); + dsz.height = MAX(dsz.height,min_size); + sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dsz; + sizes[INPUT][1] = cvSize( 3, 2 ); +} + + +void CV_GetQuadSubPixTest::run_func() +{ + CvMat mtx = test_mat[INPUT][1]; + cvGetQuadrangleSubPix( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx ); +} + + +double CV_GetQuadSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int in_depth = test_mat[INPUT][0].depth(); + //int out_depth = test_mat[INPUT_OUTPUT][0].depth(); + + return in_depth >= CV_32F ? 1e-2 : 4; +} + + +int CV_GetQuadSubPixTest::prepare_test_case( int test_case_idx ) +{ + RNG& rng = ts->get_rng(); + int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx ); + const Mat& src = test_mat[INPUT][0]; + Mat& mat = test_mat[INPUT][1]; + CvPoint2D32f center; + double scale, angle; + + if( code <= 0 ) + return code; + + double a[6]; + Mat A( 2, 3, CV_64FC1, a ); + + center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols); + center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows); + angle = cvtest::randReal(rng)*360; + scale = cvtest::randReal(rng)*0.2 + 0.9; + + // y = Ax + b -> x = A^-1(y - b) = A^-1*y - A^-1*b + scale = 1./scale; + angle = angle*(CV_PI/180.); + a[0] = a[4] = cos(angle)*scale; + a[1] = sin(angle)*scale; + a[3] = -a[1]; + a[2] = center.x - a[0]*center.x - a[1]*center.y; + a[5] = center.y - a[3]*center.x - a[4]*center.y; + A.convertTo( mat, mat.depth() ); + + return code; +} + + +void CV_GetQuadSubPixTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src0 = test_mat[INPUT][0]; + Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0]; + Mat src = src0, dst = dst0; + int ftype = CV_MAKETYPE(CV_32F,src0.channels()); + double a[6], dx = (dst0.cols - 1)*0.5, dy = (dst0.rows - 1)*0.5; + Mat A( 2, 3, CV_64F, a ); + + if( src.depth() != CV_32F ) + src0.convertTo(src, CV_32F); + + if( dst.depth() != CV_32F ) + dst.create(dst0.size(), ftype); + + test_mat[INPUT][1].convertTo( A, CV_64F ); + a[2] -= a[0]*dx + a[1]*dy; + a[5] -= a[3]*dx + a[4]*dy; + test_getQuadrangeSubPix( src, dst, a ); + + if( dst.data != dst0.data ) + dst.convertTo(dst0, dst0.depth()); +} + +TEST(Imgproc_cvWarpAffine, regression) +{ + IplImage* src = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1); + IplImage* dst = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1); + + float m[6]; + CvMat M = cvMat( 2, 3, CV_32F, m ); + int w = src->width; + int h = src->height; + cv2DRotationMatrix(cvPoint2D32f(w*0.5f, h*0.5f), 45.0, 1.0, &M); + cvWarpAffine(src, dst, &M); +} + +TEST(Imgproc_fitLine_vector_3d, regression) +{ + std::vector points_vector; + + Point3f p21(4,4,4); + Point3f p22(8,8,8); + + points_vector.push_back(p21); + points_vector.push_back(p22); + + std::vector line; + + cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line.size(), (size_t)6); + +} + +TEST(Imgproc_fitLine_vector_2d, regression) +{ + std::vector points_vector; + + Point2f p21(4,4); + Point2f p22(8,8); + Point2f p23(16,16); + + points_vector.push_back(p21); + points_vector.push_back(p22); + points_vector.push_back(p23); + + std::vector line; + + cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line.size(), (size_t)4); +} + +TEST(Imgproc_fitLine_Mat_2dC2, regression) +{ + cv::Mat mat1(3, 1, CV_32SC2); + std::vector line1; + + cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line1.size(), (size_t)4); +} + +TEST(Imgproc_fitLine_Mat_2dC1, regression) +{ + cv::Matx mat2; + std::vector line2; + + cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line2.size(), (size_t)4); +} + +TEST(Imgproc_fitLine_Mat_3dC3, regression) +{ + cv::Mat mat1(2, 1, CV_32SC3); + std::vector line1; + + cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line1.size(), (size_t)6); +} + +TEST(Imgproc_fitLine_Mat_3dC1, regression) +{ + cv::Mat mat2(2, 3, CV_32SC1); + std::vector line2; + + cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0); + + ASSERT_EQ(line2.size(), (size_t)6); +} + +TEST(Imgproc_resize_area, regression) +{ + static ushort input_data[16 * 16] = { + 90, 94, 80, 3, 231, 2, 186, 245, 188, 165, 10, 19, 201, 169, 8, 228, + 86, 5, 203, 120, 136, 185, 24, 94, 81, 150, 163, 137, 88, 105, 132, 132, + 236, 48, 250, 218, 19, 52, 54, 221, 159, 112, 45, 11, 152, 153, 112, 134, + 78, 133, 136, 83, 65, 76, 82, 250, 9, 235, 148, 26, 236, 179, 200, 50, + 99, 51, 103, 142, 201, 65, 176, 33, 49, 226, 177, 109, 46, 21, 67, 130, + 54, 125, 107, 154, 145, 51, 199, 189, 161, 142, 231, 240, 139, 162, 240, 22, + 231, 86, 79, 106, 92, 47, 146, 156, 36, 207, 71, 33, 2, 244, 221, 71, + 44, 127, 71, 177, 75, 126, 68, 119, 200, 129, 191, 251, 6, 236, 247, 6, + 133, 175, 56, 239, 147, 221, 243, 154, 242, 82, 106, 99, 77, 158, 60, 229, + 2, 42, 24, 174, 27, 198, 14, 204, 246, 251, 141, 31, 114, 163, 29, 147, + 121, 53, 74, 31, 147, 189, 42, 98, 202, 17, 228, 123, 209, 40, 77, 49, + 112, 203, 30, 12, 205, 25, 19, 106, 145, 185, 163, 201, 237, 223, 247, 38, + 33, 105, 243, 117, 92, 179, 204, 248, 160, 90, 73, 126, 2, 41, 213, 204, + 6, 124, 195, 201, 230, 187, 210, 167, 48, 79, 123, 159, 145, 218, 105, 209, + 240, 152, 136, 235, 235, 164, 157, 9, 152, 38, 27, 209, 120, 77, 238, 196, + 240, 233, 10, 241, 90, 67, 12, 79, 0, 43, 58, 27, 83, 199, 190, 182}; + + static ushort expected_data[5 * 5] = { + 120, 100, 151, 101, 130, + 106, 115, 141, 130, 127, + 91, 136, 170, 114, 140, + 104, 122, 131, 147, 133, + 161, 163, 70, 107, 182 + }; + + cv::Mat src(16, 16, CV_16UC1, input_data); + cv::Mat expected(5, 5, CV_16UC1, expected_data); + cv::Mat actual(expected.size(), expected.type()); + + cv::resize(src, actual, cv::Size(), 0.3, 0.3, INTER_AREA); + + ASSERT_EQ(actual.type(), expected.type()); + ASSERT_EQ(actual.size(), expected.size()); + + Mat diff; + absdiff(actual, expected, diff); + + Mat one_channel_diff = diff; //.reshape(1); + + float elem_diff = 1.0f; + Size dsize = actual.size(); + bool next = true; + for (int dy = 0; dy < dsize.height && next; ++dy) + { + ushort* eD = expected.ptr(dy); + ushort* aD = actual.ptr(dy); + + for (int dx = 0; dx < dsize.width && next; ++dx) + if (fabs(static_cast(aD[dx] - eD[dx])) > elem_diff) + { + cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Inf norm: %f\n", static_cast(norm(actual, expected, NORM_INF))); + cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Error in : (%d, %d)\n", dx, dy); + + const int radius = 3; + int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height); + int cmin = MAX(dx - radius, 0), cmax = MIN(dx + radius, dsize.width); + + std::cout << "Abs diff:" << std::endl << diff << std::endl; + std::cout << "actual result:\n" << actual(Range(rmin, rmax), Range(cmin, cmax)) << std::endl; + std::cout << "expected result:\n" << expected(Range(rmin, rmax), Range(cmin, cmax)) << std::endl; + + next = false; + } + } + + ASSERT_EQ(norm(one_channel_diff, cv::NORM_INF), 0); +} + + +////////////////////////////////////////////////////////////////////////// + +TEST(Imgproc_Resize, accuracy) { CV_ResizeTest test; test.safe_run(); } +TEST(Imgproc_WarpAffine, accuracy) { CV_WarpAffineTest test; test.safe_run(); } +TEST(Imgproc_WarpPerspective, accuracy) { CV_WarpPerspectiveTest test; test.safe_run(); } +TEST(Imgproc_Remap, accuracy) { CV_RemapTest test; test.safe_run(); } +TEST(Imgproc_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); } +TEST(Imgproc_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); } +TEST(Imgproc_GetRectSubPix, accuracy) { CV_GetRectSubPixTest test; test.safe_run(); } +TEST(Imgproc_GetQuadSubPix, accuracy) { CV_GetQuadSubPixTest test; test.safe_run(); } + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_imgwarp_strict.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_imgwarp_strict.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_imgwarp_strict.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_imgwarp_strict.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1222 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +#include +#include +#include + +using namespace cv; + +namespace internal +{ + void __wrap_printf_func(const char* fmt, ...) + { + va_list args; + va_start(args, fmt); + char buffer[256]; + vsprintf (buffer, fmt, args); + cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, buffer); + va_end(args); + } + + #define PRINT_TO_LOG __wrap_printf_func +} + +using internal::PRINT_TO_LOG; +#define SHOW_IMAGE +#undef SHOW_IMAGE + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// ImageWarpBaseTest +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_ImageWarpBaseTest : + public cvtest::BaseTest +{ +public: + enum { cell_size = 10 }; + + CV_ImageWarpBaseTest(); + virtual ~CV_ImageWarpBaseTest(); + + virtual void run(int); +protected: + virtual void generate_test_data(); + + virtual void run_func() = 0; + virtual void run_reference_func() = 0; + virtual void validate_results() const; + virtual void prepare_test_data_for_reference_func(); + + Size randSize(RNG& rng) const; + + const char* interpolation_to_string(int inter_type) const; + + int interpolation; + Mat src; + Mat dst; + Mat reference_dst; +}; + +CV_ImageWarpBaseTest::CV_ImageWarpBaseTest() : + BaseTest(), interpolation(-1), + src(), dst(), reference_dst() +{ + test_case_count = 40; + ts->set_failed_test_info(cvtest::TS::OK); +} + +CV_ImageWarpBaseTest::~CV_ImageWarpBaseTest() +{ +} + +const char* CV_ImageWarpBaseTest::interpolation_to_string(int inter) const +{ + if (inter == INTER_NEAREST) + return "INTER_NEAREST"; + if (inter == INTER_LINEAR) + return "INTER_LINEAR"; + if (inter == INTER_AREA) + return "INTER_AREA"; + if (inter == INTER_CUBIC) + return "INTER_CUBIC"; + if (inter == INTER_LANCZOS4) + return "INTER_LANCZOS4"; + if (inter == INTER_LANCZOS4 + 1) + return "INTER_AREA_FAST"; + return "Unsupported/Unkown interpolation type"; +} + +Size CV_ImageWarpBaseTest::randSize(RNG& rng) const +{ + Size size; + size.width = static_cast(std::exp(rng.uniform(1.0f, 7.0f))); + size.height = static_cast(std::exp(rng.uniform(1.0f, 7.0f))); + + return size; +} + +void CV_ImageWarpBaseTest::generate_test_data() +{ + RNG& rng = ts->get_rng(); + + // generating the src matrix structure + Size ssize = randSize(rng), dsize; + + int depth = rng.uniform(0, CV_64F); + while (depth == CV_8S || depth == CV_32S) + depth = rng.uniform(0, CV_64F); + + int cn = rng.uniform(1, 4); + while (cn == 2) + cn = rng.uniform(1, 4); + + src.create(ssize, CV_MAKE_TYPE(depth, cn)); + + // generating the src matrix + int x, y; + if (cvtest::randInt(rng) % 2) + { + for (y = 0; y < ssize.height; y += cell_size) + for (x = 0; x < ssize.width; x += cell_size) + rectangle(src, Point(x, y), Point(x + std::min(cell_size, ssize.width - x), y + + std::min(cell_size, ssize.height - y)), Scalar::all((x + y) % 2 ? 255: 0), CV_FILLED); + } + else + { + src = Scalar::all(255); + for (y = cell_size; y < src.rows; y += cell_size) + line(src, Point2i(0, y), Point2i(src.cols, y), Scalar::all(0), 1); + for (x = cell_size; x < src.cols; x += cell_size) + line(src, Point2i(x, 0), Point2i(x, src.rows), Scalar::all(0), 1); + } + + // generating an interpolation type + interpolation = rng.uniform(0, CV_INTER_LANCZOS4 + 1); + + // generating the dst matrix structure + double scale_x, scale_y; + if (interpolation == INTER_AREA) + { + bool area_fast = rng.uniform(0., 1.) > 0.5; + if (area_fast) + { + scale_x = rng.uniform(2, 5); + scale_y = rng.uniform(2, 5); + } + else + { + scale_x = rng.uniform(1.0, 3.0); + scale_y = rng.uniform(1.0, 3.0); + } + } + else + { + scale_x = rng.uniform(0.4, 4.0); + scale_y = rng.uniform(0.4, 4.0); + } + CV_Assert(scale_x > 0.0f && scale_y > 0.0f); + + dsize.width = saturate_cast((ssize.width + scale_x - 1) / scale_x); + dsize.height = saturate_cast((ssize.height + scale_y - 1) / scale_y); + + dst = Mat::zeros(dsize, src.type()); + reference_dst = Mat::zeros(dst.size(), CV_MAKE_TYPE(CV_32F, dst.channels())); + + scale_x = src.cols / static_cast(dst.cols); + scale_y = src.rows / static_cast(dst.rows); + + if (interpolation == INTER_AREA && (scale_x < 1.0 || scale_y < 1.0)) + interpolation = INTER_LINEAR; +} + +void CV_ImageWarpBaseTest::run(int) +{ + for (int i = 0; i < test_case_count; ++i) + { + generate_test_data(); + run_func(); + run_reference_func(); + if (ts->get_err_code() < 0) + break; + validate_results(); + if (ts->get_err_code() < 0) + break; + ts->update_context(this, i, true); + } + ts->set_gtest_status(); +} + +void CV_ImageWarpBaseTest::validate_results() const +{ + Mat _dst; + dst.convertTo(_dst, reference_dst.depth()); + + Size dsize = dst.size(), ssize = src.size(); + int cn = _dst.channels(); + dsize.width *= cn; + float t = 1.0f; + if (interpolation == INTER_CUBIC) + t = 1.0f; + else if (interpolation == INTER_LANCZOS4) + t = 1.0f; + else if (interpolation == INTER_NEAREST) + t = 1.0f; + else if (interpolation == INTER_AREA) + t = 2.0f; + + for (int dy = 0; dy < dsize.height; ++dy) + { + const float* rD = reference_dst.ptr(dy); + const float* D = _dst.ptr(dy); + + for (int dx = 0; dx < dsize.width; ++dx) + if (fabs(rD[dx] - D[dx]) > t && +// fabs(rD[dx] - D[dx]) < 250.0f && + rD[dx] <= 255.0f && D[dx] <= 255.0f && rD[dx] >= 0.0f && D[dx] >= 0.0f) + { + PRINT_TO_LOG("\nNorm of the difference: %lf\n", norm(reference_dst, _dst, NORM_INF)); + PRINT_TO_LOG("Error in (dx, dy): (%d, %d)\n", dx / cn + 1, dy + 1); + PRINT_TO_LOG("Tuple (rD, D): (%f, %f)\n", rD[dx], D[dx]); + PRINT_TO_LOG("Dsize: (%d, %d)\n", dsize.width / cn, dsize.height); + PRINT_TO_LOG("Ssize: (%d, %d)\n", src.cols, src.rows); + + double scale_x = static_cast(ssize.width) / dsize.width; + double scale_y = static_cast(ssize.height) / dsize.height; + bool area_fast = interpolation == INTER_AREA && + fabs(scale_x - cvRound(scale_x)) < FLT_EPSILON && + fabs(scale_y - cvRound(scale_y)) < FLT_EPSILON; + if (area_fast) + { + scale_y = cvRound(scale_y); + scale_x = cvRound(scale_x); + } + + PRINT_TO_LOG("Interpolation: %s\n", interpolation_to_string(area_fast ? INTER_LANCZOS4 + 1 : interpolation)); + PRINT_TO_LOG("Scale (x, y): (%lf, %lf)\n", scale_x, scale_y); + PRINT_TO_LOG("Elemsize: %d\n", src.elemSize1()); + PRINT_TO_LOG("Channels: %d\n", cn); + +#ifdef SHOW_IMAGE + const std::string w1("OpenCV impl (run func)"), w2("Reference func"), w3("Src image"), w4("Diff"); + namedWindow(w1, CV_WINDOW_KEEPRATIO); + namedWindow(w2, CV_WINDOW_KEEPRATIO); + namedWindow(w3, CV_WINDOW_KEEPRATIO); + namedWindow(w4, CV_WINDOW_KEEPRATIO); + + Mat diff; + absdiff(reference_dst, _dst, diff); + + imshow(w1, dst); + imshow(w2, reference_dst); + imshow(w3, src); + imshow(w4, diff); + + waitKey(); +#endif + + const int radius = 3; + int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height); + int cmin = MAX(dx / cn - radius, 0), cmax = MIN(dx / cn + radius, dsize.width); + + std::cout << "opencv result:\n" << dst(Range(rmin, rmax), Range(cmin, cmax)) << std::endl; + std::cout << "reference result:\n" << reference_dst(Range(rmin, rmax), Range(cmin, cmax)) << std::endl; + + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + return; + } + } +} + +void CV_ImageWarpBaseTest::prepare_test_data_for_reference_func() +{ + if (src.depth() != CV_32F) + { + Mat tmp; + src.convertTo(tmp, CV_32F); + src = tmp; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Resize +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_Resize_Test : + public CV_ImageWarpBaseTest +{ +public: + CV_Resize_Test(); + virtual ~CV_Resize_Test(); + +protected: + virtual void generate_test_data(); + + virtual void run_func(); + virtual void run_reference_func(); + +private: + double scale_x; + double scale_y; + bool area_fast; + + void resize_generic(); + void resize_area(); + double getWeight(double a, double b, int x); + + typedef std::vector > dim; + void generate_buffer(double scale, dim& _dim); + void resize_1d(const Mat& _src, Mat& _dst, int dy, const dim& _dim); +}; + +CV_Resize_Test::CV_Resize_Test() : + CV_ImageWarpBaseTest(), scale_x(), + scale_y(), area_fast(false) +{ +} + +CV_Resize_Test::~CV_Resize_Test() +{ +} + +namespace internal +{ + void interpolateLinear(float x, float* coeffs) + { + coeffs[0] = 1.f - x; + coeffs[1] = x; + } + + void interpolateCubic(float x, float* coeffs) + { + const float A = -0.75f; + + coeffs[0] = ((A*(x + 1) - 5*A)*(x + 1) + 8*A)*(x + 1) - 4*A; + coeffs[1] = ((A + 2)*x - (A + 3))*x*x + 1; + coeffs[2] = ((A + 2)*(1 - x) - (A + 3))*(1 - x)*(1 - x) + 1; + coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2]; + } + + void interpolateLanczos4(float x, float* coeffs) + { + static const double s45 = 0.70710678118654752440084436210485; + static const double cs[][2]= + {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}}; + + if( x < FLT_EPSILON ) + { + for( int i = 0; i < 8; i++ ) + coeffs[i] = 0; + coeffs[3] = 1; + return; + } + + float sum = 0; + double y0=-(x+3)*CV_PI*0.25, s0 = sin(y0), c0=cos(y0); + for(int i = 0; i < 8; i++ ) + { + double y = -(x+3-i)*CV_PI*0.25; + coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y)); + sum += coeffs[i]; + } + + sum = 1.f/sum; + for(int i = 0; i < 8; i++ ) + coeffs[i] *= sum; + } + + typedef void (*interpolate_method)(float x, float* coeffs); + interpolate_method inter_array[] = { &interpolateLinear, &interpolateCubic, &interpolateLanczos4 }; +} + +void CV_Resize_Test::generate_test_data() +{ + CV_ImageWarpBaseTest::generate_test_data(); + + scale_x = src.cols / static_cast(dst.cols); + scale_y = src.rows / static_cast(dst.rows); + + area_fast = interpolation == INTER_AREA && + fabs(scale_x - cvRound(scale_x)) < FLT_EPSILON && + fabs(scale_y - cvRound(scale_y)) < FLT_EPSILON; + if (area_fast) + { + scale_x = cvRound(scale_x); + scale_y = cvRound(scale_y); + } +} + +void CV_Resize_Test::run_func() +{ + cv::resize(src, dst, dst.size(), 0, 0, interpolation); +} + +void CV_Resize_Test::run_reference_func() +{ + CV_ImageWarpBaseTest::prepare_test_data_for_reference_func(); + + if (interpolation == INTER_AREA) + resize_area(); + else + resize_generic(); +} + +double CV_Resize_Test::getWeight(double a, double b, int x) +{ + double w = std::min(static_cast(x + 1), b) - std::max(static_cast(x), a); + CV_Assert(w >= 0); + return w; +} + +void CV_Resize_Test::resize_area() +{ + Size ssize = src.size(), dsize = reference_dst.size(); + CV_Assert(ssize.area() > 0 && dsize.area() > 0); + int cn = src.channels(); + + CV_Assert(scale_x >= 1.0 && scale_y >= 1.0); + + double fsy0 = 0, fsy1 = scale_y; + for (int dy = 0; dy < dsize.height; ++dy) + { + float* yD = reference_dst.ptr(dy); + int isy0 = cvFloor(fsy0), isy1 = std::min(cvFloor(fsy1), ssize.height - 1); + CV_Assert(isy1 <= ssize.height && isy0 < ssize.height); + + double fsx0 = 0, fsx1 = scale_x; + + for (int dx = 0; dx < dsize.width; ++dx) + { + float* xyD = yD + cn * dx; + int isx0 = cvFloor(fsx0), isx1 = std::min(ssize.width - 1, cvFloor(fsx1)); + + CV_Assert(isx1 <= ssize.width); + CV_Assert(isx0 < ssize.width); + + // for each pixel of dst + for (int r = 0; r < cn; ++r) + { + xyD[r] = 0.0f; + double area = 0.0; + for (int sy = isy0; sy <= isy1; ++sy) + { + const float* yS = src.ptr(sy); + for (int sx = isx0; sx <= isx1; ++sx) + { + double wy = getWeight(fsy0, fsy1, sy); + double wx = getWeight(fsx0, fsx1, sx); + double w = wx * wy; + xyD[r] += static_cast(yS[sx * cn + r] * w); + area += w; + } + } + + CV_Assert(area != 0); + // norming pixel + xyD[r] = static_cast(xyD[r] / area); + } + fsx1 = std::min((fsx0 = fsx1) + scale_x, static_cast(ssize.width)); + } + fsy1 = std::min((fsy0 = fsy1) + scale_y, static_cast(ssize.height)); + } +} + +// for interpolation type : INTER_LINEAR, INTER_LINEAR, INTER_CUBIC, INTER_LANCZOS4 +void CV_Resize_Test::resize_1d(const Mat& _src, Mat& _dst, int dy, const dim& _dim) +{ + Size dsize = _dst.size(); + int cn = _dst.channels(); + float* yD = _dst.ptr(dy); + + if (interpolation == INTER_NEAREST) + { + const float* yS = _src.ptr(dy); + for (int dx = 0; dx < dsize.width; ++dx) + { + int isx = _dim[dx].first; + const float* xyS = yS + isx * cn; + float* xyD = yD + dx * cn; + + for (int r = 0; r < cn; ++r) + xyD[r] = xyS[r]; + } + } + else if (interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_LANCZOS4) + { + internal::interpolate_method inter_func = internal::inter_array[interpolation - (interpolation == INTER_LANCZOS4 ? 2 : 1)]; + size_t elemsize = _src.elemSize(); + + int ofs = 0, ksize = 2; + if (interpolation == INTER_CUBIC) + ofs = 1, ksize = 4; + else if (interpolation == INTER_LANCZOS4) + ofs = 3, ksize = 8; + + Mat _extended_src_row(1, _src.cols + ksize * 2, _src.type()); + uchar* srow = _src.data + dy * _src.step; + memcpy(_extended_src_row.data + elemsize * ksize, srow, _src.step); + for (int k = 0; k < ksize; ++k) + { + memcpy(_extended_src_row.data + k * elemsize, srow, elemsize); + memcpy(_extended_src_row.data + (ksize + k) * elemsize + _src.step, srow + _src.step - elemsize, elemsize); + } + + for (int dx = 0; dx < dsize.width; ++dx) + { + int isx = _dim[dx].first; + double fsx = _dim[dx].second; + + float *xyD = yD + dx * cn; + const float* xyS = _extended_src_row.ptr(0) + (isx + ksize - ofs) * cn; + + float w[8]; + inter_func(static_cast(fsx), w); + + for (int r = 0; r < cn; ++r) + { + xyD[r] = 0; + for (int k = 0; k < ksize; ++k) + xyD[r] += w[k] * xyS[k * cn + r]; + xyD[r] = xyD[r]; + } + } + } + else + CV_Assert(0); +} + +void CV_Resize_Test::generate_buffer(double scale, dim& _dim) +{ + size_t length = _dim.size(); + for (size_t dx = 0; dx < length; ++dx) + { + double fsx = scale * (dx + 0.5) - 0.5; + int isx = cvFloor(fsx); + _dim[dx] = std::make_pair(isx, fsx - isx); + } +} + +void CV_Resize_Test::resize_generic() +{ + Size dsize = reference_dst.size(), ssize = src.size(); + CV_Assert(dsize.area() > 0 && ssize.area() > 0); + + dim dims[] = { dim(dsize.width), dim(dsize.height) }; + if (interpolation == INTER_NEAREST) + { + for (int dx = 0; dx < dsize.width; ++dx) + dims[0][dx].first = std::min(cvFloor(dx * scale_x), ssize.width - 1); + for (int dy = 0; dy < dsize.height; ++dy) + dims[1][dy].first = std::min(cvFloor(dy * scale_y), ssize.height - 1); + } + else + { + generate_buffer(scale_x, dims[0]); + generate_buffer(scale_y, dims[1]); + } + + Mat tmp(ssize.height, dsize.width, reference_dst.type()); + for (int dy = 0; dy < tmp.rows; ++dy) + resize_1d(src, tmp, dy, dims[0]); + + transpose(tmp, tmp); + transpose(reference_dst, reference_dst); + + for (int dy = 0; dy < tmp.rows; ++dy) + resize_1d(tmp, reference_dst, dy, dims[1]); + transpose(reference_dst, reference_dst); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// remap +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_Remap_Test : + public CV_ImageWarpBaseTest +{ +public: + CV_Remap_Test(); + + virtual ~CV_Remap_Test(); + +private: + typedef void (CV_Remap_Test::*remap_func)(const Mat&, Mat&); + +protected: + virtual void generate_test_data(); + virtual void prepare_test_data_for_reference_func(); + + virtual void run_func(); + virtual void run_reference_func(); + + Mat mapx, mapy; + int borderType; + Scalar borderValue; + + remap_func funcs[2]; + +private: + void remap_nearest(const Mat&, Mat&); + void remap_generic(const Mat&, Mat&); + + void convert_maps(); + const char* borderType_to_string() const; + virtual void validate_results() const; +}; + +CV_Remap_Test::CV_Remap_Test() : + CV_ImageWarpBaseTest(), mapx(), mapy(), + borderType(-1), borderValue() +{ + funcs[0] = &CV_Remap_Test::remap_nearest; + funcs[1] = &CV_Remap_Test::remap_generic; +} + +CV_Remap_Test::~CV_Remap_Test() +{ +} + +void CV_Remap_Test::generate_test_data() +{ + CV_ImageWarpBaseTest::generate_test_data(); + + RNG& rng = ts->get_rng(); + borderType = rng.uniform(1, BORDER_WRAP); + borderValue = Scalar::all(rng.uniform(0, 255)); + + // generating the mapx, mapy matrices + static const int mapx_types[] = { CV_16SC2, CV_32FC1, CV_32FC2 }; + mapx.create(dst.size(), mapx_types[rng.uniform(0, sizeof(mapx_types) / sizeof(int))]); + mapy = Mat(); + + const int n = std::min(std::min(src.cols, src.rows) / 10 + 1, 2); + float _n = 0; //static_cast(-n); + + switch (mapx.type()) + { + case CV_16SC2: + { + MatIterator_ begin_x = mapx.begin(), end_x = mapx.end(); + for ( ; begin_x != end_x; ++begin_x) + { + begin_x[0] = static_cast(rng.uniform(static_cast(_n), std::max(src.cols + n - 1, 0))); + begin_x[1] = static_cast(rng.uniform(static_cast(_n), std::max(src.rows + n - 1, 0))); + } + + if (interpolation != INTER_NEAREST) + { + static const int mapy_types[] = { CV_16UC1, CV_16SC1 }; + mapy.create(dst.size(), mapy_types[rng.uniform(0, sizeof(mapy_types) / sizeof(int))]); + + switch (mapy.type()) + { + case CV_16UC1: + { + MatIterator_ begin_y = mapy.begin(), end_y = mapy.end(); + for ( ; begin_y != end_y; ++begin_y) + begin_y[0] = static_cast(rng.uniform(0, 1024)); + } + break; + + case CV_16SC1: + { + MatIterator_ begin_y = mapy.begin(), end_y = mapy.end(); + for ( ; begin_y != end_y; ++begin_y) + begin_y[0] = static_cast(rng.uniform(0, 1024)); + } + break; + } + } + } + break; + + case CV_32FC1: + { + mapy.create(dst.size(), CV_32FC1); + float fscols = static_cast(std::max(src.cols - 1 + n, 0)), + fsrows = static_cast(std::max(src.rows - 1 + n, 0)); + MatIterator_ begin_x = mapx.begin(), end_x = mapx.end(); + MatIterator_ begin_y = mapy.begin(); + for ( ; begin_x != end_x; ++begin_x, ++begin_y) + { + begin_x[0] = rng.uniform(_n, fscols); + begin_y[0] = rng.uniform(_n, fsrows); + } + } + break; + + case CV_32FC2: + { + MatIterator_ begin_x = mapx.begin(), end_x = mapx.end(); + float fscols = static_cast(std::max(src.cols - 1 + n, 0)), + fsrows = static_cast(std::max(src.rows - 1 + n, 0)); + for ( ; begin_x != end_x; ++begin_x) + { + begin_x[0] = rng.uniform(_n, fscols); + begin_x[1] = rng.uniform(_n, fsrows); + } + } + break; + + default: + assert(0); + break; + } +} + +void CV_Remap_Test::run_func() +{ + remap(src, dst, mapx, mapy, interpolation, borderType, borderValue); +} + +void CV_Remap_Test::convert_maps() +{ + if (mapx.type() != CV_16SC2) + convertMaps(mapx.clone(), mapy.clone(), mapx, mapy, CV_16SC2, interpolation == INTER_NEAREST); + else if (interpolation != INTER_NEAREST) + if (mapy.type() != CV_16UC1) + mapy.clone().convertTo(mapy, CV_16UC1); + + if (interpolation == INTER_NEAREST) + mapy = Mat(); + CV_Assert(((interpolation == INTER_NEAREST && !mapy.data) || mapy.type() == CV_16UC1 || + mapy.type() == CV_16SC1) && mapx.type() == CV_16SC2); +} + +const char* CV_Remap_Test::borderType_to_string() const +{ + if (borderType == BORDER_CONSTANT) + return "BORDER_CONSTANT"; + if (borderType == BORDER_REPLICATE) + return "BORDER_REPLICATE"; + if (borderType == BORDER_REFLECT) + return "BORDER_REFLECT"; + return "Unsupported/Unkown border type"; +} + +void CV_Remap_Test::prepare_test_data_for_reference_func() +{ + CV_ImageWarpBaseTest::prepare_test_data_for_reference_func(); + convert_maps(); +/* + const int ksize = 3; + Mat kernel = getStructuringElement(CV_MOP_ERODE, Size(ksize, ksize)); + Mat mask(src.size(), CV_8UC1, Scalar::all(255)), dst_mask; + cv::erode(src, erode_src, kernel); + cv::erode(mask, dst_mask, kernel, Point(-1, -1), 1, BORDER_CONSTANT, Scalar::all(0)); + bitwise_not(dst_mask, mask); + src.copyTo(erode_src, mask); + dst_mask.release(); + + mask = Scalar::all(0); + kernel = getStructuringElement(CV_MOP_DILATE, kernel.size()); + cv::dilate(src, dilate_src, kernel); + cv::dilate(mask, dst_mask, kernel, Point(-1, -1), 1, BORDER_CONSTANT, Scalar::all(255)); + src.copyTo(dilate_src, dst_mask); + dst_mask.release(); +*/ +} + +void CV_Remap_Test::run_reference_func() +{ + prepare_test_data_for_reference_func(); + + if (interpolation == INTER_AREA) + interpolation = INTER_LINEAR; + + int index = interpolation == INTER_NEAREST ? 0 : 1; + (this->*funcs[index])(src, reference_dst); +} + +void CV_Remap_Test::remap_nearest(const Mat& _src, Mat& _dst) +{ + CV_Assert(_src.depth() == CV_32F && _dst.type() == _src.type()); + CV_Assert(mapx.type() == CV_16SC2 && !mapy.data); + + Size ssize = _src.size(), dsize = _dst.size(); + CV_Assert(ssize.area() > 0 && dsize.area() > 0); + int cn = _src.channels(); + + for (int dy = 0; dy < dsize.height; ++dy) + { + const short* yM = mapx.ptr(dy); + float* yD = _dst.ptr(dy); + + for (int dx = 0; dx < dsize.width; ++dx) + { + float* xyD = yD + cn * dx; + int sx = yM[dx * 2], sy = yM[dx * 2 + 1]; + + if (sx >= 0 && sx < ssize.width && sy >= 0 && sy < ssize.height) + { + const float *xyS = _src.ptr(sy) + sx * cn; + + for (int r = 0; r < cn; ++r) + xyD[r] = xyS[r]; + } + else if (borderType != BORDER_TRANSPARENT) + { + if (borderType == BORDER_CONSTANT) + for (int r = 0; r < cn; ++r) + xyD[r] = saturate_cast(borderValue[r]); + else + { + sx = borderInterpolate(sx, ssize.width, borderType); + sy = borderInterpolate(sy, ssize.height, borderType); + CV_Assert(sx >= 0 && sy >= 0 && sx < ssize.width && sy < ssize.height); + + const float *xyS = _src.ptr(sy) + sx * cn; + + for (int r = 0; r < cn; ++r) + xyD[r] = xyS[r]; + } + } + } + } +} + +void CV_Remap_Test::remap_generic(const Mat& _src, Mat& _dst) +{ + CV_Assert(mapx.type() == CV_16SC2 && mapy.type() == CV_16UC1); + + int ksize = 2; + if (interpolation == INTER_CUBIC) + ksize = 4; + else if (interpolation == INTER_LANCZOS4) + ksize = 8; + else if (interpolation != INTER_LINEAR) + assert(0); + int ofs = (ksize / 2) - 1; + + CV_Assert(_src.depth() == CV_32F && _dst.type() == _src.type()); + Size ssize = _src.size(), dsize = _dst.size(); + int cn = _src.channels(), width1 = std::max(ssize.width - ksize + 1, 0), + height1 = std::max(ssize.height - ksize + 1, 0); + + float ix[8], w[16]; + internal::interpolate_method inter_func = internal::inter_array[interpolation - (interpolation == INTER_LANCZOS4 ? 2 : 1)]; + + for (int dy = 0; dy < dsize.height; ++dy) + { + const short* yMx = mapx.ptr(dy); + const ushort* yMy = mapy.ptr(dy); + + float* yD = _dst.ptr(dy); + + for (int dx = 0; dx < dsize.width; ++dx) + { + float* xyD = yD + dx * cn; + float sx = yMx[dx * 2], sy = yMx[dx * 2 + 1]; + int isx = cvFloor(sx), isy = cvFloor(sy); + + inter_func((yMy[dx] & (INTER_TAB_SIZE - 1)) / static_cast(INTER_TAB_SIZE), w); + inter_func(((yMy[dx] >> INTER_BITS) & (INTER_TAB_SIZE - 1)) / static_cast(INTER_TAB_SIZE), w + ksize); + + isx -= ofs; + isy -= ofs; + + if (isx >= 0 && isx < width1 && isy >= 0 && isy < height1) + { + for (int r = 0; r < cn; ++r) + { + for (int y = 0; y < ksize; ++y) + { + const float* xyS = _src.ptr(isy + y) + isx * cn; + + ix[y] = 0; + for (int i = 0; i < ksize; ++i) + ix[y] += w[i] * xyS[i * cn + r]; + } + xyD[r] = 0; + for (int i = 0; i < ksize; ++i) + xyD[r] += w[ksize + i] * ix[i]; + } + } + else if (borderType != BORDER_TRANSPARENT) + { + int ar_x[8], ar_y[8]; + + for (int k = 0; k < ksize; k++) + { + ar_x[k] = borderInterpolate(isx + k, ssize.width, borderType) * cn; + ar_y[k] = borderInterpolate(isy + k, ssize.height, borderType); + } + + for (int r = 0; r < cn; r++) + { + xyD[r] = 0; + for (int i = 0; i < ksize; ++i) + { + ix[i] = 0; + if (ar_y[i] >= 0) + { + const float* yS = _src.ptr(ar_y[i]); + for (int j = 0; j < ksize; ++j) + ix[i] += saturate_cast((ar_x[j] >= 0 ? yS[ar_x[j] + r] : borderValue[r]) * w[j]); + } + else + for (int j = 0; j < ksize; ++j) + ix[i] += saturate_cast(borderValue[r] * w[j]); + } + for (int i = 0; i < ksize; ++i) + xyD[r] += saturate_cast(w[ksize + i] * ix[i]); + } + } + } + } +} + +void CV_Remap_Test::validate_results() const +{ + CV_ImageWarpBaseTest::validate_results(); + if (cvtest::TS::ptr()->get_err_code() == cvtest::TS::FAIL_BAD_ACCURACY) + { + PRINT_TO_LOG("BorderType: %s\n", borderType_to_string()); + PRINT_TO_LOG("BorderValue: (%f, %f, %f, %f)\n", + borderValue[0], borderValue[1], borderValue[2], borderValue[3]); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// warpAffine +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_WarpAffine_Test : + public CV_Remap_Test +{ +public: + CV_WarpAffine_Test(); + + virtual ~CV_WarpAffine_Test(); + +protected: + virtual void generate_test_data(); + virtual void prepare_test_data_for_reference_func(); + + virtual void run_func(); + virtual void run_reference_func(); + + Mat M; +private: + void warpAffine(const Mat&, Mat&); +}; + +CV_WarpAffine_Test::CV_WarpAffine_Test() : + CV_Remap_Test() +{ +} + +CV_WarpAffine_Test::~CV_WarpAffine_Test() +{ +} + +void CV_WarpAffine_Test::generate_test_data() +{ + CV_Remap_Test::generate_test_data(); + + RNG& rng = ts->get_rng(); + + // generating the M 2x3 matrix + static const int depths[] = { CV_32FC1, CV_64FC1 }; + + // generating 2d matrix + M = getRotationMatrix2D(Point2f(src.cols / 2.f, src.rows / 2.f), + rng.uniform(-180.f, 180.f), rng.uniform(0.4f, 2.0f)); + int depth = depths[rng.uniform(0, sizeof(depths) / sizeof(depths[0]))]; + if (M.depth() != depth) + { + Mat tmp; + M.convertTo(tmp, depth); + M = tmp; + } + + // warp_matrix is inverse + if (rng.uniform(0., 1.) > 0) + interpolation |= CV_WARP_INVERSE_MAP; +} + +void CV_WarpAffine_Test::run_func() +{ + cv::warpAffine(src, dst, M, dst.size(), interpolation, borderType, borderValue); +} + +void CV_WarpAffine_Test::prepare_test_data_for_reference_func() +{ + CV_ImageWarpBaseTest::prepare_test_data_for_reference_func(); +} + +void CV_WarpAffine_Test::run_reference_func() +{ + prepare_test_data_for_reference_func(); + + warpAffine(src, reference_dst); +} + +void CV_WarpAffine_Test::warpAffine(const Mat& _src, Mat& _dst) +{ + Size dsize = _dst.size(); + + CV_Assert(_src.size().area() > 0); + CV_Assert(dsize.area() > 0); + CV_Assert(_src.type() == _dst.type()); + + Mat tM; + M.convertTo(tM, CV_64F); + + int inter = interpolation & INTER_MAX; + if (inter == INTER_AREA) + inter = INTER_LINEAR; + + mapx.create(dsize, CV_16SC2); + if (inter != INTER_NEAREST) + mapy.create(dsize, CV_16SC1); + else + mapy = Mat(); + + if (!(interpolation & CV_WARP_INVERSE_MAP)) + invertAffineTransform(tM.clone(), tM); + + const int AB_BITS = MAX(10, (int)INTER_BITS); + const int AB_SCALE = 1 << AB_BITS; + int round_delta = (inter == INTER_NEAREST) ? AB_SCALE / 2 : (AB_SCALE / INTER_TAB_SIZE / 2); + + const double* data_tM = tM.ptr(0); + for (int dy = 0; dy < dsize.height; ++dy) + { + short* yM = mapx.ptr(dy); + for (int dx = 0; dx < dsize.width; ++dx, yM += 2) + { + int v1 = saturate_cast(saturate_cast(data_tM[0] * dx * AB_SCALE) + + saturate_cast((data_tM[1] * dy + data_tM[2]) * AB_SCALE) + round_delta), + v2 = saturate_cast(saturate_cast(data_tM[3] * dx * AB_SCALE) + + saturate_cast((data_tM[4] * dy + data_tM[5]) * AB_SCALE) + round_delta); + v1 >>= AB_BITS - INTER_BITS; + v2 >>= AB_BITS - INTER_BITS; + + yM[0] = saturate_cast(v1 >> INTER_BITS); + yM[1] = saturate_cast(v2 >> INTER_BITS); + + if (inter != INTER_NEAREST) + mapy.ptr(dy)[dx] = ((v2 & (INTER_TAB_SIZE - 1)) * INTER_TAB_SIZE + (v1 & (INTER_TAB_SIZE - 1))); + } + } + + CV_Assert(mapx.type() == CV_16SC2 && ((inter == INTER_NEAREST && !mapy.data) || mapy.type() == CV_16SC1)); + cv::remap(_src, _dst, mapx, mapy, inter, borderType, borderValue); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// warpPerspective +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_WarpPerspective_Test : + public CV_WarpAffine_Test +{ +public: + CV_WarpPerspective_Test(); + + virtual ~CV_WarpPerspective_Test(); + +protected: + virtual void generate_test_data(); + + virtual void run_func(); + virtual void run_reference_func(); + +private: + void warpPerspective(const Mat&, Mat&); +}; + +CV_WarpPerspective_Test::CV_WarpPerspective_Test() : + CV_WarpAffine_Test() +{ +} + +CV_WarpPerspective_Test::~CV_WarpPerspective_Test() +{ +} + +void CV_WarpPerspective_Test::generate_test_data() +{ + CV_Remap_Test::generate_test_data(); + + // generating the M 3x3 matrix + RNG& rng = ts->get_rng(); + + float cols = static_cast(src.cols), rows = static_cast(src.rows); + Point2f sp[] = { Point2f(0.0f, 0.0f), Point2f(cols, 0.0f), Point2f(0.0f, rows), Point2f(cols, rows) }; + Point2f dp[] = { Point2f(rng.uniform(0.0f, cols), rng.uniform(0.0f, rows)), + Point2f(rng.uniform(0.0f, cols), rng.uniform(0.0f, rows)), + Point2f(rng.uniform(0.0f, cols), rng.uniform(0.0f, rows)), + Point2f(rng.uniform(0.0f, cols), rng.uniform(0.0f, rows)) }; + M = getPerspectiveTransform(sp, dp); + + static const int depths[] = { CV_32F, CV_64F }; + int depth = depths[rng.uniform(0, 2)]; + M.clone().convertTo(M, depth); +} + +void CV_WarpPerspective_Test::run_func() +{ + cv::warpPerspective(src, dst, M, dst.size(), interpolation, borderType, borderValue); +} + +void CV_WarpPerspective_Test::run_reference_func() +{ + prepare_test_data_for_reference_func(); + + warpPerspective(src, reference_dst); +} + +void CV_WarpPerspective_Test::warpPerspective(const Mat& _src, Mat& _dst) +{ + Size ssize = _src.size(), dsize = _dst.size(); + + CV_Assert(ssize.area() > 0); + CV_Assert(dsize.area() > 0); + CV_Assert(_src.type() == _dst.type()); + + if (M.depth() != CV_64F) + { + Mat tmp; + M.convertTo(tmp, CV_64F); + M = tmp; + } + + if (!(interpolation & CV_WARP_INVERSE_MAP)) + { + Mat tmp; + invert(M, tmp); + M = tmp; + } + + int inter = interpolation & INTER_MAX; + if (inter == INTER_AREA) + inter = INTER_LINEAR; + + mapx.create(dsize, CV_16SC2); + if (inter != INTER_NEAREST) + mapy.create(dsize, CV_16SC1); + else + mapy = Mat(); + + double* tM = M.ptr(0); + for (int dy = 0; dy < dsize.height; ++dy) + { + short* yMx = mapx.ptr(dy); + + for (int dx = 0; dx < dsize.width; ++dx, yMx += 2) + { + double den = tM[6] * dx + tM[7] * dy + tM[8]; + den = den ? 1.0 / den : 0.0; + + if (inter == INTER_NEAREST) + { + yMx[0] = saturate_cast((tM[0] * dx + tM[1] * dy + tM[2]) * den); + yMx[1] = saturate_cast((tM[3] * dx + tM[4] * dy + tM[5]) * den); + continue; + } + + den *= INTER_TAB_SIZE; + int v0 = saturate_cast((tM[0] * dx + tM[1] * dy + tM[2]) * den); + int v1 = saturate_cast((tM[3] * dx + tM[4] * dy + tM[5]) * den); + + yMx[0] = saturate_cast(v0 >> INTER_BITS); + yMx[1] = saturate_cast(v1 >> INTER_BITS); + mapy.ptr(dy)[dx] = saturate_cast((v1 & (INTER_TAB_SIZE - 1)) * + INTER_TAB_SIZE + (v0 & (INTER_TAB_SIZE - 1))); + } + } + + CV_Assert(mapx.type() == CV_16SC2 && ((inter == INTER_NEAREST && !mapy.data) || mapy.type() == CV_16SC1)); + cv::remap(_src, _dst, mapx, mapy, inter, borderType, borderValue); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST(Imgproc_Resize_Test, accuracy) { CV_Resize_Test test; test.safe_run(); } +TEST(Imgproc_Remap_Test, accuracy) { CV_Remap_Test test; test.safe_run(); } +TEST(Imgproc_WarpAffine_Test, accuracy) { CV_WarpAffine_Test test; test.safe_run(); } +TEST(Imgproc_WarpPerspective_Test, accuracy) { CV_WarpPerspective_Test test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_main.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_main.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,3 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("cv") diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_moments.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_moments.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_moments.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_moments.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,423 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +// image moments +class CV_MomentsTest : public cvtest::ArrayTest +{ +public: + CV_MomentsTest(); + +protected: + + enum { MOMENT_COUNT = 25 }; + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + int coi; + bool is_binary; +}; + + +CV_MomentsTest::CV_MomentsTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + coi = -1; + is_binary = false; + //element_wise_relative_error = false; +} + + +void CV_MomentsTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + int depth = CV_MAT_DEPTH(type); + + if( depth == CV_16U ) + { + low = Scalar::all(0); + high = Scalar::all(1000); + } + else if( depth == CV_16S ) + { + low = Scalar::all(-1000); + high = Scalar::all(1000); + } + else if( depth == CV_32F ) + { + low = Scalar::all(-1); + high = Scalar::all(1); + } +} + + +void CV_MomentsTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + int cn = cvtest::randInt(rng) % 4 + 1; + int depth = cvtest::randInt(rng) % 4; + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : depth == 2 ? CV_16S : CV_32F; + if( cn == 2 ) + cn = 1; + + types[INPUT][0] = CV_MAKETYPE(depth, cn); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1; + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(MOMENT_COUNT,1); + + is_binary = cvtest::randInt(rng) % 2 != 0; + coi = 0; + cvmat_allowed = true; + if( cn > 1 ) + { + coi = cvtest::randInt(rng) % cn; + cvmat_allowed = false; + } +} + + +double CV_MomentsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + int depth = test_mat[INPUT][0].depth(); + return depth != CV_32F ? FLT_EPSILON*10 : FLT_EPSILON*100; +} + +int CV_MomentsTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + int cn = test_mat[INPUT][0].channels(); + if( cn > 1 ) + cvSetImageCOI( (IplImage*)test_array[INPUT][0], coi + 1 ); + } + + return code; +} + + +void CV_MomentsTest::run_func() +{ + CvMoments* m = (CvMoments*)test_mat[OUTPUT][0].ptr(); + double* others = (double*)(m + 1); + cvMoments( test_array[INPUT][0], m, is_binary ); + others[0] = cvGetNormalizedCentralMoment( m, 2, 0 ); + others[1] = cvGetNormalizedCentralMoment( m, 1, 1 ); + others[2] = cvGetNormalizedCentralMoment( m, 0, 2 ); + others[3] = cvGetNormalizedCentralMoment( m, 3, 0 ); + others[4] = cvGetNormalizedCentralMoment( m, 2, 1 ); + others[5] = cvGetNormalizedCentralMoment( m, 1, 2 ); + others[6] = cvGetNormalizedCentralMoment( m, 0, 3 ); +} + + +void CV_MomentsTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + Mat& src = test_mat[INPUT][0]; + CvMoments m; + double* mdata = test_mat[REF_OUTPUT][0].ptr(); + int depth = src.depth(); + int cn = src.channels(); + int i, y, x, cols = src.cols; + double xc = 0., yc = 0.; + + memset( &m, 0, sizeof(m)); + + for( y = 0; y < src.rows; y++ ) + { + double s0 = 0, s1 = 0, s2 = 0, s3 = 0; + uchar* ptr = src.ptr(y); + for( x = 0; x < cols; x++ ) + { + double val; + if( depth == CV_8U ) + val = ptr[x*cn + coi]; + else if( depth == CV_16U ) + val = ((ushort*)ptr)[x*cn + coi]; + else if( depth == CV_16S ) + val = ((short*)ptr)[x*cn + coi]; + else + val = ((float*)ptr)[x*cn + coi]; + + if( is_binary ) + val = val != 0; + + s0 += val; + s1 += val*x; + s2 += val*x*x; + s3 += ((val*x)*x)*x; + } + + m.m00 += s0; + m.m01 += s0*y; + m.m02 += (s0*y)*y; + m.m03 += ((s0*y)*y)*y; + + m.m10 += s1; + m.m11 += s1*y; + m.m12 += (s1*y)*y; + + m.m20 += s2; + m.m21 += s2*y; + + m.m30 += s3; + } + + if( m.m00 != 0 ) + { + xc = m.m10/m.m00, yc = m.m01/m.m00; + m.inv_sqrt_m00 = 1./sqrt(fabs(m.m00)); + } + + for( y = 0; y < src.rows; y++ ) + { + double s0 = 0, s1 = 0, s2 = 0, s3 = 0, y1 = y - yc; + uchar* ptr = src.ptr(y); + for( x = 0; x < cols; x++ ) + { + double val, x1 = x - xc; + if( depth == CV_8U ) + val = ptr[x*cn + coi]; + else if( depth == CV_16U ) + val = ((ushort*)ptr)[x*cn + coi]; + else if( depth == CV_16S ) + val = ((short*)ptr)[x*cn + coi]; + else + val = ((float*)ptr)[x*cn + coi]; + + if( is_binary ) + val = val != 0; + + s0 += val; + s1 += val*x1; + s2 += val*x1*x1; + s3 += ((val*x1)*x1)*x1; + } + + m.mu02 += s0*y1*y1; + m.mu03 += ((s0*y1)*y1)*y1; + + m.mu11 += s1*y1; + m.mu12 += (s1*y1)*y1; + + m.mu20 += s2; + m.mu21 += s2*y1; + + m.mu30 += s3; + } + + memcpy( mdata, &m, sizeof(m)); + mdata += sizeof(m)/sizeof(m.m00); + + /* calc normalized moments */ + { + double inv_m00 = m.inv_sqrt_m00*m.inv_sqrt_m00; + double s2 = inv_m00*inv_m00; /* 1./(m00 ^ (2/2 + 1)) */ + double s3 = s2*m.inv_sqrt_m00; /* 1./(m00 ^ (3/2 + 1)) */ + + mdata[0] = m.mu20 * s2; + mdata[1] = m.mu11 * s2; + mdata[2] = m.mu02 * s2; + + mdata[3] = m.mu30 * s3; + mdata[4] = m.mu21 * s3; + mdata[5] = m.mu12 * s3; + mdata[6] = m.mu03 * s3; + } + + double* a = test_mat[REF_OUTPUT][0].ptr(); + double* b = test_mat[OUTPUT][0].ptr(); + for( i = 0; i < MOMENT_COUNT; i++ ) + { + if( fabs(a[i]) < 1e-3 ) + a[i] = 0; + if( fabs(b[i]) < 1e-3 ) + b[i] = 0; + } +} + + +// Hu invariants +class CV_HuMomentsTest : public cvtest::ArrayTest +{ +public: + CV_HuMomentsTest(); + +protected: + + enum { MOMENT_COUNT = 18, HU_MOMENT_COUNT = 7 }; + + int prepare_test_case( int test_case_idx ); + void prepare_to_validation( int /*test_case_idx*/ ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); +}; + + +CV_HuMomentsTest::CV_HuMomentsTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); +} + + +void CV_HuMomentsTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + low = Scalar::all(-10000); + high = Scalar::all(10000); +} + + +void CV_HuMomentsTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1; + sizes[INPUT][0] = cvSize(MOMENT_COUNT,1); + sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(HU_MOMENT_COUNT,1); +} + + +double CV_HuMomentsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return FLT_EPSILON; +} + + + +int CV_HuMomentsTest::prepare_test_case( int test_case_idx ) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + if( code > 0 ) + { + // ... + } + + return code; +} + + +void CV_HuMomentsTest::run_func() +{ + cvGetHuMoments( (CvMoments*)test_mat[INPUT][0].data, + (CvHuMoments*)test_mat[OUTPUT][0].data ); +} + + +void CV_HuMomentsTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + CvMoments* m = (CvMoments*)test_mat[INPUT][0].data; + CvHuMoments* hu = (CvHuMoments*)test_mat[REF_OUTPUT][0].data; + + double inv_m00 = m->inv_sqrt_m00*m->inv_sqrt_m00; + double s2 = inv_m00*inv_m00; /* 1./(m00 ^ (2/2 + 1)) */ + double s3 = s2*m->inv_sqrt_m00; /* 1./(m00 ^ (3/2 + 1)) */ + + double nu20 = m->mu20 * s2; + double nu11 = m->mu11 * s2; + double nu02 = m->mu02 * s2; + + double nu30 = m->mu30 * s3; + double nu21 = m->mu21 * s3; + double nu12 = m->mu12 * s3; + double nu03 = m->mu03 * s3; + + #undef sqr + #define sqr(a) ((a)*(a)) + + hu->hu1 = nu20 + nu02; + hu->hu2 = sqr(nu20 - nu02) + 4*sqr(nu11); + hu->hu3 = sqr(nu30 - 3*nu12) + sqr(3*nu21 - nu03); + hu->hu4 = sqr(nu30 + nu12) + sqr(nu21 + nu03); + hu->hu5 = (nu30 - 3*nu12)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) + + (3*nu21 - nu03)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03)); + hu->hu6 = (nu20 - nu02)*(sqr(nu30 + nu12) - sqr(nu21 + nu03)) + + 4*nu11*(nu30 + nu12)*(nu21 + nu03); + hu->hu7 = (3*nu21 - nu03)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) + + (3*nu12 - nu30)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03)); +} + + +TEST(Imgproc_Moments, accuracy) { CV_MomentsTest test; test.safe_run(); } +TEST(Imgproc_HuMoments, accuracy) { CV_HuMomentsTest test; test.safe_run(); } + +class CV_SmallContourMomentTest : public cvtest::BaseTest +{ +public: + CV_SmallContourMomentTest() {} + ~CV_SmallContourMomentTest() {} +protected: + void run(int) + { + try + { + vector points; + points.push_back(Point(50, 56)); + points.push_back(Point(53, 53)); + points.push_back(Point(46, 54)); + points.push_back(Point(49, 51)); + + Moments m = moments(points, false); + double area = contourArea(points); + + CV_Assert( m.m00 == 0 && m.m01 == 0 && m.m10 == 0 && area == 0 ); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + } + } +}; + +TEST(Imgproc_ContourMoment, small) { CV_SmallContourMomentTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_pc.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_pc.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_pc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_pc.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,89 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +namespace cvtest +{ + +/// phase correlation +class CV_PhaseCorrelatorTest : public cvtest::ArrayTest +{ +public: + CV_PhaseCorrelatorTest(); +protected: + void run( int ); +}; + +CV_PhaseCorrelatorTest::CV_PhaseCorrelatorTest() {} + +void CV_PhaseCorrelatorTest::run( int ) +{ + ts->set_failed_test_info(cvtest::TS::OK); + + Mat r1 = Mat::ones(Size(129, 128), CV_64F); + Mat r2 = Mat::ones(Size(129, 128), CV_64F); + + double expectedShiftX = -10.0; + double expectedShiftY = -20.0; + + // draw 10x10 rectangles @ (100, 100) and (90, 80) should see ~(-10, -20) shift here... + cv::rectangle(r1, Point(100, 100), Point(110, 110), Scalar(0, 0, 0), CV_FILLED); + cv::rectangle(r2, Point(90, 80), Point(100, 90), Scalar(0, 0, 0), CV_FILLED); + + Mat hann; + createHanningWindow(hann, r1.size(), CV_64F); + Point2d phaseShift = phaseCorrelate(r1, r2, hann); + + // test accuracy should be less than 1 pixel... + if((expectedShiftX - phaseShift.x) >= 1 || (expectedShiftY - phaseShift.y) >= 1) + { + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + } +} + +TEST(Imgproc_PhaseCorrelatorTest, accuracy) { CV_PhaseCorrelatorTest test; test.safe_run(); } + +} diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_precomp.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_precomp.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_precomp.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_precomp.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1 @@ +#include "test_precomp.hpp" diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_precomp.hpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_precomp.hpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_precomp.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_precomp.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,19 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/highgui/highgui_c.h" +#include + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_templmatch.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_templmatch.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_templmatch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_templmatch.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,336 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_TemplMatchTest : public cvtest::ArrayTest +{ +public: + CV_TemplMatchTest(); + +protected: + int read_params( CvFileStorage* fs ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int ); + + int max_template_size; + int method; + bool test_cpp; +}; + + +CV_TemplMatchTest::CV_TemplMatchTest() +{ + test_array[INPUT].push_back(NULL); + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + element_wise_relative_error = false; + max_template_size = 100; + method = 0; + test_cpp = false; +} + + +int CV_TemplMatchTest::read_params( CvFileStorage* fs ) +{ + int code = cvtest::ArrayTest::read_params( fs ); + if( code < 0 ) + return code; + + max_template_size = cvReadInt( find_param( fs, "max_template_size" ), max_template_size ); + max_template_size = cvtest::clipInt( max_template_size, 1, 100 ); + + return code; +} + + +void CV_TemplMatchTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high ) +{ + cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high ); + int depth = CV_MAT_DEPTH(type); + if( depth == CV_32F ) + { + low = Scalar::all(-10.); + high = Scalar::all(10.); + } +} + + +void CV_TemplMatchTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % 2, cn = cvtest::randInt(rng) & 1 ? 3 : 1; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + depth = depth == 0 ? CV_8U : CV_32F; + + types[INPUT][0] = types[INPUT][1] = CV_MAKETYPE(depth,cn); + types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_32FC1; + + sizes[INPUT][1].width = cvtest::randInt(rng)%MIN(sizes[INPUT][1].width,max_template_size) + 1; + sizes[INPUT][1].height = cvtest::randInt(rng)%MIN(sizes[INPUT][1].height,max_template_size) + 1; + sizes[OUTPUT][0].width = sizes[INPUT][0].width - sizes[INPUT][1].width + 1; + sizes[OUTPUT][0].height = sizes[INPUT][0].height - sizes[INPUT][1].height + 1; + sizes[REF_OUTPUT][0] = sizes[OUTPUT][0]; + + method = cvtest::randInt(rng)%6; + test_cpp = (cvtest::randInt(rng) & 256) == 0; +} + + +double CV_TemplMatchTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + if( test_mat[INPUT][1].depth() == CV_8U || + (method >= CV_TM_CCOEFF && test_mat[INPUT][1].cols*test_mat[INPUT][1].rows <= 2) ) + return 1e-2; + else + return 1e-3; +} + + +void CV_TemplMatchTest::run_func() +{ + if(!test_cpp) + cvMatchTemplate( test_array[INPUT][0], test_array[INPUT][1], test_array[OUTPUT][0], method ); + else + { + cv::Mat _out = cv::cvarrToMat(test_array[OUTPUT][0]); + cv::matchTemplate(cv::cvarrToMat(test_array[INPUT][0]), cv::cvarrToMat(test_array[INPUT][1]), _out, method); + } +} + + +static void cvTsMatchTemplate( const CvMat* img, const CvMat* templ, CvMat* result, int method ) +{ + int i, j, k, l; + int depth = CV_MAT_DEPTH(img->type), cn = CV_MAT_CN(img->type); + int width_n = templ->cols*cn, height = templ->rows; + int a_step = img->step / CV_ELEM_SIZE(img->type & CV_MAT_DEPTH_MASK); + int b_step = templ->step / CV_ELEM_SIZE(templ->type & CV_MAT_DEPTH_MASK); + CvScalar b_mean, b_sdv; + double b_denom = 1., b_sum2 = 0; + int area = templ->rows*templ->cols; + + cvAvgSdv(templ, &b_mean, &b_sdv); + + for( i = 0; i < cn; i++ ) + b_sum2 += (b_sdv.val[i]*b_sdv.val[i] + b_mean.val[i]*b_mean.val[i])*area; + + if( b_sdv.val[0]*b_sdv.val[0] + b_sdv.val[1]*b_sdv.val[1] + + b_sdv.val[2]*b_sdv.val[2] + b_sdv.val[3]*b_sdv.val[3] < DBL_EPSILON && + method == CV_TM_CCOEFF_NORMED ) + { + cvSet( result, cvScalarAll(1.) ); + return; + } + + if( method & 1 ) + { + b_denom = 0; + if( method != CV_TM_CCOEFF_NORMED ) + { + b_denom = b_sum2; + } + else + { + for( i = 0; i < cn; i++ ) + b_denom += b_sdv.val[i]*b_sdv.val[i]*area; + } + b_denom = sqrt(b_denom); + if( b_denom == 0 ) + b_denom = 1.; + } + + assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED ); + + for( i = 0; i < result->rows; i++ ) + { + for( j = 0; j < result->cols; j++ ) + { + CvScalar a_sum = {{ 0, 0, 0, 0 }}, a_sum2 = {{ 0, 0, 0, 0 }}; + CvScalar ccorr = {{ 0, 0, 0, 0 }}; + double value = 0.; + + if( depth == CV_8U ) + { + const uchar* a = img->data.ptr + i*img->step + j*cn; + const uchar* b = templ->data.ptr; + + if( cn == 1 || method < CV_TM_CCOEFF ) + { + for( k = 0; k < height; k++, a += a_step, b += b_step ) + for( l = 0; l < width_n; l++ ) + { + ccorr.val[0] += a[l]*b[l]; + a_sum.val[0] += a[l]; + a_sum2.val[0] += a[l]*a[l]; + } + } + else + { + for( k = 0; k < height; k++, a += a_step, b += b_step ) + for( l = 0; l < width_n; l += 3 ) + { + ccorr.val[0] += a[l]*b[l]; + ccorr.val[1] += a[l+1]*b[l+1]; + ccorr.val[2] += a[l+2]*b[l+2]; + a_sum.val[0] += a[l]; + a_sum.val[1] += a[l+1]; + a_sum.val[2] += a[l+2]; + a_sum2.val[0] += a[l]*a[l]; + a_sum2.val[1] += a[l+1]*a[l+1]; + a_sum2.val[2] += a[l+2]*a[l+2]; + } + } + } + else + { + const float* a = (const float*)(img->data.ptr + i*img->step) + j*cn; + const float* b = (const float*)templ->data.ptr; + + if( cn == 1 || method < CV_TM_CCOEFF ) + { + for( k = 0; k < height; k++, a += a_step, b += b_step ) + for( l = 0; l < width_n; l++ ) + { + ccorr.val[0] += a[l]*b[l]; + a_sum.val[0] += a[l]; + a_sum2.val[0] += a[l]*a[l]; + } + } + else + { + for( k = 0; k < height; k++, a += a_step, b += b_step ) + for( l = 0; l < width_n; l += 3 ) + { + ccorr.val[0] += a[l]*b[l]; + ccorr.val[1] += a[l+1]*b[l+1]; + ccorr.val[2] += a[l+2]*b[l+2]; + a_sum.val[0] += a[l]; + a_sum.val[1] += a[l+1]; + a_sum.val[2] += a[l+2]; + a_sum2.val[0] += a[l]*a[l]; + a_sum2.val[1] += a[l+1]*a[l+1]; + a_sum2.val[2] += a[l+2]*a[l+2]; + } + } + } + + switch( method ) + { + case CV_TM_CCORR: + case CV_TM_CCORR_NORMED: + value = ccorr.val[0]; + break; + case CV_TM_SQDIFF: + case CV_TM_SQDIFF_NORMED: + value = (a_sum2.val[0] + b_sum2 - 2*ccorr.val[0]); + break; + default: + value = (ccorr.val[0] - a_sum.val[0]*b_mean.val[0]+ + ccorr.val[1] - a_sum.val[1]*b_mean.val[1]+ + ccorr.val[2] - a_sum.val[2]*b_mean.val[2]); + } + + if( method & 1 ) + { + double denom; + + // calc denominator + if( method != CV_TM_CCOEFF_NORMED ) + { + denom = a_sum2.val[0] + a_sum2.val[1] + a_sum2.val[2]; + } + else + { + denom = a_sum2.val[0] - (a_sum.val[0]*a_sum.val[0])/area; + denom += a_sum2.val[1] - (a_sum.val[1]*a_sum.val[1])/area; + denom += a_sum2.val[2] - (a_sum.val[2]*a_sum.val[2])/area; + } + denom = sqrt(MAX(denom,0))*b_denom; + if( fabs(value) < denom ) + value /= denom; + else if( fabs(value) < denom*1.125 ) + value = value > 0 ? 1 : -1; + else + value = method != CV_TM_SQDIFF_NORMED ? 0 : 1; + } + + ((float*)(result->data.ptr + result->step*i))[j] = (float)value; + } + } +} + + +void CV_TemplMatchTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + CvMat _input = test_mat[INPUT][0], _templ = test_mat[INPUT][1]; + CvMat _output = test_mat[REF_OUTPUT][0]; + cvTsMatchTemplate( &_input, &_templ, &_output, method ); + + //if( ts->get_current_test_info()->test_case_idx == 0 ) + /*{ + CvFileStorage* fs = cvOpenFileStorage( "_match_template.yml", 0, CV_STORAGE_WRITE ); + cvWrite( fs, "image", &test_mat[INPUT][0] ); + cvWrite( fs, "template", &test_mat[INPUT][1] ); + cvWrite( fs, "ref", &test_mat[REF_OUTPUT][0] ); + cvWrite( fs, "opencv", &test_mat[OUTPUT][0] ); + cvWriteInt( fs, "method", method ); + cvReleaseFileStorage( &fs ); + }*/ + + if( method >= CV_TM_CCOEFF ) + { + // avoid numerical stability problems in singular cases (when the results are near to 0) + const double delta = 10.; + test_mat[REF_OUTPUT][0] += Scalar::all(delta); + test_mat[OUTPUT][0] += Scalar::all(delta); + } +} + +TEST(Imgproc_MatchTemplate, accuracy) { CV_TemplMatchTest test; test.safe_run(); } diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_thresh.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_thresh.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_thresh.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_thresh.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,321 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_ThreshTest : public cvtest::ArrayTest +{ +public: + CV_ThreshTest(); + +protected: + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + void prepare_to_validation( int ); + + int thresh_type; + float thresh_val; + float max_val; +}; + + +CV_ThreshTest::CV_ThreshTest() +{ + test_array[INPUT].push_back(NULL); + test_array[OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + optional_mask = false; + element_wise_relative_error = true; +} + + +void CV_ThreshTest::get_test_array_types_and_sizes( int test_case_idx, + vector >& sizes, vector >& types ) +{ + RNG& rng = ts->get_rng(); + int depth = cvtest::randInt(rng) % 3, cn = cvtest::randInt(rng) % 4 + 1; + cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); + depth = depth == 0 ? CV_8U : depth == 1 ? CV_16S : CV_32F; + + types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn); + thresh_type = cvtest::randInt(rng) % 5; + + if( depth == CV_8U ) + { + thresh_val = (float)(cvtest::randReal(rng)*350. - 50.); + max_val = (float)(cvtest::randReal(rng)*350. - 50.); + if( cvtest::randInt(rng)%4 == 0 ) + max_val = 255.f; + } + else if( depth == CV_16S ) + { + float min_val = SHRT_MIN-100.f; + max_val = SHRT_MAX+100.f; + thresh_val = (float)(cvtest::randReal(rng)*(max_val - min_val) + min_val); + max_val = (float)(cvtest::randReal(rng)*(max_val - min_val) + min_val); + if( cvtest::randInt(rng)%4 == 0 ) + max_val = (float)SHRT_MAX; + } + else + { + thresh_val = (float)(cvtest::randReal(rng)*1000. - 500.); + max_val = (float)(cvtest::randReal(rng)*1000. - 500.); + } +} + + +double CV_ThreshTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return FLT_EPSILON*10; +} + + +void CV_ThreshTest::run_func() +{ + cvThreshold( test_array[INPUT][0], test_array[OUTPUT][0], + thresh_val, max_val, thresh_type ); +} + + +static void test_threshold( const Mat& _src, Mat& _dst, + float thresh, float maxval, int thresh_type ) +{ + int i, j; + int depth = _src.depth(), cn = _src.channels(); + int width_n = _src.cols*cn, height = _src.rows; + int ithresh = cvFloor(thresh); + int imaxval, ithresh2; + + if( depth == CV_8U ) + { + ithresh2 = saturate_cast(ithresh); + imaxval = saturate_cast(maxval); + } + else if( depth == CV_16S ) + { + ithresh2 = saturate_cast(ithresh); + imaxval = saturate_cast(maxval); + } + else + { + ithresh2 = cvRound(ithresh); + imaxval = cvRound(maxval); + } + + assert( depth == CV_8U || depth == CV_16S || depth == CV_32F ); + + switch( thresh_type ) + { + case CV_THRESH_BINARY: + for( i = 0; i < height; i++ ) + { + if( depth == CV_8U ) + { + const uchar* src = _src.ptr(i); + uchar* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = (uchar)(src[j] > ithresh ? imaxval : 0); + } + else if( depth == CV_16S ) + { + const short* src = _src.ptr(i); + short* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = (short)(src[j] > ithresh ? imaxval : 0); + } + else + { + const float* src = _src.ptr(i); + float* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = src[j] > thresh ? maxval : 0.f; + } + } + break; + case CV_THRESH_BINARY_INV: + for( i = 0; i < height; i++ ) + { + if( depth == CV_8U ) + { + const uchar* src = _src.ptr(i); + uchar* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = (uchar)(src[j] > ithresh ? 0 : imaxval); + } + else if( depth == CV_16S ) + { + const short* src = _src.ptr(i); + short* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = (short)(src[j] > ithresh ? 0 : imaxval); + } + else + { + const float* src = _src.ptr(i); + float* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + dst[j] = src[j] > thresh ? 0.f : maxval; + } + } + break; + case CV_THRESH_TRUNC: + for( i = 0; i < height; i++ ) + { + if( depth == CV_8U ) + { + const uchar* src = _src.ptr(i); + uchar* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (uchar)(s > ithresh ? ithresh2 : s); + } + } + else if( depth == CV_16S ) + { + const short* src = _src.ptr(i); + short* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (short)(s > ithresh ? ithresh2 : s); + } + } + else + { + const float* src = _src.ptr(i); + float* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + float s = src[j]; + dst[j] = s > thresh ? thresh : s; + } + } + } + break; + case CV_THRESH_TOZERO: + for( i = 0; i < height; i++ ) + { + if( depth == CV_8U ) + { + const uchar* src = _src.ptr(i); + uchar* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (uchar)(s > ithresh ? s : 0); + } + } + else if( depth == CV_16S ) + { + const short* src = _src.ptr(i); + short* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (short)(s > ithresh ? s : 0); + } + } + else + { + const float* src = _src.ptr(i); + float* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + float s = src[j]; + dst[j] = s > thresh ? s : 0.f; + } + } + } + break; + case CV_THRESH_TOZERO_INV: + for( i = 0; i < height; i++ ) + { + if( depth == CV_8U ) + { + const uchar* src = _src.ptr(i); + uchar* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (uchar)(s > ithresh ? 0 : s); + } + } + else if( depth == CV_16S ) + { + const short* src = _src.ptr(i); + short* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + int s = src[j]; + dst[j] = (short)(s > ithresh ? 0 : s); + } + } + else + { + const float* src = _src.ptr(i); + float* dst = _dst.ptr(i); + for( j = 0; j < width_n; j++ ) + { + float s = src[j]; + dst[j] = s > thresh ? 0.f : s; + } + } + } + break; + default: + assert(0); + } +} + + +void CV_ThreshTest::prepare_to_validation( int /*test_case_idx*/ ) +{ + test_threshold( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], + thresh_val, max_val, thresh_type ); +} + +TEST(Imgproc_Threshold, accuracy) { CV_ThreshTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_watershed.cpp diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_watershed.cpp --- diffimg-1.5.0/3rdparty/opencv/imgproc/test/test_watershed.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/imgproc/test/test_watershed.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,133 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include + +using namespace cv; +using namespace std; + +class CV_WatershedTest : public cvtest::BaseTest +{ +public: + CV_WatershedTest(); + ~CV_WatershedTest(); +protected: + void run(int); +}; + +CV_WatershedTest::CV_WatershedTest() {} +CV_WatershedTest::~CV_WatershedTest() {} + +void CV_WatershedTest::run( int /* start_from */) +{ + string exp_path = string(ts->get_data_path()) + "watershed/wshed_exp.png"; + Mat exp = imread(exp_path, 0); + Mat orig = imread(string(ts->get_data_path()) + "inpaint/orig.png"); + FileStorage fs(string(ts->get_data_path()) + "watershed/comp.xml", FileStorage::READ); + + if (orig.empty() || !fs.isOpened()) + { + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); + return; + } + + CvSeq* cnts = (CvSeq*)fs["contours"].readObj(); + + Mat markers(orig.size(), CV_32SC1); + markers = Scalar(0); + IplImage iplmrks = markers; + + vector colors(1); + for(int i = 0; cnts != 0; cnts = cnts->h_next, ++i ) + { + cvDrawContours( &iplmrks, cnts, Scalar::all(i + 1), Scalar::all(i + 1), -1, CV_FILLED); + Point* p = (Point*)cvGetSeqElem(cnts, 0); + + //expected image was added with 1 in order to save to png + //so now we substract 1 to get real color + if(exp.data) + colors.push_back(exp.ptr(p->y)[p->x] - 1); + } + fs.release(); + const int compNum = (int)(colors.size() - 1); + + watershed(orig, markers); + + for(int j = 0; j < markers.rows; ++j) + { + int* line = markers.ptr(j); + for(int i = 0; i < markers.cols; ++i) + { + int& pixel = line[i]; + + if (pixel == -1) // border + continue; + + if (pixel <= 0 || pixel > compNum) + continue; // bad result, doing nothing and going to get error latter; + + // repaint in saved color to compare with expected; + if(exp.data) + pixel = colors[pixel]; + } + } + + Mat markers8U; + markers.convertTo(markers8U, CV_8U, 1, 1); + + if( exp.empty() || orig.size() != exp.size() ) + { + imwrite(exp_path, markers8U); + exp = markers8U; + } + + if (0 != norm(markers8U, exp, NORM_INF)) + { + ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); + return; + } + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Imgproc_Watershed, regression) { CV_WatershedTest test; test.safe_run(); } + diff -Nru diffimg-1.5.0/3rdparty/opencv/include/CMakeLists.txt diffimg-2.0.0/3rdparty/opencv/include/CMakeLists.txt --- diffimg-1.5.0/3rdparty/opencv/include/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/CMakeLists.txt 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,9 @@ +file(GLOB old_hdrs "opencv/*.h*") +install(FILES ${old_hdrs} + DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv + COMPONENT main) +install(FILES "opencv2/opencv.hpp" + DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2 + COMPONENT main) + + diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cv.h diffimg-2.0.0/3rdparty/opencv/include/opencv/cv.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cv.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cv.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,83 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_CV_H__ +#define __OPENCV_OLD_CV_H__ + +#if defined(_MSC_VER) + #define CV_DO_PRAGMA(x) __pragma(x) + #define __CVSTR2__(x) #x + #define __CVSTR1__(x) __CVSTR2__(x) + #define __CVMSVCLOC__ __FILE__ "("__CVSTR1__(__LINE__)") : " + #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (__CVMSVCLOC__ _msg)) +#elif defined(__GNUC__) + #define CV_DO_PRAGMA(x) _Pragma (#x) + #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (_msg)) +#else + #define CV_DO_PRAGMA(x) + #define CV_MSG_PRAGMA(_msg) +#endif +#define CV_WARNING(x) CV_MSG_PRAGMA("Warning: " #x) + +//CV_WARNING("This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module") + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/video/tracking.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "opencv2/flann/flann.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/legacy/compat.hpp" + +#if !defined(CV_IMPL) +#define CV_IMPL extern "C" +#endif //CV_IMPL + +#if defined(__cplusplus) +#include "opencv2/core/internal.hpp" +#endif //__cplusplus + +#endif // __OPENCV_OLD_CV_H_ + diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cv.hpp diffimg-2.0.0/3rdparty/opencv/include/opencv/cv.hpp --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cv.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cv.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,52 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_CV_HPP__ +#define __OPENCV_OLD_CV_HPP__ + +//#if defined(__GNUC__) +//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" +//#endif + +#include + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cvaux.h diffimg-2.0.0/3rdparty/opencv/include/opencv/cvaux.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cvaux.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cvaux.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,65 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_AUX_H__ +#define __OPENCV_OLD_AUX_H__ + +//#if defined(__GNUC__) +//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" +//#endif + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/video/tracking.hpp" +#include "opencv2/video/background_segm.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/legacy/legacy.hpp" +#include "opencv2/legacy/compat.hpp" +#include "opencv2/legacy/blobtrack.hpp" +#include "opencv2/contrib/contrib.hpp" + +#endif + +/* End of file. */ diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cvaux.hpp diffimg-2.0.0/3rdparty/opencv/include/opencv/cvaux.hpp --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cvaux.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cvaux.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,51 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_AUX_HPP__ +#define __OPENCV_OLD_AUX_HPP__ + +//#if defined(__GNUC__) +//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" +//#endif + +#include + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cvwimage.h diffimg-2.0.0/3rdparty/opencv/include/opencv/cvwimage.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cvwimage.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cvwimage.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to +// this license. If you do not agree to this license, do not download, +// install, copy or use the software. +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2008, Google, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation or contributors may not be used to endorse +// or promote products derived from this software without specific +// prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" +// and any express or implied warranties, including, but not limited to, the +// implied warranties of merchantability and fitness for a particular purpose +// are disclaimed. In no event shall the Intel Corporation or contributors be +// liable for any direct, indirect, incidental, special, exemplary, or +// consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. + + +#ifndef __OPENCV_OLD_WIMAGE_HPP__ +#define __OPENCV_OLD_WIMAGE_HPP__ + +#include "opencv2/core/wimage.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cxcore.h diffimg-2.0.0/3rdparty/opencv/include/opencv/cxcore.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cxcore.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cxcore.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,53 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_CXCORE_H__ +#define __OPENCV_OLD_CXCORE_H__ + +//#if defined(__GNUC__) +//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" +//#endif + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cxcore.hpp diffimg-2.0.0/3rdparty/opencv/include/opencv/cxcore.hpp --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cxcore.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cxcore.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,52 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_CXCORE_HPP__ +#define __OPENCV_OLD_CXCORE_HPP__ + +//#if defined(__GNUC__) +//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" +//#endif + +#include + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cxeigen.hpp diffimg-2.0.0/3rdparty/opencv/include/opencv/cxeigen.hpp --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cxeigen.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cxeigen.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,49 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_EIGEN_HPP__ +#define __OPENCV_OLD_EIGEN_HPP__ + +#include "opencv2/core/eigen.hpp" + +#endif + diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/cxmisc.h diffimg-2.0.0/3rdparty/opencv/include/opencv/cxmisc.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/cxmisc.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/cxmisc.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,6 @@ +#ifndef __OPENCV_OLD_CXMISC_H__ +#define __OPENCV_OLD_CXMISC_H__ + +#include "opencv2/core/internal.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/highgui.h diffimg-2.0.0/3rdparty/opencv/include/opencv/highgui.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/highgui.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/highgui.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,50 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_HIGHGUI_H__ +#define __OPENCV_OLD_HIGHGUI_H__ + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/highgui/highgui_c.h" +#include "opencv2/highgui/highgui.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv/ml.h diffimg-2.0.0/3rdparty/opencv/include/opencv/ml.h --- diffimg-1.5.0/3rdparty/opencv/include/opencv/ml.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv/ml.h 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_OLD_ML_H__ +#define __OPENCV_OLD_ML_H__ + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/ml/ml.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/include/opencv2/opencv.hpp diffimg-2.0.0/3rdparty/opencv/include/opencv2/opencv.hpp --- diffimg-1.5.0/3rdparty/opencv/include/opencv2/opencv.hpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/include/opencv2/opencv.hpp 2013-04-05 09:00:20.000000000 +0000 @@ -0,0 +1,61 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_ALL_HPP__ +#define __OPENCV_ALL_HPP__ + +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/flann/miniflann.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/photo/photo.hpp" +#include "opencv2/video/video.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/ml/ml.hpp" +#include "opencv2/highgui/highgui_c.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/contrib/contrib.hpp" + +#endif diff -Nru diffimg-1.5.0/3rdparty/opencv/opencv.pro diffimg-2.0.0/3rdparty/opencv/opencv.pro --- diffimg-1.5.0/3rdparty/opencv/opencv.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/opencv/opencv.pro 2013-05-05 16:55:20.000000000 +0000 @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +CONFIG += warn_on debug_and_release +SUBDIRS += core imgproc highgui 3rdparty + + diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/CMakeLists.txt diffimg-2.0.0/3rdparty/perceptualdiff/CMakeLists.txt --- diffimg-1.5.0/3rdparty/perceptualdiff/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/CMakeLists.txt 2013-05-15 20:37:18.000000000 +0000 @@ -0,0 +1,16 @@ +PROJECT (PerceptualDiff) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4) + +SET(DIFF_SRC LPyramid.cpp RGBAImage.cpp CompareArgs.cpp Metric.cpp OpenCVImageLoader.cpp) + +ADD_LIBRARY(PerceptualDiff STATIC ${DIFF_SRC} ${}) + +IF (MSVC) +# Turn off deprecation warnings +ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) +ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS) +ENDIF(MSVC) + + + diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/CompareArgs.cpp diffimg-2.0.0/3rdparty/perceptualdiff/CompareArgs.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/CompareArgs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/CompareArgs.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,209 @@ + +/* + Comapre Args + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "CompareArgs.h" +#include "RGBAImage.h" +#ifdef FREEIMAGE_LOADER +#include "FreeImageLoader.h" +#endif +#include "RGBAImage.h" +#include +#include +#include + +static const char* copyright = + "PerceptualDiff version 1.1.1, Copyright (C) 2006 Yangli Hector Yee\n\ +PerceptualDiff comes with ABSOLUTELY NO WARRANTY;\n\ +This is free software, and you are welcome\n\ +to redistribute it under certain conditions;\n\ +See the GPL page for details: http://www.gnu.org/copyleft/gpl.html\n\n"; + +static const char *usage = + "PeceptualDiff image1.tif image2.tif\n\n\ + Compares image1.tif and image2.tif using a perceptually based image metric\n\ + Options:\n\ +\t-verbose : Turns on verbose mode\n\ +\t-fov deg : Field of view in degrees (0.1 to 89.9)\n\ +\t-threshold p : #pixels p below which differences are ignored\n\ +\t-gamma g : Value to convert rgb into linear space (default 2.2)\n\ +\t-luminance l : White luminance (default 100.0 cdm^-2)\n\ +\t-luminanceonly : Only consider luminance; ignore chroma (color) in the comparison\n\ +\t-colorfactor : How much of color to use, 0.0 to 1.0, 0.0 = ignore color.\n\ +\t-downsample : How many powers of two to down sample the image.\n\ +\t-output o.ppm : Write difference to the file o.ppm\n\ +\n\ +\n Note: Input or Output files can also be in the PNG or JPG format or any format\ +\n that FreeImage supports.\ +\n"; + +CompareArgs::CompareArgs() +{ + ImgA = NULL; + ImgB = NULL; + ImgDiff = NULL; + Verbose = false; + LuminanceOnly = false; + FieldOfView = 45.0f; + Gamma = 2.2f; + ThresholdPixels = 100; + Luminance = 100.0f; + ColorFactor = 1.0f; + DownSample = 0; +} + +CompareArgs::~CompareArgs() +{ + if (ImgA) + delete ImgA; + if (ImgB) + delete ImgB; + if (ImgDiff) + delete ImgDiff; +} + +bool CompareArgs::Parse_Args(int argc, char **argv) +{ + if (argc < 3) + { + ErrorStr = copyright; + ErrorStr += usage; + return false; + } + int image_count = 0; + const char* output_file_name = NULL; + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-fov") == 0) + { + if (++i < argc) + { + FieldOfView = (float) atof(argv[i]); + } + } + else if (strcmp(argv[i], "-verbose") == 0) + { + Verbose = true; + } + else if (strcmp(argv[i], "-threshold") == 0) + { + if (++i < argc) + { + ThresholdPixels = atoi(argv[i]); + } + } + else if (strcmp(argv[i], "-gamma") == 0) + { + if (++i < argc) + { + Gamma = (float) atof(argv[i]); + } + } + else if (strcmp(argv[i], "-luminance") == 0) + { + if (++i < argc) + { + Luminance = (float) atof(argv[i]); + } + } + else if (strcmp(argv[i], "-luminanceonly") == 0) + { + LuminanceOnly = true; + } + else if (strcmp(argv[i], "-colorfactor") == 0) + { + if (++i < argc) + { + ColorFactor = (float) atof(argv[i]); + } + } + else if (strcmp(argv[i], "-downsample") == 0) + { + if (++i < argc) + { + DownSample = (int) atoi(argv[i]); + } + } + else if (strcmp(argv[i], "-output") == 0) + { + if (++i < argc) + { + output_file_name = argv[i]; + } + } + else if (image_count < 2) + { +#ifdef FREEIMAGE_LOADER + RGBAImage* img = FreeImageLoader::ReadFromFile(argv[i]); + + if (!img) + { + ErrorStr = "FAIL: Cannot open "; + ErrorStr += argv[i]; + ErrorStr += "\n"; + return false; + } + else + { + ++image_count; + if(image_count == 1) + ImgA = img; + else + ImgB = img; + } +#endif + } + else + { + fprintf(stderr, "Warning: option/file \"%s\" ignored\n", argv[i]); + } + } // i + if(!ImgA || !ImgB) + { + ErrorStr = "FAIL: Not enough image files specified\n"; + return false; + } + for (int i = 0; i < DownSample; i++) + { + if (Verbose) + printf( "Downsampling by %d\n", 1 << (i + 1) ); + RGBAImage *tmp = ImgA->DownSample(); + if (tmp) + { + delete ImgA; + ImgA = tmp; + } + tmp = ImgB->DownSample(); + if (tmp) + { + delete ImgB; + ImgB = tmp; + } + } + if(output_file_name) + { + ImgDiff = new RGBAImage(ImgA->Get_Width(), ImgA->Get_Height(), output_file_name); + } + return true; +} + +void CompareArgs::Print_Args() +{ + printf("Field of view is %f degrees\n", FieldOfView); + printf("Threshold pixels is %d pixels\n", ThresholdPixels); + printf("The Gamma is %f\n", Gamma); + printf("The Display's luminance is %f candela per meter squared\n", Luminance); +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/CompareArgs.h diffimg-2.0.0/3rdparty/perceptualdiff/CompareArgs.h --- diffimg-1.5.0/3rdparty/perceptualdiff/CompareArgs.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/CompareArgs.h 2013-05-08 13:54:32.000000000 +0000 @@ -0,0 +1,53 @@ + +/* + Comapre Args + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _COMPAREARGS_H +#define _COMPAREARGS_H + +#include + +class RGBAImage; + +// Args to pass into the comparison function +class CompareArgs +{ +public: + CompareArgs(); + ~CompareArgs(); + bool Parse_Args(int argc, char **argv); + void Print_Args(); + + RGBAImage *ImgA; // Image A + RGBAImage *ImgB; // Image B + RGBAImage *ImgDiff; // Diff image + bool Verbose; // Print lots of text or not + bool LuminanceOnly; // Only consider luminance; ignore chroma channels in the comparison. + float FieldOfView; // Field of view in degrees + float Gamma; // The gamma to convert to linear color space + float Luminance; // the display's luminance + unsigned int ThresholdPixels; // How many pixels different to ignore + std::string ErrorStr; // Error string + // How much color to use in the metric. + // 0.0 is the same as LuminanceOnly = true, + // 1.0 means full strength. + float ColorFactor; + + // How much to down sample image before comparing, in powers of 2. + int DownSample; +}; + +#endif diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/FreeImageLoader.cpp diffimg-2.0.0/3rdparty/perceptualdiff/FreeImageLoader.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/FreeImageLoader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/FreeImageLoader.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,104 @@ + +/* + FreeImageLoader.cpp + Copyright (C) 2006 Yangli Hector Yee + + (This entire file was rewritten by Jim Tilander) + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "RGBAImage.h" +#include "FreeImageLoader.h" +#include +#include +#include + + +bool FreeImageLoader::WriteToFile(RGBAImage *image, const char* filename) +{ + if (!image) + return false; + + const FREE_IMAGE_FORMAT fileType = FreeImage_GetFIFFromFilename(filename); + if(FIF_UNKNOWN == fileType) + { + printf("Can't save to unknown filetype %s\n", filename); + return false; + } + + int Width = image->Get_Width(); + int Height = image->Get_Height(); + + FIBITMAP* bitmap = FreeImage_Allocate(Width, Height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000); + if(!bitmap) + { + printf("Failed to create freeimage for %s\n", filename); + return false; + } + + const unsigned int* source = image->Get_Data(); + for( int y = 0; y < Height; y++, source += Width ) + { + unsigned int* scanline = (unsigned int*)FreeImage_GetScanLine(bitmap, Height - y - 1 ); + memcpy(scanline, source, sizeof(source[0]) * Width); + } + + FreeImage_SetTransparent(bitmap, false); + FIBITMAP* converted = FreeImage_ConvertTo24Bits(bitmap); + + const bool result = !!FreeImage_Save(fileType, converted, filename); + if(!result) + printf("Failed to save to %s\n", filename); + + FreeImage_Unload(converted); + FreeImage_Unload(bitmap); + return result; +} + +RGBAImage* FreeImageLoader::ReadFromFile(const char* filename) +{ + const FREE_IMAGE_FORMAT fileType = FreeImage_GetFileType(filename); + if(FIF_UNKNOWN == fileType) + { + printf("Unknown filetype %s\n", filename); + return 0; + } + + FIBITMAP* freeImage = 0; + if( FIBITMAP * temporary = FreeImage_Load(fileType, filename, 0) ) + { + freeImage = FreeImage_ConvertTo32Bits(temporary); + FreeImage_Unload(temporary); + } + if(!freeImage) + { + printf( "Failed to load the image %s\n", filename); + return 0; + } + + const int w = FreeImage_GetWidth(freeImage); + const int h = FreeImage_GetHeight(freeImage); + + RGBAImage* result = new RGBAImage(w, h, filename); + + // Copy the image over to our internal format, FreeImage has the scanlines bottom to top though. + unsigned int* dest = result->Get_Data(); + for( int y = 0; y < h; y++, dest += w ) + { + const unsigned int* scanline = (const unsigned int*)FreeImage_GetScanLine(freeImage, h - y - 1 ); + memcpy(dest, scanline, sizeof(dest[0]) * w); + } + + FreeImage_Unload(freeImage); + return result; +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/FreeImageLoader.h diffimg-2.0.0/3rdparty/perceptualdiff/FreeImageLoader.h --- diffimg-1.5.0/3rdparty/perceptualdiff/FreeImageLoader.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/FreeImageLoader.h 2013-05-08 15:06:50.000000000 +0000 @@ -0,0 +1,44 @@ + +/* + FreeImageLoader.h + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _FREEIMAGELOADER_H +#define _FREEIMAGELOADER_H + +#include + +/** Class encapsulating an image containing R,G,B,A channels. + * + * Internal representation assumes data is in the ABGR format, with the RGB + * color channels premultiplied by the alpha value. Premultiplied alpha is + * often also called "associated alpha" - see the tiff 6 specification for some + * discussion - http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf + * + */ + +class RGBAImage; + +class FreeImageLoader +{ + +public: + + static bool WriteToFile(RGBAImage *, const char* filename); + static RGBAImage* ReadFromFile(const char* filename); + +}; + +#endif // _FREEIMAGELOADER_H diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/LPyramid.cpp diffimg-2.0.0/3rdparty/perceptualdiff/LPyramid.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/LPyramid.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/LPyramid.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,98 @@ + +/* + Laplacian Pyramid + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "LPyramid.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +LPyramid::LPyramid(float *image, int width, int height) : + Width(width), + Height(height) +{ + // Make the Laplacian pyramid by successively + // copying the earlier levels and blurring them + for (int i = 0; i=Width) + nx = 2 * Width - nx - 1; + if (ny>=Height) + ny = 2 * Height - ny - 1; + a[index] += Kernel[i + 2] * Kernel[j + 2] * b[ny * Width + nx]; + } + } +} + +float LPyramid::Get_Value(int x, int y, int level) +{ + int index = x + y * Width; + int l = level; + if (l > MAX_PYR_LEVELS) + l = MAX_PYR_LEVELS; + return Levels[level][index]; +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/LPyramid.h diffimg-2.0.0/3rdparty/perceptualdiff/LPyramid.h --- diffimg-1.5.0/3rdparty/perceptualdiff/LPyramid.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/LPyramid.h 2013-05-08 13:54:20.000000000 +0000 @@ -0,0 +1,39 @@ + +/* + Laplacian Pyramid + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _LPYRAMID_H +#define _LPYRAMID_H + +#define MAX_PYR_LEVELS 8 + +class LPyramid +{ +public: + LPyramid(float *image, int width, int height); + virtual ~LPyramid(); + float Get_Value(int x, int y, int level); +protected: + float * Copy(float *img); + void Convolve(float *a, float *b); + + // Succesively blurred versions of the original image + float *Levels[MAX_PYR_LEVELS]; + + int Width; + int Height; +}; + +#endif // _LPYRAMID_H diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/Metric.cpp diffimg-2.0.0/3rdparty/perceptualdiff/Metric.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/Metric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/Metric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,385 @@ + +/* + Metric + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Metric.h" +#include "CompareArgs.h" +#include "RGBAImage.h" +#ifdef FREEIMAGE_LOADER +#include "FreeImageLoader.h" +#endif +#include "LPyramid.h" +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265f +#endif + +/* + * Given the adaptation luminance, this function returns the + * threshold of visibility in cd per m^2 + * TVI means Threshold vs Intensity function + * This version comes from Ward Larson Siggraph 1997 + */ + +float tvi(float adaptation_luminance) +{ + // returns the threshold luminance given the adaptation luminance + // units are candelas per meter squared + + float log_a, r, result; + log_a = log10f(adaptation_luminance); + + if (log_a < -3.94f) + { + r = -2.86f; + } + else if (log_a < -1.44f) + { + r = powf(0.405f * log_a + 1.6f, 2.18f) - 2.86f; + } + else if (log_a < -0.0184f) + { + r = log_a - 0.395f; + } + else if (log_a < 1.9f) + { + r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f; + } + else + { + r = log_a - 1.255f; + } + + result = powf(10.0f, r); + + return result; +} + +// computes the contrast sensitivity function (Barten SPIE 1989) +// given the cycles per degree (cpd) and luminance (lum) +float csf(float cpd, float lum) +{ + float a, b, result; + + a = 440.0f * powf( (1.0f + 0.7f / lum), -0.2f ); + b = 0.3f * powf( (1.0f + 100.0f / lum), 0.15f ); + + result = a * cpd * expf(-b * cpd) * sqrtf( 1.0f + 0.06f * expf(b * cpd) ); + + return result; +} + +/* + * Visual Masking Function + * from Daly 1993 + */ +float mask(float contrast) +{ + float a, b, result; + a = powf(392.498f * contrast, 0.7f); + b = powf(0.0153f * a, 4.0f); + result = powf(1.0f + b, 0.25f); + + return result; +} + +// convert Adobe RGB (1998) with reference white D65 to XYZ +void AdobeRGBToXYZ(float r, float g, float b, float &x, float &y, float &z) +{ + // matrix is from http://www.brucelindbloom.com/ + x = r * 0.576700f + g * 0.185556f + b * 0.188212f; + y = r * 0.297361f + g * 0.627355f + b * 0.0752847f; + z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f; +} + +void XYZToLAB(float x, float y, float z, float &L, float &A, float &B) +{ + static float xw = -1; + static float yw; + static float zw; + + // reference white + if (xw < 0) + { + AdobeRGBToXYZ(1, 1, 1, xw, yw, zw); + } + const float epsilon = 216.0f / 24389.0f; + const float kappa = 24389.0f / 27.0f; + float f[3]; + float r[3]; + r[0] = x / xw; + r[1] = y / yw; + r[2] = z / zw; + for (int i = 0; i < 3; i++) + { + if (r[i] > epsilon) + { + f[i] = powf(r[i], 1.0f / 3.0f); + } + else + { + f[i] = (kappa * r[i] + 16.0f) / 116.0f; + } + } + L = 116.0f * f[1] - 16.0f; + A = 500.0f * (f[0] - f[1]); + B = 200.0f * (f[1] - f[2]); +} + +bool Yee_Compare(CompareArgs &args) +{ + if ( ( args.ImgA->Get_Width() != args.ImgB->Get_Width() ) || + ( args.ImgA->Get_Height() != args.ImgB->Get_Height() ) ) + { + args.ErrorStr = "Image dimensions do not match\n"; + return false; + } + + unsigned int i, dim; + dim = args.ImgA->Get_Width() * args.ImgA->Get_Height(); + bool identical = true; + for (i = 0; i < dim; i++) + if ( args.ImgA->Get(i) != args.ImgB->Get(i) ) + { + identical = false; + break; + } + if (identical) + { + args.ErrorStr = "Images are binary identical\n"; + return true; + } + + // assuming colorspaces are in Adobe RGB (1998) convert to XYZ + float *aX = new float[dim]; + float *aY = new float[dim]; + float *aZ = new float[dim]; + float *bX = new float[dim]; + float *bY = new float[dim]; + float *bZ = new float[dim]; + float *aLum = new float[dim]; + float *bLum = new float[dim]; + + float *aA = new float[dim]; + float *bA = new float[dim]; + float *aB = new float[dim]; + float *bB = new float[dim]; + + if (args.Verbose) + printf("Converting RGB to XYZ\n"); + + unsigned int x, y, w, h; + w = args.ImgA->Get_Width(); + h = args.ImgA->Get_Height(); + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) + { + float r, g, b, l; + i = x + y * w; + r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma); + g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma); + b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma); + AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]); + XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]); + r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma); + g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma); + b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma); + AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]); + XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]); + aLum[i] = aY[i] * args.Luminance; + bLum[i] = bY[i] * args.Luminance; + } + + if (args.Verbose) + printf("Constructing Laplacian Pyramids\n"); + + LPyramid *la = new LPyramid(aLum, w, h); + LPyramid *lb = new LPyramid(bLum, w, h); + + float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI); + float pixels_per_degree = w / num_one_degree_pixels; + + if (args.Verbose) + printf("Performing test\n"); + + float num_pixels = 1; + unsigned int adaptation_level = 0; + for (i = 0; i < MAX_PYR_LEVELS; i++) + { + adaptation_level = i; + if (num_pixels > num_one_degree_pixels) + break; + num_pixels *= 2; + } + + float cpd[MAX_PYR_LEVELS]; + cpd[0] = 0.5f * pixels_per_degree; + for (i = 1; i < MAX_PYR_LEVELS; i++) + cpd[i] = 0.5f * cpd[i - 1]; + float csf_max = csf(3.248f, 100.0f); + + float F_freq[MAX_PYR_LEVELS - 2]; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) + F_freq[i] = csf_max / csf( cpd[i], 100.0f); + + unsigned int pixels_failed = 0; + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) + { + int index = x + y * w; + float contrast[MAX_PYR_LEVELS - 2]; + float sum_contrast = 0; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) + { + float n1 = fabsf( la->Get_Value(x,y,i) - la->Get_Value(x,y,i + 1) ); + float n2 = fabsf( lb->Get_Value(x,y,i) - lb->Get_Value(x,y,i + 1) ); + float numerator = (n1 > n2) ? n1 : n2; + float d1 = fabsf( la->Get_Value(x,y,i + 2) ); + float d2 = fabsf( lb->Get_Value(x,y,i + 2) ); + float denominator = (d1 > d2) ? d1 : d2; + if (denominator < 1e-5f) + denominator = 1e-5f; + contrast[i] = numerator / denominator; + sum_contrast += contrast[i]; + } + if (sum_contrast < 1e-5) + sum_contrast = 1e-5f; + float F_mask[MAX_PYR_LEVELS - 2]; + float adapt = la->Get_Value(x,y,adaptation_level) + lb->Get_Value(x,y,adaptation_level); + adapt *= 0.5f; + if (adapt < 1e-5) + adapt = 1e-5f; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) + F_mask[i] = mask( contrast[i] * csf(cpd[i], adapt) ); + float factor = 0; + for (i = 0; i < MAX_PYR_LEVELS - 2; i++) + factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast; + if (factor < 1) + factor = 1; + if (factor > 10) + factor = 10; + float delta = fabsf( la->Get_Value(x,y,0) - lb->Get_Value(x,y,0) ); + bool pass = true; + + // pure luminance test + if ( delta > factor * tvi(adapt) ) + { + pass = false; + } + else if (!args.LuminanceOnly) + { + // CIE delta E test with modifications + float color_scale = args.ColorFactor; + + // ramp down the color test in scotopic regions + if (adapt < 10.0f) + { + // Don't do color test at all. + color_scale = 0.0; + } + float da = aA[index] - bA[index]; + float db = aB[index] - bB[index]; + da = da * da; + db = db * db; + float delta_e = (da + db) * color_scale; + if (delta_e > factor) + { + pass = false; + } + } + if (!pass) + { + pixels_failed++; + if (args.ImgDiff) + { + args.ImgDiff->Set(255, 0, 0, 255, index); + } + } + else + { + if (args.ImgDiff) + { + args.ImgDiff->Set(0, 0, 0, 255, index); + } + } + } + + if (aX) + delete[] aX; + if (aY) + delete[] aY; + if (aZ) + delete[] aZ; + if (bX) + delete[] bX; + if (bY) + delete[] bY; + if (bZ) + delete[] bZ; + if (aLum) + delete[] aLum; + if (bLum) + delete[] bLum; + if (la) + delete la; + if (lb) + delete lb; + if (aA) + delete aA; + if (bA) + delete bA; + if (aB) + delete aB; + if (bB) + delete bB; + + char different[100]; + sprintf(different, "%d pixels are different\n", pixels_failed); + + // Always output image difference if requested. + if (args.ImgDiff) + { +#ifdef FREEIMAGE_LOADER + if ( FreeImageLoader::WriteToFile(args.ImgDiff, args.ImgDiff->Get_Name().c_str() ) ) + + { + args.ErrorStr += "Wrote difference image to "; + args.ErrorStr += args.ImgDiff->Get_Name(); + args.ErrorStr += "\n"; + } + else + { + args.ErrorStr += "Could not write difference image to "; + args.ErrorStr += args.ImgDiff->Get_Name(); + args.ErrorStr += "\n"; + } +#endif + } + + if (pixels_failed < args.ThresholdPixels) + { + args.ErrorStr = "Images are perceptually indistinguishable\n"; + args.ErrorStr += different; + return true; + } + + args.ErrorStr = "Images are visibly different\n"; + args.ErrorStr += different; + + return false; +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/Metric.h diffimg-2.0.0/3rdparty/perceptualdiff/Metric.h --- diffimg-1.5.0/3rdparty/perceptualdiff/Metric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/Metric.h 2013-05-08 13:54:10.000000000 +0000 @@ -0,0 +1,27 @@ + +/* + Metric + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _METRIC_H +#define _METRIC_H + +class CompareArgs; + +// Image comparison metric using Yee's method +// References: A Perceptual Metric for Production Testing, Hector Yee, Journal of Graphics Tools 2004 +bool Yee_Compare(CompareArgs &args); + +#endif diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/OpenCVImageLoader.cpp diffimg-2.0.0/3rdparty/perceptualdiff/OpenCVImageLoader.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/OpenCVImageLoader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/OpenCVImageLoader.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,138 @@ + +/* + FreeImageLoader.cpp + Copyright (C) 2006 Yangli Hector Yee + + (This entire file was rewritten by Jim Tilander) + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "RGBAImage.h" +#include "OpenCVImageLoader.h" + +#include +#include + +#include +#include + + +bool OpenCVImageLoader::WriteToFile(RGBAImage *image, const char* filename) +{ + if (!image || !filename) + return false; + + cv::Mat mat = RGBAImageToMat(image); + + /* + int Width = image->Get_Width(); + int Height = image->Get_Height(); + + cv::Mat mat = cv::Mat(Height, Width , CV_8UC4 ); + + const unsigned int* source = image->Get_Data(); + for( int y = 0; y < Height; y++, source += Width ) + { + unsigned int * ptr = mat.ptr(y); + //unsigned int* scanline = (unsigned int*)FreeImage_GetScanLine(bitmap, Height - y - 1 ); + memcpy(ptr, source, sizeof(source[0]) * Width); + } + */ + + const bool result = cv::imwrite(filename,mat); + + + return result; +} + +RGBAImage* OpenCVImageLoader::ReadFromFile(const char* filename) +{ + cv::Mat img = cv::imread(filename); + if(img.empty()) + { + printf( "Failed to load the image %s\n", filename); + return 0; + } + + return MatToRGBAImage(img); +/* + const int w = img.cols; + const int h = img.rows; + + RGBAImage* result = new RGBAImage(w, h, filename); + + cvtColor(img, img, CV_RGB2RGBA); + + // Copy the image over to our internal format, FreeImage has the scanlines bottom to top though. + unsigned int* dest = result->Get_Data(); + + for( int y = 0; y < h; y++, dest += w ) + { + //const unsigned int* scanline = (const unsigned int*)FreeImage_GetScanLine(freeImage, h - y - 1 ); + const unsigned int * ptr = img.ptr(y); + memcpy(dest, ptr, sizeof(dest[0]) * w); + } + + //FreeImage_Unload(freeImage); + return result; + */ +} + +RGBAImage* OpenCVImageLoader::MatToRGBAImage(const cv::Mat &img) +{ + if (img.empty() || (img.type() != CV_8UC3 && img.type() != CV_8UC4)) + return 0; + + cv::Mat tmpImg(img); + + const int w = img.cols; + const int h = img.rows; + + RGBAImage* result = new RGBAImage(w, h, "unknown"); + + if (img.type() == CV_8UC3) + cvtColor(img, tmpImg, CV_RGB2RGBA); + + // Copy the image over to our internal format, FreeImage has the scanlines bottom to top though. + unsigned int* dest = result->Get_Data(); + + for( int y = 0; y < h; y++, dest += w ) + { + //const unsigned int* scanline = (const unsigned int*)FreeImage_GetScanLine(freeImage, h - y - 1 ); + const unsigned int * ptr = tmpImg.ptr(y); + memcpy(dest, ptr, sizeof(dest[0]) * w); + } + + return result; +} + +cv::Mat OpenCVImageLoader::RGBAImageToMat(RGBAImage *image) +{ + if (!image) + return cv::Mat(); + + int Width = image->Get_Width(); + int Height = image->Get_Height(); + + cv::Mat mat = cv::Mat(Height, Width , CV_8UC4 ); + + const unsigned int* source = image->Get_Data(); + for( int y = 0; y < Height; y++, source += Width ) + { + unsigned int * ptr = mat.ptr(y); + //unsigned int* scanline = (unsigned int*)FreeImage_GetScanLine(bitmap, Height - y - 1 ); + memcpy(ptr, source, sizeof(source[0]) * Width); + } + + return mat; +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/OpenCVImageLoader.h diffimg-2.0.0/3rdparty/perceptualdiff/OpenCVImageLoader.h --- diffimg-1.5.0/3rdparty/perceptualdiff/OpenCVImageLoader.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/OpenCVImageLoader.h 2013-05-09 13:19:50.000000000 +0000 @@ -0,0 +1,51 @@ + +/* + OpenCVImageLoader.h + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _OPENCVIMAGELOADER_H +#define _OPENCVIMAGELOADER_H + +#include + +/** Class encapsulating an image containing R,G,B,A channels. + * + * Internal representation assumes data is in the ABGR format, with the RGB + * color channels premultiplied by the alpha value. Premultiplied alpha is + * often also called "associated alpha" - see the tiff 6 specification for some + * discussion - http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf + * + */ + +class RGBAImage; + +namespace cv +{ +class Mat; +} + +class OpenCVImageLoader +{ + +public: + + static bool WriteToFile(RGBAImage *, const char* filename); + static RGBAImage* ReadFromFile(const char* filename); + static RGBAImage* MatToRGBAImage(const cv::Mat &); + static cv::Mat RGBAImageToMat(RGBAImage *); + +}; + +#endif // _OPENCVIMAGELOADER_H diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/PerceptualDiff.cpp diffimg-2.0.0/3rdparty/perceptualdiff/PerceptualDiff.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/PerceptualDiff.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/PerceptualDiff.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,48 @@ +/* +PerceptualDiff - a program that compares two images using a perceptual metric +based on the paper : +A perceptual metric for production testing. Journal of graphics tools, 9(4):33-40, 2004, Hector Yee +Copyright (C) 2006 Yangli Hector Yee + +This program is free software; you can redistribute it and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; +if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include "LPyramid.h" +#include "RGBAImage.h" +#include "CompareArgs.h" +#include "Metric.h" + +int main(int argc, char **argv) +{ + CompareArgs args; + + if (!args.Parse_Args(argc, argv)) { + printf("%s", args.ErrorStr.c_str()); + return -1; + } else { + if (args.Verbose) args.Print_Args(); + } + + const bool passed = Yee_Compare(args); + if (passed) { + if(args.Verbose) + printf("PASS: %s\n", args.ErrorStr.c_str()); + } else { + printf("FAIL: %s\n", args.ErrorStr.c_str()); + } + + return passed ? 0 : 1; +} diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/README.txt diffimg-2.0.0/3rdparty/perceptualdiff/README.txt --- diffimg-1.5.0/3rdparty/perceptualdiff/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/README.txt 2009-05-22 21:31:28.000000000 +0000 @@ -0,0 +1,58 @@ +perceptualdiff - a program that compares two images using +a perceptually based image metric. +Copyright (C) 2006 Yangli Hector Yee +yeehector@users.sourceforge.net +http://pdiff.sourceforge.net/ + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details in the file gpl.txt. + +Build Instructions +1. Download cross platform make from http://www.cmake.org +2. Download freeimage from https://sourceforge.net/projects/freeimage +3. Edit CMakeLists.txt to tell it where to find your free image build +4. Type cmake . +5. Type make . (or on Windows systems cmake makes a Visual Studio +Project file) +6. To specify the install directory, use make install DESTDIR="/home/me/mydist" + +Usage + +perceptualdiff image1.(tif | png) image2.(tif | png) [options] +-verbose : Turns on verbose mode +-fov deg: field of view, deg, in degrees. Usually between 10.0 to 85.0. +This controls how much of the screen the oberserver is seeing. Front row of +a theatre has a field of view of around 25 degrees. Back row has a field of + view of around 60 degrees. +-threshold p : Sets the number of pixels, p, to reject. For example if p is + 100, then the test fails if 100 or more pixels are perceptably different. +-gamma g : The gamma to use to convert to RGB linear space. Default is 2.2 +-luminance l: The luminance of the display the observer is seeing. Default + is 100 candela per meter squared +-colorfactor : How much of color to use, 0.0 to 1.0, 0.0 = ignore color. +-downsample : How many powers of two to down sample the image. +-output foo.ppm : Saves the difference image to foo.ppm + +Credits + +Hector Yee, project administrator and originator - hectorgon.blogspot.com +Scott Corley, for png file IO code +Tobias Sauerwein, for make install, package_source Cmake configuration +Cairo Team for bugfixes +Jim Tilander, Rewrote the IO to use FreeImage. + +Version History + +1.0 - Initial distribution +1.0.1 - Fixed off by one convolution error and libpng interface to 1.2.8 +1.0.2 - [jt] Converted the loading and saving routines to use FreeImage +1.1 - Added colorfactor and downsample options. Also always output +difference file if requested. Always print out differing pixels even if the test passes. +1.1.1 - Turn off color test in low lighting conditions. diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/RGBAImage.cpp diffimg-2.0.0/3rdparty/perceptualdiff/RGBAImage.cpp --- diffimg-1.5.0/3rdparty/perceptualdiff/RGBAImage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/RGBAImage.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,59 @@ + +/* + RGBAImage.cpp + Copyright (C) 2006 Yangli Hector Yee + + (This entire file was rewritten by Jim Tilander) + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "RGBAImage.h" +//#include "FreeImage.h" +#include +#include + +RGBAImage* RGBAImage::DownSample() const +{ + if (Width <=1 || Height <=1) + return NULL; + + int nw = Width / 2; + int nh = Height / 2; + RGBAImage* img = new RGBAImage( nw, nh, Name.c_str() ); + for (int y = 0; y < nh; y++) + for (int x = 0; x < nw; x++) + { + int d[4]; + + // Sample a 2x2 patch from the parent image. + d[0] = Get(2 * x + 0, 2 * y + 0); + d[1] = Get(2 * x + 1, 2 * y + 0); + d[2] = Get(2 * x + 0, 2 * y + 1); + d[3] = Get(2 * x + 1, 2 * y + 1); + int rgba = 0; + + // Find the average color. + for (int i = 0; i < 4; i++) + { + int c = ( d[0] >> (8 * i) ) & 0xFF; + c += ( d[1] >> (8 * i) ) & 0xFF; + c += ( d[2] >> (8 * i) ) & 0xFF; + c += ( d[3] >> (8 * i) ) & 0xFF; + c /= 4; + rgba |= (c & 0xFF) << (8 * i); + } + img->Set(x, y, rgba); + } + return img; +} + diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/RGBAImage.h diffimg-2.0.0/3rdparty/perceptualdiff/RGBAImage.h --- diffimg-1.5.0/3rdparty/perceptualdiff/RGBAImage.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/RGBAImage.h 2013-05-08 14:59:54.000000000 +0000 @@ -0,0 +1,120 @@ + +/* + RGBAImage.h + Copyright (C) 2006 Yangli Hector Yee + + This program is free software; you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _RGBAIMAGE_H +#define _RGBAIMAGE_H + +#include + +/** Class encapsulating an image containing R,G,B,A channels. + * + * Internal representation assumes data is in the ABGR format, with the RGB + * color channels premultiplied by the alpha value. Premultiplied alpha is + * often also called "associated alpha" - see the tiff 6 specification for some + * discussion - http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf + * + */ +class RGBAImage +{ + RGBAImage(const RGBAImage&); + RGBAImage& operator=(const RGBAImage&); +public: + RGBAImage(int w, int h, const char *name = 0) + { + Width = w; + Height = h; + if (name) + Name = name; + Data = new unsigned int[w * h]; + } + + ~RGBAImage() + { + if (Data) + delete[] Data; + } + + unsigned char Get_Red(unsigned int i) + { + return (Data[i] & 0xFF); + } + + unsigned char Get_Green(unsigned int i) + { + return ( (Data[i] >> 8) & 0xFF ); + } + + unsigned char Get_Blue(unsigned int i) + { + return ( (Data[i] >> 16) & 0xFF ); + } + + unsigned char Get_Alpha(unsigned int i) + { + return ( (Data[i] >> 24) & 0xFF ); + } + + void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) + { + Data[i] = r | (g << 8) | (b << 16) | (a << 24); + } + + int Get_Width(void) const + { + return Width; + } + + int Get_Height(void) const + { + return Height; + } + + void Set(int x, int y, unsigned int d) + { + Data[x + y * Width] = d; + } + + unsigned int Get(int x, int y) const + { + return Data[x + y * Width]; + } + + unsigned int Get(int i) const + { + return Data[i]; + } + + const std::string &Get_Name(void) const + { + return Name; + } + + unsigned int *Get_Data() const + { + return Data; + } + + RGBAImage* DownSample() const; + +protected: + int Width; + int Height; + std::string Name; + unsigned int *Data; +}; + +#endif diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/gpl.txt diffimg-2.0.0/3rdparty/perceptualdiff/gpl.txt --- diffimg-1.5.0/3rdparty/perceptualdiff/gpl.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/gpl.txt 2009-05-22 21:27:14.000000000 +0000 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -Nru diffimg-1.5.0/3rdparty/perceptualdiff/perceptualdiff.pro diffimg-2.0.0/3rdparty/perceptualdiff/perceptualdiff.pro --- diffimg-1.5.0/3rdparty/perceptualdiff/perceptualdiff.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/perceptualdiff/perceptualdiff.pro 2013-05-15 17:33:04.000000000 +0000 @@ -0,0 +1,29 @@ + + + +TEMPLATE = lib +TARGET = perceptualdiff + +DESTDIR = ./lib + +CONFIG += staticlib + +HEADERS += LPyramid.h \ + Metric.h \ + CompareArgs.h \ + RGBAImage.h \ + OpenCVImageLoader.h + +SOURCES += LPyramid.cpp \ + Metric.cpp \ + CompareArgs.cpp \ + RGBAImage.cpp \ + OpenCVImageLoader.cpp + +INCLUDEPATH += ./ \ + ../opencv/include \ + ../opencv/core/include \ + ../opencv/highgui/include \ + ../opencv/imgproc/include + +win32-msvc:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/CMakeLists.txt diffimg-2.0.0/3rdparty/qtpropertybrowser/CMakeLists.txt --- diffimg-1.5.0/3rdparty/qtpropertybrowser/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/CMakeLists.txt 2013-05-15 19:14:12.000000000 +0000 @@ -0,0 +1,42 @@ +PROJECT (PerceptualDiff) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4) + +# this command finds Qt4 libraries and sets all required variables +FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui REQUIRED) + +# add some useful macros and variables +# (QT_USE_FILE is a variable defined by FIND_PACKAGE( Qt4 ) that contains a path to CMake script) +INCLUDE(${QT_USE_FILE}) + + +FILE(GLOB include_file_list "*.h" ) +FILE(GLOB cpp_file_list "*.cpp" ) + +SET(MYLIB_HDRS + ${include_file_list} +) + +SET(MYLIB_SRCS + ${cpp_file_list} +) + +IF(CMAKE_COMPILER_IS_GNUCXX ) + ADD_DEFINITIONS( -Wall -Wextra ) +ENDIF(CMAKE_COMPILER_IS_GNUCXX ) + +# qt4 definitinos +QT4_WRAP_CPP ( MYLIB_MOC_SRCS ${MYLIB_HDRS} ) +QT4_AUTOMOC ( ${MYLIB_SRCS} ) + + +ADD_LIBRARY(qtpropertybrowser STATIC ${MYLIB_SRCS} ${MYLIB_MOC_SRCS} ) + +IF (MSVC) +# Turn off deprecation warnings +ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) +ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS) +ENDIF(MSVC) + + + diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase 2011-01-20 14:44:36.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser 2011-01-20 14:44:36.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtAbstractPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtAbstractPropertyManager 2011-01-20 14:44:38.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtBoolPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtBoolPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtBoolPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtBoolPropertyManager 2011-01-20 14:44:38.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtBrowserItem diffimg-2.0.0/3rdparty/qtpropertybrowser/QtBrowserItem --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtBrowserItem 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtBrowserItem 2011-01-20 14:44:38.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser diffimg-2.0.0/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser 2011-01-20 14:44:38.000000000 +0000 @@ -0,0 +1 @@ +#include "qtbuttonpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCharEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCharEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCharEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCharEditorFactory 2011-01-20 14:44:40.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCharPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCharPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCharPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCharPropertyManager 2011-01-20 14:44:40.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCheckBoxFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCheckBoxFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCheckBoxFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCheckBoxFactory 2011-01-20 14:44:40.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtColorEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtColorEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtColorEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtColorEditorFactory 2011-01-20 14:44:40.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtColorPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtColorPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtColorPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtColorPropertyManager 2011-01-20 14:44:42.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCursorEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCursorEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCursorEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCursorEditorFactory 2011-01-20 14:44:42.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCursorPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCursorPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtCursorPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtCursorPropertyManager 2011-01-20 14:44:42.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateEditFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateEditFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateEditFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateEditFactory 2011-01-20 14:44:42.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDatePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDatePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDatePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDatePropertyManager 2011-01-20 14:44:44.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateTimeEditFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateTimeEditFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateTimeEditFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateTimeEditFactory 2011-01-20 14:44:44.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateTimePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateTimePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDateTimePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDateTimePropertyManager 2011-01-20 14:44:44.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDoublePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDoublePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDoublePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDoublePropertyManager 2011-01-20 14:44:44.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory 2011-01-20 14:44:46.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtEnumEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtEnumEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtEnumEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtEnumEditorFactory 2011-01-20 14:44:46.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtEnumPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtEnumPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtEnumPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtEnumPropertyManager 2011-01-20 14:44:46.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFlagPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFlagPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFlagPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFlagPropertyManager 2011-01-20 14:44:46.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFontEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFontEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFontEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFontEditorFactory 2011-01-20 14:44:48.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFontPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFontPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtFontPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtFontPropertyManager 2011-01-20 14:44:48.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser diffimg-2.0.0/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser 2011-01-20 14:44:48.000000000 +0000 @@ -0,0 +1 @@ +#include "qtgroupboxpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtGroupPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtGroupPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtGroupPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtGroupPropertyManager 2011-01-20 14:44:36.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtIntPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtIntPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtIntPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtIntPropertyManager 2011-01-20 14:44:36.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory 2011-01-20 14:44:50.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager 2011-01-20 14:44:50.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtLineEditFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtLineEditFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtLineEditFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtLineEditFactory 2011-01-20 14:44:34.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtLocalePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtLocalePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtLocalePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtLocalePropertyManager 2011-01-20 14:44:50.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtPointFPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtPointFPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtPointFPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtPointFPropertyManager 2011-01-20 14:44:34.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtPointPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtPointPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtPointPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtPointPropertyManager 2011-01-20 14:44:34.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtProperty diffimg-2.0.0/3rdparty/qtpropertybrowser/QtProperty --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtProperty 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtProperty 2011-01-20 14:44:32.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtRectFPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtRectFPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtRectFPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtRectFPropertyManager 2011-01-20 14:44:30.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtRectPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtRectPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtRectPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtRectPropertyManager 2011-01-20 14:44:30.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtScrollBarFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtScrollBarFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtScrollBarFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtScrollBarFactory 2011-01-20 14:44:30.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizeFPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizeFPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizeFPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizeFPropertyManager 2011-01-20 14:44:28.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager 2011-01-20 14:44:28.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSizePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSizePropertyManager 2011-01-20 14:44:28.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSliderFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSliderFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSliderFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSliderFactory 2011-01-20 14:44:28.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSpinBoxFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSpinBoxFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtSpinBoxFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtSpinBoxFactory 2011-01-20 14:44:28.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtStringPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtStringPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtStringPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtStringPropertyManager 2011-01-20 14:44:26.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTimeEditFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTimeEditFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTimeEditFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTimeEditFactory 2011-01-20 14:44:26.000000000 +0000 @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTimePropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTimePropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTimePropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTimePropertyManager 2011-01-20 14:44:26.000000000 +0000 @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTreePropertyBrowser diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTreePropertyBrowser --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtTreePropertyBrowser 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtTreePropertyBrowser 2011-01-20 14:44:26.000000000 +0000 @@ -0,0 +1 @@ +#include "qttreepropertybrowser.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantEditorFactory diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantEditorFactory --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantEditorFactory 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantEditorFactory 2011-01-20 14:44:24.000000000 +0000 @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantProperty diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantProperty --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantProperty 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantProperty 2011-01-20 14:44:24.000000000 +0000 @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantPropertyManager diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantPropertyManager --- diffimg-1.5.0/3rdparty/qtpropertybrowser/QtVariantPropertyManager 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/QtVariantPropertyManager 2011-01-20 14:44:50.000000000 +0000 @@ -0,0 +1 @@ +#include "qtvariantproperty.h" Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-arrow.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-arrow.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-busy.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-busy.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-closedhand.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-closedhand.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-cross.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-cross.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-forbidden.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-forbidden.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-hand.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-hand.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-hsplit.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-hsplit.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-ibeam.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-ibeam.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-openhand.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-openhand.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-sizeall.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-sizeall.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-sizeb.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-sizeb.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-sizef.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-sizef.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-sizeh.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-sizeh.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-sizev.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-sizev.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-uparrow.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-uparrow.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-vsplit.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-vsplit.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-wait.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-wait.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/3rdparty/qtpropertybrowser/images/cursor-whatsthis.png and /tmp/TanR_227uO/diffimg-2.0.0/3rdparty/qtpropertybrowser/images/cursor-whatsthis.png differ diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,631 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtbuttonpropertybrowser.h" +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +/* +class QtButtonPropertyBrowserPrivate +{ + QtButtonPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtButtonPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + void slotToggled(bool checked); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + button(0), container(0), layout(0), parent(0), expanded(false) { } + QWidget *widget; // can be null + QLabel *label; // main label with property name + QLabel *widgetLabel; // label substitute showing the current value if there is no widget + QToolButton *button; // expandable button for items with children + QWidget *container; // container which is expanded when the button is clicked + QGridLayout *layout; // layout in container + WidgetItem *parent; + QList children; + bool expanded; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + int gridRow(WidgetItem *item) const; + int gridSpan(WidgetItem *item) const; + void setExpanded(WidgetItem *item, bool expanded); + QToolButton *createButton(QWidget *panret = 0) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QMap m_buttonToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; +*/ + +QToolButton *QtButtonPropertyBrowserPrivate::createButton(QWidget *parent) const +{ + QToolButton *button = new QToolButton(parent); + button->setCheckable(true); + button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setArrowType(Qt::DownArrow); + button->setIconSize(QSize(3, 16)); + /* + QIcon icon; + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowDown), QIcon::Normal, QIcon::Off); + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowUp), QIcon::Normal, QIcon::On); + button->setIcon(icon); + */ + return button; +} + +int QtButtonPropertyBrowserPrivate::gridRow(WidgetItem *item) const +{ + QList siblings; + if (item->parent) + siblings = item->parent->children; + else + siblings = m_children; + + int row = 0; + QListIterator it(siblings); + while (it.hasNext()) { + WidgetItem *sibling = it.next(); + if (sibling == item) + return row; + row += gridSpan(sibling); + } + return -1; +} + +int QtButtonPropertyBrowserPrivate::gridSpan(WidgetItem *item) const +{ + if (item->container && item->expanded) + return 2; + return 1; +} + +void QtButtonPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtButtonPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtButtonPropertyBrowserPrivate::slotUpdate() +{ + QListIterator itItem(m_recreateQueue); + while (itItem.hasNext()) { + WidgetItem *item = itItem.next(); + + WidgetItem *parent = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + const int oldRow = gridRow(item); + if (parent) { + w = parent->container; + l = parent->layout; + } else { + w = q_ptr; + l = m_mainLayout; + } + + int span = 1; + if (!item->widget && !item->widgetLabel) + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtButtonPropertyBrowserPrivate::setExpanded(WidgetItem *item, bool expanded) +{ + if (item->expanded == expanded) + return; + + if (!item->container) + return; + + item->expanded = expanded; + const int row = gridRow(item); + WidgetItem *parent = item->parent; + QGridLayout *l = 0; + if (parent) + l = parent->layout; + else + l = m_mainLayout; + + if (expanded) { + insertRow(l, row + 1); + l->addWidget(item->container, row + 1, 0, 1, 2); + item->container->show(); + } else { + l->removeWidget(item->container); + item->container->hide(); + removeRow(l, row + 1); + } + + item->button->setChecked(expanded); + item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow); +} + +void QtButtonPropertyBrowserPrivate::slotToggled(bool checked) +{ + WidgetItem *item = m_buttonToItem.value(q_ptr->sender()); + if (!item) + return; + + setExpanded(item, checked); + + if (checked) + emit q_ptr->expanded(m_itemToIndex.value(item)); + else + emit q_ptr->collapsed(m_itemToIndex.value(item)); +} + +void QtButtonPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + row = gridRow(afterItem) + gridSpan(afterItem); + if (parentItem) + parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem); + else + m_children.insert(m_children.indexOf(afterItem) + 1, newItem); + } + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr; + } else { + if (!parentItem->container) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *grandParent = parentItem->parent; + //QWidget *w = 0; + QGridLayout *l = 0; + const int oldRow = gridRow(parentItem); + if (grandParent) { + //w = grandParent->container; + l = grandParent->layout; + } else { + //w = q_ptr; + l = m_mainLayout; + } + QFrame *container = new QFrame(); + container->setFrameShape(QFrame::Panel); + container->setFrameShadow(QFrame::Raised); + parentItem->container = container; + parentItem->button = createButton(); + m_buttonToItem[parentItem->button] = parentItem; + q_ptr->connect(parentItem->button, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool))); + parentItem->layout = new QGridLayout(); + container->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + int span = 1; + if (!parentItem->widget && !parentItem->widgetLabel) + span = 2; + l->addWidget(parentItem->button, oldRow, 0, 1, span); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->container; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (newItem->widget) { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } else if (index->property()->hasValue()) { + newItem->widgetLabel = new QLabel(parentWidget); + newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, span, 1); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtButtonPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + const int row = gridRow(item); + + if (parentItem) + parentItem->children.removeAt(parentItem->children.indexOf(item)); + else + m_children.removeAt(m_children.indexOf(item)); + + const int colSpan = gridSpan(item); + + m_buttonToItem.remove(item->button); + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->button) + delete item->button; + if (item->container) + delete item->container; + + if (!parentItem) { + removeRow(m_mainLayout, row); + if (colSpan > 1) + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + if (colSpan > 1) + removeRow(parentItem->layout, row); + } else { + const WidgetItem *grandParent = parentItem->parent; + QGridLayout *l = 0; + if (grandParent) { + l = grandParent->layout; + } else { + l = m_mainLayout; + } + + const int parentRow = gridRow(parentItem); + const int parentSpan = gridSpan(parentItem); + + l->removeWidget(parentItem->button); + l->removeWidget(parentItem->container); + delete parentItem->button; + delete parentItem->container; + parentItem->button = 0; + parentItem->container = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + if (parentSpan > 1) + removeRow(l, parentRow + 1); + + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtButtonPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for(QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for(QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtButtonPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->button) { + QFont font = item->button->font(); + font.setUnderline(property->isModified()); + item->button->setFont(font); + item->button->setText(property->propertyName()); + item->button->setToolTip(property->toolTip()); + item->button->setStatusTip(property->statusTip()); + item->button->setWhatsThis(property->whatsThis()); + item->button->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->toolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setToolTip(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + item->widget->setToolTip(property->valueText()); + } +} + + + +/*! + \class QtButtonPropertyBrowser + + \brief The QtButtonPropertyBrowser class provides a drop down QToolButton + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtButtonPropertyBrowser provides drop down button for all nested + properties, i.e. subproperties are enclosed by a container associated with + the drop down button. The parent property's name is displayed as button text. For example: + + \image qtbuttonpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtButtonPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtButtonPropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtButtonPropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtButtonPropertyBrowser::QtButtonPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtButtonPropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtButtonPropertyBrowser::~QtButtonPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); + delete d_ptr; +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtButtonPropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + d_ptr->setExpanded(itm, expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + return itm->expanded; + return false; +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qtbuttonpropertybrowser.cpp" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h 2012-02-21 23:07:26.000000000 +0000 @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTBUTTONPROPERTYBROWSER_H +#define QTBUTTONPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" +#include +#include +#include +#include + + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtButtonPropertyBrowserPrivate; + + +class QT_QTPROPERTYBROWSER_EXPORT QtButtonPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtButtonPropertyBrowser(QWidget *parent = 0); + ~QtButtonPropertyBrowser(); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtButtonPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtButtonPropertyBrowser) + Q_DISABLE_COPY(QtButtonPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + Q_PRIVATE_SLOT(d_func(), void slotToggled(bool)) + +}; + +class QtButtonPropertyBrowserPrivate +{ + QtButtonPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtButtonPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + void slotToggled(bool checked); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + button(0), container(0), layout(0), /*line(0), */parent(0), expanded(false) { } + QWidget *widget; // can be null + QLabel *label; // main label with property name + QLabel *widgetLabel; // label substitute showing the current value if there is no widget + QToolButton *button; // expandable button for items with children + QWidget *container; // container which is expanded when the button is clicked + QGridLayout *layout; // layout in container + WidgetItem *parent; + QList children; + bool expanded; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + int gridRow(WidgetItem *item) const; + int gridSpan(WidgetItem *item) const; + void setExpanded(WidgetItem *item, bool expanded); + QToolButton *createButton(QWidget *panret = 0) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QMap m_buttonToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qteditorfactory.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qteditorfactory.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qteditorfactory.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qteditorfactory.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2583 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qteditorfactory.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +// Set a hard coded left margin to account for the indentation +// of the tree view icon when switching to an editor + +static inline void setupTreeViewEditorMargin(QLayout *lt) +{ + enum { DecorationMargin = 4 }; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(DecorationMargin, 0, 0, 0); + else + lt->setContentsMargins(0, 0, DecorationMargin, 0); +} + +// ---------- EditorFactoryPrivate : +// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa. + +/* +template +class EditorFactoryPrivate +{ +public: + + typedef QList EditorList; + typedef QMap PropertyToEditorListMap; + typedef QMap EditorToPropertyMap; + + Editor *createEditor(QtProperty *property, QWidget *parent); + void initializeEditor(QtProperty *property, Editor *e); + void slotEditorDestroyed(QObject *object); + + PropertyToEditorListMap m_createdEditors; + EditorToPropertyMap m_editorToProperty; +}; +*/ + +template +Editor *EditorFactoryPrivate::createEditor(QtProperty *property, QWidget *parent) +{ + Editor *editor = new Editor(parent); + initializeEditor(property, editor); + return editor; +} + +template +void EditorFactoryPrivate::initializeEditor(QtProperty *property, Editor *editor) +{ + Q_TYPENAME PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + it = m_createdEditors.insert(property, EditorList()); + it.value().append(editor); + m_editorToProperty.insert(editor, property); +} + +template +void EditorFactoryPrivate::slotEditorDestroyed(QObject *object) +{ + const Q_TYPENAME EditorToPropertyMap::iterator ecend = m_editorToProperty.end(); + for (Q_TYPENAME EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + Editor *editor = itEditor.key(); + QtProperty *property = itEditor.value(); + const Q_TYPENAME PropertyToEditorListMap::iterator pit = m_createdEditors.find(property); + if (pit != m_createdEditors.end()) { + pit.value().removeAll(editor); + if (pit.value().empty()) + m_createdEditors.erase(pit); + } + m_editorToProperty.erase(itEditor); + return; + } + } +} + +// ------------ QtSpinBoxFactory + +/* +class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; +*/ + +void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSpinBoxFactory + + \brief The QtSpinBoxFactory class provides QSpinBox widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtSpinBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSpinBoxFactory::~QtSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QSpinBox *editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtSliderFactory + +/* +class QtSliderFactoryPrivate : public EditorFactoryPrivate +{ + QtSliderFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSliderFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; +*/ + +void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor ) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSliderFactory + + \brief The QtSliderFactory class provides QSlider widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSliderFactory::QtSliderFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtSliderFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSliderFactory::~QtSliderFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QSlider *editor = new QSlider(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtSliderFactory + +/* +class QtScrollBarFactoryPrivate : public EditorFactoryPrivate +{ + QtScrollBarFactory *q_ptr; + Q_DECLARE_PUBLIC(QtScrollBarFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; +*/ + +void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtScrollBarFactory + + \brief The QtScrollBarFactory class provides QScrollBar widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtScrollBarFactory::QtScrollBarFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtScrollBarFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtScrollBarFactory::~QtScrollBarFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QScrollBar *editor = new QScrollBar(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtCheckBoxFactory + +/* +class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtCheckBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCheckBoxFactory) +public: + void slotPropertyChanged(QtProperty *property, bool value); + void slotSetValue(bool value); +}; +*/ + +void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtBoolEdit *editor = itEditor.next(); + editor->blockCheckBoxSignals(true); + editor->setChecked(value); + editor->blockCheckBoxSignals(false); + } +} + +void QtCheckBoxFactoryPrivate::slotSetValue(bool value) +{ + QObject *object = q_ptr->sender(); + + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtBoolPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCheckBoxFactory + + \brief The QtCheckBoxFactory class provides QCheckBox widgets for + properties created by QtBoolPropertyManager objects. + + \sa QtAbstractEditorFactory, QtBoolPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCheckBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCheckBoxFactory::~QtCheckBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotPropertyChanged(QtProperty *, bool))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QtBoolEdit *editor = d_ptr->createEditor(property, parent); + editor->setChecked(manager->value(property)); + + connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotPropertyChanged(QtProperty *, bool))); +} + +// QtDoubleSpinBoxFactory + +/* +class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtDoubleSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, double value); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotSetValue(double value); +}; +*/ + +void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value) +{ + QList editors = m_createdEditors[property]; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, + double min, double max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDecimals(prec); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator itcend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! \class QtDoubleSpinBoxFactory + + \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox + widgets for properties created by QtDoublePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDoublePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDoubleSpinBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotPropertyChanged(QtProperty *, double))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + connect(manager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QDoubleSpinBox *editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setDecimals(manager->decimals(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotPropertyChanged(QtProperty *, double))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + disconnect(manager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); +} + +// QtLineEditFactory + +/* +class QtLineEditFactoryPrivate : public EditorFactoryPrivate +{ + QtLineEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtLineEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QString &value); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotSetValue(const QString &value); +}; +*/ + +void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QString &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QLineEdit *editor = itEditor.next(); + if (editor->text() != value) + editor->setText(value); + } +} + +void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property, + const QRegExp ®Exp) +{ + if (!m_createdEditors.contains(property)) + return; + + QtStringPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QLineEdit *editor = itEditor.next(); + editor->blockSignals(true); + const QValidator *oldValidator = editor->validator(); + QValidator *newValidator = 0; + if (regExp.isValid()) { + newValidator = new QRegExpValidator(regExp, editor); + } + editor->setValidator(newValidator); + if (oldValidator) + delete oldValidator; + editor->blockSignals(false); + } +} + +void QtLineEditFactoryPrivate::slotSetValue(const QString &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtStringPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtLineEditFactory + + \brief The QtLineEditFactory class provides QLineEdit widgets for + properties created by QtStringPropertyManager objects. + + \sa QtAbstractEditorFactory, QtStringPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtLineEditFactory::QtLineEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtLineEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtLineEditFactory::~QtLineEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); + connect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + + QLineEdit *editor = d_ptr->createEditor(property, parent); + QRegExp regExp = manager->regExp(property); + if (regExp.isValid()) { + QValidator *validator = new QRegExpValidator(regExp, editor); + editor->setValidator(validator); + } + editor->setText(manager->value(property)); + + connect(editor, SIGNAL(textEdited(const QString &)), + this, SLOT(slotSetValue(const QString &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); + disconnect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); +} + +// QtDateEditFactory + +/* +class QtDateEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDate &value); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotSetValue(const QDate &value); +}; +*/ + +void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QDate &value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDate(value); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property, + const QDate &min, const QDate &max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDatePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDateRange(min, max); + editor->setDate(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotSetValue(const QDate &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDatePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateEditFactory + + \brief The QtDateEditFactory class provides QDateEdit widgets for + properties created by QtDatePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDatePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateEditFactory::QtDateEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDateEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateEditFactory::~QtDateEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDate &))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QDateEdit *editor = d_ptr->createEditor(property, parent); + editor->setCalendarPopup(true); + editor->setDateRange(manager->minimum(property), manager->maximum(property)); + editor->setDate(manager->value(property)); + + connect(editor, SIGNAL(dateChanged(const QDate &)), + this, SLOT(slotSetValue(const QDate &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDate &))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); +} + +// QtTimeEditFactory + +/* +class QtTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QTime &value); + void slotSetValue(const QTime &value); +}; +*/ + +void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QTime &value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QTimeEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setTime(value); + editor->blockSignals(false); + } +} + +void QtTimeEditFactoryPrivate::slotSetValue(const QTime &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtTimePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtTimeEditFactory + + \brief The QtTimeEditFactory class provides QTimeEdit widgets for + properties created by QtTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtTimeEditFactory::QtTimeEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtTimeEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtTimeEditFactory::~QtTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QTime &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QTimeEdit *editor = d_ptr->createEditor(property, parent); + editor->setTime(manager->value(property)); + + connect(editor, SIGNAL(timeChanged(const QTime &)), + this, SLOT(slotSetValue(const QTime &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QTime &))); +} + +// QtDateTimeEditFactory + +/* +class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDateTime &value); + void slotSetValue(const QDateTime &value); + +}; +*/ + +void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QDateTime &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateTimeEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDateTime(value); + editor->blockSignals(false); + } +} + +void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDateTimePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateTimeEditFactory + + \brief The QtDateTimeEditFactory class provides QDateTimeEdit + widgets for properties created by QtDateTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDateTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDateTimeEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateTimeEditFactory::~QtDateTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QDateTimeEdit *editor = d_ptr->createEditor(property, parent); + editor->setDateTime(manager->value(property)); + + connect(editor, SIGNAL(dateTimeChanged(const QDateTime &)), + this, SLOT(slotSetValue(const QDateTime &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &))); +} + +// QtKeySequenceEditorFactory + +/* +class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtKeySequenceEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QKeySequence &value); + void slotSetValue(const QKeySequence &value); +}; +*/ + +void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QKeySequence &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtKeySequenceEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setKeySequence(value); + editor->blockSignals(false); + } +} + +void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtKeySequenceEditorFactory + + \brief The QtKeySequenceEditorFactory class provides editor + widgets for properties created by QtKeySequencePropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtKeySequenceEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtKeySequenceEdit *editor = d_ptr->createEditor(property, parent); + editor->setKeySequence(manager->value(property)); + + connect(editor, SIGNAL(keySequenceChanged(const QKeySequence &)), + this, SLOT(slotSetValue(const QKeySequence &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &))); +} + +// QtCharEdit + +/* +class QtCharEdit : public QWidget +{ + Q_OBJECT +public: + QtCharEdit(QWidget *parent = 0); + + QChar value() const; + bool eventFilter(QObject *o, QEvent *e); +public Q_SLOTS: + void setValue(const QChar &value); +Q_SIGNALS: + void valueChanged(const QChar &value); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + bool event(QEvent *e); +private slots: + void slotClearChar(); +private: + void handleKeyEvent(QKeyEvent *e); + + QChar m_value; + QLineEdit *m_lineEdit; +}; +*/ + +QtCharEdit::QtCharEdit(QWidget *parent) + : QWidget(parent), m_lineEdit(new QLineEdit(this)) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->setMargin(0); + m_lineEdit->installEventFilter(this); + m_lineEdit->setReadOnly(true); + m_lineEdit->setFocusProxy(this); + setFocusPolicy(m_lineEdit->focusPolicy()); + setAttribute(Qt::WA_InputMethodEnabled); +} + +bool QtCharEdit::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_lineEdit && e->type() == QEvent::ContextMenu) { + QContextMenuEvent *c = static_cast(e); + QMenu *menu = m_lineEdit->createStandardContextMenu(); + QList actions = menu->actions(); + QListIterator itAction(actions); + while (itAction.hasNext()) { + QAction *action = itAction.next(); + action->setShortcut(QKeySequence()); + QString actionString = action->text(); + const int pos = actionString.lastIndexOf(QLatin1Char('\t')); + if (pos > 0) + actionString = actionString.remove(pos, actionString.length() - pos); + action->setText(actionString); + } + QAction *actionBefore = 0; + if (actions.count() > 0) + actionBefore = actions[0]; + QAction *clearAction = new QAction(tr("Clear Char"), menu); + menu->insertAction(actionBefore, clearAction); + menu->insertSeparator(actionBefore); + clearAction->setEnabled(!m_value.isNull()); + connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar())); + menu->exec(c->globalPos()); + delete menu; + e->accept(); + return true; + } + + return QWidget::eventFilter(o, e); +} + +void QtCharEdit::slotClearChar() +{ + if (m_value.isNull()) + return; + setValue(QChar()); + emit valueChanged(m_value); +} + +void QtCharEdit::handleKeyEvent(QKeyEvent *e) +{ + const int key = e->key(); + switch (key) { + case Qt::Key_Control: + case Qt::Key_Shift: + case Qt::Key_Meta: + case Qt::Key_Alt: + case Qt::Key_Super_L: + case Qt::Key_Return: + return; + default: + break; + } + + const QString text = e->text(); + if (text.count() != 1) + return; + + const QChar c = text.at(0); + if (!c.isPrint()) + return; + + if (m_value == c) + return; + + m_value = c; + const QString str = m_value.isNull() ? QString() : QString(m_value); + m_lineEdit->setText(str); + e->accept(); + emit valueChanged(m_value); +} + +void QtCharEdit::setValue(const QChar &value) +{ + if (value == m_value) + return; + + m_value = value; + QString str = value.isNull() ? QString() : QString(value); + m_lineEdit->setText(str); +} + +QChar QtCharEdit::value() const +{ + return m_value; +} + +void QtCharEdit::focusInEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + m_lineEdit->selectAll(); + QWidget::focusInEvent(e); +} + +void QtCharEdit::focusOutEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + QWidget::focusOutEvent(e); +} + +void QtCharEdit::keyPressEvent(QKeyEvent *e) +{ + handleKeyEvent(e); + e->accept(); +} + +void QtCharEdit::keyReleaseEvent(QKeyEvent *e) +{ + m_lineEdit->event(e); +} + +bool QtCharEdit::event(QEvent *e) +{ + switch(e->type()) { + case QEvent::Shortcut: + case QEvent::ShortcutOverride: + case QEvent::KeyRelease: + e->accept(); + return true; + default: + break; + } + return QWidget::event(e); +} + +// QtCharEditorFactory + +/* +class QtCharEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtCharEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCharEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QChar &value); + void slotSetValue(const QChar &value); + +}; +*/ + +void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QChar &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtCharEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtCharPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCharEditorFactory + + \brief The QtCharEditorFactory class provides editor + widgets for properties created by QtCharPropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCharEditorFactory::QtCharEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCharEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCharEditorFactory::~QtCharEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtCharEdit *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(const QChar &)), + this, SLOT(slotSetValue(const QChar &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); +} + +// QtEnumEditorFactory + +/* +class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtEnumEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtEnumEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotEnumNamesChanged(QtProperty *property, const QStringList &); + void slotEnumIconsChanged(QtProperty *property, const QMap &); + void slotSetValue(int value); +}; +*/ + +void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setCurrentIndex(value); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property, + const QStringList &enumNames) +{ + if (!m_createdEditors.contains(property)) + return; + + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QMap enumIcons = manager->enumIcons(property); + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->clear(); + editor->addItems(enumNames); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property, + const QMap &enumIcons) +{ + if (!m_createdEditors.contains(property)) + return; + + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + const QStringList enumNames = manager->enumNames(property); + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtEnumEditorFactory + + \brief The QtEnumEditorFactory class provides QComboBox widgets for + properties created by QtEnumPropertyManager objects. + + \sa QtAbstractEditorFactory, QtEnumPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtEnumEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtEnumEditorFactory::~QtEnumEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QComboBox *editor = d_ptr->createEditor(property, parent); + editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + editor->view()->setTextElideMode(Qt::ElideRight); + QStringList enumNames = manager->enumNames(property); + editor->addItems(enumNames); + QMap enumIcons = manager->enumIcons(property); + const int enumNamesCount = enumNames.count(); + for (int i = 0; i < enumNamesCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + + connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); +} + +// QtCursorEditorFactory + +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + + /* +class QtCursorEditorFactoryPrivate +{ + QtCursorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCursorEditorFactory) +public: + QtCursorEditorFactoryPrivate(); + + void slotPropertyChanged(QtProperty *property, const QCursor &cursor); + void slotEnumChanged(QtProperty *property, int value); + void slotEditorDestroyed(QObject *object); + + QtEnumEditorFactory *m_enumEditorFactory; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToEnum; + QMap m_enumToProperty; + QMap > m_enumToEditors; + QMap m_editorToEnum; + bool m_updatingEnum; +}; +*/ + +QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate() + : m_updatingEnum(false) +{ + +} + +void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor) +{ + // update enum property + QtProperty *enumProp = m_propertyToEnum.value(property); + if (!enumProp) + return; + + m_updatingEnum = true; + m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(cursor)); + m_updatingEnum = false; +} + +void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (m_updatingEnum) + return; + // update cursor property + QtProperty *prop = m_enumToProperty.value(property); + if (!prop) + return; + QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop); + if (!cursorManager) + return; +#ifndef QT_NO_CURSOR + cursorManager->setValue(prop, QCursor(cursorDatabase()->valueToCursor(value))); +#endif +} + +void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object) +{ + // remove from m_editorToEnum map; + // remove from m_enumToEditors map; + // if m_enumToEditors doesn't contains more editors delete enum property; + const QMap::ConstIterator ecend = m_editorToEnum.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToEnum.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QWidget *editor = itEditor.key(); + QtProperty *enumProp = itEditor.value(); + m_editorToEnum.remove(editor); + m_enumToEditors[enumProp].removeAll(editor); + if (m_enumToEditors[enumProp].isEmpty()) { + m_enumToEditors.remove(enumProp); + QtProperty *property = m_enumToProperty.value(enumProp); + m_enumToProperty.remove(enumProp); + m_propertyToEnum.remove(property); + delete enumProp; + } + return; + } +} + +/*! + \class QtCursorEditorFactory + + \brief The QtCursorEditorFactory class provides QComboBox widgets for + properties created by QtCursorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtCursorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCursorEditorFactoryPrivate(); + d_ptr->q_ptr = this; + + d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager); +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCursorEditorFactory::~QtCursorEditorFactory() +{ + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QtProperty *enumProp = 0; + if (d_ptr->m_propertyToEnum.contains(property)) { + enumProp = d_ptr->m_propertyToEnum[property]; + } else { + enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName()); + d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cursorDatabase()->cursorShapeNames()); + d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cursorDatabase()->cursorShapeIcons()); +#ifndef QT_NO_CURSOR + d_ptr->m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(manager->value(property))); +#endif + d_ptr->m_propertyToEnum[property] = enumProp; + d_ptr->m_enumToProperty[enumProp] = property; + } + QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory; + QWidget *editor = af->createEditor(enumProp, parent); + d_ptr->m_enumToEditors[enumProp].append(editor); + d_ptr->m_editorToEnum[editor] = enumProp; + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &))); +} + +// QtColorEditWidget + +/* +class QtColorEditWidget : public QWidget { + Q_OBJECT + +public: + QtColorEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QColor &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QColor &value); + +private: + QColor m_color; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; +*/ + +QtColorEditWidget::QtColorEditWidget(QWidget *parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout *lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color)); +} + +void QtColorEditWidget::setValue(const QColor &c) +{ + if (m_color != c) { + m_color = c; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(c))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(c)); + } +} + +void QtColorEditWidget::buttonClicked() +{ + bool ok = false; + QRgb oldRgba = m_color.rgba(); + QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, this); + if (ok && newRgba != oldRgba) { + setValue(QColor::fromRgba(newRgba)); + emit valueChanged(m_color); + } +} + +bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +// QtColorEditorFactoryPrivate + +/* +class QtColorEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtColorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtColorEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QColor &value); + void slotSetValue(const QColor &value); +}; +*/ + +void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QColor &value) +{ + const PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + return; + QListIterator itEditor(it.value()); + + while (itEditor.hasNext()) + itEditor.next()->setValue(value); +} + +void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value) +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtColorPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtColorEditorFactory + + \brief The QtColorEditorFactory class provides color editing for + properties created by QtColorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtColorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtColorEditorFactory::QtColorEditorFactory(QObject *parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtColorEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtColorEditorFactory::~QtColorEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), + this, SLOT(slotPropertyChanged(QtProperty*,QColor))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtColorEditWidget *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QColor)), this, SLOT(slotSetValue(QColor))); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), this, SLOT(slotPropertyChanged(QtProperty*,QColor))); +} + +// QtFontEditWidget + +/* +class QtFontEditWidget : public QWidget { + Q_OBJECT + +public: + QtFontEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QFont &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QFont &value); + +private: + QFont m_font; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; +*/ + +QtFontEditWidget::QtFontEditWidget(QWidget *parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout *lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font)); +} + +void QtFontEditWidget::setValue(const QFont &f) +{ + if (m_font != f) { + m_font = f; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(f)); + } +} + +void QtFontEditWidget::buttonClicked() +{ + bool ok = false; + QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font")); + if (ok && newFont != m_font) { + QFont f = m_font; + // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...) + if (m_font.family() != newFont.family()) + f.setFamily(newFont.family()); + if (m_font.pointSize() != newFont.pointSize()) + f.setPointSize(newFont.pointSize()); + if (m_font.bold() != newFont.bold()) + f.setBold(newFont.bold()); + if (m_font.italic() != newFont.italic()) + f.setItalic(newFont.italic()); + if (m_font.underline() != newFont.underline()) + f.setUnderline(newFont.underline()); + if (m_font.strikeOut() != newFont.strikeOut()) + f.setStrikeOut(newFont.strikeOut()); + setValue(f); + emit valueChanged(m_font); + } +} + +bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +// QtFontEditorFactoryPrivate + +/* +class QtFontEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtFontEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtFontEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QFont &value); + void slotSetValue(const QFont &value); +}; +*/ + +void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QFont &value) +{ + const PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + return; + QListIterator itEditor(it.value()); + + while (itEditor.hasNext()) + itEditor.next()->setValue(value); +} + +void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value) +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtFontPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtFontEditorFactory + + \brief The QtFontEditorFactory class provides font editing for + properties created by QtFontPropertyManager objects. + + \sa QtAbstractEditorFactory, QtFontPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtFontEditorFactory::QtFontEditorFactory(QObject *parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtFontEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtFontEditorFactory::~QtFontEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), + this, SLOT(slotPropertyChanged(QtProperty*,QFont))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtFontEditWidget *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont))); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont))); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qteditorfactory.cpp" +//#include "qteditorfactory.moc" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qteditorfactory.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qteditorfactory.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qteditorfactory.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qteditorfactory.h 2012-02-21 23:07:20.000000000 +0000 @@ -0,0 +1,679 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTEDITORFACTORY_H +#define QTEDITORFACTORY_H + +#include "qtpropertymanager.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qtpropertybrowserutils_p.h" + + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSpinBoxFactory(QObject *parent = 0); + ~QtSpinBoxFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtSpinBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSpinBoxFactory) + Q_DISABLE_COPY(QtSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtSliderFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSliderFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSliderFactory(QObject *parent = 0); + ~QtSliderFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtSliderFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSliderFactory) + Q_DISABLE_COPY(QtSliderFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtScrollBarFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtScrollBarFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtScrollBarFactory(QObject *parent = 0); + ~QtScrollBarFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtScrollBarFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtScrollBarFactory) + Q_DISABLE_COPY(QtScrollBarFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCheckBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCheckBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCheckBoxFactory(QObject *parent = 0); + ~QtCheckBoxFactory(); +protected: + void connectPropertyManager(QtBoolPropertyManager *manager); + QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtBoolPropertyManager *manager); +private: + QtCheckBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCheckBoxFactory) + Q_DISABLE_COPY(QtCheckBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDoubleSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoubleSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDoubleSpinBoxFactory(QObject *parent = 0); + ~QtDoubleSpinBoxFactory(); +protected: + void connectPropertyManager(QtDoublePropertyManager *manager); + QWidget *createEditor(QtDoublePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDoublePropertyManager *manager); +private: + QtDoubleSpinBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory) + Q_DISABLE_COPY(QtDoubleSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(double)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtLineEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtLineEditFactory(QObject *parent = 0); + ~QtLineEditFactory(); +protected: + void connectPropertyManager(QtStringPropertyManager *manager); + QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtStringPropertyManager *manager); +private: + QtLineEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtLineEditFactory) + Q_DISABLE_COPY(QtLineEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateEditFactory(QObject *parent = 0); + ~QtDateEditFactory(); +protected: + void connectPropertyManager(QtDatePropertyManager *manager); + QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDatePropertyManager *manager); +private: + QtDateEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateEditFactory) + Q_DISABLE_COPY(QtDateEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, + const QDate &, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDate &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtTimeEditFactory(QObject *parent = 0); + ~QtTimeEditFactory(); +protected: + void connectPropertyManager(QtTimePropertyManager *manager); + QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtTimePropertyManager *manager); +private: + QtTimeEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTimeEditFactory) + Q_DISABLE_COPY(QtTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QTime &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QTime &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateTimeEditFactory(QObject *parent = 0); + ~QtDateTimeEditFactory(); +protected: + void connectPropertyManager(QtDateTimePropertyManager *manager); + QWidget *createEditor(QtDateTimePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDateTimePropertyManager *manager); +private: + QtDateTimeEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateTimeEditFactory) + Q_DISABLE_COPY(QtDateTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtKeySequenceEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequenceEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtKeySequenceEditorFactory(QObject *parent = 0); + ~QtKeySequenceEditorFactory(); +protected: + void connectPropertyManager(QtKeySequencePropertyManager *manager); + QWidget *createEditor(QtKeySequencePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtKeySequencePropertyManager *manager); +private: + QtKeySequenceEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory) + Q_DISABLE_COPY(QtKeySequenceEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCharEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCharEditorFactory(QObject *parent = 0); + ~QtCharEditorFactory(); +protected: + void connectPropertyManager(QtCharPropertyManager *manager); + QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtCharPropertyManager *manager); +private: + QtCharEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCharEditorFactory) + Q_DISABLE_COPY(QtCharEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtEnumEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtEnumEditorFactory(QObject *parent = 0); + ~QtEnumEditorFactory(); +protected: + void connectPropertyManager(QtEnumPropertyManager *manager); + QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtEnumPropertyManager *manager); +private: + QtEnumEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtEnumEditorFactory) + Q_DISABLE_COPY(QtEnumEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, + const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, + const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCursorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCursorEditorFactory(QObject *parent = 0); + ~QtCursorEditorFactory(); +protected: + void connectPropertyManager(QtCursorPropertyManager *manager); + QWidget *createEditor(QtCursorPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtCursorPropertyManager *manager); +private: + QtCursorEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCursorEditorFactory) + Q_DISABLE_COPY(QtCursorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtColorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtColorEditorFactory(QObject *parent = 0); + ~QtColorEditorFactory(); +protected: + void connectPropertyManager(QtColorPropertyManager *manager); + QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtColorPropertyManager *manager); +private: + QtColorEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtColorEditorFactory) + Q_DISABLE_COPY(QtColorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QColor &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &)) +}; + +class QtFontEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtFontEditorFactory(QObject *parent = 0); + ~QtFontEditorFactory(); +protected: + void connectPropertyManager(QtFontPropertyManager *manager); + QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtFontPropertyManager *manager); +private: + QtFontEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFontEditorFactory) + Q_DISABLE_COPY(QtFontEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QFont &)) + //Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) +}; + +template +class EditorFactoryPrivate +{ +public: + + typedef QList EditorList; + typedef QMap PropertyToEditorListMap; + typedef QMap EditorToPropertyMap; + + Editor *createEditor(QtProperty *property, QWidget *parent); + void initializeEditor(QtProperty *property, Editor *e); + void slotEditorDestroyed(QObject *object); + + PropertyToEditorListMap m_createdEditors; + EditorToPropertyMap m_editorToProperty; +}; + +class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + +class QtSliderFactoryPrivate : public EditorFactoryPrivate +{ + QtSliderFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSliderFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + +class QtScrollBarFactoryPrivate : public EditorFactoryPrivate +{ + QtScrollBarFactory *q_ptr; + Q_DECLARE_PUBLIC(QtScrollBarFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + + +class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtCheckBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCheckBoxFactory) +public: + void slotPropertyChanged(QtProperty *property, bool value); + void slotSetValue(bool value); +}; + +class QtColorEditWidget : public QWidget { + Q_OBJECT + +public: + QtColorEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QColor &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QColor &value); + +private: + QColor m_color; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; + +class QtColorEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtColorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtColorEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QColor &value); + void slotSetValue(const QColor &value); +}; + +class QtFontEditWidget : public QWidget { + Q_OBJECT + +public: + QtFontEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QFont &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QFont &value); + +private: + QFont m_font; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; + +class QtFontEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtFontEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtFontEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QFont &value); + void slotSetValue(const QFont &value); +}; + +class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtDoubleSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, double value); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotSetValue(double value); +}; + +class QtLineEditFactoryPrivate : public EditorFactoryPrivate +{ + QtLineEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtLineEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QString &value); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotSetValue(const QString &value); +}; + +class QtCursorEditorFactoryPrivate +{ + QtCursorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCursorEditorFactory) +public: + QtCursorEditorFactoryPrivate(); + + void slotPropertyChanged(QtProperty *property, const QCursor &cursor); + void slotEnumChanged(QtProperty *property, int value); + void slotEditorDestroyed(QObject *object); + + QtEnumEditorFactory *m_enumEditorFactory; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToEnum; + QMap m_enumToProperty; + QMap > m_enumToEditors; + QMap m_editorToEnum; + bool m_updatingEnum; +}; + +class QtDateEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDate &value); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotSetValue(const QDate &value); +}; + +class QtTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QTime &value); + void slotSetValue(const QTime &value); +}; + +class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDateTime &value); + void slotSetValue(const QDateTime &value); + +}; + +class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtKeySequenceEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QKeySequence &value); + void slotSetValue(const QKeySequence &value); +}; + +class QtCharEdit; + +class QtCharEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtCharEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCharEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QChar &value); + void slotSetValue(const QChar &value); + +}; + +class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtEnumEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtEnumEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotEnumNamesChanged(QtProperty *property, const QStringList &); + void slotEnumIconsChanged(QtProperty *property, const QMap &); + void slotSetValue(int value); +}; + +class QtCharEdit : public QWidget +{ + Q_OBJECT +public: + QtCharEdit(QWidget *parent = 0); + + QChar value() const; + bool eventFilter(QObject *o, QEvent *e); +public Q_SLOTS: + void setValue(const QChar &value); +Q_SIGNALS: + void valueChanged(const QChar &value); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + bool event(QEvent *e); +private slots: + void slotClearChar(); +private: + void handleKeyEvent(QKeyEvent *e); + + QChar m_value; + QLineEdit *m_lineEdit; +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,533 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtgroupboxpropertybrowser.h" +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +/* +class QtGroupBoxPropertyBrowserPrivate +{ + QtGroupBoxPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + groupBox(0), layout(0), line(0), parent(0) { } + QWidget *widget; // can be null + QLabel *label; + QLabel *widgetLabel; + QGroupBox *groupBox; + QGridLayout *layout; + QFrame *line; + WidgetItem *parent; + QList children; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + + bool hasHeader(WidgetItem *item) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; +*/ + +void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtGroupBoxPropertyBrowserPrivate::slotUpdate() +{ + QListIterator itItem(m_recreateQueue); + while (itItem.hasNext()) { + WidgetItem *item = itItem.next(); + + WidgetItem *par = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(item); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(item); + if (hasHeader(par)) + oldRow += 2; + } + + if (item->widget) { + item->widget->setParent(w); + } else if (item->widgetLabel) { + item->widgetLabel->setParent(w); + } else { + item->widgetLabel = new QLabel(w); + } + int span = 1; + if (item->widget) + l->addWidget(item->widget, oldRow, 1, 1, 1); + else if (item->widgetLabel) + l->addWidget(item->widgetLabel, oldRow, 1, 1, 1); + else + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtGroupBoxPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + if (parentItem) { + row = parentItem->children.indexOf(afterItem) + 1; + parentItem->children.insert(row, newItem); + } else { + row = m_children.indexOf(afterItem) + 1; + m_children.insert(row, newItem); + } + } + if (parentItem && hasHeader(parentItem)) + row += 2; + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr;; + } else { + if (!parentItem->groupBox) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *par = parentItem->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + parentItem->groupBox = new QGroupBox(w); + parentItem->layout = new QGridLayout(); + parentItem->groupBox->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + if (parentItem->widget) { + l->removeWidget(parentItem->widget); + parentItem->widget->setParent(parentItem->groupBox); + parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2); + parentItem->line = new QFrame(parentItem->groupBox); + } else if (parentItem->widgetLabel) { + l->removeWidget(parentItem->widgetLabel); + delete parentItem->widgetLabel; + parentItem->widgetLabel = 0; + } + if (parentItem->line) { + parentItem->line->setFrameShape(QFrame::HLine); + parentItem->line->setFrameShadow(QFrame::Sunken); + parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2); + } + l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->groupBox; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (!newItem->widget) { + newItem->widgetLabel = new QLabel(parentWidget); + } else { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, 1, span); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + int row = -1; + + if (parentItem) { + row = parentItem->children.indexOf(item); + parentItem->children.removeAt(row); + if (hasHeader(parentItem)) + row += 2; + } else { + row = m_children.indexOf(item); + m_children.removeAt(row); + } + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->groupBox) + delete item->groupBox; + + if (!parentItem) { + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + } else { + WidgetItem *par = parentItem->parent; + //QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + //w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + //w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + + if (parentItem->widget) { + parentItem->widget->hide(); + parentItem->widget->setParent(0); + } else if (parentItem->widgetLabel) { + parentItem->widgetLabel->hide(); + parentItem->widgetLabel->setParent(0); + } else { + //parentItem->widgetLabel = new QLabel(w); + } + l->removeWidget(parentItem->groupBox); + delete parentItem->groupBox; + parentItem->groupBox = 0; + parentItem->line = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const +{ + if (item->widget) + return true; + return false; +} + +void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->groupBox) { + QFont font = item->groupBox->font(); + font.setUnderline(property->isModified()); + item->groupBox->setFont(font); + item->groupBox->setTitle(property->propertyName()); + item->groupBox->setToolTip(property->toolTip()); + item->groupBox->setStatusTip(property->statusTip()); + item->groupBox->setWhatsThis(property->whatsThis()); + item->groupBox->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->toolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + item->widget->setToolTip(property->valueText()); + } + //item->setIcon(1, property->valueIcon()); +} + + + +/*! + \class QtGroupBoxPropertyBrowser + + \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtGroupBoxPropertyBrowser provides group boxes for all nested + properties, i.e. subproperties are enclosed by a group box with + the parent property's name as its title. For example: + + \image qtgroupboxpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtGroupBoxPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtGroupBoxPropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); + delete d_ptr; +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qtgroupboxpropertybrowser.cpp" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h 2012-02-21 23:07:14.000000000 +0000 @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTGROUPBOXPROPERTYBROWSER_H +#define QTGROUPBOXPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtGroupBoxPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupBoxPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtGroupBoxPropertyBrowser(QWidget *parent = 0); + ~QtGroupBoxPropertyBrowser(); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtGroupBoxPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtGroupBoxPropertyBrowser) + Q_DISABLE_COPY(QtGroupBoxPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + +}; + +class QtGroupBoxPropertyBrowserPrivate +{ + QtGroupBoxPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + groupBox(0), layout(0), line(0), parent(0) { } + QWidget *widget; // can be null + QLabel *label; + QLabel *widgetLabel; + QGroupBox *groupBox; + QGridLayout *layout; + QFrame *line; + WidgetItem *parent; + QList children; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + + bool hasHeader(WidgetItem *item) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1983 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtpropertybrowser.h" +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtPropertyPrivate +{ +public: + QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {} + QtProperty *q_ptr; + + QSet m_parentItems; + QList m_subItems; + + QString m_toolTip; + QString m_statusTip; + QString m_whatsThis; + QString m_name; + bool m_enabled; + bool m_modified; + + QtAbstractPropertyManager * const m_manager; +}; + +class QtAbstractPropertyManagerPrivate +{ + QtAbstractPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyManager) +public: + void propertyDestroyed(QtProperty *property); + void propertyChanged(QtProperty *property) const; + void propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const; + void propertyInserted(QtProperty *property, QtProperty *parentProperty, + QtProperty *afterProperty) const; + + QSet m_properties; +}; + +/*! + \class QtProperty + + \brief The QtProperty class encapsulates an instance of a property. + + Properties are created by objects of QtAbstractPropertyManager + subclasses; a manager can create properties of a given type, and + is used in conjunction with the QtAbstractPropertyBrowser class. A + property is always owned by the manager that created it, which can + be retrieved using the propertyManager() function. + + QtProperty contains the most common property attributes, and + provides functions for retrieving as well as setting their values: + + \table + \header \o Getter \o Setter + \row + \o propertyName() \o setPropertyName() + \row + \o statusTip() \o setStatusTip() + \row + \o toolTip() \o setToolTip() + \row + \o whatsThis() \o setWhatsThis() + \row + \o isEnabled() \o setEnabled() + \row + \o isModified() \o setModified() + \row + \o valueText() \o Nop + \row + \o valueIcon() \o Nop + \endtable + + It is also possible to nest properties: QtProperty provides the + addSubProperty(), insertSubProperty() and removeSubProperty() functions to + manipulate the set of subproperties. Use the subProperties() + function to retrieve a property's current set of subproperties. + Note that nested properties are not owned by the parent property, + i.e. each subproperty is owned by the manager that created it. + + \sa QtAbstractPropertyManager, QtBrowserItem +*/ + +/*! + Creates a property with the given \a manager. + + This constructor is only useful when creating a custom QtProperty + subclass (e.g. QtVariantProperty). To create a regular QtProperty + object, use the QtAbstractPropertyManager::addProperty() + function instead. + + \sa QtAbstractPropertyManager::addProperty() +*/ +QtProperty::QtProperty(QtAbstractPropertyManager *manager) +{ + d_ptr = new QtPropertyPrivate(manager); + d_ptr->q_ptr = this; +} + +/*! + Destroys this property. + + Note that subproperties are detached but not destroyed, i.e. they + can still be used in another context. + + \sa QtAbstractPropertyManager::clear() + +*/ +QtProperty::~QtProperty() +{ + QSetIterator itParent(d_ptr->m_parentItems); + while (itParent.hasNext()) { + QtProperty *property = itParent.next(); + property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property); + } + + d_ptr->m_manager->d_ptr->propertyDestroyed(this); + + QListIterator itChild(d_ptr->m_subItems); + while (itChild.hasNext()) { + QtProperty *property = itChild.next(); + property->d_ptr->m_parentItems.remove(this); + } + + itParent.toFront(); + while (itParent.hasNext()) { + QtProperty *property = itParent.next(); + property->d_ptr->m_subItems.removeAll(this); + } + delete d_ptr; +} + +/*! + Returns the set of subproperties. + + Note that subproperties are not owned by \e this property, but by + the manager that created them. + + \sa insertSubProperty(), removeSubProperty() +*/ +QList QtProperty::subProperties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns a pointer to the manager that owns this property. +*/ +QtAbstractPropertyManager *QtProperty::propertyManager() const +{ + return d_ptr->m_manager; +} + +/*! + Returns the property's tool tip. + + \sa setToolTip() +*/ +QString QtProperty::toolTip() const +{ + return d_ptr->m_toolTip; +} + +/*! + Returns the property's status tip. + + \sa setStatusTip() +*/ +QString QtProperty::statusTip() const +{ + return d_ptr->m_statusTip; +} + +/*! + Returns the property's "What's This" help text. + + \sa setWhatsThis() +*/ +QString QtProperty::whatsThis() const +{ + return d_ptr->m_whatsThis; +} + +/*! + Returns the property's name. + + \sa setPropertyName() +*/ +QString QtProperty::propertyName() const +{ + return d_ptr->m_name; +} + +/*! + Returns whether the property is enabled. + + \sa setEnabled() +*/ +bool QtProperty::isEnabled() const +{ + return d_ptr->m_enabled; +} + +/*! + Returns whether the property is modified. + + \sa setModified() +*/ +bool QtProperty::isModified() const +{ + return d_ptr->m_modified; +} + +/*! + Returns whether the property has a value. + + \sa QtAbstractPropertyManager::hasValue() +*/ +bool QtProperty::hasValue() const +{ + return d_ptr->m_manager->hasValue(this); +} + +/*! + Returns an icon representing the current state of this property. + + If the given property type can not generate such an icon, this + function returns an invalid icon. + + \sa QtAbstractPropertyManager::valueIcon() +*/ +QIcon QtProperty::valueIcon() const +{ + return d_ptr->m_manager->valueIcon(this); +} + +/*! + Returns a string representing the current state of this property. + + If the given property type can not generate such a string, this + function returns an empty string. + + \sa QtAbstractPropertyManager::valueText() +*/ +QString QtProperty::valueText() const +{ + return d_ptr->m_manager->valueText(this); +} + +/*! + Sets the property's tool tip to the given \a text. + + \sa toolTip() +*/ +void QtProperty::setToolTip(const QString &text) +{ + if (d_ptr->m_toolTip == text) + return; + + d_ptr->m_toolTip = text; + propertyChanged(); +} + +/*! + Sets the property's status tip to the given \a text. + + \sa statusTip() +*/ +void QtProperty::setStatusTip(const QString &text) +{ + if (d_ptr->m_statusTip == text) + return; + + d_ptr->m_statusTip = text; + propertyChanged(); +} + +/*! + Sets the property's "What's This" help text to the given \a text. + + \sa whatsThis() +*/ +void QtProperty::setWhatsThis(const QString &text) +{ + if (d_ptr->m_whatsThis == text) + return; + + d_ptr->m_whatsThis = text; + propertyChanged(); +} + +/*! + \fn void QtProperty::setPropertyName(const QString &name) + + Sets the property's name to the given \a name. + + \sa propertyName() +*/ +void QtProperty::setPropertyName(const QString &text) +{ + if (d_ptr->m_name == text) + return; + + d_ptr->m_name = text; + propertyChanged(); +} + +/*! + Enables or disables the property according to the passed \a enable value. + + \sa isEnabled() +*/ +void QtProperty::setEnabled(bool enable) +{ + if (d_ptr->m_enabled == enable) + return; + + d_ptr->m_enabled = enable; + propertyChanged(); +} + +/*! + Sets the property's modified state according to the passed \a modified value. + + \sa isModified() +*/ +void QtProperty::setModified(bool modified) +{ + if (d_ptr->m_modified == modified) + return; + + d_ptr->m_modified = modified; + propertyChanged(); +} + +/*! + Appends the given \a property to this property's subproperties. + + If the given \a property already is added, this function does + nothing. + + \sa insertSubProperty(), removeSubProperty() +*/ +void QtProperty::addSubProperty(QtProperty *property) +{ + QtProperty *after = 0; + if (d_ptr->m_subItems.count() > 0) + after = d_ptr->m_subItems.last(); + insertSubProperty(property, after); +} + +/*! + \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty) + + Inserts the given \a property after the specified \a + precedingProperty into this property's list of subproperties. If + \a precedingProperty is 0, the specified \a property is inserted + at the beginning of the list. + + If the given \a property already is inserted, this function does + nothing. + + \sa addSubProperty(), removeSubProperty() +*/ +void QtProperty::insertSubProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return; + + if (property == this) + return; + + // traverse all children of item. if this item is a child of item then cannot add. + QList pendingList = property->subProperties(); + QMap visited; + while (!pendingList.isEmpty()) { + QtProperty *i = pendingList.first(); + if (i == this) + return; + pendingList.removeFirst(); + if (visited.contains(i)) + continue; + visited[i] = true; + pendingList += i->subProperties(); + } + + pendingList = subProperties(); + int pos = 0; + int newPos = 0; + QtProperty *properAfterProperty = 0; + while (pos < pendingList.count()) { + QtProperty *i = pendingList.at(pos); + if (i == property) + return; // if item is already inserted in this item then cannot add. + if (i == afterProperty) { + newPos = pos + 1; + properAfterProperty = afterProperty; + } + pos++; + } + + d_ptr->m_subItems.insert(newPos, property); + property->d_ptr->m_parentItems.insert(this); + + d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty); +} + +/*! + Removes the given \a property from the list of subproperties + without deleting it. + + \sa addSubProperty(), insertSubProperty() +*/ +void QtProperty::removeSubProperty(QtProperty *property) +{ + if (!property) + return; + + d_ptr->m_manager->d_ptr->propertyRemoved(property, this); + + QList pendingList = subProperties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); + property->d_ptr->m_parentItems.remove(this); + + return; + } + pos++; + } +} + +/*! + \internal +*/ +void QtProperty::propertyChanged() +{ + d_ptr->m_manager->d_ptr->propertyChanged(this); +} + +//////////////////////////////// + +void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property) +{ + if (m_properties.contains(property)) { + emit q_ptr->propertyDestroyed(property); + q_ptr->uninitializeProperty(property); + m_properties.remove(property); + } +} + +void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const +{ + emit q_ptr->propertyChanged(property); +} + +void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const +{ + emit q_ptr->propertyRemoved(property, parentProperty); +} + +void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) const +{ + emit q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +/*! + \class QtAbstractPropertyManager + + \brief The QtAbstractPropertyManager provides an interface for + property managers. + + A manager can create and manage properties of a given type, and is + used in conjunction with the QtAbstractPropertyBrowser class. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + The QtAbstractPropertyManager class provides common functionality + like creating a property using the addProperty() function, and + retrieving the properties created by the manager using the + properties() function. The class also provides signals that are + emitted when the manager's properties change: propertyInserted(), + propertyRemoved(), propertyChanged() and propertyDestroyed(). + + QtAbstractPropertyManager subclasses are supposed to provide their + own type specific API. Note that several ready-made + implementations are available: + + \list + \o QtBoolPropertyManager + \o QtColorPropertyManager + \o QtDatePropertyManager + \o QtDateTimePropertyManager + \o QtDoublePropertyManager + \o QtEnumPropertyManager + \o QtFlagPropertyManager + \o QtFontPropertyManager + \o QtGroupPropertyManager + \o QtIntPropertyManager + \o QtPointPropertyManager + \o QtRectPropertyManager + \o QtSizePropertyManager + \o QtSizePolicyPropertyManager + \o QtStringPropertyManager + \o QtTimePropertyManager + \o QtVariantPropertyManager + \endlist + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty, + QtProperty *parentProperty, QtProperty *precedingProperty) + + This signal is emitted when a new subproperty is inserted into an + existing property, passing pointers to the \a newProperty, \a + parentProperty and \a precedingProperty as parameters. + + If \a precedingProperty is 0, the \a newProperty was inserted at + the beginning of the \a parentProperty's subproperties list. + + Note that signal is emitted only if the \a parentProperty is created + by this manager. + + \sa QtAbstractPropertyBrowser::itemInserted() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property) + + This signal is emitted whenever a property's data changes, passing + a pointer to the \a property as parameter. + + Note that signal is only emitted for properties that are created by + this manager. + + \sa QtAbstractPropertyBrowser::itemChanged() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent) + + This signal is emitted when a subproperty is removed, passing + pointers to the removed \a property and the \a parent property as + parameters. + + Note that signal is emitted only when the \a parent property is + created by this manager. + + \sa QtAbstractPropertyBrowser::itemRemoved() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property) + + This signal is emitted when the specified \a property is about to + be destroyed. + + Note that signal is only emitted for properties that are created + by this manager. + + \sa clear(), uninitializeProperty() +*/ + +/*! + \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current) + + This signal is emitted when the current item changes. The current item is specified by \a current. + + \sa QtAbstractPropertyBrowser::setCurrentItem() +*/ + +/*! + Creates an abstract property manager with the given \a parent. +*/ +QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent) + : QObject(parent) +{ + d_ptr = new QtAbstractPropertyManagerPrivate; + d_ptr->q_ptr = this; + +} + +/*! + Destroys the manager. All properties created by the manager are + destroyed. +*/ +QtAbstractPropertyManager::~QtAbstractPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Destroys all the properties that this manager has created. + + \sa propertyDestroyed(), uninitializeProperty() +*/ +void QtAbstractPropertyManager::clear() const +{ + while (!properties().isEmpty()) { + QSetIterator itProperty(properties()); + QtProperty *prop = itProperty.next(); + delete prop; + } +} + +/*! + Returns the set of properties created by this manager. + + \sa addProperty() +*/ +QSet QtAbstractPropertyManager::properties() const +{ + return d_ptr->m_properties; +} + +/*! + Returns whether the given \a property has a value. + + The default implementation of this function returns true. + + \sa QtProperty::hasValue() +*/ +bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const +{ + Q_UNUSED(property) + return true; +} + +/*! + Returns an icon representing the current state of the given \a + property. + + The default implementation of this function returns an invalid + icon. + + \sa QtProperty::valueIcon() +*/ +QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const +{ + Q_UNUSED(property) + return QIcon(); +} + +/*! + Returns a string representing the current state of the given \a + property. + + The default implementation of this function returns an empty + string. + + \sa QtProperty::valueText() +*/ +QString QtAbstractPropertyManager::valueText(const QtProperty *property) const +{ + Q_UNUSED(property) + return QString(); +} + +/*! + Creates a property with the given \a name which then is owned by this manager. + + Internally, this function calls the createProperty() and + initializeProperty() functions. + + \sa initializeProperty(), properties() +*/ +QtProperty *QtAbstractPropertyManager::addProperty(const QString &name) +{ + QtProperty *property = createProperty(); + if (property) { + property->setPropertyName(name); + d_ptr->m_properties.insert(property); + initializeProperty(property); + } + return property; +} + +/*! + Creates a property. + + The base implementation produce QtProperty instances; Reimplement + this function to make this manager produce objects of a QtProperty + subclass. + + \sa addProperty(), initializeProperty() +*/ +QtProperty *QtAbstractPropertyManager::createProperty() +{ + return new QtProperty(this); +} + +/*! + \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0 + + This function is called whenever a new valid property pointer has + been created, passing the pointer as parameter. + + The purpose is to let the manager know that the \a property has + been created so that it can provide additional attributes for the + new property, e.g. QtIntPropertyManager adds \l + {QtIntPropertyManager::value()}{value}, \l + {QtIntPropertyManager::minimum()}{minimum} and \l + {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager + subclass adds type specific attributes, this function is pure + virtual and must be reimplemented when deriving from the + QtAbstractPropertyManager class. + + \sa addProperty(), createProperty() +*/ + +/*! + This function is called just before the specified \a property is destroyed. + + The purpose is to let the property manager know that the \a + property is being destroyed so that it can remove the property's + additional attributes. + + \sa clear(), propertyDestroyed() +*/ +void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +//////////////////////////////////// + +/*! + \class QtAbstractEditorFactoryBase + + \brief The QtAbstractEditorFactoryBase provides an interface for + editor factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + Typically, an editor factory is created by subclassing the + QtAbstractEditorFactory template class which inherits + QtAbstractEditorFactoryBase. But note that several ready-made + implementations are available: + + \list + \o QtCheckBoxFactory + \o QtDateEditFactory + \o QtDateTimeEditFactory + \o QtDoubleSpinBoxFactory + \o QtEnumEditorFactory + \o QtLineEditFactory + \o QtScrollBarFactory + \o QtSliderFactory + \o QtSpinBoxFactory + \o QtTimeEditFactory + \o QtVariantEditorFactory + \endlist + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget (with the given \a parent) for the given + \a property. + + This function is reimplemented in QtAbstractEditorFactory template class + which also provides a pure virtual convenience overload of this + function enabling access to the property's manager. + + \sa QtAbstractEditorFactory::createEditor() +*/ + +/*! + \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0) + + Creates an abstract editor factory with the given \a parent. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0 + + \internal + + Detaches property manager from factory. + This method is reimplemented in QtAbstractEditorFactory template subclass. + You don't need to reimplement it in your subclasses. Instead implement more convenient + QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0 + + \internal + + This method is called when property manager is being destroyed. + Basically it notifies factory not to produce editors for properties owned by \a manager. + You don't need to reimplement it in your subclass. This method is implemented in + QtAbstractEditorFactory template subclass. +*/ + +/*! + \class QtAbstractEditorFactory + + \brief The QtAbstractEditorFactory is the base template class for editor + factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + Note that the QtAbstractEditorFactory functions are using the + PropertyManager template argument class which can be any + QtAbstractPropertyManager subclass. For example: + + \code + QtSpinBoxFactory *factory; + QSet managers = factory->propertyManagers(); + \endcode + + Note that QtSpinBoxFactory by definition creates editing widgets + \e only for properties created by QtIntPropertyManager. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser will + use these associations to determine which factories it should use + to create the preferred editing widgets. + + A QtAbstractEditorFactory object is capable of producing editors for + several property managers at the same time. To create an + association between this factory and a given manager, use the + addPropertyManager() function. Use the removePropertyManager() function to make + this factory stop producing editors for a given property + manager. Use the propertyManagers() function to retrieve the set of + managers currently associated with this factory. + + Several ready-made implementations of the QtAbstractEditorFactory class + are available: + + \list + \o QtCheckBoxFactory + \o QtDateEditFactory + \o QtDateTimeEditFactory + \o QtDoubleSpinBoxFactory + \o QtEnumEditorFactory + \o QtLineEditFactory + \o QtScrollBarFactory + \o QtSliderFactory + \o QtSpinBoxFactory + \o QtTimeEditFactory + \o QtVariantEditorFactory + \endlist + + When deriving from the QtAbstractEditorFactory class, several pure virtual + functions must be implemented: the connectPropertyManager() function is + used by the factory to connect to the given manager's signals, the + createEditor() function is supposed to create an editor for the + given property controlled by the given manager, and finally the + disconnectPropertyManager() function is used by the factory to disconnect + from the specified manager's signals. + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager +*/ + +/*! + \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0) + + Creates an editor factory with the given \a parent. + + \sa addPropertyManager() +*/ + +/*! + \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent) + + Creates an editing widget (with the given \a parent) for the given + \a property. +*/ + +/*! + \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager) + + Adds the given \a manager to this factory's set of managers, + making this factory produce editing widgets for properties created + by the given manager. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers(), removePropertyManager() +*/ + +/*! + \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager) + + Removes the given \a manager from this factory's set of + managers. The PropertyManager type is a template argument class, and may be + any QtAbstractPropertyManager subclass. + + \sa propertyManagers(), addPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0 + + Connects this factory to the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the addPropertyManager() function, and + makes it possible to update an editing widget when the associated + property's data changes. This is typically done in custom slots + responding to the signals emitted by the property's manager, + e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa propertyManagers(), disconnectPropertyManager() +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget with the given \a parent for the + specified \a property created by the given \a manager. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function must be implemented in derived classes: It is + recommended to store a pointer to the widget and map it to the + given \a property, since the widget must be updated whenever the + associated property's data changes. This is typically done in + custom slots responding to the signals emitted by the property's + manager, e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa connectPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0 + + Disconnects this factory from the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the removePropertyManager() function. + + \sa propertyManagers(), connectPropertyManager() +*/ + +/*! + \fn QSet QtAbstractEditorFactory::propertyManagers() const + + Returns the factory's set of associated managers. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + \sa addPropertyManager(), removePropertyManager() +*/ + +/*! + \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const + + Returns the property manager for the given \a property, or 0 if + the given \a property doesn't belong to any of this factory's + registered managers. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager) + + \internal + \reimp +*/ + +//////////////////////////////////// +class QtBrowserItemPrivate +{ +public: + QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) + : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {} + + void addChild(QtBrowserItem *index, QtBrowserItem *after); + void removeChild(QtBrowserItem *index); + + QtAbstractPropertyBrowser * const m_browser; + QtProperty *m_property; + QtBrowserItem *m_parent; + + QtBrowserItem *q_ptr; + + QList m_children; + +}; + +void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after) +{ + if (m_children.contains(index)) + return; + int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0; + m_children.insert(idx, index); +} + +void QtBrowserItemPrivate::removeChild(QtBrowserItem *index) +{ + m_children.removeAll(index); +} + + +/*! + \class QtBrowserItem + + \brief The QtBrowserItem class represents a property in + a property browser instance. + + Browser items are created whenever a QtProperty is inserted to the + property browser. A QtBrowserItem uniquely identifies a + browser's item. Thus, if the same QtProperty is inserted multiple + times, each occurrence gets its own unique QtBrowserItem. The + items are owned by QtAbstractPropertyBrowser and automatically + deleted when they are removed from the browser. + + You can traverse a browser's properties by calling parent() and + children(). The property and the browser associated with an item + are available as property() and browser(). + + \sa QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + Returns the property which is accosiated with this item. Note that + several items can be associated with the same property instance in + the same property browser. + + \sa QtAbstractPropertyBrowser::items() +*/ + +QtProperty *QtBrowserItem::property() const +{ + return d_ptr->m_property; +} + +/*! + Returns the parent item of \e this item. Returns 0 if \e this item + is associated with top-level property in item's property browser. + + \sa children() +*/ + +QtBrowserItem *QtBrowserItem::parent() const +{ + return d_ptr->m_parent; +} + +/*! + Returns the children items of \e this item. The properties + reproduced from children items are always the same as + reproduced from associated property' children, for example: + + \code + QtBrowserItem *item; + QList childrenItems = item->children(); + + QList childrenProperties = item->property()->subProperties(); + \endcode + + The \e childrenItems list represents the same list as \e childrenProperties. +*/ + +QList QtBrowserItem::children() const +{ + return d_ptr->m_children; +} + +/*! + Returns the property browser which owns \e this item. +*/ + +QtAbstractPropertyBrowser *QtBrowserItem::browser() const +{ + return d_ptr->m_browser; +} + +QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) +{ + d_ptr = new QtBrowserItemPrivate(browser, property, parent); + d_ptr->q_ptr = this; +} + +QtBrowserItem::~QtBrowserItem() +{ + delete d_ptr; +} + + +//////////////////////////////////// + +typedef QMap > Map1; +typedef QMap > > Map2; +Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory) +Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews) + + /* +class QtAbstractPropertyBrowserPrivate +{ + QtAbstractPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser) +public: + QtAbstractPropertyBrowserPrivate(); + + void insertSubTree(QtProperty *property, + QtProperty *parentProperty); + void removeSubTree(QtProperty *property, + QtProperty *parentProperty); + void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty); + void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty); + QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex); + void removeBrowserIndex(QtBrowserItem *index); + void clearIndex(QtBrowserItem *index); + + void slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty); + void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty); + void slotPropertyDestroyed(QtProperty *property); + void slotPropertyDataChanged(QtProperty *property); + + QList m_subItems; + QMap > m_managerToProperties; + QMap > m_propertyToParents; + + QMap m_topLevelPropertyToIndex; + QList m_topLevelIndexes; + QMap > m_propertyToIndexes; + + QtBrowserItem *m_currentItem; +}; +*/ + +QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() : + m_currentItem(0) +{ +} + +void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (m_propertyToParents.contains(property)) { + // property was already inserted, so its manager is connected + // and all its children are inserted and theirs managers are connected + // we just register new parent (parent has to be new). + m_propertyToParents[property].append(parentProperty); + // don't need to update m_managerToProperties map since + // m_managerToProperties[manager] already contains property. + return; + } + QtAbstractPropertyManager *manager = property->propertyManager(); + if (m_managerToProperties[manager].isEmpty()) { + // connect manager's signals + q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty *)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty *)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty *))); + } + m_managerToProperties[manager].append(property); + m_propertyToParents[property].append(parentProperty); + + QList subList = property->subProperties(); + QListIterator itSub(subList); + while (itSub.hasNext()) { + QtProperty *subProperty = itSub.next(); + insertSubTree(subProperty, property); + } +} + +void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(property)) { + // ASSERT + return; + } + + m_propertyToParents[property].removeAll(parentProperty); + if (!m_propertyToParents[property].isEmpty()) + return; + + m_propertyToParents.remove(property); + QtAbstractPropertyManager *manager = property->propertyManager(); + m_managerToProperties[manager].removeAll(property); + if (m_managerToProperties[manager].isEmpty()) { + // disconnect manager's signals + q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty *)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty *)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty *))); + + m_managerToProperties.remove(manager); + } + + QList subList = property->subProperties(); + QListIterator itSub(subList); + while (itSub.hasNext()) { + QtProperty *subProperty = itSub.next(); + removeSubTree(subProperty, property); + } +} + +void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty) +{ + QMap parentToAfter; + if (afterProperty) { + QMap >::ConstIterator it = + m_propertyToIndexes.find(afterProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + parentToAfter[idx->parent()] = idx; + } + } else if (parentProperty) { + QMap >::ConstIterator it = + m_propertyToIndexes.find(parentProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + parentToAfter[idx] = 0; + } + } else { + parentToAfter[0] = 0; + } + + const QMap::ConstIterator pcend = parentToAfter.constEnd(); + for (QMap::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it) + createBrowserIndex(property, it.key(), it.value()); +} + +QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property, + QtBrowserItem *parentIndex, QtBrowserItem *afterIndex) +{ + QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex); + if (parentIndex) { + parentIndex->d_ptr->addChild(newIndex, afterIndex); + } else { + m_topLevelPropertyToIndex[property] = newIndex; + m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex); + } + m_propertyToIndexes[property].append(newIndex); + + q_ptr->itemInserted(newIndex, afterIndex); + + QList subItems = property->subProperties(); + QListIterator itChild(subItems); + QtBrowserItem *afterChild = 0; + while (itChild.hasNext()) { + QtProperty *child = itChild.next(); + afterChild = createBrowserIndex(child, newIndex, afterChild); + } + return newIndex; +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty) +{ + QList toRemove; + QMap >::ConstIterator it = + m_propertyToIndexes.find(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + toRemove.append(idx); + } + + QListIterator itRemove(toRemove); + while (itRemove.hasNext()) { + QtBrowserItem *index = itRemove.next(); + removeBrowserIndex(index); + } +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index) +{ + QList children = index->children(); + for (int i = children.count(); i > 0; i--) { + removeBrowserIndex(children.at(i - 1)); + } + + q_ptr->itemRemoved(index); + + if (index->parent()) { + index->parent()->d_ptr->removeChild(index); + } else { + m_topLevelPropertyToIndex.remove(index->property()); + m_topLevelIndexes.removeAll(index); + } + + QtProperty *property = index->property(); + + m_propertyToIndexes[property].removeAll(index); + if (m_propertyToIndexes[property].isEmpty()) + m_propertyToIndexes.remove(property); + + delete index; +} + +void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index) +{ + QList children = index->children(); + QListIterator itChild(children); + while (itChild.hasNext()) { + clearIndex(itChild.next()); + } + delete index; +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + createBrowserIndexes(property, parentProperty, afterProperty); + insertSubTree(property, parentProperty); + //q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call + //q_ptr->propertyRemoved(property, parentProperty); + removeBrowserIndexes(property, parentProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (!m_subItems.contains(property)) + return; + q_ptr->removeProperty(property); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property) +{ + if (!m_propertyToParents.contains(property)) + return; + + QMap >::ConstIterator it = + m_propertyToIndexes.find(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + q_ptr->itemChanged(idx); + } + //q_ptr->propertyChanged(property); +} + +/*! + \class QtAbstractPropertyBrowser + + \brief QtAbstractPropertyBrowser provides a base class for + implementing property browsers. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + \image qtpropertybrowser.png + + The top level properties can be retrieved using the + properties() function. To traverse each property's + subproperties, use the QtProperty::subProperties() function. In + addition, the set of top level properties can be manipulated using + the addProperty(), insertProperty() and removeProperty() + functions. Note that the QtProperty class provides a corresponding + set of functions making it possible to manipulate the set of + subproperties as well. + + To remove all the properties from the property browser widget, use + the clear() function. This function will clear the editor, but it + will not delete the properties since they can still be used in + other editors. + + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. A manager + can handle (i.e. create and manage) properties of a given type. In + the property browser the managers are associated with + implementations of the QtAbstractEditorFactory: A factory is a + class able to create an editing widget of a specified type. + + When using a property browser widget, managers must be created for + each of the required property types before the properties + themselves can be created. To ensure that the properties' values + will be displayed using suitable editing widgets, the managers + must be associated with objects of the preferred factory + implementations using the setFactoryForManager() function. The + property browser will use these associations to determine which + factory it should use to create the preferred editing widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory within the + context of a single property browser. The associations between + managers and factories can at any time be removed using the + unsetFactoryForManager() function. + + Whenever the property data changes or a property is inserted or + removed, the itemChanged(), itemInserted() or + itemRemoved() functions are called, respectively. These + functions must be reimplemented in derived classes in order to + update the property browser widget. Be aware that some property + instances can appear several times in an abstract tree + structure. For example: + + \table 100% + \row + \o + \code + QtProperty *property1, *property2, *property3; + + property2->addSubProperty(property1); + property3->addSubProperty(property2); + + QtAbstractPropertyBrowser *editor; + + editor->addProperty(property1); + editor->addProperty(property2); + editor->addProperty(property3); + \endcode + \o \image qtpropertybrowser-duplicate.png + \endtable + + The addProperty() function returns a QtBrowserItem that uniquely + identifies the created item. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Note that there are two ready-made property browser + implementations: + + \list + \o QtGroupBoxPropertyBrowser + \o QtTreePropertyBrowser + \endlist + + \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase +*/ + +/*! + \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) + + Connects the given \a manager to the given \a factory, ensuring + that properties of the \a manager's type will be displayed with an + editing widget suitable for their value. + + For example: + + \code + QtIntPropertyManager *intManager; + QtDoublePropertyManager *doubleManager; + + QtProperty *myInteger = intManager->addProperty(); + QtProperty *myDouble = doubleManager->addProperty(); + + QtSpinBoxFactory *spinBoxFactory; + QtDoubleSpinBoxFactory *doubleSpinBoxFactory; + + QtAbstractPropertyBrowser *editor; + editor->setFactoryForManager(intManager, spinBoxFactory); + editor->setFactoryForManager(doubleManager, doubleSpinBoxFactory); + + editor->addProperty(myInteger); + editor->addProperty(myDouble); + \endcode + + In this example the \c myInteger property's value is displayed + with a QSpinBox widget, while the \c myDouble property's value is + displayed with a QDoubleSpinBox widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory. If the + given \a manager already is associated with another factory, the + old association is broken before the new one established. + + This function ensures that the given \a manager and the given \a + factory are compatible, and it automatically calls the + QtAbstractEditorFactory::addPropertyManager() function if necessary. + + \sa unsetFactoryForManager() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem, + QtBrowserItem *precedingItem) = 0 + + This function is called to update the widget whenever a property + is inserted or added to the property browser, passing pointers to + the \a insertedItem of property and the specified + \a precedingItem as parameters. + + If \a precedingItem is 0, the \a insertedItem was put at + the beginning of its parent item's list of subproperties. If + the parent of \a insertedItem is 0, the \a insertedItem was added as a top + level property of \e this property browser. + + This function must be reimplemented in derived classes. Note that + if the \a insertedItem's property has subproperties, this + method will be called for those properties as soon as the current call is finished. + + \sa insertProperty(), addProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0 + + This function is called to update the widget whenever a property + is removed from the property browser, passing the pointer to the + \a item of the property as parameters. The passed \a item is + deleted just after this call is finished. + + If the the parent of \a item is 0, the removed \a item was a + top level property in this editor. + + This function must be reimplemented in derived classes. Note that + if the removed \a item's property has subproperties, this + method will be called for those properties just before the current call is started. + + \sa removeProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0 + + This function is called whenever a property's data changes, + passing a pointer to the \a item of property as parameter. + + This function must be reimplemented in derived classes in order to + update the property browser widget whenever a property's name, + tool tip, status tip, "what's this" text, value text or value icon + changes. + + Note that if the property browser contains several occurrences of + the same property, this method will be called once for each + occurrence (with a different item each time). + + \sa QtProperty, items() +*/ + +/*! + Creates an abstract property browser with the given \a parent. +*/ +QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent) + : QWidget(parent) +{ + d_ptr = new QtAbstractPropertyBrowserPrivate; + d_ptr->q_ptr = this; + +} + +/*! + Destroys the property browser, and destroys all the items that were + created by this property browser. + + Note that the properties that were displayed in the editor are not + deleted since they still can be used in other editors. Neither + does the destructor delete the property managers and editor + factories that were used by this property browser widget unless + this widget was their parent. + + \sa QtAbstractPropertyManager::~QtAbstractPropertyManager() +*/ +QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser() +{ + QList indexes = topLevelItems(); + QListIterator itItem(indexes); + while (itItem.hasNext()) + d_ptr->clearIndex(itItem.next()); + delete d_ptr; +} + +/*! + Returns the property browser's list of top level properties. + + To traverse the subproperties, use the QtProperty::subProperties() + function. + + \sa addProperty(), insertProperty(), removeProperty() +*/ +QList QtAbstractPropertyBrowser::properties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns the property browser's list of all items associated + with the given \a property. + + There is one item per instance of the property in the browser. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::items(QtProperty *property) const +{ + return d_ptr->m_propertyToIndexes.value(property); +} + +/*! + Returns the top-level items associated with the given \a property. + + Returns 0 if \a property wasn't inserted into this property + browser or isn't a top-level one. + + \sa topLevelItems(), items() +*/ + +QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const +{ + return d_ptr->m_topLevelPropertyToIndex.value(property); +} + +/*! + Returns the list of top-level items. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::topLevelItems() const +{ + return d_ptr->m_topLevelIndexes; +} + +/*! + Removes all the properties from the editor, but does not delete + them since they can still be used in other editors. + + \sa removeProperty(), QtAbstractPropertyManager::clear() +*/ +void QtAbstractPropertyBrowser::clear() +{ + QList subList = properties(); + QListIterator itSub(subList); + itSub.toBack(); + while (itSub.hasPrevious()) { + QtProperty *property = itSub.previous(); + removeProperty(property); + } +} + +/*! + Appends the given \a property (and its subproperties) to the + property browser's list of top level properties. Returns the item + created by property browser which is associated with the \a property. + In order to get all children items created by the property + browser in this call, the returned item should be traversed. + + If the specified \a property is already added, this function does + nothing and returns 0. + + \sa insertProperty(), QtProperty::addSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property) +{ + QtProperty *afterProperty = 0; + if (d_ptr->m_subItems.count() > 0) + afterProperty = d_ptr->m_subItems.last(); + return insertProperty(property, afterProperty); +} + +/*! + \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) + + Inserts the given \a property (and its subproperties) after + the specified \a afterProperty in the browser's list of top + level properties. Returns item created by property browser which + is associated with the \a property. In order to get all children items + created by the property browser in this call returned item should be traversed. + + If the specified \a afterProperty is 0, the given \a property is + inserted at the beginning of the list. If \a property is + already inserted, this function does nothing and returns 0. + + \sa addProperty(), QtProperty::insertSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return 0; + + // if item is already inserted in this item then cannot add. + QList pendingList = properties(); + int pos = 0; + int newPos = 0; + QtProperty *properAfterProperty = 0; + while (pos < pendingList.count()) { + QtProperty *prop = pendingList.at(pos); + if (prop == property) + return 0; + if (prop == afterProperty) { + newPos = pos + 1; + properAfterProperty = afterProperty; + } + pos++; + } + d_ptr->createBrowserIndexes(property, 0, afterProperty); + + // traverse inserted subtree and connect to manager's signals + d_ptr->insertSubTree(property, 0); + + d_ptr->m_subItems.insert(newPos, property); + //propertyInserted(property, 0, properAfterProperty); + return topLevelItem(property); +} + +/*! + Removes the specified \a property (and its subproperties) from the + property browser's list of top level properties. All items + that were associated with the given \a property and its children + are deleted. + + Note that the properties are \e not deleted since they can still + be used in other editors. + + \sa clear(), QtProperty::removeSubProperty(), properties() +*/ +void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) +{ + if (!property) + return; + + QList pendingList = properties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); //perhaps this two lines + d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call. + //propertyRemoved(property, 0); + + d_ptr->removeBrowserIndexes(property, 0); + + // when item is deleted, item will call removeItem for top level items, + // and itemRemoved for nested items. + + return; + } + pos++; + } +} + +/*! + Creates an editing widget (with the given \a parent) for the given + \a property according to the previously established associations + between property managers and editor factories. + + If the property is created by a property manager which was not + associated with any of the existing factories in \e this property + editor, the function returns 0. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Reimplement this function to provide additional decoration for the + editing widgets created by the installed factories. + + \sa setFactoryForManager() +*/ +QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property, + QWidget *parent) +{ + QtAbstractEditorFactoryBase *factory = 0; + QtAbstractPropertyManager *manager = property->propertyManager(); + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(manager)) { + factory = (*m_viewToManagerToFactory())[this][manager]; + } + + if (!factory) + return 0; + return factory->createEditor(property, parent); +} + +bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory) +{ + bool connectNeeded = false; + if (!m_managerToFactoryToViews()->contains(abstractManager) || + !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) { + connectNeeded = true; + } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory] + .contains(this)) { + return connectNeeded; + } + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(abstractManager)) { + unsetFactoryForManager(abstractManager); + } + + (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this); + (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory; + + return connectNeeded; +} + +/*! + Removes the association between the given \a manager and the + factory bound to it, automatically calling the + QtAbstractEditorFactory::removePropertyManager() function if necessary. + + \sa setFactoryForManager() +*/ +void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager) +{ + if (!m_viewToManagerToFactory()->contains(this) || + !(*m_viewToManagerToFactory())[this].contains(manager)) { + return; + } + + QtAbstractEditorFactoryBase *abstractFactory = + (*m_viewToManagerToFactory())[this][manager]; + (*m_viewToManagerToFactory())[this].remove(manager); + if ((*m_viewToManagerToFactory())[this].isEmpty()) { + (*m_viewToManagerToFactory()).remove(this); + } + + (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this); + if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) { + (*m_managerToFactoryToViews())[manager].remove(abstractFactory); + abstractFactory->breakConnection(manager); + if ((*m_managerToFactoryToViews())[manager].isEmpty()) { + (*m_managerToFactoryToViews()).remove(manager); + } + } +} + +/*! + Returns the current item in the property browser. + + \sa setCurrentItem() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const +{ + return d_ptr->m_currentItem; +} + +/*! + Sets the current item in the property browser to \a item. + + \sa currentItem(), currentItemChanged() +*/ +void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item) +{ + QtBrowserItem *oldItem = d_ptr->m_currentItem; + d_ptr->m_currentItem = item; + if (oldItem != item) + emit currentItemChanged(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qtpropertybrowser.cpp" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.h 2012-02-21 23:06:08.000000000 +0000 @@ -0,0 +1,365 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTPROPERTYBROWSER_H +#define QTPROPERTYBROWSER_H + +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +#if defined(Q_WS_WIN) +# if !defined(QT_QTPROPERTYBROWSER_EXPORT) && !defined(QT_QTPROPERTYBROWSER_IMPORT) +# define QT_QTPROPERTYBROWSER_EXPORT +# elif defined(QT_QTPROPERTYBROWSER_IMPORT) +# if defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# endif +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllimport) +# elif defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTPROPERTYBROWSER_EXPORT +#endif + + +class QtAbstractPropertyManager; +class QtPropertyPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtProperty +{ +public: + virtual ~QtProperty(); + + QList subProperties() const; + + QtAbstractPropertyManager *propertyManager() const; + + QString toolTip() const; + QString statusTip() const; + QString whatsThis() const; + QString propertyName() const; + bool isEnabled() const; + bool isModified() const; + + bool hasValue() const; + QIcon valueIcon() const; + QString valueText() const; + + void setToolTip(const QString &text); + void setStatusTip(const QString &text); + void setWhatsThis(const QString &text); + void setPropertyName(const QString &text); + void setEnabled(bool enable); + void setModified(bool modified); + + void addSubProperty(QtProperty *property); + void insertSubProperty(QtProperty *property, QtProperty *afterProperty); + void removeSubProperty(QtProperty *property); +protected: + explicit QtProperty(QtAbstractPropertyManager *manager); + void propertyChanged(); +private: + friend class QtAbstractPropertyManager; + QtPropertyPrivate *d_ptr; +}; + +class QtAbstractPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyManager : public QObject +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyManager(QObject *parent = 0); + ~QtAbstractPropertyManager(); + + QSet properties() const; + void clear() const; + + QtProperty *addProperty(const QString &name = QString()); +Q_SIGNALS: + + void propertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after); + void propertyChanged(QtProperty *property); + void propertyRemoved(QtProperty *property, QtProperty *parent); + void propertyDestroyed(QtProperty *property); +protected: + virtual bool hasValue(const QtProperty *property) const; + virtual QIcon valueIcon(const QtProperty *property) const; + virtual QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property) = 0; + virtual void uninitializeProperty(QtProperty *property); + virtual QtProperty *createProperty(); +private: + friend class QtProperty; + QtAbstractPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyManager) + Q_DISABLE_COPY(QtAbstractPropertyManager) +}; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractEditorFactoryBase : public QObject +{ + Q_OBJECT +public: + virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0; +protected: + explicit QtAbstractEditorFactoryBase(QObject *parent = 0) + : QObject(parent) {} + + virtual void breakConnection(QtAbstractPropertyManager *manager) = 0; +protected Q_SLOTS: + virtual void managerDestroyed(QObject *manager) = 0; + + friend class QtAbstractPropertyBrowser; +}; + +template +class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase +{ +public: + explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {} + QWidget *createEditor(QtProperty *property, QWidget *parent) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *manager = it.next(); + if (manager == property->propertyManager()) { + return createEditor(manager, property, parent); + } + } + return 0; + } + void addPropertyManager(PropertyManager *manager) + { + if (m_managers.contains(manager)) + return; + m_managers.insert(manager); + connectPropertyManager(manager); + connect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + } + void removePropertyManager(PropertyManager *manager) + { + if (!m_managers.contains(manager)) + return; + disconnect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + disconnectPropertyManager(manager); + m_managers.remove(manager); + } + QSet propertyManagers() const + { + return m_managers; + } + PropertyManager *propertyManager(QtProperty *property) const + { + QtAbstractPropertyManager *manager = property->propertyManager(); + QSetIterator itManager(m_managers); + while (itManager.hasNext()) { + PropertyManager *m = itManager.next(); + if (m == manager) { + return m; + } + } + return 0; + } +protected: + virtual void connectPropertyManager(PropertyManager *manager) = 0; + virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0; + virtual void disconnectPropertyManager(PropertyManager *manager) = 0; + void managerDestroyed(QObject *manager) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *m = it.next(); + if (m == manager) { + m_managers.remove(m); + return; + } + } + } +private: + void breakConnection(QtAbstractPropertyManager *manager) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *m = it.next(); + if (m == manager) { + removePropertyManager(m); + return; + } + } + } +private: + QSet m_managers; + friend class QtAbstractPropertyEditor; +}; + +class QtAbstractPropertyBrowser; +class QtBrowserItemPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBrowserItem +{ +public: + QtProperty *property() const; + QtBrowserItem *parent() const; + QList children() const; + QtAbstractPropertyBrowser *browser() const; +private: + explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent); + ~QtBrowserItem(); + QtBrowserItemPrivate *d_ptr; + friend class QtAbstractPropertyBrowserPrivate; +}; + +class QtAbstractPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyBrowser : public QWidget +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyBrowser(QWidget *parent = 0); + ~QtAbstractPropertyBrowser(); + + QList properties() const; + QList items(QtProperty *property) const; + QtBrowserItem *topLevelItem(QtProperty *property) const; + QList topLevelItems() const; + void clear(); + + template + void setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) { + QtAbstractPropertyManager *abstractManager = manager; + QtAbstractEditorFactoryBase *abstractFactory = factory; + + if (addFactory(abstractManager, abstractFactory)) + factory->addPropertyManager(manager); + } + + void unsetFactoryForManager(QtAbstractPropertyManager *manager); + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *); + +Q_SIGNALS: + void currentItemChanged(QtBrowserItem *); + +public Q_SLOTS: + + QtBrowserItem *addProperty(QtProperty *property); + QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty); + void removeProperty(QtProperty *property); + +protected: + + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0; + virtual void itemRemoved(QtBrowserItem *item) = 0; + // can be tooltip, statustip, whatsthis, name, icon, text. + virtual void itemChanged(QtBrowserItem *item) = 0; + + virtual QWidget *createEditor(QtProperty *property, QWidget *parent); +private: + + bool addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory); + + QtAbstractPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser) + Q_DISABLE_COPY(QtAbstractPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, + QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *)) + +}; + +class QtAbstractPropertyBrowserPrivate +{ + QtAbstractPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser) +public: + QtAbstractPropertyBrowserPrivate(); + + void insertSubTree(QtProperty *property, + QtProperty *parentProperty); + void removeSubTree(QtProperty *property, + QtProperty *parentProperty); + void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty); + void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty); + QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex); + void removeBrowserIndex(QtBrowserItem *index); + void clearIndex(QtBrowserItem *index); + + void slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty); + void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty); + void slotPropertyDestroyed(QtProperty *property); + void slotPropertyDataChanged(QtProperty *property); + + QList m_subItems; + QMap > m_managerToProperties; + QMap > m_propertyToParents; + + QMap m_topLevelPropertyToIndex; + QList m_topLevelIndexes; + QMap > m_propertyToIndexes; + + QtBrowserItem *m_currentItem; +}; + + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif // QTPROPERTYBROWSER_H diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.pro diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.pro --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.pro 2013-05-08 13:20:34.000000000 +0000 @@ -0,0 +1,17 @@ + + + +TEMPLATE = lib +TARGET = qtpropertybrowser + +DESTDIR = ./lib + +CONFIG += staticlib + +HEADERS += *.h + +SOURCES += *.cpp + +RESOURCES += *.qrc + +INCLUDEPATH += ./ \ No newline at end of file diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc 2011-01-20 14:44:30.000000000 +0000 @@ -0,0 +1,23 @@ + + + images/cursor-arrow.png + images/cursor-busy.png + images/cursor-closedhand.png + images/cursor-cross.png + images/cursor-forbidden.png + images/cursor-hand.png + images/cursor-hsplit.png + images/cursor-ibeam.png + images/cursor-openhand.png + images/cursor-sizeall.png + images/cursor-sizeb.png + images/cursor-sizef.png + images/cursor-sizeh.png + images/cursor-sizev.png + images/cursor-uparrow.png + images/cursor-vsplit.png + images/cursor-wait.png + images/cursor-whatsthis.png + + + diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,433 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +QtCursorDatabase::QtCursorDatabase() +{ + appendCursor(Qt::ArrowCursor, QApplication::translate("QtCursorDatabase", "Arrow", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-arrow.png"))); + appendCursor(Qt::UpArrowCursor, QApplication::translate("QtCursorDatabase", "Up Arrow", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-uparrow.png"))); + appendCursor(Qt::CrossCursor, QApplication::translate("QtCursorDatabase", "Cross", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-cross.png"))); + appendCursor(Qt::WaitCursor, QApplication::translate("QtCursorDatabase", "Wait", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-wait.png"))); + appendCursor(Qt::IBeamCursor, QApplication::translate("QtCursorDatabase", "IBeam", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-ibeam.png"))); + appendCursor(Qt::SizeVerCursor, QApplication::translate("QtCursorDatabase", "Size Vertical", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizev.png"))); + appendCursor(Qt::SizeHorCursor, QApplication::translate("QtCursorDatabase", "Size Horizontal", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeh.png"))); + appendCursor(Qt::SizeFDiagCursor, QApplication::translate("QtCursorDatabase", "Size Backslash", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizef.png"))); + appendCursor(Qt::SizeBDiagCursor, QApplication::translate("QtCursorDatabase", "Size Slash", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeb.png"))); + appendCursor(Qt::SizeAllCursor, QApplication::translate("QtCursorDatabase", "Size All", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeall.png"))); + appendCursor(Qt::BlankCursor, QApplication::translate("QtCursorDatabase", "Blank", 0, + QApplication::UnicodeUTF8), QIcon()); + appendCursor(Qt::SplitVCursor, QApplication::translate("QtCursorDatabase", "Split Vertical", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-vsplit.png"))); + appendCursor(Qt::SplitHCursor, QApplication::translate("QtCursorDatabase", "Split Horizontal", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hsplit.png"))); + appendCursor(Qt::PointingHandCursor, QApplication::translate("QtCursorDatabase", "Pointing Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hand.png"))); + appendCursor(Qt::ForbiddenCursor, QApplication::translate("QtCursorDatabase", "Forbidden", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-forbidden.png"))); + appendCursor(Qt::OpenHandCursor, QApplication::translate("QtCursorDatabase", "Open Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-openhand.png"))); + appendCursor(Qt::ClosedHandCursor, QApplication::translate("QtCursorDatabase", "Closed Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-closedhand.png"))); + appendCursor(Qt::WhatsThisCursor, QApplication::translate("QtCursorDatabase", "What's This", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-whatsthis.png"))); + appendCursor(Qt::BusyCursor, QApplication::translate("QtCursorDatabase", "Busy", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png"))); +} + +void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon) +{ + if (m_cursorShapeToValue.contains(shape)) + return; + int value = m_cursorNames.count(); + m_cursorNames.append(name); + m_cursorIcons[value] = icon; + m_valueToCursorShape[value] = shape; + m_cursorShapeToValue[shape] = value; +} + +QStringList QtCursorDatabase::cursorShapeNames() const +{ + return m_cursorNames; +} + +QMap QtCursorDatabase::cursorShapeIcons() const +{ + return m_cursorIcons; +} + +QString QtCursorDatabase::cursorToShapeName(const QCursor &cursor) const +{ + int val = cursorToValue(cursor); + if (val >= 0) + return m_cursorNames.at(val); + return QString(); +} + +QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor &cursor) const +{ + int val = cursorToValue(cursor); + return m_cursorIcons.value(val); +} + +int QtCursorDatabase::cursorToValue(const QCursor &cursor) const +{ +#ifndef QT_NO_CURSOR + Qt::CursorShape shape = cursor.shape(); + if (m_cursorShapeToValue.contains(shape)) + return m_cursorShapeToValue[shape]; +#endif + return -1; +} + +#ifndef QT_NO_CURSOR +QCursor QtCursorDatabase::valueToCursor(int value) const +{ + if (m_valueToCursorShape.contains(value)) + return QCursor(m_valueToCursorShape[value]); + return QCursor(); +} +#endif + +QPixmap QtPropertyBrowserUtils::brushValuePixmap(const QBrush &b) +{ + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + + QPainter painter(&img); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(0, 0, img.width(), img.height(), b); + QColor color = b.color(); + if (color.alpha() != 255) { // indicate alpha by an inset + QBrush opaqueBrush = b; + color.setAlpha(255); + opaqueBrush.setColor(color); + painter.fillRect(img.width() / 4, img.height() / 4, + img.width() / 2, img.height() / 2, opaqueBrush); + } + painter.end(); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::brushValueIcon(const QBrush &b) +{ + return QIcon(brushValuePixmap(b)); +} + +QString QtPropertyBrowserUtils::colorValueText(const QColor &c) +{ + return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)", 0, QApplication::UnicodeUTF8) + .arg(QString::number(c.red())) + .arg(QString::number(c.green())) + .arg(QString::number(c.blue())) + .arg(QString::number(c.alpha())); +} + +QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont &font) +{ + QFont f = font; + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter p(&img); + p.setRenderHint(QPainter::TextAntialiasing, true); + p.setRenderHint(QPainter::Antialiasing, true); + f.setPointSize(13); + p.setFont(f); + QTextOption t; + t.setAlignment(Qt::AlignCenter); + p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::fontValueIcon(const QFont &f) +{ + return QIcon(fontValuePixmap(f)); +} + +QString QtPropertyBrowserUtils::fontValueText(const QFont &f) +{ + return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2]", 0, QApplication::UnicodeUTF8) + .arg(f.family()) + .arg(f.pointSize()); +} + + +QtBoolEdit::QtBoolEdit(QWidget *parent) : + QWidget(parent), + m_checkBox(new QCheckBox(this)), + m_textVisible(true) +{ + QHBoxLayout *lt = new QHBoxLayout; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(4, 0, 0, 0); + else + lt->setContentsMargins(0, 0, 4, 0); + lt->addWidget(m_checkBox); + setLayout(lt); + connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); + setFocusProxy(m_checkBox); + m_checkBox->setText(tr("True")); +} + +void QtBoolEdit::setTextVisible(bool textVisible) +{ + if (m_textVisible == textVisible) + return; + + m_textVisible = textVisible; + if (m_textVisible) + m_checkBox->setText(isChecked() ? tr("True") : tr("False")); + else + m_checkBox->setText(QString()); +} + +Qt::CheckState QtBoolEdit::checkState() const +{ + return m_checkBox->checkState(); +} + +void QtBoolEdit::setCheckState(Qt::CheckState state) +{ + m_checkBox->setCheckState(state); +} + +bool QtBoolEdit::isChecked() const +{ + return m_checkBox->isChecked(); +} + +void QtBoolEdit::setChecked(bool c) +{ + m_checkBox->setChecked(c); + if (!m_textVisible) + return; + m_checkBox->setText(isChecked() ? tr("True") : tr("False")); +} + +bool QtBoolEdit::blockCheckBoxSignals(bool block) +{ + return m_checkBox->blockSignals(block); +} + +void QtBoolEdit::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton) { + m_checkBox->click(); + event->accept(); + } else { + QWidget::mousePressEvent(event); + } +} + + +QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent) + : QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this)) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->setMargin(0); + m_lineEdit->installEventFilter(this); + m_lineEdit->setReadOnly(true); + m_lineEdit->setFocusProxy(this); + setFocusPolicy(m_lineEdit->focusPolicy()); + setAttribute(Qt::WA_InputMethodEnabled); +} + +bool QtKeySequenceEdit::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_lineEdit && e->type() == QEvent::ContextMenu) { + QContextMenuEvent *c = static_cast(e); + QMenu *menu = m_lineEdit->createStandardContextMenu(); + const QList actions = menu->actions(); + QListIterator itAction(actions); + while (itAction.hasNext()) { + QAction *action = itAction.next(); + action->setShortcut(QKeySequence()); + QString actionString = action->text(); + const int pos = actionString.lastIndexOf(QLatin1Char('\t')); + if (pos > 0) + actionString.remove(pos, actionString.length() - pos); + action->setText(actionString); + } + QAction *actionBefore = 0; + if (actions.count() > 0) + actionBefore = actions[0]; + QAction *clearAction = new QAction(tr("Clear Shortcut"), menu); + menu->insertAction(actionBefore, clearAction); + menu->insertSeparator(actionBefore); + clearAction->setEnabled(!m_keySequence.isEmpty()); + connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut())); + menu->exec(c->globalPos()); + delete menu; + e->accept(); + return true; + } + + return QWidget::eventFilter(o, e); +} + +void QtKeySequenceEdit::slotClearShortcut() +{ + if (m_keySequence.isEmpty()) + return; + setKeySequence(QKeySequence()); + emit keySequenceChanged(m_keySequence); +} + +void QtKeySequenceEdit::handleKeyEvent(QKeyEvent *e) +{ + int nextKey = e->key(); + if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || + nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt || + nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr) + return; + + nextKey |= translateModifiers(e->modifiers(), e->text()); + int k0 = m_keySequence[0]; + int k1 = m_keySequence[1]; + int k2 = m_keySequence[2]; + int k3 = m_keySequence[3]; + switch (m_num) { + case 0: k0 = nextKey; k1 = 0; k2 = 0; k3 = 0; break; + case 1: k1 = nextKey; k2 = 0; k3 = 0; break; + case 2: k2 = nextKey; k3 = 0; break; + case 3: k3 = nextKey; break; + default: break; + } + ++m_num; + if (m_num > 3) + m_num = 0; + m_keySequence = QKeySequence(k0, k1, k2, k3); + m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText)); + e->accept(); + emit keySequenceChanged(m_keySequence); +} + +void QtKeySequenceEdit::setKeySequence(const QKeySequence &sequence) +{ + if (sequence == m_keySequence) + return; + m_num = 0; + m_keySequence = sequence; + m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText)); +} + +QKeySequence QtKeySequenceEdit::keySequence() const +{ + return m_keySequence; +} + +int QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text) const +{ + int result = 0; + if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace())) + result |= Qt::SHIFT; + if (state & Qt::ControlModifier) + result |= Qt::CTRL; + if (state & Qt::MetaModifier) + result |= Qt::META; + if (state & Qt::AltModifier) + result |= Qt::ALT; + return result; +} + +void QtKeySequenceEdit::focusInEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + m_lineEdit->selectAll(); + QWidget::focusInEvent(e); +} + +void QtKeySequenceEdit::focusOutEvent(QFocusEvent *e) +{ + m_num = 0; + m_lineEdit->event(e); + QWidget::focusOutEvent(e); +} + +void QtKeySequenceEdit::keyPressEvent(QKeyEvent *e) +{ + handleKeyEvent(e); + e->accept(); +} + +void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e) +{ + m_lineEdit->event(e); +} + +bool QtKeySequenceEdit::event(QEvent *e) +{ + if (e->type() == QEvent::Shortcut || + e->type() == QEvent::ShortcutOverride || + e->type() == QEvent::KeyRelease) { + e->accept(); + return true; + } + return QWidget::event(e); +} + + + + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h 2012-02-21 23:06:08.000000000 +0000 @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QTPROPERTYBROWSERUTILS_H +#define QTPROPERTYBROWSERUTILS_H + +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QMouseEvent; +class QCheckBox; +class QLineEdit; + +class QtCursorDatabase +{ +public: + QtCursorDatabase(); + + QStringList cursorShapeNames() const; + QMap cursorShapeIcons() const; + QString cursorToShapeName(const QCursor &cursor) const; + QIcon cursorToShapeIcon(const QCursor &cursor) const; + int cursorToValue(const QCursor &cursor) const; +#ifndef QT_NO_CURSOR + QCursor valueToCursor(int value) const; +#endif +private: + void appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon); + QStringList m_cursorNames; + QMap m_cursorIcons; + QMap m_valueToCursorShape; + QMap m_cursorShapeToValue; +}; + +class QtPropertyBrowserUtils +{ +public: + static QPixmap brushValuePixmap(const QBrush &b); + static QIcon brushValueIcon(const QBrush &b); + static QString colorValueText(const QColor &c); + static QPixmap fontValuePixmap(const QFont &f); + static QIcon fontValueIcon(const QFont &f); + static QString fontValueText(const QFont &f); +}; + +class QtBoolEdit : public QWidget { + Q_OBJECT +public: + QtBoolEdit(QWidget *parent = 0); + + bool textVisible() const { return m_textVisible; } + void setTextVisible(bool textVisible); + + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + + bool isChecked() const; + void setChecked(bool c); + + bool blockCheckBoxSignals(bool block); + +Q_SIGNALS: + void toggled(bool); + +protected: + void mousePressEvent(QMouseEvent * event); + +private: + QCheckBox *m_checkBox; + bool m_textVisible; +}; + +class QtKeySequenceEdit : public QWidget +{ + Q_OBJECT +public: + QtKeySequenceEdit(QWidget *parent = 0); + + QKeySequence keySequence() const; + bool eventFilter(QObject *o, QEvent *e); +public Q_SLOTS: + void setKeySequence(const QKeySequence &sequence); +Q_SIGNALS: + void keySequenceChanged(const QKeySequence &sequence); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + bool event(QEvent *e); +private slots: + void slotClearShortcut(); +private: + void handleKeyEvent(QKeyEvent *e); + int translateModifiers(Qt::KeyboardModifiers state, const QString &text) const; + + int m_num; + QKeySequence m_keySequence; + QLineEdit *m_lineEdit; +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertymanager.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertymanager.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertymanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertymanager.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,6453 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtpropertymanager.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +/* +template +static void setSimpleMinimumData(PrivateData *data, const Value &minVal) +{ + data->minVal = minVal; + if (data->maxVal < data->minVal) + data->maxVal = data->minVal; + + if (data->val < data->minVal) + data->val = data->minVal; +} + +template +static void setSimpleMaximumData(PrivateData *data, const Value &maxVal) +{ + data->maxVal = maxVal; + if (data->minVal > data->maxVal) + data->minVal = data->maxVal; + + if (data->val > data->maxVal) + data->val = data->maxVal; +} +*/ + +/* +template +static void setSizeMinimumData(PrivateData *data, const Value &newMinVal) +{ + data->minVal = newMinVal; + if (data->maxVal.width() < data->minVal.width()) + data->maxVal.setWidth(data->minVal.width()); + if (data->maxVal.height() < data->minVal.height()) + data->maxVal.setHeight(data->minVal.height()); + + if (data->val.width() < data->minVal.width()) + data->val.setWidth(data->minVal.width()); + if (data->val.height() < data->minVal.height()) + data->val.setHeight(data->minVal.height()); +} +*/ + +/* +template +static void setSizeMaximumData(PrivateData *data, const Value &newMaxVal) +{ + data->maxVal = newMaxVal; + if (data->minVal.width() > data->maxVal.width()) + data->minVal.setWidth(data->maxVal.width()); + if (data->minVal.height() > data->maxVal.height()) + data->minVal.setHeight(data->maxVal.height()); + + if (data->val.width() > data->maxVal.width()) + data->val.setWidth(data->maxVal.width()); + if (data->val.height() > data->maxVal.height()) + data->val.setHeight(data->maxVal.height()); +} +*/ + +template +static SizeValue qBoundSize(const SizeValue &minVal, const SizeValue &val, const SizeValue &maxVal) +{ + SizeValue croppedVal = val; + if (minVal.width() > val.width()) + croppedVal.setWidth(minVal.width()); + else if (maxVal.width() < val.width()) + croppedVal.setWidth(maxVal.width()); + + if (minVal.height() > val.height()) + croppedVal.setHeight(minVal.height()); + else if (maxVal.height() < val.height()) + croppedVal.setHeight(maxVal.height()); + + return croppedVal; +} + +// Match the exact signature of qBound for VS 6. +QSize qBound(QSize minVal, QSize val, QSize maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +namespace { + +namespace { +template +void orderBorders(Value &minVal, Value &maxVal) +{ + if (minVal > maxVal) + qSwap(minVal, maxVal); +} + +template +static void orderSizeBorders(Value &minVal, Value &maxVal) +{ + Value fromSize = minVal; + Value toSize = maxVal; + if (fromSize.width() > toSize.width()) { + fromSize.setWidth(maxVal.width()); + toSize.setWidth(minVal.width()); + } + if (fromSize.height() > toSize.height()) { + fromSize.setHeight(maxVal.height()); + toSize.setHeight(minVal.height()); + } + minVal = fromSize; + maxVal = toSize; +} + +void orderBorders(QSize &minVal, QSize &maxVal) +{ + orderSizeBorders(minVal, maxVal); +} + +void orderBorders(QSizeF &minVal, QSizeF &maxVal) +{ + orderSizeBorders(minVal, maxVal); +} + +} +} +//////// + +template +static Value getData(const QMap &propertyMap, + Value PrivateData::*data, + const QtProperty *property, const Value &defaultValue = Value()) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::const_iterator PropertyToDataConstIterator; + const PropertyToDataConstIterator it = propertyMap.constFind(property); + if (it == propertyMap.constEnd()) + return defaultValue; + return it.value().*data; +} + +template +static Value getValue(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::val, property, defaultValue); +} + +template +static Value getMinimum(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::minVal, property, defaultValue); +} + +template +static Value getMaximum(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::maxVal, property, defaultValue); +} + +template +static void setSimpleValue(QMap &propertyMap, + PropertyManager *manager, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + QtProperty *property, const Value &val) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = propertyMap.find(property); + if (it == propertyMap.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, val); +} + +template +static void setValueInRange(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + QtProperty *property, const Value &val, + void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, ValueChangeParameter)) +{ + typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData; + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + PrivateData &data = it.value(); + + if (data.val == val) + return; + + const Value oldVal = data.val; + + data.val = qBound(data.minVal, val, data.maxVal); + + if (data.val == oldVal) + return; + + if (setSubPropertyValue) + (managerPrivate->*setSubPropertyValue)(property, data.val); + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValues(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &minVal, const Value &maxVal, + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData; + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + Value fromVal = minVal; + Value toVal = maxVal; + orderBorders(fromVal, toVal); + + PrivateData &data = it.value(); + + if (data.minVal == fromVal && data.maxVal == toVal) + return; + + const Value oldVal = data.val; + + data.setMinimumValue(fromVal); + data.setMaximumValue(toVal); + + emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, + Value (PrivateData::*getRangeVal)() const, + void (PrivateData::*setRangeVal)(ValueChangeParameter), const Value &borderVal, + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + PrivateData &data = it.value(); + + if ((data.*getRangeVal)() == borderVal) + return; + + const Value oldVal = data.val; + + (data.*setRangeVal)(borderVal); + + emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setMinimumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &minVal) +{ + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange); +} + +template +static void setMaximumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &maxVal) +{ + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange); +} + +/* +class QtMetaEnumWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSizePolicy::Policy policy READ policy) +public: + QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; } +private: + QtMetaEnumWrapper(QObject *parent) : QObject(parent) {} +}; +*/ + +class QtMetaEnumProvider +{ +public: + QtMetaEnumProvider(); + + QStringList policyEnumNames() const { return m_policyEnumNames; } + QStringList languageEnumNames() const { return m_languageEnumNames; } + QStringList countryEnumNames(QLocale::Language language) const { return m_countryEnumNames.value(language); } + + QSizePolicy::Policy indexToSizePolicy(int index) const; + int sizePolicyToIndex(QSizePolicy::Policy policy) const; + + void indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const; + void localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const; + +private: + void initLocale(); + + QStringList m_policyEnumNames; + QStringList m_languageEnumNames; + QMap m_countryEnumNames; + QMap m_indexToLanguage; + QMap m_languageToIndex; + QMap > m_indexToCountry; + QMap > m_countryToIndex; + QMetaEnum m_policyEnum; +}; + +#if QT_VERSION < 0x040300 + +static QList countriesForLanguage(QLocale::Language language) +{ + QList countries; + QLocale::Country country = QLocale::AnyCountry; + while (country <= QLocale::LastCountry) { + QLocale locale(language, country); + if (locale.language() == language && !countries.contains(locale.country())) + countries << locale.country(); + country = (QLocale::Country)((uint)country + 1); // ++country + } + return countries; +} + +#endif + +static QList sortCountries(const QList &countries) +{ + QMultiMap nameToCountry; + QListIterator itCountry(countries); + while (itCountry.hasNext()) { + QLocale::Country country = itCountry.next(); + nameToCountry.insert(QLocale::countryToString(country), country); + } + return nameToCountry.values(); +} + +void QtMetaEnumProvider::initLocale() +{ + QMultiMap nameToLanguage; + QLocale::Language language = QLocale::C; + while (language <= QLocale::LastLanguage) { + QLocale locale(language); + if (locale.language() == language) + nameToLanguage.insert(QLocale::languageToString(language), language); + language = (QLocale::Language)((uint)language + 1); // ++language + } + + const QLocale system = QLocale::system(); + if (!nameToLanguage.contains(QLocale::languageToString(system.language()))) + nameToLanguage.insert(QLocale::languageToString(system.language()), system.language()); + + QList languages = nameToLanguage.values(); + QListIterator itLang(languages); + while (itLang.hasNext()) { + QLocale::Language language = itLang.next(); + QList countries; +#if QT_VERSION < 0x040300 + countries = countriesForLanguage(language); +#else + countries = QLocale::countriesForLanguage(language); +#endif + if (countries.isEmpty() && language == system.language()) + countries << system.country(); + + if (!countries.isEmpty() && !m_languageToIndex.contains(language)) { + countries = sortCountries(countries); + int langIdx = m_languageEnumNames.count(); + m_indexToLanguage[langIdx] = language; + m_languageToIndex[language] = langIdx; + QStringList countryNames; + QListIterator it(countries); + int countryIdx = 0; + while (it.hasNext()) { + QLocale::Country country = it.next(); + countryNames << QLocale::countryToString(country); + m_indexToCountry[langIdx][countryIdx] = country; + m_countryToIndex[language][country] = countryIdx; + ++countryIdx; + } + m_languageEnumNames << QLocale::languageToString(language); + m_countryEnumNames[language] = countryNames; + } + } +} + +QtMetaEnumProvider::QtMetaEnumProvider() +{ + QMetaProperty p; + + p = QtMetaEnumWrapper::staticMetaObject.property( + QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0); + m_policyEnum = p.enumerator(); + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + m_policyEnumNames << QLatin1String(m_policyEnum.key(i)); + + initLocale(); +} + +QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const +{ + return static_cast(m_policyEnum.value(index)); +} + +int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const +{ + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + if (indexToSizePolicy(i) == policy) + return i; + return -1; +} + +void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const +{ + QLocale::Language l = QLocale::C; + QLocale::Country c = QLocale::AnyCountry; + if (m_indexToLanguage.contains(languageIndex)) { + l = m_indexToLanguage[languageIndex]; + if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex)) + c = m_indexToCountry[languageIndex][countryIndex]; + } + if (language) + *language = l; + if (country) + *country = c; +} + +void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const +{ + int l = -1; + int c = -1; + if (m_languageToIndex.contains(language)) { + l = m_languageToIndex[language]; + if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country)) + c = m_countryToIndex[language][country]; + } + + if (languageIndex) + *languageIndex = l; + if (countryIndex) + *countryIndex = c; +} + +Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider) + +// QtGroupPropertyManager + +/*! + \class QtGroupPropertyManager + + \brief The QtGroupPropertyManager provides and manages group properties. + + This class is intended to provide a grouping element without any value. + + \sa QtAbstractPropertyManager +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtGroupPropertyManager::QtGroupPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtGroupPropertyManager::~QtGroupPropertyManager() +{ + +} + +/*! + \reimp +*/ +bool QtGroupPropertyManager::hasValue(const QtProperty *property) const +{ + Q_UNUSED(property) + return false; +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::initializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::uninitializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +// QtIntPropertyManager + +class QtIntPropertyManagerPrivate +{ + QtIntPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtIntPropertyManager) +public: + + struct Data + { + Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1) {} + int val; + int minVal; + int maxVal; + int singleStep; + int minimumValue() const { return minVal; } + int maximumValue() const { return maxVal; } + void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(int newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtIntPropertyManager + + \brief The QtIntPropertyManager provides and manages int properties. + + An int property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtIntPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes, + and the rangeChanged() signal which is emitted whenever such a + property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory +*/ + +/*! + \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values. + + \sa setRange() +*/ + +/*! + \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtIntPropertyManager::QtIntPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtIntPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtIntPropertyManager::~QtIntPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +int QtIntPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's minimum value. + + \sa setMinimum(), maximum(), setRange() +*/ +int QtIntPropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's maximum value. + + \sa setMaximum(), minimum(), setRange() +*/ +int QtIntPropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +int QtIntPropertyManager::singleStep(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + \reimp +*/ +QString QtIntPropertyManager::valueText(const QtProperty *property) const +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return QString::number(it.value().val); +} + +/*! + \fn void QtIntPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's range, the \a value is adjusted to the nearest valid + value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtIntPropertyManager::setValue(QtProperty *property, int val) +{ + void (QtIntPropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, int) = 0; + setValueInRange(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMinimum(QtProperty *property, int minVal) +{ + setMinimumValue(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMaximum(QtProperty *property, int maxVal) +{ + setMaximumValue(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtIntPropertyManager::setRange(QtProperty *property, int minVal, int maxVal) +{ + void (QtIntPropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, int, int, int) = 0; + setBorderValues(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtIntPropertyManager::setSingleStep(QtProperty *property, int step) +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtIntPropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDoublePropertyManager + +class QtDoublePropertyManagerPrivate +{ + QtDoublePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDoublePropertyManager) +public: + + struct Data + { + Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), decimals(2) {} + double val; + double minVal; + double maxVal; + double singleStep; + int decimals; + double minimumValue() const { return minVal; } + double maximumValue() const { return maxVal; } + void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(double newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtDoublePropertyManager + + \brief The QtDoublePropertyManager provides and manages double properties. + + A double property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. + Alternatively, the range can be defined in one go using the + setRange() slot. + + In addition, QtDoublePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory +*/ + +/*! + \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values + + \sa setRange() +*/ + +/*! + \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDoublePropertyManager::QtDoublePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDoublePropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDoublePropertyManager::~QtDoublePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +double QtDoublePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's minimum value. + + \sa maximum(), setRange() +*/ +double QtDoublePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's maximum value. + + \sa minimum(), setRange() +*/ +double QtDoublePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +double QtDoublePropertyManager::singleStep(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtDoublePropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtDoublePropertyManager::valueText(const QtProperty *property) const +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return QString::number(it.value().val, 'f', it.value().decimals); +} + +/*! + \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given + \a property's range, the \a value is adjusted to the nearest valid value + within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDoublePropertyManager::setValue(QtProperty *property, double val) +{ + void (QtDoublePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, double) = 0; + setValueInRange(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtDoublePropertyManager::setSingleStep(QtProperty *property, double step) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMinimum(QtProperty *property, double minVal) +{ + setMinimumValue(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMaximum(QtProperty *property, double maxVal) +{ + setMaximumValue(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDoublePropertyManager::setRange(QtProperty *property, double minVal, double maxVal) +{ + void (QtDoublePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, double, double, double) = 0; + setBorderValues(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtStringPropertyManager + +class QtStringPropertyManagerPrivate +{ + QtStringPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtStringPropertyManager) +public: + + struct Data + { + Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard) + { + } + QString val; + QRegExp regExp; + }; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +/*! + \class QtStringPropertyManager + + \brief The QtStringPropertyManager provides and manages QString properties. + + A string property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The current value can be checked against a regular expression. To + set the regular expression use the setRegExp() slot, use the + regExp() function to retrieve the currently set expression. + + In addition, QtStringPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the regExpChanged() signal which is emitted whenever + such a property changes its currently set regular expression. + + \sa QtAbstractPropertyManager, QtLineEditFactory +*/ + +/*! + \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp ®Exp) + + This signal is emitted whenever a property created by this manager + changes its currenlty set regular expression, passing a pointer to + the \a property and the new \a regExp as parameters. + + \sa setRegExp() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtStringPropertyManager::QtStringPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtStringPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtStringPropertyManager::~QtStringPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an empty string. + + \sa setValue() +*/ +QString QtStringPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's currently set regular expression. + + If the given \a property is not managed by this manager, this + function returns an empty expression. + + \sa setRegExp() +*/ +QRegExp QtStringPropertyManager::regExp(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp()); +} + +/*! + \reimp +*/ +QString QtStringPropertyManager::valueText(const QtProperty *property) const +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val; +} + +/*! + \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value doesn't match the given \a property's + regular expression, this function does nothing. + + \sa value(), setRegExp(), valueChanged() +*/ +void QtStringPropertyManager::setValue(QtProperty *property, const QString &val) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (data.regExp.isValid() && !data.regExp.exactMatch(val)) + return; + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the regular expression of the given \a property to \a regExp. + + \sa regExp(), setValue(), regExpChanged() +*/ +void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegExp ®Exp) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value() ; + + if (data.regExp == regExp) + return; + + data.regExp = regExp; + + it.value() = data; + + emit regExpChanged(property, data.regExp); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtBoolPropertyManager + +class QtBoolPropertyManagerPrivate +{ + QtBoolPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtBoolPropertyManager) +public: + + QMap m_values; +}; + +/*! + \class QtBoolPropertyManager + + \brief The QtBoolPropertyManager class provides and manages boolean properties. + + The property's value can be retrieved using the value() function, + and set using the setValue() slot. + + In addition, QtBoolPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtCheckBoxFactory +*/ + +/*! + \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtBoolPropertyManager::QtBoolPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtBoolPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtBoolPropertyManager::~QtBoolPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns false. + + \sa setValue() +*/ +bool QtBoolPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, false); +} + +/*! + \reimp +*/ +QString QtBoolPropertyManager::valueText(const QtProperty *property) const +{ + const QMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + static const QString trueText = tr("True"); + static const QString falseText = tr("False"); + return it.value() ? trueText : falseText; +} + +// Return an icon containing a check box indicator +static QIcon drawCheckBox(bool value) +{ + QStyleOptionButton opt; + opt.state |= value ? QStyle::State_On : QStyle::State_Off; + opt.state |= QStyle::State_Enabled; + const QStyle *style = QApplication::style(); + // Figure out size of an indicator and make sure it is not scaled down in a list view item + // by making the pixmap as big as a list view icon and centering the indicator in it. + // (if it is smaller, it can't be helped) + const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); + const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); + const int listViewIconSize = indicatorWidth; + const int pixmapWidth = indicatorWidth; + const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); + + opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); + QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); + pixmap.fill(Qt::transparent); + { + // Center? + const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; + const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; + QPainter painter(&pixmap); + painter.translate(xoff, yoff); + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); + } + return QIcon(pixmap); +} + +/*! + \reimp +*/ +QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const +{ + const QMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + static const QIcon checkedIcon = drawCheckBox(true); + static const QIcon uncheckedIcon = drawCheckBox(false); + return it.value() ? checkedIcon : uncheckedIcon; +} + +/*! + \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value) + + Sets the value of the given \a property to \a value. + + \sa value() +*/ +void QtBoolPropertyManager::setValue(QtProperty *property, bool val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtBoolPropertyManager::propertyChanged, + &QtBoolPropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = false; +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDatePropertyManager + +class QtDatePropertyManagerPrivate +{ + QtDatePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDatePropertyManager) +public: + + struct Data + { + Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)), + maxVal(QDate(7999, 12, 31)) {} + QDate val; + QDate minVal; + QDate maxVal; + QDate minimumValue() const { return minVal; } + QDate maximumValue() const { return maxVal; } + void setMinimumValue(const QDate &newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(const QDate &newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + QString m_format; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +/*! + \class QtDatePropertyManager + + \brief The QtDatePropertyManager provides and manages QDate properties. + + A date property has a current value, and a range specifying the + valid dates. The range is defined by a minimum and a maximum + value. + + The property's values can be retrieved using the minimum(), + maximum() and value() functions, and can be set using the + setMinimum(), setMaximum() and setValue() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtDatePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid dates. + + \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager +*/ + +/*! + \fn void QtDatePropertyManager::valueChanged(QtProperty *property, const QDate &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, const QDate &minimum, const QDate &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid dates, passing a pointer to the \a + property and the new \a minimum and \a maximum dates. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDatePropertyManager::QtDatePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDatePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDatePropertyManager::~QtDatePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid date. + + \sa setValue() +*/ +QDate QtDatePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's minimum date. + + \sa maximum(), setRange() +*/ +QDate QtDatePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum date. + + \sa minimum(), setRange() +*/ +QDate QtDatePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtDatePropertyManager::valueText(const QtProperty *property) const +{ + const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val.toString(d_ptr->m_format); +} + +/*! + \fn void QtDatePropertyManager::setValue(QtProperty *property, const QDate &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not a valid date according to the + given \a property's range, the value is adjusted to the nearest + valid value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDatePropertyManager::setValue(QtProperty *property, const QDate &val) +{ + void (QtDatePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, const QDate &) = 0; + setValueInRange(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange() +*/ +void QtDatePropertyManager::setMinimum(QtProperty *property, const QDate &minVal) +{ + setMinimumValue(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current + values are adjusted if necessary (ensuring that the range remains + valid and that the current value is within in the range). + + \sa maximum(), setRange() +*/ +void QtDatePropertyManager::setMaximum(QtProperty *property, const QDate &maxVal) +{ + setMaximumValue(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minimum, const QDate &maximum) + + Sets the range of valid dates. + + This is a convenience function defining the range of valid dates + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new date range, the current value is adjusted if + necessary (ensuring that the value remains in date range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal) +{ + void (QtDatePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, const QDate &, + const QDate &, const QDate &) = 0; + setBorderValues(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtTimePropertyManager + +class QtTimePropertyManagerPrivate +{ + QtTimePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtTimePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtTimePropertyManager + + \brief The QtTimePropertyManager provides and manages QTime properties. + + A time property's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtTimePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtTimeEditFactory +*/ + +/*! + \fn void QtTimePropertyManager::valueChanged(QtProperty *property, const QTime &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtTimePropertyManager::QtTimePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtTimePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.timeFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtTimePropertyManager::~QtTimePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an invalid time object. + + \sa setValue() +*/ +QTime QtTimePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QTime()); +} + +/*! + \reimp +*/ +QString QtTimePropertyManager::valueText(const QtProperty *property) const +{ + const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(d_ptr->m_format); +} + +/*! + \fn void QtTimePropertyManager::setValue(QtProperty *property, const QTime &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtTimePropertyManager::setValue(QtProperty *property, const QTime &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtTimePropertyManager::propertyChanged, + &QtTimePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtTimePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QTime::currentTime(); +} + +/*! + \reimp +*/ +void QtTimePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDateTimePropertyManager + +class QtDateTimePropertyManagerPrivate +{ + QtDateTimePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDateTimePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtDateTimePropertyManager + + \brief The QtDateTimePropertyManager provides and manages QDateTime properties. + + A date and time property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtDateTimePropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager +*/ + +/*! + \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDateTimePropertyManager::QtDateTimePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDateTimePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat); + d_ptr->m_format += QLatin1Char(' '); + d_ptr->m_format += loc.timeFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDateTimePropertyManager::~QtDateTimePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid QDateTime object. + + \sa setValue() +*/ +QDateTime QtDateTimePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QDateTime()); +} + +/*! + \reimp +*/ +QString QtDateTimePropertyManager::valueText(const QtProperty *property) const +{ + const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(d_ptr->m_format); +} + +/*! + \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtDateTimePropertyManager::propertyChanged, + &QtDateTimePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QDateTime::currentDateTime(); +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtKeySequencePropertyManager + +class QtKeySequencePropertyManagerPrivate +{ + QtKeySequencePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtKeySequencePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtKeySequencePropertyManager + + \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties. + + A key sequence's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtKeySequencePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtKeySequencePropertyManager::QtKeySequencePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtKeySequencePropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtKeySequencePropertyManager::~QtKeySequencePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an empty QKeySequence object. + + \sa setValue() +*/ +QKeySequence QtKeySequencePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QKeySequence()); +} + +/*! + \reimp +*/ +QString QtKeySequencePropertyManager::valueText(const QtProperty *property) const +{ + const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(QKeySequence::NativeText); +} + +/*! + \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtKeySequencePropertyManager::propertyChanged, + &QtKeySequencePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QKeySequence(); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtCharPropertyManager + +class QtCharPropertyManagerPrivate +{ + QtCharPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtCharPropertyManager) +public: + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtCharPropertyManager + + \brief The QtCharPropertyManager provides and manages QChar properties. + + A char's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtCharPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCharPropertyManager::QtCharPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtCharPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCharPropertyManager::~QtCharPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an null QChar object. + + \sa setValue() +*/ +QChar QtCharPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QChar()); +} + +/*! + \reimp +*/ +QString QtCharPropertyManager::valueText(const QtProperty *property) const +{ + const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QChar c = it.value(); + return c.isNull() ? QString() : QString(c); +} + +/*! + \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCharPropertyManager::setValue(QtProperty *property, const QChar &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtCharPropertyManager::propertyChanged, + &QtCharPropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QChar(); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtLocalePropertyManager + +/* +class QtLocalePropertyManagerPrivate +{ + QtLocalePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtLocalePropertyManager) +public: + + QtLocalePropertyManagerPrivate(); + + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToLanguage; + QMap m_propertyToCountry; + + QMap m_languageToProperty; + QMap m_countryToProperty; +}; +*/ + +QtLocalePropertyManagerPrivate::QtLocalePropertyManagerPrivate() +{ +} + +void QtLocalePropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_languageToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } else if (QtProperty *prop = m_countryToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } +} + +void QtLocalePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *subProp = m_languageToProperty.value(property, 0)) { + m_propertyToLanguage[subProp] = 0; + m_languageToProperty.remove(property); + } else if (QtProperty *subProp = m_countryToProperty.value(property, 0)) { + m_propertyToCountry[subProp] = 0; + m_countryToProperty.remove(property); + } +} + +/*! + \class QtLocalePropertyManager + + \brief The QtLocalePropertyManager provides and manages QLocale properties. + + A locale property has nested \e language and \e country + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtEnumPropertyManager object. + These submanager can be retrieved using the subEnumPropertyManager() + function. In order to provide editing widgets for the subproperties + in a property browser widget, this manager must be associated with editor factory. + + In addition, QtLocalePropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtLocalePropertyManager::QtLocalePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtLocalePropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtLocalePropertyManager::~QtLocalePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e language + and \e country subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtLocalePropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default locale. + + \sa setValue() +*/ +QLocale QtLocalePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QLocale()); +} + +/*! + \reimp +*/ +QString QtLocalePropertyManager::valueText(const QtProperty *property) const +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + QLocale loc = it.value(); + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx); + QString str = tr("%1, %2") + .arg(metaEnumProvider()->languageEnumNames().at(langIdx)) + .arg(metaEnumProvider()->countryEnumNames(loc.language()).at(countryIdx)); + return str; +} + +/*! + \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &val) +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QLocale loc = it.value(); + if (loc == val) + return; + + it.value() = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + if (loc.language() != val.language()) { + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx); + d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property), + metaEnumProvider()->countryEnumNames(val.language())); + } + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::initializeProperty(QtProperty *property) +{ + QLocale val; + d_ptr->m_values[property] = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + + QtProperty *languageProp = d_ptr->m_enumPropertyManager->addProperty(); + languageProp->setPropertyName(tr("Language")); + d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames()); + d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx); + d_ptr->m_propertyToLanguage[property] = languageProp; + d_ptr->m_languageToProperty[languageProp] = property; + property->addSubProperty(languageProp); + + QtProperty *countryProp = d_ptr->m_enumPropertyManager->addProperty(); + countryProp->setPropertyName(tr("Country")); + d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language())); + d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx); + d_ptr->m_propertyToCountry[property] = countryProp; + d_ptr->m_countryToProperty[countryProp] = property; + property->addSubProperty(countryProp); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *languageProp = d_ptr->m_propertyToLanguage[property]; + if (languageProp) { + d_ptr->m_languageToProperty.remove(languageProp); + delete languageProp; + } + d_ptr->m_propertyToLanguage.remove(property); + + QtProperty *countryProp = d_ptr->m_propertyToCountry[property]; + if (countryProp) { + d_ptr->m_countryToProperty.remove(countryProp); + delete countryProp; + } + d_ptr->m_propertyToCountry.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtPointPropertyManager + +/* +class QtPointPropertyManagerPrivate +{ + QtPointPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; +*/ + +void QtPointPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *xprop = m_xToProperty.value(property, 0)) { + QPoint p = m_values[xprop]; + p.setX(value); + q_ptr->setValue(xprop, p); + } else if (QtProperty *yprop = m_yToProperty.value(property, 0)) { + QPoint p = m_values[yprop]; + p.setY(value); + q_ptr->setValue(yprop, p); + } +} + +void QtPointPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointPropertyManager + + \brief The QtPointPropertyManager provides and manages QPoint properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager +*/ + +/*! + \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointPropertyManager::QtPointPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtPointPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointPropertyManager::~QtPointPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtPointPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPoint QtPointPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QPoint()); +} + +/*! + \reimp +*/ +QString QtPointPropertyManager::valueText(const QtProperty *property) const +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPoint v = it.value(); + return QString(tr("(%1, %2)").arg(QString::number(v.x())) + .arg(QString::number(v.y()))); +} + +/*! + \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &val) +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QPoint(0, 0); + + QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtPointFPropertyManager + +/* +class QtPointFPropertyManagerPrivate +{ + QtPointFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointFPropertyManager) +public: + + struct Data + { + Data() : decimals(2) {} + QPointF val; + int decimals; + }; + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; +*/ + +void QtPointFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setX(value); + q_ptr->setValue(prop, p); + } else if (QtProperty *prop = m_yToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setY(value); + q_ptr->setValue(prop, p); + } +} + +void QtPointFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointFPropertyManager + + \brief The QtPointFPropertyManager provides and manages QPointF properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointFPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager +*/ + +/*! + \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointFPropertyManager::QtPointFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtPointFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointFPropertyManager::~QtPointFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtPointFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPointF QtPointFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtPointFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtPointFPropertyManager::valueText(const QtProperty *property) const +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPointF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec))); +} + +/*! + \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &val) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().val == val) + return; + + it.value().val = val; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtPointFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizePropertyManager + +/* +class QtSizePropertyManagerPrivate +{ + QtSizePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSize &val); + void setRange(QtProperty *property, + const QSize &minVal, const QSize &maxVal, const QSize &val); + + struct Data + { + Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {} + QSize val; + QSize minVal; + QSize maxVal; + QSize minimumValue() const { return minVal; } + QSize maximumValue() const { return maxVal; } + void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSize &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; +*/ + +void QtSizePropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_wToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizePropertyManagerPrivate::setValue(QtProperty *property, const QSize &val) +{ + m_intPropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_intPropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizePropertyManagerPrivate::setRange(QtProperty *property, + const QSize &minVal, const QSize &maxVal, const QSize &val) +{ + QtProperty *wProperty = m_propertyToW.value(property); + QtProperty *hProperty = m_propertyToH.value(property); + m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width()); + m_intPropertyManager->setValue(wProperty, val.width()); + m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height()); + m_intPropertyManager->setValue(hProperty, val.height()); +} + +/*! + \class QtSizePropertyManager + + \brief The QtSizePropertyManager provides and manages QSize properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager +*/ + +/*! + \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePropertyManager::QtSizePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizePropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePropertyManager::~QtSizePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtSizePropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSize QtSizePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSize QtSizePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSize QtSizePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizePropertyManager::valueText(const QtProperty *property) const +{ + const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSize v = it.value().val; + return QString(tr("%1 x %2").arg(QString::number(v.width())) + .arg(QString::number(v.height()))); +} + +/*! + \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizePropertyManager::setValue(QtProperty *property, const QSize &val) +{ + setValueInRange(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + property, val, &QtSizePropertyManagerPrivate::setValue); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMinimum(QtProperty *property, const QSize &minVal) +{ + setBorderValue(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::minimumValue, + &QtSizePropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMaximum(QtProperty *property, const QSize &maxVal) +{ + setBorderValue(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::maximumValue, + &QtSizePropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal) +{ + setBorderValues(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data(); + + QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValue(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValue(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizeFPropertyManager + +/* +class QtSizeFPropertyManagerPrivate +{ + QtSizeFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizeFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSizeF &val); + void setRange(QtProperty *property, + const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val); + + struct Data + { + Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {} + QSizeF val; + QSizeF minVal; + QSizeF maxVal; + int decimals; + QSizeF minimumValue() const { return minVal; } + QSizeF maximumValue() const { return maxVal; } + void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSizeF &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; +*/ + +void QtSizeFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_wToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizeFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizeFPropertyManagerPrivate::setValue(QtProperty *property, const QSizeF &val) +{ + m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizeFPropertyManagerPrivate::setRange(QtProperty *property, + const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val) +{ + m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtSizeFPropertyManager + + \brief The QtSizeFPropertyManager provides and manages QSizeF properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizeFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager +*/ + +/*! + \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizeFPropertyManager::QtSizeFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizeFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizeFPropertyManager::~QtSizeFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtSizeFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSizeF QtSizeFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtSizeFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizeFPropertyManager::valueText(const QtProperty *property) const +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSizeF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("%1 x %2").arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec))); +} + +/*! + \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &val) +{ + setValueInRange(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + property, val, &QtSizeFPropertyManagerPrivate::setValue); +} + +/*! + \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtSizeFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMinimum(QtProperty *property, const QSizeF &minVal) +{ + setBorderValue(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::minimumValue, + &QtSizeFPropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMaximum(QtProperty *property, const QSizeF &maxVal) +{ + setBorderValue(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::maximumValue, + &QtSizeFPropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal) +{ + setBorderValues(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data(); + + QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtRectPropertyManager + +/* +class QtRectPropertyManagerPrivate +{ + QtRectPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRect &constraint, const QRect &val); + + struct Data + { + Data() : val(0, 0, 0, 0) {} + QRect val; + QRect constraint; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; +*/ + +void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QRect r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_yToProperty.value(property)) { + QRect r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectPropertyManagerPrivate::setConstraint(QtProperty *property, + const QRect &constraint, const QRect &val) +{ + const bool isNull = constraint.isNull(); + const int left = isNull ? INT_MIN : constraint.left(); + const int right = isNull ? INT_MAX : constraint.left() + constraint.width(); + const int top = isNull ? INT_MIN : constraint.top(); + const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height(); + const int width = isNull ? INT_MAX : constraint.width(); + const int height = isNull ? INT_MAX : constraint.height(); + + m_intPropertyManager->setRange(m_propertyToX[property], left, right); + m_intPropertyManager->setRange(m_propertyToY[property], top, bottom); + m_intPropertyManager->setRange(m_propertyToW[property], 0, width); + m_intPropertyManager->setRange(m_propertyToH[property], 0, height); + + m_intPropertyManager->setValue(m_propertyToX[property], val.x()); + m_intPropertyManager->setValue(m_propertyToY[property], val.y()); + m_intPropertyManager->setValue(m_propertyToW[property], val.width()); + m_intPropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectPropertyManager + + \brief The QtRectPropertyManager provides and manages QRect properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager +*/ + +/*! + \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectPropertyManager::QtRectPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtRectPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectPropertyManager::~QtRectPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtRectPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRect QtRectPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRect QtRectPropertyManager::constraint(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectPropertyManager::valueText(const QtProperty *property) const +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRect v = it.value().val; + return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x())) + .arg(QString::number(v.y())) + .arg(QString::number(v.width())) + .arg(QString::number(v.height()))); +} + +/*! + \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectPropertyManager::setValue(QtProperty *property, const QRect &val) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRect r1 = data.constraint; + const QRect r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRect value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectPropertyManager::setConstraint(QtProperty *property, const QRect &constraint) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRect oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRect r1 = data.constraint; + QRect r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValue(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValue(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtRectFPropertyManager + +/* +class QtRectFPropertyManagerPrivate +{ + QtRectFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRectF &constraint, const QRectF &val); + + struct Data + { + Data() : val(0, 0, 0, 0), decimals(2) {} + QRectF val; + QRectF constraint; + int decimals; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; +*/ + +void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_yToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectFPropertyManagerPrivate::setConstraint(QtProperty *property, + const QRectF &constraint, const QRectF &val) +{ + const bool isNull = constraint.isNull(); + const float left = isNull ? FLT_MIN : constraint.left(); + const float right = isNull ? FLT_MAX : constraint.left() + constraint.width(); + const float top = isNull ? FLT_MIN : constraint.top(); + const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height(); + const float width = isNull ? FLT_MAX : constraint.width(); + const float height = isNull ? FLT_MAX : constraint.height(); + + m_doublePropertyManager->setRange(m_propertyToX[property], left, right); + m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom); + m_doublePropertyManager->setRange(m_propertyToW[property], 0, width); + m_doublePropertyManager->setRange(m_propertyToH[property], 0, height); + + m_doublePropertyManager->setValue(m_propertyToX[property], val.x()); + m_doublePropertyManager->setValue(m_propertyToY[property], val.y()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectFPropertyManager + + \brief The QtRectFPropertyManager provides and manages QRectF properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager +*/ + +/*! + \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectFPropertyManager::QtRectFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtRectFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectFPropertyManager::~QtRectFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtRectFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRectF QtRectFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtRectFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRectF QtRectFPropertyManager::constraint(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectFPropertyManager::valueText(const QtProperty *property) const +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRectF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec)) + .arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec))); +} + +/*! + \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &val) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRectF r1 = data.constraint; + const QRectF r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRectF value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectFPropertyManager::setConstraint(QtProperty *property, const QRectF &constraint) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRectF oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRectF r1 = data.constraint; + QRectF r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtEnumPropertyManager + +class QtEnumPropertyManagerPrivate +{ + QtEnumPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtEnumPropertyManager) +public: + + struct Data + { + Data() : val(-1) {} + int val; + QStringList enumNames; + QMap enumIcons; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtEnumPropertyManager + + \brief The QtEnumPropertyManager provides and manages enum properties. + + Each enum property has an associated list of enum names which can + be retrieved using the enumNames() function, and set using the + corresponding setEnumNames() function. An enum property's value is + represented by an index in this list, and can be retrieved and set + using the value() and setValue() slots respectively. + + Each enum value can also have an associated icon. The mapping from + values to icons can be set using the setEnumIcons() function and + queried with the enumIcons() function. + + In addition, QtEnumPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. The enumNamesChanged() or enumIconsChanged() signal is emitted + whenever the list of enum names or icons is altered. + + \sa QtAbstractPropertyManager, QtEnumEditorFactory +*/ + +/*! + \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its enum names, passing a pointer to the \a property and + the new \a names as parameters. + + \sa setEnumNames() +*/ + +/*! + \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap &icons) + + This signal is emitted whenever a property created by this manager + changes its enum icons, passing a pointer to the \a property and + the new mapping of values to \a icons as parameters. + + \sa setEnumIcons() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtEnumPropertyManager::QtEnumPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtEnumPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtEnumPropertyManager::~QtEnumPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value which is an index in the + list returned by enumNames() + + If the given property is not managed by this manager, this + function returns -1. + + \sa enumNames(), setValue() +*/ +int QtEnumPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, -1); +} + +/*! + Returns the given \a property's list of enum names. + + \sa value(), setEnumNames() +*/ +QStringList QtEnumPropertyManager::enumNames(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList()); +} + +/*! + Returns the given \a property's map of enum values to their icons. + + \sa value(), setEnumIcons() +*/ +QMap QtEnumPropertyManager::enumIcons(const QtProperty *property) const +{ + return getData >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap()); +} + +/*! + \reimp +*/ +QString QtEnumPropertyManager::valueText(const QtProperty *property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtEnumPropertyManagerPrivate::Data &data = it.value(); + + const int v = data.val; + if (v >= 0 && v < data.enumNames.count()) + return data.enumNames.at(v); + return QString(); +} + +/*! + \reimp +*/ +QIcon QtEnumPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + const QtEnumPropertyManagerPrivate::Data &data = it.value(); + + const int v = data.val; + return data.enumIcons.value(v); +} + +/*! + \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be less than the size of the given \a + property's enumNames() list, and larger than (or equal to) 0. + + \sa value(), valueChanged() +*/ +void QtEnumPropertyManager::setValue(QtProperty *property, int val) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (val >= data.enumNames.count()) + return; + + if (val < 0 && data.enumNames.count() > 0) + return; + + if (val < 0) + val = -1; + + if (data.val == val) + return; + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of enum names to \a + enumNames. The \a property's current value is reset to 0 + indicating the first item of the list. + + If the specified \a enumNames list is empty, the \a property's + current value is set to -1. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumNames(QtProperty *property, const QStringList &enumNames) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (data.enumNames == enumNames) + return; + + data.enumNames = enumNames; + + data.val = -1; + + if (enumNames.count() > 0) + data.val = 0; + + it.value() = data; + + emit enumNamesChanged(property, data.enumNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's map of enum values to their icons to \a + enumIcons. + + Each enum value can have associated icon. This association is represented with passed \a enumIcons map. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumIcons(QtProperty *property, const QMap &enumIcons) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + it.value().enumIcons = enumIcons; + + emit enumIconsChanged(property, it.value().enumIcons); + + emit propertyChanged(property); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtFlagPropertyManager + +/* +class QtFlagPropertyManagerPrivate +{ + QtFlagPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFlagPropertyManager) +public: + + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + + struct Data + { + Data() : val(-1) {} + int val; + QStringList flagNames; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtBoolPropertyManager *m_boolPropertyManager; + + QMap > m_propertyToFlags; + + QMap m_flagToProperty; +}; +*/ + +void QtFlagPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value) +{ + QtProperty *prop = m_flagToProperty.value(property, 0); + if (prop == 0) + return; + + QListIterator itProp(m_propertyToFlags[prop]); + int level = 0; + while (itProp.hasNext()) { + QtProperty *p = itProp.next(); + if (p == property) { + int v = m_values[prop].val; + if (value) { + v |= (1 << level); + } else { + v &= ~(1 << level); + } + q_ptr->setValue(prop, v); + return; + } + level++; + } +} + +void QtFlagPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + QtProperty *flagProperty = m_flagToProperty.value(property, 0); + if (flagProperty == 0) + return; + + m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0); + m_flagToProperty.remove(property); +} + +/*! + \class QtFlagPropertyManager + + \brief The QtFlagPropertyManager provides and manages flag properties. + + Each flag property has an associated list of flag names which can + be retrieved using the flagNames() function, and set using the + corresponding setFlagNames() function. + + The flag manager provides properties with nested boolean + subproperties representing each flag, i.e. a flag property's value + is the binary combination of the subproperties' values. A + property's value can be retrieved and set using the value() and + setValue() slots respectively. The combination of flags is represented + by single int value - that's why it's possible to store up to + 32 independent flags in one flag property. + + The subproperties are created by a QtBoolPropertyManager object. This + manager can be retrieved using the subBoolPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtFlagPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the flagNamesChanged() signal which is emitted + whenever the list of flag names is altered. + + \sa QtAbstractPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its flag names, passing a pointer to the \a property and the + new \a names as parameters. + + \sa setFlagNames() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFlagPropertyManager::QtFlagPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtFlagPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotBoolChanged(QtProperty *, bool))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFlagPropertyManager::~QtFlagPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that produces the nested boolean subproperties + representing each flag. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager *QtFlagPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa flagNames(), setValue() +*/ +int QtFlagPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's list of flag names. + + \sa value(), setFlagNames() +*/ +QStringList QtFlagPropertyManager::flagNames(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList()); +} + +/*! + \reimp +*/ +QString QtFlagPropertyManager::valueText(const QtProperty *property) const +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtFlagPropertyManagerPrivate::Data &data = it.value(); + + QString str; + int level = 0; + const QChar bar = QLatin1Char('|'); + const QStringList::const_iterator fncend = data.flagNames.constEnd(); + for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it) { + if (data.val & (1 << level)) { + if (!str.isEmpty()) + str += bar; + str += *it; + } + + level++; + } + return str; +} + +/*! + \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + The specified \a value must be less than the binary combination of + the property's flagNames() list size (i.e. less than 2\sup n, + where \c n is the size of the list) and larger than (or equal to) + 0. + + \sa value(), valueChanged() +*/ +void QtFlagPropertyManager::setValue(QtProperty *property, int val) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (val > (1 << data.flagNames.count()) - 1) + return; + + if (val < 0) + return; + + data.val = val; + + it.value() = data; + + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + int level = 0; + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) + d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level)); + level++; + } + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of flag names to \a flagNames. The + property's current value is reset to 0 indicating the first item + of the list. + + \sa flagNames(), flagNamesChanged() +*/ +void QtFlagPropertyManager::setFlagNames(QtProperty *property, const QStringList &flagNames) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.flagNames == flagNames) + return; + + data.flagNames = flagNames; + data.val = 0; + + it.value() = data; + + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) { + delete prop; + d_ptr->m_flagToProperty.remove(prop); + } + } + d_ptr->m_propertyToFlags[property].clear(); + + QStringListIterator itFlag(flagNames); + while (itFlag.hasNext()) { + const QString flagName = itFlag.next(); + QtProperty *prop = d_ptr->m_boolPropertyManager->addProperty(); + prop->setPropertyName(flagName); + property->addSubProperty(prop); + d_ptr->m_propertyToFlags[property].append(prop); + d_ptr->m_flagToProperty[prop] = property; + } + + emit flagNamesChanged(property, data.flagNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtFlagPropertyManagerPrivate::Data(); + + d_ptr->m_propertyToFlags[property] = QList(); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::uninitializeProperty(QtProperty *property) +{ + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) { + delete prop; + d_ptr->m_flagToProperty.remove(prop); + } + } + d_ptr->m_propertyToFlags.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizePolicyPropertyManager + +/* +class QtSizePolicyPropertyManagerPrivate +{ + QtSizePolicyPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager) +public: + + QtSizePolicyPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToHPolicy; + QMap m_propertyToVPolicy; + QMap m_propertyToHStretch; + QMap m_propertyToVStretch; + + QMap m_hPolicyToProperty; + QMap m_vPolicyToProperty; + QMap m_hStretchToProperty; + QMap m_vStretchToProperty; +}; +*/ + +QtSizePolicyPropertyManagerPrivate::QtSizePolicyPropertyManagerPrivate() +{ +} + +void QtSizePolicyPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_hStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalStretch(value); + q_ptr->setValue(prop, sp); + } else if (QtProperty *prop = m_vStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalStretch(value); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_hPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } else if (QtProperty *prop = m_vPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_hStretchToProperty.value(property, 0)) { + m_propertyToHStretch[pointProp] = 0; + m_hStretchToProperty.remove(property); + } else if (QtProperty *pointProp = m_vStretchToProperty.value(property, 0)) { + m_propertyToVStretch[pointProp] = 0; + m_vStretchToProperty.remove(property); + } else if (QtProperty *pointProp = m_hPolicyToProperty.value(property, 0)) { + m_propertyToHPolicy[pointProp] = 0; + m_hPolicyToProperty.remove(property); + } else if (QtProperty *pointProp = m_vPolicyToProperty.value(property, 0)) { + m_propertyToVPolicy[pointProp] = 0; + m_vPolicyToProperty.remove(property); + } +} + +/*! + \class QtSizePolicyPropertyManager + + \brief The QtSizePolicyPropertyManager provides and manages QSizePolicy properties. + + A size policy property has nested \e horizontalPolicy, \e + verticalPolicy, \e horizontalStretch and \e verticalStretch + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager + objects. These managers can be retrieved using the subIntPropertyManager() + and subEnumPropertyManager() functions respectively. In order to provide + editing widgets for the subproperties in a property browser widget, + these managers must be associated with editor factories. + + In addition, QtSizePolicyPropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtSizePolicyPropertyManager::valueChanged(QtProperty *property, const QSizePolicy &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePolicyPropertyManager::QtSizePolicyPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizePolicyPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e horizontalStretch + and \e verticalStretch subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtSizePolicyPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that creates the nested \e horizontalPolicy + and \e verticalPolicy subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtSizePolicyPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default size policy. + + \sa setValue() +*/ +QSizePolicy QtSizePolicyPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QSizePolicy()); +} + +/*! + \reimp +*/ +QString QtSizePolicyPropertyManager::valueText(const QtProperty *property) const +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QSizePolicy sp = it.value(); + const QtMetaEnumProvider *mep = metaEnumProvider(); + const int hIndex = mep->sizePolicyToIndex(sp.horizontalPolicy()); + const int vIndex = mep->sizePolicyToIndex(sp.verticalPolicy()); + //! Unknown size policy on reading invalid uic3 files + const QString hPolicy = hIndex != -1 ? mep->policyEnumNames().at(hIndex) : tr(""); + const QString vPolicy = vIndex != -1 ? mep->policyEnumNames().at(vIndex) : tr(""); + const QString str = tr("[%1, %2, %3, %4]").arg(hPolicy, vPolicy).arg(sp.horizontalStretch()).arg(sp.verticalStretch()); + return str; +} + +/*! + \fn void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &val) +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToHPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToVPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToHStretch[property], + val.horizontalStretch()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToVStretch[property], + val.verticalStretch()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::initializeProperty(QtProperty *property) +{ + QSizePolicy val; + d_ptr->m_values[property] = val; + + QtProperty *hPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + hPolicyProp->setPropertyName(tr("Horizontal Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(hPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(hPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_propertyToHPolicy[property] = hPolicyProp; + d_ptr->m_hPolicyToProperty[hPolicyProp] = property; + property->addSubProperty(hPolicyProp); + + QtProperty *vPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + vPolicyProp->setPropertyName(tr("Vertical Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(vPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(vPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_propertyToVPolicy[property] = vPolicyProp; + d_ptr->m_vPolicyToProperty[vPolicyProp] = property; + property->addSubProperty(vPolicyProp); + + QtProperty *hStretchProp = d_ptr->m_intPropertyManager->addProperty(); + hStretchProp->setPropertyName(tr("Horizontal Stretch")); + d_ptr->m_intPropertyManager->setValue(hStretchProp, val.horizontalStretch()); + d_ptr->m_intPropertyManager->setRange(hStretchProp, 0, 0xff); + d_ptr->m_propertyToHStretch[property] = hStretchProp; + d_ptr->m_hStretchToProperty[hStretchProp] = property; + property->addSubProperty(hStretchProp); + + QtProperty *vStretchProp = d_ptr->m_intPropertyManager->addProperty(); + vStretchProp->setPropertyName(tr("Vertical Stretch")); + d_ptr->m_intPropertyManager->setValue(vStretchProp, val.verticalStretch()); + d_ptr->m_intPropertyManager->setRange(vStretchProp, 0, 0xff); + d_ptr->m_propertyToVStretch[property] = vStretchProp; + d_ptr->m_vStretchToProperty[vStretchProp] = property; + property->addSubProperty(vStretchProp); + +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *hPolicyProp = d_ptr->m_propertyToHPolicy[property]; + if (hPolicyProp) { + d_ptr->m_hPolicyToProperty.remove(hPolicyProp); + delete hPolicyProp; + } + d_ptr->m_propertyToHPolicy.remove(property); + + QtProperty *vPolicyProp = d_ptr->m_propertyToVPolicy[property]; + if (vPolicyProp) { + d_ptr->m_vPolicyToProperty.remove(vPolicyProp); + delete vPolicyProp; + } + d_ptr->m_propertyToVPolicy.remove(property); + + QtProperty *hStretchProp = d_ptr->m_propertyToHStretch[property]; + if (hStretchProp) { + d_ptr->m_hStretchToProperty.remove(hStretchProp); + delete hStretchProp; + } + d_ptr->m_propertyToHStretch.remove(property); + + QtProperty *vStretchProp = d_ptr->m_propertyToVStretch[property]; + if (vStretchProp) { + d_ptr->m_vStretchToProperty.remove(vStretchProp); + delete vStretchProp; + } + d_ptr->m_propertyToVStretch.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtFontPropertyManager: +// QtFontPropertyManagerPrivate has a mechanism for reacting +// to QApplication::fontDatabaseChanged() [4.5], which is emitted +// when someone loads an application font. The signals are compressed +// using a timer with interval 0, which then causes the family +// enumeration manager to re-set its strings and index values +// for each property. + +Q_GLOBAL_STATIC(QFontDatabase, fontDatabase) + + /* +class QtFontPropertyManagerPrivate +{ + QtFontPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFontPropertyManager) +public: + + QtFontPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + void slotFontDatabaseChanged(); + void slotFontDatabaseDelayedChange(); + + QStringList m_familyNames; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + QtBoolPropertyManager *m_boolPropertyManager; + + QMap m_propertyToFamily; + QMap m_propertyToPointSize; + QMap m_propertyToBold; + QMap m_propertyToItalic; + QMap m_propertyToUnderline; + QMap m_propertyToStrikeOut; + QMap m_propertyToKerning; + + QMap m_familyToProperty; + QMap m_pointSizeToProperty; + QMap m_boldToProperty; + QMap m_italicToProperty; + QMap m_underlineToProperty; + QMap m_strikeOutToProperty; + QMap m_kerningToProperty; + + bool m_settingValue; + QTimer *m_fontDatabaseChangeTimer; +}; +*/ + +QtFontPropertyManagerPrivate::QtFontPropertyManagerPrivate() : + m_settingValue(false), + m_fontDatabaseChangeTimer(0) +{ +} + +void QtFontPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_pointSizeToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setPointSize(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_familyToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setFamily(m_familyNames.at(value)); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_boldToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setBold(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_italicToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setItalic(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_underlineToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setUnderline(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_strikeOutToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setStrikeOut(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_kerningToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setKerning(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_pointSizeToProperty.value(property, 0)) { + m_propertyToPointSize[pointProp] = 0; + m_pointSizeToProperty.remove(property); + } else if (QtProperty *pointProp = m_familyToProperty.value(property, 0)) { + m_propertyToFamily[pointProp] = 0; + m_familyToProperty.remove(property); + } else if (QtProperty *pointProp = m_boldToProperty.value(property, 0)) { + m_propertyToBold[pointProp] = 0; + m_boldToProperty.remove(property); + } else if (QtProperty *pointProp = m_italicToProperty.value(property, 0)) { + m_propertyToItalic[pointProp] = 0; + m_italicToProperty.remove(property); + } else if (QtProperty *pointProp = m_underlineToProperty.value(property, 0)) { + m_propertyToUnderline[pointProp] = 0; + m_underlineToProperty.remove(property); + } else if (QtProperty *pointProp = m_strikeOutToProperty.value(property, 0)) { + m_propertyToStrikeOut[pointProp] = 0; + m_strikeOutToProperty.remove(property); + } else if (QtProperty *pointProp = m_kerningToProperty.value(property, 0)) { + m_propertyToKerning[pointProp] = 0; + m_kerningToProperty.remove(property); + } +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseChanged() +{ + if (!m_fontDatabaseChangeTimer) { + m_fontDatabaseChangeTimer = new QTimer(q_ptr); + m_fontDatabaseChangeTimer->setInterval(0); + m_fontDatabaseChangeTimer->setSingleShot(true); + QObject::connect(m_fontDatabaseChangeTimer, SIGNAL(timeout()), q_ptr, SLOT(slotFontDatabaseDelayedChange())); + } + if (!m_fontDatabaseChangeTimer->isActive()) + m_fontDatabaseChangeTimer->start(); +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange() +{ + typedef QMap PropertyPropertyMap; + // rescan available font names + const QStringList oldFamilies = m_familyNames; + m_familyNames = fontDatabase()->families(); + + // Adapt all existing properties + if (!m_propertyToFamily.empty()) { + PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd(); + for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) { + QtProperty *familyProp = it.value(); + const int oldIdx = m_enumPropertyManager->value(familyProp); + int newIdx = m_familyNames.indexOf(oldFamilies.at(oldIdx)); + if (newIdx < 0) + newIdx = 0; + m_enumPropertyManager->setEnumNames(familyProp, m_familyNames); + m_enumPropertyManager->setValue(familyProp, newIdx); + } + } +} + +/*! + \class QtFontPropertyManager + + \brief The QtFontPropertyManager provides and manages QFont properties. + + A font property has nested \e family, \e pointSize, \e bold, \e + italic, \e underline, \e strikeOut and \e kerning subproperties. The top-level + property's value can be retrieved using the value() function, and + set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and + QtBoolPropertyManager objects. These managers can be retrieved using the + corresponding subIntPropertyManager(), subEnumPropertyManager() and + subBoolPropertyManager() functions. In order to provide editing widgets + for the subproperties in a property browser widget, these managers + must be associated with editor factories. + + In addition, QtFontPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFontPropertyManager::valueChanged(QtProperty *property, const QFont &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFontPropertyManager::QtFontPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtFontPropertyManagerPrivate; + d_ptr->q_ptr = this; +#if QT_VERSION >= 0x040500 + QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged())); +#endif + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotBoolChanged(QtProperty *, bool))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFontPropertyManager::~QtFontPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the \e pointSize subproperty. + + In order to provide editing widgets for the \e pointSize property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtFontPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that create the \e family subproperty. + + In order to provide editing widgets for the \e family property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtFontPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the manager that creates the \e bold, \e italic, \e underline, + \e strikeOut and \e kerning subproperties. + + In order to provide editing widgets for the mentioned properties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager *QtFontPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns a font object that uses the application's default + font. + + \sa setValue() +*/ +QFont QtFontPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QFont()); +} + +/*! + \reimp +*/ +QString QtFontPropertyManager::valueText(const QtProperty *property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::fontValueText(it.value()); +} + +/*! + \reimp +*/ +QIcon QtFontPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return QtPropertyBrowserUtils::fontValueIcon(it.value()); +} + +/*! + \fn void QtFontPropertyManager::setValue(QtProperty *property, const QFont &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val) +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QFont oldVal = it.value(); + if (oldVal == val && oldVal.resolve() == val.resolve()) + return; + + it.value() = val; + + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + bool settingValue = d_ptr->m_settingValue; + d_ptr->m_settingValue = true; + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToFamily[property], idx); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToPointSize[property], val.pointSize()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToBold[property], val.bold()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToItalic[property], val.italic()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToUnderline[property], val.underline()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToStrikeOut[property], val.strikeOut()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToKerning[property], val.kerning()); + d_ptr->m_settingValue = settingValue; + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::initializeProperty(QtProperty *property) +{ + QFont val; + d_ptr->m_values[property] = val; + + QtProperty *familyProp = d_ptr->m_enumPropertyManager->addProperty(); + familyProp->setPropertyName(tr("Family")); + if (d_ptr->m_familyNames.empty()) + d_ptr->m_familyNames = fontDatabase()->families(); + d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames); + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + d_ptr->m_enumPropertyManager->setValue(familyProp, idx); + d_ptr->m_propertyToFamily[property] = familyProp; + d_ptr->m_familyToProperty[familyProp] = property; + property->addSubProperty(familyProp); + + QtProperty *pointSizeProp = d_ptr->m_intPropertyManager->addProperty(); + pointSizeProp->setPropertyName(tr("Point Size")); + d_ptr->m_intPropertyManager->setValue(pointSizeProp, val.pointSize()); + d_ptr->m_intPropertyManager->setMinimum(pointSizeProp, 1); + d_ptr->m_propertyToPointSize[property] = pointSizeProp; + d_ptr->m_pointSizeToProperty[pointSizeProp] = property; + property->addSubProperty(pointSizeProp); + + QtProperty *boldProp = d_ptr->m_boolPropertyManager->addProperty(); + boldProp->setPropertyName(tr("Bold")); + d_ptr->m_boolPropertyManager->setValue(boldProp, val.bold()); + d_ptr->m_propertyToBold[property] = boldProp; + d_ptr->m_boldToProperty[boldProp] = property; + property->addSubProperty(boldProp); + + QtProperty *italicProp = d_ptr->m_boolPropertyManager->addProperty(); + italicProp->setPropertyName(tr("Italic")); + d_ptr->m_boolPropertyManager->setValue(italicProp, val.italic()); + d_ptr->m_propertyToItalic[property] = italicProp; + d_ptr->m_italicToProperty[italicProp] = property; + property->addSubProperty(italicProp); + + QtProperty *underlineProp = d_ptr->m_boolPropertyManager->addProperty(); + underlineProp->setPropertyName(tr("Underline")); + d_ptr->m_boolPropertyManager->setValue(underlineProp, val.underline()); + d_ptr->m_propertyToUnderline[property] = underlineProp; + d_ptr->m_underlineToProperty[underlineProp] = property; + property->addSubProperty(underlineProp); + + QtProperty *strikeOutProp = d_ptr->m_boolPropertyManager->addProperty(); + strikeOutProp->setPropertyName(tr("Strikeout")); + d_ptr->m_boolPropertyManager->setValue(strikeOutProp, val.strikeOut()); + d_ptr->m_propertyToStrikeOut[property] = strikeOutProp; + d_ptr->m_strikeOutToProperty[strikeOutProp] = property; + property->addSubProperty(strikeOutProp); + + QtProperty *kerningProp = d_ptr->m_boolPropertyManager->addProperty(); + kerningProp->setPropertyName(tr("Kerning")); + d_ptr->m_boolPropertyManager->setValue(kerningProp, val.kerning()); + d_ptr->m_propertyToKerning[property] = kerningProp; + d_ptr->m_kerningToProperty[kerningProp] = property; + property->addSubProperty(kerningProp); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *familyProp = d_ptr->m_propertyToFamily[property]; + if (familyProp) { + d_ptr->m_familyToProperty.remove(familyProp); + delete familyProp; + } + d_ptr->m_propertyToFamily.remove(property); + + QtProperty *pointSizeProp = d_ptr->m_propertyToPointSize[property]; + if (pointSizeProp) { + d_ptr->m_pointSizeToProperty.remove(pointSizeProp); + delete pointSizeProp; + } + d_ptr->m_propertyToPointSize.remove(property); + + QtProperty *boldProp = d_ptr->m_propertyToBold[property]; + if (boldProp) { + d_ptr->m_boldToProperty.remove(boldProp); + delete boldProp; + } + d_ptr->m_propertyToBold.remove(property); + + QtProperty *italicProp = d_ptr->m_propertyToItalic[property]; + if (italicProp) { + d_ptr->m_italicToProperty.remove(italicProp); + delete italicProp; + } + d_ptr->m_propertyToItalic.remove(property); + + QtProperty *underlineProp = d_ptr->m_propertyToUnderline[property]; + if (underlineProp) { + d_ptr->m_underlineToProperty.remove(underlineProp); + delete underlineProp; + } + d_ptr->m_propertyToUnderline.remove(property); + + QtProperty *strikeOutProp = d_ptr->m_propertyToStrikeOut[property]; + if (strikeOutProp) { + d_ptr->m_strikeOutToProperty.remove(strikeOutProp); + delete strikeOutProp; + } + d_ptr->m_propertyToStrikeOut.remove(property); + + QtProperty *kerningProp = d_ptr->m_propertyToKerning[property]; + if (kerningProp) { + d_ptr->m_kerningToProperty.remove(kerningProp); + delete kerningProp; + } + d_ptr->m_propertyToKerning.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtColorPropertyManager + +/* +class QtColorPropertyManagerPrivate +{ + QtColorPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtColorPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToR; + QMap m_propertyToG; + QMap m_propertyToB; + QMap m_propertyToA; + + QMap m_rToProperty; + QMap m_gToProperty; + QMap m_bToProperty; + QMap m_aToProperty; +}; +*/ + +void QtColorPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_rToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setRed(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_gToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setGreen(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_bToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setBlue(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_aToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setAlpha(value); + q_ptr->setValue(prop, c); + } +} + +void QtColorPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_rToProperty.value(property, 0)) { + m_propertyToR[pointProp] = 0; + m_rToProperty.remove(property); + } else if (QtProperty *pointProp = m_gToProperty.value(property, 0)) { + m_propertyToG[pointProp] = 0; + m_gToProperty.remove(property); + } else if (QtProperty *pointProp = m_bToProperty.value(property, 0)) { + m_propertyToB[pointProp] = 0; + m_bToProperty.remove(property); + } else if (QtProperty *pointProp = m_aToProperty.value(property, 0)) { + m_propertyToA[pointProp] = 0; + m_aToProperty.remove(property); + } +} + +/*! + \class QtColorPropertyManager + + \brief The QtColorPropertyManager provides and manages QColor properties. + + A color property has nested \e red, \e green and \e blue + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtColorPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser, QtIntPropertyManager +*/ + +/*! + \fn void QtColorPropertyManager::valueChanged(QtProperty *property, const QColor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtColorPropertyManager::QtColorPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtColorPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtColorPropertyManager::~QtColorPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that produces the nested \e red, \e green and + \e blue subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtColorPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid color. + + \sa setValue() +*/ +QColor QtColorPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QColor()); +} + +/*! + \reimp +*/ + +QString QtColorPropertyManager::valueText(const QtProperty *property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::colorValueText(it.value()); +} + +/*! + \reimp +*/ + +QIcon QtColorPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + return QtPropertyBrowserUtils::brushValueIcon(QBrush(it.value())); +} + +/*! + \fn void QtColorPropertyManager::setValue(QtProperty *property, const QColor &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtColorPropertyManager::setValue(QtProperty *property, const QColor &val) +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToR[property], val.red()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToG[property], val.green()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToB[property], val.blue()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToA[property], val.alpha()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::initializeProperty(QtProperty *property) +{ + QColor val; + d_ptr->m_values[property] = val; + + QtProperty *rProp = d_ptr->m_intPropertyManager->addProperty(); + rProp->setPropertyName(tr("Red")); + d_ptr->m_intPropertyManager->setValue(rProp, val.red()); + d_ptr->m_intPropertyManager->setRange(rProp, 0, 0xFF); + d_ptr->m_propertyToR[property] = rProp; + d_ptr->m_rToProperty[rProp] = property; + property->addSubProperty(rProp); + + QtProperty *gProp = d_ptr->m_intPropertyManager->addProperty(); + gProp->setPropertyName(tr("Green")); + d_ptr->m_intPropertyManager->setValue(gProp, val.green()); + d_ptr->m_intPropertyManager->setRange(gProp, 0, 0xFF); + d_ptr->m_propertyToG[property] = gProp; + d_ptr->m_gToProperty[gProp] = property; + property->addSubProperty(gProp); + + QtProperty *bProp = d_ptr->m_intPropertyManager->addProperty(); + bProp->setPropertyName(tr("Blue")); + d_ptr->m_intPropertyManager->setValue(bProp, val.blue()); + d_ptr->m_intPropertyManager->setRange(bProp, 0, 0xFF); + d_ptr->m_propertyToB[property] = bProp; + d_ptr->m_bToProperty[bProp] = property; + property->addSubProperty(bProp); + + QtProperty *aProp = d_ptr->m_intPropertyManager->addProperty(); + aProp->setPropertyName(tr("Alpha")); + d_ptr->m_intPropertyManager->setValue(aProp, val.alpha()); + d_ptr->m_intPropertyManager->setRange(aProp, 0, 0xFF); + d_ptr->m_propertyToA[property] = aProp; + d_ptr->m_aToProperty[aProp] = property; + property->addSubProperty(aProp); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *rProp = d_ptr->m_propertyToR[property]; + if (rProp) { + d_ptr->m_rToProperty.remove(rProp); + delete rProp; + } + d_ptr->m_propertyToR.remove(property); + + QtProperty *gProp = d_ptr->m_propertyToG[property]; + if (gProp) { + d_ptr->m_gToProperty.remove(gProp); + delete gProp; + } + d_ptr->m_propertyToG.remove(property); + + QtProperty *bProp = d_ptr->m_propertyToB[property]; + if (bProp) { + d_ptr->m_bToProperty.remove(bProp); + delete bProp; + } + d_ptr->m_propertyToB.remove(property); + + QtProperty *aProp = d_ptr->m_propertyToA[property]; + if (aProp) { + d_ptr->m_aToProperty.remove(aProp); + delete aProp; + } + d_ptr->m_propertyToA.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtCursorPropertyManager + +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + +class QtCursorPropertyManagerPrivate +{ + QtCursorPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtCursorPropertyManager) +public: + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtCursorPropertyManager + + \brief The QtCursorPropertyManager provides and manages QCursor properties. + + A cursor property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtCursorPropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCursorPropertyManager::valueChanged(QtProperty *property, const QCursor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCursorPropertyManager::QtCursorPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtCursorPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCursorPropertyManager::~QtCursorPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a default QCursor object. + + \sa setValue() +*/ +#ifndef QT_NO_CURSOR +QCursor QtCursorPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QCursor()); +} +#endif + +/*! + \reimp +*/ +QString QtCursorPropertyManager::valueText(const QtProperty *property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return cursorDatabase()->cursorToShapeName(it.value()); +} + +/*! + \reimp +*/ +QIcon QtCursorPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return cursorDatabase()->cursorToShapeIcon(it.value()); +} + +/*! + \fn void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value) +{ +#ifndef QT_NO_CURSOR + const QtCursorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().shape() == value.shape() && value.shape() != Qt::BitmapCursor) + return; + + it.value() = value; + + emit propertyChanged(property); + emit valueChanged(property, value); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::initializeProperty(QtProperty *property) +{ +#ifndef QT_NO_CURSOR + d_ptr->m_values[property] = QCursor(); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qtpropertymanager.cpp" +//#include "qtpropertymanager.moc" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertymanager.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertymanager.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtpropertymanager.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtpropertymanager.h 2011-01-20 14:44:20.000000000 +0000 @@ -0,0 +1,1159 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#ifndef QTPROPERTYMANAGER_H +#define QTPROPERTYMANAGER_H + +#include "qtpropertybrowser.h" + +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QDate; +class QTime; +class QDateTime; +class QLocale; + +template +static void setSimpleMinimumData(PrivateData *data, const Value &minVal) +{ + data->minVal = minVal; + if (data->maxVal < data->minVal) + data->maxVal = data->minVal; + + if (data->val < data->minVal) + data->val = data->minVal; +} + +template +static void setSimpleMaximumData(PrivateData *data, const Value &maxVal) +{ + data->maxVal = maxVal; + if (data->minVal > data->maxVal) + data->minVal = data->maxVal; + + if (data->val > data->maxVal) + data->val = data->maxVal; +} + + +template +static void setSizeMinimumData(PrivateData *data, const Value &newMinVal) +{ + data->minVal = newMinVal; + if (data->maxVal.width() < data->minVal.width()) + data->maxVal.setWidth(data->minVal.width()); + if (data->maxVal.height() < data->minVal.height()) + data->maxVal.setHeight(data->minVal.height()); + + if (data->val.width() < data->minVal.width()) + data->val.setWidth(data->minVal.width()); + if (data->val.height() < data->minVal.height()) + data->val.setHeight(data->minVal.height()); +} + +template +static void setSizeMaximumData(PrivateData *data, const Value &newMaxVal) +{ + data->maxVal = newMaxVal; + if (data->minVal.width() > data->maxVal.width()) + data->minVal.setWidth(data->maxVal.width()); + if (data->minVal.height() > data->maxVal.height()) + data->minVal.setHeight(data->maxVal.height()); + + if (data->val.width() > data->maxVal.width()) + data->val.setWidth(data->maxVal.width()); + if (data->val.height() > data->maxVal.height()) + data->val.setHeight(data->maxVal.height()); +} + + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtGroupPropertyManager(QObject *parent = 0); + ~QtGroupPropertyManager(); + +protected: + virtual bool hasValue(const QtProperty *property) const; + + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +}; + +class QtIntPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtIntPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtIntPropertyManager(QObject *parent = 0); + ~QtIntPropertyManager(); + + int value(const QtProperty *property) const; + int minimum(const QtProperty *property) const; + int maximum(const QtProperty *property) const; + int singleStep(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setMinimum(QtProperty *property, int minVal); + void setMaximum(QtProperty *property, int maxVal); + void setRange(QtProperty *property, int minVal, int maxVal); + void setSingleStep(QtProperty *property, int step); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void rangeChanged(QtProperty *property, int minVal, int maxVal); + void singleStepChanged(QtProperty *property, int step); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtIntPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtIntPropertyManager) + Q_DISABLE_COPY(QtIntPropertyManager) +}; + +class QtBoolPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBoolPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtBoolPropertyManager(QObject *parent = 0); + ~QtBoolPropertyManager(); + + bool value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, bool val); +Q_SIGNALS: + void valueChanged(QtProperty *property, bool val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtBoolPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtBoolPropertyManager) + Q_DISABLE_COPY(QtBoolPropertyManager) +}; + +class QtDoublePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoublePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDoublePropertyManager(QObject *parent = 0); + ~QtDoublePropertyManager(); + + double value(const QtProperty *property) const; + double minimum(const QtProperty *property) const; + double maximum(const QtProperty *property) const; + double singleStep(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, double val); + void setMinimum(QtProperty *property, double minVal); + void setMaximum(QtProperty *property, double maxVal); + void setRange(QtProperty *property, double minVal, double maxVal); + void setSingleStep(QtProperty *property, double step); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, double val); + void rangeChanged(QtProperty *property, double minVal, double maxVal); + void singleStepChanged(QtProperty *property, double step); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDoublePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDoublePropertyManager) + Q_DISABLE_COPY(QtDoublePropertyManager) +}; + +class QtStringPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtStringPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtStringPropertyManager(QObject *parent = 0); + ~QtStringPropertyManager(); + + QString value(const QtProperty *property) const; + QRegExp regExp(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QString &val); + void setRegExp(QtProperty *property, const QRegExp ®Exp); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QString &val); + void regExpChanged(QtProperty *property, const QRegExp ®Exp); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtStringPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtStringPropertyManager) + Q_DISABLE_COPY(QtStringPropertyManager) +}; + +class QtDatePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDatePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDatePropertyManager(QObject *parent = 0); + ~QtDatePropertyManager(); + + QDate value(const QtProperty *property) const; + QDate minimum(const QtProperty *property) const; + QDate maximum(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QDate &val); + void setMinimum(QtProperty *property, const QDate &minVal); + void setMaximum(QtProperty *property, const QDate &maxVal); + void setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QDate &val); + void rangeChanged(QtProperty *property, const QDate &minVal, const QDate &maxVal); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDatePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDatePropertyManager) + Q_DISABLE_COPY(QtDatePropertyManager) +}; + +class QtTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtTimePropertyManager(QObject *parent = 0); + ~QtTimePropertyManager(); + + QTime value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QTime &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QTime &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtTimePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTimePropertyManager) + Q_DISABLE_COPY(QtTimePropertyManager) +}; + +class QtDateTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDateTimePropertyManager(QObject *parent = 0); + ~QtDateTimePropertyManager(); + + QDateTime value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QDateTime &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QDateTime &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDateTimePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateTimePropertyManager) + Q_DISABLE_COPY(QtDateTimePropertyManager) +}; + +class QtKeySequencePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequencePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtKeySequencePropertyManager(QObject *parent = 0); + ~QtKeySequencePropertyManager(); + + QKeySequence value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QKeySequence &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QKeySequence &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtKeySequencePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtKeySequencePropertyManager) + Q_DISABLE_COPY(QtKeySequencePropertyManager) +}; + +class QtCharPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCharPropertyManager(QObject *parent = 0); + ~QtCharPropertyManager(); + + QChar value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QChar &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QChar &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtCharPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCharPropertyManager) + Q_DISABLE_COPY(QtCharPropertyManager) +}; + +class QtEnumPropertyManager; +class QtLocalePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLocalePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtLocalePropertyManager(QObject *parent = 0); + ~QtLocalePropertyManager(); + + QtEnumPropertyManager *subEnumPropertyManager() const; + + QLocale value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QLocale &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QLocale &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtLocalePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtLocalePropertyManager) + Q_DISABLE_COPY(QtLocalePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtPointPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointPropertyManager(QObject *parent = 0); + ~QtPointPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QPoint value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QPoint &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QPoint &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtPointPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtPointPropertyManager) + Q_DISABLE_COPY(QtPointPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtPointFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointFPropertyManager(QObject *parent = 0); + ~QtPointFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QPointF value(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QPointF &val); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QPointF &val); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtPointFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtPointFPropertyManager) + Q_DISABLE_COPY(QtPointFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePropertyManager(QObject *parent = 0); + ~QtSizePropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QSize value(const QtProperty *property) const; + QSize minimum(const QtProperty *property) const; + QSize maximum(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSize &val); + void setMinimum(QtProperty *property, const QSize &minVal); + void setMaximum(QtProperty *property, const QSize &maxVal); + void setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSize &val); + void rangeChanged(QtProperty *property, const QSize &minVal, const QSize &maxVal); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizePropertyManager) + Q_DISABLE_COPY(QtSizePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizeFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizeFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizeFPropertyManager(QObject *parent = 0); + ~QtSizeFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QSizeF value(const QtProperty *property) const; + QSizeF minimum(const QtProperty *property) const; + QSizeF maximum(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSizeF &val); + void setMinimum(QtProperty *property, const QSizeF &minVal); + void setMaximum(QtProperty *property, const QSizeF &maxVal); + void setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSizeF &val); + void rangeChanged(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizeFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizeFPropertyManager) + Q_DISABLE_COPY(QtSizeFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtRectPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectPropertyManager(QObject *parent = 0); + ~QtRectPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QRect value(const QtProperty *property) const; + QRect constraint(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QRect &val); + void setConstraint(QtProperty *property, const QRect &constraint); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QRect &val); + void constraintChanged(QtProperty *property, const QRect &constraint); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtRectPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtRectPropertyManager) + Q_DISABLE_COPY(QtRectPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtRectFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectFPropertyManager(QObject *parent = 0); + ~QtRectFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QRectF value(const QtProperty *property) const; + QRectF constraint(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QRectF &val); + void setConstraint(QtProperty *property, const QRectF &constraint); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QRectF &val); + void constraintChanged(QtProperty *property, const QRectF &constraint); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtRectFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtRectFPropertyManager) + Q_DISABLE_COPY(QtRectFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtEnumPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtEnumPropertyManager(QObject *parent = 0); + ~QtEnumPropertyManager(); + + int value(const QtProperty *property) const; + QStringList enumNames(const QtProperty *property) const; + QMap enumIcons(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setEnumNames(QtProperty *property, const QStringList &names); + void setEnumIcons(QtProperty *property, const QMap &icons); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void enumNamesChanged(QtProperty *property, const QStringList &names); + void enumIconsChanged(QtProperty *property, const QMap &icons); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtEnumPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtEnumPropertyManager) + Q_DISABLE_COPY(QtEnumPropertyManager) +}; + +class QtFlagPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFlagPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFlagPropertyManager(QObject *parent = 0); + ~QtFlagPropertyManager(); + + QtBoolPropertyManager *subBoolPropertyManager() const; + + int value(const QtProperty *property) const; + QStringList flagNames(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setFlagNames(QtProperty *property, const QStringList &names); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void flagNamesChanged(QtProperty *property, const QStringList &names); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtFlagPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFlagPropertyManager) + Q_DISABLE_COPY(QtFlagPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizePolicyPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePolicyPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePolicyPropertyManager(QObject *parent = 0); + ~QtSizePolicyPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + QtEnumPropertyManager *subEnumPropertyManager() const; + + QSizePolicy value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSizePolicy &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSizePolicy &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizePolicyPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizePolicyPropertyManager) + Q_DISABLE_COPY(QtSizePolicyPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtFontPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFontPropertyManager(QObject *parent = 0); + ~QtFontPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + QtEnumPropertyManager *subEnumPropertyManager() const; + QtBoolPropertyManager *subBoolPropertyManager() const; + + QFont value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QFont &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QFont &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtFontPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFontPropertyManager) + Q_DISABLE_COPY(QtFontPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseChanged()) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseDelayedChange()) +}; + +class QtColorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtColorPropertyManager(QObject *parent = 0); + ~QtColorPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QColor value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QColor &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QColor &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtColorPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtColorPropertyManager) + Q_DISABLE_COPY(QtColorPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtCursorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCursorPropertyManager(QObject *parent = 0); + ~QtCursorPropertyManager(); + +#ifndef QT_NO_CURSOR + QCursor value(const QtProperty *property) const; +#endif + +public Q_SLOTS: + void setValue(QtProperty *property, const QCursor &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QCursor &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtCursorPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCursorPropertyManager) + Q_DISABLE_COPY(QtCursorPropertyManager) +}; + +class QtLocalePropertyManagerPrivate +{ + QtLocalePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtLocalePropertyManager) +public: + + QtLocalePropertyManagerPrivate(); + + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToLanguage; + QMap m_propertyToCountry; + + QMap m_languageToProperty; + QMap m_countryToProperty; +}; + +class QtPointPropertyManagerPrivate +{ + QtPointPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +class QtFontPropertyManagerPrivate +{ + QtFontPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFontPropertyManager) +public: + + QtFontPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + void slotFontDatabaseChanged(); + void slotFontDatabaseDelayedChange(); + + QStringList m_familyNames; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + QtBoolPropertyManager *m_boolPropertyManager; + + QMap m_propertyToFamily; + QMap m_propertyToPointSize; + QMap m_propertyToBold; + QMap m_propertyToItalic; + QMap m_propertyToUnderline; + QMap m_propertyToStrikeOut; + QMap m_propertyToKerning; + + QMap m_familyToProperty; + QMap m_pointSizeToProperty; + QMap m_boldToProperty; + QMap m_italicToProperty; + QMap m_underlineToProperty; + QMap m_strikeOutToProperty; + QMap m_kerningToProperty; + + bool m_settingValue; + QTimer *m_fontDatabaseChangeTimer; +}; + +class QtColorPropertyManagerPrivate +{ + QtColorPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtColorPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToR; + QMap m_propertyToG; + QMap m_propertyToB; + QMap m_propertyToA; + + QMap m_rToProperty; + QMap m_gToProperty; + QMap m_bToProperty; + QMap m_aToProperty; +}; + +class QtSizePolicyPropertyManagerPrivate +{ + QtSizePolicyPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager) +public: + + QtSizePolicyPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToHPolicy; + QMap m_propertyToVPolicy; + QMap m_propertyToHStretch; + QMap m_propertyToVStretch; + + QMap m_hPolicyToProperty; + QMap m_vPolicyToProperty; + QMap m_hStretchToProperty; + QMap m_vStretchToProperty; +}; + +class QtSizeFPropertyManagerPrivate +{ + QtSizeFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizeFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSizeF &val); + void setRange(QtProperty *property, + const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val); + + struct Data + { + Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {} + QSizeF val; + QSizeF minVal; + QSizeF maxVal; + int decimals; + QSizeF minimumValue() const { return minVal; } + QSizeF maximumValue() const { return maxVal; } + void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSizeF &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +class QtPointFPropertyManagerPrivate +{ + QtPointFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointFPropertyManager) +public: + + struct Data + { + Data() : decimals(2) {} + QPointF val; + int decimals; + }; + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +class QtSizePropertyManagerPrivate +{ + QtSizePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSize &val); + void setRange(QtProperty *property, + const QSize &minVal, const QSize &maxVal, const QSize &val); + + struct Data + { + Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {} + QSize val; + QSize minVal; + QSize maxVal; + QSize minimumValue() const { return minVal; } + QSize maximumValue() const { return maxVal; } + void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSize &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +class QtRectPropertyManagerPrivate +{ + QtRectPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRect &constraint, const QRect &val); + + struct Data + { + Data() : val(0, 0, 0, 0) {} + QRect val; + QRect constraint; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +class QtRectFPropertyManagerPrivate +{ + QtRectFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRectF &constraint, const QRectF &val); + + struct Data + { + Data() : val(0, 0, 0, 0), decimals(2) {} + QRectF val; + QRectF constraint; + int decimals; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +class QtFlagPropertyManagerPrivate +{ + QtFlagPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFlagPropertyManager) +public: + + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + + struct Data + { + Data() : val(-1) {} + int val; + QStringList flagNames; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtBoolPropertyManager *m_boolPropertyManager; + + QMap > m_propertyToFlags; + + QMap m_flagToProperty; +}; + +class QtMetaEnumWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSizePolicy::Policy policy READ policy) +public: + QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; } +private: + QtMetaEnumWrapper(QObject *parent) : QObject(parent) {} +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,1050 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qttreepropertybrowser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtPropertyEditorView; + +/* +class QtTreePropertyBrowserPrivate +{ + QtTreePropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtTreePropertyBrowser) + +public: + QtTreePropertyBrowserPrivate(); + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + QtProperty *indexToProperty(const QModelIndex &index) const; + QTreeWidgetItem *indexToItem(const QModelIndex &index) const; + QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const; + bool lastColumn(int column) const; + void disableItem(QTreeWidgetItem *item) const; + void enableItem(QTreeWidgetItem *item) const; + bool hasValue(QTreeWidgetItem *item) const; + + void slotCollapsed(const QModelIndex &index); + void slotExpanded(const QModelIndex &index); + + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + QtPropertyEditorView *treeWidget() const { return m_treeWidget; } + bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; } + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *browserItem, bool block); + void editItem(QtBrowserItem *browserItem); + + void slotCurrentBrowserItemChanged(QtBrowserItem *item); + void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *); + + QTreeWidgetItem *editedItem() const; + +private: + void updateItem(QTreeWidgetItem *item); + + QMap m_indexToItem; + QMap m_itemToIndex; + + QMap m_indexToBackgroundColor; + + QtPropertyEditorView *m_treeWidget; + + bool m_headerVisible; + QtTreePropertyBrowser::ResizeMode m_resizeMode; + class QtPropertyEditorDelegate *m_delegate; + bool m_markPropertiesWithoutValue; + bool m_browserChangedBlocked; + QIcon m_expandIcon; +}; +*/ + +// ------------ QtPropertyEditorView +/* +class QtPropertyEditorView : public QTreeWidget +{ + Q_OBJECT +public: + QtPropertyEditorView(QWidget *parent = 0); + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QTreeWidgetItem *indexToItem(const QModelIndex &index) const + { return itemFromIndex(index); } + +protected: + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + QtTreePropertyBrowserPrivate *m_editorPrivate; +}; +*/ + +QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) : + QTreeWidget(parent), + m_editorPrivate(0) +{ + connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); +} + +void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItemV3 opt = option; + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + hasValue = property->hasValue(); + } + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + const QColor c = option.palette.color(QPalette::Dark); + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c); + } else { + const QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid()) { + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c.lighter(112)); + } + } + QTreeWidget::drawRow(painter, opt, index); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); + painter->restore(); +} + +void QtPropertyEditorView::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Space: // Trigger Edit + if (!m_editorPrivate->editedItem()) + if (const QTreeWidgetItem *item = currentItem()) + if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + event->accept(); + // If the current position is at column 0, move to 1. + QModelIndex index = currentIndex(); + if (index.column() == 0) { + index = index.sibling(index.row(), 1); + setCurrentIndex(index); + } + edit(index); + return; + } + break; + default: + break; + } + QTreeWidget::keyPressEvent(event); +} + +void QtPropertyEditorView::mousePressEvent(QMouseEvent *event) +{ + QTreeWidget::mousePressEvent(event); + QTreeWidgetItem *item = itemAt(event->pos()); + + if (item) { + if ((item != m_editorPrivate->editedItem()) && (event->button() == Qt::LeftButton) + && (header()->logicalIndexAt(event->pos().x()) == 1) + && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + editItem(item, 1); + } else if (!m_editorPrivate->hasValue(item) && m_editorPrivate->markPropertiesWithoutValue() && !rootIsDecorated()) { + if (event->pos().x() + header()->offset() < 20) + item->setExpanded(!item->isExpanded()); + } + } +} + +// ------------ QtPropertyEditorDelegate +/* +class QtPropertyEditorDelegate : public QItemDelegate +{ + Q_OBJECT +public: + QtPropertyEditorDelegate(QObject *parent = 0) + : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0) + {} + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setModelData(QWidget *, QAbstractItemModel *, + const QModelIndex &) const {} + + void setEditorData(QWidget *, const QModelIndex &) const {} + + bool eventFilter(QObject *object, QEvent *event); + void closeEditor(QtProperty *property); + + QTreeWidgetItem *editedItem() const { return m_editedItem; } + +private slots: + void slotEditorDestroyed(QObject *object); + +private: + int indentation(const QModelIndex &index) const; + + typedef QMap EditorToPropertyMap; + mutable EditorToPropertyMap m_editorToProperty; + + typedef QMap PropertyToEditorMap; + mutable PropertyToEditorMap m_propertyToEditor; + QtTreePropertyBrowserPrivate *m_editorPrivate; + mutable QTreeWidgetItem *m_editedItem; + mutable QWidget *m_editedWidget; +}; +*/ + +int QtPropertyEditorDelegate::indentation(const QModelIndex &index) const +{ + if (!m_editorPrivate) + return 0; + + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + int indent = 0; + while (item->parent()) { + item = item->parent(); + ++indent; + } + if (m_editorPrivate->treeWidget()->rootIsDecorated()) + ++indent; + return indent * m_editorPrivate->treeWidget()->indentation(); +} + +void QtPropertyEditorDelegate::slotEditorDestroyed(QObject *object) +{ + if (QWidget *w = qobject_cast(object)) { + const EditorToPropertyMap::iterator it = m_editorToProperty.find(w); + if (it != m_editorToProperty.end()) { + m_propertyToEditor.remove(it.value()); + m_editorToProperty.erase(it); + } + if (m_editedWidget == w) { + m_editedWidget = 0; + m_editedItem = 0; + } + } +} + +void QtPropertyEditorDelegate::closeEditor(QtProperty *property) +{ + if (QWidget *w = m_propertyToEditor.value(property, 0)) + w->deleteLater(); +} + +QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &, const QModelIndex &index) const +{ + if (index.column() == 1 && m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + if (property && item && (item->flags() & Qt::ItemIsEnabled)) { + QWidget *editor = m_editorPrivate->createEditor(property, parent); + if (editor) { + editor->setAutoFillBackground(true); + editor->installEventFilter(const_cast(this)); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + m_propertyToEditor[property] = editor; + m_editorToProperty[editor] = property; + m_editedItem = item; + m_editedWidget = editor; + } + return editor; + } + } + return 0; +} + +void QtPropertyEditorDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(0, 0, 0, -1)); +} + +void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + hasValue = property->hasValue(); + } + QStyleOptionViewItemV3 opt = option; + if ((m_editorPrivate && index.column() == 0) || !hasValue) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property && property->isModified()) { + opt.font.setBold(true); + opt.fontMetrics = QFontMetrics(opt.font); + } + } + QColor c; + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + c = opt.palette.color(QPalette::Dark); + opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText)); + } else { + c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate)) + c = c.lighter(112); + } + if (c.isValid()) + painter->fillRect(option.rect, c); + opt.state &= ~QStyle::State_HasFocus; + QItemDelegate::paint(painter, opt, index); + + opt.palette.setCurrentColorGroup(QPalette::Active); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + if (!m_editorPrivate || (!m_editorPrivate->lastColumn(index.column()) && hasValue)) { + int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left(); + painter->drawLine(right, option.rect.y(), right, option.rect.bottom()); + } + painter->restore(); +} + +QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + return QItemDelegate::sizeHint(option, index) + QSize(3, 4); +} + +bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusOut) { + QFocusEvent *fe = static_cast(event); + if (fe->reason() == Qt::ActiveWindowFocusReason) + return false; + } + return QItemDelegate::eventFilter(object, event); +} + +// -------- QtTreePropertyBrowserPrivate implementation +QtTreePropertyBrowserPrivate::QtTreePropertyBrowserPrivate() : + m_treeWidget(0), + m_headerVisible(true), + m_resizeMode(QtTreePropertyBrowser::Stretch), + m_delegate(0), + m_markPropertiesWithoutValue(false), + m_browserChangedBlocked(false) +{ +} + +// Draw an icon indicating opened/closing branches +static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) +{ + QPixmap pix(14, 14); + pix.fill(Qt::transparent); + QStyleOption branchOption; + QRect r(QPoint(0, 0), pix.size()); + branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp + branchOption.palette = palette; + branchOption.state = QStyle::State_Children; + + QPainter p; + // Draw closed state + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + QIcon rc = pix; + rc.addPixmap(pix, QIcon::Selected, QIcon::Off); + // Draw opened state + branchOption.state |= QStyle::State_Open; + pix.fill(Qt::transparent); + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + + rc.addPixmap(pix, QIcon::Normal, QIcon::On); + rc.addPixmap(pix, QIcon::Selected, QIcon::On); + return rc; +} + +void QtTreePropertyBrowserPrivate::init(QWidget *parent) +{ + QHBoxLayout *layout = new QHBoxLayout(parent); + layout->setMargin(0); + m_treeWidget = new QtPropertyEditorView(parent); + m_treeWidget->setEditorPrivate(this); + m_treeWidget->setIconSize(QSize(18, 18)); + layout->addWidget(m_treeWidget); + + m_treeWidget->setColumnCount(2); + QStringList labels; + labels.append(QApplication::translate("QtTreePropertyBrowser", "Property", 0, QApplication::UnicodeUTF8)); + labels.append(QApplication::translate("QtTreePropertyBrowser", "Value", 0, QApplication::UnicodeUTF8)); + m_treeWidget->setHeaderLabels(labels); + m_treeWidget->setAlternatingRowColors(true); + m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed); + m_delegate = new QtPropertyEditorDelegate(parent); + m_delegate->setEditorPrivate(this); + m_treeWidget->setItemDelegate(m_delegate); + m_treeWidget->header()->setMovable(false); + m_treeWidget->header()->setResizeMode(QHeaderView::Stretch); + + m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style()); + + QObject::connect(m_treeWidget, SIGNAL(collapsed(const QModelIndex &)), q_ptr, SLOT(slotCollapsed(const QModelIndex &))); + QObject::connect(m_treeWidget, SIGNAL(expanded(const QModelIndex &)), q_ptr, SLOT(slotExpanded(const QModelIndex &))); + QObject::connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), q_ptr, SLOT(slotCurrentTreeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const +{ + if (QTreeWidgetItem *treeItem = m_treeWidget->currentItem()) + return m_itemToIndex.value(treeItem); + return 0; +} + +void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block) +{ + const bool blocked = block ? m_treeWidget->blockSignals(true) : false; + if (browserItem == 0) + m_treeWidget->setCurrentItem(0); + else + m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem)); + if (block) + m_treeWidget->blockSignals(blocked); +} + +QtProperty *QtTreePropertyBrowserPrivate::indexToProperty(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (idx) + return idx->property(); + return 0; +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::indexToBrowserItem(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + return m_itemToIndex.value(item); +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::indexToItem(const QModelIndex &index) const +{ + return m_treeWidget->indexToItem(index); +} + +bool QtTreePropertyBrowserPrivate::lastColumn(int column) const +{ + return m_treeWidget->header()->visualIndex(column) == m_treeWidget->columnCount() - 1; +} + +void QtTreePropertyBrowserPrivate::disableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + if (flags & Qt::ItemIsEnabled) { + flags &= ~Qt::ItemIsEnabled; + item->setFlags(flags); + m_delegate->closeEditor(m_itemToIndex[item]->property()); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + disableItem(child); + } + } +} + +void QtTreePropertyBrowserPrivate::enableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + flags |= Qt::ItemIsEnabled; + item->setFlags(flags); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + QtProperty *property = m_itemToIndex[child]->property(); + if (property->isEnabled()) { + enableItem(child); + } + } +} + +bool QtTreePropertyBrowserPrivate::hasValue(QTreeWidgetItem *item) const +{ + QtBrowserItem *browserItem = m_itemToIndex.value(item); + if (browserItem) + return browserItem->property()->hasValue(); + return false; +} + +void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex); + QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent()); + + QTreeWidgetItem *newItem = 0; + if (parentItem) { + newItem = new QTreeWidgetItem(parentItem, afterItem); + } else { + newItem = new QTreeWidgetItem(m_treeWidget, afterItem); + } + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); + m_treeWidget->setItemExpanded(newItem, true); + + updateItem(newItem); +} + +void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + if (m_treeWidget->currentItem() == item) { + m_treeWidget->setCurrentItem(0); + } + + delete item; + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + m_indexToBackgroundColor.remove(index); +} + +void QtTreePropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtTreePropertyBrowserPrivate::updateItem(QTreeWidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + QIcon expandIcon; + if (property->hasValue()) { + QString toolTip = property->toolTip(); + if (toolTip.isEmpty()) + toolTip = property->valueText(); + item->setToolTip(1, toolTip); + item->setIcon(1, property->valueIcon()); + item->setText(1, property->valueText()); + } else if (markPropertiesWithoutValue() && !m_treeWidget->rootIsDecorated()) { + expandIcon = m_expandIcon; + } + item->setIcon(0, expandIcon); + item->setFirstColumnSpanned(!property->hasValue()); + item->setToolTip(0, property->propertyName()); + item->setStatusTip(0, property->statusTip()); + item->setWhatsThis(0, property->whatsThis()); + item->setText(0, property->propertyName()); + bool wasEnabled = item->flags() & Qt::ItemIsEnabled; + bool isEnabled = wasEnabled; + if (property->isEnabled()) { + QTreeWidgetItem *parent = item->parent(); + if (!parent || (parent->flags() & Qt::ItemIsEnabled)) + isEnabled = true; + else + isEnabled = false; + } else { + isEnabled = false; + } + if (wasEnabled != isEnabled) { + if (isEnabled) + enableItem(item); + else + disableItem(item); + } + m_treeWidget->viewport()->update(); +} + +QColor QtTreePropertyBrowserPrivate::calculatedBackgroundColor(QtBrowserItem *item) const +{ + QtBrowserItem *i = item; + const QMap::const_iterator itEnd = m_indexToBackgroundColor.constEnd(); + while (i) { + QMap::const_iterator it = m_indexToBackgroundColor.constFind(i); + if (it != itEnd) + return it.value(); + i = i->parent(); + } + return QColor(); +} + +void QtTreePropertyBrowserPrivate::slotCollapsed(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->collapsed(idx); +} + +void QtTreePropertyBrowserPrivate::slotExpanded(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->expanded(idx); +} + +void QtTreePropertyBrowserPrivate::slotCurrentBrowserItemChanged(QtBrowserItem *item) +{ + if (!m_browserChangedBlocked && item != currentItem()) + setCurrentItem(item, true); +} + +void QtTreePropertyBrowserPrivate::slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *) +{ + QtBrowserItem *browserItem = newItem ? m_itemToIndex.value(newItem) : 0; + m_browserChangedBlocked = true; + q_ptr->setCurrentItem(browserItem); + m_browserChangedBlocked = false; +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::editedItem() const +{ + return m_delegate->editedItem(); +} + +void QtTreePropertyBrowserPrivate::editItem(QtBrowserItem *browserItem) +{ + if (QTreeWidgetItem *treeItem = m_indexToItem.value(browserItem, 0)) { + m_treeWidget->setCurrentItem (treeItem, 1); + m_treeWidget->editItem(treeItem, 1); + } +} + +/*! + \class QtTreePropertyBrowser + + \brief The QtTreePropertyBrowser class provides QTreeWidget based + property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtTreePropertyBrowser provides a tree based view for all nested + properties, i.e. properties that have subproperties can be in an + expanded (subproperties are visible) or collapsed (subproperties + are hidden) state. For example: + + \image qttreepropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtTreePropertyBrowser class. + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtGroupBoxPropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtTreePropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtTreePropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtTreePropertyBrowser::QtTreePropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtTreePropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); + connect(this, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentBrowserItemChanged(QtBrowserItem*))); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtTreePropertyBrowser::~QtTreePropertyBrowser() +{ + delete d_ptr; +} + +/*! + \property QtTreePropertyBrowser::indentation + \brief indentation of the items in the tree view. +*/ +int QtTreePropertyBrowser::indentation() const +{ + return d_ptr->m_treeWidget->indentation(); +} + +void QtTreePropertyBrowser::setIndentation(int i) +{ + d_ptr->m_treeWidget->setIndentation(i); +} + +/*! + \property QtTreePropertyBrowser::rootIsDecorated + \brief whether to show controls for expanding and collapsing root items. +*/ +bool QtTreePropertyBrowser::rootIsDecorated() const +{ + return d_ptr->m_treeWidget->rootIsDecorated(); +} + +void QtTreePropertyBrowser::setRootIsDecorated(bool show) +{ + d_ptr->m_treeWidget->setRootIsDecorated(show); + QMapIterator it(d_ptr->m_itemToIndex); + while (it.hasNext()) { + QtProperty *property = it.next().value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } +} + +/*! + \property QtTreePropertyBrowser::alternatingRowColors + \brief whether to draw the background using alternating colors. + By default this property is set to true. +*/ +bool QtTreePropertyBrowser::alternatingRowColors() const +{ + return d_ptr->m_treeWidget->alternatingRowColors(); +} + +void QtTreePropertyBrowser::setAlternatingRowColors(bool enable) +{ + d_ptr->m_treeWidget->setAlternatingRowColors(enable); + QMapIterator it(d_ptr->m_itemToIndex); +} + +/*! + \property QtTreePropertyBrowser::headerVisible + \brief whether to show the header. +*/ +bool QtTreePropertyBrowser::isHeaderVisible() const +{ + return d_ptr->m_headerVisible; +} + +void QtTreePropertyBrowser::setHeaderVisible(bool visible) +{ + if (d_ptr->m_headerVisible == visible) + return; + + d_ptr->m_headerVisible = visible; + d_ptr->m_treeWidget->header()->setVisible(visible); +} + +/*! + \enum QtTreePropertyBrowser::ResizeMode + + The resize mode specifies the behavior of the header sections. + + \value Interactive The user can resize the sections. + The sections can also be resized programmatically using setSplitterPosition(). + + \value Fixed The user cannot resize the section. + The section can only be resized programmatically using setSplitterPosition(). + + \value Stretch QHeaderView will automatically resize the section to fill the available space. + The size cannot be changed by the user or programmatically. + + \value ResizeToContents QHeaderView will automatically resize the section to its optimal + size based on the contents of the entire column. + The size cannot be changed by the user or programmatically. + + \sa setResizeMode() +*/ + +/*! + \property QtTreePropertyBrowser::resizeMode + \brief the resize mode of setions in the header. +*/ + +QtTreePropertyBrowser::ResizeMode QtTreePropertyBrowser::resizeMode() const +{ + return d_ptr->m_resizeMode; +} + +void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode) +{ + if (d_ptr->m_resizeMode == mode) + return; + + d_ptr->m_resizeMode = mode; + QHeaderView::ResizeMode m = QHeaderView::Stretch; + switch (mode) { + case QtTreePropertyBrowser::Interactive: m = QHeaderView::Interactive; break; + case QtTreePropertyBrowser::Fixed: m = QHeaderView::Fixed; break; + case QtTreePropertyBrowser::ResizeToContents: m = QHeaderView::ResizeToContents; break; + case QtTreePropertyBrowser::Stretch: + default: m = QHeaderView::Stretch; break; + } + d_ptr->m_treeWidget->header()->setResizeMode(m); +} + +/*! + \property QtTreePropertyBrowser::splitterPosition + \brief the position of the splitter between the colunms. +*/ + +int QtTreePropertyBrowser::splitterPosition() const +{ + return d_ptr->m_treeWidget->header()->sectionSize(0); +} + +void QtTreePropertyBrowser::setSplitterPosition(int position) +{ + d_ptr->m_treeWidget->header()->resizeSection(0, position); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtTreePropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + treeItem->setExpanded(expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtTreePropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + return treeItem->isExpanded(); + return false; +} + +/*! + Returns true if the \a item is visible; otherwise returns false. + + \sa setItemVisible() + \since 4.5 +*/ + +bool QtTreePropertyBrowser::isItemVisible(QtBrowserItem *item) const +{ + if (const QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + return !treeItem->isHidden(); + return false; +} + +/*! + Sets the \a item to be visible, depending on the value of \a visible. + + \sa isItemVisible() + \since 4.5 +*/ + +void QtTreePropertyBrowser::setItemVisible(QtBrowserItem *item, bool visible) +{ + if (QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + treeItem->setHidden(!visible); +} + +/*! + Sets the \a item's background color to \a color. Note that while item's background + is rendered every second row is being drawn with alternate color (which is a bit lighter than items \a color) + + \sa backgroundColor(), calculatedBackgroundColor() +*/ + +void QtTreePropertyBrowser::setBackgroundColor(QtBrowserItem *item, const QColor &color) +{ + if (!d_ptr->m_indexToItem.contains(item)) + return; + if (color.isValid()) + d_ptr->m_indexToBackgroundColor[item] = color; + else + d_ptr->m_indexToBackgroundColor.remove(item); + d_ptr->m_treeWidget->viewport()->update(); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns invalid color. + + \sa calculatedBackgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::backgroundColor(QtBrowserItem *item) const +{ + return d_ptr->m_indexToBackgroundColor.value(item); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns parent \a item's + color (if there is no color set for parent it returns grandparent's color and so on). In case + the color is not set for \a item and it's top level item it returns invalid color. + + \sa backgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::calculatedBackgroundColor(QtBrowserItem *item) const +{ + return d_ptr->calculatedBackgroundColor(item); +} + +/*! + \property QtTreePropertyBrowser::propertiesWithoutValueMarked + \brief whether to enable or disable marking properties without value. + + When marking is enabled the item's background is rendered in dark color and item's + foreground is rendered with light color. + + \sa propertiesWithoutValueMarked() +*/ +void QtTreePropertyBrowser::setPropertiesWithoutValueMarked(bool mark) +{ + if (d_ptr->m_markPropertiesWithoutValue == mark) + return; + + d_ptr->m_markPropertiesWithoutValue = mark; + QMapIterator it(d_ptr->m_itemToIndex); + while (it.hasNext()) { + QtProperty *property = it.next().value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } + d_ptr->m_treeWidget->viewport()->update(); +} + +bool QtTreePropertyBrowser::propertiesWithoutValueMarked() const +{ + return d_ptr->m_markPropertiesWithoutValue; +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the current item to \a item and opens the relevant editor for it. +*/ +void QtTreePropertyBrowser::editItem(QtBrowserItem *item) +{ + d_ptr->editItem(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qttreepropertybrowser.cpp" +//#include "qttreepropertybrowser.moc" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qttreepropertybrowser.h 2012-02-21 23:07:04.000000000 +0000 @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTTREEPROPERTYBROWSER_H +#define QTTREEPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" +#include +#include +#include +#include +#include + + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QTreeWidgetItem; +class QtTreePropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTreePropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT + Q_ENUMS(ResizeMode) + Q_PROPERTY(int indentation READ indentation WRITE setIndentation) + Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated) + Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) + Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible) + Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode) + Q_PROPERTY(int splitterPosition READ splitterPosition WRITE setSplitterPosition) + Q_PROPERTY(bool propertiesWithoutValueMarked READ propertiesWithoutValueMarked WRITE setPropertiesWithoutValueMarked) +public: + + enum ResizeMode + { + Interactive, + Stretch, + Fixed, + ResizeToContents + }; + + QtTreePropertyBrowser(QWidget *parent = 0); + ~QtTreePropertyBrowser(); + + int indentation() const; + void setIndentation(int i); + + bool rootIsDecorated() const; + void setRootIsDecorated(bool show); + + bool alternatingRowColors() const; + void setAlternatingRowColors(bool enable); + + bool isHeaderVisible() const; + void setHeaderVisible(bool visible); + + ResizeMode resizeMode() const; + void setResizeMode(ResizeMode mode); + + int splitterPosition() const; + void setSplitterPosition(int position); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + + bool isItemVisible(QtBrowserItem *item) const; + void setItemVisible(QtBrowserItem *item, bool visible); + + void setBackgroundColor(QtBrowserItem *item, const QColor &color); + QColor backgroundColor(QtBrowserItem *item) const; + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + void setPropertiesWithoutValueMarked(bool mark); + bool propertiesWithoutValueMarked() const; + + void editItem(QtBrowserItem *item); + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtTreePropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTreePropertyBrowser) + Q_DISABLE_COPY(QtTreePropertyBrowser) + + Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotExpanded(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentBrowserItemChanged(QtBrowserItem *)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)) + +}; +class QtPropertyEditorView; + +class QtTreePropertyBrowserPrivate +{ + QtTreePropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtTreePropertyBrowser) + +public: + QtTreePropertyBrowserPrivate(); + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + QtProperty *indexToProperty(const QModelIndex &index) const; + QTreeWidgetItem *indexToItem(const QModelIndex &index) const; + QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const; + bool lastColumn(int column) const; + void disableItem(QTreeWidgetItem *item) const; + void enableItem(QTreeWidgetItem *item) const; + bool hasValue(QTreeWidgetItem *item) const; + + void slotCollapsed(const QModelIndex &index); + void slotExpanded(const QModelIndex &index); + + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + QtPropertyEditorView *treeWidget() const { return m_treeWidget; } + bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; } + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *browserItem, bool block); + void editItem(QtBrowserItem *browserItem); + + void slotCurrentBrowserItemChanged(QtBrowserItem *item); + void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *); + + QTreeWidgetItem *editedItem() const; + +private: + void updateItem(QTreeWidgetItem *item); + + QMap m_indexToItem; + QMap m_itemToIndex; + + QMap m_indexToBackgroundColor; + + QtPropertyEditorView *m_treeWidget; + + bool m_headerVisible; + QtTreePropertyBrowser::ResizeMode m_resizeMode; + class QtPropertyEditorDelegate *m_delegate; + bool m_markPropertiesWithoutValue; + bool m_browserChangedBlocked; + QIcon m_expandIcon; +}; + +class QtPropertyEditorView : public QTreeWidget +{ + Q_OBJECT +public: + QtPropertyEditorView(QWidget *parent = 0); + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QTreeWidgetItem *indexToItem(const QModelIndex &index) const + { return itemFromIndex(index); } + +protected: + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + QtTreePropertyBrowserPrivate *m_editorPrivate; +}; + +class QtPropertyEditorDelegate : public QItemDelegate +{ + Q_OBJECT +public: + QtPropertyEditorDelegate(QObject *parent = 0) + : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0) + {} + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setModelData(QWidget *, QAbstractItemModel *, + const QModelIndex &) const {} + + void setEditorData(QWidget *, const QModelIndex &) const {} + + bool eventFilter(QObject *object, QEvent *event); + void closeEditor(QtProperty *property); + + QTreeWidgetItem *editedItem() const { return m_editedItem; } + +private slots: + void slotEditorDestroyed(QObject *object); + +private: + int indentation(const QModelIndex &index) const; + + typedef QMap EditorToPropertyMap; + mutable EditorToPropertyMap m_editorToProperty; + + typedef QMap PropertyToEditorMap; + mutable PropertyToEditorMap m_propertyToEditor; + QtTreePropertyBrowserPrivate *m_editorPrivate; + mutable QTreeWidgetItem *m_editedItem; + mutable QWidget *m_editedWidget; +}; + + + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtvariantproperty.cpp diffimg-2.0.0/3rdparty/qtpropertybrowser/qtvariantproperty.cpp --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtvariantproperty.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtvariantproperty.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,2284 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "qtvariantproperty.h" +#include "qtpropertymanager.h" +#include "qteditorfactory.h" +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtEnumPropertyType +{ +}; + + +class QtFlagPropertyType +{ +}; + + +class QtGroupPropertyType +{ +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +Q_DECLARE_METATYPE(QtEnumPropertyType) +Q_DECLARE_METATYPE(QtFlagPropertyType) +Q_DECLARE_METATYPE(QtGroupPropertyType) + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +/*! + Returns the type id for an enum property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Int for the enum property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::enumTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a flag property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Int for the flag property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::flagTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a group property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Invalid for the group + property type, since it doesn't provide any value). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::groupTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a icon map attribute. + + Note that the property's attribute type can be retrieved using the + attributeType() function. + + \sa attributeType(), QtEnumPropertyManager::enumIcons() +*/ +int QtVariantPropertyManager::iconMapTypeId() +{ + return qMetaTypeId(); +} + +typedef QMap PropertyMap; +Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty) + +static QtProperty *wrappedProperty(QtProperty *property) +{ + return propertyToWrappedProperty()->value(property, 0); +} + +class QtVariantPropertyPrivate +{ + QtVariantProperty *q_ptr; +public: + QtVariantPropertyPrivate(QtVariantPropertyManager *m) : manager(m) {} + + QtVariantPropertyManager *manager; +}; + +/*! + \class QtVariantProperty + + \brief The QtVariantProperty class is a convenience class handling + QVariant based properties. + + QtVariantProperty provides additional API: A property's type, + value type, attribute values and current value can easily be + retrieved using the propertyType(), valueType(), attributeValue() + and value() functions respectively. In addition, the attribute + values and the current value can be set using the corresponding + setValue() and setAttribute() functions. + + For example, instead of writing: + + \code + QtVariantPropertyManager *variantPropertyManager; + QtProperty *property; + + variantPropertyManager->setValue(property, 10); + \endcode + + you can write: + + \code + QtVariantPropertyManager *variantPropertyManager; + QtVariantProperty *property; + + property->setValue(10); + \endcode + + QtVariantProperty instances can only be created by the + QtVariantPropertyManager class. + + \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory +*/ + +/*! + Creates a variant property using the given \a manager. + + Do not use this constructor to create variant property instances; + use the QtVariantPropertyManager::addProperty() function + instead. This constructor is used internally by the + QtVariantPropertyManager::createProperty() function. + + \sa QtVariantPropertyManager +*/ +QtVariantProperty::QtVariantProperty(QtVariantPropertyManager *manager) + : QtProperty(manager), d_ptr(new QtVariantPropertyPrivate(manager)) +{ + +} + +/*! + Destroys this property. + + \sa QtProperty::~QtProperty() +*/ +QtVariantProperty::~QtVariantProperty() +{ + delete d_ptr; +} + +/*! + Returns the property's current value. + + \sa valueType(), setValue() +*/ +QVariant QtVariantProperty::value() const +{ + return d_ptr->manager->value(this); +} + +/*! + Returns this property's value for the specified \a attribute. + + QtVariantPropertyManager provides a couple of related functions: + \l{QtVariantPropertyManager::attributes()}{attributes()} and + \l{QtVariantPropertyManager::attributeType()}{attributeType()}. + + \sa setAttribute() +*/ +QVariant QtVariantProperty::attributeValue(const QString &attribute) const +{ + return d_ptr->manager->attributeValue(this, attribute); +} + +/*! + Returns the type of this property's value. + + \sa propertyType() +*/ +int QtVariantProperty::valueType() const +{ + return d_ptr->manager->valueType(this); +} + +/*! + Returns this property's type. + + QtVariantPropertyManager provides several related functions: + \l{QtVariantPropertyManager::enumTypeId()}{enumTypeId()}, + \l{QtVariantPropertyManager::flagTypeId()}{flagTypeId()} and + \l{QtVariantPropertyManager::groupTypeId()}{groupTypeId()}. + + \sa valueType() +*/ +int QtVariantProperty::propertyType() const +{ + return d_ptr->manager->propertyType(this); +} + +/*! + Sets the value of this property to \a value. + + The specified \a value must be of the type returned by + valueType(), or of a type that can be converted to valueType() + using the QVariant::canConvert() function; otherwise this function + does nothing. + + \sa value() +*/ +void QtVariantProperty::setValue(const QVariant &value) +{ + d_ptr->manager->setValue(this, value); +} + +/*! + Sets the \a attribute of property to \a value. + + QtVariantPropertyManager provides the related + \l{QtVariantPropertyManager::setAttribute()}{setAttribute()} + function. + + \sa attributeValue() +*/ +void QtVariantProperty::setAttribute(const QString &attribute, const QVariant &value) +{ + d_ptr->manager->setAttribute(this, attribute, value); +} + +/* +class QtVariantPropertyManagerPrivate +{ + QtVariantPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtVariantPropertyManager) +public: + QtVariantPropertyManagerPrivate(); + + bool m_creatingProperty; + bool m_creatingSubProperties; + bool m_destroyingSubProperties; + int m_propertyType; + + void slotValueChanged(QtProperty *property, int val); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotValueChanged(QtProperty *property, double val); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotValueChanged(QtProperty *property, bool val); + void slotValueChanged(QtProperty *property, const QString &val); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotValueChanged(QtProperty *property, const QDate &val); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotValueChanged(QtProperty *property, const QTime &val); + void slotValueChanged(QtProperty *property, const QDateTime &val); + void slotValueChanged(QtProperty *property, const QKeySequence &val); + void slotValueChanged(QtProperty *property, const QChar &val); + void slotValueChanged(QtProperty *property, const QLocale &val); + void slotValueChanged(QtProperty *property, const QPoint &val); + void slotValueChanged(QtProperty *property, const QPointF &val); + void slotValueChanged(QtProperty *property, const QSize &val); + void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max); + void slotValueChanged(QtProperty *property, const QSizeF &val); + void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max); + void slotValueChanged(QtProperty *property, const QRect &val); + void slotConstraintChanged(QtProperty *property, const QRect &val); + void slotValueChanged(QtProperty *property, const QRectF &val); + void slotConstraintChanged(QtProperty *property, const QRectF &val); + void slotValueChanged(QtProperty *property, const QColor &val); + void slotEnumChanged(QtProperty *property, int val); + void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames); + void slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons); + void slotValueChanged(QtProperty *property, const QSizePolicy &val); + void slotValueChanged(QtProperty *property, const QFont &val); + void slotValueChanged(QtProperty *property, const QCursor &val); + void slotFlagChanged(QtProperty *property, int val); + void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames); + void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after); + void slotPropertyRemoved(QtProperty *property, QtProperty *parent); + + void valueChanged(QtProperty *property, const QVariant &val); + + int internalPropertyToType(QtProperty *property) const; + QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after, + QtProperty *internal); + void removeSubProperty(QtVariantProperty *property); + + QMap m_typeToPropertyManager; + QMap > m_typeToAttributeToAttributeType; + + QMap > m_propertyToType; + + QMap m_typeToValueType; + + + QMap m_internalToProperty; + + const QString m_constraintAttribute; + const QString m_singleStepAttribute; + const QString m_decimalsAttribute; + const QString m_enumIconsAttribute; + const QString m_enumNamesAttribute; + const QString m_flagNamesAttribute; + const QString m_maximumAttribute; + const QString m_minimumAttribute; + const QString m_regExpAttribute; +}; +*/ + +QtVariantPropertyManagerPrivate::QtVariantPropertyManagerPrivate() : + m_constraintAttribute(QLatin1String("constraint")), + m_singleStepAttribute(QLatin1String("singleStep")), + m_decimalsAttribute(QLatin1String("decimals")), + m_enumIconsAttribute(QLatin1String("enumIcons")), + m_enumNamesAttribute(QLatin1String("enumNames")), + m_flagNamesAttribute(QLatin1String("flagNames")), + m_maximumAttribute(QLatin1String("maximum")), + m_minimumAttribute(QLatin1String("minimum")), + m_regExpAttribute(QLatin1String("regExp")) +{ +} + +int QtVariantPropertyManagerPrivate::internalPropertyToType(QtProperty *property) const +{ + int type = 0; + QtAbstractPropertyManager *internPropertyManager = property->propertyManager(); + if (qobject_cast(internPropertyManager)) + type = QVariant::Int; + else if (qobject_cast(internPropertyManager)) + type = QtVariantPropertyManager::enumTypeId(); + else if (qobject_cast(internPropertyManager)) + type = QVariant::Bool; + else if (qobject_cast(internPropertyManager)) + type = QVariant::Double; + return type; +} + +QtVariantProperty *QtVariantPropertyManagerPrivate::createSubProperty(QtVariantProperty *parent, + QtVariantProperty *after, QtProperty *internal) +{ + int type = internalPropertyToType(internal); + if (!type) + return 0; + + bool wasCreatingSubProperties = m_creatingSubProperties; + m_creatingSubProperties = true; + + QtVariantProperty *varChild = q_ptr->addProperty(type, internal->propertyName()); + + m_creatingSubProperties = wasCreatingSubProperties; + + varChild->setPropertyName(internal->propertyName()); + varChild->setToolTip(internal->toolTip()); + varChild->setStatusTip(internal->statusTip()); + varChild->setWhatsThis(internal->whatsThis()); + + parent->insertSubProperty(varChild, after); + + m_internalToProperty[internal] = varChild; + propertyToWrappedProperty()->insert(varChild, internal); + return varChild; +} + +void QtVariantPropertyManagerPrivate::removeSubProperty(QtVariantProperty *property) +{ + QtProperty *internChild = wrappedProperty(property); + bool wasDestroyingSubProperties = m_destroyingSubProperties; + m_destroyingSubProperties = true; + delete property; + m_destroyingSubProperties = wasDestroyingSubProperties; + m_internalToProperty.remove(internChild); + propertyToWrappedProperty()->remove(property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after) +{ + if (m_creatingProperty) + return; + + QtVariantProperty *varParent = m_internalToProperty.value(parent, 0); + if (!varParent) + return; + + QtVariantProperty *varAfter = 0; + if (after) { + varAfter = m_internalToProperty.value(after, 0); + if (!varAfter) + return; + } + + createSubProperty(varParent, varAfter, property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyRemoved(QtProperty *property, QtProperty *parent) +{ + Q_UNUSED(parent) + + QtVariantProperty *varProperty = m_internalToProperty.value(property, 0); + if (!varProperty) + return; + + removeSubProperty(varProperty); +} + +void QtVariantPropertyManagerPrivate::valueChanged(QtProperty *property, const QVariant &val) +{ + QtVariantProperty *varProp = m_internalToProperty.value(property, 0); + if (!varProp) + return; + emit q_ptr->valueChanged(varProp, val); + emit q_ptr->propertyChanged(varProp); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, int val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, double val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, double min, double max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, double step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotDecimalsChanged(QtProperty *property, int prec) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_decimalsAttribute, QVariant(prec)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, bool val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QString &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegExp ®Exp) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDate &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QTime &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDateTime &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val) +{ + QVariant v; + qVariantSetValue(v, val); + valueChanged(property, v); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QChar &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QLocale &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPoint &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPointF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSize &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizeF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRect &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRect &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRectF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRectF &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QColor &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_enumNamesAttribute, QVariant(enumNames)); +} + +void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + QVariant v; + qVariantSetValue(v, enumIcons); + emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizePolicy &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QFont &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QCursor &val) +{ +#ifndef QT_NO_CURSOR + valueChanged(property, QVariant(val)); +#endif +} + +void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_flagNamesAttribute, QVariant(flagNames)); +} + +/*! + \class QtVariantPropertyManager + + \brief The QtVariantPropertyManager class provides and manages QVariant based properties. + + QtVariantPropertyManager provides the addProperty() function which + creates QtVariantProperty objects. The QtVariantProperty class is + a convenience class handling QVariant based properties inheriting + QtProperty. A QtProperty object created by a + QtVariantPropertyManager instance can be converted into a + QtVariantProperty object using the variantProperty() function. + + The property's value can be retrieved using the value(), and set + using the setValue() slot. In addition the property's type, and + the type of its value, can be retrieved using the propertyType() + and valueType() functions respectively. + + A property's type is a QVariant::Type enumerator value, and + usually a property's type is the same as its value type. But for + some properties the types differ, for example for enums, flags and + group types in which case QtVariantPropertyManager provides the + enumTypeId(), flagTypeId() and groupTypeId() functions, + respectively, to identify their property type (the value types are + QVariant::Int for the enum and flag types, and QVariant::Invalid + for the group type). + + Use the isPropertyTypeSupported() function to check if a particular + property type is supported. The currently supported property types + are: + + \table + \header + \o Property Type + \o Property Type Id + \row + \o int + \o QVariant::Int + \row + \o double + \o QVariant::Double + \row + \o bool + \o QVariant::Bool + \row + \o QString + \o QVariant::String + \row + \o QDate + \o QVariant::Date + \row + \o QTime + \o QVariant::Time + \row + \o QDateTime + \o QVariant::DateTime + \row + \o QKeySequence + \o QVariant::KeySequence + \row + \o QChar + \o QVariant::Char + \row + \o QLocale + \o QVariant::Locale + \row + \o QPoint + \o QVariant::Point + \row + \o QPointF + \o QVariant::PointF + \row + \o QSize + \o QVariant::Size + \row + \o QSizeF + \o QVariant::SizeF + \row + \o QRect + \o QVariant::Rect + \row + \o QRectF + \o QVariant::RectF + \row + \o QColor + \o QVariant::Color + \row + \o QSizePolicy + \o QVariant::SizePolicy + \row + \o QFont + \o QVariant::Font + \row + \o QCursor + \o QVariant::Cursor + \row + \o enum + \o enumTypeId() + \row + \o flag + \o flagTypeId() + \row + \o group + \o groupTypeId() + \endtable + + Each property type can provide additional attributes, + e.g. QVariant::Int and QVariant::Double provides minimum and + maximum values. The currently supported attributes are: + + \table + \header + \o Property Type + \o Attribute Name + \o Attribute Type + \row + \o \c int + \o minimum + \o QVariant::Int + \row + \o + \o maximum + \o QVariant::Int + \row + \o + \o singleStep + \o QVariant::Int + \row + \o \c double + \o minimum + \o QVariant::Double + \row + \o + \o maximum + \o QVariant::Double + \row + \o + \o singleStep + \o QVariant::Double + \row + \o + \o decimals + \o QVariant::Int + \row + \o QString + \o regExp + \o QVariant::RegExp + \row + \o QDate + \o minimum + \o QVariant::Date + \row + \o + \o maximum + \o QVariant::Date + \row + \o QPointF + \o decimals + \o QVariant::Int + \row + \o QSize + \o minimum + \o QVariant::Size + \row + \o + \o maximum + \o QVariant::Size + \row + \o QSizeF + \o minimum + \o QVariant::SizeF + \row + \o + \o maximum + \o QVariant::SizeF + \row + \o + \o decimals + \o QVariant::Int + \row + \o QRect + \o constraint + \o QVariant::Rect + \row + \o QRectF + \o constraint + \o QVariant::RectF + \row + \o + \o decimals + \o QVariant::Int + \row + \o \c enum + \o enumNames + \o QVariant::StringList + \row + \o + \o enumIcons + \o iconMapTypeId() + \row + \o \c flag + \o flagNames + \o QVariant::StringList + \endtable + + The attributes for a given property type can be retrieved using + the attributes() function. Each attribute has a value type which + can be retrieved using the attributeType() function, and a value + accessible through the attributeValue() function. In addition, the + value can be set using the setAttribute() slot. + + QtVariantManager also provides the valueChanged() signal which is + emitted whenever a property created by this manager change, and + the attributeChanged() signal which is emitted whenever an + attribute of such a property changes. + + \sa QtVariantProperty, QtVariantEditorFactory +*/ + +/*! + \fn void QtVariantPropertyManager::valueChanged(QtProperty *property, const QVariant &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtVariantPropertyManager::attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &value) + + This signal is emitted whenever an attribute of a property created + by this manager changes its value, passing a pointer to the \a + property, the \a attribute and the new \a value as parameters. + + \sa setAttribute() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtVariantPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_creatingProperty = false; + d_ptr->m_creatingSubProperties = false; + d_ptr->m_destroyingSubProperties = false; + d_ptr->m_propertyType = 0; + + // IntPropertyManager + QtIntPropertyManager *intPropertyManager = new QtIntPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Int] = intPropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_minimumAttribute] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_maximumAttribute] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_singleStepAttribute] = QVariant::Int; + d_ptr->m_typeToValueType[QVariant::Int] = QVariant::Int; + connect(intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(intPropertyManager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(intPropertyManager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); + // DoublePropertyManager + QtDoublePropertyManager *doublePropertyManager = new QtDoublePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Double] = doublePropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_minimumAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_maximumAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_singleStepAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_decimalsAttribute] = + QVariant::Int; + d_ptr->m_typeToValueType[QVariant::Double] = QVariant::Double; + connect(doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(doublePropertyManager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(doublePropertyManager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + connect(doublePropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + // BoolPropertyManager + QtBoolPropertyManager *boolPropertyManager = new QtBoolPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Bool] = boolPropertyManager; + d_ptr->m_typeToValueType[QVariant::Bool] = QVariant::Bool; + connect(boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + // StringPropertyManager + QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager; + d_ptr->m_typeToValueType[QVariant::String] = QVariant::String; + d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] = + QVariant::RegExp; + connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotValueChanged(QtProperty *, const QString &))); + connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); + // DatePropertyManager + QtDatePropertyManager *datePropertyManager = new QtDatePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Date] = datePropertyManager; + d_ptr->m_typeToValueType[QVariant::Date] = QVariant::Date; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_minimumAttribute] = + QVariant::Date; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_maximumAttribute] = + QVariant::Date; + connect(datePropertyManager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotValueChanged(QtProperty *, const QDate &))); + connect(datePropertyManager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); + // TimePropertyManager + QtTimePropertyManager *timePropertyManager = new QtTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Time] = timePropertyManager; + d_ptr->m_typeToValueType[QVariant::Time] = QVariant::Time; + connect(timePropertyManager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotValueChanged(QtProperty *, const QTime &))); + // DateTimePropertyManager + QtDateTimePropertyManager *dateTimePropertyManager = new QtDateTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::DateTime] = dateTimePropertyManager; + d_ptr->m_typeToValueType[QVariant::DateTime] = QVariant::DateTime; + connect(dateTimePropertyManager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotValueChanged(QtProperty *, const QDateTime &))); + // KeySequencePropertyManager + QtKeySequencePropertyManager *keySequencePropertyManager = new QtKeySequencePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::KeySequence] = keySequencePropertyManager; + d_ptr->m_typeToValueType[QVariant::KeySequence] = QVariant::KeySequence; + connect(keySequencePropertyManager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotValueChanged(QtProperty *, const QKeySequence &))); + // CharPropertyManager + QtCharPropertyManager *charPropertyManager = new QtCharPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Char] = charPropertyManager; + d_ptr->m_typeToValueType[QVariant::Char] = QVariant::Char; + connect(charPropertyManager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotValueChanged(QtProperty *, const QChar &))); + // LocalePropertyManager + QtLocalePropertyManager *localePropertyManager = new QtLocalePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Locale] = localePropertyManager; + d_ptr->m_typeToValueType[QVariant::Locale] = QVariant::Locale; + connect(localePropertyManager, SIGNAL(valueChanged(QtProperty *, const QLocale &)), + this, SLOT(slotValueChanged(QtProperty *, const QLocale &))); + connect(localePropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(localePropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(localePropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // PointPropertyManager + QtPointPropertyManager *pointPropertyManager = new QtPointPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Point] = pointPropertyManager; + d_ptr->m_typeToValueType[QVariant::Point] = QVariant::Point; + connect(pointPropertyManager, SIGNAL(valueChanged(QtProperty *, const QPoint &)), + this, SLOT(slotValueChanged(QtProperty *, const QPoint &))); + connect(pointPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(pointPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(pointPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // PointFPropertyManager + QtPointFPropertyManager *pointFPropertyManager = new QtPointFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::PointF] = pointFPropertyManager; + d_ptr->m_typeToValueType[QVariant::PointF] = QVariant::PointF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::PointF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(pointFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QPointF &)), + this, SLOT(slotValueChanged(QtProperty *, const QPointF &))); + connect(pointFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(pointFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(pointFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(pointFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // SizePropertyManager + QtSizePropertyManager *sizePropertyManager = new QtSizePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Size] = sizePropertyManager; + d_ptr->m_typeToValueType[QVariant::Size] = QVariant::Size; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_minimumAttribute] = + QVariant::Size; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_maximumAttribute] = + QVariant::Size; + connect(sizePropertyManager, SIGNAL(valueChanged(QtProperty *, const QSize &)), + this, SLOT(slotValueChanged(QtProperty *, const QSize &))); + connect(sizePropertyManager, SIGNAL(rangeChanged(QtProperty *, const QSize &, const QSize &)), + this, SLOT(slotRangeChanged(QtProperty *, const QSize &, const QSize &))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(sizePropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizePropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // SizeFPropertyManager + QtSizeFPropertyManager *sizeFPropertyManager = new QtSizeFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::SizeF] = sizeFPropertyManager; + d_ptr->m_typeToValueType[QVariant::SizeF] = QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_minimumAttribute] = + QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_maximumAttribute] = + QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(sizeFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QSizeF &)), + this, SLOT(slotValueChanged(QtProperty *, const QSizeF &))); + connect(sizeFPropertyManager, SIGNAL(rangeChanged(QtProperty *, const QSizeF &, const QSizeF &)), + this, SLOT(slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &))); + connect(sizeFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(sizeFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizeFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // RectPropertyManager + QtRectPropertyManager *rectPropertyManager = new QtRectPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Rect] = rectPropertyManager; + d_ptr->m_typeToValueType[QVariant::Rect] = QVariant::Rect; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Rect][d_ptr->m_constraintAttribute] = + QVariant::Rect; + connect(rectPropertyManager, SIGNAL(valueChanged(QtProperty *, const QRect &)), + this, SLOT(slotValueChanged(QtProperty *, const QRect &))); + connect(rectPropertyManager, SIGNAL(constraintChanged(QtProperty *, const QRect &)), + this, SLOT(slotConstraintChanged(QtProperty *, const QRect &))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(rectPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(rectPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // RectFPropertyManager + QtRectFPropertyManager *rectFPropertyManager = new QtRectFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::RectF] = rectFPropertyManager; + d_ptr->m_typeToValueType[QVariant::RectF] = QVariant::RectF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_constraintAttribute] = + QVariant::RectF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(rectFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QRectF &)), + this, SLOT(slotValueChanged(QtProperty *, const QRectF &))); + connect(rectFPropertyManager, SIGNAL(constraintChanged(QtProperty *, const QRectF &)), + this, SLOT(slotConstraintChanged(QtProperty *, const QRectF &))); + connect(rectFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(rectFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(rectFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // ColorPropertyManager + QtColorPropertyManager *colorPropertyManager = new QtColorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Color] = colorPropertyManager; + d_ptr->m_typeToValueType[QVariant::Color] = QVariant::Color; + connect(colorPropertyManager, SIGNAL(valueChanged(QtProperty *, const QColor &)), + this, SLOT(slotValueChanged(QtProperty *, const QColor &))); + connect(colorPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(colorPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(colorPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // EnumPropertyManager + int enumId = enumTypeId(); + QtEnumPropertyManager *enumPropertyManager = new QtEnumPropertyManager(this); + d_ptr->m_typeToPropertyManager[enumId] = enumPropertyManager; + d_ptr->m_typeToValueType[enumId] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumNamesAttribute] = + QVariant::StringList; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumIconsAttribute] = + iconMapTypeId(); + connect(enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(enumPropertyManager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(enumPropertyManager, SIGNAL(enumIconsChanged(QtProperty *, const QMap &)), + this, SLOT(slotEnumIconsChanged(QtProperty *, const QMap &))); + // SizePolicyPropertyManager + QtSizePolicyPropertyManager *sizePolicyPropertyManager = new QtSizePolicyPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::SizePolicy] = sizePolicyPropertyManager; + d_ptr->m_typeToValueType[QVariant::SizePolicy] = QVariant::SizePolicy; + connect(sizePolicyPropertyManager, SIGNAL(valueChanged(QtProperty *, const QSizePolicy &)), + this, SLOT(slotValueChanged(QtProperty *, const QSizePolicy &))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(sizePolicyPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizePolicyPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // FontPropertyManager + QtFontPropertyManager *fontPropertyManager = new QtFontPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Font] = fontPropertyManager; + d_ptr->m_typeToValueType[QVariant::Font] = QVariant::Font; + connect(fontPropertyManager, SIGNAL(valueChanged(QtProperty *, const QFont &)), + this, SLOT(slotValueChanged(QtProperty *, const QFont &))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(fontPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(fontPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(fontPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + connect(fontPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(fontPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // CursorPropertyManager + QtCursorPropertyManager *cursorPropertyManager = new QtCursorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Cursor] = cursorPropertyManager; + d_ptr->m_typeToValueType[QVariant::Cursor] = QVariant::Cursor; + connect(cursorPropertyManager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotValueChanged(QtProperty *, const QCursor &))); + // FlagPropertyManager + int flagId = flagTypeId(); + QtFlagPropertyManager *flagPropertyManager = new QtFlagPropertyManager(this); + d_ptr->m_typeToPropertyManager[flagId] = flagPropertyManager; + d_ptr->m_typeToValueType[flagId] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[flagId][d_ptr->m_flagNamesAttribute] = + QVariant::StringList; + connect(flagPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(flagPropertyManager, SIGNAL(flagNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotFlagNamesChanged(QtProperty *, const QStringList &))); + connect(flagPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + connect(flagPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(flagPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // FlagPropertyManager + int groupId = groupTypeId(); + QtGroupPropertyManager *groupPropertyManager = new QtGroupPropertyManager(this); + d_ptr->m_typeToPropertyManager[groupId] = groupPropertyManager; + d_ptr->m_typeToValueType[groupId] = QVariant::Invalid; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtVariantPropertyManager::~QtVariantPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property converted into a QtVariantProperty. + + If the \a property was not created by this variant manager, the + function returns 0. + + \sa createProperty() +*/ +QtVariantProperty *QtVariantPropertyManager::variantProperty(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().first; +} + +/*! + Returns true if the given \a propertyType is supported by this + variant manager; otherwise false. + + \sa propertyType() +*/ +bool QtVariantPropertyManager::isPropertyTypeSupported(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return true; + return false; +} + +/*! + Creates and returns a variant property of the given \a propertyType + with the given \a name. + + If the specified \a propertyType is not supported by this variant + manager, this function returns 0. + + Do not use the inherited + QtAbstractPropertyManager::addProperty() function to create a + variant property (that function will always return 0 since it will + not be clear what type the property should have). + + \sa isPropertyTypeSupported() +*/ +QtVariantProperty *QtVariantPropertyManager::addProperty(int propertyType, const QString &name) +{ + if (!isPropertyTypeSupported(propertyType)) + return 0; + + bool wasCreating = d_ptr->m_creatingProperty; + d_ptr->m_creatingProperty = true; + d_ptr->m_propertyType = propertyType; + QtProperty *property = QtAbstractPropertyManager::addProperty(name); + d_ptr->m_creatingProperty = wasCreating; + d_ptr->m_propertyType = 0; + + if (!property) + return 0; + + return variantProperty(property); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid variant. + + \sa setValue() +*/ +QVariant QtVariantPropertyManager::value(const QtProperty *property) const +{ + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + return intManager->value(internProp); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + return doubleManager->value(internProp); + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + return boolManager->value(internProp); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + return stringManager->value(internProp); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + return dateManager->value(internProp); + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + return timeManager->value(internProp); + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + return dateTimeManager->value(internProp); + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + return keySequenceManager->value(internProp); + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + return charManager->value(internProp); + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + return localeManager->value(internProp); + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + return pointManager->value(internProp); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + return pointFManager->value(internProp); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + return sizeManager->value(internProp); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + return sizeFManager->value(internProp); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + return rectManager->value(internProp); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + return rectFManager->value(internProp); + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + return colorManager->value(internProp); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + return enumManager->value(internProp); + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + return sizePolicyManager->value(internProp); + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + return fontManager->value(internProp); +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + return cursorManager->value(internProp); +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + return flagManager->value(internProp); + } + return QVariant(); +} + +/*! + Returns the given \a property's value type. + + \sa propertyType() +*/ +int QtVariantPropertyManager::valueType(const QtProperty *property) const +{ + int propType = propertyType(property); + return valueType(propType); +} + +/*! + \overload + + Returns the value type associated with the given \a propertyType. +*/ +int QtVariantPropertyManager::valueType(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return d_ptr->m_typeToValueType[propertyType]; + return 0; +} + +/*! + Returns the given \a property's type. + + \sa valueType() +*/ +int QtVariantPropertyManager::propertyType(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().second; +} + +/*! + Returns the given \a property's value for the specified \a + attribute + + If the given \a property was not created by \e this manager, or if + the specified \a attribute does not exist, this function returns + an invalid variant. + + \sa attributes(), attributeType(), setAttribute() +*/ +QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const +{ + int propType = propertyType(property); + if (!propType) + return QVariant(); + + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QVariant(); + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return QVariant(); + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return intManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return intManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return intManager->singleStep(internProp); + return QVariant(); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return doubleManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return doubleManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return doubleManager->singleStep(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return doubleManager->decimals(internProp); + return QVariant(); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + return stringManager->regExp(internProp); + return QVariant(); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return dateManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return dateManager->minimum(internProp); + return QVariant(); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + return pointFManager->decimals(internProp); + return QVariant(); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeManager->minimum(internProp); + return QVariant(); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeFManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeFManager->minimum(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return sizeFManager->decimals(internProp); + return QVariant(); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectManager->constraint(internProp); + return QVariant(); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectFManager->constraint(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return rectFManager->decimals(internProp); + return QVariant(); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + return enumManager->enumNames(internProp); + if (attribute == d_ptr->m_enumIconsAttribute) { + QVariant v; + qVariantSetValue(v, enumManager->enumIcons(internProp)); + return v; + } + return QVariant(); + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + return flagManager->flagNames(internProp); + return QVariant(); + } + return QVariant(); +} + +/*! + Returns a list of the given \a propertyType 's attributes. + + \sa attributeValue(), attributeType() +*/ +QStringList QtVariantPropertyManager::attributes(int propertyType) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QStringList(); + return it.value().keys(); +} + +/*! + Returns the type of the specified \a attribute of the given \a + propertyType. + + If the given \a propertyType is not supported by \e this manager, + or if the given \a propertyType does not possess the specified \a + attribute, this function returns QVariant::Invalid. + + \sa attributes(), valueType() +*/ +int QtVariantPropertyManager::attributeType(int propertyType, const QString &attribute) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return 0; + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return 0; + return itAttr.value(); +} + +/*! + \fn void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be of a type returned by valueType(), + or of type that can be converted to valueType() using the + QVariant::canConvert() function, otherwise this function does + nothing. + + \sa value(), QtVariantProperty::setValue(), valueChanged() +*/ +void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &val) +{ + int propType = val.userType(); + if (!propType) + return; + + int valType = valueType(property); + + if (propType != valType && !val.canConvert(static_cast(valType))) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + intManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + doubleManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + boolManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + stringManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + dateManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + timeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + dateTimeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + keySequenceManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + charManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + localeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + pointManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + pointFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + sizeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + sizeFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + rectManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + rectFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + colorManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + enumManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + sizePolicyManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + fontManager->setValue(internProp, qVariantValue(val)); + return; +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + cursorManager->setValue(internProp, qVariantValue(val)); + return; +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + flagManager->setValue(internProp, qVariantValue(val)); + return; + } +} + +/*! + Sets the value of the specified \a attribute of the given \a + property, to \a value. + + The new \a value's type must be of the type returned by + attributeType(), or of a type that can be converted to + attributeType() using the QVariant::canConvert() function, + otherwise this function does nothing. + + \sa attributeValue(), QtVariantProperty::setAttribute(), attributeChanged() +*/ +void QtVariantPropertyManager::setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value) +{ + QVariant oldAttr = attributeValue(property, attribute); + if (!oldAttr.isValid()) + return; + + int attrType = value.userType(); + if (!attrType) + return; + + if (attrType != attributeType(propertyType(property), attribute) && + !value.canConvert((QVariant::Type)attrType)) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + intManager->setMaximum(internProp, qVariantValue(value)); + else if (attribute == d_ptr->m_minimumAttribute) + intManager->setMinimum(internProp, qVariantValue(value)); + else if (attribute == d_ptr->m_singleStepAttribute) + intManager->setSingleStep(internProp, qVariantValue(value)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + doubleManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + doubleManager->setMinimum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_singleStepAttribute) + doubleManager->setSingleStep(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + doubleManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + stringManager->setRegExp(internProp, qVariantValue(value)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + dateManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + dateManager->setMinimum(internProp, qVariantValue(value)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + pointFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeManager->setMinimum(internProp, qVariantValue(value)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeFManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeFManager->setMinimum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + sizeFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectManager->setConstraint(internProp, qVariantValue(value)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectFManager->setConstraint(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + rectFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + enumManager->setEnumNames(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_enumIconsAttribute) + enumManager->setEnumIcons(internProp, qVariantValue(value)); + return; + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + flagManager->setFlagNames(internProp, qVariantValue(value)); + return; + } +} + +/*! + \reimp +*/ +bool QtVariantPropertyManager::hasValue(const QtProperty *property) const +{ + if (propertyType(property) == groupTypeId()) + return false; + return true; +} + +/*! + \reimp +*/ +QString QtVariantPropertyManager::valueText(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueText() : QString(); +} + +/*! + \reimp +*/ +QIcon QtVariantPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueIcon() : QIcon(); +} + +/*! + \reimp +*/ +void QtVariantPropertyManager::initializeProperty(QtProperty *property) +{ + QtVariantProperty *varProp = variantProperty(property); + if (!varProp) + return; + + QMap::ConstIterator it = + d_ptr->m_typeToPropertyManager.find(d_ptr->m_propertyType); + if (it != d_ptr->m_typeToPropertyManager.constEnd()) { + QtProperty *internProp = 0; + if (!d_ptr->m_creatingSubProperties) { + QtAbstractPropertyManager *manager = it.value(); + internProp = manager->addProperty(); + d_ptr->m_internalToProperty[internProp] = varProp; + } + propertyToWrappedProperty()->insert(varProp, internProp); + if (internProp) { + QList children = internProp->subProperties(); + QListIterator itChild(children); + QtVariantProperty *lastProperty = 0; + while (itChild.hasNext()) { + QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, itChild.next()); + lastProperty = prop ? prop : lastProperty; + } + } + } +} + +/*! + \reimp +*/ +void QtVariantPropertyManager::uninitializeProperty(QtProperty *property) +{ + const QMap >::iterator type_it = d_ptr->m_propertyToType.find(property); + if (type_it == d_ptr->m_propertyToType.end()) + return; + + PropertyMap::iterator it = propertyToWrappedProperty()->find(property); + if (it != propertyToWrappedProperty()->end()) { + QtProperty *internProp = it.value(); + if (internProp) { + d_ptr->m_internalToProperty.remove(internProp); + if (!d_ptr->m_destroyingSubProperties) { + delete internProp; + } + } + propertyToWrappedProperty()->erase(it); + } + d_ptr->m_propertyToType.erase(type_it); +} + +/*! + \reimp +*/ +QtProperty *QtVariantPropertyManager::createProperty() +{ + if (!d_ptr->m_creatingProperty) + return 0; + + QtVariantProperty *property = new QtVariantProperty(this); + d_ptr->m_propertyToType.insert(property, qMakePair(property, d_ptr->m_propertyType)); + + return property; +} + +///////////////////////////// + +class QtVariantEditorFactoryPrivate +{ + QtVariantEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtVariantEditorFactory) +public: + + QtSpinBoxFactory *m_spinBoxFactory; + QtDoubleSpinBoxFactory *m_doubleSpinBoxFactory; + QtCheckBoxFactory *m_checkBoxFactory; + QtLineEditFactory *m_lineEditFactory; + QtDateEditFactory *m_dateEditFactory; + QtTimeEditFactory *m_timeEditFactory; + QtDateTimeEditFactory *m_dateTimeEditFactory; + QtKeySequenceEditorFactory *m_keySequenceEditorFactory; + QtCharEditorFactory *m_charEditorFactory; + QtEnumEditorFactory *m_comboBoxFactory; + QtCursorEditorFactory *m_cursorEditorFactory; + QtColorEditorFactory *m_colorEditorFactory; + QtFontEditorFactory *m_fontEditorFactory; + + QMap m_factoryToType; + QMap m_typeToFactory; +}; + +/*! + \class QtVariantEditorFactory + + \brief The QtVariantEditorFactory class provides widgets for properties + created by QtVariantPropertyManager objects. + + The variant factory provides the following widgets for the + specified property types: + + \table + \header + \o Property Type + \o Widget + \row + \o \c int + \o QSpinBox + \row + \o \c double + \o QDoubleSpinBox + \row + \o \c bool + \o QCheckBox + \row + \o QString + \o QLineEdit + \row + \o QDate + \o QDateEdit + \row + \o QTime + \o QTimeEdit + \row + \o QDateTime + \o QDateTimeEdit + \row + \o QKeySequence + \o customized editor + \row + \o QChar + \o customized editor + \row + \o \c enum + \o QComboBox + \row + \o QCursor + \o QComboBox + \endtable + + Note that QtVariantPropertyManager supports several additional property + types for which the QtVariantEditorFactory class does not provide + editing widgets, e.g. QPoint and QSize. To provide widgets for other + types using the variant approach, derive from the QtVariantEditorFactory + class. + + \sa QtAbstractEditorFactory, QtVariantPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtVariantEditorFactory::QtVariantEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtVariantEditorFactoryPrivate(); + d_ptr->q_ptr = this; + + d_ptr->m_spinBoxFactory = new QtSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_spinBoxFactory] = QVariant::Int; + d_ptr->m_typeToFactory[QVariant::Int] = d_ptr->m_spinBoxFactory; + + d_ptr->m_doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_doubleSpinBoxFactory] = QVariant::Double; + d_ptr->m_typeToFactory[QVariant::Double] = d_ptr->m_doubleSpinBoxFactory; + + d_ptr->m_checkBoxFactory = new QtCheckBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_checkBoxFactory] = QVariant::Bool; + d_ptr->m_typeToFactory[QVariant::Bool] = d_ptr->m_checkBoxFactory; + + d_ptr->m_lineEditFactory = new QtLineEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_lineEditFactory] = QVariant::String; + d_ptr->m_typeToFactory[QVariant::String] = d_ptr->m_lineEditFactory; + + d_ptr->m_dateEditFactory = new QtDateEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateEditFactory] = QVariant::Date; + d_ptr->m_typeToFactory[QVariant::Date] = d_ptr->m_dateEditFactory; + + d_ptr->m_timeEditFactory = new QtTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_timeEditFactory] = QVariant::Time; + d_ptr->m_typeToFactory[QVariant::Time] = d_ptr->m_timeEditFactory; + + d_ptr->m_dateTimeEditFactory = new QtDateTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateTimeEditFactory] = QVariant::DateTime; + d_ptr->m_typeToFactory[QVariant::DateTime] = d_ptr->m_dateTimeEditFactory; + + d_ptr->m_keySequenceEditorFactory = new QtKeySequenceEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_keySequenceEditorFactory] = QVariant::KeySequence; + d_ptr->m_typeToFactory[QVariant::KeySequence] = d_ptr->m_keySequenceEditorFactory; + + d_ptr->m_charEditorFactory = new QtCharEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_charEditorFactory] = QVariant::Char; + d_ptr->m_typeToFactory[QVariant::Char] = d_ptr->m_charEditorFactory; + + d_ptr->m_cursorEditorFactory = new QtCursorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_cursorEditorFactory] = QVariant::Cursor; + d_ptr->m_typeToFactory[QVariant::Cursor] = d_ptr->m_cursorEditorFactory; + + d_ptr->m_colorEditorFactory = new QtColorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_colorEditorFactory] = QVariant::Color; + d_ptr->m_typeToFactory[QVariant::Color] = d_ptr->m_colorEditorFactory; + + d_ptr->m_fontEditorFactory = new QtFontEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_fontEditorFactory] = QVariant::Font; + d_ptr->m_typeToFactory[QVariant::Font] = d_ptr->m_fontEditorFactory; + + d_ptr->m_comboBoxFactory = new QtEnumEditorFactory(this); + const int enumId = QtVariantPropertyManager::enumTypeId(); + d_ptr->m_factoryToType[d_ptr->m_comboBoxFactory] = enumId; + d_ptr->m_typeToFactory[enumId] = d_ptr->m_comboBoxFactory; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtVariantEditorFactory::~QtVariantEditorFactory() +{ + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager) +{ + QList intPropertyManagers = qFindChildren(manager); + QListIterator itInt(intPropertyManagers); + while (itInt.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itInt.next()); + + QList doublePropertyManagers = qFindChildren(manager); + QListIterator itDouble(doublePropertyManagers); + while (itDouble.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itDouble.next()); + + QList boolPropertyManagers = qFindChildren(manager); + QListIterator itBool(boolPropertyManagers); + while (itBool.hasNext()) + d_ptr->m_checkBoxFactory->addPropertyManager(itBool.next()); + + QList stringPropertyManagers = qFindChildren(manager); + QListIterator itString(stringPropertyManagers); + while (itString.hasNext()) + d_ptr->m_lineEditFactory->addPropertyManager(itString.next()); + + QList datePropertyManagers = qFindChildren(manager); + QListIterator itDate(datePropertyManagers); + while (itDate.hasNext()) + d_ptr->m_dateEditFactory->addPropertyManager(itDate.next()); + + QList timePropertyManagers = qFindChildren(manager); + QListIterator itTime(timePropertyManagers); + while (itTime.hasNext()) + d_ptr->m_timeEditFactory->addPropertyManager(itTime.next()); + + QList dateTimePropertyManagers = qFindChildren(manager); + QListIterator itDateTime(dateTimePropertyManagers); + while (itDateTime.hasNext()) + d_ptr->m_dateTimeEditFactory->addPropertyManager(itDateTime.next()); + + QList keySequencePropertyManagers = qFindChildren(manager); + QListIterator itKeySequence(keySequencePropertyManagers); + while (itKeySequence.hasNext()) + d_ptr->m_keySequenceEditorFactory->addPropertyManager(itKeySequence.next()); + + QList charPropertyManagers = qFindChildren(manager); + QListIterator itChar(charPropertyManagers); + while (itChar.hasNext()) + d_ptr->m_charEditorFactory->addPropertyManager(itChar.next()); + + QList localePropertyManagers = qFindChildren(manager); + QListIterator itLocale(localePropertyManagers); + while (itLocale.hasNext()) + d_ptr->m_comboBoxFactory->addPropertyManager(itLocale.next()->subEnumPropertyManager()); + + QList pointPropertyManagers = qFindChildren(manager); + QListIterator itPoint(pointPropertyManagers); + while (itPoint.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itPoint.next()->subIntPropertyManager()); + + QList pointFPropertyManagers = qFindChildren(manager); + QListIterator itPointF(pointFPropertyManagers); + while (itPointF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itPointF.next()->subDoublePropertyManager()); + + QList sizePropertyManagers = qFindChildren(manager); + QListIterator itSize(sizePropertyManagers); + while (itSize.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itSize.next()->subIntPropertyManager()); + + QList sizeFPropertyManagers = qFindChildren(manager); + QListIterator itSizeF(sizeFPropertyManagers); + while (itSizeF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itSizeF.next()->subDoublePropertyManager()); + + QList rectPropertyManagers = qFindChildren(manager); + QListIterator itRect(rectPropertyManagers); + while (itRect.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itRect.next()->subIntPropertyManager()); + + QList rectFPropertyManagers = qFindChildren(manager); + QListIterator itRectF(rectFPropertyManagers); + while (itRectF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itRectF.next()->subDoublePropertyManager()); + + QList colorPropertyManagers = qFindChildren(manager); + QListIterator itColor(colorPropertyManagers); + while (itColor.hasNext()) { + QtColorPropertyManager *manager = itColor.next(); + d_ptr->m_colorEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + } + + QList enumPropertyManagers = qFindChildren(manager); + QListIterator itEnum(enumPropertyManagers); + while (itEnum.hasNext()) + d_ptr->m_comboBoxFactory->addPropertyManager(itEnum.next()); + + QList sizePolicyPropertyManagers = qFindChildren(manager); + QListIterator itSizePolicy(sizePolicyPropertyManagers); + while (itSizePolicy.hasNext()) { + QtSizePolicyPropertyManager *manager = itSizePolicy.next(); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + } + + QList fontPropertyManagers = qFindChildren(manager); + QListIterator itFont(fontPropertyManagers); + while (itFont.hasNext()) { + QtFontPropertyManager *manager = itFont.next(); + d_ptr->m_fontEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager()); + } + + QList cursorPropertyManagers = qFindChildren(manager); + QListIterator itCursor(cursorPropertyManagers); + while (itCursor.hasNext()) + d_ptr->m_cursorEditorFactory->addPropertyManager(itCursor.next()); + + QList flagPropertyManagers = qFindChildren(manager); + QListIterator itFlag(flagPropertyManagers); + while (itFlag.hasNext()) + d_ptr->m_checkBoxFactory->addPropertyManager(itFlag.next()->subBoolPropertyManager()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + const int propType = manager->propertyType(property); + QtAbstractEditorFactoryBase *factory = d_ptr->m_typeToFactory.value(propType, 0); + if (!factory) + return 0; + return factory->createEditor(wrappedProperty(property), parent); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager) +{ + QList intPropertyManagers = qFindChildren(manager); + QListIterator itInt(intPropertyManagers); + while (itInt.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itInt.next()); + + QList doublePropertyManagers = qFindChildren(manager); + QListIterator itDouble(doublePropertyManagers); + while (itDouble.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itDouble.next()); + + QList boolPropertyManagers = qFindChildren(manager); + QListIterator itBool(boolPropertyManagers); + while (itBool.hasNext()) + d_ptr->m_checkBoxFactory->removePropertyManager(itBool.next()); + + QList stringPropertyManagers = qFindChildren(manager); + QListIterator itString(stringPropertyManagers); + while (itString.hasNext()) + d_ptr->m_lineEditFactory->removePropertyManager(itString.next()); + + QList datePropertyManagers = qFindChildren(manager); + QListIterator itDate(datePropertyManagers); + while (itDate.hasNext()) + d_ptr->m_dateEditFactory->removePropertyManager(itDate.next()); + + QList timePropertyManagers = qFindChildren(manager); + QListIterator itTime(timePropertyManagers); + while (itTime.hasNext()) + d_ptr->m_timeEditFactory->removePropertyManager(itTime.next()); + + QList dateTimePropertyManagers = qFindChildren(manager); + QListIterator itDateTime(dateTimePropertyManagers); + while (itDateTime.hasNext()) + d_ptr->m_dateTimeEditFactory->removePropertyManager(itDateTime.next()); + + QList keySequencePropertyManagers = qFindChildren(manager); + QListIterator itKeySequence(keySequencePropertyManagers); + while (itKeySequence.hasNext()) + d_ptr->m_keySequenceEditorFactory->removePropertyManager(itKeySequence.next()); + + QList charPropertyManagers = qFindChildren(manager); + QListIterator itChar(charPropertyManagers); + while (itChar.hasNext()) + d_ptr->m_charEditorFactory->removePropertyManager(itChar.next()); + + QList localePropertyManagers = qFindChildren(manager); + QListIterator itLocale(localePropertyManagers); + while (itLocale.hasNext()) + d_ptr->m_comboBoxFactory->removePropertyManager(itLocale.next()->subEnumPropertyManager()); + + QList pointPropertyManagers = qFindChildren(manager); + QListIterator itPoint(pointPropertyManagers); + while (itPoint.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itPoint.next()->subIntPropertyManager()); + + QList pointFPropertyManagers = qFindChildren(manager); + QListIterator itPointF(pointFPropertyManagers); + while (itPointF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itPointF.next()->subDoublePropertyManager()); + + QList sizePropertyManagers = qFindChildren(manager); + QListIterator itSize(sizePropertyManagers); + while (itSize.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itSize.next()->subIntPropertyManager()); + + QList sizeFPropertyManagers = qFindChildren(manager); + QListIterator itSizeF(sizeFPropertyManagers); + while (itSizeF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itSizeF.next()->subDoublePropertyManager()); + + QList rectPropertyManagers = qFindChildren(manager); + QListIterator itRect(rectPropertyManagers); + while (itRect.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itRect.next()->subIntPropertyManager()); + + QList rectFPropertyManagers = qFindChildren(manager); + QListIterator itRectF(rectFPropertyManagers); + while (itRectF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itRectF.next()->subDoublePropertyManager()); + + QList colorPropertyManagers = qFindChildren(manager); + QListIterator itColor(colorPropertyManagers); + while (itColor.hasNext()) { + QtColorPropertyManager *manager = itColor.next(); + d_ptr->m_colorEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + } + + QList enumPropertyManagers = qFindChildren(manager); + QListIterator itEnum(enumPropertyManagers); + while (itEnum.hasNext()) + d_ptr->m_comboBoxFactory->removePropertyManager(itEnum.next()); + + QList sizePolicyPropertyManagers = qFindChildren(manager); + QListIterator itSizePolicy(sizePolicyPropertyManagers); + while (itSizePolicy.hasNext()) { + QtSizePolicyPropertyManager *manager = itSizePolicy.next(); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + } + + QList fontPropertyManagers = qFindChildren(manager); + QListIterator itFont(fontPropertyManagers); + while (itFont.hasNext()) { + QtFontPropertyManager *manager = itFont.next(); + d_ptr->m_fontEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager()); + } + + QList cursorPropertyManagers = qFindChildren(manager); + QListIterator itCursor(cursorPropertyManagers); + while (itCursor.hasNext()) + d_ptr->m_cursorEditorFactory->removePropertyManager(itCursor.next()); + + QList flagPropertyManagers = qFindChildren(manager); + QListIterator itFlag(flagPropertyManagers); + while (itFlag.hasNext()) + d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager()); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +//#include "moc_qtvariantproperty.cpp" diff -Nru diffimg-1.5.0/3rdparty/qtpropertybrowser/qtvariantproperty.h diffimg-2.0.0/3rdparty/qtpropertybrowser/qtvariantproperty.h --- diffimg-1.5.0/3rdparty/qtpropertybrowser/qtvariantproperty.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qtpropertybrowser/qtvariantproperty.h 2012-02-21 23:06:58.000000000 +0000 @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef QTVARIANTPROPERTY_H +#define QTVARIANTPROPERTY_H + +#include "qtpropertybrowser.h" +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +typedef QMap QtIconMap; + +class QtVariantPropertyManager; +class QtVariantPropertyPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantProperty : public QtProperty +{ +public: + ~QtVariantProperty(); + QVariant value() const; + QVariant attributeValue(const QString &attribute) const; + int valueType() const; + int propertyType() const; + + void setValue(const QVariant &value); + void setAttribute(const QString &attribute, const QVariant &value); +protected: + QtVariantProperty(QtVariantPropertyManager *manager); +private: + friend class QtVariantPropertyManager; + QtVariantPropertyPrivate *d_ptr; +}; + +class QtVariantPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtVariantPropertyManager(QObject *parent = 0); + ~QtVariantPropertyManager(); + + virtual QtVariantProperty *addProperty(int propertyType, const QString &name = QString()); + + int propertyType(const QtProperty *property) const; + int valueType(const QtProperty *property) const; + QtVariantProperty *variantProperty(const QtProperty *property) const; + + virtual bool isPropertyTypeSupported(int propertyType) const; + virtual int valueType(int propertyType) const; + virtual QStringList attributes(int propertyType) const; + virtual int attributeType(int propertyType, const QString &attribute) const; + + virtual QVariant value(const QtProperty *property) const; + virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const; + + static int enumTypeId(); + static int flagTypeId(); + static int groupTypeId(); + static int iconMapTypeId(); +public Q_SLOTS: + virtual void setValue(QtProperty *property, const QVariant &val); + virtual void setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QVariant &val); + void attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &val); +protected: + virtual bool hasValue(const QtProperty *property) const; + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); + virtual QtProperty *createProperty(); +private: + QtVariantPropertyManagerPrivate *d_ptr; + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QDate &, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QTime &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QLocale &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPoint &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPointF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSize &, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QColor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizePolicy &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QFont &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty *, const QStringList &)) + + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, QtProperty *)) + Q_DECLARE_PRIVATE(QtVariantPropertyManager) + Q_DISABLE_COPY(QtVariantPropertyManager) +}; + +class QtVariantEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtVariantEditorFactory(QObject *parent = 0); + ~QtVariantEditorFactory(); +protected: + void connectPropertyManager(QtVariantPropertyManager *manager); + QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtVariantPropertyManager *manager); +private: + QtVariantEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtVariantEditorFactory) + Q_DISABLE_COPY(QtVariantEditorFactory) +}; + +class QtVariantPropertyManagerPrivate +{ + QtVariantPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtVariantPropertyManager) +public: + QtVariantPropertyManagerPrivate(); + + bool m_creatingProperty; + bool m_creatingSubProperties; + bool m_destroyingSubProperties; + int m_propertyType; + + void slotValueChanged(QtProperty *property, int val); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotValueChanged(QtProperty *property, double val); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotValueChanged(QtProperty *property, bool val); + void slotValueChanged(QtProperty *property, const QString &val); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotValueChanged(QtProperty *property, const QDate &val); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotValueChanged(QtProperty *property, const QTime &val); + void slotValueChanged(QtProperty *property, const QDateTime &val); + void slotValueChanged(QtProperty *property, const QKeySequence &val); + void slotValueChanged(QtProperty *property, const QChar &val); + void slotValueChanged(QtProperty *property, const QLocale &val); + void slotValueChanged(QtProperty *property, const QPoint &val); + void slotValueChanged(QtProperty *property, const QPointF &val); + void slotValueChanged(QtProperty *property, const QSize &val); + void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max); + void slotValueChanged(QtProperty *property, const QSizeF &val); + void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max); + void slotValueChanged(QtProperty *property, const QRect &val); + void slotConstraintChanged(QtProperty *property, const QRect &val); + void slotValueChanged(QtProperty *property, const QRectF &val); + void slotConstraintChanged(QtProperty *property, const QRectF &val); + void slotValueChanged(QtProperty *property, const QColor &val); + void slotEnumChanged(QtProperty *property, int val); + void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames); + void slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons); + void slotValueChanged(QtProperty *property, const QSizePolicy &val); + void slotValueChanged(QtProperty *property, const QFont &val); + void slotValueChanged(QtProperty *property, const QCursor &val); + void slotFlagChanged(QtProperty *property, int val); + void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames); + void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after); + void slotPropertyRemoved(QtProperty *property, QtProperty *parent); + + void valueChanged(QtProperty *property, const QVariant &val); + + int internalPropertyToType(QtProperty *property) const; + QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after, + QtProperty *internal); + void removeSubProperty(QtVariantProperty *property); + + QMap m_typeToPropertyManager; + QMap > m_typeToAttributeToAttributeType; + + QMap > m_propertyToType; + + QMap m_typeToValueType; + + + QMap m_internalToProperty; + + const QString m_constraintAttribute; + const QString m_singleStepAttribute; + const QString m_decimalsAttribute; + const QString m_enumIconsAttribute; + const QString m_enumNamesAttribute; + const QString m_flagNamesAttribute; + const QString m_maximumAttribute; + const QString m_minimumAttribute; + const QString m_regExpAttribute; +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +Q_DECLARE_METATYPE(QIcon) +Q_DECLARE_METATYPE(QtIconMap) +#endif diff -Nru diffimg-1.5.0/3rdparty/qwt/CMakeLists.txt diffimg-2.0.0/3rdparty/qwt/CMakeLists.txt --- diffimg-1.5.0/3rdparty/qwt/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qwt/CMakeLists.txt 2013-05-05 18:50:54.000000000 +0000 @@ -0,0 +1,33 @@ +project(Qwt) + + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# this command finds Qt4 libraries and sets all required variables +FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui REQUIRED) + +INCLUDE(${QT_USE_FILE}) +INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} ${CMAKE_BINARY_DIR} "./" ) + +FILE(GLOB include_file_list "*.h" ) +FILE(GLOB cpp_file_list "*.cpp" ) + + +SET(QWT_HDRS + ${include_file_list} +) + +SET(QWT_SRCS + ${cpp_file_list} +) + +QT4_WRAP_CPP ( QWT_MOC_SRCS ${QWT_HDRS} ) + +IF(COMMAND CMAKE_POLICY) + CMAKE_POLICY(SET CMP0003 NEW) + CMAKE_POLICY(SET CMP0005 OLD) +ENDIF(COMMAND CMAKE_POLICY) + +add_library(qwt STATIC ${QWT_SRCS} ${QWT_MOC_SRCS}) + + diff -Nru diffimg-1.5.0/3rdparty/qwt/qwt.pro diffimg-2.0.0/3rdparty/qwt/qwt.pro --- diffimg-1.5.0/3rdparty/qwt/qwt.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qwt/qwt.pro 2013-05-16 06:41:50.000000000 +0000 @@ -0,0 +1,137 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +# qmake project file for building the qwt libraries + +QWT_ROOT = $${PWD}/. +#include( $${QWT_ROOT}/qwtconfig.pri ) +#include( $${QWT_ROOT}/qwtbuild.pri ) +#include( $${QWT_ROOT}/qwtfunctions.pri ) + +TEMPLATE = lib +TARGET = qwt + +DESTDIR = $${QWT_ROOT}/lib + +contains(QWT_CONFIG, QwtDll) { + + CONFIG += dll + win32|symbian: DEFINES += QT_DLL QWT_DLL QWT_MAKEDLL +} +else { + CONFIG += staticlib +} + +contains(QWT_CONFIG, QwtFramework) { + + CONFIG += lib_bundle +} + +HEADERS += \ + qwt_abstract_scale_draw.h \ + qwt_clipper.h \ + qwt_color_map.h \ + qwt_column_symbol.h \ + qwt_curve_fitter.h \ + qwt_dyngrid_layout.h \ + qwt_global.h \ + qwt_interval.h \ + qwt_legend.h \ + qwt_legend_item.h \ + qwt_legend_itemmanager.h \ + qwt_math.h \ + qwt_null_paintdevice.h \ + qwt_painter.h \ + qwt_plot.h \ + qwt_plot_canvas.h \ + qwt_plot_curve.h \ + qwt_plot_dict.h \ + qwt_plot_grid.h \ + qwt_plot_histogram.h \ + qwt_plot_item.h \ + qwt_plot_layout.h \ + qwt_plot_seriesitem.h \ + qwt_point_3d.h \ + qwt_point_polar.h \ + qwt_scale_div.h \ + qwt_scale_draw.h \ + qwt_scale_engine.h \ + qwt_scale_map.h \ + qwt_scale_widget.h \ + qwt_series_data.h \ + qwt_spline.h \ + qwt_symbol.h \ + qwt_text.h \ + qwt_text_engine.h \ + qwt_text_label.h + +SOURCES += \ + qwt_abstract_scale_draw.cpp \ + qwt_clipper.cpp \ + qwt_color_map.cpp \ + qwt_column_symbol.cpp \ + qwt_curve_fitter.cpp \ + qwt_dyngrid_layout.cpp \ + qwt_interval.cpp \ + qwt_legend.cpp \ + qwt_legend_item.cpp \ + qwt_math.cpp \ + qwt_null_paintdevice.cpp \ + qwt_painter.cpp \ + qwt_plot.cpp \ + qwt_plot_axis.cpp \ + qwt_plot_canvas.cpp \ + qwt_plot_curve.cpp \ + qwt_plot_dict.cpp \ + qwt_plot_grid.cpp \ + qwt_plot_histogram.cpp \ + qwt_plot_item.cpp \ + qwt_plot_layout.cpp \ + qwt_plot_seriesitem.cpp \ + qwt_plot_xml.cpp \ + qwt_point_3d.cpp \ + qwt_point_polar.cpp \ + qwt_scale_div.cpp \ + qwt_scale_draw.cpp \ + qwt_scale_engine.cpp \ + qwt_scale_map.cpp \ + qwt_scale_widget.cpp \ + qwt_series_data.cpp \ + qwt_spline.cpp \ + qwt_symbol.cpp \ + qwt_text.cpp \ + qwt_text_engine.cpp \ + qwt_text_label.cpp + + + DEFINES += QWT_NO_SVG + +# Install directives + +#target.path = $${QWT_INSTALL_LIBS} + +#doc.files = $${QWT_ROOT}/doc/html +#unix:doc.files += $${QWT_ROOT}/doc/man +#doc.path = $${QWT_INSTALL_DOCS} + +#INSTALLS = target doc + +CONFIG(lib_bundle) { + + FRAMEWORK_HEADERS.version = Versions + FRAMEWORK_HEADERS.files = $${HEADERS} + FRAMEWORK_HEADERS.path = Headers + QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS +} +else { + + #headers.files = $${HEADERS} + #headers.path = $${QWT_INSTALL_HEADERS} + #INSTALLS += headers +} diff -Nru diffimg-1.5.0/3rdparty/qwt/qwtbuild.pri diffimg-2.0.0/3rdparty/qwt/qwtbuild.pri --- diffimg-1.5.0/3rdparty/qwt/qwtbuild.pri 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qwt/qwtbuild.pri 2013-05-05 14:00:10.000000000 +0000 @@ -0,0 +1,81 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +###################################################################### +# qmake internal options +###################################################################### + +CONFIG += qt +CONFIG += warn_on +CONFIG += no_keywords +CONFIG += silent + +###################################################################### +# release/debug mode +###################################################################### + +win32 { + # On Windows you can't mix release and debug libraries. + # The designer is built in release mode. If you like to use it + # you need a release version. For your own application development you + # might need a debug version. + # Enable debug_and_release + build_all if you want to build both. + + CONFIG += debug_and_release + CONFIG += build_all +} +else { + + CONFIG += release + + VER_MAJ = $${QWT_VER_MAJ} + VER_MIN = $${QWT_VER_MIN} + VER_PAT = $${QWT_VER_PAT} + VERSION = $${QWT_VERSION} +} + +linux-g++ { + #CONFIG += separate_debug_info + #QMAKE_CXXFLAGS *= -Wfloat-equal + #QMAKE_CXXFLAGS *= -Wshadow + #QMAKE_CXXFLAGS *= -Wpointer-arith + #QMAKE_CXXFLAGS *= -Wconversion + #QMAKE_CXXFLAGS *= -Wsign-compare + #QMAKE_CXXFLAGS *= -Wsign-conversion + #QMAKE_CXXFLAGS *= -Wlogical-op + #QMAKE_CXXFLAGS *= -Werror=format-security + + # when using the gold linker - might be + # necessary on non linux systems too + QMAKE_LFLAGS += -lrt +} + +###################################################################### +# paths for building qwt +###################################################################### + +MOC_DIR = moc +RCC_DIR = resources +!debug_and_release { + OBJECTS_DIR = obj +} + +unix { + + exists( $${QMAKE_LIBDIR_QT}/libqwt.* ) { + + # On some Linux distributions the Qwt libraries are installed + # in the same directory as the Qt libraries. Unfortunately + # qmake always adds QMAKE_LIBDIR_QT at the beginning of the + # linker path, so that the installed libraries will be + # used instead of the local ones. + + error( "local build will conflict with $${QMAKE_LIBDIR_QT}/libqwt.*" ) + } +} diff -Nru diffimg-1.5.0/3rdparty/qwt/qwtconfig.pri diffimg-2.0.0/3rdparty/qwt/qwtconfig.pri --- diffimg-1.5.0/3rdparty/qwt/qwtconfig.pri 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qwt/qwtconfig.pri 2013-05-05 14:21:22.000000000 +0000 @@ -0,0 +1,118 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +QWT_VER_MAJ = 6 +QWT_VER_MIN = 0 +QWT_VER_PAT = 1 +QWT_VERSION = $${QWT_VER_MAJ}.$${QWT_VER_MIN}.$${QWT_VER_PAT} + +###################################################################### +# Install paths +###################################################################### + +QWT_INSTALL_PREFIX = $$[QT_INSTALL_PREFIX] + +unix { + QWT_INSTALL_PREFIX = /usr/local/qwt-$$QWT_VERSION +} + +win32 { + QWT_INSTALL_PREFIX = C:/Qwt-$$QWT_VERSION +} + +QWT_INSTALL_DOCS = $${QWT_INSTALL_PREFIX}/doc +QWT_INSTALL_HEADERS = $${QWT_INSTALL_PREFIX}/include +QWT_INSTALL_LIBS = $${QWT_INSTALL_PREFIX}/lib + +###################################################################### +# Designer plugin +###################################################################### + +QWT_INSTALL_PLUGINS = $${QWT_INSTALL_PREFIX}/plugins/designer +# QWT_INSTALL_PLUGINS = $${QT_INSTALL_PREFIX}/plugins/designer + +###################################################################### +# Features +# When building a Qwt application with qmake you might want to load +# the compiler/linker flags, that are required to build a Qwt application +# from qwt.prf. Therefore all you need to do is to add "CONFIG += qwt" +# to your project file and take care, that qwt.prf can be found by qmake. +# ( see http://doc.trolltech.com/4.7/qmake-advanced-usage.html#adding-new-configuration-features ) +# I recommend not to install the Qwt features together with the +# Qt features, because you will have to reinstall the Qwt features, +# with every Qt upgrade. +###################################################################### + +QWT_INSTALL_FEATURES = $${QWT_INSTALL_PREFIX}/features +# QWT_INSTALL_FEATURES = $${QT_INSTALL_PREFIX}/features + +###################################################################### +# Build the static/shared libraries. +# If QwtDll is enabled, a shared library is built, otherwise +# it will be a static library. +###################################################################### + +#QWT_CONFIG += QwtDll + +###################################################################### +# QwtPlot enables all classes, that are needed to use the QwtPlot +# widget. +###################################################################### + +QWT_CONFIG += QwtPlot + +###################################################################### +# QwtWidgets enables all classes, that are needed to use the all other +# widgets (sliders, dials, ...), beside QwtPlot. +###################################################################### + +QWT_CONFIG += QwtWidgets + +###################################################################### +# If you want to display svg images on the plot canvas, or +# export a plot to a SVG document +###################################################################### + +QWT_CONFIG += QwtSvg + +###################################################################### +# You can use the MathML renderer of the Qt solutions package to +# enable MathML support in Qwt. Because of license implications +# the ( modified ) code of the MML Widget solution is included and +# linked together with the QwtMathMLTextEngine into an own library. +# To use it you will have to add "CONFIG += qwtmathml" +# to your qmake project file. +###################################################################### + +QWT_CONFIG += QwtMathML + +###################################################################### +# If you want to build the Qwt designer plugin, +# enable the line below. +# Otherwise you have to build it from the designer directory. +###################################################################### + +QWT_CONFIG += QwtDesigner + +###################################################################### +# If you want to auto build the examples, enable the line below +# Otherwise you have to build them from the examples directory. +###################################################################### + +# QWT_CONFIG += QwtExamples + +###################################################################### +# When Qt has been built as framework qmake ( qtAddLibrary ) wants +# to link frameworks instead of regular libs +###################################################################### + +macx:CONFIG(qt_framework, qt_framework|qt_no_framework) { + + QWT_CONFIG += QwtFramework +} diff -Nru diffimg-1.5.0/3rdparty/qwt/qwtfunctions.pri diffimg-2.0.0/3rdparty/qwt/qwtfunctions.pri --- diffimg-1.5.0/3rdparty/qwt/qwtfunctions.pri 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/3rdparty/qwt/qwtfunctions.pri 2012-11-30 14:25:08.000000000 +0000 @@ -0,0 +1,55 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +# Copied and modified from qt_functions.prf + +defineReplace(qwtLibraryTarget) { + + unset(LIBRARY_NAME) + LIBRARY_NAME = $$1 + + mac:!static:contains(QT_CONFIG, qt_framework) { + QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME + export(QMAKE_FRAMEWORK_BUNDLE_NAME) + } + + contains(TEMPLATE, .*lib):CONFIG(debug, debug|release) { + !debug_and_release|build_pass { + mac:RET = $$member(LIBRARY_NAME, 0)_debug + else:win32:RET = $$member(LIBRARY_NAME, 0)d + } + } + + isEmpty(RET):RET = $$LIBRARY_NAME + return($$RET) +} + +defineTest(qwtAddLibrary) { + + LIB_NAME = $$1 + + unset(LINKAGE) + + if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + win32:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}d + mac:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}_debug + } + + isEmpty(LINKAGE):LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX} + + !isEmpty(QMAKE_LSB) { + QMAKE_LFLAGS *= --lsb-shared-libs=$${LIB_NAME}$${QT_LIBINFIX} + } + + LIBS += $$LINKAGE + export(LIBS) + export(QMAKE_LFLAGS) + + return(true) +} diff -Nru diffimg-1.5.0/Changelog.txt diffimg-2.0.0/Changelog.txt --- diffimg-1.5.0/Changelog.txt 2013-02-07 12:26:44.000000000 +0000 +++ diffimg-2.0.0/Changelog.txt 2013-07-13 14:31:06.000000000 +0000 @@ -1,3 +1,22 @@ +Version 2.0.0 +* Features: +- new metric engine allowing easy addition of new metric +- support of 16 bits and 32 bits mono channel image (tiff) +- add drag&drop +- add a new metric "perceptual diff" from http://pdiff.sourceforge.net/ +- add gain/offset on displayed image +- add an interactive "navigator" window +- slideshow mode can use files with differents suffix (e.g. compare a file.png with a file.jpg) +- Add Vietnamese translation. Thanks to ppanhh. +- Add Swedish translation. Thanks to eson. +- Add Portuguese translation. Thanks to rafaelff1 . +* Bugs +- incorrect loading of translation file in some cases +- incorrect layout (switch mono/dual panel mode) +Version 1.5.1 +- some code refactoring +- add a direct link to website for help +- update .pro file for missed translation files Version 1.5.0 * Features - add the ability to save image difference in batch mode diff -Nru diffimg-1.5.0/INSTALL.txt diffimg-2.0.0/INSTALL.txt --- diffimg-1.5.0/INSTALL.txt 2012-01-23 18:15:21.000000000 +0000 +++ diffimg-2.0.0/INSTALL.txt 2013-05-15 16:56:36.000000000 +0000 @@ -3,12 +3,26 @@ #> dos2unix tounix.sh #> sh ./tounix.sh #> cd ./build -#> qmake-qt4 -recursive +#> qmake-qt4 -recursive diffimg.pro + or -#> qmake -recursive + +#> cd build +#> qmake -recursive diffimg.pro +#> make +#>sudo make install + +or with cmake +#> cd build +#> cmake . #> make #>sudo make install +Linux dependencies: +- opencv (ubuntu: libopencv-dev) +- qwt (ubuntu: libqwt-dev) + + You can also use qtcreator from qt-sdk # For Centos 5.x user (need a valid Qt4 release in order to compil) @@ -18,6 +32,8 @@ * Windows (tested on XP/Seven x64) +Opencv and qwt are bundled for practicality + Use qtcreator, cmake or the Visual Qt plugin There a NSI script for building a setup.exe file in the setup directory diff -Nru diffimg-1.5.0/LICENSE.txt diffimg-2.0.0/LICENSE.txt --- diffimg-1.5.0/LICENSE.txt 2011-08-29 20:26:10.000000000 +0000 +++ diffimg-2.0.0/LICENSE.txt 2013-05-06 06:01:10.000000000 +0000 @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -56,7 +56,7 @@ The precise terms and conditions for copying, distribution and modification follow. - GNU GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -255,7 +255,7 @@ of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,4 +277,63 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -Nru diffimg-1.5.0/README.txt diffimg-2.0.0/README.txt --- diffimg-1.5.0/README.txt 2012-01-23 18:09:22.000000000 +0000 +++ diffimg-2.0.0/README.txt 2013-05-05 10:41:32.000000000 +0000 @@ -1,2 +1,8 @@ DiffImg is a simple image comparison tool which take two RGB images with the same size as input. Some statitics are computed and the positions where pixel differ are displayed as a color mask. -Because DiffImg is written with Qt, it runs on Windows, Linux, OS/2 (MacOSX isn't tested yet). \ No newline at end of file +Because DiffImg is written with Qt, it runs on Windows, Linux, OS/2 (MacOSX isn't tested yet). + +You want to help ? You can proposed you as translator on transifex.com (DiffImg project) or post feedbacks on SourceForge: +- http://sourceforge.net/p/diffimg/tickets for bug report or feature request +- http://sourceforge.net/p/diffimg/discussion/ for general feedbacks + +You can also help me by correcting my brief help page (I'm sure you've noticed that English is not my mother tongue! :)) Contact me xbee at xbee dot net \ No newline at end of file diff -Nru diffimg-1.5.0/TODO.txt diffimg-2.0.0/TODO.txt --- diffimg-1.5.0/TODO.txt 2012-08-18 13:27:44.000000000 +0000 +++ diffimg-2.0.0/TODO.txt 2013-04-20 08:33:00.000000000 +0000 @@ -1,4 +1,4 @@ - Bug hunt -- more translations (I need help ! Send them to xbee at xbee dot net) +- more translations (I need help !). Send them to xbee at xbee dot net or project is referenced on www.transifex.com, feel free to give help. - Add more metrics ? - And Feel free to write feedback, bug-reports and patches ! diff -Nru diffimg-1.5.0/build/CMakeLists.txt diffimg-2.0.0/build/CMakeLists.txt --- diffimg-1.5.0/build/CMakeLists.txt 2013-03-24 05:59:34.000000000 +0000 +++ diffimg-2.0.0/build/CMakeLists.txt 2013-07-25 03:51:33.000000000 +0000 @@ -18,9 +18,18 @@ PROJECT(DiffImg) # note: change this BEFORE making a release !! -SET( MYAPP_VERSION "1.5.0" ) +SET( MYAPP_VERSION "2.0.0" ) set( PROGNAME diffimg ) +# compilation of others directories +ADD_SUBDIRECTORY("../3rdparty/qtpropertybrowser" "${CMAKE_CURRENT_BINARY_DIR}/qtpropertybrowser") +ADD_SUBDIRECTORY("../3rdparty/perceptualdiff" "${CMAKE_CURRENT_BINARY_DIR}/perceptualdiff") + +IF (MSVC) +ADD_SUBDIRECTORY("../3rdparty/qwt" "${CMAKE_CURRENT_BINARY_DIR}/qwt") +ADD_SUBDIRECTORY("../3rdparty/opencv" "${CMAKE_CURRENT_BINARY_DIR}/opencv") +ENDIF( MSVC ) + IF( APPLE ) SET( MACOSX_BUNDLE_ICON_FILE ${PROGNAME}.icns ) SET( MACOSX_BUNDLE_SHORT_VERSION_STRING ${MYAPP_VERSION} ) @@ -35,16 +44,41 @@ SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_INCLUDE_CURRENT_DIR TRUE) +# Packages path +SET (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) + + # this command finds Qt4 libraries and sets all required variables -FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) +FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui REQUIRED) # add some useful macros and variables # (QT_USE_FILE is a variable defined by FIND_PACKAGE( Qt4 ) that contains a path to CMake script) INCLUDE(${QT_USE_FILE}) -INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} "../src/" "../3rdparty/qwt") -FILE(GLOB include_file_list "../src/*.h" "../3rdparty/qwt/*.h" ) -FILE(GLOB cpp_file_list "../src/*.cpp" "../3rdparty/qwt/*.cpp" ) +IF (MSVC) +INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} "../src/" +"../src/metrics" +"../3rdparty/qwt/" +"../3rdparty/qtpropertybrowser" +"../3rdparty/perceptualdiff" +"../3rdparty/opencv/include" +"../3rdparty/opencv/core/include" +"../3rdparty/opencv/highgui/include" +"../3rdparty/opencv/imgproc/include" ) +ELSE(MSVC) + +FIND_PACKAGE(OpenCV COMPONENTS opencv_core opencv_highgui opencv_imgproc REQUIRED) +FIND_PACKAGE(Qwt6 REQUIRED) + +INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} "../src/" +"../src/metrics" +"../3rdparty/qtpropertybrowser" +"../3rdparty/perceptualdiff" +"/usr/include/qwt" ) +ENDIF(MSVC) + +FILE(GLOB include_file_list "../src/*.h" "../src/metrics/*.h" ) +FILE(GLOB cpp_file_list "../src/*.cpp" "../src/metrics/*.cpp" ) FILE(GLOB resource_file_list "../res/*.qrc") FILE(GLOB ui_file_list "../ui/*.ui") FILE(GLOB trans_file_list "../lang/*.ts") @@ -75,7 +109,7 @@ # enable warnings for GCC compiler IF(CMAKE_COMPILER_IS_GNUCXX ) - ADD_DEFINITIONS( -Wall -Wextra ) + ADD_DEFINITIONS( -Wall -Wextra -Wno-switch -Wno-enum-compare ) ENDIF(CMAKE_COMPILER_IS_GNUCXX ) # qt4 definitinos @@ -110,7 +144,6 @@ # Set some Win32 Specific Settings IF(WIN32) SET(GUI_TYPE WIN32) - ENDIF(WIN32) IF (MSVC) @@ -132,15 +165,15 @@ COMMAND cp ARGS ${MACOSX_BUNDLE_ICON_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.app/Contents/Resources COMMAND cp ARGS *.qm ${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.app/Contents/Resources ) ELSE( APPLE ) - ADD_EXECUTABLE( ${PROGNAME} WIN32 ${MYAPP_SRCS} ${MYAPP_UIS_H} ${MYAPP_MOC_SRCS} ${MYAPP_RESOURCES} ${MYAPP_QM} ) + ADD_EXECUTABLE( ${PROGNAME} WIN32 ${MYAPP_SRCS} ${MYAPP_UIS_H} ${MYAPP_MOC_SRCS} ${MYAPP_RESOURCES} ${MYAPP_QM} ${Qwt6_Qt4_LIBRARY} ) ENDIF( APPLE ) # last thing we have to do is to tell CMake what libraries our executable needs, # luckily FIND_PACKAGE prepared QT_LIBRARIES variable for us: IF (UNIX) - TARGET_LINK_LIBRARIES( ${PROGNAME} ${QT_LIBRARIES} -lX11 -ldl ) + TARGET_LINK_LIBRARIES( ${PROGNAME} ${QT_LIBRARIES} PerceptualDiff qtpropertybrowser qwt opencv_core opencv_highgui opencv_imgproc -lX11 -ldl ) ELSE (UNIX) - TARGET_LINK_LIBRARIES( ${PROGNAME} ${QT_LIBRARIES} ) + TARGET_LINK_LIBRARIES( ${PROGNAME} ${QT_LIBRARIES} PerceptualDiff qtpropertybrowser qwt opencv_core opencv_highgui opencv_imgproc ) ENDIF (UNIX) IF(WIN32) @@ -159,7 +192,7 @@ ADD_CUSTOM_COMMAND( OUTPUT ${DESKTOP_ENTRY} COMMAND touch ${DESKTOP_ENTRY} - COMMAND sh ${CMAKE_SOURCE_DIR}/${PROGNAME}-desktop.sh ${CMAKE_INSTALL_PREFIX} ${MYAPP_VERSION} > ${CMAKE_SOURCE_DIR}/${DESKTOP_ENTRY} + COMMAND sh ${CMAKE_SOURCE_DIR}/${PROGNAME}-desktop.sh ${CMAKE_INSTALL_PREFIX} ${MYAPP_VERSION} > ${CMAKE_SOURCE_DIR}/${DESKTOP_ENTRY} DEPENDS ${PROGNAME}-desktop.sh COMMENT "Generating desktop entry file" ) @@ -176,7 +209,7 @@ ADD_CUSTOM_COMMAND( OUTPUT ${PROGNAME}.1.gz COMMAND touch ${PROGNAME}.1 - COMMAND sh ${CMAKE_SOURCE_DIR}/${PROGNAME}-manpage.sh ${MYAPP_VERSION} > ${CMAKE_SOURCE_DIR}/${PROGNAME}.1 + COMMAND sh ${CMAKE_SOURCE_DIR}/${PROGNAME}-manpage.sh ${MYAPP_VERSION} > ${CMAKE_SOURCE_DIR}/${PROGNAME}.1 COMMAND gzip -f -9 ${PROGNAME}.1 DEPENDS ${PROGNAME}-manpage.sh COMMENT "Generating manpage" @@ -202,7 +235,7 @@ # linux if (UNIX AND NOT APPLE) INSTALL ( TARGETS ${PROGNAME} RUNTIME DESTINATION bin ) - INSTALL ( FILES ${MYAPP_QM} DESTINATION share/${PROGNAME} ) + INSTALL ( FILES ${MYAPP_QM} DESTINATION share/locale ) # freedesktop file INSTALL(FILES ${PROGNAME}.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications/" ) INSTALL(FILES ../res/${PROGNAME}.png DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pixmaps/" ) diff -Nru diffimg-1.5.0/build/apps.pro diffimg-2.0.0/build/apps.pro --- diffimg-1.5.0/build/apps.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/build/apps.pro 2013-07-25 03:51:48.000000000 +0000 @@ -0,0 +1,215 @@ + +QT += core gui + +CONFIG += ordered debug_and_release + +TARGET = diffimg +TEMPLATE = app + +# directories setup +isEmpty( INSTALL_PREFIX ) : INSTALL_PREFIX = /usr + +isEmpty( INSTALL_BINDIR ) : INSTALL_BINDIR = $$INSTALL_PREFIX/bin +isEmpty( INSTALL_LIBDIR ) { + INSTALL_LIBDIR = $$INSTALL_PREFIX/lib + #installing to lib64 on 64-bit platforms: + contains (QMAKE_HOST.arch, x86_64) : INSTALL_LIBDIR = $$INSTALL_PREFIX/lib64 +} + +isEmpty( INSTALL_MANDIR ) : INSTALL_MANDIR = $$INSTALL_PREFIX/share/man +isEmpty( INSTALL_DATADIR ) : INSTALL_DATADIR = $$INSTALL_PREFIX/share + +isEmpty( MYAPP_INSTALL_DESKTOP ) : MYAPP_INSTALL_DESKTOP = $$INSTALL_DATADIR/applications +isEmpty( MYAPP_INSTALL_PIXMAPS ) : MYAPP_INSTALL_PIXMAPS = $$INSTALL_DATADIR/pixmaps +isEmpty( MYAPP_INSTALL_DATA ) : MYAPP_INSTALL_DATA = $$INSTALL_DATADIR/$$TARGET +isEmpty( MYAPP_INSTALL_DIR ) : MYAPP_INSTALL_DIR = $$INSTALL_LIBDIR/$$TARGET +isEmpty( MYAPP_INSTALL_BINDIR ) : MYAPP_INSTALL_BINDIR = $$INSTALL_BINDIR +isEmpty( MYAPP_INSTALL_MAN ) : MYAPP_INSTALL_MAN = $$INSTALL_MANDIR/man1 +isEmpty( MYAPP_INSTALL_TRANS ) : MYAPP_INSTALL_TRANS = $$INSTALL_DATADIR/locale + +HEADERS += \ + ../src/AboutDialog.h \ + ../src/AppSettings.h \ + ../src/DiffImgWindow.h \ + ../src/FilesDialog.h \ + ../src/FilesManager.h \ + ../src/ImageNavigator.h \ + ../src/ImageView.h \ + ../src/LogHandler.h \ + ../src/metrics/BaseMetric.h \ + ../src/metrics/MetricsManager.h \ + ../src/metrics/MetricsRegistering.h \ + ../src/metrics/PerceptualMetric.h \ + ../src/metrics/PerChannelMeanMetric.h \ + ../src/metrics/PerChannelMetric.h \ + ../src/metrics/PerLuminanceMetric.h \ + ../src/MiscFunctions.h \ + ../src/PropertyWidget.h \ + ../src/SplashScreen.h + +SOURCES += \ + ../src/AboutDialog.cpp \ + ../src/AppSettings.cpp \ + ../src/DiffImgWindow.cpp \ + ../src/FilesDialog.cpp \ + ../src/FilesManager.cpp \ + ../src/ImageNavigator.cpp \ + ../src/ImageView.cpp \ + ../src/LogHandler.cpp \ + ../src/main.cpp \ + ../src/metrics/BaseMetric.cpp \ + ../src/metrics/MetricsManager.cpp \ + ../src/metrics/MetricsRegistering.cpp \ + ../src/metrics/PerceptualMetric.cpp \ + ../src/metrics/PerChannelMeanMetric.cpp \ + ../src/metrics/PerChannelMetric.cpp \ + ../src/metrics/PerLuminanceMetric.cpp \ + ../src/MiscFunctions.cpp \ + ../src/PropertyWidget.cpp \ + ../src/SplashScreen.cpp + +FORMS += \ + ../ui/*.ui + + +INCLUDEPATH += \ + $${DESTDIR} \ + ../3rdparty/qtpropertybrowser \ + ../3rdparty/perceptualdiff \ + ../src \ + ../src/metrics + +# bundled libs are only available on visual +# Dont cross the streams. It would be bad ! :) +win32|os2-g++ { + +INCLUDEPATH += \ + ../3rdparty/qwt \ + ../3rdparty/opencv/include \ + ../3rdparty/opencv/core/include \ + ../3rdparty/opencv/highgui/include \ + ../3rdparty/opencv/imgproc/include + +LIBS += -L../3rdparty/qwt/lib -lqwt \ + -L../3rdparty/qtpropertybrowser/lib -lqtpropertybrowser \ + -L../3rdparty/perceptualdiff/lib -lperceptualdiff \ + -L../3rdparty/opencv/imgproc/release -lopencv_imgproc \ + -L../3rdparty/opencv/highgui/release -lopencv_highgui \ + -L../3rdparty/opencv/core/release -lopencv_core \ + -L../3rdparty/opencv/3rdparty/openexr/release -lopenexr \ + -L../3rdparty/opencv/3rdparty/libjasper/release -ljasper \ + -L../3rdparty/opencv/3rdparty/libpng/release -lpng \ + -L../3rdparty/opencv/3rdparty/libtiff/release -ltiff \ + -L../3rdparty/opencv/3rdparty/libjpeg/release -ljpeg \ + -L../3rdparty/opencv/3rdparty/zlib/release -lz + +} + +os2-g++ { +LIBS += -lpthread +} + +unix { + +INCLUDEPATH += /usr/include/qwt + +LIBS += -lqwt \ + -L../3rdparty/qtpropertybrowser/lib -lqtpropertybrowser \ + -L../3rdparty/perceptualdiff/lib -lperceptualdiff \ + -lopencv_imgproc \ + -lopencv_highgui \ + -lopencv_core +} + + + +RESOURCES += ../res/$${TARGET}.qrc + + +TRANSLATIONS = ../lang/$${TARGET}_fr.ts # french +TRANSLATIONS += ../lang/$${TARGET}_cs.ts # Czech +TRANSLATIONS += ../lang/$${TARGET}_it.ts # Italian +TRANSLATIONS += ../lang/$${TARGET}_vi.ts # Vietnamese +TRANSLATIONS += ../lang/$${TARGET}_pt.ts # Portuguese +TRANSLATIONS += ../lang/$${TARGET}_sv.ts # Swedish + +macx:ICON = ../res/$${TARGET}.icns +macx:QMAKE_INFO_PLIST = ../res/Info.plist + +win32:RC_FILE = ../res/$${TARGET}.rc + +win32-msvc*:DEFINES += _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS +*-g++*:QMAKE_CXXFLAGS += -Wno-enum-compare -Wno-switch + +Release:DESTDIR = release +Release:OBJECTS_DIR = release +Release:MOC_DIR = release +Release:RCC_DIR = release +Release:UI_DIR = release + +Debug:DESTDIR = debug +Debug:OBJECTS_DIR = debug +Debug:MOC_DIR = debug +Debug:RCC_DIR = debug +Debug:UI_DIR = debug + +# .qm file for mingw and before setup.nsi +win32-g++ { + # add auto compilation of .ts files + QMAKE_EXTRA_COMPILERS += copyQtTrans + for(TRANS,TRANSLATIONS){ + lang = $$replace(TRANS, .*_([^/]*)\\.ts, \\1) + GLOBALTRANSLATIONS += $$[QT_INSTALL_TRANSLATIONS]/qt_$${lang}.qm + } + copyQtTrans.input = GLOBALTRANSLATIONS + copyQtTrans.output = ${QMAKE_FILE_BASE}.qm + copyQtTrans.commands = cp ${QMAKE_FILE_IN} ../lang/ + copyQtTrans.CONFIG += no_link target_predeps + + # add auto compilation of .ts files + QMAKE_EXTRA_COMPILERS += lrelease + lrelease.input = TRANSLATIONS + lrelease.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.qm + lrelease.commands = $$[QT_INSTALL_BINS]/lrelease ${QMAKE_FILE_IN} -qm ../lang/${QMAKE_FILE_BASE}.qm + lrelease.CONFIG += no_link target_predeps +} + + +unix { + # add auto compilation of .ts files + QMAKE_EXTRA_COMPILERS += lrelease + lrelease.input = TRANSLATIONS + lrelease.output = ${QMAKE_FILE_BASE}.qm + lrelease.commands = $$[QT_INSTALL_BINS]/lrelease ${QMAKE_FILE_IN} -qm ../lang/${QMAKE_FILE_BASE}.qm + lrelease.CONFIG += no_link target_predeps + + # to copy executable to /usr/local/bin directory + starter.files = ./release/$${TARGET} + starter.path = $$MYAPP_INSTALL_BINDIR + + transl.files = ../lang/*.qm + transl.path = $$MYAPP_INSTALL_TRANS + + data.files += ../CREDITS.txt ../README.txt ../AUTHORS.txt ../Changelog.txt + data.path = $$MYAPP_INSTALL_DATA + + # generate desktop file + VERSION = $$system(grep VERSION ../src/AppSettings.h | awk \' { print $NF }\' | sed \'s/\"//g\') + system( sh diffimg-desktop.sh $$INSTALL_PREFIX $$VERSION > diffimg.desktop ) + desktop.files += $${TARGET}.desktop + desktop.path = $$MYAPP_INSTALL_DESKTOP + + icons.files += ../res/$${TARGET}.png + icons.path = $$MYAPP_INSTALL_PIXMAPS + + # generate manpage + system( sh diffimg-manpage.sh > diffimg.1 ) + system( gzip -9 -f diffimg.1 ) + manual.files += diffimg.1.gz + manual.path = $$MYAPP_INSTALL_MAN + + INSTALLS += starter transl data desktop icons manual +} + + + diff -Nru diffimg-1.5.0/build/build.pro diffimg-2.0.0/build/build.pro --- diffimg-1.5.0/build/build.pro 2012-08-18 15:46:05.000000000 +0000 +++ diffimg-2.0.0/build/build.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ - -TARGET = diffimg - -CONFIG += ordered debug_and_release - -# directories setup -isEmpty( INSTALL_PREFIX ) : INSTALL_PREFIX = /usr/local - -isEmpty( INSTALL_BINDIR ) : INSTALL_BINDIR = $$INSTALL_PREFIX/bin -isEmpty( INSTALL_LIBDIR ) { - INSTALL_LIBDIR = $$INSTALL_PREFIX/lib - #installing to lib64 on 64-bit platforms: - contains (QMAKE_HOST.arch, x86_64) : INSTALL_LIBDIR = $$INSTALL_PREFIX/lib64 -} - -isEmpty( INSTALL_MANDIR ) : INSTALL_MANDIR = $$INSTALL_PREFIX/share/man -isEmpty( INSTALL_DATADIR ) : INSTALL_DATADIR = $$INSTALL_PREFIX/share - -isEmpty( MYAPP_INSTALL_DESKTOP ) : MYAPP_INSTALL_DESKTOP = $$INSTALL_DATADIR/applications -isEmpty( MYAPP_INSTALL_PIXMAPS ) : MYAPP_INSTALL_PIXMAPS = $$INSTALL_DATADIR/pixmaps -isEmpty( MYAPP_INSTALL_DATA ) : MYAPP_INSTALL_DATA = $$INSTALL_DATADIR/$$TARGET -isEmpty( MYAPP_INSTALL_DIR ) : MYAPP_INSTALL_DIR = $$INSTALL_LIBDIR/$$TARGET -isEmpty( MYAPP_INSTALL_BINDIR ) : MYAPP_INSTALL_BINDIR = $$INSTALL_BINDIR -isEmpty( MYAPP_INSTALL_MAN ) : MYAPP_INSTALL_MAN = $$INSTALL_MANDIR/man1 -isEmpty( MYAPP_INSTALL_TRANS ) : MYAPP_INSTALL_TRANS = $$INSTALL_DATADIR/locale - - -HEADERS += \ - ../src/AboutDialog.h \ - ../src/AppSettings.h \ - ../src/DiffImgWindow.h \ - ../src/FilesDialog.h \ - ../src/ImageWidget.h \ - ../src/IMessageHandler.h \ - ../src/LogHandler.h \ - ../src/MiscFunctions.h \ - ../src/ScrollImageWidget.h \ - ../src/SplashScreen.h - -SOURCES += \ - ../src/AboutDialog.cpp \ - ../src/AppSettings.cpp \ - ../src/DiffImgWindow.cpp \ - ../src/FilesDialog.cpp \ - ../src/ImageWidget.cpp \ - ../src/LogHandler.cpp \ - ../src/main.cpp \ - ../src/MiscFunctions.cpp \ - ../src/ScrollImageWidget.cpp \ - ../src/SplashScreen.cpp - -FORMS += \ - ../ui/FilesDialog.ui \ - ../ui/DiffImgWindow.ui \ - ../ui/AboutDialog.ui - -#3rd party sources - -SOURCES += \ - ../3rdparty/qwt/qwt_abstract_scale_draw.cpp \ - ../3rdparty/qwt/qwt_clipper.cpp \ - ../3rdparty/qwt/qwt_color_map.cpp \ - ../3rdparty/qwt/qwt_column_symbol.cpp \ - ../3rdparty/qwt/qwt_curve_fitter.cpp \ - ../3rdparty/qwt/qwt_dyngrid_layout.cpp \ - ../3rdparty/qwt/qwt_interval.cpp \ - ../3rdparty/qwt/qwt_legend.cpp \ - ../3rdparty/qwt/qwt_legend_item.cpp \ - ../3rdparty/qwt/qwt_math.cpp \ - ../3rdparty/qwt/qwt_null_paintdevice.cpp \ - ../3rdparty/qwt/qwt_painter.cpp \ - ../3rdparty/qwt/qwt_plot.cpp \ - ../3rdparty/qwt/qwt_plot_axis.cpp \ - ../3rdparty/qwt/qwt_plot_canvas.cpp \ - ../3rdparty/qwt/qwt_plot_curve.cpp \ - ../3rdparty/qwt/qwt_plot_dict.cpp \ - ../3rdparty/qwt/qwt_plot_grid.cpp \ - ../3rdparty/qwt/qwt_plot_histogram.cpp \ - ../3rdparty/qwt/qwt_plot_item.cpp \ - ../3rdparty/qwt/qwt_plot_layout.cpp \ - ../3rdparty/qwt/qwt_plot_seriesitem.cpp \ - ../3rdparty/qwt/qwt_plot_xml.cpp \ - ../3rdparty/qwt/qwt_point_3d.cpp \ - ../3rdparty/qwt/qwt_point_polar.cpp \ - ../3rdparty/qwt/qwt_scale_div.cpp \ - ../3rdparty/qwt/qwt_scale_draw.cpp \ - ../3rdparty/qwt/qwt_scale_engine.cpp \ - ../3rdparty/qwt/qwt_scale_map.cpp \ - ../3rdparty/qwt/qwt_scale_widget.cpp \ - ../3rdparty/qwt/qwt_series_data.cpp \ - ../3rdparty/qwt/qwt_spline.cpp \ - ../3rdparty/qwt/qwt_symbol.cpp \ - ../3rdparty/qwt/qwt_text.cpp \ - ../3rdparty/qwt/qwt_text_engine.cpp \ - ../3rdparty/qwt/qwt_text_label.cpp - -HEADERS += \ - ../3rdparty/qwt/qwt_abstract_scale_draw.h \ - ../3rdparty/qwt/qwt_clipper.h \ - ../3rdparty/qwt/qwt_color_map.h \ - ../3rdparty/qwt/qwt_column_symbol.h \ - ../3rdparty/qwt/qwt_curve_fitter.h \ - ../3rdparty/qwt/qwt_dyngrid_layout.h \ - ../3rdparty/qwt/qwt_global.h \ - ../3rdparty/qwt/qwt_interval.h \ - ../3rdparty/qwt/qwt_legend.h \ - ../3rdparty/qwt/qwt_legend_item.h \ - ../3rdparty/qwt/qwt_legend_itemmanager.h \ - ../3rdparty/qwt/qwt_math.h \ - ../3rdparty/qwt/qwt_null_paintdevice.h \ - ../3rdparty/qwt/qwt_painter.h \ - ../3rdparty/qwt/qwt_plot.h \ - ../3rdparty/qwt/qwt_plot_canvas.h \ - ../3rdparty/qwt/qwt_plot_curve.h \ - ../3rdparty/qwt/qwt_plot_dict.h \ - ../3rdparty/qwt/qwt_plot_grid.h \ - ../3rdparty/qwt/qwt_plot_histogram.h \ - ../3rdparty/qwt/qwt_plot_item.h \ - ../3rdparty/qwt/qwt_plot_layout.h \ - ../3rdparty/qwt/qwt_plot_seriesitem.h \ - ../3rdparty/qwt/qwt_point_3d.h \ - ../3rdparty/qwt/qwt_point_polar.h \ - ../3rdparty/qwt/qwt_scale_div.h \ - ../3rdparty/qwt/qwt_scale_draw.h \ - ../3rdparty/qwt/qwt_scale_engine.h \ - ../3rdparty/qwt/qwt_scale_map.h \ - ../3rdparty/qwt/qwt_scale_widget.h \ - ../3rdparty/qwt/qwt_series_data.h \ - ../3rdparty/qwt/qwt_spline.h \ - ../3rdparty/qwt/qwt_symbol.h \ - ../3rdparty/qwt/qwt_text.h \ - ../3rdparty/qwt/qwt_text_engine.h \ - ../3rdparty/qwt/qwt_text_label.h - -INCLUDEPATH += \ - $${DESTDIR} \ - ../3rdparty/qwt \ - ../src - -#DEFINES += - -RESOURCES += ../res/$${TARGET}.qrc - -QT += core gui - -TRANSLATIONS = ../lang/$${TARGET}_fr.ts ../lang/$${TARGET}_cs.ts ../lang/$${TARGET}_it.ts - -macx:ICON = ../res/$${TARGET}.icns -macx:QMAKE_INFO_PLIST = ../res/Info.plist - -win32:RC_FILE = ../res/$${TARGET}.rc - - -Release:DESTDIR = release -Release:OBJECTS_DIR = release -Release:MOC_DIR = release -Release:RCC_DIR = release -Release:UI_DIR = release - -Debug:DESTDIR = debug -Debug:OBJECTS_DIR = debug -Debug:MOC_DIR = debug -Debug:RCC_DIR = debug -Debug:UI_DIR = debug - -unix { - # to copy executable to /usr/local/bin directory - starter.files = ./release/$$TARGET - starter.path = $$MYAPP_INSTALL_BINDIR - - transl.files = ./lang/*.qm - transl.path = $$MYAPP_INSTALL_TRANS - - data.files += ../CREDITS.txt ../README.txt ../AUTHORS.txt ../Changelog.txt - data.path = $$MYAPP_INSTALL_DATA - - desktop.files += $$TARGET.desktop - desktop.path = $$MYAPP_INSTALL_DESKTOP - - icons.files += ../res/$$TARGET.png - icons.path = $$MYAPP_INSTALL_PIXMAPS - - # generate manpage - system( sh diffimg-manpage.sh > diffimg.1 ) - system( gzip -9 -f diffimg.1 ) - manual.files += diffimg.1.gz - manual.path = $$MYAPP_INSTALL_MAN - - INSTALLS += starter transl data desktop icons manual -} - - - diff -Nru diffimg-1.5.0/build/cmake/FindQwt6.cmake diffimg-2.0.0/build/cmake/FindQwt6.cmake --- diffimg-1.5.0/build/cmake/FindQwt6.cmake 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/build/cmake/FindQwt6.cmake 2012-09-14 13:58:22.000000000 +0000 @@ -0,0 +1,137 @@ +# Find the Qwt 6.x includes and library, either the version linked to Qt3 or +# the version linked to Qt4 +# +# On Windows it makes these assumptions: +# - the Qwt DLL is where the other DLLs for Qt are (QT_DIR\bin) or in the path +# - the Qwt .h files are in QT_DIR\include\Qwt or in the path +# - the Qwt .lib is where the other LIBs for Qt are (QT_DIR\lib) or in the path +# +# Qwt6_INCLUDE_DIR - where to find qwt.h if Qwt +# Qwt6_Qt4_LIBRARY - The Qwt6 library linked against Qt4 (if it exists) +# Qwt6_Qt3_LIBRARY - The Qwt6 library linked against Qt4 (if it exists) +# Qwt6_Qt4_FOUND - Qwt6 was found and uses Qt4 +# Qwt6_Qt3_FOUND - Qwt6 was found and uses Qt3 +# Qwt6_FOUND - Set to TRUE if Qwt6 was found (linked either to Qt3 or Qt4) + +# Copyright (c) 2007, Pau Garcia i Quiles, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# Condition is "(A OR B) AND C", CMake does not support parentheses but it +# evaluates left to right +IF(Qwt6_Qt4_LIBRARY OR Qwt6_Qt3_LIBRARY AND Qwt6_INCLUDE_DIR) + SET(Qwt6_FIND_QUIETLY TRUE) +ENDIF(Qwt6_Qt4_LIBRARY OR Qwt6_Qt3_LIBRARY AND Qwt6_INCLUDE_DIR) + +IF(NOT QT4_FOUND) + FIND_PACKAGE( Qt4 REQUIRED QUIET ) +ENDIF(NOT QT4_FOUND) + +IF( QT4_FOUND ) + # Is Qwt6 installed? Look for header files + FIND_PATH( Qwt6_INCLUDE_DIR qwt.h + PATHS ${QT_INCLUDE_DIR} + /usr/local/qwt/include + /usr/include/qwt + /usr/local/qwt-6.0.1-svn/include/ + /usr/local/qwt-6.0.0-rc1/include + /usr/local/qwt-6.0.0-rc3/include + F:/kde/qwt-6.0.0-rc4/src + PATH_SUFFIXES + qwt + qwt6 + qwt-qt4 + qwt6-qt4 + qwt-qt3 + qwt6-qt3 + include + qwt/include + qwt6/include + qwt-qt4/include + qwt6-qt4/include + qwt-qt3/include + qwt6-qt3/include + ENV PATH) + + # Find Qwt version + IF( Qwt6_INCLUDE_DIR ) + FILE( READ ${Qwt6_INCLUDE_DIR}/qwt_global.h QWT_GLOBAL_H ) + STRING( REGEX MATCH "#define *QWT_VERSION *(0x06*)" QWT_IS_VERSION_6 ${QWT_GLOBAL_H}) + + IF( QWT_IS_VERSION_6 ) + STRING(REGEX REPLACE ".*#define[\\t\\ ]+QWT_VERSION_STR[\\t\\ ]+\"([0-9]+\\.[0-9]+\\.[0-9]+)\".*" "\\1" Qwt_VERSION "${QWT_GLOBAL_H}") + + # Find Qwt6 library linked to Qt4 + FIND_LIBRARY( Qwt6_Qt4_TENTATIVE_LIBRARY + NAMES qwt6-qt4 qwt-qt4 qwt6 qwt + PATHS + /usr/local/qwt/lib + /usr/local/lib + /usr/local/qwt-6.0.1-svn/lib + /usr/local/qwt-6.0.0-rc1/lib + /usr/local/qwt-6.0.0-rc3/lib + /usr/lib + F:/kde/qwt-6.0.0-rc4/lib + ${QT_LIBRARY_DIR}) + + IF( UNIX AND NOT CYGWIN) + IF( Qwt6_Qt4_TENTATIVE_LIBRARY ) + #MESSAGE("Qwt6_Qt4_TENTATIVE_LIBRARY = ${Qwt6_Qt4_TENTATIVE_LIBRARY}") + EXECUTE_PROCESS( COMMAND "ldd" ${Qwt6_Qt4_TENTATIVE_LIBRARY} OUTPUT_VARIABLE Qwt_Qt4_LIBRARIES_LINKED_TO ) + STRING( REGEX MATCH ".*QtCore.*" Qwt6_IS_LINKED_TO_Qt4 ${Qwt_Qt4_LIBRARIES_LINKED_TO}) + IF( Qwt6_IS_LINKED_TO_Qt4 ) + SET( Qwt6_Qt4_LIBRARY ${Qwt6_Qt4_TENTATIVE_LIBRARY} ) + SET( Qwt6_Qt4_FOUND TRUE ) + IF (NOT Qwt6_FIND_QUIETLY) + MESSAGE( STATUS "Found Qwt: ${Qwt6_Qt4_LIBRARY}" ) + ENDIF (NOT Qwt6_FIND_QUIETLY) + ENDIF( Qwt6_IS_LINKED_TO_Qt4 ) + ENDIF( Qwt6_Qt4_TENTATIVE_LIBRARY ) + ELSE( UNIX AND NOT CYGWIN) + # Assumes qwt.dll is in the Qt dir + SET( Qwt6_Qt4_LIBRARY ${Qwt6_Qt4_TENTATIVE_LIBRARY} ) + SET( Qwt6_Qt4_FOUND TRUE ) + IF (NOT Qwt6_FIND_QUIETLY) + MESSAGE( STATUS "Found Qwt version ${Qwt_VERSION} linked to Qt4" ) + ENDIF (NOT Qwt6_FIND_QUIETLY) + ENDIF( UNIX AND NOT CYGWIN) + + + # Find Qwt6 library linked to Qt3 + FIND_LIBRARY( Qwt6_Qt3_TENTATIVE_LIBRARY NAMES qwt-qt3 qwt qwt6-qt3 qwt6 ) + IF( UNIX AND NOT CYGWIN) + IF( Qwt6_Qt3_TENTATIVE_LIBRARY ) + #MESSAGE("Qwt6_Qt3_TENTATIVE_LIBRARY = ${Qwt6_Qt3_TENTATIVE_LIBRARY}") + EXECUTE_PROCESS( COMMAND "ldd" ${Qwt6_Qt3_TENTATIVE_LIBRARY} OUTPUT_VARIABLE Qwt-Qt3_LIBRARIES_LINKED_TO ) + STRING( REGEX MATCH "qt-mt" Qwt6_IS_LINKED_TO_Qt3 ${Qwt-Qt3_LIBRARIES_LINKED_TO}) + IF( Qwt6_IS_LINKED_TO_Qt3 ) + SET( Qwt6_Qt3_LIBRARY ${Qwt6_Qt3_TENTATIVE_LIBRARY} ) + SET( Qwt6_Qt3_FOUND TRUE ) + IF (NOT Qwt6_FIND_QUIETLY) + MESSAGE( STATUS "Found Qwt version ${Qwt_VERSION} linked to Qt3" ) + ENDIF (NOT Qwt6_FIND_QUIETLY) + ENDIF( Qwt6_IS_LINKED_TO_Qt3 ) + ENDIF( Qwt6_Qt3_TENTATIVE_LIBRARY ) + ELSE( UNIX AND NOT CYGWIN) + SET( Qwt6_Qt3_LIBRARY ${Qwt6_Qt3_TENTATIVE_LIBRARY} ) + SET( Qwt6_Qt3_FOUND TRUE ) + IF (NOT Qwt6_FIND_QUIETLY) + MESSAGE( STATUS "Found Qwt: ${Qwt6_Qt3_LIBRARY}" ) + ENDIF (NOT Qwt6_FIND_QUIETLY) + ENDIF( UNIX AND NOT CYGWIN) + + ENDIF( QWT_IS_VERSION_6 ) + + IF( Qwt6_Qt4_FOUND OR Qwt6_Qt3_FOUND ) + SET( Qwt6_FOUND TRUE ) + ENDIF( Qwt6_Qt4_FOUND OR Qwt6_Qt3_FOUND ) + + MARK_AS_ADVANCED( Qwt6_INCLUDE_DIR Qwt6_Qt4_LIBRARY Qwt6_Qt3_LIBRARY ) + ENDIF( Qwt6_INCLUDE_DIR ) + + IF (NOT Qwt6_FOUND AND Qwt6_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Qwt 6.x") + ENDIF (NOT Qwt6_FOUND AND Qwt6_FIND_REQUIRED) + +ENDIF( QT4_FOUND ) diff -Nru diffimg-1.5.0/build/diffimg-desktop.sh diffimg-2.0.0/build/diffimg-desktop.sh --- diffimg-1.5.0/build/diffimg-desktop.sh 2013-03-24 05:46:48.000000000 +0000 +++ diffimg-2.0.0/build/diffimg-desktop.sh 2013-07-24 11:38:33.000000000 +0000 @@ -3,11 +3,11 @@ [Desktop Entry] Version=$2 Name=DiffImg -Comment=image comparison tool +Comment=Image comparison tool Type=Application GenericName=image comparison tool TryExec=$1/bin/diffimg -Exec=$1/bin/diffimg & +Exec=$1/bin/diffimg Categories=Utility;Application; Icon=$1/share/pixmaps/diffimg.png EOF diff -Nru diffimg-1.5.0/build/diffimg-manpage.sh diffimg-2.0.0/build/diffimg-manpage.sh --- diffimg-1.5.0/build/diffimg-manpage.sh 2013-03-24 05:46:48.000000000 +0000 +++ diffimg-2.0.0/build/diffimg-manpage.sh 2013-07-24 11:38:51.000000000 +0000 @@ -1,6 +1,6 @@ #!/bin/sh cat < - -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root - - -BuildRequires: qt-devel >= 4.6 -BuildRequires: cmake >= 2.4.3 - -%description -DiffImg is a simple image comparison tool which take two RGB images with the same size as input. Some statitics are computed and the positions where pixel differ are displayed as a color mask. - -Homepage: http://thehive.xbee.net/index.php?module=pages&func=display&pageid=11 - - - -%prep -%setup - -%build -cd build -cmake -DCMAKE_INSTALL_PREFIX=$RPM_BUILD_ROOT/usr \ - -DCMAKE_BUILD_TYPE=Release \ - ./ -make - -%install -rm -rf $RPM_BUILD_ROOT -cd build -make install DESTDIR=$RPM_BUILD_ROOT -make install - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files - -%defattr(-,root,root) -# DiffImg binary -%{_bindir}/diffimg -%{_datadir}/applications/diffimg.desktop -%{_datadir}/pixmaps/diffimg.png - - -%doc CREDITS.txt README.txt AUTHORS.txt Changelog.txt - - - - - - - - -%changelog -* Thu Jan 24 2012 xbee - - first package version diff -Nru diffimg-1.5.0/build/genRPM.sh diffimg-2.0.0/build/genRPM.sh --- diffimg-1.5.0/build/genRPM.sh 2013-03-24 05:46:48.000000000 +0000 +++ diffimg-2.0.0/build/genRPM.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -#!/bin/sh - -if [ -n "$OSGDESIGNER_HOME" ]; then - OSGDESIGNER_DIR=${OSGDESIGNER_HOME} -elif [ -d "./osgDesigner" ]; then - OSGDESIGNER_DIR=$PWD/osgDesigner -elif [ -n $1 ]; then - OSGDESIGNER_DIR=$1 -else - echo "Must define $OSGDESIGNER_HOME" - echo " or change current directory to directory where osgDesigner is" - echo " or give the osgDesigner path in parameter" - exit 1 -fi - - -if [ -z "$RPMBUILDDIR" ]; then - if [ -d $HOME/rpmbuild ]; then - RPMBUILDDIR=$HOME/rpmbuild - else - echo "Must define RPMBUILDDIR environment variable" - exit 1 - fi -fi - -echo "Use $RPMBUILDDIR for rpmbuild" - -VERSION=`grep "%define osgDesigner_version" $OSGDESIGNER_DIR/packages/rpm/osgDesigner.spec | cut -d " " -f 3` -RELEASE=`grep "%define osgDesigner_release" $OSGDESIGNER_DIR/packages/rpm/osgDesigner.spec | cut -d " " -f 3` - - -#cd $RPMBUILDDIR/SOURCES/ - -# clean the SOURCES directory -rm -rf $RPMBUILDDIR/SOURCES/osgDesigner-$VERSION - -# export the svn repository -svn export $OSGDESIGNER_DIR $RPMBUILDDIR/SOURCES/osgDesigner-$VERSION - -# tar bzip the source -tar --directory $RPMBUILDDIR/SOURCES -jcvf $RPMBUILDDIR/SOURCES/osgDesigner-$VERSION-$RELEASE.tar.bz2 osgDesigner-$VERSION - -# make rpm and srpm -rpmbuild --ta --rmsource --rmspec --clean $RPMBUILDDIR/SOURCES/osgDesigner-$VERSION-$RELEASE.tar.bz2 --nodeps - -exit 0 diff -Nru diffimg-1.5.0/build/libs.pro diffimg-2.0.0/build/libs.pro --- diffimg-1.5.0/build/libs.pro 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/build/libs.pro 2013-05-15 16:53:34.000000000 +0000 @@ -0,0 +1,3 @@ +SUBDIRS += ../3rdparty +TEMPLATE = subdirs + diff -Nru diffimg-1.5.0/debian/changelog diffimg-2.0.0/debian/changelog --- diffimg-1.5.0/debian/changelog 2013-03-24 07:38:07.000000000 +0000 +++ diffimg-2.0.0/debian/changelog 2013-07-25 04:00:27.000000000 +0000 @@ -1,4 +1,19 @@ -diffimg (1.5.0-1dhor~raring) raring; urgency=low +diffimg (2.0.0-1dhor~raring) raring; urgency=low + + * new metric engine allowing easy addition of new metric + * support of 16 bits and 32 bits mono channel image (tiff) + * add drag&drop + * add a new metric "perceptual diff" from http://pdiff.sourceforge.net/ + * add gain/offset on displayed image + * add an interactive "navigator" window + * slideshow mode can use files with differents suffix (e.g. compare a file.png with a file.jpg) + * Add Vietnamese translation. Thanks to ppanhh. + * Add Swedish translation. Thanks to eson. + * Add Portuguese translation. Thanks to rafaelff1 + + -- Dariusz Duma Wed, 24 Jul 2013 13:13:11 +0200 + +diffimg (1.5.0-2dhor~raring) raring; urgency=low * add the ability to save image difference in batch mode * clean code (cppcheck) diff -Nru diffimg-1.5.0/debian/control diffimg-2.0.0/debian/control --- diffimg-1.5.0/debian/control 2012-11-13 09:40:20.000000000 +0000 +++ diffimg-2.0.0/debian/control 2013-07-24 11:36:31.000000000 +0000 @@ -2,7 +2,7 @@ Section: graphics Priority: extra Maintainer: Dariusz Duma -Build-Depends: debhelper (>= 8.0.0), qt4-qmake, cmake, libqt4-dev, libx11-dev +Build-Depends: debhelper (>= 8.0.0), qt4-qmake, cmake, libqt4-dev, libx11-dev, libopencv-dev, libqwt-dev Standards-Version: 3.9.2 Homepage: http://thehive.xbee.net #Vcs-Git: git://git.debian.org/collab-maint/diffimg.git diff -Nru diffimg-1.5.0/debian/rules_bak diffimg-2.0.0/debian/rules_bak --- diffimg-1.5.0/debian/rules_bak 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/debian/rules_bak 2013-07-25 03:16:57.000000000 +0000 @@ -0,0 +1,14 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ --buildsystem=cmake --sourcedirectory=build + Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/diffimg_1.5.0.orig.tar.gz and /tmp/TanR_227uO/diffimg-2.0.0/diffimg_1.5.0.orig.tar.gz differ diff -Nru diffimg-1.5.0/formater.bat diffimg-2.0.0/formater.bat --- diffimg-1.5.0/formater.bat 2012-03-30 20:18:56.000000000 +0000 +++ diffimg-2.0.0/formater.bat 2013-05-15 06:03:56.000000000 +0000 @@ -2,4 +2,10 @@ dir /b *.cpp > lfiles.txt dir /b *.h >> lfiles.txt uncrustify.exe -F lfiles.txt --no-backup -c ..\uncrustify.cfg +del lfiles.txt +cd metrics +dir /b *.cpp *.h > lfiles.txt +uncrustify.exe -F lfiles.txt --no-backup -c ..\..\uncrustify.cfg +del lfiles.txt +cd .. pause Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/icons.png and /tmp/TanR_227uO/diffimg-2.0.0/icons.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_cs.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_cs.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_cs.ts diffimg-2.0.0/lang/diffimg_cs.ts --- diffimg-1.5.0/lang/diffimg_cs.ts 2013-02-05 19:53:18.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_cs.ts 2013-07-17 17:28:46.000000000 +0000 @@ -4,7 +4,7 @@ - + release of translation and translator name please put your name here dear translator and the release of the translation file !! Pavel Fric @@ -13,78 +13,42 @@ AboutDialog - The CREDITS file can't be found, sorry ... - Le fichier CREDITS n'a pas été trouvé, désolé ... + + <a href="%1">Check for new release ...</a> + <a href="%1">Zkontrolovat dostupnost nového vydání...</a> - The CREDITS.txt file can't be found, sorry ... - Le fichier CREDITS.txt n'a pas été trouvé, désolé ... + + Qt version %1 + Verze Qt %1 - + The %1 file can't be found, sorry ... Nelze najít soubor %1, promiňte... - + detected language: %1 ZjiÅ¡tÄ›ný jazyk: %1 - + Automatic detection Automatické urÄení - + Default (no use of translation files) Výchozí (žádné užití pÅ™ekladových souborů) - + The application need to restart in order to take into account new translation , Do you want to restart application now ? Program je potÅ™eba spustit znovu, aby se zmÄ›na jazyka mohla projevit. Chcete program spustit znovu nyní? - - - Difference by channel - Rozdíl podle kanálu - - - - Difference by channel mean - Rozdíl podle průmÄ›ru kanálu - - - - Difference by image lightness - Rozdíl podle podle svÄ›tlosti obrázku - - - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - Rozdíl je poÄítán mezi obÄ›ma průmÄ›rnými hodnotami stanovenými jako mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - - - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - Rozdíl je poÄítán mezi obÄ›ma hodnotami svÄ›tlosti stanovenými jako lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - - - Difference by constrast - Rozdíl podle kontrastu - - - - Difference is computed channel by channel - Rozdíl je poÄítán kanál podle kanálu - - - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - Rozdíl je poÄítán mezi obÄ›ma hodnotami kontrastu stanovenými jako contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - AboutDialogClass @@ -95,583 +59,527 @@ O programu - - Release Number - Verze - - - + Credits PodÄ›kování - + Changelog Seznam zmÄ›n - + + Release Number + Verze + + + Preferences Nastavení - + Language Jazyk - + Detected language ... ZjiÅ¡tÄ›ný jazyk... - - Mask opacity (0-transparent,100-opaque) - Neprůhlednost masky (0 - průhledná, 100 - neprůhledná) + + Splashscreen with transparent background + Uvítací obrazovka s průhledným pozadím - - Error mask opacity (%) - Neprůhlednost masky odchylky (%) + + Display splashscreen at startup + PÅ™i spuÅ¡tÄ›ní zobrazit uvítací obrazovku - - Difference method - Metoda rozdílu + + Difference metric used + Použitá metrika - - Threshold in RMS - Práh v SKHod + + Allow image difference + Povolit rozdíl mezi obrázky - - RMS threshold (float): - Práh SKHod (pohyblivá hodnota): + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + DiskriminaÄní parametr (obrázky jsou považovány za lišící se, pokud je pÅ™ekroÄen práh) - - Allow image difference - Povolit rozdíl mezi obrázky + + Discriminating parameter + RozliÅ¡ovací parametr - - Display splashscreen at startup - PÅ™i spuÅ¡tÄ›ní zobrazit uvítací obrazovku + + Threshold + Práh - - Splashscreen with transparent background - Uvítací obrazovka s průhledným pozadím + + Metric + Metrika + + + + Input parameters + Vstupní parametry - RMS threshold: - Seuil RMS + + Mask opacity (0-transparent,100-opaque) + Neprůhlednost masky (0 - průhledná, 100 - neprůhledná) - Allow pixel difference - Autoriser les pixels différents + + Error mask opacity (%) + Neprůhlednost masky odchylky (%) - + Infos Informace - + Supported formats (via Qt plugins) Podporované formáty (pÅ™es přídavné moduly Qt) - + Available translations Dostupné pÅ™eklady - + Log Zápis - BackgroundPainter - - No Desktop Environment Detected - Aucun environnement détecté - - - load %1 - chargement de %1 - - - Saving temp file (%1) - Sauvegarde du fichier temporaire (%1) - - - Failed to save temp file (%1) - Echec de la sauvegarde du fichier temporaire (%1) - - - - BackgroundPainterConfigWidget - - Image parameters - Parametres d'image - - - Ignore aspect ratio - Ignorer le rapport d'aspect - - - Keep aspect ratio - Conserver le rapport d'aspect - - - Keep aspect ratio by expanding - Conserver le rapport d'aspect par accroissement - + BaseMetric - Center Image - Centrer l'image + + + + Unknown + Neznámý - Linux desktop integration - Intégration au bureau Linux + + No description + Žádný popis - KDE3 desktop - KDE3 - - - GNOME desktop - Gnome - - - KDE4 desktop - KDE4 - - - Xfce Desktop - Xfce - - - Fluxbox desktop - Fluxbox - - - Blackbox desktop - Blackbox - - - WindowMaker desktop - WindowMaker + + Mean error + PrůmÄ›rná odchylka - FVWM desktop - FVWM + + Mean absolute error + PrůmÄ›rná absolutní odchylka - - - DiffImgWindow - - - - Image Viewer - ProhlížeÄ obrázků + + Min error + Nejmenší odchylka - - Cannot display difference, image have different size (%1x%2/%3x%4) - Nelze zobrazit rozdíl, obrázky mají různou velikost (%1x%2/%3x%4) + + Minimum error + Nejmenší odchylka - - - Cannot load %1. - Nelze nahrát %1. + + Max error + NejvÄ›tší odchylka - - - DiffImgWindowClass - - diffimg - diffimg + + Maximum error + NejvÄ›tší odchylka - - Navigator - Obrázky + + Standard deviation + Obvyklá odchylka - - Original - Původní + + RMS error deviation + RMS odchylky - - Modified - ZmÄ›nÄ›ný + + Root Mean Square error + Odchylka stÅ™ední kvadratické hodnoty - - Difference - Rozdíl + + Error num (pixels) + PoÄet odchylek (v pixelech) - - - Statistics - Statistika + + Number of different pixels + PoÄet rozdílných pixelů - Size: - Taille: + + Error (% pixels) + Odchylka (% pixelů) - - - - - - - - - - - - - - 0 - 0 + + Number of different pixels in % + PoÄet rozdílných pixelů v % - Diff Nb: - Nb diff : + + Dimension (pixels) + RozmÄ›ry (v pixelech) - Mean Diff: - Diff moyenne : + + Dimension in pixel of images + RozmÄ›ry v pixelech - RMS Diff: - Diff RMS : + + Size (pixels) + Velikost (v pixelech) - Mean pixel diff: - Moyenne des diff : + + Size in pixel of images + Velikost v pixelech - - Min error: - Nejmenší odchylka: + + Size file1 + Velikost souboru 1 - - Max error: - NejvÄ›tší odchylka: + + + Size in bytes of image + Velikost v bytech - - Position - Poloha + + + %1/%2 + %1/%2 - - X: - X: + + Size file2 + Velikost souboru 2 - - Y: - Y: + + Format file1 + Formát souboru 1 - - R: - ÄŒervená: + + + Format of the image + Formát obrázku - - Size (pixels): - Velikost (v pixelech): + + Format file2 + Formát souboru 2 - - number of pixel with difference - PoÄet pixelů s rozdílem + + Band + Pásmo - Error Nb (pixels): - Nb erreurs (pixels) : + + Number of band in the image (3 for RGB image) + PoÄet pásem v obrázku (3 pro obrázek RGB) - - - Mean error - PrůmÄ›rná odchylka + + Band depth + Hloubka - Global mean error: - Erreur moyenne globale : + + Number of bits per band (U:unsigned, S:signed, F:float) + PoÄet bitů na pásmo (U:bez znaménka, S:se znaménkem, F:plovoucí řádová Äárka) + + + DiffImgWindow - - - Root Mean Square error - Odchylka stÅ™ední kvadratické hodnoty + + Current metric: %1 + NynÄ›jší metrika: %1 - - RMS Error: - Odchylka stÅ™ední kvadratické hodnoty: + + Can't display difference, more information in the log panel ... + Nelze zobrazit rozdíl. Více informací je v panelu se zápisem... - Mean of error on pixel with difference - Moyenne des erreurs sur les pixels différents + + + Image Viewer + ProhlížeÄ obrázků - - Mean error: - PrůmÄ›rná odchylka: + + + Cannot load %1. + Nelze nahrát %1. - - - Minimal value of error - Nejmenší hodnota odchylky + + Scale x%1 + Měřítko x%1 + + + DiffImgWindowClass - - - Maximal value of error - NejvÄ›tší hodnota odchylky + + diffimg + diffimg - - - Standard deviation of error - Obvyklá odchylka odchylky + + Main toolbar + Hlavní nástrojový pruh - - Standard deviation - Obvyklá odchylka + + Navigator + Obrázky - - - Red component - ÄŒervená složka + + Original + Původní - - Method: - Metoda: + + Modified + ZmÄ›nÄ›ný - - - Green component - Zelená složka + + Difference + Rozdíl - - G: - Zelená: + + Gain + Zesílení - - - Blue component - Modrá složka + + Offset + Posun - - B: - Modrá: + + + Histogram + Histogram - - - Zoom factor - Násobek zvÄ›tÅ¡ení + + Statistics + Statistika - - Zoom: - ZvÄ›tÅ¡ení: + + (*) statistics exceeding the authorized threshold + (*) statistika pÅ™ekroÄila povolený práh - + yellow color: pixel with error >mean error Žlutá barva: pixel s chybou > průmÄ›rná odchylka - <img src=":/diffimg/yellow.png" /> diff pixel > mean diff - <img src=":/diffimg/yellow.png" /> diff > diff moyenne + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> odchylka &gt;průmÄ›rná odchylka - + red color: pixel with error <= mean error ÄŒervená barva: pixel s chybou <= průmÄ›rná odchylka - <img src=":/diffimg/red.png" /> diff pixel - <img src=":/diffimg/red.png" /> erreur - - - - Error Num (pixels): - PoÄet odchylek (v pixelech): - - - - <img src=":/diffimg/yellow.png" /> error &gt; mean error - <img src=":/diffimg/yellow.png" /> odchylka &gt;průmÄ›rná odchylka - - - + <img src=":/diffimg/red.png" /> error <img src=":/diffimg/red.png" /> odchylka - - - Histogram - Histogram - - - + Display Original Image Zobrazit původní obrázek - + 1 1 - + Display Modified Image Zobrazit zmÄ›nÄ›ný obrázek - + 2 2 - + Display Difference Image Zobrazit rozdílový obrázek - + D D - + Quit UkonÄit - + Ctrl+Q Ctrl+Q - + Fit to window Umístit do okna - + Full resolution Plné rozliÅ¡ení - + Open Otevřít - + actionNext Další - - - + + + Next image Další obrázek - + N N - + Prev PÅ™edchozí - - - + + + Previous image PÅ™edchozí obrázek - + P P - + Difference Image Rozdílový obrázek - + 3 3 - + Dual Panel Dva panely - + Ctrl+D Ctrl+D - + About O programu - + Preferences Nastavení - + Refresh Obnovit + + + R + R + + + + Help + NápovÄ›da + + + + Online help + NápovÄ›da na internetu + + + + F1 + F1 + FilesDialog - - + + Open File Otevřít soubor @@ -695,388 +603,402 @@ - QObject - - message from other instance. - message d'une autre instance. - - - %1 is already running !! - %1 est déjà en fonctionnement !! - - - - translations path %1 - Cesta k pÅ™ekladům %1 - - - - setting language to : %1 - Nastavení jazyka na %1 - - - - successfully loaded data from %1 - ÚspěšnÄ› nahrána data z %1 - - - - failed to load data from %1 - NepodaÅ™ilo se nahrát data z %1 - - - - Image Difference tool. - Nástroj na zobrazení rozdílů mezi obrázky. - - - - Usage: - Použití: - - - - [options] - [volby] - - - - img1 img2 - img1 img2 - - - - Following options are known: - Jsou dostupné následující volby: - - - - --batch - batch mode. Differences are computed without GUI and return code is used as result. - --batch - dávkový režim. Rozdíly jsou poÄítány bez grafického uživatelského rozhraní a jako výsledek se používá vrácený kód. - - - - --rms-threshold value - [only for batch mode]. Threshold value for RMS computation. - --rms-threshold value - [pouze pro dávkový režim]. Hodnota prahu pro výpoÄet stÅ™ední kvadratické hodnoty. - + PerChannelMeanMetric - - --diff-method value - [only for batch mode]. Method used to compute difference. - --diff-method value - [pouze pro dávkový režim]. Metoda používaná na výpoÄet rozdílu. + + Difference per channel mean + Rozdíl na průmÄ›r kanálu - - --output xx.yy - [only for batch mode]. Save image difference in xx.yy file (only if comparison failed). - --output xx.yy - [pouze pro dávkový režim]. Uložit rozdíl obrázku do souboru xx.yy (pouze, když porovnání selže). + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + Rozdíl je poÄítán mezi obÄ›ma průmÄ›rnými hodnotami stanovenými jako mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + + PerChannelMetric - - Available methods: 0 - - Dostupné metody: 0 - + + Difference per channel + Rozdíl na kanál - + Difference is computed channel per channel Rozdíl je poÄítán kanál podle kanálu + + + PerLuminanceMetric - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - Rozdíl je poÄítán mezi obÄ›ma průmÄ›rnými hodnotami stanovenými jako mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - - - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - Rozdíl je poÄítán mezi obÄ›ma hodnotami svÄ›tlosti stanovenými jako lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + Difference per image luminance + Rozdíl na jasnost obrázku - - 2 - - 2 - + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + Rozdíl je poÄítán mezi obÄ›ma průmÄ›rnými hodnotami stanovenými jako luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + + PerceptualMetric - Difference is computed channel by channel - Rozdíl je poÄítán kanál podle kanálu + + Perceptual difference + Vjemový rozdíl - - 1 - - 1 - + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Na vnímání založená metrika obrázku. Autorské právo (C) 2006 Yangli Hector Yee - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - Rozdíl je poÄítán mezi obÄ›ma hodnotami kontrastu stanovenými jako contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + Field of view + Zorné pole - - --help - displays this help. - --help - zobrazí tuto nápovÄ›du. + + Field of view in degrees (0.1 to 89.9) + Zorné pole ve stupních (0.1 až 89.9) - - --reset-config - clear the saved preference parameters. - --reset-config - vynuluje uložená nastavení. + + Gamma of screen + Gama obrazovky - - You must set valid filename files as arguments in batch mode !! - V dávkovém režimu musíte jako argumenty nastavit platné souborové názvy souborů! + + Value to convert rgb into linear space (default 2.2) + Hodnota pro pÅ™evod rgb into lineární prostor (výchozí 2.2) - - Files are different - Soubory jsou odliÅ¡né + + White luminance + Bílý jas - - Error Num (pixels): - PoÄet odchylek (v pixelech): + + White luminance (default 100.0 cdm^-2) + Bílý jas (výchozí 100.0 cdm^-2) - - Mean error: - PrůmÄ›rná odchylka: + + Luminance only + Pouze jasnost - - RMS Error: - Odchylka stÅ™ední kvadratické hodnoty: + + Only consider luminance; ignore chroma (color) in the comparison + Zvažovat pouze jas; ve srovnání si nevšímat sytosti barvy (chroma) (barva) - - Standard deviation - Obvyklá odchylka + + Color factor + Faktor barvy - - Saving of %1 failed !! - Uložení %1 selhalo! + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Kolik barvy použít, 0.0 až 1.0, 0.0 = pÅ™ehlížet barvu. - - Files are identical - Soubory jsou totožné + + Downsample + Podvzorkování - - You must set two files as arguments in batch mode !! - V dávkovém režimu musíte jako argumenty nastavit dva soubory! + + How many powers of two to down sample the image + Kolik umocnÄ›ní na druhou pro pÅ™evzorkování obrázku dolů - Scheduler + PropertyWidget - Start new timer for %1 sec ... - Démarrage d'un nouveau minuteur pour %1 sec ... + + Properties + Vlastnosti - New Schedule fired ... - Nouvelle programmation démarrée ... + + Statistics + Statistika - SchedulerConfigWidget - - Scheduling parameters - Paramètres de programmation - - - - Auto change at startup - Changement automatique au démarrage - + QObject - Quit application after startup change (30s) - Quitter l'application après le démarrage (30sec) + + + Image Difference tool. + Nástroj na zobrazení rozdílů mezi obrázky. - Change Interval - Intervale + + Available metrics: + Dostupné metriky: - Interval between change (h:m:s) - Intervale entre les changements + + Input parameters: + Vstupní parametry: - set time of day (h:m:s) - Ajouter un horaire + + Output parameters: + Výstupní parametry: - Add to the timeofday list - Ajouter à la liste des horaires + + How to use batch mode: + Jak použít dávkový režim: - Delete selected timeofday - Effacer les horaires sélectionnés + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Příklad 1: --batch --metric PerChannelMeanMetric : Použít průmÄ›rnou metriku na kanál - - - SyncWall - Can't create storage location, check why ?! (%1) - Impossible de créer le répertoire de stockage, recherchez pourquoi ?! (%1) + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Příklad 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Použít metriku na kanál a ukonÄit s chybou, pokud je poÄet pixelů s rozdílem vyšší než 250 - Active Desktop must be disabled !! - ActiveDesktop doit être désactivé !! + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Příklad 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Použít vnímavostní metriku s nÄ›kterou sadou vstupních parametrů a ukonÄit s chybou, pokud je poÄet pixelů s rozdílem vyšší než 250 - Add Wallpaper Directory - Ajouter un répertoire de fonds d'écran + + Usage: + Použití: - Add all found directories recursively ? - Ajouter tous les répertoires récursivement ? + + [options] + [volby] - add %1 folder - ajouter répertoire %1 + + img1 img2 + img1 img2 - Select one or more wallpapers - Sélectionner un ou plusieurs fonds d'écran + + Following options are known: + Jsou dostupné následující volby: - Images (%1) - Images (%1) + + --list - list all metrics with their parameters. + --list - uvést vÅ¡echnu metriku s parametry. - Systray - Zone de notification + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - dávkový režim. Rozdíly jsou poÄítány bez grafického uživatelského rozhraní a jako výsledek se používá vrácený kód. - The program will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray entry. - Le programme va rester actif dans la zone de notification. Pour sortir définitivement, choisir <b>Quitter</b> dans le menu contextuel de la zone de notification. + + --metric - metric tag name. Display list of metrics with --list option. + --metric - Název znaÄky metriky. Zobrazit seznam metriky volbou --list. - &Quit - &Quitter + + --in name=value - input parameter update. + --in name=value - aktualizace vstupního parametru. - Change background - Change de fond d'écran + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold name=value - Výstupní parametr použitý pro stanovení porovnávacího dávkového režimu. Pokud nastavíte nÄ›kolik parametrů prahu, bude zachován jen ten poslední. - %1 images in list - %1 images dans la liste + + You must set valid filename files as arguments in batch mode !! + V dávkovém režimu musíte jako argumenty nastavit platné souborové názvy souborů! - Invalid file ? : %1 - Fichier invalide ? : %1 + + Metric %1 unknown !! + Metrika %1 neznámá! - - - SyncWallClass - Preview - Prévisualisation + + Metric %1 has no input parameter !! + Metrika %1 nemá vstupní parametr! - Quit - Quitter + + Can't display difference, more information in the log panel ... + Nelze zobrazit rozdíl. Více informací je v panelu se zápisem... - Add a new folder - Ajouter un nouveau répertoire + + Files are identical + Soubory jsou totožné - Preview - Prévisualisation + + Files are identical (under the threshold) + Soubory jsou totožné (pod prahem) - Refresh file list - Rafraîchir la liste de fichiers + + Error in options ! + Chyba ve volbách! - Switch file list/provider view - Basculer vue fichiers/fournisseurs + + You must set at least two files as arguments in batch mode !! + V dávkovém režimu musíte jako argumenty nastavit alespoň dva soubory! - No Wallpaper - Aucun fond d'écran + + setting language to : %1 + Nastavení jazyka na %1 - Preview selected wallpaper - Prévisualiser le fond d'écran sélectionné + + + successfully loaded data from %1 + Data úspěšnÄ› nahrána z %1 - Auto Change in random order - Changement automatique aléatoire + + failed to load data from %1 + NepodaÅ™ilo se nahrát data z %1 - Preferences - Préférences + + Bytes + byty - Startup - Démarrage + + KB + Kilobyte + KB - Startup - Démarrage + + MB + Megabyte + MB - Start in notification tray (minimized) - Démarrer dans la zone de notification (minimisé) + + GB + Gigabyte + GB - Display splashscreen at startup - Afficher l'écran d'accueil au démarrage + + TB + Terabyte + TB - Auto start with system - Démarrage automatique avec le système + + Pixels + pixelsů - Use Global Hotkey for manual change of wallpaper - Utiliser un raccourcis clavier global pour changer + + Kp + Kilopixel + Kp - Hotkey: - Raccourcis : + + Mp + Megapixel + Mp - Scheduling - Programmation + + Gp + Gigapixel + Gp - Display Parameters - Paramètres d'affichage + + Tp + Terapixel + Tp - Network - Réseau + + + + Value: %1 + Hodnota: %1 - About - A propos + + + + Value: %1, + Hodnota: %1. - Supported formats (via Qt plugins) - Formats supportés (via greffons Qt) + + + + + Alpha: %1 + Alfa: %1 - Available translations - Traductions disponibles + + + Red: %1, + ÄŒervená: %1, - Release Number - Version + + + Green: %1, + Zelená: %1, - Log - Journal + + Blue: %1 + Modrá: %1 - Clear Log - Effacer le journal + + Blue: %1, + Modrá: %1, - - - WallpaperProvider - Cannot find the directory - Impossible de trouver le répertoire + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + Neprovedeno (%1) Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_fr.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_fr.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_fr.ts diffimg-2.0.0/lang/diffimg_fr.ts --- diffimg-1.5.0/lang/diffimg_fr.ts 2013-02-05 15:59:36.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_fr.ts 2013-07-17 17:28:46.000000000 +0000 @@ -1,103 +1,54 @@ - + - release of and translator name - put your name here dear translator !! - fichier de traduction par xbee (v1.0) - - - + release of translation and translator name please put your name here dear translator and the release of the translation file !! - Fichier de traduction par xbee (v1.5.0) + Fichier de traduction par xbee v2.0 AboutDialog - The CREDITS file can't be found, sorry ... - Le fichier CREDITS n'a pas été trouvé, désolé ... + + <a href="%1">Check for new release ...</a> + <a href="%1">Voir pour une nouvelle version ...</a> - The CREDITS.txt file can't be found, sorry ... - Le fichier CREDITS.txt n'a pas été trouvé, désolé ... + + Qt version %1 + Qt version %1 - + The %1 file can't be found, sorry ... Le fichier %1 n'a pas été trouvé, désolé ... - + detected language: %1 langue détectée : %1 - + Automatic detection Détection automatique - + Default (no use of translation files) Par défaut (pas d'utilisation de traduction) - + The application need to restart in order to take into account new translation , Do you want to restart application now ? L'application doit redémerrer pour prendre en compte le changement de langue, Voulez-vous redémarrer maintenant ? - - - Difference by channel - Différence par canal - - - - Difference by channel mean - Différence par la moyenne des canaux - - - - Difference by image lightness - Différence des luminosités - - - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les moyennes des canaux RVB exprimée par moy(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 - - - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - La différence est calculée entre les luminosités des images exprimée par Y(x,y) = 0.3*R(x,y)+0.59*V(x,y)+0.11*B(x,y) - - - Difference is computed between both mean value defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les moyennes des canaux RVB exprimée par moy(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 - - - Difference is computed between both lightness value defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - La différence est calculée entre les luminosités des images exprimée par Y(x,y) = 0.3*R(x,y)+0.59*V(x,y)+0.11*B(x,y) - - - Difference by constrast - Différence par constraste - - - - Difference is computed channel by channel - La différence est calculée canal par canal - - - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les constrastes des images exprimée par contrast(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 - AboutDialogClass @@ -108,583 +59,527 @@ A propos - - Release Number - Version - - - + Credits Remerciements - + Changelog Journal des modifications - + + Release Number + Version + + + Preferences Préférences - + Language Langue - + Detected language ... Langue détectée ... - - Mask opacity (0-transparent,100-opaque) - Opacity du masque (0 - transparent, 100 - opaque) + + Splashscreen with transparent background + Afficher l'écran d'acceuil avec transparence - - Error mask opacity (%) - Opacité du masque des erreurs + + Display splashscreen at startup + Afficher l'écran d'accueil au démarrage - - Difference method - Méthode de calcul + + Difference metric used + Métrique utilisé - - Threshold in RMS - Seuil RMS + + Allow image difference + Autoriser les différences entre images - - RMS threshold (float): - Seuil RMS (valeur flottante) : + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + Paramètre discriminant (les images sont considérées différentes si le seuil est dépassé) - - Allow image difference - Autoriser les différences entre images + + Discriminating parameter + Paramètre discriminant - - Display splashscreen at startup - Afficher l'écran d'accueil au démarrage + + Threshold + Seuil - - Splashscreen with transparent background - Afficher l'écran d'acceuil avec transparence + + Metric + Métrique - RMS threshold: - Seuil RMS + + Input parameters + Paramètres d'entrée - Allow pixel difference - Autoriser les pixels différents + + Mask opacity (0-transparent,100-opaque) + Opacity du masque (0 - transparent, 100 - opaque) - + + Error mask opacity (%) + Opacité du masque des erreurs + + + Infos Informations - + Supported formats (via Qt plugins) Formats supportés (via greffons Qt) - + Available translations Traductions disponibles - + Log Journal - BackgroundPainter - - No Desktop Environment Detected - Aucun environnement détecté - - - load %1 - chargement de %1 - - - Saving temp file (%1) - Sauvegarde du fichier temporaire (%1) - - - Failed to save temp file (%1) - Echec de la sauvegarde du fichier temporaire (%1) - - - - BackgroundPainterConfigWidget + BaseMetric - Image parameters - Parametres d'image + + + + Unknown + Inconnu - Ignore aspect ratio - Ignorer le rapport d'aspect + + No description + Aucune description - Keep aspect ratio - Conserver le rapport d'aspect - - - Keep aspect ratio by expanding - Conserver le rapport d'aspect par accroissement - - - Center Image - Centrer l'image - - - Linux desktop integration - Intégration au bureau Linux - - - KDE3 desktop - KDE3 - - - GNOME desktop - Gnome - - - KDE4 desktop - KDE4 - - - Xfce Desktop - Xfce - - - Fluxbox desktop - Fluxbox - - - Blackbox desktop - Blackbox + + Mean error + Erreur moyenne - WindowMaker desktop - WindowMaker + + Mean absolute error + Erreur moyenne absolue - FVWM desktop - FVWM - - - - DiffImgWindow - - - - - Image Viewer - Visualiseur d'image + + Min error + Erreur min - - Cannot display difference, image have different size (%1x%2/%3x%4) - Impossible d'afficher les différences, les images ont des tailles différentes (%1x%2/%3x%4) + + Minimum error + Erreur minimale - - - Cannot load %1. - Impossible de charger %1. + + Max error + Erreur max - - - DiffImgWindowClass - - diffimg - diffimg + + Maximum error + Erreur maximale - - Navigator - Navigateur + + Standard deviation + Ecart type - - Original - Originale + + RMS error deviation + RMS de l'erreur - - Modified - Modifiée + + Root Mean Square error + Racine carrée de l'erreur quadratique moyenne - - Difference - Différence + + Error num (pixels) + Nombre d'erreurs (pixels) - - - Statistics - Statistiques + + Number of different pixels + Nombre des pixels ayant une différence - Size: - Taille: + + Error (% pixels) + Erreurs ( % pixels): - - - - - - - - - - - - - - 0 - + + Number of different pixels in % + Nombre des pixels différents en % - Diff Nb: - Nb diff : + + Dimension (pixels) + Taille (pixels) - Mean Diff: - Diff moyenne : + + Dimension in pixel of images + Taille en pixel des images - RMS Diff: - Diff RMS : + + Size (pixels) + Taille (pixels) - Mean pixel diff: - Moyenne des diff : + + Size in pixel of images + Taille en pixel des images - - Min error: - Erreur min : + + Size file1 + Taille fichier 1 - - Max error: - Erreur max : + + + Size in bytes of image + Taille en octet de l'image - - Position - Position + + + %1/%2 + %1/%2 - - X: - + + Size file2 + Taille fichier 2 - - Y: - + + Format file1 + Format fichier 1 - - R: - + + + Format of the image + Format de l'image - - Size (pixels): - Taille (pixels): + + Format file2 + Format fichier 2 - - number of pixel with difference - Nombre des pixels ayant une différence + + Band + Bande - Error Nb (pixels): - Nb erreurs (pixels) : + + Number of band in the image (3 for RGB image) + Nombre de bandes de l'image (3 pour les image RVB) - - - Mean error - Erreur moyenne + + Band depth + Profondeur - Global mean error: - Erreur moyenne globale : + + Number of bits per band (U:unsigned, S:signed, F:float) + Nombre de bits par bande (U:non signé, S:signé, F: flottant) + + + DiffImgWindow - - - Root Mean Square error - Erreur quadratique moyenne + + Current metric: %1 + Métrique courante: %1 - - RMS Error: - Erreur quadratique moyenne : + + Can't display difference, more information in the log panel ... + Impossible d'afficher la différence, plus d'informations dans le journal - Mean of error on pixel with difference - Moyenne des erreurs sur les pixels différents + + + Image Viewer + Visualiseur d'image - - Mean error: - Erreur moyenne : + + + Cannot load %1. + Impossible de charger %1. - - - Minimal value of error - Valeur minimale de l'erreur + + Scale x%1 + Echelle x%1 + + + DiffImgWindowClass - - - Maximal value of error - Valeur maximale de l'erreur + + diffimg + diffimg - - - Standard deviation of error - Déviation standard ed l'erreur + + Main toolbar + Barre d'outils principale - - Standard deviation - Déviation standard + + Navigator + Navigateur - - - Red component - Composante rouge + + Original + Originale - - Method: - Méthode : + + Modified + Modifiée - - - Green component - Composante verte + + Difference + Différence - - G: - V: + + Gain + Gain - - - Blue component - Composante bleue + + Offset + Décalage - - B: - + + + Histogram + Histogramme - - - Zoom factor - Facteur de zoom + + Statistics + Statistiques - - Zoom: - + + (*) statistics exceeding the authorized threshold + (*) statistiques dépassant le seuil autorisé - + yellow color: pixel with error >mean error Couleur jaune: pixel ayant une erreur > moyenne des erreurs - <img src=":/diffimg/yellow.png" /> diff pixel > mean diff - <img src=":/diffimg/yellow.png" /> diff > diff moyenne + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> erreur &gt;erreur moyenne - + red color: pixel with error <= mean error Couleur rouge: pixel ayant une erreur <= moyenne des erreurs - <img src=":/diffimg/red.png" /> diff pixel - <img src=":/diffimg/red.png" /> erreur - - - - Error Num (pixels): - Nb erreurs (pixels): - - - - <img src=":/diffimg/yellow.png" /> error &gt; mean error - <img src=":/diffimg/yellow.png" /> erreur &gt;erreur moyenne - - - + <img src=":/diffimg/red.png" /> error <img src=":/diffimg/red.png" /> erreur - - - Histogram - Histogramme - - - + Display Original Image Affichage image originale - + 1 - + 1 - + Display Modified Image Affichage image modifiée - + 2 - + 2 - + Display Difference Image Affichage image des différences - + D - + D - + Quit Quitter - + Ctrl+Q Ctrl+Q - + Fit to window Ajuster à la fenêtre - + Full resolution Pleine résolution - + Open Ouvrir - + actionNext - + Suivant - - - + + + Next image Prochaine image - + N - + N - + Prev Image précedente - - - + + + Previous image Image précédente - + P - + P - + Difference Image Image des différences - + 3 - + 3 - + Dual Panel Deux panneaux - + Ctrl+D - + Ctrl+D - + About A propos - + Preferences Préférences - + Refresh Recharger + + + R + R + + + + Help + Aide en ligne + + + + Online help + Aide en ligne + + + + F1 + F1 + FilesDialog - - + + Open File Ouvrir fichier @@ -694,7 +589,7 @@ Dialog - + Dialogue @@ -708,392 +603,402 @@ - QObject - - message from other instance. - message d'une autre instance. - - - %1 is already running !! - %1 est déjà en fonctionnement !! - + PerChannelMeanMetric - - translations path %1 - chemin des traductions %1 - - - - setting language to : %1 - positionner le lauguage à %1 - - - - successfully loaded data from %1 - chargement réussi des données de %1 - - - - failed to load data from %1 - échec de chargement des données de %1 - - - - Image Difference tool. - Outil d'affichage de différence d'images. - - - - Usage: - Usage : - - - - [options] - [options] - - - - img1 img2 - img1 img2 - - - - Following options are known: - Les options suivantes sont disponibles : - - - - --batch - batch mode. Differences are computed without GUI and return code is used as result. - --batch - mode batch.La comparaison est réalisée en ligne et un code de retour est positionné comme résultat. - - - - --rms-threshold value - [only for batch mode]. Threshold value for RMS computation. - --rms-threshold value - [seulement pour le mode batch]. Valeur du seuil RMS pour la comparaison (défaut: 0.0). - - - - --diff-method value - [only for batch mode]. Method used to compute difference. - --diff-method valeur - [seulement pour le mode batch]. Méthode utilisé pour calculer les différences. + + Difference per channel mean + Différence par la moyenne des canaux - - --output xx.yy - [only for batch mode]. Save image difference in xx.yy file (only if comparison failed). - --output xx.yy - [seulement pour le mode batch]. Sauvegarde de l'image des différences (uniquement si des différences sont détectées). + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + La différence est calculée entre les moyennes des canaux RVB exprimée par moy(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 + + + PerChannelMetric - - Available methods: 0 - - Méthodes disponibles: 0 - + + Difference per channel + Différence par canal - + Difference is computed channel per channel La différence est calculée canal par canal + + + PerLuminanceMetric - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les moyennes des canaux RVB exprimée par moy(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 + + Difference per image luminance + Différence des luminosités - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) La différence est calculée entre les luminosités des images exprimée par Y(x,y) = 0.3*R(x,y)+0.59*V(x,y)+0.11*B(x,y) + + + PerceptualMetric - Difference is computed between both mean value defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les moyennes des canaux RVB exprimée par moy(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 - - - - 2 - - - - - Difference is computed channel by channel - La différence est calculée canal par canal + + Perceptual difference + Différence perceptuelle - - 1 - - + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Une métrique basée sur les perceptions visuelles. Copyright (C) 2006 Yangli Hector Yee - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La différence est calculée entre les constrastes des images exprimée par contrast(x,y) = (R(x,y)+V(x,y)+B(x,y))/3 + + Field of view + Champs de vision - - --help - displays this help. - --help - affiche cette aide.. + + Field of view in degrees (0.1 to 89.9) + Champs de vision en degré (0.1 à 89.9) - - --reset-config - clear the saved preference parameters. - --reset-config - remise à zéro des préférences sauvegardées. + + Gamma of screen + Gamma de l'écran - - You must set valid filename files as arguments in batch mode !! - Vous devez donner des fichiers valides pour le mode batch !! + + Value to convert rgb into linear space (default 2.2) + Valeur de conversion entre l'espace RVB et l'espace linéaire (défaut 2.2) - - Files are different - Les fichiers sont différents + + White luminance + Luminance du blanc - - Error Num (pixels): - Nb erreurs (pixels): + + White luminance (default 100.0 cdm^-2) + Luminance du blanc (défaut 100.0 cdm^-2) - - Mean error: - Erreur moyenne : + + Luminance only + Seulement la luminance - - RMS Error: - Erreur quadratique moyenne : + + Only consider luminance; ignore chroma (color) in the comparison + Prise en compte uniquement de la luminance; les composantes couleurs sont ignorées - - Standard deviation - Déviation standard + + Color factor + Facteur de couleur - - Saving of %1 failed !! - La sauvegarde de %1 à échouée !! + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Facteur de participation de la couleur (0.0-1.0, 0.0 = couleur ignorée) - - Files are identical - Les fichiers sont identiques + + Downsample + Sous-échantillonnage - - You must set two files as arguments in batch mode !! - Vous devez positionner deux fichiers comme argument en mode batch !! + + How many powers of two to down sample the image + Nombre de puissance de deux pour sous échantillonner l'image - Scheduler + PropertyWidget - Start new timer for %1 sec ... - Démarrage d'un nouveau minuteur pour %1 sec ... + + Properties + Propriétés - New Schedule fired ... - Nouvelle programmation démarrée ... + + Statistics + Statistiques - SchedulerConfigWidget - - Scheduling parameters - Paramètres de programmation - - - - Auto change at startup - Changement automatique au démarrage - + QObject - Quit application after startup change (30s) - Quitter l'application après le démarrage (30sec) + + + Image Difference tool. + Outil d'affichage de différence d'images. - Change Interval - Intervale + + Available metrics: + Métriques disponibles : - Interval between change (h:m:s) - Intervale entre les changements + + Input parameters: + ⇥Paramètres d'entrée : - set time of day (h:m:s) - Ajouter un horaire + + Output parameters: + ⇥Paramètres de sortie : - Add to the timeofday list - Ajouter à la liste des horaires + + How to use batch mode: + Comment utiliser le mode batch - Delete selected timeofday - Effacer les horaires sélectionnés + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Exemple 1: --batch --metric PerChannelMeanMetric : Utilisation de la métrique "moyenne des canaux" - - - SyncWall - Can't create storage location, check why ?! (%1) - Impossible de créer le répertoire de stockage, recherchez pourquoi ?! (%1) + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exemple 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Utilisation de la métrique "différence par canal" avec échec de la comparaison si le nombre de différences est supérieur à 250 - Active Desktop must be disabled !! - ActiveDesktop doit être désactivé !! + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exemple 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Utilisation de la métrique "perceptuelle" avec la modification de plusieurs paramètres d'entrée et échec de la comparaison si le nombre de différences est supérieur à 250 - Add Wallpaper Directory - Ajouter un répertoire de fonds d'écran + + Usage: + Usage : - Add all found directories recursively ? - Ajouter tous les répertoires récursivement ? + + [options] + [options] - add %1 folder - ajouter répertoire %1 + + img1 img2 + img1 img2 - Select one or more wallpapers - Sélectionner un ou plusieurs fonds d'écran + + Following options are known: + Les options suivantes sont disponibles : - Images (%1) - Images (%1) + + --list - list all metrics with their parameters. + --list - liste de toutes les métriques avec leurs paramètres. - Systray - Zone de notification + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - mode batch.La comparaison est réalisée en ligne et un code de retour est positionné comme résultat. - The program will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray entry. - Le programme va rester actif dans la zone de notification. Pour sortir définitivement, choisir <b>Quitter</b> dans le menu contextuel de la zone de notification. + + --metric - metric tag name. Display list of metrics with --list option. + --metric - Nom de la métrique. Afficher la liste des métriques avec l'option --list. - &Quit - &Quitter + + --in name=value - input parameter update. + --in nom=valeur - modification paramètre d'entrée "nom". - Change background - Change de fond d'écran + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold nom=valeur - Paramètres de sortie utilisé pour définir le critère de comparaison. Si vous positionnez plusieurs paramètres, seul le dernier est pris en compte. - %1 images in list - %1 images dans la liste + + You must set valid filename files as arguments in batch mode !! + Vous devez donner des fichiers valides pour le mode batch !! - Invalid file ? : %1 - Fichier invalide ? : %1 + + Metric %1 unknown !! + Métrique %1 inconnue !! - - - SyncWallClass - Preview - Prévisualisation + + Metric %1 has no input parameter !! + La métrique %1 n'a pas de paramètre d'entrée !! - Quit - Quitter + + Can't display difference, more information in the log panel ... + Impossible d'afficher la différence, plus d'informations dans le panneau "journal" ... - Add a new folder - Ajouter un nouveau répertoire + + Files are identical + Les fichiers sont identiques - Preview - Prévisualisation + + Files are identical (under the threshold) + Les fichiers sont identiques (sous le critère de comparaison) - Refresh file list - Rafraîchir la liste de fichiers + + Error in options ! + Erreur dans les options ! - Switch file list/provider view - Basculer vue fichiers/fournisseurs + + You must set at least two files as arguments in batch mode !! + Vous devez positionner deux fichiers comme argument en mode batch !! - No Wallpaper - Aucun fond d'écran + + setting language to : %1 + langue positionnée à %1 - Preview selected wallpaper - Prévisualiser le fond d'écran sélectionné + + + successfully loaded data from %1 + chargement réussi de %1 - Auto Change in random order - Changement automatique aléatoire + + failed to load data from %1 + échec au chargement de %1 - Preferences - Préférences + + Bytes + Octets - Startup - Démarrage + + KB + Kilobyte + Ko - Startup - Démarrage + + MB + Megabyte + Mo - Start in notification tray (minimized) - Démarrer dans la zone de notification (minimisé) + + GB + Gigabyte + Go - Display splashscreen at startup - Afficher l'écran d'accueil au démarrage + + TB + Terabyte + To - Auto start with system - Démarrage automatique avec le système + + Pixels + Pixels - Use Global Hotkey for manual change of wallpaper - Utiliser un raccourcis clavier global pour changer + + Kp + Kilopixel + Kp - Hotkey: - Raccourcis : + + Mp + Megapixel + Mp - Scheduling - Programmation + + Gp + Gigapixel + Gp - Display Parameters - Paramètres d'affichage + + Tp + Terapixel + Tp - Network - Réseau + + + + Value: %1 + Valeur: %1 - About - A propos + + + + Value: %1, + Valeur: %1, - Supported formats (via Qt plugins) - Formats supportés (via greffons Qt) + + + + + Alpha: %1 + Transparence: %1 - Available translations - Traductions disponibles + + + Red: %1, + Rouge: %1, - Release Number - Version + + + Green: %1, + Vert: %1, - Log - Journal + + Blue: %1 + Bleu: %1 - Clear Log - Effacer le journal + + Blue: %1, + Bleu: %1, - - - WallpaperProvider - Cannot find the directory - Impossible de trouver le répertoire + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + pas encore implémenté (%1) Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_it.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_it.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_it.ts diffimg-2.0.0/lang/diffimg_it.ts --- diffimg-1.5.0/lang/diffimg_it.ts 2013-02-11 13:10:12.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_it.ts 2013-07-17 17:28:46.000000000 +0000 @@ -4,88 +4,50 @@ - + release of translation and translator name please put your name here dear translator and the release of the translation file !! - Italian translation v1.5.0 by nicola giacobbe + Italian translation v1.5.1 by Man from Mars AboutDialog - The CREDITS file can't be found, sorry ... - Le fichier CREDITS n'a pas été trouvé, désolé ... + + <a href="%1">Check for new release ...</a> + <a href="%1">Controlla aggiornamenti...</a> - The CREDITS.txt file can't be found, sorry ... - Le fichier CREDITS.txt n'a pas été trouvé, désolé ... + + Qt version %1 + Versione Qt %1 - + The %1 file can't be found, sorry ... - There is no equivalent italian expression to having a comma+'sorry' at the end of a text. There is a spoken language version, loosely translated as TEXT+", spiacente..." but it is very difficult to render in written language. So I decided to avoid the problem altogether even if the text isn't a one-to-one translation of the original. - Mi scuso ma il file %1 non e' stato trovato ... + Oops! File %1 non trovato... - + detected language: %1 lingua rilevata: %1 - + Automatic detection Rilevamento automatico - + Default (no use of translation files) Default (file di traduzione non utilizzati) - + The application need to restart in order to take into account new translation , Do you want to restart application now ? - L'applicazione deve essere fatta ripartire per poter completare il cambio di lingua -Desidera far ripartire l'applicazione adesso? - - - - Difference by channel - Differenza canale per canale - - - - Difference by channel mean - "channel mean" is a polysemic term. I have interpreted here as 'the mean of each channel is computed and the difference between each channel mean on the original and varied image is used as a metric' - Differenza per valore medio del canale - - - - Difference by image lightness - Differenza per luminosita' dell'immagine - - - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La differenza e' calcolata tra i valori medi delle immagini, con la media definita come: media(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - - - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - La differenza e' calcolata tra i valori di luminosita' delle immagini, con la luminosita' definita come: luminosita'(x,y) = 0.30*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - - - Difference by constrast - Differenza per contrasto - - - - Difference is computed channel by channel - La differenza viene calcolata canale per canale - - - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La differenza viene calcolata tra i due valori di contrasto, definito come: contrasto(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + L'applicazione deve essere riavviata per completare il cambio di lingua +Riavviare l'applicazione adesso? @@ -97,585 +59,527 @@ About - - Release Number - Versione - - - + Credits - more correct would be 'Crediti' but 'Ringraziamenti' is warmer Ringraziamenti - + Changelog Registro delle modifiche - + + Release Number + Versione + + + Preferences Preferenze - + Language Lingua - + Detected language ... - Lingua trovata ... + Lingua rilevata... - - Mask opacity (0-transparent,100-opaque) - Opacità della maschera (0 - trasparente, 100 - opaca) + + Splashscreen with transparent background + Splash screen con sfondo trasparente - - Error mask opacity (%) - Errore sull'opacità della maschera (in %) + + Display splashscreen at startup + Mostra lo splash screen alla partenza - - Difference method - Metodo usato per calcolare la differenza + + Difference metric used + Metrica di confronto usata - - Threshold in RMS - Soglia in RMS + + Allow image difference + Permetti immagini differenti - - RMS threshold (float): - Soglia in RMS (virgola mobile): + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + Parametro di discriminazione (le immagini sono considerate diverse se viene superata la soglia) - - Allow image difference - Permetti immagini differenti + + Discriminating parameter + Parametro di discriminazione - - Display splashscreen at startup - Mostra lo splash screen alla partenza + + Threshold + Soglia - - Splashscreen with transparent background - Splash screen con sfondo trasparente + + Metric + Metrica - RMS threshold: - Seuil RMS + + Input parameters + Parametri in entrata - Allow pixel difference - Autoriser les pixels différents + + Mask opacity (0-transparent,100-opaque) + Opacità della maschera (0 - trasparente, 100 - opaca) - + + Error mask opacity (%) + Errore sull'opacità della maschera (in %) + + + Infos Informazioni - + Supported formats (via Qt plugins) Formati gestiti (mediante plugin QT) - + Available translations Traduzioni disponibili - + Log Registrazioni - BackgroundPainter - - No Desktop Environment Detected - Aucun environnement détecté - - - load %1 - chargement de %1 - - - Saving temp file (%1) - Sauvegarde du fichier temporaire (%1) - - - Failed to save temp file (%1) - Echec de la sauvegarde du fichier temporaire (%1) - - - - BackgroundPainterConfigWidget - - Image parameters - Parametres d'image - - - Ignore aspect ratio - Ignorer le rapport d'aspect - - - Keep aspect ratio - Conserver le rapport d'aspect - - - Keep aspect ratio by expanding - Conserver le rapport d'aspect par accroissement - - - Center Image - Centrer l'image - - - Linux desktop integration - Intégration au bureau Linux - - - KDE3 desktop - KDE3 - - - GNOME desktop - Gnome - - - KDE4 desktop - KDE4 - + BaseMetric - Xfce Desktop - Xfce + + + + Unknown + Sconosciuto - Fluxbox desktop - Fluxbox + + No description + Nessuna descrizione - Blackbox desktop - Blackbox + + Mean error + Errore medio - WindowMaker desktop - WindowMaker + + Mean absolute error + Errore medio assoluto - FVWM desktop - FVWM - - - - DiffImgWindow - - - - - Image Viewer - Visualizzatore d'immagini + + Min error + Errore minimo - - Cannot display difference, image have different size (%1x%2/%3x%4) - The images have passed from 'having different size' to 'having incompatible dimensions' to avoid citing twice the term 'different' in two different context - Impossibile mostrare le differenze, le immagini hanno dimensioni incompatibili (%1x%2/%3x%4) + + Minimum error + Errore minimo - - - Cannot load %1. - Impossibile caricare %1. + + Max error + Errore massimo - - - DiffImgWindowClass - - diffimg - diffimg + + Maximum error + Errore massimo - - Navigator - Navigatore + + Standard deviation + Deviazione standard - - Original - Originale + + RMS error deviation + Erroe deviazione RMS - - Modified - Modificata + + Root Mean Square error + Errore Root Mean Square - - Difference - Differenze + + Error num (pixels) + Num errore (pixels) - - - Statistics - Statistiche + + Number of different pixels + Numero di pixel differenti - Size: - Taille: + + Error (% pixels) + Errore (% pixel) - - - - - - - - - - - - - - 0 - + + Number of different pixels in % + Numero di pixel differenti in % - Diff Nb: - Nb diff : + + Dimension (pixels) + Dimensione (pixel) - Mean Diff: - Diff moyenne : + + Dimension in pixel of images + Dimensione delle immagini in pixel - RMS Diff: - Diff RMS : + + Size (pixels) + Dimensione (pixel) - Mean pixel diff: - Moyenne des diff : + + Size in pixel of images + Dimensione delle immagini in pixel - - Min error: - Errore min : + + Size file1 + Dimensione file 1 - - Max error: - Errore max : + + + Size in bytes of image + Dimensioni immagine in byte - - Position - Posizione + + + %1/%2 + %1/%2 - - X: - + + Size file2 + DImensione file 2 - - Y: - + + Format file1 + Formato file 1 - - R: - + + + Format of the image + Formato immagine - - Size (pixels): - Dimensione (pixels): + + Format file2 + Formato file 2 - - number of pixel with difference - Numero di pixel differenti + + Band + Banda - Error Nb (pixels): - Nb erreurs (pixels) : + + Number of band in the image (3 for RGB image) + Numero di bande nell'immagine (3 per immagini RGB) - - - Mean error - Errore medio + + Band depth + Profondità di banda - Global mean error: - Erreur moyenne globale : + + Number of bits per band (U:unsigned, S:signed, F:float) + Numero di bit per banda (U:non firmato, S:firmato, F:fluttuante) + + + DiffImgWindow - - - Root Mean Square error - Errore Root Mean Square + + Current metric: %1 + Metrica corrente: %1 - - RMS Error: - Errore RMS: + + Can't display difference, more information in the log panel ... + Impossibile mostrare le differenze: consultare il registro per maggiori informazioni... - Mean of error on pixel with difference - Moyenne des erreurs sur les pixels différents + + + Image Viewer + Visualizzatore d'immagini - - Mean error: - Errore medio: + + + Cannot load %1. + Impossibile caricare %1. - - - Minimal value of error - Errore minimo + + Scale x%1 + Scala x%1 + + + DiffImgWindowClass - - - Maximal value of error - Errore massimo + + diffimg + diffimg - - - Standard deviation of error - Deviazione standard dell'errore + + Main toolbar + Barra degli strumenti principale - - Standard deviation - Deviazione standard + + Navigator + Navigatore - - - Red component - Componente Rossa + + Original + Originale - - Method: - Metodo: + + Modified + Modificata - - - Green component - Componente Verde + + Difference + Differenze - - G: - V: + + Gain + Guadagno - - - Blue component - Componente Blu + + Offset + Offset - - B: - + + + Histogram + Istogramma - - - Zoom factor - Fattore di Zoom + + Statistics + Statistiche - - Zoom: - + + (*) statistics exceeding the authorized threshold + (*) statistiche che eccedono la soglia consentita - + yellow color: pixel with error >mean error In Giallo: pixel con errore > errore medio - <img src=":/diffimg/yellow.png" /> diff pixel > mean diff - <img src=":/diffimg/yellow.png" /> diff > diff moyenne + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> errore &gt; errore medio - + red color: pixel with error <= mean error In Rosso: pixel con errore <= errore medio - <img src=":/diffimg/red.png" /> diff pixel - <img src=":/diffimg/red.png" /> erreur - - - - Error Num (pixels): - Num Errori (pixels): - - - - <img src=":/diffimg/yellow.png" /> error &gt; mean error - <img src=":/diffimg/yellow.png" /> errore &gt; errore medio - - - + <img src=":/diffimg/red.png" /> error <img src=":/diffimg/red.png" /> errore - - - Histogram - Histogramma - - - + Display Original Image Mostra l'immagine originale - + 1 - + 1 - + Display Modified Image Mostra l'immagine modificata - + 2 - + 2 - + Display Difference Image Mostra la differenza tra le immagini - + D - + D - + Quit - Quit + Esci - + Ctrl+Q Ctrl+Q - + Fit to window Adatta alla finestra - + Full resolution Massima risoluzione - + Open Apri - + actionNext - + Seguito - - - + + + Next image Immagine seguente - + N - + N - + Prev Precedente - - - + + + Previous image Immagine precedente - + P - + P - + Difference Image Immagine differenza - + 3 - + 3 - + Dual Panel Doppio pannello - + Ctrl+D - + Ctrl+D - + About About - + Preferences Preferenze - + Refresh Aggiorna lo schermo + + + R + R + + + + Help + Aiuto + + + + Online help + Aiuto online + + + + F1 + F1 + FilesDialog - - + + Open File Apri File @@ -699,389 +603,402 @@ - QObject - - message from other instance. - message d'une autre instance. - - - %1 is already running !! - %1 est déjà en fonctionnement !! - - - - translations path %1 - percorso delle varie traduzioni %1 - - - - setting language to : %1 - linguaggio configurato: %1 - - - - successfully loaded data from %1 - caricamento con successo dei dati da %1 - + PerChannelMeanMetric - - failed to load data from %1 - impossibile caricare i dati da %1 + + Difference per channel mean + Differenza per canale di flusso - - Image Difference tool. - Strumenti per la differenza tra immagini. - - - - Usage: - Utilizzo : - - - - [options] - [opzioni] - - - - img1 img2 - img1 img2 - - - - Following options are known: - Sono disponibili le opzioni seguenti: - - - - --batch - batch mode. Differences are computed without GUI and return code is used as result. - --batch - modalità batch.Le differenze vengono calcolate senza essere mostrate a video, al loro posto viene restituito un codice. - - - - --rms-threshold value - [only for batch mode]. Threshold value for RMS computation. - --rms-threshold value - [solo per la modalita' batch]. Valore di soglia RMS per il confronto (default: 0.0). - - - - --diff-method value - [only for batch mode]. Method used to compute difference. - --diff-method value - [solo per la modalita' batch]. Metodo usato per calcolare le differenze. - - - - --output xx.yy - [only for batch mode]. Save image difference in xx.yy file (only if comparison failed). - --output xx.yy - [solo per la modalita' batch]. Salva le differenze tra le immagini nel file xx.yy (solo se la comparazione fallisce). + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + La differenza e' calcolata tra i valori medi delle immagini, con la media definita come: media(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + + PerChannelMetric - - Available methods: 0 - - Metodi disponibili: 0 - + + Difference per channel + Differenza per canale - + Difference is computed channel per channel La differenza viene calcolata canale per canale + + + PerLuminanceMetric - - Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La differenza e' calcolata tra i valori medi delle immagini, con la media definita come: media(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - - - - Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) - La differenza e' calcolata tra i valori di luminosita' delle immagini, con la luminosita' definita come: luminosita'(x,y) = 0.30*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + Difference per image luminance + Differenza per luminanza dell'immagine - - 2 - - 2 - + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + La differenza è calcolata tra i due valori di luminanza definiti come luminanza(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + + PerceptualMetric - Difference is computed channel by channel - La differenza viene calcolata canale per canale + + Perceptual difference + Differenza percentuale - - 1 - - 1 - + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Una metrica di immagine basata sulla percezione dell'immagine. Copyright (C) 2006 Yangli Hector Yee - Difference is computed between both contrast value defined as contrast(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 - La differenza viene calcolata tra i due valori di contrasto, definiti come: contrasto(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + Field of view + Campo di vista - - --help - displays this help. - --help - mostra queste informazioni. + + Field of view in degrees (0.1 to 89.9) + Campo visivo in gradi (0.1 - 89.9) - - --reset-config - clear the saved preference parameters. - --reset-config - fa il reset dei parametri salvati. + + Gamma of screen + Gamma dello schermo - - You must set valid filename files as arguments in batch mode !! - E' necessario fornire nomi di file validi al programma in modalita' batch!! + + Value to convert rgb into linear space (default 2.2) + Valore per convertire rgb nello spazio lineare (predef. 2.2) - - Files are different - I file sono differenti + + White luminance + Luminanza del bianco - - Error Num (pixels): - Num Errori (pixels): + + White luminance (default 100.0 cdm^-2) + Luminanza del bianco (predefinito 100.0 cdm^-2) - - Mean error: - Errore medio: + + Luminance only + Solo luminanza - - RMS Error: - Errore RMS: + + Only consider luminance; ignore chroma (color) in the comparison + Considera solo la luminanza; ignora chroma (colore) nel confronto - - Standard deviation - Deviazione standard + + Color factor + Fattore colore - - Saving of %1 failed !! - The english form "XXing of YY failed" is very terse. A direct, word-by-word translation could result in poor understanding and lead to confusion. I have converted it in the equivalent of: "It has not been possibile to save the file %1". - Non e' stato possibile salvare il file %1 ! + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Quanto colore usare, 0.0 a 1.0, 0.0 = ignora colore. - - Files are identical - I file sono identici + + Downsample + Decampionamento - - You must set two files as arguments in batch mode !! - E' necessario fornire due file come argomenti al programma in modalità batch !! + + How many powers of two to down sample the image + Quanto devono influire i decampionamenti sull'immagine - Scheduler + PropertyWidget - Start new timer for %1 sec ... - Démarrage d'un nouveau minuteur pour %1 sec ... + + Properties + Proprietà - New Schedule fired ... - Nouvelle programmation démarrée ... + + Statistics + Statistiche - SchedulerConfigWidget - - Scheduling parameters - Paramètres de programmation - - - - Auto change at startup - Changement automatique au démarrage - + QObject - Quit application after startup change (30s) - Quitter l'application après le démarrage (30sec) + + + Image Difference tool. + Strumenti per la differenza tra immagini. - Change Interval - Intervale + + Available metrics: + Metriche disponibili: - Interval between change (h:m:s) - Intervale entre les changements + + Input parameters: + »Parametri in Input: - set time of day (h:m:s) - Ajouter un horaire + + Output parameters: + »Parametri in Output: - Add to the timeofday list - Ajouter à la liste des horaires + + How to use batch mode: + Come usare la modalità automatica: - Delete selected timeofday - Effacer les horaires sélectionnés + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Esempio 1: --batch --metric PerChannelMeanMetric : Uso della metrica principale per canale - - - SyncWall - Can't create storage location, check why ?! (%1) - Impossible de créer le répertoire de stockage, recherchez pourquoi ?! (%1) + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Esempio 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Uso della metrica per canale ed uscita con errore se il numero dei pixel con differenze è superiore a 250 - Active Desktop must be disabled !! - ActiveDesktop doit être désactivé !! + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Esempio 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Uso della metrica percantuale con alcuni parametri di input impostati ed uscita con errore se il numero dei pixel con differenze è superiore a 250 - Add Wallpaper Directory - Ajouter un répertoire de fonds d'écran + + Usage: + Utilizzo : - Add all found directories recursively ? - Ajouter tous les répertoires récursivement ? + + [options] + [opzioni] - add %1 folder - ajouter répertoire %1 + + img1 img2 + img1 img2 - Select one or more wallpapers - Sélectionner un ou plusieurs fonds d'écran + + Following options are known: + Sono disponibili le opzioni seguenti: - Images (%1) - Images (%1) + + --list - list all metrics with their parameters. + --list - elenca tutte le metriche con i loro parametri. - Systray - Zone de notification + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - modalità batch.Le differenze vengono calcolate senza essere mostrate a video, al loro posto viene restituito un codice. - The program will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray entry. - Le programme va rester actif dans la zone de notification. Pour sortir définitivement, choisir <b>Quitter</b> dans le menu contextuel de la zone de notification. + + --metric - metric tag name. Display list of metrics with --list option. + --metric - metric tag name. Elenca le metriche con l'opzione --list. - &Quit - &Quitter + + --in name=value - input parameter update. + --in name=value - aggiorna i parametri di input. - Change background - Change de fond d'écran + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold name=value - parametro in uscita usato per definire il confronto in modalità automatica. Se impostate più parametri di soglia, verrà mantenuto solo l'ultimo. - %1 images in list - %1 images dans la liste + + You must set valid filename files as arguments in batch mode !! + È necessario fornire nomi di file validi al programma in modalità batch!! - Invalid file ? : %1 - Fichier invalide ? : %1 + + Metric %1 unknown !! + Metrica %1 sconosciuta !! - - - SyncWallClass - Preview - Prévisualisation + + Metric %1 has no input parameter !! + La metrica %1 non ha parametri di input !! - Quit - Quitter + + Can't display difference, more information in the log panel ... + Impossibile visualizzare la differenza, maggiori informazioni nel pannello di log ... - Add a new folder - Ajouter un nouveau répertoire + + Files are identical + I file sono identici - Preview - Prévisualisation + + Files are identical (under the threshold) + I file sono identici (sotto la soglia) - Refresh file list - Rafraîchir la liste de fichiers + + Error in options ! + Errore nelle opzioni ! - Switch file list/provider view - Basculer vue fichiers/fournisseurs + + You must set at least two files as arguments in batch mode !! + Dovete impostare almeno due file come argomenti in modalità automatica !! - No Wallpaper - Aucun fond d'écran + + setting language to : %1 + linguaggio configurato: %1 - Preview selected wallpaper - Prévisualiser le fond d'écran sélectionné + + + successfully loaded data from %1 + caricamento con successo dei dati da %1 - Auto Change in random order - Changement automatique aléatoire + + failed to load data from %1 + impossibile caricare i dati da %1 - Preferences - Préférences + + Bytes + Byte - Startup - Démarrage + + KB + Kilobyte + KB - Startup - Démarrage + + MB + Megabyte + MB - Start in notification tray (minimized) - Démarrer dans la zone de notification (minimisé) + + GB + Gigabyte + GB - Display splashscreen at startup - Afficher l'écran d'accueil au démarrage + + TB + Terabyte + TB - Auto start with system - Démarrage automatique avec le système + + Pixels + Pixel - Use Global Hotkey for manual change of wallpaper - Utiliser un raccourcis clavier global pour changer + + Kp + Kilopixel + Kp - Hotkey: - Raccourcis : + + Mp + Megapixel + Mp - Scheduling - Programmation + + Gp + Gigapixel + Gp - Display Parameters - Paramètres d'affichage + + Tp + Terapixel + Tp - Network - Réseau + + + + Value: %1 + Valore: %1 - About - A propos + + + + Value: %1, + Valore: %1, - Supported formats (via Qt plugins) - Formats supportés (via greffons Qt) + + + + + Alpha: %1 + Alpha: %1 - Available translations - Traductions disponibles + + + Red: %1, + Rosso: %1, - Release Number - Version + + + Green: %1, + Verde: %1, - Log - Journal + + Blue: %1 + Blu: %1 - Clear Log - Effacer le journal + + Blue: %1, + Blu: %1, - - - WallpaperProvider - Cannot find the directory - Impossible de trouver le répertoire + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + non ancora implementato (%1) Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_pt.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_pt.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_pt.ts diffimg-2.0.0/lang/diffimg_pt.ts --- diffimg-1.5.0/lang/diffimg_pt.ts 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_pt.ts 2013-07-17 17:28:48.000000000 +0000 @@ -0,0 +1,1004 @@ + + + + + + + + release of translation and translator name please + put your name here dear translator and the release of the translation file !! + Tradução para Português (Brasil) da versão 1.5.0 por Rafael Ferreira + + + + AboutDialog + + + <a href="%1">Check for new release ...</a> + <a href="%1">Verificar nova versão ...</a> + + + + Qt version %1 + Qt versão %1 + + + + The %1 file can't be found, sorry ... + O arquivo %1 não pôde ser encontrado, sinto muito ... + + + + detected language: %1 + detectado idioma: %1 + + + + Automatic detection + Detecção automática + + + + Default (no use of translation files) + Padrão (sem uso dos arquivos de tradução) + + + + The application need to restart in order to take into account new translation +, Do you want to restart application now ? + O aplicativo precisa ser reinicializado para aplicar a nova tradução. +Você deseja reinicializá-lo agora? + + + + AboutDialogClass + + + + About + Sobre + + + + Credits + Créditos + + + + Changelog + Changelog + + + + Release Number + Número do lançamento + + + + Preferences + Preferências + + + + Language + Idioma + + + + Detected language ... + Idioma detectado ... + + + + Splashscreen with transparent background + Tela de inicialização com fundo transparente + + + + Display splashscreen at startup + Exibir a tela de inicializar + + + + Difference metric used + Métrica de diferenciação usada + + + + Allow image difference + Permitir diferenciação de imagens + + + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + Parâmetro de discriminação (imagens são consideradas como diferentes, se o limite for excedido) + + + + Discriminating parameter + Parâmetro de discriminação + + + + Threshold + Limite + + + + Metric + Métrica + + + + Input parameters + Parâmetros de entrada + + + + Mask opacity (0-transparent,100-opaque) + Máscara de opacidade (0-transparente, 100-opaco) + + + + Error mask opacity (%) + Erro na máscara de opacidade (%) + + + + Infos + Infos + + + + Supported formats (via Qt plugins) + Formatos suportados (via plug-ins do Qt) + + + + Available translations + Traduções disponíveis + + + + Log + Log + + + + BaseMetric + + + + + Unknown + Desconhecido + + + + No description + Nenhuma descrição + + + + Mean error + Erro médio + + + + Mean absolute error + Erro médio absoluto + + + + Min error + Erro mín + + + + Minimum error + Erro mínimo + + + + Max error + Erro máx + + + + Maximum error + Erro máximo + + + + Standard deviation + Desvio padrão + + + + RMS error deviation + Desvio de erro RMS + + + + Root Mean Square error + Erro de valor quadrático médio (RMS) + + + + Error num (pixels) + Número erro (pixels) + + + + Number of different pixels + Número de pixels diferentes + + + + Error (% pixels) + Erro (% pixels) + + + + Number of different pixels in % + Número de pixels diferentes em % + + + + Dimension (pixels) + Dimensão (pixels) + + + + Dimension in pixel of images + Dimensão das imagens, em pixels + + + + Size (pixels) + Tamanho (pixels) + + + + Size in pixel of images + Tamanho das imagens, em pixel + + + + Size file1 + Tamanho arquivo1 + + + + + Size in bytes of image + Tamanho da imagem, em bytes + + + + + %1/%2 + %1/%2 + + + + Size file2 + Tamanho arquivo2 + + + + Format file1 + Formato arquivo1 + + + + + Format of the image + Formato da imagem + + + + Format file2 + Formato arquivo2 + + + + Band + Faixa + + + + Number of band in the image (3 for RGB image) + Número da faixa da imagem (3 para imagem RGB) + + + + Band depth + Profundidade da faixa + + + + Number of bits per band (U:unsigned, S:signed, F:float) + Número de bits por faixa (U:não-assinado, S:assinado, F:flutuante) + + + + DiffImgWindow + + + Current metric: %1 + Métrica atual: %1 + + + + Can't display difference, more information in the log panel ... + Não foi possível exibir diferença, mais informação no painel de log ... + + + + + Image Viewer + Visualizador de imagens + + + + + Cannot load %1. + Não foi possível carregar %1. + + + + Scale x%1 + Escala x%1 + + + + DiffImgWindowClass + + + diffimg + diffimg + + + + Main toolbar + Barra de ferramentas principal + + + + Navigator + Navegação + + + + Original + Original + + + + Modified + Modificado + + + + Difference + Diferença + + + + Gain + Ganho + + + + Offset + Deslocamento + + + + + Histogram + Histograma + + + + Statistics + Estatísticas + + + + (*) statistics exceeding the authorized threshold + (*) estatísticas excedendo o limite autorizado + + + + yellow color: pixel with error >mean error + cor amarela: pixel com erro > erro médio + + + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> erro &gt; erro médio + + + + red color: pixel with error <= mean error + cor vermelha: pixel com erro <= erro médio + + + + <img src=":/diffimg/red.png" /> error + <img src=":/diffimg/red.png" /> erro + + + + Display Original Image + Exibir imagem original + + + + 1 + 1 + + + + Display Modified Image + Exibir imagem modificada + + + + 2 + 2 + + + + Display Difference Image + Exibir imagem da diferença + + + + D + D + + + + Quit + Sair + + + + Ctrl+Q + Ctrl+Q + + + + Fit to window + Ajustar à janela + + + + Full resolution + Resolução completa + + + + Open + Abrir + + + + actionNext + actionNext + + + + + + Next image + Próxima imagem + + + + N + N + + + + Prev + Prev + + + + + + Previous image + Imagem anterior + + + + P + P + + + + Difference Image + Imagem anterior + + + + 3 + 3 + + + + Dual Panel + Painel duplo + + + + Ctrl+D + Ctrl+D + + + + About + Sobre + + + + Preferences + Preferências + + + + Refresh + Renovar + + + + R + R + + + + Help + Ajuda + + + + Online help + Ajuda online + + + + F1 + F1 + + + + FilesDialog + + + + Open File + Abrir arquivo + + + + FilesDialogClass + + + Dialog + Diálogo + + + + Base Image File + Arquivo de imagem base + + + + Image to compare + Imagem para comparar + + + + PerChannelMeanMetric + + + Difference per channel mean + Diferença por média de canal + + + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + Diferença é computada entre ambos valores médios definidos como mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + + + PerChannelMetric + + + Difference per channel + Diferença por canal + + + + Difference is computed channel per channel + Diferença é computada canal por canal + + + + PerLuminanceMetric + + + Difference per image luminance + Diferença por iluminação da imagem + + + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + Diferença é computada entre ambos valores de iluminação definido como luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + + + PerceptualMetric + + + Perceptual difference + Diferença perceptível + + + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Um métrica de imagem baseada na percepção. Copyright (C) 2006 Yangli Hector Yee + + + + Field of view + Campo de visão + + + + Field of view in degrees (0.1 to 89.9) + Campo de visão em graus (0.1 to 89.9) + + + + Gamma of screen + Gama da tela + + + + Value to convert rgb into linear space (default 2.2) + Valor para converter rgb em espaço linear (padrão 2.2) + + + + White luminance + Iluminação branca + + + + White luminance (default 100.0 cdm^-2) + Iluminação branca (padrão 100.0 cdm^-2) + + + + Luminance only + Apenas iluminação + + + + Only consider luminance; ignore chroma (color) in the comparison + Considera apenas iluminação; ignora chroma (cor) na comparação + + + + Color factor + Fator da cor + + + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Quanto da cor a ser usada, 0.0 a 1.0, 0.0 = ignorar cor. + + + + Downsample + Redução da resolução + + + + How many powers of two to down sample the image + Em quantos exponenciais de dois deve-se reduzir a resolução da imagem + + + + PropertyWidget + + + Properties + Propriedades + + + + Statistics + Estatísticas + + + + QObject + + + + Image Difference tool. + Ferramenta para diferenciação de imagens. + + + + Available metrics: + Métricas disponíveis: + + + + Input parameters: + Parâmetros de entrada: + + + + Output parameters: + Parâmetros de saída: + + + + How to use batch mode: + Como usar o modo em lote: + + + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Exemplo 1: --batch --metric PerChannelMeanMetric : Uso de métrica média por canal + + + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exemplo 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Uso de métrica média por canal e sai com erro se pixel com número de diferença estiver acima de 250 + + + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exemplo 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Usa uma métrica perceptível com alguns parâmetros de entrada definidos e sai com erro se pixel com número de diferença estiver acima de 250 + + + + Usage: + Uso: + + + + [options] + [opções] + + + + img1 img2 + img1 img2 + + + + Following options are known: + As seguintes opções são conhecidas: + + + + --list - list all metrics with their parameters. + --list - lista todas as métricas com seus parâmetros. + + + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - modo batch. Diferenças são computadas sem a interface gráfica e códigos de retorno são usados como resultados. + + + + --metric - metric tag name. Display list of metrics with --list option. + --metric - nome da tag de métrica. Exibe uma lista de métricas com a opção --list. + + + + --in name=value - input parameter update. + --in nome=valor - atualiza parâmetro de entrada. + + + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold nome=valor - retorna parâmetro usado para definir um modo de comparação em lote. Se você definir vários parâmetros de limite, apenas o último será mantido. + + + + You must set valid filename files as arguments in batch mode !! + Você deve definir nomes de arquivos válidos como argumentos no modo batch !! + + + + Metric %1 unknown !! + Métrica %1 desconhecida !! + + + + Metric %1 has no input parameter !! + Métrica %1 não possui parâmetro de entrada !! + + + + Can't display difference, more information in the log panel ... + Não foi possível exibir a diferença, mais informações no painel de log ... + + + + Files are identical + Arquivos são idênticos + + + + Files are identical (under the threshold) + Arquivos são idênticos (abaixo do limite) + + + + Error in options ! + Erro nas opções ! + + + + You must set at least two files as arguments in batch mode !! + Você deve definir pelo menos dois arquivos como argumentos no modo em lote !! + + + + setting language to : %1 + definindo idioma para : %1 + + + + + successfully loaded data from %1 + dados carregados com sucesso de %1 + + + + failed to load data from %1 + falha ao carregar dados de %1 + + + + Bytes + Bytes + + + + KB + Kilobyte + KB + + + + MB + Megabyte + MB + + + + GB + Gigabyte + GB + + + + TB + Terabyte + TB + + + + Pixels + Pixels + + + + Kp + Kilopixel + Kp + + + + Mp + Megapixel + Mp + + + + Gp + Gigapixel + Gp + + + + Tp + Terapixel + Tp + + + + + + Value: %1 + Valor: %1 + + + + + + Value: %1, + Valor: %1, + + + + + + + Alpha: %1 + Alfa: %1 + + + + + Red: %1, + Vermelho: %1, + + + + + Green: %1, + Verde: %1, + + + + Blue: %1 + Azul: %1 + + + + Blue: %1, + Azul: %1, + + + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + não implementado ainda (%1) + + + Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_sv.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_sv.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_sv.ts diffimg-2.0.0/lang/diffimg_sv.ts --- diffimg-1.5.0/lang/diffimg_sv.ts 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_sv.ts 2013-07-17 17:28:48.000000000 +0000 @@ -0,0 +1,1004 @@ + + + + + + + + release of translation and translator name please + put your name here dear translator and the release of the translation file !! + Ã…ke Engelbrektson, http://svenskasprakfiler.se, diffimg_sv_v2.0b + + + + AboutDialog + + + <a href="%1">Check for new release ...</a> + <a href="%1">Sök efter uppdateringar...</a> + + + + Qt version %1 + Qt version %1 + + + + The %1 file can't be found, sorry ... + Filen %1 kan inte hittas... + + + + detected language: %1 + Lokalt sprÃ¥k: %1 + + + + Automatic detection + Automatiskt + + + + Default (no use of translation files) + Standard (använd ingen sprÃ¥kfil) + + + + The application need to restart in order to take into account new translation +, Do you want to restart application now ? + Programmet mÃ¥ste startas om för att verkställa sprÃ¥kändringen. +Vill du starta om programmet nu? + + + + AboutDialogClass + + + + About + Om + + + + Credits + Tack + + + + Changelog + Ändringslogg + + + + Release Number + Utgivningsnummer + + + + Preferences + Inställningar + + + + Language + SprÃ¥k + + + + Detected language ... + Lokalt sprÃ¥k... + + + + Splashscreen with transparent background + Startskärm med transparent bakgrund + + + + Display splashscreen at startup + Visa startskärm vid uppstart + + + + Difference metric used + DifferensmÃ¥tt + + + + Allow image difference + TillÃ¥t feltolerans + + + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + Feltolerans (Bilder betraktas som olika om värdet överskrids) + + + + Discriminating parameter + Feltolerans + + + + Threshold + Tröskelvärde + + + + Metric + MÃ¥tt + + + + Input parameters + Indataparameter + + + + Mask opacity (0-transparent,100-opaque) + Maskopacitet (0=transparent, 100=opak) + + + + Error mask opacity (%) + Differensmaskens opacitet (%) + + + + Infos + Info + + + + Supported formats (via Qt plugins) + Formatstöd (via Qt-tillägg) + + + + Available translations + Tillgängliga översättningar + + + + Log + Logg + + + + BaseMetric + + + + + Unknown + Okänd + + + + No description + Ingen beskrivning + + + + Mean error + Medel + + + + Mean absolute error + Medelvärdet för absoluta avvikelser (MAE) + + + + Min error + Min + + + + Minimum error + Minsta avvikelse (MMSE) + + + + Max error + Max + + + + Maximum error + Maximal avvikelse + + + + Standard deviation + Standardavvikelse + + + + RMS error deviation + RMS-avvikelse + + + + Root Mean Square error + Medelvärdet för standardavvikelsen (Root Mean Square) + + + + Error num (pixels) + Antal avvikelser (pixel) + + + + Number of different pixels + Antalet avvikande pixlar + + + + Error (% pixels) + Fel (% pixel) + + + + Number of different pixels in % + Antal avvikande pixlar i % + + + + Dimension (pixels) + Dimension (pixel) + + + + Dimension in pixel of images + Bilddimension i pixlar + + + + Size (pixels) + Storlek (pixel) + + + + Size in pixel of images + Bildstorlek i pixlar + + + + Size file1 + Filstorlek1 + + + + + Size in bytes of image + Bildstorlek i byte + + + + + %1/%2 + %1/%2 + + + + Size file2 + Filstorlek2 + + + + Format file1 + Filformat1 + + + + + Format of the image + Bildfilformat + + + + Format file2 + Filformat2 + + + + Band + Band + + + + Number of band in the image (3 for RGB image) + Antal band i bilden (3 för RGB-bild) + + + + Band depth + Banddjup + + + + Number of bits per band (U:unsigned, S:signed, F:float) + Antal bitar (bits) per band (U:osignerat, S:signerat, F:flyter) + + + + DiffImgWindow + + + Current metric: %1 + Aktuellt mÃ¥tt: %1 + + + + Can't display difference, more information in the log panel ... + Kan inte visa differens, mer information finns i loggen... + + + + + Image Viewer + Bildvisare + + + + + Cannot load %1. + Kan inte läsa in %1. + + + + Scale x%1 + Skala x%1 + + + + DiffImgWindowClass + + + diffimg + diffimg + + + + Main toolbar + Verktygsfält + + + + Navigator + Navigator + + + + Original + Original + + + + Modified + Ändrad + + + + Difference + Differens + + + + Gain + Gain + + + + Offset + Offset + + + + + Histogram + Histogram + + + + Statistics + Statistik + + + + (*) statistics exceeding the authorized threshold + (*) statistiken överskrider det fastställda tröskelvärdet + + + + yellow color: pixel with error >mean error + Gul färg: Avvikande pixel > Medelavvikelse + + + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> Fel &gt; Medelavvikelse + + + + red color: pixel with error <= mean error + Röd färg: Avvikande pixel <= mean error + + + + <img src=":/diffimg/red.png" /> error + <img src=":/diffimg/red.png" /> Fel + + + + Display Original Image + Visa originalbild + + + + 1 + 1 + + + + Display Modified Image + Visa ändrad bild + + + + 2 + 2 + + + + Display Difference Image + Visa differentierad bild + + + + D + D + + + + Quit + Avsluta + + + + Ctrl+Q + Ctrl+Q + + + + Fit to window + Anpassa + + + + Full resolution + Ursprunglig storlek + + + + Open + Öppna + + + + actionNext + Nästa + + + + + + Next image + Nästa bild + + + + N + N + + + + Prev + Föreg. + + + + + + Previous image + FöregÃ¥ende bild + + + + P + P + + + + Difference Image + Differentierad bild + + + + 3 + 3 + + + + Dual Panel + Dubbelpanel + + + + Ctrl+D + Ctrl+D + + + + About + Om + + + + Preferences + Inställningar + + + + Refresh + Uppdatera + + + + R + R + + + + Help + Hjälp + + + + Online help + Online-hjälp + + + + F1 + F1 + + + + FilesDialog + + + + Open File + Öppna fil + + + + FilesDialogClass + + + Dialog + Öppna filer + + + + Base Image File + Primär bildfil + + + + Image to compare + Bild att jämföra + + + + PerChannelMeanMetric + + + Difference per channel mean + Differens per kanal-medelvärde + + + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + Differensen utarbetas genom medelvärden definierade som medel (x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + + + PerChannelMetric + + + Difference per channel + Differens per kanal + + + + Difference is computed channel per channel + Differensen utarbetas kanal för kanal + + + + PerLuminanceMetric + + + Difference per image luminance + Differens genom bildluminans + + + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + Differensen utarbetas genom jämförelse av luminansvärden definierade som luminans (x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + + + PerceptualMetric + + + Perceptual difference + Perceptuell differens + + + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Ett perceptuellt baserat bildmÃ¥tt. Copyright (C) 2006 Yangli Hector Yee + + + + Field of view + Synfält + + + + Field of view in degrees (0.1 to 89.9) + Synfält i grader (0.1 till 89.9) + + + + Gamma of screen + Gamma + + + + Value to convert rgb into linear space (default 2.2) + Värde för att konvertera RGB till linjärt utrymme (standardvärde 2.2) + + + + White luminance + Vit luminans + + + + White luminance (default 100.0 cdm^-2) + Vit luminans (standard 100.0 cdm^-2) + + + + Luminance only + Endast luminans + + + + Only consider luminance; ignore chroma (color) in the comparison + Jämför endast luminans. Undantar chroma (färg) i jämförelsen. + + + + Color factor + Färgfaktor + + + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Hur mycket färg som används, 0.0 till 1.0 (0.0=undanta färg). + + + + Downsample + Nedsampling + + + + How many powers of two to down sample the image + Värde för att skala ner bilden + + + + PropertyWidget + + + Properties + Egenskaper + + + + Statistics + Statistik + + + + QObject + + + + Image Difference tool. + Bildjämförelseverktyg + + + + Available metrics: + Tillgängliga mÃ¥tt: + + + + Input parameters: + Indataparametrar: + + + + Output parameters: + Utdataparametrar: + + + + How to use batch mode: + Hur batch-läget används: + + + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Exempel 1: --batch --metric PerChannelMeanMetric : Använder genomsnittliga mÃ¥tt per kanal + + + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exempel 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Använder genomsnittliga mÃ¥tt per kanal och avslutas med med fel om pixeldifferensen är större än 250 + + + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Exempel 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Använder perceptuella mÃ¥tt med definierade indataparametrar och avslutas med fel om pixeldifferensen är större än 250 + + + + Usage: + Användning: + + + + [options] + [alternativ] + + + + img1 img2 + img1 img2 + + + + Following options are known: + Följande alternativ är kända: + + + + --list - list all metrics with their parameters. + --list - Listar alla mÃ¥tt med parametrar. + + + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - Batch-läge. Differenser bearbetas utan användargränssnitt och returnerad kod används som resultat. + + + + --metric - metric tag name. Display list of metrics with --list option. + --metric - MÃ¥tt-taggnamn. Visar lista över mÃ¥tt med --listalternativ. + + + + --in name=value - input parameter update. + --in name=value - Uppdatering av indataparametrar. + + + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold name=value - Utdataparameter som används för att definiera jämförelse i batch-läge. Om du anger flera tröskelvärdeparametrar, kommer endast det sista att behÃ¥llas. + + + + You must set valid filename files as arguments in batch mode !! + Du mÃ¥ste ange giltiga filnamn som argument i batch-läge! + + + + Metric %1 unknown !! + %1 okänt mÃ¥tt! + + + + Metric %1 has no input parameter !! + %1 har ingen indataparameter! + + + + Can't display difference, more information in the log panel ... + Kan inte visa differens, mer information i loggen... + + + + Files are identical + Filerna är identiska + + + + Files are identical (under the threshold) + Filerna är identiska (under tröskelvärdet) + + + + Error in options ! + Fel i alternativen! + + + + You must set at least two files as arguments in batch mode !! + Du mÃ¥ste ange minst tvÃ¥ filer som argument i batch-läge! + + + + setting language to : %1 + Anger användarsprÃ¥ket till : %1 + + + + + successfully loaded data from %1 + Läste in data frÃ¥n %1 + + + + failed to load data from %1 + Kunde inte läsa in data frÃ¥n %1 + + + + Bytes + Byte + + + + KB + Kilobyte + KB + + + + MB + Megabyte + MB + + + + GB + Gigabyte + GB + + + + TB + Terabyte + TB + + + + Pixels + Pixel + + + + Kp + Kilopixel + Kp + + + + Mp + Megapixel + Mp + + + + Gp + Gigapixel + Gp + + + + Tp + Terapixel + Tp + + + + + + Value: %1 + Värde: %1 + + + + + + Value: %1, + Värde: %1, + + + + + + + Alpha: %1 + Alfa: %1 + + + + + Red: %1, + Röd: %1, + + + + + Green: %1, + Grön: %1, + + + + Blue: %1 + BlÃ¥: %1 + + + + Blue: %1, + BlÃ¥: %1, + + + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + Ej implementerad (%1) + + + Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/diffimg_vi.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/diffimg_vi.qm differ diff -Nru diffimg-1.5.0/lang/diffimg_vi.ts diffimg-2.0.0/lang/diffimg_vi.ts --- diffimg-1.5.0/lang/diffimg_vi.ts 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/lang/diffimg_vi.ts 2013-07-17 17:28:48.000000000 +0000 @@ -0,0 +1,1004 @@ + + + + + + + + release of translation and translator name please + put your name here dear translator and the release of the translation file !! + tên phiên bản dịch thuật và ngÆ°á»i dịch + + + + AboutDialog + + + <a href="%1">Check for new release ...</a> + <a href="%1">Kiểm tra phiên bản má»›i ...</a> + + + + Qt version %1 + Phiên bản Qt %1 + + + + The %1 file can't be found, sorry ... + Không tìm thấy tập tin %1, rất tiếc... + + + + detected language: %1 + đã phát hiện ngôn ngữ:%1 + + + + Automatic detection + Tá»± Ä‘á»™ng phát hiện + + + + Default (no use of translation files) + Mặc định (không sá»­ dụng tập tin chuyển ngữ) + + + + The application need to restart in order to take into account new translation +, Do you want to restart application now ? + Ứng dụng cần được khởi Ä‘á»™ng lại để có thể áp dụng thay đổi phiên bản ngôn ngữ +, Bạn có muốn khởi Ä‘á»™ng lại chÆ°Æ¡ng trình không? + + + + AboutDialogClass + + + + About + Dịch bởi Phan Anh + + + + Credits + Thá»±c hiện bởi + + + + Changelog + Nhật trình thay đổi + + + + Release Number + Số hiệu phiên bản + + + + Preferences + Tùy biến + + + + Language + Ngôn ngữ + + + + Detected language ... + Äã phát hiện ngôn ngữ... + + + + Splashscreen with transparent background + Màn hình giá»›i thiệu vá»›i hiệu ứng ná»n trong suốt + + + + Display splashscreen at startup + Hiển thị màn hình giá»›i thiệu khi khởi Ä‘á»™ng chÆ°Æ¡ng trình + + + + Difference metric used + Äã sá»­ dụng hệ Ä‘iểm khác nhau + + + + Allow image difference + Cho phép các hình ảnh khác nhau + + + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + Thông số sai biệt (hình ảnh được xem là khác nhau nếu đạt đến ngưỡng này) + + + + Discriminating parameter + Thông số sai biệt + + + + Threshold + Ngưỡng + + + + Metric + Metric + + + + Input parameters + Thông số đầu vào + + + + Mask opacity (0-transparent,100-opaque) + Äá»™ má» của mặt nạ (0-trong suốt, 100-hiện toàn bá»™) + + + + Error mask opacity (%) + Lá»—i vá» giá trị mặt nạ (%) + + + + Infos + Thông tin + + + + Supported formats (via Qt plugins) + Äịnh dạng được há»— trợ (thông qua tiện ích Qt) + + + + Available translations + Các phần chuyển ngữ hiện có + + + + Log + Nhật trình hệ thống + + + + BaseMetric + + + + + Unknown + ChÆ°a rõ + + + + No description + Không có mô tả + + + + Mean error + à nghÄ©a ná»™i dung lá»—i + + + + Mean absolute error + Có nghÄ©a hoàn toàn lá»—i + + + + Min error + Lá»—i nhá» nhất + + + + Minimum error + Lá»—i nhá» nhất + + + + Max error + Lá»—i lá»›n nhất + + + + Maximum error + Lá»—i lá»›n nhất + + + + Standard deviation + Äá»™ lệch chuẩn + + + + RMS error deviation + Äá»™ lệch lá»—i RMS + + + + Root Mean Square error + Lá»—i Giá Trị Hiệu Dụng + + + + Error num (pixels) + Số (Ä‘iểm ảnh) lá»—i + + + + Number of different pixels + Số Ä‘iểm ảnh khác nhau + + + + Error (% pixels) + Lá»—i (% p Ä‘iểm ảnh) + + + + Number of different pixels in % + Số Ä‘iểm ảnh khác nhau trong % + + + + Dimension (pixels) + Chiá»u (Ä‘iểm ảnh) + + + + Dimension in pixel of images + Chiá»u trong Ä‘iểm ảnh của hình + + + + Size (pixels) + Kích thÆ°á»›c (Ä‘iểm ảnh) + + + + Size in pixel of images + Kích thÆ°á»›c bằng giá trị Ä‘iểm ảnh của hình ảnh + + + + Size file1 + Kích thÆ°á»›c tập tin 1 + + + + + Size in bytes of image + Kích thÆ°á»›c tính bằng Ä‘Æ¡n vị byte của hình ảnh + + + + + %1/%2 + %1/%2 + + + + Size file2 + Kích thÆ°á»›c tập tin2 + + + + Format file1 + Äịnh dạng tập tin1 + + + + + Format of the image + Äịnh dạng hình ảnh + + + + Format file2 + Äịnh dạng tập tin2 + + + + Band + Nhóm + + + + Number of band in the image (3 for RGB image) + Số lượng nhóm trong hình ảnh (3 vá»›i hình ảnh RGB) + + + + Band depth + Äá»™ sâu nhóm + + + + Number of bits per band (U:unsigned, S:signed, F:float) + Số lượng bit má»—i nhóm (U:chÆ°a gán, S:đã được gán, F:phẳng) + + + + DiffImgWindow + + + Current metric: %1 + Metric hiện tại: %1 + + + + Can't display difference, more information in the log panel ... + Không thể hiển thị sá»± khác biệt, Ä‘á»c thêm thông tin ở khung Ä‘iá»u khiển nhật trình... + + + + + Image Viewer + Xem hình ảnh + + + + + Cannot load %1. + Không thể tải %1. + + + + Scale x%1 + Tỉ lệ x%1 + + + + DiffImgWindowClass + + + diffimg + hình ảnh khác nhau + + + + Main toolbar + Thanh công cụ chính + + + + Navigator + Äiá»u hÆ°á»›ng + + + + Original + Nguyên gốc + + + + Modified + Äã chỉnh sá»­a + + + + Difference + Äiểm khác nhau + + + + Gain + Tăng + + + + Offset + Offset + + + + + Histogram + Biểu đồ tần suất + + + + Statistics + Thống kê + + + + (*) statistics exceeding the authorized threshold + (*) thống kê vượt ngưỡng cho phép + + + + yellow color: pixel with error >mean error + màu vàng: Ä‘iểm ảnh vá»›i lá»—i > biểu thị trạng thái lá»—i + + + + <img src=":/diffimg/yellow.png" /> error &gt; mean error + <img src=":/diffimg/yellow.png" /> error &gt; biểu thị trạng thái lá»—i + + + + red color: pixel with error <= mean error + màu Ä‘á»: Ä‘iểm ảnh vá»›i lá»—i <= biểu thị trạng thái lá»—i + + + + <img src=":/diffimg/red.png" /> error + <img src=":/diffimg/red.png" /> lá»—i + + + + Display Original Image + Hiển thị hình ảnh gốc + + + + 1 + 1 + + + + Display Modified Image + Hiển thị hình ảnh đã chỉnh sá»­a + + + + 2 + 2 + + + + Display Difference Image + Hiển thị hình ảnh khác biệt + + + + D + D + + + + Quit + Thoát + + + + Ctrl+Q + Ctrl+Q + + + + Fit to window + Vừa vặn trong cá»­a sổ + + + + Full resolution + Äá»™ phân giải tối Ä‘a + + + + Open + Mở + + + + actionNext + thao tác tiếp theo + + + + + + Next image + Hình ảnh kế tiếp + + + + N + N + + + + Prev + TrÆ°á»›c đó + + + + + + Previous image + Hình ảnh trÆ°á»›c đó + + + + P + P + + + + Difference Image + Hình ảnh vá» sá»± khác biệt + + + + 3 + 3 + + + + Dual Panel + Cả hai khung + + + + Ctrl+D + Ctrl+D + + + + About + Dịch bởi Phan Anh + + + + Preferences + Tùy biến + + + + Refresh + Cập nhật lại + + + + R + R + + + + Help + Trợ giúp + + + + Online help + Trợ giúp trá»±c tuyến + + + + F1 + F1 + + + + FilesDialog + + + + Open File + Mở tập tin + + + + FilesDialogClass + + + Dialog + Há»™p thoại + + + + Base Image File + Dá»±a trên tập tin hình ảnh + + + + Image to compare + Hình ảnh để so sánh + + + + PerChannelMeanMetric + + + Difference per channel mean + Sá»± khác biệt cho từng kênh có nghÄ©a + + + + Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + Sá»± khác biệt được tính toán giữa các giá trị được xác định dÆ°á»›i dạng(x,y) = (R(x,y)+G(x,y)+B(x,y))/3 + + + + PerChannelMetric + + + Difference per channel + Sá»± khác biệt má»—i kênh + + + + Difference is computed channel per channel + Sá»± khác biệt được tính toán má»—i từng kênh + + + + PerLuminanceMetric + + + Difference per image luminance + Sá»± khác biệt má»—i Ä‘á»™ chói của hình ảnh + + + + Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + Sá»± khác biệt được tính toán tất cả các giá trị Ä‘á»™ chói dÆ°á»›i dạng Ä‘á»™chói(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y) + + + + PerceptualMetric + + + Perceptual difference + Khác biệt dá»±a vào cảm giác + + + + A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee + Sá»± khác biệt vá» cảm giác dá»±a trên metric của hình ảnh. Äây là thuật toán thuá»™c bản quyá»n của Yangli Hector Yee (C) 2006 + + + + Field of view + Khung nhìn + + + + Field of view in degrees (0.1 to 89.9) + Khung nhìn tính băng Ä‘á»™ (0.1 đến 89.9) + + + + Gamma of screen + Màn hình gamma + + + + Value to convert rgb into linear space (default 2.2) + Giá trị chuyển đổi rgb thành linear space (mặc định 2.2) + + + + White luminance + Äá»™ chói trắng + + + + White luminance (default 100.0 cdm^-2) + Äá»™ chói trắng (mặc định 100.0 cdm^-2) + + + + Luminance only + Chỉ có Ä‘á»™ chói + + + + Only consider luminance; ignore chroma (color) in the comparison + Chỉ xem xét giá trị Ä‘á»™ chói; bá» qua chroma (màu) khi so sánh + + + + Color factor + Hệ số màu + + + + How much of color to use, 0.0 to 1.0, 0.0 = ignore color. + Hệ số màu được sá»­ dụng, 0.0 đến 1.0, 0.0 = loại bá» màu. + + + + Downsample + Mẫu thá»­ + + + + How many powers of two to down sample the image + Số lượng phần mẫu thá»­ của hình ảnh + + + + PropertyWidget + + + Properties + Thuá»™c tính + + + + Statistics + Thống kê + + + + QObject + + + + Image Difference tool. + Công cụ tìm khác biệt trong hình. + + + + Available metrics: + Metric hiện có: + + + + Input parameters: + Thông số đầu vào: + + + + Output parameters: + Thông số đầu ra: + + + + How to use batch mode: + Cách sá»­ dụng chế Ä‘á»™ kết hợp hàng loạt: + + + + Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric + Do not translate parameters, only comments + Ví dụ 1: --batch --metric PerChannelMeanMetric : sá»­ dụng má»—i kênh vá»›i metric + + + + Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Ví dụ 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Dùng metric má»—i kênh và thoát để lại cảnh báo lá»—i nếu Ä‘iểm ảnh có giá trị khác nhau lên đến 250 + + + + Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250 + Do not translate parameters, only comments + Ví dụ 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Sá»­ dụng metric cảm quan vá»›i các thông số đầu và thoát rồi để lại lá»—i nếu số Ä‘iểm ảnh khác biệt vượt quá 250 + + + + Usage: + Các dùng: + + + + [options] + [tùy chá»n] + + + + img1 img2 + hinh1 hinh2 + + + + Following options are known: + Các tùy chá»n sau đây được biết dÆ°á»›i dạng: + + + + --list - list all metrics with their parameters. + --list - danh sách của tất cả metric kèm theo thông số. + + + + --batch - batch mode. Differences are computed without GUI and return code is used as result. + --batch - chế Ä‘á»™ chỉnh sá»­a hàng loạt. Các Ä‘iểm khác biệt được tá»± Ä‘á»™ng tính toán và hiển thị ra dạng mã chứ không cần thông qua giao diện đồ há»a. + + + + --metric - metric tag name. Display list of metrics with --list option. + --metric - thẻ đánh dấu tên của metric. Hiển thị danh sách metric vá»›i --list option. + + + + --in name=value - input parameter update. + --in name=value - cập nhật giá trị thông số đầu vào. + + + + --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept. + --threshold name=value - thông số đầu ra được dùng để xác định sá»± so sánh trong chế Ä‘á»™ thá»±c hiện đồng loạt. Nếu bạn đặt má»™t vài ngưỡng thông số nhất định, chỉ có thông số gần đây nhất sẽ được giữ lại. + + + + You must set valid filename files as arguments in batch mode !! + Bạn phải đặt tên tập tin hợp lệ vì các tên này là những thông số trong chế Ä‘á»™ so sánh hàng loạt !! + + + + Metric %1 unknown !! + Không biết rõ metric %1 !! + + + + Metric %1 has no input parameter !! + Metric %1 không có thông số đầu vào !! + + + + Can't display difference, more information in the log panel ... + Không thể hiển thị sá»± khác biệt, Ä‘á»c thêm thông tin ở khung Ä‘iá»u khiển nhật trình... + + + + Files are identical + Các tập tin này là đồng nhất + + + + Files are identical (under the threshold) + Các tập tin đồng nhất (dÆ°á»›i ngưỡng cho phép) + + + + Error in options ! + Lá»—i trong tùy chá»n! + + + + You must set at least two files as arguments in batch mode !! + Bạn phải đặt ít nhất là hai tập tin vì đây là những thông số đầu vào trong chế Ä‘á»™ so sánh hàng loạt !! + + + + setting language to : %1 + đặt ngôn ngữ : %1 + + + + + successfully loaded data from %1 + đã tải thành công dữ liệu từ %1 + + + + failed to load data from %1 + xảy ra lá»—i khi tải dữ liệu từ %1 + + + + Bytes + Byte + + + + KB + Kilobyte + KB + + + + MB + Megabyte + MB + + + + GB + Gigabyte + GB + + + + TB + Terabyte + TB + + + + Pixels + Äiểm ảnh + + + + Kp + Kilopixel + Kđả + + + + Mp + Megapixel + Mđả + + + + Gp + Gigapixel + Gđả + + + + Tp + Terapixel + Tđả + + + + + + Value: %1 + Giá trị: %1 + + + + + + Value: %1, + Giá trị: %1, + + + + + + + Alpha: %1 + Alpha: %1 + + + + + Red: %1, + Äá»: %1, + + + + + Green: %1, + Xanh lá: %1, + + + + Blue: %1 + Xanh dÆ°Æ¡ng: %1 + + + + Blue: %1, + Xanh dÆ°Æ¡ng: %1, + + + + + + + + + + + + + + + + + + + + + + + not yet implemented (%1) + chÆ°a được hoàn thiện xong (%1) + + + Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_cs.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_cs.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_fr.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_fr.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_it.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_it.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_pt.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_pt.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_sv.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_sv.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/lang/qt_vi.qm and /tmp/TanR_227uO/diffimg-2.0.0/lang/qt_vi.qm differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/about.png and /tmp/TanR_227uO/diffimg-2.0.0/res/about.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/check2.png and /tmp/TanR_227uO/diffimg-2.0.0/res/check2.png differ diff -Nru diffimg-1.5.0/res/diffimg.qrc diffimg-2.0.0/res/diffimg.qrc --- diffimg-1.5.0/res/diffimg.qrc 2012-01-17 20:26:57.000000000 +0000 +++ diffimg-2.0.0/res/diffimg.qrc 2013-05-06 15:58:34.000000000 +0000 @@ -1,5 +1,12 @@ + check2.png + perceptual.png + perchannel.png + perchannelmean.png + perluminance.png + journal.png + help.png allgood.png bad.png somebad.png Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/help.png and /tmp/TanR_227uO/diffimg-2.0.0/res/help.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/journal.png and /tmp/TanR_227uO/diffimg-2.0.0/res/journal.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/next.png and /tmp/TanR_227uO/diffimg-2.0.0/res/next.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/perceptual.png and /tmp/TanR_227uO/diffimg-2.0.0/res/perceptual.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/perchannel.png and /tmp/TanR_227uO/diffimg-2.0.0/res/perchannel.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/perchannelmean.png and /tmp/TanR_227uO/diffimg-2.0.0/res/perchannelmean.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/perluminance.png and /tmp/TanR_227uO/diffimg-2.0.0/res/perluminance.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/preferences.png and /tmp/TanR_227uO/diffimg-2.0.0/res/preferences.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/prev.png and /tmp/TanR_227uO/diffimg-2.0.0/res/prev.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/splashscreen.png and /tmp/TanR_227uO/diffimg-2.0.0/res/splashscreen.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/res/unknown.png and /tmp/TanR_227uO/diffimg-2.0.0/res/unknown.png differ diff -Nru diffimg-1.5.0/setup/setup-x64.nsi diffimg-2.0.0/setup/setup-x64.nsi --- diffimg-1.5.0/setup/setup-x64.nsi 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/setup/setup-x64.nsi 2013-07-13 15:28:06.000000000 +0000 @@ -0,0 +1,238 @@ + +;NSIS Modern User Interface +;Written by Joost Verburg + +XPStyle on +!define PROGRAM_NAME "DiffImg" +!define TARGET_NAME "${PROGRAM_NAME}" +!define ORGANIZATION_NAME "TheHive" +!define SHCNE_ASSOCCHANGED 0x8000000 +!define SHCNF_IDLIST 0 +!define ARCH 'x64' + +!include "x64.nsh" + + +BrandingText "${PROGRAM_NAME} installation"; remove the nsis release on the gui + +########################################################################################### +# init functions +########################################################################################### + +Function .onInit + + # set the 64 registry + SetRegView 64 + + # fading splashscreen !! + # the plugins dir is automatically deleted when the installer exits + InitPluginsDir + File /oname=$PLUGINSDIR\splash.bmp "splashscreen-x64.bmp" + #optional + #File /oname=$PLUGINSDIR\splash.wav "C:\myprog\sound.wav" + + advsplash::show 2000 600 400 -1 $PLUGINSDIR\splash + + Pop $0 ; $0 has '1' if the user closed the splash screen early, + ; '0' if everything closed normally, and '-1' if some error occurred. + + Delete $PLUGINSDIR\splash.bmp + + # uninstall previous release before installing a new one + ReadRegStr $R0 HKLM \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" \ + "UninstallString" + StrCmp $R0 "" done + + MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ + "${PROGRAM_NAME} (x64) is already installed. $\n$\nClick `OK` to remove the \ + previous version or `Cancel` to cancel this upgrade." \ + IDOK uninst + Abort + + ;Run the uninstaller + uninst: + ClearErrors + Exec "$INSTDIR\uninstall.exe /S" + + done: + +FunctionEnd + +;-------------------------------- + +Function LaunchLink + ExecShell "" "$INSTDIR\${PROGRAM_NAME}.exe" +FunctionEnd + +;-------------------------------- +;Include Modern UI + + !include "MUI2.nsh" + +;-------------------------------- +;General + + ;Name and file + !ifndef VERSION + !define VERSION 'bxx' + !endif + +;-------------------------------- +;Configuration + + ;Name and file + Name "${PROGRAM_NAME} (x64)" + + ; output directory if not set by batch + !ifndef SETUP_DIR + !define SETUP_DIR '.\' + !endif + + ; output setup file + !ifdef OUTFILE + OutFile "${SETUP_DIR}\${OUTFILE}" + !else + OutFile "${SETUP_DIR}\${PROGRAM_NAME}-${ARCH}-${VERSION}-setup.exe" + !endif + + ;Default installation folder + InstallDir "$PROGRAMFILES64\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" + + ;Get installation folder from registry if available + InstallDirRegKey HKLM "Software\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" "Install_Dir" + + ;Request application privileges for Windows Vista + RequestExecutionLevel admin + +;-------------------------------- +;Interface Settings + + !define MUI_HEADERIMAGE + !define MUI_HEADERIMAGE_RIGHT + !define MUI_HEADERIMAGE_BITMAP "banner.bmp" ; optional installer pages + !define MUI_HEADERIMAGE_UNBITMAP "banner.bmp" ; uninstaller pages + !define MUI_ABORTWARNING + !define MUI_ICON "icon_install.ico" + !define MUI_UNICON "icon_uninstall.ico" + !define MUI_WELCOMEFINISHPAGE_BITMAP "welcome.bmp" ; welcome/finish banner + !define MUI_FINISHPAGE_NOAUTOCLOSE + + !define MUI_FINISHPAGE_RUN + !define MUI_FINISHPAGE_RUN_NOTCHECKED + !define MUI_FINISHPAGE_RUN_TEXT "Start ${PROGRAM_NAME} (x64) after install" + !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink" + !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED + +;-------------------------------- +;Pages + + ;!insertmacro MUI_PAGE_LICENSE "License.txt" + ;!insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_WELCOME ; affiche un welcome + !insertmacro MUI_PAGE_DIRECTORY + !insertmacro MUI_PAGE_INSTFILES + !insertmacro MUI_PAGE_FINISH ; affiche une page de fin + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + +Section "Dummy Section" SecDummy + + SectionIn RO + + ; Program files there + SetOutPath $INSTDIR + File "..\build\Release\${PROGRAM_NAME}.exe" + File "$%QTDIR%\bin\QtCore4.dll" + File "$%QTDIR%\bin\QtGui4.dll" + ; Minggw case ... + File /nonfatal "$%QTDIR%\bin\mingwm10.dll" + File /nonfatal "$%QTDIR%\bin\libgcc_s_dw2-1.dll" + + + ; qt image plugin + SetOutPath "$INSTDIR\plugins\imageformats" + File "$%QTDIR%\plugins\imageformats\*.dll" + + ; Lang files + SetOutPath "$INSTDIR\lang" + File /nonfatal "..\lang\*.qm" + File /nonfatal "*.qm" + + ; test files + SetOutPath "$INSTDIR\test" + File /r "..\test\*.*" + + ; Other files + SetOutPath $INSTDIR + File "..\CREDITS.txt" + File "..\AUTHORS.txt" + File "..\LICENSE.txt" + File "..\Changelog.txt" + + ; resources files + SetOutPath $INSTDIR + File "icon.ico" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" "Install_Dir" "$INSTDIR" + WriteRegStr HKLM "SOFTWARE\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" "Version" "${VERSION}" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" "DisplayName" "${PROGRAM_NAME} (x64)" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + +SectionEnd + +;-------------------------------- +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" + + SetShellVarContext all ; scope is "All Users" + CreateDirectory "$SMPROGRAMS\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" + CreateShortCut "$SMPROGRAMS\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)\${PROGRAM_NAME} (x64).lnk" "$INSTDIR\${PROGRAM_NAME}.exe" "" "$INSTDIR\${PROGRAM_NAME}.exe" 0 + + ;create desktop shortcut + CreateShortCut "$DESKTOP\${PROGRAM_NAME} (x64).lnk" "$INSTDIR\${PROGRAM_NAME}.exe" "" "$INSTDIR\icon.ico" + +SectionEnd + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME} (x64)" + DeleteRegKey HKLM "SOFTWARE\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" + + ; Remove files and uninstaller + Delete "$INSTDIR\*.*" + + ; Remove shortcuts, if any + SetShellVarContext all ; scope is "All Users" + Delete "$SMPROGRAMS\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)\*.*" + + ; remove desktop link + Delete "$DESKTOP\${PROGRAM_NAME} (x64).lnk" + + ; Remove directories used + RMDir "$SMPROGRAMS\${ORGANIZATION_NAME}\${PROGRAM_NAME} (x64)" + RMDir "$SMPROGRAMS\${ORGANIZATION_NAME}" + RMDir /r "$INSTDIR\plugins" + RMDir /r "$INSTDIR" + +SectionEnd \ No newline at end of file Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/setup/splashscreen-x64.bmp and /tmp/TanR_227uO/diffimg-2.0.0/setup/splashscreen-x64.bmp differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/setup/splashscreen.bmp and /tmp/TanR_227uO/diffimg-2.0.0/setup/splashscreen.bmp differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/setup/welcome.bmp and /tmp/TanR_227uO/diffimg-2.0.0/setup/welcome.bmp differ diff -Nru diffimg-1.5.0/src/AboutDialog.cpp diffimg-2.0.0/src/AboutDialog.cpp --- diffimg-1.5.0/src/AboutDialog.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/AboutDialog.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,20 +15,29 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include "AboutDialog.h" #include "MiscFunctions.h" #include "AppSettings.h" #include "LogHandler.h" + +#include "MetricsManager.h" +#include "BaseMetric.h" + #include #include #include + #include +#include +#include AboutDialog::AboutDialog(QWidget *parent) - : QDialog(parent) + : QDialog(parent), + m_dValidator( new QDoubleValidator(this) ), + m_iValidator( new QIntValidator(this) ) { setupUi(this); updateAbout(); @@ -55,10 +64,11 @@ // setup pref language updatePrefsLanguages(); - // init combobox method - initMethodType(); + // init combobox metrics + initMetrics(); labelRelease->setText( QString(PACKAGE_NAME) + " " + QString(PACKAGE_VERSION) ); + labelCheckRelease->setText( tr("Check for new release ...").arg(PACKAGE_CHECK_RELEASE_URL) ); } void AboutDialog::updateInfosImageFormats() @@ -78,6 +88,9 @@ else new QListWidgetItem(format, listWidgetFormats); } + + // Qt version + labelQtVersion->setText( tr("Qt version %1").arg(QT_VERSION_STR) ); } void AboutDialog::updateInfosLanguages() @@ -128,8 +141,8 @@ paths << QApplication::applicationDirPath () + "/../" + file; paths << QApplication::applicationDirPath () + "/../../" + file; paths << QApplication::applicationDirPath () + "/../../../" + file; - paths << "/usr/share/diffimg/" + file; - paths << "/usr/local/share/diffimg/" + file; + paths << "/usr/share/" + QString("%1").arg(PACKAGE_NAME).toLower() + "/" + file; + paths << "/usr/local/share/" + QString("%1").arg(PACKAGE_NAME).toLower() + "/" + file; foreach (const QString &path, paths) { @@ -220,42 +233,202 @@ } } -void AboutDialog::initMethodType() +void AboutDialog::initMetrics() +{ + // update comboBoxUploaders + const QList &list = MetricsManager::getMetrics(); + foreach (BaseMetric * met, list) + { + comboBoxMetrics->addItem( met->getName(),qVariantFromValue( (void *) met ) ); // store directly pointer + } +} + +void AboutDialog::on_listWidgetTranslations_itemClicked( QListWidgetItem * item) +{ + QString lang = item->data(Qt::UserRole).toString(); + QString file( MiscFunctions::getTranslationsPath() ); + file += QString("/%1_%2.qm").arg( QString(PACKAGE_NAME).toLower() ).arg(lang); + + QTranslator translator; + translator.load(file); + labelTranslation->setText( translator.translate("","release of translation and translator name please","put your name here dear translator and the release of the translation file !!") ); +} + +void AboutDialog::on_comboBoxMetrics_currentIndexChanged(int index) { - // user data are set just to help (not used) - comboBoxMethod->addItem(tr("Difference by channel"),MiscFunctions::METHOD_BYCHANNEL); - comboBoxMethod->addItem(tr("Difference by channel mean"),MiscFunctions::METHOD_BYCHANNELMEAN); - comboBoxMethod->addItem(tr("Difference by image lightness"),MiscFunctions::METHOD_BYLIGHTNESS); + labelMetricPixmap->setPixmap( QPixmap() ); + labelMetricDesc->setText(""); - m_descMethodHash[MiscFunctions::METHOD_BYCHANNEL] = tr("Difference is computed channel by channel"); - m_descMethodHash[MiscFunctions::METHOD_BYCHANNELMEAN] = tr("Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3"); - m_descMethodHash[MiscFunctions::METHOD_BYLIGHTNESS] = tr("Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y)"); + if (index < 0) + return; + + BaseMetric *met = static_cast( comboBoxMetrics->itemData(index,Qt::UserRole).value() ); + labelMetricPixmap->setPixmap( met->getLogo().scaled(QSize(48,48),Qt::KeepAspectRatio,Qt::SmoothTransformation) ); + labelMetricDesc->setText( met->getDesc() ); + + // update comboBoxInputParam + comboBoxInputParam->clear(); + const QList &listInput = met->getInputParams(); + + lineEditInputParam->setText(""); + lineEditInputParam->setToolTip(""); + lineEditInputParam->setEnabled( !listInput.isEmpty() ); + comboBoxInputParam->setToolTip(""); + pushButtonApplyInputParam->setEnabled(false); + + foreach (MetricParam * param, listInput) + { + comboBoxInputParam->addItem( param->name,qVariantFromValue( (void *) param ) ); // store directly pointer + } + + // update comboBoxOutputParameter + comboBoxOutputParam->clear(); + const QList &listOutput = met->getOutputParams(); + + lineEditThreshold->setText(""); + lineEditThreshold->setToolTip(""); + lineEditThreshold->setEnabled( !listOutput.isEmpty() && groupBoxEnableThreshold->isChecked() ); + comboBoxOutputParam->setToolTip(""); + + foreach (MetricParam * param, listOutput) + { + comboBoxOutputParam->addItem( param->name,qVariantFromValue( (void *) param ) ); // store directly pointer + if (param->used) + comboBoxOutputParam->setCurrentIndex(comboBoxOutputParam->count() - 1); + } } -void AboutDialog::on_comboBoxMethod_activated(int index) +void AboutDialog::on_groupBoxEnableThreshold_toggled ( bool on ) { - int type = comboBoxMethod->itemData(index).toInt(); - labelDescMethod->setText(m_descMethodHash[type]); + BaseMetric *met = static_cast( comboBoxMetrics->itemData(comboBoxMetrics->currentIndex(),Qt::UserRole).value() ); + if (met) + { + const QList &list = met->getOutputParams(); + lineEditThreshold->setEnabled(!list.isEmpty() && on); + } } -void AboutDialog::setCurrentDiffMethod(int type) +void AboutDialog::on_comboBoxInputParam_currentIndexChanged(int index) { - labelDescMethod->setText(m_descMethodHash[type]); - comboBoxMethod->setCurrentIndex( type ); + setupParam(index,comboBoxInputParam,lineEditInputParam,pushButtonApplyInputParam); } -QString AboutDialog::getStringForMethod(int index) const +void AboutDialog::on_comboBoxOutputParam_currentIndexChanged(int index) { - return comboBoxMethod->itemText(index); + setupParam(index,comboBoxOutputParam,lineEditThreshold,pushButtonApply); + + MetricParam *param = static_cast( comboBoxOutputParam->itemData(index,Qt::UserRole).value() ); + BaseMetric *met = static_cast( comboBoxMetrics->itemData(comboBoxMetrics->currentIndex(),Qt::UserRole).value() ); + met->setDiscriminatingParam(param); } -void AboutDialog::on_listWidgetTranslations_itemClicked( QListWidgetItem * item) +void AboutDialog::setupParam(int index, QComboBox *combo, QLineEdit *lineEdit, QPushButton *button ) { - QString lang = item->data(Qt::UserRole).toString(); - QString file( MiscFunctions::getTranslationsPath() ); - file += QString("/%1_%2.qm").arg( QString(PACKAGE_NAME).toLower() ).arg(lang); + if (index < 0) + return; - QTranslator translator; - translator.load(file); - labelTranslation->setText( translator.translate("","release of translation and translator name please","put your name here dear translator and the release of the translation file !!") ); + MetricParam *param = static_cast( combo->itemData(index,Qt::UserRole).value() ); + combo->setToolTip(param->desc); + lineEdit->setText( param->threshold.toString() ); + lineEdit->setToolTip(param->desc); + + // update the validator + switch ( param->threshold.type() ) + { + case QMetaType::Int: + { + lineEdit->setValidator(m_iValidator); + break; + } + case QMetaType::Double: + case QMetaType::Float: + { + lineEdit->setValidator(m_dValidator); + break; + } + default: + lineEdit->setValidator(NULL); + break; + } + + // restore the standard palette + changePalette(false,lineEdit,button ); +} + +void AboutDialog::on_lineEditInputParam_textEdited ( const QString & text ) +{ + Q_UNUSED(text); + changePalette(true,lineEditInputParam,pushButtonApplyInputParam); +} + +void AboutDialog::on_lineEditThreshold_textEdited ( const QString & text ) +{ + Q_UNUSED(text); + changePalette(true,lineEditThreshold,pushButtonApply); +} + +void AboutDialog::on_pushButtonApplyInputParam_pressed() +{ + applyParam(comboBoxInputParam, lineEditInputParam, pushButtonApplyInputParam ); +} + +void AboutDialog::on_pushButtonApply_pressed() +{ + applyParam(comboBoxOutputParam, lineEditThreshold, pushButtonApply ); +} + +void AboutDialog::applyParam(QComboBox *combo, QLineEdit *lineEdit, QPushButton *button ) +{ + changePalette(false,lineEdit,button); + + // apply the modification + MetricParam *param = static_cast( combo->itemData(combo->currentIndex(),Qt::UserRole).value() ); + QString valText = lineEdit->text(); + if (param) + { + // update the theshold + + /* + switch ( param->threshold.type() ) + { + case QVariant::Int: + { + param->threshold = valText.toInt(); + break; + } + case QVariant::Double: + case QMetaType::Float: + { + param->threshold = valText.toFloat(); + break; + } + default: + break; + } + */ + param->setThreshold(valText); + } +} + +void AboutDialog::changePalette(bool modified, QLineEdit *lineEdit, QPushButton *button) +{ + button->setEnabled(modified); + if (modified) + { + QPalette pal; + pal.setColor(QPalette::Text, Qt::red); + lineEdit->setPalette(pal); + } + else + { + // restore normal palette + QPalette pal; + pal.setColor(QPalette::Text, Qt::black); + lineEdit->setPalette(pal); + } +} + +void AboutDialog::on_tabWidget_currentChanged ( int index ) +{ + setWindowTitle( tabWidget->tabText(index) ); } diff -Nru diffimg-1.5.0/src/AboutDialog.h diffimg-2.0.0/src/AboutDialog.h --- diffimg-1.5.0/src/AboutDialog.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/AboutDialog.h 2013-05-17 20:03:38.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #ifndef _DIALOGABOUT_H_ @@ -26,6 +26,9 @@ using namespace Ui; +class QDoubleValidator; +class QIntValidator; + class AboutDialog : public QDialog, public AboutDialogClass { Q_OBJECT @@ -39,16 +42,21 @@ void showPreferences(); void setCurrentLanguage(const QString &); - void setCurrentDiffMethod(int); - - QString getStringForMethod(int) const; public slots: void on_pushButtonClearLog_pressed(); void on_comboBoxLanguage_activated(int index); - void on_comboBoxMethod_activated(int index); void on_listWidgetTranslations_itemClicked( QListWidgetItem * item); + void on_comboBoxMetrics_currentIndexChanged(int); + void on_comboBoxOutputParam_currentIndexChanged(int); + void on_comboBoxInputParam_currentIndexChanged(int); + void on_lineEditThreshold_textEdited ( const QString & text ); + void on_lineEditInputParam_textEdited ( const QString & text ); + void on_pushButtonApplyInputParam_pressed(); + void on_pushButtonApply_pressed(); + void on_groupBoxEnableThreshold_toggled ( bool on ); + void on_tabWidget_currentChanged ( int index ); signals: @@ -63,10 +71,15 @@ void updatePrefsLanguages(); void updateInfosLanguages(); void updateInfosImageFormats(); - void initMethodType(); + void initMetrics(); + void changePalette(bool modified, QLineEdit *lineEdit, QPushButton *button); + void setupParam(int index, QComboBox *combo, QLineEdit *lineEdit, QPushButton *button ); + void applyParam(QComboBox *combo, QLineEdit *lineEdit, QPushButton *button ); QString m_currentLanguage; QMap m_descMethodHash; + QDoubleValidator *m_dValidator; + QIntValidator *m_iValidator; }; #endif // _DIALOGABOUT_H_ diff -Nru diffimg-1.5.0/src/AppSettings.cpp diffimg-2.0.0/src/AppSettings.cpp --- diffimg-1.5.0/src/AppSettings.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/AppSettings.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include "AppSettings.h" diff -Nru diffimg-1.5.0/src/AppSettings.h diffimg-2.0.0/src/AppSettings.h --- diffimg-1.5.0/src/AppSettings.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/AppSettings.h 2013-05-17 18:57:54.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #ifndef _APPETTINGS_H_ @@ -25,7 +25,9 @@ #define PACKAGE_ORGANIZATION "TheHive" #define PACKAGE_NAME "DiffImg" -#define PACKAGE_VERSION "1.5.0" +#define PACKAGE_VERSION "2.0" +#define PACKAGE_ONLINE_HELP_URL "http://thehive.xbee.net/index.php?module=pages&func=display&pageid=11" +#define PACKAGE_CHECK_RELEASE_URL "http://sourceforge.net/projects/diffimg/files" class AppSettings : public QSettings { diff -Nru diffimg-1.5.0/src/DiffImgWindow.cpp diffimg-2.0.0/src/DiffImgWindow.cpp --- diffimg-1.5.0/src/DiffImgWindow.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/DiffImgWindow.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,29 +15,37 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include "DiffImgWindow.h" #include "FilesDialog.h" -#include "ScrollImageWidget.h" #include "AppSettings.h" #include "LogHandler.h" #include "AboutDialog.h" #include "MiscFunctions.h" +#include "BaseMetric.h" +#include "MetricsRegistering.h" +#include "MetricsManager.h" +#include "FilesManager.h" + #include #include #include #include #include +#include +#include #include +#include #include -#include #include +#include #include +#include #include @@ -54,6 +62,7 @@ #endif const int defaultThumbnailSize = 128; +const int updateWaitTime = 200; // QWT #include @@ -89,15 +98,19 @@ DiffImgWindow::DiffImgWindow(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags), - m_displayDiff(true), + m_displayOverlayDiff(true), m_displayOriginalImage(true), m_displayModifiedImage(false), m_displayDifferenceImage(false), m_displayDualPanel(false), - m_newFile1(true), - m_newFile2(true), + m_newFile1m_newFile1(true), + m_newFile2m_newFile1(true), m_version(PACKAGE_VERSION), +#ifdef WIN64 + m_appName( PACKAGE_NAME + QString(" (x64)") ), +#else m_appName(PACKAGE_NAME), +#endif m_firstTime(true), m_splashscreenAtStartup(true), m_splashscreenTransparentBackground(true), @@ -108,10 +121,18 @@ m_widgetHistoCurveB(NULL), m_resetConfig(false), m_maskOpacity(50), - m_enableThreshold(false), - m_diffMethod(MiscFunctions::METHOD_BYCHANNEL), - m_RMSThreshold(0.3f), - m_diffRes(NULL) + m_compareWithThreshold(false), + m_metricType(0), + m_thresholdType(0), + m_diffRes(NULL), + m_currentDisplayType(TYPE_ORIGINAL), + m_labelZoom(NULL), + m_labelPos(NULL), + m_labelInfos(NULL), + m_applyGain(false), + m_applyOffset(false), + m_currentGain(1.0f), + m_currentOffset(0.0f) { setupUi(this); updateUi(); @@ -122,77 +143,117 @@ { saveSettings(); delete m_diffRes; + MetricsManager::clear(); } void DiffImgWindow::updateUi() { updateApplicationIdentity(); -// m_sourceImage = QImage(":/diffimg/original.png"); -// m_destinationImage = QImage(":/diffimg/modified.png"); -// m_diffImage = QImage(":/diffimg/diffimg.png"); -// m_resultImage1 = QImage(":/diffimg/diffimg.png"); -// m_resultImage2 = QImage(":/diffimg/diffimg.png"); + // metrics registering + int nb = MetricsRegistering::registerAll(); + LogHandler::getInstance()->reportDebug( QString("Register of %1 metrics").arg(nb) ); m_dfiles = new FilesDialog(this); connect( m_dfiles, SIGNAL( accepted () ), this, SLOT( acceptFiles() ) ); QActionGroup *actionGroup = new QActionGroup(this); - actionGroup->addAction(actionOriginalImage); - actionGroup->addAction(actionModifiedImage); + actionGroup->addAction(actionImage1); + actionGroup->addAction(actionImage2); actionGroup->addAction(actionDifferenceImage); actionGroup->setExclusive(true); - on_actionOriginalImage_toggled(true); - - connect( scrollAreaImage1, SIGNAL( somethingChanged() ), this, SLOT( displayNavigator() ) ); - connect( scrollAreaImage1, SIGNAL( mousePosition(const QPoint &) ), this, SLOT( displayPosition(const QPoint &) ) ); - - connect( scrollAreaImage2, SIGNAL( somethingChanged() ), this, SLOT( displayNavigator() ) ); - connect( scrollAreaImage2, SIGNAL( mousePosition(const QPoint &) ), this, SLOT( displayPosition(const QPoint &) ) ); - - connect( scrollAreaImage2, SIGNAL( currentZoomFactor(float) ), scrollAreaImage1, SLOT( setZoomFactor(float) ) ); - connect( scrollAreaImage1, SIGNAL( currentZoomFactor(float) ), scrollAreaImage2, SLOT( setZoomFactor(float) ) ); - - connect( scrollAreaImage2, SIGNAL( scrollPosition(const QPoint &) ), scrollAreaImage1, SLOT( setScrollValue(const QPoint &) ) ); - connect( scrollAreaImage1, SIGNAL( scrollPosition(const QPoint &) ), scrollAreaImage2, SLOT( setScrollValue(const QPoint &) ) ); - -// scrollAreaImage1->setImage(QImage(QSize(2,2),QImage::Format_RGB32)); -// scrollAreaImage2->setImage(QImage(QSize(2,2),QImage::Format_RGB32)); - m_about = new AboutDialog(this); connect( m_about,SIGNAL( restart() ),this,SLOT( restart() ) ); connect( m_about, SIGNAL( accepted() ), this, SLOT( setPreferences() ) ); // create and connect the log handler connect( LogHandler::getInstance(),SIGNAL( newMessage(const QString &) ),this,SLOT( printToLog(const QString &) ) ); + LogHandler::getInstance()->setBufferization(false); // get all stored messages if exists m_diffRes = new DiffStruct; - // setup "buttons" -// pushButtonOriginal->setIconSize(QSize(defaultThumbnailSize,defaultThumbnailSize)); -// pushButtonOriginal->setIcon(QPixmap(":/diffimg/original.png")); -// pushButtonModified->setIconSize(QSize(defaultThumbnailSize,defaultThumbnailSize)); -// pushButtonModified->setIcon(QPixmap(":/diffimg/modified.png")); -// pushButtonDifference->setIconSize(QSize(defaultThumbnailSize,defaultThumbnailSize)); -// pushButtonDifference->setIcon(QPixmap(":/diffimg/diffimg.png")); + // add some labels to status bar + m_labelInfos = new QLabel(this); + QMainWindow::statusBar()->addPermanentWidget(m_labelInfos); + + m_labelPos = new QLabel(this); + QMainWindow::statusBar()->addPermanentWidget(m_labelPos); + + m_labelZoom = new QLabel(this); + QMainWindow::statusBar()->addPermanentWidget(m_labelZoom); + + connect( graphicsView1,SIGNAL( mouseMoved(const QPointF &) ),this,SLOT( displayMousePosition(const QPointF &) ) ); + connect( graphicsView1,SIGNAL( mouseMoved(const QPointF &) ),graphicsView2,SLOT( setMarkerPosition(const QPointF &) ) ); + connect( graphicsView1,SIGNAL( scaleChanged(qreal) ),this,SLOT( displayZoomFactor(qreal) ) ); + + connect( graphicsView2,SIGNAL( mouseMoved(const QPointF &) ),this,SLOT( displayMousePosition(const QPointF &) ) ); + connect( graphicsView2,SIGNAL( mouseMoved(const QPointF &) ),graphicsView1,SLOT( setMarkerPosition(const QPointF &) ) ); + connect( graphicsView2,SIGNAL( scaleChanged(qreal) ),this,SLOT( displayZoomFactor(qreal) ) ); + + connect( graphicsView1,SIGNAL( somethingChanged() ),this,SLOT( syncPanels() ) ); + connect( graphicsView2,SIGNAL( somethingChanged() ),this,SLOT( syncPanels() ) ); + + graphicsView2->setShowOverview(false); // no navigator in view 2 + //connect( graphicsView2,SIGNAL( newZoomFactor(qreal) ),graphicsView1,SLOT( zoom(qreal) ) ); + + QButtonGroup *bg = new QButtonGroup(this); + bg->setExclusive(true); + bg->addButton(pushButtonFile1); + bg->addButton(pushButtonFile2); + bg->addButton(pushButtonDifference); + + // highlight pressed buttons + pushButtonFile1->setStyleSheet("QPushButton:checked { background-color: #ffff00;}"); + pushButtonFile2->setStyleSheet("QPushButton:checked { background-color: #ffff00; }"); + pushButtonDifference->setStyleSheet("QPushButton:checked { background-color: #ffff00; }"); + + // update tooltip with shortcuts ... + updateTooltips(); + + // update timer for gain/offset + m_timerUpdate = new QTimer(this); + connect( m_timerUpdate,SIGNAL( timeout() ),this,SLOT( updateDisplay() ) ); + m_timerUpdate->setSingleShot(true); +} + +void DiffImgWindow::updateTooltips() +{ + QList actions = findChildren(); + + foreach(QAction * act, actions ) + { + QString tooltip = act->toolTip(); + QKeySequence keyShortcut = act->shortcut(); + QString strShortcutString = keyShortcut.toString(); + if ( !strShortcutString.isEmpty() ) + act->setToolTip( QString("%1 (%2)").arg(tooltip,strShortcutString) ); + } } void DiffImgWindow::updateTitle() { - QString title = QFileInfo(m_file1).fileName() + "/" + QFileInfo(m_file2).fileName(); + int index1 = FilesManager::getFilelist1().indexOf( QFileInfo(m_file1).fileName() ); + int index2 = FilesManager::getFilelist2().indexOf( QFileInfo(m_file2).fileName() ); + int total1 = FilesManager::getFilelist1().size() - 1; + int total2 = FilesManager::getFilelist2().size() - 1; + QString title; + if (index1 >= 0 && index2 >= 0) + title = QString(" (%1/%2) [%3] / [%4] (%5/%6)").arg(index1).arg(total1).arg( QFileInfo(m_file1).fileName() ).arg( QFileInfo(m_file2).fileName() ).arg(index2).arg(total2); + else + title = "[" + QFileInfo(m_file1).fileName() + "] / [" + QFileInfo(m_file2).fileName() + "]"; setWindowTitle(m_appName + " " + m_version + ": " + title); } -void DiffImgWindow::setFiles(const QString &original, const QString &modified) +void DiffImgWindow::setFiles(const QString &file1, const QString &file2) { - m_file1 = original; - m_file2 = modified; + m_file1 = file1; + m_file2 = file2; m_firstTime = false; // not open dialog file // reinit the dialog - m_dfiles->lineEditFileBase->setText(m_file1); - m_dfiles->lineEditFileNew->setText(m_file2); + m_dfiles->lineEditFile1->setText(m_file1); + m_dfiles->lineEditFile2->setText(m_file2); } void DiffImgWindow::on_actionQuit_triggered() @@ -245,9 +306,13 @@ settings.setValue("resetConfig", m_resetConfig); // not use by now settings.setValue("maskOpacity", m_maskOpacity); - settings.setValue("enableThreshold", m_enableThreshold); - settings.setValue("diffMethod", m_diffMethod); - settings.setValue("RMSThreshold", m_RMSThreshold); + + settings.setValue("compareWithThreshold", m_compareWithThreshold); + settings.setValue("metricType", m_metricType); + settings.setValue("thresholdType", m_thresholdType); + + settings.setValue("currentDisplayType", m_currentDisplayType); + settings.setValue("displayOverlayDiff", m_displayOverlayDiff); settings.endGroup(); } @@ -290,10 +355,24 @@ m_resetConfig = settings.value("resetConfig", false).toBool(); // not use by now m_maskOpacity = settings.value("maskOpacity", 50).toInt(); - m_enableThreshold = settings.value("enableThreshold", false).toBool(); - m_diffMethod = settings.value("diffMethod", MiscFunctions::METHOD_BYCHANNEL).toInt(); - labelMethod->setText( m_about->getStringForMethod(m_diffMethod) ); - m_RMSThreshold = settings.value("RMSThreshold", 0.3f).toFloat(); + graphicsView1->setMaskOpacity(m_maskOpacity / 100.0f); + graphicsView2->setMaskOpacity(m_maskOpacity / 100.0f); + + m_compareWithThreshold = settings.value("compareWithThreshold", false).toBool(); + m_metricType = settings.value("metricType", 0).toInt(); + m_thresholdType = settings.value("thresholdType", 0).toInt(); + + m_currentDisplayType = settings.value("currentDisplayType", TYPE_ORIGINAL).toInt(); + if (m_currentDisplayType == TYPE_ORIGINAL) + actionImage1->activate(QAction::Trigger); + else if (m_currentDisplayType == TYPE_MODIFIED) + actionImage2->activate(QAction::Trigger); + else + actionDifferenceImage->activate(QAction::Trigger); + m_displayOverlayDiff = settings.value("displayOverlayDiff", true).toBool(); + actionDifferenceMask->setChecked(m_displayOverlayDiff); + + //on_actionDifferenceMask_toggled(m_displayOverlayDiff); settings.endGroup(); } @@ -302,204 +381,87 @@ void DiffImgWindow::load() { // display the selection file dialog if needed - if (!m_file1.size() || !m_file2.size() || m_firstTime) - on_actionOpen_triggered(); - else - computeDifference(); -} - -void DiffImgWindow::on_actionOpen_triggered() -{ - // reinit - m_dfiles->lineEditFileBase->setText(m_file1); - m_dfiles->lineEditFileNew->setText(m_file2); - m_dfiles->show(); -} - -int DiffImgWindow::getNextValidIndex(int curr, int increment) -{ - bool nok = true; - int newIndex = -1; - int nextIndex = curr + increment; - int loop = 0; - - while ( nok && loop < 2 * m_lFiles1.size() ) - { - if ( nextIndex >= m_lFiles1.size() ) - nextIndex = 0; - else if (nextIndex < 0) - nextIndex = m_lFiles1.size() - 1; - - if ( m_lFiles2.contains(m_lFiles1[nextIndex]) ) - { - nok = false; - newIndex = nextIndex; - } - else - nextIndex += increment; - - loop++; - } - return newIndex; + if (m_file1.isEmpty() || m_file2.isEmpty() || m_firstTime) + QTimer::singleShot( 1000, this, SLOT( on_actionOpen_triggered() ) ); } -int DiffImgWindow::prevValidIndex(int curr) +void DiffImgWindow::on_actionHelp_triggered() { - bool nok = true; - int newIndex = -1; - int nextIndex = curr - 1; - while (nok) - { - if ( m_lFiles2.contains(m_lFiles1[m_lFiles1.size() - nextIndex % m_lFiles1.size()]) ) - { - nok = false; - newIndex = m_lFiles1.size() - nextIndex % m_lFiles1.size(); - } - else - nextIndex--; - - // break if needed - if ( nextIndex < -2 * m_lFiles1.size() ) - nok = false; - } - return newIndex; + QDesktopServices::openUrl( QUrl( QString(PACKAGE_ONLINE_HELP_URL) ) ); } -int DiffImgWindow::nextValidIndex(int curr) +void DiffImgWindow::on_actionOpen_triggered() { - bool nok = true; - int newIndex = -1; - int nextIndex = curr + 1; - while (nok) - { - if ( m_lFiles2.contains(m_lFiles1[nextIndex % m_lFiles1.size()]) ) - { - nok = false; - newIndex = nextIndex % m_lFiles1.size(); - } - else - nextIndex++; - - // break if needed - if ( nextIndex > 2 * m_lFiles1.size() ) - nok = false; - } - return newIndex; + // reinit + m_dfiles->setFile1(m_file1); + m_dfiles->setFile2(m_file2); + m_dfiles->show(); } void DiffImgWindow::on_actionNext_triggered() { - if ( !m_lFiles1.size() || !m_lFiles2.size() ) - return; + QString file1 = m_file1, file2 = m_file2; + FilesManager::getNextFiles(file1,file2); - QFileInfo fi1(m_file1); - QFileInfo fi2(m_file2); - int currIndex = m_lFiles1.indexOf( fi1.fileName () ); - int newindex = getNextValidIndex(currIndex); - - if (newindex < 0) + if ( file1.isEmpty() || file2.isEmpty() ) return; - m_dfiles->lineEditFileBase->setText(fi1.absolutePath () + "/" + m_lFiles1[newindex]); - m_dfiles->lineEditFileNew->setText(fi2.absolutePath () + "/" + m_lFiles1[newindex]); + m_dfiles->setFile1(file1); + m_dfiles->setFile2(file2); acceptFiles(); } void DiffImgWindow::on_actionPrev_triggered() { - if ( !m_lFiles1.size() || !m_lFiles2.size() ) - return; + QString file1 = m_file1, file2 = m_file2; + FilesManager::getPrevFiles(file1,file2); - QFileInfo fi1(m_file1); - QFileInfo fi2(m_file2); - int currIndex = m_lFiles1.indexOf( fi1.fileName () ); - int newindex = getNextValidIndex(currIndex,-1); - - if (newindex < 0) + if ( file1.isEmpty() || file2.isEmpty() ) return; - m_dfiles->lineEditFileBase->setText(fi1.absolutePath () + "/" + m_lFiles1[newindex]); - m_dfiles->lineEditFileNew->setText(fi2.absolutePath () + "/" + m_lFiles1[newindex]); + m_dfiles->setFile1(file1); + m_dfiles->setFile2(file2); acceptFiles(); } -void DiffImgWindow::computeDifference(bool force) +void DiffImgWindow::computeDifferenceNew() { - bool computeDiff = force; - if (m_newFile1) - { - QFileInfo fi1(m_file1); - if ( m_file1path != fi1.absoluteDir().absolutePath() ) - { - m_file1path = fi1.absoluteDir().absolutePath(); - m_lFiles1 = fi1.absoluteDir().entryList(QString("*.rgb;*.gli;*.rgba;*.sgi;*.int;*.inta;*.png;*.jpg").split(";"), QDir::Files | QDir::Readable,QDir::Time | QDir::Reversed); - } - m_newFile1 = false; - openOriginal(m_file1); - computeDiff = true; - } + BaseMetric *met = MetricsManager::getMetrics()[m_metricType]; - if (m_newFile2) - { - m_file2 = m_dfiles->lineEditFileNew->text(); - - QFileInfo fi2(m_file2); + // TODO put htis at the right place !!! + labelCurrentMetric->setText( tr("Current metric: %1").arg( met->getName() ) ); - // check if directory must be "rescanned" ? - if ( m_file2path != fi2.absoluteDir().absolutePath() ) - { - m_file2path = fi2.absoluteDir().absolutePath(); - m_lFiles2 = fi2.absoluteDir().entryList(QString("*.rgb;*.gli;*.rgba;*.sgi;*.int;*.inta;*.png;*.jpg").split(";"), QDir::Files | QDir::Readable,QDir::Time | QDir::Reversed); - } - m_newFile2 = false; - openModified(m_file2); - computeDiff = true; - } + met->checkDifferences(m_file1,m_file2); - // enable/disable next/prev action if needed - if (m_lFiles1.size() < 2 || m_lFiles2.size() < 2) + if ( !met->isValid() ) { - actionNext->setEnabled(false); - actionPrev->setEnabled(false); - } - else - { - actionNext->setEnabled(true); - actionPrev->setEnabled(true); + QMessageBox::information( this, PACKAGE_NAME,tr("Can't display difference, more information in the log panel ...") ); + return; } - // setup the window title with filename - if (computeDiff) - { - updateTitle(); - computeDifferencePixels(); + updateImage1( met->getImage1() ); + updateImage2( met->getImage2() ); + updateDifference( met->getImageDifference() ); + m_maskDiffImage = met->getImageMask(); + graphicsView1->setMask(m_maskDiffImage); + graphicsView2->setMask(m_maskDiffImage); + on_actionFitToWindow_triggered(); - // reset the view - if (m_displayOriginalImage) - on_actionOriginalImage_toggled(true); - else if (m_displayModifiedImage) - on_actionModifiedImage_toggled(true); - else - on_actionDifferenceImage_toggled(true); - } + widgetProperties->displayData(met); + + updateSmileyStatus(); + showRGBHistogramNew(); + updateDisplay(); } -void DiffImgWindow::acceptFiles(bool force) +void DiffImgWindow::acceptFiles() { - if (m_file1 != m_dfiles->lineEditFileBase->text() || force) - { - m_file1 = m_dfiles->lineEditFileBase->text(); - m_newFile1 = true; - } + m_dfiles->getCurrentFiles(m_file1,m_file2); - if (m_file2 != m_dfiles->lineEditFileNew->text() || force) - { - m_file2 = m_dfiles->lineEditFileNew->text(); - m_newFile2 = true; - } - computeDifference(); + updateTitle(); + computeDifferenceNew(); } void DiffImgWindow::on_actionDualPanel_toggled(bool val) @@ -508,51 +470,25 @@ setModeDualPanel(m_displayDualPanel); // enable/disable some actions - actionModifiedImage->setEnabled(!m_displayDualPanel); + actionImage2->setEnabled(!m_displayDualPanel); // if dual panel mode => force original image display if (m_displayDualPanel) - actionOriginalImage->trigger(); + actionImage1->trigger(); } -void DiffImgWindow::computeDifferencePixels() -{ - if ( m_sourceImage.size() != m_destinationImage.size() ) - { - QMessageBox::information( this, tr("Image Viewer"),tr("Cannot display difference, image have different size (%1x%2/%3x%4)").arg( m_sourceImage.size().width() ).arg( m_sourceImage.size().height() ).arg( m_destinationImage.size().width() ).arg( m_destinationImage.size().height() ) ); - return; - } - - // compute difference - MiscFunctions::computeDifferencePixels(m_sourceImage, m_destinationImage, *m_diffRes, m_maskOpacity, true, m_diffMethod ); - - int width = m_sourceImage.width(); - int height = m_sourceImage.height(); - - QString percent = QString().sprintf( "%.1f",m_diffRes->nbErr * 100.0f / (width * height) ); - labelNbDiff->setText( QString("%1 (%2%)").arg( QString::number(m_diffRes->nbErr) ).arg(percent) ); - labelMeanDiff->setText( QString::number(m_diffRes->meanError) ); - labelRMSDiff->setText( QString::number(m_diffRes->rmsDiff) ); - - //labelMeanPixelDiff->setText(QString::number(meanPixelError)); - labelStandardDeviation->setText( QString::number(m_diffRes->stantdardDeviation) ); - labelMinError->setText( QString::number(m_diffRes->minError) ); - labelMaxError->setText( QString::number(m_diffRes->maxError) ); - - m_diffImageThumbnail = m_diffRes->diffImage.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_diffImageBuffer = m_diffImageThumbnail; - m_thbSize = m_diffImageThumbnail.size(); +//------------------------------------------------------------------------- - // set default iconsize for pushbutton - pushButtonDifference->setIconSize( m_diffImageBuffer.size() ); - pushButtonDifference->setIcon( QPixmap::fromImage(m_diffImageBuffer) ); +void DiffImgWindow::updateSmileyStatus() +{ + BaseMetric *met = MetricsManager::getMetrics()[m_metricType]; // setup the emoticon - if (m_diffRes->nbErr == 0) + if ( !met->getPixelError() ) { labelSmiley->setPixmap( QPixmap(":/diffimg/allgood.png") ); } - else if (m_enableThreshold && m_diffRes->rmsDiff <= m_RMSThreshold) + else if ( m_compareWithThreshold && met->selectedStatsIsValid() ) { labelSmiley->setPixmap( QPixmap(":/diffimg/somebad.png") ); } @@ -560,303 +496,204 @@ { labelSmiley->setPixmap( QPixmap(":/diffimg/bad.png") ); } - - if (m_displayDiff) - recalculateResult(); - - showRGBHistogram(); } //------------------------------------------------------------------------- -void DiffImgWindow::displayPosition(const QPoint & pos) +void DiffImgWindow::openFile1(const QString &fileName) { - ScrollImageWidget *scrollAreaImage = qobject_cast( sender() ); - if (!scrollAreaImage) - scrollAreaImage = scrollAreaImage1; - - QSize srcSize = m_diffRes->diffImage.size(); - QSize vs = scrollAreaImage->viewport()->size(); - float zoomFactor = scrollAreaImage->getZoomFactor(); - - int offx = (int)( ( scrollAreaImage->horizontalScrollBar()->value() ) / zoomFactor ); - int offy = (int)( ( scrollAreaImage->verticalScrollBar()->value() ) / zoomFactor ); - - int decalx = 0; - if ( srcSize.width() * zoomFactor < vs.width() ) - decalx = (int)(vs.width() - srcSize.width() * zoomFactor) / 2; - - int decaly = 0; - if ( srcSize.height() * zoomFactor < vs.height() ) - decaly = (int)(vs.height() - srcSize.height() * zoomFactor) / 2; - - int posx = (int)(pos.x() / zoomFactor + offx - decalx / zoomFactor + 0.5); - int posy = (int)(pos.y() / zoomFactor + offy - decaly / zoomFactor + 0.5); - - labelValueZoom->setText( QString::number(zoomFactor) ); - - if ( posx >=0 && posx < m_sourceImage.width() && posy >= 0 && posy < m_sourceImage.height() ) - { - labelPosX->setText( QString::number(posx) ); - labelPosY->setText( QString::number(posy) ); + if ( fileName.isEmpty() ) + return; - if (scrollAreaImage == scrollAreaImage1) // mode one panel - { - if (m_displayOriginalImage) - { - labelValueR->setText( QString::number( qRed( m_sourceImage.pixel(posx,posy) ) ) ); - labelValueV->setText( QString::number( qGreen( m_sourceImage.pixel(posx,posy) ) ) ); - labelValueB->setText( QString::number( qBlue( m_sourceImage.pixel(posx,posy) ) ) ); - } - else if (m_displayModifiedImage) - { - labelValueR->setText( QString::number( qRed( m_destinationImage.pixel(posx,posy) ) ) ); - labelValueV->setText( QString::number( qGreen( m_destinationImage.pixel(posx,posy) ) ) ); - labelValueB->setText( QString::number( qBlue( m_destinationImage.pixel(posx,posy) ) ) ); - } - else if (m_displayDifferenceImage) - { - labelValueR->setText( QString::number(qRed( m_diffRes->diffImage.pixel(posx,posy) ) - 128) ); - labelValueV->setText( QString::number(qGreen( m_diffRes->diffImage.pixel(posx,posy) ) - 128) ); - labelValueB->setText( QString::number(qBlue( m_diffRes->diffImage.pixel(posx,posy) ) - 128) ); - } - } - else // mode two panel - { - labelValueR->setText( QString::number( qRed( m_destinationImage.pixel(posx,posy) ) ) ); - labelValueV->setText( QString::number( qGreen( m_destinationImage.pixel(posx,posy) ) ) ); - labelValueB->setText( QString::number( qBlue( m_destinationImage.pixel(posx,posy) ) ) ); - } - } - else + QImage image(fileName); + if ( image.isNull() ) { - labelPosX->setText(""); - labelPosY->setText(""); - labelValueR->setText(""); - labelValueV->setText(""); - labelValueB->setText(""); + QMessageBox::information( this, tr("Image Viewer"),tr("Cannot load %1.").arg(fileName) ); + return; } + updateImage1(image); } -//------------------------------------------------------------------------- - -void DiffImgWindow::displayNavigator() +void DiffImgWindow::updateImage1(const QImage &image) { - if ( m_diffImageBuffer.isNull() || m_sourceImageThumbnail.isNull() || m_destinationImageThumbnail.isNull() || m_diffImageThumbnail.isNull() ) - return; + m_image1 = image; + m_image1Thumbnail = m_image1.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - ScrollImageWidget *scrollAreaImage = qobject_cast( sender() ); - if (!scrollAreaImage) - scrollAreaImage = scrollAreaImage1; + //m_resultImage1 = QImage(m_image1.size(), QImage::Format_ARGB32); - // window is hide - if (!m_displayDualPanel && scrollAreaImage == scrollAreaImage2) - return; + // set default iconsize for pushbutton + pushButtonFile1->setIconSize( m_image1Thumbnail.size() ); + pushButtonFile1->setIcon( QPixmap::fromImage(m_image1Thumbnail) ); - QSize vs = scrollAreaImage->viewport()->size(); - QSize thbSize = m_diffImageThumbnail.size(); - QSize srcSize = m_diffRes->diffImage.size(); - float ratio = thbSize.width() / (float)srcSize.width(); - float zoomFactor = scrollAreaImage->getZoomFactor(); + //labelSize->setText( QString("%1x%2").arg( m_sourceImage.size().width() ).arg( m_sourceImage.size().height() ) ); - QPainter painter(&m_diffImageBuffer); + // init of the +// scrollAreaImage1->setImage(m_sourceImage); + graphicsView1->setImage(m_image1); - if (m_displayOriginalImage) - painter.drawImage(0, 0, m_sourceImageThumbnail); - else if (m_displayModifiedImage) - painter.drawImage(0, 0, m_destinationImageThumbnail); - else if (m_displayDifferenceImage) - painter.drawImage(0, 0, m_diffImageThumbnail); - - int offx = (int)( ( scrollAreaImage->horizontalScrollBar()->value() ) / zoomFactor * ratio ); - int offy = (int)( ( scrollAreaImage->verticalScrollBar()->value() ) / zoomFactor * ratio ); - - if (offx <0) - offx = 0; - if (offy <0) - offy = 0; - - int sx = (int)(vs.width() / zoomFactor * ratio); - int sy = (int)(vs.height() / zoomFactor * ratio); - - if (sx >= thbSize.width() - 1) - sx = thbSize.width() - 1; - if (sy >= thbSize.height() - 1) - sy = thbSize.height() - 1; - - QPen pen(Qt::red, 2); + // m_size = m_image1.size(); + on_actionFitToWindow_triggered(); +} - painter.setPen(pen); - painter.drawRect(offx, offy, sx, sy); +void DiffImgWindow::updateDisplay() +{ + BaseMetric *met = MetricsManager::getMetrics()[m_metricType]; - if (m_displayOriginalImage) - { - pushButtonOriginal->setIcon( QPixmap::fromImage(m_diffImageBuffer) ); - } - else if (m_displayModifiedImage) - { - pushButtonModified->setIcon( QPixmap::fromImage(m_diffImageBuffer) ); - } - else if (m_displayDifferenceImage) - { - pushButtonDifference->setIcon( QPixmap::fromImage(m_diffImageBuffer) ); - } -} + // always update image2 + QImage img2; + if (m_applyGain || m_applyOffset) + img2 = met->getImage2WithGain(m_currentGain,m_currentOffset); + else + img2 = m_image2; + graphicsView2->setImage(img2); -//------------------------------------------------------------------------- + graphicsView1->show(); -void DiffImgWindow::openOriginal(const QString &fileName) -{ - if ( !fileName.isEmpty() ) + // new mode + if (m_displayDualPanel) { - QImage image(fileName); - if ( image.isNull() ) + graphicsView2->show(); + graphicsView2->setShowOverview(false); + if (m_currentDisplayType == TYPE_ORIGINAL) { - QMessageBox::information( this, tr("Image Viewer"),tr("Cannot load %1.").arg(fileName) ); - return; + QImage img1; + if (m_applyGain || m_applyOffset) + img1 = met->getImage1WithGain(m_currentGain,m_currentOffset); + else + img1 = m_image1; + graphicsView1->setImage(img1); + } + else + { + QImage img1; + if (m_applyGain || m_applyOffset) + img1 = met->getImageDifferenceWithGain(m_currentGain,m_currentOffset); + else + img1 = m_diffImage; + graphicsView1->setImage(img1); } - - m_sourceImage = image; - m_sourceImageThumbnail = m_sourceImage.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_resultImage1 = QImage(m_sourceImage.size(), QImage::Format_ARGB32); - - // set default iconsize for pushbutton - pushButtonOriginal->setIconSize( m_sourceImageThumbnail.size() ); - pushButtonOriginal->setIcon( QPixmap::fromImage(m_sourceImageThumbnail) ); - labelSize->setText( QString("%1x%2").arg( m_sourceImage.size().width() ).arg( m_sourceImage.size().height() ) ); - - // init of the - scrollAreaImage1->setImage(m_sourceImage); - m_size = m_sourceImage.size(); - on_actionFitToWindow_triggered(); } -} - -//------------------------------------------------------------------------- - -void DiffImgWindow::openModified(const QString &fileName) -{ - if ( !fileName.isEmpty() ) + else { - QImage image(fileName); - if ( image.isNull() ) + graphicsView2->hide(); + graphicsView2->setShowOverview(false); + QImage img1; + if (m_currentDisplayType == TYPE_ORIGINAL) { - QMessageBox::information( this, tr("Image Viewer"),tr("Cannot load %1.").arg(fileName) ); - return; + if (m_applyGain || m_applyOffset) + img1 = met->getImage1WithGain(m_currentGain,m_currentOffset); + else + img1 = m_image1; } - - m_destinationImage = image; - m_destinationImageThumbnail = m_destinationImage.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_resultImage2 = QImage(m_destinationImage.size(), QImage::Format_ARGB32); - - // set default iconsize for pushbutton - pushButtonModified->setIconSize( m_destinationImageThumbnail.size() ); - pushButtonModified->setIcon( QPixmap::fromImage(m_destinationImageThumbnail) ); - - if (m_displayDualPanel) + else if (m_currentDisplayType == TYPE_MODIFIED) { - scrollAreaImage2->setImage(m_destinationImage); - - synchronizePanels(); + if (m_applyGain || m_applyOffset) + img1 = met->getImage2WithGain(m_currentGain,m_currentOffset); + else + img1 = m_image2; + } + else + { + if (m_applyGain || m_applyOffset) + img1 = met->getImageDifferenceWithGain(m_currentGain,m_currentOffset); + else + img1 = m_diffImage; } + graphicsView1->setImage(img1); } } //------------------------------------------------------------------------- -void DiffImgWindow::recalculateResult() +void DiffImgWindow::openFile2(const QString &fileName) { - if (m_displayDualPanel) - { - if (m_displayOriginalImage) - recalculateResult(m_sourceImage, m_resultImage1, scrollAreaImage1); - else if (m_displayDifferenceImage) - recalculateResult(m_diffRes->diffImage, m_resultImage1, scrollAreaImage1); - } - else + if ( fileName.isEmpty() ) + return; + + QImage image(fileName); + if ( image.isNull() ) { - if (m_displayOriginalImage) - recalculateResult(m_sourceImage, m_resultImage1, scrollAreaImage1); - else if (m_displayModifiedImage) - recalculateResult(m_destinationImage, m_resultImage1, scrollAreaImage1); - else if (m_displayDifferenceImage) - recalculateResult(m_diffRes->diffImage, m_resultImage1, scrollAreaImage1); + QMessageBox::information( this, tr("Image Viewer"),tr("Cannot load %1.").arg(fileName) ); + return; } - recalculateResult(m_destinationImage, m_resultImage2, scrollAreaImage2); - - displayNavigator(); + updateImage2(image); } -//------------------------------------------------------------------------- - -void DiffImgWindow::recalculateResult(const QImage &inputImage, QImage &resultImage, ScrollImageWidget *scrollAreaImage) +void DiffImgWindow::updateImage2(const QImage &image) { - if ( inputImage.isNull() || resultImage.isNull() ) - return; - - QPainter painter(&resultImage); - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(resultImage.rect(), Qt::transparent); - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + m_image2 = image; + m_image2Thumbnail = m_image2.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter.drawImage(0, 0,inputImage ); - - if (m_displayDiff) - { - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); - painter.drawImage(0, 0, m_diffRes->maskDiffImage); - } + // set default iconsize for pushbutton + pushButtonFile2->setIconSize( m_image2Thumbnail.size() ); + pushButtonFile2->setIcon( QPixmap::fromImage(m_image2Thumbnail) ); - painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); - painter.fillRect(resultImage.rect(), Qt::white); - painter.end(); + graphicsView2->setImage(m_image2); + if (m_displayDualPanel) + synchronizePanels(); +} - scrollAreaImage->setImage(resultImage); - displayNavigator(); +void DiffImgWindow::updateDifference(const QImage &image) +{ + m_diffImage = image; + m_diffImageThumbnail = m_diffImage.scaled( (int) defaultThumbnailSize, (int) defaultThumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + pushButtonDifference->setIconSize( m_diffImageThumbnail.size() ); + pushButtonDifference->setIcon( QPixmap::fromImage(m_diffImageThumbnail) ); } //------------------------------------------------------------------------- -void DiffImgWindow::on_actionDifference_toggled(bool val) +void DiffImgWindow::on_actionDifferenceMask_toggled(bool val) { - m_displayDiff = val; - recalculateResult(); + m_displayOverlayDiff = val; + graphicsView1->setEnabledMask(m_displayOverlayDiff); + graphicsView2->setEnabledMask(m_displayOverlayDiff); + + updateDisplay(); } //------------------------------------------------------------------------- -void DiffImgWindow::on_actionOriginalImage_toggled(bool val) +void DiffImgWindow::on_actionImage1_toggled(bool val) { m_displayOriginalImage = val; if (m_displayOriginalImage) { + m_currentDisplayType = TYPE_ORIGINAL; + showRGBHistogramNew(); m_displayModifiedImage = false; m_displayDifferenceImage = false; - // restore other thumbnails - if ( !m_destinationImageThumbnail.isNull() ) - pushButtonModified->setIcon( QPixmap::fromImage(m_destinationImageThumbnail) ); - if ( !m_diffImageThumbnail.isNull() ) - pushButtonDifference->setIcon( QPixmap::fromImage(m_diffImageThumbnail) ); - recalculateResult(); + if ( !pushButtonFile1->isChecked() ) + pushButtonFile1->setChecked(true); + + graphicsView1->setScale( graphicsView2->getScale() ); + graphicsView1->setCenter( graphicsView2->getCenter() ); + + updateDisplay(); } } //------------------------------------------------------------------------- -void DiffImgWindow::on_actionModifiedImage_toggled(bool val) +void DiffImgWindow::on_actionImage2_toggled(bool val) { m_displayModifiedImage = val; if (m_displayModifiedImage) { + m_currentDisplayType = TYPE_MODIFIED; + showRGBHistogramNew(); m_displayOriginalImage = false; m_displayDifferenceImage = false; - // restore other thumbnails - pushButtonOriginal->setIcon( QPixmap::fromImage(m_sourceImageThumbnail) ); - pushButtonDifference->setIcon( QPixmap::fromImage(m_diffImageThumbnail) ); - recalculateResult(); + if ( !pushButtonFile2->isChecked() ) + pushButtonFile2->setChecked(true); + + graphicsView2->setScale( graphicsView1->getScale() ); + graphicsView2->setCenter( graphicsView1->getCenter() ); + + updateDisplay(); } } @@ -867,13 +704,14 @@ m_displayDifferenceImage = val; if (m_displayDifferenceImage) { + m_currentDisplayType = TYPE_DIFFERENCE; + showRGBHistogramNew(); m_displayOriginalImage = false; m_displayModifiedImage = false; + if ( !pushButtonDifference->isChecked() ) + pushButtonDifference->setChecked(true); - // restore other thumbnails - pushButtonModified->setIcon( QPixmap::fromImage(m_destinationImageThumbnail) ); - pushButtonOriginal->setIcon( QPixmap::fromImage(m_sourceImageThumbnail) ); - recalculateResult(); + updateDisplay(); } } @@ -881,34 +719,32 @@ void DiffImgWindow::on_actionFitToWindow_triggered() { - scrollAreaImage1->fitToWindow(); - if (m_displayDualPanel) - scrollAreaImage2->fitToWindow(); + graphicsView1->fitScale(); } //------------------------------------------------------------------------- void DiffImgWindow::on_actionFullResolution_triggered() { - scrollAreaImage1->setZoomFactor(1.0); - scrollAreaImage2->setZoomFactor(1.0); + graphicsView1->resetScale(); + graphicsView2->resetScale(); } //------------------------------------------------------------------------- -void DiffImgWindow::on_pushButtonOriginal_pressed() +void DiffImgWindow::on_pushButtonFile1_pressed() { - actionOriginalImage->setChecked(true); + actionImage1->setChecked(true); } //------------------------------------------------------------------------- -void DiffImgWindow::on_pushButtonModified_pressed() +void DiffImgWindow::on_pushButtonFile2_pressed() { if (m_displayDualPanel) return; - actionModifiedImage->setChecked(true); + actionImage2->setChecked(true); } //------------------------------------------------------------------------- @@ -922,19 +758,16 @@ void DiffImgWindow::resetView() { - QPixmap reset = QPixmap( m_diffImageBuffer.size() ); - reset.fill( QColor(0,0,0,0) ); - - pushButtonOriginal->setIcon(reset); - pushButtonModified->setIcon(reset); - pushButtonDifference->setIcon(reset); + pushButtonFile1->setIcon( QIcon(":/diffimg/original.png") ); + pushButtonFile2->setIcon( QIcon(":/diffimg/modified.png") ); + pushButtonDifference->setIcon( QIcon(":/diffimg/diffimg.png") ); } //------------------------------------------------------------------------- void DiffImgWindow::setModeSingleImage() { - pushButtonModified->setEnabled(false); + pushButtonFile2->setEnabled(false); pushButtonDifference->setEnabled(false); } @@ -942,7 +775,7 @@ void DiffImgWindow::setModeDualImage() { - pushButtonModified->setEnabled(true); + pushButtonFile2->setEnabled(true); pushButtonDifference->setEnabled(true); } @@ -953,25 +786,51 @@ m_displayDualPanel = val; if (m_displayDualPanel) { - scrollAreaImage2->show(); - pushButtonModified->setEnabled(false); + // for a problem of incorrect layout (??), I have to hide both view before showing them + graphicsView2->hide(); + graphicsView1->hide(); + + graphicsView2->show(); + graphicsView1->show(); + + pushButtonFile2->setEnabled(false); } else { - scrollAreaImage2->hide(); - pushButtonModified->setEnabled(true); + graphicsView2->hide(); + pushButtonFile2->setEnabled(true); } synchronizePanels(); } +void DiffImgWindow::etHop() +{ + graphicsView2->parentWidget()->layout()->invalidate(); +} + +//------------------------------------------------------------------------- + +void DiffImgWindow::syncPanels() +{ + ImageView *iv = qobject_cast( sender() ); + if (iv == graphicsView1) + { + graphicsView2->setScale( graphicsView1->getScale() ); + graphicsView2->setCenter( graphicsView1->getCenter() ); + } + else if (iv == graphicsView2) + { + graphicsView1->setScale( graphicsView2->getScale() ); + graphicsView1->setCenter( graphicsView2->getCenter() ); + } +} + //------------------------------------------------------------------------- void DiffImgWindow::synchronizePanels() { // reference is panel1 - scrollAreaImage2->setScrollMaximum( scrollAreaImage1->getScrollMaximum() ); - scrollAreaImage2->setZoomFactor( scrollAreaImage1->getZoomFactor() ); - scrollAreaImage2->setScrollValue( scrollAreaImage1->getScrollValue() ); + graphicsView2->setScale( graphicsView1->getScale() ); } void DiffImgWindow::updateApplicationIdentity() @@ -1003,9 +862,10 @@ // update prefs if needed m_about->horizontalSliderOpacity->setValue(m_maskOpacity); m_about->setCurrentLanguage(m_currentLanguage); - m_about->checkBoxEnableThreshold->setChecked(m_enableThreshold); - m_about->lineEditRMSThreshold->setText( QString::number(m_RMSThreshold) ); - m_about->setCurrentDiffMethod(m_diffMethod); + + m_about->groupBoxEnableThreshold->setChecked(m_compareWithThreshold); + m_about->comboBoxMetrics->setCurrentIndex(m_metricType); + m_about->comboBoxOutputParam->setCurrentIndex(m_thresholdType); // splashscreen m_about->checkBoxSplashscreenAtStartup->setChecked(m_splashscreenAtStartup); @@ -1023,61 +883,92 @@ //--------------------------------------------------------------------------------------------------------------------------------- -void DiffImgWindow::initHisto() +void DiffImgWindow::initHistoNew() { widgetHisto->detachItems(); + BaseMetric *met = MetricsManager::getMetrics()[m_metricType]; + // histogram - widgetHisto->setAxisScale(QwtPlot::xBottom,m_diffRes->minError,m_diffRes->maxError); + //widgetHisto->setAxisScale(QwtPlot::xBottom,met->getMinError(),met->getMaxError()); widgetHisto->setCanvasBackground (Qt::white); + int nbChannels = 0; + + if (m_currentDisplayType == TYPE_ORIGINAL) + { + nbChannels = met->getImage1Channels(); + widgetHisto->setAxisScale( QwtPlot::xBottom,met->getMinImage1(),met->getMaxImage1() ); + } + else if (m_currentDisplayType == TYPE_MODIFIED) + { + nbChannels = met->getImage2Channels(); + widgetHisto->setAxisScale( QwtPlot::xBottom,met->getMinImage2(),met->getMaxImage2() ); + } + else + { + nbChannels = met->getDifferenceChannels(); + widgetHisto->setAxisScale( QwtPlot::xBottom,met->getMinError(),met->getMaxError() ); + } - // prepare RGB curves - m_widgetHistoCurveR = new ChannelCurve("Red"); - m_widgetHistoCurveR->setColor(Qt::red); + if (nbChannels == 1) + { + // prepare RGB curves + m_widgetHistoCurveR = new ChannelCurve("Value"); + m_widgetHistoCurveR->setColor(Qt::black); + } + else + { + // prepare RGB curves + m_widgetHistoCurveR = new ChannelCurve("Red"); + m_widgetHistoCurveR->setColor(Qt::red); - m_widgetHistoCurveG = new ChannelCurve("Green"); - m_widgetHistoCurveG->setColor(Qt::green); + m_widgetHistoCurveG = new ChannelCurve("Green"); + m_widgetHistoCurveG->setColor(Qt::green); - m_widgetHistoCurveB = new ChannelCurve("Blue"); - m_widgetHistoCurveB->setColor(Qt::blue); + m_widgetHistoCurveB = new ChannelCurve("Blue"); + m_widgetHistoCurveB->setColor(Qt::blue); + } } -void DiffImgWindow::showRGBHistogram() +void DiffImgWindow::showRGBHistogramNew() { - initHisto(); - setPlots(m_diffRes->valueR,m_diffRes->valueG,m_diffRes->valueB); + initHistoNew(); + applyHisto(); } -void DiffImgWindow::setPlots(double *red,double *green, double *blue) +void DiffImgWindow::applyHisto() { - // prepare axes - int nItems = 2 * 256; - double *index = new double[nItems]; - for(int i = 0; i * pHistos = NULL; - // set plot curves - if (red) - { - red[256] = 0; // filter null values - m_widgetHistoCurveR->setSamples(index,red,nItems); - m_widgetHistoCurveR->attach(widgetHisto); - } + if (m_currentDisplayType == TYPE_ORIGINAL) + pHistos = &met->getHistogramImage1(); + else if (m_currentDisplayType == TYPE_MODIFIED) + pHistos = &met->getHistogramImage2(); + else + pHistos = &met->getHistogramImageDiff(); - if (green) + for (int i = 0; i < (*pHistos).size(); i++) { - green[256] = 0; // filter null values - m_widgetHistoCurveG->setSamples(index,green,nItems); - m_widgetHistoCurveG->attach(widgetHisto); - } + if ( (*pHistos)[i].isEmpty() ) + continue; - if (blue) - { - blue[256] = 0; // filter null values - m_widgetHistoCurveB->setSamples(index,blue,nItems); - m_widgetHistoCurveB->attach(widgetHisto); + if (i==0) + { + m_widgetHistoCurveR->setSamples( (*pHistos)[i] ); + m_widgetHistoCurveR->attach(widgetHisto); + } + else if (i == 1) + { + m_widgetHistoCurveR->setSamples( (*pHistos)[i] ); + m_widgetHistoCurveR->attach(widgetHisto); + } + else if (i == 2) + { + m_widgetHistoCurveB->setSamples( (*pHistos)[i] ); + m_widgetHistoCurveB->attach(widgetHisto); + } } - delete [] index; // plot the histogram widgetHisto->replot(); @@ -1085,7 +976,7 @@ void DiffImgWindow::restart() { - QProcess::startDetached( qApp->arguments()[0], qApp->arguments() ); + QProcess::startDetached( qApp->arguments()[0], qApp->arguments().mid(1) ); QApplication::exit(0); } @@ -1110,23 +1001,214 @@ bool hasDifference = false; hasDifference |= ( m_maskOpacity != m_about->horizontalSliderOpacity->value() ); - hasDifference |= ( m_enableThreshold != m_about->checkBoxEnableThreshold->isChecked() ); - hasDifference |= ( m_RMSThreshold != m_about->lineEditRMSThreshold->text().toFloat() ); - hasDifference |= ( m_diffMethod != m_about->comboBoxMethod->itemData( m_about->comboBoxMethod->currentIndex() ).toInt() ); + + hasDifference |= ( m_compareWithThreshold != m_about->groupBoxEnableThreshold->isChecked() ); + hasDifference |= ( m_metricType != m_about->comboBoxMetrics->currentIndex() ); + hasDifference |= ( m_thresholdType != m_about->comboBoxOutputParam->currentIndex() ); if (hasDifference) { m_maskOpacity = m_about->horizontalSliderOpacity->value(); - m_enableThreshold = m_about->checkBoxEnableThreshold->isChecked(); - m_RMSThreshold = m_about->lineEditRMSThreshold->text().toFloat(); - m_diffMethod = m_about->comboBoxMethod->itemData( m_about->comboBoxMethod->currentIndex() ).toInt(); - computeDifference(true); + graphicsView1->setMaskOpacity(m_maskOpacity / 100.0f); + graphicsView2->setMaskOpacity(m_maskOpacity / 100.0f); + + m_compareWithThreshold = m_about->groupBoxEnableThreshold->isChecked(); + m_metricType = m_about->comboBoxMetrics->currentIndex(); + m_thresholdType = m_about->comboBoxOutputParam->currentIndex(); + + computeDifferenceNew(); } - labelMethod->setText( m_about->getStringForMethod(m_diffMethod) ); + saveSettings(); } void DiffImgWindow::on_actionRefresh_triggered() { - acceptFiles(true); + acceptFiles(); +} + +void DiffImgWindow::displayMousePosition(const QPointF &p) +{ + QPoint pt( (int)p.x(),(int)p.y() ); + if ( pt.isNull() ) + m_labelPos->setText(""); + else + m_labelPos->setText( QString("%1x%2").arg( pt.x() ).arg( pt.y() ) ); + + // display a marker if needed + ImageView *view = qobject_cast( sender() ); + if (!view) + return; + + graphicsView1->setEnabledMarker(view != graphicsView1); + graphicsView2->setEnabledMarker(view != graphicsView2); + + // display pixel infos + QString infos; + if ( !pt.isNull() ) + { + BaseMetric *met = MetricsManager::getMetrics()[m_metricType]; + if (m_displayDualPanel) + { + if (m_currentDisplayType == TYPE_ORIGINAL) + { + infos += met->getImage1Data(pt); + infos += " | "; + infos += met->getImage2Data(pt); + } + else + { + infos += met->getErrorData(pt); + infos += " | "; + infos += met->getImage2Data(pt); + } + } + else + { + if (m_currentDisplayType == TYPE_ORIGINAL) + { + infos += met->getImage1Data(pt); + } + else if (m_currentDisplayType == TYPE_MODIFIED) + { + infos += met->getImage2Data(pt); + } + else + { + infos += met->getErrorData(pt); + } + } + } + m_labelInfos->setText(infos); +} + +void DiffImgWindow::displayZoomFactor(qreal zoom) +{ + m_labelZoom->setText( tr(" Scale x%1 ").arg( zoom, 3, 'g', 3 ) ); +} + +void DiffImgWindow::on_sliderGain_valueChanged(int val) +{ + m_currentGain = val / 100.0f; + doubleSpinBoxGain->setValue( (double)m_currentGain ); + m_timerUpdate->start(updateWaitTime); +} + +void DiffImgWindow::on_doubleSpinBoxGain_valueChanged(double val) +{ + m_currentGain = val; + sliderGain->setValue( (int)(val * 100) ); +} + +void DiffImgWindow::on_sliderOffset_valueChanged(int val) +{ + m_currentOffset = val; + doubleSpinBoxOffset->setValue( (double)m_currentOffset ); + m_timerUpdate->start(updateWaitTime); + +// if (m_lyr) +// m_lyr->setOffset(currentOffset_); +// +// displayImage(); +} + +void DiffImgWindow::on_doubleSpinBoxOffset_valueChanged(double val) +{ + m_currentOffset = val; + sliderOffset->setValue( (int)(val) ); +} + +void DiffImgWindow::on_checkBoxGain_toggled(bool val) +{ + m_applyGain = val; + if (m_applyGain) + { + on_sliderGain_valueChanged( sliderGain->value() ); + } + else + { + m_currentGain = 1.0f; + updateDisplay(); + } +} + +void DiffImgWindow::on_checkBoxOffset_toggled(bool val) +{ + m_applyOffset = val; + if (m_applyOffset) + { + on_sliderOffset_valueChanged( sliderOffset->value() ); + } + else + { + m_currentOffset = 0.0; + updateDisplay(); + } +} + +// ------------- Drag and drop ----------- + +void DiffImgWindow::dragEnterEvent(QDragEnterEvent *event) +{ + const QMimeData* mimeData = event->mimeData(); + + if ( !mimeData->hasUrls() ) + { + event->ignore(); + return; + } + + QList urls = mimeData->urls(); + + if(urls.count() != 2) + { + event->ignore(); + return; + } + + QUrl url = urls.at(0); + QString filename = url.toLocalFile(); + + // We don't test extension + if ( !QFileInfo(filename).exists() ) + { + event->ignore(); + return; + } + + if ( !QFileInfo(filename).isFile() ) + { + event->ignore(); + return; + } + + event->acceptProposedAction(); +} + +void DiffImgWindow::dragMoveEvent(QDragMoveEvent *event) +{ + if ( event->source() == this ) + { + event->setDropAction(Qt::MoveAction); + event->accept(); + } + else + { + event->acceptProposedAction(); + } +} + +void DiffImgWindow::dropEvent(QDropEvent *event) +{ + const QMimeData* mimeData = event->mimeData(); + QList urls = mimeData->urls(); + + if (urls.size()>1) + { + QString file1 = urls.at(0).toLocalFile(); + QString file2 = urls.at(1).toLocalFile(); + m_dfiles->setFile1(file1); + m_dfiles->setFile2(file2); + acceptFiles(); + } } diff -Nru diffimg-1.5.0/src/DiffImgWindow.h diffimg-2.0.0/src/DiffImgWindow.h --- diffimg-1.5.0/src/DiffImgWindow.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/DiffImgWindow.h 2013-05-17 18:54:20.000000000 +0000 @@ -1,183 +1,208 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _DIFFIMGWINDOW_H_ -#define _DIFFIMGWINDOW_H_ - -#include -#include "ui_DiffImgWindow.h" - -// forward declarations -class FilesDialog; -class ScrollImageWidget; -class AboutDialog; -class ChannelCurve; - -struct DiffStruct; - -class DiffImgWindow : public QMainWindow, private Ui::DiffImgWindowClass -{ - Q_OBJECT - -public: - - DiffImgWindow(QWidget *parent = 0, Qt::WFlags flags = 0); - ~DiffImgWindow(); - -public slots: - - void setFiles(const QString &original,const QString &modified); - void load(); - - void on_actionDifference_toggled(bool val); - void on_actionOriginalImage_toggled(bool val); - void on_actionModifiedImage_toggled(bool val); - void on_actionDifferenceImage_toggled(bool val); - - void on_actionQuit_triggered(); - void on_actionFitToWindow_triggered(); - void on_actionFullResolution_triggered(); - - void on_actionRefresh_triggered(); - - void on_actionNext_triggered(); - void on_actionPrev_triggered(); - - void on_actionOpen_triggered(); - - void on_actionDualPanel_toggled(bool val); - - void openOriginal(const QString &fileName); - void openModified(const QString &fileName); - - void displayNavigator(); - void displayPosition(const QPoint & pos); - - void computeDifference(bool force = false); - - //void computeDifferencePixelsOld(); - void computeDifferencePixels(); - - void on_pushButtonOriginal_pressed(); - void on_pushButtonModified_pressed(); - void on_pushButtonDifference_pressed(); - - void resetView(); - void setModeSingleImage(); - void setModeDualImage(); - - void setModeDualPanel(bool val); - - void synchronizePanels(); - - void on_actionAbout_triggered(); - void on_actionPreferences_triggered(); - - void printToLog(const QString & mess); - - void restart(); - void setPreferences(); - -private slots: - - void acceptFiles(bool force = false); - -private: - - void updateUi(); - void updateAbout(); - - void saveSettings(); - void loadSettings(); - - void updateTitle(); - - int nextValidIndex(int curr); - int prevValidIndex(int curr); - int getNextValidIndex(int curr, int increment = 1); - void updateApplicationIdentity(); - void initHisto(); - void showRGBHistogram(); - void setPlots(double red[],double green[], double blue[]); // show the histogram plot - void recalculateResult(); - void recalculateResult(const QImage &inputImage, QImage &resultImage, ScrollImageWidget *scrollAreaImage); - - bool m_displayDiff; - bool m_displayOriginalImage; - bool m_displayModifiedImage; - bool m_displayDifferenceImage; - bool m_displayDualPanel; - - QString m_file1; - QStringList m_lFiles1; - QString m_file1path; - bool m_newFile1; - - QString m_file2; - QStringList m_lFiles2; - QString m_file2path; - bool m_newFile2; - - FilesDialog *m_dfiles; - - QString m_version; - QString m_appName; - bool m_firstTime; - - QImage m_sourceImage; - QImage m_sourceImageThumbnail; - QImage m_destinationImage; - QImage m_destinationImageThumbnail; -/* QImage m_diffRes->diffImage;*/ - QImage m_diffImageThumbnail; - QImage m_diffImageBuffer; - QSize m_thbSize; - QSize m_size; -/* QImage m_diffRes->maskDiffImage;*/ - QImage m_resultImage1; - QImage m_resultImage2; - - QString m_currentLanguage; - bool m_splashscreenAtStartup; - bool m_splashscreenTransparentBackground; - - AboutDialog *m_about; - int m_logLevel; - - ChannelCurve *m_widgetHistoCurveR; - ChannelCurve *m_widgetHistoCurveG; - ChannelCurve *m_widgetHistoCurveB; - -// double m_diffRes->valueR[2*256]; -// double m_diffRes->valueG[2*256]; -// double m_diffRes->valueB[2*256]; -// int m_diffRes->minError; -// int m_diffRes->maxError; - - bool m_resetConfig; - int m_maskOpacity; - bool m_enableThreshold; - int m_diffMethod; - float m_RMSThreshold; - - DiffStruct *m_diffRes; -}; - -#endif // _DIFFIMGWINDOW_H_ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _DIFFIMGWINDOW_H_ +#define _DIFFIMGWINDOW_H_ + +#include +#include "ui_DiffImgWindow.h" + +// forward declarations +class FilesDialog; +class AboutDialog; +class ChannelCurve; +class QLabel; +class QTimer; + +struct DiffStruct; + +class DiffImgWindow : public QMainWindow, private Ui::DiffImgWindowClass +{ + Q_OBJECT + +public: + + enum typImage + { + TYPE_ORIGINAL = 0, + TYPE_MODIFIED, + TYPE_DIFFERENCE + }; + + DiffImgWindow(QWidget *parent = 0, Qt::WFlags flags = 0); + ~DiffImgWindow(); + +public slots: + + void setFiles(const QString &original,const QString &modified); + void load(); + + void on_actionDifferenceMask_toggled(bool val); + void on_actionImage1_toggled(bool val); + void on_actionImage2_toggled(bool val); + void on_actionDifferenceImage_toggled(bool val); + + void on_actionQuit_triggered(); + void on_actionFitToWindow_triggered(); + void on_actionFullResolution_triggered(); + + void on_actionRefresh_triggered(); + + void on_actionNext_triggered(); + void on_actionPrev_triggered(); + + void on_actionOpen_triggered(); + void on_actionHelp_triggered(); + + void on_actionDualPanel_toggled(bool val); + + void openFile1(const QString &fileName); + void openFile2(const QString &fileName); + + void computeDifferenceNew(); + + void on_pushButtonFile1_pressed(); + void on_pushButtonFile2_pressed(); + void on_pushButtonDifference_pressed(); + + void resetView(); + void setModeSingleImage(); + void setModeDualImage(); + + void setModeDualPanel(bool val); + + void synchronizePanels(); + void syncPanels(); + + void on_actionAbout_triggered(); + void on_actionPreferences_triggered(); + + void printToLog(const QString & mess); + + void restart(); + void setPreferences(); + +protected slots: + + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + +private slots: + + void acceptFiles(); + void displayZoomFactor(qreal zoom); + void displayMousePosition(const QPointF &pt); + void etHop(); + + void on_sliderGain_valueChanged(int); + void on_checkBoxGain_toggled(bool); + void on_doubleSpinBoxGain_valueChanged(double); + void on_sliderOffset_valueChanged(int); + void on_checkBoxOffset_toggled(bool); + void on_doubleSpinBoxOffset_valueChanged(double); + + void updateDisplay(); + +private: + + void updateUi(); + void updateAbout(); + + void saveSettings(); + void loadSettings(); + + void updateTitle(); + void updateTooltips(); + + void updateApplicationIdentity(); + void initHistoNew(); + void applyHisto(); + void showRGBHistogramNew(); + + void updateImage1(const QImage &image); + void updateImage2(const QImage &image); + void updateDifference(const QImage &image); + + void updateSmileyStatus(); + + bool m_displayOverlayDiff; + bool m_displayOriginalImage; + bool m_displayModifiedImage; + bool m_displayDifferenceImage; + bool m_displayDualPanel; + + QString m_file1; + QStringList m_lFiles1Deprecated; + QString m_file1pathDeprecated; + bool m_newFile1m_newFile1; + + QString m_file2; + QStringList m_lFiles2m_newFile1; + QString m_file2pathm_newFile1; + bool m_newFile2m_newFile1; + + FilesDialog *m_dfiles; + + QString m_version; + QString m_appName; + bool m_firstTime; + + QImage m_image1; + QImage m_image1Thumbnail; + QImage m_image2; + QImage m_image2Thumbnail; + QImage m_diffImage; + QImage m_diffImageThumbnail; + + QImage m_maskDiffImage; + + QString m_currentLanguage; + bool m_splashscreenAtStartup; + bool m_splashscreenTransparentBackground; + + AboutDialog *m_about; + int m_logLevel; + + ChannelCurve *m_widgetHistoCurveR; + ChannelCurve *m_widgetHistoCurveG; + ChannelCurve *m_widgetHistoCurveB; + + bool m_resetConfig; + int m_maskOpacity; + + bool m_compareWithThreshold; + int m_metricType; + int m_thresholdType; + + DiffStruct *m_diffRes; + int m_currentDisplayType; + QLabel *m_labelZoom; + QLabel *m_labelPos; + QLabel *m_labelInfos; + bool m_applyGain; + bool m_applyOffset; + qreal m_currentGain; + qreal m_currentOffset; + + QTimer *m_timerUpdate; +}; + +#endif // _DIFFIMGWINDOW_H_ diff -Nru diffimg-1.5.0/src/FilesDialog.cpp diffimg-2.0.0/src/FilesDialog.cpp --- diffimg-1.5.0/src/FilesDialog.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/FilesDialog.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,19 +15,33 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ +#include + #include +#include +#include #include "FilesDialog.h" #include "MiscFunctions.h" +#include "LogHandler.h" +#include "FilesManager.h" FilesDialog::FilesDialog(QWidget *parent) : QDialog(parent) { Q_INIT_RESOURCE(diffimg); setupUi(this); + + // add completer to line edit + QCompleter *completerDir = new QCompleter(this); + QDirModel *dirModelDir = new QDirModel(completerDir); + dirModelDir->setFilter(QDir::Dirs); + completerDir->setModel(dirModelDir); + lineEditFile1->setCompleter(completerDir); + lineEditFile2->setCompleter(completerDir); } FilesDialog::~FilesDialog() @@ -49,9 +63,9 @@ } } -void FilesDialog::on_pushButtonFileBase_pressed() +void FilesDialog::on_pushButtonFile1_pressed() { - getPath( lineEditFileBase->text(),lineEditFileNew->text() ); + getPath( lineEditFile1->text(),lineEditFile2->text() ); QString formats = MiscFunctions::getAvailablesImageFormats(); QString file = QFileDialog::getOpenFileName(this, tr("Open File"), @@ -59,14 +73,12 @@ formats); if ( !file.isEmpty() ) - { - lineEditFileBase->setText(file); - } + lineEditFile1->setText(file); } -void FilesDialog::on_pushButtonFileNew_pressed() +void FilesDialog::on_pushButtonFile2_pressed() { - getPath( lineEditFileNew->text(),lineEditFileBase->text() ); + getPath( lineEditFile2->text(),lineEditFile1->text() ); QString formats = MiscFunctions::getAvailablesImageFormats(); QString file = QFileDialog::getOpenFileName(this, tr("Open File"), @@ -74,7 +86,53 @@ formats); if ( !file.isEmpty() ) + lineEditFile2->setText(file); +} + +void FilesDialog::on_lineEditFile1_textChanged ( const QString & text ) +{ + validPath(text,lineEditFile1); +} + +void FilesDialog::on_lineEditFile2_textChanged ( const QString & text ) +{ + validPath(text,lineEditFile2); +} + +void FilesDialog::validPath(const QString &path, QWidget *w) +{ + if (!w) + return; + + if ( !QFileInfo(path).exists() ) + { + QPalette pal; + pal.setColor(QPalette::Text, Qt::red); + w->setPalette(pal); + } + else { - lineEditFileNew->setText(file); + // restore normal palette + QPalette pal; + pal.setColor(QPalette::Text, Qt::black); + w->setPalette(pal); } } + +void FilesDialog::getCurrentFiles(QString &file1,QString &file2) +{ + file1 = lineEditFile1->text(); + file2 = lineEditFile2->text(); + + FilesManager::getCurrentFiles(file1,file2); +} + +void FilesDialog::setFile1(const QString &f) +{ + lineEditFile1->setText(f); +} + +void FilesDialog::setFile2(const QString &f) +{ + lineEditFile2->setText(f); +} diff -Nru diffimg-1.5.0/src/FilesDialog.h diffimg-2.0.0/src/FilesDialog.h --- diffimg-1.5.0/src/FilesDialog.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/FilesDialog.h 2013-05-17 20:03:38.000000000 +0000 @@ -1,50 +1,58 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _DIALOGFILES_H_ -#define _DIALOGFILES_H_ - -#include -#include "ui_FilesDialog.h" - -using namespace Ui; - -class FilesDialog : public QDialog, public FilesDialogClass -{ - Q_OBJECT - -public: - - FilesDialog(QWidget *parent = 0); - ~FilesDialog(); - -public slots: - - void on_pushButtonFileBase_pressed(); - void on_pushButtonFileNew_pressed(); - -private: - - void getPath(const QString &f1,const QString &f2); - - QString m_path; -}; - -#endif // _DIALOGFILES_H_ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _DIALOGFILES_H_ +#define _DIALOGFILES_H_ + +#include +#include "ui_FilesDialog.h" + +using namespace Ui; + +class FilesDialog : public QDialog, public FilesDialogClass +{ + Q_OBJECT + +public: + + FilesDialog(QWidget *parent = 0); + ~FilesDialog(); + + void getCurrentFiles(QString &file1,QString &file2); + + void setFile1(const QString &); + void setFile2(const QString &); + +public slots: + + void on_pushButtonFile1_pressed(); + void on_pushButtonFile2_pressed(); + void on_lineEditFile1_textChanged ( const QString & text ); + void on_lineEditFile2_textChanged ( const QString & text ); + +private: + + void getPath(const QString &f1,const QString &f2); + void validPath(const QString &path, QWidget *w); + + QString m_path; +}; + +#endif // _DIALOGFILES_H_ diff -Nru diffimg-1.5.0/src/FilesManager.cpp diffimg-2.0.0/src/FilesManager.cpp --- diffimg-1.5.0/src/FilesManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/FilesManager.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,175 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include +#include + +#include "FilesManager.h" +#include "MiscFunctions.h" +#include "LogHandler.h" + +QStringList FilesManager::m_lFiles1; +QString FilesManager::m_refPath1; +QString FilesManager::m_refPath2; +QStringList FilesManager::m_lFiles2; + +void FilesManager::getPrevFiles(QString &file1,QString &file2) +{ + getFollowingFiles(file1,file2,-1); +} + +void FilesManager::getNextFiles(QString &file1,QString &file2) +{ + getFollowingFiles(file1,file2); +} + +void FilesManager::getFollowingFiles(QString &file1,QString &file2, int increment) +{ + QFileInfo fi1(file1); + QFileInfo fi2(file2); + + // reference is always 1 + int currIndex = m_lFiles1.indexOf( fi1.fileName () ); + + if ( currIndex>=0 && !m_lFiles1.isEmpty() ) + { + int loop = 0; + bool ok = false; + currIndex += increment; + while (!ok) + { + if (increment>0) + { + currIndex %= m_lFiles1.size(); + } + else + { + if (currIndex < 0) + currIndex = m_lFiles1.size() - 1; + } + + file1 = m_refPath1 + "/" + m_lFiles1[(currIndex) % m_lFiles1.size()]; + file2 = getValidFile(QFileInfo(file1).fileName(),m_refPath2,m_lFiles2); + + if ( !file2.isEmpty() ) + ok = true; + + loop++; + currIndex += increment; + + if ( loop > 2 * m_lFiles1.size() ) + { + ok = true; + file1 = ""; + file2 = ""; + break; + } + } + } +} + +void FilesManager::rescan(const QString &file, QString &refPath, QStringList &refList) +{ + bool rescan = false; + if ( QFileInfo(file).isDir() ) + { + if (refPath != file) + { + refPath = file; + rescan = true; + } + } + else if ( QFileInfo(file).isFile() ) + { + if (QFileInfo(file).absolutePath() != refPath ) + { + refPath = QFileInfo(file).absolutePath(); + rescan = true; + } + } + + if (rescan) + { + QString formats = MiscFunctions::getAvailablesImageFormats(); + refList = QDir(refPath).entryList(formats.split(" "), QDir::Files | QDir::Readable,QDir::Name); + } +} + +void FilesManager::rescan1(const QString &file) +{ + rescan(file,m_refPath1,m_lFiles1); +} + +void FilesManager::rescan2(const QString &file) +{ + rescan(file,m_refPath2,m_lFiles2); +} + +QString FilesManager::getValidFile(const QString &basename, const QString &refPath, const QStringList &refList) +{ + // file exist in the second directory ? + if ( refList.contains(basename) ) + return refPath + "/" + basename; + + // try to find a file with another suffix + QRegExp rx( QString("^%1.*").arg( QFileInfo(basename).completeBaseName() ) ); + int index = refList.indexOf(rx); + if (index >= 0) + return refPath + "/" + refList.at(index); + + return ""; +} + +void FilesManager::getCurrentFiles(QString &file1,QString &file2) +{ + // basic check + if ( QFileInfo(file1).isDir() && QFileInfo(file2).isDir() ) + { + LogHandler::getInstance()->reportError( QString("Can't compare two directory, only two files or a file and a directory (%1/%2)").arg( file1 ).arg(file2) ); + file1 = ""; + file2 = ""; + return; + } + + rescan1(file1); + rescan2(file2); + + if ( QFileInfo(file1).isDir() ) + { + // try to find the same basename + file1 = getValidFile(QFileInfo(file2).fileName(),m_refPath1, m_lFiles1); + } + + if ( QFileInfo(file2).isDir() ) + { + // try to find the same basename + file2 = getValidFile(QFileInfo(file1).fileName(),m_refPath2,m_lFiles2); + } +} + +const QStringList & FilesManager::getFilelist1() +{ + return m_lFiles1; +} + +const QStringList & FilesManager::getFilelist2() +{ + return m_lFiles2; +} diff -Nru diffimg-1.5.0/src/FilesManager.h diffimg-2.0.0/src/FilesManager.h --- diffimg-1.5.0/src/FilesManager.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/FilesManager.h 2013-05-17 15:33:18.000000000 +0000 @@ -0,0 +1,54 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _FILESMANAGER_H_ +#define _FILESMANAGER_H_ + +#include +#include + +//! Class for manage proposed filename across widget + +class FilesManager +{ +public: + + static void getCurrentFiles(QString &file1,QString &file2); + static void getNextFiles(QString &file1,QString &file2); + static void getPrevFiles(QString &file1,QString &file2); + static const QStringList & getFilelist1(); + static const QStringList & getFilelist2(); + +private: + + static QString getValidFile(const QString &basename,const QString &refpath, const QStringList &refList); + static void getFollowingFiles(QString &file1,QString &file2, int increment = 1); + + static void rescan1(const QString &); + static void rescan2(const QString &); + static void rescan(const QString &file, QString & refPath, QStringList &refList); + + static QStringList m_lFiles1; + static QString m_refPath1; + static QString m_refPath2; + static QStringList m_lFiles2; +}; + +#endif // _FilesManager_H_ diff -Nru diffimg-1.5.0/src/IMessageHandler.h diffimg-2.0.0/src/IMessageHandler.h --- diffimg-1.5.0/src/IMessageHandler.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/IMessageHandler.h 2013-05-06 06:36:56.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #ifndef _IMESSAGEHANDLER_H_ diff -Nru diffimg-1.5.0/src/ImageNavigator.cpp diffimg-2.0.0/src/ImageNavigator.cpp --- diffimg-1.5.0/src/ImageNavigator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/ImageNavigator.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,198 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include +#include +#include +#include + +#include "ImageNavigator.h" + +const double factorMaxSize = 0.15; // max xx% of parent widget + +// ImageNavigator -------------------------------------------------------------------- + +ImageNavigator::ImageNavigator(QGraphicsView* parent, Qt::WindowFlags flags) : QWidget(parent, flags), + m_worldMatrix( new QTransform() ), + m_imgMatrix( new QTransform() ), + m_backgroundColor( QColor(0, 0, 0, 150) ), + m_view(parent) +{ +} + +void ImageNavigator::setImage(const QImage &img) +{ + m_img = img; + resizeImg(); +} + +void ImageNavigator::setTransforms(QTransform* worldMatrix, QTransform* imgMatrix) +{ + m_worldMatrix = worldMatrix; + m_imgMatrix = imgMatrix; +} + +void ImageNavigator::setViewPortRect(const QRectF &viewPortRect) +{ + m_viewPortRect = viewPortRect; + resizeImg(); +} + +void ImageNavigator::paintEvent(QPaintEvent * /*event */) +{ + if (m_img.isNull() /*|| !m_imgMatrix || !m_worldMatrix*/) + return; + + QPainter painter(this); + + //draw the image's location + painter.setBrush(m_backgroundColor); + painter.setPen( QColor(200, 200, 200) ); + + painter.setOpacity(0.8f); + painter.drawImage( 0,0, m_imgT ); + painter.drawRect( m_imgT.rect().adjusted(0,0,0,0) ); + + // compute view rect + QRectF viewRect = m_view->mapToScene( m_view->rect() ).boundingRect(); + QRectF viewRectInImage = m_view->scene()->sceneRect().intersected(viewRect); + + QRectF viewRectInThumbnail = viewRectInImage.intersected( m_img.rect() ); + float reducFactor = m_imgT.height() / (float)m_img.height(); + viewRectInThumbnail = QRectF(viewRectInThumbnail.topLeft() * reducFactor,viewRectInThumbnail.size() * reducFactor); + + painter.setOpacity(1.0f); + painter.setPen( QColor(255, 0, 0) ); + painter.setBrush( QColor(255, 0, 0, 100) ); + painter.drawRect(viewRectInThumbnail); +} + +void ImageNavigator::mousePressEvent(QMouseEvent *event) +{ + m_enterPos = event->pos(); + m_lastPos = event->pos(); +} + +void ImageNavigator::mouseReleaseEvent(QMouseEvent *event) +{ + QPointF dxy = m_enterPos - QPointF( event->pos() ); + + if (dxy.manhattanLength() < 4) + { + // compute view rect + QRectF viewRect = m_view->mapToScene( m_view->rect() ).boundingRect(); + QRectF viewRectInImage = m_view->scene()->sceneRect().intersected(viewRect); + + QRectF viewRectInThumbnail = viewRectInImage.intersected( m_img.rect() ); + float reducFactor = m_imgT.height() / (float)m_img.height(); + viewRectInThumbnail = QRectF(viewRectInThumbnail.topLeft() * reducFactor,viewRectInThumbnail.size() * reducFactor); + + if ( viewRectInThumbnail.contains( event->pos() ) ) + { + QPointF newPt = event->pos() / reducFactor; + emit moveView(newPt); + event->accept(); + } + } +} + +void ImageNavigator::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() != Qt::LeftButton) + return; + + // compute view rect + QRectF viewRect = m_view->mapToScene( m_view->rect() ).boundingRect(); + QRectF viewRectInImage = m_view->scene()->sceneRect().intersected(viewRect); + + //QRectF viewRectInThumbnail = QRectF(viewRectInImage.topLeft()*factorMaxSize,viewRectInImage.size()*factorMaxSize); + QRectF viewRectInThumbnail = viewRectInImage.intersected( m_img.rect() ); + float reducFactor = m_imgT.height() / (float)m_img.height(); + viewRectInThumbnail = QRectF(viewRectInThumbnail.topLeft() * reducFactor,viewRectInThumbnail.size() * reducFactor); + + if ( viewRectInThumbnail.contains( event->pos() ) ) + { + QPointF newPt = event->pos() / reducFactor; + emit moveView(newPt); + event->accept(); + } +} + +void ImageNavigator::resizeEvent(QResizeEvent* event) +{ + if ( event->size() == size() ) + return; + + QWidget::resizeEvent(event); +} + +QSize ImageNavigator::sizeHint() const +{ + return m_imgT.rect().adjusted(-1,-1,1,1).size(); +} + +void ImageNavigator::resizeImg() +{ + if ( m_img.isNull() ) + return; + + QSizeF maxSize = m_viewPortRect.size() * factorMaxSize; + m_imgT = m_img.scaled(maxSize.toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + resize( sizeHint() ); + return; + + QRectF imgRect = QRectF( QPoint(), m_img.size() ); + + QTransform overviewImgMatrix = getScaledImageMatrix(); // matrix that always resizes the image to the current viewport + QRectF overviewImgRect = overviewImgMatrix.mapRect(imgRect); + overviewImgRect.setTop(overviewImgRect.top() + 1); + overviewImgRect.setLeft(overviewImgRect.left() + 1); + overviewImgRect.setWidth(overviewImgRect.width() - 1); // we have a border... correct that... + overviewImgRect.setHeight(overviewImgRect.height() - 1); + + // fast downscaling + m_imgT = m_img.scaled(overviewImgRect.size().width(), overviewImgRect.size().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); +} + +QTransform ImageNavigator::getScaledImageMatrix() +{ + if ( m_img.isNull() ) + return QTransform(); + + // the image resizes as we zoom + QRectF imgRect = QRectF( QPoint(), m_img.size() ); + float ratioImg = imgRect.width() / imgRect.height(); + float ratioWin = (float)width() / (float)height(); + + QTransform imgMatrix; + float s; + + if (imgRect.width() == 0 || imgRect.height() == 0) + s = 1.0f; + else + s = (ratioImg > ratioWin) ? (float)width() / imgRect.width() : (float)height() / imgRect.height(); + + imgMatrix.scale(s, s); + + QRectF imgViewRect = imgMatrix.mapRect(imgRect); + imgMatrix.translate( ( width() - imgViewRect.width() ) * 0.5f / s, ( height() - imgViewRect.height() ) * 0.5f / s ); + + return imgMatrix; +} diff -Nru diffimg-1.5.0/src/ImageNavigator.h diffimg-2.0.0/src/ImageNavigator.h --- diffimg-1.5.0/src/ImageNavigator.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/ImageNavigator.h 2013-05-15 17:38:50.000000000 +0000 @@ -0,0 +1,72 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _IMAGENAVIGATOR_H_ +#define _IMAGENAVIGATOR_H_ + +#include + +class QGraphicsView; + +class ImageNavigator : public QWidget +{ + Q_OBJECT + +public: + + explicit ImageNavigator(QGraphicsView * parent = 0, Qt::WindowFlags f = 0); + virtual ~ImageNavigator() {} + + void setImage(const QImage &img); + + void setTransforms(QTransform* worldMatrix, QTransform* imgMatrix); + + void setViewPortRect(const QRectF &viewPortRect); + + virtual QSize sizeHint() const; + +signals: + + void moveView(const QPointF &dxy); + +protected: + + void resizeImg(); + void paintEvent(QPaintEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void resizeEvent(QResizeEvent* event); + QTransform getScaledImageMatrix(); + +private: + + QImage m_img; + QImage m_imgT; + QTransform* m_worldMatrix; + QTransform* m_imgMatrix; + QRectF m_viewPortRect; + QPointF m_lastPos; + QPointF m_enterPos; + QColor m_backgroundColor; + QGraphicsView *m_view; +}; + +#endif // _IMAGENAVIGATOR_H_ diff -Nru diffimg-1.5.0/src/ImageView.cpp diffimg-2.0.0/src/ImageView.cpp --- diffimg-1.5.0/src/ImageView.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/ImageView.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,402 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +// Qt +#include + +#include +#include + +#include + +//#include + +#include "ImageView.h" +#include "ImageNavigator.h" + +ImageView::ImageView(QWidget * parent) : QGraphicsView(parent), + m_navigator(NULL), + m_imageItem(NULL), + m_maskItem(NULL), + m_navigatorSize(0.15f), + m_navigatorMargin(10), + m_showNavigator(true), + m_maskOpacity(0.5f), + m_showMask(true), + m_drag(false), + m_showMarker(false) +{ + // OpenGL + //setViewport(new QGLWidget(this)); + + // GUI + setContentsMargins(1,1,1,1); + + // Initialize properties + setMouseTracking(true); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setDragMode(QGraphicsView::ScrollHandDrag); + setViewportUpdateMode (QGraphicsView::FullViewportUpdate); // because artifact (view rect diff scene rect !!) + + // Center + m_centerPoint = QPointF(0.0f,0.0f); + centerOn(m_centerPoint); + initBackground(); + + QGraphicsScene *scene = new QGraphicsScene(this); + + // trace change in the scene (in order to view more than only scene rect + connect( scene,SIGNAL( sceneRectChanged ( const QRectF &) ),this,SLOT( updateSceneRect(const QRectF &) ) ); + setScene(scene); + + // navigator windows + m_navigator = new ImageNavigator(this); + connect( m_navigator, SIGNAL( moveView(const QPointF &) ), this, SLOT( setCenter(const QPointF &) ) ); + connect( m_navigator, SIGNAL( moveView(const QPointF &) ), this, SIGNAL( somethingChanged(const QPointF &) ) ); // must inform "connected" views +} + +ImageView::~ImageView() +{ +} + +void ImageView::setMaskOpacity(qreal opa) +{ + m_maskOpacity = opa; + if (m_maskItem) + m_maskItem->setOpacity(m_maskOpacity); +} + +qreal ImageView::maskOpacity() const +{ + return m_maskOpacity; +} + +void ImageView::setEnabledMask(bool val) +{ + m_showMask = val; + if (m_maskItem) + { + m_maskItem->setVisible(m_showMask); + viewport()->update(); + } +} + +bool ImageView::isMaskEnabled() const +{ + return m_showMask; +} + +void ImageView::setEnabledMarker(bool val) +{ + m_showMarker = val; + viewport()->update(); +} + +bool ImageView::isMarkerEnabled() const +{ + return m_showMarker; +} + +void ImageView::setShowOverview(bool val) +{ + m_showNavigator = val; + viewport()->update(); +} + +void ImageView::setScale(qreal val) +{ + setMatrix( QMatrix() ); + scale(val,val); + emit scaleChanged( transform().m22() ); +} + +qreal ImageView::getScale() const +{ + return transform().m22(); +} + +void ImageView::setImage(const QImage &newImg) +{ + m_navigator->setImage( newImg ); // reset overview + + if (!m_imageItem) + m_imageItem = scene()->addPixmap( QPixmap::fromImage(newImg) ); + else + m_imageItem->setPixmap( QPixmap::fromImage(newImg) ); + scene()->setSceneRect( newImg.rect() ); +} + +void ImageView::setMask(const QImage &newMask) +{ + if (!m_maskItem) + m_maskItem = scene()->addPixmap( QPixmap::fromImage(newMask) ); + else + m_maskItem->setPixmap( QPixmap::fromImage(newMask) ); + m_maskItem->setOpacity(m_maskOpacity); + m_maskItem->setVisible(m_showMask); +} + +void ImageView::updateSceneRect(const QRectF &rect) +{ + // the view can "see" sceneRect x 2 + setSceneRect( rect.adjusted(-rect.width() / 2,-rect.height() / 2,rect.width() / 2,rect.height() / 2) ); +} + +bool ImageView::isImageInside() +{ + // view rect is completely inside the image rect ? + if ( scene() ) + return mapToScene( rect() ).boundingRect().contains( scene()->sceneRect() ); + else + return false; +} + +void ImageView::paintEvent(QPaintEvent* event) +{ + QPainter painter( viewport() ); + + // draw background + painter.drawTiledPixmap(rect(), m_tileBg); + QGraphicsView::paintEvent(event); + + if (!isImageInside() && m_showNavigator) + { + if ( m_navigator->isVisible() ) + { + // top left placement + m_navigator->move(m_navigatorMargin, m_navigatorMargin); + } + else + { + m_navigator->show(); + m_navigator->update(); + } + } + else + { + m_navigator->hide(); + } + + if (m_showMarker) + drawMarker(painter); +} + +bool ImageView::event(QEvent *e) +{ + switch ( e->type() ) + { + case QEvent::Leave: + emit mouseMoved( QPointF() ); + break; + default: + break; + } + return QGraphicsView::event(e); +} + +void ImageView::initBackground() +{ + // recreate background tile + m_tileBg = QPixmap(16, 16); + m_tileBg.fill(Qt::white); + QPainter pt(&m_tileBg); + QColor color(202, 202, 202); + pt.fillRect(0, 0, 8, 8, color); + pt.fillRect(8, 8, 8, 8, color); + pt.end(); +} + +void ImageView::fitScale() +{ + if ( scene() ) + { + fitInView(scene()->sceneRect(), Qt::KeepAspectRatio ); + setCenter( scene()->sceneRect().center() ); + emit scaleChanged( transform().m22() ); + emit somethingChanged(); + } +} + +void ImageView::resetScale() +{ + setMatrix( QMatrix() ); + setCenter( scene()->sceneRect().center() ); + emit scaleChanged( transform().m22() ); + emit somethingChanged(); +} + +void ImageView::mousePressEvent(QMouseEvent *event) +{ + m_drag = false; + if (event->button() == Qt::LeftButton) + { + m_drag = true; + } + QGraphicsView::mousePressEvent(event); +} + +void ImageView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + m_drag = false; + } + QGraphicsView::mouseReleaseEvent(event); +} + +/** + *Handles the mouse move event + */ +void ImageView::mouseMoveEvent(QMouseEvent* event) +{ + QPointF mousePos = QGraphicsView::mapToScene( event->pos() ); + emit mouseMoved(mousePos); + m_centerPoint = QGraphicsView::mapToScene( rect().center() ); + QGraphicsView::mouseMoveEvent(event); + if (m_drag) + emit somethingChanged(); +} + +/** + * Zoom the view in and out. + */ + +void ImageView::wheelEvent(QWheelEvent* event) +{ + // Scaled ? + bool scaled = false; + + //Get the position of the mouse before scaling, in scene coords + QPointF pointBeforeScale( QGraphicsView::mapToScene( event->pos() ) ); + + //Get the original screen centerpoint + QPointF screenCenter = mapToScene( rect().center() ); + + //Scale the view ie. do the zoom + double scaleFactor = 1.3; //How fast we zoom + if(event->delta() > 0 ) + { + //Zoom in + scale(scaleFactor, scaleFactor); + scaled = true; + } + else + { + //Zooming out + scale(1.0 / scaleFactor, 1.0 / scaleFactor); + scaled = true; + } + + emit scaleChanged( transform().m22() ); + + if ( scaled ) + { + //Get the position after scaling, in scene coords + QPointF pointAfterScale( QGraphicsView::mapToScene( event->pos() ) ); + + //Get the offset of how the screen moved + QPointF offset = pointBeforeScale - pointAfterScale; + + //Adjust to the new center for correct zooming + QPointF newCenter = screenCenter + offset; + setCenter(newCenter); + } + + // mouse position has changed!! + emit mouseMoved( QGraphicsView::mapToScene( event->pos() ) ); + emit somethingChanged(); +} + +void ImageView::setMarkerPosition(const QPointF &p) +{ + m_posMarker = mapFromScene(p); + if (m_showMarker) + viewport()->update(); +} + +void ImageView::setCenter(const QPointF& position) +{ + m_centerPoint = position; + centerOn(m_centerPoint); +} + +void ImageView::resizeEvent(QResizeEvent* event) +{ + //Scale the view ie. do the zoom + double heightscale; + + // Not on the width direction widthscale = (double)event->size().width() / event->oldSize().width(); + heightscale = (double)event->size().height() / event->oldSize().height(); + + // Not on the width direction double doscale = widthscale 0 ) + { + scale(heightscale,heightscale); + emit scaleChanged( transform().m22() ); + } + + // Set center + centerOn(m_centerPoint); + + // navigator + m_navigator->setViewPortRect( geometry() ); + + //Call the subclass resize so the scrollbars are updated correctly + QGraphicsView::resizeEvent(event); +} + +void ImageView::drawLines(const QPointF ¢er, QPainter &p) +{ + int markerSize = 10; + + // horizontal lines + p.drawLine( QPointF( center.x() - markerSize, center.y() ), + QPointF( center.x() - markerSize / 2, center.y() ) ); + p.drawLine( QPointF( center.x() + markerSize / 2, center.y() ), + QPointF( center.x() + markerSize, center.y() ) ); + + // vertical lines + p.drawLine( QPointF(center.x(), center.y() - markerSize ), + QPointF(center.x(), center.y() - markerSize / 2) ); + p.drawLine( QPointF(center.x(), center.y() + markerSize / 2 ), + QPointF(center.x(), center.y() + markerSize) ); +} + +void ImageView::drawMarker(QPainter &p) +{ + // draw a darker line to "highlight" cross + p.save(); + + QPen pen = p.pen(); + pen.setWidthF(3.0); + pen.setColor( QColor(255,255,255,255) ); + p.setPen(pen); + + drawLines(m_posMarker, p); + + pen.setWidthF(2.0); + pen.setColor( QColor(50,50,50,255) ); + p.setPen(pen); + + drawLines(m_posMarker, p); + + p.restore(); +} diff -Nru diffimg-1.5.0/src/ImageView.h diffimg-2.0.0/src/ImageView.h --- diffimg-1.5.0/src/ImageView.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/ImageView.h 2013-07-13 14:03:54.000000000 +0000 @@ -0,0 +1,117 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _EDITORVIEW_H_ +#define _EDITORVIEW_H_ + +// Qt +#include +#include + +class QGraphicsPixmapItem; +class ImageNavigator; + +class ImageView : public QGraphicsView +{ + Q_OBJECT + +public: + + ImageView(QWidget * map); + ~ImageView(); + + //virtual void setImage(const QImage &newImg); + + void resetScale(); + void fitScale(); + qreal getScale() const; + void setScale(qreal); + + void setShowOverview(bool); + + void setImage(const QImage &newImg); + void setMask(const QImage &newMask); + + // mask opacity (0.0->1.0) + void setMaskOpacity(qreal); + qreal maskOpacity() const; + void setEnabledMask(bool); + bool isMaskEnabled() const; + void setEnabledMarker(bool); + bool isMarkerEnabled() const; + + // Center + const QPointF& getCenter() const + { + return m_centerPoint; + } + +public slots: + + void updateSceneRect(const QRectF &); + void setCenter(const QPointF& position); + void setMarkerPosition(const QPointF &); + +signals: + + void mouseMoved(const QPointF &pos); + void scaleChanged(qreal); + void somethingChanged( const QPointF &pt = QPointF() ); // scale or center point change + +protected: + + //Take over the interaction + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mousePressEvent(QMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QMouseEvent *mouseEvent); + + virtual void wheelEvent(QWheelEvent* event); + virtual void resizeEvent(QResizeEvent* event); + virtual void paintEvent(QPaintEvent* event); + virtual bool event(QEvent *e); + +private: + + void initBackground(); + bool isImageInside(); + void drawMarker(QPainter &p); + void drawLines(const QPointF &,QPainter &p); + + //Holds the current centerpoint for the view, used for panning and zooming + QPointF m_centerPoint; + QPixmap m_tileBg; + + ImageNavigator* m_navigator; + + QGraphicsPixmapItem *m_imageItem; + QGraphicsPixmapItem *m_maskItem; + + // overview rendering + float m_navigatorSize; + float m_navigatorMargin; + bool m_showNavigator; + qreal m_maskOpacity; + bool m_showMask; + bool m_drag; + bool m_showMarker; + QPointF m_posMarker; +}; + +#endif // _EDITORVIEW_H_ diff -Nru diffimg-1.5.0/src/ImageWidget.cpp diffimg-2.0.0/src/ImageWidget.cpp --- diffimg-1.5.0/src/ImageWidget.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/ImageWidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#include -#include -#include -#include - -#include "ImageWidget.h" - -ImageWidget::ImageWidget( QWidget *parent ) : QWidget( parent ), - m_zoomFactor(1.0f), - m_tile( QPixmap(16, 16) ) -{ - m_tile.fill(Qt::white); - QPainter pt(&m_tile); - QColor color(202, 202, 202); - pt.fillRect(0, 0, 8, 8, color); - pt.fillRect(8, 8, 8, 8, color); - pt.end(); - - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); -} - -void ImageWidget::setImage(const QString &image) -{ - if ( !image.isEmpty() ) - { - m_img = QImage( image ); - - setMinimumSize( (int)(m_img.width() * m_zoomFactor),(int) (m_img.height() * m_zoomFactor) ); - update(); - } -} - -void ImageWidget::setImage(const QImage &image) -{ - if ( !image.isNull() ) - { - m_img = QImage( image ); - int w = m_img.width() * m_zoomFactor; - int h = m_img.height() * m_zoomFactor; - - setMinimumSize( w, h ); - update(); - } -} - -ImageWidget::~ImageWidget() -{ -} - -void ImageWidget::setZoomFactor( float f ) -{ - int w, h; - - if( f == m_zoomFactor || m_img.isNull() ) - return; - - m_zoomFactor = f; - - w = (int)( m_img.width() * m_zoomFactor); - h = (int)(m_img.height() * m_zoomFactor); - - // set the size of the widget - setMinimumSize( w, h ); - update(); -} - -void ImageWidget::paintEvent(QPaintEvent *e) -{ - int xoffset = 0, yoffset = 0; - QPainter painter; - - painter.begin(this); - - painter.setClipRect( e->rect() ); - - //painter.setRenderHint(QPainter::Antialiasing); - - QPainterPath clipPath; - - QRect r = rect(); - qreal left = r.x() + 1; - qreal top = r.y() + 1; - qreal right = r.right(); - qreal bottom = r.bottom(); - qreal radius2 = 8 * 2; - - clipPath.moveTo(right - radius2, top); - clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90); - clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90); - clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90); - clipPath.arcTo(left, top, radius2, radius2, 180, -90); - clipPath.closeSubpath(); - - //painter.save(); - painter.setClipPath(clipPath, Qt::IntersectClip); - - painter.drawTiledPixmap(rect(), m_tile); - - if ( m_img.isNull() ) - { - painter.end(); - return; - } - - // client painting - int pw = m_img.width(); - int ph = m_img.height(); - int ww = width(); - int wh = height(); - - /*if( ww > pw * m_zoomFactor ) - xoffset = (int) (ww - pw * m_zoomFactor) / 2; - else*/ - xoffset = (int) (ww - pw * m_zoomFactor) / 2; - - /*if(wh > ph * m_zoomFactor ) - yoffset = (int)(wh - ph * m_zoomFactor) / 2; - else*/ - yoffset = (int)(wh - ph * m_zoomFactor) / 2; - - painter.translate( xoffset, yoffset ); - painter.scale(m_zoomFactor, m_zoomFactor); - - painter.drawImage(QPointF(0.0f, 0.0f), m_img); - - // trace contour rouge - painter.setPen( QPen(QColor(255, 0, 0, 155), 1.0 / m_zoomFactor, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin) ); - painter.setBrush(Qt::NoBrush); - painter.drawRect( QRect( 0.0f, 0.0f, m_img.width(), m_img.height() ).adjusted(-2, -2, 2, 2) ); - painter.end(); -} diff -Nru diffimg-1.5.0/src/ImageWidget.h diffimg-2.0.0/src/ImageWidget.h --- diffimg-1.5.0/src/ImageWidget.h 2013-02-06 16:36:04.000000000 +0000 +++ diffimg-2.0.0/src/ImageWidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _PIXMAPWIDGET_H_ -#define _PIXMAPWIDGET_H_ - -#include -#include -#include - -class QPixmap; - -class ImageWidget : public QWidget -{ - Q_OBJECT - -public: - - ImageWidget( QWidget *parent = 0 ); - ~ImageWidget(); - - void setImage(const QImage &image); - void setImage(const QString &); - void setZoomFactor( float f ); - const QImage & getImage() const {return m_img; } - -protected: - - void paintEvent( QPaintEvent* ); - -private: - - QImage m_img; - float m_zoomFactor; - QPoint lastPoint; - QPixmap m_tile; -}; - -#endif // _PIXMAPWIDGET_H_ diff -Nru diffimg-1.5.0/src/LogHandler.cpp diffimg-2.0.0/src/LogHandler.cpp --- diffimg-1.5.0/src/LogHandler.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/LogHandler.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,11 +15,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include "LogHandler.h" -#include +#include LogHandler* LogHandler::m_Instance = 0; @@ -49,7 +49,8 @@ } LogHandler::LogHandler( ) : - m_currLevel(MSG_DEBUG) + m_currLevel(MSG_DEBUG), + m_bufferized(true) { } @@ -100,8 +101,13 @@ } } - //qDebug("%s",msg.toStdString().c_str()); - emit newMessage(msg); +#ifdef _DEBUG + qDebug( "%s",msg.toStdString().c_str() ); +#endif + if (m_bufferized) + m_buffer << msg; + else + emit newMessage(msg); } void LogHandler::reportDebug(const QString &message ) @@ -123,3 +129,16 @@ { reportMessage(IMessageHandler::MSG_ERROR,message); } + +void LogHandler::setBufferization(bool val) +{ + m_bufferized = val; + if (!m_bufferized) // send all stored messages + { + foreach (const QString &mess, m_buffer) + { + emit newMessage(mess); + } + m_buffer.clear(); + } +} diff -Nru diffimg-1.5.0/src/LogHandler.h diffimg-2.0.0/src/LogHandler.h --- diffimg-1.5.0/src/LogHandler.h 2013-02-06 16:36:05.000000000 +0000 +++ diffimg-2.0.0/src/LogHandler.h 2013-05-18 21:16:24.000000000 +0000 @@ -1,76 +1,82 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _LOGHANDLER_H_ -#define _LOGHANDLER_H_ - -#include "IMessageHandler.h" - -#include -#include - -//! A dialog for displaying message from reader/writer - -/*! - * Displaying colored message by taking care of the message level - */ - -class LogHandler : public QObject, public IMessageHandler -{ - Q_OBJECT - -public: - - static LogHandler *getInstance(); - ~LogHandler(); - - void setMessageLevel(MessageLevel level) - { - m_currLevel = level; - } - -public slots: - - void reportMessage(MessageLevel level, const QString &message ); - void reportDebug(const QString &message ); - void reportInfo(const QString &message ); - void reportWarning(const QString &message ); - void reportError(const QString &message ); - -signals: - - void newMessage(const QString &); - -private: - - LogHandler( ); - - LogHandler(const LogHandler &); // hide copy constructor - LogHandler& operator=(const LogHandler &); // hide assign op - // we leave just the declarations, so the compiler will warn us - // if we try to use those two functions by accident - -private: - - static LogHandler* m_Instance; - MessageLevel m_currLevel; -}; - -#endif // _LOGHANDLER_H_ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _LOGHANDLER_H_ +#define _LOGHANDLER_H_ + +#include "IMessageHandler.h" + +#include +#include +#include + +//! A dialog for displaying message from reader/writer + +/*! + * Displaying colored message by taking care of the message level + */ + +class LogHandler : + public QObject, public IMessageHandler +{ + Q_OBJECT + +public: + + static LogHandler *getInstance(); + ~LogHandler(); + + void setMessageLevel(MessageLevel level) + { + m_currLevel = level; + } + + void setBufferization(bool); + +public slots: + + void reportMessage(MessageLevel level, const QString &message ); + void reportDebug(const QString &message ); + void reportInfo(const QString &message ); + void reportWarning(const QString &message ); + void reportError(const QString &message ); + +signals: + + void newMessage(const QString &); + +private: + + LogHandler( ); + + LogHandler(const LogHandler &); // hide copy constructor + LogHandler& operator=(const LogHandler &); // hide assign op + // we leave just the declarations, so the compiler will warn us + // if we try to use those two functions by accident + +private: + + static LogHandler* m_Instance; + MessageLevel m_currLevel; + QStringList m_buffer; + bool m_bufferized; +}; + +#endif // _LOGHANDLER_H_ diff -Nru diffimg-1.5.0/src/MiscFunctions.cpp diffimg-2.0.0/src/MiscFunctions.cpp --- diffimg-1.5.0/src/MiscFunctions.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/MiscFunctions.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,26 +15,31 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ -#include - -#include -#include -#include #include #include #include #include #include +#include +#include + +#include +#include +#include #include +#include +#include + #include "MiscFunctions.h" #include "LogHandler.h" #include "AppSettings.h" -#include "math.h" +#include +#include #ifndef ABS #define ABS(x) ( ( (x)>=0 ) ? (x) : ( -(x) ) ) @@ -63,6 +68,10 @@ result << format; } + // add formats not support by Qt + result << "exr"; // OpenEXR + result << "jp2"; // jpeg2000 + return result; } @@ -146,7 +155,7 @@ QString MiscFunctions::getAvailablesImageFormats() { QString imglist; - QList formats = QImageReader::supportedImageFormats(); + QStringList formats = getAvailablesImageFormatsList(); for (int i = 0; i < formats.size(); ++i) imglist += "*." + formats[i] + " "; @@ -161,6 +170,7 @@ ldir << QCoreApplication::applicationDirPath () + "/../lang"; ldir << QCoreApplication::applicationDirPath () + "/../../lang"; ldir << "/usr/local/share/locale"; + ldir << "/usr/share/local/locale"; foreach (const QString &dir, ldir) { @@ -176,10 +186,10 @@ { QMap languageMap; QDir dir( MiscFunctions::getTranslationsPath() ); - QRegExp expr("^diffimg_(\\w+)\\.qm$"); + QRegExp expr( QString("^%1_(\\w+)\\.qm$").arg(PACKAGE_NAME).toLower() ); QStringList files = dir.entryList(QDir::Files, QDir::Name); - LogHandler::getInstance()->reportDebug( QObject::tr("translations path %1").arg( dir.path() ) ); + LogHandler::getInstance()->reportDebug( QString("translations path %1").arg( dir.path() ) ); foreach ( const QString &file, files ) { @@ -227,9 +237,16 @@ // try load the qt translator for selected language QTranslator *qt = new QTranslator(); - if ( qt->load( "qt_" + language, QLibraryInfo::location(QLibraryInfo::TranslationsPath) ) ) + QStringList excludedFiles; + QString globalTranslationPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); + if ( !QFileInfo(globalTranslationPath).exists() ) + globalTranslationPath = MiscFunctions::getTranslationsPath(); + + if ( qt->load( "qt_" + language, globalTranslationPath ) ) { + LogHandler::getInstance()->reportDebug( QObject::tr("successfully loaded data from %1").arg( globalTranslationPath + "/qt_" + language ) ); QCoreApplication::installTranslator(qt); + excludedFiles << "qt_" + language + ".qm"; } else { @@ -239,18 +256,16 @@ QString suff = language + ".qm"; QDir dir( MiscFunctions::getTranslationsPath() ); - foreach ( QString s, dir.entryList(QDir::Files | QDir::Readable) ) + foreach ( const QString &s, dir.entryList(QDir::Files | QDir::Readable) ) { - if ( !s.endsWith(suff) ) + if ( !s.endsWith(suff) || excludedFiles.contains(s) ) continue; - QTranslator *t = new QTranslator(); if ( t->load( dir.filePath(s) ) ) { QCoreApplication::installTranslator(t); LogHandler::getInstance()->reportDebug( QObject::tr("successfully loaded data from %1").arg( dir.filePath(s) ) ); - break; } else { @@ -267,176 +282,568 @@ QCoreApplication::setOrganizationName(PACKAGE_ORGANIZATION); } -bool MiscFunctions::computeDifferencePixels(const QImage &sourceImage, const QImage &destinationImage, DiffStruct &res, int maskOpacity, bool interactive, int method ) +QImage MiscFunctions::opencvMatToQImage(const cv::Mat& mat, bool deepCopy) { - if ( sourceImage.size() != destinationImage.size() ) + // 8-bits unsigned, NO. OF CHANNELS=1 + if(mat.type()==CV_8UC1) { - //QMessageBox::information(this, tr("Image Viewer"),tr("Cannot display difference, image have different size (%1x%2/%3x%4)").arg(sourceImage.size().width()).arg(sourceImage.size().height()).arg(destinationImage.size().width()).arg(destinationImage.size().height())); - return false; + // Set the color table (used to translate color indexes to qRgb values) + QVector colorTable; + for (int i = 0; i<256; i++) + colorTable.push_back( qRgb(i,i,i) ); + + if (deepCopy) + { + QImage img(mat.cols, mat.rows, QImage::Format_Indexed8); + for (int i = 0; i < img.height(); i++) + // scanLine returns a ptr to the start of the data for that row + memcpy( img.scanLine(i), mat.ptr(i), img.bytesPerLine() ); //correct + return img; + } + else + { + // Copy input Mat + const uchar *qImageBuffer = (const uchar*)mat.data; + + // Create QImage with same dimensions as input Mat + QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8); + img.setColorTable(colorTable); + return img; + } } + else if (mat.type()==CV_16UC1) + { + cv::Mat ucharMatScaled; + cv::Mat ushortMatScaled; + cv::Mat floatMatScaled; + double minImage, maxImage; + cv::minMaxLoc(mat, &minImage, &maxImage); + mat.convertTo(floatMatScaled, CV_32FC1); - QRgb valueMask; - QRgb valueImg; + // to ensure [0-1.0] + floatMatScaled = (floatMatScaled - minImage) / (maxImage - minImage); + floatMatScaled.convertTo(ucharMatScaled, CV_8UC1, 255, 0); + return opencvMatToQImage(ucharMatScaled); + } + else if (mat.type()==CV_32FC1) + { + cv::Mat ucharMatScaled; + cv::Mat floatMatScaled; + double minImage, maxImage; + cv::minMaxLoc(mat, &minImage, &maxImage); - res.diffImage = QImage(sourceImage.size(), QImage::Format_ARGB32); - res.maskDiffImage = QImage(sourceImage.size(), QImage::Format_ARGB32); + // to ensure [0-1.0] + floatMatScaled = (mat - minImage) / (maxImage - minImage); + floatMatScaled.convertTo(ucharMatScaled, CV_8UC1, 255, 0); - res.rmsDiff = 0.0; + return opencvMatToQImage(ucharMatScaled); + } + else if (mat.type() == CV_32FC3) + { + cv::Mat ucharMatScaled; + cv::Mat floatMatScaled; + double minImage, maxImage; + cv::minMaxLoc(mat, &minImage, &maxImage); + + normalize(mat, floatMatScaled, 0.0, 1.0, cv::NORM_MINMAX); + cv::pow(floatMatScaled, 1. / 5, floatMatScaled); // apply gamma curve: img = img ** (1./5) + mat.convertTo(ucharMatScaled, CV_8UC3, 255, 0); - memset(res.valueR,0,sizeof(double) * 2 * 256); - memset(res.valueG,0,sizeof(double) * 2 * 256); - memset(res.valueB,0,sizeof(double) * 2 * 256); - res.minError = 256; - res.maxError = -256; + qDebug() << "type ucharMatScaled = " << MiscFunctions::matTypeToText( ucharMatScaled.type() ); - int nb = 0; - res.nbErr = 0; - int sum = 0; - float val; - int width = sourceImage.width(); - int height = sourceImage.height(); + return opencvMatToQImage(ucharMatScaled); + } - // first pass compute stats and diff image - for (int y = 0; y < height; y++) + // 8-bits unsigned, NO. OF CHANNELS=3 + else { - const QRgb *lineSrc = reinterpret_cast( sourceImage.scanLine(y) ); - const QRgb *lineDst = reinterpret_cast( destinationImage.scanLine(y) ); - for (int x = 0; x < width; x++) + cv::Mat rgbMat; + int qImageFormat = QImage::Format_RGB888; + if(mat.type()==CV_8UC4) { - int red1 = qRed(lineSrc[x]); - int red2 = qRed(lineDst[x]); - int green1 = qGreen(lineSrc[x]); - int green2 = qGreen(lineDst[x]); - int blue1 = qBlue(lineSrc[x]); - int blue2 = qBlue(lineDst[x]); - - // change the channel value to reflect the difference methid choose - transformChannel(red1,red2,green1,green2,blue1,blue2,method); - - res.rmsDiff += (red1 - red2) * (red1 - red2) + (green1 - green2) * (green1 - green2) + (blue1 - blue2) * (blue1 - blue2); - - int rr = (red1 - red2); - res.maxError = MAX(res.maxError,rr); - res.minError = MIN(res.minError,rr); - - int gg = (green1 - green2); - res.maxError = MAX(res.maxError,gg); - res.minError = MIN(res.minError,gg); - - int bb = (blue1 - blue2); - res.maxError = MAX(res.maxError,bb); - res.minError = MIN(res.minError,bb); - - val = ( ABS(rr) + ABS(gg) + ABS(bb) ); - if (val > 0.0f) - { - sum += (int)val; - res.nbErr++; - - //valueImg = qRgba(128-red1+red2,128-green1+green2,128-blue1+blue2,255); - valueImg = qRgba( - qBound(0,128 - red1 + red2,255), - qBound(0,128 - green1 + green2,255), - qBound(0,128 - blue1 + blue2,255), - 255); - } - else - { - valueImg = qRgba(128,128,128,255); - } - - if (interactive) - { - res.valueR[256 - rr]++; - res.valueG[256 - gg]++; - res.valueB[256 - bb]++; - res.diffImage.setPixel(x,y,valueImg); - } - - nb++; + qImageFormat = QImage::Format_ARGB32; + rgbMat = mat; + } + else if (mat.type()==CV_8UC3) + { + rgbMat = mat; } + else + { + cvtColor(mat, rgbMat,CV_BGR2RGB); + } + + // Copy input Mat + const uchar *qImageBuffer = (const uchar*)mat.data; + + // Create QImage with same dimensions as input Mat + QImage img(qImageBuffer, mat.cols, mat.rows, mat.step,(QImage::Format) qImageFormat); + return img.rgbSwapped(); // deep copy !! + //} } +} - res.rmsDiff = sqrt ( res.rmsDiff / (3.0f * nb) ); +cv::Mat MiscFunctions::qImageToOpencvMat(const QImage &image) +{ + if ( image.isNull() ) + return cv::Mat(); + + cv::Mat mat = cv::Mat( image.height(), image.width(), CV_8UC4, (uchar*)image.bits(), image.bytesPerLine() ); + cv::Mat mat2 = cv::Mat(mat.rows, mat.cols, CV_8UC3 ); + int from_to[] = { 0,0, 1,1, 2,2 }; + cv::mixChannels( &mat, 1, &mat2, 1, from_to, 3 ); + return mat2; +} + +QString MiscFunctions::matTypeToText(int type) +{ + switch( type ) + { + case CV_8UC1: + return "CV_8UC1"; - res.meanError = sum / (float)nb; + break; + case CV_8UC2: + return "CV_8UC2"; + + break; + case CV_8UC3: + return "CV_8UC3"; - //float meanPixelError = sum/(float)nbErr; - int opacity = (int)( 255 * (maskOpacity / 100.0f) ); - res.stantdardDeviation = 0.0f; + break; + case CV_8UC4: + return "CV_8UC4"; + + break; + case CV_8SC1: + return "CV_8SC1"; - // second pass highlight max error - for (int y = 0; y < height; y++) + break; + case CV_8SC2: + return "CV_8SC2"; + + break; + case CV_8SC3: + return "CV_8SC3"; + + break; + case CV_8SC4: + return "CV_8SC4"; + + break; + case CV_16UC1: + return "CV_16UC1"; + + break; + case CV_16UC2: + return "CV_16UC2"; + + break; + case CV_16UC3: + return "CV_16UC3"; + + break; + case CV_16UC4: + return "CV_16UC4"; + + break; + case CV_16SC1: + return "CV_16SC1"; + + break; + case CV_16SC2: + return "CV_16SC2"; + + break; + case CV_16SC3: + return "CV_16SC3"; + + break; + case CV_16SC4: + return "CV_16SC4"; + + break; + case CV_32SC1: + return "CV_32SC1"; + + break; + case CV_32SC2: + return "CV_32SC2"; + + break; + case CV_32SC3: + return "CV_32SC3"; + + break; + case CV_32SC4: + return "CV_32SC4"; + + break; + case CV_32FC1: + return "CV_32FC1"; + + break; + case CV_32FC2: + return "CV_32FC2"; + + break; + case CV_32FC3: + return "CV_32FC3"; + + break; + case CV_32FC4: + return "CV_32FC4"; + + break; + case CV_64FC1: + return "CV_64FC1"; + + break; + case CV_64FC2: + return "CV_64FC2"; + + break; + case CV_64FC3: + return "CV_64FC3"; + + break; + case CV_64FC4: + return "CV_64FC4"; + + break; + default: + break; + } + return ""; +} + +QString MiscFunctions::matDepthToText(int depth) +{ + switch( depth ) { - const QRgb *lineSrc = reinterpret_cast( sourceImage.scanLine(y) ); - const QRgb *lineDst = reinterpret_cast( destinationImage.scanLine(y) ); - for (int x = 0; x < width; x++) - { - int red1 = qRed(lineSrc[x]); - int red2 = qRed(lineDst[x]); - int green1 = qGreen(lineSrc[x]); - int green2 = qGreen(lineDst[x]); - int blue1 = qBlue(lineSrc[x]); - int blue2 = qBlue(lineDst[x]); - - if (interactive) - { - val = ( ABS(red1 - red2) + ABS(green1 - green2) + ABS(blue1 - blue2) ) / 3.0; - if (val > 0.0) - { - if (val > res.meanError) - valueMask = qRgba(255,255,0,opacity); - else - valueMask = qRgba(255,0,0,opacity); - } - else - { - valueMask = qRgba(0,0,0,0); - } - res.maskDiffImage.setPixel(x,y,valueMask); - } - - // for the standard deviation - int rr = (red1 - red2); - int gg = (green1 - green2); - int bb = (blue1 - blue2); - res.stantdardDeviation += (rr - res.meanError) * (rr - res.meanError) + (gg - res.meanError) * (gg - res.meanError) + (bb - res.meanError) * (bb - res.meanError); - } + case CV_8U: + return "8U"; + + break; + case CV_8S: + return "8S"; + + break; + case CV_16U: + return "16U"; + + break; + case CV_16S: + return "16S"; + + break; + case CV_32S: + return "32S"; + + break; + case CV_32F: + return "32F"; + + break; + case CV_64F: + return "64F"; + + break; + default: + break; } + return ""; +} + +quint64 MiscFunctions::getFileSize(const QString &file) +{ + return QFile(file).size(); +} - res.stantdardDeviation = sqrt ( res.stantdardDeviation / (3.0f * nb) ); - if (res.nbErr) - return false; +QString MiscFunctions::bytesToString(quint64 bytes) +{ + quint64 size = bytes; - return true; + QString bytesStr; + if ( !(size >> 10) ) + bytesStr = QString::number(size) + ' ' + QObject::tr("Bytes"); + else if ( !(size >> 20) ) + bytesStr = QString::number(size / 1024.0, 'f', 3) + ' ' + QObject::tr("KB","Kilobyte"); + else if ( !(size >> 30) ) + bytesStr = QString::number( (size >> 10) / 1024.0, 'f', 3 ) + ' ' + QObject::tr("MB","Megabyte"); + else if ( !(size >> 40) ) + bytesStr = QString::number( (size >> 20) / 1024.0, 'f', 3 ) + ' ' + QObject::tr("GB","Gigabyte"); + else + bytesStr = QString::number( (size >> 30) / 1024.0, 'f', 3 ) + ' ' + QObject::tr("TB","Terabyte"); + + return bytesStr; } -void MiscFunctions::transformChannel(int &red1,int &red2,int &green1,int &green2,int &blue1,int &blue2,int method) +QString MiscFunctions::pixelsToString(quint64 pixels) { - switch (method) + quint64 size = pixels; + + QString bytesStr; + if ( !(size >> 10) ) + bytesStr = QString::number(size) + ' ' + QObject::tr("Pixels"); + else if ( !(size >> 20) ) + bytesStr = QString::number(size / 1000.0, 'f', 3) + ' ' + QObject::tr("Kp","Kilopixel"); + else if ( !(size >> 30) ) + bytesStr = QString::number( (size >> 10) / 1000.0, 'f', 3 ) + ' ' + QObject::tr("Mp","Megapixel"); + else if ( !(size >> 40) ) + bytesStr = QString::number( (size >> 20) / 1000.0, 'f', 3 ) + ' ' + QObject::tr("Gp","Gigapixel"); + else + bytesStr = QString::number( (size >> 30) / 1000.0, 'f', 3 ) + ' ' + QObject::tr("Tp","Terapixel"); + + return bytesStr; +} + +//----------------------------------------------------------------------------- +// Computes a three channel (BGR) histogram from Paul Filitchkin histLib +//----------------------------------------------------------------------------- +void MiscFunctions::ComputeHistogramBGR( + const cv::Mat& Image, + cv::Mat& HistB, + cv::Mat& HistG, + cv::Mat& HistR) +{ + const cv::Mat* pImageBGR = NULL; + cv::Mat ImageBGR; + + switch ( Image.type() ) { - case METHOD_BYCHANNELMEAN: + case CV_8UC3: + pImageBGR = &Image; + break; + + case CV_8UC4: { - float c1 = (red1 + green1 + blue1) / 3.0f; - float c2 = (red2 + green2 + blue2) / 3.0f; - red1 = green1 = blue1 = (int) c1; - red2 = green2 = blue2 = (int) c2; + cvtColor(Image, ImageBGR, CV_RGBA2RGB); + pImageBGR = &ImageBGR; break; } - case METHOD_BYLIGHTNESS: + + default: + LogHandler::getInstance()->reportError("MiscFunctions::ComputeHistogramBGR: the data format/type is not supported by the function"); + break; + } + + // Initialize histogram settings + int histSize[] = {256}; + float Range[] = {0, 256}; //{0, 256} = 0 to 255 + const float* Ranges[] = {Range}; + int chanB[] = {0}; + int chanG[] = {1}; + int chanR[] = {2}; + + calcHist(pImageBGR, 1, chanB, cv::Mat(), // do not use mask + HistB, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); + + calcHist(pImageBGR, 1, chanG, cv::Mat(), // do not use mask + HistG, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); + + calcHist(pImageBGR, 1, chanR, cv::Mat(), // do not use mask + HistR, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); +} + +//----------------------------------------------------------------------------- +// Computes a single channel (Value) histogram +//----------------------------------------------------------------------------- +void MiscFunctions::computeHistogramValue(const cv::Mat& Image, cv::Mat& Hist) +{ + // Create 1 channel image to get a value representation + cv::Mat ImageValue = cv::Mat(Image.size(), CV_8UC1); + + switch ( Image.type() ) + { + case CV_8UC1: + Image.copyTo(ImageValue); + break; + + case CV_8UC3: { - float y1 = 0.30 * red1 + 0.59 * green1 + 0.11 * blue1; - float y2 = 0.30 * red2 + 0.59 * green2 + 0.11 * blue2; - red1 = green1 = blue1 = (int) y1; - red2 = green2 = blue2 = (int) y2; + cv::Mat ImageHSV = cv::Mat(Image.size(), CV_8UC3); + std::vector ChannlesHsv; + + cvtColor(Image, ImageHSV, CV_BGR2HSV); + cv::split(ImageHSV, ChannlesHsv); + ImageValue = ChannlesHsv[2]; break; } - case METHOD_BYCHANNEL: - // nothing to do - default: + case CV_8UC4: { + cv::Mat ImageHSV = cv::Mat(Image.size(), CV_8UC3); + cv::Mat ImageBGR = cv::Mat(Image.size(), CV_8UC3); + std::vector ChannlesHsv; + + cvtColor(Image, ImageBGR, CV_RGBA2RGB); + cvtColor(ImageBGR, ImageHSV, CV_RGBA2RGB); + cv::split(ImageHSV, ChannlesHsv); + ImageValue = ChannlesHsv[2]; break; } + + default: + LogHandler::getInstance()->reportError("MiscFunctions::computeHistogramValue: the data format/type is not supported by the function"); + break; + } + + // Initialize histogram settings + int histSize[] = { 256 }; + float Range[] = { 0, 256 }; //{0, 256} = 0 to 255 + const float *Ranges[] = { Range }; + int channels[] = { 0 }; + + calcHist(&ImageValue, 1, channels, cv::Mat(), // do not use mask + Hist, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); +} + +void MiscFunctions::computeHistogram1D(const cv::Mat& img, cv::Mat& hist) +{ + if (img.channels() != 1) + return; + + // Initialize histogram settings + int histSize[] = { 256 }; + float Range[] = { 0, 256 }; //{0, 256} = 0 to 255 + const float *Ranges[] = { Range }; + int channels[] = { 0 }; + + calcHist(&img, 1, channels, cv::Mat(), // do not use mask + hist, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); +} + +QString MiscFunctions::dataToText(const cv::Mat& img, int x, int y) +{ + if ( img.empty() || x < 0 || y < 0 || x > (img.cols - 1) || y > (img.rows - 1) ) + return ""; + + QString data; + switch( img.type() ) + { + case CV_8UC1: + + //for (int i = 0 ; i < img.channels(); i++) + data += QObject::tr("Value: %1").arg( img.at(y,x) ); + break; + case CV_8UC2: + data += QObject::tr("Value: %1,").arg(img.at(y,x)[0]); + data += QObject::tr("Alpha: %1").arg(img.at(y,x)[1]); + break; + case CV_8UC3: // BGR !! + data += QObject::tr("Red: %1,").arg(img.at(y,x)[2]); + data += QObject::tr("Green: %1,").arg(img.at(y,x)[1]); + data += QObject::tr("Blue: %1").arg(img.at(y,x)[0]); + break; + case CV_8UC4: + data += QObject::tr("Red: %1,").arg(img.at(y,x)[2]); + data += QObject::tr("Green: %1,").arg(img.at(y,x)[1]); + data += QObject::tr("Blue: %1,").arg(img.at(y,x)[0]); + data += QObject::tr("Alpha: %1").arg(img.at(y,x)[4]); + break; + case CV_8SC1: + data += QObject::tr("not yet implemented (%1)").arg("CV_8SC1"); + break; + case CV_8SC2: + data += QObject::tr("not yet implemented (%1)").arg("CV_8SC2"); + break; + case CV_8SC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_8SC3"); + break; + case CV_8SC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_8SC4"); + break; + case CV_16UC1: + data += QObject::tr("Value: %1").arg( img.at(y,x) ); + break; + case CV_16UC2: + data += QObject::tr("Value: %1,").arg(img.at(y,x)[0]); + data += QObject::tr("Alpha: %1").arg(img.at(y,x)[1]); + break; + case CV_16UC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_16UC3"); + break; + case CV_16UC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_16UC4"); + break; + case CV_16SC1: + data += QObject::tr("not yet implemented (%1)").arg("CV_16SC1"); + break; + case CV_16SC2: + data += QObject::tr("not yet implemented (%1)").arg("CV_16SC2"); + break; + case CV_16SC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_16SC3"); + break; + case CV_16SC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_16SC4"); + break; + case CV_32SC1: + data += QObject::tr("not yet implemented (%1)").arg("CV_32SC1"); + break; + case CV_32SC2: + data += QObject::tr("not yet implemented (%1)").arg("CV_32SC2"); + break; + case CV_32SC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_32SC3"); + break; + case CV_32SC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_32SC4"); + break; + case CV_32FC1: + data += QObject::tr("Value: %1").arg( img.at(y,x) ); + break; + case CV_32FC2: + data += QObject::tr("Value: %1,").arg(img.at(y,x)[0]); + data += QObject::tr("Alpha: %1").arg(img.at(y,x)[1]); + break; + case CV_32FC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_32FC3"); + break; + case CV_32FC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_32FC4"); + break; + case CV_64FC1: + data += QObject::tr("not yet implemented (%1)").arg("CV_64FC1"); + break; + case CV_64FC2: + data += QObject::tr("not yet implemented (%1)").arg("CV_64FC2"); + break; + case CV_64FC3: + data += QObject::tr("not yet implemented (%1)").arg("CV_64FC3"); + break; + case CV_64FC4: + data += QObject::tr("not yet implemented (%1)").arg("CV_64FC4"); + break; + default: + break; } + + return data; } diff -Nru diffimg-1.5.0/src/MiscFunctions.h diffimg-2.0.0/src/MiscFunctions.h --- diffimg-1.5.0/src/MiscFunctions.h 2013-02-06 16:36:05.000000000 +0000 +++ diffimg-2.0.0/src/MiscFunctions.h 2013-05-15 17:31:28.000000000 +0000 @@ -1,71 +1,89 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _MISCFUNCTIONS_H_ -#define _MISCFUNCTIONS_H_ - -#include - -struct DiffStruct -{ - QImage maskDiffImage; // mask image - QImage diffImage; // diff image - unsigned int nbErr; - double meanError; - double stantdardDeviation; - double rmsDiff; - - // histograms - int minError; - int maxError; - double valueR[2 * 256]; - double valueG[2 * 256]; - double valueB[2 * 256]; -}; - -class MiscFunctions -{ -public: - - enum DiffMethodType - { - METHOD_BYCHANNEL = 0, - METHOD_BYCHANNELMEAN, - METHOD_BYLIGHTNESS, - METHOD_END - }; - - // images function - static QString getAvailablesImageFormats(); - static QStringList getAvailablesImageFormatsList(); - static QMap getLongImageFormats(); - - // translations functions - static QString getTranslationsPath(); - static QMap getAvailableLanguages(); - static void setDefaultLanguage(); - static void setLanguage(const QString& lang); - - static void updateApplicationIdentity(); - static bool computeDifferencePixels(const QImage &sourceImage, const QImage &destinationImage, DiffStruct &res, int opacity, bool interactive, int method = METHOD_BYCHANNEL ); - static void transformChannel(int &red1,int &red2,int &green1,int &green2,int &blue1,int &blue2,int method); -}; - -#endif // _MISCFUNCTIONS_H_ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _MISCFUNCTIONS_H_ +#define _MISCFUNCTIONS_H_ + +#include +#include + +namespace cv +{ +class Mat; +} + +struct DiffStruct +{ + QImage maskDiffImage; // mask image + QImage diffImage; // diff image + unsigned int nbErr; + double meanError; + double stantdardDeviation; + double rmsDiff; + + // histograms + int minError; + int maxError; + double valueR[2 * 256]; + double valueG[2 * 256]; + double valueB[2 * 256]; +}; + +class MiscFunctions +{ +public: + + enum DiffMethodType + { + METHOD_BYCHANNEL = 0, + METHOD_BYCHANNELMEAN, + METHOD_BYLIGHTNESS, + METHOD_END + }; + + // images function + static QString getAvailablesImageFormats(); + static QStringList getAvailablesImageFormatsList(); + static QMap getLongImageFormats(); + + // translations functions + static QString getTranslationsPath(); + static QMap getAvailableLanguages(); + static void setDefaultLanguage(); + static void setLanguage(const QString& lang); + + static void updateApplicationIdentity(); + + static QString matTypeToText(int); + static QString matDepthToText(int); + static quint64 getFileSize(const QString &file); + static QString bytesToString(quint64 bytes); + static QString pixelsToString(quint64 pixels); + + // opencv tools + static QImage opencvMatToQImage(const cv::Mat& mat, bool deepCopy = false); + static cv::Mat qImageToOpencvMat(const QImage &); + static void computeHistogramValue(const cv::Mat& Image, cv::Mat& Hist); + static void ComputeHistogramBGR(const cv::Mat& Image,cv::Mat& HistB, cv::Mat& HistG, cv::Mat& HistR); + static void computeHistogram1D(const cv::Mat& Image, cv::Mat& Hist); + static QString dataToText(const cv::Mat& img, int x, int y); +}; + +#endif // _MISCFUNCTIONS_H_ diff -Nru diffimg-1.5.0/src/PropertyWidget.cpp diffimg-2.0.0/src/PropertyWidget.cpp --- diffimg-1.5.0/src/PropertyWidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/PropertyWidget.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,93 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include +#include +#include + +#include + +#include "PropertyWidget.h" +#include "qtpropertymanager.h" +#include "BaseMetric.h" + +PropertyWidget::PropertyWidget( QWidget *parent ) : + QtTreePropertyBrowser( parent ) +{ + m_variantManager = new QtVariantPropertyManager(this); +} + +void PropertyWidget::displayData(BaseMetric *met) +{ + clear(); + if (!met) + return; + + displayProperties(met); + displayStatistics(met); +} + +void PropertyWidget::displayProperties(BaseMetric *met) +{ + QtVariantProperty *parent; + + const QList &props = met->getProperties(); + + // Range list + parent = m_variantManager->addProperty( QVariant::String, tr("Properties") ); + parent->setValue(""); + addProperty(parent); + + foreach (const ImageProperty &prop, props) + { + QtVariantProperty *property = m_variantManager->addProperty( QVariant::String, prop.name ); + property->setValue(prop.value); + property->setToolTip(prop.desc); + property->setStatusTip(prop.value); + parent->addSubProperty(property); + } +} + +void PropertyWidget::displayStatistics(BaseMetric *met) +{ + QtVariantProperty *property; + QtVariantProperty *parent; + + const QList params = met->getOutputParams(); + + // Range list + parent = m_variantManager->addProperty( QVariant::String, tr("Statistics") ); + parent->setValue(""); + addProperty(parent); + + foreach (MetricParam * param, params) + { + if ( !param->isValid() ) + property = m_variantManager->addProperty( QVariant::String, param->name + " (*)" ); + else + property = m_variantManager->addProperty( QVariant::String, param->name ); + if (param->value.type() == QMetaType::Double || param->value.type() == QMetaType::Float) + property->setValue( QString().sprintf( "%.5f",param->value.toFloat() ) ); + else + property->setValue(param->value); + property->setToolTip(param->desc); + parent->addSubProperty(property); + } +} diff -Nru diffimg-1.5.0/src/PropertyWidget.h diffimg-2.0.0/src/PropertyWidget.h --- diffimg-1.5.0/src/PropertyWidget.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/PropertyWidget.h 2013-05-15 06:04:12.000000000 +0000 @@ -0,0 +1,57 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _PROPERTYWIDGET_H_ +#define _PROPERTYWIDGET_H_ + +#include +#include + +#include "qttreepropertybrowser.h" +#include "qtvariantproperty.h" + +class BaseMetric; + +class PropertyWidget : public QtTreePropertyBrowser +{ + Q_OBJECT + +public: + + PropertyWidget( QWidget *parent = 0 ); + ~PropertyWidget() {} + + void displayData(BaseMetric *met); + +public slots: + +signals: + +protected: + +private: + + void displayProperties(BaseMetric *met); + void displayStatistics(BaseMetric *met); + + QtVariantPropertyManager *m_variantManager; +}; + +#endif // _PROPERTYWIDGET_H_ diff -Nru diffimg-1.5.0/src/ScrollImageWidget.cpp diffimg-2.0.0/src/ScrollImageWidget.cpp --- diffimg-1.5.0/src/ScrollImageWidget.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/ScrollImageWidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#include -#include -#include -#include - -#include - -#include "ScrollImageWidget.h" -#include "ImageWidget.h" - -const float DeltaZoom = 1.2f; - -ScrollImageWidget::ScrollImageWidget( QWidget *parent ) : - QScrollArea( parent ), - m_moving(false), - m_pw(NULL), - m_zoomFactor(1.0f) -{ - setWidgetResizable( true ); - - m_pw = new ImageWidget( this ); - setWidget( m_pw ); - setMouseTracking(true); - - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - // to allow get the mouse position - //viewport()->setMouseTracking(true); - widget ()->setMouseTracking(true); - - connect( horizontalScrollBar(), SIGNAL( valueChanged(int) ), this, SIGNAL( horizontalScroll(int) ) ); - connect( verticalScrollBar(), SIGNAL( valueChanged(int) ), this, SIGNAL( verticalScroll(int) ) ); -} - -//------------------------------------------------------------------------- - -ScrollImageWidget::~ScrollImageWidget() -{ - //delete pw_; -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { - lastPoint = event->pos(); - m_moving = true; - setCursor(Qt::OpenHandCursor); - } -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setScrollValue(const QPoint & p) -{ - horizontalScrollBar()->setValue( p.x() ); - verticalScrollBar()->setValue( p.y() ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setHorizontalScrollValue(int val) -{ - horizontalScrollBar()->setValue( val ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setVerticalScrollValue(int val) -{ - verticalScrollBar()->setValue( val ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::mouseMoveEvent(QMouseEvent *event) -{ - if ( (event->buttons() & Qt::LeftButton) && m_moving ) - { - const int x = horizontalScrollBar()->value() + lastPoint.x() - event->pos().x(); - - //horizontalScrollBar()->setValue( x ); - const int y = verticalScrollBar()->value() + lastPoint.y() - event->pos().y(); - - //verticalScrollBar()->setValue( y ); - lastPoint = event->pos(); - setScrollValue( QPoint(x,y) ); - emit scrollPosition( QPoint(x,y) ); - } - emit mousePosition( event->pos() ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && m_moving) - { - m_moving = false; - setCursor(Qt::ArrowCursor); - emit somethingChanged(); - } -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::wheelEvent( QWheelEvent *event ) -{ - float f; - - //qDebug("a wheel event is received !!! object = %x with event %x",this,event); - if (event->delta() < 0) - f = m_zoomFactor * DeltaZoom; - else - f = m_zoomFactor / DeltaZoom; - - setZoomFactor( f ); - - emit currentZoomFactor(f); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setZoomFactor( float f) -{ - //qDebug("setZoomFactor = %f on object = %x ",f,this); - - // controle du zoom max => l'image zoomée ne doit pas depsser 5000x5000 - if (m_pmSize.width() * f > 10000.0f) - f = 10000.0f / m_pmSize.width(); - if (m_pmSize.height() * f > 10000.0f) - f = 10000.0f / m_pmSize.height(); - - float delta_zoom = f / m_zoomFactor; - - // if (f == m_zoomFactor) - // return; - - // decalage sans zoom - float oldOffsetX = horizontalScrollBar()->value() / m_zoomFactor; - float oldOffsetY = verticalScrollBar()->value() / m_zoomFactor; - - // disable update for flicking - //setUpdatesEnabled(false); - - m_zoomFactor = f; - - //qDebug("m_zoomFactor = %f",m_zoomFactor); - m_pw->setZoomFactor(m_zoomFactor); - - // nouveau decalage avec zoom - float newOffsetX; - float newOffsetY; - - newOffsetX = (oldOffsetX) * m_zoomFactor + (delta_zoom - 1) * viewport()->width() / 2; - newOffsetY = (oldOffsetY) * m_zoomFactor + (delta_zoom - 1) * viewport()->height() / 2; - - // recentrage - horizontalScrollBar()->setValue( (int)(newOffsetX ) ); - verticalScrollBar()->setValue( (int)(newOffsetY) ); - - // enable redraw - //setUpdatesEnabled(true); - - emit somethingChanged(); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setImage(const QImage &image) -{ - m_pmSize = image.size(); - m_pw->setImage(image); -} - -//------------------------------------------------------------------------- - -QPoint ScrollImageWidget::getScrollValue() -{ - return QPoint( horizontalScrollBar()->value(),verticalScrollBar()->value() ); -} - -//------------------------------------------------------------------------- - -QPoint ScrollImageWidget::getScrollMaximum() -{ - return QPoint( horizontalScrollBar()->maximum(),verticalScrollBar()->maximum() ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::setScrollMaximum(const QPoint &p) -{ - //qDebug("setScrollMaximum = %d/%d on object = %x ",p.x(),p.y(),this); - - horizontalScrollBar()->setMaximum( p.x() ); - verticalScrollBar()->setMaximum( p.y() ); -} - -//------------------------------------------------------------------------- - -void ScrollImageWidget::fitToWindow() -{ - if ( !m_pmSize.isValid() ) - return; - - QSize vs = viewport()->size(); - - QSize imgs = m_pmSize; - - float valy = vs.height() / (float)imgs.height(); - float valx = vs.width() / (float)imgs.width(); - - if (valx > valy) - { - setZoomFactor(valy); - } - else - { - setZoomFactor(valx); - } - emit currentZoomFactor(m_zoomFactor); -} - -//------------------------------------------------------------------------- - -QColor ScrollImageWidget::getColorAtPosition(const QPoint &pos) -{ - QSize srcSize = m_pmSize; - QSize vs = viewport()->size(); - QColor color; - - float zoomFactor = m_zoomFactor; - - int offx = (int)( ( horizontalScrollBar()->value() ) / zoomFactor ); - int offy = (int)( ( verticalScrollBar()->value() ) / zoomFactor ); - - int decalx = 0; - int decaly = 0; - - if ( srcSize.width() * zoomFactor < vs.width() ) - decalx = (int)(vs.width() - srcSize.width() * zoomFactor) / 2; - - if ( srcSize.height() * zoomFactor < vs.height() ) - decaly = (int)(vs.height() - srcSize.height() * zoomFactor) / 2; - - int posx = (int)(pos.x() / zoomFactor + offx - decalx / zoomFactor + 0.5); - int posy = (int)(pos.y() / zoomFactor + offy - decaly / zoomFactor + 0.5); - - if ( posx >=0 && posx < srcSize.width() && posy >= 0 && posy < srcSize.height() ) - { - return QColor( m_pw->getImage().pixel(posx,posy) ); - } - - return color; -} diff -Nru diffimg-1.5.0/src/ScrollImageWidget.h diffimg-2.0.0/src/ScrollImageWidget.h --- diffimg-1.5.0/src/ScrollImageWidget.h 2013-02-06 16:36:05.000000000 +0000 +++ diffimg-2.0.0/src/ScrollImageWidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ - -/****************************************************************************** - DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _SCROLLIMAGEWIDGET_H_ -#define _SCROLLIMAGEWIDGET_H_ - -#include -#include - -class ImageWidget; - -class ScrollImageWidget : - public QScrollArea -{ - Q_OBJECT - -public: - - ScrollImageWidget( QWidget *parent = 0 ); - ~ScrollImageWidget(); - float getZoomFactor() const {return m_zoomFactor; } - - void setImage(const QImage &); - QPoint getScrollValue(); - QPoint getScrollMaximum(); - QColor getColorAtPosition(const QPoint & ); - -public slots: - - void setZoomFactor( float ); - void setScrollValue( const QPoint &); - void setScrollMaximum(const QPoint&); - void setHorizontalScrollValue(int); - void setVerticalScrollValue(int); - void fitToWindow(); - -signals: - - void somethingChanged(); - void mousePosition(const QPoint&); - void scrollPosition(const QPoint&); - void horizontalScroll(int); - void verticalScroll(int); - - void currentZoomFactor(float); - -protected: - - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void wheelEvent( QWheelEvent *event ); - -private: - - bool m_moving; - QPoint lastPoint; - QSize m_pmSize; - ImageWidget *m_pw; - float m_zoomFactor; -}; - -#endif // _SCROLLIMAGEWIDGET_H_ diff -Nru diffimg-1.5.0/src/SplashScreen.cpp diffimg-2.0.0/src/SplashScreen.cpp --- diffimg-1.5.0/src/SplashScreen.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/SplashScreen.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** - SyncWall: Wallpaper manager - Copyright(C) 2011-2012 xbee@xbee.net + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include "SplashScreen.h" @@ -27,13 +27,26 @@ SplashScreen::SplashScreen(const QPixmap& pixmap, unsigned int minimalDisplayDuration, int screenId, bool transparentBackground, Qt::WindowFlags /* f */) : QSplashScreen(), + m_nextWidget(NULL), m_timerFired(false), m_currAlign(Qt::AlignLeft), m_currColor(Qt::black), m_screenId(screenId) { + setWindowModality(Qt::ApplicationModal); setSplash(pixmap,transparentBackground); - init(minimalDisplayDuration); + startTimer(minimalDisplayDuration); +} + +void SplashScreen::timerEvent(QTimerEvent *event) +{ + killTimer( event->timerId() ); + m_timerFired = true; + if (m_nextWidget) + { + m_nextWidget->show(); + } + QSplashScreen::finish(m_nextWidget); } void SplashScreen::setSplash(const QPixmap& pixmap,bool transparentBackground) @@ -75,46 +88,14 @@ void SplashScreen::delayedFinish(QWidget *next) { - if (m_timerFired) - { - if (next) - { - next->show(); - QSplashScreen::finish(next); - } - else if (nextWidget) - { - nextWidget->show(); - QSplashScreen::finish(nextWidget); - } - } - else - { - nextWidget = next; - } + m_nextWidget = next; + if (m_timerFired && m_nextWidget) + m_nextWidget->show(); } -void SplashScreen::init(unsigned int minimalDisplayDuration) +void SplashScreen::closeEvent(QCloseEvent *event) { - nextWidget = 0; - setWindowModality(Qt::ApplicationModal); - - if ( minimalDisplayDuration != 0 && !pixmap().isNull() ) - { - m_timerFired = false; - QTimer::singleShot( minimalDisplayDuration, this, SLOT( close() ) ); - } - else - { - m_timerFired = true; - } -} - -void SplashScreen::finish(void) -{ - m_timerFired = true; - emit finished(); - delayedFinish(); + QWidget::closeEvent(event); } void SplashScreen::drawContents(QPainter *painter) diff -Nru diffimg-1.5.0/src/SplashScreen.h diffimg-2.0.0/src/SplashScreen.h --- diffimg-1.5.0/src/SplashScreen.h 2013-02-06 16:36:05.000000000 +0000 +++ diffimg-2.0.0/src/SplashScreen.h 2013-05-15 05:58:26.000000000 +0000 @@ -1,68 +1,69 @@ - -/****************************************************************************** - SyncWall: Wallpaper manager - Copyright(C) 2011-2012 xbee@xbee.net - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *******************************************************************************/ - -#ifndef _SPLASHSCREEN_H_ -#define _SPLASHSCREEN_H_ - -#include -#include -#include -#include -#include - -class SplashScreen : - public QSplashScreen -{ - Q_OBJECT - -public: - - SplashScreen(const QPixmap& pixmap, unsigned int minimalDisplayDuration = 0, int screenId = -1, bool transparentBackground = true, Qt::WindowFlags f = 0); - - void delayedFinish(QWidget *next = 0); - void showMessage(const QString &message, int alignment = Qt::AlignLeft, const QColor &color = Qt::black); - -signals: - - void finished(); - -protected: - - void drawContents(QPainter *painter); - -private slots: - - void finish(void); - -private: - - void init(unsigned int minimalDisplayDuration); - void setSplash(const QPixmap& pixmap,bool transparentBackground = true); - - QWidget *nextWidget; - bool m_timerFired; - QPixmap m_pixmap; - QString m_currStatus; - int m_currAlign; - QColor m_currColor; - int m_screenId; -}; - -#endif // _SPLASHSCREEN_H_ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _SPLASHSCREEN_H_ +#define _SPLASHSCREEN_H_ + +#include +#include +#include +#include +#include + +class SplashScreen : + public QSplashScreen +{ + Q_OBJECT + +public: + + SplashScreen(const QPixmap& pixmap, unsigned int minimalDisplayDuration = 0, int screenId = -1, bool transparentBackground = true, Qt::WindowFlags f = 0); + + void delayedFinish(QWidget *next = 0); + void showMessage(const QString &message, int alignment = Qt::AlignLeft, const QColor &color = Qt::black); + +signals: + + void finished(); + +protected: + + void drawContents(QPainter *painter); + +private slots: + + void closeEvent(QCloseEvent *event); + void timerEvent(QTimerEvent *event); + +private: + + void init(unsigned int minimalDisplayDuration); + void setSplash(const QPixmap& pixmap,bool transparentBackground = true); + + QWidget *m_nextWidget; + bool m_timerFired; + QPixmap m_pixmap; + QString m_currStatus; + int m_currAlign; + QColor m_currColor; + int m_screenId; +}; + +#endif // _SPLASHSCREEN_H_ diff -Nru diffimg-1.5.0/src/main.cpp diffimg-2.0.0/src/main.cpp --- diffimg-1.5.0/src/main.cpp 2013-03-24 05:18:17.000000000 +0000 +++ diffimg-2.0.0/src/main.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** DiffImg: image difference viewer - Copyright(C) 2011-2012 xbee@xbee.net + Copyright(C) 2011-2013 xbee@xbee.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ #include @@ -28,6 +28,9 @@ #include "AppSettings.h" #include "MiscFunctions.h" #include "SplashScreen.h" +#include "MetricsRegistering.h" +#include "MetricsManager.h" +#include "BaseMetric.h" const int EXIT_OK = 0; const int EXIT_NOK = 1; @@ -128,6 +131,53 @@ #endif } +void listMetrics() +{ + QTextStream out(stdout); + out << endl; + out << QObject::tr("Image Difference tool.") << endl; + out << endl; + out << QObject::tr("Available metrics:") << endl; + out << endl; + + // metrics registering + MetricsRegistering::registerAll(); + + // + const QList &list = MetricsManager::getMetrics(); + foreach (BaseMetric * met, list) + { + out << met->getType() << ": " << met->getName() << endl; + + // input parameters + const QList &listInput = met->getInputParams(); + if ( !listInput.isEmpty() ) + { + out << QObject::tr("\tInput parameters:") << endl; + foreach (MetricParam * param, listInput) + { + out << "\t\t" << param->type << " = " << param->threshold.toString() << " (" << param->name << ")" << endl; + } + } + + // output parameters + const QList &listOutput = met->getOutputParams(); + out << QObject::tr("\tOutput parameters:") << endl; + foreach (MetricParam * param, listOutput) + { + out << "\t\t" << param->type << " = " << param->threshold.toString() << " (" << param->name << ")" << endl; + } + + out << endl; + } + out << endl; + out << QObject::tr("How to use batch mode:") << endl; + out << QObject::tr("Example 1: --batch --metric PerChannelMeanMetric : Use of per channel mean metric","Do not translate parameters, only comments") << endl; + out << QObject::tr("Example 2: --batch --metric PerChannelMetric --threshold ErrorNum=250 : Use of per channel metric and exit with error if pixel with difference number is upper to 250","Do not translate parameters, only comments") << endl; + out << QObject::tr("Example 3: --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 img1.png img2.png : Use of perceptual metric with some input parameters set and exit with error if pixel with difference number is upper to 250","Do not translate parameters, only comments") << endl; + out << endl; +} + void usage() { QTextStream out(stdout); @@ -137,20 +187,31 @@ out << QObject::tr("Usage: ") << QApplication::arguments().at(0) << " " << QObject::tr("[options]") << " " << QObject::tr("img1 img2") << endl; out << QObject::tr("") << endl; out << QObject::tr("Following options are known:") << endl; - out << QObject::tr(" --batch - batch mode. Differences are computed without GUI and return code is used as result.") << endl; - out << QObject::tr(" --rms-threshold value - [only for batch mode]. Threshold value for RMS computation.") << endl; - out << QObject::tr(" --diff-method value - [only for batch mode]. Method used to compute difference.") << endl; - out << QObject::tr(" --output xx.yy - [only for batch mode]. Save image difference in xx.yy file (only if comparison failed).") << endl; - out << QObject::tr(" Available methods: 0 - ") << QObject::tr("Difference is computed channel per channel") << endl; - out << QObject::tr(" 1 - ") << QObject::tr("Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3") << endl; - out << QObject::tr(" 2 - ") << QObject::tr("Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y)") << endl; + out << QObject::tr(" --list - list all metrics with their parameters.") << endl; out << QObject::tr("") << endl; - out << QObject::tr(" --help - displays this help.") << endl; - out << QObject::tr(" --reset-config - clear the saved preference parameters.") << endl; - out << endl; + out << QObject::tr(" --batch - batch mode. Differences are computed without GUI and return code is used as result.") << endl; + out << QObject::tr(" --metric - metric tag name. Display list of metrics with --list option.") << endl; + out << QObject::tr(" --in name=value - input parameter update.") << endl; + out << QObject::tr(" --threshold name=value - output parameter used to define comparison batch mode. If you set several threshold parameters, only the last one will be kept.") << endl; + + /* + + out << QObject::tr(" --rms-threshold value - [only for batch mode]. Threshold value for RMS computation.") << endl; + out << QObject::tr(" --diff-method value - [only for batch mode]. Method used to compute difference.") << endl; + out << QObject::tr(" --output xx.yy - [only for batch mode]. Save image difference in xx.yy file (only if comparison failed).") << endl; + out << QObject::tr(" Available methods: 0 - ") << QObject::tr("Difference is computed channel per channel") << endl; + out << QObject::tr(" 1 - ") << QObject::tr("Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3") << endl; + out << QObject::tr(" 2 - ") << QObject::tr("Difference is computed between both lightness values defined as lightness(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y)") << endl; + out << QObject::tr("") << endl; + out << QObject::tr(" --help - displays this help.") << endl; + out << QObject::tr(" --reset-config - clear the saved preference parameters.") << endl; + out << endl; + */ } -int makeDiffBatch(const QString &file1, const QString &file2, float threshold, int diffMethod, const QString &outFile) +// --batch --metric PerceptualMetric --in Gamma=1.8 --in FOV=75 --threshold ErrorNum=250 D:\developpements\qt4\DevAMoi\diffimg2.0\test\img1\IMG_0149.png D:\developpements\qt4\DevAMoi\diffimg2.0\test\img2\IMG_0149.png + +int makeDiffBatch(const QString &file1, const QString &file2, const QString & metric, const QMap &inParams, const QMap &outParams, const QString &outFile) { if ( !QFileInfo(file1).exists() || !QFileInfo(file2).exists() ) { @@ -158,47 +219,112 @@ return EXIT_NOK; } - DiffStruct res; - QImage sourceImage(file1); - QImage destinationImage(file2); - bool ok = MiscFunctions::computeDifferencePixels(sourceImage, destinationImage, res, 0, !outFile.isEmpty(), diffMethod ); - int width = sourceImage.width(); - int height = sourceImage.height(); + // metrics registering + MetricsRegistering::registerAll(); - // specific threshold set ? - if (!ok && threshold != 0.0f) + // + // + const QList &list = MetricsManager::getMetrics(); + BaseMetric * met = NULL; + bool found = false; + foreach (met, list) { - ok = (threshold > res.rmsDiff); + if (met->getType() == metric) + { + found = true; + break; + } } - // some difference are found - if (!ok) + if (!found) { - QTextStream out(stdout); + qWarning() << QObject::tr("Metric %1 unknown !!"); + return EXIT_NOK; + } - // print some statistics - out << QObject::tr("Files are different") << endl; + // set input parameters + const QList &listInput = met->getInputParams(); - QString percent = QString().sprintf( "%.1f",res.nbErr * 100.0f / (width * height) ); - out << QObject::tr("Error Num (pixels):") << QString("%1 (%2%)").arg( QString::number(res.nbErr) ).arg(percent) << endl; - out << QObject::tr("Mean error:") << QString::number(res.meanError) << endl; - out << QObject::tr("RMS Error:") << QString::number(res.rmsDiff) << endl; - out << QObject::tr("Standard deviation") << QString::number(res.stantdardDeviation) << endl; + if ( !inParams.isEmpty() && listInput.isEmpty() ) + { + qWarning() << QObject::tr("Metric %1 has no input parameter !!").arg( met->getType() ); + return EXIT_NOK; + } - // save result image if needed - if ( !outFile.isEmpty() ) + if ( !inParams.isEmpty() && !listInput.isEmpty() ) + { + foreach (MetricParam * param, listInput) { - bool valid = res.diffImage.save(outFile); - if (!valid) - out << QObject::tr("Saving of %1 failed !!").arg(outFile) << endl; + foreach ( const QString &key, inParams.keys() ) + { + if (param->type == key) + param->setThreshold(inParams[key]); + } } + } + const QList &listOutput = met->getOutputParams(); + + // clear saved settings + foreach (MetricParam * param, listOutput) + { + param->reset(); + param->used = false; + } + + if ( !outParams.isEmpty() ) + { + foreach (MetricParam * param, listOutput) + { + foreach ( const QString &key, outParams.keys() ) + { + if (param->type == key) + { + param->setThreshold(outParams[key]); + param->used = true; + } + } + } + } + + met->checkDifferences(file1,file2); + + if ( !met->isValid() ) + { + qWarning() << QObject::tr("Can't display difference, more information in the log panel ..."); return EXIT_NOK; } - qDebug() << QObject::tr("Files are identical"); + if ( !met->getPixelError() ) + { + qDebug() << QObject::tr("Files are identical"); + return EXIT_OK; + } - return EXIT_OK; + // display stats + QTextStream out(stdout); + + foreach (MetricParam * param, listInput) + { + out << " " << param->type << " = " << param->threshold.toString() << endl; + } + + foreach (MetricParam * param, listOutput) + { + if (param->used) + out << "* "; + else + out << " "; + out << param->type << " = " << param->value.toString() << " (threshold = " << param->threshold.toString() << ")" << endl; + } + + if ( met->selectedStatsIsValid() ) + { + out << QObject::tr("Files are identical (under the threshold)") << endl; + return EXIT_OK; + } + + return EXIT_NOK; } int main(int argc, char *argv[]) @@ -217,16 +343,21 @@ MiscFunctions::setDefaultLanguage(); // modifying base look +#ifdef Q_WS_WIN QApplication::setStyle(new QPlastiqueStyle); +#endif // check for special argument bool forceResetConfig = false; bool batchMode = false; float batchThreshold = 0.0f; QString outfile; - int diffMethod = MiscFunctions::METHOD_BYCHANNEL; QStringList args = QApplication::arguments(); QStringList files; + QString metric = "PerChannelMetric"; + QMap inParams; + QMap outParams; + bool errorInParameters = false; for ( int i = 1; i < args.count(); ++i ) { const QString arg = args.at(i); @@ -235,26 +366,43 @@ { forceResetConfig = true; } + else if ( arg == "--list" ) // list all metrics & parameters + { + listMetrics(); + return EXIT_OK; + } else if ( arg == "--batch" ) { batchMode = true; } - else if ( arg == "--rms-threshold" ) + else if ( arg == "--metric" ) { - batchThreshold = args.at(++i).toFloat(); + metric = args.at(++i); } - else if ( arg == "--diff-method" ) + else if ( arg == "--in" ) { - diffMethod = args.at(++i).toInt(); + QStringList in = args.at(++i).split("="); + if (in.size() == 2) + inParams[in[0]] = in[1]; + else + errorInParameters = true; + } + else if ( arg == "--threshold" ) + { + QStringList out = args.at(++i).split("="); + if (out.size() == 2) + outParams[out[0]] = out[1]; + else + errorInParameters = true; } else if ( arg == "--output" ) { - outfile = args.at(++i); + outfile = args.value(++i); } else if (arg == "--help") { usage(); - return 0; + return EXIT_OK; } else { @@ -265,6 +413,13 @@ if (files.size() == 1) // must have two parameters files << ""; + if (errorInParameters) + { + qWarning() << QObject::tr("Error in options !"); + usage(); + return EXIT_NOK; + } + // check batch mode if (batchMode) { @@ -272,13 +427,14 @@ if ( attachToConsole() ) redirectToConsole(); #endif + if (files.size() == 2) { - return makeDiffBatch(files[0],files[1],batchThreshold,diffMethod,outfile); + return makeDiffBatch(files[0],files[1],metric,inParams,outParams,outfile); } else { - qWarning() << QObject::tr("You must set two files as arguments in batch mode !!"); + qWarning() << QObject::tr("You must set at least two files as arguments in batch mode !!"); usage(); return EXIT_NOK; } @@ -288,7 +444,7 @@ // in order to display splashscreen on the same screen than application ... settings.beginGroup("MainWindow"); - int screenNumber = settings.value("screenNumber",0).toInt(); + int screenNumber = settings.value( "screenNumber",QApplication::desktop()->primaryScreen() ).toInt(); settings.endGroup(); settings.beginGroup("Application"); @@ -315,7 +471,11 @@ QObject::connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); - w.show(); + // splash screen + if (splashscreenAtStartup) + sScreen.delayedFinish(&w); + else + w.show(); if ( !files.isEmpty() ) w.setFiles(files[0],files[1]); diff -Nru diffimg-1.5.0/src/metrics/BaseMetric.cpp diffimg-2.0.0/src/metrics/BaseMetric.cpp --- diffimg-1.5.0/src/metrics/BaseMetric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/BaseMetric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,961 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include +#include +#include +#include + +#include + +#include "BaseMetric.h" +#include "LogHandler.h" +#include "AppSettings.h" +#include "MiscFunctions.h" + +int BaseMetric::defaultThresholdNumPixel = 100; +float BaseMetric::defaultThresholdMeanError = 0.3f; +float BaseMetric::defaultThresholdRMSError = 0.3f; +int BaseMetric::defaultThresholdMinError = 50; +int BaseMetric::defaultThresholdMaxError = 50; +float BaseMetric::defaultThresholdStandardDeviation = 0.3f; + +bool MetricParam::isValid() +{ + if ( value.toFloat() > threshold.toFloat() ) + return false; + + return true; +} + +void MetricParam::reset(bool all) +{ + value = defaultValue; + if (all) + threshold = defaultValue; +} + +void MetricParam::setThreshold(const QString &valText) +{ + switch ( threshold.type() ) + { + case QMetaType::Int: + { + threshold = valText.toInt(); + break; + } + case QMetaType::Double: + case QMetaType::Float: + { + threshold = valText.toFloat(); + break; + } + default: + break; + } +} + +//--------------------------------------------------------------------------- + +BaseMetric::BaseMetric(QObject *parent) : + QObject(parent), + m_type("Unknown"), + m_name( tr("Unknown") ), + m_desc( tr("No description") ), + m_valid(false), + m_nbPixelError(0), + m_maxError(0.0), + m_minError(0.0), + m_meanError(0.0), + m_minImage1(0.0), + m_minImage2(0.0), + m_maxImage1(0.0), + m_maxImage2(0.0), + m_init(false) +{ +} + +BaseMetric::~BaseMetric() +{ + saveSettings(); + clearOutputParams(); +} + +void BaseMetric::init() +{ + if (m_init) + return; + + createInputParams(); + createOutputParams(); + loadSettings(); + m_init = true; +} + +MetricParam *BaseMetric::addInputParam(MetricParam *p) +{ + m_inputParams << p; + return p; +} + +MetricParam *BaseMetric::addOutputParam(MetricParam *p) +{ + m_outputParams << p; + return p; +} + +void BaseMetric::clearOutputParams() +{ + qDeleteAll(m_outputParams); + m_outputParams.clear(); +} + +void BaseMetric::resetOutputParams() +{ + foreach (MetricParam * param, m_outputParams) + { + param->reset(false); + } +} + +void BaseMetric::createInputParams() +{ +} + +void BaseMetric::createOutputParams() +{ + // mean error + addOutputParam( new MetricParam("MeanError",tr("Mean error"),tr("Mean absolute error"),BaseMetric::defaultThresholdMeanError) ); + + // min error + addOutputParam( new MetricParam("MinError",tr("Min error"),tr("Minimum error"),0) ); + + // max error + addOutputParam( new MetricParam("MaxError",tr("Max error"),tr("Maximum error"),BaseMetric::defaultThresholdMaxError) ); + + addOutputParam( new MetricParam("StandardDeviation",tr("Standard deviation"),tr("Standard deviation"),BaseMetric::defaultThresholdStandardDeviation) ); + + // Root Mean Square + addOutputParam( new MetricParam("RMS",tr("RMS error deviation"),tr("Root Mean Square error"),BaseMetric::defaultThresholdRMSError) ); + + // nb error + addOutputParam( new MetricParam("ErrorNum",tr("Error num (pixels)"),tr("Number of different pixels"),BaseMetric::defaultThresholdNumPixel) ); + + // % error + addOutputParam( new MetricParam("ErrorPercent",tr("Error (% pixels)"),tr("Number of different pixels in %"),0.0f) ); +} + +MetricParam * BaseMetric::getInputParam(const QString &name) +{ + foreach (MetricParam * param, m_inputParams) + { + if (param->type == name) + return param; + } + return NULL; +} + +MetricParam * BaseMetric::getOutputParam(const QString &name) +{ + foreach (MetricParam * param, m_outputParams) + { + if (param->type == name) + return param; + } + return NULL; +} + +QPixmap BaseMetric::getLogo() const +{ + return QPixmap("::/providers/providers/unknown.png"); +} + +const QString & BaseMetric::getType() const +{ + return m_type; +} + +const QString & BaseMetric::getName() const +{ + return m_name; +} + +const QString & BaseMetric::getDesc() const +{ + return m_desc; +} + +const QList & BaseMetric::getProperties() const +{ + return m_properties; +} + +const QList & BaseMetric::getInputParams() +{ + init(); + return m_inputParams; +} + +const QList & BaseMetric::getOutputParams() +{ + init(); + return m_outputParams; +} + +void BaseMetric::computeStandardProperties() +{ + // Dimension (pixels) + m_properties << ImageProperty( tr("Dimension (pixels)"), tr("Dimension in pixel of images"),QString("%1x%2").arg(m_opencvInput1.cols).arg(m_opencvInput1.rows) ); + + // size (pixels) + m_properties << ImageProperty( tr("Size (pixels)"), tr("Size in pixel of images"),MiscFunctions::pixelsToString(m_opencvInput1.cols * m_opencvInput1.rows) ); + + // size (bytes) + int sz1 = MiscFunctions::getFileSize(m_file1); + m_properties << ImageProperty( tr("Size file1"), tr("Size in bytes of image"),tr("%1/%2").arg(sz1).arg( MiscFunctions::bytesToString(sz1) ) ); + int sz2 = MiscFunctions::getFileSize(m_file2); + m_properties << ImageProperty( tr("Size file2"), tr("Size in bytes of image"),tr("%1/%2").arg(sz2).arg( MiscFunctions::bytesToString(sz2) ) ); + + // image format + QMap longFormats = MiscFunctions::getLongImageFormats(); + QString ext1 = QFileInfo(m_file1).suffix(); + QString fm1 = tr("Unknown"); + if ( longFormats.contains(ext1) ) + fm1 = QString("%1 (%2)").arg(longFormats[ext1]).arg(ext1); + m_properties << ImageProperty( tr("Format file1"), tr("Format of the image"),QString("%1").arg(fm1) ); + + QString ext2 = QFileInfo(m_file1).suffix(); + QString fm2 = tr("Unknown"); + if ( longFormats.contains(ext2) ) + fm2 = QString("%1 (%2)").arg(longFormats[ext2]).arg(ext2); + m_properties << ImageProperty( tr("Format file2"), tr("Format of the image"),QString("%1").arg(fm2) ); + + // bands + m_properties << ImageProperty( tr("Band"), tr("Number of band in the image (3 for RGB image)"),QString::number( m_opencvInput1.channels() ) ); + + // depth + m_properties << ImageProperty( tr("Band depth"), tr("Number of bits per band (U:unsigned, S:signed, F:float)"),MiscFunctions::matDepthToText( m_opencvInput1.depth() ) ); + + cv::minMaxLoc(m_opencvInput1, &m_minImage1, &m_maxImage1); //Locate max and min values + cv::minMaxLoc(m_opencvInput2, &m_minImage2, &m_maxImage2); //Locate max and min values +} + +void BaseMetric::loadSettings() +{ + AppSettings settings; + + settings.beginGroup("Metrics"); + + settings.beginGroup(m_type); + + settings.beginGroup("Input"); + + foreach (MetricParam * param, m_inputParams) + { + QVariant t = settings.value(param->type,param->defaultValue); + t.convert( param->defaultValue.type() ); + param->threshold = t; + } + + settings.endGroup(); + + settings.beginGroup("Output"); + + foreach (MetricParam * param, m_outputParams) + { + QVariant t = settings.value(param->type,param->defaultValue); + t.convert( param->defaultValue.type() ); + param->threshold = t; + } + + QString typeUsed = settings.value("paramUsed","").toString(); + if ( !typeUsed.isEmpty() ) + setDiscriminatingParam( getOutputParam(typeUsed) ); + + settings.endGroup(); + settings.endGroup(); + settings.endGroup(); +} + +void BaseMetric::saveSettings() +{ + AppSettings settings; + + settings.beginGroup("Metrics"); + + settings.beginGroup(m_type); + + settings.beginGroup("Input"); + + foreach (MetricParam * param, m_inputParams) + { + settings.setValue(param->type,param->threshold); + qDebug() << m_type << " " << param->type << " = " << param->threshold; + } + + settings.endGroup(); + + settings.beginGroup("Output"); + + foreach (MetricParam * param, m_outputParams) + { + settings.setValue(param->type,param->threshold); + if (param->used) + settings.setValue("paramUsed",param->type); + } + + settings.endGroup(); + settings.endGroup(); + settings.endGroup(); +} + +bool BaseMetric::isValid() const +{ + return m_valid; +} + +int BaseMetric::getPixelError() const +{ + return m_nbPixelError; +} + +float BaseMetric::getMinError() const +{ + return m_minError; +} + +float BaseMetric::getMaxError() const +{ + return m_maxError; +} + +QImage BaseMetric::getImage1WithGain(double gain, double offset) +{ + cv::Mat converted; + m_opencvInput1.convertTo(converted, -1, gain, offset); + return MiscFunctions::opencvMatToQImage(converted); +} + +QImage BaseMetric::getImage2WithGain(double gain, double offset) +{ + cv::Mat converted; + m_opencvInput2.convertTo(converted, -1, gain, offset); + return MiscFunctions::opencvMatToQImage(converted); +} + +QImage BaseMetric::getImageDifferenceWithGain(double gain, double offset) +{ + cv::Mat converted; + m_opencvDiff.convertTo(converted, -1, gain, offset); + return MiscFunctions::opencvMatToQImage(converted); +} + +const QImage & BaseMetric::getImage1() const +{ + return m_image1; +} + +const QImage & BaseMetric::getImage2() const +{ + return m_image2; +} + +const QImage & BaseMetric::getImageDifference() const +{ + return m_imageDiff; +} + +const QImage & BaseMetric::getImageMask() const +{ + return m_imageMask; +} + +int BaseMetric::getDifferenceChannels() const +{ + return m_opencvDiff.channels(); +} + +double BaseMetric::getMaxImage1() const +{ + return m_maxImage1; +} + +double BaseMetric::getMaxImage2() const +{ + return m_maxImage2; +} + +double BaseMetric::getMinImage1() const +{ + return m_minImage1; +} + +double BaseMetric::getMinImage2() const +{ + return m_minImage2; +} + +int BaseMetric::getImage1Channels() const +{ + return m_opencvInput1.channels(); +} + +int BaseMetric::getImage2Channels() const +{ + return m_opencvInput2.channels(); +} + +void BaseMetric::setDiscriminatingParam(MetricParam *p) +{ + foreach (MetricParam * param, m_outputParams) + { + if (param == p) + param->used = true; + else + param->used = false; + } +} + +QString BaseMetric::getImage1Data(int x,int y) const +{ + return MiscFunctions::dataToText(m_opencvInput1,x,y); +} + +QString BaseMetric::getImage2Data(int x,int y) const +{ + return MiscFunctions::dataToText(m_opencvInput2,x,y); +} + +QString BaseMetric::getErrorData(int x,int y) const +{ + return MiscFunctions::dataToText(m_opencvDiff,x,y); +} + +QString BaseMetric::getImage1Data(const QPoint &pt) const +{ + return getImage1Data( pt.x(),pt.y() ); +} + +QString BaseMetric::getImage2Data(const QPoint &pt) const +{ + return getImage2Data( pt.x(),pt.y() ); +} + +QString BaseMetric::getErrorData(const QPoint &pt) const +{ + return getErrorData( pt.x(),pt.y() ); +} + +MetricParam *BaseMetric::getDiscriminatingParam() const +{ + foreach (MetricParam * param, m_outputParams) + if (param->used == true) + return param; + + return NULL; +} + +bool BaseMetric::checkImages() +{ + m_valid = false; + + // check loading of files + if ( m_opencvInput1.empty() ) + { + LogHandler::getInstance()->reportError( QString("Can't read %1").arg( m_file1 ) ); + return m_valid; + } + if ( m_opencvInput2.empty() ) + { + LogHandler::getInstance()->reportError( QString("Can't read %1").arg( m_file2 ) ); + return m_valid; + } + + // check size + if (m_opencvInput1.rows != m_opencvInput2.rows || m_opencvInput1.cols != m_opencvInput2.cols) + { + LogHandler::getInstance()->reportError( QString("Size mismatch (%1x%2)/(%3/%4)").arg(m_opencvInput1.rows ).arg(m_opencvInput1.cols).arg(m_opencvInput2.rows).arg(m_opencvInput2.cols) ); + return m_valid; + } + + // check type + if ( m_opencvInput1.type() != m_opencvInput2.type() ) + { + LogHandler::getInstance()->reportError( QString("Type mismatch (%1)/(%2)").arg( MiscFunctions::matTypeToText( m_opencvInput1.type() ) ).arg( MiscFunctions::matTypeToText( m_opencvInput2.type() ) ) ); + return m_valid; + } + + m_valid = true; + return m_valid; +} + +bool BaseMetric::selectedStatsIsValid() const +{ + foreach (MetricParam * param, m_outputParams) + { + if ( param->used && !param->isValid() ) + return false; + } + return true; +} + +const QList &BaseMetric::getHistogramImage1() +{ + if ( m_histoImage1.isEmpty() ) + computeHisto(m_opencvInput1,m_histoImage1); + return m_histoImage1; +} + +const QList &BaseMetric::getHistogramImage2() +{ + if ( m_histoImage2.isEmpty() ) + computeHisto(m_opencvInput2,m_histoImage2); + return m_histoImage2; +} + +const QList &BaseMetric::getHistogramImageDiff() +{ + if ( m_histoImageDiff.isEmpty() ) + computeHisto(m_opencvDiff,m_histoImageDiff,true); + return m_histoImageDiff; +} + +void BaseMetric::computeHisto(const cv::Mat img,QList &polys, bool skipZeroLevel) +{ + polys.clear(); + + if ( img.empty() ) + return; + + QList listHisto; + + for (int i = 0; i < img.channels(); i++) + listHisto << cv::Mat(); + + std::vector listChannels; + + cv::split(img, listChannels); + + // compute global min/max + double min = 100000; + double max = -100000; + for (size_t i = 0; i < listChannels.size(); i++) + { + double minVal, maxVal; + cv::minMaxLoc(listChannels[i], &minVal, &maxVal); //Locate max and min values + min = qMin(min,minVal); + max = qMax(max,maxVal); + } + + // null image => exit + if (min == 0.0 && max == 0.0) + return; + + for (size_t i = 0; i < listChannels.size(); i++) + { +// double minVal, maxVal; +// cv::minMaxLoc(listChannels[i], &minVal, &maxVal); //Locate max and min values +// +// qDebug() << "min " << minVal << " max = " << maxVal; + + // Initialize histogram settings + int histSize[] = { (int)(max - min) }; + float Range[] = { min, max }; //{0, 256} = 0 to 255 + const float *Ranges[] = { Range }; + int channels[] = { 0 }; + + /* + int histSize[] = { 256 }; + float Range[] = { 0, 256 }; //{0, 256} = 0 to 255 + const float *Ranges[] = { Range }; + int channels[] = { 0 }; + */ + + cv::Mat hist; + + calcHist(&(listChannels[i]), 1, channels, cv::Mat(), // do not use mask + hist, + 1, + histSize, + Ranges, + true, // the histogram is uniform + false); + + QPolygonF points; + for( int h = 0; h < hist.rows; h++) + { + float bin_value = 0; + if (!skipZeroLevel || h) + bin_value = hist.at(h); + points << QPointF( (float)h, bin_value ); + } + polys << points; + } + + /* + return; + + + cv::Mat histB; + cv::Mat histG; + cv::Mat histR; + + MiscFunctions::ComputeHistogramBGR(img, histB, histG, histR); + + //computeHistogram1D + + // Insert the points that should be plotted on the graph in a vector of QPoints or a QPolgonF + QPolygonF points; + for( int h = 0; h < histB.rows; h++) + { + float bin_value = histB.at(h); + points << QPointF((float)h, bin_value); + } + polys << points; + + points.clear(); + for( int h = 0; h < histG.rows; h++) + { + float bin_value = histG.at(h); + points << QPointF((float)h, bin_value); + } + polys << points; + + points.clear(); + for( int h = 0; h < histR.rows; h++) + { + float bin_value = histR.at(h); + points << QPointF((float)h, bin_value); + } + polys << points; + + */ +} + +void BaseMetric::checkDifferences(const QString &file1,const QString &file2) +{ + m_file1 = file1; + m_file2 = file2; + m_valid = false; + m_nbPixelError = 0; + m_maxError = 0; + m_minError = 0; + m_meanError = 0; + m_minImage1 = 0.0; + m_minImage2 = 0.0; + m_maxImage1 = 0.0; + m_maxImage2 = 0.0; + m_histoImage1.clear(); + m_histoImage2.clear(); + m_histoImageDiff.clear(); + + m_opencvInput1.release(); + + //m_opencvTransf1.release(); + m_opencvInput2.release(); + + //m_opencvTransf2.release(); + m_opencvDiff.release(); + m_opencvMaskDiff.release(); + + m_properties.clear(); + init(); + resetOutputParams(); + + // load file1 + m_opencvInput1 = cv::imread(m_file1.toStdString(),CV_LOAD_IMAGE_UNCHANGED ); + if ( m_opencvInput1.empty() ) + { + LogHandler::getInstance()->reportDebug( QString("OpenCV can't read file, trying with Qt ... (%1)").arg( m_file1 ) ); + + // try to load with Qt + m_opencvInput1 = MiscFunctions::qImageToOpencvMat( QImage(m_file1) ); + } + + // load file2 + m_opencvInput2 = cv::imread(m_file2.toStdString(),CV_LOAD_IMAGE_UNCHANGED ); + if ( m_opencvInput2.empty() ) + { + LogHandler::getInstance()->reportDebug( QString("OpenCV can't read file, trying with Qt ... (%1)").arg( m_file2 ) ); + + // try to load with Qt + m_opencvInput2 = MiscFunctions::qImageToOpencvMat( QImage(m_file2) ); + } + + // check compatibility + if( !checkImages() ) + return; + + // compute "standard" properties + computeStandardProperties(); + + // perform the difference algorithm + performDifference(); + + // compute some statistics on difference image + computeStatistics(); + +// bool ok1 = cv::imwrite("d:/toto1.png",m_opencvInput1); +// bool ok2 = cv::imwrite("d:/toto2.png",m_opencvInput2); + + /* + cvtColor(m_opencvInput1, m_opencvTransf1,CV_BGR2RGB); + m_image1 = QImage((uchar*)m_opencvTransf1.data, m_opencvTransf1.cols, m_opencvTransf1.rows,m_opencvTransf1.step,QImage::Format_RGB888); + cvtColor(m_opencvInput2, m_opencvTransf2,CV_BGR2RGB); + m_image2 = QImage((uchar*)m_opencvTransf2.data, m_opencvTransf2.cols, m_opencvTransf2.rows,m_opencvTransf2.step,QImage::Format_RGB888); + */ + + m_image1 = MiscFunctions::opencvMatToQImage(m_opencvInput1,false); + m_image2 = MiscFunctions::opencvMatToQImage(m_opencvInput2,false); + m_imageDiff = MiscFunctions::opencvMatToQImage(m_opencvDiff,false); + + // !!!!!!!!!!! debug !!!!!!!! + + /* + if (m_opencvDiff.type() == CV_8UC3) + { + m_opencvDiff.at(200,300)[0] = 255; + m_opencvDiff.at(200,300)[1] = 128; + m_opencvDiff.at(200,300)[2] = 50; + } + */ + + computeDifferenceMask(); + + m_imageMask = MiscFunctions::opencvMatToQImage(m_opencvMaskDiff,false); +} + +void BaseMetric::computeStatistics() +{ + MetricParam *param; + + //double maxval, minval; + minMaxLoc(m_opencvDiff, &m_minError, &m_maxError); + + cv::Scalar templMean, templSdv; + + cv::Mat reshaped = m_opencvDiff.reshape(1); + meanStdDev( reshaped, templMean, templSdv ); + + ////////////////////////////////// + +/* + unsigned char * pixelPtr = (unsigned char*)m_opencvDiff.data; + int cn = m_opencvDiff.channels(); + float err = 0, err2 = 0; + int nb = 0; + + for(int i=0;ivalue = m_meanError; + + // min error + param = getOutputParam("MinError"); + param->value = (int)m_minError; + + // max error + param = getOutputParam("MaxError"); + param->value = (int)m_maxError; + + param = getOutputParam("StandardDeviation"); + param->value = stdDev; + + // Root Mean Square as https://en.wikipedia.org/wiki/Root_mean_square#Relationship_to_the_arithmetic_mean_and_the_standard_deviation + float rms = sqrtf(m_meanError * m_meanError + stdDev * stdDev); + param = getOutputParam("RMS"); + param->value = rms; + + // nb error + m_nbPixelError = computeNbErrors(m_opencvDiff); + param = getOutputParam("ErrorNum"); + param->value = m_nbPixelError; + + // % error + param = getOutputParam("ErrorPercent"); + param->value = m_nbPixelError * 100.0 / (m_opencvDiff.cols * m_opencvDiff.rows); +} + +int BaseMetric::computeNbErrors(const cv::Mat &mat) +{ + cv::Mat thresh; + if ( mat.empty() ) + return 0; + + // caution must do threshold before rgbtogray !! + if (mat.channels()>1) + threshold(mat,thresh,0,255,cv::THRESH_BINARY); + else + thresh = mat; + + // convert multichannel to a single plane + // CAUTION !! 2 channels isn't take into account (waiting some data to test this case !!) + if (thresh.channels()>=3) + cvtColor(thresh,thresh,CV_RGB2GRAY); + return countNonZero(thresh); +} + +void BaseMetric::computeDifferenceMask() +{ +// methode bestiale pour l'instant + + m_opencvMaskDiff = cv::Mat(m_opencvDiff.size(), CV_8UC4); + + // unsigned char * pixelPtr = (unsigned char*)m_opencvDiff.data; + int cn = m_opencvDiff.channels(); + +// qDebug() << "type = " << MiscFunctions::matTypeToText( m_opencvDiff.type() ); +// qDebug() << "depth = " << MiscFunctions::matDepthToText( m_opencvDiff.depth() ); + + m_opencvMaskDiff.setTo( cv::Scalar(0,0,0,255) ); + + for(int i = 0; i(i,j); + else if (m_opencvDiff.depth() == CV_16S) + val = m_opencvDiff.at(i,j); + else if (m_opencvDiff.depth() == CV_16U) + val = m_opencvDiff.at(i,j); + else if (m_opencvDiff.depth() == CV_32F) + val = m_opencvDiff.at(i,j); + } + else if (cn == 3) + { +// for(int k = 0; k(i,j)[k]; + for(int k = 0; k(i,j)[k]; + else if (m_opencvDiff.depth() == CV_16S) + val += m_opencvDiff.at(i,j)[k]; + else if (m_opencvDiff.depth() == CV_16U) + val += m_opencvDiff.at(i,j)[k]; + else if (m_opencvDiff.depth() == CV_32F) + val += m_opencvDiff.at(i,j)[k]; + } + + val /= cn; + } + else // RGBA => not taking account of Alpha channel !! + { +// for(int k = 0; k(i,j)[k]; + for(int k = 0; k(i,j)[k]; + else if (m_opencvDiff.depth() == CV_16U) + val += m_opencvDiff.at(i,j)[k]; + else if (m_opencvDiff.depth() == CV_16S) + val += m_opencvDiff.at(i,j)[k]; + else if (m_opencvDiff.depth() == CV_32F) + val += m_opencvDiff.at(i,j)[k]; + } + + val /= cn - 1; + } + + if (val > 0.0) + { + if (val > m_meanError) + { + m_opencvMaskDiff.at(i,j)[0] = 255; // first channel (B) + m_opencvMaskDiff.at(i,j)[1] = 255; // second channel (G) + m_opencvMaskDiff.at(i,j)[2] = 0; // 3 channel (R) + m_opencvMaskDiff.at(i,j)[3] = 255; // 4 channel (A) + } + else + { + m_opencvMaskDiff.at(i,j)[0] = 255; // first channel (B) + m_opencvMaskDiff.at(i,j)[1] = 0; // second channel (G) + m_opencvMaskDiff.at(i,j)[2] = 0; // 3 channel (R) + m_opencvMaskDiff.at(i,j)[3] = 255; // 4 channel (A) + } + } + else + { + m_opencvMaskDiff.at(i,j)[0] = 0; // first channel (B) + m_opencvMaskDiff.at(i,j)[1] = 0; // second channel (G) + m_opencvMaskDiff.at(i,j)[2] = 0; // second channel (R) + m_opencvMaskDiff.at(i,j)[3] = 0; // second channel (A) + } + } + } + +/* + return; + cv::Mat upperMean,lowerMean; + + cv::Scalar mins,maxs; + + for (int i = 0; i < m_opencvDiff.channels(); i++) + { + mins[i] = m_meanError+1; + maxs[i] = m_maxError; + } + inRange(m_opencvDiff, mins,maxs, upperMean); + //threshold(upperMean,upperMean,0,255,cv::THRESH_BINARY); + cv::imwrite("d:/mask.png",upperMean); + + for (int i = 0; i < m_opencvDiff.channels(); i++) + { + mins[i] = 1; + maxs[i] = m_meanError+1; + } + inRange(m_opencvDiff, mins,maxs, lowerMean); + cv::imwrite("d:/mask2.png",lowerMean); + */ +} diff -Nru diffimg-1.5.0/src/metrics/BaseMetric.h diffimg-2.0.0/src/metrics/BaseMetric.h --- diffimg-1.5.0/src/metrics/BaseMetric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/BaseMetric.h 2013-05-23 22:01:08.000000000 +0000 @@ -0,0 +1,217 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _BaseMetric_H_ +#define _BaseMetric_H_ + +#include +#include +#include + +#include +#include + +struct ImageProperty +{ + ImageProperty(const QString & n, const QString &d, const QString &v) : + name(n), + desc(d), + value(v) + { + } + + QString name; + QString desc; + QString value; +}; + +class MetricParam +{ +public: + + MetricParam(const QString &t, const QString &n, const QString &d, const QVariant &v) : + type(t), + name(n), + desc(d), + threshold(v), + value(v), + defaultValue(v), + used(false) + { + } + + virtual ~MetricParam(){} + + bool isValid(); + void reset(bool all = true); + void setThreshold(const QString &valText); + + QString type; + QString name; + QString desc; + QVariant threshold; + QVariant value; + QVariant defaultValue; + bool used; +}; + +class BaseMetric : public QObject +{ + Q_OBJECT + +public: + + explicit BaseMetric(QObject *parent = 0); + virtual ~BaseMetric(); + + virtual QPixmap getLogo() const; + + const QString & getType() const; + const QString & getName() const; + const QString & getDesc() const; + + const QList & getProperties() const; + const QList & getOutputParams(); + const QList & getInputParams(); + + virtual void checkDifferences(const QString &file1,const QString &file2); + + static int defaultThresholdNumPixel; + static float defaultThresholdMeanError; + static float defaultThresholdRMSError; + static int defaultThresholdMinError; + static int defaultThresholdMaxError; + static float defaultThresholdStandardDeviation; + + QImage getImage1WithGain(double gain, double offset); + QImage getImage2WithGain(double gain, double offset); + QImage getImageDifferenceWithGain(double gain, double offset); + const QImage & getImage1() const; + const QImage & getImage2() const; + const QImage & getImageDifference() const; + const QImage & getImageMask() const; + + const QList &getHistogramImage1(); + const QList &getHistogramImage2(); + const QList &getHistogramImageDiff(); + + void setDiscriminatingParam(MetricParam *); + MetricParam *getDiscriminatingParam() const; + + bool isValid() const; + + int getPixelError() const; + float getMaxError() const; + float getMinError() const; + int getDifferenceChannels() const; + int getImage2Channels() const; + int getImage1Channels() const; + + double getMaxImage1() const; + double getMaxImage2() const; + double getMinImage1() const; + double getMinImage2() const; + + QString getImage1Data(int x,int y) const; + QString getImage2Data(int x,int y) const; + QString getErrorData(int x,int y) const; + QString getImage1Data(const QPoint &) const; + QString getImage2Data(const QPoint &) const; + QString getErrorData(const QPoint &) const; + + virtual bool selectedStatsIsValid() const; + + MetricParam * getOutputParam(const QString &name); + MetricParam * getInputParam(const QString &name); + +public slots: + +protected slots: + +protected: + + void init(); + MetricParam *addOutputParam(MetricParam *); + MetricParam *addInputParam(MetricParam *); + + void computeStandardProperties(); + void clearOutputParams(); + void resetOutputParams(); + virtual void createOutputParams(); + virtual void createInputParams(); + void saveSettings(); + void loadSettings(); + bool checkImages(); + + virtual void computeStatistics(); + virtual void performDifference() = 0; + + int computeNbErrors(const cv::Mat &mat); + void computeHisto(const cv::Mat img,QList &polys, bool skipZeroLevel = false); + void computeDifferenceMask(); + + QString m_type; + QString m_name; + QString m_desc; + + // properties = size, type, ... + QList m_properties; + + // input param if needed + QList m_inputParams; + + // params RMS, ... + QList m_outputParams; + + QString m_file1; + QString m_file2; + + cv::Mat m_opencvInput1; + + //cv::Mat m_opencvTransf1; + cv::Mat m_opencvInput2; + + //cv::Mat m_opencvTransf2; + cv::Mat m_opencvDiff; + cv::Mat m_opencvMaskDiff; + QImage m_image1; + QImage m_image2; + QImage m_imageDiff; + QImage m_imageMask; + + bool m_valid; + int m_nbPixelError; + double m_maxError; + double m_minError; + double m_meanError; + + double m_minImage1; + double m_minImage2; + double m_maxImage1; + double m_maxImage2; + + QList m_histoImage1; + QList m_histoImage2; + QList m_histoImageDiff; + + bool m_init; +}; + +#endif // _BaseMetric_H_ diff -Nru diffimg-1.5.0/src/metrics/MetricsManager.cpp diffimg-2.0.0/src/metrics/MetricsManager.cpp --- diffimg-1.5.0/src/metrics/MetricsManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/MetricsManager.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,51 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include + +#include "MetricsManager.h" +#include "BaseMetric.h" + +QList MetricsManager::m_metrics; + +MetricsManager::MetricsManager(QObject *parent) : QObject(parent) +{ +} + +MetricsManager::~MetricsManager() +{ + clear(); +} + +void MetricsManager::clear() +{ + qDeleteAll(m_metrics); + m_metrics.clear(); +} + +void MetricsManager::registerMetrics(BaseMetric *metric) +{ + m_metrics << metric; +} + +const QList & MetricsManager::getMetrics() +{ + return m_metrics; +} diff -Nru diffimg-1.5.0/src/metrics/MetricsManager.h diffimg-2.0.0/src/metrics/MetricsManager.h --- diffimg-1.5.0/src/metrics/MetricsManager.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/MetricsManager.h 2013-05-15 06:04:12.000000000 +0000 @@ -0,0 +1,48 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _METRICSMANAGER_H_ +#define _METRICSMANAGER_H_ + +#include + +class BaseMetric; + +class MetricsManager : public QObject +{ + Q_OBJECT + +public: + + explicit MetricsManager(QObject *parent = 0); + virtual ~MetricsManager(); + + static void registerMetrics(BaseMetric*); + + static const QList & getMetrics(); + + static void clear(); + +private: + + static QList m_metrics; +}; + +#endif // _METRICSMANAGER_H_ diff -Nru diffimg-1.5.0/src/metrics/MetricsRegistering.cpp diffimg-2.0.0/src/metrics/MetricsRegistering.cpp --- diffimg-1.5.0/src/metrics/MetricsRegistering.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/MetricsRegistering.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,47 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include "MetricsRegistering.h" + +#include "MetricsManager.h" +#include "BaseMetric.h" + +#include "PerChannelMetric.h" +#include "PerChannelMeanMetric.h" +#include "PerLuminanceMetric.h" +#include "PerceptualMetric.h" + +int MetricsRegistering::registerAll() +{ + if ( MetricsManager::getMetrics().isEmpty() ) // avoid multiple init + { + MetricsManager::registerMetrics( new PerChannelMetric() ); + MetricsManager::registerMetrics( new PerChannelMeanMetric() ); + MetricsManager::registerMetrics( new PerLuminanceMetric() ); + MetricsManager::registerMetrics( new PerceptualMetric() ); + } + + return MetricsManager::getMetrics().size(); +} + +void MetricsRegistering::unregisterAll() +{ + MetricsManager::clear(); +} diff -Nru diffimg-1.5.0/src/metrics/MetricsRegistering.h diffimg-2.0.0/src/metrics/MetricsRegistering.h --- diffimg-1.5.0/src/metrics/MetricsRegistering.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/MetricsRegistering.h 2013-05-21 20:52:00.000000000 +0000 @@ -0,0 +1,33 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ +#ifndef _METRICSREGISTERING_H_ +#define _METRICSREGISTERING_H_ + +class MetricsRegistering +{ +public: + + static int registerAll(); + static void unregisterAll(); + +private: +}; + +#endif // _METRICSREGISTERING_H_ diff -Nru diffimg-1.5.0/src/metrics/PerChannelMeanMetric.cpp diffimg-2.0.0/src/metrics/PerChannelMeanMetric.cpp --- diffimg-1.5.0/src/metrics/PerChannelMeanMetric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerChannelMeanMetric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,66 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include + +#include "PerChannelMeanMetric.h" + +#include "MiscFunctions.h" +#include "LogHandler.h" + +PerChannelMeanMetric::PerChannelMeanMetric(QObject *parent) : BaseMetric(parent) +{ + m_type = metaObject()->className(); + m_name = tr("Difference per channel mean"); + m_desc = tr("Difference is computed between both mean values defined as mean(x,y) = (R(x,y)+G(x,y)+B(x,y))/3"); + + // init settings + //loadSettings(); +} + +PerChannelMeanMetric::~PerChannelMeanMetric() +{ +} + +QPixmap PerChannelMeanMetric::getLogo() const +{ + return QPixmap(":/diffimg/perchannelmean.png"); +} + +void PerChannelMeanMetric::performDifference() +{ + // create two "mean" images + cv::Mat mean1 = mat2mean(m_opencvInput1); + cv::Mat mean2 = mat2mean(m_opencvInput2); + absdiff(mean1,mean2,m_opencvDiff); + + //cv::imwrite("d:/toto2.png",mean1); +} + +cv::Mat PerChannelMeanMetric::mat2mean(const cv::Mat& src) +{ + std::vector planes( src.channels() ); + cv::split(src,planes); + float factor = 1.0 / src.channels(); + cv::Mat mean = factor * planes[0]; + for (int i = 1; i < m_opencvInput1.channels(); i++) + mean += (factor * planes[i]); + return mean; +} diff -Nru diffimg-1.5.0/src/metrics/PerChannelMeanMetric.h diffimg-2.0.0/src/metrics/PerChannelMeanMetric.h --- diffimg-1.5.0/src/metrics/PerChannelMeanMetric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerChannelMeanMetric.h 2013-05-15 06:04:12.000000000 +0000 @@ -0,0 +1,49 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ +#ifndef _BYCHANNELMEANMETRIC_H_ +#define _BYCHANNELMEANMETRIC_H_ + +#include "BaseMetric.h" + +class PerChannelMeanMetric : public BaseMetric +{ + Q_OBJECT + +public: + + explicit PerChannelMeanMetric(QObject *parent = 0); + virtual ~PerChannelMeanMetric(); + + virtual QPixmap getLogo() const; + +signals: + +protected: + + virtual void performDifference(); + +private slots: + +private: + + cv::Mat mat2mean(const cv::Mat& src); +}; + +#endif // _BYCHANNELMEANMETRIC_H_ diff -Nru diffimg-1.5.0/src/metrics/PerChannelMetric.cpp diffimg-2.0.0/src/metrics/PerChannelMetric.cpp --- diffimg-1.5.0/src/metrics/PerChannelMetric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerChannelMetric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,63 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include + +#include + +#include "PerChannelMetric.h" + +#include "MiscFunctions.h" +#include "LogHandler.h" + +PerChannelMetric::PerChannelMetric(QObject *parent) : BaseMetric(parent) +{ + m_type = metaObject()->className(); + m_name = tr("Difference per channel"); + m_desc = tr("Difference is computed channel per channel"); + + updateParameters(); + + // init settings + //loadSettings(); +} + +PerChannelMetric::~PerChannelMetric() +{ +} + +QPixmap PerChannelMetric::getLogo() const +{ + return QPixmap(":/diffimg/perchannel.png"); +} + +void PerChannelMetric::performDifference() +{ + absdiff(m_opencvInput1,m_opencvInput2,m_opencvDiff); +} + +void PerChannelMetric::updateParameters() +{ + // m_params << new MetricParam("RMSError",tr("RMS error"),tr("Root Mean Square error"),BaseMetric::defaultThresholdRMSError); + // m_params << new MetricParam("MeanError",tr("Mean error"),tr("Mean absolute error"),BaseMetric::defaultThresholdMeanError); + // m_params << new MetricParam("MaxError",tr("Max error"),tr("Maximal error"),BaseMetric::defaultThresholdMaxError); + //m_params << new MetricParam("StandardDeviation",tr("Standard deviation"),tr("Standard deviation"),BaseMetric::defaultThresholdStandardDeviation); + //m_params << new MetricParam("ErrorNum",tr("Error num (pixels)"),tr("Number of different pixels"),BaseMetric::defaultThresholdNumPixel); +} diff -Nru diffimg-1.5.0/src/metrics/PerChannelMetric.h diffimg-2.0.0/src/metrics/PerChannelMetric.h --- diffimg-1.5.0/src/metrics/PerChannelMetric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerChannelMetric.h 2013-05-15 17:05:46.000000000 +0000 @@ -0,0 +1,50 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _BYCHANNELMETRIC_H_ +#define _BYCHANNELMETRIC_H_ + +#include "BaseMetric.h" + +class PerChannelMetric : public BaseMetric +{ + Q_OBJECT + +public: + + explicit PerChannelMetric(QObject *parent = 0); + virtual ~PerChannelMetric(); + + virtual QPixmap getLogo() const; + +signals: + +protected: + + virtual void performDifference(); + +private slots: + +private: + + void updateParameters(); +}; + +#endif // _BYCHANNELMETRIC_H_ diff -Nru diffimg-1.5.0/src/metrics/PerLuminanceMetric.cpp diffimg-2.0.0/src/metrics/PerLuminanceMetric.cpp --- diffimg-1.5.0/src/metrics/PerLuminanceMetric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerLuminanceMetric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,67 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include + +#include + +#include "PerLuminanceMetric.h" + +#include "MiscFunctions.h" +#include "LogHandler.h" + +PerLuminanceMetric::PerLuminanceMetric(QObject *parent) : BaseMetric(parent) +{ + m_type = metaObject()->className(); + m_name = tr("Difference per image luminance"); + m_desc = tr("Difference is computed between both luminance values defined as luminance(x,y) = 0.3*R(x,y)+0.59*G(x,y)+0.11*B(x,y)"); + + // init settings + //loadSettings(); +} + +PerLuminanceMetric::~PerLuminanceMetric() +{ +} + +QPixmap PerLuminanceMetric::getLogo() const +{ + return QPixmap(":/diffimg/perluminance.png"); +} + +void PerLuminanceMetric::performDifference() +{ + cv::Mat gray1; + cv::Mat gray2; + if (m_opencvInput1.channels()>=3) + { + cvtColor(m_opencvInput1,gray1,CV_RGB2GRAY); + cvtColor(m_opencvInput2,gray2,CV_RGB2GRAY); + } + else + { + gray1 = m_opencvInput1; + gray2 = m_opencvInput2; + } + + absdiff(gray1,gray2,m_opencvDiff); + + //cv::imwrite("d:/toto2.png",gray1); +} diff -Nru diffimg-1.5.0/src/metrics/PerLuminanceMetric.h diffimg-2.0.0/src/metrics/PerLuminanceMetric.h --- diffimg-1.5.0/src/metrics/PerLuminanceMetric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerLuminanceMetric.h 2013-05-15 06:04:12.000000000 +0000 @@ -0,0 +1,48 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#ifndef _BYLUMINANCEMETRIC_H_ +#define _BYLUMINANCEMETRIC_H_ + +#include "BaseMetric.h" + +class PerLuminanceMetric : public BaseMetric +{ + Q_OBJECT + +public: + + explicit PerLuminanceMetric(QObject *parent = 0); + virtual ~PerLuminanceMetric(); + + virtual QPixmap getLogo() const; + +signals: + +protected: + + virtual void performDifference(); + +private slots: + +private: +}; + +#endif // _BYLUMINANCEMETRIC_H_ diff -Nru diffimg-1.5.0/src/metrics/PerceptualMetric.cpp diffimg-2.0.0/src/metrics/PerceptualMetric.cpp --- diffimg-1.5.0/src/metrics/PerceptualMetric.cpp 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerceptualMetric.cpp 2013-07-24 11:39:11.000000000 +0000 @@ -0,0 +1,127 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + +#include + +#include "PerceptualMetric.h" + +#include "MiscFunctions.h" +#include "LogHandler.h" + +// Perceptual diff includes +#include "CompareArgs.h" +#include "Metric.h" +#include "RGBAImage.h" + +#include "OpenCVImageLoader.h" + +static int defaultLuminanceOnly = 0; +static float defaultFieldOfView = 45.0f; +static float defaultGamma = 2.2f; +static float defaultLuminance = 100.0f; +static float defaultColorFactor = 1.0f; +static int defaultDownSample = 0; + +PerceptualMetric::PerceptualMetric(QObject *parent) : BaseMetric(parent), + m_noDifference(true) +{ + m_type = metaObject()->className(); + m_name = tr("Perceptual difference"); + m_desc = tr("A perceptually based image metric. Copyright (C) 2006 Yangli Hector Yee"); + + // init settings + //loadSettings(); +} + +PerceptualMetric::~PerceptualMetric() +{ +} + +QPixmap PerceptualMetric::getLogo() const +{ + return QPixmap(":/diffimg/perceptual.png"); +} + +void PerceptualMetric::createInputParams() +{ + /* + \t-fov deg : Field of view in degrees (0.1 to 89.9)\n\ + \t-threshold p : #pixels p below which differences are ignored\n\ + \t-gamma g : Value to convert rgb into linear space (default 2.2)\n\ + \t-luminance l : White luminance (default 100.0 cdm^-2)\n\ + \t-luminanceonly : Only consider luminance; ignore chroma (color) in the comparison\n\ + \t-colorfactor : How much of color to use, 0.0 to 1.0, 0.0 = ignore color.\n\ + \t-downsample : How many powers of two to down sample the image.\n\ + */ + + // FOV + addInputParam( new MetricParam("FOV",tr("Field of view"),tr("Field of view in degrees (0.1 to 89.9)"),defaultFieldOfView) ); + + // Gamma + addInputParam( new MetricParam("Gamma",tr("Gamma of screen"),tr("Value to convert rgb into linear space (default 2.2)"),defaultGamma) ); + + // Luminance + addInputParam( new MetricParam("Luminance",tr("White luminance"),tr("White luminance (default 100.0 cdm^-2)"),defaultLuminance) ); + + // Luminance only + addInputParam( new MetricParam("LuminanceOnly",tr("Luminance only"),tr("Only consider luminance; ignore chroma (color) in the comparison"),defaultLuminanceOnly) ); + + // FOV + addInputParam( new MetricParam("ColorFactor",tr("Color factor"),tr("How much of color to use, 0.0 to 1.0, 0.0 = ignore color."),defaultColorFactor) ); + + // FOV + addInputParam( new MetricParam("Downsample",tr("Downsample"),tr("How many powers of two to down sample the image"),defaultDownSample) ); +} + +void PerceptualMetric::performDifference() +{ + CompareArgs args; + m_noDifference = true; + + // update input params + args.FieldOfView = getInputParam("FOV")->threshold.toFloat(); + args.Gamma = getInputParam("Gamma")->threshold.toFloat(); + args.Luminance = getInputParam("Luminance")->threshold.toFloat(); + args.LuminanceOnly = getInputParam("LuminanceOnly")->threshold.toInt(); + args.ColorFactor = getInputParam("ColorFactor")->threshold.toFloat(); + args.DownSample = getInputParam("Downsample")->threshold.toInt(); + args.ThresholdPixels = getOutputParam("ErrorNum")->threshold.toInt(); + + args.ImgA = OpenCVImageLoader::MatToRGBAImage(m_opencvInput1); + args.ImgB = OpenCVImageLoader::MatToRGBAImage(m_opencvInput2); + args.ImgDiff = new RGBAImage(m_opencvInput1.cols, m_opencvInput1.rows,""); + + if (!args.ImgA ||!args.ImgB) // convert problem + { + LogHandler::getInstance()->reportError( "PerceptualDiff: Error during image conversion"); + return; + } + + // perform comparison + m_noDifference = Yee_Compare(args); + + // save diff image + std::vector channels; + cv::Mat rgbDiff = m_opencvDiff = OpenCVImageLoader::RGBAImageToMat(args.ImgDiff); + cv::split(rgbDiff,channels); + m_opencvDiff = channels[0]; + + //OpenCVImageLoader::WriteToFile(args.ImgDiff ,"d:/tmp.png"); +} diff -Nru diffimg-1.5.0/src/metrics/PerceptualMetric.h diffimg-2.0.0/src/metrics/PerceptualMetric.h --- diffimg-1.5.0/src/metrics/PerceptualMetric.h 1970-01-01 00:00:00.000000000 +0000 +++ diffimg-2.0.0/src/metrics/PerceptualMetric.h 2013-05-15 17:05:46.000000000 +0000 @@ -0,0 +1,52 @@ + +/****************************************************************************** + DiffImg: image difference viewer + Copyright(C) 2011-2013 xbee@xbee.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *******************************************************************************/ + + #ifndef _PERCEPTUALMETRIC_H_ +#define _PERCEPTUALMETRIC_H_ + +#include "BaseMetric.h" + +class PerceptualMetric : public BaseMetric +{ + Q_OBJECT + +public: + + explicit PerceptualMetric(QObject *parent = 0); + virtual ~PerceptualMetric(); + + virtual QPixmap getLogo() const; + +signals: + +protected: + + virtual void createInputParams(); + + virtual void performDifference(); + +private slots: + +private: + + bool m_noDifference; +}; + +#endif // _PERCEPTUALMETRIC_H_ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img1/IMG_0044.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img1/IMG_0044.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img1/IMG_0052.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img1/IMG_0052.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img1/IMG_0144.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img1/IMG_0144.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img1/IMG_0145.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img1/IMG_0145.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img1/IMG_0149.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img1/IMG_0149.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img2/IMG_0044.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img2/IMG_0044.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img2/IMG_0052.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img2/IMG_0052.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img2/IMG_0144.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img2/IMG_0144.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img2/IMG_0145.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img2/IMG_0145.png differ Binary files /tmp/JlWh6P2YUc/diffimg-1.5.0/test/img2/IMG_0149.png and /tmp/TanR_227uO/diffimg-2.0.0/test/img2/IMG_0149.png differ diff -Nru diffimg-1.5.0/ui/AboutDialog.ui diffimg-2.0.0/ui/AboutDialog.ui --- diffimg-1.5.0/ui/AboutDialog.ui 2012-08-25 16:42:11.000000000 +0000 +++ diffimg-2.0.0/ui/AboutDialog.ui 2013-05-17 19:12:26.000000000 +0000 @@ -9,8 +9,8 @@ 0 0 - 545 - 509 + 535 + 588 @@ -33,12 +33,12 @@ - 2 + 0 - - :/GraphX/about.png:/GraphX/about.png + + :/diffimg/about.png:/diffimg/about.png About @@ -80,22 +80,6 @@ - - - - - 0 - 0 - - - - Release Number - - - false - - - @@ -174,9 +158,52 @@ + + + + + + + 0 + 0 + + + + Release Number + + + false + + + + + + + + + + Qt::AutoText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + Qt::TextBrowserInteraction + + + + + + + + :/diffimg/preferences.png:/diffimg/preferences.png + Preferences @@ -203,70 +230,6 @@ - - - - Allow image difference - - - - - - - Threshold in RMS - - - RMS threshold (float): - - - - - - - Qt::Vertical - - - - 20 - 5 - - - - - - - - 100 - - - 50 - - - - - - - Mask opacity (0-transparent,100-opaque) - - - Error mask opacity (%) - - - - - - - false - - - - - - - Qt::Horizontal - - - @@ -280,6 +243,13 @@ + + + + Qt::Horizontal + + + @@ -287,44 +257,163 @@ - - - - Difference method + + + + Difference metric used + + + + + Allow image difference + + + true + + + + + + Discriminating parameter (Image are considered as different if the threshold is exceeded) + + + Discriminating parameter + + + + + + + Threshold + + + + + + + + + + + + + + :/diffimg/check2.png:/diffimg/check2.png + + + + + + + + + + + + + Metric + + + + + + + + + + true + + + + + + + + 48 + 16777215 + + + + + + + + + + + + + + Input parameters + + + + + + + + + + + + + :/diffimg/check2.png:/diffimg/check2.png + + + + + + + + + + - - - - - - - - 7 - - - - + + + + 100 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 50 - - true + + Qt::Horizontal - - + + 100 - + 50 + + + + - Qt::Horizontal + Qt::Vertical + + + + 20 + 5 + + + + + + + + Mask opacity (0-transparent,100-opaque) + + + Error mask opacity (%) @@ -332,8 +421,8 @@ - - :/GraphX/help.png:/GraphX/help.png + + :/diffimg/help.png:/diffimg/help.png Infos @@ -360,6 +449,18 @@ + + + + + 7 + + + + + + + @@ -402,6 +503,10 @@ + + + :/diffimg/journal.png:/diffimg/journal.png + Log @@ -441,11 +546,6 @@ - - - - - @@ -455,8 +555,8 @@ accept() - 257 - 499 + 266 + 480 157 @@ -471,8 +571,8 @@ reject() - 325 - 499 + 334 + 480 286 @@ -513,22 +613,6 @@ - checkBoxEnableThreshold - toggled(bool) - lineEditRMSThreshold - setEnabled(bool) - - - 121 - 190 - - - 346 - 216 - - - - checkBoxSplashscreenAtStartup toggled(bool) checkBoxSplashscreenTransparentBackground diff -Nru diffimg-1.5.0/ui/DiffImgWindow.ui diffimg-2.0.0/ui/DiffImgWindow.ui --- diffimg-1.5.0/ui/DiffImgWindow.ui 2012-08-25 13:59:21.000000000 +0000 +++ diffimg-2.0.0/ui/DiffImgWindow.ui 2013-07-13 14:21:14.000000000 +0000 @@ -6,13 +6,16 @@ 0 0 - 894 - 794 + 910 + 833 false + + true + diffimg @@ -25,41 +28,35 @@ + + 2 + + + 2 + - - - QLayout::SetDefaultConstraint + + + 6 - + - - 1 + + 0 0 - - QFrame::NoFrame - - - QFrame::Raised - - + - - 1 + + 0 0 - - QFrame::NoFrame - - - QFrame::Raised - @@ -71,12 +68,15 @@ 0 0 - 894 + 910 21 + + Main toolbar + Qt::Horizontal @@ -90,12 +90,12 @@ - - + + - + @@ -104,6 +104,7 @@ + @@ -114,8 +115,8 @@ 1 - - + + @@ -134,7 +135,7 @@ - + @@ -148,6 +149,9 @@ 100 + + true + true @@ -156,7 +160,7 @@ - + @@ -175,7 +179,7 @@ - + @@ -189,6 +193,9 @@ 100 + + true + true @@ -197,7 +204,7 @@ - + @@ -233,6 +240,9 @@ 100 + + true + true @@ -242,6 +252,111 @@ + + + Gain + + + + + + + false + + + 4.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + false + + + 0 + + + 400 + + + 1 + + + 100 + + + Qt::Horizontal + + + false + + + QSlider::TicksBelow + + + 10 + + + + + + + Offset + + + + + + + false + + + 0 + + + 0.000000000000000 + + + 100.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + 0 + + + 100 + + + Qt::Horizontal + + + false + + + QSlider::TicksBelow + + + 10 + + + + Qt::Vertical @@ -260,302 +375,74 @@ - + - Statistics + Histogram - 2 + 1 - - - - - - Method: + + + + 6 + + + + + + 0 + 100 + - - - - - - + + Histogram + + + 6 + + + + + + + + + + + Statistics + + + 2 + + + - - - - 0 - 0 - + + + + 7 + - - Position + + (*) statistics exceeding the authorized threshold - - false + + true - - - - - X: - - - - - - - 0 - - - - - - - Y: - - - - - - - 0 - - - - - - - Red component - - - R: - - - - - - - Red component - - - 0 - - - - - - - Green component - - - G: - - - - - - - Green component - - - 0 - - - - - - - Blue component - - - B: - - - - - - - Blue component - - - 0 - - - - - - - Zoom factor - - - Zoom: - - - - - - - Zoom factor - - - 0 - - - - - - - - 0 - 0 - - - - Statistics + + + - - - - - Size (pixels): - - - - - - - 0 - - - - - - - number of pixel with difference - - - Error Num (pixels): - - - - - - - 0 - - - - - - - Mean error - - - Mean error: - - - - - - - Mean error - - - 0 - - - - - - - Root Mean Square error - - - RMS Error: - - - - - - - Root Mean Square error - - - 0 - - - - - - - Minimal value of error - - - Min error: - - - - - - - Minimal value of error - - - 0 - - - - - - - Maximal value of error - - - Max error: - - - - - - - Maximal value of error - - - 0 - - - - - - - Standard deviation of error - - - Standard deviation - - - - - - - Standard deviation of error - - - 0 - - - - - + yellow color: pixel with error >mean error @@ -571,7 +458,10 @@ - + + + + red color: pixel with error <= mean error @@ -584,66 +474,42 @@ - - - - - - - :/diffimg/allgood.png - - - false - - - Qt::AlignCenter - - - - - + + Qt::Vertical - QSizePolicy::MinimumExpanding + QSizePolicy::Maximum 20 - 5 + 40 - - - - - - Histogram - - - 1 - - - - - - - Histogram + + + + + + + :/diffimg/allgood.png + + + false + + + Qt::AlignCenter - - - - - - + true @@ -661,7 +527,7 @@ 1 - + true @@ -676,7 +542,7 @@ 2 - + true @@ -843,29 +709,113 @@ Refresh + + R + + + + + + :/diffimg/help.png:/diffimg/help.png + + + Help + + + Online help + + + F1 + - ScrollImageWidget - QFrame -
ScrollImageWidget.h
+ QwtPlot + QWidget +
qwt_plot.h
1
- QwtPlot + PropertyWidget QWidget -
qwt_plot.h
+
PropertyWidget.h
1
+ + ImageView + QGraphicsView +
ImageView.h
+
- - - - - + + + checkBoxGain + toggled(bool) + sliderGain + setEnabled(bool) + + + 44 + 511 + + + 94 + 512 + + + + + checkBoxGain + toggled(bool) + doubleSpinBoxGain + setEnabled(bool) + + + 36 + 510 + + + 178 + 513 + + + + + checkBoxOffset + toggled(bool) + sliderOffset + setEnabled(bool) + + + 31 + 540 + + + 101 + 541 + + + + + checkBoxOffset + toggled(bool) + doubleSpinBoxOffset + setEnabled(bool) + + + 36 + 540 + + + 182 + 545 + + + + diff -Nru diffimg-1.5.0/ui/FilesDialog.ui diffimg-2.0.0/ui/FilesDialog.ui --- diffimg-1.5.0/ui/FilesDialog.ui 2011-12-30 22:57:43.000000000 +0000 +++ diffimg-2.0.0/ui/FilesDialog.ui 2013-05-14 06:45:00.000000000 +0000 @@ -34,10 +34,10 @@
- + - + @@ -82,10 +82,10 @@ - + - + @@ -131,7 +131,7 @@ - +